About

This worksheet includes three main tasks on data outliers, data preparation, and data modeling. The lab requires the use of Microsoft Excel, R, and ERDplus.

Setup

Remember to always set your working directory to the source file location. Go to ‘Session’, scroll down to ‘Set Working Directory’, and click ‘To Source File Location’. Read carefully the below and follow the instructions to complete the tasks and answer any questions. Submit your work to RPubs as detailed in previous notes.

Note

For your assignment you may be using different data sets than what is included here. Always read carefully the instructions on Sakai. For clarity, tasks/questions to be completed/answered are highlighted in red color (visible in preview) and numbered according to their particular placement in the task section. Quite often you will need to add your own code chunk.

Execute all code chunks, preview, publish, and submit link on Sakai.


Task 1: Data Outliers

First, we must calculate the mean, standard deviation, maximum, and minimum for the Age column using R.

In R, we must read in the file again, extract the column and find the values that are asked for.

rr #Read File mydata = read.csv(file=/creditrisk.csv) #Name the extracted variable age = mydata$Age

##### 1A) Fill in the code chunk below to calculate and display each result. Refer to previous worksheets and on-line help for some commands.

rr #Calculate the average age below. mean(age)

[1] 34.39765

rr #Calculate the standard deviation of age below. sd(age)

[1] 11.04513

rr #Calculate the maxima of age below. Look in Help to find the right command for maxima max(age)

[1] 73

rr #Calculate the minima of age below. Look in Help to find the right command for minima min(age)

[1] 18

Next, we will use the formula from class to detect any outliers. An outlier is a value that “lies outside” most of the other values in a set of data. A common way to estimate the upper and lower limits is to take the mean (+ or -) 3 * standard deviation.

##### 1B) Write and execute the code chunk corresponding to the above formula to calculate the upper and lower limits for age. Display your results. Based on the limits do you think there are outliers? Explain your answer.

rr UL=mean(age) + 3 * sd(age) UL

[1] 67.53302

rr LL=mean(age) - 3 * sd(age) LL

[1] 1.262269

According to the answer of 1B and 1A, it states that there are outliers. Since the minimum 18 is larger than lower limit 1.262269, that means minimum 18 is in the boundaries. However, the maximum 73 is bigger than upper limit is 67.53302, that says 73 is not within the boundaries, and the outliners exist.

Another similar method to find the upper and lower thresholds, discussed in many introductory statistics courses, involves finding the interquartile range. Follow along below to see how we first calculate the interquartile range..

rr quantile(age)

  0%  25%  50%  75% 100% 
  18   26   32   41   73 

rr lowerq = quantile(age)[2] upperq = quantile(age)[4] iqr = upperq - lowerq

Next we calculate the limiting thresholds. A threshold here is the boundary that determines if a value is an outlier. If the value falls above the upper threshold or below the lower threshold, it is an outlier.

To calculate the upper threshold:

rr upperthreshold = (iqr * 1.5) + upperq upperthreshold

 75% 
63.5 

Below is the lower threshold:

rr lowerthreshold = lowerq - (iqr * 1.5) lowerthreshold

25% 
3.5 

A good way to undertsand the above calculations is to visualize the results using a box and whisker plot. The top and lower ends of the box correspond to the upper and lower quartiles. The median is marked by a bolded line. The whiskers are the lines connecting the upper and lower quartiles to upper and lower thresholds. Any points beyond the thresholds is a potential outlier.

rr boxplot(age)

##### 1C) From the box plot representation are there any outliers? How many can you count? How does your answer reconcile with the result from Task 1B? #### From the box plot above, there seem to be five outliers on the upper end of this data and no outliers on the lower end. This observation confirms the statement made in the task 1B. —————

Task 2: Data Preparation

Next, we will read the file creditriskorg.csv into R as provided in its original form. Unlike the cleaned file creditrisk.csv, the original dataset will require some data preparation.

rr newdata = read.csv(file=/creditriskorg.csv) head(newdata)

We observe a new line is inserted with the header labels X, X.1, ... and that the true column headers are shifted down. This is because of the empty line in the original dataset. To account for this detail we must skip one line when reading the file.

rr newdata = read.csv(file=/creditriskorg.csv,skip=1) head(newdata)

Next we want to extract the Checking column and then find the average of checking, smilar to what we did in the previous lab. When we try to execute the code chunk below notice that we get an error.

rr checking = newdata$Checking # command to extract the Checking column from the data file newdata mean(checking)

argument is not numeric or logical: returning NA
[1] NA

To resolve the error, we must understand first where it’s source. There are missing values in the csv file represented by the symbol $-. Missing data is quite common as most datasets are not perfect. Additionally, there are commas within the excel spreadsheet, and R does not recognize that ‘1,234’ is equivalent to ‘1234’. Lastly, there are ‘$’ symbols throughout the file which is not a numerical symbol either.

To correct for the error we need to do some data cleanup. For this we will use the sub function sub() in R to replace unwanted symbols with something else. For example, in order to remove the comma in the number “1,234”, we can substitute it with blank. Below is a sequence of commands to help with the cleanup of the data in the Checking column and eventual calculation of the mean.

rr #substitute comma with blank in all of checking
checking= sub(
```

NAs introduced by coercion

rr #Calculate mean of checking with all NAs removed mean(checking,na.rm=TRUE)

[1] 2559.805

##### 2A) Repeat the above commands to calculate the mean of the Savings column instead. Use a different variable naming.

rr Savings = newdata$Savings # command to extract the Savings column from the data file newdata mean(Savings)

argument is not numeric or logical: returning NA
[1] NA

rr #substitute comma with blank in all of Savings
Savings= sub(
```

[1] 2122.146

##### 2B) Calculate now the mean of the Checking column in Excel using the Excel function Average. Compare the two results, from Excel and R and share your observation.

The mean of the checking calculated in Excel is 2122.15, and it is kind of the same number calculated in R. They both were able to find the same average upon correct manipulation of the data.

##### 2C) Based on your observation how did Excel treat the missing values represented by the symbol $-? Are they included in the calculation of the mean or excluded? Explain your answer.

Based on my observation Excel treated the missing values as 0s and excluded them from the calculation which is why the mean calculation for checking in Excel is so much lower than the mean calculation of checking in R.

Task 3: Data Modeling

Here, we will look at Chicago Divvy bike data. The historical data sets with description of fields can be found at:

Chicago Divvy Data: https://www.divvybikes.com/data

###### 3A) Open in RStudio or Excel the file Divvy_Trips_2017_Q4.csv located in the data folder. What is the size of the file (measured in bytes), the number of columns and of rows?. Identify the column field(s) in the data that is/are unique identifier(s) (cannot have duplicate/repeated values)

The file is 81.9 MB (megabites). There are 12 columns and 669,240 rows of data. Trip_id is the only field that is unique to this data set.

Read carefully the file README.txt, located in same data folder, for the description of the data.

###### 3B) Define a relational business logic integrity rule for the column field Trip Duration. ####The trip duration cannot be 0, because if it’s 0, they’re not gonna have any trip. Also, the start and end time must less than 24 hours.

###### 3C) Using https://erdplus.com/#/standalone draw a star like schema using the below three tables. Include an image capture of your schema here.

  • A Fact table for Trips
  • A Dimension table for Stations
  • A Dimension table for Users
LS0tDQp0aXRsZTogIkJTQUQzNDMgRmFsbCAyMDE4IExhYiBXb3Jrc2hlZXQgMDMiDQphdXRob3I6ICJZaSBQYW4iDQpkYXRlOiAiMDktMjYtMjAxOCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50OiBkZWZhdWx0DQpzdWJ0aXRsZTogRGF0YSBQcmVwYXJhdGlvbiAmIEZsb3cgKGJzYWQtbGFiMDMpDQotLS0NCg0KIyMjIEFib3V0DQoNClRoaXMgd29ya3NoZWV0IGluY2x1ZGVzIHRocmVlIG1haW4gdGFza3Mgb24gZGF0YSBvdXRsaWVycywgZGF0YSBwcmVwYXJhdGlvbiwgYW5kIGRhdGEgbW9kZWxpbmcuIFRoZSBsYWIgcmVxdWlyZXMgdGhlIHVzZSBvZiBNaWNyb3NvZnQgRXhjZWwsIFIsIGFuZCBFUkRwbHVzLg0KDQojIyMgU2V0dXANCg0KUmVtZW1iZXIgdG8gYWx3YXlzIHNldCB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5IHRvIHRoZSBzb3VyY2UgZmlsZSBsb2NhdGlvbi4gR28gdG8gJ1Nlc3Npb24nLCBzY3JvbGwgZG93biB0byAnU2V0IFdvcmtpbmcgRGlyZWN0b3J5JywgYW5kIGNsaWNrICdUbyBTb3VyY2UgRmlsZSBMb2NhdGlvbicuIFJlYWQgY2FyZWZ1bGx5IHRoZSBiZWxvdyBhbmQgZm9sbG93IHRoZSBpbnN0cnVjdGlvbnMgdG8gY29tcGxldGUgdGhlIHRhc2tzIGFuZCBhbnN3ZXIgYW55IHF1ZXN0aW9ucy4gIFN1Ym1pdCB5b3VyIHdvcmsgdG8gUlB1YnMgYXMgZGV0YWlsZWQgaW4gcHJldmlvdXMgbm90ZXMuIA0KDQojIyMgTm90ZQ0KDQpGb3IgeW91ciBhc3NpZ25tZW50IHlvdSBtYXkgYmUgdXNpbmcgZGlmZmVyZW50IGRhdGEgc2V0cyB0aGFuIHdoYXQgaXMgaW5jbHVkZWQgaGVyZS4gQWx3YXlzIHJlYWQgY2FyZWZ1bGx5IHRoZSBpbnN0cnVjdGlvbnMgb24gU2FrYWkuICBGb3IgY2xhcml0eSwgdGFza3MvcXVlc3Rpb25zIHRvIGJlIGNvbXBsZXRlZC9hbnN3ZXJlZCBhcmUgaGlnaGxpZ2h0ZWQgaW4gcmVkIGNvbG9yICh2aXNpYmxlIGluIHByZXZpZXcpIGFuZCBudW1iZXJlZCBhY2NvcmRpbmcgdG8gdGhlaXIgcGFydGljdWxhciBwbGFjZW1lbnQgaW4gdGhlIHRhc2sgc2VjdGlvbi4gIFF1aXRlIG9mdGVuIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHlvdXIgb3duIGNvZGUgY2h1bmsuDQoNCkV4ZWN1dGUgYWxsIGNvZGUgY2h1bmtzLCBwcmV2aWV3LCBwdWJsaXNoLCBhbmQgc3VibWl0IGxpbmsgb24gU2FrYWkuDQoNCi0tLS0tLS0tLS0tLS0tDQoNCiMjIyBUYXNrIDE6IERhdGEgT3V0bGllcnMNCg0KRmlyc3QsIHdlIG11c3QgY2FsY3VsYXRlIHRoZSBtZWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIG1heGltdW0sIGFuZCBtaW5pbXVtIGZvciB0aGUgQWdlIGNvbHVtbiB1c2luZyBSLg0KDQpJbiBSLCB3ZSBtdXN0IHJlYWQgaW4gdGhlIGZpbGUgYWdhaW4sIGV4dHJhY3QgdGhlIGNvbHVtbiBhbmQgZmluZCB0aGUgdmFsdWVzIHRoYXQgYXJlIGFza2VkIGZvci4NCg0KYGBge3J9DQojUmVhZCBGaWxlDQpteWRhdGEgPSByZWFkLmNzdihmaWxlPSJkYXRhL2NyZWRpdHJpc2suY3N2IikgDQoNCiNOYW1lIHRoZSBleHRyYWN0ZWQgdmFyaWFibGUNCmFnZSA9IG15ZGF0YSRBZ2UgDQoNCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDFBKSBGaWxsIGluIHRoZSBjb2RlIGNodW5rIGJlbG93IHRvIGNhbGN1bGF0ZSBhbmQgZGlzcGxheSBlYWNoIHJlc3VsdC4gIFJlZmVyIHRvIHByZXZpb3VzIHdvcmtzaGVldHMgYW5kIG9uLWxpbmUgaGVscCBmb3Igc29tZSBjb21tYW5kcy4NCjwvc3Bhbj4NCg0KYGBge3J9DQojQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIGFnZSBiZWxvdy4gDQptZWFuKGFnZSkNCg0KI0NhbGN1bGF0ZSB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGFnZSBiZWxvdy4gDQpzZChhZ2UpDQoNCiNDYWxjdWxhdGUgdGhlIG1heGltYSBvZiBhZ2UgYmVsb3cuIExvb2sgaW4gSGVscCB0byBmaW5kIHRoZSByaWdodCBjb21tYW5kIGZvciBtYXhpbWENCm1heChhZ2UpDQoNCiNDYWxjdWxhdGUgdGhlIG1pbmltYSBvZiBhZ2UgYmVsb3cuIExvb2sgaW4gSGVscCB0byBmaW5kIHRoZSByaWdodCBjb21tYW5kIGZvciBtaW5pbWENCm1pbihhZ2UpDQpgYGANCg0KTmV4dCwgd2Ugd2lsbCB1c2UgdGhlIGZvcm11bGEgZnJvbSBjbGFzcyB0byBkZXRlY3QgYW55IG91dGxpZXJzLiBBbiBvdXRsaWVyIGlzIGEgdmFsdWUgdGhhdCAibGllcyBvdXRzaWRlIiBtb3N0IG9mIHRoZSBvdGhlciB2YWx1ZXMgaW4gYSBzZXQgb2YgZGF0YS4gQSBjb21tb24gd2F5IHRvIGVzdGltYXRlIHRoZSB1cHBlciBhbmQgbG93ZXIgbGltaXRzIGlzIHRvIHRha2UgdGhlIGBgYG1lYW4gKCsgb3IgLSkgMyAqIHN0YW5kYXJkIGRldmlhdGlvbmBgYC4gIA0KDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMgMUIpIFdyaXRlIGFuZCBleGVjdXRlIHRoZSBjb2RlIGNodW5rIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGFib3ZlIGZvcm11bGEgdG8gY2FsY3VsYXRlIHRoZSB1cHBlciBhbmQgbG93ZXIgbGltaXRzIGZvciBhZ2UuIERpc3BsYXkgeW91ciByZXN1bHRzLiBCYXNlZCBvbiB0aGUgbGltaXRzIGRvIHlvdSB0aGluayB0aGVyZSBhcmUgb3V0bGllcnM/IEV4cGxhaW4geW91ciBhbnN3ZXIuDQo8L3NwYW4+DQpgYGB7cn0NClVMPW1lYW4oYWdlKSArIDMgKiBzZChhZ2UpDQpVTA0KYGBgDQpgYGB7cn0NCkxMPW1lYW4oYWdlKSAtIDMgKiBzZChhZ2UpDQpMTA0KYGBgDQojIyMjIEFjY29yZGluZyB0byB0aGUgYW5zd2VyIG9mIDFCIGFuZCAxQSwgaXQgc3RhdGVzIHRoYXQgdGhlcmUgYXJlIG91dGxpZXJzLiBTaW5jZSB0aGUgbWluaW11bSAxOCBpcyBsYXJnZXIgdGhhbiBsb3dlciBsaW1pdCAxLjI2MjI2OSwgdGhhdCBtZWFucyBtaW5pbXVtIDE4IGlzIGluIHRoZSBib3VuZGFyaWVzLiBIb3dldmVyLCB0aGUgbWF4aW11bSA3MyAgaXMgYmlnZ2VyIHRoYW4gdXBwZXIgbGltaXQgaXMgNjcuNTMzMDIsIHRoYXQgc2F5cyA3MyBpcyBub3Qgd2l0aGluIHRoZSBib3VuZGFyaWVzLCBhbmQgdGhlIG91dGxpbmVycyBleGlzdC4NCg0KQW5vdGhlciBzaW1pbGFyIG1ldGhvZCB0byBmaW5kIHRoZSB1cHBlciBhbmQgbG93ZXIgdGhyZXNob2xkcywgZGlzY3Vzc2VkIGluIG1hbnkgaW50cm9kdWN0b3J5IHN0YXRpc3RpY3MgY291cnNlcywgaW52b2x2ZXMgZmluZGluZyB0aGUgaW50ZXJxdWFydGlsZSByYW5nZS4gRm9sbG93IGFsb25nIGJlbG93IHRvIHNlZSBob3cgd2UgZmlyc3QgY2FsY3VsYXRlIHRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlLi4gDQoNCmBgYHtyfSANCnF1YW50aWxlKGFnZSkgDQpsb3dlcnEgPSBxdWFudGlsZShhZ2UpWzJdDQp1cHBlcnEgPSBxdWFudGlsZShhZ2UpWzRdDQppcXIgPSB1cHBlcnEgLSBsb3dlcnENCmBgYA0KDQpOZXh0IHdlIGNhbGN1bGF0ZSB0aGUgbGltaXRpbmcgdGhyZXNob2xkcy4gQSB0aHJlc2hvbGQgaGVyZSBpcyB0aGUgYm91bmRhcnkgdGhhdCBkZXRlcm1pbmVzIGlmIGEgdmFsdWUgaXMgYW4gb3V0bGllci4gSWYgdGhlIHZhbHVlIGZhbGxzIGFib3ZlIHRoZSB1cHBlciB0aHJlc2hvbGQgb3IgYmVsb3cgdGhlIGxvd2VyIHRocmVzaG9sZCwgaXQgaXMgYW4gb3V0bGllci4gDQoNClRvIGNhbGN1bGF0ZSB0aGUgdXBwZXIgdGhyZXNob2xkOg0KYGBge3J9IA0KdXBwZXJ0aHJlc2hvbGQgPSAoaXFyICogMS41KSArIHVwcGVycSANCnVwcGVydGhyZXNob2xkDQpgYGANCg0KQmVsb3cgaXMgdGhlIGxvd2VyIHRocmVzaG9sZDoNCmBgYHtyfQ0KbG93ZXJ0aHJlc2hvbGQgPSBsb3dlcnEgLSAoaXFyICogMS41KQ0KbG93ZXJ0aHJlc2hvbGQNCmBgYA0KDQpBIGdvb2Qgd2F5IHRvIHVuZGVydHNhbmQgdGhlIGFib3ZlIGNhbGN1bGF0aW9ucyBpcyB0byB2aXN1YWxpemUgdGhlIHJlc3VsdHMgdXNpbmcgYSBib3ggYW5kIHdoaXNrZXIgcGxvdC4gVGhlIHRvcCBhbmQgbG93ZXIgZW5kcyBvZiB0aGUgYm94IGNvcnJlc3BvbmQgdG8gdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFydGlsZXMuIFRoZSBtZWRpYW4gaXMgbWFya2VkIGJ5IGEgYm9sZGVkIGxpbmUuIFRoZSB3aGlza2VycyBhcmUgdGhlIGxpbmVzIGNvbm5lY3RpbmcgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFydGlsZXMgdG8gdXBwZXIgYW5kIGxvd2VyIHRocmVzaG9sZHMuIEFueSBwb2ludHMgYmV5b25kIHRoZSB0aHJlc2hvbGRzIGlzIGEgcG90ZW50aWFsIG91dGxpZXIuDQoNCmBgYHtyfSANCmJveHBsb3QoYWdlKSANCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDFDKSBGcm9tIHRoZSBib3ggcGxvdCByZXByZXNlbnRhdGlvbiBhcmUgdGhlcmUgYW55IG91dGxpZXJzPyBIb3cgbWFueSBjYW4geW91IGNvdW50PyBIb3cgZG9lcyB5b3VyIGFuc3dlciByZWNvbmNpbGUgd2l0aCB0aGUgcmVzdWx0IGZyb20gVGFzayAxQj8NCjwvc3Bhbj4NCiMjIyMgRnJvbSB0aGUgYm94IHBsb3QgYWJvdmUsIHRoZXJlIHNlZW0gdG8gYmUgZml2ZSBvdXRsaWVycyBvbiB0aGUgdXBwZXIgZW5kIG9mIHRoaXMgZGF0YSBhbmQgbm8gb3V0bGllcnMgb24gdGhlIGxvd2VyIGVuZC4gVGhpcyBvYnNlcnZhdGlvbiBjb25maXJtcyB0aGUgc3RhdGVtZW50IG1hZGUgaW4gdGhlIHRhc2sgMUIuIA0KLS0tLS0tLS0tLS0tLS0tDQoNCiMjIyBUYXNrIDI6IERhdGEgUHJlcGFyYXRpb24NCg0KTmV4dCwgd2Ugd2lsbCByZWFkIHRoZSBmaWxlIGBjcmVkaXRyaXNrb3JnLmNzdmAgaW50byBSIGFzIHByb3ZpZGVkIGluIGl0cyBvcmlnaW5hbCBmb3JtLiBVbmxpa2UgdGhlIGNsZWFuZWQgZmlsZSBgY3JlZGl0cmlzay5jc3ZgLCB0aGUgb3JpZ2luYWwgZGF0YXNldCB3aWxsIHJlcXVpcmUgc29tZSBkYXRhIHByZXBhcmF0aW9uLiAgDQoNCmBgYHtyfQ0KbmV3ZGF0YSA9IHJlYWQuY3N2KGZpbGU9ImRhdGEvY3JlZGl0cmlza29yZy5jc3YiKQ0KaGVhZChuZXdkYXRhKQ0KYGBgDQoNCldlIG9ic2VydmUgYSBuZXcgbGluZSBpcyBpbnNlcnRlZCB3aXRoIHRoZSBoZWFkZXIgbGFiZWxzIGBYLCBYLjEsIC4uLmAgYW5kIHRoYXQgdGhlIHRydWUgY29sdW1uIGhlYWRlcnMgYXJlIHNoaWZ0ZWQgZG93bi4gIFRoaXMgaXMgYmVjYXVzZSBvZiB0aGUgZW1wdHkgbGluZSBpbiB0aGUgb3JpZ2luYWwgZGF0YXNldC4gVG8gYWNjb3VudCBmb3IgdGhpcyBkZXRhaWwgd2UgbXVzdCBza2lwIG9uZSBsaW5lIHdoZW4gcmVhZGluZyB0aGUgZmlsZS4NCg0KYGBge3J9IA0KbmV3ZGF0YSA9IHJlYWQuY3N2KGZpbGU9ImRhdGEvY3JlZGl0cmlza29yZy5jc3YiLHNraXA9MSkgDQpoZWFkKG5ld2RhdGEpDQpgYGANCg0KTmV4dCB3ZSB3YW50IHRvIGV4dHJhY3QgdGhlIENoZWNraW5nIGNvbHVtbiBhbmQgdGhlbiBmaW5kIHRoZSBhdmVyYWdlIG9mIGNoZWNraW5nLCBzbWlsYXIgdG8gd2hhdCB3ZSBkaWQgaW4gdGhlIHByZXZpb3VzIGxhYi4gIFdoZW4gd2UgdHJ5IHRvIGV4ZWN1dGUgdGhlIGNvZGUgY2h1bmsgYmVsb3cgbm90aWNlIHRoYXQgd2UgZ2V0IGFuIGVycm9yLg0KDQpgYGB7cn0gDQpjaGVja2luZyA9IG5ld2RhdGEkQ2hlY2tpbmcgIyBjb21tYW5kIHRvIGV4dHJhY3QgdGhlIENoZWNraW5nIGNvbHVtbiBmcm9tIHRoZSBkYXRhIGZpbGUgbmV3ZGF0YQ0KbWVhbihjaGVja2luZykNCmBgYA0KDQpUbyByZXNvbHZlIHRoZSBlcnJvciwgd2UgbXVzdCB1bmRlcnN0YW5kIGZpcnN0IHdoZXJlIGl0J3Mgc291cmNlLiBUaGVyZSBhcmUgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGNzdiBmaWxlIHJlcHJlc2VudGVkIGJ5IHRoZSBzeW1ib2wgYCQtYC4gTWlzc2luZyBkYXRhIGlzIHF1aXRlIGNvbW1vbiBhcyBtb3N0IGRhdGFzZXRzIGFyZSBub3QgcGVyZmVjdC4gQWRkaXRpb25hbGx5LCB0aGVyZSBhcmUgY29tbWFzIHdpdGhpbiB0aGUgZXhjZWwgc3ByZWFkc2hlZXQsIGFuZCBSIGRvZXMgbm90IHJlY29nbml6ZSB0aGF0ICcxLDIzNCcgaXMgZXF1aXZhbGVudCB0byAnMTIzNCcuIExhc3RseSwgdGhlcmUgYXJlICckJyBzeW1ib2xzIHRocm91Z2hvdXQgdGhlIGZpbGUgd2hpY2ggaXMgbm90IGEgbnVtZXJpY2FsIHN5bWJvbCBlaXRoZXIuDQoNClRvIGNvcnJlY3QgZm9yIHRoZSBlcnJvciB3ZSBuZWVkIHRvIGRvIHNvbWUgZGF0YSBjbGVhbnVwLiBGb3IgdGhpcyB3ZSB3aWxsIHVzZSB0aGUgc3ViIGZ1bmN0aW9uIGBzdWIoKWAgaW4gUiB0byByZXBsYWNlIHVud2FudGVkIHN5bWJvbHMgd2l0aCBzb21ldGhpbmcgZWxzZS4gRm9yIGV4YW1wbGUsIGluIG9yZGVyIHRvIHJlbW92ZSB0aGUgY29tbWEgaW4gdGhlIG51bWJlciAiMSwyMzQiLCB3ZSBjYW4gc3Vic3RpdHV0ZSBpdCB3aXRoIGJsYW5rLiBCZWxvdyBpcyBhIHNlcXVlbmNlIG9mIGNvbW1hbmRzIHRvIGhlbHAgd2l0aCB0aGUgY2xlYW51cCBvZiB0aGUgZGF0YSBpbiB0aGUgQ2hlY2tpbmcgY29sdW1uIGFuZCBldmVudHVhbCBjYWxjdWxhdGlvbiBvZiB0aGUgbWVhbi4NCg0KYGBge3J9IA0KI3N1YnN0aXR1dGUgY29tbWEgd2l0aCBibGFuayBpbiBhbGwgb2YgY2hlY2tpbmcgIA0KY2hlY2tpbmc9IHN1YigiLCIsIiIsY2hlY2tpbmcpDQoNCiNzdWJzdGl0dXRlIGRvbGxhciBzaWduIHdpdGggYmxhbmsgaW4gYWxsIG9mIGNoZWNraW5nIA0KIyBFeGFtcGxlIG5ldyA9IHN1YigiXFwkIiwiIixuZXcpDQpjaGVja2luZyA9IHN1YigiXFwkIiwiIixjaGVja2luZykNCg0KI0NvbnZlcnQgdmFsdWVzIHRvIG51bWVyaWMuIEFueSB2YWx1ZSB0aGF0IGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gbnVtZXJpYyB3aWxsIGJlIGRlc2lnbmF0ZWQgYXMgTkEgKE5vdCBBcHBsaWNhYmxlKQ0KY2hlY2tpbmcgPSBhcy5udW1lcmljKGNoZWNraW5nKQ0KDQojQ2FsY3VsYXRlIG1lYW4gb2YgY2hlY2tpbmcgd2l0aCBhbGwgTkFzIHJlbW92ZWQgDQptZWFuKGNoZWNraW5nLG5hLnJtPVRSVUUpDQpgYGANCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyAyQSkgUmVwZWF0IHRoZSBhYm92ZSBjb21tYW5kcyB0byBjYWxjdWxhdGUgdGhlIG1lYW4gb2YgdGhlIFNhdmluZ3MgY29sdW1uIGluc3RlYWQuIFVzZSBhIGRpZmZlcmVudCB2YXJpYWJsZSBuYW1pbmcuDQpgYGB7cn0gDQpTYXZpbmdzID0gbmV3ZGF0YSRTYXZpbmdzICMgY29tbWFuZCB0byBleHRyYWN0IHRoZSBTYXZpbmdzIGNvbHVtbiBmcm9tIHRoZSBkYXRhIGZpbGUgbmV3ZGF0YQ0KbWVhbihTYXZpbmdzKQ0KYGBgDQpgYGB7cn0NCiNzdWJzdGl0dXRlIGNvbW1hIHdpdGggYmxhbmsgaW4gYWxsIG9mIFNhdmluZ3MgIA0KU2F2aW5ncz0gc3ViKCIsIiwiIixTYXZpbmdzKQ0KDQojc3Vic3RpdHV0ZSBkb2xsYXIgc2lnbiB3aXRoIGJsYW5rIGluIGFsbCBvZiBTYXZpbmdzIA0KIyBFeGFtcGxlIG5ldyA9IHN1YigiXFwkIiwiIixuZXcpDQpTYXZpbmdzID0gc3ViKCJcXCQiLCIiLFNhdmluZ3MpDQoNCiNDb252ZXJ0IHZhbHVlcyB0byBudW1lcmljLiBBbnkgdmFsdWUgdGhhdCBjYW5ub3QgYmUgY29udmVydGVkIHRvIG51bWVyaWMgd2lsbCBiZSBkZXNpZ25hdGVkIGFzIE5BIChOb3QgQXBwbGljYWJsZSkNClNhdmluZ3MgPSBhcy5udW1lcmljKFNhdmluZ3MpDQoNCiNDYWxjdWxhdGUgbWVhbiBvZiBTYXZpbmdzIHdpdGggYWxsIE5BcyByZW1vdmVkIA0KbWVhbihTYXZpbmdzLG5hLnJtPVRSVUUpDQpgYGANCg0KDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMgMkIpIENhbGN1bGF0ZSBub3cgdGhlIG1lYW4gb2YgdGhlIENoZWNraW5nIGNvbHVtbiBpbiBFeGNlbCB1c2luZyB0aGUgRXhjZWwgZnVuY3Rpb24gYEF2ZXJhZ2VgLiBDb21wYXJlIHRoZSB0d28gcmVzdWx0cywgZnJvbSBFeGNlbCBhbmQgUiBhbmQgc2hhcmUgeW91ciBvYnNlcnZhdGlvbi4NCjwvc3Bhbj4NCg0KIyMjIyBUaGUgbWVhbiBvZiB0aGUgY2hlY2tpbmcgY2FsY3VsYXRlZCBpbiBFeGNlbCBpcyAyMTIyLjE1LCBhbmQgaXQgaXMga2luZCBvZiB0aGUgc2FtZSBudW1iZXIgY2FsY3VsYXRlZCBpbiBSLiBUaGV5IGJvdGggd2VyZSBhYmxlIHRvIGZpbmQgdGhlIHNhbWUgYXZlcmFnZSB1cG9uIGNvcnJlY3QgbWFuaXB1bGF0aW9uIG9mIHRoZSBkYXRhLg0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDJDKSBCYXNlZCBvbiB5b3VyIG9ic2VydmF0aW9uIGhvdyBkaWQgRXhjZWwgdHJlYXQgdGhlIG1pc3NpbmcgdmFsdWVzIHJlcHJlc2VudGVkIGJ5IHRoZSBzeW1ib2wgYCQtYD8gQXJlIHRoZXkgaW5jbHVkZWQgaW4gdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBtZWFuIG9yIGV4Y2x1ZGVkPyAgRXhwbGFpbiB5b3VyIGFuc3dlci4NCg0KQmFzZWQgb24gbXkgb2JzZXJ2YXRpb24gRXhjZWwgdHJlYXRlZCB0aGUgbWlzc2luZyB2YWx1ZXMgYXMgMHMgYW5kIGV4Y2x1ZGVkIHRoZW0gZnJvbSB0aGUgY2FsY3VsYXRpb24gd2hpY2ggaXMgd2h5IHRoZSBtZWFuIGNhbGN1bGF0aW9uIGZvciBjaGVja2luZyBpbiBFeGNlbCBpcyBzbyBtdWNoIGxvd2VyIHRoYW4gdGhlIG1lYW4gY2FsY3VsYXRpb24gb2YgY2hlY2tpbmcgaW4gUi4NCi0tLS0tLS0tLS0tLS0NCg0KIyMjIFRhc2sgMzogRGF0YSBNb2RlbGluZw0KDQpIZXJlLCB3ZSB3aWxsIGxvb2sgYXQgQ2hpY2FnbyBEaXZ2eSBiaWtlIGRhdGEuIFRoZSBoaXN0b3JpY2FsIGRhdGEgc2V0cyB3aXRoIGRlc2NyaXB0aW9uIG9mIGZpZWxkcyBjYW4gYmUgZm91bmQgYXQ6ICANCg0KQ2hpY2FnbyBEaXZ2eSBEYXRhOiBbaHR0cHM6Ly93d3cuZGl2dnliaWtlcy5jb20vZGF0YV0oaHR0cHM6Ly93d3cuZGl2dnliaWtlcy5jb20vc3lzdGVtLWRhdGEpDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMjIDNBKSBPcGVuIGluIFJTdHVkaW8gb3IgRXhjZWwgdGhlIGZpbGUgYERpdnZ5X1RyaXBzXzIwMTdfUTQuY3N2YCAgbG9jYXRlZCBpbiB0aGUgZGF0YSBmb2xkZXIuIFdoYXQgaXMgdGhlIHNpemUgb2YgdGhlIGZpbGUgKG1lYXN1cmVkIGluIGJ5dGVzKSwgdGhlIG51bWJlciBvZiBjb2x1bW5zIGFuZCBvZiByb3dzPy4gSWRlbnRpZnkgdGhlIGNvbHVtbiBmaWVsZChzKSBpbiB0aGUgZGF0YSB0aGF0IGlzL2FyZSB1bmlxdWUgaWRlbnRpZmllcihzKSAoY2Fubm90IGhhdmUgZHVwbGljYXRlL3JlcGVhdGVkIHZhbHVlcykNCjwvc3Bhbj4NCg0KIyMjI1RoZSBmaWxlIGlzIDgxLjkgTUIgKG1lZ2FiaXRlcykuIFRoZXJlIGFyZSAxMiBjb2x1bW5zIGFuZCA2NjksMjQwIHJvd3Mgb2YgZGF0YS4gVHJpcF9pZCBpcyB0aGUgb25seSBmaWVsZCB0aGF0IGlzIHVuaXF1ZSB0byB0aGlzIGRhdGEgc2V0Lg0KDQpSZWFkIGNhcmVmdWxseSB0aGUgZmlsZSBgUkVBRE1FLnR4dGAsIGxvY2F0ZWQgaW4gc2FtZSBkYXRhIGZvbGRlciwgZm9yIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgZGF0YS4NCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyMgM0IpIERlZmluZSBhIHJlbGF0aW9uYWwgYnVzaW5lc3MgbG9naWMgaW50ZWdyaXR5IHJ1bGUgZm9yIHRoZSBjb2x1bW4gZmllbGQgYFRyaXAgRHVyYXRpb25gLg0KPC9zcGFuPg0KIyMjI1RoZSB0cmlwIGR1cmF0aW9uIGNhbm5vdCBiZSAwLCBiZWNhdXNlIGlmIGl0J3MgMCwgdGhleSdyZSBub3QgZ29ubmEgaGF2ZSBhbnkgdHJpcC4gQWxzbywgdGhlIHN0YXJ0IGFuZCBlbmQgdGltZSBtdXN0IGxlc3MgdGhhbiAyNCBob3Vycy4gDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMjIDNDKSBVc2luZyBbaHR0cHM6Ly9lcmRwbHVzLmNvbS8jL3N0YW5kYWxvbmVdKGh0dHBzOi8vZXJkcGx1cy5jb20vIy9zdGFuZGFsb25lKSBkcmF3IGEgc3RhciBsaWtlIHNjaGVtYSB1c2luZyB0aGUgYmVsb3cgdGhyZWUgdGFibGVzLiBJbmNsdWRlIGFuIGltYWdlIGNhcHR1cmUgb2YgeW91ciBzY2hlbWEgaGVyZS4NCjwvc3Bhbj4gDQoNCi0gQSBGYWN0IHRhYmxlIGZvciBUcmlwcw0KLSBBIERpbWVuc2lvbiB0YWJsZSBmb3IgU3RhdGlvbnMNCi0gQSBEaW1lbnNpb24gdGFibGUgZm9yIFVzZXJzDQoNCiFbXShpbWdzL2ltZzAxLnBuZykNCg0KDQo=