1 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 (```)

2 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

3 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.

3.1 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.

4 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)

5 Introduction

In this RMarkdown document, we try to connect story-making questions with two ideas:

  1. a Variable in a dataset
  2. 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!

6 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.

6.1 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
  1. What are the variable names()?
  2. What would be the Question you might have asked to obtain each of the variables?
  3. 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?)
  4. Where might the answers take your story?

6.1.1 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?

6.2 Pronouns and Variables

In the Table below, we have a rough mapping of interrogative pronouns to the kinds of variables in the data:

Pronoun Answer Variable / Scale Example What Op erations?
What, Who, Where, Whom, Which Name, Place, Animal, Thing Qu alitative / Nominal Name
  • Count no. of cases

  • Mode

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”).

  • Median
  • Pe rcentiles
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

  • Mean

  • Standard

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

  • Enzyme

activity, dose

amount,

reaction rate, flow rate, conc entration

  • Pulse

  • Survival time

  • Co rrelation
  • Coeff of

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:

  1. https://stats.idre.ucla.edu/other/mult-pkg/whatstat/what-is-the-difference-between-categorical-ordinal-and-interval-variables/
  2. https://www.freecodecamp.org/news/types-of-data-in-statistics-nominal-ordinal-interval-and-ratio-data-types-explained-with-examples/

6.3 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

6.3.1 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?

7 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()

7.1 Single Qualitative/Categorical/ Nominal Variable

  1. Questions: Which? What Kind? How? How many of each Kind?
  • Island ( Which island ? )
  • Species ( Which Species? )
  1. 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
  1. 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))

7.1.1 YOUR TURN-3

7.2 Single Quantitative Variable

  1. Questions: How many? How few? How often? How much?

  2. Calculations: max / min / mean / mode / (units)

  • max(), min(), range(), mean(), mode(), summary()
  1. 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`.

7.2.1 YOUR TURN-4

Are all the above Quantitative variables ratio variables? Justify.

7.3 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?

  1. 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?)

  2. Calculations: Correlation / Covariance / T-test / Chi-Square Test for Two Means etc. We won’t go into this here !

  3. 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))

7.3.1 YOUR TURN-5

7.4 Two Variables: Categorical vs Categorical

What sort of question could we ask that involves two categorical variables?

  1. Questions: How Many of this Kind( ~x) are How Many of that Kind( ~y ) ?

  2. Calculations: Counts and Tallies sliced by Category

    • counts , tally
  3. 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!)

7.4.1 YOUR TURN-6

7.5 Two Variables: Quantitative vs Qualitative

Finally, what if we want to look at Quant variables and Qual variables together? What questions could we ask?

  1. Questions: How much of this is Which Kind of that? How many vs Which? How many vs How?

  2. 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)

  1. 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`.

7.5.1 YOUR TURN-7

7.5.2 Time to Play

  1. Create a fresh RMarkdown and similarly analyse two datasets of the following data sets

8 References

  1. Data Visualization with R, Robert Kabacoff (Good crisp descriptions of many kinds of graphs, no nonsense book. Available free on the web.)
  1. Wickham and Grolemund, R for Data Science (R Bible. Available free on the web.)
  1. The best stats you’ve ever seen | Hans Rosling

Ask me for help any time!

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