The dataset contains date, stock open/close prices, stock price daily high/low and volume of shares traded over the past 5 years as of October 15th, 2021.
Data Cleaning and Preparation
In this stage the data is checked for accuracy and completeness prior to beginning the analysis. Some of the issues addressed are as follows:
- Remove extraneous data
- Check for in missing values
- Replace missing values
- Delete data that cannot be corrected/replaced
- Correct any data formatting issues
- Creating new features
- Identify errors revealed when new variables are created
Missing Values
#Identifying total number of missing values
sum(is.na(tesla))
[1] 0
There are no missing values.
Creating New Features
Moving Average
We will create a new column to track the moving average of the daily Closing Stock Price over a set period. The moving average smooths out the stock price price data by creating a constantly updated average stock price. We will track the moving average across two periods:
- 7 Day Period
- 30 Day Period
#Calculating a moving average for stock price over the last 7 days
tesla$Moving_Average_7_Day <- round(ma(tesla$Close.Last, 7),2)
tesla$Moving_Average_30_Day <- round(ma(tesla$Close.Last, 30),2)
Identify Issues Revealed due to New Features
The Moving averages calculate an average based on previous data over the set period. However, for cases where there is not enough previous data, the moving average cannot calculate a value and leaves a missing value. To rectify these missing values we will have to remove the associated rows.
#Removing rows with missing data
tesla <- na.omit(tesla)
Exploratory Data Analysis
In this stage, we will examine the data to identify any patterns, trends and relationships between the variables. It will help us analyze the data and extract insights that can be used to make decisions.
Data Visualization will give us a clear idea of what the data means by giving it visual context.
Statistics
Lets take a look at the data as a whole to understand how the Tesla Stock Price has varied over the last 5 years.
summary(tesla)
Date Close.Last Volume Open High Low Moving_Average_7_Day
Min. :2016-11-07 Min. : 35.79 Min. : 9800558 Min. : 36.22 Min. : 36.95 Min. : 35.40 Min. : 37.02
1st Qu.:2018-01-28 1st Qu.: 57.88 1st Qu.: 25252174 1st Qu.: 57.53 1st Qu.: 58.98 1st Qu.: 56.53 1st Qu.: 57.73
Median :2019-04-17 Median : 68.04 Median : 35270215 Median : 68.06 Median : 69.22 Median : 66.92 Median : 68.02
Mean :2019-04-17 Mean :202.45 Mean : 44992494 Mean :202.33 Mean :206.90 Mean :197.71 Mean :202.47
3rd Qu.:2020-07-07 3rd Qu.:274.46 3rd Qu.: 53038012 3rd Qu.:279.20 3rd Qu.:282.14 3rd Qu.:263.54 3rd Qu.:271.12
Max. :2021-09-23 Max. :883.09 Max. :304693800 Max. :891.38 Max. :900.40 Max. :871.60 Max. :859.24
Moving_Average_30_Day
Min. : 37.84
1st Qu.: 58.33
Median : 67.24
Mean :202.56
3rd Qu.:257.06
Max. :836.38
As seen in the summary above:
- Oldest data point is from 2016-11-07 and the most recent data point is from 2021-09-23.
- Highest Closing Stock Price was $883.09, while the lowest Closing Stock Price $35.79.
- Highest Opening Stock Price was $891.38, while the lowest Opening Stock Price $36.22.
- The Highest Stock Price over the past 5 years was $900.40.
- The Lowest Stock Price over the past 5 years was $35.40.
- The Volume of Stocks traded averaged around 45 million with a maximum of around 304 million.
Closing Stock Price
#Plotting the Closing Stock Price over the last 5 years
ggplot(tesla, aes(x=Date, y=Close.Last )) +
geom_line() +
labs(title="Tesla Closing Stock Price Over the Last 5 Years", x="Year", y="Tesla Closing Stock Price ($)") +
scale_x_date(date_minor_breaks = "1 month") +
theme_bw() +
theme(axis.text.x = element_text(size = 10), axis.title.x = element_text(size = 12),
axis.text.y = element_text(size = 10), axis.title.y = element_text(size = 12),
plot.title = element_text(size = 15))
As seen previously above there is a steep rise in the Tesla Stock Price since early 2020. Lets take a closer look at the stock price during this time.
Closing Stock Price since Jan 2020
#Plotting the Stock Price since beginning of Jan 2020 onwards
ggplot(tesla, aes(x=Date, y=Close.Last )) +
geom_line() +
labs(title="Tesla Closing Stock Price in 2020", x="Month", y="Tesla Closing Stock Price ($)") +
scale_x_date(date_breaks = "1 month", date_labels = "%b", limit=c(as.Date("2020-01-01"),as.Date("2021-09-23"))) +
ylim(0,900) +
theme_bw() +
theme(axis.text.x = element_text(size = 10), axis.title.x = element_text(size = 12),
axis.text.y = element_text(size = 10), axis.title.y = element_text(size = 12),
plot.title = element_text(size = 15))
Warning: Removed 792 row(s) containing missing values (geom_path).
The stock price has continued to increase significantly since Jan 2020, reaching a peak around Feb 2021.
#The most recent stock price
recent_stock <- tesla %>% filter(Date == max(tesla$Date))
#Stock price at the beginning of 2020
#Note: No data for date 2020-01-01
stock_start_2020 <- tesla %>% filter(Date == as.Date("2020-01-02"))
#Stock price at the end of 2020
stock_end_2020 <- tesla %>% filter(Date == as.Date("2020-12-31"))
#Calculating the percentage increase since the start of 2020 and the most recent date
pct_recent = round((((recent_stock$Close.Last-stock_start_2020$Close.Last)/stock_start_2020$Close.Last)*100),0)
#Calculating the percentage increase between the start and end of 2020
pct_2020 = round((((stock_end_2020$Close.Last-stock_start_2020$Close.Last)/stock_start_2020$Close.Last)*100),0)
cat("The stock price increase: \n Jan 2020-Present",pct_recent,"% \n Jan 2020 - Dec 2020 End:",pct_2020,"%")
The stock price increase:
Jan 2020-Present 776 %
Jan 2020 - Dec 2020 End: 720 %
The stock price has increased 776% between the beginning of 2020 and the present. In fact, it increased by 720% just in 2020 alone.
Moving Average
#Plotting the Closing Stock price vs the 7 Day Moving Average
ggplot(tesla, aes(x=Date)) +
geom_line(aes(y = Close.Last, colour="Close Price")) +
geom_line(aes(y = Moving_Average_7_Day, colour="7 Day")) +
labs(title="Tesla Stock Price vs. 7 Day Moving Average", x="Year", y="Tesla Stock Price ($)", colour = "Price & Moving Average") +
scale_color_manual(values = c("black","tan3")) +
scale_x_date(date_minor_breaks = "1 month") +
theme_bw() +
theme(axis.text.x = element_text(size = 10), axis.title.x = element_text(size = 12),
axis.text.y = element_text(size = 10), axis.title.y = element_text(size = 12),
plot.title = element_text(size = 15))
#Plotting the Closing Stock price vs the 30 Day Moving Average
ggplot(tesla, aes(x=Date)) +
geom_line(aes(y = Close.Last, colour="Close Price")) +
geom_line(aes(y = Moving_Average_30_Day, colour="30 Day")) +
labs(title="Tesla Stock Price vs. 30 Day Moving Average", x="Year", y="Tesla Stock Price ($)", colour = "Price & Moving Average") +
scale_color_manual(values = c("black","orange")) +
scale_x_date(date_minor_breaks = "1 month") +
theme_bw() +
theme(axis.text.x = element_text(size = 10), axis.title.x = element_text(size = 12),
axis.text.y = element_text(size = 10), axis.title.y = element_text(size = 12),
plot.title = element_text(size = 15))
The 30 Day Moving Average gives us a much smoother curve than the 7 Day Moving Average. Therefore, using the 30 Day Moving Average we can clearly see the points where the stock price deviated noticeably from the predicted price. The stock price fluctuations seem to be most significant in the period after early 2020, which correlates with our earlier observation.
Stock Trading Volume
#Plotting the Closing Stock Price over the last 5 years
ggplot(tesla, aes(x=Date, y=Volume, color ="orange")) +
geom_point() +
geom_line(aes(y = 45000000, color="red")) +
labs(title="Tesla Stock Trading Volume Over the Last 5 Years", x="Year", y="Number of Stocks Traded") +
scale_x_date(date_minor_breaks = "1 month") +
theme_bw() +
theme(axis.text.x = element_text(size = 10), axis.title.x = element_text(size = 12),
axis.text.y = element_text(size = 10), axis.title.y = element_text(size = 12),
plot.title = element_text(size = 15)) +
theme(legend.position = "none")
The volume of stocks traded has generally remained around or been under the average of 45 million (indicated by the line), however there is an increase in volume during the year 2020, though the it does seem to be getting back to normal since the beginning of 2021.
Summary of Data Analysis
- Oldest data point is from 2016-11-07 and the most recent data point is from 2021-09-23.
- Highest Closing Stock Price was $883.09, while the lowest Closing Stock Price $35.79.
- Highest Opening Stock Price was $891.38, while the lowest Opening Stock Price $36.22.
- The Highest Stock Price over the past 5 years was $900.40.
- The Lowest Stock Price over the past 5 years was $35.40.
- The Volume of Stocks traded averaged around 45 million with a maximum of around 304 million.
The Tesla Stock Price has increase significantly since 2016. The stock price remained relatively steady until early 2020 when it began to rise drastically. The stock price has increased 776% between the beginning of 2020 and the present. In fact, it increased by 720% just in 2020 alone. While the stock price reaches its peak around Feb 2021, it has continued its general upward trend. However, during the period of price increase the Daily stock price would fluctuate significantly compared to its relatively stable price prior to 2020.
The volume of stocks traded during the last 5 years has generally remained around or been under the average of 45 million, however there is an increase in volume during the year 2020, which corresponds to the steep increase in stock price. We would typically expect an increase in trading activity like this during a period when the company’s stocks are rapidly rising.
LS0tCnRpdGxlOiAiVGVzbGEgU3RvY2sgRGF0YSBBbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpBbmFseXNpcyBvZiBhIFRlc2xhIEluYy4gKFRTTEEpIGhpc3RvcmljYWwgc3RvY2sgcHJpY2UgZGF0YXNldCBmcm9tIE5BU0RBUSBIaXN0b3JpY2FsIERhdGE6IGh0dHBzOi8vd3d3Lm5hc2RhcS5jb20vbWFya2V0LWFjdGl2aXR5L3N0b2Nrcy90c2xhL2hpc3RvcmljYWwKClRoZSBkYXRhc2V0IGNvbnRhaW5zIGRhdGUsIHN0b2NrIG9wZW4vY2xvc2UgcHJpY2VzLCBzdG9jayBwcmljZSBkYWlseSBoaWdoL2xvdyBhbmQgdm9sdW1lIG9mIHNoYXJlcyB0cmFkZWQgb3ZlciB0aGUgcGFzdCA1IHllYXJzIGFzIG9mIE9jdG9iZXIgMTV0aCwgMjAyMS4gCgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2doaWdobGlnaHQpCmxpYnJhcnkoZm9yZWNhc3QpCgojSW1wb3J0aW5nIHRoZSBjc3YgZmlsZSB0byBhIERhdGEgRnJhbWUKdGVzbGEgPC0gcmVhZC5jc3YoInRlc2xhX3N0b2NrLmNzdiIpCgojVmlld2luZyB0aGUgRGF0YSBGcmFtZQpoZWFkKHRlc2xhKQpgYGAKCiMgRGF0YSBDbGVhbmluZyBhbmQgUHJlcGFyYXRpb24KSW4gdGhpcyBzdGFnZSB0aGUgZGF0YSBpcyBjaGVja2VkIGZvciBhY2N1cmFjeSBhbmQgY29tcGxldGVuZXNzIHByaW9yIHRvIGJlZ2lubmluZyB0aGUgYW5hbHlzaXMuIFNvbWUgb2YgdGhlIGlzc3VlcyBhZGRyZXNzZWQgYXJlIGFzIGZvbGxvd3M6CgotIFJlbW92ZSBleHRyYW5lb3VzIGRhdGEKLSBDaGVjayBmb3IgaW4gbWlzc2luZyB2YWx1ZXMKLSBSZXBsYWNlIG1pc3NpbmcgdmFsdWVzCi0gRGVsZXRlIGRhdGEgdGhhdCBjYW5ub3QgYmUgY29ycmVjdGVkL3JlcGxhY2VkCi0gQ29ycmVjdCBhbnkgZGF0YSBmb3JtYXR0aW5nIGlzc3VlcwotIENyZWF0aW5nIG5ldyBmZWF0dXJlcwotIElkZW50aWZ5IGVycm9ycyByZXZlYWxlZCB3aGVuIG5ldyB2YXJpYWJsZXMgYXJlIGNyZWF0ZWQKCiMjIE1pc3NpbmcgVmFsdWVzCmBgYHtyfQojSWRlbnRpZnlpbmcgdG90YWwgbnVtYmVyIG9mIG1pc3NpbmcgdmFsdWVzCnN1bShpcy5uYSh0ZXNsYSkpCmBgYApUaGVyZSBhcmUgbm8gbWlzc2luZyB2YWx1ZXMuIAoKIyMgQ29ycmVjdGluZyBGb3JtYXR0aW5nIElzc3VlcwpgYGB7cn0KI0NoZWNraW5nIHRoZSBkYXRhIHR5cGVzCnN0cih0ZXNsYSkKYGBgCldlIG5lZWQgdG8gZm9ybWF0IHRoZSBEYXRlIGNvbHVtbiBhcyBkYXRlIHZhbHVlcyBhbmQgZm9ybWF0IHRoZSBDbG9zZS5MYXN0LCBPcGVuLCBIaWdoIGFuZCBMb3cgYXMgbnVtYmVycy4KCmBgYHtyfQojRm9ybWF0dGluZyB0aGUgRGF0ZSBjb2x1bW4gYXMgZGF0ZSB2YWx1ZXMKdGVzbGEkRGF0ZSA8LSBhcy5EYXRlKHRlc2xhJERhdGUsICIlbS8lZC8lWSIpCgojRm9ybWF0dGluZyBDbG9zZS5MYXN0LCBPcGVuLCBIaWdoIGFuZCBMb3cgYXMgbnVtYmVycyByb3VuZGVkIHRvIDIgZGVjaW1hbCBwbGFjZXMKIyhnc3ViKCJbJF0iLCIiLCBjb2x1bW5fbmFtZSkgYWxsb3dzIHVzIHRvIHJlbW92ZSB0aGUgRG9sbGFyIHNpZ24gZnJvbSB0aGUgY2hhcmFjdGVyIHN0cmluZwp0ZXNsYSRDbG9zZS5MYXN0IDwtICByb3VuZChhcy5udW1lcmljKGdzdWIoIlskXSIsIiIsIHRlc2xhJENsb3NlLkxhc3QpKSwyKQp0ZXNsYSRPcGVuIDwtICByb3VuZChhcy5udW1lcmljKGdzdWIoIlskXSIsIiIsIHRlc2xhJE9wZW4pKSwyKQp0ZXNsYSRIaWdoIDwtICByb3VuZChhcy5udW1lcmljKGdzdWIoIlskXSIsIiIsIHRlc2xhJEhpZ2gpKSwyKQp0ZXNsYSRMb3cgPC0gcm91bmQoYXMubnVtZXJpYyhnc3ViKCJbJF0iLCIiLCB0ZXNsYSRMb3cpKSwyKQoKaGVhZCh0ZXNsYSkKCmBgYAojIyBDcmVhdGluZyBOZXcgRmVhdHVyZXMKIyMjIE1vdmluZyBBdmVyYWdlCldlIHdpbGwgY3JlYXRlIGEgbmV3IGNvbHVtbiB0byB0cmFjayB0aGUgbW92aW5nIGF2ZXJhZ2Ugb2YgdGhlIGRhaWx5IENsb3NpbmcgU3RvY2sgUHJpY2Ugb3ZlciBhIHNldCBwZXJpb2QuIFRoZSBtb3ZpbmcgYXZlcmFnZSBzbW9vdGhzIG91dCB0aGUgc3RvY2sgcHJpY2UgcHJpY2UgZGF0YSBieSBjcmVhdGluZyBhIGNvbnN0YW50bHkgdXBkYXRlZCBhdmVyYWdlIHN0b2NrIHByaWNlLiBXZSB3aWxsIHRyYWNrIHRoZSBtb3ZpbmcgYXZlcmFnZSBhY3Jvc3MgdHdvIHBlcmlvZHM6CgotIDcgRGF5IFBlcmlvZAotIDMwIERheSBQZXJpb2QKCmBgYHtyfQojQ2FsY3VsYXRpbmcgYSBtb3ZpbmcgYXZlcmFnZSBmb3Igc3RvY2sgcHJpY2Ugb3ZlciB0aGUgbGFzdCA3IGRheXMKdGVzbGEkTW92aW5nX0F2ZXJhZ2VfN19EYXkgPC0gcm91bmQobWEodGVzbGEkQ2xvc2UuTGFzdCwgNyksMikKdGVzbGEkTW92aW5nX0F2ZXJhZ2VfMzBfRGF5IDwtIHJvdW5kKG1hKHRlc2xhJENsb3NlLkxhc3QsIDMwKSwyKQpgYGAKCiMjIElkZW50aWZ5IElzc3VlcyBSZXZlYWxlZCBkdWUgdG8gTmV3IEZlYXR1cmVzClRoZSBNb3ZpbmcgYXZlcmFnZXMgY2FsY3VsYXRlIGFuIGF2ZXJhZ2UgYmFzZWQgb24gcHJldmlvdXMgZGF0YSBvdmVyIHRoZSBzZXQgcGVyaW9kLiBIb3dldmVyLCBmb3IgY2FzZXMgd2hlcmUgdGhlcmUgaXMgbm90IGVub3VnaCBwcmV2aW91cyBkYXRhLCB0aGUgbW92aW5nIGF2ZXJhZ2UgY2Fubm90IGNhbGN1bGF0ZSBhIHZhbHVlIGFuZCBsZWF2ZXMgYSBtaXNzaW5nIHZhbHVlLiBUbyByZWN0aWZ5IHRoZXNlIG1pc3NpbmcgdmFsdWVzIHdlIHdpbGwgaGF2ZSB0byByZW1vdmUgdGhlIGFzc29jaWF0ZWQgcm93cy4KYGBge3J9CiNSZW1vdmluZyByb3dzIHdpdGggbWlzc2luZyBkYXRhCnRlc2xhIDwtIG5hLm9taXQodGVzbGEpCmBgYAoKIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzCkluIHRoaXMgc3RhZ2UsIHdlIHdpbGwgZXhhbWluZSB0aGUgZGF0YSB0byBpZGVudGlmeSBhbnkgcGF0dGVybnMsIHRyZW5kcyBhbmQgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMuIEl0IHdpbGwgaGVscCB1cyBhbmFseXplIHRoZSBkYXRhIGFuZCBleHRyYWN0IGluc2lnaHRzIHRoYXQgY2FuIGJlIHVzZWQgdG8gbWFrZSBkZWNpc2lvbnMuCgpEYXRhIFZpc3VhbGl6YXRpb24gd2lsbCBnaXZlIHVzIGEgY2xlYXIgaWRlYSBvZiB3aGF0IHRoZSBkYXRhIG1lYW5zIGJ5IGdpdmluZyBpdCB2aXN1YWwgY29udGV4dC4KCiMjIFN0YXRpc3RpY3MKTGV0cyB0YWtlIGEgbG9vayBhdCB0aGUgZGF0YSBhcyBhIHdob2xlIHRvIHVuZGVyc3RhbmQgaG93IHRoZSBUZXNsYSBTdG9jayBQcmljZSBoYXMgdmFyaWVkIG92ZXIgdGhlIGxhc3QgNSB5ZWFycy4KYGBge3J9CnN1bW1hcnkodGVzbGEpCmBgYApBcyBzZWVuIGluIHRoZSBzdW1tYXJ5IGFib3ZlOgoKLSBPbGRlc3QgZGF0YSBwb2ludCBpcyBmcm9tIDxiPjIwMTYtMTEtMDc8L2I+IGFuZCB0aGUgbW9zdCByZWNlbnQgZGF0YSBwb2ludCBpcyBmcm9tIDxiPjIwMjEtMDktMjM8L2I+LiAKLSBIaWdoZXN0IENsb3NpbmcgU3RvY2sgUHJpY2Ugd2FzIDxiPiQ4ODMuMDk8L2I+LCB3aGlsZSB0aGUgbG93ZXN0IENsb3NpbmcgU3RvY2sgUHJpY2UgPGI+JDM1Ljc5PC9iPi4KLSBIaWdoZXN0IE9wZW5pbmcgU3RvY2sgUHJpY2Ugd2FzIDxiPiQ4OTEuMzg8L2I+LCB3aGlsZSB0aGUgbG93ZXN0IE9wZW5pbmcgU3RvY2sgUHJpY2UgPGI+JDM2LjIyPC9iPi4KLSBUaGUgSGlnaGVzdCBTdG9jayBQcmljZSBvdmVyIHRoZSBwYXN0IDUgeWVhcnMgd2FzIDxiPiQ5MDAuNDA8L2I+LgotIFRoZSBMb3dlc3QgU3RvY2sgUHJpY2Ugb3ZlciB0aGUgcGFzdCA1IHllYXJzIHdhcyA8Yj4kMzUuNDA8L2I+LgotIFRoZSBWb2x1bWUgb2YgU3RvY2tzIHRyYWRlZCBhdmVyYWdlZCBhcm91bmQgPGI+NDUgbWlsbGlvbjwvYj4gd2l0aCBhIG1heGltdW0gb2YgYXJvdW5kIDxiPjMwNCBtaWxsaW9uPC9iPi4gIAoKIyMgVGVzbGEgU3RvY2sgUGVyZm9ybWFjZQoKYGBge3J9CmdncGxvdCh0ZXNsYSwgYWVzKHg9RGF0ZSkpICsgCiAgZ2VvbV9saW5lKGFlcyh5ID0gQ2xvc2UuTGFzdCwgY29sb3VyPSJDbG9zZSBQcmljZSIpKSArIAogIGdlb21fbGluZShhZXMoeSA9ICBPcGVuLCBjb2xvdXI9Ik9wZW4gUHJpY2UiKSkgKwogIGdlb21fbGluZShhZXMoeSA9ICBIaWdoLCBjb2xvdXI9IkhpZ2ggUHJpY2UiKSkgKwogIGdlb21fbGluZShhZXMoeSA9ICBMb3csIGNvbG91cj0iTG93IFByaWNlIikpICsKICBsYWJzKHRpdGxlPSJUZXNsYSBTdG9jayBQcmljZSBPdmVyIHRoZSBMYXN0IDUgWWVhcnMiLCB4PSJZZWFyIiwgeT0iVGVzbGEgU3RvY2sgUHJpY2UgKCQpIiwgY29sb3VyID0gIlByaWNlIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJzdGVlbGJsdWUiLCJnb2xkIiwiZGFya3Zpb2xldCIpKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbWlub3JfYnJlYWtzID0gIjEgbW9udGgiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKClRoZSBwbG90IGFib3ZlIHNob3dzIHRoZSBEYWlseSBDbG9zaW5nLCBPcGVuaW5nLCBIaWdoIGFuZCBMb3cgU3RvY2sgUHJpY2VzLiBUaGUgc3ByZWFkIG9mIHRoZSBsaW5lcyBpbmRpY2F0ZXMgdGhlIGZsdWN0dWF0aW9ucyBpbiBEYWlseSBTdG9jayBQcmljZXMuIFRoZSBmb3VyIGxpbmVzIHN0aWNrIHRvZ2V0aGVyIHdpdGggbGl0dGxlIHZhcmlhdGlvbiB1bnRpbCBlYXJseSAyMDIwLCB3aGljaCBpcyB3aGVuIHdlIGJlZ2luIHRvIHNlZSBhIGxvdCBtb3JlIGZsdWN0dWF0aW9uIGluIHByaWNlIGJ1dCBpbiBnZW5lcmFsIHRoZXJlIGlzIHN0ZWVwIGluY3JlYXNlIGluIHN0b2NrIHByaWNlLiBXZSBjYW4gZXhhbWluZSB0aGUgQ2xvc2luZyBTdG9jayBQcmljZSB0byBnZXQgYSBjbGVhcmVyIGlkZWEgb2YgdGhpcyBiZWhhdmlvci4KCgojIyBDbG9zaW5nIFN0b2NrIFByaWNlCmBgYHtyfQojUGxvdHRpbmcgdGhlIENsb3NpbmcgU3RvY2sgUHJpY2Ugb3ZlciB0aGUgbGFzdCA1IHllYXJzCmdncGxvdCh0ZXNsYSwgYWVzKHg9RGF0ZSwgeT1DbG9zZS5MYXN0ICkpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlPSJUZXNsYSBDbG9zaW5nIFN0b2NrIFByaWNlIE92ZXIgdGhlIExhc3QgNSBZZWFycyIsIHg9IlllYXIiLCB5PSJUZXNsYSBDbG9zaW5nIFN0b2NrIFByaWNlICgkKSIpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9taW5vcl9icmVha3MgPSAiMSBtb250aCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKQXMgc2VlbiBwcmV2aW91c2x5IGFib3ZlIHRoZXJlIGlzIGEgc3RlZXAgcmlzZSBpbiB0aGUgVGVzbGEgU3RvY2sgUHJpY2Ugc2luY2UgZWFybHkgMjAyMC4gTGV0cyB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIHN0b2NrIHByaWNlIGR1cmluZyB0aGlzIHRpbWUuCgojIyMgQ2xvc2luZyBTdG9jayBQcmljZSBzaW5jZSBKYW4gMjAyMApgYGB7cn0KI1Bsb3R0aW5nIHRoZSBTdG9jayBQcmljZSBzaW5jZSBiZWdpbm5pbmcgb2YgSmFuIDIwMjAgb253YXJkcwpnZ3Bsb3QodGVzbGEsIGFlcyh4PURhdGUsIHk9Q2xvc2UuTGFzdCApKSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZT0iVGVzbGEgQ2xvc2luZyBTdG9jayBQcmljZSBpbiAyMDIwIiwgeD0iTW9udGgiLCB5PSJUZXNsYSBDbG9zaW5nIFN0b2NrIFByaWNlICgkKSIpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSBtb250aCIsIGRhdGVfbGFiZWxzID0gIiViIiwgbGltaXQ9Yyhhcy5EYXRlKCIyMDIwLTAxLTAxIiksYXMuRGF0ZSgiMjAyMS0wOS0yMyIpKSkgKwogIHlsaW0oMCw5MDApICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKClRoZSBzdG9jayBwcmljZSBoYXMgY29udGludWVkIHRvIGluY3JlYXNlIHNpZ25pZmljYW50bHkgc2luY2UgSmFuIDIwMjAsIHJlYWNoaW5nIGEgcGVhayBhcm91bmQgRmViIDIwMjEuIAoKYGBge3J9CiNUaGUgbW9zdCByZWNlbnQgc3RvY2sgcHJpY2UKcmVjZW50X3N0b2NrIDwtIHRlc2xhICU+JSBmaWx0ZXIoRGF0ZSA9PSBtYXgodGVzbGEkRGF0ZSkpCgojU3RvY2sgcHJpY2UgYXQgdGhlIGJlZ2lubmluZyBvZiAyMDIwCiNOb3RlOiBObyBkYXRhIGZvciBkYXRlIDIwMjAtMDEtMDEKc3RvY2tfc3RhcnRfMjAyMCA8LSB0ZXNsYSAlPiUgZmlsdGVyKERhdGUgPT0gYXMuRGF0ZSgiMjAyMC0wMS0wMiIpKQoKI1N0b2NrIHByaWNlIGF0IHRoZSBlbmQgb2YgMjAyMApzdG9ja19lbmRfMjAyMCA8LSB0ZXNsYSAlPiUgZmlsdGVyKERhdGUgPT0gYXMuRGF0ZSgiMjAyMC0xMi0zMSIpKQoKI0NhbGN1bGF0aW5nIHRoZSBwZXJjZW50YWdlIGluY3JlYXNlIHNpbmNlIHRoZSBzdGFydCBvZiAyMDIwIGFuZCB0aGUgbW9zdCByZWNlbnQgZGF0ZSAKcGN0X3JlY2VudCA9IHJvdW5kKCgoKHJlY2VudF9zdG9jayRDbG9zZS5MYXN0LXN0b2NrX3N0YXJ0XzIwMjAkQ2xvc2UuTGFzdCkvc3RvY2tfc3RhcnRfMjAyMCRDbG9zZS5MYXN0KSoxMDApLDApIAoKI0NhbGN1bGF0aW5nIHRoZSBwZXJjZW50YWdlIGluY3JlYXNlIGJldHdlZW4gdGhlIHN0YXJ0IGFuZCBlbmQgb2YgMjAyMCAKcGN0XzIwMjAgPSByb3VuZCgoKChzdG9ja19lbmRfMjAyMCRDbG9zZS5MYXN0LXN0b2NrX3N0YXJ0XzIwMjAkQ2xvc2UuTGFzdCkvc3RvY2tfc3RhcnRfMjAyMCRDbG9zZS5MYXN0KSoxMDApLDApIAoKY2F0KCJUaGUgc3RvY2sgcHJpY2UgaW5jcmVhc2U6IFxuIEphbiAyMDIwLVByZXNlbnQ6IixwY3RfcmVjZW50LCIlIFxuIEphbiAyMDIwIC0gRGVjIDIwMjAgRW5kOiIscGN0XzIwMjAsIiUiKSAKCmBgYApUaGUgc3RvY2sgcHJpY2UgaGFzIGluY3JlYXNlZCA8Yj43NzYlPC9iPiBiZXR3ZWVuIHRoZSBiZWdpbm5pbmcgb2YgMjAyMCBhbmQgdGhlIHByZXNlbnQuIEluIGZhY3QsIGl0IGluY3JlYXNlZCBieSA8Yj43MjAlPC9iPiBqdXN0IGluIDIwMjAgYWxvbmUuCgojIyBNb3ZpbmcgQXZlcmFnZQpgYGB7cn0KI1Bsb3R0aW5nIHRoZSBDbG9zaW5nIFN0b2NrIHByaWNlIHZzIHRoZSA3IERheSBNb3ZpbmcgQXZlcmFnZQpnZ3Bsb3QodGVzbGEsIGFlcyh4PURhdGUpKSArIAogIGdlb21fbGluZShhZXMoeSA9IENsb3NlLkxhc3QsIGNvbG91cj0iQ2xvc2UgUHJpY2UiKSkgKyAKICBnZW9tX2xpbmUoYWVzKHkgPSAgTW92aW5nX0F2ZXJhZ2VfN19EYXksIGNvbG91cj0iNyBEYXkiKSkgKwogIGxhYnModGl0bGU9IlRlc2xhIFN0b2NrIFByaWNlIHZzLiA3IERheSBNb3ZpbmcgQXZlcmFnZSIsIHg9IlllYXIiLCB5PSJUZXNsYSBTdG9jayBQcmljZSAoJCkiLCBjb2xvdXIgPSAiUHJpY2UgJiBNb3ZpbmcgQXZlcmFnZSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCJ0YW4zIikpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9taW5vcl9icmVha3MgPSAiMSBtb250aCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKYGBge3J9CiNQbG90dGluZyB0aGUgQ2xvc2luZyBTdG9jayBwcmljZSB2cyB0aGUgMzAgRGF5IE1vdmluZyBBdmVyYWdlCmdncGxvdCh0ZXNsYSwgYWVzKHg9RGF0ZSkpICsgCiAgZ2VvbV9saW5lKGFlcyh5ID0gQ2xvc2UuTGFzdCwgY29sb3VyPSJDbG9zZSBQcmljZSIpKSArIAogIGdlb21fbGluZShhZXMoeSA9ICBNb3ZpbmdfQXZlcmFnZV8zMF9EYXksIGNvbG91cj0iMzAgRGF5IikpICsKICBsYWJzKHRpdGxlPSJUZXNsYSBTdG9jayBQcmljZSB2cy4gMzAgRGF5IE1vdmluZyBBdmVyYWdlIiwgeD0iWWVhciIsIHk9IlRlc2xhIFN0b2NrIFByaWNlICgkKSIsIGNvbG91ciA9ICJQcmljZSAmIE1vdmluZyBBdmVyYWdlIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsIm9yYW5nZSIpKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbWlub3JfYnJlYWtzID0gIjEgbW9udGgiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKClRoZSAzMCBEYXkgTW92aW5nIEF2ZXJhZ2UgZ2l2ZXMgdXMgYSBtdWNoIHNtb290aGVyIGN1cnZlIHRoYW4gdGhlIDcgRGF5IE1vdmluZyBBdmVyYWdlLiBUaGVyZWZvcmUsIHVzaW5nIHRoZSAzMCBEYXkgTW92aW5nIEF2ZXJhZ2Ugd2UgY2FuIGNsZWFybHkgc2VlIHRoZSBwb2ludHMgd2hlcmUgdGhlIHN0b2NrIHByaWNlIGRldmlhdGVkIG5vdGljZWFibHkgZnJvbSB0aGUgcHJlZGljdGVkIHByaWNlLiBUaGUgc3RvY2sgcHJpY2UgZmx1Y3R1YXRpb25zIHNlZW0gdG8gYmUgbW9zdCBzaWduaWZpY2FudCBpbiB0aGUgcGVyaW9kIGFmdGVyIGVhcmx5IDIwMjAsIHdoaWNoIGNvcnJlbGF0ZXMgd2l0aCBvdXIgZWFybGllciBvYnNlcnZhdGlvbi4gCgojIyBTdG9jayBUcmFkaW5nIFZvbHVtZQpgYGB7cn0KI1Bsb3R0aW5nIHRoZSBDbG9zaW5nIFN0b2NrIFByaWNlIG92ZXIgdGhlIGxhc3QgNSB5ZWFycwpnZ3Bsb3QodGVzbGEsIGFlcyh4PURhdGUsIHk9Vm9sdW1lLCBjb2xvciA9Im9yYW5nZSIpKSArIAogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gIDQ1MDAwMDAwLCBjb2xvcj0icmVkIikpICsKICBsYWJzKHRpdGxlPSJUZXNsYSBTdG9jayBUcmFkaW5nIFZvbHVtZSBPdmVyIHRoZSBMYXN0IDUgWWVhcnMiLCB4PSJZZWFyIiwgeT0iTnVtYmVyIG9mIFN0b2NrcyBUcmFkZWQiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbWlub3JfYnJlYWtzID0gIjEgbW9udGgiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgCmBgYAoKVGhlIHZvbHVtZSBvZiBzdG9ja3MgdHJhZGVkIGhhcyBnZW5lcmFsbHkgcmVtYWluZWQgYXJvdW5kIG9yIGJlZW4gdW5kZXIgdGhlIGF2ZXJhZ2Ugb2YgNDUgbWlsbGlvbiAoaW5kaWNhdGVkIGJ5IHRoZSBsaW5lKSwgaG93ZXZlciB0aGVyZSBpcyBhbiBpbmNyZWFzZSBpbiB2b2x1bWUgZHVyaW5nIHRoZSB5ZWFyIDIwMjAsIHRob3VnaCB0aGUgaXQgZG9lcyBzZWVtIHRvIGJlIGdldHRpbmcgYmFjayB0byBub3JtYWwgc2luY2UgdGhlIGJlZ2lubmluZyBvZiAyMDIxLgoKIyBTdW1tYXJ5IG9mIERhdGEgQW5hbHlzaXMKCi0gT2xkZXN0IGRhdGEgcG9pbnQgaXMgZnJvbSA8Yj4yMDE2LTExLTA3PC9iPiBhbmQgdGhlIG1vc3QgcmVjZW50IGRhdGEgcG9pbnQgaXMgZnJvbSA8Yj4yMDIxLTA5LTIzPC9iPi4gCi0gSGlnaGVzdCBDbG9zaW5nIFN0b2NrIFByaWNlIHdhcyA8Yj4kODgzLjA5PC9iPiwgd2hpbGUgdGhlIGxvd2VzdCBDbG9zaW5nIFN0b2NrIFByaWNlIDxiPiQzNS43OTwvYj4uCi0gSGlnaGVzdCBPcGVuaW5nIFN0b2NrIFByaWNlIHdhcyA8Yj4kODkxLjM4PC9iPiwgd2hpbGUgdGhlIGxvd2VzdCBPcGVuaW5nIFN0b2NrIFByaWNlIDxiPiQzNi4yMjwvYj4uCi0gVGhlIEhpZ2hlc3QgU3RvY2sgUHJpY2Ugb3ZlciB0aGUgcGFzdCA1IHllYXJzIHdhcyA8Yj4kOTAwLjQwPC9iPi4KLSBUaGUgTG93ZXN0IFN0b2NrIFByaWNlIG92ZXIgdGhlIHBhc3QgNSB5ZWFycyB3YXMgPGI+JDM1LjQwPC9iPi4KLSBUaGUgVm9sdW1lIG9mIFN0b2NrcyB0cmFkZWQgYXZlcmFnZWQgYXJvdW5kIDxiPjQ1IG1pbGxpb248L2I+IHdpdGggYSBtYXhpbXVtIG9mIGFyb3VuZCA8Yj4zMDQgbWlsbGlvbjwvYj4uICAKClRoZSBUZXNsYSBTdG9jayBQcmljZSBoYXMgaW5jcmVhc2Ugc2lnbmlmaWNhbnRseSBzaW5jZSAyMDE2LiBUaGUgc3RvY2sgcHJpY2UgcmVtYWluZWQgcmVsYXRpdmVseSBzdGVhZHkgdW50aWwgZWFybHkgMjAyMCB3aGVuIGl0IGJlZ2FuIHRvIHJpc2UgZHJhc3RpY2FsbHkuIFRoZSBzdG9jayBwcmljZSBoYXMgaW5jcmVhc2VkIDxiPjc3NiU8L2I+IGJldHdlZW4gdGhlIGJlZ2lubmluZyBvZiAyMDIwIGFuZCB0aGUgcHJlc2VudC4gSW4gZmFjdCwgaXQgaW5jcmVhc2VkIGJ5IDxiPjcyMCU8L2I+IGp1c3QgaW4gMjAyMCBhbG9uZS4gV2hpbGUgdGhlIHN0b2NrIHByaWNlIHJlYWNoZXMgaXRzIHBlYWsgYXJvdW5kIDxiPkZlYiAyMDIxPC9iPiwgaXQgaGFzIGNvbnRpbnVlZCBpdHMgZ2VuZXJhbCB1cHdhcmQgdHJlbmQuIEhvd2V2ZXIsIGR1cmluZyB0aGUgcGVyaW9kIG9mIHByaWNlIGluY3JlYXNlIHRoZSBEYWlseSBzdG9jayBwcmljZSB3b3VsZCBmbHVjdHVhdGUgc2lnbmlmaWNhbnRseSBjb21wYXJlZCB0byBpdHMgcmVsYXRpdmVseSBzdGFibGUgcHJpY2UgcHJpb3IgdG8gMjAyMC4gCgpUaGUgdm9sdW1lIG9mIHN0b2NrcyB0cmFkZWQgZHVyaW5nIHRoZSBsYXN0IDUgeWVhcnMgaGFzIGdlbmVyYWxseSByZW1haW5lZCBhcm91bmQgb3IgYmVlbiB1bmRlciB0aGUgYXZlcmFnZSBvZiA0NSBtaWxsaW9uLCBob3dldmVyIHRoZXJlIGlzIGFuIGluY3JlYXNlIGluIHZvbHVtZSBkdXJpbmcgdGhlIHllYXIgMjAyMCwgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIHN0ZWVwIGluY3JlYXNlIGluIHN0b2NrIHByaWNlLiBXZSB3b3VsZCB0eXBpY2FsbHkgZXhwZWN0IGFuIGluY3JlYXNlIGluIHRyYWRpbmcgYWN0aXZpdHkgbGlrZSB0aGlzIGR1cmluZyBhIHBlcmlvZCB3aGVuIHRoZSBjb21wYW55J3Mgc3RvY2tzIGFyZSByYXBpZGx5IHJpc2luZy4gCgo=