Changed the names of the sequences to allow for the sequencing ids that Sarah has used.

source("../genomics/scripts/lab_helpers.R")

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
lab <- read_db("Laboratory")
library(readr)

See the jupyter notebook seq_processing for the amphiprion side of this protocol. Start there.

Create an index file for the Pools that is tab separated done

# read baits table
baits <- lab %>%
  tbl("baits") %>% 
  collect() %>% 
  select(baits_id, seq)
# read PCR table
pcr <- lab %>% 
  tbl("pcr") %>% 
  collect() %>% 
  filter(bait_id %in% baits$baits_id) %>% 
  select(pcr_id, bait_id, index)
# join pcr_id and index to seq id
pools <- left_join(pcr, baits, by = c("bait_id" = "baits_id")) %>% 
  select(seq, pcr_id, index)
# pull in the barcodes for illumina indexes
index <- lab %>% 
  tbl("illumina") %>% 
  collect()
# join the barcodes to the seq and pcr ids
pools <- left_join(pools, index, by = c("index" = "index_num")) %>% 
  select(seq, pcr_id, index_code)
# create a list of the multiple seqs
seqs <- select(pools, seq) %>% 
  distinct()
for(i in seq(seqs$seq)){
  x <- pools %>% 
  filter(seq == seqs$seq[i]) %>% 
  select(pcr_id, index_code)
# write the files for amphiprion
# readr::write_tsv(x, path = paste0("index-", seqs$seq[i], ".tsv"), col_names = F)
}

Move the files from the laptop to amphiprion using the fetch program, place the index files in the log folder for each seq ** done**
See Michelle if you need a serial number for Fetch

Create a names file for each pool done

The names have to be species, underscore and then the sample identifier, so APCL_L5432 for ligation_id L5432

# read the ligations
ligs <- lab %>% 
  tbl("ligation") %>% 
  filter(pool %in% pools$pcr_id) %>% 
  select(ligation_id, barcode_num, pool) %>% 
  collect()
Warning messages:
1: Unknown or uninitialised column: 'pool_dir'. 
2: Unknown or uninitialised column: 'pool_dir'. 
3: Unknown or uninitialised column: 'pool_dir'. 
4: Unknown or uninitialised column: 'pool_dir'. 
# read the barcodes
barcode <- lab %>% 
  tbl("barcodes") %>% 
  collect()
# join the ligation_id and pool ids to the barcodes
ligs <- left_join(ligs, barcode, by = "barcode_num")
# join the ligs to the seq_ids
ligs <- left_join(ligs, pools, by = c("pool" = "pcr_id")) %>% 
  # adjust the ligation name for dDocent
  mutate(name = paste0("APCL_", ligation_id, ".F")) %>% 
  select(seq, pool, name, barcode) %>% 
# reduce the pool to only a number
    mutate(pool = substr(pool, 2,5))
# write files for amphiprion
# create a list of the multiple seqs
names <- select(ligs, pool) %>% 
  distinct()
# loop through all of the pools
for(i in seq(names$pool)){
  x <- ligs %>% 
  filter(pool == names$pool[i]) %>% 
  select(name, barcode)
# write the files for amphiprion
# readr::write_tsv(x, path = paste0("names_", names$pool[i], ".tsv"), col_names = F)
}

Move the files from the laptop to amphiprion using the fetch program, place the names files in the log folder for each seq done

Concatenate the results in the bcsplit folder - takes about a minute done

library(readr)
for (j in seqs$seq){
  y <- pools %>% 
    filter(seq == j)
  write_file("#!/bin/bash", path = paste0(j,"_cat_all.sh"), append = F)
  # add a line return
  write_file("\n", path = paste0(j,"_cat_all.sh"), append = T)
  for (i in seq(y$pcr_id)){
    z <- formatC(i, width = 2, flag = 0)
    # generate the code
    x <- paste("cat", paste0("./lane1/", y$pcr_id[i], "-read-1.fastq.gz"), paste0("./lane2/", y$pcr_id[i], "-read-1.fastq.gz"), ">",  paste0("../", z, "Pool/", y$pcr_id[i], ".fastq.gz"), sep = " ")
    # add the code to the file
    write_file(x, path = paste0(j,"_cat_all.sh"), append = T)  
    # add a line return
    write_file("\n", path = paste0(j,"_cat_all.sh"), append = T)
  }  
}

create scripts for all 48 pools to process radtags done

Move the scripts to amphiprion into the seq scripts folder with fetch

With fetch you can also highlight all of the scripts and click get info, execute instead of having to type in the chmod u+x command for each file.

process_radtags - use esc-R or ctrl- to “find and replace” in nano - takes about 2.5 hours for 4 pools and 192 samples

From the seq folder (18SEQ for example), run the process scripts, can run all 4 in separate windows (or all 48?)

write a script to generate command line to run process radtags scripts

for (j in seqs$seq){
  y <- pools %>% 
    filter(seq == j)
  write_file("#!/bin/bash", path = paste0(j,"_process_all.sh"), append = F)
  # add a line return
  write_file("\n", path = paste0(j,"_process_all.sh"), append = T)
  for (i in y$pcr_id){
    # generate the code
    x <- paste("nohup", paste0("./scripts/", i, "_process.sh &"), sep = " ")
    # add the code to the file
    write_file(x, path = paste0(j,"_process_all.sh"), append = T)  
    # add a line return
    write_file("\n", path = paste0(j,"_process_all.sh"), append = T)
  }  
}

started the last one at 9:45pm on Monday 9/24/2018 - should take about 5 hours done before 6am on Tuesday

Write text for moving files

for (j in seqs$seq){
  y <- pools %>% 
    filter(seq == j)
  write_file("#!/bin/bash", path = paste0(j,"_move_radlogs.sh"), append = F)
  # add a line return
  write_file("\n", path = paste0(j,"_move_radlogs.sh"), append = T)
  for (i in seq(y$pcr_id)){
    z <- formatC(i, width = 2, flag = 0)
    # generate the code
    x <- paste("mv", paste0(z, "Pool/process_radtags.log"), paste0("./logs/process", y$pcr_id[i], ".log"), sep = " ")
    # add the code to the file
    write_file(x, path = paste0(j,"_move_radlogs.sh"), append = T)  
    # add a line return
    write_file("\n", path = paste0(j,"_move_radlogs.sh"), append = T)
  }  
}

add the sequencing results to the database

# set to current sequencing run
wlab <- write_db("Laboratory")
Loading required package: DBI

Which samples failed?

Rename the process radtags output to sample names

write renaming text

library(readr)
for (j in seqs$seq){
  y <- pools %>% 
    filter(seq == j) %>% 
    arrange(pcr_id)
  write_file("#!/bin/bash", path = paste0(j,"_all_rename.sh"), append = F)
  # add a line return
  write_file("\n", path = paste0(j,"_all_rename.sh"), append = T)
  for (i in seq(y$pcr_id)){
    z <- formatC(i, width = 2, flag = 0)
    c <- substr(y$pcr_id[i], 2, 5)
    # generate the code
    a <- paste("cd", paste0(z, "Pool/"), sep = " ")
    # add the code to the file
    write_file(a, path = paste0(j,"_all_rename.sh"), append = T)  
    # add a line return
    write_file("\n", path = paste0(j,"_all_rename.sh"), append = T)
    x <- paste("sh rename.for.dDocent_se_gz",  paste0("../logs/names_", c, ".tsv"), sep = " ")
    # add the code to the file
    write_file(x, path = paste0(j,"_all_rename.sh"), append = T)  
    # add a line return
    write_file("\n", path = paste0(j,"_all_rename.sh"), append = T)
    write_file("mv APCL* ../samples/", path = paste0(j,"_all_rename.sh"), append = T)
    write_file("\n", path = paste0(j,"_all_rename.sh"), append = T)
  write_file("cd ..", path = paste0(j,"_all_rename.sh"), append = T)  
  write_file("\n", path = paste0(j,"_all_rename.sh"), append = T)
    
  }  
}

Trim and map the reads

michelles 2018-09-25 07:25:10 samples $ dDocent dDocent 2.5.5

Contact jpuritz@uri.edu with any problems

Checking for required software /local/home/michelles/14_programs/dDocent/dDocent: line 84: [: 1.0-r82: integer expression expected

All required software is installed!

dDocent run started Tue Sep 25 07:25:15 EDT 2018

576 individuals are detected. Is this correct? Enter yes or no and press [ENTER] yes Proceeding with 576 individuals dDocent detects 40 processors available on this system. Please enter the maximum number of processors to use for this analysis. 30 dDocent detects 252 gigabytes of maximum memory available on this system. Please enter the maximum memory to use for this analysis in gigabytes For example, to limit dDocent to ten gigabytes, enter 10 This option does not work with all distributions of Linux. If runs are hanging at variant calling, enter 0 Then press [ENTER] 150

Do you want to quality trim your reads? Type yes or no and press [ENTER]? yes

Do you want to perform an assembly? Type yes or no and press [ENTER]. no

Reference contigs need to be in a file named reference.fasta

Do you want to map reads? Type yes or no and press [ENTER] yes BWA will be used to map reads. You may need to adjust -A -B and -O parameters for your taxa. Would you like to enter a new parameters now? Type yes or no and press [ENTER] yes Please enter new value for A (match score). It should be an integer. Default is 1. 1 Please enter new value for B (mismatch score). It should be an integer. Default is 4. 4 Please enter new value for O (gap penalty). It should be an integer. Default is 6. 6 Do you want to use FreeBayes to call SNPs? Please type yes or no and press [ENTER] no

Please enter your email address. dDocent will email you when it is finished running. Don’t worry; dDocent has no financial need to sell your email address to spammers. stuart620@gmail.com

At this point, all configuration information has been entered and dDocent may take several hours to run. It is recommended that you move this script to a background operation and disable terminal input and output. All data and logfiles will still be recorded. To do this: Press control and Z simultaneously Type ‘bg’ without the quotes and press enter Type ‘disown -h’ again without the quotes and press enter

Now sit back, relax, and wait for your analysis to finish

Finished at 9:47am same day

Once trimming is done, prepare to call snps Symlink the files into the analysis directory

In the APCL_analysis directory, create a new analysis folder mkdir 21-03seq

In all of the XXseq/sample directories, symlink the files to the 21-03seq directory

ln -s APCL* ../../APCL_analysis/21-03seq/

Wait for seq 19-21 to be ready

LS0tCnRpdGxlOiAiUHJvY2Vzc2luZyBzZXF1ZW5jZXMgZmFsbCAyMDE4IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKcGFyYW1zOgogIHNlcTogIFNFUTI4CiAgCi0tLQpDaGFuZ2VkIHRoZSBuYW1lcyBvZiB0aGUgc2VxdWVuY2VzIHRvIGFsbG93IGZvciB0aGUgc2VxdWVuY2luZyBpZHMgdGhhdCBTYXJhaCBoYXMgdXNlZC4KCmBgYHtyIHNldHVwfQpzb3VyY2UoIi4uL2dlbm9taWNzL3NjcmlwdHMvbGFiX2hlbHBlcnMuUiIpCmxhYiA8LSByZWFkX2RiKCJMYWJvcmF0b3J5IikKbGlicmFyeShyZWFkcikKYGBgClNlZSB0aGUganVweXRlciBub3RlYm9vayBzZXFfcHJvY2Vzc2luZyBmb3IgdGhlIGFtcGhpcHJpb24gc2lkZSBvZiB0aGlzIHByb3RvY29sLiAgU3RhcnQgdGhlcmUuCgojIyNDcmVhdGUgYW4gaW5kZXggZmlsZSBmb3IgdGhlIFBvb2xzIHRoYXQgaXMgdGFiIHNlcGFyYXRlZCAqKmRvbmUqKgoKYGBge3J9CiMgcmVhZCBiYWl0cyB0YWJsZQpiYWl0cyA8LSBsYWIgJT4lCiAgdGJsKCJiYWl0cyIpICU+JSAKICBjb2xsZWN0KCkgJT4lIAogIHNlbGVjdChiYWl0c19pZCwgc2VxKQoKIyByZWFkIFBDUiB0YWJsZQpwY3IgPC0gbGFiICU+JSAKICB0YmwoInBjciIpICU+JSAKICBjb2xsZWN0KCkgJT4lIAogIGZpbHRlcihiYWl0X2lkICVpbiUgYmFpdHMkYmFpdHNfaWQpICU+JSAKICBzZWxlY3QocGNyX2lkLCBiYWl0X2lkLCBpbmRleCkKCiMgam9pbiBwY3JfaWQgYW5kIGluZGV4IHRvIHNlcSBpZApwb29scyA8LSBsZWZ0X2pvaW4ocGNyLCBiYWl0cywgYnkgPSBjKCJiYWl0X2lkIiA9ICJiYWl0c19pZCIpKSAlPiUgCiAgc2VsZWN0KHNlcSwgcGNyX2lkLCBpbmRleCkKCiMgcHVsbCBpbiB0aGUgYmFyY29kZXMgZm9yIGlsbHVtaW5hIGluZGV4ZXMKaW5kZXggPC0gbGFiICU+JSAKICB0YmwoImlsbHVtaW5hIikgJT4lIAogIGNvbGxlY3QoKQoKIyBqb2luIHRoZSBiYXJjb2RlcyB0byB0aGUgc2VxIGFuZCBwY3IgaWRzCnBvb2xzIDwtIGxlZnRfam9pbihwb29scywgaW5kZXgsIGJ5ID0gYygiaW5kZXgiID0gImluZGV4X251bSIpKSAlPiUgCiAgc2VsZWN0KHNlcSwgcGNyX2lkLCBpbmRleF9jb2RlKQoKIyBjcmVhdGUgYSBsaXN0IG9mIHRoZSBtdWx0aXBsZSBzZXFzCnNlcXMgPC0gc2VsZWN0KHBvb2xzLCBzZXEpICU+JSAKICBkaXN0aW5jdCgpCmZvcihpIGluIHNlcShzZXFzJHNlcSkpewogIHggPC0gcG9vbHMgJT4lIAogIGZpbHRlcihzZXEgPT0gc2VxcyRzZXFbaV0pICU+JSAKICBzZWxlY3QocGNyX2lkLCBpbmRleF9jb2RlKQoKIyB3cml0ZSB0aGUgZmlsZXMgZm9yIGFtcGhpcHJpb24KIyByZWFkcjo6d3JpdGVfdHN2KHgsIHBhdGggPSBwYXN0ZTAoImluZGV4LSIsIHNlcXMkc2VxW2ldLCAiLnRzdiIpLCBjb2xfbmFtZXMgPSBGKQp9CmBgYAojI01vdmUgdGhlIGZpbGVzIGZyb20gdGhlIGxhcHRvcCB0byBhbXBoaXByaW9uIHVzaW5nIHRoZSBmZXRjaCBwcm9ncmFtLCBwbGFjZSB0aGUgaW5kZXggZmlsZXMgaW4gdGhlIGxvZyBmb2xkZXIgZm9yIGVhY2ggc2VxICoqIGRvbmUqKiAgClNlZSBNaWNoZWxsZSBpZiB5b3UgbmVlZCBhIHNlcmlhbCBudW1iZXIgZm9yIEZldGNoCgoKIyMjQ3JlYXRlIGEgbmFtZXMgZmlsZSBmb3IgZWFjaCBwb29sICoqZG9uZSoqClRoZSBuYW1lcyBoYXZlIHRvIGJlIHNwZWNpZXMsIHVuZGVyc2NvcmUgYW5kIHRoZW4gdGhlIHNhbXBsZSBpZGVudGlmaWVyLCBzbyBBUENMX0w1NDMyIGZvciBsaWdhdGlvbl9pZCBMNTQzMgpgYGB7cn0KIyByZWFkIHRoZSBsaWdhdGlvbnMKbGlncyA8LSBsYWIgJT4lIAogIHRibCgibGlnYXRpb24iKSAlPiUgCiAgZmlsdGVyKHBvb2wgJWluJSBwb29scyRwY3JfaWQpICU+JSAKICBzZWxlY3QobGlnYXRpb25faWQsIGJhcmNvZGVfbnVtLCBwb29sKSAlPiUgCiAgY29sbGVjdCgpCgojIHJlYWQgdGhlIGJhcmNvZGVzCmJhcmNvZGUgPC0gbGFiICU+JSAKICB0YmwoImJhcmNvZGVzIikgJT4lIAogIGNvbGxlY3QoKQoKIyBqb2luIHRoZSBsaWdhdGlvbl9pZCBhbmQgcG9vbCBpZHMgdG8gdGhlIGJhcmNvZGVzCmxpZ3MgPC0gbGVmdF9qb2luKGxpZ3MsIGJhcmNvZGUsIGJ5ID0gImJhcmNvZGVfbnVtIikKCiMgam9pbiB0aGUgbGlncyB0byB0aGUgc2VxX2lkcwpsaWdzIDwtIGxlZnRfam9pbihsaWdzLCBwb29scywgYnkgPSBjKCJwb29sIiA9ICJwY3JfaWQiKSkgJT4lIAogICMgYWRqdXN0IHRoZSBsaWdhdGlvbiBuYW1lIGZvciBkRG9jZW50CiAgbXV0YXRlKG5hbWUgPSBwYXN0ZTAoIkFQQ0xfIiwgbGlnYXRpb25faWQsICIuRiIpKSAlPiUgCiAgc2VsZWN0KHNlcSwgcG9vbCwgbmFtZSwgYmFyY29kZSkgJT4lIAojIHJlZHVjZSB0aGUgcG9vbCB0byBvbmx5IGEgbnVtYmVyCiAgICBtdXRhdGUocG9vbCA9IHN1YnN0cihwb29sLCAyLDUpKQoKIyB3cml0ZSBmaWxlcyBmb3IgYW1waGlwcmlvbgojIGNyZWF0ZSBhIGxpc3Qgb2YgdGhlIG11bHRpcGxlIHNlcXMKbmFtZXMgPC0gc2VsZWN0KGxpZ3MsIHBvb2wpICU+JSAKICBkaXN0aW5jdCgpCgojIGxvb3AgdGhyb3VnaCBhbGwgb2YgdGhlIHBvb2xzCmZvcihpIGluIHNlcShuYW1lcyRwb29sKSl7CiAgeCA8LSBsaWdzICU+JSAKICBmaWx0ZXIocG9vbCA9PSBuYW1lcyRwb29sW2ldKSAlPiUgCiAgc2VsZWN0KG5hbWUsIGJhcmNvZGUpCgojIHdyaXRlIHRoZSBmaWxlcyBmb3IgYW1waGlwcmlvbgojIHJlYWRyOjp3cml0ZV90c3YoeCwgcGF0aCA9IHBhc3RlMCgibmFtZXNfIiwgbmFtZXMkcG9vbFtpXSwgIi50c3YiKSwgY29sX25hbWVzID0gRikKfQoKYGBgCiMjI01vdmUgdGhlIGZpbGVzIGZyb20gdGhlIGxhcHRvcCB0byBhbXBoaXByaW9uIHVzaW5nIHRoZSBmZXRjaCBwcm9ncmFtLCBwbGFjZSB0aGUgbmFtZXMgZmlsZXMgaW4gdGhlIGxvZyBmb2xkZXIgZm9yIGVhY2ggc2VxICoqZG9uZSoqCgoKCgoKIyMjQ29uY2F0ZW5hdGUgdGhlIHJlc3VsdHMgaW4gdGhlIGJjc3BsaXQgZm9sZGVyIC0gdGFrZXMgYWJvdXQgYSBtaW51dGUgKipkb25lKioKCmBgYHtyfQpsaWJyYXJ5KHJlYWRyKQpmb3IgKGogaW4gc2VxcyRzZXEpewogIHkgPC0gcG9vbHMgJT4lIAogICAgZmlsdGVyKHNlcSA9PSBqKQogIHdyaXRlX2ZpbGUoIiMhL2Jpbi9iYXNoIiwgcGF0aCA9IHBhc3RlMChqLCJfY2F0X2FsbC5zaCIpLCBhcHBlbmQgPSBGKQogICMgYWRkIGEgbGluZSByZXR1cm4KICB3cml0ZV9maWxlKCJcbiIsIHBhdGggPSBwYXN0ZTAoaiwiX2NhdF9hbGwuc2giKSwgYXBwZW5kID0gVCkKICBmb3IgKGkgaW4gc2VxKHkkcGNyX2lkKSl7CiAgICB6IDwtIGZvcm1hdEMoaSwgd2lkdGggPSAyLCBmbGFnID0gMCkKICAgICMgZ2VuZXJhdGUgdGhlIGNvZGUKICAgIHggPC0gcGFzdGUoImNhdCIsIHBhc3RlMCgiLi9sYW5lMS8iLCB5JHBjcl9pZFtpXSwgIi1yZWFkLTEuZmFzdHEuZ3oiKSwgcGFzdGUwKCIuL2xhbmUyLyIsIHkkcGNyX2lkW2ldLCAiLXJlYWQtMS5mYXN0cS5neiIpLCAiPiIsICBwYXN0ZTAoIi4uLyIsIHosICJQb29sLyIsIHkkcGNyX2lkW2ldLCAiLmZhc3RxLmd6IiksIHNlcCA9ICIgIikKICAgICMgYWRkIHRoZSBjb2RlIHRvIHRoZSBmaWxlCiAgICB3cml0ZV9maWxlKHgsIHBhdGggPSBwYXN0ZTAoaiwiX2NhdF9hbGwuc2giKSwgYXBwZW5kID0gVCkgIAogICAgIyBhZGQgYSBsaW5lIHJldHVybgogICAgd3JpdGVfZmlsZSgiXG4iLCBwYXRoID0gcGFzdGUwKGosIl9jYXRfYWxsLnNoIiksIGFwcGVuZCA9IFQpCiAgfSAgCn0KCmBgYAoKCiMjIyBjcmVhdGUgc2NyaXB0cyBmb3IgYWxsIDQ4IHBvb2xzIHRvIHByb2Nlc3MgcmFkdGFncyAqKmRvbmUqKgoKYGBge3J9CiNhc3NpZ24gdGhlIGNvcnJlY3QgcG9vbCBkaXJlY3RvcnkgdG8gZWFjaCBwb29sCgpwb29scyA8LSBwb29scyAlPiUgCiAgYXJyYW5nZShzZXEsIHBjcl9pZCkgJT4lIAogIG11dGF0ZShwb29sX2RpciA9IHJlcCgxOjEyLCA0KSwgCiAgICAgICAgIHBvb2xfZGlyID0gZm9ybWF0Qyhwb29sX2Rpciwgd2lkdGggPSAyLCBmbGFnID0gMCksIAogICAgICAgICBwb29sX2RpciA9IHBhc3RlMChwb29sX2RpciwgIlBvb2wiKSkKCiMjIHdyaXRlIGZpbGVzCmxpYnJhcnkocmVhZHIpCiMgY3JlYXRlIGZpcnN0IGxpbmUgb2YgbmV3IGZpbGUKZm9yIChpIGluIHNlcShwb29scyRzZXEpKXsKICB3cml0ZV9maWxlKCIjIS9iaW4vYmFzaCIsIHBhdGggPSBwYXN0ZTAocG9vbHMkcGNyX2lkW2ldLCAiX3Byb2Nlc3Muc2giKSwgYXBwZW5kID0gRikKICAjIGFkZCBhIGxpbmUgcmV0dXJuCiAgd3JpdGVfZmlsZSgiXG4iLCBwYXRoID0gcGFzdGUwKHBvb2xzJHBjcl9pZFtpXSwgIl9wcm9jZXNzLnNoIiksIGFwcGVuZCA9IFQpCiAgIyBnZW5lcmF0ZSB0aGUgY29kZQogIHggPC0gcGFzdGUoInByb2Nlc3NfcmFkdGFncyAtYiAuL2xvZ3MvYmFyY29kZXMgLWMgLXEgLS1yZW56XzEgcHN0SSAtLXJlbnpfMiBtbHVDSSAtaSBnemZhc3RxIC0tYWRhcHRlcl8xIEFDQUNUQ1RUVENDQ1RBQ0FDR0FDR0NUQ1RUQ0NHQVRDVCAtZiIsIHBhc3RlMCgiLi8iLCBwb29scyRwb29sX2RpcltpXSwgIi8iLCBwb29scyRwY3JfaWRbaV0sICIuZmFzdHEuZ3oiKSwgICItbyIsIHBhc3RlMCgiLi8iLCBwb29scyRwb29sX2RpcltpXSwgIi8iKSwgc2VwID0gIiAiKQogICMgYWRkIHRoZSBjb2RlIHRvIHRoZSBmaWxlCiAgd3JpdGVfZmlsZSh4LCBwYXRoID0gcGFzdGUwKHBvb2xzJHBjcl9pZFtpXSwgIl9wcm9jZXNzLnNoIiksIGFwcGVuZCA9IFQpICAKfQoKYGBgCiMjI01vdmUgdGhlIHNjcmlwdHMgdG8gYW1waGlwcmlvbiBpbnRvIHRoZSBzZXEgc2NyaXB0cyBmb2xkZXIgd2l0aCBmZXRjaCAKV2l0aCBmZXRjaCB5b3UgY2FuIGFsc28gaGlnaGxpZ2h0IGFsbCBvZiB0aGUgc2NyaXB0cyBhbmQgY2xpY2sgZ2V0IGluZm8sIGV4ZWN1dGUgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdHlwZSBpbiB0aGUgY2htb2QgdSt4IGNvbW1hbmQgZm9yIGVhY2ggZmlsZS4KCiNwcm9jZXNzX3JhZHRhZ3MgLSB1c2UgZXNjLVIgb3IgY3RybC1cIHRvICJmaW5kIGFuZCByZXBsYWNlIiBpbiBuYW5vIC0gdGFrZXMgYWJvdXQgMi41IGhvdXJzIGZvciA0IHBvb2xzIGFuZCAxOTIgc2FtcGxlcwoKRnJvbSB0aGUgc2VxIGZvbGRlciAoMThTRVEgZm9yIGV4YW1wbGUpLCBydW4gdGhlIHByb2Nlc3Mgc2NyaXB0cywgY2FuIHJ1biBhbGwgNCBpbiBzZXBhcmF0ZSB3aW5kb3dzIChvciBhbGwgNDg/KQoKIyB3cml0ZSBhIHNjcmlwdCB0byBnZW5lcmF0ZSBjb21tYW5kIGxpbmUgdG8gcnVuIHByb2Nlc3MgcmFkdGFncyBzY3JpcHRzCmBgYHtyfQpmb3IgKGogaW4gc2VxcyRzZXEpewogIHkgPC0gcG9vbHMgJT4lIAogICAgZmlsdGVyKHNlcSA9PSBqKQogIHdyaXRlX2ZpbGUoIiMhL2Jpbi9iYXNoIiwgcGF0aCA9IHBhc3RlMChqLCJfcHJvY2Vzc19hbGwuc2giKSwgYXBwZW5kID0gRikKICAjIGFkZCBhIGxpbmUgcmV0dXJuCiAgd3JpdGVfZmlsZSgiXG4iLCBwYXRoID0gcGFzdGUwKGosIl9wcm9jZXNzX2FsbC5zaCIpLCBhcHBlbmQgPSBUKQogIGZvciAoaSBpbiB5JHBjcl9pZCl7CiAgICAjIGdlbmVyYXRlIHRoZSBjb2RlCiAgICB4IDwtIHBhc3RlKCJub2h1cCIsIHBhc3RlMCgiLi9zY3JpcHRzLyIsIGksICJfcHJvY2Vzcy5zaCAmIiksIHNlcCA9ICIgIikKICAgICMgYWRkIHRoZSBjb2RlIHRvIHRoZSBmaWxlCiAgICB3cml0ZV9maWxlKHgsIHBhdGggPSBwYXN0ZTAoaiwiX3Byb2Nlc3NfYWxsLnNoIiksIGFwcGVuZCA9IFQpICAKICAgICMgYWRkIGEgbGluZSByZXR1cm4KICAgIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfcHJvY2Vzc19hbGwuc2giKSwgYXBwZW5kID0gVCkKICB9ICAKfQoKYGBgCgoKc3RhcnRlZCB0aGUgbGFzdCBvbmUgYXQgOTo0NXBtIG9uIE1vbmRheSA5LzI0LzIwMTggLSBzaG91bGQgdGFrZSBhYm91dCA1IGhvdXJzCmRvbmUgYmVmb3JlIDZhbSBvbiBUdWVzZGF5CgoKV3JpdGUgdGV4dCBmb3IgbW92aW5nIGZpbGVzCmBgYHtyfQpmb3IgKGogaW4gc2VxcyRzZXEpewogIHkgPC0gcG9vbHMgJT4lIAogICAgZmlsdGVyKHNlcSA9PSBqKQogIHdyaXRlX2ZpbGUoIiMhL2Jpbi9iYXNoIiwgcGF0aCA9IHBhc3RlMChqLCJfbW92ZV9yYWRsb2dzLnNoIiksIGFwcGVuZCA9IEYpCiAgIyBhZGQgYSBsaW5lIHJldHVybgogIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfbW92ZV9yYWRsb2dzLnNoIiksIGFwcGVuZCA9IFQpCiAgZm9yIChpIGluIHNlcSh5JHBjcl9pZCkpewogICAgeiA8LSBmb3JtYXRDKGksIHdpZHRoID0gMiwgZmxhZyA9IDApCiAgICAjIGdlbmVyYXRlIHRoZSBjb2RlCiAgICB4IDwtIHBhc3RlKCJtdiIsIHBhc3RlMCh6LCAiUG9vbC9wcm9jZXNzX3JhZHRhZ3MubG9nIiksIHBhc3RlMCgiLi9sb2dzL3Byb2Nlc3MiLCB5JHBjcl9pZFtpXSwgIi5sb2ciKSwgc2VwID0gIiAiKQogICAgIyBhZGQgdGhlIGNvZGUgdG8gdGhlIGZpbGUKICAgIHdyaXRlX2ZpbGUoeCwgcGF0aCA9IHBhc3RlMChqLCJfbW92ZV9yYWRsb2dzLnNoIiksIGFwcGVuZCA9IFQpICAKICAgICMgYWRkIGEgbGluZSByZXR1cm4KICAgIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfbW92ZV9yYWRsb2dzLnNoIiksIGFwcGVuZCA9IFQpCiAgfSAgCn0KCmBgYAoKIyMgYWRkIHRoZSBzZXF1ZW5jaW5nIHJlc3VsdHMgdG8gdGhlIGRhdGFiYXNlCmBgYHtyfQojIHNldCB0byBjdXJyZW50IHNlcXVlbmNpbmcgcnVuCndsYWIgPC0gd3JpdGVfZGIoIkxhYm9yYXRvcnkiKQpjdXJyZW50IDwtIHBvb2xzICU+JSAKICBmaWx0ZXIoc2VxID09IHBhcmFtcyRzZXEpCgojIHB1bGwgb3V0IG9ubHkgdGhlIHBvb2xzIGluIGN1cnJlbnQgc2VxdWVuY2luZyBydW4KZm9yKGkgaW4gc2VxKGN1cnJlbnQkcGNyX2lkKSl7CiAgIyBkZWZpbmUgdGhlIGxvZyBmaWxlCiAgZmlsZW5hbWUgPC0gcGFzdGUwKCJ+L0Rvd25sb2Fkcy9wcm9jZXNzIiwgY3VycmVudCRwY3JfaWRbaV0sICIubG9nLnRzdiIpCiAgIyByZWFkIGluIHRoZSBsb2cgZmlsZQogIHNhbXBsZXMgPC0gcmVhZF9kZWxpbShmaWxlbmFtZSwgZGVsaW0gPSAiXHQiLCBjb2xfbmFtZXMgPSBjKCJiYXJjb2RlIiwgInRvdGFsX3JlYWRzIiwgImxhY2tfcmFkX3RhZyIsICJsb3dfcXVhbGl0eSIsICJyZXRhaW5lZCIpLCAKICAgIGNvbF90eXBlcyA9IGNvbHMoImMiLCAiYyIsICJjIiwgImMiLCAiYyIpKSAjaW1wb3J0IGFsbCBjb2x1bW5zIGFzIGNoYXJhY3RlcgogICMgbWVyZ2UgdG8gYmFyY29kZXMgdG8gZ2V0IGJhcmNvZGUgbnVtYmVyIGFuZCBhZGQgcG9vbCB0byB0YWJsZQogIHNhbXBsZXMgPC0gbGVmdF9qb2luKHNhbXBsZXMsIGJhcmNvZGUsIGJ5ID0gImJhcmNvZGUiKSAlPiUgCiAgICBtdXRhdGUocG9vbCA9IGN1cnJlbnQkcGNyX2lkW2ldKQogICMgbWVyZ2UgdG8gbGlnYXRpb25faWRzIGFuZCByZW1vdmUgYmFyY29kZQogIHNhbXBsZXMgPC0gbGVmdF9qb2luKHNhbXBsZXMsIGxpZ3MsIGJ5ID0gYygiYmFyY29kZV9udW0iLCAicG9vbCIpKSAlPiUgCiAgICBzZWxlY3QoLWJhcmNvZGUpCgpkYXQgPC0gbGFiICU+JQogIHRibCgibGlnYXRpb24iKSAlPiUgCiAgY29sbGVjdCgpCgpjaGFuZ2UgPC0gZGF0ICU+JSAKICBmaWx0ZXIobGlnYXRpb25faWQgJWluJSBzYW1wbGVzJGxpZ2F0aW9uX2lkKSAlPiUgCiAgc2VsZWN0KC10b3RhbF9yZWFkcywgLWxhY2tfcmFkX3RhZywgLWxvd19xdWFsaXR5LCAtcmV0YWluZWQpCmNoYW5nZSA8LSBsZWZ0X2pvaW4oY2hhbmdlLCBzYW1wbGVzLCBieSA9IGMoImxpZ2F0aW9uX2lkIiwgImJhcmNvZGVfbnVtIiwgInBvb2wiKSkKCmRhdCA8LSBjaGFuZ2Vfcm93cyhkYXQsIGNoYW5nZSwgImxpZ2F0aW9uX2lkIikKIyBkYldyaXRlVGFibGUod2xhYiwgImxpZ2F0aW9uIiwgZGF0LCByb3cubmFtZXMgPSBGLCBvdmVyd3JpdGUgPSBUKQp9CmBgYAoKV2hpY2ggc2FtcGxlcyBmYWlsZWQ/CmBgYHtyfQp1cGxpZ3MgPC0gbGFiICU+JQogIHRibCgibGlnYXRpb24iKSAlPiUgCiAgZmlsdGVyKHBvb2wgJWluJSBjdXJyZW50JHBjcl9pZCkgJT4lIAogIG11dGF0ZSh0b3RhbF9yZWFkcyA9IGFzLm51bWVyaWModG90YWxfcmVhZHMpLCAKICAgIGxhY2tfcmFkX3RhZyA9IGFzLm51bWVyaWMobGFja19yYWRfdGFnKSwgCiAgICBsb3dfcXVhbGl0eSA9IGFzLm51bWVyaWMobG93X3F1YWxpdHkpLCAKICAgIHJldGFpbmVkID0gYXMubnVtZXJpYyhyZXRhaW5lZCkpICU+JSAKICBjb2xsZWN0KCkKCgpoaXN0KHVwbGlncyR0b3RhbF9yZWFkcywgYnJlYWtzID0gMTAwKQoKIyB6b29tIGluIHRvIHRoZSBsb3dlciBlbmQgCnpvb20gPC0gdXBsaWdzICU+JSAKICBmaWx0ZXIodG90YWxfcmVhZHMgPCAyMDAwMDApCmhpc3Qoem9vbSR0b3RhbF9yZWFkcywgYnJlYWtzID0gMTApCgpsb3cgPC0gdXBsaWdzICU+JSAKICBtdXRhdGUodG90YWxfcmVhZHMgPSBhcy5udW1lcmljKHRvdGFsX3JlYWRzKSkgJT4lIAogIGZpbHRlcih0b3RhbF9yZWFkcyA8IDEwMDAwMCkgJT4lIAogIHNlbGVjdChsaWdhdGlvbl9pZCkKCgoKc3VtbWFyeSh1cGxpZ3MpCgptYXhpbXVtIDwtIHVwbGlncyAlPiUgCiAgZmlsdGVyKHJldGFpbmVkID4gMTAwMDAwMCkKCnRvdGFsIDwtIHVwbGlncyAlPiUgCiAgc3VtbWFyaXNlKHN1bSA9IHN1bSh0b3RhbF9yZWFkcykpCgpgYGAKCgoKIyMgUmVuYW1lIHRoZSBwcm9jZXNzIHJhZHRhZ3Mgb3V0cHV0IHRvIHNhbXBsZSBuYW1lcwp3cml0ZSByZW5hbWluZyB0ZXh0CmBgYHtyfQpsaWJyYXJ5KHJlYWRyKQpmb3IgKGogaW4gc2VxcyRzZXEpewogIHkgPC0gcG9vbHMgJT4lIAogICAgZmlsdGVyKHNlcSA9PSBqKSAlPiUgCiAgICBhcnJhbmdlKHBjcl9pZCkKICB3cml0ZV9maWxlKCIjIS9iaW4vYmFzaCIsIHBhdGggPSBwYXN0ZTAoaiwiX2FsbF9yZW5hbWUuc2giKSwgYXBwZW5kID0gRikKICAjIGFkZCBhIGxpbmUgcmV0dXJuCiAgd3JpdGVfZmlsZSgiXG4iLCBwYXRoID0gcGFzdGUwKGosIl9hbGxfcmVuYW1lLnNoIiksIGFwcGVuZCA9IFQpCiAgZm9yIChpIGluIHNlcSh5JHBjcl9pZCkpewogICAgeiA8LSBmb3JtYXRDKGksIHdpZHRoID0gMiwgZmxhZyA9IDApCiAgICBjIDwtIHN1YnN0cih5JHBjcl9pZFtpXSwgMiwgNSkKICAgICMgZ2VuZXJhdGUgdGhlIGNvZGUKICAgIGEgPC0gcGFzdGUoImNkIiwgcGFzdGUwKHosICJQb29sLyIpLCBzZXAgPSAiICIpCiAgICAjIGFkZCB0aGUgY29kZSB0byB0aGUgZmlsZQogICAgd3JpdGVfZmlsZShhLCBwYXRoID0gcGFzdGUwKGosIl9hbGxfcmVuYW1lLnNoIiksIGFwcGVuZCA9IFQpICAKICAgICMgYWRkIGEgbGluZSByZXR1cm4KICAgIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfYWxsX3JlbmFtZS5zaCIpLCBhcHBlbmQgPSBUKQogICAgeCA8LSBwYXN0ZSgic2ggcmVuYW1lLmZvci5kRG9jZW50X3NlX2d6IiwgIHBhc3RlMCgiLi4vbG9ncy9uYW1lc18iLCBjLCAiLnRzdiIpLCBzZXAgPSAiICIpCiAgICAjIGFkZCB0aGUgY29kZSB0byB0aGUgZmlsZQogICAgd3JpdGVfZmlsZSh4LCBwYXRoID0gcGFzdGUwKGosIl9hbGxfcmVuYW1lLnNoIiksIGFwcGVuZCA9IFQpICAKICAgICMgYWRkIGEgbGluZSByZXR1cm4KICAgIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfYWxsX3JlbmFtZS5zaCIpLCBhcHBlbmQgPSBUKQogICAgd3JpdGVfZmlsZSgibXYgQVBDTCogLi4vc2FtcGxlcy8iLCBwYXRoID0gcGFzdGUwKGosIl9hbGxfcmVuYW1lLnNoIiksIGFwcGVuZCA9IFQpCiAgICB3cml0ZV9maWxlKCJcbiIsIHBhdGggPSBwYXN0ZTAoaiwiX2FsbF9yZW5hbWUuc2giKSwgYXBwZW5kID0gVCkKICB3cml0ZV9maWxlKCJjZCAuLiIsIHBhdGggPSBwYXN0ZTAoaiwiX2FsbF9yZW5hbWUuc2giKSwgYXBwZW5kID0gVCkgIAogIHdyaXRlX2ZpbGUoIlxuIiwgcGF0aCA9IHBhc3RlMChqLCJfYWxsX3JlbmFtZS5zaCIpLCBhcHBlbmQgPSBUKQogICAgCiAgfSAgCn0KCmBgYAoKCgoKCiMjIFRyaW0gYW5kIG1hcCB0aGUgcmVhZHMKbWljaGVsbGVzIDIwMTgtMDktMjUgMDc6MjU6MTAgc2FtcGxlcyAkIGREb2NlbnQKZERvY2VudCAyLjUuNSAKCkNvbnRhY3QganB1cml0ekB1cmkuZWR1IHdpdGggYW55IHByb2JsZW1zIAoKIApDaGVja2luZyBmb3IgcmVxdWlyZWQgc29mdHdhcmUKL2xvY2FsL2hvbWUvbWljaGVsbGVzLzE0X3Byb2dyYW1zL2REb2NlbnQvZERvY2VudDogbGluZSA4NDogWzogMS4wLXI4MjogaW50ZWdlciBleHByZXNzaW9uIGV4cGVjdGVkCgpBbGwgcmVxdWlyZWQgc29mdHdhcmUgaXMgaW5zdGFsbGVkIQoKKipkRG9jZW50IHJ1biBzdGFydGVkIFR1ZSBTZXAgMjUgMDc6MjU6MTUgRURUIDIwMTggKioKCjU3NiBpbmRpdmlkdWFscyBhcmUgZGV0ZWN0ZWQuIElzIHRoaXMgY29ycmVjdD8gRW50ZXIgeWVzIG9yIG5vIGFuZCBwcmVzcyBbRU5URVJdCnllcwpQcm9jZWVkaW5nIHdpdGggNTc2IGluZGl2aWR1YWxzCmREb2NlbnQgZGV0ZWN0cyA0MCBwcm9jZXNzb3JzIGF2YWlsYWJsZSBvbiB0aGlzIHN5c3RlbS4KUGxlYXNlIGVudGVyIHRoZSBtYXhpbXVtIG51bWJlciBvZiBwcm9jZXNzb3JzIHRvIHVzZSBmb3IgdGhpcyBhbmFseXNpcy4KMzAKZERvY2VudCBkZXRlY3RzIDI1MiBnaWdhYnl0ZXMgb2YgbWF4aW11bSBtZW1vcnkgYXZhaWxhYmxlIG9uIHRoaXMgc3lzdGVtLgpQbGVhc2UgZW50ZXIgdGhlIG1heGltdW0gbWVtb3J5IHRvIHVzZSBmb3IgdGhpcyBhbmFseXNpcyBpbiBnaWdhYnl0ZXMKRm9yIGV4YW1wbGUsIHRvIGxpbWl0IGREb2NlbnQgdG8gdGVuIGdpZ2FieXRlcywgZW50ZXIgMTAKVGhpcyBvcHRpb24gZG9lcyBub3Qgd29yayB3aXRoIGFsbCBkaXN0cmlidXRpb25zIG9mIExpbnV4LiAgSWYgcnVucyBhcmUgaGFuZ2luZyBhdCB2YXJpYW50IGNhbGxpbmcsIGVudGVyIDAKVGhlbiBwcmVzcyBbRU5URVJdCjE1MAoKRG8geW91IHdhbnQgdG8gcXVhbGl0eSB0cmltIHlvdXIgcmVhZHM/ClR5cGUgeWVzIG9yIG5vIGFuZCBwcmVzcyBbRU5URVJdPwp5ZXMKCkRvIHlvdSB3YW50IHRvIHBlcmZvcm0gYW4gYXNzZW1ibHk/ClR5cGUgeWVzIG9yIG5vIGFuZCBwcmVzcyBbRU5URVJdLgpubwoKUmVmZXJlbmNlIGNvbnRpZ3MgbmVlZCB0byBiZSBpbiBhIGZpbGUgbmFtZWQgcmVmZXJlbmNlLmZhc3RhCgpEbyB5b3Ugd2FudCB0byBtYXAgcmVhZHM/ICBUeXBlIHllcyBvciBubyBhbmQgcHJlc3MgW0VOVEVSXQp5ZXMKQldBIHdpbGwgYmUgdXNlZCB0byBtYXAgcmVhZHMuICBZb3UgbWF5IG5lZWQgdG8gYWRqdXN0IC1BIC1CIGFuZCAtTyBwYXJhbWV0ZXJzIGZvciB5b3VyIHRheGEuCldvdWxkIHlvdSBsaWtlIHRvIGVudGVyIGEgbmV3IHBhcmFtZXRlcnMgbm93PyBUeXBlIHllcyBvciBubyBhbmQgcHJlc3MgW0VOVEVSXQp5ZXMKUGxlYXNlIGVudGVyIG5ldyB2YWx1ZSBmb3IgQSAobWF0Y2ggc2NvcmUpLiAgSXQgc2hvdWxkIGJlIGFuIGludGVnZXIuICBEZWZhdWx0IGlzIDEuCjEKUGxlYXNlIGVudGVyIG5ldyB2YWx1ZSBmb3IgQiAobWlzbWF0Y2ggc2NvcmUpLiAgSXQgc2hvdWxkIGJlIGFuIGludGVnZXIuICBEZWZhdWx0IGlzIDQuCjQKUGxlYXNlIGVudGVyIG5ldyB2YWx1ZSBmb3IgTyAoZ2FwIHBlbmFsdHkpLiAgSXQgc2hvdWxkIGJlIGFuIGludGVnZXIuICBEZWZhdWx0IGlzIDYuCjYKRG8geW91IHdhbnQgdG8gdXNlIEZyZWVCYXllcyB0byBjYWxsIFNOUHM/ICBQbGVhc2UgdHlwZSB5ZXMgb3Igbm8gYW5kIHByZXNzIFtFTlRFUl0Kbm8KClBsZWFzZSBlbnRlciB5b3VyIGVtYWlsIGFkZHJlc3MuICBkRG9jZW50IHdpbGwgZW1haWwgeW91IHdoZW4gaXQgaXMgZmluaXNoZWQgcnVubmluZy4KRG9uJ3Qgd29ycnk7IGREb2NlbnQgaGFzIG5vIGZpbmFuY2lhbCBuZWVkIHRvIHNlbGwgeW91ciBlbWFpbCBhZGRyZXNzIHRvIHNwYW1tZXJzLgpzdHVhcnQ2MjBAZ21haWwuY29tICAgICAgICAKCgpBdCB0aGlzIHBvaW50LCBhbGwgY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbiBoYXMgYmVlbiBlbnRlcmVkIGFuZCBkRG9jZW50IG1heSB0YWtlIHNldmVyYWwgaG91cnMgdG8gcnVuLgpJdCBpcyByZWNvbW1lbmRlZCB0aGF0IHlvdSBtb3ZlIHRoaXMgc2NyaXB0IHRvIGEgYmFja2dyb3VuZCBvcGVyYXRpb24gYW5kIGRpc2FibGUgdGVybWluYWwgaW5wdXQgYW5kIG91dHB1dC4KQWxsIGRhdGEgYW5kIGxvZ2ZpbGVzIHdpbGwgc3RpbGwgYmUgcmVjb3JkZWQuClRvIGRvIHRoaXM6ClByZXNzIGNvbnRyb2wgYW5kIFogc2ltdWx0YW5lb3VzbHkKVHlwZSAnYmcnIHdpdGhvdXQgdGhlIHF1b3RlcyBhbmQgcHJlc3MgZW50ZXIKVHlwZSAnZGlzb3duIC1oJyBhZ2FpbiB3aXRob3V0IHRoZSBxdW90ZXMgYW5kIHByZXNzIGVudGVyCgpOb3cgc2l0IGJhY2ssIHJlbGF4LCBhbmQgd2FpdCBmb3IgeW91ciBhbmFseXNpcyB0byBmaW5pc2gKCkZpbmlzaGVkIGF0IDk6NDdhbSBzYW1lIGRheQoKT25jZSB0cmltbWluZyBpcyBkb25lLCBwcmVwYXJlIHRvIGNhbGwgc25wcwpTeW1saW5rIHRoZSBmaWxlcyBpbnRvIHRoZSBhbmFseXNpcyBkaXJlY3RvcnkKCkluIHRoZSBBUENMX2FuYWx5c2lzIGRpcmVjdG9yeSwgY3JlYXRlIGEgbmV3IGFuYWx5c2lzIGZvbGRlcgpta2RpciAyMS0wM3NlcQoKSW4gYWxsIG9mIHRoZSBYWHNlcS9zYW1wbGUgZGlyZWN0b3JpZXMsIHN5bWxpbmsgdGhlIGZpbGVzIHRvIHRoZSAyMS0wM3NlcSBkaXJlY3RvcnkKCmxuIC1zIEFQQ0wqIC4uLy4uL0FQQ0xfYW5hbHlzaXMvMjEtMDNzZXEvCgoKCldhaXQgZm9yIHNlcSAxOS0yMSB0byBiZSByZWFkeSAKCgo=