1 Introduction

For this project, we will be working on creating a simple logistic regression model. The data set for this project looks at the factors affecting an individual patient’s risk of developing coronary heart disease (CHD) in a 10-year period of time. The response variable in this data set is binary with 1 representing yes, the patient is at risk of developing CHD within a 10-year period of time, and 0 representing no, the patient is not at risk of developing CHD within a 10-year period of time.

1.1 Data Description

I found this data set on kaggle.com on the following web page: https://www.kaggle.com/datasets/dileep070/heart-disease-prediction-using-logistic-regression/data

This data set takes a look at various medical and personal factors which may have an impact on an individual’s risk of developing CHD within the next 10 years. The binary response variable tells whether an individual patient is at risk of developing CHD within the next 10 years, with a response value of 1 meaning yes they are at risk, and 0 meaning no they are not at risk.

1.2 Variables

There are 16 variables in this data set.

  • male: The gender of the patient. A categorical variable with 1 for “male”, 0 for “female”, and 2 for “other”.

  • age: The age of the patient in years. This is a quantitative, continuous variable given as an integer value.

  • education: The education level of the patient. A categorical variable with 1 for “less than high school”, 2 for “high school diploma”, 3 for “college graduate”, and 4 for “post-college graduate”.

  • currentSmoker: Whether or not the patient is currently a smoker. A binary variable with 1 for “yes” and 0 for “no”.

  • cigsPerDay: The average number of cigarettes the patient smokes in a day. This is a quantitative, continuous variable.

  • BPMeds: Whether or not the patient takes blood pressure medication. A binary variable with 1 for “yes” and 0 for “no”.

  • prevalentStroke: Whether or not the patient has a history of strokes. A binary variable with 1 for “yes” and 0 for “no”.

  • prevalentHyp: Whether or not the patient has a history of hypertension. A binary variable with 1 for “yes” and 0 for “no”.

  • diabetes: Whether or not the patient has a history of diabetes. A binary variable with 1 for “yes” and 0 for “no”.

  • totChol: The patient’s total cholesterol level, given in mg/dL (milligrams per deciliter). A quantitative, continuous variable.

  • sysBP: The patient’s systolic blood pressure, given in mmHG (millimeters of mercury). A quantitative, continuous variable.

  • diaBP: The patient’s diastolic blood pressure, given in mmHG (millimeters of mercury). A quantitative, continuous variable.

  • BMI: The patient’s body mass index (BMI). A quantitative, continuous variable.

  • heartRate: The patient’s heart rate, given in beats per minute. A numeric, quantitative variable.

  • glucose: The patient’s glucose level. A numeric, quantitative variable.

  • TenYearCHD (response variable): The binary response variable of this data set which represents whether or not the patient has a 10-year risk of developing Coronary Heart Disease (CHD). This response variable is binary with 1 meaning yes, the patient does have a risk of developing CHD in the next 10 years, and 0 meaning no, the patient does not have a risk of developing CHD in the next 10 years.

1.3 Research Questions

One key analytical question which I would like to investigate in this project is:

  • Can we create a model which statistically significantly predicts a patient’s odds of being at risk for developing coronary heart disease within a 10-year period of time based on the predictor variables in this data set?

This question will serve as the basis for creating the logistic regression model for this data set. For this project, we will just create a simple logistic regression model for now with only one of the predictor variables. However, we will still use the question of whether this simple logistic regression model allows us to statistically significantly predict a patient’s odds of being at risk for developing CHD within a 10-year period. The findings to this question could provide utility for both patients and doctors to provide them with information relating to the odds and risks for developing CHD and which factors significantly impact these odds.

Some further questions to consider as a starting point for this project include:

  • Which predictor variables provide the greatest statistical significance in predicting the patient’s odds of being at risk for developing CHD in a 10-year period?

  • Do the continuous independent variables in this data set follow a normal distribution? And if not, is there a potential explanation for why this may be the case?

  • How accurately can our model predict who will be at risk for developing CHD in a 10-year period of time?

We will use these questions as a starting point for this project in order to create a logistic regression model which statistically significantly predicts the odds of a patient being at risk for developing CHD in a 10-year period based on the many factors which play a role in this prediction.

2 Exploratory Data Analysis

First, we will read in the data set from Github and we will call it “heartdisease”.

'data.frame':   4238 obs. of  16 variables:
 $ male           : int  1 0 1 0 0 0 0 0 1 1 ...
 $ age            : int  39 46 48 61 46 43 63 45 52 43 ...
 $ education      : int  4 2 1 3 3 2 1 2 1 1 ...
 $ currentSmoker  : int  0 0 1 1 1 0 0 1 0 1 ...
 $ cigsPerDay     : int  0 0 20 30 23 0 0 20 0 30 ...
 $ BPMeds         : int  0 0 0 0 0 0 0 0 0 0 ...
 $ prevalentStroke: int  0 0 0 0 0 0 0 0 0 0 ...
 $ prevalentHyp   : int  0 0 0 1 0 1 0 0 1 1 ...
 $ diabetes       : int  0 0 0 0 0 0 0 0 0 0 ...
 $ totChol        : int  195 250 245 225 285 228 205 313 260 225 ...
 $ sysBP          : num  106 121 128 150 130 ...
 $ diaBP          : num  70 81 80 95 84 110 71 71 89 107 ...
 $ BMI            : num  27 28.7 25.3 28.6 23.1 ...
 $ heartRate      : int  80 95 75 65 85 77 60 79 76 93 ...
 $ glucose        : int  77 76 70 103 85 99 85 78 79 88 ...
 $ TenYearCHD     : int  0 0 0 1 0 0 1 0 0 0 ...

2.1 Fixing the Missing Observations

When looking through the data set, I noticed that some observations appeared to be missing from the data set, as they had values of “NA” for certain variables. Before we can begin with the logistic regression, this is something that we should look into.

First, let’s see how many values are missing for each of the variables.

           male             age       education   currentSmoker      cigsPerDay 
              0               0             105               0              29 
         BPMeds prevalentStroke    prevalentHyp        diabetes         totChol 
             53               0               0               0              50 
          sysBP           diaBP             BMI       heartRate         glucose 
              0               0              19               1             388 
     TenYearCHD 
              0 

We can see that the variables education, cigsPerDay, BPMeds, totChol, BMI, heartRate, and glucose all have missing observations.

Now that we know which variables are missing observations, we can see which specific observations are missing from these variables.

$male
integer(0)

$age
integer(0)

$education
  [1]   34   37   73  185  214  294  306  307  320  401  413  430  473  500  504
 [16]  623  695  720  738  783  820  917  944  967  981 1028 1039 1071 1073 1076
 [31] 1130 1139 1180 1228 1240 1254 1260 1287 1289 1315 1376 1381 1395 1479 1605
 [46] 1623 1642 1655 1676 1682 1731 1952 1972 1985 1999 2061 2139 2251 2268 2294
 [61] 2347 2431 2469 2519 2543 2596 2670 2749 2785 2847 2883 2886 2902 2912 2929
 [76] 3013 3034 3035 3114 3149 3161 3220 3235 3259 3291 3311 3471 3486 3515 3589
 [91] 3604 3619 3656 3674 3764 3765 3869 3874 3944 4013 4083 4099 4122 4123 4139

$currentSmoker
integer(0)

$cigsPerDay
 [1]  132  140 1047 1293 1348 1452 1498 1611 1626 1871 1964 1981 2406 2514 2543
[16] 3022 3035 3095 3107 3109 3157 3178 3310 3433 3580 3716 3848 3925 3943

$BPMeds
 [1]   50   78  194  246  315  396  422  766  770  798  999 1003 1045 1105 1123
[16] 1178 1207 1285 1302 1567 1574 1617 1722 1858 1862 1914 1984 1986 1987 2003
[31] 2075 2121 2174 2182 2368 2609 2646 2739 2836 2944 3227 3314 3374 3376 3527
[46] 3645 3738 3792 3817 4009 4140 4163 4236

$prevalentStroke
integer(0)

$prevalentHyp
integer(0)

$diabetes
integer(0)

$totChol
 [1]   43  155  248  430  568  578  610  674  823  835  872  952 1106 1123 1318
[16] 1355 1360 1449 1576 1745 1748 1786 1880 1941 2004 2009 2080 2210 2264 2341
[31] 2342 2418 2584 2590 2613 2806 2873 2903 3111 3112 3150 3286 3577 3608 3631
[46] 3661 3961 3962 3989 4186

$sysBP
integer(0)

$diaBP
integer(0)

$BMI
 [1]   98  295  706 1156 1162 1595 1605 1625 1748 1976 2049 2068 2092 2178 2530
[16] 2720 2926 3091 3340

$heartRate
[1] 690

$glucose
  [1]   15   22   27   43   55   71  112  115  132  155  204  212  216  217  247
 [16]  248  251  264  274  280  283  295  297  302  303  310  316  330  339  344
 [31]  346  356  383  408  414  419  426  428  429  434  437  449  456  457  468
 [46]  488  491  500  512  520  541  553  564  568  577  578  592  610  646  662
 [61]  674  676  680  691  706  715  756  758  761  778  779  780  813  814  823
 [76]  830  833  873  884  897  906  918  923  937  940  943  973  996 1000 1020
 [91] 1029 1064 1065 1102 1116 1119 1120 1123 1143 1162 1173 1176 1182 1191 1203
[106] 1212 1215 1235 1251 1276 1298 1318 1328 1336 1348 1355 1360 1362 1369 1378
[121] 1396 1401 1409 1412 1430 1449 1471 1494 1507 1522 1525 1538 1541 1570 1575
[136] 1576 1582 1618 1646 1648 1659 1672 1682 1688 1693 1695 1707 1717 1721 1724
[151] 1745 1748 1759 1771 1776 1779 1786 1787 1801 1809 1816 1822 1831 1846 1861
[166] 1867 1870 1884 1886 1916 1925 1927 1933 1941 1959 1975 1979 1981 1988 2004
[181] 2007 2009 2011 2015 2023 2027 2039 2046 2050 2065 2069 2080 2082 2086 2097
[196] 2104 2105 2108 2109 2110 2111 2119 2135 2161 2162 2175 2184 2210 2217 2220
[211] 2255 2263 2264 2270 2271 2274 2315 2316 2341 2342 2356 2376 2399 2410 2418
[226] 2432 2463 2508 2524 2525 2531 2555 2568 2571 2574 2586 2590 2594 2610 2613
[241] 2616 2627 2639 2641 2656 2659 2690 2696 2697 2700 2711 2712 2728 2729 2753
[256] 2757 2764 2772 2774 2793 2801 2826 2847 2848 2859 2873 2886 2896 2903 2905
[271] 2906 2930 2942 2945 2947 2950 2957 2968 2972 2987 2988 2995 3002 3008 3046
[286] 3047 3049 3052 3056 3063 3090 3099 3106 3111 3112 3119 3124 3147 3150 3158
[301] 3159 3164 3191 3192 3208 3291 3292 3297 3309 3314 3317 3331 3333 3340 3365
[316] 3381 3384 3387 3409 3456 3457 3466 3480 3489 3534 3559 3561 3572 3574 3577
[331] 3580 3592 3598 3608 3614 3619 3625 3631 3648 3650 3661 3662 3671 3682 3686
[346] 3713 3714 3744 3747 3752 3756 3765 3772 3774 3776 3781 3788 3865 3873 3879
[361] 3884 3894 3902 3904 3914 3926 3948 3958 3961 3962 3980 3988 3989 3990 4004
[376] 4018 4029 4050 4062 4087 4122 4154 4161 4171 4209 4230 4231 4237

$TenYearCHD
integer(0)

We will create a new data set called “heartdisease1” to represent the corrected data set that will have no missing values.

2.1.1 Fixing the Quantitative Variables

First, let’s fix the missing values for the quantitative variables. The quantitative variables with missing values are totChol, BMI, heartRate, and glucose.

Let’s start with totChol. We will calculate the mean value of totChol and use this mean to replace the missing observations. After we replace the missing observations with the mean value, we will then check the first 20 observations of the corrected totChol variable with the missing observations filled in to make sure everything looks good.

[1] 236.7216
 [1] 195 250 245 225 285 228 205 313 260 225 254 247 294 332 226 221 232 291 195
[20] 195

Next, let’s fix BMI. We will calculate the mean value of BMI and use this mean to replace the missing observations. After we replace the missing observations with the mean value, we will then check the first 20 observations of the corrected BMI variable with the missing observations filled in to make sure everything looks good.

[1] 25.80201
 [1] 26.97 28.73 25.34 28.58 23.10 30.30 33.11 21.68 26.36 23.61 22.91 27.64
[13] 26.31 31.31 22.35 21.35 22.37 23.38 23.24 26.88

Next, let’s fix heartRate. We will calculate the mean value of heartRate and use this mean to replace the missing observations. After we replace the missing observations with the mean value, we will then check the first 20 observations of the corrected heartRate variable with the missing observations filled in to make sure everything looks good.

[1] 75.87892
 [1] 80 95 75 65 85 77 60 79 76 93 75 72 98 65 85 95 64 80 75 85

And now let’s fix glucose. We will calculate the mean value of glucose and use this mean to replace the missing observations. After we replace the missing observations with the mean value, we will then check the first 20 observations of the corrected glucose variable with the missing observations filled in to make sure everything looks good.

[1] 81.96675
 [1]  77.00000  76.00000  70.00000 103.00000  85.00000  99.00000  85.00000
 [8]  78.00000  79.00000  88.00000  76.00000  61.00000  64.00000  84.00000
[15]  81.96675  70.00000  72.00000  89.00000  78.00000  65.00000

2.1.2 Fixing the Categorical Variables

Now that we have fixed all of the missing observations for the quantitative variables, we will fix the missing observations for the categorical variables as well. The categorical variables with missing observations are education, cigsPerDay, and BPMeds. To do this, we will replace the missing values with the mode of that variable.

Let’s start with education. We will calculate the mode value of education and use this mode to replace the missing observations. After we replace the missing observations with the mode value, we will then check the first 20 observations of the corrected education variable with the missing observations filled in to make sure everything looks good.

 [1] "4" "2" "1" "3" "3" "2" "1" "2" "1" "1" "1" "2" "1" "3" "2" "2" "3" "2" "2"
[20] "2" "2" "1" "1" "3" "2" "4" "1" "2" "3" "1"

Now let’s fix cigsPerDay. We will calculate the mode value of cigsPerDay and use this mode to replace the missing observations. After we replace the missing observations with the mode value, we will then check the first 20 observations of the corrected cigsPerDay variable with the missing observations filled in to make sure everything looks good.

 [1] "0"  "0"  "20" "30" "23" "0"  "0"  "20" "0"  "30" "0"  "0"  "15" "0"  "9" 
[16] "20" "10" "20" "5"  "0"  "30" "0"  "0"  "20" "30" "20" "0"  "20" "0"  "0" 

Lastly, let’s fix BPMeds. We will calculate the mode value of BPMeds and use this mode to replace the missing observations. After we replace the missing observations with the mode value, we will then check the first 20 observations of the corrected BPMeds variable with the missing observations filled in to make sure everything looks good.

 [1] "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "1" "0" "0" "0" "0" "0"
[20] "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"

2.1.3 Checking that the Missing Observations are Fixed

Now that we have fixed all of the variables that were missing observations, let’s double check that there are no more missing observations in the new data set “heartdisease1”.

           male             age       education   currentSmoker      cigsPerDay 
              0               0               0               0               0 
         BPMeds prevalentStroke    prevalentHyp        diabetes         totChol 
              0               0               0               0               0 
          sysBP           diaBP             BMI       heartRate         glucose 
              0               0               0               0               0 
     TenYearCHD 
              0 

As we can see, all of the variables now have zero missing observations, so we successfully fixed all of the missing values by filling them in with either the mean or mode depending on whether the variable in question was quantitative or categorical. The new, revised data set “heartdisease1” now has no missing observations, so we will use this for further analysis and for creating the logistic regression model.

Now that the missing observations problem has been fixed, we will soon begin with constructing the simple logistic regression model.

2.2 Fixing Variable Types

One other thing I noticed while looking through the data set is that the variable “cigsPerDay” is given as a character variable even though it should be a numeric variable. This variable is a measure of the number of cigarettes a patient smokes in a day, so it should be reported as a numeric variable since it is a continuous range of possible values and not collected as categories. So, let’s convert cigsPerDay from a character variable to a numeric variable. We will use the as.numeric() function to convert cigsPerDay to a numeric variable.

Now, the cigsPerDay variable is correctly given as a numeric variable.

Additionally, the variable BPMeds is given as a character, however this is a binary variable so it should be given as an integer variable with values 0 and 1 like the other binary variables in the data set. We will convert this variable from a character to an integer. We will use the as.integer() function to do this conversion.

Now, the BPMeds variable is correctly given as a binary, integer variable.

Now that we have corrected the types of the variables that were mislabeled as the incorrect type, we will begin with the creation of the simple logistic regression model in the following steps.

3 Simple Logistic Regression Model

To build a simple logistic regression model, we will pick one predictor variable to use in our model. For this model, we will look at the predictor variable diaBP. This quantitative predictor variable is a measure of the patient’s diastolic blood pressure.

First, let’s make sure diaBP follows a normal distribution without any extreme skew or outliers. We will create a histogram of the distribution of diaBP to check that it follows a normal distribution.

As we can see, the data for diaBP appears to be approximately normally distributed so we can move forward with building the simple logistic regression model with diaBP as our predictor variable. There do not appear to be any noticeable or extreme skew or outliers present in this histogram, so we can say that the distribution for diastolic blood pressure appears to follow a normal distribution. This makes diaBP a good variable to analyze further in this simple logisitic regression model.

3.1 Building the Logistic Regression Model

Let’s begin with constructing the simple logistic regression model for the predictor variable diaBP This will be a simple logistic regression model for the predictor variable, diastolic blood pressure, vs. the response variable TenYearCHD, the patient’s risk of developing CHD in a 10-year period.


Call:
glm(formula = TenYearCHD ~ diaBP, family = binomial(link = "logit"), 
    data = heartdisease1)

Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -4.402010   0.297183 -14.812   <2e-16 ***
diaBP        0.031764   0.003421   9.286   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 3611.5  on 4237  degrees of freedom
Residual deviance: 3526.5  on 4236  degrees of freedom
AIC: 3530.5

Number of Fisher Scoring iterations: 4

The equation for the simple logistic regression model of diaBP vs. TenYearCHD is given as follows:

log p/(1-p) = -4.4020 + 0.0318 * diaBP

Diastolic blood pressure statistically significantly predicted the odds of a patient being at risk for developing CHD within a 10-year period of time, p < .001.

Summary Statistics of the Regression Coefficients
Estimate Std. Error z value Pr(>|z|) 2.5 % 97.5 %
(Intercept) -4.4020100 0.2971831 -14.812451 0 -4.9872187 -3.8217547
diaBP 0.0317643 0.0034205 9.286403 0 0.0250623 0.0384777

In the table above we can see that the simple logistic regression model is statistically significant with a p-value of p < .001.

Furthermore, diastolic blood pressure is positively associated with the 10-year risk of developing CHD, with β1 = 0.0318. The 95% Confidence Interval further supports the statistical significance of diastolic blood pressure in predicting the risk of a patient being at risk for developing CHD in a 10-year period of time, [0.0251, 0.0385].

3.2 Goodness of Fit Diagnostic Tests

Some goodness of fit tests were performed on the simple logisitic regression model to verify its significance and utility.

Deviance.Residual Null.Deviance.Residual AIC
3527 3612 3531

Using the goodness of fit diagnostic tests, we found the deviance residual, the null deviance residual, and the AIC value for the simple logistic regression model of diaBP and TenYearCHD. The deviance residual is 3,527, the null deviance residual is 3,612, and the AIC value is 3,531.

As there was only a simple logistic regression model that was created, we do not have any other potential candidate models to compare these diagnostic values with.

4 Regression Coefficient Interpretations

To help us interpret the regression coefficient, we will look at the odds ratio. The odds ratio tells us the measure of association between an exposure and an outcome. In this case, our exposure will be the patient’s diastolic blood pressure level and the outcome will be the patient’s odds of being at risk for developing CHD in a 10-year period of time. This odds ratio value will allow us to see how a patient’s odds of being at risk for developing CHD in a 10-year period changes with an increase in this patient’s diastolic blood pressure.

We will create a table of the summary statistics with the odds ratio to see what the odds ratio is for diaBP and we will use this value to interpret its meaning.

Summary Statistics with the Odds Ratio
Estimate Std. Error z value Pr(>|z|) odds.ratio
(Intercept) -4.4020100 0.2971831 -14.812451 0 0.0122527
diaBP 0.0317643 0.0034205 9.286403 0 1.0322742

The odds ratio for diaBP is 1.0323. This means that for every 1 mmHG increase in a patient’s diastolic blood pressure, the odds of this patient developing CHD within a 10-year period of time increases by 3.23%. This is a significant percentage, because as a patient’s diastolic blood pressure increases more and more, so will the odds of them being at risk for developing CHD in a 10 year period.

4.1 Odds Ratio Interpretation

Diastolic blood pressure is the lower number in a blood pressure reading. For instance, in the blood pressure measurement of 110/70, the 70 is the diastolic blood pressure. Additionally, diastolic blood pressure is given in units of mmHG, millimeters of mercury.

Ignoring all other factors, a patient with a blood pressure of 120/81 would have 3.23% higher odds of being at risk for developing CHD in 10 years than they would if their blood pressure was 120/80. This is because for every 1 mmHG increase in diastolic blood pressure, their odds of being at risk for developing CHD in a 10-year period increases by 3.23%.

To go even further to show the significance of this odds ratio, a patient with a blood pressure of 120/90 would have an incredibly significant 32.30% higher odds of being at risk for developing CHD in 10 years than they would if their blood pressure was 120/80. This is because for every 1 mmHG increase in diastolic blood pressure, a patient’s odds of being at risk for developing CHD in 10 years increases by 3.23%, so a 10 mmHG increase in diastolic blood pressure would increase the odds by 10%, giving a 32.30% odds of developing CHD in 10 years for a 10 mmHG increase in diastolic blood pressure. This is an incredibly significant percentage of the odds, and these odds would increase even further as diastolic blood pressure continues to increase.

The odds ratio of diastolic blood pressure is very significant, and it provides importance for showing how the variable of diastolic blood pressure affects the patient’s odds of being at risk for developing CHD in a 10-year period of time.

5 Behavior of the Success Probability

Now we will look a the behavior and trends of the success probability. We will create two graphs to help visualize this, with these two graphs being the success probability curve and the rate of change of the success probabilty curve.

5.1 Probability Curve

First, we will create the graph of the probability of being at risk for developing CHD over a 10-year period of time with diaBP as our independent variable. We will graph the success probability which is the probability of the patient being at risk for developing CHD over a 10-year period based on their diastolic blood pressure. This graph will visualize how the patient’s probability of being at risk of developing CHD over a 10-year period of time based on their diastolic blood pressure.

The curve of the success probability matches up with previous observations that as diastolic blood pressure increases, so do the odds of being at risk for developing CHD in a 10-year period of time. We can see the curve in the graph following a positive distribution, with the probability increasing as diastolic blood pressure also increases.

5.2 Rate of Change in the Success Probability

Next, we will create a graph of the rate of change in the success probability. This graph will visualize the rate of change in the probability of being at risk for developing CHD in a 10-year period of time based on diastolic blood pressure. As stated in the previous section, the success probability in this case represents the patient’s probability of being at risk for developing CHD in a 10-year period. This probability is based on the patient’s diastolic blood pressure, as that is the independent variable in our model. This graph will show how the rate of change in the probability of being at risk for developing CHD over a 10-year period of time changes based on the patient’s diastolic blood pressure.

The curve for the rate of change in the success probability of being at risk for developing CHD in a 10-year period appears to follow an S-curve fitting to that of a logistic model like which was created. The rate of change appears to increase rapidly at first but then slows down when diastolic blood pressure reaches around 120 mmHg. The curve follows an overall positive distribution, with the rate of change being higher as diastolic blood pressure is also higher. This S-curve shows how the rate of change in the probability of being at risk for developing CHD over a 10-year period changes as diastolic blood pressure increases.

6 Conclusion

Overall, a simple logistic regression model was created to observe the relationship between the independent variable of diastolic blood pressure and the response variable of whether a patient is at risk for developing CHD over a 10-year period of time. The regression model was given as follows:

log p/(1-p) = -4.4020 + 0.0318 * diaBP

And it turned out that this model was statistically significant in predicting the odds of a patient being at risk for developing CHD in a 10-year period with a p-value of p < .001. This model shows that as diastolic blood pressure increases, so does the odds of a patient being at risk for developing CHD in a 10-year period. Furthermore, it was found that the odds ratio for diastolic blood pressure in this logistic regression model was 1.0323, meaning that for every 1 mmHG increase in a patient’s diastolic blood pressure, the odds of this patient developing CHD within a 10-year period of time increases by 3.23%.

This is significant as it provides useful information for both doctors and patients to assess the patient’s odds of being at risk for developing CHD. It appears that there is sufficient evidence to conclude that the higher a patient’s diastolic blood pressure is, the higher their odds of being at risk for developing CHD are. So, this is very useful for providing doctors and patients with a factor which affects their odds of being at risk for developing CHD over a 10-year period.

Some recommendations I would make for future projects include:

  • This simple logistic regression model focused on using diastolic blood pressure to predict the odds of an individual being at risk of developing CHD in a 10-year period. For future research, it could be a good idea to look into a combination of systolic and diastolic blood pressure levels to see if that provides higher significance for prediction.

  • Additionally, some interactions between different variables could be looked into in further experiments that get into multiple logistic regression models. It would be worth looking into whether any of the variables in this model interact with one another.

  • The diastolic blood pressure variable was shown to follow a normal distribution and did not need to undergo any transformations to be used in the final model. However, in future projects it would be important to look at the other variables in the model to see if there are any which need to be transformed in some way to provide the beat utility to the model.

Overall, this project showed that diastolic blood pressure is statistically significant in predicting the odds of a patient being at risk for developing CHD in a 10-year period of time. This provides useful information to patients so that they can look into how their diastolic blood pressure affects their odds of being at risk for developing CHD. This also provides useful information to doctors so they can keep an eye out for which patients may have higher odds of being at risk for developing CHD due to potential high diastolic blood pressure levels. This simple logistic regression model that was created has good utility for predicting a patient’s odds of being at risk for developing CHD in a 10-year period based off of their diastolic blood pressure, and this provides useful information in allowing patients to understand whether they have greater odds of being at risk for developing CHD based on their diastolic blood pressure level.

7 References

This data set was found on kaggle.com under the collection of logistic regression data sets. Included below is the citation of the web page of where I found the data set I used for my project.

Dileep. (2019, June 7). Logistic regression to predict heart disease. Kaggle. https://www.kaggle.com/datasets/dileep070/heart-disease-prediction-using-logistic-regression?resource=download&select=framingham.csv

LS0tDQp0aXRsZTogIlVzaW5nIERpYXN0b2xpYyBCbG9vZCBQcmVzc3VyZSB0byBQcmVkaWN0IGEgUGF0aWVudCdzIE9kZHMgb2YgQmVpbmcgYXQgUmlzayBmb3IgRGV2ZWxvcGluZyBDSEQtIFNpbXBsZSBMb2dpc3RpYyBSZWdyZXNzaW9uIg0KYXV0aG9yOiAiSm9zaWUgR2FsbG9wIg0KZGF0ZTogIjIwMjQtMTAtMDEiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7PWh0bWx9DQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCi8qIENhc2NhZGluZyBTdHlsZSBTaGVldHMgKENTUykgaXMgYSBzdHlsZXNoZWV0IGxhbmd1YWdlIHVzZWQgdG8gZGVzY3JpYmUgdGhlIHByZXNlbnRhdGlvbiBvZiBhIGRvY3VtZW50IHdyaXR0ZW4gaW4gSFRNTCBvciBYTUwuIGl0IGlzIGEgc2ltcGxlIG1lY2hhbmlzbSBmb3IgYWRkaW5nIHN0eWxlIChlLmcuLCBmb250cywgY29sb3JzLCBzcGFjaW5nKSB0byBXZWIgZG9jdW1lbnRzLiAqLw0KDQpoMS50aXRsZSB7ICAvKiBUaXRsZSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgdGhlIHJlcG9ydCB0aXRsZSAqLw0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgYXV0aG9ycyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgdGhlIGRhdGUgICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMSB7IC8qIEhlYWRlciAxIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMSBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IC8qIEhlYWRlciAyIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMiBzZWN0aW9uIHRpdGxlICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDMgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgNCBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQo8L3N0eWxlPg0KYGBgDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgRGV0ZWN0LCBpbnN0YWxsLCBhbmQgbG9hZCBwYWNrYWdlcyBpZiBuZWVkZWQuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpDQogICBsaWJyYXJ5KGxlYWZsZXQpDQp9DQppZiAoIXJlcXVpcmUoIkVudlN0YXRzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkVudlN0YXRzIikNCiAgIGxpYnJhcnkoRW52U3RhdHMpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiTUFTUyIpDQogICBsaWJyYXJ5KE1BU1MpDQp9DQppZiAoIXJlcXVpcmUoInBoeXRvb2xzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBoeXRvb2xzIikNCiAgIGxpYnJhcnkocGh5dG9vbHMpDQp9DQppZighcmVxdWlyZSgiZHBseXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KICAgbGlicmFyeShkcGx5cikNCn0NCmlmKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYoIXJlcXVpcmUoIkdHYWxseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQ0KICAgbGlicmFyeShHR2FsbHkpDQp9DQppZighcmVxdWlyZSgidXNkbSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ1c2RtIikNCiAgIGxpYnJhcnkodXNkbSkNCn0NCmlmKCFyZXF1aXJlKCJjYXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCiAgIGxpYnJhcnkoY2FyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJib290IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImJvb3QiKQ0KICAgbGlicmFyeShib290KQ0KfQ0KaWYoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZighcmVxdWlyZSgibWljZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJtaWNlIikNCiAgIGxpYnJhcnkobWljZSkNCn0NCiMgU3BlY2lmaWNhdGlvbnMgb2Ygb3V0cHV0cyBvZiBjb2RlIGluIGNvZGUgY2h1bmtzDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlDQogICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIyBTb21ldGltZXMsIHlvdXIgY29kZSBtYXkgcHJvZHVjZSBhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcywgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHdhcm5pbmcgbWVzc2FnZXMgaW4gdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsICANCiAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEgICAgICAjIFN1cHByZXNzIGhhc2gtdGFncyBpbiB0aGUgb3V0cHV0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuDQogICAgICAgICAgICAgICAgICAgICAgKSAgIA0KYGBgDQoNCg0KDQojIEludHJvZHVjdGlvbg0KDQpGb3IgdGhpcyBwcm9qZWN0LCB3ZSB3aWxsIGJlIHdvcmtpbmcgb24gY3JlYXRpbmcgYSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbC4gVGhlIGRhdGEgc2V0IGZvciB0aGlzIHByb2plY3QgbG9va3MgYXQgdGhlIGZhY3RvcnMgYWZmZWN0aW5nIGFuIGluZGl2aWR1YWwgcGF0aWVudCdzIHJpc2sgb2YgZGV2ZWxvcGluZyBjb3JvbmFyeSBoZWFydCBkaXNlYXNlIChDSEQpIGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4gVGhlIHJlc3BvbnNlIHZhcmlhYmxlIGluIHRoaXMgZGF0YSBzZXQgaXMgYmluYXJ5IHdpdGggMSByZXByZXNlbnRpbmcgeWVzLCB0aGUgcGF0aWVudCBpcyBhdCByaXNrIG9mIGRldmVsb3BpbmcgQ0hEIHdpdGhpbiBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUsIGFuZCAwIHJlcHJlc2VudGluZyBubywgdGhlIHBhdGllbnQgaXMgbm90IGF0IHJpc2sgb2YgZGV2ZWxvcGluZyBDSEQgd2l0aGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4NCg0KDQoNCiMjIERhdGEgRGVzY3JpcHRpb24NCg0KSSBmb3VuZCB0aGlzIGRhdGEgc2V0IG9uIGthZ2dsZS5jb20gb24gdGhlIGZvbGxvd2luZyB3ZWIgcGFnZToNCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvZGlsZWVwMDcwL2hlYXJ0LWRpc2Vhc2UtcHJlZGljdGlvbi11c2luZy1sb2dpc3RpYy1yZWdyZXNzaW9uL2RhdGENCg0KVGhpcyBkYXRhIHNldCB0YWtlcyBhIGxvb2sgYXQgdmFyaW91cyBtZWRpY2FsIGFuZCBwZXJzb25hbCBmYWN0b3JzIHdoaWNoIG1heSBoYXZlIGFuIGltcGFjdCBvbiBhbiBpbmRpdmlkdWFsJ3MgcmlzayBvZiBkZXZlbG9waW5nIENIRCB3aXRoaW4gdGhlIG5leHQgMTAgeWVhcnMuIFRoZSBiaW5hcnkgcmVzcG9uc2UgdmFyaWFibGUgdGVsbHMgd2hldGhlciBhbiBpbmRpdmlkdWFsIHBhdGllbnQgaXMgYXQgcmlzayBvZiBkZXZlbG9waW5nIENIRCB3aXRoaW4gdGhlIG5leHQgMTAgeWVhcnMsIHdpdGggYSByZXNwb25zZSB2YWx1ZSBvZiAxIG1lYW5pbmcgeWVzIHRoZXkgYXJlIGF0IHJpc2ssIGFuZCAwIG1lYW5pbmcgbm8gdGhleSBhcmUgbm90IGF0IHJpc2suDQoNCg0KDQojIyBWYXJpYWJsZXMNCg0KVGhlcmUgYXJlIDE2IHZhcmlhYmxlcyBpbiB0aGlzIGRhdGEgc2V0Lg0KDQoqIG1hbGU6IFRoZSBnZW5kZXIgb2YgdGhlIHBhdGllbnQuIEEgY2F0ZWdvcmljYWwgdmFyaWFibGUgd2l0aCAxIGZvciAibWFsZSIsICAwIGZvciAiZmVtYWxlIiwgYW5kIDIgZm9yICJvdGhlciIuIA0KDQoqIGFnZTogVGhlIGFnZSBvZiB0aGUgcGF0aWVudCBpbiB5ZWFycy4gVGhpcyBpcyBhIHF1YW50aXRhdGl2ZSwgY29udGludW91cyB2YXJpYWJsZSBnaXZlbiBhcyBhbiBpbnRlZ2VyIHZhbHVlLg0KDQoqIGVkdWNhdGlvbjogVGhlIGVkdWNhdGlvbiBsZXZlbCBvZiB0aGUgcGF0aWVudC4gQSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB3aXRoIDEgZm9yICJsZXNzIHRoYW4gaGlnaCBzY2hvb2wiLCAyIGZvciAiaGlnaCBzY2hvb2wgZGlwbG9tYSIsIDMgZm9yICJjb2xsZWdlIGdyYWR1YXRlIiwgYW5kIDQgZm9yICJwb3N0LWNvbGxlZ2UgZ3JhZHVhdGUiLg0KDQoqIGN1cnJlbnRTbW9rZXI6IFdoZXRoZXIgb3Igbm90IHRoZSBwYXRpZW50IGlzIGN1cnJlbnRseSBhIHNtb2tlci4gQSBiaW5hcnkgdmFyaWFibGUgd2l0aCAxIGZvciAieWVzIiBhbmQgMCBmb3IgIm5vIi4NCg0KKiBjaWdzUGVyRGF5OiBUaGUgYXZlcmFnZSBudW1iZXIgb2YgY2lnYXJldHRlcyB0aGUgcGF0aWVudCBzbW9rZXMgaW4gYSBkYXkuIFRoaXMgaXMgYSBxdWFudGl0YXRpdmUsIGNvbnRpbnVvdXMgdmFyaWFibGUuIA0KDQoqIEJQTWVkczogV2hldGhlciBvciBub3QgdGhlIHBhdGllbnQgdGFrZXMgYmxvb2QgcHJlc3N1cmUgbWVkaWNhdGlvbi4gQSBiaW5hcnkgdmFyaWFibGUgd2l0aCAxIGZvciAieWVzIiBhbmQgMCBmb3IgIm5vIi4NCg0KKiBwcmV2YWxlbnRTdHJva2U6IFdoZXRoZXIgb3Igbm90IHRoZSBwYXRpZW50IGhhcyBhIGhpc3Rvcnkgb2Ygc3Ryb2tlcy4gQSBiaW5hcnkgdmFyaWFibGUgd2l0aCAxIGZvciAieWVzIiBhbmQgMCBmb3IgIm5vIi4NCg0KKiBwcmV2YWxlbnRIeXA6IFdoZXRoZXIgb3Igbm90IHRoZSBwYXRpZW50IGhhcyBhIGhpc3Rvcnkgb2YgaHlwZXJ0ZW5zaW9uLiBBIGJpbmFyeSB2YXJpYWJsZSB3aXRoIDEgZm9yICJ5ZXMiIGFuZCAwIGZvciAibm8iLg0KDQoqIGRpYWJldGVzOiBXaGV0aGVyIG9yIG5vdCB0aGUgcGF0aWVudCBoYXMgYSBoaXN0b3J5IG9mIGRpYWJldGVzLiBBIGJpbmFyeSB2YXJpYWJsZSB3aXRoIDEgZm9yICJ5ZXMiIGFuZCAwIGZvciAibm8iLg0KDQoqIHRvdENob2w6IFRoZSBwYXRpZW50J3MgdG90YWwgY2hvbGVzdGVyb2wgbGV2ZWwsIGdpdmVuIGluIG1nL2RMIChtaWxsaWdyYW1zIHBlciBkZWNpbGl0ZXIpLiBBIHF1YW50aXRhdGl2ZSwgY29udGludW91cyB2YXJpYWJsZS4gDQoNCiogc3lzQlA6IFRoZSBwYXRpZW50J3Mgc3lzdG9saWMgYmxvb2QgcHJlc3N1cmUsIGdpdmVuIGluIG1tSEcgKG1pbGxpbWV0ZXJzIG9mIG1lcmN1cnkpLiBBIHF1YW50aXRhdGl2ZSwgY29udGludW91cyB2YXJpYWJsZS4gDQoNCiogZGlhQlA6IFRoZSBwYXRpZW50J3MgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlLCBnaXZlbiBpbiBtbUhHIChtaWxsaW1ldGVycyBvZiBtZXJjdXJ5KS4gQSBxdWFudGl0YXRpdmUsIGNvbnRpbnVvdXMgdmFyaWFibGUuIA0KDQoqIEJNSTogVGhlIHBhdGllbnQncyBib2R5IG1hc3MgaW5kZXggKEJNSSkuIEEgcXVhbnRpdGF0aXZlLCBjb250aW51b3VzIHZhcmlhYmxlLiANCg0KKiBoZWFydFJhdGU6IFRoZSBwYXRpZW50J3MgaGVhcnQgcmF0ZSwgZ2l2ZW4gaW4gYmVhdHMgcGVyIG1pbnV0ZS4gQSBudW1lcmljLCBxdWFudGl0YXRpdmUgdmFyaWFibGUuIA0KDQoqIGdsdWNvc2U6IFRoZSBwYXRpZW50J3MgZ2x1Y29zZSBsZXZlbC4gQSBudW1lcmljLCBxdWFudGl0YXRpdmUgdmFyaWFibGUuIA0KDQoqIFRlblllYXJDSEQgKHJlc3BvbnNlIHZhcmlhYmxlKTogVGhlIGJpbmFyeSByZXNwb25zZSB2YXJpYWJsZSBvZiB0aGlzIGRhdGEgc2V0IHdoaWNoIHJlcHJlc2VudHMgd2hldGhlciBvciBub3QgdGhlIHBhdGllbnQgaGFzIGEgMTAteWVhciByaXNrIG9mIGRldmVsb3BpbmcgQ29yb25hcnkgSGVhcnQgRGlzZWFzZSAoQ0hEKS4gVGhpcyByZXNwb25zZSB2YXJpYWJsZSBpcyBiaW5hcnkgd2l0aCAxIG1lYW5pbmcgeWVzLCB0aGUgcGF0aWVudCBkb2VzIGhhdmUgYSByaXNrIG9mIGRldmVsb3BpbmcgQ0hEIGluIHRoZSBuZXh0IDEwIHllYXJzLCBhbmQgMCBtZWFuaW5nIG5vLCB0aGUgcGF0aWVudCBkb2VzIG5vdCBoYXZlIGEgcmlzayBvZiBkZXZlbG9waW5nIENIRCBpbiB0aGUgbmV4dCAxMCB5ZWFycy4NCg0KDQoNCiMjIFJlc2VhcmNoIFF1ZXN0aW9ucw0KDQoNCk9uZSBrZXkgYW5hbHl0aWNhbCBxdWVzdGlvbiB3aGljaCBJIHdvdWxkIGxpa2UgdG8gaW52ZXN0aWdhdGUgaW4gdGhpcyBwcm9qZWN0IGlzOg0KDQoqIENhbiB3ZSBjcmVhdGUgYSBtb2RlbCB3aGljaCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50bHkgcHJlZGljdHMgYSBwYXRpZW50J3Mgb2RkcyBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIGNvcm9uYXJ5IGhlYXJ0IGRpc2Vhc2Ugd2l0aGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZSBiYXNlZCBvbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyBpbiB0aGlzIGRhdGEgc2V0Pw0KDQpUaGlzIHF1ZXN0aW9uIHdpbGwgc2VydmUgYXMgdGhlIGJhc2lzIGZvciBjcmVhdGluZyB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBmb3IgdGhpcyBkYXRhIHNldC4gRm9yIHRoaXMgcHJvamVjdCwgd2Ugd2lsbCBqdXN0IGNyZWF0ZSBhIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIGZvciBub3cgd2l0aCBvbmx5IG9uZSBvZiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcy4gSG93ZXZlciwgd2Ugd2lsbCBzdGlsbCB1c2UgdGhlIHF1ZXN0aW9uIG9mIHdoZXRoZXIgdGhpcyBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBhbGxvd3MgdXMgdG8gc3RhdGlzdGljYWxseSBzaWduaWZpY2FudGx5IHByZWRpY3QgYSBwYXRpZW50J3Mgb2RkcyBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCB3aXRoaW4gYSAxMC15ZWFyIHBlcmlvZC4gVGhlIGZpbmRpbmdzIHRvIHRoaXMgcXVlc3Rpb24gY291bGQgcHJvdmlkZSB1dGlsaXR5IGZvciBib3RoIHBhdGllbnRzIGFuZCBkb2N0b3JzIHRvIHByb3ZpZGUgdGhlbSB3aXRoIGluZm9ybWF0aW9uIHJlbGF0aW5nIHRvIHRoZSBvZGRzIGFuZCByaXNrcyBmb3IgZGV2ZWxvcGluZyBDSEQgYW5kIHdoaWNoIGZhY3RvcnMgc2lnbmlmaWNhbnRseSBpbXBhY3QgdGhlc2Ugb2Rkcy4gDQoNClNvbWUgZnVydGhlciBxdWVzdGlvbnMgdG8gY29uc2lkZXIgYXMgYSBzdGFydGluZyBwb2ludCBmb3IgdGhpcyBwcm9qZWN0IGluY2x1ZGU6DQoNCiogV2hpY2ggcHJlZGljdG9yIHZhcmlhYmxlcyBwcm92aWRlIHRoZSBncmVhdGVzdCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgaW4gcHJlZGljdGluZyB0aGUgcGF0aWVudCdzIG9kZHMgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZD8NCg0KKiBEbyB0aGUgY29udGludW91cyBpbmRlcGVuZGVudCB2YXJpYWJsZXMgaW4gdGhpcyBkYXRhIHNldCBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uPyBBbmQgaWYgbm90LCBpcyB0aGVyZSBhIHBvdGVudGlhbCBleHBsYW5hdGlvbiBmb3Igd2h5IHRoaXMgbWF5IGJlIHRoZSBjYXNlPw0KDQoqIEhvdyBhY2N1cmF0ZWx5IGNhbiBvdXIgbW9kZWwgcHJlZGljdCB3aG8gd2lsbCBiZSBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCBpbiBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWU/DQoNCg0KV2Ugd2lsbCB1c2UgdGhlc2UgcXVlc3Rpb25zIGFzIGEgc3RhcnRpbmcgcG9pbnQgZm9yIHRoaXMgcHJvamVjdCBpbiBvcmRlciB0byBjcmVhdGUgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHdoaWNoIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnRseSBwcmVkaWN0cyB0aGUgb2RkcyBvZiBhIHBhdGllbnQgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZCBiYXNlZCBvbiB0aGUgbWFueSBmYWN0b3JzIHdoaWNoIHBsYXkgYSByb2xlIGluIHRoaXMgcHJlZGljdGlvbi4gDQoNCg0KDQoNCiMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcw0KDQpGaXJzdCwgd2Ugd2lsbCByZWFkIGluIHRoZSBkYXRhIHNldCBmcm9tIEdpdGh1YiBhbmQgd2Ugd2lsbCBjYWxsIGl0ICJoZWFydGRpc2Vhc2UiLiANCg0KYGBge3J9DQpoZWFydGRpc2Vhc2UgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Kb3NpZUdhbGxvcC9TVEEzMjEvcmVmcy9oZWFkcy9tYWluL2RhdGFzZXQvZnJhbWluZ2hhbS5jc3YiLCBoZWFkZXI9VFJVRSkNCg0Kc3RyKGhlYXJ0ZGlzZWFzZSkNCmBgYA0KDQoNCg0KDQojIyBGaXhpbmcgdGhlIE1pc3NpbmcgT2JzZXJ2YXRpb25zDQoNCg0KV2hlbiBsb29raW5nIHRocm91Z2ggdGhlIGRhdGEgc2V0LCBJIG5vdGljZWQgdGhhdCBzb21lIG9ic2VydmF0aW9ucyBhcHBlYXJlZCB0byBiZSBtaXNzaW5nIGZyb20gdGhlIGRhdGEgc2V0LCBhcyB0aGV5IGhhZCB2YWx1ZXMgb2YgIk5BIiBmb3IgY2VydGFpbiB2YXJpYWJsZXMuIEJlZm9yZSB3ZSBjYW4gYmVnaW4gd2l0aCB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiwgdGhpcyBpcyBzb21ldGhpbmcgdGhhdCB3ZSBzaG91bGQgbG9vayBpbnRvLg0KDQpGaXJzdCwgbGV0J3Mgc2VlIGhvdyBtYW55IHZhbHVlcyBhcmUgbWlzc2luZyBmb3IgZWFjaCBvZiB0aGUgdmFyaWFibGVzLg0KDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEoaGVhcnRkaXNlYXNlKSkNCmBgYA0KDQpXZSBjYW4gc2VlIHRoYXQgdGhlIHZhcmlhYmxlcyBlZHVjYXRpb24sIGNpZ3NQZXJEYXksIEJQTWVkcywgdG90Q2hvbCwgQk1JLCBoZWFydFJhdGUsIGFuZCBnbHVjb3NlIGFsbCBoYXZlIG1pc3Npbmcgb2JzZXJ2YXRpb25zLg0KDQpOb3cgdGhhdCB3ZSBrbm93IHdoaWNoIHZhcmlhYmxlcyBhcmUgbWlzc2luZyBvYnNlcnZhdGlvbnMsIHdlIGNhbiBzZWUgd2hpY2ggc3BlY2lmaWMgb2JzZXJ2YXRpb25zIGFyZSBtaXNzaW5nIGZyb20gdGhlc2UgdmFyaWFibGVzLg0KDQpgYGB7cn0NCnNhcHBseShoZWFydGRpc2Vhc2UsIGZ1bmN0aW9uKHgpIHdoaWNoKGlzLm5hKHgpKSkgDQpgYGANCg0KV2Ugd2lsbCBjcmVhdGUgYSBuZXcgZGF0YSBzZXQgY2FsbGVkICJoZWFydGRpc2Vhc2UxIiB0byByZXByZXNlbnQgdGhlIGNvcnJlY3RlZCBkYXRhIHNldCB0aGF0IHdpbGwgaGF2ZSBubyBtaXNzaW5nIHZhbHVlcy4NCg0KYGBge3J9DQpoZWFydGRpc2Vhc2UxIDwtIGhlYXJ0ZGlzZWFzZSAgDQpgYGANCg0KDQojIyMgRml4aW5nIHRoZSBRdWFudGl0YXRpdmUgVmFyaWFibGVzDQoNCkZpcnN0LCBsZXQncyBmaXggdGhlIG1pc3NpbmcgdmFsdWVzIGZvciB0aGUgcXVhbnRpdGF0aXZlIHZhcmlhYmxlcy4gVGhlIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgd2l0aCBtaXNzaW5nIHZhbHVlcyBhcmUgdG90Q2hvbCwgQk1JLCBoZWFydFJhdGUsIGFuZCBnbHVjb3NlLiANCg0KTGV0J3Mgc3RhcnQgd2l0aCB0b3RDaG9sLiBXZSB3aWxsIGNhbGN1bGF0ZSB0aGUgbWVhbiB2YWx1ZSBvZiB0b3RDaG9sIGFuZCB1c2UgdGhpcyBtZWFuIHRvIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zLiBBZnRlciB3ZSByZXBsYWNlIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyB3aXRoIHRoZSBtZWFuIHZhbHVlLCB3ZSB3aWxsIHRoZW4gY2hlY2sgdGhlIGZpcnN0IDIwIG9ic2VydmF0aW9ucyBvZiB0aGUgY29ycmVjdGVkIHRvdENob2wgdmFyaWFibGUgd2l0aCB0aGUgbWlzc2luZyBvYnNlcnZhdGlvbnMgZmlsbGVkIGluIHRvIG1ha2Ugc3VyZSBldmVyeXRoaW5nIGxvb2tzIGdvb2QuIA0KDQpgYGB7cn0NCiMgUmVwbGFjZSBtaXNzaW5nIHZhbHVlcyBvZiB0b3RDaG9sIHdpdGggdGhlIG1lYW4gb2YgdG90Q2hvbC4NCm1lYW4oaGVhcnRkaXNlYXNlMSR0b3RDaG9sLCBuYS5ybSA9IFRSVUUpDQpoZWFydGRpc2Vhc2UxJHRvdENob2wgPC0gDQogIHJlcGxhY2UoaGVhcnRkaXNlYXNlMSR0b3RDaG9sLCANCiAgICAgICAgICBpcy5uYShoZWFydGRpc2Vhc2UxJHRvdENob2wpLCANCiAgICAgICAgICBtZWFuKGhlYXJ0ZGlzZWFzZTEkdG90Q2hvbCwgbmEucm0gPSBUUlVFKSkNCiMgTGV0J3MgY2hlY2sgdGhlIGZpcnN0IDIwIG9ic2VydmF0aW9ucyBvZiB0aGUgZml4ZWQgdG90Q2hvbCB0byBtYWtlIHN1cmUgaXQgYWxsIGxvb2sgZ29vZC4NCmhlYWQoaGVhcnRkaXNlYXNlMSR0b3RDaG9sLCAyMCkNCmBgYA0KDQpOZXh0LCBsZXQncyBmaXggQk1JLiBXZSB3aWxsIGNhbGN1bGF0ZSB0aGUgbWVhbiB2YWx1ZSBvZiBCTUkgYW5kIHVzZSB0aGlzIG1lYW4gdG8gcmVwbGFjZSB0aGUgbWlzc2luZyBvYnNlcnZhdGlvbnMuIEFmdGVyIHdlIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIHdpdGggdGhlIG1lYW4gdmFsdWUsIHdlIHdpbGwgdGhlbiBjaGVjayB0aGUgZmlyc3QgMjAgb2JzZXJ2YXRpb25zIG9mIHRoZSBjb3JyZWN0ZWQgQk1JIHZhcmlhYmxlIHdpdGggdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIGZpbGxlZCBpbiB0byBtYWtlIHN1cmUgZXZlcnl0aGluZyBsb29rcyBnb29kLiANCg0KYGBge3J9DQojIFJlcGxhY2UgbWlzc2luZyB2YWx1ZXMgb2YgQk1JIHdpdGggdGhlIG1lYW4gb2YgQk1JLg0KbWVhbihoZWFydGRpc2Vhc2UxJEJNSSwgbmEucm0gPSBUUlVFKQ0KaGVhcnRkaXNlYXNlMSRCTUkgPC0gDQogIHJlcGxhY2UoaGVhcnRkaXNlYXNlMSRCTUksIA0KICAgICAgICAgIGlzLm5hKGhlYXJ0ZGlzZWFzZTEkQk1JKSwgDQogICAgICAgICAgbWVhbihoZWFydGRpc2Vhc2UxJEJNSSwgbmEucm0gPSBUUlVFKSkNCiMgTGV0J3MgY2hlY2sgdGhlIGZpcnN0IDIwIG9ic2VydmF0aW9ucyBvZiB0aGUgZml4ZWQgQk1JIHRvIG1ha2Ugc3VyZSBpdCBhbGwgbG9vayBnb29kLg0KaGVhZChoZWFydGRpc2Vhc2UxJEJNSSwgMjApDQpgYGANCg0KTmV4dCwgbGV0J3MgZml4IGhlYXJ0UmF0ZS4gV2Ugd2lsbCBjYWxjdWxhdGUgdGhlIG1lYW4gdmFsdWUgb2YgaGVhcnRSYXRlIGFuZCB1c2UgdGhpcyBtZWFuIHRvIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zLiBBZnRlciB3ZSByZXBsYWNlIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyB3aXRoIHRoZSBtZWFuIHZhbHVlLCB3ZSB3aWxsIHRoZW4gY2hlY2sgdGhlIGZpcnN0IDIwIG9ic2VydmF0aW9ucyBvZiB0aGUgY29ycmVjdGVkIGhlYXJ0UmF0ZSB2YXJpYWJsZSB3aXRoIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmaWxsZWQgaW4gdG8gbWFrZSBzdXJlIGV2ZXJ5dGhpbmcgbG9va3MgZ29vZC4gDQoNCmBgYHtyfQ0KIyBSZXBsYWNlIG1pc3NpbmcgdmFsdWVzIG9mIGhlYXJ0UmF0ZSB3aXRoIHRoZSBtZWFuIG9mIGhlYXJ0UmF0ZS4NCm1lYW4oaGVhcnRkaXNlYXNlMSRoZWFydFJhdGUsIG5hLnJtID0gVFJVRSkNCmhlYXJ0ZGlzZWFzZTEkaGVhcnRSYXRlIDwtIA0KICByZXBsYWNlKGhlYXJ0ZGlzZWFzZTEkaGVhcnRSYXRlLCANCiAgICAgICAgICBpcy5uYShoZWFydGRpc2Vhc2UxJGhlYXJ0UmF0ZSksIA0KICAgICAgICAgIG1lYW4oaGVhcnRkaXNlYXNlMSRoZWFydFJhdGUsIG5hLnJtID0gVFJVRSkpDQojIExldCdzIGNoZWNrIHRoZSBmaXJzdCAyMCBvYnNlcnZhdGlvbnMgb2YgdGhlIGZpeGVkIGhlYXJ0UmF0ZSB0byBtYWtlIHN1cmUgaXQgYWxsIGxvb2sgZ29vZC4NCmhlYWQoaGVhcnRkaXNlYXNlMSRoZWFydFJhdGUsIDIwKQ0KYGBgDQoNCkFuZCBub3cgbGV0J3MgZml4IGdsdWNvc2UuIFdlIHdpbGwgY2FsY3VsYXRlIHRoZSBtZWFuIHZhbHVlIG9mIGdsdWNvc2UgYW5kIHVzZSB0aGlzIG1lYW4gdG8gcmVwbGFjZSB0aGUgbWlzc2luZyBvYnNlcnZhdGlvbnMuIEFmdGVyIHdlIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIHdpdGggdGhlIG1lYW4gdmFsdWUsIHdlIHdpbGwgdGhlbiBjaGVjayB0aGUgZmlyc3QgMjAgb2JzZXJ2YXRpb25zIG9mIHRoZSBjb3JyZWN0ZWQgZ2x1Y29zZSB2YXJpYWJsZSB3aXRoIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmaWxsZWQgaW4gdG8gbWFrZSBzdXJlIGV2ZXJ5dGhpbmcgbG9va3MgZ29vZC4gDQoNCmBgYHtyfQ0KIyBSZXBsYWNlIG1pc3NpbmcgdmFsdWVzIG9mIGdsdWNvc2Ugd2l0aCB0aGUgbWVhbiBvZiBnbHVjb3NlLg0KbWVhbihoZWFydGRpc2Vhc2UxJGdsdWNvc2UsIG5hLnJtID0gVFJVRSkNCmhlYXJ0ZGlzZWFzZTEkZ2x1Y29zZSA8LSANCiAgcmVwbGFjZShoZWFydGRpc2Vhc2UxJGdsdWNvc2UsIA0KICAgICAgICAgIGlzLm5hKGhlYXJ0ZGlzZWFzZTEkZ2x1Y29zZSksIA0KICAgICAgICAgIG1lYW4oaGVhcnRkaXNlYXNlMSRnbHVjb3NlLCBuYS5ybSA9IFRSVUUpKQ0KIyBMZXQncyBjaGVjayB0aGUgZmlyc3QgMjAgb2JzZXJ2YXRpb25zIG9mIHRoZSBmaXhlZCBnbHVjb3NlIHRvIG1ha2Ugc3VyZSBpdCBhbGwgbG9vayBnb29kLg0KaGVhZChoZWFydGRpc2Vhc2UxJGdsdWNvc2UsIDIwKQ0KYGBgDQoNCg0KIyMjIEZpeGluZyB0aGUgQ2F0ZWdvcmljYWwgVmFyaWFibGVzDQoNCk5vdyB0aGF0IHdlIGhhdmUgZml4ZWQgYWxsIG9mIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmb3IgdGhlIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMsIHdlIHdpbGwgZml4IHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmb3IgdGhlIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBhcyB3ZWxsLiBUaGUgY2F0ZWdvcmljYWwgdmFyaWFibGVzIHdpdGggbWlzc2luZyBvYnNlcnZhdGlvbnMgYXJlIGVkdWNhdGlvbiwgY2lnc1BlckRheSwgYW5kIEJQTWVkcy4gVG8gZG8gdGhpcywgd2Ugd2lsbCByZXBsYWNlIHRoZSBtaXNzaW5nIHZhbHVlcyB3aXRoIHRoZSBtb2RlIG9mIHRoYXQgdmFyaWFibGUuDQoNCkxldCdzIHN0YXJ0IHdpdGggZWR1Y2F0aW9uLiBXZSB3aWxsIGNhbGN1bGF0ZSB0aGUgbW9kZSB2YWx1ZSBvZiBlZHVjYXRpb24gYW5kIHVzZSB0aGlzIG1vZGUgdG8gcmVwbGFjZSB0aGUgbWlzc2luZyBvYnNlcnZhdGlvbnMuIEFmdGVyIHdlIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIHdpdGggdGhlIG1vZGUgdmFsdWUsIHdlIHdpbGwgdGhlbiBjaGVjayB0aGUgZmlyc3QgMjAgb2JzZXJ2YXRpb25zIG9mIHRoZSBjb3JyZWN0ZWQgZWR1Y2F0aW9uIHZhcmlhYmxlIHdpdGggdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIGZpbGxlZCBpbiB0byBtYWtlIHN1cmUgZXZlcnl0aGluZyBsb29rcyBnb29kLiANCg0KYGBge3J9DQojIFJlcGxhY2UgbWlzc2luZyB2YWx1ZXMgb2YgZWR1Y2F0aW9uIHdpdGggdGhlIG1vZGUgY2F0ZWdvcmljYWwgdmFsdWUgb2YgZWR1Y2F0aW9uLg0KaGVhcnRkaXNlYXNlMSRlZHVjYXRpb24gPC0gDQogIHJlcGxhY2UoaGVhcnRkaXNlYXNlMSRlZHVjYXRpb24sDQogICAgICAgICAgaXMubmEoaGVhcnRkaXNlYXNlMSRlZHVjYXRpb24pLA0KICAgICAgICAgIG5hbWVzKHdoaWNoLm1heCh0YWJsZShoZWFydGRpc2Vhc2UxJGVkdWNhdGlvbiBbMTo0MjM4XSkpKSkNCiMgTGV0J3MgY2hlY2sgdGhlIGZpcnN0IDMwIG9ic2VydmF0aW9ucyBvZiB0aGUgZml4ZWQgZWR1Y2F0aW9uIHRvIG1ha2Ugc3VyZSBpdCBhbGwgbG9va3MgZ29vZC4gDQpoZWFkKGhlYXJ0ZGlzZWFzZTEkZWR1Y2F0aW9uLCAzMCkNCmBgYA0KDQpOb3cgbGV0J3MgZml4IGNpZ3NQZXJEYXkuIFdlIHdpbGwgY2FsY3VsYXRlIHRoZSBtb2RlIHZhbHVlIG9mIGNpZ3NQZXJEYXkgYW5kIHVzZSB0aGlzIG1vZGUgdG8gcmVwbGFjZSB0aGUgbWlzc2luZyBvYnNlcnZhdGlvbnMuIEFmdGVyIHdlIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zIHdpdGggdGhlIG1vZGUgdmFsdWUsIHdlIHdpbGwgdGhlbiBjaGVjayB0aGUgZmlyc3QgMjAgb2JzZXJ2YXRpb25zIG9mIHRoZSBjb3JyZWN0ZWQgY2lnc1BlckRheSB2YXJpYWJsZSB3aXRoIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmaWxsZWQgaW4gdG8gbWFrZSBzdXJlIGV2ZXJ5dGhpbmcgbG9va3MgZ29vZC4gDQoNCmBgYHtyfQ0KIyBSZXBsYWNlIG1pc3NpbmcgdmFsdWVzIG9mIGNpZ3NQZXJEYXkgd2l0aCB0aGUgbW9kZSBjYXRlZ29yaWNhbCB2YWx1ZSBvZiBjaWdzUGVyRGF5Lg0KaGVhcnRkaXNlYXNlMSRjaWdzUGVyRGF5IDwtIA0KICByZXBsYWNlKGhlYXJ0ZGlzZWFzZTEkY2lnc1BlckRheSwNCiAgICAgICAgICBpcy5uYShoZWFydGRpc2Vhc2UxJGNpZ3NQZXJEYXkpLA0KICAgICAgICAgIG5hbWVzKHdoaWNoLm1heCh0YWJsZShoZWFydGRpc2Vhc2UxJGNpZ3NQZXJEYXkgWzE6NDIzOF0pKSkpDQojIExldCdzIGNoZWNrIHRoZSBmaXJzdCAzMCBvYnNlcnZhdGlvbnMgb2YgdGhlIGZpeGVkIGVkdWNhdGlvbiB0byBtYWtlIHN1cmUgaXQgYWxsIGxvb2tzIGdvb2QuIA0KaGVhZChoZWFydGRpc2Vhc2UxJGNpZ3NQZXJEYXksIDMwKQ0KYGBgDQoNCkxhc3RseSwgbGV0J3MgZml4IEJQTWVkcy4gV2Ugd2lsbCBjYWxjdWxhdGUgdGhlIG1vZGUgdmFsdWUgb2YgQlBNZWRzIGFuZCB1c2UgdGhpcyBtb2RlIHRvIHJlcGxhY2UgdGhlIG1pc3Npbmcgb2JzZXJ2YXRpb25zLiBBZnRlciB3ZSByZXBsYWNlIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyB3aXRoIHRoZSBtb2RlIHZhbHVlLCB3ZSB3aWxsIHRoZW4gY2hlY2sgdGhlIGZpcnN0IDIwIG9ic2VydmF0aW9ucyBvZiB0aGUgY29ycmVjdGVkIEJQTWVkcyB2YXJpYWJsZSB3aXRoIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBmaWxsZWQgaW4gdG8gbWFrZSBzdXJlIGV2ZXJ5dGhpbmcgbG9va3MgZ29vZC4gDQoNCmBgYHtyfQ0KIyBSZXBsYWNlIG1pc3NpbmcgdmFsdWVzIG9mIEJQTWVkcyB3aXRoIHRoZSBtb2RlIGNhdGVnb3JpY2FsIHZhbHVlIG9mIEJQTWVkcy4NCmhlYXJ0ZGlzZWFzZTEkQlBNZWRzIDwtIA0KICByZXBsYWNlKGhlYXJ0ZGlzZWFzZTEkQlBNZWRzLA0KICAgICAgICAgIGlzLm5hKGhlYXJ0ZGlzZWFzZTEkQlBNZWRzKSwNCiAgICAgICAgICBuYW1lcyh3aGljaC5tYXgodGFibGUoaGVhcnRkaXNlYXNlMSRCUE1lZHMgWzE6NDIzOF0pKSkpDQojIExldCdzIGNoZWNrIHRoZSBmaXJzdCAzMCBvYnNlcnZhdGlvbnMgb2YgdGhlIGZpeGVkIGVkdWNhdGlvbiB0byBtYWtlIHN1cmUgaXQgYWxsIGxvb2tzIGdvb2QuIA0KaGVhZChoZWFydGRpc2Vhc2UxJEJQTWVkcywgMzApDQpgYGANCg0KDQojIyMgQ2hlY2tpbmcgdGhhdCB0aGUgTWlzc2luZyBPYnNlcnZhdGlvbnMgYXJlIEZpeGVkDQoNCk5vdyB0aGF0IHdlIGhhdmUgZml4ZWQgYWxsIG9mIHRoZSB2YXJpYWJsZXMgdGhhdCB3ZXJlIG1pc3Npbmcgb2JzZXJ2YXRpb25zLCBsZXQncyBkb3VibGUgY2hlY2sgdGhhdCB0aGVyZSBhcmUgbm8gbW9yZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBpbiB0aGUgbmV3IGRhdGEgc2V0ICJoZWFydGRpc2Vhc2UxIi4NCg0KYGBge3J9DQpjb2xTdW1zKGlzLm5hKGhlYXJ0ZGlzZWFzZTEpKQ0KYGBgDQoNCkFzIHdlIGNhbiBzZWUsIGFsbCBvZiB0aGUgdmFyaWFibGVzIG5vdyBoYXZlIHplcm8gbWlzc2luZyBvYnNlcnZhdGlvbnMsIHNvIHdlIHN1Y2Nlc3NmdWxseSBmaXhlZCBhbGwgb2YgdGhlIG1pc3NpbmcgdmFsdWVzIGJ5IGZpbGxpbmcgdGhlbSBpbiB3aXRoIGVpdGhlciB0aGUgbWVhbiBvciBtb2RlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSB2YXJpYWJsZSBpbiBxdWVzdGlvbiB3YXMgcXVhbnRpdGF0aXZlIG9yIGNhdGVnb3JpY2FsLiBUaGUgbmV3LCByZXZpc2VkIGRhdGEgc2V0ICJoZWFydGRpc2Vhc2UxIiBub3cgaGFzIG5vIG1pc3Npbmcgb2JzZXJ2YXRpb25zLCBzbyB3ZSB3aWxsIHVzZSB0aGlzIGZvciBmdXJ0aGVyIGFuYWx5c2lzIGFuZCBmb3IgY3JlYXRpbmcgdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwuDQoNCk5vdyB0aGF0IHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucyBwcm9ibGVtIGhhcyBiZWVuIGZpeGVkLCB3ZSB3aWxsIHNvb24gYmVnaW4gd2l0aCBjb25zdHJ1Y3RpbmcgdGhlIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsLiANCg0KDQoNCiMjIEZpeGluZyBWYXJpYWJsZSBUeXBlcw0KDQpPbmUgb3RoZXIgdGhpbmcgSSBub3RpY2VkIHdoaWxlIGxvb2tpbmcgdGhyb3VnaCB0aGUgZGF0YSBzZXQgaXMgdGhhdCB0aGUgdmFyaWFibGUgImNpZ3NQZXJEYXkiIGlzIGdpdmVuIGFzIGEgY2hhcmFjdGVyIHZhcmlhYmxlIGV2ZW4gdGhvdWdoIGl0IHNob3VsZCBiZSBhIG51bWVyaWMgdmFyaWFibGUuIFRoaXMgdmFyaWFibGUgaXMgYSBtZWFzdXJlIG9mIHRoZSBudW1iZXIgb2YgY2lnYXJldHRlcyBhIHBhdGllbnQgc21va2VzIGluIGEgZGF5LCBzbyBpdCBzaG91bGQgYmUgcmVwb3J0ZWQgYXMgYSBudW1lcmljIHZhcmlhYmxlIHNpbmNlIGl0IGlzIGEgY29udGludW91cyByYW5nZSBvZiBwb3NzaWJsZSB2YWx1ZXMgYW5kIG5vdCBjb2xsZWN0ZWQgYXMgY2F0ZWdvcmllcy4gU28sIGxldCdzIGNvbnZlcnQgY2lnc1BlckRheSBmcm9tIGEgY2hhcmFjdGVyIHZhcmlhYmxlIHRvIGEgbnVtZXJpYyB2YXJpYWJsZS4gV2Ugd2lsbCB1c2UgdGhlIGFzLm51bWVyaWMoKSBmdW5jdGlvbiB0byBjb252ZXJ0IGNpZ3NQZXJEYXkgdG8gYSBudW1lcmljIHZhcmlhYmxlLg0KDQpgYGB7cn0NCmhlYXJ0ZGlzZWFzZTEkY2lnc1BlckRheSA8LSBhcy5udW1lcmljKGhlYXJ0ZGlzZWFzZTEkY2lnc1BlckRheSkNCmBgYA0KDQpOb3csIHRoZSBjaWdzUGVyRGF5IHZhcmlhYmxlIGlzIGNvcnJlY3RseSBnaXZlbiBhcyBhIG51bWVyaWMgdmFyaWFibGUuDQoNCg0KQWRkaXRpb25hbGx5LCB0aGUgdmFyaWFibGUgQlBNZWRzIGlzIGdpdmVuIGFzIGEgY2hhcmFjdGVyLCBob3dldmVyIHRoaXMgaXMgYSBiaW5hcnkgdmFyaWFibGUgc28gaXQgc2hvdWxkIGJlIGdpdmVuIGFzIGFuIGludGVnZXIgdmFyaWFibGUgd2l0aCB2YWx1ZXMgMCBhbmQgMSBsaWtlIHRoZSBvdGhlciBiaW5hcnkgdmFyaWFibGVzIGluIHRoZSBkYXRhIHNldC4gV2Ugd2lsbCBjb252ZXJ0IHRoaXMgdmFyaWFibGUgZnJvbSBhIGNoYXJhY3RlciB0byBhbiBpbnRlZ2VyLiBXZSB3aWxsIHVzZSB0aGUgYXMuaW50ZWdlcigpIGZ1bmN0aW9uIHRvIGRvIHRoaXMgY29udmVyc2lvbi4NCg0KYGBge3J9DQpoZWFydGRpc2Vhc2UxJEJQTWVkcyA8LSBhcy5pbnRlZ2VyKGhlYXJ0ZGlzZWFzZTEkQlBNZWRzKQ0KYGBgDQoNCk5vdywgdGhlIEJQTWVkcyB2YXJpYWJsZSBpcyBjb3JyZWN0bHkgZ2l2ZW4gYXMgYSBiaW5hcnksIGludGVnZXIgdmFyaWFibGUuDQoNCg0KTm93IHRoYXQgd2UgaGF2ZSBjb3JyZWN0ZWQgdGhlIHR5cGVzIG9mIHRoZSB2YXJpYWJsZXMgdGhhdCB3ZXJlIG1pc2xhYmVsZWQgYXMgdGhlIGluY29ycmVjdCB0eXBlLCB3ZSB3aWxsIGJlZ2luIHdpdGggdGhlIGNyZWF0aW9uIG9mIHRoZSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBpbiB0aGUgZm9sbG93aW5nIHN0ZXBzLiANCg0KDQoNCiMgU2ltcGxlIExvZ2lzdGljIFJlZ3Jlc3Npb24gTW9kZWwNCg0KDQpUbyBidWlsZCBhIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsLCB3ZSB3aWxsIHBpY2sgb25lIHByZWRpY3RvciB2YXJpYWJsZSB0byB1c2UgaW4gb3VyIG1vZGVsLiBGb3IgdGhpcyBtb2RlbCwgd2Ugd2lsbCBsb29rIGF0IHRoZSBwcmVkaWN0b3IgdmFyaWFibGUgZGlhQlAuIFRoaXMgcXVhbnRpdGF0aXZlIHByZWRpY3RvciB2YXJpYWJsZSBpcyBhIG1lYXN1cmUgb2YgdGhlIHBhdGllbnQncyBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUuIA0KDQpGaXJzdCwgbGV0J3MgbWFrZSBzdXJlIGRpYUJQIGZvbGxvd3MgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGhvdXQgYW55IGV4dHJlbWUgc2tldyBvciBvdXRsaWVycy4gV2Ugd2lsbCBjcmVhdGUgYSBoaXN0b2dyYW0gb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWFCUCB0byBjaGVjayB0aGF0IGl0IGZvbGxvd3MgYSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KDQpgYGB7cn0NCnlsaW1pdCA9IG1heChkZW5zaXR5KGhlYXJ0ZGlzZWFzZTEkZGlhQlApJHkpDQpoaXN0KGhlYXJ0ZGlzZWFzZTEkZGlhQlAsIHByb2JhYmlsaXR5ID0gVFJVRSwgbWFpbiA9ICJkaWFCUCBEaXN0cmlidXRpb24iLCB4bGFiPSJkaWFCUCIsIA0KICAgICAgIGNvbCA9ICJhbGljZWJsdWUiLCBib3JkZXI9ImNvcm5mbG93ZXJibHVlIikNCiAgbGluZXMoZGVuc2l0eShoZWFydGRpc2Vhc2UkZGlhQlAsIGFkanVzdD0yKSwgY29sPSJkYXJrb3JjaGlkIikNCmBgYA0KDQpBcyB3ZSBjYW4gc2VlLCB0aGUgZGF0YSBmb3IgZGlhQlAgYXBwZWFycyB0byBiZSBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHNvIHdlIGNhbiBtb3ZlIGZvcndhcmQgd2l0aCBidWlsZGluZyB0aGUgc2ltcGxlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCBkaWFCUCBhcyBvdXIgcHJlZGljdG9yIHZhcmlhYmxlLiBUaGVyZSBkbyBub3QgYXBwZWFyIHRvIGJlIGFueSBub3RpY2VhYmxlIG9yIGV4dHJlbWUgc2tldyBvciBvdXRsaWVycyBwcmVzZW50IGluIHRoaXMgaGlzdG9ncmFtLCBzbyB3ZSBjYW4gc2F5IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBmb3IgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGFwcGVhcnMgdG8gZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhpcyBtYWtlcyBkaWFCUCBhIGdvb2QgdmFyaWFibGUgdG8gYW5hbHl6ZSBmdXJ0aGVyIGluIHRoaXMgc2ltcGxlIGxvZ2lzaXRpYyByZWdyZXNzaW9uIG1vZGVsLg0KDQoNCg0KIyMgQnVpbGRpbmcgdGhlIExvZ2lzdGljIFJlZ3Jlc3Npb24gTW9kZWwNCg0KDQpMZXQncyBiZWdpbiB3aXRoIGNvbnN0cnVjdGluZyB0aGUgc2ltcGxlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUgZGlhQlAgVGhpcyB3aWxsIGJlIGEgc2ltcGxlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUsIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSwgdnMuIHRoZSByZXNwb25zZSB2YXJpYWJsZSBUZW5ZZWFyQ0hELCB0aGUgcGF0aWVudCdzIHJpc2sgb2YgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZC4NCg0KYGBge3J9DQpzLmxvZ2l0ID0gZ2xtKFRlblllYXJDSEQgfiBkaWFCUCwgIA0KICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSwgIA0KICAgICAgICAgIGRhdGEgPSBoZWFydGRpc2Vhc2UxKSAgICAgICAgICAgICAgICAgICAgDQpyZXN1bHQgPSBzdW1tYXJ5KHMubG9naXQpDQpyZXN1bHQNCmBgYA0KDQpUaGUgZXF1YXRpb24gZm9yIHRoZSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBvZiBkaWFCUCB2cy4gVGVuWWVhckNIRCBpcyBnaXZlbiBhcyBmb2xsb3dzOg0KDQpsb2cgcC8oMS1wKSA9IC00LjQwMjAgKyAwLjAzMTggKiBkaWFCUCANCg0KRGlhc3RvbGljIGJsb29kIHByZXNzdXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnRseSBwcmVkaWN0ZWQgdGhlIG9kZHMgb2YgYSBwYXRpZW50IGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIHdpdGhpbiBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUsIHAgPCAuMDAxLiANCg0KDQpgYGB7cn0NCm1vZGVsLmNvZWZmaWNpZW50LnN0YXRzID0gc3VtbWFyeShzLmxvZ2l0KSRjb2VmICAgICAgDQpjb25mLmNpID0gY29uZmludChzLmxvZ2l0KSAgICAgICAgICAgICAgICAgICAgDQpzdW0uc3RhdHMgPSBjYmluZChtb2RlbC5jb2VmZmljaWVudC5zdGF0cywgY29uZi5jaS45NT1jb25mLmNpKSAgDQprYWJsZShzdW0uc3RhdHMsY2FwdGlvbiA9ICJTdW1tYXJ5IFN0YXRpc3RpY3Mgb2YgdGhlIFJlZ3Jlc3Npb24gQ29lZmZpY2llbnRzIikNCmBgYA0KDQpJbiB0aGUgdGFibGUgYWJvdmUgd2UgY2FuIHNlZSB0aGF0IHRoZSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHdpdGggYSBwLXZhbHVlIG9mIHAgPCAuMDAxLiANCg0KRnVydGhlcm1vcmUsIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpcyBwb3NpdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgMTAteWVhciByaXNrIG9mIGRldmVsb3BpbmcgQ0hELCB3aXRoIM6yMSA9IDAuMDMxOC4gVGhlIDk1JSBDb25maWRlbmNlIEludGVydmFsIGZ1cnRoZXIgc3VwcG9ydHMgdGhlIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBvZiBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgaW4gcHJlZGljdGluZyB0aGUgcmlzayBvZiBhIHBhdGllbnQgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZCBvZiB0aW1lLCBbMC4wMjUxLCAwLjAzODVdLg0KDQoNCg0KIyMgR29vZG5lc3Mgb2YgRml0IERpYWdub3N0aWMgVGVzdHMNCg0KDQpTb21lIGdvb2RuZXNzIG9mIGZpdCB0ZXN0cyB3ZXJlIHBlcmZvcm1lZCBvbiB0aGUgc2ltcGxlIGxvZ2lzaXRpYyByZWdyZXNzaW9uIG1vZGVsIHRvIHZlcmlmeSBpdHMgc2lnbmlmaWNhbmNlIGFuZCB1dGlsaXR5Lg0KDQpgYGB7cn0NCmRldi5yZXNpZCA9IHMubG9naXQkZGV2aWFuY2UNCmRldi4wLnJlc2lkID0gcy5sb2dpdCRudWxsLmRldmlhbmNlDQphaWMgPSBzLmxvZ2l0JGFpYw0KZ29vZG5lc3MgPSBjYmluZChEZXZpYW5jZS5SZXNpZHVhbCA9ZGV2LnJlc2lkLCBOdWxsLkRldmlhbmNlLlJlc2lkdWFsID0gZGV2LjAucmVzaWQsDQogICAgICBBSUMgPSBhaWMpDQpwYW5kZXIoZ29vZG5lc3MpDQpgYGANCg0KVXNpbmcgdGhlIGdvb2RuZXNzIG9mIGZpdCBkaWFnbm9zdGljIHRlc3RzLCB3ZSBmb3VuZCB0aGUgZGV2aWFuY2UgcmVzaWR1YWwsIHRoZSBudWxsIGRldmlhbmNlIHJlc2lkdWFsLCBhbmQgdGhlIEFJQyB2YWx1ZSBmb3IgdGhlIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIG9mIGRpYUJQIGFuZCBUZW5ZZWFyQ0hELiBUaGUgZGV2aWFuY2UgcmVzaWR1YWwgaXMgMyw1MjcsIHRoZSBudWxsIGRldmlhbmNlIHJlc2lkdWFsIGlzIDMsNjEyLCBhbmQgdGhlIEFJQyB2YWx1ZSBpcyAzLDUzMS4NCg0KQXMgdGhlcmUgd2FzIG9ubHkgYSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCB0aGF0IHdhcyBjcmVhdGVkLCB3ZSBkbyBub3QgaGF2ZSBhbnkgb3RoZXIgcG90ZW50aWFsIGNhbmRpZGF0ZSBtb2RlbHMgdG8gY29tcGFyZSB0aGVzZSBkaWFnbm9zdGljIHZhbHVlcyB3aXRoLiANCg0KDQoNCg0KIyBSZWdyZXNzaW9uIENvZWZmaWNpZW50IEludGVycHJldGF0aW9ucw0KDQoNClRvIGhlbHAgdXMgaW50ZXJwcmV0IHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50LCB3ZSB3aWxsIGxvb2sgYXQgdGhlIG9kZHMgcmF0aW8uIFRoZSBvZGRzIHJhdGlvIHRlbGxzIHVzIHRoZSBtZWFzdXJlIG9mIGFzc29jaWF0aW9uIGJldHdlZW4gYW4gZXhwb3N1cmUgYW5kIGFuIG91dGNvbWUuIEluIHRoaXMgY2FzZSwgb3VyIGV4cG9zdXJlIHdpbGwgYmUgdGhlIHBhdGllbnQncyBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgbGV2ZWwgYW5kIHRoZSBvdXRjb21lIHdpbGwgYmUgdGhlIHBhdGllbnQncyBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4gVGhpcyBvZGRzIHJhdGlvIHZhbHVlIHdpbGwgYWxsb3cgdXMgdG8gc2VlIGhvdyBhIHBhdGllbnQncyBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2QgY2hhbmdlcyB3aXRoIGFuIGluY3JlYXNlIGluIHRoaXMgcGF0aWVudCdzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZS4NCg0KV2Ugd2lsbCBjcmVhdGUgYSB0YWJsZSBvZiB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzIHdpdGggdGhlIG9kZHMgcmF0aW8gdG8gc2VlIHdoYXQgdGhlIG9kZHMgcmF0aW8gaXMgZm9yIGRpYUJQIGFuZCB3ZSB3aWxsIHVzZSB0aGlzIHZhbHVlIHRvIGludGVycHJldCBpdHMgbWVhbmluZy4NCg0KYGBge3J9DQptb2RlbC5jb2VmZmljaWVudC5zdGF0cyA9IHN1bW1hcnkocy5sb2dpdCkkY29lZg0Kb2Rkcy5yYXRpbyA9IGV4cChjb2VmKHMubG9naXQpKQ0Kb3V0LnN0YXRzID0gY2JpbmQobW9kZWwuY29lZmZpY2llbnQuc3RhdHMsIG9kZHMucmF0aW8gPSBvZGRzLnJhdGlvKQ0Ka2FibGUob3V0LnN0YXRzLGNhcHRpb24gPSAiU3VtbWFyeSBTdGF0aXN0aWNzIHdpdGggdGhlIE9kZHMgUmF0aW8iKQ0KYGBgDQoNCg0KVGhlIG9kZHMgcmF0aW8gZm9yIGRpYUJQIGlzIDEuMDMyMy4gVGhpcyBtZWFucyB0aGF0IGZvciBldmVyeSAxIG1tSEcgaW5jcmVhc2UgaW4gYSBwYXRpZW50J3MgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlLCB0aGUgb2RkcyBvZiB0aGlzIHBhdGllbnQgZGV2ZWxvcGluZyBDSEQgd2l0aGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZSBpbmNyZWFzZXMgYnkgMy4yMyUuIFRoaXMgaXMgYSBzaWduaWZpY2FudCBwZXJjZW50YWdlLCBiZWNhdXNlIGFzIGEgcGF0aWVudCdzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpbmNyZWFzZXMgbW9yZSBhbmQgbW9yZSwgc28gd2lsbCB0aGUgb2RkcyBvZiB0aGVtIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAgeWVhciBwZXJpb2QuIA0KDQoNCg0KIyMgT2RkcyBSYXRpbyBJbnRlcnByZXRhdGlvbg0KDQoNCkRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpcyB0aGUgbG93ZXIgbnVtYmVyIGluIGEgYmxvb2QgcHJlc3N1cmUgcmVhZGluZy4gRm9yIGluc3RhbmNlLCBpbiB0aGUgYmxvb2QgcHJlc3N1cmUgbWVhc3VyZW1lbnQgb2YgMTEwLzcwLCB0aGUgNzAgaXMgdGhlIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZS4gQWRkaXRpb25hbGx5LCBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgaXMgZ2l2ZW4gaW4gdW5pdHMgb2YgbW1IRywgbWlsbGltZXRlcnMgb2YgbWVyY3VyeS4NCg0KSWdub3JpbmcgYWxsIG90aGVyIGZhY3RvcnMsIGEgcGF0aWVudCB3aXRoIGEgYmxvb2QgcHJlc3N1cmUgb2YgMTIwLzgxIHdvdWxkIGhhdmUgMy4yMyUgaGlnaGVyIG9kZHMgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gMTAgeWVhcnMgdGhhbiB0aGV5IHdvdWxkIGlmIHRoZWlyIGJsb29kIHByZXNzdXJlIHdhcyAxMjAvODAuIFRoaXMgaXMgYmVjYXVzZSBmb3IgZXZlcnkgMSBtbUhHIGluY3JlYXNlIGluIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSwgdGhlaXIgb2RkcyBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCBpbiBhIDEwLXllYXIgcGVyaW9kIGluY3JlYXNlcyBieSAzLjIzJS4gDQoNClRvIGdvIGV2ZW4gZnVydGhlciB0byBzaG93IHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhpcyBvZGRzIHJhdGlvLCBhIHBhdGllbnQgd2l0aCBhIGJsb29kIHByZXNzdXJlIG9mIDEyMC85MCB3b3VsZCBoYXZlIGFuIGluY3JlZGlibHkgc2lnbmlmaWNhbnQgMzIuMzAlIGhpZ2hlciBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIDEwIHllYXJzIHRoYW4gdGhleSB3b3VsZCBpZiB0aGVpciBibG9vZCBwcmVzc3VyZSB3YXMgMTIwLzgwLiBUaGlzIGlzIGJlY2F1c2UgZm9yIGV2ZXJ5IDEgbW1IRyBpbmNyZWFzZSBpbiBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUsIGEgcGF0aWVudCdzIG9kZHMgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gMTAgeWVhcnMgaW5jcmVhc2VzIGJ5IDMuMjMlLCBzbyBhIDEwIG1tSEcgaW5jcmVhc2UgaW4gZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIHdvdWxkIGluY3JlYXNlIHRoZSBvZGRzIGJ5IDEwJSwgZ2l2aW5nIGEgMzIuMzAlIG9kZHMgb2YgZGV2ZWxvcGluZyBDSEQgaW4gMTAgeWVhcnMgZm9yIGEgMTAgbW1IRyBpbmNyZWFzZSBpbiBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUuIFRoaXMgaXMgYW4gaW5jcmVkaWJseSBzaWduaWZpY2FudCBwZXJjZW50YWdlIG9mIHRoZSBvZGRzLCBhbmQgdGhlc2Ugb2RkcyB3b3VsZCBpbmNyZWFzZSBldmVuIGZ1cnRoZXIgYXMgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGNvbnRpbnVlcyB0byBpbmNyZWFzZS4NCg0KVGhlIG9kZHMgcmF0aW8gb2YgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGlzIHZlcnkgc2lnbmlmaWNhbnQsIGFuZCBpdCBwcm92aWRlcyBpbXBvcnRhbmNlIGZvciBzaG93aW5nIGhvdyB0aGUgdmFyaWFibGUgb2YgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGFmZmVjdHMgdGhlIHBhdGllbnQncyBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4gDQoNCg0KDQoNCg0KIyBCZWhhdmlvciBvZiB0aGUgU3VjY2VzcyBQcm9iYWJpbGl0eQ0KDQoNCk5vdyB3ZSB3aWxsIGxvb2sgYSB0aGUgYmVoYXZpb3IgYW5kIHRyZW5kcyBvZiB0aGUgc3VjY2VzcyBwcm9iYWJpbGl0eS4gV2Ugd2lsbCBjcmVhdGUgdHdvIGdyYXBocyB0byBoZWxwIHZpc3VhbGl6ZSB0aGlzLCB3aXRoIHRoZXNlIHR3byBncmFwaHMgYmVpbmcgdGhlIHN1Y2Nlc3MgcHJvYmFiaWxpdHkgY3VydmUgYW5kIHRoZSByYXRlIG9mIGNoYW5nZSBvZiB0aGUgc3VjY2VzcyBwcm9iYWJpbHR5IGN1cnZlLg0KDQoNCiMjIFByb2JhYmlsaXR5IEN1cnZlDQoNCg0KRmlyc3QsIHdlIHdpbGwgY3JlYXRlIHRoZSBncmFwaCBvZiB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgb3ZlciBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUgd2l0aCBkaWFCUCBhcyBvdXIgaW5kZXBlbmRlbnQgdmFyaWFibGUuIFdlIHdpbGwgZ3JhcGggdGhlIHN1Y2Nlc3MgcHJvYmFiaWxpdHkgd2hpY2ggaXMgdGhlIHByb2JhYmlsaXR5IG9mIHRoZSBwYXRpZW50IGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIG92ZXIgYSAxMC15ZWFyIHBlcmlvZCBiYXNlZCBvbiB0aGVpciBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUuIFRoaXMgZ3JhcGggd2lsbCB2aXN1YWxpemUgaG93IHRoZSBwYXRpZW50J3MgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBvZiBkZXZlbG9waW5nIENIRCBvdmVyIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZSBiYXNlZCBvbiB0aGVpciBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUuDQoNCg0KYGBge3J9DQojIFdlIHdpbGwgY3JlYXRlIHRoZSBncmFwaCBvZiB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBmb3IgQ0hEIG92ZXIgYSAxMC15ZWFyIHBlcmlvZCwgd2l0aCBkaWFCUCBhcyBvdXIgaW5kZXBlbmRlbnQgdmFyaWFibGUuDQpkaWFCUC5yYW5nZSA9IHJhbmdlKGhlYXJ0ZGlzZWFzZTEkZGlhQlApDQp4ID0gc2VxKGRpYUJQLnJhbmdlWzFdLCBkaWFCUC5yYW5nZVsyXSwgbGVuZ3RoID0gMjAwMCkNCmJldGEueCA9IGNvZWYocy5sb2dpdClbMV0gKyBjb2VmKHMubG9naXQpWzJdKngNCnN1Y2Nlc3MucHJvYmFiaWxpdHkgPSBleHAoYmV0YS54KS8oMStleHAoYmV0YS54KSkNCmZhaWx1cmUucHJvYmFiaWxpdHkgPSAxLygxK2V4cChiZXRhLngpKQ0KeWxpbWl0ID0gbWF4KHN1Y2Nlc3MucHJvYmFiaWxpdHksIGZhaWx1cmUucHJvYmFiaWxpdHkpDQoNCmJldGExID0gY29lZihzLmxvZ2l0KVsyXQ0Kc3VjY2Vzcy5wcm9iYWJpbGl0eS5yYXRlID0gYmV0YTEqZXhwKGJldGEueCkvKDErZXhwKGJldGEueCkpXjINCg0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGxvdCh4LCBzdWNjZXNzLnByb2JhYmlsaXR5LCB0eXBlID0gImwiLCBsd2QgPSAyLCBjb2wgPSAiZGVlcHBpbms0IiwNCiAgICAgbWFpbiA9ICJUaGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBcbiBmb3IgQ0hEIG92ZXIgYSAxMC15ZWFyIHBlcmlvZCIsIA0KICAgICB5bGltPWMoMCwgMS4xKnlsaW1pdCksDQogICAgIHhsYWIgPSAiZGlhQlAiLA0KICAgICB5bGFiID0gInByb2JhYmlsaXR5IiwNCiAgICAgYXhlcyA9IEZBTFNFLA0KICAgICBjb2wubWFpbiA9ICJkZWVwcGluazQiLA0KICAgICBjZXgubWFpbiA9IDAuOCkNCiANCmF4aXMoMSwgcG9zID0gMCkNCmF4aXMoMikNCmBgYA0KDQpUaGUgY3VydmUgb2YgdGhlIHN1Y2Nlc3MgcHJvYmFiaWxpdHkgbWF0Y2hlcyB1cCB3aXRoIHByZXZpb3VzIG9ic2VydmF0aW9ucyB0aGF0IGFzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpbmNyZWFzZXMsIHNvIGRvIHRoZSBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4gV2UgY2FuIHNlZSB0aGUgY3VydmUgaW4gdGhlIGdyYXBoIGZvbGxvd2luZyBhIHBvc2l0aXZlIGRpc3RyaWJ1dGlvbiwgd2l0aCB0aGUgcHJvYmFiaWxpdHkgaW5jcmVhc2luZyBhcyBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgYWxzbyBpbmNyZWFzZXMuIA0KDQoNCg0KDQojIyBSYXRlIG9mIENoYW5nZSBpbiB0aGUgU3VjY2VzcyBQcm9iYWJpbGl0eQ0KDQoNCk5leHQsIHdlIHdpbGwgY3JlYXRlIGEgZ3JhcGggb2YgdGhlIHJhdGUgb2YgY2hhbmdlIGluIHRoZSBzdWNjZXNzIHByb2JhYmlsaXR5LiBUaGlzIGdyYXBoIHdpbGwgdmlzdWFsaXplIHRoZSByYXRlIG9mIGNoYW5nZSBpbiB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZCBvZiB0aW1lIGJhc2VkIG9uIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZS4gQXMgc3RhdGVkIGluIHRoZSBwcmV2aW91cyBzZWN0aW9uLCB0aGUgc3VjY2VzcyBwcm9iYWJpbGl0eSBpbiB0aGlzIGNhc2UgcmVwcmVzZW50cyB0aGUgcGF0aWVudCdzIHByb2JhYmlsaXR5IG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2QuIFRoaXMgcHJvYmFiaWxpdHkgaXMgYmFzZWQgb24gdGhlIHBhdGllbnQncyBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUsIGFzIHRoYXQgaXMgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlIGluIG91ciBtb2RlbC4gVGhpcyBncmFwaCB3aWxsIHNob3cgaG93IHRoZSByYXRlIG9mIGNoYW5nZSBpbiB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgb3ZlciBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUgY2hhbmdlcyBiYXNlZCBvbiB0aGUgcGF0aWVudCdzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZS4gDQoNCmBgYHtyfQ0KIyBXZSB3aWxsIGNyZWF0ZSBhIGdyYXBoIHRvIHNob3cgdGhlIHJhdGUgb2YgY2hhbmdlIGluIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBhdCByaXNrIGZvciBDSEQgb3ZlciBhIDEwLXllYXIgcGVyaW9kLCB3aXRoIGRpYUJQIGFzIG91ciBpbmRlcGVuZGVudCB2YXJpYWJsZS4NCnkucmF0ZSA9IG1heChzdWNjZXNzLnByb2JhYmlsaXR5LnJhdGUpDQpwbG90KHgsIHN1Y2Nlc3MucHJvYmFiaWxpdHkucmF0ZSwgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gImRlZXBwaW5rNCIsDQogICAgIG1haW4gPSAiVGhlIHJhdGUgb2YgY2hhbmdlIGluIHRoZSBwcm9iYWJpbGl0eSBcbiAgb2YgYmVpbmcgYXQgcmlzayBmb3IgQ0hEIG92ZXIgYSBcbiAxMCB5ZWFyIHBlcmlvZCIsIA0KICAgICB4bGFiID0gImRpYUJQIiwNCiAgICAgeWxhYiA9ICJSYXRlIG9mIENoYW5nZSIsDQogICAgIHlsaW09YygwLDEuMSp5LnJhdGUpLA0KICAgICBheGVzID0gRkFMU0UsDQogICAgIGNvbC5tYWluID0gImRlZXBwaW5rNCIsDQogICAgIGNleC5tYWluID0gMC44DQogICAgICkNCmF4aXMoMSwgcG9zID0gMCkNCmF4aXMoMikNCmBgYA0KDQpUaGUgY3VydmUgZm9yIHRoZSByYXRlIG9mIGNoYW5nZSBpbiB0aGUgc3VjY2VzcyBwcm9iYWJpbGl0eSBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCBpbiBhIDEwLXllYXIgcGVyaW9kIGFwcGVhcnMgdG8gZm9sbG93IGFuIFMtY3VydmUgZml0dGluZyB0byB0aGF0IG9mIGEgbG9naXN0aWMgbW9kZWwgbGlrZSB3aGljaCB3YXMgY3JlYXRlZC4gVGhlIHJhdGUgb2YgY2hhbmdlIGFwcGVhcnMgdG8gaW5jcmVhc2UgcmFwaWRseSBhdCBmaXJzdCBidXQgdGhlbiBzbG93cyBkb3duIHdoZW4gZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIHJlYWNoZXMgYXJvdW5kIDEyMCBtbUhnLiBUaGUgY3VydmUgZm9sbG93cyBhbiBvdmVyYWxsIHBvc2l0aXZlIGRpc3RyaWJ1dGlvbiwgd2l0aCB0aGUgcmF0ZSBvZiBjaGFuZ2UgYmVpbmcgaGlnaGVyIGFzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpcyBhbHNvIGhpZ2hlci4gVGhpcyBTLWN1cnZlIHNob3dzIGhvdyB0aGUgcmF0ZSBvZiBjaGFuZ2UgaW4gdGhlIHByb2JhYmlsaXR5IG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIG92ZXIgYSAxMC15ZWFyIHBlcmlvZCBjaGFuZ2VzIGFzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpbmNyZWFzZXMuIA0KDQoNCg0KDQojIENvbmNsdXNpb24NCg0KT3ZlcmFsbCwgYSBzaW1wbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCB3YXMgY3JlYXRlZCB0byBvYnNlcnZlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUgb2YgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGFuZCB0aGUgcmVzcG9uc2UgdmFyaWFibGUgb2Ygd2hldGhlciBhIHBhdGllbnQgaXMgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgb3ZlciBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUuIFRoZSByZWdyZXNzaW9uIG1vZGVsIHdhcyBnaXZlbiBhcyBmb2xsb3dzOiANCg0KbG9nIHAvKDEtcCkgPSAtNC40MDIwICsgMC4wMzE4ICogZGlhQlAgDQoNCkFuZCBpdCB0dXJuZWQgb3V0IHRoYXQgdGhpcyBtb2RlbCB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBpbiBwcmVkaWN0aW5nIHRoZSBvZGRzIG9mIGEgcGF0aWVudCBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCBpbiBhIDEwLXllYXIgcGVyaW9kIHdpdGggYSBwLXZhbHVlIG9mIHAgPCAuMDAxLiBUaGlzIG1vZGVsIHNob3dzIHRoYXQgYXMgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIGluY3JlYXNlcywgc28gZG9lcyB0aGUgb2RkcyBvZiBhIHBhdGllbnQgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQgaW4gYSAxMC15ZWFyIHBlcmlvZC4gRnVydGhlcm1vcmUsIGl0IHdhcyBmb3VuZCB0aGF0IHRoZSBvZGRzIHJhdGlvIGZvciBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgaW4gdGhpcyBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHdhcyAxLjAzMjMsIG1lYW5pbmcgdGhhdCBmb3IgZXZlcnkgMSBtbUhHIGluY3JlYXNlIGluIGEgcGF0aWVudCdzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSwgdGhlIG9kZHMgb2YgdGhpcyBwYXRpZW50IGRldmVsb3BpbmcgQ0hEIHdpdGhpbiBhIDEwLXllYXIgcGVyaW9kIG9mIHRpbWUgaW5jcmVhc2VzIGJ5IDMuMjMlLiANCg0KVGhpcyBpcyBzaWduaWZpY2FudCBhcyBpdCBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24gZm9yIGJvdGggZG9jdG9ycyBhbmQgcGF0aWVudHMgdG8gYXNzZXNzIHRoZSBwYXRpZW50J3Mgb2RkcyBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRC4gSXQgYXBwZWFycyB0aGF0IHRoZXJlIGlzIHN1ZmZpY2llbnQgZXZpZGVuY2UgdG8gY29uY2x1ZGUgdGhhdCB0aGUgaGlnaGVyIGEgcGF0aWVudCdzIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpcywgdGhlIGhpZ2hlciB0aGVpciBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGFyZS4gU28sIHRoaXMgaXMgdmVyeSB1c2VmdWwgZm9yIHByb3ZpZGluZyBkb2N0b3JzIGFuZCBwYXRpZW50cyB3aXRoIGEgZmFjdG9yIHdoaWNoIGFmZmVjdHMgdGhlaXIgb2RkcyBvZiBiZWluZyBhdCByaXNrIGZvciBkZXZlbG9waW5nIENIRCBvdmVyIGEgMTAteWVhciBwZXJpb2QuDQoNCg0KU29tZSByZWNvbW1lbmRhdGlvbnMgSSB3b3VsZCBtYWtlIGZvciBmdXR1cmUgcHJvamVjdHMgaW5jbHVkZToNCg0KKiBUaGlzIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIGZvY3VzZWQgb24gdXNpbmcgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlIHRvIHByZWRpY3QgdGhlIG9kZHMgb2YgYW4gaW5kaXZpZHVhbCBiZWluZyBhdCByaXNrIG9mIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2QuIEZvciBmdXR1cmUgcmVzZWFyY2gsIGl0IGNvdWxkIGJlIGEgZ29vZCBpZGVhIHRvIGxvb2sgaW50byBhIGNvbWJpbmF0aW9uIG9mIHN5c3RvbGljIGFuZCBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgbGV2ZWxzIHRvIHNlZSBpZiB0aGF0IHByb3ZpZGVzIGhpZ2hlciBzaWduaWZpY2FuY2UgZm9yIHByZWRpY3Rpb24uIA0KDQoqIEFkZGl0aW9uYWxseSwgc29tZSBpbnRlcmFjdGlvbnMgYmV0d2VlbiBkaWZmZXJlbnQgdmFyaWFibGVzIGNvdWxkIGJlIGxvb2tlZCBpbnRvIGluIGZ1cnRoZXIgZXhwZXJpbWVudHMgdGhhdCBnZXQgaW50byBtdWx0aXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVscy4gSXQgd291bGQgYmUgd29ydGggbG9va2luZyBpbnRvIHdoZXRoZXIgYW55IG9mIHRoZSB2YXJpYWJsZXMgaW4gdGhpcyBtb2RlbCBpbnRlcmFjdCB3aXRoIG9uZSBhbm90aGVyLg0KDQoqIFRoZSBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgdmFyaWFibGUgd2FzIHNob3duIHRvIGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24gYW5kIGRpZCBub3QgbmVlZCB0byB1bmRlcmdvIGFueSB0cmFuc2Zvcm1hdGlvbnMgdG8gYmUgdXNlZCBpbiB0aGUgZmluYWwgbW9kZWwuIEhvd2V2ZXIsIGluIGZ1dHVyZSBwcm9qZWN0cyBpdCB3b3VsZCBiZSBpbXBvcnRhbnQgdG8gbG9vayBhdCB0aGUgb3RoZXIgdmFyaWFibGVzIGluIHRoZSBtb2RlbCB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSB3aGljaCBuZWVkIHRvIGJlIHRyYW5zZm9ybWVkIGluIHNvbWUgd2F5IHRvIHByb3ZpZGUgdGhlIGJlYXQgdXRpbGl0eSB0byB0aGUgbW9kZWwuDQoNCg0KT3ZlcmFsbCwgdGhpcyBwcm9qZWN0IHNob3dlZCB0aGF0IGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGluIHByZWRpY3RpbmcgdGhlIG9kZHMgb2YgYSBwYXRpZW50IGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2Qgb2YgdGltZS4gVGhpcyBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24gdG8gcGF0aWVudHMgc28gdGhhdCB0aGV5IGNhbiBsb29rIGludG8gaG93IHRoZWlyIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBhZmZlY3RzIHRoZWlyIG9kZHMgb2YgYmVpbmcgYXQgcmlzayBmb3IgZGV2ZWxvcGluZyBDSEQuIFRoaXMgYWxzbyBwcm92aWRlcyB1c2VmdWwgaW5mb3JtYXRpb24gdG8gZG9jdG9ycyBzbyB0aGV5IGNhbiBrZWVwIGFuIGV5ZSBvdXQgZm9yIHdoaWNoIHBhdGllbnRzIG1heSBoYXZlIGhpZ2hlciBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGR1ZSB0byBwb3RlbnRpYWwgaGlnaCBkaWFzdG9saWMgYmxvb2QgcHJlc3N1cmUgbGV2ZWxzLiBUaGlzIHNpbXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHRoYXQgd2FzIGNyZWF0ZWQgaGFzIGdvb2QgdXRpbGl0eSBmb3IgcHJlZGljdGluZyBhIHBhdGllbnQncyBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGluIGEgMTAteWVhciBwZXJpb2QgYmFzZWQgb2ZmIG9mIHRoZWlyIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSwgYW5kIHRoaXMgcHJvdmlkZXMgdXNlZnVsIGluZm9ybWF0aW9uIGluIGFsbG93aW5nIHBhdGllbnRzIHRvIHVuZGVyc3RhbmQgd2hldGhlciB0aGV5IGhhdmUgZ3JlYXRlciBvZGRzIG9mIGJlaW5nIGF0IHJpc2sgZm9yIGRldmVsb3BpbmcgQ0hEIGJhc2VkIG9uIHRoZWlyIGRpYXN0b2xpYyBibG9vZCBwcmVzc3VyZSBsZXZlbC4gDQoNCg0KDQoNCiMgUmVmZXJlbmNlcw0KDQpUaGlzIGRhdGEgc2V0IHdhcyBmb3VuZCBvbiBrYWdnbGUuY29tIHVuZGVyIHRoZSBjb2xsZWN0aW9uIG9mIGxvZ2lzdGljIHJlZ3Jlc3Npb24gZGF0YSBzZXRzLiBJbmNsdWRlZCBiZWxvdyBpcyB0aGUgY2l0YXRpb24gb2YgdGhlIHdlYiBwYWdlIG9mIHdoZXJlIEkgZm91bmQgdGhlIGRhdGEgc2V0IEkgdXNlZCBmb3IgbXkgcHJvamVjdC4gDQoNCkRpbGVlcC4gKDIwMTksIEp1bmUgNykuIExvZ2lzdGljIHJlZ3Jlc3Npb24gdG8gcHJlZGljdCBoZWFydCBkaXNlYXNlLiBLYWdnbGUuIGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvZGlsZWVwMDcwL2hlYXJ0LWRpc2Vhc2UtcHJlZGljdGlvbi11c2luZy1sb2dpc3RpYy1yZWdyZXNzaW9uP3Jlc291cmNlPWRvd25sb2FkJnNlbGVjdD1mcmFtaW5naGFtLmNzdiANCg==