1 Introduction and Background

Here we have a dataset sourced from New York City’s Traffic Information Management System (TIMS). TIMS recorded the number of cyclists entering and leaving three of New York City’s five boroughs - Queens, Manhattan and Brooklyn - via a collection of bridges known as the East River Bridges (Brooklyn Bridge, Manhattan Bridge, Williamsburg Bridge, and Queensboro Bridge). These recordings took place in 2017. April, July and October are the three months that are present in our available copy of the data.

For today’s analysis we are going to look at a randomly selected subset of the larger dataset (subset was chosen using R’s runif function), that pertains to cyclists who entered and left our three boroughs of interest - Queens, Manhattan and Brooklyn - via the Manhattan Bridge throughout the entire month of July 2017. This data has 31 observations, one detailing each day, and no missing values. A breakdown of each of the original dataset’s variables, their practical meaning and data types are below.

Name Meaning Data_Type
Date Date for that observation; YYYY-MM-DD form Date
Day Day of the week for that observation character
HighTemp That day’s highest recorded temperature double
LowTemp That day’s lowest recorded temperature double
Precipitation Measure of rain that day (inches) double
Manhattan Number of cyclists entering/leaving Queens, Manhattan or Brooklyn via the MANHATTAN Bridge double
Total Total number of cyclists entering/leaving Queens, Manhattan or Brooklyn via ANY of the East River Bridges double

1.1 Objective of Analysis

With the available data, my goal for this analysis is to examine the association between weather conditions and day of the week with the amount of cyclist traffic that the Manhattan Bridge experiences. In order to do this, I created two new variables - MeanTemp and TempDiff - which were calculated by averaging that particular day’s low and high temperatures and finding the difference between those temperatures respectively.

Using these temperature-related metrics, along with measures of precipitation and records of the day of the week, I will use Poisson regression techniques to see which if any of these factors play a particular role in the overall amount or the relative rate of cyclist traffic that the Manhattan Bridge experiences.

2 Poisson Regression Modeling

To explore any potential associations, I created Poisson models of two different regression types, one being for counts and one being for rates.

Poisson counts regression examines the total number of occurrences of a particular event (in this case cyclists on the Manhattan Bridge) and uses a logarithmic function to determine which, if any of the explanatory variables have a significant effect on said response variable’s mean. The formula for said regression is below:

  • \(\beta\)0 = the log of our response variable’s mean; not very useful for practical interpretation

  • \(\beta\)1, \(\beta\)2, \(\beta\)3, … \(\beta\)p = the change in our response variable’s log mean, in association with a one unit increase in said predictor variable


Additionally, Poisson rates regression aims to find the expected rate of a particular event’s occurrence relative to that event’s proportion within a larger “population.” In the instance of this dataset and analysis, our variable Total, which represents the total number of cyclists on all the East River Bridges, will be what the number of cyclists on the Manhattan Bridge are considered to be a proportion of. The calculation for this type of Poisson regression is similar to counts regression, but the logarithm of the population variable is also considered to be a factor. This can be expressed in both of the following ways.


  • In Poisson rates regression, the parameters \(\beta\)0, …. \(\beta\)p should be interpreted in the same manner as they are in Poisson counts model.

2.1 Poisson Regression (Counts)

Below is a summary of the Poisson counts regression model I created, with measures of temperature range and averages, precipitation amount and day of the week all functioning as predictors of how many cyclists crossed the Manhattan Bridge in or out of our three boroughs of interest.

# Counts Model:
  # Response = Manhattan
  # Predictors = Day, MeanTemp, TempDiff, Precipitation
    # Day is stored as a Factor

Counts_Model = glm(Manhattan ~ Day + MeanTemp + TempDiff + Precipitation, family = poisson(link = "log"), data = Data)

Counts_Model_Sum = summary(Counts_Model)
Counts_Model_Coef = Counts_Model_Sum$coefficients

invisible(Counts_Model_Coef)
kable(Counts_Model_Coef, caption = "Poisson Counts Regression: Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists")
Poisson Counts Regression: Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists
Estimate Std. Error z value Pr(>|z|)
(Intercept) 8.5013371 0.0421490 201.697286 0.0000000
DayMonday 0.3199236 0.0089935 35.572866 0.0000000
DayTuesday 0.3357894 0.0093242 36.012843 0.0000000
DayWednesday 0.4023102 0.0090796 44.309388 0.0000000
DayThursday 0.2807381 0.0096557 29.074878 0.0000000
DayFriday 0.1331873 0.0107366 12.405032 0.0000000
DaySaturday -0.0859127 0.0097279 -8.831613 0.0000000
MeanTemp -0.0029260 0.0006129 -4.774076 0.0000018
TempDiff 0.0143243 0.0008575 16.703807 0.0000000
Precipitation -0.4307477 0.0104214 -41.332836 0.0000000
# All predictor variables are significant

In the model, we can see that every predictor variable is statistically significant as per p values well below the standard of 0.05, so no stepwise regression or model simplification is necessary.

As for the practical implications of our model summary, we can say that although every predictor variable is statistically significant, the magnitude of their impacts are relatively small. Precipitation’s estimated negative effect on the log mean of Manhattan Bridge cyclists has an absolute value ~ |.4307|, which is the the highest of all our predictors.

It appears that the day’s average temperature and difference in daily highs and lows played very little practical significance in the log mean of that day’s cyclists. When we look at the difference in log means from a day-of-the-week perspective, we do see a slightly more impactful effect. With Sunday being coded in as the baseline, it looks like Wednesday has the greatest amount of cyclist traffic and Saturday has the least. This higher count of cyclists during the workweek could be due to the Manhattan Bridge functioning for many as a commuting method.

All in all, our Poisson counts model yields some interesting and statistically significant revelations, most notably that cyclists care far more about precipitation than they do temperature fluctuation, and that cyclist traffic appears to tick upwards throughout the workweek before dying down for the weekend. However, the relatively small magnitude of each variable’s estimated effect is a downside regarding the model’s utility.

2.2 Poisson Regression (Rates)

After Poisson counts regression, I then performed Poisson rates regression with the total number of cyclists entering and exiting our three boroughs of interest across all the East River Bridges as the “population” for which the Manhattan Bridge cyclists are acting as a sample of.

This process consisted of me creating two different Poisson rates models. The first one I created listed both temperature variables as statistically insignificant. Given their status as statistically insignificant in this model, and their minute practical significance in the previous counts model, I chose to remove them and create a second Poisson rates model which did not factor in the day’s average or range of temperature.

### Rates Model 1
Rates_Model = glm(Manhattan ~ Day + MeanTemp + TempDiff + Precipitation, offset = log(Total), family = poisson(link = "log"), data = Data)

Rates_Model_Sum = summary(Rates_Model)
Rates_Model_Coef = Rates_Model_Sum$coefficients

invisible(Rates_Model_Coef)
kable(Rates_Model_Coef, caption = "Poisson Rates Regression (1): Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists")
Poisson Rates Regression (1): Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.1844325 0.0418215 -28.3211719 0.0000000
DayMonday 0.0418134 0.0088829 4.7071774 0.0000025
DayTuesday 0.0549949 0.0094416 5.8247706 0.0000000
DayWednesday 0.0316272 0.0090743 3.4853702 0.0004915
DayThursday 0.0048565 0.0096974 0.5008067 0.6165072
DayFriday -0.0167479 0.0108925 -1.5375635 0.1241554
DaySaturday -0.0667274 0.0097414 -6.8498669 0.0000000
MeanTemp -0.0010004 0.0006053 -1.6527512 0.0983815
TempDiff 0.0008449 0.0008628 0.9792330 0.3274649
Precipitation -0.0306511 0.0095235 -3.2184824 0.0012887
### Rates Model 2
Rates_Model2 = glm(Manhattan ~ Day + Precipitation, offset = log(Total), family = poisson(link = "log"), data = Data)

Rates_Model2_Sum = summary(Rates_Model2)
Rates_Model2_Coef = Rates_Model2_Sum$coefficients

invisible(Rates_Model_Coef)
kable(Rates_Model2_Coef, caption = "Poisson Rates Regression (2): Precipitation and Schedule Relationship with Count of Manhattan Bridge Cyclists")
Poisson Rates Regression (2): Precipitation and Schedule Relationship with Count of Manhattan Bridge Cyclists
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.2497005 0.0065309 -191.3530685 0.0000000
DayMonday 0.0417392 0.0088231 4.7306551 0.0000022
DayTuesday 0.0522471 0.0090521 5.7718313 0.0000000
DayWednesday 0.0285783 0.0088706 3.2216687 0.0012745
DayThursday 0.0006398 0.0091826 0.0696739 0.9444532
DayFriday -0.0205402 0.0106430 -1.9299220 0.0536165
DaySaturday -0.0684652 0.0096858 -7.0685797 0.0000000
Precipitation -0.0288171 0.0093266 -3.0897749 0.0020031

Looking at the findings of our second Poisson rates regression model, we see a trend similar to that of our Poisson counts regression model, that being a common occurrence of statistical significance but not a great deal of practical significance on display when the magnitude of the regression coefficient is taken into consideration.

Once again treating Sunday as our baseline, it looks like the rate of Manhattan Bridge cyclists in proportion to the entirety of East River Bridge cyclists is at its highest early in the week, with that rate declining going into the weekend. That being said, the statistical significance of this breakdown also greatly decreases when we look at the data for Thursday and to a much lesser but still noticeable extent Friday, perhaps suggesting that the Manhattan Bridge cyclist rate’s decline at the tail end of the workweek could be chalked up to random chance and not a particular characteristic of the Bridge that affects the experience of its cyclists only on those particular days.

2.3 Day-By-Day Averages

Since both our counts and rates models suggested that the day of the week has the greatest association with the log mean of the Manhattan Bridge’s cyclists, I decided to calculate the average counts and rates per day to compare them to each other and the mean across all days considered. The table with this information is below.

Count_Averages = c(
  round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Sunday"])),
  round(mean(Data$Manhattan[Data$Day == "Monday"])),
  round(mean(Data$Manhattan[Data$Day == "Tuesday"])),
  round(mean(Data$Manhattan[Data$Day == "Wednesday"])),
  round(mean(Data$Manhattan[Data$Day == "Thursday"])),
  round(mean(Data$Manhattan[Data$Day == "Friday"])),
  round(mean(Data$Manhattan[Data$Day == "Saturday"]))
)

AllDays_Rates_Avg = sum(Data$Manhattan)/sum(Data$Total)

Sun_Rates_Avg = sum(Data$Manhattan[Data$Day == "Sunday"])/sum(Data$Total[Data$Day == "Sunday"])

Mon_Rates_Avg = sum(Data$Manhattan[Data$Day == "Monday"])/sum(Data$Total[Data$Day == "Monday"])

Tues_Rates_Avg = sum(Data$Manhattan[Data$Day == "Tuesday"])/sum(Data$Total[Data$Day == "Tuesday"])

Wed_Rates_Avg = sum(Data$Manhattan[Data$Day == "Wednesday"])/sum(Data$Total[Data$Day == "Wednesday"])

Thur_Rates_Avg = sum(Data$Manhattan[Data$Day == "Thursday"])/sum(Data$Total[Data$Day == "Thursday"])

Fri_Rates_Avg = sum(Data$Manhattan[Data$Day == "Friday"])/sum(Data$Total[Data$Day == "Friday"])

Sat_Rates_Avg = sum(Data$Manhattan[Data$Day == "Saturday"])/sum(Data$Total[Data$Day == "Saturday"])

Day_Rates_Averages = c(AllDays_Rates_Avg, Sun_Rates_Avg, Mon_Rates_Avg, Tues_Rates_Avg, Wed_Rates_Avg, Thur_Rates_Avg, Fri_Rates_Avg, Sat_Rates_Avg)

Rate_Averages = round(Day_Rates_Averages, digits = 4)

Days = c("All Days", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")

Counts_Difference = c(
  0, # Difference between the average count of all days and itself
  round(mean(Data$Manhattan[Data$Day == "Sunday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Monday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Tuesday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Wednesday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Thursday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Friday"])) - round(mean(Data$Manhattan)),
  round(mean(Data$Manhattan[Data$Day == "Saturday"])) - round(mean(Data$Manhattan))
)

Rates_DifferenceB = c(
  0,
  Sun_Rates_Avg - AllDays_Rates_Avg,
  Mon_Rates_Avg - AllDays_Rates_Avg,
  Tues_Rates_Avg - AllDays_Rates_Avg,
  Wed_Rates_Avg - AllDays_Rates_Avg,
  Thur_Rates_Avg - AllDays_Rates_Avg,
  Fri_Rates_Avg - AllDays_Rates_Avg,
  Sat_Rates_Avg - AllDays_Rates_Avg
)

Rates_Difference = round(Rates_DifferenceB, digits = 4)

Table = cbind(Days, Count_Averages, Counts_Difference, Rate_Averages, Rates_Difference)

kable(Table, caption = "Distribution of Manhattan Bridge Cyclist Count and Rates July 2017") %>%
  kable_styling(
    bootstrap_options = c("striped", "bordered"),
    full_width = FALSE,
    position = "center"
  )
Distribution of Manhattan Bridge Cyclist Count and Rates July 2017
Days Count_Averages Counts_Difference Rate_Averages Rates_Difference
All Days 5425 0 0.2885 0
Sunday 4690 -735 0.2865 -0.002
Monday 6001 576 0.2975 0.009
Tuesday 6363 938 0.302 0.0135
Wednesday 6938 1513 0.2949 0.0064
Thursday 5999 574 0.2868 -0.0017
Friday 4338 -1087 0.2775 -0.0109
Saturday 4031 -1394 0.2665 -0.022

The table provides greater detail into the implications of our Poisson count and rate models. That being weekday totals of Manhattan Bridge cyclists (specifically Monday - Thursday) far outweigh the count of cyclists on the bridge from Friday to Sunday. With the average number of cylclists from Monday - Thursday being about 6,325, and the average number Friday - Sunday being about 4,353.

As for the rate of Manhattan Bridge cyclists relative to cyclists on all East River Bridges, we see that the Manhattan Bridge’s cyclist rate is slightly above average Monday - Wednesday, but then below average Thursday through Sunday.

3 Conclusion and Takeaways

To conclude, any implementations done in response to this model’s findings should be done with caution due to the low practical significance found in both our count and rate Poisson models. That being said, there are still valuable takeaways that we can draw from our analysis.

First, the Manhattan Bridge is clearly busier, both in the sense of raw volume and as a proportion of the overall East River Bridge network, early and throughout the standard workweek than it is during the weekend. Second, the daily average temperature as well as the difference between that day’s high and low played very little if any role in the count or rate of cyclists on any given day, but the measure of precipitation does appear to have a relatively noticeable and negative association with the number of that day’s cyclists on the Manhattan Bridge.

If we were to continue or expand on this analysis in the future, it would be valuable to expand the scope of our data outside of the month of July and into months that border on seasonal changes such as March, April or October. Intuitively, one might guess that the day’s temperatures play a much larger role in a time of the year like that.

LS0tCnRpdGxlOiAiQXNzb2NpYXRpb24gYmV0d2VlbiBXZWF0aGVyIGFuZCBEYXkgb2YgV2VlayB3aXRoIEN5Y2xpc3QgVHJhZmZpYyBvbiBNYW5oYXR0YW4gQnJpZGdlIgphdXRob3I6ICJDaHJpcyBCYWhtIgpkYXRlOiAiMjAyNS0xMC0zMCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgZmlnX3dpZHRoOiA2CiAgICBmaWdfaGVpZ2h0OiA0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBsdW1lbgogICAgaGlnaGxpZ2h0OiB0YW5nbwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiA0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgd29yZF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiA0Ci0tLQoKYGBge2NzcywgZWNobyA9IEZBTFNFfQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQoKaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8KICBmb250LXNpemU6IDI0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIwcHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTRweDsKICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsKICBjb250ZW50OiAiLiI7Cn0KYGBgCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IAojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4KCmlmICghcmVxdWlyZSgia25pdHIiKSkgeyAgICAgICAgICAgICAgICAgICAgICAjIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgdG8gZGV0ZWN0CiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikgICAgICAgICAgICAgICAgICAjIHdoZXRoZXIgYSBwYWNrYWdlIHdhcyBpbnN0YWxsZWQgaW4KICAgbGlicmFyeShrbml0cikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91ciBtYWNoaW5lLiBJZiBub3QsIGluc3RhbGwgaXQgYW5kCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGxvYWQgaXQgdG8gdGhlIHdvcmtpbmcgZGlyZWN0b3J5LgoKaWYgKCFyZXF1aXJlKHRpZHl2ZXJzZSkpIHtsaWJyYXJ5KHRpZHl2c2Vyc2UpfSAKCmlmICghcmVxdWlyZShHR2FsbHkpKSB7bGlicmFyeShHR2FsbHkpfSAKCmlmICghcmVxdWlyZShrYWJsZUV4dHJhKSkge2xpYnJhcnkoa2FibGVFeHRyYSl9IAoKaWYgKCFyZXF1aXJlKGdncGxvdDIpKSB7bGlicmFyeShnZ3Bsb3QyKX0gCgppZiAoIXJlcXVpcmUoY2FyKSkge2xpYnJhcnkoY2FyKX0gCgppZiAoIXJlcXVpcmUoZHBseXIpKSB7bGlicmFyeShkcGx5cil9IAoKaWYgKCFyZXF1aXJlKHBhbmRlcikpIHtsaWJyYXJ5KHBhbmRlcil9IAoKaWYgKCFyZXF1aXJlKGNhcikpIHtsaWJyYXJ5KGNhcil9IAoKaWYgKCFyZXF1aXJlKCJzY2FsZXMiKSkgewppbnN0YWxsLnBhY2thZ2VzKCJzY2FsZXMiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKbGlicmFyeSgic2NhbGVzIikgCn0KCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKCWVjaG8gPSBUUlVFLAoJbWVzc2FnZSA9IEZBTFNFLAoJd2FybmluZyA9IEZBTFNFLAoJY29tbWVudCA9IE5BLAoJcmVzdWx0cyA9IFRSVUUKKQogICAKYGBgCgojIEludHJvZHVjdGlvbiBhbmQgQmFja2dyb3VuZApIZXJlIHdlIGhhdmUgYSBkYXRhc2V0IHNvdXJjZWQgZnJvbSBOZXcgWW9yayBDaXR5J3MgVHJhZmZpYyBJbmZvcm1hdGlvbiBNYW5hZ2VtZW50IFN5c3RlbSAoVElNUykuIFRJTVMgcmVjb3JkZWQgdGhlIG51bWJlciBvZiBjeWNsaXN0cyBlbnRlcmluZyBhbmQgbGVhdmluZyB0aHJlZSBvZiBOZXcgWW9yayBDaXR5J3MgZml2ZSBib3JvdWdocyAtIFF1ZWVucywgTWFuaGF0dGFuIGFuZCBCcm9va2x5biAtIHZpYSBhIGNvbGxlY3Rpb24gb2YgYnJpZGdlcyBrbm93biBhcyB0aGUgRWFzdCBSaXZlciBCcmlkZ2VzIChCcm9va2x5biBCcmlkZ2UsIE1hbmhhdHRhbiBCcmlkZ2UsIFdpbGxpYW1zYnVyZyBCcmlkZ2UsIGFuZCBRdWVlbnNib3JvIEJyaWRnZSkuIFRoZXNlIHJlY29yZGluZ3MgdG9vayBwbGFjZSBpbiAyMDE3LiBBcHJpbCwgSnVseSBhbmQgT2N0b2JlciBhcmUgdGhlIHRocmVlIG1vbnRocyB0aGF0IGFyZSBwcmVzZW50IGluIG91ciBhdmFpbGFibGUgY29weSBvZiB0aGUgZGF0YS4KCkZvciB0b2RheSdzIGFuYWx5c2lzIHdlIGFyZSBnb2luZyB0byBsb29rIGF0IGEgcmFuZG9tbHkgc2VsZWN0ZWQgc3Vic2V0IG9mIHRoZSBsYXJnZXIgZGF0YXNldCAoc3Vic2V0IHdhcyBjaG9zZW4gdXNpbmcgUidzIHJ1bmlmIGZ1bmN0aW9uKSwgdGhhdCBwZXJ0YWlucyB0byBjeWNsaXN0cyB3aG8gZW50ZXJlZCBhbmQgbGVmdCBvdXIgdGhyZWUgYm9yb3VnaHMgb2YgaW50ZXJlc3QgLSBRdWVlbnMsIE1hbmhhdHRhbiBhbmQgQnJvb2tseW4gLSB2aWEgdGhlICoqTWFuaGF0dGFuKiogQnJpZGdlIHRocm91Z2hvdXQgdGhlIGVudGlyZSBtb250aCBvZiBKdWx5IDIwMTcuIFRoaXMgZGF0YSBoYXMgMzEgb2JzZXJ2YXRpb25zLCBvbmUgZGV0YWlsaW5nIGVhY2ggZGF5LCBhbmQgbm8gbWlzc2luZyB2YWx1ZXMuIEEgYnJlYWtkb3duIG9mIGVhY2ggb2YgdGhlIG9yaWdpbmFsIGRhdGFzZXQncyB2YXJpYWJsZXMsIHRoZWlyIHByYWN0aWNhbCBtZWFuaW5nIGFuZCBkYXRhIHR5cGVzIGFyZSBiZWxvdy4KCmBgYHtyIFZhcmlhYmxlIFRhYmxlLCBlY2hvPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQoKVmFyX1RhYmxlID0gZGF0YS5mcmFtZSgKICBOYW1lID0gYygiRGF0ZSIsCiAgICAgICAgICAgIkRheSIsIAogICAgICAgICAgICJIaWdoVGVtcCIsIAogICAgICAgICAgICJMb3dUZW1wIiwKICAgICAgICAgICAiUHJlY2lwaXRhdGlvbiIsIAogICAgICAgICAgICJNYW5oYXR0YW4iLCAKICAgICAgICAgICAiVG90YWwiKSwKICAKICBNZWFuaW5nID0gYygiRGF0ZSBmb3IgdGhhdCBvYnNlcnZhdGlvbjsgWVlZWS1NTS1ERCBmb3JtIiwgCiAgICAgICAgICAgICAgIkRheSBvZiB0aGUgd2VlayBmb3IgdGhhdCBvYnNlcnZhdGlvbiIsCiAgICAgICAgICAgICAgIlRoYXQgZGF5J3MgaGlnaGVzdCByZWNvcmRlZCB0ZW1wZXJhdHVyZSIsIAogICAgICAgICAgICAgICJUaGF0IGRheSdzIGxvd2VzdCByZWNvcmRlZCB0ZW1wZXJhdHVyZSIsIAogICAgICAgICAgICAgICJNZWFzdXJlIG9mIHJhaW4gdGhhdCBkYXkgKGluY2hlcykiLCAgCiAgICAgICAgICAgICAgIk51bWJlciBvZiBjeWNsaXN0cyBlbnRlcmluZy9sZWF2aW5nIFF1ZWVucywgTWFuaGF0dGFuIG9yIEJyb29rbHluIHZpYSB0aGUgTUFOSEFUVEFOIEJyaWRnZSIsCiAgICAgICAgICAgICAgIlRvdGFsIG51bWJlciBvZiBjeWNsaXN0cyBlbnRlcmluZy9sZWF2aW5nIFF1ZWVucywgTWFuaGF0dGFuIG9yIEJyb29rbHluIHZpYSBBTlkgb2YgdGhlIEVhc3QgUml2ZXIgQnJpZGdlcyIpLCAKICAgICAgICAgICAgICAKICAKICBEYXRhX1R5cGUgPSBjKCJEYXRlIiwgImNoYXJhY3RlciIsICJkb3VibGUiLCAiZG91YmxlIiwgImRvdWJsZSIsICJkb3VibGUiLCAiZG91YmxlIikpCgprYWJsZShWYXJfVGFibGUpICU+JQogIGthYmxlX3N0eWxpbmcoCiAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwKICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwKICAgIHBvc2l0aW9uID0gImNlbnRlciIpCgpgYGAKIyMgT2JqZWN0aXZlIG9mIEFuYWx5c2lzCldpdGggdGhlIGF2YWlsYWJsZSBkYXRhLCBteSBnb2FsIGZvciB0aGlzIGFuYWx5c2lzIGlzIHRvIGV4YW1pbmUgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gd2VhdGhlciBjb25kaXRpb25zIGFuZCBkYXkgb2YgdGhlIHdlZWsgd2l0aCB0aGUgYW1vdW50IG9mIGN5Y2xpc3QgdHJhZmZpYyB0aGF0IHRoZSBNYW5oYXR0YW4gQnJpZGdlIGV4cGVyaWVuY2VzLiBJbiBvcmRlciB0byBkbyB0aGlzLCBJIGNyZWF0ZWQgdHdvIG5ldyB2YXJpYWJsZXMgLSBNZWFuVGVtcCBhbmQgVGVtcERpZmYgLSB3aGljaCB3ZXJlIGNhbGN1bGF0ZWQgYnkgYXZlcmFnaW5nIHRoYXQgcGFydGljdWxhciBkYXkncyBsb3cgYW5kIGhpZ2ggdGVtcGVyYXR1cmVzIGFuZCBmaW5kaW5nIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhvc2UgdGVtcGVyYXR1cmVzIHJlc3BlY3RpdmVseS4gCgpVc2luZyB0aGVzZSB0ZW1wZXJhdHVyZS1yZWxhdGVkIG1ldHJpY3MsIGFsb25nIHdpdGggbWVhc3VyZXMgb2YgcHJlY2lwaXRhdGlvbiBhbmQgcmVjb3JkcyBvZiB0aGUgZGF5IG9mIHRoZSB3ZWVrLCBJIHdpbGwgdXNlIFBvaXNzb24gcmVncmVzc2lvbiB0ZWNobmlxdWVzIHRvIHNlZSB3aGljaCBpZiBhbnkgb2YgdGhlc2UgZmFjdG9ycyBwbGF5IGEgcGFydGljdWxhciByb2xlIGluIHRoZSBvdmVyYWxsIGFtb3VudCAqb3IqIHRoZSByZWxhdGl2ZSByYXRlIG9mIGN5Y2xpc3QgdHJhZmZpYyB0aGF0IHRoZSBNYW5oYXR0YW4gQnJpZGdlIGV4cGVyaWVuY2VzLgoKYGBge3IgRGF0YSBMb2FkaW5nIGFuZCBDbGVhbmluZywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSAob3Blbnhsc3gpCm9wdGlvbnMoc2NpcGVuID0gOTk5KQoKIyByb3VuZChydW5pZigxLCBtaW4gPSAxLCBtYXggPSAxMCkpCiAgIyBVc2VkIGxpbmUgYWJvdmUgdG8gcmFuZG9tbHkgc2VsZWN0IHdoaWNoIHN1YnNldCBvZiB0aGUgZGF0YSB0byBkbyBteSBhbmFseXNpcyBvbi4gVGhlIGZpZnRoIHRhYiBvbiB0aGUgb3JpZ2luYWwgZGF0YSBFeGNlbCBzcHJlYWRzaGVldCB3YXMgZm9yIG9ic2VydmF0aW9ucyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZSBmcm9tIDcvMSB0byA3LzMxCgpEYXRhID0gcmVhZC54bHN4KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQ2hyaXNCMjMyMy9TVEEzMjEvcmVmcy9oZWFkcy9tYWluL05ZQ19DeWNsaXN0c19EYXRhLnhsc3giLCBzaGVldCA9ICJNYW5oYXR0YW4gMiIpCgpnbGltcHNlKERhdGEpCgojIENvbnZlcnRpbmcgdmFyaWFibGUgRGF0ZSB0byBhIGRhdGUgb2JqZWN0LgojIE9yaWdpbiA9IDE4OTktMTItMzAgc2luY2UgRXhjZWwgc3RvcmVzIGRhdGEgdmFsdWVzIGFzIHRoZSBudW1iZXIgb2YgZGF5cyBzaW5jZSB0aGVuLgpEYXRhJERhdGUgPSBhcy5EYXRlKERhdGEkRGF0ZSwgb3JpZ2luID0gIjE4OTktMTItMzAiKQoKIyBPcmlnaW5hbGx5IGNvbnZlcnRpbmcgdmFyaWFibGUgRGF5IHRvIGEgZGF0ZSBvYmplY3QsIHRoZW4gdXNpbmcgdGhlIHdlZWtkYXlzIGZ1bmN0aW9uIG9uIGl0LgpEYXRhJERheSA9IGFzLkRhdGUoRGF0YSREYXksIG9yaWdpbiA9ICIxODk5LTEyLTMwIikKICBEYXRhJERheSA9IHdlZWtkYXlzKGFzLkRhdGUoRGF0YSREYXkpKQoKICAjIENyZWF0aW9uIG9mIERheV9OdW0gdmFyaWFibGUKRGF0YSREYXlfTnVtW0RhdGEkRGF5ID09ICJTdW5kYXkiXSA9IDEKRGF0YSREYXlfTnVtW0RhdGEkRGF5ID09ICJNb25kYXkiXSA9IDIKRGF0YSREYXlfTnVtW0RhdGEkRGF5ID09ICJUdWVzZGF5Il0gPSAzCkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiV2VkbmVzZGF5Il0gPSA0CkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiVGh1cnNkYXkiXSA9IDUKRGF0YSREYXlfTnVtW0RhdGEkRGF5ID09ICJGcmlkYXkiXSA9IDYKRGF0YSREYXlfTnVtW0RhdGEkRGF5ID09ICJTYXR1cmRheSJdID0gNwoKICBEYXRhJE1lYW5UZW1wID0gKERhdGEkSGlnaFRlbXAgKyBEYXRhJExvd1RlbXApLzIKICBEYXRhJFRlbXBEaWZmID0gRGF0YSRIaWdoVGVtcCAtIERhdGEkTG93VGVtcAogIERhdGEkRGF5ID0gZmFjdG9yKERhdGEkRGF5LAogICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTdW5kYXkiLCAiTW9uZGF5IiwgIlR1ZXNkYXkiLCAiV2VkbmVzZGF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRodXJzZGF5IiwgIkZyaWRheSIsICJTYXR1cmRheSIpKQogICAgICAgICAgICAjIFNpbmNlIFN1bmRheSBpcyB0aGUgZmlyc3QgbGV2ZWwgb2YgdGhlIGZhY3RvciBsaXN0ZWQgaGVyZSwgaXQgd2lsbCBiZSByZWNvZ25pemVkIGFzIHRoZSBiYXNlbGluZSBieSBSCgoKIyBSZW9yZGVyIGNvbHVtbnMgZm9yIGlkZWFsIHZpc3VhbCBwZXJjZXB0aW9uCkRhdGEgPSBkYXRhLmZyYW1lKERhdGEkRGF0ZSwgRGF0YSREYXksIERhdGEkRGF5X051bSwgRGF0YSRIaWdoVGVtcCwgRGF0YSRMb3dUZW1wLCBEYXRhJE1lYW5UZW1wLCBEYXRhJFRlbXBEaWZmLCBEYXRhJFByZWNpcGl0YXRpb24sIERhdGEkTWFuaGF0dGFuLCBEYXRhJFRvdGFsKQpjb2xuYW1lcyhEYXRhKSA9IGMoIkRhdGUiLCAiRGF5IiwgIkRheV9OdW0iLCAiSGlnaFRlbXAiLCAiTG93VGVtcCIsICJNZWFuVGVtcCIsIlRlbXBEaWZmIiwgIlByZWNpcGl0YXRpb24iLCAiTWFuaGF0dGFuIiwgIlRvdGFsIikKCmdsaW1wc2UoRGF0YSkKYGBgCgojIFBvaXNzb24gUmVncmVzc2lvbiBNb2RlbGluZwpUbyBleHBsb3JlIGFueSBwb3RlbnRpYWwgYXNzb2NpYXRpb25zLCBJIGNyZWF0ZWQgUG9pc3NvbiBtb2RlbHMgb2YgdHdvIGRpZmZlcmVudCByZWdyZXNzaW9uIHR5cGVzLCBvbmUgYmVpbmcgZm9yIGNvdW50cyBhbmQgb25lIGJlaW5nIGZvciByYXRlcy4KClBvaXNzb24gY291bnRzIHJlZ3Jlc3Npb24gZXhhbWluZXMgdGhlIHRvdGFsIG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBhIHBhcnRpY3VsYXIgZXZlbnQgKGluIHRoaXMgY2FzZSBjeWNsaXN0cyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZSkgYW5kIHVzZXMgYSBsb2dhcml0aG1pYyBmdW5jdGlvbiB0byBkZXRlcm1pbmUgd2hpY2gsIGlmIGFueSBvZiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gc2FpZCByZXNwb25zZSB2YXJpYWJsZSdzIG1lYW4uIFRoZSBmb3JtdWxhIGZvciBzYWlkIHJlZ3Jlc3Npb24gaXMgYmVsb3c6CgpgYGB7ciwgZWNobz1GQUxTRX0KaW5jbHVkZV9ncmFwaGljcygiUG9pc3Nvbl9Nb2RlbF9Gb3JtLnBuZyIpCmBgYAoKLSAkXGJldGEkfjB+ID0gdGhlIGxvZyBvZiBvdXIgcmVzcG9uc2UgdmFyaWFibGUncyBtZWFuOyBub3QgdmVyeSB1c2VmdWwgZm9yIHByYWN0aWNhbCBpbnRlcnByZXRhdGlvbiAKCi0gJFxiZXRhJH4xfiwgJFxiZXRhJH4yfiwgJFxiZXRhJH4zfiwgLi4uICRcYmV0YSR+cH4gPSB0aGUgY2hhbmdlIGluIG91ciByZXNwb25zZSB2YXJpYWJsZSdzIGxvZyBtZWFuLCBpbiBhc3NvY2lhdGlvbiB3aXRoIGEgb25lIHVuaXQgaW5jcmVhc2UgaW4gc2FpZCBwcmVkaWN0b3IgdmFyaWFibGUKCiA8YnI+IAoKQWRkaXRpb25hbGx5LCBQb2lzc29uIHJhdGVzIHJlZ3Jlc3Npb24gYWltcyB0byBmaW5kIHRoZSBleHBlY3RlZCByYXRlIG9mIGEgcGFydGljdWxhciBldmVudCdzIG9jY3VycmVuY2UgcmVsYXRpdmUgdG8gdGhhdCBldmVudCdzIHByb3BvcnRpb24gd2l0aGluIGEgbGFyZ2VyICJwb3B1bGF0aW9uLiIgSW4gdGhlIGluc3RhbmNlIG9mIHRoaXMgZGF0YXNldCBhbmQgYW5hbHlzaXMsIG91ciB2YXJpYWJsZSBUb3RhbCwgd2hpY2ggcmVwcmVzZW50cyB0aGUgKip0b3RhbCoqIG51bWJlciBvZiBjeWNsaXN0cyBvbiBhbGwgdGhlIEVhc3QgUml2ZXIgQnJpZGdlcywgd2lsbCBiZSB3aGF0IHRoZSBudW1iZXIgb2YgY3ljbGlzdHMgb24gdGhlIE1hbmhhdHRhbiBCcmlkZ2UgYXJlIGNvbnNpZGVyZWQgdG8gYmUgYSBwcm9wb3J0aW9uIG9mLiBUaGUgY2FsY3VsYXRpb24gZm9yIHRoaXMgdHlwZSBvZiBQb2lzc29uIHJlZ3Jlc3Npb24gaXMgc2ltaWxhciB0byBjb3VudHMgcmVncmVzc2lvbiwgYnV0IHRoZSBsb2dhcml0aG0gb2YgdGhlIHBvcHVsYXRpb24gdmFyaWFibGUgaXMgYWxzbyBjb25zaWRlcmVkIHRvIGJlIGEgZmFjdG9yLiBUaGlzIGNhbiBiZSBleHByZXNzZWQgaW4gYm90aCBvZiB0aGUgZm9sbG93aW5nIHdheXMuCjxicj4KYGBge3IsIGVjaG89RkFMU0V9CmluY2x1ZGVfZ3JhcGhpY3MoIlBvaXNzb25fRm9ybV9SYXRlczEucG5nIikKYGBgCiA8YnI+IApgYGB7ciwgZWNobz1GQUxTRX0KaW5jbHVkZV9ncmFwaGljcygiUG9pc3Nvbl9Nb2RlbF9Gb3JtX1JhdGVzLnBuZyIpCmBgYAogPGJyPiAKIAogLSBJbiBQb2lzc29uIHJhdGVzIHJlZ3Jlc3Npb24sIHRoZSBwYXJhbWV0ZXJzICRcYmV0YSR+MH4sIC4uLi4gJFxiZXRhJH5wfiBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHRoZXkgYXJlIGluIFBvaXNzb24gY291bnRzIG1vZGVsLgoKIyMgUG9pc3NvbiBSZWdyZXNzaW9uIChDb3VudHMpCkJlbG93IGlzIGEgc3VtbWFyeSBvZiB0aGUgUG9pc3NvbiBjb3VudHMgcmVncmVzc2lvbiBtb2RlbCBJIGNyZWF0ZWQsIHdpdGggbWVhc3VyZXMgb2YgdGVtcGVyYXR1cmUgcmFuZ2UgYW5kIGF2ZXJhZ2VzLCBwcmVjaXBpdGF0aW9uIGFtb3VudCBhbmQgZGF5IG9mIHRoZSB3ZWVrIGFsbCBmdW5jdGlvbmluZyBhcyBwcmVkaWN0b3JzIG9mIGhvdyBtYW55IGN5Y2xpc3RzIGNyb3NzZWQgdGhlIE1hbmhhdHRhbiBCcmlkZ2UgaW4gb3Igb3V0IG9mIG91ciB0aHJlZSBib3JvdWdocyBvZiBpbnRlcmVzdC4KYGBge3J9CiMgQ291bnRzIE1vZGVsOgogICMgUmVzcG9uc2UgPSBNYW5oYXR0YW4KICAjIFByZWRpY3RvcnMgPSBEYXksIE1lYW5UZW1wLCBUZW1wRGlmZiwgUHJlY2lwaXRhdGlvbgogICAgIyBEYXkgaXMgc3RvcmVkIGFzIGEgRmFjdG9yCgpDb3VudHNfTW9kZWwgPSBnbG0oTWFuaGF0dGFuIH4gRGF5ICsgTWVhblRlbXAgKyBUZW1wRGlmZiArIFByZWNpcGl0YXRpb24sIGZhbWlseSA9IHBvaXNzb24obGluayA9ICJsb2ciKSwgZGF0YSA9IERhdGEpCgpDb3VudHNfTW9kZWxfU3VtID0gc3VtbWFyeShDb3VudHNfTW9kZWwpCkNvdW50c19Nb2RlbF9Db2VmID0gQ291bnRzX01vZGVsX1N1bSRjb2VmZmljaWVudHMKCmludmlzaWJsZShDb3VudHNfTW9kZWxfQ29lZikKa2FibGUoQ291bnRzX01vZGVsX0NvZWYsIGNhcHRpb24gPSAiUG9pc3NvbiBDb3VudHMgUmVncmVzc2lvbjogV2VhdGhlciBhbmQgU2NoZWR1bGUgUmVsYXRpb25zaGlwIHdpdGggQ291bnQgb2YgTWFuaGF0dGFuIEJyaWRnZSBDeWNsaXN0cyIpCgojIEFsbCBwcmVkaWN0b3IgdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudApgYGAKSW4gdGhlIG1vZGVsLCB3ZSBjYW4gc2VlIHRoYXQgKmV2ZXJ5KiBwcmVkaWN0b3IgdmFyaWFibGUgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhcyBwZXIgcCB2YWx1ZXMgd2VsbCBiZWxvdyB0aGUgc3RhbmRhcmQgb2YgMC4wNSwgc28gbm8gc3RlcHdpc2UgcmVncmVzc2lvbiBvciBtb2RlbCBzaW1wbGlmaWNhdGlvbiBpcyBuZWNlc3NhcnkuIAoKQXMgZm9yIHRoZSBwcmFjdGljYWwgaW1wbGljYXRpb25zIG9mIG91ciBtb2RlbCBzdW1tYXJ5LCB3ZSBjYW4gc2F5IHRoYXQgYWx0aG91Z2ggZXZlcnkgcHJlZGljdG9yIHZhcmlhYmxlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHRoZSBtYWduaXR1ZGUgb2YgdGhlaXIgaW1wYWN0cyBhcmUgcmVsYXRpdmVseSBzbWFsbC4gUHJlY2lwaXRhdGlvbidzIGVzdGltYXRlZCBuZWdhdGl2ZSBlZmZlY3Qgb24gdGhlIGxvZyBtZWFuIG9mIE1hbmhhdHRhbiBCcmlkZ2UgY3ljbGlzdHMgaGFzIGFuIGFic29sdXRlIHZhbHVlIH4gfC40MzA3fCwgd2hpY2ggaXMgdGhlIHRoZSBoaWdoZXN0IG9mIGFsbCBvdXIgcHJlZGljdG9ycy4KCkl0IGFwcGVhcnMgdGhhdCB0aGUgZGF5J3MgYXZlcmFnZSB0ZW1wZXJhdHVyZSBhbmQgZGlmZmVyZW5jZSBpbiBkYWlseSBoaWdocyBhbmQgbG93cyBwbGF5ZWQgdmVyeSBsaXR0bGUgcHJhY3RpY2FsIHNpZ25pZmljYW5jZSBpbiB0aGUgbG9nIG1lYW4gb2YgdGhhdCBkYXkncyBjeWNsaXN0cy4gV2hlbiB3ZSBsb29rIGF0IHRoZSBkaWZmZXJlbmNlIGluIGxvZyBtZWFucyBmcm9tIGEgZGF5LW9mLXRoZS13ZWVrIHBlcnNwZWN0aXZlLCB3ZSBkbyBzZWUgYSBzbGlnaHRseSBtb3JlIGltcGFjdGZ1bCBlZmZlY3QuIFdpdGggU3VuZGF5IGJlaW5nIGNvZGVkIGluIGFzIHRoZSBiYXNlbGluZSwgaXQgbG9va3MgbGlrZSBXZWRuZXNkYXkgaGFzIHRoZSBncmVhdGVzdCBhbW91bnQgb2YgY3ljbGlzdCB0cmFmZmljIGFuZCBTYXR1cmRheSBoYXMgdGhlIGxlYXN0LiBUaGlzIGhpZ2hlciBjb3VudCBvZiBjeWNsaXN0cyBkdXJpbmcgdGhlIHdvcmt3ZWVrIGNvdWxkIGJlIGR1ZSB0byB0aGUgTWFuaGF0dGFuIEJyaWRnZSBmdW5jdGlvbmluZyBmb3IgbWFueSBhcyBhIGNvbW11dGluZyBtZXRob2QuCgpBbGwgaW4gYWxsLCBvdXIgUG9pc3NvbiBjb3VudHMgbW9kZWwgeWllbGRzIHNvbWUgaW50ZXJlc3RpbmcgYW5kIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgcmV2ZWxhdGlvbnMsIG1vc3Qgbm90YWJseSB0aGF0IGN5Y2xpc3RzIGNhcmUgZmFyIG1vcmUgYWJvdXQgcHJlY2lwaXRhdGlvbiB0aGFuIHRoZXkgZG8gdGVtcGVyYXR1cmUgZmx1Y3R1YXRpb24sIGFuZCB0aGF0IGN5Y2xpc3QgdHJhZmZpYyBhcHBlYXJzIHRvIHRpY2sgdXB3YXJkcyB0aHJvdWdob3V0IHRoZSB3b3Jrd2VlayBiZWZvcmUgZHlpbmcgZG93biBmb3IgdGhlIHdlZWtlbmQuIEhvd2V2ZXIsIHRoZSByZWxhdGl2ZWx5IHNtYWxsIG1hZ25pdHVkZSBvZiBlYWNoIHZhcmlhYmxlJ3MgZXN0aW1hdGVkIGVmZmVjdCBpcyBhIGRvd25zaWRlIHJlZ2FyZGluZyB0aGUgbW9kZWwncyB1dGlsaXR5LiAKCiMjIFBvaXNzb24gUmVncmVzc2lvbiAoUmF0ZXMpCkFmdGVyIFBvaXNzb24gY291bnRzIHJlZ3Jlc3Npb24sIEkgdGhlbiBwZXJmb3JtZWQgUG9pc3NvbiByYXRlcyByZWdyZXNzaW9uIHdpdGggdGhlIHRvdGFsIG51bWJlciBvZiBjeWNsaXN0cyBlbnRlcmluZyBhbmQgZXhpdGluZyBvdXIgdGhyZWUgYm9yb3VnaHMgb2YgaW50ZXJlc3QgYWNyb3NzICphbGwqIHRoZSBFYXN0IFJpdmVyIEJyaWRnZXMgYXMgdGhlICJwb3B1bGF0aW9uIiBmb3Igd2hpY2ggdGhlIE1hbmhhdHRhbiBCcmlkZ2UgY3ljbGlzdHMgYXJlIGFjdGluZyBhcyBhIHNhbXBsZSBvZi4gCgpUaGlzIHByb2Nlc3MgY29uc2lzdGVkIG9mIG1lIGNyZWF0aW5nIHR3byBkaWZmZXJlbnQgUG9pc3NvbiByYXRlcyBtb2RlbHMuIFRoZSBmaXJzdCBvbmUgSSBjcmVhdGVkIGxpc3RlZCBib3RoIHRlbXBlcmF0dXJlIHZhcmlhYmxlcyBhcyBzdGF0aXN0aWNhbGx5IGluc2lnbmlmaWNhbnQuIEdpdmVuIHRoZWlyIHN0YXR1cyBhcyBzdGF0aXN0aWNhbGx5IGluc2lnbmlmaWNhbnQgaW4gdGhpcyBtb2RlbCwgYW5kIHRoZWlyIG1pbnV0ZSBwcmFjdGljYWwgc2lnbmlmaWNhbmNlIGluIHRoZSBwcmV2aW91cyBjb3VudHMgbW9kZWwsIEkgY2hvc2UgdG8gcmVtb3ZlIHRoZW0gYW5kIGNyZWF0ZSBhIHNlY29uZCBQb2lzc29uIHJhdGVzIG1vZGVsIHdoaWNoIGRpZCBub3QgZmFjdG9yIGluIHRoZSBkYXkncyBhdmVyYWdlIG9yIHJhbmdlIG9mIHRlbXBlcmF0dXJlLgpgYGB7cn0KIyMjIFJhdGVzIE1vZGVsIDEKUmF0ZXNfTW9kZWwgPSBnbG0oTWFuaGF0dGFuIH4gRGF5ICsgTWVhblRlbXAgKyBUZW1wRGlmZiArIFByZWNpcGl0YXRpb24sIG9mZnNldCA9IGxvZyhUb3RhbCksIGZhbWlseSA9IHBvaXNzb24obGluayA9ICJsb2ciKSwgZGF0YSA9IERhdGEpCgpSYXRlc19Nb2RlbF9TdW0gPSBzdW1tYXJ5KFJhdGVzX01vZGVsKQpSYXRlc19Nb2RlbF9Db2VmID0gUmF0ZXNfTW9kZWxfU3VtJGNvZWZmaWNpZW50cwoKaW52aXNpYmxlKFJhdGVzX01vZGVsX0NvZWYpCmthYmxlKFJhdGVzX01vZGVsX0NvZWYsIGNhcHRpb24gPSAiUG9pc3NvbiBSYXRlcyBSZWdyZXNzaW9uICgxKTogV2VhdGhlciBhbmQgU2NoZWR1bGUgUmVsYXRpb25zaGlwIHdpdGggQ291bnQgb2YgTWFuaGF0dGFuIEJyaWRnZSBDeWNsaXN0cyIpCgoKIyMjIFJhdGVzIE1vZGVsIDIKUmF0ZXNfTW9kZWwyID0gZ2xtKE1hbmhhdHRhbiB+IERheSArIFByZWNpcGl0YXRpb24sIG9mZnNldCA9IGxvZyhUb3RhbCksIGZhbWlseSA9IHBvaXNzb24obGluayA9ICJsb2ciKSwgZGF0YSA9IERhdGEpCgpSYXRlc19Nb2RlbDJfU3VtID0gc3VtbWFyeShSYXRlc19Nb2RlbDIpClJhdGVzX01vZGVsMl9Db2VmID0gUmF0ZXNfTW9kZWwyX1N1bSRjb2VmZmljaWVudHMKCmludmlzaWJsZShSYXRlc19Nb2RlbF9Db2VmKQprYWJsZShSYXRlc19Nb2RlbDJfQ29lZiwgY2FwdGlvbiA9ICJQb2lzc29uIFJhdGVzIFJlZ3Jlc3Npb24gKDIpOiBQcmVjaXBpdGF0aW9uIGFuZCBTY2hlZHVsZSBSZWxhdGlvbnNoaXAgd2l0aCBDb3VudCBvZiBNYW5oYXR0YW4gQnJpZGdlIEN5Y2xpc3RzIikKCmBgYApMb29raW5nIGF0IHRoZSBmaW5kaW5ncyBvZiBvdXIgc2Vjb25kIFBvaXNzb24gcmF0ZXMgcmVncmVzc2lvbiBtb2RlbCwgd2Ugc2VlIGEgdHJlbmQgc2ltaWxhciB0byB0aGF0IG9mIG91ciBQb2lzc29uIGNvdW50cyByZWdyZXNzaW9uIG1vZGVsLCB0aGF0IGJlaW5nIGEgY29tbW9uIG9jY3VycmVuY2Ugb2Ygc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIGJ1dCBub3QgYSBncmVhdCBkZWFsIG9mIHByYWN0aWNhbCBzaWduaWZpY2FuY2Ugb24gZGlzcGxheSB3aGVuIHRoZSBtYWduaXR1ZGUgb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnQgaXMgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uLgoKT25jZSBhZ2FpbiB0cmVhdGluZyBTdW5kYXkgYXMgb3VyIGJhc2VsaW5lLCBpdCBsb29rcyBsaWtlIHRoZSByYXRlIG9mIE1hbmhhdHRhbiBCcmlkZ2UgY3ljbGlzdHMgaW4gcHJvcG9ydGlvbiB0byB0aGUgZW50aXJldHkgb2YgRWFzdCBSaXZlciBCcmlkZ2UgY3ljbGlzdHMgaXMgYXQgaXRzIGhpZ2hlc3QgZWFybHkgaW4gdGhlIHdlZWssIHdpdGggdGhhdCByYXRlIGRlY2xpbmluZyBnb2luZyBpbnRvIHRoZSB3ZWVrZW5kLiBUaGF0IGJlaW5nIHNhaWQsIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhpcyBicmVha2Rvd24gYWxzbyBncmVhdGx5IGRlY3JlYXNlcyB3aGVuIHdlIGxvb2sgYXQgdGhlIGRhdGEgZm9yIFRodXJzZGF5IGFuZCB0byBhIG11Y2ggbGVzc2VyIGJ1dCBzdGlsbCBub3RpY2VhYmxlIGV4dGVudCBGcmlkYXksIHBlcmhhcHMgc3VnZ2VzdGluZyB0aGF0IHRoZSBNYW5oYXR0YW4gQnJpZGdlIGN5Y2xpc3QgcmF0ZSdzIGRlY2xpbmUgYXQgdGhlIHRhaWwgZW5kIG9mIHRoZSB3b3Jrd2VlayBjb3VsZCBiZSBjaGFsa2VkIHVwIHRvIHJhbmRvbSBjaGFuY2UgYW5kIG5vdCBhIHBhcnRpY3VsYXIgY2hhcmFjdGVyaXN0aWMgb2YgdGhlIEJyaWRnZSB0aGF0IGFmZmVjdHMgdGhlIGV4cGVyaWVuY2Ugb2YgaXRzIGN5Y2xpc3RzIG9ubHkgb24gdGhvc2UgcGFydGljdWxhciBkYXlzLgoKCiMjIERheS1CeS1EYXkgQXZlcmFnZXMKU2luY2UgYm90aCBvdXIgY291bnRzIGFuZCByYXRlcyBtb2RlbHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGRheSBvZiB0aGUgd2VlayBoYXMgdGhlIGdyZWF0ZXN0IGFzc29jaWF0aW9uIHdpdGggdGhlIGxvZyBtZWFuIG9mIHRoZSBNYW5oYXR0YW4gQnJpZGdlJ3MgY3ljbGlzdHMsIEkgZGVjaWRlZCB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgY291bnRzIGFuZCByYXRlcyBwZXIgZGF5IHRvIGNvbXBhcmUgdGhlbSB0byBlYWNoIG90aGVyIGFuZCB0aGUgbWVhbiBhY3Jvc3MgYWxsIGRheXMgY29uc2lkZXJlZC4gVGhlIHRhYmxlIHdpdGggdGhpcyBpbmZvcm1hdGlvbiBpcyBiZWxvdy4KYGBge3J9CkNvdW50X0F2ZXJhZ2VzID0gYygKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiU3VuZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJNb25kYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlR1ZXNkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIldlZG5lc2RheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiVGh1cnNkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIkZyaWRheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiU2F0dXJkYXkiXSkpCikKCkFsbERheXNfUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuKS9zdW0oRGF0YSRUb3RhbCkKClN1bl9SYXRlc19BdmcgPSBzdW0oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlN1bmRheSJdKS9zdW0oRGF0YSRUb3RhbFtEYXRhJERheSA9PSAiU3VuZGF5Il0pCgpNb25fUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJNb25kYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIk1vbmRheSJdKQoKVHVlc19SYXRlc19BdmcgPSBzdW0oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlR1ZXNkYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIlR1ZXNkYXkiXSkKCldlZF9SYXRlc19BdmcgPSBzdW0oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIldlZG5lc2RheSJdKS9zdW0oRGF0YSRUb3RhbFtEYXRhJERheSA9PSAiV2VkbmVzZGF5Il0pCgpUaHVyX1JhdGVzX0F2ZyA9IHN1bShEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiVGh1cnNkYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIlRodXJzZGF5Il0pCgpGcmlfUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJGcmlkYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIkZyaWRheSJdKQoKU2F0X1JhdGVzX0F2ZyA9IHN1bShEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiU2F0dXJkYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIlNhdHVyZGF5Il0pCgpEYXlfUmF0ZXNfQXZlcmFnZXMgPSBjKEFsbERheXNfUmF0ZXNfQXZnLCBTdW5fUmF0ZXNfQXZnLCBNb25fUmF0ZXNfQXZnLCBUdWVzX1JhdGVzX0F2ZywgV2VkX1JhdGVzX0F2ZywgVGh1cl9SYXRlc19BdmcsIEZyaV9SYXRlc19BdmcsIFNhdF9SYXRlc19BdmcpCgpSYXRlX0F2ZXJhZ2VzID0gcm91bmQoRGF5X1JhdGVzX0F2ZXJhZ2VzLCBkaWdpdHMgPSA0KQoKRGF5cyA9IGMoIkFsbCBEYXlzIiwgIlN1bmRheSIsICJNb25kYXkiLCAiVHVlc2RheSIsICJXZWRuZXNkYXkiLCAiVGh1cnNkYXkiLCAiRnJpZGF5IiwgIlNhdHVyZGF5IikKCkNvdW50c19EaWZmZXJlbmNlID0gYygKICAwLCAjIERpZmZlcmVuY2UgYmV0d2VlbiB0aGUgYXZlcmFnZSBjb3VudCBvZiBhbGwgZGF5cyBhbmQgaXRzZWxmCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiU3VuZGF5Il0pKSAtIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW4pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJNb25kYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlR1ZXNkYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIldlZG5lc2RheSJdKSkgLSByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiVGh1cnNkYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIkZyaWRheSJdKSkgLSByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiU2F0dXJkYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpCikKClJhdGVzX0RpZmZlcmVuY2VCID0gYygKICAwLAogIFN1bl9SYXRlc19BdmcgLSBBbGxEYXlzX1JhdGVzX0F2ZywKICBNb25fUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgVHVlc19SYXRlc19BdmcgLSBBbGxEYXlzX1JhdGVzX0F2ZywKICBXZWRfUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgVGh1cl9SYXRlc19BdmcgLSBBbGxEYXlzX1JhdGVzX0F2ZywKICBGcmlfUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgU2F0X1JhdGVzX0F2ZyAtIEFsbERheXNfUmF0ZXNfQXZnCikKClJhdGVzX0RpZmZlcmVuY2UgPSByb3VuZChSYXRlc19EaWZmZXJlbmNlQiwgZGlnaXRzID0gNCkKClRhYmxlID0gY2JpbmQoRGF5cywgQ291bnRfQXZlcmFnZXMsIENvdW50c19EaWZmZXJlbmNlLCBSYXRlX0F2ZXJhZ2VzLCBSYXRlc19EaWZmZXJlbmNlKQoKa2FibGUoVGFibGUsIGNhcHRpb24gPSAiRGlzdHJpYnV0aW9uIG9mIE1hbmhhdHRhbiBCcmlkZ2UgQ3ljbGlzdCBDb3VudCBhbmQgUmF0ZXMgSnVseSAyMDE3IikgJT4lCiAga2FibGVfc3R5bGluZygKICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJib3JkZXJlZCIpLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAiY2VudGVyIgogICkKYGBgCgpUaGUgdGFibGUgcHJvdmlkZXMgZ3JlYXRlciBkZXRhaWwgaW50byB0aGUgaW1wbGljYXRpb25zIG9mIG91ciBQb2lzc29uIGNvdW50IGFuZCByYXRlIG1vZGVscy4gVGhhdCBiZWluZyB3ZWVrZGF5IHRvdGFscyBvZiBNYW5oYXR0YW4gQnJpZGdlIGN5Y2xpc3RzIChzcGVjaWZpY2FsbHkgTW9uZGF5IC0gVGh1cnNkYXkpIGZhciBvdXR3ZWlnaCB0aGUgY291bnQgb2YgY3ljbGlzdHMgb24gdGhlIGJyaWRnZSBmcm9tIEZyaWRheSB0byBTdW5kYXkuIFdpdGggdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGN5bGNsaXN0cyBmcm9tIE1vbmRheSAtIFRodXJzZGF5IGJlaW5nIGFib3V0IDYsMzI1LCBhbmQgdGhlIGF2ZXJhZ2UgbnVtYmVyIEZyaWRheSAtIFN1bmRheSBiZWluZyBhYm91dCA0LDM1My4KCkFzIGZvciB0aGUgcmF0ZSBvZiBNYW5oYXR0YW4gQnJpZGdlIGN5Y2xpc3RzIHJlbGF0aXZlIHRvIGN5Y2xpc3RzIG9uIGFsbCBFYXN0IFJpdmVyIEJyaWRnZXMsIHdlIHNlZSB0aGF0IHRoZSBNYW5oYXR0YW4gQnJpZGdlJ3MgY3ljbGlzdCByYXRlIGlzIHNsaWdodGx5IGFib3ZlIGF2ZXJhZ2UgTW9uZGF5IC0gV2VkbmVzZGF5LCBidXQgdGhlbiBiZWxvdyBhdmVyYWdlIFRodXJzZGF5IHRocm91Z2ggU3VuZGF5LgoKCiMgQ29uY2x1c2lvbiBhbmQgVGFrZWF3YXlzClRvIGNvbmNsdWRlLCBhbnkgaW1wbGVtZW50YXRpb25zIGRvbmUgaW4gcmVzcG9uc2UgdG8gdGhpcyBtb2RlbCdzIGZpbmRpbmdzIHNob3VsZCBiZSBkb25lIHdpdGggY2F1dGlvbiBkdWUgdG8gdGhlIGxvdyBwcmFjdGljYWwgc2lnbmlmaWNhbmNlIGZvdW5kIGluIGJvdGggb3VyIGNvdW50IGFuZCByYXRlIFBvaXNzb24gbW9kZWxzLiBUaGF0IGJlaW5nIHNhaWQsIHRoZXJlIGFyZSBzdGlsbCB2YWx1YWJsZSB0YWtlYXdheXMgdGhhdCB3ZSBjYW4gZHJhdyBmcm9tIG91ciBhbmFseXNpcy4gCgpGaXJzdCwgdGhlIE1hbmhhdHRhbiBCcmlkZ2UgaXMgY2xlYXJseSBidXNpZXIsIGJvdGggaW4gdGhlIHNlbnNlIG9mIHJhdyB2b2x1bWUgYW5kIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgb3ZlcmFsbCBFYXN0IFJpdmVyIEJyaWRnZSBuZXR3b3JrLCBlYXJseSBhbmQgdGhyb3VnaG91dCB0aGUgc3RhbmRhcmQgd29ya3dlZWsgdGhhbiBpdCBpcyBkdXJpbmcgdGhlIHdlZWtlbmQuIFNlY29uZCwgdGhlIGRhaWx5IGF2ZXJhZ2UgdGVtcGVyYXR1cmUgYXMgd2VsbCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoYXQgZGF5J3MgaGlnaCBhbmQgbG93IHBsYXllZCB2ZXJ5IGxpdHRsZSBpZiBhbnkgcm9sZSBpbiB0aGUgY291bnQgb3IgcmF0ZSBvZiBjeWNsaXN0cyBvbiBhbnkgZ2l2ZW4gZGF5LCBidXQgdGhlIG1lYXN1cmUgb2YgcHJlY2lwaXRhdGlvbiBkb2VzIGFwcGVhciB0byBoYXZlIGEgcmVsYXRpdmVseSBub3RpY2VhYmxlIGFuZCBuZWdhdGl2ZSBhc3NvY2lhdGlvbiB3aXRoIHRoZSBudW1iZXIgb2YgdGhhdCBkYXkncyBjeWNsaXN0cyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZS4KCklmIHdlIHdlcmUgdG8gY29udGludWUgb3IgZXhwYW5kIG9uIHRoaXMgYW5hbHlzaXMgaW4gdGhlIGZ1dHVyZSwgaXQgd291bGQgYmUgdmFsdWFibGUgdG8gZXhwYW5kIHRoZSBzY29wZSBvZiBvdXIgZGF0YSBvdXRzaWRlIG9mIHRoZSBtb250aCBvZiBKdWx5IGFuZCBpbnRvIG1vbnRocyB0aGF0IGJvcmRlciBvbiBzZWFzb25hbCBjaGFuZ2VzIHN1Y2ggYXMgTWFyY2gsIEFwcmlsIG9yIE9jdG9iZXIuIEludHVpdGl2ZWx5LCBvbmUgbWlnaHQgZ3Vlc3MgdGhhdCB0aGUgZGF5J3MgdGVtcGVyYXR1cmVzIHBsYXkgYSBtdWNoIGxhcmdlciByb2xlIGluIGEgdGltZSBvZiB0aGUgeWVhciBsaWtlIHRoYXQuCgojIFJlZmVyZW5jZXM6CgpPcmlnaW5hbCBEYXRhc2V0IFNvdXJjZToKCi0gaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vU1RBMzIxL3d3MDkvdzA5LUFzc2lnbkRhdGFTZXQueGxzeAoKRGF0YXNldCBEb3dubG9hZCBMaW5rcyB2aWEgR2l0aHViOgoKLSBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQ2hyaXNCMjMyMy9TVEEzMjEvcmVmcy9oZWFkcy9tYWluL05ZQ19DeWNsaXN0c19EYXRhLnhsc3g=