Goal

Check origin of CDN education changes.

Set up

#library
library(tidyverse)
library(lavaan)
library(data.table)
library(doParallel)
library(parallel)

#data
load("data/data-processed/ml_sem_data/240813_lisscdn-mlsem-panel-data-cleaned.Rdata")
load("data/data-processed/lisscdn_cl-ready_240624.Rdata")

Functions

#recode function for education alter
feducation_alter <- function(x) {
  x2 <- ifelse(x == 1, 4, x)
  x3 <- ifelse(x == 2, 6, x2)
  x4 <- ifelse(x == 3, 10, x3)
  x5 <- ifelse(x == 4, 11.5, x4)
  x6 <- ifelse(x == 5, 10.5, x5)
  x7 <- ifelse(x == 6, 15, x6)
  x8<- ifelse(x == 7, 16, x7)
  return(x8)
}

Data preperation

#create educ_test datafile
educ_test <- liss_long %>%
  select(nomem_encr,
         survey_wave,
         starts_with("alter_id"),
         starts_with("educ_alter")) %>%
  rename(
    educ_alter.1 = educ_alter1,
    educ_alter.2 = educ_alter2,
    educ_alter.3 = educ_alter3,
    educ_alter.4 = educ_alter4,
    educ_alter.5 = educ_alter5,
    alter_id.1 = alter_id_1,
    alter_id.2 = alter_id_2,
    alter_id.3 = alter_id_3,
    alter_id.4 = alter_id_4,
    alter_id.5 = alter_id_5
  ) %>%
  pivot_longer(
    3:12,
    names_to = c("name", "alter"),
    names_pattern = "(.+)\\.(.+)",
    values_to = "value"
  ) %>%
  pivot_wider(names_from = name,
              values_from = value) %>% 
  mutate(dyad_id = paste0(nomem_encr, alter_id),
         survey_wave = as.numeric(survey_wave)) %>%
  filter(!is.na(alter_id)) %>%
  select(!alter) %>% 
  arrange(nomem_encr, alter_id, survey_wave) %>% 
  mutate(educ_alter = feducation_alter(educ_alter))

#extract data that is used in this project
MyData <- mlsem_datafiles[[3]]
sample <- MyData$nomem_encr

#filter educ_test data
educ_test <- educ_test %>% 
  filter(nomem_encr %in% sample)

Check 1: Linear changes in education of alters

#check linear changes in education of alters
#create seperate lists
educ_test_df_list <- educ_test %>% 
  group_split(nomem_encr, alter_id)

#set up parallelization
numCores <- detectCores()
registerDoParallel(core = 6)

lm_educ_test <- foreach(
  a = 1:length(educ_test_df_list), #full run
  .packages = c("tidyverse", #packages needed in dopar
                "lavaan"),
  .combine = rbind, #used to combine dfs
  .errorhandling = "remove"
) %dopar% {
  #run lm and store results
  list_result <- educ_test_df_list[[a]] %>%
    lm(educ_alter ~ survey_wave,
                  data = .)
  #cleand results
  df_clean <- list_result %>%
    broom::tidy(.)
  
  return(df_clean)
}

#clean datafile with lm results
lm_educ_results <- lm_educ_test %>% 
  filter(term == "survey_wave") %>% 
  filter(!is.na(estimate)) %>% 
  filter(!is.na(std.error))

#create plot that shows changes in alters education
lm_educ_alter_plot <- lm_educ_results %>% 
  ggplot(aes(x = estimate)) +
  geom_histogram(binwidth = 0.1) +
  geom_vline(xintercept = mean(lm_educ_results$estimate),
             color = "red") +
  annotate("text",
           x = 1, 
           y = 1000,
           label = paste0("Mean: ", round(mean(lm_educ_results$estimate), 3)),
           size = 2) +
  theme_minimal() +
  labs(x = "Linear change estimate",
       y = "Count")

ggsave(lm_educ_alter_plot,
       file = "plots/rr/lm_educ_alter_plot.jpg",
       height = 4,
       width = 6,
       dpi = 600)

Check 2: Change in mean educational attainment for unstable and completely stable nettwoks.

#check stable alters and create stability of network
alters_long <- educ_test %>% 
  group_by(nomem_encr, alter_id) %>% 
  mutate(rl_alter = ifelse(is.na(alter_id), NA, 1:n())) %>%
  ungroup() %>% 
  mutate(rl_alter = ifelse(rl_alter > 1, 0, rl_alter))

#create list to use in loop
list_alters <- alters_long %>% 
  arrange(nomem_encr, survey_wave) %>% 
  group_split(nomem_encr)

#crete
list_networks <- list()

for(j in 1:length(list_alters)) {
  #j = 1
  #outer loop, select networks
  list_test <- list_alters[[j]] %>%
    group_split(survey_wave)
  
  
  list_dfs <- list()
  #inner while loop. Create returning dfs
  i <- 1
  while (i < length(list_test)) {
    #i = 1
    returning <- c(list_test[[i]] %>%
                     pull(alter_id)) %in%
      c(list_test[[i + 1]] %>%
          pull(alter_id))
    
    list_dfs[[i]] <-  tibble(returning,
                                 alter_id = c(list_test[[i]] %>%
                                                pull(alter_id))) %>%
      mutate(
        returning = as.numeric(returning),
        survey_wave = list_test[[i]] %>%
          select(survey_wave) %>%
          distinct() %>%
          pull(survey_wave)
      )
    i <- i + 1
  }
  
  if(length(list_dfs) != 0){
  #combine dfs
  list_networks[[j]] <- list_dfs %>%
    bind_rows() %>%
    mutate(nomem_encr = list_alters[[j]] %>%
             select(nomem_encr) %>%
             distinct() %>%
             pull(nomem_encr)) %>%
    select(nomem_encr, alter_id, survey_wave, returning) %>% 
    bind_rows(list_test[[length(list_test)]] %>% 
      select(nomem_encr, alter_id, survey_wave) %>% 
      mutate(returning = 0)) #add last wave of data
  }
}
#Combine dfs
test_df <- list_networks %>% 
  bind_rows()

#create stability indicator for each alter in a network
test_df <- test_df %>% 
  arrange(nomem_encr, alter_id, survey_wave) %>% 
  group_by(nomem_encr, alter_id) %>% 
  mutate(stable = ifelse(lag(returning == 1) | returning == 1, 1, 0),
         stable = ifelse(is.na(stable), 0, stable)) %>% 
  arrange(nomem_encr, survey_wave, alter_id)

#extract alter education data
educ_sel <- alters_long %>% 
  select(nomem_encr, survey_wave, alter_id, educ_alter)

#add alter education data
test_df <- test_df %>% 
  left_join(educ_sel, by = c("nomem_encr", "survey_wave", "alter_id"))

#create indicator whether alters have changed
changes_alter <- test_df %>% 
  filter(stable == 1) %>% 
  group_by(nomem_encr, alter_id) %>% 
  mutate(change_alter_educ = ifelse((educ_alter - lag(educ_alter)) != 0, 1, 0),
         changes_alter_educ = educ_alter - lag(educ_alter)) %>% 
  ungroup()

#create df for network change
change_df <- test_df %>% 
  group_by(nomem_encr, survey_wave) %>% 
  summarise(net_size = n(),
         sum_stable = sum(stable,na.rm = T),
         net_educ = mean(educ_alter, na.rm =T)) %>% 
  ungroup() %>% 
  group_by(nomem_encr) %>% 
  mutate(change_educ = net_educ - lag(net_educ)) %>% 
  mutate(net_stability = (sum_stable/(net_size))*100, #percentage of network that stays
         net_change = abs(net_size - lag(net_size))) %>%  #changes in the network
  ungroup() %>% 
  mutate(complete_stable = ifelse(net_change == 0 & sum_stable == net_size, 1, 0)) #create indicator whether a network is complete stable (similar size and no internal changes)

#create plot
net_complstable_plot <- change_df %>% 
  mutate(changed_educ = ifelse(change_educ != 0, 1, 0)) %>%
  mutate(complete_stable = ifelse(net_change == 0 & sum_stable == net_size, 1, 0),
         complete_stable = factor(complete_stable,
                                  levels = 0:1,
                                  labels = c(
                                    "Unstable networks",
                                    "Complete stable networks")),
         changed_educ = factor(changed_educ,
                               levels = 0:1,
                               labels = c(
                                 "No change",
                                 "Changed"))) %>% 
  filter(!is.na(complete_stable)) %>%
  filter(!is.na(changed_educ)) %>%
  ggplot(aes(x = changed_educ)) +
  facet_wrap(vars(complete_stable)) +
  geom_bar(fill = "black",
               alpha = 0.4,
               na.rm = T) +
  theme_minimal() +
  labs(x = "Change in CDNs' educational attainment")

#save plot
ggsave(net_complstable_plot,
       file = "plots/rr/net_complstable_plot_plot.pdf",
       height = 4,
       width = 6,
       dpi = 600)

#Show plot
net_complstable_plot

LS0tDQp0aXRsZTogIlJvYnVzdG5lc3M6IEFuYWx5c2lzIG9mIGNoYW5nZXMgaW4gQ0ROIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQiDQphdXRob3I6ICJUaGlqbWVuIEplcm9lbnNlIg0KZGF0ZTogIkxhc3QgY29tcGlsZWQgb24gYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2RlcHRoOiAzDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KLS0tDQojIEdvYWwNCg0KQ2hlY2sgb3JpZ2luIG9mIENETiBlZHVjYXRpb24gY2hhbmdlcy4gDQoNCiMgU2V0IHVwDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjYWNoZSA9IFRSVUUsDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICByZXN1bHRzID0gImFzaXMiLA0KICBmaWcuYWxpZ24gPSAiY2VudGVyIg0KKQ0KYGBgDQoNCmBgYHtyIGxpYnJhcmllcyBhbmQgZGF0YSBpbXBvcnR9DQojbGlicmFyeQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGxhdmFhbikNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoZG9QYXJhbGxlbCkNCmxpYnJhcnkocGFyYWxsZWwpDQoNCiNkYXRhDQpsb2FkKCJkYXRhL2RhdGEtcHJvY2Vzc2VkL21sX3NlbV9kYXRhLzI0MDgxM19saXNzY2RuLW1sc2VtLXBhbmVsLWRhdGEtY2xlYW5lZC5SZGF0YSIpDQpsb2FkKCJkYXRhL2RhdGEtcHJvY2Vzc2VkL2xpc3NjZG5fY2wtcmVhZHlfMjQwNjI0LlJkYXRhIikNCmBgYA0KDQojIEZ1bmN0aW9ucw0KDQpgYGB7ciBmdW5jdGlvbnN9DQojcmVjb2RlIGZ1bmN0aW9uIGZvciBlZHVjYXRpb24gYWx0ZXINCmZlZHVjYXRpb25fYWx0ZXIgPC0gZnVuY3Rpb24oeCkgew0KICB4MiA8LSBpZmVsc2UoeCA9PSAxLCA0LCB4KQ0KICB4MyA8LSBpZmVsc2UoeCA9PSAyLCA2LCB4MikNCiAgeDQgPC0gaWZlbHNlKHggPT0gMywgMTAsIHgzKQ0KICB4NSA8LSBpZmVsc2UoeCA9PSA0LCAxMS41LCB4NCkNCiAgeDYgPC0gaWZlbHNlKHggPT0gNSwgMTAuNSwgeDUpDQogIHg3IDwtIGlmZWxzZSh4ID09IDYsIDE1LCB4NikNCiAgeDg8LSBpZmVsc2UoeCA9PSA3LCAxNiwgeDcpDQogIHJldHVybih4OCkNCn0NCg0KYGBgDQoNCiMgRGF0YSBwcmVwZXJhdGlvbg0KDQpgYGB7ciBjcmVhdGUgZWR1Y2F0aW9uIHRlc3QgZmlsZX0NCiNjcmVhdGUgZWR1Y190ZXN0IGRhdGFmaWxlDQplZHVjX3Rlc3QgPC0gbGlzc19sb25nICU+JQ0KICBzZWxlY3Qobm9tZW1fZW5jciwNCiAgICAgICAgIHN1cnZleV93YXZlLA0KICAgICAgICAgc3RhcnRzX3dpdGgoImFsdGVyX2lkIiksDQogICAgICAgICBzdGFydHNfd2l0aCgiZWR1Y19hbHRlciIpKSAlPiUNCiAgcmVuYW1lKA0KICAgIGVkdWNfYWx0ZXIuMSA9IGVkdWNfYWx0ZXIxLA0KICAgIGVkdWNfYWx0ZXIuMiA9IGVkdWNfYWx0ZXIyLA0KICAgIGVkdWNfYWx0ZXIuMyA9IGVkdWNfYWx0ZXIzLA0KICAgIGVkdWNfYWx0ZXIuNCA9IGVkdWNfYWx0ZXI0LA0KICAgIGVkdWNfYWx0ZXIuNSA9IGVkdWNfYWx0ZXI1LA0KICAgIGFsdGVyX2lkLjEgPSBhbHRlcl9pZF8xLA0KICAgIGFsdGVyX2lkLjIgPSBhbHRlcl9pZF8yLA0KICAgIGFsdGVyX2lkLjMgPSBhbHRlcl9pZF8zLA0KICAgIGFsdGVyX2lkLjQgPSBhbHRlcl9pZF80LA0KICAgIGFsdGVyX2lkLjUgPSBhbHRlcl9pZF81DQogICkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICAzOjEyLA0KICAgIG5hbWVzX3RvID0gYygibmFtZSIsICJhbHRlciIpLA0KICAgIG5hbWVzX3BhdHRlcm4gPSAiKC4rKVxcLiguKykiLA0KICAgIHZhbHVlc190byA9ICJ2YWx1ZSINCiAgKSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IG5hbWUsDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JSANCiAgbXV0YXRlKGR5YWRfaWQgPSBwYXN0ZTAobm9tZW1fZW5jciwgYWx0ZXJfaWQpLA0KICAgICAgICAgc3VydmV5X3dhdmUgPSBhcy5udW1lcmljKHN1cnZleV93YXZlKSkgJT4lDQogIGZpbHRlcighaXMubmEoYWx0ZXJfaWQpKSAlPiUNCiAgc2VsZWN0KCFhbHRlcikgJT4lIA0KICBhcnJhbmdlKG5vbWVtX2VuY3IsIGFsdGVyX2lkLCBzdXJ2ZXlfd2F2ZSkgJT4lIA0KICBtdXRhdGUoZWR1Y19hbHRlciA9IGZlZHVjYXRpb25fYWx0ZXIoZWR1Y19hbHRlcikpDQoNCiNleHRyYWN0IGRhdGEgdGhhdCBpcyB1c2VkIGluIHRoaXMgcHJvamVjdA0KTXlEYXRhIDwtIG1sc2VtX2RhdGFmaWxlc1tbM11dDQpzYW1wbGUgPC0gTXlEYXRhJG5vbWVtX2VuY3INCg0KI2ZpbHRlciBlZHVjX3Rlc3QgZGF0YQ0KZWR1Y190ZXN0IDwtIGVkdWNfdGVzdCAlPiUgDQogIGZpbHRlcihub21lbV9lbmNyICVpbiUgc2FtcGxlKQ0KDQpgYGANCg0KIyBDaGVjayAxOiBMaW5lYXIgY2hhbmdlcyBpbiBlZHVjYXRpb24gb2YgYWx0ZXJzDQoNCmBgYHtyIGNoZWNrIGxpbmVhciBjaGFuZ2VzfQ0KI2NoZWNrIGxpbmVhciBjaGFuZ2VzIGluIGVkdWNhdGlvbiBvZiBhbHRlcnMNCiNjcmVhdGUgc2VwZXJhdGUgbGlzdHMNCmVkdWNfdGVzdF9kZl9saXN0IDwtIGVkdWNfdGVzdCAlPiUgDQogIGdyb3VwX3NwbGl0KG5vbWVtX2VuY3IsIGFsdGVyX2lkKQ0KDQojc2V0IHVwIHBhcmFsbGVsaXphdGlvbg0KbnVtQ29yZXMgPC0gZGV0ZWN0Q29yZXMoKQ0KcmVnaXN0ZXJEb1BhcmFsbGVsKGNvcmUgPSA2KQ0KDQpsbV9lZHVjX3Rlc3QgPC0gZm9yZWFjaCgNCiAgYSA9IDE6bGVuZ3RoKGVkdWNfdGVzdF9kZl9saXN0KSwgI2Z1bGwgcnVuDQogIC5wYWNrYWdlcyA9IGMoInRpZHl2ZXJzZSIsICNwYWNrYWdlcyBuZWVkZWQgaW4gZG9wYXINCiAgICAgICAgICAgICAgICAibGF2YWFuIiksDQogIC5jb21iaW5lID0gcmJpbmQsICN1c2VkIHRvIGNvbWJpbmUgZGZzDQogIC5lcnJvcmhhbmRsaW5nID0gInJlbW92ZSINCikgJWRvcGFyJSB7DQogICNydW4gbG0gYW5kIHN0b3JlIHJlc3VsdHMNCiAgbGlzdF9yZXN1bHQgPC0gZWR1Y190ZXN0X2RmX2xpc3RbW2FdXSAlPiUNCiAgICBsbShlZHVjX2FsdGVyIH4gc3VydmV5X3dhdmUsDQogICAgICAgICAgICAgICAgICBkYXRhID0gLikNCiAgI2NsZWFuZCByZXN1bHRzDQogIGRmX2NsZWFuIDwtIGxpc3RfcmVzdWx0ICU+JQ0KICAgIGJyb29tOjp0aWR5KC4pDQogIA0KICByZXR1cm4oZGZfY2xlYW4pDQp9DQoNCiNjbGVhbiBkYXRhZmlsZSB3aXRoIGxtIHJlc3VsdHMNCmxtX2VkdWNfcmVzdWx0cyA8LSBsbV9lZHVjX3Rlc3QgJT4lIA0KICBmaWx0ZXIodGVybSA9PSAic3VydmV5X3dhdmUiKSAlPiUgDQogIGZpbHRlcighaXMubmEoZXN0aW1hdGUpKSAlPiUgDQogIGZpbHRlcighaXMubmEoc3RkLmVycm9yKSkNCg0KI2NyZWF0ZSBwbG90IHRoYXQgc2hvd3MgY2hhbmdlcyBpbiBhbHRlcnMgZWR1Y2F0aW9uDQpsbV9lZHVjX2FsdGVyX3Bsb3QgPC0gbG1fZWR1Y19yZXN1bHRzICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZXN0aW1hdGUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lYW4obG1fZWR1Y19yZXN1bHRzJGVzdGltYXRlKSwNCiAgICAgICAgICAgICBjb2xvciA9ICJyZWQiKSArDQogIGFubm90YXRlKCJ0ZXh0IiwNCiAgICAgICAgICAgeCA9IDEsIA0KICAgICAgICAgICB5ID0gMTAwMCwNCiAgICAgICAgICAgbGFiZWwgPSBwYXN0ZTAoIk1lYW46ICIsIHJvdW5kKG1lYW4obG1fZWR1Y19yZXN1bHRzJGVzdGltYXRlKSwgMykpLA0KICAgICAgICAgICBzaXplID0gMikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHggPSAiTGluZWFyIGNoYW5nZSBlc3RpbWF0ZSIsDQogICAgICAgeSA9ICJDb3VudCIpDQoNCmdnc2F2ZShsbV9lZHVjX2FsdGVyX3Bsb3QsDQogICAgICAgZmlsZSA9ICJwbG90cy9yci9sbV9lZHVjX2FsdGVyX3Bsb3QuanBnIiwNCiAgICAgICBoZWlnaHQgPSA0LA0KICAgICAgIHdpZHRoID0gNiwNCiAgICAgICBkcGkgPSA2MDApDQoNCmBgYA0KDQojIENoZWNrIDI6IENoYW5nZSBpbiBtZWFuIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgZm9yIHVuc3RhYmxlIGFuZCBjb21wbGV0ZWx5IHN0YWJsZSBuZXR0d29rcy4NCg0KYGBge3IgY2hlY2sgc3RhYmxlIGFsdGVyc30NCiNjaGVjayBzdGFibGUgYWx0ZXJzIGFuZCBjcmVhdGUgc3RhYmlsaXR5IG9mIG5ldHdvcmsNCmFsdGVyc19sb25nIDwtIGVkdWNfdGVzdCAlPiUgDQogIGdyb3VwX2J5KG5vbWVtX2VuY3IsIGFsdGVyX2lkKSAlPiUgDQogIG11dGF0ZShybF9hbHRlciA9IGlmZWxzZShpcy5uYShhbHRlcl9pZCksIE5BLCAxOm4oKSkpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUocmxfYWx0ZXIgPSBpZmVsc2UocmxfYWx0ZXIgPiAxLCAwLCBybF9hbHRlcikpDQoNCiNjcmVhdGUgbGlzdCB0byB1c2UgaW4gbG9vcA0KbGlzdF9hbHRlcnMgPC0gYWx0ZXJzX2xvbmcgJT4lIA0KICBhcnJhbmdlKG5vbWVtX2VuY3IsIHN1cnZleV93YXZlKSAlPiUgDQogIGdyb3VwX3NwbGl0KG5vbWVtX2VuY3IpDQoNCiNjcmV0ZQ0KbGlzdF9uZXR3b3JrcyA8LSBsaXN0KCkNCg0KZm9yKGogaW4gMTpsZW5ndGgobGlzdF9hbHRlcnMpKSB7DQogICNqID0gMQ0KICAjb3V0ZXIgbG9vcCwgc2VsZWN0IG5ldHdvcmtzDQogIGxpc3RfdGVzdCA8LSBsaXN0X2FsdGVyc1tbal1dICU+JQ0KICAgIGdyb3VwX3NwbGl0KHN1cnZleV93YXZlKQ0KICANCiAgDQogIGxpc3RfZGZzIDwtIGxpc3QoKQ0KICAjaW5uZXIgd2hpbGUgbG9vcC4gQ3JlYXRlIHJldHVybmluZyBkZnMNCiAgaSA8LSAxDQogIHdoaWxlIChpIDwgbGVuZ3RoKGxpc3RfdGVzdCkpIHsNCiAgICAjaSA9IDENCiAgICByZXR1cm5pbmcgPC0gYyhsaXN0X3Rlc3RbW2ldXSAlPiUNCiAgICAgICAgICAgICAgICAgICAgIHB1bGwoYWx0ZXJfaWQpKSAlaW4lDQogICAgICBjKGxpc3RfdGVzdFtbaSArIDFdXSAlPiUNCiAgICAgICAgICBwdWxsKGFsdGVyX2lkKSkNCiAgICANCiAgICBsaXN0X2Rmc1tbaV1dIDwtICB0aWJibGUocmV0dXJuaW5nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0ZXJfaWQgPSBjKGxpc3RfdGVzdFtbaV1dICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbChhbHRlcl9pZCkpKSAlPiUNCiAgICAgIG11dGF0ZSgNCiAgICAgICAgcmV0dXJuaW5nID0gYXMubnVtZXJpYyhyZXR1cm5pbmcpLA0KICAgICAgICBzdXJ2ZXlfd2F2ZSA9IGxpc3RfdGVzdFtbaV1dICU+JQ0KICAgICAgICAgIHNlbGVjdChzdXJ2ZXlfd2F2ZSkgJT4lDQogICAgICAgICAgZGlzdGluY3QoKSAlPiUNCiAgICAgICAgICBwdWxsKHN1cnZleV93YXZlKQ0KICAgICAgKQ0KICAgIGkgPC0gaSArIDENCiAgfQ0KICANCiAgaWYobGVuZ3RoKGxpc3RfZGZzKSAhPSAwKXsNCiAgI2NvbWJpbmUgZGZzDQogIGxpc3RfbmV0d29ya3NbW2pdXSA8LSBsaXN0X2RmcyAlPiUNCiAgICBiaW5kX3Jvd3MoKSAlPiUNCiAgICBtdXRhdGUobm9tZW1fZW5jciA9IGxpc3RfYWx0ZXJzW1tqXV0gJT4lDQogICAgICAgICAgICAgc2VsZWN0KG5vbWVtX2VuY3IpICU+JQ0KICAgICAgICAgICAgIGRpc3RpbmN0KCkgJT4lDQogICAgICAgICAgICAgcHVsbChub21lbV9lbmNyKSkgJT4lDQogICAgc2VsZWN0KG5vbWVtX2VuY3IsIGFsdGVyX2lkLCBzdXJ2ZXlfd2F2ZSwgcmV0dXJuaW5nKSAlPiUgDQogICAgYmluZF9yb3dzKGxpc3RfdGVzdFtbbGVuZ3RoKGxpc3RfdGVzdCldXSAlPiUgDQogICAgICBzZWxlY3Qobm9tZW1fZW5jciwgYWx0ZXJfaWQsIHN1cnZleV93YXZlKSAlPiUgDQogICAgICBtdXRhdGUocmV0dXJuaW5nID0gMCkpICNhZGQgbGFzdCB3YXZlIG9mIGRhdGENCiAgfQ0KfQ0KI0NvbWJpbmUgZGZzDQp0ZXN0X2RmIDwtIGxpc3RfbmV0d29ya3MgJT4lIA0KICBiaW5kX3Jvd3MoKQ0KDQojY3JlYXRlIHN0YWJpbGl0eSBpbmRpY2F0b3IgZm9yIGVhY2ggYWx0ZXIgaW4gYSBuZXR3b3JrDQp0ZXN0X2RmIDwtIHRlc3RfZGYgJT4lIA0KICBhcnJhbmdlKG5vbWVtX2VuY3IsIGFsdGVyX2lkLCBzdXJ2ZXlfd2F2ZSkgJT4lIA0KICBncm91cF9ieShub21lbV9lbmNyLCBhbHRlcl9pZCkgJT4lIA0KICBtdXRhdGUoc3RhYmxlID0gaWZlbHNlKGxhZyhyZXR1cm5pbmcgPT0gMSkgfCByZXR1cm5pbmcgPT0gMSwgMSwgMCksDQogICAgICAgICBzdGFibGUgPSBpZmVsc2UoaXMubmEoc3RhYmxlKSwgMCwgc3RhYmxlKSkgJT4lIA0KICBhcnJhbmdlKG5vbWVtX2VuY3IsIHN1cnZleV93YXZlLCBhbHRlcl9pZCkNCg0KI2V4dHJhY3QgYWx0ZXIgZWR1Y2F0aW9uIGRhdGENCmVkdWNfc2VsIDwtIGFsdGVyc19sb25nICU+JSANCiAgc2VsZWN0KG5vbWVtX2VuY3IsIHN1cnZleV93YXZlLCBhbHRlcl9pZCwgZWR1Y19hbHRlcikNCg0KI2FkZCBhbHRlciBlZHVjYXRpb24gZGF0YQ0KdGVzdF9kZiA8LSB0ZXN0X2RmICU+JSANCiAgbGVmdF9qb2luKGVkdWNfc2VsLCBieSA9IGMoIm5vbWVtX2VuY3IiLCAic3VydmV5X3dhdmUiLCAiYWx0ZXJfaWQiKSkNCg0KI2NyZWF0ZSBpbmRpY2F0b3Igd2hldGhlciBhbHRlcnMgaGF2ZSBjaGFuZ2VkDQpjaGFuZ2VzX2FsdGVyIDwtIHRlc3RfZGYgJT4lIA0KICBmaWx0ZXIoc3RhYmxlID09IDEpICU+JSANCiAgZ3JvdXBfYnkobm9tZW1fZW5jciwgYWx0ZXJfaWQpICU+JSANCiAgbXV0YXRlKGNoYW5nZV9hbHRlcl9lZHVjID0gaWZlbHNlKChlZHVjX2FsdGVyIC0gbGFnKGVkdWNfYWx0ZXIpKSAhPSAwLCAxLCAwKSwNCiAgICAgICAgIGNoYW5nZXNfYWx0ZXJfZWR1YyA9IGVkdWNfYWx0ZXIgLSBsYWcoZWR1Y19hbHRlcikpICU+JSANCiAgdW5ncm91cCgpDQoNCiNjcmVhdGUgZGYgZm9yIG5ldHdvcmsgY2hhbmdlDQpjaGFuZ2VfZGYgPC0gdGVzdF9kZiAlPiUgDQogIGdyb3VwX2J5KG5vbWVtX2VuY3IsIHN1cnZleV93YXZlKSAlPiUgDQogIHN1bW1hcmlzZShuZXRfc2l6ZSA9IG4oKSwNCiAgICAgICAgIHN1bV9zdGFibGUgPSBzdW0oc3RhYmxlLG5hLnJtID0gVCksDQogICAgICAgICBuZXRfZWR1YyA9IG1lYW4oZWR1Y19hbHRlciwgbmEucm0gPVQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdyb3VwX2J5KG5vbWVtX2VuY3IpICU+JSANCiAgbXV0YXRlKGNoYW5nZV9lZHVjID0gbmV0X2VkdWMgLSBsYWcobmV0X2VkdWMpKSAlPiUgDQogIG11dGF0ZShuZXRfc3RhYmlsaXR5ID0gKHN1bV9zdGFibGUvKG5ldF9zaXplKSkqMTAwLCAjcGVyY2VudGFnZSBvZiBuZXR3b3JrIHRoYXQgc3RheXMNCiAgICAgICAgIG5ldF9jaGFuZ2UgPSBhYnMobmV0X3NpemUgLSBsYWcobmV0X3NpemUpKSkgJT4lICAjY2hhbmdlcyBpbiB0aGUgbmV0d29yaw0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUoY29tcGxldGVfc3RhYmxlID0gaWZlbHNlKG5ldF9jaGFuZ2UgPT0gMCAmIHN1bV9zdGFibGUgPT0gbmV0X3NpemUsIDEsIDApKSAjY3JlYXRlIGluZGljYXRvciB3aGV0aGVyIGEgbmV0d29yayBpcyBjb21wbGV0ZSBzdGFibGUgKHNpbWlsYXIgc2l6ZSBhbmQgbm8gaW50ZXJuYWwgY2hhbmdlcykNCg0KI2NyZWF0ZSBwbG90DQpuZXRfY29tcGxzdGFibGVfcGxvdCA8LSBjaGFuZ2VfZGYgJT4lIA0KICBtdXRhdGUoY2hhbmdlZF9lZHVjID0gaWZlbHNlKGNoYW5nZV9lZHVjICE9IDAsIDEsIDApKSAlPiUNCiAgbXV0YXRlKGNvbXBsZXRlX3N0YWJsZSA9IGlmZWxzZShuZXRfY2hhbmdlID09IDAgJiBzdW1fc3RhYmxlID09IG5ldF9zaXplLCAxLCAwKSwNCiAgICAgICAgIGNvbXBsZXRlX3N0YWJsZSA9IGZhY3Rvcihjb21wbGV0ZV9zdGFibGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gMDoxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5zdGFibGUgbmV0d29ya3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbXBsZXRlIHN0YWJsZSBuZXR3b3JrcyIpKSwNCiAgICAgICAgIGNoYW5nZWRfZWR1YyA9IGZhY3RvcihjaGFuZ2VkX2VkdWMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gMDoxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gY2hhbmdlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGFuZ2VkIikpKSAlPiUgDQogIGZpbHRlcighaXMubmEoY29tcGxldGVfc3RhYmxlKSkgJT4lDQogIGZpbHRlcighaXMubmEoY2hhbmdlZF9lZHVjKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNoYW5nZWRfZWR1YykpICsNCiAgZmFjZXRfd3JhcCh2YXJzKGNvbXBsZXRlX3N0YWJsZSkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICJibGFjayIsDQogICAgICAgICAgICAgICBhbHBoYSA9IDAuNCwNCiAgICAgICAgICAgICAgIG5hLnJtID0gVCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHggPSAiQ2hhbmdlIGluIENETnMnIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQiKQ0KDQojc2F2ZSBwbG90DQpnZ3NhdmUobmV0X2NvbXBsc3RhYmxlX3Bsb3QsDQogICAgICAgZmlsZSA9ICJwbG90cy9yci9uZXRfY29tcGxzdGFibGVfcGxvdF9wbG90LnBkZiIsDQogICAgICAgaGVpZ2h0ID0gNCwNCiAgICAgICB3aWR0aCA9IDYsDQogICAgICAgZHBpID0gNjAwKQ0KDQojU2hvdyBwbG90DQpuZXRfY29tcGxzdGFibGVfcGxvdA0KYGBgDQoNCg==


Copyright © 2024 Jeroense Thijmen