1 Evaluate Previous Result: version: 20171205

1.1 Reading in the existing result

As per Yan’s suggestion, I am using the existing results, found in the file: “2017_0811BrikenMultiConsensus.xlsx”

Unfortunately, this table is in a particularly strange format: it is a triply nested table of tables of tables in one worksheet in Excel. At one level, this is a really novel and interesting use of Excel, but on every other level it is sub-optimal. The primary reason it is sub-optimal is that the column headings end up being repeated once for every new sub-table (874 of the inner tables plus however many middle tables), which makes it nearly unparseable.

I am displeased I need to do this level of data wrangling.

The following function is my first attempt at handling this parsing puzzle.

For the interested, the structure is:

  • all_protein_groups is a list of two elements: group_id => (“summary”, “data”)
  • for every protein group discovered, one of these two element lists is created.
    • The summary slot gets the one-row summary for the protein group from the excel.
  • The data slot is a list of groups: protein => (“summary”, “data”)
    • Once again, the summary is the single row from excel.
  • Again, the data slot is a list of peptides: peptide => data.frame(peptides)
    • Each peptide data frame contains all of the inner-most rows describing the observed peptides.
parse_difficult_excel <- function(xlsx_file, test_row=92150) {
  old_options <- options(java.parameters="-Xmx20G")
  message(paste0("Reading ", xlsx_file))
  result <- readxl::read_xlsx(path=xlsx_file, sheet=1, col_names=FALSE)
  message("Starting parse.")
  group_data <- list()
  bar <- utils::txtProgressBar(style=3)
  for (r in 1:nrow(result)) {
    row <- as.data.frame(result[r, ])
    row[, is.na(row)] <- ""
    pct_done <- r / nrow(result)
    setTxtProgressBar(bar, pct_done)
    ## The following 3 stanzas handle the creation of the levels of our data structure
    ## The first defines the protein group
    if (row[, 1] == "Checked") {
      group_colnames <- as.character(row)
      group_keepers <- !grepl(pattern="^$", x=group_colnames)
      group_keepers[1] <- FALSE
      group_colnames <- group_colnames[group_keepers]
      next
    }
    ## When the 2nd column is 'Checked', then this defines a new protein in the group.
    if (row[, 2] == "Checked") {
      protein_colnames <- as.character(row)
      protein_keepers <- !grepl(pattern="^$", x=protein_colnames)
      protein_keepers[2] <- FALSE
      protein_colnames <- protein_colnames[protein_keepers]
      next
    }
    ## When the 3rd column is 'Checked', then this starts a peptide definition
    if (row[, 3] == "Checked") {
      peptide_colnames <- as.character(row)
      peptide_keepers <- !grepl(pattern="^$", x=peptide_colnames)
      peptide_keepers[3] <- FALSE
      peptide_colnames <- peptide_colnames[peptide_keepers]
      next
    }
    ## Once the column names for the data are defined, we consider how to
    ## Fill in the actual data, the protein group is probably the least interesting.
    if (row[, 1] == FALSE | row[, 1] == TRUE) {
      group_information <- row[group_keepers]
      colnames(group_information) <- group_colnames
      group_information[["ID"]] <- sub(pattern="^.* GN=(\\w+) .*$",
                                       replacement="\\1",
                                       x=group_information[["Group Description"]])
      group_accession <- group_information[["Protein Group ID"]]
      group_list <- list(
        "summary" = group_information,
        "data" = list())
      group_data[[group_accession]] <- group_list
      next
    }
    ## When the 2nd column is FALSE, then this defined a protein in the group.
    ## The protein data structure is likely the most interesting.
    if (row[, 2] == FALSE | row[, 2] == TRUE) {
      protein_information <- row[protein_keepers]
      colnames(protein_information) <- protein_colnames
      protein_information[["ID"]] <- sub(pattern="^.* GN=(\\w+) .*$",
                                         replacement="\\1",
                                         x=protein_information[["Description"]])
      protein_accession <- protein_information[["Accession"]]
      protein_list <- list(
        "summary" = protein_information,
        "data" = data.frame())
      group_data[[group_accession]][["data"]][[protein_accession]] <- protein_list
      next
    }
    ## When the 3rd group is FALSE, then this adds a peptide.
    ## The peptide data structure is the most detailed, but probably not the most interesting.
    if (row[, 3] == FALSE | row[, 3] == TRUE) {
      peptide_information <- row[peptide_keepers]
      colnames(peptide_information) <- peptide_colnames
      current <- group_data[[group_accession]][["data"]][[protein_accession]][["data"]]
      new <- rbind(current, peptide_information)
      group_data[[group_accession]][["data"]][[protein_accession]][["data"]] <- new
      next
    }
  } ## End iterating over ever row of this unholy stupid data structure.
  close(bar)
  message("Finished parsing, reorganizing the protein data.")
  protein_df <- data.frame()
  peptide_df <- data.frame()
  protein_names <- c()
  message(paste0("Starting to iterate over ", length(group_data),  " groups."))
  bar <- utils::txtProgressBar(style=3)
  for (g in 1:length(group_data)) {
    pct_done <- g / length(group_data)
    setTxtProgressBar(bar, pct_done)
    group <- as.character(names(group_data)[g])
    protein_group <- group_data[[group]][["data"]]
    protein_accessions <- names(protein_group)
    for (p in 1:length(protein_accessions)) {
      protein <- protein_accessions[p]
      protein_names <- c(protein_names, protein)
      protein_summary <- group_data[[group]][["data"]][[protein]][["summary"]]
      protein_df <- rbind(protein_df, protein_summary)
      peptide_data <- group_data[[group]][["data"]][[protein]][["data"]]
      ## peptide_df <- rbind(peptide_df, peptide_data)
    }
  } ## End of the for loop
  close(bar)
  retlist <- list(
    "group_data" = group_data,
    "protein_data" = protein_df,
    "peptide_data" = peptide_df)
  return(retlist)
}

##xlsx_file <- "previous_results/2017_0811BrikenMultiConsensus.xlsx"
xlsx_file <- "previous_results/2017_1101BrikenMulti_PE_PPE_Complete.xlsx"
less_difficult <- parse_difficult_excel(xlsx_file)
## Reading previous_results/2017_1101BrikenMulti_PE_PPE_Complete.xlsx
## Starting parse.
##
  |
  |                                                                                |   0%
  |
  |                                                                                |   1%
  |
  |=                                                                               |   1%
  |
  |=                                                                               |   2%
  |
  |==                                                                              |   2%
  |
  |==                                                                              |   3%
  |
  |===                                                                             |   3%
  |
  |===                                                                             |   4%
  |
  |====                                                                            |   4%
  |
  |====                                                                            |   5%
  |
  |====                                                                            |   6%
  |
  |=====                                                                           |   6%
  |
  |=====                                                                           |   7%
  |
  |======                                                                          |   7%
  |
  |======                                                                          |   8%
  |
  |=======                                                                         |   8%
  |
  |=======                                                                         |   9%
  |
  |========                                                                        |   9%
  |
  |========                                                                        |  10%
  |
  |========                                                                        |  11%
  |
  |=========                                                                       |  11%
  |
  |=========                                                                       |  12%
  |
  |==========                                                                      |  12%
  |
  |==========                                                                      |  13%
  |
  |===========                                                                     |  13%
  |
  |===========                                                                     |  14%
  |
  |============                                                                    |  14%
  |
  |============                                                                    |  15%
  |
  |============                                                                    |  16%
  |
  |=============                                                                   |  16%
  |
  |=============                                                                   |  17%
  |
  |==============                                                                  |  17%
  |
  |==============                                                                  |  18%
  |
  |===============                                                                 |  18%
  |
  |===============                                                                 |  19%
  |
  |================                                                                |  19%
  |
  |================                                                                |  20%
  |
  |================                                                                |  21%
  |
  |=================                                                               |  21%
  |
  |=================                                                               |  22%
  |
  |==================                                                              |  22%
  |
  |==================                                                              |  23%
  |
  |===================                                                             |  23%
  |
  |===================                                                             |  24%
  |
  |====================                                                            |  24%
  |
  |====================                                                            |  25%
  |
  |====================                                                            |  26%
  |
  |=====================                                                           |  26%
  |
  |=====================                                                           |  27%
  |
  |======================                                                          |  27%
  |
  |======================                                                          |  28%
  |
  |=======================                                                         |  28%
  |
  |=======================                                                         |  29%
  |
  |========================                                                        |  29%
  |
  |========================                                                        |  30%
  |
  |========================                                                        |  31%
  |
  |=========================                                                       |  31%
  |
  |=========================                                                       |  32%
  |
  |==========================                                                      |  32%
  |
  |==========================                                                      |  33%
  |
  |===========================                                                     |  33%
  |
  |===========================                                                     |  34%
  |
  |============================                                                    |  34%
  |
  |============================                                                    |  35%
  |
  |============================                                                    |  36%
  |
  |=============================                                                   |  36%
  |
  |=============================                                                   |  37%
  |
  |==============================                                                  |  37%
  |
  |==============================                                                  |  38%
  |
  |===============================                                                 |  38%
  |
  |===============================                                                 |  39%
  |
  |================================                                                |  39%
  |
  |================================                                                |  40%
  |
  |================================                                                |  41%
  |
  |=================================                                               |  41%
  |
  |=================================                                               |  42%
  |
  |==================================                                              |  42%
  |
  |==================================                                              |  43%
  |
  |===================================                                             |  43%
  |
  |===================================                                             |  44%
  |
  |====================================                                            |  44%
  |
  |====================================                                            |  45%
  |
  |====================================                                            |  46%
  |
  |=====================================                                           |  46%
  |
  |=====================================                                           |  47%
  |
  |======================================                                          |  47%
  |
  |======================================                                          |  48%
  |
  |=======================================                                         |  48%
  |
  |=======================================                                         |  49%
  |
  |========================================                                        |  49%
  |
  |========================================                                        |  50%
  |
  |========================================                                        |  51%
  |
  |=========================================                                       |  51%
  |
  |=========================================                                       |  52%
  |
  |==========================================                                      |  52%
  |
  |==========================================                                      |  53%
  |
  |===========================================                                     |  53%
  |
  |===========================================                                     |  54%
  |
  |============================================                                    |  54%
  |
  |============================================                                    |  55%
  |
  |============================================                                    |  56%
  |
  |=============================================                                   |  56%
  |
  |=============================================                                   |  57%
  |
  |==============================================                                  |  57%
  |
  |==============================================                                  |  58%
  |
  |===============================================                                 |  58%
  |
  |===============================================                                 |  59%
  |
  |================================================                                |  59%
  |
  |================================================                                |  60%
  |
  |================================================                                |  61%
  |
  |=================================================                               |  61%
  |
  |=================================================                               |  62%
  |
  |==================================================                              |  62%
  |
  |==================================================                              |  63%
  |
  |===================================================                             |  63%
  |
  |===================================================                             |  64%
  |
  |====================================================                            |  64%
  |
  |====================================================                            |  65%
  |
  |====================================================                            |  66%
  |
  |=====================================================                           |  66%
  |
  |=====================================================                           |  67%
  |
  |======================================================                          |  67%
  |
  |======================================================                          |  68%
  |
  |=======================================================                         |  68%
  |
  |=======================================================                         |  69%
  |
  |========================================================                        |  69%
  |
  |========================================================                        |  70%
  |
  |========================================================                        |  71%
  |
  |=========================================================                       |  71%
  |
  |=========================================================                       |  72%
  |
  |==========================================================                      |  72%
  |
  |==========================================================                      |  73%
  |
  |===========================================================                     |  73%
  |
  |===========================================================                     |  74%
  |
  |============================================================                    |  74%
  |
  |============================================================                    |  75%
  |
  |============================================================                    |  76%
  |
  |=============================================================                   |  76%
  |
  |=============================================================                   |  77%
  |
  |==============================================================                  |  77%
  |
  |==============================================================                  |  78%
  |
  |===============================================================                 |  78%
  |
  |===============================================================                 |  79%
  |
  |================================================================                |  79%
  |
  |================================================================                |  80%
  |
  |================================================================                |  81%
  |
  |=================================================================               |  81%
  |
  |=================================================================               |  82%
  |
  |==================================================================              |  82%
  |
  |==================================================================              |  83%
  |
  |===================================================================             |  83%
  |
  |===================================================================             |  84%
  |
  |====================================================================            |  84%
  |
  |====================================================================            |  85%
  |
  |====================================================================            |  86%
  |
  |=====================================================================           |  86%
  |
  |=====================================================================           |  87%
  |
  |======================================================================          |  87%
  |
  |======================================================================          |  88%
  |
  |=======================================================================         |  88%
  |
  |=======================================================================         |  89%
  |
  |========================================================================        |  89%
  |
  |========================================================================        |  90%
  |
  |========================================================================        |  91%
  |
  |=========================================================================       |  91%
  |
  |=========================================================================       |  92%
  |
  |==========================================================================      |  92%
  |
  |==========================================================================      |  93%
  |
  |===========================================================================     |  93%
  |
  |===========================================================================     |  94%
  |
  |============================================================================    |  94%
  |
  |============================================================================    |  95%
  |
  |============================================================================    |  96%
  |
  |=============================================================================   |  96%
  |
  |=============================================================================   |  97%
  |
  |==============================================================================  |  97%
  |
  |==============================================================================  |  98%
  |
  |=============================================================================== |  98%
  |
  |=============================================================================== |  99%
  |
  |================================================================================|  99%
  |
  |================================================================================| 100%
## Finished parsing, reorganizing the protein data.
## Starting to iterate over 2574 groups.
##
  |
  |                                                                                |   0%
  |
  |                                                                                |   1%
  |
  |=                                                                               |   1%
  |
  |=                                                                               |   2%
  |
  |==                                                                              |   2%
  |
  |==                                                                              |   3%
  |
  |===                                                                             |   3%
  |
  |===                                                                             |   4%
  |
  |====                                                                            |   4%
  |
  |====                                                                            |   5%
  |
  |====                                                                            |   6%
  |
  |=====                                                                           |   6%
  |
  |=====                                                                           |   7%
  |
  |======                                                                          |   7%
  |
  |======                                                                          |   8%
  |
  |=======                                                                         |   8%
  |
  |=======                                                                         |   9%
  |
  |========                                                                        |   9%
  |
  |========                                                                        |  10%
  |
  |========                                                                        |  11%
  |
  |=========                                                                       |  11%
  |
  |=========                                                                       |  12%
  |
  |==========                                                                      |  12%
  |
  |==========                                                                      |  13%
  |
  |===========                                                                     |  13%
  |
  |===========                                                                     |  14%
  |
  |============                                                                    |  14%
  |
  |============                                                                    |  15%
  |
  |============                                                                    |  16%
  |
  |=============                                                                   |  16%
  |
  |=============                                                                   |  17%
  |
  |==============                                                                  |  17%
  |
  |==============                                                                  |  18%
  |
  |===============                                                                 |  18%
  |
  |===============                                                                 |  19%
  |
  |================                                                                |  19%
  |
  |================                                                                |  20%
  |
  |================                                                                |  21%
  |
  |=================                                                               |  21%
  |
  |=================                                                               |  22%
  |
  |==================                                                              |  22%
  |
  |==================                                                              |  23%
  |
  |===================                                                             |  23%
  |
  |===================                                                             |  24%
  |
  |====================                                                            |  24%
  |
  |====================                                                            |  25%
  |
  |====================                                                            |  26%
  |
  |=====================                                                           |  26%
  |
  |=====================                                                           |  27%
  |
  |======================                                                          |  27%
  |
  |======================                                                          |  28%
  |
  |=======================                                                         |  28%
  |
  |=======================                                                         |  29%
  |
  |========================                                                        |  29%
  |
  |========================                                                        |  30%
  |
  |========================                                                        |  31%
  |
  |=========================                                                       |  31%
  |
  |=========================                                                       |  32%
  |
  |==========================                                                      |  32%
  |
  |==========================                                                      |  33%
  |
  |===========================                                                     |  33%
  |
  |===========================                                                     |  34%
  |
  |============================                                                    |  34%
  |
  |============================                                                    |  35%
  |
  |============================                                                    |  36%
  |
  |=============================                                                   |  36%
  |
  |=============================                                                   |  37%
  |
  |==============================                                                  |  37%
  |
  |==============================                                                  |  38%
  |
  |===============================                                                 |  38%
  |
  |===============================                                                 |  39%
  |
  |================================                                                |  39%
  |
  |================================                                                |  40%
  |
  |================================                                                |  41%
  |
  |=================================                                               |  41%
  |
  |=================================                                               |  42%
  |
  |==================================                                              |  42%
  |
  |==================================                                              |  43%
  |
  |===================================                                             |  43%
  |
  |===================================                                             |  44%
  |
  |====================================                                            |  44%
  |
  |====================================                                            |  45%
  |
  |====================================                                            |  46%
  |
  |=====================================                                           |  46%
  |
  |=====================================                                           |  47%
  |
  |======================================                                          |  47%
  |
  |======================================                                          |  48%
  |
  |=======================================                                         |  48%
  |
  |=======================================                                         |  49%
  |
  |========================================                                        |  49%
  |
  |========================================                                        |  50%
  |
  |========================================                                        |  51%
  |
  |=========================================                                       |  51%
  |
  |=========================================                                       |  52%
  |
  |==========================================                                      |  52%
  |
  |==========================================                                      |  53%
  |
  |===========================================                                     |  53%
  |
  |===========================================                                     |  54%
  |
  |============================================                                    |  54%
  |
  |============================================                                    |  55%
  |
  |============================================                                    |  56%
  |
  |=============================================                                   |  56%
  |
  |=============================================                                   |  57%
  |
  |==============================================                                  |  57%
  |
  |==============================================                                  |  58%
  |
  |===============================================                                 |  58%
  |
  |===============================================                                 |  59%
  |
  |================================================                                |  59%
  |
  |================================================                                |  60%
  |
  |================================================                                |  61%
  |
  |=================================================                               |  61%
  |
  |=================================================                               |  62%
  |
  |==================================================                              |  62%
  |
  |==================================================                              |  63%
  |
  |===================================================                             |  63%
  |
  |===================================================                             |  64%
  |
  |====================================================                            |  64%
  |
  |====================================================                            |  65%
  |
  |====================================================                            |  66%
  |
  |=====================================================                           |  66%
  |
  |=====================================================                           |  67%
  |
  |======================================================                          |  67%
  |
  |======================================================                          |  68%
  |
  |=======================================================                         |  68%
  |
  |=======================================================                         |  69%
  |
  |========================================================                        |  69%
  |
  |========================================================                        |  70%
  |
  |========================================================                        |  71%
  |
  |=========================================================                       |  71%
  |
  |=========================================================                       |  72%
  |
  |==========================================================                      |  72%
  |
  |==========================================================                      |  73%
  |
  |===========================================================                     |  73%
  |
  |===========================================================                     |  74%
  |
  |============================================================                    |  74%
  |
  |============================================================                    |  75%
  |
  |============================================================                    |  76%
  |
  |=============================================================                   |  76%
  |
  |=============================================================                   |  77%
  |
  |==============================================================                  |  77%
  |
  |==============================================================                  |  78%
  |
  |===============================================================                 |  78%
  |
  |===============================================================                 |  79%
  |
  |================================================================                |  79%
  |
  |================================================================                |  80%
  |
  |================================================================                |  81%
  |
  |=================================================================               |  81%
  |
  |=================================================================               |  82%
  |
  |==================================================================              |  82%
  |
  |==================================================================              |  83%
  |
  |===================================================================             |  83%
  |
  |===================================================================             |  84%
  |
  |====================================================================            |  84%
  |
  |====================================================================            |  85%
  |
  |====================================================================            |  86%
  |
  |=====================================================================           |  86%
  |
  |=====================================================================           |  87%
  |
  |======================================================================          |  87%
  |
  |======================================================================          |  88%
  |
  |=======================================================================         |  88%
  |
  |=======================================================================         |  89%
  |
  |========================================================================        |  89%
  |
  |========================================================================        |  90%
  |
  |========================================================================        |  91%
  |
  |=========================================================================       |  91%
  |
  |=========================================================================       |  92%
  |
  |==========================================================================      |  92%
  |
  |==========================================================================      |  93%
  |
  |===========================================================================     |  93%
  |
  |===========================================================================     |  94%
  |
  |============================================================================    |  94%
  |
  |============================================================================    |  95%
  |
  |============================================================================    |  96%
  |
  |=============================================================================   |  96%
  |
  |=============================================================================   |  97%
  |
  |==============================================================================  |  97%
  |
  |==============================================================================  |  98%
  |
  |=============================================================================== |  98%
  |
  |=============================================================================== |  99%
  |
  |================================================================================|  99%
  |
  |================================================================================| 100%

The function above is not immediately helpful, as it only wrangles the crazy excel into a less-crazy data structure, but if we wish to graph the data or play with it, we need to extract the elements of interest. For the moment those are primarily the peptide fragments and whether they were found in the trypsin digestions, chymotrypsin digestions, or both.

This data frame now contains everything we are likely to want to visualize.

1.2 Cleaning the data frame

Unfortunately, this data structure also suffers from a couple weaknesses:

  1. The protein IDs are not unique (because of the groups)
  2. The column names from Excel are insane (punctuation, special characters, and really long)
  3. Excel left the numeric columns of data as characters, not numbers!

Therefore, I will take a moment to fix these problems before trying any plots.

## Set some reasonable row names
protein_df <- less_difficult[["protein_data"]]

rownames(protein_df) <- make.names(protein_names, unique=TRUE)
## Error in `row.names<-.data.frame`(`*tmp*`, value = value): invalid 'row.names' length
## Set the column names to something legible.
## Each line denotes my mental organizational unit
new_colnames <- c("mascot_fdr", "sequest_fdr", "master", "accession", "description",
                  "mascot_q", "sequest_q", "coverage", "contaminant", "marked_as",
                  "num_peptides", "num_psms", "num_unique_pep", "num_prot_groups", "num_aas",
                  "mw", "pi", "mascot_score", "sequest_score", "num_peptides_mascot",
                  "num_peptides_sequest", "bp", "cc", "mf", "pfam_ids",
                  "entrez_gene_id", "ensembl_gene_id", "gene_symbol", "chromosome", "kegg",
                  "wikipathways", "found_trypsin_lysc_cf", "found_trypsin_lysc_wcl", "found_chymotrypsin_cf", "found_chymotrypsin_wcl",
                  "modifications", "id")
colnames(protein_df) <- new_colnames
## Now make sure the columns which should be numeric, are numeric.
numeric_cols <- c("mascot_q", "sequest_q", "coverage", "num_peptides", "num_psms",
                  "num_unique_pep", "num_prot_groups", "num_aas", "mw", "pi",
                  "mascot_score", "sequest_score",
                  "num_peptides_mascot", "num_peptides_sequest")
for (col in numeric_cols) {
  protein_df[[col]] <- as.numeric(protein_df[[col]])
}
factor_cols <- c("found_trypsin_lysc_cf", "found_trypsin_lysc_wcl",
                 "found_chymotrypsin_cf", "found_chymotrypsin_wcl")
for (col in factor_cols) {
  protein_df[[col]] <- as.factor(protein_df[[col]])
}
## Finally, set a 'state' column describing the 4 columns of chymotrypsin/trypsin digestions.
protein_df[["state"]] <- "ambiguous"
## If something is found in one chymo trypsin, but in neither trypsin, set it to chymo_only.
chymo_hits <- (protein_df[["found_chymotrypsin_cf"]] == "High" | protein_df[["found_chymotrypsin_wcl"]] == "High") &
  (protein_df[["found_trypsin_lysc_cf"]] != "High" & protein_df[["found_trypsin_lysc_wcl"]] != "High")
protein_df[chymo_hits, "state"] <- "chymo_only"
## Conversely, if found in trypsin but not chymo, set it to tryp_only.
tryp_hits <- (protein_df[["found_trypsin_lysc_cf"]] == "High" | protein_df[["found_trypsin_lysc_wcl"]] == "High") &
  (protein_df[["found_chymotrypsin_cf"]] != "High" & protein_df[["found_chymotrypsin_wcl"]] != "High")
protein_df[tryp_hits, "state"] <- "tryp_only"
no_hits <- protein_df[["found_trypsin_lysc_cf"]] == "Not Found" &
  protein_df[["found_trypsin_lysc_wcl"]] == "Not Found" &
  protein_df[["found_chymotrypsin_cf"]] == "Not Found" &
  protein_df[["found_chymotrypsin_wcl"]] == "Not Found"
protein_df[no_hits, "state"] <- "None"
protein_df[["state"]] <- as.factor(protein_df[["state"]])

chymo_df <- protein_df[chymo_hits, ]
tryp_df <- protein_df[tryp_hits, ]

1.3 Make a couple plots

Now that the data has been wrangled, we can use the various R plotters to look at the data relatively quickly and easily.

library(ggplot2)
coverage_wrt_pi <- ggplot(protein_df, aes_string(x="pi", y="coverage", colour="state")) +
  geom_point(alpha=0.6, size=2) +
  geom_density_2d()

coverage_wrt_mw <- ggplot(protein_df, aes_string(x="mw", y="coverage", colour="state")) +
  geom_point(alpha=0.6, size=2) +
  geom_density_2d()

protein_df$logmascot <- log2(protein_df$mascot_score)
scores_by_state <- ggplot(protein_df, aes_string(x="state", y="logmascot")) +
  geom_boxplot(aes_string(fill="state"))

1.3.1 Coverage vs. pI

Yan suggested that peptides with low-pIs would be less covered, especially in the chymotrypsin samples.

pp(file="images/coverage_wrt_pi.png")
## NULL
coverage_wrt_pi
## Warning: Computation failed in `stat_density2d()`:
## bandwidths must be strictly positive
dev.off()
## X11cairo
##        2
## To me, it looks like there might be something to that idea.

1.3.2 Coverage vs. Molecular Weight

Maybe there is a trend of coverage and molecular weight by sample-type.

pp(file="images/coverage_wrt_mw.png")
## NULL
coverage_wrt_mw
## Warning: Computation failed in `stat_density2d()`:
## bandwidths must be strictly positive
dev.off()
## X11cairo
##        2
## It looks to me that the trypsin is slightly better than chymotrypsin.
## It is not clear in the excel, but I presume this is in kDa.

1.3.3 Mascot scores

A quick boxplot showing mascot scores by what was observed.

scores_by_state
## Warning: Removed 96 rows containing non-finite values (stat_boxplot).

all_de <- read.table("limma_result.csv", header=TRUE, sep="\t")
colnames(all_de) <- c("ID", "logFC", "AveExpr", "adj.P.Val", "abbrev_id", "description", "gene_length", "type")
all_de <- merge(all_de, mtb_annotations, by.x="ID", by.y="ID")
dim(all_de)
## [1] 3995   21
pe_ids <- read.table("reference/annotated_pe_genes.txt")
colnames(pe_ids) <- "locus_tag"
pe_annotations <- merge(pe_ids, mtb_annotations, by="locus_tag")
rownames(pe_annotations) <- pe_annotations[["ID"]]
dim(pe_annotations)
## [1] 161  14
uniprot_annot <- load_uniprot_annotations(file="reference/uniprot_3AUP000001584.txt.gz")
##
  |
  |                                                                                |   0%
  |
  |                                                                                |   1%
  |
  |=                                                                               |   1%
  |
  |=                                                                               |   2%
  |
  |==                                                                              |   2%
  |
  |==                                                                              |   3%
  |
  |===                                                                             |   3%
  |
  |===                                                                             |   4%
  |
  |====                                                                            |   4%
  |
  |====                                                                            |   5%
  |
  |====                                                                            |   6%
  |
  |=====                                                                           |   6%
  |
  |=====                                                                           |   7%
  |
  |======                                                                          |   7%
  |
  |======                                                                          |   8%
  |
  |=======                                                                         |   8%
  |
  |=======                                                                         |   9%
  |
  |========                                                                        |   9%
  |
  |========                                                                        |  10%
  |
  |========                                                                        |  11%
  |
  |=========                                                                       |  11%
  |
  |=========                                                                       |  12%
  |
  |==========                                                                      |  12%
  |
  |==========                                                                      |  13%
  |
  |===========                                                                     |  13%
  |
  |===========                                                                     |  14%
  |
  |============                                                                    |  14%
  |
  |============                                                                    |  15%
  |
  |============                                                                    |  16%
  |
  |=============                                                                   |  16%
  |
  |=============                                                                   |  17%
  |
  |==============                                                                  |  17%
  |
  |==============                                                                  |  18%
  |
  |===============                                                                 |  18%
  |
  |===============                                                                 |  19%
  |
  |================                                                                |  19%
  |
  |================                                                                |  20%
  |
  |================                                                                |  21%
  |
  |=================                                                               |  21%
  |
  |=================                                                               |  22%
  |
  |==================                                                              |  22%
  |
  |==================                                                              |  23%
  |
  |===================                                                             |  23%
  |
  |===================                                                             |  24%
  |
  |====================                                                            |  24%
  |
  |====================                                                            |  25%
  |
  |====================                                                            |  26%
  |
  |=====================                                                           |  26%
  |
  |=====================                                                           |  27%
  |
  |======================                                                          |  27%
  |
  |======================                                                          |  28%
  |
  |=======================                                                         |  28%
  |
  |=======================                                                         |  29%
  |
  |========================                                                        |  29%
  |
  |========================                                                        |  30%
  |
  |========================                                                        |  31%
  |
  |=========================                                                       |  31%
  |
  |=========================                                                       |  32%
  |
  |==========================                                                      |  32%
  |
  |==========================                                                      |  33%
  |
  |===========================                                                     |  33%
  |
  |===========================                                                     |  34%
  |
  |============================                                                    |  34%
  |
  |============================                                                    |  35%
  |
  |============================                                                    |  36%
  |
  |=============================                                                   |  36%
  |
  |=============================                                                   |  37%
  |
  |==============================                                                  |  37%
  |
  |==============================                                                  |  38%
  |
  |===============================                                                 |  38%
  |
  |===============================                                                 |  39%
  |
  |================================                                                |  39%
  |
  |================================                                                |  40%
  |
  |================================                                                |  41%
  |
  |=================================                                               |  41%
  |
  |=================================                                               |  42%
  |
  |==================================                                              |  42%
  |
  |==================================                                              |  43%
  |
  |===================================                                             |  43%
  |
  |===================================                                             |  44%
  |
  |====================================                                            |  44%
  |
  |====================================                                            |  45%
  |
  |====================================                                            |  46%
  |
  |=====================================                                           |  46%
  |
  |=====================================                                           |  47%
  |
  |======================================                                          |  47%
  |
  |======================================                                          |  48%
  |
  |=======================================                                         |  48%
  |
  |=======================================                                         |  49%
  |
  |========================================                                        |  49%
  |
  |========================================                                        |  50%
  |
  |========================================                                        |  51%
  |
  |=========================================                                       |  51%
  |
  |=========================================                                       |  52%
  |
  |==========================================                                      |  52%
  |
  |==========================================                                      |  53%
  |
  |===========================================                                     |  53%
  |
  |===========================================                                     |  54%
  |
  |============================================                                    |  54%
  |
  |============================================                                    |  55%
  |
  |============================================                                    |  56%
  |
  |=============================================                                   |  56%
  |
  |=============================================                                   |  57%
  |
  |==============================================                                  |  57%
  |
  |==============================================                                  |  58%
  |
  |===============================================                                 |  58%
  |
  |===============================================                                 |  59%
  |
  |================================================                                |  59%
  |
  |================================================                                |  60%
  |
  |================================================                                |  61%
  |
  |=================================================                               |  61%
  |
  |=================================================                               |  62%
  |
  |==================================================                              |  62%
  |
  |==================================================                              |  63%
  |
  |===================================================                             |  63%
  |
  |===================================================                             |  64%
  |
  |====================================================                            |  64%
  |
  |====================================================                            |  65%
  |
  |====================================================                            |  66%
  |
  |=====================================================                           |  66%
  |
  |=====================================================                           |  67%
  |
  |======================================================                          |  67%
  |
  |======================================================                          |  68%
  |
  |=======================================================                         |  68%
  |
  |=======================================================                         |  69%
  |
  |========================================================                        |  69%
  |
  |========================================================                        |  70%
  |
  |========================================================                        |  71%
  |
  |=========================================================                       |  71%
  |
  |=========================================================                       |  72%
  |
  |==========================================================                      |  72%
  |
  |==========================================================                      |  73%
  |
  |===========================================================                     |  73%
  |
  |===========================================================                     |  74%
  |
  |============================================================                    |  74%
  |
  |============================================================                    |  75%
  |
  |============================================================                    |  76%
  |
  |=============================================================                   |  76%
  |
  |=============================================================                   |  77%
  |
  |==============================================================                  |  77%
  |
  |==============================================================                  |  78%
  |
  |===============================================================                 |  78%
  |
  |===============================================================                 |  79%
  |
  |================================================================                |  79%
  |
  |================================================================                |  80%
  |
  |================================================================                |  81%
  |
  |=================================================================               |  81%
  |
  |=================================================================               |  82%
  |
  |==================================================================              |  82%
  |
  |==================================================================              |  83%
  |
  |===================================================================             |  83%
  |
  |===================================================================             |  84%
  |
  |====================================================================            |  84%
  |
  |====================================================================            |  85%
  |
  |====================================================================            |  86%
  |
  |=====================================================================           |  86%
  |
  |=====================================================================           |  87%
  |
  |======================================================================          |  87%
  |
  |======================================================================          |  88%
  |
  |=======================================================================         |  88%
  |
  |=======================================================================         |  89%
  |
  |========================================================================        |  89%
  |
  |========================================================================        |  90%
  |
  |========================================================================        |  91%
  |
  |=========================================================================       |  91%
  |
  |=========================================================================       |  92%
  |
  |==========================================================================      |  92%
  |
  |==========================================================================      |  93%
  |
  |===========================================================================     |  93%
  |
  |===========================================================================     |  94%
  |
  |============================================================================    |  94%
  |
  |============================================================================    |  95%
  |
  |============================================================================    |  96%
  |
  |=============================================================================   |  96%
  |
  |=============================================================================   |  97%
  |
  |==============================================================================  |  97%
  |
  |==============================================================================  |  98%
  |
  |=============================================================================== |  98%
  |
  |=============================================================================== |  99%
  |
  |================================================================================|  99%
  |
  |================================================================================| 100%
## Finished parsing, creating data frame.
dim(uniprot_annot)
## [1] 3993   41
uniprot_rna <- merge(all_de, uniprot_annot, by.x="ID", by.y="loci")
dim(uniprot_rna)
## [1] 3891   61
uniprot_pe <- merge(pe_annotations, uniprot_annot, by.x="ID", by.y="loci")
dim(uniprot_pe)
## [1] 157  54
uniprot_pe_peptides <- merge(uniprot_annot, protein_df, by.x="primary_accessions", by.y="accession")
uniprot_pe_peptides <- merge(uniprot_pe_peptides, pe_ids, by.x="loci", by.y="locus_tag")
dim(uniprot_pe_peptides)
## [1] 40 79
uniprot_rna_protein <- merge(uniprot_rna, protein_df, by.x="primary_accessions", by.y="accession")
dim(protein_df)
## [1] 2671   39
dim(uniprot_rna_protein)
## [1] 2511   99
uniprot_rna_pe <- merge(uniprot_pe, uniprot_rna_protein, by="ID")
## Warning in merge.data.frame(uniprot_pe, uniprot_rna_protein, by = "ID"): column names
## 'description.x', 'description.y' are duplicated in the result
dim(uniprot_rna_pe)
## [1]  40 152
## This is exhausting, I will call these big and little from now on
big <- uniprot_rna_protein
rownames(big) <- make.names(big$ID, unique=TRUE)
ordered <- order(rownames(big))
big <- big[ordered, ]
little <- uniprot_rna_pe
rownames(little) <- make.names(little$ID, unique=TRUE)
ordered <- order(rownames(little))
little <- little[ordered, ]
shared <- rownames(big) %in% rownames(little)
## pe_de_annot <- merge(pe_de, mtb_annotations, by="locus_tag")
## The contrast is written as wt - delta, so add back the logFC I think
## Hopefully I did not reverse this in my head.
big$ave_minus_log <- big$AveExpr - big$logFC
big$ave_minus_log <- big$AveExpr - big$logFC
big$pseudo_rpkm <- (big$ave_minus_log / big$width) * 1000
maximum_rpkm <- max(big$pseudo_rpkm)
big$express_vs_max <- big$pseudo_rpkm / maximum_rpkm
## Since we constant ordered the dataframes above, this is valid.
little$pseudo_rpkm <- big$pseudo_rpkm[shared]
little$express_vs_max <- big$express_vs_max[shared]

write.csv(x=little, file="pe_relative_expression_annotation-20171205.csv")

library(hpgltools)
library(ggplot2)
test <- list(
  "all_peptides" = big$express_vs_max,
  "pe_peptides" = little$express_vs_max)
multi <- plot_multihistogram(test)
## Used Bon Ferroni corrected t test(s) between columns.
multi$plot

rpkm_vs_psms <- big[, c("pseudo_rpkm", "num_psms")]
little_rpkm_vs_psms <- little[, c("pseudo_rpkm", "num_psms")]
rpkm_vs_psms$num_psms <- log2(rpkm_vs_psms$num_psms + 1)
little_rpkm_vs_psms$num_psms <- log2(little_rpkm_vs_psms$num_psms + 1)
rpkm_psms_linear <- plot_linear_scatter(rpkm_vs_psms)
## Used Bon Ferroni corrected t test(s) between columns.
rpkm_psms_linear$scatter

rpkm_psms_linear$cor
##
##  Pearson's product-moment correlation
##
## data:  df[, 1] and df[, 2]
## t = 5.8, df = 2500, p-value = 9e-09
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.07575 0.15296
## sample estimates:
##    cor
## 0.1145
rpkm_psms_linear$lm_rsq
## [1] 0.007207
big_little <- ggplot(data=rpkm_vs_psms, aes_string(x="pseudo_rpkm", y="num_psms")) +
  geom_point()
big_little

big_little <- big_little +
  geom_point(data=little_rpkm_vs_psms, aes_string(x="pseudo_rpkm", y="num_psms"), colour="red")
pp(file="rpkm_vs_psms.png")
## NULL
big_little
dev.off()
## X11cairo
##        2
rpkm_vs_peptides <- big[, c("pseudo_rpkm", "num_peptides")]

rpkm_peptides_linear <- plot_linear_scatter(rpkm_vs_peptides)
## Used Bon Ferroni corrected t test(s) between columns.
rpkm_peptides_linear$scatter

rpkm_peptides_linear$cor
##
##  Pearson's product-moment correlation
##
## data:  df[, 1] and df[, 2]
## t = -4.8, df = 2500, p-value = 2e-06
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.13318 -0.05564
## sample estimates:
##      cor
## -0.09455
rpkm_psms_linear$lm_rsq
## [1] 0.007207
little_rpkm_vs_peptides <- little[, c("pseudo_rpkm", "num_peptides")]
big_little <- ggplot(data=rpkm_vs_peptides, aes_string(x="pseudo_rpkm", y="num_peptides")) +
  geom_point()
big_little

big_little <- big_little +
  geom_point(data=little_rpkm_vs_peptides, aes_string(x="pseudo_rpkm", y="num_peptides"), colour="red")
big_little

rpkm_vs_coverage <- big[, c("pseudo_rpkm", "coverage")]
rpkm_coverage_linear <- plot_linear_scatter(rpkm_vs_coverage)
## Used Bon Ferroni corrected t test(s) between columns.
rpkm_coverage_linear$scatter

rpkm_coverage_linear$cor
##
##  Pearson's product-moment correlation
##
## data:  df[, 1] and df[, 2]
## t = 21, df = 2500, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.3532 0.4198
## sample estimates:
##   cor
## 0.387
rpkm_coverage_linear$lm_rsq
## [1] 0.1618
little_rpkm_vs_coverage <- little[, c("pseudo_rpkm", "coverage")]
big_little <- ggplot(data=rpkm_vs_coverage, aes_string(x="pseudo_rpkm", y="coverage")) +
  geom_point()
big_little

big_little <- big_little +
  geom_point(data=little_rpkm_vs_coverage, aes_string(x="pseudo_rpkm", y="coverage"), colour="red")
big_little

pander::pander(sessionInfo())

R version 3.4.3 (2017-11-30)

**Platform:** x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.UTF-8, LC_NUMERIC=C, LC_TIME=en_US.UTF-8, LC_COLLATE=en_US.UTF-8, LC_MONETARY=en_US.UTF-8, LC_MESSAGES=en_US.UTF-8, LC_PAPER=en_US.UTF-8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.UTF-8 and LC_IDENTIFICATION=C

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

other attached packages: hpgltools(v.2017.10) and ggplot2(v.2.2.1)

loaded via a namespace (and not attached): reshape2(v.1.4.2), pander(v.0.6.1), colorspace(v.1.3-2), htmltools(v.0.3.6), yaml(v.2.1.15), base64enc(v.0.1-3), rlang(v.0.1.4), withr(v.2.1.0), BiocGenerics(v.0.24.0), readxl(v.1.0.0), foreach(v.1.4.3), plyr(v.1.8.4), robustbase(v.0.92-8), stringr(v.1.2.0), munsell(v.0.4.3), commonmark(v.1.4), gtable(v.0.2.0), cellranger(v.1.1.0), devtools(v.1.13.4), codetools(v.0.2-15), memoise(v.1.1.0), evaluate(v.0.10.1), labeling(v.0.3), Biobase(v.2.38.0), knitr(v.1.17), parallel(v.3.4.3), DEoptimR(v.1.0-8), Rcpp(v.0.12.14), readr(v.1.1.1), scales(v.0.5.0), backports(v.1.1.1), hms(v.0.4.0), digest(v.0.6.12), stringi(v.1.1.6), grid(v.3.4.3), rprojroot(v.1.2), tools(v.3.4.3), magrittr(v.1.5), lazyeval(v.0.2.1), tibble(v.1.3.4), pkgconfig(v.2.0.1), MASS(v.7.3-47), data.table(v.1.10.4-3), xml2(v.1.1.1), rmarkdown(v.1.8), roxygen2(v.6.0.1), iterators(v.1.0.8), R6(v.2.2.2) and compiler(v.3.4.3)

message(paste0("This is hpgltools commit: ", get_git_commit()))
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset e98d5f5d939340766de61c5d354576f11c2769db
## R> packrat::restore()
## This is hpgltools commit: Tue Dec 5 22:18:58 2017 -0500: e98d5f5d939340766de61c5d354576f11c2769db
this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
message(paste0("Saving to ", this_save))
## Saving to 02_eval_result_201711-v20171205.rda.xz
tmp <- sm(saveme(filename=this_save))
LS0tCnRpdGxlOiAiRXZhbHVhdGluZyBzb21lIE1TL01TIHBlcHRpZGUgc2VhcmNoIG1ldHJpY3MuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IGRlZmF1bHQKICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4OwogIH0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoaHBnbHRvb2xzKQp0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKa25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQp2ZXIgPC0gIjIwMTcxMjA1IgpwcmV2aW91c19maWxlIDwtICIwMV9hbm5vdGF0aW9uLlJtZCIKCnRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQoKcm1kX2ZpbGUgPC0gIjAyX2V2YWxfcmVzdWx0XzIwMTcxMS5SbWQiCmBgYAoKIyBFdmFsdWF0ZSBQcmV2aW91cyBSZXN1bHQ6IHZlcnNpb246IGByIHZlcmAKCiMjIFJlYWRpbmcgaW4gdGhlIGV4aXN0aW5nIHJlc3VsdAoKQXMgcGVyIFlhbidzIHN1Z2dlc3Rpb24sIEkgYW0gdXNpbmcgdGhlIGV4aXN0aW5nIHJlc3VsdHMsIGZvdW5kIGluIHRoZSBmaWxlOgoiMjAxN18wODExQnJpa2VuTXVsdGlDb25zZW5zdXMueGxzeCIKClVuZm9ydHVuYXRlbHksIHRoaXMgdGFibGUgaXMgaW4gYSBwYXJ0aWN1bGFybHkgc3RyYW5nZSBmb3JtYXQ6IGl0IGlzIGEgdHJpcGx5Cm5lc3RlZCB0YWJsZSBvZiB0YWJsZXMgb2YgdGFibGVzIGluIG9uZSB3b3Jrc2hlZXQgaW4gRXhjZWwuICBBdCBvbmUgbGV2ZWwsIHRoaXMKaXMgYSByZWFsbHkgbm92ZWwgYW5kIGludGVyZXN0aW5nIHVzZSBvZiBFeGNlbCwgYnV0IG9uIGV2ZXJ5IG90aGVyIGxldmVsIGl0IGlzCnN1Yi1vcHRpbWFsLiAgVGhlIHByaW1hcnkgcmVhc29uIGl0IGlzIHN1Yi1vcHRpbWFsIGlzIHRoYXQgdGhlIGNvbHVtbiBoZWFkaW5ncwplbmQgdXAgYmVpbmcgcmVwZWF0ZWQgb25jZSBmb3IgZXZlcnkgbmV3IHN1Yi10YWJsZSAoODc0IG9mIHRoZSBpbm5lciB0YWJsZXMgcGx1cwpob3dldmVyIG1hbnkgbWlkZGxlIHRhYmxlcyksIHdoaWNoIG1ha2VzIGl0IG5lYXJseSB1bnBhcnNlYWJsZS4KCkkgYW0gZGlzcGxlYXNlZCBJIG5lZWQgdG8gZG8gdGhpcyBsZXZlbCBvZiBkYXRhIHdyYW5nbGluZy4KClRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gaXMgbXkgZmlyc3QgYXR0ZW1wdCBhdCBoYW5kbGluZyB0aGlzIHBhcnNpbmcgcHV6emxlLgoKRm9yIHRoZSBpbnRlcmVzdGVkLCB0aGUgc3RydWN0dXJlIGlzOgoKKiAgYWxsX3Byb3RlaW5fZ3JvdXBzIGlzIGEgbGlzdCBvZiB0d28gZWxlbWVudHM6IGdyb3VwX2lkID0+ICgic3VtbWFyeSIsICJkYXRhIikKKiAgZm9yIGV2ZXJ5IHByb3RlaW4gZ3JvdXAgZGlzY292ZXJlZCwgb25lIG9mIHRoZXNlIHR3byBlbGVtZW50IGxpc3RzIGlzIGNyZWF0ZWQuCiAgICAqICBUaGUgc3VtbWFyeSBzbG90IGdldHMgdGhlIG9uZS1yb3cgc3VtbWFyeSBmb3IgdGhlIHByb3RlaW4gZ3JvdXAgZnJvbSB0aGUgZXhjZWwuCiogIFRoZSBkYXRhIHNsb3QgaXMgYSBsaXN0IG9mIGdyb3VwczogcHJvdGVpbiA9PiAoInN1bW1hcnkiLCAiZGF0YSIpCiAgICAqICBPbmNlIGFnYWluLCB0aGUgc3VtbWFyeSBpcyB0aGUgc2luZ2xlIHJvdyBmcm9tIGV4Y2VsLgoqICBBZ2FpbiwgdGhlIGRhdGEgc2xvdCBpcyBhIGxpc3Qgb2YgcGVwdGlkZXM6IHBlcHRpZGUgPT4gZGF0YS5mcmFtZShwZXB0aWRlcykKICAgICogIEVhY2ggcGVwdGlkZSBkYXRhIGZyYW1lIGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5uZXItbW9zdCByb3dzIGRlc2NyaWJpbmcgdGhlCiAgICAgICBvYnNlcnZlZCBwZXB0aWRlcy4KCmBgYHtyIGV4dHJhY3RfcGVwdGlkZXN9CnBhcnNlX2RpZmZpY3VsdF9leGNlbCA8LSBmdW5jdGlvbih4bHN4X2ZpbGUsIHRlc3Rfcm93PTkyMTUwKSB7CiAgb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhqYXZhLnBhcmFtZXRlcnM9Ii1YbXgyMEciKQogIG1lc3NhZ2UocGFzdGUwKCJSZWFkaW5nICIsIHhsc3hfZmlsZSkpCiAgcmVzdWx0IDwtIHJlYWR4bDo6cmVhZF94bHN4KHBhdGg9eGxzeF9maWxlLCBzaGVldD0xLCBjb2xfbmFtZXM9RkFMU0UpCiAgbWVzc2FnZSgiU3RhcnRpbmcgcGFyc2UuIikKICBncm91cF9kYXRhIDwtIGxpc3QoKQogIGJhciA8LSB1dGlsczo6dHh0UHJvZ3Jlc3NCYXIoc3R5bGU9MykKICBmb3IgKHIgaW4gMTpucm93KHJlc3VsdCkpIHsKICAgIHJvdyA8LSBhcy5kYXRhLmZyYW1lKHJlc3VsdFtyLCBdKQogICAgcm93WywgaXMubmEocm93KV0gPC0gIiIKICAgIHBjdF9kb25lIDwtIHIgLyBucm93KHJlc3VsdCkKICAgIHNldFR4dFByb2dyZXNzQmFyKGJhciwgcGN0X2RvbmUpCiAgICAjIyBUaGUgZm9sbG93aW5nIDMgc3RhbnphcyBoYW5kbGUgdGhlIGNyZWF0aW9uIG9mIHRoZSBsZXZlbHMgb2Ygb3VyIGRhdGEgc3RydWN0dXJlCiAgICAjIyBUaGUgZmlyc3QgZGVmaW5lcyB0aGUgcHJvdGVpbiBncm91cAogICAgaWYgKHJvd1ssIDFdID09ICJDaGVja2VkIikgewogICAgICBncm91cF9jb2xuYW1lcyA8LSBhcy5jaGFyYWN0ZXIocm93KQogICAgICBncm91cF9rZWVwZXJzIDwtICFncmVwbChwYXR0ZXJuPSJeJCIsIHg9Z3JvdXBfY29sbmFtZXMpCiAgICAgIGdyb3VwX2tlZXBlcnNbMV0gPC0gRkFMU0UKICAgICAgZ3JvdXBfY29sbmFtZXMgPC0gZ3JvdXBfY29sbmFtZXNbZ3JvdXBfa2VlcGVyc10KICAgICAgbmV4dAogICAgfQogICAgIyMgV2hlbiB0aGUgMm5kIGNvbHVtbiBpcyAnQ2hlY2tlZCcsIHRoZW4gdGhpcyBkZWZpbmVzIGEgbmV3IHByb3RlaW4gaW4gdGhlIGdyb3VwLgogICAgaWYgKHJvd1ssIDJdID09ICJDaGVja2VkIikgewogICAgICBwcm90ZWluX2NvbG5hbWVzIDwtIGFzLmNoYXJhY3Rlcihyb3cpCiAgICAgIHByb3RlaW5fa2VlcGVycyA8LSAhZ3JlcGwocGF0dGVybj0iXiQiLCB4PXByb3RlaW5fY29sbmFtZXMpCiAgICAgIHByb3RlaW5fa2VlcGVyc1syXSA8LSBGQUxTRQogICAgICBwcm90ZWluX2NvbG5hbWVzIDwtIHByb3RlaW5fY29sbmFtZXNbcHJvdGVpbl9rZWVwZXJzXQogICAgICBuZXh0CiAgICB9CiAgICAjIyBXaGVuIHRoZSAzcmQgY29sdW1uIGlzICdDaGVja2VkJywgdGhlbiB0aGlzIHN0YXJ0cyBhIHBlcHRpZGUgZGVmaW5pdGlvbgogICAgaWYgKHJvd1ssIDNdID09ICJDaGVja2VkIikgewogICAgICBwZXB0aWRlX2NvbG5hbWVzIDwtIGFzLmNoYXJhY3Rlcihyb3cpCiAgICAgIHBlcHRpZGVfa2VlcGVycyA8LSAhZ3JlcGwocGF0dGVybj0iXiQiLCB4PXBlcHRpZGVfY29sbmFtZXMpCiAgICAgIHBlcHRpZGVfa2VlcGVyc1szXSA8LSBGQUxTRQogICAgICBwZXB0aWRlX2NvbG5hbWVzIDwtIHBlcHRpZGVfY29sbmFtZXNbcGVwdGlkZV9rZWVwZXJzXQogICAgICBuZXh0CiAgICB9CiAgICAjIyBPbmNlIHRoZSBjb2x1bW4gbmFtZXMgZm9yIHRoZSBkYXRhIGFyZSBkZWZpbmVkLCB3ZSBjb25zaWRlciBob3cgdG8KICAgICMjIEZpbGwgaW4gdGhlIGFjdHVhbCBkYXRhLCB0aGUgcHJvdGVpbiBncm91cCBpcyBwcm9iYWJseSB0aGUgbGVhc3QgaW50ZXJlc3RpbmcuCiAgICBpZiAocm93WywgMV0gPT0gRkFMU0UgfCByb3dbLCAxXSA9PSBUUlVFKSB7CiAgICAgIGdyb3VwX2luZm9ybWF0aW9uIDwtIHJvd1tncm91cF9rZWVwZXJzXQogICAgICBjb2xuYW1lcyhncm91cF9pbmZvcm1hdGlvbikgPC0gZ3JvdXBfY29sbmFtZXMKICAgICAgZ3JvdXBfaW5mb3JtYXRpb25bWyJJRCJdXSA8LSBzdWIocGF0dGVybj0iXi4qIEdOPShcXHcrKSAuKiQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudD0iXFwxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeD1ncm91cF9pbmZvcm1hdGlvbltbIkdyb3VwIERlc2NyaXB0aW9uIl1dKQogICAgICBncm91cF9hY2Nlc3Npb24gPC0gZ3JvdXBfaW5mb3JtYXRpb25bWyJQcm90ZWluIEdyb3VwIElEIl1dCiAgICAgIGdyb3VwX2xpc3QgPC0gbGlzdCgKICAgICAgICAic3VtbWFyeSIgPSBncm91cF9pbmZvcm1hdGlvbiwKICAgICAgICAiZGF0YSIgPSBsaXN0KCkpCiAgICAgIGdyb3VwX2RhdGFbW2dyb3VwX2FjY2Vzc2lvbl1dIDwtIGdyb3VwX2xpc3QKICAgICAgbmV4dAogICAgfQogICAgIyMgV2hlbiB0aGUgMm5kIGNvbHVtbiBpcyBGQUxTRSwgdGhlbiB0aGlzIGRlZmluZWQgYSBwcm90ZWluIGluIHRoZSBncm91cC4KICAgICMjIFRoZSBwcm90ZWluIGRhdGEgc3RydWN0dXJlIGlzIGxpa2VseSB0aGUgbW9zdCBpbnRlcmVzdGluZy4KICAgIGlmIChyb3dbLCAyXSA9PSBGQUxTRSB8IHJvd1ssIDJdID09IFRSVUUpIHsKICAgICAgcHJvdGVpbl9pbmZvcm1hdGlvbiA8LSByb3dbcHJvdGVpbl9rZWVwZXJzXQogICAgICBjb2xuYW1lcyhwcm90ZWluX2luZm9ybWF0aW9uKSA8LSBwcm90ZWluX2NvbG5hbWVzCiAgICAgIHByb3RlaW5faW5mb3JtYXRpb25bWyJJRCJdXSA8LSBzdWIocGF0dGVybj0iXi4qIEdOPShcXHcrKSAuKiQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50PSJcXDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg9cHJvdGVpbl9pbmZvcm1hdGlvbltbIkRlc2NyaXB0aW9uIl1dKQogICAgICBwcm90ZWluX2FjY2Vzc2lvbiA8LSBwcm90ZWluX2luZm9ybWF0aW9uW1siQWNjZXNzaW9uIl1dCiAgICAgIHByb3RlaW5fbGlzdCA8LSBsaXN0KAogICAgICAgICJzdW1tYXJ5IiA9IHByb3RlaW5faW5mb3JtYXRpb24sCiAgICAgICAgImRhdGEiID0gZGF0YS5mcmFtZSgpKQogICAgICBncm91cF9kYXRhW1tncm91cF9hY2Nlc3Npb25dXVtbImRhdGEiXV1bW3Byb3RlaW5fYWNjZXNzaW9uXV0gPC0gcHJvdGVpbl9saXN0CiAgICAgIG5leHQKICAgIH0KICAgICMjIFdoZW4gdGhlIDNyZCBncm91cCBpcyBGQUxTRSwgdGhlbiB0aGlzIGFkZHMgYSBwZXB0aWRlLgogICAgIyMgVGhlIHBlcHRpZGUgZGF0YSBzdHJ1Y3R1cmUgaXMgdGhlIG1vc3QgZGV0YWlsZWQsIGJ1dCBwcm9iYWJseSBub3QgdGhlIG1vc3QgaW50ZXJlc3RpbmcuCiAgICBpZiAocm93WywgM10gPT0gRkFMU0UgfCByb3dbLCAzXSA9PSBUUlVFKSB7CiAgICAgIHBlcHRpZGVfaW5mb3JtYXRpb24gPC0gcm93W3BlcHRpZGVfa2VlcGVyc10KICAgICAgY29sbmFtZXMocGVwdGlkZV9pbmZvcm1hdGlvbikgPC0gcGVwdGlkZV9jb2xuYW1lcwogICAgICBjdXJyZW50IDwtIGdyb3VwX2RhdGFbW2dyb3VwX2FjY2Vzc2lvbl1dW1siZGF0YSJdXVtbcHJvdGVpbl9hY2Nlc3Npb25dXVtbImRhdGEiXV0KICAgICAgbmV3IDwtIHJiaW5kKGN1cnJlbnQsIHBlcHRpZGVfaW5mb3JtYXRpb24pCiAgICAgIGdyb3VwX2RhdGFbW2dyb3VwX2FjY2Vzc2lvbl1dW1siZGF0YSJdXVtbcHJvdGVpbl9hY2Nlc3Npb25dXVtbImRhdGEiXV0gPC0gbmV3CiAgICAgIG5leHQKICAgIH0KICB9ICMjIEVuZCBpdGVyYXRpbmcgb3ZlciBldmVyIHJvdyBvZiB0aGlzIHVuaG9seSBzdHVwaWQgZGF0YSBzdHJ1Y3R1cmUuCiAgY2xvc2UoYmFyKQogIG1lc3NhZ2UoIkZpbmlzaGVkIHBhcnNpbmcsIHJlb3JnYW5pemluZyB0aGUgcHJvdGVpbiBkYXRhLiIpCiAgcHJvdGVpbl9kZiA8LSBkYXRhLmZyYW1lKCkKICBwZXB0aWRlX2RmIDwtIGRhdGEuZnJhbWUoKQogIHByb3RlaW5fbmFtZXMgPC0gYygpCiAgbWVzc2FnZShwYXN0ZTAoIlN0YXJ0aW5nIHRvIGl0ZXJhdGUgb3ZlciAiLCBsZW5ndGgoZ3JvdXBfZGF0YSksICAiIGdyb3Vwcy4iKSkKICBiYXIgPC0gdXRpbHM6OnR4dFByb2dyZXNzQmFyKHN0eWxlPTMpCiAgZm9yIChnIGluIDE6bGVuZ3RoKGdyb3VwX2RhdGEpKSB7CiAgICBwY3RfZG9uZSA8LSBnIC8gbGVuZ3RoKGdyb3VwX2RhdGEpCiAgICBzZXRUeHRQcm9ncmVzc0JhcihiYXIsIHBjdF9kb25lKQogICAgZ3JvdXAgPC0gYXMuY2hhcmFjdGVyKG5hbWVzKGdyb3VwX2RhdGEpW2ddKQogICAgcHJvdGVpbl9ncm91cCA8LSBncm91cF9kYXRhW1tncm91cF1dW1siZGF0YSJdXQogICAgcHJvdGVpbl9hY2Nlc3Npb25zIDwtIG5hbWVzKHByb3RlaW5fZ3JvdXApCiAgICBmb3IgKHAgaW4gMTpsZW5ndGgocHJvdGVpbl9hY2Nlc3Npb25zKSkgewogICAgICBwcm90ZWluIDwtIHByb3RlaW5fYWNjZXNzaW9uc1twXQogICAgICBwcm90ZWluX25hbWVzIDwtIGMocHJvdGVpbl9uYW1lcywgcHJvdGVpbikKICAgICAgcHJvdGVpbl9zdW1tYXJ5IDwtIGdyb3VwX2RhdGFbW2dyb3VwXV1bWyJkYXRhIl1dW1twcm90ZWluXV1bWyJzdW1tYXJ5Il1dCiAgICAgIHByb3RlaW5fZGYgPC0gcmJpbmQocHJvdGVpbl9kZiwgcHJvdGVpbl9zdW1tYXJ5KQogICAgICBwZXB0aWRlX2RhdGEgPC0gZ3JvdXBfZGF0YVtbZ3JvdXBdXVtbImRhdGEiXV1bW3Byb3RlaW5dXVtbImRhdGEiXV0KICAgICAgIyMgcGVwdGlkZV9kZiA8LSByYmluZChwZXB0aWRlX2RmLCBwZXB0aWRlX2RhdGEpCiAgICB9CiAgfSAjIyBFbmQgb2YgdGhlIGZvciBsb29wCiAgY2xvc2UoYmFyKQogIHJldGxpc3QgPC0gbGlzdCgKICAgICJncm91cF9kYXRhIiA9IGdyb3VwX2RhdGEsCiAgICAicHJvdGVpbl9kYXRhIiA9IHByb3RlaW5fZGYsCiAgICAicGVwdGlkZV9kYXRhIiA9IHBlcHRpZGVfZGYpCiAgcmV0dXJuKHJldGxpc3QpCn0KCiMjeGxzeF9maWxlIDwtICJwcmV2aW91c19yZXN1bHRzLzIwMTdfMDgxMUJyaWtlbk11bHRpQ29uc2Vuc3VzLnhsc3giCnhsc3hfZmlsZSA8LSAicHJldmlvdXNfcmVzdWx0cy8yMDE3XzExMDFCcmlrZW5NdWx0aV9QRV9QUEVfQ29tcGxldGUueGxzeCIKbGVzc19kaWZmaWN1bHQgPC0gcGFyc2VfZGlmZmljdWx0X2V4Y2VsKHhsc3hfZmlsZSkKYGBgCgpUaGUgZnVuY3Rpb24gYWJvdmUgaXMgbm90IGltbWVkaWF0ZWx5IGhlbHBmdWwsIGFzIGl0IG9ubHkgd3JhbmdsZXMgdGhlIGNyYXp5CmV4Y2VsIGludG8gYSBsZXNzLWNyYXp5IGRhdGEgc3RydWN0dXJlLCBidXQgaWYgd2Ugd2lzaCB0byBncmFwaCB0aGUgZGF0YSBvciBwbGF5CndpdGggaXQsIHdlIG5lZWQgdG8gZXh0cmFjdCB0aGUgZWxlbWVudHMgb2YgaW50ZXJlc3QuICBGb3IgdGhlIG1vbWVudCB0aG9zZSBhcmUKcHJpbWFyaWx5IHRoZSBwZXB0aWRlIGZyYWdtZW50cyBhbmQgd2hldGhlciB0aGV5IHdlcmUgZm91bmQgaW4gdGhlIHRyeXBzaW4KZGlnZXN0aW9ucywgY2h5bW90cnlwc2luIGRpZ2VzdGlvbnMsIG9yIGJvdGguCgpUaGlzIGRhdGEgZnJhbWUgbm93IGNvbnRhaW5zIGV2ZXJ5dGhpbmcgd2UgYXJlIGxpa2VseSB0byB3YW50IHRvIHZpc3VhbGl6ZS4KCiMjIENsZWFuaW5nIHRoZSBkYXRhIGZyYW1lCgpVbmZvcnR1bmF0ZWx5LCB0aGlzIGRhdGEgc3RydWN0dXJlIGFsc28gc3VmZmVycyBmcm9tIGEgY291cGxlIHdlYWtuZXNzZXM6CgoxLiAgVGhlIHByb3RlaW4gSURzIGFyZSBub3QgdW5pcXVlIChiZWNhdXNlIG9mIHRoZSBncm91cHMpCjIuICBUaGUgY29sdW1uIG5hbWVzIGZyb20gRXhjZWwgYXJlIGluc2FuZSAocHVuY3R1YXRpb24sIHNwZWNpYWwgY2hhcmFjdGVycywgYW5kIHJlYWxseSBsb25nKQozLiAgRXhjZWwgbGVmdCB0aGUgbnVtZXJpYyBjb2x1bW5zIG9mIGRhdGEgYXMgY2hhcmFjdGVycywgbm90IG51bWJlcnMhCgpUaGVyZWZvcmUsIEkgd2lsbCB0YWtlIGEgbW9tZW50IHRvIGZpeCB0aGVzZSBwcm9ibGVtcyBiZWZvcmUgdHJ5aW5nIGFueSBwbG90cy4KCmBgYHtyIGRmX2NsZWFuaW5nfQojIyBTZXQgc29tZSByZWFzb25hYmxlIHJvdyBuYW1lcwpwcm90ZWluX2RmIDwtIGxlc3NfZGlmZmljdWx0W1sicHJvdGVpbl9kYXRhIl1dCgpyb3duYW1lcyhwcm90ZWluX2RmKSA8LSBtYWtlLm5hbWVzKHByb3RlaW5fbmFtZXMsIHVuaXF1ZT1UUlVFKQojIyBTZXQgdGhlIGNvbHVtbiBuYW1lcyB0byBzb21ldGhpbmcgbGVnaWJsZS4KIyMgRWFjaCBsaW5lIGRlbm90ZXMgbXkgbWVudGFsIG9yZ2FuaXphdGlvbmFsIHVuaXQKbmV3X2NvbG5hbWVzIDwtIGMoIm1hc2NvdF9mZHIiLCAic2VxdWVzdF9mZHIiLCAibWFzdGVyIiwgImFjY2Vzc2lvbiIsICJkZXNjcmlwdGlvbiIsCiAgICAgICAgICAgICAgICAgICJtYXNjb3RfcSIsICJzZXF1ZXN0X3EiLCAiY292ZXJhZ2UiLCAiY29udGFtaW5hbnQiLCAibWFya2VkX2FzIiwKICAgICAgICAgICAgICAgICAgIm51bV9wZXB0aWRlcyIsICJudW1fcHNtcyIsICJudW1fdW5pcXVlX3BlcCIsICJudW1fcHJvdF9ncm91cHMiLCAibnVtX2FhcyIsCiAgICAgICAgICAgICAgICAgICJtdyIsICJwaSIsICJtYXNjb3Rfc2NvcmUiLCAic2VxdWVzdF9zY29yZSIsICJudW1fcGVwdGlkZXNfbWFzY290IiwKICAgICAgICAgICAgICAgICAgIm51bV9wZXB0aWRlc19zZXF1ZXN0IiwgImJwIiwgImNjIiwgIm1mIiwgInBmYW1faWRzIiwKICAgICAgICAgICAgICAgICAgImVudHJlel9nZW5lX2lkIiwgImVuc2VtYmxfZ2VuZV9pZCIsICJnZW5lX3N5bWJvbCIsICJjaHJvbW9zb21lIiwgImtlZ2ciLAogICAgICAgICAgICAgICAgICAid2lraXBhdGh3YXlzIiwgImZvdW5kX3RyeXBzaW5fbHlzY19jZiIsICJmb3VuZF90cnlwc2luX2x5c2Nfd2NsIiwgImZvdW5kX2NoeW1vdHJ5cHNpbl9jZiIsICJmb3VuZF9jaHltb3RyeXBzaW5fd2NsIiwKICAgICAgICAgICAgICAgICAgIm1vZGlmaWNhdGlvbnMiLCAiaWQiKQpjb2xuYW1lcyhwcm90ZWluX2RmKSA8LSBuZXdfY29sbmFtZXMKIyMgTm93IG1ha2Ugc3VyZSB0aGUgY29sdW1ucyB3aGljaCBzaG91bGQgYmUgbnVtZXJpYywgYXJlIG51bWVyaWMuCm51bWVyaWNfY29scyA8LSBjKCJtYXNjb3RfcSIsICJzZXF1ZXN0X3EiLCAiY292ZXJhZ2UiLCAibnVtX3BlcHRpZGVzIiwgIm51bV9wc21zIiwKICAgICAgICAgICAgICAgICAgIm51bV91bmlxdWVfcGVwIiwgIm51bV9wcm90X2dyb3VwcyIsICJudW1fYWFzIiwgIm13IiwgInBpIiwKICAgICAgICAgICAgICAgICAgIm1hc2NvdF9zY29yZSIsICJzZXF1ZXN0X3Njb3JlIiwKICAgICAgICAgICAgICAgICAgIm51bV9wZXB0aWRlc19tYXNjb3QiLCAibnVtX3BlcHRpZGVzX3NlcXVlc3QiKQpmb3IgKGNvbCBpbiBudW1lcmljX2NvbHMpIHsKICBwcm90ZWluX2RmW1tjb2xdXSA8LSBhcy5udW1lcmljKHByb3RlaW5fZGZbW2NvbF1dKQp9CmZhY3Rvcl9jb2xzIDwtIGMoImZvdW5kX3RyeXBzaW5fbHlzY19jZiIsICJmb3VuZF90cnlwc2luX2x5c2Nfd2NsIiwKICAgICAgICAgICAgICAgICAiZm91bmRfY2h5bW90cnlwc2luX2NmIiwgImZvdW5kX2NoeW1vdHJ5cHNpbl93Y2wiKQpmb3IgKGNvbCBpbiBmYWN0b3JfY29scykgewogIHByb3RlaW5fZGZbW2NvbF1dIDwtIGFzLmZhY3Rvcihwcm90ZWluX2RmW1tjb2xdXSkKfQojIyBGaW5hbGx5LCBzZXQgYSAnc3RhdGUnIGNvbHVtbiBkZXNjcmliaW5nIHRoZSA0IGNvbHVtbnMgb2YgY2h5bW90cnlwc2luL3RyeXBzaW4gZGlnZXN0aW9ucy4KcHJvdGVpbl9kZltbInN0YXRlIl1dIDwtICJhbWJpZ3VvdXMiCiMjIElmIHNvbWV0aGluZyBpcyBmb3VuZCBpbiBvbmUgY2h5bW8gdHJ5cHNpbiwgYnV0IGluIG5laXRoZXIgdHJ5cHNpbiwgc2V0IGl0IHRvIGNoeW1vX29ubHkuCmNoeW1vX2hpdHMgPC0gKHByb3RlaW5fZGZbWyJmb3VuZF9jaHltb3RyeXBzaW5fY2YiXV0gPT0gIkhpZ2giIHwgcHJvdGVpbl9kZltbImZvdW5kX2NoeW1vdHJ5cHNpbl93Y2wiXV0gPT0gIkhpZ2giKSAmCiAgKHByb3RlaW5fZGZbWyJmb3VuZF90cnlwc2luX2x5c2NfY2YiXV0gIT0gIkhpZ2giICYgcHJvdGVpbl9kZltbImZvdW5kX3RyeXBzaW5fbHlzY193Y2wiXV0gIT0gIkhpZ2giKQpwcm90ZWluX2RmW2NoeW1vX2hpdHMsICJzdGF0ZSJdIDwtICJjaHltb19vbmx5IgojIyBDb252ZXJzZWx5LCBpZiBmb3VuZCBpbiB0cnlwc2luIGJ1dCBub3QgY2h5bW8sIHNldCBpdCB0byB0cnlwX29ubHkuCnRyeXBfaGl0cyA8LSAocHJvdGVpbl9kZltbImZvdW5kX3RyeXBzaW5fbHlzY19jZiJdXSA9PSAiSGlnaCIgfCBwcm90ZWluX2RmW1siZm91bmRfdHJ5cHNpbl9seXNjX3djbCJdXSA9PSAiSGlnaCIpICYKICAocHJvdGVpbl9kZltbImZvdW5kX2NoeW1vdHJ5cHNpbl9jZiJdXSAhPSAiSGlnaCIgJiBwcm90ZWluX2RmW1siZm91bmRfY2h5bW90cnlwc2luX3djbCJdXSAhPSAiSGlnaCIpCnByb3RlaW5fZGZbdHJ5cF9oaXRzLCAic3RhdGUiXSA8LSAidHJ5cF9vbmx5Igpub19oaXRzIDwtIHByb3RlaW5fZGZbWyJmb3VuZF90cnlwc2luX2x5c2NfY2YiXV0gPT0gIk5vdCBGb3VuZCIgJgogIHByb3RlaW5fZGZbWyJmb3VuZF90cnlwc2luX2x5c2Nfd2NsIl1dID09ICJOb3QgRm91bmQiICYKICBwcm90ZWluX2RmW1siZm91bmRfY2h5bW90cnlwc2luX2NmIl1dID09ICJOb3QgRm91bmQiICYKICBwcm90ZWluX2RmW1siZm91bmRfY2h5bW90cnlwc2luX3djbCJdXSA9PSAiTm90IEZvdW5kIgpwcm90ZWluX2RmW25vX2hpdHMsICJzdGF0ZSJdIDwtICJOb25lIgpwcm90ZWluX2RmW1sic3RhdGUiXV0gPC0gYXMuZmFjdG9yKHByb3RlaW5fZGZbWyJzdGF0ZSJdXSkKCmNoeW1vX2RmIDwtIHByb3RlaW5fZGZbY2h5bW9faGl0cywgXQp0cnlwX2RmIDwtIHByb3RlaW5fZGZbdHJ5cF9oaXRzLCBdCmBgYAoKIyMgTWFrZSBhIGNvdXBsZSBwbG90cwoKTm93IHRoYXQgdGhlIGRhdGEgaGFzIGJlZW4gd3JhbmdsZWQsIHdlIGNhbiB1c2UgdGhlIHZhcmlvdXMgUiBwbG90dGVycyB0byBsb29rCmF0IHRoZSBkYXRhIHJlbGF0aXZlbHkgcXVpY2tseSBhbmQgZWFzaWx5LgoKYGBge3IgcGxvdHN9CmxpYnJhcnkoZ2dwbG90MikKY292ZXJhZ2Vfd3J0X3BpIDwtIGdncGxvdChwcm90ZWluX2RmLCBhZXNfc3RyaW5nKHg9InBpIiwgeT0iY292ZXJhZ2UiLCBjb2xvdXI9InN0YXRlIikpICsKICBnZW9tX3BvaW50KGFscGhhPTAuNiwgc2l6ZT0yKSArCiAgZ2VvbV9kZW5zaXR5XzJkKCkKCmNvdmVyYWdlX3dydF9tdyA8LSBnZ3Bsb3QocHJvdGVpbl9kZiwgYWVzX3N0cmluZyh4PSJtdyIsIHk9ImNvdmVyYWdlIiwgY29sb3VyPSJzdGF0ZSIpKSArCiAgZ2VvbV9wb2ludChhbHBoYT0wLjYsIHNpemU9MikgKwogIGdlb21fZGVuc2l0eV8yZCgpCgpwcm90ZWluX2RmJGxvZ21hc2NvdCA8LSBsb2cyKHByb3RlaW5fZGYkbWFzY290X3Njb3JlKQpzY29yZXNfYnlfc3RhdGUgPC0gZ2dwbG90KHByb3RlaW5fZGYsIGFlc19zdHJpbmcoeD0ic3RhdGUiLCB5PSJsb2dtYXNjb3QiKSkgKwogIGdlb21fYm94cGxvdChhZXNfc3RyaW5nKGZpbGw9InN0YXRlIikpCmBgYAoKIyMjIENvdmVyYWdlIHZzLiBwSQoKWWFuIHN1Z2dlc3RlZCB0aGF0IHBlcHRpZGVzIHdpdGggbG93LXBJcyB3b3VsZCBiZSBsZXNzIGNvdmVyZWQsIGVzcGVjaWFsbHkgaW4KdGhlIGNoeW1vdHJ5cHNpbiBzYW1wbGVzLgoKYGBge3IgY292X3BpfQpwcChmaWxlPSJpbWFnZXMvY292ZXJhZ2Vfd3J0X3BpLnBuZyIpCmNvdmVyYWdlX3dydF9waQpkZXYub2ZmKCkKIyMgVG8gbWUsIGl0IGxvb2tzIGxpa2UgdGhlcmUgbWlnaHQgYmUgc29tZXRoaW5nIHRvIHRoYXQgaWRlYS4KYGBgCgojIyMgQ292ZXJhZ2UgdnMuIE1vbGVjdWxhciBXZWlnaHQKCk1heWJlIHRoZXJlIGlzIGEgdHJlbmQgb2YgY292ZXJhZ2UgYW5kIG1vbGVjdWxhciB3ZWlnaHQgYnkgc2FtcGxlLXR5cGUuCgpgYGB7ciBjb3ZfbXd9CnBwKGZpbGU9ImltYWdlcy9jb3ZlcmFnZV93cnRfbXcucG5nIikKY292ZXJhZ2Vfd3J0X213CmRldi5vZmYoKQojIyBJdCBsb29rcyB0byBtZSB0aGF0IHRoZSB0cnlwc2luIGlzIHNsaWdodGx5IGJldHRlciB0aGFuIGNoeW1vdHJ5cHNpbi4KIyMgSXQgaXMgbm90IGNsZWFyIGluIHRoZSBleGNlbCwgYnV0IEkgcHJlc3VtZSB0aGlzIGlzIGluIGtEYS4KYGBgCgojIyMgTWFzY290IHNjb3JlcwoKQSBxdWljayBib3hwbG90IHNob3dpbmcgbWFzY290IHNjb3JlcyBieSB3aGF0IHdhcyBvYnNlcnZlZC4KCmBgYHtyIG1hc2NvdH0Kc2NvcmVzX2J5X3N0YXRlCmBgYAoKYGBge3IgeHJlZl9hbm5vdGF0aW9uc30KYWxsX2RlIDwtIHJlYWQudGFibGUoImxpbW1hX3Jlc3VsdC5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPSJcdCIpCmNvbG5hbWVzKGFsbF9kZSkgPC0gYygiSUQiLCAibG9nRkMiLCAiQXZlRXhwciIsICJhZGouUC5WYWwiLCAiYWJicmV2X2lkIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfbGVuZ3RoIiwgInR5cGUiKQphbGxfZGUgPC0gbWVyZ2UoYWxsX2RlLCBtdGJfYW5ub3RhdGlvbnMsIGJ5Lng9IklEIiwgYnkueT0iSUQiKQpkaW0oYWxsX2RlKQoKcGVfaWRzIDwtIHJlYWQudGFibGUoInJlZmVyZW5jZS9hbm5vdGF0ZWRfcGVfZ2VuZXMudHh0IikKY29sbmFtZXMocGVfaWRzKSA8LSAibG9jdXNfdGFnIgpwZV9hbm5vdGF0aW9ucyA8LSBtZXJnZShwZV9pZHMsIG10Yl9hbm5vdGF0aW9ucywgYnk9ImxvY3VzX3RhZyIpCnJvd25hbWVzKHBlX2Fubm90YXRpb25zKSA8LSBwZV9hbm5vdGF0aW9uc1tbIklEIl1dCmRpbShwZV9hbm5vdGF0aW9ucykKCnVuaXByb3RfYW5ub3QgPC0gbG9hZF91bmlwcm90X2Fubm90YXRpb25zKGZpbGU9InJlZmVyZW5jZS91bmlwcm90XzNBVVAwMDAwMDE1ODQudHh0Lmd6IikKZGltKHVuaXByb3RfYW5ub3QpCgp1bmlwcm90X3JuYSA8LSBtZXJnZShhbGxfZGUsIHVuaXByb3RfYW5ub3QsIGJ5Lng9IklEIiwgYnkueT0ibG9jaSIpCmRpbSh1bmlwcm90X3JuYSkKCnVuaXByb3RfcGUgPC0gbWVyZ2UocGVfYW5ub3RhdGlvbnMsIHVuaXByb3RfYW5ub3QsIGJ5Lng9IklEIiwgYnkueT0ibG9jaSIpCmRpbSh1bmlwcm90X3BlKQp1bmlwcm90X3BlX3BlcHRpZGVzIDwtIG1lcmdlKHVuaXByb3RfYW5ub3QsIHByb3RlaW5fZGYsIGJ5Lng9InByaW1hcnlfYWNjZXNzaW9ucyIsIGJ5Lnk9ImFjY2Vzc2lvbiIpCnVuaXByb3RfcGVfcGVwdGlkZXMgPC0gbWVyZ2UodW5pcHJvdF9wZV9wZXB0aWRlcywgcGVfaWRzLCBieS54PSJsb2NpIiwgYnkueT0ibG9jdXNfdGFnIikKZGltKHVuaXByb3RfcGVfcGVwdGlkZXMpCgp1bmlwcm90X3JuYV9wcm90ZWluIDwtIG1lcmdlKHVuaXByb3Rfcm5hLCBwcm90ZWluX2RmLCBieS54PSJwcmltYXJ5X2FjY2Vzc2lvbnMiLCBieS55PSJhY2Nlc3Npb24iKQpkaW0ocHJvdGVpbl9kZikKZGltKHVuaXByb3Rfcm5hX3Byb3RlaW4pCgp1bmlwcm90X3JuYV9wZSA8LSBtZXJnZSh1bmlwcm90X3BlLCB1bmlwcm90X3JuYV9wcm90ZWluLCBieT0iSUQiKQpkaW0odW5pcHJvdF9ybmFfcGUpCgojIyBUaGlzIGlzIGV4aGF1c3RpbmcsIEkgd2lsbCBjYWxsIHRoZXNlIGJpZyBhbmQgbGl0dGxlIGZyb20gbm93IG9uCmJpZyA8LSB1bmlwcm90X3JuYV9wcm90ZWluCnJvd25hbWVzKGJpZykgPC0gbWFrZS5uYW1lcyhiaWckSUQsIHVuaXF1ZT1UUlVFKQpvcmRlcmVkIDwtIG9yZGVyKHJvd25hbWVzKGJpZykpCmJpZyA8LSBiaWdbb3JkZXJlZCwgXQpsaXR0bGUgPC0gdW5pcHJvdF9ybmFfcGUKcm93bmFtZXMobGl0dGxlKSA8LSBtYWtlLm5hbWVzKGxpdHRsZSRJRCwgdW5pcXVlPVRSVUUpCm9yZGVyZWQgPC0gb3JkZXIocm93bmFtZXMobGl0dGxlKSkKbGl0dGxlIDwtIGxpdHRsZVtvcmRlcmVkLCBdCnNoYXJlZCA8LSByb3duYW1lcyhiaWcpICVpbiUgcm93bmFtZXMobGl0dGxlKQpgYGAKCmBgYHtyIGV4dHJhY3Rfcm5hfQojIyBwZV9kZV9hbm5vdCA8LSBtZXJnZShwZV9kZSwgbXRiX2Fubm90YXRpb25zLCBieT0ibG9jdXNfdGFnIikKIyMgVGhlIGNvbnRyYXN0IGlzIHdyaXR0ZW4gYXMgd3QgLSBkZWx0YSwgc28gYWRkIGJhY2sgdGhlIGxvZ0ZDIEkgdGhpbmsKIyMgSG9wZWZ1bGx5IEkgZGlkIG5vdCByZXZlcnNlIHRoaXMgaW4gbXkgaGVhZC4KYmlnJGF2ZV9taW51c19sb2cgPC0gYmlnJEF2ZUV4cHIgLSBiaWckbG9nRkMKYmlnJGF2ZV9taW51c19sb2cgPC0gYmlnJEF2ZUV4cHIgLSBiaWckbG9nRkMKYmlnJHBzZXVkb19ycGttIDwtIChiaWckYXZlX21pbnVzX2xvZyAvIGJpZyR3aWR0aCkgKiAxMDAwCm1heGltdW1fcnBrbSA8LSBtYXgoYmlnJHBzZXVkb19ycGttKQpiaWckZXhwcmVzc192c19tYXggPC0gYmlnJHBzZXVkb19ycGttIC8gbWF4aW11bV9ycGttCiMjIFNpbmNlIHdlIGNvbnN0YW50IG9yZGVyZWQgdGhlIGRhdGFmcmFtZXMgYWJvdmUsIHRoaXMgaXMgdmFsaWQuCmxpdHRsZSRwc2V1ZG9fcnBrbSA8LSBiaWckcHNldWRvX3Jwa21bc2hhcmVkXQpsaXR0bGUkZXhwcmVzc192c19tYXggPC0gYmlnJGV4cHJlc3NfdnNfbWF4W3NoYXJlZF0KCndyaXRlLmNzdih4PWxpdHRsZSwgZmlsZT0icGVfcmVsYXRpdmVfZXhwcmVzc2lvbl9hbm5vdGF0aW9uLTIwMTcxMjA1LmNzdiIpCgpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeShnZ3Bsb3QyKQp0ZXN0IDwtIGxpc3QoCiAgImFsbF9wZXB0aWRlcyIgPSBiaWckZXhwcmVzc192c19tYXgsCiAgInBlX3BlcHRpZGVzIiA9IGxpdHRsZSRleHByZXNzX3ZzX21heCkKbXVsdGkgPC0gcGxvdF9tdWx0aWhpc3RvZ3JhbSh0ZXN0KQptdWx0aSRwbG90CgpycGttX3ZzX3BzbXMgPC0gYmlnWywgYygicHNldWRvX3Jwa20iLCAibnVtX3BzbXMiKV0KbGl0dGxlX3Jwa21fdnNfcHNtcyA8LSBsaXR0bGVbLCBjKCJwc2V1ZG9fcnBrbSIsICJudW1fcHNtcyIpXQpycGttX3ZzX3BzbXMkbnVtX3BzbXMgPC0gbG9nMihycGttX3ZzX3BzbXMkbnVtX3BzbXMgKyAxKQpsaXR0bGVfcnBrbV92c19wc21zJG51bV9wc21zIDwtIGxvZzIobGl0dGxlX3Jwa21fdnNfcHNtcyRudW1fcHNtcyArIDEpCnJwa21fcHNtc19saW5lYXIgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihycGttX3ZzX3BzbXMpCnJwa21fcHNtc19saW5lYXIkc2NhdHRlcgpycGttX3BzbXNfbGluZWFyJGNvcgpycGttX3BzbXNfbGluZWFyJGxtX3JzcQpiaWdfbGl0dGxlIDwtIGdncGxvdChkYXRhPXJwa21fdnNfcHNtcywgYWVzX3N0cmluZyh4PSJwc2V1ZG9fcnBrbSIsIHk9Im51bV9wc21zIikpICsKICBnZW9tX3BvaW50KCkKYmlnX2xpdHRsZQpiaWdfbGl0dGxlIDwtIGJpZ19saXR0bGUgKwogIGdlb21fcG9pbnQoZGF0YT1saXR0bGVfcnBrbV92c19wc21zLCBhZXNfc3RyaW5nKHg9InBzZXVkb19ycGttIiwgeT0ibnVtX3BzbXMiKSwgY29sb3VyPSJyZWQiKQpwcChmaWxlPSJycGttX3ZzX3BzbXMucG5nIikKYmlnX2xpdHRsZQpkZXYub2ZmKCkKCnJwa21fdnNfcGVwdGlkZXMgPC0gYmlnWywgYygicHNldWRvX3Jwa20iLCAibnVtX3BlcHRpZGVzIildCnJwa21fcGVwdGlkZXNfbGluZWFyIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIocnBrbV92c19wZXB0aWRlcykKcnBrbV9wZXB0aWRlc19saW5lYXIkc2NhdHRlcgpycGttX3BlcHRpZGVzX2xpbmVhciRjb3IKcnBrbV9wc21zX2xpbmVhciRsbV9yc3EKbGl0dGxlX3Jwa21fdnNfcGVwdGlkZXMgPC0gbGl0dGxlWywgYygicHNldWRvX3Jwa20iLCAibnVtX3BlcHRpZGVzIildCmJpZ19saXR0bGUgPC0gZ2dwbG90KGRhdGE9cnBrbV92c19wZXB0aWRlcywgYWVzX3N0cmluZyh4PSJwc2V1ZG9fcnBrbSIsIHk9Im51bV9wZXB0aWRlcyIpKSArCiAgZ2VvbV9wb2ludCgpCmJpZ19saXR0bGUKYmlnX2xpdHRsZSA8LSBiaWdfbGl0dGxlICsKICBnZW9tX3BvaW50KGRhdGE9bGl0dGxlX3Jwa21fdnNfcGVwdGlkZXMsIGFlc19zdHJpbmcoeD0icHNldWRvX3Jwa20iLCB5PSJudW1fcGVwdGlkZXMiKSwgY29sb3VyPSJyZWQiKQpiaWdfbGl0dGxlCgpycGttX3ZzX2NvdmVyYWdlIDwtIGJpZ1ssIGMoInBzZXVkb19ycGttIiwgImNvdmVyYWdlIildCnJwa21fY292ZXJhZ2VfbGluZWFyIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIocnBrbV92c19jb3ZlcmFnZSkKcnBrbV9jb3ZlcmFnZV9saW5lYXIkc2NhdHRlcgpycGttX2NvdmVyYWdlX2xpbmVhciRjb3IKcnBrbV9jb3ZlcmFnZV9saW5lYXIkbG1fcnNxCmxpdHRsZV9ycGttX3ZzX2NvdmVyYWdlIDwtIGxpdHRsZVssIGMoInBzZXVkb19ycGttIiwgImNvdmVyYWdlIildCmJpZ19saXR0bGUgPC0gZ2dwbG90KGRhdGE9cnBrbV92c19jb3ZlcmFnZSwgYWVzX3N0cmluZyh4PSJwc2V1ZG9fcnBrbSIsIHk9ImNvdmVyYWdlIikpICsKICBnZW9tX3BvaW50KCkKYmlnX2xpdHRsZQpiaWdfbGl0dGxlIDwtIGJpZ19saXR0bGUgKwogIGdlb21fcG9pbnQoZGF0YT1saXR0bGVfcnBrbV92c19jb3ZlcmFnZSwgYWVzX3N0cmluZyh4PSJwc2V1ZG9fcnBrbSIsIHk9ImNvdmVyYWdlIiksIGNvbG91cj0icmVkIikKYmlnX2xpdHRsZQpgYGAKCmBgYHtyIHNhdmVtZX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAK