diff --git a/.gitignore b/.gitignore index 5df29fb..5049c59 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,7 @@ out *.sav *.sas7bdat wsi -#*.log +dataverse # Temp files _gsdata_/ diff --git a/AEDB.EM.baseline.Rmd b/AEDB.EM.baseline.Rmd new file mode 100644 index 0000000..5cd1f53 --- /dev/null +++ b/AEDB.EM.baseline.Rmd @@ -0,0 +1,1221 @@ +--- +title: "Baseline characteristics" +author: "[Sander W. van der Laan, PhD](https://swvanderlaan.github.io) | @swvanderlaan | s.w.vanderlaan@gmail.com" +date: "`r Sys.Date()`" +output: + html_notebook: + cache: yes + code_folding: hide + collapse: yes + df_print: paged + fig.align: center + fig_caption: yes + fig_height: 6 + fig_retina: 2 + fig_width: 7 + highlight: tango + theme: lumen + toc: yes + toc_float: + collapsed: no + smooth_scroll: yes +mainfont: Arial +subtitle: Accompanying 'EntropyMasker' +editor_options: + chunk_output_type: inline +# bibliography: references.bib +# knit: worcs::cite_all +--- + +# General Setup +We will clean the environment, setup the locations, define colors, and create a datestamp. + +_Clean the environment._ +```{r echo = FALSE} +rm(list = ls()) +``` + +_Set locations and working directories..._ +```{r LocalSystem, echo = FALSE} +source("scripts/local.system.R") + +``` + +_... a package-installation function ..._ +```{r Function: installations} +source("scripts/functions.R") + +``` + + +_... and load those packages._ +```{r loading_packages, message=FALSE, warning=FALSE} +source("scripts/pack01.packages.R") + + +``` + +_We will create a datestamp and define the Utrecht Science Park Colour Scheme_. +```{r Setting: Colors} + +Today = format(as.Date(as.POSIXlt(Sys.time())), "%Y%m%d") +Today.Report = format(as.Date(as.POSIXlt(Sys.time())), "%A, %B %d, %Y") + +source("scripts/colors.R") + +``` + +```{r global_options, include = FALSE} +# further define some knitr-options. +knitr::opts_chunk$set(fig.width = 12, fig.height = 8, fig.path = 'Figures/', + wwarning = TRUE, # show warnings during codebook generation + message = TRUE, # show messages during codebook generation + error = TRUE, # do not interrupt codebook generation in case of errors, + # usually better for debugging + echo = TRUE, # show R code + eval = TRUE) +ggplot2::theme_set(ggplot2::theme_minimal()) +pander::panderOptions("table.split.table", Inf) +``` + +# This notebook + +In this notebook we create a baseline table of the samples used in **`EntropyMasker`**. + +# Athero-Express Biobank Study + +The [*Athero-Express Biobank Study (AE)*](https://doi.org/10.1007/s10564-004-2304-6) contains plaque material of patients that underwent endarterectomyat two Dutch tertiary referral centers. Details of the study design were described before. Briefly, blood and plaque material were obtained during endarterectomy and stored at -80 ℃. All patients provided informed consent and the study was approved by the medical ethics committee. + +## Load relevant samples + +```{r} +EM_samples <- fread(paste0(ANALYSIS_loc, "/dataverse/EntropyMasker_image_files_used.txt")) +``` + +## Load data + +Loading Athero-Express Biobank Study clinical and biobank data. + +```{r LoadAEDB} +cat("* get Athero-Express Biobank Study Database...") +# METHOD 1: It seems this method gives loads of errors and warnings, which all are hard to comprehend +# or debug. We expect 3,527 samples, and 927 variables; we get 927 variables!!! +# AEdata = as.data.table(read.spss(paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.sav"), +# trim.factor.names = TRUE, trim_values = TRUE, # we trim spaces in values +# reencode = TRUE, # we re-encode to the local locale encoding +# add.undeclared.levels = "append", # we do *not* want to convert to R-factors +# use.value.labels = FALSE, # we do *not* convert variables with value labels into R factors +# use.missings = TRUE, sub = "NA", # we will set every missing variable to NA +# duplicated.value.labels = "condense", # we will condense duplicated value labels +# to.data.frame = TRUE)) +# AEdata.labels <- as.data.table(attr(AEdata, "variable.labels")) +# names(AEdata.labels) <- "Variable" + +# METHOD 2: Using library("haven") importing seems flawless; best argument being: +# we expect 3,527 samples and 888 variables, which is what you'd get with this method +# So for now, METHOD 2 is prefered. +# +require(haven) + +# AEDB <- haven::read_sav(paste0(AEDB_loc, "/2022_1_NEW_AtheroExpressDatabase_ScientificAE_15-02-2022.sav")) # something wrong with Age-variable +# AEDB <- haven::read_sav(paste0(AEDB_loc, "/2020_1_NEW_AtheroExpressDatabase_ScientificAE_30-09-2020.sav")) # duplicate studynumbers in it +AEDB <- haven::read_sav(paste0(AEDB_loc, "/2020_1_NEW_AtheroExpressDatabase_ScientificAE_16-03-2020.sav")) + +# writing off the SPSS data to an Excel. +# fwrite(AEdata, file = paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.values.xlsx"), +# sep = ";", na = "NA", dec = ".", col.names = TRUE, row.names = FALSE, +# dateTimeAs = "ISO", showProgress = TRUE, verbose = TRUE) +# warnings() + +AEDB[1:10, 1:10] +dim(AEDB) + +``` + + + + + + + + + + + + + + + + + + + + + + +## Fixing and creating variables + +We have to fix certain clinical parameters: + +- symptoms +- diabetes +- alcohol use +- smoking +- plaque phenotypes + +### Symptoms + +We need to be very strict in defining *symptoms.* Therefore we will fix a new +variable that groups *symptoms* at inclusion. + +Coding of *symptoms* is as follows: + +- missing -999 +- Asymptomatic 0 +- TIA 1 +- minor stroke 2 +- Major stroke 3 +- Amaurosis fugax 4 +- Four vessel disease 5 +- Vertebrobasilary TIA 7 +- Retinal infarction 8 +- Symptomatic, but aspecific symtoms 9 +- Contralateral symptomatic occlusion 10 +- retinal infarction 11 +- armclaudication due to occlusion subclavian artery, CEA needed for bypass + 12 +- retinal infarction + TIAs 13 +- Ocular ischemic syndrome 14 +- ischemisch glaucoom 15 +- subclavian steal syndrome 16 +- TGA 17 + +We will group as follows: + +1. Asymptomatic > 0 +2. TIA > 1, 7, 13 +3. Stroke > 2, 3 +4. Ocular > 4, 14, 15 +5. Retinal infarction > 8, 11 +6. Other > 5, 9, 10, 12, 16, 17 + +```{r FixSymptoms, message=FALSE, warning=FALSE} + +# Fix symptoms + +attach(AEDB) +AEDB[,"Symptoms.5G"] <- NA +AEDB$Symptoms.5G[sympt == 0] <- "Asymptomatic" +AEDB$Symptoms.5G[sympt == 1 | sympt == 7 | sympt == 13] <- "TIA" +AEDB$Symptoms.5G[sympt == 2 | sympt == 3] <- "Stroke" +AEDB$Symptoms.5G[sympt == 4 | sympt == 14 | sympt == 15 ] <- "Ocular" +AEDB$Symptoms.5G[sympt == 8 | sympt == 11] <- "Retinal infarction" +AEDB$Symptoms.5G[sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Other" + + +# AsymptSympt +AEDB[,"AsymptSympt"] <- NA +AEDB$AsymptSympt[sympt == -999] <- NA +AEDB$AsymptSympt[sympt == 0] <- "Asymptomatic" +AEDB$AsymptSympt[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3] <- "Symptomatic" +AEDB$AsymptSympt[sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Ocular and others" + +# AsymptSympt +AEDB[,"AsymptSympt2G"] <- NA +AEDB$AsymptSympt2G[sympt == -999] <- NA +AEDB$AsymptSympt2G[sympt == 0] <- "Asymptomatic" +AEDB$AsymptSympt2G[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3 | sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Symptomatic" + +detach(AEDB) + +# table(AEDB$sympt, useNA = "ifany") +# table(AEDB$AsymptSympt2G, useNA = "ifany") +# table(AEDB$Symptoms.5G, useNA = "ifany") +# +# table(AEDB$AsymptSympt2G, AEDB$sympt, useNA = "ifany") +# table(AEDB$Symptoms.5G, AEDB$sympt, useNA = "ifany") +table(AEDB$AsymptSympt2G, AEDB$Symptoms.5G, useNA = "ifany") + +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "sympt", "Symptoms.5G", "AsymptSympt")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# table(AEDB.temp$Symptoms.5G, AEDB.temp$AsymptSympt) +# +# rm(AEDB.temp) +``` + +### Re-assessed symptoms + +We re-assessed the categorization of symptoms. These are summarized and parsed +in this section. + +Labeling of new symptom categories. + +```{r message=FALSE, warning=FALSE, paged.print=TRUE} + +AEDB$indexsymptoms_worst +AEDB$indexsymptoms_worst_4g +AEDB$indexsymptoms_latest +AEDB$indexsymptoms_latest_4g + +``` + +Getting counts for each of the most important categories. + +```{r} +cat("New 'worst' vs 'latest' symptom categories.\n") +table(as_factor(AEDB$indexsymptoms_worst_4g), as_factor(AEDB$indexsymptoms_latest_4g)) + +cat("\nNew 'worst' symptom categories.\n") +table((AEDB$indexsymptoms_worst_4g)) + +cat("\nNew 'latest' symptom categories.\n") +table(as_factor(AEDB$indexsymptoms_latest_4g)) +``` + +Comparing with the original symptom categories. + +```{r} +cat("New 'latest' vs original symptom 2G categories.\n") +table((AEDB$indexsymptoms_latest_4g), AEDB$AsymptSympt2G) + +cat("\nNew 'latest' vs original symptom 5G categories.\n") +table((AEDB$indexsymptoms_latest_4g), AEDB$Symptoms.5G) + +``` + +We need to be very strict in defining *symptoms.* Therefore we will fix a new +variable that groups *symptoms* at inclusion. + +Coding of *symptoms* is as follows: + +- asympt 0\ +- ocular 1\ +- TIA 2\ +- stroke 3\ +- unclear 9 + +We will group as follows: + +1. Asymptomatic > 0 +2. Symptomatic > 1, 2, 3 +3. NA > 9 + +```{r FixNewSymptoms} + +# Fix symptoms +attach(AEDB) + +# Symptoms.Update2G +AEDB[,"Symptoms.Update2G"] <- NA +AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 0] <- "Asymptomatic" +AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 1 | indexsymptoms_latest_4g == 2 | indexsymptoms_latest_4g == 3] <- "Symptomatic" +AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 9 ] <- NA + +# Symptoms.Update3G +AEDB[,"Symptoms.Update3G"] <- NA +AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 0] <- "Asymptomatic" +AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 1 | indexsymptoms_latest_4g == 2 | indexsymptoms_latest_4g == 3] <- "Symptomatic" +AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 9 ] <- "Unclear" + +detach(AEDB) + +table(AEDB$Symptoms.Update2G, AEDB$Symptoms.5G, useNA = "ifany") +table(AEDB$Symptoms.Update3G, AEDB$Symptoms.5G, useNA = "ifany") + +``` + +### Other clinical characteristics + +We will also fix the *diabetes* status variable. + +```{r FixDiabetes, message=FALSE, warning=FALSE} + +# Fix diabetes +attach(AEDB) +AEDB[,"DiabetesStatus"] <- NA +AEDB$DiabetesStatus[DM.composite == -999] <- NA +AEDB$DiabetesStatus[DM.composite == 0] <- "Control (no Diabetes Dx/Med)" +AEDB$DiabetesStatus[DM.composite == 1] <- "Diabetes" +detach(AEDB) + +table(AEDB$DM.composite, AEDB$DiabetesStatus) +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# rm(AEDB.temp) + +``` + +We will also fix the *smoking* status variable. We are interested in whether +someone never, ever or is currently (at the time of inclusion) smoking. This is +based on the questionnaire. + +- `diet801`: are you a smoker? +- `diet802`: did you smoke in the past? + +We already have some variables indicating smoking status: + +- `SmokingReported`: patient has reported to smoke. +- `SmokingYearOR`: smoking in the year of surgery? +- `SmokerCurrent`: currently smoking? + +```{r FixSmoking, message=FALSE, warning=FALSE} +require(labelled) +AEDB$diet801 <- to_factor(AEDB$diet801) +AEDB$diet802 <- to_factor(AEDB$diet802) +AEDB$diet805 <- to_factor(AEDB$diet805) +AEDB$SmokingReported <- to_factor(AEDB$SmokingReported) +AEDB$SmokerCurrent <- to_factor(AEDB$SmokerCurrent) +AEDB$SmokingYearOR <- to_factor(AEDB$SmokingYearOR) + +# table(AEDB$diet801) +# table(AEDB$diet802) +# table(AEDB$SmokingReported) +# table(AEDB$SmokerCurrent) +# table(AEDB$SmokingYearOR) +# table(AEDB$SmokingReported, AEDB$SmokerCurrent, useNA = "ifany", dnn = c("Reported smoking", "Current smoker")) +# +# table(AEDB$diet801, AEDB$diet802, useNA = "ifany", dnn = c("Smoker", "Past smoker")) + +cat("\nFixing smoking status.\n") +attach(AEDB) +AEDB[,"SmokerStatus"] <- NA +AEDB$SmokerStatus[diet802 == "don't know"] <- "Never smoked" +AEDB$SmokerStatus[diet802 == "I still smoke"] <- "Current smoker" +AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "no"] <- "Never smoked" +AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "yes"] <- "Ex-smoker" +AEDB$SmokerStatus[SmokerCurrent == "yes"] <- "Current smoker" +AEDB$SmokerStatus[SmokerCurrent == "no data available/missing"] <- NA +# AEDB$SmokerStatus[is.na(SmokerCurrent)] <- "Never smoked" +detach(AEDB) + +cat("\n* Current smoking status.\n") +table(AEDB$SmokerCurrent, + useNA = "ifany", + dnn = c("Current smoker")) + +cat("\n* Updated smoking status.\n") +table(AEDB$SmokerStatus, + useNA = "ifany", + dnn = c("Updated smoking status")) + +cat("\n* Comparing to 'SmokerCurrent'.\n") +table(AEDB$SmokerStatus, AEDB$SmokerCurrent, + useNA = "ifany", + dnn = c("Updated smoking status", "Current smoker")) + +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# rm(AEDB.temp) + + +``` + +We will also fix the *alcohol* status variable. + +```{r FixAlcohol, message=FALSE, warning=FALSE} + +# Fix diabetes +attach(AEDB) +AEDB[,"AlcoholUse"] <- NA +AEDB$AlcoholUse[diet810 == -999] <- NA +AEDB$AlcoholUse[diet810 == 0] <- "No" +AEDB$AlcoholUse[diet810 == 1] <- "Yes" +detach(AEDB) + +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "diet810", "AlcoholUse")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# AEDB.temp$AlcoholUse <- to_factor(AEDB.temp$AlcoholUse) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# rm(AEDB.temp) + + +``` + +We will also fix a history of CAD, stroke or peripheral intervention status variable. This will be based on `CAD_history`, `Stroke_history`, and `Peripheral.interv` + +```{r FixCAD_History, message=FALSE, warning=FALSE} + +# Fix diabetes +attach(AEDB) +AEDB[,"MedHx_CVD"] <- NA +AEDB$MedHx_CVD[CAD_history == 0 | Stroke_history == 0 | Peripheral.interv == 0] <- "No" +AEDB$MedHx_CVD[CAD_history == 1 | Stroke_history == 1 | Peripheral.interv == 1] <- "yes" +detach(AEDB) + +table(AEDB$CAD_history) +table(AEDB$Stroke_history) +table(AEDB$Peripheral.interv) +table(AEDB$MedHx_CVD) + +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "diet810", "AlcoholUse")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# AEDB.temp$AlcoholUse <- to_factor(AEDB.temp$AlcoholUse) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# rm(AEDB.temp) + + +``` + +### Plaque phenotypes + +We will also fix the *plaquephenotypes* variable. + +Coding of symptoms is as follows: + +- missing -999\ +- not relevant -888 +- fibrous 1\ +- fibroatheromatous 2\ +- atheromatous 3 + +```{r FixPlaquePhenotypes, message=FALSE, warning=FALSE} + +# Fix plaquephenotypes +attach(AEDB) +AEDB[,"OverallPlaquePhenotype"] <- NA +AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA +AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA +AEDB$OverallPlaquePhenotype[plaquephenotype == 1] <- "fibrous" +AEDB$OverallPlaquePhenotype[plaquephenotype == 2] <- "fibroatheromatous" +AEDB$OverallPlaquePhenotype[plaquephenotype == 3] <- "atheromatous" +detach(AEDB) + +# AEDB.temp <- subset(AEDB, select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "plaquephenotype", "OverallPlaquePhenotype")) +# require(labelled) +# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender) +# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital) +# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary) +# +# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE) +# +# rm(AEDB.temp) + +``` + +We will also fix and inverse-rank normal transform the continuous (manually) +scored plaque phenotypes. + +```{r IRNT PlaquePhenotypes} +AEDB$macmean0 <- as.numeric(AEDB$macmean0) +AEDB$smcmean0 <- as.numeric(AEDB$smcmean0) +AEDB$neutrophils <- as.numeric(AEDB$neutrophils) +AEDB$Mast_cells_plaque <- as.numeric(AEDB$Mast_cells_plaque) +AEDB$vessel_density_averaged <- as.numeric(AEDB$vessel_density_averaged) + +AEDB$MAC_rankNorm <- qnorm((rank(AEDB$macmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$macmean0))) +AEDB$SMC_rankNorm <- qnorm((rank(AEDB$smcmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$smcmean0))) +AEDB$Neutrophils_rankNorm <- qnorm((rank(AEDB$neutrophils, na.last = "keep") - 0.5) / sum(!is.na(AEDB$neutrophils))) +AEDB$MastCells_rankNorm <- qnorm((rank(AEDB$Mast_cells_plaque, na.last = "keep") - 0.5) / sum(!is.na(AEDB$Mast_cells_plaque))) +AEDB$VesselDensity_rankNorm <- qnorm((rank(AEDB$vessel_density_averaged, na.last = "keep") - 0.5) / sum(!is.na(AEDB$vessel_density_averaged))) + +``` + +```{r IRNT PlaquePhenotypes: Visualisation} +library(labelled) +AEDB$Gender <- to_factor(AEDB$Gender) +library(patchwork) + +p1 <- ggpubr::gghistogram(AEDB, "macmean0", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "% of macrophages (CD68)", + xlab = "% per region of interest", + ggtheme = theme_minimal()) + +p2 <- ggpubr::gghistogram(AEDB, "MAC_rankNorm", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "% of macrophages (CD68)", + xlab = "% per region of interest\ninverse-rank normalized number", + ggtheme = theme_minimal()) + +p1 | p2 + +p1 <- ggpubr::gghistogram(AEDB, "smcmean0", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "% of smooth muscle cells (SMA)", + xlab = "% per region of interest", + ggtheme = theme_minimal()) + +p2 <- ggpubr::gghistogram(AEDB, "SMC_rankNorm", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "% of smooth muscle cells (SMA)", + xlab = "% per region of interest\ninverse-rank normalized number", + ggtheme = theme_minimal()) + +p1 | p2 + + +p1 <- ggpubr::gghistogram(AEDB, "neutrophils", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of neutrophils (CD66b)", + xlab = "counts per plaque", + ggtheme = theme_minimal()) + +p2 <- ggpubr::gghistogram(AEDB, "Neutrophils_rankNorm", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of neutrophils (CD66b)", + xlab = "counts per plaque\ninverse-rank normalized number", + ggtheme = theme_minimal()) + +p1 | p2 + + +p1 <- ggpubr::gghistogram(AEDB, "Mast_cells_plaque", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of mast cells", + xlab = "counts per plaque", + ggtheme = theme_minimal()) + +p2 <- ggpubr::gghistogram(AEDB, "MastCells_rankNorm", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of mast cells", + xlab = "counts per plaque\ninverse-rank normalized number", + ggtheme = theme_minimal()) + +p1 | p2 + + +p1 <- ggpubr::gghistogram(AEDB, "vessel_density_averaged", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of intraplaque neovessels", + xlab = "counts per 3-4 hotspots", + ggtheme = theme_minimal()) + +p2 <- ggpubr::gghistogram(AEDB, "VesselDensity_rankNorm", + # y = "..count..", + color = "white", + fill = "Gender", + palette = c("#1290D9", "#DB003F"), + add = "median", + #add_density = TRUE, + rug = TRUE, + #add.params = list(color = "black", linetype = 2), + title = "number of intraplaque neovessels", + xlab = "counts per 3-4 hotspots\ninverse-rank normalized number", + ggtheme = theme_minimal()) + +p1 | p2 + +rm(p1, p2) +``` + +Here we calculate the *plaque instability/vulnerability* index + +```{r Plaque Vulnerability} +# Plaque vulnerability +require(labelled) +AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin) +AEDB$SMC.bin <- to_factor(AEDB$SMC.bin) +AEDB$IPH.bin <- to_factor(AEDB$IPH.bin) +AEDB$Calc.bin <- to_factor(AEDB$Calc.bin) +AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin) +AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10) +AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40) + +table(AEDB$Macrophages.bin) +table(AEDB$Fat.bin_10) +table(AEDB$Collagen.bin) +table(AEDB$SMC.bin) +table(AEDB$IPH.bin) + +# SPSS code + +# +# *** syntax- Plaque vulnerability**. +# COMPUTE Macro_instab = -999. +# IF macrophages.bin=2 Macro_instab=1. +# IF macrophages.bin=1 Macro_instab=0. +# EXECUTE. +# +# COMPUTE Fat10_instab = -999. +# IF Fat.bin_10=2 Fat10_instab=1. +# IF Fat.bin_10=1 Fat10_instab=0. +# EXECUTE. +# +# COMPUTE coll_instab=-999. +# IF Collagen.bin=2 coll_instab=0. +# IF Collagen.bin=1 coll_instab=1. +# EXECUTE. +# +# +# COMPUTE SMC_instab=-999. +# IF SMC.bin=2 SMC_instab=0. +# IF SMC.bin=1 SMC_instab=1. +# EXECUTE. +# +# COMPUTE IPH_instab=-999. +# IF IPH.bin=0 IPH_instab=0. +# IF IPH.bin=1 IPH_instab=1. +# EXECUTE. +# +# COMPUTE Instability=Macro_instab + Fat10_instab + coll_instab + SMC_instab + IPH_instab. +# EXECUTE. + +# Fix plaquephenotypes +attach(AEDB) +# mac instability +AEDB[,"MAC_Instability"] <- NA +AEDB$MAC_Instability[Macrophages.bin == -999] <- NA +AEDB$MAC_Instability[Macrophages.bin == "no/minor"] <- 0 +AEDB$MAC_Instability[Macrophages.bin == "moderate/heavy"] <- 1 + +# fat instability +AEDB[,"FAT10_Instability"] <- NA +AEDB$FAT10_Instability[Fat.bin_10 == -999] <- NA +AEDB$FAT10_Instability[Fat.bin_10 == " <10%"] <- 0 +AEDB$FAT10_Instability[Fat.bin_10 == " >10%"] <- 1 + +# col instability +AEDB[,"COL_Instability"] <- NA +AEDB$COL_Instability[Collagen.bin == -999] <- NA +AEDB$COL_Instability[Collagen.bin == "no/minor"] <- 1 +AEDB$COL_Instability[Collagen.bin == "moderate/heavy"] <- 0 + +# smc instability +AEDB[,"SMC_Instability"] <- NA +AEDB$SMC_Instability[SMC.bin == -999] <- NA +AEDB$SMC_Instability[SMC.bin == "no/minor"] <- 1 +AEDB$SMC_Instability[SMC.bin == "moderate/heavy"] <- 0 + +# iph instability +AEDB[,"IPH_Instability"] <- NA +AEDB$IPH_Instability[IPH.bin == -999] <- NA +AEDB$IPH_Instability[IPH.bin == "no"] <- 0 +AEDB$IPH_Instability[IPH.bin == "yes"] <- 1 + +detach(AEDB) + +table(AEDB$MAC_Instability, useNA = "ifany") +table(AEDB$FAT10_Instability, useNA = "ifany") +table(AEDB$COL_Instability, useNA = "ifany") +table(AEDB$SMC_Instability, useNA = "ifany") +table(AEDB$IPH_Instability, useNA = "ifany") + +# creating vulnerability index +AEDB <- AEDB %>% mutate(Plaque_Vulnerability_Index = factor(rowSums(.[grep("_Instability", names(.))], na.rm = TRUE)), + ) + +table(AEDB$Plaque_Vulnerability_Index, useNA = "ifany") + +# str(AEDB$Plaque_Vulnerability_Index) + +``` + +## Prepare baseline summary + +We are interested in the following variables at baseline in the whole cohort. + +- Age (years) +- Female sex (N, %) +- Artery type (N, %) +- Hospital (N, %) + + + + + + + + + + + + + + + + + + + + + + + + + + + +```{r Baseline AEDB: preparation} +cat("====================================================================================================\n") +cat("SELECTION THE SHIZZLE\n") + +### Artery levels +# AEdata$Artery_summary: +# value label +# NOT USE - 0 No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA +# USE - 1 carotid (left & right) +# USE - 2 femoral/iliac (left, right or both sides) +# NOT USE - 3 other carotid arteries (common, external) +# NOT USE - 4 carotid bypass and injury (left, right or both sides) +# NOT USE - 5 aneurysmata (carotid & femoral) +# NOT USE - 6 aorta +# NOT USE - 7 other arteries (renal, popliteal, vertebral) +# NOT USE - 8 femoral bypass, angioseal and injury (left, right or both sides) + +### AEdata$informedconsent +# value label +# NOT USE - -999 missing +# NOT USE - 0 no, died +# USE - 1 yes +# USE - 2 yes, health treatment when possible +# USE - 3 yes, no health treatment +# USE - 4 yes, no health treatment, no commercial business +# NOT USE - 5 yes, no tissue, no commerical business +# NOT USE - 6 yes, no tissue, no questionnaires, no medical info, no commercial business +# USE - 7 yes, no questionnaires, no health treatment, no commercial business +# USE - 8 yes, no questionnaires, health treatment when possible +# NOT USE - 9 yes, no tissue, no questionnaires, no health treatment, no commerical business +# USE - 10 yes, no health treatment, no medical info, no commercial business +# NOT USE - 11 yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business +# USE - 12 yes, no questionnaires, no health treatment +# NOT USE - 13 yes, no tissue, no health treatment +# NOT USE - 14 yes, no tissue, no questionnaires +# NOT USE - 15 yes, no tissue, health treatment when possible +# NOT USE - 16 yes, no tissue +# USE - 17 yes, no commerical business +# USE - 18 yes, health treatment when possible, no commercial business +# USE - 19 yes, no medical info, no commercial business +# USE - 20 yes, no questionnaires +# NOT USE - 21 yes, no tissue, no questionnaires, no health treatment, no medical info +# NOT USE - 22 yes, no tissue, no questionnaires, no health treatment, no commercial business +# USE - 23 yes, no medical info +# USE - 24 yes, no questionnaires, no commercial business +# USE - 25 yes, no questionnaires, no health treatment, no medical info +# USE - 26 yes, no questionnaires, health treatment when possible, no commercial business +# USE - 27 yes, no health treatment, no medical info +# NOT USE - 28 no, doesn't want to +# NOT USE - 29 no, unable to sign +# NOT USE - 30 no, no reaction +# NOT USE - 31 no, lost +# NOT USE - 32 no, too old +# NOT USE - 34 yes, no medical info, health treatment when possible +# NOT USE - 35 no (never asked for IC because there was no tissue) +# USE - 36 yes, no medical info, no commercial business, health treatment when possible +# NOT USE - 37 no, endpoint +# USE - 38 wil niets invullen, wel alles gebruiken +# USE - 39 second informed concents: yes, no commercial business +# NOT USE - 40 nooit geincludeerd + +cat("- sanity checking PRIOR to selection") +library(data.table) +require(labelled) +ae.gender <- to_factor(AEDB$Gender) +ae.hospital <- to_factor(AEDB$Hospital) +table(ae.gender, ae.hospital, dnn = c("Sex", "Hospital")) +ae.artery <- to_factor(AEDB$Artery_summary) +table(ae.artery, ae.gender, dnn = c("Sex", "Artery")) + +rm(ae.gender, ae.hospital, ae.artery) + +# I change numeric and factors manually because, well, I wouldn't know how to fix it otherwise +# to have this 'tibble' work with 'tableone'... :-) + +AEDB$Age <- as.numeric(AEDB$Age) +AEDB$diastoli <- as.numeric(AEDB$diastoli) +AEDB$systolic <- as.numeric(AEDB$systolic) + +AEDB$TC_finalCU <- as.numeric(AEDB$TC_finalCU) +AEDB$LDL_finalCU <- as.numeric(AEDB$LDL_finalCU) +AEDB$HDL_finalCU <- as.numeric(AEDB$HDL_finalCU) +AEDB$TG_finalCU <- as.numeric(AEDB$TG_finalCU) + +AEDB$TC_final <- as.numeric(AEDB$TC_final) +AEDB$LDL_final <- as.numeric(AEDB$LDL_final) +AEDB$HDL_final <- as.numeric(AEDB$HDL_final) +AEDB$TG_final <- as.numeric(AEDB$TG_final) + +AEDB$Age <- as.numeric(AEDB$Age) +AEDB$GFR_MDRD <- as.numeric(AEDB$GFR_MDRD) +AEDB$BMI <- as.numeric(AEDB$BMI) +AEDB$eCigarettes <- as.numeric(AEDB$eCigarettes) +AEDB$ePackYearsSmoking <- as.numeric(AEDB$ePackYearsSmoking) +AEDB$EP_composite_time <- as.numeric(AEDB$EP_composite_time) +AEDB$EP_major_time <- as.numeric(AEDB$EP_major_time) + +require(labelled) +AEDB$Artery_summary <- to_factor(AEDB$Artery_summary) +AEDB$ORyear <- to_factor(AEDB$ORyear) +AEDB$Gender <- to_factor(AEDB$Gender) +AEDB$Hospital <- to_factor(AEDB$Hospital) +AEDB$KDOQI <- to_factor(AEDB$KDOQI) +AEDB$BMI_WHO <- to_factor(AEDB$BMI_WHO) +AEDB$DiabetesStatus <- to_factor(AEDB$DiabetesStatus) +AEDB$SmokerStatus <- to_factor(AEDB$SmokerStatus) +AEDB$AlcoholUse <- to_factor(AEDB$AlcoholUse) + +AEDB$Hypertension.selfreport <- to_factor(AEDB$Hypertension1) +AEDB$Hypertension.selfreportdrug <- to_factor(AEDB$Hypertension2) +AEDB$Hypertension.composite <- to_factor(AEDB$Hypertension.composite) +AEDB$Hypertension.drugs <- to_factor(AEDB$Hypertension.drugs) + +AEDB$Med.anticoagulants <- to_factor(AEDB$Med.anticoagulants) +AEDB$Med.all.antiplatelet <- to_factor(AEDB$Med.all.antiplatelet) +AEDB$Med.Statin.LLD <- to_factor(AEDB$Med.Statin.LLD) + +AEDB$Stroke_Dx <- to_factor(AEDB$Stroke_Dx) +AEDB$CAD_history <- to_factor(AEDB$CAD_history) +AEDB$PAOD <- to_factor(AEDB$PAOD) +AEDB$Peripheral.interv <- to_factor(AEDB$Peripheral.interv) + +AEDB$sympt <- to_factor(AEDB$sympt) +AEDB$Symptoms.3g <- to_factor(AEDB$Symptoms.3g) +AEDB$Symptoms.4g <- to_factor(AEDB$Symptoms.4g) +AEDB$Symptoms.5G <- to_factor(AEDB$Symptoms.5G) +AEDB$AsymptSympt <- to_factor(AEDB$AsymptSympt) +AEDB$AsymptSympt2G <- to_factor(AEDB$AsymptSympt2G) +AEDB$Symptoms.Update2G <- to_factor(AEDB$Symptoms.Update2G) +AEDB$Symptoms.Update3G <- to_factor(AEDB$Symptoms.Update3G) + +AEDB$restenos <- to_factor(AEDB$restenos) +AEDB$stenose <- to_factor(AEDB$stenose) +AEDB$EP_composite <- to_factor(AEDB$EP_composite) +AEDB$EP_major <- to_factor(AEDB$EP_major) +AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin) +AEDB$SMC.bin <- to_factor(AEDB$SMC.bin) +AEDB$IPH.bin <- to_factor(AEDB$IPH.bin) +AEDB$Calc.bin <- to_factor(AEDB$Calc.bin) +AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin) +AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10) +AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40) +AEDB$OverallPlaquePhenotype <- to_factor(AEDB$OverallPlaquePhenotype) +AEDB$Plaque_Vulnerability_Index <- to_factor(AEDB$Plaque_Vulnerability_Index) + +AEDB$Artery_summary <- to_factor(AEDB$Artery_summary) + +AEDB$informedconsent <- to_factor(AEDB$informedconsent) + +AEDB.full <- subset(AEDB, + informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'! + informedconsent != "no, died" & + informedconsent != "yes, no tissue, no commerical business" & + informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" & + informedconsent != "yes, no tissue, no health treatment" & + informedconsent != "yes, no tissue, no questionnaires" & + informedconsent != "yes, no tissue, health treatment when possible" & + informedconsent != "yes, no tissue" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" & + informedconsent != "no, doesn't want to" & + informedconsent != "no, unable to sign" & + informedconsent != "no, no reaction" & + informedconsent != "no, lost" & + informedconsent != "no, too old" & + informedconsent != "yes, no medical info, health treatment when possible" & + informedconsent != "no (never asked for IC because there was no tissue)" & + informedconsent != "no, endpoint" & + informedconsent != "nooit geincludeerd") +# AEDB.CEA[1:10, 1:10] +dim(AEDB.full) + +``` + +```{r Baseline AEDB: creation} +cat("===========================================================================================\n") +cat("CREATE BASELINE TABLE\n") + +# Baseline table variables +basetable_vars = c("Hospital", + "Artery_summary", + "Age", "Gender") + # "ORyear", + # "TC_finalCU", "LDL_finalCU", "HDL_finalCU", "TG_finalCU", + # "TC_final", "LDL_final", "HDL_final", "TG_final", + # "hsCRP_plasma", + # "systolic", "diastoli", "GFR_MDRD", "BMI", + # "KDOQI", "BMI_WHO", + # "SmokerStatus", "AlcoholUse", + # "DiabetesStatus", + # "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", + # "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", + # "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G", + # "Symptoms.Update2G", + # "Symptoms.Update3G", + # "restenos", "stenose", + # "CAD_history", "PAOD", "Peripheral.interv", + # "EP_composite", "EP_composite_time", "EP_major", "EP_major_time", + # "MAC_rankNorm", "SMC_rankNorm", "Macrophages.bin", "SMC.bin", + # "Neutrophils_rankNorm", "MastCells_rankNorm", + # "IPH.bin", "VesselDensity_rankNorm", + # "Calc.bin", "Collagen.bin", + # "Fat.bin_10", "Fat.bin_40", + # "OverallPlaquePhenotype", "Plaque_Vulnerability_Index") + +basetable_bin = c("Hospital", + "Artery_summary", + "Gender") +# basetable_bin + +basetable_con = basetable_vars[!basetable_vars %in% basetable_bin] +# basetable_con +``` + +# Athero-Express Biobank Study Baseline Characteristics + +Showing the baseline table of the whole Athero-Express Biobank. + +```{r Baseline AEDB: Visualize AEDB} +# Create baseline tables +# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html +AEDB.tableOne = print(CreateTableOne(vars = basetable_vars, + factorVars = basetable_bin, + # strata = "Symptoms.4g", + data = AEDB.full, includeNA = TRUE), + nonnormal = c(), missing = TRUE, + quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, + format = "pf", + contDigits = 3)[,1:3] +``` + + +## Match samples used + +Here we match the full database with the samples used in **`EntropyMasker`**. + +```{r} +# Remove duplicate rows of the dataframe +library(dplyr) +temp <- EM_samples %>% select(., "Studynumber") %>% + distinct(.) + +AEDB_EM <- merge(temp, + AEDB, + by.x = "Studynumber", + by.y = "STUDY_NUMBER", + sort = FALSE) + +AEDB_EM.full <- subset(AEDB_EM, + informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'! + informedconsent != "no, died" & + informedconsent != "yes, no tissue, no commerical business" & + informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" & + informedconsent != "yes, no tissue, no health treatment" & + informedconsent != "yes, no tissue, no questionnaires" & + informedconsent != "yes, no tissue, health treatment when possible" & + informedconsent != "yes, no tissue" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" & + informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" & + informedconsent != "no, doesn't want to" & + informedconsent != "no, unable to sign" & + informedconsent != "no, no reaction" & + informedconsent != "no, lost" & + informedconsent != "no, too old" & + informedconsent != "yes, no medical info, health treatment when possible" & + informedconsent != "no (never asked for IC because there was no tissue)" & + informedconsent != "no, endpoint" & + informedconsent != "nooit geincludeerd") +# AEDB_EM.full[1:10, 1:10] + +rm(temp) +``` + + + +```{r Baseline AEDB: Visualize AEDB EM FULL} +# Create baseline tables +# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html +AEDB_EM.full.tableOne = print(CreateTableOne(vars = basetable_vars, + factorVars = basetable_bin, + # strata = "Symptoms.4g", + data = AEDB_EM.full, includeNA = TRUE), + nonnormal = c(), missing = TRUE, + quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, + format = "pf", + contDigits = 3)[,1:3] +``` + +```{r Baseline AEDB: Visualize AEDB EM} + +basetable_vars = c("Hospital", + "Artery_summary") + +basetable_bin = c("Hospital", + "Artery_summary") + +# Create baseline tables +# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html +AEDB_EM.tableOne = print(CreateTableOne(vars = basetable_vars, + factorVars = basetable_bin, + # strata = "Symptoms.4g", + data = AEDB_EM, includeNA = TRUE), + nonnormal = c(), missing = TRUE, + quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, + format = "pf", + contDigits = 3)[,1:3] +``` + +## Baseline writing + +Let's save the baseline characteristics of the Athero-Express Biobank Study. + +```{r Baseline SampleSelection: write} +# Write basetable + +require(openxlsx) + +write.xlsx(as.data.frame(AEDB.tableOne), + file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.BaselineTable.xlsx"), + rowNames = TRUE, + colNames = TRUE, + sheetName = "AE_Base", overwrite = TRUE) + +write.xlsx(as.data.frame(AEDB_EM.tableOne), + file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.EM.59.BaselineTable.xlsx"), + rowNames = TRUE, + colNames = TRUE, + sheetName = "AE_Base_EM_59", overwrite = TRUE) + +write.xlsx(as.data.frame(AEDB_EM.full.tableOne), + file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.EM.56.BaselineTable.xlsx"), + rowNames = TRUE, + colNames = TRUE, + sheetName = "AE_Base_EM_56", overwrite = TRUE) + +``` + +We will also write the newly prepared AEDB selected for this study which we can use in downstream analyses. + +```{r} +saveRDS(AEDB_EM.full, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.EM.FULL.RDS")) +saveRDS(AEDB.full, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.FULL.RDS")) +saveRDS(AEDB, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.raw.RDS")) + +``` + + +# Session information + +------------------------------------------------------------------------------------------------------------------------ + + Version: v1.0.2 + Last update: 2022-07-12 + Written by: Sander W. van der Laan (s.w.vanderlaan-2[at]umcutrecht.nl). + Description: Script to get some Athero-Express Biobank Study baseline characteristics. + Minimum requirements: R version 3.4.3 (2017-06-30) -- 'Single Candle', Mac OS X El Capitan + + **MoSCoW To-Do List** + The things we Must, Should, Could, and Would have given the time we have. + _M_ + + _S_ + + _C_ + + _W_ + + **Changes log** + * v1.0.2 Simplified the initial script. It now outputs the relevant R-objects (as .RDS). + * v1.0.1 Update to main AEDB (there is an error in the Age-variable in the new version). + * v1.0.0 Initial version. Add 'plaque vulnerability index', Fixed baseline table, added codes, and results. Major update to WORCS system. + +------------------------------------------------------------------------------------------------------------------------ + +```{r eval = TRUE} +sessionInfo() +``` + +# Saving environment + +```{r Saving} +save.image(paste0(PROJECT_loc, "/",Today,".",PROJECTNAME,".AEDB.EM.baseline.RData")) +``` + ++-----------------------------------------------------------------------------------------------------------------------------------------+ +| © 1979-2022 Sander W. van der Laan | s.w.vanderlaan[at]gmail.com | [swvanderlaan.github.io](https://swvanderlaan.github.io). | ++-----------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/AEDB.EM.baseline.nb.html b/AEDB.EM.baseline.nb.html new file mode 100644 index 0000000..6645fca --- /dev/null +++ b/AEDB.EM.baseline.nb.html @@ -0,0 +1,4972 @@ + + + + + + + + + + + + + + + +Baseline characteristics + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+ + + + + + + + +
+

General Setup

+

We will clean the environment, setup the locations, define colors, +and create a datestamp.

+

Clean the environment.

+ + + + +

Set locations and working directories…

+ + + +

+Create a new analysis directories.
+
+- general directory
+
+- for plots
+
+- for output of summary results
+
+- for baseline tables
+ + + +

… a package-installation function …

+ + + +
source("scripts/functions.R")
+ + + +

… and load those packages.

+ + + +
source("scripts/pack01.packages.R")
+ + +

+* General packages...
+ + + +

We will create a datestamp and define the Utrecht Science Park +Colour Scheme.

+ + + +

+Today = format(as.Date(as.POSIXlt(Sys.time())), "%Y%m%d")
+Today.Report = format(as.Date(as.POSIXlt(Sys.time())), "%A, %B %d, %Y")
+
+source("scripts/colors.R")
+ + + + + +
+
+

This notebook

+

In this notebook we create a baseline table of the samples used in +EntropyMasker.

+
+
+

Athero-Express Biobank Study

+

The Athero-Express +Biobank Study (AE) contains plaque material of patients that +underwent endarterectomyat two Dutch tertiary referral centers. Details +of the study design were described before. Briefly, blood and plaque +material were obtained during endarterectomy and stored at -80 ℃. All +patients provided informed consent and the study was approved by the +medical ethics committee.

+
+

Load relevant samples

+ + + +
EM_samples <- fread(paste0(ANALYSIS_loc, "/dataverse/EntropyMasker_image_files_used.txt"))
+ + + +
+
+

Load data

+

Loading Athero-Express Biobank Study clinical and biobank data.

+ + + +
cat("* get Athero-Express Biobank Study Database...")
+ + +
* get Athero-Express Biobank Study Database...
+ + +
# METHOD 1: It seems this method gives loads of errors and warnings, which all are hard to comprehend
+#           or debug. We expect 3,527 samples, and 927 variables; we get 927 variables!!!
+# AEdata = as.data.table(read.spss(paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.sav"),
+#                                  trim.factor.names = TRUE, trim_values = TRUE, # we trim spaces in values
+#                                  reencode = TRUE, # we re-encode to the local locale encoding
+#                                  add.undeclared.levels = "append", # we do *not* want to convert to R-factors
+#                                  use.value.labels = FALSE, # we do *not* convert variables with value labels into R factors
+#                                  use.missings = TRUE, sub = "NA", # we will set every missing variable to NA
+#                                  duplicated.value.labels = "condense", # we will condense duplicated value labels
+#                                  to.data.frame = TRUE))
+# AEdata.labels <- as.data.table(attr(AEdata, "variable.labels"))
+# names(AEdata.labels) <- "Variable"
+
+# METHOD 2: Using library("haven") importing seems flawless; best argument being:
+#           we expect 3,527 samples and 888 variables, which is what you'd get with this method
+#           So for now, METHOD 2 is prefered. 
+#            
+require(haven)
+
+# AEDB <- haven::read_sav(paste0(AEDB_loc, "/2022_1_NEW_AtheroExpressDatabase_ScientificAE_15-02-2022.sav")) # something wrong with Age-variable
+# AEDB <- haven::read_sav(paste0(AEDB_loc, "/2020_1_NEW_AtheroExpressDatabase_ScientificAE_30-09-2020.sav")) # duplicate studynumbers in it
+AEDB <- haven::read_sav(paste0(AEDB_loc, "/2020_1_NEW_AtheroExpressDatabase_ScientificAE_16-03-2020.sav"))
+
+# writing off the SPSS data to an Excel.
+# fwrite(AEdata, file = paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.values.xlsx"), 
+#        sep = ";", na = "NA", dec = ".", col.names = TRUE, row.names = FALSE,
+#        dateTimeAs = "ISO", showProgress = TRUE, verbose = TRUE)
+# warnings()
+
+AEDB[1:10, 1:10]
+ + +
+ +
+ + +
dim(AEDB)
+ + +
[1] 3791 1091
+ + + + + + + + + + + + + + + + + + +
+
+

Fixing and creating variables

+

We have to fix certain clinical parameters:

+
    +
  • symptoms
  • +
  • diabetes
  • +
  • alcohol use
  • +
  • smoking
  • +
  • plaque phenotypes
  • +
+
+

Symptoms

+

We need to be very strict in defining symptoms. Therefore we +will fix a new variable that groups symptoms at inclusion.

+

Coding of symptoms is as follows:

+
    +
  • missing -999
  • +
  • Asymptomatic 0
  • +
  • TIA 1
  • +
  • minor stroke 2
  • +
  • Major stroke 3
  • +
  • Amaurosis fugax 4
  • +
  • Four vessel disease 5
  • +
  • Vertebrobasilary TIA 7
  • +
  • Retinal infarction 8
  • +
  • Symptomatic, but aspecific symtoms 9
  • +
  • Contralateral symptomatic occlusion 10
  • +
  • retinal infarction 11
  • +
  • armclaudication due to occlusion subclavian artery, CEA needed for +bypass 12
  • +
  • retinal infarction + TIAs 13
  • +
  • Ocular ischemic syndrome 14
  • +
  • ischemisch glaucoom 15
  • +
  • subclavian steal syndrome 16
  • +
  • TGA 17
  • +
+

We will group as follows:

+
    +
  1. Asymptomatic > 0
  2. +
  3. TIA > 1, 7, 13
  4. +
  5. Stroke > 2, 3
  6. +
  7. Ocular > 4, 14, 15
  8. +
  9. Retinal infarction > 8, 11
  10. +
  11. Other > 5, 9, 10, 12, 16, 17
  12. +
+ + + +

+# Fix symptoms
+
+attach(AEDB)
+AEDB[,"Symptoms.5G"] <- NA
+AEDB$Symptoms.5G[sympt == 0] <- "Asymptomatic"
+AEDB$Symptoms.5G[sympt == 1 | sympt == 7 | sympt == 13] <- "TIA"
+AEDB$Symptoms.5G[sympt == 2 | sympt == 3] <- "Stroke"
+AEDB$Symptoms.5G[sympt == 4 | sympt == 14 | sympt == 15 ] <- "Ocular"
+AEDB$Symptoms.5G[sympt == 8 | sympt == 11] <- "Retinal infarction"
+AEDB$Symptoms.5G[sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Other"
+
+
+# AsymptSympt
+AEDB[,"AsymptSympt"] <- NA
+AEDB$AsymptSympt[sympt == -999] <- NA
+AEDB$AsymptSympt[sympt == 0] <- "Asymptomatic"
+AEDB$AsymptSympt[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3] <- "Symptomatic"
+AEDB$AsymptSympt[sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Ocular and others"
+
+# AsymptSympt
+AEDB[,"AsymptSympt2G"] <- NA
+AEDB$AsymptSympt2G[sympt == -999] <- NA
+AEDB$AsymptSympt2G[sympt == 0] <- "Asymptomatic"
+AEDB$AsymptSympt2G[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3 | sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Symptomatic"
+
+detach(AEDB)
+
+# table(AEDB$sympt, useNA = "ifany")
+# table(AEDB$AsymptSympt2G, useNA = "ifany")
+# table(AEDB$Symptoms.5G, useNA = "ifany")
+# 
+# table(AEDB$AsymptSympt2G, AEDB$sympt, useNA = "ifany")
+# table(AEDB$Symptoms.5G, AEDB$sympt, useNA = "ifany")
+table(AEDB$AsymptSympt2G, AEDB$Symptoms.5G, useNA = "ifany")
+ + +
              
+               Asymptomatic Ocular Other Retinal infarction Stroke  TIA <NA>
+  Asymptomatic          333      0     0                  0      0    0    0
+  Symptomatic             0    416   119                 43    732 1045    0
+  <NA>                    0      0     0                  0      0    0 1103
+ + +
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "sympt", "Symptoms.5G", "AsymptSympt"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# table(AEDB.temp$Symptoms.5G, AEDB.temp$AsymptSympt)
+# 
+# rm(AEDB.temp)
+ + + +
+
+

Re-assessed symptoms

+

We re-assessed the categorization of symptoms. These are summarized +and parsed in this section.

+

Labeling of new symptom categories.

+ + + +

+AEDB$indexsymptoms_worst
+ + +
<labelled<double>[3791]>: Latest cerebrovascular symptoms (indication CEA).
+   [1]  2  3  2  0  0  2  0  3 NA  0  0  0  2  1  0  0  0  0 NA  0  1  0  0  0  0  2  0  0 NA  0  0 NA  1  0  9  2  0  9  0  1  0  9  0  0  3  2  0 NA
+  [49]  0  0  1  9  2  9  1  0  0  2  2  2  0  9  2  0  0  0  2 NA  0  0  0  0  0  0  2  0  0  2  3  0  1  3  0 NA  0  0  9  2  3  3 NA  2  0  0  3 NA
+  [97] NA  3  1  0  9  1  2  0  0  0  2  0  0 NA NA  0  0  9 NA  2  2  1  1  2  0  0  9  2  0  3 NA  0 NA  2  0  0  0 NA  9  2  2 NA  0  3  2  0  2  0
+ [145]  1  1  0  0  0 NA NA  2 NA NA  3  0  9  0  0 NA  0  9  1  3  2  2  1  0  2 NA  0  1  0 NA  2  2  1  1 NA  0 NA  3  0  3 NA NA  0 NA NA NA NA  2
+ [193]  0  2  0  0  0  3 NA  2  0  0  0  0  0  0 NA  0 NA  3 NA  2  0 NA  2  0  3 NA NA  3 NA NA NA NA NA NA  0 NA  3  9 NA  0 NA  0 NA NA  1  0  2  3
+ [241] NA NA NA  0 NA NA  1 NA  2 NA NA NA NA  0  1  2  0 NA  0 NA  3  0  3  0  0 NA NA  2  3 NA NA NA NA  1 NA  2  2  3  0  0  0 NA NA  0  0  3  1  1
+ [289]  0  9  2  0  2  2 NA NA  1 NA NA NA  0  0 NA NA  3 NA  0 NA NA  1 NA  9 NA  0  3 NA NA NA NA NA  0 NA  1 NA  0  3  2 NA NA  2  1 NA NA NA NA  2
+ [337]  0  0  0  2 NA  1  1 NA  0  0 NA NA  1  3 NA  0 NA  2  1 NA NA  9 NA NA NA NA NA NA  9  0 NA  2  0 NA NA NA NA NA  2 NA NA NA  2  0  1  2  9  9
+ [385]  0 NA  3  0 NA  2 NA  3  9  9  2  0 NA NA  1  2 NA NA  0  3 NA NA NA NA NA NA  2  0 NA NA NA NA NA NA  9  0 NA NA NA NA NA NA  3 NA  0  2  9 NA
+ [433]  0  1 NA  0  2  1 NA NA  1  0  2  0 NA  0  3  3  1  0  3 NA  3  0 NA  2 NA  1  2  0 NA  0 NA NA NA NA  0  9  2  0 NA NA NA NA NA NA  0 NA NA  0
+ [481]  0  2 NA NA  0 NA  1 NA  2  3  0  2  2  0  0  1  2  3  9 NA  9 NA  2  2  1  2  2  1  2  0  1  3 NA NA NA NA NA NA NA  9 NA NA NA NA NA  1  0  0
+ [529] NA  3 NA  2  2  9  3 NA NA  2  2 NA  2  2 NA  2 NA NA  0 NA NA  1  0 NA NA  1  2  2 NA NA NA NA NA  0  2  0 NA  0  0  0  0  0  0 NA NA NA NA NA
+ [577] NA NA  2 NA NA NA NA  2 NA  0  3  0  0 NA NA NA NA  0 NA NA  0  3 NA NA NA  0 NA NA NA  9 NA NA NA NA NA NA NA  2  2 NA  2 NA NA NA  0 NA NA  1
+ [625]  1  9  0  2 NA NA NA NA  1 NA NA NA  2 NA  0  0 NA  0  9  2 NA  0  1 NA  0  1 NA  0  0  2 NA  1  9 NA  0  3  3  1  3 NA  2 NA NA  2 NA  0  9  0
+ [673]  1  1 NA  2  0 NA  2  1 NA NA NA NA  3  3 NA NA  3  0 NA  9 NA  3 NA NA  9  2  0  3  2  0  0 NA  0  2  2 NA NA  2  0 NA NA  2 NA  1 NA NA NA NA
+ [721] NA NA  2  2 NA  0 NA  2  0  2  2  2  2  1  0 NA NA NA NA  1 NA  2  0  0 NA NA NA  2  1  1 NA  2  0  1  0 NA  1  2  1  1  9  0 NA NA  0  1 NA NA
+ [769]  1  0  2 NA NA NA NA NA NA NA NA NA  0 NA NA NA  0 NA  1  1  2  1 NA NA NA NA NA NA NA  2 NA  0 NA NA  0 NA NA  0 NA NA NA NA  0 NA  0 NA NA  0
+ [817] NA NA  2  0 NA NA NA NA NA NA NA NA NA NA  1 NA NA NA NA NA  2 NA  1  0 NA  2  2  1  2 NA NA NA NA  0  9 NA NA  2  0 NA NA  3  0  2  2  0  1  0
+ [865]  0 NA  1  9  0  0  0  0  2  0  1  0  1  0 NA  0 NA NA  9 NA NA NA NA NA NA NA NA NA NA  0 NA  3  0 NA NA  2  9 NA NA NA  3 NA  1 NA NA  1  2  0
+ [913] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0  1 NA NA NA NA NA NA  0 NA NA NA NA  2  1 NA NA  1 NA NA  1  0  1 NA  0  9 NA NA  1
+ [961] NA  2 NA NA  0 NA NA  3  0 NA NA  2  0 NA NA NA NA NA NA  3 NA  2 NA NA NA NA  1  2  1  0 NA  0 NA  0 NA NA NA NA NA  0
+ [ reached getOption("max.print") -- omitted 2791 entries ]
+
+Labels:
+ + +
+ +
+ + +
AEDB$indexsymptoms_worst_4g
+ + +
<labelled<double>[3791]>:  symptoms strokefenotype en symptoms.4g .
+   [1]  2  3  2  0  0  2  0  3 NA  0  0  0  2  1  0  0  0  0 NA  0  1  0  0  0  0  2  0  0 NA  0  0 NA  1  0  9  2  0  9  0  1  0  9  0  0  3  2  0 NA
+  [49]  0  0  1  9  2  9  1  0  0  2  2  2  0  9  2  0  0  0  2 NA  0  0  0  0  0  0  2  0  0  2  3  0  1  3  0 NA  0  0  9  2  3  3 NA  2  0  0  3 NA
+  [97] NA  3  1  0  9  1  2  0  0  0  2  0  0 NA NA  0  0  9 NA  2  2  1  1  2  0  0  9  2  0  3 NA  0 NA  2  0  0  0 NA  9  2  2 NA  0  3  2  0  2  0
+ [145]  1  1  0  0  0 NA NA  2 NA NA  3  0  9  0  0 NA  0  9  1  3  2  2  1  0  2 NA  0  1  0 NA  2  2  1  1 NA  0 NA  3  0  3 NA NA  0 NA NA NA NA  2
+ [193]  0  2  0  0  0  3 NA  2  0  0  0  0  0  0 NA  0 NA  3 NA  2  0 NA  2  0  3 NA NA  3 NA NA NA NA NA NA  0 NA  3  9 NA  0 NA  0 NA NA  1  0  2  3
+ [241] NA NA NA  0 NA NA  1 NA  2 NA NA NA NA  0  1  2  0 NA  0 NA  3  0  3  0  0 NA NA  2  3 NA NA NA NA  1 NA  2  2  3  0  0  0 NA NA  0  0  3  1  1
+ [289]  0  9  2  0  2  2 NA NA  1 NA NA NA  0  0 NA NA  3 NA  0 NA NA  1 NA  9 NA  0  3 NA NA NA NA NA  0 NA  1 NA  0  3  2 NA NA  2  1 NA NA NA NA  2
+ [337]  0  0  0  2 NA  1  1 NA  0  0 NA NA  1  3 NA  0 NA  2  1 NA NA  9 NA NA NA NA NA NA  9  0 NA  2  0 NA NA NA NA NA  2 NA NA NA  2  0  1  2  9  9
+ [385]  0 NA  3  0 NA  2 NA  3  9  9  2  0 NA NA  1  2 NA NA  0  3 NA NA NA NA NA NA  2  0 NA NA NA NA NA NA  9  0 NA NA NA NA NA NA  3 NA  0  2  9 NA
+ [433]  0  1 NA  0  2  1 NA NA  1  0  2  0 NA  0  3  3  1  0  3 NA  3  0 NA  2 NA  1  2  0 NA  0 NA NA NA NA  0  9  2  0 NA NA NA NA NA NA  0 NA NA  0
+ [481]  0  2 NA NA  0 NA  1 NA  2  3  0  2  2  0  0  1  2  3  9 NA  9 NA  2  2  1  2  2  1  2  0  1  3 NA NA NA NA NA NA NA  9 NA NA NA NA NA  1  0  0
+ [529] NA  3 NA  2  2  9  3 NA NA  2  2 NA  2  2 NA  2 NA NA  0 NA NA  1  0 NA NA  1  2  2 NA NA NA NA NA  0  2  0 NA  0  0  0  0  0  0 NA NA NA NA NA
+ [577] NA NA  2 NA NA NA NA  2 NA  0  3  0  0 NA NA NA NA  0 NA NA  0  3 NA NA NA  0 NA NA NA  9 NA NA NA NA NA NA NA  2  2 NA  2 NA NA NA  0 NA NA  1
+ [625]  1  9  0  2 NA NA NA NA  1 NA NA NA  2 NA  0  0 NA  0  9  2 NA  0  1 NA  0  1 NA  0  0  2 NA  1  9 NA  0  3  3  1  3 NA  2 NA NA  2 NA  0  9  0
+ [673]  1  1 NA  2  0 NA  2  1 NA NA NA NA  3  3 NA NA  3  0 NA  9 NA  3 NA NA  9  2  0  3  2  0  0 NA  0  2  2 NA NA  2  0 NA NA  2 NA  1 NA NA NA NA
+ [721] NA NA  2  2 NA  0 NA  2  0  2  2  2  2  1  0 NA NA NA NA  1 NA  2  0  0 NA NA NA  2  1  1 NA  2  0  1  0 NA  1  2  1  1  9  0 NA NA  0  1 NA NA
+ [769]  1  0  2 NA NA NA NA NA NA NA NA NA  0 NA NA NA  0 NA  1  1  2  1 NA NA NA NA NA NA NA  2 NA  0 NA NA  0 NA NA  0 NA NA NA NA  0 NA  0 NA NA  0
+ [817] NA NA  2  0 NA NA NA NA NA NA NA NA NA NA  1 NA NA NA NA NA  2 NA  1  0 NA  2  2  1  2 NA NA NA NA  0  9 NA NA  2  0 NA NA  3  0  2  2  0  1  0
+ [865]  0 NA  1  9  0  0  0  0  2  0  1  0  1  0 NA  0 NA NA  9 NA NA NA NA NA NA NA NA NA NA  0 NA  3  0 NA NA  2  9 NA NA NA  3 NA  1 NA NA  1  2  0
+ [913] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0  1 NA NA NA NA NA NA  0 NA NA NA NA  2  1 NA NA  1 NA NA  1  0  1 NA  0  9 NA NA  1
+ [961] NA  2 NA NA  0 NA NA  3  0 NA NA  2  0 NA NA NA NA NA NA  3 NA  2 NA NA NA NA  1  2  1  0 NA  0 NA  0 NA NA NA NA NA  0
+ [ reached getOption("max.print") -- omitted 2791 entries ]
+
+Labels:
+ + +
+ +
+ + +
AEDB$indexsymptoms_latest
+ + +
<labelled<double>[3791]>: Latest cerebrovascular symptoms (indication CEA).
+   [1]  2  3  2  0  0  2  0  3 NA  0  0  0  2  1  0  0  0  0 NA  0  1  0  0  0  0  2  0  0 NA  0  0 NA  1  0  9  2  0  9  0  1  0  9  0  0  3  2  0 NA
+  [49]  0  0  1  9  2  9  1  0  0  2  2  9  0  9  2  0  0  0  2 NA  0  0  0  0  0  0  2  0  0  2  3  0  1  3  0 NA  0  0  9  2  3  3 NA  2  0  0  3 NA
+  [97] NA  3  1  0  9  1  2  0  0  0  2  0  0 NA NA  0  0  9 NA  2  2  1  1  2  0  0  9  2  0  3 NA  0 NA  2  0  0  0 NA  9  2  2 NA  0  3  2  0  2  0
+ [145]  1  1  0  0  0 NA NA  2 NA NA  3  0  9  0  0 NA  0  9  1  3  2  2  1  0  2 NA  0  1  0 NA  2  2  1  1 NA  0 NA  3  0  3 NA NA  0 NA NA NA NA  2
+ [193]  0  2  0  0  0  3 NA  2  0  0  0  0  0  0 NA  0 NA  3 NA  2  0 NA  2  0  3 NA NA  3 NA NA NA NA NA NA  0 NA  3  9 NA  0 NA  0 NA NA  1  0  2  3
+ [241] NA NA NA  0 NA NA  1 NA  2 NA NA NA NA  0  1  2  0 NA  0 NA  3  0  3  0  0 NA NA  2  3 NA NA NA NA  1 NA  2  2  3  0  0  0 NA NA  0  0  3  1  1
+ [289]  0  9  2  0  2  2 NA NA  1 NA NA NA  0  0 NA NA  3 NA  0 NA NA  1 NA  9 NA  0  3 NA NA NA NA NA  0 NA  1 NA  0  3  2 NA NA  2  1 NA NA NA NA  2
+ [337]  0  0  0  2 NA  1  1 NA  0  0 NA NA  1  3 NA  0 NA  2  1 NA NA  9 NA NA NA NA NA NA  9  0 NA  2  0 NA NA NA NA NA  2 NA NA NA  2  0  1  2  9  9
+ [385]  0 NA  3  0 NA  2 NA  3  9  9  2  0 NA NA  1  2 NA NA  0  3 NA NA NA NA NA NA  2  0 NA NA NA NA NA NA  9  0 NA NA NA NA NA NA  3 NA  0  2  9 NA
+ [433]  0  1 NA  0  2  1 NA NA  1  0  2  0 NA  0  3  3  1  0  3 NA  3  0 NA  2 NA  1  2  0 NA  0 NA NA NA NA  0  9  2  0 NA NA NA NA NA NA  0 NA NA  0
+ [481]  0  2 NA NA  0 NA  1 NA  2  3  0  2  2  0  0  1  2  3  9 NA  9 NA  2  2  1  2  2  1  2  0  1  3 NA NA NA NA NA NA NA  9 NA NA NA NA NA  1  0  0
+ [529] NA  3 NA  2  2  9  3 NA NA  2  2 NA  2  2 NA  2 NA NA  0 NA NA  1  0 NA NA  1  2  2 NA NA NA NA NA  0  2  0 NA  0  0  0  0  0  0 NA NA NA NA NA
+ [577] NA NA  2 NA NA NA NA  2 NA  0  3  0  0 NA NA NA NA  0 NA NA  0  3 NA NA NA  0 NA NA NA  9 NA NA NA NA NA NA NA  2  2 NA  2 NA NA NA  0 NA NA  1
+ [625]  1  9  0  2 NA NA NA NA  1 NA NA NA  2 NA  0  0 NA  0  9  2 NA  0  1 NA  0  1 NA  0  0  2 NA  1  9 NA  0  3  3  1  3 NA  2 NA NA  2 NA  0  9  0
+ [673]  1  1 NA  2  0 NA  2  1 NA NA NA NA  3  3 NA NA  3  0 NA  9 NA  3 NA NA  9  2  0  3  2  0  0 NA  0  2  2 NA NA  2  0 NA NA  2 NA  1 NA NA NA NA
+ [721] NA NA  2  2 NA  0 NA  2  0  2  2  2  2  1  0 NA NA NA NA  1 NA  2  0  0 NA NA NA  2  1  1 NA  2  0  1  0 NA  1  2  1  1  9  0 NA NA  0  1 NA NA
+ [769]  1  0  2 NA NA NA NA NA NA NA NA NA  0 NA NA NA  0 NA  1  1  2  1 NA NA NA NA NA NA NA  2 NA  0 NA NA  0 NA NA  0 NA NA NA NA  0 NA  0 NA NA  0
+ [817] NA NA  2  0 NA NA NA NA NA NA NA NA NA NA  1 NA NA NA NA NA  2 NA  1  0 NA  2  2  1  2 NA NA NA NA  0  9 NA NA  2  0 NA NA  3  0  2  2  0  1  0
+ [865]  0 NA  1  9  0  0  0  0  2  0  1  0  1  0 NA  0 NA NA  9 NA NA NA NA NA NA NA NA NA NA  0 NA  3  0 NA NA  2  9 NA NA NA  3 NA  1 NA NA  1  2  0
+ [913] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0  1 NA NA NA NA NA NA  0 NA NA NA NA  2  1 NA NA  1 NA NA  1  0  1 NA  0  9 NA NA  1
+ [961] NA  2 NA NA  0 NA NA  3  0 NA NA  2  0 NA NA NA NA NA NA  3 NA  2 NA NA NA NA  1  2  1  0 NA  0 NA  0 NA NA NA NA NA  0
+ [ reached getOption("max.print") -- omitted 2791 entries ]
+
+Labels:
+ + +
+ +
+ + +
AEDB$indexsymptoms_latest_4g
+ + +
<labelled<double>[3791]>:  symptoms strokefenotype en symptoms.4g .
+   [1]  2  3  2  0  0  2  0  3 NA  0  0  0  2  1  0  0  0  0 NA  0  1  0  0  0  0  2  0  0 NA  0  0 NA  1  0  9  2  0  9  0  1  0  9  0  0  3  2  0 NA
+  [49]  0  0  1  9  2  9  1  0  0  2  2  9  0  9  2  0  0  0  2 NA  0  0  0  0  0  0  2  0  0  2  3  0  1  3  0 NA  0  0  9  2  3  3 NA  2  0  0  3 NA
+  [97] NA  3  1  0  9  1  2  0  0  0  2  0  0 NA NA  0  0  9 NA  2  2  1  1  2  0  0  9  2  0  3 NA  0 NA  2  0  0  0 NA  9  2  2 NA  0  3  2  0  2  0
+ [145]  1  1  0  0  0 NA NA  2 NA NA  3  0  9  0  0 NA  0  9  1  3  2  2  1  0  2 NA  0  1  0 NA  2  2  1  1 NA  0 NA  3  0  3 NA NA  0 NA NA NA NA  2
+ [193]  0  2  0  0  0  3 NA  2  0  0  0  0  0  0 NA  0 NA  3 NA  2  0 NA  2  0  3 NA NA  3 NA NA NA NA NA NA  0 NA  3  9 NA  0 NA  0 NA NA  1  0  2  3
+ [241] NA NA NA  0 NA NA  1 NA  2 NA NA NA NA  0  1  2  0 NA  0 NA  3  0  3  0  0 NA NA  2  3 NA NA NA NA  1 NA  2  2  3  0  0  0 NA NA  0  0  3  1  1
+ [289]  0  9  2  0  2  2 NA NA  1 NA NA NA  0  0 NA NA  3 NA  0 NA NA  1 NA  9 NA  0  3 NA NA NA NA NA  0 NA  1 NA  0  3  2 NA NA  2  1 NA NA NA NA  2
+ [337]  0  0  0  2 NA  1  1 NA  0  0 NA NA  1  3 NA  0 NA  2  1 NA NA  9 NA NA NA NA NA NA  9  0 NA  2  0 NA NA NA NA NA  2 NA NA NA  2  0  1  2  9  9
+ [385]  0 NA  3  0 NA  2 NA  3  9  9  2  0 NA NA  1  2 NA NA  0  3 NA NA NA NA NA NA  2  0 NA NA NA NA NA NA  9  0 NA NA NA NA NA NA  3 NA  0  2  9 NA
+ [433]  0  1 NA  0  2  1 NA NA  1  0  2  0 NA  0  3  3  1  0  3 NA  3  0 NA  2 NA  1  2  0 NA  0 NA NA NA NA  0  9  2  0 NA NA NA NA NA NA  0 NA NA  0
+ [481]  0  2 NA NA  0 NA  1 NA  2  3  0  2  2  0  0  1  2  3  9 NA  9 NA  2  2  1  2  2  1  2  0  1  3 NA NA NA NA NA NA NA  9 NA NA NA NA NA  1  0  0
+ [529] NA  3 NA  2  2  9  3 NA NA  2  2 NA  2  2 NA  2 NA NA  0 NA NA  1  0 NA NA  1  2  2 NA NA NA NA NA  0  2  0 NA  0  0  0  0  0  0 NA NA NA NA NA
+ [577] NA NA  2 NA NA NA NA  2 NA  0  3  0  0 NA NA NA NA  0 NA NA  0  3 NA NA NA  0 NA NA NA  9 NA NA NA NA NA NA NA  2  2 NA  2 NA NA NA  0 NA NA  1
+ [625]  1  9  0  2 NA NA NA NA  1 NA NA NA  2 NA  0  0 NA  0  9  2 NA  0  1 NA  0  1 NA  0  0  2 NA  1  9 NA  0  3  3  1  3 NA  2 NA NA  2 NA  0  9  0
+ [673]  1  1 NA  2  0 NA  2  1 NA NA NA NA  3  3 NA NA  3  0 NA  9 NA  3 NA NA  9  2  0  3  2  0  0 NA  0  2  2 NA NA  2  0 NA NA  2 NA  1 NA NA NA NA
+ [721] NA NA  2  2 NA  0 NA  2  0  2  2  2  2  1  0 NA NA NA NA  1 NA  2  0  0 NA NA NA  2  1  1 NA  2  0  1  0 NA  1  2  1  1  9  0 NA NA  0  1 NA NA
+ [769]  1  0  2 NA NA NA NA NA NA NA NA NA  0 NA NA NA  0 NA  1  1  2  1 NA NA NA NA NA NA NA  2 NA  0 NA NA  0 NA NA  0 NA NA NA NA  0 NA  0 NA NA  0
+ [817] NA NA  2  0 NA NA NA NA NA NA NA NA NA NA  1 NA NA NA NA NA  2 NA  1  0 NA  2  2  1  2 NA NA NA NA  0  9 NA NA  2  0 NA NA  3  0  2  2  0  1  0
+ [865]  0 NA  1  9  0  0  0  0  2  0  1  0  1  0 NA  0 NA NA  9 NA NA NA NA NA NA NA NA NA NA  0 NA  3  0 NA NA  2  9 NA NA NA  3 NA  1 NA NA  1  2  0
+ [913] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0  1 NA NA NA NA NA NA  0 NA NA NA NA  2  1 NA NA  1 NA NA  1  0  1 NA  0  9 NA NA  1
+ [961] NA  2 NA NA  0 NA NA  3  0 NA NA  2  0 NA NA NA NA NA NA  3 NA  2 NA NA NA NA  1  2  1  0 NA  0 NA  0 NA NA NA NA NA  0
+ [ reached getOption("max.print") -- omitted 2791 entries ]
+
+Labels:
+ + +
+ +
+ + + +

Getting counts for each of the most important categories.

+ + + +
cat("New 'worst' vs 'latest' symptom categories.\n")
+ + +
New 'worst' vs 'latest' symptom categories.
+ + +
table(as_factor(AEDB$indexsymptoms_worst_4g), as_factor(AEDB$indexsymptoms_latest_4g))
+ + +
         
+          asymp ocular TIA stroke unclear
+  asymp     804     62  84     25      25
+  ocular      0    345   0      0       0
+  TIA         0     19 703      0       1
+  stroke      0      7  18    555       0
+  unclear     0      0   0      0      55
+ + +
cat("\nNew 'worst' symptom categories.\n")
+ + +

+New 'worst' symptom categories.
+ + +
table((AEDB$indexsymptoms_worst_4g))
+ + +

+   0    1    2    3    9 
+1000  345  723  580   55 
+ + +
cat("\nNew 'latest' symptom categories.\n")
+ + +

+New 'latest' symptom categories.
+ + +
table(as_factor(AEDB$indexsymptoms_latest_4g))
+ + +

+  asymp  ocular     TIA  stroke unclear 
+    804     433     805     580      81 
+ + + +

Comparing with the original symptom categories.

+ + + +
cat("New 'latest' vs original symptom 2G categories.\n")
+ + +
New 'latest' vs original symptom 2G categories.
+ + +
table((AEDB$indexsymptoms_latest_4g), AEDB$AsymptSympt2G)
+ + +
   
+    Asymptomatic Symptomatic
+  0          317         479
+  1            2         430
+  2            6         796
+  3            1         576
+  9            7          74
+ + +
cat("\nNew 'latest' vs original symptom 5G categories.\n")
+ + +

+New 'latest' vs original symptom 5G categories.
+ + +
table((AEDB$indexsymptoms_latest_4g), AEDB$Symptoms.5G)
+ + +
   
+    Asymptomatic Ocular Other Retinal infarction Stroke TIA
+  0          317     79    82                  9    128 181
+  1            2    313     4                 32     13  68
+  2            6     11    16                  2     90 677
+  3            1      2     7                  0    488  79
+  9            7     11    10                  0     13  40
+ + +
   
+ + + +

We need to be very strict in defining symptoms. Therefore we +will fix a new variable that groups symptoms at inclusion.

+

Coding of symptoms is as follows:

+
    +
  • asympt 0
    +
  • +
  • ocular 1
    +
  • +
  • TIA 2
    +
  • +
  • stroke 3
    +
  • +
  • unclear 9
  • +
+

We will group as follows:

+
    +
  1. Asymptomatic > 0
  2. +
  3. Symptomatic > 1, 2, 3
  4. +
  5. NA > 9
  6. +
+ + + +

+# Fix symptoms
+attach(AEDB)
+
+# Symptoms.Update2G
+AEDB[,"Symptoms.Update2G"] <- NA
+AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 0] <- "Asymptomatic"
+AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 1 | indexsymptoms_latest_4g == 2 | indexsymptoms_latest_4g == 3] <- "Symptomatic"
+AEDB$Symptoms.Update2G[indexsymptoms_latest_4g == 9 ] <- NA
+
+# Symptoms.Update3G
+AEDB[,"Symptoms.Update3G"] <- NA
+AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 0] <- "Asymptomatic"
+AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 1 | indexsymptoms_latest_4g == 2 | indexsymptoms_latest_4g == 3] <- "Symptomatic"
+AEDB$Symptoms.Update3G[indexsymptoms_latest_4g == 9 ] <- "Unclear"
+
+detach(AEDB)
+
+table(AEDB$Symptoms.Update2G, AEDB$Symptoms.5G, useNA = "ifany")
+ + +
              
+               Asymptomatic Ocular Other Retinal infarction Stroke  TIA <NA>
+  Asymptomatic          317     79    82                  9    128  181    8
+  Symptomatic             9    326    27                 34    591  824    7
+  <NA>                    7     11    10                  0     13   40 1088
+ + +
table(AEDB$Symptoms.Update3G, AEDB$Symptoms.5G, useNA = "ifany")
+ + +
              
+               Asymptomatic Ocular Other Retinal infarction Stroke  TIA <NA>
+  Asymptomatic          317     79    82                  9    128  181    8
+  Symptomatic             9    326    27                 34    591  824    7
+  Unclear                 7     11    10                  0     13   40    0
+  <NA>                    0      0     0                  0      0    0 1088
+ + + +
+
+

Other clinical characteristics

+

We will also fix the diabetes status variable.

+ + + +

+# Fix diabetes
+attach(AEDB)
+AEDB[,"DiabetesStatus"] <- NA
+AEDB$DiabetesStatus[DM.composite == -999] <- NA
+AEDB$DiabetesStatus[DM.composite == 0] <- "Control (no Diabetes Dx/Med)"
+AEDB$DiabetesStatus[DM.composite == 1] <- "Diabetes"
+detach(AEDB)
+
+table(AEDB$DM.composite, AEDB$DiabetesStatus)
+ + +
   
+    Control (no Diabetes Dx/Med) Diabetes
+  0                         2764        0
+  1                            0      985
+ + +
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# rm(AEDB.temp)
+ + + +

We will also fix the smoking status variable. We are +interested in whether someone never, ever or is currently (at the time +of inclusion) smoking. This is based on the questionnaire.

+
    +
  • diet801: are you a smoker?
  • +
  • diet802: did you smoke in the past?
  • +
+

We already have some variables indicating smoking status:

+
    +
  • SmokingReported: patient has reported to smoke.
  • +
  • SmokingYearOR: smoking in the year of surgery?
  • +
  • SmokerCurrent: currently smoking?
  • +
+ + + +
require(labelled)
+AEDB$diet801 <- to_factor(AEDB$diet801)
+AEDB$diet802 <- to_factor(AEDB$diet802)
+AEDB$diet805 <- to_factor(AEDB$diet805)
+AEDB$SmokingReported <- to_factor(AEDB$SmokingReported)
+AEDB$SmokerCurrent <- to_factor(AEDB$SmokerCurrent)
+AEDB$SmokingYearOR <- to_factor(AEDB$SmokingYearOR)
+
+# table(AEDB$diet801)
+# table(AEDB$diet802)
+# table(AEDB$SmokingReported)
+# table(AEDB$SmokerCurrent)
+# table(AEDB$SmokingYearOR)
+# table(AEDB$SmokingReported, AEDB$SmokerCurrent, useNA = "ifany", dnn = c("Reported smoking", "Current smoker"))
+# 
+# table(AEDB$diet801, AEDB$diet802, useNA = "ifany", dnn = c("Smoker", "Past smoker"))
+
+cat("\nFixing smoking status.\n")
+ + +

+Fixing smoking status.
+ + +
attach(AEDB)
+AEDB[,"SmokerStatus"] <- NA
+AEDB$SmokerStatus[diet802 == "don't know"] <- "Never smoked"
+AEDB$SmokerStatus[diet802 == "I still smoke"] <- "Current smoker"
+AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "no"] <- "Never smoked"
+AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "yes"] <- "Ex-smoker"
+AEDB$SmokerStatus[SmokerCurrent == "yes"] <- "Current smoker"
+AEDB$SmokerStatus[SmokerCurrent == "no data available/missing"] <- NA
+# AEDB$SmokerStatus[is.na(SmokerCurrent)] <- "Never smoked"
+detach(AEDB)
+
+cat("\n* Current smoking status.\n")
+ + +

+* Current smoking status.
+ + +
table(AEDB$SmokerCurrent,
+      useNA = "ifany", 
+      dnn = c("Current smoker"))
+ + +
Current smoker
+no data available/missing                        no                       yes                      <NA> 
+                        0                      2364                      1308                       119 
+ + +
cat("\n* Updated smoking status.\n")
+ + +

+* Updated smoking status.
+ + +
table(AEDB$SmokerStatus,
+      useNA = "ifany", 
+      dnn = c("Updated smoking status"))
+ + +
Updated smoking status
+Current smoker      Ex-smoker   Never smoked           <NA> 
+          1308           1814            389            280 
+ + +
cat("\n* Comparing to 'SmokerCurrent'.\n")
+ + +

+* Comparing to 'SmokerCurrent'.
+ + +
table(AEDB$SmokerStatus, AEDB$SmokerCurrent, 
+      useNA = "ifany", 
+      dnn = c("Updated smoking status", "Current smoker"))
+ + +
                      Current smoker
+Updated smoking status no data available/missing   no  yes <NA>
+        Current smoker                         0    0 1308    0
+        Ex-smoker                              0 1814    0    0
+        Never smoked                           0  389    0    0
+        <NA>                                   0  161    0  119
+ + +
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# rm(AEDB.temp)
+ + + +

We will also fix the alcohol status variable.

+ + + +

+# Fix diabetes
+attach(AEDB)
+AEDB[,"AlcoholUse"] <- NA
+AEDB$AlcoholUse[diet810 == -999] <- NA
+AEDB$AlcoholUse[diet810 == 0] <- "No"
+AEDB$AlcoholUse[diet810 == 1] <- "Yes"
+detach(AEDB)
+
+# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "diet810", "AlcoholUse"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# AEDB.temp$AlcoholUse <- to_factor(AEDB.temp$AlcoholUse)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# rm(AEDB.temp)
+ + + +

We will also fix a history of CAD, stroke or peripheral intervention +status variable. This will be based on CAD_history, +Stroke_history, and Peripheral.interv

+ + + +

+# Fix diabetes
+attach(AEDB)
+AEDB[,"MedHx_CVD"] <- NA
+AEDB$MedHx_CVD[CAD_history == 0 | Stroke_history == 0 | Peripheral.interv == 0] <- "No"
+AEDB$MedHx_CVD[CAD_history == 1 | Stroke_history == 1 | Peripheral.interv == 1] <- "yes"
+detach(AEDB)
+
+table(AEDB$CAD_history)
+ + +

+   0    1 
+2430 1285 
+ + +
table(AEDB$Stroke_history)
+ + +

+   0    1 
+2763  947 
+ + +
table(AEDB$Peripheral.interv)
+ + +

+   0    1 
+2579 1099 
+ + +
table(AEDB$MedHx_CVD)
+ + +

+  No  yes 
+1309 2475 
+ + +
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "diet810", "AlcoholUse"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# AEDB.temp$AlcoholUse <- to_factor(AEDB.temp$AlcoholUse)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# rm(AEDB.temp)
+ + + +
+
+

Plaque phenotypes

+

We will also fix the plaquephenotypes variable.

+

Coding of symptoms is as follows:

+
    +
  • missing -999
    +
  • +
  • not relevant -888
  • +
  • fibrous 1
    +
  • +
  • fibroatheromatous 2
    +
  • +
  • atheromatous 3
  • +
+ + + +

+# Fix plaquephenotypes
+attach(AEDB)
+AEDB[,"OverallPlaquePhenotype"] <- NA
+AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA
+AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA
+AEDB$OverallPlaquePhenotype[plaquephenotype == 1] <- "fibrous"
+AEDB$OverallPlaquePhenotype[plaquephenotype == 2] <- "fibroatheromatous"
+AEDB$OverallPlaquePhenotype[plaquephenotype == 3] <- "atheromatous"
+detach(AEDB)
+
+# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "plaquephenotype", "OverallPlaquePhenotype"))
+# require(labelled)
+# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
+# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
+# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
+# 
+# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
+# 
+# rm(AEDB.temp)
+ + + +

We will also fix and inverse-rank normal transform the continuous +(manually) scored plaque phenotypes.

+ + + +
AEDB$macmean0 <- as.numeric(AEDB$macmean0)
+AEDB$smcmean0 <- as.numeric(AEDB$smcmean0)
+AEDB$neutrophils <- as.numeric(AEDB$neutrophils)
+AEDB$Mast_cells_plaque <- as.numeric(AEDB$Mast_cells_plaque)
+AEDB$vessel_density_averaged <- as.numeric(AEDB$vessel_density_averaged)
+
+AEDB$MAC_rankNorm <- qnorm((rank(AEDB$macmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$macmean0)))
+AEDB$SMC_rankNorm <- qnorm((rank(AEDB$smcmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$smcmean0)))
+AEDB$Neutrophils_rankNorm <- qnorm((rank(AEDB$neutrophils, na.last = "keep") - 0.5) / sum(!is.na(AEDB$neutrophils)))
+AEDB$MastCells_rankNorm <- qnorm((rank(AEDB$Mast_cells_plaque, na.last = "keep") - 0.5) / sum(!is.na(AEDB$Mast_cells_plaque)))
+AEDB$VesselDensity_rankNorm <- qnorm((rank(AEDB$vessel_density_averaged, na.last = "keep") - 0.5) / sum(!is.na(AEDB$vessel_density_averaged)))
+ + + + + + +
library(labelled)
+AEDB$Gender <- to_factor(AEDB$Gender)
+library(patchwork)
+
+p1 <- ggpubr::gghistogram(AEDB, "macmean0", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "% of macrophages (CD68)",
+                    xlab = "% per region of interest", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p2 <- ggpubr::gghistogram(AEDB, "MAC_rankNorm", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "% of macrophages (CD68)",
+                   xlab = "% per region of interest\ninverse-rank normalized number", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p1 | p2 
+ + +

+ + +

+p1 <- ggpubr::gghistogram(AEDB, "smcmean0", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "% of smooth muscle cells (SMA)",
+                    xlab = "% per region of interest", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p2 <- ggpubr::gghistogram(AEDB, "SMC_rankNorm", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "% of smooth muscle cells (SMA)",
+                   xlab = "% per region of interest\ninverse-rank normalized number", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p1 | p2 
+ + +

+ + +

+
+p1 <- ggpubr::gghistogram(AEDB, "neutrophils", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of neutrophils (CD66b)",
+                    xlab = "counts per plaque", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p2 <- ggpubr::gghistogram(AEDB, "Neutrophils_rankNorm", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of neutrophils (CD66b)",
+                   xlab = "counts per plaque\ninverse-rank normalized number", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p1 | p2 
+ + +

+ + +

+
+p1 <- ggpubr::gghistogram(AEDB, "Mast_cells_plaque", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of mast cells",
+                    xlab = "counts per plaque", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p2 <- ggpubr::gghistogram(AEDB, "MastCells_rankNorm", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of mast cells",
+                   xlab = "counts per plaque\ninverse-rank normalized number", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p1 | p2 
+ + +

+ + +

+
+p1 <- ggpubr::gghistogram(AEDB, "vessel_density_averaged", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of intraplaque neovessels",
+                    xlab = "counts per 3-4 hotspots", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p2 <- ggpubr::gghistogram(AEDB, "VesselDensity_rankNorm", 
+                    # y = "..count..", 
+                    color = "white",
+                    fill = "Gender",
+                    palette = c("#1290D9", "#DB003F"), 
+                    add = "median", 
+                    #add_density = TRUE,
+                    rug = TRUE,
+                    #add.params =  list(color = "black", linetype = 2), 
+                    title = "number of intraplaque neovessels",
+                   xlab = "counts per 3-4 hotspots\ninverse-rank normalized number", 
+                    ggtheme = theme_minimal())
+ + +
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
+ + +
p1 | p2 
+ + +

+ + +

+rm(p1, p2)
+ + + +

Here we calculate the plaque instability/vulnerability +index

+ + + +
# Plaque vulnerability
+require(labelled)
+AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin)
+AEDB$SMC.bin <- to_factor(AEDB$SMC.bin)
+AEDB$IPH.bin <- to_factor(AEDB$IPH.bin)
+AEDB$Calc.bin <- to_factor(AEDB$Calc.bin)
+AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin)
+AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10)
+AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40)
+
+table(AEDB$Macrophages.bin)
+ + +

+      no/minor moderate/heavy 
+          1602           1215 
+ + +
table(AEDB$Fat.bin_10)
+ + +

+ <10%  >10% 
+ 1226  1628 
+ + +
table(AEDB$Collagen.bin)
+ + +

+      no/minor moderate/heavy 
+           540           2297 
+ + +
table(AEDB$SMC.bin)
+ + +

+      no/minor moderate/heavy 
+           870           1962 
+ + +
table(AEDB$IPH.bin)
+ + +

+  no  yes 
+1223 1628 
+ + +
# SPSS code
+
+# 
+# *** syntax- Plaque vulnerability**.
+# COMPUTE Macro_instab = -999.
+# IF macrophages.bin=2 Macro_instab=1.
+# IF macrophages.bin=1 Macro_instab=0.
+# EXECUTE.
+# 
+# COMPUTE Fat10_instab = -999.
+# IF Fat.bin_10=2 Fat10_instab=1.
+# IF Fat.bin_10=1 Fat10_instab=0.
+# EXECUTE.
+# 
+# COMPUTE coll_instab=-999.
+# IF Collagen.bin=2 coll_instab=0.
+# IF Collagen.bin=1 coll_instab=1.
+# EXECUTE.
+# 
+# 
+# COMPUTE SMC_instab=-999.
+# IF SMC.bin=2 SMC_instab=0.
+# IF SMC.bin=1 SMC_instab=1.
+# EXECUTE.
+# 
+# COMPUTE IPH_instab=-999.
+# IF IPH.bin=0 IPH_instab=0.
+# IF IPH.bin=1 IPH_instab=1.
+# EXECUTE.
+# 
+# COMPUTE Instability=Macro_instab + Fat10_instab +  coll_instab + SMC_instab + IPH_instab.
+# EXECUTE.
+
+# Fix plaquephenotypes
+attach(AEDB)
+# mac instability
+AEDB[,"MAC_Instability"] <- NA
+AEDB$MAC_Instability[Macrophages.bin == -999] <- NA
+AEDB$MAC_Instability[Macrophages.bin == "no/minor"] <- 0
+AEDB$MAC_Instability[Macrophages.bin == "moderate/heavy"] <- 1
+
+# fat instability
+AEDB[,"FAT10_Instability"] <- NA
+AEDB$FAT10_Instability[Fat.bin_10 == -999] <- NA
+AEDB$FAT10_Instability[Fat.bin_10 == " <10%"] <- 0
+AEDB$FAT10_Instability[Fat.bin_10 == " >10%"] <- 1
+
+# col instability 
+AEDB[,"COL_Instability"] <- NA
+AEDB$COL_Instability[Collagen.bin == -999] <- NA
+AEDB$COL_Instability[Collagen.bin == "no/minor"] <- 1
+AEDB$COL_Instability[Collagen.bin == "moderate/heavy"] <- 0
+
+# smc instability
+AEDB[,"SMC_Instability"] <- NA
+AEDB$SMC_Instability[SMC.bin == -999] <- NA
+AEDB$SMC_Instability[SMC.bin == "no/minor"] <- 1
+AEDB$SMC_Instability[SMC.bin == "moderate/heavy"] <- 0
+
+# iph instability
+AEDB[,"IPH_Instability"] <- NA
+AEDB$IPH_Instability[IPH.bin == -999] <- NA
+AEDB$IPH_Instability[IPH.bin == "no"] <- 0
+AEDB$IPH_Instability[IPH.bin == "yes"] <- 1
+
+detach(AEDB)
+
+table(AEDB$MAC_Instability, useNA = "ifany")
+ + +

+   0    1 <NA> 
+1602 1215  974 
+ + +
table(AEDB$FAT10_Instability, useNA = "ifany")
+ + +

+   0    1 <NA> 
+1226 1628  937 
+ + +
table(AEDB$COL_Instability, useNA = "ifany")
+ + +

+   0    1 <NA> 
+2297  540  954 
+ + +
table(AEDB$SMC_Instability, useNA = "ifany")
+ + +

+   0    1 <NA> 
+1962  870  959 
+ + +
table(AEDB$IPH_Instability, useNA = "ifany")
+ + +

+   0    1 <NA> 
+1223 1628  940 
+ + +
# creating vulnerability index
+AEDB <- AEDB %>% mutate(Plaque_Vulnerability_Index = factor(rowSums(.[grep("_Instability", names(.))], na.rm = TRUE)),
+                                )
+
+table(AEDB$Plaque_Vulnerability_Index, useNA = "ifany")
+ + +

+   0    1    2    3    4    5 
+1324  655  728  676  298  110 
+ + +
# str(AEDB$Plaque_Vulnerability_Index)
+ + + +
+
+
+

Prepare baseline summary

+

We are interested in the following variables at baseline in the whole +cohort.

+
    +
  • Age (years)
  • +
  • Female sex (N, %)
  • +
  • Artery type (N, %)
  • +
  • Hospital (N, %) + + + + + + + + + + + + + + + +
  • +
+ + + +
cat("====================================================================================================\n")
+ + +
====================================================================================================
+ + +
cat("SELECTION THE SHIZZLE\n")
+ + +
SELECTION THE SHIZZLE
+ + +
### Artery levels
+# AEdata$Artery_summary: 
+#           value                                                                                   label
+# NOT USE - 0 No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA
+# USE - 1                                                                  carotid (left & right)
+# USE - 2                                               femoral/iliac (left, right or both sides)
+# NOT USE - 3                                               other carotid arteries (common, external)
+# NOT USE - 4                                   carotid bypass and injury (left, right or both sides)
+# NOT USE - 5                                                         aneurysmata (carotid & femoral)
+# NOT USE - 6                                                                                   aorta
+# NOT USE - 7                                            other arteries (renal, popliteal, vertebral)
+# NOT USE - 8                        femoral bypass, angioseal and injury (left, right or both sides)
+
+### AEdata$informedconsent
+#           value                                                                                           label
+# NOT USE - -999                                                                                         missing
+# NOT USE - 0                                                                                        no, died
+# USE - 1                                                                                             yes
+# USE - 2                                                             yes, health treatment when possible
+# USE - 3                                                                        yes, no health treatment
+# USE - 4                                                yes, no health treatment, no commercial business
+# NOT USE - 5                                                          yes, no tissue, no commerical business
+# NOT USE - 6                      yes, no tissue, no questionnaires, no medical info, no commercial business
+# USE - 7                             yes, no questionnaires, no health treatment, no commercial business
+# USE - 8                                          yes, no questionnaires, health treatment when possible
+# NOT USE - 9                  yes, no tissue, no questionnaires, no health treatment, no commerical business
+# USE - 10                               yes, no health treatment, no medical info, no commercial business
+# NOT USE - 11 yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business
+# USE - 12                                                     yes, no questionnaires, no health treatment
+# NOT USE - 13                                                             yes, no tissue, no health treatment
+# NOT USE - 14                                                               yes, no tissue, no questionnaires
+# NOT USE - 15                                                  yes, no tissue, health treatment when possible
+# NOT USE - 16                                                                                  yes, no tissue
+# USE - 17                                                                     yes, no commerical business
+# USE - 18                                     yes, health treatment when possible, no commercial business
+# USE - 19                                                    yes, no medical info, no commercial business
+# USE - 20                                                                          yes, no questionnaires
+# NOT USE - 21                         yes, no tissue, no questionnaires, no health treatment, no medical info
+# NOT USE - 22                  yes, no tissue, no questionnaires, no health treatment, no commercial business
+# USE - 23                                                                            yes, no medical info
+# USE - 24                                                  yes, no questionnaires, no commercial business
+# USE - 25                                    yes, no questionnaires, no health treatment, no medical info
+# USE - 26                  yes, no questionnaires, health treatment when possible, no commercial business
+# USE - 27                                                      yes,  no health treatment, no medical info
+# NOT USE - 28                                                                             no, doesn't want to
+# NOT USE - 29                                                                              no, unable to sign
+# NOT USE - 30                                                                                 no, no reaction
+# NOT USE - 31                                                                                        no, lost
+# NOT USE - 32                                                                                     no, too old
+# NOT USE - 34                                            yes, no medical info, health treatment when possible
+# NOT USE - 35                                             no (never asked for IC because there was no tissue)
+# USE - 36                    yes, no medical info, no commercial business, health treatment when possible
+# NOT USE - 37                                                                                    no, endpoint
+# USE - 38                                                         wil niets invullen, wel alles gebruiken
+# USE - 39                                           second informed concents: yes, no commercial business
+# NOT USE - 40                                                                              nooit geincludeerd
+
+cat("- sanity checking PRIOR to selection")
+ + +
- sanity checking PRIOR to selection
+ + +
library(data.table)
+require(labelled)
+ae.gender <- to_factor(AEDB$Gender)
+ae.hospital <- to_factor(AEDB$Hospital)
+table(ae.gender, ae.hospital, dnn = c("Sex", "Hospital"))
+ + +
        Hospital
+Sex      St. Antonius, Nieuwegein UMC Utrecht
+  female                      524         636
+  male                       1211        1420
+ + +
ae.artery <- to_factor(AEDB$Artery_summary)
+table(ae.artery, ae.gender, dnn = c("Sex", "Artery"))
+ + +
                                                                                         Artery
+Sex                                                                                       female male
+  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA      0    0
+  carotid (left & right)                                                                     805 1781
+  femoral/iliac (left, right or both sides)                                                  320  796
+  other carotid arteries (common, external)                                                   17   35
+  carotid bypass and injury (left, right or both sides)                                        6    3
+  aneurysmata (carotid & femoral)                                                              1    0
+  aorta                                                                                        3    5
+  other arteries (renal, popliteal, vertebral)                                                 4    9
+  femoral bypass, angioseal and injury (left, right or both sides)                             4    2
+ + +
rm(ae.gender, ae.hospital, ae.artery)
+
+# I change numeric and factors manually because, well, I wouldn't know how to fix it otherwise
+# to have this 'tibble' work with 'tableone'... :-)
+
+AEDB$Age <- as.numeric(AEDB$Age)
+AEDB$diastoli <- as.numeric(AEDB$diastoli)
+AEDB$systolic <- as.numeric(AEDB$systolic)
+
+AEDB$TC_finalCU <- as.numeric(AEDB$TC_finalCU)
+AEDB$LDL_finalCU <- as.numeric(AEDB$LDL_finalCU)
+AEDB$HDL_finalCU <- as.numeric(AEDB$HDL_finalCU)
+AEDB$TG_finalCU <- as.numeric(AEDB$TG_finalCU)
+
+AEDB$TC_final <- as.numeric(AEDB$TC_final)
+AEDB$LDL_final <- as.numeric(AEDB$LDL_final)
+AEDB$HDL_final <- as.numeric(AEDB$HDL_final)
+AEDB$TG_final <- as.numeric(AEDB$TG_final)
+
+AEDB$Age <- as.numeric(AEDB$Age)
+AEDB$GFR_MDRD <- as.numeric(AEDB$GFR_MDRD)
+AEDB$BMI <- as.numeric(AEDB$BMI)
+AEDB$eCigarettes <- as.numeric(AEDB$eCigarettes)
+AEDB$ePackYearsSmoking <- as.numeric(AEDB$ePackYearsSmoking)
+AEDB$EP_composite_time <- as.numeric(AEDB$EP_composite_time)
+AEDB$EP_major_time <- as.numeric(AEDB$EP_major_time)
+
+require(labelled)
+AEDB$Artery_summary <- to_factor(AEDB$Artery_summary)
+AEDB$ORyear <- to_factor(AEDB$ORyear)
+AEDB$Gender <- to_factor(AEDB$Gender)
+AEDB$Hospital <- to_factor(AEDB$Hospital)
+AEDB$KDOQI <- to_factor(AEDB$KDOQI)
+AEDB$BMI_WHO <- to_factor(AEDB$BMI_WHO)
+AEDB$DiabetesStatus <- to_factor(AEDB$DiabetesStatus)
+AEDB$SmokerStatus <- to_factor(AEDB$SmokerStatus)
+AEDB$AlcoholUse <- to_factor(AEDB$AlcoholUse)
+
+AEDB$Hypertension.selfreport <- to_factor(AEDB$Hypertension1)
+AEDB$Hypertension.selfreportdrug <- to_factor(AEDB$Hypertension2)
+AEDB$Hypertension.composite <- to_factor(AEDB$Hypertension.composite)
+AEDB$Hypertension.drugs <- to_factor(AEDB$Hypertension.drugs)
+
+AEDB$Med.anticoagulants <- to_factor(AEDB$Med.anticoagulants)
+AEDB$Med.all.antiplatelet <- to_factor(AEDB$Med.all.antiplatelet)
+AEDB$Med.Statin.LLD <- to_factor(AEDB$Med.Statin.LLD)
+
+AEDB$Stroke_Dx <- to_factor(AEDB$Stroke_Dx)
+AEDB$CAD_history <- to_factor(AEDB$CAD_history)
+AEDB$PAOD <- to_factor(AEDB$PAOD)
+AEDB$Peripheral.interv <- to_factor(AEDB$Peripheral.interv)
+
+AEDB$sympt <- to_factor(AEDB$sympt)
+AEDB$Symptoms.3g <- to_factor(AEDB$Symptoms.3g)
+AEDB$Symptoms.4g <- to_factor(AEDB$Symptoms.4g)
+AEDB$Symptoms.5G <- to_factor(AEDB$Symptoms.5G)
+AEDB$AsymptSympt <- to_factor(AEDB$AsymptSympt)
+AEDB$AsymptSympt2G <- to_factor(AEDB$AsymptSympt2G)
+AEDB$Symptoms.Update2G <- to_factor(AEDB$Symptoms.Update2G)
+AEDB$Symptoms.Update3G <- to_factor(AEDB$Symptoms.Update3G)
+
+AEDB$restenos <- to_factor(AEDB$restenos)
+AEDB$stenose <- to_factor(AEDB$stenose)
+AEDB$EP_composite <- to_factor(AEDB$EP_composite)
+AEDB$EP_major <- to_factor(AEDB$EP_major)
+AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin)
+AEDB$SMC.bin <- to_factor(AEDB$SMC.bin)
+AEDB$IPH.bin <- to_factor(AEDB$IPH.bin)
+AEDB$Calc.bin <- to_factor(AEDB$Calc.bin)
+AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin)
+AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10)
+AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40)
+AEDB$OverallPlaquePhenotype <- to_factor(AEDB$OverallPlaquePhenotype)
+AEDB$Plaque_Vulnerability_Index <- to_factor(AEDB$Plaque_Vulnerability_Index)
+
+AEDB$Artery_summary <- to_factor(AEDB$Artery_summary)
+
+AEDB$informedconsent <- to_factor(AEDB$informedconsent)
+
+AEDB.full <- subset(AEDB,
+                    informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
+                       informedconsent != "no, died" & 
+                       informedconsent != "yes, no tissue, no commerical business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
+                       informedconsent != "yes, no tissue, no health treatment" &
+                       informedconsent != "yes, no tissue, no questionnaires" &
+                       informedconsent != "yes, no tissue, health treatment when possible" &
+                       informedconsent != "yes, no tissue" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
+                       informedconsent != "no, doesn't want to" &
+                       informedconsent != "no, unable to sign" & 
+                       informedconsent != "no, no reaction" & 
+                       informedconsent != "no, lost" & 
+                       informedconsent != "no, too old" & 
+                       informedconsent != "yes, no medical info, health treatment when possible" &
+                       informedconsent != "no (never asked for IC because there was no tissue)" &
+                       informedconsent != "no, endpoint" & 
+                       informedconsent != "nooit geincludeerd")
+# AEDB.CEA[1:10, 1:10]
+dim(AEDB.full)
+ + +
[1] 3458 1114
+ + + + + + +
cat("===========================================================================================\n")
+ + +
===========================================================================================
+ + +
cat("CREATE BASELINE TABLE\n")
+ + +
CREATE BASELINE TABLE
+ + +
# Baseline table variables
+basetable_vars = c("Hospital", 
+                   "Artery_summary",
+                   "Age", "Gender")
+                   # "ORyear", 
+                   # "TC_finalCU", "LDL_finalCU", "HDL_finalCU", "TG_finalCU", 
+                   # "TC_final", "LDL_final", "HDL_final", "TG_final", 
+                   # "hsCRP_plasma",
+                   # "systolic", "diastoli", "GFR_MDRD", "BMI", 
+                   # "KDOQI", "BMI_WHO",
+                   # "SmokerStatus", "AlcoholUse",
+                   # "DiabetesStatus", 
+                   # "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", 
+                   # "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
+                   # "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
+                   # "Symptoms.Update2G", 
+                   # "Symptoms.Update3G",
+                   # "restenos", "stenose",
+                   # "CAD_history", "PAOD", "Peripheral.interv", 
+                   # "EP_composite", "EP_composite_time", "EP_major", "EP_major_time",
+                   # "MAC_rankNorm", "SMC_rankNorm", "Macrophages.bin", "SMC.bin",
+                   # "Neutrophils_rankNorm", "MastCells_rankNorm",
+                   # "IPH.bin", "VesselDensity_rankNorm",
+                   # "Calc.bin", "Collagen.bin", 
+                   # "Fat.bin_10", "Fat.bin_40", 
+                   # "OverallPlaquePhenotype", "Plaque_Vulnerability_Index")
+
+basetable_bin = c("Hospital", 
+                  "Artery_summary",
+                  "Gender")
+# basetable_bin
+
+basetable_con = basetable_vars[!basetable_vars %in% basetable_bin]
+# basetable_con
+ + + +
+
+
+

Athero-Express Biobank Study Baseline Characteristics

+

Showing the baseline table of the whole Athero-Express Biobank.

+ + + +
# Create baseline tables
+# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
+AEDB.tableOne = print(CreateTableOne(vars = basetable_vars, 
+                                         factorVars = basetable_bin,
+                                         # strata = "Symptoms.4g",
+                                         data = AEDB.full, includeNA = TRUE), 
+                          nonnormal = c(), missing = TRUE,
+                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
+                          format = "pf", 
+                          contDigits = 3)[,1:3]
+ + +
                         
+                          level                                                            Overall        Missing
+  n                                                                                          3458                
+  Hospital % (freq)       St. Antonius, Nieuwegein                                           45.3 (1567)  0.0    
+                          UMC Utrecht                                                        54.7 (1891)         
+  Artery_summary % (freq) carotid (left & right)                                             69.0 (2387)  0.0    
+                          femoral/iliac (left, right or both sides)                          28.8 ( 995)         
+                          other carotid arteries (common, external)                           1.3 (  45)         
+                          carotid bypass and injury (left, right or both sides)               0.2 (   7)         
+                          aneurysmata (carotid & femoral)                                     0.0 (   1)         
+                          aorta                                                               0.2 (   6)         
+                          other arteries (renal, popliteal, vertebral)                        0.3 (  12)         
+                          femoral bypass, angioseal and injury (left, right or both sides)    0.1 (   5)         
+  Age (mean (SD))                                                                          68.733 (9.214) 0.0    
+  Gender % (freq)         female                                                             29.7 (1026)  0.0    
+                          male                                                               70.3 (2432)         
+ + + +
+

Match samples used

+

Here we match the full database with the samples used in +EntropyMasker.

+ + + +
# Remove duplicate rows of the dataframe
+library(dplyr)
+temp <- EM_samples %>% select(., "Studynumber") %>%
+  distinct(.)
+
+AEDB_EM <- merge(temp,
+                 AEDB,
+                 by.x = "Studynumber",
+                 by.y = "STUDY_NUMBER", 
+                 sort = FALSE)
+
+AEDB_EM.full <- subset(AEDB_EM,
+                    informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
+                       informedconsent != "no, died" & 
+                       informedconsent != "yes, no tissue, no commerical business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
+                       informedconsent != "yes, no tissue, no health treatment" &
+                       informedconsent != "yes, no tissue, no questionnaires" &
+                       informedconsent != "yes, no tissue, health treatment when possible" &
+                       informedconsent != "yes, no tissue" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
+                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
+                       informedconsent != "no, doesn't want to" &
+                       informedconsent != "no, unable to sign" & 
+                       informedconsent != "no, no reaction" & 
+                       informedconsent != "no, lost" & 
+                       informedconsent != "no, too old" & 
+                       informedconsent != "yes, no medical info, health treatment when possible" &
+                       informedconsent != "no (never asked for IC because there was no tissue)" &
+                       informedconsent != "no, endpoint" & 
+                       informedconsent != "nooit geincludeerd")
+# AEDB_EM.full[1:10, 1:10]
+
+rm(temp)
+ + + + + + +
# Create baseline tables
+# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
+AEDB_EM.full.tableOne = print(CreateTableOne(vars = basetable_vars, 
+                                         factorVars = basetable_bin,
+                                         # strata = "Symptoms.4g",
+                                         data = AEDB_EM.full, includeNA = TRUE), 
+                          nonnormal = c(), missing = TRUE,
+                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
+                          format = "pf", 
+                          contDigits = 3)[,1:3]
+ + +
                         
+                          level                                        Overall        Missing
+  n                                                                        56                
+  Hospital % (freq)       St. Antonius, Nieuwegein                       21.4 (12)    0.0    
+                          UMC Utrecht                                    78.6 (44)           
+  Artery_summary % (freq) carotid (left & right)                         85.7 (48)    0.0    
+                          femoral/iliac (left, right or both sides)      12.5 ( 7)           
+                          other arteries (renal, popliteal, vertebral)    1.8 ( 1)           
+  Age (mean (SD))                                                      69.500 (9.260) 0.0    
+  Gender % (freq)         female                                         33.9 (19)    0.0    
+                          male                                           66.1 (37)           
+ + + + + + +

+basetable_vars = c("Hospital", 
+                   "Artery_summary")
+
+basetable_bin = c("Hospital", 
+                  "Artery_summary")
+
+# Create baseline tables
+# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
+AEDB_EM.tableOne = print(CreateTableOne(vars = basetable_vars, 
+                                         factorVars = basetable_bin,
+                                         # strata = "Symptoms.4g",
+                                         data = AEDB_EM, includeNA = TRUE), 
+                          nonnormal = c(), missing = TRUE,
+                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
+                          format = "pf", 
+                          contDigits = 3)[,1:3]
+ + +
                         
+                          level                                        Overall    Missing
+  n                                                                      59              
+  Hospital % (freq)       St. Antonius, Nieuwegein                     22.0 (13)  0.0    
+                          UMC Utrecht                                  78.0 (46)         
+  Artery_summary % (freq) carotid (left & right)                       84.7 (50)  0.0    
+                          femoral/iliac (left, right or both sides)    13.6 ( 8)         
+                          other arteries (renal, popliteal, vertebral)  1.7 ( 1)         
+ + + +
+
+

Baseline writing

+

Let’s save the baseline characteristics of the Athero-Express Biobank +Study.

+ + + +
# Write basetable
+
+require(openxlsx)
+
+write.xlsx(as.data.frame(AEDB.tableOne), 
+           file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.BaselineTable.xlsx"), 
+           rowNames = TRUE, 
+           colNames = TRUE, 
+           sheetName = "AE_Base", overwrite = TRUE)
+
+write.xlsx(as.data.frame(AEDB_EM.tableOne), 
+           file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.EM.59.BaselineTable.xlsx"), 
+           rowNames = TRUE, 
+           colNames = TRUE, 
+           sheetName = "AE_Base_EM_59", overwrite = TRUE)
+
+write.xlsx(as.data.frame(AEDB_EM.full.tableOne), 
+           file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AE.EM.56.BaselineTable.xlsx"), 
+           rowNames = TRUE, 
+           colNames = TRUE, 
+           sheetName = "AE_Base_EM_56", overwrite = TRUE)
+ + + +

We will also write the newly prepared AEDB selected for this study +which we can use in downstream analyses.

+ + + +
saveRDS(AEDB_EM.full, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.EM.FULL.RDS"))
+saveRDS(AEDB.full, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.FULL.RDS"))
+saveRDS(AEDB, file = paste0(OUT_loc, "/",Today,".",PROJECTNAME,".AEDB.raw.RDS"))
+ + + +
+
+
+

Session information

+
+
Version:      v1.0.2
+Last update:  2022-07-12
+Written by:   Sander W. van der Laan (s.w.vanderlaan-2[at]umcutrecht.nl).
+Description:  Script to get some Athero-Express Biobank Study baseline characteristics.
+Minimum requirements: R version 3.4.3 (2017-06-30) -- 'Single Candle', Mac OS X El Capitan
+
+**MoSCoW To-Do List**
+The things we Must, Should, Could, and Would have given the time we have.
+_M_
+
+_S_
+
+_C_
+
+_W_
+
+**Changes log**
+* v1.0.2 Simplified the initial script. It now outputs the relevant R-objects (as .RDS).
+* v1.0.1 Update to main AEDB (there is an error in the Age-variable in the new version).
+* v1.0.0 Initial version. Add 'plaque vulnerability index', Fixed baseline table, added codes, and results. Major update to WORCS system.
+
+ + + +
sessionInfo()
+ + +
R version 4.2.1 (2022-06-23)
+Platform: x86_64-apple-darwin21.5.0 (64-bit)
+Running under: macOS Ventura 13.0
+
+Matrix products: default
+LAPACK: /usr/local/Cellar/r/4.2.1/lib/R/lib/libRlapack.dylib
+
+locale:
+[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
+
+attached base packages:
+[1] grid      tools     stats     graphics  grDevices utils     datasets  methods   base     
+
+other attached packages:
+ [1] openxlsx_4.2.5       patchwork_1.1.0.9000 labelled_2.9.1       sjPlot_2.8.10        UpSetR_1.4.0         ggpubr_0.4.0        
+ [7] forestplot_2.0.1     checkmate_2.1.0      magrittr_2.0.3       pheatmap_1.0.12      devtools_2.4.3       usethis_2.1.6       
+[13] BlandAltmanLeh_0.3.1 tableone_0.13.2      haven_2.5.0          eeptools_1.2.4       DT_0.23              knitr_1.39          
+[19] forcats_0.5.1        stringr_1.4.0        purrr_0.3.4          tibble_3.1.7         ggplot2_3.3.6        tidyverse_1.3.1     
+[25] data.table_1.14.2    naniar_0.6.1         tidyr_1.2.0          dplyr_1.0.9          optparse_1.7.1       readr_2.1.2         
+[31] R.utils_2.11.0       R.oo_1.25.0          R.methodsS3_1.8.2    credentials_1.3.2   
+
+loaded via a namespace (and not attached):
+  [1] readxl_1.4.0       backports_1.4.1    plyr_1.8.7         sp_1.5-0           splines_4.2.1      TH.data_1.1-1      digest_0.6.29     
+  [8] htmltools_0.5.2    fansi_1.0.3        memoise_2.0.1      remotes_2.4.2      tzdb_0.3.0         modelr_0.1.8       sandwich_3.0-2    
+ [15] askpass_1.1        prettyunits_1.1.1  colorspace_2.0-3   rvest_1.0.2        mitools_2.4        xfun_0.31          callr_3.7.0       
+ [22] crayon_1.5.1       jsonlite_1.8.0     lme4_1.1-29        survival_3.3-1     zoo_1.8-10         glue_1.6.2         gtable_0.3.0      
+ [29] emmeans_1.7.5      sjstats_0.18.1     sjmisc_2.8.9       car_3.1-0          pkgbuild_1.3.1     abind_1.4-5        scales_1.2.0      
+ [36] mvtnorm_1.1-3      DBI_1.1.3          rstatix_0.7.0      ggeffects_1.1.2    Rcpp_1.0.8.3       xtable_1.8-4       performance_0.9.1 
+ [43] proxy_0.4-27       foreign_0.8-82     survey_4.1-1       vcd_1.4-10         datawizard_0.4.1   htmlwidgets_1.5.4  httr_1.4.3        
+ [50] getopt_1.20.3      RColorBrewer_1.1-3 ellipsis_0.3.2     farver_2.1.0       pkgconfig_2.0.3    sass_0.4.1         dbplyr_2.2.0      
+ [57] utf8_1.2.2         labeling_0.4.2     tidyselect_1.1.2   rlang_1.0.2        effectsize_0.7.0   munsell_0.5.0      cellranger_1.1.0  
+ [64] cachem_1.0.6       cli_3.3.0          generics_0.1.2     sjlabelled_1.2.0   broom_0.8.0        evaluate_0.15      fastmap_1.1.0     
+ [71] arm_1.12-2         yaml_2.3.5         sys_3.4            processx_3.6.1     fs_1.5.2           zip_2.2.0          pander_0.6.5      
+ [78] visdat_0.5.3       nlme_3.1-157       xml2_1.3.3         brio_1.1.3         compiler_4.2.1     rstudioapi_0.13    curl_4.3.2        
+ [85] e1071_1.7-11       testthat_3.1.4     ggsignif_0.6.3     reprex_2.0.1       bslib_0.3.1        stringi_1.7.6      ps_1.7.1          
+ [92] parameters_0.18.1  desc_1.4.1         lattice_0.20-45    Matrix_1.4-1       nloptr_2.0.3       vctrs_0.4.1        pillar_1.7.0      
+ [99] lifecycle_1.0.1    jquerylib_0.1.4    lmtest_0.9-40      estimability_1.3   maptools_1.1-4     insight_0.17.1     R6_2.5.1          
+[106] gridExtra_2.3      sessioninfo_1.2.2  codetools_0.2-18   boot_1.3-28        MASS_7.3-57        assertthat_0.2.1   pkgload_1.2.4     
+[113] openssl_2.0.2      rprojroot_2.0.3    withr_2.5.0        multcomp_1.4-19    bayestestR_0.12.1  hms_1.1.1          class_7.3-20      
+[120] coda_0.19-4        minqa_1.2.4        rmarkdown_2.14     carData_3.0-5      lubridate_1.8.0   
+ + + +
+
+

Saving environment

+ + + +
save.image(paste0(PROJECT_loc, "/",Today,".",PROJECTNAME,".AEDB.EM.baseline.RData"))
+ + + + +++ + + + + + +
© 1979-2022 Sander W. van der Laan | +s.w.vanderlaan[at]gmail.com | swvanderlaan.github.io.
+ +
+ +
LS0tCnRpdGxlOiAiQmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIgphdXRob3I6ICJbU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiwgUGhEXShodHRwczovL3N3dmFuZGVybGFhbi5naXRodWIuaW8pIHwgQHN3dmFuZGVybGFhbiB8IHMudy52YW5kZXJsYWFuQGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNhY2hlOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY29sbGFwc2U6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWcuYWxpZ246IGNlbnRlcgogICAgZmlnX2NhcHRpb246IHllcwogICAgZmlnX2hlaWdodDogNgogICAgZmlnX3JldGluYTogMgogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0aGVtZTogbHVtZW4KICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogbm8KICAgICAgc21vb3RoX3Njcm9sbDogeWVzCm1haW5mb250OiBBcmlhbApzdWJ0aXRsZTogQWNjb21wYW55aW5nICdFbnRyb3B5TWFza2VyJwplZGl0b3Jfb3B0aW9uczoKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCiMgYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgojIGtuaXQ6IHdvcmNzOjpjaXRlX2FsbAotLS0KCiMgR2VuZXJhbCBTZXR1cApXZSB3aWxsIGNsZWFuIHRoZSBlbnZpcm9ubWVudCwgc2V0dXAgdGhlIGxvY2F0aW9ucywgZGVmaW5lIGNvbG9ycywgYW5kIGNyZWF0ZSBhIGRhdGVzdGFtcC4KCl9DbGVhbiB0aGUgZW52aXJvbm1lbnQuXwpgYGB7ciBlY2hvID0gRkFMU0V9CnJtKGxpc3QgPSBscygpKQpgYGAKCl9TZXQgbG9jYXRpb25zIGFuZCB3b3JraW5nIGRpcmVjdG9yaWVzLi4uXwpgYGB7ciBMb2NhbFN5c3RlbSwgZWNobyA9IEZBTFNFfQpzb3VyY2UoInNjcmlwdHMvbG9jYWwuc3lzdGVtLlIiKQoKYGBgCgpfLi4uIGEgcGFja2FnZS1pbnN0YWxsYXRpb24gZnVuY3Rpb24gLi4uXwpgYGB7ciBGdW5jdGlvbjogaW5zdGFsbGF0aW9uc30Kc291cmNlKCJzY3JpcHRzL2Z1bmN0aW9ucy5SIikKCmBgYAoKCl8uLi4gYW5kIGxvYWQgdGhvc2UgcGFja2FnZXMuXwpgYGB7ciBsb2FkaW5nX3BhY2thZ2VzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzb3VyY2UoInNjcmlwdHMvcGFjazAxLnBhY2thZ2VzLlIiKQoKCmBgYAoKX1dlIHdpbGwgY3JlYXRlIGEgZGF0ZXN0YW1wIGFuZCBkZWZpbmUgdGhlIFV0cmVjaHQgU2NpZW5jZSBQYXJrIENvbG91ciBTY2hlbWVfLgpgYGB7ciBTZXR0aW5nOiBDb2xvcnN9CgpUb2RheSA9IGZvcm1hdChhcy5EYXRlKGFzLlBPU0lYbHQoU3lzLnRpbWUoKSkpLCAiJVklbSVkIikKVG9kYXkuUmVwb3J0ID0gZm9ybWF0KGFzLkRhdGUoYXMuUE9TSVhsdChTeXMudGltZSgpKSksICIlQSwgJUIgJWQsICVZIikKCnNvdXJjZSgic2NyaXB0cy9jb2xvcnMuUiIpCgpgYGAKCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlID0gRkFMU0V9CiMgZnVydGhlciBkZWZpbmUgc29tZSBrbml0ci1vcHRpb25zLgprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA4LCBmaWcucGF0aCA9ICdGaWd1cmVzLycsIAogICAgICAgICAgICAgICAgICAgICAgd3dhcm5pbmcgPSBUUlVFLCAjIHNob3cgd2FybmluZ3MgZHVyaW5nIGNvZGVib29rIGdlbmVyYXRpb24KICBtZXNzYWdlID0gVFJVRSwgIyBzaG93IG1lc3NhZ2VzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgZXJyb3IgPSBUUlVFLCAjIGRvIG5vdCBpbnRlcnJ1cHQgY29kZWJvb2sgZ2VuZXJhdGlvbiBpbiBjYXNlIG9mIGVycm9ycywKICAgICAgICAgICAgICAgICMgdXN1YWxseSBiZXR0ZXIgZm9yIGRlYnVnZ2luZwogIGVjaG8gPSBUUlVFLCAgIyBzaG93IFIgY29kZQogICAgICAgICAgICAgICAgICAgICAgZXZhbCA9IFRSVUUpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9taW5pbWFsKCkpCnBhbmRlcjo6cGFuZGVyT3B0aW9ucygidGFibGUuc3BsaXQudGFibGUiLCBJbmYpCmBgYAoKIyBUaGlzIG5vdGVib29rIAoKSW4gdGhpcyBub3RlYm9vayB3ZSBjcmVhdGUgYSBiYXNlbGluZSB0YWJsZSBvZiB0aGUgc2FtcGxlcyB1c2VkIGluICoqYEVudHJvcHlNYXNrZXJgKiouIAoKIyBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5CgpUaGUgWypBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IChBRSkqXShodHRwczovL2RvaS5vcmcvMTAuMTAwNy9zMTA1NjQtMDA0LTIzMDQtNikgY29udGFpbnMgcGxhcXVlIG1hdGVyaWFsIG9mIHBhdGllbnRzIHRoYXQgdW5kZXJ3ZW50IGVuZGFydGVyZWN0b215YXQgdHdvIER1dGNoIHRlcnRpYXJ5IHJlZmVycmFsIGNlbnRlcnMuIERldGFpbHMgb2YgdGhlIHN0dWR5IGRlc2lnbiB3ZXJlIGRlc2NyaWJlZCBiZWZvcmUuIEJyaWVmbHksIGJsb29kIGFuZCBwbGFxdWUgbWF0ZXJpYWwgd2VyZSBvYnRhaW5lZCBkdXJpbmcgZW5kYXJ0ZXJlY3RvbXkgYW5kIHN0b3JlZCBhdCAtODAg4oSDLiBBbGwgcGF0aWVudHMgcHJvdmlkZWQgaW5mb3JtZWQgY29uc2VudCBhbmQgdGhlIHN0dWR5IHdhcyBhcHByb3ZlZCBieSB0aGUgbWVkaWNhbCBldGhpY3MgY29tbWl0dGVlLgoKIyMgTG9hZCByZWxldmFudCBzYW1wbGVzCgpgYGB7cn0KRU1fc2FtcGxlcyA8LSBmcmVhZChwYXN0ZTAoQU5BTFlTSVNfbG9jLCAiL2RhdGF2ZXJzZS9FbnRyb3B5TWFza2VyX2ltYWdlX2ZpbGVzX3VzZWQudHh0IikpCmBgYAoKIyMgTG9hZCBkYXRhCgpMb2FkaW5nIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgY2xpbmljYWwgYW5kIGJpb2JhbmsgZGF0YS4KCmBgYHtyIExvYWRBRURCfQpjYXQoIiogZ2V0IEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgRGF0YWJhc2UuLi4iKQojIE1FVEhPRCAxOiBJdCBzZWVtcyB0aGlzIG1ldGhvZCBnaXZlcyBsb2FkcyBvZiBlcnJvcnMgYW5kIHdhcm5pbmdzLCB3aGljaCBhbGwgYXJlIGhhcmQgdG8gY29tcHJlaGVuZAojICAgICAgICAgICBvciBkZWJ1Zy4gV2UgZXhwZWN0IDMsNTI3IHNhbXBsZXMsIGFuZCA5MjcgdmFyaWFibGVzOyB3ZSBnZXQgOTI3IHZhcmlhYmxlcyEhIQojIEFFZGF0YSA9IGFzLmRhdGEudGFibGUocmVhZC5zcHNzKHBhc3RlMChJTlBfbG9jLCIvMjAxNy0xTkVXX0F0aGVyb0V4cHJlc3NEYXRhYmFzZV9TY2llbnRpZmljQUVfMjAxNzEzMDZfdjEuMC5zYXYiKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmltLmZhY3Rvci5uYW1lcyA9IFRSVUUsIHRyaW1fdmFsdWVzID0gVFJVRSwgIyB3ZSB0cmltIHNwYWNlcyBpbiB2YWx1ZXMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWVuY29kZSA9IFRSVUUsICMgd2UgcmUtZW5jb2RlIHRvIHRoZSBsb2NhbCBsb2NhbGUgZW5jb2RpbmcKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQudW5kZWNsYXJlZC5sZXZlbHMgPSAiYXBwZW5kIiwgIyB3ZSBkbyAqbm90KiB3YW50IHRvIGNvbnZlcnQgdG8gUi1mYWN0b3JzCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLnZhbHVlLmxhYmVscyA9IEZBTFNFLCAjIHdlIGRvICpub3QqIGNvbnZlcnQgdmFyaWFibGVzIHdpdGggdmFsdWUgbGFiZWxzIGludG8gUiBmYWN0b3JzCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLm1pc3NpbmdzID0gVFJVRSwgc3ViID0gIk5BIiwgIyB3ZSB3aWxsIHNldCBldmVyeSBtaXNzaW5nIHZhcmlhYmxlIHRvIE5BCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwbGljYXRlZC52YWx1ZS5sYWJlbHMgPSAiY29uZGVuc2UiLCAjIHdlIHdpbGwgY29uZGVuc2UgZHVwbGljYXRlZCB2YWx1ZSBsYWJlbHMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0by5kYXRhLmZyYW1lID0gVFJVRSkpCiMgQUVkYXRhLmxhYmVscyA8LSBhcy5kYXRhLnRhYmxlKGF0dHIoQUVkYXRhLCAidmFyaWFibGUubGFiZWxzIikpCiMgbmFtZXMoQUVkYXRhLmxhYmVscykgPC0gIlZhcmlhYmxlIgoKIyBNRVRIT0QgMjogVXNpbmcgbGlicmFyeSgiaGF2ZW4iKSBpbXBvcnRpbmcgc2VlbXMgZmxhd2xlc3M7IGJlc3QgYXJndW1lbnQgYmVpbmc6CiMgICAgICAgICAgIHdlIGV4cGVjdCAzLDUyNyBzYW1wbGVzIGFuZCA4ODggdmFyaWFibGVzLCB3aGljaCBpcyB3aGF0IHlvdSdkIGdldCB3aXRoIHRoaXMgbWV0aG9kCiMgICAgICAgICAgIFNvIGZvciBub3csIE1FVEhPRCAyIGlzIHByZWZlcmVkLiAKIyAgICAgICAgICAgIApyZXF1aXJlKGhhdmVuKQoKIyBBRURCIDwtIGhhdmVuOjpyZWFkX3NhdihwYXN0ZTAoQUVEQl9sb2MsICIvMjAyMl8xX05FV19BdGhlcm9FeHByZXNzRGF0YWJhc2VfU2NpZW50aWZpY0FFXzE1LTAyLTIwMjIuc2F2IikpICMgc29tZXRoaW5nIHdyb25nIHdpdGggQWdlLXZhcmlhYmxlCiMgQUVEQiA8LSBoYXZlbjo6cmVhZF9zYXYocGFzdGUwKEFFREJfbG9jLCAiLzIwMjBfMV9ORVdfQXRoZXJvRXhwcmVzc0RhdGFiYXNlX1NjaWVudGlmaWNBRV8zMC0wOS0yMDIwLnNhdiIpKSAjIGR1cGxpY2F0ZSBzdHVkeW51bWJlcnMgaW4gaXQKQUVEQiA8LSBoYXZlbjo6cmVhZF9zYXYocGFzdGUwKEFFREJfbG9jLCAiLzIwMjBfMV9ORVdfQXRoZXJvRXhwcmVzc0RhdGFiYXNlX1NjaWVudGlmaWNBRV8xNi0wMy0yMDIwLnNhdiIpKQoKIyB3cml0aW5nIG9mZiB0aGUgU1BTUyBkYXRhIHRvIGFuIEV4Y2VsLgojIGZ3cml0ZShBRWRhdGEsIGZpbGUgPSBwYXN0ZTAoSU5QX2xvYywiLzIwMTctMU5FV19BdGhlcm9FeHByZXNzRGF0YWJhc2VfU2NpZW50aWZpY0FFXzIwMTcxMzA2X3YxLjAudmFsdWVzLnhsc3giKSwgCiMgICAgICAgIHNlcCA9ICI7IiwgbmEgPSAiTkEiLCBkZWMgPSAiLiIsIGNvbC5uYW1lcyA9IFRSVUUsIHJvdy5uYW1lcyA9IEZBTFNFLAojICAgICAgICBkYXRlVGltZUFzID0gIklTTyIsIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQojIHdhcm5pbmdzKCkKCkFFREJbMToxMCwgMToxMF0KZGltKEFFREIpCgpgYGAKCgoKPCEtLSAjIyBFeGFtaW5lIEFFREIgLS0+Cgo8IS0tIFdlIGNhbiBleGFtaW5lIHRoZSBjb250ZW50cyBvZiB0aGUgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBkYXRhc2V0IHRvIGtub3cgd2hhdCBlYWNoIHZhcmlhYmxlIGlzIGNhbGxlZCwgd2hhdCBjbGFzcyAtLT4KPCEtLSAodHlwZSkgaXQgaGFzLCBhbmQgd2hhdCB0aGUgdmFyaWFibGUgZGVzY3JpcHRpb24gaXMuIC0tPgoKPCEtLSBUaGVyZSBpcyBhbiBleGNlbGxlbnQgcG9zdCBvbiB0aGlzOiA8aHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vd29ya2luZy13aXRoLXNwc3MtbGFiZWxzLWluLXIvPi4gLS0+Cgo8IS0tIGBgYHtyIEFFREI6IGRlc2NyaWJlfSAtLT4KPCEtLSBBRURCICU+JSBzalBsb3Q6OnZpZXdfZGYoc2hvdy50eXBlID0gVFJVRSwgLS0+CjwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cuZnJxID0gVFJVRSwgLS0+CjwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cucHJjID0gVFJVRSwgLS0+CjwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubmEgPSBUUlVFLCAgLS0+CjwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgIG1heC5sZW4gPSBUUlVFLCAgLS0+CjwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgIHdyYXAubGFiZWxzID0gMjAsIC0tPgo8IS0tICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsICAtLT4KPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLnZpZXdlciA9IEZBTFNFLCAtLT4KPCEtLSAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFREIuZGljdGlvbmFyeS5odG1sIikpICAtLT4KPCEtLSBgYGAgLS0+CgojIyBGaXhpbmcgYW5kIGNyZWF0aW5nIHZhcmlhYmxlcwoKV2UgaGF2ZSB0byBmaXggY2VydGFpbiBjbGluaWNhbCBwYXJhbWV0ZXJzOgoKLSAgIHN5bXB0b21zCi0gICBkaWFiZXRlcwotICAgYWxjb2hvbCB1c2UKLSAgIHNtb2tpbmcKLSAgIHBsYXF1ZSBwaGVub3R5cGVzCgojIyMgU3ltcHRvbXMKCldlIG5lZWQgdG8gYmUgdmVyeSBzdHJpY3QgaW4gZGVmaW5pbmcgKnN5bXB0b21zLiogVGhlcmVmb3JlIHdlIHdpbGwgZml4IGEgbmV3CnZhcmlhYmxlIHRoYXQgZ3JvdXBzICpzeW1wdG9tcyogYXQgaW5jbHVzaW9uLgoKQ29kaW5nIG9mICpzeW1wdG9tcyogaXMgYXMgZm9sbG93czoKCi0gICBtaXNzaW5nIC05OTkKLSAgIEFzeW1wdG9tYXRpYyAwCi0gICBUSUEgMQotICAgbWlub3Igc3Ryb2tlIDIKLSAgIE1ham9yIHN0cm9rZSAzCi0gICBBbWF1cm9zaXMgZnVnYXggNAotICAgRm91ciB2ZXNzZWwgZGlzZWFzZSA1Ci0gICBWZXJ0ZWJyb2Jhc2lsYXJ5IFRJQSA3Ci0gICBSZXRpbmFsIGluZmFyY3Rpb24gOAotICAgU3ltcHRvbWF0aWMsIGJ1dCBhc3BlY2lmaWMgc3ltdG9tcyA5Ci0gICBDb250cmFsYXRlcmFsIHN5bXB0b21hdGljIG9jY2x1c2lvbiAxMAotICAgcmV0aW5hbCBpbmZhcmN0aW9uIDExCi0gICBhcm1jbGF1ZGljYXRpb24gZHVlIHRvIG9jY2x1c2lvbiBzdWJjbGF2aWFuIGFydGVyeSwgQ0VBIG5lZWRlZCBmb3IgYnlwYXNzCiAgICAxMgotICAgcmV0aW5hbCBpbmZhcmN0aW9uICsgVElBcyAxMwotICAgT2N1bGFyIGlzY2hlbWljIHN5bmRyb21lIDE0Ci0gICBpc2NoZW1pc2NoIGdsYXVjb29tIDE1Ci0gICBzdWJjbGF2aWFuIHN0ZWFsIHN5bmRyb21lIDE2Ci0gICBUR0EgMTcKCldlIHdpbGwgZ3JvdXAgYXMgZm9sbG93czoKCjEuICBBc3ltcHRvbWF0aWMgPiAwCjIuICBUSUEgPiAxLCA3LCAxMwozLiAgU3Ryb2tlID4gMiwgMwo0LiAgT2N1bGFyID4gNCwgMTQsIDE1CjUuICBSZXRpbmFsIGluZmFyY3Rpb24gPiA4LCAxMQo2LiAgT3RoZXIgPiA1LCA5LCAxMCwgMTIsIDE2LCAxNwoKYGBge3IgRml4U3ltcHRvbXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIEZpeCBzeW1wdG9tcwoKYXR0YWNoKEFFREIpCkFFREJbLCJTeW1wdG9tcy41RyJdIDwtIE5BCkFFREIkU3ltcHRvbXMuNUdbc3ltcHQgPT0gMF0gPC0gIkFzeW1wdG9tYXRpYyIKQUVEQiRTeW1wdG9tcy41R1tzeW1wdCA9PSAxIHwgc3ltcHQgPT0gNyB8IHN5bXB0ID09IDEzXSA8LSAiVElBIgpBRURCJFN5bXB0b21zLjVHW3N5bXB0ID09IDIgfCBzeW1wdCA9PSAzXSA8LSAiU3Ryb2tlIgpBRURCJFN5bXB0b21zLjVHW3N5bXB0ID09IDQgfCBzeW1wdCA9PSAxNCB8IHN5bXB0ID09IDE1IF0gPC0gIk9jdWxhciIKQUVEQiRTeW1wdG9tcy41R1tzeW1wdCA9PSA4IHwgc3ltcHQgPT0gMTFdIDwtICJSZXRpbmFsIGluZmFyY3Rpb24iCkFFREIkU3ltcHRvbXMuNUdbc3ltcHQgPT0gNSB8IHN5bXB0ID09IDkgfCBzeW1wdCA9PSAxMCB8IHN5bXB0ID09IDEyIHwgc3ltcHQgPT0gMTYgfCBzeW1wdCA9PSAxN10gPC0gIk90aGVyIgoKCiMgQXN5bXB0U3ltcHQKQUVEQlssIkFzeW1wdFN5bXB0Il0gPC0gTkEKQUVEQiRBc3ltcHRTeW1wdFtzeW1wdCA9PSAtOTk5XSA8LSBOQQpBRURCJEFzeW1wdFN5bXB0W3N5bXB0ID09IDBdIDwtICJBc3ltcHRvbWF0aWMiCkFFREIkQXN5bXB0U3ltcHRbc3ltcHQgPT0gMSB8IHN5bXB0ID09IDcgfCBzeW1wdCA9PSAxMyB8IHN5bXB0ID09IDIgfCBzeW1wdCA9PSAzXSA8LSAiU3ltcHRvbWF0aWMiCkFFREIkQXN5bXB0U3ltcHRbc3ltcHQgPT0gNCB8IHN5bXB0ID09IDE0IHwgc3ltcHQgPT0gMTUgfCBzeW1wdCA9PSA4IHwgc3ltcHQgPT0gMTEgfCBzeW1wdCA9PSA1IHwgc3ltcHQgPT0gOSB8IHN5bXB0ID09IDEwIHwgc3ltcHQgPT0gMTIgfCBzeW1wdCA9PSAxNiB8IHN5bXB0ID09IDE3XSA8LSAiT2N1bGFyIGFuZCBvdGhlcnMiCgojIEFzeW1wdFN5bXB0CkFFREJbLCJBc3ltcHRTeW1wdDJHIl0gPC0gTkEKQUVEQiRBc3ltcHRTeW1wdDJHW3N5bXB0ID09IC05OTldIDwtIE5BCkFFREIkQXN5bXB0U3ltcHQyR1tzeW1wdCA9PSAwXSA8LSAiQXN5bXB0b21hdGljIgpBRURCJEFzeW1wdFN5bXB0Mkdbc3ltcHQgPT0gMSB8IHN5bXB0ID09IDcgfCBzeW1wdCA9PSAxMyB8IHN5bXB0ID09IDIgfCBzeW1wdCA9PSAzIHwgc3ltcHQgPT0gNCB8IHN5bXB0ID09IDE0IHwgc3ltcHQgPT0gMTUgfCBzeW1wdCA9PSA4IHwgc3ltcHQgPT0gMTEgfCBzeW1wdCA9PSA1IHwgc3ltcHQgPT0gOSB8IHN5bXB0ID09IDEwIHwgc3ltcHQgPT0gMTIgfCBzeW1wdCA9PSAxNiB8IHN5bXB0ID09IDE3XSA8LSAiU3ltcHRvbWF0aWMiCgpkZXRhY2goQUVEQikKCiMgdGFibGUoQUVEQiRzeW1wdCwgdXNlTkEgPSAiaWZhbnkiKQojIHRhYmxlKEFFREIkQXN5bXB0U3ltcHQyRywgdXNlTkEgPSAiaWZhbnkiKQojIHRhYmxlKEFFREIkU3ltcHRvbXMuNUcsIHVzZU5BID0gImlmYW55IikKIyAKIyB0YWJsZShBRURCJEFzeW1wdFN5bXB0MkcsIEFFREIkc3ltcHQsIHVzZU5BID0gImlmYW55IikKIyB0YWJsZShBRURCJFN5bXB0b21zLjVHLCBBRURCJHN5bXB0LCB1c2VOQSA9ICJpZmFueSIpCnRhYmxlKEFFREIkQXN5bXB0U3ltcHQyRywgQUVEQiRTeW1wdG9tcy41RywgdXNlTkEgPSAiaWZhbnkiKQoKIyBBRURCLnRlbXAgPC0gc3Vic2V0KEFFREIsICBzZWxlY3QgPSBjKCJTVFVEWV9OVU1CRVIiLCAiVVBJRCIsICJBZ2UiLCAiR2VuZGVyIiwgIkhvc3BpdGFsIiwgIkFydGVyeV9zdW1tYXJ5IiwgInN5bXB0IiwgIlN5bXB0b21zLjVHIiwgIkFzeW1wdFN5bXB0IikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgdGFibGUoQUVEQi50ZW1wJFN5bXB0b21zLjVHLCBBRURCLnRlbXAkQXN5bXB0U3ltcHQpCiMgCiMgcm0oQUVEQi50ZW1wKQpgYGAKCiMjIyBSZS1hc3Nlc3NlZCBzeW1wdG9tcwoKV2UgcmUtYXNzZXNzZWQgdGhlIGNhdGVnb3JpemF0aW9uIG9mIHN5bXB0b21zLiBUaGVzZSBhcmUgc3VtbWFyaXplZCBhbmQgcGFyc2VkCmluIHRoaXMgc2VjdGlvbi4KCkxhYmVsaW5nIG9mIG5ldyBzeW1wdG9tIGNhdGVnb3JpZXMuCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1UUlVFfQoKQUVEQiRpbmRleHN5bXB0b21zX3dvcnN0CkFFREIkaW5kZXhzeW1wdG9tc193b3JzdF80ZwpBRURCJGluZGV4c3ltcHRvbXNfbGF0ZXN0CkFFREIkaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcKCmBgYAoKR2V0dGluZyBjb3VudHMgZm9yIGVhY2ggb2YgdGhlIG1vc3QgaW1wb3J0YW50IGNhdGVnb3JpZXMuCgpgYGB7cn0KY2F0KCJOZXcgJ3dvcnN0JyB2cyAnbGF0ZXN0JyBzeW1wdG9tIGNhdGVnb3JpZXMuXG4iKQp0YWJsZShhc19mYWN0b3IoQUVEQiRpbmRleHN5bXB0b21zX3dvcnN0XzRnKSwgYXNfZmFjdG9yKEFFREIkaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcpKQoKY2F0KCJcbk5ldyAnd29yc3QnIHN5bXB0b20gY2F0ZWdvcmllcy5cbiIpCnRhYmxlKChBRURCJGluZGV4c3ltcHRvbXNfd29yc3RfNGcpKQoKY2F0KCJcbk5ldyAnbGF0ZXN0JyBzeW1wdG9tIGNhdGVnb3JpZXMuXG4iKQp0YWJsZShhc19mYWN0b3IoQUVEQiRpbmRleHN5bXB0b21zX2xhdGVzdF80ZykpCmBgYAoKQ29tcGFyaW5nIHdpdGggdGhlIG9yaWdpbmFsIHN5bXB0b20gY2F0ZWdvcmllcy4KCmBgYHtyfQpjYXQoIk5ldyAnbGF0ZXN0JyB2cyBvcmlnaW5hbCBzeW1wdG9tIDJHIGNhdGVnb3JpZXMuXG4iKQp0YWJsZSgoQUVEQiRpbmRleHN5bXB0b21zX2xhdGVzdF80ZyksIEFFREIkQXN5bXB0U3ltcHQyRykKCmNhdCgiXG5OZXcgJ2xhdGVzdCcgdnMgb3JpZ2luYWwgc3ltcHRvbSA1RyBjYXRlZ29yaWVzLlxuIikKdGFibGUoKEFFREIkaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcpLCBBRURCJFN5bXB0b21zLjVHKQogICAKYGBgCgpXZSBuZWVkIHRvIGJlIHZlcnkgc3RyaWN0IGluIGRlZmluaW5nICpzeW1wdG9tcy4qIFRoZXJlZm9yZSB3ZSB3aWxsIGZpeCBhIG5ldwp2YXJpYWJsZSB0aGF0IGdyb3VwcyAqc3ltcHRvbXMqIGF0IGluY2x1c2lvbi4KCkNvZGluZyBvZiAqc3ltcHRvbXMqIGlzIGFzIGZvbGxvd3M6CgotICAgYXN5bXB0IDBcCi0gICBvY3VsYXIgMVwKLSAgIFRJQSAyXAotICAgc3Ryb2tlIDNcCi0gICB1bmNsZWFyIDkKCldlIHdpbGwgZ3JvdXAgYXMgZm9sbG93czoKCjEuICBBc3ltcHRvbWF0aWMgPiAwCjIuICBTeW1wdG9tYXRpYyA+IDEsIDIsIDMKMy4gIE5BID4gOQoKYGBge3IgRml4TmV3U3ltcHRvbXN9CgojIEZpeCBzeW1wdG9tcwphdHRhY2goQUVEQikKCiMgU3ltcHRvbXMuVXBkYXRlMkcKQUVEQlssIlN5bXB0b21zLlVwZGF0ZTJHIl0gPC0gTkEKQUVEQiRTeW1wdG9tcy5VcGRhdGUyR1tpbmRleHN5bXB0b21zX2xhdGVzdF80ZyA9PSAwXSA8LSAiQXN5bXB0b21hdGljIgpBRURCJFN5bXB0b21zLlVwZGF0ZTJHW2luZGV4c3ltcHRvbXNfbGF0ZXN0XzRnID09IDEgfCBpbmRleHN5bXB0b21zX2xhdGVzdF80ZyA9PSAyIHwgaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcgPT0gM10gPC0gIlN5bXB0b21hdGljIgpBRURCJFN5bXB0b21zLlVwZGF0ZTJHW2luZGV4c3ltcHRvbXNfbGF0ZXN0XzRnID09IDkgXSA8LSBOQQoKIyBTeW1wdG9tcy5VcGRhdGUzRwpBRURCWywiU3ltcHRvbXMuVXBkYXRlM0ciXSA8LSBOQQpBRURCJFN5bXB0b21zLlVwZGF0ZTNHW2luZGV4c3ltcHRvbXNfbGF0ZXN0XzRnID09IDBdIDwtICJBc3ltcHRvbWF0aWMiCkFFREIkU3ltcHRvbXMuVXBkYXRlM0dbaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcgPT0gMSB8IGluZGV4c3ltcHRvbXNfbGF0ZXN0XzRnID09IDIgfCBpbmRleHN5bXB0b21zX2xhdGVzdF80ZyA9PSAzXSA8LSAiU3ltcHRvbWF0aWMiCkFFREIkU3ltcHRvbXMuVXBkYXRlM0dbaW5kZXhzeW1wdG9tc19sYXRlc3RfNGcgPT0gOSBdIDwtICJVbmNsZWFyIgoKZGV0YWNoKEFFREIpCgp0YWJsZShBRURCJFN5bXB0b21zLlVwZGF0ZTJHLCBBRURCJFN5bXB0b21zLjVHLCB1c2VOQSA9ICJpZmFueSIpCnRhYmxlKEFFREIkU3ltcHRvbXMuVXBkYXRlM0csIEFFREIkU3ltcHRvbXMuNUcsIHVzZU5BID0gImlmYW55IikKCmBgYAoKIyMjIE90aGVyIGNsaW5pY2FsIGNoYXJhY3RlcmlzdGljcwoKV2Ugd2lsbCBhbHNvIGZpeCB0aGUgKmRpYWJldGVzKiBzdGF0dXMgdmFyaWFibGUuCgpgYGB7ciBGaXhEaWFiZXRlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgRml4IGRpYWJldGVzCmF0dGFjaChBRURCKQpBRURCWywiRGlhYmV0ZXNTdGF0dXMiXSA8LSBOQQpBRURCJERpYWJldGVzU3RhdHVzW0RNLmNvbXBvc2l0ZSA9PSAtOTk5XSA8LSBOQQpBRURCJERpYWJldGVzU3RhdHVzW0RNLmNvbXBvc2l0ZSA9PSAwXSA8LSAiQ29udHJvbCAobm8gRGlhYmV0ZXMgRHgvTWVkKSIKQUVEQiREaWFiZXRlc1N0YXR1c1tETS5jb21wb3NpdGUgPT0gMV0gPC0gIkRpYWJldGVzIgpkZXRhY2goQUVEQikKCnRhYmxlKEFFREIkRE0uY29tcG9zaXRlLCBBRURCJERpYWJldGVzU3RhdHVzKQojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiRE0uY29tcG9zaXRlIiwgIkRpYWJldGVzU3RhdHVzIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIEFFREIudGVtcCREaWFiZXRlc1N0YXR1cyA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJERpYWJldGVzU3RhdHVzKQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKYGBgCgpXZSB3aWxsIGFsc28gZml4IHRoZSAqc21va2luZyogc3RhdHVzIHZhcmlhYmxlLiBXZSBhcmUgaW50ZXJlc3RlZCBpbiB3aGV0aGVyCnNvbWVvbmUgbmV2ZXIsIGV2ZXIgb3IgaXMgY3VycmVudGx5IChhdCB0aGUgdGltZSBvZiBpbmNsdXNpb24pIHNtb2tpbmcuIFRoaXMgaXMKYmFzZWQgb24gdGhlIHF1ZXN0aW9ubmFpcmUuCgotICAgYGRpZXQ4MDFgOiBhcmUgeW91IGEgc21va2VyPwotICAgYGRpZXQ4MDJgOiBkaWQgeW91IHNtb2tlIGluIHRoZSBwYXN0PwoKV2UgYWxyZWFkeSBoYXZlIHNvbWUgdmFyaWFibGVzIGluZGljYXRpbmcgc21va2luZyBzdGF0dXM6CgotICAgYFNtb2tpbmdSZXBvcnRlZGA6IHBhdGllbnQgaGFzIHJlcG9ydGVkIHRvIHNtb2tlLgotICAgYFNtb2tpbmdZZWFyT1JgOiBzbW9raW5nIGluIHRoZSB5ZWFyIG9mIHN1cmdlcnk/Ci0gICBgU21va2VyQ3VycmVudGA6IGN1cnJlbnRseSBzbW9raW5nPwoKYGBge3IgRml4U21va2luZywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcmVxdWlyZShsYWJlbGxlZCkKQUVEQiRkaWV0ODAxIDwtIHRvX2ZhY3RvcihBRURCJGRpZXQ4MDEpCkFFREIkZGlldDgwMiA8LSB0b19mYWN0b3IoQUVEQiRkaWV0ODAyKQpBRURCJGRpZXQ4MDUgPC0gdG9fZmFjdG9yKEFFREIkZGlldDgwNSkKQUVEQiRTbW9raW5nUmVwb3J0ZWQgPC0gdG9fZmFjdG9yKEFFREIkU21va2luZ1JlcG9ydGVkKQpBRURCJFNtb2tlckN1cnJlbnQgPC0gdG9fZmFjdG9yKEFFREIkU21va2VyQ3VycmVudCkKQUVEQiRTbW9raW5nWWVhck9SIDwtIHRvX2ZhY3RvcihBRURCJFNtb2tpbmdZZWFyT1IpCgojIHRhYmxlKEFFREIkZGlldDgwMSkKIyB0YWJsZShBRURCJGRpZXQ4MDIpCiMgdGFibGUoQUVEQiRTbW9raW5nUmVwb3J0ZWQpCiMgdGFibGUoQUVEQiRTbW9rZXJDdXJyZW50KQojIHRhYmxlKEFFREIkU21va2luZ1llYXJPUikKIyB0YWJsZShBRURCJFNtb2tpbmdSZXBvcnRlZCwgQUVEQiRTbW9rZXJDdXJyZW50LCB1c2VOQSA9ICJpZmFueSIsIGRubiA9IGMoIlJlcG9ydGVkIHNtb2tpbmciLCAiQ3VycmVudCBzbW9rZXIiKSkKIyAKIyB0YWJsZShBRURCJGRpZXQ4MDEsIEFFREIkZGlldDgwMiwgdXNlTkEgPSAiaWZhbnkiLCBkbm4gPSBjKCJTbW9rZXIiLCAiUGFzdCBzbW9rZXIiKSkKCmNhdCgiXG5GaXhpbmcgc21va2luZyBzdGF0dXMuXG4iKQphdHRhY2goQUVEQikKQUVEQlssIlNtb2tlclN0YXR1cyJdIDwtIE5BCkFFREIkU21va2VyU3RhdHVzW2RpZXQ4MDIgPT0gImRvbid0IGtub3ciXSA8LSAiTmV2ZXIgc21va2VkIgpBRURCJFNtb2tlclN0YXR1c1tkaWV0ODAyID09ICJJIHN0aWxsIHNtb2tlIl0gPC0gIkN1cnJlbnQgc21va2VyIgpBRURCJFNtb2tlclN0YXR1c1tTbW9rZXJDdXJyZW50ID09ICJubyIgJiBkaWV0ODAyID09ICJubyJdIDwtICJOZXZlciBzbW9rZWQiCkFFREIkU21va2VyU3RhdHVzW1Ntb2tlckN1cnJlbnQgPT0gIm5vIiAmIGRpZXQ4MDIgPT0gInllcyJdIDwtICJFeC1zbW9rZXIiCkFFREIkU21va2VyU3RhdHVzW1Ntb2tlckN1cnJlbnQgPT0gInllcyJdIDwtICJDdXJyZW50IHNtb2tlciIKQUVEQiRTbW9rZXJTdGF0dXNbU21va2VyQ3VycmVudCA9PSAibm8gZGF0YSBhdmFpbGFibGUvbWlzc2luZyJdIDwtIE5BCiMgQUVEQiRTbW9rZXJTdGF0dXNbaXMubmEoU21va2VyQ3VycmVudCldIDwtICJOZXZlciBzbW9rZWQiCmRldGFjaChBRURCKQoKY2F0KCJcbiogQ3VycmVudCBzbW9raW5nIHN0YXR1cy5cbiIpCnRhYmxlKEFFREIkU21va2VyQ3VycmVudCwKICAgICAgdXNlTkEgPSAiaWZhbnkiLCAKICAgICAgZG5uID0gYygiQ3VycmVudCBzbW9rZXIiKSkKCmNhdCgiXG4qIFVwZGF0ZWQgc21va2luZyBzdGF0dXMuXG4iKQp0YWJsZShBRURCJFNtb2tlclN0YXR1cywKICAgICAgdXNlTkEgPSAiaWZhbnkiLCAKICAgICAgZG5uID0gYygiVXBkYXRlZCBzbW9raW5nIHN0YXR1cyIpKQoKY2F0KCJcbiogQ29tcGFyaW5nIHRvICdTbW9rZXJDdXJyZW50Jy5cbiIpCnRhYmxlKEFFREIkU21va2VyU3RhdHVzLCBBRURCJFNtb2tlckN1cnJlbnQsIAogICAgICB1c2VOQSA9ICJpZmFueSIsIAogICAgICBkbm4gPSBjKCJVcGRhdGVkIHNtb2tpbmcgc3RhdHVzIiwgIkN1cnJlbnQgc21va2VyIikpCgojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiRE0uY29tcG9zaXRlIiwgIkRpYWJldGVzU3RhdHVzIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIEFFREIudGVtcCREaWFiZXRlc1N0YXR1cyA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJERpYWJldGVzU3RhdHVzKQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKCmBgYAoKV2Ugd2lsbCBhbHNvIGZpeCB0aGUgKmFsY29ob2wqIHN0YXR1cyB2YXJpYWJsZS4KCmBgYHtyIEZpeEFsY29ob2wsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIEZpeCBkaWFiZXRlcwphdHRhY2goQUVEQikKQUVEQlssIkFsY29ob2xVc2UiXSA8LSBOQQpBRURCJEFsY29ob2xVc2VbZGlldDgxMCA9PSAtOTk5XSA8LSBOQQpBRURCJEFsY29ob2xVc2VbZGlldDgxMCA9PSAwXSA8LSAiTm8iCkFFREIkQWxjb2hvbFVzZVtkaWV0ODEwID09IDFdIDwtICJZZXMiCmRldGFjaChBRURCKQoKIyBBRURCLnRlbXAgPC0gc3Vic2V0KEFFREIsICBzZWxlY3QgPSBjKCJTVFVEWV9OVU1CRVIiLCAiVVBJRCIsICJBZ2UiLCAiR2VuZGVyIiwgIkhvc3BpdGFsIiwgIkFydGVyeV9zdW1tYXJ5IiwgImRpZXQ4MTAiLCAiQWxjb2hvbFVzZSIpKQojIHJlcXVpcmUobGFiZWxsZWQpCiMgQUVEQi50ZW1wJEdlbmRlciA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEdlbmRlcikKIyBBRURCLnRlbXAkSG9zcGl0YWwgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRIb3NwaXRhbCkKIyBBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSkKIyBBRURCLnRlbXAkQWxjb2hvbFVzZSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFsY29ob2xVc2UpCiMgCiMgRFQ6OmRhdGF0YWJsZShBRURCLnRlbXBbMToxMCxdLCBjYXB0aW9uID0gIkV4Y2VycHQgb2YgdGhlIHdob2xlIEFFREIuIiwgcm93bmFtZXMgPSBGQUxTRSkKIyAKIyBybShBRURCLnRlbXApCgoKYGBgCgpXZSB3aWxsIGFsc28gZml4IGEgaGlzdG9yeSBvZiBDQUQsIHN0cm9rZSBvciBwZXJpcGhlcmFsIGludGVydmVudGlvbiBzdGF0dXMgdmFyaWFibGUuIFRoaXMgd2lsbCBiZSBiYXNlZCBvbiBgQ0FEX2hpc3RvcnlgLCBgU3Ryb2tlX2hpc3RvcnlgLCBhbmQgYFBlcmlwaGVyYWwuaW50ZXJ2YAoKYGBge3IgRml4Q0FEX0hpc3RvcnksIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIEZpeCBkaWFiZXRlcwphdHRhY2goQUVEQikKQUVEQlssIk1lZEh4X0NWRCJdIDwtIE5BCkFFREIkTWVkSHhfQ1ZEW0NBRF9oaXN0b3J5ID09IDAgfCBTdHJva2VfaGlzdG9yeSA9PSAwIHwgUGVyaXBoZXJhbC5pbnRlcnYgPT0gMF0gPC0gIk5vIgpBRURCJE1lZEh4X0NWRFtDQURfaGlzdG9yeSA9PSAxIHwgU3Ryb2tlX2hpc3RvcnkgPT0gMSB8IFBlcmlwaGVyYWwuaW50ZXJ2ID09IDFdIDwtICJ5ZXMiCmRldGFjaChBRURCKQoKdGFibGUoQUVEQiRDQURfaGlzdG9yeSkKdGFibGUoQUVEQiRTdHJva2VfaGlzdG9yeSkKdGFibGUoQUVEQiRQZXJpcGhlcmFsLmludGVydikKdGFibGUoQUVEQiRNZWRIeF9DVkQpCgojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiZGlldDgxMCIsICJBbGNvaG9sVXNlIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIEFFREIudGVtcCRBbGNvaG9sVXNlIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkQWxjb2hvbFVzZSkKIyAKIyBEVDo6ZGF0YXRhYmxlKEFFREIudGVtcFsxOjEwLF0sIGNhcHRpb24gPSAiRXhjZXJwdCBvZiB0aGUgd2hvbGUgQUVEQi4iLCByb3duYW1lcyA9IEZBTFNFKQojIAojIHJtKEFFREIudGVtcCkKCgpgYGAKCiMjIyBQbGFxdWUgcGhlbm90eXBlcwoKV2Ugd2lsbCBhbHNvIGZpeCB0aGUgKnBsYXF1ZXBoZW5vdHlwZXMqIHZhcmlhYmxlLgoKQ29kaW5nIG9mIHN5bXB0b21zIGlzIGFzIGZvbGxvd3M6CgotICAgbWlzc2luZyAtOTk5XAotICAgbm90IHJlbGV2YW50IC04ODgKLSAgIGZpYnJvdXMgMVwKLSAgIGZpYnJvYXRoZXJvbWF0b3VzIDJcCi0gICBhdGhlcm9tYXRvdXMgMwoKYGBge3IgRml4UGxhcXVlUGhlbm90eXBlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgRml4IHBsYXF1ZXBoZW5vdHlwZXMKYXR0YWNoKEFFREIpCkFFREJbLCJPdmVyYWxsUGxhcXVlUGhlbm90eXBlIl0gPC0gTkEKQUVEQiRPdmVyYWxsUGxhcXVlUGhlbm90eXBlW3BsYXF1ZXBoZW5vdHlwZSA9PSAtOTk5XSA8LSBOQQpBRURCJE92ZXJhbGxQbGFxdWVQaGVub3R5cGVbcGxhcXVlcGhlbm90eXBlID09IC05OTldIDwtIE5BCkFFREIkT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZVtwbGFxdWVwaGVub3R5cGUgPT0gMV0gPC0gImZpYnJvdXMiCkFFREIkT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZVtwbGFxdWVwaGVub3R5cGUgPT0gMl0gPC0gImZpYnJvYXRoZXJvbWF0b3VzIgpBRURCJE92ZXJhbGxQbGFxdWVQaGVub3R5cGVbcGxhcXVlcGhlbm90eXBlID09IDNdIDwtICJhdGhlcm9tYXRvdXMiCmRldGFjaChBRURCKQoKIyBBRURCLnRlbXAgPC0gc3Vic2V0KEFFREIsICBzZWxlY3QgPSBjKCJTVFVEWV9OVU1CRVIiLCAiVVBJRCIsICJBZ2UiLCAiR2VuZGVyIiwgIkhvc3BpdGFsIiwgIkFydGVyeV9zdW1tYXJ5IiwgInBsYXF1ZXBoZW5vdHlwZSIsICJPdmVyYWxsUGxhcXVlUGhlbm90eXBlIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKYGBgCgpXZSB3aWxsIGFsc28gZml4IGFuZCBpbnZlcnNlLXJhbmsgbm9ybWFsIHRyYW5zZm9ybSB0aGUgY29udGludW91cyAobWFudWFsbHkpCnNjb3JlZCBwbGFxdWUgcGhlbm90eXBlcy4KCmBgYHtyIElSTlQgUGxhcXVlUGhlbm90eXBlc30KQUVEQiRtYWNtZWFuMCA8LSBhcy5udW1lcmljKEFFREIkbWFjbWVhbjApCkFFREIkc21jbWVhbjAgPC0gYXMubnVtZXJpYyhBRURCJHNtY21lYW4wKQpBRURCJG5ldXRyb3BoaWxzIDwtIGFzLm51bWVyaWMoQUVEQiRuZXV0cm9waGlscykKQUVEQiRNYXN0X2NlbGxzX3BsYXF1ZSA8LSBhcy5udW1lcmljKEFFREIkTWFzdF9jZWxsc19wbGFxdWUpCkFFREIkdmVzc2VsX2RlbnNpdHlfYXZlcmFnZWQgPC0gYXMubnVtZXJpYyhBRURCJHZlc3NlbF9kZW5zaXR5X2F2ZXJhZ2VkKQoKQUVEQiRNQUNfcmFua05vcm0gPC0gcW5vcm0oKHJhbmsoQUVEQiRtYWNtZWFuMCwgbmEubGFzdCA9ICJrZWVwIikgLSAwLjUpIC8gc3VtKCFpcy5uYShBRURCJG1hY21lYW4wKSkpCkFFREIkU01DX3JhbmtOb3JtIDwtIHFub3JtKChyYW5rKEFFREIkc21jbWVhbjAsIG5hLmxhc3QgPSAia2VlcCIpIC0gMC41KSAvIHN1bSghaXMubmEoQUVEQiRzbWNtZWFuMCkpKQpBRURCJE5ldXRyb3BoaWxzX3JhbmtOb3JtIDwtIHFub3JtKChyYW5rKEFFREIkbmV1dHJvcGhpbHMsIG5hLmxhc3QgPSAia2VlcCIpIC0gMC41KSAvIHN1bSghaXMubmEoQUVEQiRuZXV0cm9waGlscykpKQpBRURCJE1hc3RDZWxsc19yYW5rTm9ybSA8LSBxbm9ybSgocmFuayhBRURCJE1hc3RfY2VsbHNfcGxhcXVlLCBuYS5sYXN0ID0gImtlZXAiKSAtIDAuNSkgLyBzdW0oIWlzLm5hKEFFREIkTWFzdF9jZWxsc19wbGFxdWUpKSkKQUVEQiRWZXNzZWxEZW5zaXR5X3JhbmtOb3JtIDwtIHFub3JtKChyYW5rKEFFREIkdmVzc2VsX2RlbnNpdHlfYXZlcmFnZWQsIG5hLmxhc3QgPSAia2VlcCIpIC0gMC41KSAvIHN1bSghaXMubmEoQUVEQiR2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZCkpKQoKYGBgCgpgYGB7ciBJUk5UIFBsYXF1ZVBoZW5vdHlwZXM6IFZpc3VhbGlzYXRpb259CmxpYnJhcnkobGFiZWxsZWQpCkFFREIkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCJEdlbmRlcikKbGlicmFyeShwYXRjaHdvcmspCgpwMSA8LSBnZ3B1YnI6OmdnaGlzdG9ncmFtKEFFREIsICJtYWNtZWFuMCIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiJSBvZiBtYWNyb3BoYWdlcyAoQ0Q2OCkiLAogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiJSBwZXIgcmVnaW9uIG9mIGludGVyZXN0IiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCnAyIDwtIGdncHVicjo6Z2doaXN0b2dyYW0oQUVEQiwgIk1BQ19yYW5rTm9ybSIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiJSBvZiBtYWNyb3BoYWdlcyAoQ0Q2OCkiLAogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIlIHBlciByZWdpb24gb2YgaW50ZXJlc3RcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpwMSB8IHAyIAoKcDEgPC0gZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAic21jbWVhbjAiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIiUgb2Ygc21vb3RoIG11c2NsZSBjZWxscyAoU01BKSIsCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIlIHBlciByZWdpb24gb2YgaW50ZXJlc3QiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKcDIgPC0gZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAiU01DX3JhbmtOb3JtIiwgCiAgICAgICAgICAgICAgICAgICAgIyB5ID0gIi4uY291bnQuLiIsIAogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgICBmaWxsID0gIkdlbmRlciIsCiAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMxMjkwRDkiLCAiI0RCMDAzRiIpLCAKICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVkaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgI2FkZF9kZW5zaXR5ID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICNhZGQucGFyYW1zID0gIGxpc3QoY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9IDIpLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICIlIG9mIHNtb290aCBtdXNjbGUgY2VsbHMgKFNNQSkiLAogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIlIHBlciByZWdpb24gb2YgaW50ZXJlc3RcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpwMSB8IHAyIAoKCnAxIDwtIGdncHVicjo6Z2doaXN0b2dyYW0oQUVEQiwgIm5ldXRyb3BoaWxzIiwgCiAgICAgICAgICAgICAgICAgICAgIyB5ID0gIi4uY291bnQuLiIsIAogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgICBmaWxsID0gIkdlbmRlciIsCiAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMxMjkwRDkiLCAiI0RCMDAzRiIpLCAKICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVkaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgI2FkZF9kZW5zaXR5ID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICNhZGQucGFyYW1zID0gIGxpc3QoY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9IDIpLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJudW1iZXIgb2YgbmV1dHJvcGhpbHMgKENENjZiKSIsCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJjb3VudHMgcGVyIHBsYXF1ZSIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpwMiA8LSBnZ3B1YnI6OmdnaGlzdG9ncmFtKEFFREIsICJOZXV0cm9waGlsc19yYW5rTm9ybSIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAibnVtYmVyIG9mIG5ldXRyb3BoaWxzIChDRDY2YikiLAogICAgICAgICAgICAgICAgICAgeGxhYiA9ICJjb3VudHMgcGVyIHBsYXF1ZVxuaW52ZXJzZS1yYW5rIG5vcm1hbGl6ZWQgbnVtYmVyIiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCnAxIHwgcDIgCgoKcDEgPC0gZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAiTWFzdF9jZWxsc19wbGFxdWUiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBtYXN0IGNlbGxzIiwKICAgICAgICAgICAgICAgICAgICB4bGFiID0gImNvdW50cyBwZXIgcGxhcXVlIiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCnAyIDwtIGdncHVicjo6Z2doaXN0b2dyYW0oQUVEQiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAibnVtYmVyIG9mIG1hc3QgY2VsbHMiLAogICAgICAgICAgICAgICAgICAgeGxhYiA9ICJjb3VudHMgcGVyIHBsYXF1ZVxuaW52ZXJzZS1yYW5rIG5vcm1hbGl6ZWQgbnVtYmVyIiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCnAxIHwgcDIgCgoKcDEgPC0gZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAidmVzc2VsX2RlbnNpdHlfYXZlcmFnZWQiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBpbnRyYXBsYXF1ZSBuZW92ZXNzZWxzIiwKICAgICAgICAgICAgICAgICAgICB4bGFiID0gImNvdW50cyBwZXIgMy00IGhvdHNwb3RzIiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCnAyIDwtIGdncHVicjo6Z2doaXN0b2dyYW0oQUVEQiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBpbnRyYXBsYXF1ZSBuZW92ZXNzZWxzIiwKICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiY291bnRzIHBlciAzLTQgaG90c3BvdHNcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpwMSB8IHAyIAoKcm0ocDEsIHAyKQpgYGAKCkhlcmUgd2UgY2FsY3VsYXRlIHRoZSAqcGxhcXVlIGluc3RhYmlsaXR5L3Z1bG5lcmFiaWxpdHkqIGluZGV4CgpgYGB7ciBQbGFxdWUgVnVsbmVyYWJpbGl0eX0KIyBQbGFxdWUgdnVsbmVyYWJpbGl0eQpyZXF1aXJlKGxhYmVsbGVkKQpBRURCJE1hY3JvcGhhZ2VzLmJpbiA8LSB0b19mYWN0b3IoQUVEQiRNYWNyb3BoYWdlcy5iaW4pCkFFREIkU01DLmJpbiA8LSB0b19mYWN0b3IoQUVEQiRTTUMuYmluKQpBRURCJElQSC5iaW4gPC0gdG9fZmFjdG9yKEFFREIkSVBILmJpbikKQUVEQiRDYWxjLmJpbiA8LSB0b19mYWN0b3IoQUVEQiRDYWxjLmJpbikKQUVEQiRDb2xsYWdlbi5iaW4gPC0gdG9fZmFjdG9yKEFFREIkQ29sbGFnZW4uYmluKQpBRURCJEZhdC5iaW5fMTAgPC0gdG9fZmFjdG9yKEFFREIkRmF0LmJpbl8xMCkKQUVEQiRGYXQuYmluXzQwIDwtIHRvX2ZhY3RvcihBRURCJEZhdC5iaW5fNDApCgp0YWJsZShBRURCJE1hY3JvcGhhZ2VzLmJpbikKdGFibGUoQUVEQiRGYXQuYmluXzEwKQp0YWJsZShBRURCJENvbGxhZ2VuLmJpbikKdGFibGUoQUVEQiRTTUMuYmluKQp0YWJsZShBRURCJElQSC5iaW4pCgojIFNQU1MgY29kZQoKIyAKIyAqKiogc3ludGF4LSBQbGFxdWUgdnVsbmVyYWJpbGl0eSoqLgojIENPTVBVVEUgTWFjcm9faW5zdGFiID0gLTk5OS4KIyBJRiBtYWNyb3BoYWdlcy5iaW49MiBNYWNyb19pbnN0YWI9MS4KIyBJRiBtYWNyb3BoYWdlcy5iaW49MSBNYWNyb19pbnN0YWI9MC4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgRmF0MTBfaW5zdGFiID0gLTk5OS4KIyBJRiBGYXQuYmluXzEwPTIgRmF0MTBfaW5zdGFiPTEuCiMgSUYgRmF0LmJpbl8xMD0xIEZhdDEwX2luc3RhYj0wLgojIEVYRUNVVEUuCiMgCiMgQ09NUFVURSBjb2xsX2luc3RhYj0tOTk5LgojIElGIENvbGxhZ2VuLmJpbj0yIGNvbGxfaW5zdGFiPTAuCiMgSUYgQ29sbGFnZW4uYmluPTEgY29sbF9pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIAojIENPTVBVVEUgU01DX2luc3RhYj0tOTk5LgojIElGIFNNQy5iaW49MiBTTUNfaW5zdGFiPTAuCiMgSUYgU01DLmJpbj0xIFNNQ19pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgSVBIX2luc3RhYj0tOTk5LgojIElGIElQSC5iaW49MCBJUEhfaW5zdGFiPTAuCiMgSUYgSVBILmJpbj0xIElQSF9pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgSW5zdGFiaWxpdHk9TWFjcm9faW5zdGFiICsgRmF0MTBfaW5zdGFiICsgIGNvbGxfaW5zdGFiICsgU01DX2luc3RhYiArIElQSF9pbnN0YWIuCiMgRVhFQ1VURS4KCiMgRml4IHBsYXF1ZXBoZW5vdHlwZXMKYXR0YWNoKEFFREIpCiMgbWFjIGluc3RhYmlsaXR5CkFFREJbLCJNQUNfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJE1BQ19JbnN0YWJpbGl0eVtNYWNyb3BoYWdlcy5iaW4gPT0gLTk5OV0gPC0gTkEKQUVEQiRNQUNfSW5zdGFiaWxpdHlbTWFjcm9waGFnZXMuYmluID09ICJuby9taW5vciJdIDwtIDAKQUVEQiRNQUNfSW5zdGFiaWxpdHlbTWFjcm9waGFnZXMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDEKCiMgZmF0IGluc3RhYmlsaXR5CkFFREJbLCJGQVQxMF9JbnN0YWJpbGl0eSJdIDwtIE5BCkFFREIkRkFUMTBfSW5zdGFiaWxpdHlbRmF0LmJpbl8xMCA9PSAtOTk5XSA8LSBOQQpBRURCJEZBVDEwX0luc3RhYmlsaXR5W0ZhdC5iaW5fMTAgPT0gIiA8MTAlIl0gPC0gMApBRURCJEZBVDEwX0luc3RhYmlsaXR5W0ZhdC5iaW5fMTAgPT0gIiA+MTAlIl0gPC0gMQoKIyBjb2wgaW5zdGFiaWxpdHkgCkFFREJbLCJDT0xfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJENPTF9JbnN0YWJpbGl0eVtDb2xsYWdlbi5iaW4gPT0gLTk5OV0gPC0gTkEKQUVEQiRDT0xfSW5zdGFiaWxpdHlbQ29sbGFnZW4uYmluID09ICJuby9taW5vciJdIDwtIDEKQUVEQiRDT0xfSW5zdGFiaWxpdHlbQ29sbGFnZW4uYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDAKCiMgc21jIGluc3RhYmlsaXR5CkFFREJbLCJTTUNfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJFNNQ19JbnN0YWJpbGl0eVtTTUMuYmluID09IC05OTldIDwtIE5BCkFFREIkU01DX0luc3RhYmlsaXR5W1NNQy5iaW4gPT0gIm5vL21pbm9yIl0gPC0gMQpBRURCJFNNQ19JbnN0YWJpbGl0eVtTTUMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDAKCiMgaXBoIGluc3RhYmlsaXR5CkFFREJbLCJJUEhfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJElQSF9JbnN0YWJpbGl0eVtJUEguYmluID09IC05OTldIDwtIE5BCkFFREIkSVBIX0luc3RhYmlsaXR5W0lQSC5iaW4gPT0gIm5vIl0gPC0gMApBRURCJElQSF9JbnN0YWJpbGl0eVtJUEguYmluID09ICJ5ZXMiXSA8LSAxCgpkZXRhY2goQUVEQikKCnRhYmxlKEFFREIkTUFDX0luc3RhYmlsaXR5LCB1c2VOQSA9ICJpZmFueSIpCnRhYmxlKEFFREIkRkFUMTBfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRDT0xfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRTTUNfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRJUEhfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKCiMgY3JlYXRpbmcgdnVsbmVyYWJpbGl0eSBpbmRleApBRURCIDwtIEFFREIgJT4lIG11dGF0ZShQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9IGZhY3Rvcihyb3dTdW1zKC5bZ3JlcCgiX0luc3RhYmlsaXR5IiwgbmFtZXMoLikpXSwgbmEucm0gPSBUUlVFKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKdGFibGUoQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCwgdXNlTkEgPSAiaWZhbnkiKQoKIyBzdHIoQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCkKCmBgYAoKIyMgUHJlcGFyZSBiYXNlbGluZSBzdW1tYXJ5CgpXZSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgZm9sbG93aW5nIHZhcmlhYmxlcyBhdCBiYXNlbGluZSBpbiB0aGUgd2hvbGUgY29ob3J0LgoKLSAgIEFnZSAoeWVhcnMpCi0gICBGZW1hbGUgc2V4IChOLCAlKQotICAgQXJ0ZXJ5IHR5cGUgKE4sICUpCi0gICBIb3NwaXRhbCAoTiwgJSkKPCEtLSAtICAgSHlwZXJ0ZW5zaW9uIChOLCAlKSAtLT4KPCEtLSAtICAgU0JQIChtbUhnKSAtLT4KPCEtLSAtICAgREJQIChtbUhnKSAtLT4KPCEtLSAtICAgRGlhYmV0ZXMgbWVsbGl0dXMgKE4sICUpIC0tPgo8IS0tIC0gICBUb3RhbCBjaG9sZXN0ZXJvbCBsZXZlbHMgKG1nL2RMKSAtLT4KPCEtLSAtICAgTERMIGNob2xlc3Rlcm9sIGxldmVscyAobWcvZEwpIC0tPgo8IS0tIC0gICBIREwgY2hvbGVzdGVyb2wgbGV2ZWxzIChtZy9kTCkgLS0+CjwhLS0gLSAgIFRyaWdseWNlcmlkZSBsZXZlbHMgKG1nL2RMKSAtLT4KPCEtLSAtICAgVXNlIG9mIHN0YXRpbnMgKE4sICUpIC0tPgo8IS0tIC0gICBVc2Ugb2YgYW50aXBsYXRlbGV0IGRydWdzIChOLCAlKSAtLT4KPCEtLSAtICAgQk1JIChrZy9twrIpIC0tPgo8IS0tIC0gICBTbW9raW5nIHN0YXR1cyAoTiwgJSkgLS0+CjwhLS0gICAgIC0gICBOZXZlciBzbW9rZXJzIC0tPgo8IS0tICAgICAtICAgRXgtc21va2VycyAtLT4KPCEtLSAgICAgLSAgIEN1cnJlbnQgc21va2VycyAtLT4KPCEtLSAtICAgSGlzdG9yeSBvZiBDQUQgKE4sICUpIC0tPgo8IS0tIC0gICBIaXN0b3J5IG9mIFBBRCAoTiwgJSkgLS0+CjwhLS0gLSAgIENsaW5pY2FsIG1hbmlmZXN0YXRpb25zIC0tPgo8IS0tICAgICAtICAgQXN5bXB0b21hdGljIC0tPgo8IS0tICAgICAtICAgQW1hdXJvc2lzIGZ1Z2F4IC0tPgo8IS0tICAgICAtICAgVElBIC0tPgo8IS0tICAgICAtICAgU3Ryb2tlIC0tPgo8IS0tIC0gICBlR0ZSIChtTC9taW4vMS43MyBtwrIpIC0tPgo8IS0tIC0gICBzdGVub3NpcyAtLT4KPCEtLSAtICAgeWVhciBvZiBzdXJnZXJ5IC0tPgo8IS0tIC0gICBwbGFxdWUgY2hhcmFjdGVyaXN0aWNzIC0tPgoKYGBge3IgQmFzZWxpbmUgQUVEQjogcHJlcGFyYXRpb259CmNhdCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIikKY2F0KCJTRUxFQ1RJT04gVEhFIFNISVpaTEVcbiIpCgojIyMgQXJ0ZXJ5IGxldmVscwojIEFFZGF0YSRBcnRlcnlfc3VtbWFyeTogCiMgICAgICAgICAgIHZhbHVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbAojIE5PVCBVU0UgLSAwIE5vIGFydGVyeSBrbm93biAoeWV0KSwgbm8gc3VyZ2VyeSAocGF0aWVudCBpbGwsIGRpZWQsIGV4aXRlZCBzdHVkeSksIHJlLW51bWJlcmVkIHRvIEFBQQojIFVTRSAtIDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJvdGlkIChsZWZ0ICYgcmlnaHQpCiMgVVNFIC0gMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVtb3JhbC9pbGlhYyAobGVmdCwgcmlnaHQgb3IgYm90aCBzaWRlcykKIyBOT1QgVVNFIC0gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXIgY2Fyb3RpZCBhcnRlcmllcyAoY29tbW9uLCBleHRlcm5hbCkKIyBOT1QgVVNFIC0gNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2Fyb3RpZCBieXBhc3MgYW5kIGluanVyeSAobGVmdCwgcmlnaHQgb3IgYm90aCBzaWRlcykKIyBOT1QgVVNFIC0gNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZXVyeXNtYXRhIChjYXJvdGlkICYgZmVtb3JhbCkKIyBOT1QgVVNFIC0gNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW9ydGEKIyBOT1QgVVNFIC0gNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXIgYXJ0ZXJpZXMgKHJlbmFsLCBwb3BsaXRlYWwsIHZlcnRlYnJhbCkKIyBOT1QgVVNFIC0gOCAgICAgICAgICAgICAgICAgICAgICAgIGZlbW9yYWwgYnlwYXNzLCBhbmdpb3NlYWwgYW5kIGluanVyeSAobGVmdCwgcmlnaHQgb3IgYm90aCBzaWRlcykKCiMjIyBBRWRhdGEkaW5mb3JtZWRjb25zZW50CiMgICAgICAgICAgIHZhbHVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsCiMgTk9UIFVTRSAtIC05OTkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3NpbmcKIyBOT1QgVVNFIC0gMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubywgZGllZAojIFVTRSAtIDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMKIyBVU0UgLSAyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlCiMgVVNFIC0gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gaGVhbHRoIHRyZWF0bWVudAojIFVTRSAtIDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBOT1QgVVNFIC0gNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHRpc3N1ZSwgbm8gY29tbWVyaWNhbCBidXNpbmVzcwojIE5PVCBVU0UgLSA2ICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIFVTRSAtIDggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHF1ZXN0aW9ubmFpcmVzLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUKIyBOT1QgVVNFIC0gOSAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyaWNhbCBidXNpbmVzcwojIFVTRSAtIDEwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgTk9UIFVTRSAtIDExIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gMTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQKIyBOT1QgVVNFIC0gMTMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQKIyBOT1QgVVNFIC0gMTQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMKIyBOT1QgVVNFIC0gMTUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUKIyBOT1QgVVNFIC0gMTYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUKIyBVU0UgLSAxNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gY29tbWVyaWNhbCBidXNpbmVzcwojIFVTRSAtIDE4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gMTkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSAyMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcwojIE5PVCBVU0UgLSAyMSAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbwojIE5PVCBVU0UgLSAyMiAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIFVTRSAtIDIzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gbWVkaWNhbCBpbmZvCiMgVVNFIC0gMjQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSAyNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbwojIFVTRSAtIDI2ICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcywgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gMjcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsICBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8KIyBOT1QgVVNFIC0gMjggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vLCBkb2Vzbid0IHdhbnQgdG8KIyBOT1QgVVNFIC0gMjkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubywgdW5hYmxlIHRvIHNpZ24KIyBOT1QgVVNFIC0gMzAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubywgbm8gcmVhY3Rpb24KIyBOT1QgVVNFIC0gMzEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm8sIGxvc3QKIyBOT1QgVVNFIC0gMzIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm8sIHRvbyBvbGQKIyBOT1QgVVNFIC0gMzQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gbWVkaWNhbCBpbmZvLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUKIyBOT1QgVVNFIC0gMzUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubyAobmV2ZXIgYXNrZWQgZm9yIElDIGJlY2F1c2UgdGhlcmUgd2FzIG5vIHRpc3N1ZSkKIyBVU0UgLSAzNiAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZQojIE5PVCBVU0UgLSAzNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vLCBlbmRwb2ludAojIFVTRSAtIDM4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsIG5pZXRzIGludnVsbGVuLCB3ZWwgYWxsZXMgZ2VicnVpa2VuCiMgVVNFIC0gMzkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kIGluZm9ybWVkIGNvbmNlbnRzOiB5ZXMsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBOT1QgVVNFIC0gNDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub29pdCBnZWluY2x1ZGVlcmQKCmNhdCgiLSBzYW5pdHkgY2hlY2tpbmcgUFJJT1IgdG8gc2VsZWN0aW9uIikKbGlicmFyeShkYXRhLnRhYmxlKQpyZXF1aXJlKGxhYmVsbGVkKQphZS5nZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIkR2VuZGVyKQphZS5ob3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQiRIb3NwaXRhbCkKdGFibGUoYWUuZ2VuZGVyLCBhZS5ob3NwaXRhbCwgZG5uID0gYygiU2V4IiwgIkhvc3BpdGFsIikpCmFlLmFydGVyeSA8LSB0b19mYWN0b3IoQUVEQiRBcnRlcnlfc3VtbWFyeSkKdGFibGUoYWUuYXJ0ZXJ5LCBhZS5nZW5kZXIsIGRubiA9IGMoIlNleCIsICJBcnRlcnkiKSkKCnJtKGFlLmdlbmRlciwgYWUuaG9zcGl0YWwsIGFlLmFydGVyeSkKCiMgSSBjaGFuZ2UgbnVtZXJpYyBhbmQgZmFjdG9ycyBtYW51YWxseSBiZWNhdXNlLCB3ZWxsLCBJIHdvdWxkbid0IGtub3cgaG93IHRvIGZpeCBpdCBvdGhlcndpc2UKIyB0byBoYXZlIHRoaXMgJ3RpYmJsZScgd29yayB3aXRoICd0YWJsZW9uZScuLi4gOi0pCgpBRURCJEFnZSA8LSBhcy5udW1lcmljKEFFREIkQWdlKQpBRURCJGRpYXN0b2xpIDwtIGFzLm51bWVyaWMoQUVEQiRkaWFzdG9saSkKQUVEQiRzeXN0b2xpYyA8LSBhcy5udW1lcmljKEFFREIkc3lzdG9saWMpCgpBRURCJFRDX2ZpbmFsQ1UgPC0gYXMubnVtZXJpYyhBRURCJFRDX2ZpbmFsQ1UpCkFFREIkTERMX2ZpbmFsQ1UgPC0gYXMubnVtZXJpYyhBRURCJExETF9maW5hbENVKQpBRURCJEhETF9maW5hbENVIDwtIGFzLm51bWVyaWMoQUVEQiRIRExfZmluYWxDVSkKQUVEQiRUR19maW5hbENVIDwtIGFzLm51bWVyaWMoQUVEQiRUR19maW5hbENVKQoKQUVEQiRUQ19maW5hbCA8LSBhcy5udW1lcmljKEFFREIkVENfZmluYWwpCkFFREIkTERMX2ZpbmFsIDwtIGFzLm51bWVyaWMoQUVEQiRMRExfZmluYWwpCkFFREIkSERMX2ZpbmFsIDwtIGFzLm51bWVyaWMoQUVEQiRIRExfZmluYWwpCkFFREIkVEdfZmluYWwgPC0gYXMubnVtZXJpYyhBRURCJFRHX2ZpbmFsKQoKQUVEQiRBZ2UgPC0gYXMubnVtZXJpYyhBRURCJEFnZSkKQUVEQiRHRlJfTURSRCA8LSBhcy5udW1lcmljKEFFREIkR0ZSX01EUkQpCkFFREIkQk1JIDwtIGFzLm51bWVyaWMoQUVEQiRCTUkpCkFFREIkZUNpZ2FyZXR0ZXMgPC0gYXMubnVtZXJpYyhBRURCJGVDaWdhcmV0dGVzKQpBRURCJGVQYWNrWWVhcnNTbW9raW5nIDwtIGFzLm51bWVyaWMoQUVEQiRlUGFja1llYXJzU21va2luZykKQUVEQiRFUF9jb21wb3NpdGVfdGltZSA8LSBhcy5udW1lcmljKEFFREIkRVBfY29tcG9zaXRlX3RpbWUpCkFFREIkRVBfbWFqb3JfdGltZSA8LSBhcy5udW1lcmljKEFFREIkRVBfbWFqb3JfdGltZSkKCnJlcXVpcmUobGFiZWxsZWQpCkFFREIkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIkQXJ0ZXJ5X3N1bW1hcnkpCkFFREIkT1J5ZWFyIDwtIHRvX2ZhY3RvcihBRURCJE9SeWVhcikKQUVEQiRHZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIkR2VuZGVyKQpBRURCJEhvc3BpdGFsIDwtIHRvX2ZhY3RvcihBRURCJEhvc3BpdGFsKQpBRURCJEtET1FJIDwtIHRvX2ZhY3RvcihBRURCJEtET1FJKQpBRURCJEJNSV9XSE8gPC0gdG9fZmFjdG9yKEFFREIkQk1JX1dITykKQUVEQiREaWFiZXRlc1N0YXR1cyA8LSB0b19mYWN0b3IoQUVEQiREaWFiZXRlc1N0YXR1cykKQUVEQiRTbW9rZXJTdGF0dXMgPC0gdG9fZmFjdG9yKEFFREIkU21va2VyU3RhdHVzKQpBRURCJEFsY29ob2xVc2UgPC0gdG9fZmFjdG9yKEFFREIkQWxjb2hvbFVzZSkKCkFFREIkSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnQgPC0gdG9fZmFjdG9yKEFFREIkSHlwZXJ0ZW5zaW9uMSkKQUVEQiRIeXBlcnRlbnNpb24uc2VsZnJlcG9ydGRydWcgPC0gdG9fZmFjdG9yKEFFREIkSHlwZXJ0ZW5zaW9uMikKQUVEQiRIeXBlcnRlbnNpb24uY29tcG9zaXRlIDwtIHRvX2ZhY3RvcihBRURCJEh5cGVydGVuc2lvbi5jb21wb3NpdGUpCkFFREIkSHlwZXJ0ZW5zaW9uLmRydWdzIDwtIHRvX2ZhY3RvcihBRURCJEh5cGVydGVuc2lvbi5kcnVncykKCkFFREIkTWVkLmFudGljb2FndWxhbnRzIDwtIHRvX2ZhY3RvcihBRURCJE1lZC5hbnRpY29hZ3VsYW50cykKQUVEQiRNZWQuYWxsLmFudGlwbGF0ZWxldCA8LSB0b19mYWN0b3IoQUVEQiRNZWQuYWxsLmFudGlwbGF0ZWxldCkKQUVEQiRNZWQuU3RhdGluLkxMRCA8LSB0b19mYWN0b3IoQUVEQiRNZWQuU3RhdGluLkxMRCkKCkFFREIkU3Ryb2tlX0R4IDwtIHRvX2ZhY3RvcihBRURCJFN0cm9rZV9EeCkKQUVEQiRDQURfaGlzdG9yeSA8LSB0b19mYWN0b3IoQUVEQiRDQURfaGlzdG9yeSkKQUVEQiRQQU9EIDwtIHRvX2ZhY3RvcihBRURCJFBBT0QpCkFFREIkUGVyaXBoZXJhbC5pbnRlcnYgPC0gdG9fZmFjdG9yKEFFREIkUGVyaXBoZXJhbC5pbnRlcnYpCgpBRURCJHN5bXB0IDwtIHRvX2ZhY3RvcihBRURCJHN5bXB0KQpBRURCJFN5bXB0b21zLjNnIDwtIHRvX2ZhY3RvcihBRURCJFN5bXB0b21zLjNnKQpBRURCJFN5bXB0b21zLjRnIDwtIHRvX2ZhY3RvcihBRURCJFN5bXB0b21zLjRnKQpBRURCJFN5bXB0b21zLjVHIDwtIHRvX2ZhY3RvcihBRURCJFN5bXB0b21zLjVHKQpBRURCJEFzeW1wdFN5bXB0IDwtIHRvX2ZhY3RvcihBRURCJEFzeW1wdFN5bXB0KQpBRURCJEFzeW1wdFN5bXB0MkcgPC0gdG9fZmFjdG9yKEFFREIkQXN5bXB0U3ltcHQyRykKQUVEQiRTeW1wdG9tcy5VcGRhdGUyRyA8LSB0b19mYWN0b3IoQUVEQiRTeW1wdG9tcy5VcGRhdGUyRykKQUVEQiRTeW1wdG9tcy5VcGRhdGUzRyA8LSB0b19mYWN0b3IoQUVEQiRTeW1wdG9tcy5VcGRhdGUzRykKCkFFREIkcmVzdGVub3MgPC0gdG9fZmFjdG9yKEFFREIkcmVzdGVub3MpCkFFREIkc3Rlbm9zZSA8LSB0b19mYWN0b3IoQUVEQiRzdGVub3NlKQpBRURCJEVQX2NvbXBvc2l0ZSA8LSB0b19mYWN0b3IoQUVEQiRFUF9jb21wb3NpdGUpCkFFREIkRVBfbWFqb3IgPC0gdG9fZmFjdG9yKEFFREIkRVBfbWFqb3IpCkFFREIkTWFjcm9waGFnZXMuYmluIDwtIHRvX2ZhY3RvcihBRURCJE1hY3JvcGhhZ2VzLmJpbikKQUVEQiRTTUMuYmluIDwtIHRvX2ZhY3RvcihBRURCJFNNQy5iaW4pCkFFREIkSVBILmJpbiA8LSB0b19mYWN0b3IoQUVEQiRJUEguYmluKQpBRURCJENhbGMuYmluIDwtIHRvX2ZhY3RvcihBRURCJENhbGMuYmluKQpBRURCJENvbGxhZ2VuLmJpbiA8LSB0b19mYWN0b3IoQUVEQiRDb2xsYWdlbi5iaW4pCkFFREIkRmF0LmJpbl8xMCA8LSB0b19mYWN0b3IoQUVEQiRGYXQuYmluXzEwKQpBRURCJEZhdC5iaW5fNDAgPC0gdG9fZmFjdG9yKEFFREIkRmF0LmJpbl80MCkKQUVEQiRPdmVyYWxsUGxhcXVlUGhlbm90eXBlIDwtIHRvX2ZhY3RvcihBRURCJE92ZXJhbGxQbGFxdWVQaGVub3R5cGUpCkFFREIkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPC0gdG9fZmFjdG9yKEFFREIkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgpCgpBRURCJEFydGVyeV9zdW1tYXJ5IDwtIHRvX2ZhY3RvcihBRURCJEFydGVyeV9zdW1tYXJ5KQoKQUVEQiRpbmZvcm1lZGNvbnNlbnQgPC0gdG9fZmFjdG9yKEFFREIkaW5mb3JtZWRjb25zZW50KQoKQUVEQi5mdWxsIDwtIHN1YnNldChBRURCLAogICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibWlzc2luZyIgJiAjIHdlIGFyZSByZWFsbHkgc3RyaWN0IGluIHNlbGVjdGluZyBiYXNlZCBvbiAnaW5mb3JtZWQgY29uc2VudCchCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZGllZCIgJiAKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkb2Vzbid0IHdhbnQgdG8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCB1bmFibGUgdG8gc2lnbiIgJiAKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBubyByZWFjdGlvbiIgJiAKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBsb3N0IiAmIAogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHRvbyBvbGQiICYgCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIG1lZGljYWwgaW5mbywgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubyAobmV2ZXIgYXNrZWQgZm9yIElDIGJlY2F1c2UgdGhlcmUgd2FzIG5vIHRpc3N1ZSkiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBlbmRwb2ludCIgJiAKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vb2l0IGdlaW5jbHVkZWVyZCIpCiMgQUVEQi5DRUFbMToxMCwgMToxMF0KZGltKEFFREIuZnVsbCkKCmBgYAoKYGBge3IgQmFzZWxpbmUgQUVEQjogY3JlYXRpb259CmNhdCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIikKY2F0KCJDUkVBVEUgQkFTRUxJTkUgVEFCTEVcbiIpCgojIEJhc2VsaW5lIHRhYmxlIHZhcmlhYmxlcwpiYXNldGFibGVfdmFycyA9IGMoIkhvc3BpdGFsIiwgCiAgICAgICAgICAgICAgICAgICAiQXJ0ZXJ5X3N1bW1hcnkiLAogICAgICAgICAgICAgICAgICAgIkFnZSIsICJHZW5kZXIiKQogICAgICAgICAgICAgICAgICAgIyAiT1J5ZWFyIiwgCiAgICAgICAgICAgICAgICAgICAjICJUQ19maW5hbENVIiwgIkxETF9maW5hbENVIiwgIkhETF9maW5hbENVIiwgIlRHX2ZpbmFsQ1UiLCAKICAgICAgICAgICAgICAgICAgICMgIlRDX2ZpbmFsIiwgIkxETF9maW5hbCIsICJIRExfZmluYWwiLCAiVEdfZmluYWwiLCAKICAgICAgICAgICAgICAgICAgICMgImhzQ1JQX3BsYXNtYSIsCiAgICAgICAgICAgICAgICAgICAjICJzeXN0b2xpYyIsICJkaWFzdG9saSIsICJHRlJfTURSRCIsICJCTUkiLCAKICAgICAgICAgICAgICAgICAgICMgIktET1FJIiwgIkJNSV9XSE8iLAogICAgICAgICAgICAgICAgICAgIyAiU21va2VyU3RhdHVzIiwgIkFsY29ob2xVc2UiLAogICAgICAgICAgICAgICAgICAgIyAiRGlhYmV0ZXNTdGF0dXMiLCAKICAgICAgICAgICAgICAgICAgICMgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0IiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyIsICJIeXBlcnRlbnNpb24uY29tcG9zaXRlIiwgIkh5cGVydGVuc2lvbi5kcnVncyIsIAogICAgICAgICAgICAgICAgICAgIyAiTWVkLmFudGljb2FndWxhbnRzIiwgIk1lZC5hbGwuYW50aXBsYXRlbGV0IiwgIk1lZC5TdGF0aW4uTExEIiwgCiAgICAgICAgICAgICAgICAgICAjICJTdHJva2VfRHgiLCAic3ltcHQiLCAiU3ltcHRvbXMuNUciLCAiQXN5bXB0U3ltcHQiLCAiQXN5bXB0U3ltcHQyRyIsCiAgICAgICAgICAgICAgICAgICAjICJTeW1wdG9tcy5VcGRhdGUyRyIsIAogICAgICAgICAgICAgICAgICAgIyAiU3ltcHRvbXMuVXBkYXRlM0ciLAogICAgICAgICAgICAgICAgICAgIyAicmVzdGVub3MiLCAic3Rlbm9zZSIsCiAgICAgICAgICAgICAgICAgICAjICJDQURfaGlzdG9yeSIsICJQQU9EIiwgIlBlcmlwaGVyYWwuaW50ZXJ2IiwgCiAgICAgICAgICAgICAgICAgICAjICJFUF9jb21wb3NpdGUiLCAiRVBfY29tcG9zaXRlX3RpbWUiLCAiRVBfbWFqb3IiLCAiRVBfbWFqb3JfdGltZSIsCiAgICAgICAgICAgICAgICAgICAjICJNQUNfcmFua05vcm0iLCAiU01DX3JhbmtOb3JtIiwgIk1hY3JvcGhhZ2VzLmJpbiIsICJTTUMuYmluIiwKICAgICAgICAgICAgICAgICAgICMgIk5ldXRyb3BoaWxzX3JhbmtOb3JtIiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsCiAgICAgICAgICAgICAgICAgICAjICJJUEguYmluIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgIyAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICAjICJGYXQuYmluXzEwIiwgIkZhdC5iaW5fNDAiLCAKICAgICAgICAgICAgICAgICAgICMgIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiLCAiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiKQoKYmFzZXRhYmxlX2JpbiA9IGMoIkhvc3BpdGFsIiwgCiAgICAgICAgICAgICAgICAgICJBcnRlcnlfc3VtbWFyeSIsCiAgICAgICAgICAgICAgICAgICJHZW5kZXIiKQojIGJhc2V0YWJsZV9iaW4KCmJhc2V0YWJsZV9jb24gPSBiYXNldGFibGVfdmFyc1shYmFzZXRhYmxlX3ZhcnMgJWluJSBiYXNldGFibGVfYmluXQojIGJhc2V0YWJsZV9jb24KYGBgCgojIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgQmFzZWxpbmUgQ2hhcmFjdGVyaXN0aWNzCgpTaG93aW5nIHRoZSBiYXNlbGluZSB0YWJsZSBvZiB0aGUgd2hvbGUgQXRoZXJvLUV4cHJlc3MgQmlvYmFuay4KCmBgYHtyIEJhc2VsaW5lIEFFREI6IFZpc3VhbGl6ZSBBRURCfQojIENyZWF0ZSBiYXNlbGluZSB0YWJsZXMKIyBodHRwOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tLzEzMzIxX2RhMzE0NjMzZGI5MjRkYzc4OTg2YTg1MDgxM2E1MGQ1Lmh0bWwKQUVEQi50YWJsZU9uZSA9IHByaW50KENyZWF0ZVRhYmxlT25lKHZhcnMgPSBiYXNldGFibGVfdmFycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yVmFycyA9IGJhc2V0YWJsZV9iaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzdHJhdGEgPSAiU3ltcHRvbXMuNGciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBRURCLmZ1bGwsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjNdCmBgYAoKCiMjIE1hdGNoIHNhbXBsZXMgdXNlZAoKSGVyZSB3ZSBtYXRjaCB0aGUgZnVsbCBkYXRhYmFzZSB3aXRoIHRoZSBzYW1wbGVzIHVzZWQgaW4gKipgRW50cm9weU1hc2tlcmAqKi4gCgpgYGB7cn0KIyBSZW1vdmUgZHVwbGljYXRlIHJvd3Mgb2YgdGhlIGRhdGFmcmFtZQpsaWJyYXJ5KGRwbHlyKQp0ZW1wIDwtIEVNX3NhbXBsZXMgJT4lIHNlbGVjdCguLCAiU3R1ZHludW1iZXIiKSAlPiUKICBkaXN0aW5jdCguKQoKQUVEQl9FTSA8LSBtZXJnZSh0ZW1wLAogICAgICAgICAgICAgICAgIEFFREIsCiAgICAgICAgICAgICAgICAgYnkueCA9ICJTdHVkeW51bWJlciIsCiAgICAgICAgICAgICAgICAgYnkueSA9ICJTVFVEWV9OVU1CRVIiLCAKICAgICAgICAgICAgICAgICBzb3J0ID0gRkFMU0UpCgpBRURCX0VNLmZ1bGwgPC0gc3Vic2V0KEFFREJfRU0sCiAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJtaXNzaW5nIiAmICMgd2UgYXJlIHJlYWxseSBzdHJpY3QgaW4gc2VsZWN0aW5nIGJhc2VkIG9uICdpbmZvcm1lZCBjb25zZW50JyEKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkaWVkIiAmIAogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gaGVhbHRoIHRyZWF0bWVudCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRvZXNuJ3Qgd2FudCB0byIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHVuYWJsZSB0byBzaWduIiAmIAogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIG5vIHJlYWN0aW9uIiAmIAogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGxvc3QiICYgCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgdG9vIG9sZCIgJiAKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gbWVkaWNhbCBpbmZvLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmIAogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm9vaXQgZ2VpbmNsdWRlZXJkIikKIyBBRURCX0VNLmZ1bGxbMToxMCwgMToxMF0KCnJtKHRlbXApCmBgYAoKCgpgYGB7ciBCYXNlbGluZSBBRURCOiBWaXN1YWxpemUgQUVEQiBFTSBGVUxMfQojIENyZWF0ZSBiYXNlbGluZSB0YWJsZXMKIyBodHRwOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tLzEzMzIxX2RhMzE0NjMzZGI5MjRkYzc4OTg2YTg1MDgxM2E1MGQ1Lmh0bWwKQUVEQl9FTS5mdWxsLnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHN0cmF0YSA9ICJTeW1wdG9tcy40ZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFFREJfRU0uZnVsbCwgaW5jbHVkZU5BID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vbm5vcm1hbCA9IGMoKSwgbWlzc2luZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcXVvdGUgPSBGQUxTRSwgbm9TcGFjZXMgPSBGQUxTRSwgc2hvd0FsbExldmVscyA9IFRSVUUsIGV4cGxhaW4gPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSAicGYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250RGlnaXRzID0gMylbLDE6M10KYGBgCgpgYGB7ciBCYXNlbGluZSBBRURCOiBWaXN1YWxpemUgQUVEQiBFTX0KCmJhc2V0YWJsZV92YXJzID0gYygiSG9zcGl0YWwiLCAKICAgICAgICAgICAgICAgICAgICJBcnRlcnlfc3VtbWFyeSIpCgpiYXNldGFibGVfYmluID0gYygiSG9zcGl0YWwiLCAKICAgICAgICAgICAgICAgICAgIkFydGVyeV9zdW1tYXJ5IikKCiMgQ3JlYXRlIGJhc2VsaW5lIHRhYmxlcwojIGh0dHA6Ly9yc3R1ZGlvLXB1YnMtc3RhdGljLnMzLmFtYXpvbmF3cy5jb20vMTMzMjFfZGEzMTQ2MzNkYjkyNGRjNzg5ODZhODUwODEzYTUwZDUuaHRtbApBRURCX0VNLnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHN0cmF0YSA9ICJTeW1wdG9tcy40ZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFFREJfRU0sIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjNdCmBgYAoKIyMgQmFzZWxpbmUgd3JpdGluZwoKTGV0J3Mgc2F2ZSB0aGUgYmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5LgoKYGBge3IgQmFzZWxpbmUgU2FtcGxlU2VsZWN0aW9uOiB3cml0ZX0KIyBXcml0ZSBiYXNldGFibGUKCnJlcXVpcmUob3Blbnhsc3gpCgp3cml0ZS54bHN4KGFzLmRhdGEuZnJhbWUoQUVEQi50YWJsZU9uZSksIAogICAgICAgICAgIGZpbGUgPSBwYXN0ZTAoQkFTRUxJTkVfbG9jLCAiLyIsVG9kYXksIi4iLFBST0pFQ1ROQU1FLCIuQUUuQmFzZWxpbmVUYWJsZS54bHN4IiksIAogICAgICAgICAgIHJvd05hbWVzID0gVFJVRSwgCiAgICAgICAgICAgY29sTmFtZXMgPSBUUlVFLCAKICAgICAgICAgICBzaGVldE5hbWUgPSAiQUVfQmFzZSIsIG92ZXJ3cml0ZSA9IFRSVUUpCgp3cml0ZS54bHN4KGFzLmRhdGEuZnJhbWUoQUVEQl9FTS50YWJsZU9uZSksIAogICAgICAgICAgIGZpbGUgPSBwYXN0ZTAoQkFTRUxJTkVfbG9jLCAiLyIsVG9kYXksIi4iLFBST0pFQ1ROQU1FLCIuQUUuRU0uNTkuQmFzZWxpbmVUYWJsZS54bHN4IiksIAogICAgICAgICAgIHJvd05hbWVzID0gVFJVRSwgCiAgICAgICAgICAgY29sTmFtZXMgPSBUUlVFLCAKICAgICAgICAgICBzaGVldE5hbWUgPSAiQUVfQmFzZV9FTV81OSIsIG92ZXJ3cml0ZSA9IFRSVUUpCgp3cml0ZS54bHN4KGFzLmRhdGEuZnJhbWUoQUVEQl9FTS5mdWxsLnRhYmxlT25lKSwgCiAgICAgICAgICAgZmlsZSA9IHBhc3RlMChCQVNFTElORV9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRS5FTS41Ni5CYXNlbGluZVRhYmxlLnhsc3giKSwgCiAgICAgICAgICAgcm93TmFtZXMgPSBUUlVFLCAKICAgICAgICAgICBjb2xOYW1lcyA9IFRSVUUsIAogICAgICAgICAgIHNoZWV0TmFtZSA9ICJBRV9CYXNlX0VNXzU2Iiwgb3ZlcndyaXRlID0gVFJVRSkKCmBgYAoKV2Ugd2lsbCBhbHNvIHdyaXRlIHRoZSBuZXdseSBwcmVwYXJlZCBBRURCIHNlbGVjdGVkIGZvciB0aGlzIHN0dWR5IHdoaWNoIHdlIGNhbiB1c2UgaW4gZG93bnN0cmVhbSBhbmFseXNlcy4gCgpgYGB7cn0Kc2F2ZVJEUyhBRURCX0VNLmZ1bGwsIGZpbGUgPSBwYXN0ZTAoT1VUX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFREIuRU0uRlVMTC5SRFMiKSkKc2F2ZVJEUyhBRURCLmZ1bGwsIGZpbGUgPSBwYXN0ZTAoT1VUX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFREIuRlVMTC5SRFMiKSkKc2F2ZVJEUyhBRURCLCBmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5BRURCLnJhdy5SRFMiKSkKCmBgYAoKCiMgU2Vzc2lvbiBpbmZvcm1hdGlvbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgVmVyc2lvbjogICAgICB2MS4wLjIKICAgIExhc3QgdXBkYXRlOiAgMjAyMi0wNy0xMgogICAgV3JpdHRlbiBieTogICBTYW5kZXIgVy4gdmFuIGRlciBMYWFuIChzLncudmFuZGVybGFhbi0yW2F0XXVtY3V0cmVjaHQubmwpLgogICAgRGVzY3JpcHRpb246ICBTY3JpcHQgdG8gZ2V0IHNvbWUgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeSBiYXNlbGluZSBjaGFyYWN0ZXJpc3RpY3MuCiAgICBNaW5pbXVtIHJlcXVpcmVtZW50czogUiB2ZXJzaW9uIDMuNC4zICgyMDE3LTA2LTMwKSAtLSAnU2luZ2xlIENhbmRsZScsIE1hYyBPUyBYIEVsIENhcGl0YW4KCiAgICAqKk1vU0NvVyBUby1EbyBMaXN0KioKICAgIFRoZSB0aGluZ3Mgd2UgTXVzdCwgU2hvdWxkLCBDb3VsZCwgYW5kIFdvdWxkIGhhdmUgZ2l2ZW4gdGhlIHRpbWUgd2UgaGF2ZS4KICAgIF9NXwoKICAgIF9TXwoKICAgIF9DXwoKICAgIF9XXwoKICAgICoqQ2hhbmdlcyBsb2cqKgogICAgKiB2MS4wLjIgU2ltcGxpZmllZCB0aGUgaW5pdGlhbCBzY3JpcHQuIEl0IG5vdyBvdXRwdXRzIHRoZSByZWxldmFudCBSLW9iamVjdHMgKGFzIC5SRFMpLgogICAgKiB2MS4wLjEgVXBkYXRlIHRvIG1haW4gQUVEQiAodGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIEFnZS12YXJpYWJsZSBpbiB0aGUgbmV3IHZlcnNpb24pLgogICAgKiB2MS4wLjAgSW5pdGlhbCB2ZXJzaW9uLiBBZGQgJ3BsYXF1ZSB2dWxuZXJhYmlsaXR5IGluZGV4JywgRml4ZWQgYmFzZWxpbmUgdGFibGUsIGFkZGVkIGNvZGVzLCBhbmQgcmVzdWx0cy4gTWFqb3IgdXBkYXRlIHRvIFdPUkNTIHN5c3RlbS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3IgZXZhbCA9IFRSVUV9CnNlc3Npb25JbmZvKCkKYGBgCgojIFNhdmluZyBlbnZpcm9ubWVudAoKYGBge3IgU2F2aW5nfQpzYXZlLmltYWdlKHBhc3RlMChQUk9KRUNUX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFREIuRU0uYmFzZWxpbmUuUkRhdGEiKSkKYGBgCgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgPHN1cD7CqSAxOTc5LTIwMjIgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiB8IHMudy52YW5kZXJsYWFuW2F0XWdtYWlsLmNvbSB8IFtzd3ZhbmRlcmxhYW4uZ2l0aHViLmlvXShodHRwczovL3N3dmFuZGVybGFhbi5naXRodWIuaW8pLjwvc3VwPiB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsK
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + diff --git a/README.html b/README.html index 8756caf..43485f5 100644 --- a/README.html +++ b/README.html @@ -30,7 +30,7 @@ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 - +h1.title {font-size: 38px;} +h2 {font-size: 30px;} +h3 {font-size: 24px;} +h4 {font-size: 18px;} +h5 {font-size: 16px;} +h6 {font-size: 12px;} +code {color: inherit; background-color: rgba(0, 0, 0, 0.04);} +pre:not([class]) { background-color: white } +code{white-space: pre-wrap;} +span.smallcaps{font-variant: small-caps;} +span.underline{text-decoration: underline;} +div.column{display: inline-block; vertical-align: top; width: 50%;} +div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} +ul.task-list{list-style: none;} +