Etivity
In the last 2 etivities, you gained a better understanding of how susceptibility in a population can change independently of the epidemic - first through population turnover, then through vaccination. So far we have only modelled immunising infections where recovered or vaccinated individuals are permamently immune to (re)infection. However, many infections only provide temporary immunity after recovery - immunity can wane over time, returning those previously infected (or vaccinated) individuals to the susceptible pool. This is the scenario you will explore in this etivity.
Go back to your simple SIR model from week 3, assuming no births or deaths and a totally susceptible population with the exception of 1 infected individual. The infection and recovery rates are 0.4 and 0.2 days\(^{-1}\) respectively, and the average duration of immunity is 10 years.
Question: What is the value of the waning rate \(\sigma\)? Draw a diagram for this model structure on paper.
Code this model below, making sure to make an appropriate choice for the duration to run the model for and the intervals to solve the equations at. Generate a plot to study the infection dynamics.
Question: What do you observe about the infection dynamics? How does this compare to the model with population turnover from the first notebook this week?
Also try to think of this in the context of informing disease control measures, which is usually the aim of using mathematical models for infectious diseases. Imagine the immunity you see building up in the population after the first outbreak here is actually due to vaccination (you should see that after about 3 months, 78% of the population are immune).
Question: In this case, what implications would this have for a vaccination programme against this disease?
Now, copy-paste your code below to model a scenario where the immunity provided by infection is much more short-lived, only lasting 6 months on average.
Question: What do you observe about the infection dynamics? How does this compare to the model with slow waning of immunity, and with population turnover?
Lastly, in the previous example, change the initial conditions to represent an endemic infection rather than introduction of a single infected case into the population. Assume an endemic prevalence of 10% and that 60% of the population are already immune at the first timestep. Adapt this in the code above.
Question: What do you observe about the infection dynamics if you change the initial state values?
Solutions - Modelling Waning Immunity
The SIR model structure with waning immunity can be visualised like this:
#<img src="https://heitaavmvtxlmxvtzwmhsb.coursera-apps.org/notebooks/Solutions/w4_nb3_model_diagram.png">
What is the value of the waning rate \(\sigma\) if the average duration of immunity is 10 years?
\(\sigma\) = 1/10 = 0.1 years\(^{-1}\)
# LOAD THE PACKAGES:
library(deSolve)
library(reshape2)
library(ggplot2)
# MODEL INPUTS:
# Vector storing the initial number of people in each compartment (at timestep 0)
initial_state_values <- c(S = 1000000-1, # the whole population is susceptible
I = 1, # the epidemic starts with a single infected person
R = 0) # no one is immune yet
# Vector storing the parameters describing the transition rates in units of years^-1
parameters <- c(beta = 0.4*365, # the infection rate, which acts on susceptibles
gamma = 0.2*365, # the rate of recovery, which acts on those infected
sigma = 1/10) # the rate of waning of immunity, which acts on those recovered
# TIMESTEPS:
# Vector storing the sequence of timesteps to solve the model at
times <- seq(from = 0, to = 100, by = 2/365) # from 0 to 100 years in timesteps of every 2 days
# SIR MODEL FUNCTION:
# The model function takes as input arguments (in the following order): time, state and parameters
sir_model <- function(time, state, parameters) {
with(as.list(c(state, parameters)), { # tell R to look for variable names within the state and parameters objects
# Calculating the total population size N (the sum of the number of people in each compartment)
N <- S+I+R
# Defining lambda as a function of beta and I:
lambda <- beta * I/N
# The differential equations
dS <- -lambda * S + sigma * R # recovered individuals now return to the susceptible compartment at a rate sigma
dI <- lambda * S - gamma * I
dR <- gamma * I - sigma * R # immune individuals leave the recovered compartment at a rate sigma
# Return the number of people in the S, I and R compartments at each timestep
# (in the same order as the input state variables)
return(list(c(dS, dI, dR)))
})
}
# MODEL OUTPUT (solving the differential equations):
# Solving the differential equations using the ode integration algorithm
output <- as.data.frame(ode(y = initial_state_values,
times = times,
func = sir_model,
parms = parameters))
output_long <- melt(as.data.frame(output), id = "time") # turn output dataset into long format
# Adding a column for the prevalence proportion to the long-format output
output_long$prevalence <- output_long$value/sum(initial_state_values)
# Plot the prevalence proportion
ggplot(data = output_long, # specify object containing data to plot
aes(x = time, y = prevalence, colour = variable, group = variable)) + # assign columns to axes and groups
geom_line() + # represent data as lines
xlab("Time (years)")+ # add label for x axis
ylab("Prevalence (proportion)") + # add label for y axis
labs(colour = "Compartment", # add legend title
title = "Prevalence of infection, susceptibility and recovery over time\nsigma = 0.1 years^-1") # add plot title

What do you observe about the infection dynamics? How does this compare to the model with population turnover from the first notebook this week?
When modelling slow waning of immunity, we observe the same epidemic patterns as when we modelled an acute disease in a population with slow turnover: spikes of epidemics alternating with long deep troughs, reflected in the cycles of susceptibility and recovery, but eventually dying out. However, with an average duration of immunity of 30 years, the rate of waning is still quicker than human population turnover, and therefore the time between epidemics is shorter. While in the population turnover example, the source of new susceptibles were births, here it is the people losing their immunity that replenish the susceptible pool.
What implications would this have for a vaccination programme against this disease?
Due to waning of vaccine-induced immunity, one-off vaccination of the population is not sufficient to prevent an epidemic in the future. The model predicts a second smaller epidemic occurring about 10 years after vaccination, so it might be necessary to deliver a second booster vaccine within that time period to maintain sufficient herd immunity in the population. However, it is important to note that this model makes many simplifying assumptions and ignores other factors affecting susceptibility in the population, so we cannot draw a conclusion based on this result alone.
Changing \(\sigma\) to reflect fast waning of immunity:
# Vector storing the parameters describing the transition rates in units of years^-1
parameters <- c(beta = 0.4*365, # the infection rate, which acts on susceptibles
gamma = 0.2*365, # the rate of recovery, which acts on those infected
sigma = 1/0.5) # the rate of waning of immunity, which acts on those recovered
# TIMESTEPS:
# Vector storing the sequence of timesteps to solve the model at
times <- seq(from = 0, to = 5, by = 2/365) # from 0 to 5 years in timesteps of every 2 days
# MODEL OUTPUT (solving the differential equations):
# Solving the differential equations using the ode integration algorithm
output <- as.data.frame(ode(y = initial_state_values,
times = times,
func = sir_model,
parms = parameters))
output_long <- melt(as.data.frame(output), id = "time") # turn output dataset into long format
# Adding a column for the prevalence proportion to the long-format output
output_long$prevalence <- output_long$value/sum(initial_state_values)
# Plot the prevalence proportion
ggplot(data = output_long, # specify object containing data to plot
aes(x = time, y = prevalence, colour = variable, group = variable)) + # assign columns to axes and groups
geom_line() + # represent data as lines
xlab("Time (years)")+ # add label for x axis
ylab("Prevalence (proportion)") + # add label for y axis
labs(colour = "Compartment", # add legend title
title = "Prevalence of infection, susceptibility and recovery over time\nsigma = 2 years^-1") # add plot title

What do you observe about the infection dynamics? How does this compare to the model with slow waning of immunity, and with population turnover?
The outcome under these assumptions is very similar to what we observed when modelling an acute disease in the pig population with fast population turnover. The infection quickly reaches an endemic equilibrium with the effective reproduction number staying stable at just over 1, because just as in the pig population, the pool of susceptibles is continually replenished.
As you can see from both these examples, waning immunity acts in a similar way to the birth rate in the SIR model dynamics.
Changing the initial state values to reflect endemicity:
# Vector storing the initial number of people in each compartment (at timestep 0)
initial_state_values <- c(S = 0.3*1000000, # 30% of the population are susceptible
I = 0.1*1000000, # 10% of the population are infected
R = 0.6*1000000) # 60% of the population are immune
# Vector storing the parameters describing the transition rates in units of years^-1
parameters <- c(beta = 0.4*365, # the infection rate, which acts on susceptibles
gamma = 0.2*365, # the rate of recovery, which acts on those infected
sigma = 1/0.5) # the rate of waning of immunity, which acts on those recovered
# TIMESTEPS:
# Vector storing the sequence of timesteps to solve the model at
times <- seq(from = 0, to = 5, by = 2/365) # from 0 to 5 years in timesteps of every 2 days
# MODEL OUTPUT (solving the differential equations):
# Solving the differential equations using the ode integration algorithm
output <- as.data.frame(ode(y = initial_state_values,
times = times,
func = sir_model,
parms = parameters))
output_long <- melt(as.data.frame(output), id = "time") # turn output dataset into long format
# Adding a column for the prevalence proportion to the long-format output
output_long$prevalence <- output_long$value/sum(initial_state_values)
# Plot the prevalence proportion
ggplot(data = output_long, # specify object containing data to plot
aes(x = time, y = prevalence, colour = variable, group = variable)) + # assign columns to axes and groups
geom_line() + # represent data as lines
xlab("Time (years)")+ # add label for x axis
ylab("Prevalence (proportion)") + # add label for y axis
labs(colour = "Compartment", # add legend title
title = "Prevalence of infection, susceptibility and recovery over time\nsigma = 2 years^-1") # add plot title

What do you observe about the infection dynamics if you change the initial state values?
As you can see, the system eventually stabilises at the same values as in the previous example where we assumed introduction of a single infected case (although over a slightly different timescale). Generally if we are modelling an endemic infection, with a combination of parameters that leads to a continuous addition of new susceptibles and reaches an endemic equilibrium, the initial number in the compartments we start off with does not affect the endemic prevalence that is eventually reached (as long as there is at least one infected person, of course)!
This is in contrast to what you saw in the previous etivity, where changing the initial proportion of the population that was susceptible determined whether an epidemic would occur or not!
LS0tDQp0aXRsZTogIk1vZGVsbGluZyBXYW5pbmcgSW1tdW5pdHkgKHc0IFNJUikiDQphdXRob3I6ICJCSW5oIFRoYW5nIFRyYW4iDQpkYXRlOiAiNS8yNi8yMDIwIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IGpvdXJuYWwNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCi0tLQ0KDQojIEV0aXZpdHkNCg0KSW4gdGhlIGxhc3QgMiBldGl2aXRpZXMsIHlvdSBnYWluZWQgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiBob3cgc3VzY2VwdGliaWxpdHkgaW4gYSBwb3B1bGF0aW9uIGNhbiBjaGFuZ2UgaW5kZXBlbmRlbnRseSBvZiB0aGUgZXBpZGVtaWMgLSBmaXJzdCB0aHJvdWdoIHBvcHVsYXRpb24gdHVybm92ZXIsIHRoZW4gdGhyb3VnaCB2YWNjaW5hdGlvbi4gU28gZmFyIHdlIGhhdmUgb25seSBtb2RlbGxlZCBpbW11bmlzaW5nIGluZmVjdGlvbnMgd2hlcmUgcmVjb3ZlcmVkIG9yIHZhY2NpbmF0ZWQgaW5kaXZpZHVhbHMgYXJlIHBlcm1hbWVudGx5IGltbXVuZSB0byAocmUpaW5mZWN0aW9uLiBIb3dldmVyLCBtYW55IGluZmVjdGlvbnMgb25seSBwcm92aWRlIHRlbXBvcmFyeSBpbW11bml0eSBhZnRlciByZWNvdmVyeSAtIGltbXVuaXR5IGNhbiB3YW5lIG92ZXIgdGltZSwgcmV0dXJuaW5nIHRob3NlIHByZXZpb3VzbHkgaW5mZWN0ZWQgKG9yIHZhY2NpbmF0ZWQpIGluZGl2aWR1YWxzIHRvIHRoZSBzdXNjZXB0aWJsZSBwb29sLiBUaGlzIGlzIHRoZSBzY2VuYXJpbyB5b3Ugd2lsbCBleHBsb3JlIGluIHRoaXMgZXRpdml0eS4gDQoNCkdvIGJhY2sgdG8geW91ciBzaW1wbGUgU0lSIG1vZGVsIGZyb20gd2VlayAzLCBhc3N1bWluZyBubyBiaXJ0aHMgb3IgZGVhdGhzIGFuZCBhIHRvdGFsbHkgc3VzY2VwdGlibGUgcG9wdWxhdGlvbiB3aXRoIHRoZSBleGNlcHRpb24gb2YgMSBpbmZlY3RlZCBpbmRpdmlkdWFsLiBUaGUgaW5mZWN0aW9uIGFuZCByZWNvdmVyeSByYXRlcyBhcmUgMC40IGFuZCAwLjIgZGF5cyReey0xfSQgcmVzcGVjdGl2ZWx5LCBhbmQgdGhlIGF2ZXJhZ2UgZHVyYXRpb24gb2YgaW1tdW5pdHkgaXMgMTAgeWVhcnMuDQoNCiMjIyBRdWVzdGlvbjogV2hhdCBpcyB0aGUgdmFsdWUgb2YgdGhlIHdhbmluZyByYXRlICRcc2lnbWEkPyBEcmF3IGEgZGlhZ3JhbSBmb3IgdGhpcyBtb2RlbCBzdHJ1Y3R1cmUgb24gcGFwZXIuIA0KDQpDb2RlIHRoaXMgbW9kZWwgYmVsb3csIG1ha2luZyBzdXJlIHRvIG1ha2UgYW4gYXBwcm9wcmlhdGUgY2hvaWNlIGZvciB0aGUgZHVyYXRpb24gdG8gcnVuIHRoZSBtb2RlbCBmb3IgYW5kIHRoZSBpbnRlcnZhbHMgdG8gc29sdmUgdGhlIGVxdWF0aW9ucyBhdC4gR2VuZXJhdGUgYSBwbG90IHRvIHN0dWR5IHRoZSBpbmZlY3Rpb24gZHluYW1pY3MuDQoNCiMjIyBRdWVzdGlvbjogV2hhdCBkbyB5b3Ugb2JzZXJ2ZSBhYm91dCB0aGUgaW5mZWN0aW9uIGR5bmFtaWNzPyBIb3cgZG9lcyB0aGlzIGNvbXBhcmUgdG8gdGhlIG1vZGVsIHdpdGggcG9wdWxhdGlvbiB0dXJub3ZlciBmcm9tIHRoZSBmaXJzdCBub3RlYm9vayB0aGlzIHdlZWs/IA0KDQpBbHNvIHRyeSB0byB0aGluayBvZiB0aGlzIGluIHRoZSBjb250ZXh0IG9mIGluZm9ybWluZyBkaXNlYXNlIGNvbnRyb2wgbWVhc3VyZXMsIHdoaWNoIGlzIHVzdWFsbHkgdGhlIGFpbSBvZiB1c2luZyBtYXRoZW1hdGljYWwgbW9kZWxzIGZvciBpbmZlY3Rpb3VzIGRpc2Vhc2VzLiBJbWFnaW5lIHRoZSBpbW11bml0eSB5b3Ugc2VlIGJ1aWxkaW5nIHVwIGluIHRoZSBwb3B1bGF0aW9uIGFmdGVyIHRoZSBmaXJzdCBvdXRicmVhayBoZXJlIGlzIGFjdHVhbGx5IGR1ZSB0byB2YWNjaW5hdGlvbiAoeW91IHNob3VsZCBzZWUgdGhhdCBhZnRlciBhYm91dCAzIG1vbnRocywgNzglIG9mIHRoZSBwb3B1bGF0aW9uIGFyZSBpbW11bmUpLg0KDQojIyMgUXVlc3Rpb246IEluIHRoaXMgY2FzZSwgd2hhdCBpbXBsaWNhdGlvbnMgd291bGQgdGhpcyBoYXZlIGZvciBhIHZhY2NpbmF0aW9uIHByb2dyYW1tZSBhZ2FpbnN0IHRoaXMgZGlzZWFzZT8NCg0KTm93LCBjb3B5LXBhc3RlIHlvdXIgY29kZSBiZWxvdyB0byBtb2RlbCBhIHNjZW5hcmlvIHdoZXJlIHRoZSBpbW11bml0eSBwcm92aWRlZCBieSBpbmZlY3Rpb24gaXMgbXVjaCBtb3JlIHNob3J0LWxpdmVkLCBvbmx5IGxhc3RpbmcgNiBtb250aHMgb24gYXZlcmFnZS4NCg0KIyMjIFF1ZXN0aW9uOiBXaGF0IGRvIHlvdSBvYnNlcnZlIGFib3V0IHRoZSBpbmZlY3Rpb24gZHluYW1pY3M/IEhvdyBkb2VzIHRoaXMgY29tcGFyZSB0byB0aGUgbW9kZWwgd2l0aCBzbG93IHdhbmluZyBvZiBpbW11bml0eSwgYW5kIHdpdGggcG9wdWxhdGlvbiB0dXJub3Zlcj8NCg0KTGFzdGx5LCBpbiB0aGUgcHJldmlvdXMgZXhhbXBsZSwgY2hhbmdlIHRoZSBpbml0aWFsIGNvbmRpdGlvbnMgdG8gcmVwcmVzZW50IGFuIGVuZGVtaWMgaW5mZWN0aW9uIHJhdGhlciB0aGFuIGludHJvZHVjdGlvbiBvZiBhIHNpbmdsZSBpbmZlY3RlZCBjYXNlIGludG8gdGhlIHBvcHVsYXRpb24uIEFzc3VtZSBhbiBlbmRlbWljIHByZXZhbGVuY2Ugb2YgMTAlIGFuZCB0aGF0IDYwJSBvZiB0aGUgcG9wdWxhdGlvbiBhcmUgYWxyZWFkeSBpbW11bmUgYXQgdGhlIGZpcnN0IHRpbWVzdGVwLiBBZGFwdCB0aGlzIGluIHRoZSBjb2RlIGFib3ZlLg0KDQojIyMgUXVlc3Rpb246IFdoYXQgZG8geW91IG9ic2VydmUgYWJvdXQgdGhlIGluZmVjdGlvbiBkeW5hbWljcyBpZiB5b3UgY2hhbmdlIHRoZSBpbml0aWFsIHN0YXRlIHZhbHVlcz8NCg0KDQoNCg0KIyBTb2x1dGlvbnMgLSBNb2RlbGxpbmcgV2FuaW5nIEltbXVuaXR5DQoNCg0KVGhlIFNJUiBtb2RlbCBzdHJ1Y3R1cmUgd2l0aCB3YW5pbmcgaW1tdW5pdHkgY2FuIGJlIHZpc3VhbGlzZWQgbGlrZSB0aGlzOg0KDQpgYGB7cn0NCiM8aW1nIHNyYz0iaHR0cHM6Ly9oZWl0YWF2bXZ0eGxteHZ0endtaHNiLmNvdXJzZXJhLWFwcHMub3JnL25vdGVib29rcy9Tb2x1dGlvbnMvdzRfbmIzX21vZGVsX2RpYWdyYW0ucG5nIj4NCmBgYA0KDQoNCg0KIyMjIFdoYXQgaXMgdGhlIHZhbHVlIG9mIHRoZSB3YW5pbmcgcmF0ZSAkXHNpZ21hJCBpZiB0aGUgYXZlcmFnZSBkdXJhdGlvbiBvZiBpbW11bml0eSBpcyAxMCB5ZWFycz8NCg0KJFxzaWdtYSQgPSAxLzEwID0gMC4xIHllYXJzJF57LTF9JA0KDQoNCmBgYHtyfQ0KIyBMT0FEIFRIRSBQQUNLQUdFUzoNCmxpYnJhcnkoZGVTb2x2ZSkNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgTU9ERUwgSU5QVVRTOg0KDQojIFZlY3RvciBzdG9yaW5nIHRoZSBpbml0aWFsIG51bWJlciBvZiBwZW9wbGUgaW4gZWFjaCBjb21wYXJ0bWVudCAoYXQgdGltZXN0ZXAgMCkNCmluaXRpYWxfc3RhdGVfdmFsdWVzIDwtIGMoUyA9IDEwMDAwMDAtMSwgIyB0aGUgd2hvbGUgcG9wdWxhdGlvbiBpcyBzdXNjZXB0aWJsZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBJID0gMSwgICAgICAgICAjIHRoZSBlcGlkZW1pYyBzdGFydHMgd2l0aCBhIHNpbmdsZSBpbmZlY3RlZCBwZXJzb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IDApICAgICAgICAgIyBubyBvbmUgaXMgaW1tdW5lIHlldA0KDQojIFZlY3RvciBzdG9yaW5nIHRoZSBwYXJhbWV0ZXJzIGRlc2NyaWJpbmcgdGhlIHRyYW5zaXRpb24gcmF0ZXMgaW4gdW5pdHMgb2YgeWVhcnNeLTENCnBhcmFtZXRlcnMgPC0gYyhiZXRhID0gMC40KjM2NSwgICAgICAjIHRoZSBpbmZlY3Rpb24gcmF0ZSwgd2hpY2ggYWN0cyBvbiBzdXNjZXB0aWJsZXMNCiAgICAgICAgICAgICAgICBnYW1tYSA9IDAuMiozNjUsICAgICAjIHRoZSByYXRlIG9mIHJlY292ZXJ5LCB3aGljaCBhY3RzIG9uIHRob3NlIGluZmVjdGVkDQogICAgICAgICAgICAgICAgc2lnbWEgPSAxLzEwKSAgICAgICAgIyB0aGUgcmF0ZSBvZiB3YW5pbmcgb2YgaW1tdW5pdHksIHdoaWNoIGFjdHMgb24gdGhvc2UgcmVjb3ZlcmVkIA0KDQojIFRJTUVTVEVQUzoNCg0KIyBWZWN0b3Igc3RvcmluZyB0aGUgc2VxdWVuY2Ugb2YgdGltZXN0ZXBzIHRvIHNvbHZlIHRoZSBtb2RlbCBhdA0KdGltZXMgPC0gc2VxKGZyb20gPSAwLCB0byA9IDEwMCwgYnkgPSAyLzM2NSkgICAjIGZyb20gMCB0byAxMDAgeWVhcnMgaW4gdGltZXN0ZXBzIG9mIGV2ZXJ5IDIgZGF5cw0KDQojIFNJUiBNT0RFTCBGVU5DVElPTjogDQoNCiMgVGhlIG1vZGVsIGZ1bmN0aW9uIHRha2VzIGFzIGlucHV0IGFyZ3VtZW50cyAoaW4gdGhlIGZvbGxvd2luZyBvcmRlcik6IHRpbWUsIHN0YXRlIGFuZCBwYXJhbWV0ZXJzDQpzaXJfbW9kZWwgPC0gZnVuY3Rpb24odGltZSwgc3RhdGUsIHBhcmFtZXRlcnMpIHsgIA0KDQogICAgd2l0aChhcy5saXN0KGMoc3RhdGUsIHBhcmFtZXRlcnMpKSwgeyAgIyB0ZWxsIFIgdG8gbG9vayBmb3IgdmFyaWFibGUgbmFtZXMgd2l0aGluIHRoZSBzdGF0ZSBhbmQgcGFyYW1ldGVycyBvYmplY3RzICAgIA0KICAgICAgICANCiAgICAjIENhbGN1bGF0aW5nIHRoZSB0b3RhbCBwb3B1bGF0aW9uIHNpemUgTiAodGhlIHN1bSBvZiB0aGUgbnVtYmVyIG9mIHBlb3BsZSBpbiBlYWNoIGNvbXBhcnRtZW50KQ0KICAgICAgTiA8LSBTK0krUg0KICAgICAgDQogICAgIyBEZWZpbmluZyBsYW1iZGEgYXMgYSBmdW5jdGlvbiBvZiBiZXRhIGFuZCBJOg0KICAgICAgbGFtYmRhIDwtIGJldGEgKiBJL04NCiAgICAgICAgDQogICAgIyBUaGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucw0KICAgICAgZFMgPC0gLWxhbWJkYSAqIFMgKyBzaWdtYSAqIFIgICAjIHJlY292ZXJlZCBpbmRpdmlkdWFscyBub3cgcmV0dXJuIHRvIHRoZSBzdXNjZXB0aWJsZSBjb21wYXJ0bWVudCBhdCBhIHJhdGUgc2lnbWEgICAgICAgICAgDQogICAgICBkSSA8LSBsYW1iZGEgKiBTIC0gZ2FtbWEgKiBJICAgICAgICAgICAgDQogICAgICBkUiA8LSBnYW1tYSAqIEkgLSBzaWdtYSAqIFIgICAgICMgaW1tdW5lIGluZGl2aWR1YWxzIGxlYXZlIHRoZSByZWNvdmVyZWQgY29tcGFydG1lbnQgYXQgYSByYXRlIHNpZ21hICAgICAgICAgICAgICAgDQogICAgICANCiAgICAjIFJldHVybiB0aGUgbnVtYmVyIG9mIHBlb3BsZSBpbiB0aGUgUywgSSBhbmQgUiBjb21wYXJ0bWVudHMgYXQgZWFjaCB0aW1lc3RlcCANCiAgICAjIChpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgaW5wdXQgc3RhdGUgdmFyaWFibGVzKQ0KICAgIHJldHVybihsaXN0KGMoZFMsIGRJLCBkUikpKSANCiAgICB9KQ0KICANCn0NCg0KIyBNT0RFTCBPVVRQVVQgKHNvbHZpbmcgdGhlIGRpZmZlcmVudGlhbCBlcXVhdGlvbnMpOg0KDQojIFNvbHZpbmcgdGhlIGRpZmZlcmVudGlhbCBlcXVhdGlvbnMgdXNpbmcgdGhlIG9kZSBpbnRlZ3JhdGlvbiBhbGdvcml0aG0NCm91dHB1dCA8LSBhcy5kYXRhLmZyYW1lKG9kZSh5ID0gaW5pdGlhbF9zdGF0ZV92YWx1ZXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzID0gdGltZXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmMgPSBzaXJfbW9kZWwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFybXMgPSBwYXJhbWV0ZXJzKSkNCg0Kb3V0cHV0X2xvbmcgPC0gbWVsdChhcy5kYXRhLmZyYW1lKG91dHB1dCksIGlkID0gInRpbWUiKSAgICAgICAgICAgICAgICAgICMgdHVybiBvdXRwdXQgZGF0YXNldCBpbnRvIGxvbmcgZm9ybWF0DQoNCiMgQWRkaW5nIGEgY29sdW1uIGZvciB0aGUgcHJldmFsZW5jZSBwcm9wb3J0aW9uIHRvIHRoZSBsb25nLWZvcm1hdCBvdXRwdXQNCm91dHB1dF9sb25nJHByZXZhbGVuY2UgPC0gb3V0cHV0X2xvbmckdmFsdWUvc3VtKGluaXRpYWxfc3RhdGVfdmFsdWVzKQ0KDQojIFBsb3QgdGhlIHByZXZhbGVuY2UgcHJvcG9ydGlvbg0KZ2dwbG90KGRhdGEgPSBvdXRwdXRfbG9uZywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3BlY2lmeSBvYmplY3QgY29udGFpbmluZyBkYXRhIHRvIHBsb3QNCiAgICAgICBhZXMoeCA9IHRpbWUsIHkgPSBwcmV2YWxlbmNlLCBjb2xvdXIgPSB2YXJpYWJsZSwgZ3JvdXAgPSB2YXJpYWJsZSkpICsgICMgYXNzaWduIGNvbHVtbnMgdG8gYXhlcyBhbmQgZ3JvdXBzDQogIGdlb21fbGluZSgpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByZXByZXNlbnQgZGF0YSBhcyBsaW5lcw0KICB4bGFiKCJUaW1lICh5ZWFycykiKSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkZCBsYWJlbCBmb3IgeCBheGlzDQogIHlsYWIoIlByZXZhbGVuY2UgKHByb3BvcnRpb24pIikgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgbGFiZWwgZm9yIHkgYXhpcw0KICBsYWJzKGNvbG91ciA9ICJDb21wYXJ0bWVudCIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRkIGxlZ2VuZCB0aXRsZQ0KICAgICAgIHRpdGxlID0gIlByZXZhbGVuY2Ugb2YgaW5mZWN0aW9uLCBzdXNjZXB0aWJpbGl0eSBhbmQgcmVjb3Zlcnkgb3ZlciB0aW1lXG5zaWdtYSA9IDAuMSB5ZWFyc14tMSIpICAjIGFkZCBwbG90IHRpdGxlICAgIA0KYGBgDQoNCg0KDQojIyMgV2hhdCBkbyB5b3Ugb2JzZXJ2ZSBhYm91dCB0aGUgaW5mZWN0aW9uIGR5bmFtaWNzPyBIb3cgZG9lcyB0aGlzIGNvbXBhcmUgdG8gdGhlIG1vZGVsIHdpdGggcG9wdWxhdGlvbiB0dXJub3ZlciBmcm9tIHRoZSBmaXJzdCBub3RlYm9vayB0aGlzIHdlZWs/DQoNCldoZW4gbW9kZWxsaW5nIHNsb3cgd2FuaW5nIG9mIGltbXVuaXR5LCB3ZSBvYnNlcnZlIHRoZSBzYW1lIGVwaWRlbWljIHBhdHRlcm5zIGFzIHdoZW4gd2UgbW9kZWxsZWQgYW4gYWN1dGUgZGlzZWFzZSBpbiBhIHBvcHVsYXRpb24gd2l0aCBzbG93IHR1cm5vdmVyOiBzcGlrZXMgb2YgZXBpZGVtaWNzIGFsdGVybmF0aW5nIHdpdGggbG9uZyBkZWVwIHRyb3VnaHMsIHJlZmxlY3RlZCBpbiB0aGUgY3ljbGVzIG9mIHN1c2NlcHRpYmlsaXR5IGFuZCByZWNvdmVyeSwgYnV0IGV2ZW50dWFsbHkgZHlpbmcgb3V0LiBIb3dldmVyLCB3aXRoIGFuIGF2ZXJhZ2UgZHVyYXRpb24gb2YgaW1tdW5pdHkgb2YgMzAgeWVhcnMsIHRoZSByYXRlIG9mIHdhbmluZyBpcyBzdGlsbCBxdWlja2VyIHRoYW4gaHVtYW4gcG9wdWxhdGlvbiB0dXJub3ZlciwgYW5kIHRoZXJlZm9yZSB0aGUgdGltZSBiZXR3ZWVuIGVwaWRlbWljcyBpcyBzaG9ydGVyLiBXaGlsZSBpbiB0aGUgcG9wdWxhdGlvbiB0dXJub3ZlciBleGFtcGxlLCB0aGUgc291cmNlIG9mIG5ldyBzdXNjZXB0aWJsZXMgd2VyZSBiaXJ0aHMsIGhlcmUgaXQgaXMgdGhlIHBlb3BsZSBsb3NpbmcgdGhlaXIgaW1tdW5pdHkgdGhhdCByZXBsZW5pc2ggdGhlIHN1c2NlcHRpYmxlIHBvb2wuDQoNCiMjIyBXaGF0IGltcGxpY2F0aW9ucyB3b3VsZCB0aGlzIGhhdmUgZm9yIGEgdmFjY2luYXRpb24gcHJvZ3JhbW1lIGFnYWluc3QgdGhpcyBkaXNlYXNlPw0KDQpEdWUgdG8gd2FuaW5nIG9mIHZhY2NpbmUtaW5kdWNlZCBpbW11bml0eSwgb25lLW9mZiB2YWNjaW5hdGlvbiBvZiB0aGUgcG9wdWxhdGlvbiBpcyBub3Qgc3VmZmljaWVudCB0byBwcmV2ZW50IGFuIGVwaWRlbWljIGluIHRoZSBmdXR1cmUuIFRoZSBtb2RlbCBwcmVkaWN0cyBhIHNlY29uZCBzbWFsbGVyIGVwaWRlbWljIG9jY3VycmluZyBhYm91dCAxMCB5ZWFycyBhZnRlciB2YWNjaW5hdGlvbiwgc28gaXQgbWlnaHQgYmUgbmVjZXNzYXJ5IHRvIGRlbGl2ZXIgYSBzZWNvbmQgYm9vc3RlciB2YWNjaW5lIHdpdGhpbiB0aGF0IHRpbWUgcGVyaW9kIHRvIG1haW50YWluIHN1ZmZpY2llbnQgaGVyZCBpbW11bml0eSBpbiB0aGUgcG9wdWxhdGlvbi4gSG93ZXZlciwgaXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCB0aGlzIG1vZGVsIG1ha2VzIG1hbnkgc2ltcGxpZnlpbmcgYXNzdW1wdGlvbnMgYW5kIGlnbm9yZXMgb3RoZXIgZmFjdG9ycyBhZmZlY3Rpbmcgc3VzY2VwdGliaWxpdHkgaW4gdGhlIHBvcHVsYXRpb24sIHNvIHdlIGNhbm5vdCBkcmF3IGEgY29uY2x1c2lvbiBiYXNlZCBvbiB0aGlzIHJlc3VsdCBhbG9uZS4gDQoNCioqQ2hhbmdpbmcgJFxzaWdtYSQgdG8gcmVmbGVjdCBmYXN0IHdhbmluZyBvZiBpbW11bml0eToqKg0KDQpgYGB7cn0NCiMgVmVjdG9yIHN0b3JpbmcgdGhlIHBhcmFtZXRlcnMgZGVzY3JpYmluZyB0aGUgdHJhbnNpdGlvbiByYXRlcyBpbiB1bml0cyBvZiB5ZWFyc14tMQ0KcGFyYW1ldGVycyA8LSBjKGJldGEgPSAwLjQqMzY1LCAgICAgICMgdGhlIGluZmVjdGlvbiByYXRlLCB3aGljaCBhY3RzIG9uIHN1c2NlcHRpYmxlcw0KICAgICAgICAgICAgICAgIGdhbW1hID0gMC4yKjM2NSwgICAgICMgdGhlIHJhdGUgb2YgcmVjb3ZlcnksIHdoaWNoIGFjdHMgb24gdGhvc2UgaW5mZWN0ZWQNCiAgICAgICAgICAgICAgICBzaWdtYSA9IDEvMC41KSAgICAgICAgIyB0aGUgcmF0ZSBvZiB3YW5pbmcgb2YgaW1tdW5pdHksIHdoaWNoIGFjdHMgb24gdGhvc2UgcmVjb3ZlcmVkIA0KDQojIFRJTUVTVEVQUzoNCg0KIyBWZWN0b3Igc3RvcmluZyB0aGUgc2VxdWVuY2Ugb2YgdGltZXN0ZXBzIHRvIHNvbHZlIHRoZSBtb2RlbCBhdA0KdGltZXMgPC0gc2VxKGZyb20gPSAwLCB0byA9IDUsIGJ5ID0gMi8zNjUpICAgIyBmcm9tIDAgdG8gNSB5ZWFycyBpbiB0aW1lc3RlcHMgb2YgZXZlcnkgMiBkYXlzDQoNCiMgTU9ERUwgT1VUUFVUIChzb2x2aW5nIHRoZSBkaWZmZXJlbnRpYWwgZXF1YXRpb25zKToNCg0KIyBTb2x2aW5nIHRoZSBkaWZmZXJlbnRpYWwgZXF1YXRpb25zIHVzaW5nIHRoZSBvZGUgaW50ZWdyYXRpb24gYWxnb3JpdGhtDQpvdXRwdXQgPC0gYXMuZGF0YS5mcmFtZShvZGUoeSA9IGluaXRpYWxfc3RhdGVfdmFsdWVzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IHRpbWVzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jID0gc2lyX21vZGVsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcm1zID0gcGFyYW1ldGVycykpDQoNCm91dHB1dF9sb25nIDwtIG1lbHQoYXMuZGF0YS5mcmFtZShvdXRwdXQpLCBpZCA9ICJ0aW1lIikgICAgICAgICAgICAgICAgICAjIHR1cm4gb3V0cHV0IGRhdGFzZXQgaW50byBsb25nIGZvcm1hdA0KDQojIEFkZGluZyBhIGNvbHVtbiBmb3IgdGhlIHByZXZhbGVuY2UgcHJvcG9ydGlvbiB0byB0aGUgbG9uZy1mb3JtYXQgb3V0cHV0DQpvdXRwdXRfbG9uZyRwcmV2YWxlbmNlIDwtIG91dHB1dF9sb25nJHZhbHVlL3N1bShpbml0aWFsX3N0YXRlX3ZhbHVlcykNCg0KIyBQbG90IHRoZSBwcmV2YWxlbmNlIHByb3BvcnRpb24NCmdncGxvdChkYXRhID0gb3V0cHV0X2xvbmcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNwZWNpZnkgb2JqZWN0IGNvbnRhaW5pbmcgZGF0YSB0byBwbG90DQogICAgICAgYWVzKHggPSB0aW1lLCB5ID0gcHJldmFsZW5jZSwgY29sb3VyID0gdmFyaWFibGUsIGdyb3VwID0gdmFyaWFibGUpKSArICAjIGFzc2lnbiBjb2x1bW5zIHRvIGF4ZXMgYW5kIGdyb3Vwcw0KICBnZW9tX2xpbmUoKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcmVwcmVzZW50IGRhdGEgYXMgbGluZXMNCiAgeGxhYigiVGltZSAoeWVhcnMpIikrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgbGFiZWwgZm9yIHggYXhpcw0KICB5bGFiKCJQcmV2YWxlbmNlIChwcm9wb3J0aW9uKSIpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRkIGxhYmVsIGZvciB5IGF4aXMNCiAgbGFicyhjb2xvdXIgPSAiQ29tcGFydG1lbnQiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkZCBsZWdlbmQgdGl0bGUNCiAgICAgICB0aXRsZSA9ICJQcmV2YWxlbmNlIG9mIGluZmVjdGlvbiwgc3VzY2VwdGliaWxpdHkgYW5kIHJlY292ZXJ5IG92ZXIgdGltZVxuc2lnbWEgPSAyIHllYXJzXi0xIikgICAjIGFkZCBwbG90IHRpdGxlICAgIA0KYGBgDQoNCg0KDQojIyMgV2hhdCBkbyB5b3Ugb2JzZXJ2ZSBhYm91dCB0aGUgaW5mZWN0aW9uIGR5bmFtaWNzPyBIb3cgZG9lcyB0aGlzIGNvbXBhcmUgdG8gdGhlIG1vZGVsIHdpdGggc2xvdyB3YW5pbmcgb2YgaW1tdW5pdHksIGFuZCB3aXRoIHBvcHVsYXRpb24gdHVybm92ZXI/DQoNClRoZSBvdXRjb21lIHVuZGVyIHRoZXNlIGFzc3VtcHRpb25zIGlzIHZlcnkgc2ltaWxhciB0byB3aGF0IHdlIG9ic2VydmVkIHdoZW4gbW9kZWxsaW5nIGFuIGFjdXRlIGRpc2Vhc2UgaW4gdGhlIHBpZyBwb3B1bGF0aW9uIHdpdGggZmFzdCBwb3B1bGF0aW9uIHR1cm5vdmVyLiBUaGUgaW5mZWN0aW9uIHF1aWNrbHkgcmVhY2hlcyBhbiBlbmRlbWljIGVxdWlsaWJyaXVtIHdpdGggdGhlIGVmZmVjdGl2ZSByZXByb2R1Y3Rpb24gbnVtYmVyIHN0YXlpbmcgc3RhYmxlIGF0IGp1c3Qgb3ZlciAxLCBiZWNhdXNlIGp1c3QgYXMgaW4gdGhlIHBpZyBwb3B1bGF0aW9uLCB0aGUgcG9vbCBvZiBzdXNjZXB0aWJsZXMgaXMgY29udGludWFsbHkgcmVwbGVuaXNoZWQuDQoNCkFzIHlvdSBjYW4gc2VlIGZyb20gYm90aCB0aGVzZSBleGFtcGxlcywgd2FuaW5nIGltbXVuaXR5IGFjdHMgaW4gYSBzaW1pbGFyIHdheSB0byB0aGUgYmlydGggcmF0ZSBpbiB0aGUgU0lSIG1vZGVsIGR5bmFtaWNzLiANCg0KKipDaGFuZ2luZyB0aGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXMgdG8gcmVmbGVjdCBlbmRlbWljaXR5OioqDQoNCmBgYHtyfQ0KIyBWZWN0b3Igc3RvcmluZyB0aGUgaW5pdGlhbCBudW1iZXIgb2YgcGVvcGxlIGluIGVhY2ggY29tcGFydG1lbnQgKGF0IHRpbWVzdGVwIDApDQppbml0aWFsX3N0YXRlX3ZhbHVlcyA8LSBjKFMgPSAwLjMqMTAwMDAwMCwgICMgMzAlIG9mIHRoZSBwb3B1bGF0aW9uIGFyZSBzdXNjZXB0aWJsZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBJID0gMC4xKjEwMDAwMDAsICAjIDEwJSBvZiB0aGUgcG9wdWxhdGlvbiBhcmUgaW5mZWN0ZWQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgUiA9IDAuNioxMDAwMDAwKSAgIyA2MCUgb2YgdGhlIHBvcHVsYXRpb24gYXJlIGltbXVuZQ0KDQojIFZlY3RvciBzdG9yaW5nIHRoZSBwYXJhbWV0ZXJzIGRlc2NyaWJpbmcgdGhlIHRyYW5zaXRpb24gcmF0ZXMgaW4gdW5pdHMgb2YgeWVhcnNeLTENCnBhcmFtZXRlcnMgPC0gYyhiZXRhID0gMC40KjM2NSwgICAgICAjIHRoZSBpbmZlY3Rpb24gcmF0ZSwgd2hpY2ggYWN0cyBvbiBzdXNjZXB0aWJsZXMNCiAgICAgICAgICAgICAgICBnYW1tYSA9IDAuMiozNjUsICAgICAjIHRoZSByYXRlIG9mIHJlY292ZXJ5LCB3aGljaCBhY3RzIG9uIHRob3NlIGluZmVjdGVkDQogICAgICAgICAgICAgICAgc2lnbWEgPSAxLzAuNSkgICAgICAgICMgdGhlIHJhdGUgb2Ygd2FuaW5nIG9mIGltbXVuaXR5LCB3aGljaCBhY3RzIG9uIHRob3NlIHJlY292ZXJlZCANCg0KIyBUSU1FU1RFUFM6DQoNCiMgVmVjdG9yIHN0b3JpbmcgdGhlIHNlcXVlbmNlIG9mIHRpbWVzdGVwcyB0byBzb2x2ZSB0aGUgbW9kZWwgYXQNCnRpbWVzIDwtIHNlcShmcm9tID0gMCwgdG8gPSA1LCBieSA9IDIvMzY1KSAgICMgZnJvbSAwIHRvIDUgeWVhcnMgaW4gdGltZXN0ZXBzIG9mIGV2ZXJ5IDIgZGF5cw0KDQojIE1PREVMIE9VVFBVVCAoc29sdmluZyB0aGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyk6DQoNCiMgU29sdmluZyB0aGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyB1c2luZyB0aGUgb2RlIGludGVncmF0aW9uIGFsZ29yaXRobQ0Kb3V0cHV0IDwtIGFzLmRhdGEuZnJhbWUob2RlKHkgPSBpbml0aWFsX3N0YXRlX3ZhbHVlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSB0aW1lcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuYyA9IHNpcl9tb2RlbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJtcyA9IHBhcmFtZXRlcnMpKQ0KDQpvdXRwdXRfbG9uZyA8LSBtZWx0KGFzLmRhdGEuZnJhbWUob3V0cHV0KSwgaWQgPSAidGltZSIpICAgICAgICAgICAgICAgICAgIyB0dXJuIG91dHB1dCBkYXRhc2V0IGludG8gbG9uZyBmb3JtYXQNCg0KIyBBZGRpbmcgYSBjb2x1bW4gZm9yIHRoZSBwcmV2YWxlbmNlIHByb3BvcnRpb24gdG8gdGhlIGxvbmctZm9ybWF0IG91dHB1dA0Kb3V0cHV0X2xvbmckcHJldmFsZW5jZSA8LSBvdXRwdXRfbG9uZyR2YWx1ZS9zdW0oaW5pdGlhbF9zdGF0ZV92YWx1ZXMpDQoNCiMgUGxvdCB0aGUgcHJldmFsZW5jZSBwcm9wb3J0aW9uDQpnZ3Bsb3QoZGF0YSA9IG91dHB1dF9sb25nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IG9iamVjdCBjb250YWluaW5nIGRhdGEgdG8gcGxvdA0KICAgICAgIGFlcyh4ID0gdGltZSwgeSA9IHByZXZhbGVuY2UsIGNvbG91ciA9IHZhcmlhYmxlLCBncm91cCA9IHZhcmlhYmxlKSkgKyAgIyBhc3NpZ24gY29sdW1ucyB0byBheGVzIGFuZCBncm91cHMNCiAgZ2VvbV9saW5lKCkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJlcHJlc2VudCBkYXRhIGFzIGxpbmVzDQogIHhsYWIoIlRpbWUgKHllYXJzKSIpKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRkIGxhYmVsIGZvciB4IGF4aXMNCiAgeWxhYigiUHJldmFsZW5jZSAocHJvcG9ydGlvbikiKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkZCBsYWJlbCBmb3IgeSBheGlzDQogIGxhYnMoY29sb3VyID0gIkNvbXBhcnRtZW50IiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgbGVnZW5kIHRpdGxlDQogICAgICAgdGl0bGUgPSAiUHJldmFsZW5jZSBvZiBpbmZlY3Rpb24sIHN1c2NlcHRpYmlsaXR5IGFuZCByZWNvdmVyeSBvdmVyIHRpbWVcbnNpZ21hID0gMiB5ZWFyc14tMSIpICAgIyBhZGQgcGxvdCB0aXRsZSAgICANCmBgYA0KDQoNCiMjIyBXaGF0IGRvIHlvdSBvYnNlcnZlIGFib3V0IHRoZSBpbmZlY3Rpb24gZHluYW1pY3MgaWYgeW91IGNoYW5nZSB0aGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXM/DQoNCkFzIHlvdSBjYW4gc2VlLCB0aGUgc3lzdGVtIGV2ZW50dWFsbHkgc3RhYmlsaXNlcyBhdCB0aGUgc2FtZSB2YWx1ZXMgYXMgaW4gdGhlIHByZXZpb3VzIGV4YW1wbGUgd2hlcmUgd2UgYXNzdW1lZCBpbnRyb2R1Y3Rpb24gb2YgYSBzaW5nbGUgaW5mZWN0ZWQgY2FzZSAoYWx0aG91Z2ggb3ZlciBhIHNsaWdodGx5IGRpZmZlcmVudCB0aW1lc2NhbGUpLiBHZW5lcmFsbHkgaWYgd2UgYXJlIG1vZGVsbGluZyBhbiBlbmRlbWljIGluZmVjdGlvbiwgd2l0aCBhIGNvbWJpbmF0aW9uIG9mIHBhcmFtZXRlcnMgdGhhdCBsZWFkcyB0byBhIGNvbnRpbnVvdXMgYWRkaXRpb24gb2YgbmV3IHN1c2NlcHRpYmxlcyBhbmQgcmVhY2hlcyBhbiBlbmRlbWljIGVxdWlsaWJyaXVtLCB0aGUgaW5pdGlhbCBudW1iZXIgaW4gdGhlIGNvbXBhcnRtZW50cyB3ZSBzdGFydCBvZmYgd2l0aCBkb2VzIG5vdCBhZmZlY3QgdGhlIGVuZGVtaWMgcHJldmFsZW5jZSB0aGF0IGlzIGV2ZW50dWFsbHkgcmVhY2hlZCAoYXMgbG9uZyBhcyB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgaW5mZWN0ZWQgcGVyc29uLCBvZiBjb3Vyc2UpIQ0KDQpUaGlzIGlzIGluIGNvbnRyYXN0IHRvIHdoYXQgeW91IHNhdyBpbiB0aGUgcHJldmlvdXMgZXRpdml0eSwgd2hlcmUgY2hhbmdpbmcgdGhlIGluaXRpYWwgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbiB0aGF0IHdhcyBzdXNjZXB0aWJsZSBkZXRlcm1pbmVkIHdoZXRoZXIgYW4gZXBpZGVtaWMgd291bGQgb2NjdXIgb3Igbm90IQ0K