Sydney Tobis, 831694209
1. The General Structure of an R Notebook
R Notebook files (*.Rmd) allow you to combine text elements with
snippets of code and the outputs generated from said code. There are
three main parts to an R Notebook file, which are introduced in this
section. In addition, each R Notebook automatically generates an *.html
file that provides you with the formatted document including all
components, which you will ultimately submit for your homework.
1.2. Code Chunks
R code chunks are delineated with three ticks (''') at
the beginning and the end, and {r} after the first set of
ticks lets your computer know that you will be using the R programming
language. You can always add a code chunk by clicking “Insert > Code
Chunk > R” above or by clicking the “+C” icon, although we usually
already created all the chunks you will need in the template. Any text
within a code chunk, if written correctly, represents executable code,
which the computer can interpret as a command to perform certain tasks.
You can make your computer execute the code in a chunk by pressing the
small, green play arrow on the top right corner of each chunk, or you
can just highlight the code and press command+enter (control+enter on
PC). When you execute the code, the output will automatically appear
below a chunk. Sometimes you will find us using hash tags
(#) within code chunks. Hash tags “silence” the text that
follows on the same line, such that the computer jumps over that section
when executing the code. That is useful for code annotation, and you
will frequently see us using the hash tags to add further descriptions
or explanations within code chunks.
Pro tip: If you want to execute all code chunks in a document
automatically, you can click “Run > Run All” in the RStudio menu.
1.3. Text
The text in between code snippets is just that: text. We will use
these sections to provide you with background information and discussion
prompts, and you will use these sections to respond to questions and
offer your interpretations of data. Sections where you need to write
something are always highlighted in italics. You can use a
variety of prompts to format your text if you are working with basic
Markdown (see here
for a cheat sheet). Most of you, however, will prefer the text editor
that is implemented in R Studio to format text with the click of a
button.
Pro tip: You can toggle back and forth between source code (with
Markdown formatting) and the WYSIWYG editor (with text formatting
through clicking) by using the Source/Visual buttons in the RStudio
menu
1.4. HTML Preview and Output
As already mentioned, your R Notebook (including text, code chunks,
and the outputs from your code) can be automatically knitted into an
*.html file. You can click “Preview > Preview Notebook” or “Preview
> Knit to HTML” to see the live html version as you are working on
your R Notebook (just make sure to save to update), and you can find the
shareable *.html file in the same folder as your *.Rmd file (same file
name with .nb appended).
Note: Sometime R will prompt you to update some packages in the
Console before you can knit the html file. If it is not working on the
first try, make sure to check for prompts in the Console.
2. Getting Started
2.1. Setting Your Working Directory
Having a well-organized file structure is critical to avoid issues
with coding, because you will frequently read in data files, and you
need to make sure that R knows where to look for those files. To
facilitate this process, we will provide you with all the necessary
files in a zipped folder (if you are working through this, you have
already found the first file). We recommend that you move that *.zip
file to the location where you want it (e.g., your folder for this
course) before unzipping.
The folder containing the files for a particular exercise is called a
“Working Directory”, and opening an *.Rmd file automatically sets the
working directory to the directory of that R Notebook file. So after
unzipping, it is important not to move any files out of the folder we
provide you with, unless you want to manually tell R where to look for
readable files. If so, you can use the setwd() command to
point R toward the location of your files (see
textbook for details).
2.2. Loading Your Libraries
When you install R, your computer can understand and execute a number
of commands. This is what is known as “Base R”. The power of R, however,
is that you can expand the number of commands your computer understands
by installing and loading additional R packages (also called libraries).
There are R packages specialized for pretty much any area of biology,
providing the capability to analyze data from the level of genes and
genomes to ecosystem level processes. We will frequently use a package
called ggplot2, which allows for plotting data. Depending
on the module, you will need to install additional libraries. To
download and install new R packages, go to “Tools > Install
Packages…” and type in the name of the package you want to install.
Alternatively, you can use the install.packages() function.
Fore example, execute the following code chunk to install
ggplot2:
Note that you only need to install every package once (unless you
reinstall R). I recommend deleting the code chunk above after you run it
successfully, or you can silence it by a hash tag in the beginning of
install.packages("ggplot2"). Failure to do so can cause
problems during the export (knitting) of your R Notebook as an *.html
file.
To make use of installed packages, you also need to load the packages
every time you use R (i.e., every time you restart the
program). You can do this with the library() command, and
you will find a code snippet prompting you to load all needed libraries
at the beginning of each R Notebook (in a section that is typically
called dependencies). You can try it here by executing the code chunk
below to load ggplot2:
2.3. Importing Data
One of the reasons we’re working through the coding basics here is of
course that you will work with actual data. To do that, you will need to
import data into R. With every exercise, we will provide you with one or
more data sets. These data sets will mostly come as *.csv files (which
stands for comma-separated values). They are essentially text files
containing data tables, and you can also open these files in Excel or
other programs. To import data, we will use the read.csv()
function. In the code chunk below, you can import a simple test data set
(“test_data.csv”) that includes the variables sex, length, and mass for
a population of an animal. Note that the fileEncoding
argument simply indicates that I generated the input files on a Mac,
which will prevent some import issues for those of you that use a
PC.
If this worked correctly, you should now see this data set as
test.data in your global environment (top right panel). You
can double click it to view it. There should be three columns: sex,
length, and mass.
4. Your First Data Set: Darwin’s Finches
One of the most iconic study systems in evolutionary biology are
Darwin’s finches on the Galapagos Islands. Rosemary and Peter Grant
spent much of their lives devoted to the study of these bird, examining
how their traits change in response to major ecological perturbations.
To do so, they collected a massive, long-term data set on different
traits of the medium ground finch (Geospiza fortis) population
on Daphne Major Island. For this exercise, we will take a look at their
beak size data from 1972-1994.

4.1. Import data
The beak size data can be found in file called “finches.csv”. The
file includes three variables: year, the average relative beak size
(rel.beak.size), and the standard error (st.err) that describes the
variability of beak size in any given year.
4.2. Plotting the Data
The following code chunk provides the base code to make a scatter
plot as above. You will only have to specify the x and y variables and
label the axes correctly.
4.3. Adding Additional Graphical Elements
There are two graphical elements that we can add to facilitate the
interpretation of the data:
- Since this is a time series, it makes sense to connect the dots
representing the means from year to year. You can do this by simply
adding another geom:
geom_line().
- We want to know how much the average beak size changes relative to
the variability in the population. If variability is high, year to year
variation in may be negligible. But if variability is low, changes
across year may actually be substantial. You can do this by adding
another geom:
geom_errorbar(). Make sure to specify the x
and y axes variables as above
4.4. Interpretation
4.4.1. General patterns
Based on the graphs you just made, what do you observe? How do you
interpret the data if I told you that 1977 was a massive drought
year?
The beaks were the smallest in 1975, then after 1977 the beak sizes
stayed pretty consistent. If 1977 was a massive drought year, the
average relative beak size must have increased because they were eating
things that would provide them with water. Because this was outside of
their normal diet, it could have increased their beak size.
4.4.2. Evolution… or Not?
Do you think these data reflect evolutionary change through time?
What is a potential alternative explanation? What additional information
would you need to either accept or reject the hypothesis that these
patterns reflect evolutionary change?
The data could also reflect a parent generation passing down their
beak size that they generated during their lifetime. The relative beak
size change is seems rapid in the graph, so that could be an
explanation. To prove that it is evolutionary change, I would want to
see the relative beak size of different generations.
5. Resources
5.1. Data References
Data on beak size variation in Darwin’s finches came from the
following publication:
5.2 Resources You Consulted
Consulting additional resources to solve this assignment is
absolutely allowed, but failure to disclose those resources is
plagiarism. Please list any collaborators you worked with and resources
you used below or state that you have not used any.
I have not used any additional resources
LS0tCnRpdGxlOiAiQW4gSW50cm9kdWN0aW9uIHRvIFIgTm90ZWJvb2tzIGFuZCBFdmlkZW5jZSBmb3IgRXZvbHV0aW9uIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCiAgaHRtbF9kb2N1bWVudDoKICAgIGtlZXBfbWQ6IFRSVUUKLS0tCgojIyBTeWRuZXkgVG9iaXMsIDgzMTY5NDIwOQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIDEuIFRoZSBHZW5lcmFsIFN0cnVjdHVyZSBvZiBhbiBSIE5vdGVib29rCgpSIE5vdGVib29rIGZpbGVzIChcKi5SbWQpIGFsbG93IHlvdSB0byBjb21iaW5lIHRleHQgZWxlbWVudHMgd2l0aCBzbmlwcGV0cyBvZiBjb2RlIGFuZCB0aGUgb3V0cHV0cyBnZW5lcmF0ZWQgZnJvbSBzYWlkIGNvZGUuIFRoZXJlIGFyZSB0aHJlZSBtYWluIHBhcnRzIHRvIGFuIFIgTm90ZWJvb2sgZmlsZSwgd2hpY2ggYXJlIGludHJvZHVjZWQgaW4gdGhpcyBzZWN0aW9uLiBJbiBhZGRpdGlvbiwgZWFjaCBSIE5vdGVib29rIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVzIGFuIFwqLmh0bWwgZmlsZSB0aGF0IHByb3ZpZGVzIHlvdSB3aXRoIHRoZSBmb3JtYXR0ZWQgZG9jdW1lbnQgaW5jbHVkaW5nIGFsbCBjb21wb25lbnRzLCB3aGljaCB5b3Ugd2lsbCB1bHRpbWF0ZWx5IHN1Ym1pdCBmb3IgeW91ciBob21ld29yay4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMS4xLiBUaGUgSGVhZGVyCgpUaGUgaGVhZGVyLCB3aGljaCB5b3UgY2FuIHNlZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgZG9jdW1lbnQsIGlzIGRlbGluZWF0ZWQgd2l0aCB0aHJlZSBkYXNoZXMgKGAtLS1gKSBhdCB0aGUgYmVnaW5uaW5nIGFuZCB0aGUgZW5kLiBJdCBpbmNsdWRlcyBzb21lIGNvZGUgdGhhdCBpcyBpbXBvcnRhbnQgZm9yIHRoZSBmb3JtYXR0aW5nIG9mIG91dHB1dCBmaWxlcywgc28gSSB3b3VsZCByZWNvbW1lbmQgbm90IGFsdGVyaW5nIHRoYXQgc2VjdGlvbi4gSW4gZ2VuZXJhbCwgdGhlcmUgc2hvdWxkIGJlIG5vIHJlYXNvbiBmb3IgeW91IHRvIGNoYW5nZSB0aGUgaGVhZGVyIGZvciBhbnkgZXhlcmNpc2VzIGluIHRoaXMgY291cnNlLiBIb3dldmVyLCBpZiB5b3Ugd291bGQgbGlrZSB0byBsZWFybiBtb3JlIGFib3V0IHRoZSBkaWZmZXJlbnQgaGVhZGVyIG9wdGlvbnMsIHlvdSBjYW4gZmluZCBhIGdvb2QgdHV0b3JpYWwgW2hlcmVdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9odG1sLWRvY3VtZW50Lmh0bWwjdGFibGUtb2YtY29udGVudHMpLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyAxLjIuIENvZGUgQ2h1bmtzCgpSIGNvZGUgY2h1bmtzIGFyZSBkZWxpbmVhdGVkIHdpdGggdGhyZWUgdGlja3MgKGAnJydgKSBhdCB0aGUgYmVnaW5uaW5nIGFuZCB0aGUgZW5kLCBhbmQgYHtyfWAgYWZ0ZXIgdGhlIGZpcnN0IHNldCBvZiB0aWNrcyBsZXRzIHlvdXIgY29tcHV0ZXIga25vdyB0aGF0IHlvdSB3aWxsIGJlIHVzaW5nIHRoZSBSIHByb2dyYW1taW5nIGxhbmd1YWdlLiBZb3UgY2FuIGFsd2F5cyBhZGQgYSBjb2RlIGNodW5rIGJ5IGNsaWNraW5nICJJbnNlcnQgXD4gQ29kZSBDaHVuayBcPiBSIiBhYm92ZSBvciBieSBjbGlja2luZyB0aGUgIitDIiBpY29uLCBhbHRob3VnaCB3ZSB1c3VhbGx5IGFscmVhZHkgY3JlYXRlZCBhbGwgdGhlIGNodW5rcyB5b3Ugd2lsbCBuZWVkIGluIHRoZSB0ZW1wbGF0ZS4gQW55IHRleHQgd2l0aGluIGEgY29kZSBjaHVuaywgaWYgd3JpdHRlbiBjb3JyZWN0bHksIHJlcHJlc2VudHMgZXhlY3V0YWJsZSBjb2RlLCB3aGljaCB0aGUgY29tcHV0ZXIgY2FuIGludGVycHJldCBhcyBhIGNvbW1hbmQgdG8gcGVyZm9ybSBjZXJ0YWluIHRhc2tzLiBZb3UgY2FuIG1ha2UgeW91ciBjb21wdXRlciBleGVjdXRlIHRoZSBjb2RlIGluIGEgY2h1bmsgYnkgcHJlc3NpbmcgdGhlIHNtYWxsLCBncmVlbiBwbGF5IGFycm93IG9uIHRoZSB0b3AgcmlnaHQgY29ybmVyIG9mIGVhY2ggY2h1bmssIG9yIHlvdSBjYW4ganVzdCBoaWdobGlnaHQgdGhlIGNvZGUgYW5kIHByZXNzIGNvbW1hbmQrZW50ZXIgKGNvbnRyb2wrZW50ZXIgb24gUEMpLiBXaGVuIHlvdSBleGVjdXRlIHRoZSBjb2RlLCB0aGUgb3V0cHV0IHdpbGwgYXV0b21hdGljYWxseSBhcHBlYXIgYmVsb3cgYSBjaHVuay4gU29tZXRpbWVzIHlvdSB3aWxsIGZpbmQgdXMgdXNpbmcgaGFzaCB0YWdzIChgI2ApIHdpdGhpbiBjb2RlIGNodW5rcy4gSGFzaCB0YWdzICJzaWxlbmNlIiB0aGUgdGV4dCB0aGF0IGZvbGxvd3Mgb24gdGhlIHNhbWUgbGluZSwgc3VjaCB0aGF0IHRoZSBjb21wdXRlciBqdW1wcyBvdmVyIHRoYXQgc2VjdGlvbiB3aGVuIGV4ZWN1dGluZyB0aGUgY29kZS4gVGhhdCBpcyB1c2VmdWwgZm9yIGNvZGUgYW5ub3RhdGlvbiwgYW5kIHlvdSB3aWxsIGZyZXF1ZW50bHkgc2VlIHVzIHVzaW5nIHRoZSBoYXNoIHRhZ3MgdG8gYWRkIGZ1cnRoZXIgZGVzY3JpcHRpb25zIG9yIGV4cGxhbmF0aW9ucyB3aXRoaW4gY29kZSBjaHVua3MuCgpQcm8gdGlwOiBJZiB5b3Ugd2FudCB0byBleGVjdXRlIGFsbCBjb2RlIGNodW5rcyBpbiBhIGRvY3VtZW50IGF1dG9tYXRpY2FsbHksIHlvdSBjYW4gY2xpY2sgIlJ1biBcPiBSdW4gQWxsIiBpbiB0aGUgUlN0dWRpbyBtZW51LgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyAxLjMuIFRleHQKClRoZSB0ZXh0IGluIGJldHdlZW4gY29kZSBzbmlwcGV0cyBpcyBqdXN0IHRoYXQ6IHRleHQuIFdlIHdpbGwgdXNlIHRoZXNlIHNlY3Rpb25zIHRvIHByb3ZpZGUgeW91IHdpdGggYmFja2dyb3VuZCBpbmZvcm1hdGlvbiBhbmQgZGlzY3Vzc2lvbiBwcm9tcHRzLCBhbmQgeW91IHdpbGwgdXNlIHRoZXNlIHNlY3Rpb25zIHRvIHJlc3BvbmQgdG8gcXVlc3Rpb25zIGFuZCBvZmZlciB5b3VyIGludGVycHJldGF0aW9ucyBvZiBkYXRhLiBTZWN0aW9ucyB3aGVyZSB5b3UgbmVlZCB0byB3cml0ZSBzb21ldGhpbmcgYXJlIGFsd2F5cyBoaWdobGlnaHRlZCBpbiAqaXRhbGljcyouIFlvdSBjYW4gdXNlIGEgdmFyaWV0eSBvZiBwcm9tcHRzIHRvIGZvcm1hdCB5b3VyIHRleHQgaWYgeW91IGFyZSB3b3JraW5nIHdpdGggYmFzaWMgTWFya2Rvd24gKHNlZSBbaGVyZV0oaHR0cHM6Ly9yc3R1ZGlvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNS8wMi9ybWFya2Rvd24tY2hlYXRzaGVldC5wZGYpIGZvciBhIGNoZWF0IHNoZWV0KS4gTW9zdCBvZiB5b3UsIGhvd2V2ZXIsIHdpbGwgcHJlZmVyIHRoZSB0ZXh0IGVkaXRvciB0aGF0IGlzIGltcGxlbWVudGVkIGluIFIgU3R1ZGlvIHRvIGZvcm1hdCB0ZXh0IHdpdGggdGhlIGNsaWNrIG9mIGEgYnV0dG9uLgoKUHJvIHRpcDogWW91IGNhbiB0b2dnbGUgYmFjayBhbmQgZm9ydGggYmV0d2VlbiBzb3VyY2UgY29kZSAod2l0aCBNYXJrZG93biBmb3JtYXR0aW5nKSBhbmQgdGhlIFdZU0lXWUcgZWRpdG9yICh3aXRoIHRleHQgZm9ybWF0dGluZyB0aHJvdWdoIGNsaWNraW5nKSBieSB1c2luZyB0aGUgU291cmNlL1Zpc3VhbCBidXR0b25zIGluIHRoZSBSU3R1ZGlvIG1lbnUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMS40LiBIVE1MIFByZXZpZXcgYW5kIE91dHB1dAoKQXMgYWxyZWFkeSBtZW50aW9uZWQsIHlvdXIgUiBOb3RlYm9vayAoaW5jbHVkaW5nIHRleHQsIGNvZGUgY2h1bmtzLCBhbmQgdGhlIG91dHB1dHMgZnJvbSB5b3VyIGNvZGUpIGNhbiBiZSBhdXRvbWF0aWNhbGx5IGtuaXR0ZWQgaW50byBhbiBcKi5odG1sIGZpbGUuIFlvdSBjYW4gY2xpY2sgIlByZXZpZXcgXD4gUHJldmlldyBOb3RlYm9vayIgb3IgIlByZXZpZXcgXD4gS25pdCB0byBIVE1MIiB0byBzZWUgdGhlIGxpdmUgaHRtbCB2ZXJzaW9uIGFzIHlvdSBhcmUgd29ya2luZyBvbiB5b3VyIFIgTm90ZWJvb2sgKGp1c3QgbWFrZSBzdXJlIHRvIHNhdmUgdG8gdXBkYXRlKSwgYW5kIHlvdSBjYW4gZmluZCB0aGUgc2hhcmVhYmxlIFwqLmh0bWwgZmlsZSBpbiB0aGUgc2FtZSBmb2xkZXIgYXMgeW91ciBcKi5SbWQgZmlsZSAoc2FtZSBmaWxlIG5hbWUgd2l0aCAubmIgYXBwZW5kZWQpLgoKTm90ZTogU29tZXRpbWUgUiB3aWxsIHByb21wdCB5b3UgdG8gdXBkYXRlIHNvbWUgcGFja2FnZXMgaW4gdGhlIENvbnNvbGUgYmVmb3JlIHlvdSBjYW4ga25pdCB0aGUgaHRtbCBmaWxlLiBJZiBpdCBpcyBub3Qgd29ya2luZyBvbiB0aGUgZmlyc3QgdHJ5LCBtYWtlIHN1cmUgdG8gY2hlY2sgZm9yIHByb21wdHMgaW4gdGhlIENvbnNvbGUuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgMi4gR2V0dGluZyBTdGFydGVkCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDIuMS4gU2V0dGluZyBZb3VyIFdvcmtpbmcgRGlyZWN0b3J5CgpIYXZpbmcgYSB3ZWxsLW9yZ2FuaXplZCBmaWxlIHN0cnVjdHVyZSBpcyBjcml0aWNhbCB0byBhdm9pZCBpc3N1ZXMgd2l0aCBjb2RpbmcsIGJlY2F1c2UgeW91IHdpbGwgZnJlcXVlbnRseSByZWFkIGluIGRhdGEgZmlsZXMsIGFuZCB5b3UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCBSIGtub3dzIHdoZXJlIHRvIGxvb2sgZm9yIHRob3NlIGZpbGVzLiBUbyBmYWNpbGl0YXRlIHRoaXMgcHJvY2Vzcywgd2Ugd2lsbCBwcm92aWRlIHlvdSB3aXRoIGFsbCB0aGUgbmVjZXNzYXJ5IGZpbGVzIGluIGEgemlwcGVkIGZvbGRlciAoaWYgeW91IGFyZSB3b3JraW5nIHRocm91Z2ggdGhpcywgeW91IGhhdmUgYWxyZWFkeSBmb3VuZCB0aGUgZmlyc3QgZmlsZSkuIFdlIHJlY29tbWVuZCB0aGF0IHlvdSBtb3ZlIHRoYXQgXCouemlwIGZpbGUgdG8gdGhlIGxvY2F0aW9uIHdoZXJlIHlvdSB3YW50IGl0IChlLmcuLCB5b3VyIGZvbGRlciBmb3IgdGhpcyBjb3Vyc2UpIGJlZm9yZSB1bnppcHBpbmcuCgpUaGUgZm9sZGVyIGNvbnRhaW5pbmcgdGhlIGZpbGVzIGZvciBhIHBhcnRpY3VsYXIgZXhlcmNpc2UgaXMgY2FsbGVkIGEgIldvcmtpbmcgRGlyZWN0b3J5IiwgYW5kIG9wZW5pbmcgYW4gXCouUm1kIGZpbGUgYXV0b21hdGljYWxseSBzZXRzIHRoZSB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgZGlyZWN0b3J5IG9mIHRoYXQgUiBOb3RlYm9vayBmaWxlLiBTbyBhZnRlciB1bnppcHBpbmcsIGl0IGlzIGltcG9ydGFudCBub3QgdG8gbW92ZSBhbnkgZmlsZXMgb3V0IG9mIHRoZSBmb2xkZXIgd2UgcHJvdmlkZSB5b3Ugd2l0aCwgdW5sZXNzIHlvdSB3YW50IHRvIG1hbnVhbGx5IHRlbGwgUiB3aGVyZSB0byBsb29rIGZvciByZWFkYWJsZSBmaWxlcy4gSWYgc28sIHlvdSBjYW4gdXNlIHRoZSBgc2V0d2QoKWAgY29tbWFuZCB0byBwb2ludCBSIHRvd2FyZCB0aGUgbG9jYXRpb24gb2YgeW91ciBmaWxlcyAoW3NlZSB0ZXh0Ym9vayBmb3IgZGV0YWlsc10oaHR0cHM6Ly93d3cuay1zdGF0ZS5lZHUvYmlvbG9neS9wMmUvZXZpZGVuY2UtZm9yLWV2b2x1dGlvbi5odG1sI2ltcG9ydC1kYXRhKSkuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDIuMi4gTG9hZGluZyBZb3VyIExpYnJhcmllcwoKV2hlbiB5b3UgaW5zdGFsbCBSLCB5b3VyIGNvbXB1dGVyIGNhbiB1bmRlcnN0YW5kIGFuZCBleGVjdXRlIGEgbnVtYmVyIG9mIGNvbW1hbmRzLiBUaGlzIGlzIHdoYXQgaXMga25vd24gYXMgIkJhc2UgUiIuIFRoZSBwb3dlciBvZiBSLCBob3dldmVyLCBpcyB0aGF0IHlvdSBjYW4gZXhwYW5kIHRoZSBudW1iZXIgb2YgY29tbWFuZHMgeW91ciBjb21wdXRlciB1bmRlcnN0YW5kcyBieSBpbnN0YWxsaW5nIGFuZCBsb2FkaW5nIGFkZGl0aW9uYWwgUiBwYWNrYWdlcyAoYWxzbyBjYWxsZWQgbGlicmFyaWVzKS4gVGhlcmUgYXJlIFIgcGFja2FnZXMgc3BlY2lhbGl6ZWQgZm9yIHByZXR0eSBtdWNoIGFueSBhcmVhIG9mIGJpb2xvZ3ksIHByb3ZpZGluZyB0aGUgY2FwYWJpbGl0eSB0byBhbmFseXplIGRhdGEgZnJvbSB0aGUgbGV2ZWwgb2YgZ2VuZXMgYW5kIGdlbm9tZXMgdG8gZWNvc3lzdGVtIGxldmVsIHByb2Nlc3Nlcy4gV2Ugd2lsbCBmcmVxdWVudGx5IHVzZSBhIHBhY2thZ2UgY2FsbGVkIGBnZ3Bsb3QyYCwgd2hpY2ggYWxsb3dzIGZvciBwbG90dGluZyBkYXRhLiBEZXBlbmRpbmcgb24gdGhlIG1vZHVsZSwgeW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIGFkZGl0aW9uYWwgbGlicmFyaWVzLiBUbyBkb3dubG9hZCBhbmQgaW5zdGFsbCBuZXcgUiBwYWNrYWdlcywgZ28gdG8gIlRvb2xzIFw+IEluc3RhbGwgUGFja2FnZXMuLi4iIGFuZCB0eXBlIGluIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHlvdSB3YW50IHRvIGluc3RhbGwuIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gdXNlIHRoZSBgaW5zdGFsbC5wYWNrYWdlcygpYCBmdW5jdGlvbi4gRm9yZSBleGFtcGxlLCBleGVjdXRlIHRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayB0byBpbnN0YWxsIGBnZ3Bsb3QyYDoKCmBgYHtyfQojSW5zdGFsbCBnZ3Bsb3QyCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikKYGBgCgpOb3RlIHRoYXQgeW91IG9ubHkgbmVlZCB0byBpbnN0YWxsIGV2ZXJ5IHBhY2thZ2Ugb25jZSAodW5sZXNzIHlvdSByZWluc3RhbGwgUikuIEkgcmVjb21tZW5kIGRlbGV0aW5nIHRoZSBjb2RlIGNodW5rIGFib3ZlIGFmdGVyIHlvdSBydW4gaXQgc3VjY2Vzc2Z1bGx5LCBvciB5b3UgY2FuIHNpbGVuY2UgaXQgYnkgYSBoYXNoIHRhZyBpbiB0aGUgYmVnaW5uaW5nIG9mIGBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIilgLiBGYWlsdXJlIHRvIGRvIHNvIGNhbiBjYXVzZSBwcm9ibGVtcyBkdXJpbmcgdGhlIGV4cG9ydCAoa25pdHRpbmcpIG9mIHlvdXIgUiBOb3RlYm9vayBhcyBhbiBcKi5odG1sIGZpbGUuCgpUbyBtYWtlIHVzZSBvZiBpbnN0YWxsZWQgcGFja2FnZXMsIHlvdSBhbHNvIG5lZWQgdG8gbG9hZCB0aGUgcGFja2FnZXMgKmV2ZXJ5IHRpbWUqIHlvdSB1c2UgUiAoKmkuZS4qLCBldmVyeSB0aW1lIHlvdSByZXN0YXJ0IHRoZSBwcm9ncmFtKS4gWW91IGNhbiBkbyB0aGlzIHdpdGggdGhlIGBsaWJyYXJ5KClgIGNvbW1hbmQsIGFuZCB5b3Ugd2lsbCBmaW5kIGEgY29kZSBzbmlwcGV0IHByb21wdGluZyB5b3UgdG8gbG9hZCBhbGwgbmVlZGVkIGxpYnJhcmllcyBhdCB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggUiBOb3RlYm9vayAoaW4gYSBzZWN0aW9uIHRoYXQgaXMgdHlwaWNhbGx5IGNhbGxlZCBkZXBlbmRlbmNpZXMpLiBZb3UgY2FuIHRyeSBpdCBoZXJlIGJ5IGV4ZWN1dGluZyB0aGUgY29kZSBjaHVuayBiZWxvdyB0byBsb2FkIGBnZ3Bsb3QyYDoKCmBgYHtyfQojTm90ZSB0aGF0IGxvYWRpbmcgYSBsaWJyYXJ5IGRvZXMgbm90IGxlYWQgdG8gYW4gb3V0cHV0CmxpYnJhcnkoZ2dwbG90MikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDIuMy4gSW1wb3J0aW5nIERhdGEKCk9uZSBvZiB0aGUgcmVhc29ucyB3ZSdyZSB3b3JraW5nIHRocm91Z2ggdGhlIGNvZGluZyBiYXNpY3MgaGVyZSBpcyBvZiBjb3Vyc2UgdGhhdCB5b3Ugd2lsbCB3b3JrIHdpdGggYWN0dWFsIGRhdGEuIFRvIGRvIHRoYXQsIHlvdSB3aWxsIG5lZWQgdG8gaW1wb3J0IGRhdGEgaW50byBSLiBXaXRoIGV2ZXJ5IGV4ZXJjaXNlLCB3ZSB3aWxsIHByb3ZpZGUgeW91IHdpdGggb25lIG9yIG1vcmUgZGF0YSBzZXRzLiBUaGVzZSBkYXRhIHNldHMgd2lsbCBtb3N0bHkgY29tZSBhcyBcKi5jc3YgZmlsZXMgKHdoaWNoIHN0YW5kcyBmb3IgY29tbWEtc2VwYXJhdGVkIHZhbHVlcykuIFRoZXkgYXJlIGVzc2VudGlhbGx5IHRleHQgZmlsZXMgY29udGFpbmluZyBkYXRhIHRhYmxlcywgYW5kIHlvdSBjYW4gYWxzbyBvcGVuIHRoZXNlIGZpbGVzIGluIEV4Y2VsIG9yIG90aGVyIHByb2dyYW1zLiBUbyBpbXBvcnQgZGF0YSwgd2Ugd2lsbCB1c2UgdGhlIGByZWFkLmNzdigpYCBmdW5jdGlvbi4gSW4gdGhlIGNvZGUgY2h1bmsgYmVsb3csIHlvdSBjYW4gaW1wb3J0IGEgc2ltcGxlIHRlc3QgZGF0YSBzZXQgKCJ0ZXN0X2RhdGEuY3N2IikgdGhhdCBpbmNsdWRlcyB0aGUgdmFyaWFibGVzIHNleCwgbGVuZ3RoLCBhbmQgbWFzcyBmb3IgYSBwb3B1bGF0aW9uIG9mIGFuIGFuaW1hbC4gTm90ZSB0aGF0IHRoZSBgZmlsZUVuY29kaW5nYCBhcmd1bWVudCBzaW1wbHkgaW5kaWNhdGVzIHRoYXQgSSBnZW5lcmF0ZWQgdGhlIGlucHV0IGZpbGVzIG9uIGEgTWFjLCB3aGljaCB3aWxsIHByZXZlbnQgc29tZSBpbXBvcnQgaXNzdWVzIGZvciB0aG9zZSBvZiB5b3UgdGhhdCB1c2UgYSBQQy4KCmBgYHtyfQojVGhlIGxpbmUgb2YgY29kZSBzaW1wbHkgcHJvbXB0cyB0aGUgY29tcHV0ZXIgdG8gcmVhZCB0aGUgInRlc3RfZGF0YS5jc3YiIGZpbGUgYW5kIGdlbmVyYXRlIGEgZGF0YS5mcmFtZSBjYWxsZWQgdGVzdC5kYXRhCnRlc3QuZGF0YSA8LSByZWFkLmNzdigiRGVza3RvcC9CSU9MNTIwLWV4MSAyL3Rlc3RfZGF0YS5jc3YiLCBmaWxlRW5jb2RpbmcgPSAnVVRGLTgtQk9NJykKYGBgCgpJZiB0aGlzIHdvcmtlZCBjb3JyZWN0bHksIHlvdSBzaG91bGQgbm93IHNlZSB0aGlzIGRhdGEgc2V0IGFzIGB0ZXN0LmRhdGFgIGluIHlvdXIgZ2xvYmFsIGVudmlyb25tZW50ICh0b3AgcmlnaHQgcGFuZWwpLiBZb3UgY2FuIGRvdWJsZSBjbGljayBpdCB0byB2aWV3IGl0LiBUaGVyZSBzaG91bGQgYmUgdGhyZWUgY29sdW1uczogc2V4LCBsZW5ndGgsIGFuZCBtYXNzLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIDMuIE1ha2luZyBGaWd1cmVzCgpBIGtleSBsZWFybmluZyBvYmplY3RpdmUgb2YgdGhpcyBjb3Vyc2UgaXMgdGhhdCB5b3UgbGVhcm4gdG8gdmlzdWFsaXplIGRhdGEgaW4gZGlmZmVyZW50IHdheXMgdG8gZmFjaWxpdGF0ZSBkYXRhIGludGVycHJldGF0aW9uIGluIHRoZSBjb250ZXh0IG9mIGRpZmZlcmVudCBldm9sdXRpb25hcnkgaHlwb3RoZXNlcy4gSW4gdGhlIGZvbGxvd2luZyBzZWN0aW9ucywgSSB3aWxsIGV4cGxhaW4gc3RlcCBieSBzdGVwICh0aGF0IGlzIGNvZGUgbGluZSBieSBjb2RlIGxpbmUpIGhvdyB0byBtYWtlIGEgc2ltcGxlIGdyYXBoIHdpdGggb3VyIHNhbXBsZSBkYXRhIHNldC4gTGV0J3MgYWltIHRvIG1ha2UgYSBzY2F0dGVyIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbGVuZ3RoIGFuZCBtYXNzIGluIG91ciBzcGVjaWVzLiBUaGUgcHJvY2VzcyBpcyBub3QgbXVjaCBkaWZmZXJlbnQgdGhhbiBza2V0Y2hpbmcgYSBncmFwaCBieSBoYW5kIGFuZCBsYXllcmluZyBkaWZmZXJlbnQgcGFydHMgb2YgdGhlIGdyYXBoIG9uIHRvcCBvZiBlYWNoIG90aGVyLCBqdXN0IHRoYXQgeW91IHVzZSB3b3JkcyAoY29kZSkgdG8gbWFrZSB0aGUgY29tcHV0ZXIgZHJhdy4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMy4xLiBEZWZpbmUgdGhlIEF4ZXMgYW5kIENvb3JkaW5hdGUgU3lzdGVtCgpUaGUgZmlyc3Qgc3RlcCBvZiBtYWtpbmcgYW55IGdyYXBoIGlzIHRvIGRlZmluZSB0aGUgYXhlcyBhbmQgZXN0YWJsaXNoIHRoZSBjb29yZGluYXRlIGdyaWQgdGhhdCBhbGxvd3MgZm9yIHRoZSBwbG90dGluZyBvZiB0aGUgZGF0YS4gWW91IGNhbiBkbyB0aGlzIGJ5IGNhbGxpbmcgdGhlIGBnZ3Bsb3QoKWAgZnVuY3Rpb24gd2l0aGluIHdoaWNoIHlvdSBmaXJzdCBuZWVkIHRvIHNwZWNpZnkgdGhlIGRhdGEgc291cmNlIChpbiBvdXIgY2FzZSB0aGUgZGF0YSBmcmFtZSB3ZSBqdXN0IGNyZWF0ZWQsIGNhbGxlZCBgdGVzdC5kYXRhYCkgYW5kIHRoZW4gdGhlIHNvIGNhbGxlZCBhZXN0aGV0aWNzLS0tYGFlcygpYC0tLXRoYXQgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IHZhcmlhYmxlcyBkZWZpbmUgdGhlIHggYW5kIHkgYXhlcy4gSW4gcHJhY3RpY2UsIHRoaXMgaXMgYWNjb21wbGlzaGVkIHdpdGggdGhlIGZvbGxvd2luZyBsaW5lIG9mIGNvZGU6CgpgYGB7cn0KI1RoaXMgbGluZSBvZiBjb2RlIGNhbGxzIGZvciB0aGUgZ2dwbG90IGZ1bmN0aW9uIChhIHBsb3R0aW5nIGZ1bmN0aW9uKSBhbmQgbWFrZSBhIGdyaWQgYmFzZWQgb24gdGhlIHRlc3QuZGF0YSBkYXRhIGZyYW1lLCB1c2luZyBsZW5ndGggYXMgdGhlIHggYXhpcyBhbmQgbWFzcyBhcyB0aGUgeSBheGlzCmdncGxvdCh0ZXN0X2RhdGEsIGFlcyh4PWxlbmd0aCwgeT1tYXNzKSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDMuMi4gQWRkaW5nIGEgTGF5ZXIgd2l0aCBEYXRhIFBvaW50cwoKVGhlIHNlY29uZCBzdGVwIGlzIHRvIGRyYXcgdGhlIGRhdGEgaW50byB0aGUgZXN0YWJsaXNoZWQgY29vcmRpbmF0ZSBzeXN0ZW0uIFRvIGRvIHNvLCB5b3UganVzdCBuZWVkIHRvIHRlbGwgdGhlIHByb2dyYW0gd2hhdCBraW5kIG9mIGdyYXBoIHlvdSB3YW50IHRvIGRyYXcuIERpZmZlcmVudCBncmFwaCB0eXBlcyBpbiBgZ2dwbG90MmAgYXJlIHJlZmVycmVkIHRvIGFzIGdlb21zIChnZW9tZXRyaWVzKSwgYW5kIGEgc2NhdHRlciBwbG90IGlzIGRlc2lnbmF0ZWQgYXMgYGdlb21fcG9pbnRgLiBZb3UgY2FuIGp1c3QgYWRkIHRoYXQgdG8geW91ciBleGlzdGluZyBjb2RlIHdpdGggYSBwbHVzIHNpZ24uIEZvciBhbiBvdmVydmlldyBvZiBzb21lIG9mIHRoZSBncmFwaCB0eXBlcyAoZ2VvbXMpIGBnZ3Bsb3QyYCBvZmZlcnMsIGNoZWNrIHRoZSBbYXBwZW5kaXhdKGh0dHBzOi8vd3d3Lmstc3RhdGUuZWR1L2Jpb2xvZ3kvcDJlL2dyYXBoLWxpYnJhcnkuaHRtbCkgb2Ygb3VyIHRleHRib29rLgoKYGBge3J9CmdncGxvdCh0ZXN0X2RhdGEsIGFlcyh4PWxlbmd0aCwgeT1tYXNzKSkgKwogIGdlb21fcG9pbnQoKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMy4zLiBBZGRpbmcgYSBUcmVuZGxpbmUKCldoZW5ldmVyIHdlIGxvb2sgYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byB2YXJpYWJsZXMsIHdlIG1heSB3YW50IHRvIGFkZCBhIHRyZW5kbGluZS4gWW91IGNhbiBhZGQgYSB0cmVuZGxpbmUgYnkgYWRkaW5nIHRoZSBgZ2VvbV9zbW9vdGgoKWAgZnVuY3Rpb24gdG8geW91ciBleGlzdGluZyBjb2RlLCBhbmQgYG1ldGhvZD0ibG0iYCBkZXNpZ25hdGVzIHRoYXQgeW91ciB0cmVuZGxpbmUgc2hvdWxkIGJlIGxpbmVhci4gVGhlIGBzZWAgYXJndW1lbnQgZGVzaWduYXRlcyB3aGV0aGVyIG9yIG5vdCB5b3Ugd2FudCB0byBkcmF3IGFuIGVycm9yIGVzdGltYXRlIGFyb3VuZCB5b3VyIHRyZW5kbGluZS4KCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CiNUaGUgY29kZSB3aXRoaW4gdGhlIGJyYWNrZXRzIG9mIHRoZSBnZW9tX3Ntb290aCBjb21tYW5kIHNwZWNpZmllZCBzb21lIGFkZGl0aW9uYWwgb3B0aW9ucywgbmFtZWx5IHRoYXQgd2Ugd2FudCB0byBkcmF3IGEgc3RyYWlnaHQgbGluZSAobWV0aG9kPSJsbSIpIGFuZCB0aGF0IHdlIGRvIG5vdCB3YW50IHRvIHNob3cgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKHNlPUZBTFNFKS4gU2V0IHRoZSBzZT1UUlVFIGFuZCBzZWUgd2hhdCBoYXBwZW5zLgpnZ3Bsb3QodGVzdF9kYXRhLCBhZXMoeD1sZW5ndGgsIHk9bWFzcykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBzZT1GQUxTRSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDMuNC4gQ2hhbmdpbmcgdGhlIEF4ZXMgTGFiZWxzCgpUaGUgdmFyaWFibGUgbmFtZXMgaW4gdGhlIGRhdGEgc2V0IGRvIG5vdCBhbHdheXMgcHJvdmlkZSB0aGUgY2xlYXJlc3QgZGVzY3JpcHRpb24gb2Ygd2hhdCBhIHZhcmlhYmxlIG1lYW5zLiBXZSBjYW4gbW9kaWZ5IHRoZSB4IGFuZCB5IGF4aXMgbGFiZWxzIHVzaW5nIHRoZSBgeGxhYigpYCBhbmQgYHlsYWIoKWAgZnVuY3Rpb25zLCByZXNwZWN0aXZlbHkuIFRoZSBhY3R1YWwgdGl0bGVzIG5lZWQgdG8gYmUgd3JpdHRlbiB3aXRoaW4gcXVvdGF0aW9uIG1hcmtzOgoKYGBge3J9CiNTaW1wbHkgYWRkIHRoZSBuZXcgbGFiZWwgdGV4dCBpbiBxdW90YXRpb24gbWFya3MKZ2dwbG90KHRlc3RfZGF0YSwgYWVzKHg9bGVuZ3RoLCB5PW1hc3MpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgc2U9RkFMU0UpICsKICB4bGFiKCJCb2R5IGxlbmd0aCBpbiBjbSIpICsKICB5bGFiKCJCb2R5IG1hc3MgaW4ga2ciKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMy41LiBDaGFuZ2UgdGhlIFRoZW1lCgpJIGhvbmVzdGx5IGhhdGUgdGhlIGRlZmF1bHQgdGhlbWUgb2YgYGdncGxvdGAgd2l0aCBpdHMgZ3JheSBiYWNrZ3JvdW5kLiBCdXQgeW91IGNhbiBxdWlja2x5IGFsdGVyIHRoZSBsb29rIG9mIHRoZSBncmFwaCBieSBzd2l0Y2hpbmcgdG8gYSBudW1iZXIgb2Ygb3RoZXIgcG9zc2libGUgdGhlbWVzLiBJIHBlcnNvbmFsbHkgbGlrZSB0aGUgYHRoZW1lX2NsYXNzaWMoKWAsIGJ1dCB5b3UgY2FuIGN1c3RvbWl6ZSB0aGUgbG9vayBvZiB5b3VyIGdyYXBoIHdpdGggdGhlbWVzIGxpc3RlZCBbaGVyZV0oaHR0cHM6Ly93d3cuZGF0YW5vdmlhLmNvbS9lbi9ibG9nL2dncGxvdC10aGVtZXMtZ2FsbGVyeS8jYmFzaWMtZ2dwbG90KS4KCmBgYHtyfQpnZ3Bsb3QodGVzdF9kYXRhLCBhZXMoeD1sZW5ndGgsIHk9bWFzcykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBzZT1GQUxTRSkgKwogIHhsYWIoIkJvZHkgbGVuZ3RoIGluIGNtIikgKwogIHlsYWIoIkJvZHkgbWFzcyBpbiBrZyIpICsKICB0aGVtZV9saW5lZHJhdygpCmBgYAoKRXQgdm9pbMOgISBZb3UgZ290IHlvdXJzZWxmIGEgcGVyZmVjdGx5IGdvb2QgZ3JhcGghIEFzIHlvdSBleGVyY2lzZSBidWlsZGluZyBncmFwaHMgdGhyb3VnaG91dCB0aGUgc2VtZXN0ZXIsIG1ha2Ugc3VyZSB0byBjaGVjayB0aGUgIlByYWN0aWNhbCBTa2lsbHMiIHNlY3Rpb25zIG9mIGluZGl2aWR1YWwgY2hhcHRlcnMgcmVmZXIgdG8gdGhlIGFwcGVuZGl4IG9mIHRoZSBib29rIGFzIG5lZWRlZC4KClRvIGdldCBhZGRpdGlvbmFsIGFkdmljZSBvbiBob3cgdG8gd29yayB3aXRoIGRpZmZlcmVudCBjb2xvciBzY2hlbWVzIGluIGBnZ2xvdCgpYCwgaW5jbHVkaW5nIHRoZSB1c2Ugb2YgY29sb3JibGluZC1mcmllbmRseSBwYWxldHRlcywgcGxlYXNlIGNoZWNrIHRoZSBbY29ycmVzcG9uZGluZyB0ZXh0Ym9vayBzZWN0aW9uXShodHRwczovL3d3dy5rLXN0YXRlLmVkdS9iaW9sb2d5L3AyZS9ldmlkZW5jZS1mb3ItZXZvbHV0aW9uLmh0bWwjZ3JhcGhpbmctZGF0YSkuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgNC4gWW91ciBGaXJzdCBEYXRhIFNldDogRGFyd2luJ3MgRmluY2hlcwoKT25lIG9mIHRoZSBtb3N0IGljb25pYyBzdHVkeSBzeXN0ZW1zIGluIGV2b2x1dGlvbmFyeSBiaW9sb2d5IGFyZSBEYXJ3aW4ncyBmaW5jaGVzIG9uIHRoZSBHYWxhcGFnb3MgSXNsYW5kcy4gUm9zZW1hcnkgYW5kIFBldGVyIEdyYW50IHNwZW50IG11Y2ggb2YgdGhlaXIgbGl2ZXMgZGV2b3RlZCB0byB0aGUgc3R1ZHkgb2YgdGhlc2UgYmlyZCwgZXhhbWluaW5nIGhvdyB0aGVpciB0cmFpdHMgY2hhbmdlIGluIHJlc3BvbnNlIHRvIG1ham9yIGVjb2xvZ2ljYWwgcGVydHVyYmF0aW9ucy4gVG8gZG8gc28sIHRoZXkgY29sbGVjdGVkIGEgbWFzc2l2ZSwgbG9uZy10ZXJtIGRhdGEgc2V0IG9uIGRpZmZlcmVudCB0cmFpdHMgb2YgdGhlIG1lZGl1bSBncm91bmQgZmluY2ggKCpHZW9zcGl6YSBmb3J0aXMqKSBwb3B1bGF0aW9uIG9uIERhcGhuZSBNYWpvciBJc2xhbmQuIEZvciB0aGlzIGV4ZXJjaXNlLCB3ZSB3aWxsIHRha2UgYSBsb29rIGF0IHRoZWlyIGJlYWsgc2l6ZSBkYXRhIGZyb20gMTk3Mi0xOTk0LgoKIVtdKGZpbmNoLmpwZykKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgNC4xLiBJbXBvcnQgZGF0YQoKVGhlIGJlYWsgc2l6ZSBkYXRhIGNhbiBiZSBmb3VuZCBpbiBmaWxlIGNhbGxlZCAiZmluY2hlcy5jc3YiLiBUaGUgZmlsZSBpbmNsdWRlcyB0aHJlZSB2YXJpYWJsZXM6IHllYXIsIHRoZSBhdmVyYWdlIHJlbGF0aXZlIGJlYWsgc2l6ZSAocmVsLmJlYWsuc2l6ZSksIGFuZCB0aGUgc3RhbmRhcmQgZXJyb3IgKHN0LmVycikgdGhhdCBkZXNjcmliZXMgdGhlIHZhcmlhYmlsaXR5IG9mIGJlYWsgc2l6ZSBpbiBhbnkgZ2l2ZW4geWVhci4KCmBgYHtyfQpmaW5jaGVzIDwtIHJlYWQuY3N2KCJEZXNrdG9wL0JJT0w1MjAtZXgxIDIvZmluY2hlcy5jc3YiLCBmaWxlRW5jb2RpbmcgPSAiVVRGLTgtQk9NJykKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDQuMi4gUGxvdHRpbmcgdGhlIERhdGEKClRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayBwcm92aWRlcyB0aGUgYmFzZSBjb2RlIHRvIG1ha2UgYSBzY2F0dGVyIHBsb3QgYXMgYWJvdmUuIFlvdSB3aWxsIG9ubHkgaGF2ZSB0byBzcGVjaWZ5IHRoZSB4IGFuZCB5IHZhcmlhYmxlcyBhbmQgbGFiZWwgdGhlIGF4ZXMgY29ycmVjdGx5LgoKYGBge3J9CmdncGxvdChmaW5jaGVzLCBhZXMoeD15ZWFyLCB5PXJlbC5iZWFrLnNpemUpKSArCiAgZ2VvbV9wb2ludCgpICsKICB4bGFiKCJ5ZWFyIikgKwogIHlsYWIoInJlbC5iZWFrLnNpemUiKSArCiAgdGhlbWVfY2xhc3NpYygpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA0LjMuIEFkZGluZyBBZGRpdGlvbmFsIEdyYXBoaWNhbCBFbGVtZW50cwoKVGhlcmUgYXJlIHR3byBncmFwaGljYWwgZWxlbWVudHMgdGhhdCB3ZSBjYW4gYWRkIHRvIGZhY2lsaXRhdGUgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBkYXRhOgoKMS4gIFNpbmNlIHRoaXMgaXMgYSB0aW1lIHNlcmllcywgaXQgbWFrZXMgc2Vuc2UgdG8gY29ubmVjdCB0aGUgZG90cyByZXByZXNlbnRpbmcgdGhlIG1lYW5zIGZyb20geWVhciB0byB5ZWFyLiBZb3UgY2FuIGRvIHRoaXMgYnkgc2ltcGx5IGFkZGluZyBhbm90aGVyIGdlb206IGBnZW9tX2xpbmUoKWAuCjIuICBXZSB3YW50IHRvIGtub3cgaG93IG11Y2ggdGhlIGF2ZXJhZ2UgYmVhayBzaXplIGNoYW5nZXMgcmVsYXRpdmUgdG8gdGhlIHZhcmlhYmlsaXR5IGluIHRoZSBwb3B1bGF0aW9uLiBJZiB2YXJpYWJpbGl0eSBpcyBoaWdoLCB5ZWFyIHRvIHllYXIgdmFyaWF0aW9uIGluIG1heSBiZSBuZWdsaWdpYmxlLiBCdXQgaWYgdmFyaWFiaWxpdHkgaXMgbG93LCBjaGFuZ2VzIGFjcm9zcyB5ZWFyIG1heSBhY3R1YWxseSBiZSBzdWJzdGFudGlhbC4gWW91IGNhbiBkbyB0aGlzIGJ5IGFkZGluZyBhbm90aGVyIGdlb206IGBnZW9tX2Vycm9yYmFyKClgLiBNYWtlIHN1cmUgdG8gc3BlY2lmeSB0aGUgeCBhbmQgeSBheGVzIHZhcmlhYmxlcyBhcyBhYm92ZQoKYGBge3J9CmdncGxvdChmaW5jaGVzLCBhZXMoeD15ZWFyLCB5PXJlbC5iZWFrLnNpemUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1yZWwuYmVhay5zaXplLXN0LmVyciwgeW1heD1yZWwuYmVhay5zaXplK3N0LmVycikpICArCiAgeGxhYigieWVhciIpICsKICB5bGFiKCJyZWwuYmVhay5zaXplIikgKwogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgNC40LiBJbnRlcnByZXRhdGlvbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgNC40LjEuIEdlbmVyYWwgcGF0dGVybnMKCkJhc2VkIG9uIHRoZSBncmFwaHMgeW91IGp1c3QgbWFkZSwgd2hhdCBkbyB5b3Ugb2JzZXJ2ZT8gSG93IGRvIHlvdSBpbnRlcnByZXQgdGhlIGRhdGEgaWYgSSB0b2xkIHlvdSB0aGF0IDE5Nzcgd2FzIGEgbWFzc2l2ZSBkcm91Z2h0IHllYXI/CgpUaGUgYmVha3Mgd2VyZSB0aGUgc21hbGxlc3QgaW4gMTk3NSwgdGhlbiBhZnRlciAxOTc3IHRoZSBiZWFrIHNpemVzIHN0YXllZCBwcmV0dHkgY29uc2lzdGVudC4gSWYgMTk3NyB3YXMgYSBtYXNzaXZlIGRyb3VnaHQgeWVhciwgdGhlIGF2ZXJhZ2UgcmVsYXRpdmUgYmVhayBzaXplIG11c3QgaGF2ZSBpbmNyZWFzZWQgYmVjYXVzZSB0aGV5IHdlcmUgZWF0aW5nIHRoaW5ncyB0aGF0IHdvdWxkIHByb3ZpZGUgdGhlbSB3aXRoIHdhdGVyLiBCZWNhdXNlIHRoaXMgd2FzIG91dHNpZGUgb2YgdGhlaXIgbm9ybWFsIGRpZXQsIGl0IGNvdWxkIGhhdmUgaW5jcmVhc2VkIHRoZWlyIGJlYWsgc2l6ZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIDQuNC4yLiBFdm9sdXRpb24uLi4gb3IgTm90PwoKRG8geW91IHRoaW5rIHRoZXNlIGRhdGEgcmVmbGVjdCBldm9sdXRpb25hcnkgY2hhbmdlIHRocm91Z2ggdGltZT8gV2hhdCBpcyBhIHBvdGVudGlhbCBhbHRlcm5hdGl2ZSBleHBsYW5hdGlvbj8gV2hhdCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHdvdWxkIHlvdSBuZWVkIHRvIGVpdGhlciBhY2NlcHQgb3IgcmVqZWN0IHRoZSBoeXBvdGhlc2lzIHRoYXQgdGhlc2UgcGF0dGVybnMgcmVmbGVjdCBldm9sdXRpb25hcnkgY2hhbmdlPwoKVGhlIGRhdGEgY291bGQgYWxzbyByZWZsZWN0IGEgcGFyZW50IGdlbmVyYXRpb24gcGFzc2luZyBkb3duIHRoZWlyIGJlYWsgc2l6ZSB0aGF0IHRoZXkgZ2VuZXJhdGVkIGR1cmluZyB0aGVpciBsaWZldGltZS4gVGhlIHJlbGF0aXZlIGJlYWsgc2l6ZSBjaGFuZ2UgaXMgc2VlbXMgcmFwaWQgaW4gdGhlIGdyYXBoLCBzbyB0aGF0IGNvdWxkIGJlIGFuIGV4cGxhbmF0aW9uLiBUbyBwcm92ZSB0aGF0IGl0IGlzIGV2b2x1dGlvbmFyeSBjaGFuZ2UsIEkgd291bGQgd2FudCB0byBzZWUgdGhlIHJlbGF0aXZlIGJlYWsgc2l6ZSBvZiBkaWZmZXJlbnQgZ2VuZXJhdGlvbnMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgNS4gUmVzb3VyY2VzCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIDUuMS4gRGF0YSBSZWZlcmVuY2VzCgpEYXRhIG9uIGJlYWsgc2l6ZSB2YXJpYXRpb24gaW4gRGFyd2luJ3MgZmluY2hlcyBjYW1lIGZyb20gdGhlIGZvbGxvd2luZyBwdWJsaWNhdGlvbjoKCi0gICBHcmFudCwgUFIgJiBCUiBHcmFudC4gMjAwMi4gW1VucHJlZGljdGFibGUgZXZvbHV0aW9uIGluIGEgMzAteWVhciBzdHVkeSBvZiBEYXJ3aW4ncyBmaW5jaGVzXShodHRwczovL3NjaWVuY2Uuc2NpZW5jZW1hZy5vcmcvY29udGVudC8yOTYvNTU2OC83MDcpLiAqU2NpZW5jZSogMjk2LCA3MDctNzExLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA1LjIgUmVzb3VyY2VzIFlvdSBDb25zdWx0ZWQKCkNvbnN1bHRpbmcgYWRkaXRpb25hbCByZXNvdXJjZXMgdG8gc29sdmUgdGhpcyBhc3NpZ25tZW50IGlzIGFic29sdXRlbHkgYWxsb3dlZCwgYnV0IGZhaWx1cmUgdG8gZGlzY2xvc2UgdGhvc2UgcmVzb3VyY2VzIGlzIHBsYWdpYXJpc20uIFBsZWFzZSBsaXN0IGFueSBjb2xsYWJvcmF0b3JzIHlvdSB3b3JrZWQgd2l0aCBhbmQgcmVzb3VyY2VzIHlvdSB1c2VkIGJlbG93IG9yIHN0YXRlIHRoYXQgeW91IGhhdmUgbm90IHVzZWQgYW55LgoKSSBoYXZlIG5vdCB1c2VkIGFueSBhZGRpdGlvbmFsIHJlc291cmNlcwo=