GitHub Repository
The Rmarkdown file can be downloaded from the Code drop down menu (top right).

This supplementary file contains the R workflow for processing and analysing the raw data, and creating figures for the manuscript ID: GCB-23-0861 titled “Sub-lethal consequences of ultraviolet radiation exposure on vertebrates: synthesis through meta-analysis”.


Supplementary Information

PRISMA

Fig. S1. PRISMA flow diagram for the systematic data-collection process. n = number of papers remaining after each stage of selection. k = number of effect size after processing individual data, and n is number of observations/records after processing data. Searches were grouped by taxonomic groups.


Dataset

Calculate effect size, \(lnRR\), and sampling variance, \(v_i\)

The raw data for analysis is available on GitHub. This section is the workflow to import and clean the raw data for analysis. Effect size as the natural log-transformed response ratio, lnRR (1), and the sampling variance, \(v_i\) (2), was calculated following Hedges and Olkin (2014):

\[ \begin{equation} lnRR = \ln \left( \frac{\bar{X}_{1}}{\bar{X}_{2}}\right), \tag{1} \end{equation} \] \[ \begin{equation} v_i = \frac{SD_{1}^2} {\bar{X}^2_{1}n_{1}} + \frac{SD_{2}^2} {\bar{X}^2_{2}n_{2}}, \tag{2} \end{equation} \]

where \(\bar{X}_1\), \(SD_1\), and \(n_1\) are the mean, standard deviation, and sample size of the exposed group, respectively, while \(\bar{X}_2\), \(SD_2\), and \(n_2\) are the mean, standard deviation, and sample size of the control group, respectively. The standard error, \(se_i\) (3), was calculated as:

\[ \begin{equation} se_{i} =\sqrt{v_i}. \tag{3} \end{equation} \]

The inverse of \(se_i\) or precision (4) was calculated as:

\[ \begin{equation} p_{i} = \frac{1}{se_i}. \tag{4} \end{equation} \]

To account for unbalanced sampling, we used the ‘effective sample size’ instead of the sample size (\(n_1\) + \(n_2\)) for the meta-analysis of lnRR (Nakagawa et al., 2022). The effective sample size (5) is formulated as:

\[ \begin{equation} 4\tilde{n_{i}} = \frac{4n_{1i} n_{2i}}{n_{1i} + n_{2i}}. \tag{5} \end{equation} \]

When \(n\) = \(n_1\) = \(n_2\), the formula reduces to 2\(n\). Indeed, the inverse of \(\tilde{n_{i}}\) is a part of sampling variance in lnRR (6):

\[ \begin{equation} \frac{1}{\tilde{n_{i}}} = \frac{n_{1i} + n_{2i}}{n_{1i} n_{2i}} = \frac{1}{n_{1i}} + \frac{1}{n_{2i}}. \tag{6} \end{equation} \]

All conversions for the standard error (\(se_i\)), sampling variance, precision (the inverse of \(se_i\)), effective sample size (\(4\tilde{n_{i}}\)) and the inverse of \(\tilde{n_{i}}\) (\(\frac{1}{\tilde{n_{i}}}\)) followed Nakagawa et al. (2022). Data were also prepared to test for publication bias, and sources of non-independance such as shared controls, study effect, species effect, and phylogeny.

# Load and clean raw data
raw_dat <- read.csv("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/UV meta-analysis/Vertebrate_UV_MetaAnalysis_FINAL.csv") %>%
  tibble::rowid_to_column("es_ID") %>% # add effect size ID
  dplyr::mutate(vi            = t_SD ^ 2 / (t_n * t_mean ^ 2) + c_SD ^ 2 / (c_n * c_mean ^ 2), # Sampling variance (v)
                sei           = sqrt(vi), # Standard error (SE)
                sei_inv       = 1 / sei, # Precision (inverse of SE)
                eff_n         = (4 * c_n * t_n) / (c_n + t_n), # Effective sample size
                inv_eff_n     = (c_n + t_n) / (c_n * t_n), # Inverse of eff_n
                sqrt_inv_eff  = sqrt(inv_eff_n), # Square root of the inverse of eff_n
                year_centre   = pub_year - mean(pub_year),  # Mean-centring year of publication)
                ln_delta_dose = log(delta_dose_J_day),
                ln_dur_day    = log(t_duration_day),
                species_OTL   = as.factor(species_OTL),
                life_stage    = factor(life_stage, levels = c("Embryo", "Larva", "Juvenile", "Adult")),
                region        = factor(region, levels = c("Tropical", "Subtropical", "Temperate")),
                classification = as.factor(classification),
                source_cat    = as.factor(source_cat),
                medium        = as.factor(medium),
                trait = as.factor(trait),
                metric        = as.factor(metric),
                uv_type       = as.factor(uv_type)) %>% 
  dplyr::select(-c(reference, notes))

# Account for shared controls
M <- metaAidR::make_VCV_matrix(data = raw_dat, V = "vi", cluster = "shared_control2", m = "c_mean",
                     sd = "c_SD", n = "c_n", type = "vcv", vcal = "ROM", obs = "es_ID")

Data summary

The raw_dat used for the meta-analysis comprises of 895 individual effect sizes from 73 studies across 47 species (detailed in Supplementary Table S1).

Table S1 - Summary

Table S1 - Responses. Trait categories and the specific metrics extracted for the study. Number of effect sizes, studies and species are shown. Responses with asterisks were corrected for direction. CAT = catalase, GST = glutathione S-transferase, LDH = lactate dehydrogenase, LPO = lactoperoxidase, ROS = reactive oxygen species, SOD = superoxide dismutase, Ucrit = critical swimming speed.

Categorised trait Specific metric Effect size (k) Studies (n) Species (n)
Behaviour Sheltering Behaviour 14 4 7
Behaviour Time Active 7 2 2
Cardiorespiratory Function Heart Rate 25 4 3
Cardiorespiratory Function Hematocrit 20 7 5
DNA Damage DNA Damage* 42 6 8
DNA Damage Photolyase Gene Expression 15 1 1
DNA Damage Pyrimidine Dimers* 4 1 1
Energy Metabolism Aerobic Scope 3 2 1
Energy Metabolism LDH Activity 21 1 1
Energy Metabolism Maximum Metabolic Rate 11 3 3
Energy Metabolism P:O Ratio 1 1 1
Energy Metabolism Respiratory Control Ratio 1 1 1
Energy Metabolism Resting Metabolic Rate 3 2 1
Energy Metabolism Routine Metabolic Rate 24 11 7
Energy Metabolism State 3 Respiration 1 1 1
Energy Metabolism State 4 Respiration 1 1 1
Energy Metabolism Tissue Level Respiration 1 1 1
Growth Final Length 112 17 16
Growth Final Mass 45 18 17
Growth Growth Rate 2 1 1
Growth Length (change) 4 1 1
Growth Specific Growth Rate 9 2 2
Hormonal Stress Response Corticosterone 7 3 2
Hormonal Stress Response Cortisol 31 7 5
Locomotion Burst Swimming 40 6 5
Locomotion Routine Swimming Speed 24 1 1
Locomotion Ucrit 5 4 2
Neuromusclular Acytlcholinesterase 6 1 1
Oxidant H2O2 Levels* 8 1 1
Oxidant ROS Production* 27 3 2
Oxidative Damage Alanine Aminotransferase* 8 1 1
Oxidative Damage Asparate Aminotransferase* 8 1 1
Oxidative Damage LPO Activity* 76 7 7
Oxidative Damage Malondialdehyde* 2 2 2
Oxidative Damage Protein Carbonyl* 5 4 2
Oxidative Damage Protein Peroxide Levels* 1 1 1
Oxidative Damage Thiobarbituric Acid Reactive Substances* 6 1 1
Oxidative Stress Response/Defense CAT Activity 65 8 8
Oxidative Stress Response/Defense CAT Gene Expression 23 2 2
Oxidative Stress Response/Defense DT-diaphorase 1 1 1
Oxidative Stress Response/Defense Glutathione 10 3 2
Oxidative Stress Response/Defense Glutathione disulfide reductase 7 2 2
Oxidative Stress Response/Defense Glutathione Peroxidase 7 2 2
Oxidative Stress Response/Defense Glutathione Transferase 1 1 1
Oxidative Stress Response/Defense GST Activity 42 2 3
Oxidative Stress Response/Defense SOD Activity 65 9 9
Oxidative Stress Response/Defense SOD Gene Expression 8 1 1
Oxidative Stress Response/Defense SOD1 Gene Expression 15 1 1
Oxidative Stress Response/Defense SOD3 Gene Expression 15 1 1
Oxidative Stress Response/Defense Total Antioxidant Capacity 4 1 1
Oxidative Stress Response/Defense Total Peroxidase 12 2 2

Life stage

Table S1 - Life stage. Continuation of data summary with additional information on the number of effect size, studies, and species in the database by life stage. Presentation in order by the number of effect size in the data.

Life stage Effect size (k) Studies (n) Species (n)
Juvenile 285 22 16
Larva 262 32 22
Embryo 180 7 5
Adult 168 16 12

Species

Table S1 - Species. Continuation of data summary with additional information on the number of effect size, and studies in the database by species. Presentation in order by the number of effect size in the data.

Class Species Effect size (k) Studies (n)
Fish Danio rerio 97 4
Fish Dicentrarchus labrax 95 2
Fish Sparus aurata 75 2
Fish Amphiprion clarkii 64 1
Fish Coryphaena hippurus 61 2
Fish Solea senegalensis 60 1
Fish Clarias gariepinus 58 2
Amphibian Litoria caerulea 57 1
Fish Gambusia holbrooki 34 4
Fish Coregonus lavaretus 29 3
Fish Girella laevifrons 28 5
Amphibian Limnodynastes peronii 23 4
Fish Rutilus rutilus 19 2
Amphibian Boana pulchella 15 2
Fish Coregonus albula 15 2
Amphibian Rana temporaria 14 6
Fish Salmo salar 14 2
Fish Pleuronectes platessa 12 1
Fish Oncorhynchus mykiss 11 3
Amphibian Bufo bufo 10 2
Fish Amatitlania nigrofasciata 10 2
Fish Cyprinus carpio 9 2
Amphibian Ambystoma maculatum 8 1
Reptile Psammodromus algirus 7 1
Amphibian Ambystoma gracile 6 1
Bird Gallus gallus 6 3
Fish Engraulis mordax 6 1
Reptile Sceloporus occidentalis 6 1
Amphibian Rana arvalis 5 2
Fish Scomber japonicus 5 1
Fish Colossoma macropomum 4 1
Fish Oryzias latipes 4 1
Reptile Sauromalus ater 4 1
Amphibian Limnodynastes ornatus 3 1
Amphibian Rana cascadae 3 2
Amphibian Ambystoma macrodactylum 2 1
Fish Graus nigra 2 1
Fish Pomacentrus amboinensis 2 1
Fish Thalassoma lunare 2 1
Reptile Eublepharis macularius 2 1
Reptile Furcifer pardalis 2 1
Amphibian Rana aurora 1 1
Amphibian Rana blairi 1 1
Fish Arapaima gigas 1 1
Fish Esox lucius 1 1
Fish Pimephales promelas 1 1
Fish Seriola lalandi 1 1

Traits

Table S1 - Traits. Continuation of data summary with additional information on the number of effect size, studies, and species in the database by by traits. Presentation in order by the number of effect size in the data.

Trait Effect size (k) Studies (k) Species (n)
Oxidative Stress Response/Defense 275 15 12
Growth 172 32 27
Oxidative Damage 106 11 8
Locomotion 69 11 8
Energy Metabolism 67 16 10
DNA Damage 61 8 10
Cardiorespiratory Function 45 11 8
Hormonal Stress Response 38 10 7
Oxidant 35 4 3
Behaviour 21 6 9
Neuromusclular 6 1 1

UV type

Table S1 - UV type. Continuation of data summary with additional information on the number of effect size, studies, and species in the database by UV radiation type and taxonomic class. Presentation in order by the number of effect size in the data.

UV type Class Effect size (k) Studies (k) Species (n)
UVA Amphibian 25 7 4
UVA Bird 5 2 1
UVA Fish 245 12 9
UVA Reptile 2 1 1
UVB Amphibian 123 23 13
UVB Bird 1 1 1
UVB Fish 475 33 23
UVB Reptile 19 5 5

Source

Table S1 - Source. Continuation of data summary with additional information on the number of effect size, studies, and species in the database by collection source. Presentation in order by the number of effect size in the data.

Source Effect size (k) Studies (k) Species (n)
Captive 512 30 24
Wild 377 42 26
Not Specified 6 1 2

Which data are missing?

The following data were not included due of poor reporting by the studies extracted: age (hours post-fertilisation and days post-hatching), body length, body mass, latitude, and longitude. Threshold was set at Good = 0-5%, Okay = 5-40%, Poor = 40-80%, Scarce = 80-100%.

Fig. S2. Frequency of missing data for each variable extracted.


Prepare phylogeny for analysis

This section provides the workflow to extract the phylogenetic tree from the Open Tree of Life (OTL; see phylogenetic reconstruction in main text), match the OTL names with the data set, and create a correlation matrix for subsequent analysis.

sp_all <- sort(unique(as.character(raw_dat$species_OTL)))  # generate list of species (as character format)
taxa <- rotl::tnrs_match_names(names = sp_all)  # match taxonomic names to the OTL

# check if species list match OT identifier taxa[taxa$approximate_match ==
# TRUE,] # none so far

# retrieving phylogenetic relationships among taxa in the form of a trimmed
# sub-tree
tree <- rotl::tol_induced_subtree(ott_ids = rotl::ott_id(taxa), label_format = "name")

# Change OTL species name to match raw_dat
tree$tip.label[tree$tip.label == "Oncorhynchus_mykiss_(species_in_domain_Eukaryota)"] <- "Oncorhynchus_mykiss"

# Compute branch lengths
tree <- ape::compute.brlen(tree, method = "Grafen", power = 1)
tree <- ape::multi2di(tree, random = TRUE)  # use a randomization approach to deal with polytomies

phylo_cor <- ape::vcv(tree, cor = T)

Meta-analysis

Model selection

Prior to the meta-analysis, we performed model selection on all moderators via the dredge function. Due to the long processing time, we used the saved RDS file when creating the html file.

eval(metafor:::.MuMIn)
options(na.action = "na.fail")  # required for dredge to run

mumin_dat <- raw_dat %>%
    dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_"))
mumin_dat <- mumin_dat[!apply(raw_dat[, c("life_stage", "source_cat", "region", "medium",
    "classification", "trait", "uv_type", "exposure_temp", "ln_dur_day", "ln_delta_dose")],
    1, anyNA), ]  # remove rows with any NA value on one of these columns

# Run multi-level model
mumin_model <- metafor::rma.mv(yi = lnRR, V = vi, mods = ~life_stage + source_cat +
    region + medium + classification + trait + uv_type + exposure_temp + ln_dur_day +
    ln_delta_dose, random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL),
    R = list(species_OTL = phylo_cor), method = "ML", test = "t", dfs = "contain",
    data = mumin_dat)

# candidate_models <- MuMIn::dredge(mumin_model) # generate all possible
# combinations of moderators saveRDS(candidate_models, file =
# 'candidate_models.rds')
candidate_models <- readRDS("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/UV meta-analysis/candidate_models.rds")

options(na.action = "na.omit")  # set back to default
subset(candidate_models, delta <= 2)  # display all models within 2 values of AICc
## Global model call: metafor::rma.mv(yi = lnRR, V = vi, mods = ~life_stage + source_cat + 
##     region + medium + classification + trait + uv_type + exposure_temp + 
##     ln_dur_day + ln_delta_dose, random = list(~1 | es_ID, ~1 | 
##     study_ID, ~1 | species, ~1 | species_OTL), data = mumin_dat, 
##     method = "ML", test = "t", dfs = "contain", R = list(species_OTL = phylo_cor))
## ---
## Model selection table 
##     (Int) cls exp_tmp lif_stg ln_dlt_dos ln_dur_day trt uv_typ df logLik AICc
## 781     +                   +      -0.02              +      + 20   -440  922
## 773     +                   +                         +      + 19   -441  922
## 789     +                   +                 0.021   +      + 20   -441  922
## 797     +                   +      -0.02      0.020   +      + 21   -440  922
## 775     +      0.0072       +                         +      + 20   -441  923
## 783     +      0.0068       +      -0.02              +      + 21   -440  923
## 774     +   +               +                         +      + 20   -441  924
## 782     +   +               +      -0.02              +      + 21   -440  924
##     delta weight
## 781  0.00  0.197
## 773  0.03  0.193
## 789  0.74  0.136
## 797  0.82  0.131
## 775  1.39  0.098
## 783  1.43  0.096
## 774  1.94  0.074
## 782  1.96  0.074
## Models ranked by AICc(x)
MuMIn::sw(MuMIn::model.avg(candidate_models, subset = delta <= 2))  # display weight of each moderators
##                      life_stage trait uv_type ln_delta_dose ln_dur_day
## Sum of weights:      1.00       1.00  1.00    0.50          0.27      
## N containing models:    8          8     8       4             2      
##                      exposure_temp classification
## Sum of weights:      0.19          0.15          
## N containing models:    2             2

Meta-analysis

Conduct phylogenically controlled, multi-level meta-analysis. The global_model tested the overall effect of UV exposure on effect size, and tested for publication bias. The overall_model (detailed in the ‘Meta-regression’ section) tested the overall effect with all relevant moderators based on the model section process described above. All models contained the following random effects: Effect size ID, study ID, species ID, study ID, and phylogeny.

The global multi-level, meta-analytic model was fitted as follows:

\[ \begin{equation} Y_i = \beta_0 + \beta_1\sqrt{\frac{1}{\tilde{n_{i}}}} + \beta_2c(\text{year}_j) + \alpha_{k[i]} + sp_{k[i]} + s_{j[i]} + e_i + m_i, \\ \alpha_{k[i]} \sim \text{Normal}(0, \sigma^2_{\text{phylogeny}}\textbf{A}), \\ sp_{k[i]} \sim \text{Normal}(0, \sigma^2_{\text{species}}), \\ s_{k[i]} \sim \text{Normal}(0, \sigma^2_{\text{study}}), \\ e_i \sim \text{Normal}(0, \sigma^2_{\text{residual}}), \\ m_i \sim \text{Normal}(0, v_i), \tag{7} \end{equation} \]

where \(Y_i\) is the \(i\)th effect size, \(\beta_0\) is the weighted overall meta-analytic mean, \(\beta_1\sqrt{\frac{1}{\tilde{n_{i}}}}\) is the inverse of effective sample size, \(\beta_2c(\text{year}_j)\) is the mean centring of publication year, and \(\alpha_{k[i]}\) is the phylogenetic effect (a random effect) for species \(k\) applied to effect size \(i\) (Cinar et al., 2022). Phylogenetic effects are assumed to be normally distributed with a mean of zero and variance \(\sigma^2_{\text{phylogeny}}\) [i.e. \((0, \sigma^2_{\text{phylogeny}}\textbf{A})\)], where \(\textbf{A}\) is a phylogenetic correlation matrix derived from a phylogenetic tree. \(sp_{k[i]}\) is the species-specific effect for the \(k\)th species applied to effect size \(i\), \(s_{k[i]}\) is the study-specifc effect for the \(j\)th study applied to effect size \(i\), \(e_i\) is the effect size-spefic effect (within-study effect, or residuals) for the \(i\)th effect size, and \(m_i\) is the sampling effect for the \(i\)th effect size, resulting from varying precision for each effect size, \(v_i\) (which is known as the sampling variance for the effect).

Meta-regression

Conduct phylogenically controlled, multi-level meta-regression. The overall_model follows the same formula (7) but applies multiple moderator variables (\(\beta\)):

\[ \begin{equation} Y_i = \beta_0 + \displaystyle\sum_{l = 1}^{p} \beta_l x_{l[i]} + \alpha_{k[i]} + sp_{k[i]} + s_{j[i]} + e_i + m_i, \tag{8} \end{equation} \]

where \(\displaystyle\sum_{l = 1}^{p} \beta_l x_{l[i]}\) is the sum of all effects for all moderators \(x_i\) (fixed effects; \(p\) = number of slopes). All other notations are the same as described above (7).

global_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~1 + sqrt_inv_eff + year_centre,
    random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), R = list(species_OTL = phylo_cor),
    method = "REML", test = "t", dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

# Moderators based on best model
overall_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~1 + life_stage + trait +
    uv_type + ln_delta_dose, random = list(~1 | es_ID, ~1 | study_ID, ~1 | species,
    ~1 | species_OTL), R = list(species_OTL = phylo_cor), method = "REML", test = "t",
    dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

global_r2 <- orchaRd::r2_ml(global_model) * 100
overall_r2 <- orchaRd::r2_ml(overall_model) * 100

Heterogeneity analysis

Heterogeneity is a persistent problem in ecological and evolutionary meta-analysis (Borenstein, 2019; Noble et al., 2022; Senior et al., 2016). Here, heterogeneity is reported as \(I^2_\text{total}\) and is calculated as:

\[ \begin{equation} I^2_\text{total} = \frac{\sigma^2_\text{phylogeny} + \sigma^2_\text{species} + \sigma^2_\text{study} + \sigma^2_\text{residual}}{\sigma^2_\text{total}}, \tag{9} \end{equation} \]

where \(\sigma^2_\text{total} = \sigma^2_\text{phylogeny} + \sigma^2_\text{species} + \sigma^2_\text{study} + \sigma^2_\text{residual} + \sigma^2_\text{sampling}\) is the total effect size variance and \(\sigma^2_\text{sampling}\) is the sampling error variance calculated as:

\[ \begin{equation} \sigma_{\text{sampling}}^2 = \sum w_{i}\left( k-1\right) / \left[ \left( \sum w_{i}\right)^2 + \sum w_{i}^2\right] \ \tag{10} \end{equation} \]

where \(k\) is the number of studies and the weights, \(w_i = 1 / v_i\), can be calculated using the inverse of the sampling variance (\(v_i\)) for each effect size \(i\). Lastly, we also calculated how much variance is explained by the model as \(R^2\) which can be separated by \(R^2_{\text{marginal}}\) (fixed effects only) and \(R^2_{\text{conditional}}\) (fixed and random effects):

\[ \begin{equation} R^2_{\text{marginal}} = \frac{\sigma^2_\text{fixed}}{\sigma^2_\text{fixed} + \sigma^2_\text{phylogeny} + \sigma^2_\text{species} + \sigma^2_\text{study} + \sigma^2_\text{residual}}, \\ R^2_{\text{conditional}} = \frac{\sigma^2_\text{fixed} + \displaystyle\sum_{r = 1}^{u} \sigma^2_r}{\sigma^2_\text{fixed} + \sigma^2_\text{phylogeny} + \sigma^2_\text{species} + \sigma^2_\text{study} + \sigma^2_\text{residual}}, \tag{11} \end{equation} \]

where \(\sigma^2_\text{fixed}\) is the variance fo the fixed effects expressed as \(var(\displaystyle\sum_{l = 1}^{p} \beta_l x_{l[i]})\) (Nakagawa and Schielzeth, 2007). The difference between \(R^2_{\text{marginal}}\) and \(R^2_{\text{conditional}}\) is whether the random effect variance is included in the numerator. This is expressed as \(\displaystyle\sum_{r = 1}^{u} \sigma^2_r\), where \(u\) is the number of random factors, and \(\sigma^2_r\) is the variance component of the \(r\)th random factor.

Model output

Table S2 - Model average

Table S2. Summary output of the model averaging of seven candidate models with AIC delta <= 2.The model average was presented as either the full average, which assumes that a moderator is included in every model, or the conditional average, which averages over the models where the moderators appears.

## 
## Call:
## model.avg(object = candidate_models, subset = delta <= 2)
## 
## Component model call: 
## metafor::rma.mv(yi = lnRR, V = vi, mods = ~<8 unique rhs>, random = 
##      list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), data = 
##      mumin_dat, method = ML, test = t, dfs = contain, R = list(species_OTL = 
##      phylo_cor))
## 
## Component models: 
##       df logLik AICc delta weight
## 3467  20   -440  922  0.00   0.20
## 367   19   -441  922  0.03   0.19
## 3567  20   -441  922  0.74   0.14
## 34567 21   -440  923  0.82   0.13
## 2367  20   -441  923  1.39   0.10
## 23467 21   -440  923  1.43   0.10
## 1367  20   -441  924  1.94   0.07
## 13467 21   -440  924  1.96   0.07
## 
## Term codes: 
## classification  exposure_temp     life_stage  ln_delta_dose     ln_dur_day 
##              1              2              3              4              5 
##          trait        uv_type 
##              6              7 
## 
## Model-averaged coefficients:  
## (full average) 
##                                        Estimate Std. Error z value Pr(>|z|)  
## intrcpt                                -0.02704    0.38522    0.07     0.94  
## life_stageLarva                        -0.27644    0.17975    1.54     0.12  
## life_stageJuvenile                     -0.00542    0.19022    0.03     0.98  
## life_stageAdult                        -0.30038    0.20757    1.45     0.15  
## ln_delta_dose                          -0.01005    0.01406    0.71     0.47  
## traitCardiorespiratory Function         0.07111    0.26142    0.27     0.79  
## traitDNA Damage                         0.02602    0.25684    0.10     0.92  
## traitEnergy Metabolism                  0.35124    0.25430    1.38     0.17  
## traitGrowth                             0.24152    0.19466    1.24     0.21  
## traitHormonal Stress Response           0.03221    0.26825    0.12     0.90  
## traitLocomotion                         0.21291    0.19571    1.09     0.28  
## traitNeuromusclular                     0.46248    0.28568    1.62     0.11  
## traitOxidant                           -0.26971    0.25435    1.06     0.29  
## traitOxidative Damage                   0.09531    0.24665    0.39     0.70  
## traitOxidative Stress Response/Defense  0.40133    0.24487    1.64     0.10 .
## uv_typeUVB                             -0.17372    0.08209    2.12     0.03 *
## ln_dur_day                              0.00559    0.01312    0.43     0.67  
## exposure_temp                           0.00137    0.00456    0.30     0.76  
## classificationTissue/Organ System      -0.01868    0.12452    0.15     0.88  
## classificationWhole Animal Performance -0.07202    0.18771    0.38     0.70  
##  
## (conditional average) 
##                                        Estimate Std. Error z value Pr(>|z|)   
## intrcpt                                -0.02704    0.38522    0.07     0.94   
## life_stageLarva                        -0.27644    0.17975    1.54     0.12   
## life_stageJuvenile                     -0.00542    0.19022    0.03     0.98   
## life_stageAdult                        -0.30038    0.20757    1.45     0.15   
## ln_delta_dose                          -0.02019    0.01388    1.45     0.15   
## traitCardiorespiratory Function         0.07111    0.26142    0.27     0.79   
## traitDNA Damage                         0.02602    0.25684    0.10     0.92   
## traitEnergy Metabolism                  0.35124    0.25430    1.38     0.17   
## traitGrowth                             0.24152    0.19466    1.24     0.21   
## traitHormonal Stress Response           0.03221    0.26825    0.12     0.90   
## traitLocomotion                         0.21291    0.19571    1.09     0.28   
## traitNeuromusclular                     0.46248    0.28568    1.62     0.11   
## traitOxidant                           -0.26971    0.25435    1.06     0.29   
## traitOxidative Damage                   0.09531    0.24665    0.39     0.70   
## traitOxidative Stress Response/Defense  0.47128    0.19351    2.44     0.01 **
## uv_typeUVB                             -0.17372    0.08209    2.12     0.03 * 
## ln_dur_day                              0.02093    0.01800    1.16     0.25   
## exposure_temp                           0.00703    0.00819    0.86     0.39   
## classificationTissue/Organ System      -0.12589    0.30160    0.42     0.68   
## classificationWhole Animal Performance -0.48520    0.19211    2.53     0.01 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Table S3 - Global model

Table S3. Summary output of the global_model. intrcpt = overall effect, sqrt_inv_eff = square root of the inverse of effective sample size (small sample effect), year_centre = mean centring of the publication year (decline effect). Heterogeneity is also presented, where I2_Total = total I2, I2_es_ID, within study effect I2, I2_study_ID = between study effects I2, I2_species = species I2, and 2_species_OTL = phylogeny I2. Publication bias as fixed effects (\(R^2_{\text{marginal}}\)) explained 0.61% of the variation, while the random effects (\(R^2_{\text{conditional}}\)) explained 100% of the variation.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1407  0.3751    895     no        es_ID   no 
## sigma^2.2  0.1586  0.3983     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 2:3):
## F(df1 = 2, df2 = 70) = 0.7325, p-val = 0.4844
## 
## Model Results:
## 
##               estimate      se     tval   df    pval    ci.lb    ci.ub     
## intrcpt        -0.3051  0.1058  -2.8823   44  0.0061  -0.5184  -0.0918  ** 
## sqrt_inv_eff    0.1695  0.1529   1.1084  892  0.2680  -0.1306   0.4696     
## year_centre    -0.0030  0.0061  -0.4986   70  0.6196  -0.0151   0.0091     
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##       I2_Total       I2_es_ID    I2_study_ID     I2_species I2_species_OTL 
##            100             47             53              0              0

Table S4 - Overall model

Table S4. Summary output of the overall_model. intrcpt = overall effect. Moderator variables include life stage (embryo, larva, juvenile, adult), trai (see Table S1), UV type (UVA, UVB), exposure temperature, and the natural logarithm of daily dosage (J day). Heterogeneity is also presented, where I2_Total = total I2, I2_es_ID, within study effect I2, I2_study_ID = between study effects I2, I2_species = species I2, and 2_species_OTL = phylogeny I2. Fixed effects (\(R^2_{\text{marginal}}\)) explained 15.84% of the variation, while the random effects (\(R^2_{\text{conditional}}\)) explained 100% of the variation.

## 
## Multivariate Meta-Analysis Model (k = 808; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1156  0.3400    808     no        es_ID   no 
## sigma^2.2  0.1719  0.4147     62     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     42     no      species   no 
## sigma^2.4  0.0000  0.0000     41     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 2:16):
## F(df1 = 15, df2 = 46) = 6.8930, p-val < .0001
## 
## Model Results:
## 
##                                         estimate      se     tval   df    pval 
## intrcpt                                   0.1316  0.2860   0.4602   25  0.6494 
## life_stageLarva                          -0.2954  0.1603  -1.8424  792  0.0658 
## life_stageJuvenile                       -0.0243  0.1760  -0.1382  792  0.8901 
## life_stageAdult                          -0.3231  0.1975  -1.6359   46  0.1087 
## traitCardiorespiratory Function           0.0646  0.1683   0.3837  792  0.7013 
## traitDNA Damage                           0.1108  0.1676   0.6614  792  0.5085 
## traitEnergy Metabolism                    0.3478  0.1672   2.0800  792  0.0378 
## traitGrowth                               0.1973  0.1409   1.4009  792  0.1616 
## traitHormonal Stress Response             0.0542  0.1804   0.3005  792  0.7639 
## traitLocomotion                           0.1624  0.1497   1.0848  792  0.2783 
## traitNeuromusclular                       0.4813  0.2050   2.3479  792  0.0191 
## traitOxidant                             -0.2454  0.1642  -1.4951  792  0.1353 
## traitOxidative Damage                     0.1112  0.1524   0.7298  792  0.4657 
## traitOxidative Stress Response/Defense    0.4075  0.1492   2.7307  792  0.0065 
## uv_typeUVB                               -0.2033  0.0796  -2.5556  792  0.0108 
## ln_delta_dose                            -0.0204  0.0137  -1.4926  792  0.1359 
##                                           ci.lb    ci.ub     
## intrcpt                                 -0.4575   0.7207     
## life_stageLarva                         -0.6102   0.0193   . 
## life_stageJuvenile                      -0.3698   0.3211     
## life_stageAdult                         -0.7206   0.0745     
## traitCardiorespiratory Function         -0.2657   0.3948     
## traitDNA Damage                         -0.2181   0.4398     
## traitEnergy Metabolism                   0.0196   0.6759   * 
## traitGrowth                             -0.0792   0.4739     
## traitHormonal Stress Response           -0.2999   0.4083     
## traitLocomotion                         -0.1314   0.4562     
## traitNeuromusclular                      0.0789   0.8836   * 
## traitOxidant                            -0.5677   0.0768     
## traitOxidative Damage                   -0.1880   0.4105     
## traitOxidative Stress Response/Defense   0.1146   0.7004  ** 
## uv_typeUVB                              -0.3595  -0.0471   * 
## ln_delta_dose                           -0.0472   0.0064     
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##       I2_Total       I2_es_ID    I2_study_ID     I2_species I2_species_OTL 
##            100             40             60              0              0

Fig. S3 - Funnel plot

metafor::funnel(raw_dat$lnRR, raw_dat$vi, yaxis = "seinv", ylab = "Precision (1/SE)",
    xlab = "Effect size (lnRR)")

Fig. S3. Funnel plot with the inverse of the standard error (i.e. precision) as the measure of uncertainty for the effect size (lnRR).

Figures for main text

Figure 1 - Geographical bias

Figure was generated with the coordinates of the wild sourced studies and the mean ultraviolet-B irradiation (UVB) of the highest month was obtained from Beckmann et al. (2014).

## OGR data source with driver: ESRI Shapefile 
## Source: "/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/UV meta-analysis/ne_50m_land/ne_50m_land.shp", layer: "ne_50m_land"
## with 1420 features
## It has 3 fields
## Integer64 fields read as strings:  scalerank


Figure 2 - UV type and region

UV type

uv_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~uv_type - 1, random = list(~1 |
    es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), R = list(species_OTL = phylo_cor),
    method = "REML", test = "t", dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

Table S5. Summary output of the uv_model.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1400  0.3742    895     no        es_ID   no 
## sigma^2.2  0.1574  0.3967     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 1:2):
## F(df1 = 2, df2 = 893) = 8.6509, p-val = 0.0002
## 
## Model Results:
## 
##             estimate      se     tval   df    pval    ci.lb    ci.ub      
## uv_typeUVA   -0.1033  0.0709  -1.4575  893  0.1453  -0.2425   0.0358      
## uv_typeUVB   -0.2239  0.0552  -4.0559  893  <.0001  -0.3323  -0.1156  *** 
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Region

region_model <- metafor::rma.mv(yi = lnRR, V = M, 
                                mods = ~ region-1,
                                random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL),
                                R = list(species_OTL = phylo_cor),
                                method ="REML",
                                test = "t", 
                                dfs = "contain",
                                control = list(rel.tol = 1e-8), # model converge 
                                data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

Table S6. Summary output of the region_model.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1404  0.3748    895     no        es_ID   no 
## sigma^2.2  0.1644  0.4054     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0002     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 1:3):
## F(df1 = 3, df2 = 44) = 4.4606, p-val = 0.0081
## 
## Model Results:
## 
##                    estimate      se     tval   df    pval    ci.lb    ci.ub    
## regionTropical      -0.2286  0.0997  -2.2922   44  0.0267  -0.4297  -0.0276  * 
## regionSubtropical   -0.1578  0.0839  -1.8808  892  0.0603  -0.3224   0.0069  . 
## regionTemperate     -0.2062  0.0840  -2.4539  892  0.0143  -0.3710  -0.0413  * 
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Figure production


Figure 3 - Taxa and life stage

Taxa

taxa_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~class - 1, random = list(~1 |
    es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), R = list(species_OTL = phylo_cor),
    method = "REML", test = "t", dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

print(taxa_model)

Table S7. Summary output of the taxa_model.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1405  0.3748    895     no        es_ID   no 
## sigma^2.2  0.1620  0.4025     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 1:4):
## F(df1 = 4, df2 = 43) = 3.8077, p-val = 0.0098
## 
## Model Results:
## 
##                 estimate      se     tval  df    pval    ci.lb    ci.ub    
## classAmphibian   -0.2608  0.0984  -2.6508  43  0.0112  -0.4593  -0.0624  * 
## classBird        -0.4754  0.2959  -1.6064  43  0.1155  -1.0722   0.1214    
## classFish        -0.1646  0.0697  -2.3604  43  0.0229  -0.3051  -0.0240  * 
## classReptile     -0.0465  0.2038  -0.2282  43  0.8206  -0.4576   0.3645    
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Life stage

stage_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~life_stage - 1, random = list(~1 |
    es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), R = list(species_OTL = phylo_cor),
    method = "REML", test = "t", dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

print(stage_model)

Table S8. Summary output of the stage_model.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1397  0.3737    895     no        es_ID   no 
## sigma^2.2  0.1621  0.4026     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 1:4):
## F(df1 = 4, df2 = 69) = 4.8917, p-val = 0.0016
## 
## Model Results:
## 
##                     estimate      se     tval   df    pval    ci.lb    ci.ub 
## life_stageEmbryo     -0.0332  0.1226  -0.2708  891  0.7866  -0.2737   0.2073 
## life_stageLarva      -0.2657  0.0712  -3.7306  891  0.0002  -0.4055  -0.1259 
## life_stageJuvenile   -0.1098  0.0825  -1.3303  891  0.1838  -0.2718   0.0522 
## life_stageAdult      -0.2517  0.1159  -2.1723   69  0.0333  -0.4829  -0.0205 
##                         
## life_stageEmbryo        
## life_stageLarva     *** 
## life_stageJuvenile      
## life_stageAdult       * 
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Figure production


Figure 4 - Trait

Trait

trait_model <- metafor::rma.mv(yi = lnRR, V = M, mods = ~trait - 1, random = list(~1 |
    es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL), R = list(species_OTL = phylo_cor),
    method = "REML", test = "t", dfs = "contain", data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

Table S9. Summary output of the trait_model.

## 
## Multivariate Meta-Analysis Model (k = 895; method: REML)
## 
## Variance Components:
## 
##             estim    sqrt  nlvls  fixed       factor    R 
## sigma^2.1  0.1250  0.3535    895     no        es_ID   no 
## sigma^2.2  0.1241  0.3523     73     no     study_ID   no 
## sigma^2.3  0.0000  0.0000     48     no      species   no 
## sigma^2.4  0.0000  0.0000     47     no  species_OTL  yes 
## 
## Test of Moderators (coefficients 1:11):
## F(df1 = 11, df2 = 884) = 12.9307, p-val < .0001
## 
## Model Results:
## 
##                                         estimate      se     tval   df    pval 
## traitBehaviour                           -0.5313  0.1208  -4.3974  884  <.0001 
## traitCardiorespiratory Function          -0.2537  0.0884  -2.8718  884  0.0042 
## traitDNA Damage                          -0.5110  0.0822  -6.2196  884  <.0001 
## traitEnergy Metabolism                    0.0615  0.0806   0.7624  884  0.4460 
## traitGrowth                              -0.1741  0.0617  -2.8205  884  0.0049 
## traitHormonal Stress Response            -0.3452  0.1076  -3.2081  884  0.0014 
## traitLocomotion                          -0.2706  0.0770  -3.5153  884  0.0005 
## traitNeuromusclular                       0.0131  0.1639   0.0801  884  0.9362 
## traitOxidant                             -0.5796  0.0958  -6.0528  884  <.0001 
## traitOxidative Damage                    -0.2440  0.0705  -3.4616  884  0.0006 
## traitOxidative Stress Response/Defense   -0.0041  0.0654  -0.0634  884  0.9495 
##                                           ci.lb    ci.ub      
## traitBehaviour                          -0.7684  -0.2942  *** 
## traitCardiorespiratory Function         -0.4272  -0.0803   ** 
## traitDNA Damage                         -0.6723  -0.3498  *** 
## traitEnergy Metabolism                  -0.0968   0.2197      
## traitGrowth                             -0.2952  -0.0530   ** 
## traitHormonal Stress Response           -0.5564  -0.1340   ** 
## traitLocomotion                         -0.4216  -0.1195  *** 
## traitNeuromusclular                     -0.3086   0.3349      
## traitOxidant                            -0.7676  -0.3917  *** 
## traitOxidative Damage                   -0.3824  -0.1057  *** 
## traitOxidative Stress Response/Defense  -0.1325   0.1242      
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Figure production


Supplementary figure

# Taxonomic group and UV interaction
taxa_uv_model <- metafor::rma.mv(yi = lnRR, V = M, 
                                mods = ~ class + uv_type-1,
                                random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL),
                                R = list(species_OTL = phylo_cor),
                                method ="REML",
                                test = "t", 
                                dfs = "contain",
                                data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

taxa_uv_model2 <- orchaRd::mod_results(taxa_uv_model, group = "study_ID", mod = "class", by = "uv_type", weights = "prop", data = raw_dat)

taxa_uv_plot <- orchaRd::orchard_plot(taxa_uv_model2, xlab = "", g = FALSE,
                                      branch.size = 1.5, trunk.size = 4, condition.lab = "UV type") + 
  geom_point() + # mean estimate
  scale_shape_manual(values = c(21, 24)) +
  scale_colour_manual(values = c("#e6e58e", "#EDA200", "#D24E71", "#a733a4")) + 
  scale_fill_manual(values = c("#e6e58e", "#EDA200", "#D24E71", "#a733a4")) + 
  ylab("Effect size (lnRR)") +
  ggtitle("Taxonomic group") +
  mytheme() + theme(legend.position = "bottom")

# Life stage and UV interaction
stage_uv_model <- metafor::rma.mv(yi = lnRR, V = M, 
                                mods = ~ life_stage + uv_type-1,
                                random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL),
                                R = list(species_OTL = phylo_cor),
                                method ="REML",
                                test = "t", 
                                dfs = "contain",
                                data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

stage_uv_model2 <- orchaRd::mod_results(stage_uv_model, group = "study_ID", mod = "life_stage", by = "uv_type", weights = "prop", data = raw_dat)

stage_uv_plot <- orchaRd::orchard_plot(stage_uv_model2, xlab = "lnRR", angle = 45, g = FALSE, 
                                       branch.size = 1.5, trunk.size = 4, condition.lab = "UV type") + 
  geom_point() + # mean estimate
  scale_shape_manual(values = c(21, 24)) +
  scale_colour_manual(values = c("#EDEF5C", "#82CC6C", "#3CB08F", "#007E7D")) + 
  scale_fill_manual(values = c("#EDEF5C", "#82CC6C", "#3CB08F", "#007E7D")) + 
  ylab("Effect size (lnRR)") +
  ggtitle("Life stage") +
  mytheme() + theme(legend.position = "bottom")

prow <- cowplot::plot_grid(taxa_uv_plot + theme(legend.position = "none"), 
                   stage_uv_plot + theme(legend.position = "none"), 
                   labels = c("a", "b"), align = "hv")

legend <- cowplot::get_legend(taxa_uv_plot + theme(legend.position = "bottom"))

cowplot::plot_grid(prow, legend, ncol = 1, rel_heights = c(1, .1))

Fig. S4. Difference in UVA and UVB radiation effects by (a) taxonomic groups and (b) life stage.

trait_uv_model <- metafor::rma.mv(yi = lnRR, V = M, 
                                mods = ~ trait + uv_type-1,
                                random = list(~1 | es_ID, ~1 | study_ID, ~1 | species, ~1 | species_OTL),
                                R = list(species_OTL = phylo_cor),
                                method ="REML",
                                test = "t", 
                                dfs = "contain",
                                data = raw_dat %>%
        dplyr::mutate(species_OTL = stringr::str_replace_all(species_OTL, " ", "_")))

trait_uv_model2 <- orchaRd::mod_results(trait_uv_model, group = "study_ID", mod = "trait", by = "uv_type", weights = "prop", data = raw_dat)

orchaRd::orchard_plot(trait_uv_model2, xlab = "lnRR", angle = 45, g = FALSE, 
                      branch.size = 1.5, trunk.size = 4, condition.lab = "UV type") + 
  geom_point() + # mean estimate
  scale_shape_manual(values = c(21, 24)) +
  scale_colour_manual(values = c("#8f6798", "#7f669f", "#7a7cab", "#7290af", "#6aa1b0", "#64b1af", "#4eb99d", "#56c57f", "#87d662", "#BBDF27", "#FDE725")) + 
  scale_fill_manual(values = c("#8f6798", "#7f669f", "#7a7cab", "#7290af", "#6aa1b0", "#64b1af", "#4eb99d", "#56c57f", "#87d662", "#BBDF27", "#FDE725")) + 
  ylab("Effect size (lnRR)") +
  ggtitle("Traits") +
  mytheme() + theme(legend.position = "bottom")

Fig. S5. Effect of UVA and UVB radiation on 11 biological traits.

ggplot(raw_dat) + geom_hline(yintercept = 0, linetype = "dashed", alpha = 0.5) +
    geom_point(aes(x = metric, y = lnRR, colour = trait), show.legend = FALSE) +
    viridis::scale_colour_viridis(discrete = TRUE) + xlab(NULL) + ylab("Effect size (lnRR") +
    coord_flip() + facet_wrap(~trait, ncol = 3, scales = "free_y") + mytheme() +
    theme(axis.text = element_text(size = 5), strip.text.x = element_text(size = 6),
        legend.position = "bottom")

Fig. S6. Effect of ultraviolet radiation on specific responses across different biological and functional traits. Data presented as individual effect sizes (lnRR).


References

Beckmann, M., Václavík, T., Manceur, A. M., Šprtová, L., Von Wehrden, H., Welk, E. and F, C. A. (2014). glUV: A global UV-B radiation data set for macroecological studies. Methods in Ecology and Evolution 5, 372–383.
Borenstein, M. (2019). Heterogeneity in meta-analysis. In The handbook of research synthesis and meta-analysis (ed. Borenstein, M.), M, C. H.), Hedges, L. V.), and Valentine, J. C.), New York, US: Russell Sage Foundation.
Cinar, O., Nakagawa, Shinichi and Viechtbauer, W. (2022). Phylogenetic multilevel meta‐analysis: A simulation study on the importance of modelling the phylogeny. Methods in Ecology and Evolution 13, 383–395.
Hedges, L. V. and Olkin, I. (2014). Statistical methods for meta-analysis. London, UK: Academic Press Inc.
Nakagawa, S. and Schielzeth, H. (2007). A general and simple method for obtaining R\(^{2}\) from generalized linear mixed-effects models. Methods in Ecology and Evolution 4, 133–142.
Nakagawa, S., Lagisz, M., Jennions, M., Koricheva, J., Noble, D. W., Parker, T. H., Sánchez-Tójar, A., Yang, Y. and O’dea, R. E. (2022). Methods for testing publication bias in ecological and evolutionary meta-analyses. Methods in Ecology and Evolution 13, 4–21.
Noble, D. W., Pottier, P., Lagisz, M., Burke, S., Drobniak, S. M., O’dea, R. E. and Nakagawa, S. (2022). Meta-analytic approaches and effect sizes to account for “nuisance heterogeneity” in comparative physiology. Journal of Experimental Biology 225, jeb243225.
Senior, A. M., Grueber, C. E., Kamiya, T., Lagisz, O., Malgorzata, A, S. E. S. and Nakagawa, S. (2016). Heterogeneity in ecological and evolutionary meta-analyses: Its magnitude and implications. Ecology 97, 3293–3299.



Session Information

R version 4.2.2 (2022-10-31)

Platform: aarch64-apple-darwin20 (64-bit)

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: ape(v.5.7-1), rotl(v.3.0.14), rgdal(v.1.6-7), raster(v.3.6-20), sp(v.1.6-1), MuMIn(v.1.47.5), data.table(v.1.14.8), DataExplorer(v.0.8.2), cowplot(v.1.1.1), pander(v.0.6.5), orchaRd(v.2.0), lubridate(v.1.9.2), forcats(v.1.0.0), stringr(v.1.5.0), dplyr(v.1.1.2), purrr(v.1.0.1), readr(v.2.1.4), tidyr(v.1.3.0), tibble(v.3.2.1), ggplot2(v.3.4.2), tidyverse(v.2.0.0), flextable(v.0.9.1), metafor(v.4.2-0), numDeriv(v.2016.8-1.1), metadat(v.1.2-0), Matrix(v.1.5-4.1), metaAidR(v.0.0.0.9000) and knitr(v.1.43)

loaded via a namespace (and not attached): ggbeeswarm(v.0.7.2), colorspace(v.2.1-0), ellipsis(v.0.3.2), estimability(v.1.4.1), httpcode(v.0.3.0), rstudioapi(v.0.14), farver(v.2.1.1), mvtnorm(v.1.2-2), fansi(v.1.0.4), mathjaxr(v.1.6-0), xml2(v.1.3.4), codetools(v.0.2-19), cachem(v.1.0.8), jsonlite(v.1.8.5), latex2exp(v.0.9.6), shiny(v.1.7.4), rentrez(v.1.2.3), compiler(v.4.2.2), httr(v.1.4.6), emmeans(v.1.8.6), fastmap(v.1.1.1), cli(v.3.6.1), formatR(v.1.14), later(v.1.3.1), prettyunits(v.1.1.1), htmltools(v.0.5.5), tools(v.4.2.2), igraph(v.1.4.3), coda(v.0.19-4), gtable(v.0.3.3), glue(v.1.6.2), Rcpp(v.1.0.10), jquerylib(v.0.1.4), fontquiver(v.0.2.1), vctrs(v.0.6.2), crul(v.1.4.0), nlme(v.3.1-162), xfun(v.0.39), networkD3(v.0.4), timechange(v.0.2.0), mime(v.0.12), lifecycle(v.1.0.3), pacman(v.0.5.1), XML(v.3.99-0.14), terra(v.1.7-29), scales(v.1.2.1), ragg(v.1.2.5), hms(v.1.1.3), promises(v.1.2.0.1), parallel(v.4.2.2), fontLiberation(v.0.1.0), yaml(v.2.3.7), curl(v.5.0.1), gridExtra(v.2.3), gdtools(v.0.3.3), sass(v.0.4.6), stringi(v.1.7.12), fontBitstreamVera(v.0.1.1), highr(v.0.10), zip(v.2.3.0), rlang(v.1.1.1), pkgconfig(v.2.0.3), systemfonts(v.1.0.4), rncl(v.0.8.7), evaluate(v.0.21), lattice(v.0.21-8), labeling(v.0.4.2), htmlwidgets(v.1.6.2), tidyselect(v.1.2.0), magrittr(v.2.0.3), bookdown(v.0.34), R6(v.2.5.1), generics(v.0.1.3), pillar(v.1.9.0), withr(v.2.5.0), crayon(v.1.5.2), gfonts(v.0.2.0), uuid(v.1.1-0), utf8(v.1.2.3), tzdb(v.0.4.0), rmarkdown(v.2.22), officer(v.0.6.2), viridis(v.0.6.3), progress(v.1.2.2), grid(v.4.2.2), digest(v.0.6.31), xtable(v.1.8-4), httpuv(v.1.6.11), textshaping(v.0.3.6), openssl(v.2.0.6), stats4(v.4.2.2), munsell(v.0.5.0), viridisLite(v.0.4.2), beeswarm(v.0.4.0), vipor(v.0.4.5), bslib(v.0.4.2) and askpass(v.1.1)


  1. Hawkesbury Institute for the Environment, Western Sydney University, NSW 2753, Australia, ↩︎

LS0tCnRpdGxlOiAiVVYgTWV0YS1hbmFseXNpcyIKc3VidGl0bGU6ICJTdXBwbGVtZW50YXJ5IEluZm9ybWF0aW9uIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclZC8lbS8lWScpYCIKYXV0aG9yOgogIC0gTmljaG9sYXMgQy4gV3VeW0hhd2tlc2J1cnkgSW5zdGl0dXRlIGZvciB0aGUgRW52aXJvbm1lbnQsIFdlc3Rlcm4gU3lkbmV5IFVuaXZlcnNpdHksIE5TVyAyNzUzLCBBdXN0cmFsaWEsIG5pY2hvbGFzLnd1Lm56QGdtYWlsLmNvbV0Kb3V0cHV0OgogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGhpZ2hsaWdodDogdGFuZ28KZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKY3NsOiAuL2JpYi90aGUtam91cm5hbC1vZi1leHBlcmltZW50YWwtYmlvbG9neS5jc2wKYmlibGlvZ3JhcGh5OiAuL2JpYi91dl9yZWYuYmliCmxpbmstY2l0YXRpb25zOiB0cnVlCi0tLQoKW0dpdEh1YiBSZXBvc2l0b3J5XShodHRwczovL2dpdGh1Yi5jb20vbmljaG9sYXN3dW56L3V2LW1ldGEtYW5hbHlzaXMpICAKVGhlIFJtYXJrZG93biBmaWxlIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gdGhlICpDb2RlKiBkcm9wIGRvd24gbWVudSAodG9wIHJpZ2h0KS4KClRoaXMgc3VwcGxlbWVudGFyeSBmaWxlIGNvbnRhaW5zIHRoZSAqUiogd29ya2Zsb3cgZm9yIHByb2Nlc3NpbmcgYW5kIGFuYWx5c2luZyB0aGUgcmF3IGRhdGEsIGFuZCBjcmVhdGluZyBmaWd1cmVzIGZvciB0aGUgbWFudXNjcmlwdCBJRDogR0NCLTIzLTA4NjEgdGl0bGVkICIqKlN1Yi1sZXRoYWwgY29uc2VxdWVuY2VzIG9mIHVsdHJhdmlvbGV0IHJhZGlhdGlvbiBleHBvc3VyZSBvbiB2ZXJ0ZWJyYXRlczogc3ludGhlc2lzIHRocm91Z2ggbWV0YS1hbmFseXNpcyoqIi4KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGNhY2hlID0gRkFMU0UsIHRpZHkgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkKb3B0aW9ucyhkcGx5ci53aWR0aCA9IEluZiwga25pdHIua2FibGUuTkEgPSAiIiwgZGlnaXRzID0gMikKCiMgTG9hZCBsaWJyYXJ5CnBhY21hbjo6cF9sb2FkKG1ldGFBaWRSLCBtZXRhZm9yLCBmbGV4dGFibGUsIHRpZHl2ZXJzZSwgb3JjaGFSZCwgcGFuZGVyLCBjb3dwbG90LAogICAgICAgICAgICAgICBEYXRhRXhwbG9yZXIsIGRhdGEudGFibGUsIE11TUluLCAKICAgICAgICAgICAgICAgcmFzdGVyLCByZ2RhbCwgc3AsIHJvdGwsIGFwZSkKCiMgRnVuY3Rpb25zCm15dGhlbWUgPC0gZnVuY3Rpb24oKSB7CiAgdGhlbWVfYncoKSArCiAgICB0aGVtZShwYW5lbC5ib3JkZXIgICAgICAgICAgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvdXIgPSAiYmxhY2siKSwgIyBzZXQgYm9yZGVyIGFyb3VuZCBwbG90LgogICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciAgICAgID0gZWxlbWVudF9ibGFuaygpLCAjIHJlbW92ZSBtYWpvciBncmlkIGxpbmVzCiAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksICMgcmVtb3ZlIG1pbm9yIGdyaWQgbGluZXMKICAgICAgICAgIGF4aXMubGluZSAgICAgICAgICAgICA9IGVsZW1lbnRfYmxhbmsoKSwgIyByZW1vdmUgYXhpcyBsaW5lcwogICAgICAgICAgYXhpcy50aWNrcyAgICAgICAgICAgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgICAgYXhpcy50ZXh0ICAgICAgICAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gImJsYWNrIiksICMgYXhpcyB0ZXh0IHNpemUKICAgICAgICAgIGF4aXMudGl0bGUgICAgICAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCAjIGF4aXMgdGl0bGUgc2l6ZQogICAgICAgICAgYXhpcy50aXRsZS55ICAgICAgICAgID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMyksICMgaW5jcmVhc2UgZGlzdGFuY2UgZnJvbSB0aGUgeS1heGlzCiAgICAgICAgICBheGlzLnRpdGxlLnggICAgICAgICAgPSBlbGVtZW50X3RleHQodmp1c3QgPSAtMSksICMgaW5jcmVhc2UgZGlzdGFuY2UgZnJvbSB0aGUgeC1heGlzCiAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kICAgICAgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwKICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCAgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLCAjIHJlbW92ZSBiYWNrZ3JvdW5kIGNvbG91cgogICAgICAgICAgcGxvdC5tYXJnaW4gICAgICAgICAgID0gdW5pdChjKDAuMiwgMC4yLCAwLjIsIDAuMiksIHVuaXRzID0gLCAiY20iKSwKICAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLCAjIGdldCByaWQgb2YgbGVnZW5kIGJnCiAgICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9IE5BKSwgIyBnZXQgcmlkIG9mIGxlZ2VuZCBwYW5lbCBiZwogICAgICAgICAgc3RyaXAudGV4dC54ICAgICAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiKSwgIyBmb3IgZmFjZXQgcGxvdHMKICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpCiAgICApCn0gIyBzZXQgdXAgcGxvdCB0aGVtZQoKZm9ybWF0X2NlbGxzIDwtIGZ1bmN0aW9uKGRmLCByb3dzICxjb2xzLCB2YWx1ZSA9IGMoIml0YWxpY3MiLCAiYm9sZCIsICJzdHJpa2V0aHJvdWdoIikpewogICMgc2VsZWN0IHRoZSBjb3JyZWN0IG1hcmt1cAogICMgb25lICogZm9yIGl0YWxpY3MsIHR3byAqKiBmb3IgYm9sZAogIG1hcCA8LSBzZXROYW1lcyhjKCIqIiwgIioqIiwgIn5+IiksIGMoIml0YWxpY3MiLCAiYm9sZCIsICJzdHJpa2V0aHJvdWdoIikpCiAgbWFya3VwIDwtIG1hcFt2YWx1ZV0gIAogIGZvciAociBpbiByb3dzKXsKICAgIGZvcihjIGluIGNvbHMpewogICAgICAjIE1ha2Ugc3VyZSB2YWx1ZXMgYXJlIG5vdCBmYWN0b3JzCiAgICAgIGRmW1tjXV0gPC0gYXMuY2hhcmFjdGVyKGRmW1tjXV0pCiAgICAgICMgVXBkYXRlIGZvcm1hdHRpbmcKICAgICAgZGZbciwgY10gPC0gcGFzdGUwKG1hcmt1cCwgZGZbciwgY10sIG1hcmt1cCkKICAgIH0KICB9CiAgcmV0dXJuKGRmKQp9ICMgYWxsb3dzIHRvIHNlbGVjdCB0aGUgY2VsbCByb3cgYW5kIGNvbHVtbnMgd2hpY2ggbmVlZCB0byBiZSByZWZvcm1hdHRlZCBhbmQgc2VsZWN0IHRoZSBzdHlsaW5nIHRvIGFwcGx5LgoKcGxvdF9taXNzaW5nXzIgPC0gZnVuY3Rpb24oZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IGxpc3QoR29vZCA9IDAuMDUsIE9rYXkgPSAwLjQsIFBvb3IgPSAwLjgsIFNjYXJjZSA9ICAxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGFiZWxfYXJncyA9IGxpc3QoKSwgdGl0bGUgPSBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSBteXRoZW1lKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfY29uZmlnID0gbGlzdChsZWdlbmQucG9zaXRpb24gPSBjKCJyaWdodCIpKSkgCnsKICBwY3RfbWlzc2luZyA8LSBCYW5kIDwtIE5VTEwKICBtaXNzaW5nX3ZhbHVlIDwtIGRhdGEudGFibGUocHJvZmlsZV9taXNzaW5nKGRhdGEpKQogIGdyb3VwIDwtIGdyb3VwW3NvcnQubGlzdCh1bmxpc3QoZ3JvdXApKV0KICBpbnZpc2libGUobGFwcGx5KHNlcV9hbG9uZyhncm91cCksIGZ1bmN0aW9uKGkpIHsKICAgIGlmIChpID09IDEpIHsKICAgICAgbWlzc2luZ192YWx1ZVtwY3RfbWlzc2luZyA8PSBncm91cFtbaV1dLCBgOj1gKEJhbmQsIG5hbWVzKGdyb3VwKVtpXSldCiAgICB9IGVsc2UgewogIG1pc3NpbmdfdmFsdWVbcGN0X21pc3NpbmcgPiBncm91cFtbaSAtIDFdXSAmIHBjdF9taXNzaW5nIDw9IGdyb3VwW1tpXV0sIGA6PWAoQmFuZCwgbmFtZXMoZ3JvdXApW2ldKV0KICAgIH0KfSkpCiAgb3V0cHV0IDwtIGdncGxvdChtaXNzaW5nX3ZhbHVlLCBhZXNfc3RyaW5nKHggPSAiZmVhdHVyZSIsIHkgPSAibnVtX21pc3NpbmciLCBmaWxsID0gIkJhbmQiKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKCJCYW5kIiwgdmFsdWVzID0gYygiR29vZCIgPSAiI0I3RjFCMiIsICJPa2F5IiA9ICIjRkRGNkI1IiwgIlBvb3IiID0gIiNFRUFDN0QiLCAiU2NhcmNlIiA9ICIjRDM1RDYwIikpICsgCiAgICBjb29yZF9mbGlwKCkgKyB4bGFiKE5VTEwpICsgeWxhYigiTWlzc2luZyBSb3dzIikKICBnZW9tX2xhYmVsX2FyZ3NfbGlzdCA8LSBsaXN0KG1hcHBpbmcgPSBhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQoMTAwICogcGN0X21pc3NpbmcsIDIpLCAiJSIpKSkKICBvdXRwdXQgPC0gb3V0cHV0ICsgZG8uY2FsbCgiZ2VvbV9sYWJlbCIsIGMoZ2VvbV9sYWJlbF9hcmdzX2xpc3QsIGdlb21fbGFiZWxfYXJncykpCiAgY2xhc3Mob3V0cHV0KSA8LSBjKCJzaW5nbGUiLCBjbGFzcyhvdXRwdXQpKQogIHBsb3REYXRhRXhwbG9yZXIocGxvdF9vYmogPSBvdXRwdXQsIHRpdGxlID0gdGl0bGUsIGdndGhlbWUgPSBnZ3RoZW1lLCB0aGVtZV9jb25maWcgPSB0aGVtZV9jb25maWcpCn0KYGBgCgoqKioKIyBTdXBwbGVtZW50YXJ5IEluZm9ybWF0aW9uIHstfQoKIyMgUFJJU01BIHstfQoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uaWNob2xhc3d1bnovdXYtbWV0YS1hbmFseXNpcy9tYWluL2ZpbGVzL0ZpZyUyMFMxJTIwLSUyMFBSSVNNQSUyMGRpYWdyYW0uUE5HKQoKKipGaWcuIFMxLioqIFBSSVNNQSBmbG93IGRpYWdyYW0gZm9yIHRoZSBzeXN0ZW1hdGljIGRhdGEtY29sbGVjdGlvbiBwcm9jZXNzLiAqbiogPSBudW1iZXIgb2YgcGFwZXJzIHJlbWFpbmluZyBhZnRlciBlYWNoIHN0YWdlIG9mIHNlbGVjdGlvbi4gKmsqID0gbnVtYmVyIG9mIGVmZmVjdCBzaXplIGFmdGVyIHByb2Nlc3NpbmcgaW5kaXZpZHVhbCBkYXRhLCBhbmQgKm4qIGlzIG51bWJlciBvZiBvYnNlcnZhdGlvbnMvcmVjb3JkcyBhZnRlciBwcm9jZXNzaW5nIGRhdGEuIFNlYXJjaGVzIHdlcmUgZ3JvdXBlZCBieSB0YXhvbm9taWMgZ3JvdXBzLgoKKioqCgojIERhdGFzZXQgey19CgojIyBDYWxjdWxhdGUgZWZmZWN0IHNpemUsICRsblJSJCwgYW5kIHNhbXBsaW5nIHZhcmlhbmNlLCAkdl9pJCB7LX0KClRoZSByYXcgZGF0YSBmb3IgYW5hbHlzaXMgaXMgYXZhaWxhYmxlIG9uIFtHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9uaWNob2xhc3d1bnovdXYtbWV0YS1hbmFseXNpcykuIFRoaXMgc2VjdGlvbiBpcyB0aGUgd29ya2Zsb3cgdG8gaW1wb3J0IGFuZCBjbGVhbiB0aGUgcmF3IGRhdGEgZm9yIGFuYWx5c2lzLiBFZmZlY3Qgc2l6ZSBhcyB0aGUgbmF0dXJhbCBsb2ctdHJhbnNmb3JtZWQgcmVzcG9uc2UgcmF0aW8sIGxuUlIgXEByZWYoZXE6UlIpLCBhbmQgdGhlIHNhbXBsaW5nIHZhcmlhbmNlLCAkdl9pJCBcQHJlZihlcTp2aSksIHdhcyBjYWxjdWxhdGVkIGZvbGxvd2luZyBASGVkZ2VzMjAxNDoKCiQkClxiZWdpbntlcXVhdGlvbn0KbG5SUiA9IFxsbiBcbGVmdCggXGZyYWN7XGJhcntYfV97MX19e1xiYXJ7WH1fezJ9fVxyaWdodCksCihcI2VxOlJSKQpcZW5ke2VxdWF0aW9ufQokJAokJApcYmVnaW57ZXF1YXRpb259CnZfaSA9IFxmcmFje1NEX3sxfV4yfSB7XGJhcntYfV4yX3sxfW5fezF9fSArIFxmcmFje1NEX3syfV4yfSB7XGJhcntYfV4yX3syfW5fezJ9fSwKKFwjZXE6dmkpClxlbmR7ZXF1YXRpb259CiQkCgp3aGVyZSAkXGJhcntYfV8xJCwgJFNEXzEkLCBhbmQgJG5fMSQgYXJlIHRoZSBtZWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIGFuZCBzYW1wbGUgc2l6ZSBvZiB0aGUgKipleHBvc2VkKiogZ3JvdXAsIHJlc3BlY3RpdmVseSwgd2hpbGUgJFxiYXJ7WH1fMiQsICRTRF8yJCwgYW5kICRuXzIkIGFyZSB0aGUgbWVhbiwgc3RhbmRhcmQgZGV2aWF0aW9uLCBhbmQgc2FtcGxlIHNpemUgb2YgdGhlICoqY29udHJvbCoqIGdyb3VwLCByZXNwZWN0aXZlbHkuIFRoZSAqKnN0YW5kYXJkIGVycm9yKiosICRzZV9pJCBcQHJlZihlcTpzZWkpLCB3YXMgY2FsY3VsYXRlZCBhczoKCiQkClxiZWdpbntlcXVhdGlvbn0Kc2Vfe2l9ID1cc3FydHt2X2l9LgooXCNlcTpzZWkpClxlbmR7ZXF1YXRpb259CiQkCgpUaGUgaW52ZXJzZSBvZiAkc2VfaSQgb3IgKipwcmVjaXNpb24qKiBcQHJlZihlcTppbnYpIHdhcyBjYWxjdWxhdGVkIGFzOgoKJCQKXGJlZ2lue2VxdWF0aW9ufQpwX3tpfSA9IFxmcmFjezF9e3NlX2l9LgooXCNlcTppbnYpClxlbmR7ZXF1YXRpb259CiQkCgpUbyBhY2NvdW50IGZvciB1bmJhbGFuY2VkIHNhbXBsaW5nLCB3ZSB1c2VkIHRoZSAnZWZmZWN0aXZlIHNhbXBsZSBzaXplJyBpbnN0ZWFkIG9mIHRoZSBzYW1wbGUgc2l6ZSAoJG5fMSQgKyAkbl8yJCkgZm9yIHRoZSBtZXRhLWFuYWx5c2lzIG9mIGxuUlIgW0BOYWthZ2F3YTIwMjJdLiBUaGUgZWZmZWN0aXZlIHNhbXBsZSBzaXplIFxAcmVmKGVxOmVzcykgaXMgZm9ybXVsYXRlZCBhczoKCiQkClxiZWdpbntlcXVhdGlvbn0KNFx0aWxkZXtuX3tpfX0gPSBcZnJhY3s0bl97MWl9IG5fezJpfX17bl97MWl9ICsgbl97Mml9fS4KKFwjZXE6ZXNzKQpcZW5ke2VxdWF0aW9ufQokJAoKV2hlbiAkbiQgPSAkbl8xJCA9ICRuXzIkLCB0aGUgZm9ybXVsYSByZWR1Y2VzIHRvIDIkbiQuIEluZGVlZCwgdGhlIGludmVyc2Ugb2YgJFx0aWxkZXtuX3tpfX0kIGlzIGEgcGFydCBvZiBzYW1wbGluZyB2YXJpYW5jZSBpbiBsblJSIFxAcmVmKGVxOmludmVzcyk6CgokJApcYmVnaW57ZXF1YXRpb259ClxmcmFjezF9e1x0aWxkZXtuX3tpfX19ID0gXGZyYWN7bl97MWl9ICsgbl97Mml9fXtuX3sxaX0gbl97Mml9fSA9IFxmcmFjezF9e25fezFpfX0gKyBcZnJhY3sxfXtuX3syaX19LgooXCNlcTppbnZlc3MpClxlbmR7ZXF1YXRpb259CiQkCgpBbGwgY29udmVyc2lvbnMgZm9yIHRoZSBzdGFuZGFyZCBlcnJvciAoJHNlX2kkKSwgc2FtcGxpbmcgdmFyaWFuY2UsIHByZWNpc2lvbiAodGhlIGludmVyc2Ugb2YgJHNlX2kkKSwgZWZmZWN0aXZlIHNhbXBsZSBzaXplICgkNFx0aWxkZXtuX3tpfX0kKSBhbmQgdGhlIGludmVyc2Ugb2YgJFx0aWxkZXtuX3tpfX0kICgkXGZyYWN7MX17XHRpbGRle25fe2l9fX0kKSBmb2xsb3dlZCBATmFrYWdhd2EyMDIyLiBEYXRhIHdlcmUgYWxzbyBwcmVwYXJlZCB0byB0ZXN0IGZvciBwdWJsaWNhdGlvbiBiaWFzLCBhbmQgc291cmNlcyBvZiBub24taW5kZXBlbmRhbmNlIHN1Y2ggYXMgc2hhcmVkIGNvbnRyb2xzLCBzdHVkeSBlZmZlY3QsIHNwZWNpZXMgZWZmZWN0LCBhbmQgcGh5bG9nZW55LgoKYGBge3IgY2xlYW4sIG1lc3NhZ2U9RkFMU0V9CiMgTG9hZCBhbmQgY2xlYW4gcmF3IGRhdGEKcmF3X2RhdCA8LSByZWFkLmNzdigiL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvVVYgbWV0YS1hbmFseXNpcy9WZXJ0ZWJyYXRlX1VWX01ldGFBbmFseXNpc19GSU5BTC5jc3YiKSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiZXNfSUQiKSAlPiUgIyBhZGQgZWZmZWN0IHNpemUgSUQKICBkcGx5cjo6bXV0YXRlKHZpICAgICAgICAgICAgPSB0X1NEIF4gMiAvICh0X24gKiB0X21lYW4gXiAyKSArIGNfU0QgXiAyIC8gKGNfbiAqIGNfbWVhbiBeIDIpLCAjIFNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgc2VpICAgICAgICAgICA9IHNxcnQodmkpLCAjIFN0YW5kYXJkIGVycm9yIChTRSkKICAgICAgICAgICAgICAgIHNlaV9pbnYgICAgICAgPSAxIC8gc2VpLCAjIFByZWNpc2lvbiAoaW52ZXJzZSBvZiBTRSkKICAgICAgICAgICAgICAgIGVmZl9uICAgICAgICAgPSAoNCAqIGNfbiAqIHRfbikgLyAoY19uICsgdF9uKSwgIyBFZmZlY3RpdmUgc2FtcGxlIHNpemUKICAgICAgICAgICAgICAgIGludl9lZmZfbiAgICAgPSAoY19uICsgdF9uKSAvIChjX24gKiB0X24pLCAjIEludmVyc2Ugb2YgZWZmX24KICAgICAgICAgICAgICAgIHNxcnRfaW52X2VmZiAgPSBzcXJ0KGludl9lZmZfbiksICMgU3F1YXJlIHJvb3Qgb2YgdGhlIGludmVyc2Ugb2YgZWZmX24KICAgICAgICAgICAgICAgIHllYXJfY2VudHJlICAgPSBwdWJfeWVhciAtIG1lYW4ocHViX3llYXIpLCAgIyBNZWFuLWNlbnRyaW5nIHllYXIgb2YgcHVibGljYXRpb24pCiAgICAgICAgICAgICAgICBsbl9kZWx0YV9kb3NlID0gbG9nKGRlbHRhX2Rvc2VfSl9kYXkpLAogICAgICAgICAgICAgICAgbG5fZHVyX2RheSAgICA9IGxvZyh0X2R1cmF0aW9uX2RheSksCiAgICAgICAgICAgICAgICBzcGVjaWVzX09UTCAgID0gYXMuZmFjdG9yKHNwZWNpZXNfT1RMKSwKICAgICAgICAgICAgICAgIGxpZmVfc3RhZ2UgICAgPSBmYWN0b3IobGlmZV9zdGFnZSwgbGV2ZWxzID0gYygiRW1icnlvIiwgIkxhcnZhIiwgIkp1dmVuaWxlIiwgIkFkdWx0IikpLAogICAgICAgICAgICAgICAgcmVnaW9uICAgICAgICA9IGZhY3RvcihyZWdpb24sIGxldmVscyA9IGMoIlRyb3BpY2FsIiwgIlN1YnRyb3BpY2FsIiwgIlRlbXBlcmF0ZSIpKSwKICAgICAgICAgICAgICAgIGNsYXNzaWZpY2F0aW9uID0gYXMuZmFjdG9yKGNsYXNzaWZpY2F0aW9uKSwKICAgICAgICAgICAgICAgIHNvdXJjZV9jYXQgICAgPSBhcy5mYWN0b3Ioc291cmNlX2NhdCksCiAgICAgICAgICAgICAgICBtZWRpdW0gICAgICAgID0gYXMuZmFjdG9yKG1lZGl1bSksCiAgICAgICAgICAgICAgICB0cmFpdCA9IGFzLmZhY3Rvcih0cmFpdCksCiAgICAgICAgICAgICAgICBtZXRyaWMgICAgICAgID0gYXMuZmFjdG9yKG1ldHJpYyksCiAgICAgICAgICAgICAgICB1dl90eXBlICAgICAgID0gYXMuZmFjdG9yKHV2X3R5cGUpKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgtYyhyZWZlcmVuY2UsIG5vdGVzKSkKCiMgQWNjb3VudCBmb3Igc2hhcmVkIGNvbnRyb2xzCk0gPC0gbWV0YUFpZFI6Om1ha2VfVkNWX21hdHJpeChkYXRhID0gcmF3X2RhdCwgViA9ICJ2aSIsIGNsdXN0ZXIgPSAic2hhcmVkX2NvbnRyb2wyIiwgbSA9ICJjX21lYW4iLAogICAgICAgICAgICAgICAgICAgICBzZCA9ICJjX1NEIiwgbiA9ICJjX24iLCB0eXBlID0gInZjdiIsIHZjYWwgPSAiUk9NIiwgb2JzID0gImVzX0lEIikKYGBgCgojIyBEYXRhIHN1bW1hcnkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KClRoZSBgcmF3X2RhdGAgdXNlZCBmb3IgdGhlIG1ldGEtYW5hbHlzaXMgY29tcHJpc2VzIG9mIGByIG5yb3cocmF3X2RhdClgIGluZGl2aWR1YWwgZWZmZWN0IHNpemVzIGZyb20gYHIgbGVuZ3RoKHVuaXF1ZShyYXdfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMgYWNyb3NzIGByIGxlbmd0aCh1bmlxdWUocmF3X2RhdCRzcGVjaWVzX09UTCkpYCBzcGVjaWVzIChkZXRhaWxlZCBpbiAqKlN1cHBsZW1lbnRhcnkgVGFibGUgUzEqKikuCgojIyMgVGFibGUgUzEgLSBTdW1tYXJ5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIFJlc3BvbnNlcy4qKiBUcmFpdCBjYXRlZ29yaWVzIGFuZCB0aGUgc3BlY2lmaWMgbWV0cmljcyBleHRyYWN0ZWQgZm9yIHRoZSBzdHVkeS4gTnVtYmVyIG9mIGVmZmVjdCBzaXplcywgc3R1ZGllcyBhbmQgc3BlY2llcyBhcmUgc2hvd24uIFJlc3BvbnNlcyB3aXRoIGFzdGVyaXNrcyB3ZXJlIGNvcnJlY3RlZCBmb3IgZGlyZWN0aW9uLiBDQVQgPSBjYXRhbGFzZSwgR1NUID0gZ2x1dGF0aGlvbmUgUy10cmFuc2ZlcmFzZSwgTERIID0gbGFjdGF0ZSBkZWh5ZHJvZ2VuYXNlLCBMUE8gPSBsYWN0b3Blcm94aWRhc2UsIFJPUyA9IHJlYWN0aXZlIG94eWdlbiBzcGVjaWVzLCBTT0QgPSBzdXBlcm94aWRlIGRpc211dGFzZSwgKlUqfmNyaXR+ID0gY3JpdGljYWwgc3dpbW1pbmcgc3BlZWQuCgpgYGB7ciB0YWJsZVMxYSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdGFibGVTMSA8LSBkYXRhLmZyYW1lKHJhd19kYXQgJT4lIAogIGRwbHlyOjpncm91cF9ieSh0cmFpdCwgbWV0cmljKSAlPiUgCiAgZHBseXI6OnN1bW1hcmlzZShlZl9uID0gbigpLAogICAgICAgICAgICAgICAgICAgc3R1ZHlfbiA9IGxlbmd0aCh1bmlxdWUoc3R1ZHlfSUQpKSwKICAgICAgICAgICAgICAgICAgIHNwZWNpZXNfbiA9IGxlbmd0aCh1bmlxdWUoc3BlY2llc19PVEwpKSkpICU+JQogIGRwbHlyOjptdXRhdGUobWV0cmljID0gY2FzZV93aGVuKAogICAgbWV0cmljICVpbiUgIkgyTzIgTGV2ZWxzIiB+ICJIfjJ+T34yfiBMZXZlbHMqIiwKICAgIG1ldHJpYyAlaW4lICJST1MgUHJvZHVjdGlvbiIgfiAiUk9TIFByb2R1Y3Rpb24qIiwKICAgIG1ldHJpYyAlaW4lICJhbGFuaW5lIGFtaW5vdHJhbnNmZXJhc2UiIH4gIkFsYW5pbmUgQW1pbm90cmFuc2ZlcmFzZSoiLAogICAgbWV0cmljICVpbiUgImFzcGFyYXRlIGFtaW5vdHJhbnNmZXJhc2UiIH4gIkFzcGFyYXRlIEFtaW5vdHJhbnNmZXJhc2UqIiwKICAgIG1ldHJpYyAlaW4lICJUaGlvYmFyYml0dXJpYyBBY2lkIFJlYWN0aXZlIFN1YnN0YW5jZXMiIH4gIlRoaW9iYXJiaXR1cmljIEFjaWQgUmVhY3RpdmUgU3Vic3RhbmNlcyoiLAogICAgbWV0cmljICVpbiUgIlByb3RlaW4gUGVyb3hpZGUgTGV2ZWxzIiB+ICJQcm90ZWluIFBlcm94aWRlIExldmVscyoiLAogICAgbWV0cmljICVpbiUgIlByb3RlaW4gQ2FyYm9ueWwiIH4gIlByb3RlaW4gQ2FyYm9ueWwqIiwKICAgIG1ldHJpYyAlaW4lICJNYWxvbmRpYWxkZWh5ZGUiIH4gIk1hbG9uZGlhbGRlaHlkZSoiLAogICAgbWV0cmljICVpbiUgIkxQTyBBY3Rpdml0eSIgfiAiTFBPIEFjdGl2aXR5KiIsCiAgICBtZXRyaWMgJWluJSAiVWNyaXQiIH4gIipVKn5jcml0fiIsCiAgICBtZXRyaWMgJWluJSAiRE5BIERhbWFnZSIgfiAiRE5BIERhbWFnZSoiLAogICAgbWV0cmljICVpbiUgIlB5cmltaWRpbmUgRGltZXJzIiB+ICJQeXJpbWlkaW5lIERpbWVycyoiLAogICAgVFJVRSB+IGFzLmNoYXJhY3RlcihtZXRyaWMpKSkKICAKIyBQcmVwYXJlIGNvbHVtbiBuYW1lcyB3aXRoIExhVGVYCnRhYmxlUzEgJT4lCiAgZHBseXI6OnJlbmFtZSgiQ2F0ZWdvcmlzZWQgdHJhaXQiID0gdHJhaXQsCiAgICAgICAgICAgICAgICAiU3BlY2lmaWMgbWV0cmljIiAgID0gbWV0cmljLAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKm4qKSIgICAgID0gc3R1ZHlfbiwKICAgICAgICAgICAgICAgICJTcGVjaWVzICgqbiopIiAgICAgPSBzcGVjaWVzX24pICU+JQogIGtuaXRyOjprYWJsZSgpIApgYGAKCiMjIyBMaWZlIHN0YWdlIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIExpZmUgc3RhZ2UuKiogQ29udGludWF0aW9uIG9mIGRhdGEgc3VtbWFyeSB3aXRoIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb24gdGhlIG51bWJlciBvZiBlZmZlY3Qgc2l6ZSwgc3R1ZGllcywgYW5kIHNwZWNpZXMgaW4gdGhlIGRhdGFiYXNlIGJ5IGxpZmUgc3RhZ2UuIFByZXNlbnRhdGlvbiBpbiBvcmRlciBieSB0aGUgbnVtYmVyIG9mIGVmZmVjdCBzaXplIGluIHRoZSBkYXRhLgoKYGBge3IgdGFibGVTMWIsIGVjaG89RkFMU0V9CmRhdGEuZnJhbWUocmF3X2RhdCAlPiUgCiAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkobGlmZV9zdGFnZSkgJT4lIAogICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShlZl9uICAgID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHVkeV9uID0gbGVuZ3RoKHVuaXF1ZShzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXNfT1RMKSkpKSAlPiUKICBkcGx5cjo6YXJyYW5nZSgtZWZfbikgJT4lCiAgZHBseXI6OnJlbmFtZSgiTGlmZSBzdGFnZSIgICAgICAgID0gbGlmZV9zdGFnZSwKICAgICAgICAgICAgICAgICJFZmZlY3Qgc2l6ZSAoKmsqKSIgPSBlZl9uLAogICAgICAgICAgICAgICAgIlN0dWRpZXMgKCpuKikiICAgICA9IHN0dWR5X24sCiAgICAgICAgICAgICAgICAiU3BlY2llcyAoKm4qKSIgICAgID0gc3BlY2llc19uKSAlPiUKICBrbml0cjo6a2FibGUoKQpgYGAKCiMjIyBTcGVjaWVzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIFNwZWNpZXMuKiogQ29udGludWF0aW9uIG9mIGRhdGEgc3VtbWFyeSB3aXRoIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb24gdGhlIG51bWJlciBvZiBlZmZlY3Qgc2l6ZSwgYW5kIHN0dWRpZXMgaW4gdGhlIGRhdGFiYXNlIGJ5IHNwZWNpZXMuIFByZXNlbnRhdGlvbiBpbiBvcmRlciBieSB0aGUgbnVtYmVyIG9mIGVmZmVjdCBzaXplIGluIHRoZSBkYXRhLgoKYGBge3IgdGFibGVTMWMsIGVjaG89RkFMU0V9CmRhdGEuZnJhbWUocmF3X2RhdCAlPiUgCiAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoY2xhc3MsIHNwZWNpZXNfT1RMKSAlPiUgCiAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGVmX24gICAgPSBuKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0dWR5X24gPSBsZW5ndGgodW5pcXVlKHN0dWR5X0lEKSkpKSAlPiUKICBmb3JtYXRfY2VsbHMoMTo0NywgMiwgIml0YWxpY3MiKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyX3JlcGxhY2Uoc3BlY2llc19PVEwsICJfIiwgIiAiKSkgJT4lCiAgZHBseXI6OmFycmFuZ2UoLWVmX24pICU+JQogIGRwbHlyOjpyZW5hbWUoIkNsYXNzIiAgICAgICAgICAgICA9IGNsYXNzLAogICAgICAgICAgICAgICAgIlNwZWNpZXMiICAgICAgICAgICA9IHNwZWNpZXNfT1RMLAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKm4qKSIgICAgID0gc3R1ZHlfbikgJT4lCiAga25pdHI6OmthYmxlKCkKYGBgCgojIyMgVHJhaXRzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIFRyYWl0cy4qKiBDb250aW51YXRpb24gb2YgZGF0YSBzdW1tYXJ5IHdpdGggYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvbiB0aGUgbnVtYmVyIG9mIGVmZmVjdCBzaXplLCBzdHVkaWVzLCBhbmQgc3BlY2llcyBpbiB0aGUgZGF0YWJhc2UgYnkgYnkgdHJhaXRzLiBQcmVzZW50YXRpb24gaW4gb3JkZXIgYnkgdGhlIG51bWJlciBvZiBlZmZlY3Qgc2l6ZSBpbiB0aGUgZGF0YS4KCmBgYHtyIHRhYmxlUzFkLCBlY2hvPUZBTFNFfQpkYXRhLmZyYW1lKHJhd19kYXQgJT4lIAogICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KHRyYWl0KSAlPiUgCiAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGVmX24gICAgICA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1ZHlfbiAgID0gbGVuZ3RoKHVuaXF1ZShzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXNfT1RMKSkpKSAlPiUKICBkcGx5cjo6YXJyYW5nZSgtZWZfbikgJT4lCiAgZHBseXI6OnJlbmFtZSgiVHJhaXQiICAgICAgICAgICAgID0gdHJhaXQsCiAgICAgICAgICAgICAgICAiRWZmZWN0IHNpemUgKCprKikiID0gZWZfbiwKICAgICAgICAgICAgICAgICJTdHVkaWVzICgqayopIiAgICAgPSBzdHVkeV9uLAogICAgICAgICAgICAgICAgIlNwZWNpZXMgKCpuKikiICAgICA9IHNwZWNpZXNfbikgJT4lCiAga25pdHI6OmthYmxlKCkKYGBgCgojIyMgVVYgdHlwZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzEgLSBVViB0eXBlLioqIENvbnRpbnVhdGlvbiBvZiBkYXRhIHN1bW1hcnkgd2l0aCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uIHRoZSBudW1iZXIgb2YgZWZmZWN0IHNpemUsIHN0dWRpZXMsIGFuZCBzcGVjaWVzIGluIHRoZSBkYXRhYmFzZSBieSBVViByYWRpYXRpb24gdHlwZSBhbmQgdGF4b25vbWljIGNsYXNzLiBQcmVzZW50YXRpb24gaW4gb3JkZXIgYnkgdGhlIG51bWJlciBvZiBlZmZlY3Qgc2l6ZSBpbiB0aGUgZGF0YS4KCmBgYHtyIHRhYmxlUzFlLCBlY2hvPUZBTFNFfQpkYXRhLmZyYW1lKHJhd19kYXQgJT4lIAogICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KHV2X3R5cGUsIGNsYXNzKSAlPiUgCiAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGVmX24gICAgICA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1ZHlfbiAgID0gbGVuZ3RoKHVuaXF1ZShzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXNfT1RMKSkpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJVViB0eXBlIiAgICAgICAgICAgPSB1dl90eXBlLAogICAgICAgICAgICAgICAgIkNsYXNzIiAgICAgICAgICAgICA9IGNsYXNzLAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKmsqKSIgICAgID0gc3R1ZHlfbiwKICAgICAgICAgICAgICAgICJTcGVjaWVzICgqbiopIiAgICAgPSBzcGVjaWVzX24pICU+JQogIGtuaXRyOjprYWJsZSgpCmBgYAoKIyMjIFNvdXJjZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzEgLSBTb3VyY2UuICoqIENvbnRpbnVhdGlvbiBvZiBkYXRhIHN1bW1hcnkgd2l0aCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uIHRoZSBudW1iZXIgb2YgZWZmZWN0IHNpemUsIHN0dWRpZXMsIGFuZCBzcGVjaWVzIGluIHRoZSBkYXRhYmFzZSBieSBjb2xsZWN0aW9uIHNvdXJjZS4gUHJlc2VudGF0aW9uIGluIG9yZGVyIGJ5IHRoZSBudW1iZXIgb2YgZWZmZWN0IHNpemUgaW4gdGhlIGRhdGEuCgpgYGB7ciB0YWJsZVMxZiwgZWNobz1GQUxTRX0KZGF0YS5mcmFtZShyYXdfZGF0ICU+JSAKICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShzb3VyY2VfY2F0KSAlPiUgCiAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGVmX24gICAgICA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1ZHlfbiAgID0gbGVuZ3RoKHVuaXF1ZShzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXNfT1RMKSkpKSAlPiUKICBkcGx5cjo6YXJyYW5nZSgtZWZfbikgJT4lCiAgZHBseXI6OnJlbmFtZSgiU291cmNlIiAgICAgICAgICAgID0gc291cmNlX2NhdCwKICAgICAgICAgICAgICAgICJFZmZlY3Qgc2l6ZSAoKmsqKSIgPSBlZl9uLAogICAgICAgICAgICAgICAgIlN0dWRpZXMgKCprKikiICAgICA9IHN0dWR5X24sCiAgICAgICAgICAgICAgICAiU3BlY2llcyAoKm4qKSIgICAgID0gc3BlY2llc19uKSAlPiUKICBrbml0cjo6a2FibGUoKQpgYGAKCgoqKioKCiMjIFdoaWNoIGRhdGEgYXJlIG1pc3Npbmc/IHstfQoKVGhlIGZvbGxvd2luZyBkYXRhIHdlcmUgbm90IGluY2x1ZGVkIGR1ZSBvZiBwb29yIHJlcG9ydGluZyBieSB0aGUgc3R1ZGllcyBleHRyYWN0ZWQ6IGFnZSAoaG91cnMgcG9zdC1mZXJ0aWxpc2F0aW9uIGFuZCBkYXlzIHBvc3QtaGF0Y2hpbmcpLCBib2R5IGxlbmd0aCwgYm9keSBtYXNzLCBsYXRpdHVkZSwgYW5kIGxvbmdpdHVkZS4gVGhyZXNob2xkIHdhcyBzZXQgYXQgR29vZCA9IDAtNSUsIE9rYXkgPSA1LTQwJSwgUG9vciA9IDQwLTgwJSwgU2NhcmNlID0gODAtMTAwJS4KCmBgYHtyIG1pc3NpbmcsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRX0KcmF3X2RhdCAlPiUKICBkcGx5cjo6c2VsZWN0KC1jKHllYXJfY2VudHJlLCBzcGVjaWVzX09UTCwgdHJhaXQsIGNsYXNzaWZpY2F0aW9uLCBtZXRyaWMsIAogICAgICAgICAgICAgICAgICAgc291cmNlX2NhdCwgc2VpLCBzZWlfaW52LCBlZmZfbiwgaW52X2VmZl9uLCBzcXJ0X2ludl9lZmYsIGNsYXNzLCBlc19JRCwgCiAgICAgICAgICAgICAgICAgICBzdHVkeV9JRCwgY19TRSwgdF9TRSwgc291cmNlX2xvY2F0aW9uLCBsblJSLCB2aSwgY29ycmVjdGVkLCBzaGFyZWRfY29udHJvbCwKICAgICAgICAgICAgICAgICAgIHNoYXJlZF9jb250cm9sMikpICU+JQogIHBsb3RfbWlzc2luZ18yKGdlb21fbGFiZWxfYXJncyA9IGxpc3QoInNpemUiID0gMikpCmBgYAoKKipGaWcuIFMyLioqIEZyZXF1ZW5jeSBvZiBtaXNzaW5nIGRhdGEgZm9yIGVhY2ggdmFyaWFibGUgZXh0cmFjdGVkLgoKKioqCgojIyBQcmVwYXJlIHBoeWxvZ2VueSBmb3IgYW5hbHlzaXMgey19CgpUaGlzIHNlY3Rpb24gcHJvdmlkZXMgdGhlIHdvcmtmbG93IHRvIGV4dHJhY3QgdGhlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20gdGhlIFtPcGVuIFRyZWUgb2YgTGlmZV0oaHR0cHM6Ly90cmVlLm9wZW50cmVlb2ZsaWZlLm9yZy8pIChPVEw7IHNlZSBwaHlsb2dlbmV0aWMgcmVjb25zdHJ1Y3Rpb24gaW4gbWFpbiB0ZXh0KSwgbWF0Y2ggdGhlIE9UTCBuYW1lcyB3aXRoIHRoZSBkYXRhIHNldCwgYW5kIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIG1hdHJpeCBmb3Igc3Vic2VxdWVudCBhbmFseXNpcy4KCmBgYHtyIHBoeWxvLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0Kc3BfYWxsICA8LSBzb3J0KHVuaXF1ZShhcy5jaGFyYWN0ZXIocmF3X2RhdCRzcGVjaWVzX09UTCkpKSAjIGdlbmVyYXRlIGxpc3Qgb2Ygc3BlY2llcyAoYXMgY2hhcmFjdGVyIGZvcm1hdCkKdGF4YSAgICA8LSByb3RsOjp0bnJzX21hdGNoX25hbWVzKG5hbWVzID0gc3BfYWxsKSAjIG1hdGNoIHRheG9ub21pYyBuYW1lcyB0byB0aGUgT1RMCgojIGNoZWNrIGlmIHNwZWNpZXMgbGlzdCBtYXRjaCBPVCBpZGVudGlmaWVyCiN0YXhhW3RheGEkYXBwcm94aW1hdGVfbWF0Y2ggPT0gVFJVRSxdICMgbm9uZSBzbyBmYXIKCiMgcmV0cmlldmluZyBwaHlsb2dlbmV0aWMgcmVsYXRpb25zaGlwcyBhbW9uZyB0YXhhIGluIHRoZSBmb3JtIG9mIGEgdHJpbW1lZCBzdWItdHJlZQp0cmVlIDwtIHJvdGw6OnRvbF9pbmR1Y2VkX3N1YnRyZWUob3R0X2lkcyA9IHJvdGw6Om90dF9pZCh0YXhhKSwgbGFiZWxfZm9ybWF0ID0gIm5hbWUiKQoKIyBDaGFuZ2UgT1RMIHNwZWNpZXMgbmFtZSB0byBtYXRjaCByYXdfZGF0CnRyZWUkdGlwLmxhYmVsW3RyZWUkdGlwLmxhYmVsID09ICJPbmNvcmh5bmNodXNfbXlraXNzXyhzcGVjaWVzX2luX2RvbWFpbl9FdWthcnlvdGEpIl0gPC0gIk9uY29yaHluY2h1c19teWtpc3MiCgojIENvbXB1dGUgYnJhbmNoIGxlbmd0aHMKdHJlZSA8LSBhcGU6OmNvbXB1dGUuYnJsZW4odHJlZSwgbWV0aG9kID0gIkdyYWZlbiIsIHBvd2VyID0gMSkKdHJlZSA8LSBhcGU6Om11bHRpMmRpKHRyZWUsIHJhbmRvbSA9IFRSVUUpICMgdXNlIGEgcmFuZG9taXphdGlvbiBhcHByb2FjaCB0byBkZWFsIHdpdGggcG9seXRvbWllcwoKcGh5bG9fY29yIDwtIGFwZTo6dmN2KHRyZWUsIGNvciA9IFQpCmBgYAoKKioqCgojIE1ldGEtYW5hbHlzaXMgey19CgojIyBNb2RlbCBzZWxlY3Rpb24gey19CgpQcmlvciB0byB0aGUgbWV0YS1hbmFseXNpcywgd2UgcGVyZm9ybWVkIG1vZGVsIHNlbGVjdGlvbiBvbiBhbGwgbW9kZXJhdG9ycyB2aWEgdGhlIGBkcmVkZ2VgIGZ1bmN0aW9uLiBEdWUgdG8gdGhlIGxvbmcgcHJvY2Vzc2luZyB0aW1lLCB3ZSB1c2VkIHRoZSBzYXZlZCBSRFMgZmlsZSB3aGVuIGNyZWF0aW5nIHRoZSBodG1sIGZpbGUuCgpgYGB7ciBzZWxlY3Rpb24sIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUV9CmV2YWwobWV0YWZvcjo6Oi5NdU1JbikKb3B0aW9ucyhuYS5hY3Rpb24gPSAibmEuZmFpbCIpICMgcmVxdWlyZWQgZm9yIGRyZWRnZSB0byBydW4KCm11bWluX2RhdCA8LSByYXdfZGF0ICU+JSBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpCm11bWluX2RhdCA8LSBtdW1pbl9kYXRbIWFwcGx5KHJhd19kYXRbLGMoImxpZmVfc3RhZ2UiLCAic291cmNlX2NhdCIsICJyZWdpb24iLCAibWVkaXVtIiwgImNsYXNzaWZpY2F0aW9uIiwgInRyYWl0IiwgInV2X3R5cGUiLCAiZXhwb3N1cmVfdGVtcCIsICJsbl9kdXJfZGF5IiwgImxuX2RlbHRhX2Rvc2UiKV0sIDEsIGFueU5BKSxdICMgcmVtb3ZlIHJvd3Mgd2l0aCBhbnkgTkEgdmFsdWUgb24gb25lIG9mIHRoZXNlIGNvbHVtbnMKCiMgUnVuIG11bHRpLWxldmVsIG1vZGVsCm11bWluX21vZGVsIDwtIG1ldGFmb3I6OnJtYS5tdih5aSA9IGxuUlIsIFYgPSB2aSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RzID0gfmxpZmVfc3RhZ2UgKyBzb3VyY2VfY2F0ICsgcmVnaW9uICsgbWVkaXVtICsgY2xhc3NpZmljYXRpb24gKyB0cmFpdCArIHV2X3R5cGUgKyBleHBvc3VyZV90ZW1wICsgbG5fZHVyX2RheSArIGxuX2RlbHRhX2Rvc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gbGlzdCh+MSB8IGVzX0lELCB+MSB8IHN0dWR5X0lELCB+MSB8IHNwZWNpZXMsIH4xIHwgc3BlY2llc19PVEwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIgPSBsaXN0KHNwZWNpZXNfT1RMID0gcGh5bG9fY29yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSJNTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJ0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZzID0gImNvbnRhaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBtdW1pbl9kYXQpCgojY2FuZGlkYXRlX21vZGVscyA8LSBNdU1Jbjo6ZHJlZGdlKG11bWluX21vZGVsKSAjIGdlbmVyYXRlIGFsbCBwb3NzaWJsZSBjb21iaW5hdGlvbnMgb2YgbW9kZXJhdG9ycwojc2F2ZVJEUyhjYW5kaWRhdGVfbW9kZWxzLCBmaWxlID0gImNhbmRpZGF0ZV9tb2RlbHMucmRzIikKY2FuZGlkYXRlX21vZGVscyA8LSByZWFkUkRTKCIvVXNlcnMvbmljaG9sYXN3dS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1XZXN0ZXJuU3lkbmV5VW5pdmVyc2l0eS9VViBtZXRhLWFuYWx5c2lzL2NhbmRpZGF0ZV9tb2RlbHMucmRzIikKCm9wdGlvbnMobmEuYWN0aW9uID0gIm5hLm9taXQiKSAjIHNldCBiYWNrIHRvIGRlZmF1bHQKc3Vic2V0KGNhbmRpZGF0ZV9tb2RlbHMsIGRlbHRhIDw9IDIpICMgZGlzcGxheSBhbGwgbW9kZWxzIHdpdGhpbiAyIHZhbHVlcyBvZiBBSUNjCgpNdU1Jbjo6c3coTXVNSW46Om1vZGVsLmF2ZyhjYW5kaWRhdGVfbW9kZWxzLCBzdWJzZXQgPSBkZWx0YSA8PSAyKSkgIyBkaXNwbGF5IHdlaWdodCBvZiBlYWNoIG1vZGVyYXRvcnMKYGBgCgojIyBNZXRhLWFuYWx5c2lzIHstfQoKQ29uZHVjdCBwaHlsb2dlbmljYWxseSBjb250cm9sbGVkLCBtdWx0aS1sZXZlbCBtZXRhLWFuYWx5c2lzLiBUaGUgYGdsb2JhbF9tb2RlbGAgdGVzdGVkIHRoZSBvdmVyYWxsIGVmZmVjdCBvZiBVViBleHBvc3VyZSBvbiBlZmZlY3Qgc2l6ZSwgYW5kIHRlc3RlZCBmb3IgcHVibGljYXRpb24gYmlhcy4gVGhlIGBvdmVyYWxsX21vZGVsYCAoZGV0YWlsZWQgaW4gdGhlICdNZXRhLXJlZ3Jlc3Npb24nIHNlY3Rpb24pIHRlc3RlZCB0aGUgb3ZlcmFsbCBlZmZlY3Qgd2l0aCBhbGwgcmVsZXZhbnQgbW9kZXJhdG9ycyBiYXNlZCBvbiB0aGUgbW9kZWwgc2VjdGlvbiBwcm9jZXNzIGRlc2NyaWJlZCBhYm92ZS4gQWxsIG1vZGVscyBjb250YWluZWQgdGhlIGZvbGxvd2luZyByYW5kb20gZWZmZWN0czogRWZmZWN0IHNpemUgSUQsIHN0dWR5IElELCBzcGVjaWVzIElELCBzdHVkeSBJRCwgYW5kIHBoeWxvZ2VueS4KClRoZSBnbG9iYWwgbXVsdGktbGV2ZWwsIG1ldGEtYW5hbHl0aWMgbW9kZWwgd2FzIGZpdHRlZCBhcyBmb2xsb3dzOgoKJCQKXGJlZ2lue2VxdWF0aW9ufQpZX2kgPSBcYmV0YV8wICsgXGJldGFfMVxzcXJ0e1xmcmFjezF9e1x0aWxkZXtuX3tpfX19fSArIFxiZXRhXzJjKFx0ZXh0e3llYXJ9X2opICsgXGFscGhhX3trW2ldfSArIHNwX3trW2ldfSArIHNfe2pbaV19ICsgZV9pICsgbV9pLCBcXApcYWxwaGFfe2tbaV19IFxzaW0gIFx0ZXh0e05vcm1hbH0oMCwgXHNpZ21hXjJfe1x0ZXh0e3BoeWxvZ2VueX19XHRleHRiZntBfSksIFxcCnNwX3trW2ldfSBcc2ltICBcdGV4dHtOb3JtYWx9KDAsIFxzaWdtYV4yX3tcdGV4dHtzcGVjaWVzfX0pLCBcXApzX3trW2ldfSBcc2ltICBcdGV4dHtOb3JtYWx9KDAsIFxzaWdtYV4yX3tcdGV4dHtzdHVkeX19KSwgXFwKZV9pIFxzaW0gIFx0ZXh0e05vcm1hbH0oMCwgXHNpZ21hXjJfe1x0ZXh0e3Jlc2lkdWFsfX0pLCBcXAptX2kgXHNpbSAgXHRleHR7Tm9ybWFsfSgwLCB2X2kpLAooXCNlcTpnbG9iYWwpClxlbmR7ZXF1YXRpb259CiQkCgp3aGVyZSAkWV9pJCBpcyB0aGUgJGkkdGggZWZmZWN0IHNpemUsICRcYmV0YV8wJCBpcyB0aGUgd2VpZ2h0ZWQgb3ZlcmFsbCBtZXRhLWFuYWx5dGljIG1lYW4sICRcYmV0YV8xXHNxcnR7XGZyYWN7MX17XHRpbGRle25fe2l9fX19JCBpcyB0aGUgaW52ZXJzZSBvZiBlZmZlY3RpdmUgc2FtcGxlIHNpemUsICRcYmV0YV8yYyhcdGV4dHt5ZWFyfV9qKSQgaXMgdGhlIG1lYW4gY2VudHJpbmcgb2YgcHVibGljYXRpb24geWVhciwgYW5kICRcYWxwaGFfe2tbaV19JCBpcyB0aGUgcGh5bG9nZW5ldGljIGVmZmVjdCAoYSByYW5kb20gZWZmZWN0KSBmb3Igc3BlY2llcyAkayQgYXBwbGllZCB0byBlZmZlY3Qgc2l6ZSAkaSQgW0BDaW5hcjIwMjJdLiBQaHlsb2dlbmV0aWMgZWZmZWN0cyBhcmUgYXNzdW1lZCB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIGEgbWVhbiBvZiB6ZXJvIGFuZCB2YXJpYW5jZSAkXHNpZ21hXjJfe1x0ZXh0e3BoeWxvZ2VueX19JCBbaS5lLiAkKDAsIFxzaWdtYV4yX3tcdGV4dHtwaHlsb2dlbnl9fVx0ZXh0YmZ7QX0pJF0sIHdoZXJlICRcdGV4dGJme0F9JCBpcyBhIHBoeWxvZ2VuZXRpYyBjb3JyZWxhdGlvbiBtYXRyaXggZGVyaXZlZCBmcm9tIGEgcGh5bG9nZW5ldGljIHRyZWUuICRzcF97a1tpXX0kIGlzIHRoZSBzcGVjaWVzLXNwZWNpZmljIGVmZmVjdCBmb3IgdGhlICRrJHRoIHNwZWNpZXMgYXBwbGllZCB0byBlZmZlY3Qgc2l6ZSAkaSQsICRzX3trW2ldfSQgaXMgdGhlIHN0dWR5LXNwZWNpZmMgZWZmZWN0IGZvciB0aGUgJGokdGggc3R1ZHkgYXBwbGllZCB0byBlZmZlY3Qgc2l6ZSAkaSQsICRlX2kkIGlzIHRoZSBlZmZlY3Qgc2l6ZS1zcGVmaWMgZWZmZWN0ICh3aXRoaW4tc3R1ZHkgZWZmZWN0LCBvciByZXNpZHVhbHMpIGZvciB0aGUgJGkkdGggZWZmZWN0IHNpemUsIGFuZCAkbV9pJCBpcyB0aGUgc2FtcGxpbmcgZWZmZWN0IGZvciB0aGUgJGkkdGggZWZmZWN0IHNpemUsIHJlc3VsdGluZyBmcm9tIHZhcnlpbmcgcHJlY2lzaW9uIGZvciBlYWNoIGVmZmVjdCBzaXplLCAkdl9pJCAod2hpY2ggaXMga25vd24gYXMgdGhlIHNhbXBsaW5nIHZhcmlhbmNlIGZvciB0aGUgZWZmZWN0KS4KCiMjIE1ldGEtcmVncmVzc2lvbiB7LX0KCkNvbmR1Y3QgcGh5bG9nZW5pY2FsbHkgY29udHJvbGxlZCwgbXVsdGktbGV2ZWwgbWV0YS1yZWdyZXNzaW9uLiBUaGUgYG92ZXJhbGxfbW9kZWxgIGZvbGxvd3MgdGhlIHNhbWUgZm9ybXVsYSBcQHJlZihlcTpnbG9iYWwpIGJ1dCBhcHBsaWVzIG11bHRpcGxlIG1vZGVyYXRvciB2YXJpYWJsZXMgKCRcYmV0YSQpOgoKJCQKXGJlZ2lue2VxdWF0aW9ufQpZX2kgPSBcYmV0YV8wICsgXGRpc3BsYXlzdHlsZVxzdW1fe2wgPSAxfV57cH0gXGJldGFfbCB4X3tsW2ldfSArIFxhbHBoYV97a1tpXX0gKyBzcF97a1tpXX0gKyBzX3tqW2ldfSArIGVfaSArIG1faSwKKFwjZXE6b3ZlcmFsbCkKXGVuZHtlcXVhdGlvbn0KJCQKCndoZXJlICRcZGlzcGxheXN0eWxlXHN1bV97bCA9IDF9XntwfSBcYmV0YV9sIHhfe2xbaV19JCBpcyB0aGUgc3VtIG9mIGFsbCBlZmZlY3RzIGZvciBhbGwgbW9kZXJhdG9ycyAkeF9pJCAoZml4ZWQgZWZmZWN0czsgJHAkID0gbnVtYmVyIG9mIHNsb3BlcykuIEFsbCBvdGhlciBub3RhdGlvbnMgYXJlIHRoZSBzYW1lIGFzIGRlc2NyaWJlZCBhYm92ZSBcQHJlZihlcTpnbG9iYWwpLgoKYGBge3IgbWV0YSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9Cmdsb2JhbF9tb2RlbCA8LSBtZXRhZm9yOjpybWEubXYoeWkgPSBsblJSLCBWID0gTSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kcyA9IH4gMSArIHNxcnRfaW52X2VmZiArIHllYXJfY2VudHJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IGxpc3QofjEgfCBlc19JRCwgfjEgfCBzdHVkeV9JRCwgfjEgfCBzcGVjaWVzLCB+MSB8IHNwZWNpZXNfT1RMKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSID0gbGlzdChzcGVjaWVzX09UTCA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0iUkVNTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJ0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZzID0gImNvbnRhaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSByYXdfZGF0ICU+JQogICAgICAgIGRwbHlyOjptdXRhdGUoc3BlY2llc19PVEwgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3BlY2llc19PVEwsICIgIiwgIl8iKSkpCgojIE1vZGVyYXRvcnMgYmFzZWQgb24gYmVzdCBtb2RlbApvdmVyYWxsX21vZGVsIDwtIG1ldGFmb3I6OnJtYS5tdih5aSA9IGxuUlIsIFYgPSBNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHMgPSB+IDEgKyBsaWZlX3N0YWdlICsgdHJhaXQgKyB1dl90eXBlICsgbG5fZGVsdGFfZG9zZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSBsaXN0KH4xIHwgZXNfSUQsIH4xIHwgc3R1ZHlfSUQsIH4xIHwgc3BlY2llcywgfjEgfCBzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IGxpc3Qoc3BlY2llc19PVEwgPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IlJFTUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAidCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmcyA9ICJjb250YWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmF3X2RhdCAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpKQoKZ2xvYmFsX3IyICA8LSBvcmNoYVJkOjpyMl9tbChnbG9iYWxfbW9kZWwpICogMTAwCm92ZXJhbGxfcjIgPC0gb3JjaGFSZDo6cjJfbWwob3ZlcmFsbF9tb2RlbCkgKiAxMDAKYGBgCgoKIyMgSGV0ZXJvZ2VuZWl0eSBhbmFseXNpcyB7LX0KCkhldGVyb2dlbmVpdHkgaXMgYSBwZXJzaXN0ZW50IHByb2JsZW0gaW4gZWNvbG9naWNhbCBhbmQgZXZvbHV0aW9uYXJ5IG1ldGEtYW5hbHlzaXMgW0BCb3JlbnN0ZWluMjAxOTsgQE5vYmxlMjAyMjsgQFNlbmlvcjIwMTZdLiBIZXJlLCBoZXRlcm9nZW5laXR5IGlzIHJlcG9ydGVkIGFzICRJXjJfXHRleHR7dG90YWx9JCBhbmQgaXMgY2FsY3VsYXRlZCBhczoKCiQkClxiZWdpbntlcXVhdGlvbn0KSV4yX1x0ZXh0e3RvdGFsfSA9IFxmcmFje1xzaWdtYV4yX1x0ZXh0e3BoeWxvZ2VueX0gKyBcc2lnbWFeMl9cdGV4dHtzcGVjaWVzfSArIFxzaWdtYV4yX1x0ZXh0e3N0dWR5fSArIFxzaWdtYV4yX1x0ZXh0e3Jlc2lkdWFsfX17XHNpZ21hXjJfXHRleHR7dG90YWx9fSwKKFwjZXE6aTIpClxlbmR7ZXF1YXRpb259CiQkCgp3aGVyZSAkXHNpZ21hXjJfXHRleHR7dG90YWx9ID0gXHNpZ21hXjJfXHRleHR7cGh5bG9nZW55fSArIFxzaWdtYV4yX1x0ZXh0e3NwZWNpZXN9ICsgXHNpZ21hXjJfXHRleHR7c3R1ZHl9ICsgXHNpZ21hXjJfXHRleHR7cmVzaWR1YWx9ICsgXHNpZ21hXjJfXHRleHR7c2FtcGxpbmd9JCBpcyB0aGUgdG90YWwgZWZmZWN0IHNpemUgdmFyaWFuY2UgYW5kICRcc2lnbWFeMl9cdGV4dHtzYW1wbGluZ30kIGlzIHRoZSBzYW1wbGluZyBlcnJvciB2YXJpYW5jZSBjYWxjdWxhdGVkIGFzOgoKJCQKXGJlZ2lue2VxdWF0aW9ufSAKXHNpZ21hX3tcdGV4dHtzYW1wbGluZ319XjIgPSBcc3VtIHdfe2l9XGxlZnQoIGstMVxyaWdodCkgLyBcbGVmdFsgXGxlZnQoIFxzdW0gd197aX1ccmlnaHQpXjIgICsgXHN1bSB3X3tpfV4yXHJpZ2h0XSBcCihcI2VxOncpClxlbmR7ZXF1YXRpb259IAokJAoKd2hlcmUgJGskIGlzIHRoZSBudW1iZXIgb2Ygc3R1ZGllcyBhbmQgdGhlIHdlaWdodHMsICR3X2kgPSAxIC8gdl9pJCwgY2FuIGJlIGNhbGN1bGF0ZWQgdXNpbmcgdGhlIGludmVyc2Ugb2YgdGhlIHNhbXBsaW5nIHZhcmlhbmNlICgkdl9pJCkgZm9yIGVhY2ggZWZmZWN0IHNpemUgJGkkLiBMYXN0bHksIHdlIGFsc28gY2FsY3VsYXRlZCBob3cgbXVjaCB2YXJpYW5jZSBpcyBleHBsYWluZWQgYnkgdGhlIG1vZGVsIGFzICRSXjIkIHdoaWNoIGNhbiBiZSBzZXBhcmF0ZWQgYnkgJFJeMl97XHRleHR7bWFyZ2luYWx9fSQgKGZpeGVkIGVmZmVjdHMgb25seSkgYW5kICRSXjJfe1x0ZXh0e2NvbmRpdGlvbmFsfX0kIChmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMpOgoKJCQKXGJlZ2lue2VxdWF0aW9ufQpSXjJfe1x0ZXh0e21hcmdpbmFsfX0gPSBcZnJhY3tcc2lnbWFeMl9cdGV4dHtmaXhlZH19e1xzaWdtYV4yX1x0ZXh0e2ZpeGVkfSArIFxzaWdtYV4yX1x0ZXh0e3BoeWxvZ2VueX0gKyBcc2lnbWFeMl9cdGV4dHtzcGVjaWVzfSArIFxzaWdtYV4yX1x0ZXh0e3N0dWR5fSArIFxzaWdtYV4yX1x0ZXh0e3Jlc2lkdWFsfX0sIFxcClJeMl97XHRleHR7Y29uZGl0aW9uYWx9fSA9IFxmcmFje1xzaWdtYV4yX1x0ZXh0e2ZpeGVkfSArIFxkaXNwbGF5c3R5bGVcc3VtX3tyID0gMX1ee3V9IFxzaWdtYV4yX3J9e1xzaWdtYV4yX1x0ZXh0e2ZpeGVkfSArIFxzaWdtYV4yX1x0ZXh0e3BoeWxvZ2VueX0gKyBcc2lnbWFeMl9cdGV4dHtzcGVjaWVzfSArIFxzaWdtYV4yX1x0ZXh0e3N0dWR5fSArIFxzaWdtYV4yX1x0ZXh0e3Jlc2lkdWFsfX0sIAooXCNlcTpyMikKXGVuZHtlcXVhdGlvbn0KJCQKCndoZXJlICRcc2lnbWFeMl9cdGV4dHtmaXhlZH0kIGlzIHRoZSB2YXJpYW5jZSBmbyB0aGUgZml4ZWQgZWZmZWN0cyBleHByZXNzZWQgYXMgJHZhcihcZGlzcGxheXN0eWxlXHN1bV97bCA9IDF9XntwfSBcYmV0YV9sIHhfe2xbaV19KSQgW0BOYWthZ2F3YTIwMTJdLiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuICRSXjJfe1x0ZXh0e21hcmdpbmFsfX0kIGFuZCAkUl4yX3tcdGV4dHtjb25kaXRpb25hbH19JCBpcyB3aGV0aGVyIHRoZSByYW5kb20gZWZmZWN0IHZhcmlhbmNlIGlzIGluY2x1ZGVkIGluIHRoZSBudW1lcmF0b3IuIFRoaXMgaXMgZXhwcmVzc2VkIGFzICRcZGlzcGxheXN0eWxlXHN1bV97ciA9IDF9Xnt1fSBcc2lnbWFeMl9yJCwgd2hlcmUgJHUkIGlzIHRoZSBudW1iZXIgb2YgcmFuZG9tIGZhY3RvcnMsIGFuZCAkXHNpZ21hXjJfciQgaXMgdGhlIHZhcmlhbmNlIGNvbXBvbmVudCBvZiB0aGUgJHIkdGggcmFuZG9tIGZhY3Rvci4gCgojIyBNb2RlbCBvdXRwdXQgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KCiMjIyBUYWJsZSBTMiAtIE1vZGVsIGF2ZXJhZ2Ugey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFMyLioqIFN1bW1hcnkgb3V0cHV0IG9mIHRoZSBtb2RlbCBhdmVyYWdpbmcgb2Ygc2V2ZW4gY2FuZGlkYXRlIG1vZGVscyB3aXRoIEFJQyBkZWx0YSA8PSAyLlRoZSBtb2RlbCBhdmVyYWdlIHdhcyBwcmVzZW50ZWQgYXMgZWl0aGVyIHRoZSBgZnVsbCBhdmVyYWdlYCwgd2hpY2ggYXNzdW1lcyB0aGF0IGEgbW9kZXJhdG9yIGlzIGluY2x1ZGVkIGluIGV2ZXJ5IG1vZGVsLCBvciB0aGUgIGBjb25kaXRpb25hbCBhdmVyYWdlYCwgd2hpY2ggYXZlcmFnZXMgb3ZlciB0aGUgbW9kZWxzIHdoZXJlIHRoZSBtb2RlcmF0b3JzIGFwcGVhcnMuCgpgYGB7ciB0YWJsZVMyLCBlY2hvID0gRkFMU0V9CnN1bW1hcnkoTXVNSW46Om1vZGVsLmF2ZyhjYW5kaWRhdGVfbW9kZWxzLCBzdWJzZXQgPSBkZWx0YSA8PTIpKSAjIGdlbmVyYXRlIG1vZGVsLWF2ZXJhZ2VkCmBgYAoKIyMjIFRhYmxlIFMzIC0gR2xvYmFsIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMy4qKiBTdW1tYXJ5IG91dHB1dCBvZiB0aGUgYGdsb2JhbF9tb2RlbGAuIGludHJjcHQgPSBvdmVyYWxsIGVmZmVjdCwgc3FydF9pbnZfZWZmID0gc3F1YXJlIHJvb3Qgb2YgdGhlIGludmVyc2Ugb2YgZWZmZWN0aXZlIHNhbXBsZSBzaXplIChzbWFsbCBzYW1wbGUgZWZmZWN0KSwgeWVhcl9jZW50cmUgPSBtZWFuIGNlbnRyaW5nIG9mIHRoZSBwdWJsaWNhdGlvbiB5ZWFyIChkZWNsaW5lIGVmZmVjdCkuIEhldGVyb2dlbmVpdHkgaXMgYWxzbyBwcmVzZW50ZWQsIHdoZXJlIEkyX1RvdGFsID0gdG90YWwgKkkqXjJeLCBJMl9lc19JRCwgd2l0aGluIHN0dWR5IGVmZmVjdCAqSSpeMl4sIEkyX3N0dWR5X0lEID0gYmV0d2VlbiBzdHVkeSBlZmZlY3RzICpJKl4yXiwgSTJfc3BlY2llcyA9IHNwZWNpZXMgKkkqXjJeLCBhbmQgMl9zcGVjaWVzX09UTCA9IHBoeWxvZ2VueSAqSSpeMl4uIFB1YmxpY2F0aW9uIGJpYXMgYXMgZml4ZWQgZWZmZWN0cyAoJFJeMl97XHRleHR7bWFyZ2luYWx9fSQpIGV4cGxhaW5lZCBgciBnbG9iYWxfcjJbMV1gJSBvZiB0aGUgdmFyaWF0aW9uLCB3aGlsZSB0aGUgcmFuZG9tIGVmZmVjdHMgKCRSXjJfe1x0ZXh0e2NvbmRpdGlvbmFsfX0kKSBleHBsYWluZWQgYHIgZ2xvYmFsX3IyWzJdYCUgb2YgdGhlIHZhcmlhdGlvbi4KCmBgYHtyIHRhYmxlUzMsIGVjaG8gPSBGQUxTRX0KIyBwcmludCBtb2RlbApwcmludChnbG9iYWxfbW9kZWwpCgojIHByaW50IEkyCnJvdW5kKG9yY2hhUmQ6OmkyX21sKGdsb2JhbF9tb2RlbCwgZGF0YSA9IHJhd19kYXQpLCBkaWdpdHMgPSAwLjEpCmBgYAoKIyMjIFRhYmxlIFM0IC0gT3ZlcmFsbCBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzQuKiogU3VtbWFyeSBvdXRwdXQgb2YgdGhlIGBvdmVyYWxsX21vZGVsYC4gaW50cmNwdCA9IG92ZXJhbGwgZWZmZWN0LiBNb2RlcmF0b3IgdmFyaWFibGVzIGluY2x1ZGUgbGlmZSBzdGFnZSAoZW1icnlvLCBsYXJ2YSwganV2ZW5pbGUsIGFkdWx0KSwgdHJhaSAoc2VlICoqVGFibGUgUzEqKiksIFVWIHR5cGUgKFVWQSwgVVZCKSwgZXhwb3N1cmUgdGVtcGVyYXR1cmUsICBhbmQgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGRhaWx5IGRvc2FnZSAoSiBkYXkpLiBIZXRlcm9nZW5laXR5IGlzIGFsc28gcHJlc2VudGVkLCB3aGVyZSBJMl9Ub3RhbCA9IHRvdGFsICpJKl4yXiwgSTJfZXNfSUQsIHdpdGhpbiBzdHVkeSBlZmZlY3QgKkkqXjJeLCBJMl9zdHVkeV9JRCA9IGJldHdlZW4gc3R1ZHkgZWZmZWN0cyAqSSpeMl4sIEkyX3NwZWNpZXMgPSBzcGVjaWVzICpJKl4yXiwgYW5kIDJfc3BlY2llc19PVEwgPSBwaHlsb2dlbnkgKkkqXjJeLiBGaXhlZCBlZmZlY3RzICgkUl4yX3tcdGV4dHttYXJnaW5hbH19JCkgZXhwbGFpbmVkIGByIG92ZXJhbGxfcjJbMV1gJSBvZiB0aGUgdmFyaWF0aW9uLCB3aGlsZSB0aGUgcmFuZG9tIGVmZmVjdHMgKCRSXjJfe1x0ZXh0e2NvbmRpdGlvbmFsfX0kKSBleHBsYWluZWQgYHIgb3ZlcmFsbF9yMlsyXWAlIG9mIHRoZSB2YXJpYXRpb24uCgpgYGB7ciB0YWJsZVM0LCBlY2hvID0gRkFMU0V9CiMgcHJpbnQgbW9kZWwKcHJpbnQob3ZlcmFsbF9tb2RlbCkKCiMgcHJpbnQgSTIKcm91bmQob3JjaGFSZDo6aTJfbWwob3ZlcmFsbF9tb2RlbCwgZGF0YSA9IHJhd19kYXQpLCBkaWdpdHMgPSAwLjEpCmBgYAoKIyMjIEZpZy4gUzMgLSBGdW5uZWwgcGxvdCB7LX0KCmBgYHtyIGZ1bm5lbH0KbWV0YWZvcjo6ZnVubmVsKHJhd19kYXQkbG5SUiwgcmF3X2RhdCR2aSwgeWF4aXMgPSAic2VpbnYiLAogICAgICAgeWxhYiA9ICJQcmVjaXNpb24gKDEvU0UpIiwKICAgICAgIHhsYWIgPSAiRWZmZWN0IHNpemUgKGxuUlIpIikgCmBgYAoKKipGaWcuIFMzLioqIEZ1bm5lbCBwbG90IHdpdGggdGhlIGludmVyc2Ugb2YgdGhlIHN0YW5kYXJkIGVycm9yIChpLmUuIHByZWNpc2lvbikgYXMgdGhlIG1lYXN1cmUgb2YgdW5jZXJ0YWludHkgZm9yIHRoZSBlZmZlY3Qgc2l6ZSAobG5SUikuCgojIEZpZ3VyZXMgZm9yIG1haW4gdGV4dCB7LX0KCiMjIEZpZ3VyZSAxIC0gR2VvZ3JhcGhpY2FsIGJpYXMgey19CgpGaWd1cmUgd2FzIGdlbmVyYXRlZCB3aXRoIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgd2lsZCBzb3VyY2VkIHN0dWRpZXMgYW5kIHRoZSBtZWFuIHVsdHJhdmlvbGV0LUIgaXJyYWRpYXRpb24gKFVWQikgb2YgdGhlIGhpZ2hlc3QgbW9udGggd2FzIG9idGFpbmVkIGZyb20gQEJlY2ttYW5uMjAxNC4KCmBgYHtyIEZpZyAxLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9CiMgTG9hZCB1di1iIG9mIGhpZ2h0ZXN0IG1vbnRoIGRhdGEgZnJvbQp1dmJfcmFzdCA8LSByYXN0ZXI6OnJhc3RlcigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25pY2hvbGFzd3Vuei91di1tZXRhLWFuYWx5c2lzL21haW4vZmlsZXMvNTY0NjFfVVZCM19NZWFuX1VWLUJfb2ZfSGlnaGVzdF9Nb250aC5hc2MiKQpyYXN0ZXI6OmNycyh1dmJfcmFzdCkgPC0gIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtub19kZWZzICtlbGxwcz1XR1M4NCArdG93Z3M4ND0wLDAsMCIgCgp3b3JsZCAgICAgIDwtIHJnZGFsOjpyZWFkT0dSKCIvVXNlcnMvbmljaG9sYXN3dS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1XZXN0ZXJuU3lkbmV5VW5pdmVyc2l0eS9VViBtZXRhLWFuYWx5c2lzL25lXzUwbV9sYW5kL25lXzUwbV9sYW5kLnNocCIpICMgV29ybGQgZGF0YSAocmVxdWlyZXMgZG93bmxvYWQpLgp3b3JsZF9zcGRmIDwtIHNwOjpTcGF0aWFsUG9seWdvbnNEYXRhRnJhbWUod29ybGQsIHdvcmxkQGRhdGEpICN0dXJuIHRoZSBkYXRhIGludG8gYSBzcGF0aWFsIGRhdGEgZnJhbWUKCiMgQ29udmVydCByYXN0ZXIgdG8gZGF0YWZyYW1lCnV2Yl9kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyh1dmJfcmFzdCkpICU+JQogIGRwbHlyOjpyZW5hbWUodXZiID0gIlg1NjQ2MV9VVkIzX01lYW5fVVYuQl9vZl9IaWdoZXN0X01vbnRoIikKCiMgR2VvZ3JhcGhpY2FsIHpvbmUgbGFiZWwKZ2VvX2xhYiA8LSBkYXRhLmZyYW1lKHggPSBjKC0xNzUsIC0xNzUsIC0xNzUpLCB5ID0gYygxOSwgMjgsIDM5KSwKICB0ZXh0ID0gYygiVHJvcGljYWwiLCAiU3VidHJvcGljYWwiLCAiVGVtcGVyYXRlIikpCgojIFBsb3QgbWFwCmdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gdXZiX2RmLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gdXZiKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gImJsYWNrIiwgZmlsbCA9IE5BLCBzaXplID0gMC4yKSArCiAgI2NvbG9yc3BhY2U6OnNjYWxlX2ZpbGxfY29udGludW91c19zZXF1ZW50aWFsKHBhbGV0dGUgPSAiSW5mZXJubyIsIHJldiA9IEZBTFNFLCBsYWJlbCA9IHNjYWxlczo6Y29tbWEpICsKICBnZW9tX3BvaW50KGRhdGEgPSByYXdfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKCFpcy5uYShsb24pKSwgYWVzKHggPSBsb24sIHkgPSBsYXQsIHNoYXBlID0gY2xhc3MpLCBzaXplID0gMikgKwogIGdlb21fcG9pbnQoZGF0YSA9IHJhd19kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKGxvbikpLCBhZXMoeCA9IGxvbiwgeSA9IGxhdCwgY29sb3VyID0gY2xhc3MsIHNoYXBlID0gY2xhc3MpLCBzaXplID0gMC44KSArCiAgY29sb3JzcGFjZTo6c2NhbGVfY29sb3VyX2Rpc2NyZXRlX3F1YWxpdGF0aXZlKHBhbGV0dGUgPSAiUGFzdGVsIDEiLCBuYW1lID0gTlVMTCkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJ3aGl0ZSIsICIjYzRiYmZkIiwgIiNmZTgwZmMiLCAiI2ZlNGYzYiIsICIjZmRiOTE1IiwgIiNmY2ZjMDEiKSwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHNjYWxlczo6Y29tbWEpICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOSwxNywxNSksIG5hbWUgPSBOVUxMKSArCiAgdGhlbWVfdm9pZCgpICsgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIGZpbGwgPSBleHByZXNzaW9uKHBhc3RlKCJKIG0iXjIsIiBkYXkiXi0xKSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgZ2d0aXRsZSgiTWVhbiBVVi1CIGlycmFkaWF0aW9uIG9mIHRoZSBoaWdoZXN0IG1vbnRoIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGMoMjMuNDM2MzQsIC0yMy40MzYzNCksIGxpbmV0eXBlID0gImRvdHRlZCIsIHNpemUgPSAwLjMpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKDM1LCAtMzUpLCBsaW5ldHlwZSA9ICJkb3R0ZWQiLCBzaXplID0gMC4zKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBnZW9fbGFiLCBhZXMoeCwgeSwgbGFiZWwgPSB0ZXh0KSwgaGp1c3QgPSAiaW53YXJkIiwgc2l6ZSA9IDIuNSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ICA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9jb2xvdXJiYXIoYmFyaGVpZ2h0ID0gMC41LCBiYXJ3aWR0aCA9IDEwLCBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkKYGBgCgoqKioKCiMjIEZpZ3VyZSAyIC0gVVYgdHlwZSBhbmQgcmVnaW9uIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19CgojIyMgVVYgdHlwZSAgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCiAKYGBge3IgdXYsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQp1dl9tb2RlbCA8LSBtZXRhZm9yOjpybWEubXYoeWkgPSBsblJSLCBWID0gTSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kcyA9IH4gdXZfdHlwZS0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IGxpc3QofjEgfCBlc19JRCwgfjEgfCBzdHVkeV9JRCwgfjEgfCBzcGVjaWVzLCB+MSB8IHNwZWNpZXNfT1RMKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSID0gbGlzdChzcGVjaWVzX09UTCA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0iUkVNTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJ0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZzID0gImNvbnRhaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSByYXdfZGF0ICU+JQogICAgICAgIGRwbHlyOjptdXRhdGUoc3BlY2llc19PVEwgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3BlY2llc19PVEwsICIgIiwgIl8iKSkpCmBgYAoKKipUYWJsZSBTNS4qKiBTdW1tYXJ5IG91dHB1dCBvZiB0aGUgYHV2X21vZGVsYC4KCmBgYHtyIHRhYmxlUzUsIGVjaG8gPSBGQUxTRX0KcHJpbnQodXZfbW9kZWwpCmBgYAoKIyMjIFJlZ2lvbiB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCmBgYHtyIHJlZ2lvbiwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CnJlZ2lvbl9tb2RlbCA8LSBtZXRhZm9yOjpybWEubXYoeWkgPSBsblJSLCBWID0gTSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kcyA9IH4gcmVnaW9uLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gbGlzdCh+MSB8IGVzX0lELCB+MSB8IHN0dWR5X0lELCB+MSB8IHNwZWNpZXMsIH4xIHwgc3BlY2llc19PVEwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIgPSBsaXN0KHNwZWNpZXNfT1RMID0gcGh5bG9fY29yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSJSRU1MIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0ID0gInQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZnMgPSAiY29udGFpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QocmVsLnRvbCA9IDFlLTgpLCAjIG1vZGVsIGNvbnZlcmdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSByYXdfZGF0ICU+JQogICAgICAgIGRwbHlyOjptdXRhdGUoc3BlY2llc19PVEwgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3BlY2llc19PVEwsICIgIiwgIl8iKSkpCmBgYAoKKipUYWJsZSBTNi4qKiBTdW1tYXJ5IG91dHB1dCBvZiB0aGUgYHJlZ2lvbl9tb2RlbGAuCgpgYGB7ciB0YWJsZVM2LCBlY2hvID0gRkFMU0V9CnByaW50KHJlZ2lvbl9tb2RlbCkKYGBgCgojIyMgRmlndXJlIHByb2R1Y3Rpb24gey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgpgYGB7ciBmaWcgMiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD03LCBtZXNzYWdlPUZBTFNFfQojIEZpZyAyYQp1dl9tb2QgPC0gb3JjaGFSZDo6bW9kX3Jlc3VsdHModXZfbW9kZWwsIG1vZCA9ICJ1dl90eXBlIiwgZ3JvdXAgPSAic3R1ZHlfSUQiLCBkYXRhID0gcmF3X2RhdCkKaW50Y3JwdF9tb2QgPC0gb3JjaGFSZDo6bW9kX3Jlc3VsdHModXZfbW9kZWwsIG1vZCA9ICIxIiwgZ3JvdXAgPSAic3R1ZHlfSUQiLCBkYXRhID0gcmF3X2RhdCkKdXZfbW9kMiA8LSBvcmNoYVJkOjpzdWJtZXJnZShpbnRjcnB0X21vZCwgdXZfbW9kKQoKdXZfcGxvdCA8LSBvcmNoYVJkOjpvcmNoYXJkX3Bsb3QodXZfbW9kMiwgbW9kID0gInV2X3R5cGUiLCB4bGFiID0gIiIsIGdyb3VwID0gInN0dWR5X0lEIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaC5zaXplID0gMS41LCB0cnVuay5zaXplID0gNCwgZGF0YSA9IHJhd19kYXQpICsKICBnZW9tX3BvaW50KCkgKyAjIG1lYW4gZXN0aW1hdGUKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIndoaXRlIiwgIiNlNDk1YWEiLCAiI2JkNjZiYiIpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIndoaXRlIiwgIiNlNDk1YWEiLCAiI2JkNjZiYiIpKSArIAogIHlsYWIoIkVmZmVjdCBzaXplIChsblJSKSIpICsKICBnZ3RpdGxlKCJVbHRyYXZpb2xldCB0eXBlIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKIyBGaWcgMmIKcmVnaW9uX3Bsb3QgPC0gb3JjaGFSZDo6b3JjaGFyZF9wbG90KHJlZ2lvbl9tb2RlbCwgbW9kID0gInJlZ2lvbiIsIHhsYWIgPSAiIiwgZ3JvdXAgPSAic3R1ZHlfSUQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyYW5jaC5zaXplID0gMS41LCB0cnVuay5zaXplID0gNCwgZGF0YSA9IHJhd19kYXQpICsKICBnZW9tX3BvaW50KCkgKyAjIG1lYW4gZXN0aW1hdGUKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiNhMDZiODEiLCAiI2RhODQ2ZCIsICIjRjhERkMxIikpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2EwNmI4MSIsICIjZGE4NDZkIiwgIiNGOERGQzEiKSkgKyAKICB5bGFiKCJFZmZlY3Qgc2l6ZSAobG5SUikiKSArCiAgZ2d0aXRsZSgiUmVnaW9uIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKcHJvdyA8LSBjb3dwbG90OjpwbG90X2dyaWQodXZfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgcmVnaW9uX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoImEiLCAiYiIpLCBhbGlnbiA9ICJodiIpCgpsZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZCh1dl9wbG90ICsgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikpCgpjb3dwbG90OjpwbG90X2dyaWQocHJvdywgbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKYGBgCgoqKioKCiMjIEZpZ3VyZSAzIC0gVGF4YSBhbmQgbGlmZSBzdGFnZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCiMjIyBUYXhhIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKYGBge3IgdGF4YSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CnRheGFfbW9kZWwgPC0gbWV0YWZvcjo6cm1hLm12KHlpID0gbG5SUiwgViA9IE0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHMgPSB+IGNsYXNzLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gbGlzdCh+MSB8IGVzX0lELCB+MSB8IHN0dWR5X0lELCB+MSB8IHNwZWNpZXMsIH4xIHwgc3BlY2llc19PVEwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIgPSBsaXN0KHNwZWNpZXNfT1RMID0gcGh5bG9fY29yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSJSRU1MIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0ID0gInQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZnMgPSAiY29udGFpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHJhd19kYXQgJT4lCiAgICAgICAgZHBseXI6Om11dGF0ZShzcGVjaWVzX09UTCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChzcGVjaWVzX09UTCwgIiAiLCAiXyIpKSkKCnByaW50KHRheGFfbW9kZWwpCmBgYAoKKipUYWJsZSBTNy4qKiAgU3VtbWFyeSBvdXRwdXQgb2YgdGhlIGB0YXhhX21vZGVsYC4KCmBgYHtyIHRhYmxlUzcsIGVjaG8gPSBGQUxTRX0KcHJpbnQodGF4YV9tb2RlbCkKYGBgCgojIyMgTGlmZSBzdGFnZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCmBgYHtyIHN0YWdlLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFLCByZXN1bHRzPSJoaWRlIn0Kc3RhZ2VfbW9kZWwgPC0gbWV0YWZvcjo6cm1hLm12KHlpID0gbG5SUiwgViA9IE0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHMgPSB+IGxpZmVfc3RhZ2UtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSBsaXN0KH4xIHwgZXNfSUQsIH4xIHwgc3R1ZHlfSUQsIH4xIHwgc3BlY2llcywgfjEgfCBzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IGxpc3Qoc3BlY2llc19PVEwgPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IlJFTUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAidCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmcyA9ICJjb250YWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmF3X2RhdCAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpKQoKcHJpbnQoc3RhZ2VfbW9kZWwpCmBgYAoKKipUYWJsZSBTOC4qKiBTdW1tYXJ5IG91dHB1dCBvZiB0aGUgYHN0YWdlX21vZGVsYC4KCmBgYHtyIHRhYmxlUzgsIGVjaG8gPSBGQUxTRX0KcHJpbnQoc3RhZ2VfbW9kZWwpCmBgYAoKIyMjIEZpZ3VyZSBwcm9kdWN0aW9uIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKYGBge3IgZmlnIDMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgbWVzc2FnZT1GQUxTRX0KIyBGaWcgMmEKdGF4YV9wbG90IDwtIG9yY2hhUmQ6Om9yY2hhcmRfcGxvdCh0YXhhX21vZGVsLCBtb2QgPSAiY2xhc3MiLCB4bGFiID0gIiIsIGdyb3VwID0gInN0dWR5X0lEIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJhbmNoLnNpemUgPSAxLjUsIHRydW5rLnNpemUgPSA0LCBkYXRhID0gcmF3X2RhdCkgKwogIGdlb21fcG9pbnQoKSArICMgbWVhbiBlc3RpbWF0ZQpzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiNlNmU1OGUiLCAiI0VEQTIwMCIsICIjRDI0RTcxIiwgIiNhNzMzYTQiKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZTZlNThlIiwgIiNFREEyMDAiLCAiI0QyNEU3MSIsICIjYTczM2E0IikpICsgCiAgeWxhYigiRWZmZWN0IHNpemUgKGxuUlIpIikgKwogIGdndGl0bGUoIlRheG9ub21pYyBncm91cCIpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCiMgRmlnIDJiCnN0YWdlX3Bsb3QgPC0gb3JjaGFSZDo6b3JjaGFyZF9wbG90KHN0YWdlX21vZGVsLCBtb2QgPSAibGlmZV9zdGFnZSIsIHhsYWIgPSAiIiwgZ3JvdXAgPSAic3R1ZHlfSUQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuY2guc2l6ZSA9IDEuNSwgdHJ1bmsuc2l6ZSA9IDQsIGRhdGEgPSByYXdfZGF0KSArCiAgZ2VvbV9wb2ludCgpICsgIyBtZWFuIGVzdGltYXRlCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjRURFRjVDIiwgIiM4MkNDNkMiLCAiIzNDQjA4RiIsICIjMDA3RTdEIikpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0VERUY1QyIsICIjODJDQzZDIiwgIiMzQ0IwOEYiLCAiIzAwN0U3RCIpKSArIAogIHlsYWIoIkVmZmVjdCBzaXplIChsblJSKSIpICsKICBnZ3RpdGxlKCJMaWZlIHN0YWdlIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKcHJvdyA8LSBjb3dwbG90OjpwbG90X2dyaWQodGF4YV9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBzdGFnZV9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJhIiwgImIiKSwgYWxpZ24gPSAiaHYiKQoKbGVnZW5kIDwtIGNvd3Bsb3Q6OmdldF9sZWdlbmQodGF4YV9wbG90ICsgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikpCgpjb3dwbG90OjpwbG90X2dyaWQocHJvdywgbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKYGBgCgoqKioKCiMjIEZpZ3VyZSA0IC0gVHJhaXQgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgojIyMgVHJhaXQgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgpgYGB7ciB0cmFpdCwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CnRyYWl0X21vZGVsIDwtIG1ldGFmb3I6OnJtYS5tdih5aSA9IGxuUlIsIFYgPSBNLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RzID0gfiB0cmFpdC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IGxpc3QofjEgfCBlc19JRCwgfjEgfCBzdHVkeV9JRCwgfjEgfCBzcGVjaWVzLCB+MSB8IHNwZWNpZXNfT1RMKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSID0gbGlzdChzcGVjaWVzX09UTCA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0iUkVNTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJ0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZzID0gImNvbnRhaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSByYXdfZGF0ICU+JQogICAgICAgIGRwbHlyOjptdXRhdGUoc3BlY2llc19PVEwgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3BlY2llc19PVEwsICIgIiwgIl8iKSkpCmBgYAoKKipUYWJsZSBTOS4qKiBTdW1tYXJ5IG91dHB1dCBvZiB0aGUgYHRyYWl0X21vZGVsYC4KCmBgYHtyIHRhYmxlUzksIGVjaG8gPSBGQUxTRX0KcHJpbnQodHJhaXRfbW9kZWwpCmBgYAoKIyMjIEZpZ3VyZSBwcm9kdWN0aW9uIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKYGBge3IgZmlnIDQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRX0Kb3JjaGFSZDo6b3JjaGFyZF9wbG90KHRyYWl0X21vZGVsLCBtb2QgPSAidHJhaXQiLCB4bGFiID0gIiIsIGdyb3VwID0gInN0dWR5X0lEIiwgCiAgICAgICAgICAgICAgICAgICAgICBicmFuY2guc2l6ZSA9IDEuNSwgdHJ1bmsuc2l6ZSA9IDQsIGRhdGEgPSByYXdfZGF0KSArCiAgZ2VvbV9wb2ludCgpICsgIyBtZWFuIGVzdGltYXRlCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjOGY2Nzk4IiwgIiM3ZjY2OWYiLCAiIzdhN2NhYiIsICIjNzI5MGFmIiwgIiM2YWExYjAiLCAiIzY0YjFhZiIsICIjNGViOTlkIiwgIiM1NmM1N2YiLCAiIzg3ZDY2MiIsICIjQkJERjI3IiwgIiNGREU3MjUiKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjOGY2Nzk4IiwgIiM3ZjY2OWYiLCAiIzdhN2NhYiIsICIjNzI5MGFmIiwgIiM2YWExYjAiLCAiIzY0YjFhZiIsICIjNGViOTlkIiwgIiM1NmM1N2YiLCAiIzg3ZDY2MiIsICIjQkJERjI3IiwgIiNGREU3MjUiKSkgKyAKICB5bGFiKCJFZmZlY3Qgc2l6ZSAobG5SUikiKSArCiAgZ2d0aXRsZSgiVHJhaXRzIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCioqKgojIFN1cHBsZW1lbnRhcnkgZmlndXJlIHstfQoKYGBge3IgZmlnIFM0LCBmaWcuYWxpZ249J2NlbnRlcicsIGNhY2hlPVRSVUUsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTd9CiMgVGF4b25vbWljIGdyb3VwIGFuZCBVViBpbnRlcmFjdGlvbgp0YXhhX3V2X21vZGVsIDwtIG1ldGFmb3I6OnJtYS5tdih5aSA9IGxuUlIsIFYgPSBNLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RzID0gfiBjbGFzcyArIHV2X3R5cGUtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSBsaXN0KH4xIHwgZXNfSUQsIH4xIHwgc3R1ZHlfSUQsIH4xIHwgc3BlY2llcywgfjEgfCBzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IGxpc3Qoc3BlY2llc19PVEwgPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IlJFTUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAidCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmcyA9ICJjb250YWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmF3X2RhdCAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpKQoKdGF4YV91dl9tb2RlbDIgPC0gb3JjaGFSZDo6bW9kX3Jlc3VsdHModGF4YV91dl9tb2RlbCwgZ3JvdXAgPSAic3R1ZHlfSUQiLCBtb2QgPSAiY2xhc3MiLCBieSA9ICJ1dl90eXBlIiwgd2VpZ2h0cyA9ICJwcm9wIiwgZGF0YSA9IHJhd19kYXQpCgp0YXhhX3V2X3Bsb3QgPC0gb3JjaGFSZDo6b3JjaGFyZF9wbG90KHRheGFfdXZfbW9kZWwyLCB4bGFiID0gIiIsIGcgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuY2guc2l6ZSA9IDEuNSwgdHJ1bmsuc2l6ZSA9IDQsIGNvbmRpdGlvbi5sYWIgPSAiVVYgdHlwZSIpICsgCiAgZ2VvbV9wb2ludCgpICsgIyBtZWFuIGVzdGltYXRlCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjEsIDI0KSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiI2U2ZTU4ZSIsICIjRURBMjAwIiwgIiNEMjRFNzEiLCAiI2E3MzNhNCIpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNlNmU1OGUiLCAiI0VEQTIwMCIsICIjRDI0RTcxIiwgIiNhNzMzYTQiKSkgKyAKICB5bGFiKCJFZmZlY3Qgc2l6ZSAobG5SUikiKSArCiAgZ2d0aXRsZSgiVGF4b25vbWljIGdyb3VwIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKIyBMaWZlIHN0YWdlIGFuZCBVViBpbnRlcmFjdGlvbgpzdGFnZV91dl9tb2RlbCA8LSBtZXRhZm9yOjpybWEubXYoeWkgPSBsblJSLCBWID0gTSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kcyA9IH4gbGlmZV9zdGFnZSArIHV2X3R5cGUtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSBsaXN0KH4xIHwgZXNfSUQsIH4xIHwgc3R1ZHlfSUQsIH4xIHwgc3BlY2llcywgfjEgfCBzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IGxpc3Qoc3BlY2llc19PVEwgPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IlJFTUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAidCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmcyA9ICJjb250YWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmF3X2RhdCAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpKQoKc3RhZ2VfdXZfbW9kZWwyIDwtIG9yY2hhUmQ6Om1vZF9yZXN1bHRzKHN0YWdlX3V2X21vZGVsLCBncm91cCA9ICJzdHVkeV9JRCIsIG1vZCA9ICJsaWZlX3N0YWdlIiwgYnkgPSAidXZfdHlwZSIsIHdlaWdodHMgPSAicHJvcCIsIGRhdGEgPSByYXdfZGF0KQoKc3RhZ2VfdXZfcGxvdCA8LSBvcmNoYVJkOjpvcmNoYXJkX3Bsb3Qoc3RhZ2VfdXZfbW9kZWwyLCB4bGFiID0gImxuUlIiLCBhbmdsZSA9IDQ1LCBnID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuY2guc2l6ZSA9IDEuNSwgdHJ1bmsuc2l6ZSA9IDQsIGNvbmRpdGlvbi5sYWIgPSAiVVYgdHlwZSIpICsgCiAgZ2VvbV9wb2ludCgpICsgIyBtZWFuIGVzdGltYXRlCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjEsIDI0KSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiI0VERUY1QyIsICIjODJDQzZDIiwgIiMzQ0IwOEYiLCAiIzAwN0U3RCIpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFREVGNUMiLCAiIzgyQ0M2QyIsICIjM0NCMDhGIiwgIiMwMDdFN0QiKSkgKyAKICB5bGFiKCJFZmZlY3Qgc2l6ZSAobG5SUikiKSArCiAgZ2d0aXRsZSgiTGlmZSBzdGFnZSIpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCnByb3cgPC0gY293cGxvdDo6cGxvdF9ncmlkKHRheGFfdXZfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgc3RhZ2VfdXZfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiYSIsICJiIiksIGFsaWduID0gImh2IikKCmxlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKHRheGFfdXZfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSkKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChwcm93LCBsZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQpgYGAKIAogKipGaWcuIFM0LioqIERpZmZlcmVuY2UgaW4gVVZBIGFuZCBVVkIgcmFkaWF0aW9uIGVmZmVjdHMgYnkgKCoqYSoqKSB0YXhvbm9taWMgZ3JvdXBzIGFuZCAoKipiKiopIGxpZmUgc3RhZ2UuIAogCmBgYHtyIGZpZyBTNSwgZmlnLmFsaWduPSdjZW50ZXInLCBjYWNoZT1UUlVFLCBmaWcuaGVpZ2h0PTcuNSwgZmlnLndpZHRoPTZ9CnRyYWl0X3V2X21vZGVsIDwtIG1ldGFmb3I6OnJtYS5tdih5aSA9IGxuUlIsIFYgPSBNLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RzID0gfiB0cmFpdCArIHV2X3R5cGUtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSBsaXN0KH4xIHwgZXNfSUQsIH4xIHwgc3R1ZHlfSUQsIH4xIHwgc3BlY2llcywgfjEgfCBzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IGxpc3Qoc3BlY2llc19PVEwgPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IlJFTUwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAidCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmcyA9ICJjb250YWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmF3X2RhdCAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXNfT1RMID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHNwZWNpZXNfT1RMLCAiICIsICJfIikpKQoKdHJhaXRfdXZfbW9kZWwyIDwtIG9yY2hhUmQ6Om1vZF9yZXN1bHRzKHRyYWl0X3V2X21vZGVsLCBncm91cCA9ICJzdHVkeV9JRCIsIG1vZCA9ICJ0cmFpdCIsIGJ5ID0gInV2X3R5cGUiLCB3ZWlnaHRzID0gInByb3AiLCBkYXRhID0gcmF3X2RhdCkKCm9yY2hhUmQ6Om9yY2hhcmRfcGxvdCh0cmFpdF91dl9tb2RlbDIsIHhsYWIgPSAibG5SUiIsIGFuZ2xlID0gNDUsIGcgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICBicmFuY2guc2l6ZSA9IDEuNSwgdHJ1bmsuc2l6ZSA9IDQsIGNvbmRpdGlvbi5sYWIgPSAiVVYgdHlwZSIpICsgCiAgZ2VvbV9wb2ludCgpICsgIyBtZWFuIGVzdGltYXRlCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjEsIDI0KSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzhmNjc5OCIsICIjN2Y2NjlmIiwgIiM3YTdjYWIiLCAiIzcyOTBhZiIsICIjNmFhMWIwIiwgIiM2NGIxYWYiLCAiIzRlYjk5ZCIsICIjNTZjNTdmIiwgIiM4N2Q2NjIiLCAiI0JCREYyNyIsICIjRkRFNzI1IikpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzhmNjc5OCIsICIjN2Y2NjlmIiwgIiM3YTdjYWIiLCAiIzcyOTBhZiIsICIjNmFhMWIwIiwgIiM2NGIxYWYiLCAiIzRlYjk5ZCIsICIjNTZjNTdmIiwgIiM4N2Q2NjIiLCAiI0JCREYyNyIsICIjRkRFNzI1IikpICsgCiAgeWxhYigiRWZmZWN0IHNpemUgKGxuUlIpIikgKwogIGdndGl0bGUoIlRyYWl0cyIpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgogKipGaWcuIFM1LioqIEVmZmVjdCBvZiBVVkEgYW5kIFVWQiByYWRpYXRpb24gb24gMTEgYmlvbG9naWNhbCB0cmFpdHMuCiAKYGBge3IgZmlnIFM2LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OSwgZmlnLndpZHRoPTh9CmdncGxvdChyYXdfZGF0KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgYWxwaGEgPSAwLjUpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbWV0cmljLCB5ID0gbG5SUiwgY29sb3VyID0gdHJhaXQpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgdmlyaWRpczo6c2NhbGVfY29sb3VyX3ZpcmlkaXMoZGlzY3JldGUgPSBUUlVFKSArCiAgeGxhYihOVUxMKSArIAogIHlsYWIoIkVmZmVjdCBzaXplIChsblJSIikgKwogIGNvb3JkX2ZsaXAoKSArIAogIGZhY2V0X3dyYXAofiB0cmFpdCwgbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgbXl0aGVtZSgpICsgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwgCiAgICAgICAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwKICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoqKkZpZy4gUzYuKiogRWZmZWN0IG9mIHVsdHJhdmlvbGV0IHJhZGlhdGlvbiBvbiBzcGVjaWZpYyByZXNwb25zZXMgYWNyb3NzIGRpZmZlcmVudCBiaW9sb2dpY2FsIGFuZCBmdW5jdGlvbmFsIHRyYWl0cy4gRGF0YSBwcmVzZW50ZWQgYXMgaW5kaXZpZHVhbCBlZmZlY3Qgc2l6ZXMgKGxuUlIpLgoKKioqCgojIFJlZmVyZW5jZXMgey19Cgo8ZGl2IGlkPSJyZWZzIj48L2Rpdj4KPGJyPgoKKioqCgojIyBTZXNzaW9uIEluZm9ybWF0aW9uIHstfQoKYGBge3Igc2Vzc2lvbmluZm8sIGVjaG8gPSBGQUxTRX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSwgbG9jYWxlID0gRkFMU0UpCmBgYAoK