Introduction

This document outlines the analyses from the paper Reexamining the “Brain Drain” Effect: Does Ward et al. (2017) replicate? (Ruiz Pardo & Minda, Oct 2021 preprint, https://psyarxiv.com/5y34g/). The purpose of this study was to investigate Ward et al.’s (2017) second experiment by completing a direct replication. Therefore, the present study investigated how the mere presence of one’s smartphone effects cognition. This project can be found on OSF (https://osf.io/ubys7/) and was pre-registered through OSF (https://osf.io/5fq4r) .

The main goal of the current study was to see if Ward et al.’s findings replicated (experiment two). Therefore, as in Ward et al., participants were randomly assigned to one of six possible conditions. These conditions were based on two independent variables: smartphone location and smartphone power. For smartphone location, a participant’s smartphone was in one of three locations: (1) on the participant’s desk (“on desk”), (2) in their pocket/bag (“pocket/bag”), or (3) outside the testing room (“outside”). For smartphone power, a participant’s smartphone was either (1) powered ON or (2) powered OFF, in their respective location. For all conditions, participants were instructed to keep their smartphones on silent (i.e., no vibrations if any notifications are received during the study). Also, as per Ward et al., participants in the “on desk” location conditions were instructed to keep their devices facing up.

Each participant completed two main tasks (counter-balanced):

1. An Automated Operation Span (OSpan) Task (Unsworth et al., 2005), which required participants to retain letter strings (i.e., ranging from three to seven letters in length) in memory while solving some simple math problems (e.g., “(7/7) + 6 = ?”). This task was a behavioural measure of the attentional control component of working memory.

  • Scoring:

    • Performance, measured with the OSpan absolute score, was shown by how many trials a participant correctly recalled all the letters in a given block (75 blocks in total). For example, a participant who recalled three letters (in a block with three letters), five letters (in a block with five letters), and two letters (in a block with six letters) would have an OSpan absolute score of eight for those blocks (i.e., 3 + 5 + 0 = 8). Therefore, OSpan absolute score showed performance where higher scores represented better performance.

2. The Cue-Dependent Go/No-Go Task (Bezdjia et al., 2009), which required participants to respond to “go” targets (i.e., green rectangle) while withholding any response to “no-go” targets (i.e. blue rectangle). This task included a cue component, where vertical targets (i.e., rectangles) were more likely to be “go” targets (i.e., 80% “go” and 20% “no-go”) and horizontal targets were more likely to be “no-go” targets (i.e., 80% “no-go” and 20% “go”). Participants were not explicitly made aware of the cue component. This task was a behavioural measure of sustained attention.

  • Scoring:

    • Performance was measured with mean omission errors and RT. It should be noted that mean errors can be divided into total error, commission error, and omission error. Commission errors occurred when a participant responded to a target stimulus. Omission errors occurred when a participant failed to respond to a non-target stimulus. Total errors were the sum of commission and omission errors. The present study focused on mean omission errors. Therefore, for each participant, higher mean omission errors represented lower performance. Additionally, higher mean RT also showed lower performance (i.e., indicative of greater interference).

Finally, after completing both tasks, all participants completed three survey measures:

1. The Demographic Questionnaire, which was created for the present study and consisted of four items: age (i.e., in years), gender (i.e., male, female, other, or prefer not to say), program (e.g., psychology, engineering), and year of study (e.g., first, fourth). The purpose of these items was to give a brief description of the sample.

2. The Smartphone Usage Questionnaire (SUQ), which was created for the present study and consisted of modified items from Ward et al.’s survey measures (i.e., found in the “BRAIN DRAIN” WEB APPENDIX“). Some items were forced-choice and some were on a 7-point likert scale ranging from 1 (”Never“) to 7 (”Always“). There were 10 items in total and there were five types of items, which measured: (1) smartphone use frequency (three items; e.g.,”On average, how many text messages do you send per day?“); (2) smartphone use without external stimulation (two items; e.g.,”If I am waiting to meet a friend, I pass the time by using my smartphone.“), or during other activities (two items; e.g.,”I use my smartphone while driving.“); (3) smartphone subjective value (one item; e.g.,”How much money would it take for you to give up your phone for a full day?“); (4) smartphone notification type (one item; e.g.,”Do you receive notifications (a sound or vibration) on your phone? Please indicate all that apply.“); and (5) phantom vibrations (one item; e.g.,”Have you ever thought you heard your phone ring or thought you felt it vibrate, only to find out you were wrong?"). The purpose of the SUQ was to measure participants’ typical smartphone use.

3. Smartphone Attachment and Dependency Inventory (SAD), which was from Ward et al.’s (2017) study. The SAD used 13-items (i.e., 7-point likert scale) that asked participants to rate (i.e., from 1 = Strongly Disagree to 7 = Strongly Agree) how much they agreed with statements regarding their emotional attachment and dependency on their smartphones. The purpose of the SAD was to measure each participant’s reliance on their smartphone.

  • Scoring:

    • Smartphone reliance was calculated with a sum total for all items with a range of 13 to 91. Higher scores indicated a higher level of reliance with three levels: low reliance (13-39), moderate reliance (40-65), and high reliance (66+).

A total of 453 undergraduate students participated in this study. Of the total sample size, 44 participants were excluded due to either testing error (11; e.g., incomplete task data), or experimenter or external confounds (33; e.g., interruption during testing, distracting noise during testing). Additionally, 26 participants were removed during the data cleaning phase, which removed participants who met an exclusion criteria (OSpan math criteria: 20; Go/No-Go response criteria, horizontal/no-go cue: 6; Go/No-Go response criteria, vertical/go cue: 6), were identified as having outlier data (OSpan: 0; Go/No-Go Error Analysis: 0; Go/No-Go Accuracy Analysis: 0), and had incomplete or missing data (OSpan: 3; Go/No-Go Error Analysis: 0; Go/No-Go Accuracy Analysis: 3). Overall, 70 participants were removed from the analysis. Note: a participant may have been removed due to multiple criteria.

Therefore, 383 participants were included in the analyses for the location (on desk = 128; pocket/bag = 132; outside = 123) and power (ON = 196; OFF = 187) condition.

Data Analysis Plan

The present study completed a pre-registered data analysis (pre-registered direct replication on Open Science Framework; OSF). Below is a summary of the data analysis plan (view full version at https://osf.io/5fq4r or https://osf.io/ubys7/).

Hypotheses

  1. The location effect hypothesis predicted that those who were closest in proximity to their smartphone (i.e., those with their smartphones on their desk) would show lower performance on the OSpan task.

  2. The power effect hypothesis predicted that smartphone power (i.e., either ON or OFF) would not affect performance on both cognitive tasks.

  3. The moderation effect hypothesis predicted that smartphone attachment and dependency (i.e., SAD score) would moderate the location effect: those who reported higher smartphone attachment and dependency would perform worse on the OSpan task.

Note: All hypotheses were based on the findings from Ward et al. (2017)

Inclusion / Exclusion Criteria

There were two exclusion criteria in the present study:

1. OSpan Task

  • Only data from participants who scored 85% accuracy on the math component or above was used.

    • Criteria helped control for any participants who did not follow instructions and neglected the math component of the task. Note: This was the same criteria as in Ward et al. (2017)

2. Cue-Dependent Go/No-Go Task

  • Only data from those who scored higher than chance performance was used (e.g., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials).

    • Criteria helped control for any participants who did not complete the task as instructed (e.g., guessing). Note: There was no inclusion/exclusion criteria for thsi task in Ward et al. (2017)

Analysis

Testing the Location and Power Hypotheses:

1. OSpan Task

  • The OSpan absolute score was used to measure OSpan performance.

  • A 3(smartphone location: desk, pocket/bag, outside) x 2(smartphone power: ON, OFF) between-subjects ANOVA was conducted (DV = OSpan absolute score).

    • Post-hocs completed if there was a significant ANOVA (\(\alpha = 0.05\)) to determine which location(s) and/or power status were significantly different.

2. Cue-Dependent Go/No-Go Task

  • An error (i.e., omission errors) and accuracy (i.e., RT) analysis was completed using the average omission errors and RT for each participant.

    (a) Error Analysis

    • A 3(Smartphone location: desk, pocket/bag, outside) x 2(Smartphone power: ON, OFF) x 2(Cue type: Go, No-Go) mixed ANOVA was completed (DV = average omission error(s)).

      • The between-subjects factors:smartphone location and power
      • The within-subjects factor: pre-target cue type
      • Post-hocs completed if there was a significant ANOVA (\(\alpha = 0.05\)) to determine which location(s), power status, and/or cue type(s) were significantly different.

    (b) Accuracy Analysis

    • A 3(smartphone location: desk, pocket/bag, outside) x 2(smartphone power: ON, OFF) between-subjects ANOVA was conducted (DV = average RT).

      • The between-subjects factors:smartphone location and power
      • The within-subjects factor: pre-target cue type
      • Post-hocs completed if there was a significant ANOVA (\(\alpha = 0.05\)) to determine which location(s) and/or power status were significantly different.

Testing the Moderation Hypothesis:

3. SAD

(a) Factor Analysis

  • A principal components factor analysis with a Varimax rotation was completed for participant’s SAD score.

    • This was done to confirm the two main factors found by Ward et al. (2017): smartphone dependence and emotional attachment.

(b) Generalized Linear Model

  • A univariate generalized linear model was used to examine if smartphone reliance (i.e., SAD score) was a moderator of the relationship between the experimental manipulation and task performance.

Note: These analysis were completed regardless of the results for the location and power hypotheses.

References

  • Bezdjian, S., Baker, L. A., Lozano, D. I., & Raine, A. (2009). Assessing inattention and impulsivity in children during the Go/NoGo task. The British Journal of Developmental Psychology, 27(2), 365–383. https://doi.org/10.1348/026151008X314919
  • Peirce, J. W. (2007). PsychoPy—Psychophysics software in Python. Journal of Neuroscience Methods, 162(1), 8–13. https://doi.org/10.1016/j.jneumeth.2006.11.017
  • Ruiz Pardo, A. C., & Minda, J. P. (2021). Reexamining the “brain drain” effect: Does Ward et al. (2017) replicate? In PsyArXiv. Western University. https://doi.org/10.31234/osf.io/5y34g
  • Unsworth, N., Heitz, R. P., Schrock, J. C., & Engle, R. W. (2005). An automated version of the operation span task. Behavior Research Methods, 37(3), 498–505. https://www.ncbi.nlm.nih.gov/pubmed/16405146
  • Ward, A. F., Duke, K., Gneezy, A., & Bos, M. W. (2017). Brain drain: The mere presence of one’s own smartphone reduces available cognitive capacity. Journal of the Association for Consumer Research, 2, 140–154. https://doi.org/10.1086/691462

Analysis Prep

Load Required Libraries

The following packages were used to complete the analyses, visualizations, data wrangling, etc. in this document.

Additional Functions

Rounding p-values

This rounding function was adapted from Dr. Emily Nielsen’s Rpubs. The function (“p_round(x)”) was created to assess and print p-values. If \(p \ge .005\), the function will display “$p = $” and the value rounded to two decimal places. If $ .0005 p <.005\(, the function will display “\)p = $" and the value rounded to three decimal places. If \(p < .0005\), the function will display “\(p < .001\)”. (click to expand)


p_round <- function(x){
  if(x > .005)
    {x1 = (paste("= ", gsub("0\\.","\\.", round(x, digits = 2)), sep = ''))
  }  
  else if(x == .005){x1 = (paste("=", gsub("0\\.","\\.", 0.01)))
  }
  else if(x > .0005 & x < .005)
    {x1 = (paste("= ", gsub("0\\.","\\.", round(x, digits = 3)), sep = ''))
  }  
  else if(x == .0005){x1 = (paste("=", gsub("0\\.","\\.", 0.001)))
  }
  else{x1 = (paste("<", gsub("0\\.","\\.", 0.001)))
  } 
  (x1)
}

Flatten Correlation Output

# ++++++++++++++++++++++++++++
# flattenCorrMatrix
# ++++++++++++++++++++++++++++
# cormat : matrix of the correlation coefficients
# pmat : matrix of the correlation p-values
flattenCorrMatrix <- function(cormat, pmat) {
  ut <- upper.tri(cormat)
  data.frame(
    row = rownames(cormat)[row(cormat)[ut]],
    column = rownames(cormat)[col(cormat)[ut]],
    cor  =(cormat)[ut],
    p = pmat[ut]
    )
}

Raw Data

There are five raw data files that were imported for the present study (see the Import Raw Data section).

Task Data

  1. OSpan Raw Data

    • spreadsheet, collected manually from each participant
  2. Go/No-Go Raw Data

    • psychopy excel files
    • Note: raw data was extracted from folder into one file (see the Import Raw Data section)

Survey Measures

  1. Demographic & SUQ Raw Data

    • csv files exported from Qualtrics
  2. SAD Raw Data

    • csv files exported from Qualtrics
  3. Testing Tracking Sheet

    • csv files, collected during testing

Import Raw Data

1. OSpan Raw Data

The OSpan Raw Data was collected using the Inquisit 5 software, which used the same automated OSpan task as in Ward et al. (2017). The raw data from the OSpan was imported as a data frame, “ospan_raw”, and included the following: (click to see description)

  • Participant number [ospan_participant]

  • OSpan ID [ospan_ID]

    • A 9-digit ID given by the Iquisit 5 software
  • OSpan Absolute Score [ospan_absolute_score]

    • Performance measured by how many trials a participant correctly recalled all the letters in a given block (75 blocks in total). For example, a participant who recalled three letters (in a block with three letters), five letters (in a block with five letters), and two letters (in a block with six letters) would have an OSpan absolute score of eight for those blocks (i.e., 3 + 5 + 0 = 8).
  • Total Letters Recalled [ospan_total_corr]

    • Performance measured by how many letters were recalled in total, regardless of whether all letters were correct within a given block.
  • Total Math Errors [ospan_math_err_tot]

    • the sum of all math errors (i.e., speed and accuracy)
  • Speed Errors [ospan_math_err_speed]

    • the sum of the speed related math errors

      • where a participant exceeded their time limit to respond to the math component of the task
  • Accuracy Errors [ospan_math_err_accuracy]

    • the sum of the accuracy related math errors

      • where a participant answered incorrectly on the math component of the task
  • Math Percentage [ospan_math_percent_corr]

    • the percent of all math trials that were answered correctly

      • Participants were asked to keep their math percentage at 85% or above to ensure participants did not ignore the math component of the task to improve on the letter recall component
  • Math Percentage Criteria [ospan_math_criteria_85]

    • whether a participant met the math criteria (i.e., 85% or above; yes or no)

      coding information (click to expand)

      • 1 = yes
      • 0 = no * including any participant that did not complete the OSpan task

This code imported the OSpan raw data. (click to expand)

ospan_raw = utils::read.csv("raw_ospan.csv", header = TRUE)

# reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)
ospan_raw = dplyr::arrange(ospan_raw, ospan_participant)

ospan_raw

2. Go/No-Go Raw Data

The Go/No-Go Raw Data was collected using PsychoPy2 Experiment Builder (v1.85.4). Each participant’s data was stored in a separate folder (default from psychopy) as an excel file. The following code re-organized the raw data into a single wide format of the data as a data frame, “gng_data_extracted”, and two data frames that separate the raw data by cue type (i.e.“vertical” or “horizontal”), “gng_data_extracted_v” and “gng_data_extracted_h”. (click to see descriptions)

For the gng_data_extracted data frame:

  • Participant number [gng_participant]

  • Age [age]

  • First Language [lang]

    • self-reported whether their fist language was English (i.e., yes or no)

      coding information (click to expand)

      code 1 2
      response Yes No
  • Total trials completed [gng_trial_tot]

  • GnG Score [gng_score]

    • the sum of the correct answers
  • Total Responses [gng_resp_tot]

    • the sum of the responses for all trials
  • Total No Responses [gng_no_resp_tot]

    • the sum of the trials without a response
  • Total Errors [gng_err_tot]

    • the sum of all errors for all trials
  • Commission Errors [gng_err_com]

    • the sum of all commission errors, defined as:

      • where a response was made during a “no-go” trial (i.e., committing an error)
  • Omission Errors [gng_err_omi]

    • the sum of all omission errors, defined as:

      • where a response was NOT made during a “go” trial (i.e., failing to respond)
  • Average Reaction Time (RT) [gng_rt_av]

For the gng_data_extracted_v data frame:

  • Participant number [gng_participant]

  • Age [age_long]

  • First Language [lang_long]

    • self-reported whether their fist language was English (i.e., yes or no)

      coding information (click to expand)

      code 1 2
      response Yes No
  • Total trials completed [trial_tot_v]

  • GnG Score [score_v]

    • the sum of the correct answers
  • Total Responses [resp_tot_v]

    • the sum of the responses for all trials
  • Total No Responses [no_resp_tot_v]

    • the sum of the trials without a response
  • Total Errors [err_tot_v]

    • the sum of all errors for all trials
  • Commission Errors [err_com_v]

    • the sum of all commission errors, defined as:

      • where a response was made during a “no-go” trial (i.e., committing an error)
  • Omission Errors [err_omi_v]

    • the sum of all omission errors, defined as:

      • where a response was NOT made during a “go” trial (i.e., failing to respond)
  • Average Reaction Time (RT) [rt_av_v]

  • Response Exclusion Criteria [exclude_v]

    • This depicts whether a participant should be excluded from analysis based on the response exclusion criteria

      • To be included, participants should score higher than chance performance (i.e., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials)

        coding information (click to expand)

        code 1 2
        response Yes (participant excluded) No (participant included)

For the gng_data_extracted_h data frame:

  • Participant number [gng_participant]

  • Age [age_long]

  • First Language [lang_long]

    • self-reported whether their fist language was English (i.e., yes or no)

      coding information (click to expand)

      code 1 2
      response Yes No
  • Total trials completed [trial_tot_h]

  • GnG Score [score_h]

    • the sum of the correct answers
  • Total Responses [resp_tot_h]

    • the sum of the responses for all trials
  • Total No Responses [no_resp_tot_h]

    • the sum of the trials without a response
  • Total Errors [err_tot_h]

    • the sum of all errors for all trials
  • Commission Errors [err_com_h]

    • the sum of all commission errors, defined as:

      • where a response was made during a “no-go” trial (i.e., committing an error)
  • Omission Errors [err_omi_h]

    • the sum of all omission errors, defined as:

      • where a response was NOT made during a “go” trial (i.e., failing to respond)
  • Average Reaction Time (RT) [rt_av_h]

  • Response Exclusion Criteria [exclude_h]

    • This depicts whether a participant should be excluded from analysis based on the response exclusion criteria

      • To be included, participants should score higher than chance performance (i.e., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials)

        coding information (click to expand)

        code 1 2
        response Yes (participant excluded) No (participant included)

This code imported the Go/No-Go raw data without separating the data by cue type. (click to expand)


#---WIDE DATA FRAME---"gng_data_extracted"  

#--This code completes the following tasks:
# (1) Create a function that extracts any required information from all psychopy folders at once
# (2) Create a list of all the directory paths to each individual file 
# (3) Apply the function to the files 
# (4) Create a data frame of the result of the function on the files

#--The FINAL OUTPUT = a wide format of the raw GnG data including:
# participant, age, lang, trial_tot, score, resp_tot, no_resp_tot, err_tot, err_com, err_omi, rt_av

#--NOTES:

# Step (3) will give warnings if there is any missing data that the function was not specified how to handle
# example: Any participant that did not respond to an item or during all trials will have an "NA" response in the data
# example: Any participant who reported their age or first language in an irregular manner (e.g. "ninteen" rather than "19")
# Either example will result in a warning, since the function would have to force that output to be "NA" as well

# Individual participant files do not stay in chronological order 
# (they are re-ordered so that all ps that start with the digit "1" go first, then the "2"...)

#--(1) Create a function that extracts any required information from all psychopy folders at once

# create a function that extracts all the required information from each excel file
# details for what is extracted in this function is found within it, 
# to use it to extract any other &/ additional information, edit within the function itself
extract_gng = function(data) {
  temp_data = readxl::read_excel(data)
  
  # Participant number (participant)
  participant = as.numeric(temp_data[which(temp_data == "participant"),2])
  
  # Age (age)
  age = as.integer(temp_data[which(temp_data == "Age"),2])
  
  # Gender (gender)
  # will be populated from survey measures
  
  # First Language (lang)
  # this finds if the language reported was English: if yes = 1; no = 0
  lang = ifelse(stringr::str_detect(as.character(temp_data[which(temp_data == "First Language"),2]), stringr::fixed("english", ignore_case=TRUE)), 1, 0)
  
  # Location Condition (location; either: (1) desk, (2) pocket/bag, or (3) outside)
  # will be populated from survey measures
  
  # Power Condition (power; either: (1) ON,or (2) OFF)
  # will be populated from survey measures
  
  # Total trials completed (trial_tot)
  # count the "order" column, which shows the order in which the trials were showed (random for each participant)
  # note: must ignore the NA values
  trial_tot = sum((is.na(temp_data$cue) == "FALSE" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE) #alternative: sum(complete.cases(temp_data$order))
  
  # GnG Score (score)
  # sum of the correct answers from the "key_resp_slash.corr_raw" column
  # note: must ignore the NA values
  score = sum(temp_data$key_resp_slash.corr_raw, na.rm = TRUE)
  
  # Total Responses (resp_tot)
  # sum of the responses from the "key_resp_slash.keys_raw" column
  # note: must ignore the NA values
  resp_tot = sum((is.na(temp_data$cue) == "FALSE" & is.na(temp_data$key_resp_slash.keys_raw) == "FALSE"), na.rm = TRUE) #alternative: sum(complete.cases(temp_data$key_resp_slash.keys_raw))
  
  # Total No Responses (no_resp_tot)
  # subtract total responses made from completed trials 
  # note: must ignore the NA values
  no_resp_tot = (trial_tot - resp_tot)
  
  # Total Errors (err_tot)
  # sum of the incorrect answers from the "key_resp_slash.corr_raw"
  err_tot = sum((temp_data$key_resp_slash.corr_raw == "0") == "TRUE", na.rm = TRUE) # alternative: sum(!temp_data$key_resp_slash.corr_raw, na.rm = TRUE)
  
  # Commission Errors (err_com)
  # sum any cases where a reponse was made & the answer was incorrect (i.e. committing an erorr)
  err_com = sum((temp_data$key_resp_slash.corr_raw == "0" & !is.na(temp_data$key_resp_slash.keys_raw)) == "TRUE", na.rm = TRUE)
  
  # Omission Errors (err_omi)
  # sum any cases where a reponse was NOT made & the answer was incorrect (i.e. failing to respond)
  err_omi = sum((temp_data$key_resp_slash.corr_raw == "0" & is.na(temp_data$key_resp_slash.keys_raw)) == "TRUE", na.rm = TRUE)
  
  # Average Reaction Time (RT) (rt_av)
  # calculate the average / mean RT for all responses
  # Note: the "no-go" trials required no response for a correct trial (for 1,000ms)
  rt_av = mean(temp_data$key_resp_slash.rt_raw, na.rm = TRUE)
  
  temp_dataframe = as.data.frame(c(participant, age, lang, trial_tot, 
                                   score, resp_tot, no_resp_tot, 
                                   err_tot, err_com, err_omi, rt_av))
}

#--(2) Create a list of all the directory paths to each individual file 

# Find the location of each excel (.xlsx) files
# the folders containing the files should be in 1 folder (e.g. "" in this case)
# this returns a list of each file's location
# Note: the pattern is set to ignore any hidden / temporary files by adding the start of each file name (e.g. "^NoGo")
files_psychopy = dir("/Users/anaceciliaruizpardo/RStudio/Smartphone_study/Study 1- Smartphone Replication/Dissertation (04:20:20)/Raw Data Organizing/gng_raw_folders", 
                     recursive = TRUE, full.names=TRUE, pattern="^NoGo(.*)xlsx$")

#--(3) Apply the function to the files 

# Apply the function to all excel files
result = sapply(files_psychopy, extract_gng)

#--(4) Create a data frame of the result of the function on the files

# take the lists of the extracted data and turn it into a data frame
gng_data_extracted = data.frame(Reduce(rbind, result)) # alternative method: x = data.frame(t(sapply(result,c)))
# rename the columns
colnames(gng_data_extracted) = c("gng_participant", "age", "lang", "gng_trial_tot", "gng_score", 
                                 "gng_resp_tot", "gng_no_resp_tot", "gng_err_tot", "gng_err_com", 
                                 "gng_err_omi", "gng_rt_av") 
# remove row names to avoid confusion
rownames(gng_data_extracted) = NULL

# reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)
gng_data_extracted = dplyr::arrange(gng_data_extracted, gng_participant)

gng_data_extracted

This code imported the Go/No-Go raw data and separated the data by cue type (i.e. “vertical” or “horizontal”). (click to expand)


#--- for the LONG DATA FRAME - CUE TYPE (vertical vs. horizontal) --- "gng_data_extracted_v" & "gng_data_extracted_h" 
  
#-- This code differs from the above code in that it organizes the gng data based the CUE type (i.e. either a "vertical" (v) or "horizontal" (h)).
  # This means that the data is in a long format to test the within-subjects factor of cue type.

#--This code completes the following tasks:
# (1) Create a function that extracts any required information from all psychopy folders at once
# (2) Create a list of all the directory paths to each individual file 
# (3) Apply the function to the files 
# (4) Create a data frame of the result of the function on the files
# (5) Re-structure the data into 1 data frame in a long format for a repeated measures analysis

#--The FINAL OUTPUT = a wide format of the raw GnG data including:
# participant, age, lang, trial_tot, score, resp_tot, no_resp_tot, err_tot, err_com, err_omi, rt_av

#--NOTES:

# Step (3) will give warnings if there is any missing data that the function was not specified how to handle
# example: Any participant that did not respond to an item or during all trials will have an "NA" response in the data
# example: Any participant who reported their age or first language in an irregular manner (e.g. "ninteen" rather than "19")
# Either example will result in a warning, since the function would have to force that output to be "NA" as well

# Individual participant files do not stay in chronological order 
# (they are re-ordered so that all ps that start with the digit "1" go first, then the "2"...)

#--(1) Create a function that extracts any required information from all psychopy folders at once...
# for the "vertical" (v) (extract_gng_v) and "horizontal" (h) (extract_gng_h) trials

# create a function that extracts all the required information from each excel file
# details for what is extracted in this function is found within it, 
# to use it to extract any other &/ additional information, edit within the function itself
# NOTE: this function extracts 2 versions of each value: one for the "vertical" (v) trials, and one for the "horizontal" (h) trials

extract_gng_v = function(data) {
  temp_data = readxl::read_excel(data)
  
  # Participant number (participant_long)
  participant_long = as.numeric(temp_data[which(temp_data == "participant"),2])
  # only one is extracted since this will not change b/w CUE type
  
  # Age (age_long)
  age_long = as.integer(temp_data[which(temp_data == "Age"),2])
  # only one is extracted since this will not change b/w CUE type
  
  # Gender (gender)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # First Language (lang_long)
  # this finds if the language reported was English: if yes = 1; no = 0
  lang_long = ifelse(stringr::str_detect(as.character(temp_data[which(temp_data == "First Language"),2]), stringr::fixed("english", ignore_case=TRUE)), 1, 0)
  # only one is extracted since this will not change b/w CUE type
  
  # Location Condition (location; either: (1) desk, (2) pocket/bag, or (3) outside)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # Power Condition (power; either: (1) ON,or (2) OFF)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # Total trials completed for the "vertical" (v) (trial_tot_v)
  # count the "order" column, which shows the order in which the trials were showed (random for each participant)
  # note: must ignore the NA values
  trial_tot_v = sum((temp_data$cue == "v_b.png" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
  
  # GnG Score for the "vertical" (v) (score_v)  
  # sum of the correct answers from the "key_resp_slash.corr_raw" column
  # note: must ignore the NA values
  score_v = sum(temp_data$cue == "v_b.png" & temp_data$key_resp_slash.corr_raw, na.rm = TRUE)  
  
  # Total Responses for the "vertical" (v) (resp_tot_v)
  # sum of the responses from the "key_resp_slash.keys_raw" column
  # note: must ignore the NA values
  resp_tot_v = sum((temp_data$cue == "v_b.png" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)  
  
  # Total No Responses for the "vertical" (v) (no_resp_tot_v)  
  # subtract total responses made from completed trials 
  # note: must ignore the NA values
  no_resp_tot_v = (trial_tot_v - resp_tot_v)  
  
  # Total Errors for the "vertical" (v) (err_tot_v) 
  # sum of the incorrect answers from the "key_resp_slash.corr_raw"
  err_tot_v = sum((temp_data$cue == "v_b.png" & temp_data$key_resp_slash.corr_raw == "0"), na.rm = TRUE)  
  
  # Commission Errors for the "vertical" (v) (err_com_v) 
  # sum any cases where a reponse was made & the answer was incorrect (i.e. committing an error)
  err_com_v = sum(temp_data$cue == "v_b.png" & temp_data$key_resp_slash.corr_raw == "0" & !is.na(temp_data$key_resp_slash.keys_raw), na.rm = TRUE)  
  
  # Omission Errors for the "vertical" (v) (err_omi_v)  
  # sum any cases where a reponse was NOT made & the answer was incorrect (i.e. failing to respond)
  err_omi_v = sum(temp_data$cue == "v_b.png" & temp_data$key_resp_slash.corr_raw == "0" & is.na(temp_data$key_resp_slash.keys_raw), na.rm = TRUE)  

  # Average Reaction Time (RT) for the "vertical" (v) (rt_av_v)  
  # calculate the average / mean RT for all responses
  # Note: the "no-go" trials required no response for a correct trial (for 1,000ms)
  rt_av_v = mean(temp_data$key_resp_slash.rt_raw[which(temp_data$cue == "v_b.png")], na.rm = TRUE)  
  
  # Exclusion Criteria for the "vertical" (v) (exclude_v)
  # calculate whether participants scored higher than chance performance 
  # (i.e. responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials)
  # code: exclude = 1; include (do not exclude) = 2
  # NOTE: this calculation is meant to exclude the participant as a whole, therefore, 
  # it does not calculate it for the cue type specifically
    # first, get the total trials and response totals for the "go" and "no-go" trials
      # "go"
      trial_tot_go = sum((temp_data$corrAns == "slash" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
      resp_tot_go = sum((temp_data$corrAns == "slash" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)
      # "no-go"
      trial_tot_nogo = sum((temp_data$corrAns == "none" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
      resp_tot_nogo = sum((temp_data$corrAns == "none" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)
    # next, find the minimum response needed based on the 50% criteria
    min_resp = trial_tot_go * .50
    # find if the participant meets exclusion criteria for the "go" and "no-go" trials
    meets_min_go = resp_tot_go > (min_resp)
    meets_min_nogo = resp_tot_nogo < (min_resp)
    # find if the participant meets exclusion criteria (exclude = 1; include = 2)
    exclude_v = ifelse((meets_min_go == "TRUE" & meets_min_nogo == "TRUE") == "FALSE", 1, 2)
  
  temp_dataframe_v = as.data.frame(c(participant_long, age_long, lang_long, trial_tot_v, score_v, resp_tot_v, 
                                        no_resp_tot_v, err_tot_v, err_com_v, err_omi_v, rt_av_v, exclude_v))
}  

extract_gng_h = function(data) {
  temp_data = readxl::read_excel(data)
  
  # Participant number (participant_long)
  participant_long = as.numeric(temp_data[which(temp_data == "participant"),2])
  # only one is extracted since this will not change b/w CUE type
  
  # Age (age_long)
  age_long = as.integer(temp_data[which(temp_data == "Age"),2])
  # only one is extracted since this will not change b/w CUE type
  
  # Gender (gender)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # First Language (lang_long)
  # this finds if the language reported was English: if yes = 1; no = 0
  lang_long = ifelse(stringr::str_detect(as.character(temp_data[which(temp_data == "First Language"),2]), stringr::fixed("english", ignore_case=TRUE)), 1, 0)
  # only one is extracted since this will not change b/w CUE type
  
  # Location Condition (location; either: (1) desk, (2) pocket/bag, or (3) outside)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # Power Condition (power; either: (1) ON,or (2) OFF)
  # will be populated from survey measures
  # only one is extracted since this will not change b/w CUE type
  
  # Total trials completed for the "horizontal" (h) (trial_tot_h)
  # count the "order" column, which shows the order in which the trials were showed (random for each participant)
  # note: must ignore the NA values
  trial_tot_h = sum((temp_data$cue == "h_b.png" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
  
  # GnG Score for the "horizontal" (h) (score_h)  
  # sum of the correct answers from the "key_resp_slash.corr_raw" column
  # note: must ignore the NA values
  score_h = sum(temp_data$cue == "h_b.png" & temp_data$key_resp_slash.corr_raw, na.rm = TRUE)  
  
  # Total Responses for the "horizontal" (h) (resp_tot_h)
  # sum of the responses from the "key_resp_slash.keys_raw" column
  # note: must ignore the NA values
  resp_tot_h = sum((temp_data$cue == "h_b.png" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)  
  
  # Total No Responses for the "horizontal" (h) (no_resp_tot_h)  
  # subtract total responses made from completed trials 
  # note: must ignore the NA values
  no_resp_tot_h = (trial_tot_h - resp_tot_h)  
  
  # Total Errors for the "horizontal" (h) (err_tot_h) 
  # sum of the incorrect answers from the "key_resp_slash.corr_raw"
  err_tot_h = sum((temp_data$cue == "h_b.png" & temp_data$key_resp_slash.corr_raw == "0"), na.rm = TRUE)  
  
  # Commission Errors for the "horizontal" (h) (err_com_h) 
  # sum any cases where a reponse was made & the answer was incorrect (i.e. committing an error)
  err_com_h = sum(temp_data$cue == "h_b.png" & temp_data$key_resp_slash.corr_raw == "0" & !is.na(temp_data$key_resp_slash.keys_raw), na.rm = TRUE)  
  
  # Omission Errors for the "horizontal" (h) (err_omi_h)  
  # sum any cases where a reponse was NOT made & the answer was incorrect (i.e. failing to respond)
  err_omi_h = sum(temp_data$cue == "h_b.png" & temp_data$key_resp_slash.corr_raw == "0" & is.na(temp_data$key_resp_slash.keys_raw), na.rm = TRUE)  
  
  # Average Reaction Time (RT) for the "horizontal" (h) (rt_av_h)  
  # calculate the average / mean RT for all responses
  # Note: the "no-go" trials required no response for a correct trial (for 1,000ms)
  rt_av_h = mean(temp_data$key_resp_slash.rt_raw[which(temp_data$cue == "h_b.png")], na.rm = TRUE)  
  
  # Exclusion Criteria for the "horizontal" (h) (exclude_h)
  # calculate whether participants scored higher than chance performance 
  # (i.e. responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials)
  # code: exclude = 1; include (do not exclude) = 2
  # NOTE: this calculation is meant to exclude the participant as a whole, therefore, 
  # it does not calculate it for the cue type specifically
  # first, get the total trials and response totals for the "go" and "no-go" trials
  # "go"
  trial_tot_go = sum((temp_data$corrAns == "slash" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
  resp_tot_go = sum((temp_data$corrAns == "slash" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)
  # "no-go"
  trial_tot_nogo = sum((temp_data$corrAns == "none" & is.na(temp_data$order) == "FALSE"), na.rm = TRUE)
  resp_tot_nogo = sum((temp_data$corrAns == "none" & temp_data$key_resp_slash.keys_raw == "'slash'"), na.rm = TRUE)
  # next, find the minimum response needed based on the 50% criteria
  min_resp = trial_tot_go * .50
  # find if the participant meets exclusion criteria for the "go" and "no-go" trials
  meets_min_go = resp_tot_go > (min_resp)
  meets_min_nogo = resp_tot_nogo < (min_resp)
  # find if the participant meets exclusion criteria (exclude = 1; include = 2)
  exclude_h = ifelse((meets_min_go == "TRUE" & meets_min_nogo == "TRUE") == "FALSE", 1, 2)
  
  temp_dataframe_h = as.data.frame(c(participant_long, age_long, lang_long, trial_tot_h, score_h, resp_tot_h, 
                                     no_resp_tot_h, err_tot_h, err_com_h, err_omi_h, rt_av_h, exclude_h))
}  

#--(2) Create a list of all the directory paths to each individual file 

# Find the location of each excel (.xlsx) files
# the folders containing the files should be in 1 folder (e.g. "" in this case)
# this returns a list of each file's location
# Note: the pattern is set to ignore any hidden / temporary files by adding the start of each file name (e.g. "^NoGo")
# THIS IS THE SAME AS IN THE ABOVE CODE, SO IT IS COMMENTED OUT TO AVOID EXTRA COMPUTING POWER

# files_psychopy = dir("/Users/anaceciliaruizpardo/RStudio/Smartphone_study/Study 1- Smartphone Replication/Dissertation (04:20:20)/Raw Data Organizing/gng_raw_folders", 
#                     recursive = TRUE, full.names=TRUE, pattern="^NoGo(.*)xlsx$")

#--(3) Apply the function to the files 

# Apply the function to all excel files for the "vertical" (v) and "horizontal" (h) trials  
result_v = sapply(files_psychopy, extract_gng_v)
result_h = sapply(files_psychopy, extract_gng_h)

#--(4) Create a data frame of the result of the function on the files...
# for the "vertical" (gng_data_extracted_v) and "horizontal" (gng_data_extracted_h) trials  

# take the lists of the extracted data and turn it into a data frame for the "vertical" (h) trials
gng_data_extracted_v = data.frame(Reduce(rbind, result_v)) 
# rename the columns
colnames(gng_data_extracted_v) = c("participant_long", "age_long", "lang_long", "trial_tot_v", "score_v", 
                                         "resp_tot_v", "no_resp_tot_v", "err_tot_v", "err_com_v", 
                                         "err_omi_v", "rt_av_v", "exclude_v")

# take the lists of the extracted data and turn it into a data frame for the "horizontal" (h) trials
gng_data_extracted_h = data.frame(Reduce(rbind, result_h)) 
# rename the columns
colnames(gng_data_extracted_h) = c("participant_long", "age_long", "lang_long", "trial_tot_h", "score_h", 
                                           "resp_tot_h", "no_resp_tot_h", "err_tot_h", "err_com_h", 
                                           "err_omi_h", "rt_av_h", "exclude_h")
# remove row names to avoid confusion
rownames(gng_data_extracted_v) = NULL
rownames(gng_data_extracted_h) = NULL

# reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)
gng_data_extracted_v = dplyr::arrange(gng_data_extracted_v, participant_long)
gng_data_extracted_h = dplyr::arrange(gng_data_extracted_h, participant_long)

3. & 4. Demographic, SUQ, and SAD Raw Data

The Demographic & SUQ Raw Data and SAD Raw Data was collected using Qualtrics. The raw survey data was imported as a data frame, “survey_raw”, and included the following: (click to see description)

General, Manipulation, and Demographic Information

General Information: (click to expand)

  • Start Date [date_start]

    • The date and time when a participant began their survey on Qualtrics (Y/M/D H:M)
  • End Date [date_end]

    • The date and time when a participant finished their survey on Qualtrics (Y/M/D H:M)
  • Duration (in seconds) [duration(s)]

    • The duration of the survey for the participant in seconds
  • Recorded Date [date_rec]

    • The date and time when a participant’s data was recorded on Qualtrics (Y/M/D H:M)
  • Participant number [sur_participant]

Manipulation Condition: (click to expand)

  • Smartphone Location [sur_location]

    • The smartphone location assigned to the participant (i.e., desk, pocket/bag, or outside)

      coding information (click to expand)

      code 1 2 3
      response Desk Pocket/Bag Outside
  • Smartphone Power [sur_power]

    • The smartphone power assigned to the participant (i.e., ON or OFF)

      coding information (click to expand)

      code 1 2
      response On Off
  • Smartphone Condition [sur_condition]

    • The smartphone condition (i.e., combination of location & power) assigned to the participant

      coding information (click to expand)

      code 1 2 3 4 5 6
      response ON & Desk ON & Pocket/Bag ON & Outside OFF & Desk OFF & Pocket/Bag OFF & Outside

Demographics: (click to expand)

  • Gender [gender]

    • Participant’s self-reported gender (i.e., male, female, other, or prefer not to say)

      coding information (click to expand)

      code 1 2 3 4
      response Male Female Other Prefer not to say
  • Year [year]

    • Participant’s self-reported year of study in their respective program (e.g., 1, 2, 3, 4)
  • Program [program]

    • Participant’s self-reported program of study (e.g., biology, BMOS, psychology)

      coding information (click to expand)

      1 = actuarial 11 = economics 21 = management 31 = psychology
      2 = anthropology science 22 = mathematics 32 = SASAH
      3 = arts 13 = english 23 = medical science 33 = science
      4 = arts & humanities 14 = film 24 = MIT 34 = social science
      5 = biology 15 = FIMS 25 = MOS 35 = sociology
      6 = BMOS 16 = geography 26 = music 36 = software
      7 = chemistry 17 = health science 27 = nutrition & dietetics 37 = visual arts
      8 = computer science 18 = integrated science 28 = philosophy
      9 = consumer behaviour 19 = kinesiology 29 = physics
      10 = criminology 20 = linguistics 30 = political science
The Smartphone Use Questionnaire (SUQ)

The purpose of the SUQ was to measure participants’ typical smartphone use. The SUQ was created for the present study and consisted of modified items from Ward and colleagues’ (2017) survey measures. (i.e. found in the “BRAIN DRAIN” WEB APPENDIX“). Some items were forced-choice and some were on a 7-point likert scale ranging from 1 (”Never“) to 7 (”Always"). There were 10 items in total and there were five types of items, which measured:

1. Smartphone Use Frequency: (SUQ_use_1 - SUQ_use_3)

Each of the following items used the following coding:

CODE 1 2 3 4
response 0-5 6-10 11-15 > 15
  • Text Messages (per day) [SUQ_use_1]

    • Answer to the following question: “On average, how many text messages do you send per day?
  • Social Media Messages (per day) [SUQ_use_2]

    • Answer to the following question: “On average, how many social media based messages do you send per day from your smartphone? (iMessage, Facebook Messenger, WhatsApp, WeChat, direct messages within social media platforms, etc.)
  • Social Media Posts (per day) [SUQ_use_3]

    • Answer to the following question: “On average, how many social media posts (e.g. written post, picture, article, etc.) do you send per day from your smartphone? (Facebook, Twitter, Instagram, etc.)

2. Smartphone Use With External Stimulation or During Other Activities: (SUQ_use_4 - SUQ_use_7)

Each of the following items used the following coding:

code 1 2 3 4 5 6 7
response Never About half
the time
Always
no text specified
  • Tendency to turn to one’s smartphone in the absence of external stimulation [SUQ_use_4 & SUQ_use_5]

    • SUQ_use_4: Answer to the following question: “I look at my smartphone before I roll out of bed in the morning.
    • SUQ_use_5: Answer to the following question: “If I am waiting to meet a friend, I pass the time by using my smartphone.
  • Tendency to turn to one’s smartphone in the midst of other activities [SUQ_use_6SUQ_use_7]

    • SUQ_use_6: Answer to the following question: “I use my smartphone while driving.
    • SUQ_use_7: Answer to the following question: “If my smartphone rings or vibrates in the middle of personal business, I look at it.

3. Smartphone Subjective Value: (SUQ_exp_1)

  • Subjective Value [SUQ_use_1]

    • Answer to the following question: “How much money would it take for you to give up your phone for a full day?

      coding information (click to expand)

      code 1 2 3 4
      response $0-$20 $21-$40 $41-$60 > $60

4. Smartphone Notification Type: (SUQ_exp_2 & SUQ_exp_3)

  • Notification Type [SUQ_use_2]

    • Answer to the following question: “Do you receive notifications (a sound or vibration) on your phone? Please indicate all that apply.

      coding information (click to expand)

      code 1 2 3 4 5 6 7
      response Email Facebook Twitter Instagram LinkedIn Snapchat Other (specify)
  • Specify Notification Type [SUQ_exp_3]

    • Answer to the following question: “Please Specify: Where you receive notifications (a sound or vibration) on your phone?

5. Phantom Vibrations: (SUQ_exp_4)

  • Phantom Vibrations [SUQ_use_4]

    • Answer to the following question: “Have you ever thought you heard your phone ring or thought you felt it vibrate, only to find out you were wrong?

      coding information (click to expand)

      code 1 2
      response Yes No
The Smartphone Attachment and Dependency Inventory (SAD; Ward et al., 2017)

The SAD asked participants to respond to 13 items (SAD_1-SAD_13) using a 7-point likert scale. (click to expand)

code 1 2 3 4 5 6 7
response Strongly
Disagree
Disagree Somewhat
Disagree
Neutral Somewhat
Agree
Agree Strongly
Agree
  • SAD_1: I would have trouble getting through a normal day without my smartphone.
  • SAD_2: It would be painful for me to give up my smartphone for a day.
  • SAD_3: I feel like I could not live without my smartphone.
  • SAD_4: If I forgot to bring my smartphone with me, I would feel anxious.
  • SAD_5: It drives me crazy when my smartphone runs out of battery.
  • SAD_6: I am upset and annoyed when I find I do not have reception on my smartphone.
  • SAD_7: I feel impatient when the Internet connection speed on my smartphone is slow.
  • SAD_8: I feel lonely when my smartphone does not ring or vibrate for several hours.
  • SAD_9: Using my smartphone relieves me of my stress.
  • SAD_10: I feel excited when I have a new message or notification.
  • SAD_11: Using my smartphone makes me feel happy.
  • SAD_12: I find it tough to focus whenever my smartphone is nearby.
  • SAD_13: I become less attentive to my surroundings when I’m using my smartphone.

This code imported the Demographic, SUQ, and SAD raw data. (click to expand)

survey_raw = utils::read.csv("raw_survey.csv", header = TRUE)

# reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)
survey_raw = dplyr::arrange(survey_raw, sur_participant)

survey_raw

5. Testing Tracking Sheet Raw Data

The Testing Tracking Sheet Raw Data was collected during testing by the experimenter to store relevant information on participant’s (1) General Information (e.g. testing start date), (2) Manipulation Condition (e.g. assigned location and power manipulation), and (3) Data Cleaning (e.g. exclusion critera from testing error or other non-task-specific criteria). The raw data from the tracking sheet was imported as a dataframe, “track_raw”, and included the following: (click to see description)

1. General Information:

  • Testing Date [track_date]

    • The date a participant completed the study (Y/M/D)
  • Testing Time [date_end]

    • The time a participant was scheduled to complete the study (24hr-time). Note: Many participants were tested at the same time, but in separate cubicle-type desks to avoid any group-testing dynamic
  • Participant number [track_participant]

2. Manupulation Condition:

  • Smartphone Location [track_location]

    • The smartphone location assigned to the participant (i.e., desk, pocket/bag, or outside)

      coding information (click to expand)

      code 1 2 3
      response Desk Pocket/Bag Outside
  • Smartphone Power [track_power]

    • The smartphone power assigned to the participant (i.e., ON or OFF)

      coding information (click to expand)

      code 1 2
      response On Off
  • Smartphone Condition [track_condition]

    • The smartphone condition (i.e., combination of location & power) assigned to the participant

      coding information (click to expand)

      code 1 2 3 4 5 6
      response ON & Desk ON & Pocket/Bag ON & Outside OFF & Desk OFF & Pocket/Bag OFF & Outside
  • Counter Balanced Order [balance]

    • This depicts which of the main tasks (i.e., either the OSpan task or the Cue-Dependent Go/No-Go Task) was completed first

      coding information (click to expand)

      code 1 2
      response OSpan Task completed first Cue-Dependent Go/No-Go Task completed first

3. Data Cleaning:

  • Exclude from Analysis [exclude]

    • This depicts whether a participant should be excluded from analysis due to testing error or other non-task-specific criteria (i.e., for reasons other than the task exclusion criteria in the data analysis plan).

      coding information (click to expand)

      code 1 2
      response Yes (participant excluded) No (participant included)
  • Reason for Exclusion from Analysis [reason]

    • This depicts the reason (summarized into 5 categories) a participant should be excluded from analysis due to testing error or other non-task-specific criteria (i.e., for reasons other than the task exclusion criteria in the data analysis plan). Note: this includes a category for “no exclusion issues”, where a participant was not excluded

      coding information (click to expand)

      code 1 2 3 4 5
      response no exclusion issues external distractor (noise) gng incomplete gng missing ospan missing
  • Possible Outlier [pos_out]

    • This depicts whether a participant is a possible outlier for exploratory analyses. Note: this was not applied to any analysis unless explicitly stated

      coding information (click to expand)

      code 1 2
      response Yes (does qualify as a possible outlier) No (does not qualify as a possible outlier)
  • Experimenter [experimenter]

    • This depicts which experimenter (3 total) collected the data for a participant. Note: this was collected for exploratory analyses and was not used unless explicitly stated

      coding information (click to expand)

      code 1 2 3
      response ARP SW LM

This code imported the study tracking sheet raw data. (click to expand)

track_raw = utils::read.csv("raw_tracking.csv", header = TRUE)

# reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)
track_raw = dplyr::arrange(track_raw, track_participant)

track_raw

Construct Working Dataframes

In order to complete the present study’s analyses, eight data frames were created:

  1. All Data
  2. All Data - Go/No-Go separated by Cue Type (WIDE FORMAT)
  3. All Data - Go/No-Go separated by Cue Type (Long FORMAT)
  4. OSpan Analysis
  5. Go/No-Go: Error Analysis
  6. Go/No-Go: Accuracy Analysis
  7. SAD: Factor Analysis
  8. Moderation Analysis

Data Cleaning was completed for (1)-(3) based on: (a) Exclusion criteria, (b) Outlier data, and (c) Incomplete/Missing data:

  1. Exclusion Criteria

    • OSpan Data: Math Criteria Planned exclusion criteria was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions, specifically, that participant payed attention to both the math component and letter recall component of the task. Only data from those who scored 85% or higher on the math component of the task were included.

    • Go/No-Go Data: Chance Performance Criteria Planned exclusion criteria was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions. Only data from those who scored higher than chance performance (i.e., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials) were used for the final analysis.

    • Go/No-Go Data: Standard Deviation Criteria Planned exclusion criteria was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions. Only data from those who scored higher than chance performance (i.e., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials) were used for the final analysis.

  2. Outlier Data

    • OSpan & Go/No-Go Data: For all task data, any extreme outliers were removed. The outliers were identified and removed using the standard deviation (SD) method. Participants who’s score was greater than 2SDs from the mean were excluded.
  3. Incomplete/Missing Data

    • For all task data, any participants with incomplete or missing data were removed.

1. All Data

All the data from the present study in one data frame: “all_data” (click to see more)

  • This data included the following:

    • participant, track_date, track_time, location, power, condition, balance, exclude, reason, pos_out, experimenter, ospan_ID, ospan_absolute_score, ospan_total_corr, ospan_math_err_tot, ospan_math_err_speed, ospan_math_err_accuracy, ospan_math_percent_corr, ospan_math_criteria_85, age, lang, gng_trial_tot, gng_score, gng_resp_tot, gng_no_resp_tot, gng_err_tot, gng_err_com, gng_err_omi, gng_rt_av, date_start, date_end, duration.s., date_rec, gender, program, year, SUQ_use_1, SUQ_use_2, SUQ_use_3, SUQ_use_4, SUQ_use_5, SUQ_use_6, SUQ_use_7, SUQ_exp_1, SUQ_exp_2, SUQ_exp_3, SUQ_exp_4, SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13, SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, SUQ_abext_score, SUQ_duract_score

This code organized the raw data into one data frame. (click to expand)


# Find the final participant list for the analyses  
  # get a list of participants that (1) completed the gng task and (2) are not excluded (i.e., inclusion list) based on the "exclude" column in the tracking sheet  
  # (1) First get the gng participant list  
  gng_par_list = gng_data_extracted$gng_participant  
  # (2) Next, get the inclusion list  
  include_par_list = data.frame(track_raw$track_participant[which(track_raw$exclude %in% 2)])  
    colnames(include_par_list) = c("par_list")
  # Get a list of all the participants who completed the study (from the testing tracking sheet)
  all_participants = as.data.frame(track_raw$track_participant)
    colnames(all_participants) = c("all_participants")
  
# find the participants to remove from the data
  # Filter each data list from the list of all participants  
  gng_remove = data.frame("all_participants" = filter(all_participants, !(all_participants %in% gng_par_list)))
  track_remove = data.frame("all_participants" = filter(all_participants, !(all_participants %in% include_par_list$par_list)))
  reason_remove = c(rep("gng", length(gng_remove$all_participants)), rep("track", length(track_remove$all_participants)))
  
  # Make a list of all the removed participants -- "all_remove"
  all_remove_notclean = data.frame(rbind(gng_remove, track_remove), reason_remove)
    # remove any duplicates from the list
    all_remove_nodup = all_remove_notclean[!duplicated(all_remove_notclean$all_participants), ]
    # reorganize rows so that the data is ordered by the participant number (e.g. 1, 2, 3, 4...)  
    all_remove = dplyr::arrange(all_remove_nodup, all_participants)  
    
# Filter raw data using the final participant list for: ospan_raw, gng_raw, survey_raw, and track_raw
  # This will now be the working data for the study (i.e. the "final" data)  
    # OSpan Data  
    ospan_final = dplyr::filter(ospan_raw, !ospan_participant %in% all_remove$all_participants)
    # Gng Data  
    gng_final = dplyr::filter(gng_data_extracted, !gng_participant %in% all_remove$all_participants)
    # Survey Data  
    survey_final = dplyr::filter(survey_raw, !sur_participant %in% all_remove$all_participants)
    # Tracking Data  
    track_final = dplyr::filter(track_raw, !track_participant %in% all_remove$all_participants)

# Combine all the final data into 1 data frame with the following:
  # Start by creating a data frame with the final participant list in the 1st column: "participant"
  all_par = as.data.frame(track_final$track_participant)
    colnames(all_par) = c("participant")

  # to use the merge function, change the respective "participant" column name in each data frame to "participant"
    # OSpan Data
    colnames(ospan_final)[which(names(ospan_final) == "ospan_participant")] = c("participant")
    # Gng Data
    colnames(gng_final)[which(names(gng_final) == "gng_participant")] = c("participant")
    # Survey Data
    colnames(survey_final)[which(names(survey_final) == "sur_participant")] = c("participant")
    # Tracking Data
    colnames(track_final)[which(names(track_final) == "track_participant")] = c("participant")

# Merge all 4 data frames into 1 data frame -- "all_data_temp" 
  # this will be refined with data cleaning later
  all_data_temp <-  Reduce(function(x, y) merge(x, y, by="participant"), list(track_final, ospan_final, gng_final, dplyr::select(survey_final, -c(sur_location, sur_power, sur_condition))))
    # rename the tracking sheet columns for the location, power, and condition 
    colnames(all_data_temp)[which(names(all_data_temp) == c("track_location", "track_power", "track_condition"))] = c("location", "power", "condition")
    
# Add score for SAD items
  #SAD score over all 13 items
    all_data_temp <- 
      all_data_temp %>% rowwise() %>% dplyr::mutate(SAD_score = sum(c_across(SAD_1:SAD_13)))
    # all_data_temp %>% 
    # # for each participant
    # rowwise() %>% 
    # # score is calculated by adding up all 13 items for a total sum score for each p
    # mutate(SAD_score = sum(SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13))
  
  # Smartphone Dependence subscale (items: 1, 2, 3) -- based on FA 
    all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SAD_dep_score = sum(c_across(SAD_1:SAD_3)))

  # Emotional Attachment subscale (items: 8, 9, 10, 11) -- based on FA 
    all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SAD_ea_score = sum(c_across(SAD_8:SAD_11)))
  
  # Smartphone Accessibility subscale (items: 5, 6, 7) -- based on FA 
    all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SAD_access_score = sum(c_across(SAD_5:SAD_7)))
    
  # Smartphone Distractibility subscale (items: 12, 13) -- based on FA 
    all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SAD_dist_score = sum(c_across(SAD_12:SAD_13)))
    
# Add score for SUQ_use_4-5
all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SUQ_abext_score = sum(SUQ_use_4, SUQ_use_5)/2)
  all_data_temp %>% 
  # for each participant
  rowwise() %>% 
  # score is calculated as average between 2 items -- measures ps tendency to turn to smartphone in absence of external stimulation
  mutate(SUQ_abext_score = (sum(SUQ_use_4, SUQ_use_5))/2)

# Add score for SUQ_use_6-7
all_data_temp <- all_data_temp %>% rowwise() %>% dplyr::mutate(SUQ_duract_score = sum(SUQ_use_6, SUQ_use_7)/2)
  all_data_temp %>% 
  # for each participant  
  rowwise() %>% 
  # score is calculated as average between 2 items -- measures ps tendency to turn to smartphone during other activities
  mutate(SUQ_duract_score = (sum(SUQ_use_6, SUQ_use_7))/2)
  
all_data_temp

Data Cleaning: Exclusion Criteria, Outliers, and Missing Data

The final sample size (N = 383) for this data frame excluded 32 participants who met the exclusion criteria (OSpan math criteria: 20; Go/No-Go response criteria, horizontal/no-go cue: 6; Go/No-Go response criteria, vertical/go cue: 6). A total of 0 participants were identified as outliers (OSpan: 0; Go/No-Go Error Analysis: 0; Go/No-Go Accuracy Analysis: 0) and removed. A total of 6 participants were removed due to incomplete or missing data (OSpan: 3; Go/No-Go Error Analysis: 0; Go/No-Go Accuracy Analysis: 3). This created the “all_data” data frame (click to see more).

This code cleaned all_data based on (1) exclusion criteria, (2) outliers, and (3) incomplete/missing data. (click to see code)

# get list of ps to remove for various reasons...
  
# Exclusion criteria
  # For OSPAN
  # ps scored <85% on math
  dc_ospan_ec <- 
    all_data_temp %>% 
    # apply filter to math criteria
    filter(ospan_math_criteria_85 == 0) %>% 
    # remove all rows except participant ID
    select(participant)

  # For GNG -- based on raw data separated by cue type (i.e., either vertical or horizontal)
  # Vertical cue type ("go")
  dc_gng_v_ec <- 
    gng_data_extracted_v %>% 
    # apply filter to response criteria
    filter(exclude_v == 1) %>% 
    # remove all rows except participant ID
    select(participant_long) %>% 
    # rename column as "participant"
    dplyr::rename(participant = participant_long)
  # Vertical cue type ("no-go")
  dc_gng_h_ec <- 
    gng_data_extracted_h %>% 
    # apply filter to response criteria
    filter(exclude_h == 1) %>% 
    # remove all rows except participant ID
    select(participant_long) %>% 
    # rename column as "participant"
    dplyr::rename(participant = participant_long)

# Outliers
  # For OSPAN
  dc_ospan_out <- 
    all_data_temp %>% 
    # remove ps with score > 2SD from mean
    filter(ospan_absolute_score > (mean(ospan_absolute_score, na.rm = T) + (2 * sd(ospan_absolute_score, na.rm = T))) |
           ospan_absolute_score < (mean(ospan_absolute_score, na.rm = T) - (2 * sd(ospan_absolute_score, na.rm = T)))
           ) %>% 
    # remove all rows except participant ID
    select(participant)
  
  # For GNG error (omission)
  dc_gng_err_out <- 
    all_data_temp %>% 
    # remove ps with score > 2SD from mean
    filter(gng_err_omi > (mean(gng_err_omi, na.rm = T) + (2 * sd(gng_err_omi, na.rm = T))) |
           gng_err_omi < (mean(gng_err_omi, na.rm = T) - (2 * sd(gng_err_omi, na.rm = T)))
           ) %>% 
    # remove all rows except participant ID
    select(participant)
  
  # For GNG accuracy (average RT)
  dc_gng_ac_out <- 
    all_data_temp %>% 
    # remove ps with score > 2SD from mean
    filter(gng_rt_av > (mean(gng_rt_av, na.rm = T) + (2 * sd(gng_rt_av, na.rm = T))) |
           gng_rt_av < (mean(gng_rt_av, na.rm = T) - (2 * sd(gng_rt_av, na.rm = T)))
           ) %>% 
    # remove all rows except participant ID
    select(participant)
  
# Missing/incomplete data
  # For OSPAN
  dc_ospan_miss <- all_data_temp %>% filter(is.na(ospan_absolute_score)) %>% select(participant)
  # For GNG error (omission)
  dc_gng_err_miss <- all_data_temp %>% filter(is.na(gng_err_omi)) %>% select(participant)
  # For GNG RT (average)
  dc_gng_ac_miss <- all_data_temp %>% filter(is.na(gng_rt_av)) %>% select(participant)
    
  
# create list of ps to remove with reason for removal -- all_remove_dc
all_remove_dc <- data.frame("participant" = bind_rows(dc_ospan_ec, dc_ospan_out, dc_ospan_miss, 
                                                      dc_gng_v_ec, dc_gng_h_ec, 
                                                      dc_gng_err_out, dc_gng_err_miss, 
                                                      dc_gng_ac_out, dc_gng_ac_miss), 
                            "reason" = c(rep("ospan_ec", nrow(dc_ospan_ec)), rep("ospan_out", nrow(dc_ospan_out)), 
                                         rep("ospan_miss", nrow(dc_ospan_miss)), rep("gng_v_ec", nrow(dc_gng_v_ec)),
                                         rep("gng_h_ec", nrow(dc_gng_h_ec)),rep("gng_err_out", nrow(dc_gng_err_out)), 
                                         rep("gng_err_miss", nrow(dc_gng_err_miss)), rep("gng_ac_out", nrow(dc_gng_ac_out)), 
                                         rep("gng_ac_miss", nrow(dc_gng_ac_miss)) 
                                         )
                            )
# create list of ps to remove without duplicates to use to filter final data
all_remove_dc_list <- 
  all_remove_dc %>% 
  # remove reason column
  select(participant) %>% 
  # remove any duplicated participant IDs
  distinct()
# clean all_data using all_remove_dc_list
all_data <- 
  all_data_temp %>% 
  filter(!participant %in% all_remove_dc_list$participant)

all_data

2. All Data - Go/No-Go separated by Cue Type (WIDE FORMAT)

All the data from the present study in one data frame, with the Go/No-Go data separated by target type (i.e., either “go” or “no-go”), presented in WIDE FORMAT: “all_data_cue” (click to see more)

  • This data included the following:

    • participant, track_date, track_time, location, power, condition, balance, exclude, reason, pos_out, experimenter, ospan_ID, ospan_absolute_score, ospan_total_corr, ospan_math_err_tot, ospan_math_err_speed, ospan_math_err_accuracy, ospan_math_percent_corr, ospan_math_criteria_85, age_long, lang_long, trial_tot_v, score_v, resp_tot_v, no_resp_tot_v, err_tot_v, err_com_v, err_omi_v, rt_av_v, exclude_v, trial_tot_h, score_h, resp_tot_h, no_resp_tot_h, err_tot_h, err_com_h, err_omi_h, rt_av_h, exclude_h, date_start, date_end, duration.s., date_rec, gender, program, year, SUQ_use_1, SUQ_use_2, SUQ_use_3, SUQ_use_4, SUQ_use_5, SUQ_use_6, SUQ_use_7, SUQ_exp_1, SUQ_exp_2, SUQ_exp_3, SUQ_exp_4, SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13, SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, SUQ_abext_score, SUQ_duract_score

This code organized the raw data into one data frame. (click to expand)

# use the list of all the participants to remove -- "all_remove" & "all_remove_dc_list" -- to filter the raw gng long data
  # for the "go" targets
  gng_v_final <- 
  gng_data_extracted_v %>% 
  # remove using use all_remove
  filter(!participant_long %in% all_remove$all_participants) %>% 
  # remove using use all_remove_dc_list
  filter(!participant_long %in% all_remove_dc_list$participant)
  
  # for the "no-go" targets
  gng_h_final <- 
  gng_data_extracted_h %>% 
  # remove using use all_remove
  filter(!participant_long %in% all_remove$all_participants) %>% 
  # remove using use all_remove_dc_list
  filter(!participant_long %in% all_remove_dc_list$participant)

# Combine all the final data into 1 data frame with the following:
  # use the final participant list -- "all_par" -- as the 1st column in the data frames

  # to use the merge function, change the respective "participant" column name in each data frame to "participant"
    # this was already done for the other data frames (e.g. ospan_final, survey_final)
    # for the "vertical" targets
    colnames(gng_v_final)[which(names(gng_v_final) == "participant_long")] = c("participant")
    # for the "horizontal" targets
    colnames(gng_h_final)[which(names(gng_h_final) == "participant_long")] = c("participant")

# Merge all 4 data frames into 1 data frame -- "all_data_cue"
  all_data_cue = Reduce(function(x, y) merge(x, y, by="participant"), list(track_final, ospan_final, gng_v_final, dplyr::select(gng_h_final, -c(age_long, lang_long)), dplyr::select(survey_final, -c(sur_location, sur_power, sur_condition))))
    # rename the tracking sheet columns for the location, power, and condition 
    colnames(all_data_cue)[which(names(all_data_cue) == c("track_location", "track_power", "track_condition"))] = c("location", "power", "condition")

# Add score for SAD items
  #SAD score over all 13 items
    all_data_cue <- 
    all_data_cue %>% 
    # for each participant
    rowwise() %>% 
    # score is calculated by adding up all 13 items for a total sum score for each p
    mutate(SAD_score = sum(SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13))
  
  # Smartphone Dependence subscale (items: 1, 2, 3, 4, 5) -- based on FA 
    all_data_cue <- 
    all_data_cue %>% 
    # for each participant
    rowwise() %>% 
    # score is calculated by adding up items 1-5 for a total sum score for each p
    mutate(SAD_dep_score = sum(SAD_1, SAD_2, SAD_3))
    
  # Emotional Attachment subscale (items: 8, 9, 10, 11) -- based on FA 
    all_data_cue <- 
    all_data_cue %>% 
    # for each participant
    rowwise() %>% 
    # score is calculated by adding up items 8-11 for a total sum score for each p
    mutate(SAD_ea_score = sum(SAD_8, SAD_9, SAD_10, SAD_11))
    
  # Smartphone Accessability subscale (items: 5, 6, 7) -- based on FA 
    all_data_cue <- 
    all_data_cue %>% 
    # for each participant
    rowwise() %>% 
    # score is calculated by adding up all 13 items for a total sum score for each p
    mutate(SAD_access_score = sum(SAD_5, SAD_6, SAD_7))
    
  # Smartphone Distractibility subscale (items: 7, 12, 13) -- based on FA 
    all_data_cue <- 
    all_data_cue %>% 
    # for each participant
    rowwise() %>% 
    # score is calculated by adding up all 13 items for a total sum score for each p
    mutate(SAD_dist_score = sum(SAD_12, SAD_13))

# Add score for SUQ_use_4-5
all_data_cue <- 
  all_data_cue %>% 
  # for each participant
  rowwise() %>% 
  # score is calculated as average between 2 items -- measures ps tendency to turn to smartphone in absence of external stimulation
  mutate(SUQ_abext_score = (sum(SUQ_use_4, SUQ_use_5))/2)

# Add score for SUQ_use_6-7
all_data_cue <- 
  all_data_cue %>% 
  # for each participant  
  rowwise() %>% 
  # score is calculated as average between 2 items -- measures ps tendency to turn to smartphone during other activities
  mutate(SUQ_duract_score = (sum(SUQ_use_6, SUQ_use_7))/2)

all_data_cue
NA

3. All Data - Go/No-Go separated by Cue Type (LONG FORMAT)

All the data from the present study in one data frame, with the Go/No-Go data separated by target type (i.e., either “go” or “no-go”), presented in LONG FORMAT: “all_data_cue_long” (click to see more)

  • This data included the following:

    • cue, participant, track_date, track_time, location, power, condition, balance, exclude, reason, pos_out, experimenter, ospan_ID, ospan_absolute_score, ospan_total_corr, ospan_math_err_tot, ospan_math_err_speed, ospan_math_err_accuracy, ospan_math_percent_corr, ospan_math_criteria_85, age_long, lang_long, gng_trial_tot_long, gng_score_long, gng_resp_tot_long, gng_no_resp_tot_long, gng_err_tot_long, gng_err_com_long, gng_err_omi_long, gng_rt_av_long, gng_exclude_long, date_start, date_end, duration.s., date_rec, gender, program, year, SUQ_use_1, SUQ_use_2, SUQ_use_3, SUQ_use_4, SUQ_use_5, SUQ_use_6, SUQ_use_7, SUQ_exp_1, SUQ_exp_2, SUQ_exp_3, SUQ_exp_4, SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13

This code organized the raw data into one data frame. (click to expand)

# Re-structure the data into 1 data frame in a long format for a repeated measures analysis

  # using the "final" data frames of all the data, make 2 data frames, one for the "vertical" (all_data_v) and one for the "horizontal" (all_data_h) targets
    # for the "vertical" targets -- all_data_v
    all_data_v = Reduce(function(x, y) merge(x, y, by="participant"), list(track_final, ospan_final, gng_v_final, dplyr::select(survey_final, -c(sur_location, sur_power, sur_condition))))
      # rename the tracking sheet columns for the location, power, and condition 
      colnames(all_data_v)[which(names(all_data_v) == c("track_location", "track_power", "track_condition"))] = c("location", "power", "condition")
    # for the "horizontal" targets -- all_data_h
    all_data_h = Reduce(function(x, y) merge(x, y, by="participant"), list(track_final, ospan_final, gng_h_final, dplyr::select(survey_final, -c(sur_location, sur_power, sur_condition))))
      # rename the tracking sheet columns for the location, power, and condition 
      colnames(all_data_h)[which(names(all_data_h) == c("track_location", "track_power", "track_condition"))] = c("location", "power", "condition")

  # rename target-specific columns for both data frames (to bind)
    # for the "go" trials
    names(all_data_v)[names(all_data_v) == "trial_tot_v"] = "gng_trial_tot_long" 
    names(all_data_v)[names(all_data_v) == "score_v"] = "gng_score_long" 
    names(all_data_v)[names(all_data_v) == "resp_tot_v"] = "gng_resp_tot_long" 
    names(all_data_v)[names(all_data_v) == "no_resp_tot_v"] = "gng_no_resp_tot_long" 
    names(all_data_v)[names(all_data_v) == "err_tot_v"] = "gng_err_tot_long" 
    names(all_data_v)[names(all_data_v) == "err_com_v"] = "gng_err_com_long" 
    names(all_data_v)[names(all_data_v) == "err_omi_v"] = "gng_err_omi_long" 
    names(all_data_v)[names(all_data_v) == "rt_av_v"] = "gng_rt_av_long" 
    names(all_data_v)[names(all_data_v) == "exclude_v"] = "gng_exclude_long"
    # for the "no-go" trials
    names(all_data_h)[names(all_data_h) == "trial_tot_h"] = "gng_trial_tot_long" 
    names(all_data_h)[names(all_data_h) == "score_h"] = "gng_score_long" 
    names(all_data_h)[names(all_data_h) == "resp_tot_h"] = "gng_resp_tot_long" 
    names(all_data_h)[names(all_data_h) == "no_resp_tot_h"] = "gng_no_resp_tot_long" 
    names(all_data_h)[names(all_data_h) == "err_tot_h"] = "gng_err_tot_long" 
    names(all_data_h)[names(all_data_h) == "err_com_h"] = "gng_err_com_long" 
    names(all_data_h)[names(all_data_h) == "err_omi_h"] = "gng_err_omi_long" 
    names(all_data_h)[names(all_data_h) == "rt_av_h"] = "gng_rt_av_long" 
    names(all_data_h)[names(all_data_h) == "exclude_h"] = "gng_exclude_long"
  
  # Create a data frame depicting the target type: either "go" (coded as 1) or "no-go" (coded as 2)
  cue_type = as.data.frame(c(rep(1, length(all_data_v$participant)), rep(2, length(all_data_h$participant))))
    colnames(cue_type) = c("cue")  

  # Bind the go and no-go data frames into 1 (in long format)
  gng_cue_bind = dplyr::bind_rows(all_data_v, all_data_h)
  
  # add the target type column depicting the target type: either "go" (coded as 1) or "no-go" (coded as 2)
  all_data_cue_long = dplyr::bind_cols(cue_type, gng_cue_bind)
  
  all_data_cue_long

4. OSpan Analysis

All the data related to the OSpan Analysis from the present study in one data frame: “ospan_analysis” (click to see more)

  • This data included the following:

    • participant, age, gender, lang, program, year, location, power, balance, ospan_absolute_score, ospan_math_percent_corr, ospan_math_criteria_85

This code organized the final data into the ospan-related data frame. (click to expand)


# make a new data frame for the ospan analysis
ospan_analysis = dplyr::select(all_data, participant, age, gender, lang, program, year, location, power, balance, ospan_absolute_score, ospan_math_percent_corr, ospan_math_criteria_85)


ospan_analysis
NA

5. Go/No-Go: Error Analysis

All the data related to the Go/No-Go Error Analysis from the present study in one data frame: “gng_err_analysis”

Note: this data is in a long format for a repeated measures analysis (i.e., based on target type: either “go” or “no-go”). (click to see more)

  • This data included the following:

    • participant, age_long, gender, lang_long, program, year, location, power, condition, balance, cue, gng_exclude_long, gng_trial_tot_long, gng_resp_tot_long, gng_no_resp_tot_long, gng_err_tot_long, gng_err_com_long, gng_err_omi_long

This code organized the final long data into a data frame for the Go/No-Go Error Analysis. (click to expand)

# make a new data frame for the gng error analysis
gng_err_analysis = dplyr::select(all_data_cue_long, participant, age_long, gender, lang_long, program, year, location, power, condition, balance, cue, gng_exclude_long, gng_trial_tot_long, gng_resp_tot_long, gng_no_resp_tot_long, gng_err_tot_long, gng_err_com_long, gng_err_omi_long)

gng_err_analysis
NA

6. Go/No-Go: Accuracy Analysis

All the data related to the Go/No-Go Accuracy Analysis from the present study in one data frame: “gng_ac_analysis” (click to see more)

  • This data included the following:

    • participant, age, gender, lang, program, year, location, power, balance, gng_trial_tot, gng_resp_tot, gng_no_resp_tot, gng_rt_av

This code organized the final data into a data frame related to the Go/No-Go Accuracy Analysis. (click to expand)


# make a new data frame for the gng accuracy analysis
gng_ac_analysis = dplyr::select(all_data, participant, age, gender, lang, program, year, location, power, balance, gng_trial_tot, gng_resp_tot, gng_no_resp_tot, gng_rt_av) 

gng_ac_analysis

7. SAD: Factor Analysis

All the data related to the Factor Analysis from the present study in one data frame: “factor_analysis” (click to see more)

  • This data included the following:

    • participant, age, gender, lang, program, year, location, power, balance, SAD_1, SAD_2, SAD_3, SAD_4, SAD_5, SAD_6, SAD_7, SAD_8, SAD_9, SAD_10, SAD_11, SAD_12, SAD_13, SAD_score

This code organized the final data into the factor analysis-related data frame. (click to expand)


# make a new data frame for the factor analysis
factor_analysis = dplyr::select(all_data, participant, age, gender, lang, program, year, location, power, balance, SAD_1:SAD_13, SAD_score)

factor_analysis
NA

8. Moderation Analysis

All the data related to the Moderation Analysis from the present study in one data frame: “mod_analysis” (click to see more)

  • This data included the following:

    • participant, ospan_absolute_score, age, gender, lang, program, year, location, power, balance, SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, SUQ_abext_score, SUQ_duract_score, SUQ_use_1, SUQ_use_2, SUQ_use_3, SUQ_exp_1, SUQ_exp_2, SUQ_exp_4, location_desk, location_out

This code organized the final data into the moderation-related data frame. (click to expand)


# make a new data frame for the glm analysis
mod_analysis = dplyr::select(all_data, participant, ospan_absolute_score, age, gender, lang, program, year, location, power, balance, SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, SUQ_abext_score, SUQ_duract_score, SUQ_use_1, SUQ_use_2, SUQ_use_3, SUQ_exp_1, SUQ_exp_2, SUQ_exp_4)

mod_analysis
NA

Descriptive Statistics

The following figures and tables depict the descriptive statistics for the present study’s data. This was done across all conditions (Toltal) and divided by condition: smartphone location (i.e., on desk, in pocket/bag, or outside) and power (i.e., on or off). For any continuous variables, the table(s) depict the mean (M), standard deviation (SD), minimum score (min.), maximum score (max.), and the sample size (n). For any nominal variables, the table(s) depict the variable, levels, and frequency for each level. This was done for the following:

  1. Demographics Data

    • Continuous variables (i.e., age)
    • Nominal variables (i.e., Sample Size, Balance, Gender, Language, Program, and Year)
  2. Task Data

    • OSpan Data (i.e., absolute score)
    • Go/No-Go Data (i.e., omission errors, average reaction time)
  3. Questionnaire Data

    • SUQ Data (e.g., typical smartphone usage)
    • SAD Data (i.e., SAD score)

This code organized the descriptive statistic data sets (click to see code)

This code organized the final data into the descriptive statistics for the Demographic Data (click to see code).

# make new data frame for descriptive stats
all_data_demo_des <- 
  all_data %>% 
  
  # subset data for descriptive variables only
  select(location, power, condition, balance, age, gender, lang, program, year) %>% 
  
  # set some variables as factors
  mutate(location = factor(location, levels = c(1:3), labels = c("Desk", "Pocket/Bag", "Outside"))) %>% 
  mutate(power = factor(power, levels = c(1:2), labels = c("On", "Off"))) %>% 
  mutate(condition = factor(condition, levels = c(1:6), labels = c("On & Desk", "On & Pocket/Bag", "On & Outside", "Off & Desk", "Off & Pocket/Bag", "Off & Outside"))) %>% 
  mutate(balance = factor(balance, levels = c(1:2), labels = c("Ospan Frist", "GnG First"))) %>% 
  mutate(gender = factor(gender, levels = c(1:2), labels = c("Male", "Female"))) %>% 
  mutate(lang = factor(lang, levels = c(0, 1), labels = c("Other", "English"))) %>% 
  mutate(program = factor(program, levels = c(3, 4, 13, 14, 28, 32, 37, 12, 17, 19, 15, 20, 24, 23, 26, 1, 2, 5, 7, 8, 11, 16, 18, 22, 27, 29, 33, 36, 6, 9, 10, 21, 25, 30, 31, 34, 35),
                          labels = c(rep("Arts & Humanities", 7), "Engineering", rep("Health Sciences", 2), rep("Information & Media Studies", 3), 
                                     "Medicine & Dentistry", "Music", rep("Science", 13), rep("Social Science", 9)))) %>% 
  mutate(year = factor(year, levels = c(1:4), labels = c("First Year", "Second Year", "Third Year", "Fourth Year")))

all_data_demo_des

This code organized the final data into the descriptive statistics for the Task Data (click to see code).

# make new data frame for descriptive stats
all_data_task_des <- 
  all_data %>% 
  # subset data for descriptive variables only
  select(location, power, condition, ospan_absolute_score, ospan_total_corr, ospan_math_percent_corr, gng_score, gng_err_omi, gng_rt_av)

all_data_task_des

This code organized the final data into the descriptive statistics for the Questionnaire Data (click to see code).

# make new data frame for descriptive stats
all_data_ques_des <- 
  all_data %>% 
  
  # subset data for descriptive variables only
  select(location, power, condition, SUQ_use_1:SUQ_use_3, SUQ_exp_1, SUQ_exp_2, SUQ_exp_4, 
         SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, SUQ_abext_score, SUQ_duract_score) %>% 
  
  # set some variables as factors
  mutate(SUQ_use_1 = factor(SUQ_use_1, levels = c(1:4), labels = c("0-5", "6-10", "11-15", ">15"))) %>% 
  mutate(SUQ_use_2 = factor(SUQ_use_2, levels = c(1:4), labels = c("0-5", "6-10", "11-15", ">15"))) %>% 
  mutate(SUQ_use_3 = factor(SUQ_use_3, levels = c(1:4), labels = c("0-5", "6-10", "11-15", ">15"))) %>% 
  mutate(SUQ_exp_1 = factor(SUQ_exp_1, levels = c(1:4), labels = c("$0-$20", "$21-$40", "$41-$60", ">$60")))

all_data_ques_des

Demographic Data

The following table depicts the continuous variable(s) (i.e., age) from all participants in the present study (click to see code).

Demographic Information by Condition and Overall: Age
ON
OFF
On Desk In Pocket/Bag Outside On Desk In Pocket/Bag Outside TOTAL
Age (years)
1 M 18.80 18.66 19.10 18.66 19.08 18.95 18.87
2 SD 0.91 0.88 2.67 1.05 1.33 1.05 1.43
3 min. 18.00 18.00 18.00 17.00 18.00 18.00 17.00
4 max. 21.00 21.00 38.00 22.00 23.00 22.00 38.00
5 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Note:
Continuous descriptive statistics shown. 'TOTAL' column shows statistics across all conditions.

The following table depicts the nominal variables (i.e., Sample Size, Balance, Gender, Language, Program, and Year) from all participants in the present study (click to see code).

Demographic Data by Condition and Overall: Sample Size, Balance, Gender, Language, Program, and Year
ON
OFF
On Desk In Pocket/Bag Outside On Desk In Pocket/Bag Outside TOTAL
Sample Size
1 n 70 67 59 58 65 64 383
Balance
2 Ospan Frist 35 28 26 23 34 31 177
3 GnG First 35 39 33 35 31 33 206
Gender
4 Male 32 32 30 34 32 25 185
5 Female 38 35 29 24 33 39 198
First Language
6 Other 15 12 9 7 10 11 64
7 English 55 55 50 51 55 53 319
Year
8 First Year 46 48 41 42 44 42 263
9 Second Year 15 10 10 7 10 14 66
10 Third Year 2 5 3 6 5 7 28
11 Fourth Year 4 1 3 1 6 1 16
12 No Selection 3 3 2 2 0 0 10
Program
13 Arts & Humanities 2 2 0 2 2 1 9
14 Engineering 1 0 0 0 0 0 1
15 Health Sciences 10 8 14 6 10 10 58
16 Information & Media Studies 3 2 1 1 3 3 13
17 Medicine & Dentistry 14 8 10 14 12 12 70
18 Music 0 1 2 1 1 0 5
19 Science 18 17 13 12 11 18 89
20 Social Science 19 28 18 20 26 19 130
21 No Selection 3 1 1 2 0 1 8
Note:
Nominal descriptive statistics shown as frequencies. Row 1 depicts sample size across all variables. 'TOTAL' column depicts frequencies across all conditions.

Task Data

The following table depicts the OSpan and Go/No-Go variable(s) (i.e., OSpan Absolute Score, OSpan Total Correct, OSpan Math Percentage Correct, Go/No-Go Score, Go/No-Go Omission Errors, Go/No-Go Average Reaction Time) from all participants in the present study (click to see code).

Task Data by Condition and Overall: OSpan Absolute Score, OSpan Total Correct, OSpan Math Percentage Correct, Go/No-Go Score, Go/No-Go Omission Errors, Go/No-Go Average Reaction Time
ON
OFF
On Desk In Pocket/Bag Outside On Desk In Pocket/Bag Outside TOTAL
OSpan Task
Absolute Score
1 M 41.46 42.76 39.05 40.76 41.25 43.62 41.54
2 SD 16.22 15.44 18.25 18.93 17.33 15.68 16.90
3 min. 6.00 6.00 4.00 0.00 3.00 0.00 0.00
4 max. 75.00 75.00 75.00 75.00 75.00 75.00 75.00
5 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Total Score
6 M 57.81 59.01 55.93 56.64 57.52 59.36 57.77
7 SD 12.72 11.71 14.27 14.88 12.34 12.91 13.09
8 min. 11.00 11.00 17.00 7.00 23.00 2.00 2.00
9 max. 75.00 75.00 75.00 75.00 75.00 75.00 75.00
10 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Math Correct (%)
11 M 95.03 95.74 94.89 94.99 95.65 95.46 95.30
12 SD 3.42 3.06 3.22 3.46 3.17 3.32 3.27
13 min. 86.67 88.00 85.33 86.67 86.67 85.33 85.33
14 max. 100.00 100.00 100.00 100.00 100.00 100.00 100.00
15 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Cue-Dependent Go/No-Go Task
Total Score
16 M 247.70 248.49 248.36 247.71 247.52 248.86 248.10
17 SD 6.81 2.37 2.10 4.43 10.35 1.62 5.62
18 min. 197.00 235.00 242.00 222.00 167.00 244.00 167.00
19 max. 250.00 250.00 250.00 250.00 250.00 250.00 250.00
20 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Omission Errors
21 M 0.81 0.45 0.76 1.09 0.78 0.45 0.72
22 SD 2.38 1.06 1.52 3.55 3.80 0.96 2.46
23 min. 0.00 0.00 0.00 0.00 0.00 0.00 0.00
24 max. 15.00 5.00 8.00 23.00 30.00 5.00 30.00
25 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Omission Errors for 'Go' Trials
26 M 0.70 0.36 0.51 0.97 0.57 0.31 0.56
27 SD 2.16 0.85 1.06 3.09 2.93 0.73 2.03
28 min. 0.00 0.00 0.00 0.00 0.00 0.00 0.00
29 max. 14.00 4.00 5.00 20.00 23.00 4.00 23.00
30 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Omission Errors for 'No-Go' Trials
31 M 0.11 0.09 0.25 0.12 0.22 0.14 0.15
32 SD 0.36 0.29 0.68 0.50 0.93 0.39 0.56
33 min. 0.00 0.00 0.00 0.00 0.00 0.00 0.00
34 max. 2.00 1.00 3.00 3.00 7.00 2.00 7.00
35 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Average Reaction Time
36 M 1.66 1.66 1.66 1.67 1.66 1.66 1.66
37 SD 0.05 0.06 0.04 0.09 0.06 0.06 0.06
38 min. 1.58 1.56 1.56 1.57 1.56 1.56 1.56
39 max. 1.88 1.80 1.77 2.21 1.84 1.87 2.21
40 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Note:
Continuous descriptive statistics shown for Task data (i.e., OSpan Task and Cue-Dependent Go/No-Go Task). 'TOTAL' column shows statistics across all conditions.

Questionnaire Data

The following table depicts the SUQ and SAD variable(s) for both continuous (i.e., SUQ score for smartphone use with absence of other stimulation, SUQ score for smartphone use during other actions, SAD score) and nominal (i.e., Average text messages per day, Average social media based messages sent per day, Average social media based posts per day, Smartphone subjective value, Types of notifications, Phantom vibrations) variables from all participants in the present study (click to see code).

The continuous data includes:

  • SUQ score for smartphone use with absence of other stimulation

  • SUQ score for smartphone use during other actions

  • SAD score (i.e., attachment and dependency to one’s smartphone):

    • \(SAD_{overall}\): SAD score for all 13 items

    • \(SAD_{Dep}\): SAD score for the Smartphone Dependence subscale (items: 1, 2, 3, 4, 5)

    • \(SAD_{EA}\): SAD score for the Emotional Attachment subscale (items: 8, 9, 10, 11)

    • \(SAD_{Dist}\): SAD score for the Smartphone Distractibility subscale (items: 7, 12, 13)

      This code organized the continuous data (click to see code). </summary)

Questionnaire Data by Condition and Overall: Continuous Variables
ON
OFF
On Desk In Pocket/Bag Outside On Desk In Pocket/Bag Outside TOTAL
Smartphone Usage Questionnaire (SUQ)
Tendency to use one's smartphone in the abscence of other stimulation
1 M 6.12 6.28 6.21 6.19 6.32 6.36 6.25
2 SD 1.14 1.06 1.04 1.04 0.92 0.97 1.03
3 min. 1.50 2.00 2.50 4.00 3.50 3.50 1.50
4 max. 7.00 7.00 7.00 7.00 7.00 7.00 7.00
5 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Tendency to use one's smartphone in the during other actions
6 M 2.71 2.93 2.51 2.84 2.78 2.58 2.73
7 SD 1.24 1.38 1.06 1.18 1.24 1.16 1.22
8 min. 1.00 1.00 1.00 1.00 1.00 1.00 1.00
9 max. 6.00 7.00 6.50 6.00 7.00 7.00 7.00
10 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Smartphone Attachment and Dependency Inventory (SAD)
Overall: Items #1-13
11 M 57.67 58.94 58.08 59.86 57.32 62.23 58.99
12 SD 15.32 13.58 14.60 13.15 12.39 12.46 13.66
13 min. 19.00 27.00 22.00 25.00 19.00 32.00 19.00
14 max. 89.00 87.00 86.00 87.00 79.00 87.00 89.00
15 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Smartphone Dependence: Items #1-3
16 M 11.73 12.51 12.42 13.31 12.20 13.77 12.63
17 SD 5.57 4.61 5.07 4.39 4.38 3.98 4.73
18 min. 3.00 3.00 3.00 3.00 3.00 5.00 3.00
19 max. 21.00 21.00 21.00 21.00 20.00 21.00 21.00
20 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Emotional Attachment: Items #8-11
21 M 16.80 16.30 16.39 16.55 16.43 17.88 16.73
22 SD 5.05 5.32 5.07 4.58 4.73 4.63 4.91
23 min. 4.00 4.00 4.00 5.00 4.00 6.00 4.00
24 max. 28.00 28.00 27.00 26.00 26.00 28.00 28.00
25 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Accessibility: Items #5, 6, 7
26 M 14.67 15.01 14.98 15.31 14.60 15.55 9.98
27 SD 4.01 3.43 3.84 3.95 3.68 3.23 2.70
28 min. 3.00 6.00 3.00 6.00 4.00 8.00 2.00
29 max. 21.00 21.00 21.00 21.00 21.00 21.00 14.00
30 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Smartphone Distractability: Items #12, 13
31 M 10.10 10.36 9.66 10.07 9.75 9.88 6.25
32 SD 2.84 2.49 2.78 2.89 2.43 2.82 1.03
33 min. 2.00 2.00 4.00 2.00 3.00 2.00 1.50
34 max. 14.00 14.00 14.00 14.00 14.00 14.00 7.00
35 n 70.00 67.00 59.00 58.00 65.00 64.00 383.00
Note:
Continuous descriptive statistics shown for Questionnaire data (i.e., SUQ score for smartphone use with absence of other stimulation, SUQ score for smartphone use during other actions, SAD score). 'TOTAL' column shows statistics across all conditions.


The nominal data includes:

  • Average text messages per day
  • Average social media based messages sent per day
  • Average social media based posts per day
  • Smartphone subjective value
  • Types of notifications
  • Phantom vibrations

This code organized the nominal data (click to see code). </summary)

Questionnaire Data by Condition and Overall: Nominal Variables
ON
OFF
On Desk In Pocket/Bag Outside On Desk In Pocket/Bag Outside TOTAL
Sample Size
1 n 70 67 59 58 65 64 383
Smartphone Usage Questionnaire (SUQ)
Average Text Messages per Day
2 0-5 18 11 10 10 10 9 68
3 6-10 5 11 9 6 6 8 45
4 11-15 8 3 5 5 10 8 39
5 >15 39 42 35 37 39 39 231
Average Social Media Based Messages Sent per Day
6 0-5 12 7 9 10 12 12 62
7 6-10 12 6 9 4 7 3 41
8 11-15 5 8 5 5 7 4 34
9 >15 41 46 36 39 39 45 246
Average Social Media Based Posts per Day
10 0-5 60 58 45 44 52 51 310
11 6-10 5 3 1 6 8 6 29
12 11-15 2 1 5 5 1 3 17
13 >15 3 5 8 3 4 4 27
Smartphone Subjective Value
14 $0-$20 32 24 25 12 23 24 140
15 $21-$40 13 13 12 22 21 12 93
16 $41-$60 8 11 11 12 16 9 67
17 >$60 17 19 11 12 5 19 83
Types of Notifications*
18 Email 47 45 47 46 39 53 277
19 Facebook 42 41 38 36 36 36 229
20 Twitter 13 22 14 14 11 22 96
21 Instagram 44 46 39 33 37 43 242
22 LinkedIn 5 2 4 5 1 7 24
23 Snapchat 53 51 47 43 49 50 293
24 Other 23 16 10 11 17 18 95
Phantom Vibrations
25 Experienced 62 54 52 53 54 56 331
26 Not Experienced 8 13 7 5 11 8 52
Note:
Continuous descriptive statistics shown for Questionnaire data (i.e., Sample size, Average text messages per day, Average social media based messages sent per day, Average social media based posts per day, Smartphone subjective value, Types of notifications, Phantom vibrations). 'TOTAL' column shows statistics across all conditions.
* Each participant could choose multiple types of notifications.

Planned Analyses

The following analyses were completed based on a pre-registered direct replication on OSF (view registration: https://osf.io/ubys7/?view_only=5db76bba381a4dc4aac130f7cd3a0de5) of Ward et al.’s (2017) second experiment. The analyses tested the three main hypotheses in the present study: (1) the location effect hypothesis, (2) the power effect hypothesis, and (3) the moderation effect hypothesis.

Each analysis contains the following:

  1. Analysis (including any relevant assumption tests)
  2. Visualizations

Note: Descriptive statistics are shown in the Descriptive Statistics section

1. & 2. Testing the Location and Power Hypotheses:

OSpan Task

A 3(smartphone location: desk, pocket/bag, outside) x 2(smartphone power: ON, OFF) between-subjects ANOVA was conducted (DV = OSpan absolute score).

Prior to completing the analysis, planned exclusion criteria was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions. Specifically, only participants who payed attention to both the math component and letter recall component of the task were included. Only data from those who scored 85% or higher on the math component of the task were included. View the Data Cleaning section under the data Construct Working Dataframes heading above. There was a total of 383 participants in the OSpan analysis.

Analysis

To assess if OSpan absolute score statistically differed, we conducted a 3x2 ANOVA with the between-subjects factors of smartphone location (i.e., on desk, in pocket/bag, or outside) and power (i.e., on or off). Since there are unequal sample sizes, we used Type III sum of squares.

Assumptions

The ANOVA made three assumptions: independent random sampling, normality, and homogeneity of variance. All assumptions were met (click to see details).

1. Independent Random Sampling

This assumption was met during testing.

2. Normality

This assumption was tested by visualizing the residuals, applying a Shapiro-Wilk test to the residuals, and observing the Skewness and Kurtosis of the data (extracted from the ANOVA output; click to see code).


# get the required data from the ospan_analysis data: participant, location, power, and score
ospan_anova_data = ospan_analysis[, c("participant", "location", "power", "ospan_absolute_score")]
    colnames(ospan_anova_data) = c("participant", "location", "power", "score")
    rownames(ospan_anova_data) = NULL
    # reformat location,  power, and balance as factors  
    ospan_anova_data$location = factor(ospan_anova_data$location, 
                  levels = c(1, 2, 3),
                  labels = c("On Desk", "Pocket/Bag", "Outside"))
    ospan_anova_data$power = factor(ospan_anova_data$power, 
                  levels = c(1, 2),
                  labels = c("ON", "OFF"))

# run between-subjects ANOVA (IV: Smartphone Power & Location, Balance; DV: OSpan Abolute Score)
ospan_anova = ezANOVA(
  data = ospan_anova_data
  , dv = .(score)
  , wid = .(participant)
  , between = .(location, power)
  , type = 3 # unequal sample sizes, therfore use type 3
  , detailed = TRUE
  , return_aov = TRUE
)
Warning: Converting "participant" to factor for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
Coefficient covariances computed by hccm()
# calculate & extract the residuals from the ANOVA
ospan_res = data.frame("residuals" = proj(ospan_anova$aov)[,"Residuals"])   
  • It appears that the residuals lie closely to a straight line, which suggests normality (see visualization below).

qqnorm(ospan_res$residuals, main = "Q-Q Plot of the OSpan Residuals") 
qqline(ospan_res$residuals)

  • It appears that residuals tend to follow the shape of a normal distribution, with a slight skew to the right (see visualization below).

qplot(ospan_res$residuals, main = "Histogram of Ospan Residuals", binwidth = 5) + 
  theme_classic()

  • The Shapiro-Wilk test of normality was significant (based on \(\alpha = 0.05\)), W = 0.99, p = .001 (see code below).

ospan_shap = shapiro.test(ospan_res$residuals)
ospan_shap

    Shapiro-Wilk normality test

data:  ospan_res$residuals
W = 0.98594, p-value = 0.0008969
  • The Skewness and Kurtosis were examined and showed that both the Skewness (range: -0.42 to -0.05) and Kurtosis (range: -0.86 to 0.1) were within the acceptable range of \(\pm 2.0\) and \(\pm 9.0\), respectively (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010) (see table below; click to see code).

# use the "ospan_des" data frame from the descriptive stats

# organize the data into a new data frame depicting the Skew, kurtosis, and sample size (n).
  ospan_sk_t = rbind((cbind(t(des_task_cont["ospan_absolute_score1", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["ospan_absolute_score2", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["ospan_absolute_score3", c("skew", "kurtosis", "n")]))), 
                      (cbind(t(des_task_cont["ospan_absolute_score4", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["ospan_absolute_score5", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["ospan_absolute_score6", c("skew", "kurtosis", "n")]))))
    colnames(ospan_sk_t) = c("On Desk", "In Pocket/Bag", "Outside")
    rownames(ospan_sk_t) = rep(c("Skewness", "Kurtosis", "n"), 2)
# use kable to show the descriptive table
  kable(ospan_sk_t, caption = "Skewness and Kurtosis of the Absolute Score on the OSpan Task", digits = 2, align = 'c') %>%
  add_header_above(c(" ", "Smartphone Location" = 3), bold = T) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  row_spec(0, bold = T) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Skewness and Kurtosis of the Absolute Score on the OSpan Task
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness -0.23 -0.42 -0.05
Kurtosis -0.71 -0.26 -0.84
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness -0.39 -0.22 -0.42
Kurtosis -0.86 -0.78 0.10
n 58.00 65.00 64.00
  • Therefore, based on all the normality assumption checks, normality was assumed to be within the acceptable range for the ANOVA analysis. Additionally, it should be noted that ANOVA analyses can be robust to violations of normality (Gardner & Tremblay, 2007).

3. Homogeneity of Variance

This assumption was tested by conducting Levene’s Test for Homogeneity of Variance for each between-subjects variable (i.e., smartphone location and smartphone power).

  • The homogeneity assumption was met (based on \(\alpha = 0.05\)) for smartphone location, F(2, 380) = 0.5, p = = .61 and smartphone power, F(1, 381) = 0.22, p = .64 (see code below).
# conduct levene's
  # for location
  ospan_lev_loc = leveneTest(data = ospan_anova_data, score ~ as.factor(location), center = mean)
  ospan_lev_loc
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value Pr(>F)
group   2  0.4966  0.609
      380               
  # for power
  ospan_lev_pow = leveneTest(data = ospan_anova_data, score ~ as.factor(power), center = mean)
  ospan_lev_pow
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value Pr(>F)
group   1  0.2177 0.6411
      381               
Results

All results were based on \(\alpha = 0.05\). Below are the reported statistics for both main effects and the interactions, followed by a table depicting the ANOVA results.

Main Effect of Smartphone Location

There was no significant main effect of smartphone location on Ospan absolute score, F(2, 377) = 0.1, p = .91, \(\eta^{2}\) = .001.

Main Effect of Smartphone Power

There was no significant main effect of smartphone power on Ospan absolute score, F(1, 377) = 0.21, p = .65, \(\eta^{2}\) = .001.

Interaction of Smartphone Location & Smartphone Power

There was no significant interaction between smartphone location and smartphone power on Ospan absolute score, F(2, 377) = 1.19, p = .3, \(\eta^{2}\) = .01.

Post-hoc Tests

Since there was no significant main or interaction effects, no post-hocs were completed.

# show ANOVA results in kable table 
kable(ospan_anova$ANOVA, caption = "3x2 ANOVA on Ospan Absolute Score", digits = 4, align = 'c') %>%
  row_spec(0, bold = T) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>% 
  kable_classic()
3x2 ANOVA on Ospan Absolute Score
Effect DFn DFd SSn SSd F p p<.05 ges
(Intercept) 1 377 656179.2350 108330.1 2283.5723 0.0000 * 0.8583
location 2 377 56.1861 108330.1 0.0978 0.9069 0.0005
power 1 377 59.0225 108330.1 0.2054 0.6507 0.0005
location:power 2 377 684.6542 108330.1 1.1913 0.3050 0.0063

Visualizations

The following shows a visualization of the OSpan absolute score based on the two smartphone conditions: location and power. (click to see code).

# create data frame with location conditions as characters rather than integers 
  # First, get a subset of the descriptive data
  ospan_bar_data <- ospan_analysis[, c("location", "power", "ospan_absolute_score")]
    colnames(ospan_bar_data) = c("location", "power", "score")
    rownames(ospan_bar_data) = NULL
    
  ospan_bar_data$location = factor(ospan_bar_data$location, 
                  levels = c(1, 2, 3),
                  labels = c("Desk", "Pocket/Bag", "Outside"))
  ospan_bar_data$power = factor(ospan_bar_data$power, 
                  levels = c(1, 2),
                  labels = c("ON", "OFF"))
# plot bar graph - GOOD
ospan_bar <- 
  ggplot(ospan_bar_data, aes(x = location, y = score, fill = power), show.legend = FALSE) +
  geom_bar(stat = "summary", fun = mean, position = "dodge") + 
    guides(shape = FALSE) + 
  scale_fill_manual(values = c("cadetblue3", "deepskyblue4")) + 
  labs(
       title = "Performance on the OSpan Task",
       subtitle = "Average Absolute OSpan Score",
       caption = "Note: Score is the number of correct letters recalled based \n on if all letters in a given block were recalled correctly.",
       x = "Smartphone Location", 
       y = "OSpan Absolute Score", 
       fill = "Smartphone Power"
       ) +
        # the "\n" here denote that you want a new line formed in the text
  scale_y_continuous(limits = c(min(ospan_bar_data$score), max(ospan_bar_data$score)), breaks = ) +
  #scale_colour_manual(values = cols) +
  geom_point(stat = "identity", aes(color = power), size = 1, 
             position = position_jitterdodge(jitter.width = .53), show.legend = FALSE) +
  scale_color_manual(values = c("deepskyblue4", "purple4")) + 
  geom_point(stat="summary", fun=mean, position = position_dodge(.9), size = 1.5, show.legend = FALSE) +
  geom_errorbar(data = ospan_bar_data, stat = "summary", funmin = function(x) mean(x) - sd(x)/sqrt(length(x)), 
                funmax = function(x) mean(x) + sd(x)/sqrt(length(x)), size= .5, width= .25, position = position_dodge(.9)) +
  theme_classic() +
  theme(plot.title = element_text(color = "black", size = 14, face = "bold"), 
        plot.subtitle = element_text(color = "black", size = 13), 
        plot.caption = element_text(hjust = 0, size = 12, face = "italic"),
        text = element_text(size = 13))

# show fig
ospan_bar
No summary function supplied, defaulting to `mean_se()`

# export plot
# ggsave(filename="fig_ospan_bar_june16", plot = ospan_bar, device = "jpeg", height = 5, width = 8, units = "in", dpi = 1000)

Cue-Dependent Go/No-Go Task

An error (i.e., omission errors) and accuracy (i.e., RT) analysis was completed using the omission errors and average RT for each participant.

Error Analysis

A 3(Smartphone location: desk, pocket/bag, outside) x 2(Smartphone power: ON, OFF) x 2(Cue type: Vertical, Horizontal) mixed ANOVA was completed (DV = omission error(s)). The between-subjects factors were smartphone location and power, and the within-subjects factor was pre-target cue type (i.e., “cue type”; either “vertical” or “horizontal”).

Prior to completing the analysis, planned exclusion criteria was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions. Only data from those who scored higher than chance performance (i.e., responded to at least 50% of “Go” trials and withheld response to at least 50% of “No-Go” trials) were used for the final analysis. View the Data Cleaning section under the data Construct Working Dataframes heading above. There was a total of 383 participants in the Go/No-Go Error analysis.

Analysis

To assess if the omission errors statistically differed, we conducted a 3x2x2 mixed ANOVA with the between-subjects factors of smartphone location (i.e., on desk, in pocket/bag, or outside) and power (i.e. on or off), and the within-subjects factor of cue type (i.e., “vertical” or “horizontal”). Since there are unequal sample sizes, we used Type III sum of squares.

Assumptions

The mixed ANOVA made four assumptions: independent random sampling, normality, homogeneity of variance (i.e., for the between-subject factors), and sphericity (i.e., for the within-subjects factor). Normality was outside of the acceptable range, however, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007). The homogeneity of variance assumption was not met. Due to this and since there are unequal sample sizes, a White-corrected F-test was completed for the between-subject factors (i.e., smartphone location, power) (click to see details).

1. Independent Random Sampling

This assumption was met during testing.

2. Normality

This assumption was tested by visualizing the residuals, applying a Shapiro-Wilk test to the resdiuals, and observing the Skewness and Kurtosis of the data (extracted from the ANOVA output; click to see code).


# get the required data from the gng_err_analysis data: participant, location, power, and score
gng_err_anova_data = gng_err_analysis[,c("participant", "location", "power", "cue", "gng_err_omi_long")]
    colnames(gng_err_anova_data) = c("participant", "location", "power", "cue", "err_omi")
    rownames(gng_err_anova_data) = NULL
    gng_err_anova_data$location = as.factor(gng_err_anova_data$location)
    gng_err_anova_data$power = as.factor(gng_err_anova_data$power)
    gng_err_anova_data$cue = as.factor(gng_err_anova_data$cue)

# run mixed ANOVA (IV b/w: Smartphone Power & Location; IV w/in: Target Type; DV: Omission Errors)
gng_err_anova = ezANOVA(
  data = gng_err_anova_data
  , dv = .(err_omi)
  , wid = .(participant)
  , within = .(cue)
  , between = .(location, power)
  , type = 3 # unequal sample sizes, therefore use type 3
  , detailed = TRUE
  , return_aov = TRUE
)
Warning: Converting "participant" to factor for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
# calculate & extract the residuals from the ANOVA
gng_err_res = data.frame("residuals" = proj(gng_err_anova$aov)[[3]][, "Residuals"])
  • It appears that the residuals lie closely to a straight line (i.e., only a couple lie away form the line), which suggests normality (see visualization below).

qqnorm(gng_err_res$residuals, main = "Q-Q Plot of the Go/No-Go Error Residuals") 
qqline(gng_err_res$residuals)

  • It appears that residuals are leptokurtic (i.e., there is a high peak near the center). This was expected since the Cue-Dependent Go/No-Go task is an easy response inhibition task, resulting in low error rates (see visualization below).

qplot(gng_err_res$residuals, main = "Histogram of Go/No-Go Error Residuals", binwidth = .15) + 
  theme_classic()

  • The Shapiro-Wilk test of normality was significant (based on \(\alpha = 0.05\)), W = 0.53, p < .001 (see code below).

gng_err_shap = shapiro.test(gng_err_res$residuals)
gng_err_shap

    Shapiro-Wilk normality test

data:  gng_err_res$residuals
W = 0.53223, p-value < 2.2e-16
  • The Skewness and Kurtosis was examined. For the vertical cue type, both the Skewness (range: 2.5 to 6.98) and Kurtosis (range: 5.8 to 50.22) were outside of the acceptable range of \(\pm 2.0\) and \(\pm 9.0\), respectively (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010). For the horizontal cue type, both the Skewness (range: 2.76 to 6.18) and Kurtosis (range: 5.99 to 41.42) were outside of the acceptable range of \(\pm 2.0\) and \(\pm 9.0\), respectively (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010) (see table below).

# create a table of the skewness & kurtosis for the gng data, separated by cue type (i.e. one for the vertical and horizontal trials)

#--FOR THE VERTICAL / Go CUE TYPE
# use the "des_task_cont_cue_v" data frame from the descriptives

# organize the data into a new data frame depicting the Skew, kurtosis, and sample size (n).
  gng_err_sk_v_t <- rbind((cbind(t(des_task_cont_cue_v["gng_err_omi_long1", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_v["gng_err_omi_long2", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_v["gng_err_omi_long3", c("skew", "kurtosis", "n")]))), 
                          (cbind(t(des_task_cont_cue_v["gng_err_omi_long4", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_v["gng_err_omi_long5", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_v["gng_err_omi_long6", c("skew", "kurtosis", "n")]))))
  colnames(gng_err_sk_v_t) = c("On Desk", "In Pocket/Bag", "Outside")
  rownames(gng_err_sk_v_t) = rep(c("Skewness", "Kurtosis", "n"), 2)
  
#--FOR THE HORIZONTAL / No-Go CUE TYPE
# use the "gng_err_des_h" data frame from the descriptives

# organize the data into a new data frame depicting the Skew, kurtosis, and sample size (n).
  gng_err_sk_h_t <- rbind((cbind(t(des_task_cont_cue_h["gng_err_omi_long1", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_h["gng_err_omi_long2", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_h["gng_err_omi_long3", c("skew", "kurtosis", "n")]))), 
                          (cbind(t(des_task_cont_cue_h["gng_err_omi_long4", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_h["gng_err_omi_long5", c("skew", "kurtosis", "n")]),
                                 t(des_task_cont_cue_h["gng_err_omi_long6", c("skew", "kurtosis", "n")]))))
    colnames(gng_err_sk_h_t) = c("On Desk", "In Pocket/Bag", "Outside")
    rownames(gng_err_sk_h_t) = rep(c("Skewness", "Kurtosis", "n"), 2)
# show a table of the skewness & kurtosis for the gng data, separated by cue type (i.e. one for the vertical and horizontal trials)
    
# for vertical cue type
# use kable to show the descriptives table
kable(gng_err_sk_v_t, caption = "Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'Go' (Vertical) Trials", digits = 2, align = 'c') %>%
  add_header_above(c(" ", "Smartphone Location" = 3), bold = T) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  row_spec(0, bold = T) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'Go' (Vertical) Trials
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness 4.38 2.50 2.52
Kurtosis 21.24 5.80 6.18
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness 4.51 6.98 2.81
Kurtosis 22.88 50.22 8.96
n 58.00 65.00 64.00
    
# for horizontal cue type
# use kable to show the descriptives table
kable(gng_err_sk_h_t, caption = "Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'No-Go' (Horizonatal) Trials", digits = 2, align = 'c') %>%
  add_header_above(c(" ", "Smartphone Location" = 3), bold = T) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  row_spec(0, bold = T) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'No-Go' (Horizonatal) Trials
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness 3.22 2.81 2.81
Kurtosis 10.47 5.99 7.34
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness 4.43 6.18 2.76
Kurtosis 20.04 41.42 7.34
n 58.00 65.00 64.00
  • Therefore, based on all the normality assumption checks, normality was not assumed to be within the acceptable range, however, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007).

3. Homogeneity of Variance

  • This assumption was tested by conducting Levene’s Test for Homogeneity of Variance for each between-subjects variable (i.e., smartphone location, smartphone power, and balance).

  • The homogeneity assumption was met (based on \(\alpha = 0.05\)) for smartphone power, F(1, 764) = 0.97, p = .32. However, it was not met for smartphone location, F(2, 763) = 3.72, p = .02,(see code below).


# conduct levene's
  # for location
  gng_err_lev_loc = leveneTest(data = gng_err_anova_data, err_omi ~ as.factor(location), center = mean)
  gng_err_lev_loc
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value  Pr(>F)  
group   2   3.724 0.02458 *
      763                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  # for power
  gng_err_lev_pow = leveneTest(data = gng_err_anova_data, err_omi ~ as.factor(power), center = mean)
  gng_err_lev_pow
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value Pr(>F)
group   1  0.9704 0.3249
      764               

4. Sphericity

This assumption was met since sphericity is always met for two levels of a repeated measure factor and is, therefore, unnecessary to evaluate (Girden, 1992).

Results

Since the homogeneity assumption was not met for the mixed ANOVA, a White-corrected F-test was completed. The results from this analysis are shown below, followed by a table depicting the statistics (click to see code).

Since the ezANOVA function can only complete a White-corrected F-test on between-subject factors, a separate ANOVA was computed using this correction for the between-subject effects. Additionally, the effect sizes were compluted separately using the EtaSq function.

All results were base on \(\alpha = 0.05\). Below are the reported statistics for both main effects and the interaction, followed by a table depicting the ANOVA results (click to see code).

Main Effect of Smartphone Location

There was no significant main effect of smartphone location on omission errors, F(2, 377) = 0.67, p = .51, \(\eta_{G}^2\) = = .002.

Main Effect of Smartphone Power

There was no significant main effect of smartphone power on omission errors, F(1, 377) = 0.15, p = .7, \(\eta_{G}^2\) = = .001.

Main Effect of Smartphone Cue Type

There was a significant main effect of cue type on omission errors, F(1, 377) = 23.22, p < .001, \(\eta_{G}^2\) = = .02.

Interaction of Smartphone Location & Power

There was no significant interaction between smartphone location and power on omission errors, F(2, 377) = 1.01, p = .37, \(\eta_{G}^2\) = = .003.

Interaction of Smartphone Location & Cue Type

There was a significant interaction between smartphone location and cue type on omission errors, F(2, 377) = 3.19, p = .04, \(\eta_{G}^2\) = = .01. Due to a significant interaction, the significant main effect of cue type was not explored further.

Interaction of Smartphone Power & Cue Type

There was no significant interaction between smartphone power and cue type on omission errors, F(1, 377) = 0.26, p = .61, \(\eta_{G}^2\) = < .001.

Interaction of Smartphone Location, Smartphone Power, & Cue Type

There was no significant interaction between smartphone location, smartphone power, and cue type on omission errors, F(2, 377) = 0.32, p = .72, \(\eta_{G}^2\) = = .001.

Post-hoc Tests

Since there was a significant interaction between cue type and smartphone location, a post-hocs assessing the simple main effects of cue type (i.e., vertical/go, horizontal/no-go) across the levels of smartphone location (i.e., desk, pocket/bag, outside) was completed.

# create data frame from mixed ANOVA results to display (including both white-corr for b/w sub effects)
gng_err_anova_t <- 
  data.frame("effect" = gng_err_anova$ANOVA$Effect[2:8], 
             "DFn" = gng_err_anova$ANOVA$DFn[2:8], 
             "DFd" = gng_err_anova$ANOVA$DFd[2:8], 
             "F" = c(gng_err_anova_white$ANOVA$F[2:3], gng_err_anova$ANOVA$F[4], gng_err_anova_white$ANOVA$F[4], gng_err_anova$ANOVA$F[6:8]), 
             "p" = c(gng_err_anova_white$ANOVA$p[2:3], gng_err_anova$ANOVA$p[4], gng_err_anova_white$ANOVA$p[4], gng_err_anova$ANOVA$p[6:8]), 
             "p<.05" = c(gng_err_anova_white$ANOVA$`p<.05`[2:3], gng_err_anova$ANOVA$`p<.05`[4], gng_err_anova_white$ANOVA$`p<.05`[4], gng_err_anova$ANOVA$`p<.05`[6:8]), 
             "ges" = c(gng_err_anova_white_es[1:2, 2], gng_err_anova$ANOVA$ges[4], gng_err_anova_white_es[3, 2], gng_err_anova$ANOVA$ges[6:8])
             )
# rename rows
rownames(gng_err_anova_t) = NULL
# show ANOVA results in kable table 
kable(gng_err_anova_t, caption = "3x2x2 Mixed ANOVA on Omission Error in the Go/No-Go Task", digits = 4, align = 'c', col.names = c("Effect", "DFn", "DFd", "F", "p", "p < .05", "ges")) %>%
  row_spec(0, bold = T) %>% 
  footnote(general = "Note: between-subject effects (i.e., location, power, location:power) are White-corrected.") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>% 
  kable_classic()
3x2x2 Mixed ANOVA on Omission Error in the Go/No-Go Task
Effect DFn DFd F p p < .05 ges
location 2 377 0.6684 0.5131 0.0023
power 1 377 0.1490 0.6997 0.0010
cue 1 377 23.2213 0.0000 * 0.0190
location:power 2 377 1.0102 0.3651 0.0034
location:cue 2 377 3.1866 0.0424 * 0.0053
power:cue 1 377 0.2592 0.6109 0.0002
location:power:cue 2 377 0.3246 0.7230 0.0005
Note:
Note: between-subject effects (i.e., location, power, location:power) are White-corrected.
Post-Hocs

An ANOVA was conducted to investigate the effect of cue type on omission errors for each smartphone location separately (with a Holm-Bonferroni adjustment).

PH: Assumptions

The two between-subjects ANOVA made three assumptions: independent random sampling, normality, and homogeneity of variance. For both ANOVAs, normality was outside of the acceptable range, however, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007). The homogeneity of variance assumption was met for the horizontal (i.e., “no-go”) cue type, but not for the vertical (i.e., “go”) cue type. Due to this and since there are unequal sample sizes, a White-corrected F-test was completed for the vertical (i.e., “go”) cue type ANOVA and a normal ANOVA for the horizontal (i.e., “no-go”) cue type (click to see details).

1. Independent Random Sampling

This assumption was met during testing for both ANOVAs.

2. Normality

This assumption was tested by visualizing the residuals, applying a Shapiro-Wilk test to the residuals, and observing the Skewness and Kurtosis of the data (extracted from the ANOVA output; click to see code).


# get the required data from the gng_err_analysis data: participant, location, and score
  # for vertical/go trials
  gng_err_anova_data_V <- 
    gng_err_anova_data %>% 
    # get cue type = "go" or vertical
    filter(cue == 1) %>% 
    # remove power factor
    select(-power)
  # for horizontal/no-go trials
  gng_err_anova_data_H <- 
    gng_err_anova_data %>% 
    # get cue type = "no-go" or horizontal 
    filter(cue == 2) %>% 
    # remove power factor
    select(-power)

# run ANOVA (IV: Smartphone Location; DV: Omission Errors)
  # for vertical/go trials
  gng_err_anova_V = ezANOVA(
    data = gng_err_anova_data_V
    , dv = .(err_omi)
    , wid = .(participant)
    , between = .(location)
    , type = 3 # unequal sample sizes, therefore use type 3
    , detailed = TRUE
    , return_aov = TRUE
    )
Warning: Converting "participant" to factor for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
Coefficient covariances computed by hccm()
  # for horizontal/no-go trials
  gng_err_anova_H = ezANOVA(
    data = gng_err_anova_data_H
    , dv = .(err_omi)
    , wid = .(participant)
    , between = .(location)
    , type = 3 # unequal sample sizes, therefore use type 3
    , detailed = TRUE
    , return_aov = TRUE
    )
Warning: Converting "participant" to factor for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
Coefficient covariances computed by hccm()
# calculate & extract the residuals from the ANOVA
  # for vertical/go trials
  gng_err_res_V = data.frame("residuals" = gng_err_anova_V$aov$residuals)
  # for horizontal/no-go trials
  gng_err_res_H = data.frame("residuals" = gng_err_anova_H$aov$residuals)
  • It appears that the residuals do not lie closely to a straight line: the data are heavy-tailed on the right (see visualization below).
# for vertical/go trials
qqnorm(gng_err_res_V$residuals, main = "Q-Q Plot of the Go/No-Go Error Residuals for Vertical/Go Trials") 
qqline(gng_err_res_V$residuals)


# for horizontal/no-go trials
qqnorm(gng_err_res_H$residuals, main = "Q-Q Plot of the Go/No-Go Error Residuals for Horizontal/No-Go Trials") 
qqline(gng_err_res_H$residuals)

  • It appears that residuals are leptokurtic (i.e., there is a high peak near the center). This was expected since the Cue-Dependent Go/No-Go task is an easy response inhibition task, resulting in low error rates (see visualization below).
# for vertical/go trials
qplot(gng_err_res_V$residuals, main = "Histogram of Go/No-Go Error Residuals for Vertical/Go Trials", binwidth = .5) + 
  theme_classic()

# for horizontal/no-go trials
qplot(gng_err_res_H$residuals, main = "Histogram of Go/No-Go Error Residuals for Horizontal/No-Go Trials", binwidth = .5) + 
  theme_classic()

  • The Shapiro-Wilk test of normality was significant (based on \(\alpha = 0.05\)) for the vertical (i.e., “go”) trials, W = 0.35, p < .001, and horizontal (i.e., “no-go”) trials, W = 0.34, p < .001 (see code below).
# for vertical/go trials
gng_err_shap_V <- shapiro.test(gng_err_res_V$residuals)
gng_err_shap_V

    Shapiro-Wilk normality test

data:  gng_err_res_V$residuals
W = 0.34529, p-value < 2.2e-16
# for horizontal/no-go trials
gng_err_shap_H <- shapiro.test(gng_err_res_H$residuals)
gng_err_shap_H

    Shapiro-Wilk normality test

data:  gng_err_res_H$residuals
W = 0.33566, p-value < 2.2e-16
  • The Skewness and Kurtosis was examined. For the vertical cue type, both the Skewness (range: 2.5 to 6.98) and Kurtosis (range: 5.8 to 50.22) were outside of the acceptable range of \(\pm 2.0\) and \(\pm 9.0\), respectively (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010). For the horizontal cue type, both the Skewness (range: 2.76 to 6.18) and Kurtosis (range: 5.99 to 41.42) were outside of the acceptable range of \(\pm 2.0\) and \(\pm 9.0\), respectively (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010) (see table below).
### NOTE: same table as before post-hocs

# show a table of the skewness & kurtosis for the gng data, separated by cue type (i.e. one for the vertical and horizontal trials)

# for vertical cue type
# use kable to show the descriptives table
kable(gng_err_sk_v_t, caption = "Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'Go' (Vertical) Trials", digits = 2, align = 'c') %>%
  add_header_above(c(" ", "Smartphone Location" = 3), bold = T) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  row_spec(0, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'Go' (Vertical) Trials
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness 4.38 2.50 2.52
Kurtosis 21.24 5.80 6.18
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness 4.51 6.98 2.81
Kurtosis 22.88 50.22 8.96
n 58.00 65.00 64.00

# for horizontal cue type
# use kable to show the descriptives table
kable(gng_err_sk_h_t, caption = "Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'No-Go' (Horizonatal) Trials", digits = 2, align = 'c') %>%
  add_header_above(c(" ", "Smartphone Location" = 3), bold = T) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  row_spec(0, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Skewness and Kurtosis of the Omission Errors on the Go/No-Go Task for 'No-Go' (Horizonatal) Trials
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness 3.22 2.81 2.81
Kurtosis 10.47 5.99 7.34
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness 4.43 6.18 2.76
Kurtosis 20.04 41.42 7.34
n 58.00 65.00 64.00
  • Therefore, based on all the normality assumption checks, normality was not assumed to be within the acceptable range, however, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007).

3. Homogeneity of Variance

  • This assumption was tested by conducting Levene’s Test for Homogeneity of Variance for vertical (i.e., “go”) trials and horizontal (i.e., “no-go”) trials.

  • The homogeneity assumption was met (based on \(\alpha = 0.05\)) for the horizontal (i.e., “no-go”) cue type, F(2, 380) = 1.93, p = .15. However, it was not met for vertical (i.e., “go”) cue type, F(2, 380) = 4.74, p = .01,(see code below).


# conduct levene's
  # for location
  gng_err_lev_V = leveneTest(data = gng_err_anova_data_V, err_omi ~ as.factor(location), center = mean)
  gng_err_lev_V
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value   Pr(>F)   
group   2  4.7449 0.009218 **
      380                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  # for power
  gng_err_lev_H = leveneTest(data = gng_err_anova_data_H, err_omi ~ as.factor(location), center = mean)
  gng_err_lev_H
Levene's Test for Homogeneity of Variance (center = mean)
       Df F value Pr(>F)
group   2  1.9329 0.1462
      380               
PH: SME Results

Since the homogeneity assumption was not met for the vertical (i.e., “go”) cue type ANOVA, a White-corrected F-test was completed. The ANOVA for the horizontal (i.e., “no-g”) cue type was completed without a correction. Both ANOVAs had a Holm-Bonferroni adjustment. The results from this analysis are shown below, followed by a table depicting the statistics (click to see code).

Run the white-corrected ANOVA for the vertical (i.e., “go”) cue type ANOVA.

Complete the Holm-Bonferroni adjustment for both ANOVAs.

# get corrected p-values for each ANOVA
gng_err_anova_cue_padj <- 
  p.adjust(c(gng_err_anova_V_white$ANOVA$p[2], # p-value from white-corrected V/go ANOVA
             gng_err_anova_H$ANOVA$p[2]), # p-value from H/no-go ANOVA
         method = c("holm"), # method: Holm-Bonferroni
         n = 2 # number of comparisons
         )

All results were base on \(\alpha = 0.05\). Below are the reported statistics for the main effects for each SME ANOVA, followed by a table depicting the SME ANOVA results (click to see code).

Cue Type: “Go” / Vertical

Main Effect of Smartphone Location

There was no significant main effect of smartphone location on omission errors for the vertical/“go” cue type, F(2, 380) = 1.42, p = .49, \(\eta_{G}^2\) = = .01.

Cue Type: “No-Go” / Horizontal

Main Effect of Smartphone Location

There was no significant main effect of smartphone location on omission errors for the horizontal/“no-go” cue type, F(2, 380) = 0.6, p = .55, \(\eta_{G}^2\) = = .003.

Post-hoc Tests

Since there was no significant main effect for either cue type, no post-hocs were completed.

# create data frame from mixed ANOVA results to display (including both white-corr for b/w sub effects)
gng_err_anova_cue_t <- 
  data.frame("effect" = c(gng_err_anova_V_white$ANOVA$Effect[2], gng_err_anova_H$ANOVA$Effect[2]), 
             "DFn" = c(gng_err_anova_V_white$ANOVA$DFn[2], gng_err_anova_H$ANOVA$DFn[2]), 
             "DFd" = c(gng_err_anova_V_white$ANOVA$DFd[2], gng_err_anova_H$ANOVA$DFd[2]), 
             "F" = c(gng_err_anova_V_white$ANOVA$F[2], gng_err_anova_H$ANOVA$F[2]), 
             "p" = gng_err_anova_cue_padj,
             "p<.05" = c(gng_err_anova_V_white$ANOVA$`p<.05`[2], gng_err_anova_H$ANOVA$`p<.05`[2]), 
             "ges" = c(gng_err_anova_V_white_es[2], gng_err_anova_H$ANOVA$ges[2])
             )
# rename rows
rownames(gng_err_anova_cue_t) = NULL
# show ANOVA results in kable table 
kable(gng_err_anova_cue_t, caption = "Tests of simple main effects on Go/No-Go omission errors for cue type (i.e., 'go' or 'no-go') across smartphone location levels (i.e., desk, pocket/bag, outside).", digits = 4, align = 'c', col.names = c("Effect", "DFn", "DFd", "F", "p", "p < .05", "ges")) %>%
  row_spec(0, bold = T) %>% 
  pack_rows("Cue Type: 'Go'", 1, 1) %>% 
  pack_rows("Cue Type: 'No-Go'", 2, 2) %>% 
  footnote(general = "Note: 'Go' cue type effect was White-corrected. Holm-Bonferroni adjusted p-values depicted.") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>% 
  kable_classic()
Tests of simple main effects on Go/No-Go omission errors for cue type (i.e., 'go' or 'no-go') across smartphone location levels (i.e., desk, pocket/bag, outside).
Effect DFn DFd F p p < .05 ges
Cue Type: 'Go'
location 2 380 1.4177 0.4871 0.0081
Cue Type: 'No-Go'
location 2 380 0.5976 0.5506 0.0031
Note:
Note: 'Go' cue type effect was White-corrected. Holm-Bonferroni adjusted p-values depicted.
Visualizations

The following shows a visualization of the Go/No-Go omission error data based on the three factors: smartphone location, smartphone power, and cue type.

  • To visualize the mixed design, two plots were created (i.e., one for each cue type).
#--FOR THE VERTICAL CUE TYPE-- 

# create data frame with location conditions as characters rather than integers 
  # First, get a subset of the data
  gng_err_bar_v_data = gng_err_analysis[gng_err_analysis$cue == 1, c("location", "power", "gng_err_omi_long")]
    colnames(gng_err_bar_v_data) = c("location", "power", "err_omi")
    rownames(gng_err_bar_v_data) = NULL 
  # reformat location & power as factors  
  gng_err_bar_v_data$location = factor(gng_err_bar_v_data$location, 
                  levels = c(1, 2, 3),
                  labels = c("On Desk", "Pocket/Bag", "Outside"))
  gng_err_bar_v_data$power = factor(gng_err_bar_v_data$power, 
                  levels = c(1, 2),
                  labels = c("ON", "OFF"))
       
# create plot
gng_err_bar_v = ggplot(gng_err_bar_v_data, aes(x = location, y = err_omi, fill = power), show.legend = FALSE) +
  geom_bar(stat = "summary", fun = "mean", position = "dodge") + 
    guides(shape = FALSE) + 
  scale_fill_manual(values = c("cadetblue3", "deepskyblue4")) + 
  labs(title = "Performance on the Go/No-Go Task: 'Vertical' Cue Type",
       subtitle = "Omission Errors",
       x = "Smartphone Location", 
       y = "Omission Error", 
       fill = "Smartphone Power",
       caption = paste0(strwrap("Figure X. Distributions of scores on the vertical cue type on the Cue-Dependent Go/No-Go Task, arranged by smartphone location (along the x-axis) and smartphone power (different bars). Omission errors occurred when a participant failed to respond to a non-target stimulus. Coloured dots represent individual data points. Black dots and error bars depict means and standard errors, respectively.", width = 80), collapse = "\n")) +
        # the "\n" here denote that you want a new line formed in the text
  scale_y_continuous(limits = c(min(gng_err_bar_v_data$err_omi), max(gng_err_bar_v_data$err_omi))) +
  #scale_colour_manual(values = cols) +
  geom_point(stat = "identity", aes(color = power), size = 1, 
             position = position_jitterdodge(jitter.width = .53), show.legend = FALSE) +
  scale_color_manual(values = c("deepskyblue4", "purple4")) + 
  geom_point(stat="summary", fun="mean", position = position_dodge(.9), size = 1.5, show.legend = FALSE) +
  geom_errorbar(data = gng_err_bar_v_data, stat = "summary", funmin = function(x) mean(x) - sd(x)/sqrt(length(x)), 
                funmax = function(x) mean(x) + sd(x)/sqrt(length(x)), size= .5, width= .25, position = position_dodge(.9)) +
  theme_classic() +
  theme(plot.title = element_text(color = "black", size = 14, face = "bold"), 
        plot.subtitle = element_text(color = "black", size = 13), 
        plot.caption = element_text(hjust = 0, size = 12, face = "italic"),
        text = element_text(size = 13))

#--FOR THE HORIZONTAL CUE TYPE-- 

# create data frame with location conditions as characters rather than integers 
  # First, get a subset of the data
  gng_err_bar_h_data = gng_err_analysis[gng_err_analysis$cue == 2, c("location", "power", "gng_err_omi_long")]
    colnames(gng_err_bar_h_data) = c("location", "power", "err_omi")
    rownames(gng_err_bar_h_data) = NULL 
  # reformat location & power as factors  
  gng_err_bar_h_data$location = factor(gng_err_bar_h_data$location, 
                  levels = c(1, 2, 3),
                  labels = c("On Desk", "Pocket/Bag", "Outside"))
  gng_err_bar_h_data$power = factor(gng_err_bar_h_data$power, 
                  levels = c(1, 2),
                  labels = c("ON", "OFF"))
       
# create plot
gng_err_bar_h = ggplot(gng_err_bar_h_data, aes(x = location, y = err_omi, fill = power), show.legend = FALSE) +
  geom_bar(stat = "summary", fun = "mean", position = "dodge") + 
    guides(shape = FALSE) + 
  scale_fill_manual(values = c("cadetblue3", "deepskyblue4")) + 
  labs(title = "Performance on the Go/No-Go Task: 'Horizontal' Cue Type",
       subtitle = "Omission Errors",
       x = "Smartphone Location", 
       y = "Omission Error", 
       fill = "Smartphone Power",
       caption = paste0(strwrap("Figure X. Distributions of scores on the horizontal cue type on the Cue-Dependent Go/No-Go Task, arranged by smartphone location (along the x-axis) and smartphone power (different bars). Omission errors occurred when a participant failed to respond to a non-target stimulus. Coloured dots represent individual data points. Black dots and error bars depict means and standard errors, respectively.", width = 80), collapse = "\n")) +
        # the "\n" here denote that you want a new line formed in the text
  scale_y_continuous(limits = c(min(gng_err_bar_h_data$err_omi), max(gng_err_bar_h_data$err_omi))) +
  #scale_colour_manual(values = cols) +
  geom_point(stat = "identity", aes(color = power), size = 1, 
             position = position_jitterdodge(jitter.width = .53), show.legend = FALSE) +
  scale_color_manual(values = c("deepskyblue4", "purple4")) + 
  geom_point(stat="summary", fun="mean", position = position_dodge(.9), size = 1.5, show.legend = FALSE) +
  geom_errorbar(data = gng_err_bar_h_data, stat = "summary", fun.ymin = function(x) mean(x) - sd(x)/sqrt(length(x)), 
                funmax = function(x) mean(x) + sd(x)/sqrt(length(x)), size= .5, width= .25, position = position_dodge(.9)) +
  theme_classic() +
  theme(plot.title = element_text(color = "black", size = 14, face = "bold"), 
        plot.subtitle = element_text(color = "black", size = 13), 
        plot.caption = element_text(hjust = 0, size = 12, face = "italic"),
        text = element_text(size = 13))

# Show plots
  # for the Vertical cue type
  gng_err_bar_v
No summary function supplied, defaulting to `mean_se()`

  # for the Horizontal cue type
  gng_err_bar_h
No summary function supplied, defaulting to `mean_se()`

  
# export plots
  # for the Vertical cue type
  # ggsave(filename="fig_gng_err_bar_v", plot = gng_err_bar_v, device = "png", height = 5, width = 8, units = "in", dpi = 500)
  # for the Horizontal cue type
  # ggsave(filename="fig_gng_err_bar_h", plot = gng_err_bar_h, device = "png", height = 5, width = 8, units = "in", dpi = 500)
  • Shown as one plot…

# create data frame with location conditions as characters rather than integers 
gng_err_bar_data <- 
  gng_err_anova_data %>% 
  # make location a factor
  mutate(location = factor(location, levels = c(1:3), labels = c("Desk", "Pocket/Bag", "Outside"))) %>% 
  # make power a factor
  mutate(power = factor(power, levels = c(1:2), labels = c("ON", "OFF"))) %>% 
  # make cue a factor
  mutate(cue = factor(cue, levels = c(1:2), labels = c("(A) 'Go' Trials", "(B) 'No-Go' Trials")))

# create plot
gng_err_bar <- 
  ggplot(gng_err_bar_data, aes(x = location, y = err_omi, fill = power), show.legend = FALSE) +
  geom_bar(stat = "summary", fun = "mean", position = "dodge") + 
    guides(shape = FALSE) + 
  scale_fill_manual(values = c("cadetblue3", "deepskyblue4")) + 
  labs(
       title = "Performance on the Go/No-Go Task",
       subtitle = "Omission Errors",
       caption = paste0(strwrap("Figure X. Distributions of scores on the vertical cue type on the Cue-Dependent Go/No-Go Task, arranged by smartphone location (along the x-axis) and smartphone power (different bars). Omission errors occurred when a participant failed to respond to a non-target stimulus. Coloured dots represent individual data points. Black dots and error bars depict means and standard errors, respectively.", width = 80), collapse = "\n"),
       x = "Smartphone Location", 
       y = "Omission Error", 
       fill = "Smartphone Power"
       ) +
        # the "\n" here denote that you want a new line formed in the text
  scale_y_continuous(limits = c(min(gng_err_bar_data$err_omi), max(gng_err_bar_data$err_omi))) +
  #scale_colour_manual(values = cols) +
  geom_point(stat = "identity", aes(color = power), size = 1, 
             position = position_jitterdodge(jitter.width = .53), show.legend = FALSE) +
  scale_color_manual(values = c("deepskyblue4", "purple4")) + 
  geom_point(stat="summary", fun="mean", position = position_dodge(.9), size = 1.5, show.legend = FALSE) +
  geom_errorbar(data = gng_err_bar_data, stat = "summary", funmin = function(x) mean(x) - sd(x)/sqrt(length(x)), 
                funmax = function(x) mean(x) + sd(x)/sqrt(length(x)), size= .5, width= .25, position = position_dodge(.9)) +
  facet_wrap(~cue, ncol = 2) +
  theme_classic() +
  theme(plot.title = element_text(color = "black", size = 14, face = "bold"), 
        plot.subtitle = element_text(color = "black", size = 13), 
        plot.caption = element_text(hjust = 0, size = 12, face = "italic"),
        text = element_text(size = 13))
# show plot
gng_err_bar
No summary function supplied, defaulting to `mean_se()`
No summary function supplied, defaulting to `mean_se()`

# export plots
# ggsave(filename="fig_gng_err_bar_june16", plot = gng_err_bar, device = "jpeg", height = 5, width = 8, units = "in", dpi = 1000)

Accuracy Analysis

A 3(smartphone location: desk, pocket/bag, outside) x 2(smartphone power: ON, OFF) between-subjects ANOVA was completed (DV = average RT). The between-subjects factors were smartphone location and power (click to see code).

Prior to completing the analysis, planned exclusion critera was applied to the data. Exclusion criteria for this analysis helped to control for any participants who did not follow the instructions. Any participants who had a reaction time that was higher than two standard deviations (SD) from the mean reaction time were not included in the final analysis. View the Data Cleaning section under the data Construct Working Dataframes heading above. There was a total of 383 participants in the Go/No-Go Accuracy analysis.

Analysis

To assess if the reaction time statistically differed, we conducted a 3x2 ANOVA with the between-subjects factors of smartphone location (i.e., on desk, in pocket/bag, or outside) and power (i.e., on or off). Since there are unequal sample sizes, we used Type III sum of squares.

Assumptions

The ANOVA made three assumptions: independent random sampling, normality, and homogeneity of variance. Normality was met but there was a slight skew to the right in the histogram and kurtosis was outside of the typical range, however, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007). (click to see details).

1. Independent Random Sampling

This assumption was met during testing.

2. Normality

This assumption was tested by visualizing the residuals, applying a Shapiro-Wilk test to the residuals, and observing the Skewness and Kurtosis of the data (extracted from the ANOVA output).


# get the required data from the ospan_analysis data: participant, location, power, and score
gng_ac_anova_data <- gng_ac_analysis[, c("participant", "location", "power", "gng_rt_av")]
    colnames(gng_ac_anova_data) = c("participant", "location", "power", "rt_av")
    rownames(gng_ac_anova_data) = NULL
    # reformat location,  power, and balance as factors  
    gng_ac_anova_data$location = factor(gng_ac_anova_data$location, 
                  levels = c(1, 2, 3),
                  labels = c("On Desk", "Pocket/Bag", "Outside"))
    gng_ac_anova_data$power = factor(gng_ac_anova_data$power, 
                  levels = c(1, 2),
                  labels = c("ON", "OFF"))

# run between-subjects ANOVA (IV: Smartphone Power & Location, Balance; DV: OSpan Abolute Score)
gng_ac_anova = ezANOVA(
  data = gng_ac_anova_data
  , dv = .(rt_av)
  , wid = .(participant)
  , between = .(location, power)
  , type = 3 # unequal sample sizes, therfore use type 3
  , detailed = TRUE
  , return_aov = TRUE
)
Warning: Converting "participant" to factor for ANOVA.
Warning: Data is unbalanced (unequal N per group). Make sure you specified a well-considered value for the type argument to ezANOVA().
Coefficient covariances computed by hccm()
# calculate & extract the residuals from the ANOVA
gng_ac_res <- data.frame("residuals" = proj(gng_ac_anova$aov)[,"Residuals"])   
  • It appears that the residuals lie closely to a straight line, which suggests normality (see visualization below).

qqnorm(gng_ac_res$residuals, main = "Q-Q Plot of the Go/No-Go Reaction Time Residuals") 
qqline(gng_ac_res$residuals)

  • It appears that residuals tend to follow the shape of a normal distribution, with a slight skew to the right and some data on the far right (see visualization below).

qplot(gng_ac_res$residuals, main = "Histogram of Go/No-Go Reaction Time Residuals", binwidth = .01) + 
  theme_classic()

  • The Shapiro-Wilk test of normality was significant (based on \(\alpha = 0.05\)), W = 0.86, p < .001 (see code below).

gng_ac_shap = shapiro.test(gng_ac_res$residuals)
gng_ac_shap

    Shapiro-Wilk normality test

data:  gng_ac_res$residuals
W = 0.86237, p-value < 2.2e-16
  • The data’s Skewness and Kurtosis was examined and showed that the Skewness (range: 0.2 to 3.74) was within the acceptable range of \(\pm 2.0\) (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010). For the Kurtosis, the on desk/powered off condition was outside the acceptable range of \(\pm 9.0\) (Schmider, Ziegler, Danay, Beyer, & Bühner, 2010; overall range: -0.6 to 18.3) (see table below).
# use the "gng_ac_des" data frame from the descriptives

# organize the data into a new data frame depicting the Skew, kurtosis, and sample size (n).
  gng_ac_sk_t = rbind((cbind(t(des_task_cont["gng_rt_av1", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["gng_rt_av2", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["gng_rt_av3", c("skew", "kurtosis", "n")]))), 
                      (cbind(t(des_task_cont["gng_rt_av4", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["gng_rt_av5", c("skew", "kurtosis", "n")]),
                             t(des_task_cont["gng_rt_av6", c("skew", "kurtosis", "n")]))))
    colnames(gng_ac_sk_t) = c("On Desk", "In Pocket/Bag", "Outside")
    rownames(gng_ac_sk_t) = rep(c("Skewness", "Kurtosis", "n"), 2)
    
# use kable to show the descriptives table
  kable(gng_ac_sk_t, caption = "Skewness and Kurtosis of the Reaction Time on the Go/No-Go Task", digits = 2, align = 'c') %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" ", "Smartphone Location" = 3)) %>%
  pack_rows("Smartphone Power ON", 1, 3) %>% 
  pack_rows("Smartphone Power OFF", 4, 6) %>%
  kable_classic()
Skewness and Kurtosis of the Reaction Time on the Go/No-Go Task
Smartphone Location
On Desk In Pocket/Bag Outside
Smartphone Power ON
Skewness 1.50 0.44 0.20
Kurtosis 3.40 -0.60 -0.30
n 70.00 67.00 59.00
Smartphone Power OFF
Skewness 3.74 0.81 0.76
Kurtosis 18.30 0.12 0.51
n 58.00 65.00 64.00
NA
  • Therefore, based on all the normality assumption checks, normality was assumed to be within the acceptable range for the ANOVA analysis. Although there was a slight skew to the right in the histogram and kurtosis was outside of the typical range, ultimately, ANOVA tests are typically robust to violations of normality (Gardner & Tremblay, 2007).

3. Homogeneity of Variance

This assumption was tested by conducting Levene’s Test for Homogeneity of Variance for each between-subjects variable (i.e. smartphone location and smartphone power).

  • The homogeneity assumption was met (based on \(\alpha = 0.05\)) for smartphone location, F(2, 380) = 0.26, p = .77 and smartphone power, F(1, 381) = 3.52, p = .06 (see code below).

# conduct levene's
  # for location
  gng_ac_lev_loc = leveneTest(data = gng_ac_anova_data, rt_av ~ as.factor(location), center = median)
  gng_ac_lev_loc
Levene's Test for Homogeneity of Variance (center = median)
       Df F value Pr(>F)
group   2  0.2647 0.7675
      380               
  # for power
  gng_ac_lev_pow = leveneTest(data = gng_ac_anova_data, rt_av ~ as.factor(power), center = median)
  gng_ac_lev_pow
Levene's Test for Homogeneity of Variance (center = median)
       Df F value  Pr(>F)  
group   1  3.5235 0.06127 .
      381                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  • The homogeneity of variance assumption was met. Based on all the normality assumption checks, normality was assumed to be within the acceptable range for the ANOVA analysis. Additionally, it should be noted that ANOVA analyses can be robust to violations of normality (Gardner & Tremblay, 2007).
Results

All results were based on \(\alpha = 0.05\). Below are the reported statistics for the main effects and the interactions, followed by a table depicting the ANOVA results.

Main Effect of Smartphone Location

There was no significant main effect of smartphone location on reaction time, F(2, 377) = 0, p = 1.49, \(\eta^{2}\) = .77.

Main Effect of Smartphone Power

There was no significant main effect of smartphone power on reaction time, F(1, 377) = 0, p = 1.49, \(\eta^{2}\) = .96.

Interaction of Smartphone Location & Smartphone Power

There was no significant interaction between smartphone location and smartphone power on reaction time, F(2, 377) = 0, p = 1.49, \(\eta^{2}\) = .96.

Post-hoc Tests

Since there was a significant three-way interaction (i.e smartphone location, smartphone power, and balance), further analyses were completed (see “Post-Hocs: Simple Two-Way Interactions” below).

# create table from ANOVA results
gng_ac_t <- gng_ac_anova$ANOVA

# show ANOVA results in kable table 
kable(gng_ac_anova$ANOVA, caption = "3x2 ANOVA on Average Reaction Time in the Go/No-Go Task", digits = 3, align = 'c') %>%
  row_spec(0, bold = T) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>% 
  kable_classic()
3x2 ANOVA on Average Reaction Time in the Go/No-Go Task
Effect DFn DFd SSn SSd F p p<.05 ges
(Intercept) 1 377 1054.389 1.491 266672.599 0.000 * 0.999
location 2 377 0.002 1.491 0.261 0.770 0.001
power 1 377 0.000 1.491 0.002 0.962 0.000
location:power 2 377 0.000 1.491 0.044 0.957 0.000
Visualizations

The following shows a visualization of Accuracy (i.e. reaction time) on the Cue-Dependent Go/No-go Task. There was no significant main effect of smartphone location or smartphone power and no significant interaction between smartphone location and power.

# First, get a subset of the data
gng_ac_bar_data <- 
  gng_ac_anova_data %>% 
  select(-participant) 
# %>% 
#   mutate(location = factor(location, labels = c("On Desk", "Pocket/Bag", "Outside"))) # didnt need this, its already a factor... 
  
# remove row names
rownames(gng_ac_bar_data) <- NULL

# plot bar graph
gng_ac_bar <- 
  ggplot(gng_ac_bar_data, aes(x = location, y = rt_av, fill = power), show.legend = FALSE) +
  geom_bar(stat = "summary", fun = "mean", position = "dodge") + 
    guides(shape = FALSE) + 
  scale_fill_manual(values = c("cadetblue3", "deepskyblue4")) + 
  labs(
       title = "Performance on the Go/No-Go Task \nfor the OSpan First Balance Condition",
       subtitle = "Accuracy (average reaction time)",
       caption = "Note: ...",
       x = "Smartphone Location", 
       y = "Average Reaction Time (sec.)", 
       fill = "Smartphone Power"
       ) +
        # the "\n" here denote that you want a new line formed in the text
  geom_point(stat = "identity", aes(color = power), size = 1, 
             position = position_jitterdodge(jitter.width = .53), show.legend = FALSE) +
  scale_color_manual(values = c("deepskyblue4", "purple4")) + 
  geom_point(stat="summary", fun="mean", position = position_dodge(.9), size = 1.5, show.legend = FALSE) +
  geom_errorbar(data = gng_ac_bar_data, stat = "summary", fun.ymin = function(x) mean(x) - sd(x)/sqrt(length(x)), 
                funmax = function(x) mean(x) + sd(x)/sqrt(length(x)), size= .5, width= .25, position = position_dodge(.9)) +
  theme_classic() +
  theme(plot.title = element_text(color = "black", size = 14, face = "bold"), 
        plot.subtitle = element_text(color = "black", size = 13), 
        plot.caption = element_text(hjust = 0, size = 12, face = "italic"),
        text = element_text(size = 13)) #+
  #scale_y_continuous(limits = c(min(gng_ac_bar_ospan_data$rt_av), max(gng_ac_bar_ospan_data$rt_av)))


# show the figures
gng_ac_bar
No summary function supplied, defaulting to `mean_se()`

  
# export plots
# ggsave(filename="fig_gng_ac_bar_june16", plot = gng_ac_bar, device = "jpeg", height = 5, width = 8, units = "in", dpi = 1000)

3. Testing the Moderation Hypothesis:

Exploratory Factor Analysis of the SAD

To examine the underlying factors measured by the Smartphone Attachment and Dependency Inventory (SAD) from Ward et al. (2017), a principal components factor analysis with a Varimax rotation was completed on participant’s SAD data. The analysis was exploratory and was compared to Ward et al.’s findings. There was a total of 383 participants in the factor analysis.

Checking the Data

To perform the principal components factor analysis, we first examined the data for (1) missing data, (2) correlations between the items, and (3) the factorability of the data.

1. Missing Data
  • From the descriptives table, it seems that there is no missing or incomplete data. This was confirmed by finding the complete cases, which were equal to the total sample size (i.e. 383). Therefore, no data was removed due to missing values for this analysis (see descriptives table below).

# get a data frame with the SAD items only for the factor analysis
fa_data = dplyr::select(factor_analysis, SAD_1:SAD_13)

# find the total complete cases to find any missing data from the data -- any participant with missing data must be removed
fa_complete = sum(complete.cases(fa_data))

# Show descriptives for the factor analysis data
fa_des = describe(fa_data)

# show descriptives in kable table 
kable(describe.by(fa_data), caption = "Descriptives for Items in the SAD", digits = 4, align = 'c', escape = FALSE) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>% 
  kable_classic()
Descriptives for Items in the SAD
vars n mean sd median trimmed mad min max range skew kurtosis se
SAD_1 1 383 4.7415 1.7301 5 4.8534 1.4826 1 7 6 -0.5343 -0.7942 0.0884
SAD_2 2 383 4.1018 1.8412 5 4.1336 1.4826 1 7 6 -0.1719 -1.2594 0.0941
SAD_3 3 383 3.7885 1.8978 4 3.7557 2.9652 1 7 6 0.1022 -1.2704 0.0970
SAD_4 4 383 4.6449 1.7722 5 4.7459 1.4826 1 7 6 -0.5174 -0.8707 0.0906
SAD_5 5 383 4.6188 1.7338 5 4.7003 1.4826 1 7 6 -0.4236 -0.9274 0.0886
SAD_6 6 383 4.6319 1.6556 5 4.7296 1.4826 1 7 6 -0.6095 -0.6438 0.0846
SAD_7 7 383 5.7598 1.1621 6 5.9283 1.4826 1 7 6 -1.2825 2.0867 0.0594
SAD_8 8 383 3.3420 1.7872 3 3.2606 2.9652 1 7 6 0.2816 -1.1532 0.0913
SAD_9 9 383 4.0209 1.7589 4 4.0684 1.4826 1 7 6 -0.1584 -1.0277 0.0899
SAD_10 10 383 4.7337 1.4783 5 4.8664 1.4826 1 7 6 -0.7401 0.0883 0.0755
SAD_11 11 383 4.6319 1.3586 5 4.7524 1.4826 1 7 6 -0.6467 0.2508 0.0694
SAD_12 12 383 4.7050 1.7692 5 4.8208 1.4826 1 7 6 -0.5285 -0.7616 0.0904
SAD_13 13 383 5.2715 1.3746 6 5.4332 1.4826 1 7 6 -1.0673 1.0619 0.0702
NA
2. Correlations between the Items
  • The correlations between the items were examined to determine if they were either not high enough (i.e., r < .30) or too high (i.e., r > .80).

    • The correlations for the 13 items in the SAD ranged from r(381) = .14 to r(381) = .72, p = .01.
    • A visual inspection of the correlations showed that items 12 and 13 might not be correlated enough with the rest of the items (i.e. 11 and 10 correlations below .30, respectively). There were no issues associated with too many high correations for any items.
    • The lower correlations for items 12 and 13 should be kept in mind when completing the factor analysis and these items may be removed.
  • To check for multicollinearity, the determinant of the correlation matrix was calculated. The determinant was greater than the necessary value of 0.00001 (i.e., 0.00576), so, there was no issues with multicollinearity (Field et al., 2012).

  • Therefore, all items in the SAD correlated reasonably with each other and without an excessively large correlation so no items were removed at this stage.


# get the pearson correlations between all items (and corresponding p-values)
fa_cor = rcorr(as.matrix(fa_data), type = "pearson") 

# make a table with the data to display it better
fa_cor_t = as.data.frame(fa_cor$r)
  # include only the lower triangle of the data
  fa_cor_t[upper.tri(fa_cor_t)] = NA
  
# find the determinant of the correlation matrix
fa_det = det(fa_cor$r)

# Print table using kable
  # make any NAs appear as blank within kable
  opts = options(knitr.kable.NA = "")
  # print table
  kable(fa_cor_t, caption = "Pearson Correlations between Items in the SAD", digits = 4, align = 'c', escape = FALSE) %>%
    kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
    add_footnote("p < .001", notation = "alphabet") %>% 
    kable_classic()
Pearson Correlations between Items in the SAD
SAD_1 SAD_2 SAD_3 SAD_4 SAD_5 SAD_6 SAD_7 SAD_8 SAD_9 SAD_10 SAD_11 SAD_12 SAD_13
SAD_1 1.0000
SAD_2 0.7150 1.0000
SAD_3 0.5510 0.6010 1.0000
SAD_4 0.5557 0.5727 0.5590 1.0000
SAD_5 0.4357 0.4525 0.4480 0.5249 1.0000
SAD_6 0.4319 0.4074 0.3767 0.4782 0.5365 1.0000
SAD_7 0.2763 0.3063 0.3081 0.3449 0.3988 0.4723 1.0000
SAD_8 0.3546 0.3545 0.2645 0.3889 0.3717 0.3974 0.2791 1.0000
SAD_9 0.3226 0.3906 0.3127 0.3677 0.3889 0.2831 0.3418 0.3733 1.0000
SAD_10 0.3179 0.3428 0.2598 0.3125 0.2708 0.3577 0.3329 0.5230 0.4381 1.0000
SAD_11 0.3826 0.4504 0.3758 0.3620 0.3148 0.3271 0.2721 0.3010 0.5575 0.5637 1.0000
SAD_12 0.2401 0.2302 0.2620 0.2470 0.2329 0.2569 0.2583 0.2986 0.2207 0.2341 0.2455 1.0000
SAD_13 0.1980 0.1390 0.2218 0.2138 0.2643 0.3167 0.2818 0.2200 0.1590 0.2070 0.1826 0.4701 1
a p < .001
    # restore the original options so that "NA" shows up again
    options(opts)
  • Another way to visualize this is using a Scatter Plot Matrix

    • This shows: (1) a scatter plot bellow the lower diagonal, with a line of best fit (red); (2) a historgram and density plot of the item on the diagonal; and (3) the correlation values (pearson r) above the diagonal, with corresponding significance shown with asterisks. The x-axis in each scatter plot represents the column variable and the y-axis the row variable.
# show a SPLOM (Scatter Plot Matrix) of the Data 
pairs.panels(fa_data, pch = ".", density = TRUE, ellipses = FALSE, lm = TRUE, digits = 2, method = "pearson", jiggle = TRUE, factor = 1, hist.col = "cadetblue3", stars = TRUE, gap = .5, verOdd = TRUE, horOdd = TRUE, main = "Scatter Plot Matrix of Items in the SAD")

3. Factorability of the Data
  • This assessed if there were meaningful latent factors to be found within the data, which was assessed in two ways: Barlett’s test of sphericity for correlation adequacy and the Kaiser-Meyer-Olkin measure of sampling adequacy.

    • Barlett’s test of sphericity for correlation adequacy:

      • This test was statistically significant, which suggested good factorability, \(\chi^{2}\)(78) = 1943.16, p < .001
    • Kaiser-Meyer-Olkin measure of sampling adequacy:

      • This measure showed an overall measure of sampling adequacy (MSA) and an MSA per item. The overall MSA was higher than both the minimum and preferred criteria (0.50 and 0.60, respectively; Kaiser, 1974, Hutcheson & Sofroniou, 1999), \(MSA_{overall}\) = 0.88. Each item’s MSA was also higher than the minimum and preferred criteria, \(MSA_{1-13}\) = 0.79 - 0.94.
  • Therefore, both factorability tests confirmed that the planned factor analysis was appropriate.

# run the Barlett Test
fa_bartest = cortest.bartlett(fa_data)
R was not square, finding R from data
fa_bartest
$chisq
[1] 1943.16

$p.value
[1] 0

$df
[1] 78
# run the KMO 
fa_kmo = KMO(fa_data)
fa_kmo
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = fa_data)
Overall MSA =  0.88
MSA for each item = 
 SAD_1  SAD_2  SAD_3  SAD_4  SAD_5  SAD_6  SAD_7  SAD_8  SAD_9 SAD_10 SAD_11 SAD_12 SAD_13 
  0.88   0.87   0.92   0.94   0.92   0.90   0.90   0.86   0.88   0.82   0.83   0.83   0.79 

Extract Factors

Now that factorability was confirmed, we found the appropriate number of factors to extract. This was done using: (1) a parallel analysis scree plot, (2) eigen values (i.e., from the parallel analysis), and (3) the factor structure between the two solutions (i.e., using factor diagrams).

1. Parallel Analysis Scree Plot.

This plotted the eigenvalues from the data and a parallel analysis which generated random correlation matrices. The number of factors is then determined by comparing the resulting eigenvalues to the observed data, that is, observed eigenvalues that were higher than the corresponding random eigenvalues were more likely to form meaningful factors.

  • The parallel analysis scree plot showed that there are NA appropriate factors (i.e. using the principal components extraction method).

    • From closer inspection of the plot, the last factor was very close to the random eigenvalue cut-off line, therefore, the 2, 3, and 4 factor solutions were compared to determine the best fit (i.e., the eigen values and factor structures were examined).

fa_par <- fa.parallel(fa_data, fa = "fa", main = "Parallel Analysis Scree Plot for Items in the SAD")
Parallel analysis suggests that the number of factors =  4  and the number of components =  NA 

2. Eigen Values

For a sample size greater than 250 (i.e., 383 complete cases) the average communalities (i.e., the proportion of common variance within the items) for the two factor (0.43) and three factor (0.49) solutions were wihtin the acceptable value (i.e., 0.60; Field et al., 2012). Therefore, Kaiser’s criterion (i.e., a meaningful factor has an eigen value greater than 1) was used for the eigen values. It should be noted that although the average communalities were not very high, the scree plot and factor diagrams were used to choose the appropriate number of factors.

  • The eigen values (unrotated solution) showed three meaningful factors (i.e., 5.34, 1.3, 1.2), which supported the three-factor solution as a better representation of the data.
# Eigen values
  # view eigen values from the parallel analysis scree plot
  round(fa_par$pc.values, 3)
 [1] 5.340 1.303 1.196 0.903 0.763 0.611 0.566 0.479 0.472 0.416 0.377 0.306 0.268
3. Factor Diagrams

A factor diagram for the two-, three-, and four-factor solutions (rotated solution) was used to determine which solution represents the most interpretable solution. The diagrams show the factor loadings for each item on the given factor for which they load the highest on. The items were ordered (i.e., descending) based on these loadings.
Note: The factor diagrams are based on the rotated solutions to better distribute the factor loadings

  • The factor diagrams showed that the two factor solution resulted in most items loading onto only one factor and was not easily interpreted. The four-factor solution showed a 2-item factor, which is not easily interpretable as it did not meet the 3-item minumum (Costello & Osborn, 2005). The three and four factor solutions showed better distributions and were more interpretable. After reviewing the items, the four-factor solution provided a logical structure compared to the three-factor solution. That is, the third factor in the 3-factor solution grouped items 6 & 7 with 12 & 13, however items 6 & 7 ask about emotional associations whereas items 12 & 13 are regarding attention. Although the fourth factor in the four-factor solution only contained 2 items, these items were considered unique in that they are the only items in the SAD which asked participants about attention with respect to their smartphone. Therefore, the four-factor solution was chosen.

Therefore, the three factor solution was chosen to better represent the data.

##-- VARIMAX ROTATION  -- 
# run a factor analysis to compare the two- and three-factor solutions (no rotation)
  # 2 factor solution
  fa_two_v = fa(fa_data, nfactors = 2, fm = "pa", rotate = "varimax", scores = T)
    # change name in loadings for clarity when visualizing the model
    colnames(fa_two_v$loadings) = c("Factor 1", "Factor 2")
  
  # 3 factor solution
  fa_three_v = fa(fa_data, nfactors = 3, fm = "pa", rotate = "varimax", scores = T)
    # change name in loadings for clarity when visualizing the model
    colnames(fa_three_v$loadings) = c("Factor 1", "Factor 2", "Factor 3")
  
  # 4 factor solution
  fa_four_v = fa(fa_data, nfactors = 4, fm = "pa", rotate = "varimax", scores = T)
    # change name in loadings for clarity when visualizing the model
    colnames(fa_four_v$loadings) = c("Factor 1", "Factor 2", "Factor 3", "Factor 4")

# Factor Diagram
  # 2 factor solution
  fa.diagram(fa_two_v, main = "Two Factor Solution for items in the SAD (Varimax Rotation)", sort = TRUE, adj = 1, digits = 2)


  # 3 factor solution
  fa.diagram(fa_three_v, main = "Three Factor Solution for Items in the SAD (Varimax Rotation)", sort = TRUE, adj = 1, digits = 2)

  
  # 4 factor solution
  fa.diagram(fa_four_v, main = "Three Factor Solution for Items in the SAD (Varimax Rotation)", sort = TRUE, adj = 1, digits = 2)

Achieving Simple Structure

Now that we determined the number of factors (i.e., four), we assessed for simple structure (i.e., a final solution of the factor analysis with the simplest solution). Simple structure was achieved by reviewing assessing the loadings for strong loadings (i.e., using a cut-off of > .40) and removing: (1) split variables (i.e., variables that loaded onto more than one factor), (2) non-loading variables, and (3) weak factors (i.e., factor with only 1 variable). Factor loadings are the correlations between each variable and the factor, that is, they represent the relationship (i.e., positive or negative) and strength (i.e., strong, moderate, or weak) between the variable and the factor.

First Solution: 13 SAD Items

First, we looked at the rotated factor loadings (i.e., varimax) for all 13 items in the SAD for the three-factor solution. The loadings are shown with a cut-off of 0.40 and rounded to three decimal places.

    1. Split variables: Item #4 loaded strongly onto factor 1 (0.58) and factor 3 (0.41).
    1. Non-Loading Variables: All items loaded onto at least one factor.
    1. Weak Factors: All factors had at least 2 variables loading strongly, which was discussed earlier.
  • Therefore, since item #46 was split between factor 1 and factor 3, it was removed from the analysis. This new solution was assessed with the same criteria to see if simple structure could be achieved.

# Rotated (i.e., varimax) Factor Loadings 
print(fa_four_v$loadings, cutoff = 0.40, digits = 3)

Loadings:
       Factor 1 Factor 2 Factor 3 Factor 4
SAD_1  0.721                              
SAD_2  0.800                              
SAD_3  0.646                              
SAD_4  0.580             0.405            
SAD_5                    0.567            
SAD_6                    0.650            
SAD_7                    0.469            
SAD_8           0.431                     
SAD_9           0.572                     
SAD_10          0.733                     
SAD_11          0.677                     
SAD_12                            0.659   
SAD_13                            0.647   

               Factor 1 Factor 2 Factor 3 Factor 4
SS loadings       2.399    1.887    1.516    1.094
Proportion Var    0.185    0.145    0.117    0.084
Cumulative Var    0.185    0.330    0.446    0.530
# make data frame to show values
fa_load_v <- as.data.frame(fa_four_v$loadings[1:13,])
Second Solution: 12 SAD Items (removed item 4)

Now, we removed item #4 and looked at the rotated factor loadings (i.e., varimax) for the remaining 12 items in the SAD for the four-factor solution. The loadings are shown with a cut-off of 0.40 and rounded to three decimal places.

    1. Split variables: No items loaded strongly onto more than one factor.
    1. Non-Loading Variables: All items loaded onto at least one factor.
    1. Weak Factors: All factors had at least 2 items loading strongly.
  • Therefore, simple structure was achieved and this final solution was used for further analysis.
# create data set without item # 6
fa_data2 <- 
  fa_data %>% 
  select(-SAD_4)

# run FA with 4 factors and a varimax rotation
  # rotated (varimax)
  fa_four_v2 <- fa(fa_data2, nfactors = 4, fm = "pa", rotate = "varimax", scores = T) 
  # change name in loadings for clarity when visualizing the model
    colnames(fa_four_v2$loadings) = c("Factor 1", "Factor 2", "Factor 3", "Factor 4")

# Rotated (i.e., varimax) Factor Loadings 
print(fa_four_v2$loadings, cutoff = 0.40, digits = 3)

Loadings:
       Factor 1 Factor 2 Factor 3 Factor 4
SAD_1  0.715                              
SAD_2  0.822                              
SAD_3  0.613                              
SAD_5                    0.557            
SAD_6                    0.684            
SAD_7                    0.480            
SAD_8           0.437                     
SAD_9           0.578                     
SAD_10          0.733                     
SAD_11          0.675                     
SAD_12                            0.674   
SAD_13                            0.631   

               Factor 1 Factor 2 Factor 3 Factor 4
SS loadings       2.001    1.858    1.421    1.076
Proportion Var    0.167    0.155    0.118    0.090
Cumulative Var    0.167    0.322    0.440    0.530
# make data frame to show values
fa_load_v2 <- as.data.frame(fa_four_v2$loadings[1:12,])

Describing the Final Solution

Now that we have acheived simple structure, we looked at the (1) Communalities, (2) Variance Accounted for in percentage, and (3) Factor Loadings. This was done using the final solution (i.e., four-factor, varimax rotation, excluding item #4).

(1) Communalities

First. we observed the communalities. Each item’s communality was the percentage of variance that was explained by the retained factors for each item. These ranged from 36.12% to 79.25%, with an average of 52.97 (see table for more details).

# get the communalities from the model
fa_com = as.data.frame(fa_four_v2$communality)
  
# create matrix to present communalities in a table
fa_com_t = rbind((fa_com[,1])*100)
  # rename row and column names
  colnames(fa_com_t) = rownames(fa_com)
  rownames(fa_com_t) = NULL

# Print table using kable
  # print table
  kable(fa_com_t, caption = "Communalities for the Three-Factor Solution for Items in the SAD (%)", digits = 4, align = 'c', escape = FALSE) %>%
    kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
    add_footnote("Communalities show the percentage of variance explained by each factor for each item on the SAD.", notation = "alphabet") %>% 
    kable_classic()
Communalities for the Three-Factor Solution for Items in the SAD (%)
SAD_1 SAD_2 SAD_3 SAD_5 SAD_6 SAD_7 SAD_8 SAD_9 SAD_10 SAD_11 SAD_12 SAD_13
62.9032 79.2493 49.7133 50.4155 61.0745 36.1421 36.116 43.8967 61.0182 56.9063 51.6665 46.5197
a Communalities show the percentage of variance explained by each factor for each item on the SAD.
(2) Variance Accounted (%)

Next, we looked at the percentage of variance accounted for by using the eigenvalues (compute the variance associated with the factors). This was done for both the unrotated and rotated (i.e., varimax) final four-factor solution. As you can see in the table below, a total of 52.97% of variance was accounted for by the three extracted factors (the same before and after rotation). This variance was mostly accounted for by factor one in the unrotated solution (factor 1 = 36.65%; factor 2 = 6.86%; factor 3 = 5.9%), but was more equally distributed after rotation (factor 1 = 16.68%; factor 2 = 15.48%; factor 3 = 11.84%; see table for more details).


# Run an unrotated three-factor solution
  fa_four2 <- fa(fa_data2, nfactors = 4, fm = "pa", rotate = "none", scores = T) 
    # change name in loadings for clarity when visualizing the model
    colnames(fa_four2$loadings) = c("Factor 1", "Factor 2", "Factor 3", "Factor 4") 
    
  
# To find the variance accounted for, you can either (1) calculate it from the eigen values for each factor, or (2) grab the calculated values from the model 
  # Both are shown below, but one is commented out to avoid creating excess variables
  # (1) Calculated 
    # For the unrotated solution
    #var_per = 100*fa_four2$values[1:3]/length(fa_four2$values)
    
    # For the rotated solution
    #var_per_v = 100*(as.numeric(fa_four_v2$Vaccounted[1,]))/length(fa_four_v2$values)
      
  # (2) The information is found in the "Vaccounted" table from the output, where "SS loadings" (row 1) shows the eigen values and "Proportion Var" (row 2) shows the variance accounted for.
    # For the unrotated solution
    var_per = 100*as.numeric(fa_four2$Vaccounted[2,])
    
    # For the rotated solution
    var_per_v = 100*as.numeric(fa_four_v2$Vaccounted[2,])

# Create & Show a table with eigen values, percent var explained, and total percent var explained for unrotated & rotated three-factor solutions
    # unrotated solution
    var_per_t = as.data.frame(cbind(rbind(as.numeric(fa_four2$Vaccounted[1,]), var_per), 
                                    rbind(as.numeric(fa_four_v2$Vaccounted[1,]), var_per_v)))
    # name the columns & rows accordingly
    colnames(var_per_t) = c(rep(c("Factor 1", "Factor 2", "Factor 3", "Factor 4"),2))
    rownames(var_per_t) = c("Eigen Values", "Variance Explained (%)")

  # use kable to show the table
  kable(var_per_t, caption = "Eigen Values and Percent of Variance Explained for the Unrotated and Rotated (varimax) for the Three-Factor Solution for Items in the SAD", digits = 4, align = 'c') %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = T) %>%
  add_header_above(c(" ", "Unrotated" = 4, "Varimax Rotation" = 4)) %>%
    kable_classic()
Eigen Values and Percent of Variance Explained for the Unrotated and Rotated (varimax) for the Three-Factor Solution for Items in the SAD
Unrotated
Varimax Rotation
Factor 1 Factor 2 Factor 3 Factor 4 Factor 1 Factor 2 Factor 3 Factor 4
Eigen Values 4.3977 0.8230 0.7082 0.4274 2.0014 1.8580 1.4209 1.0759
Variance Explained (%) 36.6472 6.8581 5.9014 3.5618 16.6784 15.4836 11.8406 8.9658
NA
(3) Factor Loadings

Lastly, we looked at the factor loadings of the final four-factor solution. Below you can see the rotated (i.e., varimax) and unrotated factor loadings. The loadings are shown with a cut-off of 0.40 and rounded to three decimal places. The unrotated factor loadings are difficult to interpret: all items loaded strongly onto factor 1 (i.e., loading was greater than 0.40). The rotated factor loadings were more easy to interpret (see below for more details).


# Unrotated Factor Loadings 
print(fa_four2$loadings, cutoff = 0.40, digits = 3)

Loadings:
       Factor 1 Factor 2 Factor 3 Factor 4
SAD_1   0.694                             
SAD_2   0.746   -0.455                    
SAD_3   0.634                             
SAD_5   0.645                             
SAD_6   0.661                             
SAD_7   0.534                             
SAD_8   0.567                             
SAD_9   0.590                             
SAD_10  0.616            -0.444           
SAD_11  0.636                             
SAD_12  0.451                             
SAD_13  0.404    0.441                    

               Factor 1 Factor 2 Factor 3 Factor 4
SS loadings       4.398    0.823    0.708    0.427
Proportion Var    0.366    0.069    0.059    0.036
Cumulative Var    0.366    0.435    0.494    0.530
# Rotated (i.e., varimax) Factor Loadings 
print(fa_four_v2$loadings, cutoff = 0.40, digits = 3)

Loadings:
       Factor 1 Factor 2 Factor 3 Factor 4
SAD_1  0.715                              
SAD_2  0.822                              
SAD_3  0.613                              
SAD_5                    0.557            
SAD_6                    0.684            
SAD_7                    0.480            
SAD_8           0.437                     
SAD_9           0.578                     
SAD_10          0.733                     
SAD_11          0.675                     
SAD_12                            0.674   
SAD_13                            0.631   

               Factor 1 Factor 2 Factor 3 Factor 4
SS loadings       2.001    1.858    1.421    1.076
Proportion Var    0.167    0.155    0.118    0.090
Cumulative Var    0.167    0.322    0.440    0.530

Reliability Analyses

In order to validate the SAD, we completed a reliability analysis (i.e., is the scale consistent) by looking at the split-half reliability using Cronbach’s alpha. This method is the most common measure of scale reliability (Field et al., 2012): the data for each participant is randomly split into two sets, which forms a “half” split for the scale. Then, a correlation is calculated between these sets to determine how similar they are: higher reliability would be seen with highly correlated sets. Since the way that the data is split can impact the correlations, Cronbach’s alpha represents an average of all the possible splits using the following equation:

\[\alpha = \frac{N^2 \overline{Cov}}{\sum s_{item}^2 + \sum Cov_{item}} \]

To obtain the best reliability measure, we must divide our data into any subscales, which in this case, are our three factors from our factor analysis. Therefore, we split the data into three sets for the reliability analysis. (click to see code)


# split the data respective to the 3 factors from the FA to perform the reliability analysis
  # factor 1 (items: 1, 2, 3)
  f1_data = fa_data2 %>% select(SAD_1:SAD_3)
  # factor 2 (items: 8, 9, 10, 11)
  f2_data = fa_data2 %>% select(SAD_8:SAD_11)
  # factor 3 (items: 5, 6, 7)
  f3_data = fa_data2 %>% select(SAD_5:SAD_7)
  # factor 4 (items: 12, 13)
  f4_data = fa_data2 %>% select(SAD_12, SAD_13)

Once we have our subscales, we completed the reliability analysis on each subscale. (click to see code)


# compute reliability analysis for each subscale using "alpha()" function in "psych" package
  # factor 1
  f1_rel = psych::alpha(f1_data)
  # factor 2
  f2_rel = psych::alpha(f2_data)
  # factor 3
  f3_rel = psych::alpha(f3_data)
  # factor 4
  f4_rel = psych::alpha(f4_data)

To view the analysis, we broke it down into three components: (1) the alpha values and overall mean and standard deviation of the subscales, (2) alpha drop values (i.e., the alpha values if an item was dropped, and (3) the item statistics.

(1) Alpha Values

The alpha values from the reliability analyses included Cronbach’s \(\alpha\) (i.e., based on the covariances), a standardized \(\alpha\) (i.e., based on the correlations), and Guttman’s Lambda 6. Additionally, the overall average correlation, mean, and standard deviation for the subscale is shown (see table below for more details).

  • As seen in the table, Cronbach’s \(\alpha\) was within the acceptable range (i.e., greater than .70; Kline, 1999) for Factor 1 (\(\alpha_C\) = 0.83), Factor 2 (\(\alpha_C\) = 0.76), and Factor 3 (\(\alpha_C\) = 0.72), but not for Factor 4 (\(\alpha_C\) = 0.63). The overall correlation for Factor 1, r(381) 0.62, was strong. Factor 2, r(381) 0.46, Factor 3, r(381) 0.47, and Factor 4, r(381) 0.47, were moderate. All correlations were positive. These statistics were further explored with dropped items.
# show the alpha values from the 3 subscales
  # create data frame with the information from the 3 reliability analyses
  fa_rel_alphas = as.data.frame(rbind("Factor 1" = dplyr::select(f1_rel$total, -c("S/N", "ase", "median_r")), 
                                      "Factor 2" = dplyr::select(f2_rel$total, -c("S/N", "ase", "median_r")), 
                                      "Factor 3" = dplyr::select(f3_rel$total, -c("S/N", "ase", "median_r")),
                                      "Factor 4" = dplyr::select(f4_rel$total, -c("S/N", "ase", "median_r")))
                                )
  # add an extra column for the "overall" or average alpha
  fa_rel_alphas = cbind("Overall alpha" = c(mean(as.numeric(dplyr::select(f1_rel$total, c("raw_alpha", "std.alpha")))), 
                                            mean(as.numeric(dplyr::select(f2_rel$total, c("raw_alpha", "std.alpha")))), 
                                            mean(as.numeric(dplyr::select(f3_rel$total, c("raw_alpha", "std.alpha")))),
                                            mean(as.numeric(dplyr::select(f4_rel$total, c("raw_alpha", "std.alpha"))))),
                        fa_rel_alphas)

  # use kable to show the table
  kable(fa_rel_alphas, caption = "Reliability Analysis for Subscales in the SAD: Alpha Values", digits = 4, align = 'c', 
        col.names = c("Overall alpha", "Cronbach's alpha", "Standardized alpha", "Guttman's lambda 6", "Average r", "M", "SD")) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = T) %>% 
    kable_classic()
Reliability Analysis for Subscales in the SAD: Alpha Values
Overall alpha Cronbach's alpha Standardized alpha Guttman's lambda 6 Average r M SD
Factor 1 0.8309 0.8301 0.8317 0.7770 0.6223 4.2106 1.5762
Factor 2 0.7676 0.7624 0.7727 0.7438 0.4594 4.1821 1.2273
Factor 3 0.7217 0.7173 0.7261 0.6449 0.4692 5.0035 1.2294
Factor 4 0.6327 0.6259 0.6395 0.4701 0.4701 4.9883 1.3515
NA
(2) Alpha Drop Values

To further explore the reliability of each subscale, we looked at the alpha values after removing each item. This allowed us to determine whether a given item was reducing the reliability of the subscale. That is, if dropping an item increased \(\alpha\) or the correlation, then removing the item from the analysis should be considered. The data presented in the table below shows Cronbach’s \(\alpha\), standardized \(\alpha\), Guttman’s Lambda 6, and the average correlation.

  • As seen in the table below, dropping an item did not improve reliability for Factor 1 (range of \(\alpha_C\) = 0.71 - 0.83), Factor 2 (range of \(\alpha_C\) = 0.66 - 0.75), Factor 3 (range of \(\alpha_C\) = 0.54 - 0.7), and Factor 4 (range of \(\alpha_C\) = 0.37 - 0.61).
  • With respect to the average correlation, dropping an item only showed a substantially improvement for Factor 1, where dropping item 3 resulted in a stronger correlation, r(381) = 0.72. This was explored further with the items statistics.
# show the alpha drop values from the 3 subscales
  # create data frame with the information
  fa_rel_adrop = as.data.frame(rbind(dplyr::select(f1_rel$alpha.drop, c("raw_alpha", "std.alpha", "G6(smc)", "average_r")), 
                                     dplyr::select(f2_rel$alpha.drop, c("raw_alpha", "std.alpha", "G6(smc)", "average_r")), 
                                     dplyr::select(f3_rel$alpha.drop, c("raw_alpha", "std.alpha", "G6(smc)", "average_r")), 
                                     dplyr::select(f4_rel$alpha.drop, c("raw_alpha", "std.alpha", "G6(smc)", "average_r"))
                                     ))

  # use kable to show the table
  kable(fa_rel_adrop, caption = "Reliability Analysis for Subscales in the SAD: Alpha Drop Values", digits = 4, align = 'c', 
        col.names = c("Cronbach's alpha", "Standardized alpha", "Guttman's lambda 6", "Average r")) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = T) %>%
  pack_rows(index = c("Factor 1" = ncol(f1_data), "Factor 2" = ncol(f2_data), "Factor 3" = ncol(f3_data), "Factor 4" = ncol(f4_data))) %>% 
    kable_classic()
Reliability Analysis for Subscales in the SAD: Alpha Drop Values
Cronbach's alpha Standardized alpha Guttman's lambda 6 Average r
Factor 1
SAD_1 0.7506 0.7508 0.6010 0.6010
SAD_2 0.7085 0.7105 0.5510 0.5510
SAD_3 0.8329 0.8338 0.7150 0.7150
Factor 2
SAD_8 0.7543 0.7645 0.6912 0.5198
SAD_9 0.7098 0.7208 0.6617 0.4626
SAD_10 0.6648 0.6764 0.6028 0.4106
SAD_11 0.6987 0.7062 0.6228 0.4448
Factor 3
SAD_5 0.6151 0.6416 0.4723 0.4723
SAD_6 0.5389 0.5702 0.3988 0.3988
SAD_7 0.6978 0.6983 0.5365 0.5365
Factor 4
SAD_12 0.6050 0.4701 0.2210 0.4701
SAD_13 0.3652 0.4701 0.2210 0.4701
NA
(3) Item Statistics

The item statistics were explored to determine whether a certain item did not correlate with the overall subscale. The table below shows: r, which is the correlations between each item and the total score from the subscale (i.e., the item-total correlations), which includes the item itself; and Drop, which is the correlation of an item with the subscale after removing the item (i.e., the item-rest correlation or the corrected item-total correlation). Additionally, the sample size, mean, and standard deviation is shown.

  • No issues were found with the item statistics for Factor 1, r(381) = .62 - = .74, Factor 2, r(381) = .49 - = .65, Factor 3, r(381) = .5 - = .61, and Factor 4, r(381) = .47 - = .47. That is, no items had a item-rest correlation (i.e., the drop column in the table below) below the cut-off (i.e., .30; Field et al., 2012).

# show the correlations for the 3 subscales
  # create data frame with the information
  fa_rel_item = as.data.frame(rbind(dplyr::select(f1_rel$item.stats, -c("std.r", "r.cor")), 
                                    dplyr::select(f2_rel$item.stats, -c("std.r", "r.cor")), 
                                    dplyr::select(f3_rel$item.stats, -c("std.r", "r.cor")),
                                    dplyr::select(f4_rel$item.stats, -c("std.r", "r.cor"))
                                    ))

  # use kable to show the table
  kable(fa_rel_item, caption = "Reliability Analysis for Subscales in the SAD: Item Statistics", digits = 4, align = 'c', 
        col.names = c("N", "r", "Drop", "M", "SD")) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = T) %>%
  pack_rows(index = c("Factor 1" = ncol(f1_data), "Factor 2" = ncol(f2_data), "Factor 3" = ncol(f3_data), "Factor 4" = ncol(f4_data)))  %>% 
    kable_classic()
Reliability Analysis for Subscales in the SAD: Item Statistics
N r Drop M SD
Factor 1
SAD_1 383 0.8654 0.7061 4.7415 1.7301
SAD_2 383 0.8922 0.7440 4.1018 1.8412
SAD_3 383 0.8370 0.6228 3.7885 1.8978
Factor 2
SAD_8 383 0.7386 0.4857 3.3420 1.7872
SAD_9 383 0.7804 0.5595 4.0209 1.7589
SAD_10 383 0.8045 0.6466 4.7337 1.4783
SAD_11 383 0.7559 0.5905 4.6319 1.3586
Factor 3
SAD_5 383 0.8366 0.5560 4.6188 1.7338
SAD_6 383 0.8499 0.6056 4.6319 1.6556
SAD_7 383 0.7146 0.4959 5.7598 1.1621
Factor 4
SAD_12 383 0.8936 0.4701 4.7050 1.7692
SAD_13 383 0.8162 0.4701 5.2715 1.3746
NA

Overall, the reliability for Factor 1, Factor 2, Factor 3, and Factor 4 was adequate. Although Factor 1 showed mixed results for item 3 (i.e., item was not as stable for alpha), Factor 1 was stable for all other comparisons/measures, therefore item 3 was not removed from the subscale. Similarly, Factor 4 was inspected carefully since it was a two-tem factor. These results suggets that it is a stable factor and so it was included in further analyses.

Conclusions

The Present Study

A principal axis factor analysis was used to analyze the underlying factors in the 13-item SAD inventory (Ward et al., 2017) using an orthogonal rotation (i.e., varimax rotation). Factorability of the data was confirmed using: (1) Bartlett’s test for correlation adequacy, \(\chi^{2}\)(78) = 1943.16, p < .001, which confirmed that correlations between the items were sufficiently large; and (2) the Kaiser-Meyer-Olkin measure for sampling adequacy (MSA), \(MSA_{overall}\) = 0.88, \(MSA_{1-13}\) = 0.79 - 0.94, which confirmed that both the overall MSA and each item’s MSA were above their required criteria (0.60 and 0.77, respectively; Kaiser, 1974). The appropriate number of factors (i.e., four) was confirmed using (1) a parallel analysis scree plot, where the two- , three-, and four-factor solutions were chosen to compare for the best fit for the data; (2) the eigen values (e.g., 5.34, 1.303, 1.196, 0.903, for factors 1 to 4, respectively) for the unrotated solution, where three meaningful factors were found using Kaiser’s criterion (i.e., eigen values greater than one); and (3) the factor structure of the two-, three-, and four-factor solutions, where the four-factor solution showed a better distribution of the data and was more interpretable. Therefore, the four-factor solution was chosen for the final analysis and an orthogonal (i.e., varimax) rotation was chosen for the final analysis. After an initial four-factor solution was completed using all 13 items in the SAD, however, item 4 was split-loaded (i.e., between factor 1 and 3). Therefore, this item was dropped and a final four-factor solution was completed with the remaining 12 items in the SAD. This final solution achieved simple structure and was used for subsequent analyses.

The for each reliability of the four factors was assessed using Cronbach’s \(\alpha\), which was within the acceptable range (i.e., greater than .70; Kline, 1999) for Factor 1 (\(\alpha_C\) = 0.83), Factor 2 (\(\alpha_C\) = 0.76), and Factor 3 (\(\alpha_C\) = 0.72), but not for Factor 4 (\(\alpha_C\) = 0.63). Therefore, the reliability for Factor 1, Factor 2, and Factor 3 was adequate. Factor 1 did show a less stable item (i.e., 3), which showed a small improvement in correlation when dropped (from 0.62 to 0.72 ). Factor 4 was a weaker factor with only two items. Overall, the four factors all showed reliability and stability. Each was used as a separate subscale for following analyses. The mean scores for each factor were: Factor 1 M = 12.63 (SD = 4.73), Factor 2 M = 16.73 (SD = 4.91), Factor 3 M = 9.98 (SD = 2.7), and Factor 4 M = 6.25 (SD = 1.03). The model also showed a moderate fit: the Root Mean Square of the Residual (RMSR; 0.03). Further descriptive statistics can be found in the Descriptive Statistics section above.

The items in the final solution’s factors explained 52.97% of the variance and suggested the following four factors: dependence, emotional attachment, accessibility, and distractibility. Dependence was relate to the degree of dependence on one’s smartphone, it consisted of 3 items (i.e., SAD 1, SAD 2, and SAD 3) and explained 16.68% of the variance (e.g., “I would have trouble getting through a normal day without my smartphone.”, and “I feel like I could not live without my smartphone.”). Emotional attachment was related to one’s smartphone use for emotional support, it consisted of 4 items (i.e, SAD 8, 9, 10, and 11) and explained 15.48% of the variance (e.g., “I feel lonely when my smartphone does not ring or vibrate for several hours.”, and “Using my smartphone makes me feel happy.”). Accessibility was related to the ability to acees the utility of one’s phone (e.g., powered on, internet access), it consisted of 3 items (i.e., SAD 5, 6, & 7) and explained 11.84% of the variance (e.g., “It drives me crazy when my smartphone runs out of battery.”, and “I feel impatient when the Internet connection speed on my smartphone is slow.”). Distractibility was related to one’s smartphone retaining one’s attention, it consisted of 2 items and explained 8.97% of the variance (e.g., “I find it tough to focus whenever my smartphone is nearby.”, and “I become less attentive to my surroundings when I’m using my smartphone.”). One item did not clearly load onto any one factor and was excluded from further analyses (i.e., item 4; Costello & Osborne, 2005). The tables below depict the final and initial (i.e., including item 4) four-factor solutions. three

# create table with all items, factor loadings, eigen values, % of variance explained, and Cronbach's alpha 

# get factor loadings
  fa_load <- as.data.frame(fa_four_v2$loadings[1:12,])
  # change row names
    # row.names(fa_load) <- c(1:nrow(fa_load))
    
  # reorder loadings to match final table
    fa_load <- 
      fa_load %>%
      # add temporary column used to reorder
      mutate(item = c(row.names(fa_four_v2$loadings[1:12,]))) %>% 
      # reorder using slice & match
      slice(match(c("SAD_1", "SAD_2", "SAD_3", "SAD_8", "SAD_9", "SAD_10", "SAD_11", "SAD_5", "SAD_6", "SAD_7", "SAD_12", "SAD_13"), item)) %>% 
      # remove temp column
      select(-item)

# make list of the items & other info
  fa_table_list <- c("I would have trouble getting through a normal day without my smartphone.",
                    "It would be painful for me to give up my smartphone for a day.",
                    "I feel like I could not live without my smartphone.",
                    "I feel lonely when my smartphone does not ring or vibrate for several hours.",
                    "Using my smartphone relieves me of my stress.",
                    "I feel excited when I have a new message or notification.",
                    "Using my smartphone makes me feel happy.",
                    "It drives me crazy when my smartphone runs out of battery.",
                    "I am upset and annoyed when I find I do not have reception on my smartphone.",
                    "I feel impatient when the Internet connection speed on my smartphone is slow.",
                    "I find it tough to focus whenever my smartphone is nearby.",
                    "I become less attentive to my surroundings when I’m using my smartphone.",
                    "Eigen Values", 
                    "Variance Explained (%)")
  
# create the final table
  # bind the loadings and items
    fa_four_t = cbind(c(1:3, 8:11, 5:7, 12, 13, "", ""), fa_table_list, rbind(fa_load, var_per_t[5:8]))
    
    # rename columns & rows
      colnames(fa_four_t) = c("item_num", "item_desc", "f1", "f2", "f3", "f4")
      rownames(fa_four_t) = 1:nrow(fa_four_t)
      
# format cells
# fa_four_t$f1 <- cell_spec(fa_four_t$f1, bold = ifelse(fa_four_t$f1 > 0.40, T, F))
      
# use kable to show the table
table_fa_four_t <- 
kable(fa_four_t, caption = "Final Solution: Summary of exploratory varimax rotated factor analysis results for the 13-Items in the SAD", 
      digits = 2, align = "llcccc", col.names = c("", "", "1", "2", "3", "4")) %>%
    kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
    add_header_above(c(" ", " ", "Factor Loading" = 4), bold = T) %>% 
    pack_rows("Factor 1: Dependence", 1, 3) %>% 
    pack_rows("Factor 2: Emotional Attachment", 4, 7) %>% 
    pack_rows("Factor 3: Accessibility", 8, 10) %>% 
    pack_rows("Factor 4: Distractibility", 11, 12) %>% 
    pack_rows("", 13, 14) %>% 
    footnote(general = "Values represent rotated factor loadings from items in the Smartphone Attachment and Dependency Inventory (Ward et al., 2017).
             Factor loadings have been sorted based on strong loading (> 0.40). Item #4 was split-loaded and removed from the final solution.", 
             symbol = c("N = 383")) %>% 
    kable_classic()

# show table
table_fa_four_t
Final Solution: Summary of exploratory varimax rotated factor analysis results for the 13-Items in the SAD
Factor Loading
1 2 3 4
Factor 1: Dependence
1 I would have trouble getting through a normal day without my smartphone. 0.72 0.21 0.24 0.12
2 It would be painful for me to give up my smartphone for a day. 0.82 0.28 0.19 0.05
3 I feel like I could not live without my smartphone. 0.61 0.18 0.24 0.17
Factor 2: Emotional Attachment
8 I feel lonely when my smartphone does not ring or vibrate for several hours. 0.18 0.44 0.32 0.19
9 Using my smartphone relieves me of my stress. 0.24 0.58 0.20 0.09
10 I feel excited when I have a new message or notification. 0.10 0.73 0.21 0.13
11 Using my smartphone makes me feel happy. 0.30 0.67 0.09 0.11
Factor 3: Accessibility
5 It drives me crazy when my smartphone runs out of battery. 0.37 0.20 0.56 0.14
6 I am upset and annoyed when I find I do not have reception on my smartphone. 0.26 0.21 0.68 0.19
7 I feel impatient when the Internet connection speed on my smartphone is slow. 0.15 0.25 0.48 0.21
Factor 4: Distractibility
12 I find it tough to focus whenever my smartphone is nearby. 0.15 0.18 0.09 0.67
13 I become less attentive to my surroundings when I’m using my smartphone. 0.06 0.08 0.24 0.63
Eigen Values 2.00 1.86 1.42 1.08
Variance Explained (%) 16.68 15.48 11.84 8.97
Note:
Values represent rotated factor loadings from items in the Smartphone Attachment and Dependency Inventory (Ward et al., 2017).
Factor loadings have been sorted based on strong loading (> 0.40). Item #4 was split-loaded and removed from the final solution.
* N = 383

#export table
#install PhantomJS using: "webshot::install_phantomjs()"
# save_kable(table_fa_four_t, "table_fa_four_t.pdf")



## INITIAL SOLUTION -- for reference not the final solution

# use initial rotated 4-factor solution from above -- "fa_four_v"
    
# To find the eigenvalues & variance accounted for, you can either grab the calculated values from the model 
    # For the initial 4-factor solution
    var_ev_per_in <- data.frame(rbind(fa_four_v$e.values[1:4],  #eigen values 
                       100*as.numeric(fa_four_v$Vaccounted[2,]) # variance accounted for, in percentage
                       ))
    colnames(var_ev_per_in) = c("Factor 1", "Factor 2", "Factor 3", "Factor 4")
    rownames(var_ev_per_in) = c("Eigen Values", "Variance Explained (%)")

# create table with all items, factor loadings, eigen values, % of variance explained, and Cronbach's alpha 

# get factor loadings
  fa_load_in = as.data.frame(fa_four_v$loadings[1:13,])

# make list of the items & other info
  fa_table_list_in = data.frame("details" = c("I would have trouble getting through a normal day without my smartphone.",
                                     "It would be painful for me to give up my smartphone for a day.",
                                     "I feel like I could not live without my smartphone.",
                                     "If I forgot to bring my smartphone with me, I would feel anxious.",
                                     "It drives me crazy when my smartphone runs out of battery.",
                                     "I am upset and annoyed when I find I do not have reception on my smartphone.",
                                     "I feel impatient when the Internet connection speed on my smartphone is slow.",
                                     "I feel lonely when my smartphone does not ring or vibrate for several hours.",
                                     "Using my smartphone relieves me of my stress.",
                                     "I feel excited when I have a new message or notification.",
                                     "Using my smartphone makes me feel happy.",
                                     "I find it tough to focus whenever my smartphone is nearby.",
                                     "I become less attentive to my surroundings when I’m using my smartphone.", 
                                     "Eigen Values", 
                                     "Variance Explained (%)"))
  
# create the final table
  # bind the loadings and items
    fa_four_t_in = cbind(fa_table_list_in, rbind(fa_load_in, var_ev_per_in))
    
    # rename columns & rows
      colnames(fa_four_t_in) = c("Item", "Factor 1", "Factor 2", "Factor 3", "Factor 4")
      rownames(fa_four_t_in) = c(1:13, "", " ")
      
# use kable to show the table
  kable(fa_four_t_in, caption = "First Solution: Summary of exploratory varimax rotated factor analysis results for the 13-Items in the SAD.", digits = 2, align = "lccc") %>%
    kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
    pack_rows("", 14, 15) %>% 
    footnote(general = "The initial solution is shown, including item #4, which was dropped as a split variable between factor 1 and factor 3.", symbol = "N = 383") %>% 
    kable_classic()
First Solution: Summary of exploratory varimax rotated factor analysis results for the 13-Items in the SAD.
Item Factor 1 Factor 2 Factor 3 Factor 4
1 I would have trouble getting through a normal day without my smartphone. 0.72 0.22 0.21 0.12
2 It would be painful for me to give up my smartphone for a day. 0.80 0.29 0.16 0.06
3 I feel like I could not live without my smartphone. 0.65 0.17 0.23 0.17
4 If I forgot to bring my smartphone with me, I would feel anxious. 0.58 0.21 0.41 0.12
5 It drives me crazy when my smartphone runs out of battery. 0.39 0.19 0.57 0.14
6 I am upset and annoyed when I find I do not have reception on my smartphone. 0.28 0.21 0.65 0.20
7 I feel impatient when the Internet connection speed on my smartphone is slow. 0.16 0.25 0.47 0.22
8 I feel lonely when my smartphone does not ring or vibrate for several hours. 0.19 0.43 0.33 0.19
9 Using my smartphone relieves me of my stress. 0.25 0.57 0.21 0.09
10 I feel excited when I have a new message or notification. 0.11 0.73 0.21 0.14
11 Using my smartphone makes me feel happy. 0.31 0.68 0.08 0.11
12 I find it tough to focus whenever my smartphone is nearby. 0.15 0.17 0.09 0.66
13 I become less attentive to my surroundings when I’m using my smartphone. 0.06 0.08 0.23 0.65
Eigen Values 5.34 1.30 1.20 0.90
Variance Explained (%) 18.45 14.52 11.66 8.41
Note:
The initial solution is shown, including item #4, which was dropped as a split variable between factor 1 and factor 3.
* N = 383
NA
Ward et al. (2017)

Ward et al. (2017) found two factors: smartphone dependence (i.e. six items; items #1-6; 31.02% of the variance) and emotional attachment (i.e. five items; items #8-11; 21.65% of the variance), which explained 52.67% of the total variance. Two items (i.e. item #7 and 13) were dropped from their subsequent analyses since they did not strongly load onto a factor (see Web Appendix Table 1 below).


Note: this table is from Ward et al. (2017) Web Appendix. Items are listed in order (i.e., 1-13). Only strongly-loaded values are shown.

Comparing Findings

The present study’s final factor solution showed some similarities with Ward et al.’s solution:

  • Factor 1 contained items # 1, 2, 3, 4, and 5
  • Factor 2 contained items # 8, 9, 10, and 11

Some differences between the solutions:

  • Only one item (i.e., item #4 due to split-loading) was dropped in the present study compared to the two items dropped in Ward et al. (i.e., items 7 due to split-loading to and 13 due to being in a weak, single-item factor).
  • Factor 3 did have more than one item load strongly (items 5, 6, 7) and was not dropped.
  • Four factors were in the final solution in the present study.

Overall, the analyses were very similar. We compared the total variances explained and found that both the initial (53.04%) and final (52.97%) solution in the present study explained more total variance than the Ward et al. (2017) solution (52.67%). Comparing the reliability tests showed that Ward et al.’s subscales (\(\alpha_{Factor1}\) = 0.89; \(\alpha_{Factor2}\) = 0.79) had slightly larger values than the resent study (\(\alpha_{Factor1}\) = 0.83; \(\alpha_{Factor2}\) = 0.76; \(\alpha_{Factor3}\) = 0.72; \(\alpha_{Factor4}\) = 0.63).

Correlations: SAD Subscales vs. OSpan

# set up the data & run correlation
SAD_corr <- 
  all_data %>% 
  select(ospan_absolute_score, gng_err_omi, gng_rt_av , SAD_score, SAD_dep_score, SAD_ea_score, SAD_access_score, SAD_dist_score, age) %>% 
  as.matrix() %>% 
  rcorr(type = "pearson")

# create new SAD_corr to shown only lower triangle... 
SAD_corr2 <- SAD_corr
# round to 4 decimals... 
SAD_corr2$r <- round(SAD_corr2$r, 4)
SAD_corr2$P <- round(SAD_corr2$P, 4)
SAD_corr2$n <- round(SAD_corr2$n, 4)
# remove upper triangle form r, p, and n
SAD_corr2$r[upper.tri(SAD_corr2$r)] <- "-"
SAD_corr2$P[upper.tri(SAD_corr2$P)] <- "-"
SAD_corr2$n[upper.tri(SAD_corr2$n)] <- "-"

# show corr table with flattenCorr

kable(flattenCorrMatrix(SAD_corr$r, SAD_corr$P), caption = "Correlations between SAD Score and Age with OSpan Performance") %>%
  footnote(general = "SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown. ") %>% 
  kable_styling(bootstrap_options = c("hover", "striped"), full_width = F) %>% 
  kable_classic()
Correlations between SAD Score and Age with OSpan Performance
row column cor p
ospan_absolute_score gng_err_omi -0.0804066 0.1161850
ospan_absolute_score gng_rt_av -0.0236680 0.6442656
gng_err_omi gng_rt_av 0.0749570 0.1431385
ospan_absolute_score SAD_score -0.0068892 0.8930979
gng_err_omi SAD_score -0.0969179 0.0580945
gng_rt_av SAD_score 0.0488313 0.3405428
ospan_absolute_score SAD_dep_score 0.0451542 0.3781849
gng_err_omi SAD_dep_score -0.0877913 0.0861970
gng_rt_av SAD_dep_score 0.0738880 0.1489460
SAD_score SAD_dep_score 0.8250672 0.0000000
ospan_absolute_score SAD_ea_score -0.0746627 0.1447200
gng_err_omi SAD_ea_score -0.0673728 0.1882756
gng_rt_av SAD_ea_score 0.0519168 0.3108716
SAD_score SAD_ea_score 0.8095738 0.0000000
SAD_dep_score SAD_ea_score 0.5135457 0.0000000
ospan_absolute_score SAD_access_score -0.0244905 0.6327969
gng_err_omi SAD_access_score -0.0457629 0.3717835
gng_rt_av SAD_access_score 0.0159967 0.7549969
SAD_score SAD_access_score 0.8055359 0.0000000
SAD_dep_score SAD_access_score 0.5607329 0.0000000
SAD_ea_score SAD_access_score 0.5338376 0.0000000
ospan_absolute_score SAD_dist_score 0.0422234 0.4099421
gng_err_omi SAD_dist_score -0.0890381 0.0818112
gng_rt_av SAD_dist_score 0.0118260 0.8175549
SAD_score SAD_dist_score 0.5604164 0.0000000
SAD_dep_score SAD_dist_score 0.2946769 0.0000000
SAD_ea_score SAD_dist_score 0.3406335 0.0000000
SAD_access_score SAD_dist_score 0.3810652 0.0000000
ospan_absolute_score age -0.0798192 0.1188839
gng_err_omi age -0.0698051 0.1727843
gng_rt_av age 0.0372320 0.4675230
SAD_score age -0.1713676 0.0007579
SAD_dep_score age -0.1407677 0.0057867
SAD_ea_score age -0.1580994 0.0019125
SAD_access_score age -0.1891536 0.0001966
SAD_dist_score age 0.0114289 0.8235785
Note:
SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown.

# print tables using kable
kable(as.data.frame(format(SAD_corr2$r, scientific = FALSE)), caption = "Correlations between SAD Score and Age with OSpan Performance: r values") %>%
  footnote(general = "SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown. ") %>% 
  kable_styling(bootstrap_options = c("hover", "striped"), full_width = F) %>% 
  kable_classic()
Correlations between SAD Score and Age with OSpan Performance: r values
ospan_absolute_score gng_err_omi gng_rt_av SAD_score SAD_dep_score SAD_ea_score SAD_access_score SAD_dist_score age
ospan_absolute_score 1 - - - - - - - -
gng_err_omi -0.0804 1 - - - - - - -
gng_rt_av -0.0237 0.075 1 - - - - - -
SAD_score -0.0069 -0.0969 0.0488 1 - - - - -
SAD_dep_score 0.0452 -0.0878 0.0739 0.8251 1 - - - -
SAD_ea_score -0.0747 -0.0674 0.0519 0.8096 0.5135 1 - - -
SAD_access_score -0.0245 -0.0458 0.016 0.8055 0.5607 0.5338 1 - -
SAD_dist_score 0.0422 -0.089 0.0118 0.5604 0.2947 0.3406 0.3811 1 -
age -0.0798 -0.0698 0.0372 -0.1714 -0.1408 -0.1581 -0.1892 0.0114 1
Note:
SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown.
  

kable(as.data.frame(format(SAD_corr2$P, scientific = FALSE)), caption = "Correlations between SAD Score and Age with OSpan Performance: p-values") %>%
  footnote(general = "SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown. ") %>% 
  kable_styling(bootstrap_options = c("hover", "striped"), full_width = F) %>% 
  kable_classic()
Correlations between SAD Score and Age with OSpan Performance: p-values
ospan_absolute_score gng_err_omi gng_rt_av SAD_score SAD_dep_score SAD_ea_score SAD_access_score SAD_dist_score age
ospan_absolute_score NA - - - - - - - -
gng_err_omi 0.1162 NA - - - - - - -
gng_rt_av 0.6443 0.1431 NA - - - - - -
SAD_score 0.8931 0.0581 0.3405 NA - - - - -
SAD_dep_score 0.3782 0.0862 0.1489 0 NA - - - -
SAD_ea_score 0.1447 0.1883 0.3109 0 0 NA - - -
SAD_access_score 0.6328 0.3718 0.755 0 0 0 NA - -
SAD_dist_score 0.4099 0.0818 0.8176 0 0 0 0 NA -
age 0.1189 0.1728 0.4675 8e-04 0.0058 0.0019 2e-04 0.8236 NA
Note:
SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown.

kable(as.data.frame(format(SAD_corr2$n, scientific = FALSE)), caption = "Correlations between SAD Score and Age with OSpan Performance: n values") %>%
  footnote(general = "SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown. ") %>% 
  kable_styling(bootstrap_options = c("hover", "striped"), full_width = F) %>% 
  kable_classic()
Correlations between SAD Score and Age with OSpan Performance: n values
ospan_absolute_score gng_err_omi gng_rt_av SAD_score SAD_dep_score SAD_ea_score SAD_access_score SAD_dist_score age
ospan_absolute_score 383 - - - - - - - -
gng_err_omi 383 383 - - - - - - -
gng_rt_av 383 383 383 - - - - - -
SAD_score 383 383 383 383 - - - - -
SAD_dep_score 383 383 383 383 383 - - - -
SAD_ea_score 383 383 383 383 383 383 - - -
SAD_access_score 383 383 383 383 383 383 383 - -
SAD_dist_score 383 383 383 383 383 383 383 383 -
age 383 383 383 383 383 383 383 383 383
Note:
SAD overall and Smartphone Dependency, Emotional Attachment, Accessibility, and Distractibility shown.

# does not fit nicely on page, possibly change later...
corrplot(SAD_corr$r, method = "circle", col = (colorRampPalette(c("purple", "grey", "blue"))(50)),
         type = "upper",
         # addCoef.col = "black", # Add coefficient of correlation
         tl.col = "darkblue", tl.srt = 90, tl.cex = .8, #Text label color and rotation
         # Combine with significance level
         p.mat = SAD_corr$P, sig.level = 0.05,
         addgrid.col = "white",
         # insig = "blank",
         insig = "pch", pch = 10, pch.col = "red", pch.cex = .1, # add this instead of insig above to denot insig p values with red dot
         # hide correlation coefficient on the principal diagonal
         diag = FALSE,
         win.asp = 1
         )

Exploratory Moderation Analyses

Potential moderators of OSpan performance were explored. These included both (1) continuous and (2) categorical moderators. Note: These analysis were completed regardless of the results for the location and power hypotheses.

1. Continuous Moderators

These variables were examined using a general linear model for each potential moderator: DV = OSpan Absolute Score, IV: Smartphone Location (desk, pocket/bag, outside), M: see list below. Simple slopes for each moderator x IV comparison were explored.

  • SAD Score: Smartphone Dependence, Emotional Attachment, Distractibilty
  • SUQ Score: Smartphone use with absence of other stimulation, Smartphone use during other actions
  • Demographic Info: Age

Each moderation analysis was completed using the MeMoBootR package’s moderation model 1 using a categorical IV (from Hayes, 2017; see figures below). This package provided: assumption tests, outliers, simple slopes, and a graph of the simple slopes. Since the IV was categorical (i.e., smartphone location: desk, pocket/bag, or outside), the variable is coded as a factor so that it is not misinterpreted as a continuous variable. This means that the IV is dummy coded and the analysis uses the first of the factors as the “comparison group”. In order to assess all possible comparions between the three location groups, the factor is re-ordered and run again. Additionally, to allow for better interpretation, the continuous moderator was mean-centered. The dummy coding and mean-centered scoring of the continuous moderator is done within the MeMoBootR package.


Conceptual diagram of a simple moderation model from Hayes (2017)




Statistical diagram of a simple moderation model with multicategorical independent variable with g categories from Hayes (2017)

2. Categorical Moderators

These variables were examined using a two-way ANOVA for each potential moderator: DV = OSpan Absolute Score, \(IV_{1}\): Smartphone Location (desk, pocket/bag, outside), \(IV_{M}\): see list below. Simple main effects for each moderator x IV comparison were explored.

  • SUQ Score: Texts per Day, Social Media Messages per Day, Social Media Posts per Day, Subjective Smartphone Value, Notification Type, Phantom Vibrations
  • Demographic Info: Gender, Program, Academic Year, First Language

Continuous Moderators

To examine the potential moderation of smartphone reliance (i.e. Smartphone Dependence, Emotional Attachment, and Distractibility) and age on the relationship between the experimental manipulation and task performance on the OSpan, a generalized linear model was used. Each potential moderator was evaluated separately, along with the relevant assumption tests (e.g., normality). The data was screened for outliers (i.e., cooks distance and leverage) and participants were removed from the analysis the criteria for both cooks and leverage was met.

Set up the Data

First, in order to provide all possible comparisons in the analyses, 2 new location variables were created in the mod_analysis data frame. Each was a factored version of the original smartphone location variable, where the order of the factors were either (1) desk > pocket/bag > outside (i.e., “location_desk”) or (2) outside > pocket/bag > desk (i.e., “location_out”). (click to see code)

# change location var as factor with different orders -- 2 new vars
mod_analysis <- 
  mod_analysis %>% 
  # "location_desk": desk vs. pocket/bag &  desk vs. outside
  mutate(location_desk = factor(location, levels = c(1, 2, 3), 
                                labels = c("desk", "pocketbag", "outside"))) %>% 
  # "location_out": outside vs. desk &  outside vs. pocket/bag
  mutate(location_out = factor(location, levels = c(3, 2, 1), 
                               labels = c("outside", "pocketbag", "desk")))
Run Analyses

Next, each moderation analysis was run to use the outputs (click to see code).

Run the moderation analyses for SAD variable(s): Smartphone Dependency, Emotional Attachment, and Distractibility.

#-- Run moderation analysis using moderation1() in the MeMoBootR package
  # note: moderator (m) and IV (x) are switched since moderator is continuous & IV is categorical in present study
    # was checked vs. manual lm() version & computes exact same values
  # note: analysis mean-centers the continuous var automatically
  # note: this analysis will compare: desk vs. pocket/bag&  desk vs. outside initially 
    # then, the data is re-organized to compare: pocket/bag vs. outside 
    # this was saved into 2 separate analyses, but most output is common b/w them

## SMARTPHONE DEPENDENCE ##
# run & save analysis to view components separately 
# for desk 1st
mod_SAD_dep1 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_dep_score", # continuous var
              m = "location_desk", # categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_dep1$datascreening$fulldata)

# for outside 1st
mod_SAD_dep2 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_dep_score", # continuous var
              m = "location_out", #categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_dep2$datascreening$fulldata)

## EMOTIONAL ATTACHMENT ##
# run & save analysis to view components separately 
# for desk 1st
mod_SAD_ea1 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_ea_score", # continuous var
              m = "location_desk", # categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_ea1$datascreening$fulldata)

# for outside 1st
mod_SAD_ea2 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_ea_score", # continuous var
              m = "location_out", #categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_ea2$datascreening$fulldata)

## ACCESSIBILITY ##
# run & save analysis to view components separately 
# for desk 1st
mod_SAD_access1 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_access_score", # continuous var
              m = "location_desk", # categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_access1$datascreening$fulldata)

# for outside 1st
mod_SAD_access2 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_access_score", # continuous var
              m = "location_out", #categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_access2$datascreening$fulldata)

## SMARTPHONE DISTRACTIBILITY ##
# run & save analysis to view components separately 
# for desk 1st
mod_SAD_dist1 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_dist_score", # continuous var
              m = "location_desk", # categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_dist1$datascreening$fulldata)

# for outside 1st
mod_SAD_dist2 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "SAD_dist_score", # continuous var
              m = "location_out", #categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SAD_dist2$datascreening$fulldata)

Run the moderation analyses for SUQ variable(s): Age.

#-- Run moderation analysis using moderation1() in the MeMoBootR package
  # note: moderator (m) and IV (x) are switched since moderator is continuous & IV is categorical in present study
    # was checked vs. manual lm() version & computes exact same values
  # note: analysis mean-centers the continuous var automatically
  # note: this analysis will compare: desk vs. pocket/bag&  desk vs. outside initially 
    # then, the data is re-organized to compare: pocket/bag vs. outside 
    # this was saved into 2 separate analyses, but most output is common b/w them

## AGE ##
# run & save analysis to view components separately 
# for desk 1st
mod_SUQ_age1 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "age", # continuous var
              m = "location_desk", # categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SUQ_age1$datascreening$fulldata)

# for outside 1st
mod_SUQ_age2 <-  
  moderation1(y = "ospan_absolute_score", # DV
              x = "age", # continuous var
              m = "location_out", #categorical var -- will show simple slopes
              cvs = NULL, # covariates (if any)
              df = mod_analysis, # data frame of columns
              with_out = F) # remove outliers


# Can view the full data set, including the identified outliers (last columns)
# View(mod_SUQ_age2$datascreening$fulldata)
Outliers

The model identified outliers based on leverage and cook’s distance and removed participants who were outside of the criteria for both measures.

  • Leverage

    • Tests for how much influence over the slope a single observation (i.e., participant) has: how much an individual score will change the b-values
    • Scores that fall outside of the “cut-off” criteria have a large effect on the slope independent of other score and are therefore considered outliers. These are defined with the equation \(\frac{2K+2}{N}\), where K is the number of IVs/predictors and N is the sample size.
  • Cook’s Distance

    • Tests for influential observations: the combination of leverage and discrepancy (i.e., how far a score is from other data points).
    • Scores that fall outside of the “cut-off” criteria have a large effect on the slope independent of other score and/or are far from the rest of the data and are therefore considered outliers. These are defined with the equation \(\frac{4}{N-K-1}\), where K is the number of IVs/predictors and N is the sample size.
  • Participants Removed

    • Any participant who fell outside of both the leverage and cook criteria were removed from each analysis. This was done separately for each analysis (see table below).
# create a table depicting the total outliers removed for each continuous moderation analysis
# details shown for 1st (dependency)
mod_cont_out_t <- 
  as.data.frame(cbind(c("Dependency", "Emotional Attachment", "Accessibility", "Distractibility", "Age"), 
                      rbind(
                      # for SAD_dep
                      c(sum(mod_SAD_dep1$datascreening$fulldata$badleverage), # total ps that fell outside of the leverage criteria
                        sum(mod_SAD_dep1$datascreening$fulldata$badcooks), # total ps that fell outside of the cooks criteria
                        sum(mod_SAD_dep1$datascreening$fulldata$totalout == 1), # total ps that fell outside of ONE outlier criteria (i.e., leverage OR cooks)
                        sum(mod_SAD_dep1$datascreening$fulldata$totalout == 2), # total ps that fell outside of BOTH outlier criteria (i.e., leverage AND cooks)
                        nrow(mod_SAD_dep1$datascreening$fulldata) - sum(mod_SAD_dep1$datascreening$fulldata$totalout == 2) # total sample size used in given analysis
                        ), 
                      # for SAD_ea
                      c(sum(mod_SAD_ea1$datascreening$fulldata$badleverage), 
                        sum(mod_SAD_ea1$datascreening$fulldata$badcooks), 
                        sum(mod_SAD_ea1$datascreening$fulldata$totalout == 1), 
                        sum(mod_SAD_ea1$datascreening$fulldata$totalout == 2), 
                        nrow(mod_SAD_ea1$datascreening$fulldata) - sum(mod_SAD_ea1$datascreening$fulldata$totalout == 2)
                        ),
                      # for SAD_access
                      c(sum(mod_SAD_access1$datascreening$fulldata$badleverage), 
                        sum(mod_SAD_access1$datascreening$fulldata$badcooks), 
                        sum(mod_SAD_access1$datascreening$fulldata$totalout == 1), 
                        sum(mod_SAD_access1$datascreening$fulldata$totalout == 2), 
                        nrow(mod_SAD_access1$datascreening$fulldata) - sum(mod_SAD_access1$datascreening$fulldata$totalout == 2)
                        ),
                      # for SAD_dist
                      c(sum(mod_SAD_dist1$datascreening$fulldata$badleverage), 
                        sum(mod_SAD_dist1$datascreening$fulldata$badcooks), 
                        sum(mod_SAD_dist1$datascreening$fulldata$totalout == 1), 
                        sum(mod_SAD_dist1$datascreening$fulldata$totalout == 2), 
                        nrow(mod_SAD_dist1$datascreening$fulldata) - sum(mod_SAD_dist1$datascreening$fulldata$totalout == 2)
                        ),
                      # for SUQ_age
                      c(sum(mod_SUQ_age1$datascreening$fulldata$badleverage), 
                        sum(mod_SUQ_age1$datascreening$fulldata$badcooks), 
                        sum(mod_SUQ_age1$datascreening$fulldata$totalout == 1), 
                        sum(mod_SUQ_age1$datascreening$fulldata$totalout == 2), 
                        nrow(mod_SUQ_age1$datascreening$fulldata) - sum(mod_SUQ_age1$datascreening$fulldata$totalout == 2)
                        )
                      )
                      )
                )

# rename columns
colnames(mod_cont_out_t) <- c(" ", "Leverage", "Cooks", "Both", "Removed", "N")

# use kable to show table
kable(mod_cont_out_t, caption = "Summary of identified and or removed outliers in GLM mderation analysis.", align = 'rccccc') %>%
  footnote(general = "Sample size prior to removing outlier data for all analyses was 383.") %>% 
  column_spec(1, bold = T) %>%
  add_header_above(c(" ", "Criteria" = 2, "Total Criteria" = 2, "")) %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of identified and or removed outliers in GLM mderation analysis.
Criteria
Total Criteria
Leverage Cooks Both Removed N
Dependency 31 18 35 7 376
Emotional Attachment 27 18 37 4 379
Accessibility 21 16 25 6 377
Distractibility 25 17 26 8 375
Age 26 17 17 13 370
Note:
Sample size prior to removing outlier data for all analyses was 383.
Assumptions

The model completed assumption tests for: (1) additivity/multicollinearity, (2) linearity, (3) normality, (4) homogeneity and homoscedasticity. All assumptions were met for all moderators. (click to see details)

(1) Additivity / Multicollinearity

Additivity / Multicollinearity was evaluated for each moderator. Correlations between the moderator and each IV comparison was visually inspected to ensure the correlations were not too high or low (i.e., approximately ranging between .30 to .80). All moderators’ correlations were within an acceptable range.


Dependency Moderator: correlations ranged from 0.43 to 0.73.

# grab table from output
mod_SAD_dep_corr_t <- 
  as.data.frame(cbind(c("Dependency Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Dep x DvPB", "Dep x DvO"), 
                      mod_SAD_dep1$datascreening$correl[2:6, 2:6],
                      c(6:10),
                      c("Dependency Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Dep x OvPB", "Dep x OvD"),
                      mod_SAD_dep2$datascreening$correl[2:6, 2:6])
                )
# rename rows & columns
colnames(mod_SAD_dep_corr_t) <- c("var1", "Dependency Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Dep x DvPB", "Dep x DvO",
                                  "row", "var2",
                             "Dependency Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Dep x OvPB", "Dep x OvD")
rownames(mod_SAD_dep_corr_t) <- 1:nrow(mod_SAD_dep_corr_t)

# reset values as numeric
mod_SAD_dep_corr_t[,2] <- as.numeric(mod_SAD_dep_corr_t[,2])
mod_SAD_dep_corr_t[,3] <- as.numeric(mod_SAD_dep_corr_t[,3])
mod_SAD_dep_corr_t[,4] <- as.numeric(mod_SAD_dep_corr_t[,4])
mod_SAD_dep_corr_t[,5] <- as.numeric(mod_SAD_dep_corr_t[,5])
mod_SAD_dep_corr_t[,6] <- as.numeric(mod_SAD_dep_corr_t[,6])
mod_SAD_dep_corr_t[,9] <- as.numeric(mod_SAD_dep_corr_t[,9])
mod_SAD_dep_corr_t[,10] <- as.numeric(mod_SAD_dep_corr_t[,10])
mod_SAD_dep_corr_t[,11] <- as.numeric(mod_SAD_dep_corr_t[,11])
mod_SAD_dep_corr_t[,12] <- as.numeric(mod_SAD_dep_corr_t[,12])
mod_SAD_dep_corr_t[,13] <- as.numeric(mod_SAD_dep_corr_t[,13])

# Print table using kable
kable(mod_SAD_dep_corr_t, caption = "Correlations for the dependency moderator.", 
      digits = 2, align = 'rccccccrrcccc', row.names = T, col.names = c(" ", 1:5, "", "", 6:10)) %>%
  # footnote(general = "Interaction variables ") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" " = 2, "Moderator", "Location" = 2, "Interaction" = 2, " " = 2, "Moderator", "Location" = 2, "Interaction" = 2), bold = T) %>%
  add_header_above(c(" " = 2, "Comparison Group: \nDesk" = 5, " " = 2, "Comparison Group: \nOutside" = 5)) %>%
  column_spec(2, bold = T) %>%
  column_spec(9, bold = T) %>%
  column_spec(7, border_right = T) %>%
  kable_classic()
Correlations for the dependency moderator.
Comparison Group:
Desk
Comparison Group:
Outside
Moderator
Location
Interaction
Moderator
Location
Interaction
1 2 3 4 5 6 7 8 9 10
1 Dependency Score 1.00 0.62 0.60 -0.66 -0.65 6 Dependency Score 1.00 0.70 0.73 -0.72 -0.76
2 Desk vs. Pocket/Bag 0.62 1.00 0.43 -0.94 -0.41 7 Outside vs. Pocket/Bag 0.70 1.00 0.56 -0.95 -0.53
3 Desk vs. Outside 0.60 0.43 1.00 -0.40 -0.94 8 Outside vs. Desk 0.73 0.56 1.00 -0.52 -0.94
4 Dep x DvPB -0.66 -0.94 -0.40 1.00 0.43 9 Dep x OvPB -0.72 -0.95 -0.52 1.00 0.54
5 Dep x DvO -0.65 -0.41 -0.94 0.43 1.00 10 Dep x OvD -0.76 -0.53 -0.94 0.54 1.00


Emotional Attachment Moderator: correlations ranged from 0.51 to 0.72.

# grab table from output
mod_SAD_ea_corr_t <- 
  as.data.frame(cbind(c("Emotional Attachment Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "EA x DvPB", "EA x DvO"), 
                      mod_SAD_ea1$datascreening$correl[2:6, 2:6],
                      c(6:10),
                      c("Emotional Attachment Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "EA x OvPB", "EA x OvD"),
                      mod_SAD_ea2$datascreening$correl[2:6, 2:6])
                )
# rename rows & columns
colnames(mod_SAD_ea_corr_t) <- c("var1", "Emotional Attachment Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "EA x DvPB", "EA x DvO",
                                  "row", "var2",
                             "Emotional Attachment Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "EA x OvPB", "EA x OvD")
rownames(mod_SAD_ea_corr_t) <- 1:nrow(mod_SAD_ea_corr_t)

# reset values as numeric
mod_SAD_ea_corr_t[,2] <- as.numeric(mod_SAD_ea_corr_t[,2])
mod_SAD_ea_corr_t[,3] <- as.numeric(mod_SAD_ea_corr_t[,3])
mod_SAD_ea_corr_t[,4] <- as.numeric(mod_SAD_ea_corr_t[,4])
mod_SAD_ea_corr_t[,5] <- as.numeric(mod_SAD_ea_corr_t[,5])
mod_SAD_ea_corr_t[,6] <- as.numeric(mod_SAD_ea_corr_t[,6])
mod_SAD_ea_corr_t[,9] <- as.numeric(mod_SAD_ea_corr_t[,9])
mod_SAD_ea_corr_t[,10] <- as.numeric(mod_SAD_ea_corr_t[,10])
mod_SAD_ea_corr_t[,11] <- as.numeric(mod_SAD_ea_corr_t[,11])
mod_SAD_ea_corr_t[,12] <- as.numeric(mod_SAD_ea_corr_t[,12])
mod_SAD_ea_corr_t[,13] <- as.numeric(mod_SAD_ea_corr_t[,13])

# Print table using kable
kable(mod_SAD_ea_corr_t, caption = "Correlations for the emotional attachment moderator.", 
      digits = 2, align = 'rccccccrrcccc', row.names = T, col.names = c(" ", 1:5, "", "", 6:10)) %>%
  # footnote(general = "Interaction variables ") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" " = 2, "Moderator", "Location" = 2, "Interaction" = 2, " " = 2, "Moderator", "Location" = 2, "Interaction" = 2), bold = T) %>%
  add_header_above(c(" " = 2, "Comparison Group: \nDesk" = 5, " " = 2, "Comparison Group: \nOutside" = 5)) %>%
  column_spec(2, bold = T) %>%
  column_spec(9, bold = T) %>%
  column_spec(7, border_right = T) %>%
  kable_classic()
Correlations for the emotional attachment moderator.
Comparison Group:
Desk
Comparison Group:
Outside
Moderator
Location
Interaction
Moderator
Location
Interaction
1 2 3 4 5 6 7 8 9 10
1 Emotional Attachment Score 1.00 0.71 0.66 -0.73 -0.70 6 Emotional Attachment Score 1.00 0.72 0.70 -0.74 -0.71
2 Desk vs. Pocket/Bag 0.71 1.00 0.51 -0.96 -0.49 7 Outside vs. Pocket/Bag 0.72 1.00 0.54 -0.96 -0.52
3 Desk vs. Outside 0.66 0.51 1.00 -0.48 -0.96 8 Outside vs. Desk 0.70 0.54 1.00 -0.51 -0.96
4 EA x DvPB -0.73 -0.96 -0.48 1.00 0.51 9 EA x OvPB -0.74 -0.96 -0.51 1.00 0.53
5 EA x DvO -0.70 -0.49 -0.96 0.51 1.00 10 EA x OvD -0.71 -0.52 -0.96 0.53 1.00


Accessibility Moderator: correlations ranged from 0.46 to 0.73.

# grab table from output
mod_SAD_access_corr_t <- 
  as.data.frame(cbind(c("Emotional Attachment Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Access x DvPB", "Access x DvO"), 
                      mod_SAD_access1$datascreening$correl[2:6, 2:6],
                      c(6:10),
                      c("Emotional Attachment Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Access x OvPB", "Access x OvD"),
                      mod_SAD_access2$datascreening$correl[2:6, 2:6])
                )
# rename rows & columns
colnames(mod_SAD_access_corr_t) <- c("var1", "Emotional Attachment Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Access x DvPB", "Access x DvO",
                                  "row", "var2",
                             "Emotional Attachment Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Access x OvPB", "Access x OvD")
rownames(mod_SAD_access_corr_t) <- 1:nrow(mod_SAD_access_corr_t)

# reset values as numeric
mod_SAD_access_corr_t[,2] <- as.numeric(mod_SAD_access_corr_t[,2])
mod_SAD_access_corr_t[,3] <- as.numeric(mod_SAD_access_corr_t[,3])
mod_SAD_access_corr_t[,4] <- as.numeric(mod_SAD_access_corr_t[,4])
mod_SAD_access_corr_t[,5] <- as.numeric(mod_SAD_access_corr_t[,5])
mod_SAD_access_corr_t[,6] <- as.numeric(mod_SAD_access_corr_t[,6])
mod_SAD_access_corr_t[,9] <- as.numeric(mod_SAD_access_corr_t[,9])
mod_SAD_access_corr_t[,10] <- as.numeric(mod_SAD_access_corr_t[,10])
mod_SAD_access_corr_t[,11] <- as.numeric(mod_SAD_access_corr_t[,11])
mod_SAD_access_corr_t[,12] <- as.numeric(mod_SAD_access_corr_t[,12])
mod_SAD_access_corr_t[,13] <- as.numeric(mod_SAD_access_corr_t[,13])

# Print table using kable
kable(mod_SAD_access_corr_t, caption = "Correlations for the accessibility moderator.", 
      digits = 2, align = 'rccccccrrcccc', row.names = T, col.names = c(" ", 1:5, "", "", 6:10)) %>%
  # footnote(general = "Interaction variables ") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" " = 2, "Moderator", "Location" = 2, "Interaction" = 2, " " = 2, "Moderator", "Location" = 2, "Interaction" = 2), bold = T) %>%
  add_header_above(c(" " = 2, "Comparison Group: \nDesk" = 5, " " = 2, "Comparison Group: \nOutside" = 5)) %>%
  column_spec(2, bold = T) %>%
  column_spec(9, bold = T) %>%
  column_spec(7, border_right = T) %>%
  kable_classic()
Correlations for the accessibility moderator.
Comparison Group:
Desk
Comparison Group:
Outside
Moderator
Location
Interaction
Moderator
Location
Interaction
1 2 3 4 5 6 7 8 9 10
1 Emotional Attachment Score 1.00 0.67 0.64 -0.68 -0.67 6 Emotional Attachment Score 1.00 0.72 0.73 -0.72 -0.74
2 Desk vs. Pocket/Bag 0.67 1.00 0.46 -0.97 -0.45 7 Outside vs. Pocket/Bag 0.72 1.00 0.55 -0.97 -0.53
3 Desk vs. Outside 0.64 0.46 1.00 -0.44 -0.97 8 Outside vs. Desk 0.73 0.55 1.00 -0.53 -0.97
4 Access x DvPB -0.68 -0.97 -0.44 1.00 0.46 9 Access x OvPB -0.72 -0.97 -0.53 1.00 0.54
5 Access x DvO -0.67 -0.45 -0.97 0.46 1.00 10 Access x OvD -0.74 -0.53 -0.97 0.54 1.00


Distractibility Moderator: correlations ranged from 0.45 to 0.7.

# grab table from output
mod_SAD_dist_corr_t <- 
  as.data.frame(cbind(c("Distractibility Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Dist x DvPB", "Dist x DvO"), 
                      mod_SAD_dist1$datascreening$correl[2:6, 2:6],
                      c(6:10),
                      c("Distractibility Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Dist x OvPB", "Dist x OvD"),
                      mod_SAD_dist2$datascreening$correl[2:6, 2:6])
                )
# rename rows & columns
colnames(mod_SAD_dist_corr_t) <- c("var1", "Distractibility Score", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Dist x DvPB", "Dist x DvO",
                                  "row", "var2",
                             "Distractibility Score", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Dist x OvPB", "Dist x OvD")
rownames(mod_SAD_dist_corr_t) <- 1:nrow(mod_SAD_dist_corr_t)

# reset values as numeric
mod_SAD_dist_corr_t[,2] <- as.numeric(mod_SAD_dist_corr_t[,2])
mod_SAD_dist_corr_t[,3] <- as.numeric(mod_SAD_dist_corr_t[,3])
mod_SAD_dist_corr_t[,4] <- as.numeric(mod_SAD_dist_corr_t[,4])
mod_SAD_dist_corr_t[,5] <- as.numeric(mod_SAD_dist_corr_t[,5])
mod_SAD_dist_corr_t[,6] <- as.numeric(mod_SAD_dist_corr_t[,6])
mod_SAD_dist_corr_t[,9] <- as.numeric(mod_SAD_dist_corr_t[,9])
mod_SAD_dist_corr_t[,10] <- as.numeric(mod_SAD_dist_corr_t[,10])
mod_SAD_dist_corr_t[,11] <- as.numeric(mod_SAD_dist_corr_t[,11])
mod_SAD_dist_corr_t[,12] <- as.numeric(mod_SAD_dist_corr_t[,12])
mod_SAD_dist_corr_t[,13] <- as.numeric(mod_SAD_dist_corr_t[,13])

# Print table using kable
kable(mod_SAD_dist_corr_t, caption = "Correlations for the distractibility moderator.", 
      digits = 2, align = 'rccccccrrcccc', row.names = T, col.names = c(" ", 1:5, "", "", 6:10)) %>%
  # footnote(general = "Interaction variables ") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" " = 2, "Moderator", "Location" = 2, "Interaction" = 2, " " = 2, "Moderator", "Location" = 2, "Interaction" = 2), bold = T) %>%
  add_header_above(c(" " = 2, "Comparison Group: \nDesk" = 5, " " = 2, "Comparison Group: \nOutside" = 5)) %>%
  column_spec(2, bold = T) %>%
  column_spec(9, bold = T) %>%
  column_spec(7, border_right = T) %>%
  kable_classic()
Correlations for the distractibility moderator.
Comparison Group:
Desk
Comparison Group:
Outside
Moderator
Location
Interaction
Moderator
Location
Interaction
1 2 3 4 5 6 7 8 9 10
1 Distractibility Score 1.00 0.66 0.70 -0.67 -0.71 6 Distractibility Score 1.00 0.64 0.66 -0.67 -0.70
2 Desk vs. Pocket/Bag 0.66 1.00 0.49 -0.97 -0.47 7 Outside vs. Pocket/Bag 0.64 1.00 0.45 -0.97 -0.45
3 Desk vs. Outside 0.70 0.49 1.00 -0.47 -0.97 8 Outside vs. Desk 0.66 0.45 1.00 -0.44 -0.97
4 Dist x DvPB -0.67 -0.97 -0.47 1.00 0.48 9 Dist x OvPB -0.67 -0.97 -0.44 1.00 0.47
5 Dist x DvO -0.71 -0.47 -0.97 0.48 1.00 10 Dist x OvD -0.70 -0.45 -0.97 0.47 1.00


Age Moderator: correlations ranged from 0.47 to 0.77.

# grab table from output
mod_SUQ_age_corr_t <- 
  as.data.frame(cbind(c("Age", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Age x DvPB", "Age x DvO"), 
                      mod_SUQ_age1$datascreening$correl[2:6, 2:6],
                      c(6:10),
                      c("Age", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Age x OvPB", "Age x OvD"),
                      mod_SUQ_age2$datascreening$correl[2:6, 2:6])
                )
# rename rows & columns
colnames(mod_SUQ_age_corr_t) <- c("var1", "Age", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Age x DvPB", "Age x DvO",
                                   "row", "var2",
                                   "Age", "Outside vs. Pocket/Bag", "Outside vs. Desk", "Age x OvPB", "Age x OvD")
rownames(mod_SUQ_age_corr_t) <- 1:nrow(mod_SUQ_age_corr_t)

# reset values as numeric
mod_SUQ_age_corr_t[,2] <- as.numeric(mod_SUQ_age_corr_t[,2])
mod_SUQ_age_corr_t[,3] <- as.numeric(mod_SUQ_age_corr_t[,3])
mod_SUQ_age_corr_t[,4] <- as.numeric(mod_SUQ_age_corr_t[,4])
mod_SUQ_age_corr_t[,5] <- as.numeric(mod_SUQ_age_corr_t[,5])
mod_SUQ_age_corr_t[,6] <- as.numeric(mod_SUQ_age_corr_t[,6])
mod_SUQ_age_corr_t[,9] <- as.numeric(mod_SUQ_age_corr_t[,9])
mod_SUQ_age_corr_t[,10] <- as.numeric(mod_SUQ_age_corr_t[,10])
mod_SUQ_age_corr_t[,11] <- as.numeric(mod_SUQ_age_corr_t[,11])
mod_SUQ_age_corr_t[,12] <- as.numeric(mod_SUQ_age_corr_t[,12])
mod_SUQ_age_corr_t[,13] <- as.numeric(mod_SUQ_age_corr_t[,13])

# Print table using kable
kable(mod_SUQ_age_corr_t, caption = "Correlations for the age moderator.", 
      digits = 2, align = 'rccccccrrcccc', row.names = T, col.names = c(" ", 1:5, "", "", 6:10)) %>%
  # footnote(general = "Interaction variables ") %>% 
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  add_header_above(c(" " = 2, "Moderator", "Location" = 2, "Interaction" = 2, " " = 2, "Moderator", "Location" = 2, "Interaction" = 2), bold = T) %>%
  add_header_above(c(" " = 2, "Comparison Group: \nDesk" = 5, " " = 2, "Comparison Group: \nOutside" = 5)) %>%
  column_spec(2, bold = T) %>%
  column_spec(9, bold = T) %>%
  column_spec(7, border_right = T) %>%
  kable_classic()
Correlations for the age moderator.
Comparison Group:
Desk
Comparison Group:
Outside
Moderator
Location
Interaction
Moderator
Location
Interaction
1 2 3 4 5 6 7 8 9 10
1 Age 1.00 0.77 0.76 -0.78 -0.76 6 Age 1.00 0.72 0.65 -0.72 -0.65
2 Desk vs. Pocket/Bag 0.77 1.00 0.59 -1.00 -0.59 7 Outside vs. Pocket/Bag 0.72 1.00 0.47 -1.00 -0.47
3 Desk vs. Outside 0.76 0.59 1.00 -0.59 -1.00 8 Outside vs. Desk 0.65 0.47 1.00 -0.47 -1.00
4 Age x DvPB -0.78 -1.00 -0.59 1.00 0.59 9 Age x OvPB -0.72 -1.00 -0.47 1.00 0.47
5 Age x DvO -0.76 -0.59 -1.00 0.59 1.00 10 Age x OvD -0.65 -0.47 -1.00 0.47 1.00
NA
(2) Linearity

Linearity was evaluated for each moderator using Q-Q plots. For all moderators, the data fell along or close to the line. Therefore, linearity was met for all moderators.

# note: this is the same across the 2 IV orders (i.e., desk or outside first)
 # each moderator's q-q plot can also be found independently using: "mod_SAD_dep1$datascreening$linearity"
grid.arrange(ggqqplot(mod_SAD_dep1$model1$residuals, title = "Q-Q Plot for \nDependence", 
                      shape = 1, ggtheme = theme_classic()),
             ggqqplot(mod_SAD_ea1$model1$residuals, title = "Q-Q Plot for \nEmotional Attachment", 
                      shape = 1, ggtheme = theme_classic()),
             ggqqplot(mod_SAD_access1$model1$residuals, title = "Q-Q Plot for \nAccessibility", 
                      shape = 1, ggtheme = theme_classic()),
             ggqqplot(mod_SAD_dist1$model1$residuals, title = "Q-Q Plot for \nDistractibility", 
                      shape = 1, ggtheme = theme_classic()),
             ggqqplot(mod_SUQ_age1$model1$residuals, title = "Q-Q Plot for Age", 
                      shape = 1, ggtheme = theme_classic()),
             # labels = c("A", "B", "C", "D"),
             nrow = 2,
             top = text_grob("Q-Q Plots For Continuous Moderators", face = "bold")
             )

(3) Normality

Normality was evaluated for each moderator by plotting a histogram of residuals. For all moderators, the data fell along or close to a normal curve. Therefore, normality was met for all moderators.

# note: this is the same across the 2 IV orders (i.e., desk or outside first)
 # each moderator's q-q plot can also be found independently using: "mod_SAD_dep1$datascreening$normality"
grid.arrange(qplot(mod_SAD_dep1$model1$residuals, main = "Dependency", xlab = "Residuals", ylab = "Frequency", binwidth = 5),
             qplot(mod_SAD_ea1$model1$residuals, main = "Emotional Attachment", xlab = "Residuals", ylab = "Frequency", binwidth = 5), 
             qplot(mod_SAD_access1$model1$residuals, main = "Accessibility", xlab = "Residuals", ylab = "Frequency", binwidth = 5), 
             qplot(mod_SAD_dist1$model1$residuals, main = "Distractibility", xlab = "Residuals", ylab = "Frequency", binwidth = 5), 
             qplot(mod_SUQ_age1$model1$residuals, main = "Age", xlab = "Residuals", ylab = "Frequency", binwidth = 5),
             # labels = c("A", "B", "C", "D"),
             nrow = 2,
             top = text_grob("Histogram of Residuals For Continuous Moderators", face = "bold")
             )

(4) Homogeneity and Homoscedasticity

Homogeneity and homoscedasticity were evaluated for each moderator by plotting a scatter plot of the fitted values vs. residuals. For all moderators, the line of best fit showed an overall linear trend. Except for age, all moderators showed a good distribution throughout the plot. This was not surprising since reported age was whole-numbers only and the sample size did not cover a large age distribution. Therefore, homogeneity and homoscedasticity were met for all moderators.

# note: this is the same across the 2 IV orders (i.e., desk or outside first)
 # each moderator's q-q plot can also be found independently using: "mod_SAD_dep1$datascreening$linearity"
grid.arrange(qplot(x = mod_SAD_dep1$model1$fitted.values, y = mod_SAD_dep1$model1$residuals, 
                   main = "Dependency", xlab = "Fitted", ylab = "Residuals", geom = "point") + geom_smooth(se = F) + theme_classic(),
             qplot(x = mod_SAD_ea1$model1$fitted.values, y = mod_SAD_ea1$model1$residuals, 
                   main = "Emotional Attachment", xlab = "Fitted", ylab = "Residuals", geom = "point") + geom_smooth(se = F) + theme_classic(), 
             qplot(x = mod_SAD_access1$model1$fitted.values, y = mod_SAD_access1$model1$residuals, 
                   main = "Accessibility", xlab = "Fitted", ylab = "Residuals", geom = "point") + geom_smooth(se = F) + theme_classic(), 
             qplot(x = mod_SAD_dist1$model1$fitted.values, y = mod_SAD_dist1$model1$residuals, 
                   main = "Distractibility", xlab = "Fitted", ylab = "Residuals", geom = "point") + geom_smooth(se = F) + theme_classic(), 
             qplot(x = mod_SUQ_age1$model1$fitted.values, y = mod_SUQ_age1$model1$residuals, 
                   main = "Age", xlab = "Fitted", ylab = "Residuals", geom = "point") + geom_smooth(se = F) + theme_classic(),
             # labels = c("A", "B", "C", "D"),
             nrow = 2,
             top = text_grob("Residual-Fitted Plot For Continuous Moderators", face = "bold")
             )
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

Overall Model

Now that assumptions were checked and met, each model was reviewed. For each moderator’s model showed: b-values, se, t, p-value, over all model fit (i.e., f-value with p-value), and \(R^{2}\).

Dependence

For dependency the moderator, IV, and interactions were not significant.

# create data frame with model values -- all values rounded to 5 decimals
  # note: you can see non-formatted model summary using "summary(mod_SAD_dep1$model1)" or "summary(mod_SAD_dep2$model1)"
mod_SAD_dep_t <- 
  # add b estimate, se, t, p
  rbind(data.frame("var" = c("Dependence", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Outside vs. Pocket/Bag", 
                                   "Dep x DvPB", "Dep x DvO", "Dep x OvPB"), 
                   "b" = round(c(mod_SAD_dep1$model1$coefficients[2:4], mod_SAD_dep2$model1$coefficients[3], mod_SAD_dep1$model1$coefficients[5:6],
                                 mod_SAD_dep2$model1$coefficients[5]), 5), 
                   "se" = round(c(summary(mod_SAD_dep1$model1)$coefficients[2:4,2], summary(mod_SAD_dep2$model1)$coefficients[3,2], 
                                  summary(mod_SAD_dep1$model1)$coefficients[5:6,2], summary(mod_SAD_dep2$model1)$coefficients[5,2]), 5), 
                   "t" = round(c(summary(mod_SAD_dep1$model1)$coefficients[2:4,3], summary(mod_SAD_dep2$model1)$coefficients[3,3], 
                                 summary(mod_SAD_dep1$model1)$coefficients[5:6,3], summary(mod_SAD_dep2$model1)$coefficients[5,3]), 5),
                   "p" = round(c(summary(mod_SAD_dep1$model1)$coefficients[2:4,4], summary(mod_SAD_dep2$model1)$coefficients[3,4], 
                                 summary(mod_SAD_dep1$model1)$coefficients[5:6,4], summary(mod_SAD_dep2$model1)$coefficients[5,4]), 5)
                         ), 
        # add labels for: F, df1, df2, p-value, and Rsq values
        c(" ", "df1", "df2", "F", "p"), 
        # add F, df1, df2, p-value, and Rsq values
        c("Overall Model Fit", round(c(summary(mod_SAD_dep1$model1)$fstatistic[2], summary(mod_SAD_dep1$model1)$fstatistic[3], summary(mod_SAD_dep1$model1)$fstatistic[1], 
                pf(summary(mod_SAD_dep1$model1)$fstatistic[1], summary(mod_SAD_dep1$model1)$fstatistic[2], summary(mod_SAD_dep1$model1)$fstatistic[3],lower.tail=FALSE)), 5)), 
        # add R squared value
        c("R-squared", round(summary(mod_SAD_dep1$model1)$r.squared, 5), rep(c(""), 3))
        )

# rename rows
rownames(mod_SAD_dep_t) <- c(1:7, " ", 8:9)

# Print table using kable
kable(mod_SAD_dep_t, caption = "Summary of moderation analysis with IV: Smartphone Location and M: Dependence.", align = 'rcccc', row.names = T, col.names = c(" ", "b", "SE", "t", "p")) %>%
  # footnote(general = "Interaction variables ") %>%
  pack_rows("Moderator", 1, 1) %>%
  pack_rows("IV: Smartphone Location", 2, 4) %>%
  pack_rows("Interactions: Moderator x IV", 5, 7) %>%
  pack_rows(" ", 8, 10, indent = F) %>%
  pack_rows("Model", 8, 10) %>% 
  row_spec(0, bold = T, italic = T) %>%
  row_spec(8, bold = T, italic = T) %>%
  column_spec(2, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of moderation analysis with IV: Smartphone Location and M: Dependence.
b SE t p
Moderator
1 Dependence 0.30817 0.29519 1.04398 0.29718
IV: Smartphone Location
2 Desk vs. Pocket/Bag 0.7494 2.06902 0.3622 0.71741
3 Desk vs. Outside 1.05897 2.11485 0.50073 0.61686
4 Outside vs. Pocket/Bag -0.30957 2.10022 -0.1474 0.8829
Interactions: Moderator x IV
5 Dep x DvPB -0.40457 0.4453 -0.90852 0.36419
6 Dep x DvO -0.2315 0.45315 -0.51085 0.60976
7 Dep x OvPB -0.17307 0.47893 -0.36137 0.71803
Model
df1 df2 F p
8 Overall Model Fit 5 370 0.3079 0.90811
9 R-squared 0.00414
Emotional Attachment

For emotional attachment the moderator was significant, xxxxx. However, the IV, and interactions were not significant.

# create data frame with model values -- all values rounded to 5 decimals
  # note: you can see non-formatted model summary using "summary(mod_SAD_ea1$model1)" or "summary(mod_SAD_ea2$model1)"
mod_SAD_ea_t <- 
  # add b estimate, se, t, p
  rbind(data.frame("var" = c("Emotional Attachment", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Outside vs. Pocket/Bag", 
                                   "EA x DvPB", "EA x DvO", "EA x OvPB"), 
                   "b" = round(c(mod_SAD_ea1$model1$coefficients[2:4], mod_SAD_ea2$model1$coefficients[3], mod_SAD_ea1$model1$coefficients[5:6],
                                 mod_SAD_ea2$model1$coefficients[5]), 5), 
                   "se" = round(c(summary(mod_SAD_ea1$model1)$coefficients[2:4,2], summary(mod_SAD_ea2$model1)$coefficients[3,2], 
                                  summary(mod_SAD_ea1$model1)$coefficients[5:6,2], summary(mod_SAD_ea2$model1)$coefficients[5,2]), 5), 
                   "t" = round(c(summary(mod_SAD_ea1$model1)$coefficients[2:4,3], summary(mod_SAD_ea2$model1)$coefficients[3,3], 
                                 summary(mod_SAD_ea1$model1)$coefficients[5:6,3], summary(mod_SAD_ea2$model1)$coefficients[5,3]), 5),
                   "p" = round(c(summary(mod_SAD_ea1$model1)$coefficients[2:4,4], summary(mod_SAD_ea2$model1)$coefficients[3,4], 
                                 summary(mod_SAD_ea1$model1)$coefficients[5:6,4], summary(mod_SAD_ea2$model1)$coefficients[5,4]), 5)
                         ), 
        # add labels for: F, df1, df2, p-value, and Rsq values
        c(" ", "df1", "df2", "F", "p"), 
        # add F, df1, df2, p-value, and Rsq values
        c("Overall Model Fit", round(c(summary(mod_SAD_ea1$model1)$fstatistic[2], summary(mod_SAD_ea1$model1)$fstatistic[3], summary(mod_SAD_ea1$model1)$fstatistic[1], 
                pf(summary(mod_SAD_ea1$model1)$fstatistic[1], summary(mod_SAD_ea1$model1)$fstatistic[2], summary(mod_SAD_ea1$model1)$fstatistic[3],lower.tail=FALSE)), 5)), 
        # add R squared value
        c("R-squared", round(summary(mod_SAD_ea1$model1)$r.squared, 5), rep(c(""), 3))
        )

# rename rows
rownames(mod_SAD_ea_t) <- c(1:7, " ", 8:9)

# Print table using kable
kable(mod_SAD_ea_t, caption = "Summary of moderation analysis with IV: Smartphone Location and M: Emotional Attachment.", align = 'rcccc', row.names = T, col.names = c(" ", "b", "SE", "t", "p")) %>%
  # footnote(general = "Interaction variables ") %>%
  pack_rows("Moderator", 1, 1) %>%
  pack_rows("IV: Smartphone Location", 2, 4) %>%
  pack_rows("Interactions: Moderator x IV", 5, 7) %>%
  pack_rows(" ", 8, 10, indent = F) %>%
  pack_rows("Model", 8, 10) %>% 
  row_spec(0, bold = T, italic = T) %>%
  row_spec(8, bold = T, italic = T) %>%
  column_spec(2, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of moderation analysis with IV: Smartphone Location and M: Emotional Attachment.
b SE t p
Moderator
1 Emotional Attachment -0.62853 0.31548 -1.9923 0.04707
IV: Smartphone Location
2 Desk vs. Pocket/Bag 0.79885 2.08812 0.38257 0.70226
3 Desk vs. Outside 0.26949 2.13268 0.12636 0.89951
4 Outside vs. Pocket/Bag 0.52936 2.12 0.2497 0.80296
Interactions: Moderator x IV
5 EA x DvPB 0.31867 0.4328 0.73629 0.46201
6 EA x DvO 0.60612 0.45097 1.34403 0.17975
7 EA x OvPB -0.28745 0.43776 -0.65663 0.51182
Model
df1 df2 F p
8 Overall Model Fit 5 373 1.05259 0.38647
9 R-squared 0.01391
Accessibility

For accessibility the moderator, IV, and interactions were not significant.

# create data frame with model values -- all values rounded to 5 decimals
  # note: you can see non-formatted model summary using "summary(mod_SAD_access1$model1)" or "summary(mod_SAD_access2$model1)"
mod_SAD_access_t <- 
  # add b estimate, se, t, p
  rbind(data.frame("var" = c("Accessibility", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Outside vs. Pocket/Bag", 
                                   "Access x DvPB", "Access x DvO", "Access x OvPB"), 
                   "b" = round(c(mod_SAD_access1$model1$coefficients[2:4], mod_SAD_access2$model1$coefficients[3], mod_SAD_access1$model1$coefficients[5:6],
                                 mod_SAD_access2$model1$coefficients[5]), 5), 
                   "se" = round(c(summary(mod_SAD_access1$model1)$coefficients[2:4,2], summary(mod_SAD_access2$model1)$coefficients[3,2], 
                                  summary(mod_SAD_access1$model1)$coefficients[5:6,2], summary(mod_SAD_access2$model1)$coefficients[5,2]), 5), 
                   "t" = round(c(summary(mod_SAD_access1$model1)$coefficients[2:4,3], summary(mod_SAD_access2$model1)$coefficients[3,3], 
                                 summary(mod_SAD_access1$model1)$coefficients[5:6,3], summary(mod_SAD_access2$model1)$coefficients[5,3]), 5),
                   "p" = round(c(summary(mod_SAD_access1$model1)$coefficients[2:4,4], summary(mod_SAD_access2$model1)$coefficients[3,4], 
                                 summary(mod_SAD_access1$model1)$coefficients[5:6,4], summary(mod_SAD_access2$model1)$coefficients[5,4]), 5)
                         ), 
        # add labels for: F, df1, df2, p-value, and Rsq values
        c(" ", "df1", "df2", "F", "p"), 
        # add F, df1, df2, p-value, and Rsq values
        c("Overall Model Fit", round(c(summary(mod_SAD_access1$model1)$fstatistic[2], summary(mod_SAD_access1$model1)$fstatistic[3], summary(mod_SAD_access1$model1)$fstatistic[1], 
                pf(summary(mod_SAD_access1$model1)$fstatistic[1], summary(mod_SAD_access1$model1)$fstatistic[2], summary(mod_SAD_access1$model1)$fstatistic[3],lower.tail=FALSE)), 5)), 
        # add R squared value
        c("R-squared", round(summary(mod_SAD_access1$model1)$r.squared, 5), rep(c(""), 3))
        )

# rename rows
rownames(mod_SAD_access_t) <- c(1:7, " ", 8:9)

# Print table using kable
kable(mod_SAD_access_t, caption = "Summary of moderation analysis with IV: Smartphone Location and M: Accessibility", align = 'rcccc', row.names = T, col.names = c(" ", "b", "SE", "t", "p")) %>%
  # footnote(general = "Interaction variables ") %>%
  pack_rows("Moderator", 1, 1) %>%
  pack_rows("IV: Smartphone Location", 2, 4) %>%
  pack_rows("Interactions: Moderator x IV", 5, 7) %>%
  pack_rows(" ", 8, 10, indent = F) %>%
  pack_rows("Model", 8, 10) %>% 
  row_spec(0, bold = T, italic = T) %>%
  row_spec(8, bold = T, italic = T) %>%
  column_spec(2, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of moderation analysis with IV: Smartphone Location and M: Accessibility
b SE t p
Moderator
1 Accessibility -0.31986 0.39716 -0.80538 0.42112
IV: Smartphone Location
2 Desk vs. Pocket/Bag 1.00154 2.09887 0.47718 0.63351
3 Desk vs. Outside 0.51756 2.14074 0.24177 0.80909
4 Outside vs. Pocket/Bag 0.48398 2.11938 0.22836 0.81949
Interactions: Moderator x IV
5 Access x DvPB 0.61708 0.58046 1.06308 0.28844
6 Access x DvO 0.28644 0.59532 0.48115 0.63069
7 Access x OvPB 0.33064 0.61309 0.5393 0.59001
Model
df1 df2 F p
8 Overall Model Fit 5 371 0.26925 0.92978
9 R-squared 0.00362
Distractibility

For distractibility the moderator, IV, and interactions were not significant.

# create data frame with model values -- all values rounded to 5 decimals
  # note: you can see non-formatted model summary using "summary(mod_SAD_dist1$model1)" or "summary(mod_SAD_dist2$model1)"
mod_SAD_dist_t <- 
  # add b estimate, se, t, p
  rbind(data.frame("var" = c("Distractibility", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Outside vs. Pocket/Bag", 
                                   "Dist x DvPB", "Dist x DvO", "Dist x OvPB"), 
                   "b" = round(c(mod_SAD_dist1$model1$coefficients[2:4], mod_SAD_dist2$model1$coefficients[3], mod_SAD_dist1$model1$coefficients[5:6],
                                 mod_SAD_dist2$model1$coefficients[5]), 5), 
                   "se" = round(c(summary(mod_SAD_dist1$model1)$coefficients[2:4,2], summary(mod_SAD_dist2$model1)$coefficients[3,2], 
                                  summary(mod_SAD_dist1$model1)$coefficients[5:6,2], summary(mod_SAD_dist2$model1)$coefficients[5,2]), 5), 
                   "t" = round(c(summary(mod_SAD_dist1$model1)$coefficients[2:4,3], summary(mod_SAD_dist2$model1)$coefficients[3,3], 
                                 summary(mod_SAD_dist1$model1)$coefficients[5:6,3], summary(mod_SAD_dist2$model1)$coefficients[5,3]), 5),
                   "p" = round(c(summary(mod_SAD_dist1$model1)$coefficients[2:4,4], summary(mod_SAD_dist2$model1)$coefficients[3,4], 
                                 summary(mod_SAD_dist1$model1)$coefficients[5:6,4], summary(mod_SAD_dist2$model1)$coefficients[5,4]), 5)
                         ), 
        # add labels for: F, df1, df2, p-value, and Rsq values
        c(" ", "df1", "df2", "F", "p"), 
        # add F, df1, df2, p-value, and Rsq values
        c("Overall Model Fit", round(c(summary(mod_SAD_dist1$model1)$fstatistic[2], summary(mod_SAD_dist1$model1)$fstatistic[3], summary(mod_SAD_dist1$model1)$fstatistic[1], 
                pf(summary(mod_SAD_dist1$model1)$fstatistic[1], summary(mod_SAD_dist1$model1)$fstatistic[2], summary(mod_SAD_dist1$model1)$fstatistic[3],lower.tail=FALSE)), 5)), 
        # add R squared value
        c("R-squared", round(summary(mod_SAD_dist1$model1)$r.squared, 5), rep(c(""), 3))
        )

# rename rows
rownames(mod_SAD_dist_t) <- c(1:7, " ", 8:9)

# Print table using kable
kable(mod_SAD_dist_t, caption = "Summary of moderation analysis with IV: Smartphone Location and M: Distractibility.", align = 'rcccc', row.names = T, col.names = c(" ", "b", "SE", "t", "p")) %>%
  # footnote(general = "Interaction variables ") %>%
  pack_rows("Moderator", 1, 1) %>%
  pack_rows("IV: Smartphone Location", 2, 4) %>%
  pack_rows("Interactions: Moderator x IV", 5, 7) %>%
  pack_rows(" ", 8, 10, indent = F) %>%
  pack_rows("Model", 8, 10) %>% 
  row_spec(0, bold = T, italic = T) %>%
  row_spec(8, bold = T, italic = T) %>%
  column_spec(2, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of moderation analysis with IV: Smartphone Location and M: Distractibility.
b SE t p
Moderator
1 Distractibility 0.31015 0.57377 0.54054 0.58915
IV: Smartphone Location
2 Desk vs. Pocket/Bag 1.18539 2.09766 0.5651 0.57235
3 Desk vs. Outside 0.82823 2.13942 0.38713 0.69888
4 Outside vs. Pocket/Bag 0.35716 2.11276 0.16905 0.86585
Interactions: Moderator x IV
5 Dist x DvPB 0.14489 0.85393 0.16967 0.86536
6 Dist x DvO -0.21229 0.80601 -0.26339 0.7924
7 Dist x OvPB 0.35718 0.84878 0.42082 0.67413
Model
df1 df2 F p
8 Overall Model Fit 5 369 0.22999 0.94932
9 R-squared 0.00311
Age

For age the moderator, IV, and interactions were not significant.

# create data frame with model values -- all values rounded to 5 decimals
  # note: you can see non-formatted model summary using "summary(mod_SUQ_age1$model1)" or "summary(mod_SUQ_age2$model1)"
mod_SUQ_age_t <- 
  # add b estimate, se, t, p
  rbind(data.frame("var" = c("Age", "Desk vs. Pocket/Bag", "Desk vs. Outside", "Outside vs. Pocket/Bag", 
                                   "Age x DvPB", "Age x DvO", "Age x OvPB"), 
                   "b" = round(c(mod_SUQ_age1$model1$coefficients[2:4], mod_SUQ_age2$model1$coefficients[3], mod_SUQ_age1$model1$coefficients[5:6],
                                 mod_SUQ_age2$model1$coefficients[5]), 5), 
                   "se" = round(c(summary(mod_SUQ_age1$model1)$coefficients[2:4,2], summary(mod_SUQ_age2$model1)$coefficients[3,2], 
                                  summary(mod_SUQ_age1$model1)$coefficients[5:6,2], summary(mod_SUQ_age2$model1)$coefficients[5,2]), 5), 
                   "t" = round(c(summary(mod_SUQ_age1$model1)$coefficients[2:4,3], summary(mod_SUQ_age2$model1)$coefficients[3,3], 
                                 summary(mod_SUQ_age1$model1)$coefficients[5:6,3], summary(mod_SUQ_age2$model1)$coefficients[5,3]), 5),
                   "p" = round(c(summary(mod_SUQ_age1$model1)$coefficients[2:4,4], summary(mod_SUQ_age2$model1)$coefficients[3,4], 
                                 summary(mod_SUQ_age1$model1)$coefficients[5:6,4], summary(mod_SUQ_age2$model1)$coefficients[5,4]), 5)
                         ), 
        # add labels for: F, df1, df2, p-value, and Rsq values
        c(" ", "df1", "df2", "F", "p"), 
        # add F, df1, df2, p-value, and Rsq values
        c("Overall Model Fit", round(c(summary(mod_SUQ_age1$model1)$fstatistic[2], summary(mod_SUQ_age1$model1)$fstatistic[3], summary(mod_SUQ_age1$model1)$fstatistic[1], 
                pf(summary(mod_SUQ_age1$model1)$fstatistic[1], summary(mod_SUQ_age1$model1)$fstatistic[2], summary(mod_SUQ_age1$model1)$fstatistic[3],lower.tail=FALSE)), 5)), 
        # add R squared value
        c("R-squared", round(summary(mod_SUQ_age1$model1)$r.squared, 5), rep(c(""), 3))
        )

# rename rows
rownames(mod_SUQ_age_t) <- c(1:7, " ", 8:9)

# Print table using kable
kable(mod_SUQ_age_t, caption = "Summary of moderation analysis with IV: Smartphone Location and M: Age", align = 'rcccc', row.names = T, col.names = c(" ", "b", "SE", "t", "p")) %>%
  # footnote(general = "Interaction variables ") %>%
  pack_rows("Moderator", 1, 1) %>%
  pack_rows("IV: Smartphone Location", 2, 4) %>%
  pack_rows("Interactions: Moderator x IV", 5, 7) %>%
  pack_rows(" ", 8, 10, indent = F) %>%
  pack_rows("Model", 8, 10) %>% 
  row_spec(0, bold = T, italic = T) %>%
  row_spec(8, bold = T, italic = T) %>%
  column_spec(2, bold = T) %>%
  kable_styling(bootstrap_options = "striped", "hover", full_width = F) %>%
  kable_classic()
Summary of moderation analysis with IV: Smartphone Location and M: Age
b SE t p
Moderator
1 Age -1.97546 1.77501 -1.11293 0.26647
IV: Smartphone Location
2 Desk vs. Pocket/Bag 1.55526 2.09747 0.74149 0.45887
3 Desk vs. Outside 1.00269 2.12117 0.47271 0.6367
4 Outside vs. Pocket/Bag 0.55256 2.09603 0.26362 0.79222
Interactions: Moderator x IV
5 Age x DvPB 0.02068 2.28762 0.00904 0.99279
6 Age x DvO -0.64199 2.32517 -0.2761 0.78263
7 Age x OvPB 0.66267 2.08285 0.31815 0.75055
Model
df1 df2 F p
8 Overall Model Fit 5 364 1.30937 0.25925
9 R-squared 0.01767
Simple Slopes
Dependence
Click to see output for simple slopes, including generated interpretations.
# summary of SS
lapply(mod_SAD_dep1$slopemodels, summary)
$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.098 -12.254   2.744  12.939  33.977 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    41.2565     1.5256  27.042   <2e-16 ***
SAD_dep_score   0.3082     0.3056   1.008    0.315    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.12 on 124 degrees of freedom
Multiple R-squared:  0.008133,  Adjusted R-squared:  0.0001336 
F-statistic: 1.017 on 1 and 124 DF,  p-value: 0.3153


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.272 -10.501   2.114  11.969  33.403 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    42.0059     1.4226  29.528   <2e-16 ***
SAD_dep_score  -0.0964     0.3266  -0.295    0.768    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.19 on 128 degrees of freedom
Multiple R-squared:  0.0006804, Adjusted R-squared:  -0.007127 
F-statistic: 0.08715 on 1 and 128 DF,  p-value: 0.7683


$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.257 -11.025   1.474  12.455  32.589 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.31547    1.49293  28.344   <2e-16 ***
SAD_dep_score  0.07667    0.33836   0.227    0.821    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.27 on 118 degrees of freedom
Multiple R-squared:  0.0004349, Adjusted R-squared:  -0.008036 
F-statistic: 0.05135 on 1 and 118 DF,  p-value: 0.8211
lapply(mod_SAD_dep2$slopemodels, summary)
$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.257 -11.025   1.474  12.455  32.589 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.31547    1.49293  28.344   <2e-16 ***
SAD_dep_score  0.07667    0.33836   0.227    0.821    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.27 on 118 degrees of freedom
Multiple R-squared:  0.0004349, Adjusted R-squared:  -0.008036 
F-statistic: 0.05135 on 1 and 118 DF,  p-value: 0.8211


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.272 -10.501   2.114  11.969  33.403 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    42.0059     1.4226  29.528   <2e-16 ***
SAD_dep_score  -0.0964     0.3266  -0.295    0.768    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.19 on 128 degrees of freedom
Multiple R-squared:  0.0006804, Adjusted R-squared:  -0.007127 
F-statistic: 0.08715 on 1 and 128 DF,  p-value: 0.7683


$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.098 -12.254   2.744  12.939  33.977 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    41.2565     1.5256  27.042   <2e-16 ***
SAD_dep_score   0.3082     0.3056   1.008    0.315    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.12 on 124 degrees of freedom
Multiple R-squared:  0.008133,  Adjusted R-squared:  0.0001336 
F-statistic: 1.017 on 1 and 124 DF,  p-value: 0.3153
# generated interpretations
cat(mod_SAD_dep1$interpretation)
At desk levels of location_desk, you see that every unit increase in SAD_dep_score predicts 0.31 unit change in ospan_absolute_score. 

At pocketbag levels of location_desk, you see that every unit increase in SAD_dep_score predicts -0.1 unit change in ospan_absolute_score. 

At outside levels of location_desk, you see that every unit increase in SAD_dep_score predicts 0.08 unit change in ospan_absolute_score. 
cat(mod_SAD_dep2$interpretation)
At outside levels of location_out, you see that every unit increase in SAD_dep_score predicts 0.08 unit change in ospan_absolute_score. 

At pocketbag levels of location_out, you see that every unit increase in SAD_dep_score predicts -0.1 unit change in ospan_absolute_score. 

At desk levels of location_out, you see that every unit increase in SAD_dep_score predicts 0.31 unit change in ospan_absolute_score. 
Emotional Attachment
Click to see output for simple slopes, including generated interpretations.
# summary of SS
lapply(mod_SAD_ea1$slopemodels, summary)
$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.524 -13.081   2.847  13.190  33.219 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   41.2539     1.5288  26.984   <2e-16 ***
SAD_ea_score  -0.6285     0.3247  -1.936   0.0551 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.23 on 125 degrees of freedom
Multiple R-squared:  0.02911,   Adjusted R-squared:  0.02134 
F-statistic: 3.748 on 1 and 125 DF,  p-value: 0.05513


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.552 -11.348   2.237  10.927  33.927 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.0528     1.4290  29.428   <2e-16 ***
SAD_ea_score  -0.3099     0.2886  -1.074    0.285    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.3 on 129 degrees of freedom
Multiple R-squared:  0.00886,   Adjusted R-squared:  0.001177 
F-statistic: 1.153 on 1 and 129 DF,  p-value: 0.2849


$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.385 -10.609   2.391  13.346  33.660 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  41.52341    1.52544   27.22   <2e-16 ***
SAD_ea_score -0.02242    0.32127   -0.07    0.944    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.69 on 119 degrees of freedom
Multiple R-squared:  4.091e-05, Adjusted R-squared:  -0.008362 
F-statistic: 0.004868 on 1 and 119 DF,  p-value: 0.9445
lapply(mod_SAD_ea2$slopemodels, summary)
$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.385 -10.609   2.391  13.346  33.660 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  41.52341    1.52544   27.22   <2e-16 ***
SAD_ea_score -0.02242    0.32127   -0.07    0.944    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.69 on 119 degrees of freedom
Multiple R-squared:  4.091e-05, Adjusted R-squared:  -0.008362 
F-statistic: 0.004868 on 1 and 119 DF,  p-value: 0.9445


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.552 -11.348   2.237  10.927  33.927 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.0528     1.4290  29.428   <2e-16 ***
SAD_ea_score  -0.3099     0.2886  -1.074    0.285    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.3 on 129 degrees of freedom
Multiple R-squared:  0.00886,   Adjusted R-squared:  0.001177 
F-statistic: 1.153 on 1 and 129 DF,  p-value: 0.2849


$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-40.524 -13.081   2.847  13.190  33.219 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   41.2539     1.5288  26.984   <2e-16 ***
SAD_ea_score  -0.6285     0.3247  -1.936   0.0551 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.23 on 125 degrees of freedom
Multiple R-squared:  0.02911,   Adjusted R-squared:  0.02134 
F-statistic: 3.748 on 1 and 125 DF,  p-value: 0.05513
# generated interpretations
cat(mod_SAD_ea1$interpretation)
At desk levels of location_desk, you see that every unit increase in SAD_ea_score predicts -0.63 unit change in ospan_absolute_score. 

At pocketbag levels of location_desk, you see that every unit increase in SAD_ea_score predicts -0.31 unit change in ospan_absolute_score. 

At outside levels of location_desk, you see that every unit increase in SAD_ea_score predicts -0.02 unit change in ospan_absolute_score. 
cat(mod_SAD_ea2$interpretation)
At outside levels of location_out, you see that every unit increase in SAD_ea_score predicts -0.02 unit change in ospan_absolute_score. 

At pocketbag levels of location_out, you see that every unit increase in SAD_ea_score predicts -0.31 unit change in ospan_absolute_score. 

At desk levels of location_out, you see that every unit increase in SAD_ea_score predicts -0.63 unit change in ospan_absolute_score. 
Accessibility
Click to see output for simple slopes, including generated interpretations.
# summary of SS
lapply(mod_SAD_access1$slopemodels, summary)
$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.917 -13.277   2.962  13.682  35.282 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)       40.9536     1.5324  26.725   <2e-16 ***
SAD_access_score  -0.3199     0.4059  -0.788    0.432    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.13 on 123 degrees of freedom
Multiple R-squared:  0.005023,  Adjusted R-squared:  -0.003066 
F-statistic: 0.621 on 1 and 123 DF,  p-value: 0.4322


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-38.320  -9.685   0.977  12.046  34.572 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)       41.9552     1.4344  29.249   <2e-16 ***
SAD_access_score   0.2972     0.4134   0.719    0.474    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.37 on 129 degrees of freedom
Multiple R-squared:  0.00399,   Adjusted R-squared:  -0.003731 
F-statistic: 0.5168 on 1 and 129 DF,  p-value: 0.4735


$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.643 -10.609   2.457  13.324  33.691 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      41.47118    1.53100  27.088   <2e-16 ***
SAD_access_score -0.03342    0.44437  -0.075     0.94    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.8 on 119 degrees of freedom
Multiple R-squared:  4.754e-05, Adjusted R-squared:  -0.008355 
F-statistic: 0.005657 on 1 and 119 DF,  p-value: 0.9402
lapply(mod_SAD_access2$slopemodels, summary)
$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.643 -10.609   2.457  13.324  33.691 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      41.47118    1.53100  27.088   <2e-16 ***
SAD_access_score -0.03342    0.44437  -0.075     0.94    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.8 on 119 degrees of freedom
Multiple R-squared:  4.754e-05, Adjusted R-squared:  -0.008355 
F-statistic: 0.005657 on 1 and 119 DF,  p-value: 0.9402


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-38.320  -9.685   0.977  12.046  34.572 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)       41.9552     1.4344  29.249   <2e-16 ***
SAD_access_score   0.2972     0.4134   0.719    0.474    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.37 on 129 degrees of freedom
Multiple R-squared:  0.00399,   Adjusted R-squared:  -0.003731 
F-statistic: 0.5168 on 1 and 129 DF,  p-value: 0.4735


$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.917 -13.277   2.962  13.682  35.282 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)       40.9536     1.5324  26.725   <2e-16 ***
SAD_access_score  -0.3199     0.4059  -0.788    0.432    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.13 on 123 degrees of freedom
Multiple R-squared:  0.005023,  Adjusted R-squared:  -0.003066 
F-statistic: 0.621 on 1 and 123 DF,  p-value: 0.4322
# generated interpretations
cat(mod_SAD_access1$interpretation)
At desk levels of location_desk, you see that every unit increase in SAD_access_score predicts -0.32 unit change in ospan_absolute_score. 

At pocketbag levels of location_desk, you see that every unit increase in SAD_access_score predicts 0.3 unit change in ospan_absolute_score. 

At outside levels of location_desk, you see that every unit increase in SAD_access_score predicts -0.03 unit change in ospan_absolute_score. 
cat(mod_SAD_access2$interpretation)
At outside levels of location_out, you see that every unit increase in SAD_access_score predicts -0.03 unit change in ospan_absolute_score. 

At pocketbag levels of location_out, you see that every unit increase in SAD_access_score predicts 0.3 unit change in ospan_absolute_score. 

At desk levels of location_out, you see that every unit increase in SAD_access_score predicts -0.32 unit change in ospan_absolute_score. 
Distractibility
Click to see output for simple slopes, including generated interpretations.
# summary of SS
lapply(mod_SAD_dist1$slopemodels, summary)
$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.832 -12.090   3.393  13.307  33.928 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     40.7987     1.5357  26.567   <2e-16 ***
SAD_dist_score   0.3101     0.5865   0.529    0.598    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.06 on 122 degrees of freedom
Multiple R-squared:  0.002287,  Adjusted R-squared:  -0.005891 
F-statistic: 0.2796 on 1 and 122 DF,  p-value: 0.5979


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.386 -10.727   1.659  12.069  33.069 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     41.9841     1.4292  29.376   <2e-16 ***
SAD_dist_score   0.4550     0.6174   0.737    0.462    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.29 on 128 degrees of freedom
Multiple R-squared:  0.004226,  Adjusted R-squared:  -0.003554 
F-statistic: 0.5432 on 1 and 128 DF,  p-value: 0.4624


$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-38.420 -10.713   1.993  12.993  33.287 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)    41.62692    1.52668  27.266   <2e-16 ***
SAD_dist_score  0.09785    0.56734   0.172    0.863    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.73 on 119 degrees of freedom
Multiple R-squared:  0.0002499, Adjusted R-squared:  -0.008151 
F-statistic: 0.02975 on 1 and 119 DF,  p-value: 0.8634
lapply(mod_SAD_dist2$slopemodels, summary)
$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-38.420 -10.713   1.993  12.993  33.287 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)    41.62692    1.52668  27.266   <2e-16 ***
SAD_dist_score  0.09785    0.56734   0.172    0.863    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.73 on 119 degrees of freedom
Multiple R-squared:  0.0002499, Adjusted R-squared:  -0.008151 
F-statistic: 0.02975 on 1 and 119 DF,  p-value: 0.8634


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.386 -10.727   1.659  12.069  33.069 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     41.9841     1.4292  29.376   <2e-16 ***
SAD_dist_score   0.4550     0.6174   0.737    0.462    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.29 on 128 degrees of freedom
Multiple R-squared:  0.004226,  Adjusted R-squared:  -0.003554 
F-statistic: 0.5432 on 1 and 128 DF,  p-value: 0.4624


$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-39.832 -12.090   3.393  13.307  33.928 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     40.7987     1.5357  26.567   <2e-16 ***
SAD_dist_score   0.3101     0.5865   0.529    0.598    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 17.06 on 122 degrees of freedom
Multiple R-squared:  0.002287,  Adjusted R-squared:  -0.005891 
F-statistic: 0.2796 on 1 and 122 DF,  p-value: 0.5979
# generated interpretations
cat(mod_SAD_dist1$interpretation)
At desk levels of location_desk, you see that every unit increase in SAD_dist_score predicts 0.31 unit change in ospan_absolute_score. 

At pocketbag levels of location_desk, you see that every unit increase in SAD_dist_score predicts 0.46 unit change in ospan_absolute_score. 

At outside levels of location_desk, you see that every unit increase in SAD_dist_score predicts 0.1 unit change in ospan_absolute_score. 
cat(mod_SAD_dist2$interpretation)
At outside levels of location_out, you see that every unit increase in SAD_dist_score predicts 0.1 unit change in ospan_absolute_score. 

At pocketbag levels of location_out, you see that every unit increase in SAD_dist_score predicts 0.46 unit change in ospan_absolute_score. 

At desk levels of location_out, you see that every unit increase in SAD_dist_score predicts 0.31 unit change in ospan_absolute_score. 
Age
Click to see output for simple slopes, including generated interpretations.
# summary of SS
lapply(mod_SUQ_age1$slopemodels, summary)
$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.173 -11.941   2.803  11.827  34.803 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   40.683      1.550  26.254   <2e-16 ***
age           -1.975      1.833  -1.078    0.283    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.98 on 120 degrees of freedom
Multiple R-squared:  0.00959,   Adjusted R-squared:  0.001337 
F-statistic: 1.162 on 1 and 120 DF,  p-value: 0.2832


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-35.758 -10.474   0.788  10.936  33.242 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.238      1.369   30.86   <2e-16 ***
age           -1.955      1.348   -1.45     0.15    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 15.36 on 124 degrees of freedom
Multiple R-squared:  0.01668,   Adjusted R-squared:  0.008746 
F-statistic: 2.103 on 1 and 124 DF,  p-value: 0.1495


$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.042 -11.409   1.341  11.980  36.575 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   41.686      1.547  26.940   <2e-16 ***
age           -2.617      1.550  -1.688    0.094 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.98 on 120 degrees of freedom
Multiple R-squared:  0.0232,    Adjusted R-squared:  0.01506 
F-statistic:  2.85 on 1 and 120 DF,  p-value: 0.09398
lapply(mod_SUQ_age2$slopemodels, summary)
$outside

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-41.042 -11.409   1.341  11.980  36.575 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   41.686      1.547  26.940   <2e-16 ***
age           -2.617      1.550  -1.688    0.094 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.98 on 120 degrees of freedom
Multiple R-squared:  0.0232,    Adjusted R-squared:  0.01506 
F-statistic:  2.85 on 1 and 120 DF,  p-value: 0.09398


$pocketbag

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-35.758 -10.474   0.788  10.936  33.242 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   42.238      1.369   30.86   <2e-16 ***
age           -1.955      1.348   -1.45     0.15    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 15.36 on 124 degrees of freedom
Multiple R-squared:  0.01668,   Adjusted R-squared:  0.008746 
F-statistic: 2.103 on 1 and 124 DF,  p-value: 0.1495


$desk

Call:
lm(formula = eqsim, data = finaldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.173 -11.941   2.803  11.827  34.803 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   40.683      1.550  26.254   <2e-16 ***
age           -1.975      1.833  -1.078    0.283    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.98 on 120 degrees of freedom
Multiple R-squared:  0.00959,   Adjusted R-squared:  0.001337 
F-statistic: 1.162 on 1 and 120 DF,  p-value: 0.2832
# generated interpretations
cat(mod_SUQ_age1$interpretation)
At desk levels of location_desk, you see that every unit increase in age predicts -1.98 unit change in ospan_absolute_score. 

At pocketbag levels of location_desk, you see that every unit increase in age predicts -1.95 unit change in ospan_absolute_score. 

At outside levels of location_desk, you see that every unit increase in age predicts -2.62 unit change in ospan_absolute_score. 
cat(mod_SUQ_age2$interpretation)
At outside levels of location_out, you see that every unit increase in age predicts -2.62 unit change in ospan_absolute_score. 

At pocketbag levels of location_out, you see that every unit increase in age predicts -1.95 unit change in ospan_absolute_score. 

At desk levels of location_out, you see that every unit increase in age predicts -1.98 unit change in ospan_absolute_score. 
Visualizations

The visualizations below are presented either in panel form (i.e., with all plots presented together) or separate.

Separate

Dependence was not a significant moderator for OSpan absolute score. No notable trends in the data were observed.

mod_SAD_dep_bar_data <- 
  mod_SAD_dep1$datascreening$fulldata %>% 
  # remove rows w/ outlier ps
  filter(totalout != 2) %>% 
  # select the data we want: IV, DV, M
  select(ospan_absolute_score, SAD_dep_score, location_desk) %>% 
  # replace moderator score with mean-centered
  mutate(SAD_dep_score = c(scale(SAD_dep_score, center = TRUE, scale = FALSE)))

mod_SAD_dep_bar <- ggplot(mod_SAD_dep_bar_data, aes(x = SAD_dep_score, y = ospan_absolute_score, color = location_desk)) +
  geom_point()+
  geom_smooth(method = lm, aes(fill = location_desk)) + 
  coord_cartesian(xlim = c(min(mod_SAD_dep_bar_data$SAD_dep_score), max(mod_SAD_dep_bar_data$SAD_dep_score)), 
                  ylim = c(min(mod_SAD_dep_bar_data$ospan_absolute_score), max(mod_SAD_dep_bar_data$ospan_absolute_score))) +
  labs(title = "Moderating OSpan Absolute Score with Dependence", 
       x = "Dependence", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       caption = "Note: Smartphone dependency is mean-centered."
       ) +
  scale_fill_manual(values = c("lightseagreen", "purple3", "deepskyblue4")) +
  scale_colour_manual(values = c("lightseagreen", "purple4", "deepskyblue4")) +
  theme_classic()

#show fig
mod_SAD_dep_bar
`geom_smooth()` using formula 'y ~ x'

# export plot
# ggsave(filename="fig_mod_SAD_dep_bar_june14", plot = mod_SAD_dep_bar, device = "png", height = 5, width = 8, units = "in", dpi = 500)

Emotional Attachment was not a significant moderator for OSpan absolute score. A notable trend in the data was observed, where participants with less emotional attachment showed better OSpan performance in the on desk condition. The outside condition showed the same but smaller trned. The pocket/bag condition did not show this trend as the slope were closer to zero.

mod_SAD_ea_bar_data <- 
  mod_SAD_ea1$datascreening$fulldata %>% 
  # remove rows w/ outlier ps
  filter(totalout != 2) %>% 
  # select the data we want: IV, DV, M
  select(ospan_absolute_score, SAD_ea_score, location_desk) %>% 
  # replace moderator score with mean-centered
  mutate(SAD_ea_score = c(scale(SAD_ea_score, center = TRUE, scale = FALSE)))

mod_SAD_ea_bar <- ggplot(mod_SAD_ea_bar_data, aes(x = SAD_ea_score, y = ospan_absolute_score, color = location_desk)) +
  geom_point()+
  geom_smooth(method = lm, aes(fill = location_desk)) + 
  coord_cartesian(xlim = c(min(mod_SAD_ea_bar_data$SAD_ea_score), max(mod_SAD_ea_bar_data$SAD_ea_score)), 
                  ylim = c(min(mod_SAD_ea_bar_data$ospan_absolute_score), max(mod_SAD_ea_bar_data$ospan_absolute_score))) +
  labs(title = "Moderating OSpan Absolute Score with Emotional Attachment", 
       x = "Emotional Attachment", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       caption = "Note: Smartphone Emotional Attachment is mean-centered."
       ) +
  scale_fill_manual(values = c("lightseagreen", "purple3", "deepskyblue4")) +
  scale_colour_manual(values = c("lightseagreen", "purple4", "deepskyblue4")) +
  theme_classic()

#show fig
mod_SAD_ea_bar
`geom_smooth()` using formula 'y ~ x'

# export plot
# ggsave(filename="fig_mod_SAD_ea_bar_june14", plot = mod_SAD_ea_bar, device = "png", height = 5, width = 8, units = "in", dpi = 500)

Accessibility was not a significant moderator for OSpan absolute score. No notable trends in the data were observed.

mod_SAD_access_bar_data <- 
  mod_SAD_access1$datascreening$fulldata %>% 
  # remove rows w/ outlier ps
  filter(totalout != 2) %>% 
  # select the data we want: IV, DV, M
  select(ospan_absolute_score, SAD_access_score, location_desk) %>% 
  # replace moderator score with mean-centered
  mutate(SAD_access_score = c(scale(SAD_access_score, center = TRUE, scale = FALSE)))

mod_SAD_access_bar <- ggplot(mod_SAD_access_bar_data, aes(x = SAD_access_score, y = ospan_absolute_score, color = location_desk)) +
  geom_point()+
  geom_smooth(method = lm, aes(fill = location_desk)) + 
  coord_cartesian(xlim = c(min(mod_SAD_access_bar_data$SAD_access_score), max(mod_SAD_access_bar_data$SAD_access_score)), 
                  ylim = c(min(mod_SAD_access_bar_data$ospan_absolute_score), max(mod_SAD_access_bar_data$ospan_absolute_score))) +
  labs(title = "Moderating OSpan Absolute Score with Accessibility", 
       x = "Accessibility", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       caption = "Note: Accessibility is mean-centered."
       ) +
  scale_fill_manual(values = c("lightseagreen", "purple3", "deepskyblue4")) +
  scale_colour_manual(values = c("lightseagreen", "purple4", "deepskyblue4")) +
  theme_classic()

#show fig
mod_SAD_access_bar
`geom_smooth()` using formula 'y ~ x'

# export plot
# ggsave(filename="fig_mod_SAD_access_bar_june14", plot = mod_SAD_access_bar, device = "png", height = 5, width = 8, units = "in", dpi = 500)

Distractibility was not a significant moderator for OSpan absolute score. No notable trends in the data were observed.

mod_SAD_dist_bar_data <- 
  mod_SAD_dist1$datascreening$fulldata %>% 
  # remove rows w/ outlier ps
  filter(totalout != 2) %>% 
  # select the data we want: IV, DV, M
  select(ospan_absolute_score, SAD_dist_score, location_desk) %>% 
  # replace moderator score with mean-centered
  mutate(SAD_dist_score = c(scale(SAD_dist_score, center = TRUE, scale = FALSE)))

mod_SAD_dist_bar <- ggplot(mod_SAD_dist_bar_data, aes(x = SAD_dist_score, y = ospan_absolute_score, color = location_desk)) +
  geom_point()+
  geom_smooth(method = lm, aes(fill = location_desk)) + 
  coord_cartesian(xlim = c(min(mod_SAD_dist_bar_data$SAD_dist_score), max(mod_SAD_dist_bar_data$SAD_dist_score)), 
                  ylim = c(min(mod_SAD_dist_bar_data$ospan_absolute_score), max(mod_SAD_dist_bar_data$ospan_absolute_score))) +
  labs(title = "Moderating OSpan Absolute Score with Distractibility", 
       x = "Distractibility", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       caption = "Note: Smartphone Distractibility is mean-centered."
       ) +
  scale_fill_manual(values = c("lightseagreen", "purple3", "deepskyblue4")) +
  scale_colour_manual(values = c("lightseagreen", "purple4", "deepskyblue4")) +
  theme_classic()

#show fig
mod_SAD_dist_bar
`geom_smooth()` using formula 'y ~ x'

# export plot
# ggsave(filename="fig_mod_SAD_dist_bar_june14", plot = mod_SAD_dist_bar, device = "png", height = 5, width = 8, units = "in", dpi = 500)

Age was not a significant moderator for OSpan absolute score. A notable trend in the data was observed: for all location conditions, younger participants tended to show better task performance.

mod_SUQ_age_bar_data <- 
  mod_SUQ_age1$datascreening$fulldata %>% 
  # remove rows w/ outlier ps
  filter(totalout != 2) %>% 
  # select the data we want: IV, DV, M
  select(ospan_absolute_score, age, location_desk) %>% 
  # replace moderator score with mean-centered
  mutate(age = c(scale(age, center = TRUE, scale = FALSE)))

mod_SUQ_age_bar <- ggplot(mod_SUQ_age_bar_data, aes(x = age, y = ospan_absolute_score, color = location_desk)) +
  geom_point()+
  geom_smooth(method = lm, aes(fill = location_desk)) + 
  coord_cartesian(xlim = c(min(mod_SUQ_age_bar_data$age), max(mod_SUQ_age_bar_data$age)), 
                  ylim = c(min(mod_SUQ_age_bar_data$ospan_absolute_score), max(mod_SUQ_age_bar_data$ospan_absolute_score))) +
  labs(title = "Moderating OSpan Absolute Score with Age", 
       x = "Age (years)", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       caption = "Note: Age is mean-centered."
       ) +
  scale_fill_manual(values = c("lightseagreen", "purple3", "deepskyblue4")) +
  scale_colour_manual(values = c("lightseagreen", "purple4", "deepskyblue4")) +
  theme_classic()

#show fig
mod_SUQ_age_bar
`geom_smooth()` using formula 'y ~ x'

# export plot
# ggsave(filename="fig_mod_SUQ_age_bar", plot = mod_SUQ_age_bar, device = "png", height = 5, width = 8, units = "in", dpi = 500)
Panel
# create join data set with all moderator data
mod_all_data_plot <- 
  cbind(data.frame("moderator" = c(rep(1, nrow(mod_SAD_dep_bar_data)), rep(2, nrow(mod_SAD_ea_bar_data)), rep(3, nrow(mod_SAD_access_bar_data)), rep(4, nrow(mod_SAD_dist_bar_data)))), 
        rbind(
        # SAD_dep data
        mod_SAD_dep_bar_data %>% dplyr::rename(mod_score = SAD_dep_score), # rename column to join correctly
        mod_SAD_ea_bar_data %>% dplyr::rename(mod_score = SAD_ea_score), # rename column to join correctly
        mod_SAD_access_bar_data %>% dplyr::rename(mod_score = SAD_access_score), # rename column to join correctly
        mod_SAD_dist_bar_data %>% dplyr::rename(mod_score = SAD_dist_score) # rename column to join correctly
        )
        ) %>% 
  mutate(moderator = factor(moderator, levels = c(1:4), labels = c("(A) Dependency", "(B) Emotional Attachment", "(C) Accessibility", "(D) Distractibility"))) %>% 
  mutate(location_desk = factor(location_desk, labels = c("Desk", "Pocket/Bag", "Outside")))

glimpse(mod_all_data_plot)
Rows: 1,507
Columns: 4
$ moderator            <fct> (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A) Dependency, (A…
$ ospan_absolute_score <int> 38, 37, 28, 51, 37, 55, 29, 43, 29, 35, 46, 50, 39, 61, 13, 37, 61, 43, 24, 52, 8, 29, 62, 29, 34, 15, 68, 37, 37, 27, 55, 12, 55, 68, 48, 44, 48, 19, 15, 55, 10, 26, 61, 15, 52,…
$ mod_score            <dbl> -1.7579787, 4.2420213, -4.7579787, -1.7579787, -2.7579787, 0.2420213, 1.2420213, -2.7579787, -2.7579787, -1.7579787, 8.2420213, 0.2420213, 2.2420213, -2.7579787, 8.2420213, 4.242…
$ location_desk        <fct> Desk, Desk, Pocket/Bag, Desk, Desk, Pocket/Bag, Pocket/Bag, Outside, Outside, Desk, Desk, Pocket/Bag, Outside, Outside, Desk, Desk, Pocket/Bag, Outside, Desk, Pocket/Bag, Outside…
# create panel fig
mod_all_plot <-
  ggplot(mod_all_data_plot, aes(x = mod_score, y = ospan_absolute_score, group = location_desk)) +
  geom_point(stat = "identity", aes(shape = location_desk, color = location_desk), size = 1.5)+
  geom_smooth(method = lm, aes(fill = location_desk, color = location_desk), size = 1) + 
  labs(
    # title = "Moderating OSpan Absolute Score",
       x = "Mean-Centered Score", 
       y = "OSpan Absolute Score", 
       color = "Smartphone Location",
       fill = "Smartphone Location",
       shape = "Smartphone Location") +
  facet_wrap(~moderator, ncol = 2) +
  scale_fill_manual(values = c("#18BAB3", "#62129B", "#007298")) +
  scale_colour_manual(values = c("#18BAB3", "#62129B", "#007298")) +
  scale_y_continuous(limits = c(0, 75), breaks = c(seq(0,75, 25))) + 
  theme_classic() +
  theme(legend.position = "bottom")
  

# show plot
mod_all_plot
`geom_smooth()` using formula 'y ~ x'

# export plots
# ggsave(filename="fig_mod_all_plot_june16", plot = mod_all_plot, device = "jpeg", height = 5, width = 8, units = "in", dpi = 1000)
LS0tCnRpdGxlOiAnUmVleGFtaW5pbmcgdGhlIOKAnEJyYWluIERyYWlu4oCdIEVmZmVjdDogRG9lcyBXYXJkIGV0IGFsLiAoMjAxNykgcmVwbGljYXRlPycKYXV0aG9yOiAiQS4gQy4gUnVpeiBQYXJkbyBhbmQgIERyLiBKLiBQLiBNaW5kYSIKZGF0ZTogIk9jdG9iZXIgMTUsIDIwMjEiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzYnCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogeWVzCiAgICB0aGVtZTogbHVtZW4KICAgIGNvZGVfZm9sZGluZzogaGlkZQogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc2JwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnNicKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB5ZXMKICAgIHRoZW1lOiBsdW1lbgogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKYGBgez1odG1sfQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoKYm9keXsgLyogTm9ybWFsICAqLwogICAgICBmb250LXNpemU6IDE1cHg7CiAgICAgIGNvbG9yOiBibGFjazt9CnRkIHsgIC8qIFRhYmxlICAqLwogIGZvbnQtc2l6ZTogMTRweDt9CmgxLnRpdGxlIHsKICBmb250LXNpemU6IDQwcHg7CiAgY29sb3I6ICM0RjI2ODN9CmgxIHsgLyogSGVhZGVyIDEgKi8KICBmb250LXNpemU6IDM1cHg7CiAgY29sb3I6ICM0RjI2ODM7fQpoMiB7IC8qIEhlYWRlciAyICovCiAgZm9udC1zaXplOiAzM3B4OwogIGNvbG9yOiAjNEYyNjgzO30KaDMgeyAvKiBIZWFkZXIgMyAqLwogIGZvbnQtc2l6ZTogMzFweDsKICBjb2xvcjogIzRGMjY4Mzt9Cmg0IHsgLyogSGVhZGVyIDQgKi8KICBmb250LXNpemU6IDI5cHg7CiAgY29sb3I6ICM0RjI2ODM7fQpoNSB7IC8qIEhlYWRlciA1ICovCiAgZm9udC1zaXplOiAyN3B4OwogIGNvbG9yOiAjNEYyNjgzO30KaDYgeyAvKiBIZWFkZXIgNiAqLwogIGZvbnQtc2l6ZTogMjVweDsKICBjb2xvcjogIzRGMjY4Mzt9Cgo8L3N0eWxlPgpgYGAKPGRpdiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdCI+CgpgYGB7ciBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSkKYGBgCgojIEludHJvZHVjdGlvbiAKClRoaXMgZG9jdW1lbnQgb3V0bGluZXMgdGhlIGFuYWx5c2VzIGZyb20gdGhlIHBhcGVyICoqUmVleGFtaW5pbmcgdGhlICJCcmFpbiBEcmFpbiIgRWZmZWN0OiBEb2VzIFdhcmQgZXQgYWwuICgyMDE3KSByZXBsaWNhdGU/KiogKFJ1aXogUGFyZG8gJiBNaW5kYSwgT2N0IDIwMjEgcHJlcHJpbnQsIDxodHRwczovL3BzeWFyeGl2LmNvbS81eTM0Zy8+KS4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBzdHVkeSB3YXMgdG8gaW52ZXN0aWdhdGUgV2FyZCBldCBhbC4ncyAoMjAxNykgc2Vjb25kIGV4cGVyaW1lbnQgYnkgY29tcGxldGluZyBhIGRpcmVjdCByZXBsaWNhdGlvbi4gVGhlcmVmb3JlLCB0aGUgcHJlc2VudCBzdHVkeSBpbnZlc3RpZ2F0ZWQgaG93IHRoZSBtZXJlIHByZXNlbmNlIG9mIG9uZSdzIHNtYXJ0cGhvbmUgZWZmZWN0cyBjb2duaXRpb24uIFRoaXMgcHJvamVjdCBjYW4gYmUgZm91bmQgb24gT1NGICg8aHR0cHM6Ly9vc2YuaW8vdWJ5czcvPikgYW5kIHdhcyBwcmUtcmVnaXN0ZXJlZCB0aHJvdWdoIE9TRiAoPGh0dHBzOi8vb3NmLmlvLzVmcTRyPikgLgoKVGhlIG1haW4gZ29hbCBvZiB0aGUgY3VycmVudCBzdHVkeSB3YXMgdG8gc2VlIGlmIFdhcmQgZXQgYWwuJ3MgZmluZGluZ3MgcmVwbGljYXRlZCAoZXhwZXJpbWVudCB0d28pLiBUaGVyZWZvcmUsIGFzIGluIFdhcmQgZXQgYWwuLCBwYXJ0aWNpcGFudHMgd2VyZSByYW5kb21seSBhc3NpZ25lZCB0byBvbmUgb2YgKnNpeCogcG9zc2libGUgY29uZGl0aW9ucy4gVGhlc2UgY29uZGl0aW9ucyB3ZXJlIGJhc2VkIG9uIHR3byBpbmRlcGVuZGVudCB2YXJpYWJsZXM6ICoqc21hcnRwaG9uZSBsb2NhdGlvbioqIGFuZCAqKnNtYXJ0cGhvbmUgcG93ZXIqKi4gRm9yIHNtYXJ0cGhvbmUgbG9jYXRpb24sIGEgcGFydGljaXBhbnQncyBzbWFydHBob25lIHdhcyBpbiBvbmUgb2YgdGhyZWUgbG9jYXRpb25zOiAoMSkgb24gdGhlIHBhcnRpY2lwYW50J3MgZGVzayAoIm9uIGRlc2siKSwgKDIpIGluIHRoZWlyIHBvY2tldC9iYWcgKCJwb2NrZXQvYmFnIiksIG9yICgzKSBvdXRzaWRlIHRoZSB0ZXN0aW5nIHJvb20gKCJvdXRzaWRlIikuIEZvciBzbWFydHBob25lIHBvd2VyLCBhIHBhcnRpY2lwYW50J3Mgc21hcnRwaG9uZSB3YXMgZWl0aGVyICgxKSBwb3dlcmVkIE9OIG9yICgyKSBwb3dlcmVkIE9GRiwgaW4gdGhlaXIgcmVzcGVjdGl2ZSBsb2NhdGlvbi4gRm9yIGFsbCBjb25kaXRpb25zLCBwYXJ0aWNpcGFudHMgd2VyZSBpbnN0cnVjdGVkIHRvIGtlZXAgdGhlaXIgc21hcnRwaG9uZXMgb24gc2lsZW50IChpLmUuLCBubyB2aWJyYXRpb25zIGlmIGFueSBub3RpZmljYXRpb25zIGFyZSByZWNlaXZlZCBkdXJpbmcgdGhlIHN0dWR5KS4gQWxzbywgYXMgcGVyIFdhcmQgZXQgYWwuLCBwYXJ0aWNpcGFudHMgaW4gdGhlICJvbiBkZXNrIiBsb2NhdGlvbiBjb25kaXRpb25zIHdlcmUgaW5zdHJ1Y3RlZCB0byBrZWVwIHRoZWlyIGRldmljZXMgZmFjaW5nIHVwLgoKRWFjaCBwYXJ0aWNpcGFudCBjb21wbGV0ZWQgKip0d28gbWFpbiB0YXNrcyoqIChjb3VudGVyLWJhbGFuY2VkKToKCioqMS4gQW4gQXV0b21hdGVkIE9wZXJhdGlvbiBTcGFuIChPU3BhbikgVGFzayoqIChVbnN3b3J0aCBldCBhbC4sIDIwMDUpLCB3aGljaCByZXF1aXJlZCBwYXJ0aWNpcGFudHMgdG8gcmV0YWluIGxldHRlciBzdHJpbmdzIChpLmUuLCByYW5naW5nIGZyb20gdGhyZWUgdG8gc2V2ZW4gbGV0dGVycyBpbiBsZW5ndGgpIGluIG1lbW9yeSB3aGlsZSBzb2x2aW5nIHNvbWUgc2ltcGxlIG1hdGggcHJvYmxlbXMgKGUuZy4sICIoNy83KSArIDYgPSA/IikuIFRoaXMgdGFzayB3YXMgYSBiZWhhdmlvdXJhbCBtZWFzdXJlIG9mIHRoZSBhdHRlbnRpb25hbCBjb250cm9sIGNvbXBvbmVudCBvZiB3b3JraW5nIG1lbW9yeS4KCi0gICBTY29yaW5nOgoKICAgIC0gICBQZXJmb3JtYW5jZSwgbWVhc3VyZWQgd2l0aCB0aGUgT1NwYW4gYWJzb2x1dGUgc2NvcmUsIHdhcyBzaG93biBieSBob3cgbWFueSB0cmlhbHMgYSBwYXJ0aWNpcGFudCBjb3JyZWN0bHkgcmVjYWxsZWQgYWxsIHRoZSBsZXR0ZXJzIGluIGEgZ2l2ZW4gYmxvY2sgKDc1IGJsb2NrcyBpbiB0b3RhbCkuIEZvciBleGFtcGxlLCBhIHBhcnRpY2lwYW50IHdobyByZWNhbGxlZCB0aHJlZSBsZXR0ZXJzIChpbiBhIGJsb2NrIHdpdGggdGhyZWUgbGV0dGVycyksIGZpdmUgbGV0dGVycyAoaW4gYSBibG9jayB3aXRoIGZpdmUgbGV0dGVycyksIGFuZCB0d28gbGV0dGVycyAoaW4gYSBibG9jayB3aXRoIHNpeCBsZXR0ZXJzKSB3b3VsZCBoYXZlIGFuIE9TcGFuIGFic29sdXRlIHNjb3JlIG9mIGVpZ2h0IGZvciB0aG9zZSBibG9ja3MgKGkuZS4sIDMgKyA1ICsgMCA9IDgpLiBUaGVyZWZvcmUsIE9TcGFuIGFic29sdXRlIHNjb3JlIHNob3dlZCBwZXJmb3JtYW5jZSB3aGVyZSBoaWdoZXIgc2NvcmVzIHJlcHJlc2VudGVkIGJldHRlciBwZXJmb3JtYW5jZS4KCioqMi4gVGhlIEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzayoqIChCZXpkamlhIGV0IGFsLiwgMjAwOSksIHdoaWNoIHJlcXVpcmVkIHBhcnRpY2lwYW50cyB0byByZXNwb25kIHRvICJnbyIgdGFyZ2V0cyAoaS5lLiwgZ3JlZW4gcmVjdGFuZ2xlKSB3aGlsZSB3aXRoaG9sZGluZyBhbnkgcmVzcG9uc2UgdG8gIm5vLWdvIiB0YXJnZXRzIChpLmUuIGJsdWUgcmVjdGFuZ2xlKS4gVGhpcyB0YXNrIGluY2x1ZGVkIGEgY3VlIGNvbXBvbmVudCwgd2hlcmUgdmVydGljYWwgdGFyZ2V0cyAoaS5lLiwgcmVjdGFuZ2xlcykgd2VyZSBtb3JlIGxpa2VseSB0byBiZSAiZ28iIHRhcmdldHMgKGkuZS4sIDgwJSAiZ28iIGFuZCAyMCUgIm5vLWdvIikgYW5kIGhvcml6b250YWwgdGFyZ2V0cyB3ZXJlIG1vcmUgbGlrZWx5IHRvIGJlICJuby1nbyIgdGFyZ2V0cyAoaS5lLiwgODAlICJuby1nbyIgYW5kIDIwJSAiZ28iKS4gUGFydGljaXBhbnRzIHdlcmUgbm90IGV4cGxpY2l0bHkgbWFkZSBhd2FyZSBvZiB0aGUgY3VlIGNvbXBvbmVudC4gVGhpcyB0YXNrIHdhcyBhIGJlaGF2aW91cmFsIG1lYXN1cmUgb2Ygc3VzdGFpbmVkIGF0dGVudGlvbi4KCi0gICBTY29yaW5nOgoKICAgIC0gICBQZXJmb3JtYW5jZSB3YXMgbWVhc3VyZWQgd2l0aCBtZWFuIG9taXNzaW9uIGVycm9ycyBhbmQgUlQuIEl0IHNob3VsZCBiZSBub3RlZCB0aGF0IG1lYW4gZXJyb3JzIGNhbiBiZSBkaXZpZGVkIGludG8gdG90YWwgZXJyb3IsIGNvbW1pc3Npb24gZXJyb3IsIGFuZCBvbWlzc2lvbiBlcnJvci4gQ29tbWlzc2lvbiBlcnJvcnMgb2NjdXJyZWQgd2hlbiBhIHBhcnRpY2lwYW50IHJlc3BvbmRlZCB0byBhIHRhcmdldCBzdGltdWx1cy4gT21pc3Npb24gZXJyb3JzIG9jY3VycmVkIHdoZW4gYSBwYXJ0aWNpcGFudCBmYWlsZWQgdG8gcmVzcG9uZCB0byBhIG5vbi10YXJnZXQgc3RpbXVsdXMuIFRvdGFsIGVycm9ycyB3ZXJlIHRoZSBzdW0gb2YgY29tbWlzc2lvbiBhbmQgb21pc3Npb24gZXJyb3JzLiBUaGUgcHJlc2VudCBzdHVkeSBmb2N1c2VkIG9uIG1lYW4gb21pc3Npb24gZXJyb3JzLiBUaGVyZWZvcmUsIGZvciBlYWNoIHBhcnRpY2lwYW50LCBoaWdoZXIgbWVhbiBvbWlzc2lvbiBlcnJvcnMgcmVwcmVzZW50ZWQgbG93ZXIgcGVyZm9ybWFuY2UuIEFkZGl0aW9uYWxseSwgaGlnaGVyIG1lYW4gUlQgYWxzbyBzaG93ZWQgbG93ZXIgcGVyZm9ybWFuY2UgKGkuZS4sIGluZGljYXRpdmUgb2YgZ3JlYXRlciBpbnRlcmZlcmVuY2UpLgoKRmluYWxseSwgYWZ0ZXIgY29tcGxldGluZyBib3RoIHRhc2tzLCBhbGwgcGFydGljaXBhbnRzIGNvbXBsZXRlZCAqKnRocmVlKiogc3VydmV5IG1lYXN1cmVzOgoKKioxLiBUaGUgRGVtb2dyYXBoaWMgUXVlc3Rpb25uYWlyZSoqLCB3aGljaCB3YXMgY3JlYXRlZCBmb3IgdGhlIHByZXNlbnQgc3R1ZHkgYW5kIGNvbnNpc3RlZCBvZiBmb3VyIGl0ZW1zOiBhZ2UgKGkuZS4sIGluIHllYXJzKSwgZ2VuZGVyIChpLmUuLCBtYWxlLCBmZW1hbGUsIG90aGVyLCBvciBwcmVmZXIgbm90IHRvIHNheSksIHByb2dyYW0gKGUuZy4sIHBzeWNob2xvZ3ksIGVuZ2luZWVyaW5nKSwgYW5kIHllYXIgb2Ygc3R1ZHkgKGUuZy4sIGZpcnN0LCBmb3VydGgpLiBUaGUgcHVycG9zZSBvZiB0aGVzZSBpdGVtcyB3YXMgdG8gZ2l2ZSBhIGJyaWVmIGRlc2NyaXB0aW9uIG9mIHRoZSBzYW1wbGUuCgoqKjIuIFRoZSBTbWFydHBob25lIFVzYWdlIFF1ZXN0aW9ubmFpcmUgKFNVUSkqKiwgd2hpY2ggd2FzIGNyZWF0ZWQgZm9yIHRoZSBwcmVzZW50IHN0dWR5IGFuZCBjb25zaXN0ZWQgb2YgbW9kaWZpZWQgaXRlbXMgZnJvbSBXYXJkIGV0IGFsLidzIHN1cnZleSBtZWFzdXJlcyAoaS5lLiwgZm91bmQgaW4gdGhlICJCUkFJTiBEUkFJTiIgV0VCIEFQUEVORElYIikuIFNvbWUgaXRlbXMgd2VyZSBmb3JjZWQtY2hvaWNlIGFuZCBzb21lIHdlcmUgb24gYSA3LXBvaW50IGxpa2VydCBzY2FsZSByYW5naW5nIGZyb20gMSAoIk5ldmVyIikgdG8gNyAoIkFsd2F5cyIpLiBUaGVyZSB3ZXJlIDEwIGl0ZW1zIGluIHRvdGFsIGFuZCB0aGVyZSB3ZXJlIGZpdmUgdHlwZXMgb2YgaXRlbXMsIHdoaWNoIG1lYXN1cmVkOiAoMSkgc21hcnRwaG9uZSB1c2UgZnJlcXVlbmN5ICh0aHJlZSBpdGVtczsgZS5nLiwgIk9uIGF2ZXJhZ2UsIGhvdyBtYW55IHRleHQgbWVzc2FnZXMgZG8geW91IHNlbmQgcGVyIGRheT8iKTsgKDIpIHNtYXJ0cGhvbmUgdXNlIHdpdGhvdXQgZXh0ZXJuYWwgc3RpbXVsYXRpb24gKHR3byBpdGVtczsgZS5nLiwgIklmIEkgYW0gd2FpdGluZyB0byBtZWV0IGEgZnJpZW5kLCBJIHBhc3MgdGhlIHRpbWUgYnkgdXNpbmcgbXkgc21hcnRwaG9uZS4iKSwgb3IgZHVyaW5nIG90aGVyIGFjdGl2aXRpZXMgKHR3byBpdGVtczsgZS5nLiwgIkkgdXNlIG15IHNtYXJ0cGhvbmUgd2hpbGUgZHJpdmluZy4iKTsgKDMpIHNtYXJ0cGhvbmUgc3ViamVjdGl2ZSB2YWx1ZSAob25lIGl0ZW07IGUuZy4sICJIb3cgbXVjaCBtb25leSB3b3VsZCBpdCB0YWtlIGZvciB5b3UgdG8gZ2l2ZSB1cCB5b3VyIHBob25lIGZvciBhIGZ1bGwgZGF5PyIpOyAoNCkgc21hcnRwaG9uZSBub3RpZmljYXRpb24gdHlwZSAob25lIGl0ZW07IGUuZy4sICJEbyB5b3UgcmVjZWl2ZSBub3RpZmljYXRpb25zIChhIHNvdW5kIG9yIHZpYnJhdGlvbikgb24geW91ciBwaG9uZT8gUGxlYXNlIGluZGljYXRlIGFsbCB0aGF0IGFwcGx5LiIpOyBhbmQgKDUpIHBoYW50b20gdmlicmF0aW9ucyAob25lIGl0ZW07IGUuZy4sICJIYXZlIHlvdSBldmVyIHRob3VnaHQgeW91IGhlYXJkIHlvdXIgcGhvbmUgcmluZyBvciB0aG91Z2h0IHlvdSBmZWx0IGl0IHZpYnJhdGUsIG9ubHkgdG8gZmluZCBvdXQgeW91IHdlcmUgd3Jvbmc/IikuIFRoZSBwdXJwb3NlIG9mIHRoZSBTVVEgd2FzIHRvIG1lYXN1cmUgcGFydGljaXBhbnRzJyB0eXBpY2FsIHNtYXJ0cGhvbmUgdXNlLgoKKiozLiBTbWFydHBob25lIEF0dGFjaG1lbnQgYW5kIERlcGVuZGVuY3kgSW52ZW50b3J5IChTQUQpKiosIHdoaWNoIHdhcyBmcm9tIFdhcmQgZXQgYWwuJ3MgKDIwMTcpIHN0dWR5LiBUaGUgU0FEIHVzZWQgMTMtaXRlbXMgKGkuZS4sIDctcG9pbnQgbGlrZXJ0IHNjYWxlKSB0aGF0IGFza2VkIHBhcnRpY2lwYW50cyB0byByYXRlIChpLmUuLCBmcm9tIDEgPSAqU3Ryb25nbHkgRGlzYWdyZWUqIHRvIDcgPSAqU3Ryb25nbHkgQWdyZWUqKSBob3cgbXVjaCB0aGV5IGFncmVlZCB3aXRoIHN0YXRlbWVudHMgcmVnYXJkaW5nIHRoZWlyIGVtb3Rpb25hbCBhdHRhY2htZW50IGFuZCBkZXBlbmRlbmN5IG9uIHRoZWlyIHNtYXJ0cGhvbmVzLiBUaGUgcHVycG9zZSBvZiB0aGUgU0FEIHdhcyB0byBtZWFzdXJlIGVhY2ggcGFydGljaXBhbnQncyByZWxpYW5jZSBvbiB0aGVpciBzbWFydHBob25lLgoKLSAgIFNjb3Jpbmc6CgogICAgLSAgIFNtYXJ0cGhvbmUgcmVsaWFuY2Ugd2FzIGNhbGN1bGF0ZWQgd2l0aCBhIHN1bSB0b3RhbCBmb3IgYWxsIGl0ZW1zIHdpdGggYSByYW5nZSBvZiAxMyB0byA5MS4gSGlnaGVyIHNjb3JlcyBpbmRpY2F0ZWQgYSBoaWdoZXIgbGV2ZWwgb2YgcmVsaWFuY2Ugd2l0aCB0aHJlZSBsZXZlbHM6IGxvdyByZWxpYW5jZSAoMTMtMzkpLCBtb2RlcmF0ZSByZWxpYW5jZSAoNDAtNjUpLCBhbmQgaGlnaCByZWxpYW5jZSAoNjYrKS4KCkEgdG90YWwgb2YgKipgciBsZW5ndGgoYWxsX3BhcnRpY2lwYW50cyRhbGxfcGFydGljaXBhbnRzKWAqKiB1bmRlcmdyYWR1YXRlIHN0dWRlbnRzIHBhcnRpY2lwYXRlZCBpbiB0aGlzIHN0dWR5LiBPZiB0aGUgdG90YWwgc2FtcGxlIHNpemUsIGByIGxlbmd0aChhbGxfcmVtb3ZlJGFsbF9wYXJ0aWNpcGFudHMpYCBwYXJ0aWNpcGFudHMgd2VyZSBleGNsdWRlZCBkdWUgdG8gZWl0aGVyIHRlc3RpbmcgZXJyb3IgKGByIGxlbmd0aChhbGxfcmVtb3ZlJGFsbF9wYXJ0aWNpcGFudHNbd2hpY2goYWxsX3JlbW92ZSRyZWFzb25fcmVtb3ZlID09ICJnbmciKV0pYDsgZS5nLiwgaW5jb21wbGV0ZSB0YXNrIGRhdGEpLCBvciBleHBlcmltZW50ZXIgb3IgZXh0ZXJuYWwgY29uZm91bmRzIChgciBsZW5ndGgoYWxsX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzW3doaWNoKGFsbF9yZW1vdmUkcmVhc29uX3JlbW92ZSA9PSAidHJhY2siKV0pYDsgZS5nLiwgaW50ZXJydXB0aW9uIGR1cmluZyB0ZXN0aW5nLCBkaXN0cmFjdGluZyBub2lzZSBkdXJpbmcgdGVzdGluZykuIEFkZGl0aW9uYWxseSwgYHIgbGVuZ3RoKGFsbF9yZW1vdmVfZGNfbGlzdCRwYXJ0aWNpcGFudClgIHBhcnRpY2lwYW50cyB3ZXJlIHJlbW92ZWQgZHVyaW5nIHRoZSBkYXRhIGNsZWFuaW5nIHBoYXNlLCB3aGljaCByZW1vdmVkIHBhcnRpY2lwYW50cyB3aG8gbWV0IGFuIGV4Y2x1c2lvbiBjcml0ZXJpYSAoT1NwYW4gbWF0aCBjcml0ZXJpYTogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJvc3Bhbl9lYyIpYDsgR28vTm8tR28gcmVzcG9uc2UgY3JpdGVyaWEsIGhvcml6b250YWwvbm8tZ28gY3VlOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19oX2VjIilgOyBHby9Oby1HbyByZXNwb25zZSBjcml0ZXJpYSwgdmVydGljYWwvZ28gY3VlOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ192X2VjIilgKSwgd2VyZSBpZGVudGlmaWVkIGFzIGhhdmluZyBvdXRsaWVyIGRhdGEgKE9TcGFuOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gIm9zcGFuX291dCIpYDsgR28vTm8tR28gRXJyb3IgQW5hbHlzaXM6IGByIHN1bShhbGxfcmVtb3ZlX2RjJHJlYXNvbiA9PSAiZ25nX2Vycl9vdXQiKWA7IEdvL05vLUdvIEFjY3VyYWN5IEFuYWx5c2lzOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19hY19vdXQiKWApLCBhbmQgaGFkIGluY29tcGxldGUgb3IgbWlzc2luZyBkYXRhIChPU3BhbjogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJvc3Bhbl9taXNzIilgOyBHby9Oby1HbyBFcnJvciBBbmFseXNpczogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJnbmdfZXJyX21pc3MiKWA7IEdvL05vLUdvIEFjY3VyYWN5IEFuYWx5c2lzOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19hY19taXNzIilgKS4gT3ZlcmFsbCwgKipgciBucm93KGFsbF9wYXJ0aWNpcGFudHMpIC0gbnJvdyhhbGxfZGF0YSlgKiogcGFydGljaXBhbnRzIHdlcmUgcmVtb3ZlZCBmcm9tIHRoZSBhbmFseXNpcy4gTm90ZTogYSBwYXJ0aWNpcGFudCBtYXkgaGF2ZSBiZWVuIHJlbW92ZWQgZHVlIHRvIG11bHRpcGxlIGNyaXRlcmlhLgoKVGhlcmVmb3JlLCAqKmByIGxlbmd0aChhbGxfZGF0YSRwYXJ0aWNpcGFudClgKiogcGFydGljaXBhbnRzIHdlcmUgaW5jbHVkZWQgaW4gdGhlIGFuYWx5c2VzIGZvciB0aGUgbG9jYXRpb24gKG9uIGRlc2sgPSBgciBsZW5ndGgod2hpY2goYWxsX2RhdGEkbG9jYXRpb24gPT0gMSkpYDsgcG9ja2V0L2JhZyA9IGByIGxlbmd0aCh3aGljaChhbGxfZGF0YSRsb2NhdGlvbiA9PSAyKSlgOyBvdXRzaWRlID0gYHIgbGVuZ3RoKHdoaWNoKGFsbF9kYXRhJGxvY2F0aW9uID09IDMpKWApIGFuZCBwb3dlciAoT04gPSBgciBsZW5ndGgod2hpY2goYWxsX2RhdGEkcG93ZXIgPT0gMSkpYDsgT0ZGID0gYHIgbGVuZ3RoKHdoaWNoKGFsbF9kYXRhJHBvd2VyID09IDIpKWApIGNvbmRpdGlvbi4KCiMgRGF0YSBBbmFseXNpcyBQbGFuCgpUaGUgcHJlc2VudCBzdHVkeSBjb21wbGV0ZWQgYSBwcmUtcmVnaXN0ZXJlZCBkYXRhIGFuYWx5c2lzIChwcmUtcmVnaXN0ZXJlZCBkaXJlY3QgcmVwbGljYXRpb24gb24gT3BlbiBTY2llbmNlIEZyYW1ld29yazsgT1NGKS4gQmVsb3cgaXMgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhIGFuYWx5c2lzIHBsYW4gKHZpZXcgZnVsbCB2ZXJzaW9uIGF0IDxodHRwczovL29zZi5pby81ZnE0cj4gb3IgPGh0dHBzOi8vb3NmLmlvL3VieXM3Lz4pLgoKIyMgSHlwb3RoZXNlcwoKMS4gIFRoZSAqKmxvY2F0aW9uIGVmZmVjdCBoeXBvdGhlc2lzKiogcHJlZGljdGVkIHRoYXQgdGhvc2Ugd2hvIHdlcmUgY2xvc2VzdCBpbiBwcm94aW1pdHkgdG8gdGhlaXIgc21hcnRwaG9uZSAoaS5lLiwgdGhvc2Ugd2l0aCB0aGVpciBzbWFydHBob25lcyBvbiB0aGVpciBkZXNrKSB3b3VsZCBzaG93IGxvd2VyIHBlcmZvcm1hbmNlIG9uIHRoZSBPU3BhbiB0YXNrLgoKMi4gIFRoZSAqKnBvd2VyIGVmZmVjdCBoeXBvdGhlc2lzKiogcHJlZGljdGVkIHRoYXQgc21hcnRwaG9uZSBwb3dlciAoaS5lLiwgZWl0aGVyIE9OIG9yIE9GRikgd291bGQgbm90IGFmZmVjdCBwZXJmb3JtYW5jZSBvbiBib3RoIGNvZ25pdGl2ZSB0YXNrcy4KCjMuICBUaGUgKiptb2RlcmF0aW9uIGVmZmVjdCBoeXBvdGhlc2lzKiogcHJlZGljdGVkIHRoYXQgc21hcnRwaG9uZSBhdHRhY2htZW50IGFuZCBkZXBlbmRlbmN5IChpLmUuLCBTQUQgc2NvcmUpIHdvdWxkIG1vZGVyYXRlIHRoZSBsb2NhdGlvbiBlZmZlY3Q6IHRob3NlIHdobyByZXBvcnRlZCBoaWdoZXIgc21hcnRwaG9uZSBhdHRhY2htZW50IGFuZCBkZXBlbmRlbmN5IHdvdWxkIHBlcmZvcm0gd29yc2Ugb24gdGhlIE9TcGFuIHRhc2suCgoqTm90ZTogQWxsIGh5cG90aGVzZXMgd2VyZSBiYXNlZCBvbiB0aGUgZmluZGluZ3MgZnJvbSBXYXJkIGV0IGFsLiAoMjAxNykqCgojIyBJbmNsdXNpb24gLyBFeGNsdXNpb24gQ3JpdGVyaWEKClRoZXJlIHdlcmUgKip0d28qKiBleGNsdXNpb24gY3JpdGVyaWEgaW4gdGhlIHByZXNlbnQgc3R1ZHk6CgoqKjEuIE9TcGFuIFRhc2sqKgoKLSAgIE9ubHkgZGF0YSBmcm9tIHBhcnRpY2lwYW50cyB3aG8gc2NvcmVkIDg1JSBhY2N1cmFjeSBvbiB0aGUgbWF0aCBjb21wb25lbnQgb3IgYWJvdmUgd2FzIHVzZWQuCgogICAgLSAgIENyaXRlcmlhIGhlbHBlZCBjb250cm9sIGZvciBhbnkgcGFydGljaXBhbnRzIHdobyBkaWQgbm90IGZvbGxvdyBpbnN0cnVjdGlvbnMgYW5kIG5lZ2xlY3RlZCB0aGUgbWF0aCBjb21wb25lbnQgb2YgdGhlIHRhc2suICpOb3RlOiBUaGlzIHdhcyB0aGUgc2FtZSBjcml0ZXJpYSBhcyBpbiBXYXJkIGV0IGFsLiAoMjAxNykqCgoqKjIuIEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzayoqCgotICAgT25seSBkYXRhIGZyb20gdGhvc2Ugd2hvIHNjb3JlZCBoaWdoZXIgdGhhbiBjaGFuY2UgcGVyZm9ybWFuY2Ugd2FzIHVzZWQgKGUuZy4sIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2YgIkdvIiB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiAiTm8tR28iIHRyaWFscykuCgogICAgLSAgIENyaXRlcmlhIGhlbHBlZCBjb250cm9sIGZvciBhbnkgcGFydGljaXBhbnRzIHdobyBkaWQgbm90IGNvbXBsZXRlIHRoZSB0YXNrIGFzIGluc3RydWN0ZWQgKGUuZy4sIGd1ZXNzaW5nKS4gKk5vdGU6IFRoZXJlIHdhcyBubyBpbmNsdXNpb24vZXhjbHVzaW9uIGNyaXRlcmlhIGZvciB0aHNpIHRhc2sgaW4gV2FyZCBldCBhbC4gKDIwMTcpKgoKIyMgQW5hbHlzaXMKCiMjIyBUZXN0aW5nIHRoZSBMb2NhdGlvbiBhbmQgUG93ZXIgSHlwb3RoZXNlczoKCioqMS4gT1NwYW4gVGFzayoqCgotICAgVGhlIE9TcGFuIGFic29sdXRlIHNjb3JlIHdhcyB1c2VkIHRvIG1lYXN1cmUgT1NwYW4gcGVyZm9ybWFuY2UuCgotICAgQSAqKjMoc21hcnRwaG9uZSBsb2NhdGlvbjogZGVzaywgcG9ja2V0L2JhZywgb3V0c2lkZSkgeCAyKHNtYXJ0cGhvbmUgcG93ZXI6IE9OLCBPRkYpKiogYmV0d2Vlbi1zdWJqZWN0cyBBTk9WQSB3YXMgY29uZHVjdGVkICoqKERWID0gT1NwYW4gYWJzb2x1dGUgc2NvcmUpKiouCgogICAgLSAgIFBvc3QtaG9jcyBjb21wbGV0ZWQgaWYgdGhlcmUgd2FzIGEgc2lnbmlmaWNhbnQgQU5PVkEgKCRcYWxwaGEgPSAwLjA1JCkgdG8gZGV0ZXJtaW5lIHdoaWNoIGxvY2F0aW9uKHMpIGFuZC9vciBwb3dlciBzdGF0dXMgd2VyZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudC4KCioqMi4gQ3VlLURlcGVuZGVudCBHby9Oby1HbyBUYXNrKioKCi0gICBBbiBlcnJvciAoaS5lLiwgb21pc3Npb24gZXJyb3JzKSBhbmQgYWNjdXJhY3kgKGkuZS4sIFJUKSBhbmFseXNpcyB3YXMgY29tcGxldGVkIHVzaW5nIHRoZSBhdmVyYWdlIG9taXNzaW9uIGVycm9ycyBhbmQgUlQgZm9yIGVhY2ggcGFydGljaXBhbnQuCgogICAgKiooYSkgRXJyb3IgQW5hbHlzaXMqKgoKICAgIC0gICBBICoqMyhTbWFydHBob25lIGxvY2F0aW9uOiBkZXNrLCBwb2NrZXQvYmFnLCBvdXRzaWRlKSB4IDIoU21hcnRwaG9uZSBwb3dlcjogT04sIE9GRikgeCAyKEN1ZSB0eXBlOiBHbywgTm8tR28pIG1peGVkIEFOT1ZBKiogd2FzIGNvbXBsZXRlZCAqKihEViA9IGF2ZXJhZ2Ugb21pc3Npb24gZXJyb3IocykpKiouCgogICAgICAgIC0gICBUaGUgYmV0d2Vlbi1zdWJqZWN0cyBmYWN0b3JzOnNtYXJ0cGhvbmUgbG9jYXRpb24gYW5kIHBvd2VyXAogICAgICAgIC0gICBUaGUgd2l0aGluLXN1YmplY3RzIGZhY3RvcjogcHJlLXRhcmdldCBjdWUgdHlwZVwKICAgICAgICAtICAgUG9zdC1ob2NzIGNvbXBsZXRlZCBpZiB0aGVyZSB3YXMgYSBzaWduaWZpY2FudCBBTk9WQSAoJFxhbHBoYSA9IDAuMDUkKSB0byBkZXRlcm1pbmUgd2hpY2ggbG9jYXRpb24ocyksIHBvd2VyIHN0YXR1cywgYW5kL29yIGN1ZSB0eXBlKHMpIHdlcmUgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQuCgogICAgKiooYikgQWNjdXJhY3kgQW5hbHlzaXMqKgoKICAgIC0gICBBICoqMyhzbWFydHBob25lIGxvY2F0aW9uOiBkZXNrLCBwb2NrZXQvYmFnLCBvdXRzaWRlKSB4IDIoc21hcnRwaG9uZSBwb3dlcjogT04sIE9GRikqKiBiZXR3ZWVuLXN1YmplY3RzIEFOT1ZBIHdhcyBjb25kdWN0ZWQgKiooRFYgPSBhdmVyYWdlIFJUKSoqLgoKICAgICAgICAtICAgVGhlIGJldHdlZW4tc3ViamVjdHMgZmFjdG9yczpzbWFydHBob25lIGxvY2F0aW9uIGFuZCBwb3dlclwKICAgICAgICAtICAgVGhlIHdpdGhpbi1zdWJqZWN0cyBmYWN0b3I6IHByZS10YXJnZXQgY3VlIHR5cGVcCiAgICAgICAgLSAgIFBvc3QtaG9jcyBjb21wbGV0ZWQgaWYgdGhlcmUgd2FzIGEgc2lnbmlmaWNhbnQgQU5PVkEgKCRcYWxwaGEgPSAwLjA1JCkgdG8gZGV0ZXJtaW5lIHdoaWNoIGxvY2F0aW9uKHMpIGFuZC9vciBwb3dlciBzdGF0dXMgd2VyZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudC4KCiMjIyBUZXN0aW5nIHRoZSBNb2RlcmF0aW9uIEh5cG90aGVzaXM6CgoqKjMuIFNBRCoqCgoqKihhKSBGYWN0b3IgQW5hbHlzaXMqKgoKLSAgIEEgcHJpbmNpcGFsIGNvbXBvbmVudHMgZmFjdG9yIGFuYWx5c2lzIHdpdGggYSBWYXJpbWF4IHJvdGF0aW9uIHdhcyBjb21wbGV0ZWQgZm9yIHBhcnRpY2lwYW50J3MgU0FEIHNjb3JlLgoKICAgIC0gICBUaGlzIHdhcyBkb25lIHRvIGNvbmZpcm0gdGhlIHR3byBtYWluIGZhY3RvcnMgZm91bmQgYnkgV2FyZCBldCBhbC4gKDIwMTcpOiBzbWFydHBob25lIGRlcGVuZGVuY2UgYW5kIGVtb3Rpb25hbCBhdHRhY2htZW50LgoKKiooYikgR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVsKioKCi0gICBBIHVuaXZhcmlhdGUgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVsIHdhcyB1c2VkIHRvIGV4YW1pbmUgaWYgc21hcnRwaG9uZSByZWxpYW5jZSAoaS5lLiwgU0FEIHNjb3JlKSB3YXMgYSBtb2RlcmF0b3Igb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBleHBlcmltZW50YWwgbWFuaXB1bGF0aW9uIGFuZCB0YXNrIHBlcmZvcm1hbmNlLgoKKk5vdGU6IFRoZXNlIGFuYWx5c2lzIHdlcmUgY29tcGxldGVkIHJlZ2FyZGxlc3Mgb2YgdGhlIHJlc3VsdHMgZm9yIHRoZSBsb2NhdGlvbiBhbmQgcG93ZXIgaHlwb3RoZXNlcy4qCgojIyBSZWZlcmVuY2VzCgotIEJlemRqaWFuLCBTLiwgQmFrZXIsIEwuIEEuLCBMb3phbm8sIEQuIEkuLCAmIFJhaW5lLCBBLiAoMjAwOSkuIEFzc2Vzc2luZyBpbmF0dGVudGlvbiBhbmQgaW1wdWxzaXZpdHkgaW4gY2hpbGRyZW4gZHVyaW5nIHRoZSBHby9Ob0dvIHRhc2suIFRoZSBCcml0aXNoIEpvdXJuYWwgb2YgRGV2ZWxvcG1lbnRhbCBQc3ljaG9sb2d5LCAyNygyKSwgMzY14oCTMzgzLiA8aHR0cHM6Ly9kb2kub3JnLzEwLjEzNDgvMDI2MTUxMDA4WDMxNDkxOT4KLSBQZWlyY2UsIEouIFcuICgyMDA3KS4gUHN5Y2hvUHnigJRQc3ljaG9waHlzaWNzIHNvZnR3YXJlIGluIFB5dGhvbi4gSm91cm5hbCBvZiBOZXVyb3NjaWVuY2UgTWV0aG9kcywgMTYyKDEpLCA44oCTMTMuIDxodHRwczovL2RvaS5vcmcvMTAuMTAxNi9qLmpuZXVtZXRoLjIwMDYuMTEuMDE3PgotIFJ1aXogUGFyZG8sIEEuIEMuLCAmIE1pbmRhLCBKLiBQLiAoMjAyMSkuIFJlZXhhbWluaW5nIHRoZSDigJxicmFpbiBkcmFpbuKAnSBlZmZlY3Q6IERvZXMgV2FyZCBldCBhbC4gKDIwMTcpIHJlcGxpY2F0ZT8gSW4gUHN5QXJYaXYuIFdlc3Rlcm4gVW5pdmVyc2l0eS4gPGh0dHBzOi8vZG9pLm9yZy8xMC4zMTIzNC9vc2YuaW8vNXkzNGc+Ci0gVW5zd29ydGgsIE4uLCBIZWl0eiwgUi4gUC4sIFNjaHJvY2ssIEouIEMuLCAmIEVuZ2xlLCBSLiBXLiAoMjAwNSkuIEFuIGF1dG9tYXRlZCB2ZXJzaW9uIG9mIHRoZSBvcGVyYXRpb24gc3BhbiB0YXNrLiBCZWhhdmlvciBSZXNlYXJjaCBNZXRob2RzLCAzNygzKSwgNDk44oCTNTA1LiA8aHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMTY0MDUxNDY+Ci0gV2FyZCwgQS4gRi4sIER1a2UsIEsuLCBHbmVlenksIEEuLCAmIEJvcywgTS4gVy4gKDIwMTcpLiBCcmFpbiBkcmFpbjogVGhlIG1lcmUgcHJlc2VuY2Ugb2Ygb25l4oCZcyBvd24gc21hcnRwaG9uZSByZWR1Y2VzIGF2YWlsYWJsZSBjb2duaXRpdmUgY2FwYWNpdHkuIEpvdXJuYWwgb2YgdGhlIEFzc29jaWF0aW9uIGZvciBDb25zdW1lciBSZXNlYXJjaCwgMiwgMTQw4oCTMTU0LiA8aHR0cHM6Ly9kb2kub3JnLzEwLjEwODYvNjkxNDYyPgoKIyBBbmFseXNpcyBQcmVwCgojIyBMb2FkIFJlcXVpcmVkIExpYnJhcmllcwoKVGhlIGZvbGxvd2luZyBwYWNrYWdlcyB3ZXJlIHVzZWQgdG8gY29tcGxldGUgdGhlIGFuYWx5c2VzLCB2aXN1YWxpemF0aW9ucywgZGF0YSB3cmFuZ2xpbmcsIGV0Yy4gaW4gdGhpcyBkb2N1bWVudC4KCmBgYHtyIGxvYWRfbGlicywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyBOb3RlOiBDb2RlIGhhcyBiZWVuIGNvbW1lbnRlZCBvdXQgdG8gcmVkdWNlIGNvbXB1dGF0aW9uIHRpbWUKCiMgbGlicmFyeSh3ZWxjaEFERikKbGlicmFyeShzY2hvUnNjaCkKbGlicmFyeShwbHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGxhdHRpY2UpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGdncGxvdDIpICMgdG8gcGxvdCBmaWd1cmVzCmxpYnJhcnkoZ2dwdWJyKSAjIHRvIHBsb3QgZmlndXJlcyAoZS5nLiwgcXFwbG90cykKbGlicmFyeShrYWJsZUV4dHJhKSAjIHRvIG1ha2UgbmljZSB0YWJsZXMKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShleikgIyB0byBydW4gQU5PVkFzCmxpYnJhcnkoSG1pc2MpCmxpYnJhcnkocHVycnIpCmxpYnJhcnkoRm9ybXVsYSkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoc3Vydml2YWwpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KERlc2NUb29scykKbGlicmFyeShHUEFyb3RhdGlvbikKbGlicmFyeShhcGFUYWJsZXMpCmxpYnJhcnkoc3RhdHMpICMgdG8gcGVyZm9ybSB0LXRlc3RzCmxpYnJhcnkoZWZmc2l6ZSkgIyB0byBjYWxjdWxhdGUgY29oZW4ncyBkIGVmZmVjdCBzaXplCmxpYnJhcnkoY29pbikgIyB0byBydW4gTWFubi1XaGl0bmV5IFUgdGVzdAojIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKbGlicmFyeShkZXZ0b29scykKIyBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImRvb21sYWIvTWVNb0Jvb3RSIikgIyBpbnN0YWxsIC0gdXNlZCB0byBydW4gbW9kZXJhdGlvbgpsaWJyYXJ5KE1lTW9Cb290UikgIyBmb3IgbW9kZXJhdGlvbgpsaWJyYXJ5KGdyaWRFeHRyYSkgIyB0byBwbG90IG11bHRpcGxlIHBsb3RzIHRvZ2V0aGVyCgpsaWJyYXJ5KGNvcnJwbG90KQoKIyBsaWJyYXJ5KHJzdGF0aXgpICMgdG8gcnVuIHQtdGVzdHMgd2l0aCBlYXN5IG91dHB1dCBmb3IgdmlzdWFsaXphdGlvbnMKIyBsaWJyYXJ5KHRpZHl1dGlscykKIyBsaWJyYXJ5KGRldnRvb2xzKQojIGluc3RhbGxfZ2l0aHViKCJ2cXYvZ2diaXBsb3QiKQojbGlicmFyeShnZ2JpcGxvdCkKIyBsaWJyYXJ5KHJtZGZvcm1hdHMpCmBgYAoKIyMgQWRkaXRpb25hbCBGdW5jdGlvbnMKCiMjIyBSb3VuZGluZyBwLXZhbHVlcwoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgcm91bmRpbmcgZnVuY3Rpb24gd2FzIGFkYXB0ZWQgZnJvbSBbRHIuIEVtaWx5IE5pZWxzZW4ncyBScHVic10oaHR0cHM6Ly9ycHVicy5jb20vZWduaWVsc2VuKS4gVGhlIGZ1bmN0aW9uICgiKipwX3JvdW5kKHgpKioiKSB3YXMgY3JlYXRlZCB0byBhc3Nlc3MgYW5kIHByaW50IHAtdmFsdWVzLiBJZiAkcCBcZ2UgLjAwNSQsIHRoZSBmdW5jdGlvbiB3aWxsIGRpc3BsYXkgIlwkcCA9IFwkIiBhbmQgdGhlIHZhbHVlIHJvdW5kZWQgdG8gdHdvIGRlY2ltYWwgcGxhY2VzLiBJZiBcJCAuMDAwNSBcbGUgcCBcPC4wMDUkLCB0aGUgZnVuY3Rpb24gd2lsbCBkaXNwbGF5IOKAnCRwID0gXCQiIGFuZCB0aGUgdmFsdWUgcm91bmRlZCB0byB0aHJlZSBkZWNpbWFsIHBsYWNlcy4gSWYgJHAgPCAuMDAwNSQsIHRoZSBmdW5jdGlvbiB3aWxsIGRpc3BsYXkgIiRwIDwgLjAwMSQiLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7ciBwX3JvdW5kIGZ1bmN0aW9ufQoKcF9yb3VuZCA8LSBmdW5jdGlvbih4KXsKICBpZih4ID4gLjAwNSkKICAgIHt4MSA9IChwYXN0ZSgiPSAiLCBnc3ViKCIwXFwuIiwiXFwuIiwgcm91bmQoeCwgZGlnaXRzID0gMikpLCBzZXAgPSAnJykpCiAgfSAgCiAgZWxzZSBpZih4ID09IC4wMDUpe3gxID0gKHBhc3RlKCI9IiwgZ3N1YigiMFxcLiIsIlxcLiIsIDAuMDEpKSkKICB9CiAgZWxzZSBpZih4ID4gLjAwMDUgJiB4IDwgLjAwNSkKICAgIHt4MSA9IChwYXN0ZSgiPSAiLCBnc3ViKCIwXFwuIiwiXFwuIiwgcm91bmQoeCwgZGlnaXRzID0gMykpLCBzZXAgPSAnJykpCiAgfSAgCiAgZWxzZSBpZih4ID09IC4wMDA1KXt4MSA9IChwYXN0ZSgiPSIsIGdzdWIoIjBcXC4iLCJcXC4iLCAwLjAwMSkpKQogIH0KICBlbHNle3gxID0gKHBhc3RlKCI8IiwgZ3N1YigiMFxcLiIsIlxcLiIsIDAuMDAxKSkpCiAgfSAKICAoeDEpCn0KCmBgYAoKPC9kZXRhaWxzPgoKIyMjIEZsYXR0ZW4gQ29ycmVsYXRpb24gT3V0cHV0CgpgYGB7ciBjcmVhdGVfZmxhdHRlbkNvcnJfZnVuY3Rpb259CiMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKwojIGZsYXR0ZW5Db3JyTWF0cml4CiMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKwojIGNvcm1hdCA6IG1hdHJpeCBvZiB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzCiMgcG1hdCA6IG1hdHJpeCBvZiB0aGUgY29ycmVsYXRpb24gcC12YWx1ZXMKZmxhdHRlbkNvcnJNYXRyaXggPC0gZnVuY3Rpb24oY29ybWF0LCBwbWF0KSB7CiAgdXQgPC0gdXBwZXIudHJpKGNvcm1hdCkKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoY29ybWF0KVtyb3coY29ybWF0KVt1dF1dLAogICAgY29sdW1uID0gcm93bmFtZXMoY29ybWF0KVtjb2woY29ybWF0KVt1dF1dLAogICAgY29yICA9KGNvcm1hdClbdXRdLAogICAgcCA9IHBtYXRbdXRdCiAgICApCn0KYGBgCgojIyBSYXcgRGF0YQoKVGhlcmUgYXJlICoqZml2ZSoqIHJhdyBkYXRhIGZpbGVzIHRoYXQgd2VyZSBpbXBvcnRlZCBmb3IgdGhlIHByZXNlbnQgc3R1ZHkgKHNlZSB0aGUgKkltcG9ydCBSYXcgRGF0YSogc2VjdGlvbikuCgoqKlRhc2sgRGF0YSoqCgoxLiAgT1NwYW4gUmF3IERhdGEKCiAgICAtICAgc3ByZWFkc2hlZXQsIGNvbGxlY3RlZCBtYW51YWxseSBmcm9tIGVhY2ggcGFydGljaXBhbnQKCjIuICBHby9Oby1HbyBSYXcgRGF0YQoKICAgIC0gICBwc3ljaG9weSBleGNlbCBmaWxlcwogICAgLSAgICpOb3RlOiogcmF3IGRhdGEgd2FzIGV4dHJhY3RlZCBmcm9tIGZvbGRlciBpbnRvIG9uZSBmaWxlIChzZWUgdGhlICpJbXBvcnQgUmF3IERhdGEqIHNlY3Rpb24pCgoqKlN1cnZleSBNZWFzdXJlcyoqCgozLiAgRGVtb2dyYXBoaWMgJiBTVVEgUmF3IERhdGEKCiAgICAtICAgY3N2IGZpbGVzIGV4cG9ydGVkIGZyb20gUXVhbHRyaWNzCgo0LiAgU0FEIFJhdyBEYXRhCgogICAgLSAgIGNzdiBmaWxlcyBleHBvcnRlZCBmcm9tIFF1YWx0cmljcwoKNS4gIFRlc3RpbmcgVHJhY2tpbmcgU2hlZXQKCiAgICAtICAgY3N2IGZpbGVzLCBjb2xsZWN0ZWQgZHVyaW5nIHRlc3RpbmcKCiMjIyBJbXBvcnQgUmF3IERhdGEKCiMjIyMgMS4gT1NwYW4gUmF3IERhdGEKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgKipPU3BhbiBSYXcgRGF0YSoqIHdhcyBjb2xsZWN0ZWQgdXNpbmcgdGhlIFtJbnF1aXNpdCA1IHNvZnR3YXJlXShodHRwczovL3d3dy5taWxsaXNlY29uZC5jb20vcHJvZHVjdHMvaW5xdWlzaXQ2L3dlYm92ZXJ2aWV3LmFzcHgpLCB3aGljaCB1c2VkIHRoZSBzYW1lIGF1dG9tYXRlZCBPU3BhbiB0YXNrIGFzIGluIFdhcmQgZXQgYWwuICgyMDE3KS4gVGhlIHJhdyBkYXRhIGZyb20gdGhlIE9TcGFuIHdhcyBpbXBvcnRlZCBhcyBhIGRhdGEgZnJhbWUsICIqKm9zcGFuX3JhdyoqIiwgYW5kIGluY2x1ZGVkIHRoZSBmb2xsb3dpbmc6ICooY2xpY2sgdG8gc2VlIGRlc2NyaXB0aW9uKSoKCjwvc3VtbWFyeT4KCi0gICAqKlBhcnRpY2lwYW50IG51bWJlciBbKm9zcGFuX3BhcnRpY2lwYW50Kl0qKlwKCi0gICAqKk9TcGFuIElEIFsqb3NwYW5fSUQqXSoqCgogICAgLSAgIEEgOS1kaWdpdCBJRCBnaXZlbiBieSB0aGUgSXF1aXNpdCA1IHNvZnR3YXJlCgotICAgKipPU3BhbiBBYnNvbHV0ZSBTY29yZSBbKm9zcGFuX2Fic29sdXRlX3Njb3JlKl0qKgoKICAgIC0gICBQZXJmb3JtYW5jZSBtZWFzdXJlZCBieSBob3cgbWFueSB0cmlhbHMgYSBwYXJ0aWNpcGFudCBjb3JyZWN0bHkgcmVjYWxsZWQgYWxsIHRoZSBsZXR0ZXJzIGluIGEgZ2l2ZW4gYmxvY2sgKDc1IGJsb2NrcyBpbiB0b3RhbCkuIEZvciBleGFtcGxlLCBhIHBhcnRpY2lwYW50IHdobyByZWNhbGxlZCB0aHJlZSBsZXR0ZXJzIChpbiBhIGJsb2NrIHdpdGggdGhyZWUgbGV0dGVycyksIGZpdmUgbGV0dGVycyAoaW4gYSBibG9jayB3aXRoIGZpdmUgbGV0dGVycyksIGFuZCB0d28gbGV0dGVycyAoaW4gYSBibG9jayB3aXRoIHNpeCBsZXR0ZXJzKSB3b3VsZCBoYXZlIGFuIE9TcGFuIGFic29sdXRlIHNjb3JlIG9mIGVpZ2h0IGZvciB0aG9zZSBibG9ja3MgKGkuZS4sIDMgKyA1ICsgMCA9IDgpLlwKCi0gICAqKlRvdGFsIExldHRlcnMgUmVjYWxsZWQgWypvc3Bhbl90b3RhbF9jb3JyKl0qKgoKICAgIC0gICBQZXJmb3JtYW5jZSBtZWFzdXJlZCBieSBob3cgbWFueSBsZXR0ZXJzIHdlcmUgcmVjYWxsZWQgaW4gdG90YWwsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBhbGwgbGV0dGVycyB3ZXJlIGNvcnJlY3Qgd2l0aGluIGEgZ2l2ZW4gYmxvY2suXAoKLSAgICoqVG90YWwgTWF0aCBFcnJvcnMgWypvc3Bhbl9tYXRoX2Vycl90b3QqXSoqCgogICAgLSAgIHRoZSBzdW0gb2YgYWxsIG1hdGggZXJyb3JzIChpLmUuLCBzcGVlZCBhbmQgYWNjdXJhY3kpXAoKLSAgICoqU3BlZWQgRXJyb3JzIFsqb3NwYW5fbWF0aF9lcnJfc3BlZWQqXSoqCgogICAgLSAgIHRoZSBzdW0gb2YgdGhlIHNwZWVkIHJlbGF0ZWQgbWF0aCBlcnJvcnMKCiAgICAgICAgLSAgIHdoZXJlIGEgcGFydGljaXBhbnQgZXhjZWVkZWQgdGhlaXIgdGltZSBsaW1pdCB0byByZXNwb25kIHRvIHRoZSBtYXRoIGNvbXBvbmVudCBvZiB0aGUgdGFza1wKCi0gICAqKkFjY3VyYWN5IEVycm9ycyBbKm9zcGFuX21hdGhfZXJyX2FjY3VyYWN5Kl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIHRoZSBhY2N1cmFjeSByZWxhdGVkIG1hdGggZXJyb3JzCgogICAgICAgIC0gICB3aGVyZSBhIHBhcnRpY2lwYW50IGFuc3dlcmVkIGluY29ycmVjdGx5IG9uIHRoZSBtYXRoIGNvbXBvbmVudCBvZiB0aGUgdGFza1wKCi0gICAqKk1hdGggUGVyY2VudGFnZSBbKm9zcGFuX21hdGhfcGVyY2VudF9jb3JyKl0qKgoKICAgIC0gICB0aGUgcGVyY2VudCBvZiBhbGwgbWF0aCB0cmlhbHMgdGhhdCB3ZXJlIGFuc3dlcmVkIGNvcnJlY3RseQoKICAgICAgICAtICAgUGFydGljaXBhbnRzIHdlcmUgYXNrZWQgdG8ga2VlcCB0aGVpciBtYXRoIHBlcmNlbnRhZ2UgYXQgODUlIG9yIGFib3ZlIHRvIGVuc3VyZSBwYXJ0aWNpcGFudHMgZGlkIG5vdCBpZ25vcmUgdGhlIG1hdGggY29tcG9uZW50IG9mIHRoZSB0YXNrIHRvIGltcHJvdmUgb24gdGhlIGxldHRlciByZWNhbGwgY29tcG9uZW50CgotICAgKipNYXRoIFBlcmNlbnRhZ2UgQ3JpdGVyaWEgWypvc3Bhbl9tYXRoX2NyaXRlcmlhXzg1Kl0qKgoKICAgIC0gICB3aGV0aGVyIGEgcGFydGljaXBhbnQgbWV0IHRoZSBtYXRoIGNyaXRlcmlhIChpLmUuLCA4NSUgb3IgYWJvdmU7IHllcyBvciBubylcCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICAtICAgMSA9IHllcwogICAgICAgIC0gICAwID0gbm8gXCogKmluY2x1ZGluZyBhbnkgcGFydGljaXBhbnQgdGhhdCBkaWQgbm90IGNvbXBsZXRlIHRoZSBPU3BhbiB0YXNrKgoKPC9kZXRhaWxzPgoKPC9kZXRhaWxzPgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBpbXBvcnRlZCB0aGUgT1NwYW4gcmF3IGRhdGEuICooY2xpY2sgdG8gZXhwYW5kKSoKCjwvc3VtbWFyeT4KCmBgYHtyIGltcG9ydF9vc3Bhbl9yYXcsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm9zcGFuX3JhdyA9IHV0aWxzOjpyZWFkLmNzdigicmF3X29zcGFuLmNzdiIsIGhlYWRlciA9IFRSVUUpCgojIHJlb3JnYW5pemUgcm93cyBzbyB0aGF0IHRoZSBkYXRhIGlzIG9yZGVyZWQgYnkgdGhlIHBhcnRpY2lwYW50IG51bWJlciAoZS5nLiAxLCAyLCAzLCA0Li4uKQpvc3Bhbl9yYXcgPSBkcGx5cjo6YXJyYW5nZShvc3Bhbl9yYXcsIG9zcGFuX3BhcnRpY2lwYW50KQoKb3NwYW5fcmF3CmBgYAoKPC9kZXRhaWxzPgoKIyMjIyAyLiBHby9Oby1HbyBSYXcgRGF0YSB7I2duZ19yYXd9Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhlICoqR28vTm8tR28gUmF3IERhdGEqKiB3YXMgY29sbGVjdGVkIHVzaW5nIFBzeWNob1B5MiBFeHBlcmltZW50IEJ1aWxkZXIgKHYxLjg1LjQpLiBFYWNoIHBhcnRpY2lwYW50J3MgZGF0YSB3YXMgc3RvcmVkIGluIGEgc2VwYXJhdGUgZm9sZGVyIChkZWZhdWx0IGZyb20gcHN5Y2hvcHkpIGFzIGFuIGV4Y2VsIGZpbGUuIFRoZSBmb2xsb3dpbmcgY29kZSByZS1vcmdhbml6ZWQgdGhlIHJhdyBkYXRhIGludG8gYSBzaW5nbGUgd2lkZSBmb3JtYXQgb2YgdGhlIGRhdGEgYXMgYSBkYXRhIGZyYW1lLCAiKipnbmdfZGF0YV9leHRyYWN0ZWQqKiIsIGFuZCB0d28gZGF0YSBmcmFtZXMgdGhhdCBzZXBhcmF0ZSB0aGUgcmF3IGRhdGEgYnkgY3VlIHR5cGUgKGkuZS4idmVydGljYWwiIG9yICJob3Jpem9udGFsIiksICIqKmduZ19kYXRhX2V4dHJhY3RlZF92KioiIGFuZCAiKipnbmdfZGF0YV9leHRyYWN0ZWRfaCoqIi4gKihjbGljayB0byBzZWUgZGVzY3JpcHRpb25zKSoKCjwvc3VtbWFyeT4KCkZvciB0aGUgKipnbmdfZGF0YV9leHRyYWN0ZWQqKiBkYXRhIGZyYW1lOgoKLSAgICoqUGFydGljaXBhbnQgbnVtYmVyIFsqZ25nX3BhcnRpY2lwYW50Kl0qKlwKCi0gICAqKkFnZSBbKmFnZSpdKipcCgotICAgKipGaXJzdCBMYW5ndWFnZSBbKmxhbmcqXSoqCgogICAgLSAgIHNlbGYtcmVwb3J0ZWQgd2hldGhlciB0aGVpciBmaXN0IGxhbmd1YWdlIHdhcyBFbmdsaXNoIChpLmUuLCB5ZXMgb3Igbm8pXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgIHwgIDIgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS06fDotLS06fAogICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyB8IE5vICB8CgotICAgKipUb3RhbCB0cmlhbHMgY29tcGxldGVkIFsqZ25nX3RyaWFsX3RvdCpdKipcCgotICAgKipHbkcgU2NvcmUgWypnbmdfc2NvcmUqXSoqCgogICAgLSAgIHRoZSBzdW0gb2YgdGhlIGNvcnJlY3QgYW5zd2Vyc1wKCi0gICAqKlRvdGFsIFJlc3BvbnNlcyBbKmduZ19yZXNwX3RvdCpdKioKCiAgICAtICAgdGhlIHN1bSBvZiB0aGUgcmVzcG9uc2VzIGZvciBhbGwgdHJpYWxzCgotICAgKipUb3RhbCBObyBSZXNwb25zZXMgWypnbmdfbm9fcmVzcF90b3QqXSoqCgogICAgLSAgIHRoZSBzdW0gb2YgdGhlIHRyaWFscyB3aXRob3V0IGEgcmVzcG9uc2VcCgotICAgKipUb3RhbCBFcnJvcnMgWypnbmdfZXJyX3RvdCpdKioKCiAgICAtICAgdGhlIHN1bSBvZiBhbGwgZXJyb3JzIGZvciBhbGwgdHJpYWxzXAoKLSAgICoqQ29tbWlzc2lvbiBFcnJvcnMgWypnbmdfZXJyX2NvbSpdKioKCiAgICAtICAgdGhlIHN1bSBvZiBhbGwgY29tbWlzc2lvbiBlcnJvcnMsIGRlZmluZWQgYXM6CgogICAgICAgIC0gICB3aGVyZSBhIHJlc3BvbnNlIHdhcyBtYWRlIGR1cmluZyBhICJuby1nbyIgdHJpYWwgKGkuZS4sIGNvbW1pdHRpbmcgYW4gZXJyb3IpXAoKLSAgICoqT21pc3Npb24gRXJyb3JzIFsqZ25nX2Vycl9vbWkqXSoqCgogICAgLSAgIHRoZSBzdW0gb2YgYWxsIG9taXNzaW9uIGVycm9ycywgZGVmaW5lZCBhczoKCiAgICAgICAgLSAgIHdoZXJlIGEgcmVzcG9uc2Ugd2FzIE5PVCBtYWRlIGR1cmluZyBhICJnbyIgdHJpYWwgKGkuZS4sIGZhaWxpbmcgdG8gcmVzcG9uZClcCgotICAgKipBdmVyYWdlIFJlYWN0aW9uIFRpbWUgKFJUKSBbKmduZ19ydF9hdipdKioKCkZvciB0aGUgKipnbmdfZGF0YV9leHRyYWN0ZWRfdioqIGRhdGEgZnJhbWU6CgotICAgKipQYXJ0aWNpcGFudCBudW1iZXIgWypnbmdfcGFydGljaXBhbnQqXSoqXAoKLSAgICoqQWdlIFsqYWdlX2xvbmcqXSoqXAoKLSAgICoqRmlyc3QgTGFuZ3VhZ2UgWypsYW5nX2xvbmcqXSoqCgogICAgLSAgIHNlbGYtcmVwb3J0ZWQgd2hldGhlciB0aGVpciBmaXN0IGxhbmd1YWdlIHdhcyBFbmdsaXNoIChpLmUuLCB5ZXMgb3Igbm8pXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgIHwgIDIgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS06fDotLS06fAogICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyB8IE5vICB8CgotICAgKipUb3RhbCB0cmlhbHMgY29tcGxldGVkIFsqdHJpYWxfdG90X3YqXSoqXAoKLSAgICoqR25HIFNjb3JlIFsqc2NvcmVfdipdKioKCiAgICAtICAgdGhlIHN1bSBvZiB0aGUgY29ycmVjdCBhbnN3ZXJzXAoKLSAgICoqVG90YWwgUmVzcG9uc2VzIFsqcmVzcF90b3RfdipdKioKCiAgICAtICAgdGhlIHN1bSBvZiB0aGUgcmVzcG9uc2VzIGZvciBhbGwgdHJpYWxzCgotICAgKipUb3RhbCBObyBSZXNwb25zZXMgWypub19yZXNwX3RvdF92Kl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIHRoZSB0cmlhbHMgd2l0aG91dCBhIHJlc3BvbnNlXAoKLSAgICoqVG90YWwgRXJyb3JzIFsqZXJyX3RvdF92Kl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIGFsbCBlcnJvcnMgZm9yIGFsbCB0cmlhbHNcCgotICAgKipDb21taXNzaW9uIEVycm9ycyBbKmVycl9jb21fdipdKioKCiAgICAtICAgdGhlIHN1bSBvZiBhbGwgY29tbWlzc2lvbiBlcnJvcnMsIGRlZmluZWQgYXM6CgogICAgICAgIC0gICB3aGVyZSBhIHJlc3BvbnNlIHdhcyBtYWRlIGR1cmluZyBhICJuby1nbyIgdHJpYWwgKGkuZS4sIGNvbW1pdHRpbmcgYW4gZXJyb3IpXAoKLSAgICoqT21pc3Npb24gRXJyb3JzIFsqZXJyX29taV92Kl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIGFsbCBvbWlzc2lvbiBlcnJvcnMsIGRlZmluZWQgYXM6CgogICAgICAgIC0gICB3aGVyZSBhIHJlc3BvbnNlIHdhcyBOT1QgbWFkZSBkdXJpbmcgYSAiZ28iIHRyaWFsIChpLmUuLCBmYWlsaW5nIHRvIHJlc3BvbmQpXAoKLSAgICoqQXZlcmFnZSBSZWFjdGlvbiBUaW1lIChSVCkgWypydF9hdl92Kl0qKlwKCi0gICAqKlJlc3BvbnNlIEV4Y2x1c2lvbiBDcml0ZXJpYSBbKmV4Y2x1ZGVfdipdKioKCiAgICAtICAgVGhpcyBkZXBpY3RzIHdoZXRoZXIgYSBwYXJ0aWNpcGFudCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSBhbmFseXNpcyBiYXNlZCBvbiB0aGUgcmVzcG9uc2UgZXhjbHVzaW9uIGNyaXRlcmlhCgogICAgICAgIC0gICBUbyBiZSBpbmNsdWRlZCwgcGFydGljaXBhbnRzIHNob3VsZCBzY29yZSBoaWdoZXIgdGhhbiBjaGFuY2UgcGVyZm9ybWFuY2UgKGkuZS4sIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2YgIkdvIiB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiAiTm8tR28iIHRyaWFscykKCiAgICAgICAgICAgIDxkZXRhaWxzPgoKICAgICAgICAgICAgPHN1bW1hcnk+CgogICAgICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICAgICAgfCAgICAgICBjb2RlIHwgICAgICAgICAgICAgICAxICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAyICAgICAgICAgICAgICAgfAogICAgICAgICAgICB8LS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8CiAgICAgICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyAocGFydGljaXBhbnQgKipleGNsdWRlZCoqKSB8IE5vIChwYXJ0aWNpcGFudCAqKmluY2x1ZGVkKiopIHwKCkZvciB0aGUgKipnbmdfZGF0YV9leHRyYWN0ZWRfaCoqIGRhdGEgZnJhbWU6CgotICAgKipQYXJ0aWNpcGFudCBudW1iZXIgWypnbmdfcGFydGljaXBhbnQqXSoqXAoKLSAgICoqQWdlIFsqYWdlX2xvbmcqXSoqXAoKLSAgICoqRmlyc3QgTGFuZ3VhZ2UgWypsYW5nX2xvbmcqXSoqCgogICAgLSAgIHNlbGYtcmVwb3J0ZWQgd2hldGhlciB0aGVpciBmaXN0IGxhbmd1YWdlIHdhcyBFbmdsaXNoIChpLmUuLCB5ZXMgb3Igbm8pXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgIHwgIDIgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS06fDotLS06fAogICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyB8IE5vICB8CgotICAgKipUb3RhbCB0cmlhbHMgY29tcGxldGVkIFsqdHJpYWxfdG90X2gqXSoqXAoKLSAgICoqR25HIFNjb3JlIFsqc2NvcmVfaCpdKioKCiAgICAtICAgdGhlIHN1bSBvZiB0aGUgY29ycmVjdCBhbnN3ZXJzXAoKLSAgICoqVG90YWwgUmVzcG9uc2VzIFsqcmVzcF90b3RfaCpdKioKCiAgICAtICAgdGhlIHN1bSBvZiB0aGUgcmVzcG9uc2VzIGZvciBhbGwgdHJpYWxzCgotICAgKipUb3RhbCBObyBSZXNwb25zZXMgWypub19yZXNwX3RvdF9oKl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIHRoZSB0cmlhbHMgd2l0aG91dCBhIHJlc3BvbnNlXAoKLSAgICoqVG90YWwgRXJyb3JzIFsqZXJyX3RvdF9oKl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIGFsbCBlcnJvcnMgZm9yIGFsbCB0cmlhbHNcCgotICAgKipDb21taXNzaW9uIEVycm9ycyBbKmVycl9jb21faCpdKioKCiAgICAtICAgdGhlIHN1bSBvZiBhbGwgY29tbWlzc2lvbiBlcnJvcnMsIGRlZmluZWQgYXM6CgogICAgICAgIC0gICB3aGVyZSBhIHJlc3BvbnNlIHdhcyBtYWRlIGR1cmluZyBhICJuby1nbyIgdHJpYWwgKGkuZS4sIGNvbW1pdHRpbmcgYW4gZXJyb3IpXAoKLSAgICoqT21pc3Npb24gRXJyb3JzIFsqZXJyX29taV9oKl0qKgoKICAgIC0gICB0aGUgc3VtIG9mIGFsbCBvbWlzc2lvbiBlcnJvcnMsIGRlZmluZWQgYXM6CgogICAgICAgIC0gICB3aGVyZSBhIHJlc3BvbnNlIHdhcyBOT1QgbWFkZSBkdXJpbmcgYSAiZ28iIHRyaWFsIChpLmUuLCBmYWlsaW5nIHRvIHJlc3BvbmQpXAoKLSAgICoqQXZlcmFnZSBSZWFjdGlvbiBUaW1lIChSVCkgWypydF9hdl9oKl0qKlwKCi0gICAqKlJlc3BvbnNlIEV4Y2x1c2lvbiBDcml0ZXJpYSBbKmV4Y2x1ZGVfaCpdKioKCiAgICAtICAgVGhpcyBkZXBpY3RzIHdoZXRoZXIgYSBwYXJ0aWNpcGFudCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSBhbmFseXNpcyBiYXNlZCBvbiB0aGUgcmVzcG9uc2UgZXhjbHVzaW9uIGNyaXRlcmlhCgogICAgICAgIC0gICBUbyBiZSBpbmNsdWRlZCwgcGFydGljaXBhbnRzIHNob3VsZCBzY29yZSBoaWdoZXIgdGhhbiBjaGFuY2UgcGVyZm9ybWFuY2UgKGkuZS4sIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2YgIkdvIiB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiAiTm8tR28iIHRyaWFscykKCiAgICAgICAgICAgIDxkZXRhaWxzPgoKICAgICAgICAgICAgPHN1bW1hcnk+CgogICAgICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICAgICAgfCAgICAgICBjb2RlIHwgICAgICAgICAgICAgICAxICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAyICAgICAgICAgICAgICAgfAogICAgICAgICAgICB8LS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8CiAgICAgICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyAocGFydGljaXBhbnQgKipleGNsdWRlZCoqKSB8IE5vIChwYXJ0aWNpcGFudCAqKmluY2x1ZGVkKiopIHwKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgaW1wb3J0ZWQgdGhlIEdvL05vLUdvIHJhdyBkYXRhIHdpdGhvdXQgc2VwYXJhdGluZyB0aGUgZGF0YSBieSBjdWUgdHlwZS4gKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKYGBge3IgZ25nX29yZ2FuaXplLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIy0tLVdJREUgREFUQSBGUkFNRS0tLSJnbmdfZGF0YV9leHRyYWN0ZWQiICAKCiMtLVRoaXMgY29kZSBjb21wbGV0ZXMgdGhlIGZvbGxvd2luZyB0YXNrczoKIyAoMSkgQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCBleHRyYWN0cyBhbnkgcmVxdWlyZWQgaW5mb3JtYXRpb24gZnJvbSBhbGwgcHN5Y2hvcHkgZm9sZGVycyBhdCBvbmNlCiMgKDIpIENyZWF0ZSBhIGxpc3Qgb2YgYWxsIHRoZSBkaXJlY3RvcnkgcGF0aHMgdG8gZWFjaCBpbmRpdmlkdWFsIGZpbGUgCiMgKDMpIEFwcGx5IHRoZSBmdW5jdGlvbiB0byB0aGUgZmlsZXMgCiMgKDQpIENyZWF0ZSBhIGRhdGEgZnJhbWUgb2YgdGhlIHJlc3VsdCBvZiB0aGUgZnVuY3Rpb24gb24gdGhlIGZpbGVzCgojLS1UaGUgRklOQUwgT1VUUFVUID0gYSB3aWRlIGZvcm1hdCBvZiB0aGUgcmF3IEduRyBkYXRhIGluY2x1ZGluZzoKIyBwYXJ0aWNpcGFudCwgYWdlLCBsYW5nLCB0cmlhbF90b3QsIHNjb3JlLCByZXNwX3RvdCwgbm9fcmVzcF90b3QsIGVycl90b3QsIGVycl9jb20sIGVycl9vbWksIHJ0X2F2CgojLS1OT1RFUzoKCiMgU3RlcCAoMykgd2lsbCBnaXZlIHdhcm5pbmdzIGlmIHRoZXJlIGlzIGFueSBtaXNzaW5nIGRhdGEgdGhhdCB0aGUgZnVuY3Rpb24gd2FzIG5vdCBzcGVjaWZpZWQgaG93IHRvIGhhbmRsZQojIGV4YW1wbGU6IEFueSBwYXJ0aWNpcGFudCB0aGF0IGRpZCBub3QgcmVzcG9uZCB0byBhbiBpdGVtIG9yIGR1cmluZyBhbGwgdHJpYWxzIHdpbGwgaGF2ZSBhbiAiTkEiIHJlc3BvbnNlIGluIHRoZSBkYXRhCiMgZXhhbXBsZTogQW55IHBhcnRpY2lwYW50IHdobyByZXBvcnRlZCB0aGVpciBhZ2Ugb3IgZmlyc3QgbGFuZ3VhZ2UgaW4gYW4gaXJyZWd1bGFyIG1hbm5lciAoZS5nLiAibmludGVlbiIgcmF0aGVyIHRoYW4gIjE5IikKIyBFaXRoZXIgZXhhbXBsZSB3aWxsIHJlc3VsdCBpbiBhIHdhcm5pbmcsIHNpbmNlIHRoZSBmdW5jdGlvbiB3b3VsZCBoYXZlIHRvIGZvcmNlIHRoYXQgb3V0cHV0IHRvIGJlICJOQSIgYXMgd2VsbAoKIyBJbmRpdmlkdWFsIHBhcnRpY2lwYW50IGZpbGVzIGRvIG5vdCBzdGF5IGluIGNocm9ub2xvZ2ljYWwgb3JkZXIgCiMgKHRoZXkgYXJlIHJlLW9yZGVyZWQgc28gdGhhdCBhbGwgcHMgdGhhdCBzdGFydCB3aXRoIHRoZSBkaWdpdCAiMSIgZ28gZmlyc3QsIHRoZW4gdGhlICIyIi4uLikKCiMtLSgxKSBDcmVhdGUgYSBmdW5jdGlvbiB0aGF0IGV4dHJhY3RzIGFueSByZXF1aXJlZCBpbmZvcm1hdGlvbiBmcm9tIGFsbCBwc3ljaG9weSBmb2xkZXJzIGF0IG9uY2UKCiMgY3JlYXRlIGEgZnVuY3Rpb24gdGhhdCBleHRyYWN0cyBhbGwgdGhlIHJlcXVpcmVkIGluZm9ybWF0aW9uIGZyb20gZWFjaCBleGNlbCBmaWxlCiMgZGV0YWlscyBmb3Igd2hhdCBpcyBleHRyYWN0ZWQgaW4gdGhpcyBmdW5jdGlvbiBpcyBmb3VuZCB3aXRoaW4gaXQsIAojIHRvIHVzZSBpdCB0byBleHRyYWN0IGFueSBvdGhlciAmLyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLCBlZGl0IHdpdGhpbiB0aGUgZnVuY3Rpb24gaXRzZWxmCmV4dHJhY3RfZ25nID0gZnVuY3Rpb24oZGF0YSkgewogIHRlbXBfZGF0YSA9IHJlYWR4bDo6cmVhZF9leGNlbChkYXRhKQogIAogICMgUGFydGljaXBhbnQgbnVtYmVyIChwYXJ0aWNpcGFudCkKICBwYXJ0aWNpcGFudCA9IGFzLm51bWVyaWModGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAicGFydGljaXBhbnQiKSwyXSkKICAKICAjIEFnZSAoYWdlKQogIGFnZSA9IGFzLmludGVnZXIodGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAiQWdlIiksMl0pCiAgCiAgIyBHZW5kZXIgKGdlbmRlcikKICAjIHdpbGwgYmUgcG9wdWxhdGVkIGZyb20gc3VydmV5IG1lYXN1cmVzCiAgCiAgIyBGaXJzdCBMYW5ndWFnZSAobGFuZykKICAjIHRoaXMgZmluZHMgaWYgdGhlIGxhbmd1YWdlIHJlcG9ydGVkIHdhcyBFbmdsaXNoOiBpZiB5ZXMgPSAxOyBubyA9IDAKICBsYW5nID0gaWZlbHNlKHN0cmluZ3I6OnN0cl9kZXRlY3QoYXMuY2hhcmFjdGVyKHRlbXBfZGF0YVt3aGljaCh0ZW1wX2RhdGEgPT0gIkZpcnN0IExhbmd1YWdlIiksMl0pLCBzdHJpbmdyOjpmaXhlZCgiZW5nbGlzaCIsIGlnbm9yZV9jYXNlPVRSVUUpKSwgMSwgMCkKICAKICAjIExvY2F0aW9uIENvbmRpdGlvbiAobG9jYXRpb247IGVpdGhlcjogKDEpIGRlc2ssICgyKSBwb2NrZXQvYmFnLCBvciAoMykgb3V0c2lkZSkKICAjIHdpbGwgYmUgcG9wdWxhdGVkIGZyb20gc3VydmV5IG1lYXN1cmVzCiAgCiAgIyBQb3dlciBDb25kaXRpb24gKHBvd2VyOyBlaXRoZXI6ICgxKSBPTixvciAoMikgT0ZGKQogICMgd2lsbCBiZSBwb3B1bGF0ZWQgZnJvbSBzdXJ2ZXkgbWVhc3VyZXMKICAKICAjIFRvdGFsIHRyaWFscyBjb21wbGV0ZWQgKHRyaWFsX3RvdCkKICAjIGNvdW50IHRoZSAib3JkZXIiIGNvbHVtbiwgd2hpY2ggc2hvd3MgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSB0cmlhbHMgd2VyZSBzaG93ZWQgKHJhbmRvbSBmb3IgZWFjaCBwYXJ0aWNpcGFudCkKICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICB0cmlhbF90b3QgPSBzdW0oKGlzLm5hKHRlbXBfZGF0YSRjdWUpID09ICJGQUxTRSIgJiBpcy5uYSh0ZW1wX2RhdGEkb3JkZXIpID09ICJGQUxTRSIpLCBuYS5ybSA9IFRSVUUpICNhbHRlcm5hdGl2ZTogc3VtKGNvbXBsZXRlLmNhc2VzKHRlbXBfZGF0YSRvcmRlcikpCiAgCiAgIyBHbkcgU2NvcmUgKHNjb3JlKQogICMgc3VtIG9mIHRoZSBjb3JyZWN0IGFuc3dlcnMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmNvcnJfcmF3IiBjb2x1bW4KICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICBzY29yZSA9IHN1bSh0ZW1wX2RhdGEka2V5X3Jlc3Bfc2xhc2guY29ycl9yYXcsIG5hLnJtID0gVFJVRSkKICAKICAjIFRvdGFsIFJlc3BvbnNlcyAocmVzcF90b3QpCiAgIyBzdW0gb2YgdGhlIHJlc3BvbnNlcyBmcm9tIHRoZSAia2V5X3Jlc3Bfc2xhc2gua2V5c19yYXciIGNvbHVtbgogICMgbm90ZTogbXVzdCBpZ25vcmUgdGhlIE5BIHZhbHVlcwogIHJlc3BfdG90ID0gc3VtKChpcy5uYSh0ZW1wX2RhdGEkY3VlKSA9PSAiRkFMU0UiICYgaXMubmEodGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3KSA9PSAiRkFMU0UiKSwgbmEucm0gPSBUUlVFKSAjYWx0ZXJuYXRpdmU6IHN1bShjb21wbGV0ZS5jYXNlcyh0ZW1wX2RhdGEka2V5X3Jlc3Bfc2xhc2gua2V5c19yYXcpKQogIAogICMgVG90YWwgTm8gUmVzcG9uc2VzIChub19yZXNwX3RvdCkKICAjIHN1YnRyYWN0IHRvdGFsIHJlc3BvbnNlcyBtYWRlIGZyb20gY29tcGxldGVkIHRyaWFscyAKICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICBub19yZXNwX3RvdCA9ICh0cmlhbF90b3QgLSByZXNwX3RvdCkKICAKICAjIFRvdGFsIEVycm9ycyAoZXJyX3RvdCkKICAjIHN1bSBvZiB0aGUgaW5jb3JyZWN0IGFuc3dlcnMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmNvcnJfcmF3IgogIGVycl90b3QgPSBzdW0oKHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIpID09ICJUUlVFIiwgbmEucm0gPSBUUlVFKSAjIGFsdGVybmF0aXZlOiBzdW0oIXRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdywgbmEucm0gPSBUUlVFKQogIAogICMgQ29tbWlzc2lvbiBFcnJvcnMgKGVycl9jb20pCiAgIyBzdW0gYW55IGNhc2VzIHdoZXJlIGEgcmVwb25zZSB3YXMgbWFkZSAmIHRoZSBhbnN3ZXIgd2FzIGluY29ycmVjdCAoaS5lLiBjb21taXR0aW5nIGFuIGVyb3JyKQogIGVycl9jb20gPSBzdW0oKHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIgJiAhaXMubmEodGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3KSkgPT0gIlRSVUUiLCBuYS5ybSA9IFRSVUUpCiAgCiAgIyBPbWlzc2lvbiBFcnJvcnMgKGVycl9vbWkpCiAgIyBzdW0gYW55IGNhc2VzIHdoZXJlIGEgcmVwb25zZSB3YXMgTk9UIG1hZGUgJiB0aGUgYW5zd2VyIHdhcyBpbmNvcnJlY3QgKGkuZS4gZmFpbGluZyB0byByZXNwb25kKQogIGVycl9vbWkgPSBzdW0oKHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIgJiBpcy5uYSh0ZW1wX2RhdGEka2V5X3Jlc3Bfc2xhc2gua2V5c19yYXcpKSA9PSAiVFJVRSIsIG5hLnJtID0gVFJVRSkKICAKICAjIEF2ZXJhZ2UgUmVhY3Rpb24gVGltZSAoUlQpIChydF9hdikKICAjIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSAvIG1lYW4gUlQgZm9yIGFsbCByZXNwb25zZXMKICAjIE5vdGU6IHRoZSAibm8tZ28iIHRyaWFscyByZXF1aXJlZCBubyByZXNwb25zZSBmb3IgYSBjb3JyZWN0IHRyaWFsIChmb3IgMSwwMDBtcykKICBydF9hdiA9IG1lYW4odGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLnJ0X3JhdywgbmEucm0gPSBUUlVFKQogIAogIHRlbXBfZGF0YWZyYW1lID0gYXMuZGF0YS5mcmFtZShjKHBhcnRpY2lwYW50LCBhZ2UsIGxhbmcsIHRyaWFsX3RvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NvcmUsIHJlc3BfdG90LCBub19yZXNwX3RvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyX3RvdCwgZXJyX2NvbSwgZXJyX29taSwgcnRfYXYpKQp9CgojLS0oMikgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGRpcmVjdG9yeSBwYXRocyB0byBlYWNoIGluZGl2aWR1YWwgZmlsZSAKCiMgRmluZCB0aGUgbG9jYXRpb24gb2YgZWFjaCBleGNlbCAoLnhsc3gpIGZpbGVzCiMgdGhlIGZvbGRlcnMgY29udGFpbmluZyB0aGUgZmlsZXMgc2hvdWxkIGJlIGluIDEgZm9sZGVyIChlLmcuICIiIGluIHRoaXMgY2FzZSkKIyB0aGlzIHJldHVybnMgYSBsaXN0IG9mIGVhY2ggZmlsZSdzIGxvY2F0aW9uCiMgTm90ZTogdGhlIHBhdHRlcm4gaXMgc2V0IHRvIGlnbm9yZSBhbnkgaGlkZGVuIC8gdGVtcG9yYXJ5IGZpbGVzIGJ5IGFkZGluZyB0aGUgc3RhcnQgb2YgZWFjaCBmaWxlIG5hbWUgKGUuZy4gIl5Ob0dvIikKZmlsZXNfcHN5Y2hvcHkgPSBkaXIoIi9Vc2Vycy9hbmFjZWNpbGlhcnVpenBhcmRvL1JTdHVkaW8vU21hcnRwaG9uZV9zdHVkeS9TdHVkeSAxLSBTbWFydHBob25lIFJlcGxpY2F0aW9uL0Rpc3NlcnRhdGlvbiAoMDQ6MjA6MjApL1JhdyBEYXRhIE9yZ2FuaXppbmcvZ25nX3Jhd19mb2xkZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZSA9IFRSVUUsIGZ1bGwubmFtZXM9VFJVRSwgcGF0dGVybj0iXk5vR28oLiopeGxzeCQiKQoKIy0tKDMpIEFwcGx5IHRoZSBmdW5jdGlvbiB0byB0aGUgZmlsZXMgCgojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBhbGwgZXhjZWwgZmlsZXMKcmVzdWx0ID0gc2FwcGx5KGZpbGVzX3BzeWNob3B5LCBleHRyYWN0X2duZykKCiMtLSg0KSBDcmVhdGUgYSBkYXRhIGZyYW1lIG9mIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uIG9uIHRoZSBmaWxlcwoKIyB0YWtlIHRoZSBsaXN0cyBvZiB0aGUgZXh0cmFjdGVkIGRhdGEgYW5kIHR1cm4gaXQgaW50byBhIGRhdGEgZnJhbWUKZ25nX2RhdGFfZXh0cmFjdGVkID0gZGF0YS5mcmFtZShSZWR1Y2UocmJpbmQsIHJlc3VsdCkpICMgYWx0ZXJuYXRpdmUgbWV0aG9kOiB4ID0gZGF0YS5mcmFtZSh0KHNhcHBseShyZXN1bHQsYykpKQojIHJlbmFtZSB0aGUgY29sdW1ucwpjb2xuYW1lcyhnbmdfZGF0YV9leHRyYWN0ZWQpID0gYygiZ25nX3BhcnRpY2lwYW50IiwgImFnZSIsICJsYW5nIiwgImduZ190cmlhbF90b3QiLCAiZ25nX3Njb3JlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfcmVzcF90b3QiLCAiZ25nX25vX3Jlc3BfdG90IiwgImduZ19lcnJfdG90IiwgImduZ19lcnJfY29tIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taSIsICJnbmdfcnRfYXYiKSAKIyByZW1vdmUgcm93IG5hbWVzIHRvIGF2b2lkIGNvbmZ1c2lvbgpyb3duYW1lcyhnbmdfZGF0YV9leHRyYWN0ZWQpID0gTlVMTAoKIyByZW9yZ2FuaXplIHJvd3Mgc28gdGhhdCB0aGUgZGF0YSBpcyBvcmRlcmVkIGJ5IHRoZSBwYXJ0aWNpcGFudCBudW1iZXIgKGUuZy4gMSwgMiwgMywgNC4uLikKZ25nX2RhdGFfZXh0cmFjdGVkID0gZHBseXI6OmFycmFuZ2UoZ25nX2RhdGFfZXh0cmFjdGVkLCBnbmdfcGFydGljaXBhbnQpCgpnbmdfZGF0YV9leHRyYWN0ZWQKYGBgCgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIGltcG9ydGVkIHRoZSBHby9Oby1HbyByYXcgZGF0YSBhbmQgc2VwYXJhdGVkIHRoZSBkYXRhIGJ5IGN1ZSB0eXBlIChpLmUuICJ2ZXJ0aWNhbCIgb3IgImhvcml6b250YWwiKS4gKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKYGBge3IgZ25nX29yZ2FuaXplX3RhcmdldCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMtLS0gZm9yIHRoZSBMT05HIERBVEEgRlJBTUUgLSBDVUUgVFlQRSAodmVydGljYWwgdnMuIGhvcml6b250YWwpIC0tLSAiZ25nX2RhdGFfZXh0cmFjdGVkX3YiICYgImduZ19kYXRhX2V4dHJhY3RlZF9oIiAKICAKIy0tIFRoaXMgY29kZSBkaWZmZXJzIGZyb20gdGhlIGFib3ZlIGNvZGUgaW4gdGhhdCBpdCBvcmdhbml6ZXMgdGhlIGduZyBkYXRhIGJhc2VkIHRoZSBDVUUgdHlwZSAoaS5lLiBlaXRoZXIgYSAidmVydGljYWwiICh2KSBvciAiaG9yaXpvbnRhbCIgKGgpKS4KICAjIFRoaXMgbWVhbnMgdGhhdCB0aGUgZGF0YSBpcyBpbiBhIGxvbmcgZm9ybWF0IHRvIHRlc3QgdGhlIHdpdGhpbi1zdWJqZWN0cyBmYWN0b3Igb2YgY3VlIHR5cGUuCgojLS1UaGlzIGNvZGUgY29tcGxldGVzIHRoZSBmb2xsb3dpbmcgdGFza3M6CiMgKDEpIENyZWF0ZSBhIGZ1bmN0aW9uIHRoYXQgZXh0cmFjdHMgYW55IHJlcXVpcmVkIGluZm9ybWF0aW9uIGZyb20gYWxsIHBzeWNob3B5IGZvbGRlcnMgYXQgb25jZQojICgyKSBDcmVhdGUgYSBsaXN0IG9mIGFsbCB0aGUgZGlyZWN0b3J5IHBhdGhzIHRvIGVhY2ggaW5kaXZpZHVhbCBmaWxlIAojICgzKSBBcHBseSB0aGUgZnVuY3Rpb24gdG8gdGhlIGZpbGVzIAojICg0KSBDcmVhdGUgYSBkYXRhIGZyYW1lIG9mIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uIG9uIHRoZSBmaWxlcwojICg1KSBSZS1zdHJ1Y3R1cmUgdGhlIGRhdGEgaW50byAxIGRhdGEgZnJhbWUgaW4gYSBsb25nIGZvcm1hdCBmb3IgYSByZXBlYXRlZCBtZWFzdXJlcyBhbmFseXNpcwoKIy0tVGhlIEZJTkFMIE9VVFBVVCA9IGEgd2lkZSBmb3JtYXQgb2YgdGhlIHJhdyBHbkcgZGF0YSBpbmNsdWRpbmc6CiMgcGFydGljaXBhbnQsIGFnZSwgbGFuZywgdHJpYWxfdG90LCBzY29yZSwgcmVzcF90b3QsIG5vX3Jlc3BfdG90LCBlcnJfdG90LCBlcnJfY29tLCBlcnJfb21pLCBydF9hdgoKIy0tTk9URVM6CgojIFN0ZXAgKDMpIHdpbGwgZ2l2ZSB3YXJuaW5ncyBpZiB0aGVyZSBpcyBhbnkgbWlzc2luZyBkYXRhIHRoYXQgdGhlIGZ1bmN0aW9uIHdhcyBub3Qgc3BlY2lmaWVkIGhvdyB0byBoYW5kbGUKIyBleGFtcGxlOiBBbnkgcGFydGljaXBhbnQgdGhhdCBkaWQgbm90IHJlc3BvbmQgdG8gYW4gaXRlbSBvciBkdXJpbmcgYWxsIHRyaWFscyB3aWxsIGhhdmUgYW4gIk5BIiByZXNwb25zZSBpbiB0aGUgZGF0YQojIGV4YW1wbGU6IEFueSBwYXJ0aWNpcGFudCB3aG8gcmVwb3J0ZWQgdGhlaXIgYWdlIG9yIGZpcnN0IGxhbmd1YWdlIGluIGFuIGlycmVndWxhciBtYW5uZXIgKGUuZy4gIm5pbnRlZW4iIHJhdGhlciB0aGFuICIxOSIpCiMgRWl0aGVyIGV4YW1wbGUgd2lsbCByZXN1bHQgaW4gYSB3YXJuaW5nLCBzaW5jZSB0aGUgZnVuY3Rpb24gd291bGQgaGF2ZSB0byBmb3JjZSB0aGF0IG91dHB1dCB0byBiZSAiTkEiIGFzIHdlbGwKCiMgSW5kaXZpZHVhbCBwYXJ0aWNpcGFudCBmaWxlcyBkbyBub3Qgc3RheSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyIAojICh0aGV5IGFyZSByZS1vcmRlcmVkIHNvIHRoYXQgYWxsIHBzIHRoYXQgc3RhcnQgd2l0aCB0aGUgZGlnaXQgIjEiIGdvIGZpcnN0LCB0aGVuIHRoZSAiMiIuLi4pCgojLS0oMSkgQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCBleHRyYWN0cyBhbnkgcmVxdWlyZWQgaW5mb3JtYXRpb24gZnJvbSBhbGwgcHN5Y2hvcHkgZm9sZGVycyBhdCBvbmNlLi4uCiMgZm9yIHRoZSAidmVydGljYWwiICh2KSAoZXh0cmFjdF9nbmdfdikgYW5kICJob3Jpem9udGFsIiAoaCkgKGV4dHJhY3RfZ25nX2gpIHRyaWFscwoKIyBjcmVhdGUgYSBmdW5jdGlvbiB0aGF0IGV4dHJhY3RzIGFsbCB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24gZnJvbSBlYWNoIGV4Y2VsIGZpbGUKIyBkZXRhaWxzIGZvciB3aGF0IGlzIGV4dHJhY3RlZCBpbiB0aGlzIGZ1bmN0aW9uIGlzIGZvdW5kIHdpdGhpbiBpdCwgCiMgdG8gdXNlIGl0IHRvIGV4dHJhY3QgYW55IG90aGVyICYvIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24sIGVkaXQgd2l0aGluIHRoZSBmdW5jdGlvbiBpdHNlbGYKIyBOT1RFOiB0aGlzIGZ1bmN0aW9uIGV4dHJhY3RzIDIgdmVyc2lvbnMgb2YgZWFjaCB2YWx1ZTogb25lIGZvciB0aGUgInZlcnRpY2FsIiAodikgdHJpYWxzLCBhbmQgb25lIGZvciB0aGUgImhvcml6b250YWwiIChoKSB0cmlhbHMKCmV4dHJhY3RfZ25nX3YgPSBmdW5jdGlvbihkYXRhKSB7CiAgdGVtcF9kYXRhID0gcmVhZHhsOjpyZWFkX2V4Y2VsKGRhdGEpCiAgCiAgIyBQYXJ0aWNpcGFudCBudW1iZXIgKHBhcnRpY2lwYW50X2xvbmcpCiAgcGFydGljaXBhbnRfbG9uZyA9IGFzLm51bWVyaWModGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAicGFydGljaXBhbnQiKSwyXSkKICAjIG9ubHkgb25lIGlzIGV4dHJhY3RlZCBzaW5jZSB0aGlzIHdpbGwgbm90IGNoYW5nZSBiL3cgQ1VFIHR5cGUKICAKICAjIEFnZSAoYWdlX2xvbmcpCiAgYWdlX2xvbmcgPSBhcy5pbnRlZ2VyKHRlbXBfZGF0YVt3aGljaCh0ZW1wX2RhdGEgPT0gIkFnZSIpLDJdKQogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgR2VuZGVyIChnZW5kZXIpCiAgIyB3aWxsIGJlIHBvcHVsYXRlZCBmcm9tIHN1cnZleSBtZWFzdXJlcwogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgRmlyc3QgTGFuZ3VhZ2UgKGxhbmdfbG9uZykKICAjIHRoaXMgZmluZHMgaWYgdGhlIGxhbmd1YWdlIHJlcG9ydGVkIHdhcyBFbmdsaXNoOiBpZiB5ZXMgPSAxOyBubyA9IDAKICBsYW5nX2xvbmcgPSBpZmVsc2Uoc3RyaW5ncjo6c3RyX2RldGVjdChhcy5jaGFyYWN0ZXIodGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAiRmlyc3QgTGFuZ3VhZ2UiKSwyXSksIHN0cmluZ3I6OmZpeGVkKCJlbmdsaXNoIiwgaWdub3JlX2Nhc2U9VFJVRSkpLCAxLCAwKQogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgTG9jYXRpb24gQ29uZGl0aW9uIChsb2NhdGlvbjsgZWl0aGVyOiAoMSkgZGVzaywgKDIpIHBvY2tldC9iYWcsIG9yICgzKSBvdXRzaWRlKQogICMgd2lsbCBiZSBwb3B1bGF0ZWQgZnJvbSBzdXJ2ZXkgbWVhc3VyZXMKICAjIG9ubHkgb25lIGlzIGV4dHJhY3RlZCBzaW5jZSB0aGlzIHdpbGwgbm90IGNoYW5nZSBiL3cgQ1VFIHR5cGUKICAKICAjIFBvd2VyIENvbmRpdGlvbiAocG93ZXI7IGVpdGhlcjogKDEpIE9OLG9yICgyKSBPRkYpCiAgIyB3aWxsIGJlIHBvcHVsYXRlZCBmcm9tIHN1cnZleSBtZWFzdXJlcwogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgVG90YWwgdHJpYWxzIGNvbXBsZXRlZCBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpICh0cmlhbF90b3RfdikKICAjIGNvdW50IHRoZSAib3JkZXIiIGNvbHVtbiwgd2hpY2ggc2hvd3MgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSB0cmlhbHMgd2VyZSBzaG93ZWQgKHJhbmRvbSBmb3IgZWFjaCBwYXJ0aWNpcGFudCkKICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICB0cmlhbF90b3RfdiA9IHN1bSgodGVtcF9kYXRhJGN1ZSA9PSAidl9iLnBuZyIgJiBpcy5uYSh0ZW1wX2RhdGEkb3JkZXIpID09ICJGQUxTRSIpLCBuYS5ybSA9IFRSVUUpCiAgCiAgIyBHbkcgU2NvcmUgZm9yIHRoZSAidmVydGljYWwiICh2KSAoc2NvcmVfdikgIAogICMgc3VtIG9mIHRoZSBjb3JyZWN0IGFuc3dlcnMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmNvcnJfcmF3IiBjb2x1bW4KICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICBzY29yZV92ID0gc3VtKHRlbXBfZGF0YSRjdWUgPT0gInZfYi5wbmciICYgdGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmNvcnJfcmF3LCBuYS5ybSA9IFRSVUUpICAKICAKICAjIFRvdGFsIFJlc3BvbnNlcyBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpIChyZXNwX3RvdF92KQogICMgc3VtIG9mIHRoZSByZXNwb25zZXMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmtleXNfcmF3IiBjb2x1bW4KICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICByZXNwX3RvdF92ID0gc3VtKCh0ZW1wX2RhdGEkY3VlID09ICJ2X2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5rZXlzX3JhdyA9PSAiJ3NsYXNoJyIpLCBuYS5ybSA9IFRSVUUpICAKICAKICAjIFRvdGFsIE5vIFJlc3BvbnNlcyBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpIChub19yZXNwX3RvdF92KSAgCiAgIyBzdWJ0cmFjdCB0b3RhbCByZXNwb25zZXMgbWFkZSBmcm9tIGNvbXBsZXRlZCB0cmlhbHMgCiAgIyBub3RlOiBtdXN0IGlnbm9yZSB0aGUgTkEgdmFsdWVzCiAgbm9fcmVzcF90b3RfdiA9ICh0cmlhbF90b3RfdiAtIHJlc3BfdG90X3YpICAKICAKICAjIFRvdGFsIEVycm9ycyBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpIChlcnJfdG90X3YpIAogICMgc3VtIG9mIHRoZSBpbmNvcnJlY3QgYW5zd2VycyBmcm9tIHRoZSAia2V5X3Jlc3Bfc2xhc2guY29ycl9yYXciCiAgZXJyX3RvdF92ID0gc3VtKCh0ZW1wX2RhdGEkY3VlID09ICJ2X2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIpLCBuYS5ybSA9IFRSVUUpICAKICAKICAjIENvbW1pc3Npb24gRXJyb3JzIGZvciB0aGUgInZlcnRpY2FsIiAodikgKGVycl9jb21fdikgCiAgIyBzdW0gYW55IGNhc2VzIHdoZXJlIGEgcmVwb25zZSB3YXMgbWFkZSAmIHRoZSBhbnN3ZXIgd2FzIGluY29ycmVjdCAoaS5lLiBjb21taXR0aW5nIGFuIGVycm9yKQogIGVycl9jb21fdiA9IHN1bSh0ZW1wX2RhdGEkY3VlID09ICJ2X2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIgJiAhaXMubmEodGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3KSwgbmEucm0gPSBUUlVFKSAgCiAgCiAgIyBPbWlzc2lvbiBFcnJvcnMgZm9yIHRoZSAidmVydGljYWwiICh2KSAoZXJyX29taV92KSAgCiAgIyBzdW0gYW55IGNhc2VzIHdoZXJlIGEgcmVwb25zZSB3YXMgTk9UIG1hZGUgJiB0aGUgYW5zd2VyIHdhcyBpbmNvcnJlY3QgKGkuZS4gZmFpbGluZyB0byByZXNwb25kKQogIGVycl9vbWlfdiA9IHN1bSh0ZW1wX2RhdGEkY3VlID09ICJ2X2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIgJiBpcy5uYSh0ZW1wX2RhdGEka2V5X3Jlc3Bfc2xhc2gua2V5c19yYXcpLCBuYS5ybSA9IFRSVUUpICAKCiAgIyBBdmVyYWdlIFJlYWN0aW9uIFRpbWUgKFJUKSBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpIChydF9hdl92KSAgCiAgIyBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgLyBtZWFuIFJUIGZvciBhbGwgcmVzcG9uc2VzCiAgIyBOb3RlOiB0aGUgIm5vLWdvIiB0cmlhbHMgcmVxdWlyZWQgbm8gcmVzcG9uc2UgZm9yIGEgY29ycmVjdCB0cmlhbCAoZm9yIDEsMDAwbXMpCiAgcnRfYXZfdiA9IG1lYW4odGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLnJ0X3Jhd1t3aGljaCh0ZW1wX2RhdGEkY3VlID09ICJ2X2IucG5nIildLCBuYS5ybSA9IFRSVUUpICAKICAKICAjIEV4Y2x1c2lvbiBDcml0ZXJpYSBmb3IgdGhlICJ2ZXJ0aWNhbCIgKHYpIChleGNsdWRlX3YpCiAgIyBjYWxjdWxhdGUgd2hldGhlciBwYXJ0aWNpcGFudHMgc2NvcmVkIGhpZ2hlciB0aGFuIGNoYW5jZSBwZXJmb3JtYW5jZSAKICAjIChpLmUuIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2Yg4oCcR2/igJ0gdHJpYWxzIGFuZCB3aXRoaGVsZCByZXNwb25zZSB0byBhdCBsZWFzdCA1MCUgb2Yg4oCcTm8tR2/igJ0gdHJpYWxzKQogICMgY29kZTogZXhjbHVkZSA9IDE7IGluY2x1ZGUgKGRvIG5vdCBleGNsdWRlKSA9IDIKICAjIE5PVEU6IHRoaXMgY2FsY3VsYXRpb24gaXMgbWVhbnQgdG8gZXhjbHVkZSB0aGUgcGFydGljaXBhbnQgYXMgYSB3aG9sZSwgdGhlcmVmb3JlLCAKICAjIGl0IGRvZXMgbm90IGNhbGN1bGF0ZSBpdCBmb3IgdGhlIGN1ZSB0eXBlIHNwZWNpZmljYWxseQogICAgIyBmaXJzdCwgZ2V0IHRoZSB0b3RhbCB0cmlhbHMgYW5kIHJlc3BvbnNlIHRvdGFscyBmb3IgdGhlICJnbyIgYW5kICJuby1nbyIgdHJpYWxzCiAgICAgICMgImdvIgogICAgICB0cmlhbF90b3RfZ28gPSBzdW0oKHRlbXBfZGF0YSRjb3JyQW5zID09ICJzbGFzaCIgJiBpcy5uYSh0ZW1wX2RhdGEkb3JkZXIpID09ICJGQUxTRSIpLCBuYS5ybSA9IFRSVUUpCiAgICAgIHJlc3BfdG90X2dvID0gc3VtKCh0ZW1wX2RhdGEkY29yckFucyA9PSAic2xhc2giICYgdGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3ID09ICInc2xhc2gnIiksIG5hLnJtID0gVFJVRSkKICAgICAgIyAibm8tZ28iCiAgICAgIHRyaWFsX3RvdF9ub2dvID0gc3VtKCh0ZW1wX2RhdGEkY29yckFucyA9PSAibm9uZSIgJiBpcy5uYSh0ZW1wX2RhdGEkb3JkZXIpID09ICJGQUxTRSIpLCBuYS5ybSA9IFRSVUUpCiAgICAgIHJlc3BfdG90X25vZ28gPSBzdW0oKHRlbXBfZGF0YSRjb3JyQW5zID09ICJub25lIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5rZXlzX3JhdyA9PSAiJ3NsYXNoJyIpLCBuYS5ybSA9IFRSVUUpCiAgICAjIG5leHQsIGZpbmQgdGhlIG1pbmltdW0gcmVzcG9uc2UgbmVlZGVkIGJhc2VkIG9uIHRoZSA1MCUgY3JpdGVyaWEKICAgIG1pbl9yZXNwID0gdHJpYWxfdG90X2dvICogLjUwCiAgICAjIGZpbmQgaWYgdGhlIHBhcnRpY2lwYW50IG1lZXRzIGV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhlICJnbyIgYW5kICJuby1nbyIgdHJpYWxzCiAgICBtZWV0c19taW5fZ28gPSByZXNwX3RvdF9nbyA+IChtaW5fcmVzcCkKICAgIG1lZXRzX21pbl9ub2dvID0gcmVzcF90b3Rfbm9nbyA8IChtaW5fcmVzcCkKICAgICMgZmluZCBpZiB0aGUgcGFydGljaXBhbnQgbWVldHMgZXhjbHVzaW9uIGNyaXRlcmlhIChleGNsdWRlID0gMTsgaW5jbHVkZSA9IDIpCiAgICBleGNsdWRlX3YgPSBpZmVsc2UoKG1lZXRzX21pbl9nbyA9PSAiVFJVRSIgJiBtZWV0c19taW5fbm9nbyA9PSAiVFJVRSIpID09ICJGQUxTRSIsIDEsIDIpCiAgCiAgdGVtcF9kYXRhZnJhbWVfdiA9IGFzLmRhdGEuZnJhbWUoYyhwYXJ0aWNpcGFudF9sb25nLCBhZ2VfbG9uZywgbGFuZ19sb25nLCB0cmlhbF90b3Rfdiwgc2NvcmVfdiwgcmVzcF90b3RfdiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub19yZXNwX3RvdF92LCBlcnJfdG90X3YsIGVycl9jb21fdiwgZXJyX29taV92LCBydF9hdl92LCBleGNsdWRlX3YpKQp9ICAKCmV4dHJhY3RfZ25nX2ggPSBmdW5jdGlvbihkYXRhKSB7CiAgdGVtcF9kYXRhID0gcmVhZHhsOjpyZWFkX2V4Y2VsKGRhdGEpCiAgCiAgIyBQYXJ0aWNpcGFudCBudW1iZXIgKHBhcnRpY2lwYW50X2xvbmcpCiAgcGFydGljaXBhbnRfbG9uZyA9IGFzLm51bWVyaWModGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAicGFydGljaXBhbnQiKSwyXSkKICAjIG9ubHkgb25lIGlzIGV4dHJhY3RlZCBzaW5jZSB0aGlzIHdpbGwgbm90IGNoYW5nZSBiL3cgQ1VFIHR5cGUKICAKICAjIEFnZSAoYWdlX2xvbmcpCiAgYWdlX2xvbmcgPSBhcy5pbnRlZ2VyKHRlbXBfZGF0YVt3aGljaCh0ZW1wX2RhdGEgPT0gIkFnZSIpLDJdKQogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgR2VuZGVyIChnZW5kZXIpCiAgIyB3aWxsIGJlIHBvcHVsYXRlZCBmcm9tIHN1cnZleSBtZWFzdXJlcwogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgRmlyc3QgTGFuZ3VhZ2UgKGxhbmdfbG9uZykKICAjIHRoaXMgZmluZHMgaWYgdGhlIGxhbmd1YWdlIHJlcG9ydGVkIHdhcyBFbmdsaXNoOiBpZiB5ZXMgPSAxOyBubyA9IDAKICBsYW5nX2xvbmcgPSBpZmVsc2Uoc3RyaW5ncjo6c3RyX2RldGVjdChhcy5jaGFyYWN0ZXIodGVtcF9kYXRhW3doaWNoKHRlbXBfZGF0YSA9PSAiRmlyc3QgTGFuZ3VhZ2UiKSwyXSksIHN0cmluZ3I6OmZpeGVkKCJlbmdsaXNoIiwgaWdub3JlX2Nhc2U9VFJVRSkpLCAxLCAwKQogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgTG9jYXRpb24gQ29uZGl0aW9uIChsb2NhdGlvbjsgZWl0aGVyOiAoMSkgZGVzaywgKDIpIHBvY2tldC9iYWcsIG9yICgzKSBvdXRzaWRlKQogICMgd2lsbCBiZSBwb3B1bGF0ZWQgZnJvbSBzdXJ2ZXkgbWVhc3VyZXMKICAjIG9ubHkgb25lIGlzIGV4dHJhY3RlZCBzaW5jZSB0aGlzIHdpbGwgbm90IGNoYW5nZSBiL3cgQ1VFIHR5cGUKICAKICAjIFBvd2VyIENvbmRpdGlvbiAocG93ZXI7IGVpdGhlcjogKDEpIE9OLG9yICgyKSBPRkYpCiAgIyB3aWxsIGJlIHBvcHVsYXRlZCBmcm9tIHN1cnZleSBtZWFzdXJlcwogICMgb25seSBvbmUgaXMgZXh0cmFjdGVkIHNpbmNlIHRoaXMgd2lsbCBub3QgY2hhbmdlIGIvdyBDVUUgdHlwZQogIAogICMgVG90YWwgdHJpYWxzIGNvbXBsZXRlZCBmb3IgdGhlICJob3Jpem9udGFsIiAoaCkgKHRyaWFsX3RvdF9oKQogICMgY291bnQgdGhlICJvcmRlciIgY29sdW1uLCB3aGljaCBzaG93cyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIHRyaWFscyB3ZXJlIHNob3dlZCAocmFuZG9tIGZvciBlYWNoIHBhcnRpY2lwYW50KQogICMgbm90ZTogbXVzdCBpZ25vcmUgdGhlIE5BIHZhbHVlcwogIHRyaWFsX3RvdF9oID0gc3VtKCh0ZW1wX2RhdGEkY3VlID09ICJoX2IucG5nIiAmIGlzLm5hKHRlbXBfZGF0YSRvcmRlcikgPT0gIkZBTFNFIiksIG5hLnJtID0gVFJVRSkKICAKICAjIEduRyBTY29yZSBmb3IgdGhlICJob3Jpem9udGFsIiAoaCkgKHNjb3JlX2gpICAKICAjIHN1bSBvZiB0aGUgY29ycmVjdCBhbnN3ZXJzIGZyb20gdGhlICJrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyIgY29sdW1uCiAgIyBub3RlOiBtdXN0IGlnbm9yZSB0aGUgTkEgdmFsdWVzCiAgc2NvcmVfaCA9IHN1bSh0ZW1wX2RhdGEkY3VlID09ICJoX2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdywgbmEucm0gPSBUUlVFKSAgCiAgCiAgIyBUb3RhbCBSZXNwb25zZXMgZm9yIHRoZSAiaG9yaXpvbnRhbCIgKGgpIChyZXNwX3RvdF9oKQogICMgc3VtIG9mIHRoZSByZXNwb25zZXMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmtleXNfcmF3IiBjb2x1bW4KICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICByZXNwX3RvdF9oID0gc3VtKCh0ZW1wX2RhdGEkY3VlID09ICJoX2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5rZXlzX3JhdyA9PSAiJ3NsYXNoJyIpLCBuYS5ybSA9IFRSVUUpICAKICAKICAjIFRvdGFsIE5vIFJlc3BvbnNlcyBmb3IgdGhlICJob3Jpem9udGFsIiAoaCkgKG5vX3Jlc3BfdG90X2gpICAKICAjIHN1YnRyYWN0IHRvdGFsIHJlc3BvbnNlcyBtYWRlIGZyb20gY29tcGxldGVkIHRyaWFscyAKICAjIG5vdGU6IG11c3QgaWdub3JlIHRoZSBOQSB2YWx1ZXMKICBub19yZXNwX3RvdF9oID0gKHRyaWFsX3RvdF9oIC0gcmVzcF90b3RfaCkgIAogIAogICMgVG90YWwgRXJyb3JzIGZvciB0aGUgImhvcml6b250YWwiIChoKSAoZXJyX3RvdF9oKSAKICAjIHN1bSBvZiB0aGUgaW5jb3JyZWN0IGFuc3dlcnMgZnJvbSB0aGUgImtleV9yZXNwX3NsYXNoLmNvcnJfcmF3IgogIGVycl90b3RfaCA9IHN1bSgodGVtcF9kYXRhJGN1ZSA9PSAiaF9iLnBuZyIgJiB0ZW1wX2RhdGEka2V5X3Jlc3Bfc2xhc2guY29ycl9yYXcgPT0gIjAiKSwgbmEucm0gPSBUUlVFKSAgCiAgCiAgIyBDb21taXNzaW9uIEVycm9ycyBmb3IgdGhlICJob3Jpem9udGFsIiAoaCkgKGVycl9jb21faCkgCiAgIyBzdW0gYW55IGNhc2VzIHdoZXJlIGEgcmVwb25zZSB3YXMgbWFkZSAmIHRoZSBhbnN3ZXIgd2FzIGluY29ycmVjdCAoaS5lLiBjb21taXR0aW5nIGFuIGVycm9yKQogIGVycl9jb21faCA9IHN1bSh0ZW1wX2RhdGEkY3VlID09ICJoX2IucG5nIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5jb3JyX3JhdyA9PSAiMCIgJiAhaXMubmEodGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3KSwgbmEucm0gPSBUUlVFKSAgCiAgCiAgIyBPbWlzc2lvbiBFcnJvcnMgZm9yIHRoZSAiaG9yaXpvbnRhbCIgKGgpIChlcnJfb21pX2gpICAKICAjIHN1bSBhbnkgY2FzZXMgd2hlcmUgYSByZXBvbnNlIHdhcyBOT1QgbWFkZSAmIHRoZSBhbnN3ZXIgd2FzIGluY29ycmVjdCAoaS5lLiBmYWlsaW5nIHRvIHJlc3BvbmQpCiAgZXJyX29taV9oID0gc3VtKHRlbXBfZGF0YSRjdWUgPT0gImhfYi5wbmciICYgdGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmNvcnJfcmF3ID09ICIwIiAmIGlzLm5hKHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5rZXlzX3JhdyksIG5hLnJtID0gVFJVRSkgIAogIAogICMgQXZlcmFnZSBSZWFjdGlvbiBUaW1lIChSVCkgZm9yIHRoZSAiaG9yaXpvbnRhbCIgKGgpIChydF9hdl9oKSAgCiAgIyBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgLyBtZWFuIFJUIGZvciBhbGwgcmVzcG9uc2VzCiAgIyBOb3RlOiB0aGUgIm5vLWdvIiB0cmlhbHMgcmVxdWlyZWQgbm8gcmVzcG9uc2UgZm9yIGEgY29ycmVjdCB0cmlhbCAoZm9yIDEsMDAwbXMpCiAgcnRfYXZfaCA9IG1lYW4odGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLnJ0X3Jhd1t3aGljaCh0ZW1wX2RhdGEkY3VlID09ICJoX2IucG5nIildLCBuYS5ybSA9IFRSVUUpICAKICAKICAjIEV4Y2x1c2lvbiBDcml0ZXJpYSBmb3IgdGhlICJob3Jpem9udGFsIiAoaCkgKGV4Y2x1ZGVfaCkKICAjIGNhbGN1bGF0ZSB3aGV0aGVyIHBhcnRpY2lwYW50cyBzY29yZWQgaGlnaGVyIHRoYW4gY2hhbmNlIHBlcmZvcm1hbmNlIAogICMgKGkuZS4gcmVzcG9uZGVkIHRvIGF0IGxlYXN0IDUwJSBvZiDigJxHb+KAnSB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiDigJxOby1Hb+KAnSB0cmlhbHMpCiAgIyBjb2RlOiBleGNsdWRlID0gMTsgaW5jbHVkZSAoZG8gbm90IGV4Y2x1ZGUpID0gMgogICMgTk9URTogdGhpcyBjYWxjdWxhdGlvbiBpcyBtZWFudCB0byBleGNsdWRlIHRoZSBwYXJ0aWNpcGFudCBhcyBhIHdob2xlLCB0aGVyZWZvcmUsIAogICMgaXQgZG9lcyBub3QgY2FsY3VsYXRlIGl0IGZvciB0aGUgY3VlIHR5cGUgc3BlY2lmaWNhbGx5CiAgIyBmaXJzdCwgZ2V0IHRoZSB0b3RhbCB0cmlhbHMgYW5kIHJlc3BvbnNlIHRvdGFscyBmb3IgdGhlICJnbyIgYW5kICJuby1nbyIgdHJpYWxzCiAgIyAiZ28iCiAgdHJpYWxfdG90X2dvID0gc3VtKCh0ZW1wX2RhdGEkY29yckFucyA9PSAic2xhc2giICYgaXMubmEodGVtcF9kYXRhJG9yZGVyKSA9PSAiRkFMU0UiKSwgbmEucm0gPSBUUlVFKQogIHJlc3BfdG90X2dvID0gc3VtKCh0ZW1wX2RhdGEkY29yckFucyA9PSAic2xhc2giICYgdGVtcF9kYXRhJGtleV9yZXNwX3NsYXNoLmtleXNfcmF3ID09ICInc2xhc2gnIiksIG5hLnJtID0gVFJVRSkKICAjICJuby1nbyIKICB0cmlhbF90b3Rfbm9nbyA9IHN1bSgodGVtcF9kYXRhJGNvcnJBbnMgPT0gIm5vbmUiICYgaXMubmEodGVtcF9kYXRhJG9yZGVyKSA9PSAiRkFMU0UiKSwgbmEucm0gPSBUUlVFKQogIHJlc3BfdG90X25vZ28gPSBzdW0oKHRlbXBfZGF0YSRjb3JyQW5zID09ICJub25lIiAmIHRlbXBfZGF0YSRrZXlfcmVzcF9zbGFzaC5rZXlzX3JhdyA9PSAiJ3NsYXNoJyIpLCBuYS5ybSA9IFRSVUUpCiAgIyBuZXh0LCBmaW5kIHRoZSBtaW5pbXVtIHJlc3BvbnNlIG5lZWRlZCBiYXNlZCBvbiB0aGUgNTAlIGNyaXRlcmlhCiAgbWluX3Jlc3AgPSB0cmlhbF90b3RfZ28gKiAuNTAKICAjIGZpbmQgaWYgdGhlIHBhcnRpY2lwYW50IG1lZXRzIGV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhlICJnbyIgYW5kICJuby1nbyIgdHJpYWxzCiAgbWVldHNfbWluX2dvID0gcmVzcF90b3RfZ28gPiAobWluX3Jlc3ApCiAgbWVldHNfbWluX25vZ28gPSByZXNwX3RvdF9ub2dvIDwgKG1pbl9yZXNwKQogICMgZmluZCBpZiB0aGUgcGFydGljaXBhbnQgbWVldHMgZXhjbHVzaW9uIGNyaXRlcmlhIChleGNsdWRlID0gMTsgaW5jbHVkZSA9IDIpCiAgZXhjbHVkZV9oID0gaWZlbHNlKChtZWV0c19taW5fZ28gPT0gIlRSVUUiICYgbWVldHNfbWluX25vZ28gPT0gIlRSVUUiKSA9PSAiRkFMU0UiLCAxLCAyKQogIAogIHRlbXBfZGF0YWZyYW1lX2ggPSBhcy5kYXRhLmZyYW1lKGMocGFydGljaXBhbnRfbG9uZywgYWdlX2xvbmcsIGxhbmdfbG9uZywgdHJpYWxfdG90X2gsIHNjb3JlX2gsIHJlc3BfdG90X2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9fcmVzcF90b3RfaCwgZXJyX3RvdF9oLCBlcnJfY29tX2gsIGVycl9vbWlfaCwgcnRfYXZfaCwgZXhjbHVkZV9oKSkKfSAgCgojLS0oMikgQ3JlYXRlIGEgbGlzdCBvZiBhbGwgdGhlIGRpcmVjdG9yeSBwYXRocyB0byBlYWNoIGluZGl2aWR1YWwgZmlsZSAKCiMgRmluZCB0aGUgbG9jYXRpb24gb2YgZWFjaCBleGNlbCAoLnhsc3gpIGZpbGVzCiMgdGhlIGZvbGRlcnMgY29udGFpbmluZyB0aGUgZmlsZXMgc2hvdWxkIGJlIGluIDEgZm9sZGVyIChlLmcuICIiIGluIHRoaXMgY2FzZSkKIyB0aGlzIHJldHVybnMgYSBsaXN0IG9mIGVhY2ggZmlsZSdzIGxvY2F0aW9uCiMgTm90ZTogdGhlIHBhdHRlcm4gaXMgc2V0IHRvIGlnbm9yZSBhbnkgaGlkZGVuIC8gdGVtcG9yYXJ5IGZpbGVzIGJ5IGFkZGluZyB0aGUgc3RhcnQgb2YgZWFjaCBmaWxlIG5hbWUgKGUuZy4gIl5Ob0dvIikKIyBUSElTIElTIFRIRSBTQU1FIEFTIElOIFRIRSBBQk9WRSBDT0RFLCBTTyBJVCBJUyBDT01NRU5URUQgT1VUIFRPIEFWT0lEIEVYVFJBIENPTVBVVElORyBQT1dFUgoKIyBmaWxlc19wc3ljaG9weSA9IGRpcigiL1VzZXJzL2FuYWNlY2lsaWFydWl6cGFyZG8vUlN0dWRpby9TbWFydHBob25lX3N0dWR5L1N0dWR5IDEtIFNtYXJ0cGhvbmUgUmVwbGljYXRpb24vRGlzc2VydGF0aW9uICgwNDoyMDoyMCkvUmF3IERhdGEgT3JnYW5pemluZy9nbmdfcmF3X2ZvbGRlcnMiLCAKIyAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZSA9IFRSVUUsIGZ1bGwubmFtZXM9VFJVRSwgcGF0dGVybj0iXk5vR28oLiopeGxzeCQiKQoKIy0tKDMpIEFwcGx5IHRoZSBmdW5jdGlvbiB0byB0aGUgZmlsZXMgCgojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBhbGwgZXhjZWwgZmlsZXMgZm9yIHRoZSAidmVydGljYWwiICh2KSBhbmQgImhvcml6b250YWwiIChoKSB0cmlhbHMgIApyZXN1bHRfdiA9IHNhcHBseShmaWxlc19wc3ljaG9weSwgZXh0cmFjdF9nbmdfdikKcmVzdWx0X2ggPSBzYXBwbHkoZmlsZXNfcHN5Y2hvcHksIGV4dHJhY3RfZ25nX2gpCgojLS0oNCkgQ3JlYXRlIGEgZGF0YSBmcmFtZSBvZiB0aGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbiBvbiB0aGUgZmlsZXMuLi4KIyBmb3IgdGhlICJ2ZXJ0aWNhbCIgKGduZ19kYXRhX2V4dHJhY3RlZF92KSBhbmQgImhvcml6b250YWwiIChnbmdfZGF0YV9leHRyYWN0ZWRfaCkgdHJpYWxzICAKCiMgdGFrZSB0aGUgbGlzdHMgb2YgdGhlIGV4dHJhY3RlZCBkYXRhIGFuZCB0dXJuIGl0IGludG8gYSBkYXRhIGZyYW1lIGZvciB0aGUgInZlcnRpY2FsIiAoaCkgdHJpYWxzCmduZ19kYXRhX2V4dHJhY3RlZF92ID0gZGF0YS5mcmFtZShSZWR1Y2UocmJpbmQsIHJlc3VsdF92KSkgCiMgcmVuYW1lIHRoZSBjb2x1bW5zCmNvbG5hbWVzKGduZ19kYXRhX2V4dHJhY3RlZF92KSA9IGMoInBhcnRpY2lwYW50X2xvbmciLCAiYWdlX2xvbmciLCAibGFuZ19sb25nIiwgInRyaWFsX3RvdF92IiwgInNjb3JlX3YiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzcF90b3RfdiIsICJub19yZXNwX3RvdF92IiwgImVycl90b3RfdiIsICJlcnJfY29tX3YiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXJyX29taV92IiwgInJ0X2F2X3YiLCAiZXhjbHVkZV92IikKCiMgdGFrZSB0aGUgbGlzdHMgb2YgdGhlIGV4dHJhY3RlZCBkYXRhIGFuZCB0dXJuIGl0IGludG8gYSBkYXRhIGZyYW1lIGZvciB0aGUgImhvcml6b250YWwiIChoKSB0cmlhbHMKZ25nX2RhdGFfZXh0cmFjdGVkX2ggPSBkYXRhLmZyYW1lKFJlZHVjZShyYmluZCwgcmVzdWx0X2gpKSAKIyByZW5hbWUgdGhlIGNvbHVtbnMKY29sbmFtZXMoZ25nX2RhdGFfZXh0cmFjdGVkX2gpID0gYygicGFydGljaXBhbnRfbG9uZyIsICJhZ2VfbG9uZyIsICJsYW5nX2xvbmciLCAidHJpYWxfdG90X2giLCAic2NvcmVfaCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlc3BfdG90X2giLCAibm9fcmVzcF90b3RfaCIsICJlcnJfdG90X2giLCAiZXJyX2NvbV9oIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXJyX29taV9oIiwgInJ0X2F2X2giLCAiZXhjbHVkZV9oIikKIyByZW1vdmUgcm93IG5hbWVzIHRvIGF2b2lkIGNvbmZ1c2lvbgpyb3duYW1lcyhnbmdfZGF0YV9leHRyYWN0ZWRfdikgPSBOVUxMCnJvd25hbWVzKGduZ19kYXRhX2V4dHJhY3RlZF9oKSA9IE5VTEwKCiMgcmVvcmdhbml6ZSByb3dzIHNvIHRoYXQgdGhlIGRhdGEgaXMgb3JkZXJlZCBieSB0aGUgcGFydGljaXBhbnQgbnVtYmVyIChlLmcuIDEsIDIsIDMsIDQuLi4pCmduZ19kYXRhX2V4dHJhY3RlZF92ID0gZHBseXI6OmFycmFuZ2UoZ25nX2RhdGFfZXh0cmFjdGVkX3YsIHBhcnRpY2lwYW50X2xvbmcpCmduZ19kYXRhX2V4dHJhY3RlZF9oID0gZHBseXI6OmFycmFuZ2UoZ25nX2RhdGFfZXh0cmFjdGVkX2gsIHBhcnRpY2lwYW50X2xvbmcpCmBgYAoKPC9kZXRhaWxzPgoKIyMjIyAzLiAmIDQuIERlbW9ncmFwaGljLCBTVVEsIGFuZCBTQUQgUmF3IERhdGEKClRoZSAqKkRlbW9ncmFwaGljICYgU1VRIFJhdyBEYXRhIGFuZCBTQUQgUmF3IERhdGEqKiB3YXMgY29sbGVjdGVkIHVzaW5nIFtRdWFsdHJpY3NdKGh0dHBzOi8vd3d3LnF1YWx0cmljcy5jb20vKS4gVGhlIHJhdyBzdXJ2ZXkgZGF0YSB3YXMgaW1wb3J0ZWQgYXMgYSBkYXRhIGZyYW1lLCAiKipzdXJ2ZXlfcmF3KioiLCBhbmQgaW5jbHVkZWQgdGhlIGZvbGxvd2luZzogKihjbGljayB0byBzZWUgZGVzY3JpcHRpb24pKgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCltHZW5lcmFsLCBNYW5pcHVsYXRpb24sIGFuZCBEZW1vZ3JhcGhpYyBJbmZvcm1hdGlvbl17c3R5bGU9ImNvbG9yOkRhcmtCbHVlOyBmb250LXNpemU6MThweDsifQoKPC9zdW1tYXJ5PgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCioqR2VuZXJhbCBJbmZvcm1hdGlvbjoqKiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgotICAgKipTdGFydCBEYXRlIFsqZGF0ZV9zdGFydCpdKioKCiAgICAtICAgVGhlIGRhdGUgYW5kIHRpbWUgd2hlbiBhIHBhcnRpY2lwYW50IGJlZ2FuIHRoZWlyIHN1cnZleSBvbiBRdWFsdHJpY3MgKFkvTS9EIEg6TSlcCgotICAgKipFbmQgRGF0ZSBbKmRhdGVfZW5kKl0qKgoKICAgIC0gICBUaGUgZGF0ZSBhbmQgdGltZSB3aGVuIGEgcGFydGljaXBhbnQgZmluaXNoZWQgdGhlaXIgc3VydmV5IG9uIFF1YWx0cmljcyAoWS9NL0QgSDpNKVwKCi0gICAqKkR1cmF0aW9uIChpbiBzZWNvbmRzKSBbKmR1cmF0aW9uKHMpKl0qKgoKICAgIC0gICBUaGUgZHVyYXRpb24gb2YgdGhlIHN1cnZleSBmb3IgdGhlIHBhcnRpY2lwYW50IGluIHNlY29uZHMKCi0gICAqKlJlY29yZGVkIERhdGUgWypkYXRlX3JlYypdKioKCiAgICAtICAgVGhlIGRhdGUgYW5kIHRpbWUgd2hlbiBhIHBhcnRpY2lwYW50J3MgZGF0YSB3YXMgcmVjb3JkZWQgb24gUXVhbHRyaWNzIChZL00vRCBIOk0pXAoKLSAgICoqUGFydGljaXBhbnQgbnVtYmVyIFsqc3VyX3BhcnRpY2lwYW50Kl0qKlwKCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgoqKk1hbmlwdWxhdGlvbiBDb25kaXRpb246KiogKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKLSAgICoqU21hcnRwaG9uZSBMb2NhdGlvbiBbKnN1cl9sb2NhdGlvbipdKioKCiAgICAtICAgVGhlIHNtYXJ0cGhvbmUgbG9jYXRpb24gYXNzaWduZWQgdG8gdGhlIHBhcnRpY2lwYW50IChpLmUuLCBkZXNrLCBwb2NrZXQvYmFnLCBvciBvdXRzaWRlKVwKCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgIHwgICAgICAgY29kZSB8ICAxICAgfCAgICAgMiAgICAgIHwgICAgMyAgICB8CiAgICAgICAgfC0tLS0tLS0tLS0tOnw6LS0tLTp8Oi0tLS0tLS0tLS06fDotLS0tLS0tOnwKICAgICAgICB8ICpyZXNwb25zZSogfCBEZXNrIHwgUG9ja2V0L0JhZyB8IE91dHNpZGUgfAoKLSAgICoqU21hcnRwaG9uZSBQb3dlciBbKnN1cl9wb3dlcipdKioKCiAgICAtICAgVGhlIHNtYXJ0cGhvbmUgcG93ZXIgYXNzaWduZWQgdG8gdGhlIHBhcnRpY2lwYW50IChpLmUuLCBPTiBvciBPRkYpXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgIHwgIDIgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS06fDotLS06fAogICAgICAgIHwgKnJlc3BvbnNlKiB8IE9uICB8IE9mZiB8CgotICAgKipTbWFydHBob25lIENvbmRpdGlvbiBbKnN1cl9jb25kaXRpb24qXSoqCgogICAgLSAgIFRoZSBzbWFydHBob25lIGNvbmRpdGlvbiAoaS5lLiwgY29tYmluYXRpb24gb2YgbG9jYXRpb24gJiBwb3dlcikgYXNzaWduZWQgdG8gdGhlIHBhcnRpY2lwYW50XAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IGNvZGUgICAgICAgfCAxICAgICAgICAgfCAyICAgICAgICAgICAgICAgfCAzICAgICAgICAgICAgfCA0ICAgICAgICAgIHwgNSAgICAgICAgICAgICAgICB8IDYgICAgICAgICAgICAgfAogICAgICAgICs9PT09PT09PT09PTorOj09PT09PT09PTorOj09PT09PT09PT09PT09PTorOj09PT09PT09PT09PTorOj09PT09PT09PT06Kzo9PT09PT09PT09PT09PT09Ois6PT09PT09PT09PT09PTorCiAgICAgICAgfCAqcmVzcG9uc2UqIHwgT04gJiBEZXNrIHwgT04gJiBQb2NrZXQvQmFnIHwgT04gJiBPdXRzaWRlIHwgT0ZGICYgRGVzayB8IE9GRiAmIFBvY2tldC9CYWcgfCBPRkYgJiBPdXRzaWRlIHwKICAgICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKwoKPC9kZXRhaWxzPgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCioqRGVtb2dyYXBoaWNzOioqICooY2xpY2sgdG8gZXhwYW5kKSoKCjwvc3VtbWFyeT4KCi0gICAqKkdlbmRlciBbKmdlbmRlcipdKioKCiAgICAtICAgUGFydGljaXBhbnQncyBzZWxmLXJlcG9ydGVkIGdlbmRlciAoaS5lLiwgbWFsZSwgZmVtYWxlLCBvdGhlciwgb3IgcHJlZmVyIG5vdCB0byBzYXkpXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgICB8ICAgMiAgICB8ICAgMyAgIHwgICAgICAgICA0ICAgICAgICAgfAogICAgICAgIHwtLS0tLS0tLS0tLTp8Oi0tLS06fDotLS0tLS06fDotLS0tLTp8Oi0tLS0tLS0tLS0tLS0tLS0tOnwKICAgICAgICB8ICpyZXNwb25zZSogfCBNYWxlIHwgRmVtYWxlIHwgT3RoZXIgfCBQcmVmZXIgbm90IHRvIHNheSB8CgotICAgKipZZWFyIFsqeWVhcipdKioKCiAgICAtICAgUGFydGljaXBhbnQncyBzZWxmLXJlcG9ydGVkIHllYXIgb2Ygc3R1ZHkgaW4gdGhlaXIgcmVzcGVjdGl2ZSBwcm9ncmFtIChlLmcuLCAxLCAyLCAzLCA0KVwKCi0gICAqKlByb2dyYW0gWypwcm9ncmFtKl0qKgoKICAgIC0gICBQYXJ0aWNpcGFudCdzIHNlbGYtcmVwb3J0ZWQgcHJvZ3JhbSBvZiBzdHVkeSAoZS5nLiwgYmlvbG9neSwgQk1PUywgcHN5Y2hvbG9neSlcCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAgICAgICAgfCAxID0gYWN0dWFyaWFsICAgICAgICAgIHwgMTEgPSBlY29ub21pY3MgICAgICAgICAgfCAyMSA9IG1hbmFnZW1lbnQgICAgICAgICAgICB8IDMxID0gcHN5Y2hvbG9neSAgICAgfAogICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IDIgPSBhbnRocm9wb2xvZ3kgICAgICAgfCBzY2llbmNlICAgICAgICAgICAgICAgICB8IDIyID0gbWF0aGVtYXRpY3MgICAgICAgICAgIHwgMzIgPSBTQVNBSCAgICAgICAgICB8CiAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICAgIHwgMyA9IGFydHMgICAgICAgICAgICAgICB8IDEzID0gZW5nbGlzaCAgICAgICAgICAgIHwgMjMgPSBtZWRpY2FsIHNjaWVuY2UgICAgICAgfCAzMyA9IHNjaWVuY2UgICAgICAgIHwKICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAgICAgICAgfCA0ID0gYXJ0cyAmIGh1bWFuaXRpZXMgIHwgMTQgPSBmaWxtICAgICAgICAgICAgICAgfCAyNCA9IE1JVCAgICAgICAgICAgICAgICAgICB8IDM0ID0gc29jaWFsIHNjaWVuY2UgfAogICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IDUgPSBiaW9sb2d5ICAgICAgICAgICAgfCAxNSA9IEZJTVMgICAgICAgICAgICAgICB8IDI1ID0gTU9TICAgICAgICAgICAgICAgICAgIHwgMzUgPSBzb2Npb2xvZ3kgICAgICB8CiAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICAgIHwgNiA9IEJNT1MgICAgICAgICAgICAgICB8IDE2ID0gZ2VvZ3JhcGh5ICAgICAgICAgIHwgMjYgPSBtdXNpYyAgICAgICAgICAgICAgICAgfCAzNiA9IHNvZnR3YXJlICAgICAgIHwKICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAgICAgICAgfCA3ID0gY2hlbWlzdHJ5ICAgICAgICAgIHwgMTcgPSBoZWFsdGggc2NpZW5jZSAgICAgfCAyNyA9IG51dHJpdGlvbiAmIGRpZXRldGljcyB8IDM3ID0gdmlzdWFsIGFydHMgICAgfAogICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IDggPSBjb21wdXRlciBzY2llbmNlICAgfCAxOCA9IGludGVncmF0ZWQgc2NpZW5jZSB8IDI4ID0gcGhpbG9zb3BoeSAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICAgIHwgOSA9IGNvbnN1bWVyIGJlaGF2aW91ciB8IDE5ID0ga2luZXNpb2xvZ3kgICAgICAgIHwgMjkgPSBwaHlzaWNzICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwKICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAgICAgICAgfCAxMCA9IGNyaW1pbm9sb2d5ICAgICAgIHwgMjAgPSBsaW5ndWlzdGljcyAgICAgICAgfCAzMCA9IHBvbGl0aWNhbCBzY2llbmNlICAgICB8ICAgICAgICAgICAgICAgICAgICAgfAogICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIyMjIFRoZSBTbWFydHBob25lIFVzZSBRdWVzdGlvbm5haXJlIChTVVEpCgpUaGUgcHVycG9zZSBvZiB0aGUgU1VRIHdhcyB0byBtZWFzdXJlIHBhcnRpY2lwYW50cycgdHlwaWNhbCBzbWFydHBob25lIHVzZS4gVGhlIFNVUSB3YXMgY3JlYXRlZCBmb3IgdGhlIHByZXNlbnQgc3R1ZHkgYW5kIGNvbnNpc3RlZCBvZiBtb2RpZmllZCBpdGVtcyBmcm9tIFdhcmQgYW5kIGNvbGxlYWd1ZXMnICgyMDE3KSBzdXJ2ZXkgbWVhc3VyZXMuIChpLmUuIGZvdW5kIGluIHRoZSAiQlJBSU4gRFJBSU4iIFdFQiBBUFBFTkRJWCIpLiBTb21lIGl0ZW1zIHdlcmUgZm9yY2VkLWNob2ljZSBhbmQgc29tZSB3ZXJlIG9uIGEgNy1wb2ludCBsaWtlcnQgc2NhbGUgcmFuZ2luZyBmcm9tIDEgKCJOZXZlciIpIHRvIDcgKCJBbHdheXMiKS4gVGhlcmUgd2VyZSAxMCBpdGVtcyBpbiB0b3RhbCBhbmQgdGhlcmUgd2VyZSAqKmZpdmUgdHlwZXMgb2YgaXRlbXMqKiwgd2hpY2ggbWVhc3VyZWQ6Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKKioxLiBTbWFydHBob25lIFVzZSBGcmVxdWVuY3k6ICgqU1VRX3VzZV8xIC0gU1VRX3VzZV8zKikqKgoKPC9zdW1tYXJ5PgoKRWFjaCBvZiB0aGUgZm9sbG93aW5nIGl0ZW1zIHVzZWQgdGhlIGZvbGxvd2luZyBjb2Rpbmc6Cgp8ICAgICAgIENPREUgfCAgMSAgfCAgMiAgIHwgICAzICAgfCAgIDQgICB8CnwtLS0tLS0tLS0tLTp8Oi0tLTp8Oi0tLS06fDotLS0tLTp8Oi0tLS0tOnwKfCAqcmVzcG9uc2UqIHwgMC01IHwgNi0xMCB8IDExLTE1IHwgXD4gMTUgfAoKLSAgICoqVGV4dCBNZXNzYWdlcyAocGVyIGRheSkgWypTVVFfdXNlXzEqXSoqCgogICAgLSAgIEFuc3dlciB0byB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uOiAiKk9uIGF2ZXJhZ2UsIGhvdyBtYW55IHRleHQgbWVzc2FnZXMgZG8geW91IHNlbmQgcGVyIGRheT8qIlwKCi0gICAqKlNvY2lhbCBNZWRpYSBNZXNzYWdlcyAocGVyIGRheSkgWypTVVFfdXNlXzIqXSoqCgogICAgLSAgIEFuc3dlciB0byB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uOiAiKk9uIGF2ZXJhZ2UsIGhvdyBtYW55IHNvY2lhbCBtZWRpYSBiYXNlZCBtZXNzYWdlcyBkbyB5b3Ugc2VuZCBwZXIgZGF5IGZyb20geW91ciBzbWFydHBob25lPyAoaU1lc3NhZ2UsIEZhY2Vib29rIE1lc3NlbmdlciwgV2hhdHNBcHAsIFdlQ2hhdCwgZGlyZWN0IG1lc3NhZ2VzIHdpdGhpbiBzb2NpYWwgbWVkaWEgcGxhdGZvcm1zLCBldGMuKSoiXAoKLSAgICoqU29jaWFsIE1lZGlhIFBvc3RzIChwZXIgZGF5KSBbKlNVUV91c2VfMypdKioKCiAgICAtICAgQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqT24gYXZlcmFnZSwgaG93IG1hbnkgc29jaWFsIG1lZGlhIHBvc3RzIChlLmcuIHdyaXR0ZW4gcG9zdCwgcGljdHVyZSwgYXJ0aWNsZSwgZXRjLikgZG8geW91IHNlbmQgcGVyIGRheSBmcm9tIHlvdXIgc21hcnRwaG9uZT8gKEZhY2Vib29rLCBUd2l0dGVyLCBJbnN0YWdyYW0sIGV0Yy4pKiJcCgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKKioyLiBTbWFydHBob25lIFVzZSBXaXRoIEV4dGVybmFsIFN0aW11bGF0aW9uIG9yIER1cmluZyBPdGhlciBBY3Rpdml0aWVzOiAoKlNVUV91c2VfNCAtIFNVUV91c2VfNyopKioKCjwvc3VtbWFyeT4KCkVhY2ggb2YgdGhlIGZvbGxvd2luZyBpdGVtcyB1c2VkIHRoZSBmb2xsb3dpbmcgY29kaW5nOgoKfCAgICAgICAgICAgICAgICAgICBjb2RlIHwgICAxICAgfCAgMiAgfCAgMyAgfCAgICAgICAgICAgIDQgICAgICAgICAgICB8IDUgICB8IDYgICB8IDcgICAgICB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8Oi0tLS0tOnw6LS0tOnw6LS0tOnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fC0tLS0tfC0tLS0tfC0tLS0tLS0tfAp8ICAgICAgICAgICAgICpyZXNwb25zZSogfCBOZXZlciB8IC0tICB8IC0tICB8IEFib3V0IGhhbGYgPGJyPnRoZSB0aW1lIHwgLS0gIHwgLS0gIHwgQWx3YXlzIHwKfCAtLSAqbm8gdGV4dCBzcGVjaWZpZWQqIHwgICAgICAgfCAgICAgfCAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICB8ICAgICB8ICAgICAgICB8CgotICAgKipUZW5kZW5jeSB0byB0dXJuIHRvIG9uZSdzIHNtYXJ0cGhvbmUgaW4gdGhlIGFic2VuY2Ugb2YgZXh0ZXJuYWwgc3RpbXVsYXRpb24gWypTVVFfdXNlXzQqICYgKlNVUV91c2VfNSpdKioKCiAgICAtICAgKipTVVFfdXNlXzQqKjogQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqSSBsb29rIGF0IG15IHNtYXJ0cGhvbmUgYmVmb3JlIEkgcm9sbCBvdXQgb2YgYmVkIGluIHRoZSBtb3JuaW5nLioiXAogICAgLSAgICoqU1VRX3VzZV81Kio6IEFuc3dlciB0byB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uOiAiKklmIEkgYW0gd2FpdGluZyB0byBtZWV0IGEgZnJpZW5kLCBJIHBhc3MgdGhlIHRpbWUgYnkgdXNpbmcgbXkgc21hcnRwaG9uZS4qIgoKLSAgICoqVGVuZGVuY3kgdG8gdHVybiB0byBvbmUncyBzbWFydHBob25lIGluIHRoZSBtaWRzdCBvZiBvdGhlciBhY3Rpdml0aWVzIFsqU1VRX3VzZV82U1VRX3VzZV83Kl0qKgoKICAgIC0gICAqKlNVUV91c2VfNioqOiBBbnN3ZXIgdG8gdGhlIGZvbGxvd2luZyBxdWVzdGlvbjogIipJIHVzZSBteSBzbWFydHBob25lIHdoaWxlIGRyaXZpbmcuKiJcCiAgICAtICAgKipTVVFfdXNlXzcqKjogQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqSWYgbXkgc21hcnRwaG9uZSByaW5ncyBvciB2aWJyYXRlcyBpbiB0aGUgbWlkZGxlIG9mIHBlcnNvbmFsIGJ1c2luZXNzLCBJIGxvb2sgYXQgaXQuKiJcCgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKKiozLiBTbWFydHBob25lIFN1YmplY3RpdmUgVmFsdWU6ICgqU1VRX2V4cF8xKikqKgoKPC9zdW1tYXJ5PgoKLSAgICoqU3ViamVjdGl2ZSBWYWx1ZSBbKlNVUV91c2VfMSpdKioKCiAgICAtICAgQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqSG93IG11Y2ggbW9uZXkgd291bGQgaXQgdGFrZSBmb3IgeW91IHRvIGdpdmUgdXAgeW91ciBwaG9uZSBmb3IgYSBmdWxsIGRheT8qIlwKCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgIHwgICAgICAgY29kZSB8ICAgIDEgICAgIHwgICAgIDIgICAgIHwgICAgIDMgICAgIHwgICAgNCAgICB8CiAgICAgICAgfC0tLS0tLS0tLS0tOnw6LS0tLS0tLS06fDotLS0tLS0tLS06fDotLS0tLS0tLS06fDotLS0tLS0tOnwKICAgICAgICB8ICpyZXNwb25zZSogfCBcJDAtXCQyMCB8IFwkMjEtXCQ0MCB8IFwkNDEtXCQ2MCB8IFw+IFwkNjAgfAoKPC9kZXRhaWxzPgoKPC9kZXRhaWxzPgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCioqNC4gU21hcnRwaG9uZSBOb3RpZmljYXRpb24gVHlwZTogKCpTVVFfZXhwXzIgJiBTVVFfZXhwXzMqKSoqCgo8L3N1bW1hcnk+CgotICAgKipOb3RpZmljYXRpb24gVHlwZSBbKlNVUV91c2VfMipdKioKCiAgICAtICAgQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqRG8geW91IHJlY2VpdmUgbm90aWZpY2F0aW9ucyAoYSBzb3VuZCBvciB2aWJyYXRpb24pIG9uIHlvdXIgcGhvbmU/IFBsZWFzZSBpbmRpY2F0ZSBhbGwgdGhhdCBhcHBseS4qIlwKCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgIHwgICAgICAgY29kZSB8ICAgMSAgIHwgICAgMiAgICAgfCAgICAzICAgIHwgICAgIDQgICAgIHwgICAgNSAgICAgfCAgICA2ICAgICB8ICAgICAgICA3ICAgICAgICB8CiAgICAgICAgfC0tLS0tLS0tLS0tOnw6LS0tLS06fDotLS0tLS0tLTp8Oi0tLS0tLS06fDotLS0tLS0tLS06fDotLS0tLS0tLTp8Oi0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLS0tOnwKICAgICAgICB8ICpyZXNwb25zZSogfCBFbWFpbCB8IEZhY2Vib29rIHwgVHdpdHRlciB8IEluc3RhZ3JhbSB8IExpbmtlZEluIHwgU25hcGNoYXQgfCBPdGhlciAoc3BlY2lmeSkgfAoKLSAgICoqU3BlY2lmeSBOb3RpZmljYXRpb24gVHlwZSBbKlNVUV9leHBfMypdKioKCiAgICAtICAgQW5zd2VyIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246ICIqUGxlYXNlIFNwZWNpZnk6IFdoZXJlIHlvdSByZWNlaXZlIG5vdGlmaWNhdGlvbnMgKGEgc291bmQgb3IgdmlicmF0aW9uKSBvbiB5b3VyIHBob25lPyoiCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKKio1LiBQaGFudG9tIFZpYnJhdGlvbnM6ICgqU1VRX2V4cF80KikqKgoKPC9zdW1tYXJ5PgoKLSAgICoqUGhhbnRvbSBWaWJyYXRpb25zIFsqU1VRX3VzZV80Kl0qKgoKICAgIC0gICBBbnN3ZXIgdG8gdGhlIGZvbGxvd2luZyBxdWVzdGlvbjogIipIYXZlIHlvdSBldmVyIHRob3VnaHQgeW91IGhlYXJkIHlvdXIgcGhvbmUgcmluZyBvciB0aG91Z2h0IHlvdSBmZWx0IGl0IHZpYnJhdGUsIG9ubHkgdG8gZmluZCBvdXQgeW91IHdlcmUgd3Jvbmc/KiJcCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICB8ICAgICAgIGNvZGUgfCAgMSAgfCAgMiAgfAogICAgICAgIHwtLS0tLS0tLS0tLTp8Oi0tLTp8Oi0tLTp8CiAgICAgICAgfCAqcmVzcG9uc2UqIHwgWWVzIHwgTm8gIHwKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIyMjIFRoZSBTbWFydHBob25lIEF0dGFjaG1lbnQgYW5kIERlcGVuZGVuY3kgSW52ZW50b3J5IChTQUQ7IFdhcmQgZXQgYWwuLCAyMDE3KQoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoZSBTQUQgYXNrZWQgcGFydGljaXBhbnRzIHRvIHJlc3BvbmQgdG8gMTMgaXRlbXMgKiooKlNBRF8xLVNBRF8xMyopKiogdXNpbmcgYSA3LXBvaW50IGxpa2VydCBzY2FsZS4gKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgY29kZSAgICAgICB8IDEgICAgICAgICAgICAgICAgICAgIHwgMiAgICAgICAgfCAzICAgICAgICAgICAgICAgICAgICB8IDQgICAgICAgfCA1ICAgICAgICAgICAgICAgICB8IDYgICAgIHwgNyAgICAgICAgICAgICAgICAgfAorPT09PT09PT09PT06Kzo9PT09PT09PT09PT09PT09PT09PTorOj09PT09PT09Ois6PT09PT09PT09PT09PT09PT09PT06Kzo9PT09PT09Ois6PT09PT09PT09PT09PT09PT06Kzo9PT09PTorOj09PT09PT09PT09PT09PT09OisKfCAqcmVzcG9uc2UqIHwgU3Ryb25nbHk8YnI+RGlzYWdyZWUgfCBEaXNhZ3JlZSB8IFNvbWV3aGF0PGJyPkRpc2FncmVlIHwgTmV1dHJhbCB8IFNvbWV3aGF0PGJyPkFncmVlIHwgQWdyZWUgfCBTdHJvbmdseTxicj5BZ3JlZSB8CistLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tKwoKLSAgICoqU0FEXzE6KiogSSB3b3VsZCBoYXZlIHRyb3VibGUgZ2V0dGluZyB0aHJvdWdoIGEgbm9ybWFsIGRheSB3aXRob3V0IG15IHNtYXJ0cGhvbmUuXAotICAgKipTQURfMjoqKiBJdCB3b3VsZCBiZSBwYWluZnVsIGZvciBtZSB0byBnaXZlIHVwIG15IHNtYXJ0cGhvbmUgZm9yIGEgZGF5LlwKLSAgICoqU0FEXzM6KiogSSBmZWVsIGxpa2UgSSBjb3VsZCBub3QgbGl2ZSB3aXRob3V0IG15IHNtYXJ0cGhvbmUuXAotICAgKipTQURfNDoqKiBJZiBJIGZvcmdvdCB0byBicmluZyBteSBzbWFydHBob25lIHdpdGggbWUsIEkgd291bGQgZmVlbCBhbnhpb3VzLlwKLSAgICoqU0FEXzU6KiogSXQgZHJpdmVzIG1lIGNyYXp5IHdoZW4gbXkgc21hcnRwaG9uZSBydW5zIG91dCBvZiBiYXR0ZXJ5LlwKLSAgICoqU0FEXzY6KiogSSBhbSB1cHNldCBhbmQgYW5ub3llZCB3aGVuIEkgZmluZCBJIGRvIG5vdCBoYXZlIHJlY2VwdGlvbiBvbiBteSBzbWFydHBob25lLlwKLSAgICoqU0FEXzc6KiogSSBmZWVsIGltcGF0aWVudCB3aGVuIHRoZSBJbnRlcm5ldCBjb25uZWN0aW9uIHNwZWVkIG9uIG15IHNtYXJ0cGhvbmUgaXMgc2xvdy5cCi0gICAqKlNBRF84OioqIEkgZmVlbCBsb25lbHkgd2hlbiBteSBzbWFydHBob25lIGRvZXMgbm90IHJpbmcgb3IgdmlicmF0ZSBmb3Igc2V2ZXJhbCBob3Vycy5cCi0gICAqKlNBRF85OioqIFVzaW5nIG15IHNtYXJ0cGhvbmUgcmVsaWV2ZXMgbWUgb2YgbXkgc3RyZXNzLlwKLSAgICoqU0FEXzEwOioqIEkgZmVlbCBleGNpdGVkIHdoZW4gSSBoYXZlIGEgbmV3IG1lc3NhZ2Ugb3Igbm90aWZpY2F0aW9uLlwKLSAgICoqU0FEXzExOioqIFVzaW5nIG15IHNtYXJ0cGhvbmUgbWFrZXMgbWUgZmVlbCBoYXBweS5cCi0gICAqKlNBRF8xMjoqKiBJIGZpbmQgaXQgdG91Z2ggdG8gZm9jdXMgd2hlbmV2ZXIgbXkgc21hcnRwaG9uZSBpcyBuZWFyYnkuXAotICAgKipTQURfMTM6KiogSSBiZWNvbWUgbGVzcyBhdHRlbnRpdmUgdG8gbXkgc3Vycm91bmRpbmdzIHdoZW4gSSdtIHVzaW5nIG15IHNtYXJ0cGhvbmUuCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIGltcG9ydGVkIHRoZSBEZW1vZ3JhcGhpYywgU1VRLCBhbmQgU0FEIHJhdyBkYXRhLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7ciBpbXBvcnRfc3VydmV5X3JhdywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc3VydmV5X3JhdyA9IHV0aWxzOjpyZWFkLmNzdigicmF3X3N1cnZleS5jc3YiLCBoZWFkZXIgPSBUUlVFKQoKIyByZW9yZ2FuaXplIHJvd3Mgc28gdGhhdCB0aGUgZGF0YSBpcyBvcmRlcmVkIGJ5IHRoZSBwYXJ0aWNpcGFudCBudW1iZXIgKGUuZy4gMSwgMiwgMywgNC4uLikKc3VydmV5X3JhdyA9IGRwbHlyOjphcnJhbmdlKHN1cnZleV9yYXcsIHN1cl9wYXJ0aWNpcGFudCkKCnN1cnZleV9yYXcKYGBgCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+CgojIyMjIDUuIFRlc3RpbmcgVHJhY2tpbmcgU2hlZXQgUmF3IERhdGEKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgKipUZXN0aW5nIFRyYWNraW5nIFNoZWV0IFJhdyBEYXRhKiogd2FzIGNvbGxlY3RlZCBkdXJpbmcgdGVzdGluZyAqYnkgdGhlIGV4cGVyaW1lbnRlciogdG8gc3RvcmUgcmVsZXZhbnQgaW5mb3JtYXRpb24gb24gcGFydGljaXBhbnQncyAoMSkgR2VuZXJhbCBJbmZvcm1hdGlvbiAoZS5nLiB0ZXN0aW5nIHN0YXJ0IGRhdGUpLCAoMikgTWFuaXB1bGF0aW9uIENvbmRpdGlvbiAoZS5nLiBhc3NpZ25lZCBsb2NhdGlvbiBhbmQgcG93ZXIgbWFuaXB1bGF0aW9uKSwgYW5kICgzKSBEYXRhIENsZWFuaW5nIChlLmcuIGV4Y2x1c2lvbiBjcml0ZXJhIGZyb20gdGVzdGluZyBlcnJvciBvciBvdGhlciBub24tdGFzay1zcGVjaWZpYyBjcml0ZXJpYSkuIFRoZSByYXcgZGF0YSBmcm9tIHRoZSB0cmFja2luZyBzaGVldCB3YXMgaW1wb3J0ZWQgYXMgYSBkYXRhZnJhbWUsICIqKnRyYWNrX3JhdyoqIiwgYW5kIGluY2x1ZGVkIHRoZSBmb2xsb3dpbmc6ICooY2xpY2sgdG8gc2VlIGRlc2NyaXB0aW9uKSoKCjwvc3VtbWFyeT4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgoqKjEuIEdlbmVyYWwgSW5mb3JtYXRpb246KioKCjwvc3VtbWFyeT4KCi0gICAqKlRlc3RpbmcgRGF0ZSBbKnRyYWNrX2RhdGUqXSoqCgogICAgLSAgIFRoZSBkYXRlIGEgcGFydGljaXBhbnQgY29tcGxldGVkIHRoZSBzdHVkeSAoWS9NL0QpXAoKLSAgICoqVGVzdGluZyBUaW1lIFsqZGF0ZV9lbmQqXSoqCgogICAgLSAgIFRoZSB0aW1lIGEgcGFydGljaXBhbnQgd2FzIHNjaGVkdWxlZCB0byBjb21wbGV0ZSB0aGUgc3R1ZHkgKDI0aHItdGltZSkuICpOb3RlOiBNYW55IHBhcnRpY2lwYW50cyB3ZXJlIHRlc3RlZCBhdCB0aGUgc2FtZSB0aW1lLCBidXQgaW4gc2VwYXJhdGUgY3ViaWNsZS10eXBlIGRlc2tzIHRvIGF2b2lkIGFueSBncm91cC10ZXN0aW5nIGR5bmFtaWMqXAoKLSAgICoqUGFydGljaXBhbnQgbnVtYmVyIFsqdHJhY2tfcGFydGljaXBhbnQqXSoqXAoKPC9kZXRhaWxzPgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCioqMi4gTWFudXB1bGF0aW9uIENvbmRpdGlvbjoqKgoKPC9zdW1tYXJ5PgoKLSAgICoqU21hcnRwaG9uZSBMb2NhdGlvbiBbKnRyYWNrX2xvY2F0aW9uKl0qKgoKICAgIC0gICBUaGUgc21hcnRwaG9uZSBsb2NhdGlvbiBhc3NpZ25lZCB0byB0aGUgcGFydGljaXBhbnQgKGkuZS4sIGRlc2ssIHBvY2tldC9iYWcsIG9yIG91dHNpZGUpXAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgfCAgICAgICBjb2RlIHwgIDEgICB8ICAgICAyICAgICAgfCAgICAzICAgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS0tOnw6LS0tLS0tLS0tLTp8Oi0tLS0tLS06fAogICAgICAgIHwgKnJlc3BvbnNlKiB8IERlc2sgfCBQb2NrZXQvQmFnIHwgT3V0c2lkZSB8CgotICAgKipTbWFydHBob25lIFBvd2VyIFsqdHJhY2tfcG93ZXIqXSoqCgogICAgLSAgIFRoZSBzbWFydHBob25lIHBvd2VyIGFzc2lnbmVkIHRvIHRoZSBwYXJ0aWNpcGFudCAoaS5lLiwgT04gb3IgT0ZGKVwKCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgIHwgICAgICAgY29kZSB8ICAxICB8ICAyICB8CiAgICAgICAgfC0tLS0tLS0tLS0tOnw6LS0tOnw6LS0tOnwKICAgICAgICB8ICpyZXNwb25zZSogfCBPbiAgfCBPZmYgfAoKLSAgICoqU21hcnRwaG9uZSBDb25kaXRpb24gWyp0cmFja19jb25kaXRpb24qXSoqCgogICAgLSAgIFRoZSBzbWFydHBob25lIGNvbmRpdGlvbiAoaS5lLiwgY29tYmluYXRpb24gb2YgbG9jYXRpb24gJiBwb3dlcikgYXNzaWduZWQgdG8gdGhlIHBhcnRpY2lwYW50XAoKICAgICAgICA8ZGV0YWlscz4KCiAgICAgICAgPHN1bW1hcnk+CgogICAgICAgIGNvZGluZyBpbmZvcm1hdGlvbiAqKGNsaWNrIHRvIGV4cGFuZCkqCgogICAgICAgIDwvc3VtbWFyeT4KCiAgICAgICAgKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IGNvZGUgICAgICAgfCAxICAgICAgICAgfCAyICAgICAgICAgICAgICAgfCAzICAgICAgICAgICAgfCA0ICAgICAgICAgIHwgNSAgICAgICAgICAgICAgICB8IDYgICAgICAgICAgICAgfAogICAgICAgICs9PT09PT09PT09PTorOj09PT09PT09PTorOj09PT09PT09PT09PT09PTorOj09PT09PT09PT09PTorOj09PT09PT09PT06Kzo9PT09PT09PT09PT09PT09Ois6PT09PT09PT09PT09PTorCiAgICAgICAgfCAqcmVzcG9uc2UqIHwgT04gJiBEZXNrIHwgT04gJiBQb2NrZXQvQmFnIHwgT04gJiBPdXRzaWRlIHwgT0ZGICYgRGVzayB8IE9GRiAmIFBvY2tldC9CYWcgfCBPRkYgJiBPdXRzaWRlIHwKICAgICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKwoKLSAgICoqQ291bnRlciBCYWxhbmNlZCBPcmRlciBbKmJhbGFuY2UqXSoqCgogICAgLSAgIFRoaXMgZGVwaWN0cyB3aGljaCBvZiB0aGUgbWFpbiB0YXNrcyAoaS5lLiwgZWl0aGVyIHRoZSBPU3BhbiB0YXNrIG9yIHRoZSBDdWUtRGVwZW5kZW50IEdvL05vLUdvIFRhc2spIHdhcyBjb21wbGV0ZWQgZmlyc3RcCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogICAgICAgIHwgY29kZSAgICAgICB8IDEgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICAgKz09PT09PT09PT09Ois6PT09PT09PT09PT09PT09PT09PT09PT09PT06Kzo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OisKICAgICAgICB8ICpyZXNwb25zZSogfCBPU3BhbiBUYXNrIGNvbXBsZXRlZCBmaXJzdCB8IEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzayBjb21wbGV0ZWQgZmlyc3QgfAogICAgICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKKiozLiBEYXRhIENsZWFuaW5nOioqCgo8L3N1bW1hcnk+CgotICAgKipFeGNsdWRlIGZyb20gQW5hbHlzaXMgWypleGNsdWRlKl0qKgoKICAgIC0gICBUaGlzIGRlcGljdHMgd2hldGhlciBhIHBhcnRpY2lwYW50IHNob3VsZCBiZSBleGNsdWRlZCBmcm9tIGFuYWx5c2lzIGR1ZSB0byB0ZXN0aW5nIGVycm9yIG9yIG90aGVyIG5vbi10YXNrLXNwZWNpZmljIGNyaXRlcmlhIChpLmUuLCBmb3IgcmVhc29ucyBvdGhlciB0aGFuIHRoZSB0YXNrIGV4Y2x1c2lvbiBjcml0ZXJpYSBpbiB0aGUgZGF0YSBhbmFseXNpcyBwbGFuKS4KCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgIHwgICAgICAgY29kZSB8ICAgICAgICAgICAgICAgMSAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgMiAgICAgICAgICAgICAgIHwKICAgICAgICB8LS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8CiAgICAgICAgfCAqcmVzcG9uc2UqIHwgWWVzIChwYXJ0aWNpcGFudCAqKmV4Y2x1ZGVkKiopIHwgTm8gKHBhcnRpY2lwYW50ICoqaW5jbHVkZWQqKikgfAoKLSAgICoqUmVhc29uIGZvciBFeGNsdXNpb24gZnJvbSBBbmFseXNpcyBbKnJlYXNvbipdKioKCiAgICAtICAgVGhpcyBkZXBpY3RzIHRoZSByZWFzb24gKHN1bW1hcml6ZWQgaW50byA1IGNhdGVnb3JpZXMpIGEgcGFydGljaXBhbnQgc2hvdWxkIGJlIGV4Y2x1ZGVkIGZyb20gYW5hbHlzaXMgZHVlIHRvIHRlc3RpbmcgZXJyb3Igb3Igb3RoZXIgbm9uLXRhc2stc3BlY2lmaWMgY3JpdGVyaWEgKGkuZS4sIGZvciByZWFzb25zIG90aGVyIHRoYW4gdGhlIHRhc2sgZXhjbHVzaW9uIGNyaXRlcmlhIGluIHRoZSBkYXRhIGFuYWx5c2lzIHBsYW4pLiAqTm90ZTogdGhpcyBpbmNsdWRlcyBhIGNhdGVnb3J5IGZvciAibm8gZXhjbHVzaW9uIGlzc3VlcyIsIHdoZXJlIGEgcGFydGljaXBhbnQgd2FzIG5vdCBleGNsdWRlZCpcCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKwogICAgICAgIHwgY29kZSAgICAgICB8IDEgICAgICAgICAgICAgICAgICAgfCAyICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAzICAgICAgICAgICAgICB8IDQgICAgICAgICAgIHwgNSAgICAgICAgICAgICB8CiAgICAgICAgKz09PT09PT09PT09Ois6PT09PT09PT09PT09PT09PT09PTorOj09PT09PT09PT09PT09PT09PT09PT09PT09PTorOj09PT09PT09PT09PT09Ois6PT09PT09PT09PT06Kzo9PT09PT09PT09PT09OisKICAgICAgICB8ICpyZXNwb25zZSogfCBubyBleGNsdXNpb24gaXNzdWVzIHwgZXh0ZXJuYWwgZGlzdHJhY3RvciAobm9pc2UpIHwgZ25nIGluY29tcGxldGUgfCBnbmcgbWlzc2luZyB8IG9zcGFuIG1pc3NpbmcgfAogICAgICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0rCgotICAgKipQb3NzaWJsZSBPdXRsaWVyIFsqcG9zX291dCpdKioKCiAgICAtICAgVGhpcyBkZXBpY3RzIHdoZXRoZXIgYSBwYXJ0aWNpcGFudCBpcyBhIHBvc3NpYmxlIG91dGxpZXIgZm9yIGV4cGxvcmF0b3J5IGFuYWx5c2VzLiAqTm90ZTogdGhpcyB3YXMgbm90IGFwcGxpZWQgdG8gYW55IGFuYWx5c2lzIHVubGVzcyBleHBsaWNpdGx5IHN0YXRlZCoKCiAgICAgICAgPGRldGFpbHM+CgogICAgICAgIDxzdW1tYXJ5PgoKICAgICAgICBjb2RpbmcgaW5mb3JtYXRpb24gKihjbGljayB0byBleHBhbmQpKgoKICAgICAgICA8L3N1bW1hcnk+CgogICAgICAgICstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgICAgICB8IGNvZGUgICAgICAgfCAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICAgKz09PT09PT09PT09Ois6PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTorOj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT06KwogICAgICAgIHwgKnJlc3BvbnNlKiB8IFllcyAoZG9lcyBxdWFsaWZ5IGFzIGEgcG9zc2libGUgb3V0bGllcikgfCBObyAoZG9lcyBub3QgcXVhbGlmeSBhcyBhIHBvc3NpYmxlIG91dGxpZXIpIHwKICAgICAgICArLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgotICAgKipFeHBlcmltZW50ZXIgWypleHBlcmltZW50ZXIqXSoqCgogICAgLSAgIFRoaXMgZGVwaWN0cyB3aGljaCBleHBlcmltZW50ZXIgKDMgdG90YWwpIGNvbGxlY3RlZCB0aGUgZGF0YSBmb3IgYSBwYXJ0aWNpcGFudC4gKk5vdGU6IHRoaXMgd2FzIGNvbGxlY3RlZCBmb3IgZXhwbG9yYXRvcnkgYW5hbHlzZXMgYW5kIHdhcyBub3QgdXNlZCB1bmxlc3MgZXhwbGljaXRseSBzdGF0ZWQqCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgY29kaW5nIGluZm9ybWF0aW9uICooY2xpY2sgdG8gZXhwYW5kKSoKCiAgICAgICAgPC9zdW1tYXJ5PgoKICAgICAgICB8ICAgICAgIGNvZGUgfCAgMSAgfCAgMiAgfCAgMyAgfAogICAgICAgIHwtLS0tLS0tLS0tLTp8Oi0tLTp8Oi0tLTp8Oi0tLTp8CiAgICAgICAgfCAqcmVzcG9uc2UqIHwgQVJQIHwgU1cgIHwgTE0gIHwKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgaW1wb3J0ZWQgdGhlIHN0dWR5IHRyYWNraW5nIHNoZWV0IHJhdyBkYXRhLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7cn0KdHJhY2tfcmF3ID0gdXRpbHM6OnJlYWQuY3N2KCJyYXdfdHJhY2tpbmcuY3N2IiwgaGVhZGVyID0gVFJVRSkKCiMgcmVvcmdhbml6ZSByb3dzIHNvIHRoYXQgdGhlIGRhdGEgaXMgb3JkZXJlZCBieSB0aGUgcGFydGljaXBhbnQgbnVtYmVyIChlLmcuIDEsIDIsIDMsIDQuLi4pCnRyYWNrX3JhdyA9IGRwbHlyOjphcnJhbmdlKHRyYWNrX3JhdywgdHJhY2tfcGFydGljaXBhbnQpCgp0cmFja19yYXcKYGBgCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+CgojIyBDb25zdHJ1Y3QgV29ya2luZyBEYXRhZnJhbWVzIHsjbWFrZURGc30KCkluIG9yZGVyIHRvIGNvbXBsZXRlIHRoZSBwcmVzZW50IHN0dWR5J3MgYW5hbHlzZXMsICoqZWlnaHQqKiBkYXRhIGZyYW1lcyB3ZXJlIGNyZWF0ZWQ6CgoxLiAgQWxsIERhdGEKMi4gIEFsbCBEYXRhIC0gR28vTm8tR28gc2VwYXJhdGVkIGJ5IEN1ZSBUeXBlIChXSURFIEZPUk1BVCkKMy4gIEFsbCBEYXRhIC0gR28vTm8tR28gc2VwYXJhdGVkIGJ5IEN1ZSBUeXBlIChMb25nIEZPUk1BVCkKNC4gIE9TcGFuIEFuYWx5c2lzCjUuICBHby9Oby1HbzogRXJyb3IgQW5hbHlzaXMKNi4gIEdvL05vLUdvOiBBY2N1cmFjeSBBbmFseXNpcwo3LiAgU0FEOiBGYWN0b3IgQW5hbHlzaXMKOC4gIE1vZGVyYXRpb24gQW5hbHlzaXMKCioqRGF0YSBDbGVhbmluZyoqIHdhcyBjb21wbGV0ZWQgZm9yICgxKS0oMykgYmFzZWQgb246IChhKSBFeGNsdXNpb24gY3JpdGVyaWEsIChiKSBPdXRsaWVyIGRhdGEsIGFuZCAoYykgSW5jb21wbGV0ZS9NaXNzaW5nIGRhdGE6CgphLiAgKipFeGNsdXNpb24gQ3JpdGVyaWEqKgoKICAgIC0gICAqKk9TcGFuIERhdGE6IE1hdGggQ3JpdGVyaWEqKiBQbGFubmVkIGV4Y2x1c2lvbiBjcml0ZXJpYSB3YXMgYXBwbGllZCB0byB0aGUgZGF0YS4gRXhjbHVzaW9uIGNyaXRlcmlhIGZvciB0aGlzIGFuYWx5c2lzIGhlbHBlZCB0byBjb250cm9sIGZvciBhbnkgcGFydGljaXBhbnRzIHdobyBkaWQgbm90IGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zLCBzcGVjaWZpY2FsbHksIHRoYXQgcGFydGljaXBhbnQgcGF5ZWQgYXR0ZW50aW9uIHRvIGJvdGggdGhlIG1hdGggY29tcG9uZW50IGFuZCBsZXR0ZXIgcmVjYWxsIGNvbXBvbmVudCBvZiB0aGUgdGFzay4gT25seSBkYXRhIGZyb20gdGhvc2Ugd2hvIHNjb3JlZCA4NSUgb3IgaGlnaGVyIG9uIHRoZSBtYXRoIGNvbXBvbmVudCBvZiB0aGUgdGFzayB3ZXJlIGluY2x1ZGVkLgoKICAgIC0gICAqKkdvL05vLUdvIERhdGE6IENoYW5jZSBQZXJmb3JtYW5jZSBDcml0ZXJpYSoqIFBsYW5uZWQgZXhjbHVzaW9uIGNyaXRlcmlhIHdhcyBhcHBsaWVkIHRvIHRoZSBkYXRhLiBFeGNsdXNpb24gY3JpdGVyaWEgZm9yIHRoaXMgYW5hbHlzaXMgaGVscGVkIHRvIGNvbnRyb2wgZm9yIGFueSBwYXJ0aWNpcGFudHMgd2hvIGRpZCBub3QgZm9sbG93IHRoZSBpbnN0cnVjdGlvbnMuIE9ubHkgZGF0YSBmcm9tIHRob3NlIHdobyBzY29yZWQgaGlnaGVyIHRoYW4gY2hhbmNlIHBlcmZvcm1hbmNlIChpLmUuLCByZXNwb25kZWQgdG8gYXQgbGVhc3QgNTAlIG9mICJHbyIgdHJpYWxzIGFuZCB3aXRoaGVsZCByZXNwb25zZSB0byBhdCBsZWFzdCA1MCUgb2YgIk5vLUdvIiB0cmlhbHMpIHdlcmUgdXNlZCBmb3IgdGhlIGZpbmFsIGFuYWx5c2lzLgoKICAgICAgICAtICAgTm90ZTogVGhpcyBkYXRhIGNsZWFuaW5nIHdhcyBjb21wbGV0ZWQgaW4gdGhlIFtHby9Oby1HbyBSYXcgRGF0YSBzZWN0aW9uXSgjZ25nX3JhdykuCgogICAgLSAgICoqR28vTm8tR28gRGF0YTogU3RhbmRhcmQgRGV2aWF0aW9uIENyaXRlcmlhKiogUGxhbm5lZCBleGNsdXNpb24gY3JpdGVyaWEgd2FzIGFwcGxpZWQgdG8gdGhlIGRhdGEuIEV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhpcyBhbmFseXNpcyBoZWxwZWQgdG8gY29udHJvbCBmb3IgYW55IHBhcnRpY2lwYW50cyB3aG8gZGlkIG5vdCBmb2xsb3cgdGhlIGluc3RydWN0aW9ucy4gT25seSBkYXRhIGZyb20gdGhvc2Ugd2hvIHNjb3JlZCBoaWdoZXIgdGhhbiBjaGFuY2UgcGVyZm9ybWFuY2UgKGkuZS4sIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2YgIkdvIiB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiAiTm8tR28iIHRyaWFscykgd2VyZSB1c2VkIGZvciB0aGUgZmluYWwgYW5hbHlzaXMuCgogICAgICAgIC0gICBOb3RlOiBUaGlzIGRhdGEgY2xlYW5pbmcgd2FzIGNvbXBsZXRlZCBpbiB0aGUgW0dvL05vLUdvIFJhdyBEYXRhIHNlY3Rpb25dKCNnbmdfcmF3KS4KCmIuICAqKk91dGxpZXIgRGF0YSoqCgogICAgLSAgICoqT1NwYW4gJiBHby9Oby1HbyBEYXRhOioqIEZvciBhbGwgdGFzayBkYXRhLCBhbnkgKmV4dHJlbWUgb3V0bGllcnMqIHdlcmUgcmVtb3ZlZC4gVGhlIG91dGxpZXJzIHdlcmUgaWRlbnRpZmllZCBhbmQgcmVtb3ZlZCB1c2luZyB0aGUgKnN0YW5kYXJkIGRldmlhdGlvbiAoU0QpKiBtZXRob2QuIFBhcnRpY2lwYW50cyB3aG8ncyBzY29yZSB3YXMgZ3JlYXRlciB0aGFuIDJTRHMgZnJvbSB0aGUgbWVhbiB3ZXJlIGV4Y2x1ZGVkLgoKYy4gICoqSW5jb21wbGV0ZS9NaXNzaW5nIERhdGEqKgoKICAgIC0gICBGb3IgYWxsIHRhc2sgZGF0YSwgYW55IHBhcnRpY2lwYW50cyB3aXRoIGluY29tcGxldGUgb3IgbWlzc2luZyBkYXRhIHdlcmUgcmVtb3ZlZC4KCiMjIyAxLiBBbGwgRGF0YQoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCkFsbCB0aGUgZGF0YSBmcm9tIHRoZSBwcmVzZW50IHN0dWR5IGluIG9uZSBkYXRhIGZyYW1lOiAqKiJhbGxfZGF0YSIqKiAqKGNsaWNrIHRvIHNlZSBtb3JlKSoKCjwvc3VtbWFyeT4KCi0gICBUaGlzIGRhdGEgaW5jbHVkZWQgdGhlIGZvbGxvd2luZzoKCiAgICAtICAgYHIgY29sbmFtZXMoYWxsX2RhdGEpYAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBvcmdhbml6ZWQgdGhlIHJhdyBkYXRhIGludG8gb25lIGRhdGEgZnJhbWUuICooY2xpY2sgdG8gZXhwYW5kKSoKCjwvc3VtbWFyeT4KCmBgYHtyIGNyZWF0ZV9hbGxfZGF0YV90ZW1wLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBGaW5kIHRoZSBmaW5hbCBwYXJ0aWNpcGFudCBsaXN0IGZvciB0aGUgYW5hbHlzZXMgIAogICMgZ2V0IGEgbGlzdCBvZiBwYXJ0aWNpcGFudHMgdGhhdCAoMSkgY29tcGxldGVkIHRoZSBnbmcgdGFzayBhbmQgKDIpIGFyZSBub3QgZXhjbHVkZWQgKGkuZS4sIGluY2x1c2lvbiBsaXN0KSBiYXNlZCBvbiB0aGUgImV4Y2x1ZGUiIGNvbHVtbiBpbiB0aGUgdHJhY2tpbmcgc2hlZXQgIAogICMgKDEpIEZpcnN0IGdldCB0aGUgZ25nIHBhcnRpY2lwYW50IGxpc3QgIAogIGduZ19wYXJfbGlzdCA9IGduZ19kYXRhX2V4dHJhY3RlZCRnbmdfcGFydGljaXBhbnQgIAogICMgKDIpIE5leHQsIGdldCB0aGUgaW5jbHVzaW9uIGxpc3QgIAogIGluY2x1ZGVfcGFyX2xpc3QgPSBkYXRhLmZyYW1lKHRyYWNrX3JhdyR0cmFja19wYXJ0aWNpcGFudFt3aGljaCh0cmFja19yYXckZXhjbHVkZSAlaW4lIDIpXSkgIAogICAgY29sbmFtZXMoaW5jbHVkZV9wYXJfbGlzdCkgPSBjKCJwYXJfbGlzdCIpCiAgIyBHZXQgYSBsaXN0IG9mIGFsbCB0aGUgcGFydGljaXBhbnRzIHdobyBjb21wbGV0ZWQgdGhlIHN0dWR5IChmcm9tIHRoZSB0ZXN0aW5nIHRyYWNraW5nIHNoZWV0KQogIGFsbF9wYXJ0aWNpcGFudHMgPSBhcy5kYXRhLmZyYW1lKHRyYWNrX3JhdyR0cmFja19wYXJ0aWNpcGFudCkKICAgIGNvbG5hbWVzKGFsbF9wYXJ0aWNpcGFudHMpID0gYygiYWxsX3BhcnRpY2lwYW50cyIpCiAgCiMgZmluZCB0aGUgcGFydGljaXBhbnRzIHRvIHJlbW92ZSBmcm9tIHRoZSBkYXRhCiAgIyBGaWx0ZXIgZWFjaCBkYXRhIGxpc3QgZnJvbSB0aGUgbGlzdCBvZiBhbGwgcGFydGljaXBhbnRzICAKICBnbmdfcmVtb3ZlID0gZGF0YS5mcmFtZSgiYWxsX3BhcnRpY2lwYW50cyIgPSBmaWx0ZXIoYWxsX3BhcnRpY2lwYW50cywgIShhbGxfcGFydGljaXBhbnRzICVpbiUgZ25nX3Bhcl9saXN0KSkpCiAgdHJhY2tfcmVtb3ZlID0gZGF0YS5mcmFtZSgiYWxsX3BhcnRpY2lwYW50cyIgPSBmaWx0ZXIoYWxsX3BhcnRpY2lwYW50cywgIShhbGxfcGFydGljaXBhbnRzICVpbiUgaW5jbHVkZV9wYXJfbGlzdCRwYXJfbGlzdCkpKQogIHJlYXNvbl9yZW1vdmUgPSBjKHJlcCgiZ25nIiwgbGVuZ3RoKGduZ19yZW1vdmUkYWxsX3BhcnRpY2lwYW50cykpLCByZXAoInRyYWNrIiwgbGVuZ3RoKHRyYWNrX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzKSkpCiAgCiAgIyBNYWtlIGEgbGlzdCBvZiBhbGwgdGhlIHJlbW92ZWQgcGFydGljaXBhbnRzIC0tICJhbGxfcmVtb3ZlIgogIGFsbF9yZW1vdmVfbm90Y2xlYW4gPSBkYXRhLmZyYW1lKHJiaW5kKGduZ19yZW1vdmUsIHRyYWNrX3JlbW92ZSksIHJlYXNvbl9yZW1vdmUpCiAgICAjIHJlbW92ZSBhbnkgZHVwbGljYXRlcyBmcm9tIHRoZSBsaXN0CiAgICBhbGxfcmVtb3ZlX25vZHVwID0gYWxsX3JlbW92ZV9ub3RjbGVhblshZHVwbGljYXRlZChhbGxfcmVtb3ZlX25vdGNsZWFuJGFsbF9wYXJ0aWNpcGFudHMpLCBdCiAgICAjIHJlb3JnYW5pemUgcm93cyBzbyB0aGF0IHRoZSBkYXRhIGlzIG9yZGVyZWQgYnkgdGhlIHBhcnRpY2lwYW50IG51bWJlciAoZS5nLiAxLCAyLCAzLCA0Li4uKSAgCiAgICBhbGxfcmVtb3ZlID0gZHBseXI6OmFycmFuZ2UoYWxsX3JlbW92ZV9ub2R1cCwgYWxsX3BhcnRpY2lwYW50cykgIAogICAgCiMgRmlsdGVyIHJhdyBkYXRhIHVzaW5nIHRoZSBmaW5hbCBwYXJ0aWNpcGFudCBsaXN0IGZvcjogb3NwYW5fcmF3LCBnbmdfcmF3LCBzdXJ2ZXlfcmF3LCBhbmQgdHJhY2tfcmF3CiAgIyBUaGlzIHdpbGwgbm93IGJlIHRoZSB3b3JraW5nIGRhdGEgZm9yIHRoZSBzdHVkeSAoaS5lLiB0aGUgImZpbmFsIiBkYXRhKSAgCiAgICAjIE9TcGFuIERhdGEgIAogICAgb3NwYW5fZmluYWwgPSBkcGx5cjo6ZmlsdGVyKG9zcGFuX3JhdywgIW9zcGFuX3BhcnRpY2lwYW50ICVpbiUgYWxsX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzKQogICAgIyBHbmcgRGF0YSAgCiAgICBnbmdfZmluYWwgPSBkcGx5cjo6ZmlsdGVyKGduZ19kYXRhX2V4dHJhY3RlZCwgIWduZ19wYXJ0aWNpcGFudCAlaW4lIGFsbF9yZW1vdmUkYWxsX3BhcnRpY2lwYW50cykKICAgICMgU3VydmV5IERhdGEgIAogICAgc3VydmV5X2ZpbmFsID0gZHBseXI6OmZpbHRlcihzdXJ2ZXlfcmF3LCAhc3VyX3BhcnRpY2lwYW50ICVpbiUgYWxsX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzKQogICAgIyBUcmFja2luZyBEYXRhICAKICAgIHRyYWNrX2ZpbmFsID0gZHBseXI6OmZpbHRlcih0cmFja19yYXcsICF0cmFja19wYXJ0aWNpcGFudCAlaW4lIGFsbF9yZW1vdmUkYWxsX3BhcnRpY2lwYW50cykKCiMgQ29tYmluZSBhbGwgdGhlIGZpbmFsIGRhdGEgaW50byAxIGRhdGEgZnJhbWUgd2l0aCB0aGUgZm9sbG93aW5nOgogICMgU3RhcnQgYnkgY3JlYXRpbmcgYSBkYXRhIGZyYW1lIHdpdGggdGhlIGZpbmFsIHBhcnRpY2lwYW50IGxpc3QgaW4gdGhlIDFzdCBjb2x1bW46ICJwYXJ0aWNpcGFudCIKICBhbGxfcGFyID0gYXMuZGF0YS5mcmFtZSh0cmFja19maW5hbCR0cmFja19wYXJ0aWNpcGFudCkKICAgIGNvbG5hbWVzKGFsbF9wYXIpID0gYygicGFydGljaXBhbnQiKQoKICAjIHRvIHVzZSB0aGUgbWVyZ2UgZnVuY3Rpb24sIGNoYW5nZSB0aGUgcmVzcGVjdGl2ZSAicGFydGljaXBhbnQiIGNvbHVtbiBuYW1lIGluIGVhY2ggZGF0YSBmcmFtZSB0byAicGFydGljaXBhbnQiCiAgICAjIE9TcGFuIERhdGEKICAgIGNvbG5hbWVzKG9zcGFuX2ZpbmFsKVt3aGljaChuYW1lcyhvc3Bhbl9maW5hbCkgPT0gIm9zcGFuX3BhcnRpY2lwYW50IildID0gYygicGFydGljaXBhbnQiKQogICAgIyBHbmcgRGF0YQogICAgY29sbmFtZXMoZ25nX2ZpbmFsKVt3aGljaChuYW1lcyhnbmdfZmluYWwpID09ICJnbmdfcGFydGljaXBhbnQiKV0gPSBjKCJwYXJ0aWNpcGFudCIpCiAgICAjIFN1cnZleSBEYXRhCiAgICBjb2xuYW1lcyhzdXJ2ZXlfZmluYWwpW3doaWNoKG5hbWVzKHN1cnZleV9maW5hbCkgPT0gInN1cl9wYXJ0aWNpcGFudCIpXSA9IGMoInBhcnRpY2lwYW50IikKICAgICMgVHJhY2tpbmcgRGF0YQogICAgY29sbmFtZXModHJhY2tfZmluYWwpW3doaWNoKG5hbWVzKHRyYWNrX2ZpbmFsKSA9PSAidHJhY2tfcGFydGljaXBhbnQiKV0gPSBjKCJwYXJ0aWNpcGFudCIpCgojIE1lcmdlIGFsbCA0IGRhdGEgZnJhbWVzIGludG8gMSBkYXRhIGZyYW1lIC0tICJhbGxfZGF0YV90ZW1wIiAKICAjIHRoaXMgd2lsbCBiZSByZWZpbmVkIHdpdGggZGF0YSBjbGVhbmluZyBsYXRlcgogIGFsbF9kYXRhX3RlbXAgPC0gIFJlZHVjZShmdW5jdGlvbih4LCB5KSBtZXJnZSh4LCB5LCBieT0icGFydGljaXBhbnQiKSwgbGlzdCh0cmFja19maW5hbCwgb3NwYW5fZmluYWwsIGduZ19maW5hbCwgZHBseXI6OnNlbGVjdChzdXJ2ZXlfZmluYWwsIC1jKHN1cl9sb2NhdGlvbiwgc3VyX3Bvd2VyLCBzdXJfY29uZGl0aW9uKSkpKQogICAgIyByZW5hbWUgdGhlIHRyYWNraW5nIHNoZWV0IGNvbHVtbnMgZm9yIHRoZSBsb2NhdGlvbiwgcG93ZXIsIGFuZCBjb25kaXRpb24gCiAgICBjb2xuYW1lcyhhbGxfZGF0YV90ZW1wKVt3aGljaChuYW1lcyhhbGxfZGF0YV90ZW1wKSA9PSBjKCJ0cmFja19sb2NhdGlvbiIsICJ0cmFja19wb3dlciIsICJ0cmFja19jb25kaXRpb24iKSldID0gYygibG9jYXRpb24iLCAicG93ZXIiLCAiY29uZGl0aW9uIikKICAgIAojIEFkZCBzY29yZSBmb3IgU0FEIGl0ZW1zCiAgI1NBRCBzY29yZSBvdmVyIGFsbCAxMyBpdGVtcwogICAgYWxsX2RhdGFfdGVtcCA8LSAKICAgICAgYWxsX2RhdGFfdGVtcCAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFNBRF9zY29yZSA9IHN1bShjX2Fjcm9zcyhTQURfMTpTQURfMTMpKSkKICAgICMgYWxsX2RhdGFfdGVtcCAlPiUgCiAgICAjICMgZm9yIGVhY2ggcGFydGljaXBhbnQKICAgICMgcm93d2lzZSgpICU+JSAKICAgICMgIyBzY29yZSBpcyBjYWxjdWxhdGVkIGJ5IGFkZGluZyB1cCBhbGwgMTMgaXRlbXMgZm9yIGEgdG90YWwgc3VtIHNjb3JlIGZvciBlYWNoIHAKICAgICMgbXV0YXRlKFNBRF9zY29yZSA9IHN1bShTQURfMSwgU0FEXzIsIFNBRF8zLCBTQURfNCwgU0FEXzUsIFNBRF82LCBTQURfNywgU0FEXzgsIFNBRF85LCBTQURfMTAsIFNBRF8xMSwgU0FEXzEyLCBTQURfMTMpKQogIAogICMgU21hcnRwaG9uZSBEZXBlbmRlbmNlIHN1YnNjYWxlIChpdGVtczogMSwgMiwgMykgLS0gYmFzZWQgb24gRkEgCiAgICBhbGxfZGF0YV90ZW1wIDwtIGFsbF9kYXRhX3RlbXAgJT4lIHJvd3dpc2UoKSAlPiUgZHBseXI6Om11dGF0ZShTQURfZGVwX3Njb3JlID0gc3VtKGNfYWNyb3NzKFNBRF8xOlNBRF8zKSkpCgogICMgRW1vdGlvbmFsIEF0dGFjaG1lbnQgc3Vic2NhbGUgKGl0ZW1zOiA4LCA5LCAxMCwgMTEpIC0tIGJhc2VkIG9uIEZBIAogICAgYWxsX2RhdGFfdGVtcCA8LSBhbGxfZGF0YV90ZW1wICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoU0FEX2VhX3Njb3JlID0gc3VtKGNfYWNyb3NzKFNBRF84OlNBRF8xMSkpKQogIAogICMgU21hcnRwaG9uZSBBY2Nlc3NpYmlsaXR5IHN1YnNjYWxlIChpdGVtczogNSwgNiwgNykgLS0gYmFzZWQgb24gRkEgCiAgICBhbGxfZGF0YV90ZW1wIDwtIGFsbF9kYXRhX3RlbXAgJT4lIHJvd3dpc2UoKSAlPiUgZHBseXI6Om11dGF0ZShTQURfYWNjZXNzX3Njb3JlID0gc3VtKGNfYWNyb3NzKFNBRF81OlNBRF83KSkpCiAgICAKICAjIFNtYXJ0cGhvbmUgRGlzdHJhY3RpYmlsaXR5IHN1YnNjYWxlIChpdGVtczogMTIsIDEzKSAtLSBiYXNlZCBvbiBGQSAKICAgIGFsbF9kYXRhX3RlbXAgPC0gYWxsX2RhdGFfdGVtcCAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFNBRF9kaXN0X3Njb3JlID0gc3VtKGNfYWNyb3NzKFNBRF8xMjpTQURfMTMpKSkKICAgIAojIEFkZCBzY29yZSBmb3IgU1VRX3VzZV80LTUKYWxsX2RhdGFfdGVtcCA8LSBhbGxfZGF0YV90ZW1wICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoU1VRX2FiZXh0X3Njb3JlID0gc3VtKFNVUV91c2VfNCwgU1VRX3VzZV81KS8yKQogIGFsbF9kYXRhX3RlbXAgJT4lIAogICMgZm9yIGVhY2ggcGFydGljaXBhbnQKICByb3d3aXNlKCkgJT4lIAogICMgc2NvcmUgaXMgY2FsY3VsYXRlZCBhcyBhdmVyYWdlIGJldHdlZW4gMiBpdGVtcyAtLSBtZWFzdXJlcyBwcyB0ZW5kZW5jeSB0byB0dXJuIHRvIHNtYXJ0cGhvbmUgaW4gYWJzZW5jZSBvZiBleHRlcm5hbCBzdGltdWxhdGlvbgogIG11dGF0ZShTVVFfYWJleHRfc2NvcmUgPSAoc3VtKFNVUV91c2VfNCwgU1VRX3VzZV81KSkvMikKCiMgQWRkIHNjb3JlIGZvciBTVVFfdXNlXzYtNwphbGxfZGF0YV90ZW1wIDwtIGFsbF9kYXRhX3RlbXAgJT4lIHJvd3dpc2UoKSAlPiUgZHBseXI6Om11dGF0ZShTVVFfZHVyYWN0X3Njb3JlID0gc3VtKFNVUV91c2VfNiwgU1VRX3VzZV83KS8yKQogIGFsbF9kYXRhX3RlbXAgJT4lIAogICMgZm9yIGVhY2ggcGFydGljaXBhbnQgIAogIHJvd3dpc2UoKSAlPiUgCiAgIyBzY29yZSBpcyBjYWxjdWxhdGVkIGFzIGF2ZXJhZ2UgYmV0d2VlbiAyIGl0ZW1zIC0tIG1lYXN1cmVzIHBzIHRlbmRlbmN5IHRvIHR1cm4gdG8gc21hcnRwaG9uZSBkdXJpbmcgb3RoZXIgYWN0aXZpdGllcwogIG11dGF0ZShTVVFfZHVyYWN0X3Njb3JlID0gKHN1bShTVVFfdXNlXzYsIFNVUV91c2VfNykpLzIpCiAgCmFsbF9kYXRhX3RlbXAKYGBgCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+CgojIyMjIERhdGEgQ2xlYW5pbmc6IEV4Y2x1c2lvbiBDcml0ZXJpYSwgT3V0bGllcnMsIGFuZCBNaXNzaW5nIERhdGEgeyNhbGxfZGF0YV9EQ30KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgZmluYWwgc2FtcGxlIHNpemUgKCpOKiA9IGByIG5yb3coYWxsX2RhdGEpYCkgZm9yIHRoaXMgZGF0YSBmcmFtZSBleGNsdWRlZCBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gIm9zcGFuX2VjIikgKyBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19oX2VjIikgKyBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ192X2VjIilgIHBhcnRpY2lwYW50cyB3aG8gbWV0IHRoZSBleGNsdXNpb24gY3JpdGVyaWEgKE9TcGFuIG1hdGggY3JpdGVyaWE6IGByIHN1bShhbGxfcmVtb3ZlX2RjJHJlYXNvbiA9PSAib3NwYW5fZWMiKWA7IEdvL05vLUdvIHJlc3BvbnNlIGNyaXRlcmlhLCBob3Jpem9udGFsL25vLWdvIGN1ZTogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJnbmdfaF9lYyIpYDsgR28vTm8tR28gcmVzcG9uc2UgY3JpdGVyaWEsIHZlcnRpY2FsL2dvIGN1ZTogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJnbmdfdl9lYyIpYCkuIEEgdG90YWwgb2YgYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJvc3Bhbl9vdXQiKSArIHN1bShhbGxfcmVtb3ZlX2RjJHJlYXNvbiA9PSAiZ25nX2Vycl9vdXQiKSArIHN1bShhbGxfcmVtb3ZlX2RjJHJlYXNvbiA9PSAiZ25nX2FjX291dCIpYCBwYXJ0aWNpcGFudHMgd2VyZSBpZGVudGlmaWVkIGFzIG91dGxpZXJzIChPU3BhbjogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJvc3Bhbl9vdXQiKWA7IEdvL05vLUdvIEVycm9yIEFuYWx5c2lzOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19lcnJfb3V0IilgOyBHby9Oby1HbyBBY2N1cmFjeSBBbmFseXNpczogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJnbmdfYWNfb3V0IilgKSBhbmQgcmVtb3ZlZC4gQSB0b3RhbCBvZiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gIm9zcGFuX21pc3MiKSArIHN1bShhbGxfcmVtb3ZlX2RjJHJlYXNvbiA9PSAiZ25nX2Vycl9taXNzIikgKyBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19hY19taXNzIilgIHBhcnRpY2lwYW50cyB3ZXJlIHJlbW92ZWQgZHVlIHRvIGluY29tcGxldGUgb3IgbWlzc2luZyBkYXRhIChPU3BhbjogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJvc3Bhbl9taXNzIilgOyBHby9Oby1HbyBFcnJvciBBbmFseXNpczogYHIgc3VtKGFsbF9yZW1vdmVfZGMkcmVhc29uID09ICJnbmdfZXJyX21pc3MiKWA7IEdvL05vLUdvIEFjY3VyYWN5IEFuYWx5c2lzOiBgciBzdW0oYWxsX3JlbW92ZV9kYyRyZWFzb24gPT0gImduZ19hY19taXNzIilgKS4gVGhpcyBjcmVhdGVkIHRoZSAqKiJhbGxfZGF0YSIqKiBkYXRhIGZyYW1lICooY2xpY2sgdG8gc2VlIG1vcmUpKi4KCjwvc3VtbWFyeT4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgY2xlYW5lZCAqYWxsX2RhdGEqIGJhc2VkIG9uICgxKSBleGNsdXNpb24gY3JpdGVyaWEsICgyKSBvdXRsaWVycywgYW5kICgzKSBpbmNvbXBsZXRlL21pc3NpbmcgZGF0YS4gKihjbGljayB0byBzZWUgY29kZSkqCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfYWxsX3JlbW92ZV9kYyZhbGxfcmVtb3ZlX2RjX2xpc3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgZ2V0IGxpc3Qgb2YgcHMgdG8gcmVtb3ZlIGZvciB2YXJpb3VzIHJlYXNvbnMuLi4KICAKIyBFeGNsdXNpb24gY3JpdGVyaWEKICAjIEZvciBPU1BBTgogICMgcHMgc2NvcmVkIDw4NSUgb24gbWF0aAogIGRjX29zcGFuX2VjIDwtIAogICAgYWxsX2RhdGFfdGVtcCAlPiUgCiAgICAjIGFwcGx5IGZpbHRlciB0byBtYXRoIGNyaXRlcmlhCiAgICBmaWx0ZXIob3NwYW5fbWF0aF9jcml0ZXJpYV84NSA9PSAwKSAlPiUgCiAgICAjIHJlbW92ZSBhbGwgcm93cyBleGNlcHQgcGFydGljaXBhbnQgSUQKICAgIHNlbGVjdChwYXJ0aWNpcGFudCkKCiAgIyBGb3IgR05HIC0tIGJhc2VkIG9uIHJhdyBkYXRhIHNlcGFyYXRlZCBieSBjdWUgdHlwZSAoaS5lLiwgZWl0aGVyIHZlcnRpY2FsIG9yIGhvcml6b250YWwpCiAgIyBWZXJ0aWNhbCBjdWUgdHlwZSAoImdvIikKICBkY19nbmdfdl9lYyA8LSAKICAgIGduZ19kYXRhX2V4dHJhY3RlZF92ICU+JSAKICAgICMgYXBwbHkgZmlsdGVyIHRvIHJlc3BvbnNlIGNyaXRlcmlhCiAgICBmaWx0ZXIoZXhjbHVkZV92ID09IDEpICU+JSAKICAgICMgcmVtb3ZlIGFsbCByb3dzIGV4Y2VwdCBwYXJ0aWNpcGFudCBJRAogICAgc2VsZWN0KHBhcnRpY2lwYW50X2xvbmcpICU+JSAKICAgICMgcmVuYW1lIGNvbHVtbiBhcyAicGFydGljaXBhbnQiCiAgICBkcGx5cjo6cmVuYW1lKHBhcnRpY2lwYW50ID0gcGFydGljaXBhbnRfbG9uZykKICAjIFZlcnRpY2FsIGN1ZSB0eXBlICgibm8tZ28iKQogIGRjX2duZ19oX2VjIDwtIAogICAgZ25nX2RhdGFfZXh0cmFjdGVkX2ggJT4lIAogICAgIyBhcHBseSBmaWx0ZXIgdG8gcmVzcG9uc2UgY3JpdGVyaWEKICAgIGZpbHRlcihleGNsdWRlX2ggPT0gMSkgJT4lIAogICAgIyByZW1vdmUgYWxsIHJvd3MgZXhjZXB0IHBhcnRpY2lwYW50IElECiAgICBzZWxlY3QocGFydGljaXBhbnRfbG9uZykgJT4lIAogICAgIyByZW5hbWUgY29sdW1uIGFzICJwYXJ0aWNpcGFudCIKICAgIGRwbHlyOjpyZW5hbWUocGFydGljaXBhbnQgPSBwYXJ0aWNpcGFudF9sb25nKQoKIyBPdXRsaWVycwogICMgRm9yIE9TUEFOCiAgZGNfb3NwYW5fb3V0IDwtIAogICAgYWxsX2RhdGFfdGVtcCAlPiUgCiAgICAjIHJlbW92ZSBwcyB3aXRoIHNjb3JlID4gMlNEIGZyb20gbWVhbgogICAgZmlsdGVyKG9zcGFuX2Fic29sdXRlX3Njb3JlID4gKG1lYW4ob3NwYW5fYWJzb2x1dGVfc2NvcmUsIG5hLnJtID0gVCkgKyAoMiAqIHNkKG9zcGFuX2Fic29sdXRlX3Njb3JlLCBuYS5ybSA9IFQpKSkgfAogICAgICAgICAgIG9zcGFuX2Fic29sdXRlX3Njb3JlIDwgKG1lYW4ob3NwYW5fYWJzb2x1dGVfc2NvcmUsIG5hLnJtID0gVCkgLSAoMiAqIHNkKG9zcGFuX2Fic29sdXRlX3Njb3JlLCBuYS5ybSA9IFQpKSkKICAgICAgICAgICApICU+JSAKICAgICMgcmVtb3ZlIGFsbCByb3dzIGV4Y2VwdCBwYXJ0aWNpcGFudCBJRAogICAgc2VsZWN0KHBhcnRpY2lwYW50KQogIAogICMgRm9yIEdORyBlcnJvciAob21pc3Npb24pCiAgZGNfZ25nX2Vycl9vdXQgPC0gCiAgICBhbGxfZGF0YV90ZW1wICU+JSAKICAgICMgcmVtb3ZlIHBzIHdpdGggc2NvcmUgPiAyU0QgZnJvbSBtZWFuCiAgICBmaWx0ZXIoZ25nX2Vycl9vbWkgPiAobWVhbihnbmdfZXJyX29taSwgbmEucm0gPSBUKSArICgyICogc2QoZ25nX2Vycl9vbWksIG5hLnJtID0gVCkpKSB8CiAgICAgICAgICAgZ25nX2Vycl9vbWkgPCAobWVhbihnbmdfZXJyX29taSwgbmEucm0gPSBUKSAtICgyICogc2QoZ25nX2Vycl9vbWksIG5hLnJtID0gVCkpKQogICAgICAgICAgICkgJT4lIAogICAgIyByZW1vdmUgYWxsIHJvd3MgZXhjZXB0IHBhcnRpY2lwYW50IElECiAgICBzZWxlY3QocGFydGljaXBhbnQpCiAgCiAgIyBGb3IgR05HIGFjY3VyYWN5IChhdmVyYWdlIFJUKQogIGRjX2duZ19hY19vdXQgPC0gCiAgICBhbGxfZGF0YV90ZW1wICU+JSAKICAgICMgcmVtb3ZlIHBzIHdpdGggc2NvcmUgPiAyU0QgZnJvbSBtZWFuCiAgICBmaWx0ZXIoZ25nX3J0X2F2ID4gKG1lYW4oZ25nX3J0X2F2LCBuYS5ybSA9IFQpICsgKDIgKiBzZChnbmdfcnRfYXYsIG5hLnJtID0gVCkpKSB8CiAgICAgICAgICAgZ25nX3J0X2F2IDwgKG1lYW4oZ25nX3J0X2F2LCBuYS5ybSA9IFQpIC0gKDIgKiBzZChnbmdfcnRfYXYsIG5hLnJtID0gVCkpKQogICAgICAgICAgICkgJT4lIAogICAgIyByZW1vdmUgYWxsIHJvd3MgZXhjZXB0IHBhcnRpY2lwYW50IElECiAgICBzZWxlY3QocGFydGljaXBhbnQpCiAgCiMgTWlzc2luZy9pbmNvbXBsZXRlIGRhdGEKICAjIEZvciBPU1BBTgogIGRjX29zcGFuX21pc3MgPC0gYWxsX2RhdGFfdGVtcCAlPiUgZmlsdGVyKGlzLm5hKG9zcGFuX2Fic29sdXRlX3Njb3JlKSkgJT4lIHNlbGVjdChwYXJ0aWNpcGFudCkKICAjIEZvciBHTkcgZXJyb3IgKG9taXNzaW9uKQogIGRjX2duZ19lcnJfbWlzcyA8LSBhbGxfZGF0YV90ZW1wICU+JSBmaWx0ZXIoaXMubmEoZ25nX2Vycl9vbWkpKSAlPiUgc2VsZWN0KHBhcnRpY2lwYW50KQogICMgRm9yIEdORyBSVCAoYXZlcmFnZSkKICBkY19nbmdfYWNfbWlzcyA8LSBhbGxfZGF0YV90ZW1wICU+JSBmaWx0ZXIoaXMubmEoZ25nX3J0X2F2KSkgJT4lIHNlbGVjdChwYXJ0aWNpcGFudCkKICAgIAogIAojIGNyZWF0ZSBsaXN0IG9mIHBzIHRvIHJlbW92ZSB3aXRoIHJlYXNvbiBmb3IgcmVtb3ZhbCAtLSBhbGxfcmVtb3ZlX2RjCmFsbF9yZW1vdmVfZGMgPC0gZGF0YS5mcmFtZSgicGFydGljaXBhbnQiID0gYmluZF9yb3dzKGRjX29zcGFuX2VjLCBkY19vc3Bhbl9vdXQsIGRjX29zcGFuX21pc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkY19nbmdfdl9lYywgZGNfZ25nX2hfZWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkY19nbmdfZXJyX291dCwgZGNfZ25nX2Vycl9taXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGNfZ25nX2FjX291dCwgZGNfZ25nX2FjX21pc3MpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFzb24iID0gYyhyZXAoIm9zcGFuX2VjIiwgbnJvdyhkY19vc3Bhbl9lYykpLCByZXAoIm9zcGFuX291dCIsIG5yb3coZGNfb3NwYW5fb3V0KSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgib3NwYW5fbWlzcyIsIG5yb3coZGNfb3NwYW5fbWlzcykpLCByZXAoImduZ192X2VjIiwgbnJvdyhkY19nbmdfdl9lYykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgiZ25nX2hfZWMiLCBucm93KGRjX2duZ19oX2VjKSkscmVwKCJnbmdfZXJyX291dCIsIG5yb3coZGNfZ25nX2Vycl9vdXQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJnbmdfZXJyX21pc3MiLCBucm93KGRjX2duZ19lcnJfbWlzcykpLCByZXAoImduZ19hY19vdXQiLCBucm93KGRjX2duZ19hY19vdXQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJnbmdfYWNfbWlzcyIsIG5yb3coZGNfZ25nX2FjX21pc3MpKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiMgY3JlYXRlIGxpc3Qgb2YgcHMgdG8gcmVtb3ZlIHdpdGhvdXQgZHVwbGljYXRlcyB0byB1c2UgdG8gZmlsdGVyIGZpbmFsIGRhdGEKYWxsX3JlbW92ZV9kY19saXN0IDwtIAogIGFsbF9yZW1vdmVfZGMgJT4lIAogICMgcmVtb3ZlIHJlYXNvbiBjb2x1bW4KICBzZWxlY3QocGFydGljaXBhbnQpICU+JSAKICAjIHJlbW92ZSBhbnkgZHVwbGljYXRlZCBwYXJ0aWNpcGFudCBJRHMKICBkaXN0aW5jdCgpCmBgYAoKYGBge3IgY2xlYW5fYWxsX2RhdGEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgY2xlYW4gYWxsX2RhdGEgdXNpbmcgYWxsX3JlbW92ZV9kY19saXN0CmFsbF9kYXRhIDwtIAogIGFsbF9kYXRhX3RlbXAgJT4lIAogIGZpbHRlcighcGFydGljaXBhbnQgJWluJSBhbGxfcmVtb3ZlX2RjX2xpc3QkcGFydGljaXBhbnQpCgphbGxfZGF0YQpgYGAKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIyAyLiBBbGwgRGF0YSAtIEdvL05vLUdvIHNlcGFyYXRlZCBieSBDdWUgVHlwZSAoV0lERSBGT1JNQVQpCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKQWxsIHRoZSBkYXRhIGZyb20gdGhlIHByZXNlbnQgc3R1ZHkgaW4gb25lIGRhdGEgZnJhbWUsIHdpdGggdGhlIEdvL05vLUdvIGRhdGEgc2VwYXJhdGVkIGJ5IHRhcmdldCB0eXBlIChpLmUuLCBlaXRoZXIgImdvIiBvciAibm8tZ28iKSwgcHJlc2VudGVkIGluIFdJREUgRk9STUFUOiAqKiJhbGxfZGF0YV9jdWUiKiogKihjbGljayB0byBzZWUgbW9yZSkqCgo8L3N1bW1hcnk+CgotICAgVGhpcyBkYXRhIGluY2x1ZGVkIHRoZSBmb2xsb3dpbmc6CgogICAgLSAgIGByIGNvbG5hbWVzKGFsbF9kYXRhX2N1ZSlgCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgcmF3IGRhdGEgaW50byBvbmUgZGF0YSBmcmFtZS4gKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2FsbF9kYXRhX2N1ZSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyB1c2UgdGhlIGxpc3Qgb2YgYWxsIHRoZSBwYXJ0aWNpcGFudHMgdG8gcmVtb3ZlIC0tICJhbGxfcmVtb3ZlIiAmICJhbGxfcmVtb3ZlX2RjX2xpc3QiIC0tIHRvIGZpbHRlciB0aGUgcmF3IGduZyBsb25nIGRhdGEKICAjIGZvciB0aGUgImdvIiB0YXJnZXRzCiAgZ25nX3ZfZmluYWwgPC0gCiAgZ25nX2RhdGFfZXh0cmFjdGVkX3YgJT4lIAogICMgcmVtb3ZlIHVzaW5nIHVzZSBhbGxfcmVtb3ZlCiAgZmlsdGVyKCFwYXJ0aWNpcGFudF9sb25nICVpbiUgYWxsX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzKSAlPiUgCiAgIyByZW1vdmUgdXNpbmcgdXNlIGFsbF9yZW1vdmVfZGNfbGlzdAogIGZpbHRlcighcGFydGljaXBhbnRfbG9uZyAlaW4lIGFsbF9yZW1vdmVfZGNfbGlzdCRwYXJ0aWNpcGFudCkKICAKICAjIGZvciB0aGUgIm5vLWdvIiB0YXJnZXRzCiAgZ25nX2hfZmluYWwgPC0gCiAgZ25nX2RhdGFfZXh0cmFjdGVkX2ggJT4lIAogICMgcmVtb3ZlIHVzaW5nIHVzZSBhbGxfcmVtb3ZlCiAgZmlsdGVyKCFwYXJ0aWNpcGFudF9sb25nICVpbiUgYWxsX3JlbW92ZSRhbGxfcGFydGljaXBhbnRzKSAlPiUgCiAgIyByZW1vdmUgdXNpbmcgdXNlIGFsbF9yZW1vdmVfZGNfbGlzdAogIGZpbHRlcighcGFydGljaXBhbnRfbG9uZyAlaW4lIGFsbF9yZW1vdmVfZGNfbGlzdCRwYXJ0aWNpcGFudCkKCiMgQ29tYmluZSBhbGwgdGhlIGZpbmFsIGRhdGEgaW50byAxIGRhdGEgZnJhbWUgd2l0aCB0aGUgZm9sbG93aW5nOgogICMgdXNlIHRoZSBmaW5hbCBwYXJ0aWNpcGFudCBsaXN0IC0tICJhbGxfcGFyIiAtLSBhcyB0aGUgMXN0IGNvbHVtbiBpbiB0aGUgZGF0YSBmcmFtZXMKCiAgIyB0byB1c2UgdGhlIG1lcmdlIGZ1bmN0aW9uLCBjaGFuZ2UgdGhlIHJlc3BlY3RpdmUgInBhcnRpY2lwYW50IiBjb2x1bW4gbmFtZSBpbiBlYWNoIGRhdGEgZnJhbWUgdG8gInBhcnRpY2lwYW50IgogICAgIyB0aGlzIHdhcyBhbHJlYWR5IGRvbmUgZm9yIHRoZSBvdGhlciBkYXRhIGZyYW1lcyAoZS5nLiBvc3Bhbl9maW5hbCwgc3VydmV5X2ZpbmFsKQogICAgIyBmb3IgdGhlICJ2ZXJ0aWNhbCIgdGFyZ2V0cwogICAgY29sbmFtZXMoZ25nX3ZfZmluYWwpW3doaWNoKG5hbWVzKGduZ192X2ZpbmFsKSA9PSAicGFydGljaXBhbnRfbG9uZyIpXSA9IGMoInBhcnRpY2lwYW50IikKICAgICMgZm9yIHRoZSAiaG9yaXpvbnRhbCIgdGFyZ2V0cwogICAgY29sbmFtZXMoZ25nX2hfZmluYWwpW3doaWNoKG5hbWVzKGduZ19oX2ZpbmFsKSA9PSAicGFydGljaXBhbnRfbG9uZyIpXSA9IGMoInBhcnRpY2lwYW50IikKCiMgTWVyZ2UgYWxsIDQgZGF0YSBmcmFtZXMgaW50byAxIGRhdGEgZnJhbWUgLS0gImFsbF9kYXRhX2N1ZSIKICBhbGxfZGF0YV9jdWUgPSBSZWR1Y2UoZnVuY3Rpb24oeCwgeSkgbWVyZ2UoeCwgeSwgYnk9InBhcnRpY2lwYW50IiksIGxpc3QodHJhY2tfZmluYWwsIG9zcGFuX2ZpbmFsLCBnbmdfdl9maW5hbCwgZHBseXI6OnNlbGVjdChnbmdfaF9maW5hbCwgLWMoYWdlX2xvbmcsIGxhbmdfbG9uZykpLCBkcGx5cjo6c2VsZWN0KHN1cnZleV9maW5hbCwgLWMoc3VyX2xvY2F0aW9uLCBzdXJfcG93ZXIsIHN1cl9jb25kaXRpb24pKSkpCiAgICAjIHJlbmFtZSB0aGUgdHJhY2tpbmcgc2hlZXQgY29sdW1ucyBmb3IgdGhlIGxvY2F0aW9uLCBwb3dlciwgYW5kIGNvbmRpdGlvbiAKICAgIGNvbG5hbWVzKGFsbF9kYXRhX2N1ZSlbd2hpY2gobmFtZXMoYWxsX2RhdGFfY3VlKSA9PSBjKCJ0cmFja19sb2NhdGlvbiIsICJ0cmFja19wb3dlciIsICJ0cmFja19jb25kaXRpb24iKSldID0gYygibG9jYXRpb24iLCAicG93ZXIiLCAiY29uZGl0aW9uIikKCiMgQWRkIHNjb3JlIGZvciBTQUQgaXRlbXMKICAjU0FEIHNjb3JlIG92ZXIgYWxsIDEzIGl0ZW1zCiAgICBhbGxfZGF0YV9jdWUgPC0gCiAgICBhbGxfZGF0YV9jdWUgJT4lIAogICAgIyBmb3IgZWFjaCBwYXJ0aWNpcGFudAogICAgcm93d2lzZSgpICU+JSAKICAgICMgc2NvcmUgaXMgY2FsY3VsYXRlZCBieSBhZGRpbmcgdXAgYWxsIDEzIGl0ZW1zIGZvciBhIHRvdGFsIHN1bSBzY29yZSBmb3IgZWFjaCBwCiAgICBtdXRhdGUoU0FEX3Njb3JlID0gc3VtKFNBRF8xLCBTQURfMiwgU0FEXzMsIFNBRF80LCBTQURfNSwgU0FEXzYsIFNBRF83LCBTQURfOCwgU0FEXzksIFNBRF8xMCwgU0FEXzExLCBTQURfMTIsIFNBRF8xMykpCiAgCiAgIyBTbWFydHBob25lIERlcGVuZGVuY2Ugc3Vic2NhbGUgKGl0ZW1zOiAxLCAyLCAzLCA0LCA1KSAtLSBiYXNlZCBvbiBGQSAKICAgIGFsbF9kYXRhX2N1ZSA8LSAKICAgIGFsbF9kYXRhX2N1ZSAlPiUgCiAgICAjIGZvciBlYWNoIHBhcnRpY2lwYW50CiAgICByb3d3aXNlKCkgJT4lIAogICAgIyBzY29yZSBpcyBjYWxjdWxhdGVkIGJ5IGFkZGluZyB1cCBpdGVtcyAxLTUgZm9yIGEgdG90YWwgc3VtIHNjb3JlIGZvciBlYWNoIHAKICAgIG11dGF0ZShTQURfZGVwX3Njb3JlID0gc3VtKFNBRF8xLCBTQURfMiwgU0FEXzMpKQogICAgCiAgIyBFbW90aW9uYWwgQXR0YWNobWVudCBzdWJzY2FsZSAoaXRlbXM6IDgsIDksIDEwLCAxMSkgLS0gYmFzZWQgb24gRkEgCiAgICBhbGxfZGF0YV9jdWUgPC0gCiAgICBhbGxfZGF0YV9jdWUgJT4lIAogICAgIyBmb3IgZWFjaCBwYXJ0aWNpcGFudAogICAgcm93d2lzZSgpICU+JSAKICAgICMgc2NvcmUgaXMgY2FsY3VsYXRlZCBieSBhZGRpbmcgdXAgaXRlbXMgOC0xMSBmb3IgYSB0b3RhbCBzdW0gc2NvcmUgZm9yIGVhY2ggcAogICAgbXV0YXRlKFNBRF9lYV9zY29yZSA9IHN1bShTQURfOCwgU0FEXzksIFNBRF8xMCwgU0FEXzExKSkKICAgIAogICMgU21hcnRwaG9uZSBBY2Nlc3NhYmlsaXR5IHN1YnNjYWxlIChpdGVtczogNSwgNiwgNykgLS0gYmFzZWQgb24gRkEgCiAgICBhbGxfZGF0YV9jdWUgPC0gCiAgICBhbGxfZGF0YV9jdWUgJT4lIAogICAgIyBmb3IgZWFjaCBwYXJ0aWNpcGFudAogICAgcm93d2lzZSgpICU+JSAKICAgICMgc2NvcmUgaXMgY2FsY3VsYXRlZCBieSBhZGRpbmcgdXAgYWxsIDEzIGl0ZW1zIGZvciBhIHRvdGFsIHN1bSBzY29yZSBmb3IgZWFjaCBwCiAgICBtdXRhdGUoU0FEX2FjY2Vzc19zY29yZSA9IHN1bShTQURfNSwgU0FEXzYsIFNBRF83KSkKICAgIAogICMgU21hcnRwaG9uZSBEaXN0cmFjdGliaWxpdHkgc3Vic2NhbGUgKGl0ZW1zOiA3LCAxMiwgMTMpIC0tIGJhc2VkIG9uIEZBIAogICAgYWxsX2RhdGFfY3VlIDwtIAogICAgYWxsX2RhdGFfY3VlICU+JSAKICAgICMgZm9yIGVhY2ggcGFydGljaXBhbnQKICAgIHJvd3dpc2UoKSAlPiUgCiAgICAjIHNjb3JlIGlzIGNhbGN1bGF0ZWQgYnkgYWRkaW5nIHVwIGFsbCAxMyBpdGVtcyBmb3IgYSB0b3RhbCBzdW0gc2NvcmUgZm9yIGVhY2ggcAogICAgbXV0YXRlKFNBRF9kaXN0X3Njb3JlID0gc3VtKFNBRF8xMiwgU0FEXzEzKSkKCiMgQWRkIHNjb3JlIGZvciBTVVFfdXNlXzQtNQphbGxfZGF0YV9jdWUgPC0gCiAgYWxsX2RhdGFfY3VlICU+JSAKICAjIGZvciBlYWNoIHBhcnRpY2lwYW50CiAgcm93d2lzZSgpICU+JSAKICAjIHNjb3JlIGlzIGNhbGN1bGF0ZWQgYXMgYXZlcmFnZSBiZXR3ZWVuIDIgaXRlbXMgLS0gbWVhc3VyZXMgcHMgdGVuZGVuY3kgdG8gdHVybiB0byBzbWFydHBob25lIGluIGFic2VuY2Ugb2YgZXh0ZXJuYWwgc3RpbXVsYXRpb24KICBtdXRhdGUoU1VRX2FiZXh0X3Njb3JlID0gKHN1bShTVVFfdXNlXzQsIFNVUV91c2VfNSkpLzIpCgojIEFkZCBzY29yZSBmb3IgU1VRX3VzZV82LTcKYWxsX2RhdGFfY3VlIDwtIAogIGFsbF9kYXRhX2N1ZSAlPiUgCiAgIyBmb3IgZWFjaCBwYXJ0aWNpcGFudCAgCiAgcm93d2lzZSgpICU+JSAKICAjIHNjb3JlIGlzIGNhbGN1bGF0ZWQgYXMgYXZlcmFnZSBiZXR3ZWVuIDIgaXRlbXMgLS0gbWVhc3VyZXMgcHMgdGVuZGVuY3kgdG8gdHVybiB0byBzbWFydHBob25lIGR1cmluZyBvdGhlciBhY3Rpdml0aWVzCiAgbXV0YXRlKFNVUV9kdXJhY3Rfc2NvcmUgPSAoc3VtKFNVUV91c2VfNiwgU1VRX3VzZV83KSkvMikKCmFsbF9kYXRhX2N1ZQogICAgCmBgYAoKPC9kZXRhaWxzPgoKPC9kZXRhaWxzPgoKIyMjIDMuIEFsbCBEYXRhIC0gR28vTm8tR28gc2VwYXJhdGVkIGJ5IEN1ZSBUeXBlIChMT05HIEZPUk1BVCkKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpBbGwgdGhlIGRhdGEgZnJvbSB0aGUgcHJlc2VudCBzdHVkeSBpbiBvbmUgZGF0YSBmcmFtZSwgd2l0aCB0aGUgR28vTm8tR28gZGF0YSBzZXBhcmF0ZWQgYnkgdGFyZ2V0IHR5cGUgKGkuZS4sIGVpdGhlciAiZ28iIG9yICJuby1nbyIpLCBwcmVzZW50ZWQgaW4gTE9ORyBGT1JNQVQ6ICoqImFsbF9kYXRhX2N1ZV9sb25nIioqICooY2xpY2sgdG8gc2VlIG1vcmUpKgoKPC9zdW1tYXJ5PgoKLSAgIFRoaXMgZGF0YSBpbmNsdWRlZCB0aGUgZm9sbG93aW5nOgoKICAgIC0gICBgciBjb2xuYW1lcyhhbGxfZGF0YV9jdWVfbG9uZylgCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgcmF3IGRhdGEgaW50byBvbmUgZGF0YSBmcmFtZS4gKihjbGljayB0byBleHBhbmQpKgoKPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2FsbF9kYXRhX2N1ZV9sb25nLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFJlLXN0cnVjdHVyZSB0aGUgZGF0YSBpbnRvIDEgZGF0YSBmcmFtZSBpbiBhIGxvbmcgZm9ybWF0IGZvciBhIHJlcGVhdGVkIG1lYXN1cmVzIGFuYWx5c2lzCgogICMgdXNpbmcgdGhlICJmaW5hbCIgZGF0YSBmcmFtZXMgb2YgYWxsIHRoZSBkYXRhLCBtYWtlIDIgZGF0YSBmcmFtZXMsIG9uZSBmb3IgdGhlICJ2ZXJ0aWNhbCIgKGFsbF9kYXRhX3YpIGFuZCBvbmUgZm9yIHRoZSAiaG9yaXpvbnRhbCIgKGFsbF9kYXRhX2gpIHRhcmdldHMKICAgICMgZm9yIHRoZSAidmVydGljYWwiIHRhcmdldHMgLS0gYWxsX2RhdGFfdgogICAgYWxsX2RhdGFfdiA9IFJlZHVjZShmdW5jdGlvbih4LCB5KSBtZXJnZSh4LCB5LCBieT0icGFydGljaXBhbnQiKSwgbGlzdCh0cmFja19maW5hbCwgb3NwYW5fZmluYWwsIGduZ192X2ZpbmFsLCBkcGx5cjo6c2VsZWN0KHN1cnZleV9maW5hbCwgLWMoc3VyX2xvY2F0aW9uLCBzdXJfcG93ZXIsIHN1cl9jb25kaXRpb24pKSkpCiAgICAgICMgcmVuYW1lIHRoZSB0cmFja2luZyBzaGVldCBjb2x1bW5zIGZvciB0aGUgbG9jYXRpb24sIHBvd2VyLCBhbmQgY29uZGl0aW9uIAogICAgICBjb2xuYW1lcyhhbGxfZGF0YV92KVt3aGljaChuYW1lcyhhbGxfZGF0YV92KSA9PSBjKCJ0cmFja19sb2NhdGlvbiIsICJ0cmFja19wb3dlciIsICJ0cmFja19jb25kaXRpb24iKSldID0gYygibG9jYXRpb24iLCAicG93ZXIiLCAiY29uZGl0aW9uIikKICAgICMgZm9yIHRoZSAiaG9yaXpvbnRhbCIgdGFyZ2V0cyAtLSBhbGxfZGF0YV9oCiAgICBhbGxfZGF0YV9oID0gUmVkdWNlKGZ1bmN0aW9uKHgsIHkpIG1lcmdlKHgsIHksIGJ5PSJwYXJ0aWNpcGFudCIpLCBsaXN0KHRyYWNrX2ZpbmFsLCBvc3Bhbl9maW5hbCwgZ25nX2hfZmluYWwsIGRwbHlyOjpzZWxlY3Qoc3VydmV5X2ZpbmFsLCAtYyhzdXJfbG9jYXRpb24sIHN1cl9wb3dlciwgc3VyX2NvbmRpdGlvbikpKSkKICAgICAgIyByZW5hbWUgdGhlIHRyYWNraW5nIHNoZWV0IGNvbHVtbnMgZm9yIHRoZSBsb2NhdGlvbiwgcG93ZXIsIGFuZCBjb25kaXRpb24gCiAgICAgIGNvbG5hbWVzKGFsbF9kYXRhX2gpW3doaWNoKG5hbWVzKGFsbF9kYXRhX2gpID09IGMoInRyYWNrX2xvY2F0aW9uIiwgInRyYWNrX3Bvd2VyIiwgInRyYWNrX2NvbmRpdGlvbiIpKV0gPSBjKCJsb2NhdGlvbiIsICJwb3dlciIsICJjb25kaXRpb24iKQoKICAjIHJlbmFtZSB0YXJnZXQtc3BlY2lmaWMgY29sdW1ucyBmb3IgYm90aCBkYXRhIGZyYW1lcyAodG8gYmluZCkKICAgICMgZm9yIHRoZSAiZ28iIHRyaWFscwogICAgbmFtZXMoYWxsX2RhdGFfdilbbmFtZXMoYWxsX2RhdGFfdikgPT0gInRyaWFsX3RvdF92Il0gPSAiZ25nX3RyaWFsX3RvdF9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX3YpW25hbWVzKGFsbF9kYXRhX3YpID09ICJzY29yZV92Il0gPSAiZ25nX3Njb3JlX2xvbmciIAogICAgbmFtZXMoYWxsX2RhdGFfdilbbmFtZXMoYWxsX2RhdGFfdikgPT0gInJlc3BfdG90X3YiXSA9ICJnbmdfcmVzcF90b3RfbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV92KVtuYW1lcyhhbGxfZGF0YV92KSA9PSAibm9fcmVzcF90b3RfdiJdID0gImduZ19ub19yZXNwX3RvdF9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX3YpW25hbWVzKGFsbF9kYXRhX3YpID09ICJlcnJfdG90X3YiXSA9ICJnbmdfZXJyX3RvdF9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX3YpW25hbWVzKGFsbF9kYXRhX3YpID09ICJlcnJfY29tX3YiXSA9ICJnbmdfZXJyX2NvbV9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX3YpW25hbWVzKGFsbF9kYXRhX3YpID09ICJlcnJfb21pX3YiXSA9ICJnbmdfZXJyX29taV9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX3YpW25hbWVzKGFsbF9kYXRhX3YpID09ICJydF9hdl92Il0gPSAiZ25nX3J0X2F2X2xvbmciIAogICAgbmFtZXMoYWxsX2RhdGFfdilbbmFtZXMoYWxsX2RhdGFfdikgPT0gImV4Y2x1ZGVfdiJdID0gImduZ19leGNsdWRlX2xvbmciCiAgICAjIGZvciB0aGUgIm5vLWdvIiB0cmlhbHMKICAgIG5hbWVzKGFsbF9kYXRhX2gpW25hbWVzKGFsbF9kYXRhX2gpID09ICJ0cmlhbF90b3RfaCJdID0gImduZ190cmlhbF90b3RfbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV9oKVtuYW1lcyhhbGxfZGF0YV9oKSA9PSAic2NvcmVfaCJdID0gImduZ19zY29yZV9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX2gpW25hbWVzKGFsbF9kYXRhX2gpID09ICJyZXNwX3RvdF9oIl0gPSAiZ25nX3Jlc3BfdG90X2xvbmciIAogICAgbmFtZXMoYWxsX2RhdGFfaClbbmFtZXMoYWxsX2RhdGFfaCkgPT0gIm5vX3Jlc3BfdG90X2giXSA9ICJnbmdfbm9fcmVzcF90b3RfbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV9oKVtuYW1lcyhhbGxfZGF0YV9oKSA9PSAiZXJyX3RvdF9oIl0gPSAiZ25nX2Vycl90b3RfbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV9oKVtuYW1lcyhhbGxfZGF0YV9oKSA9PSAiZXJyX2NvbV9oIl0gPSAiZ25nX2Vycl9jb21fbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV9oKVtuYW1lcyhhbGxfZGF0YV9oKSA9PSAiZXJyX29taV9oIl0gPSAiZ25nX2Vycl9vbWlfbG9uZyIgCiAgICBuYW1lcyhhbGxfZGF0YV9oKVtuYW1lcyhhbGxfZGF0YV9oKSA9PSAicnRfYXZfaCJdID0gImduZ19ydF9hdl9sb25nIiAKICAgIG5hbWVzKGFsbF9kYXRhX2gpW25hbWVzKGFsbF9kYXRhX2gpID09ICJleGNsdWRlX2giXSA9ICJnbmdfZXhjbHVkZV9sb25nIgogIAogICMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBkZXBpY3RpbmcgdGhlIHRhcmdldCB0eXBlOiBlaXRoZXIgImdvIiAoY29kZWQgYXMgMSkgb3IgIm5vLWdvIiAoY29kZWQgYXMgMikKICBjdWVfdHlwZSA9IGFzLmRhdGEuZnJhbWUoYyhyZXAoMSwgbGVuZ3RoKGFsbF9kYXRhX3YkcGFydGljaXBhbnQpKSwgcmVwKDIsIGxlbmd0aChhbGxfZGF0YV9oJHBhcnRpY2lwYW50KSkpKQogICAgY29sbmFtZXMoY3VlX3R5cGUpID0gYygiY3VlIikgIAoKICAjIEJpbmQgdGhlIGdvIGFuZCBuby1nbyBkYXRhIGZyYW1lcyBpbnRvIDEgKGluIGxvbmcgZm9ybWF0KQogIGduZ19jdWVfYmluZCA9IGRwbHlyOjpiaW5kX3Jvd3MoYWxsX2RhdGFfdiwgYWxsX2RhdGFfaCkKICAKICAjIGFkZCB0aGUgdGFyZ2V0IHR5cGUgY29sdW1uIGRlcGljdGluZyB0aGUgdGFyZ2V0IHR5cGU6IGVpdGhlciAiZ28iIChjb2RlZCBhcyAxKSBvciAibm8tZ28iIChjb2RlZCBhcyAyKQogIGFsbF9kYXRhX2N1ZV9sb25nID0gZHBseXI6OmJpbmRfY29scyhjdWVfdHlwZSwgZ25nX2N1ZV9iaW5kKQogIAogIGFsbF9kYXRhX2N1ZV9sb25nCmBgYAoKPC9kZXRhaWxzPgoKPC9kZXRhaWxzPgoKIyMjIDQuIE9TcGFuIEFuYWx5c2lzCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKQWxsIHRoZSBkYXRhIHJlbGF0ZWQgdG8gdGhlIE9TcGFuIEFuYWx5c2lzIGZyb20gdGhlIHByZXNlbnQgc3R1ZHkgaW4gb25lIGRhdGEgZnJhbWU6ICoqIm9zcGFuX2FuYWx5c2lzIioqICooY2xpY2sgdG8gc2VlIG1vcmUpKgoKPC9zdW1tYXJ5PgoKLSAgIFRoaXMgZGF0YSBpbmNsdWRlZCB0aGUgZm9sbG93aW5nOgoKICAgIC0gICBgciBjb2xuYW1lcyhvc3Bhbl9hbmFseXNpcylgCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgZmluYWwgZGF0YSBpbnRvIHRoZSBvc3Bhbi1yZWxhdGVkIGRhdGEgZnJhbWUuICooY2xpY2sgdG8gZXhwYW5kKSoKCjwvc3VtbWFyeT4KCmBgYHtyIGNyZWF0ZV9vc3Bhbl9hbmFseXNpc30KCiMgbWFrZSBhIG5ldyBkYXRhIGZyYW1lIGZvciB0aGUgb3NwYW4gYW5hbHlzaXMKb3NwYW5fYW5hbHlzaXMgPSBkcGx5cjo6c2VsZWN0KGFsbF9kYXRhLCBwYXJ0aWNpcGFudCwgYWdlLCBnZW5kZXIsIGxhbmcsIHByb2dyYW0sIHllYXIsIGxvY2F0aW9uLCBwb3dlciwgYmFsYW5jZSwgb3NwYW5fYWJzb2x1dGVfc2NvcmUsIG9zcGFuX21hdGhfcGVyY2VudF9jb3JyLCBvc3Bhbl9tYXRoX2NyaXRlcmlhXzg1KQoKCm9zcGFuX2FuYWx5c2lzCgpgYGAKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIyA1LiBHby9Oby1HbzogRXJyb3IgQW5hbHlzaXMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpBbGwgdGhlIGRhdGEgcmVsYXRlZCB0byB0aGUgR28vTm8tR28gRXJyb3IgQW5hbHlzaXMgZnJvbSB0aGUgcHJlc2VudCBzdHVkeSBpbiBvbmUgZGF0YSBmcmFtZTogKioiZ25nX2Vycl9hbmFseXNpcyIqKgoKTm90ZTogdGhpcyBkYXRhIGlzIGluIGEgbG9uZyBmb3JtYXQgZm9yIGEgcmVwZWF0ZWQgbWVhc3VyZXMgYW5hbHlzaXMgKGkuZS4sIGJhc2VkIG9uIHRhcmdldCB0eXBlOiBlaXRoZXIgImdvIiBvciAibm8tZ28iKS4gKihjbGljayB0byBzZWUgbW9yZSkqCgo8L3N1bW1hcnk+CgotICAgVGhpcyBkYXRhIGluY2x1ZGVkIHRoZSBmb2xsb3dpbmc6CgogICAgLSAgIGByIGNvbG5hbWVzKGduZ19lcnJfYW5hbHlzaXMpYAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBvcmdhbml6ZWQgdGhlIGZpbmFsIGxvbmcgZGF0YSBpbnRvIGEgZGF0YSBmcmFtZSBmb3IgdGhlIEdvL05vLUdvIEVycm9yIEFuYWx5c2lzLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZ25nX2Vycl9hbmFseXNpc30KIyBtYWtlIGEgbmV3IGRhdGEgZnJhbWUgZm9yIHRoZSBnbmcgZXJyb3IgYW5hbHlzaXMKZ25nX2Vycl9hbmFseXNpcyA9IGRwbHlyOjpzZWxlY3QoYWxsX2RhdGFfY3VlX2xvbmcsIHBhcnRpY2lwYW50LCBhZ2VfbG9uZywgZ2VuZGVyLCBsYW5nX2xvbmcsIHByb2dyYW0sIHllYXIsIGxvY2F0aW9uLCBwb3dlciwgY29uZGl0aW9uLCBiYWxhbmNlLCBjdWUsIGduZ19leGNsdWRlX2xvbmcsIGduZ190cmlhbF90b3RfbG9uZywgZ25nX3Jlc3BfdG90X2xvbmcsIGduZ19ub19yZXNwX3RvdF9sb25nLCBnbmdfZXJyX3RvdF9sb25nLCBnbmdfZXJyX2NvbV9sb25nLCBnbmdfZXJyX29taV9sb25nKQoKZ25nX2Vycl9hbmFseXNpcwoKYGBgCgo8L2RldGFpbHM+Cgo8L2RldGFpbHM+CgojIyMgNi4gR28vTm8tR286IEFjY3VyYWN5IEFuYWx5c2lzCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKQWxsIHRoZSBkYXRhIHJlbGF0ZWQgdG8gdGhlIEdvL05vLUdvIEFjY3VyYWN5IEFuYWx5c2lzIGZyb20gdGhlIHByZXNlbnQgc3R1ZHkgaW4gb25lIGRhdGEgZnJhbWU6ICoqImduZ19hY19hbmFseXNpcyIqKiAqKGNsaWNrIHRvIHNlZSBtb3JlKSoKCjwvc3VtbWFyeT4KCi0gICBUaGlzIGRhdGEgaW5jbHVkZWQgdGhlIGZvbGxvd2luZzoKCiAgICAtICAgYHIgY29sbmFtZXMoZ25nX2FjX2FuYWx5c2lzKWAKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgb3JnYW5pemVkIHRoZSBmaW5hbCBkYXRhIGludG8gYSBkYXRhIGZyYW1lIHJlbGF0ZWQgdG8gdGhlIEdvL05vLUdvIEFjY3VyYWN5IEFuYWx5c2lzLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZ25nX2FjX2FuYWx5c2lzfQoKIyBtYWtlIGEgbmV3IGRhdGEgZnJhbWUgZm9yIHRoZSBnbmcgYWNjdXJhY3kgYW5hbHlzaXMKZ25nX2FjX2FuYWx5c2lzID0gZHBseXI6OnNlbGVjdChhbGxfZGF0YSwgcGFydGljaXBhbnQsIGFnZSwgZ2VuZGVyLCBsYW5nLCBwcm9ncmFtLCB5ZWFyLCBsb2NhdGlvbiwgcG93ZXIsIGJhbGFuY2UsIGduZ190cmlhbF90b3QsIGduZ19yZXNwX3RvdCwgZ25nX25vX3Jlc3BfdG90LCBnbmdfcnRfYXYpIAoKZ25nX2FjX2FuYWx5c2lzCmBgYAoKPC9kZXRhaWxzPgoKPC9kZXRhaWxzPgoKIyMjIDcuIFNBRDogRmFjdG9yIEFuYWx5c2lzCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKQWxsIHRoZSBkYXRhIHJlbGF0ZWQgdG8gdGhlIEZhY3RvciBBbmFseXNpcyBmcm9tIHRoZSBwcmVzZW50IHN0dWR5IGluIG9uZSBkYXRhIGZyYW1lOiAqKiJmYWN0b3JfYW5hbHlzaXMiKiogKihjbGljayB0byBzZWUgbW9yZSkqCgo8L3N1bW1hcnk+CgotICAgVGhpcyBkYXRhIGluY2x1ZGVkIHRoZSBmb2xsb3dpbmc6CgogICAgLSAgIGByIGNvbG5hbWVzKGZhY3Rvcl9hbmFseXNpcylgCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgZmluYWwgZGF0YSBpbnRvIHRoZSBmYWN0b3IgYW5hbHlzaXMtcmVsYXRlZCBkYXRhIGZyYW1lLiAqKGNsaWNrIHRvIGV4cGFuZCkqCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZmFjdG9yX2FuYWx5c2lzfQoKIyBtYWtlIGEgbmV3IGRhdGEgZnJhbWUgZm9yIHRoZSBmYWN0b3IgYW5hbHlzaXMKZmFjdG9yX2FuYWx5c2lzID0gZHBseXI6OnNlbGVjdChhbGxfZGF0YSwgcGFydGljaXBhbnQsIGFnZSwgZ2VuZGVyLCBsYW5nLCBwcm9ncmFtLCB5ZWFyLCBsb2NhdGlvbiwgcG93ZXIsIGJhbGFuY2UsIFNBRF8xOlNBRF8xMywgU0FEX3Njb3JlKQoKZmFjdG9yX2FuYWx5c2lzCgpgYGAKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIyA4LiBNb2RlcmF0aW9uIEFuYWx5c2lzCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKQWxsIHRoZSBkYXRhIHJlbGF0ZWQgdG8gdGhlIE1vZGVyYXRpb24gQW5hbHlzaXMgZnJvbSB0aGUgcHJlc2VudCBzdHVkeSBpbiBvbmUgZGF0YSBmcmFtZTogKioibW9kX2FuYWx5c2lzIioqICooY2xpY2sgdG8gc2VlIG1vcmUpKgoKPC9zdW1tYXJ5PgoKLSAgIFRoaXMgZGF0YSBpbmNsdWRlZCB0aGUgZm9sbG93aW5nOgoKICAgIC0gICBgciBjb2xuYW1lcyhtb2RfYW5hbHlzaXMpYAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBvcmdhbml6ZWQgdGhlIGZpbmFsIGRhdGEgaW50byB0aGUgbW9kZXJhdGlvbi1yZWxhdGVkIGRhdGEgZnJhbWUuICooY2xpY2sgdG8gZXhwYW5kKSoKCjwvc3VtbWFyeT4KCmBgYHtyIGNyZWF0ZV9tb2RfYW5hbHlzaXN9CgojIG1ha2UgYSBuZXcgZGF0YSBmcmFtZSBmb3IgdGhlIGdsbSBhbmFseXNpcwptb2RfYW5hbHlzaXMgPSBkcGx5cjo6c2VsZWN0KGFsbF9kYXRhLCBwYXJ0aWNpcGFudCwgb3NwYW5fYWJzb2x1dGVfc2NvcmUsIGFnZSwgZ2VuZGVyLCBsYW5nLCBwcm9ncmFtLCB5ZWFyLCBsb2NhdGlvbiwgcG93ZXIsIGJhbGFuY2UsIFNBRF9zY29yZSwgU0FEX2RlcF9zY29yZSwgU0FEX2VhX3Njb3JlLCBTQURfYWNjZXNzX3Njb3JlLCBTQURfZGlzdF9zY29yZSwgU1VRX2FiZXh0X3Njb3JlLCBTVVFfZHVyYWN0X3Njb3JlLCBTVVFfdXNlXzEsIFNVUV91c2VfMiwgU1VRX3VzZV8zLCBTVVFfZXhwXzEsIFNVUV9leHBfMiwgU1VRX2V4cF80KQoKbW9kX2FuYWx5c2lzCgpgYGAKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMgRGVzY3JpcHRpdmUgU3RhdGlzdGljcyB7I0RTfQoKVGhlIGZvbGxvd2luZyBmaWd1cmVzIGFuZCB0YWJsZXMgZGVwaWN0IHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciB0aGUgcHJlc2VudCBzdHVkeSdzIGRhdGEuIFRoaXMgd2FzIGRvbmUgYWNyb3NzIGFsbCBjb25kaXRpb25zICgqVG9sdGFsKikgYW5kIGRpdmlkZWQgYnkgY29uZGl0aW9uOiBzbWFydHBob25lIGxvY2F0aW9uIChpLmUuLCBvbiBkZXNrLCBpbiBwb2NrZXQvYmFnLCBvciBvdXRzaWRlKSBhbmQgcG93ZXIgKGkuZS4sIG9uIG9yIG9mZikuIEZvciBhbnkgKipjb250aW51b3VzIHZhcmlhYmxlcyoqLCB0aGUgdGFibGUocykgZGVwaWN0IHRoZSBtZWFuICgqTSopLCBzdGFuZGFyZCBkZXZpYXRpb24gKCpTRCopLCBtaW5pbXVtIHNjb3JlICgqbWluLiopLCBtYXhpbXVtIHNjb3JlICgqbWF4LiopLCBhbmQgdGhlIHNhbXBsZSBzaXplICgqbiopLiBGb3IgYW55ICoqbm9taW5hbCB2YXJpYWJsZXMqKiwgdGhlIHRhYmxlKHMpIGRlcGljdCB0aGUgdmFyaWFibGUsIGxldmVscywgYW5kIGZyZXF1ZW5jeSBmb3IgZWFjaCBsZXZlbC4gVGhpcyB3YXMgZG9uZSBmb3IgdGhlIGZvbGxvd2luZzoKCjEuICBEZW1vZ3JhcGhpY3MgRGF0YQoKICAgIC0gICBDb250aW51b3VzIHZhcmlhYmxlcyAoaS5lLiwgYWdlKQogICAgLSAgIE5vbWluYWwgdmFyaWFibGVzIChpLmUuLCBTYW1wbGUgU2l6ZSwgQmFsYW5jZSwgR2VuZGVyLCBMYW5ndWFnZSwgUHJvZ3JhbSwgYW5kIFllYXIpCgoyLiAgVGFzayBEYXRhCgogICAgLSAgIE9TcGFuIERhdGEgKGkuZS4sIGFic29sdXRlIHNjb3JlKQogICAgLSAgIEdvL05vLUdvIERhdGEgKGkuZS4sIG9taXNzaW9uIGVycm9ycywgYXZlcmFnZSByZWFjdGlvbiB0aW1lKQoKMy4gIFF1ZXN0aW9ubmFpcmUgRGF0YQoKICAgIC0gICBTVVEgRGF0YSAoZS5nLiwgdHlwaWNhbCBzbWFydHBob25lIHVzYWdlKQogICAgLSAgIFNBRCBEYXRhIChpLmUuLCBTQUQgc2NvcmUpCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljIGRhdGEgc2V0cyAqKGNsaWNrIHRvIHNlZSBjb2RlKSoKCjwvc3VtbWFyeT4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgb3JnYW5pemVkIHRoZSBmaW5hbCBkYXRhIGludG8gdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIHRoZSAqKkRlbW9ncmFwaGljIERhdGEqKiAqKGNsaWNrIHRvIHNlZSBjb2RlKSouCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfYWxsX2RhdGFfZGVtb19kZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgbWFrZSBuZXcgZGF0YSBmcmFtZSBmb3IgZGVzY3JpcHRpdmUgc3RhdHMKYWxsX2RhdGFfZGVtb19kZXMgPC0gCiAgYWxsX2RhdGEgJT4lIAogIAogICMgc3Vic2V0IGRhdGEgZm9yIGRlc2NyaXB0aXZlIHZhcmlhYmxlcyBvbmx5CiAgc2VsZWN0KGxvY2F0aW9uLCBwb3dlciwgY29uZGl0aW9uLCBiYWxhbmNlLCBhZ2UsIGdlbmRlciwgbGFuZywgcHJvZ3JhbSwgeWVhcikgJT4lIAogIAogICMgc2V0IHNvbWUgdmFyaWFibGVzIGFzIGZhY3RvcnMKICBtdXRhdGUobG9jYXRpb24gPSBmYWN0b3IobG9jYXRpb24sIGxldmVscyA9IGMoMTozKSwgbGFiZWxzID0gYygiRGVzayIsICJQb2NrZXQvQmFnIiwgIk91dHNpZGUiKSkpICU+JSAKICBtdXRhdGUocG93ZXIgPSBmYWN0b3IocG93ZXIsIGxldmVscyA9IGMoMToyKSwgbGFiZWxzID0gYygiT24iLCAiT2ZmIikpKSAlPiUgCiAgbXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IGMoMTo2KSwgbGFiZWxzID0gYygiT24gJiBEZXNrIiwgIk9uICYgUG9ja2V0L0JhZyIsICJPbiAmIE91dHNpZGUiLCAiT2ZmICYgRGVzayIsICJPZmYgJiBQb2NrZXQvQmFnIiwgIk9mZiAmIE91dHNpZGUiKSkpICU+JSAKICBtdXRhdGUoYmFsYW5jZSA9IGZhY3RvcihiYWxhbmNlLCBsZXZlbHMgPSBjKDE6MiksIGxhYmVscyA9IGMoIk9zcGFuIEZyaXN0IiwgIkduRyBGaXJzdCIpKSkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSBmYWN0b3IoZ2VuZGVyLCBsZXZlbHMgPSBjKDE6MiksIGxhYmVscyA9IGMoIk1hbGUiLCAiRmVtYWxlIikpKSAlPiUgCiAgbXV0YXRlKGxhbmcgPSBmYWN0b3IobGFuZywgbGV2ZWxzID0gYygwLCAxKSwgbGFiZWxzID0gYygiT3RoZXIiLCAiRW5nbGlzaCIpKSkgJT4lIAogIG11dGF0ZShwcm9ncmFtID0gZmFjdG9yKHByb2dyYW0sIGxldmVscyA9IGMoMywgNCwgMTMsIDE0LCAyOCwgMzIsIDM3LCAxMiwgMTcsIDE5LCAxNSwgMjAsIDI0LCAyMywgMjYsIDEsIDIsIDUsIDcsIDgsIDExLCAxNiwgMTgsIDIyLCAyNywgMjksIDMzLCAzNiwgNiwgOSwgMTAsIDIxLCAyNSwgMzAsIDMxLCAzNCwgMzUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMocmVwKCJBcnRzICYgSHVtYW5pdGllcyIsIDcpLCAiRW5naW5lZXJpbmciLCByZXAoIkhlYWx0aCBTY2llbmNlcyIsIDIpLCByZXAoIkluZm9ybWF0aW9uICYgTWVkaWEgU3R1ZGllcyIsIDMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZWRpY2luZSAmIERlbnRpc3RyeSIsICJNdXNpYyIsIHJlcCgiU2NpZW5jZSIsIDEzKSwgcmVwKCJTb2NpYWwgU2NpZW5jZSIsIDkpKSkpICU+JSAKICBtdXRhdGUoeWVhciA9IGZhY3Rvcih5ZWFyLCBsZXZlbHMgPSBjKDE6NCksIGxhYmVscyA9IGMoIkZpcnN0IFllYXIiLCAiU2Vjb25kIFllYXIiLCAiVGhpcmQgWWVhciIsICJGb3VydGggWWVhciIpKSkKCmFsbF9kYXRhX2RlbW9fZGVzCmBgYAoKPC9kZXRhaWxzPgoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBvcmdhbml6ZWQgdGhlIGZpbmFsIGRhdGEgaW50byB0aGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgdGhlICoqVGFzayBEYXRhKiogKihjbGljayB0byBzZWUgY29kZSkqLgoKPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2FsbF9kYXRhX3Rhc2tfZGVzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIG1ha2UgbmV3IGRhdGEgZnJhbWUgZm9yIGRlc2NyaXB0aXZlIHN0YXRzCmFsbF9kYXRhX3Rhc2tfZGVzIDwtIAogIGFsbF9kYXRhICU+JSAKICAjIHN1YnNldCBkYXRhIGZvciBkZXNjcmlwdGl2ZSB2YXJpYWJsZXMgb25seQogIHNlbGVjdChsb2NhdGlvbiwgcG93ZXIsIGNvbmRpdGlvbiwgb3NwYW5fYWJzb2x1dGVfc2NvcmUsIG9zcGFuX3RvdGFsX2NvcnIsIG9zcGFuX21hdGhfcGVyY2VudF9jb3JyLCBnbmdfc2NvcmUsIGduZ19lcnJfb21pLCBnbmdfcnRfYXYpCgphbGxfZGF0YV90YXNrX2RlcwpgYGAKCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGNvZGUgb3JnYW5pemVkIHRoZSBmaW5hbCBkYXRhIGludG8gdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIHRoZSAqKlF1ZXN0aW9ubmFpcmUgRGF0YSoqICooY2xpY2sgdG8gc2VlIGNvZGUpKi4KCjwvc3VtbWFyeT4KCmBgYHtyIGNyZWF0ZV9hbGxfZGF0YV9xdWVzX2RlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBtYWtlIG5ldyBkYXRhIGZyYW1lIGZvciBkZXNjcmlwdGl2ZSBzdGF0cwphbGxfZGF0YV9xdWVzX2RlcyA8LSAKICBhbGxfZGF0YSAlPiUgCiAgCiAgIyBzdWJzZXQgZGF0YSBmb3IgZGVzY3JpcHRpdmUgdmFyaWFibGVzIG9ubHkKICBzZWxlY3QobG9jYXRpb24sIHBvd2VyLCBjb25kaXRpb24sIFNVUV91c2VfMTpTVVFfdXNlXzMsIFNVUV9leHBfMSwgU1VRX2V4cF8yLCBTVVFfZXhwXzQsIAogICAgICAgICBTQURfc2NvcmUsIFNBRF9kZXBfc2NvcmUsIFNBRF9lYV9zY29yZSwgU0FEX2FjY2Vzc19zY29yZSwgU0FEX2Rpc3Rfc2NvcmUsIFNVUV9hYmV4dF9zY29yZSwgU1VRX2R1cmFjdF9zY29yZSkgJT4lIAogIAogICMgc2V0IHNvbWUgdmFyaWFibGVzIGFzIGZhY3RvcnMKICBtdXRhdGUoU1VRX3VzZV8xID0gZmFjdG9yKFNVUV91c2VfMSwgbGV2ZWxzID0gYygxOjQpLCBsYWJlbHMgPSBjKCIwLTUiLCAiNi0xMCIsICIxMS0xNSIsICI+MTUiKSkpICU+JSAKICBtdXRhdGUoU1VRX3VzZV8yID0gZmFjdG9yKFNVUV91c2VfMiwgbGV2ZWxzID0gYygxOjQpLCBsYWJlbHMgPSBjKCIwLTUiLCAiNi0xMCIsICIxMS0xNSIsICI+MTUiKSkpICU+JSAKICBtdXRhdGUoU1VRX3VzZV8zID0gZmFjdG9yKFNVUV91c2VfMywgbGV2ZWxzID0gYygxOjQpLCBsYWJlbHMgPSBjKCIwLTUiLCAiNi0xMCIsICIxMS0xNSIsICI+MTUiKSkpICU+JSAKICBtdXRhdGUoU1VRX2V4cF8xID0gZmFjdG9yKFNVUV9leHBfMSwgbGV2ZWxzID0gYygxOjQpLCBsYWJlbHMgPSBjKCIkMC0kMjAiLCAiJDIxLSQ0MCIsICIkNDEtJDYwIiwgIj4kNjAiKSkpCgphbGxfZGF0YV9xdWVzX2RlcwpgYGAKCjwvZGV0YWlscz4KCjwvZGV0YWlscz4KCiMjIERlbW9ncmFwaGljIERhdGEgeyNEU2RlbW99Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhlIGZvbGxvd2luZyB0YWJsZSBkZXBpY3RzIHRoZSAqKmNvbnRpbnVvdXMgdmFyaWFibGUocykqKiAoaS5lLiwgYWdlKSBmcm9tIGFsbCBwYXJ0aWNpcGFudHMgaW4gdGhlIHByZXNlbnQgc3R1ZHkgKihjbGljayB0byBzZWUgY29kZSkqLgoKPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2Rlc19kZW1vX2NvbnQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgY3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHRoZSBkZXNjcmlwdGl2ZSBzdGF0cyBvZiBhbGwgdGhlIGRhdGEsIEdST1VQRUQgYnkgdGhlIGxvY2F0aW9uICYgcG93ZXIgY29uZGl0aW9ucwogICMgdGhpcyBjcmVhdGVzIGluZm9ybWF0aW9uIGZvciB0aGUgNiBwb3NzaWJsZSBjb21iaW5lZCBjb25kaXRpb25zCmRlc19kZW1vX2NvbnQgPC0gCiAgIyBjcmVhdGUgdGhpcyBhcyBhIGRhdGEgZnJhbWUgcmF0aGVyIHRoYW4gbWF0cml4CiAgYXMuZGF0YS5mcmFtZShhbGxfZGF0YV9kZW1vX2RlcyAlPiUgCiAgICAgICAgICAgICAgICAgICMgc2VsZWN0IG9ubHkgYWdlICYgdGhlIGNvbmRpdGlvbiBjb2x1bW5zIC0tIHNpbmNlIGFnZSBpcyB0aGUgb25seSBjb250aW51b3VzIGRlbW9ncmFwaGljIHZhcmlhYmxlCiAgICAgICAgICAgICAgICAgIHNlbGVjdChjKGxvY2F0aW9uLCBwb3dlciwgYWdlKSkgJT4lIAogICAgICAgICAgICAgICAgICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyBmb3IgYWdlICYgb3V0cHV0IGFzIGEgbWF0cml4ICgibWF0ID0gVCIpCiAgICAgICAgICAgICAgICAgIGRlc2NyaWJlQnkoZ3JvdXAgPSBsaXN0KGFsbF9kYXRhX2RlbW9fZGVzJGxvY2F0aW9uLCBhbGxfZGF0YV9kZW1vX2RlcyRwb3dlciksIG1hdCA9IFQpCiAgICAgICAgICAgICAgICApCgojIGNyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCB0aGUgZGVzY3JpcHRpdmUgc3RhdHMgb2YgYWxsIHRoZSBkYXRhLCBBQ1JPU1MgdGhlIGxvY2F0aW9uICYgcG93ZXIgY29uZGl0aW9ucwpkZXNfZGVtb19jb250X2Fjcm9zcyA8LSAKICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyBmb3IgYWdlCiAgICAjIGNyZWF0ZSB0aGlzIGFzIGEgZGF0YSBmcmFtZSByYXRoZXIgdGhhbiBtYXRyaXgKICBhcy5kYXRhLmZyYW1lKHBzeWNoOjpkZXNjcmliZShhbGxfZGF0YV9kZW1vX2RlcyRhZ2UpKQogIAojIG9yZ2FuaXplIHRoZSBkYXRhIGludG8gYSBuZXcgZGF0YSBmcmFtZSBkZXBpY3RpbmcgdGhlIE0sIFNELCBtaW4uLCBtYXguLCBhbmQgbi4KZGVzX2RlbW9fY29udF90IDwtIAogIGFzLmRhdGEuZnJhbWUoY2JpbmQoYygiTSIsICJTRCIsICJtaW4uIiwgIm1heC4iLCAibiIpLCAKICAgICAgICAgICAgICAgICAgICAgIHJiaW5kKGMoZGVzX2RlbW9fY29udFtjKCJhZ2UxIiwgImFnZTIiLCAiYWdlMyIsICJhZ2U0IiwgImFnZTUiLCAiYWdlNiIpLF0kbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfZGVtb19jb250W2MoImFnZTEiLCAiYWdlMiIsICJhZ2UzIiwgImFnZTQiLCAiYWdlNSIsICJhZ2U2IiksXSRzZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfZGVtb19jb250W2MoImFnZTEiLCAiYWdlMiIsICJhZ2UzIiwgImFnZTQiLCAiYWdlNSIsICJhZ2U2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX2RlbW9fY29udFtjKCJhZ2UxIiwgImFnZTIiLCAiYWdlMyIsICJhZ2U0IiwgImFnZTUiLCAiYWdlNiIpLF0kbWF4KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19kZW1vX2NvbnRbYygiYWdlMSIsICJhZ2UyIiwgImFnZTMiLCAiYWdlNCIsICJhZ2U1IiwgImFnZTYiKSxdJG4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX2RlbW9fY29udF9hY3Jvc3MkbWVhbiwgZGVzX2RlbW9fY29udF9hY3Jvc3Mkc2QsIGRlc19kZW1vX2NvbnRfYWNyb3NzJG1pbiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc19kZW1vX2NvbnRfYWNyb3NzJG1heCwgZGVzX2RlbW9fY29udF9hY3Jvc3MkbikKICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKIyByZW5hbWUgY29sdW1ucyAgCmNvbG5hbWVzKGRlc19kZW1vX2NvbnRfdCkgPSBjKCJ2YXIiLCAiZE9OIiwgInBiT04iLCAib09OIiwgImRPRkYiLCAicGJPRkYiLCAib09GRiIsICJvdmVyYWxsIikKIyBjaGFuZ2UgYWxsIGNvbHVtbnMgZXhjZXB0ICJ2YXIiIHRvIG51bWVyaWMKZGVzX2RlbW9fY29udF90JGRPTiA8LSBhcy5udW1lcmljKGRlc19kZW1vX2NvbnRfdCRkT04pCmRlc19kZW1vX2NvbnRfdCRwYk9OIDwtIGFzLm51bWVyaWMoZGVzX2RlbW9fY29udF90JHBiT04pCmRlc19kZW1vX2NvbnRfdCRvT04gPC0gYXMubnVtZXJpYyhkZXNfZGVtb19jb250X3Qkb09OKQpkZXNfZGVtb19jb250X3QkZE9GRiA8LSBhcy5udW1lcmljKGRlc19kZW1vX2NvbnRfdCRkT0ZGKQpkZXNfZGVtb19jb250X3QkcGJPRkYgPC0gYXMubnVtZXJpYyhkZXNfZGVtb19jb250X3QkcGJPRkYpCmRlc19kZW1vX2NvbnRfdCRvT0ZGIDwtIGFzLm51bWVyaWMoZGVzX2RlbW9fY29udF90JG9PRkYpCmRlc19kZW1vX2NvbnRfdCRvdmVyYWxsIDwtIGFzLm51bWVyaWMoZGVzX2RlbW9fY29udF90JG92ZXJhbGwpCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19kZXNfZGVtb19jb250X3QsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgc2hvdyB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShkZXNfZGVtb19jb250X3QsIGNhcHRpb24gPSAiRGVtb2dyYXBoaWMgSW5mb3JtYXRpb24gYnkgQ29uZGl0aW9uIGFuZCBPdmVyYWxsOiBBZ2UiLCBkaWdpdHMgPSAyLCBhbGlnbiA9IHJlcCgnYycpLCBjb2wubmFtZXMgPSBjKCIgIiwgcmVwKGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIiksMiksICJUT1RBTCIpLCByb3cubmFtZXMgPSBjKDE6NykpICU+JSAKICBmb290bm90ZShnZW5lcmFsID0gIkNvbnRpbnVvdXMgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBzaG93bi4gJ1RPVEFMJyBjb2x1bW4gc2hvd3Mgc3RhdGlzdGljcyBhY3Jvc3MgYWxsIGNvbmRpdGlvbnMuIikgJT4lIAogIHBhY2tfcm93cygiQWdlICh5ZWFycykiLCAxLCA1KSAlPiUgCiAgIyBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiICIsICJTbWFydHBob25lIExvY2F0aW9uIiA9IDYsICIgIikpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsIiAiLCAiT04iID0gMywgIk9GRiIgPSAzLCAiICIpLCBib2xkID0gVCkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDYsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9yZGVyX2xlZnQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoZSBmb2xsb3dpbmcgdGFibGUgZGVwaWN0cyB0aGUgKipub21pbmFsIHZhcmlhYmxlcyoqIChpLmUuLCBTYW1wbGUgU2l6ZSwgQmFsYW5jZSwgR2VuZGVyLCBMYW5ndWFnZSwgUHJvZ3JhbSwgYW5kIFllYXIpIGZyb20gYWxsIHBhcnRpY2lwYW50cyBpbiB0aGUgcHJlc2VudCBzdHVkeSAqKGNsaWNrIHRvIHNlZSBjb2RlKSouCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZGVzX2RlbW9fbm9tLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIGNyZWF0ZSBjb3VudHMgZm9yIGVhY2ggbm9taW5hbCB2YXJpYWJsZSBkaXZpZGVkIGJ5IGNvbmRpdGlvbgogICMgZGV0YWlscyBzaG93biBmb3IgZmlyc3QgdmFyaWFibGUgb25seSBkZXNfbm9tCmRlc19kZW1vX25vbV9iYWwgPC0gCiAgYWxsX2RhdGFfZGVtb19kZXMgJT4lIAogICMgc2VsZWN0IG9ubHkgdGhlIHZhcmlhYmxlcyBvZiBpbnRlcmVzdDogY29uZGl0aW9uICYgYmFsYW5jZQogIHNlbGVjdChjb25kaXRpb24sIGJhbGFuY2UpICU+JSAKICAjIGRpdmlkZSBieSB0aGUgY29uZGl0aW9uIHR5cGUgKGkuZS4sIG1peCBvZiBzbWFydHBob25lIHBvd2VyIGFuZCBsb2NhdGlvbikgJiBiYWxhbmNlIChpLmUuLCBPc3BhbiAxc3Qgb3IgR25HIDFzdCkKICBncm91cF9ieShjb25kaXRpb24sIGJhbGFuY2UpICU+JSAKICAjIGNvdW50IHRoZSBmcmVxdWVuY2llcyBmb3IgYmFsYW5jZQogIGRwbHlyOjpjb3VudCgpICU+JSAKICAjIHRyYW5zcG9zZSB0aGUgdGFibGUKICBzcHJlYWQoY29uZGl0aW9uLCBuKSAlPiUgCiAgIyByZW5hbWUgdGhlIGNvbHVtbiB0byBqb2luIGxhdGVyCiAgZHBseXI6OnJlbmFtZShWYXJpYWJsZSA9IGJhbGFuY2UpICU+JSAKICAjIGZvciBlYWNoIHJvdy4uLgogIHJvd3dpc2UoKSAlPiUgCiAgIyBhZGQgc3VtIGNvbHVtbiBhY3Jvc3MgY29uZGl0aW9ucwogIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYE9uICYgRGVza2AsIGBPbiAmIFBvY2tldC9CYWdgLCBgT24gJiBPdXRzaWRlYCwgYE9mZiAmIERlc2tgLCBgT2ZmICYgUG9ja2V0L0JhZ2AsIGBPZmYgJiBPdXRzaWRlYCwgbmEucm0gPSBUKSkKCmRlc19kZW1vX25vbV9nZW5kZXIgPC0gYWxsX2RhdGFfZGVtb19kZXMgJT4lIHNlbGVjdChjb25kaXRpb24sIGdlbmRlcikgJT4lIGdyb3VwX2J5KGNvbmRpdGlvbiwgZ2VuZGVyKSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gZ2VuZGVyKSAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGBPbiAmIERlc2tgLCBgT24gJiBQb2NrZXQvQmFnYCwgYE9uICYgT3V0c2lkZWAsIGBPZmYgJiBEZXNrYCwgYE9mZiAmIFBvY2tldC9CYWdgLCBgT2ZmICYgT3V0c2lkZWAsIG5hLnJtID0gVCkpCgpkZXNfZGVtb19ub21fbGFuZyA8LSBhbGxfZGF0YV9kZW1vX2RlcyAlPiUgc2VsZWN0KGNvbmRpdGlvbiwgbGFuZykgJT4lIGdyb3VwX2J5KGNvbmRpdGlvbiwgbGFuZykgJT4lIGRwbHlyOjpjb3VudCgpICU+JSBzcHJlYWQoY29uZGl0aW9uLCBuKSAlPiUgZHBseXI6OnJlbmFtZShWYXJpYWJsZSA9IGxhbmcpICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYE9uICYgRGVza2AsIGBPbiAmIFBvY2tldC9CYWdgLCBgT24gJiBPdXRzaWRlYCwgYE9mZiAmIERlc2tgLCBgT2ZmICYgUG9ja2V0L0JhZ2AsIGBPZmYgJiBPdXRzaWRlYCwgbmEucm0gPSBUKSkKCmRlc19kZW1vX25vbV9wcm9ncmFtIDwtIGFsbF9kYXRhX2RlbW9fZGVzICU+JSBzZWxlY3QoY29uZGl0aW9uLCBwcm9ncmFtKSAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uLCBwcm9ncmFtKSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gcHJvZ3JhbSkgJT4lIHJvd3dpc2UoKSAlPiUgZHBseXI6Om11dGF0ZShUb3RhbCA9IHN1bShgT24gJiBEZXNrYCwgYE9uICYgUG9ja2V0L0JhZ2AsIGBPbiAmIE91dHNpZGVgLCBgT2ZmICYgRGVza2AsIGBPZmYgJiBQb2NrZXQvQmFnYCwgYE9mZiAmIE91dHNpZGVgLCBuYS5ybSA9IFQpKQoKZGVzX2RlbW9fbm9tX3llYXIgPC0gYWxsX2RhdGFfZGVtb19kZXMgJT4lIHNlbGVjdChjb25kaXRpb24sIHllYXIpICU+JSBncm91cF9ieShjb25kaXRpb24sIHllYXIpICU+JSBkcGx5cjo6Y291bnQoKSAlPiUgc3ByZWFkKGNvbmRpdGlvbiwgbikgJT4lIGRwbHlyOjpyZW5hbWUoVmFyaWFibGUgPSB5ZWFyKSAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGBPbiAmIERlc2tgLCBgT24gJiBQb2NrZXQvQmFnYCwgYE9uICYgT3V0c2lkZWAsIGBPZmYgJiBEZXNrYCwgYE9mZiAmIFBvY2tldC9CYWdgLCBgT2ZmICYgT3V0c2lkZWAsIG5hLnJtID0gVCkpCgpkZXNfZGVtb19ub21fdG90IDwtIGJpbmRfY29scyh0aWJibGUoVmFyaWFibGUgPSAibiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbF9kYXRhX2RlbW9fZGVzICU+JSBzZWxlY3QoY29uZGl0aW9uKSAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uKSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYE9uICYgRGVza2AsIGBPbiAmIFBvY2tldC9CYWdgLCBgT24gJiBPdXRzaWRlYCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9mZiAmIERlc2tgLCBgT2ZmICYgUG9ja2V0L0JhZ2AsIGBPZmYgJiBPdXRzaWRlYCwgbmEucm0gPSBUKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKIyBiaW5kIGFsbCB2YXJpYWJsZXMgaW50byBvbmUgZGF0YSBmcmFtZSAtLSAiZGVzX2RlbW9fbm9tIgpkZXNfZGVtb19ub20gPC0gCiAgcmJpbmQoZGVzX2RlbW9fbm9tX3RvdCwgZGVzX2RlbW9fbm9tX2JhbCwgZGVzX2RlbW9fbm9tX2dlbmRlciwgZGVzX2RlbW9fbm9tX2xhbmcsIGRlc19kZW1vX25vbV95ZWFyLCBkZXNfZGVtb19ub21fcHJvZ3JhbSkKIyBjaGFuZ2UgIk5BIiB2YXJpYWJsZXMgdG8gIk5vIFNlbGVjdGlvbiIKZGVzX2RlbW9fbm9tJFZhcmlhYmxlW3doaWNoKGlzLm5hKGRlc19kZW1vX25vbSRWYXJpYWJsZSkpXSA8LSBjKHJlcCgiTm8gU2VsZWN0aW9uIiwgbGVuZ3RoKGRlc19kZW1vX25vbSRWYXJpYWJsZVt3aGljaChpcy5uYShkZXNfZGVtb19ub20kVmFyaWFibGUpKV0pKSkKYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzaG93X2Rlc19kZW1vX25vbSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBzaG93ICJOQSIgYXMgIjAiCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAwKSAgCgojIHNob3cgdGFibGUgdXNpbmcga2FibGUKa2FibGUoZGVzX2RlbW9fbm9tLCBjYXB0aW9uID0gIkRlbW9ncmFwaGljIERhdGEgYnkgQ29uZGl0aW9uIGFuZCBPdmVyYWxsOiBTYW1wbGUgU2l6ZSwgQmFsYW5jZSwgR2VuZGVyLCBMYW5ndWFnZSwgUHJvZ3JhbSwgYW5kIFllYXIiLCBhbGlnbiA9IHJlcCgnYycpLCBjb2wubmFtZXMgPSBjKCIgIiwgcmVwKGMoIiBPbiBEZXNrIiwgIkluIFBvY2tldC9CYWciLCAiT3V0c2lkZSIpLCAyKSwgIlRPVEFMIiksIHJvdy5uYW1lcyA9IGMoMTo3KSwgZGlnaXRzID0gMikgJT4lIAogIGZvb3Rub3RlKGdlbmVyYWwgPSAiTm9taW5hbCBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHNob3duIGFzIGZyZXF1ZW5jaWVzLiBSb3cgMSBkZXBpY3RzIHNhbXBsZSBzaXplIGFjcm9zcyBhbGwgdmFyaWFibGVzLiAnVE9UQUwnIGNvbHVtbiBkZXBpY3RzIGZyZXF1ZW5jaWVzIGFjcm9zcyBhbGwgY29uZGl0aW9ucy4iKSAlPiUgCiAgcGFja19yb3dzKCJTYW1wbGUgU2l6ZSIsIDEsIDEpICU+JSAKICBwYWNrX3Jvd3MoIkJhbGFuY2UiLCAyLCAzKSAlPiUgCiAgcGFja19yb3dzKCJHZW5kZXIiLCA0LCA1KSAlPiUgCiAgcGFja19yb3dzKCJGaXJzdCBMYW5ndWFnZSIsIDYsIDcpICU+JSAKICBwYWNrX3Jvd3MoIlllYXIiLCA4LCAxMikgJT4lIAogIHBhY2tfcm93cygiUHJvZ3JhbSIsIDEzLCAyMSkgJT4lIAogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsICIgIiwgIk9OIiA9IDMsICAiT0ZGIiA9IDMsICIgIiksIGJvbGQgPSBUKSAlPiUKICByb3dfc3BlYygwLCBib2xkID0gVCkgJT4lIAogIGNvbHVtbl9zcGVjKDYsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9yZGVyX2xlZnQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gVCkgJT4lCiAga2FibGVfY2xhc3NpYygpCgojIHJlc3RvcmUgZ2xvYmFsIFIgb3B0aW9ucwpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gTkEpICAKCiMga2FibGUobGlzdChkZXNfY29udCwgZGVzX2NvbnQpKQpgYGAKCiMjIFRhc2sgRGF0YQoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoZSBmb2xsb3dpbmcgdGFibGUgZGVwaWN0cyB0aGUgKipPU3BhbiBhbmQgR28vTm8tR28gdmFyaWFibGUocykqKiAoaS5lLiwgT1NwYW4gQWJzb2x1dGUgU2NvcmUsIE9TcGFuIFRvdGFsIENvcnJlY3QsIE9TcGFuIE1hdGggUGVyY2VudGFnZSBDb3JyZWN0LCBHby9Oby1HbyBTY29yZSwgR28vTm8tR28gT21pc3Npb24gRXJyb3JzLCBHby9Oby1HbyBBdmVyYWdlIFJlYWN0aW9uIFRpbWUpIGZyb20gYWxsIHBhcnRpY2lwYW50cyBpbiB0aGUgcHJlc2VudCBzdHVkeSAqKGNsaWNrIHRvIHNlZSBjb2RlKSouCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZGVzX3Rhc2tfY29udCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyBjcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggdGhlIGRlc2NyaXB0aXZlIHN0YXRzIG9mIGFsbCB0aGUgZGF0YSwgR1JPVVBFRCBieSB0aGUgbG9jYXRpb24gJiBwb3dlciBjb25kaXRpb25zCiAgIyB0aGlzIGNyZWF0ZXMgaW5mb3JtYXRpb24gZm9yIHRoZSA2IHBvc3NpYmxlIGNvbWJpbmVkIGNvbmRpdGlvbnMKCiMgbm90IGRpdmlkZWQgYnkgY3VlIHR5cGUKZGVzX3Rhc2tfY29udCA8LSAKICAjIGNyZWF0ZSB0aGlzIGFzIGEgZGF0YSBmcmFtZSByYXRoZXIgdGhhbiBtYXRyaXgKICBhcy5kYXRhLmZyYW1lKGFsbF9kYXRhX3Rhc2tfZGVzICU+JSAKICAgICAgICAgICAgICAgICAgIyBzZWxlY3QgdmFyaWFibGVzICYgdGhlIGNvbmRpdGlvbiBjb2x1bW5zCiAgICAgICAgICAgICAgICAgIHNlbGVjdCgtY29uZGl0aW9uKSAlPiUgCiAgICAgICAgICAgICAgICAgICMgZ2V0IGRlc2NyaXB0aXZlIHN0YXRzICYgb3V0cHV0IGFzIGEgbWF0cml4ICgibWF0ID0gVCIpCiAgICAgICAgICAgICAgICAgIGRlc2NyaWJlQnkoZ3JvdXAgPSBsaXN0KGFsbF9kYXRhX3Rhc2tfZGVzJGxvY2F0aW9uLCBhbGxfZGF0YV90YXNrX2RlcyRwb3dlciksIG1hdCA9IFQpCiAgICAgICAgICAgICAgICApCgojIGRpdmlkZWQgYnkgY3VlIHR5cGUgLS0gZm9yIEduRyBlcnJvciBhbmFseXNpcwojIGZvciB0aGUgdmVydGljYWwvZ28gY3VlIHR5cGUKZGVzX3Rhc2tfY29udF9jdWVfdiA8LSAKICAjIGNyZWF0ZSB0aGlzIGFzIGEgZGF0YSBmcmFtZSByYXRoZXIgdGhhbiBtYXRyaXgKICBhcy5kYXRhLmZyYW1lKGduZ19lcnJfYW5hbHlzaXMgJT4lIAogICAgICAgICAgICAgICAgICAjIHNlbGVjdCB2YXJpYWJsZXMgJiB0aGUgY29uZGl0aW9uIGNvbHVtbnMKICAgICAgICAgICAgICAgICAgc2VsZWN0KGMoY29uZGl0aW9uLCBjdWUsIGduZ19lcnJfb21pX2xvbmcpKSAlPiUgCiAgICAgICAgICAgICAgICAgICMgZmlsdGVyIGZvciB2ZXJ0aWNhbC9nbyBjdWUgdHlwZQogICAgICAgICAgICAgICAgICBmaWx0ZXIoY3VlID09IDEpICU+JQogICAgICAgICAgICAgICAgICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyAmIG91dHB1dCBhcyBhIG1hdHJpeCAoIm1hdCA9IFQiKQogICAgICAgICAgICAgICAgICBkZXNjcmliZUJ5KGdyb3VwID0gbGlzdChmaWx0ZXIoZ25nX2Vycl9hbmFseXNpcywgY3VlID09IDEpJGNvbmRpdGlvbiksIG1hdCA9IFQpCiAgICAgICAgICAgICAgICApCiMgZm9yIHRoZSBob3Jpem9udGFsL25vLWdvIGN1ZSB0eXBlCmRlc190YXNrX2NvbnRfY3VlX2ggPC0gCiAgIyBjcmVhdGUgdGhpcyBhcyBhIGRhdGEgZnJhbWUgcmF0aGVyIHRoYW4gbWF0cml4CiAgYXMuZGF0YS5mcmFtZShnbmdfZXJyX2FuYWx5c2lzICU+JSAKICAgICAgICAgICAgICAgICAgIyBzZWxlY3QgdmFyaWFibGVzICYgdGhlIGNvbmRpdGlvbiBjb2x1bW5zCiAgICAgICAgICAgICAgICAgIHNlbGVjdChjKGNvbmRpdGlvbiwgY3VlLCBnbmdfZXJyX29taV9sb25nKSkgJT4lIAogICAgICAgICAgICAgICAgICAjIGZpbHRlciBmb3IgaG9yaXpvbnRhbC9uby1nbyBjdWUgdHlwZQogICAgICAgICAgICAgICAgICBmaWx0ZXIoY3VlID09IDIpICU+JQogICAgICAgICAgICAgICAgICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyAmIG91dHB1dCBhcyBhIG1hdHJpeCAoIm1hdCA9IFQiKQogICAgICAgICAgICAgICAgICBkZXNjcmliZUJ5KGdyb3VwID0gbGlzdChmaWx0ZXIoZ25nX2Vycl9hbmFseXNpcywgY3VlID09IDEpJGNvbmRpdGlvbiksIG1hdCA9IFQpCiAgICAgICAgICAgICAgICApCgojIGNyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCB0aGUgZGVzY3JpcHRpdmUgc3RhdHMgb2YgYWxsIHRoZSBkYXRhLCBBQ1JPU1MgdGhlIGxvY2F0aW9uICYgcG93ZXIgY29uZGl0aW9ucwoKIyBub3QgZGl2aWRlZCBieSBjdWUgdHlwZQpkZXNfdGFza19jb250X2Fjcm9zcyA8LSAKICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyBmb3IgdmFyaWFibGVzCiAgICAjIGNyZWF0ZSB0aGlzIGFzIGEgZGF0YSBmcmFtZSByYXRoZXIgdGhhbiBtYXRyaXgKICBhcy5kYXRhLmZyYW1lKHBzeWNoOjpkZXNjcmliZShzZWxlY3QoYWxsX2RhdGFfdGFza19kZXMsIC1jb25kaXRpb24pKSkKCiMgZGl2aWRlZCBieSBjdWUgdHlwZSAtLSBmb3IgR25HIGVycm9yIGFuYWx5c2lzCiMgZm9yIHRoZSB2ZXJ0aWNhbC9nbyBjdWUgdHlwZQpkZXNfdGFza19jb250X2Fjcm9zc19jdWVfdiA8LSAKICAjIGdldCBkZXNjcmlwdGl2ZSBzdGF0cyBmb3IgdmFyaWFibGVzCiAgICAjIGNyZWF0ZSB0aGlzIGFzIGEgZGF0YSBmcmFtZSByYXRoZXIgdGhhbiBtYXRyaXgKICBhcy5kYXRhLmZyYW1lKHBzeWNoOjpkZXNjcmliZShzZWxlY3QoZmlsdGVyKGduZ19lcnJfYW5hbHlzaXMsIGN1ZSA9PSAxKSwgYyhjb25kaXRpb24sIGN1ZSwgZ25nX2Vycl9vbWlfbG9uZykpKSkKIyBmb3IgdGhlIGhvcml6b250YWwvbm8tZ28gY3VlIHR5cGUKZGVzX3Rhc2tfY29udF9hY3Jvc3NfY3VlX2ggPC0gCiAgIyBnZXQgZGVzY3JpcHRpdmUgc3RhdHMgZm9yIHZhcmlhYmxlcwogICAgIyBjcmVhdGUgdGhpcyBhcyBhIGRhdGEgZnJhbWUgcmF0aGVyIHRoYW4gbWF0cml4CiAgYXMuZGF0YS5mcmFtZShwc3ljaDo6ZGVzY3JpYmUoc2VsZWN0KGZpbHRlcihnbmdfZXJyX2FuYWx5c2lzLCBjdWUgPT0gMiksIGMoY29uZGl0aW9uLCBjdWUsIGduZ19lcnJfb21pX2xvbmcpKSkpCiAgCgojIG9yZ2FuaXplIHRoZSBkYXRhIGludG8gYSBuZXcgZGF0YSBmcmFtZSBkZXBpY3RpbmcgdGhlIE0sIFNELCBtaW4uLCBtYXguLCBhbmQgbi4KZGVzX3Rhc2tfY29udF90IDwtIAogIGFzLmRhdGEuZnJhbWUoY2JpbmQocmVwKGMoIk0iLCAiU0QiLCAibWluLiIsICJtYXguIiwgIm4iKSwgOCksIAogICAgICAgICAgICAgICAgICAgICAgcmJpbmQoYyhkZXNfdGFza19jb250W2MoIm9zcGFuX2Fic29sdXRlX3Njb3JlMSIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTIiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmUzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fYWJzb2x1dGVfc2NvcmU0IiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlNSIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl9hYnNvbHV0ZV9zY29yZTEiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmUyIiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fYWJzb2x1dGVfc2NvcmU0IiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlNSIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygib3NwYW5fYWJzb2x1dGVfc2NvcmUxIiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlMiIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9zcGFuX2Fic29sdXRlX3Njb3JlNCIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTUiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmU2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl9hYnNvbHV0ZV9zY29yZTEiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmUyIiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fYWJzb2x1dGVfc2NvcmU0IiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlNSIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoIm9zcGFuX2Fic29sdXRlX3Njb3JlMSIsICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTIiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvc3Bhbl9hYnNvbHV0ZV9zY29yZTQiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmU1IiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoIm9zcGFuX3RvdGFsX2NvcnIxIiwgIm9zcGFuX3RvdGFsX2NvcnIyIiwgIm9zcGFuX3RvdGFsX2NvcnIzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fdG90YWxfY29ycjQiLCAib3NwYW5fdG90YWxfY29ycjUiLCAib3NwYW5fdG90YWxfY29ycjYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl90b3RhbF9jb3JyMSIsICJvc3Bhbl90b3RhbF9jb3JyMiIsICJvc3Bhbl90b3RhbF9jb3JyMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fdG90YWxfY29ycjQiLCAib3NwYW5fdG90YWxfY29ycjUiLCAib3NwYW5fdG90YWxfY29ycjYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygib3NwYW5fdG90YWxfY29ycjEiLCAib3NwYW5fdG90YWxfY29ycjIiLCAib3NwYW5fdG90YWxfY29ycjMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9zcGFuX3RvdGFsX2NvcnI0IiwgIm9zcGFuX3RvdGFsX2NvcnI1IiwgIm9zcGFuX3RvdGFsX2NvcnI2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl90b3RhbF9jb3JyMSIsICJvc3Bhbl90b3RhbF9jb3JyMiIsICJvc3Bhbl90b3RhbF9jb3JyMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fdG90YWxfY29ycjQiLCAib3NwYW5fdG90YWxfY29ycjUiLCAib3NwYW5fdG90YWxfY29ycjYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoIm9zcGFuX3RvdGFsX2NvcnIxIiwgIm9zcGFuX3RvdGFsX2NvcnIyIiwgIm9zcGFuX3RvdGFsX2NvcnIzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvc3Bhbl90b3RhbF9jb3JyNCIsICJvc3Bhbl90b3RhbF9jb3JyNSIsICJvc3Bhbl90b3RhbF9jb3JyNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyMSIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjIiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnIzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnI0IiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyNSIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjEiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnIyIiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnI0IiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyNSIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygib3NwYW5fbWF0aF9wZXJjZW50X2NvcnIxIiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyMiIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyNCIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjUiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnI2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjEiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnIyIiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnI0IiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyNSIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyMSIsICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjIiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnIzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvc3Bhbl9tYXRoX3BlcmNlbnRfY29ycjQiLCAib3NwYW5fbWF0aF9wZXJjZW50X2NvcnI1IiwgIm9zcGFuX21hdGhfcGVyY2VudF9jb3JyNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19zY29yZTEiLCAiZ25nX3Njb3JlMiIsICJnbmdfc2NvcmUzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3Njb3JlNCIsICJnbmdfc2NvcmU1IiwgImduZ19zY29yZTYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfc2NvcmUxIiwgImduZ19zY29yZTIiLCAiZ25nX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3Njb3JlNCIsICJnbmdfc2NvcmU1IiwgImduZ19zY29yZTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygiZ25nX3Njb3JlMSIsICJnbmdfc2NvcmUyIiwgImduZ19zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImduZ19zY29yZTQiLCAiZ25nX3Njb3JlNSIsICJnbmdfc2NvcmU2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfc2NvcmUxIiwgImduZ19zY29yZTIiLCAiZ25nX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3Njb3JlNCIsICJnbmdfc2NvcmU1IiwgImduZ19zY29yZTYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19zY29yZTEiLCAiZ25nX3Njb3JlMiIsICJnbmdfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfc2NvcmU0IiwgImduZ19zY29yZTUiLCAiZ25nX3Njb3JlNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19lcnJfb21pMSIsICJnbmdfZXJyX29taTIiLCAiZ25nX2Vycl9vbWkzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWk0IiwgImduZ19lcnJfb21pNSIsICJnbmdfZXJyX29taTYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfZXJyX29taTEiLCAiZ25nX2Vycl9vbWkyIiwgImduZ19lcnJfb21pMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWk0IiwgImduZ19lcnJfb21pNSIsICJnbmdfZXJyX29taTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygiZ25nX2Vycl9vbWkxIiwgImduZ19lcnJfb21pMiIsICJnbmdfZXJyX29taTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImduZ19lcnJfb21pNCIsICJnbmdfZXJyX29taTUiLCAiZ25nX2Vycl9vbWk2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfZXJyX29taTEiLCAiZ25nX2Vycl9vbWkyIiwgImduZ19lcnJfb21pMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWk0IiwgImduZ19lcnJfb21pNSIsICJnbmdfZXJyX29taTYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19lcnJfb21pMSIsICJnbmdfZXJyX29taTIiLCAiZ25nX2Vycl9vbWkzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taTQiLCAiZ25nX2Vycl9vbWk1IiwgImduZ19lcnJfb21pNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250X2N1ZV92W2MoImduZ19lcnJfb21pX2xvbmcxIiwgImduZ19lcnJfb21pX2xvbmcyIiwgImduZ19lcnJfb21pX2xvbmczIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taV9sb25nNCIsICJnbmdfZXJyX29taV9sb25nNSIsICJnbmdfZXJyX29taV9sb25nNiIpLF0kbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250X2N1ZV92W2MoImduZ19lcnJfb21pX2xvbmcxIiwgImduZ19lcnJfb21pX2xvbmcyIiwgImduZ19lcnJfb21pX2xvbmczIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taV9sb25nNCIsICJnbmdfZXJyX29taV9sb25nNSIsICJnbmdfZXJyX29taV9sb25nNiIpLF0kc2QpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udF9jdWVfdltjKCJnbmdfZXJyX29taV9sb25nMSIsICJnbmdfZXJyX29taV9sb25nMiIsICJnbmdfZXJyX29taV9sb25nMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWlfbG9uZzQiLCAiZ25nX2Vycl9vbWlfbG9uZzUiLCAiZ25nX2Vycl9vbWlfbG9uZzYiKSxdJG1pbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250X2N1ZV92W2MoImduZ19lcnJfb21pX2xvbmcxIiwgImduZ19lcnJfb21pX2xvbmcyIiwgImduZ19lcnJfb21pX2xvbmczIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taV9sb25nNCIsICJnbmdfZXJyX29taV9sb25nNSIsICJnbmdfZXJyX29taV9sb25nNiIpLF0kbWF4KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRfY3VlX3ZbYygiZ25nX2Vycl9vbWlfbG9uZzEiLCAiZ25nX2Vycl9vbWlfbG9uZzIiLCAiZ25nX2Vycl9vbWlfbG9uZzMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImduZ19lcnJfb21pX2xvbmc0IiwgImduZ19lcnJfb21pX2xvbmc1IiwgImduZ19lcnJfb21pX2xvbmc2IiksXSRuKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udF9jdWVfaFtjKCJnbmdfZXJyX29taV9sb25nMSIsICJnbmdfZXJyX29taV9sb25nMiIsICJnbmdfZXJyX29taV9sb25nMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWlfbG9uZzQiLCAiZ25nX2Vycl9vbWlfbG9uZzUiLCAiZ25nX2Vycl9vbWlfbG9uZzYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udF9jdWVfaFtjKCJnbmdfZXJyX29taV9sb25nMSIsICJnbmdfZXJyX29taV9sb25nMiIsICJnbmdfZXJyX29taV9sb25nMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWlfbG9uZzQiLCAiZ25nX2Vycl9vbWlfbG9uZzUiLCAiZ25nX2Vycl9vbWlfbG9uZzYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRfY3VlX2hbYygiZ25nX2Vycl9vbWlfbG9uZzEiLCAiZ25nX2Vycl9vbWlfbG9uZzIiLCAiZ25nX2Vycl9vbWlfbG9uZzMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImduZ19lcnJfb21pX2xvbmc0IiwgImduZ19lcnJfb21pX2xvbmc1IiwgImduZ19lcnJfb21pX2xvbmc2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udF9jdWVfaFtjKCJnbmdfZXJyX29taV9sb25nMSIsICJnbmdfZXJyX29taV9sb25nMiIsICJnbmdfZXJyX29taV9sb25nMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX2Vycl9vbWlfbG9uZzQiLCAiZ25nX2Vycl9vbWlfbG9uZzUiLCAiZ25nX2Vycl9vbWlfbG9uZzYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250X2N1ZV9oW2MoImduZ19lcnJfb21pX2xvbmcxIiwgImduZ19lcnJfb21pX2xvbmcyIiwgImduZ19lcnJfb21pX2xvbmczIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfZXJyX29taV9sb25nNCIsICJnbmdfZXJyX29taV9sb25nNSIsICJnbmdfZXJyX29taV9sb25nNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19ydF9hdjEiLCAiZ25nX3J0X2F2MiIsICJnbmdfcnRfYXYzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3J0X2F2NCIsICJnbmdfcnRfYXY1IiwgImduZ19ydF9hdjYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfcnRfYXYxIiwgImduZ19ydF9hdjIiLCAiZ25nX3J0X2F2MyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3J0X2F2NCIsICJnbmdfcnRfYXY1IiwgImduZ19ydF9hdjYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRbYygiZ25nX3J0X2F2MSIsICJnbmdfcnRfYXYyIiwgImduZ19ydF9hdjMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImduZ19ydF9hdjQiLCAiZ25nX3J0X2F2NSIsICJnbmdfcnRfYXY2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3Rhc2tfY29udFtjKCJnbmdfcnRfYXYxIiwgImduZ19ydF9hdjIiLCAiZ25nX3J0X2F2MyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ25nX3J0X2F2NCIsICJnbmdfcnRfYXY1IiwgImduZ19ydF9hdjYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfdGFza19jb250W2MoImduZ19ydF9hdjEiLCAiZ25nX3J0X2F2MiIsICJnbmdfcnRfYXYzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnbmdfcnRfYXY0IiwgImduZ19ydF9hdjUiLCAiZ25nX3J0X2F2NiIpLF0kbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICBjKGRlc190YXNrX2NvbnRfYWNyb3NzWyJvc3Bhbl9hYnNvbHV0ZV9zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGVzX3Rhc2tfY29udF9hY3Jvc3NbIm9zcGFuX3RvdGFsX2NvcnIiLCBjKCJtZWFuIiwgInNkIiwgIm1pbiIsICJtYXgiLCAibiIpXSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc190YXNrX2NvbnRfYWNyb3NzWyJvc3Bhbl9tYXRoX3BlcmNlbnRfY29yciIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGVzX3Rhc2tfY29udF9hY3Jvc3NbImduZ19zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGVzX3Rhc2tfY29udF9hY3Jvc3NbImduZ19lcnJfb21pIiwgYygibWVhbiIsICJzZCIsICJtaW4iLCAibWF4IiwgIm4iKV0sIAogICAgICAgICAgICAgICAgICAgICAgICBkZXNfdGFza19jb250X2Fjcm9zc19jdWVfdlsiZ25nX2Vycl9vbWlfbG9uZyIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLAogICAgICAgICAgICAgICAgICAgICAgICBkZXNfdGFza19jb250X2Fjcm9zc19jdWVfaFsiZ25nX2Vycl9vbWlfbG9uZyIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLAogICAgICAgICAgICAgICAgICAgICAgICBkZXNfdGFza19jb250X2Fjcm9zc1siZ25nX3J0X2F2IiwgYygibWVhbiIsICJzZCIsICJtaW4iLCAibWF4IiwgIm4iKV0pCiAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiMgcmVuYW1lIGNvbHVtbnMgIApjb2xuYW1lcyhkZXNfdGFza19jb250X3QpID0gYygidmFyIiwgImRPTiIsICJwYk9OIiwgIm9PTiIsICJkT0ZGIiwgInBiT0ZGIiwgIm9PRkYiLCAib3ZlcmFsbCIpCiMgY2hhbmdlIGFsbCBjb2x1bW5zIGV4Y2VwdCAidmFyIiB0byBudW1lcmljCmRlc190YXNrX2NvbnRfdCRkT04gPC0gYXMubnVtZXJpYyhkZXNfdGFza19jb250X3QkZE9OKQpkZXNfdGFza19jb250X3QkcGJPTiA8LSBhcy5udW1lcmljKGRlc190YXNrX2NvbnRfdCRwYk9OKQpkZXNfdGFza19jb250X3Qkb09OIDwtIGFzLm51bWVyaWMoZGVzX3Rhc2tfY29udF90JG9PTikKZGVzX3Rhc2tfY29udF90JGRPRkYgPC0gYXMubnVtZXJpYyhkZXNfdGFza19jb250X3QkZE9GRikKZGVzX3Rhc2tfY29udF90JHBiT0ZGIDwtIGFzLm51bWVyaWMoZGVzX3Rhc2tfY29udF90JHBiT0ZGKQpkZXNfdGFza19jb250X3Qkb09GRiA8LSBhcy5udW1lcmljKGRlc190YXNrX2NvbnRfdCRvT0ZGKQpkZXNfdGFza19jb250X3Qkb3ZlcmFsbCA8LSBhcy5udW1lcmljKGRlc190YXNrX2NvbnRfdCRvdmVyYWxsKQojIHJlbmFtZSByb3dzCnJvd25hbWVzKGRlc190YXNrX2NvbnRfdCkgPSBjKDE6bnJvdyhkZXNfdGFza19jb250X3QpKQoKIyB3cml0ZS50YWJsZShkZXNfdGFza19jb250X3QsIi9Vc2Vycy9hbmFjZWNpbGlhcnVpenBhcmRvL0Rvd25sb2Fkcy9kZi50eHQiLHNlcD0ifCIpCiMgeCA9IHJlYWQudGFibGUoIi9Vc2Vycy9hbmFjZWNpbGlhcnVpenBhcmRvL0Rvd25sb2Fkcy9kZi50eHQiLHNlcD0ifCIpCiMgd3JpdGUuY3N2KHgsICJQYXRoL2RmLmNzdiIpCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19kZXNfdGFza19jb250X3QsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgc2hvdyB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShkZXNfdGFza19jb250X3QsIGNhcHRpb24gPSAiVGFzayBEYXRhIGJ5IENvbmRpdGlvbiBhbmQgT3ZlcmFsbDogT1NwYW4gQWJzb2x1dGUgU2NvcmUsIE9TcGFuIFRvdGFsIENvcnJlY3QsIE9TcGFuIE1hdGggUGVyY2VudGFnZSBDb3JyZWN0LCBHby9Oby1HbyBTY29yZSwgR28vTm8tR28gT21pc3Npb24gRXJyb3JzLCBHby9Oby1HbyBBdmVyYWdlIFJlYWN0aW9uIFRpbWUiLCBkaWdpdHMgPSAyLCBhbGlnbiA9IHJlcCgnYycpLCBjb2wubmFtZXMgPSBjKCIgIiwgcmVwKGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIiksMiksICJUT1RBTCIpLCByb3cubmFtZXMgPSBjKDE6bnJvdyhkZXNfdGFza19jb250X3QpKSkgJT4lIAogIGZvb3Rub3RlKGdlbmVyYWwgPSAiQ29udGludW91cyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHNob3duIGZvciBUYXNrIGRhdGEgKGkuZS4sIE9TcGFuIFRhc2sgYW5kIEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzaykuICdUT1RBTCcgY29sdW1uIHNob3dzIHN0YXRpc3RpY3MgYWNyb3NzIGFsbCBjb25kaXRpb25zLiIpICU+JSAKICBwYWNrX3Jvd3MoIk9TcGFuIFRhc2sgIiwgMSwgMTUpICU+JSAKICBwYWNrX3Jvd3MoIkFic29sdXRlIFNjb3JlIiwgMSwgNSkgJT4lIAogIHBhY2tfcm93cygiVG90YWwgU2NvcmUiLCA2LCAxMCkgJT4lIAogIHBhY2tfcm93cygiTWF0aCBDb3JyZWN0ICglKSIsIDExLCAxNSkgJT4lIAogIHBhY2tfcm93cygiIEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzayIsIDE2LCA0MCkgJT4lIAogIHBhY2tfcm93cygiVG90YWwgU2NvcmUiLCAxNiwgMjApICU+JSAKICBwYWNrX3Jvd3MoIk9taXNzaW9uIEVycm9ycyIsIDIxLCAyNSkgJT4lIAogIHBhY2tfcm93cygiT21pc3Npb24gRXJyb3JzIGZvciAnR28nIFRyaWFscyIsIDI2LCAzMCkgJT4lIAogIHBhY2tfcm93cygiT21pc3Npb24gRXJyb3JzIGZvciAnTm8tR28nIFRyaWFscyIsIDMxLCAzNSkgJT4lIAogIHBhY2tfcm93cygiQXZlcmFnZSBSZWFjdGlvbiBUaW1lIiwgMzYsIDQwKSAlPiUgCiAgIyBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiICIsICJTbWFydHBob25lIExvY2F0aW9uIiA9IDYsICIgIikpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsIiAiLCAiT04iID0gMywgIk9GRiIgPSAzLCAiICIpLCBib2xkID0gVCkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDYsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9yZGVyX2xlZnQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKIyMgUXVlc3Rpb25uYWlyZSBEYXRhCgpUaGUgZm9sbG93aW5nIHRhYmxlIGRlcGljdHMgdGhlICoqU1VRIGFuZCBTQUQgdmFyaWFibGUocykqKiBmb3IgYm90aCAqY29udGludW91cyogKGkuZS4sIFNVUSBzY29yZSBmb3Igc21hcnRwaG9uZSB1c2Ugd2l0aCBhYnNlbmNlIG9mIG90aGVyIHN0aW11bGF0aW9uLCBTVVEgc2NvcmUgZm9yIHNtYXJ0cGhvbmUgdXNlIGR1cmluZyBvdGhlciBhY3Rpb25zLCBTQUQgc2NvcmUpIGFuZCAqbm9taW5hbCogKGkuZS4sIEF2ZXJhZ2UgdGV4dCBtZXNzYWdlcyBwZXIgZGF5LCBBdmVyYWdlIHNvY2lhbCBtZWRpYSBiYXNlZCBtZXNzYWdlcyBzZW50IHBlciBkYXksIEF2ZXJhZ2Ugc29jaWFsIG1lZGlhIGJhc2VkIHBvc3RzIHBlciBkYXksIFNtYXJ0cGhvbmUgc3ViamVjdGl2ZSB2YWx1ZSwgVHlwZXMgb2Ygbm90aWZpY2F0aW9ucywgUGhhbnRvbSB2aWJyYXRpb25zKSB2YXJpYWJsZXMgZnJvbSBhbGwgcGFydGljaXBhbnRzIGluIHRoZSBwcmVzZW50IHN0dWR5ICooY2xpY2sgdG8gc2VlIGNvZGUpKi4KClRoZSAqKmNvbnRpbnVvdXMqKiBkYXRhIGluY2x1ZGVzOgoKLSAgIFNVUSBzY29yZSBmb3Igc21hcnRwaG9uZSB1c2Ugd2l0aCBhYnNlbmNlIG9mIG90aGVyIHN0aW11bGF0aW9uCgotICAgU1VRIHNjb3JlIGZvciBzbWFydHBob25lIHVzZSBkdXJpbmcgb3RoZXIgYWN0aW9ucwoKLSAgIFNBRCBzY29yZSAoaS5lLiwgYXR0YWNobWVudCBhbmQgZGVwZW5kZW5jeSB0byBvbmUncyBzbWFydHBob25lKToKCiAgICAtICAgJFNBRF97b3ZlcmFsbH0kOiBTQUQgc2NvcmUgZm9yIGFsbCAxMyBpdGVtcwoKICAgIC0gICAkU0FEX3tEZXB9JDogU0FEIHNjb3JlIGZvciB0aGUgKlNtYXJ0cGhvbmUgRGVwZW5kZW5jZSogc3Vic2NhbGUgKGl0ZW1zOiAxLCAyLCAzLCA0LCA1KQoKICAgIC0gICAkU0FEX3tFQX0kOiBTQUQgc2NvcmUgZm9yIHRoZSAqRW1vdGlvbmFsIEF0dGFjaG1lbnQqIHN1YnNjYWxlIChpdGVtczogOCwgOSwgMTAsIDExKQoKICAgIC0gICAkU0FEX3tEaXN0fSQ6IFNBRCBzY29yZSBmb3IgdGhlICpTbWFydHBob25lIERpc3RyYWN0aWJpbGl0eSogc3Vic2NhbGUgKGl0ZW1zOiA3LCAxMiwgMTMpCgogICAgICAgIDxkZXRhaWxzPgoKICAgICAgICA8c3VtbWFyeT4KCiAgICAgICAgVGhpcyBjb2RlIG9yZ2FuaXplZCB0aGUgY29udGludW91cyBkYXRhICooY2xpY2sgdG8gc2VlIGNvZGUpKi4gXDwvc3VtbWFyeSkKCiAgICBgYGB7ciBjcmVhdGVfZGVzX3F1ZXNfY29udCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KICAgICMgY3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHRoZSBkZXNjcmlwdGl2ZSBzdGF0cyBvZiBhbGwgdGhlIGRhdGEsIEdST1VQRUQgYnkgdGhlIGxvY2F0aW9uICYgcG93ZXIgY29uZGl0aW9ucwogICAgICAjIHRoaXMgY3JlYXRlcyBpbmZvcm1hdGlvbiBmb3IgdGhlIDYgcG9zc2libGUgY29tYmluZWQgY29uZGl0aW9ucwogICAgZGVzX3F1ZXNfY29udCA8LSAKICAgICAgIyBjcmVhdGUgdGhpcyBhcyBhIGRhdGEgZnJhbWUgcmF0aGVyIHRoYW4gbWF0cml4CiAgICAgIGFzLmRhdGEuZnJhbWUoYWxsX2RhdGFfcXVlc19kZXMgJT4lIAogICAgICAgICAgICAgICAgICAgICAgIyBzZWxlY3QgdmFyaWFibGVzICYgdGhlIGNvbmRpdGlvbiBjb2x1bW5zCiAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoYyhsb2NhdGlvbiwgcG93ZXIsIFNVUV9hYmV4dF9zY29yZSwgU1VRX2R1cmFjdF9zY29yZSwgU0FEX3Njb3JlLCBTQURfZGVwX3Njb3JlLCBTQURfZWFfc2NvcmUsIFNBRF9hY2Nlc3Nfc2NvcmUsIFNBRF9kaXN0X3Njb3JlKSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgIyBnZXQgZGVzY3JpcHRpdmUgc3RhdHMgJiBvdXRwdXQgYXMgYSBtYXRyaXggKCJtYXQgPSBUIikKICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaWJlQnkoZ3JvdXAgPSBsaXN0KGFsbF9kYXRhX3F1ZXNfZGVzJGxvY2F0aW9uLCBhbGxfZGF0YV9xdWVzX2RlcyRwb3dlciksIG1hdCA9IFQpCiAgICAgICAgICAgICAgICAgICAgKQoKICAgICMgY3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHRoZSBkZXNjcmlwdGl2ZSBzdGF0cyBvZiBhbGwgdGhlIGRhdGEsIEFDUk9TUyB0aGUgbG9jYXRpb24gJiBwb3dlciBjb25kaXRpb25zCiAgICBkZXNfcXVlc19jb250X2Fjcm9zcyA8LSAKICAgICAgIyBnZXQgZGVzY3JpcHRpdmUgc3RhdHMgZm9yIHZhcmlhYmxlcwogICAgICAgICMgY3JlYXRlIHRoaXMgYXMgYSBkYXRhIGZyYW1lIHJhdGhlciB0aGFuIG1hdHJpeAogICAgICBhcy5kYXRhLmZyYW1lKHBzeWNoOjpkZXNjcmliZShzZWxlY3QoYWxsX2RhdGFfcXVlc19kZXMsIGMobG9jYXRpb24sIHBvd2VyLCBTVVFfYWJleHRfc2NvcmUsIFNVUV9kdXJhY3Rfc2NvcmUsIFNBRF9zY29yZSwgU0FEX2RlcF9zY29yZSwgU0FEX2VhX3Njb3JlLCBTQURfZGlzdF9zY29yZSkpKSkKICAgICAgCiAgICAjIG9yZ2FuaXplIHRoZSBkYXRhIGludG8gYSBuZXcgZGF0YSBmcmFtZSBkZXBpY3RpbmcgdGhlIE0sIFNELCBtaW4uLCBtYXguLCBhbmQgbi4KICAgIGRlc19xdWVzX2NvbnRfdCA8LSAKICAgICAgYXMuZGF0YS5mcmFtZShjYmluZChyZXAoYygiTSIsICJTRCIsICJtaW4uIiwgIm1heC4iLCAibiIpLCAzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmJpbmQoYyhkZXNfcXVlc19jb250W2MoIlNVUV9hYmV4dF9zY29yZTEiLCAiU1VRX2FiZXh0X3Njb3JlMiIsICJTVVFfYWJleHRfc2NvcmUzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNVUV9hYmV4dF9zY29yZTQiLCAiU1VRX2FiZXh0X3Njb3JlNSIsICJTVVFfYWJleHRfc2NvcmU2IiksXSRtZWFuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNVUV9hYmV4dF9zY29yZTEiLCAiU1VRX2FiZXh0X3Njb3JlMiIsICJTVVFfYWJleHRfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1VRX2FiZXh0X3Njb3JlNCIsICJTVVFfYWJleHRfc2NvcmU1IiwgIlNVUV9hYmV4dF9zY29yZTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNVUV9hYmV4dF9zY29yZTEiLCAiU1VRX2FiZXh0X3Njb3JlMiIsICJTVVFfYWJleHRfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1VRX2FiZXh0X3Njb3JlNCIsICJTVVFfYWJleHRfc2NvcmU1IiwgIlNVUV9hYmV4dF9zY29yZTYiKSxdJG1pbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTVVFfYWJleHRfc2NvcmUxIiwgIlNVUV9hYmV4dF9zY29yZTIiLCAiU1VRX2FiZXh0X3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNVUV9hYmV4dF9zY29yZTQiLCAiU1VRX2FiZXh0X3Njb3JlNSIsICJTVVFfYWJleHRfc2NvcmU2IiksXSRtYXgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU1VRX2FiZXh0X3Njb3JlMSIsICJTVVFfYWJleHRfc2NvcmUyIiwgIlNVUV9hYmV4dF9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTVVFfYWJleHRfc2NvcmU0IiwgIlNVUV9hYmV4dF9zY29yZTUiLCAiU1VRX2FiZXh0X3Njb3JlNiIpLF0kbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTVVFfZHVyYWN0X3Njb3JlMSIsICJTVVFfZHVyYWN0X3Njb3JlMiIsICJTVVFfZHVyYWN0X3Njb3JlMyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTVVFfZHVyYWN0X3Njb3JlNCIsICJTVVFfZHVyYWN0X3Njb3JlNSIsICJTVVFfZHVyYWN0X3Njb3JlNiIpLF0kbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTVVFfZHVyYWN0X3Njb3JlMSIsICJTVVFfZHVyYWN0X3Njb3JlMiIsICJTVVFfZHVyYWN0X3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNVUV9kdXJhY3Rfc2NvcmU0IiwgIlNVUV9kdXJhY3Rfc2NvcmU1IiwgIlNVUV9kdXJhY3Rfc2NvcmU2IiksXSRzZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTVVFfZHVyYWN0X3Njb3JlMSIsICJTVVFfZHVyYWN0X3Njb3JlMiIsICJTVVFfZHVyYWN0X3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNVUV9kdXJhY3Rfc2NvcmU0IiwgIlNVUV9kdXJhY3Rfc2NvcmU1IiwgIlNVUV9kdXJhY3Rfc2NvcmU2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU1VRX2R1cmFjdF9zY29yZTEiLCAiU1VRX2R1cmFjdF9zY29yZTIiLCAiU1VRX2R1cmFjdF9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTVVFfZHVyYWN0X3Njb3JlNCIsICJTVVFfZHVyYWN0X3Njb3JlNSIsICJTVVFfZHVyYWN0X3Njb3JlNiIpLF0kbWF4KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNVUV9kdXJhY3Rfc2NvcmUxIiwgIlNVUV9kdXJhY3Rfc2NvcmUyIiwgIlNVUV9kdXJhY3Rfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1VRX2R1cmFjdF9zY29yZTQiLCAiU1VRX2R1cmFjdF9zY29yZTUiLCAiU1VRX2R1cmFjdF9zY29yZTYiKSxdJG4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfc2NvcmUxIiwgIlNBRF9zY29yZTIiLCAiU0FEX3Njb3JlMyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfc2NvcmU0IiwgIlNBRF9zY29yZTUiLCAiU0FEX3Njb3JlNiIpLF0kbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfc2NvcmUxIiwgIlNBRF9zY29yZTIiLCAiU0FEX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9zY29yZTQiLCAiU0FEX3Njb3JlNSIsICJTQURfc2NvcmU2IiksXSRzZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfc2NvcmUxIiwgIlNBRF9zY29yZTIiLCAiU0FEX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9zY29yZTQiLCAiU0FEX3Njb3JlNSIsICJTQURfc2NvcmU2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX3Njb3JlMSIsICJTQURfc2NvcmUyIiwgIlNBRF9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfc2NvcmU0IiwgIlNBRF9zY29yZTUiLCAiU0FEX3Njb3JlNiIpLF0kbWF4KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9zY29yZTEiLCAiU0FEX3Njb3JlMiIsICJTQURfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX3Njb3JlNCIsICJTQURfc2NvcmU1IiwgIlNBRF9zY29yZTYiKSxdJG4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfZGVwX3Njb3JlMSIsICJTQURfZGVwX3Njb3JlMiIsICJTQURfZGVwX3Njb3JlMyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfZGVwX3Njb3JlNCIsICJTQURfZGVwX3Njb3JlNSIsICJTQURfZGVwX3Njb3JlNiIpLF0kbWVhbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfZGVwX3Njb3JlMSIsICJTQURfZGVwX3Njb3JlMiIsICJTQURfZGVwX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9kZXBfc2NvcmU0IiwgIlNBRF9kZXBfc2NvcmU1IiwgIlNBRF9kZXBfc2NvcmU2IiksXSRzZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfZGVwX3Njb3JlMSIsICJTQURfZGVwX3Njb3JlMiIsICJTQURfZGVwX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9kZXBfc2NvcmU0IiwgIlNBRF9kZXBfc2NvcmU1IiwgIlNBRF9kZXBfc2NvcmU2IiksXSRtaW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2RlcF9zY29yZTEiLCAiU0FEX2RlcF9zY29yZTIiLCAiU0FEX2RlcF9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfZGVwX3Njb3JlNCIsICJTQURfZGVwX3Njb3JlNSIsICJTQURfZGVwX3Njb3JlNiIpLF0kbWF4KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9kZXBfc2NvcmUxIiwgIlNBRF9kZXBfc2NvcmUyIiwgIlNBRF9kZXBfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2RlcF9zY29yZTQiLCAiU0FEX2RlcF9zY29yZTUiLCAiU0FEX2RlcF9zY29yZTYiKSxdJG4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2VhX3Njb3JlMSIsICJTQURfZWFfc2NvcmUyIiwgIlNBRF9lYV9zY29yZTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2VhX3Njb3JlNCIsICJTQURfZWFfc2NvcmU1IiwgIlNBRF9lYV9zY29yZTYiKSxdJG1lYW4pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2VhX3Njb3JlMSIsICJTQURfZWFfc2NvcmUyIiwgIlNBRF9lYV9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfZWFfc2NvcmU0IiwgIlNBRF9lYV9zY29yZTUiLCAiU0FEX2VhX3Njb3JlNiIpLF0kc2QpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2VhX3Njb3JlMSIsICJTQURfZWFfc2NvcmUyIiwgIlNBRF9lYV9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfZWFfc2NvcmU0IiwgIlNBRF9lYV9zY29yZTUiLCAiU0FEX2VhX3Njb3JlNiIpLF0kbWluKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9lYV9zY29yZTEiLCAiU0FEX2VhX3Njb3JlMiIsICJTQURfZWFfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2VhX3Njb3JlNCIsICJTQURfZWFfc2NvcmU1IiwgIlNBRF9lYV9zY29yZTYiKSxdJG1heCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfZWFfc2NvcmUxIiwgIlNBRF9lYV9zY29yZTIiLCAiU0FEX2VhX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9lYV9zY29yZTQiLCAiU0FEX2VhX3Njb3JlNSIsICJTQURfZWFfc2NvcmU2IiksXSRuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9hY2Nlc3Nfc2NvcmUxIiwgIlNBRF9hY2Nlc3Nfc2NvcmUyIiwgIlNBRF9hY2Nlc3Nfc2NvcmUzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9hY2Nlc3Nfc2NvcmU0IiwgIlNBRF9hY2Nlc3Nfc2NvcmU1IiwgIlNBRF9hY2Nlc3Nfc2NvcmU2IiksXSRtZWFuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9hY2Nlc3Nfc2NvcmUxIiwgIlNBRF9hY2Nlc3Nfc2NvcmUyIiwgIlNBRF9hY2Nlc3Nfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2FjY2Vzc19zY29yZTQiLCAiU0FEX2FjY2Vzc19zY29yZTUiLCAiU0FEX2FjY2Vzc19zY29yZTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9hY2Nlc3Nfc2NvcmUxIiwgIlNBRF9hY2Nlc3Nfc2NvcmUyIiwgIlNBRF9hY2Nlc3Nfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2FjY2Vzc19zY29yZTQiLCAiU0FEX2FjY2Vzc19zY29yZTUiLCAiU0FEX2FjY2Vzc19zY29yZTYiKSxdJG1pbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfYWNjZXNzX3Njb3JlMSIsICJTQURfYWNjZXNzX3Njb3JlMiIsICJTQURfYWNjZXNzX3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9hY2Nlc3Nfc2NvcmU0IiwgIlNBRF9hY2Nlc3Nfc2NvcmU1IiwgIlNBRF9hY2Nlc3Nfc2NvcmU2IiksXSRtYXgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2FjY2Vzc19zY29yZTEiLCAiU0FEX2FjY2Vzc19zY29yZTIiLCAiU0FEX2FjY2Vzc19zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfYWNjZXNzX3Njb3JlNCIsICJTQURfYWNjZXNzX3Njb3JlNSIsICJTQURfYWNjZXNzX3Njb3JlNiIpLF0kbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9kaXN0X3Njb3JlMSIsICJTQURfZGlzdF9zY29yZTIiLCAiU0FEX2Rpc3Rfc2NvcmUzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9kaXN0X3Njb3JlNCIsICJTQURfZGlzdF9zY29yZTUiLCAiU0FEX2Rpc3Rfc2NvcmU2IiksXSRtZWFuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9kaXN0X3Njb3JlMSIsICJTQURfZGlzdF9zY29yZTIiLCAiU0FEX2Rpc3Rfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2Rpc3Rfc2NvcmU0IiwgIlNBRF9kaXN0X3Njb3JlNSIsICJTQURfZGlzdF9zY29yZTYiKSxdJHNkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXNfcXVlc19jb250W2MoIlNBRF9kaXN0X3Njb3JlMSIsICJTQURfZGlzdF9zY29yZTIiLCAiU0FEX2Rpc3Rfc2NvcmUzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FEX2Rpc3Rfc2NvcmU0IiwgIlNBRF9kaXN0X3Njb3JlNSIsICJTQURfZGlzdF9zY29yZTYiKSxdJG1pbiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udFtjKCJTQURfZGlzdF9zY29yZTEiLCAiU0FEX2Rpc3Rfc2NvcmUyIiwgIlNBRF9kaXN0X3Njb3JlMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBRF9kaXN0X3Njb3JlNCIsICJTQURfZGlzdF9zY29yZTUiLCAiU0FEX2Rpc3Rfc2NvcmU2IiksXSRtYXgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKGRlc19xdWVzX2NvbnRbYygiU0FEX2Rpc3Rfc2NvcmUxIiwgIlNBRF9kaXN0X3Njb3JlMiIsICJTQURfZGlzdF9zY29yZTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQURfZGlzdF9zY29yZTQiLCAiU0FEX2Rpc3Rfc2NvcmU1IiwgIlNBRF9kaXN0X3Njb3JlNiIpLF0kbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgIGMoZGVzX3F1ZXNfY29udF9hY3Jvc3NbIlNVUV9hYmV4dF9zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc19xdWVzX2NvbnRfYWNyb3NzWyJTVVFfZHVyYWN0X3Njb3JlIiwgYygibWVhbiIsICJzZCIsICJtaW4iLCAibWF4IiwgIm4iKV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzX3F1ZXNfY29udF9hY3Jvc3NbIlNBRF9zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc19xdWVzX2NvbnRfYWNyb3NzWyJTQURfZGVwX3Njb3JlIiwgYygibWVhbiIsICJzZCIsICJtaW4iLCAibWF4IiwgIm4iKV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzX3F1ZXNfY29udF9hY3Jvc3NbIlNBRF9lYV9zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc19xdWVzX2NvbnRfYWNyb3NzWyJTQURfZGlzdF9zY29yZSIsIGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1heCIsICJuIildCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICMgcmVuYW1lIGNvbHVtbnMgIAogICAgY29sbmFtZXMoZGVzX3F1ZXNfY29udF90KSA8LSAgYygidmFyIiwgImRPTiIsICJwYk9OIiwgIm9PTiIsICJkT0ZGIiwgInBiT0ZGIiwgIm9PRkYiLCAib3ZlcmFsbCIpCiAgICAjIGNoYW5nZSBhbGwgY29sdW1ucyBleGNlcHQgInZhciIgdG8gbnVtZXJpYwogICAgZGVzX3F1ZXNfY29udF90JGRPTiA8LSBhcy5udW1lcmljKGRlc19xdWVzX2NvbnRfdCRkT04pCiAgICBkZXNfcXVlc19jb250X3QkcGJPTiA8LSBhcy5udW1lcmljKGRlc19xdWVzX2NvbnRfdCRwYk9OKQogICAgZGVzX3F1ZXNfY29udF90JG9PTiA8LSBhcy5udW1lcmljKGRlc19xdWVzX2NvbnRfdCRvT04pCiAgICBkZXNfcXVlc19jb250X3QkZE9GRiA8LSBhcy5udW1lcmljKGRlc19xdWVzX2NvbnRfdCRkT0ZGKQogICAgZGVzX3F1ZXNfY29udF90JHBiT0ZGIDwtIGFzLm51bWVyaWMoZGVzX3F1ZXNfY29udF90JHBiT0ZGKQogICAgZGVzX3F1ZXNfY29udF90JG9PRkYgPC0gYXMubnVtZXJpYyhkZXNfcXVlc19jb250X3Qkb09GRikKICAgIGRlc19xdWVzX2NvbnRfdCRvdmVyYWxsIDwtIGFzLm51bWVyaWMoZGVzX3F1ZXNfY29udF90JG92ZXJhbGwpCiAgICAjIHJlbmFtZSByb3dzCiAgICByb3duYW1lcyhkZXNfcXVlc19jb250X3QpID0gYygxOm5yb3coZGVzX3F1ZXNfY29udF90KSkKICAgIGBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19kZXNfcXVlc19jb250X3QsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgc2hvdyB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShkZXNfcXVlc19jb250X3QsIGNhcHRpb24gPSAiUXVlc3Rpb25uYWlyZSBEYXRhIGJ5IENvbmRpdGlvbiBhbmQgT3ZlcmFsbDogQ29udGludW91cyBWYXJpYWJsZXMiLCBkaWdpdHMgPSAyLCBhbGlnbiA9IHJlcCgnYycpLCBjb2wubmFtZXMgPSBjKCIgIiwgcmVwKGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIiksMiksICJUT1RBTCIpLCByb3cubmFtZXMgPSBjKDE6bnJvdyhkZXNfcXVlc19jb250X3QpKSkgJT4lIAogIGZvb3Rub3RlKGdlbmVyYWwgPSAiQ29udGludW91cyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHNob3duIGZvciBRdWVzdGlvbm5haXJlIGRhdGEgKGkuZS4sIFNVUSBzY29yZSBmb3Igc21hcnRwaG9uZSB1c2Ugd2l0aCBhYnNlbmNlIG9mIG90aGVyIHN0aW11bGF0aW9uLCBTVVEgc2NvcmUgZm9yIHNtYXJ0cGhvbmUgdXNlIGR1cmluZyBvdGhlciBhY3Rpb25zLCBTQUQgc2NvcmUpLiAnVE9UQUwnIGNvbHVtbiBzaG93cyBzdGF0aXN0aWNzIGFjcm9zcyBhbGwgY29uZGl0aW9ucy4iKSAlPiUgCiAgcGFja19yb3dzKCJTbWFydHBob25lIFVzYWdlIFF1ZXN0aW9ubmFpcmUgKFNVUSkiLCAxLCAxMCkgJT4lIAogIHBhY2tfcm93cygiVGVuZGVuY3kgdG8gdXNlIG9uZSdzIHNtYXJ0cGhvbmUgaW4gdGhlIGFic2NlbmNlIG9mIG90aGVyIHN0aW11bGF0aW9uIiwgMSwgNSkgJT4lIAogIHBhY2tfcm93cygiVGVuZGVuY3kgdG8gdXNlIG9uZSdzIHNtYXJ0cGhvbmUgaW4gdGhlIGR1cmluZyBvdGhlciBhY3Rpb25zIiwgNiwgMTApICU+JSAKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgQXR0YWNobWVudCBhbmQgRGVwZW5kZW5jeSBJbnZlbnRvcnkgKFNBRCkiLCAxMSwgMzUpICU+JSAKICBwYWNrX3Jvd3MoIk92ZXJhbGw6IEl0ZW1zICMxLTEzIiwgMTEsIDE1KSAlPiUgCiAgcGFja19yb3dzKCJTbWFydHBob25lIERlcGVuZGVuY2U6IEl0ZW1zICMxLTMiLCAxNiwgMjApICU+JSAKICBwYWNrX3Jvd3MoIkVtb3Rpb25hbCBBdHRhY2htZW50OiBJdGVtcyAjOC0xMSIsIDIxLCAyNSkgJT4lIAogIHBhY2tfcm93cygiQWNjZXNzaWJpbGl0eTogSXRlbXMgIzUsIDYsIDciLCAyNiwgMzApICU+JSAKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgRGlzdHJhY3RhYmlsaXR5OiBJdGVtcyAjMTIsIDEzIiwgMzEsIDM1KSAlPiUgCiAgIyBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiICIsICJTbWFydHBob25lIExvY2F0aW9uIiA9IDYsICIgIikpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsIiAiLCAiT04iID0gMywgIk9GRiIgPSAzLCAiICIpLCBib2xkID0gVCkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDYsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9yZGVyX2xlZnQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKXApUaGUgKipub21pbmFsKiogZGF0YSBpbmNsdWRlczoKCi0gICBBdmVyYWdlIHRleHQgbWVzc2FnZXMgcGVyIGRheQotICAgQXZlcmFnZSBzb2NpYWwgbWVkaWEgYmFzZWQgbWVzc2FnZXMgc2VudCBwZXIgZGF5Ci0gICBBdmVyYWdlIHNvY2lhbCBtZWRpYSBiYXNlZCBwb3N0cyBwZXIgZGF5Ci0gICBTbWFydHBob25lIHN1YmplY3RpdmUgdmFsdWUKLSAgIFR5cGVzIG9mIG5vdGlmaWNhdGlvbnMKLSAgIFBoYW50b20gdmlicmF0aW9ucwoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoaXMgY29kZSBvcmdhbml6ZWQgdGhlIG5vbWluYWwgZGF0YSAqKGNsaWNrIHRvIHNlZSBjb2RlKSouIFw8L3N1bW1hcnkpCgpgYGB7ciBjcmVhdGVfZGVzX3F1ZXNfbm9tLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojbm9tIChTVVEgdXNlMSwgU1VRIHVzZTIsIFNVUSB1c2UzLCBTVVEgZXhwMSwgU1VRIGV4cDIsIFNVUSBleHA0KQojIGNyZWF0ZSBjb3VudHMgZm9yIGVhY2ggbm9taW5hbCB2YXJpYWJsZSBkaXZpZGVkIGJ5IGNvbmRpdGlvbgogICMgZGV0YWlscyBzaG93biBmb3IgZmlyc3QgdmFyaWFibGUgb25seSBkZXNfbm9tCmRlc19xdWVzX25vbV90ZXh0IDwtIAogIGFsbF9kYXRhX3F1ZXNfZGVzICU+JSAKICAjIHNlbGVjdCBvbmx5IHRoZSB2YXJpYWJsZXMgb2YgaW50ZXJlc3Q6IGNvbmRpdGlvbiAmIFNVUV91c2VfMQogIHNlbGVjdChjb25kaXRpb24sIFNVUV91c2VfMSkgJT4lCiAgIyBkaXZpZGUgYnkgdGhlIGNvbmRpdGlvbiB0eXBlIChpLmUuLCBtaXggb2Ygc21hcnRwaG9uZSBwb3dlciBhbmQgbG9jYXRpb24pCiAgZ3JvdXBfYnkoY29uZGl0aW9uLCBTVVFfdXNlXzEpICU+JSAKICAjIGNvdW50IHRoZSBmcmVxdWVuY2llcyBmb3IgU1VRX3VzZV8xCiAgZHBseXI6OmNvdW50KCkgJT4lIAogICMgdHJhbnNwb3NlIHRoZSB0YWJsZQogIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSAKICAjIHJlbmFtZSB0aGUgY29sdW1uIHRvIGpvaW4gbGF0ZXIKICBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gU1VRX3VzZV8xKSAlPiUgCiAgIyBmb3IgZWFjaCByb3cuLi4KICByb3d3aXNlKCkgJT4lIAogICMgYWRkIHN1bSBjb2x1bW4gYWNyb3NzIGNvbmRpdGlvbnMKICBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGNfYWNyb3NzKGAxYDpgNmApLCBuYS5ybSA9IFQpKQogIAogICBhbGxfZGF0YV90ZW1wICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoU0FEX3Njb3JlID0gc3VtKGNfYWNyb3NzKFNBRF8xOlNBRF8xMykpKQoKZGVzX3F1ZXNfbm9tX21lc3NhZ2UgPC0gYWxsX2RhdGFfcXVlc19kZXMgJT4lIHNlbGVjdChjb25kaXRpb24sIFNVUV91c2VfMikgJT4lIGdyb3VwX2J5KGNvbmRpdGlvbiwgU1VRX3VzZV8yKSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gU1VRX3VzZV8yKSAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGAxYCwgYDJgLCBgM2AsIGA0YCwgYDVgLCBgNmAsIG5hLnJtID0gVCkpCgpkZXNfcXVlc19ub21fcG9zdCA8LSBhbGxfZGF0YV9xdWVzX2RlcyAlPiUgc2VsZWN0KGNvbmRpdGlvbiwgU1VRX3VzZV8zKSAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uLCBTVVFfdXNlXzMpICU+JSBkcGx5cjo6Y291bnQoKSAlPiUgc3ByZWFkKGNvbmRpdGlvbiwgbikgJT4lIGRwbHlyOjpyZW5hbWUoVmFyaWFibGUgPSBTVVFfdXNlXzMpICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYDFgLCBgMmAsIGAzYCwgYDRgLCBgNWAsIGA2YCwgbmEucm0gPSBUKSkKCmRlc19xdWVzX25vbV92YWx1ZSA8LSBhbGxfZGF0YV9xdWVzX2RlcyAlPiUgc2VsZWN0KGNvbmRpdGlvbiwgU1VRX2V4cF8xKSAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uLCBTVVFfZXhwXzEpICU+JSBkcGx5cjo6Y291bnQoKSAlPiUgc3ByZWFkKGNvbmRpdGlvbiwgbikgJT4lIGRwbHlyOjpyZW5hbWUoVmFyaWFibGUgPSBTVVFfZXhwXzEpICU+JSByb3d3aXNlKCkgJT4lIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYDFgLCBgMmAsIGAzYCwgYDRgLCBgNWAsIGA2YCwgbmEucm0gPSBUKSkKCmRlc19ub21fbm90ZSA8LSAKICBhbGxfZGF0YV9xdWVzX2RlcyAlPiUKICBzZWxlY3QoY29uZGl0aW9uLCBTVVFfZXhwXzIpICU+JSAKICAjIHNwbGl0IHVwIG11bHRpcGxlIHNlbGVjdGlvbnMgZm9yIGVhY2ggcGFydGljaXBhbnQgdG8gY291bnQgb3ZlciBhbGwgLS0gbm90aWZpY2F0aW9uIHR5cGVzCiAgc2VwYXJhdGVfcm93cyhTVVFfZXhwXzIpICU+JQogIGdyb3VwX2J5KGNvbmRpdGlvbiwgU1VRX2V4cF8yKSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSAKICBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gU1VRX2V4cF8yKSAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGAxYCwgYDJgLCBgM2AsIGA0YCwgYDVgLCBgNmAsIG5hLnJtID0gVCkpICU+JSAKICBkcGx5cjo6bXV0YXRlKFZhcmlhYmxlID0gZmFjdG9yKFZhcmlhYmxlLCBsZXZlbHMgPSBjKDE6NyksIGxhYmVscyA9IGMoIkVtYWlsIiwgIkZhY2Vib29rIiwgIlR3aXR0ZXIiLCAiSW5zdGFncmFtIiwgIkxpbmtlZEluIiwgIlNuYXBjaGF0IiwgIk90aGVyIikpKQoKZGVzX3F1ZXNfbm9tX3BoYW50b20gPC0gYWxsX2RhdGFfcXVlc19kZXMgJT4lIHNlbGVjdChjb25kaXRpb24sIFNVUV9leHBfNCkgJT4lIGdyb3VwX2J5KGNvbmRpdGlvbiwgU1VRX2V4cF80KSAlPiUgZHBseXI6OmNvdW50KCkgJT4lIHNwcmVhZChjb25kaXRpb24sIG4pICU+JSBkcGx5cjo6cmVuYW1lKFZhcmlhYmxlID0gU1VRX2V4cF80KSAlPiUgcm93d2lzZSgpICU+JSBkcGx5cjo6bXV0YXRlKFRvdGFsID0gc3VtKGAxYCwgYDJgLCBgM2AsIGA0YCwgYDVgLCBgNmAsIG5hLnJtID0gVCkpICU+JSBtdXRhdGUoVmFyaWFibGUgPSBmYWN0b3IoVmFyaWFibGUsIGxldmVscyA9IGMoMToyKSwgbGFiZWxzID0gYygiRXhwZXJpZW5jZWQiLCAiTm90IEV4cGVyaWVuY2VkIikpKQoKZGVzX3F1ZXNfbm9tX3RvdCA8LSBiaW5kX2NvbHModGliYmxlKFZhcmlhYmxlID0gIm4iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBhbGxfZGF0YV9xdWVzX2RlcyAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uKSAlPiUgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKSAlPiUgc3ByZWFkKGNvbmRpdGlvbiwgbikgJT4lIHJvd3dpc2UoKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoVG90YWwgPSBzdW0oYDFgLCBgMmAsIGAzYCwgYDRgLCBgNWAsIGA2YCwgbmEucm0gPSBUKSkKICAgICAgICAgICAgICAgICAgICAgICAgICkKCiMgYmluZCBhbGwgdmFyaWFibGVzIGludG8gb25lIGRhdGEgZnJhbWUgLS0gImRlc19xdWVzX25vbSIKZGVzX3F1ZXNfbm9tIDwtIAogIHJiaW5kKGRlc19xdWVzX25vbV90b3QsIGRlc19xdWVzX25vbV90ZXh0LCBkZXNfcXVlc19ub21fbWVzc2FnZSwgZGVzX3F1ZXNfbm9tX3Bvc3QsIGRlc19xdWVzX25vbV92YWx1ZSwgZGVzX25vbV9ub3RlLCBkZXNfcXVlc19ub21fcGhhbnRvbSkKCmNvbG5hbWVzKGRlc19xdWVzX25vbSkgPC0gYygidmFyIiwgImRPTiIsICJwYk9OIiwgIm9PTiIsICJkT0ZGIiwgInBiT0ZGIiwgIm9PRkYiLCAib3ZlcmFsbCIpCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19kZXNfcXVlc19ub20sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgc2hvdyB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShkZXNfcXVlc19ub20sIGNhcHRpb24gPSAiUXVlc3Rpb25uYWlyZSBEYXRhIGJ5IENvbmRpdGlvbiBhbmQgT3ZlcmFsbDogTm9taW5hbCBWYXJpYWJsZXMiLCBkaWdpdHMgPSAyLCBhbGlnbiA9IHJlcCgnYycpLCBjb2wubmFtZXMgPSBjKCIgIiwgcmVwKGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIiksMiksICJUT1RBTCIpLCByb3cubmFtZXMgPSBjKDE6bnJvdyhkZXNfcXVlc19ub20pKSkgJT4lIAogIGZvb3Rub3RlKGdlbmVyYWwgPSAiQ29udGludW91cyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHNob3duIGZvciBRdWVzdGlvbm5haXJlIGRhdGEgKGkuZS4sIFNhbXBsZSBzaXplLCBBdmVyYWdlIHRleHQgbWVzc2FnZXMgcGVyIGRheSwgQXZlcmFnZSBzb2NpYWwgbWVkaWEgYmFzZWQgbWVzc2FnZXMgc2VudCBwZXIgZGF5LCBBdmVyYWdlIHNvY2lhbCBtZWRpYSBiYXNlZCBwb3N0cyBwZXIgZGF5LCBTbWFydHBob25lIHN1YmplY3RpdmUgdmFsdWUsIFR5cGVzIG9mIG5vdGlmaWNhdGlvbnMsIFBoYW50b20gdmlicmF0aW9ucykuICdUT1RBTCcgY29sdW1uIHNob3dzIHN0YXRpc3RpY3MgYWNyb3NzIGFsbCBjb25kaXRpb25zLiIsIAogICAgICAgICAgIHN5bWJvbCA9IGMoIkVhY2ggcGFydGljaXBhbnQgY291bGQgY2hvb3NlIG11bHRpcGxlIHR5cGVzIG9mIG5vdGlmaWNhdGlvbnMuIikpICU+JSAKICBwYWNrX3Jvd3MoIlNhbXBsZSBTaXplIiwgMSwgMSkgJT4lIAogIHBhY2tfcm93cygiU21hcnRwaG9uZSBVc2FnZSBRdWVzdGlvbm5haXJlIChTVVEpIiwgMiwgMjYpICU+JSAKICBwYWNrX3Jvd3MoIkF2ZXJhZ2UgVGV4dCBNZXNzYWdlcyBwZXIgRGF5IiwgMiwgNSkgJT4lIAogIHBhY2tfcm93cygiQXZlcmFnZSBTb2NpYWwgTWVkaWEgQmFzZWQgTWVzc2FnZXMgU2VudCBwZXIgRGF5IiwgNiwgOSkgJT4lIAogIHBhY2tfcm93cygiQXZlcmFnZSBTb2NpYWwgTWVkaWEgQmFzZWQgUG9zdHMgcGVyIERheSIsIDEwLCAxMykgJT4lIAogIHBhY2tfcm93cygiU21hcnRwaG9uZSBTdWJqZWN0aXZlIFZhbHVlIiwgMTQsIDE3KSAlPiUgCiAgcGFja19yb3dzKCJUeXBlcyBvZiBOb3RpZmljYXRpb25zKiIsIDE4LCAyNCkgJT4lIAogIHBhY2tfcm93cygiUGhhbnRvbSBWaWJyYXRpb25zIiwgMjUsIDI2KSAlPiUgCiAgIyBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiICIsICJTbWFydHBob25lIExvY2F0aW9uIiA9IDYsICIgIikpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsIiAiLCAiT04iID0gMywgIk9GRiIgPSAzLCAiICIpLCBib2xkID0gVCkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDYsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9yZGVyX2xlZnQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKIyBQbGFubmVkIEFuYWx5c2VzCgpUaGUgZm9sbG93aW5nIGFuYWx5c2VzIHdlcmUgY29tcGxldGVkIGJhc2VkIG9uIGEgcHJlLXJlZ2lzdGVyZWQgZGlyZWN0IHJlcGxpY2F0aW9uIG9uIE9TRiAodmlldyByZWdpc3RyYXRpb246IDxodHRwczovL29zZi5pby91YnlzNy8/dmlld19vbmx5PTVkYjc2YmJhMzgxYTRkYzRhYWMxMzBmN2NkM2EwZGU1Pikgb2YgV2FyZCBldCBhbC4ncyAoMjAxNykgc2Vjb25kIGV4cGVyaW1lbnQuIFRoZSBhbmFseXNlcyB0ZXN0ZWQgdGhlIHRocmVlIG1haW4gaHlwb3RoZXNlcyBpbiB0aGUgcHJlc2VudCBzdHVkeTogKDEpIHRoZSBsb2NhdGlvbiBlZmZlY3QgaHlwb3RoZXNpcywgKDIpIHRoZSBwb3dlciBlZmZlY3QgaHlwb3RoZXNpcywgYW5kICgzKSB0aGUgbW9kZXJhdGlvbiBlZmZlY3QgaHlwb3RoZXNpcy4KCkVhY2ggYW5hbHlzaXMgY29udGFpbnMgdGhlIGZvbGxvd2luZzoKCmEuICBBbmFseXNpcyAqKGluY2x1ZGluZyBhbnkgcmVsZXZhbnQgYXNzdW1wdGlvbiB0ZXN0cykqCmIuICBWaXN1YWxpemF0aW9ucwoKKk5vdGU6IERlc2NyaXB0aXZlIHN0YXRpc3RpY3MgYXJlIHNob3duIGluIHRoZSBbRGVzY3JpcHRpdmUgU3RhdGlzdGljcyBzZWN0aW9uXSgjRFMpKgoKIyMgMS4gJiAyLiBUZXN0aW5nIHRoZSBMb2NhdGlvbiBhbmQgUG93ZXIgSHlwb3RoZXNlczoKCiMjIyBPU3BhbiBUYXNrCgpBICoqMyhzbWFydHBob25lIGxvY2F0aW9uOiBkZXNrLCBwb2NrZXQvYmFnLCBvdXRzaWRlKSB4IDIoc21hcnRwaG9uZSBwb3dlcjogT04sIE9GRikqKiBiZXR3ZWVuLXN1YmplY3RzIEFOT1ZBIHdhcyBjb25kdWN0ZWQgKihEViA9IE9TcGFuIGFic29sdXRlIHNjb3JlKSouCgpQcmlvciB0byBjb21wbGV0aW5nIHRoZSBhbmFseXNpcywgcGxhbm5lZCBleGNsdXNpb24gY3JpdGVyaWEgd2FzIGFwcGxpZWQgdG8gdGhlIGRhdGEuIEV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhpcyBhbmFseXNpcyBoZWxwZWQgdG8gY29udHJvbCBmb3IgYW55IHBhcnRpY2lwYW50cyB3aG8gZGlkIG5vdCBmb2xsb3cgdGhlIGluc3RydWN0aW9ucy4gU3BlY2lmaWNhbGx5LCBvbmx5IHBhcnRpY2lwYW50cyB3aG8gcGF5ZWQgYXR0ZW50aW9uIHRvIGJvdGggdGhlIG1hdGggY29tcG9uZW50IGFuZCBsZXR0ZXIgcmVjYWxsIGNvbXBvbmVudCBvZiB0aGUgdGFzayB3ZXJlIGluY2x1ZGVkLiBPbmx5IGRhdGEgZnJvbSB0aG9zZSB3aG8gc2NvcmVkIDg1JSBvciBoaWdoZXIgb24gdGhlIG1hdGggY29tcG9uZW50IG9mIHRoZSB0YXNrIHdlcmUgaW5jbHVkZWQuIFZpZXcgdGhlIFtEYXRhIENsZWFuaW5nIHNlY3Rpb25dKCNhbGxfZGF0YV9EQykgdW5kZXIgdGhlIGRhdGEgW0NvbnN0cnVjdCBXb3JraW5nIERhdGFmcmFtZXNdKCNtYWtlREZzKSBoZWFkaW5nIGFib3ZlLiBUaGVyZSB3YXMgYSB0b3RhbCBvZiBgciBucm93KG9zcGFuX2FuYWx5c2lzKWAgcGFydGljaXBhbnRzIGluIHRoZSBPU3BhbiBhbmFseXNpcy4KCiMjIyMgQW5hbHlzaXMKClRvIGFzc2VzcyBpZiBPU3BhbiBhYnNvbHV0ZSBzY29yZSBzdGF0aXN0aWNhbGx5IGRpZmZlcmVkLCB3ZSBjb25kdWN0ZWQgYSAzeDIgQU5PVkEgd2l0aCB0aGUgYmV0d2Vlbi1zdWJqZWN0cyBmYWN0b3JzIG9mIHNtYXJ0cGhvbmUgbG9jYXRpb24gKGkuZS4sIG9uIGRlc2ssIGluIHBvY2tldC9iYWcsIG9yIG91dHNpZGUpIGFuZCBwb3dlciAoaS5lLiwgb24gb3Igb2ZmKS4gU2luY2UgdGhlcmUgYXJlIHVuZXF1YWwgc2FtcGxlIHNpemVzLCB3ZSB1c2VkIFR5cGUgSUlJIHN1bSBvZiBzcXVhcmVzLgoKIyMjIyMgQXNzdW1wdGlvbnMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgQU5PVkEgbWFkZSB0aHJlZSBhc3N1bXB0aW9uczogaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsaW5nLCBub3JtYWxpdHksIGFuZCBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZS4gQWxsIGFzc3VtcHRpb25zIHdlcmUgbWV0ICooY2xpY2sgdG8gc2VlIGRldGFpbHMpKi4KCjwvc3VtbWFyeT4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpbMS4gSW5kZXBlbmRlbnQgUmFuZG9tIFNhbXBsaW5nXXtzdHlsZT0iY29sb3I6IzRGMjY4MzsgZm9udC1zaXplOjE4cHg7In0KClRoaXMgYXNzdW1wdGlvbiB3YXMgbWV0IGR1cmluZyB0ZXN0aW5nLgoKWzIuIE5vcm1hbGl0eV17c3R5bGU9ImNvbG9yOiM0RjI2ODM7IGZvbnQtc2l6ZToxOHB4OyJ9CgpUaGlzIGFzc3VtcHRpb24gd2FzIHRlc3RlZCBieSB2aXN1YWxpemluZyB0aGUgcmVzaWR1YWxzLCBhcHBseWluZyBhIFNoYXBpcm8tV2lsayB0ZXN0IHRvIHRoZSByZXNpZHVhbHMsIGFuZCBvYnNlcnZpbmcgdGhlIFNrZXduZXNzIGFuZCBLdXJ0b3NpcyBvZiB0aGUgZGF0YSAqKGV4dHJhY3RlZCBmcm9tIHRoZSBBTk9WQSBvdXRwdXQ7IGNsaWNrIHRvIHNlZSBjb2RlKSouCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfb3NwYW5fYW5vdmEmcmVzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBnZXQgdGhlIHJlcXVpcmVkIGRhdGEgZnJvbSB0aGUgb3NwYW5fYW5hbHlzaXMgZGF0YTogcGFydGljaXBhbnQsIGxvY2F0aW9uLCBwb3dlciwgYW5kIHNjb3JlCm9zcGFuX2Fub3ZhX2RhdGEgPSBvc3Bhbl9hbmFseXNpc1ssIGMoInBhcnRpY2lwYW50IiwgImxvY2F0aW9uIiwgInBvd2VyIiwgIm9zcGFuX2Fic29sdXRlX3Njb3JlIildCiAgICBjb2xuYW1lcyhvc3Bhbl9hbm92YV9kYXRhKSA9IGMoInBhcnRpY2lwYW50IiwgImxvY2F0aW9uIiwgInBvd2VyIiwgInNjb3JlIikKICAgIHJvd25hbWVzKG9zcGFuX2Fub3ZhX2RhdGEpID0gTlVMTAogICAgIyByZWZvcm1hdCBsb2NhdGlvbiwgIHBvd2VyLCBhbmQgYmFsYW5jZSBhcyBmYWN0b3JzICAKICAgIG9zcGFuX2Fub3ZhX2RhdGEkbG9jYXRpb24gPSBmYWN0b3Iob3NwYW5fYW5vdmFfZGF0YSRsb2NhdGlvbiwgCiAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMSwgMiwgMyksCiAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk9uIERlc2siLCAiUG9ja2V0L0JhZyIsICJPdXRzaWRlIikpCiAgICBvc3Bhbl9hbm92YV9kYXRhJHBvd2VyID0gZmFjdG9yKG9zcGFuX2Fub3ZhX2RhdGEkcG93ZXIsIAogICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDEsIDIpLAogICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJPTiIsICJPRkYiKSkKCiMgcnVuIGJldHdlZW4tc3ViamVjdHMgQU5PVkEgKElWOiBTbWFydHBob25lIFBvd2VyICYgTG9jYXRpb24sIEJhbGFuY2U7IERWOiBPU3BhbiBBYm9sdXRlIFNjb3JlKQpvc3Bhbl9hbm92YSA9IGV6QU5PVkEoCiAgZGF0YSA9IG9zcGFuX2Fub3ZhX2RhdGEKICAsIGR2ID0gLihzY29yZSkKICAsIHdpZCA9IC4ocGFydGljaXBhbnQpCiAgLCBiZXR3ZWVuID0gLihsb2NhdGlvbiwgcG93ZXIpCiAgLCB0eXBlID0gMyAjIHVuZXF1YWwgc2FtcGxlIHNpemVzLCB0aGVyZm9yZSB1c2UgdHlwZSAzCiAgLCBkZXRhaWxlZCA9IFRSVUUKICAsIHJldHVybl9hb3YgPSBUUlVFCikKCiMgY2FsY3VsYXRlICYgZXh0cmFjdCB0aGUgcmVzaWR1YWxzIGZyb20gdGhlIEFOT1ZBCm9zcGFuX3JlcyA9IGRhdGEuZnJhbWUoInJlc2lkdWFscyIgPSBwcm9qKG9zcGFuX2Fub3ZhJGFvdilbLCJSZXNpZHVhbHMiXSkgICAKCmBgYAoKPC9kZXRhaWxzPgoKLSAgIEl0IGFwcGVhcnMgdGhhdCB0aGUgcmVzaWR1YWxzIGxpZSBjbG9zZWx5IHRvIGEgc3RyYWlnaHQgbGluZSwgd2hpY2ggc3VnZ2VzdHMgbm9ybWFsaXR5ICooc2VlIHZpc3VhbGl6YXRpb24gYmVsb3cpKi4KCmBgYHtyIHNob3dfb3NwYW5fcXEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpxcW5vcm0ob3NwYW5fcmVzJHJlc2lkdWFscywgbWFpbiA9ICJRLVEgUGxvdCBvZiB0aGUgT1NwYW4gUmVzaWR1YWxzIikgCnFxbGluZShvc3Bhbl9yZXMkcmVzaWR1YWxzKQoKYGBgCgotICAgSXQgYXBwZWFycyB0aGF0IHJlc2lkdWFscyB0ZW5kIHRvIGZvbGxvdyB0aGUgc2hhcGUgb2YgYSBub3JtYWwgZGlzdHJpYnV0aW9uLCB3aXRoIGEgc2xpZ2h0IHNrZXcgdG8gdGhlIHJpZ2h0ICooc2VlIHZpc3VhbGl6YXRpb24gYmVsb3cpKi4KCmBgYHtyIHNob3dfb3NwYW5fcmVzX3Bsb3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpxcGxvdChvc3Bhbl9yZXMkcmVzaWR1YWxzLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBPc3BhbiBSZXNpZHVhbHMiLCBiaW53aWR0aCA9IDUpICsgCiAgdGhlbWVfY2xhc3NpYygpCgpgYGAKCi0gICBUaGUgU2hhcGlyby1XaWxrIHRlc3Qgb2Ygbm9ybWFsaXR5IHdhcyBzaWduaWZpY2FudCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSwgKlcqID0gYHIgcm91bmQoYXMubnVtZXJpYyhvc3Bhbl9zaGFwJHN0YXRpc3RpY1siVyJdKSwgMilgLCAqcCogYHIgcF9yb3VuZChvc3Bhbl9zaGFwJHAudmFsdWUpYCAqKHNlZSBjb2RlIGJlbG93KSouCgpgYGB7ciBjcmVhdGUmc2hvd19zaGFwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKb3NwYW5fc2hhcCA9IHNoYXBpcm8udGVzdChvc3Bhbl9yZXMkcmVzaWR1YWxzKQpvc3Bhbl9zaGFwCgpgYGAKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgotICAgVGhlIFNrZXduZXNzIGFuZCBLdXJ0b3NpcyB3ZXJlIGV4YW1pbmVkIGFuZCBzaG93ZWQgdGhhdCBib3RoIHRoZSBTa2V3bmVzcyAocmFuZ2U6IGByIHJvdW5kKG1pbihhcy5udW1lcmljKG9zcGFuX3NrX3RbYygxLDQpLF0pKSwgMilgIHRvIGByIHJvdW5kKG1heChhcy5udW1lcmljKG9zcGFuX3NrX3RbYygxLDQpLF0pKSwgMilgKSBhbmQgS3VydG9zaXMgKHJhbmdlOiBgciByb3VuZChtaW4oYXMubnVtZXJpYyhvc3Bhbl9za190W2MoMiw1KSxdKSksIDIpYCB0byBgciByb3VuZChtYXgoYXMubnVtZXJpYyhvc3Bhbl9za190W2MoMiw1KSxdKSksIDIpYCkgd2VyZSB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2Ugb2YgJFxwbSAyLjAkIGFuZCAkXHBtIDkuMCQsIHJlc3BlY3RpdmVseSAoU2NobWlkZXIsIFppZWdsZXIsIERhbmF5LCBCZXllciwgJiBCw7xobmVyLCAyMDEwKSAqKHNlZSB0YWJsZSBiZWxvdzsgY2xpY2sgdG8gc2VlIGNvZGUpKi4KCiAgICA8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfb3NwYW5fc2tfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyB1c2UgdGhlICJvc3Bhbl9kZXMiIGRhdGEgZnJhbWUgZnJvbSB0aGUgZGVzY3JpcHRpdmUgc3RhdHMKCiMgb3JnYW5pemUgdGhlIGRhdGEgaW50byBhIG5ldyBkYXRhIGZyYW1lIGRlcGljdGluZyB0aGUgU2tldywga3VydG9zaXMsIGFuZCBzYW1wbGUgc2l6ZSAobikuCiAgb3NwYW5fc2tfdCA9IHJiaW5kKChjYmluZCh0KGRlc190YXNrX2NvbnRbIm9zcGFuX2Fic29sdXRlX3Njb3JlMSIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdChkZXNfdGFza19jb250WyJvc3Bhbl9hYnNvbHV0ZV9zY29yZTIiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udFsib3NwYW5fYWJzb2x1dGVfc2NvcmUzIiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSkpLCAKICAgICAgICAgICAgICAgICAgICAgIChjYmluZCh0KGRlc190YXNrX2NvbnRbIm9zcGFuX2Fic29sdXRlX3Njb3JlNCIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdChkZXNfdGFza19jb250WyJvc3Bhbl9hYnNvbHV0ZV9zY29yZTUiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udFsib3NwYW5fYWJzb2x1dGVfc2NvcmU2IiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSkpKQogICAgY29sbmFtZXMob3NwYW5fc2tfdCkgPSBjKCJPbiBEZXNrIiwgIkluIFBvY2tldC9CYWciLCAiT3V0c2lkZSIpCiAgICByb3duYW1lcyhvc3Bhbl9za190KSA9IHJlcChjKCJTa2V3bmVzcyIsICJLdXJ0b3NpcyIsICJuIiksIDIpCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19vc3Bhbl9za190LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIHVzZSBrYWJsZSB0byBzaG93IHRoZSBkZXNjcmlwdGl2ZSB0YWJsZQogIGthYmxlKG9zcGFuX3NrX3QsIGNhcHRpb24gPSAiU2tld25lc3MgYW5kIEt1cnRvc2lzIG9mIHRoZSBBYnNvbHV0ZSBTY29yZSBvbiB0aGUgT1NwYW4gVGFzayIsIGRpZ2l0cyA9IDIsIGFsaWduID0gJ2MnKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiU21hcnRwaG9uZSBMb2NhdGlvbiIgPSAzKSwgYm9sZCA9IFQpICU+JQogIHBhY2tfcm93cygiU21hcnRwaG9uZSBQb3dlciBPTiIsIDEsIDMpICU+JSAKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgUG93ZXIgT0ZGIiwgNCwgNikgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKLSAgIFRoZXJlZm9yZSwgYmFzZWQgb24gYWxsIHRoZSBub3JtYWxpdHkgYXNzdW1wdGlvbiBjaGVja3MsIG5vcm1hbGl0eSB3YXMgYXNzdW1lZCB0byBiZSB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UgZm9yIHRoZSBBTk9WQSBhbmFseXNpcy4gQWRkaXRpb25hbGx5LCBpdCBzaG91bGQgYmUgbm90ZWQgdGhhdCBBTk9WQSBhbmFseXNlcyBjYW4gYmUgcm9idXN0IHRvIHZpb2xhdGlvbnMgb2Ygbm9ybWFsaXR5IChHYXJkbmVyICYgVHJlbWJsYXksIDIwMDcpLgoKWzMuIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlXXtzdHlsZT0iY29sb3I6IzRGMjY4MzsgZm9udC1zaXplOjE4cHg7In0KClRoaXMgYXNzdW1wdGlvbiB3YXMgdGVzdGVkIGJ5IGNvbmR1Y3RpbmcgTGV2ZW5lJ3MgVGVzdCBmb3IgSG9tb2dlbmVpdHkgb2YgVmFyaWFuY2UgZm9yIGVhY2ggYmV0d2Vlbi1zdWJqZWN0cyB2YXJpYWJsZSAoaS5lLiwgc21hcnRwaG9uZSBsb2NhdGlvbiBhbmQgc21hcnRwaG9uZSBwb3dlcikuCgotICAgVGhlIGhvbW9nZW5laXR5IGFzc3VtcHRpb24gd2FzIG1ldCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSBmb3Igc21hcnRwaG9uZSBsb2NhdGlvbiwgKkYqKGByIG9zcGFuX2xldl9sb2MkRGZbMV1gLCBgciBvc3Bhbl9sZXZfbG9jJERmWzJdYCkgPSBgciByb3VuZChvc3Bhbl9sZXZfbG9jWzJdWzEsMV0sIDIpYCwgKnAqID0gYHIgcF9yb3VuZChvc3Bhbl9sZXZfbG9jWzNdWzEsMV0pYCBhbmQgc21hcnRwaG9uZSBwb3dlciwgKkYqKGByIG9zcGFuX2xldl9wb3ckRGZbMV1gLCBgciBvc3Bhbl9sZXZfcG93JERmWzJdYCkgPSBgciByb3VuZChvc3Bhbl9sZXZfcG93WzJdWzEsMV0sIDIpYCwgKnAqIGByIHBfcm91bmQob3NwYW5fbGV2X3Bvd1szXVsxLDFdKWAgKihzZWUgY29kZSBiZWxvdykqLgoKYGBge3IgY3JlYXRlJnNob3dfbGV2ZW5lcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjb25kdWN0IGxldmVuZSdzCiAgIyBmb3IgbG9jYXRpb24KICBvc3Bhbl9sZXZfbG9jID0gbGV2ZW5lVGVzdChkYXRhID0gb3NwYW5fYW5vdmFfZGF0YSwgc2NvcmUgfiBhcy5mYWN0b3IobG9jYXRpb24pLCBjZW50ZXIgPSBtZWFuKQogIG9zcGFuX2xldl9sb2MKICAjIGZvciBwb3dlcgogIG9zcGFuX2xldl9wb3cgPSBsZXZlbmVUZXN0KGRhdGEgPSBvc3Bhbl9hbm92YV9kYXRhLCBzY29yZSB+IGFzLmZhY3Rvcihwb3dlciksIGNlbnRlciA9IG1lYW4pCiAgb3NwYW5fbGV2X3BvdwpgYGAKCjwvZGV0YWlscz4KCiMjIyMjIFJlc3VsdHMKCkFsbCByZXN1bHRzIHdlcmUgYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkLiBCZWxvdyBhcmUgdGhlIHJlcG9ydGVkIHN0YXRpc3RpY3MgZm9yIGJvdGggbWFpbiBlZmZlY3RzIGFuZCB0aGUgaW50ZXJhY3Rpb25zLCBmb2xsb3dlZCBieSBhIHRhYmxlIGRlcGljdGluZyB0aGUgQU5PVkEgcmVzdWx0cy4KCioqTWFpbiBFZmZlY3Qgb2YgU21hcnRwaG9uZSBMb2NhdGlvbioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiBvbiBPc3BhbiBhYnNvbHV0ZSBzY29yZSwgKkYqKGByIG9zcGFuX2Fub3ZhJEFOT1ZBWzIsMl1gLCBgciBvc3Bhbl9hbm92YSRBTk9WQVsyLDNdYCkgPSBgciByb3VuZChvc3Bhbl9hbm92YSRBTk9WQVsyLDZdLCAyKWAsICpwKiBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzIsN10pYCwgJFxldGFeezJ9JCBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzIsOV0pYC4KCioqTWFpbiBFZmZlY3Qgb2YgU21hcnRwaG9uZSBQb3dlcioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBwb3dlciBvbiBPc3BhbiBhYnNvbHV0ZSBzY29yZSwgKkYqKGByIG9zcGFuX2Fub3ZhJEFOT1ZBWzMsMl1gLCBgciBvc3Bhbl9hbm92YSRBTk9WQVszLDNdYCkgPSBgciByb3VuZChvc3Bhbl9hbm92YSRBTk9WQVszLDZdLCAyKWAsICpwKiBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzMsN10pYCwgJFxldGFeezJ9JCBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzMsOV0pYC4KCioqSW50ZXJhY3Rpb24gb2YgU21hcnRwaG9uZSBMb2NhdGlvbiAmIFNtYXJ0cGhvbmUgUG93ZXIqKgoKVGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGJldHdlZW4gc21hcnRwaG9uZSBsb2NhdGlvbiBhbmQgc21hcnRwaG9uZSBwb3dlciBvbiBPc3BhbiBhYnNvbHV0ZSBzY29yZSwgKkYqKGByIG9zcGFuX2Fub3ZhJEFOT1ZBWzQsMl1gLCBgciBvc3Bhbl9hbm92YSRBTk9WQVs0LDNdYCkgPSBgciByb3VuZChvc3Bhbl9hbm92YSRBTk9WQVs0LDZdLCAyKWAsICpwKiBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzQsN10pYCwgJFxldGFeezJ9JCBgciBwX3JvdW5kKG9zcGFuX2Fub3ZhJEFOT1ZBWzQsOV0pYC4KCioqUG9zdC1ob2MgVGVzdHMqKgoKU2luY2UgdGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IG1haW4gb3IgaW50ZXJhY3Rpb24gZWZmZWN0cywgbm8gcG9zdC1ob2NzIHdlcmUgY29tcGxldGVkLgoKYGBge3Igc2hvd19vc3Bhbl9hbm92YV90YWJsZSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBzaG93IEFOT1ZBIHJlc3VsdHMgaW4ga2FibGUgdGFibGUgCmthYmxlKG9zcGFuX2Fub3ZhJEFOT1ZBLCBjYXB0aW9uID0gIjN4MiBBTk9WQSBvbiBPc3BhbiBBYnNvbHV0ZSBTY29yZSIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnKSAlPiUKICByb3dfc3BlYygwLCBib2xkID0gVCkgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUgCiAga2FibGVfY2xhc3NpYygpCmBgYAoKIyMjIyBWaXN1YWxpemF0aW9ucwoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoZSBmb2xsb3dpbmcgc2hvd3MgYSB2aXN1YWxpemF0aW9uIG9mIHRoZSBPU3BhbiBhYnNvbHV0ZSBzY29yZSBiYXNlZCBvbiB0aGUgdHdvIHNtYXJ0cGhvbmUgY29uZGl0aW9uczogbG9jYXRpb24gYW5kIHBvd2VyLiAqKGNsaWNrIHRvIHNlZSBjb2RlKSouCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfb3NwYW5fYmFyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggbG9jYXRpb24gY29uZGl0aW9ucyBhcyBjaGFyYWN0ZXJzIHJhdGhlciB0aGFuIGludGVnZXJzIAogICMgRmlyc3QsIGdldCBhIHN1YnNldCBvZiB0aGUgZGVzY3JpcHRpdmUgZGF0YQogIG9zcGFuX2Jhcl9kYXRhIDwtIG9zcGFuX2FuYWx5c2lzWywgYygibG9jYXRpb24iLCAicG93ZXIiLCAib3NwYW5fYWJzb2x1dGVfc2NvcmUiKV0KICAgIGNvbG5hbWVzKG9zcGFuX2Jhcl9kYXRhKSA9IGMoImxvY2F0aW9uIiwgInBvd2VyIiwgInNjb3JlIikKICAgIHJvd25hbWVzKG9zcGFuX2Jhcl9kYXRhKSA9IE5VTEwKICAgIAogIG9zcGFuX2Jhcl9kYXRhJGxvY2F0aW9uID0gZmFjdG9yKG9zcGFuX2Jhcl9kYXRhJGxvY2F0aW9uLCAKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAyLCAzKSwKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiRGVzayIsICJQb2NrZXQvQmFnIiwgIk91dHNpZGUiKSkKICBvc3Bhbl9iYXJfZGF0YSRwb3dlciA9IGZhY3Rvcihvc3Bhbl9iYXJfZGF0YSRwb3dlciwgCiAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMSwgMiksCiAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk9OIiwgIk9GRiIpKQpgYGAKCjwvZGV0YWlscz4KCmBgYHtyIHNob3dfb3NwYW5fYmFyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgcGxvdCBiYXIgZ3JhcGggLSBHT09ECm9zcGFuX2JhciA8LSAKICBnZ3Bsb3Qob3NwYW5fYmFyX2RhdGEsIGFlcyh4ID0gbG9jYXRpb24sIHkgPSBzY29yZSwgZmlsbCA9IHBvd2VyKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9IG1lYW4sIHBvc2l0aW9uID0gImRvZGdlIikgKyAKICAgIGd1aWRlcyhzaGFwZSA9IEZBTFNFKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImNhZGV0Ymx1ZTMiLCAiZGVlcHNreWJsdWU0IikpICsgCiAgbGFicygKICAgICAgIHRpdGxlID0gIlBlcmZvcm1hbmNlIG9uIHRoZSBPU3BhbiBUYXNrIiwKICAgICAgIHN1YnRpdGxlID0gIkF2ZXJhZ2UgQWJzb2x1dGUgT1NwYW4gU2NvcmUiLAogICAgICAgY2FwdGlvbiA9ICJOb3RlOiBTY29yZSBpcyB0aGUgbnVtYmVyIG9mIGNvcnJlY3QgbGV0dGVycyByZWNhbGxlZCBiYXNlZCBcbiBvbiBpZiBhbGwgbGV0dGVycyBpbiBhIGdpdmVuIGJsb2NrIHdlcmUgcmVjYWxsZWQgY29ycmVjdGx5LiIsCiAgICAgICB4ID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLCAKICAgICAgIHkgPSAiT1NwYW4gQWJzb2x1dGUgU2NvcmUiLCAKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBQb3dlciIKICAgICAgICkgKwogICAgICAgICMgdGhlICJcbiIgaGVyZSBkZW5vdGUgdGhhdCB5b3Ugd2FudCBhIG5ldyBsaW5lIGZvcm1lZCBpbiB0aGUgdGV4dAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKG1pbihvc3Bhbl9iYXJfZGF0YSRzY29yZSksIG1heChvc3Bhbl9iYXJfZGF0YSRzY29yZSkpLCBicmVha3MgPSApICsKICAjc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKGNvbG9yID0gcG93ZXIpLCBzaXplID0gMSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IC41MyksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGVlcHNreWJsdWU0IiwgInB1cnBsZTQiKSkgKyAKICBnZW9tX3BvaW50KHN0YXQ9InN1bW1hcnkiLCBmdW49bWVhbiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSguOSksIHNpemUgPSAxLjUsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX2Vycm9yYmFyKGRhdGEgPSBvc3Bhbl9iYXJfZGF0YSwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVubWluID0gZnVuY3Rpb24oeCkgbWVhbih4KSAtIHNkKHgpL3NxcnQobGVuZ3RoKHgpKSwgCiAgICAgICAgICAgICAgICBmdW5tYXggPSBmdW5jdGlvbih4KSBtZWFuKHgpICsgc2QoeCkvc3FydChsZW5ndGgoeCkpLCBzaXplPSAuNSwgd2lkdGg9IC4yNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSguOSkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEzKSwgCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDEyLCBmYWNlID0gIml0YWxpYyIpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzKSkKCiMgc2hvdyBmaWcKb3NwYW5fYmFyCgojIGV4cG9ydCBwbG90CiMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfb3NwYW5fYmFyX2p1bmUxNiIsIHBsb3QgPSBvc3Bhbl9iYXIsIGRldmljZSA9ICJqcGVnIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDEwMDApCmBgYAoKIyMjIEN1ZS1EZXBlbmRlbnQgR28vTm8tR28gVGFzawoKQW4gZXJyb3IgKGkuZS4sIG9taXNzaW9uIGVycm9ycykgYW5kIGFjY3VyYWN5IChpLmUuLCBSVCkgYW5hbHlzaXMgd2FzIGNvbXBsZXRlZCB1c2luZyB0aGUgb21pc3Npb24gZXJyb3JzIGFuZCBhdmVyYWdlIFJUIGZvciBlYWNoIHBhcnRpY2lwYW50LgoKIyMjIyBFcnJvciBBbmFseXNpcwoKQSAqKjMoU21hcnRwaG9uZSBsb2NhdGlvbjogZGVzaywgcG9ja2V0L2JhZywgb3V0c2lkZSkgeCAyKFNtYXJ0cGhvbmUgcG93ZXI6IE9OLCBPRkYpIHggMihDdWUgdHlwZTogVmVydGljYWwsIEhvcml6b250YWwpKiogbWl4ZWQgQU5PVkEgd2FzIGNvbXBsZXRlZCAqKERWID0gb21pc3Npb24gZXJyb3IocykpKi4gVGhlIGJldHdlZW4tc3ViamVjdHMgZmFjdG9ycyB3ZXJlIHNtYXJ0cGhvbmUgbG9jYXRpb24gYW5kIHBvd2VyLCBhbmQgdGhlIHdpdGhpbi1zdWJqZWN0cyBmYWN0b3Igd2FzIHByZS10YXJnZXQgY3VlIHR5cGUgKGkuZS4sICJjdWUgdHlwZSI7IGVpdGhlciAidmVydGljYWwiIG9yICJob3Jpem9udGFsIikuCgpQcmlvciB0byBjb21wbGV0aW5nIHRoZSBhbmFseXNpcywgcGxhbm5lZCBleGNsdXNpb24gY3JpdGVyaWEgd2FzIGFwcGxpZWQgdG8gdGhlIGRhdGEuIEV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhpcyBhbmFseXNpcyBoZWxwZWQgdG8gY29udHJvbCBmb3IgYW55IHBhcnRpY2lwYW50cyB3aG8gZGlkIG5vdCBmb2xsb3cgdGhlIGluc3RydWN0aW9ucy4gT25seSBkYXRhIGZyb20gdGhvc2Ugd2hvIHNjb3JlZCBoaWdoZXIgdGhhbiBjaGFuY2UgcGVyZm9ybWFuY2UgKGkuZS4sIHJlc3BvbmRlZCB0byBhdCBsZWFzdCA1MCUgb2YgIkdvIiB0cmlhbHMgYW5kIHdpdGhoZWxkIHJlc3BvbnNlIHRvIGF0IGxlYXN0IDUwJSBvZiAiTm8tR28iIHRyaWFscykgd2VyZSB1c2VkIGZvciB0aGUgZmluYWwgYW5hbHlzaXMuIFZpZXcgdGhlIFtEYXRhIENsZWFuaW5nIHNlY3Rpb25dKCNhbGxfZGF0YV9EQykgdW5kZXIgdGhlIGRhdGEgW0NvbnN0cnVjdCBXb3JraW5nIERhdGFmcmFtZXNdKCNtYWtlREZzKSBoZWFkaW5nIGFib3ZlLiBUaGVyZSB3YXMgYSB0b3RhbCBvZiBgciBucm93KGduZ19lcnJfYW5hbHlzaXMpLzJgIHBhcnRpY2lwYW50cyBpbiB0aGUgR28vTm8tR28gRXJyb3IgYW5hbHlzaXMuCgojIyMjIyBBbmFseXNpcwoKVG8gYXNzZXNzIGlmIHRoZSBvbWlzc2lvbiBlcnJvcnMgc3RhdGlzdGljYWxseSBkaWZmZXJlZCwgd2UgY29uZHVjdGVkIGEgM3gyeDIgbWl4ZWQgQU5PVkEgd2l0aCB0aGUgYmV0d2Vlbi1zdWJqZWN0cyBmYWN0b3JzIG9mIHNtYXJ0cGhvbmUgbG9jYXRpb24gKGkuZS4sIG9uIGRlc2ssIGluIHBvY2tldC9iYWcsIG9yIG91dHNpZGUpIGFuZCBwb3dlciAoaS5lLiBvbiBvciBvZmYpLCBhbmQgdGhlIHdpdGhpbi1zdWJqZWN0cyBmYWN0b3Igb2YgY3VlIHR5cGUgKGkuZS4sICJ2ZXJ0aWNhbCIgb3IgImhvcml6b250YWwiKS4gU2luY2UgdGhlcmUgYXJlIHVuZXF1YWwgc2FtcGxlIHNpemVzLCB3ZSB1c2VkIFR5cGUgSUlJIHN1bSBvZiBzcXVhcmVzLgoKIyMjIyMjIEFzc3VtcHRpb25zCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhlIG1peGVkIEFOT1ZBIG1hZGUgZm91ciBhc3N1bXB0aW9uczogaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsaW5nLCBub3JtYWxpdHksIGhvbW9nZW5laXR5IG9mIHZhcmlhbmNlIChpLmUuLCBmb3IgdGhlIGJldHdlZW4tc3ViamVjdCBmYWN0b3JzKSwgYW5kIHNwaGVyaWNpdHkgKGkuZS4sIGZvciB0aGUgd2l0aGluLXN1YmplY3RzIGZhY3RvcikuIE5vcm1hbGl0eSB3YXMgb3V0c2lkZSBvZiB0aGUgYWNjZXB0YWJsZSByYW5nZSwgaG93ZXZlciwgQU5PVkEgdGVzdHMgYXJlIHR5cGljYWxseSByb2J1c3QgdG8gdmlvbGF0aW9ucyBvZiBub3JtYWxpdHkgKEdhcmRuZXIgJiBUcmVtYmxheSwgMjAwNykuIFRoZSBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZSBhc3N1bXB0aW9uIHdhcyBub3QgbWV0LiAKRHVlIHRvIHRoaXMgYW5kIHNpbmNlIHRoZXJlIGFyZSB1bmVxdWFsIHNhbXBsZSBzaXplcywgYSBXaGl0ZS1jb3JyZWN0ZWQgRi10ZXN0IHdhcyBjb21wbGV0ZWQgZm9yIHRoZSBiZXR3ZWVuLXN1YmplY3QgZmFjdG9ycyAoaS5lLiwgc21hcnRwaG9uZSBsb2NhdGlvbiwgcG93ZXIpICooY2xpY2sgdG8gc2VlIGRldGFpbHMpKi4KCjwvc3VtbWFyeT4KClsxLiBJbmRlcGVuZGVudCBSYW5kb20gU2FtcGxpbmdde3N0eWxlPSJjb2xvcjojNEYyNjgzOyBmb250LXNpemU6MThweDsifQoKVGhpcyBhc3N1bXB0aW9uIHdhcyBtZXQgZHVyaW5nIHRlc3RpbmcuCgpbMi4gTm9ybWFsaXR5XXtzdHlsZT0iY29sb3I6IzRGMjY4MzsgZm9udC1zaXplOjE4cHg7In0KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGlzIGFzc3VtcHRpb24gd2FzIHRlc3RlZCBieSB2aXN1YWxpemluZyB0aGUgcmVzaWR1YWxzLCBhcHBseWluZyBhIFNoYXBpcm8tV2lsayB0ZXN0IHRvIHRoZSByZXNkaXVhbHMsIGFuZCBvYnNlcnZpbmcgdGhlIFNrZXduZXNzIGFuZCBLdXJ0b3NpcyBvZiB0aGUgZGF0YSAqKGV4dHJhY3RlZCBmcm9tIHRoZSBBTk9WQSBvdXRwdXQ7IGNsaWNrIHRvIHNlZSBjb2RlKS4qCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZ25nX2Vycl9hbm92YSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9CgojIGdldCB0aGUgcmVxdWlyZWQgZGF0YSBmcm9tIHRoZSBnbmdfZXJyX2FuYWx5c2lzIGRhdGE6IHBhcnRpY2lwYW50LCBsb2NhdGlvbiwgcG93ZXIsIGFuZCBzY29yZQpnbmdfZXJyX2Fub3ZhX2RhdGEgPSBnbmdfZXJyX2FuYWx5c2lzWyxjKCJwYXJ0aWNpcGFudCIsICJsb2NhdGlvbiIsICJwb3dlciIsICJjdWUiLCAiZ25nX2Vycl9vbWlfbG9uZyIpXQogICAgY29sbmFtZXMoZ25nX2Vycl9hbm92YV9kYXRhKSA9IGMoInBhcnRpY2lwYW50IiwgImxvY2F0aW9uIiwgInBvd2VyIiwgImN1ZSIsICJlcnJfb21pIikKICAgIHJvd25hbWVzKGduZ19lcnJfYW5vdmFfZGF0YSkgPSBOVUxMCiAgICBnbmdfZXJyX2Fub3ZhX2RhdGEkbG9jYXRpb24gPSBhcy5mYWN0b3IoZ25nX2Vycl9hbm92YV9kYXRhJGxvY2F0aW9uKQogICAgZ25nX2Vycl9hbm92YV9kYXRhJHBvd2VyID0gYXMuZmFjdG9yKGduZ19lcnJfYW5vdmFfZGF0YSRwb3dlcikKICAgIGduZ19lcnJfYW5vdmFfZGF0YSRjdWUgPSBhcy5mYWN0b3IoZ25nX2Vycl9hbm92YV9kYXRhJGN1ZSkKCiMgcnVuIG1peGVkIEFOT1ZBIChJViBiL3c6IFNtYXJ0cGhvbmUgUG93ZXIgJiBMb2NhdGlvbjsgSVYgdy9pbjogVGFyZ2V0IFR5cGU7IERWOiBPbWlzc2lvbiBFcnJvcnMpCmduZ19lcnJfYW5vdmEgPSBlekFOT1ZBKAogIGRhdGEgPSBnbmdfZXJyX2Fub3ZhX2RhdGEKICAsIGR2ID0gLihlcnJfb21pKQogICwgd2lkID0gLihwYXJ0aWNpcGFudCkKICAsIHdpdGhpbiA9IC4oY3VlKQogICwgYmV0d2VlbiA9IC4obG9jYXRpb24sIHBvd2VyKQogICwgdHlwZSA9IDMgIyB1bmVxdWFsIHNhbXBsZSBzaXplcywgdGhlcmVmb3JlIHVzZSB0eXBlIDMKICAsIGRldGFpbGVkID0gVFJVRQogICwgcmV0dXJuX2FvdiA9IFRSVUUKKQoKIyBjYWxjdWxhdGUgJiBleHRyYWN0IHRoZSByZXNpZHVhbHMgZnJvbSB0aGUgQU5PVkEKZ25nX2Vycl9yZXMgPSBkYXRhLmZyYW1lKCJyZXNpZHVhbHMiID0gcHJvaihnbmdfZXJyX2Fub3ZhJGFvdilbWzNdXVssICJSZXNpZHVhbHMiXSkKCmBgYAoKPC9kZXRhaWxzPgoKLSAgIEl0IGFwcGVhcnMgdGhhdCB0aGUgcmVzaWR1YWxzIGxpZSBjbG9zZWx5IHRvIGEgc3RyYWlnaHQgbGluZSAoaS5lLiwgb25seSBhIGNvdXBsZSBsaWUgYXdheSBmb3JtIHRoZSBsaW5lKSwgd2hpY2ggc3VnZ2VzdHMgbm9ybWFsaXR5ICooc2VlIHZpc3VhbGl6YXRpb24gYmVsb3cpKi4KCmBgYHtyIHNob3dfZ25nX2Vycl9xcSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnFxbm9ybShnbmdfZXJyX3JlcyRyZXNpZHVhbHMsIG1haW4gPSAiUS1RIFBsb3Qgb2YgdGhlIEdvL05vLUdvIEVycm9yIFJlc2lkdWFscyIpIApxcWxpbmUoZ25nX2Vycl9yZXMkcmVzaWR1YWxzKQoKYGBgCgotICAgSXQgYXBwZWFycyB0aGF0IHJlc2lkdWFscyBhcmUgbGVwdG9rdXJ0aWMgKGkuZS4sIHRoZXJlIGlzIGEgaGlnaCBwZWFrIG5lYXIgdGhlIGNlbnRlcikuIFRoaXMgd2FzIGV4cGVjdGVkIHNpbmNlIHRoZSBDdWUtRGVwZW5kZW50IEdvL05vLUdvIHRhc2sgaXMgYW4gZWFzeSByZXNwb25zZSBpbmhpYml0aW9uIHRhc2ssIHJlc3VsdGluZyBpbiBsb3cgZXJyb3IgcmF0ZXMgKihzZWUgdmlzdWFsaXphdGlvbiBiZWxvdykqLgoKYGBge3Igc2hvd19nbmdfZXJyX3JlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnFwbG90KGduZ19lcnJfcmVzJHJlc2lkdWFscywgbWFpbiA9ICJIaXN0b2dyYW0gb2YgR28vTm8tR28gRXJyb3IgUmVzaWR1YWxzIiwgYmlud2lkdGggPSAuMTUpICsgCiAgdGhlbWVfY2xhc3NpYygpCgpgYGAKCi0gICBUaGUgU2hhcGlyby1XaWxrIHRlc3Qgb2Ygbm9ybWFsaXR5IHdhcyBzaWduaWZpY2FudCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSwgKlcqID0gYHIgcm91bmQoYXMubnVtZXJpYyhnbmdfZXJyX3NoYXAkc3RhdGlzdGljWyJXIl0pLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfc2hhcCRwLnZhbHVlKWAgKihzZWUgY29kZSBiZWxvdykqLgoKYGBge3Igc2hvd19nbmdfZXJyX3NoYXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpnbmdfZXJyX3NoYXAgPSBzaGFwaXJvLnRlc3QoZ25nX2Vycl9yZXMkcmVzaWR1YWxzKQpnbmdfZXJyX3NoYXAKCmBgYAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KCi0gICBUaGUgU2tld25lc3MgYW5kIEt1cnRvc2lzIHdhcyBleGFtaW5lZC4gRm9yIHRoZSB2ZXJ0aWNhbCBjdWUgdHlwZSwgYm90aCB0aGUgU2tld25lc3MgKHJhbmdlOiBgciByb3VuZChtaW4oYXMubnVtZXJpYyhnbmdfZXJyX3NrX3ZfdFtjKDEsNCksXSkpLCAyKWAgdG8gYHIgcm91bmQobWF4KGFzLm51bWVyaWMoZ25nX2Vycl9za192X3RbYygxLDQpLF0pKSwgMilgKSBhbmQgS3VydG9zaXMgKHJhbmdlOiBgciByb3VuZChtaW4oYXMubnVtZXJpYyhnbmdfZXJyX3NrX3ZfdFtjKDIsNSksXSkpLCAyKWAgdG8gYHIgcm91bmQobWF4KGFzLm51bWVyaWMoZ25nX2Vycl9za192X3RbYygyLDUpLF0pKSwgMilgKSB3ZXJlIG91dHNpZGUgb2YgdGhlIGFjY2VwdGFibGUgcmFuZ2Ugb2YgJFxwbSAyLjAkIGFuZCAkXHBtIDkuMCQsIHJlc3BlY3RpdmVseSAoU2NobWlkZXIsIFppZWdsZXIsIERhbmF5LCBCZXllciwgJiBCw7xobmVyLCAyMDEwKS4gRm9yIHRoZSBob3Jpem9udGFsIGN1ZSB0eXBlLCBib3RoIHRoZSBTa2V3bmVzcyAocmFuZ2U6IGByIHJvdW5kKG1pbihhcy5udW1lcmljKGduZ19lcnJfc2tfaF90W2MoMSw0KSxdKSksIDIpYCB0byBgciByb3VuZChtYXgoYXMubnVtZXJpYyhnbmdfZXJyX3NrX2hfdFtjKDEsNCksXSkpLCAyKWApIGFuZCBLdXJ0b3NpcyAocmFuZ2U6IGByIHJvdW5kKG1pbihhcy5udW1lcmljKGduZ19lcnJfc2tfaF90W2MoMiw1KSxdKSksIDIpYCB0byBgciByb3VuZChtYXgoYXMubnVtZXJpYyhnbmdfZXJyX3NrX2hfdFtjKDIsNSksXSkpLCAyKWApIHdlcmUgb3V0c2lkZSBvZiB0aGUgYWNjZXB0YWJsZSByYW5nZSBvZiAkXHBtIDIuMCQgYW5kICRccG0gOS4wJCwgcmVzcGVjdGl2ZWx5IChTY2htaWRlciwgWmllZ2xlciwgRGFuYXksIEJleWVyLCAmIELDvGhuZXIsIDIwMTApICooc2VlIHRhYmxlIGJlbG93KSouCgogICAgPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2duZ19lcnJfc2tfdl90JmduZ19lcnJfc2tfaF90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGNyZWF0ZSBhIHRhYmxlIG9mIHRoZSBza2V3bmVzcyAmIGt1cnRvc2lzIGZvciB0aGUgZ25nIGRhdGEsIHNlcGFyYXRlZCBieSBjdWUgdHlwZSAoaS5lLiBvbmUgZm9yIHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCB0cmlhbHMpCgojLS1GT1IgVEhFIFZFUlRJQ0FMIC8gR28gQ1VFIFRZUEUKIyB1c2UgdGhlICJkZXNfdGFza19jb250X2N1ZV92IiBkYXRhIGZyYW1lIGZyb20gdGhlIGRlc2NyaXB0aXZlcwoKIyBvcmdhbml6ZSB0aGUgZGF0YSBpbnRvIGEgbmV3IGRhdGEgZnJhbWUgZGVwaWN0aW5nIHRoZSBTa2V3LCBrdXJ0b3NpcywgYW5kIHNhbXBsZSBzaXplIChuKS4KICBnbmdfZXJyX3NrX3ZfdCA8LSByYmluZCgoY2JpbmQodChkZXNfdGFza19jb250X2N1ZV92WyJnbmdfZXJyX29taV9sb25nMSIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udF9jdWVfdlsiZ25nX2Vycl9vbWlfbG9uZzIiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KGRlc190YXNrX2NvbnRfY3VlX3ZbImduZ19lcnJfb21pX2xvbmczIiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAoY2JpbmQodChkZXNfdGFza19jb250X2N1ZV92WyJnbmdfZXJyX29taV9sb25nNCIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udF9jdWVfdlsiZ25nX2Vycl9vbWlfbG9uZzUiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KGRlc190YXNrX2NvbnRfY3VlX3ZbImduZ19lcnJfb21pX2xvbmc2IiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSkpKQogIGNvbG5hbWVzKGduZ19lcnJfc2tfdl90KSA9IGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIikKICByb3duYW1lcyhnbmdfZXJyX3NrX3ZfdCkgPSByZXAoYygiU2tld25lc3MiLCAiS3VydG9zaXMiLCAibiIpLCAyKQogIAojLS1GT1IgVEhFIEhPUklaT05UQUwgLyBOby1HbyBDVUUgVFlQRQojIHVzZSB0aGUgImduZ19lcnJfZGVzX2giIGRhdGEgZnJhbWUgZnJvbSB0aGUgZGVzY3JpcHRpdmVzCgojIG9yZ2FuaXplIHRoZSBkYXRhIGludG8gYSBuZXcgZGF0YSBmcmFtZSBkZXBpY3RpbmcgdGhlIFNrZXcsIGt1cnRvc2lzLCBhbmQgc2FtcGxlIHNpemUgKG4pLgogIGduZ19lcnJfc2tfaF90IDwtIHJiaW5kKChjYmluZCh0KGRlc190YXNrX2NvbnRfY3VlX2hbImduZ19lcnJfb21pX2xvbmcxIiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdChkZXNfdGFza19jb250X2N1ZV9oWyJnbmdfZXJyX29taV9sb25nMiIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udF9jdWVfaFsiZ25nX2Vycl9vbWlfbG9uZzMiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgIChjYmluZCh0KGRlc190YXNrX2NvbnRfY3VlX2hbImduZ19lcnJfb21pX2xvbmc0IiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdChkZXNfdGFza19jb250X2N1ZV9oWyJnbmdfZXJyX29taV9sb25nNSIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udF9jdWVfaFsiZ25nX2Vycl9vbWlfbG9uZzYiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pKSkpCiAgICBjb2xuYW1lcyhnbmdfZXJyX3NrX2hfdCkgPSBjKCJPbiBEZXNrIiwgIkluIFBvY2tldC9CYWciLCAiT3V0c2lkZSIpCiAgICByb3duYW1lcyhnbmdfZXJyX3NrX2hfdCkgPSByZXAoYygiU2tld25lc3MiLCAiS3VydG9zaXMiLCAibiIpLCAyKQpgYGAKCjwvZGV0YWlscz4KCmBgYHtyIHNob3dfZ25nX2Vycl9za192X3QmZ25nX2Vycl9za19oX3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgc2hvdyBhIHRhYmxlIG9mIHRoZSBza2V3bmVzcyAmIGt1cnRvc2lzIGZvciB0aGUgZ25nIGRhdGEsIHNlcGFyYXRlZCBieSBjdWUgdHlwZSAoaS5lLiBvbmUgZm9yIHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCB0cmlhbHMpCiAgICAKIyBmb3IgdmVydGljYWwgY3VlIHR5cGUKIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgZGVzY3JpcHRpdmVzIHRhYmxlCmthYmxlKGduZ19lcnJfc2tfdl90LCBjYXB0aW9uID0gIlNrZXduZXNzIGFuZCBLdXJ0b3NpcyBvZiB0aGUgT21pc3Npb24gRXJyb3JzIG9uIHRoZSBHby9Oby1HbyBUYXNrIGZvciAnR28nIChWZXJ0aWNhbCkgVHJpYWxzIiwgZGlnaXRzID0gMiwgYWxpZ24gPSAnYycpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsICJTbWFydHBob25lIExvY2F0aW9uIiA9IDMpLCBib2xkID0gVCkgJT4lCiAgcGFja19yb3dzKCJTbWFydHBob25lIFBvd2VyIE9OIiwgMSwgMykgJT4lIAogIHBhY2tfcm93cygiU21hcnRwaG9uZSBQb3dlciBPRkYiLCA0LCA2KSAlPiUKICByb3dfc3BlYygwLCBib2xkID0gVCkgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKICAgIAojIGZvciBob3Jpem9udGFsIGN1ZSB0eXBlCiMgdXNlIGthYmxlIHRvIHNob3cgdGhlIGRlc2NyaXB0aXZlcyB0YWJsZQprYWJsZShnbmdfZXJyX3NrX2hfdCwgY2FwdGlvbiA9ICJTa2V3bmVzcyBhbmQgS3VydG9zaXMgb2YgdGhlIE9taXNzaW9uIEVycm9ycyBvbiB0aGUgR28vTm8tR28gVGFzayBmb3IgJ05vLUdvJyAoSG9yaXpvbmF0YWwpIFRyaWFscyIsIGRpZ2l0cyA9IDIsIGFsaWduID0gJ2MnKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiU21hcnRwaG9uZSBMb2NhdGlvbiIgPSAzKSwgYm9sZCA9IFQpICU+JQogIHBhY2tfcm93cygiU21hcnRwaG9uZSBQb3dlciBPTiIsIDEsIDMpICU+JSAKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgUG93ZXIgT0ZGIiwgNCwgNikgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKLSAgIFRoZXJlZm9yZSwgYmFzZWQgb24gYWxsIHRoZSBub3JtYWxpdHkgYXNzdW1wdGlvbiBjaGVja3MsIG5vcm1hbGl0eSB3YXMgbm90IGFzc3VtZWQgdG8gYmUgd2l0aGluIHRoZSBhY2NlcHRhYmxlIHJhbmdlLCBob3dldmVyLCBBTk9WQSB0ZXN0cyBhcmUgdHlwaWNhbGx5IHJvYnVzdCB0byB2aW9sYXRpb25zIG9mIG5vcm1hbGl0eSAoR2FyZG5lciAmIFRyZW1ibGF5LCAyMDA3KS4KClszLiBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZV17c3R5bGU9ImNvbG9yOiM0RjI2ODM7IGZvbnQtc2l6ZToxOHB4OyJ9CgotICAgVGhpcyBhc3N1bXB0aW9uIHdhcyB0ZXN0ZWQgYnkgY29uZHVjdGluZyBMZXZlbmUncyBUZXN0IGZvciBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZSBmb3IgZWFjaCBiZXR3ZWVuLXN1YmplY3RzIHZhcmlhYmxlIChpLmUuLCBzbWFydHBob25lIGxvY2F0aW9uLCBzbWFydHBob25lIHBvd2VyLCBhbmQgYmFsYW5jZSkuCgotICAgVGhlIGhvbW9nZW5laXR5IGFzc3VtcHRpb24gd2FzIG1ldCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSBmb3Igc21hcnRwaG9uZSBwb3dlciwgKkYqKGByIGduZ19lcnJfbGV2X3BvdyREZlsxXWAsIGByIGduZ19lcnJfbGV2X3BvdyREZlsyXWApID0gYHIgcm91bmQoZ25nX2Vycl9sZXZfcG93WzJdWzEsMV0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2Vycl9sZXZfcG93WzNdWzEsMV0pYC4gSG93ZXZlciwgaXQgd2FzIG5vdCBtZXQgZm9yIHNtYXJ0cGhvbmUgbG9jYXRpb24sICpGKihgciBnbmdfZXJyX2xldl9sb2MkRGZbMV1gLCBgciBnbmdfZXJyX2xldl9sb2MkRGZbMl1gKSA9IGByIHJvdW5kKGduZ19lcnJfbGV2X2xvY1syXVsxLDFdLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfbGV2X2xvY1szXVsxLDFdKWAsKihzZWUgY29kZSBiZWxvdykqLgoKYGBge3Igc2hvd19nbmdfZXJyX2xldmVuZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIGNvbmR1Y3QgbGV2ZW5lJ3MKICAjIGZvciBsb2NhdGlvbgogIGduZ19lcnJfbGV2X2xvYyA9IGxldmVuZVRlc3QoZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YSwgZXJyX29taSB+IGFzLmZhY3Rvcihsb2NhdGlvbiksIGNlbnRlciA9IG1lYW4pCiAgZ25nX2Vycl9sZXZfbG9jCiAgIyBmb3IgcG93ZXIKICBnbmdfZXJyX2xldl9wb3cgPSBsZXZlbmVUZXN0KGRhdGEgPSBnbmdfZXJyX2Fub3ZhX2RhdGEsIGVycl9vbWkgfiBhcy5mYWN0b3IocG93ZXIpLCBjZW50ZXIgPSBtZWFuKQogIGduZ19lcnJfbGV2X3BvdwoKYGBgCgpbNC4gU3BoZXJpY2l0eV17c3R5bGU9ImNvbG9yOkRhcmtCbHVlOyBmb250LXNpemU6MThweDsifQoKVGhpcyBhc3N1bXB0aW9uIHdhcyBtZXQgc2luY2Ugc3BoZXJpY2l0eSBpcyBhbHdheXMgbWV0IGZvciB0d28gbGV2ZWxzIG9mIGEgcmVwZWF0ZWQgbWVhc3VyZSBmYWN0b3IgYW5kIGlzLCB0aGVyZWZvcmUsIHVubmVjZXNzYXJ5IHRvIGV2YWx1YXRlIChHaXJkZW4sIDE5OTIpLgoKPC9kZXRhaWxzPgoKIyMjIyMjIFJlc3VsdHMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpTaW5jZSB0aGUgaG9tb2dlbmVpdHkgYXNzdW1wdGlvbiB3YXMgbm90IG1ldCBmb3IgdGhlIG1peGVkIEFOT1ZBLCBhIFdoaXRlLWNvcnJlY3RlZCBGLXRlc3Qgd2FzIGNvbXBsZXRlZC4gVGhlIHJlc3VsdHMgZnJvbSB0aGlzIGFuYWx5c2lzIGFyZSBzaG93biBiZWxvdywgZm9sbG93ZWQgYnkgYSB0YWJsZSBkZXBpY3RpbmcgdGhlIHN0YXRpc3RpY3MgKihjbGljayB0byBzZWUgY29kZSkqLgoKPC9zdW1tYXJ5PgoKU2luY2UgdGhlIGV6QU5PVkEgZnVuY3Rpb24gY2FuIG9ubHkgY29tcGxldGUgYSBXaGl0ZS1jb3JyZWN0ZWQgRi10ZXN0IG9uIGJldHdlZW4tc3ViamVjdCBmYWN0b3JzLCBhIHNlcGFyYXRlIEFOT1ZBIHdhcyBjb21wdXRlZCB1c2luZyB0aGlzIGNvcnJlY3Rpb24gZm9yIHRoZSBiZXR3ZWVuLXN1YmplY3QgZWZmZWN0cy4gQWRkaXRpb25hbGx5LCB0aGUgZWZmZWN0IHNpemVzIHdlcmUgY29tcGx1dGVkIHNlcGFyYXRlbHkgdXNpbmcgdGhlIEV0YVNxIGZ1bmN0aW9uLiAKCmBgYHtyIGNyZWF0ZV9nbmdfZXJyX3JvYnVzdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRSwgZXJyb3I9RkFMU0V9CiMgY29tcGxldGUgd2hpdGUtY29yciBBTk9WQSBmb3IgYi93IHN1YiBmYWN0b3JzIChsb2NhdGlvbiAmIHBvd2VyKQpnbmdfZXJyX2Fub3ZhX3doaXRlIDwtIAogIGV6QU5PVkEoZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YSwgCiAgICAgICAgICBkdiA9IC4oZXJyX29taSksIAogICAgICAgICAgd2lkID0gLihwYXJ0aWNpcGFudCksIAogICAgICAgICAgYmV0d2VlbiA9IC4obG9jYXRpb24sIHBvd2VyKSwgCiAgICAgICAgICBkZXRhaWxlZCA9IFRSVUUsIAogICAgICAgICAgdHlwZSA9ICJJSUkiLCAjIGZvciB1bmVxdWFsIHNhbXBsZSBzaXplcwogICAgICAgICAgcmV0dXJuX2FvdiA9IFRSVUUsIAogICAgICAgICAgd2hpdGUuYWRqdXN0ID0gVFJVRSwgIyBhZGQgd2hpdGUtY29ycmVjdGlvbgogICAgICAgICAgd2l0aGluX2Z1bGwgPSAuKGN1ZSkgIyBsZXQgZnVuY3Rpb24ga25vdyB0aGUgZnVsbCBBTk9WQSBpbmNsdWRlcyB0aGlzIHcvaW4tc3ViIGZhY3RvcgogICAgICAgICAgKQojIGNvbXB1dGUgZWZmZWN0IHNpemUKZ25nX2Vycl9hbm92YV93aGl0ZV9lcyA8LSBFdGFTcShnbmdfZXJyX2Fub3ZhX3doaXRlJGFvdiwgdHlwZSA9IDMsIGFub3ZhID0gRkFMU0UpCgpgYGAKCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpBbGwgcmVzdWx0cyB3ZXJlIGJhc2Ugb24gJFxhbHBoYSA9IDAuMDUkLiBCZWxvdyBhcmUgdGhlIHJlcG9ydGVkIHN0YXRpc3RpY3MgZm9yIGJvdGggbWFpbiBlZmZlY3RzIGFuZCB0aGUgaW50ZXJhY3Rpb24sIGZvbGxvd2VkIGJ5IGEgdGFibGUgZGVwaWN0aW5nIHRoZSBBTk9WQSByZXN1bHRzICooY2xpY2sgdG8gc2VlIGNvZGUpKi4KCioqTWFpbiBFZmZlY3Qgb2YgU21hcnRwaG9uZSBMb2NhdGlvbioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiBvbiBvbWlzc2lvbiBlcnJvcnMsICpGKihgciBnbmdfZXJyX2Fub3ZhX3QkREZuWzFdYCwgYHIgZ25nX2Vycl9hbm92YV90JERGZFsxXWApID0gYHIgcm91bmQoZ25nX2Vycl9hbm92YV90WzEsNF0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV90JHBbMV0pYCwgJFxldGFfe0d9XjIkID0gYHIgcF9yb3VuZChnbmdfZXJyX2Fub3ZhX3QkZ2VzWzFdKWAuCgoqKk1haW4gRWZmZWN0IG9mIFNtYXJ0cGhvbmUgUG93ZXIqKgoKVGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIHNtYXJ0cGhvbmUgcG93ZXIgb24gb21pc3Npb24gZXJyb3JzLCAqRiooYHIgZ25nX2Vycl9hbm92YV90JERGblsyXWAsIGByIGduZ19lcnJfYW5vdmFfdCRERmRbMl1gKSA9IGByIHJvdW5kKGduZ19lcnJfYW5vdmFfdFsyLDRdLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfdCRwWzJdKWAsICRcZXRhX3tHfV4yJCA9IGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV90JGdlc1syXSlgLgoKKipNYWluIEVmZmVjdCBvZiBTbWFydHBob25lIEN1ZSBUeXBlKioKClRoZXJlIHdhcyBhIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIGN1ZSB0eXBlIG9uIG9taXNzaW9uIGVycm9ycywgKkYqKGByIGduZ19lcnJfYW5vdmFfdCRERm5bM11gLCBgciBnbmdfZXJyX2Fub3ZhX3QkREZkWzNdYCkgPSBgciByb3VuZChnbmdfZXJyX2Fub3ZhX3RbMyw0XSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfZXJyX2Fub3ZhX3QkcFszXSlgLCAkXGV0YV97R31eMiQgPSBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfdCRnZXNbM10pYC4KCioqSW50ZXJhY3Rpb24gb2YgU21hcnRwaG9uZSBMb2NhdGlvbiAmIFBvd2VyKioKClRoZXJlIHdhcyBubyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBiZXR3ZWVuIHNtYXJ0cGhvbmUgbG9jYXRpb24gYW5kIHBvd2VyIG9uIG9taXNzaW9uIGVycm9ycywgKkYqKGByIGduZ19lcnJfYW5vdmFfdCRERm5bNF1gLCBgciBnbmdfZXJyX2Fub3ZhX3QkREZkWzRdYCkgPSBgciByb3VuZChnbmdfZXJyX2Fub3ZhX3RbNCw0XSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfZXJyX2Fub3ZhX3QkcFs0XSlgLCAkXGV0YV97R31eMiQgPSBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfdCRnZXNbNF0pYC4KCioqSW50ZXJhY3Rpb24gb2YgU21hcnRwaG9uZSBMb2NhdGlvbiAmIEN1ZSBUeXBlKioKClRoZXJlIHdhcyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGJldHdlZW4gc21hcnRwaG9uZSBsb2NhdGlvbiBhbmQgY3VlIHR5cGUgb24gb21pc3Npb24gZXJyb3JzLCAqRiooYHIgZ25nX2Vycl9hbm92YV90JERGbls1XWAsIGByIGduZ19lcnJfYW5vdmFfdCRERmRbNV1gKSA9IGByIHJvdW5kKGduZ19lcnJfYW5vdmFfdFs1LDRdLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfdCRwWzVdKWAsICRcZXRhX3tHfV4yJCA9IGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV90JGdlc1s1XSlgLiBEdWUgdG8gYSBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiwgdGhlIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIGN1ZSB0eXBlIHdhcyBub3QgZXhwbG9yZWQgZnVydGhlci4gCgoqKkludGVyYWN0aW9uIG9mIFNtYXJ0cGhvbmUgUG93ZXIgJiBDdWUgVHlwZSoqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBzbWFydHBob25lIHBvd2VyIGFuZCBjdWUgdHlwZSBvbiBvbWlzc2lvbiBlcnJvcnMsICpGKihgciBnbmdfZXJyX2Fub3ZhX3QkREZuWzZdYCwgYHIgZ25nX2Vycl9hbm92YV90JERGZFs2XWApID0gYHIgcm91bmQoZ25nX2Vycl9hbm92YV90WzYsNF0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV90JHBbNl0pYCwgJFxldGFfe0d9XjIkID0gYHIgcF9yb3VuZChnbmdfZXJyX2Fub3ZhX3QkZ2VzWzZdKWAuCgoqKkludGVyYWN0aW9uIG9mIFNtYXJ0cGhvbmUgTG9jYXRpb24sIFNtYXJ0cGhvbmUgUG93ZXIsICYgQ3VlIFR5cGUqKgoKVGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGJldHdlZW4gc21hcnRwaG9uZSBsb2NhdGlvbiwgc21hcnRwaG9uZSBwb3dlciwgYW5kIGN1ZSB0eXBlIG9uIG9taXNzaW9uIGVycm9ycywgKkYqKGByIGduZ19lcnJfYW5vdmFfdCRERm5bN11gLCBgciBnbmdfZXJyX2Fub3ZhX3QkREZkWzddYCkgPSBgciByb3VuZChnbmdfZXJyX2Fub3ZhX3RbNyw0XSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfZXJyX2Fub3ZhX3QkcFs3XSlgLCAkXGV0YV97R31eMiQgPSBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfdCRnZXNbN10pYC4KCioqUG9zdC1ob2MgVGVzdHMqKgoKU2luY2UgdGhlcmUgd2FzIGEgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBjdWUgdHlwZSBhbmQgc21hcnRwaG9uZSBsb2NhdGlvbiwgYSBwb3N0LWhvY3MgYXNzZXNzaW5nIHRoZSBzaW1wbGUgbWFpbiBlZmZlY3RzIG9mIGN1ZSB0eXBlIChpLmUuLCB2ZXJ0aWNhbC9nbywgaG9yaXpvbnRhbC9uby1nbykgYWNyb3NzIHRoZSBsZXZlbHMgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiAoaS5lLiwgZGVzaywgcG9ja2V0L2JhZywgb3V0c2lkZSkgd2FzIGNvbXBsZXRlZC4gCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZ25nX2Vycl9yb2J1c3RfdGFibGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgY3JlYXRlIGRhdGEgZnJhbWUgZnJvbSBtaXhlZCBBTk9WQSByZXN1bHRzIHRvIGRpc3BsYXkgKGluY2x1ZGluZyBib3RoIHdoaXRlLWNvcnIgZm9yIGIvdyBzdWIgZWZmZWN0cykKZ25nX2Vycl9hbm92YV90IDwtIAogIGRhdGEuZnJhbWUoImVmZmVjdCIgPSBnbmdfZXJyX2Fub3ZhJEFOT1ZBJEVmZmVjdFsyOjhdLCAKICAgICAgICAgICAgICJERm4iID0gZ25nX2Vycl9hbm92YSRBTk9WQSRERm5bMjo4XSwgCiAgICAgICAgICAgICAiREZkIiA9IGduZ19lcnJfYW5vdmEkQU5PVkEkREZkWzI6OF0sIAogICAgICAgICAgICAgIkYiID0gYyhnbmdfZXJyX2Fub3ZhX3doaXRlJEFOT1ZBJEZbMjozXSwgZ25nX2Vycl9hbm92YSRBTk9WQSRGWzRdLCBnbmdfZXJyX2Fub3ZhX3doaXRlJEFOT1ZBJEZbNF0sIGduZ19lcnJfYW5vdmEkQU5PVkEkRls2OjhdKSwgCiAgICAgICAgICAgICAicCIgPSBjKGduZ19lcnJfYW5vdmFfd2hpdGUkQU5PVkEkcFsyOjNdLCBnbmdfZXJyX2Fub3ZhJEFOT1ZBJHBbNF0sIGduZ19lcnJfYW5vdmFfd2hpdGUkQU5PVkEkcFs0XSwgZ25nX2Vycl9hbm92YSRBTk9WQSRwWzY6OF0pLCAKICAgICAgICAgICAgICJwPC4wNSIgPSBjKGduZ19lcnJfYW5vdmFfd2hpdGUkQU5PVkEkYHA8LjA1YFsyOjNdLCBnbmdfZXJyX2Fub3ZhJEFOT1ZBJGBwPC4wNWBbNF0sIGduZ19lcnJfYW5vdmFfd2hpdGUkQU5PVkEkYHA8LjA1YFs0XSwgZ25nX2Vycl9hbm92YSRBTk9WQSRgcDwuMDVgWzY6OF0pLCAKICAgICAgICAgICAgICJnZXMiID0gYyhnbmdfZXJyX2Fub3ZhX3doaXRlX2VzWzE6MiwgMl0sIGduZ19lcnJfYW5vdmEkQU5PVkEkZ2VzWzRdLCBnbmdfZXJyX2Fub3ZhX3doaXRlX2VzWzMsIDJdLCBnbmdfZXJyX2Fub3ZhJEFOT1ZBJGdlc1s2OjhdKQogICAgICAgICAgICAgKQojIHJlbmFtZSByb3dzCnJvd25hbWVzKGduZ19lcnJfYW5vdmFfdCkgPSBOVUxMCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19nbmdfZXJyX3JvYnVzdF90YWJsZSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBzaG93IEFOT1ZBIHJlc3VsdHMgaW4ga2FibGUgdGFibGUgCmthYmxlKGduZ19lcnJfYW5vdmFfdCwgY2FwdGlvbiA9ICIzeDJ4MiBNaXhlZCBBTk9WQSBvbiBPbWlzc2lvbiBFcnJvciBpbiB0aGUgR28vTm8tR28gVGFzayIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnLCBjb2wubmFtZXMgPSBjKCJFZmZlY3QiLCAiREZuIiwgIkRGZCIsICJGIiwgInAiLCAicCA8IC4wNSIsICJnZXMiKSkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JSAKICBmb290bm90ZShnZW5lcmFsID0gIk5vdGU6IGJldHdlZW4tc3ViamVjdCBlZmZlY3RzIChpLmUuLCBsb2NhdGlvbiwgcG93ZXIsIGxvY2F0aW9uOnBvd2VyKSBhcmUgV2hpdGUtY29ycmVjdGVkLiIpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlX2NsYXNzaWMoKQpgYGAKCiMjIyMjIyBQb3N0LUhvY3MKCkFuIEFOT1ZBIHdhcyBjb25kdWN0ZWQgdG8gaW52ZXN0aWdhdGUgdGhlIGVmZmVjdCBvZiBjdWUgdHlwZSBvbiBvbWlzc2lvbiBlcnJvcnMgZm9yIGVhY2ggc21hcnRwaG9uZSBsb2NhdGlvbiBzZXBhcmF0ZWx5ICh3aXRoIGEgSG9sbS1Cb25mZXJyb25pIGFkanVzdG1lbnQpLiAKCiMjIyMjIyBQSDogQXNzdW1wdGlvbnMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgdHdvIGJldHdlZW4tc3ViamVjdHMgQU5PVkEgbWFkZSB0aHJlZSBhc3N1bXB0aW9uczogaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsaW5nLCBub3JtYWxpdHksIGFuZCBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZS4gRm9yIGJvdGggQU5PVkFzLCBub3JtYWxpdHkgd2FzIG91dHNpZGUgb2YgdGhlIGFjY2VwdGFibGUgcmFuZ2UsIGhvd2V2ZXIsIEFOT1ZBIHRlc3RzIGFyZSB0eXBpY2FsbHkgcm9idXN0IHRvIHZpb2xhdGlvbnMgb2Ygbm9ybWFsaXR5IChHYXJkbmVyICYgVHJlbWJsYXksIDIwMDcpLiBUaGUgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbiB3YXMgbWV0IGZvciB0aGUgaG9yaXpvbnRhbCAoaS5lLiwgIm5vLWdvIikgY3VlIHR5cGUsIGJ1dCBub3QgZm9yIHRoZSB2ZXJ0aWNhbCAoaS5lLiwgImdvIikgY3VlIHR5cGUuIER1ZSB0byB0aGlzIGFuZCBzaW5jZSB0aGVyZSBhcmUgdW5lcXVhbCBzYW1wbGUgc2l6ZXMsIGEgV2hpdGUtY29ycmVjdGVkIEYtdGVzdCB3YXMgY29tcGxldGVkIGZvciB0aGUgdmVydGljYWwgKGkuZS4sICJnbyIpIGN1ZSB0eXBlIEFOT1ZBIGFuZCBhIG5vcm1hbCBBTk9WQSBmb3IgdGhlIGhvcml6b250YWwgKGkuZS4sICJuby1nbyIpIGN1ZSB0eXBlICooY2xpY2sgdG8gc2VlIGRldGFpbHMpKi4KCjwvc3VtbWFyeT4KClsxLiBJbmRlcGVuZGVudCBSYW5kb20gU2FtcGxpbmdde3N0eWxlPSJjb2xvcjojNEYyNjgzOyBmb250LXNpemU6MThweDsifQoKVGhpcyBhc3N1bXB0aW9uIHdhcyBtZXQgZHVyaW5nIHRlc3RpbmcgZm9yIGJvdGggQU5PVkFzLgoKWzIuIE5vcm1hbGl0eV17c3R5bGU9ImNvbG9yOiM0RjI2ODM7IGZvbnQtc2l6ZToxOHB4OyJ9Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKVGhpcyBhc3N1bXB0aW9uIHdhcyB0ZXN0ZWQgYnkgdmlzdWFsaXppbmcgdGhlIHJlc2lkdWFscywgYXBwbHlpbmcgYSBTaGFwaXJvLVdpbGsgdGVzdCB0byB0aGUgcmVzaWR1YWxzLCBhbmQgb2JzZXJ2aW5nIHRoZSBTa2V3bmVzcyBhbmQgS3VydG9zaXMgb2YgdGhlIGRhdGEgKihleHRyYWN0ZWQgZnJvbSB0aGUgQU5PVkEgb3V0cHV0OyBjbGljayB0byBzZWUgY29kZSkuKgoKPC9zdW1tYXJ5PgoKYGBge3IgY3JlYXRlX2duZ19lcnJfYW5vdmFfViZILCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KCiMgZ2V0IHRoZSByZXF1aXJlZCBkYXRhIGZyb20gdGhlIGduZ19lcnJfYW5hbHlzaXMgZGF0YTogcGFydGljaXBhbnQsIGxvY2F0aW9uLCBhbmQgc2NvcmUKICAjIGZvciB2ZXJ0aWNhbC9nbyB0cmlhbHMKICBnbmdfZXJyX2Fub3ZhX2RhdGFfViA8LSAKICAgIGduZ19lcnJfYW5vdmFfZGF0YSAlPiUgCiAgICAjIGdldCBjdWUgdHlwZSA9ICJnbyIgb3IgdmVydGljYWwKICAgIGZpbHRlcihjdWUgPT0gMSkgJT4lIAogICAgIyByZW1vdmUgcG93ZXIgZmFjdG9yCiAgICBzZWxlY3QoLXBvd2VyKQogICMgZm9yIGhvcml6b250YWwvbm8tZ28gdHJpYWxzCiAgZ25nX2Vycl9hbm92YV9kYXRhX0ggPC0gCiAgICBnbmdfZXJyX2Fub3ZhX2RhdGEgJT4lIAogICAgIyBnZXQgY3VlIHR5cGUgPSAibm8tZ28iIG9yIGhvcml6b250YWwgCiAgICBmaWx0ZXIoY3VlID09IDIpICU+JSAKICAgICMgcmVtb3ZlIHBvd2VyIGZhY3RvcgogICAgc2VsZWN0KC1wb3dlcikKCiMgcnVuIEFOT1ZBIChJVjogU21hcnRwaG9uZSBMb2NhdGlvbjsgRFY6IE9taXNzaW9uIEVycm9ycykKICAjIGZvciB2ZXJ0aWNhbC9nbyB0cmlhbHMKICBnbmdfZXJyX2Fub3ZhX1YgPSBlekFOT1ZBKAogICAgZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YV9WCiAgICAsIGR2ID0gLihlcnJfb21pKQogICAgLCB3aWQgPSAuKHBhcnRpY2lwYW50KQogICAgLCBiZXR3ZWVuID0gLihsb2NhdGlvbikKICAgICwgdHlwZSA9IDMgIyB1bmVxdWFsIHNhbXBsZSBzaXplcywgdGhlcmVmb3JlIHVzZSB0eXBlIDMKICAgICwgZGV0YWlsZWQgPSBUUlVFCiAgICAsIHJldHVybl9hb3YgPSBUUlVFCiAgICApCiAgIyBmb3IgaG9yaXpvbnRhbC9uby1nbyB0cmlhbHMKICBnbmdfZXJyX2Fub3ZhX0ggPSBlekFOT1ZBKAogICAgZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YV9ICiAgICAsIGR2ID0gLihlcnJfb21pKQogICAgLCB3aWQgPSAuKHBhcnRpY2lwYW50KQogICAgLCBiZXR3ZWVuID0gLihsb2NhdGlvbikKICAgICwgdHlwZSA9IDMgIyB1bmVxdWFsIHNhbXBsZSBzaXplcywgdGhlcmVmb3JlIHVzZSB0eXBlIDMKICAgICwgZGV0YWlsZWQgPSBUUlVFCiAgICAsIHJldHVybl9hb3YgPSBUUlVFCiAgICApCgojIGNhbGN1bGF0ZSAmIGV4dHJhY3QgdGhlIHJlc2lkdWFscyBmcm9tIHRoZSBBTk9WQQogICMgZm9yIHZlcnRpY2FsL2dvIHRyaWFscwogIGduZ19lcnJfcmVzX1YgPSBkYXRhLmZyYW1lKCJyZXNpZHVhbHMiID0gZ25nX2Vycl9hbm92YV9WJGFvdiRyZXNpZHVhbHMpCiAgIyBmb3IgaG9yaXpvbnRhbC9uby1nbyB0cmlhbHMKICBnbmdfZXJyX3Jlc19IID0gZGF0YS5mcmFtZSgicmVzaWR1YWxzIiA9IGduZ19lcnJfYW5vdmFfSCRhb3YkcmVzaWR1YWxzKQoKYGBgCgo8L2RldGFpbHM+CgotICAgSXQgYXBwZWFycyB0aGF0IHRoZSByZXNpZHVhbHMgZG8gbm90IGxpZSBjbG9zZWx5IHRvIGEgc3RyYWlnaHQgbGluZTogdGhlIGRhdGEgYXJlIGhlYXZ5LXRhaWxlZCBvbiB0aGUgcmlnaHQgKihzZWUgdmlzdWFsaXphdGlvbiBiZWxvdykqLgoKYGBge3Igc2hvd19nbmdfZXJyX1YmSF9xcSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBmb3IgdmVydGljYWwvZ28gdHJpYWxzCnFxbm9ybShnbmdfZXJyX3Jlc19WJHJlc2lkdWFscywgbWFpbiA9ICJRLVEgUGxvdCBvZiB0aGUgR28vTm8tR28gRXJyb3IgUmVzaWR1YWxzIGZvciBWZXJ0aWNhbC9HbyBUcmlhbHMiKSAKcXFsaW5lKGduZ19lcnJfcmVzX1YkcmVzaWR1YWxzKQoKIyBmb3IgaG9yaXpvbnRhbC9uby1nbyB0cmlhbHMKcXFub3JtKGduZ19lcnJfcmVzX0gkcmVzaWR1YWxzLCBtYWluID0gIlEtUSBQbG90IG9mIHRoZSBHby9Oby1HbyBFcnJvciBSZXNpZHVhbHMgZm9yIEhvcml6b250YWwvTm8tR28gVHJpYWxzIikgCnFxbGluZShnbmdfZXJyX3Jlc19IJHJlc2lkdWFscykKCmBgYAoKLSAgIEl0IGFwcGVhcnMgdGhhdCByZXNpZHVhbHMgYXJlIGxlcHRva3VydGljIChpLmUuLCB0aGVyZSBpcyBhIGhpZ2ggcGVhayBuZWFyIHRoZSBjZW50ZXIpLiBUaGlzIHdhcyBleHBlY3RlZCBzaW5jZSB0aGUgQ3VlLURlcGVuZGVudCBHby9Oby1HbyB0YXNrIGlzIGFuIGVhc3kgcmVzcG9uc2UgaW5oaWJpdGlvbiB0YXNrLCByZXN1bHRpbmcgaW4gbG93IGVycm9yIHJhdGVzICooc2VlIHZpc3VhbGl6YXRpb24gYmVsb3cpKi4KCmBgYHtyIHNob3dfZ25nX2Vycl9WJkggaGlzdG9ncmFtcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBmb3IgdmVydGljYWwvZ28gdHJpYWxzCnFwbG90KGduZ19lcnJfcmVzX1YkcmVzaWR1YWxzLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBHby9Oby1HbyBFcnJvciBSZXNpZHVhbHMgZm9yIFZlcnRpY2FsL0dvIFRyaWFscyIsIGJpbndpZHRoID0gLjUpICsgCiAgdGhlbWVfY2xhc3NpYygpCiMgZm9yIGhvcml6b250YWwvbm8tZ28gdHJpYWxzCnFwbG90KGduZ19lcnJfcmVzX0gkcmVzaWR1YWxzLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBHby9Oby1HbyBFcnJvciBSZXNpZHVhbHMgZm9yIEhvcml6b250YWwvTm8tR28gVHJpYWxzIiwgYmlud2lkdGggPSAuNSkgKyAKICB0aGVtZV9jbGFzc2ljKCkKYGBgCgotICAgVGhlIFNoYXBpcm8tV2lsayB0ZXN0IG9mIG5vcm1hbGl0eSB3YXMgc2lnbmlmaWNhbnQgKGJhc2VkIG9uICRcYWxwaGEgPSAwLjA1JCkgZm9yIHRoZSB2ZXJ0aWNhbCAoaS5lLiwgImdvIikgdHJpYWxzLCAqVyogPSBgciByb3VuZChhcy5udW1lcmljKGduZ19lcnJfc2hhcF9WJHN0YXRpc3RpY1siVyJdKSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfZXJyX3NoYXBfViRwLnZhbHVlKWAsIGFuZCBob3Jpem9udGFsIChpLmUuLCAibm8tZ28iKSB0cmlhbHMsICpXKiA9IGByIHJvdW5kKGFzLm51bWVyaWMoZ25nX2Vycl9zaGFwX0gkc3RhdGlzdGljWyJXIl0pLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfc2hhcF9IJHAudmFsdWUpYCAqKHNlZSBjb2RlIGJlbG93KSouCgpgYGB7ciBzaG93X2duZ19lcnJfc2hhcF9WJkgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgZm9yIHZlcnRpY2FsL2dvIHRyaWFscwpnbmdfZXJyX3NoYXBfViA8LSBzaGFwaXJvLnRlc3QoZ25nX2Vycl9yZXNfViRyZXNpZHVhbHMpCmduZ19lcnJfc2hhcF9WCiMgZm9yIGhvcml6b250YWwvbm8tZ28gdHJpYWxzCmduZ19lcnJfc2hhcF9IIDwtIHNoYXBpcm8udGVzdChnbmdfZXJyX3Jlc19IJHJlc2lkdWFscykKZ25nX2Vycl9zaGFwX0gKYGBgCgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKLSAgIFRoZSBTa2V3bmVzcyBhbmQgS3VydG9zaXMgd2FzIGV4YW1pbmVkLiBGb3IgdGhlIHZlcnRpY2FsIGN1ZSB0eXBlLCBib3RoIHRoZSBTa2V3bmVzcyAocmFuZ2U6IGByIHJvdW5kKG1pbihhcy5udW1lcmljKGduZ19lcnJfc2tfdl90W2MoMSw0KSxdKSksIDIpYCB0byBgciByb3VuZChtYXgoYXMubnVtZXJpYyhnbmdfZXJyX3NrX3ZfdFtjKDEsNCksXSkpLCAyKWApIGFuZCBLdXJ0b3NpcyAocmFuZ2U6IGByIHJvdW5kKG1pbihhcy5udW1lcmljKGduZ19lcnJfc2tfdl90W2MoMiw1KSxdKSksIDIpYCB0byBgciByb3VuZChtYXgoYXMubnVtZXJpYyhnbmdfZXJyX3NrX3ZfdFtjKDIsNSksXSkpLCAyKWApIHdlcmUgb3V0c2lkZSBvZiB0aGUgYWNjZXB0YWJsZSByYW5nZSBvZiAkXHBtIDIuMCQgYW5kICRccG0gOS4wJCwgcmVzcGVjdGl2ZWx5IChTY2htaWRlciwgWmllZ2xlciwgRGFuYXksIEJleWVyLCAmIELDvGhuZXIsIDIwMTApLiBGb3IgdGhlIGhvcml6b250YWwgY3VlIHR5cGUsIGJvdGggdGhlIFNrZXduZXNzIChyYW5nZTogYHIgcm91bmQobWluKGFzLm51bWVyaWMoZ25nX2Vycl9za19oX3RbYygxLDQpLF0pKSwgMilgIHRvIGByIHJvdW5kKG1heChhcy5udW1lcmljKGduZ19lcnJfc2tfaF90W2MoMSw0KSxdKSksIDIpYCkgYW5kIEt1cnRvc2lzIChyYW5nZTogYHIgcm91bmQobWluKGFzLm51bWVyaWMoZ25nX2Vycl9za19oX3RbYygyLDUpLF0pKSwgMilgIHRvIGByIHJvdW5kKG1heChhcy5udW1lcmljKGduZ19lcnJfc2tfaF90W2MoMiw1KSxdKSksIDIpYCkgd2VyZSBvdXRzaWRlIG9mIHRoZSBhY2NlcHRhYmxlIHJhbmdlIG9mICRccG0gMi4wJCBhbmQgJFxwbSA5LjAkLCByZXNwZWN0aXZlbHkgKFNjaG1pZGVyLCBaaWVnbGVyLCBEYW5heSwgQmV5ZXIsICYgQsO8aG5lciwgMjAxMCkgKihzZWUgdGFibGUgYmVsb3cpKi4KPC9zdW1tYXJ5PgoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19nbmdfZXJyX3NrX3ZfdCZnbmdfZXJyX3NrX2hfdDIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyBOT1RFOiBzYW1lIHRhYmxlIGFzIGJlZm9yZSBwb3N0LWhvY3MKCiMgc2hvdyBhIHRhYmxlIG9mIHRoZSBza2V3bmVzcyAmIGt1cnRvc2lzIGZvciB0aGUgZ25nIGRhdGEsIHNlcGFyYXRlZCBieSBjdWUgdHlwZSAoaS5lLiBvbmUgZm9yIHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCB0cmlhbHMpCgojIGZvciB2ZXJ0aWNhbCBjdWUgdHlwZQojIHVzZSBrYWJsZSB0byBzaG93IHRoZSBkZXNjcmlwdGl2ZXMgdGFibGUKa2FibGUoZ25nX2Vycl9za192X3QsIGNhcHRpb24gPSAiU2tld25lc3MgYW5kIEt1cnRvc2lzIG9mIHRoZSBPbWlzc2lvbiBFcnJvcnMgb24gdGhlIEdvL05vLUdvIFRhc2sgZm9yICdHbycgKFZlcnRpY2FsKSBUcmlhbHMiLCBkaWdpdHMgPSAyLCBhbGlnbiA9ICdjJykgJT4lCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiwgIlNtYXJ0cGhvbmUgTG9jYXRpb24iID0gMyksIGJvbGQgPSBUKSAlPiUKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgUG93ZXIgT04iLCAxLCAzKSAlPiUgCiAgcGFja19yb3dzKCJTbWFydHBob25lIFBvd2VyIE9GRiIsIDQsIDYpICU+JQogIHJvd19zcGVjKDAsIGJvbGQgPSBUKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAga2FibGVfY2xhc3NpYygpCgojIGZvciBob3Jpem9udGFsIGN1ZSB0eXBlCiMgdXNlIGthYmxlIHRvIHNob3cgdGhlIGRlc2NyaXB0aXZlcyB0YWJsZQprYWJsZShnbmdfZXJyX3NrX2hfdCwgY2FwdGlvbiA9ICJTa2V3bmVzcyBhbmQgS3VydG9zaXMgb2YgdGhlIE9taXNzaW9uIEVycm9ycyBvbiB0aGUgR28vTm8tR28gVGFzayBmb3IgJ05vLUdvJyAoSG9yaXpvbmF0YWwpIFRyaWFscyIsIGRpZ2l0cyA9IDIsIGFsaWduID0gJ2MnKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiU21hcnRwaG9uZSBMb2NhdGlvbiIgPSAzKSwgYm9sZCA9IFQpICU+JQogIHBhY2tfcm93cygiU21hcnRwaG9uZSBQb3dlciBPTiIsIDEsIDMpICU+JSAKICBwYWNrX3Jvd3MoIlNtYXJ0cGhvbmUgUG93ZXIgT0ZGIiwgNCwgNikgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgotICAgVGhlcmVmb3JlLCBiYXNlZCBvbiBhbGwgdGhlIG5vcm1hbGl0eSBhc3N1bXB0aW9uIGNoZWNrcywgbm9ybWFsaXR5IHdhcyBub3QgYXNzdW1lZCB0byBiZSB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UsIGhvd2V2ZXIsIEFOT1ZBIHRlc3RzIGFyZSB0eXBpY2FsbHkgcm9idXN0IHRvIHZpb2xhdGlvbnMgb2Ygbm9ybWFsaXR5IChHYXJkbmVyICYgVHJlbWJsYXksIDIwMDcpLgoKWzMuIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlXXtzdHlsZT0iY29sb3I6IzRGMjY4MzsgZm9udC1zaXplOjE4cHg7In0KCi0gICBUaGlzIGFzc3VtcHRpb24gd2FzIHRlc3RlZCBieSBjb25kdWN0aW5nIExldmVuZSdzIFRlc3QgZm9yIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlIGZvciB2ZXJ0aWNhbCAoaS5lLiwgImdvIikgdHJpYWxzIGFuZCBob3Jpem9udGFsIChpLmUuLCAibm8tZ28iKSB0cmlhbHMuCgotICAgVGhlIGhvbW9nZW5laXR5IGFzc3VtcHRpb24gd2FzIG1ldCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSBmb3IgdGhlIGhvcml6b250YWwgKGkuZS4sICJuby1nbyIpIGN1ZSB0eXBlLCAqRiooYHIgZ25nX2Vycl9sZXZfSCREZlsxXWAsIGByIGduZ19lcnJfbGV2X0gkRGZbMl1gKSA9IGByIHJvdW5kKGduZ19lcnJfbGV2X0hbMl1bMSwxXSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfZXJyX2xldl9IWzNdWzEsMV0pYC4gSG93ZXZlciwgaXQgd2FzIG5vdCBtZXQgZm9yIHZlcnRpY2FsIChpLmUuLCAiZ28iKSBjdWUgdHlwZSwgKkYqKGByIGduZ19lcnJfbGV2X1YkRGZbMV1gLCBgciBnbmdfZXJyX2xldl9WJERmWzJdYCkgPSBgciByb3VuZChnbmdfZXJyX2xldl9WWzJdWzEsMV0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2Vycl9sZXZfVlszXVsxLDFdKWAsKihzZWUgY29kZSBiZWxvdykqLgoKYGBge3Igc2hvd19nbmdfZXJyX2xldl9WJkgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIGNvbmR1Y3QgbGV2ZW5lJ3MKICAjIGZvciBsb2NhdGlvbgogIGduZ19lcnJfbGV2X1YgPSBsZXZlbmVUZXN0KGRhdGEgPSBnbmdfZXJyX2Fub3ZhX2RhdGFfViwgZXJyX29taSB+IGFzLmZhY3Rvcihsb2NhdGlvbiksIGNlbnRlciA9IG1lYW4pCiAgZ25nX2Vycl9sZXZfVgogICMgZm9yIHBvd2VyCiAgZ25nX2Vycl9sZXZfSCA9IGxldmVuZVRlc3QoZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YV9ILCBlcnJfb21pIH4gYXMuZmFjdG9yKGxvY2F0aW9uKSwgY2VudGVyID0gbWVhbikKICBnbmdfZXJyX2xldl9ICgpgYGAKCjwvZGV0YWlscz4KCiMjIyMjIyBQSDogU01FIFJlc3VsdHMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpTaW5jZSB0aGUgaG9tb2dlbmVpdHkgYXNzdW1wdGlvbiB3YXMgbm90IG1ldCBmb3IgdGhlIHZlcnRpY2FsIChpLmUuLCAiZ28iKSBjdWUgdHlwZSBBTk9WQSwgYSBXaGl0ZS1jb3JyZWN0ZWQgRi10ZXN0IHdhcyBjb21wbGV0ZWQuIFRoZSBBTk9WQSBmb3IgdGhlIGhvcml6b250YWwgKGkuZS4sICJuby1nIikgY3VlIHR5cGUgd2FzIGNvbXBsZXRlZCB3aXRob3V0IGEgY29ycmVjdGlvbi4gQm90aCBBTk9WQXMgaGFkIGEgSG9sbS1Cb25mZXJyb25pIGFkanVzdG1lbnQuIFRoZSByZXN1bHRzIGZyb20gdGhpcyBhbmFseXNpcyBhcmUgc2hvd24gYmVsb3csIGZvbGxvd2VkIGJ5IGEgdGFibGUgZGVwaWN0aW5nIHRoZSBzdGF0aXN0aWNzICooY2xpY2sgdG8gc2VlIGNvZGUpKi4KCjwvc3VtbWFyeT4KClJ1biB0aGUgd2hpdGUtY29ycmVjdGVkIEFOT1ZBIGZvciB0aGUgdmVydGljYWwgKGkuZS4sICJnbyIpIGN1ZSB0eXBlIEFOT1ZBLiAKCmBgYHtyIGNyZWF0ZV9nbmdfZXJyX2Fub3ZhX1Zfd2hpdGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0UsIGVycm9yPUZBTFNFfQojIGNvbXBsZXRlIHdoaXRlLWNvcnIgQU5PVkEgZm9yIGIvdyBzdWIgZmFjdG9ycyAobG9jYXRpb24gJiBwb3dlcikKZ25nX2Vycl9hbm92YV9WX3doaXRlIDwtIAogIGV6QU5PVkEoZGF0YSA9IGduZ19lcnJfYW5vdmFfZGF0YV9WLCAKICAgICAgICAgIGR2ID0gLihlcnJfb21pKSwgCiAgICAgICAgICB3aWQgPSAuKHBhcnRpY2lwYW50KSwgCiAgICAgICAgICBiZXR3ZWVuID0gLihsb2NhdGlvbiksIAogICAgICAgICAgZGV0YWlsZWQgPSBUUlVFLCAKICAgICAgICAgIHR5cGUgPSAiSUlJIiwgIyBmb3IgdW5lcXVhbCBzYW1wbGUgc2l6ZXMKICAgICAgICAgIHJldHVybl9hb3YgPSBUUlVFLCAKICAgICAgICAgIHdoaXRlLmFkanVzdCA9IFRSVUUgIyBhZGQgd2hpdGUtY29ycmVjdGlvbgogICAgICAgICAgKQojIGNvbXB1dGUgZWZmZWN0IHNpemUKZ25nX2Vycl9hbm92YV9WX3doaXRlX2VzIDwtIEV0YVNxKGduZ19lcnJfYW5vdmFfVl93aGl0ZSRhb3YsIHR5cGUgPSAzLCBhbm92YSA9IEZBTFNFKQpgYGAKCkNvbXBsZXRlIHRoZSBIb2xtLUJvbmZlcnJvbmkgYWRqdXN0bWVudCBmb3IgYm90aCBBTk9WQXMuCmBgYHtyIGNyZWF0ZV9nbmdfZXJyX2Fub3ZhX2N1ZV9wYWRqfQojIGdldCBjb3JyZWN0ZWQgcC12YWx1ZXMgZm9yIGVhY2ggQU5PVkEKZ25nX2Vycl9hbm92YV9jdWVfcGFkaiA8LSAKICBwLmFkanVzdChjKGduZ19lcnJfYW5vdmFfVl93aGl0ZSRBTk9WQSRwWzJdLCAjIHAtdmFsdWUgZnJvbSB3aGl0ZS1jb3JyZWN0ZWQgVi9nbyBBTk9WQQogICAgICAgICAgICAgZ25nX2Vycl9hbm92YV9IJEFOT1ZBJHBbMl0pLCAjIHAtdmFsdWUgZnJvbSBIL25vLWdvIEFOT1ZBCiAgICAgICAgIG1ldGhvZCA9IGMoImhvbG0iKSwgIyBtZXRob2Q6IEhvbG0tQm9uZmVycm9uaQogICAgICAgICBuID0gMiAjIG51bWJlciBvZiBjb21wYXJpc29ucwogICAgICAgICApCgpgYGAKCjwvZGV0YWlscz4KCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpBbGwgcmVzdWx0cyB3ZXJlIGJhc2Ugb24gJFxhbHBoYSA9IDAuMDUkLiBCZWxvdyBhcmUgdGhlIHJlcG9ydGVkIHN0YXRpc3RpY3MgZm9yIHRoZSBtYWluIGVmZmVjdHMgZm9yIGVhY2ggU01FIEFOT1ZBLCBmb2xsb3dlZCBieSBhIHRhYmxlIGRlcGljdGluZyB0aGUgU01FIEFOT1ZBIHJlc3VsdHMgKihjbGljayB0byBzZWUgY29kZSkqLgoKCioqQ3VlIFR5cGU6ICJHbyIgLyBWZXJ0aWNhbCoqCgoqKipNYWluIEVmZmVjdCBvZiBTbWFydHBob25lIExvY2F0aW9uKioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiBvbiBvbWlzc2lvbiBlcnJvcnMgZm9yIHRoZSB2ZXJ0aWNhbC8iZ28iIGN1ZSB0eXBlLCAqRiooYHIgZ25nX2Vycl9hbm92YV9jdWVfdCRERm5bMV1gLCBgciBnbmdfZXJyX2Fub3ZhX2N1ZV90JERGZFsxXWApID0gYHIgcm91bmQoZ25nX2Vycl9hbm92YV9jdWVfdCRGWzFdLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfY3VlX3QkcFsxXSlgLCAkXGV0YV97R31eMiQgPSBgciBwX3JvdW5kKGduZ19lcnJfYW5vdmFfY3VlX3QkZ2VzWzFdKWAuCgoqKkN1ZSBUeXBlOiAiTm8tR28iIC8gSG9yaXpvbnRhbCoqCgoqKipNYWluIEVmZmVjdCBvZiBTbWFydHBob25lIExvY2F0aW9uKioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiBvbiBvbWlzc2lvbiBlcnJvcnMgZm9yIHRoZSBob3Jpem9udGFsLyJuby1nbyIgY3VlIHR5cGUsICpGKihgciBnbmdfZXJyX2Fub3ZhX2N1ZV90JERGblsyXWAsIGByIGduZ19lcnJfYW5vdmFfY3VlX3QkREZkWzJdYCkgPSBgciByb3VuZChnbmdfZXJyX2Fub3ZhX2N1ZV90JEZbMl0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV9jdWVfdCRwWzJdKWAsICRcZXRhX3tHfV4yJCA9IGByIHBfcm91bmQoZ25nX2Vycl9hbm92YV9jdWVfdCRnZXNbMl0pYC4KCioqUG9zdC1ob2MgVGVzdHMqKgoKU2luY2UgdGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IGZvciBlaXRoZXIgY3VlIHR5cGUsIG5vIHBvc3QtaG9jcyB3ZXJlIGNvbXBsZXRlZC4gCgo8L3N1bW1hcnk+CgpgYGB7ciBjcmVhdGVfZ25nX2Vycl9hbm92YV9jdWVfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjcmVhdGUgZGF0YSBmcmFtZSBmcm9tIG1peGVkIEFOT1ZBIHJlc3VsdHMgdG8gZGlzcGxheSAoaW5jbHVkaW5nIGJvdGggd2hpdGUtY29yciBmb3IgYi93IHN1YiBlZmZlY3RzKQpnbmdfZXJyX2Fub3ZhX2N1ZV90IDwtIAogIGRhdGEuZnJhbWUoImVmZmVjdCIgPSBjKGduZ19lcnJfYW5vdmFfVl93aGl0ZSRBTk9WQSRFZmZlY3RbMl0sIGduZ19lcnJfYW5vdmFfSCRBTk9WQSRFZmZlY3RbMl0pLCAKICAgICAgICAgICAgICJERm4iID0gYyhnbmdfZXJyX2Fub3ZhX1Zfd2hpdGUkQU5PVkEkREZuWzJdLCBnbmdfZXJyX2Fub3ZhX0gkQU5PVkEkREZuWzJdKSwgCiAgICAgICAgICAgICAiREZkIiA9IGMoZ25nX2Vycl9hbm92YV9WX3doaXRlJEFOT1ZBJERGZFsyXSwgZ25nX2Vycl9hbm92YV9IJEFOT1ZBJERGZFsyXSksIAogICAgICAgICAgICAgIkYiID0gYyhnbmdfZXJyX2Fub3ZhX1Zfd2hpdGUkQU5PVkEkRlsyXSwgZ25nX2Vycl9hbm92YV9IJEFOT1ZBJEZbMl0pLCAKICAgICAgICAgICAgICJwIiA9IGduZ19lcnJfYW5vdmFfY3VlX3BhZGosCiAgICAgICAgICAgICAicDwuMDUiID0gYyhnbmdfZXJyX2Fub3ZhX1Zfd2hpdGUkQU5PVkEkYHA8LjA1YFsyXSwgZ25nX2Vycl9hbm92YV9IJEFOT1ZBJGBwPC4wNWBbMl0pLCAKICAgICAgICAgICAgICJnZXMiID0gYyhnbmdfZXJyX2Fub3ZhX1Zfd2hpdGVfZXNbMl0sIGduZ19lcnJfYW5vdmFfSCRBTk9WQSRnZXNbMl0pCiAgICAgICAgICAgICApCiMgcmVuYW1lIHJvd3MKcm93bmFtZXMoZ25nX2Vycl9hbm92YV9jdWVfdCkgPSBOVUxMCmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc2hvd19nbmdfZXJyX2Fub3ZhX2N1ZV90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIHNob3cgQU5PVkEgcmVzdWx0cyBpbiBrYWJsZSB0YWJsZSAKa2FibGUoZ25nX2Vycl9hbm92YV9jdWVfdCwgY2FwdGlvbiA9ICJUZXN0cyBvZiBzaW1wbGUgbWFpbiBlZmZlY3RzIG9uIEdvL05vLUdvIG9taXNzaW9uIGVycm9ycyBmb3IgY3VlIHR5cGUgKGkuZS4sICdnbycgb3IgJ25vLWdvJykgYWNyb3NzIHNtYXJ0cGhvbmUgbG9jYXRpb24gbGV2ZWxzIChpLmUuLCBkZXNrLCBwb2NrZXQvYmFnLCBvdXRzaWRlKS4iLCBkaWdpdHMgPSA0LCBhbGlnbiA9ICdjJywgY29sLm5hbWVzID0gYygiRWZmZWN0IiwgIkRGbiIsICJERmQiLCAiRiIsICJwIiwgInAgPCAuMDUiLCAiZ2VzIikpICU+JQogIHJvd19zcGVjKDAsIGJvbGQgPSBUKSAlPiUgCiAgcGFja19yb3dzKCJDdWUgVHlwZTogJ0dvJyIsIDEsIDEpICU+JSAKICBwYWNrX3Jvd3MoIkN1ZSBUeXBlOiAnTm8tR28nIiwgMiwgMikgJT4lIAogIGZvb3Rub3RlKGdlbmVyYWwgPSAiTm90ZTogJ0dvJyBjdWUgdHlwZSBlZmZlY3Qgd2FzIFdoaXRlLWNvcnJlY3RlZC4gSG9sbS1Cb25mZXJyb25pIGFkanVzdGVkIHAtdmFsdWVzIGRlcGljdGVkLiIpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlX2NsYXNzaWMoKQpgYGAKCgojIyMjIyBWaXN1YWxpemF0aW9ucwoKVGhlIGZvbGxvd2luZyBzaG93cyBhIHZpc3VhbGl6YXRpb24gb2YgdGhlIEdvL05vLUdvIG9taXNzaW9uIGVycm9yIGRhdGEgYmFzZWQgb24gdGhlIHRocmVlIGZhY3RvcnM6IHNtYXJ0cGhvbmUgbG9jYXRpb24sIHNtYXJ0cGhvbmUgcG93ZXIsIGFuZCBjdWUgdHlwZS4gCgotIFRvIHZpc3VhbGl6ZSB0aGUgbWl4ZWQgZGVzaWduLCB0d28gcGxvdHMgd2VyZSBjcmVhdGVkIChpLmUuLCBvbmUgZm9yIGVhY2ggY3VlIHR5cGUpLgoKYGBge3IgZ25nX2Vycl9wbG90X3NlcGFyYXRlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBvdXQud2lkdGg9YygnNTAlJywgJzUwJScpLCBmaWcuc2hvdz0naG9sZCd9CiMtLUZPUiBUSEUgVkVSVElDQUwgQ1VFIFRZUEUtLSAKCiMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCBsb2NhdGlvbiBjb25kaXRpb25zIGFzIGNoYXJhY3RlcnMgcmF0aGVyIHRoYW4gaW50ZWdlcnMgCiAgIyBGaXJzdCwgZ2V0IGEgc3Vic2V0IG9mIHRoZSBkYXRhCiAgZ25nX2Vycl9iYXJfdl9kYXRhID0gZ25nX2Vycl9hbmFseXNpc1tnbmdfZXJyX2FuYWx5c2lzJGN1ZSA9PSAxLCBjKCJsb2NhdGlvbiIsICJwb3dlciIsICJnbmdfZXJyX29taV9sb25nIildCiAgICBjb2xuYW1lcyhnbmdfZXJyX2Jhcl92X2RhdGEpID0gYygibG9jYXRpb24iLCAicG93ZXIiLCAiZXJyX29taSIpCiAgICByb3duYW1lcyhnbmdfZXJyX2Jhcl92X2RhdGEpID0gTlVMTCAKICAjIHJlZm9ybWF0IGxvY2F0aW9uICYgcG93ZXIgYXMgZmFjdG9ycyAgCiAgZ25nX2Vycl9iYXJfdl9kYXRhJGxvY2F0aW9uID0gZmFjdG9yKGduZ19lcnJfYmFyX3ZfZGF0YSRsb2NhdGlvbiwgCiAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMSwgMiwgMyksCiAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk9uIERlc2siLCAiUG9ja2V0L0JhZyIsICJPdXRzaWRlIikpCiAgZ25nX2Vycl9iYXJfdl9kYXRhJHBvd2VyID0gZmFjdG9yKGduZ19lcnJfYmFyX3ZfZGF0YSRwb3dlciwgCiAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMSwgMiksCiAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk9OIiwgIk9GRiIpKQogICAgICAgCiMgY3JlYXRlIHBsb3QKZ25nX2Vycl9iYXJfdiA9IGdncGxvdChnbmdfZXJyX2Jhcl92X2RhdGEsIGFlcyh4ID0gbG9jYXRpb24sIHkgPSBlcnJfb21pLCBmaWxsID0gcG93ZXIpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gIm1lYW4iLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgCiAgICBndWlkZXMoc2hhcGUgPSBGQUxTRSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJjYWRldGJsdWUzIiwgImRlZXBza3libHVlNCIpKSArIAogIGxhYnModGl0bGUgPSAiUGVyZm9ybWFuY2Ugb24gdGhlIEdvL05vLUdvIFRhc2s6ICdWZXJ0aWNhbCcgQ3VlIFR5cGUiLAogICAgICAgc3VidGl0bGUgPSAiT21pc3Npb24gRXJyb3JzIiwKICAgICAgIHggPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsIAogICAgICAgeSA9ICJPbWlzc2lvbiBFcnJvciIsIAogICAgICAgZmlsbCA9ICJTbWFydHBob25lIFBvd2VyIiwKICAgICAgIGNhcHRpb24gPSBwYXN0ZTAoc3Ryd3JhcCgiRmlndXJlIFguIERpc3RyaWJ1dGlvbnMgb2Ygc2NvcmVzIG9uIHRoZSB2ZXJ0aWNhbCBjdWUgdHlwZSBvbiB0aGUgQ3VlLURlcGVuZGVudCBHby9Oby1HbyBUYXNrLCBhcnJhbmdlZCBieSBzbWFydHBob25lIGxvY2F0aW9uIChhbG9uZyB0aGUgeC1heGlzKSBhbmQgc21hcnRwaG9uZSBwb3dlciAoZGlmZmVyZW50IGJhcnMpLiBPbWlzc2lvbiBlcnJvcnMgb2NjdXJyZWQgd2hlbiBhIHBhcnRpY2lwYW50IGZhaWxlZCB0byByZXNwb25kIHRvIGEgbm9uLXRhcmdldCBzdGltdWx1cy4gQ29sb3VyZWQgZG90cyByZXByZXNlbnQgaW5kaXZpZHVhbCBkYXRhIHBvaW50cy4gQmxhY2sgZG90cyBhbmQgZXJyb3IgYmFycyBkZXBpY3QgbWVhbnMgYW5kIHN0YW5kYXJkIGVycm9ycywgcmVzcGVjdGl2ZWx5LiIsIHdpZHRoID0gODApLCBjb2xsYXBzZSA9ICJcbiIpKSArCiAgICAgICAgIyB0aGUgIlxuIiBoZXJlIGRlbm90ZSB0aGF0IHlvdSB3YW50IGEgbmV3IGxpbmUgZm9ybWVkIGluIHRoZSB0ZXh0CiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMobWluKGduZ19lcnJfYmFyX3ZfZGF0YSRlcnJfb21pKSwgbWF4KGduZ19lcnJfYmFyX3ZfZGF0YSRlcnJfb21pKSkpICsKICAjc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKGNvbG9yID0gcG93ZXIpLCBzaXplID0gMSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IC41MyksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGVlcHNreWJsdWU0IiwgInB1cnBsZTQiKSkgKyAKICBnZW9tX3BvaW50KHN0YXQ9InN1bW1hcnkiLCBmdW49Im1lYW4iLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKC45KSwgc2l6ZSA9IDEuNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoZGF0YSA9IGduZ19lcnJfYmFyX3ZfZGF0YSwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVubWluID0gZnVuY3Rpb24oeCkgbWVhbih4KSAtIHNkKHgpL3NxcnQobGVuZ3RoKHgpKSwgCiAgICAgICAgICAgICAgICBmdW5tYXggPSBmdW5jdGlvbih4KSBtZWFuKHgpICsgc2QoeCkvc3FydChsZW5ndGgoeCkpLCBzaXplPSAuNSwgd2lkdGg9IC4yNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSguOSkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEzKSwgCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDEyLCBmYWNlID0gIml0YWxpYyIpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzKSkKCiMtLUZPUiBUSEUgSE9SSVpPTlRBTCBDVUUgVFlQRS0tIAoKIyBjcmVhdGUgZGF0YSBmcmFtZSB3aXRoIGxvY2F0aW9uIGNvbmRpdGlvbnMgYXMgY2hhcmFjdGVycyByYXRoZXIgdGhhbiBpbnRlZ2VycyAKICAjIEZpcnN0LCBnZXQgYSBzdWJzZXQgb2YgdGhlIGRhdGEKICBnbmdfZXJyX2Jhcl9oX2RhdGEgPSBnbmdfZXJyX2FuYWx5c2lzW2duZ19lcnJfYW5hbHlzaXMkY3VlID09IDIsIGMoImxvY2F0aW9uIiwgInBvd2VyIiwgImduZ19lcnJfb21pX2xvbmciKV0KICAgIGNvbG5hbWVzKGduZ19lcnJfYmFyX2hfZGF0YSkgPSBjKCJsb2NhdGlvbiIsICJwb3dlciIsICJlcnJfb21pIikKICAgIHJvd25hbWVzKGduZ19lcnJfYmFyX2hfZGF0YSkgPSBOVUxMIAogICMgcmVmb3JtYXQgbG9jYXRpb24gJiBwb3dlciBhcyBmYWN0b3JzICAKICBnbmdfZXJyX2Jhcl9oX2RhdGEkbG9jYXRpb24gPSBmYWN0b3IoZ25nX2Vycl9iYXJfaF9kYXRhJGxvY2F0aW9uLCAKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAyLCAzKSwKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiT24gRGVzayIsICJQb2NrZXQvQmFnIiwgIk91dHNpZGUiKSkKICBnbmdfZXJyX2Jhcl9oX2RhdGEkcG93ZXIgPSBmYWN0b3IoZ25nX2Vycl9iYXJfaF9kYXRhJHBvd2VyLCAKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAyKSwKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiT04iLCAiT0ZGIikpCiAgICAgICAKIyBjcmVhdGUgcGxvdApnbmdfZXJyX2Jhcl9oID0gZ2dwbG90KGduZ19lcnJfYmFyX2hfZGF0YSwgYWVzKHggPSBsb2NhdGlvbiwgeSA9IGVycl9vbWksIGZpbGwgPSBwb3dlciksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX2JhcihzdGF0ID0gInN1bW1hcnkiLCBmdW4gPSAibWVhbiIsIHBvc2l0aW9uID0gImRvZGdlIikgKyAKICAgIGd1aWRlcyhzaGFwZSA9IEZBTFNFKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImNhZGV0Ymx1ZTMiLCAiZGVlcHNreWJsdWU0IikpICsgCiAgbGFicyh0aXRsZSA9ICJQZXJmb3JtYW5jZSBvbiB0aGUgR28vTm8tR28gVGFzazogJ0hvcml6b250YWwnIEN1ZSBUeXBlIiwKICAgICAgIHN1YnRpdGxlID0gIk9taXNzaW9uIEVycm9ycyIsCiAgICAgICB4ID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLCAKICAgICAgIHkgPSAiT21pc3Npb24gRXJyb3IiLCAKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBQb3dlciIsCiAgICAgICBjYXB0aW9uID0gcGFzdGUwKHN0cndyYXAoIkZpZ3VyZSBYLiBEaXN0cmlidXRpb25zIG9mIHNjb3JlcyBvbiB0aGUgaG9yaXpvbnRhbCBjdWUgdHlwZSBvbiB0aGUgQ3VlLURlcGVuZGVudCBHby9Oby1HbyBUYXNrLCBhcnJhbmdlZCBieSBzbWFydHBob25lIGxvY2F0aW9uIChhbG9uZyB0aGUgeC1heGlzKSBhbmQgc21hcnRwaG9uZSBwb3dlciAoZGlmZmVyZW50IGJhcnMpLiBPbWlzc2lvbiBlcnJvcnMgb2NjdXJyZWQgd2hlbiBhIHBhcnRpY2lwYW50IGZhaWxlZCB0byByZXNwb25kIHRvIGEgbm9uLXRhcmdldCBzdGltdWx1cy4gQ29sb3VyZWQgZG90cyByZXByZXNlbnQgaW5kaXZpZHVhbCBkYXRhIHBvaW50cy4gQmxhY2sgZG90cyBhbmQgZXJyb3IgYmFycyBkZXBpY3QgbWVhbnMgYW5kIHN0YW5kYXJkIGVycm9ycywgcmVzcGVjdGl2ZWx5LiIsIHdpZHRoID0gODApLCBjb2xsYXBzZSA9ICJcbiIpKSArCiAgICAgICAgIyB0aGUgIlxuIiBoZXJlIGRlbm90ZSB0aGF0IHlvdSB3YW50IGEgbmV3IGxpbmUgZm9ybWVkIGluIHRoZSB0ZXh0CiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMobWluKGduZ19lcnJfYmFyX2hfZGF0YSRlcnJfb21pKSwgbWF4KGduZ19lcnJfYmFyX2hfZGF0YSRlcnJfb21pKSkpICsKICAjc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKGNvbG9yID0gcG93ZXIpLCBzaXplID0gMSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IC41MyksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGVlcHNreWJsdWU0IiwgInB1cnBsZTQiKSkgKyAKICBnZW9tX3BvaW50KHN0YXQ9InN1bW1hcnkiLCBmdW49Im1lYW4iLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKC45KSwgc2l6ZSA9IDEuNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoZGF0YSA9IGduZ19lcnJfYmFyX2hfZGF0YSwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuLnltaW4gPSBmdW5jdGlvbih4KSBtZWFuKHgpIC0gc2QoeCkvc3FydChsZW5ndGgoeCkpLCAKICAgICAgICAgICAgICAgIGZ1bm1heCA9IGZ1bmN0aW9uKHgpIG1lYW4oeCkgKyBzZCh4KS9zcXJ0KGxlbmd0aCh4KSksIHNpemU9IC41LCB3aWR0aD0gLjI1LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKC45KSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTMpLCAKICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLCBzaXplID0gMTIsIGZhY2UgPSAiaXRhbGljIiksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMpKQoKIyBTaG93IHBsb3RzCiAgIyBmb3IgdGhlIFZlcnRpY2FsIGN1ZSB0eXBlCiAgZ25nX2Vycl9iYXJfdgogICMgZm9yIHRoZSBIb3Jpem9udGFsIGN1ZSB0eXBlCiAgZ25nX2Vycl9iYXJfaAogIAojIGV4cG9ydCBwbG90cwogICMgZm9yIHRoZSBWZXJ0aWNhbCBjdWUgdHlwZQogICMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfZ25nX2Vycl9iYXJfdiIsIHBsb3QgPSBnbmdfZXJyX2Jhcl92LCBkZXZpY2UgPSAicG5nIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDUwMCkKICAjIGZvciB0aGUgSG9yaXpvbnRhbCBjdWUgdHlwZQogICMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfZ25nX2Vycl9iYXJfaCIsIHBsb3QgPSBnbmdfZXJyX2Jhcl9oLCBkZXZpY2UgPSAicG5nIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDUwMCkKYGBgCgotIFNob3duIGFzIG9uZSBwbG90Li4uCgpgYGB7ciBnbmdfZXJyX3Bsb3RfdG9nZXRoZXIsIGVycm9yPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKIyBjcmVhdGUgZGF0YSBmcmFtZSB3aXRoIGxvY2F0aW9uIGNvbmRpdGlvbnMgYXMgY2hhcmFjdGVycyByYXRoZXIgdGhhbiBpbnRlZ2VycyAKZ25nX2Vycl9iYXJfZGF0YSA8LSAKICBnbmdfZXJyX2Fub3ZhX2RhdGEgJT4lIAogICMgbWFrZSBsb2NhdGlvbiBhIGZhY3RvcgogIG11dGF0ZShsb2NhdGlvbiA9IGZhY3Rvcihsb2NhdGlvbiwgbGV2ZWxzID0gYygxOjMpLCBsYWJlbHMgPSBjKCJEZXNrIiwgIlBvY2tldC9CYWciLCAiT3V0c2lkZSIpKSkgJT4lIAogICMgbWFrZSBwb3dlciBhIGZhY3RvcgogIG11dGF0ZShwb3dlciA9IGZhY3Rvcihwb3dlciwgbGV2ZWxzID0gYygxOjIpLCBsYWJlbHMgPSBjKCJPTiIsICJPRkYiKSkpICU+JSAKICAjIG1ha2UgY3VlIGEgZmFjdG9yCiAgbXV0YXRlKGN1ZSA9IGZhY3RvcihjdWUsIGxldmVscyA9IGMoMToyKSwgbGFiZWxzID0gYygiKEEpICdHbycgVHJpYWxzIiwgIihCKSAnTm8tR28nIFRyaWFscyIpKSkKCiMgY3JlYXRlIHBsb3QKZ25nX2Vycl9iYXIgPC0gCiAgZ2dwbG90KGduZ19lcnJfYmFyX2RhdGEsIGFlcyh4ID0gbG9jYXRpb24sIHkgPSBlcnJfb21pLCBmaWxsID0gcG93ZXIpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gIm1lYW4iLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgCiAgICBndWlkZXMoc2hhcGUgPSBGQUxTRSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJjYWRldGJsdWUzIiwgImRlZXBza3libHVlNCIpKSArIAogIGxhYnMoCiAgICAgICB0aXRsZSA9ICJQZXJmb3JtYW5jZSBvbiB0aGUgR28vTm8tR28gVGFzayIsCiAgICAgICBzdWJ0aXRsZSA9ICJPbWlzc2lvbiBFcnJvcnMiLAogICAgICAgY2FwdGlvbiA9IHBhc3RlMChzdHJ3cmFwKCJGaWd1cmUgWC4gRGlzdHJpYnV0aW9ucyBvZiBzY29yZXMgb24gdGhlIHZlcnRpY2FsIGN1ZSB0eXBlIG9uIHRoZSBDdWUtRGVwZW5kZW50IEdvL05vLUdvIFRhc2ssIGFycmFuZ2VkIGJ5IHNtYXJ0cGhvbmUgbG9jYXRpb24gKGFsb25nIHRoZSB4LWF4aXMpIGFuZCBzbWFydHBob25lIHBvd2VyIChkaWZmZXJlbnQgYmFycykuIE9taXNzaW9uIGVycm9ycyBvY2N1cnJlZCB3aGVuIGEgcGFydGljaXBhbnQgZmFpbGVkIHRvIHJlc3BvbmQgdG8gYSBub24tdGFyZ2V0IHN0aW11bHVzLiBDb2xvdXJlZCBkb3RzIHJlcHJlc2VudCBpbmRpdmlkdWFsIGRhdGEgcG9pbnRzLiBCbGFjayBkb3RzIGFuZCBlcnJvciBiYXJzIGRlcGljdCBtZWFucyBhbmQgc3RhbmRhcmQgZXJyb3JzLCByZXNwZWN0aXZlbHkuIiwgd2lkdGggPSA4MCksIGNvbGxhcHNlID0gIlxuIiksCiAgICAgICB4ID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLCAKICAgICAgIHkgPSAiT21pc3Npb24gRXJyb3IiLCAKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBQb3dlciIKICAgICAgICkgKwogICAgICAgICMgdGhlICJcbiIgaGVyZSBkZW5vdGUgdGhhdCB5b3Ugd2FudCBhIG5ldyBsaW5lIGZvcm1lZCBpbiB0aGUgdGV4dAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKG1pbihnbmdfZXJyX2Jhcl9kYXRhJGVycl9vbWkpLCBtYXgoZ25nX2Vycl9iYXJfZGF0YSRlcnJfb21pKSkpICsKICAjc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgYWVzKGNvbG9yID0gcG93ZXIpLCBzaXplID0gMSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IC41MyksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGVlcHNreWJsdWU0IiwgInB1cnBsZTQiKSkgKyAKICBnZW9tX3BvaW50KHN0YXQ9InN1bW1hcnkiLCBmdW49Im1lYW4iLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKC45KSwgc2l6ZSA9IDEuNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoZGF0YSA9IGduZ19lcnJfYmFyX2RhdGEsIHN0YXQgPSAic3VtbWFyeSIsIGZ1bm1pbiA9IGZ1bmN0aW9uKHgpIG1lYW4oeCkgLSBzZCh4KS9zcXJ0KGxlbmd0aCh4KSksIAogICAgICAgICAgICAgICAgZnVubWF4ID0gZnVuY3Rpb24oeCkgbWVhbih4KSArIHNkKHgpL3NxcnQobGVuZ3RoKHgpKSwgc2l6ZT0gLjUsIHdpZHRoPSAuMjUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoLjkpKSArCiAgZmFjZXRfd3JhcCh+Y3VlLCBuY29sID0gMikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTMpLCAKICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLCBzaXplID0gMTIsIGZhY2UgPSAiaXRhbGljIiksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMpKQojIHNob3cgcGxvdApnbmdfZXJyX2JhcgoKIyBleHBvcnQgcGxvdHMKIyBnZ3NhdmUoZmlsZW5hbWU9ImZpZ19nbmdfZXJyX2Jhcl9qdW5lMTYiLCBwbG90ID0gZ25nX2Vycl9iYXIsIGRldmljZSA9ICJqcGVnIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDEwMDApCmBgYAoKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgIyBpbnN0YWxsIHRoZSBwYWNrYWdlCiMgaW5zdGFsbC5wYWNrYWdlcygiZ2dzdGF0c3Bsb3QiKQojICMgTG9hZCB0aGUgcGFja2FnZQojIGxpYnJhcnkoZ2dzdGF0c3Bsb3QpICAKIyBnZ2JldHdlZW5zdGF0cyhnbmdfZXJyX2FuYWx5c2lzWyxjKCJjb25kaXRpb24iLCAiZ25nX2Vycl9vbWlfbG9uZyIpXSwgY29uZGl0aW9uLCBnbmdfZXJyX29taV9sb25nLCBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFKQpgYGAKCiMjIyMgQWNjdXJhY3kgQW5hbHlzaXMKCkEgKiozKHNtYXJ0cGhvbmUgbG9jYXRpb246IGRlc2ssIHBvY2tldC9iYWcsIG91dHNpZGUpIHggMihzbWFydHBob25lIHBvd2VyOiBPTiwgT0ZGKSoqIGJldHdlZW4tc3ViamVjdHMgQU5PVkEgd2FzIGNvbXBsZXRlZCAqKERWID0gYXZlcmFnZSBSVCkqLiBUaGUgYmV0d2Vlbi1zdWJqZWN0cyBmYWN0b3JzIHdlcmUgc21hcnRwaG9uZSBsb2NhdGlvbiBhbmQgcG93ZXIgKihjbGljayB0byBzZWUgY29kZSkqLgoKUHJpb3IgdG8gY29tcGxldGluZyB0aGUgYW5hbHlzaXMsIHBsYW5uZWQgZXhjbHVzaW9uIGNyaXRlcmEgd2FzIGFwcGxpZWQgdG8gdGhlIGRhdGEuIEV4Y2x1c2lvbiBjcml0ZXJpYSBmb3IgdGhpcyBhbmFseXNpcyBoZWxwZWQgdG8gY29udHJvbCBmb3IgYW55IHBhcnRpY2lwYW50cyB3aG8gZGlkIG5vdCBmb2xsb3cgdGhlIGluc3RydWN0aW9ucy4gQW55IHBhcnRpY2lwYW50cyB3aG8gaGFkIGEgcmVhY3Rpb24gdGltZSB0aGF0IHdhcyBoaWdoZXIgdGhhbiB0d28gc3RhbmRhcmQgZGV2aWF0aW9ucyAoU0QpIGZyb20gdGhlIG1lYW4gcmVhY3Rpb24gdGltZSB3ZXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgZmluYWwgYW5hbHlzaXMuIFZpZXcgdGhlIFtEYXRhIENsZWFuaW5nIHNlY3Rpb25dKCNhbGxfZGF0YV9EQykgdW5kZXIgdGhlIGRhdGEgW0NvbnN0cnVjdCBXb3JraW5nIERhdGFmcmFtZXNdKCNtYWtlREZzKSBoZWFkaW5nIGFib3ZlLiBUaGVyZSB3YXMgYSB0b3RhbCBvZiBgciBucm93KGduZ19hY19hbmFseXNpcylgIHBhcnRpY2lwYW50cyBpbiB0aGUgR28vTm8tR28gQWNjdXJhY3kgYW5hbHlzaXMuCgojIyMjIyBBbmFseXNpcwoKVG8gYXNzZXNzIGlmIHRoZSByZWFjdGlvbiB0aW1lIHN0YXRpc3RpY2FsbHkgZGlmZmVyZWQsIHdlIGNvbmR1Y3RlZCBhIDN4MiBBTk9WQSB3aXRoIHRoZSBiZXR3ZWVuLXN1YmplY3RzIGZhY3RvcnMgb2Ygc21hcnRwaG9uZSBsb2NhdGlvbiAoaS5lLiwgb24gZGVzaywgaW4gcG9ja2V0L2JhZywgb3Igb3V0c2lkZSkgYW5kIHBvd2VyIChpLmUuLCBvbiBvciBvZmYpLiBTaW5jZSB0aGVyZSBhcmUgdW5lcXVhbCBzYW1wbGUgc2l6ZXMsIHdlIHVzZWQgVHlwZSBJSUkgc3VtIG9mIHNxdWFyZXMuCgojIyMjIyMgQXNzdW1wdGlvbnMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpUaGUgQU5PVkEgbWFkZSB0aHJlZSBhc3N1bXB0aW9uczogaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsaW5nLCBub3JtYWxpdHksIGFuZCBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZS4gTm9ybWFsaXR5IHdhcyBtZXQgYnV0IHRoZXJlIHdhcyBhIHNsaWdodCBza2V3IHRvIHRoZSByaWdodCBpbiB0aGUgaGlzdG9ncmFtIGFuZCBrdXJ0b3NpcyB3YXMgb3V0c2lkZSBvZiB0aGUgdHlwaWNhbCByYW5nZSwgaG93ZXZlciwgQU5PVkEgdGVzdHMgYXJlIHR5cGljYWxseSByb2J1c3QgdG8gdmlvbGF0aW9ucyBvZiBub3JtYWxpdHkgKEdhcmRuZXIgJiBUcmVtYmxheSwgMjAwNykuICooY2xpY2sgdG8gc2VlIGRldGFpbHMpKi4KCjwvc3VtbWFyeT4KClsxLiBJbmRlcGVuZGVudCBSYW5kb20gU2FtcGxpbmdde3N0eWxlPSJjb2xvcjojNEYyNjgzOyBmb250LXNpemU6MThweDsifQoKVGhpcyBhc3N1bXB0aW9uIHdhcyBtZXQgZHVyaW5nIHRlc3RpbmcuCgpbMi4gTm9ybWFsaXR5XXtzdHlsZT0iY29sb3I6IzRGMjY4MzsgZm9udC1zaXplOjE4cHg7In0KClRoaXMgYXNzdW1wdGlvbiB3YXMgdGVzdGVkIGJ5IHZpc3VhbGl6aW5nIHRoZSByZXNpZHVhbHMsIGFwcGx5aW5nIGEgU2hhcGlyby1XaWxrIHRlc3QgdG8gdGhlIHJlc2lkdWFscywgYW5kIG9ic2VydmluZyB0aGUgU2tld25lc3MgYW5kIEt1cnRvc2lzIG9mIHRoZSBkYXRhICooZXh0cmFjdGVkIGZyb20gdGhlIEFOT1ZBIG91dHB1dCkuKgoKYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBnZXQgdGhlIHJlcXVpcmVkIGRhdGEgZnJvbSB0aGUgb3NwYW5fYW5hbHlzaXMgZGF0YTogcGFydGljaXBhbnQsIGxvY2F0aW9uLCBwb3dlciwgYW5kIHNjb3JlCmduZ19hY19hbm92YV9kYXRhIDwtIGduZ19hY19hbmFseXNpc1ssIGMoInBhcnRpY2lwYW50IiwgImxvY2F0aW9uIiwgInBvd2VyIiwgImduZ19ydF9hdiIpXQogICAgY29sbmFtZXMoZ25nX2FjX2Fub3ZhX2RhdGEpID0gYygicGFydGljaXBhbnQiLCAibG9jYXRpb24iLCAicG93ZXIiLCAicnRfYXYiKQogICAgcm93bmFtZXMoZ25nX2FjX2Fub3ZhX2RhdGEpID0gTlVMTAogICAgIyByZWZvcm1hdCBsb2NhdGlvbiwgIHBvd2VyLCBhbmQgYmFsYW5jZSBhcyBmYWN0b3JzICAKICAgIGduZ19hY19hbm92YV9kYXRhJGxvY2F0aW9uID0gZmFjdG9yKGduZ19hY19hbm92YV9kYXRhJGxvY2F0aW9uLCAKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAyLCAzKSwKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiT24gRGVzayIsICJQb2NrZXQvQmFnIiwgIk91dHNpZGUiKSkKICAgIGduZ19hY19hbm92YV9kYXRhJHBvd2VyID0gZmFjdG9yKGduZ19hY19hbm92YV9kYXRhJHBvd2VyLCAKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAyKSwKICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiT04iLCAiT0ZGIikpCgojIHJ1biBiZXR3ZWVuLXN1YmplY3RzIEFOT1ZBIChJVjogU21hcnRwaG9uZSBQb3dlciAmIExvY2F0aW9uLCBCYWxhbmNlOyBEVjogT1NwYW4gQWJvbHV0ZSBTY29yZSkKZ25nX2FjX2Fub3ZhID0gZXpBTk9WQSgKICBkYXRhID0gZ25nX2FjX2Fub3ZhX2RhdGEKICAsIGR2ID0gLihydF9hdikKICAsIHdpZCA9IC4ocGFydGljaXBhbnQpCiAgLCBiZXR3ZWVuID0gLihsb2NhdGlvbiwgcG93ZXIpCiAgLCB0eXBlID0gMyAjIHVuZXF1YWwgc2FtcGxlIHNpemVzLCB0aGVyZm9yZSB1c2UgdHlwZSAzCiAgLCBkZXRhaWxlZCA9IFRSVUUKICAsIHJldHVybl9hb3YgPSBUUlVFCikKCiMgY2FsY3VsYXRlICYgZXh0cmFjdCB0aGUgcmVzaWR1YWxzIGZyb20gdGhlIEFOT1ZBCmduZ19hY19yZXMgPC0gZGF0YS5mcmFtZSgicmVzaWR1YWxzIiA9IHByb2ooZ25nX2FjX2Fub3ZhJGFvdilbLCJSZXNpZHVhbHMiXSkgICAKYGBgCgotICAgSXQgYXBwZWFycyB0aGF0IHRoZSByZXNpZHVhbHMgbGllIGNsb3NlbHkgdG8gYSBzdHJhaWdodCBsaW5lLCB3aGljaCBzdWdnZXN0cyBub3JtYWxpdHkgKihzZWUgdmlzdWFsaXphdGlvbiBiZWxvdykqLgoKYGBge3J9CgpxcW5vcm0oZ25nX2FjX3JlcyRyZXNpZHVhbHMsIG1haW4gPSAiUS1RIFBsb3Qgb2YgdGhlIEdvL05vLUdvIFJlYWN0aW9uIFRpbWUgUmVzaWR1YWxzIikgCnFxbGluZShnbmdfYWNfcmVzJHJlc2lkdWFscykKCmBgYAoKLSAgIEl0IGFwcGVhcnMgdGhhdCByZXNpZHVhbHMgdGVuZCB0byBmb2xsb3cgdGhlIHNoYXBlIG9mIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgd2l0aCBhIHNsaWdodCBza2V3IHRvIHRoZSByaWdodCBhbmQgc29tZSBkYXRhIG9uIHRoZSBmYXIgcmlnaHQgKihzZWUgdmlzdWFsaXphdGlvbiBiZWxvdykqLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnFwbG90KGduZ19hY19yZXMkcmVzaWR1YWxzLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBHby9Oby1HbyBSZWFjdGlvbiBUaW1lIFJlc2lkdWFscyIsIGJpbndpZHRoID0gLjAxKSArIAogIHRoZW1lX2NsYXNzaWMoKQoKYGBgCgotICAgVGhlIFNoYXBpcm8tV2lsayB0ZXN0IG9mIG5vcm1hbGl0eSB3YXMgc2lnbmlmaWNhbnQgKGJhc2VkIG9uICRcYWxwaGEgPSAwLjA1JCksICpXKiA9IGByIHJvdW5kKGFzLm51bWVyaWMoZ25nX2FjX3NoYXAkc3RhdGlzdGljWyJXIl0pLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19hY19zaGFwJHAudmFsdWUpYCAqKHNlZSBjb2RlIGJlbG93KSouCgpgYGB7cn0KCmduZ19hY19zaGFwID0gc2hhcGlyby50ZXN0KGduZ19hY19yZXMkcmVzaWR1YWxzKQpnbmdfYWNfc2hhcAoKYGBgCgotICAgVGhlIGRhdGEncyBTa2V3bmVzcyBhbmQgS3VydG9zaXMgd2FzIGV4YW1pbmVkIGFuZCBzaG93ZWQgdGhhdCB0aGUgU2tld25lc3MgKHJhbmdlOiBgciByb3VuZChtaW4oYXMubnVtZXJpYyhnbmdfYWNfc2tfdFtjKDEsNCksXSkpLCAyKWAgdG8gYHIgcm91bmQobWF4KGFzLm51bWVyaWMoZ25nX2FjX3NrX3RbYygxLDQpLF0pKSwgMilgKSB3YXMgd2l0aGluIHRoZSBhY2NlcHRhYmxlIHJhbmdlIG9mICRccG0gMi4wJCAoU2NobWlkZXIsIFppZWdsZXIsIERhbmF5LCBCZXllciwgJiBCw7xobmVyLCAyMDEwKS4gRm9yIHRoZSBLdXJ0b3NpcywgdGhlIG9uIGRlc2svcG93ZXJlZCBvZmYgY29uZGl0aW9uIHdhcyBvdXRzaWRlIHRoZSBhY2NlcHRhYmxlIHJhbmdlIG9mICRccG0gOS4wJCAoU2NobWlkZXIsIFppZWdsZXIsIERhbmF5LCBCZXllciwgJiBCw7xobmVyLCAyMDEwOyBvdmVyYWxsIHJhbmdlOiBgciByb3VuZChtaW4oYXMubnVtZXJpYyhnbmdfYWNfc2tfdFtjKDIsNSksXSkpLCAyKWAgdG8gYHIgcm91bmQobWF4KGFzLm51bWVyaWMoZ25nX2FjX3NrX3RbYygyLDUpLF0pKSwgMilgKSAqKHNlZSB0YWJsZSBiZWxvdykqLgoKYGBge3J9CiMgdXNlIHRoZSAiZ25nX2FjX2RlcyIgZGF0YSBmcmFtZSBmcm9tIHRoZSBkZXNjcmlwdGl2ZXMKCiMgb3JnYW5pemUgdGhlIGRhdGEgaW50byBhIG5ldyBkYXRhIGZyYW1lIGRlcGljdGluZyB0aGUgU2tldywga3VydG9zaXMsIGFuZCBzYW1wbGUgc2l6ZSAobikuCiAgZ25nX2FjX3NrX3QgPSByYmluZCgoY2JpbmQodChkZXNfdGFza19jb250WyJnbmdfcnRfYXYxIiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KGRlc190YXNrX2NvbnRbImduZ19ydF9hdjIiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udFsiZ25nX3J0X2F2MyIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSkpKSwgCiAgICAgICAgICAgICAgICAgICAgICAoY2JpbmQodChkZXNfdGFza19jb250WyJnbmdfcnRfYXY0IiwgYygic2tldyIsICJrdXJ0b3NpcyIsICJuIildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KGRlc190YXNrX2NvbnRbImduZ19ydF9hdjUiLCBjKCJza2V3IiwgImt1cnRvc2lzIiwgIm4iKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoZGVzX3Rhc2tfY29udFsiZ25nX3J0X2F2NiIsIGMoInNrZXciLCAia3VydG9zaXMiLCAibiIpXSkpKSkKICAgIGNvbG5hbWVzKGduZ19hY19za190KSA9IGMoIk9uIERlc2siLCAiSW4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIikKICAgIHJvd25hbWVzKGduZ19hY19za190KSA9IHJlcChjKCJTa2V3bmVzcyIsICJLdXJ0b3NpcyIsICJuIiksIDIpCiAgICAKIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgZGVzY3JpcHRpdmVzIHRhYmxlCiAga2FibGUoZ25nX2FjX3NrX3QsIGNhcHRpb24gPSAiU2tld25lc3MgYW5kIEt1cnRvc2lzIG9mIHRoZSBSZWFjdGlvbiBUaW1lIG9uIHRoZSBHby9Oby1HbyBUYXNrIiwgZGlnaXRzID0gMiwgYWxpZ24gPSAnYycpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiU21hcnRwaG9uZSBMb2NhdGlvbiIgPSAzKSkgJT4lCiAgcGFja19yb3dzKCJTbWFydHBob25lIFBvd2VyIE9OIiwgMSwgMykgJT4lIAogIHBhY2tfcm93cygiU21hcnRwaG9uZSBQb3dlciBPRkYiLCA0LCA2KSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKCmBgYAoKLSAgIFRoZXJlZm9yZSwgYmFzZWQgb24gYWxsIHRoZSBub3JtYWxpdHkgYXNzdW1wdGlvbiBjaGVja3MsIG5vcm1hbGl0eSB3YXMgYXNzdW1lZCB0byBiZSB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UgZm9yIHRoZSBBTk9WQSBhbmFseXNpcy4gQWx0aG91Z2ggdGhlcmUgd2FzIGEgc2xpZ2h0IHNrZXcgdG8gdGhlIHJpZ2h0IGluIHRoZSBoaXN0b2dyYW0gYW5kIGt1cnRvc2lzIHdhcyBvdXRzaWRlIG9mIHRoZSB0eXBpY2FsIHJhbmdlLCB1bHRpbWF0ZWx5LCBBTk9WQSB0ZXN0cyBhcmUgdHlwaWNhbGx5IHJvYnVzdCB0byB2aW9sYXRpb25zIG9mIG5vcm1hbGl0eSAoR2FyZG5lciAmIFRyZW1ibGF5LCAyMDA3KS4KClszLiBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZV17c3R5bGU9ImNvbG9yOiM0RjI2ODM7IGZvbnQtc2l6ZToxOHB4OyJ9CgpUaGlzIGFzc3VtcHRpb24gd2FzIHRlc3RlZCBieSBjb25kdWN0aW5nIExldmVuZSdzIFRlc3QgZm9yIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlIGZvciBlYWNoIGJldHdlZW4tc3ViamVjdHMgdmFyaWFibGUgKGkuZS4gc21hcnRwaG9uZSBsb2NhdGlvbiBhbmQgc21hcnRwaG9uZSBwb3dlcikuCgotICAgVGhlIGhvbW9nZW5laXR5IGFzc3VtcHRpb24gd2FzIG1ldCAoYmFzZWQgb24gJFxhbHBoYSA9IDAuMDUkKSBmb3Igc21hcnRwaG9uZSBsb2NhdGlvbiwgKkYqKGByIGduZ19hY19sZXZfbG9jJERmWzFdYCwgYHIgZ25nX2FjX2xldl9sb2MkRGZbMl1gKSA9IGByIHJvdW5kKGduZ19hY19sZXZfbG9jWzJdWzEsMV0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2FjX2xldl9sb2NbM11bMSwxXSlgIGFuZCBzbWFydHBob25lIHBvd2VyLCAqRiooYHIgZ25nX2FjX2xldl9wb3ckRGZbMV1gLCBgciBnbmdfYWNfbGV2X3BvdyREZlsyXWApID0gYHIgcm91bmQoZ25nX2FjX2xldl9wb3dbMl1bMSwxXSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfYWNfbGV2X3Bvd1szXVsxLDFdKWAgKihzZWUgY29kZSBiZWxvdykqLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgY29uZHVjdCBsZXZlbmUncwogICMgZm9yIGxvY2F0aW9uCiAgZ25nX2FjX2xldl9sb2MgPSBsZXZlbmVUZXN0KGRhdGEgPSBnbmdfYWNfYW5vdmFfZGF0YSwgcnRfYXYgfiBhcy5mYWN0b3IobG9jYXRpb24pLCBjZW50ZXIgPSBtZWRpYW4pCiAgZ25nX2FjX2xldl9sb2MKICAjIGZvciBwb3dlcgogIGduZ19hY19sZXZfcG93ID0gbGV2ZW5lVGVzdChkYXRhID0gZ25nX2FjX2Fub3ZhX2RhdGEsIHJ0X2F2IH4gYXMuZmFjdG9yKHBvd2VyKSwgY2VudGVyID0gbWVkaWFuKQogIGduZ19hY19sZXZfcG93CmBgYAoKLSAgIFRoZSBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZSBhc3N1bXB0aW9uIHdhcyBtZXQuIEJhc2VkIG9uIGFsbCB0aGUgbm9ybWFsaXR5IGFzc3VtcHRpb24gY2hlY2tzLCBub3JtYWxpdHkgd2FzIGFzc3VtZWQgdG8gYmUgd2l0aGluIHRoZSBhY2NlcHRhYmxlIHJhbmdlIGZvciB0aGUgQU5PVkEgYW5hbHlzaXMuIEFkZGl0aW9uYWxseSwgaXQgc2hvdWxkIGJlIG5vdGVkIHRoYXQgQU5PVkEgYW5hbHlzZXMgY2FuIGJlIHJvYnVzdCB0byB2aW9sYXRpb25zIG9mIG5vcm1hbGl0eSAoR2FyZG5lciAmIFRyZW1ibGF5LCAyMDA3KS4KCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMjIE5PVCBTSE9XTiAtLSB0aGlzIHdvdWxkIHJ1biB3LyBhIHdoaXRlIGNvcnJlY3Rpb24gaWYgaG9tbyBub3QgbWV0Li4uIAoKIyBydW4gdGhlIGNvcnJlY3RlZCBBTk9WQSAoSVY6IFNtYXJ0cGhvbmUgUG93ZXIgJiBMb2NhdGlvbiwgQmFsYW5jZTsgRFY6IE9TcGFuIEFib2x1dGUgU2NvcmUpCiMgdGhpcyB3aWxsIGJlIHVzZWQgdG8gcmVwb3J0IHRoZSBtYWluIGVmZmVjdCBvZiBzbWFydHBob25lIHBvd2VyIG9ubHkgCiMgZ25nX2FjX2Fub3ZhX2NvciA9IGV6QU5PVkEoCiMgICBkYXRhID0gZ25nX2FjX2Fub3ZhX2RhdGEKIyAgICwgZHYgPSAuKHJ0X2F2KQojICAgLCB3aWQgPSAuKHBhcnRpY2lwYW50KQojICAgLCBiZXR3ZWVuID0gLihsb2NhdGlvbiwgcG93ZXIpCiMgICAsIHR5cGUgPSAzICMgdW5lcXVhbCBzYW1wbGUgc2l6ZXMsIHRoZXJmb3JlIHVzZSB0eXBlIDMKIyAgICwgZGV0YWlsZWQgPSBUUlVFCiMgICAsIHJldHVybl9hb3YgPSBUUlVFCiMgICAsIHdoaXRlLmFkanVzdCA9IEYKIyApCgojIENhbGN1bGF0ZSBlZmZlY3Qgc2l6ZToKIyB0aGlzIHdpbGwgYmUgdXNlZCB0byByZXBvcnQgdGhlIG1haW4gZWZmZWN0IG9mIHNtYXJ0cGhvbmUgcG93ZXIgb25seSAKIyBnbmdfYWNfcG93X2VzID0gKEV0YVNxKGduZ19hY19hbm92YSRhb3YsIHR5cGUgPSAzLCBhbm92YSA9IEZBTFNFKSlbMl0KYGBgCgo8L2RldGFpbHM+CgojIyMjIyMgUmVzdWx0cwoKQWxsIHJlc3VsdHMgd2VyZSBiYXNlZCBvbiAkXGFscGhhID0gMC4wNSQuIEJlbG93IGFyZSB0aGUgcmVwb3J0ZWQgc3RhdGlzdGljcyBmb3IgdGhlIG1haW4gZWZmZWN0cyBhbmQgdGhlIGludGVyYWN0aW9ucywgZm9sbG93ZWQgYnkgYSB0YWJsZSBkZXBpY3RpbmcgdGhlIEFOT1ZBIHJlc3VsdHMuCgoqKk1haW4gRWZmZWN0IG9mIFNtYXJ0cGhvbmUgTG9jYXRpb24qKgoKVGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIHNtYXJ0cGhvbmUgbG9jYXRpb24gb24gcmVhY3Rpb24gdGltZSwgKkYqKGByIGduZ19hY190WzIsMl1gLCBgciBnbmdfYWNfdFsyLDNdYCkgPSBgciByb3VuZChnbmdfYWNfdFsyLDRdLCAyKWAsICpwKiBgciBwX3JvdW5kKGduZ19hY190WzIsNV0pYCwgJFxldGFeezJ9JCBgciBwX3JvdW5kKGduZ19hY190WzIsN10pYC4KCioqTWFpbiBFZmZlY3Qgb2YgU21hcnRwaG9uZSBQb3dlcioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2Ygc21hcnRwaG9uZSBwb3dlciBvbiByZWFjdGlvbiB0aW1lLCAqRiooYHIgZ25nX2FjX3RbMywyXWAsIGByIGduZ19hY190WzMsM11gKSA9IGByIHJvdW5kKGduZ19hY190WzMsNF0sIDIpYCwgKnAqIGByIHBfcm91bmQoZ25nX2FjX3RbMyw1XSlgLCAkXGV0YV57Mn0kIGByIHBfcm91bmQoZ25nX2FjX3RbMyw3XSlgLgoKKipJbnRlcmFjdGlvbiBvZiBTbWFydHBob25lIExvY2F0aW9uICYgU21hcnRwaG9uZSBQb3dlcioqCgpUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBzbWFydHBob25lIGxvY2F0aW9uIGFuZCBzbWFydHBob25lIHBvd2VyIG9uIHJlYWN0aW9uIHRpbWUsICpGKihgciBnbmdfYWNfdFs0LDJdYCwgYHIgZ25nX2FjX3RbNCwzXWApID0gYHIgcm91bmQoZ25nX2FjX3RbNCw0XSwgMilgLCAqcCogYHIgcF9yb3VuZChnbmdfYWNfdFs0LDVdKWAsICRcZXRhXnsyfSQgYHIgcF9yb3VuZChnbmdfYWNfdFs0LDddKWAuCgoqKlBvc3QtaG9jIFRlc3RzKioKClNpbmNlIHRoZXJlIHdhcyBhIHNpZ25pZmljYW50IHRocmVlLXdheSBpbnRlcmFjdGlvbiAoaS5lIHNtYXJ0cGhvbmUgbG9jYXRpb24sIHNtYXJ0cGhvbmUgcG93ZXIsIGFuZCBiYWxhbmNlKSwgZnVydGhlciBhbmFseXNlcyB3ZXJlIGNvbXBsZXRlZCAqKHNlZSAiUG9zdC1Ib2NzOiBTaW1wbGUgVHdvLVdheSBJbnRlcmFjdGlvbnMiIGJlbG93KSouCgpgYGB7cn0KIyBjcmVhdGUgdGFibGUgZnJvbSBBTk9WQSByZXN1bHRzCmduZ19hY190IDwtIGduZ19hY19hbm92YSRBTk9WQQoKIyBzaG93IEFOT1ZBIHJlc3VsdHMgaW4ga2FibGUgdGFibGUgCmthYmxlKGduZ19hY19hbm92YSRBTk9WQSwgY2FwdGlvbiA9ICIzeDIgQU5PVkEgb24gQXZlcmFnZSBSZWFjdGlvbiBUaW1lIGluIHRoZSBHby9Oby1HbyBUYXNrIiwgZGlnaXRzID0gMywgYWxpZ24gPSAnYycpICU+JQogIHJvd19zcGVjKDAsIGJvbGQgPSBUKSAlPiUgCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JSAKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIyBOT1QgU0hPV04gLS0gZG8gaWYgaG9tbyBub3QgbWV0Li4uIAoKIyAjIGNyZWF0ZSBhIHRhYmxlIHdpdGggdGhlIGFub3ZhIHJlc3VsdHMgaW5jbHVkaW5nIHRoZSBjb3JyZWN0ZWQgdmFsdWVzIGZvciB0aGUgbWFpbiBlZmZlY3Qgb2YgcG93ZXIgKGkuZS4gc2luY2UgaXQgZGlkIG5vdCBtZWV0IHRoZSBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZSBhc3N1bXB0aW9uKQojICAgIyBnZXQgdGhlIG9yaWdpbmFsIGFub3ZhIGRhdGEKIyAgIGduZ19hY190ID0gZ25nX2FjX2Fub3ZhJEFOT1ZBCiMgICAgICMgc2luY2UgdGhlIGNvcnJlY3RlZCBkYXRhIGRvZXMgbm90IGhhdmUgdGhlIFNTLCByZW1vdmUgdGhlc2UgY29sdW1ucyBmcm9tIHRoZSBvcmlnaW5hbCBBTk9WQSB0YWJsZQojICAgICBnbmdfYWNfdCA9IGRwbHlyOjpzZWxlY3QoZ25nX2FjX3QsIC1TU24sIC1TU2QpCiMgICAgICMgY2hhbmNlIHRoZSBkYXRhIGZvciB0aGUgbWFpbiBlZmZlY3Qgb2YgcG93ZXIgdG8gY29ycmVjdGVkIG51bWJlcnMKIyAgICAgZ25nX2FjX3RbZ25nX2FjX3QkRWZmZWN0ID09ICJwb3dlciIsXSA9IGMoZ25nX2FjX2Fub3ZhX2NvciRBTk9WQVszLF0sIGduZ19hY19wb3dfZXMpCiMgIyBzaG93IEFOT1ZBIHJlc3VsdHMgaW4ga2FibGUgdGFibGUgCiMga2FibGUoZ25nX2FjX3QsIGNhcHRpb24gPSAiM3gyeDIgQU5PVkEgb24gR28vTm8tR28gUmVhY3Rpb24gVGltZSIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnKSAlPiUKIyAgIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUgCiMgICBrYWJsZV9jbGFzc2ljKCkKYGBgCgojIyMjIyBWaXN1YWxpemF0aW9ucwoKVGhlIGZvbGxvd2luZyBzaG93cyBhIHZpc3VhbGl6YXRpb24gb2YgQWNjdXJhY3kgKGkuZS4gcmVhY3Rpb24gdGltZSkgb24gdGhlIEN1ZS1EZXBlbmRlbnQgR28vTm8tZ28gVGFzay4gVGhlcmUgd2FzIG5vIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIHNtYXJ0cGhvbmUgbG9jYXRpb24gb3Igc21hcnRwaG9uZSBwb3dlciBhbmQgbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBzbWFydHBob25lIGxvY2F0aW9uIGFuZCBwb3dlci4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgRmlyc3QsIGdldCBhIHN1YnNldCBvZiB0aGUgZGF0YQpnbmdfYWNfYmFyX2RhdGEgPC0gCiAgZ25nX2FjX2Fub3ZhX2RhdGEgJT4lIAogIHNlbGVjdCgtcGFydGljaXBhbnQpIAojICU+JSAKIyAgIG11dGF0ZShsb2NhdGlvbiA9IGZhY3Rvcihsb2NhdGlvbiwgbGFiZWxzID0gYygiT24gRGVzayIsICJQb2NrZXQvQmFnIiwgIk91dHNpZGUiKSkpICMgZGlkbnQgbmVlZCB0aGlzLCBpdHMgYWxyZWFkeSBhIGZhY3Rvci4uLiAKICAKIyByZW1vdmUgcm93IG5hbWVzCnJvd25hbWVzKGduZ19hY19iYXJfZGF0YSkgPC0gTlVMTAoKIyBwbG90IGJhciBncmFwaApnbmdfYWNfYmFyIDwtIAogIGdncGxvdChnbmdfYWNfYmFyX2RhdGEsIGFlcyh4ID0gbG9jYXRpb24sIHkgPSBydF9hdiwgZmlsbCA9IHBvd2VyKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9ICJtZWFuIiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArIAogICAgZ3VpZGVzKHNoYXBlID0gRkFMU0UpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiY2FkZXRibHVlMyIsICJkZWVwc2t5Ymx1ZTQiKSkgKyAKICBsYWJzKAogICAgICAgdGl0bGUgPSAiUGVyZm9ybWFuY2Ugb24gdGhlIEdvL05vLUdvIFRhc2sgXG5mb3IgdGhlIE9TcGFuIEZpcnN0IEJhbGFuY2UgQ29uZGl0aW9uIiwKICAgICAgIHN1YnRpdGxlID0gIkFjY3VyYWN5IChhdmVyYWdlIHJlYWN0aW9uIHRpbWUpIiwKICAgICAgIGNhcHRpb24gPSAiTm90ZTogLi4uIiwKICAgICAgIHggPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsIAogICAgICAgeSA9ICJBdmVyYWdlIFJlYWN0aW9uIFRpbWUgKHNlYy4pIiwgCiAgICAgICBmaWxsID0gIlNtYXJ0cGhvbmUgUG93ZXIiCiAgICAgICApICsKICAgICAgICAjIHRoZSAiXG4iIGhlcmUgZGVub3RlIHRoYXQgeW91IHdhbnQgYSBuZXcgbGluZSBmb3JtZWQgaW4gdGhlIHRleHQKICBnZW9tX3BvaW50KHN0YXQgPSAiaWRlbnRpdHkiLCBhZXMoY29sb3IgPSBwb3dlciksIHNpemUgPSAxLCAKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gLjUzKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkZWVwc2t5Ymx1ZTQiLCAicHVycGxlNCIpKSArIAogIGdlb21fcG9pbnQoc3RhdD0ic3VtbWFyeSIsIGZ1bj0ibWVhbiIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoLjkpLCBzaXplID0gMS41LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9lcnJvcmJhcihkYXRhID0gZ25nX2FjX2Jhcl9kYXRhLCBzdGF0ID0gInN1bW1hcnkiLCBmdW4ueW1pbiA9IGZ1bmN0aW9uKHgpIG1lYW4oeCkgLSBzZCh4KS9zcXJ0KGxlbmd0aCh4KSksIAogICAgICAgICAgICAgICAgZnVubWF4ID0gZnVuY3Rpb24oeCkgbWVhbih4KSArIHNkKHgpL3NxcnQobGVuZ3RoKHgpKSwgc2l6ZT0gLjUsIHdpZHRoPSAuMjUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoLjkpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxMyksIAogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxMiwgZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMykpICMrCiAgI3NjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKG1pbihnbmdfYWNfYmFyX29zcGFuX2RhdGEkcnRfYXYpLCBtYXgoZ25nX2FjX2Jhcl9vc3Bhbl9kYXRhJHJ0X2F2KSkpCgoKIyBzaG93IHRoZSBmaWd1cmVzCmduZ19hY19iYXIKICAKIyBleHBvcnQgcGxvdHMKIyBnZ3NhdmUoZmlsZW5hbWU9ImZpZ19nbmdfYWNfYmFyX2p1bmUxNiIsIHBsb3QgPSBnbmdfYWNfYmFyLCBkZXZpY2UgPSAianBlZyIsIGhlaWdodCA9IDUsIHdpZHRoID0gOCwgdW5pdHMgPSAiaW4iLCBkcGkgPSAxMDAwKQpgYGAKCiMjIDMuIFRlc3RpbmcgdGhlIE1vZGVyYXRpb24gSHlwb3RoZXNpczoKCiMjIyBFeHBsb3JhdG9yeSBGYWN0b3IgQW5hbHlzaXMgb2YgdGhlIFNBRAoKVG8gZXhhbWluZSB0aGUgdW5kZXJseWluZyBmYWN0b3JzIG1lYXN1cmVkIGJ5IHRoZSBTbWFydHBob25lIEF0dGFjaG1lbnQgYW5kIERlcGVuZGVuY3kgSW52ZW50b3J5IChTQUQpIGZyb20gV2FyZCBldCBhbC4gKDIwMTcpLCBhIHByaW5jaXBhbCBjb21wb25lbnRzIGZhY3RvciBhbmFseXNpcyB3aXRoIGEgVmFyaW1heCByb3RhdGlvbiB3YXMgY29tcGxldGVkIG9uIHBhcnRpY2lwYW50J3MgU0FEIGRhdGEuIFRoZSBhbmFseXNpcyB3YXMgZXhwbG9yYXRvcnkgYW5kIHdhcyBjb21wYXJlZCB0byBXYXJkIGV0IGFsLidzIGZpbmRpbmdzLiBUaGVyZSB3YXMgYSB0b3RhbCBvZiBgciBucm93KGZhX2RhdGEpYCBwYXJ0aWNpcGFudHMgaW4gdGhlIGZhY3RvciBhbmFseXNpcy4KCiMjIyMgQ2hlY2tpbmcgdGhlIERhdGEKClRvIHBlcmZvcm0gdGhlIHByaW5jaXBhbCBjb21wb25lbnRzIGZhY3RvciBhbmFseXNpcywgd2UgZmlyc3QgZXhhbWluZWQgdGhlIGRhdGEgZm9yICgxKSBtaXNzaW5nIGRhdGEsICgyKSBjb3JyZWxhdGlvbnMgYmV0d2VlbiB0aGUgaXRlbXMsIGFuZCAoMykgdGhlIGZhY3RvcmFiaWxpdHkgb2YgdGhlIGRhdGEuCgojIyMjIyAxLiBNaXNzaW5nIERhdGEKCi0gICBGcm9tIHRoZSBkZXNjcmlwdGl2ZXMgdGFibGUsIGl0IHNlZW1zIHRoYXQgdGhlcmUgaXMgbm8gbWlzc2luZyBvciBpbmNvbXBsZXRlIGRhdGEuIFRoaXMgd2FzIGNvbmZpcm1lZCBieSBmaW5kaW5nIHRoZSBjb21wbGV0ZSBjYXNlcywgd2hpY2ggd2VyZSBlcXVhbCB0byB0aGUgdG90YWwgc2FtcGxlIHNpemUgKGkuZS4gYHIgZmFfY29tcGxldGVgKS4gVGhlcmVmb3JlLCBubyBkYXRhIHdhcyByZW1vdmVkIGR1ZSB0byBtaXNzaW5nIHZhbHVlcyBmb3IgdGhpcyBhbmFseXNpcyAqKHNlZSBkZXNjcmlwdGl2ZXMgdGFibGUgYmVsb3cpKi4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIGdldCBhIGRhdGEgZnJhbWUgd2l0aCB0aGUgU0FEIGl0ZW1zIG9ubHkgZm9yIHRoZSBmYWN0b3IgYW5hbHlzaXMKZmFfZGF0YSA9IGRwbHlyOjpzZWxlY3QoZmFjdG9yX2FuYWx5c2lzLCBTQURfMTpTQURfMTMpCgojIGZpbmQgdGhlIHRvdGFsIGNvbXBsZXRlIGNhc2VzIHRvIGZpbmQgYW55IG1pc3NpbmcgZGF0YSBmcm9tIHRoZSBkYXRhIC0tIGFueSBwYXJ0aWNpcGFudCB3aXRoIG1pc3NpbmcgZGF0YSBtdXN0IGJlIHJlbW92ZWQKZmFfY29tcGxldGUgPSBzdW0oY29tcGxldGUuY2FzZXMoZmFfZGF0YSkpCgojIFNob3cgZGVzY3JpcHRpdmVzIGZvciB0aGUgZmFjdG9yIGFuYWx5c2lzIGRhdGEKZmFfZGVzID0gZGVzY3JpYmUoZmFfZGF0YSkKCiMgc2hvdyBkZXNjcmlwdGl2ZXMgaW4ga2FibGUgdGFibGUgCmthYmxlKGRlc2NyaWJlLmJ5KGZhX2RhdGEpLCBjYXB0aW9uID0gIkRlc2NyaXB0aXZlcyBmb3IgSXRlbXMgaW4gdGhlIFNBRCIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnLCBlc2NhcGUgPSBGQUxTRSkgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JSAKICBrYWJsZV9jbGFzc2ljKCkKCmBgYAoKIyMjIyMgMi4gQ29ycmVsYXRpb25zIGJldHdlZW4gdGhlIEl0ZW1zCgotICAgVGhlIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHRoZSBpdGVtcyB3ZXJlIGV4YW1pbmVkIHRvIGRldGVybWluZSBpZiB0aGV5IHdlcmUgZWl0aGVyIG5vdCBoaWdoIGVub3VnaCAoaS5lLiwgciBcPCAuMzApIG9yIHRvbyBoaWdoIChpLmUuLCByIFw+IC44MCkuCgogICAgLSAgIFRoZSBjb3JyZWxhdGlvbnMgZm9yIHRoZSAxMyBpdGVtcyBpbiB0aGUgU0FEIHJhbmdlZCBmcm9tICpyKihgciBmYV9jb3IkblsxLDFdIC0gMmApIGByIHBfcm91bmQobWluKGZhX2NvciRyW3doaWNoKGZhX2NvciRyIDwgMSldKSlgIHRvICpyKihgciBmYV9jb3IkblsxLDFdIC0gMmApIGByIHBfcm91bmQobWF4KGZhX2NvciRyW3doaWNoKGZhX2NvciRyIDwgMSldKSlgLCAqcCogYHIgcF9yb3VuZChtYXgoZmFfY29yJFBbd2hpY2goIWlzLm5hKGZhX2NvciRQKSldKSlgLgogICAgLSAgIEEgdmlzdWFsIGluc3BlY3Rpb24gb2YgdGhlIGNvcnJlbGF0aW9ucyBzaG93ZWQgdGhhdCBpdGVtcyAxMiBhbmQgMTMgbWlnaHQgbm90IGJlIGNvcnJlbGF0ZWQgZW5vdWdoIHdpdGggdGhlIHJlc3Qgb2YgdGhlIGl0ZW1zIChpLmUuIGByIGxlbmd0aCh3aGljaChmYV9jb3IkclssMTJdIDwgLjMwKSlgIGFuZCBgciBsZW5ndGgod2hpY2goZmFfY29yJHJbLDEzXSA8IC4zMCkpYCBjb3JyZWxhdGlvbnMgYmVsb3cgLjMwLCByZXNwZWN0aXZlbHkpLiBUaGVyZSB3ZXJlIG5vIGlzc3VlcyBhc3NvY2lhdGVkIHdpdGggdG9vIG1hbnkgaGlnaCBjb3JyZWF0aW9ucyBmb3IgYW55IGl0ZW1zLgogICAgLSAgIFRoZSBsb3dlciBjb3JyZWxhdGlvbnMgZm9yIGl0ZW1zIDEyIGFuZCAxMyBzaG91bGQgYmUga2VwdCBpbiBtaW5kIHdoZW4gY29tcGxldGluZyB0aGUgZmFjdG9yIGFuYWx5c2lzIGFuZCB0aGVzZSBpdGVtcyBtYXkgYmUgcmVtb3ZlZC5cCgotICAgVG8gY2hlY2sgZm9yIG11bHRpY29sbGluZWFyaXR5LCB0aGUgZGV0ZXJtaW5hbnQgb2YgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCB3YXMgY2FsY3VsYXRlZC4gVGhlIGRldGVybWluYW50IHdhcyBncmVhdGVyIHRoYW4gdGhlIG5lY2Vzc2FyeSB2YWx1ZSBvZiAwLjAwMDAxIChpLmUuLCBgciByb3VuZChmYV9kZXQsIDUpYCksIHNvLCB0aGVyZSB3YXMgbm8gaXNzdWVzIHdpdGggbXVsdGljb2xsaW5lYXJpdHkgKEZpZWxkIGV0IGFsLiwgMjAxMikuCgotICAgVGhlcmVmb3JlLCBhbGwgaXRlbXMgaW4gdGhlIFNBRCBjb3JyZWxhdGVkIHJlYXNvbmFibHkgd2l0aCBlYWNoIG90aGVyIGFuZCB3aXRob3V0IGFuIGV4Y2Vzc2l2ZWx5IGxhcmdlIGNvcnJlbGF0aW9uIHNvIG5vIGl0ZW1zIHdlcmUgcmVtb3ZlZCBhdCB0aGlzIHN0YWdlLgoKYGBge3J9CgojIGdldCB0aGUgcGVhcnNvbiBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhbGwgaXRlbXMgKGFuZCBjb3JyZXNwb25kaW5nIHAtdmFsdWVzKQpmYV9jb3IgPSByY29ycihhcy5tYXRyaXgoZmFfZGF0YSksIHR5cGUgPSAicGVhcnNvbiIpIAoKIyBtYWtlIGEgdGFibGUgd2l0aCB0aGUgZGF0YSB0byBkaXNwbGF5IGl0IGJldHRlcgpmYV9jb3JfdCA9IGFzLmRhdGEuZnJhbWUoZmFfY29yJHIpCiAgIyBpbmNsdWRlIG9ubHkgdGhlIGxvd2VyIHRyaWFuZ2xlIG9mIHRoZSBkYXRhCiAgZmFfY29yX3RbdXBwZXIudHJpKGZhX2Nvcl90KV0gPSBOQQogIAojIGZpbmQgdGhlIGRldGVybWluYW50IG9mIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgKZmFfZGV0ID0gZGV0KGZhX2NvciRyKQoKIyBQcmludCB0YWJsZSB1c2luZyBrYWJsZQogICMgbWFrZSBhbnkgTkFzIGFwcGVhciBhcyBibGFuayB3aXRoaW4ga2FibGUKICBvcHRzID0gb3B0aW9ucyhrbml0ci5rYWJsZS5OQSA9ICIiKQogICMgcHJpbnQgdGFibGUKICBrYWJsZShmYV9jb3JfdCwgY2FwdGlvbiA9ICJQZWFyc29uIENvcnJlbGF0aW9ucyBiZXR3ZWVuIEl0ZW1zIGluIHRoZSBTQUQiLCBkaWdpdHMgPSA0LCBhbGlnbiA9ICdjJywgZXNjYXBlID0gRkFMU0UpICU+JQogICAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JQogICAgYWRkX2Zvb3Rub3RlKCJwIDwgLjAwMSIsIG5vdGF0aW9uID0gImFscGhhYmV0IikgJT4lIAogICAga2FibGVfY2xhc3NpYygpCiAgICAjIHJlc3RvcmUgdGhlIG9yaWdpbmFsIG9wdGlvbnMgc28gdGhhdCAiTkEiIHNob3dzIHVwIGFnYWluCiAgICBvcHRpb25zKG9wdHMpCgpgYGAKCi0gICBBbm90aGVyIHdheSB0byB2aXN1YWxpemUgdGhpcyBpcyB1c2luZyBhIFNjYXR0ZXIgUGxvdCBNYXRyaXgKCiAgICAtICAgVGhpcyBzaG93czogKDEpIGEgc2NhdHRlciBwbG90IGJlbGxvdyB0aGUgbG93ZXIgZGlhZ29uYWwsIHdpdGggYSBsaW5lIG9mIGJlc3QgZml0IChyZWQpOyAoMikgYSBoaXN0b3JncmFtIGFuZCBkZW5zaXR5IHBsb3Qgb2YgdGhlIGl0ZW0gb24gdGhlIGRpYWdvbmFsOyBhbmQgKDMpIHRoZSBjb3JyZWxhdGlvbiB2YWx1ZXMgKHBlYXJzb24gcikgYWJvdmUgdGhlIGRpYWdvbmFsLCB3aXRoIGNvcnJlc3BvbmRpbmcgc2lnbmlmaWNhbmNlIHNob3duIHdpdGggYXN0ZXJpc2tzLiBUaGUgeC1heGlzIGluIGVhY2ggc2NhdHRlciBwbG90IHJlcHJlc2VudHMgdGhlIGNvbHVtbiB2YXJpYWJsZSBhbmQgdGhlIHktYXhpcyB0aGUgcm93IHZhcmlhYmxlLgoKYGBge3J9CiMgc2hvdyBhIFNQTE9NIChTY2F0dGVyIFBsb3QgTWF0cml4KSBvZiB0aGUgRGF0YSAKcGFpcnMucGFuZWxzKGZhX2RhdGEsIHBjaCA9ICIuIiwgZGVuc2l0eSA9IFRSVUUsIGVsbGlwc2VzID0gRkFMU0UsIGxtID0gVFJVRSwgZGlnaXRzID0gMiwgbWV0aG9kID0gInBlYXJzb24iLCBqaWdnbGUgPSBUUlVFLCBmYWN0b3IgPSAxLCBoaXN0LmNvbCA9ICJjYWRldGJsdWUzIiwgc3RhcnMgPSBUUlVFLCBnYXAgPSAuNSwgdmVyT2RkID0gVFJVRSwgaG9yT2RkID0gVFJVRSwgbWFpbiA9ICJTY2F0dGVyIFBsb3QgTWF0cml4IG9mIEl0ZW1zIGluIHRoZSBTQUQiKQoKYGBgCgojIyMjIyAzLiBGYWN0b3JhYmlsaXR5IG9mIHRoZSBEYXRhCgotICAgVGhpcyBhc3Nlc3NlZCBpZiB0aGVyZSB3ZXJlIG1lYW5pbmdmdWwgbGF0ZW50IGZhY3RvcnMgdG8gYmUgZm91bmQgd2l0aGluIHRoZSBkYXRhLCB3aGljaCB3YXMgYXNzZXNzZWQgaW4gdHdvIHdheXM6IEJhcmxldHQncyB0ZXN0IG9mIHNwaGVyaWNpdHkgZm9yIGNvcnJlbGF0aW9uIGFkZXF1YWN5IGFuZCB0aGUgS2Fpc2VyLU1leWVyLU9sa2luIG1lYXN1cmUgb2Ygc2FtcGxpbmcgYWRlcXVhY3kuCgogICAgLSAgICoqQmFybGV0dCdzIHRlc3Qgb2Ygc3BoZXJpY2l0eSBmb3IgY29ycmVsYXRpb24gYWRlcXVhY3kqKjoKCiAgICAgICAgLSAgIFRoaXMgdGVzdCB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgd2hpY2ggc3VnZ2VzdGVkIGdvb2QgZmFjdG9yYWJpbGl0eSwgJFxjaGleezJ9JChgciBmYV9iYXJ0ZXN0JGRmYCkgPSBgciByb3VuZChmYV9iYXJ0ZXN0JGNoaXNxLCAyKWAsICpwKiBgciBwX3JvdW5kKGZhX2JhcnRlc3QkcC52YWx1ZSlgCgogICAgLSAgICoqS2Fpc2VyLU1leWVyLU9sa2luIG1lYXN1cmUgb2Ygc2FtcGxpbmcgYWRlcXVhY3kqKjoKCiAgICAgICAgLSAgIFRoaXMgbWVhc3VyZSBzaG93ZWQgYW4gb3ZlcmFsbCBtZWFzdXJlIG9mIHNhbXBsaW5nIGFkZXF1YWN5IChNU0EpIGFuZCBhbiBNU0EgcGVyIGl0ZW0uIFRoZSBvdmVyYWxsIE1TQSB3YXMgaGlnaGVyIHRoYW4gYm90aCB0aGUgbWluaW11bSBhbmQgcHJlZmVycmVkIGNyaXRlcmlhICgwLjUwIGFuZCAwLjYwLCByZXNwZWN0aXZlbHk7IEthaXNlciwgMTk3NCwgSHV0Y2hlc29uICYgU29mcm9uaW91LCAxOTk5KSwgJE1TQV97b3ZlcmFsbH0kID0gYHIgcm91bmQoZmFfa21vJE1TQSwgMilgLiBFYWNoIGl0ZW0ncyBNU0Egd2FzIGFsc28gaGlnaGVyIHRoYW4gdGhlIG1pbmltdW0gYW5kIHByZWZlcnJlZCBjcml0ZXJpYSwgJE1TQV97MS0xM30kID0gYHIgbWluKHJvdW5kKGZhX2ttbyRNU0FpLCAyKSlgIC0gYHIgbWF4KHJvdW5kKGZhX2ttbyRNU0FpLCAyKSlgLgoKLSAgIFRoZXJlZm9yZSwgYm90aCBmYWN0b3JhYmlsaXR5IHRlc3RzIGNvbmZpcm1lZCB0aGF0IHRoZSBwbGFubmVkIGZhY3RvciBhbmFseXNpcyB3YXMgYXBwcm9wcmlhdGUuCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIHJ1biB0aGUgQmFybGV0dCBUZXN0CmZhX2JhcnRlc3QgPSBjb3J0ZXN0LmJhcnRsZXR0KGZhX2RhdGEpCmZhX2JhcnRlc3QKCiMgcnVuIHRoZSBLTU8gCmZhX2ttbyA9IEtNTyhmYV9kYXRhKQpmYV9rbW8KCmBgYAoKIyMjIyBFeHRyYWN0IEZhY3RvcnMKCk5vdyB0aGF0IGZhY3RvcmFiaWxpdHkgd2FzIGNvbmZpcm1lZCwgd2UgZm91bmQgdGhlIGFwcHJvcHJpYXRlIG51bWJlciBvZiBmYWN0b3JzIHRvIGV4dHJhY3QuIFRoaXMgd2FzIGRvbmUgdXNpbmc6ICgxKSBhIHBhcmFsbGVsIGFuYWx5c2lzIHNjcmVlIHBsb3QsICgyKSBlaWdlbiB2YWx1ZXMgKGkuZS4sIGZyb20gdGhlIHBhcmFsbGVsIGFuYWx5c2lzKSwgYW5kICgzKSB0aGUgZmFjdG9yIHN0cnVjdHVyZSBiZXR3ZWVuIHRoZSB0d28gc29sdXRpb25zIChpLmUuLCB1c2luZyBmYWN0b3IgZGlhZ3JhbXMpLgoKIyMjIyMgMS4gUGFyYWxsZWwgQW5hbHlzaXMgU2NyZWUgUGxvdC4KClRoaXMgcGxvdHRlZCB0aGUgZWlnZW52YWx1ZXMgZnJvbSB0aGUgZGF0YSBhbmQgYSBwYXJhbGxlbCBhbmFseXNpcyB3aGljaCBnZW5lcmF0ZWQgcmFuZG9tIGNvcnJlbGF0aW9uIG1hdHJpY2VzLiBUaGUgbnVtYmVyIG9mIGZhY3RvcnMgaXMgdGhlbiBkZXRlcm1pbmVkIGJ5IGNvbXBhcmluZyB0aGUgcmVzdWx0aW5nIGVpZ2VudmFsdWVzIHRvIHRoZSBvYnNlcnZlZCBkYXRhLCB0aGF0IGlzLCBvYnNlcnZlZCBlaWdlbnZhbHVlcyB0aGF0IHdlcmUgaGlnaGVyIHRoYW4gdGhlIGNvcnJlc3BvbmRpbmcgcmFuZG9tIGVpZ2VudmFsdWVzIHdlcmUgbW9yZSBsaWtlbHkgdG8gZm9ybSBtZWFuaW5nZnVsIGZhY3RvcnMuCgotICAgVGhlIHBhcmFsbGVsIGFuYWx5c2lzIHNjcmVlIHBsb3Qgc2hvd2VkIHRoYXQgdGhlcmUgYXJlIGByIGZhX3BhciRuY29tcGAgYXBwcm9wcmlhdGUgZmFjdG9ycyAoaS5lLiB1c2luZyB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgZXh0cmFjdGlvbiBtZXRob2QpLgoKICAgIC0gICBGcm9tIGNsb3NlciBpbnNwZWN0aW9uIG9mIHRoZSBwbG90LCB0aGUgbGFzdCBmYWN0b3Igd2FzIHZlcnkgY2xvc2UgdG8gdGhlIHJhbmRvbSBlaWdlbnZhbHVlIGN1dC1vZmYgbGluZSwgdGhlcmVmb3JlLCB0aGUgMiwgMywgYW5kIDQgZmFjdG9yIHNvbHV0aW9ucyB3ZXJlIGNvbXBhcmVkIHRvIGRldGVybWluZSB0aGUgYmVzdCBmaXQgKGkuZS4sIHRoZSBlaWdlbiB2YWx1ZXMgYW5kIGZhY3RvciBzdHJ1Y3R1cmVzIHdlcmUgZXhhbWluZWQpLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmZhX3BhciA8LSBmYS5wYXJhbGxlbChmYV9kYXRhLCBmYSA9ICJmYSIsIG1haW4gPSAiUGFyYWxsZWwgQW5hbHlzaXMgU2NyZWUgUGxvdCBmb3IgSXRlbXMgaW4gdGhlIFNBRCIpCmBgYAoKIyMjIyMgMi4gRWlnZW4gVmFsdWVzCgpGb3IgYSBzYW1wbGUgc2l6ZSBncmVhdGVyIHRoYW4gMjUwIChpLmUuLCBgciBmYV9jb21wbGV0ZWAgY29tcGxldGUgY2FzZXMpIHRoZSBhdmVyYWdlIGNvbW11bmFsaXRpZXMgKGkuZS4sIHRoZSBwcm9wb3J0aW9uIG9mIGNvbW1vbiB2YXJpYW5jZSB3aXRoaW4gdGhlIGl0ZW1zKSBmb3IgdGhlIHR3byBmYWN0b3IgKGByIHJvdW5kKG1lYW4oZmFfdHdvX3YkY29tbXVuYWxpdHkpLCAyKWApIGFuZCB0aHJlZSBmYWN0b3IgKGByIHJvdW5kKG1lYW4oZmFfdGhyZWVfdiRjb21tdW5hbGl0eSksIDIpYCkgc29sdXRpb25zIHdlcmUgd2lodGluIHRoZSBhY2NlcHRhYmxlIHZhbHVlIChpLmUuLCAwLjYwOyBGaWVsZCBldCBhbC4sIDIwMTIpLiBUaGVyZWZvcmUsIEthaXNlcidzIGNyaXRlcmlvbiAoaS5lLiwgYSBtZWFuaW5nZnVsIGZhY3RvciBoYXMgYW4gZWlnZW4gdmFsdWUgZ3JlYXRlciB0aGFuIDEpIHdhcyB1c2VkIGZvciB0aGUgZWlnZW4gdmFsdWVzLiBJdCBzaG91bGQgYmUgbm90ZWQgdGhhdCBhbHRob3VnaCB0aGUgYXZlcmFnZSBjb21tdW5hbGl0aWVzIHdlcmUgbm90IHZlcnkgaGlnaCwgdGhlIHNjcmVlIHBsb3QgYW5kIGZhY3RvciBkaWFncmFtcyB3ZXJlIHVzZWQgdG8gY2hvb3NlIHRoZSBhcHByb3ByaWF0ZSBudW1iZXIgb2YgZmFjdG9ycy4KCi0gICBUaGUgZWlnZW4gdmFsdWVzICh1bnJvdGF0ZWQgc29sdXRpb24pIHNob3dlZCB0aHJlZSBtZWFuaW5nZnVsIGZhY3RvcnMgKGkuZS4sIGByIHJvdW5kKGZhX3BhciRwYy52YWx1ZXNbMTozXSwgMilgKSwgd2hpY2ggKnN1cHBvcnRlZCB0aGUgdGhyZWUtZmFjdG9yIHNvbHV0aW9uKiBhcyBhIGJldHRlciByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGF0YS4KCmBgYHtyfQojIEVpZ2VuIHZhbHVlcwogICMgdmlldyBlaWdlbiB2YWx1ZXMgZnJvbSB0aGUgcGFyYWxsZWwgYW5hbHlzaXMgc2NyZWUgcGxvdAogIHJvdW5kKGZhX3BhciRwYy52YWx1ZXMsIDMpCmBgYAoKIyMjIyMgMy4gRmFjdG9yIERpYWdyYW1zCgpBIGZhY3RvciBkaWFncmFtIGZvciB0aGUgdHdvLSwgdGhyZWUtLCBhbmQgZm91ci1mYWN0b3Igc29sdXRpb25zIChyb3RhdGVkIHNvbHV0aW9uKSB3YXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggc29sdXRpb24gcmVwcmVzZW50cyB0aGUgbW9zdCBpbnRlcnByZXRhYmxlIHNvbHV0aW9uLiBUaGUgZGlhZ3JhbXMgc2hvdyB0aGUgZmFjdG9yIGxvYWRpbmdzIGZvciBlYWNoIGl0ZW0gb24gdGhlIGdpdmVuIGZhY3RvciBmb3Igd2hpY2ggdGhleSBsb2FkIHRoZSBoaWdoZXN0IG9uLiBUaGUgaXRlbXMgd2VyZSBvcmRlcmVkIChpLmUuLCBkZXNjZW5kaW5nKSBiYXNlZCBvbiB0aGVzZSBsb2FkaW5ncy5cCipOb3RlOiBUaGUgZmFjdG9yIGRpYWdyYW1zIGFyZSBiYXNlZCBvbiB0aGUgcm90YXRlZCBzb2x1dGlvbnMgdG8gYmV0dGVyIGRpc3RyaWJ1dGUgdGhlIGZhY3RvciBsb2FkaW5ncyoKCi0gICBUaGUgZmFjdG9yIGRpYWdyYW1zIHNob3dlZCB0aGF0IHRoZSB0d28gZmFjdG9yIHNvbHV0aW9uIHJlc3VsdGVkIGluIG1vc3QgaXRlbXMgbG9hZGluZyBvbnRvIG9ubHkgb25lIGZhY3RvciBhbmQgd2FzIG5vdCBlYXNpbHkgaW50ZXJwcmV0ZWQuIFRoZSBmb3VyLWZhY3RvciBzb2x1dGlvbiBzaG93ZWQgYSAyLWl0ZW0gZmFjdG9yLCB3aGljaCBpcyBub3QgZWFzaWx5IGludGVycHJldGFibGUgYXMgaXQgZGlkIG5vdCBtZWV0IHRoZSAzLWl0ZW0gbWludW11bSAoQ29zdGVsbG8gJiBPc2Jvcm4sIDIwMDUpLiBUaGUgdGhyZWUgYW5kIGZvdXIgZmFjdG9yIHNvbHV0aW9ucyBzaG93ZWQgYmV0dGVyIGRpc3RyaWJ1dGlvbnMgYW5kIHdlcmUgbW9yZSBpbnRlcnByZXRhYmxlLiBBZnRlciByZXZpZXdpbmcgdGhlIGl0ZW1zLCB0aGUgZm91ci1mYWN0b3Igc29sdXRpb24gcHJvdmlkZWQgYSBsb2dpY2FsIHN0cnVjdHVyZSBjb21wYXJlZCB0byB0aGUgdGhyZWUtZmFjdG9yIHNvbHV0aW9uLiBUaGF0IGlzLCB0aGUgdGhpcmQgZmFjdG9yIGluIHRoZSAzLWZhY3RvciBzb2x1dGlvbiBncm91cGVkIGl0ZW1zIDYgJiA3IHdpdGggMTIgJiAxMywgaG93ZXZlciBpdGVtcyA2ICYgNyBhc2sgYWJvdXQgZW1vdGlvbmFsIGFzc29jaWF0aW9ucyB3aGVyZWFzIGl0ZW1zIDEyICYgMTMgYXJlIHJlZ2FyZGluZyBhdHRlbnRpb24uIEFsdGhvdWdoIHRoZSBmb3VydGggZmFjdG9yIGluIHRoZSBmb3VyLWZhY3RvciBzb2x1dGlvbiBvbmx5IGNvbnRhaW5lZCAyIGl0ZW1zLCB0aGVzZSBpdGVtcyB3ZXJlIGNvbnNpZGVyZWQgdW5pcXVlIGluIHRoYXQgdGhleSBhcmUgdGhlIG9ubHkgaXRlbXMgaW4gdGhlIFNBRCB3aGljaCBhc2tlZCBwYXJ0aWNpcGFudHMgYWJvdXQgYXR0ZW50aW9uIHdpdGggcmVzcGVjdCB0byB0aGVpciBzbWFydHBob25lLiBUaGVyZWZvcmUsIHRoZSAqKmZvdXItZmFjdG9yKiogc29sdXRpb24gd2FzIGNob3Nlbi4gCgpUaGVyZWZvcmUsIHRoZSAqKnRocmVlIGZhY3RvciBzb2x1dGlvbioqIHdhcyBjaG9zZW4gdG8gYmV0dGVyIHJlcHJlc2VudCB0aGUgZGF0YS4KCmBgYHtyIGZhX2RpYWdyYW1zLCBvdXQud2lkdGg9YygnNTAlJywnNTAlJyksIGZpZy5zaG93PSdob2xkJ30KIyMtLSBWQVJJTUFYIFJPVEFUSU9OICAtLSAKIyBydW4gYSBmYWN0b3IgYW5hbHlzaXMgdG8gY29tcGFyZSB0aGUgdHdvLSBhbmQgdGhyZWUtZmFjdG9yIHNvbHV0aW9ucyAobm8gcm90YXRpb24pCiAgIyAyIGZhY3RvciBzb2x1dGlvbgogIGZhX3R3b192ID0gZmEoZmFfZGF0YSwgbmZhY3RvcnMgPSAyLCBmbSA9ICJwYSIsIHJvdGF0ZSA9ICJ2YXJpbWF4Iiwgc2NvcmVzID0gVCkKICAgICMgY2hhbmdlIG5hbWUgaW4gbG9hZGluZ3MgZm9yIGNsYXJpdHkgd2hlbiB2aXN1YWxpemluZyB0aGUgbW9kZWwKICAgIGNvbG5hbWVzKGZhX3R3b192JGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIikKICAKICAjIDMgZmFjdG9yIHNvbHV0aW9uCiAgZmFfdGhyZWVfdiA9IGZhKGZhX2RhdGEsIG5mYWN0b3JzID0gMywgZm0gPSAicGEiLCByb3RhdGUgPSAidmFyaW1heCIsIHNjb3JlcyA9IFQpCiAgICAjIGNoYW5nZSBuYW1lIGluIGxvYWRpbmdzIGZvciBjbGFyaXR5IHdoZW4gdmlzdWFsaXppbmcgdGhlIG1vZGVsCiAgICBjb2xuYW1lcyhmYV90aHJlZV92JGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIiwgIkZhY3RvciAzIikKICAKICAjIDQgZmFjdG9yIHNvbHV0aW9uCiAgZmFfZm91cl92ID0gZmEoZmFfZGF0YSwgbmZhY3RvcnMgPSA0LCBmbSA9ICJwYSIsIHJvdGF0ZSA9ICJ2YXJpbWF4Iiwgc2NvcmVzID0gVCkKICAgICMgY2hhbmdlIG5hbWUgaW4gbG9hZGluZ3MgZm9yIGNsYXJpdHkgd2hlbiB2aXN1YWxpemluZyB0aGUgbW9kZWwKICAgIGNvbG5hbWVzKGZhX2ZvdXJfdiRsb2FkaW5ncykgPSBjKCJGYWN0b3IgMSIsICJGYWN0b3IgMiIsICJGYWN0b3IgMyIsICJGYWN0b3IgNCIpCgojIEZhY3RvciBEaWFncmFtCiAgIyAyIGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfdHdvX3YsIG1haW4gPSAiVHdvIEZhY3RvciBTb2x1dGlvbiBmb3IgaXRlbXMgaW4gdGhlIFNBRCAoVmFyaW1heCBSb3RhdGlvbikiLCBzb3J0ID0gVFJVRSwgYWRqID0gMSwgZGlnaXRzID0gMikKCiAgIyAzIGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfdGhyZWVfdiwgbWFpbiA9ICJUaHJlZSBGYWN0b3IgU29sdXRpb24gZm9yIEl0ZW1zIGluIHRoZSBTQUQgKFZhcmltYXggUm90YXRpb24pIiwgc29ydCA9IFRSVUUsIGFkaiA9IDEsIGRpZ2l0cyA9IDIpCiAgCiAgIyA0IGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfZm91cl92LCBtYWluID0gIlRocmVlIEZhY3RvciBTb2x1dGlvbiBmb3IgSXRlbXMgaW4gdGhlIFNBRCAoVmFyaW1heCBSb3RhdGlvbikiLCBzb3J0ID0gVFJVRSwgYWRqID0gMSwgZGlnaXRzID0gMikKYGBgCgpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQoKIyMtLSBPQkxJTUlOIFJPVEFUSU9OIC0tICAKIyBydW4gYSBmYWN0b3IgYW5hbHlzaXMgdG8gY29tcGFyZSB0aGUgdHdvLSBhbmQgdGhyZWUtZmFjdG9yIHNvbHV0aW9ucyAobm8gcm90YXRpb24pCiAgIyAyIGZhY3RvciBzb2x1dGlvbgogIGZhX3R3b19vID0gZmEoZmFfZGF0YSwgbmZhY3RvcnMgPSAyLCBmbSA9ICJwYSIsIHJvdGF0ZSA9ICJvYmxpbWluIiwgc2NvcmVzID0gVCkKICAgICMgY2hhbmdlIG5hbWUgaW4gbG9hZGluZ3MgZm9yIGNsYXJpdHkgd2hlbiB2aXN1YWxpemluZyB0aGUgbW9kZWwKICAgIGNvbG5hbWVzKGZhX3R3b19vJGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIikKICAKICAjIDMgZmFjdG9yIHNvbHV0aW9uCiAgZmFfdGhyZWVfbyA9IGZhKGZhX2RhdGEsIG5mYWN0b3JzID0gMywgZm0gPSAicGEiLCByb3RhdGUgPSAib2JsaW1pbiIsIHNjb3JlcyA9IFQpCiAgICAjIGNoYW5nZSBuYW1lIGluIGxvYWRpbmdzIGZvciBjbGFyaXR5IHdoZW4gdmlzdWFsaXppbmcgdGhlIG1vZGVsCiAgICBjb2xuYW1lcyhmYV90aHJlZV9vJGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIiwgIkZhY3RvciAzIikKICAKICAjIDQgZmFjdG9yIHNvbHV0aW9uCiAgZmFfZm91cl9vID0gZmEoZmFfZGF0YSwgbmZhY3RvcnMgPSA0LCBmbSA9ICJwYSIsIHJvdGF0ZSA9ICJvYmxpbWluIiwgc2NvcmVzID0gVCkKICAgICMgY2hhbmdlIG5hbWUgaW4gbG9hZGluZ3MgZm9yIGNsYXJpdHkgd2hlbiB2aXN1YWxpemluZyB0aGUgbW9kZWwKICAgIGNvbG5hbWVzKGZhX2ZvdXJfbyRsb2FkaW5ncykgPSBjKCJGYWN0b3IgMSIsICJGYWN0b3IgMiIsICJGYWN0b3IgMyIsICJGYWN0b3IgNCIpCgojIEZhY3RvciBEaWFncmFtCiAgIyAyIGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfdHdvX28sIG1haW4gPSAiVHdvIEZhY3RvciBTb2x1dGlvbiBmb3IgaXRlbXMgaW4gdGhlIFNBRCAob2JsaW1pbiBSb3RhdGlvbikiLCBzb3J0ID0gVFJVRSwgYWRqID0gMSwgZGlnaXRzID0gMikKCiAgIyAzIGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfdGhyZWVfbywgbWFpbiA9ICJUaHJlZSBGYWN0b3IgU29sdXRpb24gZm9yIEl0ZW1zIGluIHRoZSBTQUQgKG9ibGltaW4gUm90YXRpb24pIiwgc29ydCA9IFRSVUUsIGFkaiA9IDEsIGRpZ2l0cyA9IDIpCiAgCiAgIyA0IGZhY3RvciBzb2x1dGlvbgogIGZhLmRpYWdyYW0oZmFfZm91cl9vLCBtYWluID0gIlRocmVlIEZhY3RvciBTb2x1dGlvbiBmb3IgSXRlbXMgaW4gdGhlIFNBRCAob2JsaW1pbiBSb3RhdGlvbikiLCBzb3J0ID0gVFJVRSwgYWRqID0gMSwgZGlnaXRzID0gMikKCmBgYAoKIyMjIyBBY2hpZXZpbmcgU2ltcGxlIFN0cnVjdHVyZQoKTm93IHRoYXQgd2UgZGV0ZXJtaW5lZCB0aGUgbnVtYmVyIG9mIGZhY3RvcnMgKGkuZS4sIGZvdXIpLCB3ZSBhc3Nlc3NlZCBmb3IgKipzaW1wbGUgc3RydWN0dXJlKiogKGkuZS4sIGEgZmluYWwgc29sdXRpb24gb2YgdGhlIGZhY3RvciBhbmFseXNpcyB3aXRoIHRoZSBzaW1wbGVzdCBzb2x1dGlvbikuIFNpbXBsZSBzdHJ1Y3R1cmUgd2FzIGFjaGlldmVkIGJ5IHJldmlld2luZyBhc3Nlc3NpbmcgdGhlIGxvYWRpbmdzIGZvciBzdHJvbmcgbG9hZGluZ3MgKGkuZS4sIHVzaW5nIGEgY3V0LW9mZiBvZiBcPiAuNDApIGFuZCByZW1vdmluZzogKDEpIHNwbGl0IHZhcmlhYmxlcyAoaS5lLiwgdmFyaWFibGVzIHRoYXQgbG9hZGVkIG9udG8gbW9yZSB0aGFuIG9uZSBmYWN0b3IpLCAoMikgbm9uLWxvYWRpbmcgdmFyaWFibGVzLCBhbmQgKDMpIHdlYWsgZmFjdG9ycyAoaS5lLiwgZmFjdG9yIHdpdGggb25seSAxIHZhcmlhYmxlKS4gRmFjdG9yIGxvYWRpbmdzIGFyZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gZWFjaCB2YXJpYWJsZSBhbmQgdGhlIGZhY3RvciwgdGhhdCBpcywgdGhleSByZXByZXNlbnQgdGhlIHJlbGF0aW9uc2hpcCAoaS5lLiwgcG9zaXRpdmUgb3IgbmVnYXRpdmUpIGFuZCBzdHJlbmd0aCAoaS5lLiwgc3Ryb25nLCBtb2RlcmF0ZSwgb3Igd2VhaykgYmV0d2VlbiB0aGUgdmFyaWFibGUgYW5kIHRoZSBmYWN0b3IuCgojIyMjIyBGaXJzdCBTb2x1dGlvbjogMTMgU0FEIEl0ZW1zCgpGaXJzdCwgd2UgbG9va2VkIGF0IHRoZSAqKnJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzKiogKGkuZS4sIHZhcmltYXgpIGZvciBhbGwgMTMgaXRlbXMgaW4gdGhlIFNBRCBmb3IgdGhlIHRocmVlLWZhY3RvciBzb2x1dGlvbi4gVGhlIGxvYWRpbmdzIGFyZSBzaG93biB3aXRoIGEgY3V0LW9mZiBvZiAwLjQwIGFuZCByb3VuZGVkIHRvIHRocmVlIGRlY2ltYWwgcGxhY2VzLiAKCi0gKDEpIFNwbGl0IHZhcmlhYmxlczogSXRlbSAjNCBsb2FkZWQgc3Ryb25nbHkgb250byBmYWN0b3IgMSAoYHIgcm91bmQoZmFfbG9hZF92WzQsMV0sIDIpYCkgYW5kIGZhY3RvciAzIChgciByb3VuZChmYV9sb2FkX3ZbNCwzXSwgMilgKS4gCgotICgyKSBOb24tTG9hZGluZyBWYXJpYWJsZXM6IEFsbCBpdGVtcyBsb2FkZWQgb250byBhdCBsZWFzdCBvbmUgZmFjdG9yLiAKCi0gKDMpIFdlYWsgRmFjdG9yczogQWxsIGZhY3RvcnMgaGFkIGF0IGxlYXN0IDIgdmFyaWFibGVzIGxvYWRpbmcgc3Ryb25nbHksIHdoaWNoIHdhcyBkaXNjdXNzZWQgZWFybGllci4gCgotIFRoZXJlZm9yZSwgc2luY2UgaXRlbSAjNDYgd2FzIHNwbGl0IGJldHdlZW4gZmFjdG9yIDEgYW5kIGZhY3RvciAzLCBpdCB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBhbmFseXNpcy4gVGhpcyBuZXcgc29sdXRpb24gd2FzIGFzc2Vzc2VkIHdpdGggdGhlIHNhbWUgY3JpdGVyaWEgdG8gc2VlIGlmIHNpbXBsZSBzdHJ1Y3R1cmUgY291bGQgYmUgYWNoaWV2ZWQuCgpgYGB7cn0KCiMgUm90YXRlZCAoaS5lLiwgdmFyaW1heCkgRmFjdG9yIExvYWRpbmdzIApwcmludChmYV9mb3VyX3YkbG9hZGluZ3MsIGN1dG9mZiA9IDAuNDAsIGRpZ2l0cyA9IDMpCgojIG1ha2UgZGF0YSBmcmFtZSB0byBzaG93IHZhbHVlcwpmYV9sb2FkX3YgPC0gYXMuZGF0YS5mcmFtZShmYV9mb3VyX3YkbG9hZGluZ3NbMToxMyxdKQoKYGBgCgojIyMjIyBTZWNvbmQgU29sdXRpb246IDEyIFNBRCBJdGVtcyAocmVtb3ZlZCBpdGVtIDQpCgpOb3csIHdlIHJlbW92ZWQgaXRlbSAjNCBhbmQgbG9va2VkIGF0IHRoZSAqKnJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzKiogKGkuZS4sIHZhcmltYXgpIGZvciB0aGUgcmVtYWluaW5nIDEyIGl0ZW1zIGluIHRoZSBTQUQgZm9yIHRoZSBmb3VyLWZhY3RvciBzb2x1dGlvbi4gVGhlIGxvYWRpbmdzIGFyZSBzaG93biB3aXRoIGEgY3V0LW9mZiBvZiAwLjQwIGFuZCByb3VuZGVkIHRvIHRocmVlIGRlY2ltYWwgcGxhY2VzLiAKCi0gKDEpIFNwbGl0IHZhcmlhYmxlczogTm8gaXRlbXMgbG9hZGVkIHN0cm9uZ2x5IG9udG8gbW9yZSB0aGFuIG9uZSBmYWN0b3IuCgotICgyKSBOb24tTG9hZGluZyBWYXJpYWJsZXM6IEFsbCBpdGVtcyBsb2FkZWQgb250byBhdCBsZWFzdCBvbmUgZmFjdG9yLgoKLSAoMykgV2VhayBGYWN0b3JzOiBBbGwgZmFjdG9ycyBoYWQgYXQgbGVhc3QgMiBpdGVtcyBsb2FkaW5nIHN0cm9uZ2x5LiAKCi0gVGhlcmVmb3JlLCAqKnNpbXBsZSBzdHJ1Y3R1cmUgd2FzIGFjaGlldmVkIGFuZCB0aGlzIGZpbmFsIHNvbHV0aW9uIHdhcyB1c2VkIGZvciBmdXJ0aGVyIGFuYWx5c2lzKiouCgpgYGB7cn0KIyBjcmVhdGUgZGF0YSBzZXQgd2l0aG91dCBpdGVtICMgNgpmYV9kYXRhMiA8LSAKICBmYV9kYXRhICU+JSAKICBzZWxlY3QoLVNBRF80KQoKIyBydW4gRkEgd2l0aCA0IGZhY3RvcnMgYW5kIGEgdmFyaW1heCByb3RhdGlvbgogICMgcm90YXRlZCAodmFyaW1heCkKICBmYV9mb3VyX3YyIDwtIGZhKGZhX2RhdGEyLCBuZmFjdG9ycyA9IDQsIGZtID0gInBhIiwgcm90YXRlID0gInZhcmltYXgiLCBzY29yZXMgPSBUKSAKICAjIGNoYW5nZSBuYW1lIGluIGxvYWRpbmdzIGZvciBjbGFyaXR5IHdoZW4gdmlzdWFsaXppbmcgdGhlIG1vZGVsCiAgICBjb2xuYW1lcyhmYV9mb3VyX3YyJGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIiwgIkZhY3RvciAzIiwgIkZhY3RvciA0IikKCiMgUm90YXRlZCAoaS5lLiwgdmFyaW1heCkgRmFjdG9yIExvYWRpbmdzIApwcmludChmYV9mb3VyX3YyJGxvYWRpbmdzLCBjdXRvZmYgPSAwLjQwLCBkaWdpdHMgPSAzKQoKIyBtYWtlIGRhdGEgZnJhbWUgdG8gc2hvdyB2YWx1ZXMKZmFfbG9hZF92MiA8LSBhcy5kYXRhLmZyYW1lKGZhX2ZvdXJfdjIkbG9hZGluZ3NbMToxMixdKQoKYGBgCgojIyMjIERlc2NyaWJpbmcgdGhlIEZpbmFsIFNvbHV0aW9uCgpOb3cgdGhhdCB3ZSBoYXZlIGFjaGVpdmVkIHNpbXBsZSBzdHJ1Y3R1cmUsIHdlIGxvb2tlZCBhdCB0aGUgKDEpIENvbW11bmFsaXRpZXMsICgyKSBWYXJpYW5jZSBBY2NvdW50ZWQgZm9yIGluIHBlcmNlbnRhZ2UsIGFuZCAoMykgRmFjdG9yIExvYWRpbmdzLiBUaGlzIHdhcyBkb25lIHVzaW5nIHRoZSBmaW5hbCBzb2x1dGlvbiAoaS5lLiwgZm91ci1mYWN0b3IsIHZhcmltYXggcm90YXRpb24sIGV4Y2x1ZGluZyBpdGVtICM0KS4KCiMjIyMjICgxKSBDb21tdW5hbGl0aWVzCgpGaXJzdC4gd2Ugb2JzZXJ2ZWQgdGhlICoqY29tbXVuYWxpdGllcy4qKiBFYWNoIGl0ZW0ncyBjb21tdW5hbGl0eSB3YXMgdGhlIHBlcmNlbnRhZ2Ugb2YgdmFyaWFuY2UgdGhhdCB3YXMgZXhwbGFpbmVkIGJ5IHRoZSByZXRhaW5lZCBmYWN0b3JzIGZvciBlYWNoIGl0ZW0uIFRoZXNlIHJhbmdlZCBmcm9tIGByIHJvdW5kKG1pbihmYV9mb3VyX3YyJGNvbW11bmFsaXR5KSoxMDAsIDIpYCUgdG8gYHIgcm91bmQobWF4KGZhX2ZvdXJfdjIkY29tbXVuYWxpdHkpKjEwMCwgMilgJSwgd2l0aCBhbiBhdmVyYWdlIG9mIGByIHJvdW5kKG1lYW4oZmFfZm91cl92MiRjb21tdW5hbGl0eSkqMTAwLCAyKWAgKHNlZSB0YWJsZSBmb3IgbW9yZSBkZXRhaWxzKS4KCmBgYHtyfQojIGdldCB0aGUgY29tbXVuYWxpdGllcyBmcm9tIHRoZSBtb2RlbApmYV9jb20gPSBhcy5kYXRhLmZyYW1lKGZhX2ZvdXJfdjIkY29tbXVuYWxpdHkpCiAgCiMgY3JlYXRlIG1hdHJpeCB0byBwcmVzZW50IGNvbW11bmFsaXRpZXMgaW4gYSB0YWJsZQpmYV9jb21fdCA9IHJiaW5kKChmYV9jb21bLDFdKSoxMDApCiAgIyByZW5hbWUgcm93IGFuZCBjb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhmYV9jb21fdCkgPSByb3duYW1lcyhmYV9jb20pCiAgcm93bmFtZXMoZmFfY29tX3QpID0gTlVMTAoKIyBQcmludCB0YWJsZSB1c2luZyBrYWJsZQogICMgcHJpbnQgdGFibGUKICBrYWJsZShmYV9jb21fdCwgY2FwdGlvbiA9ICJDb21tdW5hbGl0aWVzIGZvciB0aGUgVGhyZWUtRmFjdG9yIFNvbHV0aW9uIGZvciBJdGVtcyBpbiB0aGUgU0FEICglKSIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnLCBlc2NhcGUgPSBGQUxTRSkgJT4lCiAgICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAgICBhZGRfZm9vdG5vdGUoIkNvbW11bmFsaXRpZXMgc2hvdyB0aGUgcGVyY2VudGFnZSBvZiB2YXJpYW5jZSBleHBsYWluZWQgYnkgZWFjaCBmYWN0b3IgZm9yIGVhY2ggaXRlbSBvbiB0aGUgU0FELiIsIG5vdGF0aW9uID0gImFscGhhYmV0IikgJT4lIAogICAga2FibGVfY2xhc3NpYygpCmBgYAoKIyMjIyMgKDIpIFZhcmlhbmNlIEFjY291bnRlZCAoJSkKCk5leHQsIHdlIGxvb2tlZCBhdCB0aGUgKipwZXJjZW50YWdlIG9mIHZhcmlhbmNlIGFjY291bnRlZCBmb3IqKiBieSB1c2luZyB0aGUgZWlnZW52YWx1ZXMgKGNvbXB1dGUgdGhlIHZhcmlhbmNlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmFjdG9ycykuIFRoaXMgd2FzIGRvbmUgZm9yIGJvdGggdGhlIHVucm90YXRlZCBhbmQgcm90YXRlZCAoaS5lLiwgdmFyaW1heCkgZmluYWwgZm91ci1mYWN0b3Igc29sdXRpb24uIEFzIHlvdSBjYW4gc2VlIGluIHRoZSB0YWJsZSBiZWxvdywgYSB0b3RhbCBvZiBgciByb3VuZChzdW0odmFyX3BlciksIDIpYCUgb2YgdmFyaWFuY2Ugd2FzIGFjY291bnRlZCBmb3IgYnkgdGhlIHRocmVlIGV4dHJhY3RlZCBmYWN0b3JzICh0aGUgc2FtZSBiZWZvcmUgYW5kIGFmdGVyIHJvdGF0aW9uKS4gVGhpcyB2YXJpYW5jZSB3YXMgbW9zdGx5IGFjY291bnRlZCBmb3IgYnkgZmFjdG9yIG9uZSBpbiB0aGUgdW5yb3RhdGVkIHNvbHV0aW9uIChmYWN0b3IgMSA9IGByIHJvdW5kKHZhcl9wZXJbMV0sIDIpYCU7IGZhY3RvciAyID0gYHIgcm91bmQodmFyX3BlclsyXSwgMilgJTsgZmFjdG9yIDMgPSBgciByb3VuZCh2YXJfcGVyWzNdLCAyKWAlKSwgYnV0IHdhcyBtb3JlIGVxdWFsbHkgZGlzdHJpYnV0ZWQgYWZ0ZXIgcm90YXRpb24gKGZhY3RvciAxID0gYHIgcm91bmQodmFyX3Blcl92WzFdLCAyKWAlOyBmYWN0b3IgMiA9IGByIHJvdW5kKHZhcl9wZXJfdlsyXSwgMilgJTsgZmFjdG9yIDMgPSBgciByb3VuZCh2YXJfcGVyX3ZbM10sIDIpYCU7IHNlZSB0YWJsZSBmb3IgbW9yZSBkZXRhaWxzKS4KCmBgYHtyfQoKIyBSdW4gYW4gdW5yb3RhdGVkIHRocmVlLWZhY3RvciBzb2x1dGlvbgogIGZhX2ZvdXIyIDwtIGZhKGZhX2RhdGEyLCBuZmFjdG9ycyA9IDQsIGZtID0gInBhIiwgcm90YXRlID0gIm5vbmUiLCBzY29yZXMgPSBUKSAKICAgICMgY2hhbmdlIG5hbWUgaW4gbG9hZGluZ3MgZm9yIGNsYXJpdHkgd2hlbiB2aXN1YWxpemluZyB0aGUgbW9kZWwKICAgIGNvbG5hbWVzKGZhX2ZvdXIyJGxvYWRpbmdzKSA9IGMoIkZhY3RvciAxIiwgIkZhY3RvciAyIiwgIkZhY3RvciAzIiwgIkZhY3RvciA0IikgCiAgICAKICAKIyBUbyBmaW5kIHRoZSB2YXJpYW5jZSBhY2NvdW50ZWQgZm9yLCB5b3UgY2FuIGVpdGhlciAoMSkgY2FsY3VsYXRlIGl0IGZyb20gdGhlIGVpZ2VuIHZhbHVlcyBmb3IgZWFjaCBmYWN0b3IsIG9yICgyKSBncmFiIHRoZSBjYWxjdWxhdGVkIHZhbHVlcyBmcm9tIHRoZSBtb2RlbCAKICAjIEJvdGggYXJlIHNob3duIGJlbG93LCBidXQgb25lIGlzIGNvbW1lbnRlZCBvdXQgdG8gYXZvaWQgY3JlYXRpbmcgZXhjZXNzIHZhcmlhYmxlcwogICMgKDEpIENhbGN1bGF0ZWQgCiAgICAjIEZvciB0aGUgdW5yb3RhdGVkIHNvbHV0aW9uCiAgICAjdmFyX3BlciA9IDEwMCpmYV9mb3VyMiR2YWx1ZXNbMTozXS9sZW5ndGgoZmFfZm91cjIkdmFsdWVzKQogICAgCiAgICAjIEZvciB0aGUgcm90YXRlZCBzb2x1dGlvbgogICAgI3Zhcl9wZXJfdiA9IDEwMCooYXMubnVtZXJpYyhmYV9mb3VyX3YyJFZhY2NvdW50ZWRbMSxdKSkvbGVuZ3RoKGZhX2ZvdXJfdjIkdmFsdWVzKQogICAgICAKICAjICgyKSBUaGUgaW5mb3JtYXRpb24gaXMgZm91bmQgaW4gdGhlICJWYWNjb3VudGVkIiB0YWJsZSBmcm9tIHRoZSBvdXRwdXQsIHdoZXJlICJTUyBsb2FkaW5ncyIgKHJvdyAxKSBzaG93cyB0aGUgZWlnZW4gdmFsdWVzIGFuZCAiUHJvcG9ydGlvbiBWYXIiIChyb3cgMikgc2hvd3MgdGhlIHZhcmlhbmNlIGFjY291bnRlZCBmb3IuCiAgICAjIEZvciB0aGUgdW5yb3RhdGVkIHNvbHV0aW9uCiAgICB2YXJfcGVyID0gMTAwKmFzLm51bWVyaWMoZmFfZm91cjIkVmFjY291bnRlZFsyLF0pCiAgICAKICAgICMgRm9yIHRoZSByb3RhdGVkIHNvbHV0aW9uCiAgICB2YXJfcGVyX3YgPSAxMDAqYXMubnVtZXJpYyhmYV9mb3VyX3YyJFZhY2NvdW50ZWRbMixdKQoKIyBDcmVhdGUgJiBTaG93IGEgdGFibGUgd2l0aCBlaWdlbiB2YWx1ZXMsIHBlcmNlbnQgdmFyIGV4cGxhaW5lZCwgYW5kIHRvdGFsIHBlcmNlbnQgdmFyIGV4cGxhaW5lZCBmb3IgdW5yb3RhdGVkICYgcm90YXRlZCB0aHJlZS1mYWN0b3Igc29sdXRpb25zCiAgICAjIHVucm90YXRlZCBzb2x1dGlvbgogICAgdmFyX3Blcl90ID0gYXMuZGF0YS5mcmFtZShjYmluZChyYmluZChhcy5udW1lcmljKGZhX2ZvdXIyJFZhY2NvdW50ZWRbMSxdKSwgdmFyX3BlciksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYmluZChhcy5udW1lcmljKGZhX2ZvdXJfdjIkVmFjY291bnRlZFsxLF0pLCB2YXJfcGVyX3YpKSkKICAgICMgbmFtZSB0aGUgY29sdW1ucyAmIHJvd3MgYWNjb3JkaW5nbHkKICAgIGNvbG5hbWVzKHZhcl9wZXJfdCkgPSBjKHJlcChjKCJGYWN0b3IgMSIsICJGYWN0b3IgMiIsICJGYWN0b3IgMyIsICJGYWN0b3IgNCIpLDIpKQogICAgcm93bmFtZXModmFyX3Blcl90KSA9IGMoIkVpZ2VuIFZhbHVlcyIsICJWYXJpYW5jZSBFeHBsYWluZWQgKCUpIikKCiAgIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgdGFibGUKICBrYWJsZSh2YXJfcGVyX3QsIGNhcHRpb24gPSAiRWlnZW4gVmFsdWVzIGFuZCBQZXJjZW50IG9mIFZhcmlhbmNlIEV4cGxhaW5lZCBmb3IgdGhlIFVucm90YXRlZCBhbmQgUm90YXRlZCAodmFyaW1heCkgZm9yIHRoZSBUaHJlZS1GYWN0b3IgU29sdXRpb24gZm9yIEl0ZW1zIGluIHRoZSBTQUQiLCBkaWdpdHMgPSA0LCBhbGlnbiA9ICdjJykgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IFQpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsICJVbnJvdGF0ZWQiID0gNCwgIlZhcmltYXggUm90YXRpb24iID0gNCkpICU+JQogICAga2FibGVfY2xhc3NpYygpCgpgYGAKCiMjIyMjICgzKSBGYWN0b3IgTG9hZGluZ3MKCkxhc3RseSwgd2UgbG9va2VkIGF0IHRoZSAqKmZhY3RvciBsb2FkaW5ncyoqIG9mIHRoZSBmaW5hbCBmb3VyLWZhY3RvciBzb2x1dGlvbi4gQmVsb3cgeW91IGNhbiBzZWUgdGhlIHJvdGF0ZWQgKGkuZS4sIHZhcmltYXgpIGFuZCB1bnJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzLiBUaGUgbG9hZGluZ3MgYXJlIHNob3duIHdpdGggYSBjdXQtb2ZmIG9mIDAuNDAgYW5kIHJvdW5kZWQgdG8gdGhyZWUgZGVjaW1hbCBwbGFjZXMuIFRoZSB1bnJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzIGFyZSBkaWZmaWN1bHQgdG8gaW50ZXJwcmV0OiBhbGwgaXRlbXMgbG9hZGVkIHN0cm9uZ2x5IG9udG8gZmFjdG9yIDEgKGkuZS4sIGxvYWRpbmcgd2FzIGdyZWF0ZXIgdGhhbiAwLjQwKS4gVGhlIHJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzIHdlcmUgbW9yZSBlYXN5IHRvIGludGVycHJldCAoc2VlIGJlbG93IGZvciBtb3JlIGRldGFpbHMpLgoKYGBge3J9CgojIFVucm90YXRlZCBGYWN0b3IgTG9hZGluZ3MgCnByaW50KGZhX2ZvdXIyJGxvYWRpbmdzLCBjdXRvZmYgPSAwLjQwLCBkaWdpdHMgPSAzKQoKIyBSb3RhdGVkIChpLmUuLCB2YXJpbWF4KSBGYWN0b3IgTG9hZGluZ3MgCnByaW50KGZhX2ZvdXJfdjIkbG9hZGluZ3MsIGN1dG9mZiA9IDAuNDAsIGRpZ2l0cyA9IDMpCgpgYGAKCiMjIyMgUmVsaWFiaWxpdHkgQW5hbHlzZXMKCkluIG9yZGVyIHRvIHZhbGlkYXRlIHRoZSBTQUQsIHdlIGNvbXBsZXRlZCBhIHJlbGlhYmlsaXR5IGFuYWx5c2lzIChpLmUuLCBpcyB0aGUgc2NhbGUgY29uc2lzdGVudCkgYnkgbG9va2luZyBhdCB0aGUgc3BsaXQtaGFsZiByZWxpYWJpbGl0eSB1c2luZyBDcm9uYmFjaCdzIGFscGhhLiBUaGlzIG1ldGhvZCBpcyB0aGUgbW9zdCBjb21tb24gbWVhc3VyZSBvZiBzY2FsZSByZWxpYWJpbGl0eSAoRmllbGQgZXQgYWwuLCAyMDEyKTogdGhlIGRhdGEgZm9yIGVhY2ggcGFydGljaXBhbnQgaXMgcmFuZG9tbHkgc3BsaXQgaW50byB0d28gc2V0cywgd2hpY2ggZm9ybXMgYSAiaGFsZiIgc3BsaXQgZm9yIHRoZSBzY2FsZS4gVGhlbiwgYSBjb3JyZWxhdGlvbiBpcyBjYWxjdWxhdGVkIGJldHdlZW4gdGhlc2Ugc2V0cyB0byBkZXRlcm1pbmUgaG93IHNpbWlsYXIgdGhleSBhcmU6IGhpZ2hlciByZWxpYWJpbGl0eSB3b3VsZCBiZSBzZWVuIHdpdGggaGlnaGx5IGNvcnJlbGF0ZWQgc2V0cy4gU2luY2UgdGhlIHdheSB0aGF0IHRoZSBkYXRhIGlzIHNwbGl0IGNhbiBpbXBhY3QgdGhlIGNvcnJlbGF0aW9ucywgQ3JvbmJhY2gncyBhbHBoYSByZXByZXNlbnRzIGFuIGF2ZXJhZ2Ugb2YgYWxsIHRoZSBwb3NzaWJsZSBzcGxpdHMgdXNpbmcgdGhlIGZvbGxvd2luZyBlcXVhdGlvbjoKCiQkXGFscGhhID0gIFxmcmFje05eMiBcb3ZlcmxpbmV7Q292fX17XHN1bSBzX3tpdGVtfV4yICsgXHN1bSBDb3Zfe2l0ZW19fSAkJAoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRvIG9idGFpbiB0aGUgYmVzdCByZWxpYWJpbGl0eSBtZWFzdXJlLCB3ZSBtdXN0ICoqZGl2aWRlIG91ciBkYXRhIGludG8gYW55IHN1YnNjYWxlcyoqLCB3aGljaCBpbiB0aGlzIGNhc2UsIGFyZSBvdXIgKip0aHJlZSBmYWN0b3JzKiogZnJvbSBvdXIgZmFjdG9yIGFuYWx5c2lzLiBUaGVyZWZvcmUsIHdlIHNwbGl0IHRoZSBkYXRhIGludG8gdGhyZWUgc2V0cyBmb3IgdGhlIHJlbGlhYmlsaXR5IGFuYWx5c2lzLiAqKGNsaWNrIHRvIHNlZSBjb2RlKSoKCjwvc3VtbWFyeT4KCmBgYHtyfQoKIyBzcGxpdCB0aGUgZGF0YSByZXNwZWN0aXZlIHRvIHRoZSAzIGZhY3RvcnMgZnJvbSB0aGUgRkEgdG8gcGVyZm9ybSB0aGUgcmVsaWFiaWxpdHkgYW5hbHlzaXMKICAjIGZhY3RvciAxIChpdGVtczogMSwgMiwgMykKICBmMV9kYXRhID0gZmFfZGF0YTIgJT4lIHNlbGVjdChTQURfMTpTQURfMykKICAjIGZhY3RvciAyIChpdGVtczogOCwgOSwgMTAsIDExKQogIGYyX2RhdGEgPSBmYV9kYXRhMiAlPiUgc2VsZWN0KFNBRF84OlNBRF8xMSkKICAjIGZhY3RvciAzIChpdGVtczogNSwgNiwgNykKICBmM19kYXRhID0gZmFfZGF0YTIgJT4lIHNlbGVjdChTQURfNTpTQURfNykKICAjIGZhY3RvciA0IChpdGVtczogMTIsIDEzKQogIGY0X2RhdGEgPSBmYV9kYXRhMiAlPiUgc2VsZWN0KFNBRF8xMiwgU0FEXzEzKQoKYGBgCgo8L2RldGFpbHM+Cgo8ZGV0YWlscz4KCjxzdW1tYXJ5PgoKT25jZSB3ZSBoYXZlIG91ciBzdWJzY2FsZXMsIHdlICoqY29tcGxldGVkIHRoZSByZWxpYWJpbGl0eSBhbmFseXNpcyBvbiAqZWFjaCBzdWJzY2FsZSouKiogKihjbGljayB0byBzZWUgY29kZSkqCgo8L3N1bW1hcnk+CgpgYGB7cn0KCiMgY29tcHV0ZSByZWxpYWJpbGl0eSBhbmFseXNpcyBmb3IgZWFjaCBzdWJzY2FsZSB1c2luZyAiYWxwaGEoKSIgZnVuY3Rpb24gaW4gInBzeWNoIiBwYWNrYWdlCiAgIyBmYWN0b3IgMQogIGYxX3JlbCA9IHBzeWNoOjphbHBoYShmMV9kYXRhKQogICMgZmFjdG9yIDIKICBmMl9yZWwgPSBwc3ljaDo6YWxwaGEoZjJfZGF0YSkKICAjIGZhY3RvciAzCiAgZjNfcmVsID0gcHN5Y2g6OmFscGhhKGYzX2RhdGEpCiAgIyBmYWN0b3IgNAogIGY0X3JlbCA9IHBzeWNoOjphbHBoYShmNF9kYXRhKQoKYGBgCgo8L2RldGFpbHM+CgpUbyB2aWV3IHRoZSBhbmFseXNpcywgd2UgYnJva2UgaXQgZG93biBpbnRvIHRocmVlIGNvbXBvbmVudHM6ICgxKSB0aGUgYWxwaGEgdmFsdWVzIGFuZCBvdmVyYWxsIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgc3Vic2NhbGVzLCAoMikgYWxwaGEgZHJvcCB2YWx1ZXMgKGkuZS4sIHRoZSBhbHBoYSB2YWx1ZXMgaWYgYW4gaXRlbSB3YXMgZHJvcHBlZCwgYW5kICgzKSB0aGUgaXRlbSBzdGF0aXN0aWNzLgoKIyMjIyMgKDEpIEFscGhhIFZhbHVlcwoKVGhlIGFscGhhIHZhbHVlcyBmcm9tIHRoZSByZWxpYWJpbGl0eSBhbmFseXNlcyBpbmNsdWRlZCBDcm9uYmFjaCdzICRcYWxwaGEkIChpLmUuLCBiYXNlZCBvbiB0aGUgY292YXJpYW5jZXMpLCBhIHN0YW5kYXJkaXplZCAkXGFscGhhJCAoaS5lLiwgYmFzZWQgb24gdGhlIGNvcnJlbGF0aW9ucyksIGFuZCBHdXR0bWFuJ3MgTGFtYmRhIDYuIEFkZGl0aW9uYWxseSwgdGhlIG92ZXJhbGwgYXZlcmFnZSBjb3JyZWxhdGlvbiwgbWVhbiwgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBmb3IgdGhlIHN1YnNjYWxlIGlzIHNob3duIChzZWUgdGFibGUgYmVsb3cgZm9yIG1vcmUgZGV0YWlscykuCgotICAgQXMgc2VlbiBpbiB0aGUgdGFibGUsIENyb25iYWNoJ3MgJFxhbHBoYSQgd2FzIHdpdGhpbiB0aGUgYWNjZXB0YWJsZSByYW5nZSAoaS5lLiwgZ3JlYXRlciB0aGFuIC43MDsgS2xpbmUsIDE5OTkpIGZvciBGYWN0b3IgMSAoJFxhbHBoYV9DJCA9IGByIHJvdW5kKGZhX3JlbF9hbHBoYXMkcmF3X2FscGhhWzFdLCAyKWApLCBGYWN0b3IgMiAoJFxhbHBoYV9DJCA9IGByIHJvdW5kKGZhX3JlbF9hbHBoYXMkcmF3X2FscGhhWzJdLCAyKWApLCBhbmQgRmFjdG9yIDMgKCRcYWxwaGFfQyQgPSBgciByb3VuZChmYV9yZWxfYWxwaGFzJHJhd19hbHBoYVszXSwgMilgKSwgYnV0IG5vdCBmb3IgRmFjdG9yIDQgKCRcYWxwaGFfQyQgPSBgciByb3VuZChmYV9yZWxfYWxwaGFzJHJhd19hbHBoYVs0XSwgMilgKS4gVGhlIG92ZXJhbGwgY29ycmVsYXRpb24gZm9yIEZhY3RvciAxLCAqciooYHIgZjFfcmVsJGl0ZW0uc3RhdHNbMSwgIm4iXSAtIDJgKSBgciByb3VuZChmYV9yZWxfYWxwaGFzJGF2ZXJhZ2VfclsxXSwyKWAsIHdhcyBzdHJvbmcuIEZhY3RvciAyLCAqciooYHIgZjJfcmVsJGl0ZW0uc3RhdHNbMSwgIm4iXSAtIDJgKSBgciByb3VuZChmYV9yZWxfYWxwaGFzJGF2ZXJhZ2VfclsyXSwyKWAsIEZhY3RvciAzLCAqciooYHIgZjNfcmVsJGl0ZW0uc3RhdHNbMSwgIm4iXSAtIDJgKSBgciByb3VuZChmYV9yZWxfYWxwaGFzJGF2ZXJhZ2VfclszXSwyKWAsIGFuZCBGYWN0b3IgNCwgKnIqKGByIGYzX3JlbCRpdGVtLnN0YXRzWzEsICJuIl0gLSAyYCkgYHIgcm91bmQoZmFfcmVsX2FscGhhcyRhdmVyYWdlX3JbNF0sMilgLCB3ZXJlIG1vZGVyYXRlLiBBbGwgY29ycmVsYXRpb25zIHdlcmUgcG9zaXRpdmUuIFRoZXNlIHN0YXRpc3RpY3Mgd2VyZSBmdXJ0aGVyIGV4cGxvcmVkIHdpdGggZHJvcHBlZCBpdGVtcy4KCmBgYHtyfQojIHNob3cgdGhlIGFscGhhIHZhbHVlcyBmcm9tIHRoZSAzIHN1YnNjYWxlcwogICMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgMyByZWxpYWJpbGl0eSBhbmFseXNlcwogIGZhX3JlbF9hbHBoYXMgPSBhcy5kYXRhLmZyYW1lKHJiaW5kKCJGYWN0b3IgMSIgPSBkcGx5cjo6c2VsZWN0KGYxX3JlbCR0b3RhbCwgLWMoIlMvTiIsICJhc2UiLCAibWVkaWFuX3IiKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWN0b3IgMiIgPSBkcGx5cjo6c2VsZWN0KGYyX3JlbCR0b3RhbCwgLWMoIlMvTiIsICJhc2UiLCAibWVkaWFuX3IiKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWN0b3IgMyIgPSBkcGx5cjo6c2VsZWN0KGYzX3JlbCR0b3RhbCwgLWMoIlMvTiIsICJhc2UiLCAibWVkaWFuX3IiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhY3RvciA0IiA9IGRwbHlyOjpzZWxlY3QoZjRfcmVsJHRvdGFsLCAtYygiUy9OIiwgImFzZSIsICJtZWRpYW5fciIpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgIyBhZGQgYW4gZXh0cmEgY29sdW1uIGZvciB0aGUgIm92ZXJhbGwiIG9yIGF2ZXJhZ2UgYWxwaGEKICBmYV9yZWxfYWxwaGFzID0gY2JpbmQoIk92ZXJhbGwgYWxwaGEiID0gYyhtZWFuKGFzLm51bWVyaWMoZHBseXI6OnNlbGVjdChmMV9yZWwkdG90YWwsIGMoInJhd19hbHBoYSIsICJzdGQuYWxwaGEiKSkpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbihhcy5udW1lcmljKGRwbHlyOjpzZWxlY3QoZjJfcmVsJHRvdGFsLCBjKCJyYXdfYWxwaGEiLCAic3RkLmFscGhhIikpKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oYXMubnVtZXJpYyhkcGx5cjo6c2VsZWN0KGYzX3JlbCR0b3RhbCwgYygicmF3X2FscGhhIiwgInN0ZC5hbHBoYSIpKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oYXMubnVtZXJpYyhkcGx5cjo6c2VsZWN0KGY0X3JlbCR0b3RhbCwgYygicmF3X2FscGhhIiwgInN0ZC5hbHBoYSIpKSkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFfcmVsX2FscGhhcykKCiAgIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgdGFibGUKICBrYWJsZShmYV9yZWxfYWxwaGFzLCBjYXB0aW9uID0gIlJlbGlhYmlsaXR5IEFuYWx5c2lzIGZvciBTdWJzY2FsZXMgaW4gdGhlIFNBRDogQWxwaGEgVmFsdWVzIiwgZGlnaXRzID0gNCwgYWxpZ24gPSAnYycsIAogICAgICAgIGNvbC5uYW1lcyA9IGMoIk92ZXJhbGwgYWxwaGEiLCAiQ3JvbmJhY2gncyBhbHBoYSIsICJTdGFuZGFyZGl6ZWQgYWxwaGEiLCAiR3V0dG1hbidzIGxhbWJkYSA2IiwgIkF2ZXJhZ2UgciIsICJNIiwgIlNEIikpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBUKSAlPiUgCiAgICBrYWJsZV9jbGFzc2ljKCkKICAKYGBgCgojIyMjIyAoMikgQWxwaGEgRHJvcCBWYWx1ZXMKClRvIGZ1cnRoZXIgZXhwbG9yZSB0aGUgcmVsaWFiaWxpdHkgb2YgZWFjaCBzdWJzY2FsZSwgd2UgbG9va2VkIGF0IHRoZSBhbHBoYSB2YWx1ZXMgYWZ0ZXIgcmVtb3ZpbmcgZWFjaCBpdGVtLiBUaGlzIGFsbG93ZWQgdXMgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBpdGVtIHdhcyByZWR1Y2luZyB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIHN1YnNjYWxlLiBUaGF0IGlzLCBpZiBkcm9wcGluZyBhbiBpdGVtIGluY3JlYXNlZCAkXGFscGhhJCBvciB0aGUgY29ycmVsYXRpb24sIHRoZW4gcmVtb3ZpbmcgdGhlIGl0ZW0gZnJvbSB0aGUgYW5hbHlzaXMgc2hvdWxkIGJlIGNvbnNpZGVyZWQuIFRoZSBkYXRhIHByZXNlbnRlZCBpbiB0aGUgdGFibGUgYmVsb3cgc2hvd3MgQ3JvbmJhY2gncyAkXGFscGhhJCwgc3RhbmRhcmRpemVkICRcYWxwaGEkLCBHdXR0bWFuJ3MgTGFtYmRhIDYsIGFuZCB0aGUgYXZlcmFnZSBjb3JyZWxhdGlvbi4KCi0gICBBcyBzZWVuIGluIHRoZSB0YWJsZSBiZWxvdywgZHJvcHBpbmcgYW4gaXRlbSBkaWQgbm90IGltcHJvdmUgcmVsaWFiaWxpdHkgZm9yIEZhY3RvciAxIChyYW5nZSBvZiAkXGFscGhhX0MkID0gYHIgcm91bmQobWluKGZhX3JlbF9hZHJvcCRyYXdfYWxwaGFbMTozXSksIDIpYCAtIGByIHJvdW5kKG1heChmYV9yZWxfYWRyb3AkcmF3X2FscGhhWzE6M10pLCAyKWApLCBGYWN0b3IgMiAocmFuZ2Ugb2YgJFxhbHBoYV9DJCA9IGByIHJvdW5kKG1pbihmYV9yZWxfYWRyb3AkcmF3X2FscGhhWzQ6N10pLCAyKWAgLSBgciByb3VuZChtYXgoZmFfcmVsX2Fkcm9wJHJhd19hbHBoYVs0OjddKSwgMilgKSwgRmFjdG9yIDMgKHJhbmdlIG9mICRcYWxwaGFfQyQgPSBgciByb3VuZChtaW4oZmFfcmVsX2Fkcm9wJHJhd19hbHBoYVs4OjEwXSksIDIpYCAtIGByIHJvdW5kKG1heChmYV9yZWxfYWRyb3AkcmF3X2FscGhhWzg6MTBdKSwgMilgKSwgYW5kIEZhY3RvciA0IChyYW5nZSBvZiAkXGFscGhhX0MkID0gYHIgcm91bmQobWluKGZhX3JlbF9hZHJvcCRyYXdfYWxwaGFbMTE6MTJdKSwgMilgIC0gYHIgcm91bmQobWF4KGZhX3JlbF9hZHJvcCRyYXdfYWxwaGFbMTE6MTJdKSwgMilgKS4gCi0gV2l0aCByZXNwZWN0IHRvIHRoZSBhdmVyYWdlIGNvcnJlbGF0aW9uLCBkcm9wcGluZyBhbiBpdGVtIG9ubHkgc2hvd2VkIGEgc3Vic3RhbnRpYWxseSBpbXByb3ZlbWVudCBmb3IgRmFjdG9yIDEsIHdoZXJlIGRyb3BwaW5nIGl0ZW0gMyByZXN1bHRlZCBpbiBhIHN0cm9uZ2VyIGNvcnJlbGF0aW9uLCAqciooYHIgZjJfcmVsJGl0ZW0uc3RhdHNbMSwgIm4iXSAtIDJgKSA9IGByIHJvdW5kKGZhX3JlbF9hZHJvcCRhdmVyYWdlX3JbM10sIDIpYC4gVGhpcyB3YXMgZXhwbG9yZWQgZnVydGhlciB3aXRoIHRoZSBpdGVtcyBzdGF0aXN0aWNzLgoKYGBge3J9CiMgc2hvdyB0aGUgYWxwaGEgZHJvcCB2YWx1ZXMgZnJvbSB0aGUgMyBzdWJzY2FsZXMKICAjIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggdGhlIGluZm9ybWF0aW9uCiAgZmFfcmVsX2Fkcm9wID0gYXMuZGF0YS5mcmFtZShyYmluZChkcGx5cjo6c2VsZWN0KGYxX3JlbCRhbHBoYS5kcm9wLCBjKCJyYXdfYWxwaGEiLCAic3RkLmFscGhhIiwgIkc2KHNtYykiLCAiYXZlcmFnZV9yIikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QoZjJfcmVsJGFscGhhLmRyb3AsIGMoInJhd19hbHBoYSIsICJzdGQuYWxwaGEiLCAiRzYoc21jKSIsICJhdmVyYWdlX3IiKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChmM19yZWwkYWxwaGEuZHJvcCwgYygicmF3X2FscGhhIiwgInN0ZC5hbHBoYSIsICJHNihzbWMpIiwgImF2ZXJhZ2VfciIpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KGY0X3JlbCRhbHBoYS5kcm9wLCBjKCJyYXdfYWxwaGEiLCAic3RkLmFscGhhIiwgIkc2KHNtYykiLCAiYXZlcmFnZV9yIikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQoKICAjIHVzZSBrYWJsZSB0byBzaG93IHRoZSB0YWJsZQogIGthYmxlKGZhX3JlbF9hZHJvcCwgY2FwdGlvbiA9ICJSZWxpYWJpbGl0eSBBbmFseXNpcyBmb3IgU3Vic2NhbGVzIGluIHRoZSBTQUQ6IEFscGhhIERyb3AgVmFsdWVzIiwgZGlnaXRzID0gNCwgYWxpZ24gPSAnYycsIAogICAgICAgIGNvbC5uYW1lcyA9IGMoIkNyb25iYWNoJ3MgYWxwaGEiLCAiU3RhbmRhcmRpemVkIGFscGhhIiwgIkd1dHRtYW4ncyBsYW1iZGEgNiIsICJBdmVyYWdlIHIiKSkgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IFQpICU+JQogIHBhY2tfcm93cyhpbmRleCA9IGMoIkZhY3RvciAxIiA9IG5jb2woZjFfZGF0YSksICJGYWN0b3IgMiIgPSBuY29sKGYyX2RhdGEpLCAiRmFjdG9yIDMiID0gbmNvbChmM19kYXRhKSwgIkZhY3RvciA0IiA9IG5jb2woZjRfZGF0YSkpKSAlPiUgCiAgICBrYWJsZV9jbGFzc2ljKCkKCmBgYAoKIyMjIyMgKDMpIEl0ZW0gU3RhdGlzdGljcwoKVGhlIGl0ZW0gc3RhdGlzdGljcyB3ZXJlIGV4cGxvcmVkIHRvIGRldGVybWluZSB3aGV0aGVyIGEgY2VydGFpbiBpdGVtIGRpZCBub3QgY29ycmVsYXRlIHdpdGggdGhlIG92ZXJhbGwgc3Vic2NhbGUuIFRoZSB0YWJsZSBiZWxvdyBzaG93czogKnIqLCB3aGljaCBpcyB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gZWFjaCBpdGVtIGFuZCB0aGUgdG90YWwgc2NvcmUgZnJvbSB0aGUgc3Vic2NhbGUgKGkuZS4sIHRoZSBpdGVtLXRvdGFsIGNvcnJlbGF0aW9ucyksIHdoaWNoIGluY2x1ZGVzIHRoZSBpdGVtIGl0c2VsZjsgYW5kICpEcm9wKiwgd2hpY2ggaXMgdGhlIGNvcnJlbGF0aW9uIG9mIGFuIGl0ZW0gd2l0aCB0aGUgc3Vic2NhbGUgYWZ0ZXIgcmVtb3ZpbmcgdGhlIGl0ZW0gKGkuZS4sIHRoZSBpdGVtLXJlc3QgY29ycmVsYXRpb24gb3IgdGhlIGNvcnJlY3RlZCBpdGVtLXRvdGFsIGNvcnJlbGF0aW9uKS4gQWRkaXRpb25hbGx5LCB0aGUgc2FtcGxlIHNpemUsIG1lYW4sIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gaXMgc2hvd24uCgotICAgTm8gaXNzdWVzIHdlcmUgZm91bmQgd2l0aCB0aGUgaXRlbSBzdGF0aXN0aWNzIGZvciBGYWN0b3IgMSwgKnIqKGByIGYxX3JlbCRpdGVtLnN0YXRzWzEsICJuIl0gLSAyYCkgYHIgcF9yb3VuZChtaW4oZmFfcmVsX2l0ZW0kci5kcm9wWzE6M10pKWAgLSBgciBwX3JvdW5kKG1heChmYV9yZWxfaXRlbSRyLmRyb3BbMTozXSkpYCwgRmFjdG9yIDIsICpyKihgciBmMl9yZWwkaXRlbS5zdGF0c1sxLCAibiJdIC0gMmApIGByIHBfcm91bmQobWluKGZhX3JlbF9pdGVtJHIuZHJvcFs0OjddKSlgIC0gYHIgcF9yb3VuZChtYXgoZmFfcmVsX2l0ZW0kci5kcm9wWzQ6N10pKWAsIEZhY3RvciAzLCAqciooYHIgZjNfcmVsJGl0ZW0uc3RhdHNbMSwgIm4iXSAtIDJgKSBgciBwX3JvdW5kKG1pbihmYV9yZWxfaXRlbSRyLmRyb3BbODoxMF0pKWAgLSBgciBwX3JvdW5kKG1heChmYV9yZWxfaXRlbSRyLmRyb3BbODoxMF0pKWAsIGFuZCBGYWN0b3IgNCwgKnIqKGByIGYzX3JlbCRpdGVtLnN0YXRzWzEsICJuIl0gLSAyYCkgYHIgcF9yb3VuZChtaW4oZmFfcmVsX2l0ZW0kci5kcm9wWzExOjEyXSkpYCAtIGByIHBfcm91bmQobWF4KGZhX3JlbF9pdGVtJHIuZHJvcFsxMToxMl0pKWAuIFRoYXQgaXMsIG5vIGl0ZW1zIGhhZCBhIGl0ZW0tcmVzdCBjb3JyZWxhdGlvbiAoaS5lLiwgdGhlIGRyb3AgY29sdW1uIGluIHRoZSB0YWJsZSBiZWxvdykgYmVsb3cgdGhlIGN1dC1vZmYgKGkuZS4sIC4zMDsgRmllbGQgZXQgYWwuLCAyMDEyKS4KCmBgYHtyfQoKIyBzaG93IHRoZSBjb3JyZWxhdGlvbnMgZm9yIHRoZSAzIHN1YnNjYWxlcwogICMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCB0aGUgaW5mb3JtYXRpb24KICBmYV9yZWxfaXRlbSA9IGFzLmRhdGEuZnJhbWUocmJpbmQoZHBseXI6OnNlbGVjdChmMV9yZWwkaXRlbS5zdGF0cywgLWMoInN0ZC5yIiwgInIuY29yIikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChmMl9yZWwkaXRlbS5zdGF0cywgLWMoInN0ZC5yIiwgInIuY29yIikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChmM19yZWwkaXRlbS5zdGF0cywgLWMoInN0ZC5yIiwgInIuY29yIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KGY0X3JlbCRpdGVtLnN0YXRzLCAtYygic3RkLnIiLCAici5jb3IiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKCiAgIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgdGFibGUKICBrYWJsZShmYV9yZWxfaXRlbSwgY2FwdGlvbiA9ICJSZWxpYWJpbGl0eSBBbmFseXNpcyBmb3IgU3Vic2NhbGVzIGluIHRoZSBTQUQ6IEl0ZW0gU3RhdGlzdGljcyIsIGRpZ2l0cyA9IDQsIGFsaWduID0gJ2MnLCAKICAgICAgICBjb2wubmFtZXMgPSBjKCJOIiwgInIiLCAiRHJvcCIsICJNIiwgIlNEIikpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBUKSAlPiUKICBwYWNrX3Jvd3MoaW5kZXggPSBjKCJGYWN0b3IgMSIgPSBuY29sKGYxX2RhdGEpLCAiRmFjdG9yIDIiID0gbmNvbChmMl9kYXRhKSwgIkZhY3RvciAzIiA9IG5jb2woZjNfZGF0YSksICJGYWN0b3IgNCIgPSBuY29sKGY0X2RhdGEpKSkgICU+JSAKICAgIGthYmxlX2NsYXNzaWMoKQoKYGBgCgpPdmVyYWxsLCB0aGUgcmVsaWFiaWxpdHkgZm9yIEZhY3RvciAxLCBGYWN0b3IgMiwgRmFjdG9yIDMsIGFuZCBGYWN0b3IgNCB3YXMgYWRlcXVhdGUuIEFsdGhvdWdoIEZhY3RvciAxIHNob3dlZCBtaXhlZCByZXN1bHRzIGZvciBpdGVtIDMgKGkuZS4sIGl0ZW0gd2FzIG5vdCBhcyBzdGFibGUgZm9yIGFscGhhKSwgRmFjdG9yIDEgd2FzIHN0YWJsZSBmb3IgYWxsIG90aGVyIGNvbXBhcmlzb25zL21lYXN1cmVzLCB0aGVyZWZvcmUgaXRlbSAzIHdhcyBub3QgcmVtb3ZlZCBmcm9tIHRoZSBzdWJzY2FsZS4gU2ltaWxhcmx5LCBGYWN0b3IgNCB3YXMgaW5zcGVjdGVkIGNhcmVmdWxseSBzaW5jZSBpdCB3YXMgYSB0d28tdGVtIGZhY3Rvci4gVGhlc2UgcmVzdWx0cyBzdWdnZXRzIHRoYXQgaXQgaXMgYSBzdGFibGUgZmFjdG9yIGFuZCBzbyBpdCB3YXMgaW5jbHVkZWQgaW4gZnVydGhlciBhbmFseXNlcy4KCiMjIyMgQ29uY2x1c2lvbnMKCiMjIyMjIFRoZSBQcmVzZW50IFN0dWR5CgpBIHByaW5jaXBhbCBheGlzIGZhY3RvciBhbmFseXNpcyB3YXMgdXNlZCB0byBhbmFseXplIHRoZSB1bmRlcmx5aW5nIGZhY3RvcnMgaW4gdGhlIDEzLWl0ZW0gU0FEIGludmVudG9yeSAoV2FyZCBldCBhbC4sIDIwMTcpIHVzaW5nIGFuIG9ydGhvZ29uYWwgcm90YXRpb24gKGkuZS4sIHZhcmltYXggcm90YXRpb24pLiBGYWN0b3JhYmlsaXR5IG9mIHRoZSBkYXRhIHdhcyBjb25maXJtZWQgdXNpbmc6ICgxKSBCYXJ0bGV0dCdzIHRlc3QgZm9yIGNvcnJlbGF0aW9uIGFkZXF1YWN5LCAkXGNoaV57Mn0kKGByIGZhX2JhcnRlc3QkZGZgKSA9IGByIHJvdW5kKGZhX2JhcnRlc3QkY2hpc3EsIDIpYCwgKnAqIGByIHBfcm91bmQoZmFfYmFydGVzdCRwLnZhbHVlKWAsIHdoaWNoIGNvbmZpcm1lZCB0aGF0IGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHRoZSBpdGVtcyB3ZXJlIHN1ZmZpY2llbnRseSBsYXJnZTsgYW5kICgyKSB0aGUgS2Fpc2VyLU1leWVyLU9sa2luIG1lYXN1cmUgZm9yIHNhbXBsaW5nIGFkZXF1YWN5IChNU0EpLCAkTVNBX3tvdmVyYWxsfSQgPSBgciByb3VuZChmYV9rbW8kTVNBLCAyKWAsICRNU0FfezEtMTN9JCA9IGByIG1pbihyb3VuZChmYV9rbW8kTVNBaSwgMikpYCAtIGByIG1heChyb3VuZChmYV9rbW8kTVNBaSwgMikpYCwgd2hpY2ggY29uZmlybWVkIHRoYXQgYm90aCB0aGUgb3ZlcmFsbCBNU0EgYW5kIGVhY2ggaXRlbSdzIE1TQSB3ZXJlIGFib3ZlIHRoZWlyIHJlcXVpcmVkIGNyaXRlcmlhICgwLjYwIGFuZCAwLjc3LCByZXNwZWN0aXZlbHk7IEthaXNlciwgMTk3NCkuIFRoZSBhcHByb3ByaWF0ZSBudW1iZXIgb2YgZmFjdG9ycyAoaS5lLiwgZm91cikgd2FzIGNvbmZpcm1lZCB1c2luZyAoMSkgYSBwYXJhbGxlbCBhbmFseXNpcyBzY3JlZSBwbG90LCB3aGVyZSB0aGUgdHdvLSAsIHRocmVlLSwgYW5kIGZvdXItZmFjdG9yIHNvbHV0aW9ucyB3ZXJlIGNob3NlbiB0byBjb21wYXJlIGZvciB0aGUgYmVzdCBmaXQgZm9yIHRoZSBkYXRhOyAoMikgdGhlIGVpZ2VuIHZhbHVlcyAoZS5nLiwgYHIgcm91bmQoZmFfZm91cl92JGUudmFsdWVzWzE6NF0sIDMpYCwgZm9yIGZhY3RvcnMgMSB0byA0LCByZXNwZWN0aXZlbHkpIGZvciB0aGUgdW5yb3RhdGVkIHNvbHV0aW9uLCB3aGVyZSB0aHJlZSBtZWFuaW5nZnVsIGZhY3RvcnMgd2VyZSBmb3VuZCB1c2luZyBLYWlzZXIncyBjcml0ZXJpb24gKGkuZS4sIGVpZ2VuIHZhbHVlcyBncmVhdGVyIHRoYW4gb25lKTsgYW5kICgzKSB0aGUgZmFjdG9yIHN0cnVjdHVyZSBvZiB0aGUgdHdvLSwgdGhyZWUtLCBhbmQgZm91ci1mYWN0b3Igc29sdXRpb25zLCB3aGVyZSB0aGUgZm91ci1mYWN0b3Igc29sdXRpb24gc2hvd2VkIGEgYmV0dGVyIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YSBhbmQgd2FzIG1vcmUgaW50ZXJwcmV0YWJsZS4gVGhlcmVmb3JlLCB0aGUgZm91ci1mYWN0b3Igc29sdXRpb24gd2FzIGNob3NlbiBmb3IgdGhlIGZpbmFsIGFuYWx5c2lzIGFuZCBhbiBvcnRob2dvbmFsIChpLmUuLCB2YXJpbWF4KSByb3RhdGlvbiB3YXMgY2hvc2VuIGZvciB0aGUgZmluYWwgYW5hbHlzaXMuIEFmdGVyIGFuIGluaXRpYWwgZm91ci1mYWN0b3Igc29sdXRpb24gd2FzIGNvbXBsZXRlZCB1c2luZyBhbGwgMTMgaXRlbXMgaW4gdGhlIFNBRCwgaG93ZXZlciwgaXRlbSA0IHdhcyBzcGxpdC1sb2FkZWQgKGkuZS4sIGJldHdlZW4gZmFjdG9yIDEgYW5kIDMpLiBUaGVyZWZvcmUsIHRoaXMgaXRlbSB3YXMgZHJvcHBlZCBhbmQgYSBmaW5hbCBmb3VyLWZhY3RvciBzb2x1dGlvbiB3YXMgY29tcGxldGVkIHdpdGggdGhlIHJlbWFpbmluZyAxMiBpdGVtcyBpbiB0aGUgU0FELiBUaGlzIGZpbmFsIHNvbHV0aW9uIGFjaGlldmVkIHNpbXBsZSBzdHJ1Y3R1cmUgYW5kIHdhcyB1c2VkIGZvciBzdWJzZXF1ZW50IGFuYWx5c2VzLgoKVGhlIGZvciBlYWNoIHJlbGlhYmlsaXR5IG9mIHRoZSBmb3VyIGZhY3RvcnMgd2FzIGFzc2Vzc2VkIHVzaW5nIENyb25iYWNoJ3MgJFxhbHBoYSQsIHdoaWNoIHdhcyB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UgKGkuZS4sIGdyZWF0ZXIgdGhhbiAuNzA7IEtsaW5lLCAxOTk5KSBmb3IgRmFjdG9yIDEgKCRcYWxwaGFfQyQgPSBgciByb3VuZChmYV9yZWxfYWxwaGFzJHJhd19hbHBoYVsxXSwgMilgKSwgRmFjdG9yIDIgKCRcYWxwaGFfQyQgPSBgciByb3VuZChmYV9yZWxfYWxwaGFzJHJhd19hbHBoYVsyXSwgMilgKSwgYW5kIEZhY3RvciAzICgkXGFscGhhX0MkID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbM10sIDIpYCksIGJ1dCBub3QgZm9yIEZhY3RvciA0ICgkXGFscGhhX0MkID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbNF0sIDIpYCkuIFRoZXJlZm9yZSwgdGhlIHJlbGlhYmlsaXR5IGZvciBGYWN0b3IgMSwgRmFjdG9yIDIsIGFuZCBGYWN0b3IgMyB3YXMgYWRlcXVhdGUuIEZhY3RvciAxIGRpZCBzaG93IGEgbGVzcyBzdGFibGUgaXRlbSAoaS5lLiwgMyksIHdoaWNoIHNob3dlZCBhIHNtYWxsIGltcHJvdmVtZW50IGluIGNvcnJlbGF0aW9uIHdoZW4gZHJvcHBlZCAoZnJvbSBgciByb3VuZChmYV9yZWxfYWxwaGFzJGF2ZXJhZ2VfclsxXSwgMilgIHRvIGByIHJvdW5kKGZhX3JlbF9hZHJvcCRhdmVyYWdlX3JbM10sIDIpYCApLiBGYWN0b3IgNCB3YXMgYSB3ZWFrZXIgZmFjdG9yIHdpdGggb25seSB0d28gaXRlbXMuIE92ZXJhbGwsIHRoZSBmb3VyIGZhY3RvcnMgYWxsIHNob3dlZCByZWxpYWJpbGl0eSBhbmQgc3RhYmlsaXR5LiBFYWNoIHdhcyB1c2VkIGFzIGEgc2VwYXJhdGUgc3Vic2NhbGUgZm9yIGZvbGxvd2luZyBhbmFseXNlcy4gVGhlIG1lYW4gc2NvcmVzIGZvciBlYWNoIGZhY3RvciB3ZXJlOiBGYWN0b3IgMSAqTSogPSBgciByb3VuZChkZXNfcXVlc19jb250X2Fjcm9zc1siU0FEX2RlcF9zY29yZSIsIm1lYW4iXSwgMilgICgqU0QqID0gYHIgcm91bmQoZGVzX3F1ZXNfY29udF90JG92ZXJhbGxbMTddLCAyKWApLCBGYWN0b3IgMiBNID0gYHIgcm91bmQoZGVzX3F1ZXNfY29udF90JG92ZXJhbGxbMjFdLCAyKWAgKCpTRCogPSBgciByb3VuZChkZXNfcXVlc19jb250X3Qkb3ZlcmFsbFsyMl0sIDIpYCksIEZhY3RvciAzICpNKiA9IGByIHJvdW5kKGRlc19xdWVzX2NvbnRfdCRvdmVyYWxsWzI2XSwgMilgICgqU0QqID0gYHIgcm91bmQoZGVzX3F1ZXNfY29udF90JG92ZXJhbGxbMjddLCAyKWApLCBhbmQgRmFjdG9yIDQgKk0qID0gYHIgcm91bmQoZGVzX3F1ZXNfY29udF90JG92ZXJhbGxbMzFdLCAyKWAgKCpTRCogPSBgciByb3VuZChkZXNfcXVlc19jb250X3Qkb3ZlcmFsbFszMl0sIDIpYCkuIFRoZSBtb2RlbCBhbHNvIHNob3dlZCBhIG1vZGVyYXRlIGZpdDogdGhlIFJvb3QgTWVhbiBTcXVhcmUgb2YgdGhlIFJlc2lkdWFsIChSTVNSOyBgciByb3VuZChmYV9mb3VyX3YyJHJtcywgMilgKS4gRnVydGhlciBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGNhbiBiZSBmb3VuZCBpbiB0aGUgW0Rlc2NyaXB0aXZlIFN0YXRpc3RpY3Mgc2VjdGlvbl0oI0RTKSBhYm92ZS4KClRoZSBpdGVtcyBpbiB0aGUgZmluYWwgc29sdXRpb24ncyBmYWN0b3JzIGV4cGxhaW5lZCBgciByb3VuZChzdW0odmFyX3BlciksIDIpYCUgb2YgdGhlIHZhcmlhbmNlIGFuZCBzdWdnZXN0ZWQgdGhlIGZvbGxvd2luZyBmb3VyIGZhY3RvcnM6IGRlcGVuZGVuY2UsIGVtb3Rpb25hbCBhdHRhY2htZW50LCBhY2Nlc3NpYmlsaXR5LCBhbmQgICBkaXN0cmFjdGliaWxpdHkuIERlcGVuZGVuY2Ugd2FzIHJlbGF0ZSB0byB0aGUgZGVncmVlIG9mIGRlcGVuZGVuY2Ugb24gb25lJ3Mgc21hcnRwaG9uZSwgaXQgY29uc2lzdGVkIG9mIDMgaXRlbXMgKGkuZS4sIFNBRCAxLCBTQUQgMiwgYW5kIFNBRCAzKSBhbmQgZXhwbGFpbmVkIGByIHJvdW5kKHZhcl9wZXJfdlsxXSwgMilgJSBvZiB0aGUgdmFyaWFuY2UgKGUuZy4sICJJIHdvdWxkIGhhdmUgdHJvdWJsZSBnZXR0aW5nIHRocm91Z2ggYSBub3JtYWwgZGF5IHdpdGhvdXQgbXkgc21hcnRwaG9uZS4iLCBhbmQgIkkgZmVlbCBsaWtlIEkgY291bGQgbm90IGxpdmUgd2l0aG91dCBteSBzbWFydHBob25lLiIpLiBFbW90aW9uYWwgYXR0YWNobWVudCB3YXMgcmVsYXRlZCB0byBvbmUncyBzbWFydHBob25lIHVzZSBmb3IgZW1vdGlvbmFsIHN1cHBvcnQsIGl0IGNvbnNpc3RlZCBvZiA0IGl0ZW1zIChpLmUsIFNBRCA4LCA5LCAxMCwgYW5kIDExKSBhbmQgZXhwbGFpbmVkIGByIHJvdW5kKHZhcl9wZXJfdlsyXSwgMilgJSBvZiB0aGUgdmFyaWFuY2UgKGUuZy4sICJJIGZlZWwgbG9uZWx5IHdoZW4gbXkgc21hcnRwaG9uZSBkb2VzIG5vdCByaW5nIG9yIHZpYnJhdGUgZm9yIHNldmVyYWwgaG91cnMuIiwgYW5kICJVc2luZyBteSBzbWFydHBob25lIG1ha2VzIG1lIGZlZWwgaGFwcHkuIikuIEFjY2Vzc2liaWxpdHkgd2FzIHJlbGF0ZWQgdG8gdGhlIGFiaWxpdHkgdG8gYWNlZXMgdGhlIHV0aWxpdHkgb2Ygb25lJ3MgcGhvbmUgKGUuZy4sIHBvd2VyZWQgb24sIGludGVybmV0IGFjY2VzcyksIGl0IGNvbnNpc3RlZCBvZiAzIGl0ZW1zIChpLmUuLCBTQUQgNSwgNiwgJiA3KSBhbmQgZXhwbGFpbmVkIGByIHJvdW5kKHZhcl9wZXJfdlszXSwgMilgJSBvZiB0aGUgdmFyaWFuY2UgKGUuZy4sICJJdCBkcml2ZXMgbWUgY3Jhenkgd2hlbiBteSBzbWFydHBob25lIHJ1bnMgb3V0IG9mIGJhdHRlcnkuIiwgYW5kICJJIGZlZWwgaW1wYXRpZW50IHdoZW4gdGhlIEludGVybmV0IGNvbm5lY3Rpb24gc3BlZWQgb24gbXkgc21hcnRwaG9uZSBpcyBzbG93LiIpLiBEaXN0cmFjdGliaWxpdHkgd2FzIHJlbGF0ZWQgdG8gb25lJ3Mgc21hcnRwaG9uZSByZXRhaW5pbmcgb25lJ3MgYXR0ZW50aW9uLCBpdCBjb25zaXN0ZWQgb2YgMiBpdGVtcyBhbmQgZXhwbGFpbmVkIGByIHJvdW5kKHZhcl9wZXJfdls0XSwgMilgJSBvZiB0aGUgdmFyaWFuY2UgKGUuZy4sICJJIGZpbmQgaXQgdG91Z2ggdG8gZm9jdXMgd2hlbmV2ZXIgbXkgc21hcnRwaG9uZSBpcyBuZWFyYnkuIiwgYW5kICJJIGJlY29tZSBsZXNzIGF0dGVudGl2ZSB0byBteSBzdXJyb3VuZGluZ3Mgd2hlbiBJJ20gdXNpbmcgbXkgc21hcnRwaG9uZS4iKS4gT25lIGl0ZW0gZGlkIG5vdCBjbGVhcmx5IGxvYWQgb250byBhbnkgb25lIGZhY3RvciBhbmQgd2FzIGV4Y2x1ZGVkIGZyb20gZnVydGhlciBhbmFseXNlcyAoaS5lLiwgaXRlbSA0OyBDb3N0ZWxsbyAmIE9zYm9ybmUsIDIwMDUpLiBUaGUgdGFibGVzIGJlbG93IGRlcGljdCB0aGUgZmluYWwgYW5kIGluaXRpYWwgKGkuZS4sIGluY2x1ZGluZyBpdGVtIDQpIGZvdXItZmFjdG9yIHNvbHV0aW9ucy4gdGhyZWUKCmBgYHtyIGNyZWF0ZSAmIHNob3cgZmFfdGhyZWVfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjcmVhdGUgdGFibGUgd2l0aCBhbGwgaXRlbXMsIGZhY3RvciBsb2FkaW5ncywgZWlnZW4gdmFsdWVzLCAlIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCwgYW5kIENyb25iYWNoJ3MgYWxwaGEgCgojIGdldCBmYWN0b3IgbG9hZGluZ3MKICBmYV9sb2FkIDwtIGFzLmRhdGEuZnJhbWUoZmFfZm91cl92MiRsb2FkaW5nc1sxOjEyLF0pCiAgIyBjaGFuZ2Ugcm93IG5hbWVzCiAgICAjIHJvdy5uYW1lcyhmYV9sb2FkKSA8LSBjKDE6bnJvdyhmYV9sb2FkKSkKICAgIAogICMgcmVvcmRlciBsb2FkaW5ncyB0byBtYXRjaCBmaW5hbCB0YWJsZQogICAgZmFfbG9hZCA8LSAKICAgICAgZmFfbG9hZCAlPiUKICAgICAgIyBhZGQgdGVtcG9yYXJ5IGNvbHVtbiB1c2VkIHRvIHJlb3JkZXIKICAgICAgbXV0YXRlKGl0ZW0gPSBjKHJvdy5uYW1lcyhmYV9mb3VyX3YyJGxvYWRpbmdzWzE6MTIsXSkpKSAlPiUgCiAgICAgICMgcmVvcmRlciB1c2luZyBzbGljZSAmIG1hdGNoCiAgICAgIHNsaWNlKG1hdGNoKGMoIlNBRF8xIiwgIlNBRF8yIiwgIlNBRF8zIiwgIlNBRF84IiwgIlNBRF85IiwgIlNBRF8xMCIsICJTQURfMTEiLCAiU0FEXzUiLCAiU0FEXzYiLCAiU0FEXzciLCAiU0FEXzEyIiwgIlNBRF8xMyIpLCBpdGVtKSkgJT4lIAogICAgICAjIHJlbW92ZSB0ZW1wIGNvbHVtbgogICAgICBzZWxlY3QoLWl0ZW0pCgojIG1ha2UgbGlzdCBvZiB0aGUgaXRlbXMgJiBvdGhlciBpbmZvCiAgZmFfdGFibGVfbGlzdCA8LSBjKCJJIHdvdWxkIGhhdmUgdHJvdWJsZSBnZXR0aW5nIHRocm91Z2ggYSBub3JtYWwgZGF5IHdpdGhvdXQgbXkgc21hcnRwaG9uZS4iLAogICAgICAgICAgICAgICAgICAgICJJdCB3b3VsZCBiZSBwYWluZnVsIGZvciBtZSB0byBnaXZlIHVwIG15IHNtYXJ0cGhvbmUgZm9yIGEgZGF5LiIsCiAgICAgICAgICAgICAgICAgICAgIkkgZmVlbCBsaWtlIEkgY291bGQgbm90IGxpdmUgd2l0aG91dCBteSBzbWFydHBob25lLiIsCiAgICAgICAgICAgICAgICAgICAgIkkgZmVlbCBsb25lbHkgd2hlbiBteSBzbWFydHBob25lIGRvZXMgbm90IHJpbmcgb3IgdmlicmF0ZSBmb3Igc2V2ZXJhbCBob3Vycy4iLAogICAgICAgICAgICAgICAgICAgICJVc2luZyBteSBzbWFydHBob25lIHJlbGlldmVzIG1lIG9mIG15IHN0cmVzcy4iLAogICAgICAgICAgICAgICAgICAgICJJIGZlZWwgZXhjaXRlZCB3aGVuIEkgaGF2ZSBhIG5ldyBtZXNzYWdlIG9yIG5vdGlmaWNhdGlvbi4iLAogICAgICAgICAgICAgICAgICAgICJVc2luZyBteSBzbWFydHBob25lIG1ha2VzIG1lIGZlZWwgaGFwcHkuIiwKICAgICAgICAgICAgICAgICAgICAiSXQgZHJpdmVzIG1lIGNyYXp5IHdoZW4gbXkgc21hcnRwaG9uZSBydW5zIG91dCBvZiBiYXR0ZXJ5LiIsCiAgICAgICAgICAgICAgICAgICAgIkkgYW0gdXBzZXQgYW5kIGFubm95ZWQgd2hlbiBJIGZpbmQgSSBkbyBub3QgaGF2ZSByZWNlcHRpb24gb24gbXkgc21hcnRwaG9uZS4iLAogICAgICAgICAgICAgICAgICAgICJJIGZlZWwgaW1wYXRpZW50IHdoZW4gdGhlIEludGVybmV0IGNvbm5lY3Rpb24gc3BlZWQgb24gbXkgc21hcnRwaG9uZSBpcyBzbG93LiIsCiAgICAgICAgICAgICAgICAgICAgIkkgZmluZCBpdCB0b3VnaCB0byBmb2N1cyB3aGVuZXZlciBteSBzbWFydHBob25lIGlzIG5lYXJieS4iLAogICAgICAgICAgICAgICAgICAgICJJIGJlY29tZSBsZXNzIGF0dGVudGl2ZSB0byBteSBzdXJyb3VuZGluZ3Mgd2hlbiBJ4oCZbSB1c2luZyBteSBzbWFydHBob25lLiIsCiAgICAgICAgICAgICAgICAgICAgIkVpZ2VuIFZhbHVlcyIsIAogICAgICAgICAgICAgICAgICAgICJWYXJpYW5jZSBFeHBsYWluZWQgKCUpIikKICAKIyBjcmVhdGUgdGhlIGZpbmFsIHRhYmxlCiAgIyBiaW5kIHRoZSBsb2FkaW5ncyBhbmQgaXRlbXMKICAgIGZhX2ZvdXJfdCA9IGNiaW5kKGMoMTozLCA4OjExLCA1OjcsIDEyLCAxMywgIiIsICIiKSwgZmFfdGFibGVfbGlzdCwgcmJpbmQoZmFfbG9hZCwgdmFyX3Blcl90WzU6OF0pKQogICAgCiAgICAjIHJlbmFtZSBjb2x1bW5zICYgcm93cwogICAgICBjb2xuYW1lcyhmYV9mb3VyX3QpID0gYygiaXRlbV9udW0iLCAiaXRlbV9kZXNjIiwgImYxIiwgImYyIiwgImYzIiwgImY0IikKICAgICAgcm93bmFtZXMoZmFfZm91cl90KSA9IDE6bnJvdyhmYV9mb3VyX3QpCiAgICAgIAojIGZvcm1hdCBjZWxscwojIGZhX2ZvdXJfdCRmMSA8LSBjZWxsX3NwZWMoZmFfZm91cl90JGYxLCBib2xkID0gaWZlbHNlKGZhX2ZvdXJfdCRmMSA+IDAuNDAsIFQsIEYpKQogICAgICAKIyB1c2Uga2FibGUgdG8gc2hvdyB0aGUgdGFibGUKdGFibGVfZmFfZm91cl90IDwtIAprYWJsZShmYV9mb3VyX3QsIGNhcHRpb24gPSAiRmluYWwgU29sdXRpb246IFN1bW1hcnkgb2YgZXhwbG9yYXRvcnkgdmFyaW1heCByb3RhdGVkIGZhY3RvciBhbmFseXNpcyByZXN1bHRzIGZvciB0aGUgMTMtSXRlbXMgaW4gdGhlIFNBRCIsIAogICAgICBkaWdpdHMgPSAyLCBhbGlnbiA9ICJsbGNjY2MiLCBjb2wubmFtZXMgPSBjKCIiLCAiIiwgIjEiLCAiMiIsICIzIiwgIjQiKSkgJT4lCiAgICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAgICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiICIsICJGYWN0b3IgTG9hZGluZyIgPSA0KSwgYm9sZCA9IFQpICU+JSAKICAgIHBhY2tfcm93cygiRmFjdG9yIDE6IERlcGVuZGVuY2UiLCAxLCAzKSAlPiUgCiAgICBwYWNrX3Jvd3MoIkZhY3RvciAyOiBFbW90aW9uYWwgQXR0YWNobWVudCIsIDQsIDcpICU+JSAKICAgIHBhY2tfcm93cygiRmFjdG9yIDM6IEFjY2Vzc2liaWxpdHkiLCA4LCAxMCkgJT4lIAogICAgcGFja19yb3dzKCJGYWN0b3IgNDogRGlzdHJhY3RpYmlsaXR5IiwgMTEsIDEyKSAlPiUgCiAgICBwYWNrX3Jvd3MoIiIsIDEzLCAxNCkgJT4lIAogICAgZm9vdG5vdGUoZ2VuZXJhbCA9ICJWYWx1ZXMgcmVwcmVzZW50IHJvdGF0ZWQgZmFjdG9yIGxvYWRpbmdzIGZyb20gaXRlbXMgaW4gdGhlIFNtYXJ0cGhvbmUgQXR0YWNobWVudCBhbmQgRGVwZW5kZW5jeSBJbnZlbnRvcnkgKFdhcmQgZXQgYWwuLCAyMDE3KS4KICAgICAgICAgICAgIEZhY3RvciBsb2FkaW5ncyBoYXZlIGJlZW4gc29ydGVkIGJhc2VkIG9uIHN0cm9uZyBsb2FkaW5nICg+IDAuNDApLiBJdGVtICM0IHdhcyBzcGxpdC1sb2FkZWQgYW5kIHJlbW92ZWQgZnJvbSB0aGUgZmluYWwgc29sdXRpb24uIiwgCiAgICAgICAgICAgICBzeW1ib2wgPSBjKCJOID0gMzgzIikpICU+JSAKICAgIGthYmxlX2NsYXNzaWMoKQoKIyBzaG93IHRhYmxlCnRhYmxlX2ZhX2ZvdXJfdAoKI2V4cG9ydCB0YWJsZQojaW5zdGFsbCBQaGFudG9tSlMgdXNpbmc6ICJ3ZWJzaG90OjppbnN0YWxsX3BoYW50b21qcygpIgojIHNhdmVfa2FibGUodGFibGVfZmFfZm91cl90LCAidGFibGVfZmFfZm91cl90LnBkZiIpCmBgYAoKXAoKYGBge3IgY3JlYXRlICYgc2hvdyBmYV90aHJlZV90X2luLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyMgSU5JVElBTCBTT0xVVElPTiAtLSBmb3IgcmVmZXJlbmNlIG5vdCB0aGUgZmluYWwgc29sdXRpb24KCiMgdXNlIGluaXRpYWwgcm90YXRlZCA0LWZhY3RvciBzb2x1dGlvbiBmcm9tIGFib3ZlIC0tICJmYV9mb3VyX3YiCiAgICAKIyBUbyBmaW5kIHRoZSBlaWdlbnZhbHVlcyAmIHZhcmlhbmNlIGFjY291bnRlZCBmb3IsIHlvdSBjYW4gZWl0aGVyIGdyYWIgdGhlIGNhbGN1bGF0ZWQgdmFsdWVzIGZyb20gdGhlIG1vZGVsIAogICAgIyBGb3IgdGhlIGluaXRpYWwgNC1mYWN0b3Igc29sdXRpb24KICAgIHZhcl9ldl9wZXJfaW4gPC0gZGF0YS5mcmFtZShyYmluZChmYV9mb3VyX3YkZS52YWx1ZXNbMTo0XSwgICNlaWdlbiB2YWx1ZXMgCiAgICAgICAgICAgICAgICAgICAgICAgMTAwKmFzLm51bWVyaWMoZmFfZm91cl92JFZhY2NvdW50ZWRbMixdKSAjIHZhcmlhbmNlIGFjY291bnRlZCBmb3IsIGluIHBlcmNlbnRhZ2UKICAgICAgICAgICAgICAgICAgICAgICApKQogICAgY29sbmFtZXModmFyX2V2X3Blcl9pbikgPSBjKCJGYWN0b3IgMSIsICJGYWN0b3IgMiIsICJGYWN0b3IgMyIsICJGYWN0b3IgNCIpCiAgICByb3duYW1lcyh2YXJfZXZfcGVyX2luKSA9IGMoIkVpZ2VuIFZhbHVlcyIsICJWYXJpYW5jZSBFeHBsYWluZWQgKCUpIikKCiMgY3JlYXRlIHRhYmxlIHdpdGggYWxsIGl0ZW1zLCBmYWN0b3IgbG9hZGluZ3MsIGVpZ2VuIHZhbHVlcywgJSBvZiB2YXJpYW5jZSBleHBsYWluZWQsIGFuZCBDcm9uYmFjaCdzIGFscGhhIAoKIyBnZXQgZmFjdG9yIGxvYWRpbmdzCiAgZmFfbG9hZF9pbiA9IGFzLmRhdGEuZnJhbWUoZmFfZm91cl92JGxvYWRpbmdzWzE6MTMsXSkKCiMgbWFrZSBsaXN0IG9mIHRoZSBpdGVtcyAmIG90aGVyIGluZm8KICBmYV90YWJsZV9saXN0X2luID0gZGF0YS5mcmFtZSgiZGV0YWlscyIgPSBjKCJJIHdvdWxkIGhhdmUgdHJvdWJsZSBnZXR0aW5nIHRocm91Z2ggYSBub3JtYWwgZGF5IHdpdGhvdXQgbXkgc21hcnRwaG9uZS4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkl0IHdvdWxkIGJlIHBhaW5mdWwgZm9yIG1lIHRvIGdpdmUgdXAgbXkgc21hcnRwaG9uZSBmb3IgYSBkYXkuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJIGZlZWwgbGlrZSBJIGNvdWxkIG5vdCBsaXZlIHdpdGhvdXQgbXkgc21hcnRwaG9uZS4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklmIEkgZm9yZ290IHRvIGJyaW5nIG15IHNtYXJ0cGhvbmUgd2l0aCBtZSwgSSB3b3VsZCBmZWVsIGFueGlvdXMuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJdCBkcml2ZXMgbWUgY3Jhenkgd2hlbiBteSBzbWFydHBob25lIHJ1bnMgb3V0IG9mIGJhdHRlcnkuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJIGFtIHVwc2V0IGFuZCBhbm5veWVkIHdoZW4gSSBmaW5kIEkgZG8gbm90IGhhdmUgcmVjZXB0aW9uIG9uIG15IHNtYXJ0cGhvbmUuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJIGZlZWwgaW1wYXRpZW50IHdoZW4gdGhlIEludGVybmV0IGNvbm5lY3Rpb24gc3BlZWQgb24gbXkgc21hcnRwaG9uZSBpcyBzbG93LiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSSBmZWVsIGxvbmVseSB3aGVuIG15IHNtYXJ0cGhvbmUgZG9lcyBub3QgcmluZyBvciB2aWJyYXRlIGZvciBzZXZlcmFsIGhvdXJzLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVXNpbmcgbXkgc21hcnRwaG9uZSByZWxpZXZlcyBtZSBvZiBteSBzdHJlc3MuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJIGZlZWwgZXhjaXRlZCB3aGVuIEkgaGF2ZSBhIG5ldyBtZXNzYWdlIG9yIG5vdGlmaWNhdGlvbi4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVzaW5nIG15IHNtYXJ0cGhvbmUgbWFrZXMgbWUgZmVlbCBoYXBweS4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkkgZmluZCBpdCB0b3VnaCB0byBmb2N1cyB3aGVuZXZlciBteSBzbWFydHBob25lIGlzIG5lYXJieS4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkkgYmVjb21lIGxlc3MgYXR0ZW50aXZlIHRvIG15IHN1cnJvdW5kaW5ncyB3aGVuIEnigJltIHVzaW5nIG15IHNtYXJ0cGhvbmUuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWlnZW4gVmFsdWVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVmFyaWFuY2UgRXhwbGFpbmVkICglKSIpKQogIAojIGNyZWF0ZSB0aGUgZmluYWwgdGFibGUKICAjIGJpbmQgdGhlIGxvYWRpbmdzIGFuZCBpdGVtcwogICAgZmFfZm91cl90X2luID0gY2JpbmQoZmFfdGFibGVfbGlzdF9pbiwgcmJpbmQoZmFfbG9hZF9pbiwgdmFyX2V2X3Blcl9pbikpCiAgICAKICAgICMgcmVuYW1lIGNvbHVtbnMgJiByb3dzCiAgICAgIGNvbG5hbWVzKGZhX2ZvdXJfdF9pbikgPSBjKCJJdGVtIiwgIkZhY3RvciAxIiwgIkZhY3RvciAyIiwgIkZhY3RvciAzIiwgIkZhY3RvciA0IikKICAgICAgcm93bmFtZXMoZmFfZm91cl90X2luKSA9IGMoMToxMywgIiIsICIgIikKICAgICAgCiMgdXNlIGthYmxlIHRvIHNob3cgdGhlIHRhYmxlCiAga2FibGUoZmFfZm91cl90X2luLCBjYXB0aW9uID0gIkZpcnN0IFNvbHV0aW9uOiBTdW1tYXJ5IG9mIGV4cGxvcmF0b3J5IHZhcmltYXggcm90YXRlZCBmYWN0b3IgYW5hbHlzaXMgcmVzdWx0cyBmb3IgdGhlIDEzLUl0ZW1zIGluIHRoZSBTQUQuIiwgZGlnaXRzID0gMiwgYWxpZ24gPSAibGNjYyIpICU+JQogICAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JQogICAgcGFja19yb3dzKCIiLCAxNCwgMTUpICU+JSAKICAgIGZvb3Rub3RlKGdlbmVyYWwgPSAiVGhlIGluaXRpYWwgc29sdXRpb24gaXMgc2hvd24sIGluY2x1ZGluZyBpdGVtICM0LCB3aGljaCB3YXMgZHJvcHBlZCBhcyBhIHNwbGl0IHZhcmlhYmxlIGJldHdlZW4gZmFjdG9yIDEgYW5kIGZhY3RvciAzLiIsIHN5bWJvbCA9ICJOID0gMzgzIikgJT4lIAogICAga2FibGVfY2xhc3NpYygpCgpgYGAKCiMjIyMjIFdhcmQgZXQgYWwuICgyMDE3KQoKV2FyZCBldCBhbC4gKDIwMTcpIGZvdW5kIHR3byBmYWN0b3JzOiBzbWFydHBob25lIGRlcGVuZGVuY2UgKGkuZS4gc2l4IGl0ZW1zOyBpdGVtcyAjMS02OyAzMS4wMiUgb2YgdGhlIHZhcmlhbmNlKSBhbmQgZW1vdGlvbmFsIGF0dGFjaG1lbnQgKGkuZS4gZml2ZSBpdGVtczsgaXRlbXMgIzgtMTE7IDIxLjY1JSBvZiB0aGUgdmFyaWFuY2UpLCB3aGljaCBleHBsYWluZWQgNTIuNjclIG9mIHRoZSB0b3RhbCB2YXJpYW5jZS4gVHdvIGl0ZW1zIChpLmUuIGl0ZW0gIzcgYW5kIDEzKSB3ZXJlIGRyb3BwZWQgZnJvbSB0aGVpciBzdWJzZXF1ZW50IGFuYWx5c2VzIHNpbmNlIHRoZXkgZGlkIG5vdCBzdHJvbmdseSBsb2FkIG9udG8gYSBmYWN0b3IgKHNlZSBXZWIgQXBwZW5kaXggVGFibGUgMSBiZWxvdykuCgpcCgo8Y2VudGVyPgoKIVtOb3RlOiB0aGlzIHRhYmxlIGlzIGZyb20gV2FyZCBldCBhbC4gKDIwMTcpIFdlYiBBcHBlbmRpeC4gSXRlbXMgYXJlIGxpc3RlZCBpbiBvcmRlciAoaS5lLiwgMS0xMykuIE9ubHkgc3Ryb25nbHktbG9hZGVkIHZhbHVlcyBhcmUgc2hvd24uXSgvVXNlcnMvYW5hY2VjaWxpYXJ1aXpwYXJkby9SU3R1ZGlvL1NtYXJ0cGhvbmVfc3R1ZHkvU3R1ZHklMjAxLSUyMFNtYXJ0cGhvbmUlMjBSZXBsaWNhdGlvbi9EaXNzZXJ0YXRpb24lMjAoMDQ6MjA6MjApL3dhcmRfRkFfYXBwZW5kaXhfdGFibGUucG5nKQoKPC9jZW50ZXI+CgojIyMjIyBDb21wYXJpbmcgRmluZGluZ3MKClRoZSBwcmVzZW50IHN0dWR5J3MgZmluYWwgZmFjdG9yIHNvbHV0aW9uIHNob3dlZCBzb21lIHNpbWlsYXJpdGllcyB3aXRoIFdhcmQgZXQgYWwuJ3Mgc29sdXRpb246CgotICAgRmFjdG9yIDEgY29udGFpbmVkIGl0ZW1zIFwjIDEsIDIsIDMsIDQsIGFuZCA1Ci0gICBGYWN0b3IgMiBjb250YWluZWQgaXRlbXMgXCMgOCwgOSwgMTAsIGFuZCAxMQoKU29tZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBzb2x1dGlvbnM6CgotIE9ubHkgb25lIGl0ZW0gKGkuZS4sIGl0ZW0gIzQgZHVlIHRvIHNwbGl0LWxvYWRpbmcpIHdhcyBkcm9wcGVkIGluIHRoZSBwcmVzZW50IHN0dWR5IGNvbXBhcmVkIHRvIHRoZSB0d28gaXRlbXMgZHJvcHBlZCBpbiBXYXJkIGV0IGFsLiAoaS5lLiwgaXRlbXMgNyBkdWUgdG8gc3BsaXQtbG9hZGluZyB0byBhbmQgMTMgZHVlIHRvIGJlaW5nIGluIGEgd2Vhaywgc2luZ2xlLWl0ZW0gZmFjdG9yKS4KLSBGYWN0b3IgMyBkaWQgaGF2ZSBtb3JlIHRoYW4gb25lIGl0ZW0gbG9hZCBzdHJvbmdseSAoaXRlbXMgNSwgNiwgNykgYW5kIHdhcyBub3QgZHJvcHBlZC4KLSBGb3VyIGZhY3RvcnMgd2VyZSBpbiB0aGUgZmluYWwgc29sdXRpb24gaW4gdGhlIHByZXNlbnQgc3R1ZHkuIAoKT3ZlcmFsbCwgdGhlIGFuYWx5c2VzIHdlcmUgdmVyeSBzaW1pbGFyLiBXZSBjb21wYXJlZCB0aGUgdG90YWwgdmFyaWFuY2VzIGV4cGxhaW5lZCBhbmQgZm91bmQgdGhhdCBib3RoIHRoZSBpbml0aWFsIChgciByb3VuZChzdW0odmFyX2V2X3Blcl9pblsyLF0pLCAyKWAlKSBhbmQgZmluYWwgKGByIHJvdW5kKHN1bSh2YXJfcGVyX3YpLCAyKWAlKSBzb2x1dGlvbiBpbiB0aGUgcHJlc2VudCBzdHVkeSBleHBsYWluZWQgbW9yZSB0b3RhbCB2YXJpYW5jZSB0aGFuIHRoZSBXYXJkIGV0IGFsLiAoMjAxNykgc29sdXRpb24gKDUyLjY3JSkuIENvbXBhcmluZyB0aGUgcmVsaWFiaWxpdHkgdGVzdHMgc2hvd2VkIHRoYXQgV2FyZCBldCBhbC4ncyBzdWJzY2FsZXMgKCRcYWxwaGFfe0ZhY3RvcjF9JCA9IDAuODk7ICRcYWxwaGFfe0ZhY3RvcjJ9JCA9IDAuNzkpIGhhZCBzbGlnaHRseSBsYXJnZXIgdmFsdWVzIHRoYW4gdGhlIHJlc2VudCBzdHVkeSAoJFxhbHBoYV97RmFjdG9yMX0kID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbMV0sIDIpYDsgJFxhbHBoYV97RmFjdG9yMn0kID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbMl0sIDIpYDsgJFxhbHBoYV97RmFjdG9yM30kID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbM10sIDIpYDsgJFxhbHBoYV97RmFjdG9yNH0kID0gYHIgcm91bmQoZmFfcmVsX2FscGhhcyRyYXdfYWxwaGFbNF0sIDIpYCkuCgoKIyMjIENvcnJlbGF0aW9uczogU0FEIFN1YnNjYWxlcyB2cy4gT1NwYW4gCmBgYHtyIG1haW5fY29ycnNfb3ZlcmFsbH0KIyBzZXQgdXAgdGhlIGRhdGEgJiBydW4gY29ycmVsYXRpb24KU0FEX2NvcnIgPC0gCiAgYWxsX2RhdGEgJT4lIAogIHNlbGVjdChvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgZ25nX2Vycl9vbWksIGduZ19ydF9hdiAsIFNBRF9zY29yZSwgU0FEX2RlcF9zY29yZSwgU0FEX2VhX3Njb3JlLCBTQURfYWNjZXNzX3Njb3JlLCBTQURfZGlzdF9zY29yZSwgYWdlKSAlPiUgCiAgYXMubWF0cml4KCkgJT4lIAogIHJjb3JyKHR5cGUgPSAicGVhcnNvbiIpCgojIGNyZWF0ZSBuZXcgU0FEX2NvcnIgdG8gc2hvd24gb25seSBsb3dlciB0cmlhbmdsZS4uLiAKU0FEX2NvcnIyIDwtIFNBRF9jb3JyCiMgcm91bmQgdG8gNCBkZWNpbWFscy4uLiAKU0FEX2NvcnIyJHIgPC0gcm91bmQoU0FEX2NvcnIyJHIsIDQpClNBRF9jb3JyMiRQIDwtIHJvdW5kKFNBRF9jb3JyMiRQLCA0KQpTQURfY29ycjIkbiA8LSByb3VuZChTQURfY29ycjIkbiwgNCkKIyByZW1vdmUgdXBwZXIgdHJpYW5nbGUgZm9ybSByLCBwLCBhbmQgbgpTQURfY29ycjIkclt1cHBlci50cmkoU0FEX2NvcnIyJHIpXSA8LSAiLSIKU0FEX2NvcnIyJFBbdXBwZXIudHJpKFNBRF9jb3JyMiRQKV0gPC0gIi0iClNBRF9jb3JyMiRuW3VwcGVyLnRyaShTQURfY29ycjIkbildIDwtICItIgoKIyBzaG93IGNvcnIgdGFibGUgd2l0aCBmbGF0dGVuQ29ycgoKa2FibGUoZmxhdHRlbkNvcnJNYXRyaXgoU0FEX2NvcnIkciwgU0FEX2NvcnIkUCksIGNhcHRpb24gPSAiQ29ycmVsYXRpb25zIGJldHdlZW4gU0FEIFNjb3JlIGFuZCBBZ2Ugd2l0aCBPU3BhbiBQZXJmb3JtYW5jZSIpICU+JQogIGZvb3Rub3RlKGdlbmVyYWwgPSAiU0FEIG92ZXJhbGwgYW5kIFNtYXJ0cGhvbmUgRGVwZW5kZW5jeSwgRW1vdGlvbmFsIEF0dGFjaG1lbnQsIEFjY2Vzc2liaWxpdHksIGFuZCBEaXN0cmFjdGliaWxpdHkgc2hvd24uICIpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygiaG92ZXIiLCAic3RyaXBlZCIpLCBmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlX2NsYXNzaWMoKQoKIyBwcmludCB0YWJsZXMgdXNpbmcga2FibGUKa2FibGUoYXMuZGF0YS5mcmFtZShmb3JtYXQoU0FEX2NvcnIyJHIsIHNjaWVudGlmaWMgPSBGQUxTRSkpLCBjYXB0aW9uID0gIkNvcnJlbGF0aW9ucyBiZXR3ZWVuIFNBRCBTY29yZSBhbmQgQWdlIHdpdGggT1NwYW4gUGVyZm9ybWFuY2U6IHIgdmFsdWVzIikgJT4lCiAgZm9vdG5vdGUoZ2VuZXJhbCA9ICJTQUQgb3ZlcmFsbCBhbmQgU21hcnRwaG9uZSBEZXBlbmRlbmN5LCBFbW90aW9uYWwgQXR0YWNobWVudCwgQWNjZXNzaWJpbGl0eSwgYW5kIERpc3RyYWN0aWJpbGl0eSBzaG93bi4gIikgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJob3ZlciIsICJzdHJpcGVkIiksIGZ1bGxfd2lkdGggPSBGKSAlPiUgCiAga2FibGVfY2xhc3NpYygpCiAgCgprYWJsZShhcy5kYXRhLmZyYW1lKGZvcm1hdChTQURfY29ycjIkUCwgc2NpZW50aWZpYyA9IEZBTFNFKSksIGNhcHRpb24gPSAiQ29ycmVsYXRpb25zIGJldHdlZW4gU0FEIFNjb3JlIGFuZCBBZ2Ugd2l0aCBPU3BhbiBQZXJmb3JtYW5jZTogcC12YWx1ZXMiKSAlPiUKICBmb290bm90ZShnZW5lcmFsID0gIlNBRCBvdmVyYWxsIGFuZCBTbWFydHBob25lIERlcGVuZGVuY3ksIEVtb3Rpb25hbCBBdHRhY2htZW50LCBBY2Nlc3NpYmlsaXR5LCBhbmQgRGlzdHJhY3RpYmlsaXR5IHNob3duLiAiKSAlPiUgCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoImhvdmVyIiwgInN0cmlwZWQiKSwgZnVsbF93aWR0aCA9IEYpICU+JSAKICBrYWJsZV9jbGFzc2ljKCkKCmthYmxlKGFzLmRhdGEuZnJhbWUoZm9ybWF0KFNBRF9jb3JyMiRuLCBzY2llbnRpZmljID0gRkFMU0UpKSwgY2FwdGlvbiA9ICJDb3JyZWxhdGlvbnMgYmV0d2VlbiBTQUQgU2NvcmUgYW5kIEFnZSB3aXRoIE9TcGFuIFBlcmZvcm1hbmNlOiBuIHZhbHVlcyIpICU+JQogIGZvb3Rub3RlKGdlbmVyYWwgPSAiU0FEIG92ZXJhbGwgYW5kIFNtYXJ0cGhvbmUgRGVwZW5kZW5jeSwgRW1vdGlvbmFsIEF0dGFjaG1lbnQsIEFjY2Vzc2liaWxpdHksIGFuZCBEaXN0cmFjdGliaWxpdHkgc2hvd24uICIpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygiaG92ZXIiLCAic3RyaXBlZCIpLCBmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlX2NsYXNzaWMoKQoKIyBkb2VzIG5vdCBmaXQgbmljZWx5IG9uIHBhZ2UsIHBvc3NpYmx5IGNoYW5nZSBsYXRlci4uLgpjb3JycGxvdChTQURfY29yciRyLCBtZXRob2QgPSAiY2lyY2xlIiwgY29sID0gKGNvbG9yUmFtcFBhbGV0dGUoYygicHVycGxlIiwgImdyZXkiLCAiYmx1ZSIpKSg1MCkpLAogICAgICAgICB0eXBlID0gInVwcGVyIiwKICAgICAgICAgIyBhZGRDb2VmLmNvbCA9ICJibGFjayIsICMgQWRkIGNvZWZmaWNpZW50IG9mIGNvcnJlbGF0aW9uCiAgICAgICAgIHRsLmNvbCA9ICJkYXJrYmx1ZSIsIHRsLnNydCA9IDkwLCB0bC5jZXggPSAuOCwgI1RleHQgbGFiZWwgY29sb3IgYW5kIHJvdGF0aW9uCiAgICAgICAgICMgQ29tYmluZSB3aXRoIHNpZ25pZmljYW5jZSBsZXZlbAogICAgICAgICBwLm1hdCA9IFNBRF9jb3JyJFAsIHNpZy5sZXZlbCA9IDAuMDUsCiAgICAgICAgIGFkZGdyaWQuY29sID0gIndoaXRlIiwKICAgICAgICAgIyBpbnNpZyA9ICJibGFuayIsCiAgICAgICAgIGluc2lnID0gInBjaCIsIHBjaCA9IDEwLCBwY2guY29sID0gInJlZCIsIHBjaC5jZXggPSAuMSwgIyBhZGQgdGhpcyBpbnN0ZWFkIG9mIGluc2lnIGFib3ZlIHRvIGRlbm90IGluc2lnIHAgdmFsdWVzIHdpdGggcmVkIGRvdAogICAgICAgICAjIGhpZGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgb24gdGhlIHByaW5jaXBhbCBkaWFnb25hbAogICAgICAgICBkaWFnID0gRkFMU0UsCiAgICAgICAgIHdpbi5hc3AgPSAxCiAgICAgICAgICkKYGBgCiMjIyBFeHBsb3JhdG9yeSBNb2RlcmF0aW9uIEFuYWx5c2VzCgpQb3RlbnRpYWwgbW9kZXJhdG9ycyBvZiBPU3BhbiBwZXJmb3JtYW5jZSB3ZXJlIGV4cGxvcmVkLiBUaGVzZSBpbmNsdWRlZCBib3RoICgxKSBjb250aW51b3VzIGFuZCAoMikgY2F0ZWdvcmljYWwgbW9kZXJhdG9ycy4gKk5vdGU6IFRoZXNlIGFuYWx5c2lzIHdlcmUgY29tcGxldGVkIHJlZ2FyZGxlc3Mgb2YgdGhlIHJlc3VsdHMgZm9yIHRoZSBsb2NhdGlvbiBhbmQgcG93ZXIgaHlwb3RoZXNlcy4qCgoqKjEuIENvbnRpbnVvdXMgTW9kZXJhdG9ycyoqCgpUaGVzZSB2YXJpYWJsZXMgd2VyZSBleGFtaW5lZCB1c2luZyBhICoqZ2VuZXJhbCBsaW5lYXIgbW9kZWwgZm9yIGVhY2ggcG90ZW50aWFsIG1vZGVyYXRvcioqOiBEViA9IE9TcGFuIEFic29sdXRlIFNjb3JlLCBJVjogU21hcnRwaG9uZSBMb2NhdGlvbiAoZGVzaywgcG9ja2V0L2JhZywgb3V0c2lkZSksIE06IHNlZSBsaXN0IGJlbG93LiBTaW1wbGUgc2xvcGVzIGZvciBlYWNoIG1vZGVyYXRvciB4IElWIGNvbXBhcmlzb24gd2VyZSBleHBsb3JlZC4KCi0gICBTQUQgU2NvcmU6IFNtYXJ0cGhvbmUgRGVwZW5kZW5jZSwgRW1vdGlvbmFsIEF0dGFjaG1lbnQsIERpc3RyYWN0aWJpbHR5Ci0gICBTVVEgU2NvcmU6IFNtYXJ0cGhvbmUgdXNlIHdpdGggYWJzZW5jZSBvZiBvdGhlciBzdGltdWxhdGlvbiwgU21hcnRwaG9uZSB1c2UgZHVyaW5nIG90aGVyIGFjdGlvbnMKLSAgIERlbW9ncmFwaGljIEluZm86IEFnZQoKRWFjaCBtb2RlcmF0aW9uIGFuYWx5c2lzIHdhcyBjb21wbGV0ZWQgdXNpbmcgdGhlIE1lTW9Cb290UiBwYWNrYWdlJ3MgbW9kZXJhdGlvbiBtb2RlbCAxIHVzaW5nIGEgY2F0ZWdvcmljYWwgSVYgKGZyb20gSGF5ZXMsIDIwMTc7IHNlZSBmaWd1cmVzIGJlbG93KS4gVGhpcyBwYWNrYWdlIHByb3ZpZGVkOiBhc3N1bXB0aW9uIHRlc3RzLCBvdXRsaWVycywgc2ltcGxlIHNsb3BlcywgYW5kIGEgZ3JhcGggb2YgdGhlIHNpbXBsZSBzbG9wZXMuIFNpbmNlIHRoZSBJViB3YXMgY2F0ZWdvcmljYWwgKGkuZS4sIHNtYXJ0cGhvbmUgbG9jYXRpb246IGRlc2ssIHBvY2tldC9iYWcsIG9yIG91dHNpZGUpLCB0aGUgdmFyaWFibGUgaXMgY29kZWQgYXMgYSBmYWN0b3Igc28gdGhhdCBpdCBpcyBub3QgbWlzaW50ZXJwcmV0ZWQgYXMgYSBjb250aW51b3VzIHZhcmlhYmxlLiBUaGlzIG1lYW5zIHRoYXQgdGhlIElWIGlzICpkdW1teSBjb2RlZCogYW5kIHRoZSBhbmFseXNpcyB1c2VzIHRoZSBmaXJzdCBvZiB0aGUgZmFjdG9ycyBhcyB0aGUgIipjb21wYXJpc29uIGdyb3VwKiIuIEluIG9yZGVyIHRvIGFzc2VzcyBhbGwgcG9zc2libGUgY29tcGFyaW9ucyBiZXR3ZWVuIHRoZSB0aHJlZSBsb2NhdGlvbiBncm91cHMsIHRoZSBmYWN0b3IgaXMgcmUtb3JkZXJlZCBhbmQgcnVuIGFnYWluLiBBZGRpdGlvbmFsbHksIHRvIGFsbG93IGZvciBiZXR0ZXIgaW50ZXJwcmV0YXRpb24sIHRoZSBjb250aW51b3VzIG1vZGVyYXRvciB3YXMgKm1lYW4tY2VudGVyZWQqLiBUaGUgKmR1bW15IGNvZGluZyogYW5kICptZWFuLWNlbnRlcmVkIHNjb3JpbmcqIG9mIHRoZSBjb250aW51b3VzIG1vZGVyYXRvciBpcyBkb25lIHdpdGhpbiB0aGUgTWVNb0Jvb3RSIHBhY2thZ2UuCgpcCgo8Y2VudGVyPgoKIVtDb25jZXB0dWFsIGRpYWdyYW0gb2YgYSBzaW1wbGUgbW9kZXJhdGlvbiBtb2RlbCBmcm9tIEhheWVzICgyMDE3KV0oL1VzZXJzL2FuYWNlY2lsaWFydWl6cGFyZG8vUlN0dWRpby9TbWFydHBob25lX3N0dWR5L1N0dWR5JTIwMS0lMjBTbWFydHBob25lJTIwUmVwbGljYXRpb24vRGlzc2VydGF0aW9uJTIwKDA0OjIwOjIwKS9oYXllc19tb2RlcmF0aW9uX21vZGVsMS5wbmcpCgo8L2NlbnRlcj4KClwKXApcCgo8Y2VudGVyPgoKIVtTdGF0aXN0aWNhbCBkaWFncmFtIG9mIGEgc2ltcGxlIG1vZGVyYXRpb24gbW9kZWwgd2l0aCBtdWx0aWNhdGVnb3JpY2FsIGluZGVwZW5kZW50IHZhcmlhYmxlIHdpdGggZyBjYXRlZ29yaWVzIGZyb20gSGF5ZXMgKDIwMTcpXSgvVXNlcnMvYW5hY2VjaWxpYXJ1aXpwYXJkby9SU3R1ZGlvL1NtYXJ0cGhvbmVfc3R1ZHkvU3R1ZHklMjAxLSUyMFNtYXJ0cGhvbmUlMjBSZXBsaWNhdGlvbi9EaXNzZXJ0YXRpb24lMjAoMDQ6MjA6MjApL2hheWVzX21vZGVyYXRpb25fbW9kZWwxX3N0YXRzX2NhdFgucG5nKQoKPC9jZW50ZXI+CgoqKjIuIENhdGVnb3JpY2FsIE1vZGVyYXRvcnMqKgoKVGhlc2UgdmFyaWFibGVzIHdlcmUgZXhhbWluZWQgdXNpbmcgYSAqKnR3by13YXkgQU5PVkEgZm9yIGVhY2ggcG90ZW50aWFsIG1vZGVyYXRvcioqOiBEViA9IE9TcGFuIEFic29sdXRlIFNjb3JlLCAkSVZfezF9JDogU21hcnRwaG9uZSBMb2NhdGlvbiAoZGVzaywgcG9ja2V0L2JhZywgb3V0c2lkZSksICRJVl97TX0kOiBzZWUgbGlzdCBiZWxvdy4gU2ltcGxlIG1haW4gZWZmZWN0cyBmb3IgZWFjaCBtb2RlcmF0b3IgeCBJViBjb21wYXJpc29uIHdlcmUgZXhwbG9yZWQuCgotICAgU1VRIFNjb3JlOiBUZXh0cyBwZXIgRGF5LCBTb2NpYWwgTWVkaWEgTWVzc2FnZXMgcGVyIERheSwgU29jaWFsIE1lZGlhIFBvc3RzIHBlciBEYXksIFN1YmplY3RpdmUgU21hcnRwaG9uZSBWYWx1ZSwgTm90aWZpY2F0aW9uIFR5cGUsIFBoYW50b20gVmlicmF0aW9ucwotICAgRGVtb2dyYXBoaWMgSW5mbzogR2VuZGVyLCBQcm9ncmFtLCBBY2FkZW1pYyBZZWFyLCBGaXJzdCBMYW5ndWFnZQoKIyMjIyBDb250aW51b3VzIE1vZGVyYXRvcnMKClRvIGV4YW1pbmUgdGhlIHBvdGVudGlhbCBtb2RlcmF0aW9uIG9mIHNtYXJ0cGhvbmUgcmVsaWFuY2UgKGkuZS4gU21hcnRwaG9uZSBEZXBlbmRlbmNlLCBFbW90aW9uYWwgQXR0YWNobWVudCwgYW5kIERpc3RyYWN0aWJpbGl0eSkgYW5kIGFnZSBvbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGV4cGVyaW1lbnRhbCBtYW5pcHVsYXRpb24gYW5kIHRhc2sgcGVyZm9ybWFuY2Ugb24gdGhlIE9TcGFuLCBhIGdlbmVyYWxpemVkIGxpbmVhciBtb2RlbCB3YXMgdXNlZC4gRWFjaCBwb3RlbnRpYWwgbW9kZXJhdG9yIHdhcyBldmFsdWF0ZWQgc2VwYXJhdGVseSwgYWxvbmcgd2l0aCB0aGUgcmVsZXZhbnQgYXNzdW1wdGlvbiB0ZXN0cyAoZS5nLiwgbm9ybWFsaXR5KS4gVGhlIGRhdGEgd2FzIHNjcmVlbmVkIGZvciBvdXRsaWVycyAoaS5lLiwgY29va3MgZGlzdGFuY2UgYW5kIGxldmVyYWdlKSBhbmQgcGFydGljaXBhbnRzIHdlcmUgcmVtb3ZlZCBmcm9tIHRoZSBhbmFseXNpcyB0aGUgY3JpdGVyaWEgZm9yIGJvdGggY29va3MgYW5kIGxldmVyYWdlIHdhcyBtZXQuCgojIyMjIyBTZXQgdXAgdGhlIERhdGEKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpGaXJzdCwgaW4gb3JkZXIgdG8gcHJvdmlkZSBhbGwgcG9zc2libGUgY29tcGFyaXNvbnMgaW4gdGhlIGFuYWx5c2VzLCAyIG5ldyAqbG9jYXRpb24qIHZhcmlhYmxlcyB3ZXJlIGNyZWF0ZWQgaW4gdGhlICptb2RfYW5hbHlzaXMqIGRhdGEgZnJhbWUuIEVhY2ggd2FzIGEgZmFjdG9yZWQgdmVyc2lvbiBvZiB0aGUgb3JpZ2luYWwgc21hcnRwaG9uZSBsb2NhdGlvbiB2YXJpYWJsZSwgd2hlcmUgdGhlIG9yZGVyIG9mIHRoZSBmYWN0b3JzIHdlcmUgZWl0aGVyICgxKSAqZGVzayBcPiBwb2NrZXQvYmFnIFw+IG91dHNpZGUqIChpLmUuLCAiKmxvY2F0aW9uX2Rlc2sqIikgb3IgKDIpICpvdXRzaWRlIFw+IHBvY2tldC9iYWcgXD4gZGVzayogKGkuZS4sICIqbG9jYXRpb25fb3V0KiIpLiAqKGNsaWNrIHRvIHNlZSBjb2RlKSoKCjwvc3VtbWFyeT4KCmBgYHtyIG1vZGlmeV9tb2RfYW5hbHlzaXNfYWRkX2xvY192YXJzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGNoYW5nZSBsb2NhdGlvbiB2YXIgYXMgZmFjdG9yIHdpdGggZGlmZmVyZW50IG9yZGVycyAtLSAyIG5ldyB2YXJzCm1vZF9hbmFseXNpcyA8LSAKICBtb2RfYW5hbHlzaXMgJT4lIAogICMgImxvY2F0aW9uX2Rlc2siOiBkZXNrIHZzLiBwb2NrZXQvYmFnICYgIGRlc2sgdnMuIG91dHNpZGUKICBtdXRhdGUobG9jYXRpb25fZGVzayA9IGZhY3Rvcihsb2NhdGlvbiwgbGV2ZWxzID0gYygxLCAyLCAzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiZGVzayIsICJwb2NrZXRiYWciLCAib3V0c2lkZSIpKSkgJT4lIAogICMgImxvY2F0aW9uX291dCI6IG91dHNpZGUgdnMuIGRlc2sgJiAgb3V0c2lkZSB2cy4gcG9ja2V0L2JhZwogIG11dGF0ZShsb2NhdGlvbl9vdXQgPSBmYWN0b3IobG9jYXRpb24sIGxldmVscyA9IGMoMywgMiwgMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygib3V0c2lkZSIsICJwb2NrZXRiYWciLCAiZGVzayIpKSkKYGBgCgo8L2RldGFpbHM+CgojIyMjIyBSdW4gQW5hbHlzZXMKCjxkZXRhaWxzPgoKPHN1bW1hcnk+CgpOZXh0LCBlYWNoIG1vZGVyYXRpb24gYW5hbHlzaXMgd2FzIHJ1biB0byB1c2UgdGhlIG91dHB1dHMgKihjbGljayB0byBzZWUgY29kZSkqLgoKPC9zdW1tYXJ5PgoKUnVuIHRoZSBtb2RlcmF0aW9uIGFuYWx5c2VzIGZvciBTQUQgdmFyaWFibGUocyk6IFNtYXJ0cGhvbmUgRGVwZW5kZW5jeSwgRW1vdGlvbmFsIEF0dGFjaG1lbnQsIGFuZCBEaXN0cmFjdGliaWxpdHkuCgpgYGB7ciBydW5fbW9kX1NBRF9kZXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdD0naGlkZSd9CiMtLSBSdW4gbW9kZXJhdGlvbiBhbmFseXNpcyB1c2luZyBtb2RlcmF0aW9uMSgpIGluIHRoZSBNZU1vQm9vdFIgcGFja2FnZQogICMgbm90ZTogbW9kZXJhdG9yIChtKSBhbmQgSVYgKHgpIGFyZSBzd2l0Y2hlZCBzaW5jZSBtb2RlcmF0b3IgaXMgY29udGludW91cyAmIElWIGlzIGNhdGVnb3JpY2FsIGluIHByZXNlbnQgc3R1ZHkKICAgICMgd2FzIGNoZWNrZWQgdnMuIG1hbnVhbCBsbSgpIHZlcnNpb24gJiBjb21wdXRlcyBleGFjdCBzYW1lIHZhbHVlcwogICMgbm90ZTogYW5hbHlzaXMgbWVhbi1jZW50ZXJzIHRoZSBjb250aW51b3VzIHZhciBhdXRvbWF0aWNhbGx5CiAgIyBub3RlOiB0aGlzIGFuYWx5c2lzIHdpbGwgY29tcGFyZTogZGVzayB2cy4gcG9ja2V0L2JhZyYgIGRlc2sgdnMuIG91dHNpZGUgaW5pdGlhbGx5IAogICAgIyB0aGVuLCB0aGUgZGF0YSBpcyByZS1vcmdhbml6ZWQgdG8gY29tcGFyZTogcG9ja2V0L2JhZyB2cy4gb3V0c2lkZSAKICAgICMgdGhpcyB3YXMgc2F2ZWQgaW50byAyIHNlcGFyYXRlIGFuYWx5c2VzLCBidXQgbW9zdCBvdXRwdXQgaXMgY29tbW9uIGIvdyB0aGVtCgojIyBTTUFSVFBIT05FIERFUEVOREVOQ0UgIyMKIyBydW4gJiBzYXZlIGFuYWx5c2lzIHRvIHZpZXcgY29tcG9uZW50cyBzZXBhcmF0ZWx5IAojIGZvciBkZXNrIDFzdAptb2RfU0FEX2RlcDEgPC0gIAogIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjIERWCiAgICAgICAgICAgICAgeCA9ICJTQURfZGVwX3Njb3JlIiwgIyBjb250aW51b3VzIHZhcgogICAgICAgICAgICAgIG0gPSAibG9jYXRpb25fZGVzayIsICMgY2F0ZWdvcmljYWwgdmFyIC0tIHdpbGwgc2hvdyBzaW1wbGUgc2xvcGVzCiAgICAgICAgICAgICAgY3ZzID0gTlVMTCwgIyBjb3ZhcmlhdGVzIChpZiBhbnkpCiAgICAgICAgICAgICAgZGYgPSBtb2RfYW5hbHlzaXMsICMgZGF0YSBmcmFtZSBvZiBjb2x1bW5zCiAgICAgICAgICAgICAgd2l0aF9vdXQgPSBGKSAjIHJlbW92ZSBvdXRsaWVycwoKIyBDYW4gdmlldyB0aGUgZnVsbCBkYXRhIHNldCwgaW5jbHVkaW5nIHRoZSBpZGVudGlmaWVkIG91dGxpZXJzIChsYXN0IGNvbHVtbnMpCiMgVmlldyhtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSkKCiMgZm9yIG91dHNpZGUgMXN0Cm1vZF9TQURfZGVwMiA8LSAgCiAgbW9kZXJhdGlvbjEoeSA9ICJvc3Bhbl9hYnNvbHV0ZV9zY29yZSIsICMgRFYKICAgICAgICAgICAgICB4ID0gIlNBRF9kZXBfc2NvcmUiLCAjIGNvbnRpbnVvdXMgdmFyCiAgICAgICAgICAgICAgbSA9ICJsb2NhdGlvbl9vdXQiLCAjY2F0ZWdvcmljYWwgdmFyIC0tIHdpbGwgc2hvdyBzaW1wbGUgc2xvcGVzCiAgICAgICAgICAgICAgY3ZzID0gTlVMTCwgIyBjb3ZhcmlhdGVzIChpZiBhbnkpCiAgICAgICAgICAgICAgZGYgPSBtb2RfYW5hbHlzaXMsICMgZGF0YSBmcmFtZSBvZiBjb2x1bW5zCiAgICAgICAgICAgICAgd2l0aF9vdXQgPSBGKSAjIHJlbW92ZSBvdXRsaWVycwoKIyBDYW4gdmlldyB0aGUgZnVsbCBkYXRhIHNldCwgaW5jbHVkaW5nIHRoZSBpZGVudGlmaWVkIG91dGxpZXJzIChsYXN0IGNvbHVtbnMpCiMgVmlldyhtb2RfU0FEX2RlcDIkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSkKCiMjIEVNT1RJT05BTCBBVFRBQ0hNRU5UICMjCiMgcnVuICYgc2F2ZSBhbmFseXNpcyB0byB2aWV3IGNvbXBvbmVudHMgc2VwYXJhdGVseSAKIyBmb3IgZGVzayAxc3QKbW9kX1NBRF9lYTEgPC0gIAogIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjIERWCiAgICAgICAgICAgICAgeCA9ICJTQURfZWFfc2NvcmUiLCAjIGNvbnRpbnVvdXMgdmFyCiAgICAgICAgICAgICAgbSA9ICJsb2NhdGlvbl9kZXNrIiwgIyBjYXRlZ29yaWNhbCB2YXIgLS0gd2lsbCBzaG93IHNpbXBsZSBzbG9wZXMKICAgICAgICAgICAgICBjdnMgPSBOVUxMLCAjIGNvdmFyaWF0ZXMgKGlmIGFueSkKICAgICAgICAgICAgICBkZiA9IG1vZF9hbmFseXNpcywgIyBkYXRhIGZyYW1lIG9mIGNvbHVtbnMKICAgICAgICAgICAgICB3aXRoX291dCA9IEYpICMgcmVtb3ZlIG91dGxpZXJzCgojIENhbiB2aWV3IHRoZSBmdWxsIGRhdGEgc2V0LCBpbmNsdWRpbmcgdGhlIGlkZW50aWZpZWQgb3V0bGllcnMgKGxhc3QgY29sdW1ucykKIyBWaWV3KG1vZF9TQURfZWExJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpCgojIGZvciBvdXRzaWRlIDFzdAptb2RfU0FEX2VhMiA8LSAgCiAgbW9kZXJhdGlvbjEoeSA9ICJvc3Bhbl9hYnNvbHV0ZV9zY29yZSIsICMgRFYKICAgICAgICAgICAgICB4ID0gIlNBRF9lYV9zY29yZSIsICMgY29udGludW91cyB2YXIKICAgICAgICAgICAgICBtID0gImxvY2F0aW9uX291dCIsICNjYXRlZ29yaWNhbCB2YXIgLS0gd2lsbCBzaG93IHNpbXBsZSBzbG9wZXMKICAgICAgICAgICAgICBjdnMgPSBOVUxMLCAjIGNvdmFyaWF0ZXMgKGlmIGFueSkKICAgICAgICAgICAgICBkZiA9IG1vZF9hbmFseXNpcywgIyBkYXRhIGZyYW1lIG9mIGNvbHVtbnMKICAgICAgICAgICAgICB3aXRoX291dCA9IEYpICMgcmVtb3ZlIG91dGxpZXJzCgojIENhbiB2aWV3IHRoZSBmdWxsIGRhdGEgc2V0LCBpbmNsdWRpbmcgdGhlIGlkZW50aWZpZWQgb3V0bGllcnMgKGxhc3QgY29sdW1ucykKIyBWaWV3KG1vZF9TQURfZWEyJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpCgojIyBBQ0NFU1NJQklMSVRZICMjCiMgcnVuICYgc2F2ZSBhbmFseXNpcyB0byB2aWV3IGNvbXBvbmVudHMgc2VwYXJhdGVseSAKIyBmb3IgZGVzayAxc3QKbW9kX1NBRF9hY2Nlc3MxIDwtICAKICBtb2RlcmF0aW9uMSh5ID0gIm9zcGFuX2Fic29sdXRlX3Njb3JlIiwgIyBEVgogICAgICAgICAgICAgIHggPSAiU0FEX2FjY2Vzc19zY29yZSIsICMgY29udGludW91cyB2YXIKICAgICAgICAgICAgICBtID0gImxvY2F0aW9uX2Rlc2siLCAjIGNhdGVnb3JpY2FsIHZhciAtLSB3aWxsIHNob3cgc2ltcGxlIHNsb3BlcwogICAgICAgICAgICAgIGN2cyA9IE5VTEwsICMgY292YXJpYXRlcyAoaWYgYW55KQogICAgICAgICAgICAgIGRmID0gbW9kX2FuYWx5c2lzLCAjIGRhdGEgZnJhbWUgb2YgY29sdW1ucwogICAgICAgICAgICAgIHdpdGhfb3V0ID0gRikgIyByZW1vdmUgb3V0bGllcnMKCiMgQ2FuIHZpZXcgdGhlIGZ1bGwgZGF0YSBzZXQsIGluY2x1ZGluZyB0aGUgaWRlbnRpZmllZCBvdXRsaWVycyAobGFzdCBjb2x1bW5zKQojIFZpZXcobW9kX1NBRF9hY2Nlc3MxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpCgojIGZvciBvdXRzaWRlIDFzdAptb2RfU0FEX2FjY2VzczIgPC0gIAogIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjIERWCiAgICAgICAgICAgICAgeCA9ICJTQURfYWNjZXNzX3Njb3JlIiwgIyBjb250aW51b3VzIHZhcgogICAgICAgICAgICAgIG0gPSAibG9jYXRpb25fb3V0IiwgI2NhdGVnb3JpY2FsIHZhciAtLSB3aWxsIHNob3cgc2ltcGxlIHNsb3BlcwogICAgICAgICAgICAgIGN2cyA9IE5VTEwsICMgY292YXJpYXRlcyAoaWYgYW55KQogICAgICAgICAgICAgIGRmID0gbW9kX2FuYWx5c2lzLCAjIGRhdGEgZnJhbWUgb2YgY29sdW1ucwogICAgICAgICAgICAgIHdpdGhfb3V0ID0gRikgIyByZW1vdmUgb3V0bGllcnMKCiMgQ2FuIHZpZXcgdGhlIGZ1bGwgZGF0YSBzZXQsIGluY2x1ZGluZyB0aGUgaWRlbnRpZmllZCBvdXRsaWVycyAobGFzdCBjb2x1bW5zKQojIFZpZXcobW9kX1NBRF9hY2Nlc3MyJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpCgojIyBTTUFSVFBIT05FIERJU1RSQUNUSUJJTElUWSAjIwojIHJ1biAmIHNhdmUgYW5hbHlzaXMgdG8gdmlldyBjb21wb25lbnRzIHNlcGFyYXRlbHkgCiMgZm9yIGRlc2sgMXN0Cm1vZF9TQURfZGlzdDEgPC0gIAogIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjIERWCiAgICAgICAgICAgICAgeCA9ICJTQURfZGlzdF9zY29yZSIsICMgY29udGludW91cyB2YXIKICAgICAgICAgICAgICBtID0gImxvY2F0aW9uX2Rlc2siLCAjIGNhdGVnb3JpY2FsIHZhciAtLSB3aWxsIHNob3cgc2ltcGxlIHNsb3BlcwogICAgICAgICAgICAgIGN2cyA9IE5VTEwsICMgY292YXJpYXRlcyAoaWYgYW55KQogICAgICAgICAgICAgIGRmID0gbW9kX2FuYWx5c2lzLCAjIGRhdGEgZnJhbWUgb2YgY29sdW1ucwogICAgICAgICAgICAgIHdpdGhfb3V0ID0gRikgIyByZW1vdmUgb3V0bGllcnMKCiMgQ2FuIHZpZXcgdGhlIGZ1bGwgZGF0YSBzZXQsIGluY2x1ZGluZyB0aGUgaWRlbnRpZmllZCBvdXRsaWVycyAobGFzdCBjb2x1bW5zKQojIFZpZXcobW9kX1NBRF9kaXN0MSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhKQoKIyBmb3Igb3V0c2lkZSAxc3QKbW9kX1NBRF9kaXN0MiA8LSAgCiAgbW9kZXJhdGlvbjEoeSA9ICJvc3Bhbl9hYnNvbHV0ZV9zY29yZSIsICMgRFYKICAgICAgICAgICAgICB4ID0gIlNBRF9kaXN0X3Njb3JlIiwgIyBjb250aW51b3VzIHZhcgogICAgICAgICAgICAgIG0gPSAibG9jYXRpb25fb3V0IiwgI2NhdGVnb3JpY2FsIHZhciAtLSB3aWxsIHNob3cgc2ltcGxlIHNsb3BlcwogICAgICAgICAgICAgIGN2cyA9IE5VTEwsICMgY292YXJpYXRlcyAoaWYgYW55KQogICAgICAgICAgICAgIGRmID0gbW9kX2FuYWx5c2lzLCAjIGRhdGEgZnJhbWUgb2YgY29sdW1ucwogICAgICAgICAgICAgIHdpdGhfb3V0ID0gRikgIyByZW1vdmUgb3V0bGllcnMKCiMgQ2FuIHZpZXcgdGhlIGZ1bGwgZGF0YSBzZXQsIGluY2x1ZGluZyB0aGUgaWRlbnRpZmllZCBvdXRsaWVycyAobGFzdCBjb2x1bW5zKQojIFZpZXcobW9kX1NBRF9kaXN0MiRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhKQoKYGBgCgpSdW4gdGhlIG1vZGVyYXRpb24gYW5hbHlzZXMgZm9yIFNVUSB2YXJpYWJsZShzKTogQWdlLgoKYGBge3IgcnVuX21vZF9TVVFfYWdlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHQ9J2hpZGUnfQojLS0gUnVuIG1vZGVyYXRpb24gYW5hbHlzaXMgdXNpbmcgbW9kZXJhdGlvbjEoKSBpbiB0aGUgTWVNb0Jvb3RSIHBhY2thZ2UKICAjIG5vdGU6IG1vZGVyYXRvciAobSkgYW5kIElWICh4KSBhcmUgc3dpdGNoZWQgc2luY2UgbW9kZXJhdG9yIGlzIGNvbnRpbnVvdXMgJiBJViBpcyBjYXRlZ29yaWNhbCBpbiBwcmVzZW50IHN0dWR5CiAgICAjIHdhcyBjaGVja2VkIHZzLiBtYW51YWwgbG0oKSB2ZXJzaW9uICYgY29tcHV0ZXMgZXhhY3Qgc2FtZSB2YWx1ZXMKICAjIG5vdGU6IGFuYWx5c2lzIG1lYW4tY2VudGVycyB0aGUgY29udGludW91cyB2YXIgYXV0b21hdGljYWxseQogICMgbm90ZTogdGhpcyBhbmFseXNpcyB3aWxsIGNvbXBhcmU6IGRlc2sgdnMuIHBvY2tldC9iYWcmICBkZXNrIHZzLiBvdXRzaWRlIGluaXRpYWxseSAKICAgICMgdGhlbiwgdGhlIGRhdGEgaXMgcmUtb3JnYW5pemVkIHRvIGNvbXBhcmU6IHBvY2tldC9iYWcgdnMuIG91dHNpZGUgCiAgICAjIHRoaXMgd2FzIHNhdmVkIGludG8gMiBzZXBhcmF0ZSBhbmFseXNlcywgYnV0IG1vc3Qgb3V0cHV0IGlzIGNvbW1vbiBiL3cgdGhlbQoKIyMgQUdFICMjCiMgcnVuICYgc2F2ZSBhbmFseXNpcyB0byB2aWV3IGNvbXBvbmVudHMgc2VwYXJhdGVseSAKIyBmb3IgZGVzayAxc3QKbW9kX1NVUV9hZ2UxIDwtICAKICBtb2RlcmF0aW9uMSh5ID0gIm9zcGFuX2Fic29sdXRlX3Njb3JlIiwgIyBEVgogICAgICAgICAgICAgIHggPSAiYWdlIiwgIyBjb250aW51b3VzIHZhcgogICAgICAgICAgICAgIG0gPSAibG9jYXRpb25fZGVzayIsICMgY2F0ZWdvcmljYWwgdmFyIC0tIHdpbGwgc2hvdyBzaW1wbGUgc2xvcGVzCiAgICAgICAgICAgICAgY3ZzID0gTlVMTCwgIyBjb3ZhcmlhdGVzIChpZiBhbnkpCiAgICAgICAgICAgICAgZGYgPSBtb2RfYW5hbHlzaXMsICMgZGF0YSBmcmFtZSBvZiBjb2x1bW5zCiAgICAgICAgICAgICAgd2l0aF9vdXQgPSBGKSAjIHJlbW92ZSBvdXRsaWVycwoKIyBDYW4gdmlldyB0aGUgZnVsbCBkYXRhIHNldCwgaW5jbHVkaW5nIHRoZSBpZGVudGlmaWVkIG91dGxpZXJzIChsYXN0IGNvbHVtbnMpCiMgVmlldyhtb2RfU1VRX2FnZTEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSkKCiMgZm9yIG91dHNpZGUgMXN0Cm1vZF9TVVFfYWdlMiA8LSAgCiAgbW9kZXJhdGlvbjEoeSA9ICJvc3Bhbl9hYnNvbHV0ZV9zY29yZSIsICMgRFYKICAgICAgICAgICAgICB4ID0gImFnZSIsICMgY29udGludW91cyB2YXIKICAgICAgICAgICAgICBtID0gImxvY2F0aW9uX291dCIsICNjYXRlZ29yaWNhbCB2YXIgLS0gd2lsbCBzaG93IHNpbXBsZSBzbG9wZXMKICAgICAgICAgICAgICBjdnMgPSBOVUxMLCAjIGNvdmFyaWF0ZXMgKGlmIGFueSkKICAgICAgICAgICAgICBkZiA9IG1vZF9hbmFseXNpcywgIyBkYXRhIGZyYW1lIG9mIGNvbHVtbnMKICAgICAgICAgICAgICB3aXRoX291dCA9IEYpICMgcmVtb3ZlIG91dGxpZXJzCgojIENhbiB2aWV3IHRoZSBmdWxsIGRhdGEgc2V0LCBpbmNsdWRpbmcgdGhlIGlkZW50aWZpZWQgb3V0bGllcnMgKGxhc3QgY29sdW1ucykKIyBWaWV3KG1vZF9TVVFfYWdlMiRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhKQoKYGBgCgo8L2RldGFpbHM+CgojIyMjIyBPdXRsaWVycwoKVGhlIG1vZGVsIGlkZW50aWZpZWQgb3V0bGllcnMgYmFzZWQgb24gbGV2ZXJhZ2UgYW5kIGNvb2sncyBkaXN0YW5jZSBhbmQgcmVtb3ZlZCBwYXJ0aWNpcGFudHMgd2hvIHdlcmUgb3V0c2lkZSBvZiB0aGUgY3JpdGVyaWEgZm9yIGJvdGggbWVhc3VyZXMuCgotICAgKipMZXZlcmFnZSoqCgogICAgLSAgIFRlc3RzIGZvciBob3cgbXVjaCBpbmZsdWVuY2Ugb3ZlciB0aGUgc2xvcGUgYSBzaW5nbGUgb2JzZXJ2YXRpb24gKGkuZS4sIHBhcnRpY2lwYW50KSBoYXM6IGhvdyBtdWNoIGFuIGluZGl2aWR1YWwgc2NvcmUgd2lsbCBjaGFuZ2UgdGhlIGItdmFsdWVzCiAgICAtICAgU2NvcmVzIHRoYXQgZmFsbCBvdXRzaWRlIG9mIHRoZSAiY3V0LW9mZiIgY3JpdGVyaWEgaGF2ZSBhIGxhcmdlIGVmZmVjdCBvbiB0aGUgc2xvcGUgaW5kZXBlbmRlbnQgb2Ygb3RoZXIgc2NvcmUgYW5kIGFyZSB0aGVyZWZvcmUgY29uc2lkZXJlZCBvdXRsaWVycy4gVGhlc2UgYXJlIGRlZmluZWQgd2l0aCB0aGUgZXF1YXRpb24gJFxmcmFjezJLKzJ9e059JCwgd2hlcmUgKksqIGlzIHRoZSBudW1iZXIgb2YgSVZzL3ByZWRpY3RvcnMgYW5kICpOKiBpcyB0aGUgc2FtcGxlIHNpemUuCgotICAgKipDb29rJ3MgRGlzdGFuY2UqKgoKICAgIC0gICBUZXN0cyBmb3IgaW5mbHVlbnRpYWwgb2JzZXJ2YXRpb25zOiB0aGUgY29tYmluYXRpb24gb2YgbGV2ZXJhZ2UgYW5kIGRpc2NyZXBhbmN5IChpLmUuLCBob3cgZmFyIGEgc2NvcmUgaXMgZnJvbSBvdGhlciBkYXRhIHBvaW50cykuCiAgICAtICAgU2NvcmVzIHRoYXQgZmFsbCBvdXRzaWRlIG9mIHRoZSAiY3V0LW9mZiIgY3JpdGVyaWEgaGF2ZSBhIGxhcmdlIGVmZmVjdCBvbiB0aGUgc2xvcGUgaW5kZXBlbmRlbnQgb2Ygb3RoZXIgc2NvcmUgYW5kL29yIGFyZSBmYXIgZnJvbSB0aGUgcmVzdCBvZiB0aGUgZGF0YSBhbmQgYXJlIHRoZXJlZm9yZSBjb25zaWRlcmVkIG91dGxpZXJzLiBUaGVzZSBhcmUgZGVmaW5lZCB3aXRoIHRoZSBlcXVhdGlvbiAkXGZyYWN7NH17Ti1LLTF9JCwgd2hlcmUgKksqIGlzIHRoZSBudW1iZXIgb2YgSVZzL3ByZWRpY3RvcnMgYW5kICpOKiBpcyB0aGUgc2FtcGxlIHNpemUuCgotICAgKipQYXJ0aWNpcGFudHMgUmVtb3ZlZCoqCgogICAgLSAgIEFueSBwYXJ0aWNpcGFudCB3aG8gZmVsbCBvdXRzaWRlIG9mIGJvdGggdGhlIGxldmVyYWdlIGFuZCBjb29rIGNyaXRlcmlhIHdlcmUgcmVtb3ZlZCBmcm9tIGVhY2ggYW5hbHlzaXMuIFRoaXMgd2FzIGRvbmUgc2VwYXJhdGVseSBmb3IgZWFjaCBhbmFseXNpcyAoc2VlIHRhYmxlIGJlbG93KS4KCmBgYHtyIGNyZWF0ZV9tb2RfY29udF9vdXRfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjcmVhdGUgYSB0YWJsZSBkZXBpY3RpbmcgdGhlIHRvdGFsIG91dGxpZXJzIHJlbW92ZWQgZm9yIGVhY2ggY29udGludW91cyBtb2RlcmF0aW9uIGFuYWx5c2lzCiMgZGV0YWlscyBzaG93biBmb3IgMXN0IChkZXBlbmRlbmN5KQptb2RfY29udF9vdXRfdCA8LSAKICBhcy5kYXRhLmZyYW1lKGNiaW5kKGMoIkRlcGVuZGVuY3kiLCAiRW1vdGlvbmFsIEF0dGFjaG1lbnQiLCAiQWNjZXNzaWJpbGl0eSIsICJEaXN0cmFjdGliaWxpdHkiLCAiQWdlIiksIAogICAgICAgICAgICAgICAgICAgICAgcmJpbmQoCiAgICAgICAgICAgICAgICAgICAgICAjIGZvciBTQURfZGVwCiAgICAgICAgICAgICAgICAgICAgICBjKHN1bShtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSRiYWRsZXZlcmFnZSksICMgdG90YWwgcHMgdGhhdCBmZWxsIG91dHNpZGUgb2YgdGhlIGxldmVyYWdlIGNyaXRlcmlhCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSRiYWRjb29rcyksICMgdG90YWwgcHMgdGhhdCBmZWxsIG91dHNpZGUgb2YgdGhlIGNvb2tzIGNyaXRlcmlhCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAxKSwgIyB0b3RhbCBwcyB0aGF0IGZlbGwgb3V0c2lkZSBvZiBPTkUgb3V0bGllciBjcml0ZXJpYSAoaS5lLiwgbGV2ZXJhZ2UgT1IgY29va3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAyKSwgIyB0b3RhbCBwcyB0aGF0IGZlbGwgb3V0c2lkZSBvZiBCT1RIIG91dGxpZXIgY3JpdGVyaWEgKGkuZS4sIGxldmVyYWdlIEFORCBjb29rcykKICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyhtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSkgLSBzdW0obW9kX1NBRF9kZXAxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMikgIyB0b3RhbCBzYW1wbGUgc2l6ZSB1c2VkIGluIGdpdmVuIGFuYWx5c2lzCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgICAgICAgIyBmb3IgU0FEX2VhCiAgICAgICAgICAgICAgICAgICAgICBjKHN1bShtb2RfU0FEX2VhMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJGJhZGxldmVyYWdlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2VhMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJGJhZGNvb2tzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2VhMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJHRvdGFsb3V0ID09IDEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgc3VtKG1vZF9TQURfZWExJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICBucm93KG1vZF9TQURfZWExJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpIC0gc3VtKG1vZF9TQURfZWExJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMikKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICMgZm9yIFNBRF9hY2Nlc3MKICAgICAgICAgICAgICAgICAgICAgIGMoc3VtKG1vZF9TQURfYWNjZXNzMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJGJhZGxldmVyYWdlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2FjY2VzczEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSRiYWRjb29rcyksIAogICAgICAgICAgICAgICAgICAgICAgICBzdW0obW9kX1NBRF9hY2Nlc3MxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMSksIAogICAgICAgICAgICAgICAgICAgICAgICBzdW0obW9kX1NBRF9hY2Nlc3MxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICBucm93KG1vZF9TQURfYWNjZXNzMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhKSAtIHN1bShtb2RfU0FEX2FjY2VzczEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAyKQogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgIyBmb3IgU0FEX2Rpc3QKICAgICAgICAgICAgICAgICAgICAgIGMoc3VtKG1vZF9TQURfZGlzdDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSRiYWRsZXZlcmFnZSksIAogICAgICAgICAgICAgICAgICAgICAgICBzdW0obW9kX1NBRF9kaXN0MSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJGJhZGNvb2tzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU0FEX2Rpc3QxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkdG90YWxvdXQgPT0gMSksIAogICAgICAgICAgICAgICAgICAgICAgICBzdW0obW9kX1NBRF9kaXN0MSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJHRvdGFsb3V0ID09IDIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyhtb2RfU0FEX2Rpc3QxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpIC0gc3VtKG1vZF9TQURfZGlzdDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAyKQogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgIyBmb3IgU1VRX2FnZQogICAgICAgICAgICAgICAgICAgICAgYyhzdW0obW9kX1NVUV9hZ2UxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEkYmFkbGV2ZXJhZ2UpLCAKICAgICAgICAgICAgICAgICAgICAgICAgc3VtKG1vZF9TVVFfYWdlMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJGJhZGNvb2tzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU1VRX2FnZTEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAxKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHN1bShtb2RfU1VRX2FnZTEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSR0b3RhbG91dCA9PSAyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIG5yb3cobW9kX1NVUV9hZ2UxJGRhdGFzY3JlZW5pbmckZnVsbGRhdGEpIC0gc3VtKG1vZF9TVVFfYWdlMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhJHRvdGFsb3V0ID09IDIpCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCiMgcmVuYW1lIGNvbHVtbnMKY29sbmFtZXMobW9kX2NvbnRfb3V0X3QpIDwtIGMoIiAiLCAiTGV2ZXJhZ2UiLCAiQ29va3MiLCAiQm90aCIsICJSZW1vdmVkIiwgIk4iKQoKIyB1c2Uga2FibGUgdG8gc2hvdyB0YWJsZQprYWJsZShtb2RfY29udF9vdXRfdCwgY2FwdGlvbiA9ICJTdW1tYXJ5IG9mIGlkZW50aWZpZWQgYW5kIG9yIHJlbW92ZWQgb3V0bGllcnMgaW4gR0xNIG1kZXJhdGlvbiBhbmFseXNpcy4iLCBhbGlnbiA9ICdyY2NjY2MnKSAlPiUKICBmb290bm90ZShnZW5lcmFsID0gIlNhbXBsZSBzaXplIHByaW9yIHRvIHJlbW92aW5nIG91dGxpZXIgZGF0YSBmb3IgYWxsIGFuYWx5c2VzIHdhcyAzODMuIikgJT4lIAogIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiQ3JpdGVyaWEiID0gMiwgIlRvdGFsIENyaXRlcmlhIiA9IDIsICIiKSkgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgojIyMjIyBBc3N1bXB0aW9ucwoKPGRldGFpbHM+Cgo8c3VtbWFyeT4KClRoZSBtb2RlbCBjb21wbGV0ZWQgYXNzdW1wdGlvbiB0ZXN0cyBmb3I6ICgxKSBhZGRpdGl2aXR5L211bHRpY29sbGluZWFyaXR5LCAoMikgbGluZWFyaXR5LCAoMykgbm9ybWFsaXR5LCAoNCkgaG9tb2dlbmVpdHkgYW5kIGhvbW9zY2VkYXN0aWNpdHkuIEFsbCBhc3N1bXB0aW9ucyB3ZXJlIG1ldCBmb3IgYWxsIG1vZGVyYXRvcnMuICooY2xpY2sgdG8gc2VlIGRldGFpbHMpKgoKPC9zdW1tYXJ5PgoKIyMjIyMjICgxKSBBZGRpdGl2aXR5IC8gTXVsdGljb2xsaW5lYXJpdHkKCkFkZGl0aXZpdHkgLyBNdWx0aWNvbGxpbmVhcml0eSB3YXMgZXZhbHVhdGVkIGZvciBlYWNoIG1vZGVyYXRvci4gQ29ycmVsYXRpb25zIGJldHdlZW4gdGhlIG1vZGVyYXRvciBhbmQgZWFjaCBJViBjb21wYXJpc29uIHdhcyB2aXN1YWxseSBpbnNwZWN0ZWQgdG8gZW5zdXJlIHRoZSBjb3JyZWxhdGlvbnMgd2VyZSBub3QgdG9vIGhpZ2ggb3IgbG93IChpLmUuLCBhcHByb3hpbWF0ZWx5IHJhbmdpbmcgYmV0d2VlbiAuMzAgdG8gLjgwKS4gQWxsIG1vZGVyYXRvcnMnIGNvcnJlbGF0aW9ucyB3ZXJlIHdpdGhpbiBhbiBhY2NlcHRhYmxlIHJhbmdlLgoKXAoqKkRlcGVuZGVuY3kgTW9kZXJhdG9yKio6IGNvcnJlbGF0aW9ucyByYW5nZWQgZnJvbSBgciByb3VuZChtaW4obW9kX1NBRF9kZXBfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXSksIDIpYCB0byBgciByb3VuZChtYXgobW9kX1NBRF9kZXBfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXVttb2RfU0FEX2RlcF9jb3JyX3RbMTozLCBjKDI6NCwgOToxMSldICE9bWF4KG1vZF9TQURfZGVwX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0pXSksIDIpYC4KCmBgYHtyIGNyZWF0ZSAmIHNob3cgbW9kX1NBRF9kZXBfY29ycl90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGdyYWIgdGFibGUgZnJvbSBvdXRwdXQKbW9kX1NBRF9kZXBfY29ycl90IDwtIAogIGFzLmRhdGEuZnJhbWUoY2JpbmQoYygiRGVwZW5kZW5jeSBTY29yZSIsICJEZXNrIHZzLiBQb2NrZXQvQmFnIiwgIkRlc2sgdnMuIE91dHNpZGUiLCAiRGVwIHggRHZQQiIsICJEZXAgeCBEdk8iKSwgCiAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdLAogICAgICAgICAgICAgICAgICAgICAgYyg2OjEwKSwKICAgICAgICAgICAgICAgICAgICAgIGMoIkRlcGVuZGVuY3kgU2NvcmUiLCAiT3V0c2lkZSB2cy4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIHZzLiBEZXNrIiwgIkRlcCB4IE92UEIiLCAiRGVwIHggT3ZEIiksCiAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2RlcDIkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdKQogICAgICAgICAgICAgICAgKQojIHJlbmFtZSByb3dzICYgY29sdW1ucwpjb2xuYW1lcyhtb2RfU0FEX2RlcF9jb3JyX3QpIDwtIGMoInZhcjEiLCAiRGVwZW5kZW5jeSBTY29yZSIsICJEZXNrIHZzLiBQb2NrZXQvQmFnIiwgIkRlc2sgdnMuIE91dHNpZGUiLCAiRGVwIHggRHZQQiIsICJEZXAgeCBEdk8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJvdyIsICJ2YXIyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGVwZW5kZW5jeSBTY29yZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgIk91dHNpZGUgdnMuIERlc2siLCAiRGVwIHggT3ZQQiIsICJEZXAgeCBPdkQiKQpyb3duYW1lcyhtb2RfU0FEX2RlcF9jb3JyX3QpIDwtIDE6bnJvdyhtb2RfU0FEX2RlcF9jb3JyX3QpCgojIHJlc2V0IHZhbHVlcyBhcyBudW1lcmljCm1vZF9TQURfZGVwX2NvcnJfdFssMl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2RlcF9jb3JyX3RbLDJdKQptb2RfU0FEX2RlcF9jb3JyX3RbLDNdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90WywzXSkKbW9kX1NBRF9kZXBfY29ycl90Wyw0XSA8LSBhcy5udW1lcmljKG1vZF9TQURfZGVwX2NvcnJfdFssNF0pCm1vZF9TQURfZGVwX2NvcnJfdFssNV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2RlcF9jb3JyX3RbLDVdKQptb2RfU0FEX2RlcF9jb3JyX3RbLDZdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90Wyw2XSkKbW9kX1NBRF9kZXBfY29ycl90Wyw5XSA8LSBhcy5udW1lcmljKG1vZF9TQURfZGVwX2NvcnJfdFssOV0pCm1vZF9TQURfZGVwX2NvcnJfdFssMTBdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90WywxMF0pCm1vZF9TQURfZGVwX2NvcnJfdFssMTFdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90WywxMV0pCm1vZF9TQURfZGVwX2NvcnJfdFssMTJdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90WywxMl0pCm1vZF9TQURfZGVwX2NvcnJfdFssMTNdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kZXBfY29ycl90WywxM10pCgojIFByaW50IHRhYmxlIHVzaW5nIGthYmxlCmthYmxlKG1vZF9TQURfZGVwX2NvcnJfdCwgY2FwdGlvbiA9ICJDb3JyZWxhdGlvbnMgZm9yIHRoZSBkZXBlbmRlbmN5IG1vZGVyYXRvci4iLCAKICAgICAgZGlnaXRzID0gMiwgYWxpZ24gPSAncmNjY2NjY3JyY2NjYycsIHJvdy5uYW1lcyA9IFQsIGNvbC5uYW1lcyA9IGMoIiAiLCAxOjUsICIiLCAiIiwgNjoxMCkpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiwgIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiksIGJvbGQgPSBUKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIkNvbXBhcmlzb24gR3JvdXA6IFxuRGVzayIgPSA1LCAiICIgPSAyLCAiQ29tcGFyaXNvbiBHcm91cDogXG5PdXRzaWRlIiA9IDUpKSAlPiUKICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDcsIGJvcmRlcl9yaWdodCA9IFQpICU+JQogIGthYmxlX2NsYXNzaWMoKQpgYGAKClwKKipFbW90aW9uYWwgQXR0YWNobWVudCBNb2RlcmF0b3IqKjogY29ycmVsYXRpb25zIHJhbmdlZCBmcm9tIGByIHJvdW5kKG1pbihtb2RfU0FEX2VhX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0pLCAyKWAgdG8gYHIgcm91bmQobWF4KG1vZF9TQURfZWFfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXVttb2RfU0FEX2VhX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0gIT1tYXgobW9kX1NBRF9lYV9jb3JyX3RbMTozLCBjKDI6NCwgOToxMSldKV0pLCAyKWAuCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TQURfZWFfY29ycl90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGdyYWIgdGFibGUgZnJvbSBvdXRwdXQKbW9kX1NBRF9lYV9jb3JyX3QgPC0gCiAgYXMuZGF0YS5mcmFtZShjYmluZChjKCJFbW90aW9uYWwgQXR0YWNobWVudCBTY29yZSIsICJEZXNrIHZzLiBQb2NrZXQvQmFnIiwgIkRlc2sgdnMuIE91dHNpZGUiLCAiRUEgeCBEdlBCIiwgIkVBIHggRHZPIiksIAogICAgICAgICAgICAgICAgICAgICAgbW9kX1NBRF9lYTEkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdLAogICAgICAgICAgICAgICAgICAgICAgYyg2OjEwKSwKICAgICAgICAgICAgICAgICAgICAgIGMoIkVtb3Rpb25hbCBBdHRhY2htZW50IFNjb3JlIiwgIk91dHNpZGUgdnMuIFBvY2tldC9CYWciLCAiT3V0c2lkZSB2cy4gRGVzayIsICJFQSB4IE92UEIiLCAiRUEgeCBPdkQiKSwKICAgICAgICAgICAgICAgICAgICAgIG1vZF9TQURfZWEyJGRhdGFzY3JlZW5pbmckY29ycmVsWzI6NiwgMjo2XSkKICAgICAgICAgICAgICAgICkKIyByZW5hbWUgcm93cyAmIGNvbHVtbnMKY29sbmFtZXMobW9kX1NBRF9lYV9jb3JyX3QpIDwtIGMoInZhcjEiLCAiRW1vdGlvbmFsIEF0dGFjaG1lbnQgU2NvcmUiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIkVBIHggRHZQQiIsICJFQSB4IER2TyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm93IiwgInZhcjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbW90aW9uYWwgQXR0YWNobWVudCBTY29yZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgIk91dHNpZGUgdnMuIERlc2siLCAiRUEgeCBPdlBCIiwgIkVBIHggT3ZEIikKcm93bmFtZXMobW9kX1NBRF9lYV9jb3JyX3QpIDwtIDE6bnJvdyhtb2RfU0FEX2VhX2NvcnJfdCkKCiMgcmVzZXQgdmFsdWVzIGFzIG51bWVyaWMKbW9kX1NBRF9lYV9jb3JyX3RbLDJdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9lYV9jb3JyX3RbLDJdKQptb2RfU0FEX2VhX2NvcnJfdFssM10gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2VhX2NvcnJfdFssM10pCm1vZF9TQURfZWFfY29ycl90Wyw0XSA8LSBhcy5udW1lcmljKG1vZF9TQURfZWFfY29ycl90Wyw0XSkKbW9kX1NBRF9lYV9jb3JyX3RbLDVdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9lYV9jb3JyX3RbLDVdKQptb2RfU0FEX2VhX2NvcnJfdFssNl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2VhX2NvcnJfdFssNl0pCm1vZF9TQURfZWFfY29ycl90Wyw5XSA8LSBhcy5udW1lcmljKG1vZF9TQURfZWFfY29ycl90Wyw5XSkKbW9kX1NBRF9lYV9jb3JyX3RbLDEwXSA8LSBhcy5udW1lcmljKG1vZF9TQURfZWFfY29ycl90WywxMF0pCm1vZF9TQURfZWFfY29ycl90WywxMV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2VhX2NvcnJfdFssMTFdKQptb2RfU0FEX2VhX2NvcnJfdFssMTJdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9lYV9jb3JyX3RbLDEyXSkKbW9kX1NBRF9lYV9jb3JyX3RbLDEzXSA8LSBhcy5udW1lcmljKG1vZF9TQURfZWFfY29ycl90WywxM10pCgojIFByaW50IHRhYmxlIHVzaW5nIGthYmxlCmthYmxlKG1vZF9TQURfZWFfY29ycl90LCBjYXB0aW9uID0gIkNvcnJlbGF0aW9ucyBmb3IgdGhlIGVtb3Rpb25hbCBhdHRhY2htZW50IG1vZGVyYXRvci4iLCAKICAgICAgZGlnaXRzID0gMiwgYWxpZ24gPSAncmNjY2NjY3JyY2NjYycsIHJvdy5uYW1lcyA9IFQsIGNvbC5uYW1lcyA9IGMoIiAiLCAxOjUsICIiLCAiIiwgNjoxMCkpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiwgIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiksIGJvbGQgPSBUKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIkNvbXBhcmlzb24gR3JvdXA6IFxuRGVzayIgPSA1LCAiICIgPSAyLCAiQ29tcGFyaXNvbiBHcm91cDogXG5PdXRzaWRlIiA9IDUpKSAlPiUKICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDcsIGJvcmRlcl9yaWdodCA9IFQpICU+JQogIGthYmxlX2NsYXNzaWMoKQpgYGAKClwKKipBY2Nlc3NpYmlsaXR5IE1vZGVyYXRvcioqOiBjb3JyZWxhdGlvbnMgcmFuZ2VkIGZyb20gYHIgcm91bmQobWluKG1vZF9TQURfYWNjZXNzX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0pLCAyKWAgdG8gYHIgcm91bmQobWF4KG1vZF9TQURfYWNjZXNzX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV1bbW9kX1NBRF9hY2Nlc3NfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXSAhPW1heChtb2RfU0FEX2FjY2Vzc19jb3JyX3RbMTozLCBjKDI6NCwgOToxMSldKV0pLCAyKWAuCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TQURfYWNjZXNzX2NvcnJfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBncmFiIHRhYmxlIGZyb20gb3V0cHV0Cm1vZF9TQURfYWNjZXNzX2NvcnJfdCA8LSAKICBhcy5kYXRhLmZyYW1lKGNiaW5kKGMoIkVtb3Rpb25hbCBBdHRhY2htZW50IFNjb3JlIiwgIkRlc2sgdnMuIFBvY2tldC9CYWciLCAiRGVzayB2cy4gT3V0c2lkZSIsICJBY2Nlc3MgeCBEdlBCIiwgIkFjY2VzcyB4IER2TyIpLCAKICAgICAgICAgICAgICAgICAgICAgIG1vZF9TQURfYWNjZXNzMSRkYXRhc2NyZWVuaW5nJGNvcnJlbFsyOjYsIDI6Nl0sCiAgICAgICAgICAgICAgICAgICAgICBjKDY6MTApLAogICAgICAgICAgICAgICAgICAgICAgYygiRW1vdGlvbmFsIEF0dGFjaG1lbnQgU2NvcmUiLCAiT3V0c2lkZSB2cy4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIHZzLiBEZXNrIiwgIkFjY2VzcyB4IE92UEIiLCAiQWNjZXNzIHggT3ZEIiksCiAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2FjY2VzczIkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdKQogICAgICAgICAgICAgICAgKQojIHJlbmFtZSByb3dzICYgY29sdW1ucwpjb2xuYW1lcyhtb2RfU0FEX2FjY2Vzc19jb3JyX3QpIDwtIGMoInZhcjEiLCAiRW1vdGlvbmFsIEF0dGFjaG1lbnQgU2NvcmUiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIkFjY2VzcyB4IER2UEIiLCAiQWNjZXNzIHggRHZPIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb3ciLCAidmFyMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVtb3Rpb25hbCBBdHRhY2htZW50IFNjb3JlIiwgIk91dHNpZGUgdnMuIFBvY2tldC9CYWciLCAiT3V0c2lkZSB2cy4gRGVzayIsICJBY2Nlc3MgeCBPdlBCIiwgIkFjY2VzcyB4IE92RCIpCnJvd25hbWVzKG1vZF9TQURfYWNjZXNzX2NvcnJfdCkgPC0gMTpucm93KG1vZF9TQURfYWNjZXNzX2NvcnJfdCkKCiMgcmVzZXQgdmFsdWVzIGFzIG51bWVyaWMKbW9kX1NBRF9hY2Nlc3NfY29ycl90WywyXSA8LSBhcy5udW1lcmljKG1vZF9TQURfYWNjZXNzX2NvcnJfdFssMl0pCm1vZF9TQURfYWNjZXNzX2NvcnJfdFssM10gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDNdKQptb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDRdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9hY2Nlc3NfY29ycl90Wyw0XSkKbW9kX1NBRF9hY2Nlc3NfY29ycl90Wyw1XSA8LSBhcy5udW1lcmljKG1vZF9TQURfYWNjZXNzX2NvcnJfdFssNV0pCm1vZF9TQURfYWNjZXNzX2NvcnJfdFssNl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDZdKQptb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDldIDwtIGFzLm51bWVyaWMobW9kX1NBRF9hY2Nlc3NfY29ycl90Wyw5XSkKbW9kX1NBRF9hY2Nlc3NfY29ycl90WywxMF0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDEwXSkKbW9kX1NBRF9hY2Nlc3NfY29ycl90WywxMV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDExXSkKbW9kX1NBRF9hY2Nlc3NfY29ycl90WywxMl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDEyXSkKbW9kX1NBRF9hY2Nlc3NfY29ycl90WywxM10gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2FjY2Vzc19jb3JyX3RbLDEzXSkKCiMgUHJpbnQgdGFibGUgdXNpbmcga2FibGUKa2FibGUobW9kX1NBRF9hY2Nlc3NfY29ycl90LCBjYXB0aW9uID0gIkNvcnJlbGF0aW9ucyBmb3IgdGhlIGFjY2Vzc2liaWxpdHkgbW9kZXJhdG9yLiIsIAogICAgICBkaWdpdHMgPSAyLCBhbGlnbiA9ICdyY2NjY2NjcnJjY2NjJywgcm93Lm5hbWVzID0gVCwgY29sLm5hbWVzID0gYygiICIsIDE6NSwgIiIsICIiLCA2OjEwKSkgJT4lCiAgIyBmb290bm90ZShnZW5lcmFsID0gIkludGVyYWN0aW9uIHZhcmlhYmxlcyAiKSAlPiUgCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIgPSAyLCAiTW9kZXJhdG9yIiwgIkxvY2F0aW9uIiA9IDIsICJJbnRlcmFjdGlvbiIgPSAyLCAiICIgPSAyLCAiTW9kZXJhdG9yIiwgIkxvY2F0aW9uIiA9IDIsICJJbnRlcmFjdGlvbiIgPSAyKSwgYm9sZCA9IFQpICU+JQogIGFkZF9oZWFkZXJfYWJvdmUoYygiICIgPSAyLCAiQ29tcGFyaXNvbiBHcm91cDogXG5EZXNrIiA9IDUsICIgIiA9IDIsICJDb21wYXJpc29uIEdyb3VwOiBcbk91dHNpZGUiID0gNSkpICU+JQogIGNvbHVtbl9zcGVjKDIsIGJvbGQgPSBUKSAlPiUKICBjb2x1bW5fc3BlYyg5LCBib2xkID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoNywgYm9yZGVyX3JpZ2h0ID0gVCkgJT4lCiAga2FibGVfY2xhc3NpYygpCmBgYAoKXAoqKkRpc3RyYWN0aWJpbGl0eSBNb2RlcmF0b3IqKjogY29ycmVsYXRpb25zIHJhbmdlZCBmcm9tIGByIHJvdW5kKG1pbihtb2RfU0FEX2Rpc3RfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXSksIDIpYCB0byBgciByb3VuZChtYXgobW9kX1NBRF9kaXN0X2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV1bbW9kX1NBRF9kaXN0X2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0gIT1tYXgobW9kX1NBRF9kaXN0X2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0pXSksIDIpYC4KCmBgYHtyIGNyZWF0ZSAmIHNob3cgbW9kX1NBRF9kaXN0X2NvcnJfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBncmFiIHRhYmxlIGZyb20gb3V0cHV0Cm1vZF9TQURfZGlzdF9jb3JyX3QgPC0gCiAgYXMuZGF0YS5mcmFtZShjYmluZChjKCJEaXN0cmFjdGliaWxpdHkgU2NvcmUiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIkRpc3QgeCBEdlBCIiwgIkRpc3QgeCBEdk8iKSwgCiAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2Rpc3QxJGRhdGFzY3JlZW5pbmckY29ycmVsWzI6NiwgMjo2XSwKICAgICAgICAgICAgICAgICAgICAgIGMoNjoxMCksCiAgICAgICAgICAgICAgICAgICAgICBjKCJEaXN0cmFjdGliaWxpdHkgU2NvcmUiLCAiT3V0c2lkZSB2cy4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIHZzLiBEZXNrIiwgIkRpc3QgeCBPdlBCIiwgIkRpc3QgeCBPdkQiKSwKICAgICAgICAgICAgICAgICAgICAgIG1vZF9TQURfZGlzdDIkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdKQogICAgICAgICAgICAgICAgKQojIHJlbmFtZSByb3dzICYgY29sdW1ucwpjb2xuYW1lcyhtb2RfU0FEX2Rpc3RfY29ycl90KSA8LSBjKCJ2YXIxIiwgIkRpc3RyYWN0aWJpbGl0eSBTY29yZSIsICJEZXNrIHZzLiBQb2NrZXQvQmFnIiwgIkRlc2sgdnMuIE91dHNpZGUiLCAiRGlzdCB4IER2UEIiLCAiRGlzdCB4IER2TyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm93IiwgInZhcjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXN0cmFjdGliaWxpdHkgU2NvcmUiLCAiT3V0c2lkZSB2cy4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIHZzLiBEZXNrIiwgIkRpc3QgeCBPdlBCIiwgIkRpc3QgeCBPdkQiKQpyb3duYW1lcyhtb2RfU0FEX2Rpc3RfY29ycl90KSA8LSAxOm5yb3cobW9kX1NBRF9kaXN0X2NvcnJfdCkKCiMgcmVzZXQgdmFsdWVzIGFzIG51bWVyaWMKbW9kX1NBRF9kaXN0X2NvcnJfdFssMl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90WywyXSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssM10gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90WywzXSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssNF0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90Wyw0XSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssNV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90Wyw1XSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssNl0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90Wyw2XSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssOV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90Wyw5XSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssMTBdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kaXN0X2NvcnJfdFssMTBdKQptb2RfU0FEX2Rpc3RfY29ycl90WywxMV0gPC0gYXMubnVtZXJpYyhtb2RfU0FEX2Rpc3RfY29ycl90WywxMV0pCm1vZF9TQURfZGlzdF9jb3JyX3RbLDEyXSA8LSBhcy5udW1lcmljKG1vZF9TQURfZGlzdF9jb3JyX3RbLDEyXSkKbW9kX1NBRF9kaXN0X2NvcnJfdFssMTNdIDwtIGFzLm51bWVyaWMobW9kX1NBRF9kaXN0X2NvcnJfdFssMTNdKQoKIyBQcmludCB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShtb2RfU0FEX2Rpc3RfY29ycl90LCBjYXB0aW9uID0gIkNvcnJlbGF0aW9ucyBmb3IgdGhlIGRpc3RyYWN0aWJpbGl0eSBtb2RlcmF0b3IuIiwgCiAgICAgIGRpZ2l0cyA9IDIsIGFsaWduID0gJ3JjY2NjY2NycmNjY2MnLCByb3cubmFtZXMgPSBULCBjb2wubmFtZXMgPSBjKCIgIiwgMTo1LCAiIiwgIiIsIDY6MTApKSAlPiUKICAjIGZvb3Rub3RlKGdlbmVyYWwgPSAiSW50ZXJhY3Rpb24gdmFyaWFibGVzICIpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCAiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikgJT4lCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDIsICJNb2RlcmF0b3IiLCAiTG9jYXRpb24iID0gMiwgIkludGVyYWN0aW9uIiA9IDIsICIgIiA9IDIsICJNb2RlcmF0b3IiLCAiTG9jYXRpb24iID0gMiwgIkludGVyYWN0aW9uIiA9IDIpLCBib2xkID0gVCkgJT4lCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDIsICJDb21wYXJpc29uIEdyb3VwOiBcbkRlc2siID0gNSwgIiAiID0gMiwgIkNvbXBhcmlzb24gR3JvdXA6IFxuT3V0c2lkZSIgPSA1KSkgJT4lCiAgY29sdW1uX3NwZWMoMiwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDksIGJvbGQgPSBUKSAlPiUKICBjb2x1bW5fc3BlYyg3LCBib3JkZXJfcmlnaHQgPSBUKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgpcCioqQWdlIE1vZGVyYXRvcioqOiBjb3JyZWxhdGlvbnMgcmFuZ2VkIGZyb20gYHIgcm91bmQobWluKG1vZF9TVVFfYWdlX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV0pLCAyKWAgdG8gYHIgcm91bmQobWF4KG1vZF9TVVFfYWdlX2NvcnJfdFsxOjMsIGMoMjo0LCA5OjExKV1bbW9kX1NVUV9hZ2VfY29ycl90WzE6MywgYygyOjQsIDk6MTEpXSAhPW1heChtb2RfU1VRX2FnZV9jb3JyX3RbMTozLCBjKDI6NCwgOToxMSldKV0pLCAyKWAuCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TQURfYWdlX2NvcnJfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBncmFiIHRhYmxlIGZyb20gb3V0cHV0Cm1vZF9TVVFfYWdlX2NvcnJfdCA8LSAKICBhcy5kYXRhLmZyYW1lKGNiaW5kKGMoIkFnZSIsICJEZXNrIHZzLiBQb2NrZXQvQmFnIiwgIkRlc2sgdnMuIE91dHNpZGUiLCAiQWdlIHggRHZQQiIsICJBZ2UgeCBEdk8iKSwgCiAgICAgICAgICAgICAgICAgICAgICBtb2RfU1VRX2FnZTEkZGF0YXNjcmVlbmluZyRjb3JyZWxbMjo2LCAyOjZdLAogICAgICAgICAgICAgICAgICAgICAgYyg2OjEwKSwKICAgICAgICAgICAgICAgICAgICAgIGMoIkFnZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgIk91dHNpZGUgdnMuIERlc2siLCAiQWdlIHggT3ZQQiIsICJBZ2UgeCBPdkQiKSwKICAgICAgICAgICAgICAgICAgICAgIG1vZF9TVVFfYWdlMiRkYXRhc2NyZWVuaW5nJGNvcnJlbFsyOjYsIDI6Nl0pCiAgICAgICAgICAgICAgICApCiMgcmVuYW1lIHJvd3MgJiBjb2x1bW5zCmNvbG5hbWVzKG1vZF9TVVFfYWdlX2NvcnJfdCkgPC0gYygidmFyMSIsICJBZ2UiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIkFnZSB4IER2UEIiLCAiQWdlIHggRHZPIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm93IiwgInZhcjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZ2UiLCAiT3V0c2lkZSB2cy4gUG9ja2V0L0JhZyIsICJPdXRzaWRlIHZzLiBEZXNrIiwgIkFnZSB4IE92UEIiLCAiQWdlIHggT3ZEIikKcm93bmFtZXMobW9kX1NVUV9hZ2VfY29ycl90KSA8LSAxOm5yb3cobW9kX1NVUV9hZ2VfY29ycl90KQoKIyByZXNldCB2YWx1ZXMgYXMgbnVtZXJpYwptb2RfU1VRX2FnZV9jb3JyX3RbLDJdIDwtIGFzLm51bWVyaWMobW9kX1NVUV9hZ2VfY29ycl90WywyXSkKbW9kX1NVUV9hZ2VfY29ycl90WywzXSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssM10pCm1vZF9TVVFfYWdlX2NvcnJfdFssNF0gPC0gYXMubnVtZXJpYyhtb2RfU1VRX2FnZV9jb3JyX3RbLDRdKQptb2RfU1VRX2FnZV9jb3JyX3RbLDVdIDwtIGFzLm51bWVyaWMobW9kX1NVUV9hZ2VfY29ycl90Wyw1XSkKbW9kX1NVUV9hZ2VfY29ycl90Wyw2XSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssNl0pCm1vZF9TVVFfYWdlX2NvcnJfdFssOV0gPC0gYXMubnVtZXJpYyhtb2RfU1VRX2FnZV9jb3JyX3RbLDldKQptb2RfU1VRX2FnZV9jb3JyX3RbLDEwXSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssMTBdKQptb2RfU1VRX2FnZV9jb3JyX3RbLDExXSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssMTFdKQptb2RfU1VRX2FnZV9jb3JyX3RbLDEyXSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssMTJdKQptb2RfU1VRX2FnZV9jb3JyX3RbLDEzXSA8LSBhcy5udW1lcmljKG1vZF9TVVFfYWdlX2NvcnJfdFssMTNdKQoKIyBQcmludCB0YWJsZSB1c2luZyBrYWJsZQprYWJsZShtb2RfU1VRX2FnZV9jb3JyX3QsIGNhcHRpb24gPSAiQ29ycmVsYXRpb25zIGZvciB0aGUgYWdlIG1vZGVyYXRvci4iLCAKICAgICAgZGlnaXRzID0gMiwgYWxpZ24gPSAncmNjY2NjY3JyY2NjYycsIHJvdy5uYW1lcyA9IFQsIGNvbC5uYW1lcyA9IGMoIiAiLCAxOjUsICIiLCAiIiwgNjoxMCkpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiwgIiAiID0gMiwgIk1vZGVyYXRvciIsICJMb2NhdGlvbiIgPSAyLCAiSW50ZXJhY3Rpb24iID0gMiksIGJvbGQgPSBUKSAlPiUKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIkNvbXBhcmlzb24gR3JvdXA6IFxuRGVzayIgPSA1LCAiICIgPSAyLCAiQ29tcGFyaXNvbiBHcm91cDogXG5PdXRzaWRlIiA9IDUpKSAlPiUKICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoOSwgYm9sZCA9IFQpICU+JQogIGNvbHVtbl9zcGVjKDcsIGJvcmRlcl9yaWdodCA9IFQpICU+JQogIGthYmxlX2NsYXNzaWMoKQoKYGBgCgojIyMjIyMgKDIpIExpbmVhcml0eQoKTGluZWFyaXR5IHdhcyBldmFsdWF0ZWQgZm9yIGVhY2ggbW9kZXJhdG9yIHVzaW5nIFEtUSBwbG90cy4gRm9yIGFsbCBtb2RlcmF0b3JzLCB0aGUgZGF0YSBmZWxsIGFsb25nIG9yIGNsb3NlIHRvIHRoZSBsaW5lLiBUaGVyZWZvcmUsIGxpbmVhcml0eSB3YXMgbWV0IGZvciBhbGwgbW9kZXJhdG9ycy4KCmBgYHtyIHNob3cgbW9kX2NvbnRfcXFzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIG5vdGU6IHRoaXMgaXMgdGhlIHNhbWUgYWNyb3NzIHRoZSAyIElWIG9yZGVycyAoaS5lLiwgZGVzayBvciBvdXRzaWRlIGZpcnN0KQogIyBlYWNoIG1vZGVyYXRvcidzIHEtcSBwbG90IGNhbiBhbHNvIGJlIGZvdW5kIGluZGVwZW5kZW50bHkgdXNpbmc6ICJtb2RfU0FEX2RlcDEkZGF0YXNjcmVlbmluZyRsaW5lYXJpdHkiCmdyaWQuYXJyYW5nZShnZ3FxcGxvdChtb2RfU0FEX2RlcDEkbW9kZWwxJHJlc2lkdWFscywgdGl0bGUgPSAiUS1RIFBsb3QgZm9yIFxuRGVwZW5kZW5jZSIsIAogICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSAxLCBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpKSwKICAgICAgICAgICAgIGdncXFwbG90KG1vZF9TQURfZWExJG1vZGVsMSRyZXNpZHVhbHMsIHRpdGxlID0gIlEtUSBQbG90IGZvciBcbkVtb3Rpb25hbCBBdHRhY2htZW50IiwgCiAgICAgICAgICAgICAgICAgICAgICBzaGFwZSA9IDEsIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCkpLAogICAgICAgICAgICAgZ2dxcXBsb3QobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSRyZXNpZHVhbHMsIHRpdGxlID0gIlEtUSBQbG90IGZvciBcbkFjY2Vzc2liaWxpdHkiLCAKICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gMSwgZ2d0aGVtZSA9IHRoZW1lX2NsYXNzaWMoKSksCiAgICAgICAgICAgICBnZ3FxcGxvdChtb2RfU0FEX2Rpc3QxJG1vZGVsMSRyZXNpZHVhbHMsIHRpdGxlID0gIlEtUSBQbG90IGZvciBcbkRpc3RyYWN0aWJpbGl0eSIsIAogICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSAxLCBnZ3RoZW1lID0gdGhlbWVfY2xhc3NpYygpKSwKICAgICAgICAgICAgIGdncXFwbG90KG1vZF9TVVFfYWdlMSRtb2RlbDEkcmVzaWR1YWxzLCB0aXRsZSA9ICJRLVEgUGxvdCBmb3IgQWdlIiwgCiAgICAgICAgICAgICAgICAgICAgICBzaGFwZSA9IDEsIGdndGhlbWUgPSB0aGVtZV9jbGFzc2ljKCkpLAogICAgICAgICAgICAgIyBsYWJlbHMgPSBjKCJBIiwgIkIiLCAiQyIsICJEIiksCiAgICAgICAgICAgICBucm93ID0gMiwKICAgICAgICAgICAgIHRvcCA9IHRleHRfZ3JvYigiUS1RIFBsb3RzIEZvciBDb250aW51b3VzIE1vZGVyYXRvcnMiLCBmYWNlID0gImJvbGQiKQogICAgICAgICAgICAgKQpgYGAKCiMjIyMjIyAoMykgTm9ybWFsaXR5CgpOb3JtYWxpdHkgd2FzIGV2YWx1YXRlZCBmb3IgZWFjaCBtb2RlcmF0b3IgYnkgcGxvdHRpbmcgYSBoaXN0b2dyYW0gb2YgcmVzaWR1YWxzLiBGb3IgYWxsIG1vZGVyYXRvcnMsIHRoZSBkYXRhIGZlbGwgYWxvbmcgb3IgY2xvc2UgdG8gYSBub3JtYWwgY3VydmUuIFRoZXJlZm9yZSwgbm9ybWFsaXR5IHdhcyBtZXQgZm9yIGFsbCBtb2RlcmF0b3JzLgoKYGBge3Igc2hvdyBtb2RfY29udF9ub3JtcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBub3RlOiB0aGlzIGlzIHRoZSBzYW1lIGFjcm9zcyB0aGUgMiBJViBvcmRlcnMgKGkuZS4sIGRlc2sgb3Igb3V0c2lkZSBmaXJzdCkKICMgZWFjaCBtb2RlcmF0b3IncyBxLXEgcGxvdCBjYW4gYWxzbyBiZSBmb3VuZCBpbmRlcGVuZGVudGx5IHVzaW5nOiAibW9kX1NBRF9kZXAxJGRhdGFzY3JlZW5pbmckbm9ybWFsaXR5IgpncmlkLmFycmFuZ2UocXBsb3QobW9kX1NBRF9kZXAxJG1vZGVsMSRyZXNpZHVhbHMsIG1haW4gPSAiRGVwZW5kZW5jeSIsIHhsYWIgPSAiUmVzaWR1YWxzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBiaW53aWR0aCA9IDUpLAogICAgICAgICAgICAgcXBsb3QobW9kX1NBRF9lYTEkbW9kZWwxJHJlc2lkdWFscywgbWFpbiA9ICJFbW90aW9uYWwgQXR0YWNobWVudCIsIHhsYWIgPSAiUmVzaWR1YWxzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBiaW53aWR0aCA9IDUpLCAKICAgICAgICAgICAgIHFwbG90KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEkcmVzaWR1YWxzLCBtYWluID0gIkFjY2Vzc2liaWxpdHkiLCB4bGFiID0gIlJlc2lkdWFscyIsIHlsYWIgPSAiRnJlcXVlbmN5IiwgYmlud2lkdGggPSA1KSwgCiAgICAgICAgICAgICBxcGxvdChtb2RfU0FEX2Rpc3QxJG1vZGVsMSRyZXNpZHVhbHMsIG1haW4gPSAiRGlzdHJhY3RpYmlsaXR5IiwgeGxhYiA9ICJSZXNpZHVhbHMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGJpbndpZHRoID0gNSksIAogICAgICAgICAgICAgcXBsb3QobW9kX1NVUV9hZ2UxJG1vZGVsMSRyZXNpZHVhbHMsIG1haW4gPSAiQWdlIiwgeGxhYiA9ICJSZXNpZHVhbHMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGJpbndpZHRoID0gNSksCiAgICAgICAgICAgICAjIGxhYmVscyA9IGMoIkEiLCAiQiIsICJDIiwgIkQiKSwKICAgICAgICAgICAgIG5yb3cgPSAyLAogICAgICAgICAgICAgdG9wID0gdGV4dF9ncm9iKCJIaXN0b2dyYW0gb2YgUmVzaWR1YWxzIEZvciBDb250aW51b3VzIE1vZGVyYXRvcnMiLCBmYWNlID0gImJvbGQiKQogICAgICAgICAgICAgKQpgYGAKCiMjIyMjIyAoNCkgSG9tb2dlbmVpdHkgYW5kIEhvbW9zY2VkYXN0aWNpdHkKCkhvbW9nZW5laXR5IGFuZCBob21vc2NlZGFzdGljaXR5IHdlcmUgZXZhbHVhdGVkIGZvciBlYWNoIG1vZGVyYXRvciBieSBwbG90dGluZyBhIHNjYXR0ZXIgcGxvdCBvZiB0aGUgZml0dGVkIHZhbHVlcyB2cy4gcmVzaWR1YWxzLiBGb3IgYWxsIG1vZGVyYXRvcnMsIHRoZSBsaW5lIG9mIGJlc3QgZml0IHNob3dlZCBhbiBvdmVyYWxsIGxpbmVhciB0cmVuZC4gRXhjZXB0IGZvciBhZ2UsIGFsbCBtb2RlcmF0b3JzIHNob3dlZCBhIGdvb2QgZGlzdHJpYnV0aW9uIHRocm91Z2hvdXQgdGhlIHBsb3QuIFRoaXMgd2FzIG5vdCBzdXJwcmlzaW5nIHNpbmNlIHJlcG9ydGVkIGFnZSB3YXMgd2hvbGUtbnVtYmVycyBvbmx5IGFuZCB0aGUgc2FtcGxlIHNpemUgZGlkIG5vdCBjb3ZlciBhIGxhcmdlIGFnZSBkaXN0cmlidXRpb24uIFRoZXJlZm9yZSwgaG9tb2dlbmVpdHkgYW5kIGhvbW9zY2VkYXN0aWNpdHkgd2VyZSBtZXQgZm9yIGFsbCBtb2RlcmF0b3JzLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBub3RlOiB0aGlzIGlzIHRoZSBzYW1lIGFjcm9zcyB0aGUgMiBJViBvcmRlcnMgKGkuZS4sIGRlc2sgb3Igb3V0c2lkZSBmaXJzdCkKICMgZWFjaCBtb2RlcmF0b3IncyBxLXEgcGxvdCBjYW4gYWxzbyBiZSBmb3VuZCBpbmRlcGVuZGVudGx5IHVzaW5nOiAibW9kX1NBRF9kZXAxJGRhdGFzY3JlZW5pbmckbGluZWFyaXR5IgpncmlkLmFycmFuZ2UocXBsb3QoeCA9IG1vZF9TQURfZGVwMSRtb2RlbDEkZml0dGVkLnZhbHVlcywgeSA9IG1vZF9TQURfZGVwMSRtb2RlbDEkcmVzaWR1YWxzLCAKICAgICAgICAgICAgICAgICAgIG1haW4gPSAiRGVwZW5kZW5jeSIsIHhsYWIgPSAiRml0dGVkIiwgeWxhYiA9ICJSZXNpZHVhbHMiLCBnZW9tID0gInBvaW50IikgKyBnZW9tX3Ntb290aChzZSA9IEYpICsgdGhlbWVfY2xhc3NpYygpLAogICAgICAgICAgICAgcXBsb3QoeCA9IG1vZF9TQURfZWExJG1vZGVsMSRmaXR0ZWQudmFsdWVzLCB5ID0gbW9kX1NBRF9lYTEkbW9kZWwxJHJlc2lkdWFscywgCiAgICAgICAgICAgICAgICAgICBtYWluID0gIkVtb3Rpb25hbCBBdHRhY2htZW50IiwgeGxhYiA9ICJGaXR0ZWQiLCB5bGFiID0gIlJlc2lkdWFscyIsIGdlb20gPSAicG9pbnQiKSArIGdlb21fc21vb3RoKHNlID0gRikgKyB0aGVtZV9jbGFzc2ljKCksIAogICAgICAgICAgICAgcXBsb3QoeCA9IG1vZF9TQURfYWNjZXNzMSRtb2RlbDEkZml0dGVkLnZhbHVlcywgeSA9IG1vZF9TQURfYWNjZXNzMSRtb2RlbDEkcmVzaWR1YWxzLCAKICAgICAgICAgICAgICAgICAgIG1haW4gPSAiQWNjZXNzaWJpbGl0eSIsIHhsYWIgPSAiRml0dGVkIiwgeWxhYiA9ICJSZXNpZHVhbHMiLCBnZW9tID0gInBvaW50IikgKyBnZW9tX3Ntb290aChzZSA9IEYpICsgdGhlbWVfY2xhc3NpYygpLCAKICAgICAgICAgICAgIHFwbG90KHggPSBtb2RfU0FEX2Rpc3QxJG1vZGVsMSRmaXR0ZWQudmFsdWVzLCB5ID0gbW9kX1NBRF9kaXN0MSRtb2RlbDEkcmVzaWR1YWxzLCAKICAgICAgICAgICAgICAgICAgIG1haW4gPSAiRGlzdHJhY3RpYmlsaXR5IiwgeGxhYiA9ICJGaXR0ZWQiLCB5bGFiID0gIlJlc2lkdWFscyIsIGdlb20gPSAicG9pbnQiKSArIGdlb21fc21vb3RoKHNlID0gRikgKyB0aGVtZV9jbGFzc2ljKCksIAogICAgICAgICAgICAgcXBsb3QoeCA9IG1vZF9TVVFfYWdlMSRtb2RlbDEkZml0dGVkLnZhbHVlcywgeSA9IG1vZF9TVVFfYWdlMSRtb2RlbDEkcmVzaWR1YWxzLCAKICAgICAgICAgICAgICAgICAgIG1haW4gPSAiQWdlIiwgeGxhYiA9ICJGaXR0ZWQiLCB5bGFiID0gIlJlc2lkdWFscyIsIGdlb20gPSAicG9pbnQiKSArIGdlb21fc21vb3RoKHNlID0gRikgKyB0aGVtZV9jbGFzc2ljKCksCiAgICAgICAgICAgICAjIGxhYmVscyA9IGMoIkEiLCAiQiIsICJDIiwgIkQiKSwKICAgICAgICAgICAgIG5yb3cgPSAyLAogICAgICAgICAgICAgdG9wID0gdGV4dF9ncm9iKCJSZXNpZHVhbC1GaXR0ZWQgUGxvdCBGb3IgQ29udGludW91cyBNb2RlcmF0b3JzIiwgZmFjZSA9ICJib2xkIikKICAgICAgICAgICAgICkKYGBgCgo8L2RldGFpbHM+CgojIyMjIyBPdmVyYWxsIE1vZGVsCgpOb3cgdGhhdCBhc3N1bXB0aW9ucyB3ZXJlIGNoZWNrZWQgYW5kIG1ldCwgZWFjaCBtb2RlbCB3YXMgcmV2aWV3ZWQuIEZvciBlYWNoIG1vZGVyYXRvcidzIG1vZGVsIHNob3dlZDogYi12YWx1ZXMsIHNlLCB0LCBwLXZhbHVlLCBvdmVyIGFsbCBtb2RlbCBmaXQgKGkuZS4sIGYtdmFsdWUgd2l0aCBwLXZhbHVlKSwgYW5kICRSXnsyfSQuCgojIyMjIyMgRGVwZW5kZW5jZQoKRm9yIGRlcGVuZGVuY3kgdGhlIG1vZGVyYXRvciwgSVYsIGFuZCBpbnRlcmFjdGlvbnMgd2VyZSBub3Qgc2lnbmlmaWNhbnQuCgpgYGB7ciBjcmVhdGUmc2hvdyBtb2RfU0FEX2RlcF90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggbW9kZWwgdmFsdWVzIC0tIGFsbCB2YWx1ZXMgcm91bmRlZCB0byA1IGRlY2ltYWxzCiAgIyBub3RlOiB5b3UgY2FuIHNlZSBub24tZm9ybWF0dGVkIG1vZGVsIHN1bW1hcnkgdXNpbmcgInN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkiIG9yICJzdW1tYXJ5KG1vZF9TQURfZGVwMiRtb2RlbDEpIgptb2RfU0FEX2RlcF90IDwtIAogICMgYWRkIGIgZXN0aW1hdGUsIHNlLCB0LCBwCiAgcmJpbmQoZGF0YS5mcmFtZSgidmFyIiA9IGMoIkRlcGVuZGVuY2UiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIk91dHNpZGUgdnMuIFBvY2tldC9CYWciLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGVwIHggRHZQQiIsICJEZXAgeCBEdk8iLCAiRGVwIHggT3ZQQiIpLCAKICAgICAgICAgICAgICAgICAgICJiIiA9IHJvdW5kKGMobW9kX1NBRF9kZXAxJG1vZGVsMSRjb2VmZmljaWVudHNbMjo0XSwgbW9kX1NBRF9kZXAyJG1vZGVsMSRjb2VmZmljaWVudHNbM10sIG1vZF9TQURfZGVwMSRtb2RlbDEkY29lZmZpY2llbnRzWzU6Nl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZF9TQURfZGVwMiRtb2RlbDEkY29lZmZpY2llbnRzWzVdKSwgNSksIAogICAgICAgICAgICAgICAgICAgInNlIiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU0FEX2RlcDEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDJdLCBzdW1tYXJ5KG1vZF9TQURfZGVwMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6NiwyXSwgc3VtbWFyeShtb2RfU0FEX2RlcDIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwyXSksIDUpLCAKICAgICAgICAgICAgICAgICAgICJ0IiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU0FEX2RlcDEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDNdLCBzdW1tYXJ5KG1vZF9TQURfZGVwMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDNdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeShtb2RfU0FEX2RlcDEkbW9kZWwxKSRjb2VmZmljaWVudHNbNTo2LDNdLCBzdW1tYXJ5KG1vZF9TQURfZGVwMiRtb2RlbDEpJGNvZWZmaWNpZW50c1s1LDNdKSwgNSksCiAgICAgICAgICAgICAgICAgICAicCIgPSByb3VuZChjKHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCw0XSwgc3VtbWFyeShtb2RfU0FEX2RlcDIkbW9kZWwxKSRjb2VmZmljaWVudHNbMyw0XSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6Niw0XSwgc3VtbWFyeShtb2RfU0FEX2RlcDIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSw0XSksIDUpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAjIGFkZCBsYWJlbHMgZm9yOiBGLCBkZjEsIGRmMiwgcC12YWx1ZSwgYW5kIFJzcSB2YWx1ZXMKICAgICAgICBjKCIgIiwgImRmMSIsICJkZjIiLCAiRiIsICJwIiksIAogICAgICAgICMgYWRkIEYsIGRmMSwgZGYyLCBwLXZhbHVlLCBhbmQgUnNxIHZhbHVlcwogICAgICAgIGMoIk92ZXJhbGwgTW9kZWwgRml0Iiwgcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZGVwMSRtb2RlbDEpJGZzdGF0aXN0aWNbMl0sIHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkZnN0YXRpc3RpY1szXSwgc3VtbWFyeShtb2RfU0FEX2RlcDEkbW9kZWwxKSRmc3RhdGlzdGljWzFdLCAKICAgICAgICAgICAgICAgIHBmKHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkZnN0YXRpc3RpY1sxXSwgc3VtbWFyeShtb2RfU0FEX2RlcDEkbW9kZWwxKSRmc3RhdGlzdGljWzJdLCBzdW1tYXJ5KG1vZF9TQURfZGVwMSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sbG93ZXIudGFpbD1GQUxTRSkpLCA1KSksIAogICAgICAgICMgYWRkIFIgc3F1YXJlZCB2YWx1ZQogICAgICAgIGMoIlItc3F1YXJlZCIsIHJvdW5kKHN1bW1hcnkobW9kX1NBRF9kZXAxJG1vZGVsMSkkci5zcXVhcmVkLCA1KSwgcmVwKGMoIiIpLCAzKSkKICAgICAgICApCgojIHJlbmFtZSByb3dzCnJvd25hbWVzKG1vZF9TQURfZGVwX3QpIDwtIGMoMTo3LCAiICIsIDg6OSkKCiMgUHJpbnQgdGFibGUgdXNpbmcga2FibGUKa2FibGUobW9kX1NBRF9kZXBfdCwgY2FwdGlvbiA9ICJTdW1tYXJ5IG9mIG1vZGVyYXRpb24gYW5hbHlzaXMgd2l0aCBJVjogU21hcnRwaG9uZSBMb2NhdGlvbiBhbmQgTTogRGVwZW5kZW5jZS4iLCBhbGlnbiA9ICdyY2NjYycsIHJvdy5uYW1lcyA9IFQsIGNvbC5uYW1lcyA9IGMoIiAiLCAiYiIsICJTRSIsICJ0IiwgInAiKSkgJT4lCiAgIyBmb290bm90ZShnZW5lcmFsID0gIkludGVyYWN0aW9uIHZhcmlhYmxlcyAiKSAlPiUKICBwYWNrX3Jvd3MoIk1vZGVyYXRvciIsIDEsIDEpICU+JQogIHBhY2tfcm93cygiSVY6IFNtYXJ0cGhvbmUgTG9jYXRpb24iLCAyLCA0KSAlPiUKICBwYWNrX3Jvd3MoIkludGVyYWN0aW9uczogTW9kZXJhdG9yIHggSVYiLCA1LCA3KSAlPiUKICBwYWNrX3Jvd3MoIiAiLCA4LCAxMCwgaW5kZW50ID0gRikgJT4lCiAgcGFja19yb3dzKCJNb2RlbCIsIDgsIDEwKSAlPiUgCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGl0YWxpYyA9IFQpICU+JQogIHJvd19zcGVjKDgsIGJvbGQgPSBULCBpdGFsaWMgPSBUKSAlPiUKICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JQogIGthYmxlX2NsYXNzaWMoKQpgYGAKCiMjIyMjIyBFbW90aW9uYWwgQXR0YWNobWVudAoKRm9yIGVtb3Rpb25hbCBhdHRhY2htZW50IHRoZSBtb2RlcmF0b3Igd2FzIHNpZ25pZmljYW50LCB4eHh4eC4gSG93ZXZlciwgdGhlIElWLCBhbmQgaW50ZXJhY3Rpb25zIHdlcmUgbm90IHNpZ25pZmljYW50LgoKYGBge3IgY3JlYXRlJnNob3cgbW9kX1NBRF9lYV90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggbW9kZWwgdmFsdWVzIC0tIGFsbCB2YWx1ZXMgcm91bmRlZCB0byA1IGRlY2ltYWxzCiAgIyBub3RlOiB5b3UgY2FuIHNlZSBub24tZm9ybWF0dGVkIG1vZGVsIHN1bW1hcnkgdXNpbmcgInN1bW1hcnkobW9kX1NBRF9lYTEkbW9kZWwxKSIgb3IgInN1bW1hcnkobW9kX1NBRF9lYTIkbW9kZWwxKSIKbW9kX1NBRF9lYV90IDwtIAogICMgYWRkIGIgZXN0aW1hdGUsIHNlLCB0LCBwCiAgcmJpbmQoZGF0YS5mcmFtZSgidmFyIiA9IGMoIkVtb3Rpb25hbCBBdHRhY2htZW50IiwgIkRlc2sgdnMuIFBvY2tldC9CYWciLCAiRGVzayB2cy4gT3V0c2lkZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVBIHggRHZQQiIsICJFQSB4IER2TyIsICJFQSB4IE92UEIiKSwgCiAgICAgICAgICAgICAgICAgICAiYiIgPSByb3VuZChjKG1vZF9TQURfZWExJG1vZGVsMSRjb2VmZmljaWVudHNbMjo0XSwgbW9kX1NBRF9lYTIkbW9kZWwxJGNvZWZmaWNpZW50c1szXSwgbW9kX1NBRF9lYTEkbW9kZWwxJGNvZWZmaWNpZW50c1s1OjZdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2VhMiRtb2RlbDEkY29lZmZpY2llbnRzWzVdKSwgNSksIAogICAgICAgICAgICAgICAgICAgInNlIiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU0FEX2VhMSRtb2RlbDEpJGNvZWZmaWNpZW50c1syOjQsMl0sIHN1bW1hcnkobW9kX1NBRF9lYTIkbW9kZWwxKSRjb2VmZmljaWVudHNbMywyXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5KG1vZF9TQURfZWExJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6NiwyXSwgc3VtbWFyeShtb2RfU0FEX2VhMiRtb2RlbDEpJGNvZWZmaWNpZW50c1s1LDJdKSwgNSksIAogICAgICAgICAgICAgICAgICAgInQiID0gcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZWExJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCwzXSwgc3VtbWFyeShtb2RfU0FEX2VhMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDNdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeShtb2RfU0FEX2VhMSRtb2RlbDEpJGNvZWZmaWNpZW50c1s1OjYsM10sIHN1bW1hcnkobW9kX1NBRF9lYTIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwzXSksIDUpLAogICAgICAgICAgICAgICAgICAgInAiID0gcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZWExJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCw0XSwgc3VtbWFyeShtb2RfU0FEX2VhMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDRdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeShtb2RfU0FEX2VhMSRtb2RlbDEpJGNvZWZmaWNpZW50c1s1OjYsNF0sIHN1bW1hcnkobW9kX1NBRF9lYTIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSw0XSksIDUpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAjIGFkZCBsYWJlbHMgZm9yOiBGLCBkZjEsIGRmMiwgcC12YWx1ZSwgYW5kIFJzcSB2YWx1ZXMKICAgICAgICBjKCIgIiwgImRmMSIsICJkZjIiLCAiRiIsICJwIiksIAogICAgICAgICMgYWRkIEYsIGRmMSwgZGYyLCBwLXZhbHVlLCBhbmQgUnNxIHZhbHVlcwogICAgICAgIGMoIk92ZXJhbGwgTW9kZWwgRml0Iiwgcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZWExJG1vZGVsMSkkZnN0YXRpc3RpY1syXSwgc3VtbWFyeShtb2RfU0FEX2VhMSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sIHN1bW1hcnkobW9kX1NBRF9lYTEkbW9kZWwxKSRmc3RhdGlzdGljWzFdLCAKICAgICAgICAgICAgICAgIHBmKHN1bW1hcnkobW9kX1NBRF9lYTEkbW9kZWwxKSRmc3RhdGlzdGljWzFdLCBzdW1tYXJ5KG1vZF9TQURfZWExJG1vZGVsMSkkZnN0YXRpc3RpY1syXSwgc3VtbWFyeShtb2RfU0FEX2VhMSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sbG93ZXIudGFpbD1GQUxTRSkpLCA1KSksIAogICAgICAgICMgYWRkIFIgc3F1YXJlZCB2YWx1ZQogICAgICAgIGMoIlItc3F1YXJlZCIsIHJvdW5kKHN1bW1hcnkobW9kX1NBRF9lYTEkbW9kZWwxKSRyLnNxdWFyZWQsIDUpLCByZXAoYygiIiksIDMpKQogICAgICAgICkKCiMgcmVuYW1lIHJvd3MKcm93bmFtZXMobW9kX1NBRF9lYV90KSA8LSBjKDE6NywgIiAiLCA4OjkpCgojIFByaW50IHRhYmxlIHVzaW5nIGthYmxlCmthYmxlKG1vZF9TQURfZWFfdCwgY2FwdGlvbiA9ICJTdW1tYXJ5IG9mIG1vZGVyYXRpb24gYW5hbHlzaXMgd2l0aCBJVjogU21hcnRwaG9uZSBMb2NhdGlvbiBhbmQgTTogRW1vdGlvbmFsIEF0dGFjaG1lbnQuIiwgYWxpZ24gPSAncmNjY2MnLCByb3cubmFtZXMgPSBULCBjb2wubmFtZXMgPSBjKCIgIiwgImIiLCAiU0UiLCAidCIsICJwIikpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lCiAgcGFja19yb3dzKCJNb2RlcmF0b3IiLCAxLCAxKSAlPiUKICBwYWNrX3Jvd3MoIklWOiBTbWFydHBob25lIExvY2F0aW9uIiwgMiwgNCkgJT4lCiAgcGFja19yb3dzKCJJbnRlcmFjdGlvbnM6IE1vZGVyYXRvciB4IElWIiwgNSwgNykgJT4lCiAgcGFja19yb3dzKCIgIiwgOCwgMTAsIGluZGVudCA9IEYpICU+JQogIHBhY2tfcm93cygiTW9kZWwiLCA4LCAxMCkgJT4lIAogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBpdGFsaWMgPSBUKSAlPiUKICByb3dfc3BlYyg4LCBib2xkID0gVCwgaXRhbGljID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoMiwgYm9sZCA9IFQpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgoKIyMjIyMjIEFjY2Vzc2liaWxpdHkKCkZvciBhY2Nlc3NpYmlsaXR5IHRoZSBtb2RlcmF0b3IsIElWLCBhbmQgaW50ZXJhY3Rpb25zIHdlcmUgbm90IHNpZ25pZmljYW50LgoKYGBge3IgY3JlYXRlJnNob3cgbW9kX1NBRF9hY2Nlc3NfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjcmVhdGUgZGF0YSBmcmFtZSB3aXRoIG1vZGVsIHZhbHVlcyAtLSBhbGwgdmFsdWVzIHJvdW5kZWQgdG8gNSBkZWNpbWFscwogICMgbm90ZTogeW91IGNhbiBzZWUgbm9uLWZvcm1hdHRlZCBtb2RlbCBzdW1tYXJ5IHVzaW5nICJzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpIiBvciAic3VtbWFyeShtb2RfU0FEX2FjY2VzczIkbW9kZWwxKSIKbW9kX1NBRF9hY2Nlc3NfdCA8LSAKICAjIGFkZCBiIGVzdGltYXRlLCBzZSwgdCwgcAogIHJiaW5kKGRhdGEuZnJhbWUoInZhciIgPSBjKCJBY2Nlc3NpYmlsaXR5IiwgIkRlc2sgdnMuIFBvY2tldC9CYWciLCAiRGVzayB2cy4gT3V0c2lkZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFjY2VzcyB4IER2UEIiLCAiQWNjZXNzIHggRHZPIiwgIkFjY2VzcyB4IE92UEIiKSwgCiAgICAgICAgICAgICAgICAgICAiYiIgPSByb3VuZChjKG1vZF9TQURfYWNjZXNzMSRtb2RlbDEkY29lZmZpY2llbnRzWzI6NF0sIG1vZF9TQURfYWNjZXNzMiRtb2RlbDEkY29lZmZpY2llbnRzWzNdLCBtb2RfU0FEX2FjY2VzczEkbW9kZWwxJGNvZWZmaWNpZW50c1s1OjZdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2FjY2VzczIkbW9kZWwxJGNvZWZmaWNpZW50c1s1XSksIDUpLCAKICAgICAgICAgICAgICAgICAgICJzZSIgPSByb3VuZChjKHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCwyXSwgc3VtbWFyeShtb2RfU0FEX2FjY2VzczIkbW9kZWwxKSRjb2VmZmljaWVudHNbMywyXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJGNvZWZmaWNpZW50c1s1OjYsMl0sIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MyJG1vZGVsMSkkY29lZmZpY2llbnRzWzUsMl0pLCA1KSwgCiAgICAgICAgICAgICAgICAgICAidCIgPSByb3VuZChjKHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCwzXSwgc3VtbWFyeShtb2RfU0FEX2FjY2VzczIkbW9kZWwxKSRjb2VmZmljaWVudHNbMywzXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6NiwzXSwgc3VtbWFyeShtb2RfU0FEX2FjY2VzczIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwzXSksIDUpLAogICAgICAgICAgICAgICAgICAgInAiID0gcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJGNvZWZmaWNpZW50c1syOjQsNF0sIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MyJG1vZGVsMSkkY29lZmZpY2llbnRzWzMsNF0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJGNvZWZmaWNpZW50c1s1OjYsNF0sIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MyJG1vZGVsMSkkY29lZmZpY2llbnRzWzUsNF0pLCA1KQogICAgICAgICAgICAgICAgICAgICAgICAgKSwgCiAgICAgICAgIyBhZGQgbGFiZWxzIGZvcjogRiwgZGYxLCBkZjIsIHAtdmFsdWUsIGFuZCBSc3EgdmFsdWVzCiAgICAgICAgYygiICIsICJkZjEiLCAiZGYyIiwgIkYiLCAicCIpLCAKICAgICAgICAjIGFkZCBGLCBkZjEsIGRmMiwgcC12YWx1ZSwgYW5kIFJzcSB2YWx1ZXMKICAgICAgICBjKCJPdmVyYWxsIE1vZGVsIEZpdCIsIHJvdW5kKGMoc3VtbWFyeShtb2RfU0FEX2FjY2VzczEkbW9kZWwxKSRmc3RhdGlzdGljWzJdLCBzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSkkZnN0YXRpc3RpY1sxXSwgCiAgICAgICAgICAgICAgICBwZihzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJGZzdGF0aXN0aWNbMV0sIHN1bW1hcnkobW9kX1NBRF9hY2Nlc3MxJG1vZGVsMSkkZnN0YXRpc3RpY1syXSwgc3VtbWFyeShtb2RfU0FEX2FjY2VzczEkbW9kZWwxKSRmc3RhdGlzdGljWzNdLGxvd2VyLnRhaWw9RkFMU0UpKSwgNSkpLCAKICAgICAgICAjIGFkZCBSIHNxdWFyZWQgdmFsdWUKICAgICAgICBjKCJSLXNxdWFyZWQiLCByb3VuZChzdW1tYXJ5KG1vZF9TQURfYWNjZXNzMSRtb2RlbDEpJHIuc3F1YXJlZCwgNSksIHJlcChjKCIiKSwgMykpCiAgICAgICAgKQoKIyByZW5hbWUgcm93cwpyb3duYW1lcyhtb2RfU0FEX2FjY2Vzc190KSA8LSBjKDE6NywgIiAiLCA4OjkpCgojIFByaW50IHRhYmxlIHVzaW5nIGthYmxlCmthYmxlKG1vZF9TQURfYWNjZXNzX3QsIGNhcHRpb24gPSAiU3VtbWFyeSBvZiBtb2RlcmF0aW9uIGFuYWx5c2lzIHdpdGggSVY6IFNtYXJ0cGhvbmUgTG9jYXRpb24gYW5kIE06IEFjY2Vzc2liaWxpdHkiLCBhbGlnbiA9ICdyY2NjYycsIHJvdy5uYW1lcyA9IFQsIGNvbC5uYW1lcyA9IGMoIiAiLCAiYiIsICJTRSIsICJ0IiwgInAiKSkgJT4lCiAgIyBmb290bm90ZShnZW5lcmFsID0gIkludGVyYWN0aW9uIHZhcmlhYmxlcyAiKSAlPiUKICBwYWNrX3Jvd3MoIk1vZGVyYXRvciIsIDEsIDEpICU+JQogIHBhY2tfcm93cygiSVY6IFNtYXJ0cGhvbmUgTG9jYXRpb24iLCAyLCA0KSAlPiUKICBwYWNrX3Jvd3MoIkludGVyYWN0aW9uczogTW9kZXJhdG9yIHggSVYiLCA1LCA3KSAlPiUKICBwYWNrX3Jvd3MoIiAiLCA4LCAxMCwgaW5kZW50ID0gRikgJT4lCiAgcGFja19yb3dzKCJNb2RlbCIsIDgsIDEwKSAlPiUgCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGl0YWxpYyA9IFQpICU+JQogIHJvd19zcGVjKDgsIGJvbGQgPSBULCBpdGFsaWMgPSBUKSAlPiUKICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpICU+JQogIGthYmxlX2NsYXNzaWMoKQpgYGAKCgojIyMjIyMgRGlzdHJhY3RpYmlsaXR5CgpGb3IgZGlzdHJhY3RpYmlsaXR5IHRoZSBtb2RlcmF0b3IsIElWLCBhbmQgaW50ZXJhY3Rpb25zIHdlcmUgbm90IHNpZ25pZmljYW50LgoKYGBge3IgY3JlYXRlJnNob3cgbW9kX1NBRF9kaXN0X3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCBtb2RlbCB2YWx1ZXMgLS0gYWxsIHZhbHVlcyByb3VuZGVkIHRvIDUgZGVjaW1hbHMKICAjIG5vdGU6IHlvdSBjYW4gc2VlIG5vbi1mb3JtYXR0ZWQgbW9kZWwgc3VtbWFyeSB1c2luZyAic3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkiIG9yICJzdW1tYXJ5KG1vZF9TQURfZGlzdDIkbW9kZWwxKSIKbW9kX1NBRF9kaXN0X3QgPC0gCiAgIyBhZGQgYiBlc3RpbWF0ZSwgc2UsIHQsIHAKICByYmluZChkYXRhLmZyYW1lKCJ2YXIiID0gYygiRGlzdHJhY3RpYmlsaXR5IiwgIkRlc2sgdnMuIFBvY2tldC9CYWciLCAiRGVzayB2cy4gT3V0c2lkZSIsICJPdXRzaWRlIHZzLiBQb2NrZXQvQmFnIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpc3QgeCBEdlBCIiwgIkRpc3QgeCBEdk8iLCAiRGlzdCB4IE92UEIiKSwgCiAgICAgICAgICAgICAgICAgICAiYiIgPSByb3VuZChjKG1vZF9TQURfZGlzdDEkbW9kZWwxJGNvZWZmaWNpZW50c1syOjRdLCBtb2RfU0FEX2Rpc3QyJG1vZGVsMSRjb2VmZmljaWVudHNbM10sIG1vZF9TQURfZGlzdDEkbW9kZWwxJGNvZWZmaWNpZW50c1s1OjZdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RfU0FEX2Rpc3QyJG1vZGVsMSRjb2VmZmljaWVudHNbNV0pLCA1KSwgCiAgICAgICAgICAgICAgICAgICAic2UiID0gcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZGlzdDEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDJdLCBzdW1tYXJ5KG1vZF9TQURfZGlzdDIkbW9kZWwxKSRjb2VmZmljaWVudHNbMywyXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5KG1vZF9TQURfZGlzdDEkbW9kZWwxKSRjb2VmZmljaWVudHNbNTo2LDJdLCBzdW1tYXJ5KG1vZF9TQURfZGlzdDIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwyXSksIDUpLCAKICAgICAgICAgICAgICAgICAgICJ0IiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCwzXSwgc3VtbWFyeShtb2RfU0FEX2Rpc3QyJG1vZGVsMSkkY29lZmZpY2llbnRzWzMsM10sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5KG1vZF9TQURfZGlzdDEkbW9kZWwxKSRjb2VmZmljaWVudHNbNTo2LDNdLCBzdW1tYXJ5KG1vZF9TQURfZGlzdDIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwzXSksIDUpLAogICAgICAgICAgICAgICAgICAgInAiID0gcm91bmQoYyhzdW1tYXJ5KG1vZF9TQURfZGlzdDEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDRdLCBzdW1tYXJ5KG1vZF9TQURfZGlzdDIkbW9kZWwxKSRjb2VmZmljaWVudHNbMyw0XSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NBRF9kaXN0MSRtb2RlbDEpJGNvZWZmaWNpZW50c1s1OjYsNF0sIHN1bW1hcnkobW9kX1NBRF9kaXN0MiRtb2RlbDEpJGNvZWZmaWNpZW50c1s1LDRdKSwgNSkKICAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICMgYWRkIGxhYmVscyBmb3I6IEYsIGRmMSwgZGYyLCBwLXZhbHVlLCBhbmQgUnNxIHZhbHVlcwogICAgICAgIGMoIiAiLCAiZGYxIiwgImRmMiIsICJGIiwgInAiKSwgCiAgICAgICAgIyBhZGQgRiwgZGYxLCBkZjIsIHAtdmFsdWUsIGFuZCBSc3EgdmFsdWVzCiAgICAgICAgYygiT3ZlcmFsbCBNb2RlbCBGaXQiLCByb3VuZChjKHN1bW1hcnkobW9kX1NBRF9kaXN0MSRtb2RlbDEpJGZzdGF0aXN0aWNbMl0sIHN1bW1hcnkobW9kX1NBRF9kaXN0MSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sIHN1bW1hcnkobW9kX1NBRF9kaXN0MSRtb2RlbDEpJGZzdGF0aXN0aWNbMV0sIAogICAgICAgICAgICAgICAgcGYoc3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkkZnN0YXRpc3RpY1sxXSwgc3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkkZnN0YXRpc3RpY1syXSwgc3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkkZnN0YXRpc3RpY1szXSxsb3dlci50YWlsPUZBTFNFKSksIDUpKSwgCiAgICAgICAgIyBhZGQgUiBzcXVhcmVkIHZhbHVlCiAgICAgICAgYygiUi1zcXVhcmVkIiwgcm91bmQoc3VtbWFyeShtb2RfU0FEX2Rpc3QxJG1vZGVsMSkkci5zcXVhcmVkLCA1KSwgcmVwKGMoIiIpLCAzKSkKICAgICAgICApCgojIHJlbmFtZSByb3dzCnJvd25hbWVzKG1vZF9TQURfZGlzdF90KSA8LSBjKDE6NywgIiAiLCA4OjkpCgojIFByaW50IHRhYmxlIHVzaW5nIGthYmxlCmthYmxlKG1vZF9TQURfZGlzdF90LCBjYXB0aW9uID0gIlN1bW1hcnkgb2YgbW9kZXJhdGlvbiBhbmFseXNpcyB3aXRoIElWOiBTbWFydHBob25lIExvY2F0aW9uIGFuZCBNOiBEaXN0cmFjdGliaWxpdHkuIiwgYWxpZ24gPSAncmNjY2MnLCByb3cubmFtZXMgPSBULCBjb2wubmFtZXMgPSBjKCIgIiwgImIiLCAiU0UiLCAidCIsICJwIikpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lCiAgcGFja19yb3dzKCJNb2RlcmF0b3IiLCAxLCAxKSAlPiUKICBwYWNrX3Jvd3MoIklWOiBTbWFydHBob25lIExvY2F0aW9uIiwgMiwgNCkgJT4lCiAgcGFja19yb3dzKCJJbnRlcmFjdGlvbnM6IE1vZGVyYXRvciB4IElWIiwgNSwgNykgJT4lCiAgcGFja19yb3dzKCIgIiwgOCwgMTAsIGluZGVudCA9IEYpICU+JQogIHBhY2tfcm93cygiTW9kZWwiLCA4LCAxMCkgJT4lIAogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBpdGFsaWMgPSBUKSAlPiUKICByb3dfc3BlYyg4LCBib2xkID0gVCwgaXRhbGljID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoMiwgYm9sZCA9IFQpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgojIyMjIyMgQWdlCgpGb3IgYWdlIHRoZSBtb2RlcmF0b3IsIElWLCBhbmQgaW50ZXJhY3Rpb25zIHdlcmUgbm90IHNpZ25pZmljYW50LgoKYGBge3IgY3JlYXRlJnNob3cgbW9kX1NVUV9hZ2VfdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjcmVhdGUgZGF0YSBmcmFtZSB3aXRoIG1vZGVsIHZhbHVlcyAtLSBhbGwgdmFsdWVzIHJvdW5kZWQgdG8gNSBkZWNpbWFscwogICMgbm90ZTogeW91IGNhbiBzZWUgbm9uLWZvcm1hdHRlZCBtb2RlbCBzdW1tYXJ5IHVzaW5nICJzdW1tYXJ5KG1vZF9TVVFfYWdlMSRtb2RlbDEpIiBvciAic3VtbWFyeShtb2RfU1VRX2FnZTIkbW9kZWwxKSIKbW9kX1NVUV9hZ2VfdCA8LSAKICAjIGFkZCBiIGVzdGltYXRlLCBzZSwgdCwgcAogIHJiaW5kKGRhdGEuZnJhbWUoInZhciIgPSBjKCJBZ2UiLCAiRGVzayB2cy4gUG9ja2V0L0JhZyIsICJEZXNrIHZzLiBPdXRzaWRlIiwgIk91dHNpZGUgdnMuIFBvY2tldC9CYWciLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWdlIHggRHZQQiIsICJBZ2UgeCBEdk8iLCAiQWdlIHggT3ZQQiIpLCAKICAgICAgICAgICAgICAgICAgICJiIiA9IHJvdW5kKGMobW9kX1NVUV9hZ2UxJG1vZGVsMSRjb2VmZmljaWVudHNbMjo0XSwgbW9kX1NVUV9hZ2UyJG1vZGVsMSRjb2VmZmljaWVudHNbM10sIG1vZF9TVVFfYWdlMSRtb2RlbDEkY29lZmZpY2llbnRzWzU6Nl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZF9TVVFfYWdlMiRtb2RlbDEkY29lZmZpY2llbnRzWzVdKSwgNSksIAogICAgICAgICAgICAgICAgICAgInNlIiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU1VRX2FnZTEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDJdLCBzdW1tYXJ5KG1vZF9TVVFfYWdlMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6NiwyXSwgc3VtbWFyeShtb2RfU1VRX2FnZTIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSwyXSksIDUpLCAKICAgICAgICAgICAgICAgICAgICJ0IiA9IHJvdW5kKGMoc3VtbWFyeShtb2RfU1VRX2FnZTEkbW9kZWwxKSRjb2VmZmljaWVudHNbMjo0LDNdLCBzdW1tYXJ5KG1vZF9TVVFfYWdlMiRtb2RlbDEpJGNvZWZmaWNpZW50c1szLDNdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeShtb2RfU1VRX2FnZTEkbW9kZWwxKSRjb2VmZmljaWVudHNbNTo2LDNdLCBzdW1tYXJ5KG1vZF9TVVFfYWdlMiRtb2RlbDEpJGNvZWZmaWNpZW50c1s1LDNdKSwgNSksCiAgICAgICAgICAgICAgICAgICAicCIgPSByb3VuZChjKHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkY29lZmZpY2llbnRzWzI6NCw0XSwgc3VtbWFyeShtb2RfU1VRX2FnZTIkbW9kZWwxKSRjb2VmZmljaWVudHNbMyw0XSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkY29lZmZpY2llbnRzWzU6Niw0XSwgc3VtbWFyeShtb2RfU1VRX2FnZTIkbW9kZWwxKSRjb2VmZmljaWVudHNbNSw0XSksIDUpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAjIGFkZCBsYWJlbHMgZm9yOiBGLCBkZjEsIGRmMiwgcC12YWx1ZSwgYW5kIFJzcSB2YWx1ZXMKICAgICAgICBjKCIgIiwgImRmMSIsICJkZjIiLCAiRiIsICJwIiksIAogICAgICAgICMgYWRkIEYsIGRmMSwgZGYyLCBwLXZhbHVlLCBhbmQgUnNxIHZhbHVlcwogICAgICAgIGMoIk92ZXJhbGwgTW9kZWwgRml0Iiwgcm91bmQoYyhzdW1tYXJ5KG1vZF9TVVFfYWdlMSRtb2RlbDEpJGZzdGF0aXN0aWNbMl0sIHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkZnN0YXRpc3RpY1szXSwgc3VtbWFyeShtb2RfU1VRX2FnZTEkbW9kZWwxKSRmc3RhdGlzdGljWzFdLCAKICAgICAgICAgICAgICAgIHBmKHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkZnN0YXRpc3RpY1sxXSwgc3VtbWFyeShtb2RfU1VRX2FnZTEkbW9kZWwxKSRmc3RhdGlzdGljWzJdLCBzdW1tYXJ5KG1vZF9TVVFfYWdlMSRtb2RlbDEpJGZzdGF0aXN0aWNbM10sbG93ZXIudGFpbD1GQUxTRSkpLCA1KSksIAogICAgICAgICMgYWRkIFIgc3F1YXJlZCB2YWx1ZQogICAgICAgIGMoIlItc3F1YXJlZCIsIHJvdW5kKHN1bW1hcnkobW9kX1NVUV9hZ2UxJG1vZGVsMSkkci5zcXVhcmVkLCA1KSwgcmVwKGMoIiIpLCAzKSkKICAgICAgICApCgojIHJlbmFtZSByb3dzCnJvd25hbWVzKG1vZF9TVVFfYWdlX3QpIDwtIGMoMTo3LCAiICIsIDg6OSkKCiMgUHJpbnQgdGFibGUgdXNpbmcga2FibGUKa2FibGUobW9kX1NVUV9hZ2VfdCwgY2FwdGlvbiA9ICJTdW1tYXJ5IG9mIG1vZGVyYXRpb24gYW5hbHlzaXMgd2l0aCBJVjogU21hcnRwaG9uZSBMb2NhdGlvbiBhbmQgTTogQWdlIiwgYWxpZ24gPSAncmNjY2MnLCByb3cubmFtZXMgPSBULCBjb2wubmFtZXMgPSBjKCIgIiwgImIiLCAiU0UiLCAidCIsICJwIikpICU+JQogICMgZm9vdG5vdGUoZ2VuZXJhbCA9ICJJbnRlcmFjdGlvbiB2YXJpYWJsZXMgIikgJT4lCiAgcGFja19yb3dzKCJNb2RlcmF0b3IiLCAxLCAxKSAlPiUKICBwYWNrX3Jvd3MoIklWOiBTbWFydHBob25lIExvY2F0aW9uIiwgMiwgNCkgJT4lCiAgcGFja19yb3dzKCJJbnRlcmFjdGlvbnM6IE1vZGVyYXRvciB4IElWIiwgNSwgNykgJT4lCiAgcGFja19yb3dzKCIgIiwgOCwgMTAsIGluZGVudCA9IEYpICU+JQogIHBhY2tfcm93cygiTW9kZWwiLCA4LCAxMCkgJT4lIAogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBpdGFsaWMgPSBUKSAlPiUKICByb3dfc3BlYyg4LCBib2xkID0gVCwgaXRhbGljID0gVCkgJT4lCiAgY29sdW1uX3NwZWMoMiwgYm9sZCA9IFQpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsICJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICBrYWJsZV9jbGFzc2ljKCkKYGBgCgojIyMjIyBTaW1wbGUgU2xvcGVzCgojIyMjIyMgRGVwZW5kZW5jZQoKPGRldGFpbHM+CjxzdW1tYXJ5PiBDbGljayB0byBzZWUgb3V0cHV0IGZvciBzaW1wbGUgc2xvcGVzLCBpbmNsdWRpbmcgZ2VuZXJhdGVkIGludGVycHJldGF0aW9ucy4gPC9zdW1tYXJ5PgpgYGB7cn0KIyBzdW1tYXJ5IG9mIFNTCmxhcHBseShtb2RfU0FEX2RlcDEkc2xvcGVtb2RlbHMsIHN1bW1hcnkpCmxhcHBseShtb2RfU0FEX2RlcDIkc2xvcGVtb2RlbHMsIHN1bW1hcnkpCgojIGdlbmVyYXRlZCBpbnRlcnByZXRhdGlvbnMKY2F0KG1vZF9TQURfZGVwMSRpbnRlcnByZXRhdGlvbikKY2F0KG1vZF9TQURfZGVwMiRpbnRlcnByZXRhdGlvbikKYGBgCjwvZGV0YWlscz4gCgojIyMjIyMgRW1vdGlvbmFsIEF0dGFjaG1lbnQKCjxkZXRhaWxzPgo8c3VtbWFyeT4gQ2xpY2sgdG8gc2VlIG91dHB1dCBmb3Igc2ltcGxlIHNsb3BlcywgaW5jbHVkaW5nIGdlbmVyYXRlZCBpbnRlcnByZXRhdGlvbnMuIDwvc3VtbWFyeT4KYGBge3J9CiMgc3VtbWFyeSBvZiBTUwpsYXBwbHkobW9kX1NBRF9lYTEkc2xvcGVtb2RlbHMsIHN1bW1hcnkpCmxhcHBseShtb2RfU0FEX2VhMiRzbG9wZW1vZGVscywgc3VtbWFyeSkKCiMgZ2VuZXJhdGVkIGludGVycHJldGF0aW9ucwpjYXQobW9kX1NBRF9lYTEkaW50ZXJwcmV0YXRpb24pCmNhdChtb2RfU0FEX2VhMiRpbnRlcnByZXRhdGlvbikKYGBgCjwvZGV0YWlscz4gCgojIyMjIyMgQWNjZXNzaWJpbGl0eSAKCjxkZXRhaWxzPgo8c3VtbWFyeT4gQ2xpY2sgdG8gc2VlIG91dHB1dCBmb3Igc2ltcGxlIHNsb3BlcywgaW5jbHVkaW5nIGdlbmVyYXRlZCBpbnRlcnByZXRhdGlvbnMuIDwvc3VtbWFyeT4KYGBge3J9CiMgc3VtbWFyeSBvZiBTUwpsYXBwbHkobW9kX1NBRF9hY2Nlc3MxJHNsb3BlbW9kZWxzLCBzdW1tYXJ5KQpsYXBwbHkobW9kX1NBRF9hY2Nlc3MyJHNsb3BlbW9kZWxzLCBzdW1tYXJ5KQoKIyBnZW5lcmF0ZWQgaW50ZXJwcmV0YXRpb25zCmNhdChtb2RfU0FEX2FjY2VzczEkaW50ZXJwcmV0YXRpb24pCmNhdChtb2RfU0FEX2FjY2VzczIkaW50ZXJwcmV0YXRpb24pCmBgYAo8L2RldGFpbHM+CgoKIyMjIyMjIERpc3RyYWN0aWJpbGl0eQoKPGRldGFpbHM+CjxzdW1tYXJ5PiBDbGljayB0byBzZWUgb3V0cHV0IGZvciBzaW1wbGUgc2xvcGVzLCBpbmNsdWRpbmcgZ2VuZXJhdGVkIGludGVycHJldGF0aW9ucy4gPC9zdW1tYXJ5PgpgYGB7cn0KIyBzdW1tYXJ5IG9mIFNTCmxhcHBseShtb2RfU0FEX2Rpc3QxJHNsb3BlbW9kZWxzLCBzdW1tYXJ5KQpsYXBwbHkobW9kX1NBRF9kaXN0MiRzbG9wZW1vZGVscywgc3VtbWFyeSkKCiMgZ2VuZXJhdGVkIGludGVycHJldGF0aW9ucwpjYXQobW9kX1NBRF9kaXN0MSRpbnRlcnByZXRhdGlvbikKY2F0KG1vZF9TQURfZGlzdDIkaW50ZXJwcmV0YXRpb24pCmBgYAo8L2RldGFpbHM+CgojIyMjIyMgQWdlCgo8ZGV0YWlscz4KPHN1bW1hcnk+IENsaWNrIHRvIHNlZSBvdXRwdXQgZm9yIHNpbXBsZSBzbG9wZXMsIGluY2x1ZGluZyBnZW5lcmF0ZWQgaW50ZXJwcmV0YXRpb25zLiA8L3N1bW1hcnk+CmBgYHtyfQojIHN1bW1hcnkgb2YgU1MKbGFwcGx5KG1vZF9TVVFfYWdlMSRzbG9wZW1vZGVscywgc3VtbWFyeSkKbGFwcGx5KG1vZF9TVVFfYWdlMiRzbG9wZW1vZGVscywgc3VtbWFyeSkKCiMgZ2VuZXJhdGVkIGludGVycHJldGF0aW9ucwpjYXQobW9kX1NVUV9hZ2UxJGludGVycHJldGF0aW9uKQpjYXQobW9kX1NVUV9hZ2UyJGludGVycHJldGF0aW9uKQpgYGAKPC9kZXRhaWxzPiAKCiMjIyMjIFZpc3VhbGl6YXRpb25zCgpUaGUgdmlzdWFsaXphdGlvbnMgYmVsb3cgYXJlIHByZXNlbnRlZCBlaXRoZXIgaW4gcGFuZWwgZm9ybSAoaS5lLiwgd2l0aCBhbGwgcGxvdHMgcHJlc2VudGVkIHRvZ2V0aGVyKSBvciBzZXBhcmF0ZS4KCiMjIyMjIyBTZXBhcmF0ZQoqKkRlcGVuZGVuY2UqKiB3YXMgKipub3QqKiBhIHNpZ25pZmljYW50IG1vZGVyYXRvciBmb3IgT1NwYW4gYWJzb2x1dGUgc2NvcmUuIE5vIG5vdGFibGUgdHJlbmRzIGluIHRoZSBkYXRhIHdlcmUgb2JzZXJ2ZWQuCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TQURfZGVwX2JhciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9Cm1vZF9TQURfZGVwX2Jhcl9kYXRhIDwtIAogIG1vZF9TQURfZGVwMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhICU+JSAKICAjIHJlbW92ZSByb3dzIHcvIG91dGxpZXIgcHMKICBmaWx0ZXIodG90YWxvdXQgIT0gMikgJT4lIAogICMgc2VsZWN0IHRoZSBkYXRhIHdlIHdhbnQ6IElWLCBEViwgTQogIHNlbGVjdChvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgU0FEX2RlcF9zY29yZSwgbG9jYXRpb25fZGVzaykgJT4lIAogICMgcmVwbGFjZSBtb2RlcmF0b3Igc2NvcmUgd2l0aCBtZWFuLWNlbnRlcmVkCiAgbXV0YXRlKFNBRF9kZXBfc2NvcmUgPSBjKHNjYWxlKFNBRF9kZXBfc2NvcmUsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpKSkKCm1vZF9TQURfZGVwX2JhciA8LSBnZ3Bsb3QobW9kX1NBRF9kZXBfYmFyX2RhdGEsIGFlcyh4ID0gU0FEX2RlcF9zY29yZSwgeSA9IG9zcGFuX2Fic29sdXRlX3Njb3JlLCBjb2xvciA9IGxvY2F0aW9uX2Rlc2spKSArCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtLCBhZXMoZmlsbCA9IGxvY2F0aW9uX2Rlc2spKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhtaW4obW9kX1NBRF9kZXBfYmFyX2RhdGEkU0FEX2RlcF9zY29yZSksIG1heChtb2RfU0FEX2RlcF9iYXJfZGF0YSRTQURfZGVwX3Njb3JlKSksIAogICAgICAgICAgICAgICAgICB5bGltID0gYyhtaW4obW9kX1NBRF9kZXBfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpLCBtYXgobW9kX1NBRF9kZXBfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpKSkgKwogIGxhYnModGl0bGUgPSAiTW9kZXJhdGluZyBPU3BhbiBBYnNvbHV0ZSBTY29yZSB3aXRoIERlcGVuZGVuY2UiLCAKICAgICAgIHggPSAiRGVwZW5kZW5jZSIsIAogICAgICAgeSA9ICJPU3BhbiBBYnNvbHV0ZSBTY29yZSIsIAogICAgICAgY29sb3IgPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsCiAgICAgICBmaWxsID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLAogICAgICAgY2FwdGlvbiA9ICJOb3RlOiBTbWFydHBob25lIGRlcGVuZGVuY3kgaXMgbWVhbi1jZW50ZXJlZC4iCiAgICAgICApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHNlYWdyZWVuIiwgInB1cnBsZTMiLCAiZGVlcHNreWJsdWU0IikpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImxpZ2h0c2VhZ3JlZW4iLCAicHVycGxlNCIsICJkZWVwc2t5Ymx1ZTQiKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKI3Nob3cgZmlnCm1vZF9TQURfZGVwX2JhcgoKIyBleHBvcnQgcGxvdAojIGdnc2F2ZShmaWxlbmFtZT0iZmlnX21vZF9TQURfZGVwX2Jhcl9qdW5lMTQiLCBwbG90ID0gbW9kX1NBRF9kZXBfYmFyLCBkZXZpY2UgPSAicG5nIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDUwMCkKYGBgCgoqKkVtb3Rpb25hbCBBdHRhY2htZW50Kiogd2FzICoqbm90KiogYSBzaWduaWZpY2FudCBtb2RlcmF0b3IgZm9yIE9TcGFuIGFic29sdXRlIHNjb3JlLiBBIG5vdGFibGUgdHJlbmQgaW4gdGhlIGRhdGEgd2FzIG9ic2VydmVkLCB3aGVyZSBwYXJ0aWNpcGFudHMgd2l0aCBsZXNzIGVtb3Rpb25hbCBhdHRhY2htZW50IHNob3dlZCBiZXR0ZXIgT1NwYW4gcGVyZm9ybWFuY2UgaW4gdGhlIG9uIGRlc2sgY29uZGl0aW9uLiBUaGUgb3V0c2lkZSBjb25kaXRpb24gc2hvd2VkIHRoZSBzYW1lIGJ1dCBzbWFsbGVyIHRybmVkLiBUaGUgcG9ja2V0L2JhZyBjb25kaXRpb24gZGlkIG5vdCBzaG93IHRoaXMgdHJlbmQgYXMgdGhlIHNsb3BlIHdlcmUgY2xvc2VyIHRvIHplcm8uCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TQURfZWFfYmFyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KbW9kX1NBRF9lYV9iYXJfZGF0YSA8LSAKICBtb2RfU0FEX2VhMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhICU+JSAKICAjIHJlbW92ZSByb3dzIHcvIG91dGxpZXIgcHMKICBmaWx0ZXIodG90YWxvdXQgIT0gMikgJT4lIAogICMgc2VsZWN0IHRoZSBkYXRhIHdlIHdhbnQ6IElWLCBEViwgTQogIHNlbGVjdChvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgU0FEX2VhX3Njb3JlLCBsb2NhdGlvbl9kZXNrKSAlPiUgCiAgIyByZXBsYWNlIG1vZGVyYXRvciBzY29yZSB3aXRoIG1lYW4tY2VudGVyZWQKICBtdXRhdGUoU0FEX2VhX3Njb3JlID0gYyhzY2FsZShTQURfZWFfc2NvcmUsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpKSkKCm1vZF9TQURfZWFfYmFyIDwtIGdncGxvdChtb2RfU0FEX2VhX2Jhcl9kYXRhLCBhZXMoeCA9IFNBRF9lYV9zY29yZSwgeSA9IG9zcGFuX2Fic29sdXRlX3Njb3JlLCBjb2xvciA9IGxvY2F0aW9uX2Rlc2spKSArCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtLCBhZXMoZmlsbCA9IGxvY2F0aW9uX2Rlc2spKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyhtaW4obW9kX1NBRF9lYV9iYXJfZGF0YSRTQURfZWFfc2NvcmUpLCBtYXgobW9kX1NBRF9lYV9iYXJfZGF0YSRTQURfZWFfc2NvcmUpKSwgCiAgICAgICAgICAgICAgICAgIHlsaW0gPSBjKG1pbihtb2RfU0FEX2VhX2Jhcl9kYXRhJG9zcGFuX2Fic29sdXRlX3Njb3JlKSwgbWF4KG1vZF9TQURfZWFfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpKSkgKwogIGxhYnModGl0bGUgPSAiTW9kZXJhdGluZyBPU3BhbiBBYnNvbHV0ZSBTY29yZSB3aXRoIEVtb3Rpb25hbCBBdHRhY2htZW50IiwgCiAgICAgICB4ID0gIkVtb3Rpb25hbCBBdHRhY2htZW50IiwgCiAgICAgICB5ID0gIk9TcGFuIEFic29sdXRlIFNjb3JlIiwgCiAgICAgICBjb2xvciA9ICJTbWFydHBob25lIExvY2F0aW9uIiwKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsCiAgICAgICBjYXB0aW9uID0gIk5vdGU6IFNtYXJ0cGhvbmUgRW1vdGlvbmFsIEF0dGFjaG1lbnQgaXMgbWVhbi1jZW50ZXJlZC4iCiAgICAgICApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHNlYWdyZWVuIiwgInB1cnBsZTMiLCAiZGVlcHNreWJsdWU0IikpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImxpZ2h0c2VhZ3JlZW4iLCAicHVycGxlNCIsICJkZWVwc2t5Ymx1ZTQiKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKI3Nob3cgZmlnCm1vZF9TQURfZWFfYmFyCgojIGV4cG9ydCBwbG90CiMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfbW9kX1NBRF9lYV9iYXJfanVuZTE0IiwgcGxvdCA9IG1vZF9TQURfZWFfYmFyLCBkZXZpY2UgPSAicG5nIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDUwMCkKYGBgCgoKKipBY2Nlc3NpYmlsaXR5Kiogd2FzICoqbm90KiogYSBzaWduaWZpY2FudCBtb2RlcmF0b3IgZm9yIE9TcGFuIGFic29sdXRlIHNjb3JlLiBObyBub3RhYmxlIHRyZW5kcyBpbiB0aGUgZGF0YSB3ZXJlIG9ic2VydmVkLgoKYGBge3IgY3JlYXRlICYgc2hvdyBtb2RfU0FEX2FjY2Vzc19iYXIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfQptb2RfU0FEX2FjY2Vzc19iYXJfZGF0YSA8LSAKICBtb2RfU0FEX2FjY2VzczEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSAlPiUgCiAgIyByZW1vdmUgcm93cyB3LyBvdXRsaWVyIHBzCiAgZmlsdGVyKHRvdGFsb3V0ICE9IDIpICU+JSAKICAjIHNlbGVjdCB0aGUgZGF0YSB3ZSB3YW50OiBJViwgRFYsIE0KICBzZWxlY3Qob3NwYW5fYWJzb2x1dGVfc2NvcmUsIFNBRF9hY2Nlc3Nfc2NvcmUsIGxvY2F0aW9uX2Rlc2spICU+JSAKICAjIHJlcGxhY2UgbW9kZXJhdG9yIHNjb3JlIHdpdGggbWVhbi1jZW50ZXJlZAogIG11dGF0ZShTQURfYWNjZXNzX3Njb3JlID0gYyhzY2FsZShTQURfYWNjZXNzX3Njb3JlLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IEZBTFNFKSkpCgptb2RfU0FEX2FjY2Vzc19iYXIgPC0gZ2dwbG90KG1vZF9TQURfYWNjZXNzX2Jhcl9kYXRhLCBhZXMoeCA9IFNBRF9hY2Nlc3Nfc2NvcmUsIHkgPSBvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgY29sb3IgPSBsb2NhdGlvbl9kZXNrKSkgKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSwgYWVzKGZpbGwgPSBsb2NhdGlvbl9kZXNrKSkgKyAKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMobWluKG1vZF9TQURfYWNjZXNzX2Jhcl9kYXRhJFNBRF9hY2Nlc3Nfc2NvcmUpLCBtYXgobW9kX1NBRF9hY2Nlc3NfYmFyX2RhdGEkU0FEX2FjY2Vzc19zY29yZSkpLCAKICAgICAgICAgICAgICAgICAgeWxpbSA9IGMobWluKG1vZF9TQURfYWNjZXNzX2Jhcl9kYXRhJG9zcGFuX2Fic29sdXRlX3Njb3JlKSwgbWF4KG1vZF9TQURfYWNjZXNzX2Jhcl9kYXRhJG9zcGFuX2Fic29sdXRlX3Njb3JlKSkpICsKICBsYWJzKHRpdGxlID0gIk1vZGVyYXRpbmcgT1NwYW4gQWJzb2x1dGUgU2NvcmUgd2l0aCBBY2Nlc3NpYmlsaXR5IiwgCiAgICAgICB4ID0gIkFjY2Vzc2liaWxpdHkiLCAKICAgICAgIHkgPSAiT1NwYW4gQWJzb2x1dGUgU2NvcmUiLCAKICAgICAgIGNvbG9yID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLAogICAgICAgZmlsbCA9ICJTbWFydHBob25lIExvY2F0aW9uIiwKICAgICAgIGNhcHRpb24gPSAiTm90ZTogQWNjZXNzaWJpbGl0eSBpcyBtZWFuLWNlbnRlcmVkLiIKICAgICAgICkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImxpZ2h0c2VhZ3JlZW4iLCAicHVycGxlMyIsICJkZWVwc2t5Ymx1ZTQiKSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygibGlnaHRzZWFncmVlbiIsICJwdXJwbGU0IiwgImRlZXBza3libHVlNCIpKSArCiAgdGhlbWVfY2xhc3NpYygpCgojc2hvdyBmaWcKbW9kX1NBRF9hY2Nlc3NfYmFyCgojIGV4cG9ydCBwbG90CiMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfbW9kX1NBRF9hY2Nlc3NfYmFyX2p1bmUxNCIsIHBsb3QgPSBtb2RfU0FEX2FjY2Vzc19iYXIsIGRldmljZSA9ICJwbmciLCBoZWlnaHQgPSA1LCB3aWR0aCA9IDgsIHVuaXRzID0gImluIiwgZHBpID0gNTAwKQpgYGAKCioqRGlzdHJhY3RpYmlsaXR5Kiogd2FzICoqbm90KiogYSBzaWduaWZpY2FudCBtb2RlcmF0b3IgZm9yIE9TcGFuIGFic29sdXRlIHNjb3JlLiBObyBub3RhYmxlIHRyZW5kcyBpbiB0aGUgZGF0YSB3ZXJlIG9ic2VydmVkLgoKYGBge3IgY3JlYXRlICYgc2hvdyBtb2RfU0FEX2Rpc3RfYmFyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KbW9kX1NBRF9kaXN0X2Jhcl9kYXRhIDwtIAogIG1vZF9TQURfZGlzdDEkZGF0YXNjcmVlbmluZyRmdWxsZGF0YSAlPiUgCiAgIyByZW1vdmUgcm93cyB3LyBvdXRsaWVyIHBzCiAgZmlsdGVyKHRvdGFsb3V0ICE9IDIpICU+JSAKICAjIHNlbGVjdCB0aGUgZGF0YSB3ZSB3YW50OiBJViwgRFYsIE0KICBzZWxlY3Qob3NwYW5fYWJzb2x1dGVfc2NvcmUsIFNBRF9kaXN0X3Njb3JlLCBsb2NhdGlvbl9kZXNrKSAlPiUgCiAgIyByZXBsYWNlIG1vZGVyYXRvciBzY29yZSB3aXRoIG1lYW4tY2VudGVyZWQKICBtdXRhdGUoU0FEX2Rpc3Rfc2NvcmUgPSBjKHNjYWxlKFNBRF9kaXN0X3Njb3JlLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IEZBTFNFKSkpCgptb2RfU0FEX2Rpc3RfYmFyIDwtIGdncGxvdChtb2RfU0FEX2Rpc3RfYmFyX2RhdGEsIGFlcyh4ID0gU0FEX2Rpc3Rfc2NvcmUsIHkgPSBvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgY29sb3IgPSBsb2NhdGlvbl9kZXNrKSkgKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSwgYWVzKGZpbGwgPSBsb2NhdGlvbl9kZXNrKSkgKyAKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMobWluKG1vZF9TQURfZGlzdF9iYXJfZGF0YSRTQURfZGlzdF9zY29yZSksIG1heChtb2RfU0FEX2Rpc3RfYmFyX2RhdGEkU0FEX2Rpc3Rfc2NvcmUpKSwgCiAgICAgICAgICAgICAgICAgIHlsaW0gPSBjKG1pbihtb2RfU0FEX2Rpc3RfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpLCBtYXgobW9kX1NBRF9kaXN0X2Jhcl9kYXRhJG9zcGFuX2Fic29sdXRlX3Njb3JlKSkpICsKICBsYWJzKHRpdGxlID0gIk1vZGVyYXRpbmcgT1NwYW4gQWJzb2x1dGUgU2NvcmUgd2l0aCBEaXN0cmFjdGliaWxpdHkiLCAKICAgICAgIHggPSAiRGlzdHJhY3RpYmlsaXR5IiwgCiAgICAgICB5ID0gIk9TcGFuIEFic29sdXRlIFNjb3JlIiwgCiAgICAgICBjb2xvciA9ICJTbWFydHBob25lIExvY2F0aW9uIiwKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsCiAgICAgICBjYXB0aW9uID0gIk5vdGU6IFNtYXJ0cGhvbmUgRGlzdHJhY3RpYmlsaXR5IGlzIG1lYW4tY2VudGVyZWQuIgogICAgICAgKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygibGlnaHRzZWFncmVlbiIsICJwdXJwbGUzIiwgImRlZXBza3libHVlNCIpKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHNlYWdyZWVuIiwgInB1cnBsZTQiLCAiZGVlcHNreWJsdWU0IikpICsKICB0aGVtZV9jbGFzc2ljKCkKCiNzaG93IGZpZwptb2RfU0FEX2Rpc3RfYmFyCgojIGV4cG9ydCBwbG90CiMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfbW9kX1NBRF9kaXN0X2Jhcl9qdW5lMTQiLCBwbG90ID0gbW9kX1NBRF9kaXN0X2JhciwgZGV2aWNlID0gInBuZyIsIGhlaWdodCA9IDUsIHdpZHRoID0gOCwgdW5pdHMgPSAiaW4iLCBkcGkgPSA1MDApCmBgYAoKKipBZ2UqKiB3YXMgKipub3QqKiBhIHNpZ25pZmljYW50IG1vZGVyYXRvciBmb3IgT1NwYW4gYWJzb2x1dGUgc2NvcmUuIEEgbm90YWJsZSB0cmVuZCBpbiB0aGUgZGF0YSB3YXMgb2JzZXJ2ZWQ6IGZvciBhbGwgbG9jYXRpb24gY29uZGl0aW9ucywgeW91bmdlciBwYXJ0aWNpcGFudHMgdGVuZGVkIHRvIHNob3cgYmV0dGVyIHRhc2sgcGVyZm9ybWFuY2UuCgpgYGB7ciBjcmVhdGUgJiBzaG93IG1vZF9TVVFfYWdlX2JhciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9Cm1vZF9TVVFfYWdlX2Jhcl9kYXRhIDwtIAogIG1vZF9TVVFfYWdlMSRkYXRhc2NyZWVuaW5nJGZ1bGxkYXRhICU+JSAKICAjIHJlbW92ZSByb3dzIHcvIG91dGxpZXIgcHMKICBmaWx0ZXIodG90YWxvdXQgIT0gMikgJT4lIAogICMgc2VsZWN0IHRoZSBkYXRhIHdlIHdhbnQ6IElWLCBEViwgTQogIHNlbGVjdChvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgYWdlLCBsb2NhdGlvbl9kZXNrKSAlPiUgCiAgIyByZXBsYWNlIG1vZGVyYXRvciBzY29yZSB3aXRoIG1lYW4tY2VudGVyZWQKICBtdXRhdGUoYWdlID0gYyhzY2FsZShhZ2UsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpKSkKCm1vZF9TVVFfYWdlX2JhciA8LSBnZ3Bsb3QobW9kX1NVUV9hZ2VfYmFyX2RhdGEsIGFlcyh4ID0gYWdlLCB5ID0gb3NwYW5fYWJzb2x1dGVfc2NvcmUsIGNvbG9yID0gbG9jYXRpb25fZGVzaykpICsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gbG0sIGFlcyhmaWxsID0gbG9jYXRpb25fZGVzaykpICsgCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKG1pbihtb2RfU1VRX2FnZV9iYXJfZGF0YSRhZ2UpLCBtYXgobW9kX1NVUV9hZ2VfYmFyX2RhdGEkYWdlKSksIAogICAgICAgICAgICAgICAgICB5bGltID0gYyhtaW4obW9kX1NVUV9hZ2VfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpLCBtYXgobW9kX1NVUV9hZ2VfYmFyX2RhdGEkb3NwYW5fYWJzb2x1dGVfc2NvcmUpKSkgKwogIGxhYnModGl0bGUgPSAiTW9kZXJhdGluZyBPU3BhbiBBYnNvbHV0ZSBTY29yZSB3aXRoIEFnZSIsIAogICAgICAgeCA9ICJBZ2UgKHllYXJzKSIsIAogICAgICAgeSA9ICJPU3BhbiBBYnNvbHV0ZSBTY29yZSIsIAogICAgICAgY29sb3IgPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsCiAgICAgICBmaWxsID0gIlNtYXJ0cGhvbmUgTG9jYXRpb24iLAogICAgICAgY2FwdGlvbiA9ICJOb3RlOiBBZ2UgaXMgbWVhbi1jZW50ZXJlZC4iCiAgICAgICApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHNlYWdyZWVuIiwgInB1cnBsZTMiLCAiZGVlcHNreWJsdWU0IikpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImxpZ2h0c2VhZ3JlZW4iLCAicHVycGxlNCIsICJkZWVwc2t5Ymx1ZTQiKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKI3Nob3cgZmlnCm1vZF9TVVFfYWdlX2JhcgoKIyBleHBvcnQgcGxvdAojIGdnc2F2ZShmaWxlbmFtZT0iZmlnX21vZF9TVVFfYWdlX2JhciIsIHBsb3QgPSBtb2RfU1VRX2FnZV9iYXIsIGRldmljZSA9ICJwbmciLCBoZWlnaHQgPSA1LCB3aWR0aCA9IDgsIHVuaXRzID0gImluIiwgZHBpID0gNTAwKQpgYGAKCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgVEhFU0UgQVJFIFRIRSBGSUdTIFRIRSBNT0RFUkFUSU9OMSBGVU5DVElPTiBHSVZFUy4uLiAKCiMgRGVwZW5kZW5jeQptb2RfU0FEX2RlcDEkZ3JhcGhzbG9wZXMKCiMgRW1vdGlvbmFsIEF0dGFjaG1lbnQKbW9kX1NBRF9lYTEkZ3JhcGhzbG9wZXMKCgojIEFjY2Vzc2liaWxpdHkKbW9kX1NBRF9hY2Nlc3MxJGdyYXBoc2xvcGVzCgojIERpc3RyYWN0aWJpbGl0eQptb2RfU0FEX2Rpc3QxJGdyYXBoc2xvcGVzCgojIEFnZQptb2RfU1VRX2FnZTEkZ3JhcGhzbG9wZXMKCgojIGFkZCBnZW9tX3Ntb290aChmb3JtdWxhID0geSB+IHgsIG1ldGhvZCA9ICJsbSIpIHRvIGF2b2lkIGVycm9ycwpgYGAKCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMjb3ZlcmFsbCBtb2RlbCBzdGF0aXN0aWNzCiNGKDUsIDM3NykgPSAwLjE1LCBwID0gLjk4MSwgUjIgPSAuMDAyCgojI2VhY2ggcHJlZGljdG9yIG9uZSBhdCBhIHRpbWUKICAjRGVwZW5kZW5jeSBzY29yZSBiID0gMC4wMDgsIHQoMzc3KSA9IDAuMDM5LCBwID0gLjk2OQogICAgI0RlcGVuZGVuY3kgc2NvcmUgZG9lcyBub3QgcHJlZGljdCBpbmNvbWUgcmF0ZXMKICAKICAjUC9CIHZzLiBEZXNrIGIgPSAwLjg3MiwgdCgzNzcpID0gMC40MTMsIHAgPSAuNjgwCiAgICAjbm90IGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIGRlc2sgYW5kIHBvY2tldC9iYWcgbG9jYXRpb24gZm9yIE9TcGFuIGFiIHNjb3JlCiAgI291dHNpZGUgdnMuIERlc2sgYiA9IDAuMTQxLCB0KDM3NykgPSAwLjA2NSwgcCA9IC45NDgKICAgICNub3QgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gZGVzayBhbmQgb3V0c2lkZSBsb2NhdGlvbiBmb3IgT1NwYW4gYWIgc2NvcmUKCiMgZ2V0IG1lYW5zIGZvciBPU3BhbiBhYiBzY29yZSBieSBjYXRlZ29yaWNhbCB2YXJpYWJsZQogIHRhcHBseShtb2RfYW5hbHlzaXMkb3NwYW5fYWJzb2x1dGVfc2NvcmUsIG1vZF9hbmFseXNpcyRsb2NhdGlvbiwgbWVhbikKICMgZGVzayAgICAgIHBvY2tldGJhZyAgb3V0c2lkZSAKICMgNDEuMTQwNjIgIDQyLjAxNTE1ICA0MS40MzA4OSAKCiMjSW50ZXJhY3Rpb24KI0xvY2F0aW9uIGJ5IHAvYiB2ZXJzdXMgZGVzayAtLSBub3Qgc2lnbmlmaWNhbnQKICAjIGIgPSAtMC4wMDgsIHQoMzc3KSA9IC0wLjAyNiwgcCA9IC45NzkKI0xvY2F0aW9uIGJ5IG91dHNpZGUgdmVyc3VzIGRlc2sgLS0gbm90IHNpZ25pZmljYW50CiAgIyBiID0gMC4xNTgsIHQoMzc3KSA9IDAuNTMzLCBwID0gLjU5NAoKI2JyZWFrIGRvd24gYnkgTQojRGVwZW5kZW5jeSBzY29yZSBwcmVkaWN0aW5nIE9TcGFuIGFiIHNjb3JlIGZvciBlYWNoIGdyb3VwL2xldmVsIG9mIGxvY2F0aW9uCgojU2ltcGxlIHNsb3BlcyBieSBsZXZlbHMgb2YgTQpzYXZlZCRzbG9wZW1vZGVscwoKIyN2aWV3IHdpdGggbGFwcGx5CmxhcHBseShzYXZlZCRzbG9wZW1vZGVscywgc3VtbWFyeSkKCiNMb3cgbXVyZGVyIGxldmVscywgaWxsaXRlcmFjeSBiID0gNjIyLjcwIG5vdCBzaWduaWZpY2FudAojQXZlcmFnZSBiID0gMTI1LjAwIG5vdCBzaWduaWZpY2FudAojSGlnaCBiID0gLTkwMi42MCBpcyBzaWduaWZpY2FudAoKI2F0IGxvdyBhbmQgYXZlcmFnZSBtdXJkZXIgcmF0ZXMsIGlsbGl0ZXJhY3kgZG9lcyBub3QgcHJlZGljdCBpbmNvbWUKI2F0IGhpZ2ggbXVyZGVyIHJhdGVzLCBpbGxpdGVyYWN5IG5lZ2F0aXZlbHkgcHJlZGljdHMgaW5jb21lCgojI29yIHB1bGwgb25lIGF0IGEgdGltZQpzdW1tYXJ5KHNhdmVkJHNsb3BlbW9kZWxzJExvdykKY29lZihzYXZlZCRzbG9wZW1vZGVscyRMb3cpCgpzdW1tYXJ5KHNhdmVkJHNsb3BlbW9kZWxzJEF2ZXJhZ2UpCgojSW50ZXJwcmV0YXRpb24gb2YgU2xvcGVzCmNhdChzYXZlZCRpbnRlcnByZXRhdGlvbikKCiNHcmFwaCBvZiB0aGUgU2xvcGVzCnNhdmVkJGdyYXBoc2xvcGVzCgojcmVtZW1iZXIsIHlvdSBjYW4gcnVuIHRoZSBmdW5jdGlvbiB3aXRoIG91dCAoKQojdG8gdmlldyB0aGUgZ3JhcGggY29kZSBpZiB5b3Ugd2FudCB0byB0d2VhayBpdCBtb3JlCm1vZGVyYXRpb24xCgojIyMjUG93ZXIjIyMjCmxpYnJhcnkocHdyKQojI3Bvd2VyIHJ1bnMgb24gY29oZW4ncyBmIC0gbm90IHRvIGJlIGNvbmZ1c2VkIHdpdGggYW5vdmEgZi4KIyN0YWtlIHRoZSBSIHNxdWFyZWQgdG8gY29udmVydApSMiA9ICAuMjAKZmV0YSA9IFIyIC8gKDEtUjIpCgojdSBpcyBkZiBtb2RlbCwgd2hpY2ggaXMgbnVtYmVyIG9mIHByZWRpY3RvcnMKI3YgaXMgZGYgZXJyb3IsIGJ1dCB3ZSBhcmUgdHJ5aW5nIHRvIGZpZ3VyZSBvdXQKI3NhbXBsZSBzaXplIHNvIHdlIGxlYXZlIHRoaXMgb25lIGJsYW5rLgojZjIgaXMgY29oZW4gZiBzcXVhcmVkCgojI2FsbCB0aGUgcHJlZGljdG9ycwpwd3IuZjIudGVzdCh1ID0gNSwgdiA9IE5VTEwsIGYyID0gZmV0YSwgc2lnLmxldmVsID0gLjA1LCBwb3dlciA9IC44MCkKI3JlbWVtYmVyIHRoYXQgeW91IG5lZWQgdG8gYWRkIHUgKyB2IHRvIGdldCBmaW5hbCBzYW1wbGUgc2l6ZQoKIyNhZGRpdGlvbiBvZiB0aGUgaW50ZXJhY3Rpb24gb25seQpwd3IuZjIudGVzdCh1ID0gMiwgdiA9IE5VTEwsIGYyID0gZmV0YSwgc2lnLmxldmVsID0gLjA1LCBwb3dlciA9IC44MCkKI3JlbWVtYmVyIHRoYXQgeW91IG5lZWQgdG8gYWRkIHUgKyB2IHRvIGdldCBmaW5hbCBzYW1wbGUgc2l6ZQoKYGBgCgpgYGB7ciBtYW51YWxfbG0sIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgQW5hbHlzaXMgY2FuIGJlIHJ1biBtYW51YWxseSB1c2luZyBsbSgpCiMgdGhpcyBleGFtcGxlIGdvZXMgdGhyb3VnaCBob3cgeW91IHdvdWxkIHJ1biB0aGlzIG9uIDMgbW9kZXJhdG9ycyBpbiB0b3RhbAojIGRvZXMgbm90IGluY2x1ZGUgZ3JhcGggb3IgYXNzdW1wdGlvbiBjaGVja3MKCiMgc2V0IHVwIHRoZSBkYXRhIC0tIGFkZCBtZWFuLWNlbnRlcmVkIHNjb3JlcwogICMgbm90ZTogbWFrZSBzdXJlIGNhdGVnb3JpY2FsIHZhciAoSVYgPSBsb2NhdGlvbikgaXMgYSBmYWN0b3Igb3Igd2lsbCBub3QgcnVuIGNvcnJlY3RseQp5IDwtCiAgIyB1c2Ugb3JpZ2luYWwgZGF0YSBmaWxlCiAgbW9kX2FuYWx5c2lzICU+JQogICMgYWRkIG1lYW4tY2VudGVyZWQgdmFycyBmb3IgZWFjaCBtb2QgLS0gbm90ZTogZWFjaCBtb2Qgd2lsbCBiZSB1c2VkIGluIHNlcGFyYXRlIGFuYWx5c2lzCiAgYmluZF9jb2xzKFNBRF9kZXBDID0gYyhzY2FsZShtb2RfYW5hbHlzaXMkU0FEX2RlcF9zY29yZSwgIGNlbnRlcj1UUlVFLCBzY2FsZT1GQUxTRSkpLCAjIGZvciBkZXBlbmRlbmN5CiAgICAgICAgICAgIFNBRF9lYUMgPSBjKHNjYWxlKG1vZF9hbmFseXNpcyRTQURfZWFfc2NvcmUsICBjZW50ZXI9VFJVRSwgc2NhbGU9RkFMU0UpKSwgIyBmb3IgZW1vdGlvbmFsIGF0dGFjaG1lbnQKICAgICAgICAgICAgU0FEX2Rpc3RDID0gYyhzY2FsZShtb2RfYW5hbHlzaXMkU0FEX2Rpc3Rfc2NvcmUsICBjZW50ZXI9VFJVRSwgc2NhbGU9RkFMU0UpKSAjIGZvciBkaXN0cmFjdGliaWxpdHkKICAgICAgICAgICAgKSAlPiUKICByZW5hbWUob3NwYW4gPSBvc3Bhbl9hYnNvbHV0ZV9zY29yZSkgIyByZW5hbWUgRFYgc2hvcnRlciBuYW1lCgojIEZPUiBTTUFSVFBIT05FIERFUEVOREVOQ1kKIyB0byBydW4gdGhlIG92ZXJhbGwgbW9kZWwKICBzdW1tYXJ5KGxtKGRhdGEgPSB5LCBmb3JtdWxhID0gb3NwYW4gfiAgU0FEX2RlcEMgKyBsb2NhdGlvbiArIGxvY2F0aW9uKlNBRF9kZXBDKSkKCiMgdG8gcnVuIHRoZSBzaW1wbGUgc2xvcGVzIChpLmUuLCBwb3N0LWhvY3MgLyBwYWlyLXdpc2UgY29tcGFyaXNvbnMpCiAgc3VtbWFyeShsbShmb3JtdWxhID0gb3NwYW4gfiBTQURfZGVwQywgZGF0YSA9IGRwbHlyOjpmaWx0ZXIoeSwgbG9jYXRpb24gPT0gImRlc2siKSkpCiAgc3VtbWFyeShsbShmb3JtdWxhID0gb3NwYW4gfiBTQURfZGVwQywgZGF0YSA9IGRwbHlyOjpmaWx0ZXIoeSwgbG9jYXRpb24gPT0gInBvY2tldC9iYWciKSkpCiAgc3VtbWFyeShsbShmb3JtdWxhID0gb3NwYW4gfiBTQURfZGVwQywgZGF0YSA9IGRwbHlyOjpmaWx0ZXIoeSwgbG9jYXRpb24gPT0gIm91dHNpZGUiKSkpCgojIEZPUiBFTU9USU9OQUwgQVRUQUNITUVOVAojIHRvIHJ1biB0aGUgb3ZlcmFsbCBtb2RlbAogIHN1bW1hcnkobG0oZGF0YSA9IHksIGZvcm11bGEgPSBvc3BhbiB+ICBTQURfZWFDICsgbG9jYXRpb24gKyBsb2NhdGlvbipTQURfZWFDKSkKCiMgdG8gcnVuIHRoZSBzaW1wbGUgc2xvcGVzIChpLmUuLCBwb3N0LWhvY3MgLyBwYWlyLXdpc2UgY29tcGFyaXNvbnMpCiAgc3VtbWFyeShsbShmb3JtdWxhID0gb3NwYW4gfiBTQURfZWFDLCBkYXRhID0gZHBseXI6OmZpbHRlcih5LCBsb2NhdGlvbiA9PSAiZGVzayIpKSkKICBzdW1tYXJ5KGxtKGZvcm11bGEgPSBvc3BhbiB+IFNBRF9lYUMsIGRhdGEgPSBkcGx5cjo6ZmlsdGVyKHksIGxvY2F0aW9uID09ICJwb2NrZXQvYmFnIikpKQogIHN1bW1hcnkobG0oZm9ybXVsYSA9IG9zcGFuIH4gU0FEX2VhQywgZGF0YSA9IGRwbHlyOjpmaWx0ZXIoeSwgbG9jYXRpb24gPT0gIm91dHNpZGUiKSkpCgojIEZPUiBTTUFSVFBIT05FIERJU1RSQUNUSUJJTElUWQojIHRvIHJ1biB0aGUgb3ZlcmFsbCBtb2RlbAogIHN1bW1hcnkobG0oZGF0YSA9IHksIGZvcm11bGEgPSBvc3BhbiB+ICBTQURfZGlzdEMgKyBsb2NhdGlvbiArIGxvY2F0aW9uKlNBRF9kaXN0QykpCgojIHRvIHJ1biB0aGUgc2ltcGxlIHNsb3BlcyAoaS5lLiwgcG9zdC1ob2NzIC8gcGFpci13aXNlIGNvbXBhcmlzb25zKQogIHN1bW1hcnkobG0oZm9ybXVsYSA9IG9zcGFuIH4gU0FEX2Rpc3RDLCBkYXRhID0gZHBseXI6OmZpbHRlcih5LCBsb2NhdGlvbiA9PSAiZGVzayIpKSkKICBzdW1tYXJ5KGxtKGZvcm11bGEgPSBvc3BhbiB+IFNBRF9kaXN0QywgZGF0YSA9IGRwbHlyOjpmaWx0ZXIoeSwgbG9jYXRpb24gPT0gInBvY2tldC9iYWciKSkpCiAgc3VtbWFyeShsbShmb3JtdWxhID0gb3NwYW4gfiBTQURfZGlzdEMsIGRhdGEgPSBkcGx5cjo6ZmlsdGVyKHksIGxvY2F0aW9uID09ICJvdXRzaWRlIikpKQpgYGAKCmBgYHtyIHJ1bl9tb2Rfd2FyZCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyBleHBsb3JhdG9yeSAtLSB2aWV3IFdhcmQgZXQgYWwuJ3MgKDIwMTcpICJTbWFydHBob25lIERlcGVuZGVuY3kiICYgIkVtb3Rpb25hbCBBdHRhY2htZW50IiBzdWJzY2FsZXMKbW9kX3dhcmQgPC0gCiAgYWxsX2RhdGEgJT4lIAogIHJvd3dpc2UoKSAlPiUgCiAgbXV0YXRlKFNBRF9kZXAgPSBzdW0oU0FEXzEsIFNBRF8yLCBTQURfMywgU0FEXzQsIFNBRF81LCBTQURfNiksIAogICAgICAgICBTQURfZWEgPSBzdW0oU0FEXzgsIFNBRF85LCBTQURfMTAsIFNBRF8xMSwgU0FEXzEyKSkKIyBtYWtlIGxvY2F0aW9uIGZhY3Rvcgptb2Rfd2FyZCRsb2NhdGlvbiA8LSBmYWN0b3IobW9kX3dhcmQkbG9jYXRpb24sIGxldmVscyA9IGMoMTozKSwgbGFiZWxzID0gYygiZGVzayIsICJwb2NrZXRiYWciLCAib3V0c2lkZSIpKQoKIyBydW4gbW9kZXJhdGlvbiBmb3IgU21hcnRwaG9uZSBEZXBlbmRlbmN5IAptb2Rfd2FyZF9kZXAxIDwtIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjRFYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gIlNBRF9kZXAiLCAjSVYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtID0gImxvY2F0aW9uIiwgI01vZGVyYXRvciBmb3Igc2ltcGxlIHNsb3BlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN2cyA9IE5VTEwsICMgY292YXJpYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmID0gbW9kX3dhcmQsICMgZGF0YSBmcmFtZSBvZiBjb2x1bW5zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aF9vdXQgPSBUKQoKIyBydW4gbW9kZXJhdGlvbiBmb3IgRW1vdGlvbmFsIEF0dGFjaG1lbnQKbW9kX3dhcmRfZWExIDwtIG1vZGVyYXRpb24xKHkgPSAib3NwYW5fYWJzb2x1dGVfc2NvcmUiLCAjRFYKICAgICAgICAgICAgICAgICAgICB4ID0gIlNBRF9lYSIsICNJVgogICAgICAgICAgICAgICAgICAgIG0gPSAibG9jYXRpb24iLCAjTW9kZXJhdG9yIGZvciBzaW1wbGUgc2xvcGVzCiAgICAgICAgICAgICAgICAgICAgY3ZzID0gTlVMTCwgI2NvdmFyaWF0ZXMKICAgICAgICAgICAgICAgICAgICBkZiA9IG1vZF93YXJkLCAjIGRhdGEgZnJhbWUgb2YgY29sdW1ucwogICAgICAgICAgICAgICAgICAgIHdpdGhfb3V0ID0gVCkKCmBgYAoKCiMjIyMjIyBQYW5lbAoKYGBge3J9CiMgY3JlYXRlIGpvaW4gZGF0YSBzZXQgd2l0aCBhbGwgbW9kZXJhdG9yIGRhdGEKbW9kX2FsbF9kYXRhX3Bsb3QgPC0gCiAgY2JpbmQoZGF0YS5mcmFtZSgibW9kZXJhdG9yIiA9IGMocmVwKDEsIG5yb3cobW9kX1NBRF9kZXBfYmFyX2RhdGEpKSwgcmVwKDIsIG5yb3cobW9kX1NBRF9lYV9iYXJfZGF0YSkpLCByZXAoMywgbnJvdyhtb2RfU0FEX2FjY2Vzc19iYXJfZGF0YSkpLCByZXAoNCwgbnJvdyhtb2RfU0FEX2Rpc3RfYmFyX2RhdGEpKSkpLCAKICAgICAgICByYmluZCgKICAgICAgICAjIFNBRF9kZXAgZGF0YQogICAgICAgIG1vZF9TQURfZGVwX2Jhcl9kYXRhICU+JSBkcGx5cjo6cmVuYW1lKG1vZF9zY29yZSA9IFNBRF9kZXBfc2NvcmUpLCAjIHJlbmFtZSBjb2x1bW4gdG8gam9pbiBjb3JyZWN0bHkKICAgICAgICBtb2RfU0FEX2VhX2Jhcl9kYXRhICU+JSBkcGx5cjo6cmVuYW1lKG1vZF9zY29yZSA9IFNBRF9lYV9zY29yZSksICMgcmVuYW1lIGNvbHVtbiB0byBqb2luIGNvcnJlY3RseQogICAgICAgIG1vZF9TQURfYWNjZXNzX2Jhcl9kYXRhICU+JSBkcGx5cjo6cmVuYW1lKG1vZF9zY29yZSA9IFNBRF9hY2Nlc3Nfc2NvcmUpLCAjIHJlbmFtZSBjb2x1bW4gdG8gam9pbiBjb3JyZWN0bHkKICAgICAgICBtb2RfU0FEX2Rpc3RfYmFyX2RhdGEgJT4lIGRwbHlyOjpyZW5hbWUobW9kX3Njb3JlID0gU0FEX2Rpc3Rfc2NvcmUpICMgcmVuYW1lIGNvbHVtbiB0byBqb2luIGNvcnJlY3RseQogICAgICAgICkKICAgICAgICApICU+JSAKICBtdXRhdGUobW9kZXJhdG9yID0gZmFjdG9yKG1vZGVyYXRvciwgbGV2ZWxzID0gYygxOjQpLCBsYWJlbHMgPSBjKCIoQSkgRGVwZW5kZW5jeSIsICIoQikgRW1vdGlvbmFsIEF0dGFjaG1lbnQiLCAiKEMpIEFjY2Vzc2liaWxpdHkiLCAiKEQpIERpc3RyYWN0aWJpbGl0eSIpKSkgJT4lIAogIG11dGF0ZShsb2NhdGlvbl9kZXNrID0gZmFjdG9yKGxvY2F0aW9uX2Rlc2ssIGxhYmVscyA9IGMoIkRlc2siLCAiUG9ja2V0L0JhZyIsICJPdXRzaWRlIikpKQoKZ2xpbXBzZShtb2RfYWxsX2RhdGFfcGxvdCkKYGBgCgpgYGB7cn0KIyBjcmVhdGUgcGFuZWwgZmlnCm1vZF9hbGxfcGxvdCA8LQogIGdncGxvdChtb2RfYWxsX2RhdGFfcGxvdCwgYWVzKHggPSBtb2Rfc2NvcmUsIHkgPSBvc3Bhbl9hYnNvbHV0ZV9zY29yZSwgZ3JvdXAgPSBsb2NhdGlvbl9kZXNrKSkgKwogIGdlb21fcG9pbnQoc3RhdCA9ICJpZGVudGl0eSIsIGFlcyhzaGFwZSA9IGxvY2F0aW9uX2Rlc2ssIGNvbG9yID0gbG9jYXRpb25fZGVzayksIHNpemUgPSAxLjUpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtLCBhZXMoZmlsbCA9IGxvY2F0aW9uX2Rlc2ssIGNvbG9yID0gbG9jYXRpb25fZGVzayksIHNpemUgPSAxKSArIAogIGxhYnMoCiAgICAjIHRpdGxlID0gIk1vZGVyYXRpbmcgT1NwYW4gQWJzb2x1dGUgU2NvcmUiLAogICAgICAgeCA9ICJNZWFuLUNlbnRlcmVkIFNjb3JlIiwgCiAgICAgICB5ID0gIk9TcGFuIEFic29sdXRlIFNjb3JlIiwgCiAgICAgICBjb2xvciA9ICJTbWFydHBob25lIExvY2F0aW9uIiwKICAgICAgIGZpbGwgPSAiU21hcnRwaG9uZSBMb2NhdGlvbiIsCiAgICAgICBzaGFwZSA9ICJTbWFydHBob25lIExvY2F0aW9uIikgKwogIGZhY2V0X3dyYXAofm1vZGVyYXRvciwgbmNvbCA9IDIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjMThCQUIzIiwgIiM2MjEyOUIiLCAiIzAwNzI5OCIpKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjMThCQUIzIiwgIiM2MjEyOUIiLCAiIzAwNzI5OCIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgNzUpLCBicmVha3MgPSBjKHNlcSgwLDc1LCAyNSkpKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCiAgCgojIHNob3cgcGxvdAptb2RfYWxsX3Bsb3QKCiMgZXhwb3J0IHBsb3RzCiMgZ2dzYXZlKGZpbGVuYW1lPSJmaWdfbW9kX2FsbF9wbG90X2p1bmUxNiIsIHBsb3QgPSBtb2RfYWxsX3Bsb3QsIGRldmljZSA9ICJqcGVnIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA4LCB1bml0cyA9ICJpbiIsIGRwaSA9IDEwMDApCgpgYGA=