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 and quasi-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 = "<b><center> Poisson Counts Regression: Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists </center></b>")
Table:
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 = "<b><center> Poisson Rates Regression (1): Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists </center></b>")
Table:
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 = "<b><center> Poisson Rates Regression (2): Precipitation and Schedule Relationship with Count of Manhattan Bridge Cyclists </center></b>")
Table:
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 of the Week 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 = "<b><center><span style='color:#000000;'>Distribution of Manhattan Bridge Cyclist Count and Rates July 2017</center></b>") %>%
  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.

2.4 Poisson Modeling Takeaways

To conclude, any implementations done in response to our Poisson models’ findings should be done with some degree of caution due to the low practical significance found in both our count and rate 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.

3 Quasi-Poisson Regression Modeling

In addition to analyzing our data at hand via Poisson regression, I decided to also create a quasi-Poisson model of the data. Quasi-Poisson modeling is an alternative to Poisson modeling, and it is particularly valuable when the mean and variance of the model’s response variable (number of cyclists on the Manhattan bridge in this case) are not approximately equal to one another (known as dispersion).

For my quasi-Poisson model, I included that day’s average temperature, day of the week and precipitation amount as the relevant factors. Day of the week obviously played the biggest role in our previous Poisson models, with precipitation consistently being cited as statistically significant despite relatively low practical significance. For this model, I chose to discretize precipitation, with days of no recorded rain being marked as “0” and days with any amount of rain being marked as “1.”

Data$NewPrecip = Data$Precipitation
Data$NewPrecip[Data$Precipitation == 0] = 0
Data$NewPrecip[Data$Precipitation > 0] = 1

Data = data.frame(Data$Date, Data$Day, Data$Day_Num, Data$HighTemp, Data$LowTemp, Data$MeanTemp, Data$TempDiff, Data$Precipitation, Data$NewPrecip, Data$Manhattan, Data$Total)
colnames(Data) = c("Date", "Day", "Day_Num", "HighTemp", "LowTemp", "MeanTemp","TempDiff", "Precipitation", "NewPrecip","Manhattan", "Total")


# 1.) Below is the quasi-Poisson regression model
  # As instructed, only includes Day, MeanTemp and NewPrecip

Quasi_Counts_Model = glm(Manhattan ~ Day + MeanTemp + NewPrecip, family = quasipoisson, data = Data)
  
Quasi_Counts_Model_Sum = summary(Quasi_Counts_Model)
Quasi_Counts_Model_Coef = Quasi_Counts_Model_Sum$coefficients

invisible(Quasi_Counts_Model_Coef)
kable(Quasi_Counts_Model_Coef, caption = "<b><center> Quasi-Poisson Counts Regression: Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists </center></b>")
Table:
Quasi-Poisson Counts Regression: Weather and Schedule Relationship with Count of Manhattan Bridge Cyclists

Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.0428119 0.5287239 15.2117416 0.0000000
DayMonday 0.3201598 0.1180432 2.7122270 0.0127244
DayTuesday 0.2356884 0.1223379 1.9265366 0.0670535
DayWednesday 0.3064451 0.1211249 2.5299920 0.0190731
DayThursday 0.2542985 0.1240203 2.0504581 0.0524206
DayFriday 0.0302193 0.1365853 0.2212482 0.8269398
DaySaturday -0.0805066 0.1301538 -0.6185500 0.5425648
MeanTemp 0.0062851 0.0068223 0.9212583 0.3669084
NewPrecip -0.4057049 0.0921307 -4.4035809 0.0002251

A summary of the quasi-Poisson counts model can be seen above. We can see that there is great similarity between the findings of this model and our original Poisson counts model. However before we can determine which one is superior for interpretative use, we must calculate this quasi-Poisson’s dispersion parameter, “phi hat” (\(\hat{\phi}\)).

3.1 Dispersion and Counts Model Selection

\(\hat{\phi}\) is used in quasi-Poisson regression to determine if our data’s response variable is overly or underly dispersed. Generally, a phi hat value of around 1 is representative of an approximately equal mean and variance of the response. If a quasi-Poisson model’s dispersion value is significantly different than 1, then that model should be used for associative analysis rather than a traditional Poisson counterpart, as the quasi-Poisson calculation includes greater estimation of standard errors. However, if \(\hat{\phi}\) ~ 1, then the traditional Poisson model should be used, as it is less computationally intensive and avoids otherwise unnecessary extra steps. The formula for \(\hat{\phi}\)’s calculation can be seen below.

n = nrow(Data)
p = 3
Pearson_Residuals = residuals(Quasi_Counts_Model, type = "pearson")
Sq_Pearson_Residuals = Pearson_Residuals^2
Dispersion_Parameter = (sum(Sq_Pearson_Residuals))/(n-p)

#### Double checked phi's value using Prof's coding method; got same result
  ydif=Data$Manhattan-exp(Quasi_Counts_Model$linear.predictors)  # diff between y and yhat
  prsd = ydif/sqrt(exp(Quasi_Counts_Model$linear.predictors))   # Pearson residuals
  phi_check = sum(prsd^2)/(n-p)
#### 
  
invisible(Dispersion_Parameter)
invisible(phi_check)

Our model yielded a value of \(\hat{\phi}\) ~ 142, which is well beyond the margin of error for a properly dispersed Poisson response variable. For this reason, we can deem that the quasi-Poisson counts model is more valuable for associative analysis than the Poisson counts model. Because of this, we will use the quasi-Poisson for our ultimate interpretations.

3.2 Visual Aids

Referring to our quasi-Poisson model summary above, we see that the day’s average temperature does not appear to have significant statistical or practical association with the Manhattan bridge’s number of cyclists. However, there does appear to be such a difference between the number of cyclists on a totally clear day as opposed to a day with at least some level of precipitation (recorded via variable NewPrecip). And, as consistently seen in our original Poisson regression models, there is certainly a large difference between the typical number of cyclists depending on the day of the week.

Knowing this, I created two visuals below to enhance our grasp of the relationship that both the day of the week and the presence of precipitation have with each other as well as the standard number of cyclists that were on the Manhattan Bridge throughout July 2017. Unfortunately, there were no instances of Tuesdays or Wednesdays with precipitation in this study, resulting in a blank in both our table and bar chart below.

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

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

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

Vis_Table = data.frame(Days, No_Precipitation, Some_Precipitation)

kable(Vis_Table, caption = "<b><center><span style='color:#000000;'>Average Cyclist Counts on the Manhattan Bridge July 2017</center></b>") %>%
  kable_styling(
    bootstrap_options = c("striped", "bordered"),
    full_width = FALSE,
    position = "center")
Average Cyclist Counts on the Manhattan Bridge July 2017
Days No_Precipitation Some_Precipitation
All Days 6008 3746
Sunday 4924 3756
Monday 7408 3892
Tuesday 6363 NaN
Wednesday 6938 NaN
Thursday 6006 5980
Friday 5802 2874
Saturday 4484 3352
#### Barchart
Vis_long =
  Vis_Table %>%
  pivot_longer(
    cols = c(No_Precipitation, Some_Precipitation),
    names_to = "Precipitation",
    values_to = "Manhattan"
  )

Vis_long$Days = factor(
  Vis_long$Days,
  levels = c("All Days", "Sunday", "Monday", "Tuesday", "Wednesday",
             "Thursday", "Friday", "Saturday")
)
ggplot(Vis_long,
       aes(x = Days, y = Manhattan, fill = Precipitation)) +
  geom_bar(stat = "identity",
           position = position_dodge(width = 0.9),
           na.rm = TRUE) +
  labs(
    title = "Average Cyclist Counts on the Manhattan Bridge July 2017",
    x = "Day of the Week",
    y = "Number of Cyclists",
    fill = "Precipitation"
  ) +
  scale_fill_manual(
    values = c("No_Precipitation" = "darkred",
               "Some_Precipitation"    = "lightblue")
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank()
  )

The depictions above provide added clarity to the summary statistics from our quasi-Poisson model. Sunday was the baseline for our regression model’s calculations, and all remaining days other than Saturday had positive coefficients. We can see in both our chart and table, that the count of cyclists is certainly higher throughout the week than it is on the weekends. As for the role of precipitation; our discretized variable NewPrecip had a regression coefficent of ~ 0.4 (the highest absolute value of any factor in the model) and a significant p value ~ .0002. That finding can be intuitively confirmed by taking a glance at our visuals. Other than Thursday, all other days for which there are data points for both precipitation and no precipitation show a noticeable decrease in cyclists when there is a presence of precipitation.

4 Conclusion

Through our analysis via the means of both Poisson and quasi-Poisson modeling techniques, our findings were relatively consistent. Those being the following;

  • The Manhattan Bridge is far busier during the week than it is on the weekend.
  • At least in the month of July, the temperature does not play any sort of significant role in the raw number of the bridge’s cyclists nor its share of the totality of East River Bridge cyclists.
  • Although temperature is not significantly associated with cyclist traffic, precipitation is. Any amount of precipitation has a negative and statistically significant relationship with Manhattan Bridge’s cyclist traffic.

Regarding the existence of both our Poisson and quasi-Poisson models to estimate the association between all these factors, the quasi-Poisson is more ideal due to this dataset’s extremely high dispersion parameter (\(\hat{\phi}\) ~ 142).

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.

LS0tCnRpdGxlOiAiUG9pc3NvbiBhbmQgUXVhc2ktUG9pc3NvbiBBbmFseXNpcyBvZiBSZWxhdGlvbnNoaXAgYmV0d2VlbiBXZWF0aGVyIGFuZCBEYXkgb2YgV2VlayB3aXRoIEN5Y2xpc3QgVHJhZmZpYyBvbiBNYW5oYXR0YW4gQnJpZGdlIgphdXRob3I6ICJDaHJpcyBCYWhtIgpkYXRlOiAiMjAyNS0xMS0xMCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgZmlnX3dpZHRoOiA2CiAgICBmaWdfaGVpZ2h0OiA0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBsdW1lbgogICAgaGlnaGxpZ2h0OiB0YW5nbwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiA0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgd29yZF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiA0Ci0tLQoKYGBge2NzcywgZWNobyA9IEZBTFNFfQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQoKaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8KICBmb250LXNpemU6IDI0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIwcHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTRweDsKICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsKICBjb250ZW50OiAiLiI7Cn0KYGBgCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IAojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4KCmlmICghcmVxdWlyZSgia25pdHIiKSkgeyAgICAgICAgICAgICAgICAgICAgICAjIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgdG8gZGV0ZWN0CiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikgICAgICAgICAgICAgICAgICAjIHdoZXRoZXIgYSBwYWNrYWdlIHdhcyBpbnN0YWxsZWQgaW4KICAgbGlicmFyeShrbml0cikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91ciBtYWNoaW5lLiBJZiBub3QsIGluc3RhbGwgaXQgYW5kCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGxvYWQgaXQgdG8gdGhlIHdvcmtpbmcgZGlyZWN0b3J5LgoKaWYgKCFyZXF1aXJlKHRpZHl2ZXJzZSkpIHtsaWJyYXJ5KHRpZHl2c2Vyc2UpfSAKCmlmICghcmVxdWlyZShHR2FsbHkpKSB7bGlicmFyeShHR2FsbHkpfSAKCmlmICghcmVxdWlyZShrYWJsZUV4dHJhKSkge2xpYnJhcnkoa2FibGVFeHRyYSl9IAoKaWYgKCFyZXF1aXJlKGdncGxvdDIpKSB7bGlicmFyeShnZ3Bsb3QyKX0gCgppZiAoIXJlcXVpcmUoY2FyKSkge2xpYnJhcnkoY2FyKX0gCgppZiAoIXJlcXVpcmUoZHBseXIpKSB7bGlicmFyeShkcGx5cil9IAoKaWYgKCFyZXF1aXJlKHBhbmRlcikpIHtsaWJyYXJ5KHBhbmRlcil9IAoKaWYgKCFyZXF1aXJlKGNhcikpIHtsaWJyYXJ5KGNhcil9IAoKaWYgKCFyZXF1aXJlKCJzY2FsZXMiKSkgewppbnN0YWxsLnBhY2thZ2VzKCJzY2FsZXMiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKbGlicmFyeSgic2NhbGVzIikgCn0KCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKCWVjaG8gPSBUUlVFLAoJbWVzc2FnZSA9IEZBTFNFLAoJd2FybmluZyA9IEZBTFNFLAoJY29tbWVudCA9IE5BLAoJcmVzdWx0cyA9IFRSVUUKKQoKYGBgCgojIEludHJvZHVjdGlvbiBhbmQgQmFja2dyb3VuZCAKSGVyZSB3ZSBoYXZlIGEgZGF0YXNldCBzb3VyY2VkIGZyb20gTmV3IFlvcmsgQ2l0eSdzIFRyYWZmaWMgSW5mb3JtYXRpb24gTWFuYWdlbWVudCBTeXN0ZW0gKFRJTVMpLiBUSU1TIHJlY29yZGVkIHRoZSBudW1iZXIgb2YgY3ljbGlzdHMgZW50ZXJpbmcgYW5kIGxlYXZpbmcgdGhyZWUgb2YgTmV3IFlvcmsgQ2l0eSdzIGZpdmUgYm9yb3VnaHMgLSBRdWVlbnMsIE1hbmhhdHRhbiBhbmQgQnJvb2tseW4gLSB2aWEgYSBjb2xsZWN0aW9uIG9mIGJyaWRnZXMga25vd24gYXMgdGhlIEVhc3QgUml2ZXIgQnJpZGdlcyAoQnJvb2tseW4gQnJpZGdlLCBNYW5oYXR0YW4gQnJpZGdlLCBXaWxsaWFtc2J1cmcgQnJpZGdlLCBhbmQgUXVlZW5zYm9ybyBCcmlkZ2UpLiBUaGVzZSByZWNvcmRpbmdzIHRvb2sgcGxhY2UgaW4gMjAxNy4gQXByaWwsIEp1bHkgYW5kIE9jdG9iZXIgYXJlIHRoZSB0aHJlZSBtb250aHMgdGhhdCBhcmUgcHJlc2VudCBpbiBvdXIgYXZhaWxhYmxlIGNvcHkgb2YgdGhlIGRhdGEuCgpGb3IgdG9kYXkncyBhbmFseXNpcyB3ZSBhcmUgZ29pbmcgdG8gbG9vayBhdCBhIHJhbmRvbWx5IHNlbGVjdGVkIHN1YnNldCBvZiB0aGUgbGFyZ2VyIGRhdGFzZXQgKHN1YnNldCB3YXMgY2hvc2VuIHVzaW5nIFIncyBydW5pZiBmdW5jdGlvbiksIHRoYXQgcGVydGFpbnMgdG8gY3ljbGlzdHMgd2hvIGVudGVyZWQgYW5kIGxlZnQgb3VyIHRocmVlIGJvcm91Z2hzIG9mIGludGVyZXN0IC0gUXVlZW5zLCBNYW5oYXR0YW4gYW5kIEJyb29rbHluIC0gdmlhIHRoZSAqKk1hbmhhdHRhbioqIEJyaWRnZSB0aHJvdWdob3V0IHRoZSBlbnRpcmUgbW9udGggb2YgSnVseSAyMDE3LiBUaGlzIGRhdGEgaGFzIDMxIG9ic2VydmF0aW9ucywgb25lIGRldGFpbGluZyBlYWNoIGRheSwgYW5kIG5vIG1pc3NpbmcgdmFsdWVzLiBBIGJyZWFrZG93biBvZiBlYWNoIG9mIHRoZSBvcmlnaW5hbCBkYXRhc2V0J3MgdmFyaWFibGVzLCB0aGVpciBwcmFjdGljYWwgbWVhbmluZyBhbmQgZGF0YSB0eXBlcyBhcmUgYmVsb3cuCgpgYGB7ciBWYXJpYWJsZSBUYWJsZSwgZWNobz1GQUxTRX0KbGlicmFyeShrbml0cikKClZhcl9UYWJsZSA9IGRhdGEuZnJhbWUoCiAgTmFtZSA9IGMoIkRhdGUiLAogICAgICAgICAgICJEYXkiLCAKICAgICAgICAgICAiSGlnaFRlbXAiLCAKICAgICAgICAgICAiTG93VGVtcCIsCiAgICAgICAgICAgIlByZWNpcGl0YXRpb24iLCAKICAgICAgICAgICAiTWFuaGF0dGFuIiwgCiAgICAgICAgICAgIlRvdGFsIiksCiAgCiAgTWVhbmluZyA9IGMoIkRhdGUgZm9yIHRoYXQgb2JzZXJ2YXRpb247IFlZWVktTU0tREQgZm9ybSIsIAogICAgICAgICAgICAgICJEYXkgb2YgdGhlIHdlZWsgZm9yIHRoYXQgb2JzZXJ2YXRpb24iLAogICAgICAgICAgICAgICJUaGF0IGRheSdzIGhpZ2hlc3QgcmVjb3JkZWQgdGVtcGVyYXR1cmUiLCAKICAgICAgICAgICAgICAiVGhhdCBkYXkncyBsb3dlc3QgcmVjb3JkZWQgdGVtcGVyYXR1cmUiLCAKICAgICAgICAgICAgICAiTWVhc3VyZSBvZiByYWluIHRoYXQgZGF5IChpbmNoZXMpIiwgIAogICAgICAgICAgICAgICJOdW1iZXIgb2YgY3ljbGlzdHMgZW50ZXJpbmcvbGVhdmluZyBRdWVlbnMsIE1hbmhhdHRhbiBvciBCcm9va2x5biB2aWEgdGhlIE1BTkhBVFRBTiBCcmlkZ2UiLAogICAgICAgICAgICAgICJUb3RhbCBudW1iZXIgb2YgY3ljbGlzdHMgZW50ZXJpbmcvbGVhdmluZyBRdWVlbnMsIE1hbmhhdHRhbiBvciBCcm9va2x5biB2aWEgQU5ZIG9mIHRoZSBFYXN0IFJpdmVyIEJyaWRnZXMiKSwgCiAgICAgICAgICAgICAgCiAgCiAgRGF0YV9UeXBlID0gYygiRGF0ZSIsICJjaGFyYWN0ZXIiLCAiZG91YmxlIiwgImRvdWJsZSIsICJkb3VibGUiLCAiZG91YmxlIiwgImRvdWJsZSIpKQoKa2FibGUoVmFyX1RhYmxlKSAlPiUKICBrYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImJvcmRlcmVkIiksCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJjZW50ZXIiKQoKYGBgCiMjIE9iamVjdGl2ZSBvZiBBbmFseXNpcwpXaXRoIHRoZSBhdmFpbGFibGUgZGF0YSwgbXkgZ29hbCBmb3IgdGhpcyBhbmFseXNpcyBpcyB0byBleGFtaW5lIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHdlYXRoZXIgY29uZGl0aW9ucyBhbmQgZGF5IG9mIHRoZSB3ZWVrIHdpdGggdGhlIGFtb3VudCBvZiBjeWNsaXN0IHRyYWZmaWMgdGhhdCB0aGUgTWFuaGF0dGFuIEJyaWRnZSBleHBlcmllbmNlcy4gSW4gb3JkZXIgdG8gZG8gdGhpcywgSSBjcmVhdGVkIHR3byBuZXcgdmFyaWFibGVzIC0gTWVhblRlbXAgYW5kIFRlbXBEaWZmIC0gd2hpY2ggd2VyZSBjYWxjdWxhdGVkIGJ5IGF2ZXJhZ2luZyB0aGF0IHBhcnRpY3VsYXIgZGF5J3MgbG93IGFuZCBoaWdoIHRlbXBlcmF0dXJlcyBhbmQgZmluZGluZyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRob3NlIHRlbXBlcmF0dXJlcyByZXNwZWN0aXZlbHkuIAoKVXNpbmcgdGhlc2UgdGVtcGVyYXR1cmUtcmVsYXRlZCBtZXRyaWNzLCBhbG9uZyB3aXRoIG1lYXN1cmVzIG9mIHByZWNpcGl0YXRpb24gYW5kIHJlY29yZHMgb2YgdGhlIGRheSBvZiB0aGUgd2VlaywgSSB3aWxsIHVzZSBQb2lzc29uIGFuZCBxdWFzaS1Qb2lzc29uIHJlZ3Jlc3Npb24gdGVjaG5pcXVlcyB0byBzZWUgd2hpY2ggaWYgYW55IG9mIHRoZXNlIGZhY3RvcnMgcGxheSBhIHBhcnRpY3VsYXIgcm9sZSBpbiB0aGUgb3ZlcmFsbCBhbW91bnQgKm9yKiB0aGUgcmVsYXRpdmUgcmF0ZSBvZiBjeWNsaXN0IHRyYWZmaWMgdGhhdCB0aGUgTWFuaGF0dGFuIEJyaWRnZSBleHBlcmllbmNlcy4KCmBgYHtyIERhdGEgTG9hZGluZyBhbmQgQ2xlYW5pbmcsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkgKG9wZW54bHN4KQpvcHRpb25zKHNjaXBlbiA9IDk5OSkKCiMgcm91bmQocnVuaWYoMSwgbWluID0gMSwgbWF4ID0gMTApKQogICMgVXNlZCBsaW5lIGFib3ZlIHRvIHJhbmRvbWx5IHNlbGVjdCB3aGljaCBzdWJzZXQgb2YgdGhlIGRhdGEgdG8gZG8gbXkgYW5hbHlzaXMgb24uIFRoZSBmaWZ0aCB0YWIgb24gdGhlIG9yaWdpbmFsIGRhdGEgRXhjZWwgc3ByZWFkc2hlZXQgd2FzIGZvciBvYnNlcnZhdGlvbnMgb24gdGhlIE1hbmhhdHRhbiBCcmlkZ2UgZnJvbSA3LzEgdG8gNy8zMQoKRGF0YSA9IHJlYWQueGxzeCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NocmlzQjIzMjMvU1RBMzIxL3JlZnMvaGVhZHMvbWFpbi9OWUNfQ3ljbGlzdHNfRGF0YS54bHN4Iiwgc2hlZXQgPSAiTWFuaGF0dGFuIDIiKQoKZ2xpbXBzZShEYXRhKQoKIyBDb252ZXJ0aW5nIHZhcmlhYmxlIERhdGUgdG8gYSBkYXRlIG9iamVjdC4KIyBPcmlnaW4gPSAxODk5LTEyLTMwIHNpbmNlIEV4Y2VsIHN0b3JlcyBkYXRhIHZhbHVlcyBhcyB0aGUgbnVtYmVyIG9mIGRheXMgc2luY2UgdGhlbi4KRGF0YSREYXRlID0gYXMuRGF0ZShEYXRhJERhdGUsIG9yaWdpbiA9ICIxODk5LTEyLTMwIikKCiMgT3JpZ2luYWxseSBjb252ZXJ0aW5nIHZhcmlhYmxlIERheSB0byBhIGRhdGUgb2JqZWN0LCB0aGVuIHVzaW5nIHRoZSB3ZWVrZGF5cyBmdW5jdGlvbiBvbiBpdC4KRGF0YSREYXkgPSBhcy5EYXRlKERhdGEkRGF5LCBvcmlnaW4gPSAiMTg5OS0xMi0zMCIpCiAgRGF0YSREYXkgPSB3ZWVrZGF5cyhhcy5EYXRlKERhdGEkRGF5KSkKCiAgIyBDcmVhdGlvbiBvZiBEYXlfTnVtIHZhcmlhYmxlCkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiU3VuZGF5Il0gPSAxCkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiTW9uZGF5Il0gPSAyCkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiVHVlc2RheSJdID0gMwpEYXRhJERheV9OdW1bRGF0YSREYXkgPT0gIldlZG5lc2RheSJdID0gNApEYXRhJERheV9OdW1bRGF0YSREYXkgPT0gIlRodXJzZGF5Il0gPSA1CkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiRnJpZGF5Il0gPSA2CkRhdGEkRGF5X051bVtEYXRhJERheSA9PSAiU2F0dXJkYXkiXSA9IDcKCiAgRGF0YSRNZWFuVGVtcCA9IChEYXRhJEhpZ2hUZW1wICsgRGF0YSRMb3dUZW1wKS8yCiAgRGF0YSRUZW1wRGlmZiA9IERhdGEkSGlnaFRlbXAgLSBEYXRhJExvd1RlbXAKICBEYXRhJERheSA9IGZhY3RvcihEYXRhJERheSwKICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiU3VuZGF5IiwgIk1vbmRheSIsICJUdWVzZGF5IiwgIldlZG5lc2RheSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaHVyc2RheSIsICJGcmlkYXkiLCAiU2F0dXJkYXkiKSkKICAgICAgICAgICAgIyBTaW5jZSBTdW5kYXkgaXMgdGhlIGZpcnN0IGxldmVsIG9mIHRoZSBmYWN0b3IgbGlzdGVkIGhlcmUsIGl0IHdpbGwgYmUgcmVjb2duaXplZCBhcyB0aGUgYmFzZWxpbmUgYnkgUgoKIyBSZW9yZGVyIGNvbHVtbnMgZm9yIGlkZWFsIHZpc3VhbCBwZXJjZXB0aW9uCkRhdGEgPSBkYXRhLmZyYW1lKERhdGEkRGF0ZSwgRGF0YSREYXksIERhdGEkRGF5X051bSwgRGF0YSRIaWdoVGVtcCwgRGF0YSRMb3dUZW1wLCBEYXRhJE1lYW5UZW1wLCBEYXRhJFRlbXBEaWZmLCBEYXRhJFByZWNpcGl0YXRpb24sIERhdGEkTWFuaGF0dGFuLCBEYXRhJFRvdGFsKQpjb2xuYW1lcyhEYXRhKSA9IGMoIkRhdGUiLCAiRGF5IiwgIkRheV9OdW0iLCAiSGlnaFRlbXAiLCAiTG93VGVtcCIsICJNZWFuVGVtcCIsIlRlbXBEaWZmIiwgIlByZWNpcGl0YXRpb24iLCAiTWFuaGF0dGFuIiwgIlRvdGFsIikKCmdsaW1wc2UoRGF0YSkKYGBgCgojIFBvaXNzb24gUmVncmVzc2lvbiBNb2RlbGluZwpUbyBleHBsb3JlIGFueSBwb3RlbnRpYWwgYXNzb2NpYXRpb25zLCBJIGNyZWF0ZWQgUG9pc3NvbiBtb2RlbHMgb2YgdHdvIGRpZmZlcmVudCByZWdyZXNzaW9uIHR5cGVzLCBvbmUgYmVpbmcgZm9yIGNvdW50cyBhbmQgb25lIGJlaW5nIGZvciByYXRlcy4KClBvaXNzb24gY291bnRzIHJlZ3Jlc3Npb24gZXhhbWluZXMgdGhlIHRvdGFsIG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBhIHBhcnRpY3VsYXIgZXZlbnQgKGluIHRoaXMgY2FzZSBjeWNsaXN0cyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZSkgYW5kIHVzZXMgYSBsb2dhcml0aG1pYyBmdW5jdGlvbiB0byBkZXRlcm1pbmUgd2hpY2gsIGlmIGFueSBvZiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gc2FpZCByZXNwb25zZSB2YXJpYWJsZSdzIG1lYW4uIFRoZSBmb3JtdWxhIGZvciBzYWlkIHJlZ3Jlc3Npb24gaXMgYmVsb3c6CgpgYGB7ciwgZWNobz1GQUxTRX0KaW5jbHVkZV9ncmFwaGljcygiUG9pc3Nvbl9Nb2RlbF9Gb3JtLnBuZyIpCmBgYAoKLSAkXGJldGEkfjB+ID0gdGhlIGxvZyBvZiBvdXIgcmVzcG9uc2UgdmFyaWFibGUncyBtZWFuOyBub3QgdmVyeSB1c2VmdWwgZm9yIHByYWN0aWNhbCBpbnRlcnByZXRhdGlvbiAKCi0gJFxiZXRhJH4xfiwgJFxiZXRhJH4yfiwgJFxiZXRhJH4zfiwgLi4uICRcYmV0YSR+cH4gPSB0aGUgY2hhbmdlIGluIG91ciByZXNwb25zZSB2YXJpYWJsZSdzIGxvZyBtZWFuLCBpbiBhc3NvY2lhdGlvbiB3aXRoIGEgb25lIHVuaXQgaW5jcmVhc2UgaW4gc2FpZCBwcmVkaWN0b3IgdmFyaWFibGUKCiA8YnI+IAoKQWRkaXRpb25hbGx5LCBQb2lzc29uIHJhdGVzIHJlZ3Jlc3Npb24gYWltcyB0byBmaW5kIHRoZSBleHBlY3RlZCByYXRlIG9mIGEgcGFydGljdWxhciBldmVudCdzIG9jY3VycmVuY2UgcmVsYXRpdmUgdG8gdGhhdCBldmVudCdzIHByb3BvcnRpb24gd2l0aGluIGEgbGFyZ2VyICJwb3B1bGF0aW9uLiIgSW4gdGhlIGluc3RhbmNlIG9mIHRoaXMgZGF0YXNldCBhbmQgYW5hbHlzaXMsIG91ciB2YXJpYWJsZSBUb3RhbCwgd2hpY2ggcmVwcmVzZW50cyB0aGUgKip0b3RhbCoqIG51bWJlciBvZiBjeWNsaXN0cyBvbiBhbGwgdGhlIEVhc3QgUml2ZXIgQnJpZGdlcywgd2lsbCBiZSB3aGF0IHRoZSBudW1iZXIgb2YgY3ljbGlzdHMgb24gdGhlIE1hbmhhdHRhbiBCcmlkZ2UgYXJlIGNvbnNpZGVyZWQgdG8gYmUgYSBwcm9wb3J0aW9uIG9mLiBUaGUgY2FsY3VsYXRpb24gZm9yIHRoaXMgdHlwZSBvZiBQb2lzc29uIHJlZ3Jlc3Npb24gaXMgc2ltaWxhciB0byBjb3VudHMgcmVncmVzc2lvbiwgYnV0IHRoZSBsb2dhcml0aG0gb2YgdGhlIHBvcHVsYXRpb24gdmFyaWFibGUgaXMgYWxzbyBjb25zaWRlcmVkIHRvIGJlIGEgZmFjdG9yLiBUaGlzIGNhbiBiZSBleHByZXNzZWQgaW4gYm90aCBvZiB0aGUgZm9sbG93aW5nIHdheXMuCjxicj4KYGBge3IsIGVjaG89RkFMU0V9CmluY2x1ZGVfZ3JhcGhpY3MoIlBvaXNzb25fRm9ybV9SYXRlczEucG5nIikKYGBgCiA8YnI+IApgYGB7ciwgZWNobz1GQUxTRX0KaW5jbHVkZV9ncmFwaGljcygiUG9pc3Nvbl9Nb2RlbF9Gb3JtX1JhdGVzLnBuZyIpCmBgYAogPGJyPiAKIAogLSBJbiBQb2lzc29uIHJhdGVzIHJlZ3Jlc3Npb24sIHRoZSBwYXJhbWV0ZXJzICRcYmV0YSR+MH4sIC4uLi4gJFxiZXRhJH5wfiBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHRoZXkgYXJlIGluIFBvaXNzb24gY291bnRzIG1vZGVsLgoKIyMgUG9pc3NvbiBSZWdyZXNzaW9uIChDb3VudHMpCkJlbG93IGlzIGEgc3VtbWFyeSBvZiB0aGUgUG9pc3NvbiBjb3VudHMgcmVncmVzc2lvbiBtb2RlbCBJIGNyZWF0ZWQsIHdpdGggbWVhc3VyZXMgb2YgdGVtcGVyYXR1cmUgcmFuZ2UgYW5kIGF2ZXJhZ2VzLCBwcmVjaXBpdGF0aW9uIGFtb3VudCBhbmQgZGF5IG9mIHRoZSB3ZWVrIGFsbCBmdW5jdGlvbmluZyBhcyBwcmVkaWN0b3JzIG9mIGhvdyBtYW55IGN5Y2xpc3RzIGNyb3NzZWQgdGhlIE1hbmhhdHRhbiBCcmlkZ2UgaW4gb3Igb3V0IG9mIG91ciB0aHJlZSBib3JvdWdocyBvZiBpbnRlcmVzdC4KYGBge3J9CiMgQ291bnRzIE1vZGVsOgogICMgUmVzcG9uc2UgPSBNYW5oYXR0YW4KICAjIFByZWRpY3RvcnMgPSBEYXksIE1lYW5UZW1wLCBUZW1wRGlmZiwgUHJlY2lwaXRhdGlvbgogICAgIyBEYXkgaXMgc3RvcmVkIGFzIGEgRmFjdG9yCgpDb3VudHNfTW9kZWwgPSBnbG0oTWFuaGF0dGFuIH4gRGF5ICsgTWVhblRlbXAgKyBUZW1wRGlmZiArIFByZWNpcGl0YXRpb24sIGZhbWlseSA9IHBvaXNzb24obGluayA9ICJsb2ciKSwgZGF0YSA9IERhdGEpCgpDb3VudHNfTW9kZWxfU3VtID0gc3VtbWFyeShDb3VudHNfTW9kZWwpCkNvdW50c19Nb2RlbF9Db2VmID0gQ291bnRzX01vZGVsX1N1bSRjb2VmZmljaWVudHMKCmludmlzaWJsZShDb3VudHNfTW9kZWxfQ29lZikKa2FibGUoQ291bnRzX01vZGVsX0NvZWYsIGNhcHRpb24gPSAiPGI+PGNlbnRlcj4gUG9pc3NvbiBDb3VudHMgUmVncmVzc2lvbjogV2VhdGhlciBhbmQgU2NoZWR1bGUgUmVsYXRpb25zaGlwIHdpdGggQ291bnQgb2YgTWFuaGF0dGFuIEJyaWRnZSBDeWNsaXN0cyA8L2NlbnRlcj48L2I+IikKCiMgQWxsIHByZWRpY3RvciB2YXJpYWJsZXMgYXJlIHNpZ25pZmljYW50CmBgYApJbiB0aGUgbW9kZWwsIHdlIGNhbiBzZWUgdGhhdCAqZXZlcnkqIHByZWRpY3RvciB2YXJpYWJsZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFzIHBlciBwIHZhbHVlcyB3ZWxsIGJlbG93IHRoZSBzdGFuZGFyZCBvZiAwLjA1LCBzbyBubyBzdGVwd2lzZSByZWdyZXNzaW9uIG9yIG1vZGVsIHNpbXBsaWZpY2F0aW9uIGlzIG5lY2Vzc2FyeS4gCgpBcyBmb3IgdGhlIHByYWN0aWNhbCBpbXBsaWNhdGlvbnMgb2Ygb3VyIG1vZGVsIHN1bW1hcnksIHdlIGNhbiBzYXkgdGhhdCBhbHRob3VnaCBldmVyeSBwcmVkaWN0b3IgdmFyaWFibGUgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgdGhlIG1hZ25pdHVkZSBvZiB0aGVpciBpbXBhY3RzIGFyZSByZWxhdGl2ZWx5IHNtYWxsLiBQcmVjaXBpdGF0aW9uJ3MgZXN0aW1hdGVkIG5lZ2F0aXZlIGVmZmVjdCBvbiB0aGUgbG9nIG1lYW4gb2YgTWFuaGF0dGFuIEJyaWRnZSBjeWNsaXN0cyBoYXMgYW4gYWJzb2x1dGUgdmFsdWUgfiB8LjQzMDd8LCB3aGljaCBpcyB0aGUgdGhlIGhpZ2hlc3Qgb2YgYWxsIG91ciBwcmVkaWN0b3JzLgoKSXQgYXBwZWFycyB0aGF0IHRoZSBkYXkncyBhdmVyYWdlIHRlbXBlcmF0dXJlIGFuZCBkaWZmZXJlbmNlIGluIGRhaWx5IGhpZ2hzIGFuZCBsb3dzIHBsYXllZCB2ZXJ5IGxpdHRsZSBwcmFjdGljYWwgc2lnbmlmaWNhbmNlIGluIHRoZSBsb2cgbWVhbiBvZiB0aGF0IGRheSdzIGN5Y2xpc3RzLiBXaGVuIHdlIGxvb2sgYXQgdGhlIGRpZmZlcmVuY2UgaW4gbG9nIG1lYW5zIGZyb20gYSBkYXktb2YtdGhlLXdlZWsgcGVyc3BlY3RpdmUsIHdlIGRvIHNlZSBhIHNsaWdodGx5IG1vcmUgaW1wYWN0ZnVsIGVmZmVjdC4gV2l0aCBTdW5kYXkgYmVpbmcgY29kZWQgaW4gYXMgdGhlIGJhc2VsaW5lLCBpdCBsb29rcyBsaWtlIFdlZG5lc2RheSBoYXMgdGhlIGdyZWF0ZXN0IGFtb3VudCBvZiBjeWNsaXN0IHRyYWZmaWMgYW5kIFNhdHVyZGF5IGhhcyB0aGUgbGVhc3QuIFRoaXMgaGlnaGVyIGNvdW50IG9mIGN5Y2xpc3RzIGR1cmluZyB0aGUgd29ya3dlZWsgY291bGQgYmUgZHVlIHRvIHRoZSBNYW5oYXR0YW4gQnJpZGdlIGZ1bmN0aW9uaW5nIGZvciBtYW55IGFzIGEgY29tbXV0aW5nIG1ldGhvZC4KCkFsbCBpbiBhbGwsIG91ciBQb2lzc29uIGNvdW50cyBtb2RlbCB5aWVsZHMgc29tZSBpbnRlcmVzdGluZyBhbmQgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCByZXZlbGF0aW9ucywgbW9zdCBub3RhYmx5IHRoYXQgY3ljbGlzdHMgY2FyZSBmYXIgbW9yZSBhYm91dCBwcmVjaXBpdGF0aW9uIHRoYW4gdGhleSBkbyB0ZW1wZXJhdHVyZSBmbHVjdHVhdGlvbiwgYW5kIHRoYXQgY3ljbGlzdCB0cmFmZmljIGFwcGVhcnMgdG8gdGljayB1cHdhcmRzIHRocm91Z2hvdXQgdGhlIHdvcmt3ZWVrIGJlZm9yZSBkeWluZyBkb3duIGZvciB0aGUgd2Vla2VuZC4gSG93ZXZlciwgdGhlIHJlbGF0aXZlbHkgc21hbGwgbWFnbml0dWRlIG9mIGVhY2ggdmFyaWFibGUncyBlc3RpbWF0ZWQgZWZmZWN0IGlzIGEgZG93bnNpZGUgcmVnYXJkaW5nIHRoZSBtb2RlbCdzIHV0aWxpdHkuIAoKIyMgUG9pc3NvbiBSZWdyZXNzaW9uIChSYXRlcykKQWZ0ZXIgUG9pc3NvbiBjb3VudHMgcmVncmVzc2lvbiwgSSB0aGVuIHBlcmZvcm1lZCBQb2lzc29uIHJhdGVzIHJlZ3Jlc3Npb24gd2l0aCB0aGUgdG90YWwgbnVtYmVyIG9mIGN5Y2xpc3RzIGVudGVyaW5nIGFuZCBleGl0aW5nIG91ciB0aHJlZSBib3JvdWdocyBvZiBpbnRlcmVzdCBhY3Jvc3MgKmFsbCogdGhlIEVhc3QgUml2ZXIgQnJpZGdlcyBhcyB0aGUgInBvcHVsYXRpb24iIGZvciB3aGljaCB0aGUgTWFuaGF0dGFuIEJyaWRnZSBjeWNsaXN0cyBhcmUgYWN0aW5nIGFzIGEgc2FtcGxlIG9mLiAKClRoaXMgcHJvY2VzcyBjb25zaXN0ZWQgb2YgbWUgY3JlYXRpbmcgdHdvIGRpZmZlcmVudCBQb2lzc29uIHJhdGVzIG1vZGVscy4gVGhlIGZpcnN0IG9uZSBJIGNyZWF0ZWQgbGlzdGVkIGJvdGggdGVtcGVyYXR1cmUgdmFyaWFibGVzIGFzIHN0YXRpc3RpY2FsbHkgaW5zaWduaWZpY2FudC4gR2l2ZW4gdGhlaXIgc3RhdHVzIGFzIHN0YXRpc3RpY2FsbHkgaW5zaWduaWZpY2FudCBpbiB0aGlzIG1vZGVsLCBhbmQgdGhlaXIgbWludXRlIHByYWN0aWNhbCBzaWduaWZpY2FuY2UgaW4gdGhlIHByZXZpb3VzIGNvdW50cyBtb2RlbCwgSSBjaG9zZSB0byByZW1vdmUgdGhlbSBhbmQgY3JlYXRlIGEgc2Vjb25kIFBvaXNzb24gcmF0ZXMgbW9kZWwgd2hpY2ggZGlkIG5vdCBmYWN0b3IgaW4gdGhlIGRheSdzIGF2ZXJhZ2Ugb3IgcmFuZ2Ugb2YgdGVtcGVyYXR1cmUuCmBgYHtyfQojIyMgUmF0ZXMgTW9kZWwgMQpSYXRlc19Nb2RlbCA9IGdsbShNYW5oYXR0YW4gfiBEYXkgKyBNZWFuVGVtcCArIFRlbXBEaWZmICsgUHJlY2lwaXRhdGlvbiwgb2Zmc2V0ID0gbG9nKFRvdGFsKSwgZmFtaWx5ID0gcG9pc3NvbihsaW5rID0gImxvZyIpLCBkYXRhID0gRGF0YSkKClJhdGVzX01vZGVsX1N1bSA9IHN1bW1hcnkoUmF0ZXNfTW9kZWwpClJhdGVzX01vZGVsX0NvZWYgPSBSYXRlc19Nb2RlbF9TdW0kY29lZmZpY2llbnRzCgppbnZpc2libGUoUmF0ZXNfTW9kZWxfQ29lZikKa2FibGUoUmF0ZXNfTW9kZWxfQ29lZiwgY2FwdGlvbiA9ICI8Yj48Y2VudGVyPiBQb2lzc29uIFJhdGVzIFJlZ3Jlc3Npb24gKDEpOiBXZWF0aGVyIGFuZCBTY2hlZHVsZSBSZWxhdGlvbnNoaXAgd2l0aCBDb3VudCBvZiBNYW5oYXR0YW4gQnJpZGdlIEN5Y2xpc3RzIDwvY2VudGVyPjwvYj4iKQoKCiMjIyBSYXRlcyBNb2RlbCAyClJhdGVzX01vZGVsMiA9IGdsbShNYW5oYXR0YW4gfiBEYXkgKyBQcmVjaXBpdGF0aW9uLCBvZmZzZXQgPSBsb2coVG90YWwpLCBmYW1pbHkgPSBwb2lzc29uKGxpbmsgPSAibG9nIiksIGRhdGEgPSBEYXRhKQoKUmF0ZXNfTW9kZWwyX1N1bSA9IHN1bW1hcnkoUmF0ZXNfTW9kZWwyKQpSYXRlc19Nb2RlbDJfQ29lZiA9IFJhdGVzX01vZGVsMl9TdW0kY29lZmZpY2llbnRzCgppbnZpc2libGUoUmF0ZXNfTW9kZWxfQ29lZikKa2FibGUoUmF0ZXNfTW9kZWwyX0NvZWYsIGNhcHRpb24gPSAiPGI+PGNlbnRlcj4gUG9pc3NvbiBSYXRlcyBSZWdyZXNzaW9uICgyKTogUHJlY2lwaXRhdGlvbiBhbmQgU2NoZWR1bGUgUmVsYXRpb25zaGlwIHdpdGggQ291bnQgb2YgTWFuaGF0dGFuIEJyaWRnZSBDeWNsaXN0cyA8L2NlbnRlcj48L2I+IikKCmBgYApMb29raW5nIGF0IHRoZSBmaW5kaW5ncyBvZiBvdXIgc2Vjb25kIFBvaXNzb24gcmF0ZXMgcmVncmVzc2lvbiBtb2RlbCwgd2Ugc2VlIGEgdHJlbmQgc2ltaWxhciB0byB0aGF0IG9mIG91ciBQb2lzc29uIGNvdW50cyByZWdyZXNzaW9uIG1vZGVsLCB0aGF0IGJlaW5nIGEgY29tbW9uIG9jY3VycmVuY2Ugb2Ygc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIGJ1dCBub3QgYSBncmVhdCBkZWFsIG9mIHByYWN0aWNhbCBzaWduaWZpY2FuY2Ugb24gZGlzcGxheSB3aGVuIHRoZSBtYWduaXR1ZGUgb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnQgaXMgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uLgoKT25jZSBhZ2FpbiB0cmVhdGluZyBTdW5kYXkgYXMgb3VyIGJhc2VsaW5lLCBpdCBsb29rcyBsaWtlIHRoZSByYXRlIG9mIE1hbmhhdHRhbiBCcmlkZ2UgY3ljbGlzdHMgaW4gcHJvcG9ydGlvbiB0byB0aGUgZW50aXJldHkgb2YgRWFzdCBSaXZlciBCcmlkZ2UgY3ljbGlzdHMgaXMgYXQgaXRzIGhpZ2hlc3QgZWFybHkgaW4gdGhlIHdlZWssIHdpdGggdGhhdCByYXRlIGRlY2xpbmluZyBnb2luZyBpbnRvIHRoZSB3ZWVrZW5kLiBUaGF0IGJlaW5nIHNhaWQsIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhpcyBicmVha2Rvd24gYWxzbyBncmVhdGx5IGRlY3JlYXNlcyB3aGVuIHdlIGxvb2sgYXQgdGhlIGRhdGEgZm9yIFRodXJzZGF5IGFuZCB0byBhIG11Y2ggbGVzc2VyIGJ1dCBzdGlsbCBub3RpY2VhYmxlIGV4dGVudCBGcmlkYXksIHBlcmhhcHMgc3VnZ2VzdGluZyB0aGF0IHRoZSBNYW5oYXR0YW4gQnJpZGdlIGN5Y2xpc3QgcmF0ZSdzIGRlY2xpbmUgYXQgdGhlIHRhaWwgZW5kIG9mIHRoZSB3b3Jrd2VlayBjb3VsZCBiZSBjaGFsa2VkIHVwIHRvIHJhbmRvbSBjaGFuY2UgYW5kIG5vdCBhIHBhcnRpY3VsYXIgY2hhcmFjdGVyaXN0aWMgb2YgdGhlIEJyaWRnZSB0aGF0IGFmZmVjdHMgdGhlIGV4cGVyaWVuY2Ugb2YgaXRzIGN5Y2xpc3RzIG9ubHkgb24gdGhvc2UgcGFydGljdWxhciBkYXlzLgoKIyMgRGF5IG9mIHRoZSBXZWVrIEF2ZXJhZ2VzClNpbmNlIGJvdGggb3VyIGNvdW50cyBhbmQgcmF0ZXMgbW9kZWxzIHN1Z2dlc3RlZCB0aGF0IHRoZSBkYXkgb2YgdGhlIHdlZWsgaGFzIHRoZSBncmVhdGVzdCBhc3NvY2lhdGlvbiB3aXRoIHRoZSBsb2cgbWVhbiBvZiB0aGUgTWFuaGF0dGFuIEJyaWRnZSdzIGN5Y2xpc3RzLCBJIGRlY2lkZWQgdG8gY2FsY3VsYXRlIHRoZSBhdmVyYWdlIGNvdW50cyBhbmQgcmF0ZXMgcGVyIGRheSB0byBjb21wYXJlIHRoZW0gdG8gZWFjaCBvdGhlciBhbmQgdGhlIG1lYW4gYWNyb3NzIGFsbCBkYXlzIGNvbnNpZGVyZWQuIFRoZSB0YWJsZSB3aXRoIHRoaXMgaW5mb3JtYXRpb24gaXMgYmVsb3cuCmBgYHtyfQpDb3VudF9BdmVyYWdlcyA9IGMoCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlN1bmRheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiTW9uZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJUdWVzZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJXZWRuZXNkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlRodXJzZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJGcmlkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlNhdHVyZGF5Il0pKQopCgpBbGxEYXlzX1JhdGVzX0F2ZyA9IHN1bShEYXRhJE1hbmhhdHRhbikvc3VtKERhdGEkVG90YWwpCgpTdW5fUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJTdW5kYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIlN1bmRheSJdKQoKTW9uX1JhdGVzX0F2ZyA9IHN1bShEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiTW9uZGF5Il0pL3N1bShEYXRhJFRvdGFsW0RhdGEkRGF5ID09ICJNb25kYXkiXSkKClR1ZXNfUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJUdWVzZGF5Il0pL3N1bShEYXRhJFRvdGFsW0RhdGEkRGF5ID09ICJUdWVzZGF5Il0pCgpXZWRfUmF0ZXNfQXZnID0gc3VtKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJXZWRuZXNkYXkiXSkvc3VtKERhdGEkVG90YWxbRGF0YSREYXkgPT0gIldlZG5lc2RheSJdKQoKVGh1cl9SYXRlc19BdmcgPSBzdW0oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlRodXJzZGF5Il0pL3N1bShEYXRhJFRvdGFsW0RhdGEkRGF5ID09ICJUaHVyc2RheSJdKQoKRnJpX1JhdGVzX0F2ZyA9IHN1bShEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiRnJpZGF5Il0pL3N1bShEYXRhJFRvdGFsW0RhdGEkRGF5ID09ICJGcmlkYXkiXSkKClNhdF9SYXRlc19BdmcgPSBzdW0oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlNhdHVyZGF5Il0pL3N1bShEYXRhJFRvdGFsW0RhdGEkRGF5ID09ICJTYXR1cmRheSJdKQoKRGF5X1JhdGVzX0F2ZXJhZ2VzID0gYyhBbGxEYXlzX1JhdGVzX0F2ZywgU3VuX1JhdGVzX0F2ZywgTW9uX1JhdGVzX0F2ZywgVHVlc19SYXRlc19BdmcsIFdlZF9SYXRlc19BdmcsIFRodXJfUmF0ZXNfQXZnLCBGcmlfUmF0ZXNfQXZnLCBTYXRfUmF0ZXNfQXZnKQoKUmF0ZV9BdmVyYWdlcyA9IHJvdW5kKERheV9SYXRlc19BdmVyYWdlcywgZGlnaXRzID0gNCkKCkRheXMgPSBjKCJBbGwgRGF5cyIsICJTdW5kYXkiLCAiTW9uZGF5IiwgIlR1ZXNkYXkiLCAiV2VkbmVzZGF5IiwgIlRodXJzZGF5IiwgIkZyaWRheSIsICJTYXR1cmRheSIpCgpDb3VudHNfRGlmZmVyZW5jZSA9IGMoCiAgMCwgIyBEaWZmZXJlbmNlIGJldHdlZW4gdGhlIGF2ZXJhZ2UgY291bnQgb2YgYWxsIGRheXMgYW5kIGl0c2VsZgogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlN1bmRheSJdKSkgLSByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJERheSA9PSAiTW9uZGF5Il0pKSAtIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW4pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJUdWVzZGF5Il0pKSAtIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW4pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJXZWRuZXNkYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlRodXJzZGF5Il0pKSAtIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW4pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkRGF5ID09ICJGcmlkYXkiXSkpIC0gcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbikpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSREYXkgPT0gIlNhdHVyZGF5Il0pKSAtIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW4pKQopCgpSYXRlc19EaWZmZXJlbmNlQiA9IGMoCiAgMCwKICBTdW5fUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgTW9uX1JhdGVzX0F2ZyAtIEFsbERheXNfUmF0ZXNfQXZnLAogIFR1ZXNfUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgV2VkX1JhdGVzX0F2ZyAtIEFsbERheXNfUmF0ZXNfQXZnLAogIFRodXJfUmF0ZXNfQXZnIC0gQWxsRGF5c19SYXRlc19BdmcsCiAgRnJpX1JhdGVzX0F2ZyAtIEFsbERheXNfUmF0ZXNfQXZnLAogIFNhdF9SYXRlc19BdmcgLSBBbGxEYXlzX1JhdGVzX0F2ZwopCgpSYXRlc19EaWZmZXJlbmNlID0gcm91bmQoUmF0ZXNfRGlmZmVyZW5jZUIsIGRpZ2l0cyA9IDQpCgpUYWJsZSA9IGNiaW5kKERheXMsIENvdW50X0F2ZXJhZ2VzLCBDb3VudHNfRGlmZmVyZW5jZSwgUmF0ZV9BdmVyYWdlcywgUmF0ZXNfRGlmZmVyZW5jZSkKCmthYmxlKFRhYmxlLCBjYXB0aW9uID0gIjxiPjxjZW50ZXI+PHNwYW4gc3R5bGU9J2NvbG9yOiMwMDAwMDA7Jz5EaXN0cmlidXRpb24gb2YgTWFuaGF0dGFuIEJyaWRnZSBDeWNsaXN0IENvdW50IGFuZCBSYXRlcyBKdWx5IDIwMTc8L2NlbnRlcj48L2I+IikgJT4lCiAga2FibGVfc3R5bGluZygKICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJib3JkZXJlZCIpLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAiY2VudGVyIgogICkKCmBgYAoKVGhlIHRhYmxlIHByb3ZpZGVzIGdyZWF0ZXIgZGV0YWlsIGludG8gdGhlIGltcGxpY2F0aW9ucyBvZiBvdXIgUG9pc3NvbiBjb3VudCBhbmQgcmF0ZSBtb2RlbHMuIFRoYXQgYmVpbmcgd2Vla2RheSB0b3RhbHMgb2YgTWFuaGF0dGFuIEJyaWRnZSBjeWNsaXN0cyAoc3BlY2lmaWNhbGx5IE1vbmRheSAtIFRodXJzZGF5KSBmYXIgb3V0d2VpZ2ggdGhlIGNvdW50IG9mIGN5Y2xpc3RzIG9uIHRoZSBicmlkZ2UgZnJvbSBGcmlkYXkgdG8gU3VuZGF5LiBXaXRoIHRoZSBhdmVyYWdlIG51bWJlciBvZiBjeWxjbGlzdHMgZnJvbSBNb25kYXkgLSBUaHVyc2RheSBiZWluZyBhYm91dCA2LDMyNSwgYW5kIHRoZSBhdmVyYWdlIG51bWJlciBGcmlkYXkgLSBTdW5kYXkgYmVpbmcgYWJvdXQgNCwzNTMuCgpBcyBmb3IgdGhlIHJhdGUgb2YgTWFuaGF0dGFuIEJyaWRnZSBjeWNsaXN0cyByZWxhdGl2ZSB0byBjeWNsaXN0cyBvbiBhbGwgRWFzdCBSaXZlciBCcmlkZ2VzLCB3ZSBzZWUgdGhhdCB0aGUgTWFuaGF0dGFuIEJyaWRnZSdzIGN5Y2xpc3QgcmF0ZSBpcyBzbGlnaHRseSBhYm92ZSBhdmVyYWdlIE1vbmRheSAtIFdlZG5lc2RheSwgYnV0IHRoZW4gYmVsb3cgYXZlcmFnZSBUaHVyc2RheSB0aHJvdWdoIFN1bmRheS4KCgojIyBQb2lzc29uIE1vZGVsaW5nIFRha2Vhd2F5cwpUbyBjb25jbHVkZSwgYW55IGltcGxlbWVudGF0aW9ucyBkb25lIGluIHJlc3BvbnNlIHRvIG91ciBQb2lzc29uIG1vZGVscycgZmluZGluZ3Mgc2hvdWxkIGJlIGRvbmUgd2l0aCBzb21lIGRlZ3JlZSBvZiBjYXV0aW9uIGR1ZSB0byB0aGUgbG93IHByYWN0aWNhbCBzaWduaWZpY2FuY2UgZm91bmQgaW4gYm90aCBvdXIgY291bnQgYW5kIHJhdGUgbW9kZWxzLiBUaGF0IGJlaW5nIHNhaWQsIHRoZXJlIGFyZSBzdGlsbCB2YWx1YWJsZSB0YWtlYXdheXMgdGhhdCB3ZSBjYW4gZHJhdyBmcm9tIG91ciBhbmFseXNpcy4gCgpGaXJzdCwgdGhlIE1hbmhhdHRhbiBCcmlkZ2UgaXMgY2xlYXJseSBidXNpZXIsIGJvdGggaW4gdGhlIHNlbnNlIG9mIHJhdyB2b2x1bWUgYW5kIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgb3ZlcmFsbCBFYXN0IFJpdmVyIEJyaWRnZSBuZXR3b3JrLCBlYXJseSBhbmQgdGhyb3VnaG91dCB0aGUgc3RhbmRhcmQgd29ya3dlZWsgdGhhbiBpdCBpcyBkdXJpbmcgdGhlIHdlZWtlbmQuIFNlY29uZCwgdGhlIGRhaWx5IGF2ZXJhZ2UgdGVtcGVyYXR1cmUgYXMgd2VsbCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoYXQgZGF5J3MgaGlnaCBhbmQgbG93IHBsYXllZCB2ZXJ5IGxpdHRsZSBpZiBhbnkgcm9sZSBpbiB0aGUgY291bnQgb3IgcmF0ZSBvZiBjeWNsaXN0cyBvbiBhbnkgZ2l2ZW4gZGF5LCBidXQgdGhlIG1lYXN1cmUgb2YgcHJlY2lwaXRhdGlvbiBkb2VzIGFwcGVhciB0byBoYXZlIGEgcmVsYXRpdmVseSBub3RpY2VhYmxlIGFuZCBuZWdhdGl2ZSBhc3NvY2lhdGlvbiB3aXRoIHRoZSBudW1iZXIgb2YgdGhhdCBkYXkncyBjeWNsaXN0cyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZS4KCiMgUXVhc2ktUG9pc3NvbiBSZWdyZXNzaW9uIE1vZGVsaW5nCkluIGFkZGl0aW9uIHRvIGFuYWx5emluZyBvdXIgZGF0YSBhdCBoYW5kIHZpYSBQb2lzc29uIHJlZ3Jlc3Npb24sIEkgZGVjaWRlZCB0byBhbHNvIGNyZWF0ZSBhIHF1YXNpLVBvaXNzb24gbW9kZWwgb2YgdGhlIGRhdGEuIFF1YXNpLVBvaXNzb24gbW9kZWxpbmcgaXMgYW4gYWx0ZXJuYXRpdmUgdG8gUG9pc3NvbiBtb2RlbGluZywgYW5kIGl0IGlzIHBhcnRpY3VsYXJseSB2YWx1YWJsZSB3aGVuIHRoZSBtZWFuIGFuZCB2YXJpYW5jZSBvZiB0aGUgbW9kZWwncyByZXNwb25zZSB2YXJpYWJsZSAobnVtYmVyIG9mIGN5Y2xpc3RzIG9uIHRoZSBNYW5oYXR0YW4gYnJpZGdlIGluIHRoaXMgY2FzZSkgYXJlIG5vdCBhcHByb3hpbWF0ZWx5IGVxdWFsIHRvIG9uZSBhbm90aGVyIChrbm93biBhcyBkaXNwZXJzaW9uKS4KCkZvciBteSBxdWFzaS1Qb2lzc29uIG1vZGVsLCBJIGluY2x1ZGVkIHRoYXQgZGF5J3MgYXZlcmFnZSB0ZW1wZXJhdHVyZSwgZGF5IG9mIHRoZSB3ZWVrIGFuZCBwcmVjaXBpdGF0aW9uIGFtb3VudCBhcyB0aGUgcmVsZXZhbnQgZmFjdG9ycy4gRGF5IG9mIHRoZSB3ZWVrIG9idmlvdXNseSBwbGF5ZWQgdGhlIGJpZ2dlc3Qgcm9sZSBpbiBvdXIgcHJldmlvdXMgUG9pc3NvbiBtb2RlbHMsIHdpdGggcHJlY2lwaXRhdGlvbiBjb25zaXN0ZW50bHkgYmVpbmcgY2l0ZWQgYXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkZXNwaXRlIHJlbGF0aXZlbHkgbG93IHByYWN0aWNhbCBzaWduaWZpY2FuY2UuIEZvciB0aGlzIG1vZGVsLCBJIGNob3NlIHRvIGRpc2NyZXRpemUgcHJlY2lwaXRhdGlvbiwgd2l0aCBkYXlzIG9mIG5vIHJlY29yZGVkIHJhaW4gYmVpbmcgbWFya2VkIGFzICIwIiBhbmQgZGF5cyB3aXRoICphbnkqIGFtb3VudCBvZiByYWluIGJlaW5nIG1hcmtlZCBhcyAiMS4iIApgYGB7ciwgUXVhc2ktUG9pc3NvbiBNb2RlbH0KRGF0YSROZXdQcmVjaXAgPSBEYXRhJFByZWNpcGl0YXRpb24KRGF0YSROZXdQcmVjaXBbRGF0YSRQcmVjaXBpdGF0aW9uID09IDBdID0gMApEYXRhJE5ld1ByZWNpcFtEYXRhJFByZWNpcGl0YXRpb24gPiAwXSA9IDEKCkRhdGEgPSBkYXRhLmZyYW1lKERhdGEkRGF0ZSwgRGF0YSREYXksIERhdGEkRGF5X051bSwgRGF0YSRIaWdoVGVtcCwgRGF0YSRMb3dUZW1wLCBEYXRhJE1lYW5UZW1wLCBEYXRhJFRlbXBEaWZmLCBEYXRhJFByZWNpcGl0YXRpb24sIERhdGEkTmV3UHJlY2lwLCBEYXRhJE1hbmhhdHRhbiwgRGF0YSRUb3RhbCkKY29sbmFtZXMoRGF0YSkgPSBjKCJEYXRlIiwgIkRheSIsICJEYXlfTnVtIiwgIkhpZ2hUZW1wIiwgIkxvd1RlbXAiLCAiTWVhblRlbXAiLCJUZW1wRGlmZiIsICJQcmVjaXBpdGF0aW9uIiwgIk5ld1ByZWNpcCIsIk1hbmhhdHRhbiIsICJUb3RhbCIpCgoKIyAxLikgQmVsb3cgaXMgdGhlIHF1YXNpLVBvaXNzb24gcmVncmVzc2lvbiBtb2RlbAogICMgQXMgaW5zdHJ1Y3RlZCwgb25seSBpbmNsdWRlcyBEYXksIE1lYW5UZW1wIGFuZCBOZXdQcmVjaXAKClF1YXNpX0NvdW50c19Nb2RlbCA9IGdsbShNYW5oYXR0YW4gfiBEYXkgKyBNZWFuVGVtcCArIE5ld1ByZWNpcCwgZmFtaWx5ID0gcXVhc2lwb2lzc29uLCBkYXRhID0gRGF0YSkKICAKUXVhc2lfQ291bnRzX01vZGVsX1N1bSA9IHN1bW1hcnkoUXVhc2lfQ291bnRzX01vZGVsKQpRdWFzaV9Db3VudHNfTW9kZWxfQ29lZiA9IFF1YXNpX0NvdW50c19Nb2RlbF9TdW0kY29lZmZpY2llbnRzCgppbnZpc2libGUoUXVhc2lfQ291bnRzX01vZGVsX0NvZWYpCmthYmxlKFF1YXNpX0NvdW50c19Nb2RlbF9Db2VmLCBjYXB0aW9uID0gIjxiPjxjZW50ZXI+IFF1YXNpLVBvaXNzb24gQ291bnRzIFJlZ3Jlc3Npb246IFdlYXRoZXIgYW5kIFNjaGVkdWxlIFJlbGF0aW9uc2hpcCB3aXRoIENvdW50IG9mIE1hbmhhdHRhbiBCcmlkZ2UgQ3ljbGlzdHMgPC9jZW50ZXI+PC9iPiIpCiAgCmBgYAoKQSBzdW1tYXJ5IG9mIHRoZSBxdWFzaS1Qb2lzc29uIGNvdW50cyBtb2RlbCBjYW4gYmUgc2VlbiBhYm92ZS4gV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIGdyZWF0IHNpbWlsYXJpdHkgYmV0d2VlbiB0aGUgZmluZGluZ3Mgb2YgdGhpcyBtb2RlbCBhbmQgb3VyIG9yaWdpbmFsIFBvaXNzb24gY291bnRzIG1vZGVsLiBIb3dldmVyIGJlZm9yZSB3ZSBjYW4gZGV0ZXJtaW5lIHdoaWNoIG9uZSBpcyBzdXBlcmlvciBmb3IgaW50ZXJwcmV0YXRpdmUgdXNlLCB3ZSBtdXN0IGNhbGN1bGF0ZSB0aGlzIHF1YXNpLVBvaXNzb24ncyBkaXNwZXJzaW9uIHBhcmFtZXRlciwgInBoaSBoYXQiICgkXGhhdHtccGhpfSQpLgoKIyMgRGlzcGVyc2lvbiBhbmQgQ291bnRzIE1vZGVsIFNlbGVjdGlvbgoKJFxoYXR7XHBoaX0kIGlzIHVzZWQgaW4gcXVhc2ktUG9pc3NvbiByZWdyZXNzaW9uIHRvIGRldGVybWluZSBpZiBvdXIgZGF0YSdzIHJlc3BvbnNlIHZhcmlhYmxlIGlzIG92ZXJseSBvciB1bmRlcmx5IGRpc3BlcnNlZC4gR2VuZXJhbGx5LCBhIHBoaSBoYXQgdmFsdWUgb2YgYXJvdW5kIDEgaXMgcmVwcmVzZW50YXRpdmUgb2YgYW4gYXBwcm94aW1hdGVseSBlcXVhbCBtZWFuIGFuZCB2YXJpYW5jZSBvZiB0aGUgcmVzcG9uc2UuIElmIGEgcXVhc2ktUG9pc3NvbiBtb2RlbCdzIGRpc3BlcnNpb24gdmFsdWUgaXMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgdGhhbiAxLCB0aGVuIHRoYXQgbW9kZWwgc2hvdWxkIGJlIHVzZWQgZm9yIGFzc29jaWF0aXZlIGFuYWx5c2lzIHJhdGhlciB0aGFuIGEgdHJhZGl0aW9uYWwgUG9pc3NvbiBjb3VudGVycGFydCwgYXMgdGhlIHF1YXNpLVBvaXNzb24gY2FsY3VsYXRpb24gaW5jbHVkZXMgZ3JlYXRlciBlc3RpbWF0aW9uIG9mIHN0YW5kYXJkIGVycm9ycy4gSG93ZXZlciwgaWYgJFxoYXR7XHBoaX0kIH4gMSwgdGhlbiB0aGUgdHJhZGl0aW9uYWwgUG9pc3NvbiBtb2RlbCBzaG91bGQgYmUgdXNlZCwgYXMgaXQgaXMgbGVzcyBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIGFuZCBhdm9pZHMgb3RoZXJ3aXNlIHVubmVjZXNzYXJ5IGV4dHJhIHN0ZXBzLiBUaGUgZm9ybXVsYSBmb3IgJFxoYXR7XHBoaX0kJ3MgY2FsY3VsYXRpb24gY2FuIGJlIHNlZW4gYmVsb3cuCgpgYGB7ciwgIGZpZy5hbGlnbj0iY2VudGVyIiwgZWNobz1GQUxTRX0KaW5jbHVkZV9ncmFwaGljcygiRGlzcGVyc2lvbl9QYXJhbWV0ZXIucG5nIikKYGBgCgpgYGB7ciBEaXNwZXJzaW9uIFBhcmFtZXRlcn0KbiA9IG5yb3coRGF0YSkKcCA9IDMKUGVhcnNvbl9SZXNpZHVhbHMgPSByZXNpZHVhbHMoUXVhc2lfQ291bnRzX01vZGVsLCB0eXBlID0gInBlYXJzb24iKQpTcV9QZWFyc29uX1Jlc2lkdWFscyA9IFBlYXJzb25fUmVzaWR1YWxzXjIKRGlzcGVyc2lvbl9QYXJhbWV0ZXIgPSAoc3VtKFNxX1BlYXJzb25fUmVzaWR1YWxzKSkvKG4tcCkKCiMjIyMgRG91YmxlIGNoZWNrZWQgcGhpJ3MgdmFsdWUgdXNpbmcgUHJvZidzIGNvZGluZyBtZXRob2Q7IGdvdCBzYW1lIHJlc3VsdAogIHlkaWY9RGF0YSRNYW5oYXR0YW4tZXhwKFF1YXNpX0NvdW50c19Nb2RlbCRsaW5lYXIucHJlZGljdG9ycykgICMgZGlmZiBiZXR3ZWVuIHkgYW5kIHloYXQKICBwcnNkID0geWRpZi9zcXJ0KGV4cChRdWFzaV9Db3VudHNfTW9kZWwkbGluZWFyLnByZWRpY3RvcnMpKSAgICMgUGVhcnNvbiByZXNpZHVhbHMKICBwaGlfY2hlY2sgPSBzdW0ocHJzZF4yKS8obi1wKQojIyMjIAogIAppbnZpc2libGUoRGlzcGVyc2lvbl9QYXJhbWV0ZXIpCmludmlzaWJsZShwaGlfY2hlY2spCmBgYAoKT3VyIG1vZGVsIHlpZWxkZWQgYSB2YWx1ZSBvZiAkXGhhdHtccGhpfSQgfiAxNDIsIHdoaWNoIGlzICoqd2VsbCoqIGJleW9uZCB0aGUgbWFyZ2luIG9mIGVycm9yIGZvciBhIHByb3Blcmx5IGRpc3BlcnNlZCBQb2lzc29uIHJlc3BvbnNlIHZhcmlhYmxlLiBGb3IgdGhpcyByZWFzb24sIHdlIGNhbiBkZWVtIHRoYXQgdGhlIHF1YXNpLVBvaXNzb24gY291bnRzIG1vZGVsIGlzIG1vcmUgdmFsdWFibGUgZm9yIGFzc29jaWF0aXZlIGFuYWx5c2lzIHRoYW4gdGhlIFBvaXNzb24gY291bnRzIG1vZGVsLiBCZWNhdXNlIG9mIHRoaXMsIHdlIHdpbGwgdXNlIHRoZSBxdWFzaS1Qb2lzc29uIGZvciBvdXIgdWx0aW1hdGUgaW50ZXJwcmV0YXRpb25zLgoKIyMgVmlzdWFsIEFpZHMKUmVmZXJyaW5nIHRvIG91ciBxdWFzaS1Qb2lzc29uIG1vZGVsIHN1bW1hcnkgYWJvdmUsIHdlIHNlZSB0aGF0IHRoZSBkYXkncyBhdmVyYWdlIHRlbXBlcmF0dXJlIGRvZXMgbm90IGFwcGVhciB0byBoYXZlIHNpZ25pZmljYW50IHN0YXRpc3RpY2FsIG9yIHByYWN0aWNhbCBhc3NvY2lhdGlvbiB3aXRoIHRoZSBNYW5oYXR0YW4gYnJpZGdlJ3MgbnVtYmVyIG9mIGN5Y2xpc3RzLiBIb3dldmVyLCB0aGVyZSBkb2VzIGFwcGVhciB0byBiZSBzdWNoIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBudW1iZXIgb2YgY3ljbGlzdHMgb24gYSB0b3RhbGx5IGNsZWFyIGRheSBhcyBvcHBvc2VkIHRvIGEgZGF5IHdpdGggYXQgbGVhc3QgKnNvbWUqIGxldmVsIG9mIHByZWNpcGl0YXRpb24gKHJlY29yZGVkIHZpYSB2YXJpYWJsZSBOZXdQcmVjaXApLiBBbmQsIGFzIGNvbnNpc3RlbnRseSBzZWVuIGluIG91ciBvcmlnaW5hbCBQb2lzc29uIHJlZ3Jlc3Npb24gbW9kZWxzLCB0aGVyZSBpcyBjZXJ0YWlubHkgYSBsYXJnZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR5cGljYWwgbnVtYmVyIG9mIGN5Y2xpc3RzIGRlcGVuZGluZyBvbiB0aGUgZGF5IG9mIHRoZSB3ZWVrLgoKS25vd2luZyB0aGlzLCBJIGNyZWF0ZWQgdHdvIHZpc3VhbHMgYmVsb3cgdG8gZW5oYW5jZSBvdXIgZ3Jhc3Agb2YgdGhlIHJlbGF0aW9uc2hpcCB0aGF0IGJvdGggdGhlIGRheSBvZiB0aGUgd2VlayBhbmQgdGhlIHByZXNlbmNlIG9mIHByZWNpcGl0YXRpb24gaGF2ZSB3aXRoIGVhY2ggb3RoZXIgYXMgd2VsbCBhcyB0aGUgc3RhbmRhcmQgbnVtYmVyIG9mIGN5Y2xpc3RzIHRoYXQgd2VyZSBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZSB0aHJvdWdob3V0IEp1bHkgMjAxNy4gVW5mb3J0dW5hdGVseSwgdGhlcmUgd2VyZSBubyBpbnN0YW5jZXMgb2YgVHVlc2RheXMgb3IgV2VkbmVzZGF5cyB3aXRoIHByZWNpcGl0YXRpb24gaW4gdGhpcyBzdHVkeSwgcmVzdWx0aW5nIGluIGEgYmxhbmsgaW4gYm90aCBvdXIgdGFibGUgYW5kIGJhciBjaGFydCBiZWxvdy4KCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQojIyMjIFRhYmxlCkRheXMgPSBjKCJBbGwgRGF5cyIsICJTdW5kYXkiLCAiTW9uZGF5IiwgIlR1ZXNkYXkiLCAiV2VkbmVzZGF5IiwgIlRodXJzZGF5IiwgIkZyaWRheSIsICJTYXR1cmRheSIpCgpOb19QcmVjaXBpdGF0aW9uID0gYygKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDBdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAwICYgRGF0YSREYXkgPT0gIlN1bmRheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAwICYgRGF0YSREYXkgPT0gIk1vbmRheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAwICYgRGF0YSREYXkgPT0gIlR1ZXNkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSROZXdQcmVjaXAgPT0gMCAmIERhdGEkRGF5ID09ICJXZWRuZXNkYXkiXSkpLAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSROZXdQcmVjaXAgPT0gMCAmIERhdGEkRGF5ID09ICJUaHVyc2RheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAwICYgRGF0YSREYXkgPT0gIkZyaWRheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAwICYgRGF0YSREYXkgPT0gIlNhdHVyZGF5Il0pKQopCgpTb21lX1ByZWNpcGl0YXRpb24gPSBjKAogIHJvdW5kKG1lYW4oRGF0YSRNYW5oYXR0YW5bRGF0YSROZXdQcmVjaXAgPT0gMV0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDEgJiBEYXRhJERheSA9PSAiU3VuZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDEgJiBEYXRhJERheSA9PSAiTW9uZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDEgJiBEYXRhJERheSA9PSAiVHVlc2RheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAxICYgRGF0YSREYXkgPT0gIldlZG5lc2RheSJdKSksCiAgcm91bmQobWVhbihEYXRhJE1hbmhhdHRhbltEYXRhJE5ld1ByZWNpcCA9PSAxICYgRGF0YSREYXkgPT0gIlRodXJzZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDEgJiBEYXRhJERheSA9PSAiRnJpZGF5Il0pKSwKICByb3VuZChtZWFuKERhdGEkTWFuaGF0dGFuW0RhdGEkTmV3UHJlY2lwID09IDEgJiBEYXRhJERheSA9PSAiU2F0dXJkYXkiXSkpCikKClZpc19UYWJsZSA9IGRhdGEuZnJhbWUoRGF5cywgTm9fUHJlY2lwaXRhdGlvbiwgU29tZV9QcmVjaXBpdGF0aW9uKQoKa2FibGUoVmlzX1RhYmxlLCBjYXB0aW9uID0gIjxiPjxjZW50ZXI+PHNwYW4gc3R5bGU9J2NvbG9yOiMwMDAwMDA7Jz5BdmVyYWdlIEN5Y2xpc3QgQ291bnRzIG9uIHRoZSBNYW5oYXR0YW4gQnJpZGdlIEp1bHkgMjAxNzwvY2VudGVyPjwvYj4iKSAlPiUKICBrYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImJvcmRlcmVkIiksCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJjZW50ZXIiKQoKIyMjIyBCYXJjaGFydApWaXNfbG9uZyA9CiAgVmlzX1RhYmxlICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBjKE5vX1ByZWNpcGl0YXRpb24sIFNvbWVfUHJlY2lwaXRhdGlvbiksCiAgICBuYW1lc190byA9ICJQcmVjaXBpdGF0aW9uIiwKICAgIHZhbHVlc190byA9ICJNYW5oYXR0YW4iCiAgKQoKVmlzX2xvbmckRGF5cyA9IGZhY3RvcigKICBWaXNfbG9uZyREYXlzLAogIGxldmVscyA9IGMoIkFsbCBEYXlzIiwgIlN1bmRheSIsICJNb25kYXkiLCAiVHVlc2RheSIsICJXZWRuZXNkYXkiLAogICAgICAgICAgICAgIlRodXJzZGF5IiwgIkZyaWRheSIsICJTYXR1cmRheSIpCikKZ2dwbG90KFZpc19sb25nLAogICAgICAgYWVzKHggPSBEYXlzLCB5ID0gTWFuaGF0dGFuLCBmaWxsID0gUHJlY2lwaXRhdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwKICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwKICAgICAgICAgICBuYS5ybSA9IFRSVUUpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQXZlcmFnZSBDeWNsaXN0IENvdW50cyBvbiB0aGUgTWFuaGF0dGFuIEJyaWRnZSBKdWx5IDIwMTciLAogICAgeCA9ICJEYXkgb2YgdGhlIFdlZWsiLAogICAgeSA9ICJOdW1iZXIgb2YgQ3ljbGlzdHMiLAogICAgZmlsbCA9ICJQcmVjaXBpdGF0aW9uIgogICkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgdmFsdWVzID0gYygiTm9fUHJlY2lwaXRhdGlvbiIgPSAiZGFya3JlZCIsCiAgICAgICAgICAgICAgICJTb21lX1ByZWNpcGl0YXRpb24iICAgID0gImxpZ2h0Ymx1ZSIpCiAgKSArCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCkKICApCmBgYAoKVGhlIGRlcGljdGlvbnMgYWJvdmUgcHJvdmlkZSBhZGRlZCBjbGFyaXR5IHRvIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MgZnJvbSBvdXIgcXVhc2ktUG9pc3NvbiBtb2RlbC4gU3VuZGF5IHdhcyB0aGUgYmFzZWxpbmUgZm9yIG91ciByZWdyZXNzaW9uIG1vZGVsJ3MgY2FsY3VsYXRpb25zLCBhbmQgYWxsIHJlbWFpbmluZyBkYXlzIG90aGVyIHRoYW4gU2F0dXJkYXkgaGFkIHBvc2l0aXZlIGNvZWZmaWNpZW50cy4gV2UgY2FuIHNlZSBpbiBib3RoIG91ciBjaGFydCBhbmQgdGFibGUsIHRoYXQgdGhlIGNvdW50IG9mIGN5Y2xpc3RzIGlzIGNlcnRhaW5seSBoaWdoZXIgdGhyb3VnaG91dCB0aGUgd2VlayB0aGFuIGl0IGlzIG9uIHRoZSB3ZWVrZW5kcy4gQXMgZm9yIHRoZSByb2xlIG9mIHByZWNpcGl0YXRpb247IG91ciBkaXNjcmV0aXplZCB2YXJpYWJsZSBOZXdQcmVjaXAgaGFkIGEgcmVncmVzc2lvbiBjb2VmZmljZW50IG9mIH4gMC40ICh0aGUgaGlnaGVzdCBhYnNvbHV0ZSB2YWx1ZSBvZiBhbnkgZmFjdG9yIGluIHRoZSBtb2RlbCkgYW5kIGEgc2lnbmlmaWNhbnQgcCB2YWx1ZSB+IC4wMDAyLiBUaGF0IGZpbmRpbmcgY2FuIGJlIGludHVpdGl2ZWx5IGNvbmZpcm1lZCBieSB0YWtpbmcgYSBnbGFuY2UgYXQgb3VyIHZpc3VhbHMuIE90aGVyIHRoYW4gVGh1cnNkYXksIGFsbCBvdGhlciBkYXlzIGZvciB3aGljaCB0aGVyZSBhcmUgZGF0YSBwb2ludHMgZm9yIGJvdGggcHJlY2lwaXRhdGlvbiBhbmQgbm8gcHJlY2lwaXRhdGlvbiBzaG93IGEgKm5vdGljZWFibGUqIGRlY3JlYXNlIGluIGN5Y2xpc3RzIHdoZW4gdGhlcmUgaXMgYSBwcmVzZW5jZSBvZiBwcmVjaXBpdGF0aW9uLgoKIyBDb25jbHVzaW9uClRocm91Z2ggb3VyIGFuYWx5c2lzIHZpYSB0aGUgbWVhbnMgb2YgYm90aCBQb2lzc29uIGFuZCBxdWFzaS1Qb2lzc29uIG1vZGVsaW5nIHRlY2huaXF1ZXMsIG91ciBmaW5kaW5ncyB3ZXJlIHJlbGF0aXZlbHkgY29uc2lzdGVudC4gVGhvc2UgYmVpbmcgdGhlIGZvbGxvd2luZzsKCi0gVGhlIE1hbmhhdHRhbiBCcmlkZ2UgaXMgZmFyIGJ1c2llciBkdXJpbmcgdGhlIHdlZWsgdGhhbiBpdCBpcyBvbiB0aGUgd2Vla2VuZC4KLSBBdCBsZWFzdCBpbiB0aGUgbW9udGggb2YgSnVseSwgdGhlIHRlbXBlcmF0dXJlIGRvZXMgbm90IHBsYXkgYW55IHNvcnQgb2Ygc2lnbmlmaWNhbnQgcm9sZSBpbiB0aGUgcmF3IG51bWJlciBvZiB0aGUgYnJpZGdlJ3MgY3ljbGlzdHMgbm9yIGl0cyBzaGFyZSBvZiB0aGUgdG90YWxpdHkgb2YgRWFzdCBSaXZlciBCcmlkZ2UgY3ljbGlzdHMuCi0gQWx0aG91Z2ggdGVtcGVyYXR1cmUgaXMgbm90IHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGN5Y2xpc3QgdHJhZmZpYywgcHJlY2lwaXRhdGlvbiBpcy4gQW55IGFtb3VudCBvZiBwcmVjaXBpdGF0aW9uIGhhcyBhIG5lZ2F0aXZlIGFuZCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCB3aXRoIE1hbmhhdHRhbiBCcmlkZ2UncyBjeWNsaXN0IHRyYWZmaWMuCgpSZWdhcmRpbmcgdGhlIGV4aXN0ZW5jZSBvZiBib3RoIG91ciBQb2lzc29uIGFuZCBxdWFzaS1Qb2lzc29uIG1vZGVscyB0byBlc3RpbWF0ZSB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBhbGwgdGhlc2UgZmFjdG9ycywgdGhlIHF1YXNpLVBvaXNzb24gaXMgbW9yZSBpZGVhbCBkdWUgdG8gdGhpcyBkYXRhc2V0J3MgKmV4dHJlbWVseSogaGlnaCBkaXNwZXJzaW9uIHBhcmFtZXRlciAoJFxoYXR7XHBoaX0kIH4gMTQyKS4gCgpJZiB3ZSB3ZXJlIHRvIGNvbnRpbnVlIG9yIGV4cGFuZCBvbiB0aGlzIGFuYWx5c2lzIGluIHRoZSBmdXR1cmUsIGl0IHdvdWxkIGJlIHZhbHVhYmxlIHRvIGV4cGFuZCB0aGUgc2NvcGUgb2Ygb3VyIGRhdGEgb3V0c2lkZSBvZiB0aGUgbW9udGggb2YgSnVseSBhbmQgaW50byBtb250aHMgdGhhdCBib3JkZXIgb24gc2Vhc29uYWwgY2hhbmdlcyBzdWNoIGFzIE1hcmNoLCBBcHJpbCBvciBPY3RvYmVyLiBJbnR1aXRpdmVseSwgb25lIG1pZ2h0IGd1ZXNzIHRoYXQgdGhlIGRheSdzIHRlbXBlcmF0dXJlcyBwbGF5IGEgbXVjaCBsYXJnZXIgcm9sZSBpbiBhIHRpbWUgb2YgdGhlIHllYXIgbGlrZSB0aGF0LgoKIyBSZWZlcmVuY2VzOgoKT3JpZ2luYWwgRGF0YXNldCBTb3VyY2U6CgotIGh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTMyMS93dzA5L3cwOS1Bc3NpZ25EYXRhU2V0Lnhsc3gKCkRhdGFzZXQgRG93bmxvYWQgTGlua3MgdmlhIEdpdGh1YjoKCi0gaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NocmlzQjIzMjMvU1RBMzIxL3JlZnMvaGVhZHMvbWFpbi9OWUNfQ3ljbGlzdHNfRGF0YS54bHN4