TODO:

import data from cleaning step

df <- read.csv("Cheapseats.csv", stringsAsFactors = T)

summary of analysis

Refined business quesitons

Winsorize departure_delay_in_minutes and arrival_delay_in_minutes

departure_delay_95 <- quantile(df$departure_delay_in_minutes, .95)
sprintf("%d rows will be changed to the 95th percentile of departure_delay_in_minutes", length(which(df$departure_delay_in_minutes > departure_delay_95)))
[1] "1290 rows will be changed to the 95th percentile of departure_delay_in_minutes"
df[which(df$departure_delay_in_minutes > departure_delay_95), "departure_delay_in_minutes"] = departure_delay_95
arrival_delay_95 <- quantile(df$arrival_delay_in_minutes, .95)
sprintf("%d rows will be changed to the 95th percentile of arrival_delay_in_minutes", length(which(df$arrival_delay_in_minutes > arrival_delay_95)))
[1] "1289 rows will be changed to the 95th percentile of arrival_delay_in_minutes"
df[which(df$arrival_delay_in_minutes > arrival_delay_95),"arrival_delay_in_minutes"] = arrival_delay_95

get the r-squared values for all the variables as predictors of satisfaction

createLM <- function(mydf) {
  r_squares <- list()
  for(i in 2:ncol(mydf)) {
    model <- lm(formula=satisfaction~mydf[[i]], data=mydf)
    r_squares[[i]] <- summary(model)
  }
  
  model_names <- c('satisfaction','airline_status', 'age', 'gender', 'price_sensitivity', 'year_first_flight','num_flights', 'percent_flight_other_airlines', 'type_of_travel','num_loyalty_cards', 'airport_shopping', 'airport_dining','class', 'day_of_month', 'flight_date','origin_city', 'origin_state', 'destination_city','destination_state', 'scheduled_departure_hour', 'departure_delay_in_minutes', 'arrival_delay_in_minutes', 'flight_cancelled','flight_time_in_minutes', 'flight_distance', 'arrival_delay_greater_5_mins')
  
  names(r_squares) <- model_names  # name lists 
  return(r_squares)
}
df <- df[,-which(colnames(df)=="airline_code")]
df <- df[,-which(colnames(df)=="airline_name")]
r_squares <- createLM(df)
for(i in 2:length(r_squares)) {
  v_name <- names(r_squares)[i]
  print(sprintf("The r-squared value for %s: %f", v_name, r_squares[[i]]$r.squared))
}
[1] "The r-squared value for airline_status: 0.123284"
[1] "The r-squared value for age: 0.049398"
[1] "The r-squared value for gender: 0.018651"
[1] "The r-squared value for price_sensitivity: 0.009431"
[1] "The r-squared value for year_first_flight: 0.000059"
[1] "The r-squared value for num_flights: 0.055542"
[1] "The r-squared value for percent_flight_other_airlines: 0.004124"
[1] "The r-squared value for type_of_travel: 0.335375"
[1] "The r-squared value for num_loyalty_cards: 0.007634"
[1] "The r-squared value for airport_shopping: 0.000169"
[1] "The r-squared value for airport_dining: 0.000049"
[1] "The r-squared value for class: 0.002290"
[1] "The r-squared value for day_of_month: 0.000017"
[1] "The r-squared value for flight_date: 0.003585"
[1] "The r-squared value for origin_city: 0.002952"
[1] "The r-squared value for origin_state: 0.001570"
[1] "The r-squared value for destination_city: 0.003460"
[1] "The r-squared value for destination_state: 0.001681"
[1] "The r-squared value for scheduled_departure_hour: 0.000588"
[1] "The r-squared value for departure_delay_in_minutes: 0.009210"
[1] "The r-squared value for arrival_delay_in_minutes: 0.011927"
[1] "The r-squared value for flight_cancelled: 0.000671"
[1] "The r-squared value for flight_time_in_minutes: 0.000013"
[1] "The r-squared value for flight_distance: 0.000005"
[1] "The r-squared value for arrival_delay_greater_5_mins: 0.026848"

perform stepwise regression (backwards) to find best predictors

library(MASS)
model <- lm(satisfaction~airline_status+age+gender+type_of_travel+arrival_delay_greater_5_mins+num_flights+arrival_delay_in_minutes+departure_delay_in_minutes+num_loyalty_cards, data=df)
selected_model <- stepAIC(model, direction="backward", trace=TRUE)
Start:  AIC=-16894.93
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + arrival_delay_in_minutes + 
    departure_delay_in_minutes + num_loyalty_cards

                               Df Sum of Sq   RSS      AIC
- num_loyalty_cards             1       0.1 13537 -16896.7
- arrival_delay_in_minutes      1       0.5 13538 -16896.0
<none>                                      13537 -16894.9
- departure_delay_in_minutes    1       1.7 13539 -16893.6
- age                           1      27.8 13565 -16843.7
- num_flights                   1      39.5 13577 -16821.3
- gender                        1      94.9 13632 -16715.5
- arrival_delay_greater_5_mins  1     375.9 13913 -16185.5
- airline_status                3    1820.4 15358 -13624.2
- type_of_travel                2    5208.8 18746  -8444.4

Step:  AIC=-16896.7
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + arrival_delay_in_minutes + 
    departure_delay_in_minutes

                               Df Sum of Sq   RSS      AIC
- arrival_delay_in_minutes      1       0.5 13538 -16897.8
<none>                                      13537 -16896.7
- departure_delay_in_minutes    1       1.7 13539 -16895.4
- age                           1      31.7 13569 -16838.0
- num_flights                   1      39.6 13577 -16822.9
- gender                        1      95.2 13633 -16716.6
- arrival_delay_greater_5_mins  1     375.9 13913 -16187.5
- airline_status                3    1820.3 15358 -13626.2
- type_of_travel                2    5234.5 18772  -8410.7

Step:  AIC=-16897.8
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + departure_delay_in_minutes

                               Df Sum of Sq   RSS      AIC
<none>                                      13538 -16897.8
- departure_delay_in_minutes    1       2.2 13540 -16895.6
- age                           1      31.6 13570 -16839.2
- num_flights                   1      39.7 13578 -16823.8
- gender                        1      95.3 13633 -16717.7
- arrival_delay_greater_5_mins  1     440.1 13978 -16068.9
- airline_status                3    1820.2 15358 -13627.6
- type_of_travel                2    5235.1 18773  -8411.2
summary(selected_model)

Call:
lm(formula = satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + departure_delay_in_minutes, 
    data = df)

Residuals:
     Min       1Q   Median       3Q      Max 
-3.08100 -0.40458  0.02695  0.49302  2.76463 

Coefficients:
                                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)                      3.7727675  0.0150387 250.871  < 2e-16 ***
airline_statusGold               0.4449571  0.0167983  26.488  < 2e-16 ***
airline_statusPlatinum           0.2906776  0.0260358  11.165  < 2e-16 ***
airline_statusSilver             0.6496885  0.0115067  56.462  < 2e-16 ***
age                             -0.0021793  0.0002799  -7.786 7.19e-15 ***
genderMale                       0.1243370  0.0091996  13.515  < 2e-16 ***
type_of_travelMileage           -0.1572769  0.0173133  -9.084  < 2e-16 ***
type_of_travelPersonal          -1.0909831  0.0109545 -99.592  < 2e-16 ***
arrival_delay_greater_5_minsyes -0.3496571  0.0120358 -29.052  < 2e-16 ***
num_flights                     -0.0029503  0.0003382  -8.723  < 2e-16 ***
departure_delay_in_minutes       0.0005591  0.0002716   2.058   0.0396 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.7221 on 25960 degrees of freedom
Multiple R-squared:  0.4487,    Adjusted R-squared:  0.4485 
F-statistic:  2113 on 10 and 25960 DF,  p-value: < 2.2e-16

Interpretation of Adj R-squared and coefficients

reorder the factors for airline_status and type_of_travel to see what the coefficients are for the current reference variables “Blue”,“Business”

df$airline_status <- factor(df$airline_status, levels=c("Silver","Gold","Platinum", "Blue"))
df$type_of_travel <- factor(df$type_of_travel, levels=c("Personal","Business","Mileage"))
# create the model again 
model <- lm(satisfaction~airline_status+age+gender+type_of_travel+arrival_delay_greater_5_mins+num_flights+arrival_delay_in_minutes+departure_delay_in_minutes+num_loyalty_cards, data=df)
selected_model <- stepAIC(model, direction="backward", trace=TRUE)
Start:  AIC=-16894.93
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + arrival_delay_in_minutes + 
    departure_delay_in_minutes + num_loyalty_cards

                               Df Sum of Sq   RSS      AIC
- num_loyalty_cards             1       0.1 13537 -16896.7
- arrival_delay_in_minutes      1       0.5 13538 -16896.0
<none>                                      13537 -16894.9
- departure_delay_in_minutes    1       1.7 13539 -16893.6
- age                           1      27.8 13565 -16843.7
- num_flights                   1      39.5 13577 -16821.3
- gender                        1      94.9 13632 -16715.5
- arrival_delay_greater_5_mins  1     375.9 13913 -16185.5
- airline_status                3    1820.4 15358 -13624.2
- type_of_travel                2    5208.8 18746  -8444.4

Step:  AIC=-16896.7
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + arrival_delay_in_minutes + 
    departure_delay_in_minutes

                               Df Sum of Sq   RSS      AIC
- arrival_delay_in_minutes      1       0.5 13538 -16897.8
<none>                                      13537 -16896.7
- departure_delay_in_minutes    1       1.7 13539 -16895.4
- age                           1      31.7 13569 -16838.0
- num_flights                   1      39.6 13577 -16822.9
- gender                        1      95.2 13633 -16716.6
- arrival_delay_greater_5_mins  1     375.9 13913 -16187.5
- airline_status                3    1820.3 15358 -13626.2
- type_of_travel                2    5234.5 18772  -8410.7

Step:  AIC=-16897.8
satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + departure_delay_in_minutes

                               Df Sum of Sq   RSS      AIC
<none>                                      13538 -16897.8
- departure_delay_in_minutes    1       2.2 13540 -16895.6
- age                           1      31.6 13570 -16839.2
- num_flights                   1      39.7 13578 -16823.8
- gender                        1      95.3 13633 -16717.7
- arrival_delay_greater_5_mins  1     440.1 13978 -16068.9
- airline_status                3    1820.2 15358 -13627.6
- type_of_travel                2    5235.1 18773  -8411.2
summary(selected_model)

Call:
lm(formula = satisfaction ~ airline_status + age + gender + type_of_travel + 
    arrival_delay_greater_5_mins + num_flights + departure_delay_in_minutes, 
    data = df)

Residuals:
     Min       1Q   Median       3Q      Max 
-3.08100 -0.40458  0.02695  0.49302  2.76463 

Coefficients:
                                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)                      3.3314730  0.0208838 159.525  < 2e-16 ***
airline_statusGold              -0.2047314  0.0186525 -10.976  < 2e-16 ***
airline_statusPlatinum          -0.3590109  0.0272312 -13.184  < 2e-16 ***
airline_statusBlue              -0.6496885  0.0115067 -56.462  < 2e-16 ***
age                             -0.0021793  0.0002799  -7.786 7.19e-15 ***
genderMale                       0.1243370  0.0091996  13.515  < 2e-16 ***
type_of_travelBusiness           1.0909831  0.0109545  99.592  < 2e-16 ***
type_of_travelMileage            0.9337062  0.0185542  50.323  < 2e-16 ***
arrival_delay_greater_5_minsyes -0.3496571  0.0120358 -29.052  < 2e-16 ***
num_flights                     -0.0029503  0.0003382  -8.723  < 2e-16 ***
departure_delay_in_minutes       0.0005591  0.0002716   2.058   0.0396 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.7221 on 25960 degrees of freedom
Multiple R-squared:  0.4487,    Adjusted R-squared:  0.4485 
F-statistic:  2113 on 10 and 25960 DF,  p-value: < 2.2e-16

According to google :), a lower AIC is better, so the last “Step” is the best model:

LS0tCnRpdGxlOiAiQ2hlYXBzZWF0c19saW5lYXJfbW9kZWxpbmcuUm1kIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMjIyMgVE9ETzoKKiBXaW5zb3JpemUgZGVwYXJ0dXJlX2RlbGF5X2luX21pbnV0ZXMgYW5kIGFycml2YWxfZGVsYXlfaW5fbWludXRlcyB0byBoYW5kbGUgb3V0bGllcnMgKGRvbmUpCiogQ3JlYXRlIHNjYXR0ZXIgcGxvdHMgZm9yIHZhcmlhYmxlcywgdy8gYWJsaW5lCiogR2V0IGNvcnJlbGF0aW9uIGNvZWZmaWNpbnRzIGZvciBhbGwgdmFyaWFibGVzCgojIyMjIGltcG9ydCBkYXRhIGZyb20gY2xlYW5pbmcgc3RlcAoKYGBge3J9CmRmIDwtIHJlYWQuY3N2KCJDaGVhcHNlYXRzLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBUKQpgYGAKCiMjIyMgc3VtbWFyeSBvZiBhbmFseXNpcwoqIFRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXM6IGFpcmxpbmVfc3RhdHVzICsgYWdlICsgZ2VuZGVyICsgdHlwZV9vZl90cmF2ZWwgKyBhcnJpdmFsX2RlbGF5X2dyZWF0ZXJfNV9taW5zICsgbnVtX2ZsaWdodHMgcHJvZHVjdCBhIGxpbmVhciBtb2RlbCB0aGF0IGNhbiBleHBsYWluIDQ0JSBvZiB0aGUgdmFyaWFuY2UgYXJvdW5kIHRoZSBtZWFuIG9mIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgInNhdGlzZmFjdGlvbiIiCiogIlNpbHZlciIgc3RhdHVzIGN1c3RvbWVycyBoYXZlIHRoZSBoaWdoZXN0IHNhdGlzZmFjdGlvbiByYXRpbmdzCiogIkJ1c2luZXNzIiB0cmF2ZWxvcnMgaGF2ZSB0aGUgaGlnaGVzdCBzYXRpc2ZhY3Rpb24gcmF0aW5ncyAKKiAiTWFsZXMiIGhhdmUgaGlnaGVyIHJhdGluZ3MgdGhhbiBmZW1hbGVzIAoqIEN1c3RvbWVycyB3aXRoIGRlbGF5cyBsZXNzIHRoYW4gZml2ZSBtaW51dGVzIGhhdmUgaGlnaGVyIHNhdGlzZmFjdGlvbiByYXRpbmdzCiogKkFsbCBpbnRlcnByZXRhdGlvbnMgaGF2ZSB0aGUgY29uZGl0aW9uIG9mIGtlZXBpbmcgYWxsIG90aGVyIGluZGVwZW5kZW50IHZhcmlhYmxlcyBjb25zdGFudCoKCiMjIyMgUmVmaW5lZCBidXNpbmVzcyBxdWVzaXRvbnMKKiBXaHkgYXJlIFNpbHZlciBzdGF0dXMgY3VzdG9tZXJzIG1vcmUgc2F0aXNmaWVkIHRoYW4gdGhlIGhpZ2hlciBQbGF0aW51bSBhbmQgR29sZCBjb3VudGVycGFydHM/CiogV2h5IGFyZSBNYWxlcyBtb3JlIHNhdGlzZmllZCB0aGFuIGZlbWFsZXM/CgojIyMjIFdpbnNvcml6ZSBkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcyBhbmQgYXJyaXZhbF9kZWxheV9pbl9taW51dGVzCisgc2VlIGhvdyBtYW55IHJvd3MgZmFsbCBhYm92ZSB0aGUgOTV0aCBwZXJjZW50aWxlCmBgYHtyfQpkZXBhcnR1cmVfZGVsYXlfOTUgPC0gcXVhbnRpbGUoZGYkZGVwYXJ0dXJlX2RlbGF5X2luX21pbnV0ZXMsIC45NSkKc3ByaW50ZigiJWQgcm93cyB3aWxsIGJlIGNoYW5nZWQgdG8gdGhlIDk1dGggcGVyY2VudGlsZSBvZiBkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcyIsIGxlbmd0aCh3aGljaChkZiRkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcyA+IGRlcGFydHVyZV9kZWxheV85NSkpKQpkZlt3aGljaChkZiRkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcyA+IGRlcGFydHVyZV9kZWxheV85NSksICJkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcyJdID0gZGVwYXJ0dXJlX2RlbGF5Xzk1CgphcnJpdmFsX2RlbGF5Xzk1IDwtIHF1YW50aWxlKGRmJGFycml2YWxfZGVsYXlfaW5fbWludXRlcywgLjk1KQpzcHJpbnRmKCIlZCByb3dzIHdpbGwgYmUgY2hhbmdlZCB0byB0aGUgOTV0aCBwZXJjZW50aWxlIG9mIGFycml2YWxfZGVsYXlfaW5fbWludXRlcyIsIGxlbmd0aCh3aGljaChkZiRhcnJpdmFsX2RlbGF5X2luX21pbnV0ZXMgPiBhcnJpdmFsX2RlbGF5Xzk1KSkpCmRmW3doaWNoKGRmJGFycml2YWxfZGVsYXlfaW5fbWludXRlcyA+IGFycml2YWxfZGVsYXlfOTUpLCJhcnJpdmFsX2RlbGF5X2luX21pbnV0ZXMiXSA9IGFycml2YWxfZGVsYXlfOTUKCmBgYAoKIyMjIyBnZXQgdGhlIHItc3F1YXJlZCB2YWx1ZXMgZm9yIGFsbCB0aGUgdmFyaWFibGVzIGFzIHByZWRpY3RvcnMgb2Ygc2F0aXNmYWN0aW9uCmBgYHtyfQpjcmVhdGVMTSA8LSBmdW5jdGlvbihteWRmKSB7CiAgcl9zcXVhcmVzIDwtIGxpc3QoKQogIGZvcihpIGluIDI6bmNvbChteWRmKSkgewogICAgbW9kZWwgPC0gbG0oZm9ybXVsYT1zYXRpc2ZhY3Rpb25+bXlkZltbaV1dLCBkYXRhPW15ZGYpCiAgICByX3NxdWFyZXNbW2ldXSA8LSBzdW1tYXJ5KG1vZGVsKQogIH0KICAKICBtb2RlbF9uYW1lcyA8LSBjKCdzYXRpc2ZhY3Rpb24nLCdhaXJsaW5lX3N0YXR1cycsICdhZ2UnLCAnZ2VuZGVyJywgJ3ByaWNlX3NlbnNpdGl2aXR5JywgJ3llYXJfZmlyc3RfZmxpZ2h0JywnbnVtX2ZsaWdodHMnLCAncGVyY2VudF9mbGlnaHRfb3RoZXJfYWlybGluZXMnLCAndHlwZV9vZl90cmF2ZWwnLCdudW1fbG95YWx0eV9jYXJkcycsICdhaXJwb3J0X3Nob3BwaW5nJywgJ2FpcnBvcnRfZGluaW5nJywnY2xhc3MnLCAnZGF5X29mX21vbnRoJywgJ2ZsaWdodF9kYXRlJywnb3JpZ2luX2NpdHknLCAnb3JpZ2luX3N0YXRlJywgJ2Rlc3RpbmF0aW9uX2NpdHknLCdkZXN0aW5hdGlvbl9zdGF0ZScsICdzY2hlZHVsZWRfZGVwYXJ0dXJlX2hvdXInLCAnZGVwYXJ0dXJlX2RlbGF5X2luX21pbnV0ZXMnLCAnYXJyaXZhbF9kZWxheV9pbl9taW51dGVzJywgJ2ZsaWdodF9jYW5jZWxsZWQnLCdmbGlnaHRfdGltZV9pbl9taW51dGVzJywgJ2ZsaWdodF9kaXN0YW5jZScsICdhcnJpdmFsX2RlbGF5X2dyZWF0ZXJfNV9taW5zJykKICAKICBuYW1lcyhyX3NxdWFyZXMpIDwtIG1vZGVsX25hbWVzICAjIG5hbWUgbGlzdHMgCgogIHJldHVybihyX3NxdWFyZXMpCn0KCmRmIDwtIGRmWywtd2hpY2goY29sbmFtZXMoZGYpPT0iYWlybGluZV9jb2RlIildCmRmIDwtIGRmWywtd2hpY2goY29sbmFtZXMoZGYpPT0iYWlybGluZV9uYW1lIildCnJfc3F1YXJlcyA8LSBjcmVhdGVMTShkZikKZm9yKGkgaW4gMjpsZW5ndGgocl9zcXVhcmVzKSkgewogIHZfbmFtZSA8LSBuYW1lcyhyX3NxdWFyZXMpW2ldCiAgcHJpbnQoc3ByaW50ZigiVGhlIHItc3F1YXJlZCB2YWx1ZSBmb3IgJXM6ICVmIiwgdl9uYW1lLCByX3NxdWFyZXNbW2ldXSRyLnNxdWFyZWQpKQp9CmBgYAogICsgd2luc29yaXppbmcgdGhlIGRlcGFydHVyZS9hcnJpdmFsIGRlbGF5cyBjaGFuZ2VkIHRoZSBjb2VmZmljaWVudHMgZnJvbSAqLjAwNSBhbmQgLjAwNyogdG8gKi4wMTAgYW5kIC4wMTQqIHJlc3BlY3RpdmVseQoKCiMjIyMgcGVyZm9ybSBzdGVwd2lzZSByZWdyZXNzaW9uIChiYWNrd2FyZHMpIHRvIGZpbmQgYmVzdCBwcmVkaWN0b3JzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoTUFTUykKbW9kZWwgPC0gbG0oc2F0aXNmYWN0aW9ufmFpcmxpbmVfc3RhdHVzK2FnZStnZW5kZXIrdHlwZV9vZl90cmF2ZWwrYXJyaXZhbF9kZWxheV9ncmVhdGVyXzVfbWlucytudW1fZmxpZ2h0cythcnJpdmFsX2RlbGF5X2luX21pbnV0ZXMrZGVwYXJ0dXJlX2RlbGF5X2luX21pbnV0ZXMrbnVtX2xveWFsdHlfY2FyZHMsIGRhdGE9ZGYpCnNlbGVjdGVkX21vZGVsIDwtIHN0ZXBBSUMobW9kZWwsIGRpcmVjdGlvbj0iYmFja3dhcmQiLCB0cmFjZT1UUlVFKQpzdW1tYXJ5KHNlbGVjdGVkX21vZGVsKQpgYGAKCiMjIyMgSW50ZXJwcmV0YXRpb24gb2YgQWRqIFItc3F1YXJlZCBhbmQgY29lZmZpY2llbnRzCiAgKyBUaGlzIG1vZGVsIGV4cGxhaW5zIDQ0JSAoQWRqLiBSLXNxdWFyZWQgdmFsdWUpIG9mIHRoZSB2YXJpYW5jZSBhcm91bmQgdGhlIG1lYW4gb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBzYXRpc2ZhY3Rpb24KICArIEN1c3RvbWVycyB3aG8gYXJlIGVpdGhlciBHb2xkLCBQbGF0aW51bSwgb3IgU2lsdmVyIGhhdmUgc2F0aXNmYWN0aW9uIHJhdGluZ3Mgb2YgKC40NCwgLjI1LCBhbmQgLjYyKSBoaWdoZXIgdGhhbiBjdXN0b21lcnMgdGhhdCBkb24ndCBoYXZlIGEgZmxpZ2h0X3N0YXR1cwogICsgVGhlICJTaWx2ZXIiIHN0YXR1cyBoYXMgdGhlIHN0cm9uZ2VzdCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoIGN1c3RvbWVyIHNhdGlzZmFjdGlvbiBhbW9uZ3N0IHRoZSBhaXJsaW5lIHN0YXR1cyBjYXRlZ29yaWVzLiAgSXRzJyBjb2VmZmljaWVudCBpcyBpbnRlcnByZXRlZCBhcywgImZvciBTaWx2ZXIgc3RhdHVzLCBhbmQgaG9sZGluZyBhbGwgb3RoZXIgdmFyaWFibGVzIGNvbnN0YW50LCB0aGUgc2F0aXNmYWN0aW9uIHNjb3JlIGlzIC42MiBoaWdoZXIgZm9yIFNpbHZlciBmbHllcnMgdGhhbiBmb3IgYWxsIG90aGVyIGFpcmxpbmVfc3RhdHVzIGNhdGVnb3JpZXMiCiAgKyBIb2xkaW5nIGFsbCBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQsIG1hbGUgY3VzdG9tZXJzJyBzYXRpc2ZhY3Rpb24gc2NvcmVzIGFyZSAuMTMgaGlnaGVyIHRoYW4gZmVtYWxlIGN1c3RvbWVycwogICsgSG9sZGxpbmcgYWxsIG90aGVyIHZhcmlhYmxlcyBjb25zdGFudCwgY3VzdG9tZXJzIHRyYXZlbGluZyBmb3IgIk1pbGVhZ2UiIGhhdmUgc2F0aXNmYWN0aW9uIHNjb3JlcyAtLjE1IGxlc3MgdGhhbiBjdXN0b21lcnMgdHJhdmVsaW5nIGZvciAiQnVzaW5lc3MiCiAgKyBIb2xkaW5nIGFsbCBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQsIGN1c3RvbWVycyB0cmF2ZWxpbmcgZm9yICJQZXJzb25hbCIgaGF2ZSBzYXRpc2ZhY3Rpb24gc2NvcmVzIC0xLjEgbGVzcyB0aGFuIGN1c3RvbWVycyB0cmF2ZWxpbmcgZm9yICJCdXNpbmVzcyIKICArIEhvbGRpbmcgYWxsIG90aGVyIHZhcmlhYmxlcyBjb25zdGFudCwgY3VzdG9tZXJzIHdpdGggZmxpZ2h0cyBkZWxheXMgZ3JlYXRlciB0aGFuIDUgbWludXRlcyBoYXZlIHNhdGlzZmFjdGlvbiBzY29yZXMgIC0uMzMgbGVzcyB0aGFuIGN1c3RvbWVycyB3aXRoIGZsaWdodCBkZWxheXMgbGVzcyB0aGFuIDUgbWludXRlcwogIAogIAojIyMjIHJlb3JkZXIgdGhlIGZhY3RvcnMgZm9yIGFpcmxpbmVfc3RhdHVzIGFuZCB0eXBlX29mX3RyYXZlbCB0byBzZWUgd2hhdCB0aGUgY29lZmZpY2llbnRzIGFyZSBmb3IgdGhlIGN1cnJlbnQgcmVmZXJlbmNlIHZhcmlhYmxlcyAiQmx1ZSIsIkJ1c2luZXNzIgpgYGB7cn0KZGYkYWlybGluZV9zdGF0dXMgPC0gZmFjdG9yKGRmJGFpcmxpbmVfc3RhdHVzLCBsZXZlbHM9YygiU2lsdmVyIiwiR29sZCIsIlBsYXRpbnVtIiwgIkJsdWUiKSkKZGYkdHlwZV9vZl90cmF2ZWwgPC0gZmFjdG9yKGRmJHR5cGVfb2ZfdHJhdmVsLCBsZXZlbHM9YygiUGVyc29uYWwiLCJCdXNpbmVzcyIsIk1pbGVhZ2UiKSkKIyBjcmVhdGUgdGhlIG1vZGVsIGFnYWluIAptb2RlbCA8LSBsbShzYXRpc2ZhY3Rpb25+YWlybGluZV9zdGF0dXMrYWdlK2dlbmRlcit0eXBlX29mX3RyYXZlbCthcnJpdmFsX2RlbGF5X2dyZWF0ZXJfNV9taW5zK251bV9mbGlnaHRzK2Fycml2YWxfZGVsYXlfaW5fbWludXRlcytkZXBhcnR1cmVfZGVsYXlfaW5fbWludXRlcytudW1fbG95YWx0eV9jYXJkcywgZGF0YT1kZikKc2VsZWN0ZWRfbW9kZWwgPC0gc3RlcEFJQyhtb2RlbCwgZGlyZWN0aW9uPSJiYWNrd2FyZCIsIHRyYWNlPVRSVUUpCnN1bW1hcnkoc2VsZWN0ZWRfbW9kZWwpCmBgYAoKIyMjIyBBY2NvcmRpbmcgdG8gZ29vZ2xlIDopLCBhIGxvd2VyIEFJQyBpcyBiZXR0ZXIsIHNvIHRoZSBsYXN0ICJTdGVwIiBpcyB0aGUgYmVzdCBtb2RlbDoKKiBzYXRpc2ZhY3Rpb24gfiBhaXJsaW5lX3N0YXR1cyArIGFnZSArIGdlbmRlciArIHR5cGVfb2ZfdHJhdmVsICsgYXJyaXZhbF9kZWxheV9ncmVhdGVyXzVfbWlucyArIG51bV9mbGlnaHRzIChiZXN0IGxpbmVhciBtb2RlbCkKICAgICsgdGhpcyBtb2RlbCBleHBsYWlucyA0NCUgb2YgdGhlIHZhcmlhbmNlIGFyb3VuZCB0aGUgbWVhbiBvZiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIHNhdGlzZmFjdGlvbgogICAgCgoKCgoKCg==