Introduction
This RMarkdown document is part of the Generic Skills Component (GSK)
of the Course of the Foundation Studies Programme at Srishti Manipal
Institute of Art, Design, and Technology, Bangalore India. The material
is based on A Layered Grammar of Graphics by Hadley Wickham.
The course is meant for First Year students pursuing a Degree in Art and
Design.
The intent of this GSK part is to build Skill in coding in R, and
also appreciate R as a way to metaphorically visualize information of
various kinds, using predominantly geometric figures and structures.
All RMarkdown files combine code, text, web-images, and figures
developed using code. Everything is text; code chunks are enclosed in
fences (```)
Goals
- Understand different kinds of data variables
- Appreciate how they can be identified based on the Interrogative
Pronouns they answer to
- Understand how each kind of variable lends itself to a specific
geometric aspect in the data visualization.
- Understand how ask Questions of Data to develop Visualizations
Pedagogical Note
The method followed will be based on PRIMM:
- PREDICT Inspect the code and guess at what the code
might do, write predictions
- RUN the code provided and check what happens
- INFER what the
parameters
of the code
do and write comments to explain. What bells and
whistles can you see?
- MODIFY the
parameters
code provided to
understand the options
available. Write
comments to show what you have aimed for and achieved.
- MAKE : take an idea/concept of your own, and graph
it.
Set Up
The setup
code chunk below brings into
our coding session R packages that provide specific
computational abilities and also datasets which we can
use.
To reiterate: Packages and datasets are not the same
thing !! Packages are (small) collections of programs. Datasets are
just….information.
Packages needed
knitr::opts_chunk$set(echo = TRUE,warning = TRUE)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0 ✔ purrr 1.0.1
## ✔ tibble 3.1.8 ✔ dplyr 1.0.10
## ✔ tidyr 1.2.1 ✔ stringr 1.5.0
## ✔ readr 2.1.3 ✔ forcats 0.5.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(palmerpenguins)
Introduction
In this RMarkdown document, we try to connect story-making
questions with two ideas:
- a Variable in a dataset
- A computed Quantity / Descriptive Statistic or a
Visual, based on one or more Variables
So: a question identifies a variable and a question also leads to a
Computation or a Data Visualization. The idea is to
get the intuition behind data, and iteratively ask the questions and
form hypotheses and perform Exploratory Data Analysis (EDA)
using graphs and charts in R.
At some point we may find that the data is not adequate to
prove/disprove a particular hypothesis and need to get into further
research / experimental design. It is possible to design the research
experiments also in R, but we may cover that much later.
In the following:
When it is YOUR TURN: wherever you see YOUR TURN, please respond with
explanations, more questions and if you are already confident, code
chunks to create new calculations and graphs. This will be one of your
submissions for this module, on Teams!
Interrogative Pronouns
for Data Variables
So how do we ask questions? These are usually with interrogative
pronouns in English: What? Who? Where? Which? What Kind? How? and
so on.
The
penguins
dataset
names(penguins) # Column, i.e. Variable names
## [1] "species" "island" "bill_length_mm"
## [4] "bill_depth_mm" "flipper_length_mm" "body_mass_g"
## [7] "sex" "year"
head(penguins) # first six rows
tail(penguins) # Last six rows
dim(penguins) # Size of dataset
## [1] 344 8
# Check for missing data
any(is.na(penguins) == TRUE)
## [1] TRUE
- What are the variable
names()
?
- What would be the Question you might have asked to obtain each of
the variables?
- What further questions/meta questions would you ask to “process”
that variable? ( Hint: Add another word after any of the Interrogative
Pronouns, e.g. How…MANY?)
- Where might the answers take your story?
YOUR TURN-1
State a few questions after discussion with your friend and state
possible variables, or what you could DO with the variables, as an
answer.
E.g. Q. How many penguins? A. We need to count…rows?
Pronouns and
Variables
In the Table below, we have a rough mapping of interrogative pronouns
to the kinds of variables in the data:
What, Who, Where, Whom, Which |
Name, Place, Animal, Thing |
Qu alitative / Nominal |
Name |
|
How, What Kind, What Sort |
A Manner / Method, Type or Attribute from a list, with list items in
some ” o rder**” ( e.g. good, better, improved, best..) |
Qu alitative / Ordinal |
So cioeconom ic-status (“lo w-income, middl e-income, hig
h-income)
Education l evel(“hig hschool”,
” BS”,“MS”,
“PhD”)
Income level
(“less than 50K”,
“5 0K-100K”, “o ver100K”)
Sat isfaction
rating (” extremely
dislike”, ” dislike”, ” neutral”,
“like”, ” extremely
like”). |
|
How Many / Much / Heavy? Few? Seldom? Often? When? |
Q uantities with Scale.
Diff erences are me aningful, but not products or
ratios |
Qua ntitative / I nterval |
- pH
- SAT score (200-800)
- Credit score (300-850)
- Year of
Starting in
College |
Deviation |
How Many / Much / Heavy? Few? Seldom? Often? When? |
Qu antities, with Scale and a Zero Value.
Di fferences and Ratios /Products are me aningful. (e.g Weight
) |
Qua ntitative / Ratio |
Weight,
Length,
Height
Te mperature in
Kelvin
activity, dose
amount,
reaction rate, flow rate, conc entration
|
Variation |
As you go from Qualitative to Quantitative data types in the table, I
hope you can detect a movement from fuzzy groups/categories to more and
more crystallized numbers. Each variable/scale can be subjected to the
operations of the previous group. In the words of S.S.
Stevens (https://psychology.okstate.edu/faculty/jgrice/psyc3214/Stevens_FourScales_1946.pdf)
the basic operations needed to create each type of scale is
cumulative: to an operation listed opposite a particular scale must be
added all those operations preceding it.
Do think about this as you work with data.
Do take a look at these references:
- https://stats.idre.ucla.edu/other/mult-pkg/whatstat/what-is-the-difference-between-categorical-ordinal-and-interval-variables/
- https://www.freecodecamp.org/news/types-of-data-in-statistics-nominal-ordinal-interval-and-ratio-data-types-explained-with-examples/
The mpg
dataset
names(mpg) # Column, i.e. Variable names
## [1] "manufacturer" "model" "displ" "year" "cyl"
## [6] "trans" "drv" "cty" "hwy" "fl"
## [11] "class"
head(mpg) # first six rows
tail(mpg) # Last six rows
dim(mpg) # Size of dataset
## [1] 234 11
# Check for missing data
any(is.na(mpg) == TRUE)
## [1] FALSE
YOUR TURN-2
Look carefully at the variables here. How would you interpret say the
cyl
variable? Is it a number and therefore Quantitative, or
could it be something else?
Interrogations and
Graphs
We can also respond to ( more complex ) Questions, with not just a
variable but one of two things:
- A calculation, shown in a table
- a data visualization. This visualization can even involve
more than one variable, as we will see.
What sort of calculations, and visuals charts can we create with
different kinds of variables, taken singly or together? Let us write
some simple English descriptions of measures and visuals and see what
commands they use in R.
Here we will use the Grammar of a package called ggplot
,
which we will encounter in Lab:04. Let us go with our intuition with the
code in the following sections.
Note: since we saw a couple of missing entries in the
penguins
dataset, let us remove them for now.
penguins <- penguins %>% drop_na()
Single
Qualitative/Categorical/ Nominal Variable
- Questions: Which? What Kind? How? How many of each Kind?
- Island ( Which island ? )
- Species ( Which Species? )
- Calculations: No of
levels
/ Counts for each
level
count / tally
of no. of penguins on each island or in
each species
sort
and order
by island or species
- Charts: Bar Chart / Pie Chart / Tree Map
geom_bar
/ geom_bar + coord_polar()
/ Find
out!!
penguins %>% count(species)
ggplot(penguins) + geom_bar(aes(x = island))
ggplot(penguins) + geom_bar(aes(x = sex))
YOUR TURN-3
Single Quantitative
Variable
Questions: How many? How few? How often? How much?
Calculations: max / min / mean / mode / (units)
max()
, min()
, range()
,
mean()
, mode(), summary()
- Charts: Bar Chart / Histogram / Density
geom_histogram()
/ geom_density()
max(penguins$bill_length_mm)
## [1] 59.6
range(penguins$bill_length_mm, na.rm =TRUE)
## [1] 32.1 59.6
summary(penguins$flipper_length_mm)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 172 190 197 201 213 231
ggplot(penguins) + geom_density(aes(bill_length_mm))
ggplot(penguins) + geom_histogram(aes(x = bill_length_mm))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
YOUR TURN-4
Are all the above Quantitative variables ratio variables?
Justify.
Two Variables:
Quantitative vs Quantitative
We can easily extend our intuition about one quantitative variable,
to a pair of them. What Questions can we ask?
Questions: How many of this vs How many of that? Does this depend
upon that? How are they related? (Remember \(y
= mx + c\) and friends?)
Calculations: Correlation / Covariance / T-test / Chi-Square Test
for Two Means etc. We won’t go into this here !
Charts: Scatter Plot / Line Plot / Regression i.e. best fit
lines
cor(penguins$bill_length_mm, penguins$bill_depth_mm)
## [1] -0.2286256
ggplot(penguins) +
geom_point(aes(x = flipper_length_mm,
y = body_mass_g))
ggplot(penguins) +
geom_point(aes(x = flipper_length_mm,
y = bill_length_mm))
YOUR TURN-5
Two Variables:
Categorical vs Categorical
What sort of question could we ask that involves two
categorical variables?
Questions: How Many of this Kind( ~x) are How Many of that Kind(
~y ) ?
Calculations: Counts and Tallies sliced by Category
Charts: Stacked Bar Charts / Grouped Bar Charts / Segmented Bar
Chart / Mosaic Chart
geom_bar()
- Use the second Categorical variables to modify
fill
,
color
.
- Also try to vary the parameter
position
of the
bars.
ggplot(penguins) + geom_bar(aes(x = island,
fill = species),
position = "stack")
Storyline: तीन पेनगीन। और तुम भी तीन(Oh never mind!)
YOUR TURN-6
Two Variables:
Quantitative vs Qualitative
Finally, what if we want to look at Quant variables and Qual
variables together? What questions could we ask?
Questions: How much of this is Which Kind of that? How many vs
Which? How many vs How?
Calculations: Counts, Means, Ranges etc., grouped
by Categorical variable.
ggplot(penguins) +
geom_density(aes(x = body_mass_g,
color = island,
fill = island),
alpha = 0.3)
- Charts: Bar Chart using group / density plots by group / violin
plots by group / box plots by group
geom_bar
/ geom_density
/
geom_violin
/ geom_boxplot
using Categorical
Variable for grouping
ggplot(penguins) +
geom_density(aes(x = body_mass_g,
color = island,
fill = island),
alpha = 0.3)
ggplot(penguins) +
geom_histogram(aes(x = flipper_length_mm,
fill = sex))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
YOUR TURN-7
Time to Play
- Create a fresh RMarkdown and similarly analyse two datasets of the
following data sets
LS0tDQp0aXRsZTogIkxhYi0wMjogUHJvbm91bnMgYW5kIERhdGEiDQphdXRob3I6ICJBcnZpbmQgVmVua2F0YWRyaSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogZmxhdGx5DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgdG9jX2RlcHRoOiAyDQogICAgbnVtYmVyX3NlY3Rpb25zOiBUUlVFDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KYWJzdHJhY3Q6IFBhcnQgb2YgdGhlIGBSIGZvciBBcnRpc3RzIGFuZCBEZXNpZ25lcnNgIHdvcmtzaG9wIGNvdXJzZSBhdCB0aGUgU2Nob29sIG9mIEZvdW5kYXRpb24gU3R1ZGllcywgU3Jpc2h0aSBNYW5pcGFsIEluc3RpdHV0ZSBvZiBBcnQsIERlc2lnbiwgYW5kIFRlY2hub2xvZ3ksIEJhbmdhbG9yZS4NCmVkaXRvcl9vcHRpb25zOiANCiAgbWFya2Rvd246IA0KICAgIHdyYXA6IDcyDQotLS0NCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBSTWFya2Rvd24gZG9jdW1lbnQgaXMgcGFydCBvZiB0aGUgR2VuZXJpYyBTa2lsbHMgQ29tcG9uZW50IChHU0spIG9mDQp0aGUgQ291cnNlIG9mIHRoZSBGb3VuZGF0aW9uIFN0dWRpZXMgUHJvZ3JhbW1lIGF0IFNyaXNodGkgTWFuaXBhbA0KSW5zdGl0dXRlIG9mIEFydCwgRGVzaWduLCBhbmQgVGVjaG5vbG9neSwgQmFuZ2Fsb3JlIEluZGlhLiBUaGUgbWF0ZXJpYWwNCmlzIGJhc2VkIG9uICpBIExheWVyZWQgR3JhbW1hciBvZiBHcmFwaGljcyogYnkgSGFkbGV5IFdpY2toYW0uIFRoZQ0KY291cnNlIGlzIG1lYW50IGZvciBGaXJzdCBZZWFyIHN0dWRlbnRzIHB1cnN1aW5nIGEgRGVncmVlIGluIEFydCBhbmQNCkRlc2lnbi4NCg0KVGhlIGludGVudCBvZiB0aGlzIEdTSyBwYXJ0IGlzIHRvIGJ1aWxkIFNraWxsIGluIGNvZGluZyBpbiBSLCBhbmQgYWxzbw0KYXBwcmVjaWF0ZSBSIGFzIGEgd2F5IHRvIG1ldGFwaG9yaWNhbGx5IHZpc3VhbGl6ZSBpbmZvcm1hdGlvbiBvZiB2YXJpb3VzDQpraW5kcywgdXNpbmcgcHJlZG9taW5hbnRseSBnZW9tZXRyaWMgZmlndXJlcyBhbmQgc3RydWN0dXJlcy4NCg0KQWxsIFJNYXJrZG93biBmaWxlcyBjb21iaW5lIGNvZGUsIHRleHQsIHdlYi1pbWFnZXMsIGFuZCBmaWd1cmVzDQpkZXZlbG9wZWQgdXNpbmcgY29kZS4gRXZlcnl0aGluZyBpcyB0ZXh0OyBjb2RlIGNodW5rcyBhcmUgZW5jbG9zZWQgaW4NCioqZmVuY2VzKiogKFxgXGBcYCkNCg0KIyBHb2Fscw0KDQotICAgVW5kZXJzdGFuZCBkaWZmZXJlbnQga2luZHMgb2YgZGF0YSB2YXJpYWJsZXMNCi0gICBBcHByZWNpYXRlIGhvdyB0aGV5IGNhbiBiZSBpZGVudGlmaWVkIGJhc2VkIG9uIHRoZSAqSW50ZXJyb2dhdGl2ZQ0KICAgIFByb25vdW5zKiB0aGV5IGFuc3dlciB0bw0KLSAgIFVuZGVyc3RhbmQgaG93IGVhY2gga2luZCBvZiB2YXJpYWJsZSBsZW5kcyBpdHNlbGYgdG8gYSBzcGVjaWZpYw0KICAgIGdlb21ldHJpYyBhc3BlY3QgaW4gdGhlIGRhdGEgdmlzdWFsaXphdGlvbi4NCi0gICBVbmRlcnN0YW5kIGhvdyBhc2sgUXVlc3Rpb25zIG9mIERhdGEgdG8gZGV2ZWxvcCBWaXN1YWxpemF0aW9ucw0KDQojIFBlZGFnb2dpY2FsIE5vdGUNCg0KVGhlIG1ldGhvZCBmb2xsb3dlZCB3aWxsIGJlIGJhc2VkIG9uDQpbUFJJTU1dKGh0dHBzOi8vYmxvZ3Mua2NsLmFjLnVrL2NzZXIvMjAxNy8wOS8wMS9wcmltbS1hLXN0cnVjdHVyZWQtYXBwcm9hY2gtdG8tdGVhY2hpbmctcHJvZ3JhbW1pbmcvKToNCg0KLSAgICoqUFJFRElDVCoqIEluc3BlY3QgdGhlIGNvZGUgYW5kIGd1ZXNzIGF0IHdoYXQgdGhlIGNvZGUgbWlnaHQgZG8sDQogICAgKip3cml0ZSBwcmVkaWN0aW9ucyoqDQotICAgKipSVU4qKiB0aGUgY29kZSBwcm92aWRlZCBhbmQgY2hlY2sgd2hhdCBoYXBwZW5zDQotICAgKipJTkZFUioqIHdoYXQgdGhlIGBwYXJhbWV0ZXJzYCBvZiB0aGUgY29kZSBkbyBhbmQgKip3cml0ZSBjb21tZW50cw0KICAgIHRvIGV4cGxhaW4qKi4gV2hhdCBiZWxscyBhbmQgd2hpc3RsZXMgY2FuIHlvdSBzZWU/DQotICAgKipNT0RJRlkqKiB0aGUgYHBhcmFtZXRlcnNgIGNvZGUgcHJvdmlkZWQgdG8gdW5kZXJzdGFuZCB0aGUNCiAgICBgb3B0aW9uc2AgYXZhaWxhYmxlLiAqKldyaXRlIGNvbW1lbnRzKiogdG8gc2hvdyB3aGF0IHlvdSBoYXZlIGFpbWVkDQogICAgZm9yIGFuZCBhY2hpZXZlZC4NCi0gICAqKk1BS0UqKiA6IHRha2UgYW4gaWRlYS9jb25jZXB0IG9mIHlvdXIgb3duLCBhbmQgZ3JhcGggaXQuDQoNCiMjIFNldCBVcA0KDQpUaGUgYHNldHVwYCBjb2RlICoqY2h1bmsqKiBiZWxvdyBicmluZ3MgaW50byBvdXIgY29kaW5nIHNlc3Npb24gKipSDQpwYWNrYWdlcyoqIHRoYXQgcHJvdmlkZSBzcGVjaWZpYyBjb21wdXRhdGlvbmFsIGFiaWxpdGllcyBhbmQgYWxzbw0KKipkYXRhc2V0cyoqIHdoaWNoIHdlIGNhbiB1c2UuDQoNClRvIHJlaXRlcmF0ZTogUGFja2FnZXMgYW5kIGRhdGFzZXRzIGFyZSAqKm5vdCoqIHRoZSBzYW1lIHRoaW5nICEhDQpQYWNrYWdlcyBhcmUgKHNtYWxsKSBjb2xsZWN0aW9ucyBvZiBwcm9ncmFtcy4gRGF0YXNldHMgYXJlDQpqdXN0Li4uLmluZm9ybWF0aW9uLg0KDQojIFBhY2thZ2VzIG5lZWRlZA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1UUlVFfQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsd2FybmluZyA9IFRSVUUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocGFsbWVycGVuZ3VpbnMpDQoNCmBgYA0KDQojIEludHJvZHVjdGlvbg0KDQpJbiB0aGlzIFJNYXJrZG93biBkb2N1bWVudCwgd2UgdHJ5IHRvIGNvbm5lY3Qgc3RvcnktbWFraW5nICoqcXVlc3Rpb25zKioNCndpdGggdHdvIGlkZWFzOg0KDQphKSAgYSAqVmFyaWFibGUqIGluIGEgZGF0YXNldA0KYikgIEEgY29tcHV0ZWQgKlF1YW50aXR5IC8gRGVzY3JpcHRpdmUgU3RhdGlzdGljKiBvciBhICpWaXN1YWwqLCBiYXNlZA0KICAgIG9uIG9uZSBvciBtb3JlIFZhcmlhYmxlcw0KDQpTbzogYSBxdWVzdGlvbiBpZGVudGlmaWVzIGEgdmFyaWFibGUgYW5kIGEgcXVlc3Rpb24gYWxzbyBsZWFkcyB0byBhDQoqQ29tcHV0YXRpb24qIG9yIGEgKkRhdGEgVmlzdWFsaXphdGlvbiouIFRoZSBpZGVhIGlzIHRvIGdldCB0aGUNCmludHVpdGlvbiBiZWhpbmQgZGF0YSwgYW5kIGl0ZXJhdGl2ZWx5IGFzayB0aGUgcXVlc3Rpb25zIGFuZCBmb3JtDQpoeXBvdGhlc2VzIGFuZCBwZXJmb3JtICpFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzKiAoRURBKSB1c2luZyBncmFwaHMNCmFuZCBjaGFydHMgaW4gUi4NCg0KQXQgc29tZSBwb2ludCB3ZSBtYXkgZmluZCB0aGF0IHRoZSBkYXRhIGlzIG5vdCBhZGVxdWF0ZSB0bw0KcHJvdmUvZGlzcHJvdmUgYSBwYXJ0aWN1bGFyIGh5cG90aGVzaXMgYW5kIG5lZWQgdG8gZ2V0IGludG8gZnVydGhlcg0KcmVzZWFyY2ggLyBleHBlcmltZW50YWwgZGVzaWduLiBJdCBpcyBwb3NzaWJsZSB0byBkZXNpZ24gdGhlIHJlc2VhcmNoDQpleHBlcmltZW50cyBhbHNvIGluIFIsIGJ1dCB3ZSBtYXkgY292ZXIgdGhhdCBtdWNoIGxhdGVyLg0KDQpJbiB0aGUgZm9sbG93aW5nOg0KDQo+IFdoZW4gaXQgaXMgWU9VUiBUVVJOOiB3aGVyZXZlciB5b3Ugc2VlIFlPVVIgVFVSTiwgcGxlYXNlIHJlc3BvbmQgd2l0aA0KPiBleHBsYW5hdGlvbnMsIG1vcmUgcXVlc3Rpb25zIGFuZCBpZiB5b3UgYXJlIGFscmVhZHkgY29uZmlkZW50LCBjb2RlDQo+IGNodW5rcyB0byBjcmVhdGUgbmV3IGNhbGN1bGF0aW9ucyBhbmQgZ3JhcGhzLiBUaGlzIHdpbGwgYmUgb25lIG9mIHlvdXINCj4gc3VibWlzc2lvbnMgZm9yIHRoaXMgbW9kdWxlLCBvbiBUZWFtcyENCg0KIyBJbnRlcnJvZ2F0aXZlIFByb25vdW5zIGZvciBEYXRhIFZhcmlhYmxlcw0KDQpTbyBob3cgZG8gd2UgYXNrIHF1ZXN0aW9ucz8gVGhlc2UgYXJlIHVzdWFsbHkgd2l0aCAqaW50ZXJyb2dhdGl2ZQ0KcHJvbm91bnMqIGluIEVuZ2xpc2g6IFdoYXQ/IFdobz8gV2hlcmU/IFdoaWNoPyBXaGF0IEtpbmQ/IEhvdz8gYW5kIHNvDQpvbi4NCg0KIyMgVGhlIGBwZW5ndWluc2AgZGF0YXNldA0KDQpgYGB7ciBMb29rX2F0X1Blbmd1aW5zfQ0KDQpuYW1lcyhwZW5ndWlucykgIyBDb2x1bW4sIGkuZS4gVmFyaWFibGUgbmFtZXMNCmhlYWQocGVuZ3VpbnMpICMgZmlyc3Qgc2l4IHJvd3MNCnRhaWwocGVuZ3VpbnMpICMgTGFzdCBzaXggcm93cw0KZGltKHBlbmd1aW5zKSAjIFNpemUgb2YgZGF0YXNldA0KDQojIENoZWNrIGZvciBtaXNzaW5nIGRhdGENCmFueShpcy5uYShwZW5ndWlucykgPT0gVFJVRSkNCg0KYGBgDQoNCjEuICBXaGF0IGFyZSB0aGUgdmFyaWFibGUgYG5hbWVzKClgPw0KMi4gIFdoYXQgd291bGQgYmUgdGhlIFF1ZXN0aW9uIHlvdSBtaWdodCBoYXZlIGFza2VkIHRvIG9idGFpbiBlYWNoIG9mDQogICAgdGhlIHZhcmlhYmxlcz8NCjMuICBXaGF0IGZ1cnRoZXIgcXVlc3Rpb25zL21ldGEgcXVlc3Rpb25zIHdvdWxkIHlvdSBhc2sgdG8gInByb2Nlc3MiDQogICAgdGhhdCB2YXJpYWJsZT8gKCBIaW50OiBBZGQgYW5vdGhlciB3b3JkIGFmdGVyIGFueSBvZiB0aGUNCiAgICBJbnRlcnJvZ2F0aXZlIFByb25vdW5zLCBlLmcuIEhvdy4uLk1BTlk/KQ0KNC4gIFdoZXJlIG1pZ2h0IHRoZSBhbnN3ZXJzIHRha2UgeW91ciBzdG9yeT8NCg0KIyMjIFlPVVIgVFVSTi0xDQoNClN0YXRlIGEgZmV3IHF1ZXN0aW9ucyBhZnRlciBkaXNjdXNzaW9uIHdpdGggeW91ciBmcmllbmQgYW5kIHN0YXRlDQpwb3NzaWJsZSB2YXJpYWJsZXMsIG9yIHdoYXQgeW91IGNvdWxkIERPIHdpdGggdGhlIHZhcmlhYmxlcywgYXMgYW4NCmFuc3dlci5cDQpFLmcuIFEuIEhvdyBtYW55IHBlbmd1aW5zPyBBLiBXZSBuZWVkIHRvIGNvdW50Li4ucm93cz8NCg0KIyMgUHJvbm91bnMgYW5kIFZhcmlhYmxlcw0KDQpJbiB0aGUgVGFibGUgYmVsb3csIHdlIGhhdmUgYSByb3VnaCBtYXBwaW5nIG9mIGludGVycm9nYXRpdmUgcHJvbm91bnMgdG8NCnRoZSBraW5kcyBvZiB2YXJpYWJsZXMgaW4gdGhlIGRhdGE6DQoNCistLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCnwgUHJvbm91biAgIHwgQW5zd2VyICAgIHwgVmFyaWFibGUgIHwgRXhhbXBsZSAgIHwgV2hhdCAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgLyBTY2FsZSAgIHwgICAgICAgICAgIHwgT3AgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZXJhdGlvbnM/IHwNCis9PT09PT09PT09PSs9PT09PT09PT09PSs9PT09PT09PT09PSs9PT09PT09PT09PSs9PT09PT09PT09PSsNCnwgV2hhdCwgICAgIHwgTmFtZSwgICAgIHwgUXUgICAgICAgIHwgTmFtZSAgICAgIHwgLSAgIENvdW50IHwNCnwgV2hvLCAgICAgIHwgUGxhY2UsICAgIHwgYWxpdGF0aXZlIHwgICAgICAgICAgIHwgICAgIG5vLiAgIHwNCnwgV2hlcmUsICAgIHwgQW5pbWFsLCAgIHwgLyAgICAgICAgIHwgICAgICAgICAgIHwgICAgIG9mICAgIHwNCnwgV2hvbSwgICAgIHwgVGhpbmcgICAgIHwgKiogICAgICAgIHwgICAgICAgICAgIHwgICAgIGNhc2VzIHwNCnwgV2hpY2ggICAgIHwgICAgICAgICAgIHwgTm9taW5hbCoqIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgIE1vZGUgIHwNCistLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCnwgSG93LCBXaGF0IHwgQSBNYW5uZXIgIHwgUXUgICAgICAgIHwgLSAgIFNvICAgIHwgLSAgICAgICAgIHwNCnwgS2luZCwgICAgIHwgLyBNZXRob2QsIHwgYWxpdGF0aXZlIHwgY2lvZWNvbm9tIHwgICAgTWVkaWFuIHwNCnwgV2hhdCBTb3J0IHwgVHlwZSBvciAgIHwgLyAgICAgICAgIHwgaWMtc3RhdHVzIHwgLSAgIFBlICAgIHwNCnwgICAgICAgICAgIHwgQXR0cmlidXRlIHwgKiogICAgICAgIHwgICAgICgibG8gIHwgcmNlbnRpbGVzIHwNCnwgICAgICAgICAgIHwgZnJvbSBhICAgIHwgT3JkaW5hbCoqIHwgdy1pbmNvbWUsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgbGlzdCwgICAgIHwgICAgICAgICAgIHwgICAgIG1pZGRsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgd2l0aCBsaXN0IHwgICAgICAgICAgIHwgZS1pbmNvbWUsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgaXRlbXMgaW4gIHwgICAgICAgICAgIHwgICAgIGhpZyAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgc29tZSAiICAgIHwgICAgICAgICAgIHwgaC1pbmNvbWUpIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgbyAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgcmRlclwqXCoiIHwgICAgICAgICAgIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgKCBlLmcuICAgIHwgICAgICAgICAgIHwgRWR1Y2F0aW9uIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgZ29vZCwgICAgIHwgICAgICAgICAgIHwgICAgIGwgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYmV0dGVyLCAgIHwgICAgICAgICAgIHwgZXZlbCgiaGlnIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgaW1wcm92ZWQsIHwgICAgICAgICAgIHwgaHNjaG9vbCIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYmVzdC4uKSAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICIgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgQlMiLCJNUyIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIlBoRCIpIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgSW5jb21lIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIGxldmVsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgKCJsZXNzIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIHRoYW4gIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIDUwSyIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICI1ICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgMEstMTAwSyIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICJvICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgdmVyMTAwSyIpIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgIFNhdCAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgaXNmYWN0aW9uIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgcmF0aW5nIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICgiICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZXh0cmVtZWx5IHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZGlzbGlrZSIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICIgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZGlzbGlrZSIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICIgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgbmV1dHJhbCIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAibGlrZSIsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICIgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZXh0cmVtZWx5IHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICBsaWtlIikuIHwgICAgICAgICAgIHwNCistLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCnwgSG93IE1hbnkgIHwgUSAgICAgICAgIHwgUXVhICAgICAgIHwgLSAgIHBIICAgIHwgLSAgIE1lYW4gIHwNCnwgLyBNdWNoIC8gIHwgdWFudGl0aWVzIHwgbnRpdGF0aXZlIHwgLSAgIFNBVCAgIHwgICAgICAgICAgIHwNCnwgSGVhdnk/ICAgIHwgd2l0aCAgICAgIHwgLyAgICAgICAgIHwgICAgIHNjb3JlIHwgLSAgICAgICAgIHwNCnwgRmV3PyAgICAgIHwgU2NhbGUuICAgIHwgKipJICAgICAgIHwgKDIwMC04MDApIHwgIFN0YW5kYXJkIHwNCnwgU2VsZG9tPyAgIHwgICAgICAgICAgIHwgbnRlcnZhbCoqIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgT2Z0ZW4/ICAgIHwgKipEaWZmICAgIHwgICAgICAgICAgIHwgICAgQ3JlZGl0IHwgRGV2aWF0aW9uIHwNCnwgV2hlbj8gICAgIHwgZXJlbmNlcyoqIHwgICAgICAgICAgIHwgICAgIHNjb3JlIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYXJlICAgICAgIHwgICAgICAgICAgIHwgKDMwMC04NTApIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgbWUgICAgICAgIHwgICAgICAgICAgIHwgLSAgIFllYXIgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYW5pbmdmdWwsIHwgICAgICAgICAgIHwgICAgIG9mICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYnV0IG5vdCAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgcHJvZHVjdHMgIHwgICAgICAgICAgIHwgIFN0YXJ0aW5nIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgb3IgcmF0aW9zIHwgICAgICAgICAgIHwgICAgIGluICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICBDb2xsZWdlIHwgICAgICAgICAgIHwNCistLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCnwgSG93IE1hbnkgIHwgUXUgICAgICAgIHwgUXVhICAgICAgIHwgLSAgICAgICAgIHwgLSAgIENvICAgIHwNCnwgLyBNdWNoIC8gIHwgYW50aXRpZXMsIHwgbnRpdGF0aXZlIHwgICBXZWlnaHQsIHwgcnJlbGF0aW9uIHwNCnwgSGVhdnk/ICAgIHwgd2l0aCAgICAgIHwgLyAgICAgICAgIHwgICAgICAgICAgIHwgLSAgIENvZWZmIHwNCnwgRmV3PyAgICAgIHwgU2NhbGUgYW5kIHwgKipSYXRpbyoqIHwgLSAgICAgICAgIHwgICAgIG9mICAgIHwNCnwgU2VsZG9tPyAgIHwgYSBaZXJvICAgIHwgICAgICAgICAgIHwgICBMZW5ndGgsIHwgICAgICAgICAgIHwNCnwgT2Z0ZW4/ICAgIHwgVmFsdWUuICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgVmFyaWF0aW9uIHwNCnwgV2hlbj8gICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgRGkgICAgICAgIHwgICAgICAgICAgIHwgICAgSGVpZ2h0IHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgZmZlcmVuY2VzIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYW5kICAgICAgIHwgICAgICAgICAgIHwgLSAgIFRlICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgUmF0aW9zICAgIHwgICAgICAgICAgIHwgbXBlcmF0dXJlIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgL1Byb2R1Y3RzIHwgICAgICAgICAgIHwgICAgIGluICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYXJlICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgbWUgICAgICAgIHwgICAgICAgICAgIHwgICAgS2VsdmluIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgYW5pbmdmdWwuIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgKGUuZyAgICAgIHwgICAgICAgICAgIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgV2VpZ2h0ICkgIHwgICAgICAgICAgIHwgICAgRW56eW1lIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgYWN0aXZpdHksIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIGRvc2UgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICBhbW91bnQsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgIHJlYWN0aW9uIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIHJhdGUsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIGZsb3cgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIHJhdGUsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIGNvbmMgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgZW50cmF0aW9uIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgIFB1bHNlIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgLSAgICAgICAgIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgIFN1cnZpdmFsIHwgICAgICAgICAgIHwNCnwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgICAgICAgIHwgICAgIHRpbWUgIHwgICAgICAgICAgIHwNCistLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCg0KQXMgeW91IGdvIGZyb20gUXVhbGl0YXRpdmUgdG8gUXVhbnRpdGF0aXZlIGRhdGEgdHlwZXMgaW4gdGhlIHRhYmxlLCBJDQpob3BlIHlvdSBjYW4gZGV0ZWN0IGEgbW92ZW1lbnQgZnJvbSBmdXp6eSBncm91cHMvY2F0ZWdvcmllcyB0byBtb3JlIGFuZA0KbW9yZSBjcnlzdGFsbGl6ZWQgbnVtYmVycy4gRWFjaCB2YXJpYWJsZS9zY2FsZSBjYW4gYmUgc3ViamVjdGVkIHRvIHRoZQ0Kb3BlcmF0aW9ucyBvZiB0aGUgcHJldmlvdXMgZ3JvdXAuIEluIHRoZSB3b3JkcyBvZiBbUy5TLg0KU3RldmVuc10oaHR0cHM6Ly9zdGF0cy5pZHJlLnVjbGEuZWR1L290aGVyL211bHQtcGtnL3doYXRzdGF0L3doYXQtaXMtdGhlLWRpZmZlcmVuY2UtYmV0d2Vlbi1jYXRlZ29yaWNhbC1vcmRpbmFsLWFuZC1pbnRlcnZhbC12YXJpYWJsZXMvKQ0KKDxodHRwczovL3BzeWNob2xvZ3kub2tzdGF0ZS5lZHUvZmFjdWx0eS9qZ3JpY2UvcHN5YzMyMTQvU3RldmVuc19Gb3VyU2NhbGVzXzE5NDYucGRmPikNCg0KPiB0aGUgYmFzaWMgb3BlcmF0aW9ucyBuZWVkZWQgdG8gY3JlYXRlIGVhY2ggdHlwZSBvZiBzY2FsZSBpcw0KPiBjdW11bGF0aXZlOiB0byBhbiBvcGVyYXRpb24gbGlzdGVkIG9wcG9zaXRlIGEgcGFydGljdWxhciBzY2FsZSBtdXN0IGJlDQo+IGFkZGVkIGFsbCB0aG9zZSBvcGVyYXRpb25zIHByZWNlZGluZyBpdC4NCg0KRG8gdGhpbmsgYWJvdXQgdGhpcyBhcyB5b3Ugd29yayB3aXRoIGRhdGEuDQoNCiFbXSgvaW1hZ2VzL1R5cGUtb2YtVmFyaWFibGVzLnBuZykNCg0KYGBge3IgZWNobz1GQUxTRSwgZXZhbCA9IEZBTFNFLCBvdXQud2lkdGg9ICI0NTBweCIsIG91dC5oZWlnaHQ9IjQ1MHB4IixmaWcuYWxpZ249J2NlbnRlcid9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoInN0YXRpYyIsICJpbWFnZXMiLCAiVHlwZS1vZi1WYXJpYWJsZXMucG5nIikpDQoNCmBgYA0KDQpEbyB0YWtlIGEgbG9vayBhdCB0aGVzZSByZWZlcmVuY2VzOg0KDQoxLiAgPGh0dHBzOi8vc3RhdHMuaWRyZS51Y2xhLmVkdS9vdGhlci9tdWx0LXBrZy93aGF0c3RhdC93aGF0LWlzLXRoZS1kaWZmZXJlbmNlLWJldHdlZW4tY2F0ZWdvcmljYWwtb3JkaW5hbC1hbmQtaW50ZXJ2YWwtdmFyaWFibGVzLz4NCjIuICA8aHR0cHM6Ly93d3cuZnJlZWNvZGVjYW1wLm9yZy9uZXdzL3R5cGVzLW9mLWRhdGEtaW4tc3RhdGlzdGljcy1ub21pbmFsLW9yZGluYWwtaW50ZXJ2YWwtYW5kLXJhdGlvLWRhdGEtdHlwZXMtZXhwbGFpbmVkLXdpdGgtZXhhbXBsZXMvPg0KDQojIyBUaGUgYG1wZ2AgZGF0YXNldA0KDQpgYGB7ciBMb29rX2F0X21wZ30NCm5hbWVzKG1wZykgIyBDb2x1bW4sIGkuZS4gVmFyaWFibGUgbmFtZXMNCmhlYWQobXBnKSAjIGZpcnN0IHNpeCByb3dzDQp0YWlsKG1wZykgIyBMYXN0IHNpeCByb3dzDQpkaW0obXBnKSAjIFNpemUgb2YgZGF0YXNldA0KDQojIENoZWNrIGZvciBtaXNzaW5nIGRhdGENCmFueShpcy5uYShtcGcpID09IFRSVUUpDQoNCmBgYA0KDQojIyMgWU9VUiBUVVJOLTINCg0KTG9vayBjYXJlZnVsbHkgYXQgdGhlIHZhcmlhYmxlcyBoZXJlLiBIb3cgd291bGQgeW91IGludGVycHJldCBzYXkgdGhlDQpgY3lsYCB2YXJpYWJsZT8gSXMgaXQgYSBudW1iZXIgYW5kIHRoZXJlZm9yZSBRdWFudGl0YXRpdmUsIG9yIGNvdWxkIGl0DQpiZSBzb21ldGhpbmcgZWxzZT8NCg0KIyBJbnRlcnJvZ2F0aW9ucyBhbmQgR3JhcGhzDQoNCldlIGNhbiBhbHNvIHJlc3BvbmQgdG8gKCBtb3JlIGNvbXBsZXggKSBRdWVzdGlvbnMsIHdpdGggbm90IGp1c3QgYQ0KKnZhcmlhYmxlKiBidXQgb25lIG9mIHR3byB0aGluZ3M6DQoNCi0gICBBIGNhbGN1bGF0aW9uLCBzaG93biBpbiBhICp0YWJsZSoNCi0gICBhICpkYXRhIHZpc3VhbGl6YXRpb24qLiBUaGlzIHZpc3VhbGl6YXRpb24gY2FuIGV2ZW4gaW52b2x2ZSBtb3JlDQogICAgdGhhbiBvbmUgdmFyaWFibGUsIGFzIHdlIHdpbGwgc2VlLg0KDQpXaGF0IHNvcnQgb2YgY2FsY3VsYXRpb25zLCBhbmQgdmlzdWFscyBjaGFydHMgY2FuIHdlIGNyZWF0ZSB3aXRoDQpkaWZmZXJlbnQga2luZHMgb2YgdmFyaWFibGVzLCB0YWtlbiBzaW5nbHkgb3IgdG9nZXRoZXI/IExldCB1cyB3cml0ZQ0Kc29tZSBzaW1wbGUgRW5nbGlzaCBkZXNjcmlwdGlvbnMgb2YgbWVhc3VyZXMgYW5kIHZpc3VhbHMgYW5kIHNlZSB3aGF0DQpjb21tYW5kcyB0aGV5IHVzZSBpbiBSLg0KDQpIZXJlIHdlIHdpbGwgdXNlIHRoZSBHcmFtbWFyIG9mIGEgcGFja2FnZSBjYWxsZWQgYGdncGxvdGAsIHdoaWNoIHdlIHdpbGwNCmVuY291bnRlciBpbiBMYWI6MDQuIExldCB1cyBnbyB3aXRoIG91ciBpbnR1aXRpb24gd2l0aCB0aGUgY29kZSBpbiB0aGUNCmZvbGxvd2luZyBzZWN0aW9ucy4NCg0KTm90ZTogc2luY2Ugd2Ugc2F3IGEgY291cGxlIG9mIG1pc3NpbmcgZW50cmllcyBpbiB0aGUgYHBlbmd1aW5zYA0KZGF0YXNldCwgbGV0IHVzIHJlbW92ZSB0aGVtIGZvciBub3cuDQoNCmBgYHtyfQ0KDQpwZW5ndWlucyA8LSBwZW5ndWlucyAlPiUgZHJvcF9uYSgpDQoNCmBgYA0KDQojIyBTaW5nbGUgUXVhbGl0YXRpdmUvQ2F0ZWdvcmljYWwvIE5vbWluYWwgVmFyaWFibGUNCg0KMS4gIFF1ZXN0aW9uczogV2hpY2g/IFdoYXQgS2luZD8gSG93PyBIb3cgbWFueSBvZiBlYWNoIEtpbmQ/DQoNCi0gICBJc2xhbmQgKCBXaGljaCBpc2xhbmQgPyApDQotICAgU3BlY2llcyAoIFdoaWNoIFNwZWNpZXM/ICkNCg0KMikgIENhbGN1bGF0aW9uczogTm8gb2YgYGxldmVsc2AgLyBDb3VudHMgZm9yIGVhY2ggYGxldmVsYA0KDQotICAgYGNvdW50IC8gdGFsbHlgIG9mIG5vLiBvZiBwZW5ndWlucyBvbiBlYWNoIGlzbGFuZCBvciBpbiBlYWNoIHNwZWNpZXMNCi0gICBgc29ydGAgYW5kIGBvcmRlcmAgYnkgaXNsYW5kIG9yIHNwZWNpZXMNCg0KMykgIENoYXJ0czogQmFyIENoYXJ0IC8gUGllIENoYXJ0IC8gVHJlZSBNYXANCg0KLSAgIGBnZW9tX2JhcmAgLyBgZ2VvbV9iYXIgKyBjb29yZF9wb2xhcigpYCAvIEZpbmQgb3V0ISENCg0KYGBge3IgU2luZ2xlX0NhdF9WYXJfQ2FsY3VsYXRpb25zfQ0KDQpwZW5ndWlucyAlPiUgY291bnQoc3BlY2llcykNCg0KYGBgDQoNCmBgYHtyIFNpbmdsZV9DYXRfVmFyX0dyYXBoc30NCg0KZ2dwbG90KHBlbmd1aW5zKSArIGdlb21fYmFyKGFlcyh4ID0gaXNsYW5kKSkNCmdncGxvdChwZW5ndWlucykgKyBnZW9tX2JhcihhZXMoeCA9IHNleCkpDQoNCmBgYA0KDQojIyMgWU9VUiBUVVJOLTMNCg0KIyMgU2luZ2xlIFF1YW50aXRhdGl2ZSBWYXJpYWJsZQ0KDQoxKSAgUXVlc3Rpb25zOiBIb3cgbWFueT8gSG93IGZldz8gSG93IG9mdGVuPyBIb3cgbXVjaD8NCg0KMikgIENhbGN1bGF0aW9uczogbWF4IC8gbWluIC8gbWVhbiAvIG1vZGUgLyAodW5pdHMpDQoNCi0gICBgbWF4KClgLCBgbWluKClgLCBgcmFuZ2UoKWAsIGBtZWFuKClgLCBgbW9kZSgpLCBzdW1tYXJ5KClgDQoNCjMpICBDaGFydHM6IEJhciBDaGFydCAvIEhpc3RvZ3JhbSAvIERlbnNpdHkNCiAgICAtICAgYGdlb21faGlzdG9ncmFtKClgIC8gYGdlb21fZGVuc2l0eSgpYA0KDQpgYGB7ciBTaW5nbGVfUXVhbnRfY2FsY3VsYXRpb25zfQ0KDQptYXgocGVuZ3VpbnMkYmlsbF9sZW5ndGhfbW0pDQoNCnJhbmdlKHBlbmd1aW5zJGJpbGxfbGVuZ3RoX21tLCBuYS5ybSA9VFJVRSkgDQoNCnN1bW1hcnkocGVuZ3VpbnMkZmxpcHBlcl9sZW5ndGhfbW0pDQoNCmBgYA0KDQpgYGB7ciBTaW5nbGVfUXVhbnRfZ3JhcGhzfQ0KDQpnZ3Bsb3QocGVuZ3VpbnMpICsgZ2VvbV9kZW5zaXR5KGFlcyhiaWxsX2xlbmd0aF9tbSkpDQoNCmdncGxvdChwZW5ndWlucykgKyBnZW9tX2hpc3RvZ3JhbShhZXMoeCA9IGJpbGxfbGVuZ3RoX21tKSkNCg0KYGBgDQoNCiMjIyBZT1VSIFRVUk4tNA0KDQpBcmUgYWxsIHRoZSBhYm92ZSBRdWFudGl0YXRpdmUgdmFyaWFibGVzICpyYXRpbyogdmFyaWFibGVzPyBKdXN0aWZ5Lg0KDQojIyBUd28gVmFyaWFibGVzOiBRdWFudGl0YXRpdmUgdnMgUXVhbnRpdGF0aXZlDQoNCldlIGNhbiBlYXNpbHkgZXh0ZW5kIG91ciBpbnR1aXRpb24gYWJvdXQgb25lIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSwgdG8gYQ0KcGFpciBvZiB0aGVtLiBXaGF0IFF1ZXN0aW9ucyBjYW4gd2UgYXNrPw0KDQoxKSAgUXVlc3Rpb25zOiBIb3cgbWFueSBvZiB0aGlzIHZzIEhvdyBtYW55IG9mIHRoYXQ/IERvZXMgdGhpcyBkZXBlbmQNCiAgICB1cG9uIHRoYXQ/IEhvdyBhcmUgdGhleSByZWxhdGVkPyAoUmVtZW1iZXIgJHkgPSBteCArIGMkIGFuZA0KICAgIGZyaWVuZHM/KQ0KDQoyKSAgQ2FsY3VsYXRpb25zOiBDb3JyZWxhdGlvbiAvIENvdmFyaWFuY2UgLyBULXRlc3QgLyBDaGktU3F1YXJlIFRlc3QNCiAgICBmb3IgVHdvIE1lYW5zIGV0Yy4gV2Ugd29uJ3QgZ28gaW50byB0aGlzIGhlcmUgIQ0KDQozKSAgQ2hhcnRzOiBTY2F0dGVyIFBsb3QgLyBMaW5lIFBsb3QgLyBSZWdyZXNzaW9uIGkuZS4gYmVzdCBmaXQgbGluZXMNCg0KYGBge3IgUXVhbnRfdnNfUXVhbnRfQ2FsY3VsYXRpb25zfQ0KDQpjb3IocGVuZ3VpbnMkYmlsbF9sZW5ndGhfbW0sIHBlbmd1aW5zJGJpbGxfZGVwdGhfbW0pDQoNCg0KYGBgDQoNCmBgYHtyIFF1YW50X3ZzX1F1YW50LUdyYXBoc30NCg0KZ2dwbG90KHBlbmd1aW5zKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSwNCiAgICAgICAgICAgICAgICAgeSA9IGJvZHlfbWFzc19nKSkNCg0KZ2dwbG90KHBlbmd1aW5zKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSwgDQogICAgICAgICAgICAgICAgIHkgPSBiaWxsX2xlbmd0aF9tbSkpDQoNCmBgYA0KDQojIyMgWU9VUiBUVVJOLTUNCg0KIyMgVHdvIFZhcmlhYmxlczogQ2F0ZWdvcmljYWwgdnMgQ2F0ZWdvcmljYWwNCg0KV2hhdCBzb3J0IG9mIHF1ZXN0aW9uIGNvdWxkIHdlIGFzayB0aGF0IGludm9sdmVzICp0d28qIGNhdGVnb3JpY2FsDQp2YXJpYWJsZXM/DQoNCjEpICBRdWVzdGlvbnM6IEhvdyBNYW55IG9mIHRoaXMgS2luZCggXH54KSBhcmUgSG93IE1hbnkgb2YgdGhhdCBLaW5kKA0KICAgIFx+eSApID8NCg0KMikgIENhbGN1bGF0aW9uczogQ291bnRzIGFuZCBUYWxsaWVzIHNsaWNlZCBieSBDYXRlZ29yeQ0KDQogICAgLSAgIGBjb3VudHNgICwgYHRhbGx5YA0KDQozKSAgQ2hhcnRzOiBTdGFja2VkIEJhciBDaGFydHMgLyBHcm91cGVkIEJhciBDaGFydHMgLyBTZWdtZW50ZWQgQmFyDQogICAgQ2hhcnQgLyBNb3NhaWMgQ2hhcnQNCg0KICAgIC0gICBgZ2VvbV9iYXIoKWANCiAgICAtICAgVXNlIHRoZSBzZWNvbmQgQ2F0ZWdvcmljYWwgdmFyaWFibGVzIHRvIG1vZGlmeSBgZmlsbGAsIGBjb2xvcmAuDQogICAgLSAgIEFsc28gdHJ5IHRvIHZhcnkgdGhlIHBhcmFtZXRlciBgcG9zaXRpb25gIG9mIHRoZSBiYXJzLg0KDQpgYGB7ciBUd29fQ2F0X1Zhcl9DYWxjdWxhdGlvbnN9DQoNCg0KYGBgDQoNCmBgYHtyIFR3b19DYXRfVmFyX0dyYXBoc30NCg0KZ2dwbG90KHBlbmd1aW5zKSArIGdlb21fYmFyKGFlcyh4ID0gaXNsYW5kLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IHNwZWNpZXMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gInN0YWNrIikNCmBgYA0KDQpTdG9yeWxpbmU6IOCkpOClgOCkqCDgpKrgpYfgpKjgpJfgpYDgpKjgpaQg4KSU4KSwIOCkpOClgeCkriDgpK3gpYAg4KSk4KWA4KSoKE9oIG5ldmVyIG1pbmQhKQ0KDQojIyMgWU9VUiBUVVJOLTYNCg0KIyMgVHdvIFZhcmlhYmxlczogUXVhbnRpdGF0aXZlIHZzIFF1YWxpdGF0aXZlDQoNCkZpbmFsbHksIHdoYXQgaWYgd2Ugd2FudCB0byBsb29rIGF0IFF1YW50IHZhcmlhYmxlcyBhbmQgUXVhbCB2YXJpYWJsZXMNCnRvZ2V0aGVyPyBXaGF0IHF1ZXN0aW9ucyBjb3VsZCB3ZSBhc2s/DQoNCjEpICBRdWVzdGlvbnM6IEhvdyBtdWNoIG9mIHRoaXMgaXMgV2hpY2ggS2luZCBvZiB0aGF0PyBIb3cgbWFueSB2cw0KICAgIFdoaWNoPyBIb3cgbWFueSB2cyBIb3c/DQoNCjIpICBDYWxjdWxhdGlvbnM6IENvdW50cywgTWVhbnMsIFJhbmdlcyBldGMuLCAqKmdyb3VwZWQgYnkqKiBDYXRlZ29yaWNhbA0KICAgIHZhcmlhYmxlLg0KDQpgYGB7ciBRdWFudF92c19RdWFsX0NhbGN1bGF0aW9uc30NCg0KZ2dwbG90KHBlbmd1aW5zKSArIA0KICAgIGdlb21fZGVuc2l0eShhZXMoeCA9IGJvZHlfbWFzc19nLCANCiAgICAgICAgICAgICAgICAgY29sb3IgPSBpc2xhbmQsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gaXNsYW5kKSwgDQogICAgICAgICAgICAgICAgIGFscGhhID0gMC4zKQ0KYGBgDQoNCjMpICBDaGFydHM6IEJhciBDaGFydCB1c2luZyBncm91cCAvIGRlbnNpdHkgcGxvdHMgYnkgZ3JvdXAgLyB2aW9saW4NCiAgICBwbG90cyBieSBncm91cCAvIGJveCBwbG90cyBieSBncm91cA0KDQotICAgYGdlb21fYmFyYCAvIGBnZW9tX2RlbnNpdHlgIC8gYGdlb21fdmlvbGluYCAvIGBnZW9tX2JveHBsb3RgIHVzaW5nDQogICAgQ2F0ZWdvcmljYWwgVmFyaWFibGUgZm9yIGdyb3VwaW5nDQoNCmBgYHtyIFF1YW50X3ZzX1F1YWxfR3JhcGhzfQ0KDQpnZ3Bsb3QocGVuZ3VpbnMpICsgDQogICAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gYm9keV9tYXNzX2csIA0KICAgICAgICAgICAgICAgICBjb2xvciA9IGlzbGFuZCwgDQogICAgICAgICAgICAgICAgIGZpbGwgPSBpc2xhbmQpLCANCiAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjMpDQoNCmdncGxvdChwZW5ndWlucykgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHggPSBmbGlwcGVyX2xlbmd0aF9tbSwNCiAgICAgICAgICAgICAgICAgZmlsbCA9IHNleCkpDQoNCmBgYA0KDQojIyMgWU9VUiBUVVJOLTcNCg0KIyMjIFRpbWUgdG8gUGxheQ0KDQoxLiAgQ3JlYXRlIGEgZnJlc2ggUk1hcmtkb3duIGFuZCBzaW1pbGFybHkgYW5hbHlzZSB0d28gZGF0YXNldHMgb2YgdGhlDQogICAgZm9sbG93aW5nIGRhdGEgc2V0cw0KDQotICAgQW55IGRhdGFzZXQgaW4geW91ciBSIGluc3RhbGxhdGlvbi4gVHlwZSBgZGF0YSgpYCBpbiB5b3VyIGNvbnNvbGUgdG8NCiAgICBzZWUgd2hhdCBpcyBhdmFpbGFibGUuDQotICAgYGRpYW1vbmRzYCAuIFRoaXMgZGF0YXNldCBpcyBwYXJ0IG9mIHRoZSB0aWR5dmVyc2UgcGFja2FnZSBzbyBqdXN0DQogICAgdHlwZSBgZGlhbW9uZHNgIGluIHlvdXIgY29kZSBhbmQgdGhlcmUgaXQgaXMuDQotICAgYGdhcG1pbmRlcmAgISEgWWVzISFZb3Ugd2lsbCBuZWVkIHRvIGluc3RhbGwgdGhlIGBnYXBtaW5kZXJgIHBhY2thZ2UNCiAgICB0byBhY2Nlc3MgdGhpcyBkYXRhc2V0DQotICAgYG1vc2FpY0RhdGFgIHBhY2thZ2UgZGF0YXNldHMuIEluc3RhbGwgYG1vc2FpY0RhdGFgDQotICAgYGRhdGEud29ybGRgOiBGaW5kIERhdGFzZXRzIG9mIHlvdXIgY2hvaWNlOg0KICAgIDxodHRwczovL2RvY3MuZGF0YS53b3JsZC9lbi82NDQ5OS02NDUxNi1RdWlja3N0YXJ0cy1hbmQtdHV0b3JpYWxzLmh0bWw+DQotICAgYGthZ2dsZWA6IDxodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzPg0KLSAgICoqSW5kaWEgRGF0YSBQb3J0YWwqKiA8aHR0cHM6Ly9kYXRhLmdvdi5pbi8+DQoNCiMgUmVmZXJlbmNlcw0KDQoxLiAgRGF0YSBWaXN1YWxpemF0aW9uIHdpdGggUiwgW1JvYmVydA0KICAgIEthYmFjb2ZmXShodHRwczovL3JrYWJhY29mZi5naXRodWIuaW8vZGF0YXZpcy8pIChHb29kIGNyaXNwDQogICAgZGVzY3JpcHRpb25zIG9mIG1hbnkga2luZHMgb2YgZ3JhcGhzLCBubyBub25zZW5zZSBib29rLiBBdmFpbGFibGUNCiAgICBmcmVlIG9uIHRoZSB3ZWIuKQ0KDQpgYGB7PWh0bWx9DQo8IS0tIC0tPg0KYGBgDQoyLiAgV2lja2hhbSBhbmQgR3JvbGVtdW5kLCBbUiBmb3IgRGF0YSBTY2llbmNlXShodHRwczovL3I0ZHMuaGFkLmNvLm56LykNCiAgICAoUiBCaWJsZS4gQXZhaWxhYmxlIGZyZWUgb24gdGhlIHdlYi4pDQoNCmBgYHs9aHRtbH0NCjwhLS0gLS0+DQpgYGANCjMuICBbVGhlIGJlc3Qgc3RhdHMgeW91J3ZlIGV2ZXIgc2VlbiBcfCBIYW5zDQogICAgUm9zbGluZ10oaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1oVmltVnpndEQ2dykNCg0KQXNrIG1lIGZvciBoZWxwIGFueSB0aW1lIQ0K