#load libraries
library(dplyr)
library(readr)
library(tidyr)
library(lubridate)
library(fixest)
library(data.table)
library(stringr)
library(sf)
# Turn off scientific notation globally
#options(scipen = 999)

#load relevant files
#readRDS("C:/Users/yoshiara/OneDrive - RAND Corporation/Desktop/Dissertation/eastern drc/panel_p3_yearly.rds")

setwd("C:/Users/yoshiara/OneDrive - RAND Corporation/Desktop/Dissertation/eastern drc")

#Descriptive Stats

##Cross-sectional (2021 only)

###Mining vs. non-mining grids

What do mining vs. non-mining grid cells look like? Table below includes grids covering all of DRC. Some things that stand out: - Mining grids are closer to national borders - Mining grids have more cropland (all types - irrigated, rainfed, other). For all grids, there is more rainfed than irrigated cropland. - Mining grids have fewer permanent bodies of water - Mining grids have higher population – but this could just be because the non-mining grids may capture many unpopulated areas. This matches the pattern for impervious/manmade surfaces but not for nightlight density which is the same for both mining and non-mining grids (weird) - Mining grids have higher conflict counts (across all conflict categories)

#descriptive stats (means table) mining vs non_mining####
# 1) Restrict to latest year where all vars exist (2021)
df_latest <- panel_p3_yearly %>%
  filter(year == 2021) %>%
  mutate(mine_group = ifelse(total_mine_count == 0, "No mines", ">=1 mine"))

# 2) Variables to summarize
vars <- c(
  "dist_to_border",
  "forest","grassland","impervious","irrigated_crops",
  "nightlights","other_crops","permanent_water",
  "rainfed_crops","seasonal_water","shrubland",
  "sparse","swamp","pop", "n_conflicts", "n_battles", "n_protests"
)

# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
  if (is.numeric(x)) return(x)
  if (is.factor(x))  return(as.numeric(as.character(x)))
  if (is.character(x)) return(suppressWarnings(as.numeric(x)))
  return(suppressWarnings(as.numeric(x)))
}

# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
  x <- to_num(df_latest[[v]])
  g <- df_latest$mine_group
  
  # group means
  m0 <- mean(x[g == "No mines"], na.rm = TRUE)
  m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
  
  # t-test (Welch)
  tt <- t.test(x ~ g)
  
  data.frame(
    variable = v,
    mean_no_mines = m0,
    mean_mines = m1,
    p_value = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(sig = case_when(
    p_value < 0.001 ~ "***",
    p_value < 0.01  ~ "**",
    p_value < 0.05  ~ "*",
    TRUE ~ ""
  ))

# Turn off scientific notation globally
options(scipen = 999)

# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 1) Count grids in each group ---
group_counts <- df_latest %>%
  group_by(mine_group) %>%
  summarise(N_grids = n(), .groups = "drop")

# Extract counts
N_no_mines <- group_counts$N_grids[group_counts$mine_group == "No mines"]
N_mines    <- group_counts$N_grids[group_counts$mine_group == ">=1 mine"]

# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
  mutate(
    N_no_mines = N_no_mines,
    N_mines    = N_mines
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 3) View table ---

#turn of pagination for tables
DT::datatable(
  t_test_results_clean,
  options = list(
    pageLength = nrow(t_test_results_clean),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA
NA

###Mining vs. non-mining grids (excluding grids with fewer than 25 people)

This is the same table as the one above, except now I’m restricting to grid cells with at least 25 people. The results are generally consistent with the patterns in the previous table.

#descriptive stats (means table) mining vs non_mining (population >= 25)####
# 1) Restrict to latest year where all vars exist (2021)
df_latest_pop <- df_latest %>%
  filter(pop >= 25) 

# 2) Variables to summarize
vars <- c(
  "dist_to_border",
  "forest","grassland","impervious","irrigated_crops",
  "nightlights","other_crops","permanent_water",
  "rainfed_crops","seasonal_water","shrubland",
  "sparse","swamp","pop", "n_conflicts", "n_battles", "n_protests"
)

# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
  if (is.numeric(x)) return(x)
  if (is.factor(x))  return(as.numeric(as.character(x)))
  if (is.character(x)) return(suppressWarnings(as.numeric(x)))
  return(suppressWarnings(as.numeric(x)))
}

# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
  x <- to_num(df_latest_pop[[v]])
  g <- df_latest_pop$mine_group
  
  # group means
  m0 <- mean(x[g == "No mines"], na.rm = TRUE)
  m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
  
  # t-test (Welch)
  tt <- t.test(x ~ g)
  
  data.frame(
    variable = v,
    mean_no_mines = m0,
    mean_mines = m1,
    p_value = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(sig = case_when(
    p_value < 0.001 ~ "***",
    p_value < 0.01  ~ "**",
    p_value < 0.05  ~ "*",
    TRUE ~ ""
  ))



# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 1) Count grids in each group ---
group_counts <- df_latest_pop %>%
  group_by(mine_group) %>%
  summarise(N_grids = n(), .groups = "drop")

# Extract counts
N_no_mines <- group_counts$N_grids[group_counts$mine_group == "No mines"]
N_mines    <- group_counts$N_grids[group_counts$mine_group == ">=1 mine"]

# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
  mutate(
    N_no_mines = N_no_mines,
    N_mines    = N_mines
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 3) View table ---
#turn of pagination for tables
DT::datatable(
  t_test_results_clean,
  options = list(
    pageLength = nrow(t_test_results_clean),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA

###Mineral type treatment categories (3TG vs. non-3TG mines)

Here I’m again restricting to mining grids, but comparing grids that mine the 3TG (tin,tantalum, tungsten, and gold) with grids that mine other materials. The 3TG are the minerals covered by the DF Act. This is the alternate identification strategy I want to explore in paper 3. There is only one grid cell with both 3TG and non-3TG mines.Here we see that: - 3TG grids have more crops (irrigated and rainfed) - Much higher population in non-3TG mining grids, which tracks with impervious surfaces and nightlights - More battles in 3TG grids, more protests in non-DF grids

#descriptive stats (means table) df vs non df mining grids####
# 1) Restrict to latest year where all vars exist (2021)
df_latest_mining <- df_latest %>%
  filter(mine_group == ">=1 mine") 

# 2) Variables to summarize
vars <- c(
  "dist_to_border",
  "forest","grassland","impervious","irrigated_crops",
  "nightlights","other_crops","permanent_water",
  "rainfed_crops","seasonal_water","shrubland",
  "sparse","swamp","pop",
  "n_conflicts","n_battles","n_protests"
)

# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
  if (is.numeric(x)) return(x)
  if (is.factor(x))  return(as.numeric(as.character(x)))
  if (is.character(x)) return(suppressWarnings(as.numeric(x)))
  return(suppressWarnings(as.numeric(x)))
}

# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
  x <- to_num(df_latest_mining[[v]])
  g <- df_latest_mining$has_df_mine_dummy
  
  # group means
  m0 <- mean(x[g == 0], na.rm = TRUE)
  m1 <- mean(x[g == 1], na.rm = TRUE)
  
  # t-test (Welch)
  tt <- t.test(x ~ g)
  
  data.frame(
    variable = v,
    mean_non_df = m0,
    mean_df = m1,
    p_value = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(sig = case_when(
    p_value < 0.001 ~ "***",
    p_value < 0.01  ~ "**",
    p_value < 0.05  ~ "*",
    TRUE ~ ""
  ))


# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 1) Count grids in each group ---
group_counts <- df_latest_mining %>%
  group_by(has_df_mine_dummy) %>%
  summarise(N_grids = n(), .groups = "drop")

# Extract counts
N_non_df_mines <- group_counts$N_grids[group_counts$has_df_mine_dummy == 0]
N_df_mines    <- group_counts$N_grids[group_counts$has_df_mine_dummy == 1]

# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
  mutate(
    N_non_df_mines = N_non_df_mines,
    N_df_mines    = N_df_mines
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 3) View table ---
DT::datatable(
  t_test_results_clean,
  options = list(
    pageLength = nrow(t_test_results_clean),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA

###Parker and Vadheim/Dodd-Frank treated grids vs. untreated grids

Now I’m looking only a mining grids, comparing grids that were “treated” per the PV study (i.e. that are located in conflict affected mining areas per the 2011 State Department map) to untreated mining grids per the PV study: - There is less of a population delta than in the previous table (the 3TG vs. non-3TG mining grid comparison). I’m not sure what this means in terms of thinking through PV’s vs. my identification strategy. - No statistically significant difference in mean conflict counts in PV-DF treated vs. untreated mining grids. Again, not sure what that implies.

# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
  if (is.numeric(x)) return(x)
  if (is.factor(x))  return(as.numeric(as.character(x)))
  if (is.character(x)) return(suppressWarnings(as.numeric(x)))
  return(suppressWarnings(as.numeric(x)))
}

# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
  x <- to_num(df_latest_mining[[v]])
  g <- df_latest_mining$policy_terr
  
  # group means
  m0 <- mean(x[g == 0], na.rm = TRUE)
  m1 <- mean(x[g == 1], na.rm = TRUE)
  
  # t-test (Welch)
  tt <- t.test(x ~ g)
  
  data.frame(
    variable = v,
    mean_non_df = m0,
    mean_df = m1,
    p_value = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(sig = case_when(
    p_value < 0.001 ~ "***",
    p_value < 0.01  ~ "**",
    p_value < 0.05  ~ "*",
    TRUE ~ ""
  ))



# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 1) Count grids in each group ---
group_counts <- df_latest_mining %>%
  group_by(policy_terr) %>%
  summarise(N_grids = n(), .groups = "drop")

# Extract counts
N_non_df_terr <- group_counts$N_grids[group_counts$policy_terr == 0]
N_df_terr    <- group_counts$N_grids[group_counts$policy_terr == 1]

# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
  mutate(
    N_non_df_terr = N_non_df_terr,
    N_df_terr    = N_df_terr
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# --- 3) View table ---
DT::datatable(
  t_test_results_clean,
  options = list(
    pageLength = nrow(t_test_results_clean),  # show all rows
    paging = FALSE             # turn pagination off
  )
)

##Rate of change (comparing 2003-2006 and 2019-2021)

###Mining vs. non-mining grids - More deforestation in mining grids - More cropland growth (irrigated, rainfed) in mining grids - More population growth in mining grids - Larger increase in conflict in mining grids

#annual changes mining v. non-mining####
# -----------------------------
# 0) Choose the yearly variables (edit this list if you want)
# -----------------------------
yearly_vars <- c(
  "forest","grassland","impervious","irrigated_crops",
  "nightlights","other_crops","permanent_water",
  "rainfed_crops","seasonal_water","shrubland","sparse","swamp","pop",
  "n_conflicts","n_battles","n_protests"
)

# helper: coerce to numeric safely (handles factor/character numbers)
to_num <- function(x) {
  if (is.numeric(x)) return(x)
  if (is.factor(x))  return(as.numeric(as.character(x)))
  if (is.character(x)) return(suppressWarnings(as.numeric(x)))
  return(suppressWarnings(as.numeric(x)))
}

# -----------------------------
# 1) Create a static mine group per hex_id (No mines vs >=1 mine)
#    Uses the maximum total_mine_count observed for each hex (robust)
# -----------------------------
mine_group_by_hex <- panel_p3_yearly %>%
  group_by(hex_id) %>%
  summarise(
    total_mine_count_static = max(to_num(total_mine_count), na.rm = TRUE),
    mine_group = ifelse(total_mine_count_static == 0, "No mines", ">=1 mine"),
    .groups = "drop"
  )

# -----------------------------
# 2) Compute hex-level averages in each period, then change (post - pre)
# -----------------------------
hex_period_avgs <- panel_p3_yearly %>%
  select(hex_id, year, all_of(yearly_vars)) %>%
  mutate(year = to_num(year)) %>%
  filter(year %in% c(2003:2006, 2019:2021)) %>%
  mutate(period = ifelse(year <= 2006, "pre_2003_06", "post_2019_21")) %>%
  # ensure vars numeric
  mutate(across(all_of(yearly_vars), to_num)) %>%
  group_by(hex_id, period) %>%
  summarise(across(all_of(yearly_vars), ~ mean(.x, na.rm = TRUE)), .groups = "drop") %>%
  pivot_wider(
    names_from = period,
    values_from = all_of(yearly_vars),
    names_sep = "__"
  )

# compute change for each var: post - pre
# Join mine group onto the wide period-averaged data
tmp <- hex_period_avgs %>%
  left_join(mine_group_by_hex, by = "hex_id")

# Create change columns: post - pre
for (v in yearly_vars) {
  post_col <- paste0(v, "__post_2019_21")
  pre_col  <- paste0(v, "__pre_2003_06")
  tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}

# Keep only what you need
hex_changes <- tmp %>%
  select(hex_id, mine_group, starts_with("chg__"))

# -----------------------------
# 3) Compare mean changes across mine groups (Welch t-test), build table
# -----------------------------
chg_vars <- paste0("chg__", yearly_vars)

diff_in_changes <- lapply(chg_vars, function(v) {
  x <- hex_changes[[v]]
  g <- hex_changes$mine_group
  
  ok <- !is.na(x) & !is.na(g)
  x <- x[ok]; g <- g[ok]
  
  m0 <- mean(x[g == "No mines"], na.rm = TRUE)
  m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
  
  tt <- t.test(x ~ g)  # Welch
  
  data.frame(
    variable = sub("^chg__", "", v),
    mean_change_no_mines = m0,
    mean_change_mines    = m1,
    diff_change          = m1 - m0,
    p_value              = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(
    sig = case_when(
      p_value < 0.001 ~ "***",
      p_value < 0.01  ~ "**",
      p_value < 0.05  ~ "*",
      TRUE ~ ""
    )
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# group Ns (number of hexes contributing to the change analysis)
group_Ns <- hex_changes %>%
  count(mine_group)

group_Ns

DT::datatable(
  diff_in_changes,
  options = list(
    pageLength = nrow(diff_in_changes),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

###Mining vs. non-mining grids (excluding grids with fewer than 25 people)

Same table as the one above but restricting to grids with at least 25 people. Results generally track with the previous table.

#annual changes mining v. non-mining (pop>=25)####


# -----------------------------------
# 1) Restrict to hexes with pre-period avg pop >= 25
# -----------------------------------

hex_changes_pop25 <- hex_period_avgs %>%
  left_join(mine_group_by_hex, by = "hex_id") %>%
  filter(pop__pre_2003_06 >= 25)

# -----------------------------------
# 2) Create change variables
# -----------------------------------

tmp <- hex_changes_pop25

for (v in yearly_vars) {
  post_col <- paste0(v, "__post_2019_21")
  pre_col  <- paste0(v, "__pre_2003_06")
  tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}

hex_changes_pop25 <- tmp %>%
  select(hex_id, mine_group, starts_with("chg__"))

# -----------------------------------
# 3) Compare mean changes across mine groups
# -----------------------------------

chg_vars <- paste0("chg__", yearly_vars)

diff_in_changes_pop25 <- lapply(chg_vars, function(v) {
  
  x <- hex_changes_pop25[[v]]
  g <- hex_changes_pop25$mine_group
  
  ok <- !is.na(x) & !is.na(g)
  x <- x[ok]; g <- g[ok]
  
  m0 <- mean(x[g == "No mines"], na.rm = TRUE)
  m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
  
  tt <- t.test(x ~ g)
  
  data.frame(
    variable = sub("^chg__", "", v),
    mean_change_no_mines = m0,
    mean_change_mines    = m1,
    diff_change          = m1 - m0,
    p_value              = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(
    sig = case_when(
      p_value < 0.001 ~ "***",
      p_value < 0.01  ~ "**",
      p_value < 0.05  ~ "*",
      TRUE ~ ""
    )
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# -----------------------------------
# 4) Group counts
# -----------------------------------

group_Ns_pop25 <- hex_changes_pop25 %>%
  count(mine_group)

group_Ns_pop25

DT::datatable(
  diff_in_changes_pop25,
  options = list(
    pageLength = nrow(diff_in_changes_pop25),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA

###Mineral type treatment categories (3TG vs. non-3TG mines)

#annual changes df vs. non df mineral grids####
# ------------------------------------------------------------
# 1) Build a hex-level DF grouping variable, and restrict to mining grids
# ------------------------------------------------------------
df_group_by_hex <- panel_p3_yearly %>%
  group_by(hex_id) %>%
  summarise(
    total_mine_count_static = first(na.omit(to_num(total_mine_count))),
    has_df_static           = first(na.omit(to_num(has_df_mine_dummy))),
    df_group = ifelse(has_df_static == 1, "DF mine", "Non-DF mine"),
    .groups = "drop"
  ) %>%
  filter(total_mine_count_static >= 1)

# ------------------------------------------------------------
# 2) Join onto the period-average wide data and compute changes
# ------------------------------------------------------------
tmp <- hex_period_avgs %>%
  inner_join(df_group_by_hex %>% select(hex_id, df_group), by = "hex_id")

# change columns: post - pre
for (v in yearly_vars) {
  post_col <- paste0(v, "__post_2019_21")
  pre_col  <- paste0(v, "__pre_2003_06")
  tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}

hex_changes_df_vs_nondf <- tmp %>%
  select(hex_id, df_group, starts_with("chg__"))

# ------------------------------------------------------------
# 3) Compare mean changes across DF vs non-DF (Welch t-tests)
# ------------------------------------------------------------
chg_vars <- paste0("chg__", yearly_vars)

diff_in_changes_df_vs_nondf <- lapply(chg_vars, function(v) {
  
  x <- hex_changes_df_vs_nondf[[v]]
  g <- hex_changes_df_vs_nondf$df_group
  
  ok <- !is.na(x) & !is.na(g)
  x <- x[ok]; g <- g[ok]
  
  m0 <- mean(x[g == "Non-DF mine"], na.rm = TRUE)
  m1 <- mean(x[g == "DF mine"], na.rm = TRUE)
  
  tt <- t.test(x ~ g)  # Welch
  
  data.frame(
    variable = sub("^chg__", "", v),
    mean_change_non_df = m0,
    mean_change_df     = m1,
    diff_change        = m1 - m0,
    p_value            = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(
    sig = case_when(
      p_value < 0.001 ~ "***",
      p_value < 0.01  ~ "**",
      p_value < 0.05  ~ "*",
      TRUE ~ ""
    )
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# ------------------------------------------------------------
# 4) Group counts
# ------------------------------------------------------------
group_Ns_df_vs_nondf <- hex_changes_df_vs_nondf %>%
  count(df_group)

group_Ns_df_vs_nondf

DT::datatable(
  diff_in_changes_df_vs_nondf,
  options = list(
    pageLength = nrow(diff_in_changes_df_vs_nondf),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA

###Parker and Vadheim/Dodd-Frank mining grids vs. non-DF mining grids

#annual changes df vs. non df policy grids####
# ------------------------------------------------------------
# 1) Build a hex-level DF grouping variable, and restrict to mining grids
# ------------------------------------------------------------
df_group_by_hex <- panel_p3_yearly %>%
  group_by(hex_id) %>%
  summarise(
    total_mine_count_static = first(na.omit(to_num(total_mine_count))),
    has_policy_static           = first(na.omit(to_num(policy_terr))),
    policy_group = ifelse(has_policy_static == 1, "DF mine", "Non-DF mine"),
    .groups = "drop"
  ) %>%
  filter(total_mine_count_static >= 1)

# ------------------------------------------------------------
# 2) Join onto the period-average wide data and compute changes
# ------------------------------------------------------------
tmp <- hex_period_avgs %>%
  inner_join(df_group_by_hex %>% select(hex_id, policy_group), by = "hex_id")

# change columns: post - pre
for (v in yearly_vars) {
  post_col <- paste0(v, "__post_2019_21")
  pre_col  <- paste0(v, "__pre_2003_06")
  tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}

hex_changes_df_vs_nondf <- tmp %>%
  select(hex_id, policy_group, starts_with("chg__"))

# ------------------------------------------------------------
# 3) Compare mean changes across DF vs non-DF (Welch t-tests)
# ------------------------------------------------------------
chg_vars <- paste0("chg__", yearly_vars)

diff_in_changes_df_vs_nondf <- lapply(chg_vars, function(v) {
  
  x <- hex_changes_df_vs_nondf[[v]]
  g <- hex_changes_df_vs_nondf$policy_group
  
  ok <- !is.na(x) & !is.na(g)
  x <- x[ok]; g <- g[ok]
  
  m0 <- mean(x[g == "Non-DF mine"], na.rm = TRUE)
  m1 <- mean(x[g == "DF mine"], na.rm = TRUE)
  
  tt <- t.test(x ~ g)  # Welch
  
  data.frame(
    variable = sub("^chg__", "", v),
    mean_change_non_df = m0,
    mean_change_df     = m1,
    diff_change        = m1 - m0,
    p_value            = tt$p.value
  )
}) %>%
  bind_rows() %>%
  mutate(
    sig = case_when(
      p_value < 0.001 ~ "***",
      p_value < 0.01  ~ "**",
      p_value < 0.05  ~ "*",
      TRUE ~ ""
    )
  ) %>%
  mutate(across(where(is.numeric), ~ round(.x, 3)))

# ------------------------------------------------------------
# 4) Group counts
# ------------------------------------------------------------
group_Ns_df_vs_nondf <- hex_changes_df_vs_nondf %>%
  count(policy_group)

group_Ns_df_vs_nondf

DT::datatable(
  diff_in_changes_df_vs_nondf,
  options = list(
    pageLength = nrow(diff_in_changes_df_vs_nondf),  # show all rows
    paging = FALSE             # turn pagination off
  )
)
NA

#Regressions

##Outcome: Pr(Battle Occurence)

###PV baseline model but with grids Looking at the outcome: probability of any battle occurring. Same as PV study but using grid cells instead of territories as the unit of analysis (so a much smaller united of analysis that doesn’t follow political boundaries). Only policy_dummy (indicator for grids in a territory flagged as conflict-affected by State Dep in 2008-2010) is stat sig (at ***, 0.000187). Interaction terms with number of mine variables aren’t.

#any battles, matching PV but at grid vs. territory level####
mod <- feols(
  any_battles ~ policy_dummy + policy_dummy:is_3t_count + policy_dummy:is_gold_count | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117854
                 Within R2: 2.187e-5

###PV baseline model with grid-level treatment assignment

Now I’m assigning treatment at the grid level, rather than at the territory level, based on whether the grid is in a State Department policy territory + has a 3TG mine. When I assign treatment more granularly, the treatment effect goes away.

#any battles, matching PV but at grid vs. territory level####
mod <- feols(
  any_battles ~ df_policy_grids + df_policy_grids:is_3t_count + df_policy_grids:is_gold_count | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117839
                 Within R2: 4.347e-6

###Government ban treatment

Now I”m ignoring Dodd-Frank and looking instead at the government ban on artisanal mining that occurred at the same time that DF was passed. Here I’m using the same approach as PV (but at the grid level vs territory level). The ban covered 3 provinces, which encompass 44 of the 51 treated territories in the PV study. There is a reduction in the probability of experiencing a battle in gov_ban provinces.


#what if we just look at the gov ban####
mod <- feols(
  any_battles ~ gov_ban + gov_ban:is_3t_count + gov_ban:is_gold_count | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.11784 
                 Within R2: 5.427e-6

###Government ban assigned at the grid level

Now I’m assigning the same government ban treatment but at the grid level instead of at the territory level, based on whether the grid is in a province targeted by the government ban + has a 3TG mine. When I assign treatment more granularly, the coefficient on the Pr(battle) remains negative, but now the interaction term with the number of gold mines becomes statistically significant (and is positive).

#what if we assign gov ban treatment at the grid level
mod <- feols(
  any_battles ~ gov_ban_grids + gov_ban_grids:is_3t_count + gov_ban_grids:is_gold_count | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117839
                 Within R2: 4.331e-6

###Both PV-DF treatment and government ban

Now I’m looking at the PV-DF treatment + government ban simultaneously. First regression has treatment assigned at the territory or province level. Second regression has treatment assigned at the grid level. When treatment is assigned at the territory/province level, the two policies work in opposite directions and are both statistically significant. When treatment is assigned at the grid level, they are both negative and stat insignificant.


#what is we look at both df and gov grids
mod <- feols(
  any_battles ~ policy_dummy + gov_ban | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117856
                 Within R2: 2.34e-5 
#same regression but with treatment assigned at the grid level
mod <- feols(
  any_battles ~ df_policy_grids + gov_ban_grids | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117837
                 Within R2: 2.95e-6 

###Alternate treatment timing (May 2013)

Now I’m exploring whether using a later treatment starting time changes the original PV results. Specifically, while Dodd-Frank was passed in July 2010, companies didn’t have to file their first conflict mineral disclosure reports until May 2014. I’m using June 2013 – one year before the first company filing – as my alternate treatment start timing. I’m also extending the timeframe from 2012 (PV study) to 2020. All three coefficients of interest are positive and statistically significant.

#May 2013 treatment####

mod <- feols(
  any_battles ~ policy_dummy_2013 + policy_dummy_2013:is_3t_count + policy_dummy_2013:is_gold_count | hex_id + time_id,
  data = full_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 14,220,636
Fixed-effects: hex_id: 69,709,  time_id: 204
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.015611     Adj. R2: 0.088314
                 Within R2: 1.772e-4

###Mineral type treatment assignment

Now I’m exploring the use of an alternate treatment assignment based on whether the grid cell has a 3TG mine vs non-3TG mine. First regression uses the July 2010 treatment timing, second the June 2013 timing. Both show a positive, statistically significant treatment effect.

#Mineral type treatment and 2010 or 2013 treatment####
#2013
panel_month <- panel_month %>%
  mutate(
    policy_dummy_2013_timeonly = as.integer(time_id >= 201306L)
  )

full_months_grids <- panel_month %>%
  dplyr::filter(
    year >= 2004,
    year <= 2020,
    eastern_terr == 1
  )

#2010
panel_month <- panel_month %>%
  mutate(
    policy_dummy_2010_timeonly = as.integer(time_id >= 201007L)
  )



pv_months_grids <- panel_month %>%
  dplyr::filter(
    year >= 2004,
    year <= 2012,
    eastern_terr == 1
  )

#2013 reg
mod <- feols(
  any_battles ~ policy_dummy_2013_timeonly:has_df_mine_dummy | hex_id + time_id,
  data = full_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 14,220,636
Fixed-effects: hex_id: 69,709,  time_id: 204
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.015612     Adj. R2: 0.088213
                 Within R2: 6.65e-5 
#2010 reg
mod <- feols(
  any_battles ~ policy_dummy_2010_timeonly:has_df_mine_dummy | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095     Adj. R2: 0.117844
                 Within R2: 1.032e-5

Here I’m introducing some yearly covariates (population, nightlights and select land use categories). This is the baseline PV specification (2010 treatment, State Department map). Interesting that while the policy summy remains positive and statistically significant, the interaction term on the number of gold mines does not. The only covariate that seems to pop is rainfed crops.

#baseline PV with RS controls

mod <- feols(
  any_battles ~ policy_dummy + policy_dummy:is_3t_count + policy_dummy:is_gold_count + pop + nightlights + irrigated_crops + rainfed_crops + forest | hex_id + time_id,
  data = pv_months_grids
)

# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709,  time_id: 108
Standard-errors: Clustered (hex_id) 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010092     Adj. R2: 0.118337
                 Within R2: 5.704e-4

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tDQp0aXRsZTogIlBhcGVyIDMvRFJDIEV4cGxvcmF0b3J5IFJlZ3MiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCiNsb2FkIGxpYnJhcmllcw0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGZpeGVzdCkNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoc2YpDQoNCmBgYA0KDQpgYGB7cn0NCiMgVHVybiBvZmYgc2NpZW50aWZpYyBub3RhdGlvbiBnbG9iYWxseQ0KI29wdGlvbnMoc2NpcGVuID0gOTk5KQ0KDQojbG9hZCByZWxldmFudCBmaWxlcw0KI3JlYWRSRFMoIkM6L1VzZXJzL3lvc2hpYXJhL09uZURyaXZlIC0gUkFORCBDb3Jwb3JhdGlvbi9EZXNrdG9wL0Rpc3NlcnRhdGlvbi9lYXN0ZXJuIGRyYy9wYW5lbF9wM195ZWFybHkucmRzIikNCg0Kc2V0d2QoIkM6L1VzZXJzL3lvc2hpYXJhL09uZURyaXZlIC0gUkFORCBDb3Jwb3JhdGlvbi9EZXNrdG9wL0Rpc3NlcnRhdGlvbi9lYXN0ZXJuIGRyYyIpDQpgYGANCg0KDQojRGVzY3JpcHRpdmUgU3RhdHMNCg0KIyNDcm9zcy1zZWN0aW9uYWwgKDIwMjEgb25seSkNCg0KIyMjTWluaW5nIHZzLiBub24tbWluaW5nIGdyaWRzDQoNCldoYXQgZG8gbWluaW5nIHZzLiBub24tbWluaW5nIGdyaWQgY2VsbHMgbG9vayBsaWtlPyBUYWJsZSBiZWxvdyBpbmNsdWRlcyBncmlkcyBjb3ZlcmluZyBhbGwgb2YgRFJDLiBTb21lIHRoaW5ncyB0aGF0IHN0YW5kIG91dDoNCi0gTWluaW5nIGdyaWRzIGFyZSBjbG9zZXIgdG8gbmF0aW9uYWwgYm9yZGVycw0KLSBNaW5pbmcgZ3JpZHMgaGF2ZSBtb3JlIGNyb3BsYW5kIChhbGwgdHlwZXMgLSBpcnJpZ2F0ZWQsIHJhaW5mZWQsIG90aGVyKS4gRm9yIGFsbCBncmlkcywgdGhlcmUgaXMgbW9yZSByYWluZmVkIHRoYW4gaXJyaWdhdGVkIGNyb3BsYW5kLg0KLSBNaW5pbmcgZ3JpZHMgaGF2ZSBmZXdlciBwZXJtYW5lbnQgYm9kaWVzIG9mIHdhdGVyDQotIE1pbmluZyBncmlkcyBoYXZlIGhpZ2hlciBwb3B1bGF0aW9uIOKAkyBidXQgdGhpcyBjb3VsZCBqdXN0IGJlIGJlY2F1c2UgdGhlIG5vbi1taW5pbmcgZ3JpZHMgbWF5IGNhcHR1cmUgbWFueSB1bnBvcHVsYXRlZCBhcmVhcy4gVGhpcyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBpbXBlcnZpb3VzL21hbm1hZGUgc3VyZmFjZXMgYnV0IG5vdCBmb3IgbmlnaHRsaWdodCBkZW5zaXR5IHdoaWNoIGlzIHRoZSBzYW1lIGZvciBib3RoIG1pbmluZyBhbmQgbm9uLW1pbmluZyBncmlkcyAod2VpcmQpDQotIE1pbmluZyBncmlkcyBoYXZlIGhpZ2hlciBjb25mbGljdCBjb3VudHMgKGFjcm9zcyBhbGwgY29uZmxpY3QgY2F0ZWdvcmllcykNCmBgYHtyfQ0KI2Rlc2NyaXB0aXZlIHN0YXRzIChtZWFucyB0YWJsZSkgbWluaW5nIHZzIG5vbl9taW5pbmcjIyMjDQojIDEpIFJlc3RyaWN0IHRvIGxhdGVzdCB5ZWFyIHdoZXJlIGFsbCB2YXJzIGV4aXN0ICgyMDIxKQ0KZGZfbGF0ZXN0IDwtIHBhbmVsX3AzX3llYXJseSAlPiUNCiAgZmlsdGVyKHllYXIgPT0gMjAyMSkgJT4lDQogIG11dGF0ZShtaW5lX2dyb3VwID0gaWZlbHNlKHRvdGFsX21pbmVfY291bnQgPT0gMCwgIk5vIG1pbmVzIiwgIj49MSBtaW5lIikpDQoNCiMgMikgVmFyaWFibGVzIHRvIHN1bW1hcml6ZQ0KdmFycyA8LSBjKA0KICAiZGlzdF90b19ib3JkZXIiLA0KICAiZm9yZXN0IiwiZ3Jhc3NsYW5kIiwiaW1wZXJ2aW91cyIsImlycmlnYXRlZF9jcm9wcyIsDQogICJuaWdodGxpZ2h0cyIsIm90aGVyX2Nyb3BzIiwicGVybWFuZW50X3dhdGVyIiwNCiAgInJhaW5mZWRfY3JvcHMiLCJzZWFzb25hbF93YXRlciIsInNocnVibGFuZCIsDQogICJzcGFyc2UiLCJzd2FtcCIsInBvcCIsICJuX2NvbmZsaWN0cyIsICJuX2JhdHRsZXMiLCAibl9wcm90ZXN0cyINCikNCg0KIyBoZWxwZXI6IGNvZXJjZSB0byBudW1lcmljIGlmIG5lZWRlZCAoaGFuZGxlcyBmYWN0b3JzL2NoYXJhY3RlcnMpDQp0b19udW0gPC0gZnVuY3Rpb24oeCkgew0KICBpZiAoaXMubnVtZXJpYyh4KSkgcmV0dXJuKHgpDQogIGlmIChpcy5mYWN0b3IoeCkpICByZXR1cm4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpKQ0KICBpZiAoaXMuY2hhcmFjdGVyKHgpKSByZXR1cm4oc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKHgpKSkNCiAgcmV0dXJuKHN1cHByZXNzV2FybmluZ3MoYXMubnVtZXJpYyh4KSkpDQp9DQoNCiMgMykgUnVuIHQtdGVzdHMgKyBidWlsZCByZXN1bHRzDQp0X3Rlc3RfcmVzdWx0cyA8LSBsYXBwbHkodmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIHRvX251bShkZl9sYXRlc3RbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3QkbWluZV9ncm91cA0KICANCiAgIyBncm91cCBtZWFucw0KICBtMCA8LSBtZWFuKHhbZyA9PSAiTm8gbWluZXMiXSwgbmEucm0gPSBUUlVFKQ0KICBtMSA8LSBtZWFuKHhbZyA9PSAiPj0xIG1pbmUiXSwgbmEucm0gPSBUUlVFKQ0KICANCiAgIyB0LXRlc3QgKFdlbGNoKQ0KICB0dCA8LSB0LnRlc3QoeCB+IGcpDQogIA0KICBkYXRhLmZyYW1lKA0KICAgIHZhcmlhYmxlID0gdiwNCiAgICBtZWFuX25vX21pbmVzID0gbTAsDQogICAgbWVhbl9taW5lcyA9IG0xLA0KICAgIHBfdmFsdWUgPSB0dCRwLnZhbHVlDQogICkNCn0pICU+JQ0KICBiaW5kX3Jvd3MoKSAlPiUNCiAgbXV0YXRlKHNpZyA9IGNhc2Vfd2hlbigNCiAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgIHBfdmFsdWUgPCAwLjA1ICB+ICIqIiwNCiAgICBUUlVFIH4gIiINCiAgKSkNCg0KDQoNCiMgUm91bmQgbnVtZXJpYyBjb2x1bW5zIHRvIDMgZGVjaW1hbHMNCnRfdGVzdF9yZXN1bHRzX2NsZWFuIDwtIHRfdGVzdF9yZXN1bHRzICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tIDEpIENvdW50IGdyaWRzIGluIGVhY2ggZ3JvdXAgLS0tDQpncm91cF9jb3VudHMgPC0gZGZfbGF0ZXN0ICU+JQ0KICBncm91cF9ieShtaW5lX2dyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9fbWluZXMgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJG1pbmVfZ3JvdXAgPT0gIk5vIG1pbmVzIl0NCk5fbWluZXMgICAgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJG1pbmVfZ3JvdXAgPT0gIj49MSBtaW5lIl0NCg0KIyAtLS0gMikgQWRkIGNvdW50cyB0byByZXN1bHRzIHRhYmxlIC0tLQ0KdF90ZXN0X3Jlc3VsdHNfY2xlYW4gPC0gdF90ZXN0X3Jlc3VsdHMgJT4lDQogIG11dGF0ZSgNCiAgICBOX25vX21pbmVzID0gTl9ub19taW5lcywNCiAgICBOX21pbmVzICAgID0gTl9taW5lcw0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tIDMpIFZpZXcgdGFibGUgLS0tDQoNCiN0dXJuIG9mIHBhZ2luYXRpb24gZm9yIHRhYmxlcw0KRFQ6OmRhdGF0YWJsZSgNCiAgdF90ZXN0X3Jlc3VsdHNfY2xlYW4sDQogIG9wdGlvbnMgPSBsaXN0KA0KICAgIHBhZ2VMZW5ndGggPSBucm93KHRfdGVzdF9yZXN1bHRzX2NsZWFuKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCg0KYGBgDQojIyNNaW5pbmcgdnMuIG5vbi1taW5pbmcgZ3JpZHMgKGV4Y2x1ZGluZyBncmlkcyB3aXRoIGZld2VyIHRoYW4gMjUgcGVvcGxlKQ0KDQpUaGlzIGlzIHRoZSBzYW1lIHRhYmxlIGFzIHRoZSBvbmUgYWJvdmUsIGV4Y2VwdCBub3cgSSdtIHJlc3RyaWN0aW5nIHRvIGdyaWQgY2VsbHMgd2l0aCBhdCBsZWFzdCAyNSBwZW9wbGUuIFRoZSByZXN1bHRzIGFyZSBnZW5lcmFsbHkgY29uc2lzdGVudCB3aXRoIHRoZSBwYXR0ZXJucyBpbiB0aGUgcHJldmlvdXMgdGFibGUuDQpgYGB7cn0NCiNkZXNjcmlwdGl2ZSBzdGF0cyAobWVhbnMgdGFibGUpIG1pbmluZyB2cyBub25fbWluaW5nIChwb3B1bGF0aW9uID49IDI1KSMjIyMNCiMgMSkgUmVzdHJpY3QgdG8gbGF0ZXN0IHllYXIgd2hlcmUgYWxsIHZhcnMgZXhpc3QgKDIwMjEpDQpkZl9sYXRlc3RfcG9wIDwtIGRmX2xhdGVzdCAlPiUNCiAgZmlsdGVyKHBvcCA+PSAyNSkgDQoNCg0KIyAzKSBSdW4gdC10ZXN0cyArIGJ1aWxkIHJlc3VsdHMNCnRfdGVzdF9yZXN1bHRzIDwtIGxhcHBseSh2YXJzLCBmdW5jdGlvbih2KSB7DQogIHggPC0gdG9fbnVtKGRmX2xhdGVzdF9wb3BbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3RfcG9wJG1pbmVfZ3JvdXANCiAgDQogICMgZ3JvdXAgbWVhbnMNCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogICMgdC10ZXN0IChXZWxjaCkNCiAgdHQgPC0gdC50ZXN0KHggfiBnKQ0KICANCiAgZGF0YS5mcmFtZSgNCiAgICB2YXJpYWJsZSA9IHYsDQogICAgbWVhbl9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fbWluZXMgPSBtMSwNCiAgICBwX3ZhbHVlID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZShzaWcgPSBjYXNlX3doZW4oDQogICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgcF92YWx1ZSA8IDAuMDEgIH4gIioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgVFJVRSB+ICIiDQogICkpDQoNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9wb3AgJT4lDQogIGdyb3VwX2J5KG1pbmVfZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoTl9ncmlkcyA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0KIyBFeHRyYWN0IGNvdW50cw0KTl9ub19taW5lcyA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkbWluZV9ncm91cCA9PSAiTm8gbWluZXMiXQ0KTl9taW5lcyAgICA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkbWluZV9ncm91cCA9PSAiPj0xIG1pbmUiXQ0KDQojIC0tLSAyKSBBZGQgY291bnRzIHRvIHJlc3VsdHMgdGFibGUgLS0tDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKA0KICAgIE5fbm9fbWluZXMgPSBOX25vX21pbmVzLA0KICAgIE5fbWluZXMgICAgPSBOX21pbmVzDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCiN0dXJuIG9mIHBhZ2luYXRpb24gZm9yIHRhYmxlcw0KRFQ6OmRhdGF0YWJsZSgNCiAgdF90ZXN0X3Jlc3VsdHNfY2xlYW4sDQogIG9wdGlvbnMgPSBsaXN0KA0KICAgIHBhZ2VMZW5ndGggPSBucm93KHRfdGVzdF9yZXN1bHRzX2NsZWFuKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KIyMjTWluZXJhbCB0eXBlIHRyZWF0bWVudCBjYXRlZ29yaWVzICgzVEcgdnMuIG5vbi0zVEcgbWluZXMpDQoNCkhlcmUgSSdtIGFnYWluIHJlc3RyaWN0aW5nIHRvIG1pbmluZyBncmlkcywgYnV0IGNvbXBhcmluZyBncmlkcyB0aGF0IG1pbmUgdGhlIDNURyAodGluLHRhbnRhbHVtLCB0dW5nc3RlbiwgYW5kIGdvbGQpIHdpdGggZ3JpZHMgdGhhdCBtaW5lIG90aGVyIG1hdGVyaWFscy4gVGhlIDNURyBhcmUgdGhlIG1pbmVyYWxzIGNvdmVyZWQgYnkgdGhlIERGIEFjdC4gVGhpcyBpcyB0aGUgYWx0ZXJuYXRlIGlkZW50aWZpY2F0aW9uIHN0cmF0ZWd5IEkgd2FudCB0byBleHBsb3JlIGluIHBhcGVyIDMuIFRoZXJlIGlzIG9ubHkgb25lIGdyaWQgY2VsbCB3aXRoIGJvdGggM1RHIGFuZCBub24tM1RHIG1pbmVzLkhlcmUgd2Ugc2VlIHRoYXQ6DQotIDNURyBncmlkcyBoYXZlIG1vcmUgY3JvcHMgKGlycmlnYXRlZCBhbmQgcmFpbmZlZCkNCi0gTXVjaCBoaWdoZXIgcG9wdWxhdGlvbiBpbiBub24tM1RHIG1pbmluZyBncmlkcywgd2hpY2ggdHJhY2tzIHdpdGggaW1wZXJ2aW91cyBzdXJmYWNlcyBhbmQgbmlnaHRsaWdodHMNCi0gTW9yZSBiYXR0bGVzIGluIDNURyBncmlkcywgbW9yZSBwcm90ZXN0cyBpbiBub24tREYgZ3JpZHMNCmBgYHtyfQ0KI2Rlc2NyaXB0aXZlIHN0YXRzIChtZWFucyB0YWJsZSkgZGYgdnMgbm9uIGRmIG1pbmluZyBncmlkcyMjIyMNCiMgMSkgUmVzdHJpY3QgdG8gbGF0ZXN0IHllYXIgd2hlcmUgYWxsIHZhcnMgZXhpc3QgKDIwMjEpDQpkZl9sYXRlc3RfbWluaW5nIDwtIGRmX2xhdGVzdCAlPiUNCiAgZmlsdGVyKG1pbmVfZ3JvdXAgPT0gIj49MSBtaW5lIikgDQoNCg0KIyAzKSBSdW4gdC10ZXN0cyArIGJ1aWxkIHJlc3VsdHMNCnRfdGVzdF9yZXN1bHRzIDwtIGxhcHBseSh2YXJzLCBmdW5jdGlvbih2KSB7DQogIHggPC0gdG9fbnVtKGRmX2xhdGVzdF9taW5pbmdbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3RfbWluaW5nJGhhc19kZl9taW5lX2R1bW15DQogIA0KICAjIGdyb3VwIG1lYW5zDQogIG0wIDwtIG1lYW4oeFtnID09IDBdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09IDFdLCBuYS5ybSA9IFRSVUUpDQogIA0KICAjIHQtdGVzdCAoV2VsY2gpDQogIHR0IDwtIHQudGVzdCh4IH4gZykNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSB2LA0KICAgIG1lYW5fbm9uX2RmID0gbTAsDQogICAgbWVhbl9kZiA9IG0xLA0KICAgIHBfdmFsdWUgPSB0dCRwLnZhbHVlDQogICkNCn0pICU+JQ0KICBiaW5kX3Jvd3MoKSAlPiUNCiAgbXV0YXRlKHNpZyA9IGNhc2Vfd2hlbigNCiAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgIHBfdmFsdWUgPCAwLjA1ICB+ICIqIiwNCiAgICBUUlVFIH4gIiINCiAgKSkNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9taW5pbmcgJT4lDQogIGdyb3VwX2J5KGhhc19kZl9taW5lX2R1bW15KSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9uX2RmX21pbmVzIDwtIGdyb3VwX2NvdW50cyROX2dyaWRzW2dyb3VwX2NvdW50cyRoYXNfZGZfbWluZV9kdW1teSA9PSAwXQ0KTl9kZl9taW5lcyAgICA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkaGFzX2RmX21pbmVfZHVtbXkgPT0gMV0NCg0KIyAtLS0gMikgQWRkIGNvdW50cyB0byByZXN1bHRzIHRhYmxlIC0tLQ0KdF90ZXN0X3Jlc3VsdHNfY2xlYW4gPC0gdF90ZXN0X3Jlc3VsdHMgJT4lDQogIG11dGF0ZSgNCiAgICBOX25vbl9kZl9taW5lcyA9IE5fbm9uX2RmX21pbmVzLA0KICAgIE5fZGZfbWluZXMgICAgPSBOX2RmX21pbmVzDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCkRUOjpkYXRhdGFibGUoDQogIHRfdGVzdF9yZXN1bHRzX2NsZWFuLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyh0X3Rlc3RfcmVzdWx0c19jbGVhbiksICAjIHNob3cgYWxsIHJvd3MNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAgICAgICAjIHR1cm4gcGFnaW5hdGlvbiBvZmYNCiAgKQ0KKQ0KDQpgYGANCiMjI1BhcmtlciBhbmQgVmFkaGVpbS9Eb2RkLUZyYW5rIHRyZWF0ZWQgZ3JpZHMgdnMuIHVudHJlYXRlZCBncmlkcw0KDQpOb3cgSSdtIGxvb2tpbmcgb25seSBhIG1pbmluZyBncmlkcywgY29tcGFyaW5nIGdyaWRzIHRoYXQgd2VyZSAidHJlYXRlZCIgcGVyIHRoZSBQViBzdHVkeSAoaS5lLiB0aGF0IGFyZSBsb2NhdGVkIGluIGNvbmZsaWN0IGFmZmVjdGVkIG1pbmluZyBhcmVhcyBwZXIgdGhlIDIwMTEgU3RhdGUgRGVwYXJ0bWVudCBtYXApIHRvIHVudHJlYXRlZCBtaW5pbmcgZ3JpZHMgcGVyIHRoZSBQViBzdHVkeToNCi0gVGhlcmUgaXMgbGVzcyBvZiBhIHBvcHVsYXRpb24gZGVsdGEgdGhhbiBpbiB0aGUgcHJldmlvdXMgdGFibGUgKHRoZSAzVEcgdnMuIG5vbi0zVEcgbWluaW5nIGdyaWQgY29tcGFyaXNvbikuIEknbSBub3Qgc3VyZSB3aGF0IHRoaXMgbWVhbnMgaW4gdGVybXMgb2YgdGhpbmtpbmcgdGhyb3VnaCBQVidzIHZzLiBteSBpZGVudGlmaWNhdGlvbiBzdHJhdGVneS4NCi0gTm8gc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIG1lYW4gY29uZmxpY3QgY291bnRzIGluIFBWLURGIHRyZWF0ZWQgdnMuIHVudHJlYXRlZCBtaW5pbmcgZ3JpZHMuIEFnYWluLCBub3Qgc3VyZSB3aGF0IHRoYXQgaW1wbGllcy4NCmBgYHtyfQ0KDQoNCiMgMykgUnVuIHQtdGVzdHMgKyBidWlsZCByZXN1bHRzDQp0X3Rlc3RfcmVzdWx0cyA8LSBsYXBwbHkodmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIHRvX251bShkZl9sYXRlc3RfbWluaW5nW1t2XV0pDQogIGcgPC0gZGZfbGF0ZXN0X21pbmluZyRwb2xpY3lfdGVycg0KICANCiAgIyBncm91cCBtZWFucw0KICBtMCA8LSBtZWFuKHhbZyA9PSAwXSwgbmEucm0gPSBUUlVFKQ0KICBtMSA8LSBtZWFuKHhbZyA9PSAxXSwgbmEucm0gPSBUUlVFKQ0KICANCiAgIyB0LXRlc3QgKFdlbGNoKQ0KICB0dCA8LSB0LnRlc3QoeCB+IGcpDQogIA0KICBkYXRhLmZyYW1lKA0KICAgIHZhcmlhYmxlID0gdiwNCiAgICBtZWFuX25vbl9kZiA9IG0wLA0KICAgIG1lYW5fZGYgPSBtMSwNCiAgICBwX3ZhbHVlID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZShzaWcgPSBjYXNlX3doZW4oDQogICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgcF92YWx1ZSA8IDAuMDEgIH4gIioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgVFJVRSB+ICIiDQogICkpDQoNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9taW5pbmcgJT4lDQogIGdyb3VwX2J5KHBvbGljeV90ZXJyKSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9uX2RmX3RlcnIgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJHBvbGljeV90ZXJyID09IDBdDQpOX2RmX3RlcnIgICAgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJHBvbGljeV90ZXJyID09IDFdDQoNCiMgLS0tIDIpIEFkZCBjb3VudHMgdG8gcmVzdWx0cyB0YWJsZSAtLS0NCnRfdGVzdF9yZXN1bHRzX2NsZWFuIDwtIHRfdGVzdF9yZXN1bHRzICU+JQ0KICBtdXRhdGUoDQogICAgTl9ub25fZGZfdGVyciA9IE5fbm9uX2RmX3RlcnIsDQogICAgTl9kZl90ZXJyICAgID0gTl9kZl90ZXJyDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCkRUOjpkYXRhdGFibGUoDQogIHRfdGVzdF9yZXN1bHRzX2NsZWFuLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyh0X3Rlc3RfcmVzdWx0c19jbGVhbiksICAjIHNob3cgYWxsIHJvd3MNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAgICAgICAjIHR1cm4gcGFnaW5hdGlvbiBvZmYNCiAgKQ0KKQ0KYGBgDQojI1JhdGUgb2YgY2hhbmdlIChjb21wYXJpbmcgMjAwMy0yMDA2IGFuZCAyMDE5LTIwMjEpDQoNCiMjI01pbmluZyB2cy4gbm9uLW1pbmluZyBncmlkcw0KLSBNb3JlIGRlZm9yZXN0YXRpb24gaW4gbWluaW5nIGdyaWRzDQotIE1vcmUgY3JvcGxhbmQgZ3Jvd3RoIChpcnJpZ2F0ZWQsIHJhaW5mZWQpIGluIG1pbmluZyBncmlkcw0KLSBNb3JlIHBvcHVsYXRpb24gZ3Jvd3RoIGluIG1pbmluZyBncmlkcw0KLSBMYXJnZXIgaW5jcmVhc2UgaW4gY29uZmxpY3QgaW4gbWluaW5nIGdyaWRzDQpgYGB7cn0NCiNhbm51YWwgY2hhbmdlcyBtaW5pbmcgdi4gbm9uLW1pbmluZyMjIyMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMCkgQ2hvb3NlIHRoZSB5ZWFybHkgdmFyaWFibGVzIChlZGl0IHRoaXMgbGlzdCBpZiB5b3Ugd2FudCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCnllYXJseV92YXJzIDwtIGMoDQogICJmb3Jlc3QiLCJncmFzc2xhbmQiLCJpbXBlcnZpb3VzIiwiaXJyaWdhdGVkX2Nyb3BzIiwNCiAgIm5pZ2h0bGlnaHRzIiwib3RoZXJfY3JvcHMiLCJwZXJtYW5lbnRfd2F0ZXIiLA0KICAicmFpbmZlZF9jcm9wcyIsInNlYXNvbmFsX3dhdGVyIiwic2hydWJsYW5kIiwic3BhcnNlIiwic3dhbXAiLCJwb3AiLA0KICAibl9jb25mbGljdHMiLCJuX2JhdHRsZXMiLCJuX3Byb3Rlc3RzIg0KKQ0KDQojIGhlbHBlcjogY29lcmNlIHRvIG51bWVyaWMgc2FmZWx5IChoYW5kbGVzIGZhY3Rvci9jaGFyYWN0ZXIgbnVtYmVycykNCnRvX251bSA8LSBmdW5jdGlvbih4KSB7DQogIGlmIChpcy5udW1lcmljKHgpKSByZXR1cm4oeCkNCiAgaWYgKGlzLmZhY3Rvcih4KSkgIHJldHVybihhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSkpDQogIGlmIChpcy5jaGFyYWN0ZXIoeCkpIHJldHVybihzdXBwcmVzc1dhcm5pbmdzKGFzLm51bWVyaWMoeCkpKQ0KICByZXR1cm4oc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKHgpKSkNCn0NCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAxKSBDcmVhdGUgYSBzdGF0aWMgbWluZSBncm91cCBwZXIgaGV4X2lkIChObyBtaW5lcyB2cyA+PTEgbWluZSkNCiMgICAgVXNlcyB0aGUgbWF4aW11bSB0b3RhbF9taW5lX2NvdW50IG9ic2VydmVkIGZvciBlYWNoIGhleCAocm9idXN0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KbWluZV9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBtYXgodG9fbnVtKHRvdGFsX21pbmVfY291bnQpLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1pbmVfZ3JvdXAgPSBpZmVsc2UodG90YWxfbWluZV9jb3VudF9zdGF0aWMgPT0gMCwgIk5vIG1pbmVzIiwgIj49MSBtaW5lIiksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMikgQ29tcHV0ZSBoZXgtbGV2ZWwgYXZlcmFnZXMgaW4gZWFjaCBwZXJpb2QsIHRoZW4gY2hhbmdlIChwb3N0IC0gcHJlKQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KaGV4X3BlcmlvZF9hdmdzIDwtIHBhbmVsX3AzX3llYXJseSAlPiUNCiAgc2VsZWN0KGhleF9pZCwgeWVhciwgYWxsX29mKHllYXJseV92YXJzKSkgJT4lDQogIG11dGF0ZSh5ZWFyID0gdG9fbnVtKHllYXIpKSAlPiUNCiAgZmlsdGVyKHllYXIgJWluJSBjKDIwMDM6MjAwNiwgMjAxOToyMDIxKSkgJT4lDQogIG11dGF0ZShwZXJpb2QgPSBpZmVsc2UoeWVhciA8PSAyMDA2LCAicHJlXzIwMDNfMDYiLCAicG9zdF8yMDE5XzIxIikpICU+JQ0KICAjIGVuc3VyZSB2YXJzIG51bWVyaWMNCiAgbXV0YXRlKGFjcm9zcyhhbGxfb2YoeWVhcmx5X3ZhcnMpLCB0b19udW0pKSAlPiUNCiAgZ3JvdXBfYnkoaGV4X2lkLCBwZXJpb2QpICU+JQ0KICBzdW1tYXJpc2UoYWNyb3NzKGFsbF9vZih5ZWFybHlfdmFycyksIH4gbWVhbigueCwgbmEucm0gPSBUUlVFKSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBwaXZvdF93aWRlcigNCiAgICBuYW1lc19mcm9tID0gcGVyaW9kLA0KICAgIHZhbHVlc19mcm9tID0gYWxsX29mKHllYXJseV92YXJzKSwNCiAgICBuYW1lc19zZXAgPSAiX18iDQogICkNCg0KIyBjb21wdXRlIGNoYW5nZSBmb3IgZWFjaCB2YXI6IHBvc3QgLSBwcmUNCiMgSm9pbiBtaW5lIGdyb3VwIG9udG8gdGhlIHdpZGUgcGVyaW9kLWF2ZXJhZ2VkIGRhdGENCnRtcCA8LSBoZXhfcGVyaW9kX2F2Z3MgJT4lDQogIGxlZnRfam9pbihtaW5lX2dyb3VwX2J5X2hleCwgYnkgPSAiaGV4X2lkIikNCg0KIyBDcmVhdGUgY2hhbmdlIGNvbHVtbnM6IHBvc3QgLSBwcmUNCmZvciAodiBpbiB5ZWFybHlfdmFycykgew0KICBwb3N0X2NvbCA8LSBwYXN0ZTAodiwgIl9fcG9zdF8yMDE5XzIxIikNCiAgcHJlX2NvbCAgPC0gcGFzdGUwKHYsICJfX3ByZV8yMDAzXzA2IikNCiAgdG1wW1twYXN0ZTAoImNoZ19fIiwgdildXSA8LSB0bXBbW3Bvc3RfY29sXV0gLSB0bXBbW3ByZV9jb2xdXQ0KfQ0KDQojIEtlZXAgb25seSB3aGF0IHlvdSBuZWVkDQpoZXhfY2hhbmdlcyA8LSB0bXAgJT4lDQogIHNlbGVjdChoZXhfaWQsIG1pbmVfZ3JvdXAsIHN0YXJ0c193aXRoKCJjaGdfXyIpKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDMpIENvbXBhcmUgbWVhbiBjaGFuZ2VzIGFjcm9zcyBtaW5lIGdyb3VwcyAoV2VsY2ggdC10ZXN0KSwgYnVpbGQgdGFibGUNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmNoZ192YXJzIDwtIHBhc3RlMCgiY2hnX18iLCB5ZWFybHlfdmFycykNCg0KZGlmZl9pbl9jaGFuZ2VzIDwtIGxhcHBseShjaGdfdmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIGhleF9jaGFuZ2VzW1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlcyRtaW5lX2dyb3VwDQogIA0KICBvayA8LSAhaXMubmEoeCkgJiAhaXMubmEoZykNCiAgeCA8LSB4W29rXTsgZyA8LSBnW29rXQ0KICANCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fY2hhbmdlX21pbmVzICAgID0gbTEsDQogICAgZGlmZl9jaGFuZ2UgICAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICAgID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZSgNCiAgICBzaWcgPSBjYXNlX3doZW4oDQogICAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICAgIHBfdmFsdWUgPCAwLjAxICB+ICIqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgICBUUlVFIH4gIiINCiAgICApDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyBncm91cCBOcyAobnVtYmVyIG9mIGhleGVzIGNvbnRyaWJ1dGluZyB0byB0aGUgY2hhbmdlIGFuYWx5c2lzKQ0KZ3JvdXBfTnMgPC0gaGV4X2NoYW5nZXMgJT4lDQogIGNvdW50KG1pbmVfZ3JvdXApDQoNCmdyb3VwX05zDQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlcywNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KIyMjTWluaW5nIHZzLiBub24tbWluaW5nIGdyaWRzIChleGNsdWRpbmcgZ3JpZHMgd2l0aCBmZXdlciB0aGFuIDI1IHBlb3BsZSkNCg0KU2FtZSB0YWJsZSBhcyB0aGUgb25lIGFib3ZlIGJ1dCByZXN0cmljdGluZyB0byBncmlkcyB3aXRoIGF0IGxlYXN0IDI1IHBlb3BsZS4gUmVzdWx0cyBnZW5lcmFsbHkgdHJhY2sgd2l0aCB0aGUgcHJldmlvdXMgdGFibGUuDQpgYGB7cn0NCiNhbm51YWwgY2hhbmdlcyBtaW5pbmcgdi4gbm9uLW1pbmluZyAocG9wPj0yNSkjIyMjDQoNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAxKSBSZXN0cmljdCB0byBoZXhlcyB3aXRoIHByZS1wZXJpb2QgYXZnIHBvcCA+PSAyNQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpoZXhfY2hhbmdlc19wb3AyNSA8LSBoZXhfcGVyaW9kX2F2Z3MgJT4lDQogIGxlZnRfam9pbihtaW5lX2dyb3VwX2J5X2hleCwgYnkgPSAiaGV4X2lkIikgJT4lDQogIGZpbHRlcihwb3BfX3ByZV8yMDAzXzA2ID49IDI1KQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIENyZWF0ZSBjaGFuZ2UgdmFyaWFibGVzDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnRtcCA8LSBoZXhfY2hhbmdlc19wb3AyNQ0KDQpmb3IgKHYgaW4geWVhcmx5X3ZhcnMpIHsNCiAgcG9zdF9jb2wgPC0gcGFzdGUwKHYsICJfX3Bvc3RfMjAxOV8yMSIpDQogIHByZV9jb2wgIDwtIHBhc3RlMCh2LCAiX19wcmVfMjAwM18wNiIpDQogIHRtcFtbcGFzdGUwKCJjaGdfXyIsIHYpXV0gPC0gdG1wW1twb3N0X2NvbF1dIC0gdG1wW1twcmVfY29sXV0NCn0NCg0KaGV4X2NoYW5nZXNfcG9wMjUgPC0gdG1wICU+JQ0KICBzZWxlY3QoaGV4X2lkLCBtaW5lX2dyb3VwLCBzdGFydHNfd2l0aCgiY2hnX18iKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAzKSBDb21wYXJlIG1lYW4gY2hhbmdlcyBhY3Jvc3MgbWluZSBncm91cHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KY2hnX3ZhcnMgPC0gcGFzdGUwKCJjaGdfXyIsIHllYXJseV92YXJzKQ0KDQpkaWZmX2luX2NoYW5nZXNfcG9wMjUgPC0gbGFwcGx5KGNoZ192YXJzLCBmdW5jdGlvbih2KSB7DQogIA0KICB4IDwtIGhleF9jaGFuZ2VzX3BvcDI1W1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlc19wb3AyNSRtaW5lX2dyb3VwDQogIA0KICBvayA8LSAhaXMubmEoeCkgJiAhaXMubmEoZykNCiAgeCA8LSB4W29rXTsgZyA8LSBnW29rXQ0KICANCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fY2hhbmdlX21pbmVzICAgID0gbTEsDQogICAgZGlmZl9jaGFuZ2UgICAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICAgID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZSgNCiAgICBzaWcgPSBjYXNlX3doZW4oDQogICAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICAgIHBfdmFsdWUgPCAwLjAxICB+ICIqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgICBUUlVFIH4gIiINCiAgICApDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyA0KSBHcm91cCBjb3VudHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KZ3JvdXBfTnNfcG9wMjUgPC0gaGV4X2NoYW5nZXNfcG9wMjUgJT4lDQogIGNvdW50KG1pbmVfZ3JvdXApDQoNCmdyb3VwX05zX3BvcDI1DQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlc19wb3AyNSwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzX3BvcDI1KSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KDQojIyNNaW5lcmFsIHR5cGUgdHJlYXRtZW50IGNhdGVnb3JpZXMgKDNURyB2cy4gbm9uLTNURyBtaW5lcykNCg0KLSBMZXNzIGZvcmVzdCBsb3NzIGluIDNURyBtaW5lcmFsIGdyaWRzLCB3aGljaCB0cmFja3Mgd2l0aCBsb3dlciBuaWdodGxpZ2h0LCBwb3AgYW5kIGltcGVydmlvdXMgZ3Jvd3RoDQotIEhpZ2hlciBjcm9wbGFuZCBncm93dGggKGlycmlnYXRlZCwgcmFpbmZlZCkgaW4gM1RHIG1pbmVyYWwgZ3JpZHMNCi0gSGlnaGVyIGdyb3d0aCBpbiBjb25mbGljdHMgb3ZlcmFsbCBhbmQgYmF0dGxlcyBidXQgbm90IHByb3Rlc3RzIGZvciAzVEcgbWluZXJhbCBncmlkcw0KYGBge3J9DQojYW5udWFsIGNoYW5nZXMgZGYgdnMuIG5vbiBkZiBtaW5lcmFsIGdyaWRzIyMjIw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMSkgQnVpbGQgYSBoZXgtbGV2ZWwgREYgZ3JvdXBpbmcgdmFyaWFibGUsIGFuZCByZXN0cmljdCB0byBtaW5pbmcgZ3JpZHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpkZl9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBmaXJzdChuYS5vbWl0KHRvX251bSh0b3RhbF9taW5lX2NvdW50KSkpLA0KICAgIGhhc19kZl9zdGF0aWMgICAgICAgICAgID0gZmlyc3QobmEub21pdCh0b19udW0oaGFzX2RmX21pbmVfZHVtbXkpKSksDQogICAgZGZfZ3JvdXAgPSBpZmVsc2UoaGFzX2RmX3N0YXRpYyA9PSAxLCAiREYgbWluZSIsICJOb24tREYgbWluZSIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSAlPiUNCiAgZmlsdGVyKHRvdGFsX21pbmVfY291bnRfc3RhdGljID49IDEpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIEpvaW4gb250byB0aGUgcGVyaW9kLWF2ZXJhZ2Ugd2lkZSBkYXRhIGFuZCBjb21wdXRlIGNoYW5nZXMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0bXAgPC0gaGV4X3BlcmlvZF9hdmdzICU+JQ0KICBpbm5lcl9qb2luKGRmX2dyb3VwX2J5X2hleCAlPiUgc2VsZWN0KGhleF9pZCwgZGZfZ3JvdXApLCBieSA9ICJoZXhfaWQiKQ0KDQojIGNoYW5nZSBjb2x1bW5zOiBwb3N0IC0gcHJlDQpmb3IgKHYgaW4geWVhcmx5X3ZhcnMpIHsNCiAgcG9zdF9jb2wgPC0gcGFzdGUwKHYsICJfX3Bvc3RfMjAxOV8yMSIpDQogIHByZV9jb2wgIDwtIHBhc3RlMCh2LCAiX19wcmVfMjAwM18wNiIpDQogIHRtcFtbcGFzdGUwKCJjaGdfXyIsIHYpXV0gPC0gdG1wW1twb3N0X2NvbF1dIC0gdG1wW1twcmVfY29sXV0NCn0NCg0KaGV4X2NoYW5nZXNfZGZfdnNfbm9uZGYgPC0gdG1wICU+JQ0KICBzZWxlY3QoaGV4X2lkLCBkZl9ncm91cCwgc3RhcnRzX3dpdGgoImNoZ19fIikpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDMpIENvbXBhcmUgbWVhbiBjaGFuZ2VzIGFjcm9zcyBERiB2cyBub24tREYgKFdlbGNoIHQtdGVzdHMpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KY2hnX3ZhcnMgPC0gcGFzdGUwKCJjaGdfXyIsIHllYXJseV92YXJzKQ0KDQpkaWZmX2luX2NoYW5nZXNfZGZfdnNfbm9uZGYgPC0gbGFwcGx5KGNoZ192YXJzLCBmdW5jdGlvbih2KSB7DQogIA0KICB4IDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmW1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlc19kZl92c19ub25kZiRkZl9ncm91cA0KICANCiAgb2sgPC0gIWlzLm5hKHgpICYgIWlzLm5hKGcpDQogIHggPC0geFtva107IGcgPC0gZ1tva10NCiAgDQogIG0wIDwtIG1lYW4oeFtnID09ICJOb24tREYgbWluZSJdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09ICJERiBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub25fZGYgPSBtMCwNCiAgICBtZWFuX2NoYW5nZV9kZiAgICAgPSBtMSwNCiAgICBkaWZmX2NoYW5nZSAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICA9IHR0JHAudmFsdWUNCiAgKQ0KfSkgJT4lDQogIGJpbmRfcm93cygpICU+JQ0KICBtdXRhdGUoDQogICAgc2lnID0gY2FzZV93aGVuKA0KICAgICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgICAgcF92YWx1ZSA8IDAuMDUgIH4gIioiLA0KICAgICAgVFJVRSB+ICIiDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDQpIEdyb3VwIGNvdW50cw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmdyb3VwX05zX2RmX3ZzX25vbmRmIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmICU+JQ0KICBjb3VudChkZl9ncm91cCkNCg0KZ3JvdXBfTnNfZGZfdnNfbm9uZGYNCg0KRFQ6OmRhdGF0YWJsZSgNCiAgZGlmZl9pbl9jaGFuZ2VzX2RmX3ZzX25vbmRmLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyhkaWZmX2luX2NoYW5nZXNfZGZfdnNfbm9uZGYpLCAgIyBzaG93IGFsbCByb3dzDQogICAgcGFnaW5nID0gRkFMU0UgICAgICAgICAgICAgIyB0dXJuIHBhZ2luYXRpb24gb2ZmDQogICkNCikNCg0KYGBgDQoNCiMjI1BhcmtlciBhbmQgVmFkaGVpbS9Eb2RkLUZyYW5rIG1pbmluZyBncmlkcyB2cy4gbm9uLURGIG1pbmluZyBncmlkcw0KDQotIE5vIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBjb25mbGljdCBjb3VudCBncm93dGggaW4gUFYtREYgdHJlYXRlZCB2cy4gdW50cmVhdGVkIG1pbmluZyBncmlkcy4NCmBgYHtyfQ0KI2FubnVhbCBjaGFuZ2VzIGRmIHZzLiBub24gZGYgcG9saWN5IGdyaWRzIyMjIw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMSkgQnVpbGQgYSBoZXgtbGV2ZWwgREYgZ3JvdXBpbmcgdmFyaWFibGUsIGFuZCByZXN0cmljdCB0byBtaW5pbmcgZ3JpZHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpkZl9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBmaXJzdChuYS5vbWl0KHRvX251bSh0b3RhbF9taW5lX2NvdW50KSkpLA0KICAgIGhhc19wb2xpY3lfc3RhdGljICAgICAgICAgICA9IGZpcnN0KG5hLm9taXQodG9fbnVtKHBvbGljeV90ZXJyKSkpLA0KICAgIHBvbGljeV9ncm91cCA9IGlmZWxzZShoYXNfcG9saWN5X3N0YXRpYyA9PSAxLCAiREYgbWluZSIsICJOb24tREYgbWluZSIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSAlPiUNCiAgZmlsdGVyKHRvdGFsX21pbmVfY291bnRfc3RhdGljID49IDEpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIEpvaW4gb250byB0aGUgcGVyaW9kLWF2ZXJhZ2Ugd2lkZSBkYXRhIGFuZCBjb21wdXRlIGNoYW5nZXMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0bXAgPC0gaGV4X3BlcmlvZF9hdmdzICU+JQ0KICBpbm5lcl9qb2luKGRmX2dyb3VwX2J5X2hleCAlPiUgc2VsZWN0KGhleF9pZCwgcG9saWN5X2dyb3VwKSwgYnkgPSAiaGV4X2lkIikNCg0KIyBjaGFuZ2UgY29sdW1uczogcG9zdCAtIHByZQ0KZm9yICh2IGluIHllYXJseV92YXJzKSB7DQogIHBvc3RfY29sIDwtIHBhc3RlMCh2LCAiX19wb3N0XzIwMTlfMjEiKQ0KICBwcmVfY29sICA8LSBwYXN0ZTAodiwgIl9fcHJlXzIwMDNfMDYiKQ0KICB0bXBbW3Bhc3RlMCgiY2hnX18iLCB2KV1dIDwtIHRtcFtbcG9zdF9jb2xdXSAtIHRtcFtbcHJlX2NvbF1dDQp9DQoNCmhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmIDwtIHRtcCAlPiUNCiAgc2VsZWN0KGhleF9pZCwgcG9saWN5X2dyb3VwLCBzdGFydHNfd2l0aCgiY2hnX18iKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMykgQ29tcGFyZSBtZWFuIGNoYW5nZXMgYWNyb3NzIERGIHZzIG5vbi1ERiAoV2VsY2ggdC10ZXN0cykNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpjaGdfdmFycyA8LSBwYXN0ZTAoImNoZ19fIiwgeWVhcmx5X3ZhcnMpDQoNCmRpZmZfaW5fY2hhbmdlc19kZl92c19ub25kZiA8LSBsYXBwbHkoY2hnX3ZhcnMsIGZ1bmN0aW9uKHYpIHsNCiAgDQogIHggPC0gaGV4X2NoYW5nZXNfZGZfdnNfbm9uZGZbW3ZdXQ0KICBnIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmJHBvbGljeV9ncm91cA0KICANCiAgb2sgPC0gIWlzLm5hKHgpICYgIWlzLm5hKGcpDQogIHggPC0geFtva107IGcgPC0gZ1tva10NCiAgDQogIG0wIDwtIG1lYW4oeFtnID09ICJOb24tREYgbWluZSJdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09ICJERiBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub25fZGYgPSBtMCwNCiAgICBtZWFuX2NoYW5nZV9kZiAgICAgPSBtMSwNCiAgICBkaWZmX2NoYW5nZSAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICA9IHR0JHAudmFsdWUNCiAgKQ0KfSkgJT4lDQogIGJpbmRfcm93cygpICU+JQ0KICBtdXRhdGUoDQogICAgc2lnID0gY2FzZV93aGVuKA0KICAgICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgICAgcF92YWx1ZSA8IDAuMDUgIH4gIioiLA0KICAgICAgVFJVRSB+ICIiDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDQpIEdyb3VwIGNvdW50cw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmdyb3VwX05zX2RmX3ZzX25vbmRmIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmICU+JQ0KICBjb3VudChwb2xpY3lfZ3JvdXApDQoNCmdyb3VwX05zX2RmX3ZzX25vbmRmDQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlc19kZl92c19ub25kZiwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzX2RmX3ZzX25vbmRmKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KI1JlZ3Jlc3Npb25zDQoNCiMjT3V0Y29tZTogUHIoQmF0dGxlIE9jY3VyZW5jZSkNCg0KIyMjUFYgYmFzZWxpbmUgbW9kZWwgYnV0IHdpdGggZ3JpZHMNCkxvb2tpbmcgYXQgdGhlIG91dGNvbWU6IHByb2JhYmlsaXR5IG9mIGFueSBiYXR0bGUgb2NjdXJyaW5nLiBTYW1lIGFzIFBWIHN0dWR5IGJ1dCB1c2luZyBncmlkIGNlbGxzIGluc3RlYWQgb2YgdGVycml0b3JpZXMgYXMgdGhlIHVuaXQgb2YgYW5hbHlzaXMgKHNvIGEgbXVjaCBzbWFsbGVyIHVuaXRlZCBvZiBhbmFseXNpcyB0aGF0IGRvZXNuJ3QgZm9sbG93IHBvbGl0aWNhbCBib3VuZGFyaWVzKS4gT25seSBwb2xpY3lfZHVtbXkgKGluZGljYXRvciBmb3IgZ3JpZHMgaW4gYSB0ZXJyaXRvcnkgZmxhZ2dlZCBhcyBjb25mbGljdC1hZmZlY3RlZCBieSBTdGF0ZSBEZXAgaW4gMjAwOC0yMDEwKSBpcyBzdGF0IHNpZyAoYXQgKioqLCAwLjAwMDE4NykuIEludGVyYWN0aW9uIHRlcm1zIHdpdGggbnVtYmVyIG9mIG1pbmUgdmFyaWFibGVzIGFyZW4ndC4NCmBgYHtyfQ0KI2FueSBiYXR0bGVzLCBtYXRjaGluZyBQViBidXQgYXQgZ3JpZCB2cy4gdGVycml0b3J5IGxldmVsIyMjIw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIHBvbGljeV9kdW1teTppc18zdF9jb3VudCArIHBvbGljeV9kdW1teTppc19nb2xkX2NvdW50IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQpgYGANCiMjI1BWIGJhc2VsaW5lIG1vZGVsIHdpdGggZ3JpZC1sZXZlbCB0cmVhdG1lbnQgYXNzaWdubWVudA0KDQpOb3cgSSdtIGFzc2lnbmluZyB0cmVhdG1lbnQgYXQgdGhlIGdyaWQgbGV2ZWwsIHJhdGhlciB0aGFuIGF0IHRoZSB0ZXJyaXRvcnkgbGV2ZWwsIGJhc2VkIG9uIHdoZXRoZXIgdGhlIGdyaWQgaXMgaW4gYSBTdGF0ZSBEZXBhcnRtZW50IHBvbGljeSB0ZXJyaXRvcnkgKyBoYXMgYSAzVEcgbWluZS4gV2hlbiBJIGFzc2lnbiB0cmVhdG1lbnQgbW9yZSBncmFudWxhcmx5LCB0aGUgdHJlYXRtZW50IGVmZmVjdCBnb2VzIGF3YXkuDQpgYGB7cn0NCiNhbnkgYmF0dGxlcywgbWF0Y2hpbmcgUFYgYnV0IGF0IGdyaWQgdnMuIHRlcnJpdG9yeSBsZXZlbCMjIyMNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBkZl9wb2xpY3lfZ3JpZHMgKyBkZl9wb2xpY3lfZ3JpZHM6aXNfM3RfY291bnQgKyBkZl9wb2xpY3lfZ3JpZHM6aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KYGBgDQojIyNHb3Zlcm5tZW50IGJhbiB0cmVhdG1lbnQNCg0KTm93IEkibSBpZ25vcmluZyBEb2RkLUZyYW5rIGFuZCBsb29raW5nIGluc3RlYWQgYXQgdGhlIGdvdmVybm1lbnQgYmFuIG9uIGFydGlzYW5hbCBtaW5pbmcgdGhhdCBvY2N1cnJlZCBhdCB0aGUgc2FtZSB0aW1lIHRoYXQgREYgd2FzIHBhc3NlZC4gSGVyZSBJJ20gdXNpbmcgdGhlIHNhbWUgYXBwcm9hY2ggYXMgUFYgKGJ1dCBhdCB0aGUgZ3JpZCBsZXZlbCB2cyB0ZXJyaXRvcnkgbGV2ZWwpLiBUaGUgYmFuIGNvdmVyZWQgMyBwcm92aW5jZXMsIHdoaWNoIGVuY29tcGFzcyA0NCBvZiB0aGUgNTEgdHJlYXRlZCB0ZXJyaXRvcmllcyBpbiB0aGUgUFYgc3R1ZHkuIFRoZXJlIGlzIGEgcmVkdWN0aW9uIGluIHRoZSBwcm9iYWJpbGl0eSBvZiBleHBlcmllbmNpbmcgYSBiYXR0bGUgaW4gZ292X2JhbiBwcm92aW5jZXMuIA0KYGBge3J9DQoNCiN3aGF0IGlmIHdlIGp1c3QgbG9vayBhdCB0aGUgZ292IGJhbiMjIyMNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBnb3ZfYmFuICsgZ292X2Jhbjppc18zdF9jb3VudCArIGdvdl9iYW46aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KYGBgDQoNCiMjI0dvdmVybm1lbnQgYmFuIGFzc2lnbmVkIGF0IHRoZSBncmlkIGxldmVsDQoNCk5vdyBJJ20gYXNzaWduaW5nIHRoZSBzYW1lIGdvdmVybm1lbnQgYmFuIHRyZWF0bWVudCBidXQgYXQgdGhlIGdyaWQgbGV2ZWwgaW5zdGVhZCBvZiBhdCB0aGUgdGVycml0b3J5IGxldmVsLCBiYXNlZCBvbiB3aGV0aGVyIHRoZSBncmlkIGlzIGluIGEgcHJvdmluY2UgdGFyZ2V0ZWQgYnkgdGhlIGdvdmVybm1lbnQgYmFuICsgaGFzIGEgM1RHIG1pbmUuIFdoZW4gSSBhc3NpZ24gdHJlYXRtZW50IG1vcmUgZ3JhbnVsYXJseSwgdGhlIGNvZWZmaWNpZW50IG9uIHRoZSBQcihiYXR0bGUpIHJlbWFpbnMgbmVnYXRpdmUsIGJ1dCBub3cgdGhlIGludGVyYWN0aW9uIHRlcm0gd2l0aCB0aGUgbnVtYmVyIG9mIGdvbGQgbWluZXMgYmVjb21lcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChhbmQgaXMgcG9zaXRpdmUpLg0KYGBge3J9DQojd2hhdCBpZiB3ZSBhc3NpZ24gZ292IGJhbiB0cmVhdG1lbnQgYXQgdGhlIGdyaWQgbGV2ZWwNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBnb3ZfYmFuX2dyaWRzICsgZ292X2Jhbl9ncmlkczppc18zdF9jb3VudCArIGdvdl9iYW5fZ3JpZHM6aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KDQpgYGANCg0KIyMjQm90aCBQVi1ERiB0cmVhdG1lbnQgYW5kIGdvdmVybm1lbnQgYmFuDQoNCk5vdyBJJ20gbG9va2luZyBhdCB0aGUgUFYtREYgdHJlYXRtZW50ICsgZ292ZXJubWVudCBiYW4gc2ltdWx0YW5lb3VzbHkuIEZpcnN0IHJlZ3Jlc3Npb24gaGFzIHRyZWF0bWVudCBhc3NpZ25lZCBhdCB0aGUgdGVycml0b3J5IG9yIHByb3ZpbmNlIGxldmVsLiBTZWNvbmQgcmVncmVzc2lvbiBoYXMgdHJlYXRtZW50IGFzc2lnbmVkIGF0IHRoZSBncmlkIGxldmVsLiBXaGVuIHRyZWF0bWVudCBpcyBhc3NpZ25lZCBhdCB0aGUgdGVycml0b3J5L3Byb3ZpbmNlIGxldmVsLCB0aGUgdHdvIHBvbGljaWVzIHdvcmsgaW4gb3Bwb3NpdGUgZGlyZWN0aW9ucyBhbmQgYXJlIGJvdGggc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gV2hlbiB0cmVhdG1lbnQgaXMgYXNzaWduZWQgYXQgdGhlIGdyaWQgbGV2ZWwsIHRoZXkgYXJlIGJvdGggbmVnYXRpdmUgYW5kIHN0YXQgaW5zaWduaWZpY2FudC4NCmBgYHtyfQ0KDQojd2hhdCBpcyB3ZSBsb29rIGF0IGJvdGggZGYgYW5kIGdvdiBncmlkcw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIGdvdl9iYW4gfCBoZXhfaWQgKyB0aW1lX2lkLA0KICBkYXRhID0gcHZfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KI3NhbWUgcmVncmVzc2lvbiBidXQgd2l0aCB0cmVhdG1lbnQgYXNzaWduZWQgYXQgdGhlIGdyaWQgbGV2ZWwNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBkZl9wb2xpY3lfZ3JpZHMgKyBnb3ZfYmFuX2dyaWRzIHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQoNCmBgYA0KIyMjQWx0ZXJuYXRlIHRyZWF0bWVudCB0aW1pbmcgKE1heSAyMDEzKQ0KDQpOb3cgSSdtIGV4cGxvcmluZyB3aGV0aGVyIHVzaW5nIGEgbGF0ZXIgdHJlYXRtZW50IHN0YXJ0aW5nIHRpbWUgY2hhbmdlcyB0aGUgb3JpZ2luYWwgUFYgcmVzdWx0cy4gU3BlY2lmaWNhbGx5LCB3aGlsZSBEb2RkLUZyYW5rIHdhcyBwYXNzZWQgaW4gSnVseSAyMDEwLCBjb21wYW5pZXMgZGlkbid0IGhhdmUgdG8gZmlsZSB0aGVpciBmaXJzdCBjb25mbGljdCBtaW5lcmFsIGRpc2Nsb3N1cmUgcmVwb3J0cyB1bnRpbCBNYXkgMjAxNC4gSSdtIHVzaW5nIEp1bmUgMjAxMyAtLSBvbmUgeWVhciBiZWZvcmUgdGhlIGZpcnN0IGNvbXBhbnkgZmlsaW5nIC0tIGFzIG15IGFsdGVybmF0ZSB0cmVhdG1lbnQgc3RhcnQgdGltaW5nLiBJJ20gYWxzbyBleHRlbmRpbmcgdGhlIHRpbWVmcmFtZSBmcm9tIDIwMTIgKFBWIHN0dWR5KSB0byAyMDIwLiBBbGwgdGhyZWUgY29lZmZpY2llbnRzIG9mIGludGVyZXN0IGFyZSBwb3NpdGl2ZSBhbmQgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4NCmBgYHtyfQ0KI01heSAyMDEzIHRyZWF0bWVudCMjIyMNCg0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teV8yMDEzICsgcG9saWN5X2R1bW15XzIwMTM6aXNfM3RfY291bnQgKyBwb2xpY3lfZHVtbXlfMjAxMzppc19nb2xkX2NvdW50IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IGZ1bGxfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KDQpgYGANCiMjI01pbmVyYWwgdHlwZSB0cmVhdG1lbnQgYXNzaWdubWVudA0KDQpOb3cgSSdtIGV4cGxvcmluZyB0aGUgdXNlIG9mIGFuIGFsdGVybmF0ZSB0cmVhdG1lbnQgYXNzaWdubWVudCBiYXNlZCBvbiB3aGV0aGVyIHRoZSBncmlkIGNlbGwgaGFzIGEgM1RHIG1pbmUgdnMgbm9uLTNURyBtaW5lLiBGaXJzdCByZWdyZXNzaW9uIHVzZXMgdGhlIEp1bHkgMjAxMCB0cmVhdG1lbnQgdGltaW5nLCBzZWNvbmQgdGhlIEp1bmUgMjAxMyB0aW1pbmcuIEJvdGggc2hvdyBhIHBvc2l0aXZlLCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHRyZWF0bWVudCBlZmZlY3QuDQoNCmBgYHtyfQ0KI01pbmVyYWwgdHlwZSB0cmVhdG1lbnQgYW5kIDIwMTAgb3IgMjAxMyB0cmVhdG1lbnQjIyMjDQojMjAxMw0KcGFuZWxfbW9udGggPC0gcGFuZWxfbW9udGggJT4lDQogIG11dGF0ZSgNCiAgICBwb2xpY3lfZHVtbXlfMjAxM190aW1lb25seSA9IGFzLmludGVnZXIodGltZV9pZCA+PSAyMDEzMDZMKQ0KICApDQoNCmZ1bGxfbW9udGhzX2dyaWRzIDwtIHBhbmVsX21vbnRoICU+JQ0KICBkcGx5cjo6ZmlsdGVyKA0KICAgIHllYXIgPj0gMjAwNCwNCiAgICB5ZWFyIDw9IDIwMjAsDQogICAgZWFzdGVybl90ZXJyID09IDENCiAgKQ0KDQojMjAxMA0KcGFuZWxfbW9udGggPC0gcGFuZWxfbW9udGggJT4lDQogIG11dGF0ZSgNCiAgICBwb2xpY3lfZHVtbXlfMjAxMF90aW1lb25seSA9IGFzLmludGVnZXIodGltZV9pZCA+PSAyMDEwMDdMKQ0KICApDQoNCg0KDQpwdl9tb250aHNfZ3JpZHMgPC0gcGFuZWxfbW9udGggJT4lDQogIGRwbHlyOjpmaWx0ZXIoDQogICAgeWVhciA+PSAyMDA0LA0KICAgIHllYXIgPD0gMjAxMiwNCiAgICBlYXN0ZXJuX3RlcnIgPT0gMQ0KICApDQoNCiMyMDEzIHJlZw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teV8yMDEzX3RpbWVvbmx5Omhhc19kZl9taW5lX2R1bW15IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IGZ1bGxfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KIzIwMTAgcmVnDQptb2QgPC0gZmVvbHMoDQogIGFueV9iYXR0bGVzIH4gcG9saWN5X2R1bW15XzIwMTBfdGltZW9ubHk6aGFzX2RmX21pbmVfZHVtbXkgfCBoZXhfaWQgKyB0aW1lX2lkLA0KICBkYXRhID0gcHZfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KDQoNCmBgYA0KSGVyZSBJJ20gaW50cm9kdWNpbmcgc29tZSB5ZWFybHkgY292YXJpYXRlcyAocG9wdWxhdGlvbiwgbmlnaHRsaWdodHMgYW5kIHNlbGVjdCBsYW5kIHVzZSBjYXRlZ29yaWVzKS4gVGhpcyBpcyB0aGUgYmFzZWxpbmUgUFYgc3BlY2lmaWNhdGlvbiAoMjAxMCB0cmVhdG1lbnQsIFN0YXRlIERlcGFydG1lbnQgbWFwKS4gSW50ZXJlc3RpbmcgdGhhdCB3aGlsZSB0aGUgcG9saWN5IHN1bW15IHJlbWFpbnMgcG9zaXRpdmUgYW5kIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHRoZSBpbnRlcmFjdGlvbiB0ZXJtIG9uIHRoZSBudW1iZXIgb2YgZ29sZCBtaW5lcyBkb2VzIG5vdC4gVGhlIG9ubHkgY292YXJpYXRlIHRoYXQgc2VlbXMgdG8gcG9wIGlzIHJhaW5mZWQgY3JvcHMuDQoNCmBgYHtyfQ0KI2Jhc2VsaW5lIFBWIHdpdGggUlMgY29udHJvbHMNCg0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIHBvbGljeV9kdW1teTppc18zdF9jb3VudCArIHBvbGljeV9kdW1teTppc19nb2xkX2NvdW50ICsgcG9wICsgbmlnaHRsaWdodHMgKyBpcnJpZ2F0ZWRfY3JvcHMgKyByYWluZmVkX2Nyb3BzICsgZm9yZXN0IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0K