Code:

Erweiterung des selbstgeschriebenen Proxel-Programms mit den Tests und der Symptom-Sequenz. (siehe Code-Button rechts)

max.ts = 12
delta = 1
startproxel=c(1,0,0,1,0)
RG=matrix(c(1,1,0,1,
            0,1,1,1,
            0,0,1,1,
            0,0,0,1),ncol = 4,byrow = T)
FEVER=data.frame(nf=c(0.9,0.5,0.2,1),f=c(0.1,0.5,0.8,0))
BLOOD=data.frame(Ba=c(.7,.5,.2),Bb=c(.2,.3,.3),Bc=c(.1,.2,.5))
URINE=data.frame(Ua=c(.8,.6,.5),Ub=c(.1,.3,.3),Uc=c(.1,.1,.2))

Proxel_algo=function(RG,startproxel,delta,max.ts,Print=T,RETURN,FEVER=NA,BLOOD=NA,URINE=NA,SEQ=NA){
  
  SF=subset(SEQ,SEQ[,2] %in% c("F","nF"))
  SB=subset(SEQ,SEQ[,2] %in% c("Ba","Bb","Bc"))
  SU=subset(SEQ,SEQ[,2] %in% c("Ua","Ub","Uc"))
  
  unihrf <- function(age, a, b) {
    if (a <= age && age < b) {
      return (1.0 / (b - age))
    } else {
      return (0)
    }
  }
  
  exphrf <- function(age, l) {
    return (l)
  }
    
  proxel_df=data.frame(tau=numeric(),S1=numeric(),S2=numeric(),S3=numeric(),H=numeric())
  
  proxel_list=list()
  proxel_list[[max.ts+1]]=list()
  proxel_list[[1]]=list(timestep=c(0),proxel=data.frame(state=startproxel[1],tau=startproxel[2],tau_k=startproxel[3],prob=startproxel[4],prev=startproxel[5]),
                        HnMM=tidyr::tibble(pos.path=list(c(1)),WKT=FEVER[1,1]))
  
  if(Print) print("initial proxel:")
  if(Print) print(proxel_list[[1]])
  
  proxel_df[1,]=c(0,proxel_list[[1]]$proxel$prob[proxel_list[[1]]$proxel$state == 1],0,0,0)
  
  for (timestep in 1:max.ts) {
    proxel_list[[timestep+1]]=list(timestep=c(timestep),proxel=data.frame(state=numeric(),tau=numeric(),tau_k=numeric(),prob=numeric(),prev=numeric()),
                                   HnMM=tidyr::tibble(pos.path=list(),WKT=numeric()))     # erstelle schonmal eine neue leere liste für den nächsten timestep
    
    for (l in 1:nrow(proxel_list[[timestep]]$proxel)) {
      currprox = proxel_list[[timestep]]$proxel[l,]                                     # aktueller proxel zu dem folgeproxels erzeugt werden sollen
      folger = RG[as.numeric(currprox[1]),]                                             # folgestates von aktuellem proxel
      
      for (i in 1:4) {
        if (folger[i]==1) {                                                             # erstelle folgeproxel falls pfeil dahin gibt
          proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel)+1,1] = i                       # state vom nächsten proxel
          
          if(currprox$state==i) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),2] = currprox$tau + delta
            else proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),2] = 0                    # tau vom nächsten proxel
          
          if(currprox$state %in% c(1,2,3) & i!=4) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = currprox$tau_k + delta
            else if(currprox$state==4 & i==4) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = currprox$tau_k - delta
              else proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = 0                   # tau_k vom nächsten proxel
            
          if(currprox$state==1 & i==2) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (unihrf(currprox$tau_k,2,4) * delta) * currprox$prob}                 # transition von S1 zu S2
          if(currprox$state==2 & i==3) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (exphrf(currprox$tau_k,0.1) * delta) * currprox$prob}                 # transition von S2 zu S3
          if(currprox$state!=4 & i==4) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (unihrf(currprox$tau_k,7,14)* delta) * currprox$prob}                 # transtion zu heal von S1,S2 oder S3
          if(currprox$state==1 & i==1) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (unihrf(currprox$tau_k,2,4) * delta) - (unihrf(currprox$tau_k,7,14)* delta)) * currprox$prob}
          if(currprox$state==2 & i==2) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (exphrf(currprox$tau_k,0.1) * delta) - (unihrf(currprox$tau_k,7,14)* delta)) * currprox$prob}
          if(currprox$state==3 & i==3) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (unihrf(currprox$tau_k,7,14)* delta)) * currprox$prob}
          if(currprox$state==4 & i==4) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = 1 }
              
           proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),5] = l   
           
        }
      } 
    }
    
    if(length(which(proxel_list[[timestep+1]]$proxel[,4]<=0))!=0) proxel_list[[timestep+1]]$proxel=proxel_list[[timestep+1]]$proxel[-which(proxel_list[[timestep+1]]$proxel[,4]<=0),]
    if(length(which(proxel_list[[timestep+1]]$proxel[,3]< 0))!=0) proxel_list[[timestep+1]]$proxel=proxel_list[[timestep+1]]$proxel[-which(proxel_list[[timestep+1]]$proxel[,3]< 0),]
    
    for (prox in 1:nrow(proxel_list[[timestep+1]]$proxel)) {
      
      proxel_list[[timestep+1]]$HnMM[prox,1][[1]] = list(c(unlist(proxel_list[[timestep]]$HnMM[proxel_list[[timestep+1]]$proxel$prev[prox],1]),proxel_list[[timestep+1]]$proxel$state[prox]))
      
      if(timestep+1 <= nrow(SF)){
        if(SF[timestep+1,2]=="F") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$proxel$prob[prox] * FEVER$f[proxel_list[[timestep+1]]$proxel$state[prox]] *
            proxel_list[[timestep]]$HnMM$WKT[proxel_list[[timestep+1]]$proxel$prev[prox]]
        if(SF[timestep+1,2]=="nF") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$proxel$prob[prox] * FEVER$nf[proxel_list[[timestep+1]]$proxel$state[prox]] *
            proxel_list[[timestep]]$HnMM$WKT[proxel_list[[timestep+1]]$proxel$prev[prox]]
      }
      
      if((timestep+1)%%2 == 0){
        if(SU[SU[,1]==timestep+1,2]=="Ua") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Ua[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SU[SU[,1]==timestep+1,2]=="Ub") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Ub[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SU[SU[,1]==timestep+1,2]=="Uc") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Uc[proxel_list[[timestep+1]]$proxel$state[prox]]
      }
      
      if((timestep+1)%%3 == 0){
        if(SB[SB[,1]==timestep+1,2]=="Ba") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Ba[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SB[SB[,1]==timestep+1,2]=="Bb") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Bb[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SB[SB[,1]==timestep+1,2]=="Bc") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Bc[proxel_list[[timestep+1]]$proxel$state[prox]]
      }
    }
    
    if(Print) print(paste("Time step:",timestep))
    if(Print) print(proxel_list[[timestep+1]])
    
    proxel_df[timestep+1,1]=timestep*delta
    for (v in 2:4) {
      if(length(proxel_list[[timestep+1]]$proxel$prob[proxel_list[[timestep+1]]$proxel$state == v-1]) != 0) {
        proxel_df[timestep+1,v] = round(sum(proxel_list[[timestep+1]]$proxel$prob[proxel_list[[timestep+1]]$proxel$state == v-1]),5)}
          else proxel_df[timestep+1,v] = 0
    }
    proxel_df[timestep+1,5]=round(1-sum(proxel_df[timestep+1,2:4]),5)
      
  }
  
  if(RETURN=="TREE") return(proxel_list)
  if(RETURN=="DF") return(proxel_df)
}
proxel_list=Proxel_algo(RG,startproxel,delta,max.ts,F,"TREE",FEVER,BLOOD,URINE,patient1)

What is the probability of the given sequence of symptoms (patient1.seq)?

Prob_dis1 = sum(proxel_list[[13]]$HnMM$WKT)

What are the 5 most likely generating paths of that sequence? & What are the actual portions of time spent in each disease stage for each of these paths?

ord=order(proxel_list[[13]]$HnMM$WKT,decreasing = T)
as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[1]]])
proxel_list[[13]][["HnMM"]][["WKT"]][[ord[1]]]
table(as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[1]]]))

as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[2]]])
proxel_list[[13]][["HnMM"]][["WKT"]][[ord[2]]]
as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[2]]]) |> table()

as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[3]]])
proxel_list[[13]][["HnMM"]][["WKT"]][[ord[3]]]
as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[3]]]) |> table()

as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[4]]])
proxel_list[[13]][["HnMM"]][["WKT"]][[ord[4]]]
as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[4]]]) |> table()

as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[5]]])
proxel_list[[13]][["HnMM"]][["WKT"]][[ord[5]]]
as.vector(proxel_list[[13]][["HnMM"]][["pos.path"]][[ord[5]]]) |> table()
  1. Path: 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2
    • Prob = 5.6322607^{-22}
    • days in stage…
      • 1: 4
      • 2: 9
  2. Path: 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    • Prob = 3.9137598^{-22}
    • days in stage…
      • 1: 3
      • 2: 10
  3. Path: 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3
    • Prob = 1.5902854^{-22}
    • days in stage…
      • 1: 4
      • 2: 8
      • 3: 1
  4. Path: 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3
    • Prob = 1.1050616^{-22}
    • days in stage…
      • 1: 3
      • 2: 9
      • 3: 1
  5. Path: 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3
    • Prob = 1.9005546^{-24}
    • days in stage…
      • 1: 4
      • 2: 7
      • 3: 2

Code 2:

Abänderung des HnMM-Programms für Disease 2

max.ts = 12
delta = 1
startproxel=c(1,0,0,1,0)
RG=matrix(c(1,1,0,1,
            0,1,1,1,
            0,0,1,1,
            0,0,0,1),ncol = 4,byrow = T)
FEVER2=data.frame(nf=c(0.7,0.3,0.1,1),f=c(0.3,0.7,0.9,0))
BLOOD2=data.frame(Ba=c(.7,.5,.2),Bb=c(.2,.3,.3),Bc=c(.1,.2,.5))
URINE2=data.frame(Ua=c(.8,.7,.7),Ub=c(.2,.2,.2),Uc=c(.0,.1,.1))

Proxel_algo2=function(RG,startproxel,delta,max.ts,Print=T,RETURN,FEVER=NA,BLOOD=NA,URINE=NA,SEQ=NA){
  
  SF=subset(SEQ,SEQ[,2] %in% c("F","nF"))
  SB=subset(SEQ,SEQ[,2] %in% c("Ba","Bb","Bc"))
  SU=subset(SEQ,SEQ[,2] %in% c("Ua","Ub","Uc"))
  ###########################################################################################################################
  normalpdf <- function(x, m, s) {
  z <- (x - m) / s
  return (exp(-z^2 / 2) / (sqrt(2 * pi) * s))
}

logGamma <- function(x) {
  coef <- c(76.18009173, -86.50532033, 24.01409822, -1.231739516, 0.00120858003, -0.00000536382)
  step <- 2.50662827465
  fpf <- 5.5
  t <- x - 1
  tmp <- t + fpf
  tmp <- (t + 0.5) * log(tmp) - tmp
  ser <- 1
  for (i in 1:6) {
    t <- t + 1
    ser <- ser + coef[i] / t
  }
  return (tmp + log(step * ser))
}

gammaSeries <- function(x, a) {
  maxit <- 100
  eps <- 0.0000003
  sum <- 1.0 / a
  ap <- a
  gln <- logGamma(a)
  del <- sum

  for (n in 1:maxit) {
    ap <- ap + 1
    del <- del * x / ap
    sum <- sum + del
    if (abs(del) < abs(sum) * eps) break
  }
  return (sum * exp(-x + a * log(x) - gln))
}

gammaCF <- function(x, a) {
  maxit <- 100
  eps <- 0.0000003
  gln <- logGamma(a)
  g <- 0
  gold <- 0
  a0 <- 1
  a1 <- x
  b0 <- 0
  b1 <- 1
  fac <- 1
  an <- 0
  ana <- 0
  anf <- 0

  for (n in 1:maxit) {
    an <- 1.0 * n
    ana <- an - a
    a0 <- (a1 + a0 * ana) * fac
    b0 <- (b1 + b0 * ana) * fac
    anf <- an * fac
    a1 <- x * a0 + anf * a1
    b1 <- x * b0 + anf * b1
    if (a1 != 0) {
      fac <- 1.0 / a1
      g <- b1 * fac
      if (abs((g - gold) / g) < eps) break
      gold <- g
    }
  }
  return (exp(-x + a * log(x) - gln) * g)
}

gammacdf <- function(x, a) {
  if (x <= 0)
    return (0)
  else if (x < a + 1)
    return (gammaSeries(x, a))
  else
    return (1 - gammaCF(x, a))
}

normalcdf <- function(x, m, s) {
  z <- (x - m) / s
  if (z >= 0)
    return (0.5 + 0.5 * gammacdf(z^2 / 2, 0.5))
  else
    return (0.5 - 0.5 * gammacdf(z^2 / 2, 0.5))
}

normalhrf <- function(x, m, s) {
  return (normalpdf(x, m, s) / (1 - normalcdf(x, m, s)))
}
  
  unihrf <- function(age, a, b) {
    if (a <= age && age < b) {
      return (1.0 / (b - age))
    } else {
      return (0)
    }
  }
  
  exphrf <- function(age, l) {
    return (l)
  }
   #####################################################################################################################################################
  
  proxel_df=data.frame(tau=numeric(),S1=numeric(),S2=numeric(),S3=numeric(),H=numeric())
  
  proxel_list=list()
  proxel_list[[max.ts+1]]=list()
  proxel_list[[1]]=list(timestep=c(0),proxel=data.frame(state=startproxel[1],tau=startproxel[2],tau_k=startproxel[3],prob=startproxel[4],prev=startproxel[5]),
                        HnMM=tidyr::tibble(pos.path=list(c(1)),WKT=FEVER[1,1]))
  
  if(Print) print("initial proxel:")
  if(Print) print(proxel_list[[1]])
  
  proxel_df[1,]=c(0,proxel_list[[1]]$proxel$prob[proxel_list[[1]]$proxel$state == 1],0,0,0)
  
  for (timestep in 1:max.ts) {
    proxel_list[[timestep+1]]=list(timestep=c(timestep),proxel=data.frame(state=numeric(),tau=numeric(),tau_k=numeric(),prob=numeric(),prev=numeric()),
                                   HnMM=tidyr::tibble(pos.path=list(),WKT=numeric()))     # erstelle schonmal eine neue leere liste für den nächsten timestep
    
    for (l in 1:nrow(proxel_list[[timestep]]$proxel)) {
      currprox = proxel_list[[timestep]]$proxel[l,]                                     # aktueller proxel zu dem folgeproxels erzeugt werden sollen
      folger = RG[as.numeric(currprox[1]),]                                             # folgestates von aktuellem proxel
      
      for (i in 1:4) {
        if (folger[i]==1) {                                                             # erstelle folgeproxel falls pfeil dahin gibt
          proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel)+1,1] = i                       # state vom nächsten proxel
          
          if(currprox$state==i) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),2] = currprox$tau + delta
            else proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),2] = 0                    # tau vom nächsten proxel
          
          if(currprox$state %in% c(1,2,3) & i!=4) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = currprox$tau_k + delta
            else if(currprox$state==4 & i==4) proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = currprox$tau_k - delta
              else proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),3] = 0                   # tau_k vom nächsten proxel
            
          if(currprox$state==1 & i==2) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (normalhrf(currprox$tau_k,3,0.5) * delta) * currprox$prob}           # transition von S1 zu S2
          if(currprox$state==2 & i==3) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (exphrf(currprox$tau_k,0.3) * delta) * currprox$prob}           # transition von S2 zu S3
          if(currprox$state!=4 & i==4) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (normalhrf(currprox$tau_k,10,2)* delta) * currprox$prob}           # transtion zu heal von S1,S2 oder S3
          if(currprox$state==1 & i==1) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (normalhrf(currprox$tau_k,3,0.5) * delta) - (normalhrf(currprox$tau_k,10,2) * delta)) * currprox$prob}
          if(currprox$state==2 & i==2) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (exphrf(currprox$tau_k,0.3) * delta) - (normalhrf(currprox$tau_k,10,2) * delta)) * currprox$prob}
          if(currprox$state==3 & i==3) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = (1 - (normalhrf(currprox$tau_k,10,2) * delta)) * currprox$prob}
          if(currprox$state==4 & i==4) {
            proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),4] = 1 }
              
           proxel_list[[timestep+1]]$proxel[nrow(proxel_list[[timestep+1]]$proxel),5] = l   
           
        }
      } 
    }
    
    if(length(which(proxel_list[[timestep+1]]$proxel[,4]<=0))!=0) proxel_list[[timestep+1]]$proxel=proxel_list[[timestep+1]]$proxel[-which(proxel_list[[timestep+1]]$proxel[,4]<=0),]
    if(length(which(proxel_list[[timestep+1]]$proxel[,3]< 0))!=0) proxel_list[[timestep+1]]$proxel=proxel_list[[timestep+1]]$proxel[-which(proxel_list[[timestep+1]]$proxel[,3]< 0),]
    
    for (prox in 1:nrow(proxel_list[[timestep+1]]$proxel)) {
      
      proxel_list[[timestep+1]]$HnMM[prox,1][[1]] = list(c(unlist(proxel_list[[timestep]]$HnMM[proxel_list[[timestep+1]]$proxel$prev[prox],1]),proxel_list[[timestep+1]]$proxel$state[prox]))
      
      if(timestep+1 <= nrow(SF)){
        if(SF[timestep+1,2]=="F") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$proxel$prob[prox] * FEVER$f[proxel_list[[timestep+1]]$proxel$state[prox]] *
            proxel_list[[timestep]]$HnMM$WKT[proxel_list[[timestep+1]]$proxel$prev[prox]]
        if(SF[timestep+1,2]=="nF") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$proxel$prob[prox] * FEVER$nf[proxel_list[[timestep+1]]$proxel$state[prox]] *
            proxel_list[[timestep]]$HnMM$WKT[proxel_list[[timestep+1]]$proxel$prev[prox]]
      }
      
      if((timestep+1)%%2 == 0){
        if(SU[SU[,1]==timestep+1,2]=="Ua") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Ua[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SU[SU[,1]==timestep+1,2]=="Ub") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Ub[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SU[SU[,1]==timestep+1,2]=="Uc") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            URINE$Uc[proxel_list[[timestep+1]]$proxel$state[prox]]
      }
      
      if((timestep+1)%%3 == 0){
        if(SB[SB[,1]==timestep+1,2]=="Ba") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Ba[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SB[SB[,1]==timestep+1,2]=="Bb") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Bb[proxel_list[[timestep+1]]$proxel$state[prox]]
        if(SB[SB[,1]==timestep+1,2]=="Bc") proxel_list[[timestep+1]]$HnMM[prox,2] = proxel_list[[timestep+1]]$HnMM[prox,2] * proxel_list[[timestep+1]]$proxel$prob[prox] *
            BLOOD$Bc[proxel_list[[timestep+1]]$proxel$state[prox]]
      }
    }
    
    if(Print) print(paste("Time step:",timestep))
    if(Print) print(proxel_list[[timestep+1]])
    
    proxel_df[timestep+1,1]=timestep*delta
    for (v in 2:4) {
      if(length(proxel_list[[timestep+1]]$proxel$prob[proxel_list[[timestep+1]]$proxel$state == v-1]) != 0) {
        proxel_df[timestep+1,v] = round(sum(proxel_list[[timestep+1]]$proxel$prob[proxel_list[[timestep+1]]$proxel$state == v-1]),5)}
          else proxel_df[timestep+1,v] = 0
    }
    proxel_df[timestep+1,5]=round(1-sum(proxel_df[timestep+1,2:4]),5)
      
  }
  
  if(RETURN=="TREE") return(proxel_list)
  if(RETURN=="DF") return(proxel_df)
}
proxel_list2=Proxel_algo2(RG,startproxel,delta,max.ts,F,"TREE",FEVER2,BLOOD2,URINE2,patient1)

Compute the probability of each disease.

Prob_dis2=sum(proxel_list2[[13]]$HnMM$WKT)
#Prob_dis2>Prob_dis1

Which disease is the patient most likely suffering from?

We have further measurements from patients (2-5) that were infected by our original subject, so they must be suffering from the same disease. What does your program say to that claim?

pat2_A=Proxel_algo(RG,startproxel,delta,9,F,"TREE",FEVER,BLOOD,URINE,patient2)
pat2_B=Proxel_algo2(RG,startproxel,delta,9,F,"TREE",FEVER2,BLOOD2,URINE2,patient2)
pat3_A=Proxel_algo(RG,startproxel,delta,7,F,"TREE",FEVER,BLOOD,URINE,patient3)
pat3_B=Proxel_algo2(RG,startproxel,delta,7,F,"TREE",FEVER2,BLOOD2,URINE2,patient3)
pat4_A=Proxel_algo(RG,startproxel,delta,11,F,"TREE",FEVER,BLOOD,URINE,patient4)
pat4_B=Proxel_algo2(RG,startproxel,delta,11,F,"TREE",FEVER2,BLOOD2,URINE2,patient4)
pat5_A=Proxel_algo(RG,startproxel,delta,6,F,"TREE",FEVER,BLOOD,URINE,patient5)
pat5_B=Proxel_algo2(RG,startproxel,delta,6,F,"TREE",FEVER2,BLOOD2,URINE2,patient5)
sum(pat2_A[[10]]$HnMM$WKT,na.rm = T) < sum(pat2_B[[10]]$HnMM$WKT,na.rm = T)
sum(pat3_A[[8]]$HnMM$WKT,na.rm = T) < sum(pat3_B[[8]]$HnMM$WKT,na.rm = T)
sum(pat4_A[[12]]$HnMM$WKT,na.rm = T) < sum(pat4_B[[12]]$HnMM$WKT,na.rm = T)
sum(pat5_A[[7]]$HnMM$WKT,na.rm = T) < sum(pat5_B[[7]]$HnMM$WKT,na.rm = T)
LS0tDQp0aXRsZTogIkFETSBBc3NpZ25tZW50IDYiDQphdXRob3I6ICJEb21pbmlrIERpZWRyaWNoIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZSANCi0tLQ0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShwZXRyaW5ldFIpDQpsaWJyYXJ5KHRpZHlyKQ0KcGF0aWVudDEgPC0gcmVhZC50YWJsZSgiRDovRG9taW5pay9zdHVkaXVtL01hc3RlciAyLiBTZW1lc3Rlci9BRE0vQXVmZ2FiZW4vcGF0aWVudDEuc2VxIiwgcXVvdGU9IlwiIiwgY29tbWVudC5jaGFyPSIiKQ0KcGF0aWVudDIgPC0gcmVhZC50YWJsZSgiRDovRG9taW5pay9zdHVkaXVtL01hc3RlciAyLiBTZW1lc3Rlci9BRE0vQXVmZ2FiZW4vcGF0aWVudDIuc2VxIiwgcXVvdGU9IlwiIiwgY29tbWVudC5jaGFyPSIiKQ0KcGF0aWVudDMgPC0gcmVhZC50YWJsZSgiRDovRG9taW5pay9zdHVkaXVtL01hc3RlciAyLiBTZW1lc3Rlci9BRE0vQXVmZ2FiZW4vcGF0aWVudDMuc2VxIiwgcXVvdGU9IlwiIiwgY29tbWVudC5jaGFyPSIiKQ0KcGF0aWVudDQgPC0gcmVhZC50YWJsZSgiRDovRG9taW5pay9zdHVkaXVtL01hc3RlciAyLiBTZW1lc3Rlci9BRE0vQXVmZ2FiZW4vcGF0aWVudDQuc2VxIiwgcXVvdGU9IlwiIiwgY29tbWVudC5jaGFyPSIiKQ0KcGF0aWVudDUgPC0gcmVhZC50YWJsZSgiRDovRG9taW5pay9zdHVkaXVtL01hc3RlciAyLiBTZW1lc3Rlci9BRE0vQXVmZ2FiZW4vcGF0aWVudDUuc2VxIiwgcXVvdGU9IlwiIiwgY29tbWVudC5jaGFyPSIiKQ0KYGBgDQoNCiMjIENvZGU6DQoNCipFcndlaXRlcnVuZyBkZXMgc2VsYnN0Z2VzY2hyaWViZW5lbiBQcm94ZWwtUHJvZ3JhbW1zIG1pdCBkZW4gVGVzdHMgdW5kIGRlciBTeW1wdG9tLVNlcXVlbnouIChzaWVoZSBDb2RlLUJ1dHRvbiByZWNodHMpKg0KDQpgYGB7cn0NCm1heC50cyA9IDEyDQpkZWx0YSA9IDENCnN0YXJ0cHJveGVsPWMoMSwwLDAsMSwwKQ0KUkc9bWF0cml4KGMoMSwxLDAsMSwNCiAgICAgICAgICAgIDAsMSwxLDEsDQogICAgICAgICAgICAwLDAsMSwxLA0KICAgICAgICAgICAgMCwwLDAsMSksbmNvbCA9IDQsYnlyb3cgPSBUKQ0KRkVWRVI9ZGF0YS5mcmFtZShuZj1jKDAuOSwwLjUsMC4yLDEpLGY9YygwLjEsMC41LDAuOCwwKSkNCkJMT09EPWRhdGEuZnJhbWUoQmE9YyguNywuNSwuMiksQmI9YyguMiwuMywuMyksQmM9YyguMSwuMiwuNSkpDQpVUklORT1kYXRhLmZyYW1lKFVhPWMoLjgsLjYsLjUpLFViPWMoLjEsLjMsLjMpLFVjPWMoLjEsLjEsLjIpKQ0KDQpQcm94ZWxfYWxnbz1mdW5jdGlvbihSRyxzdGFydHByb3hlbCxkZWx0YSxtYXgudHMsUHJpbnQ9VCxSRVRVUk4sRkVWRVI9TkEsQkxPT0Q9TkEsVVJJTkU9TkEsU0VRPU5BKXsNCiAgDQogIFNGPXN1YnNldChTRVEsU0VRWywyXSAlaW4lIGMoIkYiLCJuRiIpKQ0KICBTQj1zdWJzZXQoU0VRLFNFUVssMl0gJWluJSBjKCJCYSIsIkJiIiwiQmMiKSkNCiAgU1U9c3Vic2V0KFNFUSxTRVFbLDJdICVpbiUgYygiVWEiLCJVYiIsIlVjIikpDQogIA0KICB1bmlocmYgPC0gZnVuY3Rpb24oYWdlLCBhLCBiKSB7DQogICAgaWYgKGEgPD0gYWdlICYmIGFnZSA8IGIpIHsNCiAgICAgIHJldHVybiAoMS4wIC8gKGIgLSBhZ2UpKQ0KICAgIH0gZWxzZSB7DQogICAgICByZXR1cm4gKDApDQogICAgfQ0KICB9DQogIA0KICBleHBocmYgPC0gZnVuY3Rpb24oYWdlLCBsKSB7DQogICAgcmV0dXJuIChsKQ0KICB9DQogICAgDQogIHByb3hlbF9kZj1kYXRhLmZyYW1lKHRhdT1udW1lcmljKCksUzE9bnVtZXJpYygpLFMyPW51bWVyaWMoKSxTMz1udW1lcmljKCksSD1udW1lcmljKCkpDQogIA0KICBwcm94ZWxfbGlzdD1saXN0KCkNCiAgcHJveGVsX2xpc3RbW21heC50cysxXV09bGlzdCgpDQogIHByb3hlbF9saXN0W1sxXV09bGlzdCh0aW1lc3RlcD1jKDApLHByb3hlbD1kYXRhLmZyYW1lKHN0YXRlPXN0YXJ0cHJveGVsWzFdLHRhdT1zdGFydHByb3hlbFsyXSx0YXVfaz1zdGFydHByb3hlbFszXSxwcm9iPXN0YXJ0cHJveGVsWzRdLHByZXY9c3RhcnRwcm94ZWxbNV0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgSG5NTT10aWR5cjo6dGliYmxlKHBvcy5wYXRoPWxpc3QoYygxKSksV0tUPUZFVkVSWzEsMV0pKQ0KICANCiAgaWYoUHJpbnQpIHByaW50KCJpbml0aWFsIHByb3hlbDoiKQ0KICBpZihQcmludCkgcHJpbnQocHJveGVsX2xpc3RbWzFdXSkNCiAgDQogIHByb3hlbF9kZlsxLF09YygwLHByb3hlbF9saXN0W1sxXV0kcHJveGVsJHByb2JbcHJveGVsX2xpc3RbWzFdXSRwcm94ZWwkc3RhdGUgPT0gMV0sMCwwLDApDQogIA0KICBmb3IgKHRpbWVzdGVwIGluIDE6bWF4LnRzKSB7DQogICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXT1saXN0KHRpbWVzdGVwPWModGltZXN0ZXApLHByb3hlbD1kYXRhLmZyYW1lKHN0YXRlPW51bWVyaWMoKSx0YXU9bnVtZXJpYygpLHRhdV9rPW51bWVyaWMoKSxwcm9iPW51bWVyaWMoKSxwcmV2PW51bWVyaWMoKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhuTU09dGlkeXI6OnRpYmJsZShwb3MucGF0aD1saXN0KCksV0tUPW51bWVyaWMoKSkpICAgICAjIGVyc3RlbGxlIHNjaG9ubWFsIGVpbmUgbmV1ZSBsZWVyZSBsaXN0ZSBmw7xyIGRlbiBuw6RjaHN0ZW4gdGltZXN0ZXANCiAgICANCiAgICBmb3IgKGwgaW4gMTpucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcF1dJHByb3hlbCkpIHsNCiAgICAgIGN1cnJwcm94ID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwXV0kcHJveGVsW2wsXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFrdHVlbGxlciBwcm94ZWwgenUgZGVtIGZvbGdlcHJveGVscyBlcnpldWd0IHdlcmRlbiBzb2xsZW4NCiAgICAgIGZvbGdlciA9IFJHW2FzLm51bWVyaWMoY3VycnByb3hbMV0pLF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZvbGdlc3RhdGVzIHZvbiBha3R1ZWxsZW0gcHJveGVsDQogICAgICANCiAgICAgIGZvciAoaSBpbiAxOjQpIHsNCiAgICAgICAgaWYgKGZvbGdlcltpXT09MSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGVyc3RlbGxlIGZvbGdlcHJveGVsIGZhbGxzIHBmZWlsIGRhaGluIGdpYnQNCiAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSsxLDFdID0gaSAgICAgICAgICAgICAgICAgICAgICAgIyBzdGF0ZSB2b20gbsOkY2hzdGVuIHByb3hlbA0KICAgICAgICAgIA0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT1pKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSwyXSA9IGN1cnJwcm94JHRhdSArIGRlbHRhDQogICAgICAgICAgICBlbHNlIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsW25yb3cocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwpLDJdID0gMCAgICAgICAgICAgICAgICAgICAgIyB0YXUgdm9tIG7DpGNoc3RlbiBwcm94ZWwNCiAgICAgICAgICANCiAgICAgICAgICBpZihjdXJycHJveCRzdGF0ZSAlaW4lIGMoMSwyLDMpICYgaSE9NCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSBjdXJycHJveCR0YXVfayArIGRlbHRhDQogICAgICAgICAgICBlbHNlIGlmKGN1cnJwcm94JHN0YXRlPT00ICYgaT09NCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSBjdXJycHJveCR0YXVfayAtIGRlbHRhDQogICAgICAgICAgICAgIGVsc2UgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSAwICAgICAgICAgICAgICAgICAgICMgdGF1X2sgdm9tIG7DpGNoc3RlbiBwcm94ZWwNCiAgICAgICAgICAgIA0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0xICYgaT09Mikgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAodW5paHJmKGN1cnJwcm94JHRhdV9rLDIsNCkgKiBkZWx0YSkgKiBjdXJycHJveCRwcm9ifSAgICAgICAgICAgICAgICAgIyB0cmFuc2l0aW9uIHZvbiBTMSB6dSBTMg0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0yICYgaT09Mykgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAoZXhwaHJmKGN1cnJwcm94JHRhdV9rLDAuMSkgKiBkZWx0YSkgKiBjdXJycHJveCRwcm9ifSAgICAgICAgICAgICAgICAgIyB0cmFuc2l0aW9uIHZvbiBTMiB6dSBTMw0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlIT00ICYgaT09NCkgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAodW5paHJmKGN1cnJwcm94JHRhdV9rLDcsMTQpKiBkZWx0YSkgKiBjdXJycHJveCRwcm9ifSAgICAgICAgICAgICAgICAgIyB0cmFuc3Rpb24genUgaGVhbCB2b24gUzEsUzIgb2RlciBTMw0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0xICYgaT09MSkgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAoMSAtICh1bmlocmYoY3VycnByb3gkdGF1X2ssMiw0KSAqIGRlbHRhKSAtICh1bmlocmYoY3VycnByb3gkdGF1X2ssNywxNCkqIGRlbHRhKSkgKiBjdXJycHJveCRwcm9ifQ0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0yICYgaT09Mikgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAoMSAtIChleHBocmYoY3VycnByb3gkdGF1X2ssMC4xKSAqIGRlbHRhKSAtICh1bmlocmYoY3VycnByb3gkdGF1X2ssNywxNCkqIGRlbHRhKSkgKiBjdXJycHJveCRwcm9ifQ0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0zICYgaT09Mykgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAoMSAtICh1bmlocmYoY3VycnByb3gkdGF1X2ssNywxNCkqIGRlbHRhKSkgKiBjdXJycHJveCRwcm9ifQ0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT00ICYgaT09NCkgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAxIH0NCiAgICAgICAgICAgICAgDQogICAgICAgICAgIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsW25yb3cocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwpLDVdID0gbCAgIA0KICAgICAgICAgICANCiAgICAgICAgfQ0KICAgICAgfSANCiAgICB9DQogICAgDQogICAgaWYobGVuZ3RoKHdoaWNoKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsWyw0XTw9MCkpIT0wKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbD1wcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFstd2hpY2gocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbLDRdPD0wKSxdDQogICAgaWYobGVuZ3RoKHdoaWNoKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsWywzXTwgMCkpIT0wKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbD1wcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFstd2hpY2gocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbLDNdPCAwKSxdDQogICAgDQogICAgZm9yIChwcm94IGluIDE6bnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCkpIHsNCiAgICAgIA0KICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMV1bWzFdXSA9IGxpc3QoYyh1bmxpc3QocHJveGVsX2xpc3RbW3RpbWVzdGVwXV0kSG5NTVtwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcmV2W3Byb3hdLDFdKSxwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZVtwcm94XSkpDQogICAgICANCiAgICAgIGlmKHRpbWVzdGVwKzEgPD0gbnJvdyhTRikpew0KICAgICAgICBpZihTRlt0aW1lc3RlcCsxLDJdPT0iRiIpIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94XSAqIEZFVkVSJGZbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dICoNCiAgICAgICAgICAgIHByb3hlbF9saXN0W1t0aW1lc3RlcF1dJEhuTU0kV0tUW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByZXZbcHJveF1dDQogICAgICAgIGlmKFNGW3RpbWVzdGVwKzEsMl09PSJuRiIpIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94XSAqIEZFVkVSJG5mW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlW3Byb3hdXSAqDQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXBdXSRIbk1NJFdLVFtwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcmV2W3Byb3hdXQ0KICAgICAgfQ0KICAgICAgDQogICAgICBpZigodGltZXN0ZXArMSklJTIgPT0gMCl7DQogICAgICAgIGlmKFNVW1NVWywxXT09dGltZXN0ZXArMSwyXT09IlVhIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgVVJJTkUkVWFbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICAgIGlmKFNVW1NVWywxXT09dGltZXN0ZXArMSwyXT09IlViIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgVVJJTkUkVWJbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICAgIGlmKFNVW1NVWywxXT09dGltZXN0ZXArMSwyXT09IlVjIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgVVJJTkUkVWNbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICB9DQogICAgICANCiAgICAgIGlmKCh0aW1lc3RlcCsxKSUlMyA9PSAwKXsNCiAgICAgICAgaWYoU0JbU0JbLDFdPT10aW1lc3RlcCsxLDJdPT0iQmEiKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSA9IHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdICogcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94XSAqDQogICAgICAgICAgICBCTE9PRCRCYVtwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZVtwcm94XV0NCiAgICAgICAgaWYoU0JbU0JbLDFdPT10aW1lc3RlcCsxLDJdPT0iQmIiKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSA9IHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdICogcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94XSAqDQogICAgICAgICAgICBCTE9PRCRCYltwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZVtwcm94XV0NCiAgICAgICAgaWYoU0JbU0JbLDFdPT10aW1lc3RlcCsxLDJdPT0iQmMiKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSA9IHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdICogcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94XSAqDQogICAgICAgICAgICBCTE9PRCRCY1twcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZVtwcm94XV0NCiAgICAgIH0NCiAgICB9DQogICAgDQogICAgaWYoUHJpbnQpIHByaW50KHBhc3RlKCJUaW1lIHN0ZXA6Iix0aW1lc3RlcCkpDQogICAgaWYoUHJpbnQpIHByaW50KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0pDQogICAgDQogICAgcHJveGVsX2RmW3RpbWVzdGVwKzEsMV09dGltZXN0ZXAqZGVsdGENCiAgICBmb3IgKHYgaW4gMjo0KSB7DQogICAgICBpZihsZW5ndGgocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJvYltwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZSA9PSB2LTFdKSAhPSAwKSB7DQogICAgICAgIHByb3hlbF9kZlt0aW1lc3RlcCsxLHZdID0gcm91bmQoc3VtKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGUgPT0gdi0xXSksNSl9DQogICAgICAgICAgZWxzZSBwcm94ZWxfZGZbdGltZXN0ZXArMSx2XSA9IDANCiAgICB9DQogICAgcHJveGVsX2RmW3RpbWVzdGVwKzEsNV09cm91bmQoMS1zdW0ocHJveGVsX2RmW3RpbWVzdGVwKzEsMjo0XSksNSkNCiAgICAgIA0KICB9DQogIA0KICBpZihSRVRVUk49PSJUUkVFIikgcmV0dXJuKHByb3hlbF9saXN0KQ0KICBpZihSRVRVUk49PSJERiIpIHJldHVybihwcm94ZWxfZGYpDQp9DQpwcm94ZWxfbGlzdD1Qcm94ZWxfYWxnbyhSRyxzdGFydHByb3hlbCxkZWx0YSxtYXgudHMsRiwiVFJFRSIsRkVWRVIsQkxPT0QsVVJJTkUscGF0aWVudDEpDQoNCmBgYA0KDQojIyBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgZ2l2ZW4gc2VxdWVuY2Ugb2Ygc3ltcHRvbXMgKHBhdGllbnQxLnNlcSk/DQoNCmBgYHtyfQ0KUHJvYl9kaXMxID0gc3VtKHByb3hlbF9saXN0W1sxM11dJEhuTU0kV0tUKQ0KYGBgDQoNCiogUHJvYiA9IGByIFByb2JfZGlzMWANCg0KIyMgV2hhdCBhcmUgdGhlIDUgbW9zdCBsaWtlbHkgZ2VuZXJhdGluZyBwYXRocyBvZiB0aGF0IHNlcXVlbmNlPyAmIFdoYXQgYXJlIHRoZSBhY3R1YWwgcG9ydGlvbnMgb2YgdGltZSBzcGVudCBpbiBlYWNoIGRpc2Vhc2Ugc3RhZ2UgZm9yIGVhY2ggb2YgdGhlc2UgcGF0aHM/IA0KDQoNCmBgYHtyfQ0Kb3JkPW9yZGVyKHByb3hlbF9saXN0W1sxM11dJEhuTU0kV0tULGRlY3JlYXNpbmcgPSBUKQ0KYGBgDQpgYGB7ciBldmFsPUZBTFNFfQ0KYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbMV1dXSkNCnByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbIldLVCJdXVtbb3JkWzFdXV0NCnRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzFdXV0pKQ0KDQphcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFsyXV1dKQ0KcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbMl1dXQ0KYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbMl1dXSkgfD4gdGFibGUoKQ0KDQphcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFszXV1dKQ0KcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbM11dXQ0KYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbM11dXSkgfD4gdGFibGUoKQ0KDQphcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs0XV1dKQ0KcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbNF1dXQ0KYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbNF1dXSkgfD4gdGFibGUoKQ0KDQphcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs1XV1dKQ0KcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbNV1dXQ0KYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbNV1dXSkgfD4gdGFibGUoKQ0KDQpgYGANCjEuIFBhdGg6IGByIGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzFdXV0pYA0KICAgKyBQcm9iID0gYHIgcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbMV1dXWANCiAgICsgZGF5cyBpbiBzdGFnZS4uLiANCiAgICAgICsgMTogIGByIHRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzFdXV0pKVsxXWANCiAgICAgICsgMjogIGByIHRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzFdXV0pKVsyXWAgIA0KICAgICAgDQoyLiBQYXRoOiBgciBhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFsyXV1dKWANCiAgICsgUHJvYiA9IGByIHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbIldLVCJdXVtbb3JkWzJdXV1gDQogICArIGRheXMgaW4gc3RhZ2UuLi4gDQogICAgICArIDE6ICBgciB0YWJsZShhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFsyXV1dKSlbMV1gDQogICAgICArIDI6ICBgciB0YWJsZShhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFsyXV1dKSlbMl1gICANCiAgICAgIA0KMy4gUGF0aDogYHIgYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbM11dXSlgDQogICArIFByb2IgPSBgciBwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJXS1QiXV1bW29yZFszXV1dYA0KICAgKyBkYXlzIGluIHN0YWdlLi4uIA0KICAgICAgKyAxOiAgYHIgdGFibGUoYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbM11dXSkpWzFdYA0KICAgICAgKyAyOiAgYHIgdGFibGUoYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbM11dXSkpWzJdYA0KICAgICAgKyAzOiAgYHIgdGFibGUoYXMudmVjdG9yKHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbInBvcy5wYXRoIl1dW1tvcmRbM11dXSkpWzNdYCAgDQogICAgICANCjQuIFBhdGg6IGByIGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzRdXV0pYA0KICAgKyBQcm9iID0gYHIgcHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1siV0tUIl1dW1tvcmRbNF1dXWANCiAgICsgZGF5cyBpbiBzdGFnZS4uLiANCiAgICAgICsgMTogIGByIHRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzRdXV0pKVsxXWANCiAgICAgICsgMjogIGByIHRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzRdXV0pKVsyXWANCiAgICAgICsgMzogIGByIHRhYmxlKGFzLnZlY3Rvcihwcm94ZWxfbGlzdFtbMTNdXVtbIkhuTU0iXV1bWyJwb3MucGF0aCJdXVtbb3JkWzRdXV0pKVszXWAgIA0KICAgICAgDQo1LiBQYXRoOiBgciBhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs1XV1dKWANCiAgICsgUHJvYiA9IGByIHByb3hlbF9saXN0W1sxM11dW1siSG5NTSJdXVtbIldLVCJdXVtbb3JkWzVdXV1gDQogICArIGRheXMgaW4gc3RhZ2UuLi4gDQogICAgICArIDE6ICBgciB0YWJsZShhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs1XV1dKSlbMV1gDQogICAgICArIDI6ICBgciB0YWJsZShhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs1XV1dKSlbMl1gDQogICAgICArIDM6ICBgciB0YWJsZShhcy52ZWN0b3IocHJveGVsX2xpc3RbWzEzXV1bWyJIbk1NIl1dW1sicG9zLnBhdGgiXV1bW29yZFs1XV1dKSlbM11gICANCg0KIyMgQ29kZSAyOg0KDQoqQWLDpG5kZXJ1bmcgZGVzIEhuTU0tUHJvZ3JhbW1zIGbDvHIgRGlzZWFzZSAyKg0KYGBge3J9DQptYXgudHMgPSAxMg0KZGVsdGEgPSAxDQpzdGFydHByb3hlbD1jKDEsMCwwLDEsMCkNClJHPW1hdHJpeChjKDEsMSwwLDEsDQogICAgICAgICAgICAwLDEsMSwxLA0KICAgICAgICAgICAgMCwwLDEsMSwNCiAgICAgICAgICAgIDAsMCwwLDEpLG5jb2wgPSA0LGJ5cm93ID0gVCkNCkZFVkVSMj1kYXRhLmZyYW1lKG5mPWMoMC43LDAuMywwLjEsMSksZj1jKDAuMywwLjcsMC45LDApKQ0KQkxPT0QyPWRhdGEuZnJhbWUoQmE9YyguNywuNSwuMiksQmI9YyguMiwuMywuMyksQmM9YyguMSwuMiwuNSkpDQpVUklORTI9ZGF0YS5mcmFtZShVYT1jKC44LC43LC43KSxVYj1jKC4yLC4yLC4yKSxVYz1jKC4wLC4xLC4xKSkNCg0KUHJveGVsX2FsZ28yPWZ1bmN0aW9uKFJHLHN0YXJ0cHJveGVsLGRlbHRhLG1heC50cyxQcmludD1ULFJFVFVSTixGRVZFUj1OQSxCTE9PRD1OQSxVUklORT1OQSxTRVE9TkEpew0KICANCiAgU0Y9c3Vic2V0KFNFUSxTRVFbLDJdICVpbiUgYygiRiIsIm5GIikpDQogIFNCPXN1YnNldChTRVEsU0VRWywyXSAlaW4lIGMoIkJhIiwiQmIiLCJCYyIpKQ0KICBTVT1zdWJzZXQoU0VRLFNFUVssMl0gJWluJSBjKCJVYSIsIlViIiwiVWMiKSkNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIG5vcm1hbHBkZiA8LSBmdW5jdGlvbih4LCBtLCBzKSB7DQogIHogPC0gKHggLSBtKSAvIHMNCiAgcmV0dXJuIChleHAoLXpeMiAvIDIpIC8gKHNxcnQoMiAqIHBpKSAqIHMpKQ0KfQ0KDQpsb2dHYW1tYSA8LSBmdW5jdGlvbih4KSB7DQogIGNvZWYgPC0gYyg3Ni4xODAwOTE3MywgLTg2LjUwNTMyMDMzLCAyNC4wMTQwOTgyMiwgLTEuMjMxNzM5NTE2LCAwLjAwMTIwODU4MDAzLCAtMC4wMDAwMDUzNjM4MikNCiAgc3RlcCA8LSAyLjUwNjYyODI3NDY1DQogIGZwZiA8LSA1LjUNCiAgdCA8LSB4IC0gMQ0KICB0bXAgPC0gdCArIGZwZg0KICB0bXAgPC0gKHQgKyAwLjUpICogbG9nKHRtcCkgLSB0bXANCiAgc2VyIDwtIDENCiAgZm9yIChpIGluIDE6Nikgew0KICAgIHQgPC0gdCArIDENCiAgICBzZXIgPC0gc2VyICsgY29lZltpXSAvIHQNCiAgfQ0KICByZXR1cm4gKHRtcCArIGxvZyhzdGVwICogc2VyKSkNCn0NCg0KZ2FtbWFTZXJpZXMgPC0gZnVuY3Rpb24oeCwgYSkgew0KICBtYXhpdCA8LSAxMDANCiAgZXBzIDwtIDAuMDAwMDAwMw0KICBzdW0gPC0gMS4wIC8gYQ0KICBhcCA8LSBhDQogIGdsbiA8LSBsb2dHYW1tYShhKQ0KICBkZWwgPC0gc3VtDQoNCiAgZm9yIChuIGluIDE6bWF4aXQpIHsNCiAgICBhcCA8LSBhcCArIDENCiAgICBkZWwgPC0gZGVsICogeCAvIGFwDQogICAgc3VtIDwtIHN1bSArIGRlbA0KICAgIGlmIChhYnMoZGVsKSA8IGFicyhzdW0pICogZXBzKSBicmVhaw0KICB9DQogIHJldHVybiAoc3VtICogZXhwKC14ICsgYSAqIGxvZyh4KSAtIGdsbikpDQp9DQoNCmdhbW1hQ0YgPC0gZnVuY3Rpb24oeCwgYSkgew0KICBtYXhpdCA8LSAxMDANCiAgZXBzIDwtIDAuMDAwMDAwMw0KICBnbG4gPC0gbG9nR2FtbWEoYSkNCiAgZyA8LSAwDQogIGdvbGQgPC0gMA0KICBhMCA8LSAxDQogIGExIDwtIHgNCiAgYjAgPC0gMA0KICBiMSA8LSAxDQogIGZhYyA8LSAxDQogIGFuIDwtIDANCiAgYW5hIDwtIDANCiAgYW5mIDwtIDANCg0KICBmb3IgKG4gaW4gMTptYXhpdCkgew0KICAgIGFuIDwtIDEuMCAqIG4NCiAgICBhbmEgPC0gYW4gLSBhDQogICAgYTAgPC0gKGExICsgYTAgKiBhbmEpICogZmFjDQogICAgYjAgPC0gKGIxICsgYjAgKiBhbmEpICogZmFjDQogICAgYW5mIDwtIGFuICogZmFjDQogICAgYTEgPC0geCAqIGEwICsgYW5mICogYTENCiAgICBiMSA8LSB4ICogYjAgKyBhbmYgKiBiMQ0KICAgIGlmIChhMSAhPSAwKSB7DQogICAgICBmYWMgPC0gMS4wIC8gYTENCiAgICAgIGcgPC0gYjEgKiBmYWMNCiAgICAgIGlmIChhYnMoKGcgLSBnb2xkKSAvIGcpIDwgZXBzKSBicmVhaw0KICAgICAgZ29sZCA8LSBnDQogICAgfQ0KICB9DQogIHJldHVybiAoZXhwKC14ICsgYSAqIGxvZyh4KSAtIGdsbikgKiBnKQ0KfQ0KDQpnYW1tYWNkZiA8LSBmdW5jdGlvbih4LCBhKSB7DQogIGlmICh4IDw9IDApDQogICAgcmV0dXJuICgwKQ0KICBlbHNlIGlmICh4IDwgYSArIDEpDQogICAgcmV0dXJuIChnYW1tYVNlcmllcyh4LCBhKSkNCiAgZWxzZQ0KICAgIHJldHVybiAoMSAtIGdhbW1hQ0YoeCwgYSkpDQp9DQoNCm5vcm1hbGNkZiA8LSBmdW5jdGlvbih4LCBtLCBzKSB7DQogIHogPC0gKHggLSBtKSAvIHMNCiAgaWYgKHogPj0gMCkNCiAgICByZXR1cm4gKDAuNSArIDAuNSAqIGdhbW1hY2RmKHpeMiAvIDIsIDAuNSkpDQogIGVsc2UNCiAgICByZXR1cm4gKDAuNSAtIDAuNSAqIGdhbW1hY2RmKHpeMiAvIDIsIDAuNSkpDQp9DQoNCm5vcm1hbGhyZiA8LSBmdW5jdGlvbih4LCBtLCBzKSB7DQogIHJldHVybiAobm9ybWFscGRmKHgsIG0sIHMpIC8gKDEgLSBub3JtYWxjZGYoeCwgbSwgcykpKQ0KfQ0KICANCiAgdW5paHJmIDwtIGZ1bmN0aW9uKGFnZSwgYSwgYikgew0KICAgIGlmIChhIDw9IGFnZSAmJiBhZ2UgPCBiKSB7DQogICAgICByZXR1cm4gKDEuMCAvIChiIC0gYWdlKSkNCiAgICB9IGVsc2Ugew0KICAgICAgcmV0dXJuICgwKQ0KICAgIH0NCiAgfQ0KICANCiAgZXhwaHJmIDwtIGZ1bmN0aW9uKGFnZSwgbCkgew0KICAgIHJldHVybiAobCkNCiAgfQ0KICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgDQogIHByb3hlbF9kZj1kYXRhLmZyYW1lKHRhdT1udW1lcmljKCksUzE9bnVtZXJpYygpLFMyPW51bWVyaWMoKSxTMz1udW1lcmljKCksSD1udW1lcmljKCkpDQogIA0KICBwcm94ZWxfbGlzdD1saXN0KCkNCiAgcHJveGVsX2xpc3RbW21heC50cysxXV09bGlzdCgpDQogIHByb3hlbF9saXN0W1sxXV09bGlzdCh0aW1lc3RlcD1jKDApLHByb3hlbD1kYXRhLmZyYW1lKHN0YXRlPXN0YXJ0cHJveGVsWzFdLHRhdT1zdGFydHByb3hlbFsyXSx0YXVfaz1zdGFydHByb3hlbFszXSxwcm9iPXN0YXJ0cHJveGVsWzRdLHByZXY9c3RhcnRwcm94ZWxbNV0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgSG5NTT10aWR5cjo6dGliYmxlKHBvcy5wYXRoPWxpc3QoYygxKSksV0tUPUZFVkVSWzEsMV0pKQ0KICANCiAgaWYoUHJpbnQpIHByaW50KCJpbml0aWFsIHByb3hlbDoiKQ0KICBpZihQcmludCkgcHJpbnQocHJveGVsX2xpc3RbWzFdXSkNCiAgDQogIHByb3hlbF9kZlsxLF09YygwLHByb3hlbF9saXN0W1sxXV0kcHJveGVsJHByb2JbcHJveGVsX2xpc3RbWzFdXSRwcm94ZWwkc3RhdGUgPT0gMV0sMCwwLDApDQogIA0KICBmb3IgKHRpbWVzdGVwIGluIDE6bWF4LnRzKSB7DQogICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXT1saXN0KHRpbWVzdGVwPWModGltZXN0ZXApLHByb3hlbD1kYXRhLmZyYW1lKHN0YXRlPW51bWVyaWMoKSx0YXU9bnVtZXJpYygpLHRhdV9rPW51bWVyaWMoKSxwcm9iPW51bWVyaWMoKSxwcmV2PW51bWVyaWMoKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhuTU09dGlkeXI6OnRpYmJsZShwb3MucGF0aD1saXN0KCksV0tUPW51bWVyaWMoKSkpICAgICAjIGVyc3RlbGxlIHNjaG9ubWFsIGVpbmUgbmV1ZSBsZWVyZSBsaXN0ZSBmw7xyIGRlbiBuw6RjaHN0ZW4gdGltZXN0ZXANCiAgICANCiAgICBmb3IgKGwgaW4gMTpucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcF1dJHByb3hlbCkpIHsNCiAgICAgIGN1cnJwcm94ID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwXV0kcHJveGVsW2wsXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFrdHVlbGxlciBwcm94ZWwgenUgZGVtIGZvbGdlcHJveGVscyBlcnpldWd0IHdlcmRlbiBzb2xsZW4NCiAgICAgIGZvbGdlciA9IFJHW2FzLm51bWVyaWMoY3VycnByb3hbMV0pLF0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZvbGdlc3RhdGVzIHZvbiBha3R1ZWxsZW0gcHJveGVsDQogICAgICANCiAgICAgIGZvciAoaSBpbiAxOjQpIHsNCiAgICAgICAgaWYgKGZvbGdlcltpXT09MSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGVyc3RlbGxlIGZvbGdlcHJveGVsIGZhbGxzIHBmZWlsIGRhaGluIGdpYnQNCiAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSsxLDFdID0gaSAgICAgICAgICAgICAgICAgICAgICAgIyBzdGF0ZSB2b20gbsOkY2hzdGVuIHByb3hlbA0KICAgICAgICAgIA0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT1pKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSwyXSA9IGN1cnJwcm94JHRhdSArIGRlbHRhDQogICAgICAgICAgICBlbHNlIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsW25yb3cocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwpLDJdID0gMCAgICAgICAgICAgICAgICAgICAgIyB0YXUgdm9tIG7DpGNoc3RlbiBwcm94ZWwNCiAgICAgICAgICANCiAgICAgICAgICBpZihjdXJycHJveCRzdGF0ZSAlaW4lIGMoMSwyLDMpICYgaSE9NCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSBjdXJycHJveCR0YXVfayArIGRlbHRhDQogICAgICAgICAgICBlbHNlIGlmKGN1cnJwcm94JHN0YXRlPT00ICYgaT09NCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSBjdXJycHJveCR0YXVfayAtIGRlbHRhDQogICAgICAgICAgICAgIGVsc2UgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksM10gPSAwICAgICAgICAgICAgICAgICAgICMgdGF1X2sgdm9tIG7DpGNoc3RlbiBwcm94ZWwNCiAgICAgICAgICAgIA0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0xICYgaT09Mikgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAobm9ybWFsaHJmKGN1cnJwcm94JHRhdV9rLDMsMC41KSAqIGRlbHRhKSAqIGN1cnJwcm94JHByb2J9ICAgICAgICAgICAjIHRyYW5zaXRpb24gdm9uIFMxIHp1IFMyDQogICAgICAgICAgaWYoY3VycnByb3gkc3RhdGU9PTIgJiBpPT0zKSB7DQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSw0XSA9IChleHBocmYoY3VycnByb3gkdGF1X2ssMC4zKSAqIGRlbHRhKSAqIGN1cnJwcm94JHByb2J9ICAgICAgICAgICAjIHRyYW5zaXRpb24gdm9uIFMyIHp1IFMzDQogICAgICAgICAgaWYoY3VycnByb3gkc3RhdGUhPTQgJiBpPT00KSB7DQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSw0XSA9IChub3JtYWxocmYoY3VycnByb3gkdGF1X2ssMTAsMikqIGRlbHRhKSAqIGN1cnJwcm94JHByb2J9ICAgICAgICAgICAjIHRyYW5zdGlvbiB6dSBoZWFsIHZvbiBTMSxTMiBvZGVyIFMzDQogICAgICAgICAgaWYoY3VycnByb3gkc3RhdGU9PTEgJiBpPT0xKSB7DQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSw0XSA9ICgxIC0gKG5vcm1hbGhyZihjdXJycHJveCR0YXVfaywzLDAuNSkgKiBkZWx0YSkgLSAobm9ybWFsaHJmKGN1cnJwcm94JHRhdV9rLDEwLDIpICogZGVsdGEpKSAqIGN1cnJwcm94JHByb2J9DQogICAgICAgICAgaWYoY3VycnByb3gkc3RhdGU9PTIgJiBpPT0yKSB7DQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSw0XSA9ICgxIC0gKGV4cGhyZihjdXJycHJveCR0YXVfaywwLjMpICogZGVsdGEpIC0gKG5vcm1hbGhyZihjdXJycHJveCR0YXVfaywxMCwyKSAqIGRlbHRhKSkgKiBjdXJycHJveCRwcm9ifQ0KICAgICAgICAgIGlmKGN1cnJwcm94JHN0YXRlPT0zICYgaT09Mykgew0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbbnJvdyhwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCksNF0gPSAoMSAtIChub3JtYWxocmYoY3VycnByb3gkdGF1X2ssMTAsMikgKiBkZWx0YSkpICogY3VycnByb3gkcHJvYn0NCiAgICAgICAgICBpZihjdXJycHJveCRzdGF0ZT09NCAmIGk9PTQpIHsNCiAgICAgICAgICAgIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsW25yb3cocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwpLDRdID0gMSB9DQogICAgICAgICAgICAgIA0KICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFtucm93KHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsKSw1XSA9IGwgICANCiAgICAgICAgICAgDQogICAgICAgIH0NCiAgICAgIH0gDQogICAgfQ0KICAgIA0KICAgIGlmKGxlbmd0aCh3aGljaChwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFssNF08PTApKSE9MCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWw9cHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbLXdoaWNoKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsWyw0XTw9MCksXQ0KICAgIGlmKGxlbmd0aCh3aGljaChwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbFssM108IDApKSE9MCkgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWw9cHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWxbLXdoaWNoKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsWywzXTwgMCksXQ0KICAgIA0KICAgIGZvciAocHJveCBpbiAxOm5yb3cocHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwpKSB7DQogICAgICANCiAgICAgIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDFdW1sxXV0gPSBsaXN0KGModW5saXN0KHByb3hlbF9saXN0W1t0aW1lc3RlcF1dJEhuTU1bcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJldltwcm94XSwxXSkscHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF0pKQ0KICAgICAgDQogICAgICBpZih0aW1lc3RlcCsxIDw9IG5yb3coU0YpKXsNCiAgICAgICAgaWYoU0ZbdGltZXN0ZXArMSwyXT09IkYiKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSA9IHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKiBGRVZFUiRmW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlW3Byb3hdXSAqDQogICAgICAgICAgICBwcm94ZWxfbGlzdFtbdGltZXN0ZXBdXSRIbk1NJFdLVFtwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcmV2W3Byb3hdXQ0KICAgICAgICBpZihTRlt0aW1lc3RlcCsxLDJdPT0ibkYiKSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSA9IHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKiBGRVZFUiRuZltwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRzdGF0ZVtwcm94XV0gKg0KICAgICAgICAgICAgcHJveGVsX2xpc3RbW3RpbWVzdGVwXV0kSG5NTSRXS1RbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkcHJldltwcm94XV0NCiAgICAgIH0NCiAgICAgIA0KICAgICAgaWYoKHRpbWVzdGVwKzEpJSUyID09IDApew0KICAgICAgICBpZihTVVtTVVssMV09PXRpbWVzdGVwKzEsMl09PSJVYSIpIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gKiBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcm9iW3Byb3hdICoNCiAgICAgICAgICAgIFVSSU5FJFVhW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlW3Byb3hdXQ0KICAgICAgICBpZihTVVtTVVssMV09PXRpbWVzdGVwKzEsMl09PSJVYiIpIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gKiBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcm9iW3Byb3hdICoNCiAgICAgICAgICAgIFVSSU5FJFViW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlW3Byb3hdXQ0KICAgICAgICBpZihTVVtTVVssMV09PXRpbWVzdGVwKzEsMl09PSJVYyIpIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kSG5NTVtwcm94LDJdID0gcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gKiBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcm9iW3Byb3hdICoNCiAgICAgICAgICAgIFVSSU5FJFVjW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlW3Byb3hdXQ0KICAgICAgfQ0KICAgICAgDQogICAgICBpZigodGltZXN0ZXArMSklJTMgPT0gMCl7DQogICAgICAgIGlmKFNCW1NCWywxXT09dGltZXN0ZXArMSwyXT09IkJhIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgQkxPT0QkQmFbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICAgIGlmKFNCW1NCWywxXT09dGltZXN0ZXArMSwyXT09IkJiIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgQkxPT0QkQmJbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICAgIGlmKFNCW1NCWywxXT09dGltZXN0ZXArMSwyXT09IkJjIikgcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRIbk1NW3Byb3gsMl0gPSBwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJEhuTU1bcHJveCwyXSAqIHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveF0gKg0KICAgICAgICAgICAgQkxPT0QkQmNbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGVbcHJveF1dDQogICAgICB9DQogICAgfQ0KICAgIA0KICAgIGlmKFByaW50KSBwcmludChwYXN0ZSgiVGltZSBzdGVwOiIsdGltZXN0ZXApKQ0KICAgIGlmKFByaW50KSBwcmludChwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dKQ0KICAgIA0KICAgIHByb3hlbF9kZlt0aW1lc3RlcCsxLDFdPXRpbWVzdGVwKmRlbHRhDQogICAgZm9yICh2IGluIDI6NCkgew0KICAgICAgaWYobGVuZ3RoKHByb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHByb2JbcHJveGVsX2xpc3RbW3RpbWVzdGVwKzFdXSRwcm94ZWwkc3RhdGUgPT0gdi0xXSkgIT0gMCkgew0KICAgICAgICBwcm94ZWxfZGZbdGltZXN0ZXArMSx2XSA9IHJvdW5kKHN1bShwcm94ZWxfbGlzdFtbdGltZXN0ZXArMV1dJHByb3hlbCRwcm9iW3Byb3hlbF9saXN0W1t0aW1lc3RlcCsxXV0kcHJveGVsJHN0YXRlID09IHYtMV0pLDUpfQ0KICAgICAgICAgIGVsc2UgcHJveGVsX2RmW3RpbWVzdGVwKzEsdl0gPSAwDQogICAgfQ0KICAgIHByb3hlbF9kZlt0aW1lc3RlcCsxLDVdPXJvdW5kKDEtc3VtKHByb3hlbF9kZlt0aW1lc3RlcCsxLDI6NF0pLDUpDQogICAgICANCiAgfQ0KICANCiAgaWYoUkVUVVJOPT0iVFJFRSIpIHJldHVybihwcm94ZWxfbGlzdCkNCiAgaWYoUkVUVVJOPT0iREYiKSByZXR1cm4ocHJveGVsX2RmKQ0KfQ0KcHJveGVsX2xpc3QyPVByb3hlbF9hbGdvMihSRyxzdGFydHByb3hlbCxkZWx0YSxtYXgudHMsRiwiVFJFRSIsRkVWRVIyLEJMT09EMixVUklORTIscGF0aWVudDEpDQpgYGANCg0KIyMgQ29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgb2YgZWFjaCBkaXNlYXNlLg0KDQpgYGB7cn0NClByb2JfZGlzMj1zdW0ocHJveGVsX2xpc3QyW1sxM11dJEhuTU0kV0tUKQ0KI1Byb2JfZGlzMj5Qcm9iX2RpczENCmBgYA0KDQoqIFByb2IoRGlzZWFzZSAxKSA9IGByIFByb2JfZGlzMWANCiogUHJvYihEaXNlYXNlIDIpID0gYHIgUHJvYl9kaXMyYA0KDQoNCiMjIFdoaWNoIGRpc2Vhc2UgaXMgdGhlIHBhdGllbnQgbW9zdCBsaWtlbHkgc3VmZmVyaW5nIGZyb20/IA0KDQoqICpQcm9iKERpc2Vhc2UgMSkgPCBQcm9iKERpc2Vhc2UgMikqIC0tPiAgKipzdWZmZXJpbmcgZnJvbSBkaXNlYXNlIDIqKg0KDQojIyBXZSBoYXZlIGZ1cnRoZXIgbWVhc3VyZW1lbnRzIGZyb20gcGF0aWVudHMgKDItNSkgdGhhdCB3ZXJlIGluZmVjdGVkIGJ5IG91ciBvcmlnaW5hbCBzdWJqZWN0LCBzbyB0aGV5IG11c3QgYmUgc3VmZmVyaW5nIGZyb20gdGhlIHNhbWUgZGlzZWFzZS4gV2hhdCBkb2VzIHlvdXIgcHJvZ3JhbSBzYXkgdG8gdGhhdCBjbGFpbT8gDQoNCmBgYHtyfQ0KcGF0Ml9BPVByb3hlbF9hbGdvKFJHLHN0YXJ0cHJveGVsLGRlbHRhLDksRiwiVFJFRSIsRkVWRVIsQkxPT0QsVVJJTkUscGF0aWVudDIpDQpwYXQyX0I9UHJveGVsX2FsZ28yKFJHLHN0YXJ0cHJveGVsLGRlbHRhLDksRiwiVFJFRSIsRkVWRVIyLEJMT09EMixVUklORTIscGF0aWVudDIpDQpwYXQzX0E9UHJveGVsX2FsZ28oUkcsc3RhcnRwcm94ZWwsZGVsdGEsNyxGLCJUUkVFIixGRVZFUixCTE9PRCxVUklORSxwYXRpZW50MykNCnBhdDNfQj1Qcm94ZWxfYWxnbzIoUkcsc3RhcnRwcm94ZWwsZGVsdGEsNyxGLCJUUkVFIixGRVZFUjIsQkxPT0QyLFVSSU5FMixwYXRpZW50MykNCnBhdDRfQT1Qcm94ZWxfYWxnbyhSRyxzdGFydHByb3hlbCxkZWx0YSwxMSxGLCJUUkVFIixGRVZFUixCTE9PRCxVUklORSxwYXRpZW50NCkNCnBhdDRfQj1Qcm94ZWxfYWxnbzIoUkcsc3RhcnRwcm94ZWwsZGVsdGEsMTEsRiwiVFJFRSIsRkVWRVIyLEJMT09EMixVUklORTIscGF0aWVudDQpDQpwYXQ1X0E9UHJveGVsX2FsZ28oUkcsc3RhcnRwcm94ZWwsZGVsdGEsNixGLCJUUkVFIixGRVZFUixCTE9PRCxVUklORSxwYXRpZW50NSkNCnBhdDVfQj1Qcm94ZWxfYWxnbzIoUkcsc3RhcnRwcm94ZWwsZGVsdGEsNixGLCJUUkVFIixGRVZFUjIsQkxPT0QyLFVSSU5FMixwYXRpZW50NSkNCg0KYGBgDQpgYGB7ciBldmFsPUZBTFNFfQ0Kc3VtKHBhdDJfQVtbMTBdXSRIbk1NJFdLVCxuYS5ybSA9IFQpIDwgc3VtKHBhdDJfQltbMTBdXSRIbk1NJFdLVCxuYS5ybSA9IFQpDQpzdW0ocGF0M19BW1s4XV0kSG5NTSRXS1QsbmEucm0gPSBUKSA8IHN1bShwYXQzX0JbWzhdXSRIbk1NJFdLVCxuYS5ybSA9IFQpDQpzdW0ocGF0NF9BW1sxMl1dJEhuTU0kV0tULG5hLnJtID0gVCkgPCBzdW0ocGF0NF9CW1sxMl1dJEhuTU0kV0tULG5hLnJtID0gVCkNCnN1bShwYXQ1X0FbWzddXSRIbk1NJFdLVCxuYS5ybSA9IFQpIDwgc3VtKHBhdDVfQltbN11dJEhuTU0kV0tULG5hLnJtID0gVCkNCmBgYA0KKiBQYXRpZW50IDI6DQogICArICoqUHJvYihEMSkgPSBgciBzdW0ocGF0Ml9BW1sxMF1dJEhuTU0kV0tULG5hLnJtID0gVClgKioNCiAgICsgUHJvYihEMikgPSBgciBzdW0ocGF0Ml9CW1sxMF1dJEhuTU0kV0tULG5hLnJtID0gVClgDQoNCiogUGF0aWVudCAzOg0KICAgKyBQcm9iKEQxKSA9IGByIHN1bShwYXQzX0FbWzhdXSRIbk1NJFdLVCxuYS5ybSA9IFQpYA0KICAgKyAqKlByb2IoRDIpID0gYHIgc3VtKHBhdDNfQltbOF1dJEhuTU0kV0tULG5hLnJtID0gVClgKioNCiAgIA0KKiBQYXRpZW50IDQ6DQogICArIFByb2IoRDEpID0gYHIgc3VtKHBhdDRfQVtbMTJdXSRIbk1NJFdLVCxuYS5ybSA9IFQpYA0KICAgKyAqKlByb2IoRDIpID0gYHIgc3VtKHBhdDRfQltbMTJdXSRIbk1NJFdLVCxuYS5ybSA9IFQpYCoqDQoNCiogUGF0aWVudCA1Og0KICAgKyBQcm9iKEQxKSA9IGByIHN1bShwYXQ1X0FbWzddXSRIbk1NJFdLVCxuYS5ybSA9IFQpYA0KICAgKyAqKlByb2IoRDIpID0gYHIgc3VtKHBhdDVfQltbN11dJEhuTU0kV0tULG5hLnJtID0gVClgKioNCg0KKiAqKmV4Y2VwdCBwYXRpZW50IDIgYWxsIHRoZSBvdGhlcnMgYWxzbyBzdWZmZXJpbmcgZnJvbSBkaXNlYXNlIDIqKg0KDQo=