# Load necessary libraries
library(dplyr)
library(tidyr)
library(kableExtra)
library(here)
# Add other libraries as needed

# Define the path to your R folder
r_folder_path <- here("R")

# List all R script files in the R folder (including subdirectories)
function_files <- list.files(
  path = r_folder_path,
  pattern = "\\.R$",
  full.names = TRUE,
  recursive = TRUE
)

# Source each function file
invisible(sapply(function_files, function(file) {
  tryCatch(
    source(file, echo = FALSE, print.eval = FALSE),
    error = function(e) {
      message(sprintf("Error sourcing %s: %s", file, e$message))
    }
  )
}))

Load CA Treatment Stand Level Summary Data


fvs.stand.raw = readRDS('/Users/katharynduffy/Library/CloudStorage/GoogleDrive-katharyn@vibrantplanet.net/Shared drives/VP - Resilience Group/Forest_Analytics_Team/FVS/fvs_resp_fxns/sp-raw-data/ca-data/outputs/raw_stand_data-ca.rds')

fvs.stand.raw = fvs.stand.raw%>%
  filter(!MgmtID %in% paste0('FIC', 1:6))%>%
  filter(Year>2024)

# Define the years of interest
years_of_interest <- c(2025, 2029, 2030, 2031, 2035, 2036, 2040, 2045, 2050, 2055, 2060)

all.metrics = data.frame(colnames(fvs.stand.raw)) #peruse possible variables
#Unique removal codes
unique(fvs.stand.raw$RmvCode)
[1] 0 2 1
#Unique Years
unique(fvs.stand.raw$Year)
 [1] 2025 2029 2030 2031 2035 2036 2040 2045 2050 2055 2060 2065

# Call the function
yrs.raw.data <- temporal_coverage_table(fvs.stand.raw, years_of_interest)

# View the resulting presence table
yrs.raw.data%>%
  kbl()%>%
  kable_minimal()
MgmtID 2025 2029 2030 2031 2035 2036 2040 2045 2050 2055 2060
MTIR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMGP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXGF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
BASE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HCTA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HERB TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCT TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTTH TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
REVA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXAI TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMMA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMTF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Remove multiple Stand / Year combos populated by RmvCode:

# Apply the filter_stand_data function
fvs.stand <- filter_duplicate_rmvcodes(fvs.stand.raw)

# QC check
unique(fvs.stand$RmvCode)
[1] 0 2
rm(fvs.stand.raw)
# Call the function
yrs.rmv.data <- temporal_coverage_table(fvs.stand, years_of_interest)

# View the resulting presence table
yrs.rmv.data%>%
  kbl()%>%
  kable_minimal()
MgmtID 2025 2029 2030 2031 2035 2036 2040 2045 2050 2055 2060
MTIR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMGP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXGF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
BASE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HCTA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HERB TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCT TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTTH TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
REVA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXAI TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMMA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMTF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
fvs.treated.stands <- apply_trt_thresholds(fvs.stand)
rm(fvs.stand)
# Call the function
yrs.trt.data <- temporal_coverage_table(fvs.treated.stands, years_of_interest)

# View the resulting presence table
yrs.trt.data%>%
  kbl()%>%
  kable_minimal()
MgmtID 2025 2029 2030 2031 2035 2036 2040 2045 2050 2055 2060
MTIR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMGP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXGF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
BASE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HCTA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CMUR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
HERB TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MRCT TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MTTH TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
REVA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RXAI TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMMA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
RMTF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
head(fvs.treated.stands)%>%
  kbl()%>%
  kable_minimal()
CaseID StandID Year RmvCode Age Tpa TPrdTpa BA SDI CCF TopHt QMD TCuFt TPrdTCuFt MCuFt TPrdMCuFt BdFt TPrdBdFt RTpa RTCuFt RMCuFt RBdFt PrdLen Acc Mort MAI ForTyp SizeCls StkCls Stand_CN MgmtID RunTitle KeywordFile SamplingWt Variant Version RV Groups RunDateTime Aboveground_Total_Live Aboveground_Merch_Live Belowground_Live Belowground_Dead Standing_Dead Forest_Down_Dead_Wood Forest_Floor Forest_Shrub_Herb Total_Stand_Carbon Total_Removed_Carbon Carbon_Released_From_Fire Surface_Litter Surface_Duff Surface_lt3 Surface_ge3 Surface_3to6 Surface_6to12 Surface_ge12 Surface_Herb Surface_Shrub Surface_Total Standing_Snag_lt3 Standing_Snag_ge3 Standing_Foliage Standing_Live_lt3 Standing_Live_ge3 Standing_Total Total_Biomass Total_Consumed Biomass_Removed Removal_Code Stratum_1_DBH Stratum_1_Nom_Ht Stratum_1_Lg_Ht Stratum_1_Sm_Ht Stratum_1_Crown_Base Stratum_1_Crown_Cover Stratum_1_SpeciesFVS_1 Stratum_1_SpeciesFVS_2 Stratum_1_SpeciesPLANTS_1 Stratum_1_SpeciesPLANTS_2 Stratum_1_SpeciesFIA_1 Stratum_1_SpeciesFIA_2 Stratum_1_Status_Code Stratum_2_DBH Stratum_2_Nom_Ht Stratum_2_Lg_Ht Stratum_2_Sm_Ht Stratum_2_Crown_Base Stratum_2_Crown_Cover Stratum_2_SpeciesFVS_1 Stratum_2_SpeciesFVS_2 Stratum_2_SpeciesPLANTS_1 Stratum_2_SpeciesPLANTS_2 Stratum_2_SpeciesFIA_1 Stratum_2_SpeciesFIA_2 Stratum_2_Status_Code Stratum_3_DBH Stratum_3_Nom_Ht Stratum_3_Lg_Ht Stratum_3_Sm_Ht Stratum_3_Crown_Base Stratum_3_Crown_Cover Stratum_3_SpeciesFVS_1 Stratum_3_SpeciesFVS_2 Stratum_3_SpeciesPLANTS_1 Stratum_3_SpeciesPLANTS_2 Stratum_3_SpeciesFIA_1 Stratum_3_SpeciesFIA_2 Stratum_3_Status_Code Number_of_Strata Total_Cover Structure_Class RSDI Hard_snags_class1 Hard_snags_class2 Hard_snags_class3 Hard_snags_class4 Hard_snags_class5 Hard_snags_class6 Hard_snags_total Soft_snags_class1 Soft_snags_class2 Soft_snags_class3 Soft_snags_class4 Soft_snags_class5 Soft_snags_class6 Soft_snags_total Hard_soft_snags_total ...1 ...16 ...32 ...34 ...78 ...98 ...125
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2025 0 9 70.31014 70.31014 15.55495 34 17 38 6.368859 367.7327 367.7327 56.59509 56.59509 257.4843 257.4843 0 0 0 0 4 5.266905 0.9283861 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.216443 0.4951076 0.4189228 0.3393207 0.6408244 2.248843 0.3650955 0.3554602 8.584909 0 0 0.8236790 0.1630656 1.223393 3.2742934 2.6682353 0.6060582 0 0.4155434 0.2953770 6.195351 0.0286911 1.2529577 0.4256367 1.470347 7 10 16 0 0 1 6.656566 38 48 29 28 31 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 31 1=SI 6.163643 51.734772 0 0 0 0 0 51.734772 0 0 0 0 0 0 0 51.734772 NA NA NA NA NA NA NA
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2029 0 13 69.47730 69.47730 16.17525 35 17 39 6.533415 385.0866 385.0866 76.54671 76.54671 358.0955 358.0955 0 0 0 0 1 5.480518 0.9781715 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.488533 0.6763937 0.4318150 0.2896062 0.0832323 2.370314 0.3970927 0.3541953 8.414789 0 0 0.8500748 0.2231488 1.090417 3.6502111 2.8971472 0.7530638 0 0.4137444 0.2946461 6.522242 0.0344498 0.1320147 0.4411587 1.606773 7 9 16 0 0 1 6.854605 41 48 30 29 31 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 31 1=SI 6.328206 1.822002 0 0 0 0 0 1.822002 0 0 0 0 0 0 0 1.822002 NA NA NA NA NA NA NA
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2030 0 14 69.27037 69.27037 16.32815 35 18 39 6.574021 389.5891 389.5891 107.45572 107.45572 528.1117 528.1117 0 0 0 0 1 5.085802 0.9902851 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.519055 0.9516329 0.4349737 0.2784372 0.0786167 2.276728 0.4100558 0.3538950 8.351762 0 0 0.8705845 0.2376745 3.515780 1.0376769 0.8206959 0.2169810 0 0.4133173 0.2944726 6.369506 0.0317411 0.1254924 0.4449717 1.567224 7 9 16 0 0 1 6.893935 41 49 31 29 31 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 31 1=SI 6.368267 1.705845 0 0 0 0 0 1.705845 0 0 0 0 0 0 0 1.705845 NA NA NA NA NA NA NA
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2031 0 15 69.06400 69.06400 16.47536 36 18 40 6.613446 393.6846 393.6846 114.23206 114.23206 560.5508 560.5508 0 0 0 0 4 5.082666 0.9974985 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.564504 1.0149332 0.4380045 0.2677520 0.0785624 2.111834 0.4200583 0.3536138 8.234328 0 0 0.8814083 0.2538843 3.232385 0.9912822 0.7830707 0.2082115 0 0.4129174 0.2943102 6.066188 0.0320543 0.1250705 0.4486377 1.560144 7 9 15 0 0 1 6.932452 41 49 31 29 31 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 31 1=SI 6.406497 1.663239 0 0 0 0 0 1.663239 0 0 0 0 0 0 0 1.663239 NA NA NA NA NA NA NA
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2035 0 19 68.24440 68.24440 17.07808 37 18 40 6.773644 410.0252 410.0252 159.20885 159.20885 790.8375 790.8375 0 0 0 0 1 5.524703 1.0500964 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.833869 1.4297450 0.4503874 0.2296645 0.0843967 1.536088 0.4477706 0.3524703 7.934647 0 0 0.8964277 0.3137632 2.248035 0.8241401 0.6468021 0.1773379 0 0.4112912 0.2936495 4.987307 0.0372365 0.1315569 0.4636208 1.695878 8 10 15 0 0 1 7.065926 42 49 33 29 32 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 32 1=SI 6.561871 1.620583 0 0 0 0 0 1.620583 0 0 0 0 0 0 0 1.620583 NA NA NA NA NA NA NA
d2853743-4b60-45b9-9561-9d58a65a9fe5 10002 2036 0 20 68.04076 68.04076 17.23244 37 18 41 6.814363 414.4999 414.4999 173.78842 173.78842 869.8893 869.8893 0 0 0 0 4 5.206530 1.0578144 0 997 2 4 1009 MTIR MTIR fe528030-2e70-4121-8fdc-fbbe7c1ee03c 1 CA FS2023.2 20230518 All_Plots, All_Stands 2024-05-07-14:15:59 4.861170 1.5613950 0.4535350 0.2210992 0.0825141 1.457364 0.4602750 0.3521876 7.888146 0 0 0.9164776 0.3275088 2.123497 0.7912316 0.6190196 0.1722119 0 0.4108890 0.2934861 4.863091 0.0336190 0.1314091 0.4674380 1.648465 8 10 15 0 0 1 7.110052 41 49 33 30 32 OH -- 2TB -- 998 -- 2 0 0 0 0 0 0 -- -- -- -- -- -- 0 0 0 0 0 0 0 -- -- -- -- -- -- 0 1 32 1=SI 6.601368 1.580098 0 0 0 0 0 1.580098 0 0 0 0 0 0 0 1.580098 NA NA NA NA NA NA NA
NA

library(plotly)

# Set a seed for reproducibility
set.seed(123)

# Define the sample size per MgmtID (adjust as needed)
sample_size <- 500  # Sample up to 500 observations per MgmtID

# Sample the data
sampled_data <- fvs.treated.stands %>%
  filter(Year>2025 & Year<2036)%>%
  group_by(MgmtID) %>%
  sample_n(size = min(n(), sample_size), replace = FALSE) %>%
  ungroup()

# Create the plot using the sampled data
qc.plot <- plot_ly(
  data = sampled_data,
  x = ~Year,
  y = ~Stratum_1_Crown_Cover,
  type = 'box',
  color = ~MgmtID
)

# Display the plot
qc.plot
NA
# First plot: BA
p1 <- plot_ly(data = sampled_data, x = ~Year, y = ~BA, type = 'box', color = ~MgmtID) %>%
  layout(title = "BA", yaxis = list(title = "BA"))
p1
# Second plot: Tpa
p2 <- plot_ly(data = sampled_data, x = ~Year, y = ~Tpa, type = 'box', color = ~MgmtID) %>%
  layout(title = "Tpa", yaxis = list(title = "Tpa"))
p2
# Third plot: Stratum_1_Crown_Cover
p3 <- plot_ly(data = sampled_data, x = ~Year, y = ~Stratum_1_Crown_Cover, type = 'box', color = ~MgmtID) %>%
  layout(title = "Stratum_1_Crown_Cover", yaxis = list(title = "Stratum_1_Crown_Cover"))
p3
NA
saveRDS(fvs.treated.stands, here('data','CA-TRT-StandLevel.rds'))
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTG9hZCBuZWNlc3NhcnkgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShoZXJlKQojIEFkZCBvdGhlciBsaWJyYXJpZXMgYXMgbmVlZGVkCgojIERlZmluZSB0aGUgcGF0aCB0byB5b3VyIFIgZm9sZGVyCnJfZm9sZGVyX3BhdGggPC0gaGVyZSgiUiIpCgojIExpc3QgYWxsIFIgc2NyaXB0IGZpbGVzIGluIHRoZSBSIGZvbGRlciAoaW5jbHVkaW5nIHN1YmRpcmVjdG9yaWVzKQpmdW5jdGlvbl9maWxlcyA8LSBsaXN0LmZpbGVzKAogIHBhdGggPSByX2ZvbGRlcl9wYXRoLAogIHBhdHRlcm4gPSAiXFwuUiQiLAogIGZ1bGwubmFtZXMgPSBUUlVFLAogIHJlY3Vyc2l2ZSA9IFRSVUUKKQoKIyBTb3VyY2UgZWFjaCBmdW5jdGlvbiBmaWxlCmludmlzaWJsZShzYXBwbHkoZnVuY3Rpb25fZmlsZXMsIGZ1bmN0aW9uKGZpbGUpIHsKICB0cnlDYXRjaCgKICAgIHNvdXJjZShmaWxlLCBlY2hvID0gRkFMU0UsIHByaW50LmV2YWwgPSBGQUxTRSksCiAgICBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgbWVzc2FnZShzcHJpbnRmKCJFcnJvciBzb3VyY2luZyAlczogJXMiLCBmaWxlLCBlJG1lc3NhZ2UpKQogICAgfQogICkKfSkpCmBgYAoKCkxvYWQgQ0EgVHJlYXRtZW50IFN0YW5kIExldmVsIFN1bW1hcnkgRGF0YQoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CgpmdnMuc3RhbmQucmF3ID0gcmVhZFJEUygnL1VzZXJzL2thdGhhcnluZHVmZnkvTGlicmFyeS9DbG91ZFN0b3JhZ2UvR29vZ2xlRHJpdmUta2F0aGFyeW5AdmlicmFudHBsYW5ldC5uZXQvU2hhcmVkIGRyaXZlcy9WUCAtIFJlc2lsaWVuY2UgR3JvdXAvRm9yZXN0X0FuYWx5dGljc19UZWFtL0ZWUy9mdnNfcmVzcF9meG5zL3NwLXJhdy1kYXRhL2NhLWRhdGEvb3V0cHV0cy9yYXdfc3RhbmRfZGF0YS1jYS5yZHMnKQoKZnZzLnN0YW5kLnJhdyA9IGZ2cy5zdGFuZC5yYXclPiUKICBmaWx0ZXIoIU1nbXRJRCAlaW4lIHBhc3RlMCgnRklDJywgMTo2KSklPiUKICBmaWx0ZXIoWWVhcj4yMDI0KQoKIyBEZWZpbmUgdGhlIHllYXJzIG9mIGludGVyZXN0CnllYXJzX29mX2ludGVyZXN0IDwtIGMoMjAyNSwgMjAyOSwgMjAzMCwgMjAzMSwgMjAzNSwgMjAzNiwgMjA0MCwgMjA0NSwgMjA1MCwgMjA1NSwgMjA2MCkKCmFsbC5tZXRyaWNzID0gZGF0YS5mcmFtZShjb2xuYW1lcyhmdnMuc3RhbmQucmF3KSkgI3BlcnVzZSBwb3NzaWJsZSB2YXJpYWJsZXMKI1VuaXF1ZSByZW1vdmFsIGNvZGVzCnVuaXF1ZShmdnMuc3RhbmQucmF3JFJtdkNvZGUpCiNVbmlxdWUgWWVhcnMKdW5pcXVlKGZ2cy5zdGFuZC5yYXckWWVhcikKYGBgCmBgYHtyfQoKIyBDYWxsIHRoZSBmdW5jdGlvbgp5cnMucmF3LmRhdGEgPC0gdGVtcG9yYWxfY292ZXJhZ2VfdGFibGUoZnZzLnN0YW5kLnJhdywgeWVhcnNfb2ZfaW50ZXJlc3QpCgojIFZpZXcgdGhlIHJlc3VsdGluZyBwcmVzZW5jZSB0YWJsZQp5cnMucmF3LmRhdGElPiUKICBrYmwoKSU+JQogIGthYmxlX21pbmltYWwoKQpgYGAKCgojIyBSZW1vdmUgbXVsdGlwbGUgU3RhbmQgLyBZZWFyIGNvbWJvcyBwb3B1bGF0ZWQgYnkgUm12Q29kZToKYGBge3J9CiMgQXBwbHkgdGhlIGZpbHRlcl9zdGFuZF9kYXRhIGZ1bmN0aW9uCmZ2cy5zdGFuZCA8LSBmaWx0ZXJfZHVwbGljYXRlX3JtdmNvZGVzKGZ2cy5zdGFuZC5yYXcpCgojIFFDIGNoZWNrCnVuaXF1ZShmdnMuc3RhbmQkUm12Q29kZSkKcm0oZnZzLnN0YW5kLnJhdykKYGBgCmBgYHtyfQojIENhbGwgdGhlIGZ1bmN0aW9uCnlycy5ybXYuZGF0YSA8LSB0ZW1wb3JhbF9jb3ZlcmFnZV90YWJsZShmdnMuc3RhbmQsIHllYXJzX29mX2ludGVyZXN0KQoKIyBWaWV3IHRoZSByZXN1bHRpbmcgcHJlc2VuY2UgdGFibGUKeXJzLnJtdi5kYXRhJT4lCiAga2JsKCklPiUKICBrYWJsZV9taW5pbWFsKCkKYGBgCgoKYGBge3J9CmZ2cy50cmVhdGVkLnN0YW5kcyA8LSBhcHBseV90cnRfdGhyZXNob2xkcyhmdnMuc3RhbmQpCnJtKGZ2cy5zdGFuZCkKYGBgCgoKYGBge3J9CiMgQ2FsbCB0aGUgZnVuY3Rpb24KeXJzLnRydC5kYXRhIDwtIHRlbXBvcmFsX2NvdmVyYWdlX3RhYmxlKGZ2cy50cmVhdGVkLnN0YW5kcywgeWVhcnNfb2ZfaW50ZXJlc3QpCgojIFZpZXcgdGhlIHJlc3VsdGluZyBwcmVzZW5jZSB0YWJsZQp5cnMudHJ0LmRhdGElPiUKICBrYmwoKSU+JQogIGthYmxlX21pbmltYWwoKQpgYGAKCmBgYHtyfQpoZWFkKGZ2cy50cmVhdGVkLnN0YW5kcyklPiUKICBrYmwoKSU+JQogIGthYmxlX21pbmltYWwoKQogIApgYGAKCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KCmxpYnJhcnkocGxvdGx5KQoKIyBTZXQgYSBzZWVkIGZvciByZXByb2R1Y2liaWxpdHkKc2V0LnNlZWQoMTIzKQoKIyBEZWZpbmUgdGhlIHNhbXBsZSBzaXplIHBlciBNZ210SUQgKGFkanVzdCBhcyBuZWVkZWQpCnNhbXBsZV9zaXplIDwtIDUwMCAgIyBTYW1wbGUgdXAgdG8gNTAwIG9ic2VydmF0aW9ucyBwZXIgTWdtdElECgojIFNhbXBsZSB0aGUgZGF0YQpzYW1wbGVkX2RhdGEgPC0gZnZzLnRyZWF0ZWQuc3RhbmRzICU+JQogIGZpbHRlcihZZWFyPjIwMjUgJiBZZWFyPDIwMzYpJT4lCiAgZ3JvdXBfYnkoTWdtdElEKSAlPiUKICBzYW1wbGVfbihzaXplID0gbWluKG4oKSwgc2FtcGxlX3NpemUpLCByZXBsYWNlID0gRkFMU0UpICU+JQogIHVuZ3JvdXAoKQoKIyBDcmVhdGUgdGhlIHBsb3QgdXNpbmcgdGhlIHNhbXBsZWQgZGF0YQpxYy5wbG90IDwtIHBsb3RfbHkoCiAgZGF0YSA9IHNhbXBsZWRfZGF0YSwKICB4ID0gflllYXIsCiAgeSA9IH5TdHJhdHVtXzFfQ3Jvd25fQ292ZXIsCiAgdHlwZSA9ICdib3gnLAogIGNvbG9yID0gfk1nbXRJRAopCgojIERpc3BsYXkgdGhlIHBsb3QKcWMucGxvdAoKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD0xMCwgd2FybmluZz1GQUxTRX0KIyBGaXJzdCBwbG90OiBCQQpwMSA8LSBwbG90X2x5KGRhdGEgPSBzYW1wbGVkX2RhdGEsIHggPSB+WWVhciwgeSA9IH5CQSwgdHlwZSA9ICdib3gnLCBjb2xvciA9IH5NZ210SUQpICU+JQogIGxheW91dCh0aXRsZSA9ICJCQSIsIHlheGlzID0gbGlzdCh0aXRsZSA9ICJCQSIpKQpwMQojIFNlY29uZCBwbG90OiBUcGEKcDIgPC0gcGxvdF9seShkYXRhID0gc2FtcGxlZF9kYXRhLCB4ID0gflllYXIsIHkgPSB+VHBhLCB0eXBlID0gJ2JveCcsIGNvbG9yID0gfk1nbXRJRCkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlRwYSIsIHlheGlzID0gbGlzdCh0aXRsZSA9ICJUcGEiKSkKcDIKIyBUaGlyZCBwbG90OiBTdHJhdHVtXzFfQ3Jvd25fQ292ZXIKcDMgPC0gcGxvdF9seShkYXRhID0gc2FtcGxlZF9kYXRhLCB4ID0gflllYXIsIHkgPSB+U3RyYXR1bV8xX0Nyb3duX0NvdmVyLCB0eXBlID0gJ2JveCcsIGNvbG9yID0gfk1nbXRJRCkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlN0cmF0dW1fMV9Dcm93bl9Db3ZlciIsIHlheGlzID0gbGlzdCh0aXRsZSA9ICJTdHJhdHVtXzFfQ3Jvd25fQ292ZXIiKSkKcDMKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CnNhdmVSRFMoZnZzLnRyZWF0ZWQuc3RhbmRzLCBoZXJlKCdkYXRhJywnQ0EtVFJULVN0YW5kTGV2ZWwucmRzJykpCmBgYAoK