Last compiled on May, 2025
This is the code with which we make our dependent variables.
Initatiating R
environment
Start out with a custom function to load a set of required
packages.
# packages and read data
rm(list = ls())
# (c) Jochem Tolsma
fpackage.check <- function(packages) {
lapply(packages, FUN = function(x) {
if (!require(x, character.only = TRUE)) {
install.packages(x, dependencies = TRUE)
library(x, character.only = TRUE)
}
})
}
packages = c("haven", "coda", "matrixStats", "parallel", "MASS", "doParallel", "dplyr", "cowplot", "tidyverse",
"naniar", "dotwhisker", "gt", "reshape2", "VGAM", "expss", "networkscaleup")
fpackage.check(packages)
rm(packages)
# repo <- '/yourscratch/' # yourpath
df <- read_dta("data/DQUESTUU_eindbestand.dta")
# personid
dfpid <- read.csv("data/iomatch.csv")
# df <- data.frame(df) nrow(as.matrix(na.omit(df[,c(89:100)]))) # no NAs on the demographic
# variables
Data manipulation
Essentially making the same data frame as the NSUM data frame (that I
didn’t safe at that point). It’s a copy of that code chunk.
#--------------------------------------------------------------------------------
# some data prep
# v1 in data
ref1 <- c(84957, 75214, 145600, 168066, 2500, 29808, 1558549)
# ORDER: uni, hbo, mbo, dochter/zoon, tweeling, randstad, corona
df1_1 <- df[, c(8:14)]
df1_2 <- df[, c(1:7)]
# conditional filling in of zeros when respondents answer 'no' I don't know that person loop of
# collength
for (i in 1:length(df1_2)) {
df1_1[[i]] <- ifelse(df1_2[[i]] == 2, 0, df1_1[[i]])
}
This is the second chunk of the NSUM questions that I make.
#--------------------------------------------------------------------------------
# v2 in data
ref2 <- c(273259, 460618, 261000)
# ORDER: elecauto, scooter, vegan,
df2_1 <- df[, c(18:20)]
df2_2 <- df[, c(15:17)]
# filling of zeros loop of collength
for (i in 1:length(df2_2)) {
df2_1[[i]] <- ifelse(df2_2[[i]] == 2, 0, df2_1[[i]])
}
And this is the third.
#--------------------------------------------------------------------------------
# v3 in data
ref3 <- c(15276, 16350, 27394, 21200, 25681, 334502, 29955, 266522, 39481, 2692, 136296, 110231, 112807,
98208, 1386, 2186, 11640, 22704, 13276, 40543, 17024, 23167, 307032, 36411, 49182, 186746, 35973,
134956, 118610, 86500, 102296, 4213, 5003, 4517)
# ORDER: Sophie, Julia,Sanne,Lisa,Laura,Maria,Linda,Johanna,Monique,Ester,
# Anna,Elisabeth,Cornelia,Wilhelmina,Amira,Samira,Sara,Daan,Sem,
# Thomas,Max,Kevin,Johannes,Dennis,Jeroen,Jan,Marcel,Cornelis,Hendrik,Petrus,
# Willem,Ali,Mohammed,Noor
df3_1 <- df[, c(55:88)]
df3_2 <- df[, c(21:54)]
# filling in of zeros loop of collength
for (i in 1:length(df3_2)) {
df3_1[[i]] <- ifelse(df3_2[[i]] == 2, 0, df3_1[[i]])
}
I then columbind those all together and drop the missing values. This
ultimately leads to the data set that we start out with.
#--------------------------------------------------------------------------------
# now cbind those matrices together
cont <- cbind(df1_1[, c(1, 2, 3, 4, 5, 7)], df2_1, df3_1)
cont <- as.matrix(na.omit(cont)) # nice, only 60 or so missings
pop <- c(ref1[c(1, 2, 3, 4, 5, 7)], ref2, ref3) #without randstad (only 4 grote steden, not 'randstad'), These are the known population sizes
totpop <- 17407585 # Total dutch population in 2020
#--------------------------------------------------------------------------------
# this is important: these are the data we can directly match to, same row order.
df_nomissings <- cbind(df1_2[, c(1, 2, 3, 4, 5, 7)], df1_1[, c(1, 2, 3, 4, 5, 7)], df2_2, df2_1, df3_2,
df3_1, df[, c(89:100)], dfpid[, c(1)]) # loose randstad to get at same N
names(df_nomissings)[99] <- "personid"
df_nomissings <- na.omit(df_nomissings)
I attach a number of substantive columnnames to those such that we
know what is going on.
#--------------------------------------------------------------------------------
# So this is the initial data set we start out with
head(df_nomissings[, c(87:99)])
df_answers1 <- df_nomissings[, c(7:12)]
names(df_answers1) <- c("uni", "hbo", "mbo", "dochterzoon", "tweeling", "corona")
df_answers2 <- df_nomissings[, c(16:18)]
names(df_answers2) <- c("elauto", "scooter", "vegan")
df_answers3 <- df_nomissings[, c(53:86)]
names(df_answers3) <- c("Sophie", "Julia", "Sanne", "Lisa", "Laura", "Maria", "Linda", "Johanna", "Monique",
"Ester", "Anna", "Elisabeth", "Cornelia", "Wilhelmina", "Amira", "Samira", "Sara", "Daan", "Sem",
"Thomas", "Max", "Kevin", "Johannes", "Dennis", "Jeroen", "Jan", "Marcel", "Cornelis", "Hendrik",
"Petrus", "Willem", "Ali", "Mohammed", "Noor")
df_answers <- cbind(df_answers1, df_answers2, df_answers3)
#--------------------------------------------------------------------------------
Data merging
Now it’s time to merge the different NSUM estimates. Note the four
different scenarios that are each loaded into the environment. They each
correspondent to a different tauK scenario.
# let's load the lower tauKs=25
dfl25 <- list()
for (i in 1:43) {
dfl25[[i]] <- read.csv(paste0("data/degree_estimates_tauK025_holdout", i, ".txt"), header = TRUE)
dfl25[[i]][, 1] <- NULL
names(dfl25[[i]]) <- c(paste0("ns25_", i), paste0("se25_", i))
}
dfl25 <- bind_cols(dfl25)
The second match.
#--------------------------------------------------------------------------------
# let's load the lower tauKs=50
dfl50 <- list()
for (i in 1:43) {
dfl50[[i]] <- read.csv(paste0("data/degree_estimates_tauK050_holdout", i, ".txt"), header = TRUE)
dfl50[[i]][, 1] <- NULL
names(dfl50[[i]]) <- c(paste0("ns50_", i), paste0("se50_", i))
}
dfl50 <- bind_cols(dfl50)
The third match.
#--------------------------------------------------------------------------------
# let's load the lower tauKs=75
dfl75 <- list()
for (i in 1:43) {
dfl75[[i]] <- read.csv(paste0("data/degree_estimates_tauK075_holdout", i, ".txt"), header = TRUE)
dfl75[[i]][, 1] <- NULL
names(dfl75[[i]]) <- c(paste0("ns75_", i), paste0("se75_", i))
}
dfl75 <- bind_cols(dfl75)
And finally the fourth match. These are essentially the dependent
variables to our study: the 142 different network size estimates per
individual respondent.
#--------------------------------------------------------------------------------
# let's load the lower tauKs=99
dfl99 <- list()
for (i in 1:43) {
dfl99[[i]] <- read.csv(paste0("data/degree_estimates_tauK075_holdout", i, ".txt"), header = TRUE)
dfl99[[i]][, 1] <- NULL
names(dfl99[[i]]) <- c(paste0("ns99_", i), paste0("se99_", i))
}
dfl99 <- bind_cols(dfl99)
dfs <- cbind(dfl25, dfl50, dfl75, dfl99)
# let's extract the even and odd rows such that we know the standard errors and netsizes
col_odd <- seq_len(ncol(dfs))%%2 # Create column indicator
netsizes <- dfs[, col_odd == 1] # df with netsizes
stanerrs <- dfs[, col_odd == 0] # df with standard errors
write.table(netsizes, file = "data/dutch_netsize_desc.txt")
Note that I made that identifier in a prior page. I now match those
nonmissing demographic variables, the network sizes, and answers to that
identifier on the basis of the identifier that I gave to I&O
research. I know that I don’t have diplicates on my side, so only
looking at the ID 19496, I know that that is a duplicate that I drop
from the rest of the paper. We save the data, and continue with the
independent variables on the next page.
#--------------------------------------------------------------------------------
######################## INPUT NEW IO DATA
df <- cbind(df_nomissings[, c(87:99)], netsizes, df_answers)
# df$personid <- df[,13] df[,13] <- NULL
# input extra info from io here
dfio <- read_spss("data/DQUESTUU_eindbestand_3.sav")
df <- left_join(df, dfio, by = c(personid = "personid"))
# x<-data.frame(table(dfio$personid))
# any doubles?
x <- data.frame(table(df$personid))
x[which.max(x$Freq), ] # --> 19496
df[df$personid == 19496, ]
df <- df[!df$personid == 19496, ]
Naive estimator
So now we want to make a number of variables with the naive NSUM
estimator. This to compare the network sizes across different blocks of
questions and names.
#--------------------------------------------------------------------------------
######################## Get naive scores from three blocks ant total
ref1 <- c(84957, 75214, 145600, 168066, 2500, 1558549)
# 'uni', 'hbo', 'mbo', 'dochterzoon', 'tweeling', 'corona',
ref2 <- c(273259, 460618, 261000)
# 'elauto', 'scooter', 'vegan',
ref3 <- c(15276, 16350, 27394, 21200, 25681, 334502, 29955, 266522, 39481, 2692, 136296, 110231, 112807,
98208, 1386, 2186, 11640, 22704, 13276, 40543, 17024, 23167, 307032, 36411, 49182, 186746, 35973,
134956, 118610, 86500, 102296, 4213, 5003, 4517)
# 'Sophie', 'Julia','Sanne','Lisa','Laura','Maria','Linda','Johanna','Monique','Ester',
# 'Anna','Elisabeth','Cornelia','Wilhelmina','Amira','Samira','Sara','Daan','Sem',
# 'Thomas','Max','Kevin','Johannes','Dennis','Jeroen','Jan','Marcel','Cornelis','Hendrik','Petrus',
# 'Willem','Ali','Mohammed','Noor'
totpop <- 17407585
ref <- c(ref1, ref2, ref3)
naive <- df[, c("uni", "hbo", "mbo", "dochterzoon", "tweeling", "corona", "elauto", "scooter", "vegan",
"Sophie", "Julia", "Sanne", "Lisa", "Laura", "Maria", "Linda", "Johanna", "Monique", "Ester", "Anna",
"Elisabeth", "Cornelia", "Wilhelmina", "Amira", "Samira", "Sara", "Daan", "Sem", "Thomas", "Max",
"Kevin", "Johannes", "Dennis", "Jeroen", "Jan", "Marcel", "Cornelis", "Hendrik", "Petrus", "Willem",
"Ali", "Mohammed", "Noor")]
# naive estimator total
naes <- list()
for (i in 1:length(naive)) {
naes[[i]] <- data.frame((naive[, c(i)]/ref[i]) * totpop)
}
x <- do.call(cbind, naes)
names(x) <- c("uni", "hbo", "mbo", "dochterzoon", "tweeling", "corona", "elauto", "scooter", "vegan",
"Sophie", "Julia", "Sanne", "Lisa", "Laura", "Maria", "Linda", "Johanna", "Monique", "Ester", "Anna",
"Elisabeth", "Cornelia", "Wilhelmina", "Amira", "Samira", "Sara", "Daan", "Sem", "Thomas", "Max",
"Kevin", "Johannes", "Dennis", "Jeroen", "Jan", "Marcel", "Cornelis", "Hendrik", "Petrus", "Willem",
"Ali", "Mohammed", "Noor")
# all
x$nsize_naive <- rowSums(x[, c(1:43)])/43
# block 1
x$nsize_b1 <- (x$uni + x$hbo + x$mbo + x$dochterzoon + x$tweeling + x$corona)/9
# block 2
x$nsize_b2 <- (x$elauto + x$scooter + x$vegan)/3
# block 3
x$nsize_b3 <- rowSums(x[, c(10:43)])/34
# block 1+2
x$nsize_b1b2 <- (x$uni + x$hbo + x$mbo + x$dochterzoon + x$tweeling + x$corona + x$elauto + x$scooter +
x$vegan)/12
# some names 1
x$nsize_n1 <- (x$Sophie + x$Anna + x$Thomas + x$Willem)/4
# some names 2
x$nsize_n2 <- (x$Julia + x$Elisabeth + x$Max + x$Ali)/4
# some names 3
x$nsize_n3 <- (x$Sanne + x$Cornelia + x$Kevin + x$Mohammed)/4
# some names 3
x$nsize_n123 <- (x$Sophie + x$Anna + x$Thomas + x$Willem + x$Julia + x$Elisabeth + x$Max + x$Ali + x$Sanne +
x$Cornelia + x$Kevin + x$Mohammed)/12
# correlations blocks
cor(x$nsize_b1, x$nsize_b2)
cor(x$nsize_b2, x$nsize_b3)
cor(x$nsize_b1, x$nsize_b3)
cor(x$nsize_b1b2, x$nsize_b3)
# correlation names
cor(x$nsize_n1, x$nsize_n2)
cor(x$nsize_n2, x$nsize_n3)
cor(x$nsize_n1, x$nsize_n3)
# correlation with naive
cor(x$nsize_n1, x$nsize_naive)
cor(x$nsize_n2, x$nsize_naive)
cor(x$nsize_n3, x$nsize_naive)
cor(x$nsize_n123, x$nsize_naive)
summary(x$nsize_naive)
summary(x$nsize_b1)
summary(x$nsize_b2)
summary(x$nsize_b1b2)
summary(x$nsize_b3)
summary(x$nsize_n1)
summary(x$nsize_n2)
summary(x$nsize_n3)
summary(x$nsize_n123)
x <- x[, c("nsize_naive", "nsize_b1", "nsize_b2", "nsize_b3", "nsize_b1b2", "nsize_n1", "nsize_n2", "nsize_n3",
"nsize_n123")]
df <- cbind(df, x)
# save data
save(df, file = "data/dutch_netsize_analyses_deps.rda")
# load(file = 'data/dutch_netsize_analyses_deps.rda')
LS0tCnRpdGxlOiAiRGVwZW5kZW50IHZhcmlhYmxlczogUmV2aXNpb24iCiNiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliCmF1dGhvcjogIkJhcyBIb2ZzdHJhIgotLS0KCmBgYHtyLCBnbG9iYWxzZXR0aW5ncywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CmxpYnJhcnkoa25pdHIpCgprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCm9wdHNfY2h1bmskc2V0KHRpZHkub3B0cz1saXN0KHdpZHRoLmN1dG9mZj0xMDApLHRpZHk9VFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsY29tbWVudCA9ICIjPiIsIGNhY2hlPVRSVUUsIGNsYXNzLnNvdXJjZT1jKCJ0ZXN0IiksIGNsYXNzLm91dHB1dD1jKCJ0ZXN0MiIpKQpvcHRpb25zKHdpZHRoID0gMTAwKQpyZ2w6OnNldHVwS25pdHIoKQoKCgpjb2xvcml6ZSA8LSBmdW5jdGlvbih4LCBjb2xvcikge3NwcmludGYoIjxzcGFuIHN0eWxlPSdjb2xvcjogJXM7Jz4lczwvc3Bhbj4iLCBjb2xvciwgeCkgfQoKYGBgCgpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRX0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCd0b3AnLCAncmlnaHQnKSkKI2tsaXBweTo6a2xpcHB5KGNvbG9yID0gJ2RhcmtyZWQnKQoja2xpcHB5OjprbGlwcHkodG9vbHRpcF9tZXNzYWdlID0gJ0NsaWNrIHRvIGNvcHknLCB0b29sdGlwX3N1Y2Nlc3MgPSAnRG9uZScpCmBgYAoKTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCLCAlWScpYAoKPGJyPgoKLS0tLQoKVGhpcyBpcyB0aGUgY29kZSB3aXRoIHdoaWNoIHdlIG1ha2Ugb3VyIGRlcGVuZGVudCB2YXJpYWJsZXMuCgo8YnI+CgotLS0tCgojIEluaXRhdGlhdGluZyBSIGVudmlyb25tZW50CgpTdGFydCBvdXQgd2l0aCBhIGN1c3RvbSBmdW5jdGlvbiB0byBsb2FkIGEgc2V0IG9mIHJlcXVpcmVkIHBhY2thZ2VzLgogIApgYGB7ciBwYWNrLCBldmFsPUZBTFNFfQoKIyBwYWNrYWdlcyBhbmQgcmVhZCBkYXRhCnJtKGxpc3QgPSBscygpKQoKIyAoYykgSm9jaGVtIFRvbHNtYQpmcGFja2FnZS5jaGVjayA8LSBmdW5jdGlvbihwYWNrYWdlcykgewogIGxhcHBseShwYWNrYWdlcywgRlVOID0gZnVuY3Rpb24oeCkgewogICAgaWYgKCFyZXF1aXJlKHgsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsKICAgICAgaW5zdGFsbC5wYWNrYWdlcyh4LCBkZXBlbmRlbmNpZXMgPSBUUlVFKQogICAgICBsaWJyYXJ5KHgsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkKICAgIH0KICB9KQp9CnBhY2thZ2VzID0gYygiaGF2ZW4iLCAiY29kYSIsICJtYXRyaXhTdGF0cyIsICJwYXJhbGxlbCIsICJNQVNTIiwgImRvUGFyYWxsZWwiLCAiZHBseXIiLCAiY293cGxvdCIsIAogICAgICAgICAgICAgInRpZHl2ZXJzZSIsICJuYW5pYXIiLCAiZG90d2hpc2tlciIgLCJndCIsICJyZXNoYXBlMiIsICJWR0FNIiwgImV4cHNzIiwgIm5ldHdvcmtzY2FsZXVwIikKZnBhY2thZ2UuY2hlY2socGFja2FnZXMpCnJtKHBhY2thZ2VzKQoKI3JlcG8gPC0gIi95b3Vyc2NyYXRjaC8iICMgeW91cnBhdGgKZGYgPC0gcmVhZF9kdGEoImRhdGEvRFFVRVNUVVVfZWluZGJlc3RhbmQuZHRhIikKCiMgcGVyc29uaWQKZGZwaWQgPC0gcmVhZC5jc3YoImRhdGEvaW9tYXRjaC5jc3YiKQoKI2RmIDwtIGRhdGEuZnJhbWUoZGYpCiNucm93KGFzLm1hdHJpeChuYS5vbWl0KGRmWyxjKDg5OjEwMCldKSkpICMgbm8gTkFzIG9uIHRoZSBkZW1vZ3JhcGhpYyB2YXJpYWJsZXMKYGBgCgo8YnI+CgotLS0tCgojIERhdGEgbWFuaXB1bGF0aW9uCgpFc3NlbnRpYWxseSBtYWtpbmcgdGhlIHNhbWUgZGF0YSBmcmFtZSBhcyB0aGUgTlNVTSBkYXRhIGZyYW1lICh0aGF0IEkgZGlkbid0IHNhZmUgYXQgdGhhdCBwb2ludCkuIEl0J3MgYSBjb3B5IG9mIHRoYXQgY29kZSBjaHVuay4KCgoKYGBge3IgbWFuaTEsIGV2YWw9RkFMU0V9CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHNvbWUgZGF0YSBwcmVwCgojdjEgaW4gZGF0YQpyZWYxIDwtIGMoODQ5NTcsIDc1MjE0LCAxNDU2MDAsIDE2ODA2NiwgMjUwMCwgMjk4MDgsIDE1NTg1NDkpCiMgT1JERVI6ICB1bmksIGhibywgbWJvLCBkb2NodGVyL3pvb24sIHR3ZWVsaW5nLCByYW5kc3RhZCwgY29yb25hCmRmMV8xIDwtIGRmWywgYyg4OjE0KV0KZGYxXzIgPC0gZGZbLCBjKDE6NyldCgojIGNvbmRpdGlvbmFsIGZpbGxpbmcgaW4gb2YgemVyb3Mgd2hlbiByZXNwb25kZW50cyBhbnN3ZXIgIm5vIiBJIGRvbid0IGtub3cgdGhhdCBwZXJzb24KZm9yIChpIGluIDE6bGVuZ3RoKGRmMV8yKSl7ICMgbG9vcCBvZiBjb2xsZW5ndGgKICBkZjFfMVtbaV1dIDwtIGlmZWxzZShkZjFfMltbaV1dID09IDIsIDAsIGRmMV8xW1tpXV0pCn0KYGBgCgpUaGlzIGlzIHRoZSBzZWNvbmQgY2h1bmsgb2YgdGhlIE5TVU0gcXVlc3Rpb25zIHRoYXQgSSBtYWtlLgoKYGBge3IgbWFuaTIsIGV2YWw9RkFMU0V9CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojdjIgaW4gZGF0YQpyZWYyIDwtIGMoMjczMjU5LCA0NjA2MTgsIDI2MTAwMCkKIyBPUkRFUjogICBlbGVjYXV0bywgc2Nvb3RlciwgdmVnYW4sCmRmMl8xIDwtIGRmWywgYygxODoyMCldCmRmMl8yIDwtIGRmWywgYygxNToxNyldCgojIGZpbGxpbmcgb2YgemVyb3MKZm9yIChpIGluIDE6bGVuZ3RoKGRmMl8yKSl7ICMgbG9vcCBvZiBjb2xsZW5ndGgKICBkZjJfMVtbaV1dIDwtIGlmZWxzZShkZjJfMltbaV1dID09IDIsIDAsIGRmMl8xW1tpXV0pCn0KYGBgCgpBbmQgdGhpcyBpcyB0aGUgdGhpcmQuCgpgYGB7ciBtYW5pMywgZXZhbD1GQUxTRX0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiN2MyBpbiBkYXRhCnJlZjMgPC0gYygxNTI3NiwxNjM1MCwyNzM5NCwyMTIwMCwyNTY4MSwzMzQ1MDIsMjk5NTUsMjY2NTIyLDM5NDgxLCAyNjkyLAogICAgICAgICAgMTM2Mjk2LDExMDIzMSwxMTI4MDcsOTgyMDgsMTM4NiwyMTg2LDExNjQwLDIyNzA0LDEzMjc2LAogICAgICAgICAgNDA1NDMsMTcwMjQsMjMxNjcsMzA3MDMyLDM2NDExLDQ5MTgyLDE4Njc0NiwzNTk3MywxMzQ5NTYsMTE4NjEwLDg2NTAwLAogICAgICAgICAgMTAyMjk2LDQyMTMsNTAwMyw0NTE3KQojIE9SREVSOiAgIFNvcGhpZSwgSnVsaWEsU2FubmUsTGlzYSxMYXVyYSxNYXJpYSxMaW5kYSxKb2hhbm5hLE1vbmlxdWUsRXN0ZXIsCiMgICAgICAgICAgICAgQW5uYSxFbGlzYWJldGgsQ29ybmVsaWEsV2lsaGVsbWluYSxBbWlyYSxTYW1pcmEsU2FyYSxEYWFuLFNlbSwKIyAgICAgICAgICAgICBUaG9tYXMsTWF4LEtldmluLEpvaGFubmVzLERlbm5pcyxKZXJvZW4sSmFuLE1hcmNlbCxDb3JuZWxpcyxIZW5kcmlrLFBldHJ1cywKIyAgICAgICAgICAgICBXaWxsZW0sQWxpLE1vaGFtbWVkLE5vb3IKCmRmM18xIDwtIGRmWywgYyg1NTo4OCldCmRmM18yIDwtIGRmWywgYygyMTo1NCldCgojIGZpbGxpbmcgaW4gb2YgemVyb3MKZm9yIChpIGluIDE6bGVuZ3RoKGRmM18yKSl7ICMgbG9vcCBvZiBjb2xsZW5ndGgKICBkZjNfMVtbaV1dIDwtIGlmZWxzZShkZjNfMltbaV1dID09IDIsIDAsIGRmM18xW1tpXV0pCn0KYGBgCgpJIHRoZW4gY29sdW1iaW5kIHRob3NlIGFsbCB0b2dldGhlciBhbmQgZHJvcCB0aGUgbWlzc2luZyB2YWx1ZXMuIFRoaXMgdWx0aW1hdGVseSBsZWFkcyB0byB0aGUgZGF0YSBzZXQgdGhhdCB3ZSBzdGFydCBvdXQgd2l0aC4KCmBgYHtyIG1hbmk0LCBldmFsPUZBTFNFfQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBub3cgY2JpbmQgdGhvc2UgbWF0cmljZXMgdG9nZXRoZXIKY29udCA8LSBjYmluZChkZjFfMVssIGMoMSwyLDMsNCw1LDcpXSwgZGYyXzEsIGRmM18xKQpjb250IDwtIGFzLm1hdHJpeChuYS5vbWl0KGNvbnQpKSAjIG5pY2UsIG9ubHkgNjAgb3Igc28gbWlzc2luZ3MKcG9wIDwtIGMocmVmMVtjKDEsMiwzLDQsNSw3KV0sIHJlZjIsIHJlZjMpICN3aXRob3V0IHJhbmRzdGFkIChvbmx5IDQgZ3JvdGUgc3RlZGVuLCBub3QgInJhbmRzdGFkIiksIFRoZXNlIGFyZSB0aGUga25vd24gcG9wdWxhdGlvbiBzaXplcyAKdG90cG9wIDwtIDE3NDA3NTg1ICMgVG90YWwgZHV0Y2ggcG9wdWxhdGlvbiBpbiAyMDIwCgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGhpcyBpcyBpbXBvcnRhbnQ6IHRoZXNlIGFyZSB0aGUgZGF0YSB3ZSBjYW4gZGlyZWN0bHkgbWF0Y2ggdG8sIHNhbWUgcm93IG9yZGVyLgpkZl9ub21pc3NpbmdzIDwtIGNiaW5kKGRmMV8yWywgYygxLDIsMyw0LDUsNyldLCBkZjFfMVssIGMoMSwyLDMsNCw1LDcpXSwgZGYyXzIsIGRmMl8xLCBkZjNfMiwgZGYzXzEsIGRmWywgYyg4OToxMDApXSwgZGZwaWRbLCBjKDEpXSkgIyBsb29zZSByYW5kc3RhZCB0byBnZXQgYXQgc2FtZSBOCm5hbWVzKGRmX25vbWlzc2luZ3MpWzk5XSA8LSAicGVyc29uaWQiCmRmX25vbWlzc2luZ3MgPC0gbmEub21pdChkZl9ub21pc3NpbmdzKQpgYGAKCkkgYXR0YWNoIGEgbnVtYmVyIG9mIHN1YnN0YW50aXZlIGNvbHVtbm5hbWVzIHRvIHRob3NlIHN1Y2ggdGhhdCB3ZSBrbm93IHdoYXQgaXMgZ29pbmcgb24uCgpgYGB7ciBtYW5pNSwgZXZhbD1GQUxTRX0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIFNvIHRoaXMgaXMgdGhlIGluaXRpYWwgZGF0YSBzZXQgd2Ugc3RhcnQgb3V0IHdpdGgKaGVhZChkZl9ub21pc3NpbmdzWyxjKDg3Ojk5KV0pCgpkZl9hbnN3ZXJzMSA8LSBkZl9ub21pc3NpbmdzWyxjKDc6MTIpXQpuYW1lcyhkZl9hbnN3ZXJzMSkgPC0gYygidW5pIiwgImhibyIsICJtYm8iLCAiZG9jaHRlcnpvb24iLCAidHdlZWxpbmciLCAiY29yb25hIikKCmRmX2Fuc3dlcnMyIDwtIGRmX25vbWlzc2luZ3NbLGMoMTY6MTgpXQpuYW1lcyhkZl9hbnN3ZXJzMikgPC0gYygiZWxhdXRvIiwgInNjb290ZXIiLCAidmVnYW4iKQoKZGZfYW5zd2VyczMgPC0gZGZfbm9taXNzaW5nc1ssYyg1Mzo4NildCm5hbWVzKGRmX2Fuc3dlcnMzKSA8LSBjKCJTb3BoaWUiLCAiSnVsaWEiLCJTYW5uZSIsIkxpc2EiLCJMYXVyYSIsIk1hcmlhIiwiTGluZGEiLCJKb2hhbm5hIiwiTW9uaXF1ZSIsIkVzdGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICJBbm5hIiwiRWxpc2FiZXRoIiwiQ29ybmVsaWEiLCJXaWxoZWxtaW5hIiwiQW1pcmEiLCJTYW1pcmEiLCJTYXJhIiwiRGFhbiIsIlNlbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiVGhvbWFzIiwiTWF4IiwiS2V2aW4iLCJKb2hhbm5lcyIsIkRlbm5pcyIsIkplcm9lbiIsIkphbiIsIk1hcmNlbCIsIkNvcm5lbGlzIiwiSGVuZHJpayIsIlBldHJ1cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIldpbGxlbSIsIkFsaSIsIk1vaGFtbWVkIiwiTm9vciIpCmRmX2Fuc3dlcnMgPC0gY2JpbmQoZGZfYW5zd2VyczEsIGRmX2Fuc3dlcnMyLCBkZl9hbnN3ZXJzMykKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGAKCjxicj4KCi0tLS0KCiMgRGF0YSBtZXJnaW5nCgpOb3cgaXQncyB0aW1lIHRvIG1lcmdlIHRoZSBkaWZmZXJlbnQgTlNVTSBlc3RpbWF0ZXMuIE5vdGUgdGhlIGZvdXIgZGlmZmVyZW50IHNjZW5hcmlvcyB0aGF0IGFyZSBlYWNoIGxvYWRlZCBpbnRvIHRoZSBlbnZpcm9ubWVudC4gVGhleSBlYWNoIGNvcnJlc3BvbmRlbnQgdG8gYSBkaWZmZXJlbnQgdGF1SyBzY2VuYXJpby4KCmBgYHtyIG1hdGNoMSwgZXZhbD1GQUxTRX0KIyBsZXQncyBsb2FkIHRoZSBsb3dlciB0YXVLcz0yNQpkZmwyNSA8LSBsaXN0KCkKZm9yIChpIGluIDE6NDMpIHsKICAKICBkZmwyNVtbaV1dIDwtIHJlYWQuY3N2KHBhc3RlMCgiZGF0YS9kZWdyZWVfZXN0aW1hdGVzX3RhdUswMjVfaG9sZG91dCIsIGksICIudHh0IiksIGhlYWRlciA9IFRSVUUpCiAgZGZsMjVbW2ldXVssMV0gPC0gTlVMTAogIG5hbWVzKGRmbDI1W1tpXV0pIDwtIGMocGFzdGUwKCJuczI1XyIsIGkpLCBwYXN0ZTAoInNlMjVfIiwgaSApKQogIAp9CmRmbDI1IDwtIGJpbmRfY29scyhkZmwyNSkKYGBgCgpUaGUgc2Vjb25kIG1hdGNoLgoKYGBge3IgbWF0Y2gyLCBldmFsPUZBTFNFfQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgbGV0J3MgbG9hZCB0aGUgbG93ZXIgdGF1S3M9NTAKZGZsNTAgPC0gbGlzdCgpCmZvciAoaSBpbiAxOjQzKSB7CiAgCiAgZGZsNTBbW2ldXSA8LSByZWFkLmNzdihwYXN0ZTAoImRhdGEvZGVncmVlX2VzdGltYXRlc190YXVLMDUwX2hvbGRvdXQiLCBpLCAiLnR4dCIpLCBoZWFkZXIgPSBUUlVFKQogIGRmbDUwW1tpXV1bLDFdIDwtIE5VTEwKICBuYW1lcyhkZmw1MFtbaV1dKSA8LSBjKHBhc3RlMCgibnM1MF8iLCBpKSwgcGFzdGUwKCJzZTUwXyIsIGkgKSkKICAKfQpkZmw1MCA8LSBiaW5kX2NvbHMoZGZsNTApCgpgYGAKClRoZSB0aGlyZCBtYXRjaC4KCmBgYHtyIG1hdGNoMywgZXZhbD1GQUxTRX0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIGxldCdzIGxvYWQgdGhlIGxvd2VyIHRhdUtzPTc1CmRmbDc1IDwtIGxpc3QoKQpmb3IgKGkgaW4gMTo0MykgewogIAogIGRmbDc1W1tpXV0gPC0gcmVhZC5jc3YocGFzdGUwKCJkYXRhL2RlZ3JlZV9lc3RpbWF0ZXNfdGF1SzA3NV9ob2xkb3V0IiwgaSwgIi50eHQiKSwgaGVhZGVyID0gVFJVRSkKICBkZmw3NVtbaV1dWywxXSA8LSBOVUxMCiAgbmFtZXMoZGZsNzVbW2ldXSkgPC0gYyhwYXN0ZTAoIm5zNzVfIiwgaSksIHBhc3RlMCgic2U3NV8iLCBpICkpCiAgCn0KZGZsNzUgPC0gYmluZF9jb2xzKGRmbDc1KQoKYGBgCgpBbmQgZmluYWxseSB0aGUgZm91cnRoIG1hdGNoLiBUaGVzZSBhcmUgZXNzZW50aWFsbHkgdGhlIGRlcGVuZGVudCB2YXJpYWJsZXMgdG8gb3VyIHN0dWR5OiB0aGUgMTQyIGRpZmZlcmVudCBuZXR3b3JrIHNpemUgZXN0aW1hdGVzIHBlciBpbmRpdmlkdWFsIHJlc3BvbmRlbnQuCgpgYGB7ciBtYXRjaDQsIGV2YWw9RkFMU0V9CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyBsZXQncyBsb2FkIHRoZSBsb3dlciB0YXVLcz05OQpkZmw5OSA8LSBsaXN0KCkKZm9yIChpIGluIDE6NDMpIHsKICAKICBkZmw5OVtbaV1dIDwtIHJlYWQuY3N2KHBhc3RlMCgiZGF0YS9kZWdyZWVfZXN0aW1hdGVzX3RhdUswNzVfaG9sZG91dCIsIGksICIudHh0IiksIGhlYWRlciA9IFRSVUUpCiAgZGZsOTlbW2ldXVssMV0gPC0gTlVMTAogIG5hbWVzKGRmbDk5W1tpXV0pIDwtIGMocGFzdGUwKCJuczk5XyIsIGkpLCBwYXN0ZTAoInNlOTlfIiwgaSApKQogIAp9CmRmbDk5IDwtIGJpbmRfY29scyhkZmw5OSkKZGZzIDwtIGNiaW5kKGRmbDI1LCBkZmw1MCwgZGZsNzUsIGRmbDk5KQoKCiMgbGV0J3MgZXh0cmFjdCB0aGUgZXZlbiBhbmQgb2RkIHJvd3Mgc3VjaCB0aGF0IHdlIGtub3cgdGhlIHN0YW5kYXJkIGVycm9ycyBhbmQgbmV0c2l6ZXMKY29sX29kZCA8LSBzZXFfbGVuKG5jb2woZGZzKSkgJSUgMiAgICAgICAgICAgICAgIyBDcmVhdGUgY29sdW1uIGluZGljYXRvcgpuZXRzaXplcyA8LSBkZnNbLCBjb2xfb2RkID09IDFdICMgZGYgd2l0aCBuZXRzaXplcwpzdGFuZXJycyA8LSBkZnNbLCBjb2xfb2RkID09IDBdICMgZGYgd2l0aCBzdGFuZGFyZCBlcnJvcnMKd3JpdGUudGFibGUobmV0c2l6ZXMsIGZpbGUgPSAiZGF0YS9kdXRjaF9uZXRzaXplX2Rlc2MudHh0IikKYGBgCgpOb3RlIHRoYXQgSSBtYWRlIHRoYXQgaWRlbnRpZmllciBpbiBhIHByaW9yIHBhZ2UuIEkgbm93IG1hdGNoIHRob3NlIG5vbm1pc3NpbmcgZGVtb2dyYXBoaWMgdmFyaWFibGVzLCB0aGUgbmV0d29yayBzaXplcywgYW5kIGFuc3dlcnMgdG8gdGhhdCBpZGVudGlmaWVyIG9uIHRoZSBiYXNpcyBvZiB0aGUgaWRlbnRpZmllciB0aGF0IEkgZ2F2ZSB0byBJJk8gcmVzZWFyY2guIEkga25vdyB0aGF0IEkgZG9uJ3QgaGF2ZSBkaXBsaWNhdGVzIG9uIG15IHNpZGUsIHNvIG9ubHkgbG9va2luZyBhdCB0aGUgSUQgMTk0OTYsIEkga25vdyB0aGF0IHRoYXQgaXMgYSBkdXBsaWNhdGUgdGhhdCBJIGRyb3AgZnJvbSB0aGUgcmVzdCBvZiB0aGUgcGFwZXIuIFdlIHNhdmUgdGhlIGRhdGEsIGFuZCBjb250aW51ZSB3aXRoIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgb24gdGhlIG5leHQgcGFnZS4KCmBgYHtyIG1hdGNoNSwgZXZhbD1GQUxTRX0gICAgICAgICAgCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBJTlBVVCBORVcgSU8gREFUQQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCgpkZiA8LSBjYmluZChkZl9ub21pc3NpbmdzWyxjKDg3Ojk5KV0sIG5ldHNpemVzLCBkZl9hbnN3ZXJzKQojZGYkcGVyc29uaWQgPC0gZGZbLDEzXQojZGZbLDEzXSA8LSBOVUxMCgojIGlucHV0IGV4dHJhIGluZm8gZnJvbSBpbyBoZXJlCmRmaW8gPC0gcmVhZF9zcHNzKCJkYXRhL0RRVUVTVFVVX2VpbmRiZXN0YW5kXzMuc2F2IikKCmRmIDwtIGxlZnRfam9pbihkZiwgZGZpbywgYnkgPSBjKCJwZXJzb25pZCIgPSAicGVyc29uaWQiKSkKCiN4PC1kYXRhLmZyYW1lKHRhYmxlKGRmaW8kcGVyc29uaWQpKQoKIyBhbnkgZG91Ymxlcz8KeDwtZGF0YS5mcmFtZSh0YWJsZShkZiRwZXJzb25pZCkpCnhbd2hpY2gubWF4KHgkRnJlcSksIF0gIyAtLT4gMTk0OTYKCmRmW2RmJHBlcnNvbmlkID09IDE5NDk2LCBdCmRmIDwtIGRmWyFkZiRwZXJzb25pZCA9PSAxOTQ5NiwgXQpgYGAKCjxicj4KCi0tLS0KCiMgTmFpdmUgZXN0aW1hdG9yCgpTbyBub3cgd2Ugd2FudCB0byBtYWtlIGEgbnVtYmVyIG9mIHZhcmlhYmxlcyB3aXRoIHRoZSBuYWl2ZSBOU1VNIGVzdGltYXRvci4gVGhpcyB0byBjb21wYXJlIHRoZSBuZXR3b3JrIHNpemVzIGFjcm9zcyBkaWZmZXJlbnQgYmxvY2tzIG9mIHF1ZXN0aW9ucyBhbmQgbmFtZXMuCgoKYGBge3IgbmFpdmUsICBldmFsPUZBTFNFfQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR2V0IG5haXZlIHNjb3JlcyBmcm9tIHRocmVlIGJsb2NrcyBhbnQgdG90YWwKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpyZWYxIDwtIGMoODQ5NTcsIDc1MjE0LCAxNDU2MDAsIDE2ODA2NiwgMjUwMCwgMTU1ODU0OSkKIyAidW5pIiwgImhibyIsICJtYm8iLCAiZG9jaHRlcnpvb24iLCAidHdlZWxpbmciLCAiY29yb25hIiwgCnJlZjIgPC0gYygyNzMyNTksIDQ2MDYxOCwgMjYxMDAwKQojICAgImVsYXV0byIsICJzY29vdGVyIiwgInZlZ2FuIiwgCnJlZjMgPC0gYygxNTI3NiwxNjM1MCwyNzM5NCwyMTIwMCwyNTY4MSwzMzQ1MDIsMjk5NTUsMjY2NTIyLDM5NDgxLCAyNjkyLAogICAgICAgICAgMTM2Mjk2LDExMDIzMSwxMTI4MDcsOTgyMDgsMTM4NiwyMTg2LDExNjQwLDIyNzA0LDEzMjc2LAogICAgICAgICAgNDA1NDMsMTcwMjQsMjMxNjcsMzA3MDMyLDM2NDExLDQ5MTgyLDE4Njc0NiwzNTk3MywxMzQ5NTYsMTE4NjEwLDg2NTAwLAogICAgICAgICAgMTAyMjk2LDQyMTMsNTAwMyw0NTE3KQojICJTb3BoaWUiLCAiSnVsaWEiLCJTYW5uZSIsIkxpc2EiLCJMYXVyYSIsIk1hcmlhIiwiTGluZGEiLCJKb2hhbm5hIiwiTW9uaXF1ZSIsIkVzdGVyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgIkFubmEiLCJFbGlzYWJldGgiLCJDb3JuZWxpYSIsIldpbGhlbG1pbmEiLCJBbWlyYSIsIlNhbWlyYSIsIlNhcmEiLCJEYWFuIiwiU2VtIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgIlRob21hcyIsIk1heCIsIktldmluIiwiSm9oYW5uZXMiLCJEZW5uaXMiLCJKZXJvZW4iLCJKYW4iLCJNYXJjZWwiLCJDb3JuZWxpcyIsIkhlbmRyaWsiLCJQZXRydXMiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgIldpbGxlbSIsIkFsaSIsIk1vaGFtbWVkIiwiTm9vciIKdG90cG9wIDwtIDE3NDA3NTg1IApyZWYgPC0gYyhyZWYxLCByZWYyLCByZWYzKQpuYWl2ZSA8LSBkZlssIGMoInVuaSIsICJoYm8iLCAibWJvIiwgImRvY2h0ZXJ6b29uIiwgInR3ZWVsaW5nIiwgImNvcm9uYSIsIAogICAgICAgICAgICAgICJlbGF1dG8iLCAic2Nvb3RlciIsICJ2ZWdhbiIsIAogICAgICAgICAgICAgICJTb3BoaWUiLCAiSnVsaWEiLCJTYW5uZSIsIkxpc2EiLCJMYXVyYSIsIk1hcmlhIiwiTGluZGEiLCJKb2hhbm5hIiwiTW9uaXF1ZSIsIkVzdGVyIiwKICAgICAgICAgICAgICAiQW5uYSIsIkVsaXNhYmV0aCIsIkNvcm5lbGlhIiwiV2lsaGVsbWluYSIsIkFtaXJhIiwiU2FtaXJhIiwiU2FyYSIsIkRhYW4iLCJTZW0iLAogICAgICAgICAgICAgICJUaG9tYXMiLCJNYXgiLCJLZXZpbiIsIkpvaGFubmVzIiwiRGVubmlzIiwiSmVyb2VuIiwiSmFuIiwiTWFyY2VsIiwiQ29ybmVsaXMiLCJIZW5kcmlrIiwiUGV0cnVzIiwKICAgICAgICAgICAgICAiV2lsbGVtIiwiQWxpIiwiTW9oYW1tZWQiLCJOb29yIildCgoKCiMgbmFpdmUgZXN0aW1hdG9yIHRvdGFsICAgICAgICAgICAgCm5hZXMgPC0gbGlzdCgpICAgICAgIApmb3IgKGkgaW4gMTpsZW5ndGgobmFpdmUpKSB7CiAgCiAgICBuYWVzW1tpXV0gPC0gZGF0YS5mcmFtZSgobmFpdmVbLCBjKGkpXS9yZWZbaV0pKnRvdHBvcCkKCn0KeCA8LSBkby5jYWxsKGNiaW5kLCBuYWVzKQpuYW1lcyh4KSA8LSBjKCJ1bmkiLCAiaGJvIiwgIm1ibyIsICJkb2NodGVyem9vbiIsICJ0d2VlbGluZyIsICJjb3JvbmEiLCAKICAgICAgICAgICAgICAiZWxhdXRvIiwgInNjb290ZXIiLCAidmVnYW4iLCAKICAgICAgICAgICAgICAiU29waGllIiwgIkp1bGlhIiwiU2FubmUiLCJMaXNhIiwiTGF1cmEiLCJNYXJpYSIsIkxpbmRhIiwiSm9oYW5uYSIsIk1vbmlxdWUiLCJFc3RlciIsCiAgICAgICAgICAgICAgIkFubmEiLCJFbGlzYWJldGgiLCJDb3JuZWxpYSIsIldpbGhlbG1pbmEiLCJBbWlyYSIsIlNhbWlyYSIsIlNhcmEiLCJEYWFuIiwiU2VtIiwKICAgICAgICAgICAgICAiVGhvbWFzIiwiTWF4IiwiS2V2aW4iLCJKb2hhbm5lcyIsIkRlbm5pcyIsIkplcm9lbiIsIkphbiIsIk1hcmNlbCIsIkNvcm5lbGlzIiwiSGVuZHJpayIsIlBldHJ1cyIsCiAgICAgICAgICAgICAgIldpbGxlbSIsIkFsaSIsIk1vaGFtbWVkIiwiTm9vciIpCgojIGFsbAp4JG5zaXplX25haXZlIDwtIHJvd1N1bXMoeFsgLGMoMTo0MyldICkgLyA0MwoKIyBibG9jayAxCngkbnNpemVfYjEgPC0gKHgkdW5pICsgeCRoYm8gKyB4JG1ibyArIHgkZG9jaHRlcnpvb24gKyB4JHR3ZWVsaW5nICsgeCRjb3JvbmEpIC8gOQoKIyBibG9jayAyCngkbnNpemVfYjIgPC0gKHgkZWxhdXRvICsgeCRzY29vdGVyICsgeCR2ZWdhbikgLyAzCgojIGJsb2NrIDMKeCRuc2l6ZV9iMyA8LSByb3dTdW1zKHhbICxjKDEwOjQzKV0gKSAvIDM0CgojIGJsb2NrIDErMgp4JG5zaXplX2IxYjIgPC0gKHgkdW5pICsgeCRoYm8gKyB4JG1ibyArIHgkZG9jaHRlcnpvb24gKyB4JHR3ZWVsaW5nICsgeCRjb3JvbmEgK3gkZWxhdXRvICsgeCRzY29vdGVyICsgeCR2ZWdhbikgLyAxMgoKIyBzb21lIG5hbWVzIDEKeCRuc2l6ZV9uMSA8LSAoeCRTb3BoaWUgKyB4JEFubmEgKyB4JFRob21hcyArIHgkV2lsbGVtICkgLyA0CgojIHNvbWUgbmFtZXMgMgp4JG5zaXplX24yIDwtICh4JEp1bGlhICsgeCRFbGlzYWJldGggKyB4JE1heCArIHgkQWxpICkgLyA0CgojIHNvbWUgbmFtZXMgMwp4JG5zaXplX24zIDwtICh4JFNhbm5lICsgeCRDb3JuZWxpYSArIHgkS2V2aW4gKyB4JE1vaGFtbWVkICkgLzQKCiMgc29tZSBuYW1lcyAzCngkbnNpemVfbjEyMyA8LSAoeCRTb3BoaWUgKyB4JEFubmEgKyB4JFRob21hcyArIHgkV2lsbGVtICsgeCRKdWxpYSArIHgkRWxpc2FiZXRoICsgeCRNYXggKyB4JEFsaSArIHgkU2FubmUgKyB4JENvcm5lbGlhICsgeCRLZXZpbiArIHgkTW9oYW1tZWQgKSAvIDEyCgoKIyBjb3JyZWxhdGlvbnMgYmxvY2tzCmNvcih4JG5zaXplX2IxLCB4JG5zaXplX2IyKQpjb3IoeCRuc2l6ZV9iMiwgeCRuc2l6ZV9iMykKY29yKHgkbnNpemVfYjEsIHgkbnNpemVfYjMpCmNvcih4JG5zaXplX2IxYjIsIHgkbnNpemVfYjMpCgojIGNvcnJlbGF0aW9uIG5hbWVzCmNvcih4JG5zaXplX24xLCB4JG5zaXplX24yKQpjb3IoeCRuc2l6ZV9uMiwgeCRuc2l6ZV9uMykKY29yKHgkbnNpemVfbjEsIHgkbnNpemVfbjMpCgojIGNvcnJlbGF0aW9uIHdpdGggbmFpdmUKY29yKHgkbnNpemVfbjEsIHgkbnNpemVfbmFpdmUpCmNvcih4JG5zaXplX24yLCB4JG5zaXplX25haXZlKQpjb3IoeCRuc2l6ZV9uMywgeCRuc2l6ZV9uYWl2ZSkKY29yKHgkbnNpemVfbjEyMywgeCRuc2l6ZV9uYWl2ZSkKCnN1bW1hcnkoeCRuc2l6ZV9uYWl2ZSkKCnN1bW1hcnkoeCRuc2l6ZV9iMSkKc3VtbWFyeSh4JG5zaXplX2IyKQpzdW1tYXJ5KHgkbnNpemVfYjFiMikKc3VtbWFyeSh4JG5zaXplX2IzKQoKc3VtbWFyeSh4JG5zaXplX24xKQpzdW1tYXJ5KHgkbnNpemVfbjIpCnN1bW1hcnkoeCRuc2l6ZV9uMykKc3VtbWFyeSh4JG5zaXplX24xMjMpCgp4IDwtIHhbLCBjKCJuc2l6ZV9uYWl2ZSIsICJuc2l6ZV9iMSIsICJuc2l6ZV9iMiIsICJuc2l6ZV9iMyIsICJuc2l6ZV9iMWIyIiwgIm5zaXplX24xIiwgIm5zaXplX24yIiwgIm5zaXplX24zIiwgIm5zaXplX24xMjMiKV0KCmRmIDwtIGNiaW5kKGRmLCB4KQoKYGBgCgoKCgpgYGB7ciBzYXZlLCAgZXZhbD1GQUxTRX0KIyBzYXZlIGRhdGEKc2F2ZShkZiwgZmlsZSA9ICJkYXRhL2R1dGNoX25ldHNpemVfYW5hbHlzZXNfZGVwcy5yZGEiKQoKCiNsb2FkKGZpbGUgPSAiZGF0YS9kdXRjaF9uZXRzaXplX2FuYWx5c2VzX2RlcHMucmRhIikKCmBgYAoKCg==