I. Data

Two key questions for analyses of data in statistics are:

  1. Shape?
  2. Outliers/skew?

For shape, we would like to know whether the distribution is normal (bell-shaped). Is it uniform meaning all outcomes are equally likely? Is it some other known distribution like the binomial distribution? The most significant shape for introductory statistics is the normal distribution since parametric statistical tests like the \(z\)-test, the \(t\)-test and ANOVA are built on assumptions of normality. The second question is whether or not skew and outliers exist because we often must treat skewed data and outliers with care and possibly different tools. The first steps of data analysis are to generate numeric descriptions of the data (descriptive statistics) and typical graphical displays of data like histograms, stem plots.

Data Visualization

Data scientists use more robust analytic tools and have
entire courses on data visualization which is the art of
creating visual displays that tell a story about the data.
To understand more about the groundbreaking work in
data science, check out several data visualizations at
the Pew Research Center regarding political beliefs in
the US
. Also check out this blog post where data science
and artwork intersect
or this marketing blog with 16
great examples
of data visualizations.

As data science progresses, more and more exciting
avenues exist for displaying and visualizing data. In this
course, we will provide the basic numeric and graphic
approaches to summarizing data. You’re learning some R
coding along the way. By the end of this course, if
you’re interested, a few hours will be all you will
need to teach yourself to produce some pretty powerful
visualizations of your own with RStudio.

Types of Data

Data come in two varieties: quantitative (numeric) or qualitative (categorical) data. Poker player Pete plays Heads Up tournaments with a $20 buy-in (HU20). These two-player tournaments take less than half an hour where he either loses $20, or wins $19. (The online casino takes a cut of each tournament buy-in, called the ``rake".) Pete’s HU20 win-loss record is category data, a series of W’s and L’s.

Pete’s friend Mandy, a math major with a stats minor at North Georgia, enjoys 6-max NL10, an action-intensive version of No Limit Texas Holdem with a maximum of 6 players at the table rather than the standard 9 or 10 players per table. Mandy’s list of winnings from her past twenty cash game sessions is numeric data.

For numeric data sets, we have a sample of \(n\) data points: \(\left\{x_{1},x_{2},\dots, x_{n}\right\} \in X\).

Parameters and Statistics

In statistics, we use two different sets of symbols to refer to the mean and standard deviation:

\[\begin{array}{c|cc} &\text{Population}&\text{Sample}\\ \hline \text{AVG}&\mu&\bar{x}\\ \text{SD}&\sigma& s\\ \end{array}\]

The population parameters \(\mu\) and \(\sigma\) are rarely known. Much of statistics is about estimating these parameters using the sample statistics \(\bar{x}\) and \(s\) respectively. For example, a poker player’s distribution of winnings (per 100 hands) is a normal distribution. True win rates are not known. Winning poker players often suffer long colds streaks. Over time, things average out. We don’t know Mandy’s average win rate, \(\mu\), but we can take sample of recent sessions and estimate it with \(\bar{x}\).

Initializing RStudio

The Mosaic package was created by statistics instructors to help students learn the coding in R. Commands are streamlined to be more intuitive. Installing Mosaic (Tools: “Install Packages”) must only be done once (and takes 60-90 seconds). After that, we use the library function to load it. Aren’t sure? If you execute the code block below, RStudio will prompt you to install Mosaic if needed.

library(mosaic)

II. Exploratory Data Analysis: Mandy’s Winnings

Mandy’s result from her last 2,000 hands of online poker are shown below. Poker players report win rates in units of BB/100, or big blinds per hundred hands, so she created 20 groups of 100 hands each using random samples of her recent sessions. She plays NL10 which is poker parlance for No Limit Texas Holdem with a big blind (similar to an ante) of a dime. Her first session shown in the data set below is +28 BB/100 which means she won $2.80 over the course of those 100 hands.

\[\begin{array}{|rrrrr|}\hline 28&11&18&35&36\\ 6&-38&14&-19&43\\ -14&-30&-16&-25&0\\ 40&16&-79&3&11\\ \hline \end{array}\]

Let’s load this data set into R and demonstrate how to find these descriptives along with producing some typical graphics. Often, we will import data sets or even generate them with code and randomization, but we can enter the data directly, too. Let’s create a variable \(W\) in RStudio and enter Mandy’s winnings.

W = c( 28, 11, 18, 35, 36, 6, -38, 14, -19, 43, -14, -30, -16, -25, 0, 40, 16, -79, 3, 11)

The operator \(\fbox{c}\) in the code above is the concatenate function which creates a vector from the numbers separated by commas. Once this line executes, the vector W is loaded into R and ready for our basic commands.

1. Descriptive Statistics

Native R does not have a single function that generates all the needed descriptive statistics, but Mosaic does. The library command asks R to load the Mosaic package.

favstats(W)

Standard Descriptives are the statistics all researchers compute for every numeric data set:

\[\begin{array}{lccr} \textbf{Statistic} & \textbf{Symbol} && \textbf{Value}\\ \hline \text{Mean} & \overline x & = & 2\\ \text{Standard Deviation} & s & = & 30.573\\ \text{Sample Size} & n & = & 20 \end{array}\]

The Five Number Summary uses percentiles to divide up the data into four groups called quartiles. 1

\[\begin{array}{lccr} \textbf{Statistic} & \textbf{Symbol} && \textbf{Value}\\ \hline \text{Minimum} & \text{Min} & = & -79\\ \text{25th Percentile} & \text{Q1} & = & -17.5\\ \text{50th Percentile} & \text{Med} & = & 8.5\\ \text{75th Percentile} & \text{Q3} & = & 23\\ \text{Maximum} & \text{Max} & = & 43 \end{array}\]

1.a) Analysis of Descriptives

Two interesting features appear from a glance at these numeric summaries of the data. The most salient detail is that mean and median are quite different. Since the median is 8.5 and the mean is 2, their difference is 6.5 which is about 1/4 of standard deviation.

Robb’s Rule of Thumb

When the mean and median of a data set differ
by more than one-tenth of a standard deviation,
we should expect skew and outliers.

\[|\overline x - \text{med}| \geq s\hspace{3mm}\implies \hspace{3mm}\text{check skew}\]

Not official stats info. No one does this but me.
Just a helpful way of considering if the the
difference between mean and median is significant
enough to result in skew or outliers.

In this example, because the mean is significantly less than the median, we anticipate skew to the left and outliers, if present, to be on the left, which brings up the second detail one should notice. There is a much longer tail to the left shown the Five Number Summary. The Lower Quartile spans the interval \((-79,-17.5)\) or 60+ units. The upper Quartile spans only \((23,43)\) or 20 units. This indicates likely skew to left since the lower Quartile range is much bigger and hence has more room for outliers.

1.b) Standard Deviation and Outliers

The standard deviation can be thought of as a distance metric specific to the data set. Let’s take a moment to discover why. Given the data set \(X=\{1,2,3,6\}\), we have \(n=4\) and \(\bar{x}=3\). For any data point, say, \(x_1=1\), we can compute the directional distance (or deviation) from the mean:

\[\begin{align*}d_{i}&=x_{i}-\bar{x}\implies\\ d_{1}&=x_{1}-\bar{x}\\ &=1-3=-2 \end{align*}\]

For deviations where \(x_{i}<\bar{x}\) (below average), then \(d_i<0\), e.g. a negative deviation. Positive deviations indicate data points that are above average. If we treat the data set \(X\) as a column vector \(\vec{x}\) and calculate the deviation for each component, we have the deviation vector:

\[\vec{d}_x=\begin{pmatrix}x_1-\bar{x}\\x_2-\bar{x}\\ \vdots \\ x_{n}-\bar{x}\end{pmatrix}=\begin{pmatrix}1-3\\2-3\\3-3 \\6-3\end{pmatrix}= \left(\begin{array}{r}-2 \\ -1 \\ 0 \\ 3\end{array}\right)\]

The idea for the calculation of a standard distance (deviation) beings with an application of the Euclidean distance metric to \(\vec{d}_x\):

\[\begin{align*} \left|\vec{d_x}\right|&=\sqrt{(-2)^2+(-1)^2+0^2+3^2}\\ &=\sqrt{4+1+0+9}\\ &=\sqrt{14}\approx3.742\\ \end{align*}\]

This naive idea would suffice if all data sets were the exact same size. However, we need to adjust for sample size. Let the data set \(Y\) be two copies of the data set \(X\), so that \(Y=\{1,2,3,6,1,2,3,6\}\). Note that we have \(\overline{y}=\overline{x}=3\) but with \(n_y=8\) where \(n_x=4\).

Compare \(|\vec{d}_x|=\sqrt{14}\approx 3.742\) to \(|\vec{d}_y|=\sqrt{28}=\sqrt{14}\sqrt{2}\approx5.292\). The magnitutde of the deviation vector for \(Y\) is larger, not because the data have spread out more, but simply because there is more data. To ``standardize" this magnitude or distance, we divide by \(n\) (or \(n-1\)) before we take the square root.

\[\begin{align*} \sigma_x^2&=\frac{|d_x|^2}{n}\\ \sigma_x^2&=\frac{4+1+0+9}{4}\implies\\ \sigma_x&=\sqrt{\frac{14}{4}}\approx1.871 \end{align*}\]

Compare this to the sample standard deviation, where we replace \(n\) with \(n-1\):

\[\begin{align*} s_x^2&=\frac{|d_x|^2}{n-1}\\[.2cm] s_x^2&=\frac{4+1+0+9}{3}\implies\\ s_x&=\sqrt{\frac{14}{3}}\approx2.160 \end{align*}\]

If you’ve read this far and understood something about the standard deviation, congratulations. Enough theory, the next short section shows how to use the standard deviation to check for influential data points.

1.c) Outliers and Standard Deviation

Because the standard deviation measures distances in a data set, we can check for outliers using it. For small data sets, where \(n\leq 50\), any data point more than two standard deviations from the mean may be considered an outlier.

We have the data in R, so let’s use some quick code to determine the cutoff values at which we would consider a data point an outlier. The R functions mean and sd will be needed for their obvious purposes.

right = mean(W) + 2 * sd(W)
left = mean(W) - 2 * sd(W)
left
[1] -59.14693
right
[1] 63.14693

We see that \(x=-79<-59.2\) and is an outlier to the left. No data points are larger than \(63.15\), so there are no outliers to the right.

2. Data Visualization - The Basics

Data science is a ground-breaking field right now, especially when it comes to data visualizations.

2.a) Histograms

Histograms are bar graphs that show the shape of the data set which, hopefully, gives insight into what the underlying distribution might look like.

Histograms have rules. The rules keep data presentations uniform so that it’s more difficult to lie with statistics, a favorite pass time of politicians and media pundits. Researchers don’t wish to lie with statistics. They hope to present their findings to the scientific community without bias. Scientific reports use only histograms with:

  • Single color
  • Entire \(y\)-axis shown
  • Equal bin width
    • All bins / categories intervals of same length, which leads to…
    • All bars have same width
histogram(W)

Histograms are built on frequency tables which groups the entries in the data set into bins or categories, then counts the number of entries in each category. The default histogram above looks wonky. The bins are intervals along the \(x\)-axis, but R has chosen them in a weird way. They should obviously be in units of 10 or 20 given the data range, and centered on something divisible by 10. We can have RStudio create a frequency table based on a bin width of 20, then show how to adjust the histogram to display something more reasonable. We’ll view the frequency table but suppress the R code that generates it, as you won’t be responsible for creating frequency tables in R.

Histogram Option: Type

The type parameter is cosmetic. The \(y\)-axis
units change from density to counts so we can see
how many data points fall into each bin.

We want to force RStudio to use the bin widths we want. The width parameter will force a bin width of our choosing, and the center parameter forces a single bin to be centered at that point. All bins have equal widths so we don’t have to specify the center of the histogram, just the center of one bin. We created a frequency table with a bin width of 20 above, and the center of each bin is an odd multiple of 10.

histogram(W, width = 20, center = 10 , type = "count")

R has a standard way to add headings and labels, so let’s add a few upgrades to our histogram. We use the main parameter to provide a title, and xlab and ylab to label the axes. Let’s also try a bin width of 10. Lastly, we’ll superimpose a bell-curve with the fit parameter asking for a fitted normal distribution overlay.

histogram(W,
     width = 10,
     center = 0,
     fit = "normal",
     main = "Histogram: Mandy's Winnings",
     xlab = "Dollars Won or Lost",
     ylab = "Sessions")

2.b) Box Plots

The standard box plot is easy to generate and is a visualization of the Five Number Summary.

boxplot(W)

Stem and Boxplots

Stem and Boxplot are not Mosaic functions and
thus use the DataFrame$Variable format where a
dollar sign indicates a variable within a data frame.

The box in a boxplot shows the middle the 50% of the data set. The line breaks are at the quartiles, and the tails are shown outside the box so that skew can be detected. We always prefer for the boxplot to check for outliers as is the case here.

Vertical box plots are especially useful when we’re displaying several at once, but the horizontal box plot better parallels the histogram presentation because the \(x\)-axis is the same. The title and labels work the same as before.

boxplot(W, horizontal = TRUE,
     main = "Boxplot: Mandy's Winnings",
     xlab = "Dollars Won or Lost")

Notice the outlier to the left marked by the open dot. We often use the IQR (inner-quartile range) in the Five Number Summary to detect outliers, where IQR is the distance between Q1 and Q3. \[\text{IQR}=\text{Q3}-\text{Q1}\] We calculate the fences as follows:

\[\begin{align*} \text{Upper Fence}&=\text{Q3}+1.5\times\text{IQR}\\ \text{Lower Fence}&=\text{Q1}-1.5\times\text{IQR} \end{align*}\]

Any data points below the Lower Fence are outliers to the left. Any data points above the Upper Fence are outliers to the right. Any data points that land exactly on a fence are not considered outliers.

3. Data Analysis Results for Example 1

The histogram shows an approximate bell-shape. Why? Consider the tallest bar. Then view the tails to either side of it. Both tails clearly exist, and we can consider this data set as having been sampled from a distribution that is approximately normal. The boxplot shows an outlier to left as well as a skew to the left which was also visible in the histogram which had a much longer tail to the left.

Our final word? An approximately normal (bell-shaped) distribution with skew to the left.

III. Other Visualizations

Stem and Boxplots

Stem and Boxplot are not Mosaic functions and
thus use the DataFrame$Variable format where a
dollar sign indicates a variable within a data frame.

Stem Plots

An interesting visualization is the stem-and-leaf plot which uses the numbers in the data set to create a histogram-like display. Often useful, the scaling is important. Try different scales like 1 or 2 and you’ll find the display is hopeless for showing anything about the data.

stem(W, scale = 3)

  The decimal point is 1 digit(s) to the right of the |

  -7 | 9
  -6 | 
  -5 | 
  -4 | 
  -3 | 80
  -2 | 5
  -1 | 964
  -0 | 
   0 | 036
   1 | 11468
   2 | 8
   3 | 56
   4 | 03

When scaled properly, however, we get a end up with a histogram (if we rotate our paper 90 degrees). We can read off all the values in the data set which makes finding the Five Number Summary pretty easy. For more details about creating and interpretting stem plots check out this Youtube video.

Two disadvantages of stem plots should be obvious. First, with some data sets we cannot get them scaled properly. The requirement that the bins be equally spaced limits how we can proceed since we have only ten digits. Second, big data sets defy stem plots. Even if a machine can create it, it’s not readable if there’s more than a couple hundred data points.

Density Plots

The density plot is a hybrid. It shows the data points along the \(x\)-axis and an envelope above them showing a histogram-like shape. The taller the envelope gets, the more closely the data are clumped together right below it. Where the data points are spread out, the envelope curve is near the \(x\)-axis.

densityplot(W)

This is perhaps the best visualization of the skew to the left. We can also see that Mandy tends to win a lot of small amounts, with many of the data points between 0 and 20. A few of the losses are huge which leads to longer tail to the left.

IV. Visualization Example: Old Faithful Geyser

R has preloaded data sets like faithful, a data frame with two variables: eruptions and waiting. Both are time variables. Eruptions is number of seconds the eruptions lasted. Waiting is the time interval between eruptions. By just typing the name of the data frame, R will print out a preview.

faithful

Note the 272 rows refers to 272 eruption-waiting pairs of values, so both numeric data sets have 272 entries.

Two Variable Plots

One might wonder if longer waiting times correlate with longer eruptions. Perhaps more pressure builds up, then when released the eruptions last longer. Let’s check a scatter plot. The first argument is the form \(y\sim x\). The \(y\)-variable is the dependent variable, the \(x\)-variable independent. In this setup, we are implicitly suggesting that the variable eruptions depends upon the variable waiting. If we reverse the order, we reverse the implicit dependence.

xyplot(eruptions ~ waiting, data = faithful)

There does seem to be a pattern. A quick of the correlation verifies there is a strong, positive correlation.

cor(eruptions ~ waiting, data = faithful)
[1] 0.9008112

We will discuss correlation and regression later in the course, but keep in mind that exploratory data analysis often involves studying related variables in data sets, both together and separately.

Data Analysis: Old Faithful Waiting Times

Let’s start with the numerics. When using a data frame – a data object with more than one variable – we first specify the variable we want to analyze, then the data frame where it will be found. The reason for the tilde (~) will be clear shortly.

favstats(~ waiting, data = faithful)

By Robb’s Rule of Thumb, the mean is significantly less than the median, so we expect skew and outliers to the left. However, the lower and upper quartiles of the Five Number Summary are intervals with roughly the same length, 15 vs. 14.

histogram(~ waiting, data = faithful)

This appears to be bimodal data, a histogram with two peaks. While there a large cluster of values around 80 seconds, there is a secondary clustering around 55. The bimodal shape likely accounts for the difference in mean and median, rather than outliers to the left (though they may still exist).

The boxplot function will produce a boxplot for every variable in the data frame by default.

boxplot(faithful, horizontal = TRUE)

Notice there are no outliers, so our guess about the bimodal tendencies causing the disparity between mean and median seems justified. The density plot is instructive, too.

densityplot(~ waiting, data = faithful)

Data Analysis: Old Faithful Eruption Duration Times

The mean appears to be significantly less than the median (rule of thumb), so we expect skew and outliers to the left.

favstats(~ eruptions, data = faithful)

Again, the Five Number Summary seems to belie this analysis, so perhaps there is a bimodal pattern in eruptions, too.

histogram(~ eruptions, data = faithful)

The bimodal pattern is even more stark. While the waiting histogram might still have qualified in a loose sense as approximately bell-shaped, these data surely do not. The box plots above showed no outliers in either data set. Again, the density plot shows the pattern clearly.

densityplot(~ waiting, data = faithful)

What have we learned? We have two bimodal variable that are strongly correlated. Hopefully we have also learned that exploratory data analysis (EDA) is just that - exploring. We don’t typically find cut-and-dried answers. Real-world data is real messy. We need flexible tools to analyze many varieties of data and to discover patterns. We need minds as flexible as our tools because EDA is often more art than science.

V. Data Analysis Example: Births and Day of the Year

Consider how many babies were born the different days of the year. Several patterns are apparent, but what is the cause? 2.

Births78
xyplot(births ~ day_of_year, data=Births78)

Think about what this means. Perhaps some data visualization with color coding will help.

xyplot(births ~ day_of_year, data = Births78, 
       groups = wday,
       main = "Births vs. Day of Year for 1978",
       xlab = "Day of Year",
       ylab = "Births"
       )

VI. Exercises

  1. Using the built-in R data frame ChickWeight which examines weight vs age of chicks on different diets, conduct an analysis of the variable weight. Include all relevant plots, and include titles and axis labels for your histogram and density plot.

Built-in R Datasets

R has dozens of built-in data frames like iris.
Type variable name only and execute code block.
Output shows headers, variable names and
observations. Search variable name in help tab
of bottom-right panel for details.

  1. Using the built-in R data frame InsectSprays which examines the number of insects in an area depending upon type of insecticide used, conduct an analysis of the variable count. Include all relevant plots, and include titles and axis labels for your histogram and density plot.

  2. Use the built-in R data frame cars which compares the numeric variables speed measured in miles per hours (mph) and stopping distance (variable is dist, measured in feet). The data is from the 1920’s, by the way. Create an xyplot for the two variables, and include axis labels on your plot.

  3. Using the built-in R data frame mtcars which includes miles per gallon and ten other variables for 32 different models in 1974, create an xyplot for miles per gallon (mpg variable) vs. displacement (disp variable) using a grouping variable of transmission type, automatic vs. manual (am).

  4. Using the built-in R data frame Dimes which compares the mass of a dime to the year in which is was minted, conduct an analysis of the variable mass. Include all relevant plots, and include titles and axis labels for your histogram and density plot.


  1. Quartiles refers both the four groups created and to the values Q1, Q2 and Q3 the are the cut points for creating the groups.↩︎

  2. Idea and code from Start Teaching with R by Prium, Horton and Kaplan. See Project Mosaic website↩︎

LS0tDQp0aXRsZTogIkV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMiDQpzdWJ0aXRsZTogVU5HIE1BVEggMzM1MCAob25saW5lKQ0KYXV0aG9yOiBSb2JiIFNpbm4NCmRhdGU6IEp1bHkgMjAyMA0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyI+SS4gRGF0YTwvc3Bhbj4NCg0KVHdvIGtleSBxdWVzdGlvbnMgZm9yIGFuYWx5c2VzIG9mIGRhdGEgaW4gc3RhdGlzdGljcyBhcmU6DQoNCjEuIFNoYXBlPw0KMi4gT3V0bGllcnMvc2tldz8NCg0KRm9yIHNoYXBlLCB3ZSB3b3VsZCBsaWtlIHRvIGtub3cgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIGlzICoqbm9ybWFsKiogKGJlbGwtc2hhcGVkKS4gSXMgaXQgKnVuaWZvcm0qIG1lYW5pbmcgYWxsIG91dGNvbWVzIGFyZSBlcXVhbGx5IGxpa2VseT8gSXMgaXQgc29tZSBvdGhlciBrbm93biBkaXN0cmlidXRpb24gbGlrZSB0aGUgYmlub21pYWwgZGlzdHJpYnV0aW9uPyBUaGUgbW9zdCBzaWduaWZpY2FudCBzaGFwZSBmb3IgaW50cm9kdWN0b3J5IHN0YXRpc3RpY3MgaXMgdGhlICoqbm9ybWFsIGRpc3RyaWJ1dGlvbioqIHNpbmNlIHBhcmFtZXRyaWMgc3RhdGlzdGljYWwgdGVzdHMgbGlrZSB0aGUgJHokLXRlc3QsIHRoZSAkdCQtdGVzdCBhbmQgQU5PVkEgYXJlIGJ1aWx0IG9uIGFzc3VtcHRpb25zIG9mIG5vcm1hbGl0eS4gVGhlIHNlY29uZCBxdWVzdGlvbiBpcyB3aGV0aGVyIG9yIG5vdCBza2V3IGFuZCBvdXRsaWVycyBleGlzdCBiZWNhdXNlIHdlIG9mdGVuIG11c3QgdHJlYXQgc2tld2VkIGRhdGEgYW5kIG91dGxpZXJzIHdpdGggY2FyZSBhbmQgcG9zc2libHkgZGlmZmVyZW50IHRvb2xzLiBUaGUgZmlyc3Qgc3RlcHMgb2YgZGF0YSBhbmFseXNpcyBhcmUgdG8gZ2VuZXJhdGUgbnVtZXJpYyBkZXNjcmlwdGlvbnMgb2YgdGhlIGRhdGEgKGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MpIGFuZCB0eXBpY2FsIGdyYXBoaWNhbCBkaXNwbGF5cyBvZiBkYXRhIGxpa2UgaGlzdG9ncmFtcywgc3RlbSBwbG90cy4gDQoNCjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0OyBtYXJnaW46IDhweDsgYm9yZGVyOjJweCBibGFjayBzb2xpZDsgcGFkZGluZzogMHB4IDEwcHggNXB4Ij4NCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkRhdGEgVmlzdWFsaXphdGlvbjwvc3Bhbj4NCkRhdGEgc2NpZW50aXN0cyB1c2UgbW9yZSByb2J1c3QgYW5hbHl0aWMgdG9vbHMgYW5kIGhhdmU8L2JyPg0KZW50aXJlIGNvdXJzZXMgb24gZGF0YSB2aXN1YWxpemF0aW9uIHdoaWNoIGlzIHRoZSBhcnQgb2Y8L2JyPg0KY3JlYXRpbmcgdmlzdWFsIGRpc3BsYXlzIHRoYXQgdGVsbCBhIHN0b3J5IGFib3V0IHRoZSBkYXRhLjwvYnI+DQpUbyB1bmRlcnN0YW5kIG1vcmUgYWJvdXQgdGhlIGdyb3VuZGJyZWFraW5nIHdvcmsgaW48L2JyPg0KZGF0YSBzY2llbmNlLCBjaGVjayBvdXQgc2V2ZXJhbCBkYXRhIHZpc3VhbGl6YXRpb25zIGF0PC9icj4NCnRoZSBQZXcgUmVzZWFyY2ggQ2VudGVyIHJlZ2FyZGluZyA8YSBocmVmID0gaHR0cHM6Ly93d3cucGV3cmVzZWFyY2gub3JnL2ZhY3QtdGFuay8yMDE0LzEyLzI5L291ci1mYXZvcml0ZS1wZXctcmVzZWFyY2gtY2VudGVyLWRhdGEtdmlzdWFsaXphdGlvbnMtZnJvbS0yMDE0Lz4gcG9saXRpY2FsIGJlbGllZnMgaW48L2JyPg0KdGhlIFVTPC9hPi4gQWxzbyBjaGVjayBvdXQgdGhpcyA8YSBocmVmID0gaHR0cHM6Ly92aXNtZS5jby9ibG9nL2Jlc3QtZGF0YS12aXN1YWxpemF0aW9ucy8+YmxvZyBwb3N0PC9hPiB3aGVyZSA8YSBocmVmID0gaHR0cHM6Ly92aXNtZS5jby9ibG9nL2Jlc3QtZGF0YS12aXN1YWxpemF0aW9ucy8+ZGF0YSBzY2llbmNlPC9icj4NCmFuZCBhcnR3b3JrIGludGVyc2VjdDwvYT4gb3IgdGhpcyBtYXJrZXRpbmcgYmxvZyB3aXRoIDxhIGhyZWYgPSBodHRwczovL2Jsb2cuaHVic3BvdC5jb20vbWFya2V0aW5nL2dyZWF0LWRhdGEtdmlzdWFsaXphdGlvbi1leGFtcGxlcz4xNiA8L2JyPg0KZ3JlYXQgZXhhbXBsZXM8L2E+IG9mIGRhdGEgdmlzdWFsaXphdGlvbnMuPC9icj48L2JyPg0KQXMgZGF0YSBzY2llbmNlIHByb2dyZXNzZXMsIG1vcmUgYW5kIG1vcmUgZXhjaXRpbmc8L2JyPg0KYXZlbnVlcyBleGlzdCBmb3IgZGlzcGxheWluZyBhbmQgdmlzdWFsaXppbmcgZGF0YS4gSW4gdGhpczwvYnI+DQpjb3Vyc2UsIHdlIHdpbGwgcHJvdmlkZSB0aGUgYmFzaWMgbnVtZXJpYyBhbmQgZ3JhcGhpYzwvYnI+DQphcHByb2FjaGVzIHRvIHN1bW1hcml6aW5nIGRhdGEuIFlvdSdyZSBsZWFybmluZyBzb21lIFI8L2JyPg0KY29kaW5nIGFsb25nIHRoZSB3YXkuIEJ5IHRoZSBlbmQgb2YgdGhpcyBjb3Vyc2UsIGlmPC9icj4NCnlvdSdyZSBpbnRlcmVzdGVkLCBhIGZldyBob3VycyB3aWxsIGJlIGFsbCB5b3Ugd2lsbDwvYnI+DQpuZWVkIHRvIHRlYWNoIHlvdXJzZWxmIHRvIHByb2R1Y2Ugc29tZSBwcmV0dHkgcG93ZXJmdWw8L2JyPg0KdmlzdWFsaXphdGlvbnMgb2YgeW91ciBvd24gd2l0aCBSU3R1ZGlvLjwvZGl2Pg0KDQojIyBUeXBlcyBvZiBEYXRhDQpEYXRhIGNvbWUgaW4gdHdvIHZhcmlldGllczogKipxdWFudGl0YXRpdmUqKiAobnVtZXJpYykgb3IgKipxdWFsaXRhdGl2ZSoqIChjYXRlZ29yaWNhbCkgZGF0YS4gUG9rZXIgcGxheWVyIFBldGUgcGxheXMgSGVhZHMgVXAgdG91cm5hbWVudHMgd2l0aCBhIFwkMjAgYnV5LWluIChIVTIwKS4gVGhlc2UgdHdvLXBsYXllciB0b3VybmFtZW50cyB0YWtlIGxlc3MgdGhhbiBoYWxmIGFuIGhvdXIgd2hlcmUgaGUgZWl0aGVyIGxvc2VzIFwkMjAsIG9yIHdpbnMgXCQxOS4gKFRoZSBvbmxpbmUgY2FzaW5vIHRha2VzIGEgY3V0IG9mIGVhY2ggdG91cm5hbWVudCBidXktaW4sIGNhbGxlZCB0aGUgYGByYWtlIi4pIFBldGUncyBIVTIwIHdpbi1sb3NzIHJlY29yZCBpcyAqY2F0ZWdvcnkgZGF0YSosIGEgc2VyaWVzIG9mIFcncyBhbmQgTCdzLg0KDQpQZXRlJ3MgZnJpZW5kIE1hbmR5LCBhIG1hdGggbWFqb3Igd2l0aCBhIHN0YXRzIG1pbm9yIGF0IE5vcnRoIEdlb3JnaWEsIGVuam95cyA2LW1heCBOTDEwLCBhbiBhY3Rpb24taW50ZW5zaXZlIHZlcnNpb24gb2YgTm8gTGltaXQgVGV4YXMgSG9sZGVtIHdpdGggYSBtYXhpbXVtIG9mIDYgcGxheWVycyBhdCB0aGUgdGFibGUgcmF0aGVyIHRoYW4gdGhlIHN0YW5kYXJkIDkgb3IgMTAgcGxheWVycyBwZXIgdGFibGUuIE1hbmR5J3MgbGlzdCBvZiB3aW5uaW5ncyBmcm9tIGhlciBwYXN0IHR3ZW50eSBjYXNoIGdhbWUgc2Vzc2lvbnMgaXMgKm51bWVyaWMgZGF0YSouDQoNCkZvciBudW1lcmljIGRhdGEgc2V0cywgd2UgaGF2ZSBhICoqc2FtcGxlKiogb2YgJG4kIGRhdGEgcG9pbnRzOiAkXGxlZnRce3hfezF9LHhfezJ9LFxkb3RzLCB4X3tufVxyaWdodFx9IFxpbiBYJC4NCg0KIyMgUGFyYW1ldGVycyBhbmQgU3RhdGlzdGljcw0KDQpJbiBzdGF0aXN0aWNzLCB3ZSB1c2UgdHdvIGRpZmZlcmVudCBzZXRzIG9mIHN5bWJvbHMgdG8gcmVmZXIgdG8gdGhlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbjoNCg0KJCRcYmVnaW57YXJyYXl9e2N8Y2N9DQomXHRleHR7UG9wdWxhdGlvbn0mXHRleHR7U2FtcGxlfVxcIFxobGluZQ0KXHRleHR7QVZHfSZcbXUmXGJhcnt4fVxcDQpcdGV4dHtTRH0mXHNpZ21hJiBzXFwNClxlbmR7YXJyYXl9JCQNCg0KVGhlIHBvcHVsYXRpb24gcGFyYW1ldGVycyAkXG11JCBhbmQgJFxzaWdtYSQgYXJlIHJhcmVseSBrbm93bi4gTXVjaCBvZiBzdGF0aXN0aWNzIGlzIGFib3V0IGVzdGltYXRpbmcgdGhlc2UgcGFyYW1ldGVycyB1c2luZyB0aGUgc2FtcGxlIHN0YXRpc3RpY3MgJFxiYXJ7eH0kIGFuZCAkcyQgcmVzcGVjdGl2ZWx5LiBGb3IgZXhhbXBsZSwgYSBwb2tlciBwbGF5ZXIncyBkaXN0cmlidXRpb24gb2Ygd2lubmluZ3MgKHBlciAxMDAgaGFuZHMpIGlzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVHJ1ZSB3aW4gcmF0ZXMgYXJlIG5vdCBrbm93bi4gV2lubmluZyBwb2tlciBwbGF5ZXJzIG9mdGVuIHN1ZmZlciBsb25nIGNvbGRzIHN0cmVha3MuIE92ZXIgdGltZSwgdGhpbmdzIGF2ZXJhZ2Ugb3V0LiBXZSBkb24ndCBrbm93IE1hbmR5J3MgYXZlcmFnZSB3aW4gcmF0ZSwgJFxtdSQsIGJ1dCB3ZSBjYW4gdGFrZSBzYW1wbGUgb2YgcmVjZW50IHNlc3Npb25zIGFuZCBlc3RpbWF0ZSBpdCB3aXRoICRcYmFye3h9JC4NCg0KPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQ7IG1hcmdpbjogOHB4OyBib3JkZXI6MnB4IGJsYWNrIHNvbGlkOyBwYWRkaW5nOiAwcHggMTBweCA1cHgiPg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+SW5pdGlhbGl6aW5nIFJTdHVkaW88L3NwYW4+DQpUaGUgKipNb3NhaWMqKiBwYWNrYWdlIHdhcyBjcmVhdGVkIGJ5IHN0YXRpc3RpY3MgaW5zdHJ1Y3RvcnMgdG8gaGVscCBzdHVkZW50cyBsZWFybiB0aGUgY29kaW5nIGluIFIuIENvbW1hbmRzIGFyZSBzdHJlYW1saW5lZCB0byBiZSBtb3JlIGludHVpdGl2ZS4gSW5zdGFsbGluZyAqKk1vc2FpYyoqIChUb29sczogIkluc3RhbGwgUGFja2FnZXMiKSBtdXN0IG9ubHkgYmUgZG9uZSBvbmNlIChhbmQgdGFrZXMgNjAtOTAgc2Vjb25kcykuIEFmdGVyIHRoYXQsIHdlIHVzZSB0aGUgKipsaWJyYXJ5KiogZnVuY3Rpb24gdG8gbG9hZCBpdC4gQXJlbid0IHN1cmU/IElmIHlvdSBleGVjdXRlIHRoZSBjb2RlIGJsb2NrIGJlbG93LCBSU3R1ZGlvIHdpbGwgcHJvbXB0IHlvdSB0byBpbnN0YWxsICoqTW9zYWljKiogaWYgbmVlZGVkLg0KYGBge3J9DQpsaWJyYXJ5KG1vc2FpYykNCmBgYA0KPC9kaXY+DQoNCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsdWU7Ij5JSS4gRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpczogTWFuZHkncyBXaW5uaW5nczwvc3Bhbj4NCg0KTWFuZHkncyByZXN1bHQgZnJvbSBoZXIgbGFzdCAyLDAwMCBoYW5kcyBvZiBvbmxpbmUgcG9rZXIgYXJlIHNob3duIGJlbG93LiBQb2tlciBwbGF5ZXJzIHJlcG9ydCB3aW4gcmF0ZXMgaW4gdW5pdHMgb2YgQkIvMTAwLCBvciBiaWcgYmxpbmRzIHBlciBodW5kcmVkIGhhbmRzLCBzbyBzaGUgY3JlYXRlZCAyMCBncm91cHMgb2YgMTAwIGhhbmRzIGVhY2ggdXNpbmcgcmFuZG9tIHNhbXBsZXMgb2YgaGVyIHJlY2VudCBzZXNzaW9ucy4gU2hlIHBsYXlzIE5MMTAgd2hpY2ggaXMgcG9rZXIgcGFybGFuY2UgZm9yIE5vIExpbWl0IFRleGFzIEhvbGRlbSB3aXRoIGEgYmlnIGJsaW5kIChzaW1pbGFyIHRvIGFuIGFudGUpIG9mIGEgZGltZS4gSGVyIGZpcnN0IHNlc3Npb24gc2hvd24gaW4gdGhlIGRhdGEgc2V0IGJlbG93IGlzICsyOCBCQi8xMDAgd2hpY2ggbWVhbnMgc2hlIHdvbiBcJDIuODAgb3ZlciB0aGUgY291cnNlIG9mIHRob3NlIDEwMCBoYW5kcy4NCg0KJCRcYmVnaW57YXJyYXl9e3xycnJycnx9XGhsaW5lDQoyOCYxMSYxOCYzNSYzNlxcDQo2Ji0zOCYxNCYtMTkmNDNcXA0KLTE0Ji0zMCYtMTYmLTI1JjBcXA0KNDAmMTYmLTc5JjMmMTFcXCBcaGxpbmUNClxlbmR7YXJyYXl9JCQNCg0KTGV0J3MgbG9hZCB0aGlzIGRhdGEgc2V0IGludG8gUiBhbmQgZGVtb25zdHJhdGUgaG93IHRvIGZpbmQgdGhlc2UgZGVzY3JpcHRpdmVzIGFsb25nIHdpdGggcHJvZHVjaW5nIHNvbWUgdHlwaWNhbCBncmFwaGljcy4gT2Z0ZW4sIHdlIHdpbGwgaW1wb3J0IGRhdGEgc2V0cyBvciBldmVuIGdlbmVyYXRlIHRoZW0gd2l0aCBjb2RlIGFuZCByYW5kb21pemF0aW9uLCBidXQgd2UgY2FuIGVudGVyIHRoZSBkYXRhIGRpcmVjdGx5LCB0b28uIExldCdzIGNyZWF0ZSBhIHZhcmlhYmxlICRXJCBpbiBSU3R1ZGlvIGFuZCBlbnRlciBNYW5keSdzIHdpbm5pbmdzLiANCg0KYGBge3J9DQpXID0gYyggMjgsIDExLCAxOCwgMzUsIDM2LCA2LCAtMzgsIDE0LCAtMTksIDQzLCAtMTQsIC0zMCwgLTE2LCAtMjUsIDAsIDQwLCAxNiwgLTc5LCAzLCAxMSkNCmBgYA0KVGhlIG9wZXJhdG9yICRcZmJveHtjfSQgaW4gdGhlIGNvZGUgYWJvdmUgaXMgdGhlIGNvbmNhdGVuYXRlIGZ1bmN0aW9uIHdoaWNoIGNyZWF0ZXMgYSB2ZWN0b3IgZnJvbSB0aGUgbnVtYmVycyBzZXBhcmF0ZWQgYnkgY29tbWFzLiBPbmNlIHRoaXMgbGluZSBleGVjdXRlcywgdGhlIHZlY3RvciAqKlcqKiBpcyBsb2FkZWQgaW50byBSIGFuZCByZWFkeSBmb3Igb3VyIGJhc2ljIGNvbW1hbmRzLg0KDQojIyAxLiBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpOYXRpdmUgUiBkb2VzIG5vdCBoYXZlIGEgc2luZ2xlIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGFsbCB0aGUgbmVlZGVkIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MsIGJ1dCBNb3NhaWMgZG9lcy4gVGhlICoqbGlicmFyeSoqIGNvbW1hbmQgYXNrcyBSIHRvIGxvYWQgdGhlIE1vc2FpYyBwYWNrYWdlLg0KDQpgYGB7cn0NCmZhdnN0YXRzKFcpDQpgYGANCg0KKipTdGFuZGFyZCBEZXNjcmlwdGl2ZXMqKiBhcmUgdGhlIHN0YXRpc3RpY3MgYWxsIHJlc2VhcmNoZXJzIGNvbXB1dGUgZm9yIGV2ZXJ5IG51bWVyaWMgZGF0YSBzZXQ6DQoNCiQkXGJlZ2lue2FycmF5fXtsY2NyfQ0KICBcdGV4dGJme1N0YXRpc3RpY30gJiBcdGV4dGJme1N5bWJvbH0gJiYgXHRleHRiZntWYWx1ZX1cXCBcaGxpbmUNCiAgXHRleHR7TWVhbn0gJiBcb3ZlcmxpbmUgeCAmID0gJiAgYHIgcGFzdGUobWVhbihXKSlgXFwNCiAgXHRleHR7U3RhbmRhcmQgRGV2aWF0aW9ufSAmIHMgJiA9ICYgYHIgcGFzdGUocm91bmQoc2QoVyksMykpYFxcDQogIFx0ZXh0e1NhbXBsZSBTaXplfSAmIG4gJiA9ICYgYHIgcGFzdGUobGVuZ3RoKFcpKWANClxlbmR7YXJyYXl9JCQNCg0KVGhlICoqRml2ZSBOdW1iZXIgU3VtbWFyeSoqIHVzZXMgcGVyY2VudGlsZXMgdG8gZGl2aWRlIHVwIHRoZSBkYXRhIGludG8gZm91ciBncm91cHMgY2FsbGVkIHF1YXJ0aWxlcy4gXltRdWFydGlsZXMgcmVmZXJzIGJvdGggdGhlIGZvdXIgZ3JvdXBzIGNyZWF0ZWQgYW5kIHRvIHRoZSB2YWx1ZXMgUTEsIFEyIGFuZCBRMyB0aGUgYXJlIHRoZSBjdXQgcG9pbnRzIGZvciBjcmVhdGluZyB0aGUgZ3JvdXBzLl0NCg0KJCRcYmVnaW57YXJyYXl9e2xjY3J9DQogIFx0ZXh0YmZ7U3RhdGlzdGljfSAmIFx0ZXh0YmZ7U3ltYm9sfSAmJiBcdGV4dGJme1ZhbHVlfVxcIFxobGluZQ0KICBcdGV4dHtNaW5pbXVtfSAmIFx0ZXh0e01pbn0gJiA9ICYgYHIgcGFzdGUoZml2ZW51bShXKVsxXSlgXFwNCiAgXHRleHR7MjV0aCBQZXJjZW50aWxlfSAmIFx0ZXh0e1ExfSAgJiA9ICYgYHIgcGFzdGUoZml2ZW51bShXKVsyXSlgXFwNCiAgXHRleHR7NTB0aCBQZXJjZW50aWxlfSAmIFx0ZXh0e01lZH0gICYgPSAmIGByIHBhc3RlKGZpdmVudW0oVylbM10pYFxcDQogIFx0ZXh0ezc1dGggUGVyY2VudGlsZX0gJiBcdGV4dHtRM30gICYgPSAmIGByIHBhc3RlKGZpdmVudW0oVylbNF0pYFxcDQogIFx0ZXh0e01heGltdW19ICYgXHRleHR7TWF4fSAgJiA9ICYgYHIgcGFzdGUoZml2ZW51bShXKVs1XSlgDQpcZW5ke2FycmF5fSQkDQoNCiMjIyAxLmEpIEFuYWx5c2lzIG9mIERlc2NyaXB0aXZlcw0KVHdvIGludGVyZXN0aW5nIGZlYXR1cmVzIGFwcGVhciBmcm9tIGEgZ2xhbmNlIGF0IHRoZXNlIG51bWVyaWMgc3VtbWFyaWVzIG9mIHRoZSBkYXRhLiBUaGUgbW9zdCBzYWxpZW50IGRldGFpbCBpcyB0aGF0IG1lYW4gYW5kIG1lZGlhbiBhcmUgcXVpdGUgZGlmZmVyZW50LiBTaW5jZSB0aGUgbWVkaWFuIGlzIGByIHBhc3RlKG1lZGlhbihXKSlgIGFuZCB0aGUgbWVhbiBpcyBgciBwYXN0ZShtZWFuKFcpKWAsIHRoZWlyIGRpZmZlcmVuY2UgaXMgYHIgcGFzdGUgKG1lZGlhbihXKS1tZWFuKFcpKWAgd2hpY2ggaXMgYWJvdXQgMS80IG9mIHN0YW5kYXJkIGRldmlhdGlvbi4gDQoNCjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0OyBtYXJnaW46IDhweDsgYm9yZGVyOjJweCBibGFjayBzb2xpZDsgcGFkZGluZzogMHB4IDEwcHggNXB4Ij4NCiMjIyBSb2JiJ3MgUnVsZSBvZiBUaHVtYiANCldoZW4gdGhlIG1lYW4gYW5kIG1lZGlhbiBvZiBhIGRhdGEgc2V0IGRpZmZlcjwvYnI+DQpieSBtb3JlIHRoYW4gb25lLXRlbnRoIG9mIGEgc3RhbmRhcmQgZGV2aWF0aW9uLDwvYnI+DQp3ZSBzaG91bGQgZXhwZWN0IHNrZXcgYW5kIG91dGxpZXJzLiANCg0KJCR8XG92ZXJsaW5lIHggLSBcdGV4dHttZWR9fCBcZ2VxIHNcaHNwYWNlezNtbX1caW1wbGllcyBcaHNwYWNlezNtbX1cdGV4dHtjaGVjayBza2V3fSQkDQoNCk5vdCBvZmZpY2lhbCBzdGF0cyBpbmZvLiBObyBvbmUgZG9lcyB0aGlzIGJ1dCBtZS48L2JyPg0KSnVzdCBhIGhlbHBmdWwgd2F5IG9mIGNvbnNpZGVyaW5nIGlmIHRoZSB0aGU8L2JyPg0KZGlmZmVyZW5jZSBiZXR3ZWVuIG1lYW4gYW5kIG1lZGlhbiBpcyBzaWduaWZpY2FudDwvYnI+DQplbm91Z2ggdG8gcmVzdWx0IGluIHNrZXcgb3Igb3V0bGllcnMuDQo8L2Rpdj4NCjxwPg0KSW4gdGhpcyBleGFtcGxlLCBiZWNhdXNlIHRoZSBtZWFuIGlzIHNpZ25pZmljYW50bHkgbGVzcyB0aGFuIHRoZSBtZWRpYW4sIHdlIGFudGljaXBhdGUgc2tldyB0byB0aGUgbGVmdCBhbmQgb3V0bGllcnMsIGlmIHByZXNlbnQsIHRvIGJlIG9uIHRoZSBsZWZ0LCB3aGljaCBicmluZ3MgdXAgdGhlIHNlY29uZCBkZXRhaWwgb25lIHNob3VsZCBub3RpY2UuIFRoZXJlIGlzIGEgbXVjaCBsb25nZXIgdGFpbCB0byB0aGUgbGVmdCBzaG93biB0aGUgRml2ZSBOdW1iZXIgU3VtbWFyeS4gVGhlIExvd2VyIFF1YXJ0aWxlIHNwYW5zIHRoZSBpbnRlcnZhbCAkKC03OSwtMTcuNSkkIG9yIDYwKyB1bml0cy4gVGhlIHVwcGVyIFF1YXJ0aWxlIHNwYW5zIG9ubHkgJCgyMyw0MykkIG9yIDIwIHVuaXRzLiBUaGlzIGluZGljYXRlcyBsaWtlbHkgc2tldyB0byBsZWZ0IHNpbmNlIHRoZSBsb3dlciBRdWFydGlsZSByYW5nZSBpcyBtdWNoIGJpZ2dlciBhbmQgaGVuY2UgaGFzIG1vcmUgcm9vbSBmb3Igb3V0bGllcnMuDQoNCiMjIyAxLmIpIFN0YW5kYXJkIERldmlhdGlvbiBhbmQgT3V0bGllcnMNClRoZSBzdGFuZGFyZCBkZXZpYXRpb24gY2FuIGJlIHRob3VnaHQgb2YgYXMgYSBkaXN0YW5jZSBtZXRyaWMgc3BlY2lmaWMgdG8gdGhlIGRhdGEgc2V0LiBMZXQncyB0YWtlIGEgbW9tZW50IHRvIGRpc2NvdmVyIHdoeS4gR2l2ZW4gdGhlIGRhdGEgc2V0ICRYPVx7MSwyLDMsNlx9JCwgd2UgaGF2ZSAkbj00JCBhbmQgJFxiYXJ7eH09MyQuIEZvciBhbnkgZGF0YSBwb2ludCwgc2F5LCAkeF8xPTEkLCB3ZSBjYW4gY29tcHV0ZSB0aGUgZGlyZWN0aW9uYWwgZGlzdGFuY2UgKG9yICoqZGV2aWF0aW9uKiopIGZyb20gdGhlIG1lYW46DQo8L3A+DQoNClxiZWdpbnthbGlnbip9ZF97aX0mPXhfe2l9LVxiYXJ7eH1caW1wbGllc1xcDQpkX3sxfSY9eF97MX0tXGJhcnt4fVxcDQomPTEtMz0tMg0KXGVuZHthbGlnbip9DQoNCkZvciBkZXZpYXRpb25zIHdoZXJlICR4X3tpfTxcYmFye3h9JCAoYmVsb3cgYXZlcmFnZSksIHRoZW4gJGRfaTwwJCwgZS5nLiBhIG5lZ2F0aXZlIGRldmlhdGlvbi4gUG9zaXRpdmUgZGV2aWF0aW9ucyBpbmRpY2F0ZSBkYXRhIHBvaW50cyB0aGF0IGFyZSBhYm92ZSBhdmVyYWdlLiBJZiB3ZSB0cmVhdCB0aGUgZGF0YSBzZXQgJFgkIGFzIGEgY29sdW1uIHZlY3RvciAkXHZlY3t4fSQgYW5kIGNhbGN1bGF0ZSB0aGUgZGV2aWF0aW9uIGZvciBlYWNoIGNvbXBvbmVudCwgd2UgaGF2ZSB0aGUgZGV2aWF0aW9uIHZlY3RvcjoNCg0KJCRcdmVje2R9X3g9XGJlZ2lue3BtYXRyaXh9eF8xLVxiYXJ7eH1cXHhfMi1cYmFye3h9XFwgXHZkb3RzIFxcIHhfe259LVxiYXJ7eH1cZW5ke3BtYXRyaXh9PVxiZWdpbntwbWF0cml4fTEtM1xcMi0zXFwzLTMgXFw2LTNcZW5ke3BtYXRyaXh9PQ0KXGxlZnQoXGJlZ2lue2FycmF5fXtyfS0yIFxcIC0xIFxcIDAgXFwgM1xlbmR7YXJyYXl9XHJpZ2h0KSQkDQoNClRoZSBpZGVhIGZvciB0aGUgY2FsY3VsYXRpb24gb2YgYSBzdGFuZGFyZCBkaXN0YW5jZSAoZGV2aWF0aW9uKSBiZWluZ3Mgd2l0aCBhbiBhcHBsaWNhdGlvbiBvZiB0aGUgRXVjbGlkZWFuIGRpc3RhbmNlIG1ldHJpYyB0byAkXHZlY3tkfV94JDoNCg0KXGJlZ2lue2FsaWduKn0NClxsZWZ0fFx2ZWN7ZF94fVxyaWdodHwmPVxzcXJ0eygtMileMisoLTEpXjIrMF4yKzNeMn1cXA0KJj1cc3FydHs0KzErMCs5fVxcDQomPVxzcXJ0ezE0fVxhcHByb3gzLjc0MlxcDQpcZW5ke2FsaWduKn0NCg0KVGhpcyBuYWl2ZSBpZGVhIHdvdWxkIHN1ZmZpY2UgaWYgYWxsIGRhdGEgc2V0cyB3ZXJlIHRoZSBleGFjdCBzYW1lIHNpemUuIEhvd2V2ZXIsIHdlIG5lZWQgdG8gYWRqdXN0IGZvciBzYW1wbGUgc2l6ZS4gTGV0IHRoZSBkYXRhIHNldCAkWSQgYmUgdHdvIGNvcGllcyBvZiB0aGUgZGF0YSBzZXQgJFgkLCBzbyB0aGF0ICRZPVx7MSwyLDMsNiwxLDIsMyw2XH0kLiBOb3RlIHRoYXQgd2UgaGF2ZSAkXG92ZXJsaW5le3l9PVxvdmVybGluZXt4fT0zJCBidXQgd2l0aCAkbl95PTgkIHdoZXJlICRuX3g9NCQuIA0KDQpDb21wYXJlICR8XHZlY3tkfV94fD1cc3FydHsxNH1cYXBwcm94IDMuNzQyJCB0byAkfFx2ZWN7ZH1feXw9XHNxcnR7Mjh9PVxzcXJ0ezE0fVxzcXJ0ezJ9XGFwcHJveDUuMjkyJC4gVGhlIG1hZ25pdHV0ZGUgb2YgdGhlIGRldmlhdGlvbiB2ZWN0b3IgZm9yICRZJCBpcyBsYXJnZXIsIG5vdCBiZWNhdXNlIHRoZSBkYXRhIGhhdmUgc3ByZWFkIG91dCBtb3JlLCBidXQgc2ltcGx5IGJlY2F1c2UgdGhlcmUgaXMgbW9yZSBkYXRhLiBUbyBgYHN0YW5kYXJkaXplIiB0aGlzIG1hZ25pdHVkZSBvciBkaXN0YW5jZSwgd2UgZGl2aWRlIGJ5ICRuJCAob3IgJG4tMSQpIGJlZm9yZSB3ZSB0YWtlIHRoZSBzcXVhcmUgcm9vdC4NCg0KXGJlZ2lue2FsaWduKn0NClxzaWdtYV94XjImPVxmcmFje3xkX3h8XjJ9e259XFwNClxzaWdtYV94XjImPVxmcmFjezQrMSswKzl9ezR9XGltcGxpZXNcXA0KXHNpZ21hX3gmPVxzcXJ0e1xmcmFjezE0fXs0fX1cYXBwcm94MS44NzENClxlbmR7YWxpZ24qfQ0KDQpDb21wYXJlIHRoaXMgdG8gdGhlIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24sIHdoZXJlIHdlIHJlcGxhY2UgJG4kIHdpdGggJG4tMSQ6DQoNClxiZWdpbnthbGlnbip9DQpzX3heMiY9XGZyYWN7fGRfeHxeMn17bi0xfVxcWy4yY21dDQpzX3heMiY9XGZyYWN7NCsxKzArOX17M31caW1wbGllc1xcDQpzX3gmPVxzcXJ0e1xmcmFjezE0fXszfX1cYXBwcm94Mi4xNjANClxlbmR7YWxpZ24qfQ0KDQpJZiB5b3UndmUgcmVhZCB0aGlzIGZhciBhbmQgdW5kZXJzdG9vZCBzb21ldGhpbmcgYWJvdXQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiwgY29uZ3JhdHVsYXRpb25zLiBFbm91Z2ggdGhlb3J5LCB0aGUgbmV4dCBzaG9ydCBzZWN0aW9uIHNob3dzIGhvdyB0byB1c2UgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiB0byBjaGVjayBmb3IgaW5mbHVlbnRpYWwgZGF0YSBwb2ludHMuDQoNCiMjIyAxLmMpIE91dGxpZXJzIGFuZCBTdGFuZGFyZCBEZXZpYXRpb24NCkJlY2F1c2UgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBtZWFzdXJlcyBkaXN0YW5jZXMgaW4gYSBkYXRhIHNldCwgd2UgY2FuIGNoZWNrIGZvciBvdXRsaWVycyB1c2luZyBpdC4gRm9yIHNtYWxsIGRhdGEgc2V0cywgd2hlcmUgJG5cbGVxIDUwJCwgKmFueSBkYXRhIHBvaW50IG1vcmUgdGhhbiB0d28gc3RhbmRhcmQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuIG1heSBiZSBjb25zaWRlcmVkIGFuIG91dGxpZXIqLg0KDQpXZSBoYXZlIHRoZSBkYXRhIGluIFIsIHNvIGxldCdzIHVzZSBzb21lIHF1aWNrIGNvZGUgdG8gZGV0ZXJtaW5lIHRoZSBjdXRvZmYgdmFsdWVzIGF0IHdoaWNoIHdlIHdvdWxkIGNvbnNpZGVyIGEgZGF0YSBwb2ludCBhbiBvdXRsaWVyLiBUaGUgUiBmdW5jdGlvbnMgKiptZWFuKiogYW5kICoqc2QqKiB3aWxsIGJlIG5lZWRlZCBmb3IgdGhlaXIgb2J2aW91cyBwdXJwb3Nlcy4NCg0KYGBge3J9DQpyaWdodCA9IG1lYW4oVykgKyAyICogc2QoVykNCmxlZnQgPSBtZWFuKFcpIC0gMiAqIHNkKFcpDQpsZWZ0DQpyaWdodA0KYGBgDQoNCg0KV2Ugc2VlIHRoYXQgJHg9LTc5PC01OS4yJCBhbmQgaXMgYW4gb3V0bGllciB0byB0aGUgbGVmdC4gTm8gZGF0YSBwb2ludHMgYXJlIGxhcmdlciB0aGFuICQ2My4xNSQsIHNvIHRoZXJlIGFyZSBubyBvdXRsaWVycyB0byB0aGUgcmlnaHQuDQoNCiMjIDIuIERhdGEgVmlzdWFsaXphdGlvbiAtIFRoZSBCYXNpY3MgDQpEYXRhIHNjaWVuY2UgaXMgYSBncm91bmQtYnJlYWtpbmcgZmllbGQgcmlnaHQgbm93LCBlc3BlY2lhbGx5IHdoZW4gaXQgY29tZXMgdG8gZGF0YSB2aXN1YWxpemF0aW9ucy4gDQoNCiMjIyAyLmEpIEhpc3RvZ3JhbXMNCkhpc3RvZ3JhbXMgYXJlIGJhciBncmFwaHMgdGhhdCBzaG93IHRoZSBzaGFwZSBvZiB0aGUgZGF0YSBzZXQgd2hpY2gsIGhvcGVmdWxseSwgZ2l2ZXMgaW5zaWdodCBpbnRvIHdoYXQgdGhlIHVuZGVybHlpbmcgZGlzdHJpYnV0aW9uIG1pZ2h0IGxvb2sgbGlrZS4gDQoNCkhpc3RvZ3JhbXMgaGF2ZSBydWxlcy4gVGhlIHJ1bGVzIGtlZXAgZGF0YSBwcmVzZW50YXRpb25zIHVuaWZvcm0gc28gdGhhdCBpdCdzIG1vcmUgZGlmZmljdWx0IHRvIGxpZSB3aXRoIHN0YXRpc3RpY3MsIGEgZmF2b3JpdGUgcGFzcyB0aW1lIG9mIHBvbGl0aWNpYW5zIGFuZCBtZWRpYSBwdW5kaXRzLiBSZXNlYXJjaGVycyBkb24ndCB3aXNoIHRvIGxpZSB3aXRoIHN0YXRpc3RpY3MuIFRoZXkgaG9wZSB0byBwcmVzZW50IHRoZWlyIGZpbmRpbmdzIHRvIHRoZSBzY2llbnRpZmljIGNvbW11bml0eSB3aXRob3V0IGJpYXMuIFNjaWVudGlmaWMgcmVwb3J0cyB1c2Ugb25seSBoaXN0b2dyYW1zIHdpdGg6DQoNCiogU2luZ2xlIGNvbG9yDQoqIEVudGlyZSAkeSQtYXhpcyBzaG93bg0KKiBFcXVhbCBiaW4gd2lkdGgNCiAgKyBBbGwgYmlucyAvIGNhdGVnb3JpZXMgaW50ZXJ2YWxzIG9mIHNhbWUgbGVuZ3RoLCB3aGljaCBsZWFkcyB0by4uLg0KICArIEFsbCBiYXJzIGhhdmUgc2FtZSB3aWR0aA0KICANCmBgYHtyfQ0KaGlzdG9ncmFtKFcpDQpgYGANCkhpc3RvZ3JhbXMgYXJlIGJ1aWx0IG9uIGZyZXF1ZW5jeSB0YWJsZXMgd2hpY2ggZ3JvdXBzIHRoZSBlbnRyaWVzIGluIHRoZSBkYXRhIHNldCBpbnRvIGJpbnMgb3IgY2F0ZWdvcmllcywgdGhlbiBjb3VudHMgdGhlIG51bWJlciBvZiBlbnRyaWVzIGluIGVhY2ggY2F0ZWdvcnkuIFRoZSBkZWZhdWx0IGhpc3RvZ3JhbSBhYm92ZSBsb29rcyB3b25reS4gVGhlIGJpbnMgYXJlIGludGVydmFscyBhbG9uZyB0aGUgJHgkLWF4aXMsIGJ1dCBSIGhhcyBjaG9zZW4gdGhlbSBpbiBhIHdlaXJkIHdheS4gVGhleSBzaG91bGQgb2J2aW91c2x5IGJlIGluIHVuaXRzIG9mIDEwIG9yIDIwIGdpdmVuIHRoZSBkYXRhIHJhbmdlLCBhbmQgY2VudGVyZWQgb24gc29tZXRoaW5nIGRpdmlzaWJsZSBieSAxMC4gV2UgY2FuIGhhdmUgUlN0dWRpbyBjcmVhdGUgYSBmcmVxdWVuY3kgdGFibGUgYmFzZWQgb24gYSBiaW4gd2lkdGggb2YgMjAsIHRoZW4gc2hvdyBob3cgdG8gYWRqdXN0IHRoZSBoaXN0b2dyYW0gdG8gZGlzcGxheSBzb21ldGhpbmcgbW9yZSByZWFzb25hYmxlLiBXZSdsbCB2aWV3IHRoZSBmcmVxdWVuY3kgdGFibGUgYnV0IHN1cHByZXNzIHRoZSBSIGNvZGUgdGhhdCBnZW5lcmF0ZXMgaXQsIGFzIHlvdSB3b24ndCBiZSByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgZnJlcXVlbmN5IHRhYmxlcyBpbiBSLg0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCmJpbnMgPC0gc2VxKC04MCwgNjAsIGJ5ID0gMjApDQpCaW5zIDwtIGN1dChXLCBiaW5zKQ0KdHJhbnNmb3JtKHRhYmxlKEJpbnMpKQ0KYGBgDQoNCjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0OyBtYXJnaW46IDhweDsgYm9yZGVyOjJweCBibGFjayBzb2xpZDsgcGFkZGluZzogMHB4IDEwcHggNXB4Ij4NCiMjIyMgSGlzdG9ncmFtIE9wdGlvbjogVHlwZQ0KVGhlICoqdHlwZSoqIHBhcmFtZXRlciBpcyBjb3NtZXRpYy4gVGhlICR5JC1heGlzPC9icj4NCnVuaXRzIGNoYW5nZSBmcm9tIGRlbnNpdHkgdG8gY291bnRzIHNvIHdlIGNhbiBzZWU8L2JyPg0KaG93IG1hbnkgZGF0YSBwb2ludHMgZmFsbCBpbnRvIGVhY2ggYmluLg0KPC9kaXY+DQoNCjxwPldlIHdhbnQgdG8gZm9yY2UgUlN0dWRpbyB0byB1c2UgdGhlIGJpbiB3aWR0aHMgd2Ugd2FudC4gVGhlICoqd2lkdGgqKiBwYXJhbWV0ZXIgd2lsbCBmb3JjZSBhIGJpbiB3aWR0aCBvZiBvdXIgY2hvb3NpbmcsIGFuZCB0aGUgKipjZW50ZXIqKiBwYXJhbWV0ZXIgZm9yY2VzIGEgc2luZ2xlIGJpbiB0byBiZSBjZW50ZXJlZCBhdCB0aGF0IHBvaW50LiBBbGwgIGJpbnMgaGF2ZSBlcXVhbCB3aWR0aHMgc28gd2UgZG9uJ3QgaGF2ZSB0byBzcGVjaWZ5IHRoZSBjZW50ZXIgb2YgdGhlIGhpc3RvZ3JhbSwganVzdCB0aGUgY2VudGVyIG9mIG9uZSBiaW4uIFdlIGNyZWF0ZWQgYSBmcmVxdWVuY3kgdGFibGUgd2l0aCBhIGJpbiB3aWR0aCBvZiAyMCBhYm92ZSwgYW5kIHRoZSBjZW50ZXIgb2YgZWFjaCBiaW4gaXMgYW4gb2RkIG11bHRpcGxlIG9mIDEwLiA8L3A+DQo8ZGl2IHN0eWxlPSJjbGVhcjpyaWdodDsiPjwvZGl2Pg0KDQpgYGB7cn0NCmhpc3RvZ3JhbShXLCB3aWR0aCA9IDIwLCBjZW50ZXIgPSAxMCAsIHR5cGUgPSAiY291bnQiKQ0KYGBgDQoNClIgaGFzIGEgc3RhbmRhcmQgd2F5IHRvIGFkZCBoZWFkaW5ncyBhbmQgbGFiZWxzLCBzbyBsZXQncyBhZGQgYSBmZXcgdXBncmFkZXMgdG8gb3VyIGhpc3RvZ3JhbS4gV2UgdXNlIHRoZSAqKm1haW4qKiBwYXJhbWV0ZXIgdG8gcHJvdmlkZSBhIHRpdGxlLCBhbmQgKip4bGFiKiogYW5kICoqeWxhYioqIHRvIGxhYmVsIHRoZSBheGVzLiBMZXQncyBhbHNvIHRyeSBhIGJpbiAqKndpZHRoKiogb2YgMTAuIExhc3RseSwgd2UnbGwgc3VwZXJpbXBvc2UgYSBiZWxsLWN1cnZlIHdpdGggdGhlICoqZml0KiogcGFyYW1ldGVyIGFza2luZyBmb3IgYSBmaXR0ZWQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvdmVybGF5Lg0KDQpgYGB7cn0NCmhpc3RvZ3JhbShXLA0KICAgICB3aWR0aCA9IDEwLA0KICAgICBjZW50ZXIgPSAwLA0KICAgICBmaXQgPSAibm9ybWFsIiwNCiAgICAgbWFpbiA9ICJIaXN0b2dyYW06IE1hbmR5J3MgV2lubmluZ3MiLA0KICAgICB4bGFiID0gIkRvbGxhcnMgV29uIG9yIExvc3QiLA0KICAgICB5bGFiID0gIlNlc3Npb25zIikNCmBgYA0KDQojIyAyLmIpIEJveCBQbG90cw0KVGhlIHN0YW5kYXJkICoqYm94IHBsb3QqKiBpcyBlYXN5IHRvIGdlbmVyYXRlIGFuZCBpcyBhIHZpc3VhbGl6YXRpb24gb2YgdGhlIEZpdmUgTnVtYmVyIFN1bW1hcnkuDQpgYGB7cn0NCmJveHBsb3QoVykNCmBgYA0KDQo8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodDsgbWFyZ2luOiA4cHg7IGJvcmRlcjoycHggYmxhY2sgc29saWQ7IHBhZGRpbmc6IDBweCAxMHB4IDVweCI+DQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5TdGVtIGFuZCBCb3hwbG90czwvc3Bhbj4NCioqU3RlbSoqIGFuZCAqKkJveHBsb3QqKiBhcmUgbm90ICpNb3NhaWMqIGZ1bmN0aW9ucyBhbmQ8L2JyPg0KdGh1cyB1c2UgdGhlICoqRGF0YUZyYW1lJFZhcmlhYmxlKiogZm9ybWF0IHdoZXJlIGE8L2JyPg0KZG9sbGFyIHNpZ24gaW5kaWNhdGVzIGEgdmFyaWFibGUgd2l0aGluIGEgZGF0YSBmcmFtZS4NCjwvZGl2Pg0KDQpUaGUgYm94IGluIGEgYm94cGxvdCBzaG93cyB0aGUgbWlkZGxlIHRoZSA1MCUgb2YgdGhlIGRhdGEgc2V0LiBUaGUgbGluZSBicmVha3MgYXJlIGF0IHRoZSBxdWFydGlsZXMsIGFuZCB0aGUgdGFpbHMgYXJlIHNob3duIG91dHNpZGUgdGhlIGJveCBzbyB0aGF0IHNrZXcgY2FuIGJlIGRldGVjdGVkLiBXZSBhbHdheXMgcHJlZmVyIGZvciB0aGUgYm94cGxvdCB0byBjaGVjayBmb3Igb3V0bGllcnMgYXMgaXMgdGhlIGNhc2UgaGVyZS4NCg0KVmVydGljYWwgYm94IHBsb3RzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIHdlJ3JlIGRpc3BsYXlpbmcgc2V2ZXJhbCBhdCBvbmNlLCBidXQgdGhlIGhvcml6b250YWwgYm94IHBsb3QgYmV0dGVyIHBhcmFsbGVscyB0aGUgaGlzdG9ncmFtIHByZXNlbnRhdGlvbiBiZWNhdXNlIHRoZSAkeCQtYXhpcyBpcyB0aGUgc2FtZS4gVGhlIHRpdGxlIGFuZCBsYWJlbHMgd29yayB0aGUgc2FtZSBhcyBiZWZvcmUuDQpgYGB7cn0NCmJveHBsb3QoVywgaG9yaXpvbnRhbCA9IFRSVUUsDQogICAgIG1haW4gPSAiQm94cGxvdDogTWFuZHkncyBXaW5uaW5ncyIsDQogICAgIHhsYWIgPSAiRG9sbGFycyBXb24gb3IgTG9zdCIpDQpgYGANCg0KTm90aWNlIHRoZSBvdXRsaWVyIHRvIHRoZSBsZWZ0IG1hcmtlZCBieSB0aGUgb3BlbiBkb3QuIFdlIG9mdGVuIHVzZSB0aGUgSVFSIChpbm5lci1xdWFydGlsZSByYW5nZSkgaW4gdGhlIEZpdmUgTnVtYmVyIFN1bW1hcnkgdG8gZGV0ZWN0IG91dGxpZXJzLCB3aGVyZSBJUVIgaXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gUTEgYW5kIFEzLiAkJFx0ZXh0e0lRUn09XHRleHR7UTN9LVx0ZXh0e1ExfSQkIFdlIGNhbGN1bGF0ZSB0aGUgZmVuY2VzIGFzIGZvbGxvd3M6DQoNClxiZWdpbnthbGlnbip9DQpcdGV4dHtVcHBlciBGZW5jZX0mPVx0ZXh0e1EzfSsxLjVcdGltZXNcdGV4dHtJUVJ9XFwNClx0ZXh0e0xvd2VyIEZlbmNlfSY9XHRleHR7UTF9LTEuNVx0aW1lc1x0ZXh0e0lRUn0NClxlbmR7YWxpZ24qfQ0KDQpBbnkgZGF0YSBwb2ludHMgYmVsb3cgdGhlIExvd2VyIEZlbmNlIGFyZSBvdXRsaWVycyB0byB0aGUgbGVmdC4gQW55IGRhdGEgcG9pbnRzIGFib3ZlIHRoZSBVcHBlciBGZW5jZSBhcmUgb3V0bGllcnMgdG8gdGhlIHJpZ2h0LiBBbnkgZGF0YSBwb2ludHMgdGhhdCBsYW5kIGV4YWN0bHkgb24gYSBmZW5jZSBhcmUgKm5vdCogY29uc2lkZXJlZCBvdXRsaWVycy4NCg0KIyMgMy4gRGF0YSBBbmFseXNpcyBSZXN1bHRzIGZvciBFeGFtcGxlIDENClRoZSBoaXN0b2dyYW0gc2hvd3MgYW4gYXBwcm94aW1hdGUgYmVsbC1zaGFwZS4gV2h5PyBDb25zaWRlciB0aGUgdGFsbGVzdCBiYXIuIFRoZW4gdmlldyB0aGUgdGFpbHMgdG8gZWl0aGVyIHNpZGUgb2YgaXQuIEJvdGggdGFpbHMgY2xlYXJseSBleGlzdCwgYW5kIHdlIGNhbiBjb25zaWRlciB0aGlzIGRhdGEgc2V0IGFzIGhhdmluZyBiZWVuIHNhbXBsZWQgZnJvbSBhIGRpc3RyaWJ1dGlvbiB0aGF0IGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLiBUaGUgYm94cGxvdCBzaG93cyBhbiBvdXRsaWVyIHRvIGxlZnQgYXMgd2VsbCBhcyBhIHNrZXcgdG8gdGhlIGxlZnQgd2hpY2ggd2FzIGFsc28gdmlzaWJsZSBpbiB0aGUgaGlzdG9ncmFtIHdoaWNoIGhhZCBhIG11Y2ggbG9uZ2VyIHRhaWwgdG8gdGhlIGxlZnQuDQoNCk91ciBmaW5hbCB3b3JkPyBBbiBhcHByb3hpbWF0ZWx5IG5vcm1hbCAoYmVsbC1zaGFwZWQpIGRpc3RyaWJ1dGlvbiB3aXRoIHNrZXcgdG8gdGhlIGxlZnQuDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyI+SUlJLiBPdGhlciBWaXN1YWxpemF0aW9uczwvc3Bhbj4NCg0KPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQ7IG1hcmdpbjogOHB4OyBib3JkZXI6MnB4IGJsYWNrIHNvbGlkOyBwYWRkaW5nOiAwcHggMTBweCA1cHgiPg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+U3RlbSBhbmQgQm94cGxvdHM8L3NwYW4+DQoqKlN0ZW0qKiBhbmQgKipCb3hwbG90KiogYXJlIG5vdCAqTW9zYWljKiBmdW5jdGlvbnMgYW5kPC9icj4NCnRodXMgdXNlIHRoZSAqKkRhdGFGcmFtZSRWYXJpYWJsZSoqIGZvcm1hdCB3aGVyZSBhPC9icj4NCmRvbGxhciBzaWduIGluZGljYXRlcyBhIHZhcmlhYmxlIHdpdGhpbiBhIGRhdGEgZnJhbWUuDQo8L2Rpdj4NCg0KIyMgU3RlbSBQbG90cw0KDQpBbiBpbnRlcmVzdGluZyB2aXN1YWxpemF0aW9uIGlzIHRoZSBzdGVtLWFuZC1sZWFmIHBsb3Qgd2hpY2ggdXNlcyB0aGUgbnVtYmVycyBpbiB0aGUgZGF0YSBzZXQgdG8gY3JlYXRlIGEgaGlzdG9ncmFtLWxpa2UgZGlzcGxheS4gT2Z0ZW4gdXNlZnVsLCB0aGUgc2NhbGluZyBpcyBpbXBvcnRhbnQuIFRyeSBkaWZmZXJlbnQgc2NhbGVzIGxpa2UgMSBvciAyIGFuZCB5b3UnbGwgZmluZCB0aGUgZGlzcGxheSBpcyBob3BlbGVzcyBmb3Igc2hvd2luZyBhbnl0aGluZyBhYm91dCB0aGUgZGF0YS4NCg0KYGBge3J9DQpzdGVtKFcsIHNjYWxlID0gMykNCmBgYA0KV2hlbiBzY2FsZWQgcHJvcGVybHksIGhvd2V2ZXIsIHdlIGdldCBhIGVuZCB1cCB3aXRoIGEgaGlzdG9ncmFtIChpZiB3ZSByb3RhdGUgb3VyIHBhcGVyIDkwIGRlZ3JlZXMpLiBXZSBjYW4gcmVhZCBvZmYgYWxsIHRoZSB2YWx1ZXMgaW4gdGhlIGRhdGEgc2V0IHdoaWNoIG1ha2VzIGZpbmRpbmcgdGhlIEZpdmUgTnVtYmVyIFN1bW1hcnkgcHJldHR5IGVhc3kuIEZvciBtb3JlIGRldGFpbHMgYWJvdXQgY3JlYXRpbmcgYW5kIGludGVycHJldHRpbmcgc3RlbSBwbG90cyBjaGVjayBvdXQgdGhpcyA8YSBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PVBTckN4c0lnUEZVIj5Zb3V0dWJlIHZpZGVvPC9hPi4NCg0KVHdvIGRpc2FkdmFudGFnZXMgb2Ygc3RlbSBwbG90cyBzaG91bGQgYmUgb2J2aW91cy4gRmlyc3QsIHdpdGggc29tZSBkYXRhIHNldHMgd2UgY2Fubm90IGdldCB0aGVtIHNjYWxlZCBwcm9wZXJseS4gVGhlIHJlcXVpcmVtZW50IHRoYXQgdGhlIGJpbnMgYmUgZXF1YWxseSBzcGFjZWQgbGltaXRzIGhvdyB3ZSBjYW4gcHJvY2VlZCBzaW5jZSB3ZSBoYXZlIG9ubHkgdGVuIGRpZ2l0cy4gU2Vjb25kLCBiaWcgZGF0YSBzZXRzIGRlZnkgc3RlbSBwbG90cy4gRXZlbiBpZiBhIG1hY2hpbmUgY2FuIGNyZWF0ZSBpdCwgaXQncyBub3QgcmVhZGFibGUgaWYgdGhlcmUncyBtb3JlIHRoYW4gYSBjb3VwbGUgaHVuZHJlZCBkYXRhIHBvaW50cy4NCg0KIyMgRGVuc2l0eSBQbG90cw0KVGhlICoqZGVuc2l0eSBwbG90KiogaXMgYSBoeWJyaWQuIEl0IHNob3dzIHRoZSBkYXRhIHBvaW50cyBhbG9uZyB0aGUgJHgkLWF4aXMgYW5kIGFuIGVudmVsb3BlIGFib3ZlIHRoZW0gc2hvd2luZyBhIGhpc3RvZ3JhbS1saWtlIHNoYXBlLiBUaGUgdGFsbGVyIHRoZSBlbnZlbG9wZSBnZXRzLCB0aGUgbW9yZSBjbG9zZWx5IHRoZSBkYXRhIGFyZSBjbHVtcGVkIHRvZ2V0aGVyIHJpZ2h0IGJlbG93IGl0LiBXaGVyZSB0aGUgZGF0YSBwb2ludHMgYXJlIHNwcmVhZCBvdXQsIHRoZSBlbnZlbG9wZSBjdXJ2ZSBpcyBuZWFyIHRoZSAkeCQtYXhpcy4NCg0KYGBge3J9DQpkZW5zaXR5cGxvdChXKQ0KYGBgDQpUaGlzIGlzIHBlcmhhcHMgdGhlIGJlc3QgdmlzdWFsaXphdGlvbiBvZiB0aGUgc2tldyB0byB0aGUgbGVmdC4gV2UgY2FuIGFsc28gc2VlIHRoYXQgTWFuZHkgdGVuZHMgdG8gd2luIGEgbG90IG9mIHNtYWxsIGFtb3VudHMsIHdpdGggbWFueSBvZiB0aGUgZGF0YSBwb2ludHMgYmV0d2VlbiAwIGFuZCAyMC4gQSBmZXcgb2YgdGhlIGxvc3NlcyBhcmUgaHVnZSB3aGljaCBsZWFkcyB0byBsb25nZXIgdGFpbCB0byB0aGUgbGVmdC4NCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsdWU7Ij5JVi4gVmlzdWFsaXphdGlvbiBFeGFtcGxlOiBPbGQgRmFpdGhmdWwgR2V5c2VyPC9zcGFuPg0KUiBoYXMgcHJlbG9hZGVkIGRhdGEgc2V0cyBsaWtlICoqZmFpdGhmdWwqKiwgYSBkYXRhIGZyYW1lIHdpdGggdHdvIHZhcmlhYmxlczogZXJ1cHRpb25zIGFuZCB3YWl0aW5nLiBCb3RoIGFyZSB0aW1lIHZhcmlhYmxlcy4gRXJ1cHRpb25zIGlzIG51bWJlciBvZiBzZWNvbmRzIHRoZSBlcnVwdGlvbnMgbGFzdGVkLiBXYWl0aW5nIGlzIHRoZSB0aW1lIGludGVydmFsIGJldHdlZW4gZXJ1cHRpb25zLiBCeSBqdXN0IHR5cGluZyB0aGUgbmFtZSBvZiB0aGUgZGF0YSBmcmFtZSwgUiB3aWxsIHByaW50IG91dCBhIHByZXZpZXcuDQoNCmBgYHtyfQ0KZmFpdGhmdWwNCmBgYA0KTm90ZSB0aGUgMjcyIHJvd3MgcmVmZXJzIHRvIDI3MiBlcnVwdGlvbi13YWl0aW5nIHBhaXJzIG9mIHZhbHVlcywgc28gYm90aCBudW1lcmljIGRhdGEgc2V0cyBoYXZlIDI3MiBlbnRyaWVzLg0KDQojIyBUd28gVmFyaWFibGUgUGxvdHMNCk9uZSBtaWdodCB3b25kZXIgaWYgbG9uZ2VyIHdhaXRpbmcgdGltZXMgY29ycmVsYXRlIHdpdGggbG9uZ2VyIGVydXB0aW9ucy4gUGVyaGFwcyBtb3JlIHByZXNzdXJlIGJ1aWxkcyB1cCwgdGhlbiB3aGVuIHJlbGVhc2VkIHRoZSBlcnVwdGlvbnMgbGFzdCBsb25nZXIuIExldCdzIGNoZWNrIGEgc2NhdHRlciBwbG90LiBUaGUgZmlyc3QgYXJndW1lbnQgaXMgdGhlIGZvcm0gJHlcc2ltIHgkLiBUaGUgJHkkLXZhcmlhYmxlIGlzIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIHRoZSAkeCQtdmFyaWFibGUgaW5kZXBlbmRlbnQuIEluIHRoaXMgc2V0dXAsIHdlIGFyZSBpbXBsaWNpdGx5IHN1Z2dlc3RpbmcgdGhhdCB0aGUgdmFyaWFibGUgKiplcnVwdGlvbnMqKiBkZXBlbmRzIHVwb24gdGhlIHZhcmlhYmxlICoqd2FpdGluZyoqLiBJZiB3ZSByZXZlcnNlIHRoZSBvcmRlciwgd2UgcmV2ZXJzZSB0aGUgaW1wbGljaXQgZGVwZW5kZW5jZS4NCg0KYGBge3J9DQp4eXBsb3QoZXJ1cHRpb25zIH4gd2FpdGluZywgZGF0YSA9IGZhaXRoZnVsKQ0KYGBgDQpUaGVyZSBkb2VzIHNlZW0gdG8gYmUgYSBwYXR0ZXJuLiBBIHF1aWNrIG9mIHRoZSBjb3JyZWxhdGlvbiB2ZXJpZmllcyB0aGVyZSBpcyBhIHN0cm9uZywgcG9zaXRpdmUgY29ycmVsYXRpb24uDQoNCmBgYHtyfQ0KY29yKGVydXB0aW9ucyB+IHdhaXRpbmcsIGRhdGEgPSBmYWl0aGZ1bCkNCmBgYA0KV2Ugd2lsbCBkaXNjdXNzIGNvcnJlbGF0aW9uIGFuZCByZWdyZXNzaW9uIGxhdGVyIGluIHRoZSBjb3Vyc2UsIGJ1dCBrZWVwIGluIG1pbmQgdGhhdCBleHBsb3JhdG9yeSBkYXRhIGFuYWx5c2lzIG9mdGVuIGludm9sdmVzIHN0dWR5aW5nIHJlbGF0ZWQgdmFyaWFibGVzIGluIGRhdGEgc2V0cywgYm90aCB0b2dldGhlciBhbmQgc2VwYXJhdGVseS4NCg0KIyMgRGF0YSBBbmFseXNpczogT2xkIEZhaXRoZnVsIFdhaXRpbmcgVGltZXMNCkxldCdzIHN0YXJ0IHdpdGggdGhlIG51bWVyaWNzLiBXaGVuIHVzaW5nIGEgZGF0YSBmcmFtZSAtLSBhIGRhdGEgb2JqZWN0IHdpdGggbW9yZSB0aGFuIG9uZSB2YXJpYWJsZSAtLSB3ZSBmaXJzdCBzcGVjaWZ5IHRoZSB2YXJpYWJsZSB3ZSB3YW50IHRvIGFuYWx5emUsIHRoZW4gdGhlIGRhdGEgZnJhbWUgd2hlcmUgaXQgd2lsbCBiZSBmb3VuZC4gVGhlIHJlYXNvbiBmb3IgdGhlIHRpbGRlICh+KSB3aWxsIGJlIGNsZWFyIHNob3J0bHkuDQpgYGB7cn0NCmZhdnN0YXRzKH4gd2FpdGluZywgZGF0YSA9IGZhaXRoZnVsKQ0KYGBgDQpCeSBSb2JiJ3MgUnVsZSBvZiBUaHVtYiwgdGhlIG1lYW4gaXMgc2lnbmlmaWNhbnRseSBsZXNzIHRoYW4gdGhlIG1lZGlhbiwgc28gd2UgZXhwZWN0IHNrZXcgYW5kIG91dGxpZXJzIHRvIHRoZSBsZWZ0LiBIb3dldmVyLCB0aGUgbG93ZXIgYW5kIHVwcGVyIHF1YXJ0aWxlcyBvZiB0aGUgRml2ZSBOdW1iZXIgU3VtbWFyeSBhcmUgaW50ZXJ2YWxzIHdpdGggcm91Z2hseSB0aGUgc2FtZSBsZW5ndGgsIDE1IHZzLiAxNC4NCg0KYGBge3J9DQpoaXN0b2dyYW0ofiB3YWl0aW5nLCBkYXRhID0gZmFpdGhmdWwpDQpgYGANClRoaXMgYXBwZWFycyB0byBiZSBiaW1vZGFsIGRhdGEsIGEgaGlzdG9ncmFtIHdpdGggdHdvIHBlYWtzLiBXaGlsZSB0aGVyZSBhIGxhcmdlIGNsdXN0ZXIgb2YgdmFsdWVzIGFyb3VuZCA4MCBzZWNvbmRzLCB0aGVyZSBpcyBhIHNlY29uZGFyeSBjbHVzdGVyaW5nIGFyb3VuZCA1NS4gVGhlIGJpbW9kYWwgc2hhcGUgbGlrZWx5IGFjY291bnRzIGZvciB0aGUgZGlmZmVyZW5jZSBpbiBtZWFuIGFuZCBtZWRpYW4sIHJhdGhlciB0aGFuIG91dGxpZXJzIHRvIHRoZSBsZWZ0ICh0aG91Z2ggdGhleSBtYXkgc3RpbGwgZXhpc3QpLg0KDQpUaGUgYm94cGxvdCBmdW5jdGlvbiB3aWxsIHByb2R1Y2UgYSBib3hwbG90IGZvciBldmVyeSB2YXJpYWJsZSBpbiB0aGUgZGF0YSBmcmFtZSBieSBkZWZhdWx0Lg0KDQpgYGB7cn0NCmJveHBsb3QoZmFpdGhmdWwsIGhvcml6b250YWwgPSBUUlVFKQ0KYGBgDQpOb3RpY2UgdGhlcmUgYXJlIG5vIG91dGxpZXJzLCBzbyBvdXIgZ3Vlc3MgYWJvdXQgdGhlIGJpbW9kYWwgdGVuZGVuY2llcyBjYXVzaW5nIHRoZSBkaXNwYXJpdHkgYmV0d2VlbiBtZWFuIGFuZCBtZWRpYW4gc2VlbXMganVzdGlmaWVkLiBUaGUgZGVuc2l0eSBwbG90IGlzIGluc3RydWN0aXZlLCB0b28uDQoNCmBgYHtyfQ0KZGVuc2l0eXBsb3QofiB3YWl0aW5nLCBkYXRhID0gZmFpdGhmdWwpDQpgYGANCg0KDQojIyBEYXRhIEFuYWx5c2lzOiBPbGQgRmFpdGhmdWwgRXJ1cHRpb24gRHVyYXRpb24gVGltZXMNClRoZSBtZWFuIGFwcGVhcnMgdG8gYmUgc2lnbmlmaWNhbnRseSBsZXNzIHRoYW4gdGhlIG1lZGlhbiAocnVsZSBvZiB0aHVtYiksIHNvIHdlIGV4cGVjdCBza2V3IGFuZCBvdXRsaWVycyB0byB0aGUgbGVmdC4gDQpgYGB7cn0NCmZhdnN0YXRzKH4gZXJ1cHRpb25zLCBkYXRhID0gZmFpdGhmdWwpDQpgYGANCkFnYWluLCB0aGUgRml2ZSBOdW1iZXIgU3VtbWFyeSBzZWVtcyB0byBiZWxpZSB0aGlzIGFuYWx5c2lzLCBzbyBwZXJoYXBzIHRoZXJlIGlzIGEgYmltb2RhbCBwYXR0ZXJuIGluICoqZXJ1cHRpb25zKiosIHRvby4gDQoNCmBgYHtyfQ0KaGlzdG9ncmFtKH4gZXJ1cHRpb25zLCBkYXRhID0gZmFpdGhmdWwpDQpgYGANClRoZSBiaW1vZGFsIHBhdHRlcm4gaXMgZXZlbiBtb3JlIHN0YXJrLiBXaGlsZSB0aGUgKip3YWl0aW5nKiogaGlzdG9ncmFtIG1pZ2h0IHN0aWxsIGhhdmUgcXVhbGlmaWVkIGluIGEgbG9vc2Ugc2Vuc2UgYXMgYXBwcm94aW1hdGVseSBiZWxsLXNoYXBlZCwgdGhlc2UgZGF0YSBzdXJlbHkgZG8gbm90LiBUaGUgYm94IHBsb3RzIGFib3ZlIHNob3dlZCBubyBvdXRsaWVycyBpbiBlaXRoZXIgZGF0YSBzZXQuIEFnYWluLCB0aGUgZGVuc2l0eSBwbG90IHNob3dzIHRoZSBwYXR0ZXJuIGNsZWFybHkuDQoNCmBgYHtyfQ0KZGVuc2l0eXBsb3QofiB3YWl0aW5nLCBkYXRhID0gZmFpdGhmdWwpDQpgYGANCg0KDQoNCg0KV2hhdCBoYXZlIHdlIGxlYXJuZWQ/IFdlIGhhdmUgdHdvIGJpbW9kYWwgdmFyaWFibGUgdGhhdCBhcmUgc3Ryb25nbHkgY29ycmVsYXRlZC4gSG9wZWZ1bGx5IHdlIGhhdmUgYWxzbyBsZWFybmVkIHRoYXQgZXhwbG9yYXRvcnkgZGF0YSBhbmFseXNpcyAoRURBKSBpcyBqdXN0IHRoYXQgLSBleHBsb3JpbmcuIFdlIGRvbid0IHR5cGljYWxseSBmaW5kIGN1dC1hbmQtZHJpZWQgYW5zd2Vycy4gUmVhbC13b3JsZCBkYXRhIGlzIHJlYWwgbWVzc3kuIFdlIG5lZWQgZmxleGlibGUgdG9vbHMgdG8gYW5hbHl6ZSBtYW55IHZhcmlldGllcyBvZiBkYXRhIGFuZCB0byBkaXNjb3ZlciBwYXR0ZXJucy4gV2UgbmVlZCBtaW5kcyBhcyBmbGV4aWJsZSBhcyBvdXIgdG9vbHMgYmVjYXVzZSBFREEgaXMgb2Z0ZW4gbW9yZSBhcnQgdGhhbiBzY2llbmNlLg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogYmx1ZTsiPlYuIERhdGEgQW5hbHlzaXMgRXhhbXBsZTogQmlydGhzIGFuZCBEYXkgb2YgdGhlIFllYXI8L3NwYW4+DQoNCkNvbnNpZGVyIGhvdyBtYW55IGJhYmllcyB3ZXJlIGJvcm4gdGhlIGRpZmZlcmVudCBkYXlzIG9mIHRoZSB5ZWFyLiBTZXZlcmFsIHBhdHRlcm5zIGFyZSBhcHBhcmVudCwgYnV0IHdoYXQgaXMgdGhlIGNhdXNlPyBeW0lkZWEgYW5kIGNvZGUgZnJvbSAqU3RhcnQgVGVhY2hpbmcgd2l0aCBSKiBieSBQcml1bSwgSG9ydG9uIGFuZCBLYXBsYW4uIFNlZSA8YSBocmVmID0gaHR0cDovL3d3dy5tb3NhaWMtd2ViLm9yZy9nby90ZWFjaGluZ1JsaWNlbnNlLmh0bWw+UHJvamVjdCBNb3NhaWMgd2Vic2l0ZTwvYT5dLg0KDQpgYGB7cn0NCkJpcnRoczc4DQpgYGANCg0KDQpgYGB7cn0NCnh5cGxvdChiaXJ0aHMgfiBkYXlfb2ZfeWVhciwgZGF0YT1CaXJ0aHM3OCkNCmBgYA0KVGhpbmsgYWJvdXQgd2hhdCB0aGlzIG1lYW5zLiBQZXJoYXBzIHNvbWUgZGF0YSB2aXN1YWxpemF0aW9uIHdpdGggY29sb3IgY29kaW5nIHdpbGwgaGVscC4NCg0KYGBge3J9DQp4eXBsb3QoYmlydGhzIH4gZGF5X29mX3llYXIsIGRhdGEgPSBCaXJ0aHM3OCwgDQogICAgICAgZ3JvdXBzID0gd2RheSwNCiAgICAgICBtYWluID0gIkJpcnRocyB2cy4gRGF5IG9mIFllYXIgZm9yIDE5NzgiLA0KICAgICAgIHhsYWIgPSAiRGF5IG9mIFllYXIiLA0KICAgICAgIHlsYWIgPSAiQmlydGhzIg0KICAgICAgICkNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogYmx1ZTsiPlZJLiBFeGVyY2lzZXM8L3NwYW4+DQoNCjEuIFVzaW5nIHRoZSBidWlsdC1pbiBSIGRhdGEgZnJhbWUgKipDaGlja1dlaWdodCoqIHdoaWNoIGV4YW1pbmVzIHdlaWdodCB2cyBhZ2Ugb2YgY2hpY2tzIG9uIGRpZmZlcmVudCBkaWV0cywgY29uZHVjdCBhbiBhbmFseXNpcyBvZiB0aGUgdmFyaWFibGUgKip3ZWlnaHQqKi4gSW5jbHVkZSBhbGwgcmVsZXZhbnQgcGxvdHMsIGFuZCBpbmNsdWRlIHRpdGxlcyBhbmQgYXhpcyBsYWJlbHMgZm9yIHlvdXIgaGlzdG9ncmFtIGFuZCBkZW5zaXR5IHBsb3QuDQoNCjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0OyBtYXJnaW46IDhweDsgYm9yZGVyOjJweCBibGFjayBzb2xpZDsgcGFkZGluZzogMHB4IDEwcHggNXB4Ij4NCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkJ1aWx0LWluIFIgRGF0YXNldHM8L3NwYW4+DQpSIGhhcyBkb3plbnMgb2YgYnVpbHQtaW4gZGF0YSBmcmFtZXMgbGlrZSAqKmlyaXMqKi48L2JyPg0KVHlwZSB2YXJpYWJsZSBuYW1lIG9ubHkgYW5kIGV4ZWN1dGUgY29kZSBibG9jay48L2JyPg0KT3V0cHV0IHNob3dzIGhlYWRlcnMsIHZhcmlhYmxlIG5hbWVzIGFuZDwvYnI+DQpvYnNlcnZhdGlvbnMuIFNlYXJjaCB2YXJpYWJsZSBuYW1lIGluIGhlbHAgdGFiPC9icj4NCm9mIGJvdHRvbS1yaWdodCBwYW5lbCBmb3IgZGV0YWlscy4NCjwvZGl2Pg0KDQoyLiBVc2luZyB0aGUgYnVpbHQtaW4gUiBkYXRhIGZyYW1lICoqSW5zZWN0U3ByYXlzKiogd2hpY2ggZXhhbWluZXMgdGhlIG51bWJlciBvZiBpbnNlY3RzIGluIGFuIGFyZWEgZGVwZW5kaW5nIHVwb24gdHlwZSBvZiBpbnNlY3RpY2lkZSB1c2VkLCBjb25kdWN0IGFuIGFuYWx5c2lzIG9mIHRoZSB2YXJpYWJsZSAqKmNvdW50KiouIEluY2x1ZGUgYWxsIHJlbGV2YW50IHBsb3RzLCBhbmQgaW5jbHVkZSB0aXRsZXMgYW5kIGF4aXMgbGFiZWxzIGZvciB5b3VyIGhpc3RvZ3JhbSBhbmQgZGVuc2l0eSBwbG90Lg0KDQozLiBVc2UgdGhlIGJ1aWx0LWluIFIgZGF0YSBmcmFtZSAqKmNhcnMqKiB3aGljaCBjb21wYXJlcyB0aGUgbnVtZXJpYyB2YXJpYWJsZXMgKipzcGVlZCoqIG1lYXN1cmVkIGluIG1pbGVzIHBlciBob3VycyAobXBoKSBhbmQgc3RvcHBpbmcgZGlzdGFuY2UgKHZhcmlhYmxlIGlzICoqZGlzdCoqLCBtZWFzdXJlZCBpbiBmZWV0KS4gVGhlIGRhdGEgaXMgZnJvbSB0aGUgMTkyMCdzLCBieSB0aGUgd2F5LiBDcmVhdGUgYW4gKip4eXBsb3QqKiBmb3IgdGhlIHR3byB2YXJpYWJsZXMsIGFuZCBpbmNsdWRlIGF4aXMgbGFiZWxzIG9uIHlvdXIgcGxvdC4NCg0KNC4gVXNpbmcgdGhlIGJ1aWx0LWluIFIgZGF0YSBmcmFtZSAqKm10Y2FycyoqIHdoaWNoIGluY2x1ZGVzIG1pbGVzIHBlciBnYWxsb24gYW5kIHRlbiBvdGhlciB2YXJpYWJsZXMgZm9yIDMyIGRpZmZlcmVudCBtb2RlbHMgaW4gMTk3NCwgY3JlYXRlIGFuICoqeHlwbG90KiogZm9yIG1pbGVzIHBlciBnYWxsb24gKCoqbXBnKiogdmFyaWFibGUpIHZzLiBkaXNwbGFjZW1lbnQgKCoqZGlzcCoqIHZhcmlhYmxlKSB1c2luZyBhIGdyb3VwaW5nIHZhcmlhYmxlIG9mIHRyYW5zbWlzc2lvbiB0eXBlLCBhdXRvbWF0aWMgdnMuIG1hbnVhbCAoKiphbSoqKS4NCg0KNS4gVXNpbmcgdGhlIGJ1aWx0LWluIFIgZGF0YSBmcmFtZSAqKkRpbWVzKiogd2hpY2ggY29tcGFyZXMgdGhlIG1hc3Mgb2YgYSBkaW1lIHRvIHRoZSB5ZWFyIGluIHdoaWNoIGlzIHdhcyBtaW50ZWQsIGNvbmR1Y3QgYW4gYW5hbHlzaXMgb2YgdGhlIHZhcmlhYmxlICoqbWFzcyoqLiBJbmNsdWRlIGFsbCByZWxldmFudCBwbG90cywgYW5kIGluY2x1ZGUgdGl0bGVzIGFuZCBheGlzIGxhYmVscyBmb3IgeW91ciBoaXN0b2dyYW0gYW5kIGRlbnNpdHkgcGxvdC4=