Authors

Joseph O’Hagan School of Computing Science, University of Glasgow, Glasgow, United Kingdom Pejman Saeghe School of Computer Science, University of Glasgow, Glasgow, Lanarkshire, United Kingdom, Jan Gugenheimer Télécom Paris - LTCI, Institut Polytechnique de Paris, Paris, France Dr Daniel Medeiros School of Computing Science, University of Glasgow, Glasgow, United Kingdom, Karola Marky University of Glasgow, Glasgow, Germany, Dr. Mohamed Khamis University of Glasgow, Glasgow, United Kingdom Dr Mark McGill School of Computing Science, University of Glasgow, Glasgow, Lanarkshire, United Kingdom,

Overview

This data is for our ACM IMWUT 2022 paper “Privacy-Enhancing Technology and Everyday Augmented Reality: Understanding Bystanders’ Varying Needs for Awareness and Consent”.

This was a rather complex survey, with multiple looping factors. This RMarkdown file contains our breakdown and analysis of the quesitons in the survey. See also the attachment of the survey PDF.

# MAPPINGS

For demographics

3 age 4 gender 5 country 6 have you used AR before 7 do you know what an ar headset is

Question mappings for looped questions
capability 11 23 consent by social connection 13 25 automatic consent 14 26 concerning 15 27 more concerning than smartphone 16 28 stranger awareness preference 18 30 your headset awareness preference 20 32

Ending questions

34 more or less uncomfortable with AR 35 how comortable are you —————

Behind the scenes

SETUP

library(qualtRics)
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
6: In readChar(file, size, TRUE) : truncating string with embedded nuls
7: In readChar(file, size, TRUE) : truncating string with embedded nuls
8: In readChar(file, size, TRUE) : truncating string with embedded nuls
9: In readChar(file, size, TRUE) : truncating string with embedded nuls
10: In readChar(file, size, TRUE) : truncating string with embedded nuls
library(reshape2)
library(stringr)
library(plyr)
library(dplyr) 
library(ggplot2)
library(ARTool)
library(forcats)
library(statsExpressions)
library(cowplot) 
library(scales)

raw_data <- read_survey("cleaned_data.csv")

-- Column specification ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cols(
  .default = col_character(),
  Progress = col_double(),
  `Duration (in seconds)` = col_double(),
  Finished = col_logical()
)
i Use `spec()` for the full column specifications.
raw_data$ParticipantID <- seq.int(nrow(raw_data))
head(raw_data)
raw_data <- subset(raw_data, Progress == 100)
no_complete_responses = nrow(raw_data)

UTILITY FUNCTION / TESTING

#data = raw_data
#questions_to_select =  c("Q21", "Q22", "Q42")
#question_factor_levels =  c("21"  = "Age", "22" = "Gender", "42" = "Country")
#id_variables = c("ParticipantID")
#factor_one_levels = loop.factor
#factor_two_levels = NULL

ExportPlot <- function(gplot, filename, width=2, height=1.5, doPNG=TRUE, doPDF=FALSE, doEPS=FALSE) {
  # Export plot in PDF and EPS.
  # Notice that A4: width=11.69, height=8.27
  if (doPDF){
    ggsave(paste(filename, '.pdf', sep=""), gplot, width = width, height = height)
  }
  
  if (doEPS){
    postscript(file = paste(filename, '.eps', sep=""), width = width, height = height, horizontal = FALSE, onefile = FALSE, paper = "special")
  }
  #print(gplot)
  #dev.off()
  if (doPNG){
    #png(file = paste(filename, '_.png', sep=""), width = width * 100, height = height * 100)
    ggsave(paste(filename, '_.png', sep=""), gplot, width = width, height = height)
  }
  #print(gplot)
  #dev.off()
}

# define factor levels ala c(Congruent  = "Con", InCongruent = "InCon")
extract_composite_question_with_factors <- function(data, questions_to_select, id_variables, value_order,
                                         question_factor_levels  = NULL, 
                                         factor_one_levels  = NULL, 
                                         factor_two_levels  = NULL) {
  
  # select subset of questions we are looking at and ID variables
  data_subset <- select(data,matches( append(id_variables, questions_to_select))) 

  # now flatten this list using melt, excluding ID variables
  melted_data_subset <- melt(data_subset, id.vars=id_variables)
  #print(melted_data_subset)
  
  # then we need to set the factor levels for the various factors in our questionnaire.
  # This might be encoded in the question (e.g. q34 looking at bystander perspective, Q35 looking at user perspective)
  # Or might be explicitly coded for (e.g. a question loop, or rows in a question)
  # This is all encoded in the question string e.g. "4_Q64_1" where
  #   4 indicates level of first factor
  #   54 indicates level of question factor
  #   1 indicates level of third factor
  
  if (exists("question_factor_levels") && !is.null(question_factor_levels)){
      
      question_index = 1;
      # if we have a precursor factor defined, it's parsed before the question number is parsed
      if ( (exists("factor_one_levels") && !is.null(factor_one_levels)) )
        question_index = 2;
    
      melted_data_subset$question_factor <- unlist(purrr::transpose (stringr::str_extract_all(melted_data_subset$variable,"\\(?[0-9,.]+\\)?"))[[question_index]])
      melted_data_subset$question_factor <- factor(melted_data_subset$question_factor)
      melted_data_subset$question_factor <- revalue(melted_data_subset$question_factor, question_factor_levels)
  }
  
  if (exists("factor_one_levels") && !is.null(factor_one_levels)){
      melted_data_subset$factor_one <- unlist(purrr::transpose (stringr::str_extract_all(melted_data_subset$variable,"\\(?[0-9,.]+\\)?"))[[1]])
      melted_data_subset$factor_one <- factor(melted_data_subset$factor_one)
      melted_data_subset$factor_one <- revalue(melted_data_subset$factor_one, factor_one_levels)
  }
  
  if (exists ("factor_two_levels") && !is.null(factor_two_levels)){
      melted_data_subset$factor_two <- unlist(purrr::transpose (stringr::str_extract_all(melted_data_subset$variable,"\\(?[0-9,.]+\\)?"))[[3]])
      melted_data_subset$factor_two <- factor(melted_data_subset$factor_two)
      #print(levels(melted_data_subset$factor_two))
      melted_data_subset$factor_two <- revalue(melted_data_subset$factor_two, factor_two_levels)
  }
  
  melted_data_subset$ParticipantID <- factor(melted_data_subset$ParticipantID)
  
  melted_data_subset$value <- factor(melted_data_subset$value)

  #if (! is.null(value_order)){
  #  melted_data_subset$value <- factor(melted_data_subset$value, ordered = TRUE, levels = value_order)
  #} else {
  #  melted_data_subset$value <- factor(melted_data_subset$value)
  #}
  return (na.omit(melted_data_subset))
}

common.loopfactor <- c(
  "4" = "Camera usage",
  "5" = "Microphone usage",
  "7" = "Diminished reality",
  "8" = "Activity tracking",
  "9" = "Internal state",
  "12" = "Biometric ID",
  "13" = "Augmented perception",
  "16" = "Personal characteristics",
  "17" = "Physiological state",
  "18" = "Volumetric capture",
  "19" = "Augmented appearance"
)

common.looporder <-c(
  "Camera usage",
  "Microphone usage",
  "Activity tracking",
  "Volumetric capture",
  "Personal characteristics",
  "Biometric ID",
  "Internal state",
  "Physiological state",
  "Augmented appearance",
  "Diminished reality",
  "Augmented perception"
)

common.id_variables <- c("ParticipantID")

common.relationship <- c(
  "1" = "Close friend",
  "2" = "Friend",
  "3" = "Familiar stranger",
  "4" = "Stranger",
  "5" = "Accessibility needs"
)

common.awareness <- c(
  "1" = "None",
  "2" = "Basic",
  "3" = "Iconographic",
  "4" = "Full"
)

common.consent <- c(
  "1" = "With Consent",
  "2" = "Without Consent"
)

common.theme <-    theme(legend.position="bottom", legend.text=element_text(size=11),
          legend.title =element_blank(),
          legend.spacing.x=unit(0.8,"line"),
          legend.key.width=unit(1.8,"line"), legend.key.height=unit(1,"line")) +
      theme(axis.title.x=element_blank(),
          strip.text.x=element_text(size=12),
          axis.text=element_text(size=12),
          axis.ticks.y = element_blank(),
          axis.text.y=element_text(margin=margin(0,-8,0,0)),
          panel.background=element_blank(),
          panel.border=element_blank(),
          panel.grid.major=element_blank(),
          panel.grid.minor=element_blank(),
          panel.spacing.x = unit(1.0, "lines"),
          plot.background=element_blank())
CIColor = "red"

# common.agerange <- c(
#   "18 - 24" = 21,
#   "25 - 34" = ,
#   "35 - 44" = "Diminished reality",
#   "45 - 54" = "Tracking bystanders",
#   "55 - 64" = "Emotional & Physiological State",
#   "65 - 74" = "Biometric ID",
#   "13" = "Super hearing / sight",
#   "16" = "Personal characteristics",
#   "17" = "Medical / Health data",
#   "18" = "3D capture",
#   "19" = "Augmented appearance"
# )

ENTRY QUESTIONS

Demographics

age_results = extract_composite_question_with_factors(raw_data, c("Q3$"), common.id_variables, NULL,
                                        c("3"  = "Age"))
age_results
levels(factor(age_results$value))
[1] "18 - 24"  "25 - 34"  "35 - 44"  "45 - 54"  "55 - 64"  "Under 18"
age_count <- age_results %>% count(value)
age_count$percentage <- (age_count$n / no_complete_responses) * 100
age_count

gender_results = extract_composite_question_with_factors(raw_data, c("Q4$"), common.id_variables, NULL,
                                        c("4" = "Gender"))
gender_results
gender_count <- gender_results %>% count(value)
gender_count$percentage <- (gender_count$n / no_complete_responses) * 100
gender_count

country_results = extract_composite_question_with_factors(raw_data, c("Q5$"), common.id_variables, NULL,
                                        c("5" = "Country"))
country_results
country_count <- country_results %>% count(value)
country_count$percentage <- (country_count$n / no_complete_responses) * 100
country_count

AR Experience

questionnaire_plot <- function(data, factor_one, factor_two, has_two_factors=FALSE){
  barplotdata <- NULL
  barplotdata <- data
  barplotdata$value_raw <- barplotdata$value
  barplotdata$value_multiplied <- as.numeric(barplotdata$value_raw)
  barplotdata$value_factor <- barplotdata$value_raw
  scale_size = length(levels(barplotdata$value))
  
  barplotdata$value_multiplied = (barplotdata$value_multiplied) * (no_complete_responses/scale_size) # then multiply to scale up
  print(barplotdata$value_raw_multiplied)
  
  app_plot_2 <- ggplot(data = barplotdata, aes_string(x=factor_one)) + common.theme+
      geom_bar(aes(fill=forcats::fct_rev(value_factor)), lwd=0) + coord_flip() +
  
      scale_y_continuous(limits=c(0, no_complete_responses), breaks=c(0,1/4 * no_complete_responses, 1/2 * no_complete_responses, 3/4 * no_complete_responses, no_complete_responses), labels=c("0%", "25%", "50%", "75%", "100%"))+
      stat_summary(aes(y=value_multiplied), fun.data=mean_cl_normal, fun.args = list(conf.int = 0.95), geom="errorbar", colour=CIColor, width=0.4, size=1.0) + #
      stat_summary(aes(y=value_multiplied), fun.y=mean, geom="point", colour=CIColor)+
      scale_fill_viridis_d(option = "D", drop=FALSE)+
      guides(fill = guide_legend(label.position = "bottom", reverse = TRUE, nrow=1))+
    
      xlab("")+ ylab("# of Responses")# + facet_wrap(~interactiontechnique, nrow=6)
  
  
  if (has_two_factors){
    app_plot_2 <- app_plot_2 + facet_wrap( as.formula(paste( "~", factor_two )), labeller = labeller(.rows = label_wrap_gen(20)))
  }
  
    #ExportPlot(app_plot_2, "acceptability_plot.png", 8, 20, doPDF=TRUE)
    #print(app_plot_2)
    #print(ggplot_build(app_plot_2)$data[[3]])
  return(app_plot_2)
}

#https://cran.r-project.org/web/packages/ggsignif/vignettes/intro.html 
#https://cran.r-project.org/web/packages/ARTool/vignettes/art-contrasts.html

filter_contrasts <- function(contrasts){
  result = as.data.frame(summary(contrasts))
  result = subset(result, p.value <= 0.05)
}

stats_testing <-function(data, value_order, two_factor=FALSE) {
  #data$ParticipantID <- factor(data$ParticipantID)
  #data$value <- factor(data$value, ordered = TRUE, levels = value_order)
  
  if (!two_factor){
    model.result <- art(value ~ factor_one + Error(ParticipantID), data=data)
    model.aov<-anova(model.result)
    model.contrasts<- art.con(model.result, "factor_one")
    #model.df <- as.data.frame(summary(model.contrasts))
    
    output <- list(
      model.result,
      model.aov,
      model.contrasts,
      filter_contrasts(model.contrasts)
    )
    return(output)

  } else {
    model.result <- art(value ~ factor_one*factor_two + Error(ParticipantID), data=data)
    anova_result<-anova(model.result)
    model.df_1 <- art.con(model.result, "factor_one")
    model.df_2 <- art.con(model.result, "factor_two")
    
    output<-list(
      model.result,
      anova_result,
      model.df_1,
      filter_contrasts(model.df_1),
      model.df_2,
      filter_contrasts(model.df_2)
      )
    
    return(output)
    
    #print(art.con(model.result, "factor_one"))
    #print(art.con(model.result, "factor_two"))

  }
  #return(model)
}
ar_experience_results_q6 = extract_composite_question_with_factors(raw_data, c("Q6$"), common.id_variables, NULL,
                                        c("6"  = "Know what AR is"))

ar_experience_results_q6$value <- revalue(factor(ar_experience_results_q6$value), c( 
"I don't know" = "I don't know",                                                                                  
"No" = "No",                                                                                            
"Yes, but smartphone AR only (e.g. instagram filters, snapchat lenses, IKEA furniture app etc.)" =  "Yes, but\nsmartphone\nAR only",
"Yes, including AR headsets"  = "Yes, inc.\nAR headsets"
  ))

value_order = c(
"No",
"I don't know", 
"Yes, but\nsmartphone\nAR only",     
 "Yes, inc.\nAR headsets"
)

ar_experience_results_q6$value <- factor(ar_experience_results_q6$value, ordered = TRUE, levels = value_order)

ar_experience_results_q6$variable <- "Used AR Before"
q6_plot <- questionnaire_plot(ar_experience_results_q6, "variable")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(q6_plot)

q6_count <- ar_experience_results_q6 %>% count(value)
q6_count$percentage <- (q6_count$n / no_complete_responses) * 100


#ar_experience_results_q7 = extract_composite_question_with_factors(raw_data, c("Q7$"), common.id_variables, 
#    c("No", 
#      "Yes, but smartphone AR only (e.g. instagram filters, snapchat lenses, IKEA furniture app etc.)",
#        "Yes, including AR headsets"),
#    c("7" = "Used AR Previously"))


ar_experience_results_q7 = extract_composite_question_with_factors(raw_data, c("Q7$"), common.id_variables, 
    NULL,
    c("7" = "Used AR Previously"))



ar_experience_results_q7$value <- revalue(factor(ar_experience_results_q7$value), c( 
"No" = "No",
"Sort of" = "Sort of\n\n",
"Yes" = "Yes"
  ))


ar_experience_results_q7$variable <- "Know what AR is"
q7_plot <- questionnaire_plot(ar_experience_results_q7, "variable")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(q7_plot)

q7_count <- ar_experience_results_q7 %>% count(value)
q7_count$percentage <- (q7_count$n / no_complete_responses) * 100

print(q6_count)
print(q7_count)
NA

Combination of intro questions


q6_plot_mod <- q6_plot + theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank()) + ggtitle("Used AR Before?")
  
 q7_plot_mod <- q7_plot + theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank()) + ggtitle("Know what an AR headset is?")
 
knowledge_combi <- plot_grid(q6_plot_mod, q7_plot_mod,
          ncol = 2, rel_widths = c(1.0,1.0), rel_heights = c(1.0, 1.0))

print(knowledge_combi)
ExportPlot(knowledge_combi, "knowledge_combi", 9.5, 2.1, doPDF=TRUE)

LOOPING QUESTIONS

Knowledge of AR capability

Did you know AR headsets have this capability?

know_capability.results = extract_composite_question_with_factors(raw_data, c("Q11", "Q23"), common.id_variables, NULL,
                                        c("11" = "know_capability", "27" = "know_capability"),
                                        common.loopfactor)
attributes are not identical across measure variables; they will be droppedThe following `from` values were not present in `x`: 27
know_capability.results$factor_one <- fct_rev(fct_relevel( know_capability.results$factor_one, common.looporder))

know_capability.results$value <- revalue(factor(know_capability.results$value), c( 
  "I did not know AR headsets could do this" = "Did not know",
  "I was somewhat aware AR headsets could do this" = "Somewhat aware",
  "I knew AR headsets could do this" = "Aware"
  ))

know_capability.results$value <- fct_relevel( know_capability.results$value, c("Did not know", "Somewhat aware", "Aware"))

know_capability.plot <- questionnaire_plot(know_capability.results, "factor_one") + ggtitle("Did you know AR headsets have this capability?")
NULL
`fun.y` is deprecated. Use `fun` instead.
ExportPlot(know_capability.plot, "know_capability_plot", 8.5, 3.5, doPDF=TRUE)
print(know_capability.plot)


know_capability.results$value <- factor(know_capability.results$value, ordered = TRUE, levels = c(
  "Did not know", 
  "Somewhat aware",
  "Aware"  
))

model_result<- stats_testing(know_capability.results, NULL, FALSE)
NOTE: Results are based on intra-block estimates and are biased.
print(model_result[2])
[[1]]
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Repeated Measures Analysis of Variance Table (Type I) 
Model: Repeated Measures (aov)
Response: art(value)

             Error Df Df.res  F value  Pr(>F)    
1 factor_one PrtID  1    100  0.25987 0.61134    
2 factor_one Withn 10   1009 48.57530 < 2e-16 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
print(model_result[4])
[[1]]
                                          contrast   estimate       SE   df    t.ratio      p.value
2      Augmented perception - Augmented appearance -298.75183 28.62762 1009 -10.435792 9.560130e-13
5              Augmented perception - Biometric ID -219.36948 28.62762 1009  -7.662863 3.275047e-12
8         Augmented perception - Activity tracking -115.17831 28.62762 1009  -4.023329 2.996870e-03
9          Augmented perception - Microphone usage -305.57536 28.62762 1009 -10.674147 9.503509e-13
10             Augmented perception - Camera usage -381.14889 28.62762 1009 -13.314029 8.499867e-13
11       Diminished reality - Augmented appearance -305.39706 28.54999 1009 -10.696925 9.500178e-13
14               Diminished reality - Biometric ID -226.01471 28.54999 1009  -7.916456 1.324718e-12
17          Diminished reality - Activity tracking -121.82353 28.54999 1009  -4.267026 1.092701e-03
18           Diminished reality - Microphone usage -312.22059 28.54999 1009 -10.935928 9.262591e-13
19               Diminished reality - Camera usage -387.79412 28.54999 1009 -13.582988 8.499867e-13
20      Augmented appearance - Physiological state  287.23529 28.54999 1009  10.060786 9.541257e-13
21           Augmented appearance - Internal state  276.51471 28.54999 1009   9.685284 9.529044e-13
23 Augmented appearance - Personal characteristics  226.45588 28.54999 1009   7.931909 1.284084e-12
24       Augmented appearance - Volumetric capture  226.80882 28.54999 1009   7.944271 1.254996e-12
25        Augmented appearance - Activity tracking  183.57353 28.54999 1009   6.429899 1.079970e-08
29              Physiological state - Biometric ID -207.85294 28.54999 1009  -7.280317 3.772238e-11
32         Physiological state - Activity tracking -103.66176 28.54999 1009  -3.630887 1.320539e-02
33          Physiological state - Microphone usage -294.05882 28.54999 1009 -10.299789 9.565682e-13
34              Physiological state - Camera usage -369.63235 28.54999 1009 -12.946849 8.499867e-13
35                   Internal state - Biometric ID -197.13235 28.54999 1009  -6.904814 4.889444e-10
38              Internal state - Activity tracking  -92.94118 28.54999 1009  -3.255384 4.573796e-02
39               Internal state - Microphone usage -283.33824 28.54999 1009  -9.924286 9.550138e-13
40                   Internal state - Camera usage -358.91176 28.54999 1009 -12.571347 8.499867e-13
41         Biometric ID - Personal characteristics  147.07353 28.54999 1009   5.151440 1.673514e-05
42               Biometric ID - Volumetric capture  147.42647 28.54999 1009   5.163802 1.569988e-05
43                Biometric ID - Activity tracking  104.19118 28.54999 1009   3.649430 1.236244e-02
45                     Biometric ID - Camera usage -161.77941 28.54999 1009  -5.666532 1.036488e-06
48     Personal characteristics - Microphone usage -233.27941 28.54999 1009  -8.170912 1.028067e-12
49         Personal characteristics - Camera usage -308.85294 28.54999 1009 -10.817972 9.404699e-13
51           Volumetric capture - Microphone usage -233.63235 28.54999 1009  -8.183274 1.022293e-12
52               Volumetric capture - Camera usage -309.20588 28.54999 1009 -10.830334 9.384715e-13
53            Activity tracking - Microphone usage -190.39706 28.54999 1009  -6.668902 2.329409e-09
54                Activity tracking - Camera usage -265.97059 28.54999 1009  -9.315962 9.583445e-13

FROM THE PERSPECTIVE OF THE BYSTANDER

Concern with AR

concern.results = extract_composite_question_with_factors(raw_data, c("Q15", "Q27"), common.id_variables, NULL,
                                        c("15" = "concern", "27" = "concern"),
                                        common.loopfactor)
attributes are not identical across measure variables; they will be dropped
concern.results$factor_one <- fct_rev(fct_relevel( concern.results$factor_one, common.looporder))

concern.results 
levels(factor(concern.results$value))
[1] "Neutral"             "Somewhat concerning" "Unconcerning"        "Very concerning"     "Very unconcerning"  
value_order = c(
  "Very unconcerning" ,
  "Unconcerning" ,
  "Neutral" ,
  "Somewhat concerning",
  "Very concerning"
)

concern.results$value <- factor(concern.results$value, ordered = TRUE, levels = value_order)


concern.results$value <- revalue(factor(concern.results$value), c( 
  "Very unconcerning" = "Very\nunconcerning",
  "Unconcerning" = "Unconcerning",
  "Neutral" = "Neutral",
  "Somewhat concerning" = "Somewhat\nconcerning\n ",
  "Very concerning" = "Very\nconcerning"
  ))

concern.stats_results <- stats_testing(concern.results, NULL, FALSE)
print(concern.stats_results[2])
[[1]]
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Repeated Measures Analysis of Variance Table (Type I) 
Model: Repeated Measures (aov)
Response: art(value)

             Error Df Df.res F value     Pr(>F)    
1 factor_one Withn 10   1010  29.711 < 2.22e-16 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
print(concern.stats_results[4])
[[1]]
                                          contrast  estimate       SE   df    t.ratio      p.value
1        Augmented perception - Diminished reality  275.9608 32.84765 1010   8.401235 4.473089e-13
2      Augmented perception - Augmented appearance  227.6225 32.84765 1010   6.929646 4.130342e-10
8         Augmented perception - Activity tracking  148.7696 32.84765 1010   4.529080 3.439291e-04
12        Diminished reality - Physiological state -315.0980 32.84765 1010  -9.592713 4.315437e-13
13             Diminished reality - Internal state -333.6078 32.84765 1010 -10.156218 4.295453e-13
14               Diminished reality - Biometric ID -344.9608 32.84765 1010 -10.501842 4.283240e-13
15   Diminished reality - Personal characteristics -346.1176 32.84765 1010 -10.537061 4.299894e-13
16         Diminished reality - Volumetric capture -355.5245 32.84765 1010 -10.823440 4.179990e-13
17          Diminished reality - Activity tracking -127.1912 32.84765 1010  -3.872155 5.419931e-03
18           Diminished reality - Microphone usage -215.7451 32.84765 1010  -6.568054 4.473874e-09
19               Diminished reality - Camera usage -196.1961 32.84765 1010  -5.972911 1.765652e-07
20      Augmented appearance - Physiological state -266.7598 32.84765 1010  -8.121124 5.325740e-13
21           Augmented appearance - Internal state -285.2696 32.84765 1010  -8.684629 4.223288e-13
22             Augmented appearance - Biometric ID -296.6225 32.84765 1010  -9.030253 4.282130e-13
23 Augmented appearance - Personal characteristics -297.7794 32.84765 1010  -9.065472 4.295453e-13
24       Augmented appearance - Volumetric capture -307.1863 32.84765 1010  -9.351851 4.310996e-13
26         Augmented appearance - Microphone usage -167.4069 32.84765 1010  -5.096465 2.218819e-05
27             Augmented appearance - Camera usage -147.8578 32.84765 1010  -4.501322 3.900433e-04
32         Physiological state - Activity tracking  187.9069 32.84765 1010   5.720558 7.631313e-07
34              Physiological state - Camera usage  118.9020 32.84765 1010   3.619802 1.373321e-02
38              Internal state - Activity tracking  206.4167 32.84765 1010   6.284063 2.686519e-08
39               Internal state - Microphone usage  117.8627 32.84765 1010   3.588164 1.534752e-02
40                   Internal state - Camera usage  137.4118 32.84765 1010   4.183306 1.556591e-03
43                Biometric ID - Activity tracking  217.7696 32.84765 1010   6.629687 3.004171e-09
44                 Biometric ID - Microphone usage  129.2157 32.84765 1010   3.933788 4.270102e-03
45                     Biometric ID - Camera usage  148.7647 32.84765 1010   4.528931 3.441625e-04
47    Personal characteristics - Activity tracking  218.9265 32.84765 1010   6.664906 2.389217e-09
48     Personal characteristics - Microphone usage  130.3725 32.84765 1010   3.969007 3.718907e-03
49         Personal characteristics - Camera usage  149.9216 32.84765 1010   4.564150 2.930480e-04
50          Volumetric capture - Activity tracking  228.3333 32.84765 1010   6.951285 3.569182e-10
51           Volumetric capture - Microphone usage  139.7794 32.84765 1010   4.255386 1.148240e-03
52               Volumetric capture - Camera usage  159.3284 32.84765 1010   4.850528 7.568326e-05
concern.plot <- questionnaire_plot(concern.results, "factor_one") + ggtitle("Concern with Stranger's AR Activity")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(concern.plot)
ExportPlot(concern.plot, "concern_plot", 8.5, 3.5, doPDF=TRUE)

NA
NA

Concern versus smartphone AR

concern_versus_smartphone.results = extract_composite_question_with_factors(raw_data, c("Q16", "Q28"), common.id_variables, NULL,
                                        c("16" = "concern_versus_smartphone", "28" = "concern_versus_smartphone"),
                                        common.loopfactor)
attributes are not identical across measure variables; they will be dropped
concern_versus_smartphone.results$factor_one <- fct_rev(fct_relevel( concern_versus_smartphone.results$factor_one, common.looporder))

#concern_versus_smartphone.results
#levels(factor(concern_versus_smartphone.results$value))


value_order = c(
  "Much less concerning than smartphones" ,
"Somewhat less concerning",              
"About the same",                       
"Somewhat more concerning",   
"Much more concerning than smartphones" 
)
concern_versus_smartphone.results$value <- factor(concern_versus_smartphone.results$value, ordered = TRUE, levels = value_order)

concern_versus_smartphone.results$value <- revalue(factor(concern_versus_smartphone.results$value), c( 
  "Much less concerning than smartphones" = "Much\nless\nconcerning",
"Somewhat less concerning" = "Somewhat\nless\nconcerning",              
"About the same" = "About\nthe same",                       
"Somewhat more concerning" = "Somewhat\nmore\nconcerning",   
"Much more concerning than smartphones" = "Much\nmore\nconcerning" 
  ))


concern_versus_smartphone.stats_results <- stats_testing(concern_versus_smartphone.results, NULL, FALSE) 
print(concern_versus_smartphone.stats_results[2])
[[1]]
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Repeated Measures Analysis of Variance Table (Type I) 
Model: Repeated Measures (aov)
Response: art(value)

             Error Df Df.res F value     Pr(>F)    
1 factor_one Withn 10   1010  11.164 < 2.22e-16 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
print(concern_versus_smartphone.stats_results[4])
[[1]]
                                          contrast  estimate       SE   df   t.ratio      p.value
2      Augmented perception - Augmented appearance  125.6225 31.61321 1010  3.973736 3.650144e-03
12        Diminished reality - Physiological state -133.8333 31.61321 1010 -4.233462 1.260325e-03
13             Diminished reality - Internal state -173.0637 31.61321 1010 -5.474412 3.009718e-06
14               Diminished reality - Biometric ID -164.1422 31.61321 1010 -5.192202 1.354777e-05
15   Diminished reality - Personal characteristics -172.9069 31.61321 1010 -5.469450 3.092365e-06
16         Diminished reality - Volumetric capture -158.8235 31.61321 1010 -5.023961 3.205196e-05
20      Augmented appearance - Physiological state -163.6225 31.61321 1010 -5.175765 1.475435e-05
21           Augmented appearance - Internal state -202.8529 31.61321 1010 -6.416715 1.173115e-08
22             Augmented appearance - Biometric ID -193.9314 31.61321 1010 -6.134504 6.712286e-08
23 Augmented appearance - Personal characteristics -202.6961 31.61321 1010 -6.411753 1.210378e-08
24       Augmented appearance - Volumetric capture -188.6127 31.61321 1010 -5.966264 1.836407e-07
27             Augmented appearance - Camera usage -127.6471 31.61321 1010 -4.037776 2.827854e-03
33          Physiological state - Microphone usage  110.0588 31.61321 1010  3.481419 2.212551e-02
38              Internal state - Activity tracking  138.1912 31.61321 1010  4.371311 6.957330e-04
39               Internal state - Microphone usage  149.2892 31.61321 1010  4.722368 1.401247e-04
43                Biometric ID - Activity tracking  129.2696 31.61321 1010  4.089101 2.297068e-03
44                 Biometric ID - Microphone usage  140.3676 31.61321 1010  4.440158 5.132201e-04
47    Personal characteristics - Activity tracking  138.0343 31.61321 1010  4.366349 7.110215e-04
48     Personal characteristics - Microphone usage  149.1324 31.61321 1010  4.717406 1.434596e-04
50          Volumetric capture - Activity tracking  123.9510 31.61321 1010  3.920860 4.490729e-03
51           Volumetric capture - Microphone usage  135.0490 31.61321 1010  4.271917 1.069999e-03
concern_versus_smartphone.plot <- questionnaire_plot(concern_versus_smartphone.results, "factor_one")  + ggtitle("Concern relative to Smartphone AR") #+ guides(fill = guide_legend(nrow = 2))
NULL
`fun.y` is deprecated. Use `fun` instead.
print(concern_versus_smartphone.plot)
ExportPlot(concern_versus_smartphone.plot, "concern_versus_smartphone_plot", 8.5, 3.5, doPDF=TRUE)

NA
NA

Concern combi plot

concern_versus_smartphone.plot_without_y_labels <- concern_versus_smartphone.plot + 
  theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank())

concern_plot_mod <- concern.plot + theme(legend.justification = c(1,0))

concern_combi_plot <- plot_grid(concern_plot_mod, concern_versus_smartphone.plot_without_y_labels,
          ncol = 2, rel_widths = c(1.5,0.96))

print(concern_combi_plot)

ExportPlot(concern_combi_plot, "concern_combi_plot", 11.5, 4, doPDF=TRUE)

Awareness preference for own headset

awareness_preference_headset_informs_others.results = extract_composite_question_with_factors(raw_data, c("Q20", "Q32"), common.id_variables, NULL,
                                        c("20" = "awareness_preference_headset_informs_others", "32" = "awareness_preference_headset_informs_others"),
                                        common.loopfactor)
attributes are not identical across measure variables; they will be dropped
awareness_preference_headset_informs_others.results$factor_one <- fct_rev(fct_relevel( awareness_preference_headset_informs_others.results$factor_one, common.looporder))

#awareness_preference_headset_informs_others.results 
#levels(factor(awareness_preference_headset_informs_others.results$value))

value_order = c(
"1 - No awareness of activity" ,
"2 - Basic awareness device sensing is active (e.g. LED colour)" ,
"3 - Awareness of activity type sensing is being used for"  ,    
"4 - Full, real-time awareness of what the headset is doing"    
)
awareness_preference_headset_informs_others.results$value <- factor(awareness_preference_headset_informs_others.results$value, ordered = TRUE, levels = value_order)


awareness_preference_headset_informs_others.results$value <- revalue(factor(awareness_preference_headset_informs_others.results$value), c( 
"1 - No awareness of activity" = "No awareness" ,
"2 - Basic awareness device sensing is active (e.g. LED colour)" = "Basic awareness\ndevice active",
"3 - Awareness of activity type sensing is being used for"  = "Awareness of\nactivity type",    
"4 - Full, real-time awareness of what the headset is doing" = "Full, real-time\nawareness"     
  ))

awareness_preference_headset_informs_others.stats_results <- stats_testing(awareness_preference_headset_informs_others.results, NULL, FALSE)
print(awareness_preference_headset_informs_others.stats_results[2])
[[1]]
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Repeated Measures Analysis of Variance Table (Type I) 
Model: Repeated Measures (aov)
Response: art(value)

             Error Df Df.res F value     Pr(>F)    
1 factor_one Withn 10   1010   17.31 < 2.22e-16 ***
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
awareness_preference_headset_informs_others.plot <- questionnaire_plot(awareness_preference_headset_informs_others.results, "factor_one", NULL, FALSE)
NULL
`fun.y` is deprecated. Use `fun` instead.
print(awareness_preference_headset_informs_others.plot)

Combine bystander and user perspectives

combine awareness_preference_headset_informs_others.results and awareness_preference_by_consent.results


awareness_preference_by_consent.results$factor_two <- revalue(factor(awareness_preference_by_consent.results$factor_two), c( 
  "With Consent" = "As a bystander\nwith consent",
  "Without Consent" = "As a bystander\nwithout consent"
  ))

awareness_preference_headset_informs_others.results$factor_two <- "As the \nAR user"

combined_data <- rbind(awareness_preference_by_consent.results,awareness_preference_headset_informs_others.results )

# now combined where factor_two tells us perspective (bystander with consent, without consent, and user)

combined_data.stats_results <- stats_testing(combined_data, NULL, TRUE)
NOTE: Results are based on intra-block estimates and are biased.
NOTE: Results may be misleading due to involvement in interactions
NOTE: Results are based on intra-block estimates and are biased.
NOTE: Results may be misleading due to involvement in interactions
print(combined_data.stats_results[2])
[[1]]
Analysis of Variance of Aligned Rank Transformed Data

Table Type: Repeated Measures Analysis of Variance Table (Type I) 
Model: Repeated Measures (aov)
Response: art(value)

                        Error Df Df.res  F value     Pr(>F)    
1 factor_one            PrtID  1    100  0.44277  0.5073190    
2 factor_one            Withn 10   3228 32.14512 < 2.22e-16 ***
3 factor_two            Withn  2   3228 76.85463 < 2.22e-16 ***
4 factor_one:factor_two Withn 20   3228  1.94639  0.0070543  **
---
Signif. codes:   0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
print(combined_data.stats_results[3])
[[1]]
 contrast                                        estimate   SE   df t.ratio p.value
 Augmented perception - Diminished reality        413.714 55.6 3228   7.437  <.0001
 Augmented perception - Augmented appearance      262.381 55.6 3228   4.716  0.0001
 Augmented perception - Physiological state      -132.755 55.6 3228  -2.386  0.3757
 Augmented perception - Internal state           -100.270 55.6 3228  -1.802  0.7790
 Augmented perception - Biometric ID             -118.877 55.7 3228  -2.133  0.5534
 Augmented perception - Personal characteristics -130.553 55.7 3228  -2.343  0.4048
 Augmented perception - Volumetric capture       -245.448 55.6 3228  -4.412  0.0005
 Augmented perception - Activity tracking         216.253 55.6 3228   3.887  0.0049
 Augmented perception - Microphone usage          215.927 55.6 3228   3.881  0.0050
 Augmented perception - Camera usage              294.595 55.6 3228   5.295  <.0001
 Diminished reality - Augmented appearance       -151.333 55.6 3228  -2.720  0.1911
 Diminished reality - Physiological state        -546.469 55.6 3228  -9.823  <.0001
 Diminished reality - Internal state             -513.984 55.6 3228  -9.239  <.0001
 Diminished reality - Biometric ID               -532.591 55.7 3228  -9.557  <.0001
 Diminished reality - Personal characteristics   -544.267 55.7 3228  -9.766  <.0001
 Diminished reality - Volumetric capture         -659.162 55.6 3228 -11.849  <.0001
 Diminished reality - Activity tracking          -197.461 55.6 3228  -3.549  0.0171
 Diminished reality - Microphone usage           -197.788 55.6 3228  -3.555  0.0168
 Diminished reality - Camera usage               -119.119 55.6 3228  -2.141  0.5475
 Augmented appearance - Physiological state      -395.136 55.6 3228  -7.103  <.0001
 Augmented appearance - Internal state           -362.650 55.6 3228  -6.519  <.0001
 Augmented appearance - Biometric ID             -381.258 55.7 3228  -6.841  <.0001
 Augmented appearance - Personal characteristics -392.933 55.7 3228  -7.051  <.0001
 Augmented appearance - Volumetric capture       -507.828 55.6 3228  -9.128  <.0001
 Augmented appearance - Activity tracking         -46.127 55.6 3228  -0.829  0.9991
 Augmented appearance - Microphone usage          -46.454 55.6 3228  -0.835  0.9991
 Augmented appearance - Camera usage               32.214 55.6 3228   0.579  1.0000
 Physiological state - Internal state              32.485 55.6 3228   0.584  1.0000
 Physiological state - Biometric ID                13.878 55.7 3228   0.249  1.0000
 Physiological state - Personal characteristics     2.202 55.7 3228   0.040  1.0000
 Physiological state - Volumetric capture        -112.693 55.6 3228  -2.026  0.6309
 Physiological state - Activity tracking          349.008 55.6 3228   6.274  <.0001
 Physiological state - Microphone usage           348.681 55.6 3228   6.268  <.0001
 Physiological state - Camera usage               427.350 55.6 3228   7.682  <.0001
 Internal state - Biometric ID                    -18.607 55.7 3228  -0.334  1.0000
 Internal state - Personal characteristics        -30.283 55.7 3228  -0.543  1.0000
 Internal state - Volumetric capture             -145.178 55.6 3228  -2.610  0.2439
 Internal state - Activity tracking               316.523 55.6 3228   5.690  <.0001
 Internal state - Microphone usage                316.196 55.6 3228   5.684  <.0001
 Internal state - Camera usage                    394.864 55.6 3228   7.098  <.0001
 Biometric ID - Personal characteristics          -11.676 55.8 3228  -0.209  1.0000
 Biometric ID - Volumetric capture               -126.571 55.7 3228  -2.271  0.4542
 Biometric ID - Activity tracking                 335.130 55.7 3228   6.013  <.0001
 Biometric ID - Microphone usage                  334.803 55.7 3228   6.008  <.0001
 Biometric ID - Camera usage                      413.472 55.7 3228   7.419  <.0001
 Personal characteristics - Volumetric capture   -114.895 55.7 3228  -2.062  0.6051
 Personal characteristics - Activity tracking     346.806 55.7 3228   6.223  <.0001
 Personal characteristics - Microphone usage      346.479 55.7 3228   6.217  <.0001
 Personal characteristics - Camera usage          425.148 55.7 3228   7.629  <.0001
 Volumetric capture - Activity tracking           461.701 55.6 3228   8.299  <.0001
 Volumetric capture - Microphone usage            461.374 55.6 3228   8.293  <.0001
 Volumetric capture - Camera usage                540.043 55.6 3228   9.707  <.0001
 Activity tracking - Microphone usage              -0.327 55.6 3228  -0.006  1.0000
 Activity tracking - Camera usage                  78.341 55.6 3228   1.408  0.9466
 Microphone usage - Camera usage                   78.668 55.6 3228   1.414  0.9452

Results are averaged over the levels of: factor_two 
P value adjustment: tukey method for comparing a family of 11 estimates 
print(combined_data.stats_results[4])
[[1]]
                                          contrast  estimate       SE   df    t.ratio      p.value
1        Augmented perception - Diminished reality  413.7141 55.63200 3228   7.436621 0.000000e+00
2      Augmented perception - Augmented appearance  262.3807 55.63200 3228   4.716364 1.321656e-04
7        Augmented perception - Volumetric capture -245.4477 55.63200 3228  -4.411988 5.444269e-04
8         Augmented perception - Activity tracking  216.2533 55.63200 3228   3.887210 4.923185e-03
9          Augmented perception - Microphone usage  215.9265 55.63200 3228   3.881336 5.037014e-03
10             Augmented perception - Camera usage  294.5948 55.63200 3228   5.295420 6.864245e-06
12        Diminished reality - Physiological state -546.4690 55.63200 3228  -9.822926 0.000000e+00
13             Diminished reality - Internal state -513.9837 55.63200 3228  -9.238994 0.000000e+00
14               Diminished reality - Biometric ID -532.5911 55.73004 3228  -9.556625 0.000000e+00
15   Diminished reality - Personal characteristics -544.2669 55.73004 3228  -9.766131 0.000000e+00
16         Diminished reality - Volumetric capture -659.1618 55.63200 3228 -11.848609 0.000000e+00
17          Diminished reality - Activity tracking -197.4608 55.63200 3228  -3.549410 1.711996e-02
18           Diminished reality - Microphone usage -197.7876 55.63200 3228  -3.555285 1.677326e-02
20      Augmented appearance - Physiological state -395.1356 55.63200 3228  -7.102668 0.000000e+00
21           Augmented appearance - Internal state -362.6503 55.63200 3228  -6.518737 2.963598e-09
22             Augmented appearance - Biometric ID -381.2578 55.73004 3228  -6.841154 0.000000e+00
23 Augmented appearance - Personal characteristics -392.9335 55.73004 3228  -7.050659 0.000000e+00
24       Augmented appearance - Volumetric capture -507.8284 55.63200 3228  -9.128352 0.000000e+00
32         Physiological state - Activity tracking  349.0082 55.63200 3228   6.273515 2.041322e-08
33          Physiological state - Microphone usage  348.6814 55.63200 3228   6.267641 2.124633e-08
34              Physiological state - Camera usage  427.3497 55.63200 3228   7.681725 0.000000e+00
38              Internal state - Activity tracking  316.5229 55.63200 3228   5.689583 7.561149e-07
39               Internal state - Microphone usage  316.1961 55.63200 3228   5.683709 7.822863e-07
40                   Internal state - Camera usage  394.8644 55.63200 3228   7.097793 0.000000e+00
43                Biometric ID - Activity tracking  335.1303 55.73004 3228   6.013459 1.091119e-07
44                 Biometric ID - Microphone usage  334.8035 55.73004 3228   6.007595 1.131367e-07
45                     Biometric ID - Camera usage  413.4718 55.73004 3228   7.419191 0.000000e+00
47    Personal characteristics - Activity tracking  346.8061 55.73004 3228   6.222965 2.867589e-08
48     Personal characteristics - Microphone usage  346.4793 55.73004 3228   6.217101 2.981168e-08
49         Personal characteristics - Camera usage  425.1476 55.73004 3228   7.628697 0.000000e+00
50          Volumetric capture - Activity tracking  461.7010 55.63200 3228   8.299199 0.000000e+00
51           Volumetric capture - Microphone usage  461.3742 55.63200 3228   8.293324 0.000000e+00
52               Volumetric capture - Camera usage  540.0425 55.63200 3228   9.707408 0.000000e+00
print(combined_data.stats_results[5])
[[1]]
   contrast                                                     estimate   SE   df t.ratio p.value
 As a bystander\nwith consent - As a bystander\nwithout consent   -347.8 29.8 3228 -11.673  <.0001
 As a bystander\nwith consent - As the \nAR user                   -66.2 29.8 3228  -2.224  0.0674
 As a bystander\nwithout consent - As the \nAR user                281.5 29.8 3228   9.454  <.0001

Results are averaged over the levels of: factor_one 
P value adjustment: tukey method for comparing a family of 3 estimates 
print(combined_data.stats_results[6])
[[1]]
                                                        contrast  estimate       SE   df    t.ratio p.value
1 As a bystander\nwith consent - As a bystander\nwithout consent -347.7644 29.79183 3228 -11.673146       0
3             As a bystander\nwithout consent - As the \nAR user  281.5423 29.77937 3228   9.454273       0
combined_data.plot <- questionnaire_plot(combined_data, "factor_one", "factor_two", TRUE) + ggtitle("Preference Toward Awareness of AR Activity...")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(combined_data.plot)

ExportPlot(combined_data.plot, "awareness_preferences_combined_plot", 9, 4, doPDF=TRUE)

EXIT QUESTIONS

Comfort with AR (less/more)

more_or_less_comfortable_with_ar.results = extract_composite_question_with_factors(raw_data, c("Q34"), common.id_variables, 
                                        c("34" = "more_less_comfortable"))

more_or_less_comfortable_with_ar.results

value_order = c(
"Much more uncomfortable",
"More uncomfortable", 
"Neutral / No change",     
"More comfortable",
"Much more comfortable"
)

more_or_less_comfortable_with_ar.results$value <- factor(more_or_less_comfortable_with_ar.results$value, ordered = TRUE, levels = value_order)

more_or_less_comfortable_with_ar.results$value <- revalue(factor(more_or_less_comfortable_with_ar.results$value), c( 
"Much more uncomfortable" = "Much more\n uncomfortable" ,
"More uncomfortable" = "More \nuncomfortable", 
"Neutral / No change" = "Neutral /\nNo change",     
"More comfortable" = "More\ncomfortable",
"Much more comfortable" = "Much more\ncomfortable"
  ))


more_or_less_comfortable_with_ar.plot <- questionnaire_plot(more_or_less_comfortable_with_ar.results, "factor_one", NULL, FALSE) +  
  theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank()) + ggtitle("Retrospective - More or less comfortable with AR")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(more_or_less_comfortable_with_ar.plot)

Comfort with AR generally

how_comfortable_with_ar.results = extract_composite_question_with_factors(raw_data, c("Q35"), common.id_variables, 
                                        c("35" = "how_comfortable_with_ar"))

how_comfortable_with_ar.results

value_order = c(
"Extremely uncomfortable" ,
"Somewhat uncomfortable" ,
 "Neither comfortable nor uncomfortable" ,
 "Somewhat comfortable"    ,
"Extremely comfortable"   
)

how_comfortable_with_ar.results$value <- factor(how_comfortable_with_ar.results$value, ordered = TRUE, levels = value_order)

how_comfortable_with_ar.results$value <- revalue(factor(how_comfortable_with_ar.results$value), c( 
"Extremely uncomfortable" = "Extremely\nuncomfortable",
"Somewhat uncomfortable" = "Somewhat\nuncomfortable",
 "Neither comfortable nor uncomfortable" ="Neither comfortable\nnor uncomfortable",
 "Somewhat comfortable" ="Somewhat\ncomfortable" ,
"Extremely comfortable" = "Extremely\ncomfortable"  
  ))

how_comfortable_with_ar.plot <- questionnaire_plot(how_comfortable_with_ar.results, "factor_one", NULL, FALSE) +  
  theme(axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank()) + ggtitle("Retrospective - Comfort with Everyday Augmented Reality")
NULL
`fun.y` is deprecated. Use `fun` instead.
print(how_comfortable_with_ar.plot)

Combined comfort


comfort_combi <- plot_grid(more_or_less_comfortable_with_ar.plot, how_comfortable_with_ar.plot,
          ncol = 2, rel_widths = c(1.0,1.0))

print(comfort_combi)
ExportPlot(comfort_combi, "comfort_combi", 11.5, 2, doPDF=TRUE)
LS0tDQp0aXRsZTogIkFSIGNvbnNlbnQgYW5kIGF3YXJlbmVzcyBzdXJ2ZXkgMjAyMSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQojIEF1dGhvcnMNCkpvc2VwaCBPJ0hhZ2FuIFNjaG9vbCBvZiBDb21wdXRpbmcgU2NpZW5jZSwgVW5pdmVyc2l0eSBvZiBHbGFzZ293LCBHbGFzZ293LCBVbml0ZWQgS2luZ2RvbQ0KUGVqbWFuIFNhZWdoZSBTY2hvb2wgb2YgQ29tcHV0ZXIgU2NpZW5jZSwgVW5pdmVyc2l0eSBvZiBHbGFzZ293LCBHbGFzZ293LCBMYW5hcmtzaGlyZSwgVW5pdGVkIEtpbmdkb20sIHBlam1hbi5zYWVnaGVAZ2xhc2dvdy5hYy51aw0KSmFuIEd1Z2VuaGVpbWVyIFTDqWzDqWNvbSBQYXJpcyAtIExUQ0ksIEluc3RpdHV0IFBvbHl0ZWNobmlxdWUgZGUgUGFyaXMsIFBhcmlzLCBGcmFuY2UNCkRyIERhbmllbCBNZWRlaXJvcyBTY2hvb2wgb2YgQ29tcHV0aW5nIFNjaWVuY2UsIFVuaXZlcnNpdHkgb2YgR2xhc2dvdywgR2xhc2dvdywgVW5pdGVkIEtpbmdkb20sIGRhbmllbC5waXJlc2Rlc2FtZWRlaXJvc0BnbGFzZ293LmFjLnVrDQpLYXJvbGEgTWFya3kgVW5pdmVyc2l0eSBvZiBHbGFzZ293LCBHbGFzZ293LCBHZXJtYW55LCBrYXJvbGEubWFya3lAZ2xhc2dvdy5hYy51aw0KRHIuIE1vaGFtZWQgS2hhbWlzIFVuaXZlcnNpdHkgb2YgR2xhc2dvdywgR2xhc2dvdywgVW5pdGVkIEtpbmdkb20NCkRyIE1hcmsgTWNHaWxsIFNjaG9vbCBvZiBDb21wdXRpbmcgU2NpZW5jZSwgVW5pdmVyc2l0eSBvZiBHbGFzZ293LCBHbGFzZ293LCBMYW5hcmtzaGlyZSwgVW5pdGVkIEtpbmdkb20sIG1hcmsubWNnaWxsQGdsYXNnb3cuYWMudWsNCg0KDQojIE92ZXJ2aWV3DQpUaGlzIGRhdGEgaXMgZm9yIG91ciBBQ00gSU1XVVQgMjAyMiBwYXBlciAiUHJpdmFjeS1FbmhhbmNpbmcgVGVjaG5vbG9neSBhbmQgRXZlcnlkYXkgQXVnbWVudGVkIFJlYWxpdHk6IFVuZGVyc3RhbmRpbmcgQnlzdGFuZGVycycgVmFyeWluZyBOZWVkcyBmb3IgQXdhcmVuZXNzIGFuZCBDb25zZW50Ii4NCg0KVGhpcyB3YXMgYSByYXRoZXIgY29tcGxleCBzdXJ2ZXksIHdpdGggbXVsdGlwbGUgbG9vcGluZyBmYWN0b3JzLiBUaGlzIFJNYXJrZG93biBmaWxlIGNvbnRhaW5zIG91ciBicmVha2Rvd24gYW5kIGFuYWx5c2lzIG9mIHRoZSBxdWVzaXRvbnMgaW4gdGhlIHN1cnZleS4gU2VlIGFsc28gdGhlIGF0dGFjaG1lbnQgb2YgdGhlIHN1cnZleSBQREYuIA0KDQoNCiMgTUFQUElOR1MNCi0tLS0tLS0tLS0tLS0tDQpGb3IgZGVtb2dyYXBoaWNzDQotLS0tLS0tLS0tLS0tLQ0KMyBhZ2UNCjQgZ2VuZGVyDQo1IGNvdW50cnkNCjYgaGF2ZSB5b3UgdXNlZCBBUiBiZWZvcmUNCjcgZG8geW91IGtub3cgd2hhdCBhbiBhciBoZWFkc2V0IGlzDQoNCi0tLS0tLS0tLS0tLS0tDQpRdWVzdGlvbiBtYXBwaW5ncyBmb3IgbG9vcGVkIHF1ZXN0aW9ucw0KLS0tLS0tLS0tLS0tLS0NCmNhcGFiaWxpdHkgMTEgMjMNCmNvbnNlbnQgYnkgc29jaWFsIGNvbm5lY3Rpb24gMTMgMjUNCmF1dG9tYXRpYyBjb25zZW50IDE0IDI2DQpjb25jZXJuaW5nIDE1IDI3DQptb3JlIGNvbmNlcm5pbmcgdGhhbiBzbWFydHBob25lIDE2IDI4DQpzdHJhbmdlciBhd2FyZW5lc3MgcHJlZmVyZW5jZSAxOCAzMA0KeW91ciBoZWFkc2V0IGF3YXJlbmVzcyBwcmVmZXJlbmNlIDIwIDMyDQoNCi0tLS0tLS0tLS0tLS0NCkVuZGluZyBxdWVzdGlvbnMNCi0tLS0tLS0tLS0tLS0NCjM0IG1vcmUgb3IgbGVzcyB1bmNvbWZvcnRhYmxlIHdpdGggQVINCjM1IGhvdyBjb21vcnRhYmxlIGFyZSB5b3UNCi0tLS0tLS0tLS0tLS0tLQ0KDQojIyMgQmVoaW5kIHRoZSBzY2VuZXMNCiMgU0VUVVANCmBgYHtyfQ0KbGlicmFyeShxdWFsdFJpY3MpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShwbHlyKQ0KbGlicmFyeShkcGx5cikgDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KEFSVG9vbCkNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoc3RhdHNFeHByZXNzaW9ucykNCmxpYnJhcnkoY293cGxvdCkgDQpsaWJyYXJ5KHNjYWxlcykNCg0KcmF3X2RhdGEgPC0gcmVhZF9zdXJ2ZXkoImNsZWFuZWRfZGF0YS5jc3YiKQ0KcmF3X2RhdGEkUGFydGljaXBhbnRJRCA8LSBzZXEuaW50KG5yb3cocmF3X2RhdGEpKQ0KaGVhZChyYXdfZGF0YSkNCnJhd19kYXRhIDwtIHN1YnNldChyYXdfZGF0YSwgUHJvZ3Jlc3MgPT0gMTAwKQ0Kbm9fY29tcGxldGVfcmVzcG9uc2VzID0gbnJvdyhyYXdfZGF0YSkNCmBgYA0KIyBVVElMSVRZIEZVTkNUSU9OIC8gVEVTVElORw0KYGBge3J9DQojZGF0YSA9IHJhd19kYXRhDQojcXVlc3Rpb25zX3RvX3NlbGVjdCA9ICBjKCJRMjEiLCAiUTIyIiwgIlE0MiIpDQojcXVlc3Rpb25fZmFjdG9yX2xldmVscyA9ICBjKCIyMSIgID0gIkFnZSIsICIyMiIgPSAiR2VuZGVyIiwgIjQyIiA9ICJDb3VudHJ5IikNCiNpZF92YXJpYWJsZXMgPSBjKCJQYXJ0aWNpcGFudElEIikNCiNmYWN0b3Jfb25lX2xldmVscyA9IGxvb3AuZmFjdG9yDQojZmFjdG9yX3R3b19sZXZlbHMgPSBOVUxMDQoNCkV4cG9ydFBsb3QgPC0gZnVuY3Rpb24oZ3Bsb3QsIGZpbGVuYW1lLCB3aWR0aD0yLCBoZWlnaHQ9MS41LCBkb1BORz1UUlVFLCBkb1BERj1GQUxTRSwgZG9FUFM9RkFMU0UpIHsNCiAgIyBFeHBvcnQgcGxvdCBpbiBQREYgYW5kIEVQUy4NCiAgIyBOb3RpY2UgdGhhdCBBNDogd2lkdGg9MTEuNjksIGhlaWdodD04LjI3DQogIGlmIChkb1BERil7DQogICAgZ2dzYXZlKHBhc3RlKGZpbGVuYW1lLCAnLnBkZicsIHNlcD0iIiksIGdwbG90LCB3aWR0aCA9IHdpZHRoLCBoZWlnaHQgPSBoZWlnaHQpDQogIH0NCiAgDQogIGlmIChkb0VQUyl7DQogICAgcG9zdHNjcmlwdChmaWxlID0gcGFzdGUoZmlsZW5hbWUsICcuZXBzJywgc2VwPSIiKSwgd2lkdGggPSB3aWR0aCwgaGVpZ2h0ID0gaGVpZ2h0LCBob3Jpem9udGFsID0gRkFMU0UsIG9uZWZpbGUgPSBGQUxTRSwgcGFwZXIgPSAic3BlY2lhbCIpDQogIH0NCiAgI3ByaW50KGdwbG90KQ0KICAjZGV2Lm9mZigpDQogIGlmIChkb1BORyl7DQogICAgI3BuZyhmaWxlID0gcGFzdGUoZmlsZW5hbWUsICdfLnBuZycsIHNlcD0iIiksIHdpZHRoID0gd2lkdGggKiAxMDAsIGhlaWdodCA9IGhlaWdodCAqIDEwMCkNCiAgICBnZ3NhdmUocGFzdGUoZmlsZW5hbWUsICdfLnBuZycsIHNlcD0iIiksIGdwbG90LCB3aWR0aCA9IHdpZHRoLCBoZWlnaHQgPSBoZWlnaHQpDQogIH0NCiAgI3ByaW50KGdwbG90KQ0KICAjZGV2Lm9mZigpDQp9DQoNCiMgZGVmaW5lIGZhY3RvciBsZXZlbHMgYWxhIGMoQ29uZ3J1ZW50ICA9ICJDb24iLCBJbkNvbmdydWVudCA9ICJJbkNvbiIpDQpleHRyYWN0X2NvbXBvc2l0ZV9xdWVzdGlvbl93aXRoX2ZhY3RvcnMgPC0gZnVuY3Rpb24oZGF0YSwgcXVlc3Rpb25zX3RvX3NlbGVjdCwgaWRfdmFyaWFibGVzLCB2YWx1ZV9vcmRlciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlc3Rpb25fZmFjdG9yX2xldmVscyAgPSBOVUxMLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yX29uZV9sZXZlbHMgID0gTlVMTCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3Rvcl90d29fbGV2ZWxzICA9IE5VTEwpIHsNCiAgDQogICMgc2VsZWN0IHN1YnNldCBvZiBxdWVzdGlvbnMgd2UgYXJlIGxvb2tpbmcgYXQgYW5kIElEIHZhcmlhYmxlcw0KICBkYXRhX3N1YnNldCA8LSBzZWxlY3QoZGF0YSxtYXRjaGVzKCBhcHBlbmQoaWRfdmFyaWFibGVzLCBxdWVzdGlvbnNfdG9fc2VsZWN0KSkpIA0KDQogICMgbm93IGZsYXR0ZW4gdGhpcyBsaXN0IHVzaW5nIG1lbHQsIGV4Y2x1ZGluZyBJRCB2YXJpYWJsZXMNCiAgbWVsdGVkX2RhdGFfc3Vic2V0IDwtIG1lbHQoZGF0YV9zdWJzZXQsIGlkLnZhcnM9aWRfdmFyaWFibGVzKQ0KICAjcHJpbnQobWVsdGVkX2RhdGFfc3Vic2V0KQ0KICANCiAgIyB0aGVuIHdlIG5lZWQgdG8gc2V0IHRoZSBmYWN0b3IgbGV2ZWxzIGZvciB0aGUgdmFyaW91cyBmYWN0b3JzIGluIG91ciBxdWVzdGlvbm5haXJlLg0KICAjIFRoaXMgbWlnaHQgYmUgZW5jb2RlZCBpbiB0aGUgcXVlc3Rpb24gKGUuZy4gcTM0IGxvb2tpbmcgYXQgYnlzdGFuZGVyIHBlcnNwZWN0aXZlLCBRMzUgbG9va2luZyBhdCB1c2VyIHBlcnNwZWN0aXZlKQ0KICAjIE9yIG1pZ2h0IGJlIGV4cGxpY2l0bHkgY29kZWQgZm9yIChlLmcuIGEgcXVlc3Rpb24gbG9vcCwgb3Igcm93cyBpbiBhIHF1ZXN0aW9uKQ0KICAjIFRoaXMgaXMgYWxsIGVuY29kZWQgaW4gdGhlIHF1ZXN0aW9uIHN0cmluZyBlLmcuICI0X1E2NF8xIiB3aGVyZQ0KICAjICAgNCBpbmRpY2F0ZXMgbGV2ZWwgb2YgZmlyc3QgZmFjdG9yDQogICMgICA1NCBpbmRpY2F0ZXMgbGV2ZWwgb2YgcXVlc3Rpb24gZmFjdG9yDQogICMgICAxIGluZGljYXRlcyBsZXZlbCBvZiB0aGlyZCBmYWN0b3INCiAgDQogIGlmIChleGlzdHMoInF1ZXN0aW9uX2ZhY3Rvcl9sZXZlbHMiKSAmJiAhaXMubnVsbChxdWVzdGlvbl9mYWN0b3JfbGV2ZWxzKSl7DQogICAgICANCiAgICAgIHF1ZXN0aW9uX2luZGV4ID0gMTsNCiAgICAgICMgaWYgd2UgaGF2ZSBhIHByZWN1cnNvciBmYWN0b3IgZGVmaW5lZCwgaXQncyBwYXJzZWQgYmVmb3JlIHRoZSBxdWVzdGlvbiBudW1iZXIgaXMgcGFyc2VkDQogICAgICBpZiAoIChleGlzdHMoImZhY3Rvcl9vbmVfbGV2ZWxzIikgJiYgIWlzLm51bGwoZmFjdG9yX29uZV9sZXZlbHMpKSApDQogICAgICAgIHF1ZXN0aW9uX2luZGV4ID0gMjsNCiAgICANCiAgICAgIG1lbHRlZF9kYXRhX3N1YnNldCRxdWVzdGlvbl9mYWN0b3IgPC0gdW5saXN0KHB1cnJyOjp0cmFuc3Bvc2UgKHN0cmluZ3I6OnN0cl9leHRyYWN0X2FsbChtZWx0ZWRfZGF0YV9zdWJzZXQkdmFyaWFibGUsIlxcKD9bMC05LC5dK1xcKT8iKSlbW3F1ZXN0aW9uX2luZGV4XV0pDQogICAgICBtZWx0ZWRfZGF0YV9zdWJzZXQkcXVlc3Rpb25fZmFjdG9yIDwtIGZhY3RvcihtZWx0ZWRfZGF0YV9zdWJzZXQkcXVlc3Rpb25fZmFjdG9yKQ0KICAgICAgbWVsdGVkX2RhdGFfc3Vic2V0JHF1ZXN0aW9uX2ZhY3RvciA8LSByZXZhbHVlKG1lbHRlZF9kYXRhX3N1YnNldCRxdWVzdGlvbl9mYWN0b3IsIHF1ZXN0aW9uX2ZhY3Rvcl9sZXZlbHMpDQogIH0NCiAgDQogIGlmIChleGlzdHMoImZhY3Rvcl9vbmVfbGV2ZWxzIikgJiYgIWlzLm51bGwoZmFjdG9yX29uZV9sZXZlbHMpKXsNCiAgICAgIG1lbHRlZF9kYXRhX3N1YnNldCRmYWN0b3Jfb25lIDwtIHVubGlzdChwdXJycjo6dHJhbnNwb3NlIChzdHJpbmdyOjpzdHJfZXh0cmFjdF9hbGwobWVsdGVkX2RhdGFfc3Vic2V0JHZhcmlhYmxlLCJcXCg/WzAtOSwuXStcXCk/IikpW1sxXV0pDQogICAgICBtZWx0ZWRfZGF0YV9zdWJzZXQkZmFjdG9yX29uZSA8LSBmYWN0b3IobWVsdGVkX2RhdGFfc3Vic2V0JGZhY3Rvcl9vbmUpDQogICAgICBtZWx0ZWRfZGF0YV9zdWJzZXQkZmFjdG9yX29uZSA8LSByZXZhbHVlKG1lbHRlZF9kYXRhX3N1YnNldCRmYWN0b3Jfb25lLCBmYWN0b3Jfb25lX2xldmVscykNCiAgfQ0KICANCiAgaWYgKGV4aXN0cyAoImZhY3Rvcl90d29fbGV2ZWxzIikgJiYgIWlzLm51bGwoZmFjdG9yX3R3b19sZXZlbHMpKXsNCiAgICAgIG1lbHRlZF9kYXRhX3N1YnNldCRmYWN0b3JfdHdvIDwtIHVubGlzdChwdXJycjo6dHJhbnNwb3NlIChzdHJpbmdyOjpzdHJfZXh0cmFjdF9hbGwobWVsdGVkX2RhdGFfc3Vic2V0JHZhcmlhYmxlLCJcXCg/WzAtOSwuXStcXCk/IikpW1szXV0pDQogICAgICBtZWx0ZWRfZGF0YV9zdWJzZXQkZmFjdG9yX3R3byA8LSBmYWN0b3IobWVsdGVkX2RhdGFfc3Vic2V0JGZhY3Rvcl90d28pDQogICAgICAjcHJpbnQobGV2ZWxzKG1lbHRlZF9kYXRhX3N1YnNldCRmYWN0b3JfdHdvKSkNCiAgICAgIG1lbHRlZF9kYXRhX3N1YnNldCRmYWN0b3JfdHdvIDwtIHJldmFsdWUobWVsdGVkX2RhdGFfc3Vic2V0JGZhY3Rvcl90d28sIGZhY3Rvcl90d29fbGV2ZWxzKQ0KICB9DQogIA0KICBtZWx0ZWRfZGF0YV9zdWJzZXQkUGFydGljaXBhbnRJRCA8LSBmYWN0b3IobWVsdGVkX2RhdGFfc3Vic2V0JFBhcnRpY2lwYW50SUQpDQogIA0KICBtZWx0ZWRfZGF0YV9zdWJzZXQkdmFsdWUgPC0gZmFjdG9yKG1lbHRlZF9kYXRhX3N1YnNldCR2YWx1ZSkNCg0KICAjaWYgKCEgaXMubnVsbCh2YWx1ZV9vcmRlcikpew0KICAjICBtZWx0ZWRfZGF0YV9zdWJzZXQkdmFsdWUgPC0gZmFjdG9yKG1lbHRlZF9kYXRhX3N1YnNldCR2YWx1ZSwgb3JkZXJlZCA9IFRSVUUsIGxldmVscyA9IHZhbHVlX29yZGVyKQ0KICAjfSBlbHNlIHsNCiAgIyAgbWVsdGVkX2RhdGFfc3Vic2V0JHZhbHVlIDwtIGZhY3RvcihtZWx0ZWRfZGF0YV9zdWJzZXQkdmFsdWUpDQogICN9DQogIHJldHVybiAobmEub21pdChtZWx0ZWRfZGF0YV9zdWJzZXQpKQ0KfQ0KDQpjb21tb24ubG9vcGZhY3RvciA8LSBjKA0KICAiNCIgPSAiQ2FtZXJhIHVzYWdlIiwNCiAgIjUiID0gIk1pY3JvcGhvbmUgdXNhZ2UiLA0KICAiNyIgPSAiRGltaW5pc2hlZCByZWFsaXR5IiwNCiAgIjgiID0gIkFjdGl2aXR5IHRyYWNraW5nIiwNCiAgIjkiID0gIkludGVybmFsIHN0YXRlIiwNCiAgIjEyIiA9ICJCaW9tZXRyaWMgSUQiLA0KICAiMTMiID0gIkF1Z21lbnRlZCBwZXJjZXB0aW9uIiwNCiAgIjE2IiA9ICJQZXJzb25hbCBjaGFyYWN0ZXJpc3RpY3MiLA0KICAiMTciID0gIlBoeXNpb2xvZ2ljYWwgc3RhdGUiLA0KICAiMTgiID0gIlZvbHVtZXRyaWMgY2FwdHVyZSIsDQogICIxOSIgPSAiQXVnbWVudGVkIGFwcGVhcmFuY2UiDQopDQoNCmNvbW1vbi5sb29wb3JkZXIgPC1jKA0KICAiQ2FtZXJhIHVzYWdlIiwNCiAgIk1pY3JvcGhvbmUgdXNhZ2UiLA0KICAiQWN0aXZpdHkgdHJhY2tpbmciLA0KICAiVm9sdW1ldHJpYyBjYXB0dXJlIiwNCiAgIlBlcnNvbmFsIGNoYXJhY3RlcmlzdGljcyIsDQogICJCaW9tZXRyaWMgSUQiLA0KICAiSW50ZXJuYWwgc3RhdGUiLA0KICAiUGh5c2lvbG9naWNhbCBzdGF0ZSIsDQogICJBdWdtZW50ZWQgYXBwZWFyYW5jZSIsDQogICJEaW1pbmlzaGVkIHJlYWxpdHkiLA0KICAiQXVnbWVudGVkIHBlcmNlcHRpb24iDQopDQoNCmNvbW1vbi5pZF92YXJpYWJsZXMgPC0gYygiUGFydGljaXBhbnRJRCIpDQoNCmNvbW1vbi5yZWxhdGlvbnNoaXAgPC0gYygNCiAgIjEiID0gIkNsb3NlIGZyaWVuZCIsDQogICIyIiA9ICJGcmllbmQiLA0KICAiMyIgPSAiRmFtaWxpYXIgc3RyYW5nZXIiLA0KICAiNCIgPSAiU3RyYW5nZXIiLA0KICAiNSIgPSAiQWNjZXNzaWJpbGl0eSBuZWVkcyINCikNCg0KY29tbW9uLmF3YXJlbmVzcyA8LSBjKA0KICAiMSIgPSAiTm9uZSIsDQogICIyIiA9ICJCYXNpYyIsDQogICIzIiA9ICJJY29ub2dyYXBoaWMiLA0KICAiNCIgPSAiRnVsbCINCikNCg0KY29tbW9uLmNvbnNlbnQgPC0gYygNCiAgIjEiID0gIldpdGggQ29uc2VudCIsDQogICIyIiA9ICJXaXRob3V0IENvbnNlbnQiDQopDQoNCmNvbW1vbi50aGVtZSA8LSAgICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTExKSwNCiAgICAgICAgICBsZWdlbmQudGl0bGUgPWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBsZWdlbmQuc3BhY2luZy54PXVuaXQoMC44LCJsaW5lIiksDQogICAgICAgICAgbGVnZW5kLmtleS53aWR0aD11bml0KDEuOCwibGluZSIpLCBsZWdlbmQua2V5LmhlaWdodD11bml0KDEsImxpbmUiKSkgKw0KICAgICAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MTIpLA0KICAgICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMiksDQogICAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChtYXJnaW49bWFyZ2luKDAsLTgsMCwwKSksDQogICAgICAgICAgcGFuZWwuYmFja2dyb3VuZD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yPWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yPWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBwYW5lbC5zcGFjaW5nLnggPSB1bml0KDEuMCwgImxpbmVzIiksDQogICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSkNCkNJQ29sb3IgPSAicmVkIg0KDQojIGNvbW1vbi5hZ2VyYW5nZSA8LSBjKA0KIyAgICIxOCAtIDI0IiA9IDIxLA0KIyAgICIyNSAtIDM0IiA9ICwNCiMgICAiMzUgLSA0NCIgPSAiRGltaW5pc2hlZCByZWFsaXR5IiwNCiMgICAiNDUgLSA1NCIgPSAiVHJhY2tpbmcgYnlzdGFuZGVycyIsDQojICAgIjU1IC0gNjQiID0gIkVtb3Rpb25hbCAmIFBoeXNpb2xvZ2ljYWwgU3RhdGUiLA0KIyAgICI2NSAtIDc0IiA9ICJCaW9tZXRyaWMgSUQiLA0KIyAgICIxMyIgPSAiU3VwZXIgaGVhcmluZyAvIHNpZ2h0IiwNCiMgICAiMTYiID0gIlBlcnNvbmFsIGNoYXJhY3RlcmlzdGljcyIsDQojICAgIjE3IiA9ICJNZWRpY2FsIC8gSGVhbHRoIGRhdGEiLA0KIyAgICIxOCIgPSAiM0QgY2FwdHVyZSIsDQojICAgIjE5IiA9ICJBdWdtZW50ZWQgYXBwZWFyYW5jZSINCiMgKQ0KYGBgDQoNCg0KIyMjIEVOVFJZIFFVRVNUSU9OUw0KIyBEZW1vZ3JhcGhpY3MNCmBgYHtyfQ0KYWdlX3Jlc3VsdHMgPSBleHRyYWN0X2NvbXBvc2l0ZV9xdWVzdGlvbl93aXRoX2ZhY3RvcnMocmF3X2RhdGEsIGMoIlEzJCIpLCBjb21tb24uaWRfdmFyaWFibGVzLCBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjMiICA9ICJBZ2UiKSkNCmFnZV9yZXN1bHRzDQpsZXZlbHMoZmFjdG9yKGFnZV9yZXN1bHRzJHZhbHVlKSkNCg0KYWdlX2NvdW50IDwtIGFnZV9yZXN1bHRzICU+JSBjb3VudCh2YWx1ZSkNCmFnZV9jb3VudCRwZXJjZW50YWdlIDwtIChhZ2VfY291bnQkbiAvIG5vX2NvbXBsZXRlX3Jlc3BvbnNlcykgKiAxMDANCmFnZV9jb3VudA0KDQpnZW5kZXJfcmVzdWx0cyA9IGV4dHJhY3RfY29tcG9zaXRlX3F1ZXN0aW9uX3dpdGhfZmFjdG9ycyhyYXdfZGF0YSwgYygiUTQkIiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiNCIgPSAiR2VuZGVyIikpDQpnZW5kZXJfcmVzdWx0cw0KZ2VuZGVyX2NvdW50IDwtIGdlbmRlcl9yZXN1bHRzICU+JSBjb3VudCh2YWx1ZSkNCmdlbmRlcl9jb3VudCRwZXJjZW50YWdlIDwtIChnZW5kZXJfY291bnQkbiAvIG5vX2NvbXBsZXRlX3Jlc3BvbnNlcykgKiAxMDANCmdlbmRlcl9jb3VudA0KDQpjb3VudHJ5X3Jlc3VsdHMgPSBleHRyYWN0X2NvbXBvc2l0ZV9xdWVzdGlvbl93aXRoX2ZhY3RvcnMocmF3X2RhdGEsIGMoIlE1JCIpLCBjb21tb24uaWRfdmFyaWFibGVzLCBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjUiID0gIkNvdW50cnkiKSkNCmNvdW50cnlfcmVzdWx0cw0KY291bnRyeV9jb3VudCA8LSBjb3VudHJ5X3Jlc3VsdHMgJT4lIGNvdW50KHZhbHVlKQ0KY291bnRyeV9jb3VudCRwZXJjZW50YWdlIDwtIChjb3VudHJ5X2NvdW50JG4gLyBub19jb21wbGV0ZV9yZXNwb25zZXMpICogMTAwDQpjb3VudHJ5X2NvdW50DQpgYGANCg0KIyBBUiBFeHBlcmllbmNlDQpgYGB7cn0NCnF1ZXN0aW9ubmFpcmVfcGxvdCA8LSBmdW5jdGlvbihkYXRhLCBmYWN0b3Jfb25lLCBmYWN0b3JfdHdvLCBoYXNfdHdvX2ZhY3RvcnM9RkFMU0Upew0KICBiYXJwbG90ZGF0YSA8LSBOVUxMDQogIGJhcnBsb3RkYXRhIDwtIGRhdGENCiAgYmFycGxvdGRhdGEkdmFsdWVfcmF3IDwtIGJhcnBsb3RkYXRhJHZhbHVlDQogIGJhcnBsb3RkYXRhJHZhbHVlX211bHRpcGxpZWQgPC0gYXMubnVtZXJpYyhiYXJwbG90ZGF0YSR2YWx1ZV9yYXcpDQogIGJhcnBsb3RkYXRhJHZhbHVlX2ZhY3RvciA8LSBiYXJwbG90ZGF0YSR2YWx1ZV9yYXcNCiAgc2NhbGVfc2l6ZSA9IGxlbmd0aChsZXZlbHMoYmFycGxvdGRhdGEkdmFsdWUpKQ0KICANCiAgYmFycGxvdGRhdGEkdmFsdWVfbXVsdGlwbGllZCA9IChiYXJwbG90ZGF0YSR2YWx1ZV9tdWx0aXBsaWVkKSAqIChub19jb21wbGV0ZV9yZXNwb25zZXMvc2NhbGVfc2l6ZSkgIyB0aGVuIG11bHRpcGx5IHRvIHNjYWxlIHVwDQogIHByaW50KGJhcnBsb3RkYXRhJHZhbHVlX3Jhd19tdWx0aXBsaWVkKQ0KICANCiAgYXBwX3Bsb3RfMiA8LSBnZ3Bsb3QoZGF0YSA9IGJhcnBsb3RkYXRhLCBhZXNfc3RyaW5nKHg9ZmFjdG9yX29uZSkpICsgY29tbW9uLnRoZW1lKw0KICAgICAgZ2VvbV9iYXIoYWVzKGZpbGw9Zm9yY2F0czo6ZmN0X3Jldih2YWx1ZV9mYWN0b3IpKSwgbHdkPTApICsgY29vcmRfZmxpcCgpICsNCiAgDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgbm9fY29tcGxldGVfcmVzcG9uc2VzKSwgYnJlYWtzPWMoMCwxLzQgKiBub19jb21wbGV0ZV9yZXNwb25zZXMsIDEvMiAqIG5vX2NvbXBsZXRlX3Jlc3BvbnNlcywgMy80ICogbm9fY29tcGxldGVfcmVzcG9uc2VzLCBub19jb21wbGV0ZV9yZXNwb25zZXMpLCBsYWJlbHM9YygiMCUiLCAiMjUlIiwgIjUwJSIsICI3NSUiLCAiMTAwJSIpKSsNCiAgICAgIHN0YXRfc3VtbWFyeShhZXMoeT12YWx1ZV9tdWx0aXBsaWVkKSwgZnVuLmRhdGE9bWVhbl9jbF9ub3JtYWwsIGZ1bi5hcmdzID0gbGlzdChjb25mLmludCA9IDAuOTUpLCBnZW9tPSJlcnJvcmJhciIsIGNvbG91cj1DSUNvbG9yLCB3aWR0aD0wLjQsIHNpemU9MS4wKSArICMNCiAgICAgIHN0YXRfc3VtbWFyeShhZXMoeT12YWx1ZV9tdWx0aXBsaWVkKSwgZnVuLnk9bWVhbiwgZ2VvbT0icG9pbnQiLCBjb2xvdXI9Q0lDb2xvcikrDQogICAgICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIsIGRyb3A9RkFMU0UpKw0KICAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobGFiZWwucG9zaXRpb24gPSAiYm90dG9tIiwgcmV2ZXJzZSA9IFRSVUUsIG5yb3c9MSkpKw0KICAgIA0KICAgICAgeGxhYigiIikrIHlsYWIoIiMgb2YgUmVzcG9uc2VzIikjICsgZmFjZXRfd3JhcCh+aW50ZXJhY3Rpb250ZWNobmlxdWUsIG5yb3c9NikNCiAgDQogIA0KICBpZiAoaGFzX3R3b19mYWN0b3JzKXsNCiAgICBhcHBfcGxvdF8yIDwtIGFwcF9wbG90XzIgKyBmYWNldF93cmFwKCBhcy5mb3JtdWxhKHBhc3RlKCAifiIsIGZhY3Rvcl90d28gKSksIGxhYmVsbGVyID0gbGFiZWxsZXIoLnJvd3MgPSBsYWJlbF93cmFwX2dlbigyMCkpKQ0KICB9DQogIA0KICAgICNFeHBvcnRQbG90KGFwcF9wbG90XzIsICJhY2NlcHRhYmlsaXR5X3Bsb3QucG5nIiwgOCwgMjAsIGRvUERGPVRSVUUpDQogICAgI3ByaW50KGFwcF9wbG90XzIpDQogICAgI3ByaW50KGdncGxvdF9idWlsZChhcHBfcGxvdF8yKSRkYXRhW1szXV0pDQogIHJldHVybihhcHBfcGxvdF8yKQ0KfQ0KDQojaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2dnc2lnbmlmL3ZpZ25ldHRlcy9pbnRyby5odG1sIA0KI2h0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9BUlRvb2wvdmlnbmV0dGVzL2FydC1jb250cmFzdHMuaHRtbA0KDQpmaWx0ZXJfY29udHJhc3RzIDwtIGZ1bmN0aW9uKGNvbnRyYXN0cyl7DQogIHJlc3VsdCA9IGFzLmRhdGEuZnJhbWUoc3VtbWFyeShjb250cmFzdHMpKQ0KICByZXN1bHQgPSBzdWJzZXQocmVzdWx0LCBwLnZhbHVlIDw9IDAuMDUpDQp9DQoNCnN0YXRzX3Rlc3RpbmcgPC1mdW5jdGlvbihkYXRhLCB2YWx1ZV9vcmRlciwgdHdvX2ZhY3Rvcj1GQUxTRSkgew0KICAjZGF0YSRQYXJ0aWNpcGFudElEIDwtIGZhY3RvcihkYXRhJFBhcnRpY2lwYW50SUQpDQogICNkYXRhJHZhbHVlIDwtIGZhY3RvcihkYXRhJHZhbHVlLCBvcmRlcmVkID0gVFJVRSwgbGV2ZWxzID0gdmFsdWVfb3JkZXIpDQogIA0KICBpZiAoIXR3b19mYWN0b3Ipew0KICAgIG1vZGVsLnJlc3VsdCA8LSBhcnQodmFsdWUgfiBmYWN0b3Jfb25lICsgRXJyb3IoUGFydGljaXBhbnRJRCksIGRhdGE9ZGF0YSkNCiAgICBtb2RlbC5hb3Y8LWFub3ZhKG1vZGVsLnJlc3VsdCkNCiAgICBtb2RlbC5jb250cmFzdHM8LSBhcnQuY29uKG1vZGVsLnJlc3VsdCwgImZhY3Rvcl9vbmUiKQ0KICAgICNtb2RlbC5kZiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkobW9kZWwuY29udHJhc3RzKSkNCiAgICANCiAgICBvdXRwdXQgPC0gbGlzdCgNCiAgICAgIG1vZGVsLnJlc3VsdCwNCiAgICAgIG1vZGVsLmFvdiwNCiAgICAgIG1vZGVsLmNvbnRyYXN0cywNCiAgICAgIGZpbHRlcl9jb250cmFzdHMobW9kZWwuY29udHJhc3RzKQ0KICAgICkNCiAgICByZXR1cm4ob3V0cHV0KQ0KDQogIH0gZWxzZSB7DQogICAgbW9kZWwucmVzdWx0IDwtIGFydCh2YWx1ZSB+IGZhY3Rvcl9vbmUqZmFjdG9yX3R3byArIEVycm9yKFBhcnRpY2lwYW50SUQpLCBkYXRhPWRhdGEpDQogICAgYW5vdmFfcmVzdWx0PC1hbm92YShtb2RlbC5yZXN1bHQpDQogICAgbW9kZWwuZGZfMSA8LSBhcnQuY29uKG1vZGVsLnJlc3VsdCwgImZhY3Rvcl9vbmUiKQ0KICAgIG1vZGVsLmRmXzIgPC0gYXJ0LmNvbihtb2RlbC5yZXN1bHQsICJmYWN0b3JfdHdvIikNCiAgICANCiAgICBvdXRwdXQ8LWxpc3QoDQogICAgICBtb2RlbC5yZXN1bHQsDQogICAgICBhbm92YV9yZXN1bHQsDQogICAgICBtb2RlbC5kZl8xLA0KICAgICAgZmlsdGVyX2NvbnRyYXN0cyhtb2RlbC5kZl8xKSwNCiAgICAgIG1vZGVsLmRmXzIsDQogICAgICBmaWx0ZXJfY29udHJhc3RzKG1vZGVsLmRmXzIpDQogICAgICApDQogICAgDQogICAgcmV0dXJuKG91dHB1dCkNCiAgICANCiAgICAjcHJpbnQoYXJ0LmNvbihtb2RlbC5yZXN1bHQsICJmYWN0b3Jfb25lIikpDQogICAgI3ByaW50KGFydC5jb24obW9kZWwucmVzdWx0LCAiZmFjdG9yX3R3byIpKQ0KDQogIH0NCiAgI3JldHVybihtb2RlbCkNCn0NCmBgYA0KDQoNCmBgYHtyfQ0KYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E2ID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRNiQiKSwgY29tbW9uLmlkX3ZhcmlhYmxlcywgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCI2IiAgPSAiS25vdyB3aGF0IEFSIGlzIikpDQoNCmFyX2V4cGVyaWVuY2VfcmVzdWx0c19xNiR2YWx1ZSA8LSByZXZhbHVlKGZhY3Rvcihhcl9leHBlcmllbmNlX3Jlc3VsdHNfcTYkdmFsdWUpLCBjKCANCiJJIGRvbid0IGtub3ciID0gIkkgZG9uJ3Qga25vdyIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIk5vIiA9ICJObyIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiJZZXMsIGJ1dCBzbWFydHBob25lIEFSIG9ubHkgKGUuZy4gaW5zdGFncmFtIGZpbHRlcnMsIHNuYXBjaGF0IGxlbnNlcywgSUtFQSBmdXJuaXR1cmUgYXBwIGV0Yy4pIiA9ICAiWWVzLCBidXRcbnNtYXJ0cGhvbmVcbkFSIG9ubHkiLA0KIlllcywgaW5jbHVkaW5nIEFSIGhlYWRzZXRzIiAgPSAiWWVzLCBpbmMuXG5BUiBoZWFkc2V0cyINCiAgKSkNCg0KdmFsdWVfb3JkZXIgPSBjKA0KIk5vIiwNCiJJIGRvbid0IGtub3ciLCANCiJZZXMsIGJ1dFxuc21hcnRwaG9uZVxuQVIgb25seSIsICAgICANCiAiWWVzLCBpbmMuXG5BUiBoZWFkc2V0cyINCikNCg0KYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E2JHZhbHVlIDwtIGZhY3Rvcihhcl9leHBlcmllbmNlX3Jlc3VsdHNfcTYkdmFsdWUsIG9yZGVyZWQgPSBUUlVFLCBsZXZlbHMgPSB2YWx1ZV9vcmRlcikNCg0KYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E2JHZhcmlhYmxlIDwtICJVc2VkIEFSIEJlZm9yZSINCnE2X3Bsb3QgPC0gcXVlc3Rpb25uYWlyZV9wbG90KGFyX2V4cGVyaWVuY2VfcmVzdWx0c19xNiwgInZhcmlhYmxlIikNCnByaW50KHE2X3Bsb3QpDQpxNl9jb3VudCA8LSBhcl9leHBlcmllbmNlX3Jlc3VsdHNfcTYgJT4lIGNvdW50KHZhbHVlKQ0KcTZfY291bnQkcGVyY2VudGFnZSA8LSAocTZfY291bnQkbiAvIG5vX2NvbXBsZXRlX3Jlc3BvbnNlcykgKiAxMDANCg0KDQojYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E3ID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRNyQiKSwgY29tbW9uLmlkX3ZhcmlhYmxlcywgDQojICAgIGMoIk5vIiwgDQojICAgICAgIlllcywgYnV0IHNtYXJ0cGhvbmUgQVIgb25seSAoZS5nLiBpbnN0YWdyYW0gZmlsdGVycywgc25hcGNoYXQgbGVuc2VzLCBJS0VBIGZ1cm5pdHVyZSBhcHAgZXRjLikiLA0KIyAgICAgICAgIlllcywgaW5jbHVkaW5nIEFSIGhlYWRzZXRzIiksDQojICAgIGMoIjciID0gIlVzZWQgQVIgUHJldmlvdXNseSIpKQ0KDQoNCmFyX2V4cGVyaWVuY2VfcmVzdWx0c19xNyA9IGV4dHJhY3RfY29tcG9zaXRlX3F1ZXN0aW9uX3dpdGhfZmFjdG9ycyhyYXdfZGF0YSwgYygiUTckIiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIA0KICAgIE5VTEwsDQogICAgYygiNyIgPSAiVXNlZCBBUiBQcmV2aW91c2x5IikpDQoNCg0KDQphcl9leHBlcmllbmNlX3Jlc3VsdHNfcTckdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IoYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E3JHZhbHVlKSwgYyggDQoiTm8iID0gIk5vIiwNCiJTb3J0IG9mIiA9ICJTb3J0IG9mXG5cbiIsDQoiWWVzIiA9ICJZZXMiDQogICkpDQoNCg0KYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E3JHZhcmlhYmxlIDwtICJLbm93IHdoYXQgQVIgaXMiDQpxN19wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChhcl9leHBlcmllbmNlX3Jlc3VsdHNfcTcsICJ2YXJpYWJsZSIpDQpwcmludChxN19wbG90KQ0KcTdfY291bnQgPC0gYXJfZXhwZXJpZW5jZV9yZXN1bHRzX3E3ICU+JSBjb3VudCh2YWx1ZSkNCnE3X2NvdW50JHBlcmNlbnRhZ2UgPC0gKHE3X2NvdW50JG4gLyBub19jb21wbGV0ZV9yZXNwb25zZXMpICogMTAwDQoNCnByaW50KHE2X2NvdW50KQ0KcHJpbnQocTdfY291bnQpDQoNCmBgYA0KQ29tYmluYXRpb24gb2YgaW50cm8gcXVlc3Rpb25zDQpgYGB7cn0NCg0KcTZfcGxvdF9tb2QgPC0gcTZfcGxvdCArIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpICsgZ2d0aXRsZSgiVXNlZCBBUiBCZWZvcmU/IikNCiAgDQogcTdfcGxvdF9tb2QgPC0gcTdfcGxvdCArIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpICsgZ2d0aXRsZSgiS25vdyB3aGF0IGFuIEFSIGhlYWRzZXQgaXM/IikNCiANCmtub3dsZWRnZV9jb21iaSA8LSBwbG90X2dyaWQocTZfcGxvdF9tb2QsIHE3X3Bsb3RfbW9kLA0KICAgICAgICAgIG5jb2wgPSAyLCByZWxfd2lkdGhzID0gYygxLjAsMS4wKSwgcmVsX2hlaWdodHMgPSBjKDEuMCwgMS4wKSkNCg0KcHJpbnQoa25vd2xlZGdlX2NvbWJpKQ0KRXhwb3J0UGxvdChrbm93bGVkZ2VfY29tYmksICJrbm93bGVkZ2VfY29tYmkiLCA5LjUsIDIuMSwgZG9QREY9VFJVRSkNCmBgYA0KDQoNCg0KIyMjIExPT1BJTkcgUVVFU1RJT05TDQojIEtub3dsZWRnZSBvZiBBUiBjYXBhYmlsaXR5DQpEaWQgeW91IGtub3cgQVIgaGVhZHNldHMgaGF2ZSB0aGlzIGNhcGFiaWxpdHk/DQpgYGB7cn0NCmtub3dfY2FwYWJpbGl0eS5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMTEiLCAiUTIzIiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMTEiID0gImtub3dfY2FwYWJpbGl0eSIsICIyNyIgPSAia25vd19jYXBhYmlsaXR5IiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uLmxvb3BmYWN0b3IpDQoNCmtub3dfY2FwYWJpbGl0eS5yZXN1bHRzJGZhY3Rvcl9vbmUgPC0gZmN0X3JldihmY3RfcmVsZXZlbCgga25vd19jYXBhYmlsaXR5LnJlc3VsdHMkZmFjdG9yX29uZSwgY29tbW9uLmxvb3BvcmRlcikpDQoNCmtub3dfY2FwYWJpbGl0eS5yZXN1bHRzJHZhbHVlIDwtIHJldmFsdWUoZmFjdG9yKGtub3dfY2FwYWJpbGl0eS5yZXN1bHRzJHZhbHVlKSwgYyggDQogICJJIGRpZCBub3Qga25vdyBBUiBoZWFkc2V0cyBjb3VsZCBkbyB0aGlzIiA9ICJEaWQgbm90IGtub3ciLA0KICAiSSB3YXMgc29tZXdoYXQgYXdhcmUgQVIgaGVhZHNldHMgY291bGQgZG8gdGhpcyIgPSAiU29tZXdoYXQgYXdhcmUiLA0KICAiSSBrbmV3IEFSIGhlYWRzZXRzIGNvdWxkIGRvIHRoaXMiID0gIkF3YXJlIg0KICApKQ0KDQprbm93X2NhcGFiaWxpdHkucmVzdWx0cyR2YWx1ZSA8LSBmY3RfcmVsZXZlbCgga25vd19jYXBhYmlsaXR5LnJlc3VsdHMkdmFsdWUsIGMoIkRpZCBub3Qga25vdyIsICJTb21ld2hhdCBhd2FyZSIsICJBd2FyZSIpKQ0KDQprbm93X2NhcGFiaWxpdHkucGxvdCA8LSBxdWVzdGlvbm5haXJlX3Bsb3Qoa25vd19jYXBhYmlsaXR5LnJlc3VsdHMsICJmYWN0b3Jfb25lIikgKyBnZ3RpdGxlKCJEaWQgeW91IGtub3cgQVIgaGVhZHNldHMgaGF2ZSB0aGlzIGNhcGFiaWxpdHk/IikNCg0KRXhwb3J0UGxvdChrbm93X2NhcGFiaWxpdHkucGxvdCwgImtub3dfY2FwYWJpbGl0eV9wbG90IiwgOC41LCAzLjUsIGRvUERGPVRSVUUpDQpwcmludChrbm93X2NhcGFiaWxpdHkucGxvdCkNCg0Ka25vd19jYXBhYmlsaXR5LnJlc3VsdHMkdmFsdWUgPC0gZmFjdG9yKGtub3dfY2FwYWJpbGl0eS5yZXN1bHRzJHZhbHVlLCBvcmRlcmVkID0gVFJVRSwgbGV2ZWxzID0gYygNCiAgIkRpZCBub3Qga25vdyIsIA0KICAiU29tZXdoYXQgYXdhcmUiLA0KICAiQXdhcmUiICANCikpDQoNCm1vZGVsX3Jlc3VsdDwtIHN0YXRzX3Rlc3Rpbmcoa25vd19jYXBhYmlsaXR5LnJlc3VsdHMsIE5VTEwsIEZBTFNFKQ0KcHJpbnQobW9kZWxfcmVzdWx0WzJdKQ0KcHJpbnQobW9kZWxfcmVzdWx0WzRdKQ0KDQpgYGANCg0KIyMgRlJPTSBUSEUgUEVSU1BFQ1RJVkUgT0YgVEhFIEJZU1RBTkRFUg0KIyBHaXZpbmcgY29uc2VudA0KSG93IHdvdWxkIHlvdSBjb25zZW50IHRvIHRoaXMsIGlmIGF0IGFsbD8NCmBgYHtyLCBmaWcud2lkdGg9MTB9DQpjb25zZW50LnJlc3VsdHMgPSBleHRyYWN0X2NvbXBvc2l0ZV9xdWVzdGlvbl93aXRoX2ZhY3RvcnMocmF3X2RhdGEsIGMoIlExMyIsICJRMjUiKSwgY29tbW9uLmlkX3ZhcmlhYmxlcywgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCIxMyIgPSAiY29uc2VudCIsICIyNSIgPSAiY29uc2VudCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbi5sb29wZmFjdG9yLCBjb21tb24ucmVsYXRpb25zaGlwKQ0KDQpjb25zZW50LnJlc3VsdHMkZmFjdG9yX29uZSA8LSBmY3RfcmVsZXZlbCggY29uc2VudC5yZXN1bHRzJGZhY3Rvcl9vbmUsIGNvbW1vbi5sb29wb3JkZXIpDQoNCnZhbHVlX29yZGVyID0gYygNCiAgIk9wdC1vdXQgLSBJIHdvdWxkIG5ldmVyIGNvbnNlbnQgdG8gdGhpcyBhY3Rpdml0eSIsDQogICJPcHQtb3V0IGJ5IGRlZmF1bHQsIHdpdGggYWJpbGl0eSB0byByZXF1ZXN0IHlvdXIgY29uc2VudCIsDQogICJPcHQtaW4gYnkgZGVmYXVsdCwgd2l0aCBhYmlsaXR5IHRvIHdpdGhkcmF3IHlvdXIgY29uc2VudCIsDQogICJPcHQtaW4gYnkgZGVmYXVsdCwgbm8gY29uc2VudCByZXF1aXJlZCINCikNCg0KY29uc2VudC5yZXN1bHRzJHZhbHVlIDwtIGZhY3Rvcihjb25zZW50LnJlc3VsdHMkdmFsdWUsIG9yZGVyZWQgPSBUUlVFLCBsZXZlbHMgPSB2YWx1ZV9vcmRlcikNCg0KY29uc2VudC5yZXN1bHRzJHZhbHVlIDwtIHJldmFsdWUoZmFjdG9yKGNvbnNlbnQucmVzdWx0cyR2YWx1ZSksIGMoIA0KICAiT3B0LW91dCAtIEkgd291bGQgbmV2ZXIgY29uc2VudCB0byB0aGlzIGFjdGl2aXR5IiA9ICJPcHQtb3V0IC0gSSB3b3VsZCBuZXZlclxuIGNvbnNlbnQgdG8gdGhpcyBhY3Rpdml0eSIsDQogICJPcHQtb3V0IGJ5IGRlZmF1bHQsIHdpdGggYWJpbGl0eSB0byByZXF1ZXN0IHlvdXIgY29uc2VudCIgPSAiT3B0LW91dCwgd2l0aCBhYmlsaXR5XG50byByZXF1ZXN0IHlvdXIgY29uc2VudCIgLA0KICAiT3B0LWluIGJ5IGRlZmF1bHQsIHdpdGggYWJpbGl0eSB0byB3aXRoZHJhdyB5b3VyIGNvbnNlbnQiID0gIk9wdC1pbiwgd2l0aCBhYmlsaXR5XG50byB3aXRoZHJhdyB5b3VyIGNvbnNlbnQiLA0KICAiT3B0LWluIGJ5IGRlZmF1bHQsIG5vIGNvbnNlbnQgcmVxdWlyZWQiID0gICAiT3B0LWluIGJ5IGRlZmF1bHQsXG5ubyBjb25zZW50IHJlcXVpcmVkIg0KICApKQ0KDQoNCmNvbnNlbnQuc3RhdHNfcmVzdWx0cyA8LSBzdGF0c190ZXN0aW5nKGNvbnNlbnQucmVzdWx0cywgTlVMTCwgVFJVRSkNCnByaW50KGNvbnNlbnQuc3RhdHNfcmVzdWx0c1syXSkNCnByaW50KGNvbnNlbnQuc3RhdHNfcmVzdWx0c1szXSkNCnByaW50KGNvbnNlbnQuc3RhdHNfcmVzdWx0c1s0XSkNCnByaW50KGNvbnNlbnQuc3RhdHNfcmVzdWx0c1s1XSkNCg0KY29uc2VudC5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChjb25zZW50LnJlc3VsdHMsICJmYWN0b3JfdHdvIiwgImZhY3Rvcl9vbmUiLCBUUlVFKSArIGdndGl0bGUoIkhvdyB3b3VsZCB5b3Ugd2lzaCB0byBtYW5hZ2UgeW91ciBjb25zZW50IHRvIHRoaXMgYWN0aXZpdHk/IikNCnByaW50KGNvbnNlbnQucGxvdCkNCkV4cG9ydFBsb3QoY29uc2VudC5wbG90LCAiY29uc2VudF9wbG90IiwgOSwgNiwgZG9QREY9VFJVRSkNCg0KYGBgDQojIFJldm9raW5nIGNvbnNlbnQNCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0zLjV9DQpyZXZva2VfY29uc2VudC5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMTQiLCAiUTI2IiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMTQiID0gInJldm9rZS5jb25zZW50IiwgIjI2IiA9ICJyZXZva2UuY29uc2VudCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbi5sb29wZmFjdG9yKQ0KDQpyZXZva2VfY29uc2VudC5yZXN1bHRzJGZhY3Rvcl9vbmUgPC0gZmN0X3JldihmY3RfcmVsZXZlbCggcmV2b2tlX2NvbnNlbnQucmVzdWx0cyRmYWN0b3Jfb25lLCBjb21tb24ubG9vcG9yZGVyKSkNCg0KI2xldmVscyhmYWN0b3IoY29uc2VudC5yZXN1bHRzJHZhbHVlKSkNCg0KdmFsdWVfb3JkZXIgPSBjKA0KICAiRGVmaW5pdGVseSBub3QiLA0KICAgIlByb2JhYmx5IG5vdCIgLA0KICAiTWF5IG9yIG1heSBub3QiLA0KICAiUHJvYmFibHkgeWVzIiAgLA0KICAiRGVmaW5pdGVseSB5ZXMiICAgDQopDQoNCnJldm9rZV9jb25zZW50LnJlc3VsdHMkdmFsdWUgPC0gZmFjdG9yKHJldm9rZV9jb25zZW50LnJlc3VsdHMkdmFsdWUsIG9yZGVyZWQgPSBUUlVFLCBsZXZlbHMgPSB2YWx1ZV9vcmRlcikNCnJldm9rZV9jb25zZW50LnJlc3VsdHMkdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IocmV2b2tlX2NvbnNlbnQucmVzdWx0cyR2YWx1ZSksIGMoIA0KICAiRGVmaW5pdGVseSBub3QiICA9ICJEZWZpbml0ZWx5XG5ub3QiLA0KICAgIlByb2JhYmx5IG5vdCIgID0gIlByb2JhYmx5XG5ub3QiLCANCiAgIk1heSBvciBtYXkgbm90IiA9ICJNYXkgb3Jcbm1heSBub3QiLA0KICAiUHJvYmFibHkgeWVzIiAgPSAiUHJvYmFibHlcbnllcyIsDQogICJEZWZpbml0ZWx5IHllcyIgPSAiRGVmaW5pdGVseVxueWVzIiAgIA0KICApKQ0KDQoNCnJldm9rZV9jb25zZW50LnN0YXRzX3Jlc3VsdHMgPC0gc3RhdHNfdGVzdGluZyhyZXZva2VfY29uc2VudC5yZXN1bHRzLCBOVUxMLCBGQUxTRSkNCnByaW50KHJldm9rZV9jb25zZW50LnN0YXRzX3Jlc3VsdHNbMl0pDQpwcmludChyZXZva2VfY29uc2VudC5zdGF0c19yZXN1bHRzWzRdKQ0KcmV2b2tlX2NvbnNlbnQucGxvdCA8LSBxdWVzdGlvbm5haXJlX3Bsb3QocmV2b2tlX2NvbnNlbnQucmVzdWx0cywgImZhY3Rvcl9vbmUiKSAgKyBnZ3RpdGxlKCJBdXRvbWF0aWMgb3B0LWluL291dCBiYXNlZCBvbiBwcmUtcHJvdmlkZWQgQVIgcHJlZmVyZW5jZXMiKQ0KcHJpbnQocmV2b2tlX2NvbnNlbnQucGxvdCkNCkV4cG9ydFBsb3QocmV2b2tlX2NvbnNlbnQucGxvdCwgInJldm9rZV9jb25zZW50X3Bsb3QiLCA4LjUsIDMuNSwgZG9QREY9VFJVRSkNCg0KYGBgDQoNCiMgQ29uY2VybiB3aXRoIEFSDQpgYGB7cn0NCmNvbmNlcm4ucmVzdWx0cyA9IGV4dHJhY3RfY29tcG9zaXRlX3F1ZXN0aW9uX3dpdGhfZmFjdG9ycyhyYXdfZGF0YSwgYygiUTE1IiwgIlEyNyIpLCBjb21tb24uaWRfdmFyaWFibGVzLCBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjE1IiA9ICJjb25jZXJuIiwgIjI3IiA9ICJjb25jZXJuIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uLmxvb3BmYWN0b3IpDQoNCmNvbmNlcm4ucmVzdWx0cyRmYWN0b3Jfb25lIDwtIGZjdF9yZXYoZmN0X3JlbGV2ZWwoIGNvbmNlcm4ucmVzdWx0cyRmYWN0b3Jfb25lLCBjb21tb24ubG9vcG9yZGVyKSkNCg0KY29uY2Vybi5yZXN1bHRzIA0KbGV2ZWxzKGZhY3Rvcihjb25jZXJuLnJlc3VsdHMkdmFsdWUpKQ0KDQp2YWx1ZV9vcmRlciA9IGMoDQogICJWZXJ5IHVuY29uY2VybmluZyIgLA0KICAiVW5jb25jZXJuaW5nIiAsDQogICJOZXV0cmFsIiAsDQogICJTb21ld2hhdCBjb25jZXJuaW5nIiwNCiAgIlZlcnkgY29uY2VybmluZyINCikNCg0KY29uY2Vybi5yZXN1bHRzJHZhbHVlIDwtIGZhY3Rvcihjb25jZXJuLnJlc3VsdHMkdmFsdWUsIG9yZGVyZWQgPSBUUlVFLCBsZXZlbHMgPSB2YWx1ZV9vcmRlcikNCg0KDQpjb25jZXJuLnJlc3VsdHMkdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IoY29uY2Vybi5yZXN1bHRzJHZhbHVlKSwgYyggDQogICJWZXJ5IHVuY29uY2VybmluZyIgPSAiVmVyeVxudW5jb25jZXJuaW5nIiwNCiAgIlVuY29uY2VybmluZyIgPSAiVW5jb25jZXJuaW5nIiwNCiAgIk5ldXRyYWwiID0gIk5ldXRyYWwiLA0KICAiU29tZXdoYXQgY29uY2VybmluZyIgPSAiU29tZXdoYXRcbmNvbmNlcm5pbmdcbiAiLA0KICAiVmVyeSBjb25jZXJuaW5nIiA9ICJWZXJ5XG5jb25jZXJuaW5nIg0KICApKQ0KDQpjb25jZXJuLnN0YXRzX3Jlc3VsdHMgPC0gc3RhdHNfdGVzdGluZyhjb25jZXJuLnJlc3VsdHMsIE5VTEwsIEZBTFNFKQ0KcHJpbnQoY29uY2Vybi5zdGF0c19yZXN1bHRzWzJdKQ0KcHJpbnQoY29uY2Vybi5zdGF0c19yZXN1bHRzWzRdKQ0KY29uY2Vybi5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChjb25jZXJuLnJlc3VsdHMsICJmYWN0b3Jfb25lIikgKyBnZ3RpdGxlKCJDb25jZXJuIHdpdGggU3RyYW5nZXIncyBBUiBBY3Rpdml0eSIpDQpwcmludChjb25jZXJuLnBsb3QpDQpFeHBvcnRQbG90KGNvbmNlcm4ucGxvdCwgImNvbmNlcm5fcGxvdCIsIDguNSwgMy41LCBkb1BERj1UUlVFKQ0KDQoNCmBgYA0KIyBDb25jZXJuIHZlcnN1cyBzbWFydHBob25lIEFSDQpgYGB7cn0NCmNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cyA9IGV4dHJhY3RfY29tcG9zaXRlX3F1ZXN0aW9uX3dpdGhfZmFjdG9ycyhyYXdfZGF0YSwgYygiUTE2IiwgIlEyOCIpLCBjb21tb24uaWRfdmFyaWFibGVzLCBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjE2IiA9ICJjb25jZXJuX3ZlcnN1c19zbWFydHBob25lIiwgIjI4IiA9ICJjb25jZXJuX3ZlcnN1c19zbWFydHBob25lIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uLmxvb3BmYWN0b3IpDQoNCmNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cyRmYWN0b3Jfb25lIDwtIGZjdF9yZXYoZmN0X3JlbGV2ZWwoIGNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cyRmYWN0b3Jfb25lLCBjb21tb24ubG9vcG9yZGVyKSkNCg0KI2NvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cw0KI2xldmVscyhmYWN0b3IoY29uY2Vybl92ZXJzdXNfc21hcnRwaG9uZS5yZXN1bHRzJHZhbHVlKSkNCg0KDQp2YWx1ZV9vcmRlciA9IGMoDQogICJNdWNoIGxlc3MgY29uY2VybmluZyB0aGFuIHNtYXJ0cGhvbmVzIiAsDQoiU29tZXdoYXQgbGVzcyBjb25jZXJuaW5nIiwgICAgICAgICAgICAgIA0KIkFib3V0IHRoZSBzYW1lIiwgICAgICAgICAgICAgICAgICAgICAgIA0KIlNvbWV3aGF0IG1vcmUgY29uY2VybmluZyIsICAgDQoiTXVjaCBtb3JlIGNvbmNlcm5pbmcgdGhhbiBzbWFydHBob25lcyIgDQopDQpjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnJlc3VsdHMkdmFsdWUgPC0gZmFjdG9yKGNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cyR2YWx1ZSwgb3JkZXJlZCA9IFRSVUUsIGxldmVscyA9IHZhbHVlX29yZGVyKQ0KDQpjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnJlc3VsdHMkdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IoY29uY2Vybl92ZXJzdXNfc21hcnRwaG9uZS5yZXN1bHRzJHZhbHVlKSwgYyggDQogICJNdWNoIGxlc3MgY29uY2VybmluZyB0aGFuIHNtYXJ0cGhvbmVzIiA9ICJNdWNoXG5sZXNzXG5jb25jZXJuaW5nIiwNCiJTb21ld2hhdCBsZXNzIGNvbmNlcm5pbmciID0gIlNvbWV3aGF0XG5sZXNzXG5jb25jZXJuaW5nIiwgICAgICAgICAgICAgIA0KIkFib3V0IHRoZSBzYW1lIiA9ICJBYm91dFxudGhlIHNhbWUiLCAgICAgICAgICAgICAgICAgICAgICAgDQoiU29tZXdoYXQgbW9yZSBjb25jZXJuaW5nIiA9ICJTb21ld2hhdFxubW9yZVxuY29uY2VybmluZyIsICAgDQoiTXVjaCBtb3JlIGNvbmNlcm5pbmcgdGhhbiBzbWFydHBob25lcyIgPSAiTXVjaFxubW9yZVxuY29uY2VybmluZyIgDQogICkpDQoNCg0KY29uY2Vybl92ZXJzdXNfc21hcnRwaG9uZS5zdGF0c19yZXN1bHRzIDwtIHN0YXRzX3Rlc3RpbmcoY29uY2Vybl92ZXJzdXNfc21hcnRwaG9uZS5yZXN1bHRzLCBOVUxMLCBGQUxTRSkgDQpwcmludChjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnN0YXRzX3Jlc3VsdHNbMl0pDQpwcmludChjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnN0YXRzX3Jlc3VsdHNbNF0pDQpjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnBsb3QgPC0gcXVlc3Rpb25uYWlyZV9wbG90KGNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucmVzdWx0cywgImZhY3Rvcl9vbmUiKSAgKyBnZ3RpdGxlKCJDb25jZXJuIHJlbGF0aXZlIHRvIFNtYXJ0cGhvbmUgQVIiKSAjKyBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMikpDQpwcmludChjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnBsb3QpDQpFeHBvcnRQbG90KGNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmUucGxvdCwgImNvbmNlcm5fdmVyc3VzX3NtYXJ0cGhvbmVfcGxvdCIsIDguNSwgMy41LCBkb1BERj1UUlVFKQ0KDQoNCmBgYA0KDQojIENvbmNlcm4gY29tYmkgcGxvdA0KYGBge3IsIGZpZy53aWR0aD0xMS41LCBmaWcuaGVpZ2h0PTR9DQpjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnBsb3Rfd2l0aG91dF95X2xhYmVscyA8LSBjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnBsb3QgKyANCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkNCg0KY29uY2Vybl9wbG90X21vZCA8LSBjb25jZXJuLnBsb3QgKyB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwwKSkNCg0KY29uY2Vybl9jb21iaV9wbG90IDwtIHBsb3RfZ3JpZChjb25jZXJuX3Bsb3RfbW9kLCBjb25jZXJuX3ZlcnN1c19zbWFydHBob25lLnBsb3Rfd2l0aG91dF95X2xhYmVscywNCiAgICAgICAgICBuY29sID0gMiwgcmVsX3dpZHRocyA9IGMoMS41LDAuOTYpKQ0KDQpwcmludChjb25jZXJuX2NvbWJpX3Bsb3QpDQpFeHBvcnRQbG90KGNvbmNlcm5fY29tYmlfcGxvdCwgImNvbmNlcm5fY29tYmlfcGxvdCIsIDExLjUsIDQsIGRvUERGPVRSVUUpDQoNCmBgYA0KDQoNCiMgQXdhcmVuZXNzIHByZWZlcmVuY2Ugd2l0aCBhbmQgd2l0aG91dCBjb25zZW50DQpUaGlzIGlzIGEgbWF0cml4IHF1ZXN0aW9uLCBzbyBuZWVkIHRvIGJlIHN1cmUgYWJvdXQgdGhlIGZvcm1hdHRpbmcgaGVyZT8NCjE5X1EzMF8xLzINCmBgYHtyfQ0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMTgiLCAiUTMwIiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMjAiID0gImF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQiLCAiMzAiID0gImF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb24ubG9vcGZhY3RvciwgY29tbW9uLmNvbnNlbnQpDQoNCmF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyRmYWN0b3Jfb25lIDwtIGZjdF9yZXYoZmN0X3JlbGV2ZWwoIGF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyRmYWN0b3Jfb25lLCBjb21tb24ubG9vcG9yZGVyKSkNCg0KI2F3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyANCiNsZXZlbHMoZmFjdG9yKGF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyAkdmFsdWUpKQ0KDQoNCnZhbHVlX29yZGVyID0gYygNCiIxIC0gTm8gYXdhcmVuZXNzIG9mIGFjdGl2aXR5IiAsDQoiMiAtIEJhc2ljIGF3YXJlbmVzcyBkZXZpY2Ugc2Vuc2luZyBpcyBhY3RpdmUgKGUuZy4gTEVEIGNvbG91cikiICwNCiIzIC0gQXdhcmVuZXNzIG9mIGFjdGl2aXR5IHR5cGUgc2Vuc2luZyBpcyBiZWluZyB1c2VkIGZvciIgICwgICAgDQoiNCAtIEZ1bGwsIHJlYWwtdGltZSBhd2FyZW5lc3Mgb2Ygd2hhdCB0aGUgaGVhZHNldCBpcyBkb2luZyIgICAgDQopDQphd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnJlc3VsdHMkdmFsdWUgPC0gZmFjdG9yKGF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyR2YWx1ZSwgb3JkZXJlZCA9IFRSVUUsIGxldmVscyA9IHZhbHVlX29yZGVyKQ0KDQphd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnJlc3VsdHMkdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IoYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5yZXN1bHRzJHZhbHVlKSwgYyggDQoiMSAtIE5vIGF3YXJlbmVzcyBvZiBhY3Rpdml0eSIgPSAiTm8gYXdhcmVuZXNzIiAsDQoiMiAtIEJhc2ljIGF3YXJlbmVzcyBkZXZpY2Ugc2Vuc2luZyBpcyBhY3RpdmUgKGUuZy4gTEVEIGNvbG91cikiID0gIkJhc2ljIGF3YXJlbmVzc1xuZGV2aWNlIGFjdGl2ZSIsDQoiMyAtIEF3YXJlbmVzcyBvZiBhY3Rpdml0eSB0eXBlIHNlbnNpbmcgaXMgYmVpbmcgdXNlZCBmb3IiICA9ICJBd2FyZW5lc3Mgb2ZcbmFjdGl2aXR5IHR5cGUiLCAgICANCiI0IC0gRnVsbCwgcmVhbC10aW1lIGF3YXJlbmVzcyBvZiB3aGF0IHRoZSBoZWFkc2V0IGlzIGRvaW5nIiA9ICJGdWxsLCByZWFsLXRpbWVcbmF3YXJlbmVzcyIgICAgDQogICkpDQoNCg0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5zdGF0c19yZXN1bHRzIDwtIHN0YXRzX3Rlc3RpbmcoYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5yZXN1bHRzLCBOVUxMLCBUUlVFKQ0KcHJpbnQoYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5zdGF0c19yZXN1bHRzWzJdKQ0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChhd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnJlc3VsdHMsICJmYWN0b3Jfb25lIiwgImZhY3Rvcl90d28iLCBUUlVFKSArIGdndGl0bGUoIkJsZXAiKQ0KcHJpbnQoYXdhcmVuZXNzX3ByZWZlcmVuY2VfYnlfY29uc2VudC5wbG90KQ0KRXhwb3J0UGxvdChhd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnBsb3QsICJhd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50X3Bsb3QiLCAxMS41LCA0LCBkb1BERj1UUlVFKQ0KDQoNCmBgYA0KDQojIyBGUk9NIFRIRSBQRVJTUEVDVElWRSBPRiBCRUlORyBUSEUgQVIgVVNFUg0KIyBBd2FyZW5lc3MgcHJlZmVyZW5jZSBmb3Igb3duIGhlYWRzZXQNCmBgYHtyfQ0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMjAiLCAiUTMyIiksIGNvbW1vbi5pZF92YXJpYWJsZXMsIE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMjAiID0gImF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMiLCAiMzIiID0gImF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb24ubG9vcGZhY3RvcikNCg0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzJGZhY3Rvcl9vbmUgPC0gZmN0X3JldihmY3RfcmVsZXZlbCggYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzJGZhY3Rvcl9vbmUsIGNvbW1vbi5sb29wb3JkZXIpKQ0KDQojYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzIA0KI2xldmVscyhmYWN0b3IoYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzJHZhbHVlKSkNCg0KdmFsdWVfb3JkZXIgPSBjKA0KIjEgLSBObyBhd2FyZW5lc3Mgb2YgYWN0aXZpdHkiICwNCiIyIC0gQmFzaWMgYXdhcmVuZXNzIGRldmljZSBzZW5zaW5nIGlzIGFjdGl2ZSAoZS5nLiBMRUQgY29sb3VyKSIgLA0KIjMgLSBBd2FyZW5lc3Mgb2YgYWN0aXZpdHkgdHlwZSBzZW5zaW5nIGlzIGJlaW5nIHVzZWQgZm9yIiAgLCAgICANCiI0IC0gRnVsbCwgcmVhbC10aW1lIGF3YXJlbmVzcyBvZiB3aGF0IHRoZSBoZWFkc2V0IGlzIGRvaW5nIiAgICANCikNCmF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMucmVzdWx0cyR2YWx1ZSA8LSBmYWN0b3IoYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzJHZhbHVlLCBvcmRlcmVkID0gVFJVRSwgbGV2ZWxzID0gdmFsdWVfb3JkZXIpDQoNCg0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzJHZhbHVlIDwtIHJldmFsdWUoZmFjdG9yKGF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMucmVzdWx0cyR2YWx1ZSksIGMoIA0KIjEgLSBObyBhd2FyZW5lc3Mgb2YgYWN0aXZpdHkiID0gIk5vIGF3YXJlbmVzcyIgLA0KIjIgLSBCYXNpYyBhd2FyZW5lc3MgZGV2aWNlIHNlbnNpbmcgaXMgYWN0aXZlIChlLmcuIExFRCBjb2xvdXIpIiA9ICJCYXNpYyBhd2FyZW5lc3NcbmRldmljZSBhY3RpdmUiLA0KIjMgLSBBd2FyZW5lc3Mgb2YgYWN0aXZpdHkgdHlwZSBzZW5zaW5nIGlzIGJlaW5nIHVzZWQgZm9yIiAgPSAiQXdhcmVuZXNzIG9mXG5hY3Rpdml0eSB0eXBlIiwgICAgDQoiNCAtIEZ1bGwsIHJlYWwtdGltZSBhd2FyZW5lc3Mgb2Ygd2hhdCB0aGUgaGVhZHNldCBpcyBkb2luZyIgPSAiRnVsbCwgcmVhbC10aW1lXG5hd2FyZW5lc3MiICAgICANCiAgKSkNCg0KYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5zdGF0c19yZXN1bHRzIDwtIHN0YXRzX3Rlc3RpbmcoYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzLCBOVUxMLCBGQUxTRSkNCnByaW50KGF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMuc3RhdHNfcmVzdWx0c1syXSkNCmF3YXJlbmVzc19wcmVmZXJlbmNlX2hlYWRzZXRfaW5mb3Jtc19vdGhlcnMucGxvdCA8LSBxdWVzdGlvbm5haXJlX3Bsb3QoYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzLCAiZmFjdG9yX29uZSIsIE5VTEwsIEZBTFNFKQ0KcHJpbnQoYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5wbG90KQ0KDQpgYGANCg0KIyBDb21iaW5lIGJ5c3RhbmRlciBhbmQgdXNlciBwZXJzcGVjdGl2ZXMNCmNvbWJpbmUgYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzIGFuZCBhd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnJlc3VsdHMNCg0KYGBge3IsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTR9DQoNCmF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyRmYWN0b3JfdHdvIDwtIHJldmFsdWUoZmFjdG9yKGF3YXJlbmVzc19wcmVmZXJlbmNlX2J5X2NvbnNlbnQucmVzdWx0cyRmYWN0b3JfdHdvKSwgYyggDQogICJXaXRoIENvbnNlbnQiID0gIkFzIGEgYnlzdGFuZGVyXG53aXRoIGNvbnNlbnQiLA0KICAiV2l0aG91dCBDb25zZW50IiA9ICJBcyBhIGJ5c3RhbmRlclxud2l0aG91dCBjb25zZW50Ig0KICApKQ0KDQphd2FyZW5lc3NfcHJlZmVyZW5jZV9oZWFkc2V0X2luZm9ybXNfb3RoZXJzLnJlc3VsdHMkZmFjdG9yX3R3byA8LSAiQXMgdGhlIFxuQVIgdXNlciINCg0KY29tYmluZWRfZGF0YSA8LSByYmluZChhd2FyZW5lc3NfcHJlZmVyZW5jZV9ieV9jb25zZW50LnJlc3VsdHMsYXdhcmVuZXNzX3ByZWZlcmVuY2VfaGVhZHNldF9pbmZvcm1zX290aGVycy5yZXN1bHRzICkNCg0KIyBub3cgY29tYmluZWQgd2hlcmUgZmFjdG9yX3R3byB0ZWxscyB1cyBwZXJzcGVjdGl2ZSAoYnlzdGFuZGVyIHdpdGggY29uc2VudCwgd2l0aG91dCBjb25zZW50LCBhbmQgdXNlcikNCg0KY29tYmluZWRfZGF0YS5zdGF0c19yZXN1bHRzIDwtIHN0YXRzX3Rlc3RpbmcoY29tYmluZWRfZGF0YSwgTlVMTCwgVFJVRSkNCnByaW50KGNvbWJpbmVkX2RhdGEuc3RhdHNfcmVzdWx0c1syXSkNCnByaW50KGNvbWJpbmVkX2RhdGEuc3RhdHNfcmVzdWx0c1szXSkNCnByaW50KGNvbWJpbmVkX2RhdGEuc3RhdHNfcmVzdWx0c1s0XSkNCnByaW50KGNvbWJpbmVkX2RhdGEuc3RhdHNfcmVzdWx0c1s1XSkNCnByaW50KGNvbWJpbmVkX2RhdGEuc3RhdHNfcmVzdWx0c1s2XSkNCg0KY29tYmluZWRfZGF0YS5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChjb21iaW5lZF9kYXRhLCAiZmFjdG9yX29uZSIsICJmYWN0b3JfdHdvIiwgVFJVRSkgKyBnZ3RpdGxlKCJQcmVmZXJlbmNlIFRvd2FyZCBBd2FyZW5lc3Mgb2YgQVIgQWN0aXZpdHkuLi4iKQ0KcHJpbnQoY29tYmluZWRfZGF0YS5wbG90KQ0KRXhwb3J0UGxvdChjb21iaW5lZF9kYXRhLnBsb3QsICJhd2FyZW5lc3NfcHJlZmVyZW5jZXNfY29tYmluZWRfcGxvdCIsIDksIDQsIGRvUERGPVRSVUUpDQoNCmBgYA0KDQoNCiMjIyBFWElUIFFVRVNUSU9OUw0KDQojIENvbWZvcnQgd2l0aCBBUiAobGVzcy9tb3JlKQ0KYGBge3J9DQptb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMzQiKSwgY29tbW9uLmlkX3ZhcmlhYmxlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMzQiID0gIm1vcmVfbGVzc19jb21mb3J0YWJsZSIpKQ0KDQptb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzDQoNCnZhbHVlX29yZGVyID0gYygNCiJNdWNoIG1vcmUgdW5jb21mb3J0YWJsZSIsDQoiTW9yZSB1bmNvbWZvcnRhYmxlIiwgDQoiTmV1dHJhbCAvIE5vIGNoYW5nZSIsICAgICANCiJNb3JlIGNvbWZvcnRhYmxlIiwNCiJNdWNoIG1vcmUgY29tZm9ydGFibGUiDQopDQoNCm1vcmVfb3JfbGVzc19jb21mb3J0YWJsZV93aXRoX2FyLnJlc3VsdHMkdmFsdWUgPC0gZmFjdG9yKG1vcmVfb3JfbGVzc19jb21mb3J0YWJsZV93aXRoX2FyLnJlc3VsdHMkdmFsdWUsIG9yZGVyZWQgPSBUUlVFLCBsZXZlbHMgPSB2YWx1ZV9vcmRlcikNCg0KbW9yZV9vcl9sZXNzX2NvbWZvcnRhYmxlX3dpdGhfYXIucmVzdWx0cyR2YWx1ZSA8LSByZXZhbHVlKGZhY3Rvcihtb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzJHZhbHVlKSwgYyggDQoiTXVjaCBtb3JlIHVuY29tZm9ydGFibGUiID0gIk11Y2ggbW9yZVxuIHVuY29tZm9ydGFibGUiICwNCiJNb3JlIHVuY29tZm9ydGFibGUiID0gIk1vcmUgXG51bmNvbWZvcnRhYmxlIiwgDQoiTmV1dHJhbCAvIE5vIGNoYW5nZSIgPSAiTmV1dHJhbCAvXG5ObyBjaGFuZ2UiLCAgICAgDQoiTW9yZSBjb21mb3J0YWJsZSIgPSAiTW9yZVxuY29tZm9ydGFibGUiLA0KIk11Y2ggbW9yZSBjb21mb3J0YWJsZSIgPSAiTXVjaCBtb3JlXG5jb21mb3J0YWJsZSINCiAgKSkNCg0KDQptb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChtb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzLCAiZmFjdG9yX29uZSIsIE5VTEwsIEZBTFNFKSArICANCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKCJSZXRyb3NwZWN0aXZlIC0gTW9yZSBvciBsZXNzIGNvbWZvcnRhYmxlIHdpdGggQVIiKQ0KcHJpbnQobW9yZV9vcl9sZXNzX2NvbWZvcnRhYmxlX3dpdGhfYXIucGxvdCkNCg0KYGBgDQoNCiMgQ29tZm9ydCB3aXRoIEFSIGdlbmVyYWxseQ0KYGBge3J9DQpob3dfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzID0gZXh0cmFjdF9jb21wb3NpdGVfcXVlc3Rpb25fd2l0aF9mYWN0b3JzKHJhd19kYXRhLCBjKCJRMzUiKSwgY29tbW9uLmlkX3ZhcmlhYmxlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiMzUiID0gImhvd19jb21mb3J0YWJsZV93aXRoX2FyIikpDQoNCmhvd19jb21mb3J0YWJsZV93aXRoX2FyLnJlc3VsdHMNCg0KdmFsdWVfb3JkZXIgPSBjKA0KIkV4dHJlbWVseSB1bmNvbWZvcnRhYmxlIiAsDQoiU29tZXdoYXQgdW5jb21mb3J0YWJsZSIgLA0KICJOZWl0aGVyIGNvbWZvcnRhYmxlIG5vciB1bmNvbWZvcnRhYmxlIiAsDQogIlNvbWV3aGF0IGNvbWZvcnRhYmxlIiAgICAsDQoiRXh0cmVtZWx5IGNvbWZvcnRhYmxlIiAgIA0KKQ0KDQpob3dfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzJHZhbHVlIDwtIGZhY3Rvcihob3dfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzJHZhbHVlLCBvcmRlcmVkID0gVFJVRSwgbGV2ZWxzID0gdmFsdWVfb3JkZXIpDQoNCmhvd19jb21mb3J0YWJsZV93aXRoX2FyLnJlc3VsdHMkdmFsdWUgPC0gcmV2YWx1ZShmYWN0b3IoaG93X2NvbWZvcnRhYmxlX3dpdGhfYXIucmVzdWx0cyR2YWx1ZSksIGMoIA0KIkV4dHJlbWVseSB1bmNvbWZvcnRhYmxlIiA9ICJFeHRyZW1lbHlcbnVuY29tZm9ydGFibGUiLA0KIlNvbWV3aGF0IHVuY29tZm9ydGFibGUiID0gIlNvbWV3aGF0XG51bmNvbWZvcnRhYmxlIiwNCiAiTmVpdGhlciBjb21mb3J0YWJsZSBub3IgdW5jb21mb3J0YWJsZSIgPSJOZWl0aGVyIGNvbWZvcnRhYmxlXG5ub3IgdW5jb21mb3J0YWJsZSIsDQogIlNvbWV3aGF0IGNvbWZvcnRhYmxlIiA9IlNvbWV3aGF0XG5jb21mb3J0YWJsZSIgLA0KIkV4dHJlbWVseSBjb21mb3J0YWJsZSIgPSAiRXh0cmVtZWx5XG5jb21mb3J0YWJsZSIgIA0KICApKQ0KDQpob3dfY29tZm9ydGFibGVfd2l0aF9hci5wbG90IDwtIHF1ZXN0aW9ubmFpcmVfcGxvdChob3dfY29tZm9ydGFibGVfd2l0aF9hci5yZXN1bHRzLCAiZmFjdG9yX29uZSIsIE5VTEwsIEZBTFNFKSArICANCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkgKyBnZ3RpdGxlKCJSZXRyb3NwZWN0aXZlIC0gQ29tZm9ydCB3aXRoIEV2ZXJ5ZGF5IEF1Z21lbnRlZCBSZWFsaXR5IikNCnByaW50KGhvd19jb21mb3J0YWJsZV93aXRoX2FyLnBsb3QpDQoNCmBgYA0KDQpDb21iaW5lZCBjb21mb3J0DQoNCmBgYHtyLCBmaWcud2lkdGg9MTEuNSwgZmlnLmhlaWdodD0yfQ0KDQpjb21mb3J0X2NvbWJpIDwtIHBsb3RfZ3JpZChtb3JlX29yX2xlc3NfY29tZm9ydGFibGVfd2l0aF9hci5wbG90LCBob3dfY29tZm9ydGFibGVfd2l0aF9hci5wbG90LA0KICAgICAgICAgIG5jb2wgPSAyLCByZWxfd2lkdGhzID0gYygxLjAsMS4wKSkNCg0KcHJpbnQoY29tZm9ydF9jb21iaSkNCkV4cG9ydFBsb3QoY29tZm9ydF9jb21iaSwgImNvbWZvcnRfY29tYmkiLCAxMS41LCAyLCBkb1BERj1UUlVFKQ0KYGBgDQoNCg==