library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.0.4
library(openintro)
library(statsr)
## Warning: package 'statsr' was built under R version 4.0.5
## Warning: package 'BayesFactor' was built under R version 4.0.5
## Warning: package 'coda' was built under R version 4.0.5
library(StMoSim)
## Warning: package 'StMoSim' was built under R version 4.0.5
library(RcppParallel)
## Warning: package 'RcppParallel' was built under R version 4.0.5
library(Rcpp)
library(ggplot2)
library(dplyr)
library(data.tree)
library(plotrix)
library(infer)
set.seed(110)

Step 1

Final Project:
Analyze Data

  1. Download the data
  2. View observations
  3. View summary data
  4. View the table of variables for the observations

Comments and Findings The original dataframe consists of 500 observations and 6 variables. To view the data, the structure, summary data, and a table of youth variables were generated as seen in the code below.

Problem
While trying to work with the original data, errors were generated during some of the tests because of data types. To resolve the problem with incompatible data types, the original dataset was modified by converting variables with char data types (Yes/No responses) to integers of 0 = No and 1 = Yes. The Sleep variable was modified from char to int (removed all chars other than numbers). Worth noting, a Sleep int of 4 is actually “4 hours or less”; a Sleep int of 10 is actually “10 hours or more.” After modifying the data file, there are 14 variables. The converted variable columns include the following: SleepNumeric, SmokeLife_Convert, SmokeDailyConvert, MarijuaEver_Convert, and x variables. The original variables 6 are as follows: Sleep, Sleep7, MarijuaEver, Age, SmokeLife, SmokeDaily.

#The Data
setwd("C:/AarynZimmerman/Biostatistics Project")
youth <-read.csv("YouthRisk2009AZ.csv")
destfile = "youth.RData"
str(youth)    #view 500 observations with 6 variables
## 'data.frame':    500 obs. of  14 variables:
##  $ X                  : int  6 7 24 25 34 39 43 49 62 74 ...
##  $ Sleep              : chr  "4 or less hours" "6 hours" "6 hours" "6 hours" ...
##  $ SleepNumeric       : int  4 6 6 6 6 5 6 6 6 6 ...
##  $ Sleep7             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.1                : logi  NA NA NA NA NA NA ...
##  $ SmokeLife_Convert  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.2                : logi  NA NA NA NA NA NA ...
##  $ SmokeDaily_Convert : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ MarijuaEver        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.3                : logi  NA NA NA NA NA NA ...
##  $ Age                : int  15 17 16 16 15 18 16 18 14 16 ...
##  $ SmokeLife          : chr  "No" "No" "No" "No" ...
##  $ SmokeDaily         : chr  "No" "No" "No" "No" ...
##  $ MarijuaEver_Convert: chr  "No" "No" "No" "No" ...
summary(youth) #view summary data
##        X            Sleep            SleepNumeric        Sleep7      
##  Min.   :  1.0   Length:500         Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:125.8   Class :character   1st Qu.: 6.000   1st Qu.:0.0000  
##  Median :250.5   Mode  :character   Median : 7.000   Median :1.0000  
##  Mean   :250.5                      Mean   : 6.184   Mean   :0.6637  
##  3rd Qu.:375.2                      3rd Qu.: 8.000   3rd Qu.:1.0000  
##  Max.   :500.0                      Max.   :10.000   Max.   :1.0000  
##                                                      NA's   :54      
##    X.1          SmokeLife_Convert   X.2          SmokeDaily_Convert
##  Mode:logical   Min.   :  0.000   Mode:logical   Min.   :  0.00    
##  NA's:500       1st Qu.:  0.000   NA's:500       1st Qu.:  0.00    
##                 Median :  0.000                  Median :  0.00    
##                 Mean   :  4.616                  Mean   :  6.68    
##                 3rd Qu.:  1.000                  3rd Qu.:  0.00    
##                 Max.   :100.000                  Max.   :100.00    
##                                                                    
##   MarijuaEver       X.3               Age         SmokeLife        
##  Min.   :0.0000   Mode:logical   Min.   :14.00   Length:500        
##  1st Qu.:0.0000   NA's:500       1st Qu.:15.00   Class :character  
##  Median :0.0000                  Median :16.00   Mode  :character  
##  Mean   :0.3608                  Mean   :16.08                     
##  3rd Qu.:1.0000                  3rd Qu.:17.00                     
##  Max.   :1.0000                  Max.   :18.00                     
##  NA's   :15                                                        
##   SmokeDaily        MarijuaEver_Convert
##  Length:500         Length:500         
##  Class :character   Class :character   
##  Mode  :character   Mode  :character   
##                                        
##                                        
##                                        
## 
view(youth)  #view table of variables for the 500 observations
#convert variables to factors, where necessary
youth$Sleep <- as.factor(youth$Sleep)
youth$Sleep7 <- as.factor(youth$Sleep7)
youth$SmokeLife <- as.factor(youth$SmokeLife)
youth$SmokeDaily <- as.factor(youth$SmokeDaily)
youth$MarijuaEver <- as.factor(youth$MarijuaEver)
summary(youth)
##        X             Sleep      SleepNumeric     Sleep7      X.1         
##  Min.   :  1.0   7 hours:140   Min.   : 0.000   0   :150   Mode:logical  
##  1st Qu.:125.8   8 hours:116   1st Qu.: 6.000   1   :296   NA's:500      
##  Median :250.5   6 hours: 90   Median : 7.000   NA's: 54                 
##  Mean   :250.5          : 53   Mean   : 6.184                            
##  3rd Qu.:375.2   5 hours: 36   3rd Qu.: 8.000                            
##  Max.   :500.0   9 hours: 32   Max.   :10.000                            
##                  (Other): 33                                             
##  SmokeLife_Convert   X.2          SmokeDaily_Convert MarijuaEver   X.3         
##  Min.   :  0.000   Mode:logical   Min.   :  0.00     0   :310    Mode:logical  
##  1st Qu.:  0.000   NA's:500       1st Qu.:  0.00     1   :175    NA's:500      
##  Median :  0.000                  Median :  0.00     NA's: 15                  
##  Mean   :  4.616                  Mean   :  6.68                               
##  3rd Qu.:  1.000                  3rd Qu.:  0.00                               
##  Max.   :100.000                  Max.   :100.00                               
##                                                                                
##       Age        SmokeLife  SmokeDaily MarijuaEver_Convert
##  Min.   :14.00   No  :271   No  :427   Length:500         
##  1st Qu.:15.00   Yes :208   Yes : 40   Class :character   
##  Median :16.00   NA's: 21   NA's: 33   Mode  :character   
##  Mean   :16.08                                            
##  3rd Qu.:17.00                                            
##  Max.   :18.00                                            
## 
str(youth)
## 'data.frame':    500 obs. of  14 variables:
##  $ X                  : int  6 7 24 25 34 39 43 49 62 74 ...
##  $ Sleep              : Factor w/ 9 levels "","10  hours",..: 3 5 5 5 5 4 5 5 5 5 ...
##  $ SleepNumeric       : int  4 6 6 6 6 5 6 6 6 6 ...
##  $ Sleep7             : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
##  $ X.1                : logi  NA NA NA NA NA NA ...
##  $ SmokeLife_Convert  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.2                : logi  NA NA NA NA NA NA ...
##  $ SmokeDaily_Convert : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ MarijuaEver        : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
##  $ X.3                : logi  NA NA NA NA NA NA ...
##  $ Age                : int  15 17 16 16 15 18 16 18 14 16 ...
##  $ SmokeLife          : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ SmokeDaily         : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ MarijuaEver_Convert: chr  "No" "No" "No" "No" ...

Step 2

Final Project:
Definition of the type of study the dataset is associated with, definition of a research question, and data manipulations based on the study type and data.

Comments and Findings This an observational study of students in grades 9-12 concerning health-risk behaviors. One research question posed is whether health-risk behaviors of smoking, including marijuana, leads directly to differences in hours of sleep.

In this observational study, youth are surveyed as to their health-risk behaviors and sleep. No attempt is made to affect the outcome; no treatment is given to measure an outcome as this is not an experiment. In this study, researchers made no attempts to manipulate the study - instead, they simply observe. There are no procedures carried out to support, refute, or validate a hypothesis; there is no experimenting to provide insight into cause-and-effect. There is no demonstration of an outcome that possibly occurs when a factor is manipulated. Since this is an observational study, there is no control group or experimental groups. The variables do not cause or explain, however the variables can be related.

Question for the observational study: A youth’s health-risk behavior (smoking) is positively/negatively correlated to hours of sleep.

To answer this question, a series of data manipulations will be performed in R as follows:

  1. Review the distribution of sleep using histograms and a normal distribution curve based on calculated mean and standard deviation Question: Is it skewed, and if so, in what direction.

    Answer: The distribution of the variable sleep is more skewed to the left (under the mean of 6). According to this distribution, youth
    get more sleep than less, which is what I expected.
    Problem: Just as I have tried to add a normal distribution curve to my histogram in previous assignments, I tried to add one in my first snippet of code. It appears my code is wrong. I was hoping to plot the normal distribution curve and then see
    “normalcy.” In other words, a normal distribution with average sleep, including a few outside the norms in the below average or above average directions, however youth of these ages aren’t “normal” sleepers, and my code resulted in a flat line. To deal with this problem, I manually calculated the mean and standard deviation and then used ggplot.

  2. One way of calculating a 95% confidence interval for a sample mean by adding and subtracting 1.96 standard errors to the point estimate. When doing this, even though the full population isn’t known, with 95% confidence, the true average hours of sleep for youth lies between the values of the upper and lower limits of 6.020721 and 7.119279, respectively. There are conditions for this range to be valid. The sample mean must be normally distributed and have standard error s/n−−√. For these conditions to be met, the sample observations are random, sample size is greater than 50 and population distribution should not be greatly skewed to one side or the other. The confidence is in the method, not a particular Confidence Interval. A confidence interval is the probability that a value will fall between an upper and lower bound of a probability distribution. Since the skewing is not greatly one way or another, according to this model the conditions for a 95% confidence interval appear to be met. Worth noting, the “0” sleep is actually where respondents did not answer the question. See data conversion problem in step 1.

    Problem: When attempting to plot the confidence interval, the code failed. See code below.

#hist (v, main, xlab, xlim, ylim, breaks,col,border)
#where v – vector with numeric values
#main – denotes title of the chart
#col – sets color
#border -sets border color to the bar
#xlab - description of x-axis
#xlim - denotes to specify range of values on x-axis
#ylim – specifies range values on y-axis
#break – specifies the width of each bar.

hist(youth$SleepNumeric,
main="Health-Risk Behavior:  Distribution of Sleep",
xlab="Sleep",
border="Green",
col="Orange")

curve (dnorm(x, mean=mean(youth$SleepNumeric), sd=sd(youth$SleepNumeric)), add=TRUE, col="red")  #Implement the Normal Distribution Curve in Histogram

#Get mean and standard deviation of SleepNumeric
SNmean <- mean(youth$SleepNumeric)
SNsd   <- sd(youth$SleepNumeric)
SNmean
## [1] 6.184
SNsd
## [1] 2.484046
hist(youth$SleepNumeric,
main ="Histogram - Youth Risk Habits, View 2 - Sleep",
border = "Green",
col = "Orange" ,
breaks = 5)

#Plot SleepNumeric; include a normal distribution curve
ggplot(data = youth, aes(x = SleepNumeric)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = SNmean, sd = SNsd), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

population <- youth$SleepNumeric
sampYouth <- sample(population, 100)
hist(sampYouth,
main ="Histogram - Hours of Sleep",
border = "Green",
col = "Orange" ,
breaks = 5)

sample_mean <- mean(sampYouth)
sample_mean
## [1] 6.2
#Calculate a 95% confidence interval for the sample mean by adding and subtracting 1.96 standard errors to the point estimate.

se <- sd(sampYouth) / sqrt(100)
lower <- sample_mean - 1.96 * se
upper <- sample_mean + 1.96 * se
c(lower, upper)
## [1] 5.669229 6.730771
se
## [1] 0.2708013
sample_mean
## [1] 6.2
#Attempted to plot the confidence interval; code failed.
#plot_ci(lower, upper, mean(sampYouth))

Step 3

Final Project:
Understand the relationship between some of the other variables, not including SleepNumeric.

Comments and Findings SleepNumeric was excluded and two other variables, SmokeDaily and Age, were selected. The relationship between the other variables was analyzed using a boxplot as a visualization tool. A scatterplot was also used to further understand the relationship.

In looking at the average age of the youth vs the health-risk variable of smoking daily, the means of the two variables were compared and resulted in a very slight difference as seen below:

youth\(SmokeDaily: No [1] 16.05621 ------------------------------------------------------------------------------------------------------ youth\)SmokeDaily: Yes [1] 16.325

The tests were repeated for another set of variables, age and use of marijuana ever. The difference between the means is more than between age and daily smoking, but other testing is still needed to understand the relationship, if any.

youth\(MarijuaEver: 0 [1] 15.90323 ------------------------------------------------------------------------------------------------------ youth\)MarijuaEver: 1 [1] 16.37143

It appears a hypothesis test might be useful to see if the difference is statistically significant. By looking at the boxplot, it does not appear there is a correlation between age and daily smoking, nor is there one between age and marijuana smoking.

#The Data
setwd("C:/AarynZimmerman/Biostatistics Project")
youth <-read.csv("YouthRisk2009AZ.csv")
destfile = "youth.RData"
str(youth)    #view 500 observations with 7 variables
## 'data.frame':    500 obs. of  14 variables:
##  $ X                  : int  6 7 24 25 34 39 43 49 62 74 ...
##  $ Sleep              : chr  "4 or less hours" "6 hours" "6 hours" "6 hours" ...
##  $ SleepNumeric       : int  4 6 6 6 6 5 6 6 6 6 ...
##  $ Sleep7             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.1                : logi  NA NA NA NA NA NA ...
##  $ SmokeLife_Convert  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.2                : logi  NA NA NA NA NA NA ...
##  $ SmokeDaily_Convert : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ MarijuaEver        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.3                : logi  NA NA NA NA NA NA ...
##  $ Age                : int  15 17 16 16 15 18 16 18 14 16 ...
##  $ SmokeLife          : chr  "No" "No" "No" "No" ...
##  $ SmokeDaily         : chr  "No" "No" "No" "No" ...
##  $ MarijuaEver_Convert: chr  "No" "No" "No" "No" ...
summary(youth) #view summary data
##        X            Sleep            SleepNumeric        Sleep7      
##  Min.   :  1.0   Length:500         Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:125.8   Class :character   1st Qu.: 6.000   1st Qu.:0.0000  
##  Median :250.5   Mode  :character   Median : 7.000   Median :1.0000  
##  Mean   :250.5                      Mean   : 6.184   Mean   :0.6637  
##  3rd Qu.:375.2                      3rd Qu.: 8.000   3rd Qu.:1.0000  
##  Max.   :500.0                      Max.   :10.000   Max.   :1.0000  
##                                                      NA's   :54      
##    X.1          SmokeLife_Convert   X.2          SmokeDaily_Convert
##  Mode:logical   Min.   :  0.000   Mode:logical   Min.   :  0.00    
##  NA's:500       1st Qu.:  0.000   NA's:500       1st Qu.:  0.00    
##                 Median :  0.000                  Median :  0.00    
##                 Mean   :  4.616                  Mean   :  6.68    
##                 3rd Qu.:  1.000                  3rd Qu.:  0.00    
##                 Max.   :100.000                  Max.   :100.00    
##                                                                    
##   MarijuaEver       X.3               Age         SmokeLife        
##  Min.   :0.0000   Mode:logical   Min.   :14.00   Length:500        
##  1st Qu.:0.0000   NA's:500       1st Qu.:15.00   Class :character  
##  Median :0.0000                  Median :16.00   Mode  :character  
##  Mean   :0.3608                  Mean   :16.08                     
##  3rd Qu.:1.0000                  3rd Qu.:17.00                     
##  Max.   :1.0000                  Max.   :18.00                     
##  NA's   :15                                                        
##   SmokeDaily        MarijuaEver_Convert
##  Length:500         Length:500         
##  Class :character   Class :character   
##  Mode  :character   Mode  :character   
##                                        
##                                        
##                                        
## 
view(youth)  #view table of variables for the 500 observations
boxplot(Age~SmokeDaily,
       data=youth,
       main = "Age vs Smoke Daily",
       xlab = "Youth Smoke Daily",
       ylab = "Age of Youth",
       col = "orange",
       border = "brown",
       vertical = TRUE,
       notch = FALSE)

#view means of the distributions by using the following function to split the SmokeDaily group variable into Yes/No groups, then taking the mean of each using the mean function.

by(youth$Age, youth$SmokeDaily, mean)
## youth$SmokeDaily: No
## [1] 16.05621
## ------------------------------------------------------------ 
## youth$SmokeDaily: Yes
## [1] 16.325
boxplot(Age~MarijuaEver,
       data=youth,
       main = "Marijuana Ever vs Age",
       xlab = "Marijuana Ever",
       ylab = "Age",
       col = "orange",
       border = "brown",
       vertical = TRUE,
       notch = FALSE)

#view means of the distributions by using the following function to split the Marijuana Ever into Yes/No groups, then taking the mean of each using the mean function.

by(youth$Age, youth$MarijuaEver, mean)
## youth$MarijuaEver: 0
## [1] 15.90323
## ------------------------------------------------------------ 
## youth$MarijuaEver: 1
## [1] 16.37143

Step 4

Final Project:
The fundamental question is whether or not the health-risk behavior (smoking) is positively/negatively correlated to hours of sleep. It seems that smoking, whether regular cigarettes or marijuana, might be disruptive to overall hours of sleep. T

Comments and Findings This was tested this using linear regression via a scatterplot to see if this appears to be the case. A scatterplot, in conjuction with jitter was used.

Problem: The scatterplot did not provide a clear image of the individual points. My assumption is this is because they overlap too closely with like values. If the values were different, the jitter would have added “noise” to the x-axis variable, and the individual points on the plot would be more clear/visible.

The scatterplot was implemented multiple ways, but as seen below, the results are the same. My interpretation is that a scatterplot isn’t the best way of viewing this particular data set.

Worth noting, because of data type conflicts, I had to assign a value to all “blanks” in the data set. I chose a value that was very different from the other values, “100.” The impact this assigned value has on results is not clear.

str(youth)    #view 500 observations with 6 (original) variables
## 'data.frame':    500 obs. of  14 variables:
##  $ X                  : int  6 7 24 25 34 39 43 49 62 74 ...
##  $ Sleep              : chr  "4 or less hours" "6 hours" "6 hours" "6 hours" ...
##  $ SleepNumeric       : int  4 6 6 6 6 5 6 6 6 6 ...
##  $ Sleep7             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.1                : logi  NA NA NA NA NA NA ...
##  $ SmokeLife_Convert  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.2                : logi  NA NA NA NA NA NA ...
##  $ SmokeDaily_Convert : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ MarijuaEver        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.3                : logi  NA NA NA NA NA NA ...
##  $ Age                : int  15 17 16 16 15 18 16 18 14 16 ...
##  $ SmokeLife          : chr  "No" "No" "No" "No" ...
##  $ SmokeDaily         : chr  "No" "No" "No" "No" ...
##  $ MarijuaEver_Convert: chr  "No" "No" "No" "No" ...
summary(youth) #view summary data
##        X            Sleep            SleepNumeric        Sleep7      
##  Min.   :  1.0   Length:500         Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:125.8   Class :character   1st Qu.: 6.000   1st Qu.:0.0000  
##  Median :250.5   Mode  :character   Median : 7.000   Median :1.0000  
##  Mean   :250.5                      Mean   : 6.184   Mean   :0.6637  
##  3rd Qu.:375.2                      3rd Qu.: 8.000   3rd Qu.:1.0000  
##  Max.   :500.0                      Max.   :10.000   Max.   :1.0000  
##                                                      NA's   :54      
##    X.1          SmokeLife_Convert   X.2          SmokeDaily_Convert
##  Mode:logical   Min.   :  0.000   Mode:logical   Min.   :  0.00    
##  NA's:500       1st Qu.:  0.000   NA's:500       1st Qu.:  0.00    
##                 Median :  0.000                  Median :  0.00    
##                 Mean   :  4.616                  Mean   :  6.68    
##                 3rd Qu.:  1.000                  3rd Qu.:  0.00    
##                 Max.   :100.000                  Max.   :100.00    
##                                                                    
##   MarijuaEver       X.3               Age         SmokeLife        
##  Min.   :0.0000   Mode:logical   Min.   :14.00   Length:500        
##  1st Qu.:0.0000   NA's:500       1st Qu.:15.00   Class :character  
##  Median :0.0000                  Median :16.00   Mode  :character  
##  Mean   :0.3608                  Mean   :16.08                     
##  3rd Qu.:1.0000                  3rd Qu.:17.00                     
##  Max.   :1.0000                  Max.   :18.00                     
##  NA's   :15                                                        
##   SmokeDaily        MarijuaEver_Convert
##  Length:500         Length:500         
##  Class :character   Class :character   
##  Mode  :character   Mode  :character   
##                                        
##                                        
##                                        
## 
view(youth)  #view table of variables for the 500 observations
#scatterplot 

#The Data
setwd("C:/AarynZimmerman/Biostatistics Project")
youth <-read.csv("YouthRisk2009AZ.csv")
destfile = "youth.RData"
str(youth)    #view 500 observations with 7 variables
## 'data.frame':    500 obs. of  14 variables:
##  $ X                  : int  6 7 24 25 34 39 43 49 62 74 ...
##  $ Sleep              : chr  "4 or less hours" "6 hours" "6 hours" "6 hours" ...
##  $ SleepNumeric       : int  4 6 6 6 6 5 6 6 6 6 ...
##  $ Sleep7             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.1                : logi  NA NA NA NA NA NA ...
##  $ SmokeLife_Convert  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.2                : logi  NA NA NA NA NA NA ...
##  $ SmokeDaily_Convert : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ MarijuaEver        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X.3                : logi  NA NA NA NA NA NA ...
##  $ Age                : int  15 17 16 16 15 18 16 18 14 16 ...
##  $ SmokeLife          : chr  "No" "No" "No" "No" ...
##  $ SmokeDaily         : chr  "No" "No" "No" "No" ...
##  $ MarijuaEver_Convert: chr  "No" "No" "No" "No" ...
summary(youth) #view summary data
##        X            Sleep            SleepNumeric        Sleep7      
##  Min.   :  1.0   Length:500         Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:125.8   Class :character   1st Qu.: 6.000   1st Qu.:0.0000  
##  Median :250.5   Mode  :character   Median : 7.000   Median :1.0000  
##  Mean   :250.5                      Mean   : 6.184   Mean   :0.6637  
##  3rd Qu.:375.2                      3rd Qu.: 8.000   3rd Qu.:1.0000  
##  Max.   :500.0                      Max.   :10.000   Max.   :1.0000  
##                                                      NA's   :54      
##    X.1          SmokeLife_Convert   X.2          SmokeDaily_Convert
##  Mode:logical   Min.   :  0.000   Mode:logical   Min.   :  0.00    
##  NA's:500       1st Qu.:  0.000   NA's:500       1st Qu.:  0.00    
##                 Median :  0.000                  Median :  0.00    
##                 Mean   :  4.616                  Mean   :  6.68    
##                 3rd Qu.:  1.000                  3rd Qu.:  0.00    
##                 Max.   :100.000                  Max.   :100.00    
##                                                                    
##   MarijuaEver       X.3               Age         SmokeLife        
##  Min.   :0.0000   Mode:logical   Min.   :14.00   Length:500        
##  1st Qu.:0.0000   NA's:500       1st Qu.:15.00   Class :character  
##  Median :0.0000                  Median :16.00   Mode  :character  
##  Mean   :0.3608                  Mean   :16.08                     
##  3rd Qu.:1.0000                  3rd Qu.:17.00                     
##  Max.   :1.0000                  Max.   :18.00                     
##  NA's   :15                                                        
##   SmokeDaily        MarijuaEver_Convert
##  Length:500         Length:500         
##  Class :character   Class :character   
##  Mode  :character   Mode  :character   
##                                        
##                                        
##                                        
## 
view(youth)  #view table of variables for the 500 observations
#youth$SleepNumeric <- as.numeric(youth$SleepNumeric)
#youth$SmokeLife_Convert <- as.numeric(youth$SmokeDaily_Convert)

plot(youth$SleepNumeric~youth$SmokeLife_Convert,
   main = "Relationship Between Hours of Sleep and Smoke Life",
     ylab = "Hours of Sleep", 
     xlab = "Smoke Life")

#scatterplot 
#plot(evals$score~evals$bty_avg,
  # main = "Relationship Between Evaluation Score and Professor Beauty Average",
   #  ylab = "Evaluation Score", 
   #  xlab = "Beauty Average")
#add jitter to SleepNumeric
youth$SleepNumeric <- as.numeric(youth$SleepNumeric)
youth$SmokeLife_Convert <- as.numeric(youth$SmokeLife_Convert)



plot(jitter(youth$SmokeLife_Convert), youth$SleepNumeric, 
     pch = 16, 
     col = 'steelblue',
     main = "Hours of Sleep and Smoke Life with Jitter",
     ylab = "Hours of Sleep", 
     xlab = "Smoke Life with Jitter")

Step 5

Final Project:
Test if a trend in the plot is something more than natural variation,

Comments and Findings A linear model was fitted (m_SmokeLifeConvert) to predict average sleep hours by average smoke life the line was added to the plot using abline. The following is the equation for the linear model along with an interpretation of the slope.

Equation for linear model, interpreted slope:

y^= 6.347579 + -0.035437 * SmokeLife_Convert

Smoke life is a statistically significant predictor of hours of sleep as the p-value is approximately 0 (8.098e-11).

Smoke life does not appear to be a practically significant predictor of hours of sleep. For every 1 point increase in SmokeLife_Convert, the equation and plot and summary data predicts a decrease in sleep hours score -0.035437 which is not a significant change in hours of sleep. In summary, smoke life does not appear to be a significant predictor of hours of sleep.

m_SmokeLifeConvert <- lm(youth$SleepNumeric ~ youth$SmokeLife_Convert)
plot(jitter(youth$SleepNumeric, factor = 1.5) ~ jitter(youth$SmokeLife_Convert,factor = 1.5))
abline(m_SmokeLifeConvert)

cor(youth$SleepNumeric,youth$SmokeLife_Convert)
## [1] -0.2852868
summary(m_SmokeLifeConvert)
## 
## Call:
## lm(formula = youth$SleepNumeric ~ youth$SmokeLife_Convert)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.3476 -0.3476  0.6524  1.6524  5.1962 
## 
## Coefficients:
##                          Estimate Std. Error t value Pr(>|t|)    
## (Intercept)              6.347579   0.109388  58.028  < 2e-16 ***
## youth$SmokeLife_Convert -0.035437   0.005335  -6.642  8.1e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.383 on 498 degrees of freedom
## Multiple R-squared:  0.08139,    Adjusted R-squared:  0.07954 
## F-statistic: 44.12 on 1 and 498 DF,  p-value: 8.098e-11

Step 6

Final Project:
Review estimated proportion of daily smokers out of the population of youth smokers.

Comments and Findings A new dataframe, smokers was created that contains only the rows from the youth dataset that are associated with smoker respondents. The proportion of daily smokers was then calculated.

The calculated proportion of daily smokers from the smoker life pool of responses = 0.2163462, which is approximately 22%.

#us12 <- subset(atheism, nationality == "United States" & year == "2012")
smokers <- subset(youth, SmokeLife == "Yes")
summary(smokers)
##        X            Sleep            SleepNumeric        Sleep7      
##  Min.   :  2.0   Length:208         Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:112.2   Class :character   1st Qu.: 5.000   1st Qu.:0.0000  
##  Median :225.5   Mode  :character   Median : 7.000   Median :1.0000  
##  Mean   :238.4                      Mean   : 6.255   Mean   :0.5918  
##  3rd Qu.:365.0                      3rd Qu.: 7.000   3rd Qu.:1.0000  
##  Max.   :500.0                      Max.   :10.000   Max.   :1.0000  
##                                                      NA's   :12      
##    X.1          SmokeLife_Convert   X.2          SmokeDaily_Convert
##  Mode:logical   Min.   :1         Mode:logical   Min.   :  0.000   
##  NA's:208       1st Qu.:1         NA's:208       1st Qu.:  0.000   
##                 Median :1                        Median :  0.000   
##                 Mean   :1                        Mean   :  2.596   
##                 3rd Qu.:1                        3rd Qu.:  0.000   
##                 Max.   :1                        Max.   :100.000   
##                                                                    
##   MarijuaEver       X.3               Age        SmokeLife        
##  Min.   :0.0000   Mode:logical   Min.   :14.0   Length:208        
##  1st Qu.:0.0000   NA's:208       1st Qu.:15.0   Class :character  
##  Median :1.0000                  Median :16.0   Mode  :character  
##  Mean   :0.6798                  Mean   :16.2                     
##  3rd Qu.:1.0000                  3rd Qu.:17.0                     
##  Max.   :1.0000                  Max.   :18.0                     
##  NA's   :5                                                        
##   SmokeDaily        MarijuaEver_Convert
##  Length:208         Length:208         
##  Class :character   Class :character   
##  Mode  :character   Mode  :character   
##                                        
##                                        
##                                        
## 
#calculate proportion of daily youth smokers
#get number of daily smokers


smokers_youth <-nrow(smokers[smokers$SmokeDaily=="Yes",])
smokers_youth
## [1] 45
#calculate proportion of daily youth smokers out of the number of smokers
#get number of us rows

smokers_rows <- nrow(smokers)
smokers_rows
## [1] 208
#calculate proportion of daily smokers out of total youth smokers
smokers_youth/smokers_rows
## [1] 0.2163462

Step 7

Final Project:
The statistic above was made from a sample of 500 youth. Of interest is insight into the population parameters. The calculation answers what proportion of youth smokers reported smoking daily, however the question of what proportion of youth who smoke do so daily is answered with an estimate of the parameter. For this understanding, an inference on proportions is needed.

Comments and Findings The inferential tools for estimating population proportion include the confidence interval and the hypothesis test. Conditions can be checked for inference by obtaining sample sizes to check those conditions. Group size is computed with the “by” command as follows: by(youth\(SmokeLife, youth\)SmokeDaily, length)

Below are the conditions for inference to construct a 95% confidence interval for the proportion of daily youth smokers in the United States:

  1. Randomly picked - If the random (picked radomly across the US) sample size is less than 10% of the population of daily youth smokers, the observations are independent - and this condition necessary for inference is satisfied as observations must be independent. In the smokers data set, there are 208 observations. This number of observations is significantly below 10% of the US population, so the observations are independent.

  2. In the population of youth smokers, the success/fail condition is satisfied: Calc 1 - Population of 208 * 0.2163462 = 45 Calc 2 - Population of 208 * 0.8076923 = 168 Both calculations are greater than 10. The success/fail condition is met if there are at least 10 expected successes and 10 expected failures in the sample.

  3. Expected number of successes is at least 10: np ≥ 10 Expected number of failures is at least 10: n(1-p) ≥ 10 where n is the sample size & p is the probability of success on a given trial.

All conditions for inference are met. Since the conditions for inference are reasonable, the standard error was calculated and the interval using the inference function was constructed.

Since the goal is to construct an interval estimate for a proportion, it’s necessary to specify what constitutes a “success”, which here is a response of “Yes” for smokes daily.

The error margin for surveys of this kind is ± 14-25% at 95% confidence.

Standard error = 0.0279 95 % Confidence interval = ( 0.1423 , 0.2518 )

by(youth$SmokeLife, youth$SmokeDaily, length)
## youth$SmokeDaily: No
## [1] 427
## ------------------------------------------------------------ 
## youth$SmokeDaily: Yes
## [1] 40
#calculate proportion of non-daily smokers
#get number of youth non-daily smokers
non_daily_smokers_youth <-nrow(smokers[smokers$SmokeDaily == "No",])
non_daily_smokers_youth
## [1] 168
#calculate proportion of non-daily-smoker responses
non_daily_smokers_youth/smokers_rows
## [1] 0.8076923
#Success/fail condition satisfied:  Is the calculation greater than 10?

#us_rows *(us_atheist/us_rows)

smokers_rows*(smokers_youth/smokers_rows)
## [1] 45
#Success/fail condition satisfied:  Is the calculation greater than 10?

#us_rows *(us_non_atheist/us_rows)

smokers_rows*(non_daily_smokers_youth/smokers_rows)
## [1] 168
#If the conditions for inference are reasonable, calculate the standard error and construct the interval using the inference function 


#inference(smokers$SmokeDaily, est = "proportion", type = "ci", method = "theoretical", success = "Yes")

Step 8

Final Project: Since gathering information on an entire population of youth would be very costly, time consuming, and likely impossible, a sample of the population is helpful for understanding the properties of the population.

Comments and Findings To estimate the proportion of youth smokers who smoke daily, the sample_n command is used to survey the population. A bar plot is used to visualize the distribution of smoking responses, and summary statistics assist in confirming the population properties are in alignment with the sample.

The sample_n command collects a random sample size of 100 from the smokers dataset and assigns the result to youthSamp1. This is similar to randomly drawing from responses from the entire population. It is easier to work with 100 responses than with all of those in the population.

By using a larger number of samples tested, a more accurate estimate of the population proportion is generated (hence the basis of 100 vs. a smaller number). One hundred responses from the smoker subset of youth is easier to work with than the entire population.
When using the population, 78% of youth smokers do not smoke daily while 19% do (2% did not respond to the daily question). When using the random sample of 100, 78% of youth smokers do not smoke daily while 21% do (1% did not respond to the daily question).

ggplot(smokers, aes(x = SmokeDaily)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Proportion of Youth Daily Smokers"
  ) +
  coord_flip() 

smokers %>%
  count(SmokeDaily) %>%
  mutate(p = n /sum(n))
##   SmokeDaily   n          p
## 1         No 163 0.78365385
## 2        Yes  40 0.19230769
## 3       <NA>   5 0.02403846
#take sample of population of youth smokers
set.seed(1)
youthSamp1 <- smokers %>%
  sample_n(100)
#Visualize the distribution of the sample by using a bar plot.
set.seed(1)
ggplot(youthSamp1, aes(x = SmokeDaily)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Sample of Youth Daily Smokers"
  ) +
  coord_flip()

#summary statistics from the sample
set.seed(1)
youthSamp1 %>%
  count(SmokeDaily) %>%
  mutate(s = n /sum(n))
##   SmokeDaily  n    s
## 1         No 77 0.77
## 2        Yes 20 0.20
## 3       <NA>  3 0.03

Step 9

Final Project:

To accurately estimate the population mean, it’s useful to get a sense of how much variability to expect. The distribution of sample proportions (i.e. sampling distribution of the proportion) is used to understand the variability.

Comments and Findings There are 15,000 elements in sample_youth100. Around 8% (1,200 of the 15,000 elements in sample_youth100) smoke daily. The mean appears to be less than the original dataset (approximately 20%) and more concentrated than the graph above. Since the mean is a better estimate the larger the sample size, a sample size of 100 was used instead of a lower sample size. In order to make estimates that are close to the true value, a sampling distribution with a small spread is best. The larger sample size has a smaller spread and is preferable for a sampling distribution.

#take 15,000 different samples of size 100 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (100) from the population of all youth daily smokers in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the Smokes Daily == "no" responses
#store each result in a vector called sample_youth100
#replace = TRUE since sampling distributions are constructed by sampling with replacement.



sample_youth100 <- youth %>%
                     rep_sample_n(size = 100, reps = 15000, replace = TRUE) %>%
                     count(SmokeDaily) %>%
                     mutate(p_hat = n /sum(n)) %>%
                     filter(SmokeDaily == "Yes")
#Visualize the distribution of the proportions with a histogram.


ggplot(data = sample_youth100, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02) +
  labs(
    x = "p_hat (Smokes Daily)",
    title = "Sampling distribution of p_hat",
    subtitle = "Sample size = 100, Number of samples = 15000")

set.seed(200)
ggplot(sample_youth100, aes(x = p_hat)) +
  geom_bar() +
  labs(
    x = "p_hat   Smokes Daily", y = "Count",
    title = "Sample _youth100:  Sampling Distribution of p_hat"
  ) +
  coord_flip() #for fun, flipping the coordinate :)

Problem After running most of the tests, it seems this data set is quite limited, especially with the number of variables. I would have liked to have had more variables so I could take additional subsets and processed additional tests. It seems there are weaknesses in this observational study. I would be interested to understand if gender played a role in the observational study. It seems the response successes and failures could be better understood by further separating the groups into male/female.

LS0tDQp0aXRsZTogIkZpbmFsIFByb2plY3QiDQphdXRob3I6ICJBYXJ5biBaaW1tZXJtYW4iDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQpsaWJyYXJ5KHN0YXRzcikNCmxpYnJhcnkoU3RNb1NpbSkNCmxpYnJhcnkoUmNwcFBhcmFsbGVsKQ0KbGlicmFyeShSY3BwKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZGF0YS50cmVlKQ0KbGlicmFyeShwbG90cml4KQ0KbGlicmFyeShpbmZlcikNCnNldC5zZWVkKDExMCkNCg0KDQoNCg0KYGBgDQoNCiMjIyBTdGVwIDEgDQpGaW5hbCBQcm9qZWN0OiAgDQpBbmFseXplIERhdGEgDQoNCjEuICBEb3dubG9hZCB0aGUgZGF0YQ0KMi4gIFZpZXcgb2JzZXJ2YXRpb25zDQozLiAgVmlldyBzdW1tYXJ5IGRhdGENCjQuICBWaWV3IHRoZSB0YWJsZSBvZiB2YXJpYWJsZXMgZm9yIHRoZSBvYnNlcnZhdGlvbnMNCg0KDQoqKipDb21tZW50cyBhbmQgRmluZGluZ3MqKioNClRoZSBvcmlnaW5hbCBkYXRhZnJhbWUgY29uc2lzdHMgb2YgNTAwIG9ic2VydmF0aW9ucyBhbmQgNiB2YXJpYWJsZXMuICBUbyB2aWV3IHRoZSBkYXRhLCB0aGUgc3RydWN0dXJlLCBzdW1tYXJ5IGRhdGEsIGFuZCBhIHRhYmxlIG9mIHlvdXRoIHZhcmlhYmxlcyB3ZXJlIGdlbmVyYXRlZCBhcyBzZWVuIGluIHRoZSBjb2RlIGJlbG93Lg0KDQoqKipQcm9ibGVtKioqICANCldoaWxlIHRyeWluZyB0byB3b3JrIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEsIGVycm9ycyB3ZXJlIGdlbmVyYXRlZCBkdXJpbmcgc29tZSBvZiB0aGUgdGVzdHMgYmVjYXVzZSBvZiBkYXRhIHR5cGVzLiAgVG8gcmVzb2x2ZSB0aGUgcHJvYmxlbSB3aXRoIGluY29tcGF0aWJsZSBkYXRhIHR5cGVzLCB0aGUgb3JpZ2luYWwgZGF0YXNldCB3YXMgbW9kaWZpZWQgYnkgY29udmVydGluZyB2YXJpYWJsZXMgd2l0aCBjaGFyIGRhdGEgdHlwZXMgKFllcy9ObyByZXNwb25zZXMpIHRvIGludGVnZXJzIG9mIDAgPSBObyBhbmQgMSA9IFllcy4gIFRoZSBTbGVlcCB2YXJpYWJsZSB3YXMgbW9kaWZpZWQgZnJvbSBjaGFyIHRvIGludCAocmVtb3ZlZCBhbGwgY2hhcnMgb3RoZXIgdGhhbiBudW1iZXJzKS4gIFdvcnRoIG5vdGluZywgYSBTbGVlcCBpbnQgb2YgNCBpcyBhY3R1YWxseSAiNCBob3VycyBvciBsZXNzIjsgYSBTbGVlcCBpbnQgb2YgMTAgaXMgYWN0dWFsbHkgIjEwIGhvdXJzIG9yIG1vcmUuIiAgQWZ0ZXIgbW9kaWZ5aW5nIHRoZSBkYXRhIGZpbGUsIHRoZXJlIGFyZSAxNCB2YXJpYWJsZXMuICBUaGUgY29udmVydGVkIHZhcmlhYmxlIGNvbHVtbnMgaW5jbHVkZSB0aGUgZm9sbG93aW5nOiAgU2xlZXBOdW1lcmljLCBTbW9rZUxpZmVfQ29udmVydCwgU21va2VEYWlseUNvbnZlcnQsIE1hcmlqdWFFdmVyX0NvbnZlcnQsIGFuZCB4IHZhcmlhYmxlcy4gIFRoZSBvcmlnaW5hbCB2YXJpYWJsZXMgNiBhcmUgYXMgZm9sbG93czogIFNsZWVwLCBTbGVlcDcsIE1hcmlqdWFFdmVyLCBBZ2UsIFNtb2tlTGlmZSwgU21va2VEYWlseS4gDQpgYGB7ciBjb2RlLWNodW5rLWxhYmVsfQ0KI1RoZSBEYXRhDQpzZXR3ZCgiQzovQWFyeW5aaW1tZXJtYW4vQmlvc3RhdGlzdGljcyBQcm9qZWN0IikNCnlvdXRoIDwtcmVhZC5jc3YoIllvdXRoUmlzazIwMDlBWi5jc3YiKQ0KZGVzdGZpbGUgPSAieW91dGguUkRhdGEiDQpzdHIoeW91dGgpICAgICN2aWV3IDUwMCBvYnNlcnZhdGlvbnMgd2l0aCA2IHZhcmlhYmxlcw0Kc3VtbWFyeSh5b3V0aCkgI3ZpZXcgc3VtbWFyeSBkYXRhDQp2aWV3KHlvdXRoKSAgI3ZpZXcgdGFibGUgb2YgdmFyaWFibGVzIGZvciB0aGUgNTAwIG9ic2VydmF0aW9ucw0KDQpgYGANCmBgYHtyfQ0KI2NvbnZlcnQgdmFyaWFibGVzIHRvIGZhY3RvcnMsIHdoZXJlIG5lY2Vzc2FyeQ0KeW91dGgkU2xlZXAgPC0gYXMuZmFjdG9yKHlvdXRoJFNsZWVwKQ0KeW91dGgkU2xlZXA3IDwtIGFzLmZhY3Rvcih5b3V0aCRTbGVlcDcpDQp5b3V0aCRTbW9rZUxpZmUgPC0gYXMuZmFjdG9yKHlvdXRoJFNtb2tlTGlmZSkNCnlvdXRoJFNtb2tlRGFpbHkgPC0gYXMuZmFjdG9yKHlvdXRoJFNtb2tlRGFpbHkpDQp5b3V0aCRNYXJpanVhRXZlciA8LSBhcy5mYWN0b3IoeW91dGgkTWFyaWp1YUV2ZXIpDQpzdW1tYXJ5KHlvdXRoKQ0Kc3RyKHlvdXRoKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KYGBgDQojIyMgU3RlcCAyDQpGaW5hbCBQcm9qZWN0OiAgDQpEZWZpbml0aW9uIG9mIHRoZSB0eXBlIG9mIHN0dWR5IHRoZSBkYXRhc2V0IGlzIGFzc29jaWF0ZWQgd2l0aCwgZGVmaW5pdGlvbiBvZiBhIHJlc2VhcmNoIHF1ZXN0aW9uLCBhbmQgZGF0YSBtYW5pcHVsYXRpb25zIGJhc2VkIG9uIHRoZSBzdHVkeSB0eXBlIGFuZCBkYXRhLiAgIA0KDQoNCioqKkNvbW1lbnRzIGFuZCBGaW5kaW5ncyoqKg0KVGhpcyBhbiBvYnNlcnZhdGlvbmFsIHN0dWR5IG9mIHN0dWRlbnRzIGluIGdyYWRlcyA5LTEyIGNvbmNlcm5pbmcgaGVhbHRoLXJpc2sgYmVoYXZpb3JzLiAgT25lIHJlc2VhcmNoIHF1ZXN0aW9uIHBvc2VkIGlzIHdoZXRoZXIgaGVhbHRoLXJpc2sgYmVoYXZpb3JzIG9mIHNtb2tpbmcsIGluY2x1ZGluZyBtYXJpanVhbmEsIGxlYWRzIGRpcmVjdGx5IHRvIGRpZmZlcmVuY2VzIGluIGhvdXJzIG9mIHNsZWVwLg0KDQpJbiB0aGlzIG9ic2VydmF0aW9uYWwgc3R1ZHksIHlvdXRoIGFyZSBzdXJ2ZXllZCBhcyB0byB0aGVpciBoZWFsdGgtcmlzayBiZWhhdmlvcnMgYW5kIHNsZWVwLiBObyBhdHRlbXB0IGlzIG1hZGUgdG8gYWZmZWN0IHRoZSBvdXRjb21lOyBubyB0cmVhdG1lbnQgaXMgZ2l2ZW4gdG8gbWVhc3VyZSBhbiBvdXRjb21lIGFzIHRoaXMgaXMgbm90IGFuIGV4cGVyaW1lbnQuICBJbiB0aGlzIHN0dWR5LCByZXNlYXJjaGVycyBtYWRlIG5vIGF0dGVtcHRzIHRvIG1hbmlwdWxhdGUgdGhlIHN0dWR5IC0gaW5zdGVhZCwgdGhleSBzaW1wbHkgb2JzZXJ2ZS4gIFRoZXJlIGFyZSBubyBwcm9jZWR1cmVzIGNhcnJpZWQgb3V0IHRvIHN1cHBvcnQsIHJlZnV0ZSwgb3IgdmFsaWRhdGUgYSBoeXBvdGhlc2lzOyB0aGVyZSBpcyBubyBleHBlcmltZW50aW5nIHRvIHByb3ZpZGUgaW5zaWdodCBpbnRvIGNhdXNlLWFuZC1lZmZlY3QuICBUaGVyZSBpcyBubyBkZW1vbnN0cmF0aW9uIG9mIGFuIG91dGNvbWUgdGhhdCBwb3NzaWJseSBvY2N1cnMgd2hlbiBhIGZhY3RvciBpcyBtYW5pcHVsYXRlZC4gIFNpbmNlIHRoaXMgaXMgYW4gb2JzZXJ2YXRpb25hbCBzdHVkeSwgdGhlcmUgaXMgbm8gY29udHJvbCBncm91cCBvciBleHBlcmltZW50YWwgZ3JvdXBzLiAgVGhlIHZhcmlhYmxlcyBkbyBub3QgY2F1c2Ugb3IgZXhwbGFpbiwgaG93ZXZlciB0aGUgdmFyaWFibGVzIGNhbiBiZSByZWxhdGVkLiAgDQoNCg0KUXVlc3Rpb24gZm9yIHRoZSBvYnNlcnZhdGlvbmFsIHN0dWR5OiAgQSB5b3V0aCdzIGhlYWx0aC1yaXNrIGJlaGF2aW9yIChzbW9raW5nKSBpcyBwb3NpdGl2ZWx5L25lZ2F0aXZlbHkgY29ycmVsYXRlZCB0byBob3VycyBvZiBzbGVlcC4NCg0KDQpUbyBhbnN3ZXIgdGhpcyBxdWVzdGlvbiwgYSBzZXJpZXMgb2YgZGF0YSBtYW5pcHVsYXRpb25zIHdpbGwgYmUgcGVyZm9ybWVkIGluIFIgYXMgZm9sbG93czoNCg0KDQoxLiAgUmV2aWV3IHRoZSBkaXN0cmlidXRpb24gb2Ygc2xlZXAgdXNpbmcgaGlzdG9ncmFtcyBhbmQgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGN1cnZlIGJhc2VkIG9uIGNhbGN1bGF0ZWQgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uDQogICAgUXVlc3Rpb246IElzIGl0IHNrZXdlZCwgYW5kIGlmIHNvLCBpbiB3aGF0IGRpcmVjdGlvbi4NCiAgDQogICAgQW5zd2VyOiAgVGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgdmFyaWFibGUgc2xlZXAgaXMgbW9yZSBza2V3ZWQgdG8gdGhlIGxlZnQgKHVuZGVyIHRoZSBtZWFuIG9mIDYpLiAgQWNjb3JkaW5nIHRvIHRoaXMgZGlzdHJpYnV0aW9uLCB5b3V0aCAgDQogICAgICAgICAgICAgIGdldCBtb3JlIHNsZWVwIHRoYW4gbGVzcywgd2hpY2ggaXMgd2hhdCBJIGV4cGVjdGVkLiAgDQogICAgUHJvYmxlbTogSnVzdCBhcyBJIGhhdmUgdHJpZWQgdG8gYWRkIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjdXJ2ZSB0byBteSBoaXN0b2dyYW0gaW4gcHJldmlvdXMgYXNzaWdubWVudHMsIEkgdHJpZWQgdG8gYWRkIG9uZSBpbiANCiAgICAgICAgICAgICBteSBmaXJzdCBzbmlwcGV0IG9mIGNvZGUuICBJdCBhcHBlYXJzIG15IGNvZGUgaXMgd3JvbmcuIEkgd2FzIGhvcGluZyB0byBwbG90IHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGN1cnZlIGFuZCB0aGVuIHNlZSAgDQogICAgICAgICAgICAgIm5vcm1hbGN5LiIgIEluIG90aGVyIHdvcmRzLCBhIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBhdmVyYWdlIHNsZWVwLCBpbmNsdWRpbmcgYSBmZXcgb3V0c2lkZSB0aGUgbm9ybXMgaW4gdGhlIGJlbG93IGF2ZXJhZ2Ugb3IgDQogICAgICAgICAgICAgYWJvdmUgYXZlcmFnZSBkaXJlY3Rpb25zLCBob3dldmVyIHlvdXRoIG9mIHRoZXNlIGFnZXMgYXJlbid0ICJub3JtYWwiIHNsZWVwZXJzLCBhbmQgbXkgY29kZSByZXN1bHRlZCBpbiBhIGZsYXQgbGluZS4gIFRvIGRlYWwgd2l0aCAgICAgICAgICAgICAgdGhpcyBwcm9ibGVtLCBJIG1hbnVhbGx5IGNhbGN1bGF0ZWQgdGhlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBhbmQgdGhlbiB1c2VkIGdncGxvdC4gIA0KICAgIA0KICAgICAgICAgICAgIA0KMi4gT25lIHdheSBvZiBjYWxjdWxhdGluZyBhIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciBhIHNhbXBsZSBtZWFuIGJ5IGFkZGluZyBhbmQgc3VidHJhY3RpbmcgMS45NiBzdGFuZGFyZCBlcnJvcnMgdG8gdGhlIHBvaW50IGVzdGltYXRlLiAgV2hlbiBkb2luZyB0aGlzLCBldmVuIHRob3VnaCB0aGUgZnVsbCBwb3B1bGF0aW9uIGlzbid0IGtub3duLCB3aXRoIDk1JSBjb25maWRlbmNlLCB0aGUgdHJ1ZSBhdmVyYWdlIGhvdXJzIG9mIHNsZWVwIGZvciB5b3V0aCBsaWVzIGJldHdlZW4gdGhlIHZhbHVlcyBvZiB0aGUgdXBwZXIgYW5kIGxvd2VyIGxpbWl0cyBvZiA2LjAyMDcyMSBhbmQgNy4xMTkyNzksIHJlc3BlY3RpdmVseS4gIFRoZXJlIGFyZSBjb25kaXRpb25zIGZvciB0aGlzIHJhbmdlIHRvIGJlIHZhbGlkLiBUaGUgc2FtcGxlIG1lYW4gbXVzdCBiZSBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgaGF2ZSBzdGFuZGFyZCBlcnJvciBzL27iiJLiiJLiiJouIEZvciB0aGVzZSBjb25kaXRpb25zIHRvIGJlIG1ldCwgdGhlIHNhbXBsZSBvYnNlcnZhdGlvbnMgYXJlIHJhbmRvbSwgc2FtcGxlIHNpemUgaXMgZ3JlYXRlciB0aGFuIDUwIGFuZCBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBzaG91bGQgbm90IGJlIGdyZWF0bHkgc2tld2VkIHRvIG9uZSBzaWRlIG9yIHRoZSBvdGhlci4gVGhlIGNvbmZpZGVuY2UgaXMgaW4gdGhlIG1ldGhvZCwgbm90IGEgcGFydGljdWxhciBDb25maWRlbmNlIEludGVydmFsLiAgIEEgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhIHZhbHVlIHdpbGwgZmFsbCBiZXR3ZWVuIGFuIHVwcGVyIGFuZCBsb3dlciBib3VuZCBvZiBhIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbi4gIFNpbmNlIHRoZSBza2V3aW5nIGlzIG5vdCBncmVhdGx5IG9uZSB3YXkgb3IgYW5vdGhlciwgYWNjb3JkaW5nIHRvIHRoaXMgbW9kZWwgdGhlIGNvbmRpdGlvbnMgZm9yIGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgYXBwZWFyIHRvIGJlIG1ldC4gIFdvcnRoIG5vdGluZywgdGhlICIwIiBzbGVlcCBpcyBhY3R1YWxseSB3aGVyZSByZXNwb25kZW50cyBkaWQgbm90IGFuc3dlciB0aGUgcXVlc3Rpb24uICBTZWUgZGF0YSBjb252ZXJzaW9uIHByb2JsZW0gaW4gc3RlcCAxLg0KDQogICAgIFByb2JsZW06ICBXaGVuIGF0dGVtcHRpbmcgdG8gcGxvdCB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCwgdGhlIGNvZGUgZmFpbGVkLiAgU2VlIGNvZGUgYmVsb3cuDQoNCg0KDQpgYGB7cn0NCg0KYGBgDQoNCg0KYGBge3J9DQojaGlzdCAodiwgbWFpbiwgeGxhYiwgeGxpbSwgeWxpbSwgYnJlYWtzLGNvbCxib3JkZXIpDQojd2hlcmUgdiDigJMgdmVjdG9yIHdpdGggbnVtZXJpYyB2YWx1ZXMNCiNtYWluIOKAkyBkZW5vdGVzIHRpdGxlIG9mIHRoZSBjaGFydA0KI2NvbCDigJMgc2V0cyBjb2xvcg0KI2JvcmRlciAtc2V0cyBib3JkZXIgY29sb3IgdG8gdGhlIGJhcg0KI3hsYWIgLSBkZXNjcmlwdGlvbiBvZiB4LWF4aXMNCiN4bGltIC0gZGVub3RlcyB0byBzcGVjaWZ5IHJhbmdlIG9mIHZhbHVlcyBvbiB4LWF4aXMNCiN5bGltIOKAkyBzcGVjaWZpZXMgcmFuZ2UgdmFsdWVzIG9uIHktYXhpcw0KI2JyZWFrIOKAkyBzcGVjaWZpZXMgdGhlIHdpZHRoIG9mIGVhY2ggYmFyLg0KDQpoaXN0KHlvdXRoJFNsZWVwTnVtZXJpYywNCm1haW49IkhlYWx0aC1SaXNrIEJlaGF2aW9yOiAgRGlzdHJpYnV0aW9uIG9mIFNsZWVwIiwNCnhsYWI9IlNsZWVwIiwNCmJvcmRlcj0iR3JlZW4iLA0KY29sPSJPcmFuZ2UiKQ0KDQpjdXJ2ZSAoZG5vcm0oeCwgbWVhbj1tZWFuKHlvdXRoJFNsZWVwTnVtZXJpYyksIHNkPXNkKHlvdXRoJFNsZWVwTnVtZXJpYykpLCBhZGQ9VFJVRSwgY29sPSJyZWQiKSAgI0ltcGxlbWVudCB0aGUgTm9ybWFsIERpc3RyaWJ1dGlvbiBDdXJ2ZSBpbiBIaXN0b2dyYW0NCmBgYA0KYGBge3J9DQoNCiNHZXQgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIFNsZWVwTnVtZXJpYw0KU05tZWFuIDwtIG1lYW4oeW91dGgkU2xlZXBOdW1lcmljKQ0KU05zZCAgIDwtIHNkKHlvdXRoJFNsZWVwTnVtZXJpYykNClNObWVhbg0KU05zZA0KYGBgDQpgYGB7cn0NCmhpc3QoeW91dGgkU2xlZXBOdW1lcmljLA0KbWFpbiA9Ikhpc3RvZ3JhbSAtIFlvdXRoIFJpc2sgSGFiaXRzLCBWaWV3IDIgLSBTbGVlcCIsDQpib3JkZXIgPSAiR3JlZW4iLA0KY29sID0gIk9yYW5nZSIgLA0KYnJlYWtzID0gNSkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCiNQbG90IFNsZWVwTnVtZXJpYzsgaW5jbHVkZSBhIG5vcm1hbCBkaXN0cmlidXRpb24gY3VydmUNCmdncGxvdChkYXRhID0geW91dGgsIGFlcyh4ID0gU2xlZXBOdW1lcmljKSkgKw0KICAgICAgICBnZW9tX2JsYW5rKCkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKw0KICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gU05tZWFuLCBzZCA9IFNOc2QpLCBjb2wgPSAidG9tYXRvIikNCmBgYA0KYGBge3J9DQpwb3B1bGF0aW9uIDwtIHlvdXRoJFNsZWVwTnVtZXJpYw0Kc2FtcFlvdXRoIDwtIHNhbXBsZShwb3B1bGF0aW9uLCAxMDApDQpoaXN0KHNhbXBZb3V0aCwNCm1haW4gPSJIaXN0b2dyYW0gLSBIb3VycyBvZiBTbGVlcCIsDQpib3JkZXIgPSAiR3JlZW4iLA0KY29sID0gIk9yYW5nZSIgLA0KYnJlYWtzID0gNSkNCmBgYA0KDQoNCmBgYHtyfQ0Kc2FtcGxlX21lYW4gPC0gbWVhbihzYW1wWW91dGgpDQpzYW1wbGVfbWVhbg0KYGBgDQpgYGB7cn0NCiNDYWxjdWxhdGUgYSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHNhbXBsZSBtZWFuIGJ5IGFkZGluZyBhbmQgc3VidHJhY3RpbmcgMS45NiBzdGFuZGFyZCBlcnJvcnMgdG8gdGhlIHBvaW50IGVzdGltYXRlLg0KDQpzZSA8LSBzZChzYW1wWW91dGgpIC8gc3FydCgxMDApDQpsb3dlciA8LSBzYW1wbGVfbWVhbiAtIDEuOTYgKiBzZQ0KdXBwZXIgPC0gc2FtcGxlX21lYW4gKyAxLjk2ICogc2UNCmMobG93ZXIsIHVwcGVyKQ0Kc2UNCnNhbXBsZV9tZWFuDQpgYGANCmBgYHtyfQ0KYGBgDQoNCmBgYHtyfQ0KI0F0dGVtcHRlZCB0byBwbG90IHRoZSBjb25maWRlbmNlIGludGVydmFsOyBjb2RlIGZhaWxlZC4NCiNwbG90X2NpKGxvd2VyLCB1cHBlciwgbWVhbihzYW1wWW91dGgpKQ0KYGBgDQoNCiMjIyBTdGVwIDMNCkZpbmFsIFByb2plY3Q6ICANClVuZGVyc3RhbmQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNvbWUgb2YgdGhlIG90aGVyIHZhcmlhYmxlcywgbm90IGluY2x1ZGluZyBTbGVlcE51bWVyaWMuICANCg0KKioqQ29tbWVudHMgYW5kIEZpbmRpbmdzKioqDQpTbGVlcE51bWVyaWMgd2FzIGV4Y2x1ZGVkIGFuZCB0d28gb3RoZXIgdmFyaWFibGVzLCBTbW9rZURhaWx5IGFuZCBBZ2UsIHdlcmUgc2VsZWN0ZWQuIFRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgb3RoZXIgdmFyaWFibGVzIHdhcyBhbmFseXplZCB1c2luZyBhIGJveHBsb3QgYXMgYSB2aXN1YWxpemF0aW9uIHRvb2wuICBBIHNjYXR0ZXJwbG90IHdhcyBhbHNvIHVzZWQgdG8gZnVydGhlciB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAuIA0KDQoNCkluIGxvb2tpbmcgYXQgdGhlIGF2ZXJhZ2UgYWdlIG9mIHRoZSB5b3V0aCB2cyB0aGUgaGVhbHRoLXJpc2sgdmFyaWFibGUgb2Ygc21va2luZyBkYWlseSwgdGhlIG1lYW5zIG9mIHRoZSB0d28gdmFyaWFibGVzIHdlcmUgY29tcGFyZWQgYW5kIHJlc3VsdGVkIGluIGEgdmVyeSBzbGlnaHQgZGlmZmVyZW5jZSBhcyBzZWVuIGJlbG93Og0KDQoNCnlvdXRoJFNtb2tlRGFpbHk6IE5vDQpbMV0gMTYuMDU2MjENCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSANCnlvdXRoJFNtb2tlRGFpbHk6IFllcw0KWzFdIDE2LjMyNQ0KDQoNCg0KVGhlIHRlc3RzIHdlcmUgcmVwZWF0ZWQgZm9yIGFub3RoZXIgc2V0IG9mIHZhcmlhYmxlcywgYWdlIGFuZCB1c2Ugb2YgbWFyaWp1YW5hIGV2ZXIuICBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtZWFucyBpcyBtb3JlIHRoYW4gYmV0d2VlbiBhZ2UgYW5kIGRhaWx5IHNtb2tpbmcsIGJ1dCBvdGhlciB0ZXN0aW5nIGlzIHN0aWxsIG5lZWRlZCB0byB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAsIGlmIGFueS4NCg0KeW91dGgkTWFyaWp1YUV2ZXI6IDANClsxXSAxNS45MDMyMw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIA0KeW91dGgkTWFyaWp1YUV2ZXI6IDENClsxXSAxNi4zNzE0Mw0KDQoNCkl0IGFwcGVhcnMgYSBoeXBvdGhlc2lzIHRlc3QgbWlnaHQgYmUgdXNlZnVsIHRvIHNlZSBpZiB0aGUgZGlmZmVyZW5jZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBCeSBsb29raW5nIGF0IHRoZSBib3hwbG90LCBpdCBkb2VzIG5vdCBhcHBlYXIgdGhlcmUgaXMgYSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGFnZSBhbmQgZGFpbHkgc21va2luZywgbm9yIGlzIHRoZXJlIG9uZSBiZXR3ZWVuIGFnZSBhbmQgbWFyaWp1YW5hIHNtb2tpbmcuDQoNCmBgYHtyfQ0KI1RoZSBEYXRhDQpzZXR3ZCgiQzovQWFyeW5aaW1tZXJtYW4vQmlvc3RhdGlzdGljcyBQcm9qZWN0IikNCnlvdXRoIDwtcmVhZC5jc3YoIllvdXRoUmlzazIwMDlBWi5jc3YiKQ0KZGVzdGZpbGUgPSAieW91dGguUkRhdGEiDQpzdHIoeW91dGgpICAgICN2aWV3IDUwMCBvYnNlcnZhdGlvbnMgd2l0aCA3IHZhcmlhYmxlcw0Kc3VtbWFyeSh5b3V0aCkgI3ZpZXcgc3VtbWFyeSBkYXRhDQp2aWV3KHlvdXRoKSAgI3ZpZXcgdGFibGUgb2YgdmFyaWFibGVzIGZvciB0aGUgNTAwIG9ic2VydmF0aW9ucw0KYGBgDQoNCg0KDQpgYGB7cn0NCmJveHBsb3QoQWdlflNtb2tlRGFpbHksDQogICAgICAgZGF0YT15b3V0aCwNCiAgICAgICBtYWluID0gIkFnZSB2cyBTbW9rZSBEYWlseSIsDQogICAgICAgeGxhYiA9ICJZb3V0aCBTbW9rZSBEYWlseSIsDQogICAgICAgeWxhYiA9ICJBZ2Ugb2YgWW91dGgiLA0KICAgICAgIGNvbCA9ICJvcmFuZ2UiLA0KICAgICAgIGJvcmRlciA9ICJicm93biIsDQogICAgICAgdmVydGljYWwgPSBUUlVFLA0KICAgICAgIG5vdGNoID0gRkFMU0UpDQoNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCiN2aWV3IG1lYW5zIG9mIHRoZSBkaXN0cmlidXRpb25zIGJ5IHVzaW5nIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gdG8gc3BsaXQgdGhlIFNtb2tlRGFpbHkgZ3JvdXAgdmFyaWFibGUgaW50byBZZXMvTm8gZ3JvdXBzLCB0aGVuIHRha2luZyB0aGUgbWVhbiBvZiBlYWNoIHVzaW5nIHRoZSBtZWFuIGZ1bmN0aW9uLg0KDQpieSh5b3V0aCRBZ2UsIHlvdXRoJFNtb2tlRGFpbHksIG1lYW4pDQpgYGANCmBgYHtyfQ0KYm94cGxvdChBZ2V+TWFyaWp1YUV2ZXIsDQogICAgICAgZGF0YT15b3V0aCwNCiAgICAgICBtYWluID0gIk1hcmlqdWFuYSBFdmVyIHZzIEFnZSIsDQogICAgICAgeGxhYiA9ICJNYXJpanVhbmEgRXZlciIsDQogICAgICAgeWxhYiA9ICJBZ2UiLA0KICAgICAgIGNvbCA9ICJvcmFuZ2UiLA0KICAgICAgIGJvcmRlciA9ICJicm93biIsDQogICAgICAgdmVydGljYWwgPSBUUlVFLA0KICAgICAgIG5vdGNoID0gRkFMU0UpDQpgYGANCg0KYGBge3J9DQojdmlldyBtZWFucyBvZiB0aGUgZGlzdHJpYnV0aW9ucyBieSB1c2luZyB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIHRvIHNwbGl0IHRoZSBNYXJpanVhbmEgRXZlciBpbnRvIFllcy9ObyBncm91cHMsIHRoZW4gdGFraW5nIHRoZSBtZWFuIG9mIGVhY2ggdXNpbmcgdGhlIG1lYW4gZnVuY3Rpb24uDQoNCmJ5KHlvdXRoJEFnZSwgeW91dGgkTWFyaWp1YUV2ZXIsIG1lYW4pDQpgYGANCiMjIyBTdGVwIDQNCkZpbmFsIFByb2plY3Q6ICANClRoZSBmdW5kYW1lbnRhbCBxdWVzdGlvbiBpcyB3aGV0aGVyIG9yIG5vdCB0aGUgaGVhbHRoLXJpc2sgYmVoYXZpb3IgKHNtb2tpbmcpIGlzIHBvc2l0aXZlbHkvbmVnYXRpdmVseSBjb3JyZWxhdGVkIHRvIGhvdXJzIG9mIHNsZWVwLiBJdCBzZWVtcyB0aGF0IHNtb2tpbmcsIHdoZXRoZXIgcmVndWxhciBjaWdhcmV0dGVzIG9yIG1hcmlqdWFuYSwgbWlnaHQgYmUgZGlzcnVwdGl2ZSB0byBvdmVyYWxsIGhvdXJzIG9mIHNsZWVwLiAgVA0KDQoqKipDb21tZW50cyBhbmQgRmluZGluZ3MqKioNClRoaXMgd2FzIHRlc3RlZCB0aGlzIHVzaW5nIGxpbmVhciByZWdyZXNzaW9uIHZpYSBhIHNjYXR0ZXJwbG90IHRvIHNlZSBpZiB0aGlzIGFwcGVhcnMgdG8gYmUgdGhlIGNhc2UuIEEgc2NhdHRlcnBsb3QsIGluIGNvbmp1Y3Rpb24gd2l0aCBqaXR0ZXIgd2FzIHVzZWQuDQoNClByb2JsZW06ICBUaGUgc2NhdHRlcnBsb3QgZGlkIG5vdCBwcm92aWRlIGEgY2xlYXIgaW1hZ2Ugb2YgdGhlIGluZGl2aWR1YWwgcG9pbnRzLiAgTXkgYXNzdW1wdGlvbiBpcyB0aGlzIGlzIGJlY2F1c2UgdGhleSBvdmVybGFwIHRvbyBjbG9zZWx5IHdpdGggbGlrZSB2YWx1ZXMuICBJZiB0aGUgdmFsdWVzIHdlcmUgZGlmZmVyZW50LCB0aGUgaml0dGVyIHdvdWxkIGhhdmUgYWRkZWQgIm5vaXNlIiB0byB0aGUgeC1heGlzIHZhcmlhYmxlLCBhbmQgdGhlIGluZGl2aWR1YWwgcG9pbnRzIG9uIHRoZSBwbG90IHdvdWxkIGJlIG1vcmUgY2xlYXIvdmlzaWJsZS4gIA0KDQpUaGUgc2NhdHRlcnBsb3Qgd2FzIGltcGxlbWVudGVkIG11bHRpcGxlIHdheXMsIGJ1dCBhcyBzZWVuIGJlbG93LCB0aGUgcmVzdWx0cyBhcmUgdGhlIHNhbWUuIE15IGludGVycHJldGF0aW9uIGlzIHRoYXQgYSBzY2F0dGVycGxvdCBpc24ndCB0aGUgYmVzdCB3YXkgb2Ygdmlld2luZyB0aGlzIHBhcnRpY3VsYXIgZGF0YSBzZXQuDQoNCldvcnRoIG5vdGluZywgYmVjYXVzZSBvZiBkYXRhIHR5cGUgY29uZmxpY3RzLCBJIGhhZCB0byBhc3NpZ24gYSB2YWx1ZSB0byBhbGwgImJsYW5rcyIgaW4gdGhlIGRhdGEgc2V0LiAgSSBjaG9zZSBhIHZhbHVlIHRoYXQgd2FzIHZlcnkgZGlmZmVyZW50IGZyb20gdGhlIG90aGVyIHZhbHVlcywgIjEwMC4iIFRoZSBpbXBhY3QgdGhpcyBhc3NpZ25lZCB2YWx1ZSBoYXMgb24gcmVzdWx0cyBpcyBub3QgY2xlYXIuDQoNCmBgYHtyfQ0Kc3RyKHlvdXRoKSAgICAjdmlldyA1MDAgb2JzZXJ2YXRpb25zIHdpdGggNiAob3JpZ2luYWwpIHZhcmlhYmxlcw0Kc3VtbWFyeSh5b3V0aCkgI3ZpZXcgc3VtbWFyeSBkYXRhDQp2aWV3KHlvdXRoKSAgI3ZpZXcgdGFibGUgb2YgdmFyaWFibGVzIGZvciB0aGUgNTAwIG9ic2VydmF0aW9ucw0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KI3NjYXR0ZXJwbG90IA0KDQojVGhlIERhdGENCnNldHdkKCJDOi9BYXJ5blppbW1lcm1hbi9CaW9zdGF0aXN0aWNzIFByb2plY3QiKQ0KeW91dGggPC1yZWFkLmNzdigiWW91dGhSaXNrMjAwOUFaLmNzdiIpDQpkZXN0ZmlsZSA9ICJ5b3V0aC5SRGF0YSINCnN0cih5b3V0aCkgICAgI3ZpZXcgNTAwIG9ic2VydmF0aW9ucyB3aXRoIDcgdmFyaWFibGVzDQpzdW1tYXJ5KHlvdXRoKSAjdmlldyBzdW1tYXJ5IGRhdGENCnZpZXcoeW91dGgpICAjdmlldyB0YWJsZSBvZiB2YXJpYWJsZXMgZm9yIHRoZSA1MDAgb2JzZXJ2YXRpb25zDQpgYGANCg0KDQpgYGB7cn0NCiN5b3V0aCRTbGVlcE51bWVyaWMgPC0gYXMubnVtZXJpYyh5b3V0aCRTbGVlcE51bWVyaWMpDQojeW91dGgkU21va2VMaWZlX0NvbnZlcnQgPC0gYXMubnVtZXJpYyh5b3V0aCRTbW9rZURhaWx5X0NvbnZlcnQpDQoNCnBsb3QoeW91dGgkU2xlZXBOdW1lcmljfnlvdXRoJFNtb2tlTGlmZV9Db252ZXJ0LA0KICAgbWFpbiA9ICJSZWxhdGlvbnNoaXAgQmV0d2VlbiBIb3VycyBvZiBTbGVlcCBhbmQgU21va2UgTGlmZSIsDQogICAgIHlsYWIgPSAiSG91cnMgb2YgU2xlZXAiLCANCiAgICAgeGxhYiA9ICJTbW9rZSBMaWZlIikNCg0KDQoNCiNzY2F0dGVycGxvdCANCiNwbG90KGV2YWxzJHNjb3JlfmV2YWxzJGJ0eV9hdmcsDQogICMgbWFpbiA9ICJSZWxhdGlvbnNoaXAgQmV0d2VlbiBFdmFsdWF0aW9uIFNjb3JlIGFuZCBQcm9mZXNzb3IgQmVhdXR5IEF2ZXJhZ2UiLA0KICAgIyAgeWxhYiA9ICJFdmFsdWF0aW9uIFNjb3JlIiwgDQogICAjICB4bGFiID0gIkJlYXV0eSBBdmVyYWdlIikNCg0KYGBgDQoNCmBgYHtyfQ0KDQojYWRkIGppdHRlciB0byBTbGVlcE51bWVyaWMNCnlvdXRoJFNsZWVwTnVtZXJpYyA8LSBhcy5udW1lcmljKHlvdXRoJFNsZWVwTnVtZXJpYykNCnlvdXRoJFNtb2tlTGlmZV9Db252ZXJ0IDwtIGFzLm51bWVyaWMoeW91dGgkU21va2VMaWZlX0NvbnZlcnQpDQoNCg0KDQpwbG90KGppdHRlcih5b3V0aCRTbW9rZUxpZmVfQ29udmVydCksIHlvdXRoJFNsZWVwTnVtZXJpYywgDQogICAgIHBjaCA9IDE2LCANCiAgICAgY29sID0gJ3N0ZWVsYmx1ZScsDQogICAgIG1haW4gPSAiSG91cnMgb2YgU2xlZXAgYW5kIFNtb2tlIExpZmUgd2l0aCBKaXR0ZXIiLA0KICAgICB5bGFiID0gIkhvdXJzIG9mIFNsZWVwIiwgDQogICAgIHhsYWIgPSAiU21va2UgTGlmZSB3aXRoIEppdHRlciIpDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KIyMjIFN0ZXAgNQ0KRmluYWwgUHJvamVjdDogIA0KVGVzdCBpZiBhIHRyZW5kIGluIHRoZSBwbG90IGlzIHNvbWV0aGluZyBtb3JlIHRoYW4gbmF0dXJhbCB2YXJpYXRpb24sIA0KDQoqKipDb21tZW50cyBhbmQgRmluZGluZ3MqKioNCkEgbGluZWFyIG1vZGVsIHdhcyBmaXR0ZWQgKG1fU21va2VMaWZlQ29udmVydCkgdG8gcHJlZGljdCBhdmVyYWdlIHNsZWVwIGhvdXJzIGJ5IGF2ZXJhZ2Ugc21va2UgbGlmZSB0aGUgbGluZSB3YXMgYWRkZWQgdG8gdGhlIHBsb3QgdXNpbmcgYWJsaW5lLiBUaGUgZm9sbG93aW5nIGlzIHRoZSBlcXVhdGlvbiBmb3IgdGhlIGxpbmVhciBtb2RlbCBhbG9uZyB3aXRoIGFuIGludGVycHJldGF0aW9uIG9mIHRoZSBzbG9wZS4NCg0KDQpFcXVhdGlvbiBmb3IgbGluZWFyIG1vZGVsLCBpbnRlcnByZXRlZCBzbG9wZToNCg0KeV49IDYuMzQ3NTc5ICsgLTAuMDM1NDM3ICogU21va2VMaWZlX0NvbnZlcnQNCg0KDQpTbW9rZSBsaWZlIGlzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBwcmVkaWN0b3Igb2YgaG91cnMgb2Ygc2xlZXAgYXMgdGhlIHAtdmFsdWUgaXMgYXBwcm94aW1hdGVseSAwICg4LjA5OGUtMTEpLg0KDQoNClNtb2tlIGxpZmUgZG9lcyBub3QgYXBwZWFyIHRvIGJlIGEgcHJhY3RpY2FsbHkgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIGhvdXJzIG9mIHNsZWVwLiAgRm9yIGV2ZXJ5IDEgcG9pbnQgaW5jcmVhc2UgaW4gU21va2VMaWZlX0NvbnZlcnQsIHRoZSBlcXVhdGlvbiBhbmQgcGxvdCBhbmQgc3VtbWFyeSBkYXRhIHByZWRpY3RzIGEgZGVjcmVhc2UgaW4gc2xlZXAgaG91cnMgc2NvcmUgLTAuMDM1NDM3IHdoaWNoIGlzIG5vdCBhIHNpZ25pZmljYW50IGNoYW5nZSBpbiBob3VycyBvZiBzbGVlcC4gIEluIHN1bW1hcnksIHNtb2tlIGxpZmUgZG9lcyBub3QgYXBwZWFyIHRvIGJlIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIGhvdXJzIG9mIHNsZWVwLg0KDQoNCmBgYHtyfQ0KDQptX1Ntb2tlTGlmZUNvbnZlcnQgPC0gbG0oeW91dGgkU2xlZXBOdW1lcmljIH4geW91dGgkU21va2VMaWZlX0NvbnZlcnQpDQpwbG90KGppdHRlcih5b3V0aCRTbGVlcE51bWVyaWMsIGZhY3RvciA9IDEuNSkgfiBqaXR0ZXIoeW91dGgkU21va2VMaWZlX0NvbnZlcnQsZmFjdG9yID0gMS41KSkNCmFibGluZShtX1Ntb2tlTGlmZUNvbnZlcnQpDQpgYGANCmBgYHtyfQ0KY29yKHlvdXRoJFNsZWVwTnVtZXJpYyx5b3V0aCRTbW9rZUxpZmVfQ29udmVydCkNCmBgYA0KYGBge3J9DQpzdW1tYXJ5KG1fU21va2VMaWZlQ29udmVydCkNCmBgYA0KYGBge3J9DQoNCmBgYA0KIyMjIFN0ZXAgNg0KRmluYWwgUHJvamVjdDogIA0KUmV2aWV3IGVzdGltYXRlZCBwcm9wb3J0aW9uIG9mIGRhaWx5IHNtb2tlcnMgb3V0IG9mIHRoZSBwb3B1bGF0aW9uIG9mIHlvdXRoIHNtb2tlcnMuDQoNCioqKkNvbW1lbnRzIGFuZCBGaW5kaW5ncyoqKg0KQSBuZXcgZGF0YWZyYW1lLCBzbW9rZXJzIHdhcyBjcmVhdGVkIHRoYXQgY29udGFpbnMgb25seSB0aGUgcm93cyBmcm9tIHRoZSB5b3V0aCBkYXRhc2V0IHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBzbW9rZXIgcmVzcG9uZGVudHMuICBUaGUgcHJvcG9ydGlvbiBvZiBkYWlseSBzbW9rZXJzIHdhcyB0aGVuIGNhbGN1bGF0ZWQuICANCg0KDQpUaGUgY2FsY3VsYXRlZCBwcm9wb3J0aW9uIG9mIGRhaWx5IHNtb2tlcnMgZnJvbSB0aGUgc21va2VyIGxpZmUgcG9vbCBvZiByZXNwb25zZXMgPSAwLjIxNjM0NjIsIHdoaWNoIGlzIGFwcHJveGltYXRlbHkgMjIlLiANCg0KDQpgYGB7cn0NCiN1czEyIDwtIHN1YnNldChhdGhlaXNtLCBuYXRpb25hbGl0eSA9PSAiVW5pdGVkIFN0YXRlcyIgJiB5ZWFyID09ICIyMDEyIikNCnNtb2tlcnMgPC0gc3Vic2V0KHlvdXRoLCBTbW9rZUxpZmUgPT0gIlllcyIpDQpgYGANCg0KDQpgYGB7cn0NCnN1bW1hcnkoc21va2VycykNCmBgYA0KDQpgYGB7cn0NCiNjYWxjdWxhdGUgcHJvcG9ydGlvbiBvZiBkYWlseSB5b3V0aCBzbW9rZXJzDQojZ2V0IG51bWJlciBvZiBkYWlseSBzbW9rZXJzDQoNCg0Kc21va2Vyc195b3V0aCA8LW5yb3coc21va2Vyc1tzbW9rZXJzJFNtb2tlRGFpbHk9PSJZZXMiLF0pDQpzbW9rZXJzX3lvdXRoDQpgYGANCmBgYHtyfQ0KI2NhbGN1bGF0ZSBwcm9wb3J0aW9uIG9mIGRhaWx5IHlvdXRoIHNtb2tlcnMgb3V0IG9mIHRoZSBudW1iZXIgb2Ygc21va2Vycw0KI2dldCBudW1iZXIgb2YgdXMgcm93cw0KDQpzbW9rZXJzX3Jvd3MgPC0gbnJvdyhzbW9rZXJzKQ0Kc21va2Vyc19yb3dzDQpgYGANCmBgYHtyfQ0KI2NhbGN1bGF0ZSBwcm9wb3J0aW9uIG9mIGRhaWx5IHNtb2tlcnMgb3V0IG9mIHRvdGFsIHlvdXRoIHNtb2tlcnMNCnNtb2tlcnNfeW91dGgvc21va2Vyc19yb3dzDQpgYGANCmBgYHtyfQ0KDQpgYGANCg0KIyMjIFN0ZXAgNw0KRmluYWwgUHJvamVjdDogIA0KVGhlIHN0YXRpc3RpYyBhYm92ZSB3YXMgbWFkZSBmcm9tIGEgc2FtcGxlIG9mIDUwMCB5b3V0aC4gT2YgaW50ZXJlc3QgaXMgaW5zaWdodCBpbnRvIHRoZSBwb3B1bGF0aW9uIHBhcmFtZXRlcnMuIFRoZSBjYWxjdWxhdGlvbiBhbnN3ZXJzIHdoYXQgcHJvcG9ydGlvbiBvZiB5b3V0aCBzbW9rZXJzIHJlcG9ydGVkIHNtb2tpbmcgZGFpbHksIGhvd2V2ZXIgdGhlIHF1ZXN0aW9uIG9mIHdoYXQgcHJvcG9ydGlvbiBvZiB5b3V0aCB3aG8gc21va2UgZG8gc28gZGFpbHkgaXMgYW5zd2VyZWQgd2l0aCBhbiBlc3RpbWF0ZSBvZiB0aGUgcGFyYW1ldGVyLiBGb3IgdGhpcyB1bmRlcnN0YW5kaW5nLCBhbiBpbmZlcmVuY2Ugb24gcHJvcG9ydGlvbnMgaXMgbmVlZGVkLg0KDQoqKipDb21tZW50cyBhbmQgRmluZGluZ3MqKioNClRoZSBpbmZlcmVudGlhbCB0b29scyBmb3IgZXN0aW1hdGluZyBwb3B1bGF0aW9uIHByb3BvcnRpb24gaW5jbHVkZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhbmQgdGhlIGh5cG90aGVzaXMgdGVzdC4gQ29uZGl0aW9ucyBjYW4gYmUgY2hlY2tlZCBmb3IgaW5mZXJlbmNlIGJ5IG9idGFpbmluZyBzYW1wbGUgc2l6ZXMgdG8gY2hlY2sgdGhvc2UgY29uZGl0aW9ucy4gIEdyb3VwIHNpemUgaXMgY29tcHV0ZWQgd2l0aCB0aGUgImJ5IiBjb21tYW5kIGFzIGZvbGxvd3M6ICAgYnkoeW91dGgkU21va2VMaWZlLCB5b3V0aCRTbW9rZURhaWx5LCBsZW5ndGgpDQoNCkJlbG93IGFyZSB0aGUgY29uZGl0aW9ucyBmb3IgaW5mZXJlbmNlIHRvIGNvbnN0cnVjdCBhIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgcHJvcG9ydGlvbiBvZiBkYWlseSB5b3V0aCBzbW9rZXJzIGluIHRoZSBVbml0ZWQgU3RhdGVzOg0KDQoxLiAgUmFuZG9tbHkgcGlja2VkIC0gDQpJZiB0aGUgcmFuZG9tIChwaWNrZWQgcmFkb21seSBhY3Jvc3MgdGhlIFVTKSBzYW1wbGUgc2l6ZSBpcyBsZXNzIHRoYW4gMTAlIG9mIHRoZSBwb3B1bGF0aW9uIG9mIGRhaWx5IHlvdXRoIHNtb2tlcnMsIHRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IC0gYW5kIHRoaXMgY29uZGl0aW9uIG5lY2Vzc2FyeSBmb3IgaW5mZXJlbmNlIGlzIHNhdGlzZmllZCBhcyBvYnNlcnZhdGlvbnMgbXVzdCBiZSBpbmRlcGVuZGVudC4gIEluIHRoZSBzbW9rZXJzIGRhdGEgc2V0LCB0aGVyZSBhcmUgMjA4IG9ic2VydmF0aW9ucy4gIFRoaXMgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBpcyBzaWduaWZpY2FudGx5IGJlbG93IDEwJSBvZiB0aGUgVVMgcG9wdWxhdGlvbiwgc28gdGhlIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQuDQoNCg0KDQoyLiAgIEluIHRoZSBwb3B1bGF0aW9uIG9mIHlvdXRoIHNtb2tlcnMsIHRoZSBzdWNjZXNzL2ZhaWwgY29uZGl0aW9uIGlzIHNhdGlzZmllZDogDQpDYWxjIDEgLSBQb3B1bGF0aW9uIG9mIDIwOCAqIDAuMjE2MzQ2MiA9IDQ1DQpDYWxjIDIgLSBQb3B1bGF0aW9uIG9mIDIwOCAqIDAuODA3NjkyMyA9IDE2OCANCkJvdGggY2FsY3VsYXRpb25zIGFyZSBncmVhdGVyIHRoYW4gMTAuICBUaGUgc3VjY2Vzcy9mYWlsIGNvbmRpdGlvbiBpcyBtZXQgaWYgdGhlcmUgYXJlIGF0IGxlYXN0IDEwIGV4cGVjdGVkIHN1Y2Nlc3NlcyBhbmQgMTAgZXhwZWN0ZWQgZmFpbHVyZXMgaW4gdGhlIHNhbXBsZS4gDQoNCg0KMy4gIEV4cGVjdGVkIG51bWJlciBvZiBzdWNjZXNzZXMgaXMgYXQgbGVhc3QgMTA6IG5wIOKJpSAxMA0KRXhwZWN0ZWQgbnVtYmVyIG9mIGZhaWx1cmVzIGlzIGF0IGxlYXN0IDEwOiBuKDEtcCkg4omlIDEwDQp3aGVyZSBuIGlzIHRoZSBzYW1wbGUgc2l6ZSAmIHAgaXMgdGhlIHByb2JhYmlsaXR5IG9mIHN1Y2Nlc3Mgb24gYSBnaXZlbiB0cmlhbC4NCg0KDQpBbGwgY29uZGl0aW9ucyBmb3IgaW5mZXJlbmNlIGFyZSBtZXQuICBTaW5jZSB0aGUgY29uZGl0aW9ucyBmb3IgaW5mZXJlbmNlIGFyZSByZWFzb25hYmxlLCB0aGUgc3RhbmRhcmQgZXJyb3Igd2FzIGNhbGN1bGF0ZWQgYW5kIHRoZSBpbnRlcnZhbCB1c2luZyB0aGUgaW5mZXJlbmNlIGZ1bmN0aW9uIHdhcyBjb25zdHJ1Y3RlZC4NCg0KU2luY2UgdGhlIGdvYWwgaXMgdG8gY29uc3RydWN0IGFuIGludGVydmFsIGVzdGltYXRlIGZvciBhIHByb3BvcnRpb24sIGl04oCZcyBuZWNlc3NhcnkgdG8gc3BlY2lmeSB3aGF0IGNvbnN0aXR1dGVzIGEg4oCcc3VjY2Vzc+KAnSwgd2hpY2ggaGVyZSBpcyBhIHJlc3BvbnNlIG9mICJZZXMiIGZvciBzbW9rZXMgZGFpbHkuDQoNClRoZSBlcnJvciBtYXJnaW4gZm9yIHN1cnZleXMgb2YgdGhpcyBraW5kIGlzIMKxIDE0LTI1JSBhdCA5NSUgY29uZmlkZW5jZS4NCg0KU3RhbmRhcmQgZXJyb3IgPSAwLjAyNzkgDQo5NSAlIENvbmZpZGVuY2UgaW50ZXJ2YWwgPSAoIDAuMTQyMyAsIDAuMjUxOCApDQoNCg0KDQpgYGB7cn0NCmJ5KHlvdXRoJFNtb2tlTGlmZSwgeW91dGgkU21va2VEYWlseSwgbGVuZ3RoKQ0KYGBgDQpgYGB7cn0NCg0KDQojY2FsY3VsYXRlIHByb3BvcnRpb24gb2Ygbm9uLWRhaWx5IHNtb2tlcnMNCiNnZXQgbnVtYmVyIG9mIHlvdXRoIG5vbi1kYWlseSBzbW9rZXJzDQpub25fZGFpbHlfc21va2Vyc195b3V0aCA8LW5yb3coc21va2Vyc1tzbW9rZXJzJFNtb2tlRGFpbHkgPT0gIk5vIixdKQ0Kbm9uX2RhaWx5X3Ntb2tlcnNfeW91dGgNCg0KYGBgDQpgYGB7cn0NCiNjYWxjdWxhdGUgcHJvcG9ydGlvbiBvZiBub24tZGFpbHktc21va2VyIHJlc3BvbnNlcw0Kbm9uX2RhaWx5X3Ntb2tlcnNfeW91dGgvc21va2Vyc19yb3dzDQpgYGANCmBgYHtyfQ0KI1N1Y2Nlc3MvZmFpbCBjb25kaXRpb24gc2F0aXNmaWVkOiAgSXMgdGhlIGNhbGN1bGF0aW9uIGdyZWF0ZXIgdGhhbiAxMD8NCg0KI3VzX3Jvd3MgKih1c19hdGhlaXN0L3VzX3Jvd3MpDQoNCnNtb2tlcnNfcm93cyooc21va2Vyc195b3V0aC9zbW9rZXJzX3Jvd3MpDQpgYGANCmBgYHtyfQ0KI1N1Y2Nlc3MvZmFpbCBjb25kaXRpb24gc2F0aXNmaWVkOiAgSXMgdGhlIGNhbGN1bGF0aW9uIGdyZWF0ZXIgdGhhbiAxMD8NCg0KI3VzX3Jvd3MgKih1c19ub25fYXRoZWlzdC91c19yb3dzKQ0KDQpzbW9rZXJzX3Jvd3MqKG5vbl9kYWlseV9zbW9rZXJzX3lvdXRoL3Ntb2tlcnNfcm93cykNCg0KDQpgYGANCmBgYHtyfQ0KI0lmIHRoZSBjb25kaXRpb25zIGZvciBpbmZlcmVuY2UgYXJlIHJlYXNvbmFibGUsIGNhbGN1bGF0ZSB0aGUgc3RhbmRhcmQgZXJyb3IgYW5kIGNvbnN0cnVjdCB0aGUgaW50ZXJ2YWwgdXNpbmcgdGhlIGluZmVyZW5jZSBmdW5jdGlvbiANCg0KDQojaW5mZXJlbmNlKHNtb2tlcnMkU21va2VEYWlseSwgZXN0ID0gInByb3BvcnRpb24iLCB0eXBlID0gImNpIiwgbWV0aG9kID0gInRoZW9yZXRpY2FsIiwgc3VjY2VzcyA9ICJZZXMiKQ0KYGBgDQpgYGB7cn0NCg0KYGBgDQoNCiMjIyBTdGVwIDgNCkZpbmFsIFByb2plY3Q6IA0KU2luY2UgZ2F0aGVyaW5nIGluZm9ybWF0aW9uIG9uIGFuIGVudGlyZSBwb3B1bGF0aW9uIG9mIHlvdXRoIHdvdWxkIGJlIHZlcnkgY29zdGx5LCB0aW1lIGNvbnN1bWluZywgYW5kIGxpa2VseSBpbXBvc3NpYmxlLCBhIHNhbXBsZSBvZiB0aGUgcG9wdWxhdGlvbiBpcyBoZWxwZnVsIGZvciB1bmRlcnN0YW5kaW5nIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBwb3B1bGF0aW9uLiAgDQoNCg0KKioqQ29tbWVudHMgYW5kIEZpbmRpbmdzKioqDQpUbyBlc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbiBvZiB5b3V0aCBzbW9rZXJzIHdobyBzbW9rZSBkYWlseSwgdGhlIHNhbXBsZV9uIGNvbW1hbmQgaXMgdXNlZCB0byBzdXJ2ZXkgdGhlIHBvcHVsYXRpb24uICBBIGJhciBwbG90IGlzIHVzZWQgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2Ygc21va2luZyByZXNwb25zZXMsIGFuZCBzdW1tYXJ5IHN0YXRpc3RpY3MgYXNzaXN0IGluIGNvbmZpcm1pbmcgdGhlIHBvcHVsYXRpb24gcHJvcGVydGllcyBhcmUgaW4gYWxpZ25tZW50IHdpdGggdGhlIHNhbXBsZS4NCg0KDQpUaGUgc2FtcGxlX24gY29tbWFuZCBjb2xsZWN0cyBhIHJhbmRvbSBzYW1wbGUgc2l6ZSBvZiAxMDAgZnJvbSB0aGUgc21va2VycyBkYXRhc2V0IGFuZCBhc3NpZ25zIHRoZSByZXN1bHQgdG8geW91dGhTYW1wMS4gIFRoaXMgaXMgc2ltaWxhciB0byByYW5kb21seSBkcmF3aW5nIGZyb20gcmVzcG9uc2VzIGZyb20gdGhlIGVudGlyZSBwb3B1bGF0aW9uLiAgSXQgaXMgZWFzaWVyIHRvIHdvcmsgd2l0aCAxMDAgcmVzcG9uc2VzIHRoYW4gd2l0aCBhbGwgb2YgdGhvc2UgaW4gdGhlIHBvcHVsYXRpb24uIA0KDQoNCkJ5IHVzaW5nIGEgbGFyZ2VyIG51bWJlciBvZiBzYW1wbGVzIHRlc3RlZCwgYSBtb3JlIGFjY3VyYXRlIGVzdGltYXRlIG9mIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gaXMgZ2VuZXJhdGVkIChoZW5jZSB0aGUgYmFzaXMgb2YgMTAwIHZzLiBhIHNtYWxsZXIgbnVtYmVyKS4gIE9uZSBodW5kcmVkIHJlc3BvbnNlcyBmcm9tIHRoZSBzbW9rZXIgc3Vic2V0IG9mIHlvdXRoIGlzIGVhc2llciB0byB3b3JrIHdpdGggdGhhbiB0aGUgZW50aXJlIHBvcHVsYXRpb24uICANCldoZW4gdXNpbmcgdGhlIHBvcHVsYXRpb24sIDc4JSBvZiB5b3V0aCBzbW9rZXJzIGRvIG5vdCBzbW9rZSBkYWlseSB3aGlsZSAxOSUgZG8gKDIlIGRpZCBub3QgcmVzcG9uZCB0byB0aGUgZGFpbHkgcXVlc3Rpb24pLiAgV2hlbiB1c2luZyB0aGUgcmFuZG9tIHNhbXBsZSBvZiAxMDAsIDc4JSBvZiB5b3V0aCBzbW9rZXJzIGRvIG5vdCBzbW9rZSBkYWlseSB3aGlsZSAyMSUgZG8gKDElIGRpZCBub3QgcmVzcG9uZCB0byB0aGUgZGFpbHkgcXVlc3Rpb24pLiAgIA0KDQoNCmBgYHtyfQ0KDQpnZ3Bsb3Qoc21va2VycywgYWVzKHggPSBTbW9rZURhaWx5KSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIFlvdXRoIERhaWx5IFNtb2tlcnMiDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQoNCmBgYA0KYGBge3J9DQpzbW9rZXJzICU+JQ0KICBjb3VudChTbW9rZURhaWx5KSAlPiUNCiAgbXV0YXRlKHAgPSBuIC9zdW0obikpDQpgYGANCmBgYHtyfQ0KI3Rha2Ugc2FtcGxlIG9mIHBvcHVsYXRpb24gb2YgeW91dGggc21va2Vycw0Kc2V0LnNlZWQoMSkNCnlvdXRoU2FtcDEgPC0gc21va2VycyAlPiUNCiAgc2FtcGxlX24oMTAwKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCiNWaXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIGJ5IHVzaW5nIGEgYmFyIHBsb3QuDQpzZXQuc2VlZCgxKQ0KZ2dwbG90KHlvdXRoU2FtcDEsIGFlcyh4ID0gU21va2VEYWlseSkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiU2FtcGxlIG9mIFlvdXRoIERhaWx5IFNtb2tlcnMiDQogICkgKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KYGBge3J9DQoNCiNzdW1tYXJ5IHN0YXRpc3RpY3MgZnJvbSB0aGUgc2FtcGxlDQpzZXQuc2VlZCgxKQ0KeW91dGhTYW1wMSAlPiUNCiAgY291bnQoU21va2VEYWlseSkgJT4lDQogIG11dGF0ZShzID0gbiAvc3VtKG4pKQ0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCiMjIyBTdGVwIDkNCkZpbmFsIFByb2plY3Q6IA0KDQpUbyBhY2N1cmF0ZWx5IGVzdGltYXRlIHRoZSBwb3B1bGF0aW9uIG1lYW4sIGl0J3MgdXNlZnVsIHRvIGdldCBhIHNlbnNlIG9mIGhvdyBtdWNoIHZhcmlhYmlsaXR5IHRvIGV4cGVjdC4gIFRoZSBkaXN0cmlidXRpb24gb2Ygc2FtcGxlIHByb3BvcnRpb25zIChpLmUuIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcHJvcG9ydGlvbikgaXMgdXNlZCB0byB1bmRlcnN0YW5kIHRoZSB2YXJpYWJpbGl0eS4NCg0KKioqQ29tbWVudHMgYW5kIEZpbmRpbmdzKioqDQpUaGVyZSBhcmUgMTUsMDAwIGVsZW1lbnRzIGluIHNhbXBsZV95b3V0aDEwMC4gIEFyb3VuZCA4JSAoMSwyMDAgb2YgdGhlIDE1LDAwMCBlbGVtZW50cyBpbiBzYW1wbGVfeW91dGgxMDApIHNtb2tlIGRhaWx5LiAgVGhlIG1lYW4gYXBwZWFycyB0byBiZSBsZXNzIHRoYW4gdGhlIG9yaWdpbmFsIGRhdGFzZXQgKGFwcHJveGltYXRlbHkgMjAlKSBhbmQgbW9yZSBjb25jZW50cmF0ZWQgdGhhbiB0aGUgZ3JhcGggYWJvdmUuIFNpbmNlIHRoZSBtZWFuIGlzIGEgYmV0dGVyIGVzdGltYXRlIHRoZSBsYXJnZXIgdGhlIHNhbXBsZSBzaXplLCBhIHNhbXBsZSBzaXplIG9mIDEwMCB3YXMgdXNlZCBpbnN0ZWFkIG9mIGEgbG93ZXIgc2FtcGxlIHNpemUuICBJbiBvcmRlciB0byBtYWtlIGVzdGltYXRlcyB0aGF0IGFyZSBjbG9zZSB0byB0aGUgdHJ1ZSB2YWx1ZSwgYSBzYW1wbGluZyBkaXN0cmlidXRpb24gd2l0aCBhIHNtYWxsIHNwcmVhZCBpcyBiZXN0LiAgVGhlIGxhcmdlciBzYW1wbGUgc2l6ZSBoYXMgYSBzbWFsbGVyIHNwcmVhZCBhbmQgaXMgcHJlZmVyYWJsZSBmb3IgYSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQoNCg0KYGBge3J9DQojdGFrZSAxNSwwMDAgZGlmZmVyZW50IHNhbXBsZXMgb2Ygc2l6ZSAxMDAgZnJvbSB0aGUgcG9wdWxhdGlvbg0KI3JlcF9zYW1wbGVfbiBmdW5jdGlvbiBpcyBmb3IgcmVwZXRpdGlvbi4gUmF0aGVyIHRoYW4gdGFraW5nIGEgc2luZ2xlIHNhbXBsZSBvZiBzaXplIG4gKDEwMCkgZnJvbSB0aGUgcG9wdWxhdGlvbiBvZiBhbGwgeW91dGggZGFpbHkgc21va2VycyBpbiB0aGUgcG9wdWxhdGlvbiwgcmVwZWF0IHRoaXMgc2FtcGxpbmcgcHJvY2VkdXJlIHJlcCB0aW1lcyBpbiBvcmRlciB0byBidWlsZCBhIGRpc3RyaWJ1dGlvbiBvZiBhIHNlcmllcyBvZiBzYW1wbGUgc3RhdGlzdGljcywgd2hpY2ggaXMgY2FsbGVkIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQojY2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbnNlcyBpbiBlYWNoIHNhbXBsZQ0KI2ZpbHRlciBmb3Igb25seSB0aGUgU21va2VzIERhaWx5ID09ICJubyIgcmVzcG9uc2VzDQojc3RvcmUgZWFjaCByZXN1bHQgaW4gYSB2ZWN0b3IgY2FsbGVkIHNhbXBsZV95b3V0aDEwMA0KI3JlcGxhY2UgPSBUUlVFIHNpbmNlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYXJlIGNvbnN0cnVjdGVkIGJ5IHNhbXBsaW5nIHdpdGggcmVwbGFjZW1lbnQuDQoNCg0KDQpzYW1wbGVfeW91dGgxMDAgPC0geW91dGggJT4lDQogICAgICAgICAgICAgICAgICAgICByZXBfc2FtcGxlX24oc2l6ZSA9IDEwMCwgcmVwcyA9IDE1MDAwLCByZXBsYWNlID0gVFJVRSkgJT4lDQogICAgICAgICAgICAgICAgICAgICBjb3VudChTbW9rZURhaWx5KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU21va2VEYWlseSA9PSAiWWVzIikNCmBgYA0KDQoNCmBgYHtyfQ0KI1Zpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBwcm9wb3J0aW9ucyB3aXRoIGEgaGlzdG9ncmFtLg0KDQoNCmdncGxvdChkYXRhID0gc2FtcGxlX3lvdXRoMTAwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDIpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0IChTbW9rZXMgRGFpbHkpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTAwLCBOdW1iZXIgb2Ygc2FtcGxlcyA9IDE1MDAwIikNCg0KDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMjAwKQ0KZ2dwbG90KHNhbXBsZV95b3V0aDEwMCwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAgIFNtb2tlcyBEYWlseSIsIHkgPSAiQ291bnQiLA0KICAgIHRpdGxlID0gIlNhbXBsZSBfeW91dGgxMDA6ICBTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgcF9oYXQiDQogICkgKw0KICBjb29yZF9mbGlwKCkgI2ZvciBmdW4sIGZsaXBwaW5nIHRoZSBjb29yZGluYXRlIDopDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQpgYGANCg0KKioqUHJvYmxlbSoqKg0KQWZ0ZXIgcnVubmluZyBtb3N0IG9mIHRoZSB0ZXN0cywgaXQgc2VlbXMgdGhpcyBkYXRhIHNldCBpcyBxdWl0ZSBsaW1pdGVkLCBlc3BlY2lhbGx5IHdpdGggdGhlIG51bWJlciBvZiB2YXJpYWJsZXMuICBJIHdvdWxkIGhhdmUgbGlrZWQgdG8gaGF2ZSBoYWQgbW9yZSB2YXJpYWJsZXMgc28gSSBjb3VsZCB0YWtlIGFkZGl0aW9uYWwgc3Vic2V0cyBhbmQgcHJvY2Vzc2VkIGFkZGl0aW9uYWwgdGVzdHMuICBJdCBzZWVtcyB0aGVyZSBhcmUgd2Vha25lc3NlcyBpbiB0aGlzIG9ic2VydmF0aW9uYWwgc3R1ZHkuICBJIHdvdWxkIGJlIGludGVyZXN0ZWQgdG8gdW5kZXJzdGFuZCBpZiBnZW5kZXIgcGxheWVkIGEgcm9sZSBpbiB0aGUgb2JzZXJ2YXRpb25hbCBzdHVkeS4gIEl0IHNlZW1zIHRoZSByZXNwb25zZSBzdWNjZXNzZXMgYW5kIGZhaWx1cmVzIGNvdWxkIGJlIGJldHRlciB1bmRlcnN0b29kIGJ5IGZ1cnRoZXIgc2VwYXJhdGluZyB0aGUgZ3JvdXBzIGludG8gbWFsZS9mZW1hbGUuICANCg==