Data Wrangling

Helper

Packages and functions used

source("0_helpers.R")
## 
## Attaching package: 'formr'
## The following object is masked from 'package:rmarkdown':
## 
##     word_document
## 
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
## 
##     date
## Loading required package: carData
## lattice theme set by effectsTheme()
## See ?effectsTheme for details.
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:lubridate':
## 
##     hour, isoweek, mday, minute, month, quarter, second, wday, week, yday, year
## The following objects are masked from 'package:formr':
## 
##     first, last
## Loading required package: Matrix
## 
## Attaching package: 'lmerTest'
## The following object is masked from 'package:lme4':
## 
##     lmer
## The following object is masked from 'package:stats':
## 
##     step
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
## This is lavaan 0.6-3
## lavaan is BETA software! Please report any bugs.
## 
## Attaching package: 'lavaan'
## The following object is masked from 'package:psych':
## 
##     cor2cov
## Loading required package: lattice
## Loading required package: survival
## Loading required package: Formula
## 
## Attaching package: 'Hmisc'
## The following object is masked from 'package:psych':
## 
##     describe
## The following objects are masked from 'package:base':
## 
##     format.pval, units
## 
## Attaching package: 'tidyr'
## The following object is masked from 'package:Matrix':
## 
##     expand
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:Hmisc':
## 
##     src, summarize
## The following objects are masked from 'package:data.table':
## 
##     between, first, last
## The following objects are masked from 'package:lubridate':
## 
##     intersect, setdiff, union
## The following objects are masked from 'package:formr':
## 
##     first, last
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## 
## Attaching package: 'codebook'
## The following object is masked from 'package:psych':
## 
##     bfi
## The following objects are masked from 'package:formr':
## 
##     aggregate_and_document_scale, asis_knit_child, expired, paste.knit_asis
## 
## Attaching package: 'effsize'
## The following object is masked from 'package:psych':
## 
##     cohen.d

Import data

Analyses are based on the Indonesian Family Life Survey (IFLS). All data is retrieved from the RAND foundation.

We included the following data sets:

  • IFLS Wave 1
    • buk4ch1
    • buk4kw2
    • bukkar2
  • IFLS Wave 2
    • b4_ch1
    • b4_kw2
    • b4_cov
  • IFLS Wave 3
    • b4_ch1
    • b4_kw3
    • b4_cov
  • IFLS Wave 4
    • b4_ch1
    • b4_kw2
    • b4_cov
    • bek_ek1
    • bek_ek2
  • IFLS Wave 5
    • bk_ar1
    • bk_sc1
    • ptrack
    • b4_ch1
    • b4_kw3
    • b4_cov
    • ek_ek2
    • ek_ek1
    • b3b_cob
    • b3b_co1
    • b3b_psn
    • b3a_si
    • b3a_dl1
    • b3a_dl3
    • b3a_dl4
    • b3a_tk2
    • b3b_km
### Informations about individuals living in the household in 2014/2015
## All Individuals living in the household
bk_ar1 = read_dta("data/hh14_all_dta/bk_ar1.dta") # Book K, Section ar
# compute father pidlink
bk_ar1 = left_join(bk_ar1, bk_ar1 %>%
                     select(hhid14_9, pid14, pidlink) %>%
                     rename(ar10 = pid14, father_pidlink = pidlink), by = c("hhid14_9", "ar10"))
# compute mother pidlink
bk_ar1 = left_join(bk_ar1, bk_ar1 %>%
                     select(hhid14_9, pid14, pidlink) %>%
                     rename(ar11 = pid14, mother_pidlink = pidlink), by = c("hhid14_9", "ar11"))

bk_sc1 = read_dta("data/hh14_all_dta/bk_sc1.dta") # Location info, Book K, Section sc
# Recode Regions:
bk_sc1 <- bk_sc1 %>%
  mutate(province = str_trim(recode(bk_sc1$sc01_14_14,  `11` = 'N. Aceh Darussalam',
 `12` = 'North Sumatera  ',
 `13` = 'West Sumatera',
 `14` = 'Riau  ',
 `15` = 'Jambi ',
 `16` = 'South Sumatera  ',
 `17` = 'Bengkulu',
 `18` = 'Lampung ',
 `19` = 'Bangka Belitung ',
 `31` = 'Jakarta ',
 `32` = 'West Java  ',
 `33` = 'Central Java ',
 `34` = 'DI Yogyakarta',
 `35` = 'East Java  ',
 `36` = 'Banten',
 `51` = 'Bali  ',
 `52` = 'West Nusa Tenggara',
 `53` = 'East Nusa Tenggara',
 `61` = 'West Kalimantan ',
 `62` = 'Central Kalimantan',
 `63` = 'South Kalimantan',
 `64` = 'East Kalimantan ',
 `71` = 'North Sulawesi  ',
 `72` = 'Central Sulawesi',
 `73` = 'South Sulawesi  ',
 `74` = 'Southeast Sulawesi',
 `81` = 'Maluku',
 `94` = 'Papua ',
 `98` = NA_character_,
 `99` = NA_character_, .default = NA_character_)))

### Informations from IFLS wave 5 to link data to earlier waves:
ptrack = read_dta("data/hh14_all_dta/ptrack.dta") # Tracking informations

### Pregnancy Informations from mother
## Wave 5 - 2014
w5_pregnancy = read_dta("data/hh14_all_dta/b4_ch1.dta") # Book 4, Section ch
## Wave 4 - 2007
w4_pregnancy = read_dta("data/hh07_all_dta/b4_ch1.dta") # Book 4, Section ch
## Wave 3 - 2000
w3_pregnancy = read_dta("data/hh00_all_dta/b4_ch1.dta") # Book 4, Section ch
## Wave 2 - 1997
w2_pregnancy = read_dta("data/hh97dta/b4_ch1.dta") # Book 4, Section ch
## Wave 1 - 1993
w1_pregnancy = read_dta("data/hh93dta/buk4ch1.dta") # Book 4, Section ch

### Marriage information from mother
## Wave 5 - 2014
w5_marriage= read_dta("data/hh14_all_dta/b4_kw3.dta") # Book 4, Section kw3
## Wave 4 - 2007
w4_marriage = read_dta("data/hh07_all_dta/b4_kw2.dta") # Book 4, Section kw2
## Wave 3 - 2000
w3_marriage = read_dta("data/hh00_all_dta/b4_kw3.dta") # Book 4, Section kw3
## Wave 2 - 1997
w2_marriage = read_dta("data/hh97dta/b4_kw2.dta") # Book 4, Section kw2
## Wave 1 - 1993
w1_marriage = read_dta("data/hh93dta/buk4kw2.dta") # Book 4, Section kw2

## Additional marriage information from mother
# Wave 5 - 2014
w5_marriage_additional = read_dta("data/hh14_all_dta/b4_cov.dta") # Book 4, Section cov
# Wave 4 - 2007
w4_marriage_additional = read_dta("data/hh07_all_dta/b4_cov.dta") # Book 4, Section cov
# Wave 3 - 2000
w3_marriage_additional = read_dta("data/hh00_all_dta/b4_cov.dta") # Book 4, Section cov
# Wave 2 - 1997
w2_marriage_additional = read_dta("data/hh97dta/b4_cov.dta") # Book 4, Section cov
# Wave 1 - 1993
w1_marriage_additional = read_dta("data/hh93dta/bukkar2.dta") # Book K, Section ar, household roaster

### IQ Information
ek_ek2 = read_dta("data/hh14_all_dta/ek_ek2.dta") # Book ek2: >15 years
ek_ek1 = read_dta("data/hh14_all_dta/ek_ek1.dta") # Book ek1: <15 years
# additional information (counting backwards, adaptive testing) for adults
b3b_cob = read_dta("data/hh14_all_dta/b3b_cob.dta") # Book 3b, Section cob
b3b_co1 = read_dta("data/hh14_all_dta/b3b_co1.dta") # Book 3b, Section co1
# additional information from earlier waves
bek_ek1 = read_dta("data/hh07_all_dta/bek_ek1.dta") # Intelligence information from wave 4 (2007): 7-14
bek_ek2 = read_dta("data/hh07_all_dta/bek_ek2.dta") # Intelligence info from wave 4 (2007): 15 - 24

### Personality Information (only for adults)
b3b_psn = read_dta("data/hh14_all_dta/b3b_psn.dta") # Book 3b, Section psn

### Risk taking
b3a_si = read_dta("data/hh14_all_dta/b3a_si.dta") # Book 3a, Section si

### Educational Attainment
b3a_dl1 = read_dta("data/hh14_all_dta/b3a_dl1.dta") # Book 3a, Section dl1

### EBTANAS/UAN/UN Score
b3a_dl3 = read_dta("data/hh14_all_dta/b3a_dl3.dta") # Book 3a, Section dl3
b3a_dl4 = read_dta("data/hh14_all_dta/b3a_dl4.dta") # Book 3a, Section dl4

### Job Information
b3a_tk2 = read_dta("data/hh14_all_dta/b3a_tk2.dta") # Book 3a, Section tk2

### Smoking behavior
b3b_km = read_dta("data/hh14_all_dta/b3b_km.dta") # Book 3b, Section km

Birth order information

Information about pregnancy

To compute birth order we need information about all pregnancies of all women who participated in IFLS wave 1 - 5

## Select data from pregnancy files
w5_pregnancy = w5_pregnancy %>%
  select(pidlink, ch05, ch06, ch06a, ch08, ch09day, ch09mth, ch09yr, ch25)
w4_pregnancy = w4_pregnancy %>%
  select(pidlink, ch05, ch06, ch06a, ch08, ch09day, ch09mth, ch09yr, ch25)
w3_pregnancy = w3_pregnancy %>%
  select(pidlink, ch05, ch06, ch06a, ch08, ch09day, ch09mth, ch09yr, ch25)
w2_pregnancy = w2_pregnancy %>%
  select(pidlink, ch05, ch06, ch06a, ch08, ch09day, ch09mth, ch09yr, ch25)
w1_pregnancy = w1_pregnancy %>% 
  group_by(pidlink, ch04) %>%
  mutate(ch06a = if_else(!is.na(pidlink) & !is.na(ch04), if_else( n() > 1, 1, 3), 9)) %>%
  ungroup() %>% 
  select(pidlink, ch05, ch06, ch06a, ch08, ch09day, ch09mth, ch09yr, ch25) %>% 
# In the first wave the year is named wrong
  mutate(ch09yr = ifelse(ch09yr <= 93, ch09yr, NA),
          ch09yr = as.numeric(str_c("19", ch09yr)))

## Combine data
pregnancy = bind_rows(w1 = w1_pregnancy, w2 = w2_pregnancy, w3 = w3_pregnancy, w4 = w4_pregnancy, w5 = w5_pregnancy, .id = "wave")
pregnancy = codebook::rescue_attributes(pregnancy, w5_pregnancy)

## Rename Variables
pregnancy = pregnancy %>%
  rename(chron_order_birth = ch05, lifebirths = ch06, multiple_birth = ch06a, gender = ch08,
                                 birth_day = ch09day, birth_month = ch09mth, birth_year = ch09yr, 
                                 mother_pidlink = pidlink, alive = ch25)
          # pregnancy$lifebirths values: 1 = still pregnant, 2 = livebirth, 3 = still birth, 4 = misscarriage

## Set values as NA that are missing (all values that are not logical)
pregnancy = pregnancy %>%
  mutate(birth_day = ifelse(birth_day>31, NA, birth_day),
         birth_month = ifelse(birth_month>12, NA, birth_month),
         birth_year = ifelse(birth_year>2016, NA, birth_year),
         birth_day = ifelse(is.nan(birth_day), NA, birth_day),
         birth_month = ifelse(is.nan(birth_month), NA, birth_month),
         birth_year = ifelse(is.nan(birth_year), NA, birth_year),
         multiple_birth = ifelse(multiple_birth == 9, NA, multiple_birth),
         multiple_birth = ifelse(is.nan(multiple_birth), NA, multiple_birth))

# if month of pregnancy is missing, set as first month of the year (January)
pregnancy$month = ifelse(is.na(pregnancy$birth_year), NA,
                               paste0(pregnancy$birth_year,"-",
                                      ifelse(is.na(pregnancy$birth_month), "01",
                                             pad_month(pregnancy$birth_month))))

# create birthdate variable that includes all available information about birth (year-month-day) 
pregnancy = pregnancy %>% 
  mutate(birthdate = all_available_info_birth_date(birth_year, birth_month, birth_day),
         mother_birthdate = str_c(mother_pidlink, "-", birthdate),
         mother_birthorder = paste0(mother_pidlink , "-", chron_order_birth))

# some pregnancies were reported in multiple waves,
# e.g. because pregnancies changed status (still ongoing pregnancy --> alive)
# to eliminate duplicates we only use the most recent report
pregnancy = pregnancy %>% 
  mutate(wave = str_sub(wave, 2, 3) %>% as.numeric()) %>% # from most recent wave to oldest
  arrange(desc(wave)) %>% # use most recent wave (because these will have pregnancy outcomes)
  group_by(mother_birthdate) %>% 
  mutate(birthdate_duped_in_earlier_wave = min_rank(wave)) %>% 
  group_by(mother_birthorder) %>% 
  mutate(birthorder_duped_in_earlier_wave = min_rank(wave))
# these are pregnancy that changes status (i.e. ongoing in wave 2, miscarried/born by wave 3)
crosstabs(~ birthdate_duped_in_earlier_wave + birthorder_duped_in_earlier_wave + is.na(birthdate), pregnancy)
is.na(birthdate) FALSE TRUE
birthdate_duped_in_earlier_wave birthorder_duped_in_earlier_wave
1 1 36830 1339
2 9330 0
3 2189 0
4 444 0
5 55 0
2 1 182 0
2 2371 0
3 807 0
4 218 0
5 42 0
3 1 3 0
2 80 0
3 191 0
4 58 0
5 16 0
4 1 1 0
2 1 0
3 5 0
4 31 0
5 5 0
5 1 0 0
2 0 0
3 2 0
4 0 0
5 0 0
6 1 0 0
2 0 0
3 0 0
4 1 0
5 1 0
7 1 0 0
2 0 0
3 0 0
4 2 0
5 0 0
1340 1 0 313
2 0 151
3 0 0
4 0 0
5 0 0
1804 1 0 442
2 0 160
3 0 57
4 0 0
5 0 0
2463 1 0 590
2 0 56
3 0 23
4 0 9
5 0 0
3141 1 0 727
2 0 171
3 0 65
4 0 42
5 0 10
# unfortunately, sometimes chron_order_birth is inconsistent with birthdates
# to eliminate duplicates from the pregnancy file (because pregnancies changed statuses)
# now, for those where we don't know the birthdate, we keep only unique birth orders
# for those, where we know the birthdate, we keep only unique birthdates (as this is higher q information)
pregnancy = pregnancy %>% 
  filter((is.na(birthdate) && birthorder_duped_in_earlier_wave == 1) | birthdate_duped_in_earlier_wave == 1) %>% 
  ungroup() # eliminate dupes across waves (same mother_birthdate), keep mult births
crosstabs(~ birthdate_duped_in_earlier_wave + birthorder_duped_in_earlier_wave + is.na(birthdate), pregnancy)
is.na(birthdate) FALSE TRUE
birthdate_duped_in_earlier_wave birthorder_duped_in_earlier_wave
1 1 36830 1339
2 9330 0
3 2189 0
4 444 0
5 55 0
1340 1 0 170
2 0 0
3 0 0
4 0 0
5 0 0
1804 1 0 167
2 0 0
3 0 0
4 0 0
5 0 0
2463 1 0 252
2 0 0
3 0 0
4 0 0
5 0 0
3141 1 0 727
2 0 0
3 0 0
4 0 0
5 0 0
x = (unique(pregnancy$mother_pidlink))


# for whatever reason there are some multiple births with just one row in the data, but number are low enough
# that we consider some errors in the records the likely reason
pregnancy %>% filter(!is.na(birthdate)) %>% group_by(mother_birthdate)  %>% 
  mutate(mult = n()) %>% crosstabs(~ mult + multiple_birth + is.na(birth_month), data = .)
is.na(birth_month) FALSE TRUE
mult multiple_birth
1 1 682 34
3 37015 5670
NA 2613 1974
2 1 493 93
3 28 100
NA 13 99
3 1 8 0
3 1 4
NA 0 17
4 1 4 0
3 0 0
NA 0 0
## Form variable for any multiple birth within a family (these families have to be excluded later)
pregnancy = pregnancy %>% group_by(mother_pidlink) %>%
  mutate(any_multiple_birth = if_else(any(multiple_birth == 1, na.rm = T), 1, 0))
# Proportion of multiple births:
prop.table(crosstabs(pregnancy$multiple_birth))
1 3 NA
0.02604 0.8549 0.119
# Proportion of families with any multiple birth:
prop.table(crosstabs(pregnancy$any_multiple_birth))
0 1
0.9248 0.07524

Information about marriage history

For full sibling birth order we need information about all marriages of all women who participated in IFLS wave 1 - 5. We are assuming here that the husband is the father of all children who were born within this marriage.

## Select marriage data
w5_marriage = w5_marriage %>% select(pidlink, kw10mth, kw10yr, kw18mth, kw18yr, kw11, kw19)
w4_marriage = w4_marriage %>% select(pidlink, kw10mth, kw10yr, kw18mth, kw18yr, kw11, kw19)
w3_marriage = w3_marriage %>% select(pidlink, kw10mth, kw10yr, kw18mth, kw18yr, kw11, kw19)
w2_marriage = w2_marriage %>% select(pidlink, kw10mth, kw10yr, kw18mth, kw18yr, kw11, kw19)
w1_marriage = w1_marriage %>% select(pidlink, kw05a, kw05b, kw13a, kw13b, kw06, kw14age)
# In the first wave the year is named wrong
w1_marriage = w1_marriage %>%
  mutate(kw05a = ifelse(kw05a <= 93, as.numeric(str_c("19", w1_marriage$kw05a)), kw05a),
         kw13a = ifelse(kw13a <=93 , as.numeric(str_c("19", w1_marriage$kw13a)), kw13a))
# And the column names are different than in later waves
w1_marriage = w1_marriage %>%
  rename(kw10mth = kw05b, kw10yr = kw05a, kw18mth = kw13b, kw18yr = kw13a, kw11 = kw06, kw19 = kw14age)

## Select additional marriage information (age of respondent)
w5_marriage_additional = w5_marriage_additional %>% select(pidlink, age, dob_yr)
w4_marriage_additional = w4_marriage_additional %>% select(pidlink, age, dob_yr)
w3_marriage_additional = w3_marriage_additional %>% select(pidlink, age, dob_yr)
w2_marriage_additional = w2_marriage_additional %>% select(pidlink, age, dob_yr)
w1_marriage_additional = w1_marriage_additional %>% select(pidlink, ar09yr, ar08yr)
# In the first wave the year is named wrong
w1_marriage_additional = w1_marriage_additional %>%
  mutate(ar08yr = ifelse(ar08yr <= 93, 
                         as.numeric(str_c("19", w1_marriage_additional$ar08yr)),
                         ar08yr))
# And the column names are different than in later waves
w1_marriage_additional = w1_marriage_additional %>% rename(age = ar09yr, dob_yr = ar08yr)

## Combine marriage information and additional marriage information:
w1_marriage = left_join(w1_marriage, w1_marriage_additional, by = "pidlink") %>%
  mutate(wave = as.numeric("1993"))
w2_marriage = left_join(w2_marriage, w2_marriage_additional, by = "pidlink") %>%
  mutate(wave = as.numeric("1997"))
w3_marriage = left_join(w3_marriage, w3_marriage_additional, by = "pidlink")  %>%
  mutate(wave = as.numeric("2000"))
w4_marriage = left_join(w4_marriage, w4_marriage_additional, by = "pidlink") %>%
  mutate(wave = as.numeric("2007"))
w5_marriage = left_join(w5_marriage, w5_marriage_additional, by = "pidlink") %>%
  mutate(wave = as.numeric("2014"))

## Combine marriage informations
marriage = bind_rows(w1_marriage, w2_marriage, w3_marriage, w4_marriage, w5_marriage)

# Rename columns
marriage = marriage %>%
  rename(start_year = kw10yr, start_month = kw10mth, end_year = kw18yr, end_month = kw18mth, start_age = kw11, end_age = kw19, birth_year = dob_yr, birth_age = age)


# Set values as NA that are missing (all values that are not logical)
marriage$start_year[marriage$start_year < 1900] = NA
marriage$start_year[marriage$start_year > 2016] = NA
marriage$start_year[is.nan(marriage$start_year)] = NA
marriage$end_year[marriage$end_year < 1900] = NA
marriage$end_year[marriage$end_year > 2016] = NA
marriage$end_year[is.nan(marriage$end_year)] = NA
marriage$start_month[marriage$start_month > 12] = NA
marriage$start_month[is.nan(marriage$start_month)] = NA
marriage$end_month[marriage$end_month > 12] = NA
marriage$end_month[is.nan(marriage$end_month)] = NA
marriage$start_age[marriage$start_age > 97] = NA
marriage$start_age[is.nan(marriage$start_age)] = NA
marriage$end_age[marriage$end_age > 97] = NA
marriage$end_age[is.nan(marriage$end_age)] = NA
marriage$birth_year[marriage$birth_year < 1900] = NA
marriage$birth_year[marriage$birth_year > 2016] = NA
marriage$birth_year[is.nan(marriage$birth_year)] = NA
marriage$birth_age[marriage$birth_age > 97] = NA
marriage$birth_age[is.nan(marriage$birth_age)] = NA

## Reconstruct marriage start year and end year for marriages with missing year from age at marriage
marriage = marriage %>%
  mutate(birth_year = ifelse(is.na(birth_year), wave - birth_age, birth_year),
         start_year = ifelse(is.na(start_year), birth_year + start_age, start_year),
         end_year = ifelse(is.na(end_year), birth_year + end_age, end_year))

## Arrange dataset:
marriage = marriage %>% arrange(pidlink, start_year, start_month, start_age, end_year, end_month, end_age)

## Eliminate duplicates (people who got married twice on the same day)
# propably due to some error in reporting marriages
marriage = marriage %>% filter(!duplicated(cbind(pidlink, start_year, start_month)) | is.na(start_year) | is.na(start_month)) # nobody gets married twice on the same day, right? so these are dupes.

## Calculate date for beginning of marriage:
marriage = marriage %>% 
  ungroup() %>%
  mutate(start_string = str_c(start_year, "-", ifelse(is.na(start_month), "01",
                                                      pad_month(start_month)), "-01"),
        end_string = str_c(end_year, "-", ifelse(is.na(end_month), "12", pad_month(end_month)), "-01"),
        start = ymd(start_string),
        end = ymd(end_string) + months(1) - days(1))

## Count number of marriages for every woman
marriage = marriage %>%
  arrange(pidlink, start, end) %>%
  group_by(pidlink) %>%
  mutate(number_marriages = n(),
         order_marriage = row_number(),
         marriage_id = paste0(pidlink, "_", as.character(order_marriage), "_",
                              as.character(start), "/",as.character(end)))

## Marriage Timeline: reconstruct timeline of marriages for every woman
# We need this later for reconstructing who is the father
minimum_start = min(ymd(str_c(pregnancy$month, "-01")), na.rm = T)
maximum_end = max(ymd(str_c(pregnancy$month, "-01")), na.rm = T)

marriage_timeline = marriage %>%
    mutate(implied_start = as.Date(ifelse(is.na(start), minimum_start , start),
                                   origin = "1970-01-01"),
           implied_end = as.Date(ifelse(is.na(end), maximum_end , end),
                                 origin = "1970-01-01")) %>%
  filter(implied_start < implied_end)

marriage_timeline = marriage_timeline %>%
    rowwise() %>%
    do(data.frame(
        marriage_id = .$marriage_id, 
        mother_pidlink = .$pidlink,
        order_marriage = .$order_marriage,
        start = .$start,
        end = .$end,
        month = seq(.$implied_start,.$implied_end, by = "1 month") ))

# no duplicate mother_id - month combinations (no two marriages at the same time)
marriage_timeline = marriage_timeline %>% 
  arrange(mother_pidlink, start, end) %>% 
  distinct(mother_pidlink, month, .keep_all = TRUE)

# We only need year and month, not the exact day
marriage_timeline$month = stringr::str_sub(as.character(marriage_timeline$month),1,7)

# we assume that fathers are those to whom mothers were married in the birth month
pregnancy = pregnancy %>% left_join(marriage_timeline, by = c("mother_pidlink", "month")) %>% ungroup()

Birth order calculations

Here we calculate full sibling birth order, maternal birth order and maternal pregnancy order

#### Maternal Pregnancy Order
pregnancy1 = pregnancy %>%
  group_by(mother_pidlink) %>%
  mutate(birthorder_uterus_preg = min_rank(birthdate),
         birthorder_uterus_preg2 = ifelse(is.na(birthorder_uterus_preg), chron_order_birth, 
                                          ifelse(chron_order_birth > birthorder_uterus_preg, 
                                                  chron_order_birth, birthorder_uterus_preg)),
         sibling_count_uterus_preg = sum(!is.na(birthdate)),
         sibling_count_uterus_preg2 = ifelse(is.na(sibling_count_uterus_preg), max(chron_order_birth, na.rm = T),
                                             ifelse(max(chron_order_birth, na.rm = T) > sibling_count_uterus_preg,
                                                     max(chron_order_birth, na.rm = T), sibling_count_uterus_preg))
        ) %>%
  ungroup()

cor.test(pregnancy1$birthorder_uterus_preg, pregnancy1$birthorder_uterus_preg2)
Pearson’s product-moment correlation: pregnancy1$birthorder_uterus_preg and pregnancy1$birthorder_uterus_preg2
Test statistic df P value Alternative hypothesis cor
1876 48846 0 * * * two.sided 0.9931
crosstabs(~ is.na(birthorder_uterus_preg) + is.na(birthorder_uterus_preg2) + is.na(birthdate), pregnancy1)
is.na(birthdate) FALSE TRUE
is.na(birthorder_uterus_preg) is.na(birthorder_uterus_preg2)
FALSE FALSE 48848 0
TRUE 0 0
TRUE FALSE 0 2426
TRUE 0 229
crosstabs(~ is.na(sibling_count_uterus_preg) + is.na(sibling_count_uterus_preg2) + is.na(birthdate), pregnancy1)
is.na(birthdate) FALSE TRUE
is.na(sibling_count_uterus_preg) is.na(sibling_count_uterus_preg2)
FALSE FALSE 48848 2655
# our birthdate based birthorder estimates are extremely consistent with chron_order_birth

#### Maternal Birth Order
pregnancy2 = pregnancy %>%
  filter(lifebirths == 2) %>%
  group_by(mother_pidlink) %>%
    mutate(birthorder_uterus_alive = min_rank(birthdate),
           sibling_count_uterus_alive = sum(!is.na(birthdate))
           ) %>%
  ungroup()

pregnancy2 = pregnancy2 %>% select(mother_birthdate, birthorder_uterus_alive, sibling_count_uterus_alive) %>% distinct()

#### Parental Full Sibling Birthorder (based on mother and father)
pregnancy3 = pregnancy %>%
  filter(lifebirths == 2) %>%
  group_by(marriage_id) %>%
    mutate(birthorder_genes = min_rank(birthdate),
           birthorder_genes = ifelse(is.na(marriage_id), NA, birthorder_genes),
           sibling_count_genes = ifelse(is.na(marriage_id), NA, sum(!is.na(marriage_id)))) %>%
  ungroup()

pregnancy3 = pregnancy3 %>% select(mother_birthdate, birthorder_genes, sibling_count_genes) %>% distinct()


# remove duplicates because of missings and twins
pregnancy1 <- pregnancy1 %>% select(-birthorder_uterus_preg2, -sibling_count_uterus_preg2) %>% 
  filter(!is.na(birthdate)) %>% 
  distinct(mother_birthdate, .keep_all = TRUE)

pregnancy2 <- pregnancy2 %>%
  distinct(mother_birthdate, .keep_all = TRUE)

### Combine birthorder data
pregnancy = left_join(pregnancy1, pregnancy2, by = "mother_birthdate") %>% ungroup()
pregnancy = left_join(pregnancy, pregnancy3, by = "mother_birthdate") %>% ungroup()

Birth order graphs

In order to check whether we calculated birth order correctly we created some graphs.

### Graphs are used to show differences between birth order measurements
## Biological Birthorder - Uterus_Pregnancies
ggplot(pregnancy, aes(x = sibling_count_uterus_preg, y = birthorder_uterus_preg)) +
  geom_jitter(alpha = 0.1)

## Biological Birthorder - Uterus_Births
ggplot(pregnancy, aes(x = sibling_count_uterus_alive, y = birthorder_uterus_alive)) +
  geom_jitter(alpha = 0.1)

## Biological Birthorder - Full Sibling Order
ggplot(pregnancy, aes(x = sibling_count_genes, y=birthorder_genes)) + geom_jitter(alpha = 0.1)

## Bio: Uterus_preg vs. Uterus_Births
ggplot(pregnancy, aes(x = birthorder_uterus_preg, y = birthorder_uterus_alive)) +
  geom_jitter(alpha = 0.1)

# The birth_order_alive is always lower, which makes sense, becaus not live births (miscarriage, still births) are excluded

## Bio: Uterus_preg vs. Genes
ggplot(pregnancy, aes(x = birthorder_uterus_preg, y = birthorder_genes)) + geom_jitter(alpha = 0.1)

# The birthorder_genes is always lower, which makes sense, because different/unknown fathers are excluded

## Bio: Uterus_alive vs. Genes
ggplot(pregnancy, aes(x = birthorder_uterus_alive, y = birthorder_genes))  + geom_jitter(alpha = 0.1)

# children with the same father includes only live births

# chron order birth does not correlate perfectly, unsurprising given that we found chron orders sometimes started from 1 in new waves even though previous births were recorded
pregnancy %>% select(chron_order_birth, birthorder_uterus_alive, birthorder_uterus_preg, birthorder_genes) %>%
  na.omit() %>% cor()
chron_order_birth birthorder_uterus_alive birthorder_uterus_preg birthorder_genes
1 0.7455 0.7705 0.7238
0.7455 1 0.9667 0.9679
0.7705 0.9667 1 0.9359
0.7238 0.9679 0.9359 1
pregnancy %>% select(chron_order_birth, birthorder_uterus_alive, birthorder_uterus_preg, birthorder_genes) %>% missingness_patterns()
##  index                     col missings
##      1        birthorder_genes     5864
##      2 birthorder_uterus_alive     5224
Pattern Freq Culprit
___ 42548 _
1_2 5224
1__ 640 birthorder_genes
pregnancy %>% select(sibling_count_uterus_alive, sibling_count_uterus_preg, sibling_count_genes) %>% missingness_patterns()
##  index                        col missings
##      1        sibling_count_genes     5864
##      2 sibling_count_uterus_alive     5224
Pattern Freq Culprit
___ 42548 _
1_2 5224
1__ 640 sibling_count_genes

Select individual data from IFLS 5

Here we select all variables for outcome measurements

### Individuals
individuals = bk_ar1 %>% select(hhid14_9, pidlink, father_pidlink, mother_pidlink, ar01a, ar02b, ar10, ar11, ar07, ar08day, ar08mth, ar08yr, ar09, ar18eyr, ar18emth)
individuals = left_join(individuals, bk_sc1 %>% select(hhid14_9, sc05, province, sc01_14_14), by = c("hhid14_9"))

#Rename variables:
individuals = rename(individuals, relation_to_HH_head = ar02b, fatherID = ar10, motherID = ar11, sex = ar07, age = ar09, status = ar01a, death_yr = ar18eyr, death_month = ar18emth) 
# Remove duplicats (some people are mentioned in two households, e.g. because they moved in the last 12 months)
individuals = individuals %>% distinct(pidlink, .keep_all = TRUE)
individuals_unchanged = individuals

## people whose parents can not be identified have to be marked as NA:
individuals$fatherID[individuals$fatherID > 50] = NA
individuals$motherID[individuals$motherID > 50] = NA


## Create date of birth
#Set all variables missing that have not been reported:
individuals$ar08day[individuals$ar08day > 31] = NA
individuals$ar08mth[individuals$ar08mth > 12] = NA
individuals$ar08yr[individuals$ar08yr > 2016] = NA
individuals$ar08day[is.nan(individuals$ar08day)] = NA
individuals$ar08mth[is.nan(individuals$ar08mth)] = NA
individuals$ar08yr[is.nan(individuals$ar08yr)] = NA
individuals$death_month[individuals$death_month > 12] = NA
individuals$death_yr[individuals$death_yr > 2016] = NA
individuals$death_month[is.nan(individuals$death_month)] = NA
individuals$death_yr[is.nan(individuals$death_yr)] = NA

## Create variable that contains pidlink of mother and birthdate of child:
individuals = individuals %>%
    mutate(birthdate = all_available_info_birth_date(ar08yr, ar08mth, ar08day),
           mother_birthdate = str_c(mother_pidlink, "-", birthdate)) # mother_pidlink-YYYY-MM; is NA if birth_year is missing

## Create naive birth order(based on mother_id and living in the same household)
individuals = individuals %>% group_by(mother_pidlink) %>% 
  mutate(birthorder_naive_ind = if_else(!is.na(mother_pidlink), min_rank(birthdate), NA_integer_),
         sibling_count_naive_ind = if_else(!is.na(mother_pidlink), n(), NA_integer_)) %>% 
  ungroup()

## Joing pregnancy and individuals data
alldata_pregnancy = full_join(pregnancy, individuals,
                              by = c("mother_pidlink", "birthdate", "mother_birthdate")) %>% 
  distinct(mother_pidlink, birthdate, pidlink, .keep_all = TRUE)

## check wether we have duplicated birthdates, but not reported as twins before
alldata_pregnancy = alldata_pregnancy %>% 
  group_by(mother_pidlink) %>%
  mutate(any_multiple_birthdate = if_else(any(ifelse(!is.na(birth_month), duplicated(birthdate), NA), na.rm =T), 1, 0))

crosstabs(~alldata_pregnancy$any_multiple_birthdate + alldata_pregnancy$any_multiple_birth)
0 1 NA
45034 2918 52631
34 560 64
#if we have duplicated birthdates within a family, we have to exclude these families, too (probably twins)
alldata_pregnancy = alldata_pregnancy %>% mutate(any_multiple_birth = ifelse(any_multiple_birthdate == 1, 1,
                                                                             any_multiple_birth))
alldata_pregnancy = alldata_pregnancy %>% group_by(mother_pidlink) %>% 
  mutate(birthorder_naive = min_rank(if_else(!is.na(mother_pidlink), birthdate, NA_character_)),
         sibling_count_naive = if_else(!is.na(mother_pidlink), n(), NA_integer_)) %>% 
  ungroup()

Intelligence

Calculate g factor for intelligence

### IQ Informations from wave 5 (2014)
##ek2 (>14yrs, includes only individuals, that are 15 years or older)
iq2.1 = ek_ek2 %>% select(hhid14_9, pidlink, age, sex, ektype, resptype, result, reason, ek1_ans, ek2_ans, ek3_ans, ek4_ans, ek5_ans, ek6_ans, ek7_ans, ek8_ans, ek9_ans, ek10_ans, ek11_ans, ek12_ans, ek13_ans, ek14_ans, ek15_ans, ek16_ans, ek17_ans, ek18_ans, ek19_ans, ek20_ans, ek21_ans, ek22_ans)

##ek2 (<14yrs, includes all individuals, that are younger than 15 years old)
iq3.1 = ek_ek1 %>% select(hhid14_9, pidlink, age, sex, ektype, resptype, result, reason, ek1_ans, ek2_ans, ek3_ans, ek4_ans, ek5_ans, ek6_ans, ek7_ans, ek8_ans, ek9_ans, ek10_ans, ek11_ans, ek12_ans, ek13_ans, ek14_ans, ek15_ans, ek16_ans, ek17_ans, ek18_ans, ek19_ans, ek20_ans, ek21_ans, ek22_ans)

#### Raven Test (wave 2015, younger than 15 years)
answered_raven_items = iq3.1 %>% select(ek1_ans:ek12_ans)
psych::alpha(data.frame(answered_raven_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_raven_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.87      0.87    0.88      0.36 6.9 0.0016 0.68 0.28     0.37
## 
##  lower alpha upper     95% confidence boundaries
## 0.87 0.87 0.87 
## 
##  Reliability if an item is dropped:
##          raw_alpha std.alpha G6(smc) average_r S/N alpha se var.r med.r
## ek1_ans       0.86      0.86    0.87      0.36 6.2   0.0017 0.020  0.35
## ek2_ans       0.86      0.86    0.87      0.36 6.1   0.0018 0.020  0.36
## ek3_ans       0.85      0.86    0.87      0.36 6.1   0.0018 0.020  0.36
## ek4_ans       0.86      0.86    0.87      0.36 6.2   0.0018 0.021  0.35
## ek5_ans       0.86      0.87    0.88      0.38 6.6   0.0016 0.021  0.39
## ek6_ans       0.87      0.88    0.88      0.39 7.1   0.0015 0.018  0.40
## ek7_ans       0.86      0.86    0.87      0.36 6.1   0.0017 0.017  0.37
## ek8_ans       0.85      0.86    0.86      0.35 6.0   0.0018 0.016  0.37
## ek9_ans       0.85      0.86    0.86      0.35 6.0   0.0018 0.017  0.35
## ek10_ans      0.86      0.86    0.87      0.36 6.2   0.0018 0.020  0.35
## ek11_ans      0.85      0.86    0.87      0.36 6.1   0.0018 0.019  0.35
## ek12_ans      0.87      0.88    0.89      0.40 7.3   0.0015 0.015  0.40
## 
##  Item statistics 
##              n raw.r std.r r.cor r.drop mean   sd
## ek1_ans  14943  0.66  0.68  0.64   0.60 0.87 0.33
## ek2_ans  14943  0.69  0.69  0.67   0.62 0.77 0.42
## ek3_ans  14943  0.71  0.70  0.67   0.63 0.70 0.46
## ek4_ans  14943  0.69  0.68  0.65   0.61 0.69 0.46
## ek5_ans  14943  0.59  0.57  0.51   0.48 0.61 0.49
## ek6_ans  14943  0.48  0.46  0.38   0.36 0.37 0.48
## ek7_ans  14943  0.68  0.69  0.67   0.60 0.78 0.42
## ek8_ans  14943  0.71  0.72  0.71   0.64 0.81 0.39
## ek9_ans  14943  0.73  0.74  0.73   0.67 0.79 0.41
## ek10_ans 14943  0.69  0.69  0.65   0.61 0.72 0.45
## ek11_ans 14943  0.70  0.71  0.68   0.63 0.77 0.42
## ek12_ans 14943  0.41  0.41  0.31   0.29 0.24 0.43
## 
## Non missing response frequency for each item
##             0    1 miss
## ek1_ans  0.13 0.87    0
## ek2_ans  0.23 0.77    0
## ek3_ans  0.30 0.70    0
## ek4_ans  0.31 0.69    0
## ek5_ans  0.39 0.61    0
## ek6_ans  0.63 0.37    0
## ek7_ans  0.22 0.78    0
## ek8_ans  0.19 0.81    0
## ek9_ans  0.21 0.79    0
## ek10_ans 0.28 0.72    0
## ek11_ans 0.23 0.77    0
## ek12_ans 0.76 0.24    0
iq3.1$raven_2015_young = rowMeans( answered_raven_items, na.rm = T)
qplot(iq3.1$raven_2015_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

#### Math Test (wave 2015, younger than 15 years)
answered_math_items = iq3.1 %>% select(ek13_ans:ek17_ans)
psych::alpha(data.frame(answered_math_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_math_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.62      0.62    0.59      0.24 1.6 0.0049 0.53 0.29     0.19
## 
##  lower alpha upper     95% confidence boundaries
## 0.61 0.62 0.63 
## 
##  Reliability if an item is dropped:
##          raw_alpha std.alpha G6(smc) average_r S/N alpha se  var.r med.r
## ek13_ans      0.54      0.54    0.49      0.23 1.2   0.0061 0.0107  0.19
## ek14_ans      0.51      0.51    0.46      0.21 1.1   0.0065 0.0087  0.18
## ek15_ans      0.52      0.52    0.47      0.21 1.1   0.0064 0.0117  0.17
## ek16_ans      0.61      0.61    0.56      0.28 1.6   0.0051 0.0208  0.27
## ek17_ans      0.62      0.62    0.57      0.29 1.7   0.0050 0.0170  0.29
## 
##  Item statistics 
##              n raw.r std.r r.cor r.drop mean   sd
## ek13_ans 14943  0.65  0.66  0.54   0.42 0.76 0.43
## ek14_ans 14943  0.70  0.70  0.61   0.47 0.66 0.47
## ek15_ans 14943  0.70  0.69  0.59   0.46 0.64 0.48
## ek16_ans 14943  0.57  0.56  0.36   0.28 0.34 0.47
## ek17_ans 14943  0.52  0.54  0.32   0.25 0.25 0.43
## 
## Non missing response frequency for each item
##             0    1 miss
## ek13_ans 0.24 0.76    0
## ek14_ans 0.34 0.66    0
## ek15_ans 0.36 0.64    0
## ek16_ans 0.66 0.34    0
## ek17_ans 0.75 0.25    0
iq3.1$math_2015_young = rowMeans( answered_math_items, na.rm = T)
qplot(iq3.1$math_2015_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

iq3.1 = iq3.1 %>% select(pidlink, age_2015_young = age, sex_2015_young = sex,
                         raven_2015_young, math_2015_young, reason_2015_young = reason)

##additional informations for adults: counting backwards
iq2.2 = b3b_co1 %>% select(hhid14_9, pidlink, co04a, co04b, co04c, co04d, co04e, co07count, co10count)
##additional informations for adults: adaptive number test
iq2.3 = b3b_cob %>% select(hhid14_9, pidlink, w_abil, cob18, cob19b)

## put all the informations for participants >= 15 together
iq2 = full_join(iq2.1, iq2.2, by = "pidlink")
iq2 = full_join(iq2, iq2.3, by = "pidlink")
iq = iq2
iq <- rename(iq, age_2015_old = age, reason_2015_old = reason, sex_2015_old = sex) 
iq = full_join(iq, iq3.1, by = "pidlink")

### calculate iq scores
##Raven Test (wave 2015, older than 14 years)
answered_raven_items = iq %>% select(ek1_ans:ek6_ans, ek11_ans, ek12_ans)
psych::alpha(data.frame(answered_raven_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_raven_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.85      0.85    0.84      0.41 5.5 0.0011 0.53 0.33     0.42
## 
##  lower alpha upper     95% confidence boundaries
## 0.85 0.85 0.85 
## 
##  Reliability if an item is dropped:
##          raw_alpha std.alpha G6(smc) average_r S/N alpha se var.r med.r
## ek1_ans       0.82      0.82    0.81      0.39 4.5   0.0013 0.019  0.34
## ek2_ans       0.81      0.81    0.80      0.38 4.3   0.0013 0.016  0.34
## ek3_ans       0.81      0.81    0.80      0.38 4.3   0.0013 0.019  0.31
## ek4_ans       0.82      0.81    0.81      0.38 4.4   0.0013 0.020  0.34
## ek5_ans       0.83      0.83    0.83      0.41 4.9   0.0012 0.025  0.34
## ek6_ans       0.85      0.85    0.84      0.44 5.6   0.0011 0.021  0.47
## ek11_ans      0.83      0.82    0.82      0.40 4.6   0.0012 0.023  0.34
## ek12_ans      0.86      0.86    0.85      0.46 5.9   0.0010 0.015  0.47
## 
##  Item statistics 
##              n raw.r std.r r.cor r.drop mean   sd
## ek1_ans  36380  0.74  0.74  0.71   0.65 0.74 0.44
## ek2_ans  36380  0.80  0.80  0.79   0.72 0.67 0.47
## ek3_ans  36380  0.79  0.79  0.77   0.71 0.58 0.49
## ek4_ans  36380  0.78  0.77  0.74   0.69 0.59 0.49
## ek5_ans  36380  0.68  0.68  0.60   0.56 0.50 0.50
## ek6_ans  36380  0.54  0.55  0.44   0.40 0.28 0.45
## ek11_ans 36380  0.73  0.72  0.67   0.62 0.61 0.49
## ek12_ans 36380  0.47  0.49  0.36   0.34 0.22 0.42
## 
## Non missing response frequency for each item
##             0    1 miss
## ek1_ans  0.26 0.74 0.18
## ek2_ans  0.33 0.67 0.18
## ek3_ans  0.42 0.58 0.18
## ek4_ans  0.41 0.59 0.18
## ek5_ans  0.50 0.50 0.18
## ek6_ans  0.72 0.28 0.18
## ek11_ans 0.39 0.61 0.18
## ek12_ans 0.78 0.22 0.18
iq$raven_2015_old = rowMeans( answered_raven_items, na.rm = T)
qplot(iq$raven_2015_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Math Test (wave 2015, older than 14 years)
answered_math_items = iq %>% select(ek18_ans:ek22_ans)
psych::alpha(data.frame(answered_math_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_math_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.68      0.68    0.64       0.3 2.1 0.0023 0.26 0.29     0.28
## 
##  lower alpha upper     95% confidence boundaries
## 0.68 0.68 0.69 
## 
##  Reliability if an item is dropped:
##          raw_alpha std.alpha G6(smc) average_r S/N alpha se  var.r med.r
## ek18_ans      0.68      0.67    0.61      0.34 2.1   0.0025 0.0047  0.33
## ek19_ans      0.60      0.60    0.54      0.28 1.5   0.0030 0.0026  0.26
## ek20_ans      0.60      0.60    0.53      0.27 1.5   0.0031 0.0025  0.26
## ek21_ans      0.66      0.65    0.60      0.32 1.9   0.0027 0.0074  0.31
## ek22_ans      0.63      0.62    0.56      0.29 1.7   0.0029 0.0077  0.27
## 
##  Item statistics 
##              n raw.r std.r r.cor r.drop mean   sd
## ek18_ans 36380  0.59  0.59  0.41   0.34 0.25 0.43
## ek19_ans 36380  0.71  0.71  0.61   0.50 0.28 0.45
## ek20_ans 36380  0.73  0.72  0.63   0.51 0.34 0.47
## ek21_ans 36380  0.60  0.63  0.46   0.38 0.18 0.38
## ek22_ans 36380  0.68  0.68  0.55   0.46 0.28 0.45
## 
## Non missing response frequency for each item
##             0    1 miss
## ek18_ans 0.75 0.25 0.18
## ek19_ans 0.72 0.28 0.18
## ek20_ans 0.66 0.34 0.18
## ek21_ans 0.82 0.18 0.18
## ek22_ans 0.72 0.28 0.18
iq$math_2015_old = rowMeans( answered_math_items, na.rm = T)
qplot(iq$math_2015_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Counting Items
# Create Right/Wrong Scores for the counting items
iq$co04aright = as.numeric(iq$co04a == 93)
iq$co04bright = as.numeric(iq$co04b == iq$co04a-7)
iq$co04cright = as.numeric(iq$co04c == iq$co04b-7)
iq$co04dright = as.numeric(iq$co04d == iq$co04c-7)
iq$co04eright = as.numeric(iq$co04e == iq$co04d-7)

answered_counting_items = iq %>% select(co04aright:co04eright)
psych::alpha(data.frame(answered_counting_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_counting_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.69      0.68    0.64      0.29 2.1 0.0021 0.73 0.29     0.34
## 
##  lower alpha upper     95% confidence boundaries
## 0.68 0.69 0.69 
## 
##  Reliability if an item is dropped:
##            raw_alpha std.alpha G6(smc) average_r S/N alpha se  var.r med.r
## co04aright      0.71      0.71    0.65      0.38 2.4   0.0023 0.0016  0.38
## co04bright      0.64      0.62    0.57      0.29 1.6   0.0025 0.0165  0.28
## co04cright      0.60      0.59    0.54      0.27 1.5   0.0028 0.0131  0.25
## co04dright      0.61      0.60    0.54      0.27 1.5   0.0027 0.0130  0.27
## co04eright      0.60      0.59    0.54      0.27 1.5   0.0028 0.0139  0.25
## 
##  Item statistics 
##                n raw.r std.r r.cor r.drop mean   sd
## co04aright 30452  0.43  0.51  0.27   0.23 0.95 0.22
## co04bright 29661  0.70  0.67  0.53   0.45 0.63 0.48
## co04cright 29260  0.73  0.71  0.61   0.52 0.69 0.46
## co04dright 29078  0.73  0.71  0.61   0.51 0.69 0.46
## co04eright 28983  0.73  0.71  0.61   0.52 0.70 0.46
## 
## Non missing response frequency for each item
##               0    1 miss
## co04aright 0.05 0.95 0.32
## co04bright 0.37 0.63 0.33
## co04cright 0.31 0.69 0.34
## co04dright 0.31 0.69 0.35
## co04eright 0.30 0.70 0.35
iq$count_backwards = rowMeans( answered_counting_items, na.rm = T)
qplot(iq$count_backwards)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

## Word Memory
iq$words_immediate = iq$co07count
iq$words_delayed = iq$co10count
qplot(iq$words_immediate, iq$words_delayed, geom = "jitter")

answered_word_items = iq %>% select(co07count,co10count)
psych::alpha(data.frame(answered_word_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_word_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean  sd median_r
##       0.87      0.87    0.77      0.77 6.8 0.0012  4.6 1.8     0.77
## 
##  lower alpha upper     95% confidence boundaries
## 0.87 0.87 0.87 
## 
##  Reliability if an item is dropped:
##           raw_alpha std.alpha G6(smc) average_r S/N alpha se var.r med.r
## co07count      0.77      0.77     0.6      0.77  NA       NA  0.77  0.77
## co10count      0.60      0.77      NA        NA  NA       NA  0.60  0.77
## 
##  Item statistics 
##               n raw.r std.r r.cor r.drop mean  sd
## co07count 31471  0.94  0.94  0.83   0.77  5.1 1.8
## co10count 31471  0.94  0.94  0.83   0.77  4.2 1.9
iq$words_remembered_avg = rowMeans( answered_word_items, na.rm = T)
qplot(iq$words_remembered_avg)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Adaptive Numbering
iq$adaptive_numbering = iq$w_abil
qplot(iq$adaptive_numbering)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# some people have reasons not to answer the test (dead, not contacted), that dont justify
# giving them zero points for that task. so i set these to NA
# additionally all participants older than 59 only answered the Raven Test, not the Math 
# Test
iq = iq %>%
  mutate(reason_2015_young = ifelse(reason_2015_young == 1, "refused",
                   ifelse(reason_2015_young == 2, "cannot read",
                   ifelse(reason_2015_young == 3, "unable to answer",
                   ifelse(reason_2015_young == 4, "not enough time",
                   ifelse(reason_2015_young == 5, "proxy respondent",
                   ifelse(reason_2015_young == 6, "other",
                   ifelse(reason_2015_young == 7, "could not be contacted", NA))))))),
         raven_2015_young = ifelse(is.na(reason_2015_young), raven_2015_young,
                             ifelse(reason_2015_young == "cannot read"|
                                    reason_2015_young == "not enough time"|
                                    reason_2015_young == "proxy respondent"|
                                    reason_2015_young == "other"|
                                    reason_2015_young == "refused"|
                                    reason_2015_young == "could not be contacted", NA,
                                    raven_2015_young)),
         math_2015_young = ifelse(is.na(reason_2015_young), math_2015_young,
                             ifelse(reason_2015_young == "cannot read"|
                                    reason_2015_young == "not enough time"|
                                    reason_2015_young == "proxy respondent"|
                                    reason_2015_young == "other"|
                                    reason_2015_young == "refused"|
                                    reason_2015_young == "could not be contacted", NA,
                                    math_2015_young)),
         reason_2015_old = ifelse(reason_2015_old == 1, "refused",
                   ifelse(reason_2015_old == 2, "cannot read",
                   ifelse(reason_2015_old == 3, "unable to answer",
                   ifelse(reason_2015_old == 4, "not enough time",
                   ifelse(reason_2015_old == 5, "proxy respondent",
                   ifelse(reason_2015_old == 6, "other",
                   ifelse(reason_2015_old == 7, "could not be contacted", NA))))))),
         raven_2015_old = ifelse(is.na(reason_2015_old), raven_2015_old,
                             ifelse(reason_2015_old == "cannot read"|
                                    reason_2015_old == "not enough time"|
                                    reason_2015_old == "proxy respondent"|
                                    reason_2015_old == "other"|
                                    reason_2015_old == "refused"|
                                    reason_2015_old == "could not be contacted", NA,
                                    raven_2015_old)),
         math_2015_old = ifelse(is.na(reason_2015_old), math_2015_old,
                             ifelse(reason_2015_old == "cannot read"|
                                    reason_2015_old == "not enough time"|
                                    reason_2015_old == "proxy respondent"|
                                    reason_2015_old == "other"|
                                    reason_2015_old == "refused"|
                                    reason_2015_old == "could not be contacted", NA,
                                    math_2015_old)),
         math_2015_old = ifelse(age_2015_old >= 60, NA, math_2015_old))

iq %>% select(raven_2015_old, math_2015_old, raven_2015_young, math_2015_young, count_backwards, words_immediate, words_delayed, adaptive_numbering) %>% tidyr::gather() %>%
  ggplot(aes(value)) + geom_bar() + facet_wrap(~ key, scales = "free")

Intelligence from earlier waves

## Wave 4 - 2007
### Data
iq2007_ek2= bek_ek2 %>%
  select(pidlink, ektype, reason_2007_old = reason, "age_2007_old" = age,
         sex_2007_old = sex, matches("ek[0-9]x"), matches("ek[0-9][0-9]x"))

iq2007_ek1= bek_ek1 %>%
  select(pidlink, ektype, reason_2007_young = reason, "age_2007_young" = age,
         sex_2007_young = sex, matches("ek[0-9]x"), matches("ek[0-9][0-9]x")) %>%
  filter(!(pidlink %in% iq2007_ek2$pidlink))

# some people answered both versions of the test
# (depending on whether they had seen test ek1 already in 2000)
# In order to deal with them i form an additional dataset that includes the information from
# the people that repeated the first test and their score on the first test in 2007
# that means they have already seen the test 7 years before...
# i merge this data later in the same column as the other scores in 2007 in the first test
# check with Ruben, if that is the right way to go...

iq2007_ek1_repeater = bek_ek1 %>%
  select(pidlink, ektype, reason_2007_young_repeater = reason,
         "age_2007_young_repeater" = age, sex_2007_young_repeater = sex,
         matches("ek[0-9]x"), matches("ek[0-9][0-9]x")) %>%
  filter((pidlink %in% iq2007_ek2$pidlink))

iq2007 = bind_rows(iq2007_ek1, iq2007_ek2) 

### Raven
iq2007 = iq2007 %>%
  mutate(ek1x = ifelse(ek1x == 1, 1,
                       ifelse(ek1x == 6, NA, 0)),
         ek2x = ifelse(ek2x == 1,  1,
                       ifelse(ek2x == 6, NA, 0)),
         ek3x = ifelse(ek3x == 1,  1,
                       ifelse(ek3x == 6, NA, 0)),
         ek4x = ifelse(ek4x == 1,  1,
                       ifelse(ek4x == 6, NA, 0)),
         ek5x = ifelse(ek5x == 1,  1,
                       ifelse(ek5x == 6, NA, 0)),
         ek6x = ifelse(ek6x == 1,  1,
                       ifelse(ek6x == 6, NA, 0)),
         ek7x = ifelse(ek7x == 1,  1,
                       ifelse(ek7x == 6, NA, 0)),
         ek8x = ifelse(ek8x == 1,  1,
                       ifelse(ek8x == 6, NA, 0)),
         ek9x = ifelse(ek9x == 1,  1,
                       ifelse(ek9x == 6, NA, 0)),
         ek10x = ifelse(ek10x == 1, 1,
                       ifelse(ek10x == 6, NA, 0)),
         ek11x = ifelse(ek11x == 1,  1,
                       ifelse(ek11x == 6, NA, 0)),
         ek12x = ifelse(ek12x == 1,  1,
                       ifelse(ek12x == 6, NA, 0)))

answered_raven_items = iq2007 %>% select(ek1x:ek12x)
psych::alpha(data.frame(answered_raven_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_raven_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.85      0.87    0.87      0.35 6.4 0.0016 0.69 0.28     0.34
## 
##  lower alpha upper     95% confidence boundaries
## 0.85 0.85 0.86 
## 
##  Reliability if an item is dropped:
##       raw_alpha std.alpha G6(smc) average_r S/N alpha se var.r med.r
## ek1x       0.84      0.85    0.86      0.34 5.7   0.0017 0.014  0.34
## ek2x       0.83      0.85    0.86      0.34 5.6   0.0018 0.014  0.33
## ek3x       0.83      0.85    0.85      0.34 5.6   0.0018 0.014  0.33
## ek4x       0.84      0.85    0.86      0.34 5.7   0.0018 0.014  0.34
## ek5x       0.85      0.86    0.87      0.36 6.1   0.0017 0.016  0.35
## ek6x       0.85      0.87    0.87      0.37 6.5   0.0016 0.013  0.37
## ek7x       0.84      0.85    0.85      0.34 5.8   0.0017 0.011  0.34
## ek8x       0.84      0.85    0.85      0.34 5.7   0.0017 0.011  0.34
## ek9x       0.84      0.85    0.86      0.35 5.8   0.0017 0.014  0.34
## ek10x      0.84      0.86    0.87      0.35 6.0   0.0017 0.016  0.34
## ek11x      0.84      0.85    0.86      0.34 5.7   0.0017 0.015  0.34
## ek12x      0.86      0.87    0.87      0.37 6.5   0.0015 0.012  0.37
## 
##  Item statistics 
##           n raw.r std.r r.cor r.drop mean   sd
## ek1x  18508  0.63  0.69  0.65   0.58 0.89 0.31
## ek2x  18508  0.73  0.71  0.69   0.65 0.74 0.44
## ek3x  18508  0.75  0.72  0.70   0.67 0.70 0.46
## ek4x  18508  0.72  0.69  0.66   0.62 0.69 0.46
## ek5x  18508  0.63  0.59  0.52   0.50 0.64 0.48
## ek6x  18508  0.55  0.48  0.40   0.39 0.42 0.49
## ek7x   6684  0.62  0.67  0.65   0.55 0.92 0.27
## ek8x   6684  0.63  0.68  0.67   0.56 0.91 0.29
## ek9x   6684  0.63  0.65  0.61   0.54 0.85 0.36
## ek10x  6684  0.61  0.61  0.55   0.51 0.79 0.40
## ek11x 18508  0.65  0.68  0.64   0.58 0.82 0.38
## ek12x 18508  0.54  0.47  0.38   0.37 0.40 0.49
## 
## Non missing response frequency for each item
##          0    1 miss
## ek1x  0.11 0.89 0.00
## ek2x  0.26 0.74 0.00
## ek3x  0.30 0.70 0.00
## ek4x  0.31 0.69 0.00
## ek5x  0.36 0.64 0.00
## ek6x  0.58 0.42 0.00
## ek7x  0.08 0.92 0.64
## ek8x  0.09 0.91 0.64
## ek9x  0.15 0.85 0.64
## ek10x 0.21 0.79 0.64
## ek11x 0.18 0.82 0.00
## ek12x 0.60 0.40 0.00
iq2007$raven2007 = rowMeans(answered_raven_items, na.rm = T)
iq2007 = iq2007 %>%
  mutate(raven_2007_young = ifelse(ektype == 1, raven2007, NA),
         raven_2007_old = ifelse(ektype == 2, raven2007, NA))
qplot(iq2007$raven_2007_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qplot(iq2007$raven_2007_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Math Test
iq2007 = iq2007 %>%
  mutate(ek13x = ifelse(ek13x == 1, 1,
                       ifelse(ek13x == 6, NA, 0)),
         ek14x = ifelse(ek14x == 1,  1,
                       ifelse(ek14x == 6, NA, 0)),
         ek15x = ifelse(ek15x == 1,  1,
                       ifelse(ek15x == 6, NA, 0)),
         ek16x = ifelse(ek16x == 1,  1,
                       ifelse(ek16x == 6, NA, 0)),
         ek17x = ifelse(ek17x == 1,  1,
                       ifelse(ek17x == 6, NA, 0)),
         ek18x = ifelse(ek18x == 1,  1,
                       ifelse(ek18x == 6, NA, 0)),
         ek19x = ifelse(ek19x == 1,  1,
                       ifelse(ek19x == 6, NA, 0)),
         ek20x = ifelse(ek20x == 1,  1,
                       ifelse(ek20x == 6, NA, 0)),
         ek21x = ifelse(ek21x == 1,  1,
                       ifelse(ek21x == 6, NA, 0)),
         ek22x = ifelse(ek22x == 1, 1,
                       ifelse(ek22x == 6, NA, 0)))

answered_math_items = iq2007 %>% select(ek13x:ek22x)
iq2007$math2007 = rowMeans( answered_math_items, na.rm = T)
iq2007 = iq2007 %>%
  mutate(math_2007_young = ifelse(ektype == 1, math2007, NA),
         math_2007_old = ifelse(ektype == 2, math2007, NA))
qplot(iq2007$math_2007_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qplot(iq2007$math_2007_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

iq2007 = iq2007 %>% select(pidlink, age_2007_young, age_2007_old, sex_2007_young,
                           sex_2007_old, raven_2007_young, raven_2007_old, math_2007_young,
                           math_2007_old, reason_2007_old, reason_2007_young)

##Do the same for the repeater
### Raven
iq2007_ek1_repeater = iq2007_ek1_repeater %>%
  mutate(ek1x = ifelse(ek1x == 1, 1,
                       ifelse(ek1x == 6, NA, 0)),
         ek2x = ifelse(ek2x == 1,  1,
                       ifelse(ek2x == 6, NA, 0)),
         ek3x = ifelse(ek3x == 1,  1,
                       ifelse(ek3x == 6, NA, 0)),
         ek4x = ifelse(ek4x == 1,  1,
                       ifelse(ek4x == 6, NA, 0)),
         ek5x = ifelse(ek5x == 1,  1,
                       ifelse(ek5x == 6, NA, 0)),
         ek6x = ifelse(ek6x == 1,  1,
                       ifelse(ek6x == 6, NA, 0)),
         ek7x = ifelse(ek7x == 1,  1,
                       ifelse(ek7x == 6, NA, 0)),
         ek8x = ifelse(ek8x == 1,  1,
                       ifelse(ek8x == 6, NA, 0)),
         ek9x = ifelse(ek9x == 1,  1,
                       ifelse(ek9x == 6, NA, 0)),
         ek10x = ifelse(ek10x == 1, 1,
                       ifelse(ek10x == 6, NA, 0)),
         ek11x = ifelse(ek11x == 1,  1,
                       ifelse(ek11x == 6, NA, 0)),
         ek12x = ifelse(ek12x == 1,  1,
                       ifelse(ek12x == 6, NA, 0)))

answered_raven_items = iq2007_ek1_repeater %>% select(ek1x:ek12x)
psych::alpha(data.frame(answered_raven_items))
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(answered_raven_items))
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean   sd median_r
##       0.87      0.89     0.9      0.41 8.2 0.0028 0.78 0.25     0.41
## 
##  lower alpha upper     95% confidence boundaries
## 0.87 0.87 0.88 
## 
##  Reliability if an item is dropped:
##       raw_alpha std.alpha G6(smc) average_r S/N alpha se var.r med.r
## ek1x       0.86      0.88    0.89      0.40 7.3   0.0031 0.020  0.40
## ek2x       0.86      0.88    0.89      0.40 7.3   0.0032 0.023  0.39
## ek3x       0.85      0.88    0.89      0.40 7.3   0.0033 0.022  0.39
## ek4x       0.86      0.88    0.89      0.40 7.5   0.0032 0.023  0.42
## ek5x       0.87      0.89    0.90      0.42 8.0   0.0030 0.023  0.43
## ek6x       0.88      0.89    0.90      0.44 8.5   0.0027 0.019  0.43
## ek7x       0.86      0.88    0.88      0.39 7.1   0.0031 0.017  0.40
## ek8x       0.86      0.88    0.88      0.39 7.1   0.0031 0.016  0.40
## ek9x       0.86      0.88    0.89      0.39 7.1   0.0032 0.019  0.40
## ek10x      0.86      0.88    0.89      0.40 7.3   0.0032 0.022  0.40
## ek11x      0.86      0.88    0.89      0.40 7.5   0.0031 0.022  0.40
## ek12x      0.88      0.90    0.90      0.44 8.6   0.0027 0.018  0.43
## 
##  Item statistics 
##          n raw.r std.r r.cor r.drop mean   sd
## ek1x  4518  0.69  0.73  0.71   0.64 0.91 0.29
## ek2x  4518  0.72  0.72  0.69   0.65 0.81 0.40
## ek3x  4518  0.76  0.74  0.72   0.69 0.78 0.41
## ek4x  4518  0.71  0.69  0.65   0.62 0.76 0.43
## ek5x  4518  0.61  0.58  0.51   0.49 0.69 0.46
## ek6x  4518  0.53  0.48  0.40   0.39 0.48 0.50
## ek7x  4518  0.71  0.76  0.76   0.66 0.92 0.27
## ek8x  4518  0.73  0.78  0.78   0.68 0.92 0.27
## ek9x  4518  0.73  0.77  0.75   0.67 0.90 0.30
## ek10x 4518  0.70  0.72  0.69   0.64 0.87 0.34
## ek11x 4518  0.67  0.69  0.65   0.59 0.86 0.35
## ek12x 4518  0.51  0.46  0.37   0.37 0.46 0.50
## 
## Non missing response frequency for each item
##          0    1 miss
## ek1x  0.09 0.91    0
## ek2x  0.19 0.81    0
## ek3x  0.22 0.78    0
## ek4x  0.24 0.76    0
## ek5x  0.31 0.69    0
## ek6x  0.52 0.48    0
## ek7x  0.08 0.92    0
## ek8x  0.08 0.92    0
## ek9x  0.10 0.90    0
## ek10x 0.13 0.87    0
## ek11x 0.14 0.86    0
## ek12x 0.54 0.46    0
iq2007_ek1_repeater$raven_2007_young_repeater = rowMeans(answered_raven_items, na.rm = T)
qplot(iq2007_ek1_repeater$raven_2007_young_repeater)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Math Test
iq2007_ek1_repeater = iq2007_ek1_repeater %>%
  mutate(ek13x = ifelse(ek13x == 1, 1,
                       ifelse(ek13x == 6, NA, 0)),
         ek14x = ifelse(ek14x == 1,  1,
                       ifelse(ek14x == 6, NA, 0)),
         ek15x = ifelse(ek15x == 1,  1,
                       ifelse(ek15x == 6, NA, 0)),
         ek16x = ifelse(ek16x == 1,  1,
                       ifelse(ek16x == 6, NA, 0)),
         ek17x = ifelse(ek17x == 1,  1,
                       ifelse(ek17x == 6, NA, 0)),
         ek18x = ifelse(ek18x == 1,  1,
                       ifelse(ek18x == 6, NA, 0)),
         ek19x = ifelse(ek19x == 1,  1,
                       ifelse(ek19x == 6, NA, 0)),
         ek20x = ifelse(ek20x == 1,  1,
                       ifelse(ek20x == 6, NA, 0)),
         ek21x = ifelse(ek21x == 1,  1,
                       ifelse(ek21x == 6, NA, 0)),
         ek22x = ifelse(ek22x == 1, 1,
                       ifelse(ek22x == 6, NA, 0)))

answered_math_items = iq2007_ek1_repeater %>% select(ek13x:ek22x)
iq2007_ek1_repeater$math_2007_young_repeater = rowMeans( answered_math_items, na.rm = T)
qplot(iq2007_ek1_repeater$math_2007_young_repeater)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

iq2007_ek1_repeater = iq2007_ek1_repeater %>%
  select(pidlink, raven_2007_young_repeater, math_2007_young_repeater,
         reason_2007_young_repeater, age_2007_young_repeater, sex_2007_young_repeater)

iq2007_all = left_join(iq2007, iq2007_ek1_repeater, by = "pidlink")

# Now we instert raven and math scores from the repeaters as raven and math scores young
# Treat them like all the others.
crosstabs(is.na(iq2007_all$raven_2007_young) + is.na(iq2007_all$raven_2007_young_repeater))
FALSE TRUE
0 6684
4518 7306
iq2007_all = iq2007_all %>%
  mutate(raven_2007_young = ifelse(!is.na(raven_2007_young_repeater),
                                   raven_2007_young_repeater, raven_2007_young),
         math_2007_young = ifelse(!is.na(math_2007_young_repeater),
                                  math_2007_young_repeater, math_2007_young),
         age_2007_young = ifelse(!is.na(age_2007_young_repeater),
                                 age_2007_young_repeater, age_2007_young),
         sex_2007_young = ifelse(!is.na(sex_2007_young_repeater),
                                 sex_2007_young_repeater, sex_2007_young))

iq2007_all = iq2007_all %>% select(pidlink, age_2007_young, age_2007_old, raven_2007_old,
                                   raven_2007_young, math_2007_young, math_2007_old,
                                   reason_2007_young, reason_2007_old)

# some people have reasons not to answer the test (dead, not contacted), that dont justify
# giving them zero points for that task. so i set these to NA
# it is important to note that raven and math test were only answered by participants
# aged 7 - 24
iq2007_all = iq2007_all %>%
  mutate(reason_2007_young = ifelse(reason_2007_young == 1, "refused",
                   ifelse(reason_2007_young == 2, "cannot read",
                   ifelse(reason_2007_young == 3, "unable to answer",
                   ifelse(reason_2007_young == 4, "not enough time",
                   ifelse(reason_2007_young == 5, "proxy respondent",
                   ifelse(reason_2007_young == 6, "other",
                   ifelse(reason_2007_young == 7, "could not be contacted", NA))))))),
         raven_2007_young = ifelse(is.na(reason_2007_young), raven_2007_young,
                             ifelse(reason_2007_young == "cannot read"|
                                    reason_2007_young == "not enough time"|
                                    reason_2007_young == "proxy respondent"|
                                    reason_2007_young == "other"|
                                    reason_2007_young == "refused"|
                                    reason_2007_young == "could not be contacted", NA,
                                    raven_2007_young)),
         math_2007_young = ifelse(is.na(reason_2007_young), math_2007_young,
                             ifelse(reason_2007_young == "cannot read"|
                                    reason_2007_young == "not enough time"|
                                    reason_2007_young == "proxy respondent"|
                                    reason_2007_young == "other"|
                                    reason_2007_young == "refused"|
                                    reason_2007_young == "could not be contacted", NA,
                                    math_2007_young)),
         reason_2007_old = ifelse(reason_2007_old == 1, "refused",
                   ifelse(reason_2007_old == 2, "cannot read",
                   ifelse(reason_2007_old == 3, "unable to answer",
                   ifelse(reason_2007_old == 4, "not enough time",
                   ifelse(reason_2007_old == 5, "proxy respondent",
                   ifelse(reason_2007_old == 6, "other",
                   ifelse(reason_2007_old == 7, "could not be contacted", NA))))))),
         raven_2007_old = ifelse(is.na(reason_2007_old), raven_2007_old,
                             ifelse(reason_2007_old == "cannot read"|
                                    reason_2007_old == "not enough time"|
                                    reason_2007_old == "proxy respondent"|
                                    reason_2007_old == "other"|
                                    reason_2007_old == "refused"|
                                    reason_2007_old == "could not be contacted", NA,
                                    raven_2007_old)),
         math_2007_old = ifelse(is.na(reason_2007_old), math_2007_old,
                             ifelse(reason_2007_old == "cannot read"|
                                    reason_2007_old == "not enough time"|
                                    reason_2007_old == "proxy respondent"|
                                    reason_2007_old == "other"|
                                    reason_2007_young == "refused"|
                                    reason_2007_old == "could not be contacted", NA,
                                    math_2007_old)))

iq2007_all %>% select(raven_2007_old, math_2007_old, raven_2007_young, math_2007_young) %>% tidyr::gather() %>%  ggplot(aes(value)) + geom_bar() + facet_wrap(~ key, scales = "free")

iq = full_join(iq, iq2007_all, by = "pidlink") %>%
  select(-matches("ek[0-9]_ans"), -matches("ek[0-9][0-9]_ans"), -starts_with("hhid"),
         -ektype, -resptype, -result, -starts_with("reason"), -starts_with("co"),
         count_backwards, -w_abil)

Correlations and Missingness Patterns for Intelligence

## IQ Tests 
## Correlation of all Iq-Tests
round(cor(iq %>% select(raven_2015_old, math_2015_old, raven_2015_young, math_2015_young, count_backwards, words_immediate, words_delayed, adaptive_numbering, raven_2007_old, math_2007_young), use = "pairwise.complete.obs"), 2)
raven_2015_old math_2015_old raven_2015_young math_2015_young count_backwards words_immediate words_delayed adaptive_numbering raven_2007_old math_2007_young
1 0.36 0.69 0.31 0.27 0.39 0.37 0.45 0.37 0.19
0.36 1 0.31 0.5 0.21 0.25 0.25 0.31 0.21 0.23
0.69 0.31 1 0.4 0.22 0.19 0.19 0.3 0.32 0.13
0.31 0.5 0.4 1 0.23 0.18 0.18 0.29 0.18 0.19
0.27 0.21 0.22 0.23 1 0.23 0.22 0.33 0.23 0.17
0.39 0.25 0.19 0.18 0.23 1 0.77 0.4 0.2 0.13
0.37 0.25 0.19 0.18 0.22 0.77 1 0.37 0.18 0.13
0.45 0.31 0.3 0.29 0.33 0.4 0.37 1 0.3 0.22
0.37 0.21 0.32 0.18 0.23 0.2 0.18 0.3 1 0.32
0.19 0.23 0.13 0.19 0.17 0.13 0.13 0.22 0.32 1
##Missingness_Patterns
formr::missingness_patterns(iq %>% select(raven_2015_old, math_2015_old, raven_2015_young, math_2015_young, count_backwards, words_immediate, words_delayed, adaptive_numbering, raven_2007_old, math_2007_young))
##  index                col missings
##      1    math_2007_young    37147
##      2     raven_2007_old    36988
##      3   raven_2015_young    34066
##      4    math_2015_young    34066
##      5      math_2015_old    19612
##      6    count_backwards    17635
##      7 adaptive_numbering    16678
##      8     raven_2015_old    16669
##      9    words_immediate    16616
##     10      words_delayed    16616
Pattern Freq Culprit
1_2_3_4_____________ 15403
1_2_____5_6_7_8_9_10 6889
1_3_4___________ 4987
1_2_3_4_5_6_7_8_9_10 4129
2_______________ 3490 raven_2007_old
____________________ 2629 _
1_2_3_4_5___________ 2593
1___3_4_5_6_7_8_9_10 1616
__2_3_4_5_6_7_8_9_10 1547
____3_4_5_6_7_8_9_10 1171
2___5_6_7_8_9_10 888
2_3_4___________ 601
1_2_3_4_6_______ 482
____3_4_____________ 416
1_2_3_4_5_____8_____ 248
1_2_3_4_5_6_________ 188
1_2_3_4_5_6_7___9_10 160
1_2_3_4_6_7_9_10 140
1_3_46________ 121
1_2_3_4_5_6_8___ 66
2_____6_________ 54
1_3_4_58__ 38
__________6_________ 38 count_backwards
1_3_4_6_7___9_10 33
1_2_3_4_5_6_7_8_____ 23
2_3_4_58__ 15
2_3_46________ 14
2_____6_7___9_10 14
1_2_3_4_5_7_8___ 13
__________6_7___9_10 13
____3_4_5_____8_____ 12
2_3_4_6_7___9_10 11
____3_4_6_______ 11
1_2_3_4_6_7_____ 8
____3_4_5_6_7_8_____ 3
____3_4_6_7_9_10 3
1_2_3_4_5_6_7_______ 2
1_2_3_4_____7_______ 2
2_3_4_5_6_7_8___ 2
2_3_4_57_8____ 2
__________6_7_______ 2
1_2_____5_____8_____ 1
1_3_4_5_6_7_8___ 1
1_3_4_5_68____ 1
1_3_4_57_8____ 1
1_3_47____ 1
1_______5_6_7_8_9_10 1
2_3_4_5_68____ 1
2_3_46_7______ 1
2_____6_7_______ 1
________5_6_7_8_9_10 1
iq %>% select(raven_2015_old, math_2015_old, raven_2015_young, math_2015_young, raven_2007_old, math_2007_old, raven_2007_young, math_2007_young, count_backwards, words_immediate, words_delayed, adaptive_numbering) %>% tidyr::gather() %>%
  ggplot(aes(value)) + geom_bar() + facet_wrap(~ key, scales = "free")

Calculation of different g-factors

# G_factor_2015_old
nomiss = iq %>%
  filter(!is.na(raven_2015_old), !is.na(math_2015_old), !is.na(count_backwards),
         !is.na(words_delayed), !is.na(adaptive_numbering))


"g_factor_2015_old =~ raven_2015_old + math_2015_old + count_backwards +  words_delayed+  adaptive_numbering" %>%
  cfa(data = nomiss, std.lv = T, std.ov = T) -> cfa_g

summary(cfa_g, fit.measures = T, standardized = T, rsquare = TRUE)
## lavaan 0.6-3 ended normally after 14 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         10
## 
##   Number of observations                         27526
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     198.999
##   Degrees of freedom                                 5
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic            17985.333
##   Degrees of freedom                                10
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.989
##   Tucker-Lewis Index (TLI)                       0.978
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -186392.843
##   Loglikelihood unrestricted model (H1)     -186293.344
## 
##   Number of free parameters                         10
##   Akaike (AIC)                              372805.686
##   Bayesian (BIC)                            372887.915
##   Sample-size adjusted Bayesian (BIC)       372856.135
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.038
##   90 Percent Confidence Interval          0.033  0.042
##   P-value RMSEA <= 0.05                          1.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.015
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                        Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   g_factor_2015_old =~                                                      
##     raven_2015_old        0.650    0.007   94.857    0.000    0.650    0.650
##     math_2015_old         0.501    0.007   72.702    0.000    0.501    0.501
##     count_backwrds        0.452    0.007   65.043    0.000    0.452    0.452
##     words_delayed         0.478    0.007   69.072    0.000    0.478    0.478
##     adaptiv_nmbrng        0.632    0.007   92.413    0.000    0.632    0.632
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .raven_2015_old    0.578    0.007   77.886    0.000    0.578    0.578
##    .math_2015_old     0.749    0.008   99.579    0.000    0.749    0.749
##    .count_backwrds    0.796    0.008  103.868    0.000    0.796    0.796
##    .words_delayed     0.772    0.008  101.737    0.000    0.772    0.772
##    .adaptiv_nmbrng    0.600    0.007   81.214    0.000    0.600    0.600
##     g_fctr_2015_ld    1.000                               1.000    1.000
## 
## R-Square:
##                    Estimate
##     raven_2015_old    0.422
##     math_2015_old     0.251
##     count_backwrds    0.204
##     words_delayed     0.228
##     adaptiv_nmbrng    0.400
nomiss$g_factor_2015_old = predict(cfa_g)[,1]

qplot(nomiss$g_factor_2015_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

nomiss = nomiss %>% select(pidlink, g_factor_2015_old)

iq = left_join(iq, nomiss, by = "pidlink")

# G_factor_2015_young
nomiss = iq %>%
  filter(!is.na(raven_2015_young), !is.na(math_2015_young))


fa.parallel(nomiss %>% select(raven_2015_young, math_2015_young) %>% data.frame())

## Parallel analysis suggests that the number of factors =  1  and the number of components =  1
fa(nomiss %>% select(raven_2015_young, math_2015_young) %>% data.frame(), nfactors = 1)
## Factor Analysis using method =  minres
## Call: fa(r = nomiss %>% select(raven_2015_young, math_2015_young) %>% 
##     data.frame(), nfactors = 1)
## Standardized loadings (pattern matrix) based upon correlation matrix
##                   MR1  h2  u2 com
## raven_2015_young 0.63 0.4 0.6   1
## math_2015_young  0.63 0.4 0.6   1
## 
##                MR1
## SS loadings    0.8
## Proportion Var 0.4
## 
## Mean item complexity =  1
## Test of the hypothesis that 1 factor is sufficient.
## 
## The degrees of freedom for the null model are  1  and the objective function was  0.18 with Chi Square of  2456
## The degrees of freedom for the model are -1  and the objective function was  0 
## 
## The root mean square of the residuals (RMSR) is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## The harmonic number of observations is  14021 with the empirical chi square  0  with prob <  NA 
## The total number of observations was  14021  with Likelihood Chi Square =  0  with prob <  NA 
## 
## Tucker Lewis Index of factoring reliability =  1
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy             
##                                                    MR1
## Correlation of (regression) scores with factors   0.76
## Multiple R square of scores with factors          0.57
## Minimum correlation of possible factor scores     0.14
om_results = omega(nomiss %>% select(raven_2015_young, math_2015_young) %>% data.frame(), nfactors = 1, sl = F)
## Omega_h for 1 factor is not meaningful, just omega_t
om_results
## Omega 
## Call: omega(m = nomiss %>% select(raven_2015_young, math_2015_young) %>% 
##     data.frame(), nfactors = 1, sl = F)
## Alpha:                 0.57 
## G.6:                   0.4 
## Omega Hierarchical:    0.57 
## Omega H asymptotic:    1 
## Omega Total            0.57 
## 
## Schmid Leiman Factor loadings greater than  0.2 
##                     g F1*  h2  u2 p2
## raven_2015_young 0.63     0.4 0.6  1
## math_2015_young  0.63     0.4 0.6  1
## 
## With eigenvalues of:
##   g F1* 
## 0.8 0.0 
## 
## general/max  Inf   max/min =   NaN
## mean percent general =  1    with sd =  0 and cv of  0 
## Explained Common Variance of the general factor =  1 
## 
## The degrees of freedom are -1  and the fit is  0 
## The number of observations was  14021  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA
## 
## Compare this with the adequacy of just a general factor and no group factors
## The degrees of freedom for just the general factor are -1  and the fit is  0 
## The number of observations was  14021  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## Measures of factor score adequacy             
##                                                  g F1*
## Correlation of scores with factors            0.76   0
## Multiple R square of scores with factors      0.57   0
## Minimum correlation of factor score estimates 0.14  -1
## 
##  Total, General and Subset omega for each subset
##                                                  g  F1*
## Omega total for total scores and subscales    0.57 0.57
## Omega general for total scores and subscales  0.57 0.57
## Omega group for total scores and subscales    0.00 0.00
omega.diagram(om_results)

"g_factor_2015_young =~ raven_2015_young + math_2015_young" %>%
  cfa(data = nomiss, std.lv = T, std.ov = T) -> cfa_g
summary(cfa_g)
## lavaan 0.6-3 ended normally after 9 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                          4
## 
##   Number of observations                         14021
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                          NA
##   Degrees of freedom                                -1
##   Minimum Function Value               0.0000000000000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                          Estimate  Std.Err  z-value  P(>|z|)
##   g_factor_2015_young =~                                    
##     raven_2015_yng          0.786       NA                  
##     math_2015_yong          0.510       NA                  
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .raven_2015_yng    0.382       NA                  
##    .math_2015_yong    0.740       NA                  
##     g_fctr_2015_yn    1.000
nomiss$g_factor_2015_young = predict(cfa_g)[,1]

qplot(nomiss$g_factor_2015_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

nomiss = nomiss %>% select(pidlink, g_factor_2015_young)

iq = left_join(iq, nomiss, by = "pidlink")

# G_factor_2007_old
nomiss = iq %>%
  filter(!is.na(raven_2007_old), !is.na(math_2007_old))


fa.parallel(nomiss %>% select(raven_2007_old, math_2007_old) %>% data.frame())

## Parallel analysis suggests that the number of factors =  1  and the number of components =  1
fa(nomiss %>% select(raven_2007_old, math_2007_old) %>% data.frame(), nfactors = 1)
## Factor Analysis using method =  minres
## Call: fa(r = nomiss %>% select(raven_2007_old, math_2007_old) %>% data.frame(), 
##     nfactors = 1)
## Standardized loadings (pattern matrix) based upon correlation matrix
##                 MR1   h2   u2 com
## raven_2007_old 0.59 0.35 0.65   1
## math_2007_old  0.59 0.35 0.65   1
## 
##                 MR1
## SS loadings    0.70
## Proportion Var 0.35
## 
## Mean item complexity =  1
## Test of the hypothesis that 1 factor is sufficient.
## 
## The degrees of freedom for the null model are  1  and the objective function was  0.13 with Chi Square of  1467
## The degrees of freedom for the model are -1  and the objective function was  0 
## 
## The root mean square of the residuals (RMSR) is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## The harmonic number of observations is  11082 with the empirical chi square  0  with prob <  NA 
## The total number of observations was  11082  with Likelihood Chi Square =  0  with prob <  NA 
## 
## Tucker Lewis Index of factoring reliability =  1.001
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy             
##                                                    MR1
## Correlation of (regression) scores with factors   0.72
## Multiple R square of scores with factors          0.52
## Minimum correlation of possible factor scores     0.04
om_results = omega(nomiss %>% select(raven_2007_old, math_2007_old) %>% data.frame(), nfactors = 1, sl = F)
## Omega_h for 1 factor is not meaningful, just omega_t
om_results
## Omega 
## Call: omega(m = nomiss %>% select(raven_2007_old, math_2007_old) %>% 
##     data.frame(), nfactors = 1, sl = F)
## Alpha:                 0.52 
## G.6:                   0.35 
## Omega Hierarchical:    0.52 
## Omega H asymptotic:    1 
## Omega Total            0.52 
## 
## Schmid Leiman Factor loadings greater than  0.2 
##                   g  F1*   h2   u2 p2
## raven_2007_old 0.59      0.35 0.65  1
## math_2007_old  0.59      0.35 0.65  1
## 
## With eigenvalues of:
##   g F1* 
## 0.7 0.0 
## 
## general/max  Inf   max/min =   NaN
## mean percent general =  1    with sd =  0 and cv of  0 
## Explained Common Variance of the general factor =  1 
## 
## The degrees of freedom are -1  and the fit is  0 
## The number of observations was  11082  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA
## 
## Compare this with the adequacy of just a general factor and no group factors
## The degrees of freedom for just the general factor are -1  and the fit is  0 
## The number of observations was  11082  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## Measures of factor score adequacy             
##                                                  g F1*
## Correlation of scores with factors            0.72   0
## Multiple R square of scores with factors      0.52   0
## Minimum correlation of factor score estimates 0.04  -1
## 
##  Total, General and Subset omega for each subset
##                                                  g  F1*
## Omega total for total scores and subscales    0.52 0.52
## Omega general for total scores and subscales  0.52 0.52
## Omega group for total scores and subscales    0.00 0.00
omega.diagram(om_results)

"g_factor_2007_old =~ raven_2007_old + math_2007_old" %>%
  cfa(data = nomiss, std.lv = T, std.ov = T) -> cfa_g
summary(cfa_g)
## lavaan 0.6-3 ended normally after 9 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                          4
## 
##   Number of observations                         11082
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                          NA
##   Degrees of freedom                                -1
##   Minimum Function Value               0.0000000000000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                        Estimate  Std.Err  z-value  P(>|z|)
##   g_factor_2007_old =~                                    
##     raven_2007_old        0.784       NA                  
##     math_2007_old         0.449       NA                  
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .raven_2007_old    0.386       NA                  
##    .math_2007_old     0.798       NA                  
##     g_fctr_2007_ld    1.000
nomiss$g_factor_2007_old = predict(cfa_g)[,1]

qplot(nomiss$g_factor_2007_old)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

nomiss = nomiss %>% select(pidlink, g_factor_2007_old)

iq = left_join(iq, nomiss, by = "pidlink")

# G_factor_2007_young
nomiss = iq %>%
  filter(!is.na(raven_2007_young), !is.na(math_2007_young))


fa.parallel(nomiss %>% select(raven_2007_young, math_2007_young) %>% data.frame())

## Parallel analysis suggests that the number of factors =  1  and the number of components =  1
fa(nomiss %>% select(raven_2007_young, math_2007_young) %>% data.frame(), nfactors = 1)
## Factor Analysis using method =  minres
## Call: fa(r = nomiss %>% select(raven_2007_young, math_2007_young) %>% 
##     data.frame(), nfactors = 1)
## Standardized loadings (pattern matrix) based upon correlation matrix
##                   MR1   h2   u2 com
## raven_2007_young 0.69 0.48 0.52   1
## math_2007_young  0.69 0.48 0.52   1
## 
##                 MR1
## SS loadings    0.96
## Proportion Var 0.48
## 
## Mean item complexity =  1
## Test of the hypothesis that 1 factor is sufficient.
## 
## The degrees of freedom for the null model are  1  and the objective function was  0.26 with Chi Square of  2885
## The degrees of freedom for the model are -1  and the objective function was  0 
## 
## The root mean square of the residuals (RMSR) is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## The harmonic number of observations is  10940 with the empirical chi square  0  with prob <  NA 
## The total number of observations was  10940  with Likelihood Chi Square =  0  with prob <  NA 
## 
## Tucker Lewis Index of factoring reliability =  1
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy             
##                                                    MR1
## Correlation of (regression) scores with factors   0.81
## Multiple R square of scores with factors          0.65
## Minimum correlation of possible factor scores     0.30
om_results = omega(nomiss %>% select(raven_2007_young, math_2007_young) %>% data.frame(), nfactors = 1, sl = F)
## Omega_h for 1 factor is not meaningful, just omega_t
om_results
## Omega 
## Call: omega(m = nomiss %>% select(raven_2007_young, math_2007_young) %>% 
##     data.frame(), nfactors = 1, sl = F)
## Alpha:                 0.65 
## G.6:                   0.48 
## Omega Hierarchical:    0.65 
## Omega H asymptotic:    1 
## Omega Total            0.65 
## 
## Schmid Leiman Factor loadings greater than  0.2 
##                     g  F1*   h2   u2 p2
## raven_2007_young 0.69      0.48 0.52  1
## math_2007_young  0.69      0.48 0.52  1
## 
## With eigenvalues of:
##    g  F1* 
## 0.96 0.00 
## 
## general/max  Inf   max/min =   NaN
## mean percent general =  1    with sd =  0 and cv of  0 
## Explained Common Variance of the general factor =  1 
## 
## The degrees of freedom are -1  and the fit is  0 
## The number of observations was  10940  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA
## 
## Compare this with the adequacy of just a general factor and no group factors
## The degrees of freedom for just the general factor are -1  and the fit is  0 
## The number of observations was  10940  with Chi Square =  0  with prob <  NA
## The root mean square of the residuals is  0 
## The df corrected root mean square of the residuals is  NA 
## 
## Measures of factor score adequacy             
##                                                  g F1*
## Correlation of scores with factors            0.81   0
## Multiple R square of scores with factors      0.65   0
## Minimum correlation of factor score estimates 0.30  -1
## 
##  Total, General and Subset omega for each subset
##                                                  g  F1*
## Omega total for total scores and subscales    0.65 0.65
## Omega general for total scores and subscales  0.65 0.65
## Omega group for total scores and subscales    0.00 0.00
omega.diagram(om_results)

"g_factor_2007_young =~ raven_2007_young + math_2007_young" %>%
  cfa(data = nomiss, std.lv = T, std.ov = T) -> cfa_g
summary(cfa_g)
## lavaan 0.6-3 ended normally after 9 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                          4
## 
##   Number of observations                         10940
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                          NA
##   Degrees of freedom                                -1
##   Minimum Function Value               0.0000000000000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                          Estimate  Std.Err  z-value  P(>|z|)
##   g_factor_2007_young =~                                    
##     raven_2007_yng          0.792       NA                  
##     math_2007_yong          0.608       NA                  
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .raven_2007_yng    0.372       NA                  
##    .math_2007_yong    0.631       NA                  
##     g_fctr_2007_yn    1.000
nomiss$g_factor_2007_young = predict(cfa_g)[,1]

qplot(nomiss$g_factor_2007_young)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

nomiss = nomiss %>% select(pidlink, g_factor_2007_young)

iq = left_join(iq, nomiss, by = "pidlink")

Personality

Personality based on Big Five 15

### Personality
##Rearrange personality data so that every individual has only one row
pers = spread(b3b_psn, psntype, psn01)
##name columns
colnames(pers) <- c("hhid14_9", "pid14", "hhid14", "pidlink", "version", "module", "e1", "c1", "o1", "e2r", "n1r", "a1", "n2", "o2", "c2r", "o3", "a2", "c3", "e3", "a3r", "n3")
pers = pers %>% select(hhid14_9, pidlink, e1, c1, o1, e2r, n1r, a1, n2, o2, c2r, o3, a2, c3, e3, a3r, n3)

##Extraversion
pers$e2r_reversed = 6 - pers$e2r
extraversion = pers %>% select(e1, e2r_reversed, e3)
psych::alpha(data.frame(extraversion), check.keys = T)
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(extraversion), check.keys = T)
## 
##   raw_alpha std.alpha G6(smc) average_r  S/N    ase mean   sd median_r
##       0.37      0.35    0.28      0.15 0.54 0.0056  3.4 0.67     0.14
## 
##  lower alpha upper     95% confidence boundaries
## 0.36 0.37 0.38 
## 
##  Reliability if an item is dropped:
##              raw_alpha std.alpha G6(smc) average_r   S/N alpha se var.r med.r
## e1               0.072     0.081   0.042     0.042 0.088   0.0092    NA 0.042
## e2r_reversed     0.218     0.246   0.140     0.140 0.326   0.0077    NA 0.140
## e3               0.429     0.429   0.273     0.273 0.753   0.0064    NA 0.273
## 
##  Item statistics 
##                  n raw.r std.r r.cor r.drop mean   sd
## e1           31446  0.77  0.71  0.48   0.30  3.1 1.14
## e2r_reversed 31446  0.73  0.67  0.37   0.24  3.0 1.12
## e3           31446  0.44  0.60  0.19   0.11  4.2 0.67
## 
## Non missing response frequency for each item
##                 1    2    3    4    5 miss
## e1           0.03 0.39 0.08 0.39 0.11    0
## e2r_reversed 0.07 0.36 0.09 0.43 0.05    0
## e3           0.00 0.03 0.05 0.64 0.28    0
pers$big5_ext = rowMeans(extraversion)
qplot(pers$big5_ext)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##conscientiousness
pers$c2r_reversed = 6 - pers$c2r
conscientiousness = pers %>% select(c1, c2r_reversed, c3)
psych::alpha(data.frame(conscientiousness), check.keys = T)
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(conscientiousness), check.keys = T)
## 
##   raw_alpha std.alpha G6(smc) average_r  S/N   ase mean   sd median_r
##       0.29      0.31    0.24      0.13 0.45 0.007  3.8 0.55     0.12
## 
##  lower alpha upper     95% confidence boundaries
## 0.27 0.29 0.3 
## 
##  Reliability if an item is dropped:
##              raw_alpha std.alpha G6(smc) average_r  S/N alpha se var.r med.r
## c1                0.10      0.10   0.054     0.054 0.11   0.0101    NA 0.054
## c2r_reversed      0.35      0.36   0.219     0.219 0.56   0.0071    NA 0.219
## c3                0.20      0.21   0.116     0.116 0.26   0.0087    NA 0.116
## 
##  Item statistics 
##                  n raw.r std.r r.cor r.drop mean   sd
## c1           31446  0.61  0.69  0.42   0.23  4.1 0.71
## c2r_reversed 31446  0.65  0.60  0.19   0.10  3.6 0.95
## c3           31446  0.67  0.65  0.34   0.17  3.8 0.90
## 
## Non missing response frequency for each item
##                 1    2    3    4    5 miss
## c1           0.01 0.04 0.04 0.66 0.25    0
## c2r_reversed 0.03 0.18 0.07 0.65 0.07    0
## c3           0.01 0.12 0.08 0.63 0.15    0
pers$big5_con = rowMeans(conscientiousness)
qplot(pers$big5_con)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Openness
openness = pers %>% select(o1, o2, o3)
psych::alpha(data.frame(openness), check.keys = T)
## 
## Reliability analysis   
## Call: psych::alpha(x = data.frame(openness), check.keys = T)
## 
##   raw_alpha std.alpha G6(smc) average_r  S/N    ase mean   sd median_r
##       0.45      0.45    0.35      0.21 0.81 0.0054  3.7 0.67     0.22
## 
##  lower alpha upper     95% confidence boundaries
## 0.43 0.45 0.46 
## 
##  Reliability if an item is dropped:
##    raw_alpha std.alpha G6(smc) average_r  S/N alpha se var.r med.r
## o1      0.30      0.30    0.18      0.18 0.43   0.0078    NA  0.18
## o2      0.39      0.39    0.25      0.25 0.65   0.0068    NA  0.25
## o3      0.35      0.36    0.22      0.22 0.55   0.0073    NA  0.22
## 
##  Item statistics 
##        n raw.r std.r r.cor r.drop mean   sd
## o1 31446  0.71  0.71  0.45   0.30  3.7 0.98
## o2 31446  0.70  0.67  0.37   0.25  3.5 1.05
## o3 31446  0.65  0.69  0.41   0.27  4.0 0.88
## 
## Non missing response frequency for each item
##       1    2    3    4    5 miss
## o1 0.02 0.18 0.08 0.58 0.14    0
## o2 0.03 0.22 0.09 0.54 0.12    0
## o3 0.01 0.10 0.05 0.61 0.23    0
pers$big5_open = rowMeans(openness)
qplot(pers$big5_open)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

## Neuroticism
pers$n1r_reversed = 6 - pers$n1r
neuroticism = pers %>% select(n1r_reversed, n2, n3)
pers$big5_neu = rowMeans(neuroticism)
qplot(pers$big5_neu)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##Agreeableness
pers$a3r_reversed = 6- pers$a3r
agreeableness= pers %>% select(a1, a2, a3r_reversed)
pers$big5_agree = rowMeans(agreeableness)
qplot(pers$big5_agree)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Risk aversion

Risk aversion based on adaptive lottery task

###Risktaking
risk = b3a_si %>% select(hhid14_9, pidlink, random_si, si01, si02, si03, si04, si05, si11, si12, si13, si14, si15)

## 8 means they didnt know which answer they would choose
risk$si01[ risk$si01 == 8] = NA
risk$si02[ risk$si02 == 8] = NA
risk$si03[ risk$si03 == 8] = NA
risk$si04[ risk$si04 == 8] = NA
risk$si05[ risk$si05 == 8] = NA
risk$si11[ risk$si11 == 8] = NA
risk$si12[ risk$si12 == 8] = NA
risk$si13[ risk$si13 == 8] = NA
risk$si14[ risk$si14 == 8] = NA
risk$si15[ risk$si15 == 8] = NA

## calculate a risk score for risk game A 
# (5 = gamble averse, Ordinalskala : 1 = risk loving, 4 = risk averse)
risk$riskA = ifelse(risk$si01 == 1 & risk$si02 == 1, 5,
             ifelse(risk$si01 == 2 & risk$si03 == 1 & risk$si04 == 1, 4,
             ifelse(risk$si01 == 2 & risk$si03 == 1 & risk$si04 == 2, 3,
             ifelse(risk$si01 == 2 & risk$si03 == 2 & risk$si05 == 1, 2,
             ifelse(risk$si01 == 2 & risk$si03 == 2 & risk$si05 == 2, 1,
             NA)))))

## calculate a risk score for risk game B 
# (5 = gamble loving, Ordinalskala : 1 = risk loving, 4 = risk averse)
risk$riskB = ifelse(risk$si11 == 2 & risk$si12 == 1, 5,
             ifelse(risk$si11 == 1 & risk$si13 == 1 & risk$si14 == 1, 4,
             ifelse(risk$si11 == 1 & risk$si13 == 1 & risk$si14 == 2, 3,
             ifelse(risk$si11 == 1 & risk$si13 == 2 & risk$si15 == 1, 2,
             ifelse(risk$si11 == 1 & risk$si13 == 2 & risk$si15 == 2, 1,
             NA)))))

# recode risk variable
risk = risk %>%
  mutate(riskB = ifelse(riskB == 5, 0, riskB),
         riskB = riskB + 1)

Educational Attainment

# Select, rename and mutate data
ea = b3a_dl1 %>%
  select(pidlink, dl04, dl06, dl07, dl07a, dl07aa) %>%
  rename(pidlink = pidlink, attended_school = dl04, highest_education = dl06,
         highest_grade=dl07, currently_attending_school = dl07a, hours_in_class = dl07aa) %>%
  mutate(attended_school = as.factor(ifelse(attended_school == 8, NA,
                                            ifelse(attended_school == 1, "yes",
                                                   ifelse(attended_school == 3, "no",
                                                          attended_school)))),
         highest_education = as.factor(ifelse(highest_education == 2 | highest_education == 72,
                                                     "Elementary",
                                                     ifelse(highest_education == 3 |
                                                              highest_education == 4 |
                                                              highest_education == 73,
                                                            "Junior High",
                                                            ifelse(highest_education == 5 |
                                                                     highest_education == 6 |
                                                                     highest_education == 74,
                                                                   "Senior High",
                                                                   ifelse(highest_education == 60 |
                                                                            highest_education == 61 |
                                                                            highest_education == 62 |
                                                                            highest_education == 63 |
                                                                            highest_education == 13,
                                                                          "University", NA))))),#"other" = NA
         highest_grade = ifelse(highest_grade == 98, NA,
                                ifelse(highest_grade == 99, NA, highest_grade)),
         currently_attending_school = as.factor(ifelse(currently_attending_school == 1, "yes",
                                                       ifelse(currently_attending_school == 3, "no", NA))),
         hours_in_class = ifelse(hours_in_class == 99, NA,
                                 ifelse(hours_in_class == 98, NA, hours_in_class)))

## Create variable that includes years of education (highest_education.highest_grade) as a numeric variable
# People who started an education level, but dropped out within the first year, are coded with half a year of schooling
ea = ea %>%
  mutate(years_of_education_factor = as.factor(str_c(highest_education, ".", highest_grade)),
         years_of_education = as.numeric(ifelse(attended_school == "no", 0,
                                         ifelse(years_of_education_factor == "Elementary.0", 0.5,
                                         ifelse(years_of_education_factor == "Elementary.1", 1,
                                         ifelse(years_of_education_factor == "Elementary.2", 2,
                                         ifelse(years_of_education_factor == "Elementary.3", 3,
                                         ifelse(years_of_education_factor == "Elementary.4", 4,
                                         ifelse(years_of_education_factor == "Elementary.5", 5,
                                         ifelse(years_of_education_factor == "Elementary.6", NA,
                                         ifelse(years_of_education_factor == "Elementary.7", 6,
                                         ifelse(years_of_education_factor == "Junior High.0", 6.5,
                                         ifelse(years_of_education_factor == "Junior High.1", 7,
                                         ifelse(years_of_education_factor == "Junior High.2", 8,
                                         ifelse(years_of_education_factor == "Junior High.3", NA,
                                         ifelse(years_of_education_factor == "Junior High.7", 9,
                                         ifelse(years_of_education_factor == "Senior High.0", 9.5,
                                         ifelse(years_of_education_factor == "Senior High.1", 10,
                                         ifelse(years_of_education_factor == "Senior High.2", 11,
                                         ifelse(years_of_education_factor == "Senior High.3", NA,
                                         ifelse(years_of_education_factor == "Senior High.7", 12,
                                         ifelse(years_of_education_factor == "University.0", 12.5,
                                         ifelse(years_of_education_factor == "University.1", 13,
                                         ifelse(years_of_education_factor == "University.2", 14,
                                         ifelse(years_of_education_factor == "University.3", 15,
                                         ifelse(years_of_education_factor == "University.4", 16,
                                         ifelse(years_of_education_factor == "University.5", 17,
                                         ifelse(years_of_education_factor == "University.6", NA,
                                         ifelse(years_of_education_factor == "University.7", 18,
                                                NA)))))))))))))))))))))))))))))
qplot(ea$years_of_education)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

EBTANAS/UAN/UN Score

EBTANAS_long = b3a_dl3 %>%
  select(pidlink, "Level_of_schooling" = dl3type, "Type_of_test" = dl16c1, "Indonesia_score" = dl16db,
         "English_score" = dl16dc, "Math_score" = dl16dd, "Total_score" = dl16e) %>%
  mutate(Level_of_schooling = ifelse(Level_of_schooling == 1, "Elementary",
                                     ifelse(Level_of_schooling == 2, "Junior High",
                                            ifelse(Level_of_schooling == 3, "Senior High", NA))),
         Type_of_test = ifelse(Type_of_test == 1, "EBTANAS",
                               ifelse(Type_of_test == 2, "UAN/UN", NA))) %>%
  filter(!is.na(Indonesia_score) | !is.na(English_score) | !is.na(Math_score) | !is.na(Total_score))
  # remove people with no EBTANAS Information

#Wrangle Data
EBTANAS_Elemenatry = EBTANAS_long %>%
  filter(Level_of_schooling == "Elementary") %>%
  rename("Indonesia_score_elementary" = Indonesia_score, "English_score_elementary" = English_score,
         "Math_score_elemenatry" = Math_score, "Total_score_elemenatry" = Total_score,
         "Type_of_test_elementary" = Type_of_test) %>%
  select(-Level_of_schooling)

EBTANAS_Junior_High = EBTANAS_long %>%
  filter(Level_of_schooling == "Junior High") %>%
  rename("Indonesia_score_Junior_High" = Indonesia_score, "English_score_Junior_High" = English_score,
         "Math_score_Junior_High" = Math_score, "Total_score_Junior_High" = Total_score,
         "Type_of_test_Junior_High" = Type_of_test)%>%
  select(-Level_of_schooling)

EBTANAS_Senior_High = EBTANAS_long %>%
  filter(Level_of_schooling == "Senior High") %>%
  rename("Indonesia_score_Senior_High" = Indonesia_score, "English_score_Senior_High" = English_score,
         "Math_score_Senior_High" = Math_score, "Total_score_Senior_High" = Total_score,
         "Type_of_test_Senior_High" = Type_of_test)%>%
  select(-Level_of_schooling)

EBTANAS = full_join(EBTANAS_Elemenatry, EBTANAS_Junior_High, by = "pidlink")
EBTANAS = full_join(EBTANAS, EBTANAS_Senior_High, by = "pidlink") 

table(is.na(EBTANAS$Total_score_elemenatry))
FALSE TRUE
4275 2002
table(is.na(EBTANAS$Total_score_Junior_High))
FALSE TRUE
3911 2366
table(is.na(EBTANAS$Total_score_Senior_High))
FALSE TRUE
2459 3818
EBTANAS = EBTANAS %>%
  mutate(Total_score_highest = Total_score_elemenatry,
         Total_score_highest = ifelse(!is.na(Total_score_Senior_High), Total_score_Senior_High,
                                      ifelse(!is.na(Total_score_Junior_High), Total_score_Junior_High,
                                             Total_score_highest)),
         Total_score_highest_type = ifelse(!is.na(Total_score_Senior_High), "Senior High",
                                      ifelse(!is.na(Total_score_Junior_High), "Junior High",
                                             ifelse(!is.na(Total_score_elemenatry), "Elementary",
                                                           NA))),
         Math_score_highest = Math_score_elemenatry,
         Math_score_highest = ifelse(!is.na(Math_score_Senior_High), Math_score_Senior_High,
                                      ifelse(!is.na(Math_score_Junior_High), Math_score_Junior_High,
                                             Math_score_highest)),
         Math_score_highest_type = ifelse(!is.na(Math_score_Senior_High), "Senior High",
                                      ifelse(!is.na(Math_score_Junior_High), "Junior High",
                                             ifelse(!is.na(Math_score_elemenatry), "Elementary",
                                                           NA))))
qplot(EBTANAS$Total_score_highest)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qplot(EBTANAS$Math_score_highest)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Child Labour

## Working while still in school
child_labour = b3a_dl4 %>%
  select(pidlink, "Level_of_schooling" = dl4type, "Worked" = dl15, "Missed_school" = dl14a) %>%
  mutate(Level_of_schooling = ifelse(Level_of_schooling == 1, "Elementary",
                                     ifelse(Level_of_schooling == 2, "JuniorHigh",
                                            ifelse(Level_of_schooling == 3, "SeniorHigh",
                                                   ifelse(Level_of_schooling == 4, "University", NA)))),
         Worked = ifelse(Worked == 1, 1,
                         ifelse(Worked == 3, 0, NA)),
         Missed_school = ifelse(Missed_school == 1, 1,
                         ifelse(Missed_school == 3, 0, NA)))

# Wrangle Data
child_labour_work = child_labour %>%
  select(pidlink, Level_of_schooling, Worked) %>%
  spread(., Level_of_schooling, Worked) %>%
  rename("Elementary_worked" = Elementary, "Junior_high_worked" = JuniorHigh, 
         "Senior_high_worked" = SeniorHigh, "University_worked" = University) %>%
  mutate(total_worked = ifelse(Elementary_worked == 1 | Junior_high_worked == 1 |
                                 Senior_high_worked == 1 | University_worked == 1, 1, 0),
         total_worked  = ifelse(is.na(total_worked), 0, total_worked))

## Missed school
child_labour_missed = child_labour %>%
  select(pidlink, Level_of_schooling, Missed_school) %>%
  spread(., Level_of_schooling, Missed_school) %>%
  rename("Elementary_missed" = Elementary, "Junior_high_missed" = JuniorHigh, 
         "Senior_high_missed" = SeniorHigh, "University_missed" = University) %>%
  mutate(total_missed = ifelse(Elementary_missed == 1 | Junior_high_missed == 1 |
                                 Senior_high_missed == 1 | University_missed == 1, 1, 0))

child_labour = full_join(child_labour_work, child_labour_missed, by = "pidlink")
table(child_labour$total_missed)
0 1
2608 1017
table(child_labour$total_worked)
0 1
9379 3498

Job Information

job = b3a_tk2 %>% select(pidlink, "Category" = tk24a, "Sector" = tk19ab, "wage_last_month" = tk25a1,
                         "wage_last_year" = tk25a2) %>%
  mutate(Category = ifelse(Category == 1 | Category == 2 | Category == 3, "Self-employed",
                           ifelse(Category == 4, "Government worker",
                                  ifelse(Category == 5, "Private worker",
                                         ifelse(Category == 7, "Casual worker in agriculture",
                                                ifelse(Category == 8, "Casual worker not in agriculture",
                                                       ifelse(Category == 6, "Unpaid family worker",
                                                              NA)))))),
         Self_employed = ifelse(Category == "Self-employed", 1,
                                ifelse(is.na(Category), NA, 0)),
         Sector = ifelse(Sector == 1, "Agriculture, forestry, fishing and hunting",
                  ifelse(Sector == 2, "Mining and quarrying",
                  ifelse(Sector == 3, "Manufacturing",
                  ifelse(Sector == 4, "Electricity, gas, water",
                  ifelse(Sector == 5, "Construction",
                  ifelse(Sector == 6, "Wholesale, retail, restaurants and hotels",
                  ifelse(Sector == 7, "Transportation, storage and communications",
                  ifelse(Sector == 8, "Finance, insurance, real estate and business services",
                  ifelse(Sector == 9, "Social services",
                  ifelse(Sector == 10, "Activities that cannot be classified", NA)))))))))),
         wage_last_month = ifelse(wage_last_month == 8, NA, wage_last_month),
         wage_last_year = ifelse(wage_last_year == 8, NA, wage_last_year))

table(job$Category)
Casual worker in agriculture Casual worker not in agriculture Government worker Private worker Self-employed Unpaid family worker
830 1888 1616 8364 9194 2589
table(job$Sector)
Agriculture, forestry, fishing and hunting Construction Electricity, gas, water Finance, insurance, real estate and business services Manufacturing Mining and quarrying Social services Transportation, storage and communications Wholesale, retail, restaurants and hotels
5940 29 394 5003 5469 839 1510 787 3754
qplot(job$wage_last_month)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

summary(job$wage_last_month)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA’s
0 550000 1250000 1923793 2400000 999999997 11970
x = job %>% filter(wage_last_month < 5000000)
qplot(x$wage_last_month)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

qplot(job$wage_last_year)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

summary(job$wage_last_year)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA’s
0 3960000 12000000 20680463 27000000 999999997 12064
x = job %>% filter(wage_last_year < 50000000)
qplot(x$wage_last_year)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Health Information - Smoking Behavior

smoking = b3b_km %>%
  select(pidlink, "ever_smoked" = km01a, "still_smoking" = km04, "amount" = km08,
         "money_spent_smoking" = km09, "age_first_smoke" = km10) %>%
  mutate(ever_smoked = ifelse(ever_smoked == 1, 1, 0),
         still_smoking = ifelse(still_smoking == 1, 1, 0),
         amount = ifelse(amount == 8, NA,
                         ifelse(amount == 98, NA, amount)),
         amount_still_smokers = ifelse(still_smoking == 1, amount, NA))

Merge data

### Merge all data for people with birthorder informations
alldata_birthorder = left_join(alldata_pregnancy, iq, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, pers, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, risk, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, ea, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, EBTANAS, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, child_labour, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, job, by = "pidlink")
alldata_birthorder = left_join(alldata_birthorder, smoking, by = "pidlink")


alldata = left_join(individuals_unchanged, iq, by = "pidlink")
alldata = left_join(alldata, pers, by = "pidlink")
alldata = left_join(alldata, risk, by = "pidlink")
alldata = left_join(alldata, ea, by = "pidlink")
alldata = left_join(alldata, EBTANAS, by = "pidlink")
alldata = left_join(alldata, child_labour, by = "pidlink")
alldata = left_join(alldata, job, by = "pidlink")
alldata = left_join(alldata, smoking, by = "pidlink")

Fix types

alldata_birthorder <- alldata_birthorder %>% 
  mutate_at(vars(age_2015_old, age_2015_young, alive, death_yr, 
                 English_score_elementary, English_score_Junior_High, English_score_Senior_High,
                 Indonesia_score_elementary, Indonesia_score_Junior_High, Indonesia_score_Senior_High,
                 Math_score_elemenatry, Math_score_Junior_High, Math_score_Senior_High,
                 e1, c1, o1, e2r, n1r, a1, n2, o2, c2r, o3, a2, c3, e3, a3r, n3, e2r_reversed, c2r_reversed,
                 n1r_reversed, a3r_reversed,
                 si01 ,si02, si03, si04, si05, si11, si12, si13, si14, si15
                 ), funs(as.numeric)) %>% 
  mutate_at(vars(Math_score_highest_type, Total_score_highest_type, mother_pidlink, father_pidlink, marriage_id,
                 pidlink,  random_si, Sector, Type_of_test_elementary, Type_of_test_Junior_High,
                 Type_of_test_Senior_High, lifebirths, Category
                 ), funs(as.factor)) %>% 
  mutate(male = if_else(sex == 1, 1L, 0L),
         wage_last_month_log = log(wage_last_month+1),
         wage_last_year_log = log(wage_last_year+1),
         money_spent_smoking_log = log(money_spent_smoking+1)) %>% 
  mutate_at(vars(alive, Elementary_missed, Elementary_worked, ever_smoked, Junior_high_missed, Junior_high_worked,
                 Self_employed, total_missed, Senior_high_missed, Senior_high_worked, still_smoking, University_missed,
                 University_worked, wave), funs(as.integer)) %>% 
  mutate_at(vars(birthdate), funs(as.Date)) %>% 
    select(-motherID, -fatherID, -mother_birthorder, -mother_birthdate, -month, -end, -start, -gender, -sex, -sex_2015_old, -sex_2015_young,
           -relation_to_HH_head, -years_of_education_factor, -birthdate_duped_in_earlier_wave, -birthorder_duped_in_earlier_wave, -birthorder_naive_ind,
           -order_marriage,
           -ar08day, -ar08mth, -ar08yr, -birth_day, -birth_month, -birth_year, -highest_grade, -wage_last_month, -wage_last_year, -status,
           -money_spent_smoking, -starts_with("hhid14_"), sc05, province, sc01_14_14)

Save data

for future analyses

alldata_birthorder = alldata_birthorder %>% ungroup()
alldata = alldata %>% ungroup()
pregnancy = pregnancy %>% ungroup()
iq = iq %>% ungroup()

saveRDS(alldata_birthorder, file = "data/alldata_birthorder.rds")
saveRDS(alldata, file = "data/alldata.rds")
saveRDS(pregnancy, file = "data/pregnancy.rds")
saveRDS(iq, file = "data/iq.rds")
LS0tCnRpdGxlOiAiMV9kYXRhX2ltcG9ydCIKYXV0aG9yOiAiTGF1cmEgQm90emV0ICYgUnViZW4gQXJzbGFuIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogInNob3ciCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQotLS0KCiMgIDxzcGFuIHN0eWxlPSJjb2xvcjojRkM4RDYyIj5EYXRhIFdyYW5nbGluZzwvc3Bhbj4gey50YWJzZXR9CgojIyBIZWxwZXIKUGFja2FnZXMgYW5kIGZ1bmN0aW9ucyB1c2VkCmBgYHtyIGhlbHBlcn0Kc291cmNlKCIwX2hlbHBlcnMuUiIpCmBgYAoKCiMjIEltcG9ydCBkYXRhIHsuYWN0aXZlfQoKQW5hbHlzZXMgYXJlIGJhc2VkIG9uIHRoZSBJbmRvbmVzaWFuIEZhbWlseSBMaWZlIFN1cnZleSAoSUZMUykuIEFsbCBkYXRhIGlzIHJldHJpZXZlZCBmcm9tIHRoZSBbUkFORCBmb3VuZGF0aW9uXShodHRwOi8vd3d3LnJhbmQub3JnL2xhYm9yL0ZMUy9JRkxTLmh0bWwpLgoKV2UgaW5jbHVkZWQgdGhlIGZvbGxvd2luZyBkYXRhIHNldHM6CgoqIElGTFMgV2F2ZSAxCiAgICArIGJ1azRjaDEKICAgICsgYnVrNGt3MgogICAgKyBidWtrYXIyCiAgCgoqIElGTFMgV2F2ZSAyCiAgICArIGI0X2NoMQogICAgKyBiNF9rdzIKICAgICsgYjRfY292CgoqIElGTFMgV2F2ZSAzCiAgICArIGI0X2NoMQogICAgKyBiNF9rdzMKICAgICsgYjRfY292CgoqIElGTFMgV2F2ZSA0CiAgICArIGI0X2NoMQogICAgKyBiNF9rdzIKICAgICsgYjRfY292CiAgICArIGJla19lazEKICAgICsgYmVrX2VrMgoKKiBJRkxTIFdhdmUgNQogICAgKyBia19hcjEKICAgICsgYmtfc2MxCiAgICArIHB0cmFjawogICAgKyBiNF9jaDEKICAgICsgYjRfa3czCiAgICArIGI0X2NvdgogICAgKyBla19lazIKICAgICsgZWtfZWsxCiAgICArIGIzYl9jb2IKICAgICsgYjNiX2NvMQogICAgKyBiM2JfcHNuCiAgICArIGIzYV9zaQogICAgKyBiM2FfZGwxCiAgICArIGIzYV9kbDMKICAgICsgYjNhX2RsNAogICAgKyBiM2FfdGsyCiAgICArIGIzYl9rbQoKYGBge3IgSW1wb3J0IGRhdGF9CiMjIyBJbmZvcm1hdGlvbnMgYWJvdXQgaW5kaXZpZHVhbHMgbGl2aW5nIGluIHRoZSBob3VzZWhvbGQgaW4gMjAxNC8yMDE1CiMjIEFsbCBJbmRpdmlkdWFscyBsaXZpbmcgaW4gdGhlIGhvdXNlaG9sZApia19hcjEgPSByZWFkX2R0YSgiZGF0YS9oaDE0X2FsbF9kdGEvYmtfYXIxLmR0YSIpICMgQm9vayBLLCBTZWN0aW9uIGFyCiMgY29tcHV0ZSBmYXRoZXIgcGlkbGluawpia19hcjEgPSBsZWZ0X2pvaW4oYmtfYXIxLCBia19hcjEgJT4lCiAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChoaGlkMTRfOSwgcGlkMTQsIHBpZGxpbmspICU+JQogICAgICAgICAgICAgICAgICAgICByZW5hbWUoYXIxMCA9IHBpZDE0LCBmYXRoZXJfcGlkbGluayA9IHBpZGxpbmspLCBieSA9IGMoImhoaWQxNF85IiwgImFyMTAiKSkKIyBjb21wdXRlIG1vdGhlciBwaWRsaW5rCmJrX2FyMSA9IGxlZnRfam9pbihia19hcjEsIGJrX2FyMSAlPiUKICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGhoaWQxNF85LCBwaWQxNCwgcGlkbGluaykgJT4lCiAgICAgICAgICAgICAgICAgICAgIHJlbmFtZShhcjExID0gcGlkMTQsIG1vdGhlcl9waWRsaW5rID0gcGlkbGluayksIGJ5ID0gYygiaGhpZDE0XzkiLCAiYXIxMSIpKQoKYmtfc2MxID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2JrX3NjMS5kdGEiKSAjIExvY2F0aW9uIGluZm8sIEJvb2sgSywgU2VjdGlvbiBzYwojIFJlY29kZSBSZWdpb25zOgpia19zYzEgPC0gYmtfc2MxICU+JQogIG11dGF0ZShwcm92aW5jZSA9IHN0cl90cmltKHJlY29kZShia19zYzEkc2MwMV8xNF8xNCwgIGAxMWAgPSAnTi4gQWNlaCBEYXJ1c3NhbGFtJywKIGAxMmAgPSAnTm9ydGggU3VtYXRlcmEgICcsCiBgMTNgID0gJ1dlc3QgU3VtYXRlcmEnLAogYDE0YCA9ICdSaWF1ICAnLAogYDE1YCA9ICdKYW1iaSAnLAogYDE2YCA9ICdTb3V0aCBTdW1hdGVyYSAgJywKIGAxN2AgPSAnQmVuZ2t1bHUnLAogYDE4YCA9ICdMYW1wdW5nICcsCiBgMTlgID0gJ0JhbmdrYSBCZWxpdHVuZyAnLAogYDMxYCA9ICdKYWthcnRhICcsCiBgMzJgID0gJ1dlc3QgSmF2YSAgJywKIGAzM2AgPSAnQ2VudHJhbCBKYXZhICcsCiBgMzRgID0gJ0RJIFlvZ3lha2FydGEnLAogYDM1YCA9ICdFYXN0IEphdmEgICcsCiBgMzZgID0gJ0JhbnRlbicsCiBgNTFgID0gJ0JhbGkgICcsCiBgNTJgID0gJ1dlc3QgTnVzYSBUZW5nZ2FyYScsCiBgNTNgID0gJ0Vhc3QgTnVzYSBUZW5nZ2FyYScsCiBgNjFgID0gJ1dlc3QgS2FsaW1hbnRhbiAnLAogYDYyYCA9ICdDZW50cmFsIEthbGltYW50YW4nLAogYDYzYCA9ICdTb3V0aCBLYWxpbWFudGFuJywKIGA2NGAgPSAnRWFzdCBLYWxpbWFudGFuICcsCiBgNzFgID0gJ05vcnRoIFN1bGF3ZXNpICAnLAogYDcyYCA9ICdDZW50cmFsIFN1bGF3ZXNpJywKIGA3M2AgPSAnU291dGggU3VsYXdlc2kgICcsCiBgNzRgID0gJ1NvdXRoZWFzdCBTdWxhd2VzaScsCiBgODFgID0gJ01hbHVrdScsCiBgOTRgID0gJ1BhcHVhICcsCiBgOThgID0gTkFfY2hhcmFjdGVyXywKIGA5OWAgPSBOQV9jaGFyYWN0ZXJfLCAuZGVmYXVsdCA9IE5BX2NoYXJhY3Rlcl8pKSkKCiMjIyBJbmZvcm1hdGlvbnMgZnJvbSBJRkxTIHdhdmUgNSB0byBsaW5rIGRhdGEgdG8gZWFybGllciB3YXZlczoKcHRyYWNrID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL3B0cmFjay5kdGEiKSAjIFRyYWNraW5nIGluZm9ybWF0aW9ucwoKIyMjIFByZWduYW5jeSBJbmZvcm1hdGlvbnMgZnJvbSBtb3RoZXIKIyMgV2F2ZSA1IC0gMjAxNAp3NV9wcmVnbmFuY3kgPSByZWFkX2R0YSgiZGF0YS9oaDE0X2FsbF9kdGEvYjRfY2gxLmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGNoCiMjIFdhdmUgNCAtIDIwMDcKdzRfcHJlZ25hbmN5ID0gcmVhZF9kdGEoImRhdGEvaGgwN19hbGxfZHRhL2I0X2NoMS5kdGEiKSAjIEJvb2sgNCwgU2VjdGlvbiBjaAojIyBXYXZlIDMgLSAyMDAwCnczX3ByZWduYW5jeSA9IHJlYWRfZHRhKCJkYXRhL2hoMDBfYWxsX2R0YS9iNF9jaDEuZHRhIikgIyBCb29rIDQsIFNlY3Rpb24gY2gKIyMgV2F2ZSAyIC0gMTk5Nwp3Ml9wcmVnbmFuY3kgPSByZWFkX2R0YSgiZGF0YS9oaDk3ZHRhL2I0X2NoMS5kdGEiKSAjIEJvb2sgNCwgU2VjdGlvbiBjaAojIyBXYXZlIDEgLSAxOTkzCncxX3ByZWduYW5jeSA9IHJlYWRfZHRhKCJkYXRhL2hoOTNkdGEvYnVrNGNoMS5kdGEiKSAjIEJvb2sgNCwgU2VjdGlvbiBjaAoKIyMjIE1hcnJpYWdlIGluZm9ybWF0aW9uIGZyb20gbW90aGVyCiMjIFdhdmUgNSAtIDIwMTQKdzVfbWFycmlhZ2U9IHJlYWRfZHRhKCJkYXRhL2hoMTRfYWxsX2R0YS9iNF9rdzMuZHRhIikgIyBCb29rIDQsIFNlY3Rpb24ga3czCiMjIFdhdmUgNCAtIDIwMDcKdzRfbWFycmlhZ2UgPSByZWFkX2R0YSgiZGF0YS9oaDA3X2FsbF9kdGEvYjRfa3cyLmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGt3MgojIyBXYXZlIDMgLSAyMDAwCnczX21hcnJpYWdlID0gcmVhZF9kdGEoImRhdGEvaGgwMF9hbGxfZHRhL2I0X2t3My5kdGEiKSAjIEJvb2sgNCwgU2VjdGlvbiBrdzMKIyMgV2F2ZSAyIC0gMTk5Nwp3Ml9tYXJyaWFnZSA9IHJlYWRfZHRhKCJkYXRhL2hoOTdkdGEvYjRfa3cyLmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGt3MgojIyBXYXZlIDEgLSAxOTkzCncxX21hcnJpYWdlID0gcmVhZF9kdGEoImRhdGEvaGg5M2R0YS9idWs0a3cyLmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGt3MgoKIyMgQWRkaXRpb25hbCBtYXJyaWFnZSBpbmZvcm1hdGlvbiBmcm9tIG1vdGhlcgojIFdhdmUgNSAtIDIwMTQKdzVfbWFycmlhZ2VfYWRkaXRpb25hbCA9IHJlYWRfZHRhKCJkYXRhL2hoMTRfYWxsX2R0YS9iNF9jb3YuZHRhIikgIyBCb29rIDQsIFNlY3Rpb24gY292CiMgV2F2ZSA0IC0gMjAwNwp3NF9tYXJyaWFnZV9hZGRpdGlvbmFsID0gcmVhZF9kdGEoImRhdGEvaGgwN19hbGxfZHRhL2I0X2Nvdi5kdGEiKSAjIEJvb2sgNCwgU2VjdGlvbiBjb3YKIyBXYXZlIDMgLSAyMDAwCnczX21hcnJpYWdlX2FkZGl0aW9uYWwgPSByZWFkX2R0YSgiZGF0YS9oaDAwX2FsbF9kdGEvYjRfY292LmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGNvdgojIFdhdmUgMiAtIDE5OTcKdzJfbWFycmlhZ2VfYWRkaXRpb25hbCA9IHJlYWRfZHRhKCJkYXRhL2hoOTdkdGEvYjRfY292LmR0YSIpICMgQm9vayA0LCBTZWN0aW9uIGNvdgojIFdhdmUgMSAtIDE5OTMKdzFfbWFycmlhZ2VfYWRkaXRpb25hbCA9IHJlYWRfZHRhKCJkYXRhL2hoOTNkdGEvYnVra2FyMi5kdGEiKSAjIEJvb2sgSywgU2VjdGlvbiBhciwgaG91c2Vob2xkIHJvYXN0ZXIKCiMjIyBJUSBJbmZvcm1hdGlvbgpla19lazIgPSByZWFkX2R0YSgiZGF0YS9oaDE0X2FsbF9kdGEvZWtfZWsyLmR0YSIpICMgQm9vayBlazI6ID4xNSB5ZWFycwpla19lazEgPSByZWFkX2R0YSgiZGF0YS9oaDE0X2FsbF9kdGEvZWtfZWsxLmR0YSIpICMgQm9vayBlazE6IDwxNSB5ZWFycwojIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gKGNvdW50aW5nIGJhY2t3YXJkcywgYWRhcHRpdmUgdGVzdGluZykgZm9yIGFkdWx0cwpiM2JfY29iID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYl9jb2IuZHRhIikgIyBCb29rIDNiLCBTZWN0aW9uIGNvYgpiM2JfY28xID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYl9jbzEuZHRhIikgIyBCb29rIDNiLCBTZWN0aW9uIGNvMQojIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gZnJvbSBlYXJsaWVyIHdhdmVzCmJla19lazEgPSByZWFkX2R0YSgiZGF0YS9oaDA3X2FsbF9kdGEvYmVrX2VrMS5kdGEiKSAjIEludGVsbGlnZW5jZSBpbmZvcm1hdGlvbiBmcm9tIHdhdmUgNCAoMjAwNyk6IDctMTQKYmVrX2VrMiA9IHJlYWRfZHRhKCJkYXRhL2hoMDdfYWxsX2R0YS9iZWtfZWsyLmR0YSIpICMgSW50ZWxsaWdlbmNlIGluZm8gZnJvbSB3YXZlIDQgKDIwMDcpOiAxNSAtIDI0CgojIyMgUGVyc29uYWxpdHkgSW5mb3JtYXRpb24gKG9ubHkgZm9yIGFkdWx0cykKYjNiX3BzbiA9IHJlYWRfZHRhKCJkYXRhL2hoMTRfYWxsX2R0YS9iM2JfcHNuLmR0YSIpICMgQm9vayAzYiwgU2VjdGlvbiBwc24KCiMjIyBSaXNrIHRha2luZwpiM2Ffc2kgPSByZWFkX2R0YSgiZGF0YS9oaDE0X2FsbF9kdGEvYjNhX3NpLmR0YSIpICMgQm9vayAzYSwgU2VjdGlvbiBzaQoKIyMjIEVkdWNhdGlvbmFsIEF0dGFpbm1lbnQKYjNhX2RsMSA9IHJlYWRfZHRhKCJkYXRhL2hoMTRfYWxsX2R0YS9iM2FfZGwxLmR0YSIpICMgQm9vayAzYSwgU2VjdGlvbiBkbDEKCiMjIyBFQlRBTkFTL1VBTi9VTiBTY29yZQpiM2FfZGwzID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYV9kbDMuZHRhIikgIyBCb29rIDNhLCBTZWN0aW9uIGRsMwpiM2FfZGw0ID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYV9kbDQuZHRhIikgIyBCb29rIDNhLCBTZWN0aW9uIGRsNAoKIyMjIEpvYiBJbmZvcm1hdGlvbgpiM2FfdGsyID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYV90azIuZHRhIikgIyBCb29rIDNhLCBTZWN0aW9uIHRrMgoKIyMjIFNtb2tpbmcgYmVoYXZpb3IKYjNiX2ttID0gcmVhZF9kdGEoImRhdGEvaGgxNF9hbGxfZHRhL2IzYl9rbS5kdGEiKSAjIEJvb2sgM2IsIFNlY3Rpb24ga20KYGBgCgojIyBCaXJ0aCBvcmRlciBpbmZvcm1hdGlvbiB7LnRhYnNldH0KIyMjIEluZm9ybWF0aW9uIGFib3V0IHByZWduYW5jeQpUbyBjb21wdXRlIGJpcnRoIG9yZGVyIHdlIG5lZWQgaW5mb3JtYXRpb24gYWJvdXQgYWxsIHByZWduYW5jaWVzIG9mIGFsbCB3b21lbiB3aG8gcGFydGljaXBhdGVkIGluIElGTFMgd2F2ZSAxIC0gNQpgYGB7cn0KIyMgU2VsZWN0IGRhdGEgZnJvbSBwcmVnbmFuY3kgZmlsZXMKdzVfcHJlZ25hbmN5ID0gdzVfcHJlZ25hbmN5ICU+JQogIHNlbGVjdChwaWRsaW5rLCBjaDA1LCBjaDA2LCBjaDA2YSwgY2gwOCwgY2gwOWRheSwgY2gwOW10aCwgY2gwOXlyLCBjaDI1KQp3NF9wcmVnbmFuY3kgPSB3NF9wcmVnbmFuY3kgJT4lCiAgc2VsZWN0KHBpZGxpbmssIGNoMDUsIGNoMDYsIGNoMDZhLCBjaDA4LCBjaDA5ZGF5LCBjaDA5bXRoLCBjaDA5eXIsIGNoMjUpCnczX3ByZWduYW5jeSA9IHczX3ByZWduYW5jeSAlPiUKICBzZWxlY3QocGlkbGluaywgY2gwNSwgY2gwNiwgY2gwNmEsIGNoMDgsIGNoMDlkYXksIGNoMDltdGgsIGNoMDl5ciwgY2gyNSkKdzJfcHJlZ25hbmN5ID0gdzJfcHJlZ25hbmN5ICU+JQogIHNlbGVjdChwaWRsaW5rLCBjaDA1LCBjaDA2LCBjaDA2YSwgY2gwOCwgY2gwOWRheSwgY2gwOW10aCwgY2gwOXlyLCBjaDI1KQp3MV9wcmVnbmFuY3kgPSB3MV9wcmVnbmFuY3kgJT4lIAogIGdyb3VwX2J5KHBpZGxpbmssIGNoMDQpICU+JQogIG11dGF0ZShjaDA2YSA9IGlmX2Vsc2UoIWlzLm5hKHBpZGxpbmspICYgIWlzLm5hKGNoMDQpLCBpZl9lbHNlKCBuKCkgPiAxLCAxLCAzKSwgOSkpICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KHBpZGxpbmssIGNoMDUsIGNoMDYsIGNoMDZhLCBjaDA4LCBjaDA5ZGF5LCBjaDA5bXRoLCBjaDA5eXIsIGNoMjUpICU+JSAKIyBJbiB0aGUgZmlyc3Qgd2F2ZSB0aGUgeWVhciBpcyBuYW1lZCB3cm9uZwogIG11dGF0ZShjaDA5eXIgPSBpZmVsc2UoY2gwOXlyIDw9IDkzLCBjaDA5eXIsIE5BKSwKICAgICAgICAgIGNoMDl5ciA9IGFzLm51bWVyaWMoc3RyX2MoIjE5IiwgY2gwOXlyKSkpCgojIyBDb21iaW5lIGRhdGEKcHJlZ25hbmN5ID0gYmluZF9yb3dzKHcxID0gdzFfcHJlZ25hbmN5LCB3MiA9IHcyX3ByZWduYW5jeSwgdzMgPSB3M19wcmVnbmFuY3ksIHc0ID0gdzRfcHJlZ25hbmN5LCB3NSA9IHc1X3ByZWduYW5jeSwgLmlkID0gIndhdmUiKQpwcmVnbmFuY3kgPSBjb2RlYm9vazo6cmVzY3VlX2F0dHJpYnV0ZXMocHJlZ25hbmN5LCB3NV9wcmVnbmFuY3kpCgojIyBSZW5hbWUgVmFyaWFibGVzCnByZWduYW5jeSA9IHByZWduYW5jeSAlPiUKICByZW5hbWUoY2hyb25fb3JkZXJfYmlydGggPSBjaDA1LCBsaWZlYmlydGhzID0gY2gwNiwgbXVsdGlwbGVfYmlydGggPSBjaDA2YSwgZ2VuZGVyID0gY2gwOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlydGhfZGF5ID0gY2gwOWRheSwgYmlydGhfbW9udGggPSBjaDA5bXRoLCBiaXJ0aF95ZWFyID0gY2gwOXlyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW90aGVyX3BpZGxpbmsgPSBwaWRsaW5rLCBhbGl2ZSA9IGNoMjUpCiAgICAgICAgICAjIHByZWduYW5jeSRsaWZlYmlydGhzIHZhbHVlczogMSA9IHN0aWxsIHByZWduYW50LCAyID0gbGl2ZWJpcnRoLCAzID0gc3RpbGwgYmlydGgsIDQgPSBtaXNzY2FycmlhZ2UKCiMjIFNldCB2YWx1ZXMgYXMgTkEgdGhhdCBhcmUgbWlzc2luZyAoYWxsIHZhbHVlcyB0aGF0IGFyZSBub3QgbG9naWNhbCkKcHJlZ25hbmN5ID0gcHJlZ25hbmN5ICU+JQogIG11dGF0ZShiaXJ0aF9kYXkgPSBpZmVsc2UoYmlydGhfZGF5PjMxLCBOQSwgYmlydGhfZGF5KSwKICAgICAgICAgYmlydGhfbW9udGggPSBpZmVsc2UoYmlydGhfbW9udGg+MTIsIE5BLCBiaXJ0aF9tb250aCksCiAgICAgICAgIGJpcnRoX3llYXIgPSBpZmVsc2UoYmlydGhfeWVhcj4yMDE2LCBOQSwgYmlydGhfeWVhciksCiAgICAgICAgIGJpcnRoX2RheSA9IGlmZWxzZShpcy5uYW4oYmlydGhfZGF5KSwgTkEsIGJpcnRoX2RheSksCiAgICAgICAgIGJpcnRoX21vbnRoID0gaWZlbHNlKGlzLm5hbihiaXJ0aF9tb250aCksIE5BLCBiaXJ0aF9tb250aCksCiAgICAgICAgIGJpcnRoX3llYXIgPSBpZmVsc2UoaXMubmFuKGJpcnRoX3llYXIpLCBOQSwgYmlydGhfeWVhciksCiAgICAgICAgIG11bHRpcGxlX2JpcnRoID0gaWZlbHNlKG11bHRpcGxlX2JpcnRoID09IDksIE5BLCBtdWx0aXBsZV9iaXJ0aCksCiAgICAgICAgIG11bHRpcGxlX2JpcnRoID0gaWZlbHNlKGlzLm5hbihtdWx0aXBsZV9iaXJ0aCksIE5BLCBtdWx0aXBsZV9iaXJ0aCkpCgojIGlmIG1vbnRoIG9mIHByZWduYW5jeSBpcyBtaXNzaW5nLCBzZXQgYXMgZmlyc3QgbW9udGggb2YgdGhlIHllYXIgKEphbnVhcnkpCnByZWduYW5jeSRtb250aCA9IGlmZWxzZShpcy5uYShwcmVnbmFuY3kkYmlydGhfeWVhciksIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHByZWduYW5jeSRiaXJ0aF95ZWFyLCItIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaXMubmEocHJlZ25hbmN5JGJpcnRoX21vbnRoKSwgIjAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkX21vbnRoKHByZWduYW5jeSRiaXJ0aF9tb250aCkpKSkKCiMgY3JlYXRlIGJpcnRoZGF0ZSB2YXJpYWJsZSB0aGF0IGluY2x1ZGVzIGFsbCBhdmFpbGFibGUgaW5mb3JtYXRpb24gYWJvdXQgYmlydGggKHllYXItbW9udGgtZGF5KSAKcHJlZ25hbmN5ID0gcHJlZ25hbmN5ICU+JSAKICBtdXRhdGUoYmlydGhkYXRlID0gYWxsX2F2YWlsYWJsZV9pbmZvX2JpcnRoX2RhdGUoYmlydGhfeWVhciwgYmlydGhfbW9udGgsIGJpcnRoX2RheSksCiAgICAgICAgIG1vdGhlcl9iaXJ0aGRhdGUgPSBzdHJfYyhtb3RoZXJfcGlkbGluaywgIi0iLCBiaXJ0aGRhdGUpLAogICAgICAgICBtb3RoZXJfYmlydGhvcmRlciA9IHBhc3RlMChtb3RoZXJfcGlkbGluayAsICItIiwgY2hyb25fb3JkZXJfYmlydGgpKQoKIyBzb21lIHByZWduYW5jaWVzIHdlcmUgcmVwb3J0ZWQgaW4gbXVsdGlwbGUgd2F2ZXMsCiMgZS5nLiBiZWNhdXNlIHByZWduYW5jaWVzIGNoYW5nZWQgc3RhdHVzIChzdGlsbCBvbmdvaW5nIHByZWduYW5jeSAtLT4gYWxpdmUpCiMgdG8gZWxpbWluYXRlIGR1cGxpY2F0ZXMgd2Ugb25seSB1c2UgdGhlIG1vc3QgcmVjZW50IHJlcG9ydApwcmVnbmFuY3kgPSBwcmVnbmFuY3kgJT4lIAogIG11dGF0ZSh3YXZlID0gc3RyX3N1Yih3YXZlLCAyLCAzKSAlPiUgYXMubnVtZXJpYygpKSAlPiUgIyBmcm9tIG1vc3QgcmVjZW50IHdhdmUgdG8gb2xkZXN0CiAgYXJyYW5nZShkZXNjKHdhdmUpKSAlPiUgIyB1c2UgbW9zdCByZWNlbnQgd2F2ZSAoYmVjYXVzZSB0aGVzZSB3aWxsIGhhdmUgcHJlZ25hbmN5IG91dGNvbWVzKQogIGdyb3VwX2J5KG1vdGhlcl9iaXJ0aGRhdGUpICU+JSAKICBtdXRhdGUoYmlydGhkYXRlX2R1cGVkX2luX2VhcmxpZXJfd2F2ZSA9IG1pbl9yYW5rKHdhdmUpKSAlPiUgCiAgZ3JvdXBfYnkobW90aGVyX2JpcnRob3JkZXIpICU+JSAKICBtdXRhdGUoYmlydGhvcmRlcl9kdXBlZF9pbl9lYXJsaWVyX3dhdmUgPSBtaW5fcmFuayh3YXZlKSkKIyB0aGVzZSBhcmUgcHJlZ25hbmN5IHRoYXQgY2hhbmdlcyBzdGF0dXMgKGkuZS4gb25nb2luZyBpbiB3YXZlIDIsIG1pc2NhcnJpZWQvYm9ybiBieSB3YXZlIDMpCmNyb3NzdGFicyh+IGJpcnRoZGF0ZV9kdXBlZF9pbl9lYXJsaWVyX3dhdmUgKyBiaXJ0aG9yZGVyX2R1cGVkX2luX2VhcmxpZXJfd2F2ZSArIGlzLm5hKGJpcnRoZGF0ZSksIHByZWduYW5jeSkKCiMgdW5mb3J0dW5hdGVseSwgc29tZXRpbWVzIGNocm9uX29yZGVyX2JpcnRoIGlzIGluY29uc2lzdGVudCB3aXRoIGJpcnRoZGF0ZXMKIyB0byBlbGltaW5hdGUgZHVwbGljYXRlcyBmcm9tIHRoZSBwcmVnbmFuY3kgZmlsZSAoYmVjYXVzZSBwcmVnbmFuY2llcyBjaGFuZ2VkIHN0YXR1c2VzKQojIG5vdywgZm9yIHRob3NlIHdoZXJlIHdlIGRvbid0IGtub3cgdGhlIGJpcnRoZGF0ZSwgd2Uga2VlcCBvbmx5IHVuaXF1ZSBiaXJ0aCBvcmRlcnMKIyBmb3IgdGhvc2UsIHdoZXJlIHdlIGtub3cgdGhlIGJpcnRoZGF0ZSwgd2Uga2VlcCBvbmx5IHVuaXF1ZSBiaXJ0aGRhdGVzIChhcyB0aGlzIGlzIGhpZ2hlciBxIGluZm9ybWF0aW9uKQpwcmVnbmFuY3kgPSBwcmVnbmFuY3kgJT4lIAogIGZpbHRlcigoaXMubmEoYmlydGhkYXRlKSAmJiBiaXJ0aG9yZGVyX2R1cGVkX2luX2VhcmxpZXJfd2F2ZSA9PSAxKSB8IGJpcnRoZGF0ZV9kdXBlZF9pbl9lYXJsaWVyX3dhdmUgPT0gMSkgJT4lIAogIHVuZ3JvdXAoKSAjIGVsaW1pbmF0ZSBkdXBlcyBhY3Jvc3Mgd2F2ZXMgKHNhbWUgbW90aGVyX2JpcnRoZGF0ZSksIGtlZXAgbXVsdCBiaXJ0aHMKY3Jvc3N0YWJzKH4gYmlydGhkYXRlX2R1cGVkX2luX2VhcmxpZXJfd2F2ZSArIGJpcnRob3JkZXJfZHVwZWRfaW5fZWFybGllcl93YXZlICsgaXMubmEoYmlydGhkYXRlKSwgcHJlZ25hbmN5KQoKeCA9ICh1bmlxdWUocHJlZ25hbmN5JG1vdGhlcl9waWRsaW5rKSkKCgojIGZvciB3aGF0ZXZlciByZWFzb24gdGhlcmUgYXJlIHNvbWUgbXVsdGlwbGUgYmlydGhzIHdpdGgganVzdCBvbmUgcm93IGluIHRoZSBkYXRhLCBidXQgbnVtYmVyIGFyZSBsb3cgZW5vdWdoCiMgdGhhdCB3ZSBjb25zaWRlciBzb21lIGVycm9ycyBpbiB0aGUgcmVjb3JkcyB0aGUgbGlrZWx5IHJlYXNvbgpwcmVnbmFuY3kgJT4lIGZpbHRlcighaXMubmEoYmlydGhkYXRlKSkgJT4lIGdyb3VwX2J5KG1vdGhlcl9iaXJ0aGRhdGUpICAlPiUgCiAgbXV0YXRlKG11bHQgPSBuKCkpICU+JSBjcm9zc3RhYnMofiBtdWx0ICsgbXVsdGlwbGVfYmlydGggKyBpcy5uYShiaXJ0aF9tb250aCksIGRhdGEgPSAuKQoKIyMgRm9ybSB2YXJpYWJsZSBmb3IgYW55IG11bHRpcGxlIGJpcnRoIHdpdGhpbiBhIGZhbWlseSAodGhlc2UgZmFtaWxpZXMgaGF2ZSB0byBiZSBleGNsdWRlZCBsYXRlcikKcHJlZ25hbmN5ID0gcHJlZ25hbmN5ICU+JSBncm91cF9ieShtb3RoZXJfcGlkbGluaykgJT4lCiAgbXV0YXRlKGFueV9tdWx0aXBsZV9iaXJ0aCA9IGlmX2Vsc2UoYW55KG11bHRpcGxlX2JpcnRoID09IDEsIG5hLnJtID0gVCksIDEsIDApKQojIFByb3BvcnRpb24gb2YgbXVsdGlwbGUgYmlydGhzOgpwcm9wLnRhYmxlKGNyb3NzdGFicyhwcmVnbmFuY3kkbXVsdGlwbGVfYmlydGgpKQojIFByb3BvcnRpb24gb2YgZmFtaWxpZXMgd2l0aCBhbnkgbXVsdGlwbGUgYmlydGg6CnByb3AudGFibGUoY3Jvc3N0YWJzKHByZWduYW5jeSRhbnlfbXVsdGlwbGVfYmlydGgpKQpgYGAKCiMjIyBJbmZvcm1hdGlvbiBhYm91dCBtYXJyaWFnZSBoaXN0b3J5CkZvciBmdWxsIHNpYmxpbmcgYmlydGggb3JkZXIgd2UgbmVlZCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgbWFycmlhZ2VzIG9mIGFsbCB3b21lbiB3aG8gcGFydGljaXBhdGVkIGluIElGTFMgd2F2ZSAxIC0gNS4gV2UgYXJlIGFzc3VtaW5nIGhlcmUgdGhhdCB0aGUgaHVzYmFuZCBpcyB0aGUgZmF0aGVyIG9mIGFsbCBjaGlsZHJlbiB3aG8gd2VyZSBib3JuIHdpdGhpbiB0aGlzIG1hcnJpYWdlLgpgYGB7ciBtYXJyaWFnZSBoaXN0b3J5fQojIyBTZWxlY3QgbWFycmlhZ2UgZGF0YQp3NV9tYXJyaWFnZSA9IHc1X21hcnJpYWdlICU+JSBzZWxlY3QocGlkbGluaywga3cxMG10aCwga3cxMHlyLCBrdzE4bXRoLCBrdzE4eXIsIGt3MTEsIGt3MTkpCnc0X21hcnJpYWdlID0gdzRfbWFycmlhZ2UgJT4lIHNlbGVjdChwaWRsaW5rLCBrdzEwbXRoLCBrdzEweXIsIGt3MThtdGgsIGt3MTh5ciwga3cxMSwga3cxOSkKdzNfbWFycmlhZ2UgPSB3M19tYXJyaWFnZSAlPiUgc2VsZWN0KHBpZGxpbmssIGt3MTBtdGgsIGt3MTB5ciwga3cxOG10aCwga3cxOHlyLCBrdzExLCBrdzE5KQp3Ml9tYXJyaWFnZSA9IHcyX21hcnJpYWdlICU+JSBzZWxlY3QocGlkbGluaywga3cxMG10aCwga3cxMHlyLCBrdzE4bXRoLCBrdzE4eXIsIGt3MTEsIGt3MTkpCncxX21hcnJpYWdlID0gdzFfbWFycmlhZ2UgJT4lIHNlbGVjdChwaWRsaW5rLCBrdzA1YSwga3cwNWIsIGt3MTNhLCBrdzEzYiwga3cwNiwga3cxNGFnZSkKIyBJbiB0aGUgZmlyc3Qgd2F2ZSB0aGUgeWVhciBpcyBuYW1lZCB3cm9uZwp3MV9tYXJyaWFnZSA9IHcxX21hcnJpYWdlICU+JQogIG11dGF0ZShrdzA1YSA9IGlmZWxzZShrdzA1YSA8PSA5MywgYXMubnVtZXJpYyhzdHJfYygiMTkiLCB3MV9tYXJyaWFnZSRrdzA1YSkpLCBrdzA1YSksCiAgICAgICAgIGt3MTNhID0gaWZlbHNlKGt3MTNhIDw9OTMgLCBhcy5udW1lcmljKHN0cl9jKCIxOSIsIHcxX21hcnJpYWdlJGt3MTNhKSksIGt3MTNhKSkKIyBBbmQgdGhlIGNvbHVtbiBuYW1lcyBhcmUgZGlmZmVyZW50IHRoYW4gaW4gbGF0ZXIgd2F2ZXMKdzFfbWFycmlhZ2UgPSB3MV9tYXJyaWFnZSAlPiUKICByZW5hbWUoa3cxMG10aCA9IGt3MDViLCBrdzEweXIgPSBrdzA1YSwga3cxOG10aCA9IGt3MTNiLCBrdzE4eXIgPSBrdzEzYSwga3cxMSA9IGt3MDYsIGt3MTkgPSBrdzE0YWdlKQoKIyMgU2VsZWN0IGFkZGl0aW9uYWwgbWFycmlhZ2UgaW5mb3JtYXRpb24gKGFnZSBvZiByZXNwb25kZW50KQp3NV9tYXJyaWFnZV9hZGRpdGlvbmFsID0gdzVfbWFycmlhZ2VfYWRkaXRpb25hbCAlPiUgc2VsZWN0KHBpZGxpbmssIGFnZSwgZG9iX3lyKQp3NF9tYXJyaWFnZV9hZGRpdGlvbmFsID0gdzRfbWFycmlhZ2VfYWRkaXRpb25hbCAlPiUgc2VsZWN0KHBpZGxpbmssIGFnZSwgZG9iX3lyKQp3M19tYXJyaWFnZV9hZGRpdGlvbmFsID0gdzNfbWFycmlhZ2VfYWRkaXRpb25hbCAlPiUgc2VsZWN0KHBpZGxpbmssIGFnZSwgZG9iX3lyKQp3Ml9tYXJyaWFnZV9hZGRpdGlvbmFsID0gdzJfbWFycmlhZ2VfYWRkaXRpb25hbCAlPiUgc2VsZWN0KHBpZGxpbmssIGFnZSwgZG9iX3lyKQp3MV9tYXJyaWFnZV9hZGRpdGlvbmFsID0gdzFfbWFycmlhZ2VfYWRkaXRpb25hbCAlPiUgc2VsZWN0KHBpZGxpbmssIGFyMDl5ciwgYXIwOHlyKQojIEluIHRoZSBmaXJzdCB3YXZlIHRoZSB5ZWFyIGlzIG5hbWVkIHdyb25nCncxX21hcnJpYWdlX2FkZGl0aW9uYWwgPSB3MV9tYXJyaWFnZV9hZGRpdGlvbmFsICU+JQogIG11dGF0ZShhcjA4eXIgPSBpZmVsc2UoYXIwOHlyIDw9IDkzLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGFzLm51bWVyaWMoc3RyX2MoIjE5IiwgdzFfbWFycmlhZ2VfYWRkaXRpb25hbCRhcjA4eXIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGFyMDh5cikpCiMgQW5kIHRoZSBjb2x1bW4gbmFtZXMgYXJlIGRpZmZlcmVudCB0aGFuIGluIGxhdGVyIHdhdmVzCncxX21hcnJpYWdlX2FkZGl0aW9uYWwgPSB3MV9tYXJyaWFnZV9hZGRpdGlvbmFsICU+JSByZW5hbWUoYWdlID0gYXIwOXlyLCBkb2JfeXIgPSBhcjA4eXIpCgojIyBDb21iaW5lIG1hcnJpYWdlIGluZm9ybWF0aW9uIGFuZCBhZGRpdGlvbmFsIG1hcnJpYWdlIGluZm9ybWF0aW9uOgp3MV9tYXJyaWFnZSA9IGxlZnRfam9pbih3MV9tYXJyaWFnZSwgdzFfbWFycmlhZ2VfYWRkaXRpb25hbCwgYnkgPSAicGlkbGluayIpICU+JQogIG11dGF0ZSh3YXZlID0gYXMubnVtZXJpYygiMTk5MyIpKQp3Ml9tYXJyaWFnZSA9IGxlZnRfam9pbih3Ml9tYXJyaWFnZSwgdzJfbWFycmlhZ2VfYWRkaXRpb25hbCwgYnkgPSAicGlkbGluayIpICU+JQogIG11dGF0ZSh3YXZlID0gYXMubnVtZXJpYygiMTk5NyIpKQp3M19tYXJyaWFnZSA9IGxlZnRfam9pbih3M19tYXJyaWFnZSwgdzNfbWFycmlhZ2VfYWRkaXRpb25hbCwgYnkgPSAicGlkbGluayIpICAlPiUKICBtdXRhdGUod2F2ZSA9IGFzLm51bWVyaWMoIjIwMDAiKSkKdzRfbWFycmlhZ2UgPSBsZWZ0X2pvaW4odzRfbWFycmlhZ2UsIHc0X21hcnJpYWdlX2FkZGl0aW9uYWwsIGJ5ID0gInBpZGxpbmsiKSAlPiUKICBtdXRhdGUod2F2ZSA9IGFzLm51bWVyaWMoIjIwMDciKSkKdzVfbWFycmlhZ2UgPSBsZWZ0X2pvaW4odzVfbWFycmlhZ2UsIHc1X21hcnJpYWdlX2FkZGl0aW9uYWwsIGJ5ID0gInBpZGxpbmsiKSAlPiUKICBtdXRhdGUod2F2ZSA9IGFzLm51bWVyaWMoIjIwMTQiKSkKCiMjIENvbWJpbmUgbWFycmlhZ2UgaW5mb3JtYXRpb25zCm1hcnJpYWdlID0gYmluZF9yb3dzKHcxX21hcnJpYWdlLCB3Ml9tYXJyaWFnZSwgdzNfbWFycmlhZ2UsIHc0X21hcnJpYWdlLCB3NV9tYXJyaWFnZSkKCiMgUmVuYW1lIGNvbHVtbnMKbWFycmlhZ2UgPSBtYXJyaWFnZSAlPiUKICByZW5hbWUoc3RhcnRfeWVhciA9IGt3MTB5ciwgc3RhcnRfbW9udGggPSBrdzEwbXRoLCBlbmRfeWVhciA9IGt3MTh5ciwgZW5kX21vbnRoID0ga3cxOG10aCwgc3RhcnRfYWdlID0ga3cxMSwgZW5kX2FnZSA9IGt3MTksIGJpcnRoX3llYXIgPSBkb2JfeXIsIGJpcnRoX2FnZSA9IGFnZSkKCgojIFNldCB2YWx1ZXMgYXMgTkEgdGhhdCBhcmUgbWlzc2luZyAoYWxsIHZhbHVlcyB0aGF0IGFyZSBub3QgbG9naWNhbCkKbWFycmlhZ2Ukc3RhcnRfeWVhclttYXJyaWFnZSRzdGFydF95ZWFyIDwgMTkwMF0gPSBOQQptYXJyaWFnZSRzdGFydF95ZWFyW21hcnJpYWdlJHN0YXJ0X3llYXIgPiAyMDE2XSA9IE5BCm1hcnJpYWdlJHN0YXJ0X3llYXJbaXMubmFuKG1hcnJpYWdlJHN0YXJ0X3llYXIpXSA9IE5BCm1hcnJpYWdlJGVuZF95ZWFyW21hcnJpYWdlJGVuZF95ZWFyIDwgMTkwMF0gPSBOQQptYXJyaWFnZSRlbmRfeWVhclttYXJyaWFnZSRlbmRfeWVhciA+IDIwMTZdID0gTkEKbWFycmlhZ2UkZW5kX3llYXJbaXMubmFuKG1hcnJpYWdlJGVuZF95ZWFyKV0gPSBOQQptYXJyaWFnZSRzdGFydF9tb250aFttYXJyaWFnZSRzdGFydF9tb250aCA+IDEyXSA9IE5BCm1hcnJpYWdlJHN0YXJ0X21vbnRoW2lzLm5hbihtYXJyaWFnZSRzdGFydF9tb250aCldID0gTkEKbWFycmlhZ2UkZW5kX21vbnRoW21hcnJpYWdlJGVuZF9tb250aCA+IDEyXSA9IE5BCm1hcnJpYWdlJGVuZF9tb250aFtpcy5uYW4obWFycmlhZ2UkZW5kX21vbnRoKV0gPSBOQQptYXJyaWFnZSRzdGFydF9hZ2VbbWFycmlhZ2Ukc3RhcnRfYWdlID4gOTddID0gTkEKbWFycmlhZ2Ukc3RhcnRfYWdlW2lzLm5hbihtYXJyaWFnZSRzdGFydF9hZ2UpXSA9IE5BCm1hcnJpYWdlJGVuZF9hZ2VbbWFycmlhZ2UkZW5kX2FnZSA+IDk3XSA9IE5BCm1hcnJpYWdlJGVuZF9hZ2VbaXMubmFuKG1hcnJpYWdlJGVuZF9hZ2UpXSA9IE5BCm1hcnJpYWdlJGJpcnRoX3llYXJbbWFycmlhZ2UkYmlydGhfeWVhciA8IDE5MDBdID0gTkEKbWFycmlhZ2UkYmlydGhfeWVhclttYXJyaWFnZSRiaXJ0aF95ZWFyID4gMjAxNl0gPSBOQQptYXJyaWFnZSRiaXJ0aF95ZWFyW2lzLm5hbihtYXJyaWFnZSRiaXJ0aF95ZWFyKV0gPSBOQQptYXJyaWFnZSRiaXJ0aF9hZ2VbbWFycmlhZ2UkYmlydGhfYWdlID4gOTddID0gTkEKbWFycmlhZ2UkYmlydGhfYWdlW2lzLm5hbihtYXJyaWFnZSRiaXJ0aF9hZ2UpXSA9IE5BCgojIyBSZWNvbnN0cnVjdCBtYXJyaWFnZSBzdGFydCB5ZWFyIGFuZCBlbmQgeWVhciBmb3IgbWFycmlhZ2VzIHdpdGggbWlzc2luZyB5ZWFyIGZyb20gYWdlIGF0IG1hcnJpYWdlCm1hcnJpYWdlID0gbWFycmlhZ2UgJT4lCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBpZmVsc2UoaXMubmEoYmlydGhfeWVhciksIHdhdmUgLSBiaXJ0aF9hZ2UsIGJpcnRoX3llYXIpLAogICAgICAgICBzdGFydF95ZWFyID0gaWZlbHNlKGlzLm5hKHN0YXJ0X3llYXIpLCBiaXJ0aF95ZWFyICsgc3RhcnRfYWdlLCBzdGFydF95ZWFyKSwKICAgICAgICAgZW5kX3llYXIgPSBpZmVsc2UoaXMubmEoZW5kX3llYXIpLCBiaXJ0aF95ZWFyICsgZW5kX2FnZSwgZW5kX3llYXIpKQoKIyMgQXJyYW5nZSBkYXRhc2V0OgptYXJyaWFnZSA9IG1hcnJpYWdlICU+JSBhcnJhbmdlKHBpZGxpbmssIHN0YXJ0X3llYXIsIHN0YXJ0X21vbnRoLCBzdGFydF9hZ2UsIGVuZF95ZWFyLCBlbmRfbW9udGgsIGVuZF9hZ2UpCgojIyBFbGltaW5hdGUgZHVwbGljYXRlcyAocGVvcGxlIHdobyBnb3QgbWFycmllZCB0d2ljZSBvbiB0aGUgc2FtZSBkYXkpCiMgcHJvcGFibHkgZHVlIHRvIHNvbWUgZXJyb3IgaW4gcmVwb3J0aW5nIG1hcnJpYWdlcwptYXJyaWFnZSA9IG1hcnJpYWdlICU+JSBmaWx0ZXIoIWR1cGxpY2F0ZWQoY2JpbmQocGlkbGluaywgc3RhcnRfeWVhciwgc3RhcnRfbW9udGgpKSB8IGlzLm5hKHN0YXJ0X3llYXIpIHwgaXMubmEoc3RhcnRfbW9udGgpKSAjIG5vYm9keSBnZXRzIG1hcnJpZWQgdHdpY2Ugb24gdGhlIHNhbWUgZGF5LCByaWdodD8gc28gdGhlc2UgYXJlIGR1cGVzLgoKIyMgQ2FsY3VsYXRlIGRhdGUgZm9yIGJlZ2lubmluZyBvZiBtYXJyaWFnZToKbWFycmlhZ2UgPSBtYXJyaWFnZSAlPiUgCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShzdGFydF9zdHJpbmcgPSBzdHJfYyhzdGFydF95ZWFyLCAiLSIsIGlmZWxzZShpcy5uYShzdGFydF9tb250aCksICIwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZF9tb250aChzdGFydF9tb250aCkpLCAiLTAxIiksCiAgICAgICAgZW5kX3N0cmluZyA9IHN0cl9jKGVuZF95ZWFyLCAiLSIsIGlmZWxzZShpcy5uYShlbmRfbW9udGgpLCAiMTIiLCBwYWRfbW9udGgoZW5kX21vbnRoKSksICItMDEiKSwKICAgICAgICBzdGFydCA9IHltZChzdGFydF9zdHJpbmcpLAogICAgICAgIGVuZCA9IHltZChlbmRfc3RyaW5nKSArIG1vbnRocygxKSAtIGRheXMoMSkpCgojIyBDb3VudCBudW1iZXIgb2YgbWFycmlhZ2VzIGZvciBldmVyeSB3b21hbgptYXJyaWFnZSA9IG1hcnJpYWdlICU+JQogIGFycmFuZ2UocGlkbGluaywgc3RhcnQsIGVuZCkgJT4lCiAgZ3JvdXBfYnkocGlkbGluaykgJT4lCiAgbXV0YXRlKG51bWJlcl9tYXJyaWFnZXMgPSBuKCksCiAgICAgICAgIG9yZGVyX21hcnJpYWdlID0gcm93X251bWJlcigpLAogICAgICAgICBtYXJyaWFnZV9pZCA9IHBhc3RlMChwaWRsaW5rLCAiXyIsIGFzLmNoYXJhY3RlcihvcmRlcl9tYXJyaWFnZSksICJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMuY2hhcmFjdGVyKHN0YXJ0KSwgIi8iLGFzLmNoYXJhY3RlcihlbmQpKSkKCiMjIE1hcnJpYWdlIFRpbWVsaW5lOiByZWNvbnN0cnVjdCB0aW1lbGluZSBvZiBtYXJyaWFnZXMgZm9yIGV2ZXJ5IHdvbWFuCiMgV2UgbmVlZCB0aGlzIGxhdGVyIGZvciByZWNvbnN0cnVjdGluZyB3aG8gaXMgdGhlIGZhdGhlcgptaW5pbXVtX3N0YXJ0ID0gbWluKHltZChzdHJfYyhwcmVnbmFuY3kkbW9udGgsICItMDEiKSksIG5hLnJtID0gVCkKbWF4aW11bV9lbmQgPSBtYXgoeW1kKHN0cl9jKHByZWduYW5jeSRtb250aCwgIi0wMSIpKSwgbmEucm0gPSBUKQoKbWFycmlhZ2VfdGltZWxpbmUgPSBtYXJyaWFnZSAlPiUKICAgIG11dGF0ZShpbXBsaWVkX3N0YXJ0ID0gYXMuRGF0ZShpZmVsc2UoaXMubmEoc3RhcnQpLCBtaW5pbXVtX3N0YXJ0ICwgc3RhcnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiA9ICIxOTcwLTAxLTAxIiksCiAgICAgICAgICAgaW1wbGllZF9lbmQgPSBhcy5EYXRlKGlmZWxzZShpcy5uYShlbmQpLCBtYXhpbXVtX2VuZCAsIGVuZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbiA9ICIxOTcwLTAxLTAxIikpICU+JQogIGZpbHRlcihpbXBsaWVkX3N0YXJ0IDwgaW1wbGllZF9lbmQpCgptYXJyaWFnZV90aW1lbGluZSA9IG1hcnJpYWdlX3RpbWVsaW5lICU+JQogICAgcm93d2lzZSgpICU+JQogICAgZG8oZGF0YS5mcmFtZSgKICAgICAgICBtYXJyaWFnZV9pZCA9IC4kbWFycmlhZ2VfaWQsIAogICAgICAgIG1vdGhlcl9waWRsaW5rID0gLiRwaWRsaW5rLAogICAgICAgIG9yZGVyX21hcnJpYWdlID0gLiRvcmRlcl9tYXJyaWFnZSwKICAgICAgICBzdGFydCA9IC4kc3RhcnQsCiAgICAgICAgZW5kID0gLiRlbmQsCiAgICAgICAgbW9udGggPSBzZXEoLiRpbXBsaWVkX3N0YXJ0LC4kaW1wbGllZF9lbmQsIGJ5ID0gIjEgbW9udGgiKSApKQoKIyBubyBkdXBsaWNhdGUgbW90aGVyX2lkIC0gbW9udGggY29tYmluYXRpb25zIChubyB0d28gbWFycmlhZ2VzIGF0IHRoZSBzYW1lIHRpbWUpCm1hcnJpYWdlX3RpbWVsaW5lID0gbWFycmlhZ2VfdGltZWxpbmUgJT4lIAogIGFycmFuZ2UobW90aGVyX3BpZGxpbmssIHN0YXJ0LCBlbmQpICU+JSAKICBkaXN0aW5jdChtb3RoZXJfcGlkbGluaywgbW9udGgsIC5rZWVwX2FsbCA9IFRSVUUpCgojIFdlIG9ubHkgbmVlZCB5ZWFyIGFuZCBtb250aCwgbm90IHRoZSBleGFjdCBkYXkKbWFycmlhZ2VfdGltZWxpbmUkbW9udGggPSBzdHJpbmdyOjpzdHJfc3ViKGFzLmNoYXJhY3RlcihtYXJyaWFnZV90aW1lbGluZSRtb250aCksMSw3KQoKIyB3ZSBhc3N1bWUgdGhhdCBmYXRoZXJzIGFyZSB0aG9zZSB0byB3aG9tIG1vdGhlcnMgd2VyZSBtYXJyaWVkIGluIHRoZSBiaXJ0aCBtb250aApwcmVnbmFuY3kgPSBwcmVnbmFuY3kgJT4lIGxlZnRfam9pbihtYXJyaWFnZV90aW1lbGluZSwgYnkgPSBjKCJtb3RoZXJfcGlkbGluayIsICJtb250aCIpKSAlPiUgdW5ncm91cCgpCmBgYAoKCiMjIyBCaXJ0aCBvcmRlciBjYWxjdWxhdGlvbnMgey50YWJzZXR9CkhlcmUgd2UgY2FsY3VsYXRlIGZ1bGwgc2libGluZyBiaXJ0aCBvcmRlciwgbWF0ZXJuYWwgYmlydGggb3JkZXIgYW5kIG1hdGVybmFsIHByZWduYW5jeSBvcmRlcgpgYGB7ciBmdWxsIHNpYmxpbmcgYmlydGggb3JkZXJ9CiMjIyMgTWF0ZXJuYWwgUHJlZ25hbmN5IE9yZGVyCnByZWduYW5jeTEgPSBwcmVnbmFuY3kgJT4lCiAgZ3JvdXBfYnkobW90aGVyX3BpZGxpbmspICU+JQogIG11dGF0ZShiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnID0gbWluX3JhbmsoYmlydGhkYXRlKSwKICAgICAgICAgYmlydGhvcmRlcl91dGVydXNfcHJlZzIgPSBpZmVsc2UoaXMubmEoYmlydGhvcmRlcl91dGVydXNfcHJlZyksIGNocm9uX29yZGVyX2JpcnRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGNocm9uX29yZGVyX2JpcnRoID4gYmlydGhvcmRlcl91dGVydXNfcHJlZywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hyb25fb3JkZXJfYmlydGgsIGJpcnRob3JkZXJfdXRlcnVzX3ByZWcpKSwKICAgICAgICAgc2libGluZ19jb3VudF91dGVydXNfcHJlZyA9IHN1bSghaXMubmEoYmlydGhkYXRlKSksCiAgICAgICAgIHNpYmxpbmdfY291bnRfdXRlcnVzX3ByZWcyID0gaWZlbHNlKGlzLm5hKHNpYmxpbmdfY291bnRfdXRlcnVzX3ByZWcpLCBtYXgoY2hyb25fb3JkZXJfYmlydGgsIG5hLnJtID0gVCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShtYXgoY2hyb25fb3JkZXJfYmlydGgsIG5hLnJtID0gVCkgPiBzaWJsaW5nX2NvdW50X3V0ZXJ1c19wcmVnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChjaHJvbl9vcmRlcl9iaXJ0aCwgbmEucm0gPSBUKSwgc2libGluZ19jb3VudF91dGVydXNfcHJlZykpCiAgICAgICAgKSAlPiUKICB1bmdyb3VwKCkKCmNvci50ZXN0KHByZWduYW5jeTEkYmlydGhvcmRlcl91dGVydXNfcHJlZywgcHJlZ25hbmN5MSRiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnMikKY3Jvc3N0YWJzKH4gaXMubmEoYmlydGhvcmRlcl91dGVydXNfcHJlZykgKyBpcy5uYShiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnMikgKyBpcy5uYShiaXJ0aGRhdGUpLCBwcmVnbmFuY3kxKQpjcm9zc3RhYnMofiBpcy5uYShzaWJsaW5nX2NvdW50X3V0ZXJ1c19wcmVnKSArIGlzLm5hKHNpYmxpbmdfY291bnRfdXRlcnVzX3ByZWcyKSArIGlzLm5hKGJpcnRoZGF0ZSksIHByZWduYW5jeTEpCiMgb3VyIGJpcnRoZGF0ZSBiYXNlZCBiaXJ0aG9yZGVyIGVzdGltYXRlcyBhcmUgZXh0cmVtZWx5IGNvbnNpc3RlbnQgd2l0aCBjaHJvbl9vcmRlcl9iaXJ0aAoKIyMjIyBNYXRlcm5hbCBCaXJ0aCBPcmRlcgpwcmVnbmFuY3kyID0gcHJlZ25hbmN5ICU+JQogIGZpbHRlcihsaWZlYmlydGhzID09IDIpICU+JQogIGdyb3VwX2J5KG1vdGhlcl9waWRsaW5rKSAlPiUKICAgIG11dGF0ZShiaXJ0aG9yZGVyX3V0ZXJ1c19hbGl2ZSA9IG1pbl9yYW5rKGJpcnRoZGF0ZSksCiAgICAgICAgICAgc2libGluZ19jb3VudF91dGVydXNfYWxpdmUgPSBzdW0oIWlzLm5hKGJpcnRoZGF0ZSkpCiAgICAgICAgICAgKSAlPiUKICB1bmdyb3VwKCkKCnByZWduYW5jeTIgPSBwcmVnbmFuY3kyICU+JSBzZWxlY3QobW90aGVyX2JpcnRoZGF0ZSwgYmlydGhvcmRlcl91dGVydXNfYWxpdmUsIHNpYmxpbmdfY291bnRfdXRlcnVzX2FsaXZlKSAlPiUgZGlzdGluY3QoKQoKIyMjIyBQYXJlbnRhbCBGdWxsIFNpYmxpbmcgQmlydGhvcmRlciAoYmFzZWQgb24gbW90aGVyIGFuZCBmYXRoZXIpCnByZWduYW5jeTMgPSBwcmVnbmFuY3kgJT4lCiAgZmlsdGVyKGxpZmViaXJ0aHMgPT0gMikgJT4lCiAgZ3JvdXBfYnkobWFycmlhZ2VfaWQpICU+JQogICAgbXV0YXRlKGJpcnRob3JkZXJfZ2VuZXMgPSBtaW5fcmFuayhiaXJ0aGRhdGUpLAogICAgICAgICAgIGJpcnRob3JkZXJfZ2VuZXMgPSBpZmVsc2UoaXMubmEobWFycmlhZ2VfaWQpLCBOQSwgYmlydGhvcmRlcl9nZW5lcyksCiAgICAgICAgICAgc2libGluZ19jb3VudF9nZW5lcyA9IGlmZWxzZShpcy5uYShtYXJyaWFnZV9pZCksIE5BLCBzdW0oIWlzLm5hKG1hcnJpYWdlX2lkKSkpKSAlPiUKICB1bmdyb3VwKCkKCnByZWduYW5jeTMgPSBwcmVnbmFuY3kzICU+JSBzZWxlY3QobW90aGVyX2JpcnRoZGF0ZSwgYmlydGhvcmRlcl9nZW5lcywgc2libGluZ19jb3VudF9nZW5lcykgJT4lIGRpc3RpbmN0KCkKCgojIHJlbW92ZSBkdXBsaWNhdGVzIGJlY2F1c2Ugb2YgbWlzc2luZ3MgYW5kIHR3aW5zCnByZWduYW5jeTEgPC0gcHJlZ25hbmN5MSAlPiUgc2VsZWN0KC1iaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnMiwgLXNpYmxpbmdfY291bnRfdXRlcnVzX3ByZWcyKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShiaXJ0aGRhdGUpKSAlPiUgCiAgZGlzdGluY3QobW90aGVyX2JpcnRoZGF0ZSwgLmtlZXBfYWxsID0gVFJVRSkKCnByZWduYW5jeTIgPC0gcHJlZ25hbmN5MiAlPiUKICBkaXN0aW5jdChtb3RoZXJfYmlydGhkYXRlLCAua2VlcF9hbGwgPSBUUlVFKQoKIyMjIENvbWJpbmUgYmlydGhvcmRlciBkYXRhCnByZWduYW5jeSA9IGxlZnRfam9pbihwcmVnbmFuY3kxLCBwcmVnbmFuY3kyLCBieSA9ICJtb3RoZXJfYmlydGhkYXRlIikgJT4lIHVuZ3JvdXAoKQpwcmVnbmFuY3kgPSBsZWZ0X2pvaW4ocHJlZ25hbmN5LCBwcmVnbmFuY3kzLCBieSA9ICJtb3RoZXJfYmlydGhkYXRlIikgJT4lIHVuZ3JvdXAoKQpgYGAKCgojIyMgQmlydGggb3JkZXIgZ3JhcGhzCkluIG9yZGVyIHRvIGNoZWNrIHdoZXRoZXIgd2UgY2FsY3VsYXRlZCBiaXJ0aCBvcmRlciBjb3JyZWN0bHkgd2UgY3JlYXRlZCBzb21lIGdyYXBocy4KYGBge3J9CiMjIyBHcmFwaHMgYXJlIHVzZWQgdG8gc2hvdyBkaWZmZXJlbmNlcyBiZXR3ZWVuIGJpcnRoIG9yZGVyIG1lYXN1cmVtZW50cwojIyBCaW9sb2dpY2FsIEJpcnRob3JkZXIgLSBVdGVydXNfUHJlZ25hbmNpZXMKZ2dwbG90KHByZWduYW5jeSwgYWVzKHggPSBzaWJsaW5nX2NvdW50X3V0ZXJ1c19wcmVnLCB5ID0gYmlydGhvcmRlcl91dGVydXNfcHJlZykpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSkKCiMjIEJpb2xvZ2ljYWwgQmlydGhvcmRlciAtIFV0ZXJ1c19CaXJ0aHMKZ2dwbG90KHByZWduYW5jeSwgYWVzKHggPSBzaWJsaW5nX2NvdW50X3V0ZXJ1c19hbGl2ZSwgeSA9IGJpcnRob3JkZXJfdXRlcnVzX2FsaXZlKSkgKwogIGdlb21faml0dGVyKGFscGhhID0gMC4xKQoKIyMgQmlvbG9naWNhbCBCaXJ0aG9yZGVyIC0gRnVsbCBTaWJsaW5nIE9yZGVyCmdncGxvdChwcmVnbmFuY3ksIGFlcyh4ID0gc2libGluZ19jb3VudF9nZW5lcywgeT1iaXJ0aG9yZGVyX2dlbmVzKSkgKyBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSkKCiMjIEJpbzogVXRlcnVzX3ByZWcgdnMuIFV0ZXJ1c19CaXJ0aHMKZ2dwbG90KHByZWduYW5jeSwgYWVzKHggPSBiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnLCB5ID0gYmlydGhvcmRlcl91dGVydXNfYWxpdmUpKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEpCiMgVGhlIGJpcnRoX29yZGVyX2FsaXZlIGlzIGFsd2F5cyBsb3dlciwgd2hpY2ggbWFrZXMgc2Vuc2UsIGJlY2F1cyBub3QgbGl2ZSBiaXJ0aHMgKG1pc2NhcnJpYWdlLCBzdGlsbCBiaXJ0aHMpIGFyZSBleGNsdWRlZAoKIyMgQmlvOiBVdGVydXNfcHJlZyB2cy4gR2VuZXMKZ2dwbG90KHByZWduYW5jeSwgYWVzKHggPSBiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnLCB5ID0gYmlydGhvcmRlcl9nZW5lcykpICsgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEpCiMgVGhlIGJpcnRob3JkZXJfZ2VuZXMgaXMgYWx3YXlzIGxvd2VyLCB3aGljaCBtYWtlcyBzZW5zZSwgYmVjYXVzZSBkaWZmZXJlbnQvdW5rbm93biBmYXRoZXJzIGFyZSBleGNsdWRlZAoKIyMgQmlvOiBVdGVydXNfYWxpdmUgdnMuIEdlbmVzCmdncGxvdChwcmVnbmFuY3ksIGFlcyh4ID0gYmlydGhvcmRlcl91dGVydXNfYWxpdmUsIHkgPSBiaXJ0aG9yZGVyX2dlbmVzKSkgICsgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEpCiMgY2hpbGRyZW4gd2l0aCB0aGUgc2FtZSBmYXRoZXIgaW5jbHVkZXMgb25seSBsaXZlIGJpcnRocwoKIyBjaHJvbiBvcmRlciBiaXJ0aCBkb2VzIG5vdCBjb3JyZWxhdGUgcGVyZmVjdGx5LCB1bnN1cnByaXNpbmcgZ2l2ZW4gdGhhdCB3ZSBmb3VuZCBjaHJvbiBvcmRlcnMgc29tZXRpbWVzIHN0YXJ0ZWQgZnJvbSAxIGluIG5ldyB3YXZlcyBldmVuIHRob3VnaCBwcmV2aW91cyBiaXJ0aHMgd2VyZSByZWNvcmRlZApwcmVnbmFuY3kgJT4lIHNlbGVjdChjaHJvbl9vcmRlcl9iaXJ0aCwgYmlydGhvcmRlcl91dGVydXNfYWxpdmUsIGJpcnRob3JkZXJfdXRlcnVzX3ByZWcsIGJpcnRob3JkZXJfZ2VuZXMpICU+JQogIG5hLm9taXQoKSAlPiUgY29yKCkKcHJlZ25hbmN5ICU+JSBzZWxlY3QoY2hyb25fb3JkZXJfYmlydGgsIGJpcnRob3JkZXJfdXRlcnVzX2FsaXZlLCBiaXJ0aG9yZGVyX3V0ZXJ1c19wcmVnLCBiaXJ0aG9yZGVyX2dlbmVzKSAlPiUgbWlzc2luZ25lc3NfcGF0dGVybnMoKQpwcmVnbmFuY3kgJT4lIHNlbGVjdChzaWJsaW5nX2NvdW50X3V0ZXJ1c19hbGl2ZSwgc2libGluZ19jb3VudF91dGVydXNfcHJlZywgc2libGluZ19jb3VudF9nZW5lcykgJT4lIG1pc3NpbmduZXNzX3BhdHRlcm5zKCkKYGBgCgojIyBTZWxlY3QgaW5kaXZpZHVhbCBkYXRhIGZyb20gSUZMUyA1CkhlcmUgd2Ugc2VsZWN0IGFsbCB2YXJpYWJsZXMgZm9yIG91dGNvbWUgbWVhc3VyZW1lbnRzCmBgYHtyIHNlbGVjdCBpbmRpdmlkdWFsIGRhdGF9CiMjIyBJbmRpdmlkdWFscwppbmRpdmlkdWFscyA9IGJrX2FyMSAlPiUgc2VsZWN0KGhoaWQxNF85LCBwaWRsaW5rLCBmYXRoZXJfcGlkbGluaywgbW90aGVyX3BpZGxpbmssIGFyMDFhLCBhcjAyYiwgYXIxMCwgYXIxMSwgYXIwNywgYXIwOGRheSwgYXIwOG10aCwgYXIwOHlyLCBhcjA5LCBhcjE4ZXlyLCBhcjE4ZW10aCkKaW5kaXZpZHVhbHMgPSBsZWZ0X2pvaW4oaW5kaXZpZHVhbHMsIGJrX3NjMSAlPiUgc2VsZWN0KGhoaWQxNF85LCBzYzA1LCBwcm92aW5jZSwgc2MwMV8xNF8xNCksIGJ5ID0gYygiaGhpZDE0XzkiKSkKCiNSZW5hbWUgdmFyaWFibGVzOgppbmRpdmlkdWFscyA9IHJlbmFtZShpbmRpdmlkdWFscywgcmVsYXRpb25fdG9fSEhfaGVhZCA9IGFyMDJiLCBmYXRoZXJJRCA9IGFyMTAsIG1vdGhlcklEID0gYXIxMSwgc2V4ID0gYXIwNywgYWdlID0gYXIwOSwgc3RhdHVzID0gYXIwMWEsIGRlYXRoX3lyID0gYXIxOGV5ciwgZGVhdGhfbW9udGggPSBhcjE4ZW10aCkgCiMgUmVtb3ZlIGR1cGxpY2F0cyAoc29tZSBwZW9wbGUgYXJlIG1lbnRpb25lZCBpbiB0d28gaG91c2Vob2xkcywgZS5nLiBiZWNhdXNlIHRoZXkgbW92ZWQgaW4gdGhlIGxhc3QgMTIgbW9udGhzKQppbmRpdmlkdWFscyA9IGluZGl2aWR1YWxzICU+JSBkaXN0aW5jdChwaWRsaW5rLCAua2VlcF9hbGwgPSBUUlVFKQppbmRpdmlkdWFsc191bmNoYW5nZWQgPSBpbmRpdmlkdWFscwoKIyMgcGVvcGxlIHdob3NlIHBhcmVudHMgY2FuIG5vdCBiZSBpZGVudGlmaWVkIGhhdmUgdG8gYmUgbWFya2VkIGFzIE5BOgppbmRpdmlkdWFscyRmYXRoZXJJRFtpbmRpdmlkdWFscyRmYXRoZXJJRCA+IDUwXSA9IE5BCmluZGl2aWR1YWxzJG1vdGhlcklEW2luZGl2aWR1YWxzJG1vdGhlcklEID4gNTBdID0gTkEKCgojIyBDcmVhdGUgZGF0ZSBvZiBiaXJ0aAojU2V0IGFsbCB2YXJpYWJsZXMgbWlzc2luZyB0aGF0IGhhdmUgbm90IGJlZW4gcmVwb3J0ZWQ6CmluZGl2aWR1YWxzJGFyMDhkYXlbaW5kaXZpZHVhbHMkYXIwOGRheSA+IDMxXSA9IE5BCmluZGl2aWR1YWxzJGFyMDhtdGhbaW5kaXZpZHVhbHMkYXIwOG10aCA+IDEyXSA9IE5BCmluZGl2aWR1YWxzJGFyMDh5cltpbmRpdmlkdWFscyRhcjA4eXIgPiAyMDE2XSA9IE5BCmluZGl2aWR1YWxzJGFyMDhkYXlbaXMubmFuKGluZGl2aWR1YWxzJGFyMDhkYXkpXSA9IE5BCmluZGl2aWR1YWxzJGFyMDhtdGhbaXMubmFuKGluZGl2aWR1YWxzJGFyMDhtdGgpXSA9IE5BCmluZGl2aWR1YWxzJGFyMDh5cltpcy5uYW4oaW5kaXZpZHVhbHMkYXIwOHlyKV0gPSBOQQppbmRpdmlkdWFscyRkZWF0aF9tb250aFtpbmRpdmlkdWFscyRkZWF0aF9tb250aCA+IDEyXSA9IE5BCmluZGl2aWR1YWxzJGRlYXRoX3lyW2luZGl2aWR1YWxzJGRlYXRoX3lyID4gMjAxNl0gPSBOQQppbmRpdmlkdWFscyRkZWF0aF9tb250aFtpcy5uYW4oaW5kaXZpZHVhbHMkZGVhdGhfbW9udGgpXSA9IE5BCmluZGl2aWR1YWxzJGRlYXRoX3lyW2lzLm5hbihpbmRpdmlkdWFscyRkZWF0aF95cildID0gTkEKCiMjIENyZWF0ZSB2YXJpYWJsZSB0aGF0IGNvbnRhaW5zIHBpZGxpbmsgb2YgbW90aGVyIGFuZCBiaXJ0aGRhdGUgb2YgY2hpbGQ6CmluZGl2aWR1YWxzID0gaW5kaXZpZHVhbHMgJT4lCiAgICBtdXRhdGUoYmlydGhkYXRlID0gYWxsX2F2YWlsYWJsZV9pbmZvX2JpcnRoX2RhdGUoYXIwOHlyLCBhcjA4bXRoLCBhcjA4ZGF5KSwKICAgICAgICAgICBtb3RoZXJfYmlydGhkYXRlID0gc3RyX2MobW90aGVyX3BpZGxpbmssICItIiwgYmlydGhkYXRlKSkgIyBtb3RoZXJfcGlkbGluay1ZWVlZLU1NOyBpcyBOQSBpZiBiaXJ0aF95ZWFyIGlzIG1pc3NpbmcKCiMjIENyZWF0ZSBuYWl2ZSBiaXJ0aCBvcmRlcihiYXNlZCBvbiBtb3RoZXJfaWQgYW5kIGxpdmluZyBpbiB0aGUgc2FtZSBob3VzZWhvbGQpCmluZGl2aWR1YWxzID0gaW5kaXZpZHVhbHMgJT4lIGdyb3VwX2J5KG1vdGhlcl9waWRsaW5rKSAlPiUgCiAgbXV0YXRlKGJpcnRob3JkZXJfbmFpdmVfaW5kID0gaWZfZWxzZSghaXMubmEobW90aGVyX3BpZGxpbmspLCBtaW5fcmFuayhiaXJ0aGRhdGUpLCBOQV9pbnRlZ2VyXyksCiAgICAgICAgIHNpYmxpbmdfY291bnRfbmFpdmVfaW5kID0gaWZfZWxzZSghaXMubmEobW90aGVyX3BpZGxpbmspLCBuKCksIE5BX2ludGVnZXJfKSkgJT4lIAogIHVuZ3JvdXAoKQoKIyMgSm9pbmcgcHJlZ25hbmN5IGFuZCBpbmRpdmlkdWFscyBkYXRhCmFsbGRhdGFfcHJlZ25hbmN5ID0gZnVsbF9qb2luKHByZWduYW5jeSwgaW5kaXZpZHVhbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygibW90aGVyX3BpZGxpbmsiLCAiYmlydGhkYXRlIiwgIm1vdGhlcl9iaXJ0aGRhdGUiKSkgJT4lIAogIGRpc3RpbmN0KG1vdGhlcl9waWRsaW5rLCBiaXJ0aGRhdGUsIHBpZGxpbmssIC5rZWVwX2FsbCA9IFRSVUUpCgojIyBjaGVjayB3ZXRoZXIgd2UgaGF2ZSBkdXBsaWNhdGVkIGJpcnRoZGF0ZXMsIGJ1dCBub3QgcmVwb3J0ZWQgYXMgdHdpbnMgYmVmb3JlCmFsbGRhdGFfcHJlZ25hbmN5ID0gYWxsZGF0YV9wcmVnbmFuY3kgJT4lIAogIGdyb3VwX2J5KG1vdGhlcl9waWRsaW5rKSAlPiUKICBtdXRhdGUoYW55X211bHRpcGxlX2JpcnRoZGF0ZSA9IGlmX2Vsc2UoYW55KGlmZWxzZSghaXMubmEoYmlydGhfbW9udGgpLCBkdXBsaWNhdGVkKGJpcnRoZGF0ZSksIE5BKSwgbmEucm0gPVQpLCAxLCAwKSkKCmNyb3NzdGFicyh+YWxsZGF0YV9wcmVnbmFuY3kkYW55X211bHRpcGxlX2JpcnRoZGF0ZSArIGFsbGRhdGFfcHJlZ25hbmN5JGFueV9tdWx0aXBsZV9iaXJ0aCkKCiNpZiB3ZSBoYXZlIGR1cGxpY2F0ZWQgYmlydGhkYXRlcyB3aXRoaW4gYSBmYW1pbHksIHdlIGhhdmUgdG8gZXhjbHVkZSB0aGVzZSBmYW1pbGllcywgdG9vIChwcm9iYWJseSB0d2lucykKYWxsZGF0YV9wcmVnbmFuY3kgPSBhbGxkYXRhX3ByZWduYW5jeSAlPiUgbXV0YXRlKGFueV9tdWx0aXBsZV9iaXJ0aCA9IGlmZWxzZShhbnlfbXVsdGlwbGVfYmlydGhkYXRlID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW55X211bHRpcGxlX2JpcnRoKSkKYWxsZGF0YV9wcmVnbmFuY3kgPSBhbGxkYXRhX3ByZWduYW5jeSAlPiUgZ3JvdXBfYnkobW90aGVyX3BpZGxpbmspICU+JSAKICBtdXRhdGUoYmlydGhvcmRlcl9uYWl2ZSA9IG1pbl9yYW5rKGlmX2Vsc2UoIWlzLm5hKG1vdGhlcl9waWRsaW5rKSwgYmlydGhkYXRlLCBOQV9jaGFyYWN0ZXJfKSksCiAgICAgICAgIHNpYmxpbmdfY291bnRfbmFpdmUgPSBpZl9lbHNlKCFpcy5uYShtb3RoZXJfcGlkbGluayksIG4oKSwgTkFfaW50ZWdlcl8pKSAlPiUgCiAgdW5ncm91cCgpCgpgYGAKCgojIyBJbnRlbGxpZ2VuY2Ugey50YWJzZXR9CkNhbGN1bGF0ZSBnIGZhY3RvciBmb3IgaW50ZWxsaWdlbmNlCmBgYHtyIHNlbGVjdCBJUSBkYXRhfQojIyMgSVEgSW5mb3JtYXRpb25zIGZyb20gd2F2ZSA1ICgyMDE0KQojI2VrMiAoPjE0eXJzLCBpbmNsdWRlcyBvbmx5IGluZGl2aWR1YWxzLCB0aGF0IGFyZSAxNSB5ZWFycyBvciBvbGRlcikKaXEyLjEgPSBla19lazIgJT4lIHNlbGVjdChoaGlkMTRfOSwgcGlkbGluaywgYWdlLCBzZXgsIGVrdHlwZSwgcmVzcHR5cGUsIHJlc3VsdCwgcmVhc29uLCBlazFfYW5zLCBlazJfYW5zLCBlazNfYW5zLCBlazRfYW5zLCBlazVfYW5zLCBlazZfYW5zLCBlazdfYW5zLCBlazhfYW5zLCBlazlfYW5zLCBlazEwX2FucywgZWsxMV9hbnMsIGVrMTJfYW5zLCBlazEzX2FucywgZWsxNF9hbnMsIGVrMTVfYW5zLCBlazE2X2FucywgZWsxN19hbnMsIGVrMThfYW5zLCBlazE5X2FucywgZWsyMF9hbnMsIGVrMjFfYW5zLCBlazIyX2FucykKCiMjZWsyICg8MTR5cnMsIGluY2x1ZGVzIGFsbCBpbmRpdmlkdWFscywgdGhhdCBhcmUgeW91bmdlciB0aGFuIDE1IHllYXJzIG9sZCkKaXEzLjEgPSBla19lazEgJT4lIHNlbGVjdChoaGlkMTRfOSwgcGlkbGluaywgYWdlLCBzZXgsIGVrdHlwZSwgcmVzcHR5cGUsIHJlc3VsdCwgcmVhc29uLCBlazFfYW5zLCBlazJfYW5zLCBlazNfYW5zLCBlazRfYW5zLCBlazVfYW5zLCBlazZfYW5zLCBlazdfYW5zLCBlazhfYW5zLCBlazlfYW5zLCBlazEwX2FucywgZWsxMV9hbnMsIGVrMTJfYW5zLCBlazEzX2FucywgZWsxNF9hbnMsIGVrMTVfYW5zLCBlazE2X2FucywgZWsxN19hbnMsIGVrMThfYW5zLCBlazE5X2FucywgZWsyMF9hbnMsIGVrMjFfYW5zLCBlazIyX2FucykKCiMjIyMgUmF2ZW4gVGVzdCAod2F2ZSAyMDE1LCB5b3VuZ2VyIHRoYW4gMTUgeWVhcnMpCmFuc3dlcmVkX3JhdmVuX2l0ZW1zID0gaXEzLjEgJT4lIHNlbGVjdChlazFfYW5zOmVrMTJfYW5zKQpwc3ljaDo6YWxwaGEoZGF0YS5mcmFtZShhbnN3ZXJlZF9yYXZlbl9pdGVtcykpCmlxMy4xJHJhdmVuXzIwMTVfeW91bmcgPSByb3dNZWFucyggYW5zd2VyZWRfcmF2ZW5faXRlbXMsIG5hLnJtID0gVCkKcXBsb3QoaXEzLjEkcmF2ZW5fMjAxNV95b3VuZykKCiMjIyMgTWF0aCBUZXN0ICh3YXZlIDIwMTUsIHlvdW5nZXIgdGhhbiAxNSB5ZWFycykKYW5zd2VyZWRfbWF0aF9pdGVtcyA9IGlxMy4xICU+JSBzZWxlY3QoZWsxM19hbnM6ZWsxN19hbnMpCnBzeWNoOjphbHBoYShkYXRhLmZyYW1lKGFuc3dlcmVkX21hdGhfaXRlbXMpKQppcTMuMSRtYXRoXzIwMTVfeW91bmcgPSByb3dNZWFucyggYW5zd2VyZWRfbWF0aF9pdGVtcywgbmEucm0gPSBUKQpxcGxvdChpcTMuMSRtYXRoXzIwMTVfeW91bmcpCgppcTMuMSA9IGlxMy4xICU+JSBzZWxlY3QocGlkbGluaywgYWdlXzIwMTVfeW91bmcgPSBhZ2UsIHNleF8yMDE1X3lvdW5nID0gc2V4LAogICAgICAgICAgICAgICAgICAgICAgICAgcmF2ZW5fMjAxNV95b3VuZywgbWF0aF8yMDE1X3lvdW5nLCByZWFzb25fMjAxNV95b3VuZyA9IHJlYXNvbikKCiMjYWRkaXRpb25hbCBpbmZvcm1hdGlvbnMgZm9yIGFkdWx0czogY291bnRpbmcgYmFja3dhcmRzCmlxMi4yID0gYjNiX2NvMSAlPiUgc2VsZWN0KGhoaWQxNF85LCBwaWRsaW5rLCBjbzA0YSwgY28wNGIsIGNvMDRjLCBjbzA0ZCwgY28wNGUsIGNvMDdjb3VudCwgY28xMGNvdW50KQojI2FkZGl0aW9uYWwgaW5mb3JtYXRpb25zIGZvciBhZHVsdHM6IGFkYXB0aXZlIG51bWJlciB0ZXN0CmlxMi4zID0gYjNiX2NvYiAlPiUgc2VsZWN0KGhoaWQxNF85LCBwaWRsaW5rLCB3X2FiaWwsIGNvYjE4LCBjb2IxOWIpCgojIyBwdXQgYWxsIHRoZSBpbmZvcm1hdGlvbnMgZm9yIHBhcnRpY2lwYW50cyA+PSAxNSB0b2dldGhlcgppcTIgPSBmdWxsX2pvaW4oaXEyLjEsIGlxMi4yLCBieSA9ICJwaWRsaW5rIikKaXEyID0gZnVsbF9qb2luKGlxMiwgaXEyLjMsIGJ5ID0gInBpZGxpbmsiKQppcSA9IGlxMgppcSA8LSByZW5hbWUoaXEsIGFnZV8yMDE1X29sZCA9IGFnZSwgcmVhc29uXzIwMTVfb2xkID0gcmVhc29uLCBzZXhfMjAxNV9vbGQgPSBzZXgpIAppcSA9IGZ1bGxfam9pbihpcSwgaXEzLjEsIGJ5ID0gInBpZGxpbmsiKQoKIyMjIGNhbGN1bGF0ZSBpcSBzY29yZXMKIyNSYXZlbiBUZXN0ICh3YXZlIDIwMTUsIG9sZGVyIHRoYW4gMTQgeWVhcnMpCmFuc3dlcmVkX3JhdmVuX2l0ZW1zID0gaXEgJT4lIHNlbGVjdChlazFfYW5zOmVrNl9hbnMsIGVrMTFfYW5zLCBlazEyX2FucykKcHN5Y2g6OmFscGhhKGRhdGEuZnJhbWUoYW5zd2VyZWRfcmF2ZW5faXRlbXMpKQppcSRyYXZlbl8yMDE1X29sZCA9IHJvd01lYW5zKCBhbnN3ZXJlZF9yYXZlbl9pdGVtcywgbmEucm0gPSBUKQpxcGxvdChpcSRyYXZlbl8yMDE1X29sZCkKCiMjTWF0aCBUZXN0ICh3YXZlIDIwMTUsIG9sZGVyIHRoYW4gMTQgeWVhcnMpCmFuc3dlcmVkX21hdGhfaXRlbXMgPSBpcSAlPiUgc2VsZWN0KGVrMThfYW5zOmVrMjJfYW5zKQpwc3ljaDo6YWxwaGEoZGF0YS5mcmFtZShhbnN3ZXJlZF9tYXRoX2l0ZW1zKSkKaXEkbWF0aF8yMDE1X29sZCA9IHJvd01lYW5zKCBhbnN3ZXJlZF9tYXRoX2l0ZW1zLCBuYS5ybSA9IFQpCnFwbG90KGlxJG1hdGhfMjAxNV9vbGQpCgoKIyNDb3VudGluZyBJdGVtcwojIENyZWF0ZSBSaWdodC9Xcm9uZyBTY29yZXMgZm9yIHRoZSBjb3VudGluZyBpdGVtcwppcSRjbzA0YXJpZ2h0ID0gYXMubnVtZXJpYyhpcSRjbzA0YSA9PSA5MykKaXEkY28wNGJyaWdodCA9IGFzLm51bWVyaWMoaXEkY28wNGIgPT0gaXEkY28wNGEtNykKaXEkY28wNGNyaWdodCA9IGFzLm51bWVyaWMoaXEkY28wNGMgPT0gaXEkY28wNGItNykKaXEkY28wNGRyaWdodCA9IGFzLm51bWVyaWMoaXEkY28wNGQgPT0gaXEkY28wNGMtNykKaXEkY28wNGVyaWdodCA9IGFzLm51bWVyaWMoaXEkY28wNGUgPT0gaXEkY28wNGQtNykKCmFuc3dlcmVkX2NvdW50aW5nX2l0ZW1zID0gaXEgJT4lIHNlbGVjdChjbzA0YXJpZ2h0OmNvMDRlcmlnaHQpCnBzeWNoOjphbHBoYShkYXRhLmZyYW1lKGFuc3dlcmVkX2NvdW50aW5nX2l0ZW1zKSkKaXEkY291bnRfYmFja3dhcmRzID0gcm93TWVhbnMoIGFuc3dlcmVkX2NvdW50aW5nX2l0ZW1zLCBuYS5ybSA9IFQpCnFwbG90KGlxJGNvdW50X2JhY2t3YXJkcykKCiMjIFdvcmQgTWVtb3J5CmlxJHdvcmRzX2ltbWVkaWF0ZSA9IGlxJGNvMDdjb3VudAppcSR3b3Jkc19kZWxheWVkID0gaXEkY28xMGNvdW50CnFwbG90KGlxJHdvcmRzX2ltbWVkaWF0ZSwgaXEkd29yZHNfZGVsYXllZCwgZ2VvbSA9ICJqaXR0ZXIiKQphbnN3ZXJlZF93b3JkX2l0ZW1zID0gaXEgJT4lIHNlbGVjdChjbzA3Y291bnQsY28xMGNvdW50KQpwc3ljaDo6YWxwaGEoZGF0YS5mcmFtZShhbnN3ZXJlZF93b3JkX2l0ZW1zKSkKaXEkd29yZHNfcmVtZW1iZXJlZF9hdmcgPSByb3dNZWFucyggYW5zd2VyZWRfd29yZF9pdGVtcywgbmEucm0gPSBUKQpxcGxvdChpcSR3b3Jkc19yZW1lbWJlcmVkX2F2ZykKCiMjQWRhcHRpdmUgTnVtYmVyaW5nCmlxJGFkYXB0aXZlX251bWJlcmluZyA9IGlxJHdfYWJpbApxcGxvdChpcSRhZGFwdGl2ZV9udW1iZXJpbmcpCgoKIyBzb21lIHBlb3BsZSBoYXZlIHJlYXNvbnMgbm90IHRvIGFuc3dlciB0aGUgdGVzdCAoZGVhZCwgbm90IGNvbnRhY3RlZCksIHRoYXQgZG9udCBqdXN0aWZ5CiMgZ2l2aW5nIHRoZW0gemVybyBwb2ludHMgZm9yIHRoYXQgdGFzay4gc28gaSBzZXQgdGhlc2UgdG8gTkEKIyBhZGRpdGlvbmFsbHkgYWxsIHBhcnRpY2lwYW50cyBvbGRlciB0aGFuIDU5IG9ubHkgYW5zd2VyZWQgdGhlIFJhdmVuIFRlc3QsIG5vdCB0aGUgTWF0aCAKIyBUZXN0CmlxID0gaXEgJT4lCiAgbXV0YXRlKHJlYXNvbl8yMDE1X3lvdW5nID0gaWZlbHNlKHJlYXNvbl8yMDE1X3lvdW5nID09IDEsICJyZWZ1c2VkIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAxNV95b3VuZyA9PSAyLCAiY2Fubm90IHJlYWQiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X3lvdW5nID09IDMsICJ1bmFibGUgdG8gYW5zd2VyIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAxNV95b3VuZyA9PSA0LCAibm90IGVub3VnaCB0aW1lIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAxNV95b3VuZyA9PSA1LCAicHJveHkgcmVzcG9uZGVudCIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMTVfeW91bmcgPT0gNiwgIm90aGVyIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAxNV95b3VuZyA9PSA3LCAiY291bGQgbm90IGJlIGNvbnRhY3RlZCIsIE5BKSkpKSkpKSwKICAgICAgICAgcmF2ZW5fMjAxNV95b3VuZyA9IGlmZWxzZShpcy5uYShyZWFzb25fMjAxNV95b3VuZyksIHJhdmVuXzIwMTVfeW91bmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X3lvdW5nID09ICJjYW5ub3QgcmVhZCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJub3QgZW5vdWdoIHRpbWUifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAxNV95b3VuZyA9PSAicHJveHkgcmVzcG9uZGVudCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJvdGhlciJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJyZWZ1c2VkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMTVfeW91bmcgPT0gImNvdWxkIG5vdCBiZSBjb250YWN0ZWQiLCBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF2ZW5fMjAxNV95b3VuZykpLAogICAgICAgICBtYXRoXzIwMTVfeW91bmcgPSBpZmVsc2UoaXMubmEocmVhc29uXzIwMTVfeW91bmcpLCBtYXRoXzIwMTVfeW91bmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X3lvdW5nID09ICJjYW5ub3QgcmVhZCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJub3QgZW5vdWdoIHRpbWUifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAxNV95b3VuZyA9PSAicHJveHkgcmVzcG9uZGVudCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJvdGhlciJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X3lvdW5nID09ICJyZWZ1c2VkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMTVfeW91bmcgPT0gImNvdWxkIG5vdCBiZSBjb250YWN0ZWQiLCBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0aF8yMDE1X3lvdW5nKSksCiAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9IGlmZWxzZShyZWFzb25fMjAxNV9vbGQgPT0gMSwgInJlZnVzZWQiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X29sZCA9PSAyLCAiY2Fubm90IHJlYWQiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X29sZCA9PSAzLCAidW5hYmxlIHRvIGFuc3dlciIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMTVfb2xkID09IDQsICJub3QgZW5vdWdoIHRpbWUiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X29sZCA9PSA1LCAicHJveHkgcmVzcG9uZGVudCIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMTVfb2xkID09IDYsICJvdGhlciIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMTVfb2xkID09IDcsICJjb3VsZCBub3QgYmUgY29udGFjdGVkIiwgTkEpKSkpKSkpLAogICAgICAgICByYXZlbl8yMDE1X29sZCA9IGlmZWxzZShpcy5uYShyZWFzb25fMjAxNV9vbGQpLCByYXZlbl8yMDE1X29sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMTVfb2xkID09ICJjYW5ub3QgcmVhZCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9PSAibm90IGVub3VnaCB0aW1lInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMTVfb2xkID09ICJwcm94eSByZXNwb25kZW50InwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMTVfb2xkID09ICJvdGhlciJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9PSAicmVmdXNlZCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9PSAiY291bGQgbm90IGJlIGNvbnRhY3RlZCIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXZlbl8yMDE1X29sZCkpLAogICAgICAgICBtYXRoXzIwMTVfb2xkID0gaWZlbHNlKGlzLm5hKHJlYXNvbl8yMDE1X29sZCksIG1hdGhfMjAxNV9vbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDE1X29sZCA9PSAiY2Fubm90IHJlYWQifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAxNV9vbGQgPT0gIm5vdCBlbm91Z2ggdGltZSJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9PSAicHJveHkgcmVzcG9uZGVudCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDE1X29sZCA9PSAib3RoZXIifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAxNV9vbGQgPT0gInJlZnVzZWQifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAxNV9vbGQgPT0gImNvdWxkIG5vdCBiZSBjb250YWN0ZWQiLCBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0aF8yMDE1X29sZCkpLAogICAgICAgICBtYXRoXzIwMTVfb2xkID0gaWZlbHNlKGFnZV8yMDE1X29sZCA+PSA2MCwgTkEsIG1hdGhfMjAxNV9vbGQpKQoKaXEgJT4lIHNlbGVjdChyYXZlbl8yMDE1X29sZCwgbWF0aF8yMDE1X29sZCwgcmF2ZW5fMjAxNV95b3VuZywgbWF0aF8yMDE1X3lvdW5nLCBjb3VudF9iYWNrd2FyZHMsIHdvcmRzX2ltbWVkaWF0ZSwgd29yZHNfZGVsYXllZCwgYWRhcHRpdmVfbnVtYmVyaW5nKSAlPiUgdGlkeXI6OmdhdGhlcigpICU+JQogIGdncGxvdChhZXModmFsdWUpKSArIGdlb21fYmFyKCkgKyBmYWNldF93cmFwKH4ga2V5LCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKIyMjIEludGVsbGlnZW5jZSBmcm9tIGVhcmxpZXIgd2F2ZXMKYGBge3IgSW50ZWxsaWdlbmNlIGVhcmxpZXIgd2F2ZXN9CiMjIFdhdmUgNCAtIDIwMDcKIyMjIERhdGEKaXEyMDA3X2VrMj0gYmVrX2VrMiAlPiUKICBzZWxlY3QocGlkbGluaywgZWt0eXBlLCByZWFzb25fMjAwN19vbGQgPSByZWFzb24sICJhZ2VfMjAwN19vbGQiID0gYWdlLAogICAgICAgICBzZXhfMjAwN19vbGQgPSBzZXgsIG1hdGNoZXMoImVrWzAtOV14IiksIG1hdGNoZXMoImVrWzAtOV1bMC05XXgiKSkKCmlxMjAwN19lazE9IGJla19lazEgJT4lCiAgc2VsZWN0KHBpZGxpbmssIGVrdHlwZSwgcmVhc29uXzIwMDdfeW91bmcgPSByZWFzb24sICJhZ2VfMjAwN195b3VuZyIgPSBhZ2UsCiAgICAgICAgIHNleF8yMDA3X3lvdW5nID0gc2V4LCBtYXRjaGVzKCJla1swLTldeCIpLCBtYXRjaGVzKCJla1swLTldWzAtOV14IikpICU+JQogIGZpbHRlcighKHBpZGxpbmsgJWluJSBpcTIwMDdfZWsyJHBpZGxpbmspKQoKIyBzb21lIHBlb3BsZSBhbnN3ZXJlZCBib3RoIHZlcnNpb25zIG9mIHRoZSB0ZXN0CiMgKGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZXkgaGFkIHNlZW4gdGVzdCBlazEgYWxyZWFkeSBpbiAyMDAwKQojIEluIG9yZGVyIHRvIGRlYWwgd2l0aCB0aGVtIGkgZm9ybSBhbiBhZGRpdGlvbmFsIGRhdGFzZXQgdGhhdCBpbmNsdWRlcyB0aGUgaW5mb3JtYXRpb24gZnJvbQojIHRoZSBwZW9wbGUgdGhhdCByZXBlYXRlZCB0aGUgZmlyc3QgdGVzdCBhbmQgdGhlaXIgc2NvcmUgb24gdGhlIGZpcnN0IHRlc3QgaW4gMjAwNwojIHRoYXQgbWVhbnMgdGhleSBoYXZlIGFscmVhZHkgc2VlbiB0aGUgdGVzdCA3IHllYXJzIGJlZm9yZS4uLgojIGkgbWVyZ2UgdGhpcyBkYXRhIGxhdGVyIGluIHRoZSBzYW1lIGNvbHVtbiBhcyB0aGUgb3RoZXIgc2NvcmVzIGluIDIwMDcgaW4gdGhlIGZpcnN0IHRlc3QKIyBjaGVjayB3aXRoIFJ1YmVuLCBpZiB0aGF0IGlzIHRoZSByaWdodCB3YXkgdG8gZ28uLi4KCmlxMjAwN19lazFfcmVwZWF0ZXIgPSBiZWtfZWsxICU+JQogIHNlbGVjdChwaWRsaW5rLCBla3R5cGUsIHJlYXNvbl8yMDA3X3lvdW5nX3JlcGVhdGVyID0gcmVhc29uLAogICAgICAgICAiYWdlXzIwMDdfeW91bmdfcmVwZWF0ZXIiID0gYWdlLCBzZXhfMjAwN195b3VuZ19yZXBlYXRlciA9IHNleCwKICAgICAgICAgbWF0Y2hlcygiZWtbMC05XXgiKSwgbWF0Y2hlcygiZWtbMC05XVswLTldeCIpKSAlPiUKICBmaWx0ZXIoKHBpZGxpbmsgJWluJSBpcTIwMDdfZWsyJHBpZGxpbmspKQoKaXEyMDA3ID0gYmluZF9yb3dzKGlxMjAwN19lazEsIGlxMjAwN19lazIpIAoKIyMjIFJhdmVuCmlxMjAwNyA9IGlxMjAwNyAlPiUKICBtdXRhdGUoZWsxeCA9IGlmZWxzZShlazF4ID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMXggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsyeCA9IGlmZWxzZShlazJ4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazJ4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrM3ggPSBpZmVsc2UoZWszeCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWszeCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazR4ID0gaWZlbHNlKGVrNHggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrNHggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWs1eCA9IGlmZWxzZShlazV4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazV4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrNnggPSBpZmVsc2UoZWs2eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWs2eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazd4ID0gaWZlbHNlKGVrN3ggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrN3ggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWs4eCA9IGlmZWxzZShlazh4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazh4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrOXggPSBpZmVsc2UoZWs5eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWs5eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazEweCA9IGlmZWxzZShlazEweCA9PSAxLCAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazEweCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazExeCA9IGlmZWxzZShlazExeCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxMXggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsxMnggPSBpZmVsc2UoZWsxMnggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTJ4ID09IDYsIE5BLCAwKSkpCgphbnN3ZXJlZF9yYXZlbl9pdGVtcyA9IGlxMjAwNyAlPiUgc2VsZWN0KGVrMXg6ZWsxMngpCnBzeWNoOjphbHBoYShkYXRhLmZyYW1lKGFuc3dlcmVkX3JhdmVuX2l0ZW1zKSkKaXEyMDA3JHJhdmVuMjAwNyA9IHJvd01lYW5zKGFuc3dlcmVkX3JhdmVuX2l0ZW1zLCBuYS5ybSA9IFQpCmlxMjAwNyA9IGlxMjAwNyAlPiUKICBtdXRhdGUocmF2ZW5fMjAwN195b3VuZyA9IGlmZWxzZShla3R5cGUgPT0gMSwgcmF2ZW4yMDA3LCBOQSksCiAgICAgICAgIHJhdmVuXzIwMDdfb2xkID0gaWZlbHNlKGVrdHlwZSA9PSAyLCByYXZlbjIwMDcsIE5BKSkKcXBsb3QoaXEyMDA3JHJhdmVuXzIwMDdfeW91bmcpCnFwbG90KGlxMjAwNyRyYXZlbl8yMDA3X29sZCkKCgojI01hdGggVGVzdAppcTIwMDcgPSBpcTIwMDcgJT4lCiAgbXV0YXRlKGVrMTN4ID0gaWZlbHNlKGVrMTN4ID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTN4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTR4ID0gaWZlbHNlKGVrMTR4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazE0eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazE1eCA9IGlmZWxzZShlazE1eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxNXggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsxNnggPSBpZmVsc2UoZWsxNnggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTZ4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTd4ID0gaWZlbHNlKGVrMTd4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazE3eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazE4eCA9IGlmZWxzZShlazE4eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxOHggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsxOXggPSBpZmVsc2UoZWsxOXggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTl4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMjB4ID0gaWZlbHNlKGVrMjB4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazIweCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazIxeCA9IGlmZWxzZShlazIxeCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsyMXggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsyMnggPSBpZmVsc2UoZWsyMnggPT0gMSwgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsyMnggPT0gNiwgTkEsIDApKSkKCmFuc3dlcmVkX21hdGhfaXRlbXMgPSBpcTIwMDcgJT4lIHNlbGVjdChlazEzeDplazIyeCkKaXEyMDA3JG1hdGgyMDA3ID0gcm93TWVhbnMoIGFuc3dlcmVkX21hdGhfaXRlbXMsIG5hLnJtID0gVCkKaXEyMDA3ID0gaXEyMDA3ICU+JQogIG11dGF0ZShtYXRoXzIwMDdfeW91bmcgPSBpZmVsc2UoZWt0eXBlID09IDEsIG1hdGgyMDA3LCBOQSksCiAgICAgICAgIG1hdGhfMjAwN19vbGQgPSBpZmVsc2UoZWt0eXBlID09IDIsIG1hdGgyMDA3LCBOQSkpCnFwbG90KGlxMjAwNyRtYXRoXzIwMDdfeW91bmcpCnFwbG90KGlxMjAwNyRtYXRoXzIwMDdfb2xkKQoKCmlxMjAwNyA9IGlxMjAwNyAlPiUgc2VsZWN0KHBpZGxpbmssIGFnZV8yMDA3X3lvdW5nLCBhZ2VfMjAwN19vbGQsIHNleF8yMDA3X3lvdW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXhfMjAwN19vbGQsIHJhdmVuXzIwMDdfeW91bmcsIHJhdmVuXzIwMDdfb2xkLCBtYXRoXzIwMDdfeW91bmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGhfMjAwN19vbGQsIHJlYXNvbl8yMDA3X29sZCwgcmVhc29uXzIwMDdfeW91bmcpCgojI0RvIHRoZSBzYW1lIGZvciB0aGUgcmVwZWF0ZXIKIyMjIFJhdmVuCmlxMjAwN19lazFfcmVwZWF0ZXIgPSBpcTIwMDdfZWsxX3JlcGVhdGVyICU+JQogIG11dGF0ZShlazF4ID0gaWZlbHNlKGVrMXggPT0gMSwgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxeCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazJ4ID0gaWZlbHNlKGVrMnggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMnggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWszeCA9IGlmZWxzZShlazN4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazN4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrNHggPSBpZmVsc2UoZWs0eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWs0eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazV4ID0gaWZlbHNlKGVrNXggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrNXggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWs2eCA9IGlmZWxzZShlazZ4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazZ4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrN3ggPSBpZmVsc2UoZWs3eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWs3eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazh4ID0gaWZlbHNlKGVrOHggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrOHggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWs5eCA9IGlmZWxzZShlazl4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazl4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTB4ID0gaWZlbHNlKGVrMTB4ID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTB4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTF4ID0gaWZlbHNlKGVrMTF4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazExeCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazEyeCA9IGlmZWxzZShlazEyeCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxMnggPT0gNiwgTkEsIDApKSkKCmFuc3dlcmVkX3JhdmVuX2l0ZW1zID0gaXEyMDA3X2VrMV9yZXBlYXRlciAlPiUgc2VsZWN0KGVrMXg6ZWsxMngpCnBzeWNoOjphbHBoYShkYXRhLmZyYW1lKGFuc3dlcmVkX3JhdmVuX2l0ZW1zKSkKaXEyMDA3X2VrMV9yZXBlYXRlciRyYXZlbl8yMDA3X3lvdW5nX3JlcGVhdGVyID0gcm93TWVhbnMoYW5zd2VyZWRfcmF2ZW5faXRlbXMsIG5hLnJtID0gVCkKcXBsb3QoaXEyMDA3X2VrMV9yZXBlYXRlciRyYXZlbl8yMDA3X3lvdW5nX3JlcGVhdGVyKQoKCiMjTWF0aCBUZXN0CmlxMjAwN19lazFfcmVwZWF0ZXIgPSBpcTIwMDdfZWsxX3JlcGVhdGVyICU+JQogIG11dGF0ZShlazEzeCA9IGlmZWxzZShlazEzeCA9PSAxLCAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazEzeCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazE0eCA9IGlmZWxzZShlazE0eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxNHggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsxNXggPSBpZmVsc2UoZWsxNXggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTV4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTZ4ID0gaWZlbHNlKGVrMTZ4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazE2eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazE3eCA9IGlmZWxzZShlazE3eCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsxN3ggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsxOHggPSBpZmVsc2UoZWsxOHggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMTh4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMTl4ID0gaWZlbHNlKGVrMTl4ID09IDEsICAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlazE5eCA9PSA2LCBOQSwgMCkpLAogICAgICAgICBlazIweCA9IGlmZWxzZShlazIweCA9PSAxLCAgMSwKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZWsyMHggPT0gNiwgTkEsIDApKSwKICAgICAgICAgZWsyMXggPSBpZmVsc2UoZWsyMXggPT0gMSwgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMjF4ID09IDYsIE5BLCAwKSksCiAgICAgICAgIGVrMjJ4ID0gaWZlbHNlKGVrMjJ4ID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGVrMjJ4ID09IDYsIE5BLCAwKSkpCgphbnN3ZXJlZF9tYXRoX2l0ZW1zID0gaXEyMDA3X2VrMV9yZXBlYXRlciAlPiUgc2VsZWN0KGVrMTN4OmVrMjJ4KQppcTIwMDdfZWsxX3JlcGVhdGVyJG1hdGhfMjAwN195b3VuZ19yZXBlYXRlciA9IHJvd01lYW5zKCBhbnN3ZXJlZF9tYXRoX2l0ZW1zLCBuYS5ybSA9IFQpCnFwbG90KGlxMjAwN19lazFfcmVwZWF0ZXIkbWF0aF8yMDA3X3lvdW5nX3JlcGVhdGVyKQoKaXEyMDA3X2VrMV9yZXBlYXRlciA9IGlxMjAwN19lazFfcmVwZWF0ZXIgJT4lCiAgc2VsZWN0KHBpZGxpbmssIHJhdmVuXzIwMDdfeW91bmdfcmVwZWF0ZXIsIG1hdGhfMjAwN195b3VuZ19yZXBlYXRlciwKICAgICAgICAgcmVhc29uXzIwMDdfeW91bmdfcmVwZWF0ZXIsIGFnZV8yMDA3X3lvdW5nX3JlcGVhdGVyLCBzZXhfMjAwN195b3VuZ19yZXBlYXRlcikKCmlxMjAwN19hbGwgPSBsZWZ0X2pvaW4oaXEyMDA3LCBpcTIwMDdfZWsxX3JlcGVhdGVyLCBieSA9ICJwaWRsaW5rIikKCiMgTm93IHdlIGluc3RlcnQgcmF2ZW4gYW5kIG1hdGggc2NvcmVzIGZyb20gdGhlIHJlcGVhdGVycyBhcyByYXZlbiBhbmQgbWF0aCBzY29yZXMgeW91bmcKIyBUcmVhdCB0aGVtIGxpa2UgYWxsIHRoZSBvdGhlcnMuCmNyb3NzdGFicyhpcy5uYShpcTIwMDdfYWxsJHJhdmVuXzIwMDdfeW91bmcpICsgaXMubmEoaXEyMDA3X2FsbCRyYXZlbl8yMDA3X3lvdW5nX3JlcGVhdGVyKSkKCmlxMjAwN19hbGwgPSBpcTIwMDdfYWxsICU+JQogIG11dGF0ZShyYXZlbl8yMDA3X3lvdW5nID0gaWZlbHNlKCFpcy5uYShyYXZlbl8yMDA3X3lvdW5nX3JlcGVhdGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXZlbl8yMDA3X3lvdW5nX3JlcGVhdGVyLCByYXZlbl8yMDA3X3lvdW5nKSwKICAgICAgICAgbWF0aF8yMDA3X3lvdW5nID0gaWZlbHNlKCFpcy5uYShtYXRoXzIwMDdfeW91bmdfcmVwZWF0ZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0aF8yMDA3X3lvdW5nX3JlcGVhdGVyLCBtYXRoXzIwMDdfeW91bmcpLAogICAgICAgICBhZ2VfMjAwN195b3VuZyA9IGlmZWxzZSghaXMubmEoYWdlXzIwMDdfeW91bmdfcmVwZWF0ZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VfMjAwN195b3VuZ19yZXBlYXRlciwgYWdlXzIwMDdfeW91bmcpLAogICAgICAgICBzZXhfMjAwN195b3VuZyA9IGlmZWxzZSghaXMubmEoc2V4XzIwMDdfeW91bmdfcmVwZWF0ZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXhfMjAwN195b3VuZ19yZXBlYXRlciwgc2V4XzIwMDdfeW91bmcpKQoKaXEyMDA3X2FsbCA9IGlxMjAwN19hbGwgJT4lIHNlbGVjdChwaWRsaW5rLCBhZ2VfMjAwN195b3VuZywgYWdlXzIwMDdfb2xkLCByYXZlbl8yMDA3X29sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXZlbl8yMDA3X3lvdW5nLCBtYXRoXzIwMDdfeW91bmcsIG1hdGhfMjAwN19vbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcsIHJlYXNvbl8yMDA3X29sZCkKCiMgc29tZSBwZW9wbGUgaGF2ZSByZWFzb25zIG5vdCB0byBhbnN3ZXIgdGhlIHRlc3QgKGRlYWQsIG5vdCBjb250YWN0ZWQpLCB0aGF0IGRvbnQganVzdGlmeQojIGdpdmluZyB0aGVtIHplcm8gcG9pbnRzIGZvciB0aGF0IHRhc2suIHNvIGkgc2V0IHRoZXNlIHRvIE5BCiMgaXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCByYXZlbiBhbmQgbWF0aCB0ZXN0IHdlcmUgb25seSBhbnN3ZXJlZCBieSBwYXJ0aWNpcGFudHMKIyBhZ2VkIDcgLSAyNAppcTIwMDdfYWxsID0gaXEyMDA3X2FsbCAlPiUKICBtdXRhdGUocmVhc29uXzIwMDdfeW91bmcgPSBpZmVsc2UocmVhc29uXzIwMDdfeW91bmcgPT0gMSwgInJlZnVzZWQiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDA3X3lvdW5nID09IDIsICJjYW5ub3QgcmVhZCIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfeW91bmcgPT0gMywgInVuYWJsZSB0byBhbnN3ZXIiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDA3X3lvdW5nID09IDQsICJub3QgZW5vdWdoIHRpbWUiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDA3X3lvdW5nID09IDUsICJwcm94eSByZXNwb25kZW50IiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAwN195b3VuZyA9PSA2LCAib3RoZXIiLAogICAgICAgICAgICAgICAgICAgaWZlbHNlKHJlYXNvbl8yMDA3X3lvdW5nID09IDcsICJjb3VsZCBub3QgYmUgY29udGFjdGVkIiwgTkEpKSkpKSkpLAogICAgICAgICByYXZlbl8yMDA3X3lvdW5nID0gaWZlbHNlKGlzLm5hKHJlYXNvbl8yMDA3X3lvdW5nKSwgcmF2ZW5fMjAwN195b3VuZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfeW91bmcgPT0gImNhbm5vdCByZWFkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gIm5vdCBlbm91Z2ggdGltZSJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDA3X3lvdW5nID09ICJwcm94eSByZXNwb25kZW50InwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gIm90aGVyInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gInJlZnVzZWQifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAwN195b3VuZyA9PSAiY291bGQgbm90IGJlIGNvbnRhY3RlZCIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXZlbl8yMDA3X3lvdW5nKSksCiAgICAgICAgIG1hdGhfMjAwN195b3VuZyA9IGlmZWxzZShpcy5uYShyZWFzb25fMjAwN195b3VuZyksIG1hdGhfMjAwN195b3VuZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfeW91bmcgPT0gImNhbm5vdCByZWFkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gIm5vdCBlbm91Z2ggdGltZSJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDA3X3lvdW5nID09ICJwcm94eSByZXNwb25kZW50InwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gIm90aGVyInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfeW91bmcgPT0gInJlZnVzZWQifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAwN195b3VuZyA9PSAiY291bGQgbm90IGJlIGNvbnRhY3RlZCIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRoXzIwMDdfeW91bmcpKSwKICAgICAgICAgcmVhc29uXzIwMDdfb2xkID0gaWZlbHNlKHJlYXNvbl8yMDA3X29sZCA9PSAxLCAicmVmdXNlZCIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfb2xkID09IDIsICJjYW5ub3QgcmVhZCIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfb2xkID09IDMsICJ1bmFibGUgdG8gYW5zd2VyIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAwN19vbGQgPT0gNCwgIm5vdCBlbm91Z2ggdGltZSIsCiAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfb2xkID09IDUsICJwcm94eSByZXNwb25kZW50IiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAwN19vbGQgPT0gNiwgIm90aGVyIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAwN19vbGQgPT0gNywgImNvdWxkIG5vdCBiZSBjb250YWN0ZWQiLCBOQSkpKSkpKSksCiAgICAgICAgIHJhdmVuXzIwMDdfb2xkID0gaWZlbHNlKGlzLm5hKHJlYXNvbl8yMDA3X29sZCksIHJhdmVuXzIwMDdfb2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyZWFzb25fMjAwN19vbGQgPT0gImNhbm5vdCByZWFkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJub3QgZW5vdWdoIHRpbWUifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAwN19vbGQgPT0gInByb3h5IHJlc3BvbmRlbnQifAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25fMjAwN19vbGQgPT0gIm90aGVyInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJyZWZ1c2VkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJjb3VsZCBub3QgYmUgY29udGFjdGVkIiwgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdmVuXzIwMDdfb2xkKSksCiAgICAgICAgIG1hdGhfMjAwN19vbGQgPSBpZmVsc2UoaXMubmEocmVhc29uXzIwMDdfb2xkKSwgbWF0aF8yMDA3X29sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmVhc29uXzIwMDdfb2xkID09ICJjYW5ub3QgcmVhZCJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDA3X29sZCA9PSAibm90IGVub3VnaCB0aW1lInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJwcm94eSByZXNwb25kZW50InwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJvdGhlciJ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbl8yMDA3X3lvdW5nID09ICJyZWZ1c2VkInwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uXzIwMDdfb2xkID09ICJjb3VsZCBub3QgYmUgY29udGFjdGVkIiwgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGhfMjAwN19vbGQpKSkKCmlxMjAwN19hbGwgJT4lIHNlbGVjdChyYXZlbl8yMDA3X29sZCwgbWF0aF8yMDA3X29sZCwgcmF2ZW5fMjAwN195b3VuZywgbWF0aF8yMDA3X3lvdW5nKSAlPiUgdGlkeXI6OmdhdGhlcigpICU+JSAgZ2dwbG90KGFlcyh2YWx1ZSkpICsgZ2VvbV9iYXIoKSArIGZhY2V0X3dyYXAofiBrZXksIHNjYWxlcyA9ICJmcmVlIikKCmlxID0gZnVsbF9qb2luKGlxLCBpcTIwMDdfYWxsLCBieSA9ICJwaWRsaW5rIikgJT4lCiAgc2VsZWN0KC1tYXRjaGVzKCJla1swLTldX2FucyIpLCAtbWF0Y2hlcygiZWtbMC05XVswLTldX2FucyIpLCAtc3RhcnRzX3dpdGgoImhoaWQiKSwKICAgICAgICAgLWVrdHlwZSwgLXJlc3B0eXBlLCAtcmVzdWx0LCAtc3RhcnRzX3dpdGgoInJlYXNvbiIpLCAtc3RhcnRzX3dpdGgoImNvIiksCiAgICAgICAgIGNvdW50X2JhY2t3YXJkcywgLXdfYWJpbCkKYGBgCgojIyMgQ29ycmVsYXRpb25zIGFuZCBNaXNzaW5nbmVzcyBQYXR0ZXJucyBmb3IgSW50ZWxsaWdlbmNlIApgYGB7ciBjb3JyZWxhdGlvbnMgYW5kIG1pc3NpbmduZXNzIHBhdHRlcm5zIG9mIElRfQojIyBJUSBUZXN0cyAKIyMgQ29ycmVsYXRpb24gb2YgYWxsIElxLVRlc3RzCnJvdW5kKGNvcihpcSAlPiUgc2VsZWN0KHJhdmVuXzIwMTVfb2xkLCBtYXRoXzIwMTVfb2xkLCByYXZlbl8yMDE1X3lvdW5nLCBtYXRoXzIwMTVfeW91bmcsIGNvdW50X2JhY2t3YXJkcywgd29yZHNfaW1tZWRpYXRlLCB3b3Jkc19kZWxheWVkLCBhZGFwdGl2ZV9udW1iZXJpbmcsIHJhdmVuXzIwMDdfb2xkLCBtYXRoXzIwMDdfeW91bmcpLCB1c2UgPSAicGFpcndpc2UuY29tcGxldGUub2JzIiksIDIpCgojI01pc3NpbmduZXNzX1BhdHRlcm5zCmZvcm1yOjptaXNzaW5nbmVzc19wYXR0ZXJucyhpcSAlPiUgc2VsZWN0KHJhdmVuXzIwMTVfb2xkLCBtYXRoXzIwMTVfb2xkLCByYXZlbl8yMDE1X3lvdW5nLCBtYXRoXzIwMTVfeW91bmcsIGNvdW50X2JhY2t3YXJkcywgd29yZHNfaW1tZWRpYXRlLCB3b3Jkc19kZWxheWVkLCBhZGFwdGl2ZV9udW1iZXJpbmcsIHJhdmVuXzIwMDdfb2xkLCBtYXRoXzIwMDdfeW91bmcpKQoKaXEgJT4lIHNlbGVjdChyYXZlbl8yMDE1X29sZCwgbWF0aF8yMDE1X29sZCwgcmF2ZW5fMjAxNV95b3VuZywgbWF0aF8yMDE1X3lvdW5nLCByYXZlbl8yMDA3X29sZCwgbWF0aF8yMDA3X29sZCwgcmF2ZW5fMjAwN195b3VuZywgbWF0aF8yMDA3X3lvdW5nLCBjb3VudF9iYWNrd2FyZHMsIHdvcmRzX2ltbWVkaWF0ZSwgd29yZHNfZGVsYXllZCwgYWRhcHRpdmVfbnVtYmVyaW5nKSAlPiUgdGlkeXI6OmdhdGhlcigpICU+JQogIGdncGxvdChhZXModmFsdWUpKSArIGdlb21fYmFyKCkgKyBmYWNldF93cmFwKH4ga2V5LCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKCiMjIyBDYWxjdWxhdGlvbiBvZiBkaWZmZXJlbnQgZy1mYWN0b3JzCmBgYHtyfQojIEdfZmFjdG9yXzIwMTVfb2xkCm5vbWlzcyA9IGlxICU+JQogIGZpbHRlcighaXMubmEocmF2ZW5fMjAxNV9vbGQpLCAhaXMubmEobWF0aF8yMDE1X29sZCksICFpcy5uYShjb3VudF9iYWNrd2FyZHMpLAogICAgICAgICAhaXMubmEod29yZHNfZGVsYXllZCksICFpcy5uYShhZGFwdGl2ZV9udW1iZXJpbmcpKQoKCiJnX2ZhY3Rvcl8yMDE1X29sZCA9fiByYXZlbl8yMDE1X29sZCArIG1hdGhfMjAxNV9vbGQgKyBjb3VudF9iYWNrd2FyZHMgKyAgd29yZHNfZGVsYXllZCsgIGFkYXB0aXZlX251bWJlcmluZyIgJT4lCiAgY2ZhKGRhdGEgPSBub21pc3MsIHN0ZC5sdiA9IFQsIHN0ZC5vdiA9IFQpIC0+IGNmYV9nCgpzdW1tYXJ5KGNmYV9nLCBmaXQubWVhc3VyZXMgPSBULCBzdGFuZGFyZGl6ZWQgPSBULCByc3F1YXJlID0gVFJVRSkKCm5vbWlzcyRnX2ZhY3Rvcl8yMDE1X29sZCA9IHByZWRpY3QoY2ZhX2cpWywxXQoKcXBsb3Qobm9taXNzJGdfZmFjdG9yXzIwMTVfb2xkKQoKbm9taXNzID0gbm9taXNzICU+JSBzZWxlY3QocGlkbGluaywgZ19mYWN0b3JfMjAxNV9vbGQpCgppcSA9IGxlZnRfam9pbihpcSwgbm9taXNzLCBieSA9ICJwaWRsaW5rIikKCiMgR19mYWN0b3JfMjAxNV95b3VuZwpub21pc3MgPSBpcSAlPiUKICBmaWx0ZXIoIWlzLm5hKHJhdmVuXzIwMTVfeW91bmcpLCAhaXMubmEobWF0aF8yMDE1X3lvdW5nKSkKCgpmYS5wYXJhbGxlbChub21pc3MgJT4lIHNlbGVjdChyYXZlbl8yMDE1X3lvdW5nLCBtYXRoXzIwMTVfeW91bmcpICU+JSBkYXRhLmZyYW1lKCkpCmZhKG5vbWlzcyAlPiUgc2VsZWN0KHJhdmVuXzIwMTVfeW91bmcsIG1hdGhfMjAxNV95b3VuZykgJT4lIGRhdGEuZnJhbWUoKSwgbmZhY3RvcnMgPSAxKQpvbV9yZXN1bHRzID0gb21lZ2Eobm9taXNzICU+JSBzZWxlY3QocmF2ZW5fMjAxNV95b3VuZywgbWF0aF8yMDE1X3lvdW5nKSAlPiUgZGF0YS5mcmFtZSgpLCBuZmFjdG9ycyA9IDEsIHNsID0gRikKb21fcmVzdWx0cwpvbWVnYS5kaWFncmFtKG9tX3Jlc3VsdHMpCgoiZ19mYWN0b3JfMjAxNV95b3VuZyA9fiByYXZlbl8yMDE1X3lvdW5nICsgbWF0aF8yMDE1X3lvdW5nIiAlPiUKICBjZmEoZGF0YSA9IG5vbWlzcywgc3RkLmx2ID0gVCwgc3RkLm92ID0gVCkgLT4gY2ZhX2cKc3VtbWFyeShjZmFfZykKCm5vbWlzcyRnX2ZhY3Rvcl8yMDE1X3lvdW5nID0gcHJlZGljdChjZmFfZylbLDFdCgpxcGxvdChub21pc3MkZ19mYWN0b3JfMjAxNV95b3VuZykKCm5vbWlzcyA9IG5vbWlzcyAlPiUgc2VsZWN0KHBpZGxpbmssIGdfZmFjdG9yXzIwMTVfeW91bmcpCgppcSA9IGxlZnRfam9pbihpcSwgbm9taXNzLCBieSA9ICJwaWRsaW5rIikKCiMgR19mYWN0b3JfMjAwN19vbGQKbm9taXNzID0gaXEgJT4lCiAgZmlsdGVyKCFpcy5uYShyYXZlbl8yMDA3X29sZCksICFpcy5uYShtYXRoXzIwMDdfb2xkKSkKCgpmYS5wYXJhbGxlbChub21pc3MgJT4lIHNlbGVjdChyYXZlbl8yMDA3X29sZCwgbWF0aF8yMDA3X29sZCkgJT4lIGRhdGEuZnJhbWUoKSkKZmEobm9taXNzICU+JSBzZWxlY3QocmF2ZW5fMjAwN19vbGQsIG1hdGhfMjAwN19vbGQpICU+JSBkYXRhLmZyYW1lKCksIG5mYWN0b3JzID0gMSkKb21fcmVzdWx0cyA9IG9tZWdhKG5vbWlzcyAlPiUgc2VsZWN0KHJhdmVuXzIwMDdfb2xkLCBtYXRoXzIwMDdfb2xkKSAlPiUgZGF0YS5mcmFtZSgpLCBuZmFjdG9ycyA9IDEsIHNsID0gRikKb21fcmVzdWx0cwpvbWVnYS5kaWFncmFtKG9tX3Jlc3VsdHMpCgoiZ19mYWN0b3JfMjAwN19vbGQgPX4gcmF2ZW5fMjAwN19vbGQgKyBtYXRoXzIwMDdfb2xkIiAlPiUKICBjZmEoZGF0YSA9IG5vbWlzcywgc3RkLmx2ID0gVCwgc3RkLm92ID0gVCkgLT4gY2ZhX2cKc3VtbWFyeShjZmFfZykKCm5vbWlzcyRnX2ZhY3Rvcl8yMDA3X29sZCA9IHByZWRpY3QoY2ZhX2cpWywxXQoKcXBsb3Qobm9taXNzJGdfZmFjdG9yXzIwMDdfb2xkKQoKbm9taXNzID0gbm9taXNzICU+JSBzZWxlY3QocGlkbGluaywgZ19mYWN0b3JfMjAwN19vbGQpCgppcSA9IGxlZnRfam9pbihpcSwgbm9taXNzLCBieSA9ICJwaWRsaW5rIikKCiMgR19mYWN0b3JfMjAwN195b3VuZwpub21pc3MgPSBpcSAlPiUKICBmaWx0ZXIoIWlzLm5hKHJhdmVuXzIwMDdfeW91bmcpLCAhaXMubmEobWF0aF8yMDA3X3lvdW5nKSkKCgpmYS5wYXJhbGxlbChub21pc3MgJT4lIHNlbGVjdChyYXZlbl8yMDA3X3lvdW5nLCBtYXRoXzIwMDdfeW91bmcpICU+JSBkYXRhLmZyYW1lKCkpCmZhKG5vbWlzcyAlPiUgc2VsZWN0KHJhdmVuXzIwMDdfeW91bmcsIG1hdGhfMjAwN195b3VuZykgJT4lIGRhdGEuZnJhbWUoKSwgbmZhY3RvcnMgPSAxKQpvbV9yZXN1bHRzID0gb21lZ2Eobm9taXNzICU+JSBzZWxlY3QocmF2ZW5fMjAwN195b3VuZywgbWF0aF8yMDA3X3lvdW5nKSAlPiUgZGF0YS5mcmFtZSgpLCBuZmFjdG9ycyA9IDEsIHNsID0gRikKb21fcmVzdWx0cwpvbWVnYS5kaWFncmFtKG9tX3Jlc3VsdHMpCgoiZ19mYWN0b3JfMjAwN195b3VuZyA9fiByYXZlbl8yMDA3X3lvdW5nICsgbWF0aF8yMDA3X3lvdW5nIiAlPiUKICBjZmEoZGF0YSA9IG5vbWlzcywgc3RkLmx2ID0gVCwgc3RkLm92ID0gVCkgLT4gY2ZhX2cKc3VtbWFyeShjZmFfZykKCm5vbWlzcyRnX2ZhY3Rvcl8yMDA3X3lvdW5nID0gcHJlZGljdChjZmFfZylbLDFdCgpxcGxvdChub21pc3MkZ19mYWN0b3JfMjAwN195b3VuZykKCm5vbWlzcyA9IG5vbWlzcyAlPiUgc2VsZWN0KHBpZGxpbmssIGdfZmFjdG9yXzIwMDdfeW91bmcpCgppcSA9IGxlZnRfam9pbihpcSwgbm9taXNzLCBieSA9ICJwaWRsaW5rIikKCmBgYAoKCiMjIFBlcnNvbmFsaXR5ClBlcnNvbmFsaXR5IGJhc2VkIG9uIEJpZyBGaXZlIDE1CmBgYHtyIHNlbGVjdCBwZXNvbmFsaXR5IGRhdGF9CiMjIyBQZXJzb25hbGl0eQojI1JlYXJyYW5nZSBwZXJzb25hbGl0eSBkYXRhIHNvIHRoYXQgZXZlcnkgaW5kaXZpZHVhbCBoYXMgb25seSBvbmUgcm93CnBlcnMgPSBzcHJlYWQoYjNiX3BzbiwgcHNudHlwZSwgcHNuMDEpCiMjbmFtZSBjb2x1bW5zCmNvbG5hbWVzKHBlcnMpIDwtIGMoImhoaWQxNF85IiwgInBpZDE0IiwgImhoaWQxNCIsICJwaWRsaW5rIiwgInZlcnNpb24iLCAibW9kdWxlIiwgImUxIiwgImMxIiwgIm8xIiwgImUyciIsICJuMXIiLCAiYTEiLCAibjIiLCAibzIiLCAiYzJyIiwgIm8zIiwgImEyIiwgImMzIiwgImUzIiwgImEzciIsICJuMyIpCnBlcnMgPSBwZXJzICU+JSBzZWxlY3QoaGhpZDE0XzksIHBpZGxpbmssIGUxLCBjMSwgbzEsIGUyciwgbjFyLCBhMSwgbjIsIG8yLCBjMnIsIG8zLCBhMiwgYzMsIGUzLCBhM3IsIG4zKQoKIyNFeHRyYXZlcnNpb24KcGVycyRlMnJfcmV2ZXJzZWQgPSA2IC0gcGVycyRlMnIKZXh0cmF2ZXJzaW9uID0gcGVycyAlPiUgc2VsZWN0KGUxLCBlMnJfcmV2ZXJzZWQsIGUzKQpwc3ljaDo6YWxwaGEoZGF0YS5mcmFtZShleHRyYXZlcnNpb24pLCBjaGVjay5rZXlzID0gVCkKcGVycyRiaWc1X2V4dCA9IHJvd01lYW5zKGV4dHJhdmVyc2lvbikKcXBsb3QocGVycyRiaWc1X2V4dCkKCiMjY29uc2NpZW50aW91c25lc3MKcGVycyRjMnJfcmV2ZXJzZWQgPSA2IC0gcGVycyRjMnIKY29uc2NpZW50aW91c25lc3MgPSBwZXJzICU+JSBzZWxlY3QoYzEsIGMycl9yZXZlcnNlZCwgYzMpCnBzeWNoOjphbHBoYShkYXRhLmZyYW1lKGNvbnNjaWVudGlvdXNuZXNzKSwgY2hlY2sua2V5cyA9IFQpCnBlcnMkYmlnNV9jb24gPSByb3dNZWFucyhjb25zY2llbnRpb3VzbmVzcykKcXBsb3QocGVycyRiaWc1X2NvbikKCiMjT3Blbm5lc3MKb3Blbm5lc3MgPSBwZXJzICU+JSBzZWxlY3QobzEsIG8yLCBvMykKcHN5Y2g6OmFscGhhKGRhdGEuZnJhbWUob3Blbm5lc3MpLCBjaGVjay5rZXlzID0gVCkKcGVycyRiaWc1X29wZW4gPSByb3dNZWFucyhvcGVubmVzcykKcXBsb3QocGVycyRiaWc1X29wZW4pCgojIyBOZXVyb3RpY2lzbQpwZXJzJG4xcl9yZXZlcnNlZCA9IDYgLSBwZXJzJG4xcgpuZXVyb3RpY2lzbSA9IHBlcnMgJT4lIHNlbGVjdChuMXJfcmV2ZXJzZWQsIG4yLCBuMykKcGVycyRiaWc1X25ldSA9IHJvd01lYW5zKG5ldXJvdGljaXNtKQpxcGxvdChwZXJzJGJpZzVfbmV1KQoKIyNBZ3JlZWFibGVuZXNzCnBlcnMkYTNyX3JldmVyc2VkID0gNi0gcGVycyRhM3IKYWdyZWVhYmxlbmVzcz0gcGVycyAlPiUgc2VsZWN0KGExLCBhMiwgYTNyX3JldmVyc2VkKQpwZXJzJGJpZzVfYWdyZWUgPSByb3dNZWFucyhhZ3JlZWFibGVuZXNzKQpxcGxvdChwZXJzJGJpZzVfYWdyZWUpCmBgYAoKCiMjIFJpc2sgYXZlcnNpb24KUmlzayBhdmVyc2lvbiBiYXNlZCBvbiBhZGFwdGl2ZSBsb3R0ZXJ5IHRhc2sKYGBge3Igc2VsZWN0IHJpc2sgdGFraW5nIGRhdGF9CiMjI1Jpc2t0YWtpbmcKcmlzayA9IGIzYV9zaSAlPiUgc2VsZWN0KGhoaWQxNF85LCBwaWRsaW5rLCByYW5kb21fc2ksIHNpMDEsIHNpMDIsIHNpMDMsIHNpMDQsIHNpMDUsIHNpMTEsIHNpMTIsIHNpMTMsIHNpMTQsIHNpMTUpCgojIyA4IG1lYW5zIHRoZXkgZGlkbnQga25vdyB3aGljaCBhbnN3ZXIgdGhleSB3b3VsZCBjaG9vc2UKcmlzayRzaTAxWyByaXNrJHNpMDEgPT0gOF0gPSBOQQpyaXNrJHNpMDJbIHJpc2skc2kwMiA9PSA4XSA9IE5BCnJpc2skc2kwM1sgcmlzayRzaTAzID09IDhdID0gTkEKcmlzayRzaTA0WyByaXNrJHNpMDQgPT0gOF0gPSBOQQpyaXNrJHNpMDVbIHJpc2skc2kwNSA9PSA4XSA9IE5BCnJpc2skc2kxMVsgcmlzayRzaTExID09IDhdID0gTkEKcmlzayRzaTEyWyByaXNrJHNpMTIgPT0gOF0gPSBOQQpyaXNrJHNpMTNbIHJpc2skc2kxMyA9PSA4XSA9IE5BCnJpc2skc2kxNFsgcmlzayRzaTE0ID09IDhdID0gTkEKcmlzayRzaTE1WyByaXNrJHNpMTUgPT0gOF0gPSBOQQoKIyMgY2FsY3VsYXRlIGEgcmlzayBzY29yZSBmb3IgcmlzayBnYW1lIEEgCiMgKDUgPSBnYW1ibGUgYXZlcnNlLCBPcmRpbmFsc2thbGEgOiAxID0gcmlzayBsb3ZpbmcsIDQgPSByaXNrIGF2ZXJzZSkKcmlzayRyaXNrQSA9IGlmZWxzZShyaXNrJHNpMDEgPT0gMSAmIHJpc2skc2kwMiA9PSAxLCA1LAogICAgICAgICAgICAgaWZlbHNlKHJpc2skc2kwMSA9PSAyICYgcmlzayRzaTAzID09IDEgJiByaXNrJHNpMDQgPT0gMSwgNCwKICAgICAgICAgICAgIGlmZWxzZShyaXNrJHNpMDEgPT0gMiAmIHJpc2skc2kwMyA9PSAxICYgcmlzayRzaTA0ID09IDIsIDMsCiAgICAgICAgICAgICBpZmVsc2UocmlzayRzaTAxID09IDIgJiByaXNrJHNpMDMgPT0gMiAmIHJpc2skc2kwNSA9PSAxLCAyLAogICAgICAgICAgICAgaWZlbHNlKHJpc2skc2kwMSA9PSAyICYgcmlzayRzaTAzID09IDIgJiByaXNrJHNpMDUgPT0gMiwgMSwKICAgICAgICAgICAgIE5BKSkpKSkKCiMjIGNhbGN1bGF0ZSBhIHJpc2sgc2NvcmUgZm9yIHJpc2sgZ2FtZSBCIAojICg1ID0gZ2FtYmxlIGxvdmluZywgT3JkaW5hbHNrYWxhIDogMSA9IHJpc2sgbG92aW5nLCA0ID0gcmlzayBhdmVyc2UpCnJpc2skcmlza0IgPSBpZmVsc2UocmlzayRzaTExID09IDIgJiByaXNrJHNpMTIgPT0gMSwgNSwKICAgICAgICAgICAgIGlmZWxzZShyaXNrJHNpMTEgPT0gMSAmIHJpc2skc2kxMyA9PSAxICYgcmlzayRzaTE0ID09IDEsIDQsCiAgICAgICAgICAgICBpZmVsc2UocmlzayRzaTExID09IDEgJiByaXNrJHNpMTMgPT0gMSAmIHJpc2skc2kxNCA9PSAyLCAzLAogICAgICAgICAgICAgaWZlbHNlKHJpc2skc2kxMSA9PSAxICYgcmlzayRzaTEzID09IDIgJiByaXNrJHNpMTUgPT0gMSwgMiwKICAgICAgICAgICAgIGlmZWxzZShyaXNrJHNpMTEgPT0gMSAmIHJpc2skc2kxMyA9PSAyICYgcmlzayRzaTE1ID09IDIsIDEsCiAgICAgICAgICAgICBOQSkpKSkpCgojIHJlY29kZSByaXNrIHZhcmlhYmxlCnJpc2sgPSByaXNrICU+JQogIG11dGF0ZShyaXNrQiA9IGlmZWxzZShyaXNrQiA9PSA1LCAwLCByaXNrQiksCiAgICAgICAgIHJpc2tCID0gcmlza0IgKyAxKQoKCmBgYAoKIyMgRWR1Y2F0aW9uYWwgQXR0YWlubWVudApgYGB7ciBzZWxlY3QgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCBkYXRhfQojIFNlbGVjdCwgcmVuYW1lIGFuZCBtdXRhdGUgZGF0YQplYSA9IGIzYV9kbDEgJT4lCiAgc2VsZWN0KHBpZGxpbmssIGRsMDQsIGRsMDYsIGRsMDcsIGRsMDdhLCBkbDA3YWEpICU+JQogIHJlbmFtZShwaWRsaW5rID0gcGlkbGluaywgYXR0ZW5kZWRfc2Nob29sID0gZGwwNCwgaGlnaGVzdF9lZHVjYXRpb24gPSBkbDA2LAogICAgICAgICBoaWdoZXN0X2dyYWRlPWRsMDcsIGN1cnJlbnRseV9hdHRlbmRpbmdfc2Nob29sID0gZGwwN2EsIGhvdXJzX2luX2NsYXNzID0gZGwwN2FhKSAlPiUKICBtdXRhdGUoYXR0ZW5kZWRfc2Nob29sID0gYXMuZmFjdG9yKGlmZWxzZShhdHRlbmRlZF9zY2hvb2wgPT0gOCwgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGF0dGVuZGVkX3NjaG9vbCA9PSAxLCAieWVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGF0dGVuZGVkX3NjaG9vbCA9PSAzLCAibm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ZW5kZWRfc2Nob29sKSkpKSwKICAgICAgICAgaGlnaGVzdF9lZHVjYXRpb24gPSBhcy5mYWN0b3IoaWZlbHNlKGhpZ2hlc3RfZWR1Y2F0aW9uID09IDIgfCBoaWdoZXN0X2VkdWNhdGlvbiA9PSA3MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudGFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGhpZ2hlc3RfZWR1Y2F0aW9uID09IDMgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RfZWR1Y2F0aW9uID09IDQgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RfZWR1Y2F0aW9uID09IDczLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSnVuaW9yIEhpZ2giLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaGlnaGVzdF9lZHVjYXRpb24gPT0gNSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RfZWR1Y2F0aW9uID09IDYgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWdoZXN0X2VkdWNhdGlvbiA9PSA3NCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5pb3IgSGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaGlnaGVzdF9lZHVjYXRpb24gPT0gNjAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlnaGVzdF9lZHVjYXRpb24gPT0gNjEgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlnaGVzdF9lZHVjYXRpb24gPT0gNjIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlnaGVzdF9lZHVjYXRpb24gPT0gNjMgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlnaGVzdF9lZHVjYXRpb24gPT0gMTMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdHkiLCBOQSkpKSkpLCMib3RoZXIiID0gTkEKICAgICAgICAgaGlnaGVzdF9ncmFkZSA9IGlmZWxzZShoaWdoZXN0X2dyYWRlID09IDk4LCBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaGlnaGVzdF9ncmFkZSA9PSA5OSwgTkEsIGhpZ2hlc3RfZ3JhZGUpKSwKICAgICAgICAgY3VycmVudGx5X2F0dGVuZGluZ19zY2hvb2wgPSBhcy5mYWN0b3IoaWZlbHNlKGN1cnJlbnRseV9hdHRlbmRpbmdfc2Nob29sID09IDEsICJ5ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGN1cnJlbnRseV9hdHRlbmRpbmdfc2Nob29sID09IDMsICJubyIsIE5BKSkpLAogICAgICAgICBob3Vyc19pbl9jbGFzcyA9IGlmZWxzZShob3Vyc19pbl9jbGFzcyA9PSA5OSwgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShob3Vyc19pbl9jbGFzcyA9PSA5OCwgTkEsIGhvdXJzX2luX2NsYXNzKSkpCgojIyBDcmVhdGUgdmFyaWFibGUgdGhhdCBpbmNsdWRlcyB5ZWFycyBvZiBlZHVjYXRpb24gKGhpZ2hlc3RfZWR1Y2F0aW9uLmhpZ2hlc3RfZ3JhZGUpIGFzIGEgbnVtZXJpYyB2YXJpYWJsZQojIFBlb3BsZSB3aG8gc3RhcnRlZCBhbiBlZHVjYXRpb24gbGV2ZWwsIGJ1dCBkcm9wcGVkIG91dCB3aXRoaW4gdGhlIGZpcnN0IHllYXIsIGFyZSBjb2RlZCB3aXRoIGhhbGYgYSB5ZWFyIG9mIHNjaG9vbGluZwplYSA9IGVhICU+JQogIG11dGF0ZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID0gYXMuZmFjdG9yKHN0cl9jKGhpZ2hlc3RfZWR1Y2F0aW9uLCAiLiIsIGhpZ2hlc3RfZ3JhZGUpKSwKICAgICAgICAgeWVhcnNfb2ZfZWR1Y2F0aW9uID0gYXMubnVtZXJpYyhpZmVsc2UoYXR0ZW5kZWRfc2Nob29sID09ICJubyIsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIkVsZW1lbnRhcnkuMCIsIDAuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS4xIiwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS4yIiwgMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS4zIiwgMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS40IiwgNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS41IiwgNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiRWxlbWVudGFyeS42IiwgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIkVsZW1lbnRhcnkuNyIsIDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIkp1bmlvciBIaWdoLjAiLCA2LjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIkp1bmlvciBIaWdoLjEiLCA3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJKdW5pb3IgSGlnaC4yIiwgOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiSnVuaW9yIEhpZ2guMyIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJKdW5pb3IgSGlnaC43IiwgOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiU2VuaW9yIEhpZ2guMCIsIDkuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiU2VuaW9yIEhpZ2guMSIsIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJTZW5pb3IgSGlnaC4yIiwgMTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIlNlbmlvciBIaWdoLjMiLCBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiU2VuaW9yIEhpZ2guNyIsIDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJVbml2ZXJzaXR5LjAiLCAxMi41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJVbml2ZXJzaXR5LjEiLCAxMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiVW5pdmVyc2l0eS4yIiwgMTQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIlVuaXZlcnNpdHkuMyIsIDE1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJVbml2ZXJzaXR5LjQiLCAxNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeWVhcnNfb2ZfZWR1Y2F0aW9uX2ZhY3RvciA9PSAiVW5pdmVyc2l0eS41IiwgMTcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXJzX29mX2VkdWNhdGlvbl9mYWN0b3IgPT0gIlVuaXZlcnNpdHkuNiIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yID09ICJVbml2ZXJzaXR5LjciLCAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkEpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKQpxcGxvdChlYSR5ZWFyc19vZl9lZHVjYXRpb24pCmBgYAoKIyMgRUJUQU5BUy9VQU4vVU4gU2NvcmUKYGBge3IgRUJUQU5BUy9VQU4vVU4gU2NvcmV9CkVCVEFOQVNfbG9uZyA9IGIzYV9kbDMgJT4lCiAgc2VsZWN0KHBpZGxpbmssICJMZXZlbF9vZl9zY2hvb2xpbmciID0gZGwzdHlwZSwgIlR5cGVfb2ZfdGVzdCIgPSBkbDE2YzEsICJJbmRvbmVzaWFfc2NvcmUiID0gZGwxNmRiLAogICAgICAgICAiRW5nbGlzaF9zY29yZSIgPSBkbDE2ZGMsICJNYXRoX3Njb3JlIiA9IGRsMTZkZCwgIlRvdGFsX3Njb3JlIiA9IGRsMTZlKSAlPiUKICBtdXRhdGUoTGV2ZWxfb2Zfc2Nob29saW5nID0gaWZlbHNlKExldmVsX29mX3NjaG9vbGluZyA9PSAxLCAiRWxlbWVudGFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoTGV2ZWxfb2Zfc2Nob29saW5nID09IDIsICJKdW5pb3IgSGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKExldmVsX29mX3NjaG9vbGluZyA9PSAzLCAiU2VuaW9yIEhpZ2giLCBOQSkpKSwKICAgICAgICAgVHlwZV9vZl90ZXN0ID0gaWZlbHNlKFR5cGVfb2ZfdGVzdCA9PSAxLCAiRUJUQU5BUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoVHlwZV9vZl90ZXN0ID09IDIsICJVQU4vVU4iLCBOQSkpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKEluZG9uZXNpYV9zY29yZSkgfCAhaXMubmEoRW5nbGlzaF9zY29yZSkgfCAhaXMubmEoTWF0aF9zY29yZSkgfCAhaXMubmEoVG90YWxfc2NvcmUpKQogICMgcmVtb3ZlIHBlb3BsZSB3aXRoIG5vIEVCVEFOQVMgSW5mb3JtYXRpb24KCiNXcmFuZ2xlIERhdGEKRUJUQU5BU19FbGVtZW5hdHJ5ID0gRUJUQU5BU19sb25nICU+JQogIGZpbHRlcihMZXZlbF9vZl9zY2hvb2xpbmcgPT0gIkVsZW1lbnRhcnkiKSAlPiUKICByZW5hbWUoIkluZG9uZXNpYV9zY29yZV9lbGVtZW50YXJ5IiA9IEluZG9uZXNpYV9zY29yZSwgIkVuZ2xpc2hfc2NvcmVfZWxlbWVudGFyeSIgPSBFbmdsaXNoX3Njb3JlLAogICAgICAgICAiTWF0aF9zY29yZV9lbGVtZW5hdHJ5IiA9IE1hdGhfc2NvcmUsICJUb3RhbF9zY29yZV9lbGVtZW5hdHJ5IiA9IFRvdGFsX3Njb3JlLAogICAgICAgICAiVHlwZV9vZl90ZXN0X2VsZW1lbnRhcnkiID0gVHlwZV9vZl90ZXN0KSAlPiUKICBzZWxlY3QoLUxldmVsX29mX3NjaG9vbGluZykKCkVCVEFOQVNfSnVuaW9yX0hpZ2ggPSBFQlRBTkFTX2xvbmcgJT4lCiAgZmlsdGVyKExldmVsX29mX3NjaG9vbGluZyA9PSAiSnVuaW9yIEhpZ2giKSAlPiUKICByZW5hbWUoIkluZG9uZXNpYV9zY29yZV9KdW5pb3JfSGlnaCIgPSBJbmRvbmVzaWFfc2NvcmUsICJFbmdsaXNoX3Njb3JlX0p1bmlvcl9IaWdoIiA9IEVuZ2xpc2hfc2NvcmUsCiAgICAgICAgICJNYXRoX3Njb3JlX0p1bmlvcl9IaWdoIiA9IE1hdGhfc2NvcmUsICJUb3RhbF9zY29yZV9KdW5pb3JfSGlnaCIgPSBUb3RhbF9zY29yZSwKICAgICAgICAgIlR5cGVfb2ZfdGVzdF9KdW5pb3JfSGlnaCIgPSBUeXBlX29mX3Rlc3QpJT4lCiAgc2VsZWN0KC1MZXZlbF9vZl9zY2hvb2xpbmcpCgpFQlRBTkFTX1Nlbmlvcl9IaWdoID0gRUJUQU5BU19sb25nICU+JQogIGZpbHRlcihMZXZlbF9vZl9zY2hvb2xpbmcgPT0gIlNlbmlvciBIaWdoIikgJT4lCiAgcmVuYW1lKCJJbmRvbmVzaWFfc2NvcmVfU2VuaW9yX0hpZ2giID0gSW5kb25lc2lhX3Njb3JlLCAiRW5nbGlzaF9zY29yZV9TZW5pb3JfSGlnaCIgPSBFbmdsaXNoX3Njb3JlLAogICAgICAgICAiTWF0aF9zY29yZV9TZW5pb3JfSGlnaCIgPSBNYXRoX3Njb3JlLCAiVG90YWxfc2NvcmVfU2VuaW9yX0hpZ2giID0gVG90YWxfc2NvcmUsCiAgICAgICAgICJUeXBlX29mX3Rlc3RfU2VuaW9yX0hpZ2giID0gVHlwZV9vZl90ZXN0KSU+JQogIHNlbGVjdCgtTGV2ZWxfb2Zfc2Nob29saW5nKQoKRUJUQU5BUyA9IGZ1bGxfam9pbihFQlRBTkFTX0VsZW1lbmF0cnksIEVCVEFOQVNfSnVuaW9yX0hpZ2gsIGJ5ID0gInBpZGxpbmsiKQpFQlRBTkFTID0gZnVsbF9qb2luKEVCVEFOQVMsIEVCVEFOQVNfU2VuaW9yX0hpZ2gsIGJ5ID0gInBpZGxpbmsiKSAKCnRhYmxlKGlzLm5hKEVCVEFOQVMkVG90YWxfc2NvcmVfZWxlbWVuYXRyeSkpCnRhYmxlKGlzLm5hKEVCVEFOQVMkVG90YWxfc2NvcmVfSnVuaW9yX0hpZ2gpKQp0YWJsZShpcy5uYShFQlRBTkFTJFRvdGFsX3Njb3JlX1Nlbmlvcl9IaWdoKSkKCkVCVEFOQVMgPSBFQlRBTkFTICU+JQogIG11dGF0ZShUb3RhbF9zY29yZV9oaWdoZXN0ID0gVG90YWxfc2NvcmVfZWxlbWVuYXRyeSwKICAgICAgICAgVG90YWxfc2NvcmVfaGlnaGVzdCA9IGlmZWxzZSghaXMubmEoVG90YWxfc2NvcmVfU2VuaW9yX0hpZ2gpLCBUb3RhbF9zY29yZV9TZW5pb3JfSGlnaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoIWlzLm5hKFRvdGFsX3Njb3JlX0p1bmlvcl9IaWdoKSwgVG90YWxfc2NvcmVfSnVuaW9yX0hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRvdGFsX3Njb3JlX2hpZ2hlc3QpKSwKICAgICAgICAgVG90YWxfc2NvcmVfaGlnaGVzdF90eXBlID0gaWZlbHNlKCFpcy5uYShUb3RhbF9zY29yZV9TZW5pb3JfSGlnaCksICJTZW5pb3IgSGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCFpcy5uYShUb3RhbF9zY29yZV9KdW5pb3JfSGlnaCksICJKdW5pb3IgSGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSghaXMubmEoVG90YWxfc2NvcmVfZWxlbWVuYXRyeSksICJFbGVtZW50YXJ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQSkpKSwKICAgICAgICAgTWF0aF9zY29yZV9oaWdoZXN0ID0gTWF0aF9zY29yZV9lbGVtZW5hdHJ5LAogICAgICAgICBNYXRoX3Njb3JlX2hpZ2hlc3QgPSBpZmVsc2UoIWlzLm5hKE1hdGhfc2NvcmVfU2VuaW9yX0hpZ2gpLCBNYXRoX3Njb3JlX1Nlbmlvcl9IaWdoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSghaXMubmEoTWF0aF9zY29yZV9KdW5pb3JfSGlnaCksIE1hdGhfc2NvcmVfSnVuaW9yX0hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGhfc2NvcmVfaGlnaGVzdCkpLAogICAgICAgICBNYXRoX3Njb3JlX2hpZ2hlc3RfdHlwZSA9IGlmZWxzZSghaXMubmEoTWF0aF9zY29yZV9TZW5pb3JfSGlnaCksICJTZW5pb3IgSGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCFpcy5uYShNYXRoX3Njb3JlX0p1bmlvcl9IaWdoKSwgIkp1bmlvciBIaWdoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCFpcy5uYShNYXRoX3Njb3JlX2VsZW1lbmF0cnkpLCAiRWxlbWVudGFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkEpKSkpCnFwbG90KEVCVEFOQVMkVG90YWxfc2NvcmVfaGlnaGVzdCkKcXBsb3QoRUJUQU5BUyRNYXRoX3Njb3JlX2hpZ2hlc3QpCmBgYAoKIyMgQ2hpbGQgTGFib3VyCmBgYCB7ciBDaGlsZCBMYWJvdXJ9CiMjIFdvcmtpbmcgd2hpbGUgc3RpbGwgaW4gc2Nob29sCmNoaWxkX2xhYm91ciA9IGIzYV9kbDQgJT4lCiAgc2VsZWN0KHBpZGxpbmssICJMZXZlbF9vZl9zY2hvb2xpbmciID0gZGw0dHlwZSwgIldvcmtlZCIgPSBkbDE1LCAiTWlzc2VkX3NjaG9vbCIgPSBkbDE0YSkgJT4lCiAgbXV0YXRlKExldmVsX29mX3NjaG9vbGluZyA9IGlmZWxzZShMZXZlbF9vZl9zY2hvb2xpbmcgPT0gMSwgIkVsZW1lbnRhcnkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKExldmVsX29mX3NjaG9vbGluZyA9PSAyLCAiSnVuaW9ySGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKExldmVsX29mX3NjaG9vbGluZyA9PSAzLCAiU2VuaW9ySGlnaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShMZXZlbF9vZl9zY2hvb2xpbmcgPT0gNCwgIlVuaXZlcnNpdHkiLCBOQSkpKSksCiAgICAgICAgIFdvcmtlZCA9IGlmZWxzZShXb3JrZWQgPT0gMSwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShXb3JrZWQgPT0gMywgMCwgTkEpKSwKICAgICAgICAgTWlzc2VkX3NjaG9vbCA9IGlmZWxzZShNaXNzZWRfc2Nob29sID09IDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoTWlzc2VkX3NjaG9vbCA9PSAzLCAwLCBOQSkpKQoKIyBXcmFuZ2xlIERhdGEKY2hpbGRfbGFib3VyX3dvcmsgPSBjaGlsZF9sYWJvdXIgJT4lCiAgc2VsZWN0KHBpZGxpbmssIExldmVsX29mX3NjaG9vbGluZywgV29ya2VkKSAlPiUKICBzcHJlYWQoLiwgTGV2ZWxfb2Zfc2Nob29saW5nLCBXb3JrZWQpICU+JQogIHJlbmFtZSgiRWxlbWVudGFyeV93b3JrZWQiID0gRWxlbWVudGFyeSwgIkp1bmlvcl9oaWdoX3dvcmtlZCIgPSBKdW5pb3JIaWdoLCAKICAgICAgICAgIlNlbmlvcl9oaWdoX3dvcmtlZCIgPSBTZW5pb3JIaWdoLCAiVW5pdmVyc2l0eV93b3JrZWQiID0gVW5pdmVyc2l0eSkgJT4lCiAgbXV0YXRlKHRvdGFsX3dvcmtlZCA9IGlmZWxzZShFbGVtZW50YXJ5X3dvcmtlZCA9PSAxIHwgSnVuaW9yX2hpZ2hfd29ya2VkID09IDEgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZW5pb3JfaGlnaF93b3JrZWQgPT0gMSB8IFVuaXZlcnNpdHlfd29ya2VkID09IDEsIDEsIDApLAogICAgICAgICB0b3RhbF93b3JrZWQgID0gaWZlbHNlKGlzLm5hKHRvdGFsX3dvcmtlZCksIDAsIHRvdGFsX3dvcmtlZCkpCgojIyBNaXNzZWQgc2Nob29sCmNoaWxkX2xhYm91cl9taXNzZWQgPSBjaGlsZF9sYWJvdXIgJT4lCiAgc2VsZWN0KHBpZGxpbmssIExldmVsX29mX3NjaG9vbGluZywgTWlzc2VkX3NjaG9vbCkgJT4lCiAgc3ByZWFkKC4sIExldmVsX29mX3NjaG9vbGluZywgTWlzc2VkX3NjaG9vbCkgJT4lCiAgcmVuYW1lKCJFbGVtZW50YXJ5X21pc3NlZCIgPSBFbGVtZW50YXJ5LCAiSnVuaW9yX2hpZ2hfbWlzc2VkIiA9IEp1bmlvckhpZ2gsIAogICAgICAgICAiU2VuaW9yX2hpZ2hfbWlzc2VkIiA9IFNlbmlvckhpZ2gsICJVbml2ZXJzaXR5X21pc3NlZCIgPSBVbml2ZXJzaXR5KSAlPiUKICBtdXRhdGUodG90YWxfbWlzc2VkID0gaWZlbHNlKEVsZW1lbnRhcnlfbWlzc2VkID09IDEgfCBKdW5pb3JfaGlnaF9taXNzZWQgPT0gMSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbmlvcl9oaWdoX21pc3NlZCA9PSAxIHwgVW5pdmVyc2l0eV9taXNzZWQgPT0gMSwgMSwgMCkpCgpjaGlsZF9sYWJvdXIgPSBmdWxsX2pvaW4oY2hpbGRfbGFib3VyX3dvcmssIGNoaWxkX2xhYm91cl9taXNzZWQsIGJ5ID0gInBpZGxpbmsiKQp0YWJsZShjaGlsZF9sYWJvdXIkdG90YWxfbWlzc2VkKQp0YWJsZShjaGlsZF9sYWJvdXIkdG90YWxfd29ya2VkKQpgYGAgCgojIyBKb2IgSW5mb3JtYXRpb24KYGBge3J9CmpvYiA9IGIzYV90azIgJT4lIHNlbGVjdChwaWRsaW5rLCAiQ2F0ZWdvcnkiID0gdGsyNGEsICJTZWN0b3IiID0gdGsxOWFiLCAid2FnZV9sYXN0X21vbnRoIiA9IHRrMjVhMSwKICAgICAgICAgICAgICAgICAgICAgICAgICJ3YWdlX2xhc3RfeWVhciIgPSB0azI1YTIpICU+JQogIG11dGF0ZShDYXRlZ29yeSA9IGlmZWxzZShDYXRlZ29yeSA9PSAxIHwgQ2F0ZWdvcnkgPT0gMiB8IENhdGVnb3J5ID09IDMsICJTZWxmLWVtcGxveWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKENhdGVnb3J5ID09IDQsICJHb3Zlcm5tZW50IHdvcmtlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoQ2F0ZWdvcnkgPT0gNSwgIlByaXZhdGUgd29ya2VyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoQ2F0ZWdvcnkgPT0gNywgIkNhc3VhbCB3b3JrZXIgaW4gYWdyaWN1bHR1cmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoQ2F0ZWdvcnkgPT0gOCwgIkNhc3VhbCB3b3JrZXIgbm90IGluIGFncmljdWx0dXJlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShDYXRlZ29yeSA9PSA2LCAiVW5wYWlkIGZhbWlseSB3b3JrZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BKSkpKSkpLAogICAgICAgICBTZWxmX2VtcGxveWVkID0gaWZlbHNlKENhdGVnb3J5ID09ICJTZWxmLWVtcGxveWVkIiwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaXMubmEoQ2F0ZWdvcnkpLCBOQSwgMCkpLAogICAgICAgICBTZWN0b3IgPSBpZmVsc2UoU2VjdG9yID09IDEsICJBZ3JpY3VsdHVyZSwgZm9yZXN0cnksIGZpc2hpbmcgYW5kIGh1bnRpbmciLAogICAgICAgICAgICAgICAgICBpZmVsc2UoU2VjdG9yID09IDIsICJNaW5pbmcgYW5kIHF1YXJyeWluZyIsCiAgICAgICAgICAgICAgICAgIGlmZWxzZShTZWN0b3IgPT0gMywgIk1hbnVmYWN0dXJpbmciLAogICAgICAgICAgICAgICAgICBpZmVsc2UoU2VjdG9yID09IDQsICJFbGVjdHJpY2l0eSwgZ2FzLCB3YXRlciIsCiAgICAgICAgICAgICAgICAgIGlmZWxzZShTZWN0b3IgPT0gNSwgIkNvbnN0cnVjdGlvbiIsCiAgICAgICAgICAgICAgICAgIGlmZWxzZShTZWN0b3IgPT0gNiwgIldob2xlc2FsZSwgcmV0YWlsLCByZXN0YXVyYW50cyBhbmQgaG90ZWxzIiwKICAgICAgICAgICAgICAgICAgaWZlbHNlKFNlY3RvciA9PSA3LCAiVHJhbnNwb3J0YXRpb24sIHN0b3JhZ2UgYW5kIGNvbW11bmljYXRpb25zIiwKICAgICAgICAgICAgICAgICAgaWZlbHNlKFNlY3RvciA9PSA4LCAiRmluYW5jZSwgaW5zdXJhbmNlLCByZWFsIGVzdGF0ZSBhbmQgYnVzaW5lc3Mgc2VydmljZXMiLAogICAgICAgICAgICAgICAgICBpZmVsc2UoU2VjdG9yID09IDksICJTb2NpYWwgc2VydmljZXMiLAogICAgICAgICAgICAgICAgICBpZmVsc2UoU2VjdG9yID09IDEwLCAiQWN0aXZpdGllcyB0aGF0IGNhbm5vdCBiZSBjbGFzc2lmaWVkIiwgTkEpKSkpKSkpKSkpLAogICAgICAgICB3YWdlX2xhc3RfbW9udGggPSBpZmVsc2Uod2FnZV9sYXN0X21vbnRoID09IDgsIE5BLCB3YWdlX2xhc3RfbW9udGgpLAogICAgICAgICB3YWdlX2xhc3RfeWVhciA9IGlmZWxzZSh3YWdlX2xhc3RfeWVhciA9PSA4LCBOQSwgd2FnZV9sYXN0X3llYXIpKQoKdGFibGUoam9iJENhdGVnb3J5KQp0YWJsZShqb2IkU2VjdG9yKQpxcGxvdChqb2Ikd2FnZV9sYXN0X21vbnRoKQpzdW1tYXJ5KGpvYiR3YWdlX2xhc3RfbW9udGgpCnggPSBqb2IgJT4lIGZpbHRlcih3YWdlX2xhc3RfbW9udGggPCA1MDAwMDAwKQpxcGxvdCh4JHdhZ2VfbGFzdF9tb250aCkKCnFwbG90KGpvYiR3YWdlX2xhc3RfeWVhcikKc3VtbWFyeShqb2Ikd2FnZV9sYXN0X3llYXIpCnggPSBqb2IgJT4lIGZpbHRlcih3YWdlX2xhc3RfeWVhciA8IDUwMDAwMDAwKQpxcGxvdCh4JHdhZ2VfbGFzdF95ZWFyKQpgYGAKCiMjIEhlYWx0aCBJbmZvcm1hdGlvbiAtIFNtb2tpbmcgQmVoYXZpb3IKYGBge3J9CnNtb2tpbmcgPSBiM2Jfa20gJT4lCiAgc2VsZWN0KHBpZGxpbmssICJldmVyX3Ntb2tlZCIgPSBrbTAxYSwgInN0aWxsX3Ntb2tpbmciID0ga20wNCwgImFtb3VudCIgPSBrbTA4LAogICAgICAgICAibW9uZXlfc3BlbnRfc21va2luZyIgPSBrbTA5LCAiYWdlX2ZpcnN0X3Ntb2tlIiA9IGttMTApICU+JQogIG11dGF0ZShldmVyX3Ntb2tlZCA9IGlmZWxzZShldmVyX3Ntb2tlZCA9PSAxLCAxLCAwKSwKICAgICAgICAgc3RpbGxfc21va2luZyA9IGlmZWxzZShzdGlsbF9zbW9raW5nID09IDEsIDEsIDApLAogICAgICAgICBhbW91bnQgPSBpZmVsc2UoYW1vdW50ID09IDgsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGFtb3VudCA9PSA5OCwgTkEsIGFtb3VudCkpLAogICAgICAgICBhbW91bnRfc3RpbGxfc21va2VycyA9IGlmZWxzZShzdGlsbF9zbW9raW5nID09IDEsIGFtb3VudCwgTkEpKQpgYGAKCiMjIE1lcmdlIGRhdGEKCmBgYHtyIG1lcmdlIGRhdGF9CiMjIyBNZXJnZSBhbGwgZGF0YSBmb3IgcGVvcGxlIHdpdGggYmlydGhvcmRlciBpbmZvcm1hdGlvbnMKYWxsZGF0YV9iaXJ0aG9yZGVyID0gbGVmdF9qb2luKGFsbGRhdGFfcHJlZ25hbmN5LCBpcSwgYnkgPSAicGlkbGluayIpCmFsbGRhdGFfYmlydGhvcmRlciA9IGxlZnRfam9pbihhbGxkYXRhX2JpcnRob3JkZXIsIHBlcnMsIGJ5ID0gInBpZGxpbmsiKQphbGxkYXRhX2JpcnRob3JkZXIgPSBsZWZ0X2pvaW4oYWxsZGF0YV9iaXJ0aG9yZGVyLCByaXNrLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YV9iaXJ0aG9yZGVyID0gbGVmdF9qb2luKGFsbGRhdGFfYmlydGhvcmRlciwgZWEsIGJ5ID0gInBpZGxpbmsiKQphbGxkYXRhX2JpcnRob3JkZXIgPSBsZWZ0X2pvaW4oYWxsZGF0YV9iaXJ0aG9yZGVyLCBFQlRBTkFTLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YV9iaXJ0aG9yZGVyID0gbGVmdF9qb2luKGFsbGRhdGFfYmlydGhvcmRlciwgY2hpbGRfbGFib3VyLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YV9iaXJ0aG9yZGVyID0gbGVmdF9qb2luKGFsbGRhdGFfYmlydGhvcmRlciwgam9iLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YV9iaXJ0aG9yZGVyID0gbGVmdF9qb2luKGFsbGRhdGFfYmlydGhvcmRlciwgc21va2luZywgYnkgPSAicGlkbGluayIpCgoKYWxsZGF0YSA9IGxlZnRfam9pbihpbmRpdmlkdWFsc191bmNoYW5nZWQsIGlxLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YSA9IGxlZnRfam9pbihhbGxkYXRhLCBwZXJzLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YSA9IGxlZnRfam9pbihhbGxkYXRhLCByaXNrLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YSA9IGxlZnRfam9pbihhbGxkYXRhLCBlYSwgYnkgPSAicGlkbGluayIpCmFsbGRhdGEgPSBsZWZ0X2pvaW4oYWxsZGF0YSwgRUJUQU5BUywgYnkgPSAicGlkbGluayIpCmFsbGRhdGEgPSBsZWZ0X2pvaW4oYWxsZGF0YSwgY2hpbGRfbGFib3VyLCBieSA9ICJwaWRsaW5rIikKYWxsZGF0YSA9IGxlZnRfam9pbihhbGxkYXRhLCBqb2IsIGJ5ID0gInBpZGxpbmsiKQphbGxkYXRhID0gbGVmdF9qb2luKGFsbGRhdGEsIHNtb2tpbmcsIGJ5ID0gInBpZGxpbmsiKQoKYGBgCgojIyBGaXggdHlwZXMKYGBge3J9CmFsbGRhdGFfYmlydGhvcmRlciA8LSBhbGxkYXRhX2JpcnRob3JkZXIgJT4lIAogIG11dGF0ZV9hdCh2YXJzKGFnZV8yMDE1X29sZCwgYWdlXzIwMTVfeW91bmcsIGFsaXZlLCBkZWF0aF95ciwgCiAgICAgICAgICAgICAgICAgRW5nbGlzaF9zY29yZV9lbGVtZW50YXJ5LCBFbmdsaXNoX3Njb3JlX0p1bmlvcl9IaWdoLCBFbmdsaXNoX3Njb3JlX1Nlbmlvcl9IaWdoLAogICAgICAgICAgICAgICAgIEluZG9uZXNpYV9zY29yZV9lbGVtZW50YXJ5LCBJbmRvbmVzaWFfc2NvcmVfSnVuaW9yX0hpZ2gsIEluZG9uZXNpYV9zY29yZV9TZW5pb3JfSGlnaCwKICAgICAgICAgICAgICAgICBNYXRoX3Njb3JlX2VsZW1lbmF0cnksIE1hdGhfc2NvcmVfSnVuaW9yX0hpZ2gsIE1hdGhfc2NvcmVfU2VuaW9yX0hpZ2gsCiAgICAgICAgICAgICAgICAgZTEsIGMxLCBvMSwgZTJyLCBuMXIsIGExLCBuMiwgbzIsIGMyciwgbzMsIGEyLCBjMywgZTMsIGEzciwgbjMsIGUycl9yZXZlcnNlZCwgYzJyX3JldmVyc2VkLAogICAgICAgICAgICAgICAgIG4xcl9yZXZlcnNlZCwgYTNyX3JldmVyc2VkLAogICAgICAgICAgICAgICAgIHNpMDEgLHNpMDIsIHNpMDMsIHNpMDQsIHNpMDUsIHNpMTEsIHNpMTIsIHNpMTMsIHNpMTQsIHNpMTUKICAgICAgICAgICAgICAgICApLCBmdW5zKGFzLm51bWVyaWMpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoTWF0aF9zY29yZV9oaWdoZXN0X3R5cGUsIFRvdGFsX3Njb3JlX2hpZ2hlc3RfdHlwZSwgbW90aGVyX3BpZGxpbmssIGZhdGhlcl9waWRsaW5rLCBtYXJyaWFnZV9pZCwKICAgICAgICAgICAgICAgICBwaWRsaW5rLCAgcmFuZG9tX3NpLCBTZWN0b3IsIFR5cGVfb2ZfdGVzdF9lbGVtZW50YXJ5LCBUeXBlX29mX3Rlc3RfSnVuaW9yX0hpZ2gsCiAgICAgICAgICAgICAgICAgVHlwZV9vZl90ZXN0X1Nlbmlvcl9IaWdoLCBsaWZlYmlydGhzLCBDYXRlZ29yeQogICAgICAgICAgICAgICAgICksIGZ1bnMoYXMuZmFjdG9yKSkgJT4lIAogIG11dGF0ZShtYWxlID0gaWZfZWxzZShzZXggPT0gMSwgMUwsIDBMKSwKICAgICAgICAgd2FnZV9sYXN0X21vbnRoX2xvZyA9IGxvZyh3YWdlX2xhc3RfbW9udGgrMSksCiAgICAgICAgIHdhZ2VfbGFzdF95ZWFyX2xvZyA9IGxvZyh3YWdlX2xhc3RfeWVhcisxKSwKICAgICAgICAgbW9uZXlfc3BlbnRfc21va2luZ19sb2cgPSBsb2cobW9uZXlfc3BlbnRfc21va2luZysxKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKGFsaXZlLCBFbGVtZW50YXJ5X21pc3NlZCwgRWxlbWVudGFyeV93b3JrZWQsIGV2ZXJfc21va2VkLCBKdW5pb3JfaGlnaF9taXNzZWQsIEp1bmlvcl9oaWdoX3dvcmtlZCwKICAgICAgICAgICAgICAgICBTZWxmX2VtcGxveWVkLCB0b3RhbF9taXNzZWQsIFNlbmlvcl9oaWdoX21pc3NlZCwgU2VuaW9yX2hpZ2hfd29ya2VkLCBzdGlsbF9zbW9raW5nLCBVbml2ZXJzaXR5X21pc3NlZCwKICAgICAgICAgICAgICAgICBVbml2ZXJzaXR5X3dvcmtlZCwgd2F2ZSksIGZ1bnMoYXMuaW50ZWdlcikpICU+JSAKICBtdXRhdGVfYXQodmFycyhiaXJ0aGRhdGUpLCBmdW5zKGFzLkRhdGUpKSAlPiUgCiAgICBzZWxlY3QoLW1vdGhlcklELCAtZmF0aGVySUQsIC1tb3RoZXJfYmlydGhvcmRlciwgLW1vdGhlcl9iaXJ0aGRhdGUsIC1tb250aCwgLWVuZCwgLXN0YXJ0LCAtZ2VuZGVyLCAtc2V4LCAtc2V4XzIwMTVfb2xkLCAtc2V4XzIwMTVfeW91bmcsCiAgICAgICAgICAgLXJlbGF0aW9uX3RvX0hIX2hlYWQsIC15ZWFyc19vZl9lZHVjYXRpb25fZmFjdG9yLCAtYmlydGhkYXRlX2R1cGVkX2luX2VhcmxpZXJfd2F2ZSwgLWJpcnRob3JkZXJfZHVwZWRfaW5fZWFybGllcl93YXZlLCAtYmlydGhvcmRlcl9uYWl2ZV9pbmQsCiAgICAgICAgICAgLW9yZGVyX21hcnJpYWdlLAogICAgICAgICAgIC1hcjA4ZGF5LCAtYXIwOG10aCwgLWFyMDh5ciwgLWJpcnRoX2RheSwgLWJpcnRoX21vbnRoLCAtYmlydGhfeWVhciwgLWhpZ2hlc3RfZ3JhZGUsIC13YWdlX2xhc3RfbW9udGgsIC13YWdlX2xhc3RfeWVhciwgLXN0YXR1cywKICAgICAgICAgICAtbW9uZXlfc3BlbnRfc21va2luZywgLXN0YXJ0c193aXRoKCJoaGlkMTRfIiksIHNjMDUsIHByb3ZpbmNlLCBzYzAxXzE0XzE0KQpgYGAKCiMjIFNhdmUgZGF0YQoKZm9yIGZ1dHVyZSBhbmFseXNlcwoKYGBge3Igc2F2ZSBkYXRhfQphbGxkYXRhX2JpcnRob3JkZXIgPSBhbGxkYXRhX2JpcnRob3JkZXIgJT4lIHVuZ3JvdXAoKQphbGxkYXRhID0gYWxsZGF0YSAlPiUgdW5ncm91cCgpCnByZWduYW5jeSA9IHByZWduYW5jeSAlPiUgdW5ncm91cCgpCmlxID0gaXEgJT4lIHVuZ3JvdXAoKQoKc2F2ZVJEUyhhbGxkYXRhX2JpcnRob3JkZXIsIGZpbGUgPSAiZGF0YS9hbGxkYXRhX2JpcnRob3JkZXIucmRzIikKc2F2ZVJEUyhhbGxkYXRhLCBmaWxlID0gImRhdGEvYWxsZGF0YS5yZHMiKQpzYXZlUkRTKHByZWduYW5jeSwgZmlsZSA9ICJkYXRhL3ByZWduYW5jeS5yZHMiKQpzYXZlUkRTKGlxLCBmaWxlID0gImRhdGEvaXEucmRzIikKYGBgCg==