library('fpp3')
library('tsibble')
library('ggplot2')
library('USgas')
library('readr')
library('zoo')

INSTRUCTIONS

Please submit exercises 2.1, 2.2, 2.3, 2.4, 2.5 and 2.8 from the Hyndman online Forecasting book. Please submit both your Rpubs link as well as attach the .pdf file with your code.

2.1

  1. Explore the following four time series: Bricks from aus_production, Lynx from pelt, Close from gafa_stock, Demand from vic_elec.

    1. Use ? (or help()) to find out about the data in each series.
    2. What is the time interval of each series?
    3. Use autoplot() to produce a time plot of each series.
    4. For the last plot, modify the axis labels and title.
data("aus_production")
data("pelt")
data("gafa_stock")
data("vic_elec")

Bricks

i

Details Quarterly estimates of selected indicators of manufacturing production in Australia.

Bricks: Clay brick production in millions of bricks.

ii

Quarterly

aus_production%>%
  select(Bricks)

iii

autoplot(aus_production,Bricks) +
  labs(title = "Time Plot of Bricks Series",
       x = "Quarterly",
       y = "Bricks Production count")

Lynx

i

pelt is an annual tsibble with two values:

Hare: The number of Snowshoe Hare pelts traded. Lynx: The number of Canadian Lynx pelts traded.

ii

pelt %>%
  select(Lynx)

iii


autoplot(pelt,Lynx) +
  labs(title = "Time Plot of lynx Series (1845 to1935)",
       x = "Annually",
       y = "Lynx pelts traded Count")

Close

i

Details gafa_stock is a tsibble containing data on irregular trading days:

Open: The opening price for the stock. High: The stock’s highest trading price. Low: The stock’s lowest trading price. Close: The closing price for the stock. Adj_Close: The adjusted closing price for the stock. Volume: The amount of stock traded. Each stock is uniquely identified by one key:

Symbol: The ticker symbol for the stock.

ii

gafa_stock%>%
  select(Close)

The gafa_stock is daily data

iii


autoplot(gafa_stock,Close) +
  labs(title = "Time Plot of Closing Stock Price ('Yahoo Finance' 2014-2018)",
       x = "Daily",
       y = "Closing price")

Demand

i

Description*

vic_elec is a half-hourly tsibble with three values:

Demand: Total electricity demand in MWh. Temperature: Temperature of Melbourne (BOM site 086071). Holiday: Indicator for if that day is a public holiday.

ii


vic_elec %>%
  select(Demand)
NA

iii & vi

autoplot(vic_elec,Demand) +
  labs(title = "Time Plot of Electricity Demand Victoria, Australia",
       x = "Time(30min Intervals",
       y = "Demand in MWh")

2.2

Use filter() to find what days corresponded to the peak closing price for each of the four stocks in gafa_stock.

colnames(gafa_stock)
[1] "Symbol"    "Date"      "Open"      "High"      "Low"       "Close"     "Adj_Close" "Volume"   

 gafa_stock %>%
  group_by(Symbol) %>%
  filter(Close == max(Close))
NA

2.3

Download the file tute1.csv from the book website, open it in Excel (or some other spreadsheet application), and review its contents. You should find four columns of information. Columns B through D each contain a quarterly series, labelled Sales, AdBudget and GDP. Sales contains the quarterly sales for a small company over the period 1981-2005. AdBudget is the advertising budget and GDP is the gross domestic product. All series have been adjusted for inflation.

a.

You can read the data into R with the following script:


df_tute1 <- readr::read_csv(tute1_csv)
head(df_tute1,20)
NA

b.

Convert the data to time series

mytimeseries <- df_tute1 |>
  mutate(Quarter = yearquarter(Quarter)) |>
  as_tsibble(index = Quarter)

c.

Construct time series plots of each of the three series

mytimeseries |>
  pivot_longer(-Quarter) |>
  ggplot(aes(x = Quarter, y = value, colour = name)) +
  geom_line() +
  facet_grid(name ~ ., scales = "free_y")

mytimeseries %>%
  pivot_longer(-Quarter)%>%
  ggplot(aes(x = Quarter, y = value, colour = name)) +
  geom_line() #+

  # facet_grid(name ~ ., scales = "free_y")

The plot is encompassed in one plot without the facet_grid() function.

2.4

The USgas package contains data on the demand for natural gas in the US.

  1. Install the USgas package.
  2. Create a tsibble from us_total with year as the index and state as the key.
  3. Plot the annual natural gas consumption by state for the New England area (comprising the states of Maine, Vermont, New Hampshire, Massachusetts, Connecticut and Rhode Island).

i

str(USgas::us_total)
'data.frame':   1266 obs. of  3 variables:
 $ year : int  1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 ...
 $ state: chr  "Alabama" "Alabama" "Alabama" "Alabama" ...
 $ y    : int  324158 329134 337270 353614 332693 379343 350345 382367 353156 391093 ...

ii

Example

Forecasting Principles & Practice: 2.1 tsibble objects

Template

    mydata <- tsibble(
        year = 2015:2019,
        y=c(123,39,78,52,110),
        index = year
    )
    mydata

mydata <- tsibble(
  state = us_total$state,
  year = us_total$year,
  value = us_total$y,
  index = year,
  key = state
)%>%
  filter(state %in% c("Maine", "Vermont", "New Hampshire", "Massachusetts", "Connecticut", "Rhode Island"))

iii


ggplot(mydata, aes(x = year, y = value, color = state)) +
  geom_line() +
  labs(
    title = "Annual Natural Gas Consumption for New England Area (by state)",
    x = "Year",
    y = "Natural Gas Consumption",
    color = "State"
  )

2.5

a.

Download tourism.xlsx from the book website and read it into R using readxl::read_excel().

PATH<-"C:/Users/Lenny/Documents/GitableGabe/Data624_Data/"
tourism_str <- paste(PATH,"tourism.xlsx", sep = "")
df_tourism <- readxl::read_excel(tourism_str)
rm(tourism_str)
tourism

b.

Create a tsibble which is identical to the tourism tsibble from the tsibble package.

str(df_tourism)
tibble [24,320 × 5] (S3: tbl_df/tbl/data.frame)
 $ Quarter: chr [1:24320] "1998-01-01" "1998-04-01" "1998-07-01" "1998-10-01" ...
 $ Region : chr [1:24320] "Adelaide" "Adelaide" "Adelaide" "Adelaide" ...
 $ State  : chr [1:24320] "South Australia" "South Australia" "South Australia" "South Australia" ...
 $ Purpose: chr [1:24320] "Business" "Business" "Business" "Business" ...
 $ Trips  : num [1:24320] 135 110 166 127 137 ...

Example

Forecasting Principles & Practice: 2.1 tsibble objects

Template

  prison<- read::read_csv("data/prison_population.csv") %>%
            mutate(Quarter = yearquarter(date)) %>%
              select(-date) %>%
              as_tsibble(
              index = Quarter,
              key=c(state,gender,legal,indigenous)
              )
tibble_tourism <- df_tourism %>%
  mutate(Quarter = yearquarter(Quarter)) %>%
  as_tsibble(index=Quarter,
             key = c("Region", "State", "Purpose"))

tibble_tourism
NA

c.

Find what combination of Region and Purpose had the maximum number of overnight trips on average.


tibble_tourism %>% 
  group_by(Region,Purpose)%>%
  summarize(TripsAvg = mean(Trips))%>%
  filter(TripsAvg == max(TripsAvg))%>%
  arrange(desc(TripsAvg))
NA

d.

Create a new tsibble which combines the Purposes and Regions, and just has total trips by State.

tibble_tourism_v2 <- tibble_tourism %>%
  group_by(State)%>%
  summarize(Total=sum(Trips))

tibble_tourism_v2

2.8

Use the following graphics functions: autoplot(), gg_season(), gg_subseries(), gg_lag(), ACF() and explore features from the following time series: “Total Private” Employed from us_employment, Bricks from aus_production, Hare from pelt, “H02” Cost from PBS, and Barrels from us_gasoline.

  1. Can you spot any seasonality, cyclicity and trend?
  2. What do you learn about the series?
  3. What can you say about the seasonal patterns?
  4. Can you identify any unusual years?

Total Private

Example

  vic_elec |> gg_season(Demand, period = "day") +
    theme(legend.position = "none") +
    labs(y="MWh", title="Electricity demand: Victoria")
us_employment
us_employment%>%
  filter(Title=="Total Private")%>%
  autoplot(Employed,period="month") 
Warning: Ignoring unknown parameters: `period`

us_employment%>%
  filter(Title=="Total Private")%>%
  gg_season(Employed, polar = FALSE)


us_employment%>%
  filter(Title=="Total Private")%>%
  gg_season(Employed, polar = TRUE) 


us_employment%>%
  filter(Title=="Total Private")%>%
  gg_subseries(Employed)


us_employment%>%
  filter(Title=="Total Private")%>%
  gg_lag(Employed)

us_employment%>%
  filter(Title=="Total Private")%>%
  ACF(us_employment$Employed)%>%
  autoplot()

i

There is a clear upwards trend in small increments for the data.

ii

Growth has been consistent without any extreme spike or drop.

iii

No Seasonality is noted indicating there is not particular season with an affect on employment positive or negative.

iv

A small dip around 2010 which I believe aligns with the recession.

Bricks

aus_production%>%
  select(Bricks)%>%
  autoplot(period="quarter") 
Plot variable not specified, automatically selected `.vars = Bricks`Warning: Ignoring unknown parameters: `period`

aus_production%>%
  select(Bricks)%>%
  gg_season( polar = FALSE)
Plot variable not specified, automatically selected `y = Bricks`

aus_production%>%
  select(Bricks)%>%
  gg_season( polar = TRUE) 
Plot variable not specified, automatically selected `y = Bricks`

 
aus_production%>%
  select(Bricks)%>%
  gg_subseries()
Plot variable not specified, automatically selected `y = Bricks`

aus_production%>%
  select(Bricks)%>%
  gg_lag()
Plot variable not specified, automatically selected `y = Bricks`Warning: Removed 20 rows containing missing values (gg_lag).

aus_production%>%
  select(Bricks)%>%
  ACF(aus_production$Bricks)%>%
  autoplot()

i

There is lots of cyclicity with frequent spikes and dips, but it does not appear to be consistent to a time period.There is a positive upward trend in the long term.

ii

The data being broken down to Quarters my influence how well we can assess the potential seasonality. As is, there does seem to be one.

iii

There seems to be some seasonality as far as Q1 and Q3 is concerned.

iv

The early 1980s has a significant dip so I would be curious to understand what may have cause this.

Hare

pelt%>%
  select(Hare)%>%
  autoplot(period="year") 
Plot variable not specified, automatically selected `.vars = Hare`Warning: Ignoring unknown parameters: `period`

#Not possible
# pelt%>%
#   select(Hare)%>%
#   gg_season( polar = FALSE)
# 
# pelt%>%
#   select(Hare)%>%
#   gg_season( polar = TRUE) 
 
pelt%>%
  select(Hare)%>%
  gg_subseries()
Plot variable not specified, automatically selected `y = Hare`

pelt%>%
  select(Hare)%>%
  gg_lag()
Plot variable not specified, automatically selected `y = Hare`

pelt%>%
  select(Hare)%>%
  ACF()%>%
  autoplot()
Response variable not specified, automatically selected `var = Hare`

i

The data is definitely cyclical but its not possible to teal seasonality since its at a annual basis.

ii

The data does not trend and varies a great deal. But seems to have a pattern at a 5 year interval.

iii

Again no seasonality

iv

Im curious what caused the peak in the early 1860s

Cost

PBS%>%
  filter(ATC2=="H02")%>%
  autoplot(Cost) 


PBS %>% 
  filter(ATC2 == "H02") %>%
  gg_season(Cost, polar = FALSE)


PBS %>% 
  filter(ATC2 == "H02") %>%
  gg_subseries(Cost)


# PBS %>% 
#   filter(ATC2 == "H02") %>%
#   gg_lag(Cost)
PBS %>% 
  filter(ATC2 == "H02") %>%
  ACF(Cost)%>%
  autoplot()

i

The data is hard to interpret but it appears to trend upwards with cyclicity and seasonality. ### ii

the data is very volatile but spikes mainly end of year it appears.

iii

The seasonality is at the end of the year.

iv

No year stands out, outside of the latest year having the highest cost.

Barrels

us_gasoline%>%
  select(Barrels)%>%
  autoplot() 
Plot variable not specified, automatically selected `.vars = Barrels`

us_gasoline%>%
  select(Barrels)%>%
  gg_season(polar = FALSE)
Plot variable not specified, automatically selected `y = Barrels`

us_gasoline%>%
  select(Barrels)%>%
  gg_season( polar = TRUE) 
Plot variable not specified, automatically selected `y = Barrels`

us_gasoline%>%
  select(Barrels)%>%
  gg_subseries()
Plot variable not specified, automatically selected `y = Barrels`

us_gasoline%>%
  select(Barrels)%>%
  gg_lag()
Plot variable not specified, automatically selected `y = Barrels`

us_gasoline %>% 
  select(Barrels) %>%
  ACF()%>%
  autoplot()
Response variable not specified, automatically selected `var = Barrels`

i

Primarily an upward trend with a dip near the most recent year

ii

Its possible the barrels value is impacted by supply.

iii

There does not appear to be seasonality of cyclicity

iv

The most recent dip is interesting and I wonder if its just a data collection issue.

LS0tDQp0aXRsZTogJ0RBVEEgNjI0OiBQUkVESUNUSVZFIEFOQUxZVElDUyBIVzEnDQphdXRob3I6ICJHYWJyaWVsIENhbXBvcyINCmRhdGU6ICJMYXN0IGVkaXRlZCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBnZW9tZXRyeTogbGVmdD0wLjVjbSxyaWdodD0wLjVjbSx0b3A9MWNtLGJvdHRvbT0yY20NCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50Og0KICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KdXJsY29sb3I6IGJsdWUNCi0tLQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoJ2ZwcDMnKQ0KbGlicmFyeSgndHNpYmJsZScpDQpsaWJyYXJ5KCdnZ3Bsb3QyJykNCmxpYnJhcnkoJ1VTZ2FzJykNCmxpYnJhcnkoJ3JlYWRyJykNCmxpYnJhcnkoJ3pvbycpDQpgYGANCg0KDQojIElOU1RSVUNUSU9OUw0KDQpQbGVhc2Ugc3VibWl0IGV4ZXJjaXNlcyAyLjEsIDIuMiwgMi4zLCAyLjQsIDIuNSBhbmQgMi44IGZyb20gdGhlIEh5bmRtYW4gb25saW5lIEZvcmVjYXN0aW5nIGJvb2suICBQbGVhc2Ugc3VibWl0IGJvdGggeW91ciBScHVicyBsaW5rIGFzIHdlbGwgYXMgYXR0YWNoIHRoZSAucGRmIGZpbGUgd2l0aCB5b3VyIGNvZGUuDQoNCiMgMi4xDQoNCjEuICBFeHBsb3JlIHRoZSBmb2xsb3dpbmcgZm91ciB0aW1lIHNlcmllczogYEJyaWNrc2AgZnJvbSBgYXVzX3Byb2R1Y3Rpb25gLCBgTHlueGAgZnJvbSBgcGVsdGAsIGBDbG9zZWAgZnJvbSBgZ2FmYV9zdG9ja2AsIGBEZW1hbmRgIGZyb20gYHZpY19lbGVjYC4NCg0KICAgIGkuIFVzZSA/IChvciBoZWxwKCkpIHRvIGZpbmQgb3V0IGFib3V0IHRoZSBkYXRhIGluIGVhY2ggc2VyaWVzLg0KICAgIGlpLiBXaGF0IGlzIHRoZSB0aW1lIGludGVydmFsIG9mIGVhY2ggc2VyaWVzPw0KICAgIGlpaS4gVXNlIGF1dG9wbG90KCkgdG8gcHJvZHVjZSBhIHRpbWUgcGxvdCBvZiBlYWNoIHNlcmllcy4NCiAgICBpdi4gRm9yIHRoZSBsYXN0IHBsb3QsIG1vZGlmeSB0aGUgYXhpcyBsYWJlbHMgYW5kIHRpdGxlLg0KICAgIA0KICAgIA0KYGBge3J9DQpkYXRhKCJhdXNfcHJvZHVjdGlvbiIpDQpkYXRhKCJwZWx0IikNCmRhdGEoImdhZmFfc3RvY2siKQ0KZGF0YSgidmljX2VsZWMiKQ0KYGBgDQoNCiMjIEJyaWNrcw0KDQojIyMgaQ0KDQoqRGV0YWlscyoNClF1YXJ0ZXJseSBlc3RpbWF0ZXMgb2Ygc2VsZWN0ZWQgaW5kaWNhdG9ycyBvZiBtYW51ZmFjdHVyaW5nIHByb2R1Y3Rpb24gaW4gQXVzdHJhbGlhLg0KDQoqQnJpY2tzOioJQ2xheSBicmljayBwcm9kdWN0aW9uIGluIG1pbGxpb25zIG9mIGJyaWNrcy4NCg0KIyMjIGlpDQoNClF1YXJ0ZXJseQ0KDQpgYGB7cn0NCmF1c19wcm9kdWN0aW9uJT4lDQogIHNlbGVjdChCcmlja3MpDQpgYGANCiMjIyBpaWkNCg0KYGBge3J9DQphdXRvcGxvdChhdXNfcHJvZHVjdGlvbixCcmlja3MpICsNCiAgbGFicyh0aXRsZSA9ICJUaW1lIFBsb3Qgb2YgQnJpY2tzIFNlcmllcyIsDQogICAgICAgeCA9ICJRdWFydGVybHkiLA0KICAgICAgIHkgPSAiQnJpY2tzIFByb2R1Y3Rpb24gY291bnQiKQ0KYGBgDQoNCiMjIEx5bngNCg0KIyMjIGkNCg0KcGVsdCBpcyBhbiBhbm51YWwgdHNpYmJsZSB3aXRoIHR3byB2YWx1ZXM6DQoNCkhhcmU6CVRoZSBudW1iZXIgb2YgU25vd3Nob2UgSGFyZSBwZWx0cyB0cmFkZWQuDQpMeW54OglUaGUgbnVtYmVyIG9mIENhbmFkaWFuIEx5bnggcGVsdHMgdHJhZGVkLg0KDQojIyMgaWkNCg0KYGBge3J9DQpwZWx0ICU+JQ0KICBzZWxlY3QoTHlueCkNCmBgYA0KDQojIyMgaWlpDQoNCmBgYHtyfQ0KDQphdXRvcGxvdChwZWx0LEx5bngpICsNCiAgbGFicyh0aXRsZSA9ICJUaW1lIFBsb3Qgb2YgbHlueCBTZXJpZXMgKDE4NDUgdG8xOTM1KSIsDQogICAgICAgeCA9ICJBbm51YWxseSIsDQogICAgICAgeSA9ICJMeW54IHBlbHRzIHRyYWRlZCBDb3VudCIpDQoNCmBgYA0KDQojIyBDbG9zZQ0KDQojIyMgaQ0KDQpEZXRhaWxzDQpnYWZhX3N0b2NrIGlzIGEgdHNpYmJsZSBjb250YWluaW5nIGRhdGEgb24gaXJyZWd1bGFyIHRyYWRpbmcgZGF5czoNCg0KT3BlbjoJVGhlIG9wZW5pbmcgcHJpY2UgZm9yIHRoZSBzdG9jay4NCkhpZ2g6CVRoZSBzdG9jaydzIGhpZ2hlc3QgdHJhZGluZyBwcmljZS4NCkxvdzoJVGhlIHN0b2NrJ3MgbG93ZXN0IHRyYWRpbmcgcHJpY2UuDQpDbG9zZToJVGhlIGNsb3NpbmcgcHJpY2UgZm9yIHRoZSBzdG9jay4NCkFkal9DbG9zZToJVGhlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2UgZm9yIHRoZSBzdG9jay4NClZvbHVtZToJVGhlIGFtb3VudCBvZiBzdG9jayB0cmFkZWQuDQpFYWNoIHN0b2NrIGlzIHVuaXF1ZWx5IGlkZW50aWZpZWQgYnkgb25lIGtleToNCg0KU3ltYm9sOglUaGUgdGlja2VyIHN5bWJvbCBmb3IgdGhlIHN0b2NrLg0KDQojIyMgaWkNCg0KYGBge3J9DQpnYWZhX3N0b2NrJT4lDQogIHNlbGVjdChDbG9zZSkNCmBgYA0KDQpUaGUgYGdhZmFfc3RvY2tgIGlzIGRhaWx5IGRhdGENCg0KIyMjIGlpaQ0KDQpgYGB7cn0NCg0KYXV0b3Bsb3QoZ2FmYV9zdG9jayxDbG9zZSkgKw0KICBsYWJzKHRpdGxlID0gIlRpbWUgUGxvdCBvZiBDbG9zaW5nIFN0b2NrIFByaWNlICgnWWFob28gRmluYW5jZScgMjAxNC0yMDE4KSIsDQogICAgICAgeCA9ICJEYWlseSIsDQogICAgICAgeSA9ICJDbG9zaW5nIHByaWNlIikNCg0KYGBgDQoNCiMjIERlbWFuZA0KDQojIyMgaQ0KDQoqKkRlc2NyaXB0aW9uKioqDQoNCmB2aWNfZWxlY2AgaXMgYSBoYWxmLWhvdXJseSBgdHNpYmJsZWAgd2l0aCB0aHJlZSB2YWx1ZXM6DQoNCkRlbWFuZDoJVG90YWwgZWxlY3RyaWNpdHkgZGVtYW5kIGluIE1XaC4NClRlbXBlcmF0dXJlOglUZW1wZXJhdHVyZSBvZiBNZWxib3VybmUgKEJPTSBzaXRlIDA4NjA3MSkuDQpIb2xpZGF5OglJbmRpY2F0b3IgZm9yIGlmIHRoYXQgZGF5IGlzIGEgcHVibGljIGhvbGlkYXkuDQoNCiMjIyBpaQ0KDQpgYGB7cn0NCg0KdmljX2VsZWMgJT4lDQogIHNlbGVjdChEZW1hbmQpDQoNCmBgYA0KDQoNCiMjIyBpaWkgJiB2aQ0KDQpgYGB7cn0NCmF1dG9wbG90KHZpY19lbGVjLERlbWFuZCkgKw0KICBsYWJzKHRpdGxlID0gIlRpbWUgUGxvdCBvZiBFbGVjdHJpY2l0eSBEZW1hbmQgVmljdG9yaWEsIEF1c3RyYWxpYSIsDQogICAgICAgeCA9ICJUaW1lKDMwbWluIEludGVydmFscyIsDQogICAgICAgeSA9ICJEZW1hbmQgaW4gTVdoIikNCmBgYA0KDQojIDIuMg0KDQpVc2UgZmlsdGVyKCkgdG8gZmluZCB3aGF0IGRheXMgY29ycmVzcG9uZGVkIHRvIHRoZSBwZWFrIGNsb3NpbmcgcHJpY2UgZm9yIGVhY2ggb2YgdGhlIGZvdXIgc3RvY2tzIGluIGdhZmFfc3RvY2suDQoNCg0KYGBge3J9DQpjb2xuYW1lcyhnYWZhX3N0b2NrKQ0KYGBgDQoNCmBgYHtyfQ0KDQogZ2FmYV9zdG9jayAlPiUNCiAgZ3JvdXBfYnkoU3ltYm9sKSAlPiUNCiAgZmlsdGVyKENsb3NlID09IG1heChDbG9zZSkpDQoNCmBgYA0KDQoNCiMgMi4zDQoNCkRvd25sb2FkIHRoZSBmaWxlIGB0dXRlMS5jc3ZgIGZyb20gdGhlIFtib29rIHdlYnNpdGVdKGh0dHBzOi8vYml0Lmx5L2ZwcHR1dGUxKSwgb3BlbiBpdCBpbiBFeGNlbCAob3Igc29tZSBvdGhlciBzcHJlYWRzaGVldCBhcHBsaWNhdGlvbiksIGFuZCByZXZpZXcgaXRzIGNvbnRlbnRzLiBZb3Ugc2hvdWxkIGZpbmQgZm91ciBjb2x1bW5zIG9mIGluZm9ybWF0aW9uLiBDb2x1bW5zIEIgdGhyb3VnaCBEIGVhY2ggY29udGFpbiBhIHF1YXJ0ZXJseSBzZXJpZXMsIGxhYmVsbGVkIFNhbGVzLCBBZEJ1ZGdldCBhbmQgR0RQLiBTYWxlcyBjb250YWlucyB0aGUgcXVhcnRlcmx5IHNhbGVzIGZvciBhIHNtYWxsIGNvbXBhbnkgb3ZlciB0aGUgcGVyaW9kIDE5ODEtMjAwNS4gQWRCdWRnZXQgaXMgdGhlIGFkdmVydGlzaW5nIGJ1ZGdldCBhbmQgR0RQIGlzIHRoZSBncm9zcyBkb21lc3RpYyBwcm9kdWN0LiBBbGwgc2VyaWVzIGhhdmUgYmVlbiBhZGp1c3RlZCBmb3IgaW5mbGF0aW9uLg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnR1dGUxX2NzdjwtImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9HaXRhYmxlR2FiZS9EYXRhNjI0X0RhdGEvbWFpbi90dXRlMS5jc3YiDQpgYGANCg0KIyMgYS4NCg0KWW91IGNhbiByZWFkIHRoZSBkYXRhIGludG8gUiB3aXRoIHRoZSBmb2xsb3dpbmcgc2NyaXB0Og0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCg0KZGZfdHV0ZTEgPC0gcmVhZHI6OnJlYWRfY3N2KHR1dGUxX2NzdikNCmhlYWQoZGZfdHV0ZTEsMjApDQoNCmBgYA0KDQojIyBiLg0KDQpDb252ZXJ0IHRoZSBkYXRhIHRvIHRpbWUgc2VyaWVzDQoNCmBgYHtyfQ0KbXl0aW1lc2VyaWVzIDwtIGRmX3R1dGUxIHw+DQogIG11dGF0ZShRdWFydGVyID0geWVhcnF1YXJ0ZXIoUXVhcnRlcikpIHw+DQogIGFzX3RzaWJibGUoaW5kZXggPSBRdWFydGVyKQ0KYGBgDQoNCiMjIGMuDQoNCkNvbnN0cnVjdCB0aW1lIHNlcmllcyBwbG90cyBvZiBlYWNoIG9mIHRoZSB0aHJlZSBzZXJpZXMNCg0KYGBge3J9DQpteXRpbWVzZXJpZXMgfD4NCiAgcGl2b3RfbG9uZ2VyKC1RdWFydGVyKSB8Pg0KICBnZ3Bsb3QoYWVzKHggPSBRdWFydGVyLCB5ID0gdmFsdWUsIGNvbG91ciA9IG5hbWUpKSArDQogIGdlb21fbGluZSgpICsNCiAgZmFjZXRfZ3JpZChuYW1lIH4gLiwgc2NhbGVzID0gImZyZWVfeSIpDQpgYGANCg0KYGBge3J9DQpteXRpbWVzZXJpZXMgJT4lDQogIHBpdm90X2xvbmdlcigtUXVhcnRlciklPiUNCiAgZ2dwbG90KGFlcyh4ID0gUXVhcnRlciwgeSA9IHZhbHVlLCBjb2xvdXIgPSBuYW1lKSkgKw0KICBnZW9tX2xpbmUoKSAjKw0KICAjIGZhY2V0X2dyaWQobmFtZSB+IC4sIHNjYWxlcyA9ICJmcmVlX3kiKQ0KYGBgDQoNClRoZSBwbG90IGlzIGVuY29tcGFzc2VkIGluIG9uZSBwbG90IHdpdGhvdXQgdGhlIGBmYWNldF9ncmlkKClgIGZ1bmN0aW9uLg0KDQojIDIuNA0KDQpUaGUgYFVTZ2FzYCBwYWNrYWdlIGNvbnRhaW5zIGRhdGEgb24gdGhlIGRlbWFuZCBmb3IgbmF0dXJhbCBnYXMgaW4gdGhlIFVTLg0KDQppLiBJbnN0YWxsIHRoZSBgVVNnYXNgIHBhY2thZ2UuDQppaS4gQ3JlYXRlIGEgYHRzaWJibGVgIGZyb20gYHVzX3RvdGFsYCB3aXRoIHllYXIgYXMgdGhlIGluZGV4IGFuZCBzdGF0ZSBhcyB0aGUga2V5Lg0KaWlpLiBQbG90IHRoZSBhbm51YWwgbmF0dXJhbCBnYXMgY29uc3VtcHRpb24gYnkgc3RhdGUgZm9yIHRoZSBOZXcgRW5nbGFuZCBhcmVhIChjb21wcmlzaW5nIHRoZSBzdGF0ZXMgb2YgTWFpbmUsIFZlcm1vbnQsIE5ldyBIYW1wc2hpcmUsIE1hc3NhY2h1c2V0dHMsIENvbm5lY3RpY3V0IGFuZCBSaG9kZSBJc2xhbmQpLg0KDQojIyBpDQpgYGB7cn0NCnN0cihVU2dhczo6dXNfdG90YWwpDQpgYGANCg0KIyMgaWkNCioqRXhhbXBsZSoqDQoNCltGb3JlY2FzdGluZyBQcmluY2lwbGVzICYgUHJhY3RpY2U6IDIuMSB0c2liYmxlIG9iamVjdHNdKGh0dHBzOi8veW91dHUuYmUvRXdqdkEyT2NkSHM/c2k9eXRVaENyc3dfSWhQTzFvWSZ0PTMxNikNCg0KKlRlbXBsYXRlKg0KICAgICAgICANCiAgICAgICAgbXlkYXRhIDwtIHRzaWJibGUoDQogICAgICAgICAgICB5ZWFyID0gMjAxNToyMDE5LA0KICAgICAgICAgICAgeT1jKDEyMywzOSw3OCw1MiwxMTApLA0KICAgICAgICAgICAgaW5kZXggPSB5ZWFyDQogICAgICAgICkNCiAgICAgICAgbXlkYXRhDQoNCmBgYHtyfQ0KDQpteWRhdGEgPC0gdHNpYmJsZSgNCiAgc3RhdGUgPSB1c190b3RhbCRzdGF0ZSwNCiAgeWVhciA9IHVzX3RvdGFsJHllYXIsDQogIHZhbHVlID0gdXNfdG90YWwkeSwNCiAgaW5kZXggPSB5ZWFyLA0KICBrZXkgPSBzdGF0ZQ0KKSU+JQ0KICBmaWx0ZXIoc3RhdGUgJWluJSBjKCJNYWluZSIsICJWZXJtb250IiwgIk5ldyBIYW1wc2hpcmUiLCAiTWFzc2FjaHVzZXR0cyIsICJDb25uZWN0aWN1dCIsICJSaG9kZSBJc2xhbmQiKSkNCg0KYGBgDQoNCiMjIGlpaQ0KDQpgYGB7cn0NCg0KZ2dwbG90KG15ZGF0YSwgYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWUsIGNvbG9yID0gc3RhdGUpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJBbm51YWwgTmF0dXJhbCBHYXMgQ29uc3VtcHRpb24gZm9yIE5ldyBFbmdsYW5kIEFyZWEgKGJ5IHN0YXRlKSIsDQogICAgeCA9ICJZZWFyIiwNCiAgICB5ID0gIk5hdHVyYWwgR2FzIENvbnN1bXB0aW9uIiwNCiAgICBjb2xvciA9ICJTdGF0ZSINCiAgKQ0KYGBgDQoNCiMgMi41DQoNCiMjIGEuIA0KDQpEb3dubG9hZCBgdG91cmlzbS54bHN4YCBmcm9tIHRoZSBbYm9vayB3ZWJzaXRlXShodHRwczovL2JpdC5seS9mcHB0b3VyaXNtKSBhbmQgcmVhZCBpdCBpbnRvIFIgdXNpbmcgYHJlYWR4bDo6cmVhZF9leGNlbCgpYC4NCg0KYGBge3J9DQpQQVRIPC0iQzovVXNlcnMvTGVubnkvRG9jdW1lbnRzL0dpdGFibGVHYWJlL0RhdGE2MjRfRGF0YS8iDQpgYGANCg0KDQpgYGB7cn0NCnRvdXJpc21fc3RyIDwtIHBhc3RlKFBBVEgsInRvdXJpc20ueGxzeCIsIHNlcCA9ICIiKQ0KZGZfdG91cmlzbSA8LSByZWFkeGw6OnJlYWRfZXhjZWwodG91cmlzbV9zdHIpDQpybSh0b3VyaXNtX3N0cikNCnRvdXJpc20NCmBgYA0KDQoNCg0KIyMgYi4NCg0KQ3JlYXRlIGEgYHRzaWJibGVgIHdoaWNoIGlzIGlkZW50aWNhbCB0byB0aGUgdG91cmlzbSBgdHNpYmJsZWAgZnJvbSB0aGUgYHRzaWJibGVgIHBhY2thZ2UuDQoNCmBgYHtyfQ0Kc3RyKGRmX3RvdXJpc20pDQpgYGANCg0KKipFeGFtcGxlKioNCg0KW0ZvcmVjYXN0aW5nIFByaW5jaXBsZXMgJiBQcmFjdGljZTogMi4xIHRzaWJibGUgb2JqZWN0c10oaHR0cHM6Ly95b3V0dS5iZS9Fd2p2QTJPY2RIcz9zaT10Zy13VzRPT1IzcWxuMDVsJnQ9NjYxKQ0KDQoqVGVtcGxhdGUqDQoNCiAgICAgIHByaXNvbjwtIHJlYWQ6OnJlYWRfY3N2KCJkYXRhL3ByaXNvbl9wb3B1bGF0aW9uLmNzdiIpICU+JQ0KICAgICAgICAgICAgICAgIG11dGF0ZShRdWFydGVyID0geWVhcnF1YXJ0ZXIoZGF0ZSkpICU+JQ0KICAgICAgICAgICAgICAgICAgc2VsZWN0KC1kYXRlKSAlPiUNCiAgICAgICAgICAgICAgICAgIGFzX3RzaWJibGUoDQogICAgICAgICAgICAgICAgICBpbmRleCA9IFF1YXJ0ZXIsDQogICAgICAgICAgICAgICAgICBrZXk9YyhzdGF0ZSxnZW5kZXIsbGVnYWwsaW5kaWdlbm91cykNCiAgICAgICAgICAgICAgICAgICkNCg0KDQpgYGB7cn0NCnRpYmJsZV90b3VyaXNtIDwtIGRmX3RvdXJpc20gJT4lDQogIG11dGF0ZShRdWFydGVyID0geWVhcnF1YXJ0ZXIoUXVhcnRlcikpICU+JQ0KICBhc190c2liYmxlKGluZGV4PVF1YXJ0ZXIsDQogICAgICAgICAgICAga2V5ID0gYygiUmVnaW9uIiwgIlN0YXRlIiwgIlB1cnBvc2UiKSkNCg0KdGliYmxlX3RvdXJpc20NCg0KYGBgDQoNCiMjIGMuDQoNCkZpbmQgd2hhdCBjb21iaW5hdGlvbiBvZiBSZWdpb24gYW5kIFB1cnBvc2UgaGFkIHRoZSBtYXhpbXVtIG51bWJlciBvZiBvdmVybmlnaHQgdHJpcHMgb24gYXZlcmFnZS4NCg0KYGBge3J9DQoNCnRpYmJsZV90b3VyaXNtICU+JSANCiAgZ3JvdXBfYnkoUmVnaW9uLFB1cnBvc2UpJT4lDQogIHN1bW1hcml6ZShUcmlwc0F2ZyA9IG1lYW4oVHJpcHMpKSU+JQ0KICBmaWx0ZXIoVHJpcHNBdmcgPT0gbWF4KFRyaXBzQXZnKSklPiUNCiAgYXJyYW5nZShkZXNjKFRyaXBzQXZnKSkNCg0KYGBgDQoNCg0KDQojIyBkLg0KDQpDcmVhdGUgYSBuZXcgYHRzaWJibGVgIHdoaWNoIGNvbWJpbmVzIHRoZSBQdXJwb3NlcyBhbmQgUmVnaW9ucywgYW5kIGp1c3QgaGFzIHRvdGFsIHRyaXBzIGJ5IFN0YXRlLg0KDQoNCmBgYHtyfQ0KdGliYmxlX3RvdXJpc21fdjIgPC0gdGliYmxlX3RvdXJpc20gJT4lDQogIGdyb3VwX2J5KFN0YXRlKSU+JQ0KICBzdW1tYXJpemUoVG90YWw9c3VtKFRyaXBzKSkNCg0KdGliYmxlX3RvdXJpc21fdjINCmBgYA0KDQojIDIuOA0KDQpVc2UgdGhlIGZvbGxvd2luZyBncmFwaGljcyBmdW5jdGlvbnM6IGBhdXRvcGxvdCgpYCwgYGdnX3NlYXNvbigpYCwgYGdnX3N1YnNlcmllcygpYCwgYGdnX2xhZygpYCwgYEFDRigpYCBhbmQgZXhwbG9yZSBmZWF0dXJlcyBmcm9tIHRoZSBmb2xsb3dpbmcgdGltZSBzZXJpZXM6IOKAnFRvdGFsIFByaXZhdGXigJ0gYEVtcGxveWVkYCBmcm9tIGB1c19lbXBsb3ltZW50YCwgYEJyaWNrc2AgZnJvbSBgYXVzX3Byb2R1Y3Rpb25gLCBgSGFyZWAgZnJvbSBgcGVsdGAsIOKAnEgwMuKAnSBgQ29zdGAgZnJvbSBgUEJTYCwgYW5kIGBCYXJyZWxzYCBmcm9tIGB1c19nYXNvbGluZWAuDQoNCmkuIENhbiB5b3Ugc3BvdCBhbnkgc2Vhc29uYWxpdHksIGN5Y2xpY2l0eSBhbmQgdHJlbmQ/DQppaS4gV2hhdCBkbyB5b3UgbGVhcm4gYWJvdXQgdGhlIHNlcmllcz8NCmlpaS4gV2hhdCBjYW4geW91IHNheSBhYm91dCB0aGUgc2Vhc29uYWwgcGF0dGVybnM/DQppdi4gQ2FuIHlvdSBpZGVudGlmeSBhbnkgdW51c3VhbCB5ZWFycz8NCg0KIyMgVG90YWwgUHJpdmF0ZQ0KDQoqKkV4YW1wbGUqKg0KDQogICAgICB2aWNfZWxlYyB8PiBnZ19zZWFzb24oRGVtYW5kLCBwZXJpb2QgPSAiZGF5IikgKw0KICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICAgICAgbGFicyh5PSJNV2giLCB0aXRsZT0iRWxlY3RyaWNpdHkgZGVtYW5kOiBWaWN0b3JpYSIpDQoNCmBgYHtyfQ0KdXNfZW1wbG95bWVudA0KYGBgDQoNCg0KYGBge3J9DQp1c19lbXBsb3ltZW50JT4lDQogIGZpbHRlcihUaXRsZT09IlRvdGFsIFByaXZhdGUiKSU+JQ0KICBhdXRvcGxvdChFbXBsb3llZCxwZXJpb2Q9Im1vbnRoIikgDQoNCnVzX2VtcGxveW1lbnQlPiUNCiAgZmlsdGVyKFRpdGxlPT0iVG90YWwgUHJpdmF0ZSIpJT4lDQogIGdnX3NlYXNvbihFbXBsb3llZCwgcG9sYXIgPSBGQUxTRSkNCg0KdXNfZW1wbG95bWVudCU+JQ0KICBmaWx0ZXIoVGl0bGU9PSJUb3RhbCBQcml2YXRlIiklPiUNCiAgZ2dfc2Vhc29uKEVtcGxveWVkLCBwb2xhciA9IFRSVUUpIA0KDQp1c19lbXBsb3ltZW50JT4lDQogIGZpbHRlcihUaXRsZT09IlRvdGFsIFByaXZhdGUiKSU+JQ0KICBnZ19zdWJzZXJpZXMoRW1wbG95ZWQpDQoNCnVzX2VtcGxveW1lbnQlPiUNCiAgZmlsdGVyKFRpdGxlPT0iVG90YWwgUHJpdmF0ZSIpJT4lDQogIGdnX2xhZyhFbXBsb3llZCkNCg0KYGBgDQoNCmBgYHtyfQ0KdXNfZW1wbG95bWVudCU+JQ0KICBmaWx0ZXIoVGl0bGU9PSJUb3RhbCBQcml2YXRlIiklPiUNCiAgQUNGKHVzX2VtcGxveW1lbnQkRW1wbG95ZWQpJT4lDQogIGF1dG9wbG90KCkNCmBgYA0KDQojIyMgaQ0KDQpUaGVyZSBpcyBhIGNsZWFyIHVwd2FyZHMgdHJlbmQgaW4gc21hbGwgaW5jcmVtZW50cyBmb3IgdGhlIGRhdGEuDQoNCiMjIyBpaQ0KDQpHcm93dGggaGFzIGJlZW4gY29uc2lzdGVudCB3aXRob3V0IGFueSBleHRyZW1lIHNwaWtlIG9yIGRyb3AuDQoNCiMjIyBpaWkNCg0KTm8gU2Vhc29uYWxpdHkgaXMgbm90ZWQgaW5kaWNhdGluZyB0aGVyZSBpcyBub3QgcGFydGljdWxhciBzZWFzb24gd2l0aCBhbiBhZmZlY3Qgb24gZW1wbG95bWVudCBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4NCg0KIyMjIGl2DQoNCkEgc21hbGwgZGlwIGFyb3VuZCAyMDEwIHdoaWNoIEkgYmVsaWV2ZSBhbGlnbnMgd2l0aCB0aGUgcmVjZXNzaW9uLg0KDQojIyBCcmlja3MNCg0KYGBge3J9DQphdXNfcHJvZHVjdGlvbg0KYGBgDQoNCg0KYGBge3J9DQphdXNfcHJvZHVjdGlvbiU+JQ0KICBzZWxlY3QoQnJpY2tzKSU+JQ0KICBhdXRvcGxvdChwZXJpb2Q9InF1YXJ0ZXIiKSANCg0KYXVzX3Byb2R1Y3Rpb24lPiUNCiAgc2VsZWN0KEJyaWNrcyklPiUNCiAgZ2dfc2Vhc29uKCBwb2xhciA9IEZBTFNFKQ0KDQphdXNfcHJvZHVjdGlvbiU+JQ0KICBzZWxlY3QoQnJpY2tzKSU+JQ0KICBnZ19zZWFzb24oIHBvbGFyID0gVFJVRSkgDQogDQphdXNfcHJvZHVjdGlvbiU+JQ0KICBzZWxlY3QoQnJpY2tzKSU+JQ0KICBnZ19zdWJzZXJpZXMoKQ0KDQphdXNfcHJvZHVjdGlvbiU+JQ0KICBzZWxlY3QoQnJpY2tzKSU+JQ0KICBnZ19sYWcoKQ0KDQpgYGANCg0KYGBge3J9DQphdXNfcHJvZHVjdGlvbiU+JQ0KICBzZWxlY3QoQnJpY2tzKSU+JQ0KICBBQ0YoYXVzX3Byb2R1Y3Rpb24kQnJpY2tzKSU+JQ0KICBhdXRvcGxvdCgpDQpgYGANCg0KIyMjIGkNCg0KVGhlcmUgaXMgbG90cyBvZiBjeWNsaWNpdHkgd2l0aCBmcmVxdWVudCBzcGlrZXMgYW5kIGRpcHMsIGJ1dCBpdCBkb2VzIG5vdCBhcHBlYXIgdG8gYmUgY29uc2lzdGVudCB0byBhIHRpbWUgcGVyaW9kLlRoZXJlIGlzIGEgcG9zaXRpdmUgdXB3YXJkIHRyZW5kIGluIHRoZSBsb25nIHRlcm0uDQoNCiMjIyBpaQ0KDQpUaGUgZGF0YSBiZWluZyBicm9rZW4gZG93biB0byBRdWFydGVycyBteSBpbmZsdWVuY2UgaG93IHdlbGwgd2UgY2FuIGFzc2VzcyB0aGUgcG90ZW50aWFsIHNlYXNvbmFsaXR5LiBBcyBpcywgdGhlcmUgZG9lcyAgc2VlbSB0byBiZSBvbmUuDQoNCiMjIyBpaWkNCg0KVGhlcmUgc2VlbXMgdG8gYmUgc29tZSBzZWFzb25hbGl0eSBhcyBmYXIgYXMgUTEgYW5kIFEzIGlzIGNvbmNlcm5lZC4NCg0KIyMjIGl2DQoNClRoZSBlYXJseSAxOTgwcyBoYXMgYSBzaWduaWZpY2FudCBkaXAgc28gSSB3b3VsZCBiZSBjdXJpb3VzIHRvIHVuZGVyc3RhbmQgd2hhdCBtYXkgaGF2ZSBjYXVzZSB0aGlzLg0KDQojIyBIYXJlDQoNCmBgYHtyfQ0KcGVsdA0KYGBgDQoNCg0KYGBge3J9DQpwZWx0JT4lDQogIHNlbGVjdChIYXJlKSU+JQ0KICBhdXRvcGxvdChwZXJpb2Q9InllYXIiKSANCg0KI05vdCBwb3NzaWJsZQ0KIyBwZWx0JT4lDQojICAgc2VsZWN0KEhhcmUpJT4lDQojICAgZ2dfc2Vhc29uKCBwb2xhciA9IEZBTFNFKQ0KIyANCiMgcGVsdCU+JQ0KIyAgIHNlbGVjdChIYXJlKSU+JQ0KIyAgIGdnX3NlYXNvbiggcG9sYXIgPSBUUlVFKSANCiANCnBlbHQlPiUNCiAgc2VsZWN0KEhhcmUpJT4lDQogIGdnX3N1YnNlcmllcygpDQoNCnBlbHQlPiUNCiAgc2VsZWN0KEhhcmUpJT4lDQogIGdnX2xhZygpDQpgYGANCmBgYHtyfQ0KcGVsdCU+JQ0KICBzZWxlY3QoSGFyZSklPiUNCiAgQUNGKCklPiUNCiAgYXV0b3Bsb3QoKQ0KYGBgDQoNCiMjIyBpDQoNClRoZSBkYXRhIGlzIGRlZmluaXRlbHkgY3ljbGljYWwgYnV0IGl0cyBub3QgcG9zc2libGUgdG8gdGVhbCBzZWFzb25hbGl0eSBzaW5jZSBpdHMgYXQgYSBhbm51YWwgYmFzaXMuDQoNCiMjIyBpaQ0KDQpUaGUgZGF0YSBkb2VzIG5vdCB0cmVuZCBhbmQgdmFyaWVzIGEgZ3JlYXQgZGVhbC4gQnV0IHNlZW1zIHRvIGhhdmUgYSBwYXR0ZXJuIGF0IGEgNSB5ZWFyIGludGVydmFsLg0KDQojIyMgaWlpDQoNCkFnYWluIG5vIHNlYXNvbmFsaXR5DQoNCiMjIyBpdg0KDQpJbSBjdXJpb3VzIHdoYXQgY2F1c2VkIHRoZSBwZWFrIGluIHRoZSBlYXJseSAxODYwcw0KDQojIyBDb3N0DQoNCmBgYHtyfQ0KUEJTDQpgYGANCg0KDQpgYGB7cn0NClBCUyU+JQ0KICBmaWx0ZXIoQVRDMj09IkgwMiIpJT4lDQogIGF1dG9wbG90KENvc3QpIA0KDQpQQlMgJT4lIA0KICBmaWx0ZXIoQVRDMiA9PSAiSDAyIikgJT4lDQogIGdnX3NlYXNvbihDb3N0LCBwb2xhciA9IEZBTFNFKQ0KDQpQQlMgJT4lIA0KICBmaWx0ZXIoQVRDMiA9PSAiSDAyIikgJT4lDQogIGdnX3N1YnNlcmllcyhDb3N0KQ0KDQojIFBCUyAlPiUgDQojICAgZmlsdGVyKEFUQzIgPT0gIkgwMiIpICU+JQ0KIyAgIGdnX2xhZyhDb3N0KQ0KDQpgYGANCg0KYGBge3J9DQpQQlMgJT4lIA0KICBmaWx0ZXIoQVRDMiA9PSAiSDAyIikgJT4lDQogIEFDRihDb3N0KSU+JQ0KICBhdXRvcGxvdCgpDQpgYGANCg0KIyMjIGkgDQoNClRoZSBkYXRhIGlzIGhhcmQgdG8gaW50ZXJwcmV0IGJ1dCBpdCBhcHBlYXJzIHRvIHRyZW5kIHVwd2FyZHMgd2l0aCBjeWNsaWNpdHkgYW5kIHNlYXNvbmFsaXR5Lg0KIyMjIGlpDQoNCnRoZSBkYXRhIGlzIHZlcnkgdm9sYXRpbGUgYnV0IHNwaWtlcyBtYWlubHkgZW5kIG9mIHllYXIgaXQgYXBwZWFycy4NCg0KIyMjIGlpaQ0KDQpUaGUgc2Vhc29uYWxpdHkgaXMgYXQgdGhlIGVuZCBvZiB0aGUgeWVhci4NCg0KIyMjIGl2DQoNCk5vIHllYXIgc3RhbmRzIG91dCwgb3V0c2lkZSBvZiB0aGUgbGF0ZXN0IHllYXIgaGF2aW5nIHRoZSBoaWdoZXN0IGNvc3QuDQoNCiMjIEJhcnJlbHMNCg0KYGBge3J9DQp1c19nYXNvbGluZQ0KYGBgDQoNCg0KYGBge3J9DQp1c19nYXNvbGluZSU+JQ0KICBzZWxlY3QoQmFycmVscyklPiUNCiAgYXV0b3Bsb3QoKSANCg0KdXNfZ2Fzb2xpbmUlPiUNCiAgc2VsZWN0KEJhcnJlbHMpJT4lDQogIGdnX3NlYXNvbihwb2xhciA9IEZBTFNFKQ0KDQp1c19nYXNvbGluZSU+JQ0KICBzZWxlY3QoQmFycmVscyklPiUNCiAgZ2dfc2Vhc29uKCBwb2xhciA9IFRSVUUpIA0KDQp1c19nYXNvbGluZSU+JQ0KICBzZWxlY3QoQmFycmVscyklPiUNCiAgZ2dfc3Vic2VyaWVzKCkNCg0KdXNfZ2Fzb2xpbmUlPiUNCiAgc2VsZWN0KEJhcnJlbHMpJT4lDQogIGdnX2xhZygpDQoNCmBgYA0KDQpgYGB7cn0NCnVzX2dhc29saW5lICU+JSANCiAgc2VsZWN0KEJhcnJlbHMpICU+JQ0KICBBQ0YoKSU+JQ0KICBhdXRvcGxvdCgpDQpgYGANCg0KIyMjIGkNCg0KUHJpbWFyaWx5IGFuIHVwd2FyZCB0cmVuZCB3aXRoIGEgZGlwIG5lYXIgdGhlIG1vc3QgcmVjZW50IHllYXINCg0KIyMjIGlpDQoNCkl0cyBwb3NzaWJsZSB0aGUgYmFycmVscyB2YWx1ZSBpcyBpbXBhY3RlZCBieSBzdXBwbHkuDQoNCiMjIyBpaWkNCg0KVGhlcmUgZG9lcyBub3QgYXBwZWFyIHRvIGJlIHNlYXNvbmFsaXR5IG9mIGN5Y2xpY2l0eQ0KDQojIyMgaXYNCg0KVGhlIG1vc3QgcmVjZW50IGRpcCBpcyBpbnRlcmVzdGluZyBhbmQgSSB3b25kZXIgaWYgaXRzIGp1c3QgYSBkYXRhIGNvbGxlY3Rpb24gaXNzdWUuDQo=