Code Part 1:
#Packages
library(knitr)
library(kableExtra)
library(ggplot2)
library(dplyr)
#Loading the Data into R after Transforming in Excel
FemaleEarnings <- read.csv("C:/Users/edren/OneDrive/Desktop/Data Analysis/R Working Directory/Final Project Assignment/Datasets/DataSets/Female Earnings Transformed.csv")
#Clean up
names(FemaleEarnings) <- c("Year", "Female.Earnings")
#Adding a Number to year
FemaleEarnings <- FemaleEarnings %>%
arrange(Year) %>%
mutate(YearNum = row_number())
#Initial look at the data
head(FemaleEarnings)
tail(FemaleEarnings)
TableEarnings1 <- rbind(head(FemaleEarnings), "...", tail(FemaleEarnings))
kable(TableEarnings1, row.names = F, caption = "Table 1.1: US Census data regarding Median earnings for Total Female Workers from 1967 - 2021. The Years are numbered in order to not skew the analysis later.") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Creating the initial regression model
Reg.Model1 <- lm(Female.Earnings~YearNum, data = FemaleEarnings)
#Plotting the intial data
#linearity check 1
ggplot(FemaleEarnings, aes(x = Year, y = Female.Earnings)) +
geom_smooth(method = "lm", se = F, color = "blue") +
geom_point(color="red")+
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -4, hjust = 0.43),
axis.title.y = element_text(size = 14, vjust = 6, hjust = 0.6),
plot.title = element_text(size = 16, vjust = 6),
plot.margin = unit(c(1,1,1,1), "cm")) +
labs(title = expression(underline("Median Female Earnings in the US from 1967-2021"))) +
ylab("Median Female Earnings ($)") +
xlab("Time in Years")
#Figure 1.1: ...
#Looks linear
#Coefficient Table
Model1Table <- Reg.Model1$coefficients
kable(t(Model1Table), caption = "Table 1.2: Linear Regression Model 1. The intercept (constant) β0 and the slope (coefficient) β1, which are used with the predictor X to achieve the response variable Y.", col.names = c("β0 (Intercept)", "β1 (Slope)")) %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Checking assumptions are met
#Homoscedasticity check 1
par(mfrow = c(2,2))
plot(Reg.Model1)
par(mfrow = c(1,1))
#Figure 1.2:...
#QQ Plot tells us the normality of the residuals, a straight line indicates that the residuals are normally distributed.
#Residuals vs Fitted: Shows the residuals which is y - predicted y as a function of the fitted values.
#Residuals should bounce randomly around the 0 line and should be roughly equal around the estimated regression line.
#Residuals somewhat a pattern in this case, so we will transform the data to see if this makes a difference.
#log10 Transformation
Reg.Model2 <- lm(log10(Female.Earnings)~(YearNum), data = FemaleEarnings)
#Table For Coefficients
Model2Table <- Reg.Model2$coefficients
kable(t(Model2Table), caption = "Table 1.3: Linear Regression Model 2 with log10() transformation. The intercept (constant) β0 and the slope (coefficient) β1, which are used with the predictor X to achieve the response variable Y.", col.names = c("β0 (Intercept)", "β1 (Slope)")) %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Homoscedasticity Check 2
#Plotting Model 2
par(mfrow = c(2,2))
plot(Reg.Model2)
par(mfrow = c(1,1))
#Figure 1.3:...
#Residuals vs Fitted, After the log10() transformation there is less dispersion and residuals form a U shape pattern, showing a non linear relationship
##The QQ Residuals do not follow a straight line which shows lack normality of residuals.
#One cannot say that all the assumptions of linear regression are met as the data points are not randomly spread around the line.
#Adding another variable to our linear regression model.
#Inflation.
#Since we are looking at how income has increased over the years, inflation will be a good variable to add to our model as it directly has an effect on income.
InflationData <- read.csv("C:/Users/edren/OneDrive/Desktop/Data Analysis/R Working Directory/Final Project Assignment/Datasets/DataSets/Inflation.csv")
FemaleEarningsNew <- cbind(FemaleEarnings, InflationData$Inflation)
names(FemaleEarningsNew) <- c("Year", "Female.Earnings", "YearNum", "Inflation")
#Scale Both Year Num and Inflation in order to create a model.
YearNumScaled <- scale(FemaleEarningsNew$YearNum, center = T, scale = T)
InflationScaled <- scale(FemaleEarningsNew$Inflation, center = T, scale = T)
FemaleEarningsNew$YearScaled <- scale(FemaleEarningsNew$YearNum, center = T, scale = T)
FemaleEarningsNew$InflationScaled <- scale(FemaleEarningsNew$Inflation, center = T, scale = T)
#Linear Regression Model 3
Reg.Model3 <- lm(Female.Earnings ~ YearScaled + InflationScaled, data = FemaleEarningsNew)
Model3Table <- Reg.Model3$coefficients
kable(t(Model3Table), caption = "Table 1.4: Linear Regression Model 3 with new predictor Inflation (x2) . The intercept (constant) β0 and the slope (coefficient) β1 + β2, which are used with the predictor x1 + x2 to achieve the response variable Y.", col.names = c("β0 (Intercept)", "β1 (Slope for x1)", "β2 (Slope for x2)")) %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Plotting Model 3
par(mfrow = c(2,2))
plot(Reg.Model3)
par(mfrow = c(1,1))
#Figure 1.4:...
#Checking Multiple R Squared and Adjusted R Squared of the two models
summary(Reg.Model1)$r.squared
summary(Reg.Model1)$adj.r.squared
Model1rSquared<- cbind.data.frame(summary(Reg.Model1)$r.squared, summary(Reg.Model1)$adj.r.squared)
names(Model1rSquared) <- c("MultipleR^2", "AdjustedR^2")
##
Model3rSquared<- cbind.data.frame(summary(Reg.Model3)$r.squared, summary(Reg.Model3)$adj.r.squared)
names(Model3rSquared) <- c("MultipleR^2", "AdjustedR^2")
##
RSquaredTable <-rbind(Model1rSquared, Model3rSquared)
row.names(RSquaredTable) <- c("MultipleR^2", "AdjustedR^2")
kable(t(RSquaredTable), caption = "Table 1.5: Comparing the Multiple R Sqaured and Adjusted R Squared of Model 1 and 2 to determine whcih is best fit for our data.", col.names = c("Model 1", "Model 2", "Model 3"), table.attr = "style='width:80%;'") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Adding Inflation to our model -> Model3, we get an increase in MultipleR^2 and AdjustedR^2 squared.
#Main indicator for goodness of fit of introducing a new indicator to our model is AdjustedR^2. As it explaines how much variability is explained in the model.
#Can use anova to determine whether Inflation should be added to our model or not.
anova(Reg.Model1, Reg.Model3)
#Df = 1, more complex model has one additional parameter
#P-value 0.2 > 0.05, means we should reject Model 3 and continue with model 1
#Summary of regression model 1
summary(Reg.Model1)
#P - Value - Upper Tail test
p_value <- pt(q = 41.22, df = 53, lower.tail=FALSE)
p_value
#Significant increase in Female earnings by change in Time in Years.
#Plotting Residuals
FemaleEarnings$predicted <- predict(Reg.Model1)
FemaleEarnings$residuals <- residuals(Reg.Model1)
ggplot(FemaleEarnings, aes(x = Year, y = Female.Earnings)) +
geom_smooth(method = "lm", se = F, color = "blue") +
geom_point(aes(color = abs(residuals), size = abs(residuals))) +
scale_color_continuous(low = "blue", high = "red") +
guides(color = F, size = F) +
geom_segment(aes(xend = Year, yend = predicted), alpha = .2) +
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -4, hjust = 0.43),
axis.title.y = element_text(size = 14, vjust = 6, hjust = 0.6),
plot.title = element_text(size = 16, vjust = 6),
plot.margin = unit(c(1,1,1,1), "cm")) +
labs(title = expression(underline("Median Female Earnings ($) in the US from 1967-2021"))) +
ylab("Median Female Earnings ($)") +
xlab("Time in Years")
#Figure 1.5: Median Female Earnings plotted against time in Years, with line of best fit and Residuals plotted to the predicted values.
#We can predict median female earnings in the US using the coefficients...
#And using the Year number as X1
Model1Table <- Reg.Model1$coefficients
kable(t(Model1Table), caption = "Table 1.2: Linear Regression Model 1. The intercept (constant) β0 and the slope (coefficient) β1, which are used with the predictor X to achieve the response variable Y.", col.names = c("β0 (Intercept)", "β1 (Slope)")) %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
# Y(Predicted Median Female Earnings) = 15383.08 + 406.6405 * x1
#Yet this number does not account for inflation, unemployment, other socioeconomic and economic factors.
Code Part 2:
#Packages
library(ggplot2)
library(ggpubr)
library(knitr)
library(kableExtra)
library(Rcmdr)
library(dplyr)
#Data
MaleFemaleEarnings <- read.csv("C:/Users/edren/OneDrive/Desktop/Data Analysis/R Working Directory/Final Project Assignment/Datasets/DataSets/MFEarnings.csv")
names(MaleFemaleEarnings) <- c("Year", "Gender", "Median.Income")
#Initial Look at our data
head(MaleFemaleEarnings)
tail(MaleFemaleEarnings)
TableEarnings2 <- rbind(head(MaleFemaleEarnings), "...", tail(MaleFemaleEarnings))
kable(TableEarnings2,
caption = "Table 2.1: Initial look at how our data is laid out. Providing Income data for both Genders in the US from 1967 - 2022. The Income in this dataset accounts for inflation and is in 2022 Dollars ($).") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Summary Stats
#Summary Statistics by Gender
ByGender <-group_by(MaleFemaleEarnings, Gender) %>%
summarise(
count = n(),
median = median(Median.Income, na.rm = T),
IQR = IQR(Median.Income, na.rm = T)
)
kable(ByGender,caption = "Table 2.2: Summary Statistics for the seperate Genders in the US from 1967-2021. The count = number of years in the study, median income for each, and the interquartile range.") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#InterQuartile Range is very high for females meaning there is a high range where most of our values lie.
#Plots to check for normal distribution, for all median income data
par(mfrow=c(1,3))
{with(MaleFemaleEarnings, Hist(Median.Income, scale="percent", ylab= "Percent", main= "Histogram for Income", breaks="Sturges",col="lightgray"))
abline(v = mean(MaleFemaleEarnings$Median.Income), col = "red", lwd = 3)
abline(v = median(MaleFemaleEarnings$Median.Income), col = "yellow", lwd = 3)
legend("topright", c("Mean", "Median"), col = c("red", "yellow"), lwd = 3)}
densityPlot( ~ Median.Income, data = MaleFemaleEarnings, main = "Density Plot for Income", bw=bw.SJ, adjust=1, kernel=dnorm, method="adaptive")
with(MaleFemaleEarnings, qqPlot(Median.Income, dist="norm", main = "QQ Plot for Income", id=list(method="y", n=2, labels=rownames(MaleFemaleEarnings))))
par(mfrow=c(1,1))
#Figure 2.1 ...Positive skew in Histogram and density plot.
#Shapiro Wilk normality test
shapiro.test(MaleFemaleEarnings$Median.Income)
#Normality is not seen here as p-value < 0.05 - Significant deviation from the normal distribution
#Levene test for equal variances
leveneTest(Median.Income~Gender, MaleFemaleEarnings)
#Equal variances not seen here as p-value < 0.05 - Significant difference between the variances
#Continue with non-parametric version of the test.
#Wilcoxon test
wilcox.test(Median.Income ~ Gender, data = MaleFemaleEarnings, alternative = "two.sided", paired = F)
#P-value < 0.05 reject the null and there is a significant difference in median income
#visualisation
ggplot(data = MaleFemaleEarnings, aes(x=Gender, y=Median.Income, color = Gender)) +
geom_boxplot(linewidth = 0.8, width = 0.8) +
scale_fill_manual(values = c("#0000FF", "#FF0000")) +
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -5),
axis.title.y = element_text(size = 14, vjust = 5),
plot.title = element_text(size = 16, vjust = 5),
plot.margin = unit(c(1,1,1,1), "cm")) +
xlab("Gender") +
ylab("Median Income ($)") +
labs(title = expression(underline("Median Income($) by Gender in the US 1967 - 2021")))
#Figure 2.2 ...
#Effect size
wilcox_effsize(MaleFemaleEarnings, Median.Income ~ Gender, paired = F)
#Large magnitude, effsize = 0.862.
Code Part 3:
#Loading Packages
library(knitr)
library(kableExtra)
library(psych)
library(car)
library(ggplot2)
library(multcomp)
library(ggeffects)
library(phia)
library(effects)
#Importing the data
GenderIncomeDegree <- read.csv("C:/Users/edren/OneDrive/Desktop/Data Analysis/R Working Directory/Final Project Assignment/Datasets/DataSets/GenderIncomeDegree.csv")
names(GenderIncomeDegree) <- c("Year", "Gender", "Median.Income", "Degree")
#checking the structure of the data
str(GenderIncomeDegree)
GenderIncomeDegree$Gender <- as.factor(GenderIncomeDegree$Gender)
GenderIncomeDegree$Degree <- as.factor(GenderIncomeDegree$Degree)
GenderIncomeDegree$Median.Income <- as.integer(GenderIncomeDegree$Median.Income)
str(GenderIncomeDegree)
#Initial look at the data
head(GenderIncomeDegree)
head(GenderIncomeDegree[GenderIncomeDegree$Degree == "Masters",])
TableIncomeDegree <- rbind(head(GenderIncomeDegree,4), "...", head(GenderIncomeDegree[GenderIncomeDegree$Degree == "Masters",],2), tail(GenderIncomeDegree[GenderIncomeDegree$Degree == "Masters",],2), "...", tail(GenderIncomeDegree,4))
kable(TableIncomeDegree,
caption = "Table 3.1: Initial look at how our data is laid out. Providing Income data for both Genders and 3 different degree types in the US from 1991 - 2022. The Income in this dataset accounts for inflation and is in 2022 Dollars ($).") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Summary Statistics Two Way
SummaryStatsTable <- describeBy(GenderIncomeDegree$Median.Income, group = GenderIncomeDegree$Gender : GenderIncomeDegree$Degree, mat = T)
KableStatsTable <- as.data.frame(rbind((SummaryStatsTable$group1),(SummaryStatsTable$n),(SummaryStatsTable$mean),(SummaryStatsTable$sd),(SummaryStatsTable$median),(SummaryStatsTable$min),(SummaryStatsTable$max),(SummaryStatsTable$range),(SummaryStatsTable$skew),(SummaryStatsTable$kurtosis),(SummaryStatsTable$se)))
names(KableStatsTable) <- c("F:Bachelors","F:Doctorate","F:Masters", "M:Bachelors","M:Doctorate","M:Masters")
KableStatsTable <- KableStatsTable[-1, ]
KableStatsTable2 <- as.data.frame(t(KableStatsTable))
names(KableStatsTable2) <- c("n", "mean", "sd", "median", "min", "max", "range", "skew", "kurtosis", "se")
#changing some types
KableStatsTable2$n <- as.integer(KableStatsTable2$n)
KableStatsTable2$mean <- as.numeric(KableStatsTable2$mean)
KableStatsTable2$sd <- as.numeric(KableStatsTable2$sd)
KableStatsTable2$median <- as.numeric(KableStatsTable2$median)
KableStatsTable2$min <- as.numeric(KableStatsTable2$min)
KableStatsTable2$max <- as.numeric(KableStatsTable2$max)
KableStatsTable2$range <- as.numeric(KableStatsTable2$range)
KableStatsTable2$skew <- as.numeric(KableStatsTable2$skew)
KableStatsTable2$kurtosis <- as.numeric(KableStatsTable2$kurtosis)
KableStatsTable2$se <- as.numeric(KableStatsTable2$se)
#Kable Statistics table
kable(KableStatsTable2, caption = "Table 3.2: Summary Statistics of the median income data for both Genders and 3 degree types in the US from 1991-2021.") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15)
#Anova Model - Two way
TwoWayM1 <- aov(Median.Income ~ Gender * Degree, data = GenderIncomeDegree)
TwoWayM1
#Diagnostic Checks
#homoscedasticity
par(mfrow = c(2,2))
plot(TwoWayM1)
par(mfrow = c(1,1))
#Figure 3.1:...
#No more than 3 times smallest, looks fine here
#Normal Distribution of residuals
Res_Epsilon <- TwoWayM1$residuals
shapiro.test(Res_Epsilon)
ggplot(GenderIncomeDegree, aes(x = Res_Epsilon)) +
geom_histogram(aes(y=..density..),
colour = 1, fill = "white", bins = 14) +
geom_density(lwd = 1, colour = 4, fill = 4, alpha = 0.25) +
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -5),
axis.title.y = element_text(size = 14, vjust = 5, hjust = 0.6),
plot.title = element_text(size = 16, vjust = 5),
plot.margin = unit(c(1,1,1,1), "cm")) +
xlab("Residuals") +
ylab("Density") +
labs(title = expression(underline("Histogram of Residuals | Two Way ANOVA Model 1")))
#Figure 3.2
#Residuals are normally distributed
#Analyzing the data
anova(TwoWayM1)
#Interaction between variables
plot(allEffects(TwoWayM1), ylab={"Median Income ($)"},main={"Effect Plot of Median Income ($)"}, lwd = 2, lty = 5, multiline = T, rug = T, colors = c("Red", "DeepSkyBlue"))
#Figure 3.3:...
#Another
TwoWayPlot <- ggeffect(TwoWayM1, terms = c("Gender", "Degree"))
plot(TwoWayPlot) +
scale_x_continuous(labels = c("Female", "Male"), breaks = c(1,2)) +
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -4),
axis.title.y = element_text(size = 14, vjust = 6),
plot.title = element_text(size = 16, vjust = 6),
plot.margin = unit(c(1,1,1,1), "cm")) +
labs(title = expression(underline("Predicted Values of Median Income ($)"))) +
ylab("Median Income ($)") +
xlab("Gender")
#Figure 3.4:...
#Tukey HSD
#Test 1 - Post Hoc test for differences between Genders within Degrees
t1 <- testInteractions(TwoWayM1, pairwise = "Gender", fixed = "Degree", adjustment = "holm")
t1$`Pr(>F)` <- as.numeric(t1$`Pr(>F)`)
t1$`Pr(>F)` <- formatC(t1$`Pr(>F)`, format = "e", digits = 2)
kable(t1, caption = "Table 3.3: Pairwise tests to test for interaction between Genders within Degree type (adjustment = Holms test).") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15)
#Test 2 - Post Hoc test for differences between Degrees within Genders
t2 <- testInteractions(TwoWayM1, pairwise = "Degree", fixed = "Gender", adjustment = "holm")
t2$`Pr(>F)` <- as.numeric(t2$`Pr(>F)`)
t2$`Pr(>F)` <- formatC(t2$`Pr(>F)`, format = "e", digits = 2)
kable(t2, caption = "Table 3.4: Pairwise tests to test for interaction between Degree type within Genders (adjustment = Holms test).") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15)
Code Part 4:
#Packages
library(kableExtra)
library(dplyr)
library(knitr)
library(ggplot2)
library(corrplot)
library(vcd)
#Data
EmpStatusGender <- read.csv("C:/Users/edren/OneDrive/Desktop/Data Analysis/R Working Directory/Final Project Assignment/Datasets/DataSets/EmpStatusGender_25andOverBachelorsOrHigher.csv", stringsAsFactors=TRUE)
#Clean
names(EmpStatusGender) <- c("Year", "Q", "Emp.Status", "Gender", "Total.Count")
#Initial Look at our Data
head(EmpStatusGender)
tail(EmpStatusGender)
TableEmpGender1 <- rbind(head(EmpStatusGender), "...", tail(EmpStatusGender))
TableEmpGender1
kable(TableEmpGender1, row.names = F, caption = "Table 4.1: BLS Beta Labs data regarding Total Employed/Unemployed from 2015-2021 (Q1-Q4) by Gender. The count of this data is in thousands (K)") %>%
kable_styling(bootstrap_options = "striped") %>%
row_spec(0, bold = T, font_size = 15)
#Select Random Year and Q
selected_year <- sample(unique(EmpStatusGender$Year), 1)
selected_quarter <- sample(unique(EmpStatusGender$Q), 1)
RandomSample <- EmpStatusGender %>%
filter(Year == selected_year, Q == selected_quarter)
#Looking at our Sample
kable(RandomSample, row.names = F, caption = "Table 4.2: Random Year and Q selected to generate a Sample from our original data from BLS Beta Labs data. Showing Total Employed/Unemployed by Gender. The count of this data is in thousands (K)") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15)
#Contingency Table
GroupedData <- xtabs(Total.Count ~ Emp.Status + Gender, data = RandomSample)
ContingencyTable <- as.data.frame.matrix(GroupedData)
kable(ContingencyTable, caption = "Table 4.3: ") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15)
#Initial visualization
ggplot(data = RandomSample, aes(x = Gender, y = Total.Count, fill = Emp.Status)) +
geom_bar(stat = "identity", position = position_dodge()) +
ggtitle("Attrition | Job Level - Observed Values") +
scale_fill_brewer(name = "Employment", palette = "Dark2") +
theme_minimal(base_size = 12) +
theme(axis.title.x = element_text(size = 14, vjust = -5),
axis.title.y = element_text(size = 14, vjust = 5, hjust = 0.6),
plot.title = element_text(size = 16, vjust = 5),
plot.margin = unit(c(1,1,1,1), "cm")) +
xlab("Gender") +
ylab("Frequency (in thousands - k)") +
labs(title = expression(underline("Counts of Employment by Gender in the US")))
#Figure 4.1:.. **NOT USED**
#Test
Test1 <- chisq.test(ContingencyTable, correct = FALSE)
Test1
#N > 40, not using Yates Correction
##Expected Values
kable(round(Test1$expected,3), caption = "Table 4.4: Expected Values of our random sample of the population data. The count of this data is in thousands (K)") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15) %>%
add_header_above(c("Employment" = 1, "Expected Values" = 2))
#More than 20% of expected values are not less than 5. won't use fisher
#Table for Discussion
#Observed Values, Expected, Chi Squared Components in 1 table
merged_tables <- cbind(Test1$observed, round(Test1$expected,3), round(Test1$residuals^2,4))
kable(merged_tables, caption = "Table 4.5: Observed Values, Expected Values and the Chi-Square Components of our random sample of the population data. The count of this data is in thousands (K)") %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(0, bold = T, font_size = 15) %>%
add_header_above(c(" " = 1, "Observed Values" = 2, "Expected Values" = 2, "Chi-Squared Components" = 2))
#Test output
Test1
#Visualisation... For Discussion. Corrplot
association_plot <- assoc(GroupedData, shade = T, las = 3, main = "Association Plot of Gender and Employment Status")
#Figure: 4.2: Association Plot showing Pearson residuals for our Chi Squared test of the association between Gender and Employment Status.
# A positive association between Gender and Employment status is indicated with a bar above the dotted line,
# A negative association between Gender and Employment status is indicated with a bar below the dotted line.
# The strength of the association is indicated by the size of the bar.
LS0tDQp0aXRsZTogIlByb2plY3QgQ29kZSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9ICJoaWRlIiwNCiAgICAgICAgICAgICAgICAgICAgICBldmFsID0gRikNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgpDQpgYGANCg0KDQoNCiMjIyMgQ29kZSBQYXJ0IDE6DQoNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0iaGlkZSIsIGV2YWwgPSBGfQ0KI1BhY2thZ2VzDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCg0KI0xvYWRpbmcgdGhlIERhdGEgaW50byBSIGFmdGVyIFRyYW5zZm9ybWluZyBpbiBFeGNlbA0KDQpGZW1hbGVFYXJuaW5ncyA8LSByZWFkLmNzdigiQzovVXNlcnMvZWRyZW4vT25lRHJpdmUvRGVza3RvcC9EYXRhIEFuYWx5c2lzL1IgV29ya2luZyBEaXJlY3RvcnkvRmluYWwgUHJvamVjdCBBc3NpZ25tZW50L0RhdGFzZXRzL0RhdGFTZXRzL0ZlbWFsZSBFYXJuaW5ncyBUcmFuc2Zvcm1lZC5jc3YiKQ0KDQoNCg0KI0NsZWFuIHVwDQoNCm5hbWVzKEZlbWFsZUVhcm5pbmdzKSA8LSBjKCJZZWFyIiwgIkZlbWFsZS5FYXJuaW5ncyIpDQoNCiNBZGRpbmcgYSBOdW1iZXIgdG8geWVhcg0KDQpGZW1hbGVFYXJuaW5ncyA8LSBGZW1hbGVFYXJuaW5ncyAlPiUNCiAgYXJyYW5nZShZZWFyKSAlPiUNCiAgbXV0YXRlKFllYXJOdW0gPSByb3dfbnVtYmVyKCkpDQoNCg0KDQojSW5pdGlhbCBsb29rIGF0IHRoZSBkYXRhDQoNCmhlYWQoRmVtYWxlRWFybmluZ3MpDQoNCnRhaWwoRmVtYWxlRWFybmluZ3MpDQoNClRhYmxlRWFybmluZ3MxIDwtIHJiaW5kKGhlYWQoRmVtYWxlRWFybmluZ3MpLCAiLi4uIiwgdGFpbChGZW1hbGVFYXJuaW5ncykpDQoNCmthYmxlKFRhYmxlRWFybmluZ3MxLCByb3cubmFtZXMgPSBGLCBjYXB0aW9uID0gIlRhYmxlIDEuMTogVVMgQ2Vuc3VzIGRhdGEgcmVnYXJkaW5nIE1lZGlhbiBlYXJuaW5ncyBmb3IgVG90YWwgRmVtYWxlIFdvcmtlcnMgZnJvbSAxOTY3IC0gMjAyMS4gVGhlIFllYXJzIGFyZSBudW1iZXJlZCBpbiBvcmRlciB0byBub3Qgc2tldyB0aGUgYW5hbHlzaXMgbGF0ZXIuIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KDQoNCiNDcmVhdGluZyB0aGUgaW5pdGlhbCByZWdyZXNzaW9uIG1vZGVsDQoNClJlZy5Nb2RlbDEgPC0gbG0oRmVtYWxlLkVhcm5pbmdzflllYXJOdW0sIGRhdGEgPSBGZW1hbGVFYXJuaW5ncykNCg0KDQoNCg0KI1Bsb3R0aW5nIHRoZSBpbnRpYWwgZGF0YQ0KDQojbGluZWFyaXR5IGNoZWNrIDENCg0KZ2dwbG90KEZlbWFsZUVhcm5pbmdzLCBhZXMoeCA9IFllYXIsIHkgPSBGZW1hbGUuRWFybmluZ3MpKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgPSAiYmx1ZSIpICsNCiAgZ2VvbV9wb2ludChjb2xvcj0icmVkIikrDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgIHZqdXN0ID0gLTQsIGhqdXN0ID0gMC40MyksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIHZqdXN0ID0gNiwgaGp1c3QgPSAwLjYpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgdmp1c3QgPSA2KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpKSArDQogIGxhYnModGl0bGUgPSBleHByZXNzaW9uKHVuZGVybGluZSgiTWVkaWFuIEZlbWFsZSBFYXJuaW5ncyBpbiB0aGUgVVMgZnJvbSAxOTY3LTIwMjEiKSkpICsNCiAgeWxhYigiTWVkaWFuIEZlbWFsZSBFYXJuaW5ncyAoJCkiKSArDQogIHhsYWIoIlRpbWUgaW4gWWVhcnMiKQ0KI0ZpZ3VyZSAxLjE6IC4uLg0KDQoNCiNMb29rcyBsaW5lYXINCg0KDQojQ29lZmZpY2llbnQgVGFibGUNCg0KTW9kZWwxVGFibGUgPC0gUmVnLk1vZGVsMSRjb2VmZmljaWVudHMNCg0Ka2FibGUodChNb2RlbDFUYWJsZSksIGNhcHRpb24gPSAiVGFibGUgMS4yOiBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbCAxLiBUaGUgaW50ZXJjZXB0IChjb25zdGFudCkgzrIwIGFuZCB0aGUgc2xvcGUgKGNvZWZmaWNpZW50KSDOsjEsIHdoaWNoIGFyZSB1c2VkIHdpdGggdGhlIHByZWRpY3RvciBYIHRvIGFjaGlldmUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIFkuIiwgY29sLm5hbWVzID0gYygizrIwIChJbnRlcmNlcHQpIiwgIs6yMSAoU2xvcGUpIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiKSAlPiUNCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGZvbnRfc2l6ZSA9IDE1KQ0KDQojQ2hlY2tpbmcgYXNzdW1wdGlvbnMgYXJlIG1ldA0KDQoNCg0KI0hvbW9zY2VkYXN0aWNpdHkgY2hlY2sgMQ0KDQpwYXIobWZyb3cgPSBjKDIsMikpDQoNCnBsb3QoUmVnLk1vZGVsMSkNCg0KcGFyKG1mcm93ID0gYygxLDEpKQ0KDQojRmlndXJlIDEuMjouLi4NCg0KI1FRIFBsb3QgdGVsbHMgdXMgdGhlIG5vcm1hbGl0eSBvZiB0aGUgcmVzaWR1YWxzLCBhIHN0cmFpZ2h0IGxpbmUgaW5kaWNhdGVzIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCiNSZXNpZHVhbHMgdnMgRml0dGVkOiBTaG93cyB0aGUgcmVzaWR1YWxzIHdoaWNoIGlzIHkgLSBwcmVkaWN0ZWQgeSBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBmaXR0ZWQgdmFsdWVzLg0KI1Jlc2lkdWFscyBzaG91bGQgYm91bmNlIHJhbmRvbWx5IGFyb3VuZCB0aGUgMCBsaW5lIGFuZCBzaG91bGQgYmUgcm91Z2hseSBlcXVhbCBhcm91bmQgdGhlIGVzdGltYXRlZCByZWdyZXNzaW9uIGxpbmUuDQojUmVzaWR1YWxzIHNvbWV3aGF0IGEgcGF0dGVybiBpbiB0aGlzIGNhc2UsIHNvIHdlIHdpbGwgdHJhbnNmb3JtIHRoZSBkYXRhIHRvIHNlZSBpZiB0aGlzIG1ha2VzIGEgZGlmZmVyZW5jZS4NCg0KDQoNCg0KI2xvZzEwIFRyYW5zZm9ybWF0aW9uDQoNClJlZy5Nb2RlbDIgPC0gbG0obG9nMTAoRmVtYWxlLkVhcm5pbmdzKX4oWWVhck51bSksIGRhdGEgPSBGZW1hbGVFYXJuaW5ncykNCg0KDQojVGFibGUgRm9yIENvZWZmaWNpZW50cw0KDQpNb2RlbDJUYWJsZSA8LSBSZWcuTW9kZWwyJGNvZWZmaWNpZW50cw0KDQprYWJsZSh0KE1vZGVsMlRhYmxlKSwgY2FwdGlvbiA9ICJUYWJsZSAxLjM6IExpbmVhciBSZWdyZXNzaW9uIE1vZGVsIDIgd2l0aCBsb2cxMCgpIHRyYW5zZm9ybWF0aW9uLiBUaGUgaW50ZXJjZXB0IChjb25zdGFudCkgzrIwIGFuZCB0aGUgc2xvcGUgKGNvZWZmaWNpZW50KSDOsjEsIHdoaWNoIGFyZSB1c2VkIHdpdGggdGhlIHByZWRpY3RvciBYIHRvIGFjaGlldmUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIFkuIiwgY29sLm5hbWVzID0gYygizrIwIChJbnRlcmNlcHQpIiwgIs6yMSAoU2xvcGUpIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiKSAlPiUNCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGZvbnRfc2l6ZSA9IDE1KQ0KDQoNCiNIb21vc2NlZGFzdGljaXR5IENoZWNrIDINCg0KI1Bsb3R0aW5nIE1vZGVsIDINCg0KcGFyKG1mcm93ID0gYygyLDIpKQ0KDQpwbG90KFJlZy5Nb2RlbDIpDQoNCnBhcihtZnJvdyA9IGMoMSwxKSkNCg0KI0ZpZ3VyZSAxLjM6Li4uDQoNCg0KI1Jlc2lkdWFscyB2cyBGaXR0ZWQsIEFmdGVyIHRoZSBsb2cxMCgpIHRyYW5zZm9ybWF0aW9uIHRoZXJlIGlzIGxlc3MgZGlzcGVyc2lvbiBhbmQgcmVzaWR1YWxzIGZvcm0gYSBVIHNoYXBlIHBhdHRlcm4sIHNob3dpbmcgYSBub24gbGluZWFyIHJlbGF0aW9uc2hpcA0KIyNUaGUgUVEgUmVzaWR1YWxzIGRvIG5vdCBmb2xsb3cgYSBzdHJhaWdodCBsaW5lIHdoaWNoIHNob3dzIGxhY2sgbm9ybWFsaXR5IG9mIHJlc2lkdWFscy4NCg0KI09uZSBjYW5ub3Qgc2F5IHRoYXQgYWxsIHRoZSBhc3N1bXB0aW9ucyBvZiBsaW5lYXIgcmVncmVzc2lvbiBhcmUgbWV0IGFzIHRoZSBkYXRhIHBvaW50cyBhcmUgbm90IHJhbmRvbWx5IHNwcmVhZCBhcm91bmQgdGhlIGxpbmUuDQoNCg0KDQojQWRkaW5nIGFub3RoZXIgdmFyaWFibGUgdG8gb3VyIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLg0KI0luZmxhdGlvbi4NCg0KI1NpbmNlIHdlIGFyZSBsb29raW5nIGF0IGhvdyBpbmNvbWUgaGFzIGluY3JlYXNlZCBvdmVyIHRoZSB5ZWFycywgaW5mbGF0aW9uIHdpbGwgYmUgYSBnb29kIHZhcmlhYmxlIHRvIGFkZCB0byBvdXIgbW9kZWwgYXMgaXQgZGlyZWN0bHkgaGFzIGFuIGVmZmVjdCBvbiBpbmNvbWUuDQpJbmZsYXRpb25EYXRhIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9lZHJlbi9PbmVEcml2ZS9EZXNrdG9wL0RhdGEgQW5hbHlzaXMvUiBXb3JraW5nIERpcmVjdG9yeS9GaW5hbCBQcm9qZWN0IEFzc2lnbm1lbnQvRGF0YXNldHMvRGF0YVNldHMvSW5mbGF0aW9uLmNzdiIpDQoNCkZlbWFsZUVhcm5pbmdzTmV3IDwtIGNiaW5kKEZlbWFsZUVhcm5pbmdzLCBJbmZsYXRpb25EYXRhJEluZmxhdGlvbikNCg0KbmFtZXMoRmVtYWxlRWFybmluZ3NOZXcpIDwtIGMoIlllYXIiLCAiRmVtYWxlLkVhcm5pbmdzIiwgIlllYXJOdW0iLCAiSW5mbGF0aW9uIikNCiANCg0KDQoNCiNTY2FsZSBCb3RoIFllYXIgTnVtIGFuZCBJbmZsYXRpb24gaW4gb3JkZXIgdG8gY3JlYXRlIGEgbW9kZWwuDQoNClllYXJOdW1TY2FsZWQgPC0gc2NhbGUoRmVtYWxlRWFybmluZ3NOZXckWWVhck51bSwgY2VudGVyID0gVCwgc2NhbGUgPSBUKQ0KDQpJbmZsYXRpb25TY2FsZWQgPC0gc2NhbGUoRmVtYWxlRWFybmluZ3NOZXckSW5mbGF0aW9uLCBjZW50ZXIgPSBULCBzY2FsZSA9IFQpDQoNCkZlbWFsZUVhcm5pbmdzTmV3JFllYXJTY2FsZWQgPC0gc2NhbGUoRmVtYWxlRWFybmluZ3NOZXckWWVhck51bSwgY2VudGVyID0gVCwgc2NhbGUgPSBUKQ0KDQpGZW1hbGVFYXJuaW5nc05ldyRJbmZsYXRpb25TY2FsZWQgPC0gc2NhbGUoRmVtYWxlRWFybmluZ3NOZXckSW5mbGF0aW9uLCBjZW50ZXIgPSBULCBzY2FsZSA9IFQpDQoNCg0KDQoNCiNMaW5lYXIgUmVncmVzc2lvbiBNb2RlbCAzDQoNClJlZy5Nb2RlbDMgPC0gbG0oRmVtYWxlLkVhcm5pbmdzIH4gWWVhclNjYWxlZCArIEluZmxhdGlvblNjYWxlZCwgZGF0YSA9IEZlbWFsZUVhcm5pbmdzTmV3KQ0KDQoNCk1vZGVsM1RhYmxlIDwtIFJlZy5Nb2RlbDMkY29lZmZpY2llbnRzDQoNCmthYmxlKHQoTW9kZWwzVGFibGUpLCBjYXB0aW9uID0gIlRhYmxlIDEuNDogTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWwgMyB3aXRoIG5ldyBwcmVkaWN0b3IgSW5mbGF0aW9uICh4MikgLiBUaGUgaW50ZXJjZXB0IChjb25zdGFudCkgzrIwIGFuZCB0aGUgc2xvcGUgKGNvZWZmaWNpZW50KSDOsjEgKyDOsjIsIHdoaWNoIGFyZSB1c2VkIHdpdGggdGhlIHByZWRpY3RvciB4MSArIHgyIHRvIGFjaGlldmUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIFkuIiwgY29sLm5hbWVzID0gYygizrIwIChJbnRlcmNlcHQpIiwgIs6yMSAoU2xvcGUgZm9yIHgxKSIsICAizrIyIChTbG9wZSBmb3IgeDIpIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiKSAlPiUNCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGZvbnRfc2l6ZSA9IDE1KQ0KDQojUGxvdHRpbmcgTW9kZWwgMw0KDQpwYXIobWZyb3cgPSBjKDIsMikpDQoNCnBsb3QoUmVnLk1vZGVsMykNCg0KcGFyKG1mcm93ID0gYygxLDEpKQ0KDQojRmlndXJlIDEuNDouLi4NCg0KDQoNCg0KDQojQ2hlY2tpbmcgTXVsdGlwbGUgUiBTcXVhcmVkIGFuZCBBZGp1c3RlZCBSIFNxdWFyZWQgb2YgdGhlIHR3byBtb2RlbHMNCg0Kc3VtbWFyeShSZWcuTW9kZWwxKSRyLnNxdWFyZWQNCnN1bW1hcnkoUmVnLk1vZGVsMSkkYWRqLnIuc3F1YXJlZA0KDQpNb2RlbDFyU3F1YXJlZDwtIGNiaW5kLmRhdGEuZnJhbWUoc3VtbWFyeShSZWcuTW9kZWwxKSRyLnNxdWFyZWQsIHN1bW1hcnkoUmVnLk1vZGVsMSkkYWRqLnIuc3F1YXJlZCkNCg0KbmFtZXMoTW9kZWwxclNxdWFyZWQpIDwtIGMoIk11bHRpcGxlUl4yIiwgIkFkanVzdGVkUl4yIikNCg0KIyMNCg0KTW9kZWwzclNxdWFyZWQ8LSBjYmluZC5kYXRhLmZyYW1lKHN1bW1hcnkoUmVnLk1vZGVsMykkci5zcXVhcmVkLCBzdW1tYXJ5KFJlZy5Nb2RlbDMpJGFkai5yLnNxdWFyZWQpDQoNCm5hbWVzKE1vZGVsM3JTcXVhcmVkKSA8LSBjKCJNdWx0aXBsZVJeMiIsICJBZGp1c3RlZFJeMiIpDQoNCiMjDQoNClJTcXVhcmVkVGFibGUgPC1yYmluZChNb2RlbDFyU3F1YXJlZCwgTW9kZWwzclNxdWFyZWQpDQoNCnJvdy5uYW1lcyhSU3F1YXJlZFRhYmxlKSA8LSBjKCJNdWx0aXBsZVJeMiIsICJBZGp1c3RlZFJeMiIpDQoNCmthYmxlKHQoUlNxdWFyZWRUYWJsZSksIGNhcHRpb24gPSAiVGFibGUgMS41OiBDb21wYXJpbmcgdGhlIE11bHRpcGxlIFIgU3FhdXJlZCBhbmQgQWRqdXN0ZWQgUiBTcXVhcmVkIG9mIE1vZGVsIDEgYW5kIDIgdG8gZGV0ZXJtaW5lIHdoY2loIGlzIGJlc3QgZml0IGZvciBvdXIgZGF0YS4iLCBjb2wubmFtZXMgPSBjKCJNb2RlbCAxIiwgIk1vZGVsIDIiLCAiTW9kZWwgMyIpLCAgdGFibGUuYXR0ciA9ICJzdHlsZT0nd2lkdGg6ODAlOyciKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIikgJT4lDQogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBmb250X3NpemUgPSAxNSkNCg0KI0FkZGluZyBJbmZsYXRpb24gdG8gb3VyIG1vZGVsIC0+IE1vZGVsMywgd2UgZ2V0IGFuIGluY3JlYXNlIGluIE11bHRpcGxlUl4yIGFuZCBBZGp1c3RlZFJeMiBzcXVhcmVkLg0KI01haW4gaW5kaWNhdG9yIGZvciBnb29kbmVzcyBvZiBmaXQgb2YgaW50cm9kdWNpbmcgYSBuZXcgaW5kaWNhdG9yIHRvIG91ciBtb2RlbCBpcyBBZGp1c3RlZFJeMi4gQXMgaXQgZXhwbGFpbmVzIGhvdyBtdWNoIHZhcmlhYmlsaXR5IGlzIGV4cGxhaW5lZCBpbiB0aGUgbW9kZWwuDQoNCg0KDQoNCiNDYW4gdXNlIGFub3ZhIHRvIGRldGVybWluZSB3aGV0aGVyIEluZmxhdGlvbiBzaG91bGQgYmUgYWRkZWQgdG8gb3VyIG1vZGVsIG9yIG5vdC4NCg0KYW5vdmEoUmVnLk1vZGVsMSwgUmVnLk1vZGVsMykNCg0KI0RmID0gMSwgbW9yZSBjb21wbGV4IG1vZGVsIGhhcyBvbmUgYWRkaXRpb25hbCBwYXJhbWV0ZXINCiNQLXZhbHVlIDAuMiA+IDAuMDUsIG1lYW5zIHdlIHNob3VsZCByZWplY3QgTW9kZWwgMyBhbmQgY29udGludWUgd2l0aCBtb2RlbCAxDQoNCg0KDQoNCg0KI1N1bW1hcnkgb2YgcmVncmVzc2lvbiBtb2RlbCAxDQoNCnN1bW1hcnkoUmVnLk1vZGVsMSkNCg0KDQoNCiNQIC0gVmFsdWUgLSBVcHBlciBUYWlsIHRlc3QNCg0KcF92YWx1ZSA8LSBwdChxID0gNDEuMjIsIGRmID0gNTMsIGxvd2VyLnRhaWw9RkFMU0UpDQoNCnBfdmFsdWUNCg0KI1NpZ25pZmljYW50IGluY3JlYXNlIGluIEZlbWFsZSBlYXJuaW5ncyBieSBjaGFuZ2UgaW4gVGltZSBpbiBZZWFycy4NCg0KDQoNCg0KDQojUGxvdHRpbmcgUmVzaWR1YWxzDQoNCkZlbWFsZUVhcm5pbmdzJHByZWRpY3RlZCA8LSBwcmVkaWN0KFJlZy5Nb2RlbDEpDQoNCkZlbWFsZUVhcm5pbmdzJHJlc2lkdWFscyA8LSByZXNpZHVhbHMoUmVnLk1vZGVsMSkNCg0KZ2dwbG90KEZlbWFsZUVhcm5pbmdzLCBhZXMoeCA9IFllYXIsIHkgPSBGZW1hbGUuRWFybmluZ3MpKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgPSAiYmx1ZSIpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBhYnMocmVzaWR1YWxzKSwgc2l6ZSA9IGFicyhyZXNpZHVhbHMpKSkgKw0KICBzY2FsZV9jb2xvcl9jb250aW51b3VzKGxvdyA9ICJibHVlIiwgaGlnaCA9ICJyZWQiKSArDQogIGd1aWRlcyhjb2xvciA9IEYsIHNpemUgPSBGKSArDQogIGdlb21fc2VnbWVudChhZXMoeGVuZCA9IFllYXIsIHllbmQgPSBwcmVkaWN0ZWQpLCBhbHBoYSA9IC4yKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgIHZqdXN0ID0gLTQsIGhqdXN0ID0gMC40MyksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIHZqdXN0ID0gNiwgaGp1c3QgPSAwLjYpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgdmp1c3QgPSA2KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpKSArDQogIGxhYnModGl0bGUgPSBleHByZXNzaW9uKHVuZGVybGluZSgiTWVkaWFuIEZlbWFsZSBFYXJuaW5ncyAoJCkgaW4gdGhlIFVTIGZyb20gMTk2Ny0yMDIxIikpKSArDQogIHlsYWIoIk1lZGlhbiBGZW1hbGUgRWFybmluZ3MgKCQpIikgKw0KICB4bGFiKCJUaW1lIGluIFllYXJzIikNCiNGaWd1cmUgMS41OiBNZWRpYW4gRmVtYWxlIEVhcm5pbmdzIHBsb3R0ZWQgYWdhaW5zdCB0aW1lIGluIFllYXJzLCB3aXRoIGxpbmUgb2YgYmVzdCBmaXQgYW5kIFJlc2lkdWFscyBwbG90dGVkIHRvIHRoZSBwcmVkaWN0ZWQgdmFsdWVzLg0KDQoNCg0KDQojV2UgY2FuIHByZWRpY3QgbWVkaWFuIGZlbWFsZSBlYXJuaW5ncyBpbiB0aGUgVVMgdXNpbmcgdGhlIGNvZWZmaWNpZW50cy4uLg0KI0FuZCB1c2luZyB0aGUgWWVhciBudW1iZXIgYXMgWDENCg0KTW9kZWwxVGFibGUgPC0gUmVnLk1vZGVsMSRjb2VmZmljaWVudHMNCg0Ka2FibGUodChNb2RlbDFUYWJsZSksIGNhcHRpb24gPSAiVGFibGUgMS4yOiBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbCAxLiBUaGUgaW50ZXJjZXB0IChjb25zdGFudCkgzrIwIGFuZCB0aGUgc2xvcGUgKGNvZWZmaWNpZW50KSDOsjEsIHdoaWNoIGFyZSB1c2VkIHdpdGggdGhlIHByZWRpY3RvciBYIHRvIGFjaGlldmUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIFkuIiwgY29sLm5hbWVzID0gYygizrIwIChJbnRlcmNlcHQpIiwgIs6yMSAoU2xvcGUpIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiKSAlPiUNCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGZvbnRfc2l6ZSA9IDE1KQ0KDQojIFkoUHJlZGljdGVkIE1lZGlhbiBGZW1hbGUgRWFybmluZ3MpID0gMTUzODMuMDggKyA0MDYuNjQwNSAqIHgxDQoNCiNZZXQgdGhpcyBudW1iZXIgZG9lcyBub3QgYWNjb3VudCBmb3IgaW5mbGF0aW9uLCB1bmVtcGxveW1lbnQsIG90aGVyIHNvY2lvZWNvbm9taWMgYW5kIGVjb25vbWljIGZhY3RvcnMuDQoNCg0KYGBgDQoNCiMjIyMgQ29kZSBQYXJ0IDI6DQoNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0iaGlkZSIsIGV2YWwgPSBGfQ0KI1BhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdncHVicikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KFJjbWRyKQ0KbGlicmFyeShkcGx5cikNCg0KI0RhdGENCk1hbGVGZW1hbGVFYXJuaW5ncyA8LSByZWFkLmNzdigiQzovVXNlcnMvZWRyZW4vT25lRHJpdmUvRGVza3RvcC9EYXRhIEFuYWx5c2lzL1IgV29ya2luZyBEaXJlY3RvcnkvRmluYWwgUHJvamVjdCBBc3NpZ25tZW50L0RhdGFzZXRzL0RhdGFTZXRzL01GRWFybmluZ3MuY3N2IikNCg0KbmFtZXMoTWFsZUZlbWFsZUVhcm5pbmdzKSA8LSBjKCJZZWFyIiwgIkdlbmRlciIsICJNZWRpYW4uSW5jb21lIikNCg0KI0luaXRpYWwgTG9vayBhdCBvdXIgZGF0YQ0KDQpoZWFkKE1hbGVGZW1hbGVFYXJuaW5ncykNCg0KdGFpbChNYWxlRmVtYWxlRWFybmluZ3MpDQoNClRhYmxlRWFybmluZ3MyIDwtIHJiaW5kKGhlYWQoTWFsZUZlbWFsZUVhcm5pbmdzKSwgIi4uLiIsIHRhaWwoTWFsZUZlbWFsZUVhcm5pbmdzKSkNCg0Ka2FibGUoVGFibGVFYXJuaW5nczIsDQogICAgICBjYXB0aW9uID0gIlRhYmxlIDIuMTogSW5pdGlhbCBsb29rIGF0IGhvdyBvdXIgZGF0YSBpcyBsYWlkIG91dC4gUHJvdmlkaW5nIEluY29tZSBkYXRhIGZvciBib3RoIEdlbmRlcnMgaW4gdGhlIFVTIGZyb20gMTk2NyAtIDIwMjIuIFRoZSBJbmNvbWUgaW4gdGhpcyBkYXRhc2V0IGFjY291bnRzIGZvciBpbmZsYXRpb24gYW5kIGlzIGluIDIwMjIgRG9sbGFycyAoJCkuIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KDQoNCiNTdW1tYXJ5IFN0YXRzDQoNCiNTdW1tYXJ5IFN0YXRpc3RpY3MgYnkgR2VuZGVyDQoNCkJ5R2VuZGVyIDwtZ3JvdXBfYnkoTWFsZUZlbWFsZUVhcm5pbmdzLCBHZW5kZXIpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgY291bnQgPSBuKCksDQogICAgbWVkaWFuID0gbWVkaWFuKE1lZGlhbi5JbmNvbWUsIG5hLnJtID0gVCksDQogICAgSVFSID0gSVFSKE1lZGlhbi5JbmNvbWUsIG5hLnJtID0gVCkNCiAgKQ0KDQprYWJsZShCeUdlbmRlcixjYXB0aW9uID0gICJUYWJsZSAyLjI6IFN1bW1hcnkgU3RhdGlzdGljcyBmb3IgdGhlIHNlcGVyYXRlIEdlbmRlcnMgaW4gdGhlIFVTIGZyb20gMTk2Ny0yMDIxLiBUaGUgY291bnQgPSBudW1iZXIgb2YgeWVhcnMgaW4gdGhlIHN0dWR5LCBtZWRpYW4gaW5jb21lIGZvciBlYWNoLCBhbmQgdGhlIGludGVycXVhcnRpbGUgcmFuZ2UuIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCiNJbnRlclF1YXJ0aWxlIFJhbmdlIGlzIHZlcnkgaGlnaCBmb3IgZmVtYWxlcyBtZWFuaW5nIHRoZXJlIGlzIGEgaGlnaCByYW5nZSB3aGVyZSBtb3N0IG9mIG91ciB2YWx1ZXMgbGllLg0KDQoNCg0KDQoNCg0KI1Bsb3RzIHRvIGNoZWNrIGZvciBub3JtYWwgZGlzdHJpYnV0aW9uLCBmb3IgYWxsIG1lZGlhbiBpbmNvbWUgZGF0YQ0KDQpwYXIobWZyb3c9YygxLDMpKQ0KDQp7d2l0aChNYWxlRmVtYWxlRWFybmluZ3MsIEhpc3QoTWVkaWFuLkluY29tZSwgc2NhbGU9InBlcmNlbnQiLCB5bGFiPSAiUGVyY2VudCIsIG1haW49ICJIaXN0b2dyYW0gZm9yIEluY29tZSIsIGJyZWFrcz0iU3R1cmdlcyIsY29sPSJsaWdodGdyYXkiKSkNCiAgYWJsaW5lKHYgPSBtZWFuKE1hbGVGZW1hbGVFYXJuaW5ncyRNZWRpYW4uSW5jb21lKSwgY29sID0gInJlZCIsIGx3ZCA9IDMpDQogIGFibGluZSh2ID0gbWVkaWFuKE1hbGVGZW1hbGVFYXJuaW5ncyRNZWRpYW4uSW5jb21lKSwgY29sID0gInllbGxvdyIsIGx3ZCA9IDMpDQogIGxlZ2VuZCgidG9wcmlnaHQiLCBjKCJNZWFuIiwgIk1lZGlhbiIpLCBjb2wgPSBjKCJyZWQiLCAieWVsbG93IiksIGx3ZCA9IDMpfQ0KDQpkZW5zaXR5UGxvdCggfiBNZWRpYW4uSW5jb21lLCBkYXRhID0gTWFsZUZlbWFsZUVhcm5pbmdzLCBtYWluID0gIkRlbnNpdHkgUGxvdCBmb3IgSW5jb21lIiwgYnc9YncuU0osIGFkanVzdD0xLCBrZXJuZWw9ZG5vcm0sIG1ldGhvZD0iYWRhcHRpdmUiKQ0KDQp3aXRoKE1hbGVGZW1hbGVFYXJuaW5ncywgcXFQbG90KE1lZGlhbi5JbmNvbWUsIGRpc3Q9Im5vcm0iLCBtYWluID0gIlFRIFBsb3QgZm9yIEluY29tZSIsIGlkPWxpc3QobWV0aG9kPSJ5Iiwgbj0yLCBsYWJlbHM9cm93bmFtZXMoTWFsZUZlbWFsZUVhcm5pbmdzKSkpKQ0KDQpwYXIobWZyb3c9YygxLDEpKQ0KDQojRmlndXJlIDIuMSAuLi5Qb3NpdGl2ZSBza2V3IGluIEhpc3RvZ3JhbSBhbmQgZGVuc2l0eSBwbG90LiANCg0KDQoNCg0KI1NoYXBpcm8gV2lsayBub3JtYWxpdHkgdGVzdA0KDQpzaGFwaXJvLnRlc3QoTWFsZUZlbWFsZUVhcm5pbmdzJE1lZGlhbi5JbmNvbWUpDQoNCiNOb3JtYWxpdHkgaXMgbm90IHNlZW4gaGVyZSBhcyBwLXZhbHVlIDwgMC4wNSAtIFNpZ25pZmljYW50IGRldmlhdGlvbiBmcm9tIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uDQoNCg0KDQoNCiNMZXZlbmUgdGVzdCBmb3IgZXF1YWwgdmFyaWFuY2VzDQoNCmxldmVuZVRlc3QoTWVkaWFuLkluY29tZX5HZW5kZXIsIE1hbGVGZW1hbGVFYXJuaW5ncykNCg0KI0VxdWFsIHZhcmlhbmNlcyBub3Qgc2VlbiBoZXJlIGFzIHAtdmFsdWUgPCAwLjA1IC0gU2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB2YXJpYW5jZXMNCg0KDQoNCg0KI0NvbnRpbnVlIHdpdGggbm9uLXBhcmFtZXRyaWMgdmVyc2lvbiBvZiB0aGUgdGVzdC4NCiNXaWxjb3hvbiB0ZXN0DQoNCndpbGNveC50ZXN0KE1lZGlhbi5JbmNvbWUgfiBHZW5kZXIsIGRhdGEgPSBNYWxlRmVtYWxlRWFybmluZ3MsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIsIHBhaXJlZCA9IEYpDQoNCiNQLXZhbHVlIDwgMC4wNSByZWplY3QgdGhlIG51bGwgYW5kIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBtZWRpYW4gaW5jb21lDQoNCg0KDQoNCg0KDQoNCiN2aXN1YWxpc2F0aW9uDQpnZ3Bsb3QoZGF0YSA9IE1hbGVGZW1hbGVFYXJuaW5ncywgYWVzKHg9R2VuZGVyLCB5PU1lZGlhbi5JbmNvbWUsIGNvbG9yID0gR2VuZGVyKSkgKw0KICBnZW9tX2JveHBsb3QobGluZXdpZHRoID0gMC44LCB3aWR0aCA9IDAuOCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDAwMEZGIiwgIiNGRjAwMDAiKSkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsICB2anVzdCA9IC01KSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgdmp1c3QgPSA1KSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIHZqdXN0ID0gNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSkgKw0KICB4bGFiKCJHZW5kZXIiKSArDQogIHlsYWIoIk1lZGlhbiBJbmNvbWUgKCQpIikgKw0KICBsYWJzKHRpdGxlID0gZXhwcmVzc2lvbih1bmRlcmxpbmUoIk1lZGlhbiBJbmNvbWUoJCkgYnkgR2VuZGVyIGluIHRoZSBVUyAxOTY3IC0gMjAyMSIpKSkNCiNGaWd1cmUgMi4yIC4uLg0KDQoNCg0KI0VmZmVjdCBzaXplDQoNCndpbGNveF9lZmZzaXplKE1hbGVGZW1hbGVFYXJuaW5ncywgTWVkaWFuLkluY29tZSB+IEdlbmRlciwgcGFpcmVkID0gRikNCg0KI0xhcmdlIG1hZ25pdHVkZSwgZWZmc2l6ZSA9IDAuODYyLg0KDQoNCmBgYA0KDQojIyMjIENvZGUgUGFydCAzOg0KDQpgYGB7ciBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9ImhpZGUiLCBldmFsID0gRn0NCiNMb2FkaW5nIFBhY2thZ2VzDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShtdWx0Y29tcCkNCmxpYnJhcnkoZ2dlZmZlY3RzKQ0KbGlicmFyeShwaGlhKQ0KbGlicmFyeShlZmZlY3RzKQ0KDQojSW1wb3J0aW5nIHRoZSBkYXRhDQpHZW5kZXJJbmNvbWVEZWdyZWUgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL2VkcmVuL09uZURyaXZlL0Rlc2t0b3AvRGF0YSBBbmFseXNpcy9SIFdvcmtpbmcgRGlyZWN0b3J5L0ZpbmFsIFByb2plY3QgQXNzaWdubWVudC9EYXRhc2V0cy9EYXRhU2V0cy9HZW5kZXJJbmNvbWVEZWdyZWUuY3N2IikNCg0KbmFtZXMoR2VuZGVySW5jb21lRGVncmVlKSA8LSBjKCJZZWFyIiwgIkdlbmRlciIsICJNZWRpYW4uSW5jb21lIiwgIkRlZ3JlZSIpDQoNCg0KDQojY2hlY2tpbmcgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZGF0YQ0KDQpzdHIoR2VuZGVySW5jb21lRGVncmVlKQ0KDQpHZW5kZXJJbmNvbWVEZWdyZWUkR2VuZGVyIDwtIGFzLmZhY3RvcihHZW5kZXJJbmNvbWVEZWdyZWUkR2VuZGVyKQ0KDQpHZW5kZXJJbmNvbWVEZWdyZWUkRGVncmVlIDwtIGFzLmZhY3RvcihHZW5kZXJJbmNvbWVEZWdyZWUkRGVncmVlKQ0KDQpHZW5kZXJJbmNvbWVEZWdyZWUkTWVkaWFuLkluY29tZSA8LSBhcy5pbnRlZ2VyKEdlbmRlckluY29tZURlZ3JlZSRNZWRpYW4uSW5jb21lKQ0KDQpzdHIoR2VuZGVySW5jb21lRGVncmVlKQ0KDQoNCg0KDQojSW5pdGlhbCBsb29rIGF0IHRoZSBkYXRhDQoNCmhlYWQoR2VuZGVySW5jb21lRGVncmVlKQ0KDQpoZWFkKEdlbmRlckluY29tZURlZ3JlZVtHZW5kZXJJbmNvbWVEZWdyZWUkRGVncmVlID09ICJNYXN0ZXJzIixdKQ0KDQpUYWJsZUluY29tZURlZ3JlZSA8LSByYmluZChoZWFkKEdlbmRlckluY29tZURlZ3JlZSw0KSwgIi4uLiIsIGhlYWQoR2VuZGVySW5jb21lRGVncmVlW0dlbmRlckluY29tZURlZ3JlZSREZWdyZWUgPT0gIk1hc3RlcnMiLF0sMiksIHRhaWwoR2VuZGVySW5jb21lRGVncmVlW0dlbmRlckluY29tZURlZ3JlZSREZWdyZWUgPT0gIk1hc3RlcnMiLF0sMiksICIuLi4iLCB0YWlsKEdlbmRlckluY29tZURlZ3JlZSw0KSkNCg0Ka2FibGUoVGFibGVJbmNvbWVEZWdyZWUsDQogICAgICBjYXB0aW9uID0gIlRhYmxlIDMuMTogSW5pdGlhbCBsb29rIGF0IGhvdyBvdXIgZGF0YSBpcyBsYWlkIG91dC4gUHJvdmlkaW5nIEluY29tZSBkYXRhIGZvciBib3RoIEdlbmRlcnMgYW5kIDMgZGlmZmVyZW50IGRlZ3JlZSB0eXBlcyBpbiB0aGUgVVMgZnJvbSAxOTkxIC0gMjAyMi4gVGhlIEluY29tZSBpbiB0aGlzIGRhdGFzZXQgYWNjb3VudHMgZm9yIGluZmxhdGlvbiBhbmQgaXMgaW4gMjAyMiBEb2xsYXJzICgkKS4iKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIikgJT4lDQogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBmb250X3NpemUgPSAxNSkNCg0KDQoNCiNTdW1tYXJ5IFN0YXRpc3RpY3MgVHdvIFdheQ0KDQpTdW1tYXJ5U3RhdHNUYWJsZSA8LSBkZXNjcmliZUJ5KEdlbmRlckluY29tZURlZ3JlZSRNZWRpYW4uSW5jb21lLCBncm91cCA9IEdlbmRlckluY29tZURlZ3JlZSRHZW5kZXIgOiBHZW5kZXJJbmNvbWVEZWdyZWUkRGVncmVlLCBtYXQgPSBUKQ0KDQpLYWJsZVN0YXRzVGFibGUgPC0gYXMuZGF0YS5mcmFtZShyYmluZCgoU3VtbWFyeVN0YXRzVGFibGUkZ3JvdXAxKSwoU3VtbWFyeVN0YXRzVGFibGUkbiksKFN1bW1hcnlTdGF0c1RhYmxlJG1lYW4pLChTdW1tYXJ5U3RhdHNUYWJsZSRzZCksKFN1bW1hcnlTdGF0c1RhYmxlJG1lZGlhbiksKFN1bW1hcnlTdGF0c1RhYmxlJG1pbiksKFN1bW1hcnlTdGF0c1RhYmxlJG1heCksKFN1bW1hcnlTdGF0c1RhYmxlJHJhbmdlKSwoU3VtbWFyeVN0YXRzVGFibGUkc2tldyksKFN1bW1hcnlTdGF0c1RhYmxlJGt1cnRvc2lzKSwoU3VtbWFyeVN0YXRzVGFibGUkc2UpKSkNCg0KbmFtZXMoS2FibGVTdGF0c1RhYmxlKSA8LSBjKCJGOkJhY2hlbG9ycyIsIkY6RG9jdG9yYXRlIiwiRjpNYXN0ZXJzIiwgIk06QmFjaGVsb3JzIiwiTTpEb2N0b3JhdGUiLCJNOk1hc3RlcnMiKQ0KDQpLYWJsZVN0YXRzVGFibGUgPC0gS2FibGVTdGF0c1RhYmxlWy0xLCBdDQoNCkthYmxlU3RhdHNUYWJsZTIgPC0gYXMuZGF0YS5mcmFtZSh0KEthYmxlU3RhdHNUYWJsZSkpDQoNCm5hbWVzKEthYmxlU3RhdHNUYWJsZTIpIDwtIGMoIm4iLCAibWVhbiIsICJzZCIsICJtZWRpYW4iLCAibWluIiwgIm1heCIsICJyYW5nZSIsICJza2V3IiwgImt1cnRvc2lzIiwgInNlIikNCg0KDQoNCiNjaGFuZ2luZyBzb21lIHR5cGVzDQoNCkthYmxlU3RhdHNUYWJsZTIkbiA8LSBhcy5pbnRlZ2VyKEthYmxlU3RhdHNUYWJsZTIkbikNCg0KS2FibGVTdGF0c1RhYmxlMiRtZWFuIDwtIGFzLm51bWVyaWMoS2FibGVTdGF0c1RhYmxlMiRtZWFuKQ0KDQpLYWJsZVN0YXRzVGFibGUyJHNkIDwtIGFzLm51bWVyaWMoS2FibGVTdGF0c1RhYmxlMiRzZCkNCg0KS2FibGVTdGF0c1RhYmxlMiRtZWRpYW4gPC0gYXMubnVtZXJpYyhLYWJsZVN0YXRzVGFibGUyJG1lZGlhbikNCg0KS2FibGVTdGF0c1RhYmxlMiRtaW4gPC0gYXMubnVtZXJpYyhLYWJsZVN0YXRzVGFibGUyJG1pbikNCg0KS2FibGVTdGF0c1RhYmxlMiRtYXggPC0gYXMubnVtZXJpYyhLYWJsZVN0YXRzVGFibGUyJG1heCkNCg0KS2FibGVTdGF0c1RhYmxlMiRyYW5nZSA8LSBhcy5udW1lcmljKEthYmxlU3RhdHNUYWJsZTIkcmFuZ2UpDQoNCkthYmxlU3RhdHNUYWJsZTIkc2tldyA8LSBhcy5udW1lcmljKEthYmxlU3RhdHNUYWJsZTIkc2tldykNCg0KS2FibGVTdGF0c1RhYmxlMiRrdXJ0b3NpcyA8LSBhcy5udW1lcmljKEthYmxlU3RhdHNUYWJsZTIka3VydG9zaXMpDQoNCkthYmxlU3RhdHNUYWJsZTIkc2UgPC0gYXMubnVtZXJpYyhLYWJsZVN0YXRzVGFibGUyJHNlKQ0KDQoNCg0KI0thYmxlIFN0YXRpc3RpY3MgdGFibGUNCg0Ka2FibGUoS2FibGVTdGF0c1RhYmxlMiwgY2FwdGlvbiA9ICJUYWJsZSAzLjI6IFN1bW1hcnkgU3RhdGlzdGljcyBvZiB0aGUgbWVkaWFuIGluY29tZSBkYXRhIGZvciBib3RoIEdlbmRlcnMgYW5kIDMgZGVncmVlIHR5cGVzIGluIHRoZSBVUyBmcm9tIDE5OTEtMjAyMS4iKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KI0Fub3ZhIE1vZGVsIC0gVHdvIHdheQ0KDQpUd29XYXlNMSA8LSBhb3YoTWVkaWFuLkluY29tZSB+IEdlbmRlciAqIERlZ3JlZSwgZGF0YSA9IEdlbmRlckluY29tZURlZ3JlZSkNCg0KVHdvV2F5TTENCg0KDQoNCiNEaWFnbm9zdGljIENoZWNrcw0KDQojaG9tb3NjZWRhc3RpY2l0eSANCg0KcGFyKG1mcm93ID0gYygyLDIpKQ0KDQpwbG90KFR3b1dheU0xKQ0KDQpwYXIobWZyb3cgPSBjKDEsMSkpDQojRmlndXJlIDMuMTouLi4NCg0KDQojTm8gbW9yZSB0aGFuIDMgdGltZXMgc21hbGxlc3QsIGxvb2tzIGZpbmUgaGVyZQ0KDQoNCg0KI05vcm1hbCBEaXN0cmlidXRpb24gb2YgcmVzaWR1YWxzDQoNClJlc19FcHNpbG9uIDwtIFR3b1dheU0xJHJlc2lkdWFscw0KDQpzaGFwaXJvLnRlc3QoUmVzX0Vwc2lsb24pDQoNCmdncGxvdChHZW5kZXJJbmNvbWVEZWdyZWUsIGFlcyh4ID0gUmVzX0Vwc2lsb24pKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyh5PS4uZGVuc2l0eS4uKSwNCiAgICAgICAgICAgICAgICAgY29sb3VyID0gMSwgZmlsbCA9ICJ3aGl0ZSIsIGJpbnMgPSAxNCkgKw0KICBnZW9tX2RlbnNpdHkobHdkID0gMSwgY29sb3VyID0gNCwgZmlsbCA9IDQsIGFscGhhID0gMC4yNSkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsICB2anVzdCA9IC01KSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgdmp1c3QgPSA1LCBoanVzdCA9IDAuNiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCB2anVzdCA9IDUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIikpICsNCiAgeGxhYigiUmVzaWR1YWxzIikgKw0KICB5bGFiKCJEZW5zaXR5IikgKw0KICBsYWJzKHRpdGxlID0gZXhwcmVzc2lvbih1bmRlcmxpbmUoIkhpc3RvZ3JhbSBvZiBSZXNpZHVhbHMgfCBUd28gV2F5IEFOT1ZBIE1vZGVsIDEiKSkpDQojRmlndXJlIDMuMg0KDQojUmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZA0KDQoNCg0KDQojQW5hbHl6aW5nIHRoZSBkYXRhDQoNCmFub3ZhKFR3b1dheU0xKQ0KDQoNCg0KDQoNCg0KI0ludGVyYWN0aW9uIGJldHdlZW4gdmFyaWFibGVzDQoNCnBsb3QoYWxsRWZmZWN0cyhUd29XYXlNMSksIHlsYWI9eyJNZWRpYW4gSW5jb21lICgkKSJ9LG1haW49eyJFZmZlY3QgUGxvdCBvZiBNZWRpYW4gSW5jb21lICgkKSJ9LCBsd2QgPSAyLCBsdHkgPSA1LCBtdWx0aWxpbmUgPSBULCBydWcgPSBULCBjb2xvcnMgPSBjKCJSZWQiLCAiRGVlcFNreUJsdWUiKSkNCiNGaWd1cmUgMy4zOi4uLg0KICANCg0KI0Fub3RoZXINCg0KVHdvV2F5UGxvdCA8LSBnZ2VmZmVjdChUd29XYXlNMSwgdGVybXMgPSBjKCJHZW5kZXIiLCAiRGVncmVlIikpDQoNCnBsb3QoVHdvV2F5UGxvdCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gYygiRmVtYWxlIiwgIk1hbGUiKSwgYnJlYWtzID0gYygxLDIpKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgIHZqdXN0ID0gLTQpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCB2anVzdCA9IDYpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgdmp1c3QgPSA2KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpKSArDQogIGxhYnModGl0bGUgPSBleHByZXNzaW9uKHVuZGVybGluZSgiUHJlZGljdGVkIFZhbHVlcyBvZiBNZWRpYW4gSW5jb21lICgkKSIpKSkgKw0KICB5bGFiKCJNZWRpYW4gSW5jb21lICgkKSIpICsNCiAgeGxhYigiR2VuZGVyIikNCiNGaWd1cmUgMy40Oi4uLg0KDQoNCg0KDQoNCiNUdWtleSBIU0QNCg0KI1Rlc3QgMSAtIFBvc3QgSG9jIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gR2VuZGVycyB3aXRoaW4gRGVncmVlcw0KDQp0MSA8LSB0ZXN0SW50ZXJhY3Rpb25zKFR3b1dheU0xLCBwYWlyd2lzZSA9ICJHZW5kZXIiLCBmaXhlZCA9ICJEZWdyZWUiLCBhZGp1c3RtZW50ID0gImhvbG0iKQ0KDQp0MSRgUHIoPkYpYCA8LSBhcy5udW1lcmljKHQxJGBQcig+RilgKQ0KDQp0MSRgUHIoPkYpYCA8LSBmb3JtYXRDKHQxJGBQcig+RilgLCBmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDIpDQoNCmthYmxlKHQxLCBjYXB0aW9uID0gIlRhYmxlIDMuMzogUGFpcndpc2UgdGVzdHMgdG8gdGVzdCBmb3IgaW50ZXJhY3Rpb24gYmV0d2VlbiBHZW5kZXJzIHdpdGhpbiBEZWdyZWUgdHlwZSAoYWRqdXN0bWVudCA9IEhvbG1zIHRlc3QpLiIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lDQogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBmb250X3NpemUgPSAxNSkNCg0KDQoNCiNUZXN0IDIgLSBQb3N0IEhvYyB0ZXN0IGZvciBkaWZmZXJlbmNlcyBiZXR3ZWVuIERlZ3JlZXMgd2l0aGluIEdlbmRlcnMNCg0KdDIgPC0gdGVzdEludGVyYWN0aW9ucyhUd29XYXlNMSwgcGFpcndpc2UgPSAiRGVncmVlIiwgZml4ZWQgPSAiR2VuZGVyIiwgYWRqdXN0bWVudCA9ICJob2xtIikNCg0KdDIkYFByKD5GKWAgPC0gYXMubnVtZXJpYyh0MiRgUHIoPkYpYCkNCg0KdDIkYFByKD5GKWAgPC0gZm9ybWF0Qyh0MiRgUHIoPkYpYCwgZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAyKQ0KDQprYWJsZSh0MiwgY2FwdGlvbiA9ICJUYWJsZSAzLjQ6IFBhaXJ3aXNlIHRlc3RzIHRvIHRlc3QgZm9yIGludGVyYWN0aW9uIGJldHdlZW4gRGVncmVlIHR5cGUgd2l0aGluIEdlbmRlcnMgKGFkanVzdG1lbnQgPSBIb2xtcyB0ZXN0KS4iKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KYGBgDQoNCiMjIyMgQ29kZSBQYXJ0IDQ6DQoNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0iaGlkZSIsIGV2YWwgPSBGfQ0KI1BhY2thZ2VzDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KHZjZCkNCg0KDQojRGF0YQ0KRW1wU3RhdHVzR2VuZGVyIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9lZHJlbi9PbmVEcml2ZS9EZXNrdG9wL0RhdGEgQW5hbHlzaXMvUiBXb3JraW5nIERpcmVjdG9yeS9GaW5hbCBQcm9qZWN0IEFzc2lnbm1lbnQvRGF0YXNldHMvRGF0YVNldHMvRW1wU3RhdHVzR2VuZGVyXzI1YW5kT3ZlckJhY2hlbG9yc09ySGlnaGVyLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnM9VFJVRSkNCg0KI0NsZWFuDQoNCm5hbWVzKEVtcFN0YXR1c0dlbmRlcikgPC0gYygiWWVhciIsICJRIiwgIkVtcC5TdGF0dXMiLCAiR2VuZGVyIiwgIlRvdGFsLkNvdW50IikNCg0KDQojSW5pdGlhbCBMb29rIGF0IG91ciBEYXRhDQoNCmhlYWQoRW1wU3RhdHVzR2VuZGVyKQ0KDQp0YWlsKEVtcFN0YXR1c0dlbmRlcikNCg0KVGFibGVFbXBHZW5kZXIxIDwtIHJiaW5kKGhlYWQoRW1wU3RhdHVzR2VuZGVyKSwgIi4uLiIsIHRhaWwoRW1wU3RhdHVzR2VuZGVyKSkNCg0KVGFibGVFbXBHZW5kZXIxDQoNCmthYmxlKFRhYmxlRW1wR2VuZGVyMSwgcm93Lm5hbWVzID0gRiwgY2FwdGlvbiA9ICJUYWJsZSA0LjE6IEJMUyBCZXRhIExhYnMgZGF0YSByZWdhcmRpbmcgVG90YWwgRW1wbG95ZWQvVW5lbXBsb3llZCBmcm9tIDIwMTUtMjAyMSAoUTEtUTQpIGJ5IEdlbmRlci4gVGhlIGNvdW50IG9mIHRoaXMgZGF0YSBpcyBpbiB0aG91c2FuZHMgKEspIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KI1NlbGVjdCBSYW5kb20gWWVhciBhbmQgUQ0KDQpzZWxlY3RlZF95ZWFyIDwtIHNhbXBsZSh1bmlxdWUoRW1wU3RhdHVzR2VuZGVyJFllYXIpLCAxKQ0KDQpzZWxlY3RlZF9xdWFydGVyIDwtIHNhbXBsZSh1bmlxdWUoRW1wU3RhdHVzR2VuZGVyJFEpLCAxKQ0KDQpSYW5kb21TYW1wbGUgPC0gRW1wU3RhdHVzR2VuZGVyICU+JQ0KICBmaWx0ZXIoWWVhciA9PSBzZWxlY3RlZF95ZWFyLCBRID09IHNlbGVjdGVkX3F1YXJ0ZXIpDQoNCg0KDQojTG9va2luZyBhdCBvdXIgU2FtcGxlDQoNCmthYmxlKFJhbmRvbVNhbXBsZSwgcm93Lm5hbWVzID0gRiwgY2FwdGlvbiA9ICJUYWJsZSA0LjI6IFJhbmRvbSBZZWFyIGFuZCBRIHNlbGVjdGVkIHRvIGdlbmVyYXRlIGEgU2FtcGxlIGZyb20gb3VyIG9yaWdpbmFsIGRhdGEgZnJvbSBCTFMgQmV0YSBMYWJzIGRhdGEuIFNob3dpbmcgVG90YWwgRW1wbG95ZWQvVW5lbXBsb3llZCBieSBHZW5kZXIuIFRoZSBjb3VudCBvZiB0aGlzIGRhdGEgaXMgaW4gdGhvdXNhbmRzIChLKSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lDQogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBmb250X3NpemUgPSAxNSkNCg0KDQoNCiNDb250aW5nZW5jeSBUYWJsZQ0KDQpHcm91cGVkRGF0YSA8LSB4dGFicyhUb3RhbC5Db3VudCB+IEVtcC5TdGF0dXMgKyBHZW5kZXIsIGRhdGEgPSBSYW5kb21TYW1wbGUpDQoNCkNvbnRpbmdlbmN5VGFibGUgPC0gYXMuZGF0YS5mcmFtZS5tYXRyaXgoR3JvdXBlZERhdGEpDQoNCmthYmxlKENvbnRpbmdlbmN5VGFibGUsIGNhcHRpb24gPSAiVGFibGUgNC4zOiAiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpDQoNCg0KDQoNCiNJbml0aWFsIHZpc3VhbGl6YXRpb24NCg0KZ2dwbG90KGRhdGEgPSBSYW5kb21TYW1wbGUsIGFlcyh4ID0gR2VuZGVyLCB5ID0gVG90YWwuQ291bnQsIGZpbGwgPSBFbXAuU3RhdHVzKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArDQogIGdndGl0bGUoIkF0dHJpdGlvbiB8IEpvYiBMZXZlbCAtIE9ic2VydmVkIFZhbHVlcyIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIobmFtZSA9ICJFbXBsb3ltZW50IiwgcGFsZXR0ZSA9ICJEYXJrMiIpICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMikgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCAgdmp1c3QgPSAtNSksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIHZqdXN0ID0gNSwgaGp1c3QgPSAwLjYpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgdmp1c3QgPSA1KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpKSArDQogIHhsYWIoIkdlbmRlciIpICsNCiAgeWxhYigiRnJlcXVlbmN5IChpbiB0aG91c2FuZHMgLSBrKSIpICsNCiAgbGFicyh0aXRsZSA9IGV4cHJlc3Npb24odW5kZXJsaW5lKCJDb3VudHMgb2YgRW1wbG95bWVudCBieSBHZW5kZXIgaW4gdGhlIFVTIikpKQ0KI0ZpZ3VyZSA0LjE6Li4gKipOT1QgVVNFRCoqDQoNCg0KI1Rlc3QNCg0KVGVzdDEgPC0gY2hpc3EudGVzdChDb250aW5nZW5jeVRhYmxlLCBjb3JyZWN0ID0gRkFMU0UpDQoNClRlc3QxDQoNCiNOID4gNDAsIG5vdCB1c2luZyBZYXRlcyBDb3JyZWN0aW9uDQoNCg0KDQojI0V4cGVjdGVkIFZhbHVlcw0KDQprYWJsZShyb3VuZChUZXN0MSRleHBlY3RlZCwzKSwgY2FwdGlvbiA9ICJUYWJsZSA0LjQ6IEV4cGVjdGVkIFZhbHVlcyBvZiBvdXIgcmFuZG9tIHNhbXBsZSBvZiB0aGUgcG9wdWxhdGlvbiBkYXRhLiBUaGUgY291bnQgb2YgdGhpcyBkYXRhIGlzIGluIHRob3VzYW5kcyAoSykiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgZm9udF9zaXplID0gMTUpICU+JQ0KICBhZGRfaGVhZGVyX2Fib3ZlKGMoIkVtcGxveW1lbnQiID0gMSwgIkV4cGVjdGVkIFZhbHVlcyIgPSAyKSkNCg0KI01vcmUgdGhhbiAyMCUgb2YgZXhwZWN0ZWQgdmFsdWVzIGFyZSBub3QgbGVzcyB0aGFuIDUuIHdvbid0IHVzZSBmaXNoZXINCg0KDQoNCg0KI1RhYmxlIGZvciBEaXNjdXNzaW9uDQoNCiNPYnNlcnZlZCBWYWx1ZXMsIEV4cGVjdGVkLCBDaGkgU3F1YXJlZCBDb21wb25lbnRzIGluIDEgdGFibGUNCg0KbWVyZ2VkX3RhYmxlcyA8LSBjYmluZChUZXN0MSRvYnNlcnZlZCwgcm91bmQoVGVzdDEkZXhwZWN0ZWQsMyksIHJvdW5kKFRlc3QxJHJlc2lkdWFsc14yLDQpKQ0KDQprYWJsZShtZXJnZWRfdGFibGVzLCBjYXB0aW9uID0gIlRhYmxlIDQuNTogT2JzZXJ2ZWQgVmFsdWVzLCBFeHBlY3RlZCBWYWx1ZXMgYW5kIHRoZSBDaGktU3F1YXJlIENvbXBvbmVudHMgb2Ygb3VyIHJhbmRvbSBzYW1wbGUgb2YgdGhlIHBvcHVsYXRpb24gZGF0YS4gVGhlIGNvdW50IG9mIHRoaXMgZGF0YSBpcyBpbiB0aG91c2FuZHMgKEspIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUNCiAgcm93X3NwZWMoMCwgYm9sZCA9IFQsIGZvbnRfc2l6ZSA9IDE1KSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDEsICJPYnNlcnZlZCBWYWx1ZXMiID0gMiwgIkV4cGVjdGVkIFZhbHVlcyIgPSAyLCAiQ2hpLVNxdWFyZWQgQ29tcG9uZW50cyIgPSAyKSkNCg0KDQojVGVzdCBvdXRwdXQNCg0KVGVzdDENCg0KDQoNCiNWaXN1YWxpc2F0aW9uLi4uIEZvciBEaXNjdXNzaW9uLiBDb3JycGxvdA0KDQoNCmFzc29jaWF0aW9uX3Bsb3QgPC0gYXNzb2MoR3JvdXBlZERhdGEsIHNoYWRlID0gVCwgbGFzID0gMywgbWFpbiA9ICJBc3NvY2lhdGlvbiBQbG90IG9mIEdlbmRlciBhbmQgRW1wbG95bWVudCBTdGF0dXMiKQ0KDQoNCiNGaWd1cmU6IDQuMjogQXNzb2NpYXRpb24gUGxvdCBzaG93aW5nIFBlYXJzb24gcmVzaWR1YWxzIGZvciBvdXIgQ2hpIFNxdWFyZWQgdGVzdCBvZiB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBHZW5kZXIgYW5kIEVtcGxveW1lbnQgU3RhdHVzLiANCiMgQSBwb3NpdGl2ZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIEdlbmRlciBhbmQgRW1wbG95bWVudCBzdGF0dXMgaXMgaW5kaWNhdGVkIHdpdGggYSBiYXIgYWJvdmUgdGhlIGRvdHRlZCBsaW5lLCANCiMgQSBuZWdhdGl2ZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIEdlbmRlciBhbmQgRW1wbG95bWVudCBzdGF0dXMgaXMgaW5kaWNhdGVkIHdpdGggYSBiYXIgYmVsb3cgdGhlIGRvdHRlZCBsaW5lLg0KIyBUaGUgc3RyZW5ndGggb2YgdGhlIGFzc29jaWF0aW9uIGlzIGluZGljYXRlZCBieSB0aGUgc2l6ZSBvZiB0aGUgYmFyLg0KDQpgYGANCg==