Additional Information

For this workshop, we’ve provided a few things to ensure that our experience goes smoothly. In this module, we will discuss in more detail the things needed to perform an RNAseq analysis like this.

Building Blocks

The Compute Environment

Here we’re referring to all of the hardware, software, and configuration details of the system where we perform our analysis.

Hardware

  • CPU
  • Memory
  • Storage

CPU

CPU stands for Central Processing Unit. In shorthand, people often refer to “the processor”. This retrieves and executes instructions, and is one of the core components of a computing system.

Single vs Multi-Threaded

Many of the most heavily-used bioinformatics software can use multiple threads. This way they can do parallel processing, which can drastically cut down the time to receive results.

There are also plenty of single-threaded bioinformatics programs. Simple python scripts, niche tools, etc. will often not need parallel processing. In these cases, the cost/benefit tradeoff may be too great.

Multi-threaded programs we’ve used:

  • Cutadapt
  • STAR / RSEM

Single-threaded programs we’ve used:

  • FastQC
  • MultiQC
What about clock speed?

You may be familiar with clock speed of a processor from your experience while buying personal computers. You may’ve seen specs listed such as 3.3 GHz, which refers to the CPU’s clock speed.

Clock speeds on all modern processors are sufficient for basically all bioinformatics software. Clock speed is generally not a major consideration in choices today.



Memory

Here we’re referring to Random Access Memory, or RAM. RAM provides a limited amount of very fast storage that a process will use within a short time frame.

The memory requirements of various tools vary widely, and many bioinformatics programs require fairly high amounts. This is true for aligners. In the case of the STAR aligner, a very large data structure is loaded into RAM. This allows extremely fast and accurate alignments e.g. to a vertebrate genome, but requires very large amounts of RAM.

Cutadapt, fastQC, and multiQC have more modest memory requirements, so we won’t have to consider memory as much in those cases.

Storage

Here we’re referring to disk storage, or persistent storage. This stores large amounts of data for the long term - the information remains even when there is no power to the device. You may sometimes use the phrase “save [the file] to your hard drive”, which is referring to persistent storage.

Consider:

  • Storage for input files, output files
  • Storage during processing

Some input and output files can be quite large. Additionally, several large intermediates are produced during processing, requiring (sometimes considerable) additional storage.

Software

The software we’ve been using is free, open-source, and openly licensed. We can inspect the source code, use the program as we wish, modify it, contribute to it, etc. This is the case for many bioinformatics tools. We can appreciate the benefits of community-driven software.

There are tools available for various kinds of bioinformatics tasks. Today we’ve focused on a few important tasks for RNA sequencing, and used a subset of quality tools for this purpose. Here is a summary of the tasks we’ve performed and the tools we’ve used today.

Task Tool
Quality Control FastQC
Quality Control MultiQC
Read Trimming Cutadapt
Alignment STAR
Gene Quantification RSEM

System Configuration

Operating System

The Operating System (OS) is a software layer that handles communication between the hardware devices and with the end user.

In this workshop we’ve used a Linux operating system. Linux is free and open source. It’s widely used in bioinformatics; as you’ve learned, it can be very powerful.

Examples of Operating Systems?

Examples:

Some software is specific to an operating system - developers may focus their time and attention on developing for certain configurations over others, depending on the niche or goal. Often, releases may be limited to certain OS / hardware configurations.



Local vs Remote

In this workshop, we’ve used remote computing systems for our analysis. We’ve seen how we can connect to a remote computer and use it for our purposes. You’re likely most familiar with local computing, using a machine that is physically in the same room as you. However, now we can recognize some benefits of remote computing.

Why Use Remote Computing?

Remote computing is sensible in many situations - for economies of scale it’s best to have many machines in physical locations that are built and designed for that purpose. This is what it means if you’ve heard of cloud computing - a type of remote computing, often with convenience services or products built on top of the remote machines. By using remote computing, we can rent powerful hardware that would not be practical for us to buy. We can also scale this up or down to our exact needs, providing great flexibility.

How to Efficiently Manage Remote Computing Resources

This is a broad topic - job scheduling is a common method for allocating shared compute resources. Consider a job as an individual call to a piece of software. There are many ways to manage resources at the job level.

Resource management and job scheduling at the UMich HPC is handled by SLURM. Quite a large topic of its own, you can read more about these resources here.

Another large topic which we won’t dive into, are workflow managers. These allow similar job management capabilities, but are more flexible since they are not tied to a specific type of system. Snakemake is an example of this.

Today we’ve been aiming for simplicity and transparency, so managed our jobs manually and sequentially. In other words, we wrote and submitted the commands by hand, in order, for illustrative purposes. You can imagine that for large-scale processing, it is incredibly useful to allow software to automate some of these processes for us.



Software Management

There are many methods for managing software. As a system accumulates changes over time, and as the resulting software installations become more complex (esp. across multi-user systems), the need for software management systems becomes more apparent.

Today we’ve been using miniconda. This provides a good balance of simplicity, flexibility, and utility for software management.

Conda is an open-source, cross-platform, package management and environment management software. It’s widely used for packaging and distributing software, particularly in the python community. Note: it is also used for software of many different software languages; it is language-agnostic.

Miniconda is a minimal installation of conda, that provides a lightweight option to get started with.



Summary

Things that we have learned:

  • Important aspects of hardware, software, and compute environments to consider
  • Important file formats and their contents
  • Reference files necessary / where to find
  • How to use FastQC, assess quality of reads
  • How to transfer files from remote to local computer
  • How to prepare a reference for alignment and quantification with RSEM + STAR
  • How to combine expression results across samples into a count matrix
  • How to use MultiQC to summarize large volumes of QC data.



Results Summary



Conda Exercises

Environment recap:

By default you will usually have a single compute environment - one set up specifically for your user. You’ll have a set of programs, some configuration details, etc. that are set up according to your preferences.

As mentioned above, when doing data analysis tasks, it can become onerous to create and maintain one environment that satisfies all of your needs. It is good practice to create separate environments according to the specific needs of a project. A metaphor would be putting on different outfits for different occasions or tasks in your life.

Conda is a tool that we’ve used for managing our software environment for this workshop. We’re all currently using the same conda environment that we (the instructors) built ahead of time.

Conda must-know:

  • A tool for managing software environments
  • Create an environment
  • Activate and deactivate an environment

Conda Activate / Deactivate Exercise

  1. Learn about the which command - use to reveal the path to a specific software
  2. Try which python
  3. Deactivate our current shared environment with conda deactivate
  4. Try which python again - Is it different now?
  5. Activate the environment again with conda activate /workshop/conda/rsd

Conda Create Simple Exercise

  1. Check which python version we have in our current environment
  2. Create a simple conda environment named py36 that contains python 3.6 - use the bioconda channel
  3. Activate the new py36 environment and verify that you now have python 3.6
  4. Deactivate our py36 environment
# Check which python version we're using in our current environment
python --version
# Create a conda environment with python version 3.6, using the bioconda channel
conda create -n py36 -c bioconda python=3.6
# Activate our new conda environment
conda activate py36
# Check our python version now (it should be 3.6)
python --version
# Deactivate our environment
conda deactivate


Conda Create Exercise

Before starting our conda exercise, we should make sure that we are on the same page. Follow the link below:

Conda create exercise




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.

LS0tCnRpdGxlOiAiTW9kdWxlIDA1OiBBZGRpdGlvbmFsIERldGFpbHMiCmF1dGhvcjogIlVNIEJpb2luZm9ybWF0aWNzIENvcmUiCm91dHB1dDoKICAgICAgICBodG1sX2RvY3VtZW50OgogICAgICAgICAgICBpbmNsdWRlczoKICAgICAgICAgICAgICAgIGluX2hlYWRlcjogaGVhZGVyLmh0bWwKICAgICAgICAgICAgdGhlbWU6IHBhcGVyCiAgICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgICB0b2NfZGVwdGg6IDQKICAgICAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgICAgICAgICAgZmlnX2NhcHRpb246IHRydWUKICAgICAgICAgICAgbWFya2Rvd246IEdGTQogICAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5eyAvKiBOb3JtYWwgICovCiAgICAgIGZvbnQtc2l6ZTogMTRwdDsKICB9CnByZSB7CiAgZm9udC1zaXplOiAxMnB0Cn0KPC9zdHlsZT4KCiMgQWRkaXRpb25hbCBJbmZvcm1hdGlvbgoKRm9yIHRoaXMgd29ya3Nob3AsIHdlJ3ZlIHByb3ZpZGVkIGEgZmV3IHRoaW5ncyB0byBlbnN1cmUgdGhhdCBvdXIgZXhwZXJpZW5jZSBnb2VzIHNtb290aGx5LiBJbiB0aGlzIG1vZHVsZSwgd2Ugd2lsbCBkaXNjdXNzIGluIG1vcmUgZGV0YWlsIHRoZSB0aGluZ3MgbmVlZGVkIHRvIHBlcmZvcm0gYW4gUk5Bc2VxIGFuYWx5c2lzIGxpa2UgdGhpcy4KCiFbQnVpbGRpbmcgQmxvY2tzXShpbWFnZXMvYnVpbGRpbmctYmxvY2tzLnBuZykKCgojIFRoZSBDb21wdXRlIEVudmlyb25tZW50CgpIZXJlIHdlJ3JlIHJlZmVycmluZyB0byBhbGwgb2YgdGhlIGhhcmR3YXJlLCBzb2Z0d2FyZSwgYW5kIGNvbmZpZ3VyYXRpb24gZGV0YWlscyBvZiB0aGUgc3lzdGVtIHdoZXJlIHdlIHBlcmZvcm0gb3VyIGFuYWx5c2lzLgoKIyMgSGFyZHdhcmUKCi0gQ1BVCi0gTWVtb3J5Ci0gU3RvcmFnZQoKIyMjIENQVQoKQ1BVIHN0YW5kcyBmb3IgQ2VudHJhbCBQcm9jZXNzaW5nIFVuaXQuIEluIHNob3J0aGFuZCwgcGVvcGxlIG9mdGVuIHJlZmVyIHRvICJ0aGUgcHJvY2Vzc29yIi4gVGhpcyAgcmV0cmlldmVzIGFuZCBleGVjdXRlcyBpbnN0cnVjdGlvbnMsIGFuZCBpcyBvbmUgb2YgdGhlIGNvcmUgY29tcG9uZW50cyBvZiBhIGNvbXB1dGluZyBzeXN0ZW0uCgpTaW5nbGUgdnMgTXVsdGktVGhyZWFkZWQKCk1hbnkgb2YgdGhlIG1vc3QgaGVhdmlseS11c2VkIGJpb2luZm9ybWF0aWNzIHNvZnR3YXJlIGNhbiB1c2UgbXVsdGlwbGUgdGhyZWFkcy4gVGhpcyB3YXkgdGhleSBjYW4gZG8gcGFyYWxsZWwgcHJvY2Vzc2luZywgd2hpY2ggY2FuIGRyYXN0aWNhbGx5IGN1dCBkb3duIHRoZSB0aW1lIHRvIHJlY2VpdmUgcmVzdWx0cy4KClRoZXJlIGFyZSBhbHNvIHBsZW50eSBvZiBzaW5nbGUtdGhyZWFkZWQgYmlvaW5mb3JtYXRpY3MgcHJvZ3JhbXMuIFNpbXBsZSBweXRob24gc2NyaXB0cywgbmljaGUgdG9vbHMsIGV0Yy4gd2lsbCBvZnRlbiBub3QgbmVlZCBwYXJhbGxlbCBwcm9jZXNzaW5nLiBJbiB0aGVzZSBjYXNlcywgdGhlIGNvc3QvYmVuZWZpdCB0cmFkZW9mZiBtYXkgYmUgdG9vIGdyZWF0LgoKTXVsdGktdGhyZWFkZWQgcHJvZ3JhbXMgd2UndmUgdXNlZDoKCi0gQ3V0YWRhcHQKLSBTVEFSIC8gUlNFTQoKU2luZ2xlLXRocmVhZGVkIHByb2dyYW1zIHdlJ3ZlIHVzZWQ6CgotIEZhc3RRQwotIE11bHRpUUMKCjxkZXRhaWxzPgo8c3VtbWFyeT5XaGF0IGFib3V0IGNsb2NrIHNwZWVkPzwvc3VtbWFyeT4KCllvdSBtYXkgYmUgZmFtaWxpYXIgd2l0aCBjbG9jayBzcGVlZCBvZiBhIHByb2Nlc3NvciBmcm9tIHlvdXIgZXhwZXJpZW5jZSB3aGlsZSBidXlpbmcgcGVyc29uYWwgY29tcHV0ZXJzLiBZb3UgbWF5J3ZlIHNlZW4gc3BlY3MgbGlzdGVkIHN1Y2ggYXMgYDMuMyBHSHpgLCB3aGljaCByZWZlcnMgdG8gdGhlIENQVSdzIGNsb2NrIHNwZWVkLgoKQ2xvY2sgc3BlZWRzIG9uIGFsbCBtb2Rlcm4gcHJvY2Vzc29ycyBhcmUgc3VmZmljaWVudCBmb3IgYmFzaWNhbGx5IGFsbCBiaW9pbmZvcm1hdGljcyBzb2Z0d2FyZS4gQ2xvY2sgc3BlZWQgaXMgZ2VuZXJhbGx5IG5vdCBhIG1ham9yIGNvbnNpZGVyYXRpb24gaW4gY2hvaWNlcyB0b2RheS4KPC9kZXRhaWxzPgoKPGJyPgo8YnI+CgojIyMgTWVtb3J5CgpIZXJlIHdlJ3JlIHJlZmVycmluZyB0byBSYW5kb20gQWNjZXNzIE1lbW9yeSwgb3IgUkFNLiBSQU0gcHJvdmlkZXMgYSBsaW1pdGVkIGFtb3VudCBvZiB2ZXJ5IGZhc3Qgc3RvcmFnZSB0aGF0IGEgcHJvY2VzcyB3aWxsIHVzZSB3aXRoaW4gYSBzaG9ydCB0aW1lIGZyYW1lLgoKVGhlIG1lbW9yeSByZXF1aXJlbWVudHMgb2YgdmFyaW91cyB0b29scyB2YXJ5IHdpZGVseSwgYW5kIG1hbnkgYmlvaW5mb3JtYXRpY3MgcHJvZ3JhbXMgcmVxdWlyZSBmYWlybHkgaGlnaCBhbW91bnRzLiBUaGlzIGlzIHRydWUgZm9yIGFsaWduZXJzLiBJbiB0aGUgY2FzZSBvZiB0aGUgU1RBUiBhbGlnbmVyLCBhIHZlcnkgbGFyZ2UgZGF0YSBzdHJ1Y3R1cmUgaXMgbG9hZGVkIGludG8gUkFNLiBUaGlzIGFsbG93cyBleHRyZW1lbHkgZmFzdCBhbmQgYWNjdXJhdGUgYWxpZ25tZW50cyBlLmcuIHRvIGEgdmVydGVicmF0ZSBnZW5vbWUsIGJ1dCByZXF1aXJlcyB2ZXJ5IGxhcmdlIGFtb3VudHMgb2YgUkFNLgoKQ3V0YWRhcHQsIGZhc3RRQywgYW5kIG11bHRpUUMgaGF2ZSBtb3JlIG1vZGVzdCBtZW1vcnkgcmVxdWlyZW1lbnRzLCBzbyB3ZSB3b24ndCBoYXZlIHRvIGNvbnNpZGVyIG1lbW9yeSBhcyBtdWNoIGluIHRob3NlIGNhc2VzLgoKIyMjIFN0b3JhZ2UKCkhlcmUgd2UncmUgcmVmZXJyaW5nIHRvIGRpc2sgc3RvcmFnZSwgb3IgcGVyc2lzdGVudCBzdG9yYWdlLiBUaGlzIHN0b3JlcyBsYXJnZSBhbW91bnRzIG9mIGRhdGEgZm9yIHRoZSBsb25nIHRlcm0gLSB0aGUgaW5mb3JtYXRpb24gcmVtYWlucyBldmVuIHdoZW4gdGhlcmUgaXMgbm8gcG93ZXIgdG8gdGhlIGRldmljZS4gWW91IG1heSBzb21ldGltZXMgdXNlIHRoZSBwaHJhc2UgInNhdmUgW3RoZSBmaWxlXSB0byB5b3VyIGhhcmQgZHJpdmUiLCB3aGljaCBpcyByZWZlcnJpbmcgdG8gcGVyc2lzdGVudCBzdG9yYWdlLgoKQ29uc2lkZXI6CgotIFN0b3JhZ2UgZm9yIGlucHV0IGZpbGVzLCBvdXRwdXQgZmlsZXMKLSBTdG9yYWdlIGR1cmluZyBwcm9jZXNzaW5nCgpTb21lIGlucHV0IGFuZCBvdXRwdXQgZmlsZXMgY2FuIGJlIHF1aXRlIGxhcmdlLiBBZGRpdGlvbmFsbHksIHNldmVyYWwgbGFyZ2UgaW50ZXJtZWRpYXRlcyBhcmUgcHJvZHVjZWQgZHVyaW5nIHByb2Nlc3NpbmcsIHJlcXVpcmluZyAoc29tZXRpbWVzIGNvbnNpZGVyYWJsZSkgYWRkaXRpb25hbCBzdG9yYWdlLgoKIyMgU29mdHdhcmUKClRoZSBzb2Z0d2FyZSB3ZSd2ZSBiZWVuIHVzaW5nIGlzIGZyZWUsIG9wZW4tc291cmNlLCBhbmQgb3Blbmx5IGxpY2Vuc2VkLiBXZSBjYW4gaW5zcGVjdCB0aGUgc291cmNlIGNvZGUsIHVzZSB0aGUgcHJvZ3JhbSBhcyB3ZSB3aXNoLCBtb2RpZnkgaXQsIGNvbnRyaWJ1dGUgdG8gaXQsIGV0Yy4gVGhpcyBpcyB0aGUgY2FzZSBmb3IgbWFueSBiaW9pbmZvcm1hdGljcyB0b29scy4gV2UgY2FuIGFwcHJlY2lhdGUgdGhlIGJlbmVmaXRzIG9mIGNvbW11bml0eS1kcml2ZW4gc29mdHdhcmUuCgpUaGVyZSBhcmUgdG9vbHMgYXZhaWxhYmxlIGZvciB2YXJpb3VzIGtpbmRzIG9mIGJpb2luZm9ybWF0aWNzIHRhc2tzLiBUb2RheSB3ZSd2ZSBmb2N1c2VkIG9uIGEgZmV3IGltcG9ydGFudCB0YXNrcyBmb3IgUk5BIHNlcXVlbmNpbmcsIGFuZCB1c2VkIGEgc3Vic2V0IG9mIHF1YWxpdHkgdG9vbHMgZm9yIHRoaXMgcHVycG9zZS4gSGVyZSBpcyBhIHN1bW1hcnkgb2YgdGhlIHRhc2tzIHdlJ3ZlIHBlcmZvcm1lZCBhbmQgdGhlIHRvb2xzIHdlJ3ZlIHVzZWQgdG9kYXkuCgp8IFRhc2sgfCBUb29sIHwKfCA6LS06IHwgLS0tLSB8CnwgUXVhbGl0eSBDb250cm9sIHwgW0Zhc3RRQ10oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjL0hlbHAvKSB8CnwgUXVhbGl0eSBDb250cm9sIHwgW011bHRpUUNdKGh0dHBzOi8vbXVsdGlxYy5pbmZvL2RvY3MvKSB8CnwgUmVhZCBUcmltbWluZyB8IFtDdXRhZGFwdF0oaHR0cHM6Ly9jdXRhZGFwdC5yZWFkdGhlZG9jcy5pby9lbi9zdGFibGUvKSB8CnwgQWxpZ25tZW50IHwgW1NUQVJdKGh0dHBzOi8vZ2l0aHViLmNvbS9hbGV4ZG9iaW4vU1RBUi9ibG9iL21hc3Rlci9kb2MvU1RBUm1hbnVhbC5wZGYpIHwKfCBHZW5lIFF1YW50aWZpY2F0aW9uIHwgW1JTRU1dKGh0dHA6Ly9kZXdleWxhYi5naXRodWIuaW8vUlNFTS8pIHwKCiMjIFN5c3RlbSBDb25maWd1cmF0aW9uCgojIyMgT3BlcmF0aW5nIFN5c3RlbQoKVGhlIE9wZXJhdGluZyBTeXN0ZW0gKE9TKSBpcyBhIHNvZnR3YXJlIGxheWVyIHRoYXQgaGFuZGxlcyBjb21tdW5pY2F0aW9uIGJldHdlZW4gdGhlIGhhcmR3YXJlIGRldmljZXMgYW5kIHdpdGggdGhlIGVuZCB1c2VyLgoKSW4gdGhpcyB3b3Jrc2hvcCB3ZSd2ZSB1c2VkIGEgTGludXggb3BlcmF0aW5nIHN5c3RlbS4gTGludXggaXMgZnJlZSBhbmQgb3BlbiBzb3VyY2UuIEl0J3Mgd2lkZWx5IHVzZWQgaW4gYmlvaW5mb3JtYXRpY3M7IGFzIHlvdSd2ZSBsZWFybmVkLCBpdCBjYW4gYmUgdmVyeSBwb3dlcmZ1bC4KCjxkZXRhaWxzPgo8c3VtbWFyeT5FeGFtcGxlcyBvZiBPcGVyYXRpbmcgU3lzdGVtcz88L3N1bW1hcnk+CgpFeGFtcGxlczoKCi0gTWljcm9zb2Z0IC0gW1dpbmRvd3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01pY3Jvc29mdF9XaW5kb3dzKQotIEFwcGxlIC0gW01hY09TXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NYWNPUykKLSBbRk9TU10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRnJlZV9hbmRfb3Blbi1zb3VyY2Vfc29mdHdhcmUpIC0gW0dOVV0oaHR0cDovL3d3dy5nbnUub3JnKSAvIFtMSU5VWF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGludXgpCi0gR29vZ2xlIC0gW0FuZHJvaWRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FuZHJvaWRfKG9wZXJhdGluZ19zeXN0ZW0pKQotIEFwcGxlIC0gW2lPU10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSU9TKQoKU29tZSBzb2Z0d2FyZSBpcyBzcGVjaWZpYyB0byBhbiBvcGVyYXRpbmcgc3lzdGVtIC0gZGV2ZWxvcGVycyBtYXkgZm9jdXMgdGhlaXIgdGltZSBhbmQgYXR0ZW50aW9uIG9uIGRldmVsb3BpbmcgZm9yIGNlcnRhaW4gY29uZmlndXJhdGlvbnMgb3ZlciBvdGhlcnMsIGRlcGVuZGluZyBvbiB0aGUgbmljaGUgb3IgZ29hbC4gT2Z0ZW4sIHJlbGVhc2VzIG1heSBiZSBsaW1pdGVkIHRvIGNlcnRhaW4gT1MgLyBoYXJkd2FyZSBjb25maWd1cmF0aW9ucy4KCjwvZGV0YWlscz4KCjxicj4KPGJyPgoKIyMjIExvY2FsIHZzIFJlbW90ZQoKSW4gdGhpcyB3b3Jrc2hvcCwgd2UndmUgdXNlZCByZW1vdGUgY29tcHV0aW5nIHN5c3RlbXMgZm9yIG91ciBhbmFseXNpcy4gV2UndmUgc2VlbiBob3cgd2UgY2FuIGNvbm5lY3QgdG8gYSByZW1vdGUgY29tcHV0ZXIgYW5kIHVzZSBpdCBmb3Igb3VyIHB1cnBvc2VzLiBZb3UncmUgbGlrZWx5IG1vc3QgZmFtaWxpYXIgd2l0aCBsb2NhbCBjb21wdXRpbmcsIHVzaW5nIGEgbWFjaGluZSB0aGF0IGlzIHBoeXNpY2FsbHkgaW4gdGhlIHNhbWUgcm9vbSBhcyB5b3UuIEhvd2V2ZXIsIG5vdyB3ZSBjYW4gcmVjb2duaXplIHNvbWUgYmVuZWZpdHMgb2YgcmVtb3RlIGNvbXB1dGluZy4KCjxkZXRhaWxzPgo8c3VtbWFyeT5XaHkgVXNlIFJlbW90ZSBDb21wdXRpbmc/PC9zdW1tYXJ5PgoKUmVtb3RlIGNvbXB1dGluZyBpcyBzZW5zaWJsZSBpbiBtYW55IHNpdHVhdGlvbnMgLSBmb3IgZWNvbm9taWVzIG9mIHNjYWxlIGl0J3MgYmVzdCB0byBoYXZlIG1hbnkgbWFjaGluZXMgaW4gcGh5c2ljYWwgbG9jYXRpb25zIHRoYXQgYXJlIGJ1aWx0IGFuZCBkZXNpZ25lZCBmb3IgdGhhdCBwdXJwb3NlLiBUaGlzIGlzIHdoYXQgaXQgbWVhbnMgaWYgeW91J3ZlIGhlYXJkIG9mIGNsb3VkIGNvbXB1dGluZyAtIGEgdHlwZSBvZiByZW1vdGUgY29tcHV0aW5nLCBvZnRlbiB3aXRoIGNvbnZlbmllbmNlIHNlcnZpY2VzIG9yIHByb2R1Y3RzIGJ1aWx0IG9uIHRvcCBvZiB0aGUgcmVtb3RlIG1hY2hpbmVzLiBCeSB1c2luZyByZW1vdGUgY29tcHV0aW5nLCB3ZSBjYW4gcmVudCBwb3dlcmZ1bCBoYXJkd2FyZSB0aGF0IHdvdWxkIG5vdCBiZSBwcmFjdGljYWwgZm9yIHVzIHRvIGJ1eS4gV2UgY2FuIGFsc28gc2NhbGUgdGhpcyB1cCBvciBkb3duIHRvIG91ciBleGFjdCBuZWVkcywgcHJvdmlkaW5nIGdyZWF0IGZsZXhpYmlsaXR5LgoKPC9kZXRhaWxzPgoKPGRldGFpbHM+CjxzdW1tYXJ5PkhvdyB0byBFZmZpY2llbnRseSBNYW5hZ2UgUmVtb3RlIENvbXB1dGluZyBSZXNvdXJjZXM8L3N1bW1hcnk+CgpUaGlzIGlzIGEgYnJvYWQgdG9waWMgLSBqb2Igc2NoZWR1bGluZyBpcyBhIGNvbW1vbiBtZXRob2QgZm9yIGFsbG9jYXRpbmcgc2hhcmVkIGNvbXB1dGUgcmVzb3VyY2VzLiBDb25zaWRlciBhIGpvYiBhcyBhbiBpbmRpdmlkdWFsIGNhbGwgdG8gYSBwaWVjZSBvZiBzb2Z0d2FyZS4gVGhlcmUgYXJlIG1hbnkgd2F5cyB0byBtYW5hZ2UgcmVzb3VyY2VzIGF0IHRoZSBqb2IgbGV2ZWwuCgpSZXNvdXJjZSBtYW5hZ2VtZW50IGFuZCBqb2Igc2NoZWR1bGluZyBhdCB0aGUgVU1pY2ggSFBDIGlzIGhhbmRsZWQgYnkgU0xVUk0uIFF1aXRlIGEgbGFyZ2UgdG9waWMgb2YgaXRzIG93biwgeW91IGNhbiByZWFkIG1vcmUgYWJvdXQgdGhlc2UgcmVzb3VyY2VzIFtoZXJlXShodHRwczovL2FyYy51bWljaC5lZHUvZ3JlYXRsYWtlcy9zbHVybS11c2VyLWd1aWRlLykuCgpBbm90aGVyIGxhcmdlIHRvcGljIHdoaWNoIHdlIHdvbid0IGRpdmUgaW50bywgYXJlIHdvcmtmbG93IG1hbmFnZXJzLiBUaGVzZSBhbGxvdyBzaW1pbGFyIGpvYiBtYW5hZ2VtZW50IGNhcGFiaWxpdGllcywgYnV0IGFyZSBtb3JlIGZsZXhpYmxlIHNpbmNlIHRoZXkgYXJlIG5vdCB0aWVkIHRvIGEgc3BlY2lmaWMgdHlwZSBvZiBzeXN0ZW0uIFtTbmFrZW1ha2VdKGh0dHBzOi8vc25ha2VtYWtlLnJlYWR0aGVkb2NzLmlvL2VuL3N0YWJsZS8pIGlzIGFuIGV4YW1wbGUgb2YgdGhpcy4KClRvZGF5IHdlJ3ZlIGJlZW4gYWltaW5nIGZvciBzaW1wbGljaXR5IGFuZCB0cmFuc3BhcmVuY3ksIHNvIG1hbmFnZWQgb3VyIGpvYnMgbWFudWFsbHkgYW5kIHNlcXVlbnRpYWxseS4gSW4gb3RoZXIgd29yZHMsIHdlIHdyb3RlIGFuZCBzdWJtaXR0ZWQgdGhlIGNvbW1hbmRzIGJ5IGhhbmQsIGluIG9yZGVyLCBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzLiBZb3UgY2FuIGltYWdpbmUgdGhhdCBmb3IgbGFyZ2Utc2NhbGUgcHJvY2Vzc2luZywgaXQgaXMgaW5jcmVkaWJseSB1c2VmdWwgdG8gYWxsb3cgc29mdHdhcmUgdG8gYXV0b21hdGUgc29tZSBvZiB0aGVzZSBwcm9jZXNzZXMgZm9yIHVzLgoKPC9kZXRhaWxzPgoKPGJyPgo8YnI+CgojIyMgU29mdHdhcmUgTWFuYWdlbWVudAoKVGhlcmUgYXJlIG1hbnkgbWV0aG9kcyBmb3IgbWFuYWdpbmcgc29mdHdhcmUuIEFzIGEgc3lzdGVtIGFjY3VtdWxhdGVzIGNoYW5nZXMgb3ZlciB0aW1lLCBhbmQgYXMgdGhlIHJlc3VsdGluZyBzb2Z0d2FyZSBpbnN0YWxsYXRpb25zIGJlY29tZSBtb3JlIGNvbXBsZXggKGVzcC4gYWNyb3NzIG11bHRpLXVzZXIgc3lzdGVtcyksIHRoZSBuZWVkIGZvciBzb2Z0d2FyZSBtYW5hZ2VtZW50IHN5c3RlbXMgYmVjb21lcyBtb3JlIGFwcGFyZW50LgoKVG9kYXkgd2UndmUgYmVlbiB1c2luZyBbbWluaWNvbmRhXShodHRwczovL2RvY3MuY29uZGEuaW8vZW4vbGF0ZXN0L21pbmljb25kYS5odG1sKS4gVGhpcyBwcm92aWRlcyBhIGdvb2QgYmFsYW5jZSBvZiBzaW1wbGljaXR5LCBmbGV4aWJpbGl0eSwgYW5kIHV0aWxpdHkgZm9yIHNvZnR3YXJlIG1hbmFnZW1lbnQuCgpDb25kYSBpcyBhbiBvcGVuLXNvdXJjZSwgY3Jvc3MtcGxhdGZvcm0sIHBhY2thZ2UgbWFuYWdlbWVudCBhbmQgZW52aXJvbm1lbnQgbWFuYWdlbWVudCBzb2Z0d2FyZS4gSXQncyB3aWRlbHkgdXNlZCBmb3IgcGFja2FnaW5nIGFuZCBkaXN0cmlidXRpbmcgc29mdHdhcmUsIHBhcnRpY3VsYXJseSBpbiB0aGUgcHl0aG9uIGNvbW11bml0eS4gTm90ZTogaXQgaXMgYWxzbyB1c2VkIGZvciBzb2Z0d2FyZSBvZiBtYW55IGRpZmZlcmVudCBzb2Z0d2FyZSBsYW5ndWFnZXM7IGl0IGlzIGxhbmd1YWdlLWFnbm9zdGljLgoKTWluaWNvbmRhIGlzIGEgbWluaW1hbCBpbnN0YWxsYXRpb24gb2YgY29uZGEsIHRoYXQgcHJvdmlkZXMgYSBsaWdodHdlaWdodCBvcHRpb24gdG8gZ2V0IHN0YXJ0ZWQgd2l0aC4KCgo8YnI+Cjxicj4KCgojIFN1bW1hcnkKClRoaW5ncyB0aGF0IHdlIGhhdmUgbGVhcm5lZDoKCi0gSW1wb3J0YW50IGFzcGVjdHMgb2YgaGFyZHdhcmUsIHNvZnR3YXJlLCBhbmQgY29tcHV0ZSBlbnZpcm9ubWVudHMgdG8gY29uc2lkZXIKLSBJbXBvcnRhbnQgZmlsZSBmb3JtYXRzIGFuZCB0aGVpciBjb250ZW50cwotIFJlZmVyZW5jZSBmaWxlcyBuZWNlc3NhcnkgLyB3aGVyZSB0byBmaW5kCi0gSG93IHRvIHVzZSBGYXN0UUMsIGFzc2VzcyBxdWFsaXR5IG9mIHJlYWRzCi0gSG93IHRvIHRyYW5zZmVyIGZpbGVzIGZyb20gcmVtb3RlIHRvIGxvY2FsIGNvbXB1dGVyCi0gSG93IHRvIHByZXBhcmUgYSByZWZlcmVuY2UgZm9yIGFsaWdubWVudCBhbmQgcXVhbnRpZmljYXRpb24gd2l0aCBSU0VNICsgU1RBUgotIEhvdyB0byBjb21iaW5lIGV4cHJlc3Npb24gcmVzdWx0cyBhY3Jvc3Mgc2FtcGxlcyBpbnRvIGEgY291bnQgbWF0cml4Ci0gSG93IHRvIHVzZSBNdWx0aVFDIHRvIHN1bW1hcml6ZSBsYXJnZSB2b2x1bWVzIG9mIFFDIGRhdGEuCgo8YnI+Cjxicj4KCiFbUmVzdWx0cyBTdW1tYXJ5XShpbWFnZXMvcmVzdWx0cy1zdW1tYXJ5LnBuZykKCjxicj4KPGJyPgoKCiMgQ29uZGEgRXhlcmNpc2VzCgpFbnZpcm9ubWVudCByZWNhcDoKCkJ5IGRlZmF1bHQgeW91IHdpbGwgdXN1YWxseSBoYXZlIGEgc2luZ2xlIGNvbXB1dGUgZW52aXJvbm1lbnQgLSBvbmUgc2V0IHVwIHNwZWNpZmljYWxseSBmb3IgeW91ciB1c2VyLiBZb3UnbGwgaGF2ZSBhIHNldCBvZiBwcm9ncmFtcywgc29tZSBjb25maWd1cmF0aW9uIGRldGFpbHMsIGV0Yy4gdGhhdCBhcmUgc2V0IHVwIGFjY29yZGluZyB0byB5b3VyIHByZWZlcmVuY2VzLgoKQXMgbWVudGlvbmVkIGFib3ZlLCB3aGVuIGRvaW5nIGRhdGEgYW5hbHlzaXMgdGFza3MsIGl0IGNhbiBiZWNvbWUgb25lcm91cyB0byBjcmVhdGUgYW5kIG1haW50YWluIG9uZSBlbnZpcm9ubWVudCB0aGF0IHNhdGlzZmllcyBhbGwgb2YgeW91ciBuZWVkcy4gSXQgaXMgZ29vZCBwcmFjdGljZSB0byBjcmVhdGUgc2VwYXJhdGUgZW52aXJvbm1lbnRzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWMgbmVlZHMgb2YgYSBwcm9qZWN0LiBBIG1ldGFwaG9yIHdvdWxkIGJlIHB1dHRpbmcgb24gZGlmZmVyZW50IG91dGZpdHMgZm9yIGRpZmZlcmVudCBvY2Nhc2lvbnMgb3IgdGFza3MgaW4geW91ciBsaWZlLgoKQ29uZGEgaXMgYSB0b29sIHRoYXQgd2UndmUgdXNlZCBmb3IgbWFuYWdpbmcgb3VyIHNvZnR3YXJlIGVudmlyb25tZW50IGZvciB0aGlzIHdvcmtzaG9wLiBXZSdyZSBhbGwgY3VycmVudGx5IHVzaW5nIHRoZSBzYW1lIGNvbmRhIGVudmlyb25tZW50IHRoYXQgd2UgKHRoZSBpbnN0cnVjdG9ycykgYnVpbHQgYWhlYWQgb2YgdGltZS4KCkNvbmRhIG11c3Qta25vdzoKCi0gQSB0b29sIGZvciBtYW5hZ2luZyBzb2Z0d2FyZSBlbnZpcm9ubWVudHMKLSBDcmVhdGUgYW4gZW52aXJvbm1lbnQKLSBBY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZSBhbiBlbnZpcm9ubWVudAoKIyMgQ29uZGEgQWN0aXZhdGUgLyBEZWFjdGl2YXRlIEV4ZXJjaXNlCgoxLiBMZWFybiBhYm91dCB0aGUgYHdoaWNoYCBjb21tYW5kIC0gdXNlIHRvIHJldmVhbCB0aGUgcGF0aCB0byBhIHNwZWNpZmljIHNvZnR3YXJlCjIuIFRyeSBgd2hpY2ggcHl0aG9uYAozLiBEZWFjdGl2YXRlIG91ciBjdXJyZW50IHNoYXJlZCBlbnZpcm9ubWVudCB3aXRoIGBjb25kYSBkZWFjdGl2YXRlYAo0LiBUcnkgYHdoaWNoIHB5dGhvbmAgYWdhaW4gLSBJcyBpdCBkaWZmZXJlbnQgbm93Pwo1LiBBY3RpdmF0ZSB0aGUgZW52aXJvbm1lbnQgYWdhaW4gd2l0aCBgY29uZGEgYWN0aXZhdGUgL3dvcmtzaG9wL2NvbmRhL3JzZGAKCgojIyBDb25kYSBDcmVhdGUgU2ltcGxlIEV4ZXJjaXNlCgoxLiBDaGVjayB3aGljaCBweXRob24gdmVyc2lvbiB3ZSBoYXZlIGluIG91ciBjdXJyZW50IGVudmlyb25tZW50CjIuIENyZWF0ZSBhIHNpbXBsZSBjb25kYSBlbnZpcm9ubWVudCBuYW1lZCBgcHkzNmAgdGhhdCBjb250YWlucyBweXRob24gMy42IC0gdXNlIHRoZSBgYmlvY29uZGFgIGNoYW5uZWwKMy4gQWN0aXZhdGUgdGhlIG5ldyBgcHkzNmAgZW52aXJvbm1lbnQgYW5kIHZlcmlmeSB0aGF0IHlvdSBub3cgaGF2ZSBweXRob24gMy42CjQuIERlYWN0aXZhdGUgb3VyIGBweTM2YCBlbnZpcm9ubWVudAoKYGBgCiMgQ2hlY2sgd2hpY2ggcHl0aG9uIHZlcnNpb24gd2UncmUgdXNpbmcgaW4gb3VyIGN1cnJlbnQgZW52aXJvbm1lbnQKcHl0aG9uIC0tdmVyc2lvbgojIENyZWF0ZSBhIGNvbmRhIGVudmlyb25tZW50IHdpdGggcHl0aG9uIHZlcnNpb24gMy42LCB1c2luZyB0aGUgYmlvY29uZGEgY2hhbm5lbApjb25kYSBjcmVhdGUgLW4gcHkzNiAtYyBiaW9jb25kYSBweXRob249My42CiMgQWN0aXZhdGUgb3VyIG5ldyBjb25kYSBlbnZpcm9ubWVudApjb25kYSBhY3RpdmF0ZSBweTM2CiMgQ2hlY2sgb3VyIHB5dGhvbiB2ZXJzaW9uIG5vdyAoaXQgc2hvdWxkIGJlIDMuNikKcHl0aG9uIC0tdmVyc2lvbgojIERlYWN0aXZhdGUgb3VyIGVudmlyb25tZW50CmNvbmRhIGRlYWN0aXZhdGUKYGBgCgo8YnI+CgojIyBDb25kYSBDcmVhdGUgRXhlcmNpc2UKCkJlZm9yZSBzdGFydGluZyBvdXIgY29uZGEgZXhlcmNpc2UsIHdlIHNob3VsZCBtYWtlIHN1cmUgdGhhdCB3ZSBhcmUgb24gdGhlIHNhbWUgcGFnZS4gRm9sbG93IHRoZSBsaW5rIGJlbG93OgoKW0NvbmRhIGNyZWF0ZSBleGVyY2lzZV0oTW9kdWxlMDVfYnJlYWtvdXQwNF9zb2wuaHRtbCkKCjxicj4KPGJyPgoKLS0tCgpUaGVzZSBtYXRlcmlhbHMgaGF2ZSBiZWVuIGFkYXB0ZWQgYW5kIGV4dGVuZGVkIGZyb20gbWF0ZXJpYWxzIGNyZWF0ZWQgYnkgdGhlIFtIYXJ2YXJkIENoYW4gQmlvaW5mb3JtYXRpY3MgQ29yZSAoSEJDKV0oaHR0cDovL2Jpb2luZm9ybWF0aWNzLnNwaC5oYXJ2YXJkLmVkdS8pLiBUaGVzZSBhcmUgb3BlbiBhY2Nlc3MgbWF0ZXJpYWxzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgW0NyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gbGljZW5zZSAoQ0MgQlkgNC4wKV0oaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnkvNC4wLyksIHdoaWNoIHBlcm1pdHMgdW5yZXN0cmljdGVkIHVzZSwgZGlzdHJpYnV0aW9uLCBhbmQgcmVwcm9kdWN0aW9uIGluIGFueSBtZWRpdW0sIHByb3ZpZGVkIHRoZSBvcmlnaW5hbCBhdXRob3IgYW5kIHNvdXJjZSBhcmUgY3JlZGl0ZWQuCg==