Phillips 10.6 Q1-Q8

Q1 Load the dataset from https://raw.githubusercontent.com/ndphillips/ThePiratesGuideToR/master/data/caffeinestudy.txt as a new dataframe called caffeine.


caffeine<-read.table(file="/Users/silvanamontanola/Desktop/Quantitative/Code Files/Week 3/caffeinestudy.txt", 
           header=TRUE, 
           sep="\t")

I saved the data .txt from the web and then loaded it into R by reading the table with the read.table function. Since the first row was the header, I specified it with a header=TRUE and defined that the data was delimited by tabs with the sep=|t

Q2: Calculate the mean age for each gender

aggregate(formula= age~gender, 
          FUN=mean,
          data=caffeine)
#Use the aggregate function. Specify the formula with the first argument (age) as the dependent variable and the second (gender) as the independent variable (aka the variable you are testing for)
#Identify the function with FUN and the name of the function (in this case mean)
#Finally, identify the data frame. 

or with dplyr

caffeine %>% #Identify the data set as caffeine %>% "And then"
  group_by(gender) %>% #identify what subset R should group by, in this case gender
  summarise(age =mean(age)) #Fin the mean of age and call it "age" in the column

The mean age for females is 24.58 years. The mean age for males is 24.94 years

Q3: Calculate the mean age for each drink

aggregate(formula=age~drink,
          FUN=mean,
          data=caffeine)
#The set up was the same as the previous one. The dependent variable is age. The independent variable is drink. 

or with dplyr

caffeine %>% 
  group_by(drink) %>%
  summarise(age=mean(age))
#Same set up as the previous one except I identified it should group by drink instead of gender

The mean age for coffee drinkers was 25.22 years. The mean age for green tea drinkers was 24.30 years.

Q4: Calculate the mean age for each combined level of both gender and drink

aggregate(formula=age~gender+drink,
          FUN=mean,
          data=caffeine)
#Here is the setup is similar to the previous two questions, except that I have two independent variables (gender and drink).
#When I did the set up I simply added the two levels of drink and gender by adding a + sign. 

or with dplyr

caffeine %>% 
  group_by(drink, gender) %>%
  summarise(age=mean(age))
`summarise()` has grouped output by 'drink'. You can override using the `.groups` argument.
#Same set up as the previous one except now I have two independent variables to group by instead of one.

The mean age of females who are coffee drinkers is 25.25 years. The mean age of males who are coffee drinkers is 25.18 years. The mean age of females who are green tea drinkers is 23.73 years. The mean age of males who are green tea drinkers is 24.75 years.

Q5: Calculate the median score for each age

aggregate(formula= score ~ age,
          FUN= median,
          data=caffeine)
#Same set up as Q2 and Q3 except the function is now median and not mean. The dependent variable is score and the independent variable is age. 

or with dplyr

caffeine %>% 
  group_by(age) %>%
  summarise(score=median(score))
#Same set up as Q2 and Q3 except the summarise is now for median and not mean

The median score for age 18 consumers is 21.25. The median score for age 19 consumers is 20.29 The median score for age 20 consumers is 30.16 The median score for age 21 consumers is 20.03 The median score for age 22 consumers is 21.79 The median score for age 23 consumers is 32.88 The median score for age 24 consumers is 42.70 The median score for age 25 consumers is 20.52 The median score for age 26 consumers is 46.20 The median score for age 27 consumers is 23.10 The median score for age 28 consumers is 32.34 The median score for age 29 consumers is 24.90 The median score for age 30 consumers is 13.01 The median score for age 31 consumers is 9.88 The median score for age 32 consumers is 7.85 The median score for age 33 consumers is 13.97

Q6: For men only, calculate the maximum score for each age

aggregate(formula=score~age,
          subset= gender=="male",
          FUN=max,
          data=caffeine)
#The formula is still the same aggregate as before. Here, however, we only want the max score for men, so we need to subset gender when gender is equal to "male". I also used the max function instead of median

or with dplyr

caffeine %>% #Identify the data set as caffeine %>% "And then"
  group_by(age) %>% #Subset by age with the group_by condition
  filter(gender=="male") %>% #here, I am adding a new condition, which is to filter only when gender is male
  summarise(score=max(score)) #Summarise by finding the max instead of the median or mean

The maximum score for consumers of each age (in years) is as follows: 21.25 for 18 years, 55.75 for 21 years, 11.01 for 22 years, 56.86 for 23 years, 55.16 for 24 years, 72.74 for 25 years, 61.19 for 26 years, 38.50 for 27 years, 62.57 for 28 years, 38.30 for 29 years, 9.51 for 30 years, and 13.97 for 33 years.

Q7: Create a dataframe showing, for each level of drink, the mean, median, maximum, and standard deviation of scores.

With dplyr

Q8: Only for females above the age of 20, create a table showing, for each combined level of drink and cups, the mean, median, maximum, and standard deviation of scores. Also include a column showing how many people were in each group.

drink.and.cups <- caffeine %>%
  group_by(drink,cups) %>%
  filter(age>20 & gender=="female") %>%
  summarise(mean=mean(score),
            median= median(score),
            max= max(score),
            sd=sd(score),
            n=n())
`summarise()` has grouped output by 'drink'. You can override using the `.groups` argument.
drink.and.cups
#Same set up as Q7 with dplyr. Here, I added a double condition that states I only want people whose age is above 20 and gender is female. In the summarise, I also asked R to give me a total count of the participants. 

Drennan Ch.2 Q1-Q2


load("~/Desktop/Quantitative/Code Files/Week 1/Scrapers.RData") #I already had the scrapers data on my computer, so I just needed to load it back into the environment

Q1: Calculate appropriate indexes of center to put a finer point. Try out the mean, median, and trimmed mean Which index of center makes most sense? Why? Summarise the comparison

Pine.Ridge.Mean
[1] 23.42941
Pine.Ridge.Median
[1] 22
Pine.Ridge.Trimmed
[1] 22.91333
Willow.Flats.Mean
[1] 34.63226
Willow.Flats.Median
[1] 39.4
Willow.Flats.Trimmed
[1] 33.692

With dyplr

Pine.Ridge %>% #Choose the Pine Ridge data set
  summarise(mean =mean(Length), 
            median=median(Length),
            trimmed= mean(Length, trim=0.2)) #Find the mean, median, and trimmed mean 

Pine.Ridge.Hist <-hist(Pine.Ridge$Length) #Create a histogram of the Pine Ridge data set to get an idea of how the data looks

Willow.Flats %>% #Choose the Willow Flats data set
  summarise(mean =mean(Length),
            median=median(Length),
            trimmed= mean(Length, trim=0.2))  #Find the mean, median, and trimmed mean 

Willow.Flats.Hist <-hist(Willow.Flats$Length) #Create a histogram of the Willow Flats data set to get an idea of how the data looks

Answer: Based on the histograms and the comparison between the different indexes of centers, I suggest the use of the median as the center of index. Willow Flats has an outlier which pulls the mean.The trimmed mean seems to actually get farther from the center of the histogram with a trim of 10%. A trim of 20% only gets the trimmed mean closer to the original mean but not closer to the median. Hence, I suggest the median as the most resistant index of center to compare both sites and get an accurate result.

Comparing both medians, it is clear that Willow Flats had, on average, bigger scrapers than the Pine Ridges site. Moreover, based on the difference between mean and median at Willow Flats site, it is clear that the outlier is a unique case that is heavily affecting the data set. It is suggested that the archaeologists goes back to the data to make sure this is not a mistake.

Q2 Using the same data, do the same for flint scrapers and chert scrapers, disregarding which site the scrapers came from. Try the mean, median, and trimmed mean again.Which index makes most sense for comparing the lengths of the scrapers made of different materials. Why?

Flint.Scrapers <- subset(Scrapers, Material =="Flint") #Subset the data to get only the information on the scrapers made of Flint
Chert.Scrapers <- subset (Scrapers, Material =="Chert") #Subset the data to get only the information on the scrapers made of Flint
Flint.Scrapers %>% #Choose the Flint Scrapers data set
  summarise(mean=mean(Length),
            median= median(Length),
            trimmed= mean(Length, trim=0.10)) #Find the mean, median, and trimmed mean
Chert.Scrapers %>% #Choose the Chert Scrapers data set
  summarise(mean=mean(Length), 
            median= median(Length),
            trimmed= mean(Length, trim=0.10)) #Find the mean, median, and trimmed mean

Without looking at a histogram, it seems that the mean, median, and trimmed mean are all behaving normally, suggesting that the data is unimodal and approaching a normal distribution. As such, I suggest using the mean since no outliers are affecting the mean value. Moreover, the mean allows for the use of the standard deviation to understand the rate of distribution. Since there are no outliers, I do not believe it is necessary or suggested to use the trimmed mean and delete a value

Comparing all these information (but taking into account that the median of the sites cannot be compared to the means of the materials), it is clear that scrapers made from Flints have, on average, longer length than those made from Chert. The Willow Flats’ site also has longer scraper lengths than the Pine Ridge site. As a result, it is safe to assume that Willow Flats has more scrapers made from Flints than those made from Chert.

Drennan Ch3 Q1-Q3

Q1: Begin to explore these two batches of numbers with histograms

load("~/Desktop/Quantitative/Code Files/Week 3/Nanxiong.RData") #Load the downloaded Nanxiong Data Set
Early.Bronze.Age <- Nanxiong [1:24,] #Slice the data by Age period to get just the Early Bronze Age
Late.Bronze.Age <- Nanxiong [25:51,] #Slice the data by the Age period to get just the Late Bronze Age
Early.Bronze.Age.Hist <-hist(Early.Bronze.Age$Area, breaks = 10, main="Early Bronze Age", xlab="Area") #Created a histogram to explore the Early Bronze Age data

Late.Bronze.Age.Hist <-hist(Late.Bronze.Age$Area, breaks=10, main="Late Bronze Age", xlab="Area") #Created a histogram to explore the Late Bronze Age data

Q2: Calculate the mean, median, and the 10% trimmed mean for each batch and then the index of spread that corresponds to each of these indexes of level. Which pair of indexes makes most sense to use here? Why?

Early.Bronze.Age %>% #Choose the Early Bronze Age data frame
  summarise(mean =mean(Area),
            median= median(Area),
            trimmed =mean(Area, trim=0.1),
            sd= sd(Area), 
            IQR= IQR(Area),
            winsorized= sd(Winsorize(Early.Bronze.Age$Area))) #Find the median, mean, trimmed mean, sd, IQR, and winsorized sd
Late.Bronze.Age %>% #Choose the Late Bronze Age data frame
  summarise(mean =mean(Area),
            median= median(Area),
            trimmed =mean(Area, trim=0.1),
            sd=sd(Area),
            IQR=IQR(Area),
            winsorized= sd(Winsorize(Early.Bronze.Age$Area))) #Find the median, mean, trimmed mean, sd, IQR, and winsorized sd

Q3: Based on the histogram and the indexes of level and spread, what observations would you make about changes in site size from Early Bronze Age to Late Bronze Age near Nanxiong? Based on the summary statistics, it appears that, on average, the Late Bronze Age period had bigger site sizes that Early Bronze Age. Moreover, there was more variability in the spread for Late Bronze Age than that of the Early Bronze Age, suggesting that although they were generally bigger, the sizes between the sites in this period also varied highly. Finally, it is important to note that there is an Early Bronze Age site with a particularly big size which is considered an outlier. I recommend checking the data as it could have been that this site was mislabeled.

Urdan Ch.4 Q1-Q5

Q1: In statistics, the word “distribution” comes up a lot. a. In your own words, explain what a distribution is A distribution is a set of things spread out across a continuum. In the case of statistics, it is a set of values spread usually from largest to smallest or viceversa. b. Then, again in your own words, explain what a normal distribution is Normal distribution is just an average distribution. In other words, it is when the set of values is spread in a common or predictable way. In statistics, a normal distribution is a theoretical model in which values are spread in an identifiable way perfectly useful for inferential statistics.

Q2: What does asymptomatic mean and why is it important? Asymptomatic means that the tails of the distribution never actually touch the baseline, or never actually reach absolute zero. Thus is important because it indicates that the probability of something happening by chance is never 0.

Q3: In statistics, we use the normal distribution a lot a. What is so great about it? Normal distributions are perfect for understanding big populations as they usually approach the theoretical model of the normal distribution. Hence, this model helps us to do inferential and probability statistics to get a better understanding of our population.

b. Describe something that the normal distribution lets us, statisticians, do that we cannot do without it Without the normal distribution, we would not be able to infer and draw clear conclusions about our data in order to generalize. In other words, we would not be able to do probability or inferential statistics.

Q4: Many believe that most human traits form a normal distribution. Height, weight, intelligence, musical ability, friendliness, attractiveness, etc. are all examples of things that might form a normal distribution a. First, explain whether you agree with this assumption, and why or why not. I would agree with most of these assumptions since height and weight are continuous variables and can go on for both extremes. However, I would hesitate to say attractiveness follows a normal distribution because it makes it sound like attractiveness is a scientific reality when in reality it is a social construct.

b. Second, think of an example of a trait that does NOT form a normal distribution in the population. A trait that does not form a normal distribution is people who are killers, people who are left-handed (since there are more right-handed people). Probably, people who speak Latin would also be an example.

Q5: If you know that in the population adults the average number of hours slept per night is 7 with a standard deviation of 2, what proportion of the population would you expect to sleep between 7 and 9 hours per night? I would expect about 34% of people to sleep between 7 and 9 hours per night since 34% of the population is encompassed between 1 sd of the mean.

LS0tCnRpdGxlOiAiUHJvYmxlbSBTZXQgMy0gU2lsdmFuYSBNb250YW5vbGEiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KIyBQaGlsbGlwcyAxMC42IFExLVE4CgoqKlExIExvYWQgdGhlIGRhdGFzZXQgZnJvbSoqIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uZHBoaWxsaXBzL1RoZVBpcmF0ZXNHdWlkZVRvUi9tYXN0ZXIvZGF0YS9jYWZmZWluZXN0dWR5LnR4dCBhcyBhIG5ldyBkYXRhZnJhbWUgY2FsbGVkIGNhZmZlaW5lLgoKYGBge3J9CgpjYWZmZWluZTwtcmVhZC50YWJsZShmaWxlPSIvVXNlcnMvc2lsdmFuYW1vbnRhbm9sYS9EZXNrdG9wL1F1YW50aXRhdGl2ZS9Db2RlIEZpbGVzL1dlZWsgMy9jYWZmZWluZXN0dWR5LnR4dCIsIAogICAgICAgICAgIGhlYWRlcj1UUlVFLCAKICAgICAgICAgICBzZXA9Ilx0IikKYGBgCkkgc2F2ZWQgdGhlIGRhdGEgLnR4dCBmcm9tIHRoZSB3ZWIgYW5kIHRoZW4gbG9hZGVkIGl0IGludG8gUiBieSByZWFkaW5nIHRoZSB0YWJsZSB3aXRoIHRoZSByZWFkLnRhYmxlIGZ1bmN0aW9uLiBTaW5jZSB0aGUgZmlyc3Qgcm93IHdhcyB0aGUgaGVhZGVyLCBJIHNwZWNpZmllZCBpdCB3aXRoIGEgaGVhZGVyPVRSVUUgYW5kIGRlZmluZWQgdGhhdCB0aGUgZGF0YSB3YXMgZGVsaW1pdGVkIGJ5IHRhYnMgd2l0aCB0aGUgc2VwPXx0CgoqKlEyOiBDYWxjdWxhdGUgdGhlIG1lYW4gYWdlIGZvciBlYWNoIGdlbmRlcioqCmBgYHtyfQphZ2dyZWdhdGUoZm9ybXVsYT0gYWdlfmdlbmRlciwgCiAgICAgICAgICBGVU49bWVhbiwKICAgICAgICAgIGRhdGE9Y2FmZmVpbmUpCiNVc2UgdGhlIGFnZ3JlZ2F0ZSBmdW5jdGlvbi4gU3BlY2lmeSB0aGUgZm9ybXVsYSB3aXRoIHRoZSBmaXJzdCBhcmd1bWVudCAoYWdlKSBhcyB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGFuZCB0aGUgc2Vjb25kIChnZW5kZXIpIGFzIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZSAoYWthIHRoZSB2YXJpYWJsZSB5b3UgYXJlIHRlc3RpbmcgZm9yKQojSWRlbnRpZnkgdGhlIGZ1bmN0aW9uIHdpdGggRlVOIGFuZCB0aGUgbmFtZSBvZiB0aGUgZnVuY3Rpb24gKGluIHRoaXMgY2FzZSBtZWFuKQojRmluYWxseSwgaWRlbnRpZnkgdGhlIGRhdGEgZnJhbWUuIApgYGAKCm9yIHdpdGggZHBseXIgCmBgYHtyfQpjYWZmZWluZSAlPiUgI0lkZW50aWZ5IHRoZSBkYXRhIHNldCBhcyBjYWZmZWluZSAlPiUgIkFuZCB0aGVuIgogIGdyb3VwX2J5KGdlbmRlcikgJT4lICNpZGVudGlmeSB3aGF0IHN1YnNldCBSIHNob3VsZCBncm91cCBieSwgaW4gdGhpcyBjYXNlIGdlbmRlcgogIHN1bW1hcmlzZShhZ2UgPW1lYW4oYWdlKSkgI0ZpbiB0aGUgbWVhbiBvZiBhZ2UgYW5kIGNhbGwgaXQgImFnZSIgaW4gdGhlIGNvbHVtbgpgYGAKVGhlIG1lYW4gYWdlIGZvciBmZW1hbGVzIGlzIDI0LjU4IHllYXJzLiAKVGhlIG1lYW4gYWdlIGZvciBtYWxlcyBpcyAyNC45NCB5ZWFycwoKKipRMzogQ2FsY3VsYXRlIHRoZSBtZWFuIGFnZSBmb3IgZWFjaCBkcmluayoqCmBgYHtyfQphZ2dyZWdhdGUoZm9ybXVsYT1hZ2V+ZHJpbmssCiAgICAgICAgICBGVU49bWVhbiwKICAgICAgICAgIGRhdGE9Y2FmZmVpbmUpCiNUaGUgc2V0IHVwIHdhcyB0aGUgc2FtZSBhcyB0aGUgcHJldmlvdXMgb25lLiBUaGUgZGVwZW5kZW50IHZhcmlhYmxlIGlzIGFnZS4gVGhlIGluZGVwZW5kZW50IHZhcmlhYmxlIGlzIGRyaW5rLiAKYGBgCgoKb3Igd2l0aCBkcGx5ciAKYGBge3J9CmNhZmZlaW5lICU+JSAKICBncm91cF9ieShkcmluaykgJT4lCiAgc3VtbWFyaXNlKGFnZT1tZWFuKGFnZSkpCiNTYW1lIHNldCB1cCBhcyB0aGUgcHJldmlvdXMgb25lIGV4Y2VwdCBJIGlkZW50aWZpZWQgaXQgc2hvdWxkIGdyb3VwIGJ5IGRyaW5rIGluc3RlYWQgb2YgZ2VuZGVyCmBgYApUaGUgbWVhbiBhZ2UgZm9yIGNvZmZlZSBkcmlua2VycyB3YXMgMjUuMjIgeWVhcnMuIApUaGUgbWVhbiBhZ2UgZm9yIGdyZWVuIHRlYSBkcmlua2VycyB3YXMgMjQuMzAgeWVhcnMuCgoqKlE0OiBDYWxjdWxhdGUgdGhlIG1lYW4gYWdlIGZvciBlYWNoIGNvbWJpbmVkIGxldmVsIG9mIGJvdGggZ2VuZGVyIGFuZCBkcmluayoqCmBgYHtyfQphZ2dyZWdhdGUoZm9ybXVsYT1hZ2V+Z2VuZGVyK2RyaW5rLAogICAgICAgICAgRlVOPW1lYW4sCiAgICAgICAgICBkYXRhPWNhZmZlaW5lKQojSGVyZSBpcyB0aGUgc2V0dXAgaXMgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgdHdvIHF1ZXN0aW9ucywgZXhjZXB0IHRoYXQgSSBoYXZlIHR3byBpbmRlcGVuZGVudCB2YXJpYWJsZXMgKGdlbmRlciBhbmQgZHJpbmspLgojV2hlbiBJIGRpZCB0aGUgc2V0IHVwIEkgc2ltcGx5IGFkZGVkIHRoZSB0d28gbGV2ZWxzIG9mIGRyaW5rIGFuZCBnZW5kZXIgYnkgYWRkaW5nIGEgKyBzaWduLiAKYGBgCgpvciB3aXRoIGRwbHlyCmBgYHtyfQpjYWZmZWluZSAlPiUgCiAgZ3JvdXBfYnkoZHJpbmssIGdlbmRlcikgJT4lCiAgc3VtbWFyaXNlKGFnZT1tZWFuKGFnZSkpCiNTYW1lIHNldCB1cCBhcyB0aGUgcHJldmlvdXMgb25lIGV4Y2VwdCBub3cgSSBoYXZlIHR3byBpbmRlcGVuZGVudCB2YXJpYWJsZXMgdG8gZ3JvdXAgYnkgaW5zdGVhZCBvZiBvbmUuCmBgYAoKVGhlIG1lYW4gYWdlIG9mIGZlbWFsZXMgd2hvIGFyZSBjb2ZmZWUgZHJpbmtlcnMgaXMgMjUuMjUgeWVhcnMuIApUaGUgbWVhbiBhZ2Ugb2YgbWFsZXMgd2hvIGFyZSBjb2ZmZWUgZHJpbmtlcnMgaXMgMjUuMTggeWVhcnMuClRoZSBtZWFuIGFnZSBvZiBmZW1hbGVzIHdobyBhcmUgZ3JlZW4gdGVhIGRyaW5rZXJzIGlzIDIzLjczIHllYXJzLgpUaGUgbWVhbiBhZ2Ugb2YgbWFsZXMgd2hvIGFyZSBncmVlbiB0ZWEgZHJpbmtlcnMgaXMgMjQuNzUgeWVhcnMuIAoKKipRNTogQ2FsY3VsYXRlIHRoZSBtZWRpYW4gc2NvcmUgZm9yIGVhY2ggYWdlKioKYGBge3J9CmFnZ3JlZ2F0ZShmb3JtdWxhPSBzY29yZSB+IGFnZSwKICAgICAgICAgIEZVTj0gbWVkaWFuLAogICAgICAgICAgZGF0YT1jYWZmZWluZSkKI1NhbWUgc2V0IHVwIGFzIFEyIGFuZCBRMyBleGNlcHQgdGhlIGZ1bmN0aW9uIGlzIG5vdyBtZWRpYW4gYW5kIG5vdCBtZWFuLiBUaGUgZGVwZW5kZW50IHZhcmlhYmxlIGlzIHNjb3JlIGFuZCB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUgaXMgYWdlLiAKYGBgCgpvciB3aXRoIGRwbHlyCmBgYHtyfQpjYWZmZWluZSAlPiUgCiAgZ3JvdXBfYnkoYWdlKSAlPiUKICBzdW1tYXJpc2Uoc2NvcmU9bWVkaWFuKHNjb3JlKSkKI1NhbWUgc2V0IHVwIGFzIFEyIGFuZCBRMyBleGNlcHQgdGhlIHN1bW1hcmlzZSBpcyBub3cgZm9yIG1lZGlhbiBhbmQgbm90IG1lYW4KYGBgClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAxOCBjb25zdW1lcnMgaXMgMjEuMjUuClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAxOSBjb25zdW1lcnMgaXMgMjAuMjkKVGhlIG1lZGlhbiBzY29yZSBmb3IgYWdlIDIwIGNvbnN1bWVycyBpcyAzMC4xNgpUaGUgbWVkaWFuIHNjb3JlIGZvciBhZ2UgMjEgY29uc3VtZXJzIGlzIDIwLjAzClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAyMiBjb25zdW1lcnMgaXMgMjEuNzkKVGhlIG1lZGlhbiBzY29yZSBmb3IgYWdlIDIzIGNvbnN1bWVycyBpcyAzMi44OApUaGUgbWVkaWFuIHNjb3JlIGZvciBhZ2UgMjQgY29uc3VtZXJzIGlzIDQyLjcwClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAyNSBjb25zdW1lcnMgaXMgMjAuNTIKVGhlIG1lZGlhbiBzY29yZSBmb3IgYWdlIDI2IGNvbnN1bWVycyBpcyA0Ni4yMApUaGUgbWVkaWFuIHNjb3JlIGZvciBhZ2UgMjcgY29uc3VtZXJzIGlzIDIzLjEwClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAyOCBjb25zdW1lcnMgaXMgMzIuMzQKVGhlIG1lZGlhbiBzY29yZSBmb3IgYWdlIDI5IGNvbnN1bWVycyBpcyAyNC45MApUaGUgbWVkaWFuIHNjb3JlIGZvciBhZ2UgMzAgY29uc3VtZXJzIGlzIDEzLjAxClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAzMSBjb25zdW1lcnMgaXMgOS44OCAKVGhlIG1lZGlhbiBzY29yZSBmb3IgYWdlIDMyIGNvbnN1bWVycyBpcyA3Ljg1ClRoZSBtZWRpYW4gc2NvcmUgZm9yIGFnZSAzMyBjb25zdW1lcnMgaXMgMTMuOTcKCioqUTY6IEZvciBtZW4gb25seSwgY2FsY3VsYXRlIHRoZSBtYXhpbXVtIHNjb3JlIGZvciBlYWNoIGFnZSoqCmBgYHtyfQphZ2dyZWdhdGUoZm9ybXVsYT1zY29yZX5hZ2UsCiAgICAgICAgICBzdWJzZXQ9IGdlbmRlcj09Im1hbGUiLAogICAgICAgICAgRlVOPW1heCwKICAgICAgICAgIGRhdGE9Y2FmZmVpbmUpCiNUaGUgZm9ybXVsYSBpcyBzdGlsbCB0aGUgc2FtZSBhZ2dyZWdhdGUgYXMgYmVmb3JlLiBIZXJlLCBob3dldmVyLCB3ZSBvbmx5IHdhbnQgdGhlIG1heCBzY29yZSBmb3IgbWVuLCBzbyB3ZSBuZWVkIHRvIHN1YnNldCBnZW5kZXIgd2hlbiBnZW5kZXIgaXMgZXF1YWwgdG8gIm1hbGUiLiBJIGFsc28gdXNlZCB0aGUgbWF4IGZ1bmN0aW9uIGluc3RlYWQgb2YgbWVkaWFuCmBgYAoKb3Igd2l0aCBkcGx5cgpgYGB7cn0KY2FmZmVpbmUgJT4lICNJZGVudGlmeSB0aGUgZGF0YSBzZXQgYXMgY2FmZmVpbmUgJT4lICJBbmQgdGhlbiIKICBncm91cF9ieShhZ2UpICU+JSAjU3Vic2V0IGJ5IGFnZSB3aXRoIHRoZSBncm91cF9ieSBjb25kaXRpb24KICBmaWx0ZXIoZ2VuZGVyPT0ibWFsZSIpICU+JSAjaGVyZSwgSSBhbSBhZGRpbmcgYSBuZXcgY29uZGl0aW9uLCB3aGljaCBpcyB0byBmaWx0ZXIgb25seSB3aGVuIGdlbmRlciBpcyBtYWxlCiAgc3VtbWFyaXNlKHNjb3JlPW1heChzY29yZSkpICNTdW1tYXJpc2UgYnkgZmluZGluZyB0aGUgbWF4IGluc3RlYWQgb2YgdGhlIG1lZGlhbiBvciBtZWFuCmBgYApUaGUgbWF4aW11bSBzY29yZSBmb3IgY29uc3VtZXJzIG9mIGVhY2ggYWdlIChpbiB5ZWFycykgaXMgYXMgZm9sbG93czogMjEuMjUgZm9yIDE4IHllYXJzLCA1NS43NSBmb3IgMjEgeWVhcnMsIDExLjAxIGZvciAyMiB5ZWFycywgNTYuODYgZm9yIDIzIHllYXJzLCA1NS4xNiBmb3IgMjQgeWVhcnMsIDcyLjc0IGZvciAyNSB5ZWFycywgNjEuMTkgZm9yIDI2IHllYXJzLCAzOC41MCBmb3IgMjcgeWVhcnMsIDYyLjU3IGZvciAyOCB5ZWFycywgMzguMzAgZm9yIDI5IHllYXJzLCA5LjUxIGZvciAzMCB5ZWFycywgYW5kIDEzLjk3IGZvciAzMyB5ZWFycy4gCgoqKlE3OiBDcmVhdGUgYSBkYXRhZnJhbWUgc2hvd2luZywgZm9yIGVhY2ggbGV2ZWwgb2YgZHJpbmssIHRoZSBtZWFuLCBtZWRpYW4sIG1heGltdW0sIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2Ygc2NvcmVzLioqCmBgYHtyfQptZWFuLnNjb3JlLmRyaW5rIDwtYWdncmVnYXRlKGZvcm11bGE9c2NvcmV+ZHJpbmssIAogICAgICAgICAgRlVOPW1lYW4sCiAgICAgICAgICBkYXRhPWNhZmZlaW5lKSAjQWdncmVnYXRlZCB0aGUgc2NvcmUgYnkgZHJpbmsgbGV2ZWwgYW5kIGZvdW5kIHRoZSBtZWFuCm1lYW4uc2NvcmUuZHJpbmsgPC1yZW5hbWUobWVhbi5zY29yZS5kcmluaywgbWVhbj1zY29yZSkgI1JlbmFtZSB0aGUgc2NvcmUgY29sdW1uIGFzIG1lYW4gdGhlbiByZW5hbWUgdGhlIG9iamVjdAoKbWVkaWFuLnNjb3JlLmRyaW5rIDwtYWdncmVnYXRlKGZvcm11bGE9c2NvcmV+ZHJpbmssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTj1tZWRpYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1jYWZmZWluZSkgI0FnZ3JlZ2F0ZWQgdGhlIHNjb3JlIGJ5IGRyaW5rIGxldmVsIGFuZCBmb3VuZCB0aGUgbWVkaWFuCm1lZGlhbi5zY29yZS5kcmluayA8LXJlbmFtZShtZWRpYW4uc2NvcmUuZHJpbmssIG1lZGlhbj1zY29yZSkgI1RoaXMgZGlkIG5vdCB3b3JrIGJlY2F1c2Ugd2hlbiBJIG1lcmdlZCB0aGVtLCB0aGUgZGF0YS5mcmFtZSB3b3VsZCBzdGlsbCBicmluZyBiYWNrIHNjb3JlLnggYW5kIHNjb3JlLnkgYXMgdGhlIG5hbWVzIG9mIHRoZSBjb2x1bW5zCiNJIGhhdmUgZGVjaWRlZCB0byByZW5hbWUgYXQgdGhlIGVuZCBvZiBteSBtZXJnZSB0byBoYXZlIGEgY2xlYXIgY29sdW1uIG5hbWUKbWF4LnNjb3JlLmRyaW5rIDwtYWdncmVnYXRlKGZvcm11bGE9c2NvcmV+ZHJpbmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVU49bWF4LCAjQWdncmVnYXRlZCB0aGUgc2NvcmUgYnkgZHJpbmsgbGV2ZWwgYW5kIGZvdW5kIHRoZSBtYXggc2NvcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWNhZmZlaW5lKQpzZC5zY29yZS5kcmluayA8LWFnZ3JlZ2F0ZShmb3JtdWxhPXNjb3JlfmRyaW5rLCAjQWdncmVnYXRlZCB0aGUgc2NvcmUgYnkgZHJpbmsgbGV2ZWwgYW5kIGZvdW5kIHRoZSBzZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOPXNkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWNhZmZlaW5lKQpzY29yZS5ieS5sZXZlbCA8LSBtZXJnZShtZWFuLnNjb3JlLmRyaW5rLCBtZWRpYW4uc2NvcmUuZHJpbmssCiAgICAgICAgICAgICAgICAgICAgICAgIGJ5PSAiZHJpbmsiLAogICAgICAgICAgICAgICAgICAgICAgICBhbGw9VFJVRSkgI21lcmdlZCB0aGUgbWVkaWFuIGFuZCBtZWFuIGluZm9ybWF0aW9uIGludG8gb25lIGRhdGEuZnJhbWUKc2NvcmUuYnkubGV2ZWwuMiA8LSBtZXJnZShtYXguc2NvcmUuZHJpbmssIHNkLnNjb3JlLmRyaW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgIGJ5PSJkcmluayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsPVRSVUUpICNtZXJnZWQgdGhlIG1heCBhbmQgc2QgaW5mb3JtYXRpb24gaW50byBvbmUgZGF0YS5mcmFtZQpzY29yZS5ieS5sZXZlbC5maW5hbCA8LW1lcmdlKHNjb3JlLmJ5LmxldmVsLCBzY29yZS5ieS5sZXZlbC4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5PSJkcmluayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsPVRSVUUpICNtZXJnZWQgdGhlIHByZXZpb3VzbHkgY3JlYXRlZCBkYXRhIGZyYW1lcyBhYm92ZSBpbnRvIG9uZSwgaW4gb3JkZXIgdG8gaGF2ZSBhIHNpbmdsZSBkYXRhIHNldCB3aXRoIG1lZGlhbiwgbWVhbiwgc2QsIGFuZCBtYXggc2NvcmUKYW5vdGhlci50cnkgPC1tZXJnZShtZXJnZShtZWFuLnNjb3JlLmRyaW5rLCBtZWRpYW4uc2NvcmUuZHJpbmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnk9ICJkcmluayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsPVRSVUUpLCBtZXJnZShtYXguc2NvcmUuZHJpbmssIHNkLnNjb3JlLmRyaW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnk9ImRyaW5rIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbD1UUlVFKSwKICAgICAgICAgICAgICAgICAgICBieT0iZHJpbmsiKSAjSGVyZSBJIHRyaWVkIG5lc3RpbmcgYWxsIHRoZSBwcmV2aW91cyBtZXJnZXMgaW50byBqdXN0IG9uZSBmdW5jdGlvbgojTmVzdGluZyB3YXMgaGFyZCBoZXJlLiBJcyB0aGlzIGhvdyB5b3UgbmVzdF4/CmFub3RoZXIudHJ5IDwtcmVuYW1lKGFub3RoZXIudHJ5LCBtYXg9IHNjb3JlLngsIHNkPXNjb3JlLnkpCiNJIHJlbmFtZWQgdGhlIGxhc3QgZGF0YS5mcmFtZSB0byBwcm9wZXJseSBzaG93IHdoYXQgZWFjaCBjb2x1bW4gcmVwcmVzZW50ZWQgCmFub3RoZXIudHJ5CmBgYAoKV2l0aCBkcGx5ciAKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpICNJbnN0YWxsZWQgZHBseXIgZm9yIHRoZSBmaXJzdCB0aW1lLgpsaWJyYXJ5KCJkcGx5ciIpICNsb2FkZWQgaXQgaWYgaXQgd2FzIG5vdCBhbHJlYWR5IGxvYWRlZApkcmluay5hZ2dyZWdhdGUgPC0gY2FmZmVpbmUgJT4lICNpZGVudGlmaWVkIG15IGRhdGEuZnJhbWUgYW5kIHRvbGQgUiB0aGVyZSBpcyBtb3JlIGNvbWluZyAlPiUKICBncm91cF9ieShkcmluaykgJT4lICNTdXNiZXQgYnkgZHJpbmsKICBzdW1tYXJpc2UobWVhbj0gbWVhbihzY29yZSksIAogICAgICAgICAgICBtZWRpYW4gPW1lZGlhbihzY29yZSksCiAgICAgICAgICAgIG1heCA9bWF4KHNjb3JlKSwKICAgICAgICAgICAgc2Q9IHNkKHNjb3JlKSkKZHJpbmsuYWdncmVnYXRlCiNHaXZlcyBtZSBhIHN1bW1hcnkgb2YgbWVhbiwgbWVkaWFuLCBtYXgsIGFuZCBzZC4gVGhpcyBpcyBlYXNpZXIgYW5kIGZhc3RlciB0aGFuIHRoZSBwcmV2aW91cyBjb2RlLCBzaW5jZSBJIGNhbiBqdXN0IGFzayBSIHRvIGdpdmUgbWUgYWxsIHRoZSBzdW1tYXJpZXMgaW4gYSBjaGFydApgYGAKCioqUTg6IE9ubHkgZm9yIGZlbWFsZXMgYWJvdmUgdGhlIGFnZSBvZiAyMCwgY3JlYXRlIGEgdGFibGUgc2hvd2luZywgZm9yIGVhY2ggY29tYmluZWQgbGV2ZWwgb2YgZHJpbmsgYW5kIGN1cHMsIHRoZSBtZWFuLCBtZWRpYW4sIG1heGltdW0sIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2Ygc2NvcmVzLiBBbHNvIGluY2x1ZGUgYSBjb2x1bW4gc2hvd2luZyBob3cgbWFueSBwZW9wbGUgd2VyZSBpbiBlYWNoIGdyb3VwLioqCmBgYHtyfQpkcmluay5hbmQuY3VwcyA8LSBjYWZmZWluZSAlPiUKICBncm91cF9ieShkcmluayxjdXBzKSAlPiUKICBmaWx0ZXIoYWdlPjIwICYgZ2VuZGVyPT0iZmVtYWxlIikgJT4lCiAgc3VtbWFyaXNlKG1lYW49bWVhbihzY29yZSksCiAgICAgICAgICAgIG1lZGlhbj0gbWVkaWFuKHNjb3JlKSwKICAgICAgICAgICAgbWF4PSBtYXgoc2NvcmUpLAogICAgICAgICAgICBzZD1zZChzY29yZSksCiAgICAgICAgICAgIG49bigpKQpkcmluay5hbmQuY3VwcwojU2FtZSBzZXQgdXAgYXMgUTcgd2l0aCBkcGx5ci4gSGVyZSwgSSBhZGRlZCBhIGRvdWJsZSBjb25kaXRpb24gdGhhdCBzdGF0ZXMgSSBvbmx5IHdhbnQgcGVvcGxlIHdob3NlIGFnZSBpcyBhYm92ZSAyMCBhbmQgZ2VuZGVyIGlzIGZlbWFsZS4gSW4gdGhlIHN1bW1hcmlzZSwgSSBhbHNvIGFza2VkIFIgdG8gZ2l2ZSBtZSBhIHRvdGFsIGNvdW50IG9mIHRoZSBwYXJ0aWNpcGFudHMuIApgYGAKCgojIERyZW5uYW4gQ2guMiBRMS1RMgpgYGB7cn0KCmxvYWQoIn4vRGVza3RvcC9RdWFudGl0YXRpdmUvQ29kZSBGaWxlcy9XZWVrIDEvU2NyYXBlcnMuUkRhdGEiKSAjSSBhbHJlYWR5IGhhZCB0aGUgc2NyYXBlcnMgZGF0YSBvbiBteSBjb21wdXRlciwgc28gSSBqdXN0IG5lZWRlZCB0byBsb2FkIGl0IGJhY2sgaW50byB0aGUgZW52aXJvbm1lbnQKYGBgCgoqKlExOiBDYWxjdWxhdGUgYXBwcm9wcmlhdGUgaW5kZXhlcyBvZiBjZW50ZXIgdG8gcHV0IGEgZmluZXIgcG9pbnQuIFRyeSBvdXQgdGhlIG1lYW4sIG1lZGlhbiwgYW5kIHRyaW1tZWQgbWVhbiBXaGljaCBpbmRleCBvZiBjZW50ZXIgbWFrZXMgbW9zdCBzZW5zZT8gV2h5PyBTdW1tYXJpc2UgdGhlIGNvbXBhcmlzb24qKgpgYGB7cn0KUGluZS5SaWRnZSA8LVNjcmFwZXJzIFsxOjE3LF0gI1NsaWNlIHRoZSBkYXRhLmZyYW1lIHRvIGdldCBvbmx5IHRoZSBQaW5lIFJpZGdlIGRhdGEgYW5kIGZpbmQgaXRzIGluZGV4ZXMgb2YgY2VudGVycwpQaW5lLlJpZGdlLk1lYW4gPC0gbWVhbihQaW5lLlJpZGdlJExlbmd0aCkgI1VzaW5nIHRoZSBtZWFuIGZ1bmN0aW9uIGFuZCB0aGUgUGluZS5SaWRnZSBuZXcgZGF0YS5mcmFtZSBJIHN1YnNldCBieSBsZW5ndGggdG8gZ2V0IHRoZSBtZWFuIG9mIHRob3NlIG51bWVyaWNhbCB2YWx1ZXMKUGluZS5SaWRnZS5NZWRpYW4gPC1tZWRpYW4oUGluZS5SaWRnZSRMZW5ndGgpICNTYW1lIGhlcmUsIGJ1dCBmb3IgdGhlIG1lZGlhbgpQaW5lLlJpZGdlLlRyaW1tZWQgPC1tZWFuKFBpbmUuUmlkZ2UkTGVuZ3RoLCB0cmltPTAuMTApICNTYW1lIGhlcmUgYnV0IGZvciB0aGUgdHJpbW1lZCBtZWFuLiBJIGNob3NlIGEgdHJpbSBvZiAxMCUuIE5vdGljZSB0aGF0IGl0IGlzIHRoZSBzYW1lIG1lYW4gZnVuY3Rpb24gd2l0aCBhbiBhZGRlZCBjb25kaXRpb24gdG8gbWFrZSBpdCB0cmltbWVkLiAKUGluZS5SaWRnZS5NZWFuClBpbmUuUmlkZ2UuTWVkaWFuClBpbmUuUmlkZ2UuVHJpbW1lZApgYGAKCmBgYHtyfQpXaWxsb3cuRmxhdHMgPC0gU2NyYXBlcnNbMTg6NDgsXSAjU2xpY2UgdGhlIGRhdGEuZnJhbWUgdG8gZ2V0IG9ubHkgdGhlIFdpbGxvdyBGbGF0cyBkYXRhIGFuZCBmaW5kIGl0cyBpbmRleGVzIG9mIGNlbnRlcnMKV2lsbG93LkZsYXRzLk1lYW4gPC0gbWVhbihXaWxsb3cuRmxhdHMkTGVuZ3RoKSAjVXNpbmcgdGhlIG1lYW4gZnVuY3Rpb24gYW5kIHRoZSBXaWxsb3cuRmxhdHMgbmV3IGRhdGEuZnJhbWUgSSBzdWJzZXQgYnkgbGVuZ3RoIHRvIGdldCB0aGUgbWVhbiBvZiB0aG9zZSBudW1lcmljYWwgdmFsdWVzCldpbGxvdy5GbGF0cy5NZWRpYW4gPC1tZWRpYW4oV2lsbG93LkZsYXRzJExlbmd0aCkgI1NhbWUgaGVyZSwgYnV0IGZvciB0aGUgbWVkaWFuCldpbGxvdy5GbGF0cy5UcmltbWVkIDwtbWVhbihXaWxsb3cuRmxhdHMkTGVuZ3RoLCB0cmltPTAuMTApICNTYW1lIGhlcmUgYnV0IGZvciB0aGUgdHJpbW1lZCBtZWFuLiBJIGNob3NlIGEgdHJpbSBvZiAxMCUuCldpbGxvdy5GbGF0cy5NZWFuCldpbGxvdy5GbGF0cy5NZWRpYW4KV2lsbG93LkZsYXRzLlRyaW1tZWQKYGBgCgoKV2l0aCBkeXBscgpgYGB7cn0KUGluZS5SaWRnZSAlPiUgI0Nob29zZSB0aGUgUGluZSBSaWRnZSBkYXRhIHNldAogIHN1bW1hcmlzZShtZWFuID1tZWFuKExlbmd0aCksIAogICAgICAgICAgICBtZWRpYW49bWVkaWFuKExlbmd0aCksCiAgICAgICAgICAgIHRyaW1tZWQ9IG1lYW4oTGVuZ3RoLCB0cmltPTAuMikpICNGaW5kIHRoZSBtZWFuLCBtZWRpYW4sIGFuZCB0cmltbWVkIG1lYW4gCgpQaW5lLlJpZGdlLkhpc3QgPC1oaXN0KFBpbmUuUmlkZ2UkTGVuZ3RoKSAjQ3JlYXRlIGEgaGlzdG9ncmFtIG9mIHRoZSBQaW5lIFJpZGdlIGRhdGEgc2V0IHRvIGdldCBhbiBpZGVhIG9mIGhvdyB0aGUgZGF0YSBsb29rcwpgYGAKCgpgYGB7cn0KV2lsbG93LkZsYXRzICU+JSAjQ2hvb3NlIHRoZSBXaWxsb3cgRmxhdHMgZGF0YSBzZXQKICBzdW1tYXJpc2UobWVhbiA9bWVhbihMZW5ndGgpLAogICAgICAgICAgICBtZWRpYW49bWVkaWFuKExlbmd0aCksCiAgICAgICAgICAgIHRyaW1tZWQ9IG1lYW4oTGVuZ3RoLCB0cmltPTAuMikpICAjRmluZCB0aGUgbWVhbiwgbWVkaWFuLCBhbmQgdHJpbW1lZCBtZWFuIAoKV2lsbG93LkZsYXRzLkhpc3QgPC1oaXN0KFdpbGxvdy5GbGF0cyRMZW5ndGgpICNDcmVhdGUgYSBoaXN0b2dyYW0gb2YgdGhlIFdpbGxvdyBGbGF0cyBkYXRhIHNldCB0byBnZXQgYW4gaWRlYSBvZiBob3cgdGhlIGRhdGEgbG9va3MKYGBgCgpBbnN3ZXI6IEJhc2VkIG9uIHRoZSBoaXN0b2dyYW1zIGFuZCB0aGUgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBkaWZmZXJlbnQgaW5kZXhlcyBvZiBjZW50ZXJzLCBJIHN1Z2dlc3QgdGhlIHVzZSBvZiB0aGUgbWVkaWFuIGFzIHRoZSBjZW50ZXIgb2YgaW5kZXguIFdpbGxvdyBGbGF0cyBoYXMgYW4gb3V0bGllciB3aGljaCBwdWxscyB0aGUgbWVhbi5UaGUgdHJpbW1lZCBtZWFuIHNlZW1zIHRvIGFjdHVhbGx5IGdldCBmYXJ0aGVyIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgaGlzdG9ncmFtIHdpdGggYSB0cmltIG9mIDEwJS4gQSB0cmltIG9mIDIwJSBvbmx5IGdldHMgdGhlIHRyaW1tZWQgbWVhbiBjbG9zZXIgdG8gdGhlIG9yaWdpbmFsIG1lYW4gYnV0IG5vdCBjbG9zZXIgdG8gdGhlIG1lZGlhbi4gSGVuY2UsIEkgc3VnZ2VzdCB0aGUgbWVkaWFuIGFzIHRoZSBtb3N0IHJlc2lzdGFudCBpbmRleCBvZiBjZW50ZXIgdG8gY29tcGFyZSBib3RoIHNpdGVzIGFuZCBnZXQgYW4gYWNjdXJhdGUgcmVzdWx0LgoKQ29tcGFyaW5nIGJvdGggbWVkaWFucywgaXQgaXMgY2xlYXIgdGhhdCBXaWxsb3cgRmxhdHMgaGFkLCBvbiBhdmVyYWdlLCBiaWdnZXIgc2NyYXBlcnMgdGhhbiB0aGUgUGluZSBSaWRnZXMgc2l0ZS4gTW9yZW92ZXIsIGJhc2VkIG9uIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gbWVhbiBhbmQgbWVkaWFuIGF0IFdpbGxvdyBGbGF0cyBzaXRlLCBpdCBpcyBjbGVhciB0aGF0IHRoZSBvdXRsaWVyIGlzIGEgdW5pcXVlIGNhc2UgdGhhdCBpcyBoZWF2aWx5IGFmZmVjdGluZyB0aGUgZGF0YSBzZXQuIEl0IGlzIHN1Z2dlc3RlZCB0aGF0IHRoZSBhcmNoYWVvbG9naXN0cyBnb2VzIGJhY2sgdG8gdGhlIGRhdGEgdG8gbWFrZSBzdXJlIHRoaXMgaXMgbm90IGEgbWlzdGFrZS4gCgoKKipRMiBVc2luZyB0aGUgc2FtZSBkYXRhLCBkbyB0aGUgc2FtZSBmb3IgZmxpbnQgc2NyYXBlcnMgYW5kIGNoZXJ0IHNjcmFwZXJzLCBkaXNyZWdhcmRpbmcgd2hpY2ggc2l0ZSB0aGUgc2NyYXBlcnMgY2FtZSBmcm9tLiBUcnkgdGhlIG1lYW4sIG1lZGlhbiwgYW5kIHRyaW1tZWQgbWVhbiBhZ2Fpbi5XaGljaCBpbmRleCBtYWtlcyBtb3N0IHNlbnNlIGZvciBjb21wYXJpbmcgdGhlIGxlbmd0aHMgb2YgdGhlIHNjcmFwZXJzIG1hZGUgb2YgZGlmZmVyZW50IG1hdGVyaWFscy4gV2h5PyoqCmBgYHtyfQpGbGludC5TY3JhcGVycyA8LSBzdWJzZXQoU2NyYXBlcnMsIE1hdGVyaWFsID09IkZsaW50IikgI1N1YnNldCB0aGUgZGF0YSB0byBnZXQgb25seSB0aGUgaW5mb3JtYXRpb24gb24gdGhlIHNjcmFwZXJzIG1hZGUgb2YgRmxpbnQKQ2hlcnQuU2NyYXBlcnMgPC0gc3Vic2V0IChTY3JhcGVycywgTWF0ZXJpYWwgPT0iQ2hlcnQiKSAjU3Vic2V0IHRoZSBkYXRhIHRvIGdldCBvbmx5IHRoZSBpbmZvcm1hdGlvbiBvbiB0aGUgc2NyYXBlcnMgbWFkZSBvZiBGbGludApgYGAKCmBgYHtyfQpGbGludC5TY3JhcGVycyAlPiUgI0Nob29zZSB0aGUgRmxpbnQgU2NyYXBlcnMgZGF0YSBzZXQKICBzdW1tYXJpc2UobWVhbj1tZWFuKExlbmd0aCksCiAgICAgICAgICAgIG1lZGlhbj0gbWVkaWFuKExlbmd0aCksCiAgICAgICAgICAgIHRyaW1tZWQ9IG1lYW4oTGVuZ3RoLCB0cmltPTAuMTApKSAjRmluZCB0aGUgbWVhbiwgbWVkaWFuLCBhbmQgdHJpbW1lZCBtZWFuCmBgYAoKYGBge3J9CkNoZXJ0LlNjcmFwZXJzICU+JSAjQ2hvb3NlIHRoZSBDaGVydCBTY3JhcGVycyBkYXRhIHNldAogIHN1bW1hcmlzZShtZWFuPW1lYW4oTGVuZ3RoKSwgCiAgICAgICAgICAgIG1lZGlhbj0gbWVkaWFuKExlbmd0aCksCiAgICAgICAgICAgIHRyaW1tZWQ9IG1lYW4oTGVuZ3RoLCB0cmltPTAuMTApKSAjRmluZCB0aGUgbWVhbiwgbWVkaWFuLCBhbmQgdHJpbW1lZCBtZWFuCmBgYAoKV2l0aG91dCBsb29raW5nIGF0IGEgaGlzdG9ncmFtLCBpdCBzZWVtcyB0aGF0IHRoZSBtZWFuLCBtZWRpYW4sIGFuZCB0cmltbWVkIG1lYW4gYXJlIGFsbCBiZWhhdmluZyBub3JtYWxseSwgc3VnZ2VzdGluZyB0aGF0IHRoZSBkYXRhIGlzIHVuaW1vZGFsIGFuZCBhcHByb2FjaGluZyBhIG5vcm1hbCBkaXN0cmlidXRpb24uIEFzIHN1Y2gsIEkgc3VnZ2VzdCB1c2luZyB0aGUgbWVhbiBzaW5jZSBubyBvdXRsaWVycyBhcmUgYWZmZWN0aW5nIHRoZSBtZWFuIHZhbHVlLiBNb3Jlb3ZlciwgdGhlIG1lYW4gYWxsb3dzIGZvciB0aGUgdXNlIG9mIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gdG8gdW5kZXJzdGFuZCB0aGUgcmF0ZSBvZiBkaXN0cmlidXRpb24uIFNpbmNlIHRoZXJlIGFyZSBubyBvdXRsaWVycywgSSBkbyBub3QgYmVsaWV2ZSBpdCBpcyBuZWNlc3Nhcnkgb3Igc3VnZ2VzdGVkIHRvIHVzZSB0aGUgdHJpbW1lZCBtZWFuIGFuZCBkZWxldGUgYSB2YWx1ZSAKCkNvbXBhcmluZyBhbGwgdGhlc2UgaW5mb3JtYXRpb24gKGJ1dCB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgdGhlIG1lZGlhbiBvZiB0aGUgc2l0ZXMgY2Fubm90IGJlIGNvbXBhcmVkIHRvIHRoZSBtZWFucyBvZiB0aGUgbWF0ZXJpYWxzKSwgaXQgaXMgY2xlYXIgdGhhdCBzY3JhcGVycyBtYWRlIGZyb20gRmxpbnRzIGhhdmUsIG9uIGF2ZXJhZ2UsIGxvbmdlciBsZW5ndGggdGhhbiB0aG9zZSBtYWRlIGZyb20gQ2hlcnQuIFRoZSBXaWxsb3cgRmxhdHMnIHNpdGUgYWxzbyBoYXMgbG9uZ2VyIHNjcmFwZXIgbGVuZ3RocyB0aGFuIHRoZSBQaW5lIFJpZGdlIHNpdGUuIEFzIGEgcmVzdWx0LCBpdCBpcyBzYWZlIHRvIGFzc3VtZSB0aGF0IFdpbGxvdyBGbGF0cyBoYXMgbW9yZSBzY3JhcGVycyBtYWRlIGZyb20gRmxpbnRzIHRoYW4gdGhvc2UgbWFkZSBmcm9tIENoZXJ0LiAKCiMgRHJlbm5hbiBDaDMgUTEtUTMKCioqUTE6IEJlZ2luIHRvIGV4cGxvcmUgdGhlc2UgdHdvIGJhdGNoZXMgb2YgbnVtYmVycyB3aXRoIGhpc3RvZ3JhbXMqKgpgYGB7cn0KbG9hZCgifi9EZXNrdG9wL1F1YW50aXRhdGl2ZS9Db2RlIEZpbGVzL1dlZWsgMy9OYW54aW9uZy5SRGF0YSIpICNMb2FkIHRoZSBkb3dubG9hZGVkIE5hbnhpb25nIERhdGEgU2V0CkVhcmx5LkJyb256ZS5BZ2UgPC0gTmFueGlvbmcgWzE6MjQsXSAjU2xpY2UgdGhlIGRhdGEgYnkgQWdlIHBlcmlvZCB0byBnZXQganVzdCB0aGUgRWFybHkgQnJvbnplIEFnZQpMYXRlLkJyb256ZS5BZ2UgPC0gTmFueGlvbmcgWzI1OjUxLF0gI1NsaWNlIHRoZSBkYXRhIGJ5IHRoZSBBZ2UgcGVyaW9kIHRvIGdldCBqdXN0IHRoZSBMYXRlIEJyb256ZSBBZ2UKRWFybHkuQnJvbnplLkFnZS5IaXN0IDwtaGlzdChFYXJseS5Ccm9uemUuQWdlJEFyZWEsIGJyZWFrcyA9IDEwLCBtYWluPSJFYXJseSBCcm9uemUgQWdlIiwgeGxhYj0iQXJlYSIpICNDcmVhdGVkIGEgaGlzdG9ncmFtIHRvIGV4cGxvcmUgdGhlIEVhcmx5IEJyb256ZSBBZ2UgZGF0YQpMYXRlLkJyb256ZS5BZ2UuSGlzdCA8LWhpc3QoTGF0ZS5Ccm9uemUuQWdlJEFyZWEsIGJyZWFrcz0xMCwgbWFpbj0iTGF0ZSBCcm9uemUgQWdlIiwgeGxhYj0iQXJlYSIpICNDcmVhdGVkIGEgaGlzdG9ncmFtIHRvIGV4cGxvcmUgdGhlIExhdGUgQnJvbnplIEFnZSBkYXRhCmBgYAoKKipRMjogQ2FsY3VsYXRlIHRoZSBtZWFuLCBtZWRpYW4sIGFuZCB0aGUgMTAlIHRyaW1tZWQgbWVhbiBmb3IgZWFjaCBiYXRjaCBhbmQgdGhlbiB0aGUgaW5kZXggb2Ygc3ByZWFkIHRoYXQgY29ycmVzcG9uZHMgdG8gZWFjaCBvZiB0aGVzZSBpbmRleGVzIG9mIGxldmVsLiBXaGljaCBwYWlyIG9mIGluZGV4ZXMgbWFrZXMgbW9zdCBzZW5zZSB0byB1c2UgaGVyZT8gV2h5PyoqCgpgYGB7cn0KRWFybHkuQnJvbnplLkFnZSAlPiUgI0Nob29zZSB0aGUgRWFybHkgQnJvbnplIEFnZSBkYXRhIGZyYW1lCiAgc3VtbWFyaXNlKG1lYW4gPW1lYW4oQXJlYSksCiAgICAgICAgICAgIG1lZGlhbj0gbWVkaWFuKEFyZWEpLAogICAgICAgICAgICB0cmltbWVkID1tZWFuKEFyZWEsIHRyaW09MC4xKSwKICAgICAgICAgICAgc2Q9IHNkKEFyZWEpLCAKICAgICAgICAgICAgSVFSPSBJUVIoQXJlYSksCiAgICAgICAgICAgIHdpbnNvcml6ZWQ9IHNkKFdpbnNvcml6ZShFYXJseS5Ccm9uemUuQWdlJEFyZWEpKSkgI0ZpbmQgdGhlIG1lZGlhbiwgbWVhbiwgdHJpbW1lZCBtZWFuLCBzZCwgSVFSLCBhbmQgd2luc29yaXplZCBzZApgYGAKCmBgYHtyfQpMYXRlLkJyb256ZS5BZ2UgJT4lICNDaG9vc2UgdGhlIExhdGUgQnJvbnplIEFnZSBkYXRhIGZyYW1lCiAgc3VtbWFyaXNlKG1lYW4gPW1lYW4oQXJlYSksCiAgICAgICAgICAgIG1lZGlhbj0gbWVkaWFuKEFyZWEpLAogICAgICAgICAgICB0cmltbWVkID1tZWFuKEFyZWEsIHRyaW09MC4xKSwKICAgICAgICAgICAgc2Q9c2QoQXJlYSksCiAgICAgICAgICAgIElRUj1JUVIoQXJlYSksCiAgICAgICAgICAgIHdpbnNvcml6ZWQ9IHNkKFdpbnNvcml6ZShFYXJseS5Ccm9uemUuQWdlJEFyZWEpKSkgI0ZpbmQgdGhlIG1lZGlhbiwgbWVhbiwgdHJpbW1lZCBtZWFuLCBzZCwgSVFSLCBhbmQgd2luc29yaXplZCBzZApgYGAKCioqUTM6IEJhc2VkIG9uIHRoZSBoaXN0b2dyYW0gYW5kIHRoZSBpbmRleGVzIG9mIGxldmVsIGFuZCBzcHJlYWQsIHdoYXQgb2JzZXJ2YXRpb25zIHdvdWxkIHlvdSBtYWtlIGFib3V0IGNoYW5nZXMgaW4gc2l0ZSBzaXplIGZyb20gRWFybHkgQnJvbnplIEFnZSB0byBMYXRlIEJyb256ZSBBZ2UgbmVhciBOYW54aW9uZz8qKgpCYXNlZCBvbiB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzLCBpdCBhcHBlYXJzIHRoYXQsIG9uIGF2ZXJhZ2UsIHRoZSBMYXRlIEJyb256ZSBBZ2UgcGVyaW9kIGhhZCBiaWdnZXIgc2l0ZSBzaXplcyB0aGF0IEVhcmx5IEJyb256ZSBBZ2UuIE1vcmVvdmVyLCB0aGVyZSB3YXMgbW9yZSB2YXJpYWJpbGl0eSBpbiB0aGUgc3ByZWFkIGZvciBMYXRlIEJyb256ZSBBZ2UgdGhhbiB0aGF0IG9mIHRoZSBFYXJseSBCcm9uemUgQWdlLCBzdWdnZXN0aW5nIHRoYXQgYWx0aG91Z2ggdGhleSB3ZXJlIGdlbmVyYWxseSBiaWdnZXIsIHRoZSBzaXplcyBiZXR3ZWVuIHRoZSBzaXRlcyBpbiB0aGlzIHBlcmlvZCBhbHNvIHZhcmllZCBoaWdobHkuIEZpbmFsbHksIGl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlcmUgaXMgYW4gRWFybHkgQnJvbnplIEFnZSBzaXRlIHdpdGggYSBwYXJ0aWN1bGFybHkgYmlnIHNpemUgd2hpY2ggaXMgY29uc2lkZXJlZCBhbiBvdXRsaWVyLiBJIHJlY29tbWVuZCBjaGVja2luZyB0aGUgZGF0YSBhcyBpdCBjb3VsZCBoYXZlIGJlZW4gdGhhdCB0aGlzIHNpdGUgd2FzIG1pc2xhYmVsZWQuIAoKIyBVcmRhbiBDaC40IFExLVE1CgoqKlExOiBJbiBzdGF0aXN0aWNzLCB0aGUgd29yZCAiZGlzdHJpYnV0aW9uIiBjb21lcyB1cCBhIGxvdC4qKgoqKmEuIEluIHlvdXIgb3duIHdvcmRzLCBleHBsYWluIHdoYXQgYSBkaXN0cmlidXRpb24gaXMqKgpBIGRpc3RyaWJ1dGlvbiBpcyBhIHNldCBvZiB0aGluZ3Mgc3ByZWFkIG91dCBhY3Jvc3MgYSBjb250aW51dW0uIEluIHRoZSBjYXNlIG9mIHN0YXRpc3RpY3MsIGl0IGlzIGEgc2V0IG9mIHZhbHVlcyBzcHJlYWQgdXN1YWxseSBmcm9tIGxhcmdlc3QgdG8gc21hbGxlc3Qgb3IgdmljZXZlcnNhLiAKKipiLiBUaGVuLCBhZ2FpbiBpbiB5b3VyIG93biB3b3JkcywgZXhwbGFpbiB3aGF0IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyoqCk5vcm1hbCBkaXN0cmlidXRpb24gaXMganVzdCBhbiBhdmVyYWdlIGRpc3RyaWJ1dGlvbi4gSW4gb3RoZXIgd29yZHMsIGl0IGlzIHdoZW4gdGhlIHNldCBvZiB2YWx1ZXMgaXMgc3ByZWFkIGluIGEgY29tbW9uIG9yIHByZWRpY3RhYmxlIHdheS4gSW4gc3RhdGlzdGljcywgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIGEgdGhlb3JldGljYWwgbW9kZWwgaW4gd2hpY2ggdmFsdWVzIGFyZSBzcHJlYWQgaW4gYW4gaWRlbnRpZmlhYmxlIHdheSBwZXJmZWN0bHkgdXNlZnVsIGZvciBpbmZlcmVudGlhbCBzdGF0aXN0aWNzLiAKCioqUTI6IFdoYXQgZG9lcyBhc3ltcHRvbWF0aWMgbWVhbiBhbmQgd2h5IGlzIGl0IGltcG9ydGFudD8qKgpBc3ltcHRvbWF0aWMgbWVhbnMgdGhhdCB0aGUgdGFpbHMgb2YgdGhlIGRpc3RyaWJ1dGlvbiBuZXZlciBhY3R1YWxseSB0b3VjaCB0aGUgYmFzZWxpbmUsIG9yIG5ldmVyIGFjdHVhbGx5IHJlYWNoIGFic29sdXRlIHplcm8uIFRodXMgaXMgaW1wb3J0YW50IGJlY2F1c2UgaXQgaW5kaWNhdGVzIHRoYXQgdGhlIHByb2JhYmlsaXR5IG9mIHNvbWV0aGluZyBoYXBwZW5pbmcgYnkgY2hhbmNlIGlzIG5ldmVyIDAuIAoKKipRMzogSW4gc3RhdGlzdGljcywgd2UgdXNlIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGEgbG90KioKKiphLiBXaGF0IGlzIHNvIGdyZWF0IGFib3V0IGl0PyoqCk5vcm1hbCBkaXN0cmlidXRpb25zIGFyZSBwZXJmZWN0IGZvciB1bmRlcnN0YW5kaW5nIGJpZyBwb3B1bGF0aW9ucyBhcyB0aGV5IHVzdWFsbHkgYXBwcm9hY2ggdGhlIHRoZW9yZXRpY2FsIG1vZGVsIG9mIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLiBIZW5jZSwgdGhpcyBtb2RlbCBoZWxwcyB1cyB0byBkbyBpbmZlcmVudGlhbCBhbmQgcHJvYmFiaWxpdHkgc3RhdGlzdGljcyB0byBnZXQgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiBvdXIgcG9wdWxhdGlvbi4gCgoqKmIuIERlc2NyaWJlIHNvbWV0aGluZyB0aGF0IHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGxldHMgdXMsIHN0YXRpc3RpY2lhbnMsIGRvIHRoYXQgd2UgY2Fubm90IGRvIHdpdGhvdXQgaXQqKgpXaXRob3V0IHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLCB3ZSB3b3VsZCBub3QgYmUgYWJsZSB0byBpbmZlciBhbmQgZHJhdyBjbGVhciBjb25jbHVzaW9ucyBhYm91dCBvdXIgZGF0YSBpbiBvcmRlciB0byBnZW5lcmFsaXplLiBJbiBvdGhlciB3b3Jkcywgd2Ugd291bGQgbm90IGJlIGFibGUgdG8gZG8gcHJvYmFiaWxpdHkgb3IgaW5mZXJlbnRpYWwgc3RhdGlzdGljcy4KCioqUTQ6IE1hbnkgYmVsaWV2ZSB0aGF0IG1vc3QgaHVtYW4gdHJhaXRzIGZvcm0gYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBIZWlnaHQsIHdlaWdodCwgaW50ZWxsaWdlbmNlLCBtdXNpY2FsIGFiaWxpdHksIGZyaWVuZGxpbmVzcywgYXR0cmFjdGl2ZW5lc3MsIGV0Yy4gYXJlIGFsbCBleGFtcGxlcyBvZiB0aGluZ3MgdGhhdCBtaWdodCBmb3JtIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbioqCioqYS4gRmlyc3QsIGV4cGxhaW4gd2hldGhlciB5b3UgYWdyZWUgd2l0aCB0aGlzIGFzc3VtcHRpb24sIGFuZCB3aHkgb3Igd2h5IG5vdC4qKgpJIHdvdWxkIGFncmVlIHdpdGggbW9zdCBvZiB0aGVzZSBhc3N1bXB0aW9ucyBzaW5jZSBoZWlnaHQgYW5kIHdlaWdodCBhcmUgY29udGludW91cyB2YXJpYWJsZXMgYW5kIGNhbiBnbyBvbiBmb3IgYm90aCBleHRyZW1lcy4gSG93ZXZlciwgSSB3b3VsZCBoZXNpdGF0ZSB0byBzYXkgYXR0cmFjdGl2ZW5lc3MgZm9sbG93cyBhIG5vcm1hbCBkaXN0cmlidXRpb24gYmVjYXVzZSBpdCBtYWtlcyBpdCBzb3VuZCBsaWtlIGF0dHJhY3RpdmVuZXNzIGlzIGEgc2NpZW50aWZpYyByZWFsaXR5IHdoZW4gaW4gcmVhbGl0eSBpdCBpcyBhIHNvY2lhbCBjb25zdHJ1Y3QuIAoKKipiLiBTZWNvbmQsIHRoaW5rIG9mIGFuIGV4YW1wbGUgb2YgYSB0cmFpdCB0aGF0IGRvZXMgTk9UIGZvcm0gYSBub3JtYWwgZGlzdHJpYnV0aW9uIGluIHRoZSBwb3B1bGF0aW9uLioqCkEgdHJhaXQgdGhhdCBkb2VzIG5vdCBmb3JtIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBwZW9wbGUgd2hvIGFyZSBraWxsZXJzLCBwZW9wbGUgd2hvIGFyZSBsZWZ0LWhhbmRlZCAoc2luY2UgdGhlcmUgYXJlIG1vcmUgcmlnaHQtaGFuZGVkIHBlb3BsZSkuIFByb2JhYmx5LCBwZW9wbGUgd2hvIHNwZWFrIExhdGluIHdvdWxkIGFsc28gYmUgYW4gZXhhbXBsZS4KCioqUTU6IElmIHlvdSBrbm93IHRoYXQgaW4gdGhlIHBvcHVsYXRpb24gYWR1bHRzIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzbGVwdCBwZXIgbmlnaHQgaXMgNyB3aXRoIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDIsIHdoYXQgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbiB3b3VsZCB5b3UgZXhwZWN0IHRvIHNsZWVwIGJldHdlZW4gNyBhbmQgOSBob3VycyBwZXIgbmlnaHQ/KioKSSB3b3VsZCBleHBlY3QgYWJvdXQgMzQlIG9mIHBlb3BsZSB0byBzbGVlcCBiZXR3ZWVuIDcgYW5kIDkgaG91cnMgcGVyIG5pZ2h0IHNpbmNlIDM0JSBvZiB0aGUgcG9wdWxhdGlvbiBpcyBlbmNvbXBhc3NlZCBiZXR3ZWVuIDEgc2Qgb2YgdGhlIG1lYW4uIAoKCgo=