Clean table 3

library(tidyverse)
library(readxl)
library(broom)
library(gt)

PSFI_df_malnutrition <- read_xlsx("PSFI_final_malnutrition3.xlsx")
# CREATE NEW AGE GROUP CATEGORY
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
  mutate(
    age_group1 = case_when(
      age_months < 12 ~ 0L,
      age_months >= 12 & age_months < 24 ~ 1L,
      age_years >=2 & age_years <5 ~ 2L,
      TRUE ~ NA_integer_
    )
  )
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
  mutate(
    popc_change = popc_dc - popc_admit,

    popc_dc1 = case_when(
      popc_dc >= 3 & popc_change >= 1 ~ 1L,
      !is.na(popc_dc) & !is.na(popc_admit) ~ 0L,
      TRUE ~ NA_integer_
    ),

    popc_dc1 = factor(
      popc_dc1,
      levels = c(0, 1),
      labels = c(
        "No new moderate disability",
        "New moderate disability"
      )
    )
  )
analysis_df <- PSFI_df_malnutrition %>%
  filter(
    case_control == 1,
    age_years < 5
  )
# SET NUTRITIONAL STATUS REFERENCE CATEGORY
analysis_df <- analysis_df %>%
  mutate(
    malnutrition_who5 = relevel(
      factor(malnutrition_who5),
      ref = "No malnutrition"
    )
  )
analysis_df <- analysis_df %>%
  mutate(
    picu_admit1 = factor(
      picu_admit,
      levels = c("No","Yes"),
      labels = c("No PICU admission","PICU admission")
    )
  )
sapply(
  analysis_df[, c("malnutrition_who5", "age_group1", "sex1", "hiv_pos1", "comorbidity", "picu_admit1")],
  class
)
malnutrition_who5        age_group1              sex1          hiv_pos1       comorbidity       picu_admit1 
         "factor"         "integer"       "character"       "character"         "numeric"          "factor" 
analysis_df <- analysis_df %>%
  mutate(
    comorbidity = factor(
      comorbidity,
      levels = c(0, 1),
      labels = c("No", "Yes")
    )
  )
mort_crude <- glm(
  mort_inhosp ~ malnutrition_who5,
  family = binomial,
  data = analysis_df
)

mort_adj <- glm(
  mort_inhosp ~ malnutrition_who5 +
    age_group1 + sex1 + hiv_pos1 + comorbidity,
  family = binomial,
  data = analysis_df
)

popc_crude <- glm(
  popc_dc1 ~ malnutrition_who5,
  family = binomial,
  data = analysis_df
)

popc_adj <- glm(
  popc_dc1 ~ malnutrition_who5 +
    age_group1 + sex1 + hiv_pos1 +
  comorbidity,
  family = binomial,
  data = analysis_df
)

picu_crude <- glm(
  picu_admit1 ~ malnutrition_who5,
  family = binomial,
  data = analysis_df
)

picu_adj <- glm(
  picu_admit1 ~ malnutrition_who5 +
    age_group1 + sex1 + hiv_pos1 +
   comorbidity,
  family = binomial,
  data = analysis_df
)
analysis_df_survivors <- analysis_df %>%
  filter(mort_inhosp == 0, case_control == 1, age_years <5) 

los_crude <- lm(
  los ~ malnutrition_who5,
  data = analysis_df_survivors
)

los_adj <- lm(
  los ~ malnutrition_who5 +
    age_group1 + sex1 + hiv_pos1  + comorbidity,
  data = analysis_df_survivors
)
library(broom)
library(dplyr)
library(tidyr)
make_table <- function(crude, adjusted){

  c1 <- broom::tidy(
    crude,
    exponentiate = TRUE,
    conf.int = TRUE
  ) %>%
    filter(grepl("^malnutrition_who5", term)) %>%
    transmute(
      Category = sub("^malnutrition_who5", "", term),
      OR = sprintf("%.2f (%.2f–%.2f)",
                   estimate,
                   conf.low,
                   conf.high),
      P = ifelse(
        p.value < 0.001,
        "<0.001",
        sprintf("%.3f", p.value)
      )
    )

  c2 <- broom::tidy(
    adjusted,
    exponentiate = TRUE,
    conf.int = TRUE
  ) %>%
    filter(grepl("^malnutrition_who5", term)) %>%
    transmute(
      Category = sub("^malnutrition_who5", "", term),
      aOR = sprintf("%.2f (%.2f–%.2f)",
                    estimate,
                    conf.low,
                    conf.high),
      aP = ifelse(
        p.value < 0.001,
        "<0.001",
        sprintf("%.3f", p.value)
      )
    )

  full_join(c1, c2, by = "Category")
}
make_table_lm <- function(crude, adjusted){

  c1 <- broom::tidy(crude, conf.int = TRUE) %>%
    filter(grepl("^malnutrition_who5", term)) %>%
    transmute(
      Category = sub("^malnutrition_who5", "", term),
      LOS_Beta = sprintf("%.2f (%.2f–%.2f)",
                         estimate,
                         conf.low,
                         conf.high),
      LOS_P = ifelse(
        p.value < 0.001,
        "<0.001",
        sprintf("%.3f", p.value)
      )
    )

  c2 <- broom::tidy(adjusted, conf.int = TRUE) %>%
    filter(grepl("^malnutrition_who5", term)) %>%
    transmute(
      Category = sub("^malnutrition_who5", "", term),
      LOS_aBeta = sprintf("%.2f (%.2f–%.2f)",
                          estimate,
                          conf.low,
                          conf.high),
      LOS_aP = ifelse(
        p.value < 0.001,
        "<0.001",
        sprintf("%.3f", p.value)
      )
    )

  full_join(c1, c2, by = "Category")
}
mort_tbl <- make_table(mort_crude, mort_adj)
popc_tbl <- make_table(popc_crude, popc_adj)
picu_tbl <- make_table(picu_crude, picu_adj)
los_tbl  <- make_table_lm(los_crude, los_adj)
names(mort_tbl) <- c(
  "Category",
  "Mortality_OR","Mortality_P",
  "Mortality_aOR","Mortality_aP"
)

names(popc_tbl) <- c(
  "Category",
  "POPC_OR","POPC_P",
  "POPC_aOR","POPC_aP"
)

names(picu_tbl) <- c(
  "Category",
  "PICU_OR","PICU_P",
  "PICU_aOR","PICU_aP"
)

names(los_tbl) <- c(
  "Category",
  "LOS_Beta","LOS_P",
  "LOS_aBeta","LOS_aP"
)
table3 <-
  mort_tbl %>%
  left_join(popc_tbl, by = "Category") %>%
  left_join(picu_tbl, by = "Category") %>%
  left_join(los_tbl, by = "Category")
table3 <- bind_rows(
  tibble(
    Category = "No malnutrition",
    Mortality_OR = "Reference",
    Mortality_aOR = "Reference",
    POPC_OR = "Reference",
    POPC_aOR = "Reference",
    PICU_OR = "Reference",
    PICU_aOR = "Reference",
    LOS_Beta = "Reference",
    LOS_aBeta = "Reference"
  ),
  table3
)
library(gt)

table3 %>%
  gt() %>%
  tab_header(
    title = md("**Association between nutritional status and clinical outcomes**")
  ) %>%
  tab_spanner(
    label = "In-hospital mortality",
    columns = c(Mortality_OR, Mortality_P,
                Mortality_aOR, Mortality_aP)
  ) %>%
  tab_spanner(
    label = "New moderate disability",
    columns = c(POPC_OR, POPC_P,
                POPC_aOR, POPC_aP)
  ) %>%
  tab_spanner(
    label = "PICU admission",
    columns = c(PICU_OR, PICU_P,
                PICU_aOR, PICU_aP)
  ) %>%

    tab_spanner(
    label = "Length of stay (survivors only)",
    columns = c(LOS_Beta, LOS_P,
                LOS_aBeta, LOS_aP)
  )%>%

  cols_label(
    Category = "Nutritional status",

    Mortality_OR = "OR (95% CI)",
    Mortality_P = "P",
    Mortality_aOR = "aOR (95% CI)",
    Mortality_aP = "P",

    POPC_OR = "OR (95% CI)",
    POPC_P = "P",
    POPC_aOR = "aOR (95% CI)",
    POPC_aP = "P",

    PICU_OR = "OR (95% CI)",
    PICU_P = "P",
    PICU_aOR = "aOR (95% CI)",
    PICU_aP = "P",
    
    LOS_Beta = "β (95% CI)",
LOS_P = "P",
LOS_aBeta = "Adjusted β (95% CI)",
LOS_aP = "P"
  ) %>%
  tab_source_note(
    md("*Adjusted for age group, sex, HIV status, and comorbidity status.*")
  )
Association between nutritional status and clinical outcomes
Nutritional status
In-hospital mortality
New moderate disability
PICU admission
Length of stay (survivors only)
OR (95% CI) P aOR (95% CI) P OR (95% CI) P aOR (95% CI) P OR (95% CI) P aOR (95% CI) P β (95% CI) P Adjusted β (95% CI) P
No malnutrition Reference NA Reference NA Reference NA Reference NA Reference NA Reference NA Reference NA Reference NA
Moderate malnutrition 2.12 (1.25–3.54) 0.005 2.13 (1.24–3.63) 0.006 2.75 (1.72–4.38) <0.001 2.79 (1.73–4.50) <0.001 1.12 (0.67–1.85) 0.650 1.16 (0.68–1.93) 0.570 1.64 (-1.42–4.70) 0.292 1.77 (-1.31–4.85) 0.260
Obesity 0.88 (0.25–2.38) 0.823 0.85 (0.24–2.33) 0.776 1.13 (0.44–2.63) 0.782 1.12 (0.43–2.64) 0.797 1.24 (0.50–2.79) 0.625 1.19 (0.48–2.72) 0.685 -0.32 (-5.21–4.57) 0.898 -0.42 (-5.32–4.48) 0.867
Overweight 0.47 (0.11–1.37) 0.226 0.42 (0.10–1.23) 0.164 0.31 (0.07–0.88) 0.054 0.28 (0.07–0.80) 0.038 0.61 (0.22–1.41) 0.282 0.56 (0.20–1.30) 0.210 -5.02 (-9.21–-0.83) 0.019 -5.25 (-9.46–-1.04) 0.015
Severe malnutrition 3.29 (1.97–5.48) <0.001 3.40 (2.00–5.74) <0.001 2.92 (1.80–4.73) <0.001 2.97 (1.82–4.84) <0.001 0.97 (0.55–1.65) 0.922 0.97 (0.55–1.66) 0.923 1.46 (-1.93–4.84) 0.399 1.49 (-1.90–4.88) 0.389
Adjusted for age group, sex, HIV status, and comorbidity status.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIENsZWFuIHRhYmxlIDMNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkoZ3QpDQoNClBTRklfZGZfbWFsbnV0cml0aW9uIDwtIHJlYWRfeGxzeCgiUFNGSV9maW5hbF9tYWxudXRyaXRpb24zLnhsc3giKQ0KYGBgDQoNCg0KYGBge3J9DQojIENSRUFURSBORVcgQUdFIEdST1VQIENBVEVHT1JZDQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUNCiAgbXV0YXRlKA0KICAgIGFnZV9ncm91cDEgPSBjYXNlX3doZW4oDQogICAgICBhZ2VfbW9udGhzIDwgMTIgfiAwTCwNCiAgICAgIGFnZV9tb250aHMgPj0gMTIgJiBhZ2VfbW9udGhzIDwgMjQgfiAxTCwNCiAgICAgIGFnZV95ZWFycyA+PTIgJiBhZ2VfeWVhcnMgPDUgfiAyTCwNCiAgICAgIFRSVUUgfiBOQV9pbnRlZ2VyXw0KICAgICkNCiAgKQ0KDQpgYGANCg0KYGBge3J9DQojIENSRUFURSBNT0RFUkFURSBESVNBQklMSVRZIENBVEVHT1JZDQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUNCiAgbXV0YXRlKA0KICAgIHBvcGNfY2hhbmdlID0gcG9wY19kYyAtIHBvcGNfYWRtaXQsDQoNCiAgICBwb3BjX2RjMSA9IGNhc2Vfd2hlbigNCiAgICAgIHBvcGNfZGMgPj0gMyAmIHBvcGNfY2hhbmdlID49IDEgfiAxTCwNCiAgICAgICFpcy5uYShwb3BjX2RjKSAmICFpcy5uYShwb3BjX2FkbWl0KSB+IDBMLA0KICAgICAgVFJVRSB+IE5BX2ludGVnZXJfDQogICAgKSwNCg0KICAgIHBvcGNfZGMxID0gZmFjdG9yKA0KICAgICAgcG9wY19kYzEsDQogICAgICBsZXZlbHMgPSBjKDAsIDEpLA0KICAgICAgbGFiZWxzID0gYygNCiAgICAgICAgIk5vIG5ldyBtb2RlcmF0ZSBkaXNhYmlsaXR5IiwNCiAgICAgICAgIk5ldyBtb2RlcmF0ZSBkaXNhYmlsaXR5Ig0KICAgICAgKQ0KICAgICkNCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KIyBBTkFMWVNJUyBPRiBDQVNFUyBVTkRFUiA1DQphbmFseXNpc19kZiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUNCiAgZmlsdGVyKA0KICAgIGNhc2VfY29udHJvbCA9PSAxLA0KICAgIGFnZV95ZWFycyA8IDUNCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KIyBTRVQgTlVUUklUSU9OQUwgU1RBVFVTIFJFRkVSRU5DRSBDQVRFR09SWQ0KYW5hbHlzaXNfZGYgPC0gYW5hbHlzaXNfZGYgJT4lDQogIG11dGF0ZSgNCiAgICBtYWxudXRyaXRpb25fd2hvNSA9IHJlbGV2ZWwoDQogICAgICBmYWN0b3IobWFsbnV0cml0aW9uX3dobzUpLA0KICAgICAgcmVmID0gIk5vIG1hbG51dHJpdGlvbiINCiAgICApDQogICkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBSRUNPREUgUElDVSBBRE1JU1NJT04gDQphbmFseXNpc19kZiA8LSBhbmFseXNpc19kZiAlPiUNCiAgbXV0YXRlKA0KICAgIHBpY3VfYWRtaXQxID0gZmFjdG9yKA0KICAgICAgcGljdV9hZG1pdCwNCiAgICAgIGxldmVscyA9IGMoIk5vIiwiWWVzIiksDQogICAgICBsYWJlbHMgPSBjKCJObyBQSUNVIGFkbWlzc2lvbiIsIlBJQ1UgYWRtaXNzaW9uIikNCiAgICApDQogICkNCmBgYA0KDQpgYGB7cn0NCnNhcHBseSgNCiAgYW5hbHlzaXNfZGZbLCBjKCJtYWxudXRyaXRpb25fd2hvNSIsICJhZ2VfZ3JvdXAxIiwgInNleDEiLCAiaGl2X3BvczEiLCAiY29tb3JiaWRpdHkiLCAicGljdV9hZG1pdDEiKV0sDQogIGNsYXNzDQopDQpgYGANCmBgYHtyfQ0KIyBSRUNPREUgQ09NT1JCRElJVFkNCmFuYWx5c2lzX2RmIDwtIGFuYWx5c2lzX2RmICU+JQ0KICBtdXRhdGUoDQogICAgY29tb3JiaWRpdHkgPSBmYWN0b3IoDQogICAgICBjb21vcmJpZGl0eSwNCiAgICAgIGxldmVscyA9IGMoMCwgMSksDQogICAgICBsYWJlbHMgPSBjKCJObyIsICJZZXMiKQ0KICAgICkNCiAgKQ0KYGBgDQoNCg0KYGBge3J9DQojIFJVTiBMT0dJU1RJQyBSRUdSRVNTSU9OIEZPUiBUSFJFRSBCSU5BUlkgT1VUQ09NU0UsIEFESlVTVEVEIEZPUiBBR0UsIFNFWCwgSElWICYgQ09NT1JCSURJVFkNCm1vcnRfY3J1ZGUgPC0gZ2xtKA0KICBtb3J0X2luaG9zcCB+IG1hbG51dHJpdGlvbl93aG81LA0KICBmYW1pbHkgPSBiaW5vbWlhbCwNCiAgZGF0YSA9IGFuYWx5c2lzX2RmDQopDQoNCm1vcnRfYWRqIDwtIGdsbSgNCiAgbW9ydF9pbmhvc3AgfiBtYWxudXRyaXRpb25fd2hvNSArDQogICAgYWdlX2dyb3VwMSArIHNleDEgKyBoaXZfcG9zMSArIGNvbW9yYmlkaXR5LA0KICBmYW1pbHkgPSBiaW5vbWlhbCwNCiAgZGF0YSA9IGFuYWx5c2lzX2RmDQopDQoNCnBvcGNfY3J1ZGUgPC0gZ2xtKA0KICBwb3BjX2RjMSB+IG1hbG51dHJpdGlvbl93aG81LA0KICBmYW1pbHkgPSBiaW5vbWlhbCwNCiAgZGF0YSA9IGFuYWx5c2lzX2RmDQopDQoNCnBvcGNfYWRqIDwtIGdsbSgNCiAgcG9wY19kYzEgfiBtYWxudXRyaXRpb25fd2hvNSArDQogICAgYWdlX2dyb3VwMSArIHNleDEgKyBoaXZfcG9zMSArDQogIGNvbW9yYmlkaXR5LA0KICBmYW1pbHkgPSBiaW5vbWlhbCwNCiAgZGF0YSA9IGFuYWx5c2lzX2RmDQopDQoNCnBpY3VfY3J1ZGUgPC0gZ2xtKA0KICBwaWN1X2FkbWl0MSB+IG1hbG51dHJpdGlvbl93aG81LA0KICBmYW1pbHkgPSBiaW5vbWlhbCwNCiAgZGF0YSA9IGFuYWx5c2lzX2RmDQopDQoNCnBpY3VfYWRqIDwtIGdsbSgNCiAgcGljdV9hZG1pdDEgfiBtYWxudXRyaXRpb25fd2hvNSArDQogICAgYWdlX2dyb3VwMSArIHNleDEgKyBoaXZfcG9zMSArDQogICBjb21vcmJpZGl0eSwNCiAgZmFtaWx5ID0gYmlub21pYWwsDQogIGRhdGEgPSBhbmFseXNpc19kZg0KKQ0KYGBgDQoNCmBgYHtyfQ0KIyBMSU5FQVIgUkVHUkVTU0lPTiBNT0RFTCBGT1IgTEVOR1RIIE9GIFNUQVkNCmFuYWx5c2lzX2RmX3N1cnZpdm9ycyA8LSBhbmFseXNpc19kZiAlPiUNCiAgZmlsdGVyKG1vcnRfaW5ob3NwID09IDAsIGNhc2VfY29udHJvbCA9PSAxLCBhZ2VfeWVhcnMgPDUpIA0KDQpsb3NfY3J1ZGUgPC0gbG0oDQogIGxvcyB+IG1hbG51dHJpdGlvbl93aG81LA0KICBkYXRhID0gYW5hbHlzaXNfZGZfc3Vydml2b3JzDQopDQoNCmxvc19hZGogPC0gbG0oDQogIGxvcyB+IG1hbG51dHJpdGlvbl93aG81ICsNCiAgICBhZ2VfZ3JvdXAxICsgc2V4MSArIGhpdl9wb3MxICArIGNvbW9yYmlkaXR5LA0KICBkYXRhID0gYW5hbHlzaXNfZGZfc3Vydml2b3JzDQopDQpgYGANCg0KYGBge3J9DQojIEVYVFJBQ1QgUkVHUkVTU0lPTiBSRVNVTFRTDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXIpDQptYWtlX3RhYmxlIDwtIGZ1bmN0aW9uKGNydWRlLCBhZGp1c3RlZCl7DQoNCiAgYzEgPC0gYnJvb206OnRpZHkoDQogICAgY3J1ZGUsDQogICAgZXhwb25lbnRpYXRlID0gVFJVRSwNCiAgICBjb25mLmludCA9IFRSVUUNCiAgKSAlPiUNCiAgICBmaWx0ZXIoZ3JlcGwoIl5tYWxudXRyaXRpb25fd2hvNSIsIHRlcm0pKSAlPiUNCiAgICB0cmFuc211dGUoDQogICAgICBDYXRlZ29yeSA9IHN1YigiXm1hbG51dHJpdGlvbl93aG81IiwgIiIsIHRlcm0pLA0KICAgICAgT1IgPSBzcHJpbnRmKCIlLjJmICglLjJm4oCTJS4yZikiLA0KICAgICAgICAgICAgICAgICAgIGVzdGltYXRlLA0KICAgICAgICAgICAgICAgICAgIGNvbmYubG93LA0KICAgICAgICAgICAgICAgICAgIGNvbmYuaGlnaCksDQogICAgICBQID0gaWZlbHNlKA0KICAgICAgICBwLnZhbHVlIDwgMC4wMDEsDQogICAgICAgICI8MC4wMDEiLA0KICAgICAgICBzcHJpbnRmKCIlLjNmIiwgcC52YWx1ZSkNCiAgICAgICkNCiAgICApDQoNCiAgYzIgPC0gYnJvb206OnRpZHkoDQogICAgYWRqdXN0ZWQsDQogICAgZXhwb25lbnRpYXRlID0gVFJVRSwNCiAgICBjb25mLmludCA9IFRSVUUNCiAgKSAlPiUNCiAgICBmaWx0ZXIoZ3JlcGwoIl5tYWxudXRyaXRpb25fd2hvNSIsIHRlcm0pKSAlPiUNCiAgICB0cmFuc211dGUoDQogICAgICBDYXRlZ29yeSA9IHN1YigiXm1hbG51dHJpdGlvbl93aG81IiwgIiIsIHRlcm0pLA0KICAgICAgYU9SID0gc3ByaW50ZigiJS4yZiAoJS4yZuKAkyUuMmYpIiwNCiAgICAgICAgICAgICAgICAgICAgZXN0aW1hdGUsDQogICAgICAgICAgICAgICAgICAgIGNvbmYubG93LA0KICAgICAgICAgICAgICAgICAgICBjb25mLmhpZ2gpLA0KICAgICAgYVAgPSBpZmVsc2UoDQogICAgICAgIHAudmFsdWUgPCAwLjAwMSwNCiAgICAgICAgIjwwLjAwMSIsDQogICAgICAgIHNwcmludGYoIiUuM2YiLCBwLnZhbHVlKQ0KICAgICAgKQ0KICAgICkNCg0KICBmdWxsX2pvaW4oYzEsIGMyLCBieSA9ICJDYXRlZ29yeSIpDQp9DQpgYGANCg0KYGBge3J9DQojIENPTUJJTkUgRVZFUllUSElORyBJTlRPIE9ORSBUQUJMRQ0KbWFrZV90YWJsZV9sbSA8LSBmdW5jdGlvbihjcnVkZSwgYWRqdXN0ZWQpew0KDQogIGMxIDwtIGJyb29tOjp0aWR5KGNydWRlLCBjb25mLmludCA9IFRSVUUpICU+JQ0KICAgIGZpbHRlcihncmVwbCgiXm1hbG51dHJpdGlvbl93aG81IiwgdGVybSkpICU+JQ0KICAgIHRyYW5zbXV0ZSgNCiAgICAgIENhdGVnb3J5ID0gc3ViKCJebWFsbnV0cml0aW9uX3dobzUiLCAiIiwgdGVybSksDQogICAgICBMT1NfQmV0YSA9IHNwcmludGYoIiUuMmYgKCUuMmbigJMlLjJmKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZXN0aW1hdGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgY29uZi5sb3csDQogICAgICAgICAgICAgICAgICAgICAgICAgY29uZi5oaWdoKSwNCiAgICAgIExPU19QID0gaWZlbHNlKA0KICAgICAgICBwLnZhbHVlIDwgMC4wMDEsDQogICAgICAgICI8MC4wMDEiLA0KICAgICAgICBzcHJpbnRmKCIlLjNmIiwgcC52YWx1ZSkNCiAgICAgICkNCiAgICApDQoNCiAgYzIgPC0gYnJvb206OnRpZHkoYWRqdXN0ZWQsIGNvbmYuaW50ID0gVFJVRSkgJT4lDQogICAgZmlsdGVyKGdyZXBsKCJebWFsbnV0cml0aW9uX3dobzUiLCB0ZXJtKSkgJT4lDQogICAgdHJhbnNtdXRlKA0KICAgICAgQ2F0ZWdvcnkgPSBzdWIoIl5tYWxudXRyaXRpb25fd2hvNSIsICIiLCB0ZXJtKSwNCiAgICAgIExPU19hQmV0YSA9IHNwcmludGYoIiUuMmYgKCUuMmbigJMlLjJmKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVzdGltYXRlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mLmxvdywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZi5oaWdoKSwNCiAgICAgIExPU19hUCA9IGlmZWxzZSgNCiAgICAgICAgcC52YWx1ZSA8IDAuMDAxLA0KICAgICAgICAiPDAuMDAxIiwNCiAgICAgICAgc3ByaW50ZigiJS4zZiIsIHAudmFsdWUpDQogICAgICApDQogICAgKQ0KDQogIGZ1bGxfam9pbihjMSwgYzIsIGJ5ID0gIkNhdGVnb3J5IikNCn0NCmBgYA0KDQpgYGB7cn0NCm1vcnRfdGJsIDwtIG1ha2VfdGFibGUobW9ydF9jcnVkZSwgbW9ydF9hZGopDQpwb3BjX3RibCA8LSBtYWtlX3RhYmxlKHBvcGNfY3J1ZGUsIHBvcGNfYWRqKQ0KcGljdV90YmwgPC0gbWFrZV90YWJsZShwaWN1X2NydWRlLCBwaWN1X2FkaikNCmxvc190YmwgIDwtIG1ha2VfdGFibGVfbG0obG9zX2NydWRlLCBsb3NfYWRqKQ0KYGBgDQoNCmBgYHtyfQ0KbmFtZXMobW9ydF90YmwpIDwtIGMoDQogICJDYXRlZ29yeSIsDQogICJNb3J0YWxpdHlfT1IiLCJNb3J0YWxpdHlfUCIsDQogICJNb3J0YWxpdHlfYU9SIiwiTW9ydGFsaXR5X2FQIg0KKQ0KDQpuYW1lcyhwb3BjX3RibCkgPC0gYygNCiAgIkNhdGVnb3J5IiwNCiAgIlBPUENfT1IiLCJQT1BDX1AiLA0KICAiUE9QQ19hT1IiLCJQT1BDX2FQIg0KKQ0KDQpuYW1lcyhwaWN1X3RibCkgPC0gYygNCiAgIkNhdGVnb3J5IiwNCiAgIlBJQ1VfT1IiLCJQSUNVX1AiLA0KICAiUElDVV9hT1IiLCJQSUNVX2FQIg0KKQ0KDQpuYW1lcyhsb3NfdGJsKSA8LSBjKA0KICAiQ2F0ZWdvcnkiLA0KICAiTE9TX0JldGEiLCJMT1NfUCIsDQogICJMT1NfYUJldGEiLCJMT1NfYVAiDQopDQpgYGANCg0KYGBge3J9DQp0YWJsZTMgPC0NCiAgbW9ydF90YmwgJT4lDQogIGxlZnRfam9pbihwb3BjX3RibCwgYnkgPSAiQ2F0ZWdvcnkiKSAlPiUNCiAgbGVmdF9qb2luKHBpY3VfdGJsLCBieSA9ICJDYXRlZ29yeSIpICU+JQ0KICBsZWZ0X2pvaW4obG9zX3RibCwgYnkgPSAiQ2F0ZWdvcnkiKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnRhYmxlMyA8LSBiaW5kX3Jvd3MoDQogIHRpYmJsZSgNCiAgICBDYXRlZ29yeSA9ICJObyBtYWxudXRyaXRpb24iLA0KICAgIE1vcnRhbGl0eV9PUiA9ICJSZWZlcmVuY2UiLA0KICAgIE1vcnRhbGl0eV9hT1IgPSAiUmVmZXJlbmNlIiwNCiAgICBQT1BDX09SID0gIlJlZmVyZW5jZSIsDQogICAgUE9QQ19hT1IgPSAiUmVmZXJlbmNlIiwNCiAgICBQSUNVX09SID0gIlJlZmVyZW5jZSIsDQogICAgUElDVV9hT1IgPSAiUmVmZXJlbmNlIiwNCiAgICBMT1NfQmV0YSA9ICJSZWZlcmVuY2UiLA0KICAgIExPU19hQmV0YSA9ICJSZWZlcmVuY2UiDQogICksDQogIHRhYmxlMw0KKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShndCkNCg0KdGFibGUzICU+JQ0KICBndCgpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gbWQoIioqQXNzb2NpYXRpb24gYmV0d2VlbiBudXRyaXRpb25hbCBzdGF0dXMgYW5kIGNsaW5pY2FsIG91dGNvbWVzKioiKQ0KICApICU+JQ0KICB0YWJfc3Bhbm5lcigNCiAgICBsYWJlbCA9ICJJbi1ob3NwaXRhbCBtb3J0YWxpdHkiLA0KICAgIGNvbHVtbnMgPSBjKE1vcnRhbGl0eV9PUiwgTW9ydGFsaXR5X1AsDQogICAgICAgICAgICAgICAgTW9ydGFsaXR5X2FPUiwgTW9ydGFsaXR5X2FQKQ0KICApICU+JQ0KICB0YWJfc3Bhbm5lcigNCiAgICBsYWJlbCA9ICJOZXcgbW9kZXJhdGUgZGlzYWJpbGl0eSIsDQogICAgY29sdW1ucyA9IGMoUE9QQ19PUiwgUE9QQ19QLA0KICAgICAgICAgICAgICAgIFBPUENfYU9SLCBQT1BDX2FQKQ0KICApICU+JQ0KICB0YWJfc3Bhbm5lcigNCiAgICBsYWJlbCA9ICJQSUNVIGFkbWlzc2lvbiIsDQogICAgY29sdW1ucyA9IGMoUElDVV9PUiwgUElDVV9QLA0KICAgICAgICAgICAgICAgIFBJQ1VfYU9SLCBQSUNVX2FQKQ0KICApICU+JQ0KDQogICAgdGFiX3NwYW5uZXIoDQogICAgbGFiZWwgPSAiTGVuZ3RoIG9mIHN0YXkgKHN1cnZpdm9ycyBvbmx5KSIsDQogICAgY29sdW1ucyA9IGMoTE9TX0JldGEsIExPU19QLA0KICAgICAgICAgICAgICAgIExPU19hQmV0YSwgTE9TX2FQKQ0KICApJT4lDQoNCiAgY29sc19sYWJlbCgNCiAgICBDYXRlZ29yeSA9ICJOdXRyaXRpb25hbCBzdGF0dXMiLA0KDQogICAgTW9ydGFsaXR5X09SID0gIk9SICg5NSUgQ0kpIiwNCiAgICBNb3J0YWxpdHlfUCA9ICJQIiwNCiAgICBNb3J0YWxpdHlfYU9SID0gImFPUiAoOTUlIENJKSIsDQogICAgTW9ydGFsaXR5X2FQID0gIlAiLA0KDQogICAgUE9QQ19PUiA9ICJPUiAoOTUlIENJKSIsDQogICAgUE9QQ19QID0gIlAiLA0KICAgIFBPUENfYU9SID0gImFPUiAoOTUlIENJKSIsDQogICAgUE9QQ19hUCA9ICJQIiwNCg0KICAgIFBJQ1VfT1IgPSAiT1IgKDk1JSBDSSkiLA0KICAgIFBJQ1VfUCA9ICJQIiwNCiAgICBQSUNVX2FPUiA9ICJhT1IgKDk1JSBDSSkiLA0KICAgIFBJQ1VfYVAgPSAiUCIsDQogICAgDQogICAgTE9TX0JldGEgPSAizrIgKDk1JSBDSSkiLA0KTE9TX1AgPSAiUCIsDQpMT1NfYUJldGEgPSAiQWRqdXN0ZWQgzrIgKDk1JSBDSSkiLA0KTE9TX2FQID0gIlAiDQogICkgJT4lDQogIHRhYl9zb3VyY2Vfbm90ZSgNCiAgICBtZCgiKkFkanVzdGVkIGZvciBhZ2UgZ3JvdXAsIHNleCwgSElWIHN0YXR1cywgYW5kIGNvbW9yYmlkaXR5IHN0YXR1cy4qIikNCiAgKQ0KYGBgDQoNCg0K