This lab journal replicates the analyses for ‘starting to publish’.


Custom functions

  • fpackage.check: Check if packages are installed (and install if not) in R (source).

  • ddlogis: double derivative function for calculating marginal interaction effects (source).

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)
        }
    })
}


fsave <- function(x, file, location = "./data/processed/") {
    datename <- substr(gsub("[:-]", "", Sys.time()), 1, 8)
    totalname <- paste(location, datename, file, sep = "")
    save(x, file = totalname)
}

ddlogis <- function(X) {
    -(exp(-X)/(1 + exp(-X))^2 - exp(-X) * (2 * (exp(-X) * (1 + exp(-X))))/((1 + exp(-X))^2)^2)
}

Packages

  • tidyverse: for data manipulation
  • ggplot2: for creating figures 2-4
  • ggpubr: for combining two figures in one (plot 2)
  • splines splines2: for modelling non-linear cohort relations
  • boot: bootstrapping for SEs of AMEs
  • kableExtra: formatting tables
packages = c("tidyverse", "ggplot2", "ggpubr", "splines", "splines2", "boot", "kableExtra")

fpackage.check(packages)

Input

We use one processed dataset.

load(file = "./data/processed/df_starting.rda")

We use logistic regressions to predict whether an individual has a personal NARCIS profile and at least one publication

Model 1: Gender

M1 <- glm(start_pub ~ gender, data = df_starting, family = binomial)

summary(M1)
#> 
#> Call:
#> glm(formula = start_pub ~ gender, family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -0.7042  -0.6901  -0.6901  -0.5089   2.0533  
#> 
#> Coefficients:
#>               Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)   -1.31354    0.01350 -97.298   <2e-16 ***
#> genderwomen    0.04566    0.02043   2.235   0.0254 *  
#> gendermissing -0.66502    0.02270 -29.294   <2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 80858  on 85785  degrees of freedom
#> AIC: 80864
#> 
#> Number of Fisher Scoring iterations: 4

Average marginal effects (AMEs)

bootFunc <- function(data, i) {
    df <- data[i, ]  #bootstrap datasets

    M <- glm(start_pub ~ gender, family = binomial, data = df)

    suppressWarnings({

        # ME gender
        dfs0 <- dfs1 <- df
        dfs0$gender <- "men"
        dfs1$gender <- "women"
        dfs1$gender <- factor(dfs1$gender, levels = levels(df$gender))
        dfs0$gender <- factor(dfs0$gender, levels = levels(df$gender))

        # calculate the predicted probabilities
        p1 <- predict(M, type = "response", newdata = dfs1)
        p0 <- predict(M, type = "response", newdata = dfs0)

        # and the marginal effects
        AME_gender <- mean(p1 - p0)

    })

    AME_gender  #save results
}

b1 <- boot(x, bootFunc, R = 999, parallel = "snow", ncpus = 10)
fsave(b1, file = "boot1.rda", location = "./results/starting/")
original <- b1$t0
bias <- colMeans(b1$t) - b1$t0
se <- apply(b1$t, 2, sd)
boot.df1 <- data.frame(original = original, bias = bias, se = se)
row.names(boot.df1) <- c("AME_gender")
boot.df1$t <- (boot.df1$original/boot.df1$se)
round(boot.df1, 5)
#>            original  bias      se       t
#> AME_gender  0.00773 2e-04 0.00344 2.24501

Model 2: Ethnicity

M2 <- glm(start_pub ~ ethnicity2, data = df_starting, family = binomial)

summary(M2)
#> 
#> Call:
#> glm(formula = start_pub ~ ethnicity2, family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -0.6626  -0.6626  -0.6011  -0.6011   1.9685  
#> 
#> Coefficients:
#>                    Estimate Std. Error  z value Pr(>|z|)    
#> (Intercept)        -1.40441    0.01091 -128.714  < 2e-16 ***
#> ethnicity2minority -0.37757    0.06429   -5.872  4.3e-09 ***
#> ethnicity2other    -0.21503    0.01885  -11.409  < 2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 81877  on 85785  degrees of freedom
#> AIC: 81883
#> 
#> Number of Fisher Scoring iterations: 4

Average marginal effects (AMEs)

bootFunc <- function(data, i) {
    df <- data[i, ]  #bootstrap datasets

    M <- glm(start_pub ~ ethnicity2, family = binomial, data = df)

    suppressWarnings({

        # ME ethnicity
        dfs0 <- dfs1 <- df
        dfs0$ethnicity2 <- "majority"
        dfs1$ethnicity2 <- "minority"
        dfs1$ethnicity2 <- factor(dfs1$ethnicity2, levels = levels(df$ethnicity2))
        dfs0$ethnicity2 <- factor(dfs0$ethnicity2, levels = levels(df$ethnicity2))

        # calculate the predicted probabilities
        p1 <- predict(M, type = "response", newdata = dfs1)
        p0 <- predict(M, type = "response", newdata = dfs0)

        # and the marginal effects
        AME_ethnicity <- mean(p1 - p0)

    })

    AME_ethnicity  #save results
}

b2 <- boot(df_starting, bootFunc, R = 999, parallel = "snow", ncpus = 10)
fsave(b2, file = "boot2.rda", location = "./results/starting/")
load("./results/starting/boot2.rda")
b2 <- x
rm(x)
original <- b2$t0
bias <- colMeans(b2$t) - b2$t0
se <- apply(b2$t, 2, sd)
boot.df2 <- data.frame(original = original, bias = bias, se = se)
row.names(boot.df2) <- c("AME_ethnicity")
boot.df2$t <- (boot.df2$original/boot.df2$se)
round(boot.df2, 5)
#>               original     bias      se       t
#> AME_ethnicity -0.05306 -0.00033 0.00801 -6.6212

Model 3: Gender, ethnicity and controls

See Appendix 1 Splines to see how we selected the following spline configuration

knots5 <- quantile(df_starting$phd_cohort, probs=seq(0,1,0.25))[2:4]
test3 <- glm(start_pub ~ bSpline(phd_cohort, knots=knots5,df=3), family = binomial, data = df_starting)
knots5 <- quantile(df_starting$phd_cohort, probs = seq(0, 1, 0.25))[2:4]

M3 <- glm(start_pub ~ gender + ethnicity2 + uni + bSpline(phd_cohort, knots = knots5, df = 3), data = df_starting,
    family = binomial)

summary(M3)
#> 
#> Call:
#> glm(formula = start_pub ~ gender + ethnicity2 + uni + bSpline(phd_cohort, 
#>     knots = knots5, df = 3), family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -1.7438  -0.6278  -0.3303  -0.1283   3.4071  
#> 
#> Coefficients:
#>                                               Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)                                  -3.025053   0.102165 -29.609  < 2e-16 ***
#> genderwomen                                   0.001666   0.023177   0.072    0.943    
#> gendermissing                                -1.462188   0.030110 -48.562  < 2e-16 ***
#> ethnicity2minority                           -0.355192   0.071213  -4.988 6.11e-07 ***
#> ethnicity2other                              -0.156063   0.021801  -7.159 8.15e-13 ***
#> uniLU                                        -0.018678   0.066188  -0.282    0.778    
#> uniRU                                         2.043165   0.050514  40.448  < 2e-16 ***
#> uniRUG                                       -1.288330   0.076557 -16.828  < 2e-16 ***
#> uniTUD                                       -1.063854   0.089911 -11.832  < 2e-16 ***
#> uniTUE                                       -1.158010   0.090116 -12.850  < 2e-16 ***
#> uniTI                                         0.062811   0.086628   0.725    0.468    
#> uniUM                                         1.642026   0.055009  29.850  < 2e-16 ***
#> uniUT                                         2.084985   0.054222  38.453  < 2e-16 ***
#> uniUU                                         1.436107   0.051816  27.716  < 2e-16 ***
#> uniUvA                                        0.838398   0.052263  16.042  < 2e-16 ***
#> uniVU                                         2.129574   0.058023  36.702  < 2e-16 ***
#> uniWUR                                        3.010270   0.055377  54.359  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)1  1.335447   0.169038   7.900 2.78e-15 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)2  0.011234   0.098812   0.114    0.909    
#> bSpline(phd_cohort, knots = knots5, df = 3)3  1.721424   0.114230  15.070  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)4  0.583103   0.100407   5.807 6.34e-09 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)5  0.637943   0.111697   5.711 1.12e-08 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)6  0.482482   0.100926   4.781 1.75e-06 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 65501  on 85765  degrees of freedom
#> AIC: 65547
#> 
#> Number of Fisher Scoring iterations: 6

Average marginal effects (AMEs)

bootFunc <- function(data, i) {

    df <- data[i, ]  #bootstrap datasets

    knots5 <- quantile(df$phd_cohort, probs = seq(0, 1, 0.25))[2:4]

    M <- glm(start_pub ~ gender + ethnicity2 + uni + splines2::bSpline(phd_cohort, knots = knots5, df = 3),
        family = binomial, data = df)

    suppressWarnings({

        # ME gender
        dfs0 <- dfs1 <- df
        dfs0$gender <- "men"
        dfs1$gender <- "women"
        dfs1$gender <- factor(dfs1$gender, levels = levels(df$gender))
        dfs0$gender <- factor(dfs0$gender, levels = levels(df$gender))

        ME_gender <- mean(predict(M, dfs1, type = "response") - predict(M, dfs0, type = "response"))

        # ME ethnicity
        dfs0 <- dfs1 <- df
        dfs0$ethnicity2 <- "majority"
        dfs1$ethnicity2 <- "minority"
        dfs1$ethnicity2 <- factor(dfs1$ethnicity2, levels = levels(df$ethnicity2))
        dfs0$ethnicity2 <- factor(dfs0$ethnicity2, levels = levels(df$ethnicity2))

        ME_ethnicity <- mean(predict(M, dfs1, type = "response") - predict(M, dfs0, type = "response"))

    })

    c(ME_gender, ME_ethnicity)  #save results
}

b3 <- boot(df_starting, bootFunc, R = 999, parallel = "snow", ncpus = 10)
fsave(b3, file = "boot3.rda", location = "./results/starting/")
original <- b3$t0
bias <- colMeans(b3$t) - b3$t0
se <- apply(b3$t, 2, sd)
boot.df3 <- data.frame(original = original, bias = bias, se = se)
row.names(boot.df3) <- c("AME_gender", "AME_ethnicity")

boot.df3$t <- (boot.df3$original/boot.df3$se)

round(boot.df3, 5)
#>               original    bias      se        t
#> AME_gender     0.00024 0.00008 0.00317  0.07562
#> AME_ethnicity -0.04110 0.00018 0.00758 -5.42180

Model 4: Gender and ethnicity, controls and cohort interactions

M4 <- glm(start_pub ~ gender + ethnicity2 + uni + bSpline(phd_cohort, knots = knots5, df = 3) + gender *
    phd_cohort + ethnicity2 * phd_cohort, data = df_starting, family = binomial)

summary(M4)
#> 
#> Call:
#> glm(formula = start_pub ~ gender + ethnicity2 + uni + bSpline(phd_cohort, 
#>     knots = knots5, df = 3) + gender * phd_cohort + ethnicity2 * 
#>     phd_cohort, family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -1.7551  -0.6536  -0.3240  -0.1374   3.6719  
#> 
#> Coefficients: (1 not defined because of singularities)
#>                                               Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)                                  -2.783799   0.106246 -26.201  < 2e-16 ***
#> genderwomen                                  -0.072519   0.070853  -1.024 0.306071    
#> gendermissing                                -2.548950   0.072106 -35.350  < 2e-16 ***
#> ethnicity2minority                           -0.441441   0.272337  -1.621 0.105032    
#> ethnicity2other                              -0.255907   0.067565  -3.788 0.000152 ***
#> uniLU                                         0.023694   0.066262   0.358 0.720659    
#> uniRU                                         2.024585   0.050486  40.102  < 2e-16 ***
#> uniRUG                                       -1.300225   0.076558 -16.984  < 2e-16 ***
#> uniTUD                                       -0.988134   0.090074 -10.970  < 2e-16 ***
#> uniTUE                                       -1.151597   0.090119 -12.779  < 2e-16 ***
#> uniTI                                         0.066166   0.086640   0.764 0.445054    
#> uniUM                                         1.674924   0.055099  30.399  < 2e-16 ***
#> uniUT                                         2.111909   0.054335  38.868  < 2e-16 ***
#> uniUU                                         1.450850   0.051851  27.981  < 2e-16 ***
#> uniUvA                                        0.885765   0.052369  16.914  < 2e-16 ***
#> uniVU                                         2.029911   0.058266  34.838  < 2e-16 ***
#> uniWUR                                        3.104356   0.055956  55.479  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)1  1.439530   0.174955   8.228  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)2 -0.115677   0.101402  -1.141 0.253962    
#> bSpline(phd_cohort, knots = knots5, df = 3)3  1.419255   0.118845  11.942  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)4  0.193317   0.107035   1.806 0.070901 .  
#> bSpline(phd_cohort, knots = knots5, df = 3)5  0.255837   0.119292   2.145 0.031982 *  
#> bSpline(phd_cohort, knots = knots5, df = 3)6  0.086143   0.110049   0.783 0.433759    
#> phd_cohort                                          NA         NA      NA       NA    
#> genderwomen:phd_cohort                        0.005494   0.003337   1.646 0.099697 .  
#> gendermissing:phd_cohort                      0.062583   0.003615  17.314  < 2e-16 ***
#> ethnicity2minority:phd_cohort                 0.004519   0.012144   0.372 0.709790    
#> ethnicity2other:phd_cohort                    0.004437   0.003195   1.389 0.164880    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 65157  on 85761  degrees of freedom
#> AIC: 65211
#> 
#> Number of Fisher Scoring iterations: 6

Average marginal effects (AMEs)

bootFunc <- function(data, i) {
    df <- data[i, ]  #bootstrap datasets

    knots5 <- quantile(df$phd_cohort, probs = seq(0, 1, 0.25))[2:4]

    M <- glm(start_pub ~ gender + ethnicity2 + uni + splines2::bSpline(phd_cohort, knots = knots5, df = 3) +
        phd_cohort * gender + phd_cohort * ethnicity2, family = binomial, data = df)

    suppressWarnings({

        s <- 0.1

        # ME gender
        dfs0 <- dfs1 <- df
        dfs0$gender <- "men"
        dfs1$gender <- "women"
        dfs1$gender <- factor(dfs1$gender, levels = levels(df$gender))
        dfs0$gender <- factor(dfs0$gender, levels = levels(df$gender))

        ME_gender <- mean(predict(M, dfs1, type = "response") - predict(M, dfs0, type = "response"))

        # ME ethnicity
        dfs0 <- dfs1 <- df
        dfs0$ethnicity2 <- "majority"
        dfs1$ethnicity2 <- "minority"
        dfs1$ethnicity2 <- factor(dfs1$ethnicity2, levels = levels(df$ethnicity2))
        dfs0$ethnicity2 <- factor(dfs0$ethnicity2, levels = levels(df$ethnicity2))

        ME_ethnicity <- mean(predict(M, dfs1, type = "response") - predict(M, dfs0, type = "response"))

        # ME cohort
        dfs0 <- dfs1 <- df
        dfs0$phd_cohort <- df$phd_cohort - s
        dfs1$phd_cohort <- df$phd_cohort + s

        ME_phd_cohort <- mean((predict(M, dfs1, type = "response") - predict(M, dfs0, type = "response"))/(2 *
            s))

        # ME gender * cohort

        dfwomencp <- dfwomencm <- dfmencp <- dfmencm <- df

        dfwomencp$gender <- dfwomencm$gender <- "women"
        dfmencp$gender <- dfmencm$gender <- "men"

        dfwomencp$gender <- factor(dfwomencp$gender, levels = levels(df$gender))
        dfwomencm$gender <- factor(dfwomencm$gender, levels = levels(df$gender))
        dfmencp$gender <- factor(dfmencp$gender, levels = levels(df$gender))
        dfmencm$gender <- factor(dfmencm$gender, levels = levels(df$gender))

        dfwomencp$phd_cohort <- dfmencp$phd_cohort <- df$phd_cohort + s
        dfwomencm$phd_cohort <- dfmencm$phd_cohort <- df$phd_cohort - s

        # calculate the predicted probabilities
        gp11 <- predict(M, type = "response", newdata = dfwomencp)
        gp10 <- predict(M, type = "response", newdata = dfwomencm)
        gp01 <- predict(M, type = "response", newdata = dfmencp)
        gp00 <- predict(M, type = "response", newdata = dfmencm)

        # and the marginal effects. be aware of all the brackets. :-(
        ME_gender_cohort <- mean(((gp11 - gp01) - (gp10 - gp00))/(2 * s))

        # ME ethnicity * cohort
        dfminoritycp <- dfminoritycm <- dfdutchcp <- dfdutchcm <- df

        dfminoritycp$ethnicity2 <- dfminoritycm$ethnicity2 <- "minority"
        dfdutchcp$ethnicity2 <- dfdutchcm$ethnicity2 <- "majority"

        dfminoritycp$ethnicity2 <- factor(dfminoritycp$ethnicity2, levels = levels(df$ethnicity2))
        dfminoritycm$ethnicity2 <- factor(dfminoritycm$ethnicity2, levels = levels(df$ethnicity2))
        dfdutchcp$ethnicity2 <- factor(dfdutchcp$ethnicity2, levels = levels(df$ethnicity2))
        dfdutchcm$ethnicity2 <- factor(dfdutchcm$ethnicity2, levels = levels(df$ethnicity2))

        dfminoritycp$phd_cohort <- dfdutchcp$phd_cohort <- df$phd_cohort + s
        dfminoritycm$phd_cohort <- dfdutchcm$phd_cohort <- df$phd_cohort - s

        # calculate the predicted probabilities
        ep11 <- predict(M, type = "response", newdata = dfminoritycp)
        ep10 <- predict(M, type = "response", newdata = dfminoritycm)
        ep01 <- predict(M, type = "response", newdata = dfdutchcp)
        ep00 <- predict(M, type = "response", newdata = dfdutchcm)

        # and the marginal effects. be aware of all the brackets. :-(
        ME_ethnicity_cohort <- mean(((ep11 - ep01) - (ep10 - ep00))/(2 * s))

    })

    c(ME_gender, ME_ethnicity, ME_phd_cohort, ME_gender_cohort, ME_ethnicity_cohort)  #save results
}

b4 <- boot(df_starting, bootFunc, R = 999, parallel = "snow", ncpus = 10)
fsave(b4, file = "boot4.rda", location = "./results/starting/")
original <- b4$t0
bias <- colMeans(b4$t) - b4$t0
se <- apply(b4$t, 2, sd)

boot.df4 <- data.frame(original = original, bias = bias, se = se)
row.names(boot.df4) <- c("AME_gender", "AME_ethnicity", "AME_cohort", "AME_gender_cohort", "AME_ethnicity_cohort")

boot.df4$t <- (boot.df4$original/boot.df4$se)

round(boot.df4, 5)
#>                      original     bias      se        t
#> AME_gender            0.00409  0.00005 0.00346  1.18434
#> AME_ethnicity        -0.04092  0.00038 0.00806 -5.07701
#> AME_cohort           -0.00196  0.00001 0.00047 -4.14489
#> AME_gender_cohort     0.00063 -0.00001 0.00044  1.45635
#> AME_ethnicity_cohort  0.00063  0.00001 0.00103  0.61113

Table 3

columns <- c(rep(c("B", "SE"), 4))
rows <- c("Intercept", "Gender: ref=men", "Women", "Missing gender", "Ethnicity: ref=majority", "Minority",
    "Other", "University: ref=Erasmus University", "Leiden University", "Radboud University", "University of Groningen",
    "Delft University of Technology", "Eindhoven University of Technology", "Tilburg University", "Maastricht University",
    "University of Twente", "Utrecht University", "University of Amsterdam", "Vrije Universiteit Amsterdam",
    "Wageningen University and Research Centre", "PhD cohort", "Knot #1", "Knot #2", "Knot #3", "Knot #4",
    "Knot #5", "Knot #6", "Cohort interactions", "PhD cohort * woman", "PhD cohort * missing gender",
    "PhD cohort * ethnic minority", "PhD cohort * other ethnicity", "<strong>AIC</strong></p>", "<strong>N</strong></p>")

t3 <- data.frame(matrix(nrow = length(rows), ncol = length(columns)))
colnames(t3) <- columns
rownames(t3) <- rows

# names(M4$coefficients)

# Model 1
t3[c(1, 3, 4), 1] <- M1$coefficients  # log odds
t3[c(1, 3, 4), 2] <- summary(M1)$coefficients[, 2]  # SE log odds

# Model 2
t3[c(1, 6, 7), 3] <- M2$coefficients
t3[c(1, 6, 7), 4] <- summary(M2)$coefficients[, 2]

# Model 3
t3[c(1, 3:4, 6:7, 9:20, 22:27), 5] <- M3$coefficients
t3[c(1, 3:4, 6:7, 9:20, 22:27), 6] <- summary(M3)$coefficients[, 2]

# Model 4
M4_ <- data.frame(summary(M4)$coefficients[, 1])
M4_[, 2] <- summary(M4)$coefficients[, 2]
t3[c(1, 3:4, 6:7, 9:20, 22:27, 29:32), 7] <- M4_[, 1]
t3[c(1, 3:4, 6:7, 9:20, 22:27, 29:32), 8] <- M4_[, 2]

# AIC
t3[33, 1] <- round(M1$aic, 0)
t3[33, 3] <- round(M2$aic, 0)
t3[33, 5] <- round(M4$aic, 0)
t3[33, 7] <- round(M4$aic, 0)

# rounding
t3[c(1, 3, 4), c(1, 2)] <- format(round(t3[c(1, 3, 4), c(1, 2)], 2), nsmall = 2)
t3[c(1, 6, 7), c(3, 4)] <- format(round(t3[c(1, 6, 7), c(3, 4)], 2), nsmall = 2)
t3[c(1, 3, 4, 6, 7, 9:20, 22:27), c(5:6)] <- format(round(t3[c(1, 3, 4, 6, 7, 9:20, 22:27), c(5:6)],
    2), nsmall = 2)
t3[c(1, 3, 4, 6, 7, 9:20, 22:27, 29:32), c(7, 8)] <- format(round(t3[c(1, 3, 4, 6, 7, 9:20, 22:27, 29:32),
    c(7, 8)], 2), nsmall = 2)

# sample size
t3[34, c(1, 3, 5, 7)] <- rep(nrow(df_starting), 4)

# Adding significance codes
t3[1, 1] <- paste0(t3[1, 1], "***")  # intercept
t3[1, 3] <- paste0(t3[1, 3], "***")
t3[1, 5] <- paste0(t3[1, 5], "***")
t3[1, 7] <- paste0(t3[1, 7], "***")
t3[3, 1] <- paste0(t3[3, 1], "*")  # gender
t3[4, 1] <- paste0(t3[4, 1], "***")  # gender missing
t3[4, 5] <- paste0(t3[4, 5], "***")
t3[4, 7] <- paste0(t3[4, 7], "***")
t3[6, 3] <- paste0(t3[6, 3], "***")  # ethnic minorities
t3[6, 5] <- paste0(t3[6, 5], "***")
t3[7, 3] <- paste0(t3[7, 3], "***")  # other ethnicity
t3[7, 5] <- paste0(t3[7, 5], "***")
t3[7, 7] <- paste0(t3[7, 7], "***")
t3[10, 5] <- paste0(t3[10, 5], "***")  # RU
t3[10, 7] <- paste0(t3[10, 7], "***")
t3[11, 5] <- paste0(t3[11, 5], "***")  # RUG
t3[11, 7] <- paste0(t3[11, 7], "***")
t3[12, 5] <- paste0(t3[12, 5], "***")  # TUD
t3[12, 7] <- paste0(t3[12, 7], "***")
t3[13, 5] <- paste0(t3[13, 5], "***")  # TUE
t3[13, 7] <- paste0(t3[13, 7], "***")
t3[15, 5] <- paste0(t3[15, 5], "***")  # UM
t3[15, 7] <- paste0(t3[15, 7], "***")
t3[16, 5] <- paste0(t3[16, 5], "***")  #UT
t3[16, 7] <- paste0(t3[16, 7], "***")
t3[17, 5] <- paste0(t3[17, 5], "***")  #UU
t3[17, 7] <- paste0(t3[17, 7], "***")
t3[18, 5] <- paste0(t3[18, 5], "***")  #UvA
t3[18, 7] <- paste0(t3[18, 7], "***")
t3[19, 5] <- paste0(t3[19, 5], "***")  #VU
t3[19, 7] <- paste0(t3[19, 7], "***")
t3[20, 5] <- paste0(t3[20, 5], "***")  #WUR
t3[20, 7] <- paste0(t3[20, 7], "***")
t3[22, 5] <- paste0(t3[22, 5], "***")  # coh 1
t3[22, 7] <- paste0(t3[22, 7], "***")
t3[24, 5] <- paste0(t3[24, 5], "***")  # coh 3
t3[24, 7] <- paste0(t3[24, 7], "***")
t3[25, 5] <- paste0(t3[25, 5], "***")  # coh 4
t3[26, 5] <- paste0(t3[26, 5], "***")  # coh 5
t3[26, 7] <- paste0(t3[26, 7], "*")
t3[27, 5] <- paste0(t3[27, 5], "***")  # coh 6
t3[30, 7] <- paste0(t3[30, 7], "***")  # coh * gender missing

t3[is.na(t3)] <- ""
t3 %>%
    kable(format = "html", caption = "<b>Table 3.</b> Logistic regression on starting to publish", escape = FALSE) %>%
    add_header_above(., c(` ` = 1, `Model 1` = 2, `Model 2` = 2, `Model 3` = 2, `Model 4` = 2), escape = FALSE,
        bold = TRUE) %>%
    row_spec(row = c(2, 5, 8, 21, 28), bold = T) %>%
    kable_classic(full_width = F, html_font = "Cambria") %>%
    kable_styling(font_size = 12) -> table3

table3
Table 3. Logistic regression on starting to publish
Model 1
Model 2
Model 3
Model 4
B SE B SE B SE B SE
Intercept -1.31*** 0.01 -1.40*** 0.01 -3.03*** 0.10 -2.78*** 0.11
Gender: ref=men
Women 0.05* 0.02 0.00 0.02 -0.07 0.07
Missing gender -0.67*** 0.02 -1.46*** 0.03 -2.55*** 0.07
Ethnicity: ref=majority
Minority -0.38*** 0.06 -0.36*** 0.07 -0.44 0.27
Other -0.22*** 0.02 -0.16*** 0.02 -0.26*** 0.07
University: ref=Erasmus University
Leiden University -0.02 0.07 0.02 0.07
Radboud University 2.04*** 0.05 2.02*** 0.05
University of Groningen -1.29*** 0.08 -1.30*** 0.08
Delft University of Technology -1.06*** 0.09 -0.99*** 0.09
Eindhoven University of Technology -1.16*** 0.09 -1.15*** 0.09
Tilburg University 0.06 0.09 0.07 0.09
Maastricht University 1.64*** 0.06 1.67*** 0.06
University of Twente 2.08*** 0.05 2.11*** 0.05
Utrecht University 1.44*** 0.05 1.45*** 0.05
University of Amsterdam 0.84*** 0.05 0.89*** 0.05
Vrije Universiteit Amsterdam 2.13*** 0.06 2.03*** 0.06
Wageningen University and Research Centre 3.01*** 0.06 3.10*** 0.06
PhD cohort
Knot #1 1.34*** 0.17 1.44*** 0.17
Knot #2 0.01 0.10 -0.12 0.10
Knot #3 1.72*** 0.11 1.42*** 0.12
Knot #4 0.58*** 0.10 0.19 0.11
Knot #5 0.64*** 0.11 0.26* 0.12
Knot #6 0.48*** 0.10 0.09 0.11
Cohort interactions
PhD cohort * woman 0.01 0.00
PhD cohort * missing gender 0.06*** 0.00
PhD cohort * ethnic minority 0.00 0.01
PhD cohort * other ethnicity 0.00 0.00
AIC 80864 81883 65211 65211
N 85788 85788 85788 85788

Robustness checks

Ethnicity missing and other separately

M2b <- glm(start_pub ~ ethnicity3, data = df_starting, family = binomial)
summary(M2b)
#> 
#> Call:
#> glm(formula = start_pub ~ ethnicity3, family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -0.6626  -0.6626  -0.6033  -0.5999   1.9685  
#> 
#> Coefficients:
#>                    Estimate Std. Error  z value Pr(>|z|)    
#> (Intercept)        -1.40441    0.01091 -128.714  < 2e-16 ***
#> ethnicity3minority -0.37757    0.06429   -5.872 4.30e-09 ***
#> ethnicity3other    -0.20696    0.02830   -7.314 2.59e-13 ***
#> ethnicity3missing  -0.21929    0.02192  -10.005  < 2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 81877  on 85784  degrees of freedom
#> AIC: 81885
#> 
#> Number of Fisher Scoring iterations: 4
M3b <- glm(start_pub ~ gender + ethnicity3 + uni + bSpline(phd_cohort, knots = knots5, df = 3), data = df_starting,
    family = binomial)
summary(M3b)
#> 
#> Call:
#> glm(formula = start_pub ~ gender + ethnicity3 + uni + bSpline(phd_cohort, 
#>     knots = knots5, df = 3), family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -1.7437  -0.6279  -0.3303  -0.1283   3.4008  
#> 
#> Coefficients:
#>                                               Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)                                  -3.024648   0.102163 -29.606  < 2e-16 ***
#> genderwomen                                   0.001781   0.023178   0.077    0.939    
#> gendermissing                                -1.462373   0.030110 -48.567  < 2e-16 ***
#> ethnicity3minority                           -0.355084   0.071212  -4.986 6.16e-07 ***
#> ethnicity3other                              -0.134768   0.032163  -4.190 2.79e-05 ***
#> ethnicity3missing                            -0.167103   0.025055  -6.669 2.57e-11 ***
#> uniLU                                        -0.018805   0.066188  -0.284    0.776    
#> uniRU                                         2.043052   0.050514  40.445  < 2e-16 ***
#> uniRUG                                       -1.288333   0.076557 -16.828  < 2e-16 ***
#> uniTUD                                       -1.064059   0.089912 -11.834  < 2e-16 ***
#> uniTUE                                       -1.158016   0.090116 -12.850  < 2e-16 ***
#> uniTI                                         0.062603   0.086629   0.723    0.470    
#> uniUM                                         1.642174   0.055010  29.853  < 2e-16 ***
#> uniUT                                         2.084744   0.054222  38.448  < 2e-16 ***
#> uniUU                                         1.436189   0.051817  27.717  < 2e-16 ***
#> uniUvA                                        0.838617   0.052264  16.046  < 2e-16 ***
#> uniVU                                         2.130738   0.058038  36.713  < 2e-16 ***
#> uniWUR                                        3.010248   0.055377  54.359  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)1  1.335064   0.169036   7.898 2.83e-15 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)2  0.010780   0.098812   0.109    0.913    
#> bSpline(phd_cohort, knots = knots5, df = 3)3  1.721160   0.114228  15.068  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)4  0.582322   0.100409   5.800 6.65e-09 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)5  0.637164   0.111698   5.704 1.17e-08 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)6  0.481598   0.100928   4.772 1.83e-06 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 65500  on 85764  degrees of freedom
#> AIC: 65548
#> 
#> Number of Fisher Scoring iterations: 6
M4b <- glm(start_pub ~ gender + ethnicity3 + uni + bSpline(phd_cohort, knots = knots5, df = 3) + gender *
    phd_cohort + ethnicity3 * phd_cohort, data = df_starting, family = binomial)
summary(M4b)
#> 
#> Call:
#> glm(formula = start_pub ~ gender + ethnicity3 + uni + bSpline(phd_cohort, 
#>     knots = knots5, df = 3) + gender * phd_cohort + ethnicity3 * 
#>     phd_cohort, family = binomial, data = df_starting)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -1.7551  -0.6536  -0.3242  -0.1379   3.6763  
#> 
#> Coefficients: (1 not defined because of singularities)
#>                                               Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)                                  -2.783877   0.106250 -26.201  < 2e-16 ***
#> genderwomen                                  -0.072805   0.070856  -1.028  0.30418    
#> gendermissing                                -2.548882   0.072109 -35.347  < 2e-16 ***
#> ethnicity3minority                           -0.441709   0.272345  -1.622  0.10483    
#> ethnicity3other                              -0.271954   0.106025  -2.565  0.01032 *  
#> ethnicity3missing                            -0.246675   0.078317  -3.150  0.00163 ** 
#> uniLU                                         0.023523   0.066263   0.355  0.72259    
#> uniRU                                         2.024517   0.050486  40.101  < 2e-16 ***
#> uniRUG                                       -1.300256   0.076558 -16.984  < 2e-16 ***
#> uniTUD                                       -0.988314   0.090075 -10.972  < 2e-16 ***
#> uniTUE                                       -1.151544   0.090119 -12.778  < 2e-16 ***
#> uniTI                                         0.065843   0.086642   0.760  0.44729    
#> uniUM                                         1.675077   0.055099  30.401  < 2e-16 ***
#> uniUT                                         2.111596   0.054336  38.862  < 2e-16 ***
#> uniUU                                         1.450798   0.051851  27.980  < 2e-16 ***
#> uniUvA                                        0.885999   0.052370  16.918  < 2e-16 ***
#> uniVU                                         2.031196   0.058284  34.850  < 2e-16 ***
#> uniWUR                                        3.104231   0.055957  55.476  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)1  1.439455   0.174957   8.228  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)2 -0.115670   0.101409  -1.141  0.25402    
#> bSpline(phd_cohort, knots = knots5, df = 3)3  1.419468   0.118849  11.944  < 2e-16 ***
#> bSpline(phd_cohort, knots = knots5, df = 3)4  0.193232   0.107043   1.805  0.07105 .  
#> bSpline(phd_cohort, knots = knots5, df = 3)5  0.255462   0.119296   2.141  0.03224 *  
#> bSpline(phd_cohort, knots = knots5, df = 3)6  0.085719   0.110052   0.779  0.43605    
#> phd_cohort                                          NA         NA      NA       NA    
#> genderwomen:phd_cohort                        0.005517   0.003337   1.653  0.09835 .  
#> gendermissing:phd_cohort                      0.062571   0.003615  17.310  < 2e-16 ***
#> ethnicity3minority:phd_cohort                 0.004535   0.012145   0.373  0.70884    
#> ethnicity3other:phd_cohort                    0.006128   0.004904   1.250  0.21145    
#> ethnicity3missing:phd_cohort                  0.003497   0.003700   0.945  0.34467    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 82033  on 85787  degrees of freedom
#> Residual deviance: 65156  on 85759  degrees of freedom
#> AIC: 65214
#> 
#> Number of Fisher Scoring iterations: 6

Ethnicity by PhD year

df_starting %>%
    group_by(phd_year, ethnicity3) %>%
    summarize(frequency = n()) -> ethnicity_year



ethnicity_year
#> # A tibble: 120 x 3
#> # Groups:   phd_year [30]
#>    phd_year ethnicity3 frequency
#>       <dbl> <fct>          <int>
#>  1     1990 majority         654
#>  2     1990 minority           3
#>  3     1990 other             50
#>  4     1990 missing          102
#>  5     1991 majority         717
#>  6     1991 minority           7
#>  7     1991 other             58
#>  8     1991 missing          112
#>  9     1992 majority         796
#> 10     1992 minority           8
#> # i 110 more rows
ey_1994 <- ethnicity_year[ethnicity_year$phd_year < 1995 & ethnicity_year$ethnicity3 == "minority", ]

mean(ey_1994$frequency)
#> [1] 7.6
ey_1999 <- ethnicity_year[ethnicity_year$phd_year < 2000 & ethnicity_year$phd_year > 1994 & ethnicity_year$ethnicity3 ==
    "minority", ]  # 95-99

mean(ey_1999$frequency)
#> [1] 16
ey_2009 <- ethnicity_year[ethnicity_year$phd_year > 1999 & ethnicity_year$phd_year < 2010 & ethnicity_year$ethnicity3 ==
    "minority", ]  # 00-09

mean(ey_2009$frequency)
#> [1] 48.2
ey_2010p <- ethnicity_year[ethnicity_year$phd_year > 2009 & ethnicity_year$ethnicity3 == "minority",
    ]  # 00-09

mean(ey_2010p$frequency)
#> [1] 142

LS0tDQp0aXRsZTogIkFuYWx5c2VzICdzdGFydGluZyB0byBwdWJsaXNoJyINCmRhdGU6ICJMYXN0IGNvbXBpbGVkIG9uIGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIsICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjc3M6IHR3ZWFrcy5jc3MNCiAgICB0b2M6ICB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KDQotLS0NCg0KDQoNCmBgYHtyLCBnbG9iYWxzZXR0aW5ncywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0iaGlkZSJ9DQoNCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9MTAwKSx0aWR5PVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLGNvbW1lbnQgPSAiIz4iLCBjYWNoZT1UUlVFLCBjbGFzcy5zb3VyY2U9YygidGVzdCIpLCBjbGFzcy5vdXRwdXQ9YygidGVzdDIiKSwgY2FjaGUubGF6eSA9IEZBTFNFKQ0Kb3B0aW9ucyh3aWR0aCA9IDEwMCkNCnJnbDo6c2V0dXBLbml0cigpDQoNCmNvbG9yaXplIDwtIGZ1bmN0aW9uKHgsIGNvbG9yKSB7c3ByaW50ZigiPHNwYW4gc3R5bGU9J2NvbG9yOiAlczsnPiVzPC9zcGFuPiIsIGNvbG9yLCB4KSB9DQoNCmBgYA0KDQpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRSwgZXZhbD1UUlVFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCd0b3AnLCAncmlnaHQnKSkNCiNrbGlwcHk6OmtsaXBweShjb2xvciA9ICdkYXJrcmVkJykNCiNrbGlwcHk6OmtsaXBweSh0b29sdGlwX21lc3NhZ2UgPSAnQ2xpY2sgdG8gY29weScsIHRvb2x0aXBfc3VjY2VzcyA9ICdEb25lJykNCmBgYA0KDQoNCi0tLS0NCg0KVGhpcyBsYWIgam91cm5hbCByZXBsaWNhdGVzIHRoZSBhbmFseXNlcyBmb3IgJ3N0YXJ0aW5nIHRvIHB1Ymxpc2gnLiANCiAgDQoNCi0tLS0NCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCnJtKGxpc3QgPSBscygpKQ0KDQpgYGANCg0KDQoNCiMgQ3VzdG9tIGZ1bmN0aW9ucw0KDQotIGBmcGFja2FnZS5jaGVja2A6IENoZWNrIGlmIHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQgKGFuZCBpbnN0YWxsIGlmIG5vdCkgaW4gUiAoW3NvdXJjZV0oaHR0cHM6Ly92YmFsaWdhLmdpdGh1Yi5pby92ZXJpZnktdGhhdC1yLXBhY2thZ2VzLWFyZS1pbnN0YWxsZWQtYW5kLWxvYWRlZC8pKS4gIA0KDQotIGBkZGxvZ2lzYDogZG91YmxlIGRlcml2YXRpdmUgZnVuY3Rpb24gZm9yIGNhbGN1bGF0aW5nIG1hcmdpbmFsIGludGVyYWN0aW9uIGVmZmVjdHMgDQooW3NvdXJjZV0oaHR0cHM6Ly9qb2NoZW10b2xzbWEuZ2l0aHViLmlvL01hcmdpbmFsRWZmZWN0cy8jNV9Mb2dpc3RpY193aXRoX21vZGVsX2ludGVyYWN0aW9ucykpLg0KDQoNCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30NCg0KZnBhY2thZ2UuY2hlY2sgPC0gZnVuY3Rpb24ocGFja2FnZXMpIHsNCiAgbGFwcGx5KHBhY2thZ2VzLCBGVU4gPSBmdW5jdGlvbih4KSB7DQogICAgaWYgKCFyZXF1aXJlKHgsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgICAgIGluc3RhbGwucGFja2FnZXMoeCwgZGVwZW5kZW5jaWVzID0gVFJVRSkNCiAgICAgIGxpYnJhcnkoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KICAgIH0NCiAgfSkNCn0NCg0KDQpmc2F2ZSA8LSBmdW5jdGlvbih4LCBmaWxlLCBsb2NhdGlvbj0iLi9kYXRhL3Byb2Nlc3NlZC8iKSB7DQogIGRhdGVuYW1lIDwtIHN1YnN0cihnc3ViKCJbOi1dIiwgIiIsIFN5cy50aW1lKCkpLCAxLDgpICANCiAgdG90YWxuYW1lIDwtIHBhc3RlKGxvY2F0aW9uLCBkYXRlbmFtZSwgZmlsZSwgc2VwPSIiKQ0KICBzYXZlKHgsIGZpbGUgPSB0b3RhbG5hbWUpICANCn0NCg0KZGRsb2dpcyA8LSBmdW5jdGlvbihYKSB7DQogICAgLShleHAoLVgpLygxICsgZXhwKC1YKSleMiAtIGV4cCgtWCkgKiAoMiAqIChleHAoLVgpICogKDEgKyBleHAoLVgpKSkpLygoMSArIGV4cCgtWCkpXjIpXjIpDQp9DQoNCg0KYGBgDQoNCg0KLS0tICANCg0KIyBQYWNrYWdlcw0KDQoNCi0gYHRpZHl2ZXJzZWA6IGZvciBkYXRhIG1hbmlwdWxhdGlvbg0KLSBgZ2dwbG90MmA6IGZvciBjcmVhdGluZyBmaWd1cmVzIDItNA0KLSBgZ2dwdWJyYDogZm9yIGNvbWJpbmluZyB0d28gZmlndXJlcyBpbiBvbmUgKHBsb3QgMikNCi0gYHNwbGluZXNgIGBzcGxpbmVzMmA6IGZvciBtb2RlbGxpbmcgbm9uLWxpbmVhciBjb2hvcnQgcmVsYXRpb25zDQotIGBib290YDogYm9vdHN0cmFwcGluZyBmb3IgU0VzIG9mIEFNRXMNCi0gYGthYmxlRXh0cmFgOiBmb3JtYXR0aW5nIHRhYmxlcw0KDQpgYGB7ciwgcmVzdWx0cz0naGlkZScsIHdhcm5pbmc9RkFMU0V9DQoNCnBhY2thZ2VzID0gYygidGlkeXZlcnNlIiwgImdncGxvdDIiLCAiZ2dwdWJyIiwgInNwbGluZXMiLCAic3BsaW5lczIiLCAiYm9vdCIsICJrYWJsZUV4dHJhIikNCg0KZnBhY2thZ2UuY2hlY2socGFja2FnZXMpDQoNCmBgYA0KDQoNCi0tLSANCg0KIyBJbnB1dA0KDQoNCg0KV2UgdXNlIG9uZSBwcm9jZXNzZWQgZGF0YXNldC4NCg0KKiBbZGZfc3RhcnRpbmcucmRhXShodHRwczovL2dpdGh1Yi5jb20vYW1tdWxkZXJzL2FtYXR0ZXJvZnRpbWUvZGF0YS9wcm9jZXNzZWQvZGZfc3RhcnRpbmcucmRhKTogZGF0YXNldCBvZiBQaERzIHdpdGggYWxsIHJlbGV2YW50IHZhcmlhYmxlczogZ2VuZGVyICsgZXRobmljaXR5ICsgdW5pdmVyc2l0eSArIFBoRCB5ZWFyICANCiAgICAtIEZvciBjb25zdHJ1Y3Rpb24gb2YgdGhpcyBkYXRhc2V0IHNlZSBbRGVwZW5kZW50IFZhcmlhYmxlcyA6IFN0YXJ0aW5nIGFuZCBTdG9wcGluZyB0byBQdWJsaXNoXShkYXRhcHJlcGFyYXRpb24uaHRtbCkgIA0KICAgIC0gbmFtZSBvZiBkYXRhc2V0OiBgZGZfc3RhcnRpbmdgIA0KICAgIA0KDQpgYGB7ciBkYXRhfQ0KDQpsb2FkKGZpbGUgPSAiLi9kYXRhL3Byb2Nlc3NlZC9kZl9zdGFydGluZy5yZGEiKQ0KDQoNCmBgYA0KDQoNCi0tLQ0KDQpXZSB1c2UgbG9naXN0aWMgcmVncmVzc2lvbnMgdG8gcHJlZGljdCB3aGV0aGVyIGFuIGluZGl2aWR1YWwgaGFzIGEgcGVyc29uYWwgTkFSQ0lTIHByb2ZpbGUgYW5kIGF0IGxlYXN0IG9uZSBwdWJsaWNhdGlvbg0KDQojIE1vZGVsIDE6IEdlbmRlciANCg0KYGBge3J9DQoNCg0KTTEgPC0gZ2xtKHN0YXJ0X3B1YiB+IGdlbmRlciAsIGRhdGEgPSBkZl9zdGFydGluZywgZmFtaWx5ID0gYmlub21pYWwpDQoNCnN1bW1hcnkoTTEpDQoNCmBgYA0KDQoNCiMjIEF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0cyAoQU1FcykNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQoNCmJvb3RGdW5jIDwtIGZ1bmN0aW9uKGRhdGEsIGkpIHsNCiAgZGYgPC0gZGF0YVtpLF0gI2Jvb3RzdHJhcCBkYXRhc2V0cw0KICANCiAgTSA8LSBnbG0oc3RhcnRfcHViIH4gZ2VuZGVyLCBmYW1pbHk9Ymlub21pYWwsIGRhdGEgPSBkZikNCiAgDQogIHN1cHByZXNzV2FybmluZ3Moew0KICANCiAgI01FIGdlbmRlcg0KICBkZnMwIDwtIGRmczEgPC0gZGYNCiAgZGZzMCRnZW5kZXIgPC0gIm1lbiINCiAgZGZzMSRnZW5kZXIgPC0gIndvbWVuIg0KICBkZnMxJGdlbmRlciA8LSBmYWN0b3IoZGZzMSRnZW5kZXIsIGxldmVscz1sZXZlbHMoZGYkZ2VuZGVyKSkNCiAgZGZzMCRnZW5kZXIgPC0gZmFjdG9yKGRmczAkZ2VuZGVyLCBsZXZlbHM9bGV2ZWxzKGRmJGdlbmRlcikpDQoNCiAgI2NhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMNCiAgcDEgPC0gcHJlZGljdChNLCB0eXBlPSJyZXNwb25zZSIsIG5ld2RhdGE9ZGZzMSkNCiAgcDAgPC0gcHJlZGljdChNLCB0eXBlPSJyZXNwb25zZSIsIG5ld2RhdGE9ZGZzMCkNCiAgDQogICMgYW5kIHRoZSBtYXJnaW5hbCBlZmZlY3RzDQogIEFNRV9nZW5kZXIgPC0gbWVhbihwMS1wMCkNCg0KICB9KQ0KICANCiAgQU1FX2dlbmRlciAjc2F2ZSByZXN1bHRzDQp9DQoNCmIxIDwtIGJvb3QoeCwgYm9vdEZ1bmMsIFIgPSA5OTksIHBhcmFsbGVsPSJzbm93IiwgbmNwdXM9MTApDQpmc2F2ZShiMSwgZmlsZT0iYm9vdDEucmRhIiwgbG9jYXRpb24gPSAiLi9yZXN1bHRzL3N0YXJ0aW5nLyIpDQoNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCg0KbG9hZCgiLi9yZXN1bHRzL3N0YXJ0aW5nL2Jvb3QxLnJkYSIpDQpiMSA8LSB4DQpybSh4KQ0KDQpgYGANCg0KYGBge3J9DQoNCm9yaWdpbmFsIDwtIGIxJHQwDQpiaWFzIDwtIGNvbE1lYW5zKGIxJHQpIC0gYjEkdDANCnNlIDwtIGFwcGx5KGIxJHQsIDIsIHNkKQ0KYm9vdC5kZjEgPC0gZGF0YS5mcmFtZShvcmlnaW5hbD1vcmlnaW5hbCwgYmlhcz1iaWFzLCBzZT1zZSkNCnJvdy5uYW1lcyhib290LmRmMSkgPC0gYygiQU1FX2dlbmRlciIpDQpib290LmRmMSR0IDwtIChib290LmRmMSRvcmlnaW5hbCAvIGJvb3QuZGYxJHNlKQ0Kcm91bmQoYm9vdC5kZjEsIDUpDQoNCmBgYA0KDQoNCg0KDQojIE1vZGVsIDI6IEV0aG5pY2l0eQ0KDQpgYGB7cn0NCg0KTTIgPC0gZ2xtKHN0YXJ0X3B1YiB+IGV0aG5pY2l0eTIgLCBkYXRhID0gZGZfc3RhcnRpbmcsIGZhbWlseSA9IGJpbm9taWFsKQ0KDQpzdW1tYXJ5KE0yKQ0KDQpgYGANCg0KIyMgQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3RzIChBTUVzKQ0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCg0KYm9vdEZ1bmMgPC0gZnVuY3Rpb24oZGF0YSwgaSkgew0KICBkZiA8LSBkYXRhW2ksXSAjYm9vdHN0cmFwIGRhdGFzZXRzDQogIA0KICBNIDwtIGdsbShzdGFydF9wdWIgfiBldGhuaWNpdHkyLCBmYW1pbHk9Ymlub21pYWwsIGRhdGEgPSBkZikNCiAgDQogIHN1cHByZXNzV2FybmluZ3Moew0KICANCiAgI01FIGV0aG5pY2l0eQ0KICBkZnMwIDwtIGRmczEgPC0gZGYNCiAgZGZzMCRldGhuaWNpdHkyIDwtICJtYWpvcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtICJtaW5vcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtIGZhY3RvcihkZnMxJGV0aG5pY2l0eTIsIGxldmVscz1sZXZlbHMoZGYkZXRobmljaXR5MikpDQogIGRmczAkZXRobmljaXR5MiA8LSBmYWN0b3IoZGZzMCRldGhuaWNpdHkyLCBsZXZlbHM9bGV2ZWxzKGRmJGV0aG5pY2l0eTIpKQ0KDQogICNjYWxjdWxhdGUgdGhlIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzDQogIHAxIDwtIHByZWRpY3QoTSwgdHlwZT0icmVzcG9uc2UiLCBuZXdkYXRhPWRmczEpDQogIHAwIDwtIHByZWRpY3QoTSwgdHlwZT0icmVzcG9uc2UiLCBuZXdkYXRhPWRmczApDQogIA0KICAjIGFuZCB0aGUgbWFyZ2luYWwgZWZmZWN0cw0KICBBTUVfZXRobmljaXR5IDwtIG1lYW4ocDEtcDApDQoNCiAgfSkNCiAgDQogIEFNRV9ldGhuaWNpdHkgI3NhdmUgcmVzdWx0cw0KfQ0KDQpiMiA8LSBib290KGRmX3N0YXJ0aW5nLCBib290RnVuYywgUiA9IDk5OSwgcGFyYWxsZWw9InNub3ciLCBuY3B1cz0xMCkNCmZzYXZlKGIyLCBmaWxlPSJib290Mi5yZGEiLCBsb2NhdGlvbiA9ICIuL3Jlc3VsdHMvc3RhcnRpbmcvIikNCg0KYGBgDQoNCmBgYHtyLCBlaGNvPUZBTFNFfQ0KDQpsb2FkKCIuL3Jlc3VsdHMvc3RhcnRpbmcvYm9vdDIucmRhIikNCmIyIDwtIHgNCnJtKHgpDQpgYGANCg0KDQpgYGB7cn0NCg0Kb3JpZ2luYWwgPC0gYjIkdDANCmJpYXMgPC0gY29sTWVhbnMoYjIkdCkgLSBiMiR0MA0Kc2UgPC0gYXBwbHkoYjIkdCwgMiwgc2QpDQpib290LmRmMiA8LSBkYXRhLmZyYW1lKG9yaWdpbmFsPW9yaWdpbmFsLCBiaWFzPWJpYXMsIHNlPXNlKQ0Kcm93Lm5hbWVzKGJvb3QuZGYyKSA8LSBjKCJBTUVfZXRobmljaXR5IikNCmJvb3QuZGYyJHQgPC0gKGJvb3QuZGYyJG9yaWdpbmFsIC8gYm9vdC5kZjIkc2UpDQpyb3VuZChib290LmRmMiwgNSkNCg0KYGBgDQoNCg0KDQojIE1vZGVsIDM6IEdlbmRlciwgZXRobmljaXR5IGFuZCBjb250cm9scw0KDQpTZWUgW0FwcGVuZGl4IDEgU3BsaW5lc10oc3BsaW5lcy5odG1sKSB0byBzZWUgaG93IHdlIHNlbGVjdGVkIHRoZSBmb2xsb3dpbmcgc3BsaW5lIGNvbmZpZ3VyYXRpb24NCg0KDQpgYGANCmtub3RzNSA8LSBxdWFudGlsZShkZl9zdGFydGluZyRwaGRfY29ob3J0LCBwcm9icz1zZXEoMCwxLDAuMjUpKVsyOjRdDQp0ZXN0MyA8LSBnbG0oc3RhcnRfcHViIH4gYlNwbGluZShwaGRfY29ob3J0LCBrbm90cz1rbm90czUsZGY9MyksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGZfc3RhcnRpbmcpDQpgYGANCg0KDQpgYGB7cn0NCg0Ka25vdHM1IDwtIHF1YW50aWxlKGRmX3N0YXJ0aW5nJHBoZF9jb2hvcnQsIHByb2JzPXNlcSgwLDEsMC4yNSkpWzI6NF0NCg0KTTMgPC0gZ2xtKHN0YXJ0X3B1YiB+IGdlbmRlciArIGV0aG5pY2l0eTIgKyB1bmkgKyBiU3BsaW5lKHBoZF9jb2hvcnQsIGtub3RzPWtub3RzNSxkZj0zKSwgZGF0YSA9IGRmX3N0YXJ0aW5nLCBmYW1pbHkgPSBiaW5vbWlhbCkNCg0Kc3VtbWFyeShNMykNCg0KDQpgYGANCg0KDQojIyBBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdHMgKEFNRXMpDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KDQpib290RnVuYyA8LSBmdW5jdGlvbihkYXRhLCBpKSB7DQogIA0KICBkZiA8LSBkYXRhW2ksXSAjYm9vdHN0cmFwIGRhdGFzZXRzDQogIA0KICBrbm90czUgPC0gcXVhbnRpbGUoZGYkcGhkX2NvaG9ydCwgcHJvYnM9c2VxKDAsMSwwLjI1KSlbMjo0XQ0KDQogIA0KICBNIDwtIGdsbShzdGFydF9wdWIgfiBnZW5kZXIgKyBldGhuaWNpdHkyICsgdW5pICsgc3BsaW5lczI6OmJTcGxpbmUocGhkX2NvaG9ydCwga25vdHM9a25vdHM1LGRmPTMpLCBmYW1pbHk9Ymlub21pYWwsIGRhdGEgPSBkZikNCiAgDQogIHN1cHByZXNzV2FybmluZ3Moew0KDQogICNNRSBnZW5kZXINCiAgZGZzMCA8LSBkZnMxIDwtIGRmDQogIGRmczAkZ2VuZGVyIDwtICJtZW4iDQogIGRmczEkZ2VuZGVyIDwtICJ3b21lbiINCiAgZGZzMSRnZW5kZXIgPC0gZmFjdG9yKGRmczEkZ2VuZGVyLCBsZXZlbHM9bGV2ZWxzKGRmJGdlbmRlcikpDQogIGRmczAkZ2VuZGVyIDwtIGZhY3RvcihkZnMwJGdlbmRlciwgbGV2ZWxzPWxldmVscyhkZiRnZW5kZXIpKQ0KICANCiAgTUVfZ2VuZGVyIDwtIG1lYW4ocHJlZGljdChNLCBkZnMxLCB0eXBlPSJyZXNwb25zZSIpIC0gcHJlZGljdChNLCBkZnMwLCB0eXBlPSJyZXNwb25zZSIpKQ0KICANCiAgI01FIGV0aG5pY2l0eQ0KICBkZnMwIDwtIGRmczEgPC0gZGYNCiAgZGZzMCRldGhuaWNpdHkyIDwtICJtYWpvcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtICJtaW5vcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtIGZhY3RvcihkZnMxJGV0aG5pY2l0eTIsIGxldmVscz1sZXZlbHMoZGYkZXRobmljaXR5MikpDQogIGRmczAkZXRobmljaXR5MiA8LSBmYWN0b3IoZGZzMCRldGhuaWNpdHkyLCBsZXZlbHM9bGV2ZWxzKGRmJGV0aG5pY2l0eTIpKQ0KICANCiAgTUVfZXRobmljaXR5IDwtIG1lYW4ocHJlZGljdChNLCBkZnMxLCB0eXBlPSJyZXNwb25zZSIpIC0gcHJlZGljdChNLCBkZnMwLCB0eXBlPSJyZXNwb25zZSIpKQ0KICANCiAgfSkNCiAgDQogIGMoTUVfZ2VuZGVyLCBNRV9ldGhuaWNpdHkpICNzYXZlIHJlc3VsdHMNCn0NCg0KYjMgPC0gYm9vdChkZl9zdGFydGluZywgYm9vdEZ1bmMsIFIgPSA5OTksIHBhcmFsbGVsPSJzbm93IiwgbmNwdXM9MTApDQpmc2F2ZShiMywgZmlsZT0iYm9vdDMucmRhIiwgbG9jYXRpb24gPSAiLi9yZXN1bHRzL3N0YXJ0aW5nLyIpDQoNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCg0KDQpsb2FkKCIuL3Jlc3VsdHMvc3RhcnRpbmcvYm9vdDMucmRhIikNCmIzIDwtIHgNCnJtKHgpDQoNCmBgYA0KDQpgYGB7cn0NCg0Kb3JpZ2luYWwgPC0gYjMkdDANCmJpYXMgPC0gY29sTWVhbnMoYjMkdCkgLSBiMyR0MA0Kc2UgPC0gYXBwbHkoYjMkdCwgMiwgc2QpDQpib290LmRmMyA8LSBkYXRhLmZyYW1lKG9yaWdpbmFsPW9yaWdpbmFsLCBiaWFzPWJpYXMsIHNlPXNlKQ0Kcm93Lm5hbWVzKGJvb3QuZGYzKSA8LSBjKCJBTUVfZ2VuZGVyIiwiQU1FX2V0aG5pY2l0eSIpDQoNCmJvb3QuZGYzJHQgPC0gKGJvb3QuZGYzJG9yaWdpbmFsIC8gYm9vdC5kZjMkc2UpDQoNCnJvdW5kKGJvb3QuZGYzLCA1KQ0KDQoNCmBgYA0KDQoNCg0KDQojIE1vZGVsIDQ6IEdlbmRlciBhbmQgZXRobmljaXR5LCBjb250cm9scyBhbmQgY29ob3J0IGludGVyYWN0aW9ucw0KDQpgYGB7cn0NCg0KTTQgPC0gZ2xtKHN0YXJ0X3B1YiB+IGdlbmRlciArIGV0aG5pY2l0eTIgKyB1bmkgKyBiU3BsaW5lKHBoZF9jb2hvcnQsIGtub3RzPWtub3RzNSxkZj0zKSArIGdlbmRlcipwaGRfY29ob3J0ICsgZXRobmljaXR5MipwaGRfY29ob3J0LCBkYXRhID0gZGZfc3RhcnRpbmcsIGZhbWlseSA9IGJpbm9taWFsKQ0KDQpzdW1tYXJ5KE00KQ0KDQpgYGANCg0KDQojIyBBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdHMgKEFNRXMpDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KDQpib290RnVuYyA8LSBmdW5jdGlvbihkYXRhLCBpKSB7DQogIGRmIDwtIGRhdGFbaSxdICNib290c3RyYXAgZGF0YXNldHMNCiAgDQogIGtub3RzNSA8LSBxdWFudGlsZShkZiRwaGRfY29ob3J0LCBwcm9icz1zZXEoMCwxLDAuMjUpKVsyOjRdDQogIA0KICBNIDwtIGdsbShzdGFydF9wdWIgfiBnZW5kZXIgKyBldGhuaWNpdHkyICsgdW5pICsgc3BsaW5lczI6OmJTcGxpbmUocGhkX2NvaG9ydCwga25vdHM9a25vdHM1LGRmPTMpICsgcGhkX2NvaG9ydCpnZW5kZXIgKyBwaGRfY29ob3J0KmV0aG5pY2l0eTIsIGZhbWlseT1iaW5vbWlhbCwgZGF0YSA9IGRmKQ0KICANCiAgc3VwcHJlc3NXYXJuaW5ncyh7DQogIA0KICBzIDwtIDAuMQ0KICANCiAgIyBNRSBnZW5kZXINCiAgZGZzMCA8LSBkZnMxIDwtIGRmDQogIGRmczAkZ2VuZGVyIDwtICJtZW4iDQogIGRmczEkZ2VuZGVyIDwtICJ3b21lbiINCiAgZGZzMSRnZW5kZXIgPC0gZmFjdG9yKGRmczEkZ2VuZGVyLCBsZXZlbHM9bGV2ZWxzKGRmJGdlbmRlcikpDQogIGRmczAkZ2VuZGVyIDwtIGZhY3RvcihkZnMwJGdlbmRlciwgbGV2ZWxzPWxldmVscyhkZiRnZW5kZXIpKQ0KICANCiAgTUVfZ2VuZGVyIDwtIG1lYW4ocHJlZGljdChNLCBkZnMxLCB0eXBlPSJyZXNwb25zZSIpIC0gcHJlZGljdChNLCBkZnMwLCB0eXBlPSJyZXNwb25zZSIpKQ0KICANCiAgI01FIGV0aG5pY2l0eQ0KICBkZnMwIDwtIGRmczEgPC0gZGYNCiAgZGZzMCRldGhuaWNpdHkyIDwtICJtYWpvcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtICJtaW5vcml0eSINCiAgZGZzMSRldGhuaWNpdHkyIDwtIGZhY3RvcihkZnMxJGV0aG5pY2l0eTIsIGxldmVscz1sZXZlbHMoZGYkZXRobmljaXR5MikpDQogIGRmczAkZXRobmljaXR5MiA8LSBmYWN0b3IoZGZzMCRldGhuaWNpdHkyLCBsZXZlbHM9bGV2ZWxzKGRmJGV0aG5pY2l0eTIpKQ0KICANCiAgTUVfZXRobmljaXR5IDwtIG1lYW4ocHJlZGljdChNLCBkZnMxLCB0eXBlPSJyZXNwb25zZSIpIC0gcHJlZGljdChNLCBkZnMwLCB0eXBlPSJyZXNwb25zZSIpKQ0KICANCiAgIyBNRSBjb2hvcnQNCiAgZGZzMCA8LSBkZnMxIDwtIGRmDQogIGRmczAkcGhkX2NvaG9ydCA8LSBkZiRwaGRfY29ob3J0IC0gcw0KICBkZnMxJHBoZF9jb2hvcnQgPC0gZGYkcGhkX2NvaG9ydCArIHMNCiAgDQogIE1FX3BoZF9jb2hvcnQgPC0gbWVhbigocHJlZGljdChNLCBkZnMxLCB0eXBlPSJyZXNwb25zZSIpIC0gcHJlZGljdChNLCBkZnMwLCB0eXBlPSJyZXNwb25zZSIpKS8gKDIqcykpDQoNCiAgIyBNRSBnZW5kZXIgKiBjb2hvcnQgDQogIA0KICBkZndvbWVuY3AgPC0gZGZ3b21lbmNtIDwtIGRmbWVuY3AgPC0gZGZtZW5jbSA8LSBkZg0KDQogIGRmd29tZW5jcCRnZW5kZXIgPC0gZGZ3b21lbmNtJGdlbmRlciA8LSAid29tZW4iDQogIGRmbWVuY3AkZ2VuZGVyIDwtIGRmbWVuY20kZ2VuZGVyIDwtICJtZW4iDQoNCiAgZGZ3b21lbmNwJGdlbmRlciA8LSBmYWN0b3IoZGZ3b21lbmNwJGdlbmRlciwgbGV2ZWxzPWxldmVscyhkZiRnZW5kZXIpKQ0KICBkZndvbWVuY20kZ2VuZGVyIDwtIGZhY3RvcihkZndvbWVuY20kZ2VuZGVyLCBsZXZlbHM9bGV2ZWxzKGRmJGdlbmRlcikpDQogIGRmbWVuY3AkZ2VuZGVyIDwtIGZhY3RvcihkZm1lbmNwJGdlbmRlciwgbGV2ZWxzPWxldmVscyhkZiRnZW5kZXIpKQ0KICBkZm1lbmNtJGdlbmRlciA8LSBmYWN0b3IoZGZtZW5jbSRnZW5kZXIsIGxldmVscz1sZXZlbHMoZGYkZ2VuZGVyKSkNCg0KICBkZndvbWVuY3AkcGhkX2NvaG9ydCA8LSBkZm1lbmNwJHBoZF9jb2hvcnQgPC0gZGYkcGhkX2NvaG9ydCArIHMNCiAgZGZ3b21lbmNtJHBoZF9jb2hvcnQgPC0gZGZtZW5jbSRwaGRfY29ob3J0IDwtIGRmJHBoZF9jb2hvcnQgLSBzDQogDQogICNjYWxjdWxhdGUgdGhlIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzDQogIGdwMTEgPC0gcHJlZGljdChNLCB0eXBlPSJyZXNwb25zZSIsIG5ld2RhdGE9ZGZ3b21lbmNwKQ0KICBncDEwIDwtIHByZWRpY3QoTSwgdHlwZT0icmVzcG9uc2UiLCBuZXdkYXRhPWRmd29tZW5jbSkNCiAgZ3AwMSA8LSBwcmVkaWN0KE0sIHR5cGU9InJlc3BvbnNlIiwgbmV3ZGF0YT1kZm1lbmNwKQ0KICBncDAwIDwtIHByZWRpY3QoTSwgdHlwZT0icmVzcG9uc2UiLCBuZXdkYXRhPWRmbWVuY20pDQogIA0KICAjYW5kIHRoZSBtYXJnaW5hbCBlZmZlY3RzLiBiZSBhd2FyZSBvZiBhbGwgdGhlIGJyYWNrZXRzLiA6LSgNCiAgTUVfZ2VuZGVyX2NvaG9ydCA8LSBtZWFuKCgoZ3AxMSAtIGdwMDEpIC0gKGdwMTAgLSBncDAwKSkgLyAoMipzKSkNCg0KICANCiAgDQogICMgTUUgZXRobmljaXR5ICogY29ob3J0DQogIGRmbWlub3JpdHljcCA8LSBkZm1pbm9yaXR5Y20gPC0gZGZkdXRjaGNwIDwtIGRmZHV0Y2hjbSA8LSBkZg0KDQogIGRmbWlub3JpdHljcCRldGhuaWNpdHkyIDwtIGRmbWlub3JpdHljbSRldGhuaWNpdHkyIDwtICJtaW5vcml0eSINCiAgZGZkdXRjaGNwJGV0aG5pY2l0eTIgPC0gZGZkdXRjaGNtJGV0aG5pY2l0eTIgPC0gIm1ham9yaXR5Ig0KDQogIGRmbWlub3JpdHljcCRldGhuaWNpdHkyIDwtIGZhY3RvcihkZm1pbm9yaXR5Y3AkZXRobmljaXR5MiwgbGV2ZWxzPWxldmVscyhkZiRldGhuaWNpdHkyKSkNCiAgZGZtaW5vcml0eWNtJGV0aG5pY2l0eTIgPC0gZmFjdG9yKGRmbWlub3JpdHljbSRldGhuaWNpdHkyLCBsZXZlbHM9bGV2ZWxzKGRmJGV0aG5pY2l0eTIpKQ0KICBkZmR1dGNoY3AkZXRobmljaXR5MiA8LSBmYWN0b3IoZGZkdXRjaGNwJGV0aG5pY2l0eTIsIGxldmVscz1sZXZlbHMoZGYkZXRobmljaXR5MikpDQogIGRmZHV0Y2hjbSRldGhuaWNpdHkyIDwtIGZhY3RvcihkZmR1dGNoY20kZXRobmljaXR5MiwgbGV2ZWxzPWxldmVscyhkZiRldGhuaWNpdHkyKSkNCg0KICBkZm1pbm9yaXR5Y3AkcGhkX2NvaG9ydCA8LSBkZmR1dGNoY3AkcGhkX2NvaG9ydCA8LSBkZiRwaGRfY29ob3J0ICsgcw0KICBkZm1pbm9yaXR5Y20kcGhkX2NvaG9ydCA8LSBkZmR1dGNoY20kcGhkX2NvaG9ydCA8LSBkZiRwaGRfY29ob3J0IC0gcw0KICANCiAgI2NhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMNCiAgZXAxMSA8LSBwcmVkaWN0KE0sIHR5cGU9InJlc3BvbnNlIiwgbmV3ZGF0YT1kZm1pbm9yaXR5Y3ApDQogIGVwMTAgPC0gcHJlZGljdChNLCB0eXBlPSJyZXNwb25zZSIsIG5ld2RhdGE9ZGZtaW5vcml0eWNtKQ0KICBlcDAxIDwtIHByZWRpY3QoTSwgdHlwZT0icmVzcG9uc2UiLCBuZXdkYXRhPWRmZHV0Y2hjcCkNCiAgZXAwMCA8LSBwcmVkaWN0KE0sIHR5cGU9InJlc3BvbnNlIiwgbmV3ZGF0YT1kZmR1dGNoY20pDQogIA0KDQogICNhbmQgdGhlIG1hcmdpbmFsIGVmZmVjdHMuIGJlIGF3YXJlIG9mIGFsbCB0aGUgYnJhY2tldHMuIDotKA0KICBNRV9ldGhuaWNpdHlfY29ob3J0IDwtIG1lYW4oKChlcDExIC0gZXAwMSkgLSAoZXAxMCAtIGVwMDApKSAvICgyKnMpKQ0KDQogIH0pDQogIA0KICBjKE1FX2dlbmRlciwgTUVfZXRobmljaXR5LCBNRV9waGRfY29ob3J0LCBNRV9nZW5kZXJfY29ob3J0LCBNRV9ldGhuaWNpdHlfY29ob3J0KSAjc2F2ZSByZXN1bHRzDQp9DQoNCmI0IDwtIGJvb3QoZGZfc3RhcnRpbmcsIGJvb3RGdW5jLCBSID0gOTk5LCBwYXJhbGxlbD0ic25vdyIsIG5jcHVzPTEwKQ0KZnNhdmUoYjQsIGZpbGU9ImJvb3Q0LnJkYSIsIGxvY2F0aW9uID0gIi4vcmVzdWx0cy9zdGFydGluZy8iKQ0KDQoNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCg0KbG9hZCgiLi9yZXN1bHRzL3N0YXJ0aW5nL2Jvb3Q0LnJkYSIpDQpiNCA8LSB4DQpybSh4KQ0KDQpgYGANCg0KYGBge3J9DQoNCm9yaWdpbmFsIDwtIGI0JHQwDQpiaWFzIDwtIGNvbE1lYW5zKGI0JHQpIC0gYjQkdDANCnNlIDwtIGFwcGx5KGI0JHQsIDIsIHNkKQ0KDQpib290LmRmNCA8LSBkYXRhLmZyYW1lKG9yaWdpbmFsPW9yaWdpbmFsLCBiaWFzPWJpYXMsIHNlPXNlKQ0Kcm93Lm5hbWVzKGJvb3QuZGY0KSA8LSBjKCJBTUVfZ2VuZGVyIiwgIkFNRV9ldGhuaWNpdHkiLCAiQU1FX2NvaG9ydCIsICJBTUVfZ2VuZGVyX2NvaG9ydCIsICJBTUVfZXRobmljaXR5X2NvaG9ydCIpDQoNCmJvb3QuZGY0JHQgPC0gKGJvb3QuZGY0JG9yaWdpbmFsIC8gYm9vdC5kZjQkc2UpDQoNCnJvdW5kKGJvb3QuZGY0LCA1KQ0KDQoNCmBgYA0KDQoNCg0KIyBUYWJsZSAzDQoNCg0KYGBge3J9DQoNCmNvbHVtbnMgPC0gYyhyZXAoYygiQiIsICJTRSIpLCA0KSkNCnJvd3MgPC0gYygiSW50ZXJjZXB0IiwgIkdlbmRlcjogcmVmPW1lbiIgLCJXb21lbiIsICJNaXNzaW5nIGdlbmRlciIsICJFdGhuaWNpdHk6IHJlZj1tYWpvcml0eSIsIk1pbm9yaXR5IiwgIk90aGVyIiwgIlVuaXZlcnNpdHk6IHJlZj1FcmFzbXVzIFVuaXZlcnNpdHkiLCAiTGVpZGVuIFVuaXZlcnNpdHkiLCAiUmFkYm91ZCBVbml2ZXJzaXR5IiwgIlVuaXZlcnNpdHkgb2YgR3JvbmluZ2VuIiwgIkRlbGZ0IFVuaXZlcnNpdHkgb2YgVGVjaG5vbG9neSIsICJFaW5kaG92ZW4gVW5pdmVyc2l0eSBvZiBUZWNobm9sb2d5IiwgIlRpbGJ1cmcgVW5pdmVyc2l0eSIsICJNYWFzdHJpY2h0IFVuaXZlcnNpdHkiLCAiVW5pdmVyc2l0eSBvZiBUd2VudGUiLCAiVXRyZWNodCBVbml2ZXJzaXR5IiwgIlVuaXZlcnNpdHkgb2YgQW1zdGVyZGFtIiwgIlZyaWplIFVuaXZlcnNpdGVpdCBBbXN0ZXJkYW0iLCAiV2FnZW5pbmdlbiBVbml2ZXJzaXR5IGFuZCBSZXNlYXJjaCBDZW50cmUiLCAiUGhEIGNvaG9ydCIsIktub3QgIzEiLCAiS25vdCAjMiIsICJLbm90ICMzIiwgIktub3QgIzQiLCAiS25vdCAjNSIsICJLbm90ICM2IiwgIkNvaG9ydCBpbnRlcmFjdGlvbnMiLCJQaEQgY29ob3J0ICogd29tYW4iLCAiUGhEIGNvaG9ydCAqIG1pc3NpbmcgZ2VuZGVyIiwgIlBoRCBjb2hvcnQgKiBldGhuaWMgbWlub3JpdHkiLCAiUGhEIGNvaG9ydCAqIG90aGVyIGV0aG5pY2l0eSIsICI8c3Ryb25nPkFJQzwvc3Ryb25nPjwvcD4iLCAiPHN0cm9uZz5OPC9zdHJvbmc+PC9wPiIpDQoNCnQzIDwtIGRhdGEuZnJhbWUobWF0cml4KG5yb3c9bGVuZ3RoKHJvd3MpLCBuY29sPWxlbmd0aChjb2x1bW5zKSkpDQpjb2xuYW1lcyh0MykgPC0gY29sdW1ucw0Kcm93bmFtZXModDMpIDwtIHJvd3MNCg0KIyBuYW1lcyhNNCRjb2VmZmljaWVudHMpDQoNCiMgTW9kZWwgMQ0KdDNbYygxLDMsNCksIDFdIDwtIE0xJGNvZWZmaWNpZW50cyAjIGxvZyBvZGRzDQp0M1tjKDEsMyw0KSwgMl0gPC0gc3VtbWFyeShNMSkkY29lZmZpY2llbnRzWywyXSAjIFNFIGxvZyBvZGRzDQoNCiMgTW9kZWwgMg0KdDNbYygxLDYsNyksM10gPC0gTTIkY29lZmZpY2llbnRzDQp0M1tjKDEsNiw3KSw0XSA8LSBzdW1tYXJ5KE0yKSRjb2VmZmljaWVudHNbLDJdDQoNCiMgTW9kZWwgMw0KdDNbYygxLDM6NCw2OjcsOToyMCwyMjoyNyksNV0gPC0gTTMkY29lZmZpY2llbnRzDQp0M1tjKDEsMzo0LDY6Nyw5OjIwLDIyOjI3KSwgNl0gPC0gc3VtbWFyeShNMykkY29lZmZpY2llbnRzWywyXQ0KDQojIE1vZGVsIDQNCk00XyA8LSBkYXRhLmZyYW1lKHN1bW1hcnkoTTQpJGNvZWZmaWNpZW50c1ssMV0pDQpNNF9bLDJdIDwtIHN1bW1hcnkoTTQpJGNvZWZmaWNpZW50c1ssMl0NCnQzW2MoMSwzOjQsNjo3LDk6MjAsIDIyOjI3LCAyOTozMiksN10gPC0gTTRfWywxXQ0KdDNbYygxLDM6NCw2OjcsOToyMCwgMjI6MjcsIDI5OjMyKSw4XSA8LSBNNF9bLDJdDQoNCiMgQUlDDQp0M1szMywxXSA8LSByb3VuZChNMSRhaWMsIDApDQp0M1szMywzXSA8LSByb3VuZChNMiRhaWMsIDApDQp0M1szMyw1XSA8LSByb3VuZChNNCRhaWMsIDApDQp0M1szMyw3XSA8LSByb3VuZChNNCRhaWMsIDApDQoNCiMgcm91bmRpbmcNCnQzW2MoMSwzLDQpLGMoMSwyKV0gPC0gZm9ybWF0KHJvdW5kKHQzW2MoMSwzLDQpLGMoMSwyKV0sMiksIG5zbWFsbD0yKQ0KdDNbYygxLDYsNyksYygzLDQpXSA8LSBmb3JtYXQocm91bmQodDNbYygxLDYsNyksYygzLDQpXSwyKSwgbnNtYWxsPTIpDQp0M1tjKDEsMyw0LDYsNyw5OjIwLDIyOjI3KSxjKDU6NildIDwtIGZvcm1hdChyb3VuZCh0M1tjKDEsMyw0LDYsNyw5OjIwLDIyOjI3KSxjKDU6NildLDIpLCBuc21hbGw9MikNCnQzW2MoMSwzLDQsNiw3LDk6MjAsIDIyOjI3LCAyOTozMiksYyg3LDgpXSA8LSBmb3JtYXQocm91bmQodDNbYygxLDMsNCw2LDcsOToyMCwgMjI6MjcsIDI5OjMyKSxjKDcsOCldLDIpLCBuc21hbGw9MikNCg0KIyBzYW1wbGUgc2l6ZQ0KdDNbMzQsIGMoMSwzLDUsNyldIDwtIHJlcChucm93KGRmX3N0YXJ0aW5nKSwgNCkNCg0KIyBBZGRpbmcgc2lnbmlmaWNhbmNlIGNvZGVzDQp0M1sxLDFdIDwtIHBhc3RlMCh0M1sxLDFdLCAiKioqIikgIyBpbnRlcmNlcHQNCnQzWzEsM10gPC0gcGFzdGUwKHQzWzEsM10sICIqKioiKQ0KdDNbMSw1XSA8LSBwYXN0ZTAodDNbMSw1XSwgIioqKiIpIA0KdDNbMSw3XSA8LSBwYXN0ZTAodDNbMSw3XSwgIioqKiIpDQp0M1szLDFdIDwtIHBhc3RlMCh0M1szLDFdLCAiKiIpICAgIyBnZW5kZXINCnQzWzQsMV0gPC0gcGFzdGUwKHQzWzQsMV0sICIqKioiKSAjIGdlbmRlciBtaXNzaW5nDQp0M1s0LDVdIDwtIHBhc3RlMCh0M1s0LDVdLCAiKioqIikNCnQzWzQsN10gPC0gcGFzdGUwKHQzWzQsN10sICIqKioiKQ0KdDNbNiwzXSA8LSBwYXN0ZTAodDNbNiwzXSwgIioqKiIpICMgZXRobmljIG1pbm9yaXRpZXMNCnQzWzYsNV0gPC0gcGFzdGUwKHQzWzYsNV0sICIqKioiKQ0KdDNbNywzXSA8LSBwYXN0ZTAodDNbNywzXSwgIioqKiIpICMgb3RoZXIgZXRobmljaXR5DQp0M1s3LDVdIDwtIHBhc3RlMCh0M1s3LDVdLCAiKioqIikNCnQzWzcsN10gPC0gcGFzdGUwKHQzWzcsN10sICIqKioiKQ0KdDNbMTAsNV0gPC0gcGFzdGUwKHQzWzEwLDVdLCIqKioiKSAgIyBSVQ0KdDNbMTAsN10gPC0gcGFzdGUwKHQzWzEwLDddLCIqKioiKQ0KdDNbMTEsNV0gPC0gcGFzdGUwKHQzWzExLDVdLCAiKioqIikgIyBSVUcNCnQzWzExLDddIDwtIHBhc3RlMCh0M1sxMSw3XSwgIioqKiIpDQp0M1sxMiw1XSA8LSBwYXN0ZTAodDNbMTIsNV0sICIqKioiKSAjIFRVRA0KdDNbMTIsN10gPC0gcGFzdGUwKHQzWzEyLDddLCAiKioqIikNCnQzWzEzLDVdIDwtIHBhc3RlMCh0M1sxMyw1XSwgIioqKiIpICMgVFVFDQp0M1sxMyw3XSA8LSBwYXN0ZTAodDNbMTMsN10sICIqKioiKQ0KdDNbMTUsNV0gPC0gcGFzdGUwKHQzWzE1LDVdLCAiKioqIikgIyBVTQ0KdDNbMTUsN10gPC0gcGFzdGUwKHQzWzE1LDddLCAiKioqIikNCnQzWzE2LDVdIDwtIHBhc3RlMCh0M1sxNiw1XSwgIioqKiIpICNVVA0KdDNbMTYsN10gPC0gcGFzdGUwKHQzWzE2LDddLCAiKioqIikNCnQzWzE3LDVdIDwtIHBhc3RlMCh0M1sxNyw1XSwgIioqKiIpICNVVQ0KdDNbMTcsN10gPC0gcGFzdGUwKHQzWzE3LDddLCAiKioqIikNCnQzWzE4LDVdIDwtIHBhc3RlMCh0M1sxOCw1XSwgIioqKiIpICNVdkENCnQzWzE4LDddIDwtIHBhc3RlMCh0M1sxOCw3XSwgIioqKiIpDQp0M1sxOSw1XSA8LSBwYXN0ZTAodDNbMTksNV0sICIqKioiKSAjVlUNCnQzWzE5LDddIDwtIHBhc3RlMCh0M1sxOSw3XSwgIioqKiIpDQp0M1syMCw1XSA8LSBwYXN0ZTAodDNbMjAsNV0sICIqKioiKSAjV1VSDQp0M1syMCw3XSA8LSBwYXN0ZTAodDNbMjAsN10sICIqKioiKQ0KdDNbMjIsNV0gPC0gcGFzdGUwKHQzWzIyLDVdLCAiKioqIikgIyBjb2ggMQ0KdDNbMjIsN10gPC0gcGFzdGUwKHQzWzIyLDddLCAiKioqIikgDQp0M1syNCw1XSA8LSBwYXN0ZTAodDNbMjQsNV0sICIqKioiKSAjIGNvaCAzDQp0M1syNCw3XSA8LSBwYXN0ZTAodDNbMjQsN10sICIqKioiKSANCnQzWzI1LDVdIDwtIHBhc3RlMCh0M1syNSw1XSwgIioqKiIpICMgY29oIDQNCnQzWzI2LDVdIDwtIHBhc3RlMCh0M1syNiw1XSwgIioqKiIpICMgY29oIDUNCnQzWzI2LDddIDwtIHBhc3RlMCh0M1syNiw3XSwgIioiKSANCnQzWzI3LDVdIDwtIHBhc3RlMCh0M1syNyw1XSwgIioqKiIpICMgY29oIDYNCnQzWzMwLDddIDwtIHBhc3RlMCh0M1szMCw3XSwgIioqKiIpICMgY29oICogZ2VuZGVyIG1pc3NpbmcNCg0KdDNbaXMubmEodDMpXSA8LSAiIg0KDQoNCmBgYA0KDQpgYGB7cn0NCg0KdDMgJT4lDQogIGthYmxlKGZvcm1hdCA9ICdodG1sJywgY2FwdGlvbiA9ICc8Yj5UYWJsZSAzLjwvYj4gTG9naXN0aWMgcmVncmVzc2lvbiBvbiBzdGFydGluZyB0byBwdWJsaXNoJywgZXNjYXBlPUZBTFNFKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZSguLGMoJyAnPTEsICdNb2RlbCAxJz0yLCAnTW9kZWwgMic9MiwgJ01vZGVsIDMnPTIsICdNb2RlbCA0Jz0yKSwgZXNjYXBlID0gRkFMU0UsIGJvbGQgPSBUUlVFKSAlPiUNCiAgcm93X3NwZWMocm93PWMoMiw1LDgsMjEsMjgpLCBib2xkPVQpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEyKSAtPiB0YWJsZTMNCg0KdGFibGUzDQoNCmBgYA0KDQoNCg0KDQojIFJvYnVzdG5lc3MgY2hlY2tzDQoNCg0KIyMgRXRobmljaXR5IG1pc3NpbmcgYW5kIG90aGVyIHNlcGFyYXRlbHkNCg0KDQpgYGB7cn0NCg0KTTJiIDwtIGdsbShzdGFydF9wdWIgfiBldGhuaWNpdHkzICwgZGF0YSA9IGRmX3N0YXJ0aW5nLCBmYW1pbHkgPSBiaW5vbWlhbCkNCnN1bW1hcnkoTTJiKQ0KDQpNM2IgPC0gZ2xtKHN0YXJ0X3B1YiB+IGdlbmRlciArIGV0aG5pY2l0eTMgKyB1bmkgKyBiU3BsaW5lKHBoZF9jb2hvcnQsIGtub3RzPWtub3RzNSxkZj0zKSwgZGF0YSA9IGRmX3N0YXJ0aW5nLCBmYW1pbHkgPSBiaW5vbWlhbCkNCnN1bW1hcnkoTTNiKQ0KDQpNNGIgPC0gZ2xtKHN0YXJ0X3B1YiB+IGdlbmRlciArIGV0aG5pY2l0eTMgKyB1bmkgKyBiU3BsaW5lKHBoZF9jb2hvcnQsIGtub3RzPWtub3RzNSxkZj0zKSArIGdlbmRlcipwaGRfY29ob3J0ICsgZXRobmljaXR5MypwaGRfY29ob3J0LCBkYXRhID0gZGZfc3RhcnRpbmcsIGZhbWlseSA9IGJpbm9taWFsKQ0Kc3VtbWFyeShNNGIpDQoNCg0KYGBgDQoNCg0KIyMgRXRobmljaXR5IGJ5IFBoRCB5ZWFyDQoNCmBgYHtyfQ0KDQpkZl9zdGFydGluZyAlPiUNCiAgZ3JvdXBfYnkocGhkX3llYXIsIGV0aG5pY2l0eTMpICU+JQ0KICBzdW1tYXJpemUoZnJlcXVlbmN5ID0gbigpKSAtPiBldGhuaWNpdHlfeWVhcg0KDQoNCg0KZXRobmljaXR5X3llYXINCg0KZXlfMTk5NCA8LSBldGhuaWNpdHlfeWVhcltldGhuaWNpdHlfeWVhciRwaGRfeWVhcjwxOTk1ICYgZXRobmljaXR5X3llYXIkZXRobmljaXR5Mz09Im1pbm9yaXR5IixdDQoNCm1lYW4oZXlfMTk5NCRmcmVxdWVuY3kpDQoNCg0KZXlfMTk5OSA8LSBldGhuaWNpdHlfeWVhcltldGhuaWNpdHlfeWVhciRwaGRfeWVhcjwyMDAwICYgZXRobmljaXR5X3llYXIkcGhkX3llYXI+MTk5NCAmIGV0aG5pY2l0eV95ZWFyJGV0aG5pY2l0eTM9PSJtaW5vcml0eSIsXSAjIDk1LTk5DQoNCm1lYW4oZXlfMTk5OSRmcmVxdWVuY3kpDQoNCg0KDQpleV8yMDA5IDwtIGV0aG5pY2l0eV95ZWFyW2V0aG5pY2l0eV95ZWFyJHBoZF95ZWFyPjE5OTkgJiBldGhuaWNpdHlfeWVhciRwaGRfeWVhcjwyMDEwICYgZXRobmljaXR5X3llYXIkZXRobmljaXR5Mz09Im1pbm9yaXR5IixdICMgMDAtMDkNCg0KbWVhbihleV8yMDA5JGZyZXF1ZW5jeSkNCg0KDQpleV8yMDEwcCA8LSBldGhuaWNpdHlfeWVhcltldGhuaWNpdHlfeWVhciRwaGRfeWVhcj4yMDA5ICYgZXRobmljaXR5X3llYXIkZXRobmljaXR5Mz09Im1pbm9yaXR5IixdICMgMDAtMDkNCg0KbWVhbihleV8yMDEwcCRmcmVxdWVuY3kpDQoNCg0KYGBgDQoNCg0KDQoNCi0tLS0tDQo=


Copyright © 2023