1. Introduction

We are using dataset from MakeMyTrip which offers flight tickets for travel, rail and bus tickets, cab service and hotel booking. We are specifically targeting the hotel booking data scrappped from the website for analysis. This was made available to us from Kaggle

We will be doing an analysis which reflects the best rated hotels in cities across various states in India. Also, we will be narrowing down our analysis to look at which hotels are best in terms of customer experience (Food/Hospitality/Facilities/Value_for_Money). Along with this we will be doing a comparison between the Hotel Rating and the Customer Rating. We will be exploring the data further by making use of Geospatial Analysis.

This analysis will help us know which is the best rated hotel and we can further drill down on basis of best customer experience on a preferred location.

2. Packages Required

As for now, we are using the following libraries:

dplyr - Data Manipulation

tidyr - For Manipulation, Cleaning & Processing data

library(dplyr)
library(tidyr)

3. Data Preparation

Original Datasource: Kaggle

This is a pre-crawled dataset, taken as subset of a bigger dataset (more than 615,000 hotels) that was created by extracting data from MakeMyTrip.com, a travel portal in India. The complete dataset is available on DataStock.

We have 52 variables in the original dataset which we reduced to 15 variables.

Data Cleaning:

  1. There were numerous missing values in our dataset which was the major challenge. Initially, we replaced all missing values with “Unknown” except the ones where we need to perform quantitative analysis (Eg: Location Rating, Food, etc.)

  2. We have worked on “traveller_rating” which was in the following format “Location:5.0/5 | Hospitality:5.0/5 | Facilities:5.0/5 | Cleanliness:5.0/5 | Value for Money:5.0/5 | Food:5.0/5” and was not useful. Hence, we segregated this column into the respective attributes on which they were rated.

First, we read our csv file into R.

D1 = read.csv("makemytrip_com-travel_sample.csv")

Initial review of the data resulted in the removal of few insignificant columns (Ex: country “India” as it is uniform throughout the dataset)

D2 <- D1[, -c(3,4, 5, 6, 8,9, 13, 20, 21,22, 25, 26,28, 29,30,  33:52)]
head(D2)

We have cleaned and standardized all our columns by filling in “Unknown” or “0” at places where there were no values.


sum(grepl("^$",D2$area))
x<-1

D2$area<-sub("^$", "Unknown", D2$area, ignore.case = FALSE, perl = FALSE,
    fixed = FALSE, useBytes = FALSE)
D2$city<-sub("^$", "Unknown", D2$city, ignore.case = FALSE, perl = FALSE,
    fixed = FALSE, useBytes = FALSE)
D2$mmt_review_rating<-sub("\\{\\{ratingCriteria.name\\}\\}\\{\\{ratingCriteria.value\\}\\}", "Unknown", D2$mmt_review_rating, ignore.case = FALSE, perl = FALSE,
             fixed = FALSE, useBytes = FALSE)
D2$mmt_review_rating<-sub("^$", "Unknown", D2$mmt_review_rating, ignore.case = FALSE, perl = FALSE,
             fixed = FALSE, useBytes = FALSE)
D2$hotel_star_rating<-sub("^$", "Unknown", D2$hotel_star_rating, ignore.case = FALSE, perl = FALSE,
             fixed = FALSE, useBytes = FALSE)

D2$hotel_star_rating<-sub("^$", "Unknown", D2$hotel_star_rating, ignore.case = FALSE, perl = FALSE,
                          fixed = FALSE, useBytes = FALSE)
D2$hotel_star_rating<-sub("^$", "Unknown", D2$hotel_star_rating, ignore.case = FALSE, perl = FALSE,
                          fixed = FALSE, useBytes = FALSE)
D2$mmt_tripadvisor_count<-sub("Unknown", "0", D2$mmt_tripadvisor_count, ignore.case = FALSE, perl = FALSE,
                                        fixed = FALSE, useBytes = FALSE)
D2$state<-sub("^$", "Unknown", D2$state, ignore.case = FALSE, perl = FALSE,
                   fixed = FALSE, useBytes = FALSE)

D2$traveller_rating<-sub("^$", "0", D2$traveller_rating, ignore.case = FALSE, perl = FALSE,
                   fixed = FALSE, useBytes = FALSE)

We have cleaned hotel_star_rating from “1 star” format to “1” throughout the column for the respective values.

D2$hotel_star_rating<-sub("star$", "", D2$hotel_star_rating, ignore.case = T, perl = FALSE,
                         fixed = FALSE, useBytes = FALSE)

D2$hotel_star_rating<-as.factor(D2$hotel_star_rating)

We have segregated our “traveller_rating” column into “Location, Hospitality, Facilities, Cleanliness, Value_for_Money, Food”. Thus we have spread out our data into different columns for all the above mentioned attributes for the analysis based on specific customer satisfaction factors.

D2$traveller_rating<-sub("%Value for Money%", "VFM",fixed = FALSE, useBytes = FALSE)

D3<-D2

D5<-separate(D3, traveller_rating, c("Location","d1", "Hospitality","d2","Facilities","d3","Cleanliness","d4","d5","d6","Value_for_Money","d7","Food"), sep = " | ")

D5$Location<-sub("^Location:", "",D5$Location,fixed = FALSE, useBytes = FALSE)
D5$Hospitality<-sub("^Hospitality:", "",D4$Hospitality,fixed = FALSE, useBytes = FALSE)
D5$Facilities<-sub("^Facilities:", "",D4$Facilities,fixed = FALSE, useBytes = FALSE)
D5$Cleanliness<-sub("^Cleanliness:", "",D4$Cleanliness,fixed = FALSE, useBytes = FALSE)
D5$Value_for_Money<-sub("^Money:", "",D4$Value_for_Money,fixed = FALSE, useBytes = FALSE)
D5$Food<-sub("^Food:", "",D4$Food,fixed = FALSE, useBytes = FALSE)

D6 <- D5[, -c(18,20,22,24,25,26)]

On separating “traveller_rating” column into “Location, Hospitality, Facilities, Cleanliness, Value_for_Money, Food” we were getting values as “4/5” format which we converted to “4”


D6$Location<-sub("/5$", "", D6$Location, ignore.case = FALSE, perl = FALSE,
                            fixed = FALSE, useBytes = FALSE)
D6$Hospitality<-sub("/5$", "", D6$Hospitality, ignore.case = FALSE, perl = FALSE,
                 fixed = FALSE, useBytes = FALSE)
D6$Facilities<-sub("/5$", "", D6$Facilities, ignore.case = FALSE, perl = FALSE,
                 fixed = FALSE, useBytes = FALSE)
D6$Cleanliness<-sub("/5$", "", D6$Cleanliness, ignore.case = FALSE, perl = FALSE,
                    fixed = FALSE, useBytes = FALSE)
D6$Value_for_Money<-sub("/5$", "", D6$Value_for_Money, ignore.case = FALSE, perl = FALSE,
                    fixed = FALSE, useBytes = FALSE)
D6$Food<-sub("/5$", "", D6$Food, ignore.case = FALSE, perl = FALSE,
                        fixed = FALSE, useBytes = FALSE)
D7 <- D6[, -c(9,11,13:18)]

For final analysis we carried out data conversion for required columns into numeric

D7$mmt_location_rating <- sub("..","",D7$mmt_location_rating)
D7$hotel_star_rating =  as.numeric(D7$hotel_star_rating)
D7$latitude =  as.numeric(D7$latitude)
D7$mmt_location_rating = as.numeric(D7$mmt_location_rating)
D7$mmt_review_count = as.numeric(D7$mmt_review_count)
D7$mmt_review_score = as.numeric(D7$mmt_review_score)
D7$mmt_tripadvisor_count = as.numeric(D7$mmt_tripadvisor_count)
D7$Location = as.numeric(D7$Location)
D7$Facilities = as.numeric(D7$Facilities)
D7$Cleanliness = as.numeric(D7$Cleanliness)
D7$Value_for_Money = as.numeric(D7$Value_for_Money)
D7$Food = as.numeric(D7$Food)

Here we have the summary information for our cleaned dataset

str(D7)
'data.frame':   20063 obs. of  15 variables:
 $ area                 : chr  "Hardasji Ki Magri" "Near Nai Gaon" "Near Bagore Ki Haveli" "Dabok" ...
 $ city                 : chr  "Udaipur" "Udaipur" "Udaipur" "Udaipur" ...
 $ hotel_star_rating    : num  0 0 0 0 0 0 0 0 0 0 ...
 $ is_value_plus        : Factor w/ 9 levels "","0","103","43",..: 7 7 7 7 7 7 7 7 7 7 ...
 $ latitude             : num  5161 5065 5140 5229 5143 ...
 $ longitude            : num  73.7 73.6 73.7 73.9 73.7 ...
 $ mmt_location_rating  : num  NA NA NA NA NA NA NA NA NA NA ...
 $ mmt_review_count     : num  1 1 1 1 1 1 1 1 1 1 ...
 $ mmt_review_score     : num  46 46 1 1 38 42 1 40 49 48 ...
 $ mmt_tripadvisor_count: num  504 323 113 285 80 581 630 138 328 50 ...
 $ Location             : num  NA NA NA NA NA NA NA NA NA NA ...
 $ Facilities           : num  NA NA NA NA NA NA NA NA NA NA ...
 $ Cleanliness          : num  NA NA NA NA NA NA NA NA NA NA ...
 $ Value_for_Money      : num  NA NA NA NA NA NA NA NA NA NA ...
 $ Food                 : num  NA NA NA NA NA NA NA NA NA NA ...
summary(D7)
     area               city           hotel_star_rating is_value_plus  
 Length:20063       Length:20063       Min.   :0         no     :19297  
 Class :character   Class :character   1st Qu.:0         yes    :  740  
 Mode  :character   Mode  :character   Median :0                :   20  
                                       Mean   :0         0      :    1  
                                       3rd Qu.:0         103    :    1  
                                       Max.   :0         43     :    1  
                                                         (Other):    3  
    latitude        longitude      mmt_location_rating mmt_review_count
 Min.   :   1.0   Min.   :  0.00   Min.   :0.00        Min.   :  1.00  
 1st Qu.: 213.5   1st Qu.: 72.56   1st Qu.:4.00        1st Qu.:  1.00  
 Median :3375.0   Median : 75.85   Median :4.50        Median :  1.00  
 Mean   :3796.4   Mean   : 59.34   Mean   :4.55        Mean   : 46.79  
 3rd Qu.:6706.5   3rd Qu.: 77.62   3rd Qu.:5.00        3rd Qu.: 37.00  
 Max.   :9962.0   Max.   :130.00   Max.   :9.00        Max.   :301.00  
                  NA's   :42       NA's   :13360                       
 mmt_review_score mmt_tripadvisor_count    Location       Facilities     Cleanliness   
 Min.   : 1.00    Min.   :  1.0         Min.   :0.000   Min.   :1.000   Min.   :0.000  
 1st Qu.: 1.00    1st Qu.:  1.0         1st Qu.:3.900   1st Qu.:3.300   1st Qu.:3.300  
 Median : 1.00    Median : 20.0         Median :4.300   Median :3.900   Median :4.000  
 Mean   :18.15    Mean   :159.2         Mean   :4.138   Mean   :3.728   Mean   :3.805  
 3rd Qu.:40.00    3rd Qu.:296.0         3rd Qu.:4.700   3rd Qu.:4.300   3rd Qu.:4.500  
 Max.   :52.00    Max.   :651.0         Max.   :5.000   Max.   :5.000   Max.   :5.000  
                                        NA's   :13287   NA's   :13452   NA's   :13452  
 Value_for_Money      Food      
 Min.   :0.000   Min.   :0.000  
 1st Qu.:3.500   1st Qu.:2.300  
 Median :4.000   Median :3.300  
 Mean   :3.903   Mean   :3.079  
 3rd Qu.:4.500   3rd Qu.:4.000  
 Max.   :5.000   Max.   :5.000  
 NA's   :13452   NA's   :13452  
head(D7)
tail(D7)

4. Data Exploration Proposal:

  1. The data from MakeMyTrip can be explored using the various ratings provided by the customer on many parameters such as Value_For_Money, Hospitality, Cleanliness, Location, etc.
  2. As for now we have explored the travellers rating data but we can further broaden our analysis on the parameter traveller_type which includes family, solo, business trip.
  3. We plan to use bar graphs, scatter plot, ggplot2 for getting useful insights into our data. (Eg: Ratings vs Cities, Cities vs Review Count )
  4. We plan to run regression analysis to find how rating is impacted due to variation in factors such as “Cleanliness/ Location/ Value_for_Money”

This analysis will help us understand the trend of the specific customer types and their preferences while selecting hotels in India. Also, we will be incorporating geospatial analysis which will help us visualize the geopoints which attract more customers.

LS0tDQp0aXRsZTogIioqTWFrZU15VHJpcCBIb3RlbCBBbmFseXNpcyoqIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIDEuIEludHJvZHVjdGlvbg0KDQpXZSBhcmUgdXNpbmcgZGF0YXNldCBmcm9tIFtNYWtlTXlUcmlwXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NYWtlTXlUcmlwKSB3aGljaCBvZmZlcnMgZmxpZ2h0IHRpY2tldHMgZm9yIHRyYXZlbCwgcmFpbCBhbmQgYnVzIHRpY2tldHMsIGNhYiBzZXJ2aWNlIGFuZCBob3RlbCBib29raW5nLiBXZSBhcmUgc3BlY2lmaWNhbGx5IHRhcmdldGluZyB0aGUgaG90ZWwgYm9va2luZyBkYXRhIHNjcmFwcHBlZCBmcm9tIHRoZSB3ZWJzaXRlIGZvciBhbmFseXNpcy4NClRoaXMgd2FzIG1hZGUgYXZhaWxhYmxlIHRvIHVzIGZyb20gW0thZ2dsZV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9Qcm9tcHRDbG91ZEhRL2hvdGVscy1vbi1tYWtlbXl0cmlwKQ0KDQoNCldlIHdpbGwgYmUgZG9pbmcgYW4gYW5hbHlzaXMgd2hpY2ggcmVmbGVjdHMgdGhlIGJlc3QgcmF0ZWQgaG90ZWxzIGluIGNpdGllcyBhY3Jvc3MgdmFyaW91cyBzdGF0ZXMgaW4gSW5kaWEuDQpBbHNvLCB3ZSB3aWxsIGJlIG5hcnJvd2luZyBkb3duIG91ciBhbmFseXNpcyB0byBsb29rIGF0IHdoaWNoIGhvdGVscyBhcmUgYmVzdCBpbiB0ZXJtcyBvZiBjdXN0b21lciBleHBlcmllbmNlIChGb29kL0hvc3BpdGFsaXR5L0ZhY2lsaXRpZXMvVmFsdWVfZm9yX01vbmV5KS4gQWxvbmcgd2l0aCB0aGlzIHdlIHdpbGwgYmUgZG9pbmcgYSBjb21wYXJpc29uIGJldHdlZW4gdGhlIEhvdGVsIFJhdGluZyBhbmQgdGhlIEN1c3RvbWVyIFJhdGluZy4gV2Ugd2lsbCBiZSBleHBsb3JpbmcgdGhlIGRhdGEgZnVydGhlciBieSBtYWtpbmcgdXNlIG9mIEdlb3NwYXRpYWwgQW5hbHlzaXMuDQoNClRoaXMgYW5hbHlzaXMgd2lsbCBoZWxwIHVzIGtub3cgd2hpY2ggaXMgdGhlIGJlc3QgcmF0ZWQgaG90ZWwgYW5kIHdlIGNhbiBmdXJ0aGVyIGRyaWxsIGRvd24gb24gYmFzaXMgb2YgYmVzdCBjdXN0b21lciBleHBlcmllbmNlIG9uIGEgcHJlZmVycmVkIGxvY2F0aW9uLg0KDQoNCg0KIyMgMi4gUGFja2FnZXMgUmVxdWlyZWQNCg0KQXMgZm9yIG5vdywgd2UgYXJlIHVzaW5nIHRoZSBmb2xsb3dpbmcgbGlicmFyaWVzOg0KDQoqKmRwbHlyKiogLSBEYXRhIE1hbmlwdWxhdGlvbg0KDQoqKnRpZHlyKiogLSBGb3IgTWFuaXB1bGF0aW9uLCBDbGVhbmluZyAmIFByb2Nlc3NpbmcgZGF0YQ0KYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmBgYA0KDQoNCiMjIDMuIERhdGEgUHJlcGFyYXRpb24NCk9yaWdpbmFsIERhdGFzb3VyY2U6IFtLYWdnbGVdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vUHJvbXB0Q2xvdWRIUS9ob3RlbHMtb24tbWFrZW15dHJpcCkNCg0KVGhpcyBpcyBhIHByZS1jcmF3bGVkIGRhdGFzZXQsIHRha2VuIGFzIHN1YnNldCBvZiBhIGJpZ2dlciBkYXRhc2V0IChtb3JlIHRoYW4gNjE1LDAwMCBob3RlbHMpIHRoYXQgd2FzIGNyZWF0ZWQgYnkgZXh0cmFjdGluZyBkYXRhIGZyb20gTWFrZU15VHJpcC5jb20sIGEgdHJhdmVsIHBvcnRhbCBpbiBJbmRpYS4gVGhlIGNvbXBsZXRlIGRhdGFzZXQgaXMgYXZhaWxhYmxlIG9uIFtEYXRhU3RvY2tdKGh0dHBzOi8vd3d3LnByb21wdGNsb3VkLmNvbS9kYXRhc3RvY2stYWNjZXNzLXJlYWR5LXRvLXVzZS1kYXRhc2V0cy8/dXRtX3NvdXJjZT1tbS1rYWdnbGUmdXRtX21lZGl1bT1yZWZlcnJhbCkuDQoNCldlIGhhdmUgNTIgdmFyaWFibGVzIGluIHRoZSBvcmlnaW5hbCBkYXRhc2V0IHdoaWNoIHdlIHJlZHVjZWQgdG8gMTUgdmFyaWFibGVzLg0KDQoNCioqRGF0YSBDbGVhbmluZyoqOiANCg0KMS4gVGhlcmUgd2VyZSBudW1lcm91cyBtaXNzaW5nIHZhbHVlcyBpbiBvdXIgZGF0YXNldCB3aGljaCB3YXMgdGhlIG1ham9yIGNoYWxsZW5nZS4gSW5pdGlhbGx5LCB3ZSByZXBsYWNlZCBhbGwgbWlzc2luZyB2YWx1ZXMgd2l0aCAiVW5rbm93biIgZXhjZXB0IHRoZSBvbmVzIHdoZXJlIHdlIG5lZWQgdG8gcGVyZm9ybSBxdWFudGl0YXRpdmUgYW5hbHlzaXMgKEVnOiBMb2NhdGlvbiBSYXRpbmcsIEZvb2QsIGV0Yy4pDQoNCjIuIFdlIGhhdmUgd29ya2VkIG9uICJ0cmF2ZWxsZXJfcmF0aW5nIiB3aGljaCB3YXMgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQgIkxvY2F0aW9uOjUuMC81IHwgSG9zcGl0YWxpdHk6NS4wLzUgfCBGYWNpbGl0aWVzOjUuMC81IHwgQ2xlYW5saW5lc3M6NS4wLzUgfCBWYWx1ZSBmb3IgTW9uZXk6NS4wLzUgfCBGb29kOjUuMC81IiBhbmQgd2FzIG5vdCB1c2VmdWwuIEhlbmNlLCB3ZSBzZWdyZWdhdGVkIHRoaXMgY29sdW1uIGludG8gdGhlIHJlc3BlY3RpdmUgYXR0cmlidXRlcyBvbiB3aGljaCB0aGV5IHdlcmUgcmF0ZWQuDQoNCkZpcnN0LCB3ZSByZWFkIG91ciBjc3YgZmlsZSBpbnRvIFIuDQoNCmBgYHtyfQ0KRDEgPSByZWFkLmNzdigibWFrZW15dHJpcF9jb20tdHJhdmVsX3NhbXBsZS5jc3YiKQ0KYGBgDQpJbml0aWFsIHJldmlldyBvZiB0aGUgZGF0YSByZXN1bHRlZCBpbiB0aGUgcmVtb3ZhbCBvZiBmZXcgaW5zaWduaWZpY2FudCBjb2x1bW5zIChFeDogY291bnRyeSAiSW5kaWEiIGFzIGl0IGlzIHVuaWZvcm0gdGhyb3VnaG91dCB0aGUgZGF0YXNldCkNCmBgYHtyfQ0KRDIgPC0gRDFbLCAtYygzLDQsIDUsIDYsIDgsOSwgMTMsIDIwLCAyMSwyMiwgMjUsIDI2LDI4LCAyOSwzMCwgIDMzOjUyKV0NCmhlYWQoRDIpDQpgYGANCg0KDQpXZSBoYXZlIGNsZWFuZWQgYW5kIHN0YW5kYXJkaXplZCBhbGwgb3VyIGNvbHVtbnMgYnkgZmlsbGluZyBpbiAiVW5rbm93biIgb3IgIjAiIGF0IHBsYWNlcyB3aGVyZSB0aGVyZSB3ZXJlIG5vIHZhbHVlcy4NCmBgYHtyfQ0KDQpzdW0oZ3JlcGwoIl4kIixEMiRhcmVhKSkNCng8LTENCg0KRDIkYXJlYTwtc3ViKCJeJCIsICJVbmtub3duIiwgRDIkYXJlYSwgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgIGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQpEMiRjaXR5PC1zdWIoIl4kIiwgIlVua25vd24iLCBEMiRjaXR5LCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQyJG1tdF9yZXZpZXdfcmF0aW5nPC1zdWIoIlxce1xce3JhdGluZ0NyaXRlcmlhLm5hbWVcXH1cXH1cXHtcXHtyYXRpbmdDcml0ZXJpYS52YWx1ZVxcfVxcfSIsICJVbmtub3duIiwgRDIkbW10X3Jldmlld19yYXRpbmcsIGlnbm9yZS5jYXNlID0gRkFMU0UsIHBlcmwgPSBGQUxTRSwNCiAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDIkbW10X3Jldmlld19yYXRpbmc8LXN1YigiXiQiLCAiVW5rbm93biIsIEQyJG1tdF9yZXZpZXdfcmF0aW5nLCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQyJGhvdGVsX3N0YXJfcmF0aW5nPC1zdWIoIl4kIiwgIlVua25vd24iLCBEMiRob3RlbF9zdGFyX3JhdGluZywgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgIGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQoNCkQyJGhvdGVsX3N0YXJfcmF0aW5nPC1zdWIoIl4kIiwgIlVua25vd24iLCBEMiRob3RlbF9zdGFyX3JhdGluZywgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDIkaG90ZWxfc3Rhcl9yYXRpbmc8LXN1YigiXiQiLCAiVW5rbm93biIsIEQyJGhvdGVsX3N0YXJfcmF0aW5nLCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQpEMiRtbXRfdHJpcGFkdmlzb3JfY291bnQ8LXN1YigiVW5rbm93biIsICIwIiwgRDIkbW10X3RyaXBhZHZpc29yX2NvdW50LCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQyJHN0YXRlPC1zdWIoIl4kIiwgIlVua25vd24iLCBEMiRzdGF0ZSwgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgIGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQoNCkQyJHRyYXZlbGxlcl9yYXRpbmc8LXN1YigiXiQiLCAiMCIsIEQyJHRyYXZlbGxlcl9yYXRpbmcsIGlnbm9yZS5jYXNlID0gRkFMU0UsIHBlcmwgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KDQpgYGANCg0KV2UgaGF2ZSBjbGVhbmVkIGhvdGVsX3N0YXJfcmF0aW5nIGZyb20gIjEgc3RhciIgZm9ybWF0IHRvICIxIiB0aHJvdWdob3V0IHRoZSBjb2x1bW4gZm9yIHRoZSByZXNwZWN0aXZlIHZhbHVlcy4NCg0KYGBge3J9DQpEMiRob3RlbF9zdGFyX3JhdGluZzwtc3ViKCJzdGFyJCIsICIiLCBEMiRob3RlbF9zdGFyX3JhdGluZywgaWdub3JlLmNhc2UgPSBULCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCg0KRDIkaG90ZWxfc3Rhcl9yYXRpbmc8LWFzLmZhY3RvcihEMiRob3RlbF9zdGFyX3JhdGluZykNCg0KYGBgDQoNCg0KDQpXZSBoYXZlIHNlZ3JlZ2F0ZWQgb3VyICJ0cmF2ZWxsZXJfcmF0aW5nIiBjb2x1bW4gaW50byAiTG9jYXRpb24sIEhvc3BpdGFsaXR5LCBGYWNpbGl0aWVzLCBDbGVhbmxpbmVzcywgVmFsdWVfZm9yX01vbmV5LCBGb29kIi4gVGh1cyB3ZSBoYXZlIHNwcmVhZCBvdXQgb3VyIGRhdGEgaW50byBkaWZmZXJlbnQgY29sdW1ucyBmb3IgYWxsIHRoZSBhYm92ZSBtZW50aW9uZWQgYXR0cmlidXRlcyBmb3IgdGhlIGFuYWx5c2lzIGJhc2VkIG9uIHNwZWNpZmljIGN1c3RvbWVyIHNhdGlzZmFjdGlvbiBmYWN0b3JzLg0KDQpgYGB7cn0NCkQyJHRyYXZlbGxlcl9yYXRpbmc8LXN1YigiJVZhbHVlIGZvciBNb25leSUiLCAiVkZNIixmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KDQpEMzwtRDINCg0KRDU8LXNlcGFyYXRlKEQzLCB0cmF2ZWxsZXJfcmF0aW5nLCBjKCJMb2NhdGlvbiIsImQxIiwgIkhvc3BpdGFsaXR5IiwiZDIiLCJGYWNpbGl0aWVzIiwiZDMiLCJDbGVhbmxpbmVzcyIsImQ0IiwiZDUiLCJkNiIsIlZhbHVlX2Zvcl9Nb25leSIsImQ3IiwiRm9vZCIpLCBzZXAgPSAiIHwgIikNCg0KRDUkTG9jYXRpb248LXN1YigiXkxvY2F0aW9uOiIsICIiLEQ1JExvY2F0aW9uLGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQpENSRIb3NwaXRhbGl0eTwtc3ViKCJeSG9zcGl0YWxpdHk6IiwgIiIsRDQkSG9zcGl0YWxpdHksZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQ1JEZhY2lsaXRpZXM8LXN1YigiXkZhY2lsaXRpZXM6IiwgIiIsRDQkRmFjaWxpdGllcyxmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDUkQ2xlYW5saW5lc3M8LXN1YigiXkNsZWFubGluZXNzOiIsICIiLEQ0JENsZWFubGluZXNzLGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQpENSRWYWx1ZV9mb3JfTW9uZXk8LXN1YigiXk1vbmV5OiIsICIiLEQ0JFZhbHVlX2Zvcl9Nb25leSxmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDUkRm9vZDwtc3ViKCJeRm9vZDoiLCAiIixENCRGb29kLGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQoNCkQ2IDwtIEQ1WywgLWMoMTgsMjAsMjIsMjQsMjUsMjYpXQ0KDQpgYGANCg0KT24gc2VwYXJhdGluZyAidHJhdmVsbGVyX3JhdGluZyIgY29sdW1uIGludG8gIkxvY2F0aW9uLCBIb3NwaXRhbGl0eSwgRmFjaWxpdGllcywgQ2xlYW5saW5lc3MsIFZhbHVlX2Zvcl9Nb25leSwgRm9vZCIgd2Ugd2VyZSBnZXR0aW5nIHZhbHVlcyBhcyAiNC81IiBmb3JtYXQgd2hpY2ggd2UgY29udmVydGVkIHRvICI0Ig0KDQpgYGB7cn0NCg0KRDYkTG9jYXRpb248LXN1YigiLzUkIiwgIiIsIEQ2JExvY2F0aW9uLCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQ2JEhvc3BpdGFsaXR5PC1zdWIoIi81JCIsICIiLCBENiRIb3NwaXRhbGl0eSwgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDYkRmFjaWxpdGllczwtc3ViKCIvNSQiLCAiIiwgRDYkRmFjaWxpdGllcywgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDYkQ2xlYW5saW5lc3M8LXN1YigiLzUkIiwgIiIsIEQ2JENsZWFubGluZXNzLCBpZ25vcmUuY2FzZSA9IEZBTFNFLCBwZXJsID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgIGZpeGVkID0gRkFMU0UsIHVzZUJ5dGVzID0gRkFMU0UpDQpENiRWYWx1ZV9mb3JfTW9uZXk8LXN1YigiLzUkIiwgIiIsIEQ2JFZhbHVlX2Zvcl9Nb25leSwgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICBmaXhlZCA9IEZBTFNFLCB1c2VCeXRlcyA9IEZBTFNFKQ0KRDYkRm9vZDwtc3ViKCIvNSQiLCAiIiwgRDYkRm9vZCwgaWdub3JlLmNhc2UgPSBGQUxTRSwgcGVybCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgZml4ZWQgPSBGQUxTRSwgdXNlQnl0ZXMgPSBGQUxTRSkNCkQ3IDwtIEQ2WywgLWMoOSwxMSwxMzoxOCldDQoNCmBgYA0KDQpGb3IgZmluYWwgYW5hbHlzaXMgd2UgY2FycmllZCBvdXQgZGF0YSBjb252ZXJzaW9uIGZvciByZXF1aXJlZCBjb2x1bW5zIGludG8gbnVtZXJpYw0KYGBge3J9DQpENyRtbXRfbG9jYXRpb25fcmF0aW5nIDwtIHN1YigiLi4iLCIiLEQ3JG1tdF9sb2NhdGlvbl9yYXRpbmcpDQpENyRob3RlbF9zdGFyX3JhdGluZyA9ICBhcy5udW1lcmljKEQ3JGhvdGVsX3N0YXJfcmF0aW5nKQ0KRDckbGF0aXR1ZGUgPSAgYXMubnVtZXJpYyhENyRsYXRpdHVkZSkNCkQ3JG1tdF9sb2NhdGlvbl9yYXRpbmcgPSBhcy5udW1lcmljKEQ3JG1tdF9sb2NhdGlvbl9yYXRpbmcpDQpENyRtbXRfcmV2aWV3X2NvdW50ID0gYXMubnVtZXJpYyhENyRtbXRfcmV2aWV3X2NvdW50KQ0KRDckbW10X3Jldmlld19zY29yZSA9IGFzLm51bWVyaWMoRDckbW10X3Jldmlld19zY29yZSkNCkQ3JG1tdF90cmlwYWR2aXNvcl9jb3VudCA9IGFzLm51bWVyaWMoRDckbW10X3RyaXBhZHZpc29yX2NvdW50KQ0KRDckTG9jYXRpb24gPSBhcy5udW1lcmljKEQ3JExvY2F0aW9uKQ0KRDckRmFjaWxpdGllcyA9IGFzLm51bWVyaWMoRDckRmFjaWxpdGllcykNCkQ3JENsZWFubGluZXNzID0gYXMubnVtZXJpYyhENyRDbGVhbmxpbmVzcykNCkQ3JFZhbHVlX2Zvcl9Nb25leSA9IGFzLm51bWVyaWMoRDckVmFsdWVfZm9yX01vbmV5KQ0KRDckRm9vZCA9IGFzLm51bWVyaWMoRDckRm9vZCkNCmBgYA0KDQoNCkhlcmUgd2UgaGF2ZSB0aGUgc3VtbWFyeSBpbmZvcm1hdGlvbiBmb3Igb3VyIGNsZWFuZWQgZGF0YXNldA0KYGBge3J9DQpzdHIoRDcpDQpzdW1tYXJ5KEQ3KQ0KaGVhZChENykNCnRhaWwoRDcpDQoNCmBgYA0KDQoNCiMjIDQuIERhdGEgRXhwbG9yYXRpb24gUHJvcG9zYWw6DQoNCjEuIFRoZSBkYXRhIGZyb20gTWFrZU15VHJpcCBjYW4gYmUgZXhwbG9yZWQgdXNpbmcgdGhlIHZhcmlvdXMgcmF0aW5ncyBwcm92aWRlZCBieSB0aGUgY3VzdG9tZXIgb24gbWFueSBwYXJhbWV0ZXJzIHN1Y2ggYXMgVmFsdWVfRm9yX01vbmV5LCBIb3NwaXRhbGl0eSwgQ2xlYW5saW5lc3MsIExvY2F0aW9uLCBldGMuICANCjIuIEFzIGZvciBub3cgd2UgaGF2ZSBleHBsb3JlZCB0aGUgdHJhdmVsbGVycyByYXRpbmcgZGF0YSBidXQgd2UgY2FuIGZ1cnRoZXIgYnJvYWRlbiBvdXIgYW5hbHlzaXMgb24gdGhlIHBhcmFtZXRlciB0cmF2ZWxsZXJfdHlwZSB3aGljaCBpbmNsdWRlcyBmYW1pbHksIHNvbG8sIGJ1c2luZXNzIHRyaXAuDQozLiBXZSBwbGFuIHRvIHVzZSBiYXIgZ3JhcGhzLCBzY2F0dGVyIHBsb3QsIGdncGxvdDIgZm9yIGdldHRpbmcgdXNlZnVsIGluc2lnaHRzIGludG8gb3VyIGRhdGEuIChFZzogUmF0aW5ncyB2cyBDaXRpZXMsIENpdGllcyB2cyBSZXZpZXcgQ291bnQgKQ0KNC4gV2UgcGxhbiB0byBydW4gcmVncmVzc2lvbiBhbmFseXNpcyB0byBmaW5kIGhvdyByYXRpbmcgaXMgaW1wYWN0ZWQgZHVlIHRvIHZhcmlhdGlvbiBpbiBmYWN0b3JzIHN1Y2ggYXMgIkNsZWFubGluZXNzLyBMb2NhdGlvbi8gVmFsdWVfZm9yX01vbmV5Ig0KDQpUaGlzIGFuYWx5c2lzIHdpbGwgaGVscCB1cyB1bmRlcnN0YW5kIHRoZSB0cmVuZCBvZiB0aGUgc3BlY2lmaWMgY3VzdG9tZXIgdHlwZXMgYW5kIHRoZWlyIHByZWZlcmVuY2VzIHdoaWxlIHNlbGVjdGluZyBob3RlbHMgaW4gSW5kaWEuIEFsc28sIHdlIHdpbGwgYmUgaW5jb3Jwb3JhdGluZyBnZW9zcGF0aWFsIGFuYWx5c2lzIHdoaWNoIHdpbGwgaGVscCB1cyB2aXN1YWxpemUgdGhlIGdlb3BvaW50cyB3aGljaCBhdHRyYWN0IG1vcmUgY3VzdG9tZXJzLg==