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=