Time Series
The basic idea behind time series is that we use the past behavior of a variable to predict its future values.
Time series arise in a vast verity of circumstances, including but not limited to:
- Daily closing stock prices
- Daily relative values of currencies
- Monthly unemployment rates in a country
- Quarterly public debt levels in a country
- Weekly viewership figures of a TV series
- Average annual CO2 emissions
- Quarterly sales figures of a retailer
- Monthly production figures of a factory
- Annual % growth of GDP of an economy
- etc. etc. etc.
Example 1
To gain an better understanding of how time series operate, we will examine the monthly sales figures for a mobile phone Model M sold by a particular retailer. The monthly sales figures over a 24 month period are given in the table below:
| Jan |
197 |
296 |
| Feb |
211 |
276 |
| Mar |
203 |
305 |
| Apr |
247 |
308 |
| May |
239 |
356 |
| Jun |
269 |
393 |
| Jul |
308 |
363 |
| Aug |
262 |
386 |
| Sep |
258 |
443 |
| Oct |
256 |
308 |
| Nov |
261 |
358 |
| Dec |
288 |
384 |
- To begin the times series analysis of this data, we create a data vector MS (Monthly Sales) to contain the sales data:
MS<-c(197,211,203,247,239,269,308,262,258,256,261,288,296,276,305,308,356,393,363,386,443,308,358,384)
MS
length(MS)
Next we need to create a time vector against which these sales figures are plotted: We need a vector with the same length as MS, i.e. with 24 entries, starting at 1 and increasing in increments of 1. * We can automate a lot of this for future examples using the length() and seq() functions
Time <- seq(1,length(MS),1)
Time
length(Time)
This creates a sequence of values starting at 1, ending at length(MS) and increasing with a step-size 1.
Time and MS now both have 24 entries, so we can plot them on the same graph:
plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
- The function lines() indicates that a line should be drawn between each of the data points of the time series.
- Recall that the argument pch appearing in plot() selects the type of marker used to mark the data points. Its possible values are 1 to 26.
Forecasting
Recall from lectures that we used a linear regression model to model the data in this time series. This model was given by \[
\hat{y}_t=198.03+8.07t
\] where \(t\) referred to a month number.
We will now create our own R function corresponding to this, which we are going to call Forecast1
Forecast1 <- function(t){
198.03+8.07*t
}
- The values predicted by this model at each of the months in Time are now given by
Forecast1(Time)
Mean Absolute Deviation (MAD) & Mean Square Error (MSE)
- Recall that the Mean Absolute Deviation (MAD) of a model, was given by
\[
MAD= \frac{1}{n}\sum_{t=1}^{N}\vert y_{t}-\hat{y}_t\vert
\]
- \(y_t\) denotes the actual value of the variable \(y\) at time \(t\)
- \(\hat{y}_t\) denotes the predicted value of the variable \(y\) at time \(t\)
- \(n\) is the number of observations we have, i.e. the number of actual values \(y_t\).
- R will calculate this for us automatically as follows:
MAD1<-mean(abs(MS-Forecast1(Time)))
MAD1
Exercise 1
Modify this code block to find the MSE of the model.
MSE1<-mean(abs(MS-Forecast1(Time))^2)
MSE1
Prediction Intervals
\(t_{\frac{\alpha}{2},n-2}\) we us the
t_star = abs(qt(0.05,df=22)) # df= Number of months-2
\(x^*\)
x_star=27
\(y^*\)
y_star=Forecast1(27)
y_star
MSE
MSE1
\(\bar{x}\)
x_bar=mean(Time)
\(\Sigma_{i=1}^{n}(x_i-\bar{x})^2\)
Sum1=sum((Time-x_bar)^2)
Upper boundary of CI
y_star+t_star*sqrt(MSE1*(1+1/24+(x_star-x_bar)/Sum1))
Lower boundary of CI
y_star-t_star*sqrt(MSE1*(1+1/24+(x_star-x_bar)/Sum1))
The 90% Prediction Interval
We are 90% confident that sales in the 27th month will be between 362 and 469 units.
Exercise 2
Find the 90% prediction interval for sales in the 27th month.
Exercise 3
The closing values of Apple Inc. (AAPL) Stock on the NASDAQ Stock Exchange from 8 August 2017 to 8 November 2017 are given in the data file AppleQuotes(3M).csv, available on Moodle. (Available at http://www.nasdaq.com)
Using this data set answer the following:
- Import the data in this file using the following and call the data structure AAPL
AAPL<-read.csv('AppleQuotes(3M).csv')
- Create two data vectors from this file, one for the closing value and one for the day
Create a time series plot for this data.
From this data plot, determine if there is a trend in the closing value of Apple stock over the past 3 months.
Use the function lm(Closing Value ~ Day) to create a linear regression model for this data.
lm(Closing~Day)
Create a linear model to forecast this data.
Create an R function to represent this model.
Find the MAD and MSE of this model
Find the 95% prediction interval for the closing price of Apple Stock in 10 days from now.
Exercise 4
The closing values of Google Inc. (GOOGL) Stock on the NASDAQ Stock Exchange from 8 November 2016 to 8 November 2017 are given in the data file GoogleQuotes(3M).csv, available on Moodle . (Available at http://www.nasdaq.com).
Using this data set answer the following:
- Import the data in this file using the following and call the data structure GOOGL
GOOGL<-read.csv('GoogleQuotes(1Y).csv')
Create two data vectors from this file, one for the trading value and one for the day
Create a time series plot for this data.
From this data plot, determine if there is a trend in the closing value of Google stock over the past year.
Use the function lm(Trading Value ~ Day) to create a linear regression model for this data.
Create a linear model to forecast this data.
Create an R function to represent this model.
Find the MAD and MSE of this model
Find the 90% and 99% prediction intervals for the trading volume of Google Stock in 10 days from now.
Exercise 5
The % Growth in GDP of Chin, the UK, the US, Ireland, the EU, the OECD and the World, for the years 1961-2016 are given in the data file RegionalGDPGrowth(1961-2016).csv. Import this data file into R and answer the following questions. (Available at http://www.worldbank.org)
Create a data vector for the Year a separate vector for the GDP growth of each country in the data file.
Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=1 row and B=2 columns for the GDP growth of China and the US To illustrate how this function works, the time-series plot from Example 1 is plotted in 1 row and 2 columns
par(mfrow=c(1,2))
plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=3 row and B=1 columns for the GDP growth of China and the US, the UK
Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=2 row and B=2 columns for the GDP growth of the EU, the US, the OECD and the World.
Is there any apparent trend in economic growth observable from these time-series.
From the time-series plots, which region has shown the most consistent economic growth between 1961 and 2016.
LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpc2F0aW9uIDIwMTkgLSBBc3NpZ25tZW50IDYiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCgoKIyMgTGlzdCBvZiBSIGNvbG9yczoKaHR0cDovL3d3dy5zdGF0LmNvbHVtYmlhLmVkdS9+dHpoZW5nL2ZpbGVzL1Jjb2xvci5wZGYKCgojIFRpbWUgU2VyaWVzCgoqIFRoZSBiYXNpYyBpZGVhIGJlaGluZCB0aW1lIHNlcmllcyBpcyB0aGF0IHdlIHVzZSB0aGUgcGFzdCBiZWhhdmlvciBvZiBhIHZhcmlhYmxlIHRvIHByZWRpY3QgaXRzIGZ1dHVyZSB2YWx1ZXMuCgoqIFRpbWUgc2VyaWVzIGFyaXNlIGluIGEgdmFzdCB2ZXJpdHkgb2YgY2lyY3Vtc3RhbmNlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bzoKICAgIAogICAgKiBEYWlseSBjbG9zaW5nIHN0b2NrIHByaWNlcwogICAgKiBEYWlseSByZWxhdGl2ZSB2YWx1ZXMgb2YgY3VycmVuY2llcwogICAgKiBNb250aGx5IHVuZW1wbG95bWVudCByYXRlcyBpbiBhIGNvdW50cnkKICAgICogUXVhcnRlcmx5IHB1YmxpYyBkZWJ0IGxldmVscyBpbiBhIGNvdW50cnkKICAgICogV2Vla2x5IHZpZXdlcnNoaXAgZmlndXJlcyBvZiBhIFRWIHNlcmllcwogICAgKiBBdmVyYWdlIGFubnVhbCBDTzIgZW1pc3Npb25zCiAgICAqIFF1YXJ0ZXJseSBzYWxlcyBmaWd1cmVzIG9mIGEgcmV0YWlsZXIKICAgICogTW9udGhseSBwcm9kdWN0aW9uIGZpZ3VyZXMgb2YgYSBmYWN0b3J5CiAgICAqIEFubnVhbCAlIGdyb3d0aCBvZiBHRFAgb2YgYW4gZWNvbm9teQogICAgKiBldGMuIGV0Yy4gZXRjLgogICAgCiMjIEV4YW1wbGUgMSAKClRvIGdhaW4gYW4gYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2YgaG93IHRpbWUgc2VyaWVzIG9wZXJhdGUsIHdlIHdpbGwgZXhhbWluZSB0aGUgbW9udGhseSBzYWxlcyBmaWd1cmVzIGZvciBhIG1vYmlsZSBwaG9uZSBfX01vZGVsIE1fXyBzb2xkIGJ5IGEgcGFydGljdWxhciByZXRhaWxlci4gVGhlIG1vbnRobHkgc2FsZXMgZmlndXJlcyBvdmVyIGEgMjQgbW9udGggcGVyaW9kIGFyZSBnaXZlbiBpbiB0aGUgdGFibGUgYmVsb3c6Cgp8ICBNb250aCAgfCBNb250aGx5IFNhbGVzIEZpZ3VyZXMgKFllYXIgMSkgfCBNb250aGx5IFNhbGVzIEZpZ3VyZXMgKFllYXIgMikgIHwKfC0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgICBKYW4gICB8ICAgICAgICAgICAgICAgMTk3ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDI5NiAgICAgICAgICAgICAgICAgfAp8ICAgRmViICAgfCAgICAgICAgICAgICAgIDIxMSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAyNzYgICAgICAgICAgICAgICAgIHwKfCAgIE1hciAgIHwgICAgICAgICAgICAgICAyMDMgICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzA1ICAgICAgICAgICAgICAgICB8CnwgICBBcHIgICB8ICAgICAgICAgICAgICAgMjQ3ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDMwOCAgICAgICAgICAgICAgICAgfAp8ICAgTWF5ICAgfCAgICAgICAgICAgICAgIDIzOSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzNTYgICAgICAgICAgICAgICAgIHwKfCAgIEp1biAgIHwgICAgICAgICAgICAgICAyNjkgICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzkzICAgICAgICAgICAgICAgICB8CnwgICBKdWwgICB8ICAgICAgICAgICAgICAgMzA4ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDM2MyAgICAgICAgICAgICAgICAgfAp8ICAgQXVnICAgfCAgICAgICAgICAgICAgIDI2MiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzODYgICAgICAgICAgICAgICAgIHwKfCAgIFNlcCAgIHwgICAgICAgICAgICAgICAyNTggICAgICAgICAgICAgIHwgICAgICAgICAgICAgNDQzICAgICAgICAgICAgICAgICB8CnwgICBPY3QgICB8ICAgICAgICAgICAgICAgMjU2ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDMwOCAgICAgICAgICAgICAgICAgfAp8ICAgTm92ICAgfCAgICAgICAgICAgICAgIDI2MSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzNTggICAgICAgICAgICAgICAgIHwKfCAgIERlYyAgIHwgICAgICAgICAgICAgICAyODggICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzg0ICAgICAgICAgICAgICAgICB8CgoqIFRvIGJlZ2luIHRoZSB0aW1lcyBzZXJpZXMgYW5hbHlzaXMgb2YgdGhpcyBkYXRhLCB3ZSBjcmVhdGUgYSBkYXRhIHZlY3RvciBfX01TX18gKE1vbnRobHkgU2FsZXMpIHRvIGNvbnRhaW4gdGhlIHNhbGVzIGRhdGE6CmBgYHtyfQpNUzwtYygxOTcsMjExLDIwMywyNDcsMjM5LDI2OSwzMDgsMjYyLDI1OCwyNTYsMjYxLDI4OCwyOTYsMjc2LDMwNSwzMDgsMzU2LDM5MywzNjMsMzg2LDQ0MywzMDgsMzU4LDM4NCkKTVMKbGVuZ3RoKE1TKQpgYGAKKk5leHQgd2UgbmVlZCB0byBjcmVhdGUgYSBfdGltZSB2ZWN0b3JfIGFnYWluc3Qgd2hpY2ggdGhlc2Ugc2FsZXMgZmlndXJlcyBhcmUgcGxvdHRlZDoKICAgICogV2UgbmVlZCBhIHZlY3RvciB3aXRoIHRoZSBzYW1lIGxlbmd0aCBhcyBfX01TX18sIGkuZS4gd2l0aCAyNCBlbnRyaWVzLCBzdGFydGluZyBhdCAxIGFuZCBpbmNyZWFzaW5nICAgICAgICBpbiBpbmNyZW1lbnRzIG9mIDEuCiAgICAqIFdlIGNhbiBhdXRvbWF0ZSBhIGxvdCBvZiB0aGlzIGZvciBmdXR1cmUgZXhhbXBsZXMgdXNpbmcgdGhlIF9fbGVuZ3RoKClfXyBhbmQgX19zZXEoKV9fIGZ1bmN0aW9ucwpgYGB7cn0KVGltZSA8LSBzZXEoMSxsZW5ndGgoTVMpLDEpClRpbWUKbGVuZ3RoKFRpbWUpCmBgYAoqIFRoaXMgY3JlYXRlcyBhIHNlcXVlbmNlIG9mIHZhbHVlcyBzdGFydGluZyBhdCAxLCBlbmRpbmcgYXQgX19sZW5ndGgoTVMpX18gYW5kIGluY3JlYXNpbmcgd2l0aCBhIHN0ZXAtc2l6ZSAxLgoKKiBfX1RpbWVfXyBhbmQgX19NU19fIG5vdyBib3RoIGhhdmUgMjQgZW50cmllcywgc28gd2UgY2FuIHBsb3QgdGhlbSBvbiB0aGUgc2FtZSBncmFwaDoKYGBge3J9CnBsb3QoVGltZSxNUyxwY2g9MTUsY29sPSJyZWQiLHlsYWI9Ik1vbnRobHkgU2FsZXMgRmlndXJlcyIsIHhsYWI9Ik1vbnRoIixtYWluPSJNb250aGx5IFNhbGVzIEZpZ3VyZXMgb2YgUGhvbmUgTW9kZWwgTSIpCmxpbmVzKFRpbWUsTVMpCmBgYAoqIFRoZSBmdW5jdGlvbiBfX2xpbmVzKClfXyBpbmRpY2F0ZXMgdGhhdCBhIGxpbmUgc2hvdWxkIGJlIGRyYXduIGJldHdlZW4gZWFjaCBvZiB0aGUgZGF0YSBwb2ludHMgb2YgdGhlIHRpbWUgc2VyaWVzLiAKKiBSZWNhbGwgdGhhdCB0aGUgYXJndW1lbnQgX19wY2hfXyBhcHBlYXJpbmcgaW4gX19wbG90KClfXyBzZWxlY3RzIHRoZSB0eXBlIG9mIG1hcmtlciB1c2VkIHRvIG1hcmsgdGhlIGRhdGEgcG9pbnRzLiAgSXRzIHBvc3NpYmxlIHZhbHVlcyBhcmUgMSB0byAyNi4KCiMjIEZvcmVjYXN0aW5nCiogUmVjYWxsIGZyb20gbGVjdHVyZXMgdGhhdCB3ZSB1c2VkIGEgX19saW5lYXIgcmVncmVzc2lvbiBtb2RlbF9fIHRvIG1vZGVsIHRoZSBkYXRhIGluIHRoaXMgdGltZSBzZXJpZXMuIFRoaXMgbW9kZWwgd2FzIGdpdmVuIGJ5ClxbClxoYXR7eX1fdD0xOTguMDMrOC4wN3QKXF0Kd2hlcmUgJHQkIHJlZmVycmVkIHRvIGEgbW9udGggbnVtYmVyLgoKKiBXZSB3aWxsIG5vdyBjcmVhdGUgb3VyIG93biBfX1IgZnVuY3Rpb25fXyBjb3JyZXNwb25kaW5nIHRvIHRoaXMsIHdoaWNoIHdlIGFyZSBnb2luZyB0byBjYWxsIF9fRm9yZWNhc3QxX18KCmBgYHtyfQpGb3JlY2FzdDEgPC0gZnVuY3Rpb24odCl7CiAgMTk4LjAzKzguMDcqdAp9CmBgYAoqIFRoZSB2YWx1ZXMgcHJlZGljdGVkIGJ5IHRoaXMgbW9kZWwgYXQgZWFjaCBvZiB0aGUgbW9udGhzIGluIF9fVGltZV9fIGFyZSBub3cgZ2l2ZW4gYnkKYGBge3J9CkZvcmVjYXN0MShUaW1lKQpgYGAKIyMgTWVhbiBBYnNvbHV0ZSBEZXZpYXRpb24gKE1BRCkgJiBNZWFuIFNxdWFyZSBFcnJvciAoTVNFKQoqIFJlY2FsbCB0aGF0IHRoZSBfX01lYW4gQWJzb2x1dGUgRGV2aWF0aW9uX18gIChfX01BRF9fKSBvZiBhIG1vZGVsLCB3YXMgZ2l2ZW4gYnkKClxbCk1BRD0gXGZyYWN7MX17bn1cc3VtX3t0PTF9XntOfVx2ZXJ0IHlfe3R9LVxoYXR7eX1fdFx2ZXJ0ClxdCiAgICAKICAqICR5X3QkIGRlbm90ZXMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgJHkkIGF0IHRpbWUgJHQkCiAgKiAkXGhhdHt5fV90JCBkZW5vdGVzIHRoZSBwcmVkaWN0ZWQgdmFsdWUgb2YgdGhlIHZhcmlhYmxlICR5JCBhdCB0aW1lICR0JAogICogJG4kIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIHdlIGhhdmUsIGkuZS4gdGhlIG51bWJlciBvZiBhY3R1YWwgdmFsdWVzICR5X3QkLgogICogX19SX18gd2lsbCBjYWxjdWxhdGUgdGhpcyBmb3IgdXMgYXV0b21hdGljYWxseSBhcyBmb2xsb3dzOgpgYGB7cn0KTUFEMTwtbWVhbihhYnMoTVMtRm9yZWNhc3QxKFRpbWUpKSkKTUFEMQpgYGAKKiBUaGUgY29kZSBhbmQgdGhlIGZvcm11bGEgY29ycmVzcG9uZCBhcyBmb2xsb3dzCgogICAgMS4gX19NU19fICRcbGVmdHJpZ2h0YXJyb3cgeV90JCwgCiAgICAKICAgIDIuIF9fRm9yZWNhc3QoVGltZSlfXyAkXGxlZnRyaWdodGFycm93IFxoYXR7eX1fdCQKICAgIAogICAgMy4gX19hYnMoTVMtRm9yZWNhc3QxKFRpbWUpKV9fICRcbGVmdHJpZ2h0YXJyb3cgXHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0JAogICAgCiAgICA0LiBfX21lYW4oYWJzKE1TLUZvcmVjYXN0MShUaW1lKSkpX18gJFxsZWZ0cmlnaHRhcnJvdyBcZnJhY3sxfXtufVxzdW1fe3Q9MX1ee259XHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0JAoKKiBSZWNhbGwgYWxzbyB0aGF0IHRoZSBfX01lYW4gU3F1YXJlIEVycm9yX18gIChfX01TRV9fKSBvZiBhIG1vZGVsIGlzIGdpdmVuIGJ5ClxbCk1TRT1cZnJhY3sxfXtufVxzdW1fe3Q9MX1ee259XHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0XjIKXF0KCiMjIEV4ZXJjaXNlIDEKCk1vZGlmeSB0aGlzIGNvZGUgYmxvY2sgdG8gZmluZCB0aGUgX19NU0VfXyBvZiB0aGUgbW9kZWwuIAoKYGBge3J9Ck1TRTE8LW1lYW4oYWJzKE1TLUZvcmVjYXN0MShUaW1lKSleMikKTVNFMQpgYGAKCgojIFByZWRpY3Rpb24gSW50ZXJ2YWxzCiogV2UgY2FuIGFsc28gdXNlIHRoZSBtb2RlbCB0byBmb3JlY2FzdCBmdXR1cmUgc2FsZXMgdmFsdWVzIG9mIHBob25lIG1vZGVsIE0uCgoqIFRvIGZpbmQgdGhlIF9fOTAlIFByZWRpY3Rpb24gSW50ZXJ2YWxfXyBvZiB0aGUgbW9kZWwgYXQgbW9udGggMjcgc2F5LCB3ZSBjYW4gdXNlIHRoZWUgZm9sbG93aW5nIGZvcm11bGEgZm9yIHRoaXMgaW50ZXJ2YWwKXFsKICBcaGF0e3l9X3t4XnsqfX1ccG0gdF97XGZyYWN7XGFscGhhfXsyfSxuLTJ9XHNxcnR7TVNFXGxlZnQoMStcZnJhY3sxfXtufStcZnJhY3t4XnsqfS1cYmFye3h9fXtcc3VtX3tpPTF9XntufSh4X2ktXGJhcnt4fSleMn1ccmlnaHQpfQpcXQoqIFRoZSBzeW1ib2xzIGluIHRoZSBmb3JtdWxhIGhhdmUgdGhlIGZvbGxvd2luZyBtZWFuaW5nCiAgICAxLiAkeF57Kn09MjckLCB0aGUgbW9udGggbnVtYmVyIHdlIHdhbnQgdG8gcHJlZGljdCBzYWxlcyBmaWd1cmVzIGZvcgogICAgMi4gJFxoYXR7eX1fe3heeyp9fSA9IFxoYXR7eX1fezI3fSQsIHRoZSBwcmVkaWN0ZWQgc2FsZXMgZm9yIG1vbnRoIDI3CiAgICAzLiAkXGFscGhhID0gMS1cZnJhY3s5MH17MTAwfT0wLjEkLCB0aGUgY29uZmlkZW5jZSBwYXJhbWV0ZXIgZnJvIHRoZSA5MCUgUHJlZGljdGlvbiBJbnRlcnZhbAogICAgNC4gJG49MjQkLCB0aGUgbnVtYmVyIG9mIGFjdHVhbCBkYXRhIHZhbHVlcyB3ZSBoYXZlCiAgICA2LiAkbi0yJCB0aGUgbnVtYmVyIG9mIF9fZGVncmVlcyBvZiBmcmVlZG9tIChkZilfXyB1c2VkIAogICAgNy4gJHRfe1xmcmFje1xhbHBoYX17Mn0sbi0yfSQsIHRoZSBjcml0aWNhbCAkdCQtdmFsdWUgZ2l2ZW4gdGhlc2UgcGFyYW1ldGVycwogICAgOC4gJE1TRSQgdGhlIG1lYW4gc3F1YXJlIGVycm9yIG9mIHRoZSBtb2RlbAogICAgOS4gJFxiYXJ7eH0kIHRoZSBtZWFuIG1vbnRoIG51bWJlciwgaW4gdGhpcyBjYXNlICRcYmFye3h9PVxmcmFjezF9ezI0fVxzdW1fe2k9MX1eezI0fWkgPSBcZnJhY3sxKzIrXGxkb3RzKzI0fXsyNH0kCiogVG8gZmluZCB0aGUgY3JpdGljYWwgdmFsdWUKCiR0X3tcZnJhY3tcYWxwaGF9ezJ9LG4tMn0kIHdlIHVzIHRoZSAKYGBge3J9CnRfc3RhciA9IGFicyhxdCgwLjA1LGRmPTIyKSkgIyBkZj0gTnVtYmVyIG9mIG1vbnRocy0yCmBgYAokeF4qJApgYGB7cn0KeF9zdGFyPTI3CmBgYAoKJHleKiQKCmBgYHtyfQp5X3N0YXI9Rm9yZWNhc3QxKDI3KQp5X3N0YXIKYGBgCk1TRQpgYGB7cn0KTVNFMQpgYGAKCiRcYmFye3h9JAoKYGBge3J9CnhfYmFyPW1lYW4oVGltZSkKYGBgCgokXFNpZ21hX3tpPTF9XntufSh4X2ktXGJhcnt4fSleMiQKYGBge3J9ClN1bTE9c3VtKChUaW1lLXhfYmFyKV4yKQpgYGAKCiMjIyBVcHBlciBib3VuZGFyeSBvZiBDSQoKYGBge3J9Cnlfc3Rhcit0X3N0YXIqc3FydChNU0UxKigxKzEvMjQrKHhfc3Rhci14X2JhcikvU3VtMSkpCmBgYAojIyMgTG93ZXIgYm91bmRhcnkgb2YgQ0kKCmBgYHtyfQp5X3N0YXItdF9zdGFyKnNxcnQoTVNFMSooMSsxLzI0Kyh4X3N0YXIteF9iYXIpL1N1bTEpKQpgYGAKCiMjIFRoZSA5MCUgUHJlZGljdGlvbiBJbnRlcnZhbApXZSBhcmUgOTAlIGNvbmZpZGVudCB0aGF0IHNhbGVzIGluIHRoZSAyN3RoIG1vbnRoIHdpbGwgYmUgYmV0d2VlbiAzNjIgYW5kIDQ2OSB1bml0cy4gCgoKCiMgRXhlcmNpc2UgMgpGaW5kIHRoZSA5MCUgcHJlZGljdGlvbiBpbnRlcnZhbCBmb3Igc2FsZXMgaW4gdGhlIDI3dGggbW9udGguCgojIEV4ZXJjaXNlIDMKClRoZSBjbG9zaW5nIHZhbHVlcyBvZiBBcHBsZSBJbmMuIChBQVBMKSBTdG9jayBvbiB0aGUgTkFTREFRIFN0b2NrIEV4Y2hhbmdlIGZyb20gOCBBdWd1c3QgMjAxNyB0byA4IE5vdmVtYmVyIDIwMTcgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19BcHBsZVF1b3RlcygzTSkuY3N2X18sIGF2YWlsYWJsZSBvbiBNb29kbGUuCihBdmFpbGFibGUgYXQgaHR0cDovL3d3dy5uYXNkYXEuY29tKQoKClVzaW5nIHRoaXMgZGF0YSBzZXQgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBJbXBvcnQgdGhlIGRhdGEgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgYW5kIGNhbGwgdGhlIGRhdGEgc3RydWN0dXJlIF9fQUFQTF9fCmBgYHtyfQpBQVBMPC1yZWFkLmNzdignQXBwbGVRdW90ZXMoM00pLmNzdicpCmBgYAoyLiBDcmVhdGUgX190d29fXyBkYXRhIHZlY3RvcnMgZnJvbSB0aGlzIGZpbGUsIG9uZSBmb3IgdGhlIF9fY2xvc2luZyB2YWx1ZV9fIGFuZCBvbmUgZm9yIHRoZSBfX2RheV9fCgpgYGB7cn0KCmBgYAozLiBDcmVhdGUgYSB0aW1lIHNlcmllcyBwbG90IGZvciB0aGlzIGRhdGEuCgo0LiBGcm9tIHRoaXMgZGF0YSBwbG90LCBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSB0cmVuZCBpbiB0aGUgY2xvc2luZyB2YWx1ZSBvZiBBcHBsZSBzdG9jayBvdmVyIHRoZSBwYXN0IDMgbW9udGhzLgoKNS4gVXNlIHRoZSBmdW5jdGlvbiBfX2xtKENsb3NpbmcgVmFsdWUgfiBEYXkpX18gdG8gY3JlYXRlIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoaXMgZGF0YS4KYGBge3J9CmxtKENsb3Npbmd+RGF5KQpgYGAKNi4gQ3JlYXRlIGEgbGluZWFyIG1vZGVsIHRvIGZvcmVjYXN0IHRoaXMgZGF0YS4KCjcuIENyZWF0ZSBhbiBfX1JfXyBmdW5jdGlvbiB0byByZXByZXNlbnQgdGhpcyBtb2RlbC4KCjguIEZpbmQgdGhlIE1BRCBhbmQgTVNFIG9mIHRoaXMgbW9kZWwKCjkuIEZpbmQgdGhlIDk1JSBwcmVkaWN0aW9uIGludGVydmFsIGZvciB0aGUgY2xvc2luZyBwcmljZSBvZiBBcHBsZSBTdG9jayBpbiAxMCBkYXlzIGZyb20gbm93LgoKCiMgRXhlcmNpc2UgNAoKVGhlIGNsb3NpbmcgdmFsdWVzIG9mIEdvb2dsZSBJbmMuIChHT09HTCkgU3RvY2sgb24gdGhlIE5BU0RBUSBTdG9jayBFeGNoYW5nZSBmcm9tIDggTm92ZW1iZXIgMjAxNiB0byA4IE5vdmVtYmVyIDIwMTcgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19Hb29nbGVRdW90ZXMoM00pLmNzdl9fLCBhdmFpbGFibGUgb24gTW9vZGxlIC4KKEF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm5hc2RhcS5jb20pLgoKClVzaW5nIHRoaXMgZGF0YSBzZXQgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBJbXBvcnQgdGhlIGRhdGEgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgYW5kIGNhbGwgdGhlIGRhdGEgc3RydWN0dXJlIF9fR09PR0xfXwpgYGB7cn0KR09PR0w8LXJlYWQuY3N2KCdHb29nbGVRdW90ZXMoMVkpLmNzdicpCmBgYAoyLiBDcmVhdGUgX190d29fXyBkYXRhIHZlY3RvcnMgZnJvbSB0aGlzIGZpbGUsIG9uZSBmb3IgdGhlIF9fdHJhZGluZyB2YWx1ZV9fIGFuZCBvbmUgZm9yIHRoZSBfX2RheV9fCgozLiBDcmVhdGUgYSB0aW1lIHNlcmllcyBwbG90IGZvciB0aGlzIGRhdGEuCgo0LiBGcm9tIHRoaXMgZGF0YSBwbG90LCBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSB0cmVuZCBpbiB0aGUgY2xvc2luZyB2YWx1ZSBvZiBHb29nbGUgc3RvY2sgb3ZlciB0aGUgcGFzdCB5ZWFyLgoKNS4gVXNlIHRoZSBmdW5jdGlvbiBfX2xtKFRyYWRpbmcgVmFsdWUgfiBEYXkpX18gdG8gY3JlYXRlIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoaXMgZGF0YS4KYGBge3J9CgpgYGAKNi4gQ3JlYXRlIGEgbGluZWFyIG1vZGVsIHRvIGZvcmVjYXN0IHRoaXMgZGF0YS4KCjcuIENyZWF0ZSBhbiBfX1JfXyBmdW5jdGlvbiB0byByZXByZXNlbnQgdGhpcyBtb2RlbC4KCjguIEZpbmQgdGhlIF9fTUFEX18gYW5kIF9fTVNFX18gb2YgdGhpcyBtb2RlbAoKOS4gRmluZCB0aGUgOTAlIGFuZCA5OSUgcHJlZGljdGlvbiBpbnRlcnZhbHMgZm9yIHRoZSAgdHJhZGluZyB2b2x1bWUgb2YgR29vZ2xlIFN0b2NrIGluIDEwIGRheXMgZnJvbSBub3cuCgojIEV4ZXJjaXNlIDUKClRoZSAlIEdyb3d0aCBpbiBHRFAgb2YgQ2hpbiwgdGhlIFVLLCB0aGUgVVMsIElyZWxhbmQsIHRoZSBFVSwgdGhlIE9FQ0QgYW5kIHRoZSBXb3JsZCwgZm9yIHRoZSB5ZWFycyAxOTYxLTIwMTYgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19SZWdpb25hbEdEUEdyb3d0aCgxOTYxLTIwMTYpLmNzdl9fLiBJbXBvcnQgdGhpcyBkYXRhIGZpbGUgaW50byBfX1JfXyBhbmQgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zLiAKKEF2YWlsYWJsZSBhdCBodHRwOi8vd3d3LndvcmxkYmFuay5vcmcpCgoKMS4gQ3JlYXRlIGEgZGF0YSB2ZWN0b3IgZm9yIHRoZSBfX1llYXJfXyAgYSBzZXBhcmF0ZSB2ZWN0b3IgZm9yIHRoZSBHRFAgZ3Jvd3RoIG9mIGVhY2ggY291bnRyeSBpbiB0aGUgZGF0YSBmaWxlLgoKMi4gVXNlIHRoZSBmdW5jdGlvbiBfX3BhcihtZnJvdz1jKEEsQikpX18gdG8gY3JlYXRlIGEgY29sbGVjdGlvbiBvZiB0aW1lLXNlcmllcyBwbG90cyBpbiBfX0E9MV9fIHJvdyBhbmQgX19CPTJfXyBjb2x1bW5zIGZvciB0aGUgR0RQIGdyb3d0aCBvZiBDaGluYSBhbmQgdGhlIFVTCiBUbyBpbGx1c3RyYXRlIGhvdyB0aGlzIGZ1bmN0aW9uIHdvcmtzLCB0aGUgdGltZS1zZXJpZXMgcGxvdCBmcm9tIF9fRXhhbXBsZSAxX18gaXMgcGxvdHRlZCBpbiBfXzFfXyByb3cgYW5kIF9fMl9fIGNvbHVtbnMgIApgYGB7cn0KcGFyKG1mcm93PWMoMSwyKSkKcGxvdChUaW1lLE1TLHBjaD0xNSxjb2w9InJlZCIseWxhYj0iTW9udGhseSBTYWxlcyBGaWd1cmVzIiwgeGxhYj0iTW9udGgiLG1haW49Ik1vbnRobHkgU2FsZXMgRmlndXJlcyBvZiBQaG9uZSBNb2RlbCBNIikKbGluZXMoVGltZSxNUykKcGxvdChUaW1lLE1TLHBjaD0xNSxjb2w9InJlZCIseWxhYj0iTW9udGhseSBTYWxlcyBGaWd1cmVzIiwgeGxhYj0iTW9udGgiLG1haW49Ik1vbnRobHkgU2FsZXMgRmlndXJlcyBvZiBQaG9uZSBNb2RlbCBNIikKbGluZXMoVGltZSxNUykKYGBgCjMuIFVzZSB0aGUgZnVuY3Rpb24gX19wYXIobWZyb3c9YyhBLEIpKV9fIHRvIGNyZWF0ZSBhIGNvbGxlY3Rpb24gb2YgdGltZS1zZXJpZXMgcGxvdHMgaW4gX19BPTNfXyByb3cgYW5kIF9fQj0xX18gY29sdW1ucyBmb3IgdGhlIEdEUCBncm93dGggb2YgQ2hpbmEgYW5kIHRoZSBVUywgdGhlIFVLCgogCjQuIFVzZSB0aGUgZnVuY3Rpb24gX19wYXIobWZyb3c9YyhBLEIpKV9fIHRvIGNyZWF0ZSBhIGNvbGxlY3Rpb24gb2YgdGltZS1zZXJpZXMgcGxvdHMgaW4gX19BPTJfXyByb3cgYW5kIF9fQj0yX18gY29sdW1ucyBmb3IgdGhlIEdEUCBncm93dGggb2YgdGhlIEVVLCB0aGUgVVMsIHRoZSBPRUNEIGFuZCB0aGUgV29ybGQuCgo1LiBJcyB0aGVyZSBhbnkgYXBwYXJlbnQgdHJlbmQgaW4gZWNvbm9taWMgZ3Jvd3RoIG9ic2VydmFibGUgZnJvbSB0aGVzZSB0aW1lLXNlcmllcy4KCjYuIEZyb20gdGhlIHRpbWUtc2VyaWVzIHBsb3RzLCB3aGljaCByZWdpb24gaGFzIHNob3duIHRoZSBtb3N0IGNvbnNpc3RlbnQgZWNvbm9taWMgZ3Jvd3RoIGJldHdlZW4gMTk2MSBhbmQgMjAxNi4K