Packages

# install.packages("fastglm")
library(survey)
Loading required package: grid
Loading required package: Matrix
Loading required package: survival

Attaching package: ‘survey’

The following object is masked from ‘package:graphics’:

    dotchart
library(glmnet)
Loading required package: foreach
Loaded glmnet 2.0-18
library(tidyverse)
── Attaching packages ────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 3.2.0     ✔ purrr   0.3.2
✔ tibble  2.1.3     ✔ dplyr   0.8.1
✔ tidyr   0.8.3     ✔ stringr 1.4.0
✔ readr   1.3.1     ✔ forcats 0.4.0
── Conflicts ───────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ purrr::accumulate() masks foreach::accumulate()
✖ tidyr::expand()     masks Matrix::expand()
✖ dplyr::filter()     masks stats::filter()
✖ dplyr::lag()        masks stats::lag()
✖ purrr::when()       masks foreach::when()
library(xtable)
library(future)

Attaching package: ‘future’

The following object is masked from ‘package:survival’:

    cluster
library(vcd)
library(doFuture)
Loading required package: globals
Loading required package: iterators
Loading required package: parallel
library(fastglm)
source("../codes/adalasso-chen-phd.R")

Data

totals <- readRDS("../data/gus-woj-sek-boot-totals.rds") %>%
  filter(substr(kod2,1,1) != 6) %>%
  mutate(kod2 = ifelse(kod2 == 95, 96, kod2),
         kod2 = ifelse(kod2 == 92, 91, kod2),
         kod2 = ifelse(kod2 == 53, 54, kod2),
         #kod1 = as.character(kod1),
         kod2 = as.character(kod2),
         rok = as.character(rok)) 
head(totals)
final_data <- readRDS("../data/bkl-final.rds") %>%
  filter(zawod1 != 6, rok!=2012, nace %in% unique(totals$sekcja)) %>%
  mutate(zawod2 = ifelse(zawod2 == 95, 96, zawod2),
         zawod2 = ifelse(zawod2 == 92, 91, zawod2),
         zawod2 = ifelse(zawod2 == 99, 96, zawod2),
         zawod2 = ifelse(zawod2 == 53, 54, zawod2),
         zeros = str_extract(zawod6, "0+$"),
         zeros = str_count(zeros, "0"),
         zeros = ifelse(is.na(zeros), 6, 6-zeros),
         rok = as.character(rok)) %>%
  rename(kod1 = zawod1,
         kod2 = zawod2,
         kod6 = zawod6,
         sekcja = nace) %>%
  filter(zeros > 1) 

Correlations

final_data %>%
  select(kod2, woj, sekcja, komp_techniczne:komp_biurowe) %>%
  gather(comps, vals, komp_techniczne:komp_biurowe) -> for_corr
for_corr  %>%
  count(kod2, comp=comps, vals) %>%
  group_by(comp) %>%
  do(occupancy = xtabs(n~vals + kod2, data = .) %>% assocstats(.) %>% .$cramer) %>%
  unnest() %>%
  left_join(
    for_corr  %>%
  count(sekcja, comp=comps, vals) %>%
  group_by(comp) %>%
  do(NACE = xtabs(n~vals + sekcja, data = .) %>% assocstats(.) %>% .$cramer) %>%
  unnest()) %>%
  left_join(for_corr  %>%
  count(woj, comp=comps, vals) %>%
  group_by(comp) %>%
  do(Voivodeship = xtabs(n~vals + woj, data = .) %>% assocstats(.) %>% .$cramer) %>%
  unnest()) %>%
  mutate(comp = case_when(comp == "komp_kulturalne" ~ "Artistic",
                            comp == "komp_dyspozycyjne"~ "Availability",
                            comp == "komp_kognitywne" ~ "Cognitive",
                            comp == "komp_komputerowe" ~ "Computer",
                            comp == "komp_interpersonalne" ~ "Interpersonal",
                            comp == "komp_kierownicze" ~ "Managerial",
                            comp == "komp_matematyczne" ~ "Mathematical",
                            comp == "komp_biurowe"~ "Office",
                            comp == "komp_fizyczne" ~ "Physical",
                            comp == "komp_indywidualne"~ "Self-organization",
                            comp =="komp_techniczne"  ~ "Technical")) %>%
  arrange(comp) %>%
  xtable(digits = 2) %>%
  print.xtable(include.rownames = F)
Joining, by = "comp"
Joining, by = "comp"
% latex table generated in R 3.5.1 by xtable 1.8-4 package
% Wed Jul 24 14:01:48 2019
\begin{table}[ht]
\centering
\begin{tabular}{lrrr}
  \hline
comp & occupancy & NACE & Voivodeship \\ 
  \hline
Artistic & 0.22 & 0.11 & 0.05 \\ 
  Availability & 0.15 & 0.14 & 0.05 \\ 
  Cognitive & 0.21 & 0.06 & 0.06 \\ 
  Computer & 0.45 & 0.23 & 0.10 \\ 
  Interpersonal & 0.42 & 0.23 & 0.06 \\ 
  Managerial & 0.34 & 0.15 & 0.04 \\ 
  Mathematical & 0.05 & 0.02 & 0.03 \\ 
  Office & 0.11 & 0.06 & 0.03 \\ 
  Physical & 0.17 & 0.09 & 0.04 \\ 
  Self-organization & 0.34 & 0.19 & 0.04 \\ 
  Technical & 0.31 & 0.11 & 0.07 \\ 
   \hline
\end{tabular}
\end{table}
vcd::assocstats(xtabs(~komp_indywidualne + kod1 + rok, data = final_data)) %>% map("cramer")
$`rok:2011`
[1] 0.2501016

$`rok:2013`
[1] 0.231543

$`rok:2014`
[1] 0.2218449
vcd::assocstats(xtabs(~komp_indywidualne + kod2 + rok, data = final_data)) %>% map("cramer")
$`rok:2011`
[1] 0.3659692

$`rok:2013`
[1] 0.3381546

$`rok:2014`
[1] 0.3601699

Calibration

des <- svydesign(ids = ~1, data = final_data)
No weights or probabilities supplied, assuming equal probability

Calibration based on kod2

registerDoFuture()
plan(multiprocess)

tic <- Sys.time()
res_calib <- foreach(i = 1:500, .export = c("wynik")) %dopar% {
  set.seed(i)
  
  totals_kod2 <- subset(totals, subset = b == i)

  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_kod2 %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m )
  
  des_kod2 <- svydesign(ids = ~1, weight = ~weight, data = final_data_kod2)
  
  tot_kod2 <- xtabs(hat_wolne~rok + kod2, data = totals_kod2)
  tot_sek <- xtabs(hat_wolne~rok + sekcja, data = totals_kod2)
  cal_kod2 <- calibrate(design = des_kod2, formula = list(~rok + kod2), 
                      population = list(tot_kod2))
  cal_kod2_sek <- rake(design = des_kod2, 
                     sample.margins = list(~rok + kod2, ~rok + sekcja), 
                     population.margins = list(tot_kod2, tot_sek), control = list(maxit = 50))
  
  svyby(formula = ~komp_techniczne + komp_matematyczne + komp_kulturalne + komp_komputerowe + 
        komp_kognitywne + komp_kierownicze + komp_interpersonalne + 
        komp_indywidualne + komp_fizyczne + komp_dyspozycyjne + komp_biurowe, 
      by = ~ rok, 
      FUN = svymean, 
      design = cal_kod2) %>%
  select(rok, komp_techniczne:komp_biurowe) -> wyn1 
  
  svyby(formula = ~komp_techniczne + komp_matematyczne + komp_kulturalne + komp_komputerowe + 
        komp_kognitywne + komp_kierownicze + komp_interpersonalne + 
        komp_indywidualne + komp_fizyczne + komp_dyspozycyjne + komp_biurowe, 
      by = ~ rok, 
      FUN = svymean, 
      design = cal_kod2_sek) %>%
  select(rok, komp_techniczne:komp_biurowe) -> wyn2
  
  wynik <- list(calib_kod2=wyn1, 
                calib_kod2_w = weights(cal_kod2),
                calib_kod2_sek=wyn2,
                calib_kod2_sek_w = weights(cal_kod2_sek))
  
}

Sys.time() - tic
saveRDS(res_calib, file = "../results/res_calib.rds")

Model-calibration - GLM

tic <- Sys.time()
res_glm_kod2 <- foreach(i = 1:500, .export = c("wynik")) %dopar% {
  set.seed(i)
  
  totals_boot <- totals %>% filter(b == i)
  
  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_boot %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m ) %>%
      as.data.frame()
    X <- Matrix::fac2sparse(final_data_kod2$kod2) %>% t() 
    wynik_est <- list()
    wynik_wt <- list()
    wynik_model <- list()
    for (k in 1:length(komps)) {
      
        m1 <- fastglm(x = as.matrix(cbind(1,X[,-1])), y = as.matrix(final_data_kod2[,komps[k]]), 
                      family = binomial(), method = 2)
  
        X_tot <- Matrix::fac2sparse(totals_boot$kod2) %>% t() 
        lin_pred  <- as.numeric(cbind(1, X_tot[,-1]) %*% m1$coefficients)
        t1 <- totals_boot
        t2 <- totals_boot
        t1$pred <- exp(lin_pred) / (1 + exp(lin_pred))
        t2$pred <- 0
        t1$flag <- "1"
        t2$flag <- "0"
  
        totals_cal <- as.data.frame(rbind(t1,t2))
        totals_cal$wt  <- ifelse(totals_cal$flag  == 1, totals_cal$pred*totals_cal$hat_wolne, totals_cal$hat_wolne)
        tab_totals <- xtabs(wt~ rok + flag, data = totals_cal)
        tab_totals[,1] <- tab_totals[,1] - tab_totals[,2]
        final_data_kod2$flag <- as.character(final_data_kod2[,komps[k]])
        glm_kod2 <- svydesign(ids = ~1, weight = ~ weight, data = final_data_kod2)
        cal_glm_kod2 <- calibrate(design = glm_kod2, 
                                    formula = list(~rok + flag), 
                                    population = list(tab_totals))
  
      svyby(formula = as.formula(paste("~", komps[k])), 
            by = ~ rok, 
            FUN = svymean, 
            design = cal_glm_kod2) %>%
        dplyr::select(-se) -> wyn
      wynik_est[[k]] <- wyn
      wynik_wt[[k]] <- weights(cal_glm_kod2)
      wynik_model[[k]] <- m1
}
wynik <- list(wynik_est = bind_cols(wynik_est) %>% select(rok, starts_with("komp")), 
              wynik_wt = bind_cols(wynik_wt),
              wynik_model = wynik_model)
}
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
Joining, by = "rok"
toc <- Sys.time() - tic
toc
Time difference of 2.531316 hours

Lasso

Kalibracja wg kod2 + nace

registerDoFuture()
plan(multiprocess)
tic <- Sys.time()
komps <- c("komp_techniczne", "komp_matematyczne", "komp_kulturalne", "komp_komputerowe", 
                             "komp_kognitywne", "komp_kierownicze", "komp_interpersonalne", 
                             "komp_indywidualne", "komp_fizyczne", "komp_dyspozycyjne", "komp_biurowe")

res_lasso_kod2 <- foreach(i = 1:500, .export = c("wynik")) %dopar% {
  
  set.seed(i)
  
  totals_boot <- totals %>% filter(b == i)
  
  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_boot %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m ) %>%
      as.data.frame()

    X <- Matrix::fac2sparse(final_data_kod2$kod2) %>% t() 

    wynik_est <- list()
    wynik_wt <- list()
    wynik_model <- list()
    for (k in 1:length(komps)) {
      
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T)
        X_tot <- Matrix::fac2sparse(totals_boot$kod2) %>% t() 
        lin_pred  <- as.numeric(cbind(1, X_tot) %*% m1$coef)
        t1 <- totals_boot
        t2 <- totals_boot
        t1$pred <- exp(lin_pred) / (1 + exp(lin_pred))
        t2$pred <- 0
        t1$flag <- "1"
        t2$flag <- "0"
  
        totals_cal <- as.data.frame(rbind(t1,t2))
        totals_cal$wt  <- ifelse(totals_cal$flag  == 1, totals_cal$pred*totals_cal$hat_wolne, totals_cal$hat_wolne)
        tab_totals <- xtabs(wt~ rok + flag, data = totals_cal)
        tab_totals[,1] <- tab_totals[,1] - tab_totals[,2]
        final_data_kod2$flag <- as.character(final_data_kod2[,komps[k]])
        lasso_kod2 <- svydesign(ids = ~1, weight = ~ weight, data = final_data_kod2)
        cal_lasso_kod2 <- calibrate(design = lasso_kod2, 
                                    formula = list(~rok + flag), 
                                    population = list(tab_totals))
  
      svyby(formula = as.formula(paste("~", komps[k])), 
            by = ~ rok, 
            FUN = svymean, 
            design = cal_lasso_kod2) %>%
        select(-se) -> wyn

      wynik_est[[k]] <- wyn
      wynik_wt[[k]] <- weights(cal_lasso_kod2)
      wynik_model[[k]] <- m1
}


wynik <- list(wynik_est = bind_cols(wynik_est) %>% select(rok, starts_with("komp")), 
              wynik_wt = bind_cols(wynik_wt),
              wynik_model = wynik_model)


}

toc <- Sys.time() - tic
toc
saveRDS(res_lasso_kod2, file = "../results/res_lasso_kod2.rds")

Kalibracja wg kod2 + nace

tic <- Sys.time()
res_lasso_kod2_nace <- foreach(i = 1:500, .export = c("wynik")) %dopar% {
  
  set.seed(i)
  
  totals_boot <- totals %>% filter(b == i)
  
  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_boot %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m ) %>%
      as.data.frame()

    
    Xkod <- Matrix::fac2sparse(final_data_kod2$kod2) %>% t() 
    Xsek <- Matrix::fac2sparse(final_data_kod2$sekcja) %>% t() 
    X <- cbind(Xkod, Xsek) 

    wynik_est <- list()
    wynik_wt <- list()
    wynik_model <- list()
    for (k in 1:length(komps)) {
      
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T)
        Xkod_tot <- Matrix::fac2sparse(totals_boot$kod2) %>% t() 
        Xsek_tot <- Matrix::fac2sparse(totals_boot$sekcja) %>% t() 
        X_tot <- cbind(Xkod_tot, Xsek_tot)
        lin_pred  <- as.numeric(cbind(1, X_tot) %*% m1$coef)
        t1 <- totals_boot
        t2 <- totals_boot
        t1$pred <- exp(lin_pred) / (1 + exp(lin_pred))
        t2$pred <- 0
        t1$flag <- "1"
        t2$flag <- "0"
  
        totals_cal <- as.data.frame(rbind(t1,t2))
        totals_cal$wt  <- ifelse(totals_cal$flag  == 1, totals_cal$pred*totals_cal$hat_wolne, totals_cal$hat_wolne)
        tab_totals <- xtabs(wt~ rok + flag, data = totals_cal)
        tab_totals[,1] <- tab_totals[,1] - tab_totals[,2]
        final_data_kod2$flag <- as.character(final_data_kod2[,komps[k]])
        lasso_kod2 <- svydesign(ids = ~1, weight = ~ weight, data = final_data_kod2)
        cal_lasso_kod2 <- calibrate(design = lasso_kod2, 
                                    formula = list(~rok + flag), 
                                    population = list(tab_totals))
  
      svyby(formula = as.formula(paste("~", komps[k])), 
            by = ~ rok, 
            FUN = svymean, 
            design = cal_lasso_kod2) %>%
        select(-se) -> wyn

      wynik_est[[k]] <- wyn
      wynik_wt[[k]] <- weights(cal_lasso_kod2)
      wynik_model[[k]] <- m1
}


wynik <- list(wynik_est = bind_cols(wynik_est) %>% select(rok, starts_with("komp")), 
              wynik_wt = bind_cols(wynik_wt),
              wynik_model = wynik_model)
}
toc <- Sys.time() - tic
toc
saveRDS(res_lasso_kod2_nace, file = "../results/res_lasso_kod2_nace.rds")

Adaptive lasso

registerDoFuture()
plan(multiprocess)
[ONE-TIME WARNING] Forked processing ('multicore') is disabled in future (>= 1.13.0) when running R from RStudio, because it is considered unstable. Because of this, plan("multicore") will fall back to plan("sequential"), and plan("multiprocess") will fall back to plan("multisession") - not plan("multicore") as in the past. For more details, how to control forked processing or not, and how to silence this warning in future R sessions, see ?future::supportsMulticore
tic <- Sys.time()
komps <- c("komp_techniczne", "komp_matematyczne", "komp_kulturalne", "komp_komputerowe", 
                             "komp_kognitywne", "komp_kierownicze", "komp_interpersonalne", 
                             "komp_indywidualne", "komp_fizyczne", "komp_dyspozycyjne", "komp_biurowe")
res_alasso_kod2 <- foreach(i = 1:500, .export = c("wynik"), .verbose = TRUE) %dopar% {
  
  set.seed(i)
  
  totals_boot <- totals %>% filter(b == i)
  
  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_boot %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m ) %>%
      as.data.frame()
    X <- Matrix::fac2sparse(final_data_kod2$kod2) %>% t() 
    wynik_est <- list()
    wynik_wt <- list()
    wynik_model <- list()
    for (k in 1:length(komps)) {
      
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T, alpha = 0)
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T, penalty.factor = 1/abs(m1$coef[-1]))
        X_tot <- Matrix::fac2sparse(totals_boot$kod2) %>% t() 
        lin_pred  <- as.numeric(cbind(1, X_tot) %*% m1$coef)
        t1 <- totals_boot
        t2 <- totals_boot
        t1$pred <- exp(lin_pred) / (1 + exp(lin_pred))
        t2$pred <- 0
        t1$flag <- "1"
        t2$flag <- "0"
  
        totals_cal <- as.data.frame(rbind(t1,t2))
        totals_cal$wt  <- ifelse(totals_cal$flag  == 1, totals_cal$pred*totals_cal$hat_wolne, totals_cal$hat_wolne)
        tab_totals <- xtabs(wt~ rok + flag, data = totals_cal)
        tab_totals[,1] <- tab_totals[,1] - tab_totals[,2]
        final_data_kod2$flag <- as.character(final_data_kod2[,komps[k]])
        lasso_kod2 <- svydesign(ids = ~1, weight = ~ weight, data = final_data_kod2)
        cal_lasso_kod2 <- calibrate(design = lasso_kod2, 
                                    formula = list(~rok + flag), 
                                    population = list(tab_totals))
  
      svyby(formula = as.formula(paste("~", komps[k])), 
            by = ~ rok, 
            FUN = svymean, 
            design = cal_lasso_kod2) %>%
        select(-se) -> wyn
      wynik_est[[k]] <- wyn
      wynik_wt[[k]] <- weights(cal_lasso_kod2)
      wynik_model[[k]] <- m1
}
wynik <- list(wynik_est = bind_cols(wynik_est), 
              wynik_wt = bind_cols(wynik_wt),
              wynik_model = wynik_model)
}
numValues: 500, numResults: 0, stopped: TRUE
Error: Failed to retrieve the value of MultisessionFuture (<none>) from cluster SOCKnode #8 (PID 17737 on localhost ‘localhost’). The reason reported was ‘vector memory exhausted (limit reached?)’. Post-mortem diagnostic: A process with this PID exists, which suggests that the localhost worker is still alive.
saveRDS(res_alasso_kod2, file = "../results/res_alasso_kod2.rds")

Kalibracja wg kod2 + nace

tic <- Sys.time()
res_alasso_kod2_nace <- foreach(i = 1:500, .export = c("wynik")) %dopar% {
  
  set.seed(i)
  
  totals_boot <- totals %>% filter(b == i)
  
  final_data_kod2 <- final_data %>%  group_by(rok) %>%  
      sample_frac(1, replace = T) %>% ungroup() %>%
      add_count(rok, name = "m") %>%
      left_join( totals_boot %>% count(rok, wt = hat_wolne, name = "total")) %>%
      mutate(weight = total / m ) %>%
      as.data.frame()

    
    Xkod <- Matrix::fac2sparse(final_data_kod2$kod2) %>% t() 
    Xsek <- Matrix::fac2sparse(final_data_kod2$sekcja) %>% t() 
    X <- cbind(Xkod, Xsek) 

    wynik_est <- list()
    wynik_wt <- list()
    wynik_model <- list()
    for (k in 1:length(komps)) {
      
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T, alpha = 0)
        m1 <- mycv.glmnet(x = X, y = as.matrix(final_data_kod2[,komps[k]]), intercept = T, penalty.factor = 1/abs(m1$coef[-1]))
        Xkod_tot <- Matrix::fac2sparse(totals_boot$kod2) %>% t() 
        Xsek_tot <- Matrix::fac2sparse(totals_boot$sekcja) %>% t() 
        X_tot <- cbind(Xkod_tot, Xsek_tot)
        lin_pred  <- as.numeric(cbind(1, X_tot) %*% m1$coef)
        t1 <- totals_boot
        t2 <- totals_boot
        t1$pred <- exp(lin_pred) / (1 + exp(lin_pred))
        t2$pred <- 0
        t1$flag <- "1"
        t2$flag <- "0"
  
        totals_cal <- as.data.frame(rbind(t1,t2))
        totals_cal$wt  <- ifelse(totals_cal$flag  == 1, totals_cal$pred*totals_cal$hat_wolne, totals_cal$hat_wolne)
        tab_totals <- xtabs(wt~ rok + flag, data = totals_cal)
        tab_totals[,1] <- tab_totals[,1] - tab_totals[,2]
        final_data_kod2$flag <- as.character(final_data_kod2[,komps[k]])
        lasso_kod2 <- svydesign(ids = ~1, weight = ~ weight, data = final_data_kod2)
        cal_lasso_kod2 <- calibrate(design = lasso_kod2, 
                                    formula = list(~rok + flag), 
                                    population = list(tab_totals))
  
      svyby(formula = as.formula(paste("~", komps[k])), 
            by = ~ rok, 
            FUN = svymean, 
            design = cal_lasso_kod2) %>%
        select(-se) -> wyn

      wynik_est[[k]] <- wyn
      wynik_wt[[k]] <- weights(cal_lasso_kod2)
      wynik_model[[k]] <- m1
}


wynik <- list(wynik_est = bind_cols(wynik_est), 
              wynik_wt = bind_cols(wynik_wt),
              wynik_model = wynik_model)
}
toc <- Sys.time() - tic
toc
saveRDS(res_alasso_kod2_nace, file = "../results/res_alasso_kod2_nace.rds")
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBQYWNrYWdlcwoKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcygiZmFzdGdsbSIpCmxpYnJhcnkoc3VydmV5KQpsaWJyYXJ5KGdsbW5ldCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoeHRhYmxlKQpsaWJyYXJ5KGZ1dHVyZSkKbGlicmFyeSh2Y2QpCmxpYnJhcnkoZG9GdXR1cmUpCmxpYnJhcnkoZmFzdGdsbSkKCnNvdXJjZSgiLi4vY29kZXMvYWRhbGFzc28tY2hlbi1waGQuUiIpCmBgYAoKIyBEYXRhCgpgYGB7cn0KdG90YWxzIDwtIHJlYWRSRFMoIi4uL2RhdGEvZ3VzLXdvai1zZWstYm9vdC10b3RhbHMucmRzIikgJT4lCiAgZmlsdGVyKHN1YnN0cihrb2QyLDEsMSkgIT0gNikgJT4lCiAgbXV0YXRlKGtvZDIgPSBpZmVsc2Uoa29kMiA9PSA5NSwgOTYsIGtvZDIpLAogICAgICAgICBrb2QyID0gaWZlbHNlKGtvZDIgPT0gOTIsIDkxLCBrb2QyKSwKICAgICAgICAga29kMiA9IGlmZWxzZShrb2QyID09IDUzLCA1NCwga29kMiksCiAgICAgICAgICNrb2QxID0gYXMuY2hhcmFjdGVyKGtvZDEpLAogICAgICAgICBrb2QyID0gYXMuY2hhcmFjdGVyKGtvZDIpLAogICAgICAgICByb2sgPSBhcy5jaGFyYWN0ZXIocm9rKSkgCgpoZWFkKHRvdGFscykKCmZpbmFsX2RhdGEgPC0gcmVhZFJEUygiLi4vZGF0YS9ia2wtZmluYWwucmRzIikgJT4lCiAgZmlsdGVyKHphd29kMSAhPSA2LCByb2shPTIwMTIsIG5hY2UgJWluJSB1bmlxdWUodG90YWxzJHNla2NqYSkpICU+JQogIG11dGF0ZSh6YXdvZDIgPSBpZmVsc2UoemF3b2QyID09IDk1LCA5NiwgemF3b2QyKSwKICAgICAgICAgemF3b2QyID0gaWZlbHNlKHphd29kMiA9PSA5MiwgOTEsIHphd29kMiksCiAgICAgICAgIHphd29kMiA9IGlmZWxzZSh6YXdvZDIgPT0gOTksIDk2LCB6YXdvZDIpLAogICAgICAgICB6YXdvZDIgPSBpZmVsc2UoemF3b2QyID09IDUzLCA1NCwgemF3b2QyKSwKICAgICAgICAgemVyb3MgPSBzdHJfZXh0cmFjdCh6YXdvZDYsICIwKyQiKSwKICAgICAgICAgemVyb3MgPSBzdHJfY291bnQoemVyb3MsICIwIiksCiAgICAgICAgIHplcm9zID0gaWZlbHNlKGlzLm5hKHplcm9zKSwgNiwgNi16ZXJvcyksCiAgICAgICAgIHJvayA9IGFzLmNoYXJhY3Rlcihyb2spKSAlPiUKICByZW5hbWUoa29kMSA9IHphd29kMSwKICAgICAgICAga29kMiA9IHphd29kMiwKICAgICAgICAga29kNiA9IHphd29kNiwKICAgICAgICAgc2VrY2phID0gbmFjZSkgJT4lCiAgZmlsdGVyKHplcm9zID4gMSkgCmBgYAoKCiMgQ29ycmVsYXRpb25zCgoKYGBge3J9CmZpbmFsX2RhdGEgJT4lCiAgc2VsZWN0KGtvZDIsIHdvaiwgc2VrY2phLCBrb21wX3RlY2huaWN6bmU6a29tcF9iaXVyb3dlKSAlPiUKICBnYXRoZXIoY29tcHMsIHZhbHMsIGtvbXBfdGVjaG5pY3puZTprb21wX2JpdXJvd2UpIC0+IGZvcl9jb3JyCgpmb3JfY29yciAgJT4lCiAgY291bnQoa29kMiwgY29tcD1jb21wcywgdmFscykgJT4lCiAgZ3JvdXBfYnkoY29tcCkgJT4lCiAgZG8ob2NjdXBhbmN5ID0geHRhYnMobn52YWxzICsga29kMiwgZGF0YSA9IC4pICU+JSBhc3NvY3N0YXRzKC4pICU+JSAuJGNyYW1lcikgJT4lCiAgdW5uZXN0KCkgJT4lCiAgbGVmdF9qb2luKAogICAgZm9yX2NvcnIgICU+JQogIGNvdW50KHNla2NqYSwgY29tcD1jb21wcywgdmFscykgJT4lCiAgZ3JvdXBfYnkoY29tcCkgJT4lCiAgZG8oTkFDRSA9IHh0YWJzKG5+dmFscyArIHNla2NqYSwgZGF0YSA9IC4pICU+JSBhc3NvY3N0YXRzKC4pICU+JSAuJGNyYW1lcikgJT4lCiAgdW5uZXN0KCkpICU+JQogIGxlZnRfam9pbihmb3JfY29yciAgJT4lCiAgY291bnQod29qLCBjb21wPWNvbXBzLCB2YWxzKSAlPiUKICBncm91cF9ieShjb21wKSAlPiUKICBkbyhWb2l2b2Rlc2hpcCA9IHh0YWJzKG5+dmFscyArIHdvaiwgZGF0YSA9IC4pICU+JSBhc3NvY3N0YXRzKC4pICU+JSAuJGNyYW1lcikgJT4lCiAgdW5uZXN0KCkpICU+JQogIG11dGF0ZShjb21wID0gY2FzZV93aGVuKGNvbXAgPT0gImtvbXBfa3VsdHVyYWxuZSIgfiAiQXJ0aXN0aWMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9PSAia29tcF9keXNwb3p5Y3lqbmUifiAiQXZhaWxhYmlsaXR5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfa29nbml0eXduZSIgfiAiQ29nbml0aXZlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfa29tcHV0ZXJvd2UiIH4gIkNvbXB1dGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfaW50ZXJwZXJzb25hbG5lIiB+ICJJbnRlcnBlcnNvbmFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfa2llcm93bmljemUiIH4gIk1hbmFnZXJpYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcCA9PSAia29tcF9tYXRlbWF0eWN6bmUiIH4gIk1hdGhlbWF0aWNhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wID09ICJrb21wX2JpdXJvd2UifiAiT2ZmaWNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfZml6eWN6bmUiIH4gIlBoeXNpY2FsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0gImtvbXBfaW5keXdpZHVhbG5lIn4gIlNlbGYtb3JnYW5pemF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXAgPT0ia29tcF90ZWNobmljem5lIiAgfiAiVGVjaG5pY2FsIikpICU+JQogIGFycmFuZ2UoY29tcCkgJT4lCiAgeHRhYmxlKGRpZ2l0cyA9IDIpICU+JQogIHByaW50Lnh0YWJsZShpbmNsdWRlLnJvd25hbWVzID0gRikKYGBgCgpgYGB7cn0KdmNkOjphc3NvY3N0YXRzKHh0YWJzKH5rb21wX2luZHl3aWR1YWxuZSArIGtvZDEgKyByb2ssIGRhdGEgPSBmaW5hbF9kYXRhKSkgJT4lIG1hcCgiY3JhbWVyIikKdmNkOjphc3NvY3N0YXRzKHh0YWJzKH5rb21wX2luZHl3aWR1YWxuZSArIGtvZDIgKyByb2ssIGRhdGEgPSBmaW5hbF9kYXRhKSkgJT4lIG1hcCgiY3JhbWVyIikKYGBgCgojIENhbGlicmF0aW9uCgotIHphd29kMSAKLSB6YXdvZDEgKyB3b2oKLSB6YXdvZDEgKyBzZWtjamEKLSB6YXdvZDEgKyB3b2ogKyBzZWtjamEKCmBgYHtyfQpkZXMgPC0gc3Z5ZGVzaWduKGlkcyA9IH4xLCBkYXRhID0gZmluYWxfZGF0YSkKYGBgCgojIyMgQ2FsaWJyYXRpb24gYmFzZWQgb24ga29kMgoKYGBge3J9CnJlZ2lzdGVyRG9GdXR1cmUoKQpwbGFuKG11bHRpcHJvY2VzcykKCnRpYyA8LSBTeXMudGltZSgpCnJlc19jYWxpYiA8LSBmb3JlYWNoKGkgPSAxOjUwMCwgLmV4cG9ydCA9IGMoInd5bmlrIikpICVkb3BhciUgewogIHNldC5zZWVkKGkpCiAgCiAgdG90YWxzX2tvZDIgPC0gc3Vic2V0KHRvdGFscywgc3Vic2V0ID0gYiA9PSBpKQoKICBmaW5hbF9kYXRhX2tvZDIgPC0gZmluYWxfZGF0YSAlPiUgIGdyb3VwX2J5KHJvaykgJT4lICAKICAgICAgc2FtcGxlX2ZyYWMoMSwgcmVwbGFjZSA9IFQpICU+JSB1bmdyb3VwKCkgJT4lCiAgICAgIGFkZF9jb3VudChyb2ssIG5hbWUgPSAibSIpICU+JQogICAgICBsZWZ0X2pvaW4oIHRvdGFsc19rb2QyICU+JSBjb3VudChyb2ssIHd0ID0gaGF0X3dvbG5lLCBuYW1lID0gInRvdGFsIikpICU+JQogICAgICBtdXRhdGUod2VpZ2h0ID0gdG90YWwgLyBtICkKICAKICBkZXNfa29kMiA8LSBzdnlkZXNpZ24oaWRzID0gfjEsIHdlaWdodCA9IH53ZWlnaHQsIGRhdGEgPSBmaW5hbF9kYXRhX2tvZDIpCiAgCiAgdG90X2tvZDIgPC0geHRhYnMoaGF0X3dvbG5lfnJvayArIGtvZDIsIGRhdGEgPSB0b3RhbHNfa29kMikKICB0b3Rfc2VrIDwtIHh0YWJzKGhhdF93b2xuZX5yb2sgKyBzZWtjamEsIGRhdGEgPSB0b3RhbHNfa29kMikKICBjYWxfa29kMiA8LSBjYWxpYnJhdGUoZGVzaWduID0gZGVzX2tvZDIsIGZvcm11bGEgPSBsaXN0KH5yb2sgKyBrb2QyKSwgCiAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uID0gbGlzdCh0b3Rfa29kMikpCiAgY2FsX2tvZDJfc2VrIDwtIHJha2UoZGVzaWduID0gZGVzX2tvZDIsIAogICAgICAgICAgICAgICAgICAgICBzYW1wbGUubWFyZ2lucyA9IGxpc3QofnJvayArIGtvZDIsIH5yb2sgKyBzZWtjamEpLCAKICAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGlvbi5tYXJnaW5zID0gbGlzdCh0b3Rfa29kMiwgdG90X3NlayksIGNvbnRyb2wgPSBsaXN0KG1heGl0ID0gNTApKQogIAogIHN2eWJ5KGZvcm11bGEgPSB+a29tcF90ZWNobmljem5lICsga29tcF9tYXRlbWF0eWN6bmUgKyBrb21wX2t1bHR1cmFsbmUgKyBrb21wX2tvbXB1dGVyb3dlICsgCiAgICAgICAga29tcF9rb2duaXR5d25lICsga29tcF9raWVyb3duaWN6ZSArIGtvbXBfaW50ZXJwZXJzb25hbG5lICsgCiAgICAgICAga29tcF9pbmR5d2lkdWFsbmUgKyBrb21wX2Zpenljem5lICsga29tcF9keXNwb3p5Y3lqbmUgKyBrb21wX2JpdXJvd2UsIAogICAgICBieSA9IH4gcm9rLCAKICAgICAgRlVOID0gc3Z5bWVhbiwgCiAgICAgIGRlc2lnbiA9IGNhbF9rb2QyKSAlPiUKICBzZWxlY3Qocm9rLCBrb21wX3RlY2huaWN6bmU6a29tcF9iaXVyb3dlKSAtPiB3eW4xIAogIAogIHN2eWJ5KGZvcm11bGEgPSB+a29tcF90ZWNobmljem5lICsga29tcF9tYXRlbWF0eWN6bmUgKyBrb21wX2t1bHR1cmFsbmUgKyBrb21wX2tvbXB1dGVyb3dlICsgCiAgICAgICAga29tcF9rb2duaXR5d25lICsga29tcF9raWVyb3duaWN6ZSArIGtvbXBfaW50ZXJwZXJzb25hbG5lICsgCiAgICAgICAga29tcF9pbmR5d2lkdWFsbmUgKyBrb21wX2Zpenljem5lICsga29tcF9keXNwb3p5Y3lqbmUgKyBrb21wX2JpdXJvd2UsIAogICAgICBieSA9IH4gcm9rLCAKICAgICAgRlVOID0gc3Z5bWVhbiwgCiAgICAgIGRlc2lnbiA9IGNhbF9rb2QyX3NlaykgJT4lCiAgc2VsZWN0KHJvaywga29tcF90ZWNobmljem5lOmtvbXBfYml1cm93ZSkgLT4gd3luMgogIAogIHd5bmlrIDwtIGxpc3QoY2FsaWJfa29kMj13eW4xLCAKICAgICAgICAgICAgICAgIGNhbGliX2tvZDJfdyA9IHdlaWdodHMoY2FsX2tvZDIpLAogICAgICAgICAgICAgICAgY2FsaWJfa29kMl9zZWs9d3luMiwKICAgICAgICAgICAgICAgIGNhbGliX2tvZDJfc2VrX3cgPSB3ZWlnaHRzKGNhbF9rb2QyX3NlaykpCiAgCn0KClN5cy50aW1lKCkgLSB0aWMKYGBgCgpgYGB7cn0Kc2F2ZVJEUyhyZXNfY2FsaWIsIGZpbGUgPSAiLi4vcmVzdWx0cy9yZXNfY2FsaWIucmRzIikKYGBgCgoKIyMjIE1vZGVsLWNhbGlicmF0aW9uIC0gR0xNCgpgYGB7cn0Ka29tcHMgPC0gYygia29tcF90ZWNobmljem5lIiwgImtvbXBfbWF0ZW1hdHljem5lIiwgImtvbXBfa3VsdHVyYWxuZSIsICJrb21wX2tvbXB1dGVyb3dlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImtvbXBfa29nbml0eXduZSIsICJrb21wX2tpZXJvd25pY3plIiwgImtvbXBfaW50ZXJwZXJzb25hbG5lIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImtvbXBfaW5keXdpZHVhbG5lIiwgImtvbXBfZml6eWN6bmUiLCAia29tcF9keXNwb3p5Y3lqbmUiLCAia29tcF9iaXVyb3dlIikKCnRpYyA8LSBTeXMudGltZSgpCnJlc19nbG1fa29kMiA8LSBmb3JlYWNoKGkgPSAxOjUwMCwgLmV4cG9ydCA9IGMoInd5bmlrIikpICVkb3BhciUgewoKICBzZXQuc2VlZChpKQogIAogIHRvdGFsc19ib290IDwtIHRvdGFscyAlPiUgZmlsdGVyKGIgPT0gaSkKICAKICBmaW5hbF9kYXRhX2tvZDIgPC0gZmluYWxfZGF0YSAlPiUgIGdyb3VwX2J5KHJvaykgJT4lICAKICAgICAgc2FtcGxlX2ZyYWMoMSwgcmVwbGFjZSA9IFQpICU+JSB1bmdyb3VwKCkgJT4lCiAgICAgIGFkZF9jb3VudChyb2ssIG5hbWUgPSAibSIpICU+JQogICAgICBsZWZ0X2pvaW4oIHRvdGFsc19ib290ICU+JSBjb3VudChyb2ssIHd0ID0gaGF0X3dvbG5lLCBuYW1lID0gInRvdGFsIikpICU+JQogICAgICBtdXRhdGUod2VpZ2h0ID0gdG90YWwgLyBtICkgJT4lCiAgICAgIGFzLmRhdGEuZnJhbWUoKQoKICAgIFggPC0gTWF0cml4OjpmYWMyc3BhcnNlKGZpbmFsX2RhdGFfa29kMiRrb2QyKSAlPiUgdCgpIAoKICAgIHd5bmlrX2VzdCA8LSBsaXN0KCkKICAgIHd5bmlrX3d0IDwtIGxpc3QoKQogICAgd3luaWtfbW9kZWwgPC0gbGlzdCgpCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoa29tcHMpKSB7CiAgICAgIAogICAgICAgIG0xIDwtIGZhc3RnbG0oeCA9IGFzLm1hdHJpeChjYmluZCgxLFhbLC0xXSkpLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgCiAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbCgpLCBtZXRob2QgPSAyKQogIAogICAgICAgIFhfdG90IDwtIE1hdHJpeDo6ZmFjMnNwYXJzZSh0b3RhbHNfYm9vdCRrb2QyKSAlPiUgdCgpIAogICAgICAgIGxpbl9wcmVkICA8LSBhcy5udW1lcmljKGNiaW5kKDEsIFhfdG90WywtMV0pICUqJSBtMSRjb2VmZmljaWVudHMpCiAgICAgICAgdDEgPC0gdG90YWxzX2Jvb3QKICAgICAgICB0MiA8LSB0b3RhbHNfYm9vdAogICAgICAgIHQxJHByZWQgPC0gZXhwKGxpbl9wcmVkKSAvICgxICsgZXhwKGxpbl9wcmVkKSkKICAgICAgICB0MiRwcmVkIDwtIDAKICAgICAgICB0MSRmbGFnIDwtICIxIgogICAgICAgIHQyJGZsYWcgPC0gIjAiCiAgCiAgICAgICAgdG90YWxzX2NhbCA8LSBhcy5kYXRhLmZyYW1lKHJiaW5kKHQxLHQyKSkKICAgICAgICB0b3RhbHNfY2FsJHd0ICA8LSBpZmVsc2UodG90YWxzX2NhbCRmbGFnICA9PSAxLCB0b3RhbHNfY2FsJHByZWQqdG90YWxzX2NhbCRoYXRfd29sbmUsIHRvdGFsc19jYWwkaGF0X3dvbG5lKQogICAgICAgIHRhYl90b3RhbHMgPC0geHRhYnMod3R+IHJvayArIGZsYWcsIGRhdGEgPSB0b3RhbHNfY2FsKQogICAgICAgIHRhYl90b3RhbHNbLDFdIDwtIHRhYl90b3RhbHNbLDFdIC0gdGFiX3RvdGFsc1ssMl0KICAgICAgICBmaW5hbF9kYXRhX2tvZDIkZmxhZyA8LSBhcy5jaGFyYWN0ZXIoZmluYWxfZGF0YV9rb2QyWyxrb21wc1trXV0pCiAgICAgICAgZ2xtX2tvZDIgPC0gc3Z5ZGVzaWduKGlkcyA9IH4xLCB3ZWlnaHQgPSB+IHdlaWdodCwgZGF0YSA9IGZpbmFsX2RhdGFfa29kMikKICAgICAgICBjYWxfZ2xtX2tvZDIgPC0gY2FsaWJyYXRlKGRlc2lnbiA9IGdsbV9rb2QyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYSA9IGxpc3QofnJvayArIGZsYWcpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGlvbiA9IGxpc3QodGFiX3RvdGFscykpCiAgCiAgICAgIHN2eWJ5KGZvcm11bGEgPSBhcy5mb3JtdWxhKHBhc3RlKCJ+Iiwga29tcHNba10pKSwgCiAgICAgICAgICAgIGJ5ID0gfiByb2ssIAogICAgICAgICAgICBGVU4gPSBzdnltZWFuLCAKICAgICAgICAgICAgZGVzaWduID0gY2FsX2dsbV9rb2QyKSAlPiUKICAgICAgICBkcGx5cjo6c2VsZWN0KC1zZSkgLT4gd3luCgogICAgICB3eW5pa19lc3RbW2tdXSA8LSB3eW4KICAgICAgd3luaWtfd3RbW2tdXSA8LSB3ZWlnaHRzKGNhbF9nbG1fa29kMikKICAgICAgd3luaWtfbW9kZWxbW2tdXSA8LSBtMQp9CgoKd3luaWsgPC0gbGlzdCh3eW5pa19lc3QgPSBiaW5kX2NvbHMod3luaWtfZXN0KSAlPiUgc2VsZWN0KHJvaywgc3RhcnRzX3dpdGgoImtvbXAiKSksIAogICAgICAgICAgICAgIHd5bmlrX3d0ID0gYmluZF9jb2xzKHd5bmlrX3d0KSwKICAgICAgICAgICAgICB3eW5pa19tb2RlbCA9IHd5bmlrX21vZGVsKQoKCn0KCnRvYyA8LSBTeXMudGltZSgpIC0gdGljCnRvYwpgYGAKCmBgYHtyfQpzYXZlUkRTKHJlc19nbG1fa29kMiwgZmlsZSA9ICIuLi9yZXN1bHRzL3Jlc19nbG1fa29kMi5yZHMiKQpgYGAKCgojIyMgTGFzc28KCgpLYWxpYnJhY2phIHdnIGtvZDIgKyBuYWNlCgpgYGB7cn0KcmVnaXN0ZXJEb0Z1dHVyZSgpCnBsYW4obXVsdGlwcm9jZXNzKQp0aWMgPC0gU3lzLnRpbWUoKQprb21wcyA8LSBjKCJrb21wX3RlY2huaWN6bmUiLCAia29tcF9tYXRlbWF0eWN6bmUiLCAia29tcF9rdWx0dXJhbG5lIiwgImtvbXBfa29tcHV0ZXJvd2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAia29tcF9rb2duaXR5d25lIiwgImtvbXBfa2llcm93bmljemUiLCAia29tcF9pbnRlcnBlcnNvbmFsbmUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAia29tcF9pbmR5d2lkdWFsbmUiLCAia29tcF9maXp5Y3puZSIsICJrb21wX2R5c3BvenljeWpuZSIsICJrb21wX2JpdXJvd2UiKQoKcmVzX2xhc3NvX2tvZDIgPC0gZm9yZWFjaChpID0gMTo1MDAsIC5leHBvcnQgPSBjKCJ3eW5payIpKSAlZG9wYXIlIHsKICAKICBzZXQuc2VlZChpKQogIAogIHRvdGFsc19ib290IDwtIHRvdGFscyAlPiUgZmlsdGVyKGIgPT0gaSkKICAKICBmaW5hbF9kYXRhX2tvZDIgPC0gZmluYWxfZGF0YSAlPiUgIGdyb3VwX2J5KHJvaykgJT4lICAKICAgICAgc2FtcGxlX2ZyYWMoMSwgcmVwbGFjZSA9IFQpICU+JSB1bmdyb3VwKCkgJT4lCiAgICAgIGFkZF9jb3VudChyb2ssIG5hbWUgPSAibSIpICU+JQogICAgICBsZWZ0X2pvaW4oIHRvdGFsc19ib290ICU+JSBjb3VudChyb2ssIHd0ID0gaGF0X3dvbG5lLCBuYW1lID0gInRvdGFsIikpICU+JQogICAgICBtdXRhdGUod2VpZ2h0ID0gdG90YWwgLyBtICkgJT4lCiAgICAgIGFzLmRhdGEuZnJhbWUoKQoKICAgIFggPC0gTWF0cml4OjpmYWMyc3BhcnNlKGZpbmFsX2RhdGFfa29kMiRrb2QyKSAlPiUgdCgpIAoKICAgIHd5bmlrX2VzdCA8LSBsaXN0KCkKICAgIHd5bmlrX3d0IDwtIGxpc3QoKQogICAgd3luaWtfbW9kZWwgPC0gbGlzdCgpCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoa29tcHMpKSB7CiAgICAgIAogICAgICAgIG0xIDwtIG15Y3YuZ2xtbmV0KHggPSBYLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgaW50ZXJjZXB0ID0gVCkKICAgICAgICBYX3RvdCA8LSBNYXRyaXg6OmZhYzJzcGFyc2UodG90YWxzX2Jvb3Qka29kMikgJT4lIHQoKSAKICAgICAgICBsaW5fcHJlZCAgPC0gYXMubnVtZXJpYyhjYmluZCgxLCBYX3RvdCkgJSolIG0xJGNvZWYpCiAgICAgICAgdDEgPC0gdG90YWxzX2Jvb3QKICAgICAgICB0MiA8LSB0b3RhbHNfYm9vdAogICAgICAgIHQxJHByZWQgPC0gZXhwKGxpbl9wcmVkKSAvICgxICsgZXhwKGxpbl9wcmVkKSkKICAgICAgICB0MiRwcmVkIDwtIDAKICAgICAgICB0MSRmbGFnIDwtICIxIgogICAgICAgIHQyJGZsYWcgPC0gIjAiCiAgCiAgICAgICAgdG90YWxzX2NhbCA8LSBhcy5kYXRhLmZyYW1lKHJiaW5kKHQxLHQyKSkKICAgICAgICB0b3RhbHNfY2FsJHd0ICA8LSBpZmVsc2UodG90YWxzX2NhbCRmbGFnICA9PSAxLCB0b3RhbHNfY2FsJHByZWQqdG90YWxzX2NhbCRoYXRfd29sbmUsIHRvdGFsc19jYWwkaGF0X3dvbG5lKQogICAgICAgIHRhYl90b3RhbHMgPC0geHRhYnMod3R+IHJvayArIGZsYWcsIGRhdGEgPSB0b3RhbHNfY2FsKQogICAgICAgIHRhYl90b3RhbHNbLDFdIDwtIHRhYl90b3RhbHNbLDFdIC0gdGFiX3RvdGFsc1ssMl0KICAgICAgICBmaW5hbF9kYXRhX2tvZDIkZmxhZyA8LSBhcy5jaGFyYWN0ZXIoZmluYWxfZGF0YV9rb2QyWyxrb21wc1trXV0pCiAgICAgICAgbGFzc29fa29kMiA8LSBzdnlkZXNpZ24oaWRzID0gfjEsIHdlaWdodCA9IH4gd2VpZ2h0LCBkYXRhID0gZmluYWxfZGF0YV9rb2QyKQogICAgICAgIGNhbF9sYXNzb19rb2QyIDwtIGNhbGlicmF0ZShkZXNpZ24gPSBsYXNzb19rb2QyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYSA9IGxpc3QofnJvayArIGZsYWcpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGlvbiA9IGxpc3QodGFiX3RvdGFscykpCiAgCiAgICAgIHN2eWJ5KGZvcm11bGEgPSBhcy5mb3JtdWxhKHBhc3RlKCJ+Iiwga29tcHNba10pKSwgCiAgICAgICAgICAgIGJ5ID0gfiByb2ssIAogICAgICAgICAgICBGVU4gPSBzdnltZWFuLCAKICAgICAgICAgICAgZGVzaWduID0gY2FsX2xhc3NvX2tvZDIpICU+JQogICAgICAgIHNlbGVjdCgtc2UpIC0+IHd5bgoKICAgICAgd3luaWtfZXN0W1trXV0gPC0gd3luCiAgICAgIHd5bmlrX3d0W1trXV0gPC0gd2VpZ2h0cyhjYWxfbGFzc29fa29kMikKICAgICAgd3luaWtfbW9kZWxbW2tdXSA8LSBtMQp9CgoKd3luaWsgPC0gbGlzdCh3eW5pa19lc3QgPSBiaW5kX2NvbHMod3luaWtfZXN0KSAlPiUgc2VsZWN0KHJvaywgc3RhcnRzX3dpdGgoImtvbXAiKSksIAogICAgICAgICAgICAgIHd5bmlrX3d0ID0gYmluZF9jb2xzKHd5bmlrX3d0KSwKICAgICAgICAgICAgICB3eW5pa19tb2RlbCA9IHd5bmlrX21vZGVsKQoKCn0KCnRvYyA8LSBTeXMudGltZSgpIC0gdGljCnRvYwpgYGAKCmBgYHtyfQpzYXZlUkRTKHJlc19sYXNzb19rb2QyLCBmaWxlID0gIi4uL3Jlc3VsdHMvcmVzX2xhc3NvX2tvZDIucmRzIikKYGBgCgoKS2FsaWJyYWNqYSB3ZyBrb2QyICsgbmFjZQoKCmBgYHtyfQp0aWMgPC0gU3lzLnRpbWUoKQpyZXNfbGFzc29fa29kMl9uYWNlIDwtIGZvcmVhY2goaSA9IDE6NTAwLCAuZXhwb3J0ID0gYygid3luaWsiKSkgJWRvcGFyJSB7CiAgCiAgc2V0LnNlZWQoaSkKICAKICB0b3RhbHNfYm9vdCA8LSB0b3RhbHMgJT4lIGZpbHRlcihiID09IGkpCiAgCiAgZmluYWxfZGF0YV9rb2QyIDwtIGZpbmFsX2RhdGEgJT4lICBncm91cF9ieShyb2spICU+JSAgCiAgICAgIHNhbXBsZV9mcmFjKDEsIHJlcGxhY2UgPSBUKSAlPiUgdW5ncm91cCgpICU+JQogICAgICBhZGRfY291bnQocm9rLCBuYW1lID0gIm0iKSAlPiUKICAgICAgbGVmdF9qb2luKCB0b3RhbHNfYm9vdCAlPiUgY291bnQocm9rLCB3dCA9IGhhdF93b2xuZSwgbmFtZSA9ICJ0b3RhbCIpKSAlPiUKICAgICAgbXV0YXRlKHdlaWdodCA9IHRvdGFsIC8gbSApICU+JQogICAgICBhcy5kYXRhLmZyYW1lKCkKCiAgICAKICAgIFhrb2QgPC0gTWF0cml4OjpmYWMyc3BhcnNlKGZpbmFsX2RhdGFfa29kMiRrb2QyKSAlPiUgdCgpIAogICAgWHNlayA8LSBNYXRyaXg6OmZhYzJzcGFyc2UoZmluYWxfZGF0YV9rb2QyJHNla2NqYSkgJT4lIHQoKSAKICAgIFggPC0gY2JpbmQoWGtvZCwgWHNlaykgCgogICAgd3luaWtfZXN0IDwtIGxpc3QoKQogICAgd3luaWtfd3QgPC0gbGlzdCgpCiAgICB3eW5pa19tb2RlbCA8LSBsaXN0KCkKICAgIGZvciAoayBpbiAxOmxlbmd0aChrb21wcykpIHsKICAgICAgCiAgICAgICAgbTEgPC0gbXljdi5nbG1uZXQoeCA9IFgsIHkgPSBhcy5tYXRyaXgoZmluYWxfZGF0YV9rb2QyWyxrb21wc1trXV0pLCBpbnRlcmNlcHQgPSBUKQogICAgICAgIFhrb2RfdG90IDwtIE1hdHJpeDo6ZmFjMnNwYXJzZSh0b3RhbHNfYm9vdCRrb2QyKSAlPiUgdCgpIAogICAgICAgIFhzZWtfdG90IDwtIE1hdHJpeDo6ZmFjMnNwYXJzZSh0b3RhbHNfYm9vdCRzZWtjamEpICU+JSB0KCkgCiAgICAgICAgWF90b3QgPC0gY2JpbmQoWGtvZF90b3QsIFhzZWtfdG90KQogICAgICAgIGxpbl9wcmVkICA8LSBhcy5udW1lcmljKGNiaW5kKDEsIFhfdG90KSAlKiUgbTEkY29lZikKICAgICAgICB0MSA8LSB0b3RhbHNfYm9vdAogICAgICAgIHQyIDwtIHRvdGFsc19ib290CiAgICAgICAgdDEkcHJlZCA8LSBleHAobGluX3ByZWQpIC8gKDEgKyBleHAobGluX3ByZWQpKQogICAgICAgIHQyJHByZWQgPC0gMAogICAgICAgIHQxJGZsYWcgPC0gIjEiCiAgICAgICAgdDIkZmxhZyA8LSAiMCIKICAKICAgICAgICB0b3RhbHNfY2FsIDwtIGFzLmRhdGEuZnJhbWUocmJpbmQodDEsdDIpKQogICAgICAgIHRvdGFsc19jYWwkd3QgIDwtIGlmZWxzZSh0b3RhbHNfY2FsJGZsYWcgID09IDEsIHRvdGFsc19jYWwkcHJlZCp0b3RhbHNfY2FsJGhhdF93b2xuZSwgdG90YWxzX2NhbCRoYXRfd29sbmUpCiAgICAgICAgdGFiX3RvdGFscyA8LSB4dGFicyh3dH4gcm9rICsgZmxhZywgZGF0YSA9IHRvdGFsc19jYWwpCiAgICAgICAgdGFiX3RvdGFsc1ssMV0gPC0gdGFiX3RvdGFsc1ssMV0gLSB0YWJfdG90YWxzWywyXQogICAgICAgIGZpbmFsX2RhdGFfa29kMiRmbGFnIDwtIGFzLmNoYXJhY3RlcihmaW5hbF9kYXRhX2tvZDJbLGtvbXBzW2tdXSkKICAgICAgICBsYXNzb19rb2QyIDwtIHN2eWRlc2lnbihpZHMgPSB+MSwgd2VpZ2h0ID0gfiB3ZWlnaHQsIGRhdGEgPSBmaW5hbF9kYXRhX2tvZDIpCiAgICAgICAgY2FsX2xhc3NvX2tvZDIgPC0gY2FsaWJyYXRlKGRlc2lnbiA9IGxhc3NvX2tvZDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtdWxhID0gbGlzdCh+cm9rICsgZmxhZyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uID0gbGlzdCh0YWJfdG90YWxzKSkKICAKICAgICAgc3Z5YnkoZm9ybXVsYSA9IGFzLmZvcm11bGEocGFzdGUoIn4iLCBrb21wc1trXSkpLCAKICAgICAgICAgICAgYnkgPSB+IHJvaywgCiAgICAgICAgICAgIEZVTiA9IHN2eW1lYW4sIAogICAgICAgICAgICBkZXNpZ24gPSBjYWxfbGFzc29fa29kMikgJT4lCiAgICAgICAgc2VsZWN0KC1zZSkgLT4gd3luCgogICAgICB3eW5pa19lc3RbW2tdXSA8LSB3eW4KICAgICAgd3luaWtfd3RbW2tdXSA8LSB3ZWlnaHRzKGNhbF9sYXNzb19rb2QyKQogICAgICB3eW5pa19tb2RlbFtba11dIDwtIG0xCn0KCgp3eW5payA8LSBsaXN0KHd5bmlrX2VzdCA9IGJpbmRfY29scyh3eW5pa19lc3QpICU+JSBzZWxlY3Qocm9rLCBzdGFydHNfd2l0aCgia29tcCIpKSwgCiAgICAgICAgICAgICAgd3luaWtfd3QgPSBiaW5kX2NvbHMod3luaWtfd3QpLAogICAgICAgICAgICAgIHd5bmlrX21vZGVsID0gd3luaWtfbW9kZWwpCn0KdG9jIDwtIFN5cy50aW1lKCkgLSB0aWMKdG9jCmBgYAoKYGBge3J9CnNhdmVSRFMocmVzX2xhc3NvX2tvZDJfbmFjZSwgZmlsZSA9ICIuLi9yZXN1bHRzL3Jlc19sYXNzb19rb2QyX25hY2UucmRzIikKYGBgCgojIyMgQWRhcHRpdmUgbGFzc28KCgpgYGB7cn0KcmVnaXN0ZXJEb0Z1dHVyZSgpCnBsYW4obXVsdGlwcm9jZXNzKQpgYGAKCmBgYHtyfQoKdGljIDwtIFN5cy50aW1lKCkKa29tcHMgPC0gYygia29tcF90ZWNobmljem5lIiwgImtvbXBfbWF0ZW1hdHljem5lIiwgImtvbXBfa3VsdHVyYWxuZSIsICJrb21wX2tvbXB1dGVyb3dlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImtvbXBfa29nbml0eXduZSIsICJrb21wX2tpZXJvd25pY3plIiwgImtvbXBfaW50ZXJwZXJzb25hbG5lIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImtvbXBfaW5keXdpZHVhbG5lIiwgImtvbXBfZml6eWN6bmUiLCAia29tcF9keXNwb3p5Y3lqbmUiLCAia29tcF9iaXVyb3dlIikKCnJlc19hbGFzc29fa29kMiA8LSBmb3JlYWNoKGkgPSAxOjEwLCAuZXhwb3J0ID0gYygid3luaWsiKSwgLnZlcmJvc2UgPSBUUlVFKSAlZG9wYXIlIHsKICAKICBzZXQuc2VlZChpKQogIAogIHRvdGFsc19ib290IDwtIHRvdGFscyAlPiUgZmlsdGVyKGIgPT0gaSkKICAKICBmaW5hbF9kYXRhX2tvZDIgPC0gZmluYWxfZGF0YSAlPiUgIGdyb3VwX2J5KHJvaykgJT4lICAKICAgICAgc2FtcGxlX2ZyYWMoMSwgcmVwbGFjZSA9IFQpICU+JSB1bmdyb3VwKCkgJT4lCiAgICAgIGFkZF9jb3VudChyb2ssIG5hbWUgPSAibSIpICU+JQogICAgICBsZWZ0X2pvaW4oIHRvdGFsc19ib290ICU+JSBjb3VudChyb2ssIHd0ID0gaGF0X3dvbG5lLCBuYW1lID0gInRvdGFsIikpICU+JQogICAgICBtdXRhdGUod2VpZ2h0ID0gdG90YWwgLyBtICkgJT4lCiAgICAgIGFzLmRhdGEuZnJhbWUoKQoKICAgIFggPC0gTWF0cml4OjpmYWMyc3BhcnNlKGZpbmFsX2RhdGFfa29kMiRrb2QyKSAlPiUgdCgpIAoKICAgIHd5bmlrX2VzdCA8LSBsaXN0KCkKICAgIHd5bmlrX3d0IDwtIGxpc3QoKQogICAgd3luaWtfbW9kZWwgPC0gbGlzdCgpCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoa29tcHMpKSB7CiAgICAgIAogICAgICAgIG0xIDwtIG15Y3YuZ2xtbmV0KHggPSBYLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgaW50ZXJjZXB0ID0gVCwgYWxwaGEgPSAwKQogICAgICAgIG0xIDwtIG15Y3YuZ2xtbmV0KHggPSBYLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgaW50ZXJjZXB0ID0gVCwgcGVuYWx0eS5mYWN0b3IgPSAxL2FicyhtMSRjb2VmWy0xXSkpCiAgICAgICAgWF90b3QgPC0gTWF0cml4OjpmYWMyc3BhcnNlKHRvdGFsc19ib290JGtvZDIpICU+JSB0KCkgCiAgICAgICAgbGluX3ByZWQgIDwtIGFzLm51bWVyaWMoY2JpbmQoMSwgWF90b3QpICUqJSBtMSRjb2VmKQogICAgICAgIHQxIDwtIHRvdGFsc19ib290CiAgICAgICAgdDIgPC0gdG90YWxzX2Jvb3QKICAgICAgICB0MSRwcmVkIDwtIGV4cChsaW5fcHJlZCkgLyAoMSArIGV4cChsaW5fcHJlZCkpCiAgICAgICAgdDIkcHJlZCA8LSAwCiAgICAgICAgdDEkZmxhZyA8LSAiMSIKICAgICAgICB0MiRmbGFnIDwtICIwIgogIAogICAgICAgIHRvdGFsc19jYWwgPC0gYXMuZGF0YS5mcmFtZShyYmluZCh0MSx0MikpCiAgICAgICAgdG90YWxzX2NhbCR3dCAgPC0gaWZlbHNlKHRvdGFsc19jYWwkZmxhZyAgPT0gMSwgdG90YWxzX2NhbCRwcmVkKnRvdGFsc19jYWwkaGF0X3dvbG5lLCB0b3RhbHNfY2FsJGhhdF93b2xuZSkKICAgICAgICB0YWJfdG90YWxzIDwtIHh0YWJzKHd0fiByb2sgKyBmbGFnLCBkYXRhID0gdG90YWxzX2NhbCkKICAgICAgICB0YWJfdG90YWxzWywxXSA8LSB0YWJfdG90YWxzWywxXSAtIHRhYl90b3RhbHNbLDJdCiAgICAgICAgZmluYWxfZGF0YV9rb2QyJGZsYWcgPC0gYXMuY2hhcmFjdGVyKGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKQogICAgICAgIGxhc3NvX2tvZDIgPC0gc3Z5ZGVzaWduKGlkcyA9IH4xLCB3ZWlnaHQgPSB+IHdlaWdodCwgZGF0YSA9IGZpbmFsX2RhdGFfa29kMikKICAgICAgICBjYWxfbGFzc29fa29kMiA8LSBjYWxpYnJhdGUoZGVzaWduID0gbGFzc29fa29kMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEgPSBsaXN0KH5yb2sgKyBmbGFnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRpb24gPSBsaXN0KHRhYl90b3RhbHMpKQogIAogICAgICBzdnlieShmb3JtdWxhID0gYXMuZm9ybXVsYShwYXN0ZSgifiIsIGtvbXBzW2tdKSksIAogICAgICAgICAgICBieSA9IH4gcm9rLCAKICAgICAgICAgICAgRlVOID0gc3Z5bWVhbiwgCiAgICAgICAgICAgIGRlc2lnbiA9IGNhbF9sYXNzb19rb2QyKSAlPiUKICAgICAgICBzZWxlY3QoLXNlKSAtPiB3eW4KCiAgICAgIHd5bmlrX2VzdFtba11dIDwtIHd5bgogICAgICB3eW5pa193dFtba11dIDwtIHdlaWdodHMoY2FsX2xhc3NvX2tvZDIpCiAgICAgIHd5bmlrX21vZGVsW1trXV0gPC0gbTEKfQoKCnd5bmlrIDwtIGxpc3Qod3luaWtfZXN0ID0gYmluZF9jb2xzKHd5bmlrX2VzdCksIAogICAgICAgICAgICAgIHd5bmlrX3d0ID0gYmluZF9jb2xzKHd5bmlrX3d0KSwKICAgICAgICAgICAgICB3eW5pa19tb2RlbCA9IHd5bmlrX21vZGVsKQoKCn0KCnRvYyA8LSBTeXMudGltZSgpIC0gdGljCnRvYwpgYGAKCmBgYHtyfQpzYXZlUkRTKHJlc19hbGFzc29fa29kMiwgZmlsZSA9ICIuLi9yZXN1bHRzL3Jlc19hbGFzc29fa29kMi5yZHMiKQpgYGAKCgoKS2FsaWJyYWNqYSB3ZyBrb2QyICsgbmFjZQoKCmBgYHtyfQp0aWMgPC0gU3lzLnRpbWUoKQpyZXNfYWxhc3NvX2tvZDJfbmFjZSA8LSBmb3JlYWNoKGkgPSAxOjUwMCwgLmV4cG9ydCA9IGMoInd5bmlrIikpICVkb3BhciUgewogIAogIHNldC5zZWVkKGkpCiAgCiAgdG90YWxzX2Jvb3QgPC0gdG90YWxzICU+JSBmaWx0ZXIoYiA9PSBpKQogIAogIGZpbmFsX2RhdGFfa29kMiA8LSBmaW5hbF9kYXRhICU+JSAgZ3JvdXBfYnkocm9rKSAlPiUgIAogICAgICBzYW1wbGVfZnJhYygxLCByZXBsYWNlID0gVCkgJT4lIHVuZ3JvdXAoKSAlPiUKICAgICAgYWRkX2NvdW50KHJvaywgbmFtZSA9ICJtIikgJT4lCiAgICAgIGxlZnRfam9pbiggdG90YWxzX2Jvb3QgJT4lIGNvdW50KHJvaywgd3QgPSBoYXRfd29sbmUsIG5hbWUgPSAidG90YWwiKSkgJT4lCiAgICAgIG11dGF0ZSh3ZWlnaHQgPSB0b3RhbCAvIG0gKSAlPiUKICAgICAgYXMuZGF0YS5mcmFtZSgpCgogICAgCiAgICBYa29kIDwtIE1hdHJpeDo6ZmFjMnNwYXJzZShmaW5hbF9kYXRhX2tvZDIka29kMikgJT4lIHQoKSAKICAgIFhzZWsgPC0gTWF0cml4OjpmYWMyc3BhcnNlKGZpbmFsX2RhdGFfa29kMiRzZWtjamEpICU+JSB0KCkgCiAgICBYIDwtIGNiaW5kKFhrb2QsIFhzZWspIAoKICAgIHd5bmlrX2VzdCA8LSBsaXN0KCkKICAgIHd5bmlrX3d0IDwtIGxpc3QoKQogICAgd3luaWtfbW9kZWwgPC0gbGlzdCgpCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoa29tcHMpKSB7CiAgICAgIAogICAgICAgIG0xIDwtIG15Y3YuZ2xtbmV0KHggPSBYLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgaW50ZXJjZXB0ID0gVCwgYWxwaGEgPSAwKQogICAgICAgIG0xIDwtIG15Y3YuZ2xtbmV0KHggPSBYLCB5ID0gYXMubWF0cml4KGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKSwgaW50ZXJjZXB0ID0gVCwgcGVuYWx0eS5mYWN0b3IgPSAxL2FicyhtMSRjb2VmWy0xXSkpCiAgICAgICAgWGtvZF90b3QgPC0gTWF0cml4OjpmYWMyc3BhcnNlKHRvdGFsc19ib290JGtvZDIpICU+JSB0KCkgCiAgICAgICAgWHNla190b3QgPC0gTWF0cml4OjpmYWMyc3BhcnNlKHRvdGFsc19ib290JHNla2NqYSkgJT4lIHQoKSAKICAgICAgICBYX3RvdCA8LSBjYmluZChYa29kX3RvdCwgWHNla190b3QpCiAgICAgICAgbGluX3ByZWQgIDwtIGFzLm51bWVyaWMoY2JpbmQoMSwgWF90b3QpICUqJSBtMSRjb2VmKQogICAgICAgIHQxIDwtIHRvdGFsc19ib290CiAgICAgICAgdDIgPC0gdG90YWxzX2Jvb3QKICAgICAgICB0MSRwcmVkIDwtIGV4cChsaW5fcHJlZCkgLyAoMSArIGV4cChsaW5fcHJlZCkpCiAgICAgICAgdDIkcHJlZCA8LSAwCiAgICAgICAgdDEkZmxhZyA8LSAiMSIKICAgICAgICB0MiRmbGFnIDwtICIwIgogIAogICAgICAgIHRvdGFsc19jYWwgPC0gYXMuZGF0YS5mcmFtZShyYmluZCh0MSx0MikpCiAgICAgICAgdG90YWxzX2NhbCR3dCAgPC0gaWZlbHNlKHRvdGFsc19jYWwkZmxhZyAgPT0gMSwgdG90YWxzX2NhbCRwcmVkKnRvdGFsc19jYWwkaGF0X3dvbG5lLCB0b3RhbHNfY2FsJGhhdF93b2xuZSkKICAgICAgICB0YWJfdG90YWxzIDwtIHh0YWJzKHd0fiByb2sgKyBmbGFnLCBkYXRhID0gdG90YWxzX2NhbCkKICAgICAgICB0YWJfdG90YWxzWywxXSA8LSB0YWJfdG90YWxzWywxXSAtIHRhYl90b3RhbHNbLDJdCiAgICAgICAgZmluYWxfZGF0YV9rb2QyJGZsYWcgPC0gYXMuY2hhcmFjdGVyKGZpbmFsX2RhdGFfa29kMlssa29tcHNba11dKQogICAgICAgIGxhc3NvX2tvZDIgPC0gc3Z5ZGVzaWduKGlkcyA9IH4xLCB3ZWlnaHQgPSB+IHdlaWdodCwgZGF0YSA9IGZpbmFsX2RhdGFfa29kMikKICAgICAgICBjYWxfbGFzc29fa29kMiA8LSBjYWxpYnJhdGUoZGVzaWduID0gbGFzc29fa29kMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEgPSBsaXN0KH5yb2sgKyBmbGFnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRpb24gPSBsaXN0KHRhYl90b3RhbHMpKQogIAogICAgICBzdnlieShmb3JtdWxhID0gYXMuZm9ybXVsYShwYXN0ZSgifiIsIGtvbXBzW2tdKSksIAogICAgICAgICAgICBieSA9IH4gcm9rLCAKICAgICAgICAgICAgRlVOID0gc3Z5bWVhbiwgCiAgICAgICAgICAgIGRlc2lnbiA9IGNhbF9sYXNzb19rb2QyKSAlPiUKICAgICAgICBzZWxlY3QoLXNlKSAtPiB3eW4KCiAgICAgIHd5bmlrX2VzdFtba11dIDwtIHd5bgogICAgICB3eW5pa193dFtba11dIDwtIHdlaWdodHMoY2FsX2xhc3NvX2tvZDIpCiAgICAgIHd5bmlrX21vZGVsW1trXV0gPC0gbTEKfQoKCnd5bmlrIDwtIGxpc3Qod3luaWtfZXN0ID0gYmluZF9jb2xzKHd5bmlrX2VzdCksIAogICAgICAgICAgICAgIHd5bmlrX3d0ID0gYmluZF9jb2xzKHd5bmlrX3d0KSwKICAgICAgICAgICAgICB3eW5pa19tb2RlbCA9IHd5bmlrX21vZGVsKQp9CnRvYyA8LSBTeXMudGltZSgpIC0gdGljCnRvYwpgYGAKCmBgYHtyfQpzYXZlUkRTKHJlc19hbGFzc29fa29kMl9uYWNlLCBmaWxlID0gIi4uL3Jlc3VsdHMvcmVzX2FsYXNzb19rb2QyX25hY2UucmRzIikKYGBgCg==