Hands-on Somatic Variant Analysis in Galaxy and IGV
Tutorial Overview
This tutorial will cover the basics of Somatic analysis using Galaxy; a open-source web-based platform for the analysis of biological data. You should gain an appreciation of the tasks involved in a typical NGS analysis and be comfortable with the outputs generated by a sequencing service. You will also use the Integrative Genomics Viewer (IGV) to view the aligned reads in an interactive manner.
We will use training materials provided by the Galaxy Project and sign-post to relevant sections. If you want to find more detailed tutorials on IGV or Galaxy you can follow the links below:-
Background
Where do the data in this tutorial come from?
The data for this tutorial are from a cancer patient down-sampled to genes that are present in the COSMIC dataset. We will use these data throughout the course to call variants, filter and discuss the clinical impact of any mutations.
Preparation and Data Upload
If attending this workshop in-person you should have access to a private queue on the usegalaxy.eu server that will allow your jobs to run quicker.
Follow this link to register an account:-
https://usegalaxy.eu/join-training/sbc-somatic-2019-05-10
Otherwise, register as a new user on one of the public Galaxy servers
Make sure you check your email to activate your account
Import the data for the workshop.
We can going to import the fastq files for this experiment. This is a standard format for storing raw sequencing reads and their associated quality scores. However, as we will see, the representation of the quality scores has changed over time.
The fastq files for this workshop have been uploaded to google drive folder
Download all the files ending in fastq.gz
and fasta.gz
in this directory to your laptop
You can import the data by:
- In the tool panel located on the left, select Get Data > Upload File.
- Choose local file and browse to the directory containing the files from the google drive and select all the file. Click Open to close the file browser. The names of the files should now appear in Galaxy.
Click Start to begin the upload
You should now have these 5 files in your history:
231335_cancer_genes_r1.fastq.gz
231335_cancer_genes_r2.fastq.gz
231336_cancer_genes_r1.fastq.gz
231336_cancer_genes_r2.fastq.gz
hg19.chr5_12_17.fasta.gz
where the first two files represent the forward and reverse reads sequence data from a patient’s normal tissue, and the next two represent the data of the same patient’s tumor tissue. The final file is a cut-down reference genome for chromosomes 5, 12 and 17 only.
Section 4: Alignment
The result of the previous practical will be a .bam
file that we will describe in the next section. This file is not human-readable, as it is compresed. But we can convert to a readable format for illustration purposes.
Viewing the alignments
Click on the eye of the resulting file to view the alignments.
A single standard file format has emerged for aligned reads. Moreoever, this file format is consistent regardless of whether you have DNA-seq, RNA-seq, ChIP-seq… data.
The bam
file is a compressed, binary, version of a sam
file.
- Sequence Alignment/Map (sam)
- The output from an aligner such as
bwa
- Same format regardless of sequencing protocol (i.e. RNA-seq, ChIP-seq, DNA-seq etc)
- May contain un-mapped reads
- Potentially large size on disk; ~100s of Gb
- Can be manipulated with standard unix tools; e.g. cat, head, grep, more, less….
- Official specification can be obtained online: -
- We normally work on a compressed version called a
.bam
file. See later.
- Header lines starting with an
@
character, followed by tab-delimited lines
- Header gives information about the alignment and references sequences used
The first part of the header lists the names (SN
) of the sequences (chromosomes) used in alignment, their length (LN
) and somtimes a md5sum “digital fingerprint” of the .fasta
file used for alignment (M5
).
@HD VN:1.3 SO:coordinate
@SQ SN:chr5 LN:180915260
@SQ SN:chr12 LN:133851895
@SQ SN:chr17 LN:81195210
@RG ID:231335 SM:Normal PL:ILLUMINA
We also have a section where we can record the processing steps used to derive the file
@PG ID:bwa PN:bwa VN:0.7.17-r1188 CL:bwa mem -t 8 -v 1 -R @RG\tID:231335\tSM:Normal\tPL:ILLUMINA localref.fa /data/dnb02/galaxy_db/files/009/352/dataset_9352452.dat /data/dnb02/galaxy_db/files/009/352/dataset_9352453.dat
Next is a tab-delimited section that describes the alignment of each sequence in detail.
ST-K00265:137:HT33CBBXX:3:2106:5944:11759 99 chr5 218378 60 101M = 218465 188 GTATCCCCCCTCCCCCGCCAGCTCGACCCCGGTGTGGTGCGCAGGCGCAGTCTGCGCAGGGACTGGCGGGACTGCGCGGCGGCAACAGCAGACATGTCGGG AAFFFJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ NM:i:0 MD:Z:101 MC:Z:101M AS:i:101 XS:i:50 RG:Z:231335
1 |
QNAME |
Sequence ID |
2 |
FLAG |
Sequence quality expressed as a bitwise flag |
3 |
RNAME |
Chromosome |
4 |
POS |
Start Position |
5 |
MAPQ |
Mapping Quality |
6 |
CIGAR |
Describes positions of matches, insertions, deletions w.r.t reference |
7 |
RNEXT |
Ref. name of mate / next read |
8 |
PNEXT |
Postion of mate / next read |
9 |
TLEN |
Observed Template length |
10 |
SEQ |
Sequence |
11 |
QUAL |
Base Qualities |
There can also be all manner of optional tags as extra columns introduce by an aligner or downstream analysis tool. A common use is the RG
tag which refers back to the read groups in the header.
Sorting and indexing
You will notice from the 3rd column that the reads are ordered according to their start position; whereas the reads in the fastq
file were arranged in order that they were generated on the flow cell. By default, bwa-mem
produces a bam where the reads are in the same order as the fastq
. However, this is rather incovenient for analysis where we require reads from the same location to be next to each other in the file.
An additional couple of steps have been performed after bowtie2; sorting the file according to genome position and producing an index file. The index file does not provide any useful information for us and cannot be viewed in Galaxy. However, we will need it later on when viewing the data in IGV.
Dr Mark Dunning presents….Fun with flags!
The “flags” in the sam file can represent useful QC information
- Read is unmapped
- Read is paired / unpaired
- Read failed QC
- Read is a PCR duplicate (see later)
The combination of any of these properties is used to derive a numeric value
For instance, a particular read has a flag of 163
Derivation
There is a set of properties that a read can possess. If a particular property is observed, a corresponding power of 2 is added multiplied by 1. The final value is derived by summing all the powers of 2.
69 (= 1 + 4 + 64) |
The read is paired, is the first read in the pair, and is unmapped. |
77 (= 1 + 4 + 8 + 64) |
The read is paired, is the first read in the pair, both are unmapped. |
83 (= 1 + 2 + 16 + 64) |
The read is paired, mapped in a proper pair, is the first read in the pair, and it is mapped to the reverse strand. |
99 (= 1 + 2 + 32 + 64) |
The read is paired, mapped in a proper pair, is the first read in the pair, and its mate is mapped to the reverse strand. |
133 (= 1 + 4 + 128) |
The read is paired, is the second read in the pair, and it is unmapped. |
137 (= 1 + 8 + 128) |
The read is paired, is the second read in the pair, and it is mapped while its mate is not. |
141 (= 1 + 4 + 8 + 128) |
The read is paired, is the second read in the pair, but both are unmapped. |
147 (= 1 + 2 + 16 + 128) |
The read is paired, mapped in a proper pair, is the second read in the pair, and mapped to the reverse strand. |
163 (= 1 + 2 + 32 + 128) |
The read is paired, mapped in a proper pair, is the second read in the pair, and its mate is mapped to the reverse strand. |
See also
Have a CIGAR!
The CIGAR (Compact Idiosyncratic Gapped Alignment Report) string is a way of encoding the match between a given sequence and the position it has been assigned in the genome. It is comprised by a series of letters and numbers to indicate how many consecutive bases have that mapping.
M |
alignment match |
I |
insertion |
D |
deletion |
N |
skipped |
S |
soft-clipping |
H |
hard-clipping |
e.g.
68M
- 68 bases matching the reference
1S67M
- 1 soft-clipped read followed by 67 matches
15M87N70M90N16M
- 15 matches following by 87 bases skipped followed by 70 matches etc.
Checking the alignment stats
We will now generate a few basic statistics about the alignment of our data
- Select the tool NGS: SAMtools -> Flagstat
- In the BAM File to Convert box choose the bam file produced by bwa-mem.
The tool will also report how many PCR Duplicates have been found in the data. But as we haven’t yet run any software to identify such reads, the flagstat output will show 0 reads.
- Find the tool SAMtools -> Idxstats
- In the BAM file dropdown select the bam file produced by bowtie2
The output of this tool will tell you how many reads aligned to each chromosome in your reference genome.
Optional Exercise: The multiqc tool that we introduced earlier is about to interpet the output of flagstat and idxstats. Create a report the combines the results of these metrics with the fastqc reports on the fastq files
Section 5. Visualising the aligned reads with IGV
Whilst Bioinformatics tools are very powerful and allow you to perform statistical analyses and test hypotheses, there is no substitute for looking at and exploring the data. A trained-eye can quite quickly get a sense of the data quality before any computational analyses have been run. Futhermore, as the person requesting the sequencing, you probably know a lot about the biological context of the samples and what to expect.
We will load the aligned reads that we have just created into IGV and start to get a feel for the process of variant calling
- Download IGV
You can download IGV for Windows using this link
Extract the zip file that you have downloaded
Double-Click the file igv
to launch IGV
- Load a reference Genome and some Data Tracks
By default, IGV should load with Human genome version hg19 already loaded. It is essential that you use the same genome version that the reads were aligned to. You can check / change the genome by clicking the drop-down menu in the upper-left
We can also load extra tracks into the browser that can help us understand our variant calls. For example, we can load data from dbSNP which will tell us about common mutations that already been identified. These can be loaded via File -> Load from Server.. and selecting dbSNP 1.4.7
from the Variation and Repeats
section
- Navigate around IGV
When IGV loads up we start with a very high-level view of the genome where all chromosomes are visible. Such a view might be useful if we were interested in large copy-number variation across a cohort of samples. However, we are mostly interested in changes at the individual base-level which is not possible to view at this resolution. We need to navigate to a particular region of interest.
Alongside the drop-down menu used to change the genome, there is a drop-down menu to select a particular chromosome and a box where we can enter text. Inside the text box we can enter a particular genome interval of interest
e.g. chr1:10,000-11,000
IGV should now be displaying a region on chromosome 1 from base position 10,000
to 11,000
.
At this resolution, we can start to see the genome sequence. Each DNA base is represented by a different colour (A = green, C = blue) and it seems that this region is highly-repetitive; comprising mostly C
bases. We can zoom fruther in using the zoom control in the top right of IGV
We can use the zoom control, and also move along the genome by holding down by mouse button and sliding left-and-right, to navigate to whatever genomic location we want. If we known the name of the gene we want to interrogate we can navigate directly there using the text box
The text box should now update to show the coordinates of BRCA1
(chr17:....
). At the bottom of the screen we can now see the gene model for the gene BRCA1
. Genes are represented as lines and boxes. Lines represent intronic regions and boxes represent exonic regions. The arrows indicate the direction / strand of transcription for the gene.
- Load the aligned reads
Choose File > Load from File…, select the bam file that you downloaded from Galaxy, and click OK. Note that the bam and index files must be in the same directory for IGV to load these properly.
The main display of IGV should now update to hold tracks for the aligned reads from this bam file. It may seem like nothing is being displayed. This is because we are zoomed-out too far to be able to see the reads. Use the zoom function and move along the genome until you get to the first exon of BRCA1. After you have zoomed-in far enough you will start to see some grey rectangles. These are the aligned reads.
If you hover over a particular read, how will see columns from the bam file being displayed such as the mapping quality and information about the paired reads.
Discussion:
Later on we will have some more examples of inspecting variants, but for now let’s familiarise ourselves with IGV and what the data look like
Navigate to region chr17:41,244,228-41,245,700
in IGV. How many potential SNVs can you find inside the region? How many of these are likely to be somatic.
Navigate to position chr17:41,219,513
in IGV. Hover over the coverage track and discover the percentage of reference bases in the Tumour and the Normal. Is there evidence for a somatic variant at this position?
Section 6: Post-processing of reads and Variant Calling
Whilst we can inspect variants by eye, it would clearly be impossible to scrutinise each position in the genome to see if a variants exists there. We will employ a variant calling method to narrow-down our search for somatic variants, although as we will see, such calls still require some degree of filtering and curation. The particular tool we will use is varscan2, mainly because it is available via Galaxy. For production-level analyses a tool such as MuTect could be considered. However, there are licensing issues which preclude MuTect from being available in Galaxy.
Before we can proceed to variant calling, there are a couple of post-processing tasks that should be performed; removing duplicates and indel re-alignment.
In brief, removing duplicates removes reads that have exactly the same start and end position. Such reads are assumed to be an artefact of the PCR process and give a false impression of the coverage at affected positions. However, careful thinking is required in situations other than whole-genome sequencing and this should certainly never be applied for targeted sequencing.
Indel re-alignment deals with an artefact that can occur when placing reads close to indels. Since each read is aligned separately, alignment tools may prefer to align a read with a reference mismatch rather than consider an indel within a read. However, taking all reads into consideration around a locus may reveal the presence of an indel and prevent SNVs being falsely identified.
Before realignment
After realignment
(see this video for an explanation)
Now follow the steps in “Mapped Reads postprocessing” from the galaxy training page, before proceeding to “Variant calling and classification”
Section 7: Annotation
About vcf format
In the previous section, you will have produced a vcf file. The .vcf
format was initially developed by the 1000 Genomes Project, and ownership has been subsequently transferred to Global Alliance for Genomics and Health Data Working group file format team. The format can be used to represent information about all kinds of genomic variation. In this session we will just consider SNVs.
We don’t require any specialised software to look at the contents of a vcf file. They can be opened in a bog-standard text editor, however your laptop may try and interpret the file as containing contact information (virtual contact file).
In a similar vein to the .bam
and .sam
files we saw earlier, the .vcf
files contains many lines of header information. These describe the reference sequences and various filters that have been applied.
##fileformat=VCFv4.2
##FILTER=<ID=PASS,Description="All filters passed">
##reference=ref.fa
##contig=<ID=chr5,length=180915260>
##contig=<ID=chr12,length=133851895>
##contig=<ID=chr17,length=81195210>
##FILTER=<ID=VarCount,Description="Fewer than 4 variant-supporting reads">
##FILTER=<ID=VarFreq,Description="Variant allele frequency below 0.05">
##FILTER=<ID=VarAvgRL,Description="Average clipped length of variant-supporting reads < 90">
......
......
After many more lines of information, we finally get to the details of the actual calls themsevles. This part of the file is tab-delimited; with 10 columns for every call. The vcf specification page gives details of what should be contained in each column
Shown here is the information about three calls
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NORMAL TUMOR
chr5 225768 . G C . VarReadPos DP=27;SS=1;SSC=0;GPV=5.1363e-16;SPV=1 GT:GQ:DP:AD:ADF:ADR 1/1:.:16:0,16:0,2:0,14 1/1:.:11:0,11:0,1:0,10
chr5 230980 . A G . PASS DP=157;SS=1;SSC=0;GPV=0;SPV=1 GT:GQ:DP:AD:ADF:ADR 1/1:.:88:0,88:0,51:0,37 1/1:.:69:0,69:0,45:0,24
chr5 231111 . T C . PASS DP=127;SS=1;SSC=0;GPV=0;SPV=1 GT:GQ:DP:AD:ADF:ADR 1/1:.:75:0,75:0,39:0,36 1/1:.:52:0,52:0,26:0,26
The first seven columns should look consistent across different genotype callers. The contents of the INFO
and FORMAT
columns will depend on what variant caller has been used. The INFO
column contains metrics and other information related to each variant call as a set of KEY=VALUE
pairs. Each pair is separated by a ;
character.
The INFO for the a variant call may read as:-
DP=27;SS=1;SSC=0;GPV=5.1363e-16;SPV=1
or
Key Value
DP=27 DP 27
SS=1 SS 1
SSC=0 SSC 0
GPV=5.1.. GPV 5.1363e-16
SPV=1 SPV 1
The meaning of each key can be discovered by looking at the header for the file. e.g. ##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read depth">
. So this variant has a total of 27 bases covering it.
The final two columns in the file describes the calls for the NORMAL and TUMOUR samples respectively. In the sample column (NORMAL
) for the first variant we see the entry
1/1:.:16:0,16:0,2:0,14
These are values separated by a :
character and they are interpreted in the same order as dictated by the FORMAT column; which is GT:GQ:DP:AD:ADF:ADR
##FORMAT=<ID=GT,Number=1,Type=String,Description=Genotype>
##FORMAT=<ID=GQ,Number=1,Type=Integer,Description="Genotype quality">
##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read depth">
##FORMAT=<ID=AD,Number=R,Type=Integer,Description="Read depth for each allele">
##FORMAT=<ID=ADF,Number=R,Type=Integer,Description="Read depth for each allele on the forward strand">
##FORMAT=<ID=ADR,Number=R,Type=Integer,Description="Read depth for each allele on the reverse strand">
So for this particular variant there is a genotype of 1\1
(Homozygous for the alternate allele) in the normal sample and a depth of 16
etc. The same genotype information is repeated for the tumour. From this we can infer whether the variant is likely to be somatic or not and gain insight into whether it is a true variant or a false positive (which we will discuss in detail later).
Discussion: Locate the lines in the vcf file that relate to some of the positions that we looked at previously in IGV. How many reads in total cover each position?
chr17:41244936
chr17:41219513
chr17:41234304
What kind of variants (Germline, Somatic) have been called at these positions?
You can also load the vcf into IGV, which will display details of each variant call above the aligned reads.
Annotating with SNPeff
As we have seen the standard vcf file contains genome coordinates for each variant, but gives no useful information about what gene (if any) the variant lies within or the potential impact of the variant. One such tool for adding genomic information is SNPeff which is described in the Galaxy tutorial.
- See here; “Adding functional genomic annotations” only
SNPeff will produce a modified vcf
file and a HTML report.
Discussion: Scroll through the contents of the vcf file produced by snpeff. What extra information has it added? Try and locate the variants within BRCA1
. Also take some time to digest the contents of the HTML report and the information it provides
Annotation with Ensembl VEP
A useful alternative to running SNPeff within Galaxy is the online VEP tool provided by Ensembl. This will annotate our variants with gene identifiers and also provide some predictions about the impact of the variant.
More documentation on Ensembl VEP is available online
Command line tools are available, but we will use the online interface; making sure that we access the version of VEP with the correct genome version. Going straight to the Ensembl VEP website will mean using a later genome build.
The hg19 version of VEP can be accessed here. A set of coordinates can be entered into the text box, or a VCF file can be uploaded.
Upload the vcf
file that you annotated with SNPeff. If you were unable to complete this step, a copy is available in the google drive; 231335_231336_VarScan_Variants_SnpEff_SS2.vcf
.
You will have a choice about what transcript database to use. The output can also be configured by clicking the + symbol next to a particular section. e.g. Variants and frequency data. After selecting the options you want, scroll down to the bottom of the page and click Run. The screen should now change to let you know that VEP is running.
The screen will refresh by itself, and eventually a green Done box should appear. At which point you will be able to inspect the results
The results can be inspected online, or downloaded. Downloading as a text file is better for browsing in Excel, and can also be manipulated in languages such as R.
Assessment of Somatic calls
Click here to follow an exercise on inspecting and evaluating somatic calls
LS0tCnRpdGxlOiAiIgphdXRob3I6ICJNYXJrIER1bm5pbmciCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgoKCiMgSGFuZHMtb24gU29tYXRpYyBWYXJpYW50IEFuYWx5c2lzIGluIEdhbGF4eSBhbmQgSUdWCgojIyMgU2hlZmZpZWxkIEJpb2luZm9ybWF0aWNzIENvcmUKPGltZyBzcmM9Im1lZGlhL2xvZ28tc20ucG5nIiBhbGlnbj1yaWdodD4KCndlYiA6IFtzYmMuc2hlZi5hYy51a10oaHR0cDovL3NiYy5zaGVmLmFjLnVrKSAgCnR3aXR0ZXI6IFtTaGVmZkJpb2luZkNvcmVdKGh0dHBzOi8vdHdpdHRlci5jb20vU2hlZmZCaW9pbmZDb3JlKSAgCmVtYWlsOiBbYmlvaW5mb3JtYXRpY3MtY29yZUBzaGVmZmllbGQuYWMudWtdKGJpb2luZm9ybWF0aWNzLWNvcmVAc2hlZmZpZWxkLmFjLnVrKQoKLS0tLS0KCiMgVHV0b3JpYWwgT3ZlcnZpZXcKClRoaXMgdHV0b3JpYWwgd2lsbCBjb3ZlciB0aGUgYmFzaWNzIG9mIFNvbWF0aWMgYW5hbHlzaXMgdXNpbmcgR2FsYXh5OyBhIG9wZW4tc291cmNlIHdlYi1iYXNlZCBwbGF0Zm9ybSBmb3IgdGhlIGFuYWx5c2lzIG9mIGJpb2xvZ2ljYWwgZGF0YS4gWW91IHNob3VsZCBnYWluIGFuIGFwcHJlY2lhdGlvbiBvZiB0aGUgdGFza3MgaW52b2x2ZWQgaW4gYSB0eXBpY2FsIE5HUyBhbmFseXNpcyBhbmQgYmUgY29tZm9ydGFibGUgd2l0aCB0aGUgb3V0cHV0cyBnZW5lcmF0ZWQgYnkgYSBzZXF1ZW5jaW5nIHNlcnZpY2UuIFlvdSB3aWxsIGFsc28gdXNlIHRoZSBJbnRlZ3JhdGl2ZSBHZW5vbWljcyBWaWV3ZXIgKElHVikgdG8gKnZpZXcqIHRoZSBhbGlnbmVkIHJlYWRzIGluIGFuIGludGVyYWN0aXZlIG1hbm5lci4KCldlIHdpbGwgdXNlIHRyYWluaW5nIG1hdGVyaWFscyBwcm92aWRlZCBieSB0aGUgR2FsYXh5IFByb2plY3QgYW5kIHNpZ24tcG9zdCB0byByZWxldmFudCBzZWN0aW9ucy4gSWYgeW91IHdhbnQgdG8gZmluZCBtb3JlIGRldGFpbGVkIHR1dG9yaWFscyBvbiBJR1Ygb3IgR2FsYXh5IHlvdSBjYW4gZm9sbG93IHRoZSBsaW5rcyBiZWxvdzotCgotIFtHYWxheHkgVHJhaW5pbmcgUG9ydGFsXShodHRwczovL3RyYWluaW5nLmdhbGF4eXByb2plY3Qub3JnL3RyYWluaW5nLW1hdGVyaWFsLykKLSBbSUdWIFR1dG9yaWFsXShodHRwczovL2dpdGh1Yi5jb20vZ3JpZmZpdGhsYWIvcm5hc2VxX3R1dG9yaWFsL3dpa2kvSUdWLVR1dG9yaWFsKQoKPCEtLVRoZSB0dXRvcmlhbCBjb3ZlcnMgdGhlIGZvbGxvd2luZyBzdGVwcyBpbiBvdXIgYW5hbHlzaXMgcGlwZWxpbmUKCiFbXShtZWRpYS9waXBlbGluZS5wbmcpCi0tPgoKLS0tLS0KCiMjIEJhY2tncm91bmQKCiMjIyMgV2hlcmUgZG8gdGhlIGRhdGEgaW4gdGhpcyB0dXRvcmlhbCBjb21lIGZyb20/CgpUaGUgZGF0YSBmb3IgdGhpcyB0dXRvcmlhbCBhcmUgZnJvbSBhIGNhbmNlciBwYXRpZW50IGRvd24tc2FtcGxlZCB0byBnZW5lcyB0aGF0IGFyZSBwcmVzZW50IGluIHRoZSBDT1NNSUMgZGF0YXNldC4gV2Ugd2lsbCB1c2UgdGhlc2UgZGF0YSB0aHJvdWdob3V0IHRoZSBjb3Vyc2UgdG8gY2FsbCB2YXJpYW50cywgZmlsdGVyIGFuZCBkaXNjdXNzIHRoZSBjbGluaWNhbCBpbXBhY3Qgb2YgYW55IG11dGF0aW9ucy4gCgojIFByZXBhcmF0aW9uIGFuZCBEYXRhIFVwbG9hZAoKSWYgYXR0ZW5kaW5nIHRoaXMgd29ya3Nob3AgaW4tcGVyc29uIHlvdSBzaG91bGQgaGF2ZSBhY2Nlc3MgdG8gYSBwcml2YXRlIHF1ZXVlIG9uIHRoZSB1c2VnYWxheHkuZXUgc2VydmVyIHRoYXQgd2lsbCBhbGxvdyB5b3VyIGpvYnMgdG8gcnVuIHF1aWNrZXIuCgpGb2xsb3cgdGhpcyBsaW5rIHRvIHJlZ2lzdGVyIGFuIGFjY291bnQ6LSAKCmh0dHBzOi8vdXNlZ2FsYXh5LmV1L2pvaW4tdHJhaW5pbmcvc2JjLXNvbWF0aWMtMjAxOS0wNS0xMAoKT3RoZXJ3aXNlLCByZWdpc3RlciBhcyBhIG5ldyB1c2VyIG9uIG9uZSBvZiB0aGUgcHVibGljIEdhbGF4eSBzZXJ2ZXJzCgotIGh0dHBzOi8vdXNlZ2FsYXh5Lm9yZy8KLSBodHRwczovL3VzZWdhbGF4eS5vcmcuYXUKLSBodHRwczovL3VzZWdhbGF4eS5ldQoKKipNYWtlIHN1cmUgeW91IGNoZWNrIHlvdXIgZW1haWwgdG8gYWN0aXZhdGUgeW91ciBhY2NvdW50KioKCiMjIEltcG9ydCB0aGUgZGF0YSBmb3IgdGhlIHdvcmtzaG9wLgoKV2UgY2FuIGdvaW5nIHRvIGltcG9ydCB0aGUgWypmYXN0cSogZmlsZXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZBU1RRX2Zvcm1hdCkgZm9yIHRoaXMgZXhwZXJpbWVudC4gVGhpcyBpcyBhIHN0YW5kYXJkIGZvcm1hdCBmb3Igc3RvcmluZyByYXcgc2VxdWVuY2luZyByZWFkcyBhbmQgdGhlaXIgYXNzb2NpYXRlZCBxdWFsaXR5IHNjb3Jlcy4gSG93ZXZlciwgYXMgd2Ugd2lsbCBzZWUsIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcXVhbGl0eSBzY29yZXMgaGFzIGNoYW5nZWQgb3ZlciB0aW1lLgoKVGhlIGZhc3RxIGZpbGVzIGZvciB0aGlzIHdvcmtzaG9wIGhhdmUgYmVlbiB1cGxvYWRlZCB0byBnb29nbGUgZHJpdmUgZm9sZGVyCgotIFtDbGljayBoZXJlIHRvIGFjY2VzcyB0aGUgZ29vZ2xlIGZvbGRlcl0oaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMS1TOGQ5Mk5tY1E3UmZWanRQLUZFdENpelpual9HVHZYP3VzcD1zaGFyaW5nKQoKRG93bmxvYWQgYWxsIHRoZSBmaWxlcyBlbmRpbmcgaW4gYGZhc3RxLmd6YCBhbmQgYGZhc3RhLmd6YCBpbiB0aGlzIGRpcmVjdG9yeSB0byB5b3VyIGxhcHRvcAoKWW91IGNhbiBpbXBvcnQgdGhlIGRhdGEgYnk6CgoxLiAgSW4gdGhlIHRvb2wgcGFuZWwgbG9jYXRlZCBvbiB0aGUgbGVmdCwgc2VsZWN0ICoqR2V0CiAgICBEYXRhID4gVXBsb2FkIEZpbGUqKi4gCjIuICAqKkNob29zZSBsb2NhbCBmaWxlKiogYW5kIGJyb3dzZSB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIGZpbGVzIGZyb20gdGhlIGdvb2dsZSBkcml2ZSBhbmQgc2VsZWN0IGFsbCB0aGUgZmlsZS4gQ2xpY2sgKipPcGVuKiogdG8gY2xvc2UgdGhlIGZpbGUgYnJvd3Nlci4gVGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBzaG91bGQgbm93IGFwcGVhciBpbiBHYWxheHkuCjMuICBDbGljayAqKlN0YXJ0KiogdG8gYmVnaW4gdGhlIHVwbG9hZAoKMy4gIFlvdSBzaG91bGQgbm93IGhhdmUgdGhlc2UgNSBmaWxlcyBpbiB5b3VyIGhpc3Rvcnk6CgotIGAyMzEzMzVfY2FuY2VyX2dlbmVzX3IxLmZhc3RxLmd6YAotIGAyMzEzMzVfY2FuY2VyX2dlbmVzX3IyLmZhc3RxLmd6YAotIGAyMzEzMzZfY2FuY2VyX2dlbmVzX3IxLmZhc3RxLmd6YAotIGAyMzEzMzZfY2FuY2VyX2dlbmVzX3IyLmZhc3RxLmd6YAotIGBoZzE5LmNocjVfMTJfMTcuZmFzdGEuZ3pgCgp3aGVyZSB0aGUgZmlyc3QgdHdvIGZpbGVzIHJlcHJlc2VudCB0aGUgZm9yd2FyZCBhbmQgcmV2ZXJzZSByZWFkcyBzZXF1ZW5jZSBkYXRhIGZyb20gYSBwYXRpZW504oCZcyBub3JtYWwgdGlzc3VlLCBhbmQgdGhlIG5leHQgdHdvIHJlcHJlc2VudCB0aGUgZGF0YSBvZiB0aGUgc2FtZSBwYXRpZW504oCZcyB0dW1vciB0aXNzdWUuIFRoZSBmaW5hbCBmaWxlIGlzIGEgY3V0LWRvd24gcmVmZXJlbmNlIGdlbm9tZSBmb3IgY2hyb21vc29tZXMgNSwgMTIgYW5kIDE3IG9ubHkuCgoKIyBTZWN0aW9uIDI6IEZhc3RxIGZpbGUgZm9ybWF0CgpZb3UgY2FuIHZpZXcgdGhlIGZpbGVzIHlvdSBqdXN0IHVwbG9hZGVkIGJ5IGNsaWNraW5nIHRoZSAqKmV5ZSBpY29uKiogdGhlIGhpc3RvcnkgaXRlbS4gVGhlIGZpcnN0IGZldyBsaW5lcyBzaG91bGQgcmVhZCBhcyBmb2xsb3dzCgoKKioyMzEzMzZfY2FuY2VyX2dlbmVzX3IxLmZhc3RxLmd6KioKCmBgYApAU1QtSzAwMjY1OjEzNzpIVDMzQ0JCWFg6MzoxMjEzOjk5NTI6MjczOC8xCkNHR0FDQ0NDQ0dBQ0FUR1RDVEdDVEdUVEdDQ0dDQ0dDR0NBR1RDQ0NHQ0NBR1RDQ0NUR0NHQ0FHQUNUR0NHQ0NUR0NHQ0FDQ0FDQUNDR0dHR1RDR0FHQ1RHR0NHR0dHR0FHR0dHCisKLUFGLUE8QUFBN0FBLUFGPEY3QUpBSkY8QUpGNzc3RkFKSkZKSjctQS03LUZKQUFBLUFGSko8N0Y3RjxGSjctQS1GSkE8SjdKNzc8PEZKPEpKPDxKQUZKPDdGSkpKSi1KLUE8N0EKYGBgCgoqKjIzMTMzNl9jYW5jZXJfZ2VuZXNfcjIuZmFzdHEuZ3oqKgoKYGBgCkBTVC1LMDAyNjU6MTM3OkhUMzNDQkJYWDozOjExMDc6MjA0Nzo2Mzc4LzEKQ0NBR0NUQ0dBQ0NDQ0dHVEdUR0dUR0NHQ0FHR0NHQ0FHVENUR0NHQ0FHR0dBQ1RHR0NHR0dBQ1RHQ0dDR0dDR0dDQUFDQUdDQUdBQ0FUR1RDR0dHR0dUQ0NHR0dHQ0NUR1RDR0MKKwpBQTxBQUZKRkFKN0EtQTctLUFGQTxGSkZKSjdGRkpBSjctNy03RkpKSkpGSjdGRkpKN0ZBPDxGPDdGSkpBQUpKQTxKSkpGRkpKPEFKRjxKSkZKQS08N0FKSkE8LUFGLUpKSkpKLQpgYGAKCgpUaGUgZmlyc3QgbGluZSBpcyB0aGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGVhY2ggc2VxdWVuY2VkIHJlYWQuIEl0IGNhbiBiZSB1c2VkIHRvIGVuY29kZSBpbmZvcm1hdGlvbiBzdWNoIGFzIHRoZSAqc2VxdWVuY2luZyBtYWNoaW5lKiwgKmZsb3cgY2VsbCogYW5kICpsYW5lKiB0aGF0IHRoZSByZWFkIHdhcyBnZW5lcmF0ZWQgZnJvbSBhbmQgdGhlIHBoeXNpY2FsIGNvb3JkaW5hdGVzIG9uIHRoZSBsYW5lLiAgCgpUaGUgcXVhbGl0eSBzY29yZXMgYXJlIFtBU0NJSV0oaHR0cDovL2FzY2lpLWNvZGUuY29tLykgcmVwcmVzZW50YXRpb25zIG9mIGhvdyBjb25maWRlbnQgd2UgYXJlIHRoYXQgYSBwYXJ0aWN1bGFyIGJhc2UgaGFzIGJlZW4gY2FsbGVkIGNvcnJlY3RseS4gTGV0dGVycyB0aGF0IGFyZSBmdXJ0aGVyIGFsb25nIHRoZSBhbHBoYWJldCBpbmRpY2F0ZSBoaWdoZXIgY29uZmlkZW5jZS4gVGhpcyBpcyBpbXBvcnRhbnQgd2hlbiB0cnlpbmcgdG8gaWRlbnRpZnkgdHlwZXMgb2YgZ2Vub21lIHZhcmlhdGlvbiBzdWNoIGFzIHNpbmdsZSBiYXNlIGNoYW5nZXMsIGJ1dCBpcyBhbHNvIGluZGljYXRpdmUgb2YgdGhlIG92ZXJhbGwgcXVhbGl0eSBvZiB0aGUgc2VxdWVuY2luZy4gRGlmZmVyZW50IHNjYWxlcyBoYXZlIGJlZW4gZW1wbG95ZWQgb3ZlciB0aW1lIChyZXN1bHRpbmcgaW4gYSBkaWZmZXJlbnQgc2V0IG9mIGNoYXJhY3RlcnMgYXBwZWFyaW5nIGluIHRoZSBmaWxlKS4gLiAKCgojIyMgRGVyaXZpbmcgdGhlIFF1YWxpdHkgU2NvcmUKCkZpcnN0IG9mIGFsbCwgd2UgY29udmVydCB0aGUgYmFzZS1jYWxsaW5nIHByb2JhYmlsaXR5IChwKSBpbnRvIGEgYFFgIHNjb3JlIHVzaW5nIHRoZSBmb3JtdWxhCgotIFF1YWxpdHkgc2NvcmVzICQkIFEgPSAtMTBsb2dfezEwfXAkJAogICAgKyBRID0gMzAsIHA9MC4wMDEKICAgICsgUSA9IDIwLCBwPTAuMDEKICAgICsgUSA9IDEwLCBwPTAuMQotIFRoZXNlIG51bWVyaWMgcXVhbnRpZXMgYXJlICplbmNvZGVkKiBhcyBbKipBU0NJSSoqXShodHRwOi8vYXNjaWktY29kZS5jb20vKSBjb2RlCiAgICArIEF0IGxlYXN0IDMzIHRvIGdldCB0byBtZWFuaW5nZnVsIGNoYXJhY3RlcnMKICAgIChodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GQVNUUV9mb3JtYXQpCiAgICAKIVtdKG1lZGlhL3BocmVkLnBuZykgICAgICAKCiMjIyBRdWFsaXR5IFNjb3JlcyB0byBwcm9iYWJpbGl0aWVzCgotIGxvb2stdXAgdGhlIEFTQ0lJIGNvZGUgZm9yIGVhY2ggY2hhcmFjdGVyCi0gc3VidHJhY3QgdGhlIG9mZnNldCB0byBnZXQgdGhlIFEgc2NvcmUKLSBjb252ZXJ0IHRvIGEgcHJvYmFiaWxpdHkgdXNpbmcgdGhlIGZvcm11bGE6LQoKJCQgcCA9IDEwXnstUS8xMH0gJCQKCkxldCdzIHNlZSB0aGlzIGNhbGN1bGF0aW9uIGZvciB0aGUgZmlyc3QgZmV3IGJhc2VzIG9mIHRoZSBmaXJzdCByZWFkIGluIGAyMzEzMzZfY2FuY2VyX2dlbmVzX3IxLmZhc3RxYDsgYC1BRi1BPEFBQTcuLi4uYAoKQ2hhcmFjdGVyICB8IENvZGUgfCBNaW51cyAzMyBPZmZzZXQgfCBQcm9iYWJpbGl0eQotLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tCi0gIHwgNDUgfCAxMiB8IDAuMDYzMQpBICB8IDY1IHwgMzIgfCAwLjAwMDYKRiAgfCA3MCB8IDM3IHwgMC4wMDAyCi0gIHwgNDUgfCAxMiB8IDAuMDYzMQpBICB8IDY1IHwgMzIgfCAwLjAwMDYKPCAgfCA2MCB8IDI3IHwgMC4wMDIwCkEgIHwgNjUgfCAzMiB8IDAuMDAwNgpBICB8IDY1IHwgMzIgfCAwLjAwMDYKCkluIHByYWN0aWNlLCB3ZSBkb24ndCBoYXZlIHRvIGNvbnZlcnQgdGhlIHZhbHVlcyBhcyB3ZSBoYXZlIHNvZnR3YXJlIHRoYXQgd2lsbCBkbyB0aGlzIGF1dG9tYXRpY2FsbHkKCgoKLS0tLS0KCiMgU2VjdGlvbiAzOiBRdWFsaXR5IEFzc2Vzc21lbnQgb2YgTkdTIHJlYWRzCgpbRmFzdFFDXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvKSBpcyBhIHBvcHVsYXIgdG9vbCBmcm9tIFtCYWJyYWhhbSBJbnN0aXR1dGUgQmlvaW5mb3JtYXRpY3MgR3JvdXBdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL2luZGV4Lmh0bWwpIHVzZWQgZm9yICpxdWFsaXR5IGFzc2Vzc21lbnQqIG9mIHNlcXVlbmNpbmcgZGF0YS4gTW9zdCBCaW9pbmZvcm1hdGljcyBwaXBlbGluZXMgd2lsbCB1c2UgRmFzdFFDLCBvciBzaW1pbGFyIHRvb2xzIGluIHRoZSBmaXJzdCBzdGFnZSBvZiB0aGUgYW5hbHlzaXMuIFRoZSBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjL0hlbHAvKSBmb3IgRmFzdFFDIHdpbGwgaGVscCB5b3UgdG8gaW50ZXJwcmV0IHRoZSBwbG90cyBhbmQgc3RhdHMgcHJvZHVjZWQgYnkgdGhlIHRvb2wuIEEgdHJhZmZpYyBsaWdodCBzeXN0ZW0gaXMgdXNlZCB0byBhbGVydCB0aGUgdXNlcidzIGF0dGVudGlvbiB0byBwb3NzaWJsZSBpc3N1ZXMuIAoKVGhlIG1vc3QgaW1wb3J0YW50IGltYWdlIGlzIHdoZXRoZXIgdGhlIGJhc2UgcXVhbGl0eSBkZWNyZWFzZXMgc2lnbmlmaWNhbnRseSBvdmVyIHRoZSBsZW5ndGggb2YgdGhlIHJlYWQKCiFbXShtZWRpYS9mYXN0cWMtMmEucG5nKQoKR29vZCBxdWFsaXR5IGRhdGEgc2hvdWxkIGxvb2sgc29tZXRoaW5nIGxpa2U6LQoKIVtdKG1lZGlhL2Zhc3RxYy0yYi5wbmcpCgpXZSB3aWxsIG5vdyBmb2xsb3cgdGhlIHJlbGV2YW50IHNlY3Rpb24gb24gdGhlIEdhbGF4eSB0cmFpbmluZyBwYWdlIGZvciBRQyBhbmQgYWxpZ25tZW50CgpbaHR0cHM6Ly90cmFpbmluZy5nYWxheHlwcm9qZWN0Lm9yZy90cmFpbmluZy1tYXRlcmlhbC90b3BpY3MvdmFyaWFudC1hbmFseXNpcy90dXRvcmlhbHMvc29tYXRpYy12YXJpYW50cy90dXRvcmlhbC5odG1sI3F1YWxpdHktY29udHJvbC1hbmQtbWFwcGluZy1vZi1uZ3MtcmVhZHNdKGh0dHBzOi8vdHJhaW5pbmcuZ2FsYXh5cHJvamVjdC5vcmcvdHJhaW5pbmctbWF0ZXJpYWwvdG9waWNzL3ZhcmlhbnQtYW5hbHlzaXMvdHV0b3JpYWxzL3NvbWF0aWMtdmFyaWFudHMvdHV0b3JpYWwuaHRtbCNxdWFsaXR5LWNvbnRyb2wtYW5kLW1hcHBpbmctb2YtbmdzLXJlYWRzKQoKIyBTZWN0aW9uIDQ6IEFsaWdubWVudAoKVGhlIHJlc3VsdCBvZiB0aGUgcHJldmlvdXMgcHJhY3RpY2FsIHdpbGwgYmUgYSBgLmJhbWAgZmlsZSB0aGF0IHdlIHdpbGwgZGVzY3JpYmUgaW4gdGhlIG5leHQgc2VjdGlvbi4gVGhpcyBmaWxlIGlzIG5vdCBodW1hbi1yZWFkYWJsZSwgYXMgaXQgaXMgY29tcHJlc2VkLiBCdXQgd2UgY2FuIGNvbnZlcnQgdG8gYSByZWFkYWJsZSBmb3JtYXQgZm9yIGlsbHVzdHJhdGlvbiBwdXJwb3Nlcy4KCiMjIFZpZXdpbmcgdGhlIGFsaWdubWVudHMKCkNsaWNrIG9uIHRoZSBleWUgb2YgdGhlIHJlc3VsdGluZyBmaWxlIHRvIHZpZXcgdGhlIGFsaWdubWVudHMuCgoKIVtdKG1lZGlhL2JhbS1hbGlnbm1lbnRzLnBuZykKCkEgKnNpbmdsZSBzdGFuZGFyZCogZmlsZSBmb3JtYXQgaGFzIGVtZXJnZWQgZm9yIGFsaWduZWQgcmVhZHMuIE1vcmVvZXZlciwgdGhpcyBmaWxlIGZvcm1hdCBpcyBjb25zaXN0ZW50IHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB5b3UgaGF2ZSBETkEtc2VxLCBSTkEtc2VxLCBDaElQLXNlcS4uLiBkYXRhLiAKClRoZSBgYmFtYCBmaWxlIGlzIGEgY29tcHJlc3NlZCwgYmluYXJ5LCB2ZXJzaW9uIG9mIGEgYHNhbWAgZmlsZS4KCi0gKipTKiplcXVlbmNlICoqQSoqbGlnbm1lbnQvKipNKiphcCAoc2FtKSAKLSBUaGUgb3V0cHV0IGZyb20gYW4gYWxpZ25lciBzdWNoIGFzIGBid2FgCi0gU2FtZSBmb3JtYXQgcmVnYXJkbGVzcyBvZiBzZXF1ZW5jaW5nIHByb3RvY29sIChpLmUuIFJOQS1zZXEsIENoSVAtc2VxLCBETkEtc2VxIGV0YykKLSBNYXkgY29udGFpbiB1bi1tYXBwZWQgcmVhZHMKLSBQb3RlbnRpYWxseSBsYXJnZSBzaXplIG9uIGRpc2s7IH4xMDBzIG9mIEdiCiAgICArIENhbiBiZSBtYW5pcHVsYXRlZCB3aXRoIHN0YW5kYXJkIHVuaXggdG9vbHM7IGUuZy4gKmNhdCosICpoZWFkKiwgKmdyZXAqLCAqbW9yZSosICpsZXNzKi4uLi4KLSBPZmZpY2lhbCBzcGVjaWZpY2F0aW9uIGNhbiBiZSBbb2J0YWluZWQgb25saW5lXShodHRwOi8vc2FtdG9vbHMuZ2l0aHViLmlvL2h0cy1zcGVjcy9TQU12MS5wZGYpOiAtCi0gV2Ugbm9ybWFsbHkgd29yayBvbiBhIGNvbXByZXNzZWQgdmVyc2lvbiBjYWxsZWQgYSBgLmJhbWAgZmlsZS4gU2VlIGxhdGVyLgotICpIZWFkZXIqIGxpbmVzIHN0YXJ0aW5nIHdpdGggYW4gYEBgIGNoYXJhY3RlciwgZm9sbG93ZWQgYnkgdGFiLWRlbGltaXRlZCBsaW5lcwogICAgKyBIZWFkZXIgZ2l2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGFsaWdubWVudCBhbmQgcmVmZXJlbmNlcyBzZXF1ZW5jZXMgdXNlZAoKClRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBoZWFkZXIgbGlzdHMgdGhlIG5hbWVzIChgU05gKSBvZiB0aGUgc2VxdWVuY2VzIChjaHJvbW9zb21lcykgdXNlZCBpbiBhbGlnbm1lbnQsIHRoZWlyIGxlbmd0aCAoYExOYCkgYW5kIHNvbXRpbWVzIGEgKm1kNXN1bSogIltkaWdpdGFsIGZpbmdlcnByaW50XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NZDVzdW0pIiBvZiB0aGUgYC5mYXN0YWAgZmlsZSB1c2VkIGZvciBhbGlnbm1lbnQgKGBNNWApLgoKYGBgCkBIRCBWTjoxLjMgU086Y29vcmRpbmF0ZQpAU1EgU046Y2hyNSBMTjoxODA5MTUyNjAKQFNRIFNOOmNocjEyIExOOjEzMzg1MTg5NQpAU1EgU046Y2hyMTcgTE46ODExOTUyMTAKQFJHIElEOjIzMTMzNSBTTTpOb3JtYWwgUEw6SUxMVU1JTkEKCmBgYAoKCgpXZSBhbHNvIGhhdmUgYSBzZWN0aW9uIHdoZXJlIHdlIGNhbiByZWNvcmQgdGhlIHByb2Nlc3Npbmcgc3RlcHMgdXNlZCB0byBkZXJpdmUgdGhlIGZpbGUKCmBgYApAUEcgSUQ6YndhIFBOOmJ3YSBWTjowLjcuMTctcjExODggQ0w6YndhIG1lbSAtdCA4IC12IDEgLVIgQFJHXHRJRDoyMzEzMzVcdFNNOk5vcm1hbFx0UEw6SUxMVU1JTkEgbG9jYWxyZWYuZmEgL2RhdGEvZG5iMDIvZ2FsYXh5X2RiL2ZpbGVzLzAwOS8zNTIvZGF0YXNldF85MzUyNDUyLmRhdCAvZGF0YS9kbmIwMi9nYWxheHlfZGIvZmlsZXMvMDA5LzM1Mi9kYXRhc2V0XzkzNTI0NTMuZGF0CgpgYGAKCk5leHQgaXMgYSAqdGFiLWRlbGltaXRlZCogc2VjdGlvbiB0aGF0IGRlc2NyaWJlcyB0aGUgYWxpZ25tZW50IG9mIGVhY2ggc2VxdWVuY2UgaW4gZGV0YWlsLiAKCmBgYApTVC1LMDAyNjU6MTM3OkhUMzNDQkJYWDozOjIxMDY6NTk0NDoxMTc1OQk5OQljaHI1CTIxODM3OAk2MAkxMDFNCT0JMjE4NDY1CTE4OAlHVEFUQ0NDQ0NDVENDQ0NDR0NDQUdDVENHQUNDQ0NHR1RHVEdHVEdDR0NBR0dDR0NBR1RDVEdDR0NBR0dHQUNUR0dDR0dHQUNUR0NHQ0dHQ0dHQ0FBQ0FHQ0FHQUNBVEdUQ0dHRwlBQUZGRkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSglOTTppOjAgTUQ6WjoxMDEgTUM6WjoxMDFNIEFTOmk6MTAxIFhTOmk6NTAgUkc6WjoyMzEzMzUKYGBgCgoKCkNvbHVtbiB8IE9mZmljaWFsIE5hbWUgfCBCcmllZgotLS0tLS0gfCAtLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tCjEgICAgICB8IFFOQU1FICAgICAgICAgIHwgU2VxdWVuY2UgSUQKMiAgICAgIHwgRkxBRyAgICAgICAgICAgfCBTZXF1ZW5jZSBxdWFsaXR5IGV4cHJlc3NlZCBhcyBhIGJpdHdpc2UgZmxhZwozICAgICAgfCBSTkFNRSAgICAgICAgICB8IENocm9tb3NvbWUKNCAgICAgIHwgUE9TICAgICAgICAgICAgfCBTdGFydCBQb3NpdGlvbgo1ICAgICAgfCBNQVBRICAgICAgICAgICB8IE1hcHBpbmcgUXVhbGl0eQo2ICAgICAgfCBDSUdBUiAgICAgICAgICB8IERlc2NyaWJlcyBwb3NpdGlvbnMgb2YgbWF0Y2hlcywgaW5zZXJ0aW9ucywgZGVsZXRpb25zIHcuci50IHJlZmVyZW5jZQo3ICAgICAgfCBSTkVYVCAgICAgICAgICB8IFJlZi4gbmFtZSBvZiBtYXRlIC8gbmV4dCByZWFkCjggICAgICB8IFBORVhUICAgICAgICAgIHwgUG9zdGlvbiBvZiBtYXRlIC8gbmV4dCByZWFkCjkgICAgICB8IFRMRU4gICAgICAgICAgIHwgT2JzZXJ2ZWQgVGVtcGxhdGUgbGVuZ3RoCjEwICAgICB8IFNFUSAgICAgICAgICAgIHwgU2VxdWVuY2UKMTEgICAgIHwgUVVBTCAgICAgICAgICAgfCBCYXNlIFF1YWxpdGllcwoKVGhlcmUgY2FuIGFsc28gYmUgYWxsIG1hbm5lciBvZiBvcHRpb25hbCB0YWdzIGFzIGV4dHJhIGNvbHVtbnMgaW50cm9kdWNlIGJ5IGFuIGFsaWduZXIgb3IgZG93bnN0cmVhbSBhbmFseXNpcyB0b29sLiBBIGNvbW1vbiB1c2UgaXMgdGhlIGBSR2AgdGFnIHdoaWNoIHJlZmVycyBiYWNrIHRvIHRoZSByZWFkIGdyb3VwcyBpbiB0aGUgaGVhZGVyLgoKCiMjIyBTb3J0aW5nIGFuZCBpbmRleGluZwoKWW91IHdpbGwgbm90aWNlIGZyb20gdGhlIDNyZCBjb2x1bW4gdGhhdCB0aGUgcmVhZHMgYXJlIG9yZGVyZWQgYWNjb3JkaW5nIHRvIHRoZWlyIHN0YXJ0IHBvc2l0aW9uOyB3aGVyZWFzIHRoZSByZWFkcyBpbiB0aGUgYGZhc3RxYCBmaWxlIHdlcmUgYXJyYW5nZWQgaW4gb3JkZXIgdGhhdCB0aGV5IHdlcmUgZ2VuZXJhdGVkIG9uIHRoZSBmbG93IGNlbGwuIEJ5IGRlZmF1bHQsIGBid2EtbWVtYCBwcm9kdWNlcyBhIGJhbSB3aGVyZSB0aGUgcmVhZHMgYXJlIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBgZmFzdHFgLiBIb3dldmVyLCB0aGlzIGlzIHJhdGhlciBpbmNvdmVuaWVudCBmb3IgYW5hbHlzaXMgd2hlcmUgd2UgcmVxdWlyZSByZWFkcyBmcm9tIHRoZSBzYW1lIGxvY2F0aW9uIHRvIGJlIG5leHQgdG8gZWFjaCBvdGhlciBpbiB0aGUgZmlsZS4KCkFuIGFkZGl0aW9uYWwgY291cGxlIG9mIHN0ZXBzIGhhdmUgYmVlbiBwZXJmb3JtZWQgYWZ0ZXIgYm93dGllMjsgc29ydGluZyB0aGUgZmlsZSBhY2NvcmRpbmcgdG8gZ2Vub21lIHBvc2l0aW9uIGFuZCBwcm9kdWNpbmcgYW4gKmluZGV4KiBmaWxlLiBUaGUgaW5kZXggZmlsZSBkb2VzIG5vdCBwcm92aWRlIGFueSB1c2VmdWwgaW5mb3JtYXRpb24gZm9yIHVzIGFuZCBjYW5ub3QgYmUgdmlld2VkIGluIEdhbGF4eS4gSG93ZXZlciwgd2Ugd2lsbCBuZWVkIGl0IGxhdGVyIG9uIHdoZW4gdmlld2luZyB0aGUgZGF0YSBpbiBJR1YuIAoKIyMgRHIgTWFyayBEdW5uaW5nIHByZXNlbnRzLi4uLkZ1biB3aXRoIGZsYWdzIQoKVGhlICoiZmxhZ3MiKiBpbiB0aGUgc2FtIGZpbGUgY2FuIHJlcHJlc2VudCB1c2VmdWwgUUMgaW5mb3JtYXRpb24KCiAgKyBSZWFkIGlzIHVubWFwcGVkCiAgKyBSZWFkIGlzIHBhaXJlZCAvIHVucGFpcmVkCiAgKyBSZWFkIGZhaWxlZCBRQwogICsgUmVhZCBpcyBhIFBDUiBkdXBsaWNhdGUgKHNlZSBsYXRlcikKClRoZSBjb21iaW5hdGlvbiBvZiBhbnkgb2YgdGhlc2UgcHJvcGVydGllcyBpcyB1c2VkIHRvIGRlcml2ZSBhIG51bWVyaWMgdmFsdWUKCgpGb3IgaW5zdGFuY2UsIGEgcGFydGljdWxhciByZWFkIGhhcyBhIGZsYWcgb2YgMTYzCgohW10obWVkaWEvZmxhZy1oaWdobGlnaHQucG5nKQoKCiMjIyBEZXJpdmF0aW9uCgpUaGVyZSBpcyBhIHNldCBvZiBwcm9wZXJ0aWVzIHRoYXQgYSByZWFkIGNhbiBwb3NzZXNzLiBJZiBhIHBhcnRpY3VsYXIgcHJvcGVydHkgaXMgb2JzZXJ2ZWQsIGEgY29ycmVzcG9uZGluZyBwb3dlciBvZiAyIGlzIGFkZGVkIG11bHRpcGxpZWQgYnkgMS4gVGhlIGZpbmFsIHZhbHVlIGlzIGRlcml2ZWQgYnkgc3VtbWluZyBhbGwgdGhlIHBvd2VycyBvZiAyLgoKIVtdKGh0dHBzOi8vZ2FsYXh5cHJvamVjdC5vcmcvdHV0b3JpYWxzL25ncy9zYW1fZmxhZy5wbmcpCgpGbGFnIFZhbHVlIHwgTWVhbmluZwotLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KNjkgKD0gMSArIDQgKyA2NCkgCXwgVGhlIHJlYWQgaXMgcGFpcmVkLCBpcyB0aGUgZmlyc3QgcmVhZCBpbiB0aGUgcGFpciwgYW5kIGlzIHVubWFwcGVkLgo3NyAoPSAxICsgNCArIDggKyA2NCkgfAlUaGUgcmVhZCBpcyBwYWlyZWQsIGlzIHRoZSBmaXJzdCByZWFkIGluIHRoZSBwYWlyLCBib3RoIGFyZSB1bm1hcHBlZC4KODMgKD0gMSArIDIgKyAxNiArIDY0KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgbWFwcGVkIGluIGEgcHJvcGVyIHBhaXIsIGlzIHRoZSBmaXJzdCByZWFkIGluIHRoZSBwYWlyLCBhbmQgaXQgaXMgbWFwcGVkIHRvIHRoZSByZXZlcnNlIHN0cmFuZC4KOTkgKD0gMSArIDIgKyAzMiArIDY0KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgbWFwcGVkIGluIGEgcHJvcGVyIHBhaXIsIGlzIHRoZSBmaXJzdCByZWFkIGluIHRoZSBwYWlyLCBhbmQgaXRzIG1hdGUgaXMgbWFwcGVkIHRvIHRoZSByZXZlcnNlIHN0cmFuZC4KMTMzICg9IDEgKyA0ICsgMTI4KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgaXMgdGhlIHNlY29uZCByZWFkIGluIHRoZSBwYWlyLCBhbmQgaXQgaXMgdW5tYXBwZWQuCjEzNyAoPSAxICsgOCArIDEyOCkgIHwJVGhlIHJlYWQgaXMgcGFpcmVkLCBpcyB0aGUgc2Vjb25kIHJlYWQgaW4gdGhlIHBhaXIsIGFuZCBpdCBpcyBtYXBwZWQgd2hpbGUgaXRzIG1hdGUgaXMgbm90LgoxNDEgKD0gMSArIDQgKyA4ICsgMTI4KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgaXMgdGhlIHNlY29uZCByZWFkIGluIHRoZSBwYWlyLCBidXQgYm90aCBhcmUgdW5tYXBwZWQuCjE0NyAoPSAxICsgMiArIDE2ICsgMTI4KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgbWFwcGVkIGluIGEgcHJvcGVyIHBhaXIsIGlzIHRoZSBzZWNvbmQgcmVhZCBpbiB0aGUgcGFpciwgYW5kIG1hcHBlZCB0byB0aGUgcmV2ZXJzZSBzdHJhbmQuCjE2MyAoPSAxICsgMiArIDMyICsgMTI4KSB8CVRoZSByZWFkIGlzIHBhaXJlZCwgbWFwcGVkIGluIGEgcHJvcGVyIHBhaXIsIGlzIHRoZSBzZWNvbmQgcmVhZCBpbiB0aGUgcGFpciwgYW5kIGl0cyBtYXRlIGlzIG1hcHBlZCB0byB0aGUgcmV2ZXJzZSBzdHJhbmQuCgoKClNlZSBhbHNvCgotIGh0dHBzOi8vYnJvYWRpbnN0aXR1dGUuZ2l0aHViLmlvL3BpY2FyZC9leHBsYWluLWZsYWdzLmh0bWwKCiMjIEhhdmUgYSBDSUdBUiEKCgohW10obWVkaWEvY2lnYXItaGlnaGxpZ2h0LnBuZykKClRoZSAqKipDSUdBUioqKiAoKipDKipvbXBhY3QgKipJKipkaW9zeW5jcmF0aWMgKipHKiphcHBlZCAqKkFsaWdubWVudCoqICoqUioqZXBvcnQpIHN0cmluZyBpcyBhIHdheSBvZiBlbmNvZGluZyB0aGUgbWF0Y2ggYmV0d2VlbiBhIGdpdmVuIHNlcXVlbmNlIGFuZCB0aGUgcG9zaXRpb24gaXQgaGFzIGJlZW4gYXNzaWduZWQgaW4gdGhlIGdlbm9tZS4gSXQgaXMgY29tcHJpc2VkIGJ5IGEgc2VyaWVzIG9mIGxldHRlcnMgYW5kIG51bWJlcnMgdG8gaW5kaWNhdGUgaG93IG1hbnkgY29uc2VjdXRpdmUgYmFzZXMgaGF2ZSB0aGF0IG1hcHBpbmcuCgoKIAogQ29kZSAgfCBEZXNjcmlwdGlvbgotLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLQpNICB8IGFsaWdubWVudCBtYXRjaApJICB8IGluc2VydGlvbgpEICB8IGRlbGV0aW9uCk4gIHwgc2tpcHBlZApTICB8IHNvZnQtY2xpcHBpbmcKSCAgfCBoYXJkLWNsaXBwaW5nCgoKZS5nLgoKLSBgNjhNYAogICAgKyA2OCBiYXNlcyBtYXRjaGluZyB0aGUgcmVmZXJlbmNlCi0gYDFTNjdNYAogICAgKyAxIHNvZnQtY2xpcHBlZCByZWFkIGZvbGxvd2VkIGJ5IDY3IG1hdGNoZXMKLSBgMTVNODdONzBNOTBOMTZNYAogICAgKyAxNSBtYXRjaGVzIGZvbGxvd2luZyBieSA4NyBiYXNlcyBza2lwcGVkIGZvbGxvd2VkIGJ5IDcwIG1hdGNoZXMgZXRjLgoKCiMjIENoZWNraW5nIHRoZSBhbGlnbm1lbnQgc3RhdHMKCldlIHdpbGwgbm93IGdlbmVyYXRlIGEgZmV3IGJhc2ljIHN0YXRpc3RpY3MgYWJvdXQgdGhlIGFsaWdubWVudCBvZiBvdXIgZGF0YQoKMS4gU2VsZWN0IHRoZSB0b29sICpOR1M6IFNBTXRvb2xzIC0+IEZsYWdzdGF0KiAKMi4gSW4gdGhlICpCQU0gRmlsZSB0byBDb252ZXJ0KiBib3ggY2hvb3NlIHRoZSBiYW0gZmlsZSBwcm9kdWNlZCBieSBid2EtbWVtLgoKClRoZSB0b29sIHdpbGwgYWxzbyByZXBvcnQgaG93IG1hbnkgKioqUENSIER1cGxpY2F0ZXMqKiogaGF2ZSBiZWVuIGZvdW5kIGluIHRoZSBkYXRhLiBCdXQgYXMgd2UgaGF2ZW4ndCB5ZXQgcnVuIGFueSBzb2Z0d2FyZSB0byBpZGVudGlmeSBzdWNoIHJlYWRzLCB0aGUgZmxhZ3N0YXQgb3V0cHV0IHdpbGwgc2hvdyAwIHJlYWRzLgoKMS4gRmluZCB0aGUgdG9vbCAqU0FNdG9vbHMgLT4gSWR4c3RhdHMqCjIuIEluIHRoZSAqQkFNIGZpbGUqIGRyb3Bkb3duIHNlbGVjdCB0aGUgYmFtIGZpbGUgcHJvZHVjZWQgYnkgYm93dGllMgoKVGhlIG91dHB1dCBvZiB0aGlzIHRvb2wgd2lsbCB0ZWxsIHlvdSBob3cgbWFueSByZWFkcyBhbGlnbmVkIHRvIGVhY2ggY2hyb21vc29tZSBpbiB5b3VyIHJlZmVyZW5jZSBnZW5vbWUuCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KCioqT3B0aW9uYWwgRXhlcmNpc2U6KiogVGhlIG11bHRpcWMgdG9vbCB0aGF0IHdlIGludHJvZHVjZWQgZWFybGllciBpcyBhYm91dCB0byBpbnRlcnBldCB0aGUgb3V0cHV0IG9mIGZsYWdzdGF0IGFuZCBpZHhzdGF0cy4gQ3JlYXRlIGEgcmVwb3J0IHRoZSBjb21iaW5lcyB0aGUgcmVzdWx0cyBvZiB0aGVzZSBtZXRyaWNzIHdpdGggdGhlIGZhc3RxYyByZXBvcnRzIG9uIHRoZSBmYXN0cSBmaWxlcwoKPC9kaXY+CgoKIyMgRG93bmxvYWQgeW91ciBiYW0gZmlsZQoKRm9yIHRoZSBuZXh0IHNldHAgeW91IHdpbGwgbmVlZCB0byBkb3dubG9hZCB0aGUgYGJhbWAgZmlsZS4gVG8gZG8gdGhpcywgeW91IGNhbiBjbGljayB0aGUgZmxvcHB5IGRpc2sgaWNvbi4KCiFbXShtZWRpYS9kb3dubG9hZF9iYW0ucG5nKQoKKipNYWtlIHN1cmUgdGhhdCB5b3UgY2xpY2sgYm90aCBEb3dubG9hZCBkYXRhc2V0IGFuZCBEb3dubG9hZCBiYW1faW5kZXgqKgoKKipJZiB5b3UgaGF2ZSBwcm9ibGVtcyBjcmVhdGluZyB0aGUgYmFtIGZpbGUsIGEgcHJlLXByZXBhcmVkIGZpbGUgaXMgYXZhaWxhYmxlIGZyb20gdGhlIGdvb2dsZSBkcml2ZSoqCgpodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZHJpdmUvZm9sZGVycy8xLVM4ZDkyTm1jUTdSZlZqdFAtRkV0Q2l6Wm5qX0dUdlg/dXNwPXNoYXJpbmcKCiMgU2VjdGlvbiA1LiBWaXN1YWxpc2luZyB0aGUgYWxpZ25lZCByZWFkcyB3aXRoIElHVgoKV2hpbHN0IEJpb2luZm9ybWF0aWNzIHRvb2xzIGFyZSB2ZXJ5IHBvd2VyZnVsIGFuZCBhbGxvdyB5b3UgdG8gcGVyZm9ybSBzdGF0aXN0aWNhbCBhbmFseXNlcyBhbmQgdGVzdCBoeXBvdGhlc2VzLCB0aGVyZSBpcyBubyBzdWJzdGl0dXRlIGZvciAqKmxvb2tpbmcgYXQgYW5kIGV4cGxvcmluZyB0aGUgZGF0YSoqLiBBIHRyYWluZWQtZXllIGNhbiBxdWl0ZSBxdWlja2x5IGdldCBhIHNlbnNlIG9mIHRoZSBkYXRhIHF1YWxpdHkgYmVmb3JlIGFueSBjb21wdXRhdGlvbmFsIGFuYWx5c2VzIGhhdmUgYmVlbiBydW4uIEZ1dGhlcm1vcmUsIGFzIHRoZSBwZXJzb24gcmVxdWVzdGluZyB0aGUgc2VxdWVuY2luZywgeW91IHByb2JhYmx5IGtub3cgYSBsb3QgYWJvdXQgdGhlIGJpb2xvZ2ljYWwgY29udGV4dCBvZiB0aGUgc2FtcGxlcyBhbmQgd2hhdCB0byBleHBlY3QuCgpXZSB3aWxsIGxvYWQgdGhlIGFsaWduZWQgcmVhZHMgdGhhdCB3ZSBoYXZlIGp1c3QgY3JlYXRlZCBpbnRvIElHViBhbmQgc3RhcnQgdG8gZ2V0IGEgZmVlbCBmb3IgdGhlIHByb2Nlc3Mgb2YgdmFyaWFudCBjYWxsaW5nCgoxLiBEb3dubG9hZCBJR1YKCllvdSBjYW4gZG93bmxvYWQgSUdWIGZvciBXaW5kb3dzIHVzaW5nIHRoaXMgbGluayAKCi0gaHR0cHM6Ly9zb2Z0d2FyZS5icm9hZGluc3RpdHV0ZS5vcmcvc29mdHdhcmUvaWd2L2Rvd25sb2FkCgoqRXh0cmFjdCogdGhlIHppcCBmaWxlIHRoYXQgeW91IGhhdmUgZG93bmxvYWRlZAoKCgohW10obWVkaWEvZXh0cmFjdF9pZ3YuUE5HKQoKCgpEb3VibGUtQ2xpY2sgdGhlIGZpbGUgYGlndmAgdG8gbGF1bmNoIElHVgoKCgohW10obWVkaWEvcnVuX2lndi5QTkcpCgoKCjIuIExvYWQgYSByZWZlcmVuY2UgR2Vub21lIGFuZCBzb21lIERhdGEgVHJhY2tzCgpCeSBkZWZhdWx0LCBJR1Ygc2hvdWxkIGxvYWQgd2l0aCBIdW1hbiBnZW5vbWUgdmVyc2lvbiAqaGcxOSogYWxyZWFkeSBsb2FkZWQuIEl0IGlzIGVzc2VudGlhbCB0aGF0IHlvdSB1c2UgdGhlICoqc2FtZSBnZW5vbWUgdmVyc2lvbioqIHRoYXQgdGhlIHJlYWRzIHdlcmUgYWxpZ25lZCB0by4gWW91IGNhbiBjaGVjayAvIGNoYW5nZSB0aGUgZ2Vub21lIGJ5IGNsaWNraW5nIHRoZSBkcm9wLWRvd24gbWVudSBpbiB0aGUgdXBwZXItbGVmdAoKIVtdKG1lZGlhL3NlbGVjdF9nZW5vbWUuUE5HKQoKV2UgY2FuIGFsc28gbG9hZCBleHRyYSAqdHJhY2tzKiBpbnRvIHRoZSBicm93c2VyIHRoYXQgY2FuIGhlbHAgdXMgdW5kZXJzdGFuZCBvdXIgdmFyaWFudCBjYWxscy4gRm9yIGV4YW1wbGUsIHdlIGNhbiBsb2FkIGRhdGEgZnJvbSAqZGJTTlAqIHdoaWNoIHdpbGwgdGVsbCB1cyBhYm91dCBjb21tb24gbXV0YXRpb25zIHRoYXQgYWxyZWFkeSBiZWVuIGlkZW50aWZpZWQuIFRoZXNlIGNhbiBiZSBsb2FkZWQgdmlhICpGaWxlKiAtPiAqTG9hZCBmcm9tIFNlcnZlci4uKiBhbmQgc2VsZWN0aW5nIGBkYlNOUCAxLjQuN2AgZnJvbSB0aGUgYFZhcmlhdGlvbiBhbmQgUmVwZWF0c2Agc2VjdGlvbgoKIVtdKG1lZGlhL2F2YWlsYWJsZV9kYXRhc2V0cy5QTkcpCgoKMy4gTmF2aWdhdGUgYXJvdW5kIElHVgoKV2hlbiBJR1YgbG9hZHMgdXAgd2Ugc3RhcnQgd2l0aCBhIHZlcnkgaGlnaC1sZXZlbCB2aWV3IG9mIHRoZSBnZW5vbWUgd2hlcmUgKmFsbCogY2hyb21vc29tZXMgYXJlIHZpc2libGUuIFN1Y2ggYSB2aWV3IG1pZ2h0IGJlIHVzZWZ1bCBpZiB3ZSB3ZXJlIGludGVyZXN0ZWQgaW4gbGFyZ2UgY29weS1udW1iZXIgdmFyaWF0aW9uIGFjcm9zcyBhIGNvaG9ydCBvZiBzYW1wbGVzLiBIb3dldmVyLCB3ZSBhcmUgbW9zdGx5IGludGVyZXN0ZWQgaW4gY2hhbmdlcyBhdCB0aGUgaW5kaXZpZHVhbCBiYXNlLWxldmVsIHdoaWNoIGlzIG5vdCBwb3NzaWJsZSB0byB2aWV3IGF0IHRoaXMgcmVzb2x1dGlvbi4gV2UgbmVlZCB0byBuYXZpZ2F0ZSB0byBhIHBhcnRpY3VsYXIgcmVnaW9uIG9mIGludGVyZXN0LgoKQWxvbmdzaWRlIHRoZSBkcm9wLWRvd24gbWVudSB1c2VkIHRvIGNoYW5nZSB0aGUgZ2Vub21lLCB0aGVyZSBpcyBhIGRyb3AtZG93biBtZW51IHRvIHNlbGVjdCBhIHBhcnRpY3VsYXIgY2hyb21vc29tZSBhbmQgYSBib3ggd2hlcmUgd2UgY2FuIGVudGVyIHRleHQuIEluc2lkZSB0aGUgdGV4dCBib3ggd2UgY2FuIGVudGVyIGEgcGFydGljdWxhciBnZW5vbWUgaW50ZXJ2YWwgb2YgaW50ZXJlc3QKCmUuZy4gYGNocjE6MTAsMDAwLTExLDAwMGAKCgpJR1Ygc2hvdWxkIG5vdyBiZSBkaXNwbGF5aW5nIGEgcmVnaW9uIG9uIGNocm9tb3NvbWUgMSBmcm9tIGJhc2UgcG9zaXRpb24gYDEwLDAwMGAgdG8gYDExLDAwMGAuIAoKIVtdKG1lZGlhL3pvb21fcmVnaW9uLlBORykKCgpBdCB0aGlzIHJlc29sdXRpb24sIHdlIGNhbiBzdGFydCB0byBzZWUgdGhlICpnZW5vbWUgc2VxdWVuY2UqLiBFYWNoIEROQSBiYXNlIGlzIHJlcHJlc2VudGVkIGJ5IGEgZGlmZmVyZW50IGNvbG91ciAoQSA9IGdyZWVuLCBDID0gYmx1ZSkgYW5kIGl0IHNlZW1zIHRoYXQgdGhpcyByZWdpb24gaXMgaGlnaGx5LXJlcGV0aXRpdmU7IGNvbXByaXNpbmcgbW9zdGx5IGBDYCBiYXNlcy4gV2UgY2FuIHpvb20gZnJ1dGhlciBpbiB1c2luZyB0aGUgem9vbSBjb250cm9sIGluIHRoZSB0b3AgcmlnaHQgb2YgSUdWCgohW10obWVkaWEvaG93X3RvX3pvb20uUE5HKQoKV2UgY2FuIHVzZSB0aGUgem9vbSBjb250cm9sLCBhbmQgYWxzbyBtb3ZlIGFsb25nIHRoZSBnZW5vbWUgYnkgaG9sZGluZyBkb3duIGJ5IG1vdXNlIGJ1dHRvbiBhbmQgc2xpZGluZyBsZWZ0LWFuZC1yaWdodCwgdG8gbmF2aWdhdGUgdG8gd2hhdGV2ZXIgZ2Vub21pYyBsb2NhdGlvbiB3ZSB3YW50LiBJZiB3ZSBrbm93biB0aGUgbmFtZSBvZiB0aGUgZ2VuZSB3ZSB3YW50IHRvIGludGVycm9nYXRlIHdlIGNhbiBuYXZpZ2F0ZSBkaXJlY3RseSB0aGVyZSB1c2luZyB0aGUgdGV4dCBib3gKCiFbXShtZWRpYS9zZWxlY3RfcmVnaW9uLlBORykKClRoZSB0ZXh0IGJveCBzaG91bGQgbm93IHVwZGF0ZSB0byBzaG93IHRoZSBjb29yZGluYXRlcyBvZiBgQlJDQTFgIChgY2hyMTc6Li4uLmApLiBBdCB0aGUgYm90dG9tIG9mIHRoZSBzY3JlZW4gd2UgY2FuIG5vdyBzZWUgdGhlICpnZW5lIG1vZGVsKiBmb3IgdGhlIGdlbmUgYEJSQ0ExYC4gIEdlbmVzIGFyZSByZXByZXNlbnRlZCBhcyBsaW5lcyBhbmQgYm94ZXMuIExpbmVzIHJlcHJlc2VudCBpbnRyb25pYyByZWdpb25zIGFuZCBib3hlcyByZXByZXNlbnQgZXhvbmljIHJlZ2lvbnMuIFRoZSBhcnJvd3MgaW5kaWNhdGUgdGhlIGRpcmVjdGlvbiAvIHN0cmFuZCBvZiB0cmFuc2NyaXB0aW9uIGZvciB0aGUgZ2VuZS4KCiFbXShtZWRpYS9nZW5lX3JlZ2lvbi5QTkcpCgo0LiBMb2FkIHRoZSBhbGlnbmVkIHJlYWRzCgpDaG9vc2UgRmlsZSA+IExvYWQgZnJvbSBGaWxlLi4uLCBzZWxlY3QgdGhlIGJhbSBmaWxlIHRoYXQgeW91IGRvd25sb2FkZWQgZnJvbSBHYWxheHksIGFuZCBjbGljayBPSy4gTm90ZSB0aGF0IHRoZSBiYW0gYW5kIGluZGV4IGZpbGVzIG11c3QgYmUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGZvciBJR1YgdG8gbG9hZCB0aGVzZSBwcm9wZXJseS4KCiFbXShtZWRpYS9zZWxlY3RfYmFtLlBORykKClRoZSBtYWluIGRpc3BsYXkgb2YgSUdWIHNob3VsZCBub3cgdXBkYXRlIHRvIGhvbGQgdHJhY2tzIGZvciB0aGUgYWxpZ25lZCByZWFkcyBmcm9tIHRoaXMgYmFtIGZpbGUuIEl0IG1heSBzZWVtIGxpa2Ugbm90aGluZyBpcyBiZWluZyBkaXNwbGF5ZWQuIFRoaXMgaXMgYmVjYXVzZSB3ZSBhcmUgem9vbWVkLW91dCB0b28gZmFyIHRvIGJlIGFibGUgdG8gc2VlIHRoZSByZWFkcy4gKipVc2UgdGhlIHpvb20gZnVuY3Rpb24gYW5kIG1vdmUgYWxvbmcgdGhlIGdlbm9tZSB1bnRpbCB5b3UgZ2V0IHRvIHRoZSBmaXJzdCBleG9uIG9mIEJSQ0ExKiouIEFmdGVyIHlvdSBoYXZlIHpvb21lZC1pbiBmYXIgZW5vdWdoIHlvdSB3aWxsIHN0YXJ0IHRvIHNlZSBzb21lIGdyZXkgcmVjdGFuZ2xlcy4gKlRoZXNlIGFyZSB0aGUgYWxpZ25lZCByZWFkcyouCgoKSWYgeW91IGhvdmVyIG92ZXIgYSBwYXJ0aWN1bGFyIHJlYWQsIGhvdyB3aWxsIHNlZSBjb2x1bW5zIGZyb20gdGhlIGJhbSBmaWxlIGJlaW5nIGRpc3BsYXllZCBzdWNoIGFzIHRoZSBtYXBwaW5nIHF1YWxpdHkgYW5kIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwYWlyZWQgcmVhZHMuCgoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CgoqKkRpc2N1c3Npb246KiogCgpMYXRlciBvbiB3ZSB3aWxsIGhhdmUgc29tZSBtb3JlIGV4YW1wbGVzIG9mIGluc3BlY3RpbmcgdmFyaWFudHMsIGJ1dCBmb3Igbm93IGxldCdzIGZhbWlsaWFyaXNlIG91cnNlbHZlcyB3aXRoIElHViBhbmQgd2hhdCB0aGUgZGF0YSBsb29rIGxpa2UKCi0gTmF2aWdhdGUgdG8gcmVnaW9uIGBjaHIxNzo0MSwyNDQsMjI4LTQxLDI0NSw3MDBgIGluIElHVi4gSG93IG1hbnkgcG90ZW50aWFsIFNOVnMgY2FuIHlvdSBmaW5kIGluc2lkZSB0aGUgcmVnaW9uPyBIb3cgbWFueSBvZiB0aGVzZSBhcmUgbGlrZWx5IHRvIGJlICpzb21hdGljKi4KCi0gTmF2aWdhdGUgdG8gcG9zaXRpb24gYGNocjE3OjQxLDIxOSw1MTNgIGluIElHVi4gSG92ZXIgb3ZlciB0aGUgY292ZXJhZ2UgdHJhY2sgYW5kIGRpc2NvdmVyIHRoZSBwZXJjZW50YWdlIG9mIHJlZmVyZW5jZSBiYXNlcyBpbiB0aGUgVHVtb3VyIGFuZCB0aGUgTm9ybWFsLiBJcyB0aGVyZSBldmlkZW5jZSBmb3IgYSBzb21hdGljIHZhcmlhbnQgYXQgdGhpcyBwb3NpdGlvbj8gCgoKPC9kaXY+CgojIFNlY3Rpb24gNjogUG9zdC1wcm9jZXNzaW5nIG9mIHJlYWRzIGFuZCBWYXJpYW50IENhbGxpbmcKCldoaWxzdCB3ZSBjYW4gaW5zcGVjdCB2YXJpYW50cyBieSBleWUsIGl0IHdvdWxkIGNsZWFybHkgYmUgaW1wb3NzaWJsZSB0byBzY3J1dGluaXNlIGVhY2ggcG9zaXRpb24gaW4gdGhlIGdlbm9tZSB0byBzZWUgaWYgYSB2YXJpYW50cyBleGlzdHMgdGhlcmUuIFdlIHdpbGwgZW1wbG95IGEgKnZhcmlhbnQgY2FsbGluZyogbWV0aG9kIHRvIG5hcnJvdy1kb3duIG91ciBzZWFyY2ggZm9yIHNvbWF0aWMgdmFyaWFudHMsIGFsdGhvdWdoIGFzIHdlIHdpbGwgc2VlLCBzdWNoIGNhbGxzIHN0aWxsIHJlcXVpcmUgc29tZSBkZWdyZWUgb2YgZmlsdGVyaW5nIGFuZCBjdXJhdGlvbi4gVGhlIHBhcnRpY3VsYXIgdG9vbCB3ZSB3aWxsIHVzZSBpcyBbdmFyc2NhbjJdKGh0dHA6Ly9ka29ib2xkdC5naXRodWIuaW8vdmFyc2Nhbi8pLCBtYWlubHkgYmVjYXVzZSBpdCBpcyBhdmFpbGFibGUgdmlhIEdhbGF4eS4gRm9yIHByb2R1Y3Rpb24tbGV2ZWwgYW5hbHlzZXMgYSB0b29sIHN1Y2ggYXMgW011VGVjdF0oaHR0cHM6Ly9zb2Z0d2FyZS5icm9hZGluc3RpdHV0ZS5vcmcvY2FuY2VyL2NnYS9tdXRlY3QpIGNvdWxkIGJlIGNvbnNpZGVyZWQuIEhvd2V2ZXIsIHRoZXJlIGFyZSBsaWNlbnNpbmcgaXNzdWVzIHdoaWNoIHByZWNsdWRlIE11VGVjdCBmcm9tIGJlaW5nIGF2YWlsYWJsZSBpbiBHYWxheHkuIAoKQmVmb3JlIHdlIGNhbiBwcm9jZWVkIHRvIHZhcmlhbnQgY2FsbGluZywgdGhlcmUgYXJlIGEgY291cGxlIG9mIHBvc3QtcHJvY2Vzc2luZyB0YXNrcyB0aGF0IHNob3VsZCBiZSBwZXJmb3JtZWQ7IHJlbW92aW5nIGR1cGxpY2F0ZXMgYW5kIGluZGVsIHJlLWFsaWdubWVudC4gCgpJbiBicmllZiwgcmVtb3ZpbmcgKmR1cGxpY2F0ZXMqIHJlbW92ZXMgcmVhZHMgdGhhdCBoYXZlICoqZXhhY3RseSB0aGUgc2FtZSoqIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb24uIFN1Y2ggcmVhZHMgYXJlICphc3N1bWVkKiB0byBiZSBhbiBhcnRlZmFjdCBvZiB0aGUgUENSIHByb2Nlc3MgYW5kIGdpdmUgYSBmYWxzZSBpbXByZXNzaW9uIG9mIHRoZSBjb3ZlcmFnZSBhdCBhZmZlY3RlZCBwb3NpdGlvbnMuICpIb3dldmVyLCBjYXJlZnVsIHRoaW5raW5nIGlzIHJlcXVpcmVkIGluIHNpdHVhdGlvbnMgb3RoZXIgdGhhbiB3aG9sZS1nZW5vbWUgc2VxdWVuY2luZyBhbmQgdGhpcyBzaG91bGQgY2VydGFpbmx5IG5ldmVyIGJlIGFwcGxpZWQgZm9yIHRhcmdldGVkIHNlcXVlbmNpbmcqLgoKIVtdKG1lZGlhL3Bjcl9kdXBzLnBuZykKCkluZGVsIHJlLWFsaWdubWVudCBkZWFscyB3aXRoIGFuIGFydGVmYWN0IHRoYXQgY2FuIG9jY3VyIHdoZW4gcGxhY2luZyByZWFkcyBjbG9zZSB0byBpbmRlbHMuIFNpbmNlIGVhY2ggcmVhZCBpcyBhbGlnbmVkIHNlcGFyYXRlbHksIGFsaWdubWVudCB0b29scyBtYXkgcHJlZmVyIHRvIGFsaWduIGEgcmVhZCB3aXRoIGEgcmVmZXJlbmNlIG1pc21hdGNoIHJhdGhlciB0aGFuIGNvbnNpZGVyIGFuIGluZGVsIHdpdGhpbiBhIHJlYWQuIEhvd2V2ZXIsIHRha2luZyBhbGwgcmVhZHMgaW50byBjb25zaWRlcmF0aW9uIGFyb3VuZCBhIGxvY3VzIG1heSByZXZlYWwgdGhlIHByZXNlbmNlIG9mIGFuIGluZGVsIGFuZCBwcmV2ZW50IFNOVnMgYmVpbmcgZmFsc2VseSBpZGVudGlmaWVkLgoKKkJlZm9yZSByZWFsaWdubWVudCoKCiFbXShtZWRpYS9pbmRlbF9yZWFsaWduLnBuZykKCipBZnRlciByZWFsaWdubWVudCoKCiFbXShtZWRpYS9pbmRlbF9yZWFsaWduX2FmdGVyLnBuZykKCihzZWUgdGhpcyBbdmlkZW9dKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9Uy1Xa1E1bjBMTFEpIGZvciBhbiBleHBsYW5hdGlvbikKCk5vdyBmb2xsb3cgdGhlIHN0ZXBzIGluIFsiTWFwcGVkIFJlYWRzIHBvc3Rwcm9jZXNzaW5nIl0oaHR0cHM6Ly90cmFpbmluZy5nYWxheHlwcm9qZWN0Lm9yZy90cmFpbmluZy1tYXRlcmlhbC90b3BpY3MvdmFyaWFudC1hbmFseXNpcy90dXRvcmlhbHMvc29tYXRpYy12YXJpYW50cy90dXRvcmlhbC5odG1sI21hcHBlZC1yZWFkcy1wb3N0cHJvY2Vzc2luZykgZnJvbSB0aGUgZ2FsYXh5IHRyYWluaW5nIHBhZ2UsIGJlZm9yZSBwcm9jZWVkaW5nIHRvIFsiVmFyaWFudCBjYWxsaW5nIGFuZCBjbGFzc2lmaWNhdGlvbiJdKGh0dHBzOi8vdHJhaW5pbmcuZ2FsYXh5cHJvamVjdC5vcmcvdHJhaW5pbmctbWF0ZXJpYWwvdG9waWNzL3ZhcmlhbnQtYW5hbHlzaXMvdHV0b3JpYWxzL3NvbWF0aWMtdmFyaWFudHMvdHV0b3JpYWwuaHRtbCN2YXJpYW50LWFubm90YXRpb24tYW5kLXJlcG9ydGluZykKCgojIFNlY3Rpb24gNzogQW5ub3RhdGlvbgoKIyMgQWJvdXQgdmNmIGZvcm1hdAoKCkluIHRoZSBwcmV2aW91cyBzZWN0aW9uLCB5b3Ugd2lsbCBoYXZlIHByb2R1Y2VkIGEgKnZjZiogZmlsZS4gVGhlIGAudmNmYCBmb3JtYXQgd2FzIGluaXRpYWxseSBkZXZlbG9wZWQgYnkgdGhlIFsxMDAwIEdlbm9tZXMgUHJvamVjdF0oaHR0cDovL3d3dy4xMDAwZ2Vub21lcy5vcmcvd2lraS9BbmFseXNpcy92Y2Y0LjApLCBhbmQgb3duZXJzaGlwIGhhcyBiZWVuIHN1YnNlcXVlbnRseSB0cmFuc2ZlcnJlZCB0byBbR2xvYmFsIEFsbGlhbmNlIGZvciBHZW5vbWljcyBhbmQgSGVhbHRoIERhdGEgV29ya2luZyBncm91cCBmaWxlIGZvcm1hdCB0ZWFtXShodHRwOi8vZ2E0Z2gub3JnLyMvZmlsZWZvcm1hdHMtdGVhbSkuIFRoZSBmb3JtYXQgY2FuIGJlIHVzZWQgdG8gcmVwcmVzZW50IGluZm9ybWF0aW9uIGFib3V0IGFsbCBraW5kcyBvZiBnZW5vbWljIHZhcmlhdGlvbi4gSW4gdGhpcyBzZXNzaW9uIHdlIHdpbGwganVzdCBjb25zaWRlciBTTlZzLgoKV2UgZG9u4oCZdCByZXF1aXJlIGFueSBzcGVjaWFsaXNlZCBzb2Z0d2FyZSB0byBsb29rIGF0IHRoZSBjb250ZW50cyBvZiBhIHZjZiBmaWxlLiBUaGV5IGNhbiBiZSBvcGVuZWQgaW4gYSBib2ctc3RhbmRhcmQgdGV4dCBlZGl0b3IsIGhvd2V2ZXIgeW91ciBsYXB0b3AgbWF5IHRyeSBhbmQgaW50ZXJwcmV0IHRoZSBmaWxlIGFzIGNvbnRhaW5pbmcgY29udGFjdCBpbmZvcm1hdGlvbiAodmlydHVhbCBjb250YWN0IGZpbGUpLgoKSW4gYSBzaW1pbGFyIHZlaW4gdG8gdGhlIGAuYmFtYCBhbmQgYC5zYW1gIGZpbGVzIHdlIHNhdyBlYXJsaWVyLCB0aGUgYC52Y2ZgIGZpbGVzIGNvbnRhaW5zIG1hbnkgbGluZXMgb2YgaGVhZGVyIGluZm9ybWF0aW9uLiBUaGVzZSBkZXNjcmliZSB0aGUgcmVmZXJlbmNlIHNlcXVlbmNlcyBhbmQgdmFyaW91cyBmaWx0ZXJzIHRoYXQgaGF2ZSBiZWVuIGFwcGxpZWQuCgoKYGBgCiMjZmlsZWZvcm1hdD1WQ0Z2NC4yCiMjRklMVEVSPTxJRD1QQVNTLERlc2NyaXB0aW9uPSJBbGwgZmlsdGVycyBwYXNzZWQiPgojI3JlZmVyZW5jZT1yZWYuZmEKIyNjb250aWc9PElEPWNocjUsbGVuZ3RoPTE4MDkxNTI2MD4KIyNjb250aWc9PElEPWNocjEyLGxlbmd0aD0xMzM4NTE4OTU+CiMjY29udGlnPTxJRD1jaHIxNyxsZW5ndGg9ODExOTUyMTA+CiMjRklMVEVSPTxJRD1WYXJDb3VudCxEZXNjcmlwdGlvbj0iRmV3ZXIgdGhhbiA0IHZhcmlhbnQtc3VwcG9ydGluZyByZWFkcyI+CiMjRklMVEVSPTxJRD1WYXJGcmVxLERlc2NyaXB0aW9uPSJWYXJpYW50IGFsbGVsZSBmcmVxdWVuY3kgYmVsb3cgMC4wNSI+CiMjRklMVEVSPTxJRD1WYXJBdmdSTCxEZXNjcmlwdGlvbj0iQXZlcmFnZSBjbGlwcGVkIGxlbmd0aCBvZiB2YXJpYW50LXN1cHBvcnRpbmcgcmVhZHMgPCA5MCI+Ci4uLi4uLgouLi4uLi4KCmBgYAoKQWZ0ZXIgbWFueSBtb3JlIGxpbmVzIG9mIGluZm9ybWF0aW9uLCB3ZSBmaW5hbGx5IGdldCB0byB0aGUgZGV0YWlscyBvZiB0aGUgYWN0dWFsIGNhbGxzIHRoZW1zZXZsZXMuIFRoaXMgcGFydCBvZiB0aGUgZmlsZSBpcyB0YWItZGVsaW1pdGVkOyB3aXRoIDEwIGNvbHVtbnMgZm9yIGV2ZXJ5IGNhbGwuIFRoZSB2Y2Ygc3BlY2lmaWNhdGlvbiBwYWdlIGdpdmVzIGRldGFpbHMgb2Ygd2hhdCBzaG91bGQgYmUgY29udGFpbmVkIGluIGVhY2ggY29sdW1uCgoKU2hvd24gaGVyZSBpcyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhyZWUgY2FsbHMKCmBgYAojQ0hST00JUE9TCUlECVJFRglBTFQJUVVBTAlGSUxURVIJSU5GTwlGT1JNQVQJTk9STUFMCVRVTU9SCmNocjUJMjI1NzY4CS4JRwlDCS4JVmFyUmVhZFBvcwlEUD0yNztTUz0xO1NTQz0wO0dQVj01LjEzNjNlLTE2O1NQVj0xCUdUOkdROkRQOkFEOkFERjpBRFIJMS8xOi46MTY6MCwxNjowLDI6MCwxNAkxLzE6LjoxMTowLDExOjAsMTowLDEwCmNocjUJMjMwOTgwCS4JQQlHCS4JUEFTUwlEUD0xNTc7U1M9MTtTU0M9MDtHUFY9MDtTUFY9MQlHVDpHUTpEUDpBRDpBREY6QURSCTEvMTouOjg4OjAsODg6MCw1MTowLDM3CTEvMTouOjY5OjAsNjk6MCw0NTowLDI0CmNocjUJMjMxMTExCS4JVAlDCS4JUEFTUwlEUD0xMjc7U1M9MTtTU0M9MDtHUFY9MDtTUFY9MQlHVDpHUTpEUDpBRDpBREY6QURSCTEvMTouOjc1OjAsNzU6MCwzOTowLDM2CTEvMTouOjUyOjAsNTI6MCwyNjowLDI2CmBgYAoKVGhlIGZpcnN0IHNldmVuIGNvbHVtbnMgc2hvdWxkIGxvb2sgY29uc2lzdGVudCBhY3Jvc3MgZGlmZmVyZW50IGdlbm90eXBlIGNhbGxlcnMuIFRoZSBjb250ZW50cyBvZiB0aGUgYElORk9gIGFuZCBgRk9STUFUYCBjb2x1bW5zIHdpbGwgZGVwZW5kIG9uIHdoYXQgdmFyaWFudCBjYWxsZXIgaGFzIGJlZW4gdXNlZC4gVGhlIGBJTkZPYCBjb2x1bW4gY29udGFpbnMgbWV0cmljcyBhbmQgb3RoZXIgaW5mb3JtYXRpb24gcmVsYXRlZCB0byBlYWNoIHZhcmlhbnQgY2FsbCBhcyBhIHNldCBvZiBgS0VZPVZBTFVFYCBwYWlycy4gRWFjaCBwYWlyIGlzIHNlcGFyYXRlZCBieSBhIGA7YCBjaGFyYWN0ZXIuCgpUaGUgSU5GTyBmb3IgdGhlIGEgdmFyaWFudCBjYWxsIG1heSByZWFkIGFzOi0KCmBgYApEUD0yNztTUz0xO1NTQz0wO0dQVj01LjEzNjNlLTE2O1NQVj0xCmBgYAoKb3IgCgpgYGAKICAgICAgS2V5ICAgVmFsdWUKRFA9MjcgRFAgICAgMjcKU1M9MSAgU1MgICAgMQpTU0M9MCBTU0MgICAwCkdQVj01LjEuLiBHUFYgICA1LjEzNjNlLTE2ClNQVj0xIFNQViAgIDEKCmBgYAoKVGhlIG1lYW5pbmcgb2YgZWFjaCBrZXkgY2FuIGJlIGRpc2NvdmVyZWQgYnkgbG9va2luZyBhdCB0aGUgaGVhZGVyIGZvciB0aGUgZmlsZS4gZS5nLiBgIyNGT1JNQVQ9PElEPURQLE51bWJlcj0xLFR5cGU9SW50ZWdlcixEZXNjcmlwdGlvbj0iUmVhZCBkZXB0aCI+YC4gU28gdGhpcyB2YXJpYW50IGhhcyBhIHRvdGFsIG9mIDI3IGJhc2VzIGNvdmVyaW5nIGl0LiAKCgpUaGUgZmluYWwgdHdvIGNvbHVtbnMgaW4gdGhlIGZpbGUgZGVzY3JpYmVzIHRoZSBjYWxscyBmb3IgdGhlIE5PUk1BTCBhbmQgVFVNT1VSIHNhbXBsZXMgcmVzcGVjdGl2ZWx5LiBJbiB0aGUgc2FtcGxlIGNvbHVtbiAoYE5PUk1BTGApIGZvciB0aGUgZmlyc3QgdmFyaWFudCB3ZSBzZWUgdGhlIGVudHJ5CgpgYGAKMS8xOi46MTY6MCwxNjowLDI6MCwxNApgYGAKClRoZXNlIGFyZSB2YWx1ZXMgc2VwYXJhdGVkIGJ5IGEgYDpgIGNoYXJhY3RlciBhbmQgdGhleSBhcmUgaW50ZXJwcmV0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgZGljdGF0ZWQgYnkgdGhlIEZPUk1BVCBjb2x1bW47IHdoaWNoIGlzIGBHVDpHUTpEUDpBRDpBREY6QURSYAoKYGBgCiMjRk9STUFUPTxJRD1HVCxOdW1iZXI9MSxUeXBlPVN0cmluZyxEZXNjcmlwdGlvbj1HZW5vdHlwZT4KIyNGT1JNQVQ9PElEPUdRLE51bWJlcj0xLFR5cGU9SW50ZWdlcixEZXNjcmlwdGlvbj0iR2Vub3R5cGUgcXVhbGl0eSI+CiMjRk9STUFUPTxJRD1EUCxOdW1iZXI9MSxUeXBlPUludGVnZXIsRGVzY3JpcHRpb249IlJlYWQgZGVwdGgiPgojI0ZPUk1BVD08SUQ9QUQsTnVtYmVyPVIsVHlwZT1JbnRlZ2VyLERlc2NyaXB0aW9uPSJSZWFkIGRlcHRoIGZvciBlYWNoIGFsbGVsZSI+CiMjRk9STUFUPTxJRD1BREYsTnVtYmVyPVIsVHlwZT1JbnRlZ2VyLERlc2NyaXB0aW9uPSJSZWFkIGRlcHRoIGZvciBlYWNoIGFsbGVsZSBvbiB0aGUgZm9yd2FyZCBzdHJhbmQiPgojI0ZPUk1BVD08SUQ9QURSLE51bWJlcj1SLFR5cGU9SW50ZWdlcixEZXNjcmlwdGlvbj0iUmVhZCBkZXB0aCBmb3IgZWFjaCBhbGxlbGUgb24gdGhlIHJldmVyc2Ugc3RyYW5kIj4KYGBgCgpTbyBmb3IgdGhpcyBwYXJ0aWN1bGFyIHZhcmlhbnQgdGhlcmUgaXMgYSBnZW5vdHlwZSBvZiBgMVwxYCAoSG9tb3p5Z291cyBmb3IgdGhlIGFsdGVybmF0ZSBhbGxlbGUpIGluIHRoZSBub3JtYWwgc2FtcGxlIGFuZCBhIGRlcHRoIG9mIGAxNmAgZXRjLiBUaGUgc2FtZSBnZW5vdHlwZSBpbmZvcm1hdGlvbiBpcyByZXBlYXRlZCBmb3IgdGhlIHR1bW91ci4gRnJvbSB0aGlzIHdlIGNhbiBpbmZlciB3aGV0aGVyIHRoZSB2YXJpYW50IGlzIGxpa2VseSB0byBiZSBzb21hdGljIG9yIG5vdCBhbmQgZ2FpbiBpbnNpZ2h0IGludG8gd2hldGhlciBpdCBpcyBhIHRydWUgdmFyaWFudCBvciBhIGZhbHNlIHBvc2l0aXZlICh3aGljaCB3ZSB3aWxsIGRpc2N1c3MgaW4gZGV0YWlsIGxhdGVyKS4KCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KCioqRGlzY3Vzc2lvbjoqKiBMb2NhdGUgdGhlIGxpbmVzIGluIHRoZSB2Y2YgZmlsZSB0aGF0IHJlbGF0ZSB0byBzb21lIG9mIHRoZSBwb3NpdGlvbnMgdGhhdCB3ZSBsb29rZWQgYXQgcHJldmlvdXNseSBpbiBJR1YuIEhvdyBtYW55IHJlYWRzIGluIHRvdGFsIGNvdmVyIGVhY2ggcG9zaXRpb24/CgotIGBjaHIxNzo0MTI0NDkzNmAKLSBgY2hyMTc6NDEyMTk1MTNgCi0gYGNocjE3OjQxMjM0MzA0YAoKV2hhdCBraW5kIG9mIHZhcmlhbnRzIChHZXJtbGluZSwgU29tYXRpYykgaGF2ZSBiZWVuIGNhbGxlZCBhdCB0aGVzZSBwb3NpdGlvbnM/IAoKWW91IGNhbiBhbHNvIGxvYWQgdGhlIHZjZiBpbnRvIElHViwgd2hpY2ggd2lsbCBkaXNwbGF5IGRldGFpbHMgb2YgZWFjaCB2YXJpYW50IGNhbGwgYWJvdmUgdGhlIGFsaWduZWQgcmVhZHMuCiFbXShtZWRpYS9yZWFkcy13aXRoLXZjZi5wbmcpCgo8L2Rpdj4KCgoKIyMgQW5ub3RhdGluZyB3aXRoIFNOUGVmZgoKQXMgd2UgaGF2ZSBzZWVuIHRoZSBzdGFuZGFyZCB2Y2YgZmlsZSBjb250YWlucyBnZW5vbWUgY29vcmRpbmF0ZXMgZm9yIGVhY2ggdmFyaWFudCwgYnV0IGdpdmVzIG5vIHVzZWZ1bCBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IGdlbmUgKGlmIGFueSkgdGhlIHZhcmlhbnQgbGllcyB3aXRoaW4gb3IgdGhlIHBvdGVudGlhbCBpbXBhY3Qgb2YgdGhlIHZhcmlhbnQuIE9uZSBzdWNoIHRvb2wgZm9yIGFkZGluZyBnZW5vbWljIGluZm9ybWF0aW9uIGlzIFNOUGVmZiB3aGljaCBpcyBkZXNjcmliZWQgaW4gdGhlIEdhbGF4eSB0dXRvcmlhbC4KCi0gW1NlZSBoZXJlXShodHRwczovL3RyYWluaW5nLmdhbGF4eXByb2plY3Qub3JnL3RyYWluaW5nLW1hdGVyaWFsL3RvcGljcy92YXJpYW50LWFuYWx5c2lzL3R1dG9yaWFscy9zb21hdGljLXZhcmlhbnRzL3R1dG9yaWFsLmh0bWwjYWRkaW5nLWFubm90YXRpb25zLXRvLXRoZS1jYWxsZWQtdmFyaWFudHMpOyAqKiJBZGRpbmcgZnVuY3Rpb25hbCBnZW5vbWljIGFubm90YXRpb25zIiBvbmx5KioKClNOUGVmZiB3aWxsIHByb2R1Y2UgYSBtb2RpZmllZCBgdmNmYCBmaWxlIGFuZCBhIEhUTUwgcmVwb3J0LiAKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LXdhcm5pbmciPgoKKipEaXNjdXNzaW9uOioqIFNjcm9sbCB0aHJvdWdoIHRoZSBjb250ZW50cyBvZiB0aGUgdmNmIGZpbGUgcHJvZHVjZWQgYnkgc25wZWZmLiBXaGF0IGV4dHJhIGluZm9ybWF0aW9uIGhhcyBpdCBhZGRlZD8gVHJ5IGFuZCBsb2NhdGUgdGhlIHZhcmlhbnRzIHdpdGhpbiBgQlJDQTFgLiBBbHNvIHRha2Ugc29tZSB0aW1lIHRvIGRpZ2VzdCB0aGUgY29udGVudHMgb2YgdGhlIEhUTUwgcmVwb3J0IGFuZCB0aGUgaW5mb3JtYXRpb24gaXQgcHJvdmlkZXMKCjwvZGl2PgoKCgojIyBBbm5vdGF0aW9uIHdpdGggRW5zZW1ibCBWRVAKCkEgdXNlZnVsIGFsdGVybmF0aXZlIHRvIHJ1bm5pbmcgU05QZWZmIHdpdGhpbiBHYWxheHkgaXMgdGhlIG9ubGluZSBWRVAgdG9vbCBwcm92aWRlZCBieSBFbnNlbWJsLiBUaGlzIHdpbGwgYW5ub3RhdGUgb3VyIHZhcmlhbnRzIHdpdGggZ2VuZSBpZGVudGlmaWVycyBhbmQgYWxzbyBwcm92aWRlIHNvbWUgcHJlZGljdGlvbnMgYWJvdXQgdGhlIGltcGFjdCBvZiB0aGUgdmFyaWFudC4gCgpNb3JlIGRvY3VtZW50YXRpb24gb24gRW5zZW1ibCBWRVAgaXMgW2F2YWlsYWJsZSBvbmxpbmVdKGh0dHA6Ly9ncmNoMzcuZW5zZW1ibC5vcmcvaW5mby9kb2NzL3Rvb2xzL3ZlcC9vbmxpbmUvaW5kZXguaHRtbCkKCkNvbW1hbmQgbGluZSB0b29scyBhcmUgYXZhaWxhYmxlLCBidXQgd2Ugd2lsbCB1c2UgdGhlIG9ubGluZSBpbnRlcmZhY2U7IG1ha2luZyBzdXJlIHRoYXQgd2UgYWNjZXNzIHRoZSB2ZXJzaW9uIG9mIFZFUCB3aXRoIHRoZSBjb3JyZWN0IGdlbm9tZSB2ZXJzaW9uLiBHb2luZyBzdHJhaWdodCB0byB0aGUgRW5zZW1ibCBWRVAgd2Vic2l0ZSB3aWxsIG1lYW4gdXNpbmcgYSBsYXRlciBnZW5vbWUgYnVpbGQuCgpUaGUgKipoZzE5KiogdmVyc2lvbiBvZiBWRVAgY2FuIGJlIGFjY2Vzc2VkIFtoZXJlXShodHRwOi8vZ3JjaDM3LmVuc2VtYmwub3JnL0hvbW9fc2FwaWVucy9Ub29scy9WRVApLiBBIHNldCBvZiBjb29yZGluYXRlcyBjYW4gYmUgZW50ZXJlZCBpbnRvIHRoZSB0ZXh0IGJveCwgb3IgYSBWQ0YgZmlsZSBjYW4gYmUgdXBsb2FkZWQuCgohW10obWVkaWEvdmVwLXVwbG9hZC5wbmcpCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KVXBsb2FkIHRoZSBgdmNmYCBmaWxlIHRoYXQgeW91IGFubm90YXRlZCB3aXRoIFNOUGVmZi4gSWYgeW91IHdlcmUgdW5hYmxlIHRvIGNvbXBsZXRlIHRoaXMgc3RlcCwgYSBjb3B5IGlzIGF2YWlsYWJsZSBpbiB0aGUgZ29vZ2xlIGRyaXZlOyBgMjMxMzM1XzIzMTMzNl9WYXJTY2FuX1ZhcmlhbnRzX1NucEVmZl9TUzIudmNmYC4KPC9kaXY+CgpZb3Ugd2lsbCBoYXZlIGEgY2hvaWNlIGFib3V0IHdoYXQgdHJhbnNjcmlwdCBkYXRhYmFzZSB0byB1c2UuIFRoZSBvdXRwdXQgY2FuIGFsc28gYmUgY29uZmlndXJlZCBieSBjbGlja2luZyB0aGUgKisqIHN5bWJvbCBuZXh0IHRvIGEgcGFydGljdWxhciBzZWN0aW9uLiBlLmcuICpWYXJpYW50cyBhbmQgZnJlcXVlbmN5IGRhdGEqLiBBZnRlciBzZWxlY3RpbmcgdGhlIG9wdGlvbnMgeW91IHdhbnQsIHNjcm9sbCBkb3duIHRvIHRoZSBib3R0b20gb2YgdGhlIHBhZ2UgYW5kIGNsaWNrICoqUnVuKiouIFRoZSBzY3JlZW4gc2hvdWxkIG5vdyBjaGFuZ2UgdG8gbGV0IHlvdSBrbm93IHRoYXQgVkVQIGlzIHJ1bm5pbmcuCgohW10obWVkaWEvdmVwLXJ1bm5pbmcucG5nKQoKVGhlIHNjcmVlbiB3aWxsIHJlZnJlc2ggYnkgaXRzZWxmLCBhbmQgZXZlbnR1YWxseSBhIGdyZWVuICpEb25lKiBib3ggc2hvdWxkIGFwcGVhci4gQXQgd2hpY2ggcG9pbnQgeW91IHdpbGwgYmUgYWJsZSB0byBpbnNwZWN0IHRoZSByZXN1bHRzCgohW10obWVkaWEvdmVwLWZpbmlzaGVkLnBuZykKClRoZSByZXN1bHRzIGNhbiBiZSBpbnNwZWN0ZWQgb25saW5lLCBvciBkb3dubG9hZGVkLiBEb3dubG9hZGluZyBhcyBhIHRleHQgZmlsZSBpcyBiZXR0ZXIgZm9yIGJyb3dzaW5nIGluIEV4Y2VsLCBhbmQgY2FuIGFsc28gYmUgbWFuaXB1bGF0ZWQgaW4gbGFuZ3VhZ2VzIHN1Y2ggYXMgUi4KCiMjIEFzc2Vzc21lbnQgb2YgU29tYXRpYyBjYWxscwoKW0NsaWNrIGhlcmVdKHNvbWF0aWNfc252X2Fzc2Vzc21lbnRfZXhlcmNpc2UuaHRtbCkgdG8gZm9sbG93IGFuIGV4ZXJjaXNlIG9uIGluc3BlY3RpbmcgYW5kIGV2YWx1YXRpbmcgc29tYXRpYyBjYWxscwo=