R Programs I used
library(readr) # read CSV files
library(tidyr) # data manipulation
library(dplyr)# data manipulation
library(lubridate)# timestamp data
library(ggplot2) # plots
library(plotly) # interactive plots
library(viridis) # color palettes
library(viridisLite)
Load Time-Varying Results
# Time-Varying Results
Time.Varing.Results <- read_csv("20190307-7007_hrv.csv",
skip = 148)
# Columns removed
Time.Varing.Results <- Time.Varing.Results[-c(1, 41)]
# Rows kept
Time.Varing.Results <- Time.Varing.Results[c(2:142890),]
# Renamed variables
Time.Varing.Results<-Time.Varing.Results %>%
rename(Artifact=`Artifact percentage`, PNS_index= `PNS index`, SNS_index=`SNS index`,Stress_index=`Stress index`,
Mean_RR=`Mean RR`, STD_RR= `STD RR`, Mean_HR=`Mean HR`, STD_HR= `STD HR`,Min_HR= `Min HR`, Max_HR=`Max HR`,
VLF_peak=`VLF peak`, LF_peak= `LF peak`,HF_peak= `HF peak`,VLF_power.ms2= `VLF power`,LF_power.ms2=`LF power`,
HF_powerms2=`HF power`, VLF_power.log= `VLF power_1`, LF_power.log=`LF power_1`,HF_power.log= `HF power_1`,VLF_power.per=`VLF power_2`,
LF_power.per= `LF power_2`,HF_power.per=`HF power_2`, LF_power.nu=`LF power_3`,HF_power.nu= `HF power_3`,LF_HF= `LF/HF ratio`,SD2_SD= `SD2/SD1`,
DFA_a1= `DFA a1`,DFA_a2=`DFA a2`)
# Check if data are coded as characters
sapply(Time.Varing.Results , class)
Time Artifact PNS_index SNS_index Stress_index Mean_RR STD_RR Mean_HR STD_HR Min_HR Max_HR
"character" "character" "numeric" "numeric" "numeric" "character" "character" "character" "character" "character" "character"
RMSSD NNxx pNNxx HRVti TINN VLF_peak LF_peak HF_peak VLF_power.ms2 LF_power.ms2 HF_powerms2
"character" "character" "character" "numeric" "character" "character" "character" "character" "character" "character" "character"
VLF_power.log LF_power.log HF_power.log VLF_power.per LF_power.per HF_power.per LF_power.nu HF_power.nu LF_HF EDR SD1
"character" "character" "character" "character" "character" "character" "character" "character" "numeric" "character" "character"
SD2 SD2_SD ApEn SampEn DFA_a1 DFA_a2
"character" "numeric" "numeric" "numeric" "numeric" "numeric"
Time & HRV data
Fundamentally, there are two types of data when using time-varying results: (1) HRV and (2) Time. The following code breaks down the file into these two types and then combines them into a single data frame. My usual program for timestamp data (lubridate) did not work. The time data did not parse time data into hours, minutes, and seconds for every row. Consequently, I made my time calculations of seconds and hours.
## HRV Data
HRV<-Time.Varing.Results %>%
select(Artifact:DFA_a2) %>%
mutate_if(is.character,as.numeric)
# Time Data
Time<-Time.Varing.Results %>%
select(Time)
# First,I created a vector called "Seconds." Because there are 142,889 observations and the sampling rate is in seconds,there are 142,889 seconds in this sample.
Seconds<-1:142889
Time<-cbind(Time,Seconds)
# Hours
Time<-Time %>%
mutate(Hours=Seconds/3600)
# Combined HRV & Time Data
Time.Varying.Data<-cbind(Time,HRV)
Heart Rate Data
At the root of all HRV variability statistics are the RR intervals. You can convert these RR intervals into beat-per-minute (bpm). I strongly recommend using this metric because it’s intuitive to most people and often used in many scientific disciplines.
I also created a new variable called “Threshold.” This variable helps determine when there was a deviation in heart rate. I defined this deviation empirically: 2 standard deviations above the mean. Feel free to use a different method if you find information in the literature that is more informative. Importantly, we can determine how long the event occurred by knowing when heart rate was above a defined threshold.
# Mean HR Histogram
Time.Varying.Data %>%
ggplot(aes(x=Mean_HR))+
geom_histogram(bins = 100,color = "black")+
theme_bw()+
labs(
title = "Mean HR",
y = "Count",
x = "bpm")

# Descriptive Statistics
Descriptives<-Time.Varying.Data %>%
summarise(mean=mean(Mean_HR),median=median(Mean_HR),
min=min(Mean_HR), max=max(Mean_HR),SD= sd(Mean_HR), n =n()) %>%
mutate(SD2= mean+(2*SD))
# Threshold
Time.Varying.Data<-Time.Varying.Data %>%
mutate(Threshold= ifelse(Mean_HR >=Descriptives$SD2,"Above","Normal"))
Ploting time-varying data using ggplot2
I strongly recommend plotting your heart rate (x = time, y = heart rate). You will be able to determine if a significant event occurred.
I prefer using ggplot2 program in R for data visualization. There are many online tutorials out there that are easy to follow. Plus, it is part of the tiddyverse (https://www.tidyverse.org) set of programs.
# Scatter plot: Heart Rate
Time.Varying.Data%>%
ggplot(aes(x=Hours, y=Mean_HR))+
geom_hline(yintercept=Descriptives$SD2, color ="red", linetype="dashed", alpha =.75)+
geom_hline(yintercept = Descriptives$mean, color ="green")+ # Mean
geom_line()+
theme_bw()+
annotate("text", label = "2 SD Above Mean", x = 3, y = 130, size = 4, color = "red")+
annotate("text", label = "Mean", x = 3, y = 60, size = 4, color = "darkgreen")+
ylim(40,200)+
labs(
title = "Time & Mean HR",
y = "bpm",
x = "Hours")

# Scatter Plot SNS Index
Time.Varying.Data%>%
ggplot(aes(x=Hours, y=SNS_index))+
geom_line()+
theme_bw()+
labs(
title = "Time & SNS Index",
y = "SNS Index",
x = "Hours")

# Heart Rate and SNS Index
Time.Varying.Data %>%
ggplot(aes(x=Hours, y=Mean_HR, color =SNS_index))+
geom_hline(yintercept=Descriptives$SD2, color ="red", linetype="dashed", alpha =.75)+
geom_hline(yintercept = Descriptives$mean, color ="green")+ # Mean
scale_color_viridis(option = "B")+ # Inferno Color Palette
geom_line(size =1)+
theme_dark()+
annotate("text", label = "2 SD Above Mean", x = 3, y = 130, size = 4, color = "red")+
annotate("text", label = "Mean", x = 3, y = 60, size = 4, color = "green")+
ylim(40,200)+
labs(
color = "SNS Index",
title = "Time & Mean HR",
y = "bpm",
x = "Hours")

Ploting time-varying data using Plotly
When I explore my data, I sometimes like to use this program called “Plotly.” The advantage of this program is it can be interactive. That is, if you hover your cursor over the values, you can see the x- and y- values. This feature is helpful if you are quickly trying to see when an event occurred. Another interesting feature with Plotly: you can create 3D figures.
# 2D
Time.Varying.Data%>%
plot_ly(x = ~Hours, y = ~Mean_HR,type = 'scatter', mode = 'lines', name ='bpm') %>%
add_segments(x = 0, xend = 40, y = 118.9955, yend = 118.9955, name='2 SD Above Mean') %>%
add_segments(x = 0, xend = 40, y = 70.00502, yend = 70.00502, name='Mean') %>%
layout(
title = 'Time & Mean Heart Rate',
xaxis = list(title = 'Hours'),
yaxis = list(title = 'bpm'))
# 3D
Time.Varying.Data%>%
plot_ly(x = ~Hours, y = ~Mean_HR,z = ~SNS_index,type = 'scatter3d', mode = 'lines')
LS0tDQp0aXRsZTogIkt1YmlvcyBUaW1lLVZhcnlpbmcgUmVzdWx0cyINCmF1dGhvcjogIkFuZHJldyBKLiBNb2ppY2EiDQpkYXRlOiAiMy8yMi8yMDIxIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgZmlnX2NhcHRpb246IHllcw0KICBvdXRwdXQ6IG51bGwNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQotLS0NCg0KLS0tDQojIyBSIFByb2dyYW1zIEkgdXNlZA0KYGBge1IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkocmVhZHIpICMgcmVhZCBDU1YgZmlsZXMNCmxpYnJhcnkodGlkeXIpICMgIGRhdGEgbWFuaXB1bGF0aW9uDQpsaWJyYXJ5KGRwbHlyKSMgZGF0YSBtYW5pcHVsYXRpb24NCmxpYnJhcnkobHVicmlkYXRlKSMgdGltZXN0YW1wIGRhdGENCmxpYnJhcnkoZ2dwbG90MikgIyBwbG90cw0KbGlicmFyeShwbG90bHkpICMgaW50ZXJhY3RpdmUgcGxvdHMNCmxpYnJhcnkodmlyaWRpcykgIyBjb2xvciBwYWxldHRlcw0KbGlicmFyeSh2aXJpZGlzTGl0ZSkNCmBgYA0KDQoNCiMjIExvYWQgVGltZS1WYXJ5aW5nIFJlc3VsdHMNCmBgYHtSIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIFRpbWUtVmFyeWluZyBSZXN1bHRzDQpUaW1lLlZhcmluZy5SZXN1bHRzIDwtIHJlYWRfY3N2KCIyMDE5MDMwNy03MDA3X2hydi5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMTQ4KQ0KIyBDb2x1bW5zIHJlbW92ZWQNClRpbWUuVmFyaW5nLlJlc3VsdHMgPC0gVGltZS5WYXJpbmcuUmVzdWx0c1stYygxLCA0MSldDQojIFJvd3Mga2VwdA0KVGltZS5WYXJpbmcuUmVzdWx0cyAgPC0gVGltZS5WYXJpbmcuUmVzdWx0c1tjKDI6MTQyODkwKSxdDQojIFJlbmFtZWQgdmFyaWFibGVzDQpUaW1lLlZhcmluZy5SZXN1bHRzPC1UaW1lLlZhcmluZy5SZXN1bHRzICU+JSANCiAgcmVuYW1lKEFydGlmYWN0PWBBcnRpZmFjdCBwZXJjZW50YWdlYCwgUE5TX2luZGV4PQlgUE5TIGluZGV4YCwgU05TX2luZGV4PWBTTlMgaW5kZXhgLFN0cmVzc19pbmRleD1gU3RyZXNzIGluZGV4YCwNCiAgICAgICAgIE1lYW5fUlI9YE1lYW4gUlJgLCBTVERfUlI9ICBgU1REIFJSYCwgTWVhbl9IUj1gTWVhbiBIUmAsIFNURF9IUj0gYFNURCBIUmAsTWluX0hSPSBgTWluIEhSYCwgTWF4X0hSPWBNYXggSFJgLCANCiAgICAgICAgIFZMRl9wZWFrPWBWTEYgcGVha2AsIExGX3BlYWs9IGBMRiBwZWFrYCxIRl9wZWFrPSBgSEYgcGVha2AsVkxGX3Bvd2VyLm1zMj0gYFZMRiBwb3dlcmAsTEZfcG93ZXIubXMyPWBMRiBwb3dlcmAsDQogICAgICAgICBIRl9wb3dlcm1zMj1gSEYgcG93ZXJgLCBWTEZfcG93ZXIubG9nPQlgVkxGIHBvd2VyXzFgLCBMRl9wb3dlci5sb2c9YExGIHBvd2VyXzFgLEhGX3Bvd2VyLmxvZz0JYEhGIHBvd2VyXzFgLFZMRl9wb3dlci5wZXI9YFZMRiBwb3dlcl8yYCwJICAgIA0KICAgICAgICAgTEZfcG93ZXIucGVyPSBgTEYgcG93ZXJfMmAsSEZfcG93ZXIucGVyPWBIRiBwb3dlcl8yYCwgTEZfcG93ZXIubnU9YExGIHBvd2VyXzNgLEhGX3Bvd2VyLm51PSBgSEYgcG93ZXJfM2AsTEZfSEY9IGBMRi9IRiByYXRpb2AsU0QyX1NEPSBgU0QyL1NEMWAsDQogICAgICAgICBERkFfYTE9CWBERkEgYTFgLERGQV9hMj1gREZBIGEyYCkJICAgICAgICAgICAgDQoNCiMgQ2hlY2sgaWYgZGF0YSBhcmUgY29kZWQgYXMgY2hhcmFjdGVycw0Kc2FwcGx5KFRpbWUuVmFyaW5nLlJlc3VsdHMgLCBjbGFzcykgDQpgYGANCg0KIyMgVGltZSAmIEhSViBkYXRhDQpGdW5kYW1lbnRhbGx5LCB0aGVyZSBhcmUgdHdvIHR5cGVzIG9mIGRhdGEgd2hlbiB1c2luZyB0aW1lLXZhcnlpbmcgcmVzdWx0czogKDEpIEhSViBhbmQgKDIpIFRpbWUuIFRoZSBmb2xsb3dpbmcgY29kZSBicmVha3MgZG93biB0aGUgZmlsZSBpbnRvIHRoZXNlIHR3byB0eXBlcyBhbmQgdGhlbiBjb21iaW5lcyB0aGVtIGludG8gYSBzaW5nbGUgZGF0YSBmcmFtZS4gTXkgdXN1YWwgcHJvZ3JhbSBmb3IgdGltZXN0YW1wIGRhdGEgKGx1YnJpZGF0ZSkgZGlkIG5vdCB3b3JrLiBUaGUgdGltZSBkYXRhIGRpZCBub3QgcGFyc2UgdGltZSBkYXRhIGludG8gaG91cnMsIG1pbnV0ZXMsIGFuZCBzZWNvbmRzIGZvciBldmVyeSByb3cuIENvbnNlcXVlbnRseSwgSSBtYWRlIG15IHRpbWUgY2FsY3VsYXRpb25zIG9mIHNlY29uZHMgYW5kIGhvdXJzLiANCmBgYHtyfQ0KIyMgSFJWIERhdGENCkhSVjwtVGltZS5WYXJpbmcuUmVzdWx0cyAlPiUNCiAgc2VsZWN0KEFydGlmYWN0OkRGQV9hMikgJT4lIA0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLGFzLm51bWVyaWMpDQoNCiMgVGltZSBEYXRhDQpUaW1lPC1UaW1lLlZhcmluZy5SZXN1bHRzICU+JQ0KICBzZWxlY3QoVGltZSkNCiMgRmlyc3QsSSBjcmVhdGVkIGEgdmVjdG9yIGNhbGxlZCAiU2Vjb25kcy4iIEJlY2F1c2UgdGhlcmUgYXJlIDE0Miw4ODkgb2JzZXJ2YXRpb25zIGFuZCB0aGUgc2FtcGxpbmcgcmF0ZSBpcyBpbiBzZWNvbmRzLHRoZXJlIGFyZSAxNDIsODg5IHNlY29uZHMgaW4gdGhpcyBzYW1wbGUuDQpTZWNvbmRzPC0xOjE0Mjg4OQ0KVGltZTwtY2JpbmQoVGltZSxTZWNvbmRzKQ0KDQojIEhvdXJzDQpUaW1lPC1UaW1lICU+JSANCiAgbXV0YXRlKEhvdXJzPVNlY29uZHMvMzYwMCkNCg0KIyBDb21iaW5lZCBIUlYgJiBUaW1lIERhdGENClRpbWUuVmFyeWluZy5EYXRhPC1jYmluZChUaW1lLEhSVikNCmBgYA0KDQojIyBIZWFydCBSYXRlIERhdGENCkF0IHRoZSByb290IG9mIGFsbCBIUlYgdmFyaWFiaWxpdHkgc3RhdGlzdGljcyBhcmUgdGhlIFJSIGludGVydmFscy4gWW91IGNhbiBjb252ZXJ0IHRoZXNlIFJSIGludGVydmFscyBpbnRvIGJlYXQtcGVyLW1pbnV0ZSAoYnBtKS4gSSBzdHJvbmdseSByZWNvbW1lbmQgdXNpbmcgdGhpcyBtZXRyaWMgYmVjYXVzZSBpdCdzIGludHVpdGl2ZSB0byBtb3N0IHBlb3BsZSBhbmQgb2Z0ZW4gdXNlZCBpbiBtYW55IHNjaWVudGlmaWMgZGlzY2lwbGluZXMuICANCg0KSSBhbHNvIGNyZWF0ZWQgYSBuZXcgdmFyaWFibGUgY2FsbGVkICJUaHJlc2hvbGQuIiBUaGlzIHZhcmlhYmxlIGhlbHBzIGRldGVybWluZSB3aGVuIHRoZXJlIHdhcyBhIGRldmlhdGlvbiBpbiBoZWFydCByYXRlLiBJIGRlZmluZWQgdGhpcyBkZXZpYXRpb24gZW1waXJpY2FsbHk6IDIgc3RhbmRhcmQgZGV2aWF0aW9ucyBhYm92ZSB0aGUgbWVhbi4gRmVlbCBmcmVlIHRvIHVzZSBhIGRpZmZlcmVudCBtZXRob2QgaWYgeW91IGZpbmQgaW5mb3JtYXRpb24gaW4gdGhlIGxpdGVyYXR1cmUgdGhhdCBpcyBtb3JlIGluZm9ybWF0aXZlLiBJbXBvcnRhbnRseSwgd2UgY2FuIGRldGVybWluZSBob3cgbG9uZyB0aGUgZXZlbnQgb2NjdXJyZWQgYnkga25vd2luZyB3aGVuIGhlYXJ0IHJhdGUgd2FzIGFib3ZlIGEgZGVmaW5lZCB0aHJlc2hvbGQuDQpgYGB7cn0NCiMgTWVhbiBIUiBIaXN0b2dyYW0NClRpbWUuVmFyeWluZy5EYXRhICU+JSAgDQogIGdncGxvdChhZXMoeD1NZWFuX0hSKSkrDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMDAsY29sb3IgPSAiYmxhY2siKSsNCiAgdGhlbWVfYncoKSsgDQogIGxhYnMoDQogICAgdGl0bGUgICAgPSAiTWVhbiBIUiIsIA0KICAgIHkgICAgICAgID0gIkNvdW50IiwNCiAgICB4ICAgICAgICA9ICJicG0iKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCkRlc2NyaXB0aXZlczwtVGltZS5WYXJ5aW5nLkRhdGEgICU+JSANCiAgc3VtbWFyaXNlKG1lYW49bWVhbihNZWFuX0hSKSxtZWRpYW49bWVkaWFuKE1lYW5fSFIpLCANCiAgICAgICAgICAgIG1pbj1taW4oTWVhbl9IUiksIG1heD1tYXgoTWVhbl9IUiksU0Q9IHNkKE1lYW5fSFIpLCBuID1uKCkpICU+JSANCiAgbXV0YXRlKFNEMj0gbWVhbisoMipTRCkpDQogIA0KIyBUaHJlc2hvbGQgDQpUaW1lLlZhcnlpbmcuRGF0YTwtVGltZS5WYXJ5aW5nLkRhdGEgICU+JSANCiAgbXV0YXRlKFRocmVzaG9sZD0gaWZlbHNlKE1lYW5fSFIgPj1EZXNjcmlwdGl2ZXMkU0QyLCJBYm92ZSIsIk5vcm1hbCIpKQ0KYGBgDQoNCiMjIFBsb3RpbmcgdGltZS12YXJ5aW5nIGRhdGEgdXNpbmcgZ2dwbG90Mg0KSSBzdHJvbmdseSByZWNvbW1lbmQgcGxvdHRpbmcgeW91ciBoZWFydCByYXRlICh4ID0gdGltZSwgeSA9IGhlYXJ0IHJhdGUpLiBZb3Ugd2lsbCBiZSBhYmxlIHRvIGRldGVybWluZSBpZiBhIHNpZ25pZmljYW50IGV2ZW50IG9jY3VycmVkLiANCg0KSSBwcmVmZXIgdXNpbmcgZ2dwbG90MiBwcm9ncmFtIGluIFIgZm9yIGRhdGEgdmlzdWFsaXphdGlvbi4gVGhlcmUgYXJlIG1hbnkgb25saW5lIHR1dG9yaWFscyBvdXQgdGhlcmUgdGhhdCBhcmUgZWFzeSB0byBmb2xsb3cuIFBsdXMsIGl0IGlzIHBhcnQgb2YgdGhlIHRpZGR5dmVyc2UgKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcpIHNldCBvZiBwcm9ncmFtcy4NCmBgYHtyfQ0KIyBTY2F0dGVyIHBsb3Q6IEhlYXJ0IFJhdGUNClRpbWUuVmFyeWluZy5EYXRhJT4lDQogIGdncGxvdChhZXMoeD1Ib3VycywgeT1NZWFuX0hSKSkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdD1EZXNjcmlwdGl2ZXMkU0QyLCBjb2xvciA9InJlZCIsIGxpbmV0eXBlPSJkYXNoZWQiLCBhbHBoYSA9Ljc1KSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gRGVzY3JpcHRpdmVzJG1lYW4sIGNvbG9yID0iZ3JlZW4iKSsgIyBNZWFuDQogIGdlb21fbGluZSgpKw0KICB0aGVtZV9idygpKw0KICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIjIgU0QgQWJvdmUgTWVhbiIsIHggPSAzLCB5ID0gMTMwLCBzaXplID0gNCwgY29sb3IgPSAicmVkIikrDQogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTWVhbiIsIHggPSAzLCB5ID0gNjAsIHNpemUgPSA0LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSsNCiAgeWxpbSg0MCwyMDApKw0KICBsYWJzKCAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICB0aXRsZSAgICA9ICJUaW1lICYgTWVhbiBIUiIsIA0KICAgIHkgICAgICAgID0gImJwbSIsDQogICAgeCAgICAgICAgPSAiSG91cnMiKQ0KIyBTY2F0dGVyIFBsb3QgU05TIEluZGV4DQpUaW1lLlZhcnlpbmcuRGF0YSU+JQ0KICBnZ3Bsb3QoYWVzKHg9SG91cnMsIHk9U05TX2luZGV4KSkrDQogIGdlb21fbGluZSgpKw0KICB0aGVtZV9idygpKw0KICBsYWJzKCAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICB0aXRsZSAgICA9ICJUaW1lICYgU05TIEluZGV4IiwgDQogICAgeSAgICAgICAgPSAiU05TIEluZGV4IiwNCiAgICB4ICAgICAgICA9ICJIb3VycyIpDQogIA0KIyBIZWFydCBSYXRlIGFuZCBTTlMgSW5kZXgNClRpbWUuVmFyeWluZy5EYXRhICU+JSANCiAgZ2dwbG90KGFlcyh4PUhvdXJzLCB5PU1lYW5fSFIsIGNvbG9yID1TTlNfaW5kZXgpKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PURlc2NyaXB0aXZlcyRTRDIsIGNvbG9yID0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIsIGFscGhhID0uNzUpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBEZXNjcmlwdGl2ZXMkbWVhbiwgY29sb3IgPSJncmVlbiIpKyAjIE1lYW4NCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb24gPSAiQiIpKyAjIEluZmVybm8gQ29sb3IgUGFsZXR0ZQ0KICBnZW9tX2xpbmUoc2l6ZSA9MSkrDQogIHRoZW1lX2RhcmsoKSsNCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICIyIFNEIEFib3ZlIE1lYW4iLCB4ID0gMywgeSA9IDEzMCwgc2l6ZSA9IDQsIGNvbG9yID0gInJlZCIpKw0KICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIk1lYW4iLCB4ID0gMywgeSA9IDYwLCBzaXplID0gNCwgY29sb3IgPSAiZ3JlZW4iKSsNCiAgeWxpbSg0MCwyMDApKw0KICBsYWJzKA0KICAgIGNvbG9yID0gIlNOUyBJbmRleCIsDQogICAgdGl0bGUgICAgPSAiVGltZSAmIE1lYW4gSFIiLCANCiAgICB5ICAgICAgICA9ICJicG0iLA0KICAgIHggICAgICAgID0gIkhvdXJzIikNCmBgYA0KDQojIyBQbG90aW5nIHRpbWUtdmFyeWluZyBkYXRhIHVzaW5nIFBsb3RseQ0KV2hlbiBJIGV4cGxvcmUgbXkgZGF0YSwgSSBzb21ldGltZXMgbGlrZSB0byB1c2UgdGhpcyBwcm9ncmFtIGNhbGxlZCAiUGxvdGx5LiIgVGhlIGFkdmFudGFnZSBvZiB0aGlzIHByb2dyYW0gaXMgaXQgY2FuIGJlIGludGVyYWN0aXZlLiBUaGF0IGlzLCBpZiB5b3UgaG92ZXIgeW91ciBjdXJzb3Igb3ZlciB0aGUgdmFsdWVzLCB5b3UgY2FuIHNlZSB0aGUgeC0gYW5kIHktIHZhbHVlcy4gVGhpcyBmZWF0dXJlIGlzIGhlbHBmdWwgaWYgeW91IGFyZSBxdWlja2x5IHRyeWluZyB0byBzZWUgd2hlbiBhbiBldmVudCBvY2N1cnJlZC4gQW5vdGhlciBpbnRlcmVzdGluZyBmZWF0dXJlIHdpdGggUGxvdGx5OiB5b3UgY2FuIGNyZWF0ZSAzRCBmaWd1cmVzLiANCmBgYHtyfQ0KIyAyRCANClRpbWUuVmFyeWluZy5EYXRhJT4lIA0KcGxvdF9seSh4ID0gfkhvdXJzLCB5ID0gfk1lYW5fSFIsdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIG5hbWUgPSdicG0nKSAlPiUgDQogIGFkZF9zZWdtZW50cyh4ID0gMCwgeGVuZCA9IDQwLCB5ID0gMTE4Ljk5NTUsIHllbmQgPSAxMTguOTk1NSwgbmFtZT0nMiBTRCBBYm92ZSBNZWFuJykgJT4lIA0KICBhZGRfc2VnbWVudHMoeCA9IDAsIHhlbmQgPSA0MCwgeSA9IDcwLjAwNTAyLCB5ZW5kID0gNzAuMDA1MDIsIG5hbWU9J01lYW4nKSAlPiUgDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICdUaW1lICYgTWVhbiBIZWFydCBSYXRlJywNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnSG91cnMnKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnYnBtJykpDQojIDNEICANClRpbWUuVmFyeWluZy5EYXRhJT4lIA0KICBwbG90X2x5KHggPSB+SG91cnMsIHkgPSB+TWVhbl9IUix6ID0gflNOU19pbmRleCx0eXBlID0gJ3NjYXR0ZXIzZCcsIG1vZGUgPSAnbGluZXMnKQ0KYGBgDQo=