##1.0 Installation of packages.

#install.packages(c("readxl", "dplyr", "ggplot2"))
#install.packages("car")
library(readxl)
library(dplyr)
library(ggplot2)
library("nortest")

##2.0 Setting the working directory and importing the data

setwd("C:/Users/emerald/1Main assignment/R scripts/")
#setwd ("D:/1Main assignment/R scripts")
data <- read_excel("3147534SportsPeople Data.xlsx")

3.0 Inspecting the dat #3.1 Displaying the head

head(data)

#3.2 Structure of the data

str(data)
tibble [178 × 3] (S3: tbl_df/tbl/data.frame)
 $ Sex: chr [1:178] "female" "male" "male" "female" ...
 $ LBM: num [1:178] 56.5 75 76.6 49.4 48.8 ...
 $ BMI: num [1:178] 20.8 21.2 24.5 19.8 20.7 ...

#3.3 Summary of the data

summary(data)
     Sex                 LBM             BMI       
 Length:178         Min.   :39.22   Min.   :16.88  
 Class :character   1st Qu.:52.30   1st Qu.:20.15  
 Mode  :character   Median :58.56   Median :21.36  
                    Mean   :59.98   Mean   :21.57  
                    3rd Qu.:66.77   3rd Qu.:22.64  
                    Max.   :91.16   Max.   :26.06  

#3.4 Check for missing values

any(is.na(data))
[1] FALSE

#3.5 Check for null values

any(is.null(data))
[1] FALSE

#3.6 Check for outliers

boxplot(data$`LBM`, data$`BMI`)

outliers <- boxplot(data[, c("LBM", "BMI")], plot = FALSE)$out
print(outliers)
[1] 91.16

#3.7 Scatter plot of BMI vs LBM

with(data, plot(BMI,LBM,
 main="BMI VS LBM",
 xlab="BMI",
 ylab="LBM"))

##3.6 Checking the distribution of the data (checking the nature of symmetry)

#3.61 Histogram of Lean Body Mass (LBM)”

ggplot(data, aes(x = `LBM`)) +
 geom_histogram(binwidth = 5, fill = "blue", color = "black", alpha = 0.7) +
 labs(title = "Histogram of Lean Body Mass (LBM)")

#3.62 Histogram of Body Mass Index (BMI)

ggplot(data, aes(x = `BMI`)) +
 geom_histogram(binwidth = 1, fill = "green", color = "black", alpha = 0.7) +
 labs(title = "Histogram of Body Mass Index (BMI)")

cor(data[, c("LBM", "BMI")])
          LBM       BMI
LBM 1.0000000 0.5714248
BMI 0.5714248 1.0000000
males_count <- sum(data$Sex == "male")
print(males_count)
[1] 97
males_count <- sum(data$Sex == "female")
print(males_count)
[1] 81

#4.0 Checking the normality of the distribution according to the sexes AndersonDarling’s Test

ad.test(data$LBM[data$Sex == "male"])

    Anderson-Darling normality test

data:  data$LBM[data$Sex == "male"]
A = 0.48534, p-value = 0.2218
ad.test(data$LBM[data$Sex == "female"])

    Anderson-Darling normality test

data:  data$LBM[data$Sex == "female"]
A = 0.71069, p-value = 0.06123

#5.0 Checking the nature of the variance of the groups using Levene’s Test

levene_test_result <- levenetTest(LBM ~ Sex, data = data)
Error in levenetTest(LBM ~ Sex, data = data) : 
  could not find function "levenetTest"

The Levene’s test p value of 1.131e-05, which is way below the 0.05 (or 5%) significance level, indicated that the male and female groups have unequal variance. Due to this difference, the Welch-two sample t-test was used instead.

#6.0 Welch’s t-test to determine if the null hypothesis should be accepted or rejected.

t_test_result <- t.test(LBM ~ Sex, data = data, var.equal = FALSE)
t_test_result

    Welch Two Sample t-test

data:  LBM by Sex
t = -10.508, df = 159.84, p-value < 2.2e-16
alternative hypothesis: true difference in means between group female and group male is not equal to 0
95 percent confidence interval:
 -14.447940  -9.876429
sample estimates:
mean in group female   mean in group male 
            53.35644             65.51863 
p_value <- t_test_result$p.value
if (p_value < 0.05) {
#Print the result on different lines (using the \n )
 cat("There is a statistically significant difference in mean LBM between males and 
females.\n")
} else {
 cat("There is no statistically significant difference in mean LBM between males and 
females.\n")
}
There is a statistically significant difference in mean LBM between males and 
females.

The Welch Two Sample t test p value of 2.2e-16 which is way below 0.05 (or 5%) shows that there is enough evidence to reject the null hypothesis that true difference in means between group female and group male is equal to 0. In other words, there is a difference between mean LBM between in the male and female groups.

#7.0 Calculating the correlation coefficient based on gender

# Calculate correlation coefficient for males
cor_male <- cor(data[data$Sex == "male", c("LBM", "BMI")])
# Calculate correlation coefficient for females
cor_female <- cor(data[data$Sex == "female", c("LBM", "BMI")])
# Print correlation coefficients
cat("Correlation coefficient for males:", cor_male, "\n")
Correlation coefficient for males: 1 0.7829081 0.7829081 1 
cat("Correlation coefficient for females:", cor_female, "\n")
Correlation coefficient for females: 1 0.6703704 0.6703704 1 

The correlation coefficient for males is 0.7829081; for females, it is 0.6703704. This indicates a strong linear relationship between BMI and LBM in both males (to a greater degree) and females. This is not to say that one causes the other; correlation is not the same as causation. There could be a component common to both BMI and LBM that causes a rise in both

#8.0 Creating the liner regression model

# create a new data frame containing only information on males.
male_data <- data[data$Sex == "male",]
#Build the model for the male rows (LBM to be predicted by BMI)
model = lm(LBM~BMI, data = male_data)
#show summary of model
summary(model)

Call:
lm(formula = LBM ~ BMI, data = male_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-13.9069  -4.2213  -0.6453   3.7428  14.1990 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -10.9376     6.2629  -1.746    0.084 .  
BMI           3.5474     0.2892  12.266   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.981 on 95 degrees of freedom
Multiple R-squared:  0.6129,    Adjusted R-squared:  0.6089 
F-statistic: 150.4 on 1 and 95 DF,  p-value: < 2.2e-16

Estimated intercept is -10.9376. This is the predicted value of the response variable (LBM) when the predictor variable (BMI) is 0. However, this interpretation does not have much value as BMI cannot take 0 as a value.

Coefficient estimate for BMI is 3.5474. This is the change in LBM for one unit increase in BMI, in other words, this represents the value LBM when the value of BMI is 1. The p-value is < 2 e-16 (which is quite less than 0.05), this indicates that BMI is a significant predictor of LBM in this model.

Residuals: This helps to access a model’s fit. The fact that the median (-0.6453) is close to zero suggests that, on average, the model’s predictions are reasonably accurate. However, the spread of residuals indicates that there is variability in the accuracy of predictions across different observations.

R -squared: The shows the proportion in variability of LBM (response variable) that is predicted by the BMI. The output of the R code shows that 61.29% of the variability in LBM is explained by BMI (predictor variable).

The significance codes (***) suggest a high statistical significance.

F-statistic: This tests the overall significance of the model. In this case, the F-statistic is 150.4 with a very low p-value (< 2.2e-16), indicating that the overall model is statistically significant.

#9.0 Checking the assumptions of the model

# 9.1Q-Q plot of residuals (checking the normality of residuals)
qqnorm(residuals(model))
qqline(residuals(model), col = 2)

ad.test(residuals(model))

    Anderson-Darling normality test

data:  residuals(model)
A = 0.27025, p-value = 0.6697
#checking for the other assumptions (: Linearity, Independence of Residuals, and Homoscedasticity").
plot(model)

The points on the Q-Q plot fell along a straight line. This suggests that the distribution of residuals is approximately normal. In other words, this confirms the assumption that the residuals are normally distributed.

The random scattering on the “Residual vs Fitted”, “Scale-Location”, “Residual vs Leverage” plots confirm the following assumptions: Linearity, Independence of Residuals, and “Homoscedasticity”. (In addition to the linear relationship in the Q-Q Residual plot which confirms the assumption that the residuals are normally distributed.)

#10.0 Hypotheses Testing

male_data <- data[data$Sex == "male",]
model = lm(LBM~BMI, data = male_data)
summary(model)

Call:
lm(formula = LBM ~ BMI, data = male_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-13.9069  -4.2213  -0.6453   3.7428  14.1990 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -10.9376     6.2629  -1.746    0.084 .  
BMI           3.5474     0.2892  12.266   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.981 on 95 degrees of freedom
Multiple R-squared:  0.6129,    Adjusted R-squared:  0.6089 
F-statistic: 150.4 on 1 and 95 DF,  p-value: < 2.2e-16
par(mfrow = c(1,2))
#plot the regression line
plot(male_data$BMI,male_data$LBM,main="Regression line",
 xlab="LBM",
 ylab="BMI")
abline(model,col="blue")
# plot the fitted vs actual
plot(male_data$LBM,model$fitted.values,main="Actual vs Fitted",
 xlab="Actual LBM",
 ylab="Fitted LMB")
abline(a=0,b=1)

Interpretation: • The p-value is less than 0.05 (or 5%). This provides enough evidence to reject the null hypothesis, which is, there is no linear relationship between LBM and BMI. Test Conclusion: There is a linear relationship between LBM and BMI.

#11.0 Assessing the predictive performance of the model

# Assign to a different name to the model.
lm_model <- lm(LBM ~ BMI, data = male_data)
# Prediction and Confidence Intervals
new_data <- data.frame(BMI = seq(min(male_data$BMI), max(male_data$BMI)))
preds <- predict(lm_model, new_data, interval = "prediction")
confs <- predict(lm_model, new_data, interval = "confidence")
# Plotting Predictions and Intervals
plot(male_data$BMI, male_data$LBM, col = "blue", main = "Scatter Plot with Fitted 
Regression Line and Intervals")
abline(lm_model, col = "red") 
# and plot the predicted(preds) lower and upper range with dashed line (lty=2)
lines(new_data$BMI, preds[, "lwr"], col = "green", lty = 2)
lines(new_data$BMI, preds[, "upr"], col = "green", lty = 2)
# and also plot the confidence(confs) lower and upper range 
lines(new_data$BMI, confs[, "lwr"], col = "orange")
lines(new_data$BMI, confs[, "upr"], col = "orange")

# Residual Analysis and Model Summary
residuals <- residuals(lm_model)
plot(male_data$BMI, residuals, col = "purple", main = "Residual Plot")
abline(h = 0, col = "red", lty = 2)

summary(lm_model)

Call:
lm(formula = LBM ~ BMI, data = male_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-13.9069  -4.2213  -0.6453   3.7428  14.1990 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -10.9376     6.2629  -1.746    0.084 .  
BMI           3.5474     0.2892  12.266   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.981 on 95 degrees of freedom
Multiple R-squared:  0.6129,    Adjusted R-squared:  0.6089 
F-statistic: 150.4 on 1 and 95 DF,  p-value: < 2.2e-16

The scatter plot points (blue tiny circles) show the linear relationship between LBM and BMI. • Most of the observed points (blue tiny circles) fall within the interval lines (green lines), this is a positive indication of the model’s reliability. • The narrow confidence intervals (orange lines) indicate that the model operates with a lower uncertainty, and this is good for predictive purposes. • The positive correlation in the graph shows implies that as LBM increases, BMI increases. This in no way implies direct causation, though there is such a possibility.

LS0tDQp0aXRsZTogIk1BVFBNREEgUFJPSkVDVCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjMS4wIEluc3RhbGxhdGlvbiBvZiBwYWNrYWdlcy4NCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoYygicmVhZHhsIiwgImRwbHlyIiwgImdncGxvdDIiKSkNCiNpbnN0YWxsLnBhY2thZ2VzKCJjYXIiKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSgibm9ydGVzdCIpDQpgYGANCiMjMi4wIFNldHRpbmcgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IGFuZCBpbXBvcnRpbmcgdGhlIGRhdGENCg0KYGBge3J9DQpzZXR3ZCgiQzovVXNlcnMvZW1lcmFsZC8xTWFpbiBhc3NpZ25tZW50L1Igc2NyaXB0cy8iKQ0KI3NldHdkICgiRDovMU1haW4gYXNzaWdubWVudC9SIHNjcmlwdHMiKQ0KZGF0YSA8LSByZWFkX2V4Y2VsKCIzMTQ3NTM0U3BvcnRzUGVvcGxlIERhdGEueGxzeCIpDQpgYGANCg0KMy4wIEluc3BlY3RpbmcgdGhlIGRhdA0KIzMuMSBEaXNwbGF5aW5nIHRoZSBoZWFkDQpgYGB7cn0NCmhlYWQoZGF0YSkNCmBgYA0KIzMuMiBTdHJ1Y3R1cmUgb2YgdGhlIGRhdGENCmBgYHtyfQ0Kc3RyKGRhdGEpDQpgYGANCiMzLjMgU3VtbWFyeSBvZiB0aGUgZGF0YQ0KYGBge3J9DQpzdW1tYXJ5KGRhdGEpDQpgYGANCiMzLjQgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzDQpgYGB7cn0NCmFueShpcy5uYShkYXRhKSkNCmBgYA0KIzMuNSBDaGVjayBmb3IgbnVsbCB2YWx1ZXMNCmBgYHtyfQ0KYW55KGlzLm51bGwoZGF0YSkpDQpgYGANCiMzLjYgQ2hlY2sgZm9yIG91dGxpZXJzDQpgYGB7cn0NCmJveHBsb3QoZGF0YSRgTEJNYCwgZGF0YSRgQk1JYCkNCm91dGxpZXJzIDwtIGJveHBsb3QoZGF0YVssIGMoIkxCTSIsICJCTUkiKV0sIHBsb3QgPSBGQUxTRSkkb3V0DQpwcmludChvdXRsaWVycykNCmBgYA0KIzMuNyBTY2F0dGVyIHBsb3Qgb2YgQk1JIHZzIExCTQ0KYGBge3J9DQp3aXRoKGRhdGEsIHBsb3QoQk1JLExCTSwNCiBtYWluPSJCTUkgVlMgTEJNIiwNCiB4bGFiPSJCTUkiLA0KIHlsYWI9IkxCTSIpKQ0KYGBgDQojIzMuNiBDaGVja2luZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhIChjaGVja2luZyB0aGUgbmF0dXJlIG9mIHN5bW1ldHJ5KQ0KDQojMy42MSBIaXN0b2dyYW0gb2YgTGVhbiBCb2R5IE1hc3MgKExCTSkiDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGBMQk1gKSkgKw0KIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gNSwgZmlsbCA9ICJibHVlIiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKw0KIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtIG9mIExlYW4gQm9keSBNYXNzIChMQk0pIikNCmBgYA0KIzMuNjIgSGlzdG9ncmFtIG9mIEJvZHkgTWFzcyBJbmRleCAoQk1JKQ0KYGBge3J9DQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBgQk1JYCkpICsNCiBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAiZ3JlZW4iLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC43KSArDQogbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgQm9keSBNYXNzIEluZGV4IChCTUkpIikNCmBgYA0KYGBge3J9DQpjb3IoZGF0YVssIGMoIkxCTSIsICJCTUkiKV0pDQpgYGANCmBgYHtyfQ0KbWFsZXNfY291bnQgPC0gc3VtKGRhdGEkU2V4ID09ICJtYWxlIikNCnByaW50KG1hbGVzX2NvdW50KQ0KbWFsZXNfY291bnQgPC0gc3VtKGRhdGEkU2V4ID09ICJmZW1hbGUiKQ0KcHJpbnQobWFsZXNfY291bnQpDQpgYGANCiM0LjAgQ2hlY2tpbmcgdGhlIG5vcm1hbGl0eSBvZiB0aGUgZGlzdHJpYnV0aW9uIGFjY29yZGluZyB0byB0aGUgc2V4ZXMgQW5kZXJzb24CRGFybGluZ+KAmXMgVGVzdA0KYGBge3J9DQphZC50ZXN0KGRhdGEkTEJNW2RhdGEkU2V4ID09ICJtYWxlIl0pDQpgYGANCmBgYHtyfQ0KYWQudGVzdChkYXRhJExCTVtkYXRhJFNleCA9PSAiZmVtYWxlIl0pDQpgYGANCiM1LjAgQ2hlY2tpbmcgdGhlIG5hdHVyZSBvZiB0aGUgdmFyaWFuY2Ugb2YgdGhlIGdyb3VwcyB1c2luZyBMZXZlbmXigJlzIFRlc3QNCmBgYHtyfQ0KbGV2ZW5lX3Rlc3RfcmVzdWx0IDwtIGxldmVuZXRUZXN0KExCTSB+IFNleCwgZGF0YSA9IGRhdGEpDQpsZXZlbmVfdGVzdF9yZXN1bHQNCmBgYA0KVGhlIExldmVuZeKAmXMgdGVzdCBwIHZhbHVlIG9mIDEuMTMxZS0wNSwgd2hpY2ggaXMgd2F5IGJlbG93IHRoZSAwLjA1IChvciA1JSkgc2lnbmlmaWNhbmNlIGxldmVsLCBpbmRpY2F0ZWQgdGhhdCB0aGUgbWFsZSBhbmQgZmVtYWxlIGdyb3VwcyBoYXZlIHVuZXF1YWwgdmFyaWFuY2UuIER1ZSB0byB0aGlzIGRpZmZlcmVuY2UsIHRoZSBXZWxjaC10d28gc2FtcGxlIHQtdGVzdCB3YXMgdXNlZCBpbnN0ZWFkLg0KDQoNCiM2LjAgV2VsY2jigJlzIHQtdGVzdCB0byBkZXRlcm1pbmUgaWYgdGhlIG51bGwgaHlwb3RoZXNpcyBzaG91bGQgYmUgYWNjZXB0ZWQgb3IgcmVqZWN0ZWQuDQpgYGB7cn0NCnRfdGVzdF9yZXN1bHQgPC0gdC50ZXN0KExCTSB+IFNleCwgZGF0YSA9IGRhdGEsIHZhci5lcXVhbCA9IEZBTFNFKQ0KdF90ZXN0X3Jlc3VsdA0KcF92YWx1ZSA8LSB0X3Rlc3RfcmVzdWx0JHAudmFsdWUNCmlmIChwX3ZhbHVlIDwgMC4wNSkgew0KI1ByaW50IHRoZSByZXN1bHQgb24gZGlmZmVyZW50IGxpbmVzICh1c2luZyB0aGUgXG4gKQ0KIGNhdCgiVGhlcmUgaXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gbWVhbiBMQk0gYmV0d2VlbiBtYWxlcyBhbmQgDQpmZW1hbGVzLlxuIikNCn0gZWxzZSB7DQogY2F0KCJUaGVyZSBpcyBubyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gbWVhbiBMQk0gYmV0d2VlbiBtYWxlcyBhbmQgDQpmZW1hbGVzLlxuIikNCn0NCmBgYA0KDQpUaGUgV2VsY2ggVHdvIFNhbXBsZSB0IHRlc3QgcCB2YWx1ZSBvZiAyLjJlLTE2IHdoaWNoIGlzIHdheSBiZWxvdyAwLjA1IChvciA1JSkgc2hvd3MgdGhhdCB0aGVyZSBpcyBlbm91Z2ggZXZpZGVuY2UgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0cnVlIGRpZmZlcmVuY2UgaW4gbWVhbnMgYmV0d2VlbiBncm91cCBmZW1hbGUgYW5kIGdyb3VwIG1hbGUgaXMgZXF1YWwgdG8gMC4NCkluIG90aGVyIHdvcmRzLCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiBtZWFuIExCTSBiZXR3ZWVuIGluIHRoZSBtYWxlIGFuZCBmZW1hbGUgZ3JvdXBzLg0KDQojNy4wIENhbGN1bGF0aW5nIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBiYXNlZCBvbiBnZW5kZXINCmBgYHtyfQ0KIyBDYWxjdWxhdGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgZm9yIG1hbGVzDQpjb3JfbWFsZSA8LSBjb3IoZGF0YVtkYXRhJFNleCA9PSAibWFsZSIsIGMoIkxCTSIsICJCTUkiKV0pDQojIENhbGN1bGF0ZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBmb3IgZmVtYWxlcw0KY29yX2ZlbWFsZSA8LSBjb3IoZGF0YVtkYXRhJFNleCA9PSAiZmVtYWxlIiwgYygiTEJNIiwgIkJNSSIpXSkNCiMgUHJpbnQgY29ycmVsYXRpb24gY29lZmZpY2llbnRzDQpjYXQoIkNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGZvciBtYWxlczoiLCBjb3JfbWFsZSwgIlxuIikNCmNhdCgiQ29ycmVsYXRpb24gY29lZmZpY2llbnQgZm9yIGZlbWFsZXM6IiwgY29yX2ZlbWFsZSwgIlxuIikNCmBgYA0KVGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGZvciBtYWxlcyBpcyAwLjc4MjkwODE7IGZvciBmZW1hbGVzLCBpdCBpcyAwLjY3MDM3MDQuIFRoaXMgaW5kaWNhdGVzIGEgc3Ryb25nIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBCTUkgYW5kIExCTSBpbiBib3RoIG1hbGVzICh0byBhIGdyZWF0ZXIgZGVncmVlKSBhbmQgZmVtYWxlcy4NClRoaXMgaXMgbm90IHRvIHNheSB0aGF0IG9uZSBjYXVzZXMgdGhlIG90aGVyOyBjb3JyZWxhdGlvbiBpcyBub3QgdGhlIHNhbWUgYXMgY2F1c2F0aW9uLiBUaGVyZSBjb3VsZCBiZSBhIGNvbXBvbmVudCBjb21tb24gdG8gYm90aCBCTUkgYW5kIExCTSB0aGF0IGNhdXNlcyBhIHJpc2UgaW4gYm90aA0KDQoNCiM4LjAgQ3JlYXRpbmcgdGhlIGxpbmVyIHJlZ3Jlc3Npb24gbW9kZWwNCmBgYHtyfQ0KIyBjcmVhdGUgYSBuZXcgZGF0YSBmcmFtZSBjb250YWluaW5nIG9ubHkgaW5mb3JtYXRpb24gb24gbWFsZXMuDQptYWxlX2RhdGEgPC0gZGF0YVtkYXRhJFNleCA9PSAibWFsZSIsXQ0KI0J1aWxkIHRoZSBtb2RlbCBmb3IgdGhlIG1hbGUgcm93cyAoTEJNIHRvIGJlIHByZWRpY3RlZCBieSBCTUkpDQptb2RlbCA9IGxtKExCTX5CTUksIGRhdGEgPSBtYWxlX2RhdGEpDQojc2hvdyBzdW1tYXJ5IG9mIG1vZGVsDQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQpFc3RpbWF0ZWQgaW50ZXJjZXB0IGlzIC0xMC45Mzc2LiBUaGlzIGlzIHRoZSBwcmVkaWN0ZWQgdmFsdWUgb2YgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIChMQk0pIHdoZW4gdGhlIHByZWRpY3RvciB2YXJpYWJsZSAoQk1JKSBpcyAwLiBIb3dldmVyLCB0aGlzIGludGVycHJldGF0aW9uIGRvZXMgbm90IGhhdmUgbXVjaCB2YWx1ZSBhcyBCTUkgY2Fubm90IHRha2UgMCBhcyBhIHZhbHVlLg0KDQpDb2VmZmljaWVudCBlc3RpbWF0ZSBmb3IgQk1JIGlzIDMuNTQ3NC4gVGhpcyBpcyB0aGUgY2hhbmdlIGluIExCTSBmb3Igb25lIHVuaXQgDQppbmNyZWFzZSBpbiBCTUksIGluIG90aGVyIHdvcmRzLCB0aGlzIHJlcHJlc2VudHMgdGhlIHZhbHVlIExCTSB3aGVuIHRoZSB2YWx1ZSBvZiBCTUkgaXMgMS4NClRoZSBwLXZhbHVlIGlzIDwgMiBlLTE2ICh3aGljaCBpcyBxdWl0ZSBsZXNzIHRoYW4gMC4wNSksIHRoaXMgaW5kaWNhdGVzIHRoYXQgQk1JIGlzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIExCTSBpbiB0aGlzIG1vZGVsLiANCg0KUmVzaWR1YWxzOiBUaGlzIGhlbHBzIHRvIGFjY2VzcyBhIG1vZGVs4oCZcyBmaXQuIFRoZSBmYWN0IHRoYXQgdGhlIG1lZGlhbiAoLTAuNjQ1MykgaXMgDQpjbG9zZSB0byB6ZXJvIHN1Z2dlc3RzIHRoYXQsIG9uIGF2ZXJhZ2UsIHRoZSBtb2RlbOKAmXMgcHJlZGljdGlvbnMgYXJlIHJlYXNvbmFibHkgYWNjdXJhdGUuIEhvd2V2ZXIsIHRoZSBzcHJlYWQgb2YgcmVzaWR1YWxzIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIHZhcmlhYmlsaXR5IGluIHRoZSBhY2N1cmFjeSBvZiBwcmVkaWN0aW9ucyBhY3Jvc3MgZGlmZmVyZW50IG9ic2VydmF0aW9ucy4NCg0KUiAtc3F1YXJlZDogVGhlIHNob3dzIHRoZSBwcm9wb3J0aW9uIGluIHZhcmlhYmlsaXR5IG9mIExCTSAocmVzcG9uc2UgdmFyaWFibGUpIHRoYXQgaXMgcHJlZGljdGVkIGJ5IHRoZSBCTUkuIFRoZSBvdXRwdXQgb2YgdGhlIFIgY29kZSBzaG93cyB0aGF0IDYxLjI5JSBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gTEJNIGlzIGV4cGxhaW5lZCBieSBCTUkgKHByZWRpY3RvciB2YXJpYWJsZSkuDQoNClRoZSBzaWduaWZpY2FuY2UgY29kZXMgKCoqKikgc3VnZ2VzdCBhIGhpZ2ggc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlLg0KDQpGLXN0YXRpc3RpYzogVGhpcyB0ZXN0cyB0aGUgb3ZlcmFsbCBzaWduaWZpY2FuY2Ugb2YgdGhlIG1vZGVsLiBJbiB0aGlzIGNhc2UsIHRoZSBGLXN0YXRpc3RpYyBpcyAxNTAuNCB3aXRoIGEgdmVyeSBsb3cgcC12YWx1ZSAoPCAyLjJlLTE2KSwgaW5kaWNhdGluZyB0aGF0IHRoZSBvdmVyYWxsIG1vZGVsIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuDQoNCg0KIzkuMCBDaGVja2luZyB0aGUgYXNzdW1wdGlvbnMgb2YgdGhlIG1vZGVsDQpgYGB7cn0NCiMgOS4xUS1RIHBsb3Qgb2YgcmVzaWR1YWxzIChjaGVja2luZyB0aGUgbm9ybWFsaXR5IG9mIHJlc2lkdWFscykNCnFxbm9ybShyZXNpZHVhbHMobW9kZWwpKQ0KcXFsaW5lKHJlc2lkdWFscyhtb2RlbCksIGNvbCA9IDIpDQphZC50ZXN0KHJlc2lkdWFscyhtb2RlbCkpDQojY2hlY2tpbmcgZm9yIHRoZSBvdGhlciBhc3N1bXB0aW9ucyAoOiBMaW5lYXJpdHksIEluZGVwZW5kZW5jZSBvZiBSZXNpZHVhbHMsIGFuZCBIb21vc2NlZGFzdGljaXR5IikuDQpwbG90KG1vZGVsKQ0KYGBgDQpUaGUgcG9pbnRzIG9uIHRoZSBRLVEgcGxvdCBmZWxsIGFsb25nIGEgc3RyYWlnaHQgbGluZS4gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgcmVzaWR1YWxzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLiBJbiBvdGhlciB3b3JkcywgdGhpcyBjb25maXJtcyB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KDQpUaGUgcmFuZG9tIHNjYXR0ZXJpbmcgb24gdGhlIOKAnFJlc2lkdWFsIHZzIEZpdHRlZOKAnSwg4oCcU2NhbGUtTG9jYXRpb27igJ0sIOKAnFJlc2lkdWFsIHZzIExldmVyYWdl4oCdIHBsb3RzIGNvbmZpcm0gdGhlIGZvbGxvd2luZyBhc3N1bXB0aW9uczogTGluZWFyaXR5LCBJbmRlcGVuZGVuY2Ugb2YgUmVzaWR1YWxzLCBhbmQg4oCcSG9tb3NjZWRhc3RpY2l0eeKAnS4gKEluIGFkZGl0aW9uIHRvIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGluIHRoZSBRLVEgUmVzaWR1YWwgcGxvdCB3aGljaCBjb25maXJtcyB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLikNCg0KIzEwLjAgSHlwb3RoZXNlcyBUZXN0aW5nDQpgYGB7cn0NCm1hbGVfZGF0YSA8LSBkYXRhW2RhdGEkU2V4ID09ICJtYWxlIixdDQptb2RlbCA9IGxtKExCTX5CTUksIGRhdGEgPSBtYWxlX2RhdGEpDQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQpgYGB7cn0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCiNwbG90IHRoZSByZWdyZXNzaW9uIGxpbmUNCnBsb3QobWFsZV9kYXRhJEJNSSxtYWxlX2RhdGEkTEJNLG1haW49IlJlZ3Jlc3Npb24gbGluZSIsDQogeGxhYj0iTEJNIiwNCiB5bGFiPSJCTUkiKQ0KYWJsaW5lKG1vZGVsLGNvbD0iYmx1ZSIpDQojIHBsb3QgdGhlIGZpdHRlZCB2cyBhY3R1YWwNCnBsb3QobWFsZV9kYXRhJExCTSxtb2RlbCRmaXR0ZWQudmFsdWVzLG1haW49IkFjdHVhbCB2cyBGaXR0ZWQiLA0KIHhsYWI9IkFjdHVhbCBMQk0iLA0KIHlsYWI9IkZpdHRlZCBMTUIiKQ0KYWJsaW5lKGE9MCxiPTEpDQpgYGANCkludGVycHJldGF0aW9uOiANCuKAoiBUaGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gMC4wNSAob3IgNSUpLiBUaGlzIHByb3ZpZGVzIGVub3VnaCBldmlkZW5jZSB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcywgd2hpY2ggaXMsIHRoZXJlIGlzIG5vIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBMQk0gYW5kIEJNSS4NClRlc3QgQ29uY2x1c2lvbjogVGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gTEJNIGFuZCBCTUkuDQoNCiMxMS4wIEFzc2Vzc2luZyB0aGUgcHJlZGljdGl2ZSBwZXJmb3JtYW5jZSBvZiB0aGUgbW9kZWwNCmBgYHtyfQ0KIyBBc3NpZ24gdG8gYSBkaWZmZXJlbnQgbmFtZSB0byB0aGUgbW9kZWwuDQpsbV9tb2RlbCA8LSBsbShMQk0gfiBCTUksIGRhdGEgPSBtYWxlX2RhdGEpDQojIFByZWRpY3Rpb24gYW5kIENvbmZpZGVuY2UgSW50ZXJ2YWxzDQpuZXdfZGF0YSA8LSBkYXRhLmZyYW1lKEJNSSA9IHNlcShtaW4obWFsZV9kYXRhJEJNSSksIG1heChtYWxlX2RhdGEkQk1JKSkpDQpwcmVkcyA8LSBwcmVkaWN0KGxtX21vZGVsLCBuZXdfZGF0YSwgaW50ZXJ2YWwgPSAicHJlZGljdGlvbiIpDQpjb25mcyA8LSBwcmVkaWN0KGxtX21vZGVsLCBuZXdfZGF0YSwgaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIpDQojIFBsb3R0aW5nIFByZWRpY3Rpb25zIGFuZCBJbnRlcnZhbHMNCnBsb3QobWFsZV9kYXRhJEJNSSwgbWFsZV9kYXRhJExCTSwgY29sID0gImJsdWUiLCBtYWluID0gIlNjYXR0ZXIgUGxvdCB3aXRoIEZpdHRlZCANClJlZ3Jlc3Npb24gTGluZSBhbmQgSW50ZXJ2YWxzIikNCmFibGluZShsbV9tb2RlbCwgY29sID0gInJlZCIpIA0KIyBhbmQgcGxvdCB0aGUgcHJlZGljdGVkKHByZWRzKSBsb3dlciBhbmQgdXBwZXIgcmFuZ2Ugd2l0aCBkYXNoZWQgbGluZSAobHR5PTIpDQpsaW5lcyhuZXdfZGF0YSRCTUksIHByZWRzWywgImx3ciJdLCBjb2wgPSAiZ3JlZW4iLCBsdHkgPSAyKQ0KbGluZXMobmV3X2RhdGEkQk1JLCBwcmVkc1ssICJ1cHIiXSwgY29sID0gImdyZWVuIiwgbHR5ID0gMikNCiMgYW5kIGFsc28gcGxvdCB0aGUgY29uZmlkZW5jZShjb25mcykgbG93ZXIgYW5kIHVwcGVyIHJhbmdlIA0KbGluZXMobmV3X2RhdGEkQk1JLCBjb25mc1ssICJsd3IiXSwgY29sID0gIm9yYW5nZSIpDQpsaW5lcyhuZXdfZGF0YSRCTUksIGNvbmZzWywgInVwciJdLCBjb2wgPSAib3JhbmdlIikNCiMgUmVzaWR1YWwgQW5hbHlzaXMgYW5kIE1vZGVsIFN1bW1hcnkNCnJlc2lkdWFscyA8LSByZXNpZHVhbHMobG1fbW9kZWwpDQpwbG90KG1hbGVfZGF0YSRCTUksIHJlc2lkdWFscywgY29sID0gInB1cnBsZSIsIG1haW4gPSAiUmVzaWR1YWwgUGxvdCIpDQphYmxpbmUoaCA9IDAsIGNvbCA9ICJyZWQiLCBsdHkgPSAyKQ0Kc3VtbWFyeShsbV9tb2RlbCkNCmBgYA0KVGhlIHNjYXR0ZXIgcGxvdCBwb2ludHMgKGJsdWUgdGlueSBjaXJjbGVzKSBzaG93IHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gDQpMQk0gYW5kIEJNSS4NCuKAoiBNb3N0IG9mIHRoZSBvYnNlcnZlZCBwb2ludHMgKGJsdWUgdGlueSBjaXJjbGVzKSBmYWxsIHdpdGhpbiB0aGUgaW50ZXJ2YWwgbGluZXMgDQooZ3JlZW4gbGluZXMpLCB0aGlzIGlzIGEgcG9zaXRpdmUgaW5kaWNhdGlvbiBvZiB0aGUgbW9kZWzigJlzIHJlbGlhYmlsaXR5LiANCuKAoiBUaGUgbmFycm93IGNvbmZpZGVuY2UgaW50ZXJ2YWxzIChvcmFuZ2UgbGluZXMpIGluZGljYXRlIHRoYXQgdGhlIG1vZGVsIA0Kb3BlcmF0ZXMgd2l0aCBhIGxvd2VyIHVuY2VydGFpbnR5LCBhbmQgdGhpcyBpcyBnb29kIGZvciBwcmVkaWN0aXZlIHB1cnBvc2VzLg0K4oCiIFRoZSBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBpbiB0aGUgZ3JhcGggc2hvd3MgaW1wbGllcyB0aGF0IGFzIExCTSBpbmNyZWFzZXMsIA0KQk1JIGluY3JlYXNlcy4gVGhpcyBpbiBubyB3YXkgaW1wbGllcyBkaXJlY3QgY2F1c2F0aW9uLCB0aG91Z2ggdGhlcmUgaXMgc3VjaCBhIA0KcG9zc2liaWxpdHkuDQoNCg0KDQoNCg0K