Introduction

Introduction to Topic

You may have probably seen people lifting different weights in the gym. But why do people even lift? There are numerous reasons for lifting but one of the most common reasons is to become stronger, while others do lifting for a competition such as powerlifting. Powerlifting is a strength sport that has been part of the Olympics Games since 1896 and consists of three attempts to achieve the maximum weight on each of the three lifts: squat, bench press, and deadlift. During these competitions, some participants lift heavier weights than others. So we wonder, what accounts for this difference in a competitor’s performance? Could it be merely because of biological factors? Or are there any other factors that might impact a person’s ability to lift a certain weight such as their age or the equipment that they use?

Research Questions

This research will explore the aspects that enable people to lift heavier weight. In particular, we aim to answer the following research question: What aspects of a lifter makes them the most successful in lifting weights? Does the equipment used affect the weight lifted by lifters? Our initial prediction is that a person’s physiology is one of the determining factors in lifting weights. Hence, we will look at how body weight and sex assigned at birth affect the total weight lifted by an individual. Furthermore, we are keen to find out the role with which different equipment plays in assisting a weightlifter performance.

Data

Context

The original Powerlifting dataset contains 1,423,354 cases, each indicating a single powerlifter. This dataset is a snapshot of the OpenPowerlifting database as of April 2019. Moreover, this dataset pertains to the results of powerlifting competition in three barbell lifts: Squat, Bench, and Deadlift. Additionally, the dataset incorporates relevant variables corresponding to the competitor’s personal information such as their name, age, body weight in kilograms, the equipment they used during the competition, as well as their final placement in competition.

Our research aims at exploring which variables might have a higher effect on the total weight lifted by a participant. Thus, we will use total kilograms lifted by a participant, which is the sum of the best three attempts for each participant in the three barbell lifts mentioned above. Furthermore, we will use one quantitative variable as our explanatory variable, the body weight in kilograms. Additionally, we will also explore two categorical variables, the participants’ sex assigned a birth (Male and Female), and we will also consider the equipment they used, which is a categorical variable that tells us what they used during competitions which include wraps, raw, single-ply, and multi-ply. To gain a better understanding of the equipment, it is worth explaining what each category level entails. According to the website Barbend, raw powerlifting means lifting with little to no equipment. On the other hand, single-ply means the suit has one layer of fabric whereas multi-ply means two layers or more. Also, wraps aim to support a lifter’s joints (i.e knees).

It should be emphasized that this global dataset contains the recorded competition from September 4, 1964 to April 19, 2019. As mentioned before, this is a compilation of data performed by OpenPowerlifting, whose main objective is to create a public domain archive of powerlifting history. Lastly, the data can be accessed on the Kaggle website under the name of “Powerlifting Database”.

Cleaning

Since we are analyzing the total weights lifted for all three competitions - squats, bench presses, and deadlifts - we removed those lifters who were unable to fully finish all their tasks by filtering out those with missing data, since they would have skewed the results. At the same time, the original dataset contained 5 different categories for the ‘Equipment’ variable: straps, raw, single-ply, multi-ply, and wrapped. However, the ‘straps’ category was largely insufficient, and we removed it since we did not feel as if there was a large enough sample size to make accurate conclusions. We also decided to only include those competitors who were confirmed to have been tested for drugs, so as to ensure the most accurate results.

Lastly, the original dataset contained many problems regarding age that were concerning. There were many outliers for Age and TotalKg, that had described many young children lifting unusual weights, but also winning awards. At the same time, there were many data observations that had contrary values for Age and AgeClass, that were mostly found in the younger ages. We believe, then, that this was simply a mistake, where typos and similar errors created inconsistencies. We also found similar errors in the older ages of the data set. As such, in order to make the data more accurate and remove outliers, we decided to filter out all data observations that were outside of the age ranges between 16 and 50 years old. After filtering out all the data that we were originally working with, only roughly 300,000 of the original roughly 1.5 million data observations were left to be analyzed. While this was worrisome because we thought we removed too many, we later came to the conclusion that this sample size makes more sense, as it removes extreme age differences that created outliers, the errors that were occurring.

Linear Regression

Exploratory Data Analysis

For our initial visualization, we decided to look at how the weight of the participants is correlated to the total weight that they were able to successfully lift considering the equipment that they used in order to complete the lift. In this visualization, we can see that there is indeed a trend for all equipment types that the more a person weighs, the more they can seemingly lift. This trend is most obvious to those lifters who used multi-ply equipment when looking solely at the scatterplot. However, while the other equipment types seem to have weaker relations, this trend is still clearly present and seems to have very similar slopes for all equipment types, but different intercepts. At the same time, we faceted on the basis of biological sex. We found that there is also a linear relationship between the weights of the lifters and weights that they were able to successfully lift. In the facets for ‘Sex’, we found seemingly contrary results than we did for equipment types; males and females appear to have different slopes for the linear models, but have more similar y-intercepts.

Model Creation

We are interested in discovering the character and strength of the association between different factors and the total weight they can lift for their best attempts at Squat, Dead-lift, and Bench combined. Therefore, we decided to use a linear regression model. For our big model, we want to observe the correlation between biological factors, specifically a person’s body weight as well as their biological sex, and the total amount of the total amount of kilograms lifted in the three categories.

\[[TotalKg | Bodyweight,SexM] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM\]

For our larger model, we want to answer the other side of our research: Is it only biological factors that have an influence on a weight lifter’s performance? By introducing a non-biological variable that we predict may affect the amount of weight lifted in 3 categories: Equipment, we are attempting to see if there is a statistical significance that Equipment plays in our response variable: TotalKg. Hence, one of our larger models is as follows:

\[[TotalKg | Bodyweight,Sex,Equipment] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM + \\ \beta_3*Equipment_{raw}+\beta_4*Equipment_{single-ply}+\beta_5*Equipment_{wraps} \]

Furthermore, in our Exploratory Data Analysis, we observe a difference between the slope for female and male weightlifter across all equipment. More specifically, the slope for female is considerably steeper than that for male within each equipment category. This suggests that the value of the change in total weight lifted for each kilogram of body weight when it comes to female weightlifters is lower than when it comes to male weightlifters for each type of equipment we are considering. Therefore, we suspect that there is an effect modification in which \(Sex\) can modify the effect of \(Equipment\) on the outcome variable \(TotalKg\), or the total weight in kilograms lifted in 3 categories for a weightlifter. Therefore, the second larger model we consider is as follows:

\[[TotalKg | Bodyweight,Sex,Equipment] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM + \\ \beta_3*Equipment_{raw}+\beta_4*Equipment_{single-ply}+\beta_5*Equipment_{wraps} \\ \beta_6*Equipment_{raw}*SexM+\beta_7*Equipment_{single-ply}*SexM+ \\\beta_8*Equipment_{wraps}*SexM \]

Fitted Model

The table below shows the fitted model for our small nested model:

Table 1: Fitted Model 1 (Estimates, Confidence Intervals, P-values)
Coefficients Estimates Standard_Errors Test_Statistics P.value Confindence_interval
Intercept 108.65 0.77 141.96 0 (107.15, 110.15)
SexMale 181.39 0.48 378.05 0 (180.45, 182.33)
Bodyweight 3.30 0.01 329.05 0 (3.28, 3.32)

The table below shows the fitted model for our larger model without an interaction term:

Table 2: Fitted Model 2 (Estimates, Confidence Intervals, P-values)
Coefficients Estimates Standard_Errors Test_Statistics P.value Confindence_interval
Intercept 164.28 2.35 69.87 0.00 (159.68, 168.89)
SexMale 170.56 0.45 381.40 0.00 (169.68, 171.43)
Bodyweight 3.44 0.01 369.29 0.00 (3.42, 3.46)
EquipmentRaw -98.16 2.25 -43.71 0.00 (-102.56, -93.75)
EquipmentSingle-ply -15.76 2.25 -7.02 0.00 (-20.16, -11.36)
EquipmentWraps -98.36 2.37 -41.4 0.00 (-103.01, -93.72)

The table below shows the fitted model for our larger model with an interaction term:

Table 3: Fitted Model 3 (Estimates, Confidence Intervals, P-values)
Coefficients Estimates Standard_Errors Test_Statistics P.value Confindence_interval
Intercept 144.77 5.85 24.75 0.00 (133.30, 156.24)
Bodyweight 3.44 0.01 368.98 0.00 (3.42, 3.46)
SexMale 193.61 6.30 30.72 0.00 (181.26, 205.96)
EquipmentRaw -77.12 5.83 -13.22 0.00 (-88.56, -65.69)
EquipmentSingle-ply 2.71 5.84 0.46 0.64 (-8.74, 14.15)
EquipmentWraps -84.25 6.02 -14.00 0.00 (-96.05, -72.46)
SexM:EquipmentRaw -25.15 6.32 -3.97 0.00 (-37.54, -12.76)
SexM:EquipmentSingle-ply -21.46 6.33 -3.39 0.00 (-33.85, -9.06)
SexM:EquipmentWraps -15.43 6.55 -2.35 0.02 (-28.27, -2.58)

Model Interpretation

Estimates

As previously stated, our research intends to explore not only physiological factors of a competitor, but also other external factors that go into the competition. Based on our exploratory data analysis, we suspect that the model in which there is an interaction term between Sex and Equipment. Therefore, we will focus mainly on the fitted model 3. Through an examination of the slope coefficients for the variable SexMale, we can observe that the estimated average total kilograms lifted by a competitor whose sex assigned at birth is male is 193.61 kg higher than a lifter whose sex assigned at birth is female, holding body weight and equipment constant. Additionally, while interpreting the coefficient of the variable BodyweightKg we can observe that the estimated increase in the average total kilograms lifted by a competitor is 3.44 kg for a 1 unit increase in a lifter’s body weight, holding equipment and sex constant.

By examining the slope coefficients for the variable Equipment, we can see that the estimate suggests that lifters who do not wear any equipment, considered as “raw” under this category, lift, on average, 77.12 kg less than lifters that use multi-ply equipment (our reference category), holding all other variables constant. Likewise, the slope coefficient of equipment single-py suggests that lifters who use single-ply equipment can lift, on average, 2.71 kg more than lifters who use multi-ply equipment, holding other variables constant. Lastly, the slope coefficient of equipment wraps indicates that lifters who use wraps lift, on average, 84.25 kg less than lifters who use multi-ply equipment.

Furthermore, when we take a closer look at the values of slope coefficients for the interaction terms, we could see the degree to which Sex modifies the effect of Equipment has on TotalKg. For example, 25.15 is the difference in the estimated “effect” between a weightlifter using multi-ply equipment and a weightlifter using no equipment (EquipmentRaw), in which the effect is the 1 unit change in the Sex variable—from female to male. In other words, while a female weightlifter with no equipment is expected to lift, on average, 77.12kg less than when they use multi-ply equipment, a male weightlifter with no equipment is expected to lift, on average, (77.12+25.15) or 102.27kg less than a female using multi-ply equipment.

In summary, all fitted models suggest that there seems to be a positive relationship between our predictor variables, body weight and sex assigned at birth and our outcome variable, total kilograms lifted. These results are consistent with our initial predictions when considering which variables to use, especially sex assigned at birth and body weight. Furthermore, from the model we can see the average differences in total kilograms lifted while comparing each equipment category to the multi-ply equipment as our reference category. Certainly, lifters who used raw and wraps as equipment seem to have a higher average difference in the total kilograms lifted as compared to those who used multi-ply as equipment. Hence, we can glimpse from the model that there seems to be some sort of effect in our outcome variable across different equipment used. Likewise, with regards to fitted model 3, we observe that sex assigned at birth, to a certain degree, affects how the use of equipment influences the total amount lifted (in kilograms).

Confidence Intervals

As part of the interpretation process, we decided to look at our 95 % confidence intervals to better assess the statistical significance of our predictor variables and our outcome variable. For each additional 1 kg increase in body weight, we would expect an average increase of 3.42 to 3.46 kilograms in weight lifted. We are unsure whether this interval contains the true population average change in kilograms lifted per 1 kg increase in body weight, but we trust that 95% of samples will have intervals that contain the true change.

For a lifter who does not wear any equipment, we expect an average decrease of 65.69 to 88.56 kilograms in weight lifted. We expect that for competitors that use single-ply equipment, there would be an average decrease of 0 to 8.74.kilograms in weight lifted and an average increase of weight lifted from 0 to 14.15. Given that 0 is part of our confidence interval, it suggests that there might not be a relationship between lifters that use single-ply equipment and the total kilograms lifted. Lastly for lifters that use wraps, we expect an average decrease of 72.46 to 96.05 kilograms in weight lifted. For male lifters that do not use any equipment, we expect on average that the effect modification of sex on equipment is between -37.54 to -12.76. This means that we would expect male lifters that do not use any equipment to lift 12.76 to 77.54 kg lower than females that do not use any equipment. We expect competitors that are males and use single-ply to lift on average 9.06 to 33.85 kilograms lower than females that use single-ply. Lastly, we expect male participants that use wraps to lift on average 2.58 to 28.27 kilograms lower than females lifters that use wraps.

For all of these observations, we are confident in the interval construction process because we expect 95% of samples to lead to intervals that contain the true population parameter value. However, we are not sure if our particular interval from our sample contains that true population parameter value or not.

P-value and Test Statistic(s)

We also looked at the test statistic of this model to know how far the observed data is from the null hypothesis. The test statistic is a discrepancy measure where large values indicate higher discrepancy with the null hypothesis. The test statistic is the distance from the null hypothesis value of 0 (the null value) in terms of standard errors. Our model has a test statistic of 368.98, 30.72, -13.22, 0.46, -14.00, -3.97, -3.39, -2.35 for respectively Bodyweight, SexMale, EquipmentRaw, EquipmentSingleply, EquipmentWraps, SexM:EquipmentRaw, SexM:EquipmentSingle-Ply, and SexM:EquipmentWraps coefficients. Besides the coefficient EquipmentSingleply, all the other coefficients have a large test statistic which suggests that our data (and our estimate) is discrepant with what the null hypothesis proposes because our estimate is quite far away from the null value in standard error units. However, for our EquipmentSingle-Ply coefficient, we have a test statistic of -0.46 which suggests that there might not be any relationship between EquipmentSingle-Ply and the average difference in total kilograms lifted by a competitor that uses multi-ply equipment.

Moreover, we used the p-value to delve deeper into the statistically significant relationship between each of our explanatory variables and our outcome variable. The p-value for our coefficients measures the probability of observing a test statistic as or more extreme than the one we saw, if our null hypothesis holds. To illustrate, we could perform a hypothesis test for each slope coefficient associated with each predictor variable, in relation to the outcome variable, yet we decided to run only two hypothesis tests to make this process less repetitive.

Firstly, we wanted to explore the first part of our research questions, which relates to the physiological variables that might have an effect on the ability to lift higher weight. One of the variables in our model is Bodyweight, which corresponds to a lifter’s body weight in kilograms. Therefore, we want to test whether body weight has a statistically relationship with the total weight lifted by a competitor. We started by stating our hypotheses as follow: \[H_0: \beta_1 = 0 \text{ vs } H_A: \beta_1 \neq 0,\]

The null hypothesis for the Bodyweight variable is that its slope coefficient is equal to zero, suggesting that there is no relationship between a lifter’s body weight and the total weight lifted (in kilograms), after accounting for the other variables in our model.

The alternative hypothesis for the Bodyweight variable is that its slope coefficient is not equal to zero, suggesting that there is a relationship between a lifter’s body weight and the total weight lifted (in kilograms), after accounting for the other variables in our model.

By setting a significance threshold of 0.05, we can see that the p-value associated with the variable Bodyweight is equal to zero, which is less than our threshold value of 0.05. Therefore, we can reject our null hypothesis in favor of our alternative hypothesis given that we have enough evidence to suggest that there is a statistically significant relationship between the variable Bodyweight and the outcome variable, after controlling for the other variables.

Moreover, we wanted to investigate the second part of our research questions which pertains to external factors that might have an effect on the total weight lifted, rather than focusing merely on physiological factors. In particular, one of the variables is the Single-Ply Equipment. Therefore, we can test whether there is statistically significant relationship between the predictor variable corresponding to the Single-Ply Equipment and the outcome variable total weight lifted. The hypothesis test is as follow:

\[H_0: \beta_4 = 0 \text{ vs } H_A: \beta_4 \neq 0,\]

The null hypothesis for the EquipmentSingle-ply variable is that its slope coefficient is equal to zero, suggesting that there is no statistically difference in total weight lifted between lifters who use single-ply equipment with those who use multi-ply equipment, after accounting for the other variables in our model.

The alternative hypothesis for the EquipmentSingle-ply variable is that its slope coefficient is not equal to zero, suggesting that there is a statistically difference in the total weight lifted between lifters who use single-ply equipment with those who use multi-ply equipment, after accounting for the other variables in our model.

By setting a significance threshold of 0.05, we can see that the p-value associated with the variable EquipmentSingle-ply is equal to 0.64, which is greater than our threshold value of 0.05. Therefore, we fail to reject the null hypothesis since we do not have enough evidence to conclude that there is a statistically significant difference in total weight lifted between lifters who use single-ply equipment with those who use multi-ply equipment, after controlling for the other variables.

Lastly, by performing a hypothesis test for the remaining slope coefficients in our linear regression model, and setting the null hypothesis to be that each slope coefficient is equal to zero or that there is no relationship between the individual predictor variable associated with that coefficient and the total weight lifted, holding all other variables constant. Additionally, the alternative hypothesis is that each slope coefficient is not equal to zero, or that there is a relationship between the individual predictor variable and the total weight lifted, after accounting for the other variables. By setting a threshold of 0.05, we can finalize our conclusions. Interestingly, the rest of the p-values are zero or close to zero Therefore, we can reject the null hypothesis for each slope coefficient in favor of the alternative hypothesis since we have enough evidence that suggests that each predictor variable associated with that coefficient has a statistically significant relationship with the outcome variable, when accounting for the other variables in our model.

Model Evaluation

In order to finalize on a model that best answers our research question as well as reflects our population, we will use these following linear regression tools as the basis of performance criterion to select our final model: exploratory visualization (elaborated above), \(R^2\), residual standard error \(s_e\), and nested test.

R-squared

Table 4: R Squared and Residual Standard Error
Model R_Squared Residual_Standard_Erros
Model 1 0.597 108.92
Model 2 0.654 100.91
Model 3 0.654 100.91

For our model 1, we found that for those observations without equipment, there was a R-squared of 0.597. This means that the regression model explains approximately 59.7% of the variability in the data. In other words, the model 1 is able to account for 59.7% of the variation in the data, while the remaining 40.3% of the variation is unexplained by the model. While this R-squared is not ideal, it does show that there is a large percent of data that is explained. However, for the model 2 with equipment, there was an R-squared of 0.654. As such, the model can explain 65.4% of the variance, leaving 34.6% of the variance unaccounted for. Still, this is not as high of the R-squared that we were expecting. However, there is still a large amount of variability that is explained by the model 2. This becomes more interesting, especially, when looking at model 3 in which we included the interaction variable as well. For this model, the R-squared stayed almost exactly the same, but it increased by 0.0001. As such, for both models 2 and 3, we are able to explain around 67% of the variation for both. When looking at the R-squared for all three models, it is clear that the latter two models that account for the equipment used by the lifters performs better.

We also looked into the residual standard error of all three models. For our model 2, the residual standard error is 100.91, which represents the estimate of the standard deviation of the error term in the regression model. This is simply an estimate of the average distance that the data points fall from the regression line. This residual standard error value shows that on average, the actual values of the response variable TotalKg are expected to deviate from the predicted values by 100-200 kg. For our model 3 that accounts for the interaction term, the residual standard error is also 100.91 compared to that of model 1 (which is 108.92). As such, we can conclude the same as for the R-squared tests, where model 2 and 3, that include the equipment type, have more accuracy–this time is for when it comes to the size of our prediction errors.

Nested F-Test

By using a hypothesis nested F test, we directly compare our 3 models:

\[[TotalKg | Bodyweight,SexM] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM\]
\[[TotalKg | Bodyweight,SexM,Equipment] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM + \\ \beta_3*Equipment_{raw}+\beta_4*Equipment_{single-ply}+ \beta_5*Equipment_{wraps} \]
\[[TotalKg | Bodyweight,Sex,Equipment] = \beta_0 + \beta_1 * Bodyweight +\beta_2 *SexM + \\ \beta_3*Equipment_{raw}+\beta_4*Equipment_{single-ply}+\beta_5*Equipment_{wraps} \\ \beta_6*Equipment_{raw}*SexM+\beta_4*Equipment_{single-ply}*SexM+ \\\beta_5*Equipment_{wraps}*SexM \]

For our first F test between model 1 and model 2:

Null Hypothesis \(H_0 : \beta_{Equipment} = 0\): Our smaller nested model with just \(Bodyweight\) and \(Sex\) is correct; \(Equipment\) does not have an impact on \(TotalKg\) after accounting for \(Bodyweight\) and \(Sex\).

Alternative Hypothesis \(H_A: \beta_{Equipment} \neq 0\): Our smaller model is not correct and our removed variable (\(Equipment\)) has a non-zero slope in the population and, therefore, has an impact on a weightlifter’s performance.

For our second F test between model 2 and model 3:

Null Hypothesis \(H_0 : \beta_{Equipment} = 0\): Our model without an interaction term is correct; \(Sex\) does not have an impact on how \(Equipment\) affects \(TotalKg\).

Alternative Hypothesis \(H_A: \beta_{Equipment} \neq 0\): Our model without an interaction term is not correct and our removed interaction term between \(Sex\) and \(Equipment\) has a non-zero slope in the population and, therefore, has an impact on a weightlifter’s performance.

Below are the results from the 2 F-tests we carried out:

Test statistics: 17.46

For an F Test in a linear regression model, the test statistic is a ratio comparing the sum of squared residuals. This means that \(H_0\) is true if \(F\) ~ 1. Our test statistic when we are comparing between model 1 and model 2 is 17064. When we are comparing between model 2 and model 3, the test statistics is 17.457. Both are rather far from 1 and suggest that model 3 is the most preferable out of the 3 models, but there are no rules for “how far is far”.

P-value: 2.5*10^-11 = 0.000000000025

For a threshold of \(\alpha=0.05\), our p-value for the both F-tests is very much below the threshold (almost close to zero), suggesting that it is very unlikely to have observed a big difference between the two models if the smaller nested model were true. Therefore, we reject both the \(H_0\)’s that the model with only Sex and Bodyweight and the model without an interaction term between Sex and Bodyweight is correct. We are, on the other hand, in favor of model 3 as it fits our data statistically better.

Residuals versus Fitted Values Plot

By examining Figure 2, we can observe the Residuals vs Fitted values of our final model. From the plot we can assess how good our final model can fit our data. The horizontal line at 0 corresponds to the line of perfect fit, in which the predicted values and actual values from the data are equal. Overall, this plot suggests that our final model is a good fit for the data, as the smooth line is, in its majority, close to the line of perfect fit. This indicates that the model is accurately predicting most of the data points. Yet, it is important to note that our model overpredicts the large fitted values (shown by the negative residuals), yet we can observe that these are few data points compared to our large dataset.

Conclusion

General Takeaways

From the results of our model interpretation and evaluation, we can conclude that model 3 performs more preferably than all of our models. Through model 3, it is revealed that although biological factors play an important role in a lifter’s performance, there are other factors such as the equipment that they use that impact their performance. There is a positive relationship between the body weight of a lifter and the total kilograms that they can lift. Furthermore, the sex assigned at birth plays a critical role on how much weight a competitor can lift. Our model found that on average, the estimated increase in the total kg associated with a 1 unit increase in a lifter’s body weight is 3.44 kg for a lifter, holding all other variables constant. Holding body weight and equipment constant, the estimated average total kilograms lifted by a lifter of sex male is 193.61 kg higher than a lifter whose sex assigned at birth is female.

In addition, equipment also plays a critical role in a lifter’s ability to lift heavier weights. According to our model, female lifters that use no equipment are expected to lift on average 77.12 kg less than female lifters that use multi-ply equipment, holding all other variables constant. Likewise, the slope coefficient of equipment wraps indicates that female lifters who use wraps lift, on average, 84.25 kg less than female lifters who use multi-ply equipment. Lastly, female lifters who use single-ply equipment can lift, on average, 2.71 kg more than female lifters who use multi-ply equipment, holding other variables constant.

We also observed from our model that sex has a modification effect on the equipment used. Male Individuals who do not use any equipment competitors are expected to lift on average 25.15 kg less than female lifters that do not use any equipment compared to competitors (109.4 kg less) that use multi-ply equipment. From these observations, we think that biological factors such as the sex assigned at birth of a person, their body weight and other factors such as the equipment that a lifter uses determines a lifter’s performance.

Limitations

As we explained in the data cleaning process, we filtered a significant amount of our cases as there was missing data, or some inconsistencies, which might have arisen during the data compilation process. Although we were left with a significant amount of data, we are uncertain about if all these values accurately represent the actual values or information for each participant. Furthermore, this dataset did not contain other variables that could have been relevant to our research questions, such as the time each participant has been lifting (i.e. years of experience, or the number of competitions), which might have provided further insight into some of the relationships with our outcome variable. We also understand that there were many inconsistencies in each data observation. This comes from the fact that there was not one standardized method of collecting data, as it was up to each competition to record. We have tried to mitigate these effects as much as possible by cleaning the data, but recognize that the data is not perfect.

In addition, this dataset is useful in different domains as it helps to analyze the patterns and trends of powerlifting competitions, and inform the general public. Nevertheless, there are some ethical concerns, in relation to privacy, as it provides the name of each competitor, as well their personal information that might put them in the loop of public scrutiny. Moreover, we are hesitant if the disclosure of this information was consensual. On another note, we acknowledge that our study might reinforce some biases and stereotypes if these results are not well explained and contextualized to the public since our study focuses merely on a lifter’s performance based on the total kilograms they can lift. We also recognize that the R-squared of our models could be considerably higher. While they were somewhat sufficient in explaining variation, there is a relatively large amount of variation that is left unexplained. Future research could build upon this, trying to raise this R-squared test value, and also considering the removal of extreme outliers. To conclude, it would be interesting for further study to explore the statistical relationship of other predictor variables such a lifter’s nutrition, mental factors, and injury history with the total outcome of weight lifted in kilograms, yet these variables are not included in our dataset.

Appendix

Works Cited

Heggeseth, Brianna, Myint, Leslie, and Grinde, Kelsey. STAT 155 Notes. January 15, 2021. https://bcheggeseth.github.io/Stat155Notes/

Siem, Brooke. “Raw vs Equipped Powerlifting.” BarBend, July 10, 2017. https://barbend.com/raw-vs-equipped-powerlifting/

Code Appendix

# Loading libraries
library(tidyverse)
library(NHANES)
library(broom)
library(ggplot2)
library(knitr)
library(dplyr)
#Loading data
power <- read_csv("power.csv")
#Cleaning data
power_clean <- power %>%
  filter(!is.na(Best3SquatKg), 
         !is.na(Best3BenchKg),
         !is.na(Best3DeadliftKg),
         !is.na(Tested), 
         !is.na(Sex),
         !is.na(BodyweightKg),
         Equipment != 'Straps', 
         Age >= 16.0 ) %>%
  select(Sex, 
         Equipment, 
         Age, AgeClass, 
         BodyweightKg, WeightClassKg, 
         Best3SquatKg, Best3BenchKg, Best3DeadliftKg, TotalKg, 
         IPFPoints)
# EDA: Figure 1 : Weight Lifted by Lifters of Different Weights by Sex and the Equipment Used
ggplot(power_clean) +
  geom_point(aes(x = BodyweightKg, y = TotalKg, color = Equipment),
  alpha = 0.5,
  show.legend = FALSE) +
  facet_grid(Sex ~ Equipment) +
  geom_smooth(aes(x = BodyweightKg, y = TotalKg),
  alpha = 0.5,
  show.legend = FALSE) +
  labs(title = "Fig. 1: Weight Lifted by Lifters of Different Weights by Sex and the Equipment Used",
  x = " Lifter's Weight (in Kg)", 
  y = " Total Weight Lifted (in Kg)") +
  theme( panel.background = element_rect(fill = "white", colour = "grey87"),
  panel.grid.major = element_line(colour = "grey87"),
  axis.line = element_line(linewidth = 0.2, colour = "grey70"),
  axis.ticks = element_line(linewidth = 0.2), 
  plot.background = element_rect(fill = 'white', color = 'white'), 
  strip.background = element_rect(
  fill = "white", 
  color = "grey70", 
  line)) + 
  guides(fill = "none") +
  xlim(25, 100) + 
  ylim(0, 1080)   
#Fitting models
mod1 <- power_clean %>%
  with(lm(TotalKg ~ Sex+BodyweightKg))

mod2 <- power_clean %>% 
  with(lm(TotalKg ~ Sex+BodyweightKg+Equipment))

mod3 <- power_clean %>%
  with(lm(TotalKg ~BodyweightKg+Sex*Equipment))


# Calculating estimates, standard error, test statistics, p-values:

mod1_fitted<-tidy(mod1)

mod2_fitted<-tidy(mod2)

mod3_fitted<-tidy(mod3)

mod1_confint<-confint(mod1)

mod2_confint<-confint(mod2)

mod3_confint<-confint(mod3)
#Building fitted model 1 table
df1 <- data.frame(Coefficients= c("Intercept", "SexMale","Bodyweight"),
                  Estimates = c("108.65", "181.39", "3.30"), 
                  Standard_Errors = c("0.77", "0.48", "0.01"),
                  Test_Statistics =c("141.96","378.05", "329.05"),
                  P.value=c("0","0","0"),
                  Confindence_interval=c("(107.15, 110.15)","(180.45, 182.33)","(3.28, 3.32)"))

# Output the table using kable()
knitr::kable(df1, align = c("l", "c"), caption = "Fitted Model 1 (Estimates, Confidence Intervals, P-values)")
#Building fitted model 2 table
df2 <- data.frame(Coefficients= c("Intercept","SexMale","Bodyweight", "EquipmentRaw","EquipmentSingle-ply","EquipmentWraps"),
                  Estimates = c("164.28", "170.56", "3.44","-98.16","-15.76","-98.36"), 
                  Standard_Errors = c("2.35", "0.45", "0.01","2.25","2.25","2.37"),
                  Test_Statistics =c("69.87","381.40", "369.29","-43.71","-7.02","-41.4"),
                  P.value=c("0.00","0.00","0.00","0.00","0.00","0.00"),
                  Confindence_interval=c("(159.68, 168.89)","(169.68, 171.43)","(3.42, 3.46)","(-102.56, -93.75)","(-20.16, -11.36)","(-103.01, -93.72)"))

# Output the table using kable()
knitr::kable(df2, align = c("l", "c"), caption = "Fitted Model 2 (Estimates, Confidence Intervals, P-values)")
#Building fitted model 3 table
df3 <- data.frame(Coefficients= c("Intercept",  "Bodyweight","SexMale","EquipmentRaw","EquipmentSingle-ply","EquipmentWraps","SexM:EquipmentRaw","SexM:EquipmentSingle-ply","SexM:EquipmentWraps"),
                  Estimates = c("144.77", "3.44", "193.61","-77.12","2.71","-84.25","-25.15","-21.46","-15.43"), 
                  Standard_Errors = c("5.85", "0.01", "6.30","5.83","5.84","6.02","6.32","6.33","6.55"),
                  Test_Statistics =c("24.75","368.98", "30.72","-13.22","0.46","-14.00","-3.97","-3.39","-2.35"),
                  P.value=c("0.00","0.00","0.00","0.00","0.64","0.00","0.00","0.00","0.02"),
                  Confindence_interval=c("(133.30, 156.24)","(3.42, 3.46)","(181.26, 205.96)","(-88.56, -65.69)","( -8.74, 14.15)","(-96.05, -72.46)","(-37.54, -12.76)","(-33.85, -9.06)","(-28.27, -2.58)"))

# Output the table using kable()
knitr::kable(df3, align = c("l", "c"), caption = "Fitted Model 3 (Estimates, Confidence Intervals, P-values)")
# Values for R-squared and Residual Standard Error
rsquared_mod1 <-glance(mod1)
rsquared_mod2 <-glance(mod2)
rsquared_mod3 <-glance(mod3)
# Table for R-squared and Residual Standard Error

df2 <- data.frame(Model= c("Model 1", "Model 2", "Model 3"),
  R_Squared = c("0.597", "0.654", "0.654"), Standard_Deviation= c("108.92", "100.91", "100.91"))

# Output the table using kable()
knitr::kable(df2, align = c("l", "c"), caption = "R Squared and Residual Standard Error")
#Running nested F-tests
ftest_1 <- anova(mod1,mod2)
ftest_2 <- anova(mod2,mod3)
# Plotting Residuals vs Fitted Values for Final Model:
augment(mod3) %>%
  ggplot(aes(y = .resid, x = .fitted)) + 
  geom_point(alpha = 0.05) + 
  geom_smooth(se = FALSE) +
  geom_hline(yintercept = 0, color = "red") +
  theme_bw() +
  labs(x = "Fitted Values", 
  y = "Residuals", 
  title = " Fig. 2: Residuals vs Fitted Values for Final Model") + xlim(200, 1100) +
  theme_minimal()
LS0tCnRpdGxlOiAiSG93IFRvIEJlIEEgU3VjY2Vzc2Z1bCBXZWlnaHRsaWZ0ZXIiCmF1dGhvcjogIkpvcmR5IE1hcmluIFVyYmluYSBhbmQgTmEgTmd1eWVuIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgc3BsaXRfYnk6IE5PTkUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKPCEtLS0gQmVnaW4gc3R5bGluZyBjb2RlLiAtLS0+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ci8qIFdob2xlIGRvY3VtZW50OiAqLwpib2R5ewogIGZvbnQtZmFtaWx5OiAiUGFsYXRpbm8gTGlub3R5cGUiLCAiQm9vayBBbnRpcXVhIiwgUGFsYXRpbm8sIHNlcmlmOwogIGZvbnQtc2l6ZTogMTJwdDsKfQpoMS50aXRsZSB7CiAgZm9udC1zaXplOiAzOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5hdXRob3IgewogIGZvbnQtc2l6ZTogMThweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KaDQuZGF0ZSB7CiAgZm9udC1zaXplOiAxOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQo8L3N0eWxlPgo8IS0tLSBFbmQgc3R5bGluZyBjb2RlLiAtLS0+CgpgYGB7ciBsb2FkLXBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFLGVjaG89RkFMU0V9CiMgTG9hZGluZyBwYWNrYWdlcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShOSEFORVMpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShrbml0cikKbGlicmFyeShkcGx5cikKYGBgCgoKIyBJbnRyb2R1Y3Rpb24KCiMjIEludHJvZHVjdGlvbiB0byBUb3BpYwoKWW91IG1heSBoYXZlIHByb2JhYmx5IHNlZW4gcGVvcGxlIGxpZnRpbmcgZGlmZmVyZW50IHdlaWdodHMgaW4gdGhlIGd5bS4gQnV0IHdoeSBkbyBwZW9wbGUgZXZlbiBsaWZ0PyBUaGVyZSBhcmUgbnVtZXJvdXMgcmVhc29ucyBmb3IgbGlmdGluZyBidXQgb25lIG9mIHRoZSBtb3N0IGNvbW1vbiByZWFzb25zIGlzIHRvIGJlY29tZSBzdHJvbmdlciwgd2hpbGUgb3RoZXJzIGRvIGxpZnRpbmcgZm9yIGEgY29tcGV0aXRpb24gc3VjaCBhcyBwb3dlcmxpZnRpbmcuIFBvd2VybGlmdGluZyBpcyBhIHN0cmVuZ3RoIHNwb3J0IHRoYXQgaGFzIGJlZW4gcGFydCBvZiB0aGUgT2x5bXBpY3MgR2FtZXMgc2luY2UgMTg5NiBhbmQgY29uc2lzdHMgb2YgdGhyZWUgYXR0ZW1wdHMgdG8gYWNoaWV2ZSB0aGUgbWF4aW11bSB3ZWlnaHQgb24gZWFjaCBvZiB0aGUgdGhyZWUgbGlmdHM6IHNxdWF0LCBiZW5jaCBwcmVzcywgYW5kIGRlYWRsaWZ0LiBEdXJpbmcgdGhlc2UgY29tcGV0aXRpb25zLCBzb21lIHBhcnRpY2lwYW50cyBsaWZ0IGhlYXZpZXIgd2VpZ2h0cyB0aGFuIG90aGVycy4gU28gd2Ugd29uZGVyLCB3aGF0IGFjY291bnRzIGZvciB0aGlzIGRpZmZlcmVuY2UgaW4gYSBjb21wZXRpdG9y4oCZcyBwZXJmb3JtYW5jZT8gQ291bGQgaXQgYmUgbWVyZWx5IGJlY2F1c2Ugb2YgYmlvbG9naWNhbCBmYWN0b3JzPyBPciBhcmUgdGhlcmUgYW55IG90aGVyIGZhY3RvcnMgdGhhdCBtaWdodCBpbXBhY3QgYSBwZXJzb24ncyBhYmlsaXR5IHRvIGxpZnQgYSBjZXJ0YWluIHdlaWdodCBzdWNoIGFzIHRoZWlyIGFnZSBvciB0aGUgZXF1aXBtZW50IHRoYXQgdGhleSB1c2U/IAoKIyMgUmVzZWFyY2ggUXVlc3Rpb25zCgpUaGlzIHJlc2VhcmNoIHdpbGwgZXhwbG9yZSB0aGUgYXNwZWN0cyB0aGF0IGVuYWJsZSBwZW9wbGUgdG8gbGlmdCBoZWF2aWVyIHdlaWdodC4gSW4gcGFydGljdWxhciwgd2UgYWltIHRvIGFuc3dlciB0aGUgZm9sbG93aW5nIHJlc2VhcmNoIHF1ZXN0aW9uOiBXaGF0IGFzcGVjdHMgb2YgYSBsaWZ0ZXIgbWFrZXMgdGhlbSB0aGUgbW9zdCBzdWNjZXNzZnVsIGluIGxpZnRpbmcgd2VpZ2h0cz8gRG9lcyB0aGUgZXF1aXBtZW50IHVzZWQgYWZmZWN0IHRoZSB3ZWlnaHQgbGlmdGVkIGJ5IGxpZnRlcnM/IE91ciBpbml0aWFsIHByZWRpY3Rpb24gaXMgdGhhdCBhIHBlcnNvbidzIHBoeXNpb2xvZ3kgaXMgb25lIG9mIHRoZSBkZXRlcm1pbmluZyBmYWN0b3JzIGluIGxpZnRpbmcgd2VpZ2h0cy4gSGVuY2UsIHdlIHdpbGwgbG9vayBhdCBob3cgYm9keSB3ZWlnaHQgYW5kIHNleCBhc3NpZ25lZCBhdCBiaXJ0aCBhZmZlY3QgdGhlIHRvdGFsIHdlaWdodCBsaWZ0ZWQgYnkgYW4gaW5kaXZpZHVhbC4gRnVydGhlcm1vcmUsIHdlIGFyZSBrZWVuIHRvIGZpbmQgb3V0IHRoZSByb2xlIHdpdGggd2hpY2ggZGlmZmVyZW50IGVxdWlwbWVudCBwbGF5cyBpbiBhc3Npc3RpbmcgYSB3ZWlnaHRsaWZ0ZXIgcGVyZm9ybWFuY2UuCgoKIyBEYXRhCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KcG93ZXIgPC0gcmVhZF9jc3YoInBvd2VyLmNzdiIpCmBgYAoKIyMgQ29udGV4dAoKICBUaGUgb3JpZ2luYWwgUG93ZXJsaWZ0aW5nIGRhdGFzZXQgY29udGFpbnMgMSw0MjMsMzU0IGNhc2VzLCBlYWNoIGluZGljYXRpbmcgYSBzaW5nbGUgcG93ZXJsaWZ0ZXIuIFRoaXMgZGF0YXNldCBpcyBhIHNuYXBzaG90IG9mIHRoZSBPcGVuUG93ZXJsaWZ0aW5nIGRhdGFiYXNlIGFzIG9mIEFwcmlsIDIwMTkuIE1vcmVvdmVyLCB0aGlzIGRhdGFzZXQgcGVydGFpbnMgdG8gdGhlIHJlc3VsdHMgb2YgcG93ZXJsaWZ0aW5nIGNvbXBldGl0aW9uIGluIHRocmVlIGJhcmJlbGwgbGlmdHM6IFNxdWF0LCBCZW5jaCwgYW5kIERlYWRsaWZ0LiBBZGRpdGlvbmFsbHksIHRoZSBkYXRhc2V0IGluY29ycG9yYXRlcyByZWxldmFudCB2YXJpYWJsZXMgY29ycmVzcG9uZGluZyB0byB0aGUgY29tcGV0aXRvcuKAmXMgcGVyc29uYWwgaW5mb3JtYXRpb24gc3VjaCBhcyB0aGVpciBuYW1lLCBhZ2UsIGJvZHkgd2VpZ2h0IGluIGtpbG9ncmFtcywgdGhlIGVxdWlwbWVudCB0aGV5IHVzZWQgZHVyaW5nIHRoZSBjb21wZXRpdGlvbiwgYXMgd2VsbCBhcyB0aGVpciBmaW5hbCBwbGFjZW1lbnQgaW4gY29tcGV0aXRpb24uIAogIAogIE91ciByZXNlYXJjaCBhaW1zIGF0IGV4cGxvcmluZyB3aGljaCB2YXJpYWJsZXMgbWlnaHQgaGF2ZSBhIGhpZ2hlciBlZmZlY3Qgb24gdGhlIHRvdGFsIHdlaWdodCBsaWZ0ZWQgYnkgYSBwYXJ0aWNpcGFudC4gVGh1cywgd2Ugd2lsbCB1c2UgdG90YWwga2lsb2dyYW1zIGxpZnRlZCBieSBhIHBhcnRpY2lwYW50LCB3aGljaCBpcyB0aGUgc3VtIG9mIHRoZSBiZXN0IHRocmVlIGF0dGVtcHRzIGZvciBlYWNoIHBhcnRpY2lwYW50IGluIHRoZSB0aHJlZSBiYXJiZWxsIGxpZnRzIG1lbnRpb25lZCBhYm92ZS4gRnVydGhlcm1vcmUsIHdlIHdpbGwgdXNlIG9uZSBxdWFudGl0YXRpdmUgdmFyaWFibGUgYXMgb3VyIGV4cGxhbmF0b3J5IHZhcmlhYmxlLCB0aGUgYm9keSB3ZWlnaHQgaW4ga2lsb2dyYW1zLiBBZGRpdGlvbmFsbHksIHdlIHdpbGwgYWxzbyBleHBsb3JlIHR3byBjYXRlZ29yaWNhbCB2YXJpYWJsZXMsIHRoZSBwYXJ0aWNpcGFudHPigJkgc2V4IGFzc2lnbmVkIGEgYmlydGggKE1hbGUgYW5kIEZlbWFsZSksIGFuZCB3ZSB3aWxsIGFsc28gY29uc2lkZXIgdGhlIGVxdWlwbWVudCB0aGV5IHVzZWQsIHdoaWNoIGlzIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgdGhhdCB0ZWxscyB1cyB3aGF0IHRoZXkgdXNlZCBkdXJpbmcgY29tcGV0aXRpb25zIHdoaWNoIGluY2x1ZGUgd3JhcHMsIHJhdywgc2luZ2xlLXBseSwgYW5kIG11bHRpLXBseS4gVG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mIHRoZSBlcXVpcG1lbnQsIGl0IGlzIHdvcnRoIGV4cGxhaW5pbmcgd2hhdCBlYWNoIGNhdGVnb3J5IGxldmVsIGVudGFpbHMuIEFjY29yZGluZyB0byB0aGUgd2Vic2l0ZSBCYXJiZW5kLCByYXcgcG93ZXJsaWZ0aW5nIG1lYW5zIGxpZnRpbmcgd2l0aCBsaXR0bGUgdG8gbm8gZXF1aXBtZW50LiBPbiB0aGUgb3RoZXIgaGFuZCwgc2luZ2xlLXBseSBtZWFucyB0aGUgc3VpdCBoYXMgb25lIGxheWVyIG9mIGZhYnJpYyB3aGVyZWFzIG11bHRpLXBseSBtZWFucyB0d28gbGF5ZXJzIG9yIG1vcmUuIEFsc28sIHdyYXBzIGFpbSB0byBzdXBwb3J0IGEgbGlmdGVy4oCZcyBqb2ludHMgKGkuZSBrbmVlcykuCiAgCiAgSXQgc2hvdWxkIGJlIGVtcGhhc2l6ZWQgdGhhdCB0aGlzIGdsb2JhbCBkYXRhc2V0IGNvbnRhaW5zIHRoZSByZWNvcmRlZCBjb21wZXRpdGlvbiBmcm9tIFNlcHRlbWJlciA0LCAxOTY0IHRvIEFwcmlsIDE5LCAyMDE5LiBBcyBtZW50aW9uZWQgYmVmb3JlLCB0aGlzIGlzIGEgY29tcGlsYXRpb24gb2YgZGF0YSBwZXJmb3JtZWQgYnkgT3BlblBvd2VybGlmdGluZywgd2hvc2UgbWFpbiBvYmplY3RpdmUgaXMgdG8gY3JlYXRlIGEgcHVibGljIGRvbWFpbiBhcmNoaXZlIG9mIHBvd2VybGlmdGluZyBoaXN0b3J5LiBMYXN0bHksIHRoZSBkYXRhIGNhbiBiZSBhY2Nlc3NlZCBvbiB0aGUgS2FnZ2xlIHdlYnNpdGUgdW5kZXIgdGhlIG5hbWUgb2YgW+KAnFBvd2VybGlmdGluZyBEYXRhYmFzZeKAnV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9vcGVuLXBvd2VybGlmdGluZy9wb3dlcmxpZnRpbmctZGF0YWJhc2UpLgoKCiMjIENsZWFuaW5nCgogIFNpbmNlIHdlIGFyZSBhbmFseXppbmcgdGhlIHRvdGFsIHdlaWdodHMgbGlmdGVkIGZvciBhbGwgdGhyZWUgY29tcGV0aXRpb25zIC0gc3F1YXRzLCBiZW5jaCBwcmVzc2VzLCBhbmQgZGVhZGxpZnRzIC0gd2UgcmVtb3ZlZCB0aG9zZSBsaWZ0ZXJzIHdobyB3ZXJlIHVuYWJsZSB0byBmdWxseSBmaW5pc2ggYWxsIHRoZWlyIHRhc2tzIGJ5IGZpbHRlcmluZyBvdXQgdGhvc2Ugd2l0aCBtaXNzaW5nIGRhdGEsIHNpbmNlIHRoZXkgd291bGQgaGF2ZSBza2V3ZWQgdGhlIHJlc3VsdHMuIEF0IHRoZSBzYW1lIHRpbWUsIHRoZSBvcmlnaW5hbCBkYXRhc2V0IGNvbnRhaW5lZCA1IGRpZmZlcmVudCBjYXRlZ29yaWVzIGZvciB0aGUg4oCYRXF1aXBtZW504oCZIHZhcmlhYmxlOiBzdHJhcHMsIHJhdywgc2luZ2xlLXBseSwgbXVsdGktcGx5LCBhbmQgd3JhcHBlZC4gSG93ZXZlciwgdGhlIOKAmHN0cmFwc+KAmSBjYXRlZ29yeSB3YXMgbGFyZ2VseSBpbnN1ZmZpY2llbnQsIGFuZCB3ZSByZW1vdmVkIGl0IHNpbmNlIHdlIGRpZCBub3QgZmVlbCBhcyBpZiB0aGVyZSB3YXMgYSBsYXJnZSBlbm91Z2ggc2FtcGxlIHNpemUgdG8gbWFrZSBhY2N1cmF0ZSBjb25jbHVzaW9ucy4gV2UgYWxzbyBkZWNpZGVkIHRvIG9ubHkgaW5jbHVkZSB0aG9zZSBjb21wZXRpdG9ycyB3aG8gd2VyZSBjb25maXJtZWQgdG8gaGF2ZSBiZWVuIHRlc3RlZCBmb3IgZHJ1Z3MsIHNvIGFzIHRvIGVuc3VyZSB0aGUgbW9zdCBhY2N1cmF0ZSByZXN1bHRzLiAKICAKICBMYXN0bHksIHRoZSBvcmlnaW5hbCBkYXRhc2V0IGNvbnRhaW5lZCBtYW55IHByb2JsZW1zIHJlZ2FyZGluZyBhZ2UgdGhhdCB3ZXJlIGNvbmNlcm5pbmcuIFRoZXJlIHdlcmUgbWFueSBvdXRsaWVycyBmb3IgYEFnZWAgYW5kIGBUb3RhbEtnYCwgdGhhdCBoYWQgZGVzY3JpYmVkIG1hbnkgeW91bmcgY2hpbGRyZW4gbGlmdGluZyB1bnVzdWFsIHdlaWdodHMsIGJ1dCBhbHNvIHdpbm5pbmcgYXdhcmRzLiBBdCB0aGUgc2FtZSB0aW1lLCB0aGVyZSB3ZXJlIG1hbnkgZGF0YSBvYnNlcnZhdGlvbnMgdGhhdCBoYWQgY29udHJhcnkgdmFsdWVzIGZvciBgQWdlYCBhbmQgYEFnZUNsYXNzYCwgdGhhdCB3ZXJlIG1vc3RseSBmb3VuZCBpbiB0aGUgeW91bmdlciBhZ2VzLiBXZSBiZWxpZXZlLCB0aGVuLCB0aGF0IHRoaXMgd2FzIHNpbXBseSBhIG1pc3Rha2UsIHdoZXJlIHR5cG9zIGFuZCBzaW1pbGFyIGVycm9ycyBjcmVhdGVkIGluY29uc2lzdGVuY2llcy4gV2UgYWxzbyBmb3VuZCBzaW1pbGFyIGVycm9ycyBpbiB0aGUgb2xkZXIgYWdlcyBvZiB0aGUgZGF0YSBzZXQuIEFzIHN1Y2gsIGluIG9yZGVyIHRvIG1ha2UgdGhlIGRhdGEgbW9yZSBhY2N1cmF0ZSBhbmQgcmVtb3ZlIG91dGxpZXJzLCB3ZSBkZWNpZGVkIHRvIGZpbHRlciBvdXQgYWxsIGRhdGEgb2JzZXJ2YXRpb25zIHRoYXQgd2VyZSBvdXRzaWRlIG9mIHRoZSBhZ2UgcmFuZ2VzIGJldHdlZW4gMTYgYW5kIDUwIHllYXJzIG9sZC4gQWZ0ZXIgZmlsdGVyaW5nIG91dCBhbGwgdGhlIGRhdGEgdGhhdCB3ZSB3ZXJlIG9yaWdpbmFsbHkgd29ya2luZyB3aXRoLCBvbmx5IHJvdWdobHkgMzAwLDAwMCBvZiB0aGUgb3JpZ2luYWwgcm91Z2hseSAxLjUgbWlsbGlvbiBkYXRhIG9ic2VydmF0aW9ucyB3ZXJlIGxlZnQgdG8gYmUgYW5hbHl6ZWQuIFdoaWxlIHRoaXMgd2FzIHdvcnJpc29tZSBiZWNhdXNlIHdlIHRob3VnaHQgd2UgcmVtb3ZlZCB0b28gbWFueSwgd2UgbGF0ZXIgY2FtZSB0byB0aGUgY29uY2x1c2lvbiB0aGF0IHRoaXMgc2FtcGxlIHNpemUgbWFrZXMgbW9yZSBzZW5zZSwgYXMgaXQgcmVtb3ZlcyBleHRyZW1lIGFnZSBkaWZmZXJlbmNlcyB0aGF0IGNyZWF0ZWQgb3V0bGllcnMsIHRoZSBlcnJvcnMgdGhhdCB3ZXJlIG9jY3VycmluZy4KIAoKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQpwb3dlcl9jbGVhbiA8LSBwb3dlciAlPiUKICBmaWx0ZXIoIWlzLm5hKEJlc3QzU3F1YXRLZyksIAogICAgICAgICAhaXMubmEoQmVzdDNCZW5jaEtnKSwKICAgICAgICAgIWlzLm5hKEJlc3QzRGVhZGxpZnRLZyksCiAgICAgICAgICFpcy5uYShUZXN0ZWQpLCAKICAgICAgICAgIWlzLm5hKFNleCksCiAgICAgICAgICFpcy5uYShCb2R5d2VpZ2h0S2cpLAogICAgICAgICBFcXVpcG1lbnQgIT0gJ1N0cmFwcycsIAogICAgICAgICBBZ2UgPj0gMTYuMCApICU+JQogIHNlbGVjdChTZXgsIAogICAgICAgICBFcXVpcG1lbnQsIAogICAgICAgICBBZ2UsIEFnZUNsYXNzLCAKICAgICAgICAgQm9keXdlaWdodEtnLCBXZWlnaHRDbGFzc0tnLCAKICAgICAgICAgQmVzdDNTcXVhdEtnLCBCZXN0M0JlbmNoS2csIEJlc3QzRGVhZGxpZnRLZywgVG90YWxLZywgCiAgICAgICAgIElQRlBvaW50cykKYGBgCgoKIyBMaW5lYXIgUmVncmVzc2lvbgoKIyMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoPSAxMH0KIyBFREE6IEZpZ3VyZSAxIDogV2VpZ2h0IExpZnRlZCBieSBMaWZ0ZXJzIG9mIERpZmZlcmVudCBXZWlnaHRzIGJ5IFNleCBhbmQgdGhlIEVxdWlwbWVudCBVc2VkCmdncGxvdChwb3dlcl9jbGVhbikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBCb2R5d2VpZ2h0S2csIHkgPSBUb3RhbEtnLCBjb2xvciA9IEVxdWlwbWVudCksCiAgYWxwaGEgPSAwLjUsCiAgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoU2V4IH4gRXF1aXBtZW50KSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBCb2R5d2VpZ2h0S2csIHkgPSBUb3RhbEtnKSwKICBhbHBoYSA9IDAuNSwKICBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh0aXRsZSA9ICJGaWcuIDE6IFdlaWdodCBMaWZ0ZWQgYnkgTGlmdGVycyBvZiBEaWZmZXJlbnQgV2VpZ2h0cyBieSBTZXggYW5kIHRoZSBFcXVpcG1lbnQgVXNlZCIsCiAgeCA9ICIgTGlmdGVyJ3MgV2VpZ2h0IChpbiBLZykiLCAKICB5ID0gIiBUb3RhbCBXZWlnaHQgTGlmdGVkIChpbiBLZykiKSArCiAgdGhlbWUoIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJncmV5ODciKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5ODciKSwKICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4yLCBjb2xvdXIgPSAiZ3JleTcwIiksCiAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjIpLCAKICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICd3aGl0ZScsIGNvbG9yID0gJ3doaXRlJyksIAogIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoCiAgZmlsbCA9ICJ3aGl0ZSIsIAogIGNvbG9yID0gImdyZXk3MCIsIAogIGxpbmUpKSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArCiAgeGxpbSgyNSwgMTAwKSArIAogIHlsaW0oMCwgMTA4MCkgICAKYGBgCiAgCiAgRm9yIG91ciBpbml0aWFsIHZpc3VhbGl6YXRpb24sIHdlIGRlY2lkZWQgdG8gbG9vayBhdCBob3cgdGhlIHdlaWdodCBvZiB0aGUgcGFydGljaXBhbnRzIGlzIGNvcnJlbGF0ZWQgdG8gdGhlIHRvdGFsIHdlaWdodCB0aGF0IHRoZXkgd2VyZSBhYmxlIHRvIHN1Y2Nlc3NmdWxseSBsaWZ0IGNvbnNpZGVyaW5nIHRoZSBlcXVpcG1lbnQgdGhhdCB0aGV5IHVzZWQgaW4gb3JkZXIgdG8gY29tcGxldGUgdGhlIGxpZnQuIEluIHRoaXMgdmlzdWFsaXphdGlvbiwgd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIGluZGVlZCBhIHRyZW5kIGZvciBhbGwgZXF1aXBtZW50IHR5cGVzIHRoYXQgdGhlIG1vcmUgYSBwZXJzb24gd2VpZ2hzLCB0aGUgbW9yZSB0aGV5IGNhbiBzZWVtaW5nbHkgbGlmdC4gVGhpcyB0cmVuZCBpcyBtb3N0IG9idmlvdXMgdG8gdGhvc2UgbGlmdGVycyB3aG8gdXNlZCBtdWx0aS1wbHkgZXF1aXBtZW50IHdoZW4gbG9va2luZyBzb2xlbHkgYXQgdGhlIHNjYXR0ZXJwbG90LiBIb3dldmVyLCB3aGlsZSB0aGUgb3RoZXIgZXF1aXBtZW50IHR5cGVzIHNlZW0gdG8gaGF2ZSB3ZWFrZXIgcmVsYXRpb25zLCB0aGlzIHRyZW5kIGlzIHN0aWxsIGNsZWFybHkgcHJlc2VudCBhbmQgc2VlbXMgdG8gaGF2ZSB2ZXJ5IHNpbWlsYXIgc2xvcGVzIGZvciBhbGwgZXF1aXBtZW50IHR5cGVzLCBidXQgZGlmZmVyZW50IGludGVyY2VwdHMuIEF0IHRoZSBzYW1lIHRpbWUsIHdlIGZhY2V0ZWQgb24gdGhlIGJhc2lzIG9mIGJpb2xvZ2ljYWwgc2V4LiBXZSBmb3VuZCB0aGF0IHRoZXJlIGlzIGFsc28gYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHdlaWdodHMgb2YgdGhlIGxpZnRlcnMgYW5kIHdlaWdodHMgdGhhdCB0aGV5IHdlcmUgYWJsZSB0byBzdWNjZXNzZnVsbHkgbGlmdC4gSW4gdGhlIGZhY2V0cyBmb3Ig4oCYU2V44oCZLCB3ZSBmb3VuZCBzZWVtaW5nbHkgY29udHJhcnkgcmVzdWx0cyB0aGFuIHdlIGRpZCBmb3IgZXF1aXBtZW50IHR5cGVzOyBtYWxlcyBhbmQgZmVtYWxlcyBhcHBlYXIgdG8gaGF2ZSBkaWZmZXJlbnQgc2xvcGVzIGZvciB0aGUgbGluZWFyIG1vZGVscywgYnV0IGhhdmUgbW9yZSBzaW1pbGFyIHktaW50ZXJjZXB0cy4gCgojIE1vZGVsIENyZWF0aW9uIAoKICBXZSBhcmUgaW50ZXJlc3RlZCBpbiBkaXNjb3ZlcmluZyB0aGUgY2hhcmFjdGVyIGFuZCBzdHJlbmd0aCBvZiB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBkaWZmZXJlbnQgZmFjdG9ycyBhbmQgdGhlIHRvdGFsIHdlaWdodCB0aGV5IGNhbiBsaWZ0IGZvciB0aGVpciBiZXN0IGF0dGVtcHRzIGF0IFNxdWF0LCBEZWFkLWxpZnQsIGFuZCBCZW5jaCBjb21iaW5lZC4gVGhlcmVmb3JlLCB3ZSBkZWNpZGVkIHRvIHVzZSBhIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLiBGb3Igb3VyIGJpZyBtb2RlbCwgd2Ugd2FudCB0byBvYnNlcnZlIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGJpb2xvZ2ljYWwgZmFjdG9ycywgc3BlY2lmaWNhbGx5IGEgcGVyc29uJ3MgYm9keSB3ZWlnaHQgYXMgd2VsbCBhcyB0aGVpciBiaW9sb2dpY2FsIHNleCwgYW5kIHRoZSB0b3RhbCBhbW91bnQgb2YgdGhlIHRvdGFsIGFtb3VudCBvZiBraWxvZ3JhbXMgbGlmdGVkIGluIHRoZSB0aHJlZSBjYXRlZ29yaWVzLiAKICAKCiQkW1RvdGFsS2cgfCBCb2R5d2VpZ2h0LFNleE1dID0gIFxiZXRhXzAgKyBcYmV0YV8xICogQm9keXdlaWdodCArXGJldGFfMiAqU2V4TSQkCgogIEZvciBvdXIgbGFyZ2VyIG1vZGVsLCB3ZSB3YW50IHRvIGFuc3dlciB0aGUgb3RoZXIgc2lkZSBvZiBvdXIgcmVzZWFyY2g6IElzIGl0IG9ubHkgYmlvbG9naWNhbCBmYWN0b3JzIHRoYXQgaGF2ZSBhbiBpbmZsdWVuY2Ugb24gYSB3ZWlnaHQgbGlmdGVyJ3MgcGVyZm9ybWFuY2U/IEJ5IGludHJvZHVjaW5nIGEgbm9uLWJpb2xvZ2ljYWwgdmFyaWFibGUgdGhhdCB3ZSBwcmVkaWN0IG1heSBhZmZlY3QgdGhlIGFtb3VudCBvZiB3ZWlnaHQgbGlmdGVkIGluIDMgY2F0ZWdvcmllczogRXF1aXBtZW50LCB3ZSBhcmUgYXR0ZW1wdGluZyB0byBzZWUgaWYgdGhlcmUgaXMgYSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgdGhhdCBFcXVpcG1lbnQgcGxheXMgaW4gb3VyIHJlc3BvbnNlIHZhcmlhYmxlOiBUb3RhbEtnLiBIZW5jZSwgb25lIG9mIG91ciBsYXJnZXIgbW9kZWxzIGlzIGFzIGZvbGxvd3M6ICAKCiQkW1RvdGFsS2cgfCBCb2R5d2VpZ2h0LFNleCxFcXVpcG1lbnRdID0gIFxiZXRhXzAgKyBcYmV0YV8xICogQm9keXdlaWdodCArXGJldGFfMiAqU2V4TSArIFxcIFxiZXRhXzMqRXF1aXBtZW50X3tyYXd9K1xiZXRhXzQqRXF1aXBtZW50X3tzaW5nbGUtcGx5fStcYmV0YV81KkVxdWlwbWVudF97d3JhcHN9ICQkCgogIEZ1cnRoZXJtb3JlLCBpbiBvdXIgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcywgd2Ugb2JzZXJ2ZSBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc2xvcGUgZm9yIGZlbWFsZSBhbmQgbWFsZSB3ZWlnaHRsaWZ0ZXIgYWNyb3NzIGFsbCBlcXVpcG1lbnQuIE1vcmUgc3BlY2lmaWNhbGx5LCB0aGUgc2xvcGUgZm9yIGZlbWFsZSBpcyBjb25zaWRlcmFibHkgc3RlZXBlciB0aGFuIHRoYXQgZm9yIG1hbGUgd2l0aGluIGVhY2ggZXF1aXBtZW50IGNhdGVnb3J5LiBUaGlzIHN1Z2dlc3RzIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSBjaGFuZ2UgaW4gdG90YWwgd2VpZ2h0IGxpZnRlZCBmb3IgZWFjaCBraWxvZ3JhbSBvZiBib2R5IHdlaWdodCB3aGVuIGl0IGNvbWVzIHRvIGZlbWFsZSB3ZWlnaHRsaWZ0ZXJzIGlzIGxvd2VyIHRoYW4gd2hlbiBpdCBjb21lcyB0byBtYWxlIHdlaWdodGxpZnRlcnMgZm9yIGVhY2ggdHlwZSBvZiBlcXVpcG1lbnQgd2UgYXJlIGNvbnNpZGVyaW5nLiBUaGVyZWZvcmUsIHdlIHN1c3BlY3QgdGhhdCB0aGVyZSBpcyBhbiBlZmZlY3QgbW9kaWZpY2F0aW9uIGluIHdoaWNoICRTZXgkIGNhbiBtb2RpZnkgdGhlIGVmZmVjdCBvZiAkRXF1aXBtZW50JCBvbiB0aGUgb3V0Y29tZSB2YXJpYWJsZSAkVG90YWxLZyQsIG9yIHRoZSB0b3RhbCB3ZWlnaHQgaW4ga2lsb2dyYW1zIGxpZnRlZCBpbiAzIGNhdGVnb3JpZXMgZm9yIGEgd2VpZ2h0bGlmdGVyLiBUaGVyZWZvcmUsIHRoZSBzZWNvbmQgbGFyZ2VyIG1vZGVsIHdlIGNvbnNpZGVyIGlzIGFzIGZvbGxvd3M6ICAKCiQkW1RvdGFsS2cgfCBCb2R5d2VpZ2h0LFNleCxFcXVpcG1lbnRdID0gIFxiZXRhXzAgKyBcYmV0YV8xICogQm9keXdlaWdodCArXGJldGFfMiAqU2V4TSArIFxcIFxiZXRhXzMqRXF1aXBtZW50X3tyYXd9K1xiZXRhXzQqRXF1aXBtZW50X3tzaW5nbGUtcGx5fStcYmV0YV81KkVxdWlwbWVudF97d3JhcHN9IApcXCBcYmV0YV82KkVxdWlwbWVudF97cmF3fSpTZXhNK1xiZXRhXzcqRXF1aXBtZW50X3tzaW5nbGUtcGx5fSpTZXhNKwpcXFxiZXRhXzgqRXF1aXBtZW50X3t3cmFwc30qU2V4TSAkJAoKIyBGaXR0ZWQgTW9kZWwgCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KbW9kMSA8LSBwb3dlcl9jbGVhbiAlPiUKICB3aXRoKGxtKFRvdGFsS2cgfiBTZXgrQm9keXdlaWdodEtnKSkKCm1vZDIgPC0gcG93ZXJfY2xlYW4gJT4lIAogIHdpdGgobG0oVG90YWxLZyB+IFNleCtCb2R5d2VpZ2h0S2crRXF1aXBtZW50KSkKCm1vZDMgPC0gcG93ZXJfY2xlYW4gJT4lCiAgd2l0aChsbShUb3RhbEtnIH5Cb2R5d2VpZ2h0S2crU2V4KkVxdWlwbWVudCkpCgoKIyBDYWxjdWxhdGluZyBlc3RpbWF0ZXMsIHN0YW5kYXJkIGVycm9yLCB0ZXN0IHN0YXRpc3RpY3MsIHAtdmFsdWVzOgoKbW9kMV9maXR0ZWQ8LXRpZHkobW9kMSkKCm1vZDJfZml0dGVkPC10aWR5KG1vZDIpCgptb2QzX2ZpdHRlZDwtdGlkeShtb2QzKQoKbW9kMV9jb25maW50PC1jb25maW50KG1vZDEpCgptb2QyX2NvbmZpbnQ8LWNvbmZpbnQobW9kMikKCm1vZDNfY29uZmludDwtY29uZmludChtb2QzKQoKCmBgYAoKVGhlIHRhYmxlIGJlbG93IHNob3dzIHRoZSBmaXR0ZWQgbW9kZWwgZm9yIG91ciBzbWFsbCBuZXN0ZWQgbW9kZWw6CmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQpkZjEgPC0gZGF0YS5mcmFtZShDb2VmZmljaWVudHM9IGMoIkludGVyY2VwdCIsICJTZXhNYWxlIiwiQm9keXdlaWdodCIpLAogICAgICAgICAgICAgICAgICBFc3RpbWF0ZXMgPSBjKCIxMDguNjUiLCAiMTgxLjM5IiwgIjMuMzAiKSwgCiAgICAgICAgICAgICAgICAgIFN0YW5kYXJkX0Vycm9ycyA9IGMoIjAuNzciLCAiMC40OCIsICIwLjAxIiksCiAgICAgICAgICAgICAgICAgIFRlc3RfU3RhdGlzdGljcyA9YygiMTQxLjk2IiwiMzc4LjA1IiwgIjMyOS4wNSIpLAogICAgICAgICAgICAgICAgICBQLnZhbHVlPWMoIjAiLCIwIiwiMCIpLAogICAgICAgICAgICAgICAgICBDb25maW5kZW5jZV9pbnRlcnZhbD1jKCIoMTA3LjE1LCAxMTAuMTUpIiwiKDE4MC40NSwgMTgyLjMzKSIsIigzLjI4LCAzLjMyKSIpKQoKIyBPdXRwdXQgdGhlIHRhYmxlIHVzaW5nIGthYmxlKCkKa25pdHI6OmthYmxlKGRmMSwgYWxpZ24gPSBjKCJsIiwgImMiKSwgY2FwdGlvbiA9ICJGaXR0ZWQgTW9kZWwgMSAoRXN0aW1hdGVzLCBDb25maWRlbmNlIEludGVydmFscywgUC12YWx1ZXMpIikKYGBgCgpUaGUgdGFibGUgYmVsb3cgc2hvd3MgdGhlIGZpdHRlZCBtb2RlbCBmb3Igb3VyIGxhcmdlciBtb2RlbCB3aXRob3V0IGFuIGludGVyYWN0aW9uIHRlcm06CmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQpkZjIgPC0gZGF0YS5mcmFtZShDb2VmZmljaWVudHM9IGMoIkludGVyY2VwdCIsIlNleE1hbGUiLCJCb2R5d2VpZ2h0IiwgIkVxdWlwbWVudFJhdyIsIkVxdWlwbWVudFNpbmdsZS1wbHkiLCJFcXVpcG1lbnRXcmFwcyIpLAogICAgICAgICAgICAgICAgICBFc3RpbWF0ZXMgPSBjKCIxNjQuMjgiLCAiMTcwLjU2IiwgIjMuNDQiLCItOTguMTYiLCItMTUuNzYiLCItOTguMzYiKSwgCiAgICAgICAgICAgICAgICAgIFN0YW5kYXJkX0Vycm9ycyA9IGMoIjIuMzUiLCAiMC40NSIsICIwLjAxIiwiMi4yNSIsIjIuMjUiLCIyLjM3IiksCiAgICAgICAgICAgICAgICAgIFRlc3RfU3RhdGlzdGljcyA9YygiNjkuODciLCIzODEuNDAiLCAiMzY5LjI5IiwiLTQzLjcxIiwiLTcuMDIiLCItNDEuNCIpLAogICAgICAgICAgICAgICAgICBQLnZhbHVlPWMoIjAuMDAiLCIwLjAwIiwiMC4wMCIsIjAuMDAiLCIwLjAwIiwiMC4wMCIpLAogICAgICAgICAgICAgICAgICBDb25maW5kZW5jZV9pbnRlcnZhbD1jKCIoMTU5LjY4LCAxNjguODkpIiwiKDE2OS42OCwgMTcxLjQzKSIsIigzLjQyLCAzLjQ2KSIsIigtMTAyLjU2LCAtOTMuNzUpIiwiKC0yMC4xNiwgLTExLjM2KSIsIigtMTAzLjAxLCAtOTMuNzIpIikpCgojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYyLCBhbGlnbiA9IGMoImwiLCAiYyIpLCBjYXB0aW9uID0gIkZpdHRlZCBNb2RlbCAyIChFc3RpbWF0ZXMsIENvbmZpZGVuY2UgSW50ZXJ2YWxzLCBQLXZhbHVlcykiKQpgYGAKVGhlIHRhYmxlIGJlbG93IHNob3dzIHRoZSBmaXR0ZWQgbW9kZWwgZm9yIG91ciBsYXJnZXIgbW9kZWwgd2l0aCBhbiBpbnRlcmFjdGlvbiB0ZXJtOgoKYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CmRmMyA8LSBkYXRhLmZyYW1lKENvZWZmaWNpZW50cz0gYygiSW50ZXJjZXB0IiwgICJCb2R5d2VpZ2h0IiwiU2V4TWFsZSIsIkVxdWlwbWVudFJhdyIsIkVxdWlwbWVudFNpbmdsZS1wbHkiLCJFcXVpcG1lbnRXcmFwcyIsIlNleE06RXF1aXBtZW50UmF3IiwiU2V4TTpFcXVpcG1lbnRTaW5nbGUtcGx5IiwiU2V4TTpFcXVpcG1lbnRXcmFwcyIpLAogICAgICAgICAgICAgICAgICBFc3RpbWF0ZXMgPSBjKCIxNDQuNzciLCAiMy40NCIsICIxOTMuNjEiLCItNzcuMTIiLCIyLjcxIiwiLTg0LjI1IiwiLTI1LjE1IiwiLTIxLjQ2IiwiLTE1LjQzIiksIAogICAgICAgICAgICAgICAgICBTdGFuZGFyZF9FcnJvcnMgPSBjKCI1Ljg1IiwgIjAuMDEiLCAiNi4zMCIsIjUuODMiLCI1Ljg0IiwiNi4wMiIsIjYuMzIiLCI2LjMzIiwiNi41NSIpLAogICAgICAgICAgICAgICAgICBUZXN0X1N0YXRpc3RpY3MgPWMoIjI0Ljc1IiwiMzY4Ljk4IiwgIjMwLjcyIiwiLTEzLjIyIiwiMC40NiIsIi0xNC4wMCIsIi0zLjk3IiwiLTMuMzkiLCItMi4zNSIpLAogICAgICAgICAgICAgICAgICBQLnZhbHVlPWMoIjAuMDAiLCIwLjAwIiwiMC4wMCIsIjAuMDAiLCIwLjY0IiwiMC4wMCIsIjAuMDAiLCIwLjAwIiwiMC4wMiIpLAogICAgICAgICAgICAgICAgICBDb25maW5kZW5jZV9pbnRlcnZhbD1jKCIoMTMzLjMwLCAxNTYuMjQpIiwiKDMuNDIsIDMuNDYpIiwiKDE4MS4yNiwgMjA1Ljk2KSIsIigtODguNTYsIC02NS42OSkiLCIoLTguNzQsIDE0LjE1KSIsIigtOTYuMDUsIC03Mi40NikiLCIoLTM3LjU0LCAtMTIuNzYpIiwiKC0zMy44NSwgLTkuMDYpIiwiKC0yOC4yNywgLTIuNTgpIikpCgojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYzLCBhbGlnbiA9IGMoImwiLCAiYyIpLCBjYXB0aW9uID0gIkZpdHRlZCBNb2RlbCAzIChFc3RpbWF0ZXMsIENvbmZpZGVuY2UgSW50ZXJ2YWxzLCBQLXZhbHVlcykiKQpgYGAKCgojIE1vZGVsIEludGVycHJldGF0aW9uCgojIyBFc3RpbWF0ZXMgCgogIEFzIHByZXZpb3VzbHkgc3RhdGVkLCBvdXIgcmVzZWFyY2ggaW50ZW5kcyB0byBleHBsb3JlIG5vdCBvbmx5IHBoeXNpb2xvZ2ljYWwgZmFjdG9ycyBvZiBhIGNvbXBldGl0b3IsIGJ1dCBhbHNvIG90aGVyIGV4dGVybmFsIGZhY3RvcnMgdGhhdCBnbyBpbnRvIHRoZSBjb21wZXRpdGlvbi4gQmFzZWQgb24gb3VyIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMsIHdlIHN1c3BlY3QgdGhhdCB0aGUgbW9kZWwgaW4gd2hpY2ggdGhlcmUgaXMgYW4gaW50ZXJhY3Rpb24gdGVybSBiZXR3ZWVuIGBTZXhgIGFuZCBgRXF1aXBtZW50YC4gVGhlcmVmb3JlLCB3ZSB3aWxsIGZvY3VzIG1haW5seSBvbiB0aGUgZml0dGVkIG1vZGVsIDMuIFRocm91Z2ggYW4gZXhhbWluYXRpb24gb2YgdGhlIHNsb3BlIGNvZWZmaWNpZW50cyBmb3IgdGhlIHZhcmlhYmxlIGBTZXhNYWxlYCwgd2UgY2FuIG9ic2VydmUgdGhhdCB0aGUgZXN0aW1hdGVkIGF2ZXJhZ2UgdG90YWwga2lsb2dyYW1zIGxpZnRlZCBieSBhIGNvbXBldGl0b3Igd2hvc2Ugc2V4IGFzc2lnbmVkIGF0IGJpcnRoIGlzIG1hbGUgaXMgMTkzLjYxIGtnIGhpZ2hlciB0aGFuIGEgbGlmdGVyIHdob3NlIHNleCBhc3NpZ25lZCBhdCBiaXJ0aCBpcyBmZW1hbGUsIGhvbGRpbmcgYm9keSB3ZWlnaHQgYW5kIGVxdWlwbWVudCBjb25zdGFudC4gQWRkaXRpb25hbGx5LCB3aGlsZSBpbnRlcnByZXRpbmcgdGhlIGNvZWZmaWNpZW50IG9mIHRoZSB2YXJpYWJsZSBgQm9keXdlaWdodEtnYCB3ZSBjYW4gb2JzZXJ2ZSB0aGF0IHRoZSBlc3RpbWF0ZWQgaW5jcmVhc2UgaW4gdGhlIGF2ZXJhZ2UgdG90YWwga2lsb2dyYW1zIGxpZnRlZCBieSBhIGNvbXBldGl0b3IgaXMgMy40NCBrZyBmb3IgYSAxIHVuaXQgaW5jcmVhc2UgaW4gYSBsaWZ0ZXLigJlzIGJvZHkgd2VpZ2h0LCBob2xkaW5nIGVxdWlwbWVudCBhbmQgc2V4IGNvbnN0YW50LiAKICAKICBCeSBleGFtaW5pbmcgdGhlIHNsb3BlIGNvZWZmaWNpZW50cyBmb3IgdGhlIHZhcmlhYmxlIGBFcXVpcG1lbnRgLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIGVzdGltYXRlIHN1Z2dlc3RzIHRoYXQgbGlmdGVycyB3aG8gZG8gbm90IHdlYXIgYW55IGVxdWlwbWVudCwgY29uc2lkZXJlZCBhcyDigJxyYXfigJ0gdW5kZXIgdGhpcyBjYXRlZ29yeSwgbGlmdCwgb24gYXZlcmFnZSwgNzcuMTIga2cgbGVzcyB0aGFuIGxpZnRlcnMgdGhhdCB1c2UgbXVsdGktcGx5IGVxdWlwbWVudCAob3VyIHJlZmVyZW5jZSBjYXRlZ29yeSksIGhvbGRpbmcgYWxsIG90aGVyIHZhcmlhYmxlcyBjb25zdGFudC4gTGlrZXdpc2UsIHRoZSBzbG9wZSBjb2VmZmljaWVudCBvZiBlcXVpcG1lbnQgc2luZ2xlLXB5IHN1Z2dlc3RzIHRoYXQgbGlmdGVycyB3aG8gdXNlIHNpbmdsZS1wbHkgZXF1aXBtZW50IGNhbiBsaWZ0LCBvbiBhdmVyYWdlLCAyLjcxIGtnIG1vcmUgdGhhbiBsaWZ0ZXJzIHdobyB1c2UgbXVsdGktcGx5IGVxdWlwbWVudCwgaG9sZGluZyBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQuIExhc3RseSwgdGhlIHNsb3BlIGNvZWZmaWNpZW50IG9mIGVxdWlwbWVudCB3cmFwcyBpbmRpY2F0ZXMgdGhhdCBsaWZ0ZXJzIHdobyB1c2Ugd3JhcHMgbGlmdCwgb24gYXZlcmFnZSwgODQuMjUga2cgbGVzcyB0aGFuICBsaWZ0ZXJzIHdobyB1c2UgbXVsdGktcGx5IGVxdWlwbWVudC4KICAKICBGdXJ0aGVybW9yZSwgd2hlbiB3ZSB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIHZhbHVlcyBvZiBzbG9wZSBjb2VmZmljaWVudHMgZm9yIHRoZSBpbnRlcmFjdGlvbiB0ZXJtcywgd2UgY291bGQgc2VlIHRoZSBkZWdyZWUgdG8gd2hpY2ggYFNleGAgbW9kaWZpZXMgdGhlIGVmZmVjdCBvZiBgRXF1aXBtZW50YCBoYXMgb24gYFRvdGFsS2dgLiBGb3IgZXhhbXBsZSwgMjUuMTUgaXMgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIGVzdGltYXRlZCDigJxlZmZlY3TigJ0gYmV0d2VlbiBhIHdlaWdodGxpZnRlciB1c2luZyBtdWx0aS1wbHkgZXF1aXBtZW50IGFuZCBhIHdlaWdodGxpZnRlciB1c2luZyBubyBlcXVpcG1lbnQgKGBFcXVpcG1lbnRSYXdgKSwgaW4gd2hpY2ggdGhlIGVmZmVjdCBpcyB0aGUgMSB1bml0ICBjaGFuZ2UgaW4gdGhlIGBTZXhgIHZhcmlhYmxl4oCUZnJvbSBmZW1hbGUgdG8gbWFsZS4gSW4gb3RoZXIgd29yZHMsIHdoaWxlIGEgZmVtYWxlIHdlaWdodGxpZnRlciB3aXRoIG5vIGVxdWlwbWVudCBpcyBleHBlY3RlZCB0byBsaWZ0LCBvbiBhdmVyYWdlLCA3Ny4xMmtnIGxlc3MgdGhhbiB3aGVuIHRoZXkgdXNlIG11bHRpLXBseSBlcXVpcG1lbnQsIGEgbWFsZSB3ZWlnaHRsaWZ0ZXIgd2l0aCBubyBlcXVpcG1lbnQgaXMgZXhwZWN0ZWQgdG8gbGlmdCwgb24gYXZlcmFnZSwgKDc3LjEyKzI1LjE1KSBvciAxMDIuMjdrZyBsZXNzIHRoYW4gYSBmZW1hbGUgdXNpbmcgbXVsdGktcGx5IGVxdWlwbWVudC4gCgkKICBJbiBzdW1tYXJ5LCBhbGwgZml0dGVkIG1vZGVscyBzdWdnZXN0IHRoYXQgdGhlcmUgc2VlbXMgdG8gYmUgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBvdXIgcHJlZGljdG9yIHZhcmlhYmxlcywgYm9keSB3ZWlnaHQgYW5kIHNleCBhc3NpZ25lZCBhdCBiaXJ0aCBhbmQgb3VyIG91dGNvbWUgdmFyaWFibGUsIHRvdGFsIGtpbG9ncmFtcyBsaWZ0ZWQuIFRoZXNlIHJlc3VsdHMgYXJlIGNvbnNpc3RlbnQgd2l0aCBvdXIgaW5pdGlhbCBwcmVkaWN0aW9ucyB3aGVuIGNvbnNpZGVyaW5nIHdoaWNoIHZhcmlhYmxlcyB0byB1c2UsIGVzcGVjaWFsbHkgc2V4IGFzc2lnbmVkIGF0IGJpcnRoIGFuZCBib2R5IHdlaWdodC4gRnVydGhlcm1vcmUsIGZyb20gdGhlIG1vZGVsIHdlIGNhbiBzZWUgdGhlIGF2ZXJhZ2UgZGlmZmVyZW5jZXMgaW4gdG90YWwga2lsb2dyYW1zIGxpZnRlZCB3aGlsZSBjb21wYXJpbmcgZWFjaCBlcXVpcG1lbnQgY2F0ZWdvcnkgdG8gdGhlIG11bHRpLXBseSBlcXVpcG1lbnQgYXMgb3VyIHJlZmVyZW5jZSBjYXRlZ29yeS4gQ2VydGFpbmx5LCBsaWZ0ZXJzIHdobyB1c2VkIHJhdyBhbmQgd3JhcHMgYXMgZXF1aXBtZW50IHNlZW0gdG8gaGF2ZSBhIGhpZ2hlciBhdmVyYWdlIGRpZmZlcmVuY2UgaW4gdGhlIHRvdGFsIGtpbG9ncmFtcyBsaWZ0ZWQgYXMgY29tcGFyZWQgdG8gdGhvc2UgIHdobyB1c2VkIG11bHRpLXBseSBhcyBlcXVpcG1lbnQuIEhlbmNlLCB3ZSBjYW4gZ2xpbXBzZSBmcm9tIHRoZSBtb2RlbCB0aGF0IHRoZXJlIHNlZW1zIHRvIGJlIHNvbWUgc29ydCBvZiBlZmZlY3QgaW4gb3VyIG91dGNvbWUgdmFyaWFibGUgYWNyb3NzIGRpZmZlcmVudCBlcXVpcG1lbnQgdXNlZC4gTGlrZXdpc2UsIHdpdGggcmVnYXJkcyB0byBmaXR0ZWQgbW9kZWwgMywgd2Ugb2JzZXJ2ZSB0aGF0IHNleCBhc3NpZ25lZCBhdCBiaXJ0aCwgdG8gYSBjZXJ0YWluIGRlZ3JlZSwgYWZmZWN0cyBob3cgdGhlIHVzZSBvZiBlcXVpcG1lbnQgaW5mbHVlbmNlcyB0aGUgdG90YWwgYW1vdW50IGxpZnRlZCAoaW4ga2lsb2dyYW1zKS4KICAKIyMgQ29uZmlkZW5jZSBJbnRlcnZhbHMKCiAgQXMgcGFydCBvZiB0aGUgaW50ZXJwcmV0YXRpb24gcHJvY2Vzcywgd2UgZGVjaWRlZCB0byBsb29rIGF0IG91ciA5NSAlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIHRvIGJldHRlciBhc3Nlc3MgdGhlIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBvZiBvdXIgcHJlZGljdG9yIHZhcmlhYmxlcyBhbmQgb3VyIG91dGNvbWUgdmFyaWFibGUuIEZvciBlYWNoIGFkZGl0aW9uYWwgMSBrZyBpbmNyZWFzZSBpbiBib2R5IHdlaWdodCwgd2Ugd291bGQgZXhwZWN0IGFuIGF2ZXJhZ2UgaW5jcmVhc2Ugb2YgMy40MiB0byAzLjQ2IGtpbG9ncmFtcyBpbiB3ZWlnaHQgbGlmdGVkLiBXZSBhcmUgdW5zdXJlIHdoZXRoZXIgdGhpcyBpbnRlcnZhbCBjb250YWlucyB0aGUgdHJ1ZSBwb3B1bGF0aW9uIGF2ZXJhZ2UgY2hhbmdlIGluIGtpbG9ncmFtcyBsaWZ0ZWQgcGVyIDEga2cgaW5jcmVhc2UgaW4gYm9keSB3ZWlnaHQsIGJ1dCB3ZSB0cnVzdCB0aGF0IDk1JSBvZiBzYW1wbGVzIHdpbGwgaGF2ZSBpbnRlcnZhbHMgdGhhdCBjb250YWluIHRoZSB0cnVlIGNoYW5nZS4gCiAgCiAgRm9yIGEgbGlmdGVyIHdobyBkb2VzIG5vdCB3ZWFyIGFueSBlcXVpcG1lbnQsIHdlIGV4cGVjdCBhbiBhdmVyYWdlIGRlY3JlYXNlIG9mIDY1LjY5IHRvIDg4LjU2IGtpbG9ncmFtcyBpbiB3ZWlnaHQgbGlmdGVkLiBXZSBleHBlY3QgdGhhdCBmb3IgY29tcGV0aXRvcnMgdGhhdCB1c2Ugc2luZ2xlLXBseSBlcXVpcG1lbnQsIHRoZXJlIHdvdWxkIGJlIGFuIGF2ZXJhZ2UgZGVjcmVhc2Ugb2YgMCB0byA4Ljc0LmtpbG9ncmFtcyBpbiB3ZWlnaHQgbGlmdGVkIGFuZCBhbiBhdmVyYWdlIGluY3JlYXNlIG9mIHdlaWdodCBsaWZ0ZWQgZnJvbSAwIHRvIDE0LjE1LiBHaXZlbiB0aGF0IDAgaXMgcGFydCBvZiBvdXIgY29uZmlkZW5jZSBpbnRlcnZhbCwgaXQgc3VnZ2VzdHMgdGhhdCB0aGVyZSBtaWdodCBub3QgYmUgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiBsaWZ0ZXJzIHRoYXQgdXNlIHNpbmdsZS1wbHkgZXF1aXBtZW50IGFuZCB0aGUgdG90YWwga2lsb2dyYW1zIGxpZnRlZC4gTGFzdGx5IGZvciBsaWZ0ZXJzIHRoYXQgdXNlIHdyYXBzLCB3ZSBleHBlY3QgYW4gYXZlcmFnZSBkZWNyZWFzZSBvZiA3Mi40NiB0byA5Ni4wNSBraWxvZ3JhbXMgaW4gd2VpZ2h0IGxpZnRlZC4gRm9yIG1hbGUgbGlmdGVycyB0aGF0IGRvIG5vdCB1c2UgYW55IGVxdWlwbWVudCwgd2UgZXhwZWN0IG9uIGF2ZXJhZ2UgdGhhdCB0aGUgZWZmZWN0IG1vZGlmaWNhdGlvbiBvZiBzZXggb24gZXF1aXBtZW50IGlzIGJldHdlZW4gLTM3LjU0IHRvIC0xMi43Ni4gVGhpcyBtZWFucyB0aGF0IHdlIHdvdWxkIGV4cGVjdCBtYWxlIGxpZnRlcnMgdGhhdCBkbyBub3QgdXNlIGFueSBlcXVpcG1lbnQgdG8gbGlmdCAxMi43NiB0byA3Ny41NCBrZyBsb3dlciB0aGFuIGZlbWFsZXMgdGhhdCBkbyBub3QgdXNlIGFueSBlcXVpcG1lbnQuIFdlIGV4cGVjdCBjb21wZXRpdG9ycyB0aGF0IGFyZSBtYWxlcyBhbmQgdXNlIHNpbmdsZS1wbHkgdG8gbGlmdCBvbiBhdmVyYWdlIDkuMDYgdG8gMzMuODUga2lsb2dyYW1zIGxvd2VyIHRoYW4gZmVtYWxlcyB0aGF0IHVzZSBzaW5nbGUtcGx5LiBMYXN0bHksIHdlIGV4cGVjdCBtYWxlIHBhcnRpY2lwYW50cyB0aGF0IHVzZSB3cmFwcyB0byBsaWZ0IG9uIGF2ZXJhZ2UgMi41OCB0byAyOC4yNyBraWxvZ3JhbXMgbG93ZXIgdGhhbiBmZW1hbGVzIGxpZnRlcnMgdGhhdCB1c2Ugd3JhcHMuIAogIAogIEZvciBhbGwgb2YgdGhlc2Ugb2JzZXJ2YXRpb25zLCB3ZSBhcmUgY29uZmlkZW50IGluIHRoZSBpbnRlcnZhbCBjb25zdHJ1Y3Rpb24gcHJvY2VzcyBiZWNhdXNlIHdlIGV4cGVjdCA5NSUgb2Ygc2FtcGxlcyB0byBsZWFkIHRvIGludGVydmFscyB0aGF0IGNvbnRhaW4gdGhlIHRydWUgcG9wdWxhdGlvbiBwYXJhbWV0ZXIgdmFsdWUuIEhvd2V2ZXIsIHdlIGFyZSBub3Qgc3VyZSBpZiBvdXIgcGFydGljdWxhciBpbnRlcnZhbCBmcm9tIG91ciBzYW1wbGUgY29udGFpbnMgdGhhdCB0cnVlIHBvcHVsYXRpb24gcGFyYW1ldGVyIHZhbHVlIG9yIG5vdC4KCiMjIFAtdmFsdWUgYW5kIFRlc3QgU3RhdGlzdGljKHMpCgogIFdlIGFsc28gbG9va2VkIGF0IHRoZSB0ZXN0IHN0YXRpc3RpYyBvZiB0aGlzIG1vZGVsIHRvIGtub3cgaG93IGZhciB0aGUgb2JzZXJ2ZWQgZGF0YSBpcyBmcm9tIHRoZSBudWxsIGh5cG90aGVzaXMuIFRoZSB0ZXN0IHN0YXRpc3RpYyBpcyBhIGRpc2NyZXBhbmN5IG1lYXN1cmUgd2hlcmUgbGFyZ2UgdmFsdWVzIGluZGljYXRlIGhpZ2hlciBkaXNjcmVwYW5jeSB3aXRoIHRoZSBudWxsIGh5cG90aGVzaXMuIFRoZSB0ZXN0IHN0YXRpc3RpYyBpcyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgbnVsbCBoeXBvdGhlc2lzIHZhbHVlIG9mIDAgKHRoZSBudWxsIHZhbHVlKSBpbiB0ZXJtcyBvZiBzdGFuZGFyZCBlcnJvcnMuIE91ciBtb2RlbCBoYXMgYSB0ZXN0IHN0YXRpc3RpYyBvZiAzNjguOTgsIDMwLjcyLCAtMTMuMjIsIDAuNDYsIC0xNC4wMCwgLTMuOTcsIC0zLjM5LCAtMi4zNSBmb3IgcmVzcGVjdGl2ZWx5IGBCb2R5d2VpZ2h0YCwgYFNleE1hbGVgLCBgRXF1aXBtZW50UmF3YCwgYEVxdWlwbWVudFNpbmdsZXBseWAsIGBFcXVpcG1lbnRXcmFwc2AsIGBTZXhNOkVxdWlwbWVudFJhd2AsIGBTZXhNOkVxdWlwbWVudFNpbmdsZS1QbHlgLCBhbmQgYFNleE06RXF1aXBtZW50V3JhcHNgIGNvZWZmaWNpZW50cy4gQmVzaWRlcyB0aGUgY29lZmZpY2llbnQgYEVxdWlwbWVudFNpbmdsZXBseWAsIGFsbCB0aGUgb3RoZXIgY29lZmZpY2llbnRzIGhhdmUgYSBsYXJnZSB0ZXN0IHN0YXRpc3RpYyB3aGljaCBzdWdnZXN0cyB0aGF0IG91ciBkYXRhIChhbmQgb3VyIGVzdGltYXRlKSBpcyBkaXNjcmVwYW50IHdpdGggd2hhdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHByb3Bvc2VzIGJlY2F1c2Ugb3VyIGVzdGltYXRlIGlzIHF1aXRlIGZhciBhd2F5IGZyb20gdGhlIG51bGwgdmFsdWUgaW4gc3RhbmRhcmQgZXJyb3IgdW5pdHMuIEhvd2V2ZXIsIGZvciBvdXIgYEVxdWlwbWVudFNpbmdsZS1QbHlgIGNvZWZmaWNpZW50LCB3ZSBoYXZlIGEgdGVzdCBzdGF0aXN0aWMgb2YgLTAuNDYgd2hpY2ggc3VnZ2VzdHMgdGhhdCB0aGVyZSBtaWdodCBub3QgYmUgYW55IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGBFcXVpcG1lbnRTaW5nbGUtUGx5YCBhbmQgdGhlIGF2ZXJhZ2UgZGlmZmVyZW5jZSBpbiB0b3RhbCBraWxvZ3JhbXMgbGlmdGVkIGJ5IGEgY29tcGV0aXRvciB0aGF0IHVzZXMgbXVsdGktcGx5IGVxdWlwbWVudC4gCiAgCiAgTW9yZW92ZXIsIHdlIHVzZWQgdGhlIHAtdmFsdWUgdG8gZGVsdmUgZGVlcGVyIGludG8gdGhlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwIGJldHdlZW4gZWFjaCBvZiBvdXIgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGFuZCBvdXIgb3V0Y29tZSB2YXJpYWJsZS4gVGhlIHAtdmFsdWUgZm9yIG91ciBjb2VmZmljaWVudHMgbWVhc3VyZXMgdGhlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyBhIHRlc3Qgc3RhdGlzdGljIGFzIG9yIG1vcmUgZXh0cmVtZSB0aGFuIHRoZSBvbmUgd2Ugc2F3LCBpZiBvdXIgbnVsbCBoeXBvdGhlc2lzIGhvbGRzLiBUbyBpbGx1c3RyYXRlLCB3ZSBjb3VsZCBwZXJmb3JtIGEgaHlwb3RoZXNpcyB0ZXN0IGZvciBlYWNoIHNsb3BlIGNvZWZmaWNpZW50IGFzc29jaWF0ZWQgd2l0aCBlYWNoIHByZWRpY3RvciB2YXJpYWJsZSwgaW4gcmVsYXRpb24gdG8gdGhlIG91dGNvbWUgdmFyaWFibGUsIHlldCB3ZSBkZWNpZGVkIHRvIHJ1biBvbmx5IHR3byBoeXBvdGhlc2lzIHRlc3RzIHRvIG1ha2UgdGhpcyBwcm9jZXNzIGxlc3MgcmVwZXRpdGl2ZS4gIAogIAogIEZpcnN0bHksIHdlIHdhbnRlZCB0byBleHBsb3JlIHRoZSBmaXJzdCBwYXJ0IG9mIG91ciByZXNlYXJjaCBxdWVzdGlvbnMsIHdoaWNoIHJlbGF0ZXMgdG8gdGhlIHBoeXNpb2xvZ2ljYWwgdmFyaWFibGVzIHRoYXQgbWlnaHQgaGF2ZSBhbiBlZmZlY3Qgb24gdGhlIGFiaWxpdHkgdG8gbGlmdCBoaWdoZXIgd2VpZ2h0LiBPbmUgb2YgdGhlIHZhcmlhYmxlcyBpbiBvdXIgbW9kZWwgaXMgYEJvZHl3ZWlnaHRgLCB3aGljaCBjb3JyZXNwb25kcyB0byBhIGxpZnRlcuKAmXMgYm9keSB3ZWlnaHQgaW4ga2lsb2dyYW1zLiBUaGVyZWZvcmUsIHdlIHdhbnQgdG8gdGVzdCB3aGV0aGVyIGJvZHkgd2VpZ2h0IGhhcyBhIHN0YXRpc3RpY2FsbHkgcmVsYXRpb25zaGlwIHdpdGggdGhlIHRvdGFsIHdlaWdodCBsaWZ0ZWQgYnkgYSBjb21wZXRpdG9yLiBXZSBzdGFydGVkIGJ5IHN0YXRpbmcgb3VyIGh5cG90aGVzZXMgYXMgZm9sbG93OgokJEhfMDogXGJldGFfMSA9IDAgXHRleHR7IHZzIH0gSF9BOiBcYmV0YV8xIFxuZXEgMCwkJAoKPiBUaGUgbnVsbCBoeXBvdGhlc2lzIGZvciB0aGUgYEJvZHl3ZWlnaHRgIHZhcmlhYmxlIGlzIHRoYXQgaXRzIHNsb3BlIGNvZWZmaWNpZW50IGlzIGVxdWFsIHRvIHplcm8sIHN1Z2dlc3RpbmcgdGhhdCB0aGVyZSBpcyBubyByZWxhdGlvbnNoaXAgYmV0d2VlbiBhIGxpZnRlcuKAmXMgYm9keSB3ZWlnaHQgYW5kIHRoZSB0b3RhbCB3ZWlnaHQgbGlmdGVkIChpbiBraWxvZ3JhbXMpLCBhZnRlciBhY2NvdW50aW5nIGZvciB0aGUgb3RoZXIgdmFyaWFibGVzIGluIG91ciBtb2RlbC4KCj4gVGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgZm9yIHRoZSBgQm9keXdlaWdodGAgdmFyaWFibGUgaXMgdGhhdCBpdHMgc2xvcGUgY29lZmZpY2llbnQgaXMgbm90IGVxdWFsIHRvIHplcm8sIHN1Z2dlc3RpbmcgdGhhdCB0aGVyZSBpcyBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGEgbGlmdGVy4oCZcyBib2R5IHdlaWdodCBhbmQgdGhlIHRvdGFsIHdlaWdodCBsaWZ0ZWQgKGluIGtpbG9ncmFtcyksIGFmdGVyIGFjY291bnRpbmcgZm9yIHRoZSBvdGhlciB2YXJpYWJsZXMgaW4gb3VyIG1vZGVsLiAKCiAgQnkgc2V0dGluZyBhIHNpZ25pZmljYW5jZSB0aHJlc2hvbGQgb2YgMC4wNSwgd2UgY2FuIHNlZSB0aGF0IHRoZSBwLXZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgdmFyaWFibGUgYEJvZHl3ZWlnaHRgIGlzIGVxdWFsIHRvIHplcm8sIHdoaWNoIGlzIGxlc3MgdGhhbiBvdXIgdGhyZXNob2xkIHZhbHVlIG9mIDAuMDUuIFRoZXJlZm9yZSwgd2UgY2FuIHJlamVjdCBvdXIgbnVsbCBoeXBvdGhlc2lzIGluIGZhdm9yIG9mIG91ciBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGdpdmVuIHRoYXQgd2UgaGF2ZSBlbm91Z2ggZXZpZGVuY2UgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdmFyaWFibGUgYEJvZHl3ZWlnaHRgIGFuZCB0aGUgb3V0Y29tZSB2YXJpYWJsZSwgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHRoZSBvdGhlciB2YXJpYWJsZXMuICAKICAKICBNb3Jlb3Zlciwgd2Ugd2FudGVkIHRvIGludmVzdGlnYXRlIHRoZSBzZWNvbmQgcGFydCBvZiBvdXIgcmVzZWFyY2ggcXVlc3Rpb25zIHdoaWNoIHBlcnRhaW5zIHRvIGV4dGVybmFsIGZhY3RvcnMgdGhhdCBtaWdodCBoYXZlIGFuIGVmZmVjdCBvbiB0aGUgdG90YWwgd2VpZ2h0IGxpZnRlZCwgcmF0aGVyIHRoYW4gZm9jdXNpbmcgbWVyZWx5IG9uIHBoeXNpb2xvZ2ljYWwgZmFjdG9ycy4gSW4gcGFydGljdWxhciwgb25lIG9mIHRoZSB2YXJpYWJsZXMgaXMgdGhlIFNpbmdsZS1QbHkgRXF1aXBtZW50LiBUaGVyZWZvcmUsIHdlIGNhbiB0ZXN0IHdoZXRoZXIgdGhlcmUgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIFNpbmdsZS1QbHkgRXF1aXBtZW50IGFuZCB0aGUgb3V0Y29tZSB2YXJpYWJsZSB0b3RhbCB3ZWlnaHQgbGlmdGVkLiBUaGUgaHlwb3RoZXNpcyB0ZXN0IGlzIGFzIGZvbGxvdzoKICAKJCRIXzA6IFxiZXRhXzQgPSAwIFx0ZXh0eyB2cyB9IEhfQTogXGJldGFfNCBcbmVxIDAsJCQKIAo+IFRoZSBudWxsIGh5cG90aGVzaXMgZm9yIHRoZSBgRXF1aXBtZW50U2luZ2xlLXBseWAgdmFyaWFibGUgaXMgdGhhdCBpdHMgc2xvcGUgY29lZmZpY2llbnQgaXMgZXF1YWwgdG8gemVybywgc3VnZ2VzdGluZyB0aGF0IHRoZXJlIGlzIG5vIHN0YXRpc3RpY2FsbHkgZGlmZmVyZW5jZSBpbiB0b3RhbCB3ZWlnaHQgbGlmdGVkIGJldHdlZW4gbGlmdGVycyB3aG8gdXNlIHNpbmdsZS1wbHkgZXF1aXBtZW50IHdpdGggdGhvc2Ugd2hvIHVzZSBtdWx0aS1wbHkgZXF1aXBtZW50LCBhZnRlciBhY2NvdW50aW5nIGZvciB0aGUgb3RoZXIgdmFyaWFibGVzIGluIG91ciBtb2RlbC4KCj4gVGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgZm9yIHRoZSBgRXF1aXBtZW50U2luZ2xlLXBseWAgdmFyaWFibGUgaXMgdGhhdCBpdHMgc2xvcGUgY29lZmZpY2llbnQgaXMgbm90IGVxdWFsIHRvIHplcm8sIHN1Z2dlc3RpbmcgdGhhdCB0aGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgZGlmZmVyZW5jZSBpbiB0aGUgdG90YWwgd2VpZ2h0IGxpZnRlZCBiZXR3ZWVuIGxpZnRlcnMgd2hvIHVzZSBzaW5nbGUtcGx5IGVxdWlwbWVudCB3aXRoIHRob3NlIHdobyB1c2UgbXVsdGktcGx5IGVxdWlwbWVudCwgYWZ0ZXIgYWNjb3VudGluZyBmb3IgdGhlIG90aGVyIHZhcmlhYmxlcyBpbiBvdXIgbW9kZWwuCgogIEJ5IHNldHRpbmcgYSBzaWduaWZpY2FuY2UgdGhyZXNob2xkIG9mIDAuMDUsIHdlIGNhbiBzZWUgdGhhdCB0aGUgcC12YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHZhcmlhYmxlIGBFcXVpcG1lbnRTaW5nbGUtcGx5YCBpcyBlcXVhbCB0byAwLjY0LCB3aGljaCBpcyBncmVhdGVyIHRoYW4gb3VyIHRocmVzaG9sZCB2YWx1ZSBvZiAwLjA1LiBUaGVyZWZvcmUsIHdlIGZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgc2luY2Ugd2UgZG8gbm90IGhhdmUgZW5vdWdoIGV2aWRlbmNlIHRvIGNvbmNsdWRlIHRoYXQgdGhlcmUgaXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdG90YWwgd2VpZ2h0IGxpZnRlZCBiZXR3ZWVuIGxpZnRlcnMgd2hvIHVzZSBzaW5nbGUtcGx5IGVxdWlwbWVudCB3aXRoIHRob3NlIHdobyB1c2UgbXVsdGktcGx5IGVxdWlwbWVudCwgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHRoZSBvdGhlciB2YXJpYWJsZXMuIAogIAogIExhc3RseSwgYnkgcGVyZm9ybWluZyBhIGh5cG90aGVzaXMgdGVzdCBmb3IgdGhlIHJlbWFpbmluZyBzbG9wZSBjb2VmZmljaWVudHMgaW4gb3VyIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLCBhbmQgc2V0dGluZyB0aGUgbnVsbCBoeXBvdGhlc2lzIHRvIGJlIHRoYXQgZWFjaCBzbG9wZSBjb2VmZmljaWVudCBpcyBlcXVhbCB0byB6ZXJvIG9yIHRoYXQgdGhlcmUgaXMgbm8gcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGluZGl2aWR1YWwgcHJlZGljdG9yIHZhcmlhYmxlIGFzc29jaWF0ZWQgd2l0aCB0aGF0IGNvZWZmaWNpZW50IGFuZCB0aGUgdG90YWwgd2VpZ2h0IGxpZnRlZCwgaG9sZGluZyBhbGwgb3RoZXIgdmFyaWFibGVzIGNvbnN0YW50LiBBZGRpdGlvbmFsbHksIHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGlzIHRoYXQgZWFjaCBzbG9wZSBjb2VmZmljaWVudCBpcyBub3QgZXF1YWwgdG8gemVybywgb3IgdGhhdCB0aGVyZSBpcyBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBpbmRpdmlkdWFsIHByZWRpY3RvciB2YXJpYWJsZSBhbmQgdGhlIHRvdGFsIHdlaWdodCBsaWZ0ZWQsIGFmdGVyIGFjY291bnRpbmcgZm9yIHRoZSBvdGhlciB2YXJpYWJsZXMuIEJ5IHNldHRpbmcgYSB0aHJlc2hvbGQgb2YgMC4wNSwgd2UgY2FuIGZpbmFsaXplIG91ciBjb25jbHVzaW9ucy4gSW50ZXJlc3RpbmdseSwgdGhlIHJlc3Qgb2YgdGhlIHAtdmFsdWVzIGFyZSB6ZXJvIG9yIGNsb3NlIHRvIHplcm8gVGhlcmVmb3JlLCB3ZSBjYW4gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgZm9yIGVhY2ggc2xvcGUgY29lZmZpY2llbnQgaW4gZmF2b3Igb2YgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgc2luY2Ugd2UgaGF2ZSBlbm91Z2ggZXZpZGVuY2UgdGhhdCBzdWdnZXN0cyB0aGF0IGVhY2ggcHJlZGljdG9yIHZhcmlhYmxlIGFzc29jaWF0ZWQgd2l0aCB0aGF0IGNvZWZmaWNpZW50IGhhcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwIHdpdGggdGhlIG91dGNvbWUgdmFyaWFibGUsIHdoZW4gYWNjb3VudGluZyBmb3IgdGhlIG90aGVyIHZhcmlhYmxlcyBpbiBvdXIgbW9kZWwuIAoKCiMgTW9kZWwgRXZhbHVhdGlvbiAKCkluIG9yZGVyIHRvIGZpbmFsaXplIG9uIGEgbW9kZWwgdGhhdCBiZXN0IGFuc3dlcnMgb3VyIHJlc2VhcmNoIHF1ZXN0aW9uIGFzIHdlbGwgYXMgcmVmbGVjdHMgb3VyIHBvcHVsYXRpb24sIHdlIHdpbGwgdXNlIHRoZXNlIGZvbGxvd2luZyBsaW5lYXIgcmVncmVzc2lvbiB0b29scyBhcyB0aGUgYmFzaXMgb2YgcGVyZm9ybWFuY2UgY3JpdGVyaW9uIHRvIHNlbGVjdCBvdXIgZmluYWwgbW9kZWw6IGV4cGxvcmF0b3J5IHZpc3VhbGl6YXRpb24gKGVsYWJvcmF0ZWQgYWJvdmUpLCAkUl4yJCwgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IgJHNfZSQsIGFuZCBuZXN0ZWQgdGVzdC4gCgojIyBSLXNxdWFyZWQgCgpgYGB7ciwgZWNobz1GQUxTRX0KcnNxdWFyZWRfbW9kMSA8LWdsYW5jZShtb2QxKQpyc3F1YXJlZF9tb2QyIDwtZ2xhbmNlKG1vZDIpCnJzcXVhcmVkX21vZDMgPC1nbGFuY2UobW9kMykKYGBgCgpgYGB7cixlY2hvPUZBTFNFfQojIFRhYmxlIGZvciBSLXNxdWFyZWQgYW5kIFN0YW5kYXJkIERldmlhdGlvbgoKZGYyIDwtIGRhdGEuZnJhbWUoTW9kZWw9IGMoIk1vZGVsIDEiLCAiTW9kZWwgMiIsICJNb2RlbCAzIiksCiAgUl9TcXVhcmVkID0gYygiMC41OTciLCAiMC42NTQiLCAiMC42NTQiKSwgUmVzaWR1YWxfU3RhbmRhcmRfRXJyb3M9IGMoIjEwOC45MiIsICIxMDAuOTEiLCIxMDAuOTEiKSkKCiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZjIsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiUiBTcXVhcmVkIGFuZCBSZXNpZHVhbCBTdGFuZGFyZCBFcnJvciIpCmBgYAoKICBGb3Igb3VyIG1vZGVsIDEsIHdlIGZvdW5kIHRoYXQgZm9yIHRob3NlIG9ic2VydmF0aW9ucyB3aXRob3V0IGVxdWlwbWVudCwgdGhlcmUgd2FzIGEgUi1zcXVhcmVkIG9mIDAuNTk3LiBUaGlzIG1lYW5zIHRoYXQgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgZXhwbGFpbnMgYXBwcm94aW1hdGVseSA1OS43JSBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gdGhlIGRhdGEuIEluIG90aGVyIHdvcmRzLCB0aGUgbW9kZWwgMSBpcyBhYmxlIHRvIGFjY291bnQgZm9yIDU5LjclIG9mIHRoZSB2YXJpYXRpb24gaW4gdGhlIGRhdGEsIHdoaWxlIHRoZSByZW1haW5pbmcgNDAuMyUgb2YgdGhlIHZhcmlhdGlvbiBpcyB1bmV4cGxhaW5lZCBieSB0aGUgbW9kZWwuIFdoaWxlIHRoaXMgUi1zcXVhcmVkIGlzIG5vdCBpZGVhbCwgaXQgZG9lcyBzaG93IHRoYXQgdGhlcmUgaXMgYSBsYXJnZSBwZXJjZW50IG9mIGRhdGEgdGhhdCBpcyBleHBsYWluZWQuIEhvd2V2ZXIsIGZvciB0aGUgbW9kZWwgMiB3aXRoIGVxdWlwbWVudCwgdGhlcmUgd2FzIGFuIFItc3F1YXJlZCBvZiAwLjY1NC4gQXMgc3VjaCwgdGhlIG1vZGVsIGNhbiBleHBsYWluIDY1LjQlIG9mIHRoZSB2YXJpYW5jZSwgbGVhdmluZyAzNC42JSBvZiB0aGUgdmFyaWFuY2UgdW5hY2NvdW50ZWQgZm9yLiBTdGlsbCwgdGhpcyBpcyBub3QgYXMgaGlnaCBvZiB0aGUgUi1zcXVhcmVkIHRoYXQgd2Ugd2VyZSBleHBlY3RpbmcuIEhvd2V2ZXIsIHRoZXJlIGlzIHN0aWxsIGEgbGFyZ2UgYW1vdW50IG9mIHZhcmlhYmlsaXR5IHRoYXQgaXMgZXhwbGFpbmVkIGJ5IHRoZSBtb2RlbCAyLiBUaGlzIGJlY29tZXMgbW9yZSBpbnRlcmVzdGluZywgZXNwZWNpYWxseSwgd2hlbiBsb29raW5nIGF0IG1vZGVsIDMgaW4gd2hpY2ggd2UgaW5jbHVkZWQgdGhlIGludGVyYWN0aW9uIHZhcmlhYmxlIGFzIHdlbGwuIEZvciB0aGlzIG1vZGVsLCB0aGUgUi1zcXVhcmVkIHN0YXllZCBhbG1vc3QgZXhhY3RseSB0aGUgc2FtZSwgYnV0IGl0IGluY3JlYXNlZCBieSAwLjAwMDEuIEFzIHN1Y2gsIGZvciBib3RoIG1vZGVscyAyIGFuZCAzLCB3ZSBhcmUgYWJsZSB0byBleHBsYWluIGFyb3VuZCA2NyUgb2YgdGhlIHZhcmlhdGlvbiBmb3IgYm90aC4gV2hlbiBsb29raW5nIGF0IHRoZSBSLXNxdWFyZWQgZm9yIGFsbCB0aHJlZSBtb2RlbHMsIGl0IGlzIGNsZWFyIHRoYXQgdGhlIGxhdHRlciB0d28gbW9kZWxzIHRoYXQgYWNjb3VudCBmb3IgdGhlIGVxdWlwbWVudCB1c2VkIGJ5IHRoZSBsaWZ0ZXJzIHBlcmZvcm1zIGJldHRlci4gCiAgCiAgV2UgYWxzbyBsb29rZWQgaW50byB0aGUgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3Igb2YgYWxsIHRocmVlIG1vZGVscy4gRm9yIG91ciBtb2RlbCAyLCB0aGUgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IgaXMgMTAwLjkxLCB3aGljaCByZXByZXNlbnRzIHRoZSBlc3RpbWF0ZSBvZiB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBlcnJvciB0ZXJtIGluIHRoZSByZWdyZXNzaW9uIG1vZGVsLiBUaGlzIGlzIHNpbXBseSBhbiBlc3RpbWF0ZSBvZiB0aGUgYXZlcmFnZSBkaXN0YW5jZSB0aGF0IHRoZSBkYXRhIHBvaW50cyBmYWxsIGZyb20gdGhlIHJlZ3Jlc3Npb24gbGluZS4gVGhpcyByZXNpZHVhbCBzdGFuZGFyZCBlcnJvciB2YWx1ZSBzaG93cyB0aGF0IG9uIGF2ZXJhZ2UsIHRoZSBhY3R1YWwgdmFsdWVzIG9mIHRoZSByZXNwb25zZSB2YXJpYWJsZSBgVG90YWxLZ2AgYXJlIGV4cGVjdGVkIHRvIGRldmlhdGUgZnJvbSB0aGUgcHJlZGljdGVkIHZhbHVlcyBieSAxMDAtMjAwIGtnLiBGb3Igb3VyIG1vZGVsIDMgdGhhdCBhY2NvdW50cyBmb3IgdGhlIGludGVyYWN0aW9uIHRlcm0sIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBlcnJvciBpcyBhbHNvIDEwMC45MSBjb21wYXJlZCB0byB0aGF0IG9mIG1vZGVsIDEgKHdoaWNoIGlzIDEwOC45MikuIEFzIHN1Y2gsIHdlIGNhbiBjb25jbHVkZSB0aGUgc2FtZSBhcyBmb3IgdGhlIFItc3F1YXJlZCB0ZXN0cywgd2hlcmUgbW9kZWwgMiBhbmQgMywgdGhhdCBpbmNsdWRlIHRoZSBlcXVpcG1lbnQgdHlwZSwgaGF2ZSBtb3JlIGFjY3VyYWN5LS10aGlzIHRpbWUgaXMgZm9yIHdoZW4gaXQgY29tZXMgdG8gdGhlIHNpemUgb2Ygb3VyIHByZWRpY3Rpb24gZXJyb3JzLgogIAoKIyMgTmVzdGVkIEYtVGVzdAoKQnkgdXNpbmcgYSBoeXBvdGhlc2lzIG5lc3RlZCBGIHRlc3QsIHdlIGRpcmVjdGx5IGNvbXBhcmUgb3VyIDMgbW9kZWxzOgoKJCRbVG90YWxLZyB8IEJvZHl3ZWlnaHQsU2V4TV0gPSAgXGJldGFfMCArIFxiZXRhXzEgKiBCb2R5d2VpZ2h0ICtcYmV0YV8yICpTZXhNJCQKPGJyPgokJFtUb3RhbEtnIHwgQm9keXdlaWdodCxTZXhNLEVxdWlwbWVudF0gPSAgXGJldGFfMCArIFxiZXRhXzEgKiBCb2R5d2VpZ2h0ICtcYmV0YV8yICpTZXhNICsgXFwgXGJldGFfMypFcXVpcG1lbnRfe3Jhd30rXGJldGFfNCpFcXVpcG1lbnRfe3NpbmdsZS1wbHl9KyBcYmV0YV81KkVxdWlwbWVudF97d3JhcHN9ICQkCjxicj4KJCRbVG90YWxLZyB8IEJvZHl3ZWlnaHQsU2V4LEVxdWlwbWVudF0gPSAgXGJldGFfMCArIFxiZXRhXzEgKiBCb2R5d2VpZ2h0ICtcYmV0YV8yICpTZXhNICsgXFwgXGJldGFfMypFcXVpcG1lbnRfe3Jhd30rXGJldGFfNCpFcXVpcG1lbnRfe3NpbmdsZS1wbHl9K1xiZXRhXzUqRXF1aXBtZW50X3t3cmFwc30gClxcIFxiZXRhXzYqRXF1aXBtZW50X3tyYXd9KlNleE0rXGJldGFfNCpFcXVpcG1lbnRfe3NpbmdsZS1wbHl9KlNleE0rClxcXGJldGFfNSpFcXVpcG1lbnRfe3dyYXBzfSpTZXhNICQkCjxicj4KCkZvciBvdXIgZmlyc3QgRiB0ZXN0IGJldHdlZW4gbW9kZWwgMSBhbmQgbW9kZWwgMjoKCj4gTnVsbCBIeXBvdGhlc2lzICRIXzAgOiBcYmV0YV97RXF1aXBtZW50fSA9IDAkOiBPdXIgc21hbGxlciBuZXN0ZWQgbW9kZWwgd2l0aCBqdXN0ICRCb2R5d2VpZ2h0JCBhbmQgJFNleCQgaXMgY29ycmVjdDsgJEVxdWlwbWVudCQgZG9lcyBub3QgaGF2ZSBhbiBpbXBhY3Qgb24gJFRvdGFsS2ckIGFmdGVyIGFjY291bnRpbmcgZm9yICRCb2R5d2VpZ2h0JCBhbmQgJFNleCQuCgo+IEFsdGVybmF0aXZlIEh5cG90aGVzaXMgJEhfQTogXGJldGFfe0VxdWlwbWVudH0gXG5lcSAwJDogT3VyIHNtYWxsZXIgbW9kZWwgaXMgbm90IGNvcnJlY3QgYW5kIG91ciByZW1vdmVkIHZhcmlhYmxlICgkRXF1aXBtZW50JCkgaGFzIGEgbm9uLXplcm8gc2xvcGUgaW4gdGhlIHBvcHVsYXRpb24gYW5kLCB0aGVyZWZvcmUsIGhhcyBhbiBpbXBhY3Qgb24gYSB3ZWlnaHRsaWZ0ZXIncyBwZXJmb3JtYW5jZS4gCjxicj4KCgpGb3Igb3VyIHNlY29uZCBGIHRlc3QgYmV0d2VlbiBtb2RlbCAyIGFuZCBtb2RlbCAzOgoKPiBOdWxsIEh5cG90aGVzaXMgJEhfMCA6IFxiZXRhX3tFcXVpcG1lbnR9ID0gMCQ6IE91ciBtb2RlbCB3aXRob3V0IGFuIGludGVyYWN0aW9uIHRlcm0gaXMgY29ycmVjdDsgJFNleCQgZG9lcyBub3QgaGF2ZSBhbiBpbXBhY3Qgb24gaG93ICRFcXVpcG1lbnQkIGFmZmVjdHMgJFRvdGFsS2ckLgoKPiBBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzICRIX0E6IFxiZXRhX3tFcXVpcG1lbnR9IFxuZXEgMCQ6IE91ciBtb2RlbCB3aXRob3V0IGFuIGludGVyYWN0aW9uIHRlcm0gaXMgbm90IGNvcnJlY3QgYW5kIG91ciByZW1vdmVkIGludGVyYWN0aW9uIHRlcm0gYmV0d2VlbiAkU2V4JCBhbmQgJEVxdWlwbWVudCQgaGFzIGEgbm9uLXplcm8gc2xvcGUgaW4gdGhlIHBvcHVsYXRpb24gYW5kLCB0aGVyZWZvcmUsIGhhcyBhbiBpbXBhY3Qgb24gYSB3ZWlnaHRsaWZ0ZXIncyBwZXJmb3JtYW5jZS4gCgpCZWxvdyBhcmUgdGhlIHJlc3VsdHMgZnJvbSB0aGUgMiBGLXRlc3RzIHdlIGNhcnJpZWQgb3V0OgoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsIGVjaG8gPSBGQUxTRX0KYW5vdmEobW9kMSxtb2QyKQphbm92YShtb2QyLG1vZDMpCmBgYAoKPiBUZXN0IHN0YXRpc3RpY3M6IDE3LjQ2CgpGb3IgYW4gRiBUZXN0IGluIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwsIHRoZSB0ZXN0IHN0YXRpc3RpYyBpcyBhIHJhdGlvIGNvbXBhcmluZyB0aGUgc3VtIG9mIHNxdWFyZWQgcmVzaWR1YWxzLiBUaGlzIG1lYW5zIHRoYXQgJEhfMCQgaXMgdHJ1ZSBpZiAkRiQgfiAxLiBPdXIgdGVzdCBzdGF0aXN0aWMgd2hlbiB3ZSBhcmUgY29tcGFyaW5nIGJldHdlZW4gbW9kZWwgMSBhbmQgbW9kZWwgMiBpcyAxNzA2NC4gV2hlbiB3ZSBhcmUgY29tcGFyaW5nIGJldHdlZW4gbW9kZWwgMiBhbmQgbW9kZWwgMywgdGhlIHRlc3Qgc3RhdGlzdGljcyBpcyAxNy40NTcuIEJvdGggYXJlIHJhdGhlciBmYXIgZnJvbSAxIGFuZCBzdWdnZXN0IHRoYXQgbW9kZWwgMyBpcyB0aGUgbW9zdCBwcmVmZXJhYmxlIG91dCBvZiB0aGUgMyBtb2RlbHMsIGJ1dCB0aGVyZSBhcmUgbm8gcnVsZXMgZm9yIOKAnGhvdyBmYXIgaXMgZmFy4oCdLiAKCj4gUC12YWx1ZTogMi41KjEwXi0xMSA9ICAwLjAwMDAwMDAwMDAyNQoKRm9yIGEgdGhyZXNob2xkIG9mICRcYWxwaGE9MC4wNSQsIG91ciBwLXZhbHVlIGZvciB0aGUgYm90aCBGLXRlc3RzIGlzIHZlcnkgbXVjaCBiZWxvdyB0aGUgdGhyZXNob2xkIChhbG1vc3QgY2xvc2UgdG8gemVybyksIHN1Z2dlc3RpbmcgdGhhdCBpdCBpcyB2ZXJ5IHVubGlrZWx5IHRvIGhhdmUgb2JzZXJ2ZWQgYSBiaWcgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gbW9kZWxzIGlmIHRoZSBzbWFsbGVyIG5lc3RlZCBtb2RlbCB3ZXJlIHRydWUuIFRoZXJlZm9yZSwgd2UgcmVqZWN0IGJvdGggdGhlICRIXzAkJ3MgdGhhdCB0aGUgbW9kZWwgd2l0aCBvbmx5IGBTZXhgIGFuZCBgQm9keXdlaWdodGAgYW5kIHRoZSBtb2RlbCB3aXRob3V0IGFuIGludGVyYWN0aW9uIHRlcm0gYmV0d2VlbiBgU2V4YCBhbmQgYEJvZHl3ZWlnaHRgIGlzIGNvcnJlY3QuIFdlIGFyZSwgb24gdGhlIG90aGVyIGhhbmQsIGluIGZhdm9yIG9mIG1vZGVsIDMgYXMgaXQgZml0cyBvdXIgZGF0YSBzdGF0aXN0aWNhbGx5IGJldHRlci4gCgojIyBSZXNpZHVhbHMgdmVyc3VzIEZpdHRlZCBWYWx1ZXMgUGxvdAoKYGBge3Isd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQojIFBsb3R0aW5nIFJlc2lkdWFscyB2cyBGaXR0ZWQgVmFsdWVzIGZvciBGaW5hbCBNb2RlbDoKYXVnbWVudChtb2QzKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSAucmVzaWQsIHggPSAuZml0dGVkKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC4wNSkgKyAKICBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAicmVkIikgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoeCA9ICJGaXR0ZWQgVmFsdWVzIiwgCiAgeSA9ICJSZXNpZHVhbHMiLCAKICB0aXRsZSA9ICIgRmlnLiAyOiBSZXNpZHVhbHMgdnMgRml0dGVkIFZhbHVlcyBmb3IgRmluYWwgTW9kZWwiKSArIHhsaW0oMjAwLCAxMTAwKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKICBCeSBleGFtaW5pbmcgRmlndXJlIDIsIHdlIGNhbiBvYnNlcnZlIHRoZSBSZXNpZHVhbHMgdnMgRml0dGVkIHZhbHVlcyBvZiBvdXIgZmluYWwgbW9kZWwuIEZyb20gdGhlIHBsb3Qgd2UgY2FuIGFzc2VzcyBob3cgZ29vZCBvdXIgZmluYWwgbW9kZWwgY2FuIGZpdCBvdXIgZGF0YS4gVGhlIGhvcml6b250YWwgbGluZSBhdCAwIGNvcnJlc3BvbmRzIHRvIHRoZSBsaW5lIG9mIHBlcmZlY3QgZml0LCBpbiB3aGljaCB0aGUgcHJlZGljdGVkIHZhbHVlcyBhbmQgYWN0dWFsIHZhbHVlcyBmcm9tIHRoZSBkYXRhIGFyZSBlcXVhbC4gT3ZlcmFsbCwgdGhpcyBwbG90IHN1Z2dlc3RzIHRoYXQgb3VyIGZpbmFsIG1vZGVsIGlzIGEgZ29vZCBmaXQgZm9yIHRoZSBkYXRhLCBhcyB0aGUgc21vb3RoIGxpbmUgaXMsIGluIGl0cyBtYWpvcml0eSwgY2xvc2UgdG8gdGhlIGxpbmUgb2YgcGVyZmVjdCBmaXQuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIG1vZGVsIGlzIGFjY3VyYXRlbHkgcHJlZGljdGluZyBtb3N0IG9mIHRoZSBkYXRhIHBvaW50cy4gWWV0LCBpdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IG91ciBtb2RlbCBvdmVycHJlZGljdHMgdGhlIGxhcmdlIGZpdHRlZCB2YWx1ZXMgKHNob3duIGJ5IHRoZSBuZWdhdGl2ZSByZXNpZHVhbHMpLCB5ZXQgd2UgY2FuIG9ic2VydmUgdGhhdCB0aGVzZSBhcmUgZmV3IGRhdGEgcG9pbnRzIGNvbXBhcmVkIHRvIG91ciBsYXJnZSBkYXRhc2V0LgogIAojIENvbmNsdXNpb24KCiMjIEdlbmVyYWwgVGFrZWF3YXlzCgogIEZyb20gdGhlIHJlc3VsdHMgb2Ygb3VyIG1vZGVsIGludGVycHJldGF0aW9uIGFuZCBldmFsdWF0aW9uLCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCBtb2RlbCAzIHBlcmZvcm1zIG1vcmUgcHJlZmVyYWJseSB0aGFuIGFsbCBvZiBvdXIgbW9kZWxzLiBUaHJvdWdoIG1vZGVsIDMsIGl0IGlzIHJldmVhbGVkIHRoYXQgYWx0aG91Z2ggYmlvbG9naWNhbCBmYWN0b3JzIHBsYXkgYW4gaW1wb3J0YW50IHJvbGUgaW4gYSBsaWZ0ZXIncyBwZXJmb3JtYW5jZSwgdGhlcmUgYXJlIG90aGVyIGZhY3RvcnMgc3VjaCBhcyB0aGUgZXF1aXBtZW50IHRoYXQgdGhleSB1c2UgdGhhdCBpbXBhY3QgdGhlaXIgcGVyZm9ybWFuY2UuIFRoZXJlIGlzIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGJvZHkgd2VpZ2h0IG9mIGEgbGlmdGVyIGFuZCB0aGUgdG90YWwga2lsb2dyYW1zIHRoYXQgdGhleSBjYW4gbGlmdC4gRnVydGhlcm1vcmUsIHRoZSBzZXggYXNzaWduZWQgYXQgYmlydGggcGxheXMgYSBjcml0aWNhbCByb2xlIG9uIGhvdyBtdWNoIHdlaWdodCBhIGNvbXBldGl0b3IgY2FuIGxpZnQuIE91ciBtb2RlbCBmb3VuZCB0aGF0IG9uIGF2ZXJhZ2UsIHRoZSBlc3RpbWF0ZWQgaW5jcmVhc2UgaW4gdGhlIHRvdGFsIGtnIGFzc29jaWF0ZWQgd2l0aCBhIDEgdW5pdCBpbmNyZWFzZSBpbiBhIGxpZnRlcuKAmXMgYm9keSB3ZWlnaHQgaXMgMy40NCBrZyBmb3IgYSBsaWZ0ZXIsIGhvbGRpbmcgYWxsIG90aGVyIHZhcmlhYmxlcyBjb25zdGFudC4gSG9sZGluZyBib2R5IHdlaWdodCBhbmQgZXF1aXBtZW50IGNvbnN0YW50LCB0aGUgZXN0aW1hdGVkIGF2ZXJhZ2UgdG90YWwga2lsb2dyYW1zIGxpZnRlZCBieSBhIGxpZnRlciBvZiBzZXggbWFsZSBpcyAxOTMuNjEga2cgaGlnaGVyIHRoYW4gYSBsaWZ0ZXIgd2hvc2Ugc2V4IGFzc2lnbmVkIGF0IGJpcnRoIGlzIGZlbWFsZS4gCiAgCiAgSW4gYWRkaXRpb24sIGVxdWlwbWVudCBhbHNvIHBsYXlzIGEgY3JpdGljYWwgcm9sZSBpbiBhIGxpZnRlcidzIGFiaWxpdHkgdG8gbGlmdCBoZWF2aWVyIHdlaWdodHMuIEFjY29yZGluZyB0byBvdXIgbW9kZWwsIGZlbWFsZSBsaWZ0ZXJzIHRoYXQgdXNlIG5vIGVxdWlwbWVudCBhcmUgZXhwZWN0ZWQgdG8gbGlmdCBvbiBhdmVyYWdlIDc3LjEyIGtnIGxlc3MgdGhhbiBmZW1hbGUgbGlmdGVycyB0aGF0IHVzZSBtdWx0aS1wbHkgZXF1aXBtZW50LCBob2xkaW5nIGFsbCBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQuIExpa2V3aXNlLCB0aGUgc2xvcGUgY29lZmZpY2llbnQgb2YgZXF1aXBtZW50IHdyYXBzIGluZGljYXRlcyB0aGF0IGZlbWFsZSBsaWZ0ZXJzIHdobyB1c2Ugd3JhcHMgbGlmdCwgb24gYXZlcmFnZSwgODQuMjUga2cgbGVzcyB0aGFuIGZlbWFsZSBsaWZ0ZXJzIHdobyB1c2UgbXVsdGktcGx5IGVxdWlwbWVudC4gTGFzdGx5LCBmZW1hbGUgbGlmdGVycyB3aG8gdXNlIHNpbmdsZS1wbHkgZXF1aXBtZW50IGNhbiBsaWZ0LCBvbiBhdmVyYWdlLCAyLjcxIGtnIG1vcmUgdGhhbiBmZW1hbGUgbGlmdGVycyB3aG8gdXNlIG11bHRpLXBseSBlcXVpcG1lbnQsIGhvbGRpbmcgb3RoZXIgdmFyaWFibGVzIGNvbnN0YW50LiAKICAKICBXZSBhbHNvIG9ic2VydmVkIGZyb20gb3VyIG1vZGVsIHRoYXQgc2V4IGhhcyBhIG1vZGlmaWNhdGlvbiBlZmZlY3Qgb24gdGhlIGVxdWlwbWVudCB1c2VkLiBNYWxlIEluZGl2aWR1YWxzIHdobyBkbyBub3QgdXNlIGFueSBlcXVpcG1lbnQgY29tcGV0aXRvcnMgYXJlIGV4cGVjdGVkIHRvIGxpZnQgb24gYXZlcmFnZSAyNS4xNSBrZyBsZXNzIHRoYW4gZmVtYWxlIGxpZnRlcnMgdGhhdCBkbyBub3QgdXNlIGFueSBlcXVpcG1lbnQgY29tcGFyZWQgdG8gY29tcGV0aXRvcnMgKDEwOS40IGtnIGxlc3MpIHRoYXQgdXNlIG11bHRpLXBseSBlcXVpcG1lbnQuIEZyb20gdGhlc2Ugb2JzZXJ2YXRpb25zLCB3ZSB0aGluayB0aGF0IGJpb2xvZ2ljYWwgZmFjdG9ycyBzdWNoIGFzIHRoZSBzZXggYXNzaWduZWQgYXQgYmlydGggb2YgYSBwZXJzb24sIHRoZWlyIGJvZHkgd2VpZ2h0IGFuZCBvdGhlciBmYWN0b3JzIHN1Y2ggYXMgdGhlIGVxdWlwbWVudCB0aGF0IGEgbGlmdGVyIHVzZXMgZGV0ZXJtaW5lcyBhIGxpZnRlcuKAmXMgcGVyZm9ybWFuY2UuIAoKIyMgTGltaXRhdGlvbnMKCiAgQXMgd2UgZXhwbGFpbmVkIGluIHRoZSBkYXRhIGNsZWFuaW5nIHByb2Nlc3MsIHdlIGZpbHRlcmVkIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIG91ciBjYXNlcyBhcyB0aGVyZSB3YXMgbWlzc2luZyBkYXRhLCBvciBzb21lIGluY29uc2lzdGVuY2llcywgd2hpY2ggbWlnaHQgaGF2ZSBhcmlzZW4gZHVyaW5nIHRoZSBkYXRhIGNvbXBpbGF0aW9uIHByb2Nlc3MuIEFsdGhvdWdoIHdlIHdlcmUgbGVmdCB3aXRoIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIGRhdGEsIHdlIGFyZSB1bmNlcnRhaW4gYWJvdXQgaWYgYWxsIHRoZXNlIHZhbHVlcyBhY2N1cmF0ZWx5IHJlcHJlc2VudCB0aGUgYWN0dWFsIHZhbHVlcyBvciBpbmZvcm1hdGlvbiBmb3IgZWFjaCBwYXJ0aWNpcGFudC4gRnVydGhlcm1vcmUsIHRoaXMgZGF0YXNldCBkaWQgbm90IGNvbnRhaW4gb3RoZXIgdmFyaWFibGVzIHRoYXQgY291bGQgaGF2ZSBiZWVuIHJlbGV2YW50IHRvIG91ciByZXNlYXJjaCBxdWVzdGlvbnMsIHN1Y2ggYXMgdGhlIHRpbWUgZWFjaCBwYXJ0aWNpcGFudCBoYXMgYmVlbiBsaWZ0aW5nIChpLmUuIHllYXJzIG9mIGV4cGVyaWVuY2UsIG9yIHRoZSBudW1iZXIgb2YgY29tcGV0aXRpb25zKSwgd2hpY2ggbWlnaHQgaGF2ZSBwcm92aWRlZCBmdXJ0aGVyIGluc2lnaHQgaW50byBzb21lIG9mIHRoZSByZWxhdGlvbnNoaXBzIHdpdGggb3VyIG91dGNvbWUgdmFyaWFibGUuIFdlIGFsc28gdW5kZXJzdGFuZCB0aGF0IHRoZXJlIHdlcmUgbWFueSBpbmNvbnNpc3RlbmNpZXMgaW4gZWFjaCBkYXRhIG9ic2VydmF0aW9uLiBUaGlzIGNvbWVzIGZyb20gdGhlIGZhY3QgdGhhdCB0aGVyZSB3YXMgbm90IG9uZSBzdGFuZGFyZGl6ZWQgbWV0aG9kIG9mIGNvbGxlY3RpbmcgZGF0YSwgYXMgaXQgd2FzIHVwIHRvIGVhY2ggY29tcGV0aXRpb24gdG8gcmVjb3JkLiBXZSBoYXZlIHRyaWVkIHRvIG1pdGlnYXRlIHRoZXNlIGVmZmVjdHMgYXMgbXVjaCBhcyBwb3NzaWJsZSBieSBjbGVhbmluZyB0aGUgZGF0YSwgYnV0IHJlY29nbml6ZSB0aGF0IHRoZSBkYXRhIGlzIG5vdCBwZXJmZWN0LiAKCiAgSW4gYWRkaXRpb24sIHRoaXMgZGF0YXNldCBpcyB1c2VmdWwgaW4gZGlmZmVyZW50IGRvbWFpbnMgYXMgaXQgaGVscHMgdG8gYW5hbHl6ZSB0aGUgcGF0dGVybnMgYW5kIHRyZW5kcyBvZiBwb3dlcmxpZnRpbmcgY29tcGV0aXRpb25zLCBhbmQgaW5mb3JtIHRoZSBnZW5lcmFsIHB1YmxpYy4gTmV2ZXJ0aGVsZXNzLCB0aGVyZSBhcmUgc29tZSBldGhpY2FsIGNvbmNlcm5zLCBpbiByZWxhdGlvbiB0byBwcml2YWN5LCBhcyBpdCBwcm92aWRlcyB0aGUgbmFtZSBvZiBlYWNoIGNvbXBldGl0b3IsIGFzIHdlbGwgdGhlaXIgcGVyc29uYWwgaW5mb3JtYXRpb24gdGhhdCBtaWdodCBwdXQgdGhlbSBpbiB0aGUgbG9vcCBvZiBwdWJsaWMgc2NydXRpbnkuIE1vcmVvdmVyLCB3ZSBhcmUgaGVzaXRhbnQgaWYgdGhlIGRpc2Nsb3N1cmUgb2YgdGhpcyBpbmZvcm1hdGlvbiB3YXMgY29uc2Vuc3VhbC4gT24gYW5vdGhlciBub3RlLCB3ZSBhY2tub3dsZWRnZSB0aGF0IG91ciBzdHVkeSBtaWdodCByZWluZm9yY2Ugc29tZSBiaWFzZXMgYW5kIHN0ZXJlb3R5cGVzIGlmIHRoZXNlIHJlc3VsdHMgYXJlIG5vdCB3ZWxsIGV4cGxhaW5lZCBhbmQgY29udGV4dHVhbGl6ZWQgdG8gdGhlIHB1YmxpYyBzaW5jZSBvdXIgc3R1ZHkgZm9jdXNlcyBtZXJlbHkgb24gYSBsaWZ0ZXLigJlzIHBlcmZvcm1hbmNlIGJhc2VkIG9uIHRoZSB0b3RhbCBraWxvZ3JhbXMgdGhleSBjYW4gbGlmdC4gV2UgYWxzbyByZWNvZ25pemUgdGhhdCB0aGUgUi1zcXVhcmVkIG9mIG91ciBtb2RlbHMgY291bGQgYmUgY29uc2lkZXJhYmx5IGhpZ2hlci4gV2hpbGUgdGhleSB3ZXJlIHNvbWV3aGF0IHN1ZmZpY2llbnQgaW4gZXhwbGFpbmluZyB2YXJpYXRpb24sIHRoZXJlIGlzIGEgcmVsYXRpdmVseSBsYXJnZSBhbW91bnQgb2YgdmFyaWF0aW9uIHRoYXQgaXMgbGVmdCB1bmV4cGxhaW5lZC4gRnV0dXJlIHJlc2VhcmNoIGNvdWxkIGJ1aWxkIHVwb24gdGhpcywgdHJ5aW5nIHRvIHJhaXNlIHRoaXMgUi1zcXVhcmVkIHRlc3QgdmFsdWUsIGFuZCBhbHNvIGNvbnNpZGVyaW5nIHRoZSByZW1vdmFsIG9mIGV4dHJlbWUgb3V0bGllcnMuIFRvIGNvbmNsdWRlLCBpdCB3b3VsZCBiZSBpbnRlcmVzdGluZyBmb3IgZnVydGhlciBzdHVkeSB0byBleHBsb3JlIHRoZSBzdGF0aXN0aWNhbCByZWxhdGlvbnNoaXAgb2Ygb3RoZXIgcHJlZGljdG9yIHZhcmlhYmxlcyBzdWNoIGEgbGlmdGVy4oCZcyBudXRyaXRpb24sIG1lbnRhbCBmYWN0b3JzLCBhbmQgaW5qdXJ5IGhpc3Rvcnkgd2l0aCB0aGUgdG90YWwgb3V0Y29tZSBvZiB3ZWlnaHQgbGlmdGVkIGluIGtpbG9ncmFtcywgeWV0IHRoZXNlIHZhcmlhYmxlcyBhcmUgbm90IGluY2x1ZGVkIGluIG91ciBkYXRhc2V0LgoKCiMgQXBwZW5kaXgKCiMjIFdvcmtzIENpdGVkIAoKSGVnZ2VzZXRoLCBCcmlhbm5hLCBNeWludCwgTGVzbGllLCBhbmQgR3JpbmRlLCBLZWxzZXkuIFNUQVQgMTU1IE5vdGVzLiBKYW51YXJ5IDE1LCAyMDIxLgpodHRwczovL2JjaGVnZ2VzZXRoLmdpdGh1Yi5pby9TdGF0MTU1Tm90ZXMvCgpTaWVtLCBCcm9va2UuIOKAnFJhdyB2cyBFcXVpcHBlZCBQb3dlcmxpZnRpbmcu4oCdIEJhckJlbmQsIEp1bHkgMTAsIDIwMTcuIGh0dHBzOi8vYmFyYmVuZC5jb20vcmF3LXZzLWVxdWlwcGVkLXBvd2VybGlmdGluZy8KCiMjIENvZGUgQXBwZW5kaXgKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9RkFMU0V9CiMgTG9hZGluZyBsaWJyYXJpZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoTkhBTkVTKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CiNMb2FkaW5nIGRhdGEKcG93ZXIgPC0gcmVhZF9jc3YoInBvd2VyLmNzdiIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CiNDbGVhbmluZyBkYXRhCnBvd2VyX2NsZWFuIDwtIHBvd2VyICU+JQogIGZpbHRlcighaXMubmEoQmVzdDNTcXVhdEtnKSwgCiAgICAgICAgICFpcy5uYShCZXN0M0JlbmNoS2cpLAogICAgICAgICAhaXMubmEoQmVzdDNEZWFkbGlmdEtnKSwKICAgICAgICAgIWlzLm5hKFRlc3RlZCksIAogICAgICAgICAhaXMubmEoU2V4KSwKICAgICAgICAgIWlzLm5hKEJvZHl3ZWlnaHRLZyksCiAgICAgICAgIEVxdWlwbWVudCAhPSAnU3RyYXBzJywgCiAgICAgICAgIEFnZSA+PSAxNi4wICkgJT4lCiAgc2VsZWN0KFNleCwgCiAgICAgICAgIEVxdWlwbWVudCwgCiAgICAgICAgIEFnZSwgQWdlQ2xhc3MsIAogICAgICAgICBCb2R5d2VpZ2h0S2csIFdlaWdodENsYXNzS2csIAogICAgICAgICBCZXN0M1NxdWF0S2csIEJlc3QzQmVuY2hLZywgQmVzdDNEZWFkbGlmdEtnLCBUb3RhbEtnLCAKICAgICAgICAgSVBGUG9pbnRzKQpgYGAKCgpgYGB7cixldmFsPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KIyBFREE6IEZpZ3VyZSAxIDogV2VpZ2h0IExpZnRlZCBieSBMaWZ0ZXJzIG9mIERpZmZlcmVudCBXZWlnaHRzIGJ5IFNleCBhbmQgdGhlIEVxdWlwbWVudCBVc2VkCmdncGxvdChwb3dlcl9jbGVhbikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBCb2R5d2VpZ2h0S2csIHkgPSBUb3RhbEtnLCBjb2xvciA9IEVxdWlwbWVudCksCiAgYWxwaGEgPSAwLjUsCiAgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoU2V4IH4gRXF1aXBtZW50KSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBCb2R5d2VpZ2h0S2csIHkgPSBUb3RhbEtnKSwKICBhbHBoYSA9IDAuNSwKICBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh0aXRsZSA9ICJGaWcuIDE6IFdlaWdodCBMaWZ0ZWQgYnkgTGlmdGVycyBvZiBEaWZmZXJlbnQgV2VpZ2h0cyBieSBTZXggYW5kIHRoZSBFcXVpcG1lbnQgVXNlZCIsCiAgeCA9ICIgTGlmdGVyJ3MgV2VpZ2h0IChpbiBLZykiLCAKICB5ID0gIiBUb3RhbCBXZWlnaHQgTGlmdGVkIChpbiBLZykiKSArCiAgdGhlbWUoIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJncmV5ODciKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5ODciKSwKICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4yLCBjb2xvdXIgPSAiZ3JleTcwIiksCiAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjIpLCAKICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICd3aGl0ZScsIGNvbG9yID0gJ3doaXRlJyksIAogIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoCiAgZmlsbCA9ICJ3aGl0ZSIsIAogIGNvbG9yID0gImdyZXk3MCIsIAogIGxpbmUpKSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArCiAgeGxpbSgyNSwgMTAwKSArIAogIHlsaW0oMCwgMTA4MCkgICAKYGBgCgpgYGB7cixldmFsPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KI0ZpdHRpbmcgbW9kZWxzCm1vZDEgPC0gcG93ZXJfY2xlYW4gJT4lCiAgd2l0aChsbShUb3RhbEtnIH4gU2V4K0JvZHl3ZWlnaHRLZykpCgptb2QyIDwtIHBvd2VyX2NsZWFuICU+JSAKICB3aXRoKGxtKFRvdGFsS2cgfiBTZXgrQm9keXdlaWdodEtnK0VxdWlwbWVudCkpCgptb2QzIDwtIHBvd2VyX2NsZWFuICU+JQogIHdpdGgobG0oVG90YWxLZyB+Qm9keXdlaWdodEtnK1NleCpFcXVpcG1lbnQpKQoKCiMgQ2FsY3VsYXRpbmcgZXN0aW1hdGVzLCBzdGFuZGFyZCBlcnJvciwgdGVzdCBzdGF0aXN0aWNzLCBwLXZhbHVlczoKCm1vZDFfZml0dGVkPC10aWR5KG1vZDEpCgptb2QyX2ZpdHRlZDwtdGlkeShtb2QyKQoKbW9kM19maXR0ZWQ8LXRpZHkobW9kMykKCm1vZDFfY29uZmludDwtY29uZmludChtb2QxKQoKbW9kMl9jb25maW50PC1jb25maW50KG1vZDIpCgptb2QzX2NvbmZpbnQ8LWNvbmZpbnQobW9kMykKCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQojQnVpbGRpbmcgZml0dGVkIG1vZGVsIDEgdGFibGUKZGYxIDwtIGRhdGEuZnJhbWUoQ29lZmZpY2llbnRzPSBjKCJJbnRlcmNlcHQiLCAiU2V4TWFsZSIsIkJvZHl3ZWlnaHQiKSwKICAgICAgICAgICAgICAgICAgRXN0aW1hdGVzID0gYygiMTA4LjY1IiwgIjE4MS4zOSIsICIzLjMwIiksIAogICAgICAgICAgICAgICAgICBTdGFuZGFyZF9FcnJvcnMgPSBjKCIwLjc3IiwgIjAuNDgiLCAiMC4wMSIpLAogICAgICAgICAgICAgICAgICBUZXN0X1N0YXRpc3RpY3MgPWMoIjE0MS45NiIsIjM3OC4wNSIsICIzMjkuMDUiKSwKICAgICAgICAgICAgICAgICAgUC52YWx1ZT1jKCIwIiwiMCIsIjAiKSwKICAgICAgICAgICAgICAgICAgQ29uZmluZGVuY2VfaW50ZXJ2YWw9YygiKDEwNy4xNSwgMTEwLjE1KSIsIigxODAuNDUsIDE4Mi4zMykiLCIoMy4yOCwgMy4zMikiKSkKCiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZjEsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiRml0dGVkIE1vZGVsIDEgKEVzdGltYXRlcywgQ29uZmlkZW5jZSBJbnRlcnZhbHMsIFAtdmFsdWVzKSIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CiNCdWlsZGluZyBmaXR0ZWQgbW9kZWwgMiB0YWJsZQpkZjIgPC0gZGF0YS5mcmFtZShDb2VmZmljaWVudHM9IGMoIkludGVyY2VwdCIsIlNleE1hbGUiLCJCb2R5d2VpZ2h0IiwgIkVxdWlwbWVudFJhdyIsIkVxdWlwbWVudFNpbmdsZS1wbHkiLCJFcXVpcG1lbnRXcmFwcyIpLAogICAgICAgICAgICAgICAgICBFc3RpbWF0ZXMgPSBjKCIxNjQuMjgiLCAiMTcwLjU2IiwgIjMuNDQiLCItOTguMTYiLCItMTUuNzYiLCItOTguMzYiKSwgCiAgICAgICAgICAgICAgICAgIFN0YW5kYXJkX0Vycm9ycyA9IGMoIjIuMzUiLCAiMC40NSIsICIwLjAxIiwiMi4yNSIsIjIuMjUiLCIyLjM3IiksCiAgICAgICAgICAgICAgICAgIFRlc3RfU3RhdGlzdGljcyA9YygiNjkuODciLCIzODEuNDAiLCAiMzY5LjI5IiwiLTQzLjcxIiwiLTcuMDIiLCItNDEuNCIpLAogICAgICAgICAgICAgICAgICBQLnZhbHVlPWMoIjAuMDAiLCIwLjAwIiwiMC4wMCIsIjAuMDAiLCIwLjAwIiwiMC4wMCIpLAogICAgICAgICAgICAgICAgICBDb25maW5kZW5jZV9pbnRlcnZhbD1jKCIoMTU5LjY4LCAxNjguODkpIiwiKDE2OS42OCwgMTcxLjQzKSIsIigzLjQyLCAzLjQ2KSIsIigtMTAyLjU2LCAtOTMuNzUpIiwiKC0yMC4xNiwgLTExLjM2KSIsIigtMTAzLjAxLCAtOTMuNzIpIikpCgojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYyLCBhbGlnbiA9IGMoImwiLCAiYyIpLCBjYXB0aW9uID0gIkZpdHRlZCBNb2RlbCAyIChFc3RpbWF0ZXMsIENvbmZpZGVuY2UgSW50ZXJ2YWxzLCBQLXZhbHVlcykiKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQojQnVpbGRpbmcgZml0dGVkIG1vZGVsIDMgdGFibGUKZGYzIDwtIGRhdGEuZnJhbWUoQ29lZmZpY2llbnRzPSBjKCJJbnRlcmNlcHQiLCAgIkJvZHl3ZWlnaHQiLCJTZXhNYWxlIiwiRXF1aXBtZW50UmF3IiwiRXF1aXBtZW50U2luZ2xlLXBseSIsIkVxdWlwbWVudFdyYXBzIiwiU2V4TTpFcXVpcG1lbnRSYXciLCJTZXhNOkVxdWlwbWVudFNpbmdsZS1wbHkiLCJTZXhNOkVxdWlwbWVudFdyYXBzIiksCiAgICAgICAgICAgICAgICAgIEVzdGltYXRlcyA9IGMoIjE0NC43NyIsICIzLjQ0IiwgIjE5My42MSIsIi03Ny4xMiIsIjIuNzEiLCItODQuMjUiLCItMjUuMTUiLCItMjEuNDYiLCItMTUuNDMiKSwgCiAgICAgICAgICAgICAgICAgIFN0YW5kYXJkX0Vycm9ycyA9IGMoIjUuODUiLCAiMC4wMSIsICI2LjMwIiwiNS44MyIsIjUuODQiLCI2LjAyIiwiNi4zMiIsIjYuMzMiLCI2LjU1IiksCiAgICAgICAgICAgICAgICAgIFRlc3RfU3RhdGlzdGljcyA9YygiMjQuNzUiLCIzNjguOTgiLCAiMzAuNzIiLCItMTMuMjIiLCIwLjQ2IiwiLTE0LjAwIiwiLTMuOTciLCItMy4zOSIsIi0yLjM1IiksCiAgICAgICAgICAgICAgICAgIFAudmFsdWU9YygiMC4wMCIsIjAuMDAiLCIwLjAwIiwiMC4wMCIsIjAuNjQiLCIwLjAwIiwiMC4wMCIsIjAuMDAiLCIwLjAyIiksCiAgICAgICAgICAgICAgICAgIENvbmZpbmRlbmNlX2ludGVydmFsPWMoIigxMzMuMzAsIDE1Ni4yNCkiLCIoMy40MiwgMy40NikiLCIoMTgxLjI2LCAyMDUuOTYpIiwiKC04OC41NiwgLTY1LjY5KSIsIiggLTguNzQsIDE0LjE1KSIsIigtOTYuMDUsIC03Mi40NikiLCIoLTM3LjU0LCAtMTIuNzYpIiwiKC0zMy44NSwgLTkuMDYpIiwiKC0yOC4yNywgLTIuNTgpIikpCgojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYzLCBhbGlnbiA9IGMoImwiLCAiYyIpLCBjYXB0aW9uID0gIkZpdHRlZCBNb2RlbCAzIChFc3RpbWF0ZXMsIENvbmZpZGVuY2UgSW50ZXJ2YWxzLCBQLXZhbHVlcykiKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CiMgVmFsdWVzIGZvciBSLXNxdWFyZWQgYW5kIFJlc2lkdWFsIFN0YW5kYXJkIEVycm9yCnJzcXVhcmVkX21vZDEgPC1nbGFuY2UobW9kMSkKcnNxdWFyZWRfbW9kMiA8LWdsYW5jZShtb2QyKQpyc3F1YXJlZF9tb2QzIDwtZ2xhbmNlKG1vZDMpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KIyBUYWJsZSBmb3IgUi1zcXVhcmVkIGFuZCBSZXNpZHVhbCBTdGFuZGFyZCBFcnJvcgoKZGYyIDwtIGRhdGEuZnJhbWUoTW9kZWw9IGMoIk1vZGVsIDEiLCAiTW9kZWwgMiIsICJNb2RlbCAzIiksCiAgUl9TcXVhcmVkID0gYygiMC41OTciLCAiMC42NTQiLCAiMC42NTQiKSwgU3RhbmRhcmRfRGV2aWF0aW9uPSBjKCIxMDguOTIiLCAiMTAwLjkxIiwgIjEwMC45MSIpKQoKIyBPdXRwdXQgdGhlIHRhYmxlIHVzaW5nIGthYmxlKCkKa25pdHI6OmthYmxlKGRmMiwgYWxpZ24gPSBjKCJsIiwgImMiKSwgY2FwdGlvbiA9ICJSIFNxdWFyZWQgYW5kIFJlc2lkdWFsIFN0YW5kYXJkIEVycm9yIikKYGBgCgpgYGB7cixldmFsPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KI1J1bm5pbmcgbmVzdGVkIEYtdGVzdHMKZnRlc3RfMSA8LSBhbm92YShtb2QxLG1vZDIpCmZ0ZXN0XzIgPC0gYW5vdmEobW9kMixtb2QzKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0Usd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFfQojIFBsb3R0aW5nIFJlc2lkdWFscyB2cyBGaXR0ZWQgVmFsdWVzIGZvciBGaW5hbCBNb2RlbDoKYXVnbWVudChtb2QzKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSAucmVzaWQsIHggPSAuZml0dGVkKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC4wNSkgKyAKICBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAicmVkIikgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoeCA9ICJGaXR0ZWQgVmFsdWVzIiwgCiAgeSA9ICJSZXNpZHVhbHMiLCAKICB0aXRsZSA9ICIgRmlnLiAyOiBSZXNpZHVhbHMgdnMgRml0dGVkIFZhbHVlcyBmb3IgRmluYWwgTW9kZWwiKSArIHhsaW0oMjAwLCAxMTAwKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYA==