The R framework has (strictly speaking) no abilities to
perform survival analysis. The survival package fill in this
gap. You can also perform “modern” graphics using the survminer
package. To be able to use them, you must load it each time your launch
a new session by invoking
install.packages(c("survival", "survminer"))##need to be done once
library(survival)
library(survminer)
Loading required package: ggplot2
Loading required package: ggpubr
Attaching package: ‘survminer’
The following object is masked from ‘package:survival’:
myeloma
One main characteristics of survival data is censoring. How
to deal with such data using the survival package?
The main function to handle such data is the Surv function
which apparently is doing nothing except that now data belongs to the
class Surv. It is thus mandatory to use it extensively in your
analysis. A typical use is
duration <- 1:5##this are your observed duration eventually right censored
delta <- c(0, 1, 1, 1, 0)##this the binary vector specifying if an observation is right censored or not (0: censored, 1: event)
Surv(duration, delta)
[1] 1+ 2 3 4 5+
1. Generator fans
We are going to work with the genfan data included in the
survival package.
- Load the data genfan and have a look at its documentation.
- Read the documentation of the survfit function to be sure
how to use it properly.
- Fit a survival curve using the Kaplan–Meier estimator.
- What are the outputs of the summary and print
functions when applied to your just fitted Kaplan–Meier estimates?
- What about the ggsurvplot function?
2. Motor insulation
We are now going to work with the imotor data included in
the survival package.
- Load the data imotor and have a look at its
documentation.
- For each temperature, fit a survival function using the Kaplan–Meier
estimator.
- If, in the previous question, you make several call to the
survfit function, try to make use of an R formula to
do it in a single call.
- Analyze the outputs of the summary and print
functions when applied to your just fitted Kaplan–Meier estimates?
- Plot the estimated survival curves (you may want to pass
conf.int = 0.95 to get confidence intervals)
3. Confidence intervals
Recall that a widely use confidence interval for some parameter \(\theta\) is a symmetric one which is
typically of the form \[
\left[\hat{\theta} - z_{1 - \alpha / 2}
\sqrt{\mbox{Var}(\hat{\theta})}, \hat{\theta} - z_{1 - \alpha /
2} \sqrt{\mbox{Var}(\hat{\theta})} \right],
\]
where \(\hat{\theta}\) is an estimator
of \(\theta\) which is supposed here to
be at least asymptotically normal and whose standard error is \(\sqrt{\mbox{Var}(\hat{\theta})}\).
- Have a look at the lecture note about confidence intervals for
survival curves and make sure you understand why we introduce the
*log-log survivor ship.
- Have a look at the argument of the survfit function and
learn how to use it.
- On the imotor data set, compare the different type of
confidence intervals.
5. How dumb see survivals? (Optional)
In this exercise, we are going to see what happens if we were very
dumb and completely ignore censoring. To this aim we will work on
simulated data to “know the truth” (and thus see how dumb we are!).
Recall that right censoring corresponds to the situation where
we observe realizations from the random variable \[T = \min(C, T_*),\] where \(C\) is a random variable related to
censoring and \(T_*\) is the time to
failure (and only the latter is of interest). Throughout this exercise,
we will assume that both \(T_*\) and
\(C\) have an exponential distribution
with parameter \(\lambda_*\) and \(\lambda_c\) respectively and \(C\) and \(T_*\) are independent.
Without loss of generality, in our simulation study, we will assume
that \(\lambda_c = 1\) and will only
vary \(\lambda_*\).
- Generate 100 independent realizations of \(T\) with a \(\lambda_*\) value of your choice and make
sure to keep track of the indicator variable indicating censoring.
- Estimate the survival curve on this data set and compare it to the
true one.
- Estimate the survival curve ignoring censoring, i.e., we have no
censored observation, and compare it to the theoretical surrvival
curve.
- Play a bit with the value of \(\lambda_*\) to see how it impacts results
and number of censored observations. Try to make sense of it.
- We now turn to a theoretical derivation of what we experienced.
- What is the distribution of \(T\)?
*Hint: You may want to compute its survivor function
- What is the probability of being censored?
- Are those results in agreement with your conclusions?
- We now switch back to simulation and focus on median survival time.
- Learn how to retrieve the median survival time estimate using the
quantile function. *{Hint: you may want to have a look at the
documentation of quantile.survfit
- Generate a bunch of samples of size 100, say \(N\), and estimate the mean square error for
the median survival time, i.e., \[\widehat{MSE}(\lambda_*) = \frac{1}{N}
\sum_{i=1}^N \left(\hat t_{0.5,i}
- \frac{\log 2}{\lambda_*} \right)^2,
\] where \(\hat t_{0.5,i}\) is
the estimated median survival time for the \(i\)–th sample and \(\log 2 / \lambda_*\) is the theoretical one
(check it!).
- Plot the evolution of these mean square error as \(\lambda_*\) changes for both the smart way,
i.e., taking into account censoring, and the dumb way, i.e., ignoring
censoring.
6. Tongue cancer
A study was conducted on the effects of ploidy on the prognosis of
patients with cancers of the mouth. Patients were selected who had a
paraffin-embedded sample of the cancerous tissue taken at the time of
surgery. Follow-up survival data was obtained on each patient. The
tissue samples were examined using a flow cytometer to determine if the
tumor had an aneuploid (abnormal) or diploid (normal) DNA profile using
a technique discussed in Sickle–Santanello et al. (1988). Times are in
weeks.
- The dataset is available from the KMsurv package under the
name *tongue. (You may want to install it and load the library)
- Is there an impact of the tumour DNA profile in survival?
7. Cox’s regression: the basics
In this exercise we will learn how to make use of the *Cox’s
proportional hazards model.
- Have a look at the documentation of the coxph function and
make sure you understand its basic use.
- Does it make sense to use Cox’s model on the genfan data
set?
- Run the following piece of code and try to understand what’s going
on:
fit <- coxph(Surv(hours, status) ~ 1, data = genfan)
fit
Call: coxph(formula = Surv(hours, status) ~ 1, data = genfan)
Null model
log likelihood= -45.45218
n= 70
plot(survfit(fit))

- We now focus on the imotor dataset. Using Cox’s model, how
would you check if the temperature has an impact on survival? Is this in
agreement with the log-rank test?
- Read the documentation of the residuals.coxph function and
make sure to make the connection with the lecture notes.
- Perform a residual analysis to check if everything is OK with your
fitted model. Hint: the function lowess might be
useful to plot a local polynomial curve to your scatterplots.
- Read the documentation of the function cox.zph and use it
to assess whether the proportional hazards assumption is sensible on the
imotor dataset.
- Predict the survival for temperature of \(250, 280\) and \(310\). *Hint: we already saw how to predict
survival curve from a fitted Cox’s model in this exercise
8. Start working on your project (if grading is about project not
exam)
This exercise is a actually not an exercise but explain the
expectation for grading this lecture. You will have to conduct a whole
survival analysis on a dataset chosen from the ones listed below. You
should write a technical report (and include your R script as a
separate file) and upload it using the dedicated place on
Hippocampus.
- melanoma, available from the boot package,
consists of measurements made on patients with malignant melanoma;
- bfeed, available from the KMsurv package, consists
of the information from 927 first–born children to mothers who chose to
breast feed their children;
- burn, available from the KMsurv package, consists
of measurements made on burn patients and the time until staphylococcus
infection was recorded (in addition to other features);
- a dataset of your choice which is ``more related to your future
job’’ ;-)
LS0tCnRpdGxlOiAiU3Vydml2YWwgYW5hbHlzaXMgd2l0aCBSIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKClRoZSAqUiogZnJhbWV3b3JrIGhhcyAoc3RyaWN0bHkgc3BlYWtpbmcpIG5vIGFiaWxpdGllcyB0bwpwZXJmb3JtIHN1cnZpdmFsIGFuYWx5c2lzLiBUaGUgKnN1cnZpdmFsKiBwYWNrYWdlIGZpbGwgaW4gdGhpcwpnYXAuIFlvdSBjYW4gYWxzbyBwZXJmb3JtICJtb2Rlcm4iIGdyYXBoaWNzIHVzaW5nIHRoZSAqc3Vydm1pbmVyKiBwYWNrYWdlLiBUbyBiZSBhYmxlIHRvIHVzZSB0aGVtLCB5b3UgbXVzdCBsb2FkIGl0IGVhY2ggdGltZSB5b3VyIGxhdW5jaCBhCm5ldyBzZXNzaW9uIGJ5IGludm9raW5nCmBgYHtyIGV2YWw9RkFMU0V9Cmluc3RhbGwucGFja2FnZXMoYygic3Vydml2YWwiLCAic3Vydm1pbmVyIikpIyNuZWVkIHRvIGJlIGRvbmUgb25jZQpgYGAKCgpgYGB7cn0KbGlicmFyeShzdXJ2aXZhbCkKbGlicmFyeShzdXJ2bWluZXIpCmBgYAoKT25lIG1haW4gY2hhcmFjdGVyaXN0aWNzIG9mIHN1cnZpdmFsIGRhdGEgaXMgKmNlbnNvcmluZyouIEhvdyB0bwpkZWFsIHdpdGggc3VjaCBkYXRhIHVzaW5nIHRoZSAqc3Vydml2YWwqIHBhY2thZ2U/CgpUaGUgbWFpbiBmdW5jdGlvbiB0byBoYW5kbGUgc3VjaCBkYXRhIGlzIHRoZSAqU3VydiogZnVuY3Rpb24Kd2hpY2ggYXBwYXJlbnRseSBpcyBkb2luZyBub3RoaW5nIGV4Y2VwdCB0aGF0IG5vdyBkYXRhIGJlbG9uZ3MgdG8gdGhlCmNsYXNzICpTdXJ2Ki4gSXQgaXMgdGh1cyBtYW5kYXRvcnkgdG8gdXNlIGl0IGV4dGVuc2l2ZWx5IGluCnlvdXIgYW5hbHlzaXMuIEEgdHlwaWNhbCB1c2UgaXMKYGBge3J9CmR1cmF0aW9uIDwtIDE6NSMjdGhpcyBhcmUgeW91ciBvYnNlcnZlZCBkdXJhdGlvbiBldmVudHVhbGx5IHJpZ2h0IGNlbnNvcmVkCmRlbHRhIDwtIGMoMCwgMSwgMSwgMSwgMCkjI3RoaXMgdGhlIGJpbmFyeSB2ZWN0b3Igc3BlY2lmeWluZyBpZiBhbiBvYnNlcnZhdGlvbiBpcyByaWdodCBjZW5zb3JlZCBvciBub3QgKDA6IGNlbnNvcmVkLCAxOiBldmVudCkKU3VydihkdXJhdGlvbiwgZGVsdGEpCmBgYAoKCiMjIDEuIEdlbmVyYXRvciBmYW5zCgpXZSBhcmUgZ29pbmcgdG8gd29yayB3aXRoIHRoZSAqZ2VuZmFuKiBkYXRhIGluY2x1ZGVkIGluIHRoZSAqc3Vydml2YWwqIHBhY2thZ2UuCgogICsgTG9hZCB0aGUgZGF0YSBnZW5mYW4gYW5kIGhhdmUgYSBsb29rIGF0IGl0cyBkb2N1bWVudGF0aW9uLgogICsgUmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgKnN1cnZmaXQqIGZ1bmN0aW9uIHRvIGJlIHN1cmUgaG93IHRvIHVzZSBpdCBwcm9wZXJseS4KICArIEZpdCBhIHN1cnZpdmFsIGN1cnZlIHVzaW5nIHRoZSBLYXBsYW4tLU1laWVyIGVzdGltYXRvci4KICArIFdoYXQgYXJlIHRoZSBvdXRwdXRzIG9mIHRoZSAqc3VtbWFyeSogYW5kICpwcmludCogZnVuY3Rpb25zIHdoZW4gYXBwbGllZCB0byB5b3VyIGp1c3QgZml0dGVkIEthcGxhbi0tTWVpZXIgZXN0aW1hdGVzPwogICsgV2hhdCBhYm91dCB0aGUgKmdnc3VydnBsb3QqIGZ1bmN0aW9uPwoKIyMjIDIuIE1vdG9yIGluc3VsYXRpb24KCldlIGFyZSBub3cgZ29pbmcgdG8gd29yayB3aXRoIHRoZSAqaW1vdG9yKiBkYXRhIGluY2x1ZGVkIGluIHRoZSAqc3Vydml2YWwqIHBhY2thZ2UuCgogICsgTG9hZCB0aGUgZGF0YSAqaW1vdG9yKiBhbmQgaGF2ZSBhIGxvb2sgYXQgaXRzIGRvY3VtZW50YXRpb24uCiAgKyBGb3IgZWFjaCB0ZW1wZXJhdHVyZSwgZml0IGEgc3Vydml2YWwgZnVuY3Rpb24gdXNpbmcgdGhlIEthcGxhbi0tTWVpZXIgZXN0aW1hdG9yLgogICsgSWYsIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbiwgeW91IG1ha2Ugc2V2ZXJhbCBjYWxsIHRvIHRoZSAqc3VydmZpdCogZnVuY3Rpb24sIHRyeSB0byBtYWtlIHVzZSBvZiBhbiAqUiBmb3JtdWxhKiB0byBkbyBpdCBpbiBhIHNpbmdsZSBjYWxsLgogICsgQW5hbHl6ZSB0aGUgb3V0cHV0cyBvZiB0aGUgKnN1bW1hcnkqIGFuZCAqcHJpbnQqIGZ1bmN0aW9ucyB3aGVuIGFwcGxpZWQgdG8geW91ciBqdXN0IGZpdHRlZCBLYXBsYW4tLU1laWVyIGVzdGltYXRlcz8KICArIFBsb3QgdGhlIGVzdGltYXRlZCBzdXJ2aXZhbCBjdXJ2ZXMgKHlvdSBtYXkgd2FudCB0byBwYXNzICpjb25mLmludCA9IDAuOTUqIHRvIGdldCBjb25maWRlbmNlIGludGVydmFscykKICAKIyMgMy4gQ29uZmlkZW5jZSBpbnRlcnZhbHMKClJlY2FsbCB0aGF0IGEgd2lkZWx5IHVzZSBjb25maWRlbmNlIGludGVydmFsIGZvciBzb21lIHBhcmFtZXRlciAkXHRoZXRhJCBpcyBhIHN5bW1ldHJpYyBvbmUgd2hpY2ggaXMgdHlwaWNhbGx5IG9mIHRoZSBmb3JtCiQkClxsZWZ0W1xoYXR7XHRoZXRhfSAtIHpfezEgLSBcYWxwaGEgLyAyfQogICAgICBcc3FydHtcbWJveHtWYXJ9KFxoYXR7XHRoZXRhfSl9LCBcaGF0e1x0aGV0YX0gLSB6X3sxIC0gXGFscGhhIC8KICAgICAgICAyfSBcc3FydHtcbWJveHtWYXJ9KFxoYXR7XHRoZXRhfSl9IFxyaWdodF0sCiQkICAKd2hlcmUgJFxoYXR7XHRoZXRhfSQgaXMgYW4gZXN0aW1hdG9yIG9mICRcdGhldGEkIHdoaWNoIGlzIHN1cHBvc2VkIGhlcmUgdG8gYmUgYXQgbGVhc3QgYXN5bXB0b3RpY2FsbHkgbm9ybWFsIGFuZCB3aG9zZSBzdGFuZGFyZCBlcnJvciBpcyAkXHNxcnR7XG1ib3h7VmFyfShcaGF0e1x0aGV0YX0pfSQuCgogICsgSGF2ZSBhIGxvb2sgYXQgdGhlIGxlY3R1cmUgbm90ZSBhYm91dCBjb25maWRlbmNlIGludGVydmFscyBmb3Igc3Vydml2YWwgY3VydmVzIGFuZCBtYWtlIHN1cmUgeW91IHVuZGVyc3RhbmQgd2h5IHdlIGludHJvZHVjZSB0aGUgKmxvZy1sb2cgc3Vydml2b3Igc2hpcC4KICArIEhhdmUgYSBsb29rIGF0IHRoZSBcdGV4dHR0e2NvbmYudHlwZX0gYXJndW1lbnQgb2YgdGhlICpzdXJ2Zml0KiBmdW5jdGlvbiBhbmQgbGVhcm4gaG93IHRvIHVzZSBpdC4KICArIE9uIHRoZSAqaW1vdG9yKiBkYXRhIHNldCwgY29tcGFyZSB0aGUgZGlmZmVyZW50IHR5cGUgb2YgY29uZmlkZW5jZSBpbnRlcnZhbHMuCiAgCiMjIDUuIEhvdyBkdW1iIHNlZSBzdXJ2aXZhbHM/IChPcHRpb25hbCkKCkluIHRoaXMgZXhlcmNpc2UsIHdlIGFyZSBnb2luZyB0byBzZWUgd2hhdCBoYXBwZW5zIGlmIHdlIHdlcmUgdmVyeSBkdW1iIGFuZCBjb21wbGV0ZWx5IGlnbm9yZSBjZW5zb3JpbmcuIFRvIHRoaXMgYWltIHdlIHdpbGwgd29yayBvbiBzaW11bGF0ZWQgZGF0YSB0byAia25vdyB0aGUgdHJ1dGgiIChhbmQgdGh1cyBzZWUgaG93IGR1bWIgd2UgYXJlISkuIFJlY2FsbCB0aGF0ICpyaWdodCBjZW5zb3JpbmcqIGNvcnJlc3BvbmRzIHRvIHRoZSBzaXR1YXRpb24gd2hlcmUgd2Ugb2JzZXJ2ZSByZWFsaXphdGlvbnMgZnJvbSB0aGUgcmFuZG9tIHZhcmlhYmxlCiQkVCA9IFxtaW4oQywgVF8qKSwkJAp3aGVyZSAkQyQgaXMgYSByYW5kb20gdmFyaWFibGUgcmVsYXRlZCB0byBjZW5zb3JpbmcgYW5kICRUXyokIGlzIHRoZSB0aW1lIHRvIGZhaWx1cmUgKGFuZCBvbmx5IHRoZSBsYXR0ZXIgaXMgb2YgaW50ZXJlc3QpLiBUaHJvdWdob3V0IHRoaXMgZXhlcmNpc2UsIHdlIHdpbGwgYXNzdW1lIHRoYXQgYm90aCAkVF8qJCBhbmQgJEMkIGhhdmUgYW4gZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uIHdpdGggcGFyYW1ldGVyICRcbGFtYmRhXyokIGFuZCAkXGxhbWJkYV9jJCByZXNwZWN0aXZlbHkgYW5kICRDJCBhbmQgJFRfKiQgYXJlIGluZGVwZW5kZW50LgoKV2l0aG91dCBsb3NzIG9mIGdlbmVyYWxpdHksIGluIG91ciBzaW11bGF0aW9uIHN0dWR5LCB3ZSB3aWxsIGFzc3VtZSB0aGF0ICRcbGFtYmRhX2MgPSAxJCBhbmQgd2lsbCBvbmx5IHZhcnkgJFxsYW1iZGFfKiQuCgogICsgR2VuZXJhdGUgMTAwIGluZGVwZW5kZW50IHJlYWxpemF0aW9ucyBvZiAkVCQgd2l0aCBhICRcbGFtYmRhXyokIHZhbHVlIG9mIHlvdXIgY2hvaWNlIGFuZCBtYWtlIHN1cmUgdG8ga2VlcCB0cmFjayBvZiB0aGUgaW5kaWNhdG9yIHZhcmlhYmxlIGluZGljYXRpbmcgY2Vuc29yaW5nLgogICsgRXN0aW1hdGUgdGhlIHN1cnZpdmFsIGN1cnZlIG9uIHRoaXMgZGF0YSBzZXQgYW5kIGNvbXBhcmUgaXQgdG8gdGhlIHRydWUgb25lLgogICsgRXN0aW1hdGUgdGhlIHN1cnZpdmFsIGN1cnZlIGlnbm9yaW5nIGNlbnNvcmluZywgaS5lLiwgd2UgaGF2ZSAgbm8gY2Vuc29yZWQgb2JzZXJ2YXRpb24sIGFuZCBjb21wYXJlIGl0IHRvIHRoZSB0aGVvcmV0aWNhbCBzdXJydml2YWwgY3VydmUuCiAgKyBQbGF5IGEgYml0IHdpdGggdGhlIHZhbHVlIG9mICRcbGFtYmRhXyokIHRvIHNlZSBob3cgaXQgaW1wYWN0cyByZXN1bHRzIGFuZCBudW1iZXIgb2YgY2Vuc29yZWQgb2JzZXJ2YXRpb25zLiBUcnkgdG8gbWFrZSBzZW5zZSBvZiBpdC4KICArIFdlIG5vdyB0dXJuIHRvIGEgdGhlb3JldGljYWwgZGVyaXZhdGlvbiBvZiB3aGF0IHdlIGV4cGVyaWVuY2VkLgogICAgLSBXaGF0IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgJFQkPyAqSGludDogWW91IG1heSB3YW50IHRvIGNvbXB1dGUgaXRzIHN1cnZpdm9yIGZ1bmN0aW9uXGxkb3RzKgogICAgLSBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBjZW5zb3JlZD8KICAgIC0gQXJlIHRob3NlIHJlc3VsdHMgaW4gYWdyZWVtZW50IHdpdGggeW91ciBjb25jbHVzaW9ucz8KICArIFdlIG5vdyBzd2l0Y2ggYmFjayB0byBzaW11bGF0aW9uIGFuZCBmb2N1cyBvbiBtZWRpYW4gc3Vydml2YWwgdGltZS4KICAgIC0gTGVhcm4gaG93IHRvIHJldHJpZXZlIHRoZSBtZWRpYW4gc3Vydml2YWwgdGltZSBlc3RpbWF0ZSB1c2luZyB0aGUgKnF1YW50aWxlKiBmdW5jdGlvbi4gKntIaW50OiB5b3UgbWF5IHdhbnQgdG8gaGF2ZSBhIGxvb2sgYXQgdGhlIGRvY3VtZW50YXRpb24gb2YgKipxdWFudGlsZS5zdXJ2Zml0KipcbGRvdHMqCiAgICAtIEdlbmVyYXRlIGEgYnVuY2ggb2Ygc2FtcGxlcyBvZiBzaXplIDEwMCwgc2F5ICROJCwgYW5kIGVzdGltYXRlIHRoZSBtZWFuIHNxdWFyZSBlcnJvciBmb3IgdGhlIG1lZGlhbiBzdXJ2aXZhbCB0aW1lLCBpLmUuLAogICAgJCRcd2lkZWhhdHtNU0V9KFxsYW1iZGFfKikgPSBcZnJhY3sxfXtOfSBcc3VtX3tpPTF9Xk4gXGxlZnQoXGhhdCB0X3swLjUsaX0KICAgICAgICAgIC0gXGZyYWN7XGxvZyAyfXtcbGFtYmRhXyp9IFxyaWdodCleMiwKICAgICQkCiAgICB3aGVyZSAkXGhhdCB0X3swLjUsaX0kIGlzIHRoZSBlc3RpbWF0ZWQgbWVkaWFuIHN1cnZpdmFsIHRpbWUgZm9yIHRoZSAkaSQtLXRoIHNhbXBsZSBhbmQgJFxsb2cgMiAvIFxsYW1iZGFfKiQgaXMgdGhlIHRoZW9yZXRpY2FsIG9uZSAoY2hlY2sgaXQhKS4KICAgIC0gUGxvdCB0aGUgZXZvbHV0aW9uIG9mIHRoZXNlIG1lYW4gc3F1YXJlIGVycm9yIGFzICRcbGFtYmRhXyokIGNoYW5nZXMgZm9yIGJvdGggdGhlIHNtYXJ0IHdheSwgaS5lLiwgdGFraW5nIGludG8gYWNjb3VudCBjZW5zb3JpbmcsIGFuZCB0aGUgZHVtYiB3YXksIGkuZS4sIGlnbm9yaW5nIGNlbnNvcmluZy4KCiMjIDYuIFRvbmd1ZSBjYW5jZXIKCkEgc3R1ZHkgd2FzIGNvbmR1Y3RlZCBvbiB0aGUgZWZmZWN0cyBvZiBwbG9pZHkgb24gdGhlIHByb2dub3NpcyBvZiBwYXRpZW50cyB3aXRoIGNhbmNlcnMgb2YgdGhlIG1vdXRoLiBQYXRpZW50cyB3ZXJlIHNlbGVjdGVkIHdobyBoYWQgYSBwYXJhZmZpbi1lbWJlZGRlZCBzYW1wbGUgb2YgdGhlIGNhbmNlcm91cyB0aXNzdWUgdGFrZW4gYXQgdGhlIHRpbWUgb2Ygc3VyZ2VyeS4gRm9sbG93LXVwIHN1cnZpdmFsIGRhdGEgd2FzIG9idGFpbmVkIG9uIGVhY2ggcGF0aWVudC4gVGhlIHRpc3N1ZSBzYW1wbGVzIHdlcmUgZXhhbWluZWQgdXNpbmcgYSBmbG93IGN5dG9tZXRlciB0byBkZXRlcm1pbmUgaWYgdGhlIHR1bW9yIGhhZCBhbiBhbmV1cGxvaWQgKGFibm9ybWFsKSBvciBkaXBsb2lkIChub3JtYWwpIEROQSBwcm9maWxlIHVzaW5nIGEgdGVjaG5pcXVlIGRpc2N1c3NlZCBpbiBTaWNrbGXigJNTYW50YW5lbGxvIGV0IGFsLiAoMTk4OCkuIFRpbWVzIGFyZSBpbiB3ZWVrcy4KCiAgKyBUaGUgZGF0YXNldCBpcyBhdmFpbGFibGUgZnJvbSB0aGUgKktNc3VydiogcGFja2FnZSB1bmRlciB0aGUgbmFtZSAqdG9uZ3VlLiAoWW91IG1heSB3YW50IHRvIGluc3RhbGwgaXQgYW5kIGxvYWQgdGhlIGxpYnJhcnkpCiAgKyBJcyB0aGVyZSBhbiBpbXBhY3Qgb2YgdGhlIHR1bW91ciBETkEgcHJvZmlsZSBpbiBzdXJ2aXZhbD8KCiMjIDcuIENveCdzIHJlZ3Jlc3Npb246IHRoZSBiYXNpY3MKCkluIHRoaXMgZXhlcmNpc2Ugd2Ugd2lsbCBsZWFybiBob3cgdG8gbWFrZSB1c2Ugb2YgdGhlICpDb3gncyBwcm9wb3J0aW9uYWwgaGF6YXJkcyBtb2RlbC4KCiAgKyBIYXZlIGEgbG9vayBhdCB0aGUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgKmNveHBoKiBmdW5jdGlvbiBhbmQgbWFrZSBzdXJlIHlvdSB1bmRlcnN0YW5kIGl0cyBiYXNpYyB1c2UuIAogICsgRG9lcyBpdCBtYWtlIHNlbnNlIHRvIHVzZSBDb3gncyBtb2RlbCBvbiB0aGUgKmdlbmZhbiogZGF0YSBzZXQ/CiAgKyBSdW4gdGhlIGZvbGxvd2luZyBwaWVjZSBvZiBjb2RlIGFuZCB0cnkgdG8gdW5kZXJzdGFuZCB3aGF0J3MgZ29pbmcgb246CmBgYHtyfQpmaXQgPC0gY294cGgoU3Vydihob3Vycywgc3RhdHVzKSB+IDEsIGRhdGEgPSBnZW5mYW4pCmZpdApwbG90KHN1cnZmaXQoZml0KSkKYGBgCiAgKyBXZSBub3cgZm9jdXMgb24gdGhlICppbW90b3IqIGRhdGFzZXQuIFVzaW5nIENveCdzIG1vZGVsLCBob3cgd291bGQgeW91IGNoZWNrIGlmIHRoZSB0ZW1wZXJhdHVyZSBoYXMgYW4gaW1wYWN0IG9uIHN1cnZpdmFsPyBJcyB0aGlzIGluIGFncmVlbWVudCB3aXRoIHRoZSBsb2ctcmFuayB0ZXN0PwogICsgUmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgKnJlc2lkdWFscy5jb3hwaCogZnVuY3Rpb24gYW5kIG1ha2Ugc3VyZSB0byBtYWtlIHRoZSBjb25uZWN0aW9uIHdpdGggdGhlIGxlY3R1cmUgbm90ZXMuCiAgKyBQZXJmb3JtIGEgcmVzaWR1YWwgYW5hbHlzaXMgdG8gY2hlY2sgaWYgZXZlcnl0aGluZyBpcyBPSyB3aXRoIHlvdXIgZml0dGVkIG1vZGVsLiAqSGludDogdGhlIGZ1bmN0aW9uICoqbG93ZXNzKiogbWlnaHQgYmUgdXNlZnVsIHRvIHBsb3QgYSBsb2NhbCBwb2x5bm9taWFsIGN1cnZlIHRvIHlvdXIgc2NhdHRlcnBsb3RzLioKICArIFJlYWQgdGhlIGRvY3VtZW50YXRpb24gb2YgdGhlIGZ1bmN0aW9uICpjb3guenBoKiBhbmQgdXNlIGl0IHRvIGFzc2VzcyB3aGV0aGVyIHRoZSBwcm9wb3J0aW9uYWwgaGF6YXJkcyBhc3N1bXB0aW9uIGlzIHNlbnNpYmxlIG9uIHRoZSAqaW1vdG9yKiBkYXRhc2V0LgogICsgUHJlZGljdCB0aGUgc3Vydml2YWwgZm9yIHRlbXBlcmF0dXJlIG9mICQyNTAsIDI4MCQgYW5kICQzMTAkLiAqSGludDogd2UgYWxyZWFkeSBzYXcgaG93IHRvIHByZWRpY3Qgc3Vydml2YWwgY3VydmUgZnJvbSBhIGZpdHRlZCBDb3gncyBtb2RlbCBpbiB0aGlzIGV4ZXJjaXNlXGxkb3RzKgoKIyMgOC4gU3RhcnQgd29ya2luZyBvbiB5b3VyIHByb2plY3QgKGlmIGdyYWRpbmcgaXMgYWJvdXQgcHJvamVjdCBub3QgZXhhbSkKClRoaXMgZXhlcmNpc2UgaXMgYSBhY3R1YWxseSBub3QgYW4gZXhlcmNpc2UgYnV0IGV4cGxhaW4gdGhlIGV4cGVjdGF0aW9uIGZvciBncmFkaW5nIHRoaXMgbGVjdHVyZS4gWW91IHdpbGwgaGF2ZSB0byBjb25kdWN0IGEgd2hvbGUgc3Vydml2YWwgYW5hbHlzaXMgb24gYSBkYXRhc2V0IGNob3NlbiBmcm9tIHRoZSBvbmVzIGxpc3RlZCBiZWxvdy4gWW91IHNob3VsZCB3cml0ZSBhIHRlY2huaWNhbCByZXBvcnQgKGFuZCBpbmNsdWRlIHlvdXIgKlIqIHNjcmlwdCBhcyBhIHNlcGFyYXRlIGZpbGUpIGFuZCB1cGxvYWQgaXQgdXNpbmcgdGhlIGRlZGljYXRlZCBwbGFjZSBvbiBIaXBwb2NhbXB1cy4KCiAgKyAqbWVsYW5vbWEqLCBhdmFpbGFibGUgZnJvbSB0aGUgKmJvb3QqIHBhY2thZ2UsIGNvbnNpc3RzIG9mIG1lYXN1cmVtZW50cyBtYWRlIG9uIHBhdGllbnRzIHdpdGggbWFsaWduYW50IG1lbGFub21hOwogICsgKmJmZWVkKiwgYXZhaWxhYmxlIGZyb20gdGhlICpLTXN1cnYqIHBhY2thZ2UsIGNvbnNpc3RzIG9mIHRoZSBpbmZvcm1hdGlvbiBmcm9tIDkyNyBmaXJzdC0tYm9ybiBjaGlsZHJlbiB0byBtb3RoZXJzIHdobyBjaG9zZSB0byBicmVhc3QgZmVlZCB0aGVpciBjaGlsZHJlbjsKICArICpidXJuKiwgYXZhaWxhYmxlIGZyb20gdGhlICpLTXN1cnYqIHBhY2thZ2UsIGNvbnNpc3RzIG9mIG1lYXN1cmVtZW50cyBtYWRlIG9uIGJ1cm4gcGF0aWVudHMgYW5kIHRoZSB0aW1lIHVudGlsIHN0YXBoeWxvY29jY3VzIGluZmVjdGlvbiB3YXMgcmVjb3JkZWQgKGluIGFkZGl0aW9uIHRvIG90aGVyIGZlYXR1cmVzKTsKICArIGEgZGF0YXNldCBvZiB5b3VyIGNob2ljZSB3aGljaCBpcyBgYG1vcmUgcmVsYXRlZCB0byB5b3VyIGZ1dHVyZSBqb2InJyA7LSk=