RNA-seq Data
Analysis of RNA-seq requires the use of many types of data. The three most common that we will encounter are:
- Sequence data
- Genome feature data
- Alignment data
We will introduce each data type and their formats in more detail as they enter the workflow, but for now some general notes about the formats we will encounter:
- File formats represent the data in a structured manner.
- Some file formats are not human-readable; they are binary, and we will see what that means when we discuss alignments.
- Many file formats are human readable, but very large. These files should not be viewed in Word or Excel.
FASTQ Files
Raw sequenced reads are stored in FASTQ format. This is a plain text, human readable file format that stores information about each read. For a single read there are four lines:
@A00437:266:HVFMYDSXX:1:1101:1181:1000 1:N:0:AGCCTATC+TGCGTAAC
TTTATTGTTGATGGTTATTTTTTGTTTATGGTTATTTTGTGTTTATGGTTATTTTTTGTTTATGGTTATTTTTTA
+
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
1 |
Begins with @ and has information about the read. From AGC will contain flowcell and barcode information. |
2 |
The RNA sequence. |
3 |
Always begins with + and may contain the same information as line 1. |
4 |
A string of characters representing the quality scores. Always the same number of characters as line 2. |
Base Quality Scores
The fourth line encodes the quality of each nucleotide in the read. The most common encoding is referred to as PHRED-33, and the following maps characters to qualities:
Quality encoding: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI
| | | | |
Quality score: 0........10........20........30........40
The above example is a rather boring read with all bases having F
, meaning a score of 37, which is good. Each quality score represents the probability that the corresponding nucleotide call is incorrect. The quality score is logarithmic and is calculated as:
Q = -10 x log10(P), where P is the probability that the base call is erroneous
Another way to interpret the scores is in terms of the following table:
10 |
1 in 10 |
90% |
20 |
1 in 100 |
99% |
30 |
1 in 1000 |
99.9% |
40 |
1 in 10000 |
99.99% |
It would clearly be painstaking to go through all the base quality scores of all the millions of reads obtained from a sequencing run, so we typically don’t evaluate the FASTQ files by sight. Instead, we use tools that take in FASTQ files and summarize the base quality scores (and other characteristics) to determine the overall quality of the reads from the sequencer.
Quality Assessment with FastQC
The first step in many high-throughput sequencing analyses is to examine the quality of the raw reads with FastQC. It analyzes various aspects of each FASTQ file and provides a quick impression of the overall quality metrics which are useful to determine before proceeding with downstream analysis. The following modules are present in an easy to read HTML report.
- Read quality score per base (by interpreting the PHRED33 scores)
- Per tile sequencing quality (related to sequencing clusters on the flowcell)
- Read lengths
- GC content
- Adapter content
- Overrepresented sequences
Toward the end of this module, we’ll run FastQC. For now, we’ll discuss the output files it produces and view some examples.
FastQC output files
FastQC outputs an HTML report and a zipped archive of intermediate files. These will appear like this:
sample_A_R1.trimmed_fastqc.html
sample_A_R1.trimmed_fastqc.zip
For most situations, opening the HTML report and inspecting the results will provide the information necessary to make decisions about your data.
First we’ll take a look at some of the figures found in a typical FastQC report, then we’ll view an example of an HTML report and try to make interpretations from this. Finally, we’ll run FastQC to produce some of these files from our example dataset.
Interpreting FastQC
FastQC reports are organized around the the different modules characterizing different aspects of the reads. The FastQC help page has detailed descriptions for each module.
The report summary is a PASS, WARN, FAIL overview of the modules. It’s important to not take them too seriously in all cases as there are a number of assumptions that go into the thresholds that may not apply in your particular experiment.
An important note: For computational reasons, FastQC only evaluates the first 100,000 reads in a FASTQ file. The assumption is that the first 100,000 reads sufficiently represent the full library.
Per base sequence quality
A per base boxplot of the quality scores with helpful coloring for good, fair, and poor qualities. If a sample has quality scores that degrade at the 3’ end of a read (as in the second example below), the sample doesn’t necessarily have to be dropped. Some aligners, e.g. STAR, will automatically trim poor quality read ends.
An example of a good quality run.
An example of a poor quality run.
Sequence Duplication
High sequence duplication, indicated by a skew to the right of the blue curve in the plots below, can be caused by low complexity libraries, too many cycles of PCR amplification, or too little starting material.
On the other hand, if the library was prepared with an enrichment step (e.g. ChIP-seq), then sequence duplication might not be unexpected.
An example of a sample with low sequence duplication levels.
An example of a sample with high sequence duplication levels.
Overrepresented sequences
Overrepresented sequences are those making up more than 0.1% of the total (of the 100,000 reads sampled). Finding an overrepresented sequence is an indication of something biologically meaningful (e.g. an enrichment step in the library prep process), or it is an issue stemming from the library preparation process (e.g. adapters, a failure to fully remove polyA tails, or contamination).
We see that there is a high number of reads with polyA tails. This could be a result of an inefficient removal of polyA tails.
Adapter Content
Adapter sequence typically is not present in standard RNA-seq libraries. However, if the fragment sizes resulting from library prep are smaller than the read length on the sequencer, then it is possible to get “read-through” of the adapter.
This can be dealt with by adding a step to the workflow that trims the reads of adapter content with a tool such as cutadapt. We will see this in a later module.
Examining a FastQC report
From the zipped folder you downloaded earlier, find the FastQC report sample_A_R1.trimmed_fastqc.html
.
We’ll view this report and try to interpret some of the figures.
Acting on QC - Good or Bad Results?
Good QC on raw reads means that RNA quality, library preparation, and sequencing seem fine to proceed with the next steps of analysis. It does not mean that you will find differentially expressed genes downstream.
The source of bad QC measures are not always easy to determine, and doesn’t necessarily mean the data cannot be used downstream. However, bad QC measures may indicate that hazards lie ahead, and that certain steps upstream of sequencing (sample handling, RNA extraction, library preparation) might need to be altered.
FastQC Exercise
Let’s try running FastQC on our FASTQ input files.
- Navigate to
analysis
directory
- View FastQC help file
- Construct the call to FastQC
- Watch FastQC process the files / gather quality metrics
- View the output of FastQC (the filenames)
# Navigate to analysis directory
cd ~/RSD_Shell/analysis
# View the FastQC help file
fastqc -h
# Make a directory for our output
mkdir out_fastqc
# Contstruct the call to FastQC
fastqc -o out_fastqc/ ../reads/*.fastq.gz
# Watch the output of FastQC
# View the output of FastQC (the filenames)
These materials have been adapted and extended from materials created by the Harvard Chan Bioinformatics Core (HBC). These are open access materials distributed under the terms of the Creative Commons Attribution license (CC BY 4.0), which permits unrestricted use, distribution, and reproduction in any medium, provided the original author and source are credited.
LS0tCnRpdGxlOiAiTW9kdWxlIDAyYTogU2VxdWVuY2UgUUMiCmF1dGhvcjogIlVNIEJpb2luZm9ybWF0aWNzIENvcmUiCm91dHB1dDoKICAgICAgICBodG1sX2RvY3VtZW50OgogICAgICAgICAgICBpbmNsdWRlczoKICAgICAgICAgICAgICAgIGluX2hlYWRlcjogaGVhZGVyLmh0bWwKICAgICAgICAgICAgdGhlbWU6IHBhcGVyCiAgICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgICB0b2NfZGVwdGg6IDQKICAgICAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgICAgICAgICAgZmlnX2NhcHRpb246IHRydWUKICAgICAgICAgICAgbWFya2Rvd246IEdGTQogICAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5eyAvKiBOb3JtYWwgICovCiAgICAgIGZvbnQtc2l6ZTogMTRwdDsKICB9CnByZSB7CiAgZm9udC1zaXplOiAxMnB0Cn0KPC9zdHlsZT4KCiMgU2VxdWVuY2UgUUMgYW5kIEZBU1RRIEZpbGVzCgpJbiB0aGlzIFF1YWxpdHkgQ29udHJvbCAoUUMpIG1vZHVsZSwgd2Ugd2lsbCBsZWFybjoKCiogd2hhdCBhIEZBU1RRIGZpbGUgaXMKKiBob3cgdG8gdXNlIEZhc3RRQyB0byBhc3Nlc3MgdGhlIHF1YWxpdHkgb2Ygc2VxdWVuY2luZyByZWFkcwoqIGhvdyB0byBpbnRlcnByZXQgRmFzdFFDIHJlcG9ydHMKCiMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gV29ya2Zsb3cKCkFuIG92ZXJ2aWV3IG9mIHRoZSBzdGVwcyBvZiBlbnRpcmUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gZXhwZXJpbWVudCBhbmQgYW5hbHlzaXMgd29ya2Zsb3cgaXMgc2hvd24gYmVsb3cuIEluIHRoaXMgbGVzc29uLCB3ZSB3aWxsIGdvIG92ZXIgdGhlIGhpZ2hsaWdodGVkIHBhcnQgb2YgdGhlIHdvcmtmbG93LgoKIVtdKGltYWdlcy93YXlmaW5kZXIvd2F5ZmluZGVyLVNlcXVlbmNlX1FDLnBuZykKPGJyPgo8YnI+Cjxicj4KPGJyPgoKIyBSTkEtc2VxIERhdGEKCkFuYWx5c2lzIG9mIFJOQS1zZXEgcmVxdWlyZXMgdGhlIHVzZSBvZiBtYW55IHR5cGVzIG9mIGRhdGEuIFRoZSB0aHJlZSBtb3N0IGNvbW1vbiB0aGF0IHdlIHdpbGwgZW5jb3VudGVyIGFyZToKCi0gU2VxdWVuY2UgZGF0YQotIEdlbm9tZSBmZWF0dXJlIGRhdGEKLSBBbGlnbm1lbnQgZGF0YQoKV2Ugd2lsbCBpbnRyb2R1Y2UgZWFjaCBkYXRhIHR5cGUgYW5kIHRoZWlyIGZvcm1hdHMgaW4gbW9yZSBkZXRhaWwgYXMgdGhleSBlbnRlciB0aGUgd29ya2Zsb3csIGJ1dCBmb3Igbm93IHNvbWUgZ2VuZXJhbCBub3RlcyBhYm91dCB0aGUgZm9ybWF0cyB3ZSB3aWxsIGVuY291bnRlcjoKCi0gRmlsZSBmb3JtYXRzIHJlcHJlc2VudCB0aGUgZGF0YSBpbiBhIHN0cnVjdHVyZWQgbWFubmVyLgotIFNvbWUgZmlsZSBmb3JtYXRzIGFyZSBub3QgaHVtYW4tcmVhZGFibGU7IHRoZXkgYXJlIGJpbmFyeSwgYW5kIHdlIHdpbGwgc2VlIHdoYXQgdGhhdCBtZWFucyB3aGVuIHdlIGRpc2N1c3MgYWxpZ25tZW50cy4KLSBNYW55IGZpbGUgZm9ybWF0cyBhcmUgaHVtYW4gcmVhZGFibGUsIGJ1dCB2ZXJ5IGxhcmdlLiAqKlRoZXNlIGZpbGVzIHNob3VsZCBub3QgYmUgdmlld2VkIGluIFdvcmQgb3IgRXhjZWwuKioKCiMjIEZBU1RRIEZpbGVzCgpSYXcgc2VxdWVuY2VkIHJlYWRzIGFyZSBzdG9yZWQgaW4gW0ZBU1RRXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GQVNUUV9mb3JtYXQpIGZvcm1hdC4gVGhpcyBpcyBhIHBsYWluIHRleHQsIGh1bWFuIHJlYWRhYmxlIGZpbGUgZm9ybWF0IHRoYXQgc3RvcmVzIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggcmVhZC4gRm9yIGEgc2luZ2xlIHJlYWQgdGhlcmUgYXJlIGZvdXIgbGluZXM6CgoKICAgIEBBMDA0Mzc6MjY2OkhWRk1ZRFNYWDoxOjExMDE6MTE4MToxMDAwIDE6TjowOkFHQ0NUQVRDK1RHQ0dUQUFDCiAgICBUVFRBVFRHVFRHQVRHR1RUQVRUVFRUVEdUVFRBVEdHVFRBVFRUVEdUR1RUVEFUR0dUVEFUVFRUVFRHVFRUQVRHR1RUQVRUVFRUVEEKICAgICsKICAgIEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRgoKCnwgTGluZSB8IERlc2NyaXB0aW9uIHwKfCA6LS06IHwgLS0tLS0tLS0tLS0gfAp8IDEgfCBCZWdpbnMgd2l0aCBgQGAgYW5kIGhhcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcmVhZC4gRnJvbSBBR0Mgd2lsbCBjb250YWluIGZsb3djZWxsIGFuZCBiYXJjb2RlIGluZm9ybWF0aW9uLiB8CnwgMiB8IFRoZSBSTkEgc2VxdWVuY2UuIHwKfCAzIHwgQWx3YXlzIGJlZ2lucyB3aXRoIGArYCBhbmQgbWF5IGNvbnRhaW4gdGhlIHNhbWUgaW5mb3JtYXRpb24gYXMgbGluZSAxLiB8CnwgNCB8IEEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50aW5nIHRoZSBxdWFsaXR5IHNjb3Jlcy4gQWx3YXlzIHRoZSBzYW1lIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFzIGxpbmUgMi4gfAoKIyMjIEJhc2UgUXVhbGl0eSBTY29yZXMKClRoZSBmb3VydGggbGluZSBlbmNvZGVzIHRoZSBxdWFsaXR5IG9mIGVhY2ggbnVjbGVvdGlkZSBpbiB0aGUgcmVhZC4gVGhlIG1vc3QgY29tbW9uIGVuY29kaW5nIGlzIHJlZmVycmVkIHRvIGFzIFBIUkVELTMzLCBhbmQgdGhlIGZvbGxvd2luZyBtYXBzIGNoYXJhY3RlcnMgdG8gcXVhbGl0aWVzOgoKCiAgICBRdWFsaXR5IGVuY29kaW5nOiAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISQogICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgIHwgICAgICAgICB8ICAgICAgICAgfCAgICAgICAgIHwKICAgICAgIFF1YWxpdHkgc2NvcmU6IDAuLi4uLi4uLjEwLi4uLi4uLi4yMC4uLi4uLi4uMzAuLi4uLi4uLjQwCgoKVGhlIGFib3ZlIGV4YW1wbGUgaXMgYSByYXRoZXIgYm9yaW5nIHJlYWQgd2l0aCBhbGwgYmFzZXMgaGF2aW5nIGBGYCwgbWVhbmluZyBhIHNjb3JlIG9mIDM3LCB3aGljaCBpcyBnb29kLiBFYWNoIHF1YWxpdHkgc2NvcmUgcmVwcmVzZW50cyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgY29ycmVzcG9uZGluZyBudWNsZW90aWRlIGNhbGwgaXMgaW5jb3JyZWN0LiBUaGUgcXVhbGl0eSBzY29yZSBpcyBsb2dhcml0aG1pYyBhbmQgaXMgY2FsY3VsYXRlZCBhczoKCgogICAgUSA9IC0xMCB4IGxvZzEwKFApLCB3aGVyZSBQIGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBiYXNlIGNhbGwgaXMgZXJyb25lb3VzCgoKQW5vdGhlciB3YXkgdG8gaW50ZXJwcmV0IHRoZSBzY29yZXMgaXMgaW4gdGVybXMgb2YgdGhlIGZvbGxvd2luZyB0YWJsZToKCnwgUEhSRUQgUXVhbGl0eSBTY29yZSB8IFByb2JhYmlsaXR5IG9mIGluY29ycmVjdCBiYXNlIGNhbGwgfCBCYXNlIGNhbGwgYWNjdXJhY3kgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tIHwKfCAxMCB8IDEgaW4gMTAgfCA5MCUgfAp8IDIwIHwgMSBpbiAxMDAgfCA5OSUgfAp8IDMwIHwgMSBpbiAxMDAwIHwgOTkuOSUgfAp8IDQwIHwgMSBpbiAxMDAwMCB8IDk5Ljk5JSB8CgpJdCB3b3VsZCBjbGVhcmx5IGJlIHBhaW5zdGFraW5nIHRvIGdvIHRocm91Z2ggYWxsIHRoZSBiYXNlIHF1YWxpdHkgc2NvcmVzIG9mIGFsbCB0aGUgbWlsbGlvbnMgb2YgcmVhZHMgb2J0YWluZWQgZnJvbSBhIHNlcXVlbmNpbmcgcnVuLCBzbyB3ZSB0eXBpY2FsbHkgZG9uJ3QgZXZhbHVhdGUgdGhlIEZBU1RRIGZpbGVzIGJ5IHNpZ2h0LiBJbnN0ZWFkLCB3ZSB1c2UgdG9vbHMgdGhhdCB0YWtlIGluIEZBU1RRIGZpbGVzIGFuZCBzdW1tYXJpemUgdGhlIGJhc2UgcXVhbGl0eSBzY29yZXMgKGFuZCBvdGhlciBjaGFyYWN0ZXJpc3RpY3MpIHRvIGRldGVybWluZSB0aGUgb3ZlcmFsbCBxdWFsaXR5IG9mIHRoZSByZWFkcyBmcm9tIHRoZSBzZXF1ZW5jZXIuCgojIFF1YWxpdHkgQXNzZXNzbWVudCB3aXRoIEZhc3RRQwoKIVtGYXN0UUNdKGltYWdlcy9mYXN0cWNfbG9nby5wbmcpCgpUaGUgZmlyc3Qgc3RlcCBpbiBtYW55IGhpZ2gtdGhyb3VnaHB1dCBzZXF1ZW5jaW5nIGFuYWx5c2VzIGlzIHRvIGV4YW1pbmUgdGhlIHF1YWxpdHkgb2YgdGhlIHJhdyByZWFkcyB3aXRoIFtGYXN0UUNdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy8pLiBJdCBhbmFseXplcyB2YXJpb3VzIGFzcGVjdHMgb2YgZWFjaCBGQVNUUSBmaWxlIGFuZCBwcm92aWRlcyBhIHF1aWNrIGltcHJlc3Npb24gb2YgdGhlIG92ZXJhbGwgcXVhbGl0eSBtZXRyaWNzIHdoaWNoIGFyZSB1c2VmdWwgdG8gZGV0ZXJtaW5lIGJlZm9yZSBwcm9jZWVkaW5nIHdpdGggZG93bnN0cmVhbSBhbmFseXNpcy4gVGhlIGZvbGxvd2luZyBtb2R1bGVzIGFyZSBwcmVzZW50IGluIGFuIGVhc3kgdG8gcmVhZCBIVE1MIHJlcG9ydC4KCi0gUmVhZCBxdWFsaXR5IHNjb3JlIHBlciBiYXNlIChieSBpbnRlcnByZXRpbmcgdGhlIFBIUkVEMzMgc2NvcmVzKQotIFBlciB0aWxlIHNlcXVlbmNpbmcgcXVhbGl0eSAocmVsYXRlZCB0byBzZXF1ZW5jaW5nIGNsdXN0ZXJzIG9uIHRoZSBmbG93Y2VsbCkKLSBSZWFkIGxlbmd0aHMKLSBHQyBjb250ZW50Ci0gQWRhcHRlciBjb250ZW50Ci0gT3ZlcnJlcHJlc2VudGVkIHNlcXVlbmNlcwoKVG93YXJkIHRoZSBlbmQgb2YgdGhpcyBtb2R1bGUsIHdlJ2xsIHJ1biBGYXN0UUMuIEZvciBub3csIHdlJ2xsIGRpc2N1c3MgdGhlIG91dHB1dCBmaWxlcyBpdCBwcm9kdWNlcyBhbmQgdmlldyBzb21lIGV4YW1wbGVzLgoKIyMgRmFzdFFDIG91dHB1dCBmaWxlcwoKRmFzdFFDIG91dHB1dHMgYW4gSFRNTCByZXBvcnQgYW5kIGEgemlwcGVkIGFyY2hpdmUgb2YgaW50ZXJtZWRpYXRlIGZpbGVzLiBUaGVzZSB3aWxsIGFwcGVhciBsaWtlIHRoaXM6CgogICAgc2FtcGxlX0FfUjEudHJpbW1lZF9mYXN0cWMuaHRtbAogICAgc2FtcGxlX0FfUjEudHJpbW1lZF9mYXN0cWMuemlwCgpGb3IgbW9zdCBzaXR1YXRpb25zLCBvcGVuaW5nIHRoZSBIVE1MIHJlcG9ydCBhbmQgaW5zcGVjdGluZyB0aGUgcmVzdWx0cyB3aWxsIHByb3ZpZGUgdGhlIGluZm9ybWF0aW9uIG5lY2Vzc2FyeSB0byBtYWtlIGRlY2lzaW9ucyBhYm91dCB5b3VyIGRhdGEuCgpGaXJzdCB3ZSdsbCB0YWtlIGEgbG9vayBhdCBzb21lIG9mIHRoZSBmaWd1cmVzIGZvdW5kIGluIGEgdHlwaWNhbCBGYXN0UUMgcmVwb3J0LCB0aGVuIHdlJ2xsIHZpZXcgYW4gZXhhbXBsZSBvZiBhbiBIVE1MIHJlcG9ydCBhbmQgdHJ5IHRvIG1ha2UgaW50ZXJwcmV0YXRpb25zIGZyb20gdGhpcy4gRmluYWxseSwgd2UnbGwgcnVuIEZhc3RRQyB0byBwcm9kdWNlIHNvbWUgb2YgdGhlc2UgZmlsZXMgZnJvbSBvdXIgZXhhbXBsZSBkYXRhc2V0LgoKCiMjIEludGVycHJldGluZyBGYXN0UUMKCkZhc3RRQyByZXBvcnRzIGFyZSBvcmdhbml6ZWQgYXJvdW5kIHRoZSB0aGUgZGlmZmVyZW50IG1vZHVsZXMgY2hhcmFjdGVyaXppbmcgZGlmZmVyZW50IGFzcGVjdHMgb2YgdGhlIHJlYWRzLiBUaGUgRmFzdFFDIFtoZWxwIHBhZ2VdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy9IZWxwLykgaGFzIGRldGFpbGVkIGRlc2NyaXB0aW9ucyBmb3IgZWFjaCBtb2R1bGUuCgpUaGUgcmVwb3J0IHN1bW1hcnkgaXMgYSBQQVNTLCBXQVJOLCBGQUlMIG92ZXJ2aWV3IG9mIHRoZSBtb2R1bGVzLiBJdCdzIGltcG9ydGFudCB0byBub3QgdGFrZSB0aGVtIHRvbyBzZXJpb3VzbHkgaW4gYWxsIGNhc2VzIGFzIHRoZXJlIGFyZSBhIG51bWJlciBvZiBhc3N1bXB0aW9ucyB0aGF0IGdvIGludG8gdGhlIHRocmVzaG9sZHMgdGhhdCBtYXkgbm90IGFwcGx5IGluIHlvdXIgcGFydGljdWxhciBleHBlcmltZW50LgoKQW4gaW1wb3J0YW50IG5vdGU6IEZvciBjb21wdXRhdGlvbmFsIHJlYXNvbnMsIEZhc3RRQyBvbmx5IGV2YWx1YXRlcyB0aGUgZmlyc3QgMTAwLDAwMCByZWFkcyBpbiBhIEZBU1RRIGZpbGUuIFRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgdGhlIGZpcnN0IDEwMCwwMDAgcmVhZHMgc3VmZmljaWVudGx5IHJlcHJlc2VudCB0aGUgZnVsbCBsaWJyYXJ5LgoKIyMjIFBlciBiYXNlIHNlcXVlbmNlIHF1YWxpdHkKCkEgcGVyIGJhc2UgYm94cGxvdCBvZiB0aGUgcXVhbGl0eSBzY29yZXMgd2l0aCBoZWxwZnVsIGNvbG9yaW5nIGZvciBnb29kLCBmYWlyLCBhbmQgcG9vciBxdWFsaXRpZXMuIElmIGEgc2FtcGxlIGhhcyBxdWFsaXR5IHNjb3JlcyB0aGF0IGRlZ3JhZGUgYXQgdGhlIDMnIGVuZCBvZiBhIHJlYWQgKGFzIGluIHRoZSBzZWNvbmQgZXhhbXBsZSBiZWxvdyksIHRoZSBzYW1wbGUgZG9lc24ndCBuZWNlc3NhcmlseSBoYXZlIHRvIGJlIGRyb3BwZWQuIFNvbWUgYWxpZ25lcnMsIGUuZy4gU1RBUiwgd2lsbCBhdXRvbWF0aWNhbGx5IHRyaW0gcG9vciBxdWFsaXR5IHJlYWQgZW5kcy4KCjxjZW50ZXI+Cgo8aW1nIHNyYz0iaW1hZ2VzL2Zhc3RxY19wZXJfYmFzZS5wbmciIHdpZHRoPSI4MDAiLz4KCgpBbiBleGFtcGxlIG9mIGEgZ29vZCBxdWFsaXR5IHJ1bi4KCjwvY2VudGVyPgoKPGNlbnRlcj4KCjxpbWcgc3JjPSJpbWFnZXMvZmFzdHFjX3Bvb3JfcGVyX2Jhc2UucG5nIiB3aWR0aD0iODAwIiAvPgoKQW4gZXhhbXBsZSBvZiBhIHBvb3IgcXVhbGl0eSBydW4uCgo8L2NlbnRlcj4KCiMjIyBTZXF1ZW5jZSBEdXBsaWNhdGlvbgoKSGlnaCBzZXF1ZW5jZSBkdXBsaWNhdGlvbiwgaW5kaWNhdGVkIGJ5IGEgc2tldyB0byB0aGUgcmlnaHQgb2YgdGhlIGJsdWUgY3VydmUgaW4gdGhlIHBsb3RzIGJlbG93LCBjYW4gYmUgY2F1c2VkIGJ5IGxvdyBjb21wbGV4aXR5IGxpYnJhcmllcywgdG9vIG1hbnkgY3ljbGVzIG9mIFBDUiBhbXBsaWZpY2F0aW9uLCBvciB0b28gbGl0dGxlIHN0YXJ0aW5nIG1hdGVyaWFsLgoKT24gdGhlIG90aGVyIGhhbmQsIGlmIHRoZSBsaWJyYXJ5IHdhcyBwcmVwYXJlZCB3aXRoIGFuIGVucmljaG1lbnQgc3RlcCAoZS5nLiBDaElQLXNlcSksIHRoZW4gc2VxdWVuY2UgZHVwbGljYXRpb24gbWlnaHQgbm90IGJlIHVuZXhwZWN0ZWQuCgo8Y2VudGVyPgoKPGltZyBzcmM9ImltYWdlcy9mYXN0cWNfZHVwbGljYXRpb24ucG5nIiB3aWR0aD0iODAwIiAvPgoKQW4gZXhhbXBsZSBvZiBhIHNhbXBsZSB3aXRoIGxvdyBzZXF1ZW5jZSBkdXBsaWNhdGlvbiBsZXZlbHMuCgo8L2NlbnRlcj4KCjxjZW50ZXI+Cgo8aW1nIHNyYz0iaW1hZ2VzL2Zhc3RxY19wb29yX2R1cGxpY2F0aW9uLnBuZyIgd2lkdGg9IjgwMCIgLz4KCkFuIGV4YW1wbGUgb2YgYSBzYW1wbGUgd2l0aCBoaWdoIHNlcXVlbmNlIGR1cGxpY2F0aW9uIGxldmVscy4KCjwvY2VudGVyPgoKIyMjIE92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZXMKCk92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZXMgYXJlIHRob3NlIG1ha2luZyB1cCBtb3JlIHRoYW4gMC4xJSBvZiB0aGUgdG90YWwgKG9mIHRoZSAxMDAsMDAwIHJlYWRzIHNhbXBsZWQpLiBGaW5kaW5nIGFuIG92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZSBpcyBhbiBpbmRpY2F0aW9uIG9mIHNvbWV0aGluZyBiaW9sb2dpY2FsbHkgbWVhbmluZ2Z1bCAoZS5nLiBhbiBlbnJpY2htZW50IHN0ZXAgaW4gdGhlIGxpYnJhcnkgcHJlcCBwcm9jZXNzKSwgb3IgaXQgaXMgYW4gaXNzdWUgc3RlbW1pbmcgZnJvbSB0aGUgbGlicmFyeSBwcmVwYXJhdGlvbiBwcm9jZXNzIChlLmcuIGFkYXB0ZXJzLCBhIGZhaWx1cmUgdG8gZnVsbHkgcmVtb3ZlIHBvbHlBIHRhaWxzLCBvciBjb250YW1pbmF0aW9uKS4KCjxjZW50ZXI+Cgo8aW1nIHNyYz0iaW1hZ2VzL2Zhc3RxY19vdmVycmVwcmVzZW50ZWQucG5nIiB3aWR0aD0iODAwIiAvPgoKV2Ugc2VlIHRoYXQgdGhlcmUgaXMgYSBoaWdoIG51bWJlciBvZiByZWFkcyB3aXRoIHBvbHlBIHRhaWxzLiBUaGlzIGNvdWxkIGJlIGEgcmVzdWx0IG9mIGFuIGluZWZmaWNpZW50IHJlbW92YWwgb2YgcG9seUEgdGFpbHMuCgo8L2NlbnRlcj4KCiMjIyBBZGFwdGVyIENvbnRlbnQKCkFkYXB0ZXIgc2VxdWVuY2UgdHlwaWNhbGx5IGlzIG5vdCBwcmVzZW50IGluIHN0YW5kYXJkIFJOQS1zZXEgbGlicmFyaWVzLiBIb3dldmVyLCBpZiB0aGUgZnJhZ21lbnQgc2l6ZXMgcmVzdWx0aW5nIGZyb20gbGlicmFyeSBwcmVwIGFyZSBzbWFsbGVyIHRoYW4gdGhlIHJlYWQgbGVuZ3RoIG9uIHRoZSBzZXF1ZW5jZXIsIHRoZW4gaXQgaXMgcG9zc2libGUgdG8gZ2V0ICJyZWFkLXRocm91Z2giIG9mIHRoZSBhZGFwdGVyLgoKVGhpcyBjYW4gYmUgZGVhbHQgd2l0aCBieSBhZGRpbmcgYSBzdGVwIHRvIHRoZSB3b3JrZmxvdyB0aGF0IHRyaW1zIHRoZSByZWFkcyBvZiBhZGFwdGVyIGNvbnRlbnQgd2l0aCBhIHRvb2wgc3VjaCBhcyBbY3V0YWRhcHRdKGh0dHBzOi8vY3V0YWRhcHQucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlLykuIFdlIHdpbGwgc2VlIHRoaXMgaW4gYSBsYXRlciBtb2R1bGUuCgojIyBFeGFtaW5pbmcgYSBGYXN0UUMgcmVwb3J0CgpGcm9tIHRoZSB6aXBwZWQgZm9sZGVyIHlvdSBkb3dubG9hZGVkIGVhcmxpZXIsIGZpbmQgdGhlIEZhc3RRQyByZXBvcnQgYHNhbXBsZV9BX1IxLnRyaW1tZWRfZmFzdHFjLmh0bWxgLgoKV2UnbGwgdmlldyB0aGlzIHJlcG9ydCBhbmQgdHJ5IHRvIGludGVycHJldCBzb21lIG9mIHRoZSBmaWd1cmVzLgoKIyMgQWN0aW5nIG9uIFFDIC0gR29vZCBvciBCYWQgUmVzdWx0cz8KCkdvb2QgUUMgb24gcmF3IHJlYWRzIG1lYW5zIHRoYXQgUk5BIHF1YWxpdHksIGxpYnJhcnkgcHJlcGFyYXRpb24sIGFuZCBzZXF1ZW5jaW5nIHNlZW0gZmluZSB0byBwcm9jZWVkIHdpdGggdGhlIG5leHQgc3RlcHMgb2YgYW5hbHlzaXMuIEl0ICoqZG9lcyBub3QqKiBtZWFuIHRoYXQgeW91IHdpbGwgZmluZCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgZG93bnN0cmVhbS4KClRoZSBzb3VyY2Ugb2YgYmFkIFFDIG1lYXN1cmVzIGFyZSBub3QgYWx3YXlzIGVhc3kgdG8gZGV0ZXJtaW5lLCBhbmQgZG9lc24ndCBuZWNlc3NhcmlseSBtZWFuIHRoZSBkYXRhIGNhbm5vdCBiZSB1c2VkIGRvd25zdHJlYW0uIEhvd2V2ZXIsIGJhZCBRQyBtZWFzdXJlcyBtYXkgaW5kaWNhdGUgdGhhdCBoYXphcmRzIGxpZSBhaGVhZCwgYW5kIHRoYXQgY2VydGFpbiBzdGVwcyB1cHN0cmVhbSBvZiBzZXF1ZW5jaW5nIChzYW1wbGUgaGFuZGxpbmcsIFJOQSBleHRyYWN0aW9uLCBsaWJyYXJ5IHByZXBhcmF0aW9uKSBtaWdodCBuZWVkIHRvIGJlIGFsdGVyZWQuCgojIyBGYXN0UUMgRXhlcmNpc2UKCkxldCdzIHRyeSBydW5uaW5nIEZhc3RRQyBvbiBvdXIgRkFTVFEgaW5wdXQgZmlsZXMuCgoxLiBOYXZpZ2F0ZSB0byBgYW5hbHlzaXNgIGRpcmVjdG9yeQoyLiBWaWV3IEZhc3RRQyBoZWxwIGZpbGUKMy4gQ29uc3RydWN0IHRoZSBjYWxsIHRvIEZhc3RRQwo0LiBXYXRjaCBGYXN0UUMgcHJvY2VzcyB0aGUgZmlsZXMgLyBnYXRoZXIgcXVhbGl0eSBtZXRyaWNzCjUuIFZpZXcgdGhlIG91dHB1dCBvZiBGYXN0UUMgKHRoZSBmaWxlbmFtZXMpCgpgYGAKIyBOYXZpZ2F0ZSB0byBhbmFseXNpcyBkaXJlY3RvcnkKY2Qgfi9SU0RfU2hlbGwvYW5hbHlzaXMKIyBWaWV3IHRoZSBGYXN0UUMgaGVscCBmaWxlCmZhc3RxYyAtaAojIE1ha2UgYSBkaXJlY3RvcnkgZm9yIG91ciBvdXRwdXQKbWtkaXIgb3V0X2Zhc3RxYwojIENvbnRzdHJ1Y3QgdGhlIGNhbGwgdG8gRmFzdFFDCmZhc3RxYyAtbyBvdXRfZmFzdHFjLyAuLi9yZWFkcy8qLmZhc3RxLmd6CiMgV2F0Y2ggdGhlIG91dHB1dCBvZiBGYXN0UUMKIyBWaWV3IHRoZSBvdXRwdXQgb2YgRmFzdFFDICh0aGUgZmlsZW5hbWVzKQpgYGAKCjxicj4KPGJyPgoKLS0tCgpUaGVzZSBtYXRlcmlhbHMgaGF2ZSBiZWVuIGFkYXB0ZWQgYW5kIGV4dGVuZGVkIGZyb20gbWF0ZXJpYWxzIGNyZWF0ZWQgYnkgdGhlIFtIYXJ2YXJkIENoYW4gQmlvaW5mb3JtYXRpY3MgQ29yZSAoSEJDKV0oaHR0cDovL2Jpb2luZm9ybWF0aWNzLnNwaC5oYXJ2YXJkLmVkdS8pLiBUaGVzZSBhcmUgb3BlbiBhY2Nlc3MgbWF0ZXJpYWxzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgW0NyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gbGljZW5zZSAoQ0MgQlkgNC4wKV0oaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnkvNC4wLyksIHdoaWNoIHBlcm1pdHMgdW5yZXN0cmljdGVkIHVzZSwgZGlzdHJpYnV0aW9uLCBhbmQgcmVwcm9kdWN0aW9uIGluIGFueSBtZWRpdW0sIHByb3ZpZGVkIHRoZSBvcmlnaW5hbCBhdXRob3IgYW5kIHNvdXJjZSBhcmUgY3JlZGl0ZWQuCg==