library(tidyverse)
library(lubridate)
library(rdrobust)

The main data source under consideration in this project was acquired from Kaggle, where Kaggle user Abe Caesar Perez had collected a tabular dataset of all historical plane crashes across the world from 1918 to 1922. The primary source of this dataset was the Bureau of Aircraft Accident Archives (B3A), which is an international nonprofit research organzation based in Geneva that aims to conduct research into and publicize institutional knowledge related to aviation accidents in order to reduce their number, frequency, and impact.

The dataset downloaded from Kaggle included information about the aircrafts themselves, the operating companies or organizations (noting that military and government flights are included as well as commercial flights), the flight phase and location at the time of the crash, the passenger and crew manifest, records of fatalities, and the causes of the crashes, if known.

This research project aims to determine if any of these factors, or others, are associated with a greater number of crash incidents or of fatalities. It is important, however, to remember that aviation accidents are themselves quite rare events, and drawing predictions about the general safety of aviation from a dataset that solely investigates accidents would be erroneous - this project does not aim to make predictions about the likelihood of future plane crashes, but to examine the existing record of plane crashes and explore possible causative factors.

plane_crash <- read.csv('plane_crashes.csv')
head(plane_crash, 10)
print(str(plane_crash))
'data.frame':   28536 obs. of  24 variables:
 $ Date            : chr  "1918-05-02" "1918-06-08" "1918-06-11" "1918-06-19" ...
 $ Time            : chr  NA NA NA NA ...
 $ Aircraft        : chr  "De Havilland DH.4" "Handley Page V/1500" "Avro 504" "De Havilland DH.4" ...
 $ Operator        : chr  "United States Signal Corps - USSC" "Handley Page Aircraft Company Ltd" "Royal Air Force - RAF" "United States Signal Corps - USSC" ...
 $ Registration    : chr  "AS-32084" "E4104" "A8544" "AS-32098" ...
 $ Flight.phase    : chr  "Takeoff (climb)" "Takeoff (climb)" "Flight" "Flight" ...
 $ Flight.type     : chr  "Test" "Test" "Training" "Military" ...
 $ Survivors       : chr  "No" "Yes" "Yes" "No" ...
 $ Crash.site      : chr  "Airport (less than 10 km from airport)" "Airport (less than 10 km from airport)" "Plain, Valley" "Airport (less than 10 km from airport)" ...
 $ Schedule        : chr  "Dayton - Dayton" "Cricklewood - Cricklewood" "Abukir - Abukir" "Wright Patterson AFB-Wright Patterson AFB" ...
 $ MSN             : chr  NA NA NA NA ...
 $ YOM             : int  NA 1918 NA NA NA NA NA NA NA 1918 ...
 $ Flight.no.      : logi  NA NA NA NA NA NA ...
 $ Crash.location  : chr  "Dayton-McCook Field Ohio" "Cricklewood London Metropolis" "Abukir (Abu Qir) Alexandria" "Wright-Patterson AFB (Dayton) Ohio" ...
 $ Country         : chr  "United States of America" "United Kingdom" "Egypt" "United States of America" ...
 $ Region          : chr  "North America" "Europe" "Africa" "North America" ...
 $ Crew.on.board   : int  2 6 2 1 NA 1 2 2 2 2 ...
 $ Crew.fatalities : int  2 5 1 1 0 1 2 2 2 0 ...
 $ Pax.on.board    : int  0 0 0 0 NA 0 0 5 0 0 ...
 $ PAX.fatalities  : int  0 0 0 0 0 0 0 5 0 0 ...
 $ Other.fatalities: int  0 0 0 0 0 0 0 0 0 0 ...
 $ Total.fatalities: int  2 5 1 1 0 1 2 7 2 0 ...
 $ Circumstances   : chr  "The single engine airplane departed Dayton-McCook Field for a local test flight. Shortly after takeoff, the air"| __truncated__ "Assembled at Cricklewood Airfield in May 1918, the aircraft departed Cricklewood for its 13th test flight, carr"| __truncated__ "The single engine aircraft was completing a local training flight when it stalled and crashed near Abukir. A cr"| __truncated__ "Lt. Frank Stuart Patterson, son and nephew of the co-founders of National Cash Register, is killed in the crash"| __truncated__ ...
 $ Crash.cause     : chr  "Technical failure" "Technical failure" "Unknown" "Technical failure" ...
NULL
keeps <- c("Date", "Time", "Aircraft", "Operator", "Registration", "Flight.phase", "Flight.type", "Survivors", "Crash.site", "Schedule", "YOM", "Country", "Region", "Crew.on.board", "Crew.fatalities", "Pax.on.board", "PAX.fatalities", "Total.fatalities", "Crash.cause")
plane_crash_update_1 <- subset(plane_crash, select = keeps)
# remove any rows from the data frame with missing data and see how many observations are left: 
crash_data <- plane_crash_update_1[complete.cases(plane_crash_update_1), ]
crash_data$Date <- ymd(crash_data$Date) # convert Date column to date format using the package `lubridate`
crash_data$Crash.cause <- as.factor(crash_data$Crash.cause)
print(str(crash_data))
'data.frame':   11408 obs. of  19 variables:
 $ Date            : Date, format: "1919-05-01" "1919-06-15" ...
 $ Time            : chr  "5H 30M 0S" "8H 40M 0S" "8H 45M 0S" "13H 0M 0S" ...
 $ Aircraft        : chr  "De Havilland DH.9" "Vickers FB.27 Vimy Commercial" "De Havilland DH.4" "Vickers Viking (Serie I/II/III & IV)" ...
 $ Operator        : chr  "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" ...
 $ Registration    : chr  "G-EAAA" "G-EAAR" "G-EAEW" "G-EAOV" ...
 $ Flight.phase    : chr  "Flight" "Landing (descent or approach)" "Landing (descent or approach)" "Flight" ...
 $ Flight.type     : chr  "Postal (mail)" "Private" "Scheduled Revenue Flight" "Positioning" ...
 $ Survivors       : chr  "No" "Yes" "Yes" "No" ...
 $ Crash.site      : chr  "Plain, Valley" "Plain, Valley" "Airport (less than 10 km from airport)" "Plain, Valley" ...
 $ Schedule        : chr  "Hendon - Bournemouth" "Saint John's - Clifden" "Croydon – Newcastle" "Brooklands - Paris" ...
 $ YOM             : int  1919 1919 1919 1919 1919 1920 1919 1919 1920 1920 ...
 $ Country         : chr  "United Kingdom" "Ireland" "United Kingdom" "France" ...
 $ Region          : chr  "Europe" "Europe" "Europe" "Europe" ...
 $ Crew.on.board   : int  1 2 1 1 4 1 4 1 1 0 ...
 $ Crew.fatalities : int  1 0 1 1 0 0 0 0 0 0 ...
 $ Pax.on.board    : int  0 0 1 0 1 3 3 2 0 0 ...
 $ PAX.fatalities  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Total.fatalities: int  1 0 1 1 0 0 0 0 0 0 ...
 $ Crash.cause     : Factor w/ 6 levels "Human factor",..: 5 5 3 5 3 3 1 3 3 5 ...
NULL
crash_hours <- vector()
crash_minutes <- vector()
for (row in 1:nrow(crash_data)) {
  hour <- str_split_i(crash_data[row,2], " ", 1)
  new_hour <- gsub('[H]', '', hour)
  minute <- str_split_i(crash_data[row,2], " ", 2)
  new_minute <- gsub('[M]', '', minute)
  crash_hours <- c(crash_hours, as.numeric(new_hour))
  crash_minutes <- c(crash_minutes, as.numeric(new_minute))
}

crash_data$Hour <- crash_hours
crash_data$Minute <- crash_minutes
print(str(crash_data))
'data.frame':   11408 obs. of  21 variables:
 $ Date            : Date, format: "1919-05-01" "1919-06-15" ...
 $ Time            : chr  "5H 30M 0S" "8H 40M 0S" "8H 45M 0S" "13H 0M 0S" ...
 $ Aircraft        : chr  "De Havilland DH.9" "Vickers FB.27 Vimy Commercial" "De Havilland DH.4" "Vickers Viking (Serie I/II/III & IV)" ...
 $ Operator        : chr  "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" ...
 $ Registration    : chr  "G-EAAA" "G-EAAR" "G-EAEW" "G-EAOV" ...
 $ Flight.phase    : chr  "Flight" "Landing (descent or approach)" "Landing (descent or approach)" "Flight" ...
 $ Flight.type     : chr  "Postal (mail)" "Private" "Scheduled Revenue Flight" "Positioning" ...
 $ Survivors       : chr  "No" "Yes" "Yes" "No" ...
 $ Crash.site      : chr  "Plain, Valley" "Plain, Valley" "Airport (less than 10 km from airport)" "Plain, Valley" ...
 $ Schedule        : chr  "Hendon - Bournemouth" "Saint John's - Clifden" "Croydon – Newcastle" "Brooklands - Paris" ...
 $ YOM             : int  1919 1919 1919 1919 1919 1920 1919 1919 1920 1920 ...
 $ Country         : chr  "United Kingdom" "Ireland" "United Kingdom" "France" ...
 $ Region          : chr  "Europe" "Europe" "Europe" "Europe" ...
 $ Crew.on.board   : int  1 2 1 1 4 1 4 1 1 0 ...
 $ Crew.fatalities : int  1 0 1 1 0 0 0 0 0 0 ...
 $ Pax.on.board    : int  0 0 1 0 1 3 3 2 0 0 ...
 $ PAX.fatalities  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Total.fatalities: int  1 0 1 1 0 0 0 0 0 0 ...
 $ Crash.cause     : Factor w/ 6 levels "Human factor",..: 5 5 3 5 3 3 1 3 3 5 ...
 $ Hour            : num  5 8 8 13 14 22 15 16 20 12 ...
 $ Minute          : num  30 40 45 0 0 30 0 30 45 0 ...
NULL
years <- vector()
months <- vector()
for (row in 1:nrow(crash_data)) {
  year <- format(crash_data[row,1], "%Y")
  month <- format(crash_data[row,1], "%m")
  years <- c(years, as.numeric(year))
  months <- c(months, as.numeric(month))
}

crash_data$Year <- years
crash_data$Month <- months

print(str(crash_data))
'data.frame':   11408 obs. of  23 variables:
 $ Date            : Date, format: "1919-05-01" "1919-06-15" ...
 $ Time            : chr  "5H 30M 0S" "8H 40M 0S" "8H 45M 0S" "13H 0M 0S" ...
 $ Aircraft        : chr  "De Havilland DH.9" "Vickers FB.27 Vimy Commercial" "De Havilland DH.4" "Vickers Viking (Serie I/II/III & IV)" ...
 $ Operator        : chr  "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" "Aircraft Transport %26 Travel - AT%26T" "Vickers-Armstrongs Ltd" ...
 $ Registration    : chr  "G-EAAA" "G-EAAR" "G-EAEW" "G-EAOV" ...
 $ Flight.phase    : chr  "Flight" "Landing (descent or approach)" "Landing (descent or approach)" "Flight" ...
 $ Flight.type     : chr  "Postal (mail)" "Private" "Scheduled Revenue Flight" "Positioning" ...
 $ Survivors       : chr  "No" "Yes" "Yes" "No" ...
 $ Crash.site      : chr  "Plain, Valley" "Plain, Valley" "Airport (less than 10 km from airport)" "Plain, Valley" ...
 $ Schedule        : chr  "Hendon - Bournemouth" "Saint John's - Clifden" "Croydon – Newcastle" "Brooklands - Paris" ...
 $ YOM             : int  1919 1919 1919 1919 1919 1920 1919 1919 1920 1920 ...
 $ Country         : chr  "United Kingdom" "Ireland" "United Kingdom" "France" ...
 $ Region          : chr  "Europe" "Europe" "Europe" "Europe" ...
 $ Crew.on.board   : int  1 2 1 1 4 1 4 1 1 0 ...
 $ Crew.fatalities : int  1 0 1 1 0 0 0 0 0 0 ...
 $ Pax.on.board    : int  0 0 1 0 1 3 3 2 0 0 ...
 $ PAX.fatalities  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Total.fatalities: int  1 0 1 1 0 0 0 0 0 0 ...
 $ Crash.cause     : Factor w/ 6 levels "Human factor",..: 5 5 3 5 3 3 1 3 3 5 ...
 $ Hour            : num  5 8 8 13 14 22 15 16 20 12 ...
 $ Minute          : num  30 40 45 0 0 30 0 30 45 0 ...
 $ Year            : num  1919 1919 1919 1919 1920 ...
 $ Month           : num  5 6 10 12 2 6 6 7 8 11 ...
NULL

In this next section, the relationship between number of total fatalities and the different crash causes and flight phases are considered. The first step is to pull vectors of fatality numbers for each crash cause from the full crash_data dataframe. These are pulled and named below. The number of crashes in the dataset (with complete details) for each crash cause can also be determined in this step.

fatalities_technical <- crash_data$Total.fatalities[crash_data$Crash.cause == "Technical failure"]
print(length(fatalities_technical))
[1] 2617
fatalities_weather <- crash_data$Total.fatalities[crash_data$Crash.cause == "Weather"]
print(length(fatalities_weather))
[1] 685
fatalities_unknown <- crash_data$Total.fatalities[crash_data$Crash.cause == "Unknown"]
print(length(fatalities_unknown))
[1] 1273
fatalities_sabotage <- crash_data$Total.fatalities[crash_data$Crash.cause == "Terrorism act, Hijacking, Sabotage"]
print(length(fatalities_sabotage))
[1] 198
fatalities_human <- crash_data$Total.fatalities[crash_data$Crash.cause == "Human factor"]
print(length(fatalities_human))
[1] 6342
fatalities_other <- crash_data$Total.fatalities[crash_data$Crash.cause == "Other causes"]
print(length(fatalities_other))
[1] 293

In this dataset, considering only the crashes that contain full details (no missing data), we have records of 2617 crashes caused by “Technical failure”, 685 crashes caused by “Weather”, 1273 crashes with “Unknown” causes, 198 crashes caused by “Terrorism, Hijacking, Sabotage”, 6342 crashes caused by “Human factors”, and 293 crashes with some other cause not stated previously (“Other causes”).

library(plotly)
p2 <- ggplot(crash_data, aes(x=Crash.cause, y=Total.fatalities, fill = Crash.cause)) + geom_boxplot() + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) + ylim(0,100) + theme(legend.position="none") + labs(title = "Figure 1: Distributions of Fatality Counts by Crash Cause", x = "Stated Cause of Crash", y = "Total fatality count")
ggplotly(p2)
Warning: Removed 194 rows containing non-finite outside the scale range
(`stat_boxplot()`).

These are all highly right-skewed distributions, where most of the numbers of total fatalities are closer to zero (less than 10 in all causes!) with many outliers at the higher end of the distribution, meaning that a comparison of the medians is a more robust statistic than comparing averages, as median values are more stable in the presence of outliers than mean values. The distribution of crash fatality counts for crashes caused by “Terrorism, Hijacking or Sabotage” appear to have higher fatality counts than crashes with other causes, with “Weather”-caused crashes having the next highest IQR according to the boxplots shown above.

The next section conducts a test of the medians of these distributions to determine if the fatality counts for “Terrorism, Hijacking, Sabotage-caused crashes are actually significantly different than the median of crashes with all other causes. The coin library includes a non-parametric median hypothesis test used to determine if there are significant differences in the median values between two or more independent samples. The following hypotheses and assumptions are used in this test:

Null Hypothesis (H0): The medians of all groups are equal.

Alternative Hypothesis (H1): At least one of the medians is different from the others.

Assumptions: (1) Independence of samples, (2) Data is ordinal or continuous (3) Random sampling

library(coin)
Loading required package: survival
median_test_result <- median_test(Total.fatalities ~ Crash.cause, data = crash_data)
pvalue <- pvalue(median_test_result)
print(pvalue)
[1] <2.220446e-16

Based on the p-value of the median test, the null hypothesis is rejected, and there are significant differences in the medians of the distributions of fatality counts for crashes with different causes - most likely the higher median for crashes caused by “Terrorism, Hijacking, Sabotage” as observed in the side-by-side boxplots above (Figure 1). This of course aligns with expectations; in aviation crashes with accidental origins - such as technical failures, human error, or weather - the flight crew on board would be taking action to minimize expected harm during a crash landing.

Plot data over time for United States of America to investigate use of RDA

The plot of annual plane crash fatalities in the United States from 1919-2022 shows a marked increasing rate of crash fatalities for roughly the first 60 years of this time period, and decreasing since 1980. The US annual fatalities data will be used for Regression Discontinuity Analysis (RDA) with a cutpoint at 1980, and will consider significance of changes in the distribution of plane crash fatalities before and after this cutpoint. There is also a distinct outlier in 2001, corresponding to the 2001 9-11 terror attacks which involved the hijacking and purposeful crash of four passenger flights in the eastern US. This outlier may be removed in further analysis.

Plot data with cutpoint

In addition, adding the regression lines before and after the cutpoint will further help determine what type of RDA should be applied.

ggplotly(crash_plot_cp_lm)  # display plot
`geom_smooth()` using formula = 'y ~ x'

The scatter plot with regression lines as shown reinforces that these groupings present a good candidate for RDA. The before- and after-groups show a change in slope of the regression line (positive before 1980, negative after 1980) and a change in the intercept with the cutpoint (higher intercept for the regression model with the cutpoint before 1980, lower intercept with the cutpoint after 1980).

The RDA package rdrobust enables an RDA that tests whether the slopes of the regression lines within a bandwidth on either side of the cutpoint are significantly different. To install rdrobust, use install.packages("rdrobust").

Regression Discontinuity Analysis with rdrobust

Select bandwidth

bandwidths$bws #show the bandwidths
      h (left) h (right) b (left) b (right)
mserd 13.78192  13.78192 21.58261  21.58261

h, the main bandwidth, is +/- 13.78192 years b, the bias bandwidth, is +/- 21.58261 years. This bandwidth is used for both the bias-corrected and robust estimators when RDA is performed with rdrobust.

Let’s create a new plot showing the bandwidths as designated.

Plot data with bandwidths showing

bw
[1] 13.78192
ggplotly(p6)
`geom_smooth()` using formula = 'y ~ x'

Plotting the regression models for solely the data points within the bandwidth around 1980 shows that the change in slope from positive (before 1980) to negative (after 1980) still holds. Performing the RDA will determine whether this difference is statistically significant and, thus, whether there was a significant change in airplane crash fatality counts in the United States before and after 1980.

Perform RDA before/after 1980

print(rda_v1)
Call: rdrobust

Number of Obs.                   97
BW type                       mserd
Kernel                   Triangular
VCE method                       NN

Number of Obs.                   54           43
Eff. Number of Obs.              13           14
Order est. (p)                    1            1
Order bias  (q)                   2            2
BW est. (h)                  13.782       13.782
BW bias (b)                  21.583       21.583
rho (h/b)                     0.639        0.639
Unique Obs.                      54           43

Printing the rda shows that there are a total of 54 observations before the cutpoint and 43 observations after the cutpoint. The Effective Number of Observations demonstrates that 13 observations were within the bandwidth to the left of the cutpoint and 14 observations were within the bandwidth to the right of the cutpoint.

str(rda_v1)
List of 32
 $ Estimate  : num [1, 1:4] -149 -179 108 128
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:4] "tau.us" "tau.bc" "se.us" "se.rb"
 $ bws       : num [1:2, 1:2] 13.8 21.6 13.8 21.6
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:2] "h" "b"
  .. ..$ : chr [1:2] "left" "right"
 $ coef      : num [1:3, 1] -149 -179 -179
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Conventional" "Bias-Corrected" "Robust"
  .. ..$ : chr "Coeff"
 $ se        : num [1:3, 1] 108 108 128
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Conventional" "Bias-Corrected" "Robust"
  .. ..$ : chr "Std. Err."
 $ z         : num [1:3, 1] -1.38 -1.67 -1.4
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Conventional" "Bias-Corrected" "Robust"
  .. ..$ : chr "z"
 $ pv        : num [1:3, 1] 0.1664 0.0951 0.1606
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Conventional" "Bias-Corrected" "Robust"
  .. ..$ : chr "P>|z|"
 $ ci        : num [1:3, 1:2] -359.6 -390.3 -430.2 61.9 31.3 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Conventional" "Bias-Corrected" "Robust"
  .. ..$ : chr [1:2] "CI Lower" "CI Upper"
 $ beta_Y_p_l: num [1:2] 429 13
 $ beta_Y_p_r: num [1:2] 279.811 -0.772
 $ V_cl_l    : num [1:2, 1:2] 8004 987 987 128
 $ V_cl_r    : num [1:2, 1:2] 3560.3 -376.1 -376.1 57.1
 $ V_rb_l    : num [1:2, 1:2] 12137 2394 2394 507
 $ V_rb_r    : num [1:2, 1:2] 4228 -715 -715 207
 $ N         : int [1:2] 54 43
 $ N_h       : int [1:2] 13 14
 $ N_b       : int [1:2] 21 22
 $ M         : int [1:2] 54 43
 $ tau_cl    : num [1:2] 429 280
 $ tau_bc    : num [1:2] 452 272
 $ c         : num 1980
 $ p         : num 1
 $ q         : num 2
 $ bias      : num [1:2] -23.07 7.61
 $ kernel    : chr "Triangular"
 $ all       : NULL
 $ vce       : chr "NN"
 $ bwselect  : chr "mserd"
 $ level     : num 95
 $ masspoints: chr "adjust"
 $ rdmodel   : chr "Sharp RD estimates using local polynomial regression."
 $ beta_covs : NULL
 $ call      : language rdrobust(y = annual_crash_fatalities_usa$total_fatalities, x = annual_crash_fatalities_usa$Year,      c = cutpoint)
 - attr(*, "class")= chr "rdrobust"

Looking at the structure of the rda results object shows where the other important outputs are stored. Checking the coefficient, p-value, and standard error will indicate the size of the treatment effect (grouping into before and after 1980) and whether the effect was statistically significant.

Check the coefficients:

rda_v1$coef
                   Coeff
Conventional   -148.8218
Bias-Corrected -179.4990
Robust         -179.4990

The regression slope (within the bandwidth) before the cutpoint was 148.8218 less than the slope after the cutpoint. When the larger (bias or b) bandwidth was used (21.583 years instead of 13.782 years), the difference in slopes before and after the cutpoint was larger (179.4990).

The standard error of the coefficient gives an indication of how meaningful this difference is:

rda_v1$se
               Std. Err.
Conventional    107.5366
Bias-Corrected  107.5366
Robust          127.9225

-148.8218 +/- a standard error of 107.5366 does not lead to a difference equal to or close to zero. Thus, even when taking the standard error into account, there is still a relatively large difference in the regression slopes before and after the cutpoint.

The p-value will indicate whether this difference is statistically significant:

rda_v1$pv
                    P>|z|
Conventional   0.16638353
Bias-Corrected 0.09507959
Robust         0.16056156

Here, the p-value being larger than the standard significance level of 0.05 indicates that the difference in regression slopes before and after the cutpoint, but within the bandwidth, is not statistically significant.

Repeat RDA removing the 2001 9-11 terror attack fatality counts as an outlier

bw_v2
[1] 15.66757
ggplotly(p9)
`geom_smooth()` using formula = 'y ~ x'
print(rda_v2)
Call: rdrobust

Number of Obs.                   96
BW type                       mserd
Kernel                   Triangular
VCE method                       NN

Number of Obs.                   54           42
Eff. Number of Obs.              15           16
Order est. (p)                    1            1
Order bias  (q)                   2            2
BW est. (h)                  15.668       15.668
BW bias (b)                  25.230       25.230
rho (h/b)                     0.621        0.621
Unique Obs.                      54           42

<!-- rnb-source-end -->


<!-- rnb-output-end -->

<!-- rnb-output-begin eyJkYXRhIjoiRXJyb3I6IGF0dGVtcHQgdG8gdXNlIHplcm8tbGVuZ3RoIHZhcmlhYmxlIG5hbWVcbiJ9 -->

Error: attempt to use zero-length variable name




<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Check the coefficients:

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVjbVJoWDNZeUpHTnZaV1pjYmx4dVlHQmdJbjA9IC0tPlxuXG5gYGByXG5yZGFfdjIkY29lZlxuXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxucmRhX3YyJGNvZWZcblxuYGBgIn0= -->

```r
rda_v2$coef
                   Coeff
Conventional   -138.8252
Bias-Corrected -170.7526
Robust         -170.7526

The regression slope (within the bandwidth) before the cutpoint was 138.8252 less than the slope after the cutpoint. When the larger (bias or b) bandwidth was used (25.230 years instead of 15.668 years), the difference in slopes before and after the cutpoint was larger (170.7526).

The standard error of the coefficient gives an indication of how meaningful this difference is:

rda_v2$se
               Std. Err.
Conventional    100.3321
Bias-Corrected  100.3321
Robust          118.0563

-138.8252 +/- a standard error of 100.3321 does not lead to a difference equal to or close to zero. Thus, even when taking the standard error into account, there is still a relatively large difference in the regression slopes before and after the cutpoint.

The p-value will indicate whether this difference is statistically significant:

rda_v2$pv
                   P>|z|
Conventional   0.1664637
Bias-Corrected 0.0887791
Robust         0.1480745

About the same as the first analysis. So, excluding 9-11 as an outlier did not lead to a significant result.

Final analysis - include 9-11, but make 2001 the cutpoint!

Our final RDA will reset the cutpoint to 2001, since air travel and air travel safety procedures changed in many ways after the events of the 9-11 terror attacks.

Repeat the process of grouping the data into before/after 2001, and determining the appropriate bandwidth around this year for RDA.

ggplotly(p11)  # display plot
`geom_smooth()` using formula = 'y ~ x'

The before- and after-groups show a change in slope of the regression line (positive but smaller magnitude, flatter slope, before 2001, negative with steeper slope after 2001) and a change in the intercept with the cutpoint (higher intercept for the regression model with the cutpoint before 2001, lower intercept with the cutpoint after 2001).

RDA before/after 9-11

Use library(robust) to determine bandwidths for RDA around cutpoint at 2001.

bandwidths_v3$bws #show the bandwidths
      h (left) h (right) b (left) b (right)
mserd 8.970999  8.970999 13.38957  13.38957

h, the main bandwidth, is +/- 8.970999 years b, the bias bandwidth, is +/- 13.38957 years. This bandwidth is used for both the bias-corrected and robust estimators when RDA is performed with rdrobust.

Let’s create a new plot showing the bandwidths as designated.

Plot data with bandwidths showing

bw_v3
[1] 8.970999
ggplotly(p12)
`geom_smooth()` using formula = 'y ~ x'
print(rda_v3)
Call: rdrobust

Number of Obs.                   97
BW type                       mserd
Kernel                   Triangular
VCE method                       NN

Number of Obs.                   75           22
Eff. Number of Obs.               8            9
Order est. (p)                    1            1
Order bias  (q)                   2            2
BW est. (h)                   8.971        8.971
BW bias (b)                  13.390       13.390
rho (h/b)                     0.670        0.670
Unique Obs.                      75           22

Check the coefficients:

rda_v3$coef
                  Coeff
Conventional   272.8299
Bias-Corrected 338.8700
Robust         338.8700

The regression slope (within the bandwidth) before the cutpoint was 272.829 more than the slope after the cutpoint. When the larger (bias or b) bandwidth was used (13.390 years instead of 8.971 years), the difference in slopes before and after the cutpoint was larger (338.8700).

The standard error of the coefficient gives an indication of how meaningful this difference is:

rda_v3$se
               Std. Err.
Conventional    253.6951
Bias-Corrected  253.6951
Robust          302.8105

The p-value will indicate whether this difference is statistically significant:

rda_v3$pv
                   P>|z|
Conventional   0.2821848
Bias-Corrected 0.1816352
Robust         0.2631047

Here, the p-value being larger than the standard significance level of 0.05 indicates that the difference in regression slopes before and after the cutpoint, but within the bandwidth, is not statistically significant.

This is somewhat surprising, given the great labor and analytical effort to improve airline safety in the US following the 9-11 attacks, however with closer examination of Fig. 12 above it can be observed that in the decade leading up to 9-11 (within the ~9 year bandwidth), the airline crash fatality counts were already trending downward for that time period, and that the 2001 outlier value with extremely high airline crash fatality counts was indeed still an outlier for the data within the bandwidth before the 2001 cutpoint.

Thus, the improvement in airline safety and reduction in crash fatalities that has been observed since the mid-1970s cannot be associated directly with the time period following the 2001 9-11 terror attacks, and likely has causes with effects spread out in time, such as a gradual improvement in radar and sensor technology that led to better flight path management, and engineering developments that made unscheduled landings less destructive to the aircraft and crew/passengers onboard.

Further research into key innovations in air travel safety technology and air traffic control systems could reveal a more suitable cutpoint selection that does lead to a significant before/after change in airline crash fatalities, which we do indeed observe in the rising and falling fatality counts graphs from Fig. 2 to Fig. 12. Additional investigation into the rate of plane crash incidents (relative to the number of “successful” flights) could also show a similar rising/falling pattern worth investigating, or may show a consistent decline in the rate of plane crashes with fatalities and no additional temporal changes. Research consistently shows that air travel is far safer than other forms of travel, so focusing on the rare outcomes of crashes presents on its face a difficult challenge due to the limitated observational record of such incidents.

LS0tCnRpdGxlOiAiRmFjdG9ycyBsaW5rZWQgdG8gcGxhbmUgY3Jhc2hlcyBzaW5jZSAxOTE5IgpzdWJ0aXRsZTogIkEgZGF0YSBhbmFseXNpcywgZGF0YSB2aXN1YWxpemF0aW9uLCBhbmQgY2F1c2FsIGluZmVyZW5jZSBwcm9qZWN0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKYGBge3IgbG9hZCBwYWNrYWdlcywgbWVzc2FnZSA9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShyZHJvYnVzdCkKYGBgCgpUaGUgbWFpbiBkYXRhIHNvdXJjZSB1bmRlciBjb25zaWRlcmF0aW9uIGluIHRoaXMgcHJvamVjdCB3YXMgYWNxdWlyZWQgZnJvbSBbS2FnZ2xlXShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2FiZXBlcmV6L2hpc3RvcmljYWwtcGxhbmUtY3Jhc2gtZGF0YT9yZXNvdXJjZT1kb3dubG9hZCksIHdoZXJlIEthZ2dsZSB1c2VyIEFiZSBDYWVzYXIgUGVyZXogaGFkIGNvbGxlY3RlZCBhIHRhYnVsYXIgZGF0YXNldCBvZiBhbGwgaGlzdG9yaWNhbCBwbGFuZSBjcmFzaGVzIGFjcm9zcyB0aGUgd29ybGQgZnJvbSAxOTE4IHRvIDE5MjIuIFRoZSBwcmltYXJ5IHNvdXJjZSBvZiB0aGlzIGRhdGFzZXQgd2FzIHRoZSBCdXJlYXUgb2YgQWlyY3JhZnQgQWNjaWRlbnQgQXJjaGl2ZXMgKEIzQSksIHdoaWNoIGlzIGFuIGludGVybmF0aW9uYWwgbm9ucHJvZml0IHJlc2VhcmNoIG9yZ2FuemF0aW9uIGJhc2VkIGluIEdlbmV2YSB0aGF0IGFpbXMgdG8gY29uZHVjdCByZXNlYXJjaCBpbnRvIGFuZCBwdWJsaWNpemUgaW5zdGl0dXRpb25hbCBrbm93bGVkZ2UgcmVsYXRlZCB0byBhdmlhdGlvbiBhY2NpZGVudHMgaW4gb3JkZXIgdG8gcmVkdWNlIHRoZWlyIG51bWJlciwgZnJlcXVlbmN5LCBhbmQgaW1wYWN0LiAKClRoZSBkYXRhc2V0IGRvd25sb2FkZWQgZnJvbSBLYWdnbGUgaW5jbHVkZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGFpcmNyYWZ0cyB0aGVtc2VsdmVzLCB0aGUgb3BlcmF0aW5nIGNvbXBhbmllcyBvciBvcmdhbml6YXRpb25zIChub3RpbmcgdGhhdCBtaWxpdGFyeSBhbmQgZ292ZXJubWVudCBmbGlnaHRzIGFyZSBpbmNsdWRlZCBhcyB3ZWxsIGFzIGNvbW1lcmNpYWwgZmxpZ2h0cyksIHRoZSBmbGlnaHQgcGhhc2UgYW5kIGxvY2F0aW9uIGF0IHRoZSB0aW1lIG9mIHRoZSBjcmFzaCwgdGhlIHBhc3NlbmdlciBhbmQgY3JldyBtYW5pZmVzdCwgcmVjb3JkcyBvZiBmYXRhbGl0aWVzLCBhbmQgdGhlIGNhdXNlcyBvZiB0aGUgY3Jhc2hlcywgaWYga25vd24uIAoKVGhpcyByZXNlYXJjaCBwcm9qZWN0IGFpbXMgdG8gZGV0ZXJtaW5lIGlmIGFueSBvZiB0aGVzZSBmYWN0b3JzLCBvciBvdGhlcnMsIGFyZSBhc3NvY2lhdGVkIHdpdGggYSBncmVhdGVyIG51bWJlciBvZiBjcmFzaCBpbmNpZGVudHMgb3Igb2YgZmF0YWxpdGllcy4gSXQgaXMgaW1wb3J0YW50LCBob3dldmVyLCB0byByZW1lbWJlciB0aGF0IGF2aWF0aW9uIGFjY2lkZW50cyBhcmUgdGhlbXNlbHZlcyBxdWl0ZSByYXJlIGV2ZW50cywgYW5kIGRyYXdpbmcgcHJlZGljdGlvbnMgYWJvdXQgdGhlIGdlbmVyYWwgc2FmZXR5IG9mIGF2aWF0aW9uIGZyb20gYSBkYXRhc2V0IHRoYXQgc29sZWx5IGludmVzdGlnYXRlcyBhY2NpZGVudHMgd291bGQgYmUgZXJyb25lb3VzIC0gdGhpcyBwcm9qZWN0IGRvZXMgbm90IGFpbSB0byBtYWtlIHByZWRpY3Rpb25zIGFib3V0IHRoZSBsaWtlbGlob29kIG9mIGZ1dHVyZSBwbGFuZSBjcmFzaGVzLCBidXQgdG8gZXhhbWluZSB0aGUgZXhpc3RpbmcgcmVjb3JkIG9mIHBsYW5lIGNyYXNoZXMgYW5kIGV4cGxvcmUgcG9zc2libGUgY2F1c2F0aXZlIGZhY3RvcnMuIAoKYGBge3J9CnBsYW5lX2NyYXNoIDwtIHJlYWQuY3N2KCdwbGFuZV9jcmFzaGVzLmNzdicpCmhlYWQocGxhbmVfY3Jhc2gsIDEwKQpgYGAKYGBge3J9CnByaW50KHN0cihwbGFuZV9jcmFzaCkpCmBgYAoKCmBgYHtyfQprZWVwcyA8LSBjKCJEYXRlIiwgIlRpbWUiLCAiQWlyY3JhZnQiLCAiT3BlcmF0b3IiLCAiUmVnaXN0cmF0aW9uIiwgIkZsaWdodC5waGFzZSIsICJGbGlnaHQudHlwZSIsICJTdXJ2aXZvcnMiLCAiQ3Jhc2guc2l0ZSIsICJTY2hlZHVsZSIsICJZT00iLCAiQ291bnRyeSIsICJSZWdpb24iLCAiQ3Jldy5vbi5ib2FyZCIsICJDcmV3LmZhdGFsaXRpZXMiLCAiUGF4Lm9uLmJvYXJkIiwgIlBBWC5mYXRhbGl0aWVzIiwgIlRvdGFsLmZhdGFsaXRpZXMiLCAiQ3Jhc2guY2F1c2UiKQpwbGFuZV9jcmFzaF91cGRhdGVfMSA8LSBzdWJzZXQocGxhbmVfY3Jhc2gsIHNlbGVjdCA9IGtlZXBzKQojIHJlbW92ZSBhbnkgcm93cyBmcm9tIHRoZSBkYXRhIGZyYW1lIHdpdGggbWlzc2luZyBkYXRhIGFuZCBzZWUgaG93IG1hbnkgb2JzZXJ2YXRpb25zIGFyZSBsZWZ0OiAKY3Jhc2hfZGF0YSA8LSBwbGFuZV9jcmFzaF91cGRhdGVfMVtjb21wbGV0ZS5jYXNlcyhwbGFuZV9jcmFzaF91cGRhdGVfMSksIF0KYGBgCmBgYHtyfQpjcmFzaF9kYXRhJERhdGUgPC0geW1kKGNyYXNoX2RhdGEkRGF0ZSkgIyBjb252ZXJ0IERhdGUgY29sdW1uIHRvIGRhdGUgZm9ybWF0IHVzaW5nIHRoZSBwYWNrYWdlIGBsdWJyaWRhdGVgCmBgYApgYGB7cn0KY3Jhc2hfZGF0YSRDcmFzaC5jYXVzZSA8LSBhcy5mYWN0b3IoY3Jhc2hfZGF0YSRDcmFzaC5jYXVzZSkKcHJpbnQoc3RyKGNyYXNoX2RhdGEpKQpgYGAKCgpgYGB7ciwgbWVzc2FnZSA9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmNyYXNoX2hvdXJzIDwtIHZlY3RvcigpCmNyYXNoX21pbnV0ZXMgPC0gdmVjdG9yKCkKZm9yIChyb3cgaW4gMTpucm93KGNyYXNoX2RhdGEpKSB7CiAgaG91ciA8LSBzdHJfc3BsaXRfaShjcmFzaF9kYXRhW3JvdywyXSwgIiAiLCAxKQogIG5ld19ob3VyIDwtIGdzdWIoJ1tIXScsICcnLCBob3VyKQogIG1pbnV0ZSA8LSBzdHJfc3BsaXRfaShjcmFzaF9kYXRhW3JvdywyXSwgIiAiLCAyKQogIG5ld19taW51dGUgPC0gZ3N1YignW01dJywgJycsIG1pbnV0ZSkKICBjcmFzaF9ob3VycyA8LSBjKGNyYXNoX2hvdXJzLCBhcy5udW1lcmljKG5ld19ob3VyKSkKICBjcmFzaF9taW51dGVzIDwtIGMoY3Jhc2hfbWludXRlcywgYXMubnVtZXJpYyhuZXdfbWludXRlKSkKfQoKY3Jhc2hfZGF0YSRIb3VyIDwtIGNyYXNoX2hvdXJzCmNyYXNoX2RhdGEkTWludXRlIDwtIGNyYXNoX21pbnV0ZXMKcHJpbnQoc3RyKGNyYXNoX2RhdGEpKQpgYGAKYGBge3IsIG1lc3NhZ2UgPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp5ZWFycyA8LSB2ZWN0b3IoKQptb250aHMgPC0gdmVjdG9yKCkKZm9yIChyb3cgaW4gMTpucm93KGNyYXNoX2RhdGEpKSB7CiAgeWVhciA8LSBmb3JtYXQoY3Jhc2hfZGF0YVtyb3csMV0sICIlWSIpCiAgbW9udGggPC0gZm9ybWF0KGNyYXNoX2RhdGFbcm93LDFdLCAiJW0iKQogIHllYXJzIDwtIGMoeWVhcnMsIGFzLm51bWVyaWMoeWVhcikpCiAgbW9udGhzIDwtIGMobW9udGhzLCBhcy5udW1lcmljKG1vbnRoKSkKfQoKY3Jhc2hfZGF0YSRZZWFyIDwtIHllYXJzCmNyYXNoX2RhdGEkTW9udGggPC0gbW9udGhzCgpwcmludChzdHIoY3Jhc2hfZGF0YSkpCmBgYAoKSW4gdGhpcyBuZXh0IHNlY3Rpb24sIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBudW1iZXIgb2YgdG90YWwgZmF0YWxpdGllcyBhbmQgdGhlIGRpZmZlcmVudCBjcmFzaCBjYXVzZXMgYW5kIGZsaWdodCBwaGFzZXMgYXJlIGNvbnNpZGVyZWQuIFRoZSBmaXJzdCBzdGVwIGlzIHRvIHB1bGwgdmVjdG9ycyBvZiBmYXRhbGl0eSBudW1iZXJzIGZvciBlYWNoIGNyYXNoIGNhdXNlIGZyb20gdGhlIGZ1bGwgYGNyYXNoX2RhdGFgIGRhdGFmcmFtZS4gVGhlc2UgYXJlIHB1bGxlZCBhbmQgbmFtZWQgYmVsb3cuIFRoZSBudW1iZXIgb2YgY3Jhc2hlcyBpbiB0aGUgZGF0YXNldCAod2l0aCBjb21wbGV0ZSBkZXRhaWxzKSBmb3IgZWFjaCBjcmFzaCBjYXVzZSBjYW4gYWxzbyBiZSBkZXRlcm1pbmVkIGluIHRoaXMgc3RlcC4gCgpgYGB7cn0KZmF0YWxpdGllc190ZWNobmljYWwgPC0gY3Jhc2hfZGF0YSRUb3RhbC5mYXRhbGl0aWVzW2NyYXNoX2RhdGEkQ3Jhc2guY2F1c2UgPT0gIlRlY2huaWNhbCBmYWlsdXJlIl0KcHJpbnQobGVuZ3RoKGZhdGFsaXRpZXNfdGVjaG5pY2FsKSkKZmF0YWxpdGllc193ZWF0aGVyIDwtIGNyYXNoX2RhdGEkVG90YWwuZmF0YWxpdGllc1tjcmFzaF9kYXRhJENyYXNoLmNhdXNlID09ICJXZWF0aGVyIl0KcHJpbnQobGVuZ3RoKGZhdGFsaXRpZXNfd2VhdGhlcikpCmZhdGFsaXRpZXNfdW5rbm93biA8LSBjcmFzaF9kYXRhJFRvdGFsLmZhdGFsaXRpZXNbY3Jhc2hfZGF0YSRDcmFzaC5jYXVzZSA9PSAiVW5rbm93biJdCnByaW50KGxlbmd0aChmYXRhbGl0aWVzX3Vua25vd24pKQpmYXRhbGl0aWVzX3NhYm90YWdlIDwtIGNyYXNoX2RhdGEkVG90YWwuZmF0YWxpdGllc1tjcmFzaF9kYXRhJENyYXNoLmNhdXNlID09ICJUZXJyb3Jpc20gYWN0LCBIaWphY2tpbmcsIFNhYm90YWdlIl0KcHJpbnQobGVuZ3RoKGZhdGFsaXRpZXNfc2Fib3RhZ2UpKQpmYXRhbGl0aWVzX2h1bWFuIDwtIGNyYXNoX2RhdGEkVG90YWwuZmF0YWxpdGllc1tjcmFzaF9kYXRhJENyYXNoLmNhdXNlID09ICJIdW1hbiBmYWN0b3IiXQpwcmludChsZW5ndGgoZmF0YWxpdGllc19odW1hbikpCmZhdGFsaXRpZXNfb3RoZXIgPC0gY3Jhc2hfZGF0YSRUb3RhbC5mYXRhbGl0aWVzW2NyYXNoX2RhdGEkQ3Jhc2guY2F1c2UgPT0gIk90aGVyIGNhdXNlcyJdCnByaW50KGxlbmd0aChmYXRhbGl0aWVzX290aGVyKSkKYGBgCkluIHRoaXMgZGF0YXNldCwgY29uc2lkZXJpbmcgb25seSB0aGUgY3Jhc2hlcyB0aGF0IGNvbnRhaW4gZnVsbCBkZXRhaWxzIChubyBtaXNzaW5nIGRhdGEpLCB3ZSBoYXZlIHJlY29yZHMgb2YgMjYxNyBjcmFzaGVzIGNhdXNlZCBieSAiVGVjaG5pY2FsIGZhaWx1cmUiLCA2ODUgY3Jhc2hlcyBjYXVzZWQgYnkgIldlYXRoZXIiLCAxMjczIGNyYXNoZXMgd2l0aCAiVW5rbm93biIgY2F1c2VzLCAxOTggY3Jhc2hlcyBjYXVzZWQgYnkgIlRlcnJvcmlzbSwgSGlqYWNraW5nLCBTYWJvdGFnZSIsIDYzNDIgY3Jhc2hlcyBjYXVzZWQgYnkgIkh1bWFuIGZhY3RvcnMiLCBhbmQgMjkzIGNyYXNoZXMgd2l0aCBzb21lIG90aGVyIGNhdXNlIG5vdCBzdGF0ZWQgcHJldmlvdXNseSAoIk90aGVyIGNhdXNlcyIpLiAKCmBgYHtyfQpsaWJyYXJ5KHBsb3RseSkKcDIgPC0gZ2dwbG90KGNyYXNoX2RhdGEsIGFlcyh4PUNyYXNoLmNhdXNlLCB5PVRvdGFsLmZhdGFsaXRpZXMsIGZpbGwgPSBDcmFzaC5jYXVzZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKSArIHlsaW0oMCwxMDApICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxOiBEaXN0cmlidXRpb25zIG9mIEZhdGFsaXR5IENvdW50cyBieSBDcmFzaCBDYXVzZSIsIHggPSAiU3RhdGVkIENhdXNlIG9mIENyYXNoIiwgeSA9ICJUb3RhbCBmYXRhbGl0eSBjb3VudCIpCmdncGxvdGx5KHAyKQpgYGAKVGhlc2UgYXJlIGFsbCBoaWdobHkgcmlnaHQtc2tld2VkIGRpc3RyaWJ1dGlvbnMsIHdoZXJlIG1vc3Qgb2YgdGhlIG51bWJlcnMgb2YgdG90YWwgZmF0YWxpdGllcyBhcmUgY2xvc2VyIHRvIHplcm8gKGxlc3MgdGhhbiAxMCBpbiBhbGwgY2F1c2VzISkgd2l0aCBtYW55IG91dGxpZXJzIGF0IHRoZSBoaWdoZXIgZW5kIG9mIHRoZSBkaXN0cmlidXRpb24sIG1lYW5pbmcgdGhhdCBhIGNvbXBhcmlzb24gb2YgdGhlIG1lZGlhbnMgaXMgYSBtb3JlIHJvYnVzdCBzdGF0aXN0aWMgdGhhbiBjb21wYXJpbmcgYXZlcmFnZXMsIGFzIG1lZGlhbiB2YWx1ZXMgYXJlIG1vcmUgc3RhYmxlIGluIHRoZSBwcmVzZW5jZSBvZiBvdXRsaWVycyB0aGFuIG1lYW4gdmFsdWVzLiBUaGUgZGlzdHJpYnV0aW9uIG9mIGNyYXNoIGZhdGFsaXR5IGNvdW50cyBmb3IgY3Jhc2hlcyBjYXVzZWQgYnkgIlRlcnJvcmlzbSwgSGlqYWNraW5nIG9yIFNhYm90YWdlIiBhcHBlYXIgdG8gaGF2ZSBoaWdoZXIgZmF0YWxpdHkgY291bnRzIHRoYW4gY3Jhc2hlcyB3aXRoIG90aGVyIGNhdXNlcywgd2l0aCAiV2VhdGhlciItY2F1c2VkIGNyYXNoZXMgaGF2aW5nIHRoZSBuZXh0IGhpZ2hlc3QgSVFSIGFjY29yZGluZyB0byB0aGUgYm94cGxvdHMgc2hvd24gYWJvdmUuCgpUaGUgbmV4dCBzZWN0aW9uIGNvbmR1Y3RzIGEgdGVzdCBvZiB0aGUgbWVkaWFucyBvZiB0aGVzZSBkaXN0cmlidXRpb25zIHRvIGRldGVybWluZSBpZiB0aGUgZmF0YWxpdHkgY291bnRzIGZvciAiVGVycm9yaXNtLCBIaWphY2tpbmcsIFNhYm90YWdlLWNhdXNlZCBjcmFzaGVzIGFyZSBhY3R1YWxseSBzaWduaWZpY2FudGx5IGRpZmZlcmVudCB0aGFuIHRoZSBtZWRpYW4gb2YgY3Jhc2hlcyB3aXRoIGFsbCBvdGhlciBjYXVzZXMuIFRoZSBgY29pbmAgbGlicmFyeSBpbmNsdWRlcyBhIG5vbi1wYXJhbWV0cmljIG1lZGlhbiBoeXBvdGhlc2lzIHRlc3QgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGluIHRoZSBtZWRpYW4gdmFsdWVzIGJldHdlZW4gdHdvIG9yIG1vcmUgaW5kZXBlbmRlbnQgc2FtcGxlcy4gVGhlIGZvbGxvd2luZyBoeXBvdGhlc2VzIGFuZCBhc3N1bXB0aW9ucyBhcmUgdXNlZCBpbiB0aGlzIHRlc3Q6CgpOdWxsIEh5cG90aGVzaXMgKEgwKTogVGhlIG1lZGlhbnMgb2YgYWxsIGdyb3VwcyBhcmUgZXF1YWwuCgpBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzIChIMSk6IEF0IGxlYXN0IG9uZSBvZiB0aGUgbWVkaWFucyBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgb3RoZXJzLgoKQXNzdW1wdGlvbnM6ICgxKSBJbmRlcGVuZGVuY2Ugb2Ygc2FtcGxlcywgKDIpIERhdGEgaXMgb3JkaW5hbCBvciBjb250aW51b3VzICgzKSBSYW5kb20gc2FtcGxpbmcKCmBgYHtyfQpsaWJyYXJ5KGNvaW4pCm1lZGlhbl90ZXN0X3Jlc3VsdCA8LSBtZWRpYW5fdGVzdChUb3RhbC5mYXRhbGl0aWVzIH4gQ3Jhc2guY2F1c2UsIGRhdGEgPSBjcmFzaF9kYXRhKQpwdmFsdWUgPC0gcHZhbHVlKG1lZGlhbl90ZXN0X3Jlc3VsdCkKcHJpbnQocHZhbHVlKQpgYGAKCkJhc2VkIG9uIHRoZSBwLXZhbHVlIG9mIHRoZSBtZWRpYW4gdGVzdCwgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyByZWplY3RlZCwgYW5kIHRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiB0aGUgbWVkaWFucyBvZiB0aGUgZGlzdHJpYnV0aW9ucyBvZiBmYXRhbGl0eSBjb3VudHMgZm9yIGNyYXNoZXMgd2l0aCBkaWZmZXJlbnQgY2F1c2VzIC0gbW9zdCBsaWtlbHkgdGhlIGhpZ2hlciBtZWRpYW4gZm9yIGNyYXNoZXMgY2F1c2VkIGJ5ICJUZXJyb3Jpc20sIEhpamFja2luZywgU2Fib3RhZ2UiIGFzIG9ic2VydmVkIGluIHRoZSBzaWRlLWJ5LXNpZGUgYm94cGxvdHMgYWJvdmUgKEZpZ3VyZSAxKS4gVGhpcyBvZiBjb3Vyc2UgYWxpZ25zIHdpdGggZXhwZWN0YXRpb25zOyBpbiBhdmlhdGlvbiBjcmFzaGVzIHdpdGggYWNjaWRlbnRhbCBvcmlnaW5zIC0gc3VjaCBhcyB0ZWNobmljYWwgZmFpbHVyZXMsIGh1bWFuIGVycm9yLCBvciB3ZWF0aGVyIC0gdGhlIGZsaWdodCBjcmV3IG9uIGJvYXJkIHdvdWxkIGJlIHRha2luZyBhY3Rpb24gdG8gbWluaW1pemUgZXhwZWN0ZWQgaGFybSBkdXJpbmcgYSBjcmFzaCBsYW5kaW5nLiAKCiMjIyMgUGxvdCBkYXRhIG92ZXIgdGltZSBmb3IgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIHRvIGludmVzdGlnYXRlIHVzZSBvZiBSREEKCmBgYHtyfQphbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2EgPC0gY3Jhc2hfZGF0YVtjcmFzaF9kYXRhJENvdW50cnkgPT0gJ1VuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYScsXSAlPiUKICBncm91cF9ieShZZWFyKSAlPiUKICBzdW1tYXJpc2UodG90YWxfZmF0YWxpdGllcyA9IHN1bShUb3RhbC5mYXRhbGl0aWVzKSwKICAgICAgICAgICAgY3Jld19mYXRhbGl0aWVzID0gc3VtKENyZXcuZmF0YWxpdGllcyksCiAgICAgICAgICAgIHBheF9mYXRhbGl0aXRlcyA9IHN1bShQQVguZmF0YWxpdGllcykpICU+JQogIGFycmFuZ2UoWWVhcikKYGBgCgpgYGB7cn0KcDMgPC0gZ2dwbG90KGFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSwgYWVzKHg9WWVhciwgeT10b3RhbF9mYXRhbGl0aWVzKSkgKyBnZW9tX3BvaW50KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgMjogQW5udWFsIHBsYW5lIGNyYXNoIGZhdGFsaXRpZXMgaW4gdGhlIFVTLCAxOTE5LTIwMjIiLCB4ID0gIlllYXIiLCB5ID0gIkFubnVhbCB0b3RhbCBmYXRhbGl0eSBjb3VudCIpCmdncGxvdGx5KHAzKQpgYGAKClRoZSBwbG90IG9mIGFubnVhbCBwbGFuZSBjcmFzaCBmYXRhbGl0aWVzIGluIHRoZSBVbml0ZWQgU3RhdGVzIGZyb20gMTkxOS0yMDIyIHNob3dzIGEgbWFya2VkIGluY3JlYXNpbmcgcmF0ZSBvZiBjcmFzaCBmYXRhbGl0aWVzIGZvciByb3VnaGx5IHRoZSBmaXJzdCA2MCB5ZWFycyBvZiB0aGlzIHRpbWUgcGVyaW9kLCBhbmQgZGVjcmVhc2luZyBzaW5jZSAxOTgwLiBUaGUgVVMgYW5udWFsIGZhdGFsaXRpZXMgZGF0YSB3aWxsIGJlIHVzZWQgZm9yIFJlZ3Jlc3Npb24gRGlzY29udGludWl0eSBBbmFseXNpcyAoUkRBKSB3aXRoIGEgY3V0cG9pbnQgYXQgMTk4MCwgYW5kIHdpbGwgY29uc2lkZXIgc2lnbmlmaWNhbmNlIG9mIGNoYW5nZXMgaW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiBwbGFuZSBjcmFzaCBmYXRhbGl0aWVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhpcyBjdXRwb2ludC4gVGhlcmUgaXMgYWxzbyBhIGRpc3RpbmN0IG91dGxpZXIgaW4gMjAwMSwgY29ycmVzcG9uZGluZyB0byB0aGUgMjAwMSA5LTExIHRlcnJvciBhdHRhY2tzIHdoaWNoIGludm9sdmVkIHRoZSBoaWphY2tpbmcgYW5kIHB1cnBvc2VmdWwgY3Jhc2ggb2YgZm91ciBwYXNzZW5nZXIgZmxpZ2h0cyBpbiB0aGUgZWFzdGVybiBVUy4gVGhpcyBvdXRsaWVyIG1heSBiZSByZW1vdmVkIGluIGZ1cnRoZXIgYW5hbHlzaXMuIAoKIyMjIyBQbG90IGRhdGEgd2l0aCBjdXRwb2ludAoKYGBge3J9CmN1dHBvaW50IDwtIDE5ODAgI3NldCB0aGUgeWVhciAxOTgwIGFzIHRoZSBjdXRwb2ludCBmb3IgdGhlIGFuYWx5c2lzIC0gdGhpcyBjYW4gYmUgYWRqdXN0ZWQgbGF0ZXIgd2l0aG91dCBkaWZmaWN1bHR5IGFzIG5lZWRlZAoKcDQgPC0gcDMgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjdXRwb2ludCwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyBsYWJzKHRpdGxlID0gIkZpZ3VyZSAzOiBBbm51YWwgcGxhbmUgY3Jhc2ggZmF0YWxpdGllcyBpbiB0aGUgVVMsIDE5MTktMjAyMiIsIHggPSAiWWVhciIsIHkgPSAiQW5udWFsIHRvdGFsIGZhdGFsaXR5IGNvdW50IikKZ2dwbG90bHkocDQpCgpgYGAKCkluIGFkZGl0aW9uLCBhZGRpbmcgdGhlIHJlZ3Jlc3Npb24gbGluZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgY3V0cG9pbnQgd2lsbCBmdXJ0aGVyIGhlbHAgZGV0ZXJtaW5lIHdoYXQgdHlwZSBvZiBSREEgc2hvdWxkIGJlIGFwcGxpZWQuIAoKYGBge3J9CiMgY3JlYXRlIGdyb3VwZWQgZGF0YXNldCBiYXNlZCBvbiBjcmFzaCBmYXRhbGl0eSBjb3VudHMgYmVmb3JlL2FmdGVyIGN1dHBvaW50IHllYXIKdXNfY3Jhc2hfZGF0YV9ncm91cGVkICA8LSBhbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2EgJT4lICBtdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oIFllYXIgPCBjdXRwb2ludCB+ICJiZWZvcmUiLCBZZWFyID49IGN1dHBvaW50IH4gImFmdGVyIikpCgojY3JlYXRlIGdncGxvdCAKY3Jhc2hfcGxvdF9jcF9sbSA8LSB1c19jcmFzaF9kYXRhX2dyb3VwZWQgJT4lIGdncGxvdChhZXMoeD1ZZWFyLCB5ID10b3RhbF9mYXRhbGl0aWVzKSkgKwogIGdlb21fcG9pbnQoKSArIHRoZW1lX2J3KCkgKyBsYWJzKHRpdGxlID0gIkZpZ3VyZSA0OiBVUyBwbGFuZSBjcmFzaCBmYXRhbGl0aWVzIGJlZm9yZS9hZnRlciAxOTgwIiwgeCA9ICJZZWFyIiwgeSA9ICJBbm51YWwgdG90YWwgZmF0YWxpdHkgY291bnQiKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoY3V0cG9pbnQpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ3JvdXApLCBjb2xvciA9ICJibGFjayIsIG1ldGhvZCA9IGxtKQoKZ2dwbG90bHkoY3Jhc2hfcGxvdF9jcF9sbSkgICMgZGlzcGxheSBwbG90CmBgYAoKVGhlIHNjYXR0ZXIgcGxvdCB3aXRoIHJlZ3Jlc3Npb24gbGluZXMgYXMgc2hvd24gcmVpbmZvcmNlcyB0aGF0IHRoZXNlIGdyb3VwaW5ncyBwcmVzZW50IGEgZ29vZCBjYW5kaWRhdGUgZm9yIFJEQS4gVGhlIGJlZm9yZS0gYW5kIGFmdGVyLWdyb3VwcyBzaG93IGEgY2hhbmdlIGluIHNsb3BlIG9mIHRoZSByZWdyZXNzaW9uIGxpbmUgKHBvc2l0aXZlIGJlZm9yZSAxOTgwLCBuZWdhdGl2ZSBhZnRlciAxOTgwKSBhbmQgYSBjaGFuZ2UgaW4gdGhlIGludGVyY2VwdCB3aXRoIHRoZSBjdXRwb2ludCAoaGlnaGVyIGludGVyY2VwdCBmb3IgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCB0aGUgY3V0cG9pbnQgYmVmb3JlIDE5ODAsIGxvd2VyIGludGVyY2VwdCB3aXRoIHRoZSBjdXRwb2ludCBhZnRlciAxOTgwKS4gCgpbVGhlIFJEQSBwYWNrYWdlIGByZHJvYnVzdGBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9yZHJvYnVzdC9yZHJvYnVzdC5wZGYpIGVuYWJsZXMgYW4gUkRBIHRoYXQgdGVzdHMgd2hldGhlciB0aGUgc2xvcGVzIG9mIHRoZSByZWdyZXNzaW9uIGxpbmVzIHdpdGhpbiBhIGJhbmR3aWR0aCBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgY3V0cG9pbnQgYXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50LiBUbyBpbnN0YWxsIGByZHJvYnVzdGAsIHVzZSBgaW5zdGFsbC5wYWNrYWdlcygicmRyb2J1c3QiKWAuCgojIyMgUmVncmVzc2lvbiBEaXNjb250aW51aXR5IEFuYWx5c2lzIHdpdGggYHJkcm9idXN0YAoKIyMjIyBTZWxlY3QgYmFuZHdpZHRoCmBgYHtyfQpsaWJyYXJ5KHJkcm9idXN0KQojIGRldGVybWluZSB0aGUgYmFuZHdpZHRoIG9uIGVpdGhlciBzaWRlIG9mIHRoZSBjdXRwb2ludCBpbiB5ZWFycwpiYW5kd2lkdGhzIDwtIChyZGJ3c2VsZWN0KHk9YW5udWFsX2NyYXNoX2ZhdGFsaXRpZXNfdXNhJHRvdGFsX2ZhdGFsaXRpZXMsIHg9IGFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSRZZWFyLCBjID0gY3V0cG9pbnQpKQoKYmFuZHdpZHRocyRid3MgI3Nob3cgdGhlIGJhbmR3aWR0aHMKYGBgCgpgaGAsIHRoZSBtYWluIGJhbmR3aWR0aCwgaXMgKy8tIDEzLjc4MTkyIHllYXJzCmBiYCwgdGhlIGJpYXMgYmFuZHdpZHRoLCBpcyArLy0gMjEuNTgyNjEgeWVhcnMuIFRoaXMgYmFuZHdpZHRoIGlzIHVzZWQgZm9yIGJvdGggdGhlIGJpYXMtY29ycmVjdGVkIGFuZCByb2J1c3QgZXN0aW1hdG9ycyB3aGVuIFJEQSBpcyBwZXJmb3JtZWQgd2l0aCBgcmRyb2J1c3RgLiAKCkxldCdzIGNyZWF0ZSBhIG5ldyBwbG90IHNob3dpbmcgdGhlIGJhbmR3aWR0aHMgYXMgZGVzaWduYXRlZC4gCgojIyMjIFBsb3QgZGF0YSB3aXRoIGJhbmR3aWR0aHMgc2hvd2luZwoKYGBge3J9CmJ3IDwtIGJhbmR3aWR0aHMkYndzWzFdWzFdICMgc3RvcmUgdGhlIGJhbmR3aWR0aCB2YWx1ZSBhcyBhIHZhcmlhYmxlCmJ3CmBgYApgYGB7cn0KcDUgPC0gcDQgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjdXRwb2ludCArIGMoYncsIC1idykpICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgNTogY3Jhc2ggZmF0YWxpdGllcyBiZWZvcmUvYWZ0ZXIgMTk4MCB3aXRoIFJEQSBiYW5kd2lkdGgiLCB4ID0gIlllYXIiLCB5ID0gIkFubnVhbCB0b3RhbCBmYXRhbGl0eSBjb3VudCIpCmdncGxvdGx5KHA1KQpgYGAKCmBgYHtyfQojIGNyZWF0ZSBuZXcgZGF0YSBmcmFtZSB3aXRoIGp1c3QgdGhlIGRhdGEgd2l0aGluIHRoZSBiYW5kd2l0aCBvbiBlaXRoZXJzaWRlIG9mIHRoZSBjdXRwb2ludAp1c19jcmFzaF9kYXRhX2J3IDwtIHVzX2NyYXNoX2RhdGFfZ3JvdXBlZCAlPiUgZmlsdGVyKFllYXIgPiAoY3V0cG9pbnQgLSBidykgJiBZZWFyIDwgKGN1dHBvaW50ICsgYncpKSAKCnA2IDwtIHA1ICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgNjogQ3Jhc2ggZmF0YWxpdHkgcmVncmVzc2lvbiBtb2RlbHMgd2l0aGluIGJhbmR3aWR0aCBhcm91bmQgMTk4MCIsIHggPSAiWWVhciIsIHkgPSAiUGxhbmUgY3Jhc2ggdG90YWwgZmF0YWxpdGllcyIpICsgZ2VvbV9zbW9vdGgoZGF0YSA9IHVzX2NyYXNoX2RhdGFfYncsIGFlcyh4PSBZZWFyLCB5ID0gdG90YWxfZmF0YWxpdGllcywgZ3JvdXAgPSBncm91cCksIGNvbG9yID0gImJsYWNrIiwgbWV0aG9kID0gbG0pCmdncGxvdGx5KHA2KQpgYGAKClBsb3R0aW5nIHRoZSByZWdyZXNzaW9uIG1vZGVscyBmb3Igc29sZWx5IHRoZSBkYXRhIHBvaW50cyB3aXRoaW4gdGhlIGJhbmR3aWR0aCBhcm91bmQgMTk4MCBzaG93cyB0aGF0IHRoZSBjaGFuZ2UgaW4gc2xvcGUgZnJvbSBwb3NpdGl2ZSAoYmVmb3JlIDE5ODApIHRvIG5lZ2F0aXZlIChhZnRlciAxOTgwKSBzdGlsbCBob2xkcy4gUGVyZm9ybWluZyB0aGUgUkRBIHdpbGwgZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBkaWZmZXJlbmNlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYW5kLCB0aHVzLCB3aGV0aGVyIHRoZXJlIHdhcyBhIHNpZ25pZmljYW50IGNoYW5nZSBpbiBhaXJwbGFuZSBjcmFzaCBmYXRhbGl0eSBjb3VudHMgaW4gdGhlIFVuaXRlZCBTdGF0ZXMgYmVmb3JlIGFuZCBhZnRlciAxOTgwLiAKCiMjIyMgUGVyZm9ybSBSREEgYmVmb3JlL2FmdGVyIDE5ODAKYGBge3J9CnJkYV92MSA8LSByZHJvYnVzdCh5PWFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSR0b3RhbF9mYXRhbGl0aWVzLCB4PSBhbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2EkWWVhciwgYyA9IGN1dHBvaW50KQoKcHJpbnQocmRhX3YxKQpgYGAKUHJpbnRpbmcgdGhlIHJkYSBzaG93cyB0aGF0IHRoZXJlIGFyZSBhIHRvdGFsIG9mIDU0IG9ic2VydmF0aW9ucyBiZWZvcmUgdGhlIGN1dHBvaW50IGFuZCA0MyBvYnNlcnZhdGlvbnMgYWZ0ZXIgdGhlIGN1dHBvaW50LiBUaGUgRWZmZWN0aXZlIE51bWJlciBvZiBPYnNlcnZhdGlvbnMgZGVtb25zdHJhdGVzIHRoYXQgMTMgb2JzZXJ2YXRpb25zIHdlcmUgd2l0aGluIHRoZSBiYW5kd2lkdGggdG8gdGhlIGxlZnQgb2YgdGhlIGN1dHBvaW50IGFuZCAxNCBvYnNlcnZhdGlvbnMgd2VyZSB3aXRoaW4gdGhlIGJhbmR3aWR0aCB0byB0aGUgcmlnaHQgb2YgdGhlIGN1dHBvaW50LgoKYGBge3J9CnN0cihyZGFfdjEpCmBgYApMb29raW5nIGF0IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHJkYSByZXN1bHRzIG9iamVjdCBzaG93cyB3aGVyZSB0aGUgb3RoZXIgaW1wb3J0YW50IG91dHB1dHMgYXJlIHN0b3JlZC4gQ2hlY2tpbmcgdGhlIGNvZWZmaWNpZW50LCAqcCotdmFsdWUsIGFuZCBzdGFuZGFyZCBlcnJvciB3aWxsIGluZGljYXRlIHRoZSBzaXplIG9mIHRoZSB0cmVhdG1lbnQgZWZmZWN0IChncm91cGluZyBpbnRvIGJlZm9yZSBhbmQgYWZ0ZXIgMTk4MCkgYW5kIHdoZXRoZXIgdGhlIGVmZmVjdCB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gCgpDaGVjayB0aGUgY29lZmZpY2llbnRzOgpgYGB7cn0KcmRhX3YxJGNvZWYKYGBgClRoZSByZWdyZXNzaW9uIHNsb3BlICh3aXRoaW4gdGhlIGJhbmR3aWR0aCkgYmVmb3JlIHRoZSBjdXRwb2ludCB3YXMgMTQ4LjgyMTggbGVzcyB0aGFuIHRoZSBzbG9wZSBhZnRlciB0aGUgY3V0cG9pbnQuIFdoZW4gdGhlIGxhcmdlciAoYmlhcyBvciBgYmApIGJhbmR3aWR0aCB3YXMgdXNlZCAoMjEuNTgzIHllYXJzIGluc3RlYWQgb2YgMTMuNzgyIHllYXJzKSwgdGhlIGRpZmZlcmVuY2UgaW4gc2xvcGVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGN1dHBvaW50IHdhcyBsYXJnZXIgKDE3OS40OTkwKS4KClRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgY29lZmZpY2llbnQgZ2l2ZXMgYW4gaW5kaWNhdGlvbiBvZiBob3cgbWVhbmluZ2Z1bCB0aGlzIGRpZmZlcmVuY2UgaXM6IApgYGB7cn0KcmRhX3YxJHNlCmBgYAoKLTE0OC44MjE4ICsvLSBhIHN0YW5kYXJkIGVycm9yIG9mIDEwNy41MzY2IGRvZXMgbm90IGxlYWQgdG8gYSBkaWZmZXJlbmNlIGVxdWFsIHRvIG9yIGNsb3NlIHRvIHplcm8uIFRodXMsIGV2ZW4gd2hlbiB0YWtpbmcgdGhlIHN0YW5kYXJkIGVycm9yIGludG8gYWNjb3VudCwgdGhlcmUgaXMgc3RpbGwgYSByZWxhdGl2ZWx5IGxhcmdlIGRpZmZlcmVuY2UgaW4gdGhlIHJlZ3Jlc3Npb24gc2xvcGVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGN1dHBvaW50LgoKVGhlICpwKi12YWx1ZSB3aWxsIGluZGljYXRlIHdoZXRoZXIgdGhpcyBkaWZmZXJlbmNlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQ6CgpgYGB7cn0KcmRhX3YxJHB2CmBgYAoKSGVyZSwgdGhlICpwKi12YWx1ZSBiZWluZyBsYXJnZXIgdGhhbiB0aGUgc3RhbmRhcmQgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUgaW5kaWNhdGVzIHRoYXQgdGhlIGRpZmZlcmVuY2UgaW4gcmVncmVzc2lvbiBzbG9wZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgY3V0cG9pbnQsIGJ1dCB3aXRoaW4gdGhlIGJhbmR3aWR0aCwgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIAoKIyMjIyBSZXBlYXQgUkRBIHJlbW92aW5nIHRoZSAyMDAxIDktMTEgdGVycm9yIGF0dGFjayBmYXRhbGl0eSBjb3VudHMgYXMgYW4gb3V0bGllcgpgYGB7cn0KYW5udWFsX2NyYXNoX2ZhdGFsaXRpZXNfdXNhX3YyIDwtIGFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSAlPiUgZmlsdGVyKFllYXIgIT0gMjAwMSkKCnA3IDwtIGdncGxvdChhbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2FfdjIsIGFlcyh4PVllYXIsIHk9dG90YWxfZmF0YWxpdGllcykpICsgZ2VvbV9wb2ludCgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdD0xKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIGxhYnModGl0bGUgPSAiRmlndXJlIDc6IEFubnVhbCBwbGFuZSBjcmFzaCBmYXRhbGl0aWVzIGluIHRoZSBVUywgZXhjbHVkaW5nIDktMTEiLCB4ID0gIlllYXIiLCB5ID0gIkFubnVhbCB0b3RhbCBmYXRhbGl0eSBjb3VudCIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY3V0cG9pbnQsIGxpbmV0eXBlID0gImRhc2hlZCIpCmdncGxvdGx5KHA3KQpgYGAKYGBge3J9CiMgZGV0ZXJtaW5lIHRoZSBiYW5kd2lkdGggb24gZWl0aGVyIHNpZGUgb2YgdGhlIGN1dHBvaW50IGluIHllYXJzCmJhbmR3aWR0aHNfdjIgPC0gKHJkYndzZWxlY3QoeT1hbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2FfdjIkdG90YWxfZmF0YWxpdGllcywgeD0gYW5udWFsX2NyYXNoX2ZhdGFsaXRpZXNfdXNhX3YyJFllYXIsIGMgPSBjdXRwb2ludCkpCgpid192MiA8LSBiYW5kd2lkdGhzX3YyJGJ3c1sxXVsxXSAjIHN0b3JlIHRoZSBiYW5kd2lkdGggdmFsdWUgYXMgYSB2YXJpYWJsZQpid192MgpgYGAKCmBgYHtyfQpwOCA8LSBwNyArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGN1dHBvaW50ICsgYyhid192MiwgLWJ3X3YyKSkgKyBsYWJzKHRpdGxlID0gIkZpZ3VyZSA4OiBjcmFzaCBmYXRhbGl0aWVzIGV4Y2x1ZGluZyA5LTExIHdpdGggUkRBIGJhbmR3aWR0aCIsIHggPSAiWWVhciIsIHkgPSAiQW5udWFsIHRvdGFsIGZhdGFsaXR5IGNvdW50IikKZ2dwbG90bHkocDgpCmBgYApgYGB7cn0KdXNfY3Jhc2hfZGF0YV9id192MiA8LSB1c19jcmFzaF9kYXRhX2dyb3VwZWQgJT4lIGZpbHRlcihZZWFyID4gKGN1dHBvaW50IC0gYndfdjIpICYgWWVhciA8IChjdXRwb2ludCArIGJ3X3YyKSkgCgpwOSA8LSBwOCArIGxhYnModGl0bGUgPSAiRmlndXJlIDk6IENyYXNoIGZhdGFsaXR5IHJlZ3Jlc3Npb24gbW9kZWxzIHdpdGhpbiBiYW5kd2lkdGggYXJvdW5kIDE5ODAgZXhjbHVkaW5nIDktMTEiLCB4ID0gIlllYXIiLCB5ID0gIlBsYW5lIGNyYXNoIHRvdGFsIGZhdGFsaXRpZXMiKSArIGdlb21fc21vb3RoKGRhdGEgPSB1c19jcmFzaF9kYXRhX2J3LCBhZXMoeD0gWWVhciwgeSA9IHRvdGFsX2ZhdGFsaXRpZXMsIGdyb3VwID0gZ3JvdXApLCBjb2xvciA9ICJibGFjayIsIG1ldGhvZCA9IGxtKQpnZ3Bsb3RseShwOSkKYGBgCgpgYGB7cn0KcmRhX3YyIDwtIHJkcm9idXN0KHk9YW5udWFsX2NyYXNoX2ZhdGFsaXRpZXNfdXNhX3YyJHRvdGFsX2ZhdGFsaXRpZXMsIHg9IGFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYV92MiRZZWFyLCBjID0gY3V0cG9pbnQpCgpwcmludChyZGFfdjIpCmBgYApDaGVjayB0aGUgY29lZmZpY2llbnRzOgpgYGB7cn0KcmRhX3YyJGNvZWYKYGBgClRoZSByZWdyZXNzaW9uIHNsb3BlICh3aXRoaW4gdGhlIGJhbmR3aWR0aCkgYmVmb3JlIHRoZSBjdXRwb2ludCB3YXMgMTM4LjgyNTIgbGVzcyB0aGFuIHRoZSBzbG9wZSBhZnRlciB0aGUgY3V0cG9pbnQuIFdoZW4gdGhlIGxhcmdlciAoYmlhcyBvciBgYmApIGJhbmR3aWR0aCB3YXMgdXNlZCAoMjUuMjMwIHllYXJzIGluc3RlYWQgb2YgMTUuNjY4IHllYXJzKSwgdGhlIGRpZmZlcmVuY2UgaW4gc2xvcGVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGN1dHBvaW50IHdhcyBsYXJnZXIgKDE3MC43NTI2KS4KClRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgY29lZmZpY2llbnQgZ2l2ZXMgYW4gaW5kaWNhdGlvbiBvZiBob3cgbWVhbmluZ2Z1bCB0aGlzIGRpZmZlcmVuY2UgaXM6IApgYGB7cn0KcmRhX3YyJHNlCmBgYAotMTM4LjgyNTIgKy8tIGEgc3RhbmRhcmQgZXJyb3Igb2YgMTAwLjMzMjEgZG9lcyBub3QgbGVhZCB0byBhIGRpZmZlcmVuY2UgZXF1YWwgdG8gb3IgY2xvc2UgdG8gemVyby4gVGh1cywgZXZlbiB3aGVuIHRha2luZyB0aGUgc3RhbmRhcmQgZXJyb3IgaW50byBhY2NvdW50LCB0aGVyZSBpcyBzdGlsbCBhIHJlbGF0aXZlbHkgbGFyZ2UgZGlmZmVyZW5jZSBpbiB0aGUgcmVncmVzc2lvbiBzbG9wZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgY3V0cG9pbnQuCgpUaGUgKnAqLXZhbHVlIHdpbGwgaW5kaWNhdGUgd2hldGhlciB0aGlzIGRpZmZlcmVuY2UgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudDoKCmBgYHtyfQpyZGFfdjIkcHYKYGBgCgpBYm91dCB0aGUgc2FtZSBhcyB0aGUgZmlyc3QgYW5hbHlzaXMuIFNvLCBleGNsdWRpbmcgOS0xMSBhcyBhbiBvdXRsaWVyIGRpZCBub3QgbGVhZCB0byBhIHNpZ25pZmljYW50IHJlc3VsdC4gCgojIyMjIEZpbmFsIGFuYWx5c2lzIC0gaW5jbHVkZSA5LTExLCBidXQgbWFrZSAyMDAxIHRoZSBjdXRwb2ludCEKCk91ciBmaW5hbCBSREEgd2lsbCByZXNldCB0aGUgY3V0cG9pbnQgdG8gMjAwMSwgc2luY2UgYWlyIHRyYXZlbCBhbmQgYWlyIHRyYXZlbCBzYWZldHkgcHJvY2VkdXJlcyBjaGFuZ2VkIGluIG1hbnkgd2F5cyBhZnRlciB0aGUgZXZlbnRzIG9mIHRoZSA5LTExIHRlcnJvciBhdHRhY2tzLiAKCmBgYHtyfQpjdXRwb2ludF92MiA8LSAyMDAxICNzZXQgdGhlIHllYXIgMjAwMSBhcyB0aGUgY3V0cG9pbnQgZm9yIHRoZSBhbmFseXNpcwoKcDEwIDwtIHAzICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY3V0cG9pbnRfdjIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTA6IENyYXNoIGZhdGFsaXR5IGNvdW50cyB3aXRoIGN1dHBvaW50IDIwMDEiLCB4ID0gIlllYXIiLCB5ID0gIlBsYW5lIGNyYXNoIHRvdGFsIGZhdGFsaXRpZXMiKQpnZ3Bsb3RseShwMTApCmBgYAoKUmVwZWF0IHRoZSBwcm9jZXNzIG9mIGdyb3VwaW5nIHRoZSBkYXRhIGludG8gYmVmb3JlL2FmdGVyIDIwMDEsIGFuZCBkZXRlcm1pbmluZyB0aGUgYXBwcm9wcmlhdGUgYmFuZHdpZHRoIGFyb3VuZCB0aGlzIHllYXIgZm9yIFJEQS4gCgpgYGB7cn0KIyBjcmVhdGUgZ3JvdXBlZCBkYXRhc2V0IGJhc2VkIG9uIGNyYXNoIGZhdGFsaXR5IGNvdW50cyBiZWZvcmUvYWZ0ZXIgY3V0cG9pbnQgeWVhcgp1c19jcmFzaF9kYXRhX2dyb3VwZWRfdjIgIDwtIGFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSAlPiUgIG11dGF0ZShncm91cCA9IGNhc2Vfd2hlbiggWWVhciA8PSBjdXRwb2ludF92MiB+ICJiZWZvcmUiLCBZZWFyID4gY3V0cG9pbnRfdjIgfiAiYWZ0ZXIiKSkKCiNjcmVhdGUgZ2dwbG90IApwMTEgPC0gdXNfY3Jhc2hfZGF0YV9ncm91cGVkX3YyICU+JSBnZ3Bsb3QoYWVzKHg9WWVhciwgeSA9dG90YWxfZmF0YWxpdGllcykpICsKICBnZW9tX3BvaW50KCkgKyB0aGVtZV9idygpICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTE6IFVTIHBsYW5lIGNyYXNoIGZhdGFsaXRpZXMgYmVmb3JlL2FmdGVyIDIwMDEiLCB4ID0gIlllYXIiLCB5ID0gIkFubnVhbCB0b3RhbCBmYXRhbGl0eSBjb3VudCIpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhjdXRwb2ludF92MiksIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBncm91cCksIGNvbG9yID0gImJsYWNrIiwgbWV0aG9kID0gbG0pCgpnZ3Bsb3RseShwMTEpICAjIGRpc3BsYXkgcGxvdApgYGAKVGhlIGJlZm9yZS0gYW5kIGFmdGVyLWdyb3VwcyBzaG93IGEgY2hhbmdlIGluIHNsb3BlIG9mIHRoZSByZWdyZXNzaW9uIGxpbmUgKHBvc2l0aXZlIGJ1dCBzbWFsbGVyIG1hZ25pdHVkZSwgZmxhdHRlciBzbG9wZSwgYmVmb3JlIDIwMDEsIG5lZ2F0aXZlIHdpdGggc3RlZXBlciBzbG9wZSBhZnRlciAyMDAxKSBhbmQgYSBjaGFuZ2UgaW4gdGhlIGludGVyY2VwdCB3aXRoIHRoZSBjdXRwb2ludCAoaGlnaGVyIGludGVyY2VwdCBmb3IgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCB0aGUgY3V0cG9pbnQgYmVmb3JlIDIwMDEsIGxvd2VyIGludGVyY2VwdCB3aXRoIHRoZSBjdXRwb2ludCBhZnRlciAyMDAxKS4KCiMjIyMgUkRBIGJlZm9yZS9hZnRlciA5LTExClVzZSBgbGlicmFyeShyb2J1c3QpYCB0byBkZXRlcm1pbmUgYmFuZHdpZHRocyBmb3IgUkRBIGFyb3VuZCBjdXRwb2ludCBhdCAyMDAxLiAKYGBge3J9CmJhbmR3aWR0aHNfdjMgPC0gKHJkYndzZWxlY3QoeT1hbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2EkdG90YWxfZmF0YWxpdGllcywgeD0gYW5udWFsX2NyYXNoX2ZhdGFsaXRpZXNfdXNhJFllYXIsIGMgPSBjdXRwb2ludF92MikpCgpiYW5kd2lkdGhzX3YzJGJ3cyAjc2hvdyB0aGUgYmFuZHdpZHRocwpgYGAKCmBoYCwgdGhlIG1haW4gYmFuZHdpZHRoLCBpcyArLy0gOC45NzA5OTkgeWVhcnMKYGJgLCB0aGUgYmlhcyBiYW5kd2lkdGgsIGlzICsvLSAxMy4zODk1NyB5ZWFycy4gVGhpcyBiYW5kd2lkdGggaXMgdXNlZCBmb3IgYm90aCB0aGUgYmlhcy1jb3JyZWN0ZWQgYW5kIHJvYnVzdCBlc3RpbWF0b3JzIHdoZW4gUkRBIGlzIHBlcmZvcm1lZCB3aXRoIGByZHJvYnVzdGAuIAoKTGV0J3MgY3JlYXRlIGEgbmV3IHBsb3Qgc2hvd2luZyB0aGUgYmFuZHdpZHRocyBhcyBkZXNpZ25hdGVkLiAKCiMjIyMgUGxvdCBkYXRhIHdpdGggYmFuZHdpZHRocyBzaG93aW5nCgpgYGB7cn0KYndfdjMgPC0gYmFuZHdpZHRoc192MyRid3NbMV1bMV0gIyBzdG9yZSB0aGUgYmFuZHdpZHRoIHZhbHVlIGFzIGEgdmFyaWFibGUKYndfdjMKYGBgCgpgYGB7cn0KdXNfY3Jhc2hfZGF0YV9id192MyA8LSB1c19jcmFzaF9kYXRhX2dyb3VwZWRfdjIgJT4lIGZpbHRlcihZZWFyID4gKGN1dHBvaW50X3YyIC0gYndfdjMpICYgWWVhciA8IChjdXRwb2ludF92MiArIGJ3X3YzKSkgCgpwMTIgPC0gcDEwICsgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTI6IENyYXNoIGZhdGFsaXR5IHJlZ3Jlc3Npb24gbW9kZWxzIHdpdGhpbiBiYW5kd2lkdGggYXJvdW5kIDIwMDEiLCB4ID0gIlllYXIiLCB5ID0gIlBsYW5lIGNyYXNoIHRvdGFsIGZhdGFsaXRpZXMiKSArIGdlb21fc21vb3RoKGRhdGEgPSB1c19jcmFzaF9kYXRhX2J3X3YzLCBhZXMoeD0gWWVhciwgeSA9IHRvdGFsX2ZhdGFsaXRpZXMsIGdyb3VwID0gZ3JvdXApLCBjb2xvciA9ICJibGFjayIsIG1ldGhvZCA9IGxtKQpnZ3Bsb3RseShwMTIpCmBgYAoKYGBge3J9CnJkYV92MyA8LSByZHJvYnVzdCh5PWFubnVhbF9jcmFzaF9mYXRhbGl0aWVzX3VzYSR0b3RhbF9mYXRhbGl0aWVzLCB4PSBhbm51YWxfY3Jhc2hfZmF0YWxpdGllc191c2EkWWVhciwgYyA9IGN1dHBvaW50X3YyKQoKcHJpbnQocmRhX3YzKQpgYGAKQ2hlY2sgdGhlIGNvZWZmaWNpZW50czoKYGBge3J9CnJkYV92MyRjb2VmCmBgYApUaGUgcmVncmVzc2lvbiBzbG9wZSAod2l0aGluIHRoZSBiYW5kd2lkdGgpIGJlZm9yZSB0aGUgY3V0cG9pbnQgd2FzIDI3Mi44MjkgbW9yZSB0aGFuIHRoZSBzbG9wZSBhZnRlciB0aGUgY3V0cG9pbnQuIFdoZW4gdGhlIGxhcmdlciAoYmlhcyBvciBgYmApIGJhbmR3aWR0aCB3YXMgdXNlZCAoMTMuMzkwIHllYXJzIGluc3RlYWQgb2YgOC45NzEgeWVhcnMpLCB0aGUgZGlmZmVyZW5jZSBpbiBzbG9wZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgY3V0cG9pbnQgd2FzIGxhcmdlciAoMzM4Ljg3MDApLgoKVGhlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBjb2VmZmljaWVudCBnaXZlcyBhbiBpbmRpY2F0aW9uIG9mIGhvdyBtZWFuaW5nZnVsIHRoaXMgZGlmZmVyZW5jZSBpczogCmBgYHtyfQpyZGFfdjMkc2UKYGBgClRoZSAqcCotdmFsdWUgd2lsbCBpbmRpY2F0ZSB3aGV0aGVyIHRoaXMgZGlmZmVyZW5jZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50OgoKYGBge3J9CnJkYV92MyRwdgpgYGAKSGVyZSwgdGhlICpwKi12YWx1ZSBiZWluZyBsYXJnZXIgdGhhbiB0aGUgc3RhbmRhcmQgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUgaW5kaWNhdGVzIHRoYXQgdGhlIGRpZmZlcmVuY2UgaW4gcmVncmVzc2lvbiBzbG9wZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgY3V0cG9pbnQsIGJ1dCB3aXRoaW4gdGhlIGJhbmR3aWR0aCwgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIAoKVGhpcyBpcyBzb21ld2hhdCBzdXJwcmlzaW5nLCBnaXZlbiB0aGUgZ3JlYXQgbGFib3IgYW5kIGFuYWx5dGljYWwgZWZmb3J0IHRvIGltcHJvdmUgYWlybGluZSBzYWZldHkgaW4gdGhlIFVTIGZvbGxvd2luZyB0aGUgOS0xMSBhdHRhY2tzLCBob3dldmVyIHdpdGggY2xvc2VyIGV4YW1pbmF0aW9uIG9mIEZpZy4gMTIgYWJvdmUgaXQgY2FuIGJlIG9ic2VydmVkIHRoYXQgaW4gdGhlIGRlY2FkZSBsZWFkaW5nIHVwIHRvIDktMTEgKHdpdGhpbiB0aGUgfjkgeWVhciBiYW5kd2lkdGgpLCB0aGUgYWlybGluZSBjcmFzaCBmYXRhbGl0eSBjb3VudHMgd2VyZSBhbHJlYWR5IHRyZW5kaW5nIGRvd253YXJkIGZvciB0aGF0IHRpbWUgcGVyaW9kLCBhbmQgdGhhdCB0aGUgMjAwMSBvdXRsaWVyIHZhbHVlIHdpdGggZXh0cmVtZWx5IGhpZ2ggYWlybGluZSBjcmFzaCBmYXRhbGl0eSBjb3VudHMgd2FzIGluZGVlZCBzdGlsbCBhbiBvdXRsaWVyIGZvciB0aGUgZGF0YSB3aXRoaW4gdGhlIGJhbmR3aWR0aCBiZWZvcmUgdGhlIDIwMDEgY3V0cG9pbnQuIAoKVGh1cywgdGhlIGltcHJvdmVtZW50IGluIGFpcmxpbmUgc2FmZXR5IGFuZCByZWR1Y3Rpb24gaW4gY3Jhc2ggZmF0YWxpdGllcyB0aGF0IGhhcyBiZWVuIG9ic2VydmVkIHNpbmNlIHRoZSBtaWQtMTk3MHMgY2Fubm90IGJlIGFzc29jaWF0ZWQgZGlyZWN0bHkgd2l0aCB0aGUgdGltZSBwZXJpb2QgZm9sbG93aW5nIHRoZSAyMDAxIDktMTEgdGVycm9yIGF0dGFja3MsIGFuZCBsaWtlbHkgaGFzIGNhdXNlcyB3aXRoIGVmZmVjdHMgc3ByZWFkIG91dCBpbiB0aW1lLCBzdWNoIGFzIGEgZ3JhZHVhbCBpbXByb3ZlbWVudCBpbiByYWRhciBhbmQgc2Vuc29yIHRlY2hub2xvZ3kgdGhhdCBsZWQgdG8gYmV0dGVyIGZsaWdodCBwYXRoIG1hbmFnZW1lbnQsIGFuZCBlbmdpbmVlcmluZyBkZXZlbG9wbWVudHMgdGhhdCBtYWRlIHVuc2NoZWR1bGVkIGxhbmRpbmdzIGxlc3MgZGVzdHJ1Y3RpdmUgdG8gdGhlIGFpcmNyYWZ0IGFuZCBjcmV3L3Bhc3NlbmdlcnMgb25ib2FyZC4gCgpGdXJ0aGVyIHJlc2VhcmNoIGludG8ga2V5IGlubm92YXRpb25zIGluIGFpciB0cmF2ZWwgc2FmZXR5IHRlY2hub2xvZ3kgYW5kIGFpciB0cmFmZmljIGNvbnRyb2wgc3lzdGVtcyBjb3VsZCByZXZlYWwgYSBtb3JlIHN1aXRhYmxlIGN1dHBvaW50IHNlbGVjdGlvbiB0aGF0IGRvZXMgbGVhZCB0byBhIHNpZ25pZmljYW50IGJlZm9yZS9hZnRlciBjaGFuZ2UgaW4gYWlybGluZSBjcmFzaCBmYXRhbGl0aWVzLCB3aGljaCB3ZSBkbyBpbmRlZWQgb2JzZXJ2ZSBpbiB0aGUgcmlzaW5nIGFuZCBmYWxsaW5nIGZhdGFsaXR5IGNvdW50cyBncmFwaHMgZnJvbSBGaWcuIDIgdG8gRmlnLiAxMi4gQWRkaXRpb25hbCBpbnZlc3RpZ2F0aW9uIGludG8gdGhlIHJhdGUgb2YgcGxhbmUgY3Jhc2ggaW5jaWRlbnRzIChyZWxhdGl2ZSB0byB0aGUgbnVtYmVyIG9mICJzdWNjZXNzZnVsIiBmbGlnaHRzKSBjb3VsZCBhbHNvIHNob3cgYSBzaW1pbGFyIHJpc2luZy9mYWxsaW5nIHBhdHRlcm4gd29ydGggaW52ZXN0aWdhdGluZywgb3IgbWF5IHNob3cgYSBjb25zaXN0ZW50IGRlY2xpbmUgaW4gdGhlIHJhdGUgb2YgcGxhbmUgY3Jhc2hlcyB3aXRoIGZhdGFsaXRpZXMgYW5kIG5vIGFkZGl0aW9uYWwgdGVtcG9yYWwgY2hhbmdlcy4gUmVzZWFyY2ggY29uc2lzdGVudGx5IHNob3dzIHRoYXQgYWlyIHRyYXZlbCBpcyBmYXIgc2FmZXIgdGhhbiBvdGhlciBmb3JtcyBvZiB0cmF2ZWwsIHNvIGZvY3VzaW5nIG9uIHRoZSByYXJlIG91dGNvbWVzIG9mIGNyYXNoZXMgcHJlc2VudHMgb24gaXRzIGZhY2UgYSBkaWZmaWN1bHQgY2hhbGxlbmdlIGR1ZSB0byB0aGUgbGltaXRhdGVkIG9ic2VydmF0aW9uYWwgcmVjb3JkIG9mIHN1Y2ggaW5jaWRlbnRzLiAgCgo=