Introduction
This document aims to record the tasks performed to re-preprocess the
IPRGC samples of the Speer lab. I have every confidence that Theresa did
everything perfectly, the only reason I wish to redo these tasks lies in
the fact that we reorganized slightly the data to represent the new
files produced by April following a reassessment of the samples in
~202404. It turns out that a small number of samples were misnamed and
therefore it is difficult to ensure with absolute certainty that the
existing state of Theresa’s working tree is representative of the new
state of the samples.
Thus it is worth explaining slightly what I did before starting this
document:
I spent some time with Najib and April in order to create the
sample sheet ‘20240521_speer_consolidated_sample_sheet.xlsx’. This is
mostly identical to Theresa’s with a few caveats:
- There is now a series of columns with the suffix ‘AH’. With Najib’s
help, I reconciled the existing IPRGC IDs created by Theresa with the
extant samples and copied April’s sample sheet information into these
columns. They have the names ‘Project # AH’, ‘Sample # AH’, ‘Rashmi’s
Sample Name AH’, ‘Prep & Clean AH’, ‘Sequencing Run AH’, ‘Read 1
AH’, ‘Read 2 AH’, ‘Reload & Map Again AH’ and comprise columns
AO-AV. These columns are only populated for samples iprgc62-iprgc130,
because these are (I think) the only samples sequenced by April, and
definitely the only samples potentially affected by the file
re-copying.
- Given these new columns, I created a series of columns with the
suffix ‘atb’: ‘genotype_atb’, ‘location_atb’, ‘time_atb’,
‘time_geo_location_source_atb’, and ‘rashmi_code_atb’. These columns are
generally identical to Theresa’s columns of the same information with
potential exceptions in the cases of the files which were
moved/reorganized. The ‘time_geo_location_source’ column is used to
signify where I took the information for the previous columns, e.g. if
it says TAA_meta, then I took the genotype etc classifications from
Theresa’s metadata without any interpretation/modification. When it says
‘AH filename’, then I took that, as one might expect, from April’s newly
provided filenames.
- I later added Column AN when assaying Najib’s raw_data tree for
these samples. Najib had previously not populated his raw directory tree
with any sample >= iprgc_64; so I recorded in this column any actions
I took. These actions fell into three categories: 1. Nothing (the first
2), 2. Almost nothing (the raw files were actually in Najib’s tree, but
he had not yet put them into the ‘unprocessed’ directory. 3. Nothing
existed yet, so I copied the files from my fresh tree (downloaded from
the sequencer earlier in 202405) to the appropriate directories in
Najib’s tree. I then copy/pasted my command into this column so that we
may later double-check them. I probably could have put this information
into this file…
- At this moment I added a column ‘sequence_type_atb’ which is either
‘previous’ or ‘takara’ so that I can record the likely required trimming
process. I am hopeful that this column will not be needed and that I
will be able to use fastp to identically treat all samples old and new.
I hypothesize this is possible after spending a little time reading the
takara cogent package code. It seems to me that their trimming
operations are either close-to or identical to what fastp will perform.
If that is not true, then I will do my default trimomatic/fastp trimming
for the previous samples and the cogent method for the others. It should
also be noted that I am making the assumption that any sample < 2021
is not takara and vice versa (e.g. anything received with a date after
20201221 is takara).
It is hoped that 1c. above has left me in a consistent state and
that I have every sample required in the appropriate location in Najib’s
tree and that they match the modified sample sheet.
Thus I created a fresh working tree named ‘mmusculus_iprgc_2024’
and populated it with empty directories ‘sample_sheets’, ‘reference’,
and ‘preprocessing’.
Populating the raw
data
From this point on, any command run will be performed in this text
document, so you will get to read along as I make my
decisions/mistakes.
I decided I will work using the read-only copies in Najib’s tree.
cd preprocessing
ln -s /fs/cbcb-lab/nelsayed/raw_data/speer/iprgc* .
I now have 129 symlinks in my preprocessing directory with one hole
where a sample got changed and a couple new iprgc IDs due to the changes
introduced by April’s reprocessing.
After staring at the screen for a moment, I decided to split these
samples into subdirectories named after the sequencing year, thus:
mkdir 2019 2020 2022 2023
mv iprgc_0[1-8] 2019
mv iprgc_09 iprgc_1* iprgc_2* iprgc_3* iprgc_4* iprgc_5* iprgc_60 iprgc_61 2020
mv iprgc_6* iprgc_7* iprgc_8[0-4] 2022
mv iprgc* 2023
## haha I was a doofus and moved the 100s into 2020 directory because iprgc_1* matches 100+
mv 2020/iprgc_1[0-9][0-9] 2023
I am doing this because I am guessing there may be relevant
differences in the various rounds of sequencing. In addition I am
reasonably certain all the takara samples are in 2022 and 2023.
Ok, so now I should be able to comfortably process different
sequencing platform data using for-loops without worrying too much about
shenanigans.
I am therefore going to take a moment and peek in Theresa’s tree and
see how the early samples were trimmed.
Looking in Theresa’s tree, I see that she likely kept my original
trimmed data using cutadapt and also performed a trimomatic run. I took
a momemt and see that I used cutadapt because the version of trimomatic
at that time did not have the primers in it for this library type; but
that has since been ameliorated. I therefore assume that I can
comfortably trim with either trimomatic or fastp without problems. I
will definitely need to use fastqc after trimming and make certain that
none of the weirdo i3/i5(or whatever they are called) adapters
remain.
Oh, an important note: I only configured fastp recently in my
pipeline and it defaults to trying to do a UMI extraction, which is
inappropriate for these first samples. I need to remember to tell it not
to do that for these. Also, I do not fully understand UMIs yet.
module add cyoa/202402
cd 2019
start=$(pwd)
for i in $(/bin/ls -d iprgc*); do
echo "Starting $i"
cd $i
inputs=$(/bin/ls unprocessed/*.fastq.gz | tr '\n' ':' | sed 's/:$//g')
echo "The inputs are: ${inputs}"
cyoa --method trim --input "${inputs}" --jprefix 01
cyoa --method fastp --input "${inputs}" --jprefix 01
cd $start
done
Next steps, which will have to wait a few minutes: download a new
musculus assembly and check that my trimming results look like
Theresa’s.
LS0tCnRpdGxlOiAiUHJlcHJvY2Vzc2luZyB0aGUgSVBSR0Mgc2FtcGxlcyBkZS1ub3ZvLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIHdpZHRoOiAzMDAKICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogIGZvbnQtc2l6ZTogMTZweAp9CmJvZHkgLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE2MDBweDsKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCmxpYnJhcnkocmV0aWN1bGF0ZSkKdHQgPC0gdHJ5KGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQoCiAgcHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgd2lkdGggPSA5MCwgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlcnJvciA9IFRSVUUsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4LCBmaWcucmV0aW5hID0gMiwKICBvdXQud2lkdGggPSAiMTAwJSIsIGRldiA9ICJwbmciLAogIGRldi5hcmdzID0gbGlzdChwbmcgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cyA9IDQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSkKdmVyIDwtICIyMDIzMDUiCnByZXZpb3VzX2ZpbGUgPC0gIiIKdmVyIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCAiJVklbSVkIikKCiMjdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQpybWRfZmlsZSA8LSAicHJlcHJvY2Vzc2luZy5SbWQiCmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgZG9jdW1lbnQgYWltcyB0byByZWNvcmQgdGhlIHRhc2tzIHBlcmZvcm1lZCB0byByZS1wcmVwcm9jZXNzIHRoZQpJUFJHQyBzYW1wbGVzIG9mIHRoZSBTcGVlciBsYWIuICBJIGhhdmUgZXZlcnkgY29uZmlkZW5jZSB0aGF0IFRoZXJlc2EKZGlkIGV2ZXJ5dGhpbmcgcGVyZmVjdGx5LCB0aGUgb25seSByZWFzb24gSSB3aXNoIHRvIHJlZG8gdGhlc2UgdGFza3MKbGllcyBpbiB0aGUgZmFjdCB0aGF0IHdlIHJlb3JnYW5pemVkIHNsaWdodGx5IHRoZSBkYXRhIHRvIHJlcHJlc2VudAp0aGUgbmV3IGZpbGVzIHByb2R1Y2VkIGJ5IEFwcmlsIGZvbGxvd2luZyBhIHJlYXNzZXNzbWVudCBvZiB0aGUKc2FtcGxlcyBpbiB+MjAyNDA0LiAgSXQgdHVybnMgb3V0IHRoYXQgYSBzbWFsbCBudW1iZXIgb2Ygc2FtcGxlcyB3ZXJlCm1pc25hbWVkIGFuZCB0aGVyZWZvcmUgaXQgaXMgZGlmZmljdWx0IHRvIGVuc3VyZSB3aXRoIGFic29sdXRlCmNlcnRhaW50eSB0aGF0IHRoZSBleGlzdGluZyBzdGF0ZSBvZiBUaGVyZXNhJ3Mgd29ya2luZyB0cmVlIGlzCnJlcHJlc2VudGF0aXZlIG9mIHRoZSBuZXcgc3RhdGUgb2YgdGhlIHNhbXBsZXMuCgpUaHVzIGl0IGlzIHdvcnRoIGV4cGxhaW5pbmcgc2xpZ2h0bHkgd2hhdCBJIGRpZCBiZWZvcmUgc3RhcnRpbmcgdGhpcwpkb2N1bWVudDoKCjEuICBJIHNwZW50IHNvbWUgdGltZSB3aXRoIE5hamliIGFuZCBBcHJpbCBpbiBvcmRlciB0byBjcmVhdGUgdGhlCiAgICBzYW1wbGUgc2hlZXQgJzIwMjQwNTIxX3NwZWVyX2NvbnNvbGlkYXRlZF9zYW1wbGVfc2hlZXQueGxzeCcuCiAgICBUaGlzIGlzIG1vc3RseSBpZGVudGljYWwgdG8gVGhlcmVzYSdzIHdpdGggYSBmZXcgY2F2ZWF0czoKCiAgICBhLiAgVGhlcmUgaXMgbm93IGEgc2VyaWVzIG9mIGNvbHVtbnMgd2l0aCB0aGUgc3VmZml4ICdBSCcuICBXaXRoCiAgICAgICAgTmFqaWIncyBoZWxwLCBJIHJlY29uY2lsZWQgdGhlIGV4aXN0aW5nIElQUkdDIElEcyBjcmVhdGVkIGJ5CiAgICAgICAgVGhlcmVzYSB3aXRoIHRoZSBleHRhbnQgc2FtcGxlcyBhbmQgY29waWVkIEFwcmlsJ3Mgc2FtcGxlCiAgICAgICAgc2hlZXQgaW5mb3JtYXRpb24gaW50byB0aGVzZSBjb2x1bW5zLiAgVGhleSBoYXZlIHRoZSBuYW1lcwogICAgICAgICdQcm9qZWN0ICMgQUgnLCAnU2FtcGxlICMgQUgnLCAnUmFzaG1pJ3MgU2FtcGxlIE5hbWUgQUgnLAogICAgICAgICdQcmVwICYgQ2xlYW4gQUgnLCAnU2VxdWVuY2luZyBSdW4gQUgnLCAnUmVhZCAxIEFIJywgJ1JlYWQgMgogICAgICAgIEFIJywgJ1JlbG9hZCAmIE1hcCBBZ2FpbiBBSCcgYW5kIGNvbXByaXNlIGNvbHVtbnMgQU8tQVYuCiAgICAgICAgVGhlc2UgY29sdW1ucyBhcmUgb25seSBwb3B1bGF0ZWQgZm9yIHNhbXBsZXMgaXByZ2M2Mi1pcHJnYzEzMCwKICAgICAgICBiZWNhdXNlIHRoZXNlIGFyZSAoSSB0aGluaykgdGhlIG9ubHkgc2FtcGxlcyBzZXF1ZW5jZWQgYnkKICAgICAgICBBcHJpbCwgYW5kIGRlZmluaXRlbHkgdGhlIG9ubHkgc2FtcGxlcyBwb3RlbnRpYWxseSBhZmZlY3RlZCBieQogICAgICAgIHRoZSBmaWxlIHJlLWNvcHlpbmcuCiAgICBiLiAgR2l2ZW4gdGhlc2UgbmV3IGNvbHVtbnMsIEkgY3JlYXRlZCBhIHNlcmllcyBvZiBjb2x1bW5zIHdpdGgKICAgICAgICB0aGUgc3VmZml4ICdhdGInOiAnZ2Vub3R5cGVfYXRiJywgJ2xvY2F0aW9uX2F0YicsICd0aW1lX2F0YicsCiAgICAgICAgJ3RpbWVfZ2VvX2xvY2F0aW9uX3NvdXJjZV9hdGInLCBhbmQgJ3Jhc2htaV9jb2RlX2F0YicuICBUaGVzZQogICAgICAgIGNvbHVtbnMgYXJlIGdlbmVyYWxseSBpZGVudGljYWwgdG8gVGhlcmVzYSdzIGNvbHVtbnMgb2YgdGhlCiAgICAgICAgc2FtZSBpbmZvcm1hdGlvbiB3aXRoIHBvdGVudGlhbCBleGNlcHRpb25zIGluIHRoZSBjYXNlcyBvZiB0aGUKICAgICAgICBmaWxlcyB3aGljaCB3ZXJlIG1vdmVkL3Jlb3JnYW5pemVkLiAgVGhlCiAgICAgICAgJ3RpbWVfZ2VvX2xvY2F0aW9uX3NvdXJjZScgY29sdW1uIGlzIHVzZWQgdG8gc2lnbmlmeSB3aGVyZSBJCiAgICAgICAgdG9vayB0aGUgaW5mb3JtYXRpb24gZm9yIHRoZSBwcmV2aW91cyBjb2x1bW5zLCBlLmcuIGlmIGl0IHNheXMKICAgICAgICBUQUFfbWV0YSwgdGhlbiBJIHRvb2sgdGhlIGdlbm90eXBlIGV0YyBjbGFzc2lmaWNhdGlvbnMgZnJvbQogICAgICAgIFRoZXJlc2EncyBtZXRhZGF0YSB3aXRob3V0IGFueSBpbnRlcnByZXRhdGlvbi9tb2RpZmljYXRpb24uCiAgICAgICAgV2hlbiBpdCBzYXlzICdBSCBmaWxlbmFtZScsIHRoZW4gSSB0b29rIHRoYXQsIGFzIG9uZSBtaWdodAogICAgICAgIGV4cGVjdCwgZnJvbSBBcHJpbCdzIG5ld2x5IHByb3ZpZGVkIGZpbGVuYW1lcy4KICAgIGMuICBJIGxhdGVyIGFkZGVkIENvbHVtbiBBTiB3aGVuIGFzc2F5aW5nIE5hamliJ3MgcmF3X2RhdGEgdHJlZQogICAgICAgIGZvciB0aGVzZSBzYW1wbGVzLiAgTmFqaWIgaGFkIHByZXZpb3VzbHkgbm90IHBvcHVsYXRlZCBoaXMgcmF3CiAgICAgICAgZGlyZWN0b3J5IHRyZWUgd2l0aCBhbnkgc2FtcGxlID49IGlwcmdjXzY0OyBzbyBJIHJlY29yZGVkIGluCiAgICAgICAgdGhpcyBjb2x1bW4gYW55IGFjdGlvbnMgSSB0b29rLiAgVGhlc2UgYWN0aW9ucyBmZWxsIGludG8gdGhyZWUKICAgICAgICBjYXRlZ29yaWVzOiAgMS4gIE5vdGhpbmcgKHRoZSBmaXJzdCAyKSwgMi4gQWxtb3N0IG5vdGhpbmcgKHRoZQogICAgICAgIHJhdyBmaWxlcyB3ZXJlIGFjdHVhbGx5IGluIE5hamliJ3MgdHJlZSwgYnV0IGhlIGhhZCBub3QgeWV0CiAgICAgICAgcHV0IHRoZW0gaW50byB0aGUgJ3VucHJvY2Vzc2VkJyBkaXJlY3RvcnkuICAzLiAgTm90aGluZwogICAgICAgIGV4aXN0ZWQgeWV0LCBzbyBJIGNvcGllZCB0aGUgZmlsZXMgZnJvbSBteSBmcmVzaCB0cmVlCiAgICAgICAgKGRvd25sb2FkZWQgZnJvbSB0aGUgc2VxdWVuY2VyIGVhcmxpZXIgaW4gMjAyNDA1KSB0byB0aGUKICAgICAgICBhcHByb3ByaWF0ZSBkaXJlY3RvcmllcyBpbiBOYWppYidzIHRyZWUuICBJIHRoZW4gY29weS9wYXN0ZWQKICAgICAgICBteSBjb21tYW5kIGludG8gdGhpcyBjb2x1bW4gc28gdGhhdCB3ZSBtYXkgbGF0ZXIgZG91YmxlLWNoZWNrCiAgICAgICAgdGhlbS4gIEkgcHJvYmFibHkgY291bGQgaGF2ZSBwdXQgdGhpcyBpbmZvcm1hdGlvbiBpbnRvIHRoaXMKICAgICAgICBmaWxlLi4uCiAgICBkLiAgQXQgdGhpcyBtb21lbnQgSSBhZGRlZCBhIGNvbHVtbiAnc2VxdWVuY2VfdHlwZV9hdGInIHdoaWNoIGlzCiAgICAgICAgZWl0aGVyICdwcmV2aW91cycgb3IgJ3Rha2FyYScgc28gdGhhdCBJIGNhbiByZWNvcmQgdGhlIGxpa2VseQogICAgICAgIHJlcXVpcmVkIHRyaW1taW5nIHByb2Nlc3MuICBJIGFtIGhvcGVmdWwgdGhhdCB0aGlzIGNvbHVtbiB3aWxsCiAgICAgICAgbm90IGJlIG5lZWRlZCBhbmQgdGhhdCBJIHdpbGwgYmUgYWJsZSB0byB1c2UgZmFzdHAgdG8KICAgICAgICBpZGVudGljYWxseSB0cmVhdCBhbGwgc2FtcGxlcyBvbGQgYW5kIG5ldy4gIEkgaHlwb3RoZXNpemUgdGhpcwogICAgICAgIGlzIHBvc3NpYmxlIGFmdGVyIHNwZW5kaW5nIGEgbGl0dGxlIHRpbWUgcmVhZGluZyB0aGUgdGFrYXJhCiAgICAgICAgY29nZW50IHBhY2thZ2UgY29kZS4gIEl0IHNlZW1zIHRvIG1lIHRoYXQgdGhlaXIgdHJpbW1pbmcKICAgICAgICBvcGVyYXRpb25zIGFyZSBlaXRoZXIgY2xvc2UtdG8gb3IgaWRlbnRpY2FsIHRvIHdoYXQgZmFzdHAgd2lsbAogICAgICAgIHBlcmZvcm0uICBJZiB0aGF0IGlzIG5vdCB0cnVlLCB0aGVuIEkgd2lsbCBkbyBteSBkZWZhdWx0CiAgICAgICAgdHJpbW9tYXRpYy9mYXN0cCB0cmltbWluZyBmb3IgdGhlIHByZXZpb3VzIHNhbXBsZXMgYW5kIHRoZQogICAgICAgIGNvZ2VudCBtZXRob2QgZm9yIHRoZSBvdGhlcnMuICBJdCBzaG91bGQgYWxzbyBiZSBub3RlZCB0aGF0IEkKICAgICAgICBhbSBtYWtpbmcgdGhlIGFzc3VtcHRpb24gdGhhdCBhbnkgc2FtcGxlIDwgMjAyMSBpcyBub3QgdGFrYXJhCiAgICAgICAgYW5kIHZpY2UgdmVyc2EgKGUuZy4gYW55dGhpbmcgcmVjZWl2ZWQgd2l0aCBhIGRhdGUgYWZ0ZXIKICAgICAgICAyMDIwMTIyMSBpcyB0YWthcmEpLgoKMi4gIEl0IGlzIGhvcGVkIHRoYXQgMWMuIGFib3ZlIGhhcyBsZWZ0IG1lIGluIGEgY29uc2lzdGVudCBzdGF0ZSBhbmQKICAgIHRoYXQgSSBoYXZlIGV2ZXJ5IHNhbXBsZSByZXF1aXJlZCBpbiB0aGUgYXBwcm9wcmlhdGUgbG9jYXRpb24gaW4KICAgIE5hamliJ3MgdHJlZSBhbmQgdGhhdCB0aGV5IG1hdGNoIHRoZSBtb2RpZmllZCBzYW1wbGUgc2hlZXQuCjMuICBUaHVzIEkgY3JlYXRlZCBhIGZyZXNoIHdvcmtpbmcgdHJlZSBuYW1lZCAnbW11c2N1bHVzX2lwcmdjXzIwMjQnCiAgICBhbmQgcG9wdWxhdGVkIGl0IHdpdGggZW1wdHkgZGlyZWN0b3JpZXMgJ3NhbXBsZV9zaGVldHMnLAogICAgJ3JlZmVyZW5jZScsIGFuZCAncHJlcHJvY2Vzc2luZycuCgojIFBvcHVsYXRpbmcgdGhlIHJhdyBkYXRhCgpGcm9tIHRoaXMgcG9pbnQgb24sIGFueSBjb21tYW5kIHJ1biB3aWxsIGJlIHBlcmZvcm1lZCBpbiB0aGlzIHRleHQKZG9jdW1lbnQsIHNvIHlvdSB3aWxsIGdldCB0byByZWFkIGFsb25nIGFzIEkgbWFrZSBteQpkZWNpc2lvbnMvbWlzdGFrZXMuCgpJIGRlY2lkZWQgSSB3aWxsIHdvcmsgdXNpbmcgdGhlIHJlYWQtb25seSBjb3BpZXMgaW4gTmFqaWIncyB0cmVlLgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CmNkIHByZXByb2Nlc3NpbmcKbG4gLXMgL2ZzL2NiY2ItbGFiL25lbHNheWVkL3Jhd19kYXRhL3NwZWVyL2lwcmdjKiAuCmBgYAoKSSBub3cgaGF2ZSAxMjkgc3ltbGlua3MgaW4gbXkgcHJlcHJvY2Vzc2luZyBkaXJlY3Rvcnkgd2l0aCBvbmUgaG9sZQp3aGVyZSBhIHNhbXBsZSBnb3QgY2hhbmdlZCBhbmQgYSBjb3VwbGUgbmV3IGlwcmdjIElEcyBkdWUgdG8gdGhlCmNoYW5nZXMgaW50cm9kdWNlZCBieSBBcHJpbCdzIHJlcHJvY2Vzc2luZy4KCkFmdGVyIHN0YXJpbmcgYXQgdGhlIHNjcmVlbiBmb3IgYSBtb21lbnQsIEkgZGVjaWRlZCB0byBzcGxpdCB0aGVzZQpzYW1wbGVzIGludG8gc3ViZGlyZWN0b3JpZXMgbmFtZWQgYWZ0ZXIgdGhlIHNlcXVlbmNpbmcgeWVhciwgdGh1czoKCmBgYHtiYXNoLCBldmFsPUZBTFNFfQpta2RpciAyMDE5IDIwMjAgMjAyMiAyMDIzCgptdiBpcHJnY18wWzEtOF0gMjAxOQoKbXYgaXByZ2NfMDkgaXByZ2NfMSogaXByZ2NfMiogaXByZ2NfMyogaXByZ2NfNCogaXByZ2NfNSogaXByZ2NfNjAgaXByZ2NfNjEgMjAyMAoKbXYgaXByZ2NfNiogaXByZ2NfNyogaXByZ2NfOFswLTRdIDIwMjIKCm12IGlwcmdjKiAyMDIzCgojIyBoYWhhIEkgd2FzIGEgZG9vZnVzIGFuZCBtb3ZlZCB0aGUgMTAwcyBpbnRvIDIwMjAgZGlyZWN0b3J5IGJlY2F1c2UgaXByZ2NfMSogbWF0Y2hlcyAxMDArCm12IDIwMjAvaXByZ2NfMVswLTldWzAtOV0gMjAyMwpgYGAKCkkgYW0gZG9pbmcgdGhpcyBiZWNhdXNlIEkgYW0gZ3Vlc3NpbmcgdGhlcmUgbWF5IGJlIHJlbGV2YW50CmRpZmZlcmVuY2VzIGluIHRoZSB2YXJpb3VzIHJvdW5kcyBvZiBzZXF1ZW5jaW5nLiAgSW4gYWRkaXRpb24gSSBhbQpyZWFzb25hYmx5IGNlcnRhaW4gYWxsIHRoZSB0YWthcmEgc2FtcGxlcyBhcmUgaW4gMjAyMiBhbmQgMjAyMy4KCk9rLCBzbyBub3cgSSBzaG91bGQgYmUgYWJsZSB0byBjb21mb3J0YWJseSBwcm9jZXNzIGRpZmZlcmVudApzZXF1ZW5jaW5nIHBsYXRmb3JtIGRhdGEgdXNpbmcgZm9yLWxvb3BzIHdpdGhvdXQgd29ycnlpbmcgdG9vIG11Y2gKYWJvdXQgc2hlbmFuaWdhbnMuCgpJIGFtIHRoZXJlZm9yZSBnb2luZyB0byB0YWtlIGEgbW9tZW50IGFuZCBwZWVrIGluIFRoZXJlc2EncyB0cmVlIGFuZApzZWUgaG93IHRoZSBlYXJseSBzYW1wbGVzIHdlcmUgdHJpbW1lZC4KCkxvb2tpbmcgaW4gVGhlcmVzYSdzIHRyZWUsIEkgc2VlIHRoYXQgc2hlIGxpa2VseSBrZXB0IG15IG9yaWdpbmFsCnRyaW1tZWQgZGF0YSB1c2luZyBjdXRhZGFwdCBhbmQgYWxzbyBwZXJmb3JtZWQgYSB0cmltb21hdGljIHJ1bi4gIEkKdG9vayBhIG1vbWVtdCBhbmQgc2VlIHRoYXQgSSB1c2VkIGN1dGFkYXB0IGJlY2F1c2UgdGhlIHZlcnNpb24gb2YKdHJpbW9tYXRpYyBhdCB0aGF0IHRpbWUgZGlkIG5vdCBoYXZlIHRoZSBwcmltZXJzIGluIGl0IGZvciB0aGlzCmxpYnJhcnkgdHlwZTsgYnV0IHRoYXQgaGFzIHNpbmNlIGJlZW4gYW1lbGlvcmF0ZWQuICBJIHRoZXJlZm9yZSBhc3N1bWUKdGhhdCBJIGNhbiBjb21mb3J0YWJseSB0cmltIHdpdGggZWl0aGVyIHRyaW1vbWF0aWMgb3IgZmFzdHAgd2l0aG91dApwcm9ibGVtcy4gIEkgd2lsbCBkZWZpbml0ZWx5IG5lZWQgdG8gdXNlIGZhc3RxYyBhZnRlciB0cmltbWluZyBhbmQKbWFrZSBjZXJ0YWluIHRoYXQgbm9uZSBvZiB0aGUgd2VpcmRvIGkzL2k1KG9yIHdoYXRldmVyIHRoZXkgYXJlCmNhbGxlZCkgYWRhcHRlcnMgcmVtYWluLgoKT2gsIGFuIGltcG9ydGFudCBub3RlOiBJIG9ubHkgY29uZmlndXJlZCBmYXN0cCByZWNlbnRseSBpbiBteSBwaXBlbGluZQphbmQgaXQgZGVmYXVsdHMgdG8gdHJ5aW5nIHRvIGRvIGEgVU1JIGV4dHJhY3Rpb24sIHdoaWNoIGlzCmluYXBwcm9wcmlhdGUgZm9yIHRoZXNlIGZpcnN0IHNhbXBsZXMuICBJIG5lZWQgdG8gcmVtZW1iZXIgdG8gdGVsbCBpdApub3QgdG8gZG8gdGhhdCBmb3IgdGhlc2UuICBBbHNvLCBJIGRvIG5vdCBmdWxseSB1bmRlcnN0YW5kIFVNSXMgeWV0LgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9Cm1vZHVsZSBhZGQgY3lvYS8yMDI0MDIKY2QgMjAxOQpzdGFydD0kKHB3ZCkKZm9yIGkgaW4gJCgvYmluL2xzIC1kIGlwcmdjKik7IGRvCiAgICBlY2hvICJTdGFydGluZyAkaSIKICAgIGNkICRpCiAgICBpbnB1dHM9JCgvYmluL2xzIHVucHJvY2Vzc2VkLyouZmFzdHEuZ3ogfCB0ciAnXG4nICc6JyB8IHNlZCAncy86JC8vZycpCiAgICBlY2hvICJUaGUgaW5wdXRzIGFyZTogJHtpbnB1dHN9IgogICAgY3lvYSAtLW1ldGhvZCB0cmltIC0taW5wdXQgIiR7aW5wdXRzfSIgLS1qcHJlZml4IDAxCiAgICBjeW9hIC0tbWV0aG9kIGZhc3RwIC0taW5wdXQgIiR7aW5wdXRzfSIgLS1qcHJlZml4IDAxCiAgICBjZCAkc3RhcnQKZG9uZQpgYGAKCk5leHQgc3RlcHMsIHdoaWNoIHdpbGwgaGF2ZSB0byB3YWl0IGEgZmV3IG1pbnV0ZXM6IGRvd25sb2FkIGEgbmV3Cm11c2N1bHVzIGFzc2VtYmx5IGFuZCBjaGVjayB0aGF0IG15IHRyaW1taW5nIHJlc3VsdHMgbG9vayBsaWtlClRoZXJlc2Ency4K