This notebook provides the plots for the article: Heyne, M., Derrick, D., and Al-Tamimi, J. (under review). “Native language influence on brass instrument performance: An application of generalized additive mixed models (GAMMs) to midsagittal ultrasound images of the tongue”. Frontiers Research Topic: Models and Theories of Speech Production. Ed. Adamantios Gafos & Pascal van Lieshout.

1 Loading packages

load_packages = c("readr","knitr","ggplot2","mgcv","itsadug","parallel","dplyr","rlist","plotly")
# dplyr, rlist, and plotly are required by the custom plotting functions
for(pkg in load_packages){
  eval(bquote(library(.(pkg))))
  if (paste0("package:", pkg) %in% search()){
    cat(paste0("Successfully loaded the ", pkg, " package.\n"))
  }else{
    install.packages(pkg)
    eval(bquote(library(.(pkg))))
    if (paste0("package:", pkg) %in% search()){
      cat(paste0("Successfully loaded the ", pkg, " package.\n"))
    }
  }
}
Successfully loaded the readr package.
Successfully loaded the knitr package.
Successfully loaded the ggplot2 package.
Successfully loaded the mgcv package.
Successfully loaded the itsadug package.
Successfully loaded the parallel package.
Successfully loaded the dplyr package.
Successfully loaded the rlist package.
Successfully loaded the plotly package.
rm(load_packages, pkg)
Sys.setenv('MAPBOX_TOKEN' = 'sk.eyJ1IjoiZGRlcnJpY2siLCJhIjoiY2p2MW1ndnNoMXczYTRkbXd6dzRuMTQ2aCJ9.UTai4wWcFFVaJAuOrAX7VQ')
# decide whether to save plots as PDF and jpg files using the Orca command line utility
save=FALSE
printPDF=FALSE

1.1 Loading custom plotting functions

1.1.1 plotly_model_outputs function (Matthias Heyne, 2019)

# plot multiple GAM model outputs
plotly_model_outputs <- function(model, changing_cond, changing_var, constant_cond1, constant_var1, values, constant_cond2=NULL, constant_var2=NULL, print=TRUE){
  if(length(constant_var1)>1 | length(constant_var2)>1){
    print("Error: Constant variables can only have length 1.")
  }else{
    if(!is.null(constant_cond2) && !is.null(constant_var2) && length(changing_var)==2){
      # works for models Notes.gam...
      cond_p1 = capture.output(cat(paste0("list(", changing_cond, "='", changing_var[1], "', ", constant_cond1, "='", constant_var1, "', ", constant_cond2, "='", constant_var2, "')")))
      p1=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p1)))
      cond_p2 = capture.output(cat(paste0("list(", changing_cond, "='", changing_var[2], "', ", constant_cond1, "='", constant_var1, "', ", constant_cond2, "='", constant_var2, "')")))
      p2=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p2)))
      
      # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
      max_ul = max(p1$fv$ul, p2$fv$ul)
      max_fit = max(p1$fv$fit, p2$fv$fit)
      maximum=max_fit+((max_ul-max_fit)/2)
      
      # plot in polar coordinates
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=changing_var[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=changing_var[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=paste0("GAM smooths @", constant_var1, " & ", constant_var2), 
               legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
      p
    }else if(is.null(constant_cond2) && is.null(constant_var2) && length(changing_var)==2){
      # no specific case yet
      cond_p1 = capture.output(cat(paste0("list(", changing_cond, "='", changing_var[1], "', ", constant_cond1, "='", constant_var1, "')")))
      p1=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p1)))
      cond_p2 = capture.output(cat(paste0("list(", changing_cond, "='", changing_var[2], "', ", constant_cond1, "='", constant_var1, "')")))
      p2=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p2)))
      
      # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
      max_ul = max(p1$fv$ul, p2$fv$ul)
      max_fit = max(p1$fv$fit, p2$fv$fit)
      maximum=max_fit+((max_ul-max_fit)/2)
      
      # plot in polar coordinates
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=changing_var[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=changing_var[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=paste0("GAM smooths @", constant_var1, " & ", constant_var2), 
               legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
      p
    }else if(is.null(constant_cond2) && is.null(constant_var2) && length(changing_var)>2){
      # works for models NZE.gam... or Tongan.gam...
      for (i in 1:length(changing_var)){
        if(changing_cond == constant_cond1){
          cond_p1 = capture.output(cat(paste0("list(", constant_cond1, "='", constant_var1, "')")))
          p1=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p1)))
          # exception for KIT (='\\\\') when not using IPA symbols
          if (changing_var[i]!="\\\\"){
            cond_p2 = capture.output(cat(paste0("list(", changing_cond, "='", changing_var[i], "')")))
            p2=plot_smooth(x=get(model), view=values, cond = eval(parse(text=cond_p2)))
          }else{
            p2=plot_smooth(x=get(model), view=values, cond = list(token.ord='\\\\'))
          }
          
          # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
          max_ul = max(p1$fv$ul, p2$fv$ul)
          max_fit = max(p1$fv$fit, p2$fv$fit)
          maximum=max_fit+((max_ul-max_fit)/2)
          # plot in polar coordinates
          p=plot_ly(type='scatterpolar', mode='lines') %>% 
            add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=constant_var1) %>% 
            add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
            add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
            add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=changing_var[i]) %>% 
            add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
            add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
            layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                              angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
                   title=paste0("GAM smooths ",constant_var1," vs ", changing_var[i]), 
                   legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
          Sys.sleep(0)
          print(p)
        }
      }
    }
  }
}

1.1.2 plotly_sig_diff_notes function (Matthias Heyne, 2019) -> with updated legend position

# plot smooths with shading to indicate significant differences (Matthias Heyne, 2019)
plotly_smooths_w_sig_diff <- function(model, condition, var1, var2, values, language, fileName, print=TRUE, save=TRUE){
  # specify path for saving plots
  # plot_folder = "saved_plots"
  # Sys.setenv(MAPBOX_TOKEN = 11122223333444)
  # get intervals of significant differences by running plot_diff
  # unfortunately setting plot=FALSE doesn't work as intervals of significant difference are not displayed!
  # hardcoded condition
  # output = capture.output(plot_diff(get(model), view=values, 
  #                                   comp=list(tokenPooled.ord=c(var1, var2))))
  # output = capture.output(plot_diff(get(model), view=values, comp=list(langNoteInt.ord=c(paste0("Tongan.", note, ".", intensity), paste0("NZE.", note, ".", intensity)))))
  names_smooths=list()
  if (condition=="tokenPooled.ord" && length(language)==1){
    output_comp = capture.output(cat(paste0("list(", condition, "=c(var1, var2))")))
    names_smooths[1]=var1
    names_smooths[2]=var2
    plot_title = paste0("GAM smooths ", language, " ", var1, " vs ", var2)
    # plot_filename = paste0(language, "_", var1, "_vs_", var2, "_from_", model)
  }else if (condition=="langNoteInt.ord" && length(language)==2){
    output_comp = capture.output(cat(paste0("list(", condition, "=c('", language[1], ".", var1, ".", var2, 
                                            "', '", language[2], ".", var1, ".", var2, "'))")))
    names_smooths[1]=paste0(language[1], ".", var1, ".", var2)
    names_smooths[2]=paste0(language[2], ".", var1, ".", var2)
    plot_title = paste0("GAM smooths ", language[1], ".", var1, ".", var2, " vs ", language[2], ".", var1, ".", var2)
    # plot_filename = paste0(language[1], ".", var1, ".", var2, "_vs_", language[2], ".", var1, ".", var2, "_from_", model)
  }else if (condition=="langNoteInt.ord" && length(language)==1 && length(var1)==2){
    output_comp = capture.output(cat(paste0("list(", condition, "=c('", language, ".", var1[1], ".", var2, 
                                            "', '", language, ".", var1[2], ".", var2, "'))")))
    names_smooths[1]=paste0(language, ".", var1[1], ".", var2)
    names_smooths[2]=paste0(language, ".", var1[2], ".", var2)
    plot_title = paste0("GAM smooths ", language, ".", var1[1], ".", var2, " vs ", language, ".", var1[2], ".", var2)
    # plot_filename = paste0(language, ".", var1[1], ".", var2, "_vs_", language, ".", var1[2], ".", var2, "_from_", model)
  }
  # output_comp = capture.output(cat(paste0("list(", condition, "=c(var1, var2))")))
  output = capture.output(plot_diff(get(model), view=values, comp=eval(parse(text=output_comp))))
  # no significant difference
  if ((length(language)==1 && length(var1)==1 && length(output)==7) | (length(language)==2 && length(output)==6) | 
    (length(language)==1 && length(var1)==2 && length(output)==6)){
    if (length(var1)==1){
      cat(paste0("Smooths for ", var1, " & ", var2, " are not significantly different.\n"))
      dat1 = NA
      assign(paste0("int_sig_diff_", var1, "_", var2), dat1, envir = .GlobalEnv)
    }else{
      cat(paste0("Smooths for ", var1[1], " & ", var1[2], " in ", language, " are not significantly different.\n"))
      dat1 = NA
      assign(paste0("int_sig_diff_", var1[1], "_", var1[2], "_", var2, "_", language), dat1, envir = .GlobalEnv)
    }
    rm(dat1, output)
    # run plot_smooth to grab data for polar plots
    if (condition=="tokenPooled.ord" && length(language)==1){
      cond_p1 = capture.output(cat(paste0("list(", condition, "=var1)")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "=var2)")))
    }else if (condition=="langNoteInt.ord" && length(language)==2){
      cond_p1 = capture.output(cat(paste0("list(", condition, "='", language[1], ".", var1, ".", var2, 
                                          "', ", condition, "='", language[2], ".", var1, ".", var2, "')")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "='", language[2], ".", var1, ".", var2, 
                                          "', ", condition, "='", language[1], ".", var1, ".", var2, "')")))
    }else if (condition=="langNoteInt.ord" && length(language)==1 && length(var1)==2){
      cond_p1 = capture.output(cat(paste0("list(", condition, "='", language, ".", var1[1], ".", var2, 
                                          "', ", condition, "='", language, ".", var1[2], ".", var2, "')")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "='", language, ".", var1[2], ".", var2, 
                                          "', ", condition, "='", language, ".", var1[1], ".", var2, "')")))
    }
    p1 = plot_smooth(x=get(model), view=values, cond=eval(parse(text=cond_p1)), rm.ranef=TRUE)
    p2 = plot_smooth(x=get(model), view=values, cond=eval(parse(text=cond_p2)), rm.ranef=TRUE)
    # # old - hardcoded
    # p1 = plot_smooth(x=get(model), view=values, cond=list(tokenPooled.ord=var1, tokenPooled.ord=var2))
    # p2 = plot_smooth(x=get(model), view=values, cond=list(tokenPooled.ord=var2, tokenPooled.ord=var1))
    # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
    maximum=max(p1$fv$fit, p2$fv$fit)+((max(p1$fv$ul, p2$fv$ul)-max(p1$fv$fit, p2$fv$fit))/2)
    # plot in polar coordinates
    p=plot_ly(type='scatterpolar', mode='lines') %>% 
      add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=names_smooths[1]) %>% 
      add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
      add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash",  width=0.5), showlegend=FALSE) %>% 
      add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=names_smooths[2]) %>% 
      add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
      add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
      layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                        angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
             title=paste0("GAM smooths ", language, " ", var1, " vs ", var2), 
             legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
    Sys.sleep(0)
    print(p)
  # there are differences...
  }else{
    # grab intervals of significant differences from output
    if (length(language)==1 && length(var1)==1 && length(output)>=8){
    # if (length(language)==1 && length(output)>=8){
      sig_diff1 = c(as.double(unlist(strsplit(unlist(strsplit(output[8], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[8], " "))[3]))
    }else if ((length(language)==2 && length(output)>=7) | (length(language)==1 && length(var1)==2 && length(output)>=7)){
    # }else if (length(language)==2 && length(output)>=7){
      sig_diff1 = c(as.double(unlist(strsplit(unlist(strsplit(output[7], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[7], " "))[3]))
    }
    if (length(language)==1 && length(var1)==1 && length(output)>=9){
    # if (length(language)==1 && length(output)>=9){
      sig_diff2 = c(as.double(unlist(strsplit(unlist(strsplit(output[9], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[9], " "))[3]))
    }else if ((length(language)==2 && length(output)>=8) | (length(language)==1 && length(var1)==2 && length(output)>=8)){
    # }else if (length(language)==2 && length(output)>=8){
      sig_diff2 = c(as.double(unlist(strsplit(unlist(strsplit(output[8], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[8], " "))[3]))
    }
    if (length(language)==1 && length(var1)==1 && length(output)>=10){
    # if (length(language)==1 && length(output)>=10){
      sig_diff3 = c(as.double(unlist(strsplit(unlist(strsplit(output[10], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[10], " "))[3]))
    }else if ((length(language)==2 && length(output)>=9) | (length(language)==1 && length(var1)==2 && length(output)>=9)){
    # }else if (length(language)==2 && length(output)>=9){
      sig_diff3 = c(as.double(unlist(strsplit(unlist(strsplit(output[9], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[9], " "))[3]))
    }
    if (length(language)==1 && length(var1)==1 && length(output)>=11){
    # if (length(language)==1 && length(output)>=11){
      sig_diff4 = c(as.double(unlist(strsplit(unlist(strsplit(output[11], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[11], " "))[3]))
    }else if ((length(language)==2 && length(output)>=10) | (length(language)==1 && length(var1)==2 && length(output)>=10)){
    # }else if (length(language)==2 && length(output)>=10){
      sig_diff4 = c(as.double(unlist(strsplit(unlist(strsplit(output[10], " "))[1], "\t"))[2]), as.double(unlist(strsplit(output[10], " "))[3]))
    }
    
    # write intervals of significant difference to variable
    if ((length(language)==1 && length(var1)==1 && length(output)>=11) | ((length(language)==2 && length(output)>=10)) | 
        (length(language)==1 && length(var1)==2 && length(output)>=10)){
    # if ((length(language)==1 && length(output)>=11) | (length(language)==2 && length(output)>=10)){
      dat1 = c(sig_diff1, sig_diff2, sig_diff3, sig_diff4)
    }else if ((length(language)==1 && length(var1)==1 && length(output)>=10) | ((length(language)==2 && length(output)>=9)) | 
              (length(language)==1 && length(var1)==2 && length(output)>=9)){
    # }else if ((length(language)==1 && length(output)>=10) | (length(language)==2 && length(output)>=9)){
      dat1 = c(sig_diff1, sig_diff2, sig_diff3)
    }else if ((length(language)==1 && length(var1)==1 && length(output)>=9) | ((length(language)==2 && length(output)>=8)) | 
              (length(language)==1 && length(var1)==2 && length(output)>=8)){
    # }else if ((length(language)==1 && length(output)>=9) | (length(language)==2 && length(output)>=8)){
      dat1 = c(sig_diff1, sig_diff2)
    }else{
      dat1 = sig_diff1
    }
    # old
    # assign(paste0("int_sig_diff_", var1, "_", var2), dat1, envir = .GlobalEnv)
    if (length(var1)==1){
      assign(paste0("int_sig_diff_", var1, "_", var2), dat1, envir = .GlobalEnv)
    }else{
      assign(paste0("int_sig_diff_", var1[1], "_", var1[2], "_", var2, "_", language), dat1, envir = .GlobalEnv)
    }
    rm(dat1, output)
    # run plot_smooth to grab data for polar plots
    if (condition=="tokenPooled.ord" && length(language)==1){
      cond_p1 = capture.output(cat(paste0("list(", condition, "=var1)")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "=var2)")))
    }else if (condition=="langNoteInt.ord" && length(language)==2){
      cond_p1 = capture.output(cat(paste0("list(", condition, "='", language[1], ".", var1, ".", var2, 
                                "', ", condition, "='", language[2], ".", var1, ".", var2, "')")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "='", language[2], ".", var1, ".", var2, 
                                          "', ", condition, "='", language[1], ".", var1, ".", var2, "')")))
    }else if (condition=="langNoteInt.ord" && length(language)==1 && length(var1)==2){
      cond_p1 = capture.output(cat(paste0("list(", condition, "='", language, ".", var1[1], ".", var2, 
                                          "', ", condition, "='", language, ".", var1[2], ".", var2, "')")))
      cond_p2 = capture.output(cat(paste0("list(", condition, "='", language, ".", var1[2], ".", var2, 
                                          "', ", condition, "='", language, ".", var1[1], ".", var2, "')")))
    }
    p1 = plot_smooth(x=get(model), view=values, cond=eval(parse(text=cond_p1)), rm.ranef=TRUE)
    p2 = plot_smooth(x=get(model), view=values, cond=eval(parse(text=cond_p2)), rm.ranef=TRUE)
    # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
    maximum=max(p1$fv$fit, p2$fv$fit)+((max(p1$fv$ul, p2$fv$ul)-max(p1$fv$fit, p2$fv$fit))/2)
    # plot in polar coordinates
    if (exists("sig_diff4")){
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=names_smooths[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=names_smooths[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff1[1]*180/pi, sig_diff1[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff2[1]*180/pi, sig_diff2[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff3[1]*180/pi, sig_diff3[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff4[1]*180/pi, sig_diff4[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=plot_title, legend=list(orientation="h", xanchor="center", x=0.5, y=0.012))
      Sys.sleep(0)
      print(p)
    }else if (exists("sig_diff3")){
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=names_smooths[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=names_smooths[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff1[1]*180/pi, sig_diff1[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff2[1]*180/pi, sig_diff2[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff3[1]*180/pi, sig_diff3[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=plot_title, legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
      Sys.sleep(0)
      print(p)
    }else if (exists("sig_diff2")){
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=names_smooths[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=names_smooths[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff1[1]*180/pi, sig_diff1[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff2[1]*180/pi, sig_diff2[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=plot_title, legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
      Sys.sleep(0)
      print(p)
    }else{
      p=plot_ly(type='scatterpolar', mode='lines') %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color="blue", dash="dash", width=2.5), name=names_smooths[1]) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color="blue", dash="dash", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color="red", width=2.5), name=names_smooths[2]) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>% 
        add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color="red", dash="dot", width=0.5), showlegend=FALSE) %>%
        add_trace(theta=seq(sig_diff1[1]*180/pi, sig_diff1[2]*180/pi, length.out=20), 
                  r=c(0, rep(maximum, 18), 0), line=list(color="black", width=0.5), fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
        layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                          angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
               title=plot_title, legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
      Sys.sleep(0)
      print(p)
    }
  }
  # orca should work with plotly 4.9.0 after loading the orca module before stating R and RStudio
  if(save==TRUE)
  {
    orca(p, paste(fileName,".pdf",sep=""),format="pdf")
    orca(p, paste(fileName,".pdf",sep=""),format="jpeg")
  }
}

2 Load final models

# load final model for H1
Notes.gam.AR.Mod2 = readRDS("updated_models/Notes.gam.AR.Mod2.rds")
# load final model for H1b
VAR.gam.AR.Mod2 = readRDS("updated_models/VAR.gam.AR.Mod2.rds")
# load final models for H2
NZE.gam.AR.Mod2 = readRDS("updated_models/NZE.gam.AR.Mod2.rds")
Tongan.gam.AR.Mod2 = readRDS("updated_models/Tongan.gam.AR.Mod2.rds")

3 Create paper plots

3.1 (new) Figure 4 H1 -> predict average values for note productions NZE vs Tongan

# create dfNotes
df <- read.csv("GAMM_Trombone_data.csv", sep=',', stringsAsFactors = F)
# remove empty column
df$X = NULL
df$tokenPooled <- factor(df$tokenPooled)
df$subject <- factor(df$subject)
df$native_lg <- factor(df$native_lg)
# df$playing_proficiency[df$playing_proficiency == "intermediate"] <- "amateur"
df$playing_proficiency <- factor(df$playing_proficiency, levels = c("amateur","intermediate","semi-professional","professional"))
df$block <- factor(df$block)
df$point <- as.numeric(df$point)
df$note_intensity <- factor(df$note_intensity, levels = c("piano","mezzopiano","mezzoforte","forte"))
# remove fortissimo tokens
df = df[!(is.na(df$note_intensity) & df$activity=="music"),]
dfNotes <- subset(df,df$tokenPooled == "Bb2"|
                    df$tokenPooled == "Bb3"|
                    df$tokenPooled == "D4"|
                    df$tokenPooled == "F3"|
                    df$tokenPooled == "F4")
dfNotes$tokenPooled <- factor(dfNotes$tokenPooled, levels = c("Bb2","F3","Bb3","D4","F4"))
dfNotes <- subset(dfNotes,dfNotes$note_intensity == "forte"|
                    dfNotes$note_intensity == "mezzoforte"|
                    dfNotes$note_intensity == "mezzopiano"|
                    dfNotes$note_intensity == "piano")
dfNotes$note_intensity <- factor(dfNotes$note_intensity, levels = c("piano","mezzopiano","mezzoforte","forte"))
dfNotes$noteIntenInt <- interaction(dfNotes$tokenPooled, dfNotes$note_intensity)
dfNotes$langNoteInt <- interaction(dfNotes$native_lg, dfNotes$tokenPooled, dfNotes$note_intensity)
dfNotes$native_lg.ord <- as.ordered(dfNotes$native_lg)
contrasts(dfNotes$native_lg.ord) <- "contr.treatment"
dfNotes$tokenPooled.ord <- as.ordered(dfNotes$tokenPooled)
contrasts(dfNotes$tokenPooled.ord) <- "contr.treatment"
dfNotes$note_intensity.ord <- as.ordered(dfNotes$note_intensity)
contrasts(dfNotes$note_intensity.ord) <- "contr.treatment"
dfNotes$langNoteInt.ord <- as.ordered(dfNotes$langNoteInt)
contrasts(dfNotes$langNoteInt.ord) <- "contr.treatment"
dfNotes$start <- dfNotes$points==1
# make copy of dfNotes
dat1 = dfNotes
dat1$predicted_values = predict(Notes.gam.AR.Mod2)
# plot in polar coordinates using plotly
dat1_NZE = dat1[dat1$native_lg == "NZE",]
dat1_Tongan = dat1[dat1$native_lg == "Tongan",]
# estimate smooths using R's generic predict.smooth.spline function
smooth_NZE=list(theta=seq(min(dat1_NZE$theta_uncut_z)*180/pi, max(dat1_NZE$theta_uncut_z)*180/pi, length=100), r=predict(smooth.spline(dat1_NZE$theta_uncut_z, dat1_NZE$predicted_values),
 seq(min(dat1_NZE$theta_uncut_z), max(dat1_NZE$theta_uncut_z), length=100))$y, line=list(color="blue", dash="dash"))
smooth_Tongan=list(theta=seq(min(dat1_Tongan$theta_uncut_z)*180/pi, max(dat1_Tongan$theta_uncut_z)*180/pi, length=100), r=predict(smooth.spline(dat1_Tongan$theta_uncut_z, dat1_Tongan$predicted_values),
 seq(min(dat1_Tongan$theta_uncut_z), max(dat1_Tongan$theta_uncut_z), length=100))$y, line=list(color="red", dash=""))
# set Rho max to the max of the predicted_values + 5
max_predictions = max(max(smooth_NZE$r), max(smooth_Tongan$r))
maximum=max_predictions+5
rm(max_predictions)
p = plot_ly(type='scatterpolar', mode='lines') %>%
add_trace(theta=smooth_NZE$theta, r=smooth_NZE$r, line=list(color=smooth_NZE$line$color[[1]], width=2.5, dash=smooth_NZE$line$dash[[1]]), name="overall average of NZE notes") %>%
  add_trace(theta=smooth_Tongan$theta, r=smooth_Tongan$r, line=list(color=smooth_Tongan$line$color[[1]], width=2.5, dash=smooth_Tongan$line$dash[[1]]), name="overall average of Tongan notes") %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)), angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), title="Overall average smooths for NZE vs Tongan note productions", legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
p

if(save==TRUE){
  orca(p, "Figure4.pdf",format="pdf")
  orca(p, "Figure4.jpg",format="jpeg")
}
rm(dat1, dat1_NZE, dat1_Tongan, maximum, smooth_NZE, smooth_Tongan)

3.2 Figure 5 (previously 4) -> H1

3.2.1 Bb2 forte

plotly_smooths_w_sig_diff(model="Notes.gam.AR.Mod2", condition="langNoteInt.ord", var1="Bb2", 
                          var2="forte", values="theta_uncut_z", 
                          language=c("NZE","Tongan"), fileName = "Figure5(a)", save=printPDF)
Summary:
    * langNoteInt.ord : factor; set to the value(s): NZE.Bb2.forte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

Summary:
    * langNoteInt.ord : factor; set to the value(s): Tongan.Bb2.forte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

3.2.2 F3 mezzoforte

plotly_smooths_w_sig_diff(model="Notes.gam.AR.Mod2", condition="langNoteInt.ord", var1="F3", 
                          var2="mezzoforte", values="theta_uncut_z",
                          language=c("NZE","Tongan"), ,fileName = "Figure5(b)",save=printPDF)
Summary:
    * langNoteInt.ord : factor; set to the value(s): NZE.F3.mezzoforte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

Summary:
    * langNoteInt.ord : factor; set to the value(s): Tongan.F3.mezzoforte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

3.2.3 Bb3 mezzoforte

plotly_smooths_w_sig_diff(model="Notes.gam.AR.Mod2", condition="langNoteInt.ord", var1="Bb3", 
                          var2="mezzoforte", values="theta_uncut_z", 
                          language=c("NZE","Tongan"),fileName = "Figure5(c)",save=printPDF)
Summary:
    * langNoteInt.ord : factor; set to the value(s): NZE.Bb3.mezzoforte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

Summary:
    * langNoteInt.ord : factor; set to the value(s): Tongan.Bb3.mezzoforte. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.654831. 
    * subject : factor; set to the value(s): S3. (Might be canceled as random effect, check below.) 
    * noteIntenInt : factor; set to the value(s): F3.mezzoforte. 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subject):noteIntenIntBb2.piano,s(theta_uncut_z,subject):noteIntenIntF3.piano,s(theta_uncut_z,subject):noteIntenIntBb3.piano,s(theta_uncut_z,subject):noteIntenIntD4.piano,s(theta_uncut_z,subject):noteIntenIntF4.piano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb3.mezzopiano,s(theta_uncut_z,subject):noteIntenIntD4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntF4.mezzopiano,s(theta_uncut_z,subject):noteIntenIntBb2.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb3.mezzoforte,s(theta_uncut_z,subject):noteIntenIntD4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntF4.mezzoforte,s(theta_uncut_z,subject):noteIntenIntBb2.forte,s(theta_uncut_z,subject):noteIntenIntF3.forte,s(theta_uncut_z,subject):noteIntenIntBb3.forte,s(theta_uncut_z,subject):noteIntenIntD4.forte,s(theta_uncut_z,subject):noteIntenIntF4.forte
 

3.2.4 Intervals of significant difference 16 out of 19 comparisons

# read .csv file
sig_diffs = read.csv(file = "Notes.gam.AR.Mod2_intervals_of_significant_differences.csv", 
                     header=TRUE, row.names=1)
# Got rid of this plot!
# # visualize areas of overall difference
# p1=plot_ly(type='scatterpolar', mode='lines') %>%
#   add_trace(theta=seq(sig_diffs["17_out_of_19",1]*180/pi, sig_diffs["17_out_of_19",2]*180/pi, 
#                       length.out=20), r=c(0, rep(320, 18), 0), line=list(color="black", width=0.5), 
#             fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
#   add_trace(theta=seq(sig_diffs["17_out_of_19",3]*180/pi, sig_diffs["17_out_of_19",4]*180/pi, 
#                       length.out=20), r=c(0, rep(320, 18), 0), line=list(color="black", width=0.5), 
#             fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>% 
#   layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,320)),
#                         angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
#          title=paste0("Intervals of significant differences for 17 out of 19 comparisons"), 
#          legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
# Sys.sleep(0)
# print(p1)
p2=plot_ly(type='scatterpolar', mode='lines') %>%
  add_trace(theta=seq(sig_diffs["16_out_of_19",1]*180/pi, sig_diffs["16_out_of_19",2]*180/pi, 
                      length.out=20), r=c(0, rep(320, 18), 0), line=list(color="black", width=0.5), 
            fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>%
  add_trace(theta=seq(sig_diffs["16_out_of_19",3]*180/pi, sig_diffs["16_out_of_19",4]*180/pi, 
                      length.out=20), r=c(0, rep(320, 18), 0), line=list(color="black", width=0.5), 
            fill="toself", fillcolor=rgb(0,0,0,max=255,alpha=25), showlegend=FALSE) %>% 
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,320)),
                        angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
         title=paste0("Intervals of significant differences for 16 out of 19 comparisons"), 
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
Sys.sleep(0)
print(p2)

NULL
if(printPDF==TRUE)
{
  orca(p2, "Figure5(d).pdf",format="pdf")
  orca(p2, "Figure5(d).jpg",format="jpeg")
}
rm(sig_diffs, p1, p2)

3.3 Figure 6 -> H1b

# df already loaded above
dfSummary <- group_by(df, subject, playing_proficiency, activity, native_lg, tokenPooled, theta_uncut_z_group = cut(theta_uncut_z,breaks=100)) %>% summarise(rhoVar = sd(rho_uncut_z,na.rm=TRUE))
dfSummary$theta_uncut_z = as.character(dfSummary$theta_uncut_z_group)
dfSummary$theta_uncut_z = gsub("\\[|\\]|\\(|\\)", "",dfSummary$theta_uncut_z)
dfSummary$theta_uncut_z = strsplit(dfSummary$theta_uncut_z,",")
dfSummary$theta_uncut_z2 = 1
for(i in c(1:nrow(dfSummary)))
{
  dfSummary$theta_uncut_z2[i] = mean(as.numeric(unlist(dfSummary$theta_uncut_z[i])))
}
dfSummary$theta_uncut_z=dfSummary$theta_uncut_z2
dfSummary$playing_proficiency.ord <- as.ordered(dfSummary$playing_proficiency)
contrasts(dfSummary$playing_proficiency.ord) <- "contr.treatment"
dfSummary$activity.ord <- as.ordered(dfSummary$activity)
contrasts(dfSummary$activity.ord) <- "contr.treatment"
dfSummary$langNoteInt <- interaction(dfSummary$native_lg, 
dfSummary$tokenPooled)
dfSummary$langNoteInt.ord <- as.ordered(dfSummary$langNoteInt)
contrasts(dfSummary$langNoteInt.ord) <- "contr.treatment"
dfSummary$native_lg.ord <- as.ordered(dfSummary$native_lg)
contrasts(dfSummary$native_lg.ord) <- "contr.treatment"
dfSummary$tokenPooled.ord <- as.ordered(dfSummary$tokenPooled)
contrasts(dfSummary$tokenPooled.ord) <- "contr.treatment"
dfSummary = na.omit(dfSummary)
#dfSummary$start <- dfSummary$theta_uncut_z==min(dfSummary$theta_uncut_z)
dfSummary$start = TRUE
for(i in unique(dfSummary$subject))
{
  dfSubject = subset(dfSummary,dfSummary$subject == i)
  for(j in unique(dfSubject$tokenPooled))
  {
    dfSummary$start[dfSummary$subject == i & dfSummary$tokenPooled == j] <- 
      dfSummary$theta_uncut_z[dfSummary$subject == i & dfSummary$tokenPooled == j] ==
      min(dfSummary$theta_uncut_z[dfSummary$subject == i & dfSummary$tokenPooled == j])
  }
}
# make copy of dfNotes
dat1 = dfSummary
dat1$predicted_values = predict(VAR.gam.AR.Mod2)
# plot in polar coordinates using plotly
dat1_NZE = dat1[dat1$native_lg == "NZE",]
dat1_Tongan = dat1[dat1$native_lg == "Tongan",]
# estimate smooths using R's generic predict.smooth.spline function
smooth_NZE=list(theta=seq(min(dat1_NZE$theta_uncut_z)*180/pi, max(dat1_NZE$theta_uncut_z)*180/pi, length=100), r=predict(smooth.spline(dat1_NZE$theta_uncut_z, dat1_NZE$predicted_values),
 seq(min(dat1_NZE$theta_uncut_z), max(dat1_NZE$theta_uncut_z), length=100))$y, line=list(color="blue", dash="dash"))
smooth_Tongan=list(theta=seq(min(dat1_Tongan$theta_uncut_z)*180/pi, max(dat1_Tongan$theta_uncut_z)*180/pi, length=100), r=predict(smooth.spline(dat1_Tongan$theta_uncut_z, dat1_Tongan$predicted_values),
 seq(min(dat1_Tongan$theta_uncut_z), max(dat1_Tongan$theta_uncut_z), length=100))$y, line=list(color="red", dash=""))
# set Rho max to the max of the predicted_values + 5
max_predictions = max(max(smooth_NZE$r), max(smooth_Tongan$r))
maximum=max_predictions+5
rm(max_predictions)
p = plot_ly(type='scatterpolar', mode='lines') %>%
add_trace(theta=smooth_NZE$theta, r=smooth_NZE$r, line=list(color=smooth_NZE$line$color[[1]], width=2.5, dash=smooth_NZE$line$dash[[1]]), name="overall average of NZE notes") %>%
  add_trace(theta=smooth_Tongan$theta, r=smooth_Tongan$r, line=list(color=smooth_Tongan$line$color[[1]], width=2.5, dash=smooth_Tongan$line$dash[[1]]), name="overall average of Tongan notes") %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)), angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), title="Overall average smooths for NZE vs Tongan note productions", legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
p

if(printPDF==TRUE)
{
  orca(p, "Figure6.pdf",format="pdf")
  orca(p, "Figure6.jpg",format="jpeg")
}
rm(dat1, dat1_NZE, dat1_Tongan, maximum, smooth_NZE, smooth_Tongan)

3.4 Figure 7 -> H2 vowels and notes NZE

3.4.1 All NZE vowels

# define colors from PhD thesis
RED0 = (rgb(213,13,11, 255, maxColorValue=255))
BROWN0 = (rgb(123,73,55,255, maxColorValue=255))
PURPLE0 = (rgb(143,72,183,255, maxColorValue=255))
GRAY0 = (rgb(108,108,108,255, maxColorValue=255))
GREEN0 = (rgb(0,151,55,255, maxColorValue=255))
ORANGE0 = (rgb(255,123,0,255, maxColorValue=255))
PINK0 = (rgb(224,130,180,255, maxColorValue=255))
TEAL0 = (rgb(0,175,195,255, maxColorValue=255))
GOLD0 = (rgb(172,181,0,255, maxColorValue=255))
light_blue=rgb(0,117,220,255,maxColorValue=255)
black=rgb(25,25,25,255,maxColorValue=255)
pink=rgb(194,0,136,255,maxColorValue=255)
dark_blue=rgb(0,51,128,255,maxColorValue=255)
dark_red=rgb(153,0,0,255,maxColorValue=255)
# correct order
colors = c(ORANGE0, dark_blue, GREEN0, light_blue, PINK0, GOLD0, BROWN0, TEAL0, GRAY0, dark_red,
           RED0, PURPLE0, pink)
# run plot_smooth to grab values for fit, upper & lower bounds
p1=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="iː"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): iː. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="e"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): e. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ʉː"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ʉː. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɛ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɛ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɵː"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɵː. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p6=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɘ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɘ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p7=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p8=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ʊ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ʊ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p9=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə#"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə#. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p10=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɐ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɐ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p11=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɐː"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɐː. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p12=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɒ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɒ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p13=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="oː"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): oː. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("FLEECE /iː/","DRESS /e/","GOOSE /ʉː/","TRAP /ɛ/","NURSE /ɵː/","KIT /ɘ/",
               "non-final schwa /ə/","FOOT /ʊ/","final schwa /ə#/","STRUT /ɐ/","START /ɐː/",
               "LOT /ɒ/","THOUGHT /oː/")
# # set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
# max_ul = max(p1$fv$ul, p2$fv$ul, p3$fv$ul, p4$fv$ul, p5$fv$ul, p6$fv$ul, p7$fv$ul, p8$fv$ul, p9$fv$ul, p10$fv$ul, p11$fv$ul, p12$fv$ul, p13$fv$ul)
# max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit, p6$fv$fit, p7$fv$fit, p8$fv$fit, p9$fv$fit, p10$fv$fit, p11$fv$fit, p12$fv$fit, p13$fv$fit)
# maximum=max_fit+((max_ul-max_fit)/2)
# rm(max_ul, max_fit)
# 
# # plot in polar coordinates with confidence bounds
# plot1=plot_ly(type='scatterpolar', mode='lines') %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], dash="dash", width=2.5), name=smooth_names[1]) %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color=colors[1], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color=colors[1], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], width=2.5),
#             name=smooth_names[2]) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], width=2.5),
#             name=smooth_names[3]) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ul, line=list(color=colors[3], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ll, line=list(color=colors[3], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dash", width=2.5), name=smooth_names[4]) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ul, line=list(color=colors[4], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ll, line=list(color=colors[4], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=2.5),
#             name=smooth_names[5]) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ul, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ll, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$fit, line=list(color=colors[6], dash="dash", width=2.5), name=smooth_names[6]) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$ul, line=list(color=colors[6], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$ll, line=list(color=colors[6], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$fit, line=list(color=colors[7], width=2.5),
#             name=smooth_names[7]) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$ul, line=list(color=colors[7], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$ll, line=list(color=colors[7], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$fit, line=list(color=colors[8], dash="dash", width=2.5), name=smooth_names[8]) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$ul, line=list(color=colors[8], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$ll, line=list(color=colors[8], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$fit, line=list(color=colors[9], width=2.5),
#             name=smooth_names[9]) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$ul, line=list(color=colors[9], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$ll, line=list(color=colors[9], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$fit, line=list(color=colors[10], width=2.5),
#             name=smooth_names[10]) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$ul, line=list(color=colors[10], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$ll, line=list(color=colors[10], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p11$fv$theta_uncut_z*180/pi, r=p11$fv$fit, line=list(color=colors[11], width=2.5),
#             name=smooth_names[11]) %>%
#   add_trace(theta=p11$fv$theta_uncut_z*180/pi, r=p11$fv$ul, line=list(color=colors[11], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p11$fv$theta_uncut_z*180/pi, r=p11$fv$ll, line=list(color=colors[11], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p12$fv$theta_uncut_z*180/pi, r=p12$fv$fit, line=list(color=colors[12], dash="dash", width=2.5), name=smooth_names[12]) %>%
#   add_trace(theta=p12$fv$theta_uncut_z*180/pi, r=p12$fv$ul, line=list(color=colors[12], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p12$fv$theta_uncut_z*180/pi, r=p12$fv$ll, line=list(color=colors[12], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p13$fv$theta_uncut_z*180/pi, r=p13$fv$fit, line=list(color=colors[13], width=2.5),
#             name=smooth_names[13]) %>%
#   add_trace(theta=p13$fv$theta_uncut_z*180/pi, r=p13$fv$ul, line=list(color=colors[13], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p13$fv$theta_uncut_z*180/pi, r=p13$fv$ll, line=list(color=colors[13], dash="dot", width=0.5), showlegend=FALSE) %>%
#   layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
#                     angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
#          title="All vowels produced by NZE speakers")
# plot1
# set Rho max to the max of the fit + 5
max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit, p6$fv$fit, p7$fv$fit, p8$fv$fit, p9$fv$fit, p10$fv$fit, p11$fv$fit, p12$fv$fit, p13$fv$fit)
maximum=max_fit+5
rm(max_fit)
# plot in polar coordinates without confidence bounds
plot2=plot_ly(type='scatterpolar', mode='lines') %>%
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], dash="dash", width=2.5), name=smooth_names[1]) %>%
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], width=2.5),
            name=smooth_names[2]) %>%
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], width=2.5),
            name=smooth_names[3]) %>%
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dash", width=2.5), name=smooth_names[4]) %>%
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=2.5),
            name=smooth_names[5]) %>%
  add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$fit, line=list(color=colors[6], dash="dash", width=2.5), name=smooth_names[6]) %>%
  add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$fit, line=list(color=colors[7], width=2.5),
            name=smooth_names[7]) %>%
  add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$fit, line=list(color=colors[8], dash="dash", width=2.5), name=smooth_names[8]) %>%
  add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$fit, line=list(color=colors[9], width=2.5),
            name=smooth_names[9]) %>%
  add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$fit, line=list(color=colors[10], width=2.5),
            name=smooth_names[10]) %>%
  add_trace(theta=p11$fv$theta_uncut_z*180/pi, r=p11$fv$fit, line=list(color=colors[11], width=2.5),
            name=smooth_names[11]) %>%
  add_trace(theta=p12$fv$theta_uncut_z*180/pi, r=p12$fv$fit, line=list(color=colors[12], dash="dash", width=2.5), name=smooth_names[12]) %>%
  add_trace(theta=p13$fv$theta_uncut_z*180/pi, r=p13$fv$fit, line=list(color=colors[13], width=2.5),
            name=smooth_names[13]) %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
         title="All vowels produced by NZE speakers",
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.008))
plot2

if(printPDF==TRUE)
{
  orca(plot2, "Figure7(a).pdf",format="pdf")
  orca(plot2, "Figure7(a).jpg",format="jpeg")
}
rm(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13)

3.4.2 All NZE notes

# correct order
colors = c(black, black, black, black, black)
p1=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb2"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb2. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="D4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): D4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("Bb2","F3","Bb3","D4","F4")
# set Rho max to the max of the fit + 5
#max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit)
#maximum=max_fit+5
#rm(max_fit)
# plot in polar coordinates without confidence bounds
p=plot_ly(type='scatterpolar', mode='lines') %>%
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5), name=smooth_names[1]) %>%
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], dash="dash", width=2.5), name=smooth_names[2]) %>%
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], dash="dot", width=2.5), name=smooth_names[3]) %>%
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dashdot", width=2.5), name=smooth_names[4]) %>%
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=1),
            name=smooth_names[5]) %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
         title="All notes produced by NZE speakers",
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
p

if(printPDF==TRUE)
{
  orca(p, "Figure7(b).pdf",format="pdf")
  orca(p, "Figure7(b).jpg",format="jpeg")
}
rm(p1,p2,p3,p4,p5)

3.5 Figure 8 -> H2 vowels and notes Tongan

3.5.1 All Tongan vowels

# use colors from PhD thesis (loaded above)
colors = c(ORANGE0, dark_blue, RED0, pink, GREEN0)
# run plot_smooth to grab values for fit, upper & lower bounds
p1=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="i"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): i. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="e"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): e. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="a"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): a. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="o"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): o. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="u"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): u. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("/i/","/e/","/a/","/o/","/u/")
# set Rho max to the max of the fit + half the difference between max of the fit and the upper limit
max_ul = max(p1$fv$ul, p2$fv$ul, p3$fv$ul, p4$fv$ul, p5$fv$ul)
max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit)
maximum=max_fit+((max_ul-max_fit)/2)
rm(max_ul, max_fit)
# plot in polar coordinates with confidence bounds
plot1=plot_ly(type='scatterpolar', mode='lines') %>% 
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5),
            name=smooth_names[1]) %>% 
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color=colors[1], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color=colors[1], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], width=2.5), 
            name=smooth_names[2]) %>% 
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>%
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], width=2.5), 
            name=smooth_names[3]) %>% 
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ul, line=list(color=colors[3], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ll, line=list(color=colors[3], dash="dot", width=0.5), showlegend=FALSE) %>%
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], width=2.5), 
            name=smooth_names[4]) %>% 
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ul, line=list(color=colors[4], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ll, line=list(color=colors[4], dash="dot", width=0.5), showlegend=FALSE) %>%
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=2.5), 
            name=smooth_names[5]) %>% 
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ul, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>% 
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ll, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
         title="All vowels produced by Tongan speakers",
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
plot1

# # set Rho max to the max of the fit + 5
# max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit)
# maximum=max_fit+5
# rm(max_fit)
# 
# # plot in polar coordinates with confidence bounds
# plot2=plot_ly(type='scatterpolar', mode='lines') %>% 
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5),
#             name=smooth_names[1]) %>% 
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], width=2.5), 
#             name=smooth_names[2]) %>% 
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], width=2.5), 
#             name=smooth_names[3]) %>% 
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], width=2.5), 
#             name=smooth_names[4]) %>% 
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=2.5), 
#             name=smooth_names[5]) %>% 
#   layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
#                     angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
#          title="All vowels produced by Tongan speakers",
#          legend=list(orientation="h", xanchor="center", x=0.5))
# plot2
if(printPDF==TRUE)
{
  orca(plot1, "Figure8(a).pdf",format="pdf")
  orca(plot1, "Figure8(a).jpg",format="jpeg")
}
  
rm(p1,p2,p3,p4,p5)

3.5.2 All Tongan notes

# use colors from PhD thesis (loaded above)
colors = c(black, black, black, black, black)
p1=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb2"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb2. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="D4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): D4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("Bb2","F3","Bb3","D4","F4")
# plot in polar coordinates without confidence bounds
p=plot_ly(type='scatterpolar', mode='lines') %>% 
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5), name=smooth_names[1]) %>% 
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], dash="dash", width=2.5), name=smooth_names[2]) %>% 
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], dash="dot", width=2.5), name=smooth_names[3]) %>% 
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dashdot", width=2.5), name=smooth_names[4]) %>% 
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=1), 
            name=smooth_names[5]) %>% 
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
         title="All notes produced by Tongan speakers",
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
p

if(printPDF==TRUE)
{
  orca(p, "Figure8(b).pdf",format="pdf")
  orca(p, "Figure8(b).jpg",format="jpeg")
}
  
rm(p1,p2,p3,p4,p5)

3.6 Figure 9 -> H2 selected vowels with notes

3.6.1 with NZE notes

colors = c(black, black, black, black, black,BROWN0, GRAY0, PURPLE0, pink, GREEN0)
# run plot_smooth to grab values for fit, upper & lower bounds
# NZE notes
p1=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb2"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb2. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="D4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): D4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

# vowels
p6=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p7=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə#"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə#. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p8=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɒ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɒ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p9=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="o"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): o. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p10=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="u"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): u. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("Bb2 NZE","F3 NZE","Bb3 NZE","D4 NZE","F4 NZE","non-final schwa /ə/ NZE","final schwa /ə#/ NZE","LOT /ɒ/ NZE","/o/ Tongan","/u/ Tongan")
# set Rho max to the max of the fit + 5
max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit, p6$fv$fit, p7$fv$fit, p8$fv$fit, p9$fv$fit, p10$fv$fit)
maximum=max_fit+5
rm(max_fit)
# plot in polar coordinates without confidence bounds
plot2=plot_ly(type='scatterpolar', mode='lines') %>%
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5), name=smooth_names[1]) %>%
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], dash="dash", width=2.5), name=smooth_names[2]) %>%
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], dash="dot", width=2.5), name=smooth_names[3]) %>%
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dashdot", width=2.5), name=smooth_names[4]) %>%
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=1), name=smooth_names[5]) %>%
  add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$fit, line=list(color=colors[6], width=2.5), name=smooth_names[6]) %>%
  add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$fit, line=list(color=colors[7], width=2.5), name=smooth_names[7]) %>%
  add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$fit, line=list(color=colors[8], dash="dash", width=2.5), name=smooth_names[8]) %>%
  add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$fit, line=list(color=colors[9], width=2.5), name=smooth_names[9]) %>%
  add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$fit, line=list(color=colors[10], width=2.5),
name=smooth_names[10]) %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
         title="Tongan & NZE vowels closest to playing position with NZE notes",legend=list(orientation="h", xanchor="center", x=0.5,y=0.008))
plot2

if(printPDF==TRUE)
{
  orca(plot2, "Figure9(a).pdf",format="pdf")
  orca(plot2, "Figure9(a).jpeg",format="jpeg")
}
rm(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)

3.6.2 with Tongan notes

colors = c(black, black, black, black, black,BROWN0, GRAY0, PURPLE0, pink, GREEN0)
# run plot_smooth to grab values for fit, upper & lower bounds
# Tongan notes
p1=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb2"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb2. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p2=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p3=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="Bb3"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): Bb3. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p4=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="D4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): D4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p5=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="F4"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): F4. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

# vowels
p6=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p7=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ə#"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ə#. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p8=plot_smooth(x=NZE.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="ɒ"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): ɒ. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.627597 to -0.617214. 
    * subVowelInt : factor; set to the value(s): S3.ə. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): coronals.ə. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p9=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="o"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): o. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

p10=plot_smooth(x=Tongan.gam.AR.Mod2, view="theta_uncut_z", cond=list(tokenPooled.ord="u"), rm.ranef=TRUE)
Summary:
    * tokenPooled.ord : factor; set to the value(s): u. 
    * theta_uncut_z : numeric predictor; with 30 values ranging from -2.648777 to -0.708619. 
    * subVowelInt : factor; set to the value(s): S16.F3. (Might be canceled as random effect, check below.) 
    * precSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * follSoundVowelInt : factor; set to the value(s): mezzoforte.F3. (Might be canceled as random effect, check below.) 
    * NOTE : The following random effects columns are canceled: s(theta_uncut_z,subVowelInt),s(theta_uncut_z,precSoundVowelInt),s(theta_uncut_z,follSoundVowelInt)
 

smooth_names=c("Bb2 Tongan","F3 Tongan","Bb3 Tongan","D4 Tongan","F4 Tongan","non-final schwa /ə/ NZE","final schwa /ə#/ NZE","LOT /ɒ/ NZE","/o/ Tongan","/u/ Tongan")
# # set Rho max to the max of the fit + 5
# max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit, p6$fv$fit, p7$fv$fit, p8$fv$fit, p9$fv$fit, p10$fv$fit)
# maximum=max_fit+5
# rm(max_fit)
# 
# # plot in polar coordinates with confidence bounds
# plot1=plot_ly(type='scatterpolar', mode='lines') %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5), name=smooth_names[1]) %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ul, line=list(color=colors[1], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$ll, line=list(color=colors[1], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], width=2.5), name=smooth_names[2]) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ul, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$ll, line=list(color=colors[2], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], dash="dash", width=2.5), name=smooth_names[3]) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ul, line=list(color=colors[3], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$ll, line=list(color=colors[3], dash="dash", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], width=2.5),
#             name=smooth_names[4]) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ul, line=list(color=colors[4], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$ll, line=list(color=colors[4], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=2.5),
#             name=smooth_names[5]) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ul, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$ll, line=list(color=colors[5], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$fit, line=list(color=colors[6], width=1),
#             name=smooth_names[6]) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$ul, line=list(color=colors[6], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$ll, line=list(color=colors[6], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$fit, line=list(color=colors[7], dash="dashdot", width=2.5), name=smooth_names[7]) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$ul, line=list(color=colors[7], dash="dashdot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$ll, line=list(color=colors[7], dash="dashdot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$fit, line=list(color=colors[8], dash="dot", width=2.5), name=smooth_names[8]) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$ul, line=list(color=colors[8], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$ll, line=list(color=colors[8], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$fit, line=list(color=colors[9], dash="dash", width=2.5), name=smooth_names[9]) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$ul, line=list(color=colors[9], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$ll, line=list(color=colors[9], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$fit, line=list(color=colors[10], width=2.5),
#             name=smooth_names[10]) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$ul, line=list(color=colors[10], dash="dot", width=0.5), showlegend=FALSE) %>%
#   add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$ll, line=list(color=colors[10], dash="dot", width=0.5), showlegend=FALSE) %>%
#   layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
#                     angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
#          title="Tongan & NZE vowels closest to playing position with Tongan notes")
# plot1
# set Rho max to the max of the fit + 5
max_fit = max(p1$fv$fit, p2$fv$fit, p3$fv$fit, p4$fv$fit, p5$fv$fit, p6$fv$fit, p7$fv$fit, p8$fv$fit, p9$fv$fit, p10$fv$fit)
maximum=max_fit+5
rm(max_fit)
# plot in polar coordinates without confidence bounds
plot2=plot_ly(type='scatterpolar', mode='lines') %>%
  add_trace(theta=p1$fv$theta_uncut_z*180/pi, r=p1$fv$fit, line=list(color=colors[1], width=2.5), name=smooth_names[1]) %>%
  add_trace(theta=p2$fv$theta_uncut_z*180/pi, r=p2$fv$fit, line=list(color=colors[2], dash="dash", width=2.5), name=smooth_names[2]) %>%
  add_trace(theta=p3$fv$theta_uncut_z*180/pi, r=p3$fv$fit, line=list(color=colors[3], dash="dot", width=2.5), name=smooth_names[3]) %>%
  add_trace(theta=p4$fv$theta_uncut_z*180/pi, r=p4$fv$fit, line=list(color=colors[4], dash="dashdot", width=2.5), name=smooth_names[4]) %>%
  add_trace(theta=p5$fv$theta_uncut_z*180/pi, r=p5$fv$fit, line=list(color=colors[5], width=1), name=smooth_names[5]) %>%
  add_trace(theta=p6$fv$theta_uncut_z*180/pi, r=p6$fv$fit, line=list(color=colors[6], width=2.5), name=smooth_names[6]) %>%
  add_trace(theta=p7$fv$theta_uncut_z*180/pi, r=p7$fv$fit, line=list(color=colors[7], width=2.5), name=smooth_names[7]) %>%
  add_trace(theta=p8$fv$theta_uncut_z*180/pi, r=p8$fv$fit, line=list(color=colors[8], dash="dash", width=2.5), name=smooth_names[8]) %>%
  add_trace(theta=p9$fv$theta_uncut_z*180/pi, r=p9$fv$fit, line=list(color=colors[9], width=2.5), name=smooth_names[9]) %>%
  add_trace(theta=p10$fv$theta_uncut_z*180/pi, r=p10$fv$fit, line=list(color=colors[10], width=2.5),
name=smooth_names[10]) %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)),
         title="Tongan & NZE vowels closest to playing position with Tongan notes",legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
plot2

if(printPDF==TRUE)
{
  orca(plot2, "Figure9(b).pdf",format="pdf")
  orca(plot2, "Figure9(b).jpeg",format="jpeg")
}
  
rm(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)

3.7 Figure 10 ‘cardinal vowels’ -> updated version using only vowels surrounded by coronals

# create dfNZE & dfTongan -> df already loaded and manipulated above
dfNZE <- subset(df,df$native_lg=="NZE")
dfNZE$tokenPooled <- factor(dfNZE$tokenPooled, levels = c("ɐː","ɐ","ɛ","ɵː","e","iː","ʉː","ʊ","oː","ɒ","ɘ","ə","ə#","Bb2","F3","Bb3","D4","F4"))
dfNZE$playing_proficiency <- as.factor(dfNZE$playing_proficiency)
dfNZE$note_intensity[is.na(dfNZE$note_intensity)] = "NULL"
dfNZE$subVowelInt <- interaction(dfNZE$subject, dfNZE$tokenPooled)
dfNZE$precSoundVowelInt <- interaction(dfNZE$speech_prec_pooled, dfNZE$tokenPooled)
dfNZE$follSoundVowelInt <- interaction(dfNZE$speech_fol_pooled, dfNZE$tokenPooled)
dfNZE$tokenPooled.ord <- as.ordered(dfNZE$tokenPooled)
contrasts(dfNZE$tokenPooled.ord) <- "contr.treatment"
dfNZE$vowels_pooled.ord <- as.ordered(dfNZE$vowels_pooled)
contrasts(dfNZE$vowels_pooled.ord) <- "contr.treatment"
dfNZE$playing_proficiency.ord <- as.ordered(dfNZE$playing_proficiency)
contrasts(dfNZE$playing_proficiency.ord) <- "contr.treatment"
dfNZE$start <- dfNZE$points==1
dfTongan <- subset(df,df$native_lg=="Tongan")
dfTongan$tokenPooled <- factor(dfTongan$tokenPooled, levels = c("aː","a","eː","e","iː","i","uː","u","oː","o","Bb2","F3","Bb3","D4","F4"))
dfTongan$tokenPooled[dfTongan$tokenPooled == "aː"] = "a"
dfTongan$tokenPooled[dfTongan$tokenPooled == "eː"] = "e"
dfTongan$tokenPooled[dfTongan$tokenPooled == "iː"] = "i"
dfTongan$tokenPooled[dfTongan$tokenPooled == "uː"] = "u"
dfTongan$tokenPooled[dfTongan$tokenPooled == "oː"] = "o"
dfTongan$tokenPooled <- factor(dfTongan$tokenPooled)
dfTongan$playing_proficiency <- as.factor(dfTongan$playing_proficiency)
dfTongan$speech_prec_pooled[is.na(dfTongan$speech_prec_pooled)] = "NULL"
dfTongan$speech_fol_pooled[is.na(dfTongan$speech_fol_pooled)] = "NULL"
dfTongan$subVowelInt <- interaction(dfTongan$subject, dfTongan$tokenPooled)
dfTongan$precSoundVowelInt <- interaction(dfTongan$speech_prec_pooled, dfTongan$tokenPooled)
dfTongan$follSoundVowelInt <- interaction(dfTongan$speech_fol_pooled, dfTongan$tokenPooled)
dfTongan$tokenPooled.ord <- as.ordered(dfTongan$tokenPooled)
contrasts(dfTongan$tokenPooled.ord) <- "contr.treatment"
dfTongan$vowels_pooled.ord <- as.ordered(dfTongan$vowels_pooled)
contrasts(dfTongan$vowels_pooled.ord) <- "contr.treatment"
dfTongan$playing_proficiency.ord <- as.ordered(dfTongan$playing_proficiency)
contrasts(dfTongan$playing_proficiency.ord) <- "contr.treatment"
dfTongan$start <- dfTongan$points==1
# # inspect vowel token numbers in different preceding and following contexts
# cat("\ndfNZE$speech_prec_pooled\n")
# table(dfNZE$speech_prec_pooled)
# cat("\ndfNZE$speech_fol_pooled\n")
# table(dfNZE$speech_fol_pooled)
# cat("\ndfTongan$speech_prec_pooled\n")
# table(dfTongan$speech_prec_pooled)
# cat("\ndfNZE$speech_fol_pooled\n")
# table(dfTongan$speech_fol_pooled)
# make copies of dfNZE and dfTongan
dat_NZE = dfNZE
dat_Tongan = dfTongan
# predict values from models
dat_NZE$predicted_values = predict(NZE.gam.AR.Mod2)
dat_Tongan$predicted_values = predict(Tongan.gam.AR.Mod2)
# create new data.frames
NZE_FLEECE = dat_NZE[dat_NZE$tokenPooled == "iː" & dat_NZE$speech_prec_pooled == "coronals" & dat_NZE$speech_fol_pooled == "coronals",]
Tongan_i = dat_Tongan[dat_Tongan$tokenPooled == "i" & dat_Tongan$speech_prec_pooled == "coronals" & dat_Tongan$speech_fol_pooled == "coronals",]
NZE_DRESS = dat_NZE[dat_NZE$tokenPooled == "e" & dat_NZE$speech_prec_pooled == "coronals" & dat_NZE$speech_fol_pooled == "coronals",]
Tongan_e = dat_Tongan[dat_Tongan$tokenPooled == "e" & dat_Tongan$speech_prec_pooled == "coronals" & dat_Tongan$speech_fol_pooled == "coronals",]
NZE_START = dat_NZE[dat_NZE$tokenPooled == "ɐː" & dat_NZE$speech_prec_pooled == "coronals" & dat_NZE$speech_fol_pooled == "coronals",]
Tongan_a = dat_Tongan[dat_Tongan$tokenPooled == "a" & dat_Tongan$speech_prec_pooled == "coronals" & dat_Tongan$speech_fol_pooled == "coronals",]
NZE_THOUGHT = dat_NZE[dat_NZE$tokenPooled == "oː" & dat_NZE$speech_prec_pooled == "coronals" & dat_NZE$speech_fol_pooled == "coronals",]
Tongan_o = dat_Tongan[dat_Tongan$tokenPooled == "o" & dat_Tongan$speech_prec_pooled == "coronals" & dat_Tongan$speech_fol_pooled == "coronals",]
# estimate smooths using R's generic predict.smooth.spline function
smooth_NZE_FLEECE=list(theta=seq(min(NZE_FLEECE$theta_uncut_z)*180/pi, 
                                 max(NZE_FLEECE$theta_uncut_z)*180/pi, length=100), 
                       r=predict(smooth.spline(NZE_FLEECE$theta_uncut_z, NZE_FLEECE$predicted_values), 
                                 seq(min(NZE_FLEECE$theta_uncut_z), max(NZE_FLEECE$theta_uncut_z), 
                                     length=100))$y, line=list(color="ORANGE0", dash="dash"))
smooth_Tongan_i=list(theta=seq(min(Tongan_i$theta_uncut_z)*180/pi, 
                               max(Tongan_i$theta_uncut_z)*180/pi, length=100), 
                     r=predict(smooth.spline(Tongan_i$theta_uncut_z, Tongan_i$predicted_values), 
                               seq(min(Tongan_i$theta_uncut_z), max(Tongan_i$theta_uncut_z), 
                                   length=100))$y, line=list(color="ORANGE0", dash=""))
smooth_NZE_DRESS=list(theta=seq(min(NZE_DRESS$theta_uncut_z)*180/pi, 
                                 max(NZE_DRESS$theta_uncut_z)*180/pi, length=100), 
                       r=predict(smooth.spline(NZE_DRESS$theta_uncut_z, NZE_DRESS$predicted_values), 
                                 seq(min(NZE_DRESS$theta_uncut_z), max(NZE_DRESS$theta_uncut_z), 
                                     length=100))$y, line=list(color="dark_blue", dash="dash"))
smooth_Tongan_e=list(theta=seq(min(Tongan_e$theta_uncut_z)*180/pi, 
                               max(Tongan_e$theta_uncut_z)*180/pi, length=100), 
                     r=predict(smooth.spline(Tongan_e$theta_uncut_z, Tongan_e$predicted_values), 
                               seq(min(Tongan_e$theta_uncut_z), max(Tongan_e$theta_uncut_z), 
                                   length=100))$y, line=list(color="dark_blue", dash=""))
smooth_NZE_START=list(theta=seq(min(NZE_START$theta_uncut_z)*180/pi, 
                                 max(NZE_START$theta_uncut_z)*180/pi, length=100), 
                       r=predict(smooth.spline(NZE_START$theta_uncut_z, NZE_START$predicted_values), 
                                 seq(min(NZE_START$theta_uncut_z), max(NZE_START$theta_uncut_z), 
                                     length=100))$y, line=list(color="RED0", dash="dash"))
smooth_Tongan_a=list(theta=seq(min(Tongan_a$theta_uncut_z)*180/pi, 
                               max(Tongan_a$theta_uncut_z)*180/pi, length=100), 
                     r=predict(smooth.spline(Tongan_a$theta_uncut_z, Tongan_a$predicted_values), 
                               seq(min(Tongan_a$theta_uncut_z), max(Tongan_a$theta_uncut_z), 
                                   length=100))$y, line=list(color="RED0", dash=""))
smooth_NZE_THOUGHT=list(theta=seq(min(NZE_THOUGHT$theta_uncut_z)*180/pi, 
                                 max(NZE_THOUGHT$theta_uncut_z)*180/pi, length=100), 
                       r=predict(smooth.spline(NZE_THOUGHT$theta_uncut_z, 
                                               NZE_THOUGHT$predicted_values), 
                                 seq(min(NZE_THOUGHT$theta_uncut_z), max(NZE_THOUGHT$theta_uncut_z), 
                                     length=100))$y, line=list(color="pink", dash="dash"))
smooth_Tongan_o=list(theta=seq(min(Tongan_o$theta_uncut_z)*180/pi, 
                               max(Tongan_o$theta_uncut_z)*180/pi, length=100), 
                     r=predict(smooth.spline(Tongan_o$theta_uncut_z, Tongan_o$predicted_values), 
                               seq(min(Tongan_o$theta_uncut_z), max(Tongan_o$theta_uncut_z), 
                                   length=100))$y, line=list(color="pink", dash=""))
# set Rho max to the max of the predicted_values + 5
max_predictions = max(max(smooth_NZE_FLEECE$r), max(smooth_NZE_DRESS$r), max(smooth_NZE_START$r), 
                      max(smooth_NZE_THOUGHT$r), max(smooth_Tongan_i$r), max(smooth_Tongan_e$r), 
                      max(smooth_Tongan_a$r), max(smooth_Tongan_o$r))
maximum=max_predictions+5
rm(max_predictions)
# colors from smooths don't get passed on correctly -> specify again
colors = c(ORANGE0, ORANGE0, dark_blue, dark_blue, RED0, RED0, pink, pink)
p = plot_ly(type='scatterpolar', mode='lines') %>% 
  add_trace(theta=smooth_NZE_FLEECE$theta, r=smooth_NZE_FLEECE$r, line=list(color=colors[1], width=2.5,dash=smooth_NZE_FLEECE$line$dash[[1]]), name="FLEECE /iː/ NZE") %>% 
  add_trace(theta=smooth_Tongan_i$theta, r=smooth_Tongan_i$r, line=list(color=colors[2], width=2.5, dash=smooth_Tongan_i$line$dash[[1]]), name="/i/ Tongan") %>%
  add_trace(theta=smooth_NZE_DRESS$theta, r=smooth_NZE_DRESS$r, line=list(color=colors[3], width=2.5, dash=smooth_NZE_DRESS$line$dash[[1]]), name="DRESS /e/ NZE") %>% 
  add_trace(theta=smooth_Tongan_e$theta, r=smooth_Tongan_e$r, line=list(color=colors[4], width=2.5, dash=smooth_Tongan_e$line$dash[[1]]), name="/e/ Tongan") %>%
  add_trace(theta=smooth_NZE_START$theta, r=smooth_NZE_START$r, line=list(color=colors[5], width=2.5, dash=smooth_NZE_START$line$dash[[1]]), name="START /iː/ NZE") %>% 
  add_trace(theta=smooth_Tongan_a$theta, r=smooth_Tongan_a$r, line=list(color=colors[6], width=2.5, dash=smooth_Tongan_a$line$dash[[1]]), name="/a/ Tongan") %>%
  add_trace(theta=smooth_NZE_THOUGHT$theta, r=smooth_NZE_THOUGHT$r, line=list(color=colors[7], width=2.5, dash=smooth_NZE_THOUGHT$line$dash[[1]]), name="THOUGHT /oː/ NZE") %>% 
  add_trace(theta=smooth_Tongan_o$theta, r=smooth_Tongan_o$r, line=list(color=colors[8], width=2.5, dash=smooth_Tongan_o$line$dash[[1]]), name="/o/ Tongan") %>%
  layout(polar=list(sector=c(20,160), radialaxis=list(angle=90, range=c(0,maximum)),  
                    angularaxis=list(thetaunit='radians', direction="clockwise", rotation=0)), 
         title="Tongan & NZE 'cardinal vowels' flanked by coronal sounds", 
         legend=list(orientation="h", xanchor="center", x=0.5,y=0.012))
p

if(printPDF==TRUE)
{
  orca(p, "Figure10.pdf",format="pdf")
  orca(p, "Figure10.jpg",format="jpeg")
}
rm(dat_NZE, dat_Tongan, NZE_FLEECE, NZE_DRESS, NZE_START, NZE_THOUGHT, smooth_NZE_FLEECE,smooth_NZE_DRESS, smooth_NZE_START, smooth_NZE_THOUGHT, smooth_Tongan_i, smooth_Tongan_e, smooth_Tongan_a, smooth_Tongan_o, maximum)
LS0tCnRpdGxlOiAiR0FNTXMgYW5hbHlzZXMgVHJvbWJvbmUgLSBUb25nYW4gdnMgRW5nbGlzaCAoTlpFKSAtPiBwYXBlciBwbG90cyIKYXV0aG9yOgotIEphbGFsIEFsLVRhbWltaSAoTmV3Y2FzdGxlIFVuaXZlcnNpdHkpCi0gRG9uYWxkIERlcnJpY2sgKFVuaXZlcnNpdHkgb2YgQ2FudGVyYnVyeSkKLSBNYXR0aGlhcyBIZXluZSAoQm9zdG9uIFVuaXZlcnNpdHkpCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA2CiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogeWVzCiAgd29yZF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc2JwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc2JwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnNicKLS0tCgpUaGlzIG5vdGVib29rIHByb3ZpZGVzIHRoZSBwbG90cyBmb3IgdGhlIGFydGljbGU6IEhleW5lLCBNLiwgRGVycmljaywgRC4sIGFuZCBBbC1UYW1pbWksIEouICh1bmRlciByZXZpZXcpLiAiTmF0aXZlIGxhbmd1YWdlIGluZmx1ZW5jZSBvbiBicmFzcyBpbnN0cnVtZW50IHBlcmZvcm1hbmNlOiBBbiBhcHBsaWNhdGlvbiBvZiBnZW5lcmFsaXplZCBhZGRpdGl2ZSBtaXhlZCBtb2RlbHMgKEdBTU1zKSB0byBtaWRzYWdpdHRhbCB1bHRyYXNvdW5kIGltYWdlcyBvZiB0aGUgdG9uZ3VlIi4gRnJvbnRpZXJzIFJlc2VhcmNoIFRvcGljOiBNb2RlbHMgYW5kIFRoZW9yaWVzIG9mIFNwZWVjaCBQcm9kdWN0aW9uLiBFZC4gQWRhbWFudGlvcyBHYWZvcyAmIFBhc2NhbCB2YW4gTGllc2hvdXQuCgoKIyBMb2FkaW5nIHBhY2thZ2VzCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0KbG9hZF9wYWNrYWdlcyA9IGMoInJlYWRyIiwia25pdHIiLCJnZ3Bsb3QyIiwibWdjdiIsIml0c2FkdWciLCJwYXJhbGxlbCIsImRwbHlyIiwicmxpc3QiLCJwbG90bHkiKQojIGRwbHlyLCBybGlzdCwgYW5kIHBsb3RseSBhcmUgcmVxdWlyZWQgYnkgdGhlIGN1c3RvbSBwbG90dGluZyBmdW5jdGlvbnMKZm9yKHBrZyBpbiBsb2FkX3BhY2thZ2VzKXsKICBldmFsKGJxdW90ZShsaWJyYXJ5KC4ocGtnKSkpKQogIGlmIChwYXN0ZTAoInBhY2thZ2U6IiwgcGtnKSAlaW4lIHNlYXJjaCgpKXsKICAgIGNhdChwYXN0ZTAoIlN1Y2Nlc3NmdWxseSBsb2FkZWQgdGhlICIsIHBrZywgIiBwYWNrYWdlLlxuIikpCiAgfWVsc2V7CiAgICBpbnN0YWxsLnBhY2thZ2VzKHBrZykKICAgIGV2YWwoYnF1b3RlKGxpYnJhcnkoLihwa2cpKSkpCiAgICBpZiAocGFzdGUwKCJwYWNrYWdlOiIsIHBrZykgJWluJSBzZWFyY2goKSl7CiAgICAgIGNhdChwYXN0ZTAoIlN1Y2Nlc3NmdWxseSBsb2FkZWQgdGhlICIsIHBrZywgIiBwYWNrYWdlLlxuIikpCiAgICB9CiAgfQp9CnJtKGxvYWRfcGFja2FnZXMsIHBrZykKU3lzLnNldGVudignTUFQQk9YX1RPS0VOJyA9ICdzay5leUoxSWpvaVpHUmxjbkpwWTJzaUxDSmhJam9pWTJwMk1XMW5kbk5vTVhjellUUmtiWGQ2ZHpSdU1UUTJhQ0o5LlVUYWk0d1djRkZWYUpBdU9yQVg3VlEnKQoKIyBkZWNpZGUgd2hldGhlciB0byBzYXZlIHBsb3RzIGFzIFBERiBhbmQganBnIGZpbGVzIHVzaW5nIHRoZSBPcmNhIGNvbW1hbmQgbGluZSB1dGlsaXR5CnNhdmU9RkFMU0UKcHJpbnRQREY9RkFMU0UKYGBgCgojIyBMb2FkaW5nIGN1c3RvbSBwbG90dGluZyBmdW5jdGlvbnMKCiMjIyBwbG90bHlfbW9kZWxfb3V0cHV0cyBmdW5jdGlvbiAoTWF0dGhpYXMgSGV5bmUsIDIwMTkpCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0KIyBwbG90IG11bHRpcGxlIEdBTSBtb2RlbCBvdXRwdXRzCnBsb3RseV9tb2RlbF9vdXRwdXRzIDwtIGZ1bmN0aW9uKG1vZGVsLCBjaGFuZ2luZ19jb25kLCBjaGFuZ2luZ192YXIsIGNvbnN0YW50X2NvbmQxLCBjb25zdGFudF92YXIxLCB2YWx1ZXMsIGNvbnN0YW50X2NvbmQyPU5VTEwsIGNvbnN0YW50X3ZhcjI9TlVMTCwgcHJpbnQ9VFJVRSl7CiAgaWYobGVuZ3RoKGNvbnN0YW50X3ZhcjEpPjEgfCBsZW5ndGgoY29uc3RhbnRfdmFyMik+MSl7CiAgICBwcmludCgiRXJyb3I6IENvbnN0YW50IHZhcmlhYmxlcyBjYW4gb25seSBoYXZlIGxlbmd0aCAxLiIpCiAgfWVsc2V7CiAgICBpZighaXMubnVsbChjb25zdGFudF9jb25kMikgJiYgIWlzLm51bGwoY29uc3RhbnRfdmFyMikgJiYgbGVuZ3RoKGNoYW5naW5nX3Zhcik9PTIpewogICAgICAjIHdvcmtzIGZvciBtb2RlbHMgTm90ZXMuZ2FtLi4uCiAgICAgIGNvbmRfcDEgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNoYW5naW5nX2NvbmQsICI9JyIsIGNoYW5naW5nX3ZhclsxXSwgIicsICIsIGNvbnN0YW50X2NvbmQxLCAiPSciLCBjb25zdGFudF92YXIxLCAiJywgIiwgY29uc3RhbnRfY29uZDIsICI9JyIsIGNvbnN0YW50X3ZhcjIsICInKSIpKSkKICAgICAgcDE9cGxvdF9zbW9vdGgoeD1nZXQobW9kZWwpLCB2aWV3PXZhbHVlcywgY29uZCA9IGV2YWwocGFyc2UodGV4dD1jb25kX3AxKSkpCiAgICAgIGNvbmRfcDIgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNoYW5naW5nX2NvbmQsICI9JyIsIGNoYW5naW5nX3ZhclsyXSwgIicsICIsIGNvbnN0YW50X2NvbmQxLCAiPSciLCBjb25zdGFudF92YXIxLCAiJywgIiwgY29uc3RhbnRfY29uZDIsICI9JyIsIGNvbnN0YW50X3ZhcjIsICInKSIpKSkKICAgICAgcDI9cGxvdF9zbW9vdGgoeD1nZXQobW9kZWwpLCB2aWV3PXZhbHVlcywgY29uZCA9IGV2YWwocGFyc2UodGV4dD1jb25kX3AyKSkpCiAgICAgIAogICAgICAjIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIGhhbGYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBtYXggb2YgdGhlIGZpdCBhbmQgdGhlIHVwcGVyIGxpbWl0CiAgICAgIG1heF91bCA9IG1heChwMSRmdiR1bCwgcDIkZnYkdWwpCiAgICAgIG1heF9maXQgPSBtYXgocDEkZnYkZml0LCBwMiRmdiRmaXQpCiAgICAgIG1heGltdW09bWF4X2ZpdCsoKG1heF91bC1tYXhfZml0KS8yKQogICAgICAKICAgICAgIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzCiAgICAgIHA9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1jaGFuZ2luZ192YXJbMV0pICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgd2lkdGg9Mi41KSwgbmFtZT1jaGFuZ2luZ192YXJbMl0pICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgICAgICAgIHRpdGxlPXBhc3RlMCgiR0FNIHNtb290aHMgQCIsIGNvbnN0YW50X3ZhcjEsICIgJiAiLCBjb25zdGFudF92YXIyKSwgCiAgICAgICAgICAgICAgIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCiAgICAgIHAKICAgIH1lbHNlIGlmKGlzLm51bGwoY29uc3RhbnRfY29uZDIpICYmIGlzLm51bGwoY29uc3RhbnRfdmFyMikgJiYgbGVuZ3RoKGNoYW5naW5nX3Zhcik9PTIpewogICAgICAjIG5vIHNwZWNpZmljIGNhc2UgeWV0CiAgICAgIGNvbmRfcDEgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNoYW5naW5nX2NvbmQsICI9JyIsIGNoYW5naW5nX3ZhclsxXSwgIicsICIsIGNvbnN0YW50X2NvbmQxLCAiPSciLCBjb25zdGFudF92YXIxLCAiJykiKSkpCiAgICAgIHAxPXBsb3Rfc21vb3RoKHg9Z2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIGNvbmQgPSBldmFsKHBhcnNlKHRleHQ9Y29uZF9wMSkpKQogICAgICBjb25kX3AyID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjaGFuZ2luZ19jb25kLCAiPSciLCBjaGFuZ2luZ192YXJbMl0sICInLCAiLCBjb25zdGFudF9jb25kMSwgIj0nIiwgY29uc3RhbnRfdmFyMSwgIicpIikpKQogICAgICBwMj1wbG90X3Ntb290aCh4PWdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb25kID0gZXZhbChwYXJzZSh0ZXh0PWNvbmRfcDIpKSkKICAgICAgCiAgICAgICMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgaGFsZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1heCBvZiB0aGUgZml0IGFuZCB0aGUgdXBwZXIgbGltaXQKICAgICAgbWF4X3VsID0gbWF4KHAxJGZ2JHVsLCBwMiRmdiR1bCkKICAgICAgbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCkKICAgICAgbWF4aW11bT1tYXhfZml0KygobWF4X3VsLW1heF9maXQpLzIpCiAgICAgIAogICAgICAjIHBsb3QgaW4gcG9sYXIgY29vcmRpbmF0ZXMKICAgICAgcD1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPWNoYW5naW5nX3ZhclsxXSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCB3aWR0aD0yLjUpLCBuYW1lPWNoYW5naW5nX3ZhclsyXSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKICAgICAgICAgICAgICAgdGl0bGU9cGFzdGUwKCJHQU0gc21vb3RocyBAIiwgY29uc3RhbnRfdmFyMSwgIiAmICIsIGNvbnN0YW50X3ZhcjIpLCAKICAgICAgICAgICAgICAgbGVnZW5kPWxpc3Qob3JpZW50YXRpb249ImgiLCB4YW5jaG9yPSJjZW50ZXIiLCB4PTAuNSx5PTAuMDEyKSkKICAgICAgcAogICAgfWVsc2UgaWYoaXMubnVsbChjb25zdGFudF9jb25kMikgJiYgaXMubnVsbChjb25zdGFudF92YXIyKSAmJiBsZW5ndGgoY2hhbmdpbmdfdmFyKT4yKXsKICAgICAgIyB3b3JrcyBmb3IgbW9kZWxzIE5aRS5nYW0uLi4gb3IgVG9uZ2FuLmdhbS4uLgogICAgICBmb3IgKGkgaW4gMTpsZW5ndGgoY2hhbmdpbmdfdmFyKSl7CiAgICAgICAgaWYoY2hhbmdpbmdfY29uZCA9PSBjb25zdGFudF9jb25kMSl7CiAgICAgICAgICBjb25kX3AxID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25zdGFudF9jb25kMSwgIj0nIiwgY29uc3RhbnRfdmFyMSwgIicpIikpKQogICAgICAgICAgcDE9cGxvdF9zbW9vdGgoeD1nZXQobW9kZWwpLCB2aWV3PXZhbHVlcywgY29uZCA9IGV2YWwocGFyc2UodGV4dD1jb25kX3AxKSkpCiAgICAgICAgICAjIGV4Y2VwdGlvbiBmb3IgS0lUICg9J1xcXFwnKSB3aGVuIG5vdCB1c2luZyBJUEEgc3ltYm9scwogICAgICAgICAgaWYgKGNoYW5naW5nX3ZhcltpXSE9IlxcXFwiKXsKICAgICAgICAgICAgY29uZF9wMiA9IGNhcHR1cmUub3V0cHV0KGNhdChwYXN0ZTAoImxpc3QoIiwgY2hhbmdpbmdfY29uZCwgIj0nIiwgY2hhbmdpbmdfdmFyW2ldLCAiJykiKSkpCiAgICAgICAgICAgIHAyPXBsb3Rfc21vb3RoKHg9Z2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIGNvbmQgPSBldmFsKHBhcnNlKHRleHQ9Y29uZF9wMikpKQogICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHAyPXBsb3Rfc21vb3RoKHg9Z2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIGNvbmQgPSBsaXN0KHRva2VuLm9yZD0nXFxcXCcpKQogICAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgICAjIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIGhhbGYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBtYXggb2YgdGhlIGZpdCBhbmQgdGhlIHVwcGVyIGxpbWl0CiAgICAgICAgICBtYXhfdWwgPSBtYXgocDEkZnYkdWwsIHAyJGZ2JHVsKQogICAgICAgICAgbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCkKICAgICAgICAgIG1heGltdW09bWF4X2ZpdCsoKG1heF91bC1tYXhfZml0KS8yKQoKICAgICAgICAgICMgcGxvdCBpbiBwb2xhciBjb29yZGluYXRlcwogICAgICAgICAgcD1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lIAogICAgICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1jb25zdGFudF92YXIxKSAlPiUgCiAgICAgICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIHdpZHRoPTIuNSksIG5hbWU9Y2hhbmdpbmdfdmFyW2ldKSAlPiUgCiAgICAgICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICAgICAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKICAgICAgICAgICAgICAgICAgIHRpdGxlPXBhc3RlMCgiR0FNIHNtb290aHMgIixjb25zdGFudF92YXIxLCIgdnMgIiwgY2hhbmdpbmdfdmFyW2ldKSwgCiAgICAgICAgICAgICAgICAgICBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQogICAgICAgICAgU3lzLnNsZWVwKDApCiAgICAgICAgICBwcmludChwKQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQpgYGAKCiMjIyBwbG90bHlfc2lnX2RpZmZfbm90ZXMgZnVuY3Rpb24gKE1hdHRoaWFzIEhleW5lLCAyMDE5KSAtPiB3aXRoIHVwZGF0ZWQgbGVnZW5kIHBvc2l0aW9uCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0KIyBwbG90IHNtb290aHMgd2l0aCBzaGFkaW5nIHRvIGluZGljYXRlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIChNYXR0aGlhcyBIZXluZSwgMjAxOSkKcGxvdGx5X3Ntb290aHNfd19zaWdfZGlmZiA8LSBmdW5jdGlvbihtb2RlbCwgY29uZGl0aW9uLCB2YXIxLCB2YXIyLCB2YWx1ZXMsIGxhbmd1YWdlLCBmaWxlTmFtZSwgcHJpbnQ9VFJVRSwgc2F2ZT1UUlVFKXsKICAjIHNwZWNpZnkgcGF0aCBmb3Igc2F2aW5nIHBsb3RzCiAgIyBwbG90X2ZvbGRlciA9ICJzYXZlZF9wbG90cyIKICAjIFN5cy5zZXRlbnYoTUFQQk9YX1RPS0VOID0gMTExMjIyMjMzMzM0NDQpCiAgIyBnZXQgaW50ZXJ2YWxzIG9mIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJ5IHJ1bm5pbmcgcGxvdF9kaWZmCiAgIyB1bmZvcnR1bmF0ZWx5IHNldHRpbmcgcGxvdD1GQUxTRSBkb2Vzbid0IHdvcmsgYXMgaW50ZXJ2YWxzIG9mIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYXJlIG5vdCBkaXNwbGF5ZWQhCiAgIyBoYXJkY29kZWQgY29uZGl0aW9uCiAgIyBvdXRwdXQgPSBjYXB0dXJlLm91dHB1dChwbG90X2RpZmYoZ2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXA9bGlzdCh0b2tlblBvb2xlZC5vcmQ9Yyh2YXIxLCB2YXIyKSkpKQogICMgb3V0cHV0ID0gY2FwdHVyZS5vdXRwdXQocGxvdF9kaWZmKGdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb21wPWxpc3QobGFuZ05vdGVJbnQub3JkPWMocGFzdGUwKCJUb25nYW4uIiwgbm90ZSwgIi4iLCBpbnRlbnNpdHkpLCBwYXN0ZTAoIk5aRS4iLCBub3RlLCAiLiIsIGludGVuc2l0eSkpKSkpCiAgbmFtZXNfc21vb3Rocz1saXN0KCkKICBpZiAoY29uZGl0aW9uPT0idG9rZW5Qb29sZWQub3JkIiAmJiBsZW5ndGgobGFuZ3VhZ2UpPT0xKXsKICAgIG91dHB1dF9jb21wID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9Yyh2YXIxLCB2YXIyKSkiKSkpCiAgICBuYW1lc19zbW9vdGhzWzFdPXZhcjEKICAgIG5hbWVzX3Ntb290aHNbMl09dmFyMgogICAgcGxvdF90aXRsZSA9IHBhc3RlMCgiR0FNIHNtb290aHMgIiwgbGFuZ3VhZ2UsICIgIiwgdmFyMSwgIiB2cyAiLCB2YXIyKQogICAgIyBwbG90X2ZpbGVuYW1lID0gcGFzdGUwKGxhbmd1YWdlLCAiXyIsIHZhcjEsICJfdnNfIiwgdmFyMiwgIl9mcm9tXyIsIG1vZGVsKQogIH1lbHNlIGlmIChjb25kaXRpb249PSJsYW5nTm90ZUludC5vcmQiICYmIGxlbmd0aChsYW5ndWFnZSk9PTIpewogICAgb3V0cHV0X2NvbXAgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj1jKCciLCBsYW5ndWFnZVsxXSwgIi4iLCB2YXIxLCAiLiIsIHZhcjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAnIiwgbGFuZ3VhZ2VbMl0sICIuIiwgdmFyMSwgIi4iLCB2YXIyLCAiJykpIikpKQogICAgbmFtZXNfc21vb3Roc1sxXT1wYXN0ZTAobGFuZ3VhZ2VbMV0sICIuIiwgdmFyMSwgIi4iLCB2YXIyKQogICAgbmFtZXNfc21vb3Roc1syXT1wYXN0ZTAobGFuZ3VhZ2VbMl0sICIuIiwgdmFyMSwgIi4iLCB2YXIyKQogICAgcGxvdF90aXRsZSA9IHBhc3RlMCgiR0FNIHNtb290aHMgIiwgbGFuZ3VhZ2VbMV0sICIuIiwgdmFyMSwgIi4iLCB2YXIyLCAiIHZzICIsIGxhbmd1YWdlWzJdLCAiLiIsIHZhcjEsICIuIiwgdmFyMikKICAgICMgcGxvdF9maWxlbmFtZSA9IHBhc3RlMChsYW5ndWFnZVsxXSwgIi4iLCB2YXIxLCAiLiIsIHZhcjIsICJfdnNfIiwgbGFuZ3VhZ2VbMl0sICIuIiwgdmFyMSwgIi4iLCB2YXIyLCAiX2Zyb21fIiwgbW9kZWwpCiAgfWVsc2UgaWYgKGNvbmRpdGlvbj09ImxhbmdOb3RlSW50Lm9yZCIgJiYgbGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIpewogICAgb3V0cHV0X2NvbXAgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj1jKCciLCBsYW5ndWFnZSwgIi4iLCB2YXIxWzFdLCAiLiIsIHZhcjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAnIiwgbGFuZ3VhZ2UsICIuIiwgdmFyMVsyXSwgIi4iLCB2YXIyLCAiJykpIikpKQogICAgbmFtZXNfc21vb3Roc1sxXT1wYXN0ZTAobGFuZ3VhZ2UsICIuIiwgdmFyMVsxXSwgIi4iLCB2YXIyKQogICAgbmFtZXNfc21vb3Roc1syXT1wYXN0ZTAobGFuZ3VhZ2UsICIuIiwgdmFyMVsyXSwgIi4iLCB2YXIyKQogICAgcGxvdF90aXRsZSA9IHBhc3RlMCgiR0FNIHNtb290aHMgIiwgbGFuZ3VhZ2UsICIuIiwgdmFyMVsxXSwgIi4iLCB2YXIyLCAiIHZzICIsIGxhbmd1YWdlLCAiLiIsIHZhcjFbMl0sICIuIiwgdmFyMikKICAgICMgcGxvdF9maWxlbmFtZSA9IHBhc3RlMChsYW5ndWFnZSwgIi4iLCB2YXIxWzFdLCAiLiIsIHZhcjIsICJfdnNfIiwgbGFuZ3VhZ2UsICIuIiwgdmFyMVsyXSwgIi4iLCB2YXIyLCAiX2Zyb21fIiwgbW9kZWwpCiAgfQogICMgb3V0cHV0X2NvbXAgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj1jKHZhcjEsIHZhcjIpKSIpKSkKICBvdXRwdXQgPSBjYXB0dXJlLm91dHB1dChwbG90X2RpZmYoZ2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIGNvbXA9ZXZhbChwYXJzZSh0ZXh0PW91dHB1dF9jb21wKSkpKQogICMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZQogIGlmICgobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk9PTcpIHwgKGxlbmd0aChsYW5ndWFnZSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk9PTYpIHwgCiAgICAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk9PTYpKXsKICAgIGlmIChsZW5ndGgodmFyMSk9PTEpewogICAgICBjYXQocGFzdGUwKCJTbW9vdGhzIGZvciAiLCB2YXIxLCAiICYgIiwgdmFyMiwgIiBhcmUgbm90IHNpZ25pZmljYW50bHkgZGlmZmVyZW50LlxuIikpCiAgICAgIGRhdDEgPSBOQQogICAgICBhc3NpZ24ocGFzdGUwKCJpbnRfc2lnX2RpZmZfIiwgdmFyMSwgIl8iLCB2YXIyKSwgZGF0MSwgZW52aXIgPSAuR2xvYmFsRW52KQogICAgfWVsc2V7CiAgICAgIGNhdChwYXN0ZTAoIlNtb290aHMgZm9yICIsIHZhcjFbMV0sICIgJiAiLCB2YXIxWzJdLCAiIGluICIsIGxhbmd1YWdlLCAiIGFyZSBub3Qgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQuXG4iKSkKICAgICAgZGF0MSA9IE5BCiAgICAgIGFzc2lnbihwYXN0ZTAoImludF9zaWdfZGlmZl8iLCB2YXIxWzFdLCAiXyIsIHZhcjFbMl0sICJfIiwgdmFyMiwgIl8iLCBsYW5ndWFnZSksIGRhdDEsIGVudmlyID0gLkdsb2JhbEVudikKICAgIH0KICAgIHJtKGRhdDEsIG91dHB1dCkKICAgICMgcnVuIHBsb3Rfc21vb3RoIHRvIGdyYWIgZGF0YSBmb3IgcG9sYXIgcGxvdHMKICAgIGlmIChjb25kaXRpb249PSJ0b2tlblBvb2xlZC5vcmQiICYmIGxlbmd0aChsYW5ndWFnZSk9PTEpewogICAgICBjb25kX3AxID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9dmFyMSkiKSkpCiAgICAgIGNvbmRfcDIgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj12YXIyKSIpKSkKICAgIH1lbHNlIGlmIChjb25kaXRpb249PSJsYW5nTm90ZUludC5vcmQiICYmIGxlbmd0aChsYW5ndWFnZSk9PTIpewogICAgICBjb25kX3AxID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlWzFdLCAiLiIsIHZhcjEsICIuIiwgdmFyMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlWzJdLCAiLiIsIHZhcjEsICIuIiwgdmFyMiwgIicpIikpKQogICAgICBjb25kX3AyID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlWzJdLCAiLiIsIHZhcjEsICIuIiwgdmFyMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlWzFdLCAiLiIsIHZhcjEsICIuIiwgdmFyMiwgIicpIikpKQogICAgfWVsc2UgaWYgKGNvbmRpdGlvbj09ImxhbmdOb3RlSW50Lm9yZCIgJiYgbGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIpewogICAgICBjb25kX3AxID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlLCAiLiIsIHZhcjFbMV0sICIuIiwgdmFyMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlLCAiLiIsIHZhcjFbMl0sICIuIiwgdmFyMiwgIicpIikpKQogICAgICBjb25kX3AyID0gY2FwdHVyZS5vdXRwdXQoY2F0KHBhc3RlMCgibGlzdCgiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlLCAiLiIsIHZhcjFbMl0sICIuIiwgdmFyMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICInLCAiLCBjb25kaXRpb24sICI9JyIsIGxhbmd1YWdlLCAiLiIsIHZhcjFbMV0sICIuIiwgdmFyMiwgIicpIikpKQogICAgfQogICAgcDEgPSBwbG90X3Ntb290aCh4PWdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb25kPWV2YWwocGFyc2UodGV4dD1jb25kX3AxKSksIHJtLnJhbmVmPVRSVUUpCiAgICBwMiA9IHBsb3Rfc21vb3RoKHg9Z2V0KG1vZGVsKSwgdmlldz12YWx1ZXMsIGNvbmQ9ZXZhbChwYXJzZSh0ZXh0PWNvbmRfcDIpKSwgcm0ucmFuZWY9VFJVRSkKICAgICMgIyBvbGQgLSBoYXJkY29kZWQKICAgICMgcDEgPSBwbG90X3Ntb290aCh4PWdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPXZhcjEsIHRva2VuUG9vbGVkLm9yZD12YXIyKSkKICAgICMgcDIgPSBwbG90X3Ntb290aCh4PWdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPXZhcjIsIHRva2VuUG9vbGVkLm9yZD12YXIxKSkKICAgICMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgaGFsZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1heCBvZiB0aGUgZml0IGFuZCB0aGUgdXBwZXIgbGltaXQKICAgIG1heGltdW09bWF4KHAxJGZ2JGZpdCwgcDIkZnYkZml0KSsoKG1heChwMSRmdiR1bCwgcDIkZnYkdWwpLW1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCkpLzIpCiAgICAjIHBsb3QgaW4gcG9sYXIgY29vcmRpbmF0ZXMKICAgIHA9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9bmFtZXNfc21vb3Roc1sxXSkgJT4lIAogICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsICB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgd2lkdGg9Mi41KSwgbmFtZT1uYW1lc19zbW9vdGhzWzJdKSAlPiUgCiAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLAogICAgICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKICAgICAgICAgICAgIHRpdGxlPXBhc3RlMCgiR0FNIHNtb290aHMgIiwgbGFuZ3VhZ2UsICIgIiwgdmFyMSwgIiB2cyAiLCB2YXIyKSwgCiAgICAgICAgICAgICBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQogICAgU3lzLnNsZWVwKDApCiAgICBwcmludChwKQogICMgdGhlcmUgYXJlIGRpZmZlcmVuY2VzLi4uCiAgfWVsc2V7CiAgICAjIGdyYWIgaW50ZXJ2YWxzIG9mIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGZyb20gb3V0cHV0CiAgICBpZiAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTgpewogICAgIyBpZiAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgob3V0cHV0KT49OCl7CiAgICAgIHNpZ19kaWZmMSA9IGMoYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdCh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzhdLCAiICIpKVsxXSwgIlx0IikpWzJdKSwgYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdChvdXRwdXRbOF0sICIgIikpWzNdKSkKICAgIH1lbHNlIGlmICgobGVuZ3RoKGxhbmd1YWdlKT09MiAmJiBsZW5ndGgob3V0cHV0KT49NykgfCAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTcpKXsKICAgICMgfWVsc2UgaWYgKGxlbmd0aChsYW5ndWFnZSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTcpewogICAgICBzaWdfZGlmZjEgPSBjKGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQodW5saXN0KHN0cnNwbGl0KG91dHB1dFs3XSwgIiAiKSlbMV0sICJcdCIpKVsyXSksIGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzddLCAiICIpKVszXSkpCiAgICB9CiAgICBpZiAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTkpewogICAgIyBpZiAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgob3V0cHV0KT49OSl7CiAgICAgIHNpZ19kaWZmMiA9IGMoYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdCh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzldLCAiICIpKVsxXSwgIlx0IikpWzJdKSwgYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdChvdXRwdXRbOV0sICIgIikpWzNdKSkKICAgIH1lbHNlIGlmICgobGVuZ3RoKGxhbmd1YWdlKT09MiAmJiBsZW5ndGgob3V0cHV0KT49OCkgfCAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTgpKXsKICAgICMgfWVsc2UgaWYgKGxlbmd0aChsYW5ndWFnZSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTgpewogICAgICBzaWdfZGlmZjIgPSBjKGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQodW5saXN0KHN0cnNwbGl0KG91dHB1dFs4XSwgIiAiKSlbMV0sICJcdCIpKVsyXSksIGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzhdLCAiICIpKVszXSkpCiAgICB9CiAgICBpZiAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTEwKXsKICAgICMgaWYgKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTEwKXsKICAgICAgc2lnX2RpZmYzID0gYyhhcy5kb3VibGUodW5saXN0KHN0cnNwbGl0KHVubGlzdChzdHJzcGxpdChvdXRwdXRbMTBdLCAiICIpKVsxXSwgIlx0IikpWzJdKSwgYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdChvdXRwdXRbMTBdLCAiICIpKVszXSkpCiAgICB9ZWxzZSBpZiAoKGxlbmd0aChsYW5ndWFnZSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTkpIHwgKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0yICYmIGxlbmd0aChvdXRwdXQpPj05KSl7CiAgICAjIH1lbHNlIGlmIChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj05KXsKICAgICAgc2lnX2RpZmYzID0gYyhhcy5kb3VibGUodW5saXN0KHN0cnNwbGl0KHVubGlzdChzdHJzcGxpdChvdXRwdXRbOV0sICIgIikpWzFdLCAiXHQiKSlbMl0pLCBhcy5kb3VibGUodW5saXN0KHN0cnNwbGl0KG91dHB1dFs5XSwgIiAiKSlbM10pKQogICAgfQogICAgaWYgKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0xICYmIGxlbmd0aChvdXRwdXQpPj0xMSl7CiAgICAjIGlmIChsZW5ndGgobGFuZ3VhZ2UpPT0xICYmIGxlbmd0aChvdXRwdXQpPj0xMSl7CiAgICAgIHNpZ19kaWZmNCA9IGMoYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdCh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzExXSwgIiAiKSlbMV0sICJcdCIpKVsyXSksIGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzExXSwgIiAiKSlbM10pKQogICAgfWVsc2UgaWYgKChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj0xMCkgfCAobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgodmFyMSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTEwKSl7CiAgICAjIH1lbHNlIGlmIChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj0xMCl7CiAgICAgIHNpZ19kaWZmNCA9IGMoYXMuZG91YmxlKHVubGlzdChzdHJzcGxpdCh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzEwXSwgIiAiKSlbMV0sICJcdCIpKVsyXSksIGFzLmRvdWJsZSh1bmxpc3Qoc3Ryc3BsaXQob3V0cHV0WzEwXSwgIiAiKSlbM10pKQogICAgfQoKICAgIAogICAgIyB3cml0ZSBpbnRlcnZhbHMgb2Ygc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSB0byB2YXJpYWJsZQogICAgaWYgKChsZW5ndGgobGFuZ3VhZ2UpPT0xICYmIGxlbmd0aCh2YXIxKT09MSAmJiBsZW5ndGgob3V0cHV0KT49MTEpIHwgKChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj0xMCkpIHwgCiAgICAgICAgKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0yICYmIGxlbmd0aChvdXRwdXQpPj0xMCkpewogICAgIyBpZiAoKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTExKSB8IChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj0xMCkpewogICAgICBkYXQxID0gYyhzaWdfZGlmZjEsIHNpZ19kaWZmMiwgc2lnX2RpZmYzLCBzaWdfZGlmZjQpCiAgICB9ZWxzZSBpZiAoKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0xICYmIGxlbmd0aChvdXRwdXQpPj0xMCkgfCAoKGxlbmd0aChsYW5ndWFnZSk9PTIgJiYgbGVuZ3RoKG91dHB1dCk+PTkpKSB8IAogICAgICAgICAgICAgIChsZW5ndGgobGFuZ3VhZ2UpPT0xICYmIGxlbmd0aCh2YXIxKT09MiAmJiBsZW5ndGgob3V0cHV0KT49OSkpewogICAgIyB9ZWxzZSBpZiAoKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKG91dHB1dCk+PTEwKSB8IChsZW5ndGgobGFuZ3VhZ2UpPT0yICYmIGxlbmd0aChvdXRwdXQpPj05KSl7CiAgICAgIGRhdDEgPSBjKHNpZ19kaWZmMSwgc2lnX2RpZmYyLCBzaWdfZGlmZjMpCiAgICB9ZWxzZSBpZiAoKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0xICYmIGxlbmd0aChvdXRwdXQpPj05KSB8ICgobGVuZ3RoKGxhbmd1YWdlKT09MiAmJiBsZW5ndGgob3V0cHV0KT49OCkpIHwgCiAgICAgICAgICAgICAgKGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0yICYmIGxlbmd0aChvdXRwdXQpPj04KSl7CiAgICAjIH1lbHNlIGlmICgobGVuZ3RoKGxhbmd1YWdlKT09MSAmJiBsZW5ndGgob3V0cHV0KT49OSkgfCAobGVuZ3RoKGxhbmd1YWdlKT09MiAmJiBsZW5ndGgob3V0cHV0KT49OCkpewogICAgICBkYXQxID0gYyhzaWdfZGlmZjEsIHNpZ19kaWZmMikKICAgIH1lbHNlewogICAgICBkYXQxID0gc2lnX2RpZmYxCiAgICB9CiAgICAjIG9sZAogICAgIyBhc3NpZ24ocGFzdGUwKCJpbnRfc2lnX2RpZmZfIiwgdmFyMSwgIl8iLCB2YXIyKSwgZGF0MSwgZW52aXIgPSAuR2xvYmFsRW52KQogICAgaWYgKGxlbmd0aCh2YXIxKT09MSl7CiAgICAgIGFzc2lnbihwYXN0ZTAoImludF9zaWdfZGlmZl8iLCB2YXIxLCAiXyIsIHZhcjIpLCBkYXQxLCBlbnZpciA9IC5HbG9iYWxFbnYpCiAgICB9ZWxzZXsKICAgICAgYXNzaWduKHBhc3RlMCgiaW50X3NpZ19kaWZmXyIsIHZhcjFbMV0sICJfIiwgdmFyMVsyXSwgIl8iLCB2YXIyLCAiXyIsIGxhbmd1YWdlKSwgZGF0MSwgZW52aXIgPSAuR2xvYmFsRW52KQogICAgfQogICAgcm0oZGF0MSwgb3V0cHV0KQogICAgIyBydW4gcGxvdF9zbW9vdGggdG8gZ3JhYiBkYXRhIGZvciBwb2xhciBwbG90cwogICAgaWYgKGNvbmRpdGlvbj09InRva2VuUG9vbGVkLm9yZCIgJiYgbGVuZ3RoKGxhbmd1YWdlKT09MSl7CiAgICAgIGNvbmRfcDEgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj12YXIxKSIpKSkKICAgICAgY29uZF9wMiA9IGNhcHR1cmUub3V0cHV0KGNhdChwYXN0ZTAoImxpc3QoIiwgY29uZGl0aW9uLCAiPXZhcjIpIikpKQogICAgfWVsc2UgaWYgKGNvbmRpdGlvbj09ImxhbmdOb3RlSW50Lm9yZCIgJiYgbGVuZ3RoKGxhbmd1YWdlKT09Mil7CiAgICAgIGNvbmRfcDEgPSBjYXB0dXJlLm91dHB1dChjYXQocGFzdGUwKCJsaXN0KCIsIGNvbmRpdGlvbiwgIj0nIiwgbGFuZ3VhZ2VbMV0sICIuIiwgdmFyMSwgIi4iLCB2YXIyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJywgIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZVsyXSwgIi4iLCB2YXIxLCAiLiIsIHZhcjIsICInKSIpKSkKICAgICAgY29uZF9wMiA9IGNhcHR1cmUub3V0cHV0KGNhdChwYXN0ZTAoImxpc3QoIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZVsyXSwgIi4iLCB2YXIxLCAiLiIsIHZhcjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJywgIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZVsxXSwgIi4iLCB2YXIxLCAiLiIsIHZhcjIsICInKSIpKSkKICAgIH1lbHNlIGlmIChjb25kaXRpb249PSJsYW5nTm90ZUludC5vcmQiICYmIGxlbmd0aChsYW5ndWFnZSk9PTEgJiYgbGVuZ3RoKHZhcjEpPT0yKXsKICAgICAgY29uZF9wMSA9IGNhcHR1cmUub3V0cHV0KGNhdChwYXN0ZTAoImxpc3QoIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZSwgIi4iLCB2YXIxWzFdLCAiLiIsIHZhcjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJywgIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZSwgIi4iLCB2YXIxWzJdLCAiLiIsIHZhcjIsICInKSIpKSkKICAgICAgY29uZF9wMiA9IGNhcHR1cmUub3V0cHV0KGNhdChwYXN0ZTAoImxpc3QoIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZSwgIi4iLCB2YXIxWzJdLCAiLiIsIHZhcjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJywgIiwgY29uZGl0aW9uLCAiPSciLCBsYW5ndWFnZSwgIi4iLCB2YXIxWzFdLCAiLiIsIHZhcjIsICInKSIpKSkKICAgIH0KICAgIHAxID0gcGxvdF9zbW9vdGgoeD1nZXQobW9kZWwpLCB2aWV3PXZhbHVlcywgY29uZD1ldmFsKHBhcnNlKHRleHQ9Y29uZF9wMSkpLCBybS5yYW5lZj1UUlVFKQogICAgcDIgPSBwbG90X3Ntb290aCh4PWdldChtb2RlbCksIHZpZXc9dmFsdWVzLCBjb25kPWV2YWwocGFyc2UodGV4dD1jb25kX3AyKSksIHJtLnJhbmVmPVRSVUUpCiAgICAjIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIGhhbGYgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBtYXggb2YgdGhlIGZpdCBhbmQgdGhlIHVwcGVyIGxpbWl0CiAgICBtYXhpbXVtPW1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCkrKChtYXgocDEkZnYkdWwsIHAyJGZ2JHVsKS1tYXgocDEkZnYkZml0LCBwMiRmdiRmaXQpKS8yKQogICAgIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzCiAgICBpZiAoZXhpc3RzKCJzaWdfZGlmZjQiKSl7CiAgICAgIHA9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1uYW1lc19zbW9vdGhzWzFdKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIHdpZHRoPTIuNSksIG5hbWU9bmFtZXNfc21vb3Roc1syXSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGFkZF90cmFjZSh0aGV0YT1zZXEoc2lnX2RpZmYxWzFdKjE4MC9waSwgc2lnX2RpZmYxWzJdKjE4MC9waSwgbGVuZ3RoLm91dD0yMCksIAogICAgICAgICAgICAgICAgICByPWMoMCwgcmVwKG1heGltdW0sIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBhZGRfdHJhY2UodGhldGE9c2VxKHNpZ19kaWZmMlsxXSoxODAvcGksIHNpZ19kaWZmMlsyXSoxODAvcGksIGxlbmd0aC5vdXQ9MjApLCAKICAgICAgICAgICAgICAgICAgcj1jKDAsIHJlcChtYXhpbXVtLCAxOCksIDApLCBsaW5lPWxpc3QoY29sb3I9ImJsYWNrIiwgd2lkdGg9MC41KSwgZmlsbD0idG9zZWxmIiwgZmlsbGNvbG9yPXJnYigwLDAsMCxtYXg9MjU1LGFscGhhPTI1KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXNlcShzaWdfZGlmZjNbMV0qMTgwL3BpLCBzaWdfZGlmZjNbMl0qMTgwL3BpLCBsZW5ndGgub3V0PTIwKSwgCiAgICAgICAgICAgICAgICAgIHI9YygwLCByZXAobWF4aW11bSwgMTgpLCAwKSwgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIHdpZHRoPTAuNSksIGZpbGw9InRvc2VsZiIsIGZpbGxjb2xvcj1yZ2IoMCwwLDAsbWF4PTI1NSxhbHBoYT0yNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGFkZF90cmFjZSh0aGV0YT1zZXEoc2lnX2RpZmY0WzFdKjE4MC9waSwgc2lnX2RpZmY0WzJdKjE4MC9waSwgbGVuZ3RoLm91dD0yMCksIAogICAgICAgICAgICAgICAgICByPWMoMCwgcmVwKG1heGltdW0sIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgICAgICAgIHRpdGxlPXBsb3RfdGl0bGUsIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUsIHk9MC4wMTIpKQogICAgICBTeXMuc2xlZXAoMCkKICAgICAgcHJpbnQocCkKICAgIH1lbHNlIGlmIChleGlzdHMoInNpZ19kaWZmMyIpKXsKICAgICAgcD1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPW5hbWVzX3Ntb290aHNbMV0pICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgd2lkdGg9Mi41KSwgbmFtZT1uYW1lc19zbW9vdGhzWzJdKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXNlcShzaWdfZGlmZjFbMV0qMTgwL3BpLCBzaWdfZGlmZjFbMl0qMTgwL3BpLCBsZW5ndGgub3V0PTIwKSwgCiAgICAgICAgICAgICAgICAgIHI9YygwLCByZXAobWF4aW11bSwgMTgpLCAwKSwgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIHdpZHRoPTAuNSksIGZpbGw9InRvc2VsZiIsIGZpbGxjb2xvcj1yZ2IoMCwwLDAsbWF4PTI1NSxhbHBoYT0yNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGFkZF90cmFjZSh0aGV0YT1zZXEoc2lnX2RpZmYyWzFdKjE4MC9waSwgc2lnX2RpZmYyWzJdKjE4MC9waSwgbGVuZ3RoLm91dD0yMCksIAogICAgICAgICAgICAgICAgICByPWMoMCwgcmVwKG1heGltdW0sIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBhZGRfdHJhY2UodGhldGE9c2VxKHNpZ19kaWZmM1sxXSoxODAvcGksIHNpZ19kaWZmM1syXSoxODAvcGksIGxlbmd0aC5vdXQ9MjApLCAKICAgICAgICAgICAgICAgICAgcj1jKDAsIHJlcChtYXhpbXVtLCAxOCksIDApLCBsaW5lPWxpc3QoY29sb3I9ImJsYWNrIiwgd2lkdGg9MC41KSwgZmlsbD0idG9zZWxmIiwgZmlsbGNvbG9yPXJnYigwLDAsMCxtYXg9MjU1LGFscGhhPTI1KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiAgICAgICAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ3VsYXJheGlzPWxpc3QodGhldGF1bml0PSdyYWRpYW5zJywgZGlyZWN0aW9uPSJjbG9ja3dpc2UiLCByb3RhdGlvbj0wKSksIAogICAgICAgICAgICAgICB0aXRsZT1wbG90X3RpdGxlLCBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQogICAgICBTeXMuc2xlZXAoMCkKICAgICAgcHJpbnQocCkKICAgIH1lbHNlIGlmIChleGlzdHMoInNpZ19kaWZmMiIpKXsKICAgICAgcD1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPW5hbWVzX3Ntb290aHNbMV0pICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgd2lkdGg9Mi41KSwgbmFtZT1uYW1lc19zbW9vdGhzWzJdKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXNlcShzaWdfZGlmZjFbMV0qMTgwL3BpLCBzaWdfZGlmZjFbMl0qMTgwL3BpLCBsZW5ndGgub3V0PTIwKSwgCiAgICAgICAgICAgICAgICAgIHI9YygwLCByZXAobWF4aW11bSwgMTgpLCAwKSwgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIHdpZHRoPTAuNSksIGZpbGw9InRvc2VsZiIsIGZpbGxjb2xvcj1yZ2IoMCwwLDAsbWF4PTI1NSxhbHBoYT0yNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGFkZF90cmFjZSh0aGV0YT1zZXEoc2lnX2RpZmYyWzFdKjE4MC9waSwgc2lnX2RpZmYyWzJdKjE4MC9waSwgbGVuZ3RoLm91dD0yMCksIAogICAgICAgICAgICAgICAgICByPWMoMCwgcmVwKG1heGltdW0sIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgICAgICAgIHRpdGxlPXBsb3RfdGl0bGUsIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCiAgICAgIFN5cy5zbGVlcCgwKQogICAgICBwcmludChwKQogICAgfWVsc2V7CiAgICAgIHA9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1uYW1lc19zbW9vdGhzWzFdKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRsbCwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICAgICAgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIHdpZHRoPTIuNSksIG5hbWU9bmFtZXNfc21vb3Roc1syXSkgJT4lIAogICAgICAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgICAgICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogICAgICAgIGFkZF90cmFjZSh0aGV0YT1zZXEoc2lnX2RpZmYxWzFdKjE4MC9waSwgc2lnX2RpZmYxWzJdKjE4MC9waSwgbGVuZ3RoLm91dD0yMCksIAogICAgICAgICAgICAgICAgICByPWMoMCwgcmVwKG1heGltdW0sIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICAgICAgICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgICAgICAgIHRpdGxlPXBsb3RfdGl0bGUsIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCiAgICAgIFN5cy5zbGVlcCgwKQogICAgICBwcmludChwKQogICAgfQogIH0KICAjIG9yY2Egc2hvdWxkIHdvcmsgd2l0aCBwbG90bHkgNC45LjAgYWZ0ZXIgbG9hZGluZyB0aGUgb3JjYSBtb2R1bGUgYmVmb3JlIHN0YXRpbmcgUiBhbmQgUlN0dWRpbwogIGlmKHNhdmU9PVRSVUUpCiAgewogICAgb3JjYShwLCBwYXN0ZShmaWxlTmFtZSwiLnBkZiIsc2VwPSIiKSxmb3JtYXQ9InBkZiIpCiAgICBvcmNhKHAsIHBhc3RlKGZpbGVOYW1lLCIucGRmIixzZXA9IiIpLGZvcm1hdD0ianBlZyIpCiAgfQp9CmBgYAoKCiMgTG9hZCBmaW5hbCBtb2RlbHMKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFfQojIGxvYWQgZmluYWwgbW9kZWwgZm9yIEgxCk5vdGVzLmdhbS5BUi5Nb2QyID0gcmVhZFJEUygidXBkYXRlZF9tb2RlbHMvTm90ZXMuZ2FtLkFSLk1vZDIucmRzIikKCiMgbG9hZCBmaW5hbCBtb2RlbCBmb3IgSDFiClZBUi5nYW0uQVIuTW9kMiA9IHJlYWRSRFMoInVwZGF0ZWRfbW9kZWxzL1ZBUi5nYW0uQVIuTW9kMi5yZHMiKQoKIyBsb2FkIGZpbmFsIG1vZGVscyBmb3IgSDIKTlpFLmdhbS5BUi5Nb2QyID0gcmVhZFJEUygidXBkYXRlZF9tb2RlbHMvTlpFLmdhbS5BUi5Nb2QyLnJkcyIpClRvbmdhbi5nYW0uQVIuTW9kMiA9IHJlYWRSRFMoInVwZGF0ZWRfbW9kZWxzL1Rvbmdhbi5nYW0uQVIuTW9kMi5yZHMiKQpgYGAKCiMgQ3JlYXRlIHBhcGVyIHBsb3RzCgojIyAobmV3KSBGaWd1cmUgNCBIMSAtPiBwcmVkaWN0IGF2ZXJhZ2UgdmFsdWVzIGZvciBub3RlIHByb2R1Y3Rpb25zIE5aRSB2cyBUb25nYW4KCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFfQojIGNyZWF0ZSBkZk5vdGVzCmRmIDwtIHJlYWQuY3N2KCJHQU1NX1Ryb21ib25lX2RhdGEuY3N2Iiwgc2VwPScsJywgc3RyaW5nc0FzRmFjdG9ycyA9IEYpCiMgcmVtb3ZlIGVtcHR5IGNvbHVtbgpkZiRYID0gTlVMTApkZiR0b2tlblBvb2xlZCA8LSBmYWN0b3IoZGYkdG9rZW5Qb29sZWQpCmRmJHN1YmplY3QgPC0gZmFjdG9yKGRmJHN1YmplY3QpCmRmJG5hdGl2ZV9sZyA8LSBmYWN0b3IoZGYkbmF0aXZlX2xnKQojIGRmJHBsYXlpbmdfcHJvZmljaWVuY3lbZGYkcGxheWluZ19wcm9maWNpZW5jeSA9PSAiaW50ZXJtZWRpYXRlIl0gPC0gImFtYXRldXIiCmRmJHBsYXlpbmdfcHJvZmljaWVuY3kgPC0gZmFjdG9yKGRmJHBsYXlpbmdfcHJvZmljaWVuY3ksIGxldmVscyA9IGMoImFtYXRldXIiLCJpbnRlcm1lZGlhdGUiLCJzZW1pLXByb2Zlc3Npb25hbCIsInByb2Zlc3Npb25hbCIpKQpkZiRibG9jayA8LSBmYWN0b3IoZGYkYmxvY2spCmRmJHBvaW50IDwtIGFzLm51bWVyaWMoZGYkcG9pbnQpCmRmJG5vdGVfaW50ZW5zaXR5IDwtIGZhY3RvcihkZiRub3RlX2ludGVuc2l0eSwgbGV2ZWxzID0gYygicGlhbm8iLCJtZXp6b3BpYW5vIiwibWV6em9mb3J0ZSIsImZvcnRlIikpCiMgcmVtb3ZlIGZvcnRpc3NpbW8gdG9rZW5zCmRmID0gZGZbIShpcy5uYShkZiRub3RlX2ludGVuc2l0eSkgJiBkZiRhY3Rpdml0eT09Im11c2ljIiksXQpkZk5vdGVzIDwtIHN1YnNldChkZixkZiR0b2tlblBvb2xlZCA9PSAiQmIyInwKICAgICAgICAgICAgICAgICAgICBkZiR0b2tlblBvb2xlZCA9PSAiQmIzInwKICAgICAgICAgICAgICAgICAgICBkZiR0b2tlblBvb2xlZCA9PSAiRDQifAogICAgICAgICAgICAgICAgICAgIGRmJHRva2VuUG9vbGVkID09ICJGMyJ8CiAgICAgICAgICAgICAgICAgICAgZGYkdG9rZW5Qb29sZWQgPT0gIkY0IikKZGZOb3RlcyR0b2tlblBvb2xlZCA8LSBmYWN0b3IoZGZOb3RlcyR0b2tlblBvb2xlZCwgbGV2ZWxzID0gYygiQmIyIiwiRjMiLCJCYjMiLCJENCIsIkY0IikpCmRmTm90ZXMgPC0gc3Vic2V0KGRmTm90ZXMsZGZOb3RlcyRub3RlX2ludGVuc2l0eSA9PSAiZm9ydGUifAogICAgICAgICAgICAgICAgICAgIGRmTm90ZXMkbm90ZV9pbnRlbnNpdHkgPT0gIm1lenpvZm9ydGUifAogICAgICAgICAgICAgICAgICAgIGRmTm90ZXMkbm90ZV9pbnRlbnNpdHkgPT0gIm1lenpvcGlhbm8ifAogICAgICAgICAgICAgICAgICAgIGRmTm90ZXMkbm90ZV9pbnRlbnNpdHkgPT0gInBpYW5vIikKZGZOb3RlcyRub3RlX2ludGVuc2l0eSA8LSBmYWN0b3IoZGZOb3RlcyRub3RlX2ludGVuc2l0eSwgbGV2ZWxzID0gYygicGlhbm8iLCJtZXp6b3BpYW5vIiwibWV6em9mb3J0ZSIsImZvcnRlIikpCmRmTm90ZXMkbm90ZUludGVuSW50IDwtIGludGVyYWN0aW9uKGRmTm90ZXMkdG9rZW5Qb29sZWQsIGRmTm90ZXMkbm90ZV9pbnRlbnNpdHkpCmRmTm90ZXMkbGFuZ05vdGVJbnQgPC0gaW50ZXJhY3Rpb24oZGZOb3RlcyRuYXRpdmVfbGcsIGRmTm90ZXMkdG9rZW5Qb29sZWQsIGRmTm90ZXMkbm90ZV9pbnRlbnNpdHkpCmRmTm90ZXMkbmF0aXZlX2xnLm9yZCA8LSBhcy5vcmRlcmVkKGRmTm90ZXMkbmF0aXZlX2xnKQpjb250cmFzdHMoZGZOb3RlcyRuYXRpdmVfbGcub3JkKSA8LSAiY29udHIudHJlYXRtZW50IgpkZk5vdGVzJHRva2VuUG9vbGVkLm9yZCA8LSBhcy5vcmRlcmVkKGRmTm90ZXMkdG9rZW5Qb29sZWQpCmNvbnRyYXN0cyhkZk5vdGVzJHRva2VuUG9vbGVkLm9yZCkgPC0gImNvbnRyLnRyZWF0bWVudCIKZGZOb3RlcyRub3RlX2ludGVuc2l0eS5vcmQgPC0gYXMub3JkZXJlZChkZk5vdGVzJG5vdGVfaW50ZW5zaXR5KQpjb250cmFzdHMoZGZOb3RlcyRub3RlX2ludGVuc2l0eS5vcmQpIDwtICJjb250ci50cmVhdG1lbnQiCmRmTm90ZXMkbGFuZ05vdGVJbnQub3JkIDwtIGFzLm9yZGVyZWQoZGZOb3RlcyRsYW5nTm90ZUludCkKY29udHJhc3RzKGRmTm90ZXMkbGFuZ05vdGVJbnQub3JkKSA8LSAiY29udHIudHJlYXRtZW50IgpkZk5vdGVzJHN0YXJ0IDwtIGRmTm90ZXMkcG9pbnRzPT0xCgojIG1ha2UgY29weSBvZiBkZk5vdGVzCmRhdDEgPSBkZk5vdGVzCmRhdDEkcHJlZGljdGVkX3ZhbHVlcyA9IHByZWRpY3QoTm90ZXMuZ2FtLkFSLk1vZDIpCgojIHBsb3QgaW4gcG9sYXIgY29vcmRpbmF0ZXMgdXNpbmcgcGxvdGx5CmRhdDFfTlpFID0gZGF0MVtkYXQxJG5hdGl2ZV9sZyA9PSAiTlpFIixdCmRhdDFfVG9uZ2FuID0gZGF0MVtkYXQxJG5hdGl2ZV9sZyA9PSAiVG9uZ2FuIixdCgojIGVzdGltYXRlIHNtb290aHMgdXNpbmcgUidzIGdlbmVyaWMgcHJlZGljdC5zbW9vdGguc3BsaW5lIGZ1bmN0aW9uCnNtb290aF9OWkU9bGlzdCh0aGV0YT1zZXEobWluKGRhdDFfTlpFJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgbWF4KGRhdDFfTlpFJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgbGVuZ3RoPTEwMCksIHI9cHJlZGljdChzbW9vdGguc3BsaW5lKGRhdDFfTlpFJHRoZXRhX3VuY3V0X3osIGRhdDFfTlpFJHByZWRpY3RlZF92YWx1ZXMpLAogc2VxKG1pbihkYXQxX05aRSR0aGV0YV91bmN1dF96KSwgbWF4KGRhdDFfTlpFJHRoZXRhX3VuY3V0X3opLCBsZW5ndGg9MTAwKSkkeSwgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaD0iZGFzaCIpKQoKc21vb3RoX1Rvbmdhbj1saXN0KHRoZXRhPXNlcShtaW4oZGF0MV9Ub25nYW4kdGhldGFfdW5jdXRfeikqMTgwL3BpLCBtYXgoZGF0MV9Ub25nYW4kdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoZGF0MV9Ub25nYW4kdGhldGFfdW5jdXRfeiwgZGF0MV9Ub25nYW4kcHJlZGljdGVkX3ZhbHVlcyksCiBzZXEobWluKGRhdDFfVG9uZ2FuJHRoZXRhX3VuY3V0X3opLCBtYXgoZGF0MV9Ub25nYW4kdGhldGFfdW5jdXRfeiksIGxlbmd0aD0xMDApKSR5LCBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2g9IiIpKQoKIyBzZXQgUmhvIG1heCB0byB0aGUgbWF4IG9mIHRoZSBwcmVkaWN0ZWRfdmFsdWVzICsgNQptYXhfcHJlZGljdGlvbnMgPSBtYXgobWF4KHNtb290aF9OWkUkciksIG1heChzbW9vdGhfVG9uZ2FuJHIpKQptYXhpbXVtPW1heF9wcmVkaWN0aW9ucys1CnJtKG1heF9wcmVkaWN0aW9ucykKCnAgPSBwbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lCmFkZF90cmFjZSh0aGV0YT1zbW9vdGhfTlpFJHRoZXRhLCByPXNtb290aF9OWkUkciwgbGluZT1saXN0KGNvbG9yPXNtb290aF9OWkUkbGluZSRjb2xvcltbMV1dLCB3aWR0aD0yLjUsIGRhc2g9c21vb3RoX05aRSRsaW5lJGRhc2hbWzFdXSksIG5hbWU9Im92ZXJhbGwgYXZlcmFnZSBvZiBOWkUgbm90ZXMiKSAlPiUKICBhZGRfdHJhY2UodGhldGE9c21vb3RoX1RvbmdhbiR0aGV0YSwgcj1zbW9vdGhfVG9uZ2FuJHIsIGxpbmU9bGlzdChjb2xvcj1zbW9vdGhfVG9uZ2FuJGxpbmUkY29sb3JbWzFdXSwgd2lkdGg9Mi41LCBkYXNoPXNtb290aF9Ub25nYW4kbGluZSRkYXNoW1sxXV0pLCBuYW1lPSJvdmVyYWxsIGF2ZXJhZ2Ugb2YgVG9uZ2FuIG5vdGVzIikgJT4lCiAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLCBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCB0aXRsZT0iT3ZlcmFsbCBhdmVyYWdlIHNtb290aHMgZm9yIE5aRSB2cyBUb25nYW4gbm90ZSBwcm9kdWN0aW9ucyIsIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCnAKaWYoc2F2ZT09VFJVRSl7CiAgb3JjYShwLCAiRmlndXJlNC5wZGYiLGZvcm1hdD0icGRmIikKICBvcmNhKHAsICJGaWd1cmU0LmpwZyIsZm9ybWF0PSJqcGVnIikKfQpybShkYXQxLCBkYXQxX05aRSwgZGF0MV9Ub25nYW4sIG1heGltdW0sIHNtb290aF9OWkUsIHNtb290aF9Ub25nYW4pCmBgYAoKCiMjIEZpZ3VyZSA1IChwcmV2aW91c2x5IDQpIC0+IEgxCgojIyMgQmIyIGZvcnRlCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KcGxvdGx5X3Ntb290aHNfd19zaWdfZGlmZihtb2RlbD0iTm90ZXMuZ2FtLkFSLk1vZDIiLCBjb25kaXRpb249ImxhbmdOb3RlSW50Lm9yZCIsIHZhcjE9IkJiMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHZhcjI9ImZvcnRlIiwgdmFsdWVzPSJ0aGV0YV91bmN1dF96IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ3VhZ2U9YygiTlpFIiwiVG9uZ2FuIiksIGZpbGVOYW1lID0gIkZpZ3VyZTUoYSkiLCBzYXZlPXByaW50UERGKQpgYGAKCiMjIyBGMyBtZXp6b2ZvcnRlCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KcGxvdGx5X3Ntb290aHNfd19zaWdfZGlmZihtb2RlbD0iTm90ZXMuZ2FtLkFSLk1vZDIiLCBjb25kaXRpb249ImxhbmdOb3RlSW50Lm9yZCIsIHZhcjE9IkYzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyMj0ibWV6em9mb3J0ZSIsIHZhbHVlcz0idGhldGFfdW5jdXRfeiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ3VhZ2U9YygiTlpFIiwiVG9uZ2FuIiksICxmaWxlTmFtZSA9ICJGaWd1cmU1KGIpIixzYXZlPXByaW50UERGKQpgYGAKCiMjIyBCYjMgbWV6em9mb3J0ZQoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CnBsb3RseV9zbW9vdGhzX3dfc2lnX2RpZmYobW9kZWw9Ik5vdGVzLmdhbS5BUi5Nb2QyIiwgY29uZGl0aW9uPSJsYW5nTm90ZUludC5vcmQiLCB2YXIxPSJCYjMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIyPSJtZXp6b2ZvcnRlIiwgdmFsdWVzPSJ0aGV0YV91bmN1dF96IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFuZ3VhZ2U9YygiTlpFIiwiVG9uZ2FuIiksZmlsZU5hbWUgPSAiRmlndXJlNShjKSIsc2F2ZT1wcmludFBERikKCmBgYAoKIyMjIEludGVydmFscyBvZiBzaWduaWZpY2FudCBkaWZmZXJlbmNlIDE2IG91dCBvZiAxOSBjb21wYXJpc29ucwoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CiMgcmVhZCAuY3N2IGZpbGUKc2lnX2RpZmZzID0gcmVhZC5jc3YoZmlsZSA9ICJOb3Rlcy5nYW0uQVIuTW9kMl9pbnRlcnZhbHNfb2Zfc2lnbmlmaWNhbnRfZGlmZmVyZW5jZXMuY3N2IiwgCiAgICAgICAgICAgICAgICAgICAgIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9MSkKCiMgR290IHJpZCBvZiB0aGlzIHBsb3QhCiMgIyB2aXN1YWxpemUgYXJlYXMgb2Ygb3ZlcmFsbCBkaWZmZXJlbmNlCiMgcDE9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXNlcShzaWdfZGlmZnNbIjE3X291dF9vZl8xOSIsMV0qMTgwL3BpLCBzaWdfZGlmZnNbIjE3X291dF9vZl8xOSIsMl0qMTgwL3BpLCAKIyAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLm91dD0yMCksIHI9YygwLCByZXAoMzIwLCAxOCksIDApLCBsaW5lPWxpc3QoY29sb3I9ImJsYWNrIiwgd2lkdGg9MC41KSwgCiMgICAgICAgICAgICAgZmlsbD0idG9zZWxmIiwgZmlsbGNvbG9yPXJnYigwLDAsMCxtYXg9MjU1LGFscGhhPTI1KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9c2VxKHNpZ19kaWZmc1siMTdfb3V0X29mXzE5IiwzXSoxODAvcGksIHNpZ19kaWZmc1siMTdfb3V0X29mXzE5Iiw0XSoxODAvcGksIAojICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgub3V0PTIwKSwgcj1jKDAsIHJlcCgzMjAsIDE4KSwgMCksIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCB3aWR0aD0wLjUpLCAKIyAgICAgICAgICAgICBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiMgICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCwzMjApKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKIyAgICAgICAgICB0aXRsZT1wYXN0ZTAoIkludGVydmFscyBvZiBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBmb3IgMTcgb3V0IG9mIDE5IGNvbXBhcmlzb25zIiksIAojICAgICAgICAgIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCiMgU3lzLnNsZWVwKDApCiMgcHJpbnQocDEpCgpwMj1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXNlcShzaWdfZGlmZnNbIjE2X291dF9vZl8xOSIsMV0qMTgwL3BpLCBzaWdfZGlmZnNbIjE2X291dF9vZl8xOSIsMl0qMTgwL3BpLCAKICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aC5vdXQ9MjApLCByPWMoMCwgcmVwKDMyMCwgMTgpLCAwKSwgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIHdpZHRoPTAuNSksIAogICAgICAgICAgICBmaWxsPSJ0b3NlbGYiLCBmaWxsY29sb3I9cmdiKDAsMCwwLG1heD0yNTUsYWxwaGE9MjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICBhZGRfdHJhY2UodGhldGE9c2VxKHNpZ19kaWZmc1siMTZfb3V0X29mXzE5IiwzXSoxODAvcGksIHNpZ19kaWZmc1siMTZfb3V0X29mXzE5Iiw0XSoxODAvcGksIAogICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoLm91dD0yMCksIHI9YygwLCByZXAoMzIwLCAxOCksIDApLCBsaW5lPWxpc3QoY29sb3I9ImJsYWNrIiwgd2lkdGg9MC41KSwgCiAgICAgICAgICAgIGZpbGw9InRvc2VsZiIsIGZpbGxjb2xvcj1yZ2IoMCwwLDAsbWF4PTI1NSxhbHBoYT0yNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCwzMjApKSwKICAgICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgIHRpdGxlPXBhc3RlMCgiSW50ZXJ2YWxzIG9mIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGZvciAxNiBvdXQgb2YgMTkgY29tcGFyaXNvbnMiKSwgCiAgICAgICAgIGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpClN5cy5zbGVlcCgwKQpwcmludChwMikKaWYocHJpbnRQREY9PVRSVUUpCnsKICBvcmNhKHAyLCAiRmlndXJlNShkKS5wZGYiLGZvcm1hdD0icGRmIikKICBvcmNhKHAyLCAiRmlndXJlNShkKS5qcGciLGZvcm1hdD0ianBlZyIpCn0Kcm0oc2lnX2RpZmZzLCBwMSwgcDIpCmBgYAoKCiMjIEZpZ3VyZSA2IC0+IEgxYgoKYGBge3J9CiMgZGYgYWxyZWFkeSBsb2FkZWQgYWJvdmUKCmRmU3VtbWFyeSA8LSBncm91cF9ieShkZiwgc3ViamVjdCwgcGxheWluZ19wcm9maWNpZW5jeSwgYWN0aXZpdHksIG5hdGl2ZV9sZywgdG9rZW5Qb29sZWQsIHRoZXRhX3VuY3V0X3pfZ3JvdXAgPSBjdXQodGhldGFfdW5jdXRfeixicmVha3M9MTAwKSkgJT4lIHN1bW1hcmlzZShyaG9WYXIgPSBzZChyaG9fdW5jdXRfeixuYS5ybT1UUlVFKSkKZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3ogPSBhcy5jaGFyYWN0ZXIoZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3pfZ3JvdXApCmRmU3VtbWFyeSR0aGV0YV91bmN1dF96ID0gZ3N1YigiXFxbfFxcXXxcXCh8XFwpIiwgIiIsZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3opCmRmU3VtbWFyeSR0aGV0YV91bmN1dF96ID0gc3Ryc3BsaXQoZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3osIiwiKQpkZlN1bW1hcnkkdGhldGFfdW5jdXRfejIgPSAxCmZvcihpIGluIGMoMTpucm93KGRmU3VtbWFyeSkpKQp7CiAgZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3oyW2ldID0gbWVhbihhcy5udW1lcmljKHVubGlzdChkZlN1bW1hcnkkdGhldGFfdW5jdXRfeltpXSkpKQp9CmRmU3VtbWFyeSR0aGV0YV91bmN1dF96PWRmU3VtbWFyeSR0aGV0YV91bmN1dF96MgpkZlN1bW1hcnkkcGxheWluZ19wcm9maWNpZW5jeS5vcmQgPC0gYXMub3JkZXJlZChkZlN1bW1hcnkkcGxheWluZ19wcm9maWNpZW5jeSkKY29udHJhc3RzKGRmU3VtbWFyeSRwbGF5aW5nX3Byb2ZpY2llbmN5Lm9yZCkgPC0gImNvbnRyLnRyZWF0bWVudCIKZGZTdW1tYXJ5JGFjdGl2aXR5Lm9yZCA8LSBhcy5vcmRlcmVkKGRmU3VtbWFyeSRhY3Rpdml0eSkKY29udHJhc3RzKGRmU3VtbWFyeSRhY3Rpdml0eS5vcmQpIDwtICJjb250ci50cmVhdG1lbnQiCmRmU3VtbWFyeSRsYW5nTm90ZUludCA8LSBpbnRlcmFjdGlvbihkZlN1bW1hcnkkbmF0aXZlX2xnLCAKZGZTdW1tYXJ5JHRva2VuUG9vbGVkKQpkZlN1bW1hcnkkbGFuZ05vdGVJbnQub3JkIDwtIGFzLm9yZGVyZWQoZGZTdW1tYXJ5JGxhbmdOb3RlSW50KQpjb250cmFzdHMoZGZTdW1tYXJ5JGxhbmdOb3RlSW50Lm9yZCkgPC0gImNvbnRyLnRyZWF0bWVudCIKZGZTdW1tYXJ5JG5hdGl2ZV9sZy5vcmQgPC0gYXMub3JkZXJlZChkZlN1bW1hcnkkbmF0aXZlX2xnKQpjb250cmFzdHMoZGZTdW1tYXJ5JG5hdGl2ZV9sZy5vcmQpIDwtICJjb250ci50cmVhdG1lbnQiCmRmU3VtbWFyeSR0b2tlblBvb2xlZC5vcmQgPC0gYXMub3JkZXJlZChkZlN1bW1hcnkkdG9rZW5Qb29sZWQpCmNvbnRyYXN0cyhkZlN1bW1hcnkkdG9rZW5Qb29sZWQub3JkKSA8LSAiY29udHIudHJlYXRtZW50IgpkZlN1bW1hcnkgPSBuYS5vbWl0KGRmU3VtbWFyeSkKCiNkZlN1bW1hcnkkc3RhcnQgPC0gZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3o9PW1pbihkZlN1bW1hcnkkdGhldGFfdW5jdXRfeikKCmRmU3VtbWFyeSRzdGFydCA9IFRSVUUKZm9yKGkgaW4gdW5pcXVlKGRmU3VtbWFyeSRzdWJqZWN0KSkKewogIGRmU3ViamVjdCA9IHN1YnNldChkZlN1bW1hcnksZGZTdW1tYXJ5JHN1YmplY3QgPT0gaSkKICBmb3IoaiBpbiB1bmlxdWUoZGZTdWJqZWN0JHRva2VuUG9vbGVkKSkKICB7CiAgICBkZlN1bW1hcnkkc3RhcnRbZGZTdW1tYXJ5JHN1YmplY3QgPT0gaSAmIGRmU3VtbWFyeSR0b2tlblBvb2xlZCA9PSBqXSA8LSAKICAgICAgZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3pbZGZTdW1tYXJ5JHN1YmplY3QgPT0gaSAmIGRmU3VtbWFyeSR0b2tlblBvb2xlZCA9PSBqXSA9PQogICAgICBtaW4oZGZTdW1tYXJ5JHRoZXRhX3VuY3V0X3pbZGZTdW1tYXJ5JHN1YmplY3QgPT0gaSAmIGRmU3VtbWFyeSR0b2tlblBvb2xlZCA9PSBqXSkKICB9Cn0KCiMgbWFrZSBjb3B5IG9mIGRmTm90ZXMKZGF0MSA9IGRmU3VtbWFyeQpkYXQxJHByZWRpY3RlZF92YWx1ZXMgPSBwcmVkaWN0KFZBUi5nYW0uQVIuTW9kMikKCiMgcGxvdCBpbiBwb2xhciBjb29yZGluYXRlcyB1c2luZyBwbG90bHkKZGF0MV9OWkUgPSBkYXQxW2RhdDEkbmF0aXZlX2xnID09ICJOWkUiLF0KZGF0MV9Ub25nYW4gPSBkYXQxW2RhdDEkbmF0aXZlX2xnID09ICJUb25nYW4iLF0KCiMgZXN0aW1hdGUgc21vb3RocyB1c2luZyBSJ3MgZ2VuZXJpYyBwcmVkaWN0LnNtb290aC5zcGxpbmUgZnVuY3Rpb24Kc21vb3RoX05aRT1saXN0KHRoZXRhPXNlcShtaW4oZGF0MV9OWkUkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBtYXgoZGF0MV9OWkUkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoZGF0MV9OWkUkdGhldGFfdW5jdXRfeiwgZGF0MV9OWkUkcHJlZGljdGVkX3ZhbHVlcyksCiBzZXEobWluKGRhdDFfTlpFJHRoZXRhX3VuY3V0X3opLCBtYXgoZGF0MV9OWkUkdGhldGFfdW5jdXRfeiksIGxlbmd0aD0xMDApKSR5LCBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoPSJkYXNoIikpCgpzbW9vdGhfVG9uZ2FuPWxpc3QodGhldGE9c2VxKG1pbihkYXQxX1RvbmdhbiR0aGV0YV91bmN1dF96KSoxODAvcGksIG1heChkYXQxX1RvbmdhbiR0aGV0YV91bmN1dF96KSoxODAvcGksIGxlbmd0aD0xMDApLCByPXByZWRpY3Qoc21vb3RoLnNwbGluZShkYXQxX1RvbmdhbiR0aGV0YV91bmN1dF96LCBkYXQxX1RvbmdhbiRwcmVkaWN0ZWRfdmFsdWVzKSwKIHNlcShtaW4oZGF0MV9Ub25nYW4kdGhldGFfdW5jdXRfeiksIG1heChkYXQxX1RvbmdhbiR0aGV0YV91bmN1dF96KSwgbGVuZ3RoPTEwMCkpJHksIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgZGFzaD0iIikpCgojIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIHByZWRpY3RlZF92YWx1ZXMgKyA1Cm1heF9wcmVkaWN0aW9ucyA9IG1heChtYXgoc21vb3RoX05aRSRyKSwgbWF4KHNtb290aF9Ub25nYW4kcikpCm1heGltdW09bWF4X3ByZWRpY3Rpb25zKzUKcm0obWF4X3ByZWRpY3Rpb25zKQoKcCA9IHBsb3RfbHkodHlwZT0nc2NhdHRlcnBvbGFyJywgbW9kZT0nbGluZXMnKSAlPiUKYWRkX3RyYWNlKHRoZXRhPXNtb290aF9OWkUkdGhldGEsIHI9c21vb3RoX05aRSRyLCBsaW5lPWxpc3QoY29sb3I9c21vb3RoX05aRSRsaW5lJGNvbG9yW1sxXV0sIHdpZHRoPTIuNSwgZGFzaD1zbW9vdGhfTlpFJGxpbmUkZGFzaFtbMV1dKSwgbmFtZT0ib3ZlcmFsbCBhdmVyYWdlIG9mIE5aRSBub3RlcyIpICU+JQogIGFkZF90cmFjZSh0aGV0YT1zbW9vdGhfVG9uZ2FuJHRoZXRhLCByPXNtb290aF9Ub25nYW4kciwgbGluZT1saXN0KGNvbG9yPXNtb290aF9Ub25nYW4kbGluZSRjb2xvcltbMV1dLCB3aWR0aD0yLjUsIGRhc2g9c21vb3RoX1RvbmdhbiRsaW5lJGRhc2hbWzFdXSksIG5hbWU9Im92ZXJhbGwgYXZlcmFnZSBvZiBUb25nYW4gbm90ZXMiKSAlPiUKICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksIGFuZ3VsYXJheGlzPWxpc3QodGhldGF1bml0PSdyYWRpYW5zJywgZGlyZWN0aW9uPSJjbG9ja3dpc2UiLCByb3RhdGlvbj0wKSksIHRpdGxlPSJPdmVyYWxsIGF2ZXJhZ2Ugc21vb3RocyBmb3IgTlpFIHZzIFRvbmdhbiBub3RlIHByb2R1Y3Rpb25zIiwgbGVnZW5kPWxpc3Qob3JpZW50YXRpb249ImgiLCB4YW5jaG9yPSJjZW50ZXIiLCB4PTAuNSx5PTAuMDEyKSkKcAppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocCwgIkZpZ3VyZTYucGRmIixmb3JtYXQ9InBkZiIpCiAgb3JjYShwLCAiRmlndXJlNi5qcGciLGZvcm1hdD0ianBlZyIpCn0Kcm0oZGF0MSwgZGF0MV9OWkUsIGRhdDFfVG9uZ2FuLCBtYXhpbXVtLCBzbW9vdGhfTlpFLCBzbW9vdGhfVG9uZ2FuKQpgYGAKCgojIyBGaWd1cmUgNyAtPiBIMiB2b3dlbHMgYW5kIG5vdGVzIE5aRQoKIyMjIEFsbCBOWkUgdm93ZWxzCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KIyBkZWZpbmUgY29sb3JzIGZyb20gUGhEIHRoZXNpcwpSRUQwID0gKHJnYigyMTMsMTMsMTEsIDI1NSwgbWF4Q29sb3JWYWx1ZT0yNTUpKQpCUk9XTjAgPSAocmdiKDEyMyw3Myw1NSwyNTUsIG1heENvbG9yVmFsdWU9MjU1KSkKUFVSUExFMCA9IChyZ2IoMTQzLDcyLDE4MywyNTUsIG1heENvbG9yVmFsdWU9MjU1KSkKR1JBWTAgPSAocmdiKDEwOCwxMDgsMTA4LDI1NSwgbWF4Q29sb3JWYWx1ZT0yNTUpKQpHUkVFTjAgPSAocmdiKDAsMTUxLDU1LDI1NSwgbWF4Q29sb3JWYWx1ZT0yNTUpKQpPUkFOR0UwID0gKHJnYigyNTUsMTIzLDAsMjU1LCBtYXhDb2xvclZhbHVlPTI1NSkpClBJTkswID0gKHJnYigyMjQsMTMwLDE4MCwyNTUsIG1heENvbG9yVmFsdWU9MjU1KSkKVEVBTDAgPSAocmdiKDAsMTc1LDE5NSwyNTUsIG1heENvbG9yVmFsdWU9MjU1KSkKR09MRDAgPSAocmdiKDE3MiwxODEsMCwyNTUsIG1heENvbG9yVmFsdWU9MjU1KSkKbGlnaHRfYmx1ZT1yZ2IoMCwxMTcsMjIwLDI1NSxtYXhDb2xvclZhbHVlPTI1NSkKYmxhY2s9cmdiKDI1LDI1LDI1LDI1NSxtYXhDb2xvclZhbHVlPTI1NSkKcGluaz1yZ2IoMTk0LDAsMTM2LDI1NSxtYXhDb2xvclZhbHVlPTI1NSkKZGFya19ibHVlPXJnYigwLDUxLDEyOCwyNTUsbWF4Q29sb3JWYWx1ZT0yNTUpCmRhcmtfcmVkPXJnYigxNTMsMCwwLDI1NSxtYXhDb2xvclZhbHVlPTI1NSkKCiMgY29ycmVjdCBvcmRlcgpjb2xvcnMgPSBjKE9SQU5HRTAsIGRhcmtfYmx1ZSwgR1JFRU4wLCBsaWdodF9ibHVlLCBQSU5LMCwgR09MRDAsIEJST1dOMCwgVEVBTDAsIEdSQVkwLCBkYXJrX3JlZCwKICAgICAgICAgICBSRUQwLCBQVVJQTEUwLCBwaW5rKQoKIyBydW4gcGxvdF9zbW9vdGggdG8gZ3JhYiB2YWx1ZXMgZm9yIGZpdCwgdXBwZXIgJiBsb3dlciBib3VuZHMKcDE9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJpy5AiKSwgcm0ucmFuZWY9VFJVRSkKcDI9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJlIiksIHJtLnJhbmVmPVRSVUUpCnAzPXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iyonLkCIpLCBybS5yYW5lZj1UUlVFKQpwND1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmbIiksIHJtLnJhbmVmPVRSVUUpCnA1PXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iybXLkCIpLCBybS5yYW5lZj1UUlVFKQpwNj1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmYIiksIHJtLnJhbmVmPVRSVUUpCnA3PXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iyZkiKSwgcm0ucmFuZWY9VFJVRSkKcDg9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSLKiiIpLCBybS5yYW5lZj1UUlVFKQpwOT1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmZIyIpLCBybS5yYW5lZj1UUlVFKQpwMTA9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSLJkCIpLCBybS5yYW5lZj1UUlVFKQpwMTE9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSLJkMuQIiksIHJtLnJhbmVmPVRSVUUpCnAxMj1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmSIiksIHJtLnJhbmVmPVRSVUUpCnAxMz1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9Im/LkCIpLCBybS5yYW5lZj1UUlVFKQoKc21vb3RoX25hbWVzPWMoIkZMRUVDRSAvacuQLyIsIkRSRVNTIC9lLyIsIkdPT1NFIC/KicuQLyIsIlRSQVAgL8mbLyIsIk5VUlNFIC/JtcuQLyIsIktJVCAvyZgvIiwKICAgICAgICAgICAgICAgIm5vbi1maW5hbCBzY2h3YSAvyZkvIiwiRk9PVCAvyoovIiwiZmluYWwgc2Nod2EgL8mZIy8iLCJTVFJVVCAvyZAvIiwiU1RBUlQgL8mQy5AvIiwKICAgICAgICAgICAgICAgIkxPVCAvyZIvIiwiVEhPVUdIVCAvb8uQLyIpCgojICMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgaGFsZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1heCBvZiB0aGUgZml0IGFuZCB0aGUgdXBwZXIgbGltaXQKIyBtYXhfdWwgPSBtYXgocDEkZnYkdWwsIHAyJGZ2JHVsLCBwMyRmdiR1bCwgcDQkZnYkdWwsIHA1JGZ2JHVsLCBwNiRmdiR1bCwgcDckZnYkdWwsIHA4JGZ2JHVsLCBwOSRmdiR1bCwgcDEwJGZ2JHVsLCBwMTEkZnYkdWwsIHAxMiRmdiR1bCwgcDEzJGZ2JHVsKQojIG1heF9maXQgPSBtYXgocDEkZnYkZml0LCBwMiRmdiRmaXQsIHAzJGZ2JGZpdCwgcDQkZnYkZml0LCBwNSRmdiRmaXQsIHA2JGZ2JGZpdCwgcDckZnYkZml0LCBwOCRmdiRmaXQsIHA5JGZ2JGZpdCwgcDEwJGZ2JGZpdCwgcDExJGZ2JGZpdCwgcDEyJGZ2JGZpdCwgcDEzJGZ2JGZpdCkKIyBtYXhpbXVtPW1heF9maXQrKChtYXhfdWwtbWF4X2ZpdCkvMikKIyBybShtYXhfdWwsIG1heF9maXQpCiMgCiMgIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGggY29uZmlkZW5jZSBib3VuZHMKIyBwbG90MT1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzFdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbMV0pICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzFdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIHdpZHRoPTIuNSksCiMgICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzJdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRsbCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1syXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDMkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDMkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzNdLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDMkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDMkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzRdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNCRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzVdLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzVdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNSRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s1XSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA2JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA2JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s2XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzZdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s2XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA2JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA2JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzZdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDckZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDckZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzddLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzddKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNyRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s3XSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDckZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDckZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbN10sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA4JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA4JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s4XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzhdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wOCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOCRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s4XSwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA4JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA4JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDkkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDkkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzldLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzldKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wOSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOSRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s5XSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDkkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDkkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxMCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTAkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEwXSwgd2lkdGg9Mi41KSwKIyAgICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1sxMF0pICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxMCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTAkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTBdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTAkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEwJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEwXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDExJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTFdLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzExXSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDExJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMSRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTEkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTFdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEyJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMl0sIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1sxMl0pICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTIkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTJdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMiRmdiRsbCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMl0sIGRhc2g9ImRhc2giLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTMkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEzJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxM10sIHdpZHRoPTIuNSksCiMgICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMTNdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTMkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEzJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEzXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEzJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMyRmdiRsbCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxM10sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLAojICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwKIyAgICAgICAgICB0aXRsZT0iQWxsIHZvd2VscyBwcm9kdWNlZCBieSBOWkUgc3BlYWtlcnMiKQojIHBsb3QxCgojIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIDUKbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCwgcDYkZnYkZml0LCBwNyRmdiRmaXQsIHA4JGZ2JGZpdCwgcDkkZnYkZml0LCBwMTAkZnYkZml0LCBwMTEkZnYkZml0LCBwMTIkZnYkZml0LCBwMTMkZnYkZml0KQptYXhpbXVtPW1heF9maXQrNQpybShtYXhfZml0KQoKIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGhvdXQgY29uZmlkZW5jZSBib3VuZHMKcGxvdDI9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1sxXSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1syXSwgd2lkdGg9Mi41KSwKICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIHdpZHRoPTIuNSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIHdpZHRoPTIuNSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzVdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDYkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDYkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzZdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbN10sIHdpZHRoPTIuNSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzddKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDgkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDgkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbOF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wOSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIHdpZHRoPTIuNSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzldKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDEwJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMCRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTBdLCB3aWR0aD0yLjUpLAogICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1sxMF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMTEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDExJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMV0sIHdpZHRoPTIuNSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzExXSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXAxMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEyXSwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzEyXSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXAxMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMTMkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEzXSwgd2lkdGg9Mi41KSwKICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMTNdKSAlPiUKICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwKICAgICAgICAgdGl0bGU9IkFsbCB2b3dlbHMgcHJvZHVjZWQgYnkgTlpFIHNwZWFrZXJzIiwKICAgICAgICAgbGVnZW5kPWxpc3Qob3JpZW50YXRpb249ImgiLCB4YW5jaG9yPSJjZW50ZXIiLCB4PTAuNSx5PTAuMDA4KSkKcGxvdDIKaWYocHJpbnRQREY9PVRSVUUpCnsKICBvcmNhKHBsb3QyLCAiRmlndXJlNyhhKS5wZGYiLGZvcm1hdD0icGRmIikKICBvcmNhKHBsb3QyLCAiRmlndXJlNyhhKS5qcGciLGZvcm1hdD0ianBlZyIpCn0KCnJtKHAxLHAyLHAzLHA0LHA1LHA2LHA3LHA4LHA5LHAxMCxwMTEscDEyLHAxMykKYGBgCgojIyMgQWxsIE5aRSBub3RlcwoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CiMgY29ycmVjdCBvcmRlcgpjb2xvcnMgPSBjKGJsYWNrLCBibGFjaywgYmxhY2ssIGJsYWNrLCBibGFjaykKCnAxPXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iQmIyIiksIHJtLnJhbmVmPVRSVUUpCnAyPXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iRjMiKSwgcm0ucmFuZWY9VFJVRSkKcDM9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJCYjMiKSwgcm0ucmFuZWY9VFJVRSkKcDQ9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJENCIpLCBybS5yYW5lZj1UUlVFKQpwNT1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkY0IiksIHJtLnJhbmVmPVRSVUUpCgpzbW9vdGhfbmFtZXM9YygiQmIyIiwiRjMiLCJCYjMiLCJENCIsIkY0IikKCiMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgNQojbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCkKI21heGltdW09bWF4X2ZpdCs1CiNybShtYXhfZml0KQoKIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGhvdXQgY29uZmlkZW5jZSBib3VuZHMKcD1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxXSwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbMV0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1syXSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXAzJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAzJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZG90Iiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbM10pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNCRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNF0sIGRhc2g9ImRhc2hkb3QiLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1s0XSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXA1JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA1JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s1XSwgd2lkdGg9MSksCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzVdKSAlPiUKICBsYXlvdXQocG9sYXI9bGlzdChzZWN0b3I9YygyMCwxNjApLCByYWRpYWxheGlzPWxpc3QoYW5nbGU9OTAsIHJhbmdlPWMoMCxtYXhpbXVtKSksCiAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwKICAgICAgICAgdGl0bGU9IkFsbCBub3RlcyBwcm9kdWNlZCBieSBOWkUgc3BlYWtlcnMiLAogICAgICAgICBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQpwCgppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocCwgIkZpZ3VyZTcoYikucGRmIixmb3JtYXQ9InBkZiIpCiAgb3JjYShwLCAiRmlndXJlNyhiKS5qcGciLGZvcm1hdD0ianBlZyIpCn0KCnJtKHAxLHAyLHAzLHA0LHA1KQpgYGAKCgojIyBGaWd1cmUgOCAtPiBIMiB2b3dlbHMgYW5kIG5vdGVzIFRvbmdhbgoKIyMjIEFsbCBUb25nYW4gdm93ZWxzCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KIyB1c2UgY29sb3JzIGZyb20gUGhEIHRoZXNpcyAobG9hZGVkIGFib3ZlKQpjb2xvcnMgPSBjKE9SQU5HRTAsIGRhcmtfYmx1ZSwgUkVEMCwgcGluaywgR1JFRU4wKQoKIyBydW4gcGxvdF9zbW9vdGggdG8gZ3JhYiB2YWx1ZXMgZm9yIGZpdCwgdXBwZXIgJiBsb3dlciBib3VuZHMKcDE9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJpIiksIHJtLnJhbmVmPVRSVUUpCnAyPXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iZSIpLCBybS5yYW5lZj1UUlVFKQpwMz1wbG90X3Ntb290aCh4PVRvbmdhbi5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9ImEiKSwgcm0ucmFuZWY9VFJVRSkKcDQ9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJvIiksIHJtLnJhbmVmPVRSVUUpCnA1PXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0idSIpLCBybS5yYW5lZj1UUlVFKQpzbW9vdGhfbmFtZXM9YygiL2kvIiwiL2UvIiwiL2EvIiwiL28vIiwiL3UvIikKCiMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgaGFsZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1heCBvZiB0aGUgZml0IGFuZCB0aGUgdXBwZXIgbGltaXQKbWF4X3VsID0gbWF4KHAxJGZ2JHVsLCBwMiRmdiR1bCwgcDMkZnYkdWwsIHA0JGZ2JHVsLCBwNSRmdiR1bCkKbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCkKbWF4aW11bT1tYXhfZml0KygobWF4X3VsLW1heF9maXQpLzIpCnJtKG1heF91bCwgbWF4X2ZpdCkKCiMgcGxvdCBpbiBwb2xhciBjb29yZGluYXRlcyB3aXRoIGNvbmZpZGVuY2UgYm91bmRzCnBsb3QxPXBsb3RfbHkodHlwZT0nc2NhdHRlcnBvbGFyJywgbW9kZT0nbGluZXMnKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxXSwgd2lkdGg9Mi41KSwKICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMV0pICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzJdLCB3aWR0aD0yLjUpLCAKICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIHdpZHRoPTIuNSksIAogICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1szXSkgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRsbCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgd2lkdGg9Mi41KSwgCiAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzRdKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzVdLCB3aWR0aD0yLjUpLCAKICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbNV0pICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQogIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKICAgICAgICAgdGl0bGU9IkFsbCB2b3dlbHMgcHJvZHVjZWQgYnkgVG9uZ2FuIHNwZWFrZXJzIiwKICAgICAgICAgbGVnZW5kPWxpc3Qob3JpZW50YXRpb249ImgiLCB4YW5jaG9yPSJjZW50ZXIiLCB4PTAuNSx5PTAuMDEyKSkKcGxvdDEKCiMgIyBzZXQgUmhvIG1heCB0byB0aGUgbWF4IG9mIHRoZSBmaXQgKyA1CiMgbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCkKIyBtYXhpbXVtPW1heF9maXQrNQojIHJtKG1heF9maXQpCiMgCiMgIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGggY29uZmlkZW5jZSBib3VuZHMKIyBwbG90Mj1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lIAojICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxXSwgd2lkdGg9Mi41KSwKIyAgICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1sxXSkgJT4lIAojICAgYWRkX3RyYWNlKHRoZXRhPXAyJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAyJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1syXSwgd2lkdGg9Mi41KSwgCiMgICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JSAKIyAgIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIHdpZHRoPTIuNSksIAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUgCiMgICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCB3aWR0aD0yLjUpLCAKIyAgICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1s0XSkgJT4lIAojICAgYWRkX3RyYWNlKHRoZXRhPXA1JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA1JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s1XSwgd2lkdGg9Mi41KSwgCiMgICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbNV0pICU+JSAKIyAgIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKIyAgICAgICAgICAgICAgICAgICAgIGFuZ3VsYXJheGlzPWxpc3QodGhldGF1bml0PSdyYWRpYW5zJywgZGlyZWN0aW9uPSJjbG9ja3dpc2UiLCByb3RhdGlvbj0wKSksIAojICAgICAgICAgIHRpdGxlPSJBbGwgdm93ZWxzIHByb2R1Y2VkIGJ5IFRvbmdhbiBzcGVha2VycyIsCiMgICAgICAgICAgbGVnZW5kPWxpc3Qob3JpZW50YXRpb249ImgiLCB4YW5jaG9yPSJjZW50ZXIiLCB4PTAuNSkpCiMgcGxvdDIKaWYocHJpbnRQREY9PVRSVUUpCnsKCiAgb3JjYShwbG90MSwgIkZpZ3VyZTgoYSkucGRmIixmb3JtYXQ9InBkZiIpCiAgb3JjYShwbG90MSwgIkZpZ3VyZTgoYSkuanBnIixmb3JtYXQ9ImpwZWciKQp9CiAgCnJtKHAxLHAyLHAzLHA0LHA1KQpgYGAKCiMjIyBBbGwgVG9uZ2FuIG5vdGVzCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KIyB1c2UgY29sb3JzIGZyb20gUGhEIHRoZXNpcyAobG9hZGVkIGFib3ZlKQpjb2xvcnMgPSBjKGJsYWNrLCBibGFjaywgYmxhY2ssIGJsYWNrLCBibGFjaykKCnAxPXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iQmIyIiksIHJtLnJhbmVmPVRSVUUpCnAyPXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iRjMiKSwgcm0ucmFuZWY9VFJVRSkKcDM9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJCYjMiKSwgcm0ucmFuZWY9VFJVRSkKcDQ9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJENCIpLCBybS5yYW5lZj1UUlVFKQpwNT1wbG90X3Ntb290aCh4PVRvbmdhbi5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkY0IiksIHJtLnJhbmVmPVRSVUUpCgpzbW9vdGhfbmFtZXM9YygiQmIyIiwiRjMiLCJCYjMiLCJENCIsIkY0IikKCiMgcGxvdCBpbiBwb2xhciBjb29yZGluYXRlcyB3aXRob3V0IGNvbmZpZGVuY2UgYm91bmRzCnA9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzFdLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1sxXSkgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1syXSkgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIGRhc2g9ImRvdCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXA0JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA0JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgZGFzaD0iZGFzaGRvdCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzRdKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXA1JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA1JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s1XSwgd2lkdGg9MSksIAogICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1s1XSkgJT4lIAogIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLCAKICAgICAgICAgdGl0bGU9IkFsbCBub3RlcyBwcm9kdWNlZCBieSBUb25nYW4gc3BlYWtlcnMiLAogICAgICAgICBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQpwCgppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocCwgIkZpZ3VyZTgoYikucGRmIixmb3JtYXQ9InBkZiIpCiAgb3JjYShwLCAiRmlndXJlOChiKS5qcGciLGZvcm1hdD0ianBlZyIpCn0KICAKcm0ocDEscDIscDMscDQscDUpCmBgYAoKCiMjIEZpZ3VyZSA5IC0+IEgyIHNlbGVjdGVkIHZvd2VscyB3aXRoIG5vdGVzCgojIyMgd2l0aCBOWkUgbm90ZXMKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpjb2xvcnMgPSBjKGJsYWNrLCBibGFjaywgYmxhY2ssIGJsYWNrLCBibGFjayxCUk9XTjAsIEdSQVkwLCBQVVJQTEUwLCBwaW5rLCBHUkVFTjApCgojIHJ1biBwbG90X3Ntb290aCB0byBncmFiIHZhbHVlcyBmb3IgZml0LCB1cHBlciAmIGxvd2VyIGJvdW5kcwojIE5aRSBub3RlcwpwMT1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkJiMiIpLCBybS5yYW5lZj1UUlVFKQpwMj1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkYzIiksIHJtLnJhbmVmPVRSVUUpCnAzPXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iQmIzIiksIHJtLnJhbmVmPVRSVUUpCnA0PXBsb3Rfc21vb3RoKHg9TlpFLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iRDQiKSwgcm0ucmFuZWY9VFJVRSkKcDU9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJGNCIpLCBybS5yYW5lZj1UUlVFKQoKIyB2b3dlbHMKcDY9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSLJmSIpLCBybS5yYW5lZj1UUlVFKQpwNz1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmZIyIpLCBybS5yYW5lZj1UUlVFKQpwOD1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmSIiksIHJtLnJhbmVmPVRSVUUpCnA5PXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0ibyIpLCBybS5yYW5lZj1UUlVFKQpwMTA9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJ1IiksIHJtLnJhbmVmPVRSVUUpCgpzbW9vdGhfbmFtZXM9YygiQmIyIE5aRSIsIkYzIE5aRSIsIkJiMyBOWkUiLCJENCBOWkUiLCJGNCBOWkUiLCJub24tZmluYWwgc2Nod2EgL8mZLyBOWkUiLCJmaW5hbCBzY2h3YSAvyZkjLyBOWkUiLCJMT1QgL8mSLyBOWkUiLCIvby8gVG9uZ2FuIiwiL3UvIFRvbmdhbiIpCgojIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIDUKbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCwgcDYkZnYkZml0LCBwNyRmdiRmaXQsIHA4JGZ2JGZpdCwgcDkkZnYkZml0LCBwMTAkZnYkZml0KQptYXhpbXVtPW1heF9maXQrNQpybShtYXhfZml0KQoKIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGhvdXQgY29uZmlkZW5jZSBib3VuZHMKcGxvdDI9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzFdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzJdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIGRhc2g9ImRvdCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkYXNoZG90Iiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIHdpZHRoPTEpLCBuYW1lPXNtb290aF9uYW1lc1s1XSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXA2JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA2JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s2XSwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbN10sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzddKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDgkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDgkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbOF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wOSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzldKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDEwJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMCRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTBdLCB3aWR0aD0yLjUpLApuYW1lPXNtb290aF9uYW1lc1sxMF0pICU+JQogIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLAogICAgICAgICB0aXRsZT0iVG9uZ2FuICYgTlpFIHZvd2VscyBjbG9zZXN0IHRvIHBsYXlpbmcgcG9zaXRpb24gd2l0aCBOWkUgbm90ZXMiLGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAwOCkpCnBsb3QyCgppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocGxvdDIsICJGaWd1cmU5KGEpLnBkZiIsZm9ybWF0PSJwZGYiKQogIG9yY2EocGxvdDIsICJGaWd1cmU5KGEpLmpwZWciLGZvcm1hdD0ianBlZyIpCn0KCnJtKHAxLHAyLHAzLHA0LHA1LHA2LHA3LHA4LHA5LHAxMCkKYGBgCgojIyMgd2l0aCBUb25nYW4gbm90ZXMKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpjb2xvcnMgPSBjKGJsYWNrLCBibGFjaywgYmxhY2ssIGJsYWNrLCBibGFjayxCUk9XTjAsIEdSQVkwLCBQVVJQTEUwLCBwaW5rLCBHUkVFTjApCgojIHJ1biBwbG90X3Ntb290aCB0byBncmFiIHZhbHVlcyBmb3IgZml0LCB1cHBlciAmIGxvd2VyIGJvdW5kcwojIFRvbmdhbiBub3RlcwpwMT1wbG90X3Ntb290aCh4PVRvbmdhbi5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkJiMiIpLCBybS5yYW5lZj1UUlVFKQpwMj1wbG90X3Ntb290aCh4PVRvbmdhbi5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IkYzIiksIHJtLnJhbmVmPVRSVUUpCnAzPXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iQmIzIiksIHJtLnJhbmVmPVRSVUUpCnA0PXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0iRDQiKSwgcm0ucmFuZWY9VFJVRSkKcDU9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJGNCIpLCBybS5yYW5lZj1UUlVFKQoKIyB2b3dlbHMKcDY9cGxvdF9zbW9vdGgoeD1OWkUuZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSLJmSIpLCBybS5yYW5lZj1UUlVFKQpwNz1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmZIyIpLCBybS5yYW5lZj1UUlVFKQpwOD1wbG90X3Ntb290aCh4PU5aRS5nYW0uQVIuTW9kMiwgdmlldz0idGhldGFfdW5jdXRfeiIsIGNvbmQ9bGlzdCh0b2tlblBvb2xlZC5vcmQ9IsmSIiksIHJtLnJhbmVmPVRSVUUpCnA5PXBsb3Rfc21vb3RoKHg9VG9uZ2FuLmdhbS5BUi5Nb2QyLCB2aWV3PSJ0aGV0YV91bmN1dF96IiwgY29uZD1saXN0KHRva2VuUG9vbGVkLm9yZD0ibyIpLCBybS5yYW5lZj1UUlVFKQpwMTA9cGxvdF9zbW9vdGgoeD1Ub25nYW4uZ2FtLkFSLk1vZDIsIHZpZXc9InRoZXRhX3VuY3V0X3oiLCBjb25kPWxpc3QodG9rZW5Qb29sZWQub3JkPSJ1IiksIHJtLnJhbmVmPVRSVUUpCgpzbW9vdGhfbmFtZXM9YygiQmIyIFRvbmdhbiIsIkYzIFRvbmdhbiIsIkJiMyBUb25nYW4iLCJENCBUb25nYW4iLCJGNCBUb25nYW4iLCJub24tZmluYWwgc2Nod2EgL8mZLyBOWkUiLCJmaW5hbCBzY2h3YSAvyZkjLyBOWkUiLCJMT1QgL8mSLyBOWkUiLCIvby8gVG9uZ2FuIiwiL3UvIFRvbmdhbiIpCgojICMgc2V0IFJobyBtYXggdG8gdGhlIG1heCBvZiB0aGUgZml0ICsgNQojIG1heF9maXQgPSBtYXgocDEkZnYkZml0LCBwMiRmdiRmaXQsIHAzJGZ2JGZpdCwgcDQkZnYkZml0LCBwNSRmdiRmaXQsIHA2JGZ2JGZpdCwgcDckZnYkZml0LCBwOCRmdiRmaXQsIHA5JGZ2JGZpdCwgcDEwJGZ2JGZpdCkKIyBtYXhpbXVtPW1heF9maXQrNQojIHJtKG1heF9maXQpCiMgCiMgIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGggY29uZmlkZW5jZSBib3VuZHMKIyBwbG90MT1wbG90X2x5KHR5cGU9J3NjYXR0ZXJwb2xhcicsIG1vZGU9J2xpbmVzJykgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzFdLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1sxXSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAxJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzFdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzJdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1syXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAzJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAzJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZGFzaCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1szXSwgZGFzaD0iZGFzaCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXAzJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAzJGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzNdLCBkYXNoPSJkYXNoIiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCB3aWR0aD0yLjUpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzRdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNCRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNCRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNF0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA1JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA1JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s1XSwgd2lkdGg9Mi41KSwKIyAgICAgICAgICAgICBuYW1lPXNtb290aF9uYW1lc1s1XSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDUkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDUkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA1JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA1JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzVdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNiRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNl0sIHdpZHRoPTEpLAojICAgICAgICAgICAgIG5hbWU9c21vb3RoX25hbWVzWzZdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNiRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNiRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s2XSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDYkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDYkZnYkbGwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNl0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA3JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA3JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s3XSwgZGFzaD0iZGFzaGRvdCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzddKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wNyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNyRmdiR1bCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s3XSwgZGFzaD0iZGFzaGRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA3JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA3JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzddLCBkYXNoPSJkYXNoZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDgkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDgkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkb3QiLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1s4XSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDgkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDgkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOF0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA4JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA4JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wOSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIGRhc2g9ImRhc2giLCB3aWR0aD0yLjUpLCBuYW1lPXNtb290aF9uYW1lc1s5XSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDkkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDkkZnYkdWwsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgYWRkX3RyYWNlKHRoZXRhPXA5JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA5JGZ2JGxsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzldLCBkYXNoPSJkb3QiLCB3aWR0aD0wLjUpLCBzaG93bGVnZW5kPUZBTFNFKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTAkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEwJGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMF0sIHdpZHRoPTIuNSksCiMgICAgICAgICAgICAgbmFtZT1zbW9vdGhfbmFtZXNbMTBdKSAlPiUKIyAgIGFkZF90cmFjZSh0aGV0YT1wMTAkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDEwJGZ2JHVsLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzEwXSwgZGFzaD0iZG90Iiwgd2lkdGg9MC41KSwgc2hvd2xlZ2VuZD1GQUxTRSkgJT4lCiMgICBhZGRfdHJhY2UodGhldGE9cDEwJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMCRmdiRsbCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxMF0sIGRhc2g9ImRvdCIsIHdpZHRoPTAuNSksIHNob3dsZWdlbmQ9RkFMU0UpICU+JQojICAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLAojICAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwKIyAgICAgICAgICB0aXRsZT0iVG9uZ2FuICYgTlpFIHZvd2VscyBjbG9zZXN0IHRvIHBsYXlpbmcgcG9zaXRpb24gd2l0aCBUb25nYW4gbm90ZXMiKQojIHBsb3QxCgojIHNldCBSaG8gbWF4IHRvIHRoZSBtYXggb2YgdGhlIGZpdCArIDUKbWF4X2ZpdCA9IG1heChwMSRmdiRmaXQsIHAyJGZ2JGZpdCwgcDMkZnYkZml0LCBwNCRmdiRmaXQsIHA1JGZ2JGZpdCwgcDYkZnYkZml0LCBwNyRmdiRmaXQsIHA4JGZ2JGZpdCwgcDkkZnYkZml0LCBwMTAkZnYkZml0KQptYXhpbXVtPW1heF9maXQrNQpybShtYXhfZml0KQoKIyBwbG90IGluIHBvbGFyIGNvb3JkaW5hdGVzIHdpdGhvdXQgY29uZmlkZW5jZSBib3VuZHMKcGxvdDI9cGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMV0sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzFdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDIkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDIkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzJdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbMl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wMyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wMyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbM10sIGRhc2g9ImRvdCIsIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzNdKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDQkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDQkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzRdLCBkYXNoPSJkYXNoZG90Iiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIHdpZHRoPTEpLCBuYW1lPXNtb290aF9uYW1lc1s1XSkgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXA2JGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXA2JGZ2JGZpdCwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s2XSwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbNl0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wNyRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wNyRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbN10sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzddKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDgkZnYkdGhldGFfdW5jdXRfeioxODAvcGksIHI9cDgkZnYkZml0LCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzhdLCBkYXNoPSJkYXNoIiwgd2lkdGg9Mi41KSwgbmFtZT1zbW9vdGhfbmFtZXNbOF0pICU+JQogIGFkZF90cmFjZSh0aGV0YT1wOSRmdiR0aGV0YV91bmN1dF96KjE4MC9waSwgcj1wOSRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOV0sIHdpZHRoPTIuNSksIG5hbWU9c21vb3RoX25hbWVzWzldKSAlPiUKICBhZGRfdHJhY2UodGhldGE9cDEwJGZ2JHRoZXRhX3VuY3V0X3oqMTgwL3BpLCByPXAxMCRmdiRmaXQsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMTBdLCB3aWR0aD0yLjUpLApuYW1lPXNtb290aF9uYW1lc1sxMF0pICU+JQogIGxheW91dChwb2xhcj1saXN0KHNlY3Rvcj1jKDIwLDE2MCksIHJhZGlhbGF4aXM9bGlzdChhbmdsZT05MCwgcmFuZ2U9YygwLG1heGltdW0pKSwKICAgICAgICAgICAgICAgICAgICBhbmd1bGFyYXhpcz1saXN0KHRoZXRhdW5pdD0ncmFkaWFucycsIGRpcmVjdGlvbj0iY2xvY2t3aXNlIiwgcm90YXRpb249MCkpLAogICAgICAgICB0aXRsZT0iVG9uZ2FuICYgTlpFIHZvd2VscyBjbG9zZXN0IHRvIHBsYXlpbmcgcG9zaXRpb24gd2l0aCBUb25nYW4gbm90ZXMiLGxlZ2VuZD1saXN0KG9yaWVudGF0aW9uPSJoIiwgeGFuY2hvcj0iY2VudGVyIiwgeD0wLjUseT0wLjAxMikpCnBsb3QyCgppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocGxvdDIsICJGaWd1cmU5KGIpLnBkZiIsZm9ybWF0PSJwZGYiKQogIG9yY2EocGxvdDIsICJGaWd1cmU5KGIpLmpwZWciLGZvcm1hdD0ianBlZyIpCn0KICAKcm0ocDEscDIscDMscDQscDUscDYscDcscDgscDkscDEwKQpgYGAKCgojIyBGaWd1cmUgMTAgJ2NhcmRpbmFsIHZvd2VscycgLT4gdXBkYXRlZCB2ZXJzaW9uIHVzaW5nIG9ubHkgdm93ZWxzIHN1cnJvdW5kZWQgYnkgY29yb25hbHMKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQojIGNyZWF0ZSBkZk5aRSAmIGRmVG9uZ2FuIC0+IGRmIGFscmVhZHkgbG9hZGVkIGFuZCBtYW5pcHVsYXRlZCBhYm92ZQpkZk5aRSA8LSBzdWJzZXQoZGYsZGYkbmF0aXZlX2xnPT0iTlpFIikKZGZOWkUkdG9rZW5Qb29sZWQgPC0gZmFjdG9yKGRmTlpFJHRva2VuUG9vbGVkLCBsZXZlbHMgPSBjKCLJkMuQIiwiyZAiLCLJmyIsIsm1y5AiLCJlIiwiacuQIiwiyonLkCIsIsqKIiwib8uQIiwiyZIiLCLJmCIsIsmZIiwiyZkjIiwiQmIyIiwiRjMiLCJCYjMiLCJENCIsIkY0IikpCmRmTlpFJHBsYXlpbmdfcHJvZmljaWVuY3kgPC0gYXMuZmFjdG9yKGRmTlpFJHBsYXlpbmdfcHJvZmljaWVuY3kpCmRmTlpFJG5vdGVfaW50ZW5zaXR5W2lzLm5hKGRmTlpFJG5vdGVfaW50ZW5zaXR5KV0gPSAiTlVMTCIKZGZOWkUkc3ViVm93ZWxJbnQgPC0gaW50ZXJhY3Rpb24oZGZOWkUkc3ViamVjdCwgZGZOWkUkdG9rZW5Qb29sZWQpCmRmTlpFJHByZWNTb3VuZFZvd2VsSW50IDwtIGludGVyYWN0aW9uKGRmTlpFJHNwZWVjaF9wcmVjX3Bvb2xlZCwgZGZOWkUkdG9rZW5Qb29sZWQpCmRmTlpFJGZvbGxTb3VuZFZvd2VsSW50IDwtIGludGVyYWN0aW9uKGRmTlpFJHNwZWVjaF9mb2xfcG9vbGVkLCBkZk5aRSR0b2tlblBvb2xlZCkKZGZOWkUkdG9rZW5Qb29sZWQub3JkIDwtIGFzLm9yZGVyZWQoZGZOWkUkdG9rZW5Qb29sZWQpCmNvbnRyYXN0cyhkZk5aRSR0b2tlblBvb2xlZC5vcmQpIDwtICJjb250ci50cmVhdG1lbnQiCmRmTlpFJHZvd2Vsc19wb29sZWQub3JkIDwtIGFzLm9yZGVyZWQoZGZOWkUkdm93ZWxzX3Bvb2xlZCkKY29udHJhc3RzKGRmTlpFJHZvd2Vsc19wb29sZWQub3JkKSA8LSAiY29udHIudHJlYXRtZW50IgpkZk5aRSRwbGF5aW5nX3Byb2ZpY2llbmN5Lm9yZCA8LSBhcy5vcmRlcmVkKGRmTlpFJHBsYXlpbmdfcHJvZmljaWVuY3kpCmNvbnRyYXN0cyhkZk5aRSRwbGF5aW5nX3Byb2ZpY2llbmN5Lm9yZCkgPC0gImNvbnRyLnRyZWF0bWVudCIKZGZOWkUkc3RhcnQgPC0gZGZOWkUkcG9pbnRzPT0xCgpkZlRvbmdhbiA8LSBzdWJzZXQoZGYsZGYkbmF0aXZlX2xnPT0iVG9uZ2FuIikKZGZUb25nYW4kdG9rZW5Qb29sZWQgPC0gZmFjdG9yKGRmVG9uZ2FuJHRva2VuUG9vbGVkLCBsZXZlbHMgPSBjKCJhy5AiLCJhIiwiZcuQIiwiZSIsImnLkCIsImkiLCJ1y5AiLCJ1Iiwib8uQIiwibyIsIkJiMiIsIkYzIiwiQmIzIiwiRDQiLCJGNCIpKQpkZlRvbmdhbiR0b2tlblBvb2xlZFtkZlRvbmdhbiR0b2tlblBvb2xlZCA9PSAiYcuQIl0gPSAiYSIKZGZUb25nYW4kdG9rZW5Qb29sZWRbZGZUb25nYW4kdG9rZW5Qb29sZWQgPT0gImXLkCJdID0gImUiCmRmVG9uZ2FuJHRva2VuUG9vbGVkW2RmVG9uZ2FuJHRva2VuUG9vbGVkID09ICJpy5AiXSA9ICJpIgpkZlRvbmdhbiR0b2tlblBvb2xlZFtkZlRvbmdhbiR0b2tlblBvb2xlZCA9PSAidcuQIl0gPSAidSIKZGZUb25nYW4kdG9rZW5Qb29sZWRbZGZUb25nYW4kdG9rZW5Qb29sZWQgPT0gIm/LkCJdID0gIm8iCmRmVG9uZ2FuJHRva2VuUG9vbGVkIDwtIGZhY3RvcihkZlRvbmdhbiR0b2tlblBvb2xlZCkKZGZUb25nYW4kcGxheWluZ19wcm9maWNpZW5jeSA8LSBhcy5mYWN0b3IoZGZUb25nYW4kcGxheWluZ19wcm9maWNpZW5jeSkKZGZUb25nYW4kc3BlZWNoX3ByZWNfcG9vbGVkW2lzLm5hKGRmVG9uZ2FuJHNwZWVjaF9wcmVjX3Bvb2xlZCldID0gIk5VTEwiCmRmVG9uZ2FuJHNwZWVjaF9mb2xfcG9vbGVkW2lzLm5hKGRmVG9uZ2FuJHNwZWVjaF9mb2xfcG9vbGVkKV0gPSAiTlVMTCIKZGZUb25nYW4kc3ViVm93ZWxJbnQgPC0gaW50ZXJhY3Rpb24oZGZUb25nYW4kc3ViamVjdCwgZGZUb25nYW4kdG9rZW5Qb29sZWQpCmRmVG9uZ2FuJHByZWNTb3VuZFZvd2VsSW50IDwtIGludGVyYWN0aW9uKGRmVG9uZ2FuJHNwZWVjaF9wcmVjX3Bvb2xlZCwgZGZUb25nYW4kdG9rZW5Qb29sZWQpCmRmVG9uZ2FuJGZvbGxTb3VuZFZvd2VsSW50IDwtIGludGVyYWN0aW9uKGRmVG9uZ2FuJHNwZWVjaF9mb2xfcG9vbGVkLCBkZlRvbmdhbiR0b2tlblBvb2xlZCkKZGZUb25nYW4kdG9rZW5Qb29sZWQub3JkIDwtIGFzLm9yZGVyZWQoZGZUb25nYW4kdG9rZW5Qb29sZWQpCmNvbnRyYXN0cyhkZlRvbmdhbiR0b2tlblBvb2xlZC5vcmQpIDwtICJjb250ci50cmVhdG1lbnQiCmRmVG9uZ2FuJHZvd2Vsc19wb29sZWQub3JkIDwtIGFzLm9yZGVyZWQoZGZUb25nYW4kdm93ZWxzX3Bvb2xlZCkKY29udHJhc3RzKGRmVG9uZ2FuJHZvd2Vsc19wb29sZWQub3JkKSA8LSAiY29udHIudHJlYXRtZW50IgpkZlRvbmdhbiRwbGF5aW5nX3Byb2ZpY2llbmN5Lm9yZCA8LSBhcy5vcmRlcmVkKGRmVG9uZ2FuJHBsYXlpbmdfcHJvZmljaWVuY3kpCmNvbnRyYXN0cyhkZlRvbmdhbiRwbGF5aW5nX3Byb2ZpY2llbmN5Lm9yZCkgPC0gImNvbnRyLnRyZWF0bWVudCIKZGZUb25nYW4kc3RhcnQgPC0gZGZUb25nYW4kcG9pbnRzPT0xCgojICMgaW5zcGVjdCB2b3dlbCB0b2tlbiBudW1iZXJzIGluIGRpZmZlcmVudCBwcmVjZWRpbmcgYW5kIGZvbGxvd2luZyBjb250ZXh0cwojIGNhdCgiXG5kZk5aRSRzcGVlY2hfcHJlY19wb29sZWRcbiIpCiMgdGFibGUoZGZOWkUkc3BlZWNoX3ByZWNfcG9vbGVkKQojIGNhdCgiXG5kZk5aRSRzcGVlY2hfZm9sX3Bvb2xlZFxuIikKIyB0YWJsZShkZk5aRSRzcGVlY2hfZm9sX3Bvb2xlZCkKIyBjYXQoIlxuZGZUb25nYW4kc3BlZWNoX3ByZWNfcG9vbGVkXG4iKQojIHRhYmxlKGRmVG9uZ2FuJHNwZWVjaF9wcmVjX3Bvb2xlZCkKIyBjYXQoIlxuZGZOWkUkc3BlZWNoX2ZvbF9wb29sZWRcbiIpCiMgdGFibGUoZGZUb25nYW4kc3BlZWNoX2ZvbF9wb29sZWQpCgojIG1ha2UgY29waWVzIG9mIGRmTlpFIGFuZCBkZlRvbmdhbgpkYXRfTlpFID0gZGZOWkUKZGF0X1RvbmdhbiA9IGRmVG9uZ2FuCgojIHByZWRpY3QgdmFsdWVzIGZyb20gbW9kZWxzCmRhdF9OWkUkcHJlZGljdGVkX3ZhbHVlcyA9IHByZWRpY3QoTlpFLmdhbS5BUi5Nb2QyKQpkYXRfVG9uZ2FuJHByZWRpY3RlZF92YWx1ZXMgPSBwcmVkaWN0KFRvbmdhbi5nYW0uQVIuTW9kMikKCiMgY3JlYXRlIG5ldyBkYXRhLmZyYW1lcwpOWkVfRkxFRUNFID0gZGF0X05aRVtkYXRfTlpFJHRva2VuUG9vbGVkID09ICJpy5AiICYgZGF0X05aRSRzcGVlY2hfcHJlY19wb29sZWQgPT0gImNvcm9uYWxzIiAmIGRhdF9OWkUkc3BlZWNoX2ZvbF9wb29sZWQgPT0gImNvcm9uYWxzIixdClRvbmdhbl9pID0gZGF0X1RvbmdhbltkYXRfVG9uZ2FuJHRva2VuUG9vbGVkID09ICJpIiAmIGRhdF9Ub25nYW4kc3BlZWNoX3ByZWNfcG9vbGVkID09ICJjb3JvbmFscyIgJiBkYXRfVG9uZ2FuJHNwZWVjaF9mb2xfcG9vbGVkID09ICJjb3JvbmFscyIsXQoKTlpFX0RSRVNTID0gZGF0X05aRVtkYXRfTlpFJHRva2VuUG9vbGVkID09ICJlIiAmIGRhdF9OWkUkc3BlZWNoX3ByZWNfcG9vbGVkID09ICJjb3JvbmFscyIgJiBkYXRfTlpFJHNwZWVjaF9mb2xfcG9vbGVkID09ICJjb3JvbmFscyIsXQpUb25nYW5fZSA9IGRhdF9Ub25nYW5bZGF0X1RvbmdhbiR0b2tlblBvb2xlZCA9PSAiZSIgJiBkYXRfVG9uZ2FuJHNwZWVjaF9wcmVjX3Bvb2xlZCA9PSAiY29yb25hbHMiICYgZGF0X1RvbmdhbiRzcGVlY2hfZm9sX3Bvb2xlZCA9PSAiY29yb25hbHMiLF0KCk5aRV9TVEFSVCA9IGRhdF9OWkVbZGF0X05aRSR0b2tlblBvb2xlZCA9PSAiyZDLkCIgJiBkYXRfTlpFJHNwZWVjaF9wcmVjX3Bvb2xlZCA9PSAiY29yb25hbHMiICYgZGF0X05aRSRzcGVlY2hfZm9sX3Bvb2xlZCA9PSAiY29yb25hbHMiLF0KVG9uZ2FuX2EgPSBkYXRfVG9uZ2FuW2RhdF9Ub25nYW4kdG9rZW5Qb29sZWQgPT0gImEiICYgZGF0X1RvbmdhbiRzcGVlY2hfcHJlY19wb29sZWQgPT0gImNvcm9uYWxzIiAmIGRhdF9Ub25nYW4kc3BlZWNoX2ZvbF9wb29sZWQgPT0gImNvcm9uYWxzIixdCgpOWkVfVEhPVUdIVCA9IGRhdF9OWkVbZGF0X05aRSR0b2tlblBvb2xlZCA9PSAib8uQIiAmIGRhdF9OWkUkc3BlZWNoX3ByZWNfcG9vbGVkID09ICJjb3JvbmFscyIgJiBkYXRfTlpFJHNwZWVjaF9mb2xfcG9vbGVkID09ICJjb3JvbmFscyIsXQpUb25nYW5fbyA9IGRhdF9Ub25nYW5bZGF0X1RvbmdhbiR0b2tlblBvb2xlZCA9PSAibyIgJiBkYXRfVG9uZ2FuJHNwZWVjaF9wcmVjX3Bvb2xlZCA9PSAiY29yb25hbHMiICYgZGF0X1RvbmdhbiRzcGVlY2hfZm9sX3Bvb2xlZCA9PSAiY29yb25hbHMiLF0KCiMgZXN0aW1hdGUgc21vb3RocyB1c2luZyBSJ3MgZ2VuZXJpYyBwcmVkaWN0LnNtb290aC5zcGxpbmUgZnVuY3Rpb24Kc21vb3RoX05aRV9GTEVFQ0U9bGlzdCh0aGV0YT1zZXEobWluKE5aRV9GTEVFQ0UkdGhldGFfdW5jdXRfeikqMTgwL3BpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KE5aRV9GTEVFQ0UkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoTlpFX0ZMRUVDRSR0aGV0YV91bmN1dF96LCBOWkVfRkxFRUNFJHByZWRpY3RlZF92YWx1ZXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxKG1pbihOWkVfRkxFRUNFJHRoZXRhX3VuY3V0X3opLCBtYXgoTlpFX0ZMRUVDRSR0aGV0YV91bmN1dF96KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg9MTAwKSkkeSwgbGluZT1saXN0KGNvbG9yPSJPUkFOR0UwIiwgZGFzaD0iZGFzaCIpKQpzbW9vdGhfVG9uZ2FuX2k9bGlzdCh0aGV0YT1zZXEobWluKFRvbmdhbl9pJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoVG9uZ2FuX2kkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgCiAgICAgICAgICAgICAgICAgICAgIHI9cHJlZGljdChzbW9vdGguc3BsaW5lKFRvbmdhbl9pJHRoZXRhX3VuY3V0X3osIFRvbmdhbl9pJHByZWRpY3RlZF92YWx1ZXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcShtaW4oVG9uZ2FuX2kkdGhldGFfdW5jdXRfeiksIG1heChUb25nYW5faSR0aGV0YV91bmN1dF96KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoPTEwMCkpJHksIGxpbmU9bGlzdChjb2xvcj0iT1JBTkdFMCIsIGRhc2g9IiIpKQoKc21vb3RoX05aRV9EUkVTUz1saXN0KHRoZXRhPXNlcShtaW4oTlpFX0RSRVNTJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChOWkVfRFJFU1MkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoTlpFX0RSRVNTJHRoZXRhX3VuY3V0X3osIE5aRV9EUkVTUyRwcmVkaWN0ZWRfdmFsdWVzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcShtaW4oTlpFX0RSRVNTJHRoZXRhX3VuY3V0X3opLCBtYXgoTlpFX0RSRVNTJHRoZXRhX3VuY3V0X3opLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aD0xMDApKSR5LCBsaW5lPWxpc3QoY29sb3I9ImRhcmtfYmx1ZSIsIGRhc2g9ImRhc2giKSkKc21vb3RoX1Rvbmdhbl9lPWxpc3QodGhldGE9c2VxKG1pbihUb25nYW5fZSR0aGV0YV91bmN1dF96KSoxODAvcGksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KFRvbmdhbl9lJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgbGVuZ3RoPTEwMCksIAogICAgICAgICAgICAgICAgICAgICByPXByZWRpY3Qoc21vb3RoLnNwbGluZShUb25nYW5fZSR0aGV0YV91bmN1dF96LCBUb25nYW5fZSRwcmVkaWN0ZWRfdmFsdWVzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXEobWluKFRvbmdhbl9lJHRoZXRhX3VuY3V0X3opLCBtYXgoVG9uZ2FuX2UkdGhldGFfdW5jdXRfeiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aD0xMDApKSR5LCBsaW5lPWxpc3QoY29sb3I9ImRhcmtfYmx1ZSIsIGRhc2g9IiIpKQoKc21vb3RoX05aRV9TVEFSVD1saXN0KHRoZXRhPXNlcShtaW4oTlpFX1NUQVJUJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChOWkVfU1RBUlQkdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoTlpFX1NUQVJUJHRoZXRhX3VuY3V0X3osIE5aRV9TVEFSVCRwcmVkaWN0ZWRfdmFsdWVzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcShtaW4oTlpFX1NUQVJUJHRoZXRhX3VuY3V0X3opLCBtYXgoTlpFX1NUQVJUJHRoZXRhX3VuY3V0X3opLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aD0xMDApKSR5LCBsaW5lPWxpc3QoY29sb3I9IlJFRDAiLCBkYXNoPSJkYXNoIikpCnNtb290aF9Ub25nYW5fYT1saXN0KHRoZXRhPXNlcShtaW4oVG9uZ2FuX2EkdGhldGFfdW5jdXRfeikqMTgwL3BpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChUb25nYW5fYSR0aGV0YV91bmN1dF96KSoxODAvcGksIGxlbmd0aD0xMDApLCAKICAgICAgICAgICAgICAgICAgICAgcj1wcmVkaWN0KHNtb290aC5zcGxpbmUoVG9uZ2FuX2EkdGhldGFfdW5jdXRfeiwgVG9uZ2FuX2EkcHJlZGljdGVkX3ZhbHVlcyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxKG1pbihUb25nYW5fYSR0aGV0YV91bmN1dF96KSwgbWF4KFRvbmdhbl9hJHRoZXRhX3VuY3V0X3opLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg9MTAwKSkkeSwgbGluZT1saXN0KGNvbG9yPSJSRUQwIiwgZGFzaD0iIikpCgpzbW9vdGhfTlpFX1RIT1VHSFQ9bGlzdCh0aGV0YT1zZXEobWluKE5aRV9USE9VR0hUJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChOWkVfVEhPVUdIVCR0aGV0YV91bmN1dF96KSoxODAvcGksIGxlbmd0aD0xMDApLCAKICAgICAgICAgICAgICAgICAgICAgICByPXByZWRpY3Qoc21vb3RoLnNwbGluZShOWkVfVEhPVUdIVCR0aGV0YV91bmN1dF96LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOWkVfVEhPVUdIVCRwcmVkaWN0ZWRfdmFsdWVzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcShtaW4oTlpFX1RIT1VHSFQkdGhldGFfdW5jdXRfeiksIG1heChOWkVfVEhPVUdIVCR0aGV0YV91bmN1dF96KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg9MTAwKSkkeSwgbGluZT1saXN0KGNvbG9yPSJwaW5rIiwgZGFzaD0iZGFzaCIpKQpzbW9vdGhfVG9uZ2FuX289bGlzdCh0aGV0YT1zZXEobWluKFRvbmdhbl9vJHRoZXRhX3VuY3V0X3opKjE4MC9waSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgoVG9uZ2FuX28kdGhldGFfdW5jdXRfeikqMTgwL3BpLCBsZW5ndGg9MTAwKSwgCiAgICAgICAgICAgICAgICAgICAgIHI9cHJlZGljdChzbW9vdGguc3BsaW5lKFRvbmdhbl9vJHRoZXRhX3VuY3V0X3osIFRvbmdhbl9vJHByZWRpY3RlZF92YWx1ZXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcShtaW4oVG9uZ2FuX28kdGhldGFfdW5jdXRfeiksIG1heChUb25nYW5fbyR0aGV0YV91bmN1dF96KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoPTEwMCkpJHksIGxpbmU9bGlzdChjb2xvcj0icGluayIsIGRhc2g9IiIpKQoKIyBzZXQgUmhvIG1heCB0byB0aGUgbWF4IG9mIHRoZSBwcmVkaWN0ZWRfdmFsdWVzICsgNQptYXhfcHJlZGljdGlvbnMgPSBtYXgobWF4KHNtb290aF9OWkVfRkxFRUNFJHIpLCBtYXgoc21vb3RoX05aRV9EUkVTUyRyKSwgbWF4KHNtb290aF9OWkVfU1RBUlQkciksIAogICAgICAgICAgICAgICAgICAgICAgbWF4KHNtb290aF9OWkVfVEhPVUdIVCRyKSwgbWF4KHNtb290aF9Ub25nYW5faSRyKSwgbWF4KHNtb290aF9Ub25nYW5fZSRyKSwgCiAgICAgICAgICAgICAgICAgICAgICBtYXgoc21vb3RoX1Rvbmdhbl9hJHIpLCBtYXgoc21vb3RoX1Rvbmdhbl9vJHIpKQptYXhpbXVtPW1heF9wcmVkaWN0aW9ucys1CnJtKG1heF9wcmVkaWN0aW9ucykKCiMgY29sb3JzIGZyb20gc21vb3RocyBkb24ndCBnZXQgcGFzc2VkIG9uIGNvcnJlY3RseSAtPiBzcGVjaWZ5IGFnYWluCmNvbG9ycyA9IGMoT1JBTkdFMCwgT1JBTkdFMCwgZGFya19ibHVlLCBkYXJrX2JsdWUsIFJFRDAsIFJFRDAsIHBpbmssIHBpbmspCgpwID0gcGxvdF9seSh0eXBlPSdzY2F0dGVycG9sYXInLCBtb2RlPSdsaW5lcycpICU+JSAKICBhZGRfdHJhY2UodGhldGE9c21vb3RoX05aRV9GTEVFQ0UkdGhldGEsIHI9c21vb3RoX05aRV9GTEVFQ0UkciwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1sxXSwgd2lkdGg9Mi41LGRhc2g9c21vb3RoX05aRV9GTEVFQ0UkbGluZSRkYXNoW1sxXV0pLCBuYW1lPSJGTEVFQ0UgL2nLkC8gTlpFIikgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1zbW9vdGhfVG9uZ2FuX2kkdGhldGEsIHI9c21vb3RoX1Rvbmdhbl9pJHIsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbMl0sIHdpZHRoPTIuNSwgZGFzaD1zbW9vdGhfVG9uZ2FuX2kkbGluZSRkYXNoW1sxXV0pLCBuYW1lPSIvaS8gVG9uZ2FuIikgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXNtb290aF9OWkVfRFJFU1MkdGhldGEsIHI9c21vb3RoX05aRV9EUkVTUyRyLCBsaW5lPWxpc3QoY29sb3I9Y29sb3JzWzNdLCB3aWR0aD0yLjUsIGRhc2g9c21vb3RoX05aRV9EUkVTUyRsaW5lJGRhc2hbWzFdXSksIG5hbWU9IkRSRVNTIC9lLyBOWkUiKSAlPiUgCiAgYWRkX3RyYWNlKHRoZXRhPXNtb290aF9Ub25nYW5fZSR0aGV0YSwgcj1zbW9vdGhfVG9uZ2FuX2UkciwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s0XSwgd2lkdGg9Mi41LCBkYXNoPXNtb290aF9Ub25nYW5fZSRsaW5lJGRhc2hbWzFdXSksIG5hbWU9Ii9lLyBUb25nYW4iKSAlPiUKICBhZGRfdHJhY2UodGhldGE9c21vb3RoX05aRV9TVEFSVCR0aGV0YSwgcj1zbW9vdGhfTlpFX1NUQVJUJHIsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNV0sIHdpZHRoPTIuNSwgZGFzaD1zbW9vdGhfTlpFX1NUQVJUJGxpbmUkZGFzaFtbMV1dKSwgbmFtZT0iU1RBUlQgL2nLkC8gTlpFIikgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1zbW9vdGhfVG9uZ2FuX2EkdGhldGEsIHI9c21vb3RoX1Rvbmdhbl9hJHIsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbNl0sIHdpZHRoPTIuNSwgZGFzaD1zbW9vdGhfVG9uZ2FuX2EkbGluZSRkYXNoW1sxXV0pLCBuYW1lPSIvYS8gVG9uZ2FuIikgJT4lCiAgYWRkX3RyYWNlKHRoZXRhPXNtb290aF9OWkVfVEhPVUdIVCR0aGV0YSwgcj1zbW9vdGhfTlpFX1RIT1VHSFQkciwgbGluZT1saXN0KGNvbG9yPWNvbG9yc1s3XSwgd2lkdGg9Mi41LCBkYXNoPXNtb290aF9OWkVfVEhPVUdIVCRsaW5lJGRhc2hbWzFdXSksIG5hbWU9IlRIT1VHSFQgL2/LkC8gTlpFIikgJT4lIAogIGFkZF90cmFjZSh0aGV0YT1zbW9vdGhfVG9uZ2FuX28kdGhldGEsIHI9c21vb3RoX1Rvbmdhbl9vJHIsIGxpbmU9bGlzdChjb2xvcj1jb2xvcnNbOF0sIHdpZHRoPTIuNSwgZGFzaD1zbW9vdGhfVG9uZ2FuX28kbGluZSRkYXNoW1sxXV0pLCBuYW1lPSIvby8gVG9uZ2FuIikgJT4lCiAgbGF5b3V0KHBvbGFyPWxpc3Qoc2VjdG9yPWMoMjAsMTYwKSwgcmFkaWFsYXhpcz1saXN0KGFuZ2xlPTkwLCByYW5nZT1jKDAsbWF4aW11bSkpLCAgCiAgICAgICAgICAgICAgICAgICAgYW5ndWxhcmF4aXM9bGlzdCh0aGV0YXVuaXQ9J3JhZGlhbnMnLCBkaXJlY3Rpb249ImNsb2Nrd2lzZSIsIHJvdGF0aW9uPTApKSwgCiAgICAgICAgIHRpdGxlPSJUb25nYW4gJiBOWkUgJ2NhcmRpbmFsIHZvd2VscycgZmxhbmtlZCBieSBjb3JvbmFsIHNvdW5kcyIsIAogICAgICAgICBsZWdlbmQ9bGlzdChvcmllbnRhdGlvbj0iaCIsIHhhbmNob3I9ImNlbnRlciIsIHg9MC41LHk9MC4wMTIpKQpwCgppZihwcmludFBERj09VFJVRSkKewogIG9yY2EocCwgIkZpZ3VyZTEwLnBkZiIsZm9ybWF0PSJwZGYiKQogIG9yY2EocCwgIkZpZ3VyZTEwLmpwZyIsZm9ybWF0PSJqcGVnIikKfQoKcm0oZGF0X05aRSwgZGF0X1RvbmdhbiwgTlpFX0ZMRUVDRSwgTlpFX0RSRVNTLCBOWkVfU1RBUlQsIE5aRV9USE9VR0hULCBzbW9vdGhfTlpFX0ZMRUVDRSxzbW9vdGhfTlpFX0RSRVNTLCBzbW9vdGhfTlpFX1NUQVJULCBzbW9vdGhfTlpFX1RIT1VHSFQsIHNtb290aF9Ub25nYW5faSwgc21vb3RoX1Rvbmdhbl9lLCBzbW9vdGhfVG9uZ2FuX2EsIHNtb290aF9Ub25nYW5fbywgbWF4aW11bSkKYGBgCg==