require(ggplot2)
require(ggExtra)
require(hrbrthemes)
require(extrafont)
require(gridExtra)
require(ggrepel)
require(goftest)
theme_set(theme_ipsum(base_family = "Times New Roman", 
              base_size = 10, axis_title_size = 10))

First, read the data,

HC.BP = data.frame("H" = numeric(16000), 
                   "C" = numeric(16000),
                   "Dist" = numeric(16000),
                   "D" = numeric(16000),
                   "N" = numeric(16000), 
                   stringsAsFactors=FALSE)
filecsv = data.frame(read.csv("../Data/HC_series_fk0_16000.csv"))
HC.BP$H = filecsv[,1]
HC.BP$C = filecsv[,2]
HC.BP$D = as.factor(filecsv[,3])
HC.BP$N = as.factor(rep(c(rep(1e+04, 100), rep(2e+04, 100), rep(3e+04, 100), rep(4e+04, 100), rep(5e+04, 100), rep(6e+04, 100), rep(7e+04, 100), rep(8e+04, 100), rep(9e+04, 100), rep(1e+05, 100)), 16))
summary(HC.BP)
       H                C                  Dist   D              N       
 Min.   :0.9199   Min.   :0.0002271   Min.   :0   3:4000   10000  :1600  
 1st Qu.:0.9869   1st Qu.:0.0041165   1st Qu.:0   4:4000   20000  :1600  
 Median :0.9924   Median :0.0075186   Median :0   5:4000   30000  :1600  
 Mean   :0.9902   Mean   :0.0096574   Mean   :0   6:4000   40000  :1600  
 3rd Qu.:0.9959   3rd Qu.:0.0128926   3rd Qu.:0            50000  :1600  
 Max.   :0.9998   Max.   :0.0745442   Max.   :0            60000  :1600  
                                                           (Other):6400  
ggplot(data = HC.BP, aes(x = H, y = C, color = D)) +
  geom_point(size = 3) +
  labs(title = "Points in the HxC plane",
       x = expression(italic(H)),
       y = expression(italic(C))
  )

Now separated by the embedding dimension \(D\).

ggplot(data=HC.BP, aes(x=H, y=C, color=D)) +
  geom_point(size=2) +
  labs(title="Points in the HxC plane",
       x=expression(italic(H)),
       y=expression(italic(C))) +
  facet_grid(.~D)

We see a seemingly linear trend, but at this point we have to recall that \(C=HD\), in which \(D\) is a distance (in this case, the Jensen-Shannon distance) to an equilibrium distribution (in this case, the Uniform law).

In order to see the relationship between the variables we are studying, let’s look at \(H\times D\).

HC.BP$Dist = HC.BP$C / HC.BP$H
ggplot(data=HC.BP, aes(x=Dist, y=C, color=D)) +
  geom_point(size=2) +
  labs(title="Points in the Dist x C plane",
       x="Dist",
       y=expression(italic(C))) +
  facet_grid(.~D)

ggplot(data=HC.BP, aes(x=H, y=Dist, color=D)) +
  geom_point(size=2) +
  labs(title="Points in the H x Dist plane",
       x=expression(italic(H)),
       y="Dist") +
  facet_grid(.~D)

We will take N out of the data frame, in order to use the default regression in ggplot

HC.BP.regression.data = HC.BP[,-3]
lm.HC = lm(data=HC.BP.regression.data, formula = C ~ H * D)
summary(lm.HC)

Call:
lm(formula = C ~ H * D, data = HC.BP.regression.data)

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0046003 -0.0000673 -0.0000218  0.0000608  0.0037435 

Coefficients:
              Estimate Std. Error   t value Pr(>|t|)    
(Intercept)  0.9778085  0.0005905  1655.768  < 2e-16 ***
H           -0.9777680  0.0005964 -1639.509  < 2e-16 ***
D4          -0.0024713  0.0008190    -3.018  0.00255 ** 
D5          -0.0018136  0.0008318    -2.180  0.02924 *  
D6          -0.0039134  0.0008092    -4.836 1.34e-06 ***
H:D4         0.0024901  0.0008271     3.011  0.00261 ** 
H:D5         0.0018344  0.0008400     2.184  0.02899 *  
H:D6         0.0039479  0.0008173     4.831 1.37e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0002963 on 15992 degrees of freedom
Multiple R-squared:  0.9986,    Adjusted R-squared:  0.9986 
F-statistic: 1.621e+06 on 7 and 15992 DF,  p-value: < 2.2e-16
hist(lm.HC$residuals, breaks = 200)

plot(lm.HC)

The above results suggest that there is no evidence against the use of the embedding dimension \(D\) as a factor in the linear regression model.

ggplot(HC.BP.regression.data, aes(x=H, y=C, colour=D)) +
  geom_point(size=2) +
  geom_smooth(method="lm", formula = y~x) +
  labs(title="Complexity explained by Entropy",
       x=expression(italic(H)),
       y=expression(italic(C)))

Now, let’s see the fitted lines in a semilogarithmic scale.

ggplot(HC.BP.regression.data, aes(x=H, y=C, colour=D)) +
  geom_point(size=2) +
  scale_y_log10() +
  geom_smooth(method="lm", formula = y~x) +
  labs(title="Complexity explained by Entropy",
       x=expression(italic(H)),
       y=expression(italic(C)~"[logarithmic scale]"))

  facet_grid(.~D)
<ggproto object: Class FacetGrid, Facet, gg>
    compute_layout: function
    draw_back: function
    draw_front: function
    draw_labels: function
    draw_panels: function
    finish_data: function
    init_scales: function
    map_data: function
    params: list
    setup_data: function
    setup_params: function
    shrink: TRUE
    train_scales: function
    vars: function
    super:  <ggproto object: Class FacetGrid, Facet, gg>

The model we are fitting is \[ \left\{ \begin{eqnarray*} C^{(3)} &= \beta_0^{(3)} + \beta_1^{(3)} H^{(3)},\\ C^{(4)} &= \beta_0^{(4)} + \beta_1^{(4)} H^{(4)},\\ C^{(5)} &= \beta_0^{(5)} + \beta_1^{(5)} H^{(5)},\\ C^{(6)} &= \beta_0^{(6)} + \beta_1^{(6)} H^{(6)}.\\ \end{eqnarray*} \right. \] in other words, a different linear relationship for each embedding dimension \(D\).

Let’s save the estimates and their confidence intervals.

beta0 <- c(
  lm.HC$coefficients[1],
  lm.HC$coefficients[1] + lm.HC$coefficients[3],
  lm.HC$coefficients[1] + lm.HC$coefficients[4],
  lm.HC$coefficients[1] + lm.HC$coefficients[5])
beta0inf <- c(
  confint(lm.HC)[1,1],
  beta0[2] - confint(lm.HC)[3,1],
  beta0[3] - confint(lm.HC)[4,1],
  beta0[4] - confint(lm.HC)[5,1])
beta0sup <- c(
  confint(lm.HC)[1,2],
  beta0[2] + confint(lm.HC)[3,2],
  beta0[3] + confint(lm.HC)[4,2],
  beta0[4] + confint(lm.HC)[5,2])
beta1 <- c(
  lm.HC$coefficients[2],
  lm.HC$coefficients[2] + lm.HC$coefficients[6],
  lm.HC$coefficients[2] + lm.HC$coefficients[7],
  lm.HC$coefficients[2] + lm.HC$coefficients[8])
beta1inf <-c(
  confint(lm.HC)[2,1],
  beta1[2] - confint(lm.HC)[6,1],
  beta1[3] - confint(lm.HC)[7,1],
  beta1[4] - confint(lm.HC)[8,1])
beta1sup <- c(
  confint(lm.HC)[2,2],
  beta1[2] + confint(lm.HC)[6,2],
  beta1[3] + confint(lm.HC)[7,2],
  beta1[4] + confint(lm.HC)[8,2])
estimates <- data.frame(beta0=beta0, 
                        beta0inf=beta0inf,
                        beta0sup=beta0sup,
                        beta1=beta1, 
                        beta1inf=beta1inf,
                        beta1sup=beta1sup,
                        D=3:6)
estimates

The fitted parameters are: \[ \left\{ \begin{eqnarray*} \widehat{\beta}_0^{(3)} =0.983 ,&\quad \widehat{\beta}_1^{(3)}=-0.983,\\ \widehat{\beta}_0^{(4)} =1.310 ,&\quad \widehat{\beta}_1^{(4)}=-1.310,\\ \widehat{\beta}_0^{(5)} =1.785 ,&\quad \widehat{\beta}_1^{(5)}=-1.785,\\ \widehat{\beta}_0^{(6)} =2.405 ,&\quad \widehat{\beta}_1^{(6)}=-2.405.\\ \end{eqnarray*} \right. \]

Let’s see how they behave.

plot.beta0 <- ggplot(data=estimates, aes(x=D, y=beta0)) +
  geom_point() +
  labs(title="Intercept vs. embedding dimension",
    x=expression(italic(D)),
    y=expression(widehat(beta)[0]))
plot.beta1 <- ggplot(data=estimates, aes(x=D, y=beta1)) +
  geom_point() +
    labs(title="Slope vs embedding dimension",
    x=expression(italic(D)),
    y=expression(widehat(beta)[1]))
grid.arrange(plot.beta0, plot.beta1, nrow=1)

The joint variation:

ggplot(data=estimates, aes(x=beta0, y=beta1)) + 
  geom_smooth(method = "lm", formula = y~x) +
  geom_point(size=2) +
#  geom_errorbar(aes(ymin=beta1inf, ymax=beta1sup)) +
#  geom_errorbarh(aes(xmin=beta0inf, xmax=beta0sup)) +
  geom_label_repel(data=estimates, aes(x=beta0, y=beta1, label=D),
                   direction = "x") +
  labs(title="Intercept vs Slope",
    x=expression(widehat(beta)[0]),
    y=expression(widehat(beta)[1])) +
    coord_fixed()

We verify there is a linear relationship between \(\widehat{\beta}_0\) and \(\widehat{\beta}_1\).

LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBBbmFseXNpczogUmVwb3J0IDAiCmF1dGhvcjogIkFsZWphbmRybyBGcmVyeSIKZGF0ZTogIkFwciA4LCAyMDIwIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KYGBge3J9CnJlcXVpcmUoZ2dwbG90MikKcmVxdWlyZShnZ0V4dHJhKQpyZXF1aXJlKGhyYnJ0aGVtZXMpCnJlcXVpcmUoZXh0cmFmb250KQpyZXF1aXJlKGdyaWRFeHRyYSkKcmVxdWlyZShnZ3JlcGVsKQpyZXF1aXJlKGdvZnRlc3QpCgp0aGVtZV9zZXQodGhlbWVfaXBzdW0oYmFzZV9mYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiwgCiAgICAgICAgICAgICAgYmFzZV9zaXplID0gMTAsIGF4aXNfdGl0bGVfc2l6ZSA9IDEwKSkKYGBgCgoKRmlyc3QsIHJlYWQgdGhlIGRhdGEsCgpgYGB7cn0KSEMuQlAgPSBkYXRhLmZyYW1lKCJIIiA9IG51bWVyaWMoMTYwMDApLCAKICAgICAgICAgICAgICAgICAgICJDIiA9IG51bWVyaWMoMTYwMDApLAogICAgICAgICAgICAgICAgICAgIkRpc3QiID0gbnVtZXJpYygxNjAwMCksCiAgICAgICAgICAgICAgICAgICAiRCIgPSBudW1lcmljKDE2MDAwKSwKICAgICAgICAgICAgICAgICAgICJOIiA9IG51bWVyaWMoMTYwMDApLCAKICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCgpmaWxlY3N2ID0gZGF0YS5mcmFtZShyZWFkLmNzdigiLi4vRGF0YS9IQ19zZXJpZXNfZmswXzE2MDAwLmNzdiIpKQpIQy5CUCRIID0gZmlsZWNzdlssMV0KSEMuQlAkQyA9IGZpbGVjc3ZbLDJdCkhDLkJQJEQgPSBhcy5mYWN0b3IoZmlsZWNzdlssM10pCkhDLkJQJE4gPSBhcy5mYWN0b3IocmVwKGMocmVwKDFlKzA0LCAxMDApLCByZXAoMmUrMDQsIDEwMCksIHJlcCgzZSswNCwgMTAwKSwgcmVwKDRlKzA0LCAxMDApLCByZXAoNWUrMDQsIDEwMCksIHJlcCg2ZSswNCwgMTAwKSwgcmVwKDdlKzA0LCAxMDApLCByZXAoOGUrMDQsIDEwMCksIHJlcCg5ZSswNCwgMTAwKSwgcmVwKDFlKzA1LCAxMDApKSwgMTYpKQoKc3VtbWFyeShIQy5CUCkKCmdncGxvdChkYXRhID0gSEMuQlAsIGFlcyh4ID0gSCwgeSA9IEMsIGNvbG9yID0gRCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiAgbGFicyh0aXRsZSA9ICJQb2ludHMgaW4gdGhlIEh4QyBwbGFuZSIsCiAgICAgICB4ID0gZXhwcmVzc2lvbihpdGFsaWMoSCkpLAogICAgICAgeSA9IGV4cHJlc3Npb24oaXRhbGljKEMpKQogICkKYGBgCgoKTm93IHNlcGFyYXRlZCBieSB0aGUgZW1iZWRkaW5nIGRpbWVuc2lvbiAkRCQuCgpgYGB7cn0KZ2dwbG90KGRhdGE9SEMuQlAsIGFlcyh4PUgsIHk9QywgY29sb3I9RCkpICsKICBnZW9tX3BvaW50KHNpemU9MikgKwogIGxhYnModGl0bGU9IlBvaW50cyBpbiB0aGUgSHhDIHBsYW5lIiwKICAgICAgIHg9ZXhwcmVzc2lvbihpdGFsaWMoSCkpLAogICAgICAgeT1leHByZXNzaW9uKGl0YWxpYyhDKSkpICsKICBmYWNldF9ncmlkKC5+RCkKYGBgCgpXZSBzZWUgYSBzZWVtaW5nbHkgbGluZWFyIHRyZW5kLCBidXQgYXQgdGhpcyBwb2ludCB3ZSBoYXZlIHRvIHJlY2FsbCB0aGF0ICRDPUhEJCwgaW4gd2hpY2ggJEQkIGlzIGEgZGlzdGFuY2UgKGluIHRoaXMgY2FzZSwgdGhlIEplbnNlbi1TaGFubm9uIGRpc3RhbmNlKSB0byBhbiBlcXVpbGlicml1bSBkaXN0cmlidXRpb24gKGluIHRoaXMgY2FzZSwgdGhlIFVuaWZvcm0gbGF3KS4KCkluIG9yZGVyIHRvIHNlZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHZhcmlhYmxlcyB3ZSBhcmUgc3R1ZHlpbmcsIGxldCdzIGxvb2sgYXQgJEhcdGltZXMgRCQuCmBgYHtyfQpIQy5CUCREaXN0ID0gSEMuQlAkQyAvIEhDLkJQJEgKCmdncGxvdChkYXRhPUhDLkJQLCBhZXMoeD1EaXN0LCB5PUMsIGNvbG9yPUQpKSArCiAgZ2VvbV9wb2ludChzaXplPTIpICsKICBsYWJzKHRpdGxlPSJQb2ludHMgaW4gdGhlIERpc3QgeCBDIHBsYW5lIiwKICAgICAgIHg9IkRpc3QiLAogICAgICAgeT1leHByZXNzaW9uKGl0YWxpYyhDKSkpICsKICBmYWNldF9ncmlkKC5+RCkKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGE9SEMuQlAsIGFlcyh4PUgsIHk9RGlzdCwgY29sb3I9RCkpICsKICBnZW9tX3BvaW50KHNpemU9MikgKwogIGxhYnModGl0bGU9IlBvaW50cyBpbiB0aGUgSCB4IERpc3QgcGxhbmUiLAogICAgICAgeD1leHByZXNzaW9uKGl0YWxpYyhIKSksCiAgICAgICB5PSJEaXN0IikgKwogIGZhY2V0X2dyaWQoLn5EKQpgYGAKCldlIHdpbGwgdGFrZSBOIG91dCBvZiB0aGUgZGF0YSBmcmFtZSwgaW4gb3JkZXIgdG8gdXNlIHRoZSBkZWZhdWx0IHJlZ3Jlc3Npb24gaW4gZ2dwbG90CmBgYHtyfQpIQy5CUC5yZWdyZXNzaW9uLmRhdGEgPSBIQy5CUFssLTNdCmxtLkhDID0gbG0oZGF0YT1IQy5CUC5yZWdyZXNzaW9uLmRhdGEsIGZvcm11bGEgPSBDIH4gSCAqIEQpCnN1bW1hcnkobG0uSEMpCmBgYAoKYGBge3J9Cmhpc3QobG0uSEMkcmVzaWR1YWxzLCBicmVha3MgPSAyMDApCnBsb3QobG0uSEMpCmBgYAoKVGhlIGFib3ZlIHJlc3VsdHMgc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIG5vIGV2aWRlbmNlIGFnYWluc3QgdGhlIHVzZSBvZiB0aGUgZW1iZWRkaW5nIGRpbWVuc2lvbiAkRCQgYXMgYSBmYWN0b3IgaW4gdGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLgoKYGBge3J9CmdncGxvdChIQy5CUC5yZWdyZXNzaW9uLmRhdGEsIGFlcyh4PUgsIHk9QywgY29sb3VyPUQpKSArCiAgZ2VvbV9wb2ludChzaXplPTIpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgZm9ybXVsYSA9IHl+eCkgKwogIGxhYnModGl0bGU9IkNvbXBsZXhpdHkgZXhwbGFpbmVkIGJ5IEVudHJvcHkiLAogICAgICAgeD1leHByZXNzaW9uKGl0YWxpYyhIKSksCiAgICAgICB5PWV4cHJlc3Npb24oaXRhbGljKEMpKSkKYGBgCgpOb3csIGxldCdzIHNlZSB0aGUgZml0dGVkIGxpbmVzIGluIGEgc2VtaWxvZ2FyaXRobWljIHNjYWxlLgoKYGBge3J9CmdncGxvdChIQy5CUC5yZWdyZXNzaW9uLmRhdGEsIGFlcyh4PUgsIHk9QywgY29sb3VyPUQpKSArCiAgZ2VvbV9wb2ludChzaXplPTIpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBmb3JtdWxhID0geX54KSArCiAgbGFicyh0aXRsZT0iQ29tcGxleGl0eSBleHBsYWluZWQgYnkgRW50cm9weSIsCiAgICAgICB4PWV4cHJlc3Npb24oaXRhbGljKEgpKSwKICAgICAgIHk9ZXhwcmVzc2lvbihpdGFsaWMoQyl+Iltsb2dhcml0aG1pYyBzY2FsZV0iKSkKICBmYWNldF9ncmlkKC5+RCkKYGBgClRoZSBtb2RlbCB3ZSBhcmUgZml0dGluZyBpcwokJApcbGVmdFx7CiAgXGJlZ2lue2VxbmFycmF5Kn0KICAgIENeeygzKX0gJj0gXGJldGFfMF57KDMpfSArIFxiZXRhXzFeeygzKX0gSF57KDMpfSxcXCAKICAgIENeeyg0KX0gJj0gXGJldGFfMF57KDQpfSArIFxiZXRhXzFeeyg0KX0gSF57KDQpfSxcXCAKICAgIENeeyg1KX0gJj0gXGJldGFfMF57KDUpfSArIFxiZXRhXzFeeyg1KX0gSF57KDUpfSxcXCAKICAgIENeeyg2KX0gJj0gXGJldGFfMF57KDYpfSArIFxiZXRhXzFeeyg2KX0gSF57KDYpfS5cXCAKICBcZW5ke2VxbmFycmF5Kn0KXHJpZ2h0LgokJAppbiBvdGhlciB3b3JkcywgYSBkaWZmZXJlbnQgbGluZWFyIHJlbGF0aW9uc2hpcCBmb3IgZWFjaCBlbWJlZGRpbmcgZGltZW5zaW9uICREJC4KCkxldCdzIHNhdmUgdGhlIGVzdGltYXRlcyBhbmQgdGhlaXIgY29uZmlkZW5jZSBpbnRlcnZhbHMuCmBgYHtyfQpiZXRhMCA8LSBjKAogIGxtLkhDJGNvZWZmaWNpZW50c1sxXSwKICBsbS5IQyRjb2VmZmljaWVudHNbMV0gKyBsbS5IQyRjb2VmZmljaWVudHNbM10sCiAgbG0uSEMkY29lZmZpY2llbnRzWzFdICsgbG0uSEMkY29lZmZpY2llbnRzWzRdLAogIGxtLkhDJGNvZWZmaWNpZW50c1sxXSArIGxtLkhDJGNvZWZmaWNpZW50c1s1XSkKCmJldGEwaW5mIDwtIGMoCiAgY29uZmludChsbS5IQylbMSwxXSwKICBiZXRhMFsyXSAtIGNvbmZpbnQobG0uSEMpWzMsMV0sCiAgYmV0YTBbM10gLSBjb25maW50KGxtLkhDKVs0LDFdLAogIGJldGEwWzRdIC0gY29uZmludChsbS5IQylbNSwxXSkKCmJldGEwc3VwIDwtIGMoCiAgY29uZmludChsbS5IQylbMSwyXSwKICBiZXRhMFsyXSArIGNvbmZpbnQobG0uSEMpWzMsMl0sCiAgYmV0YTBbM10gKyBjb25maW50KGxtLkhDKVs0LDJdLAogIGJldGEwWzRdICsgY29uZmludChsbS5IQylbNSwyXSkKCmJldGExIDwtIGMoCiAgbG0uSEMkY29lZmZpY2llbnRzWzJdLAogIGxtLkhDJGNvZWZmaWNpZW50c1syXSArIGxtLkhDJGNvZWZmaWNpZW50c1s2XSwKICBsbS5IQyRjb2VmZmljaWVudHNbMl0gKyBsbS5IQyRjb2VmZmljaWVudHNbN10sCiAgbG0uSEMkY29lZmZpY2llbnRzWzJdICsgbG0uSEMkY29lZmZpY2llbnRzWzhdKQoKYmV0YTFpbmYgPC1jKAogIGNvbmZpbnQobG0uSEMpWzIsMV0sCiAgYmV0YTFbMl0gLSBjb25maW50KGxtLkhDKVs2LDFdLAogIGJldGExWzNdIC0gY29uZmludChsbS5IQylbNywxXSwKICBiZXRhMVs0XSAtIGNvbmZpbnQobG0uSEMpWzgsMV0pCgpiZXRhMXN1cCA8LSBjKAogIGNvbmZpbnQobG0uSEMpWzIsMl0sCiAgYmV0YTFbMl0gKyBjb25maW50KGxtLkhDKVs2LDJdLAogIGJldGExWzNdICsgY29uZmludChsbS5IQylbNywyXSwKICBiZXRhMVs0XSArIGNvbmZpbnQobG0uSEMpWzgsMl0pCgplc3RpbWF0ZXMgPC0gZGF0YS5mcmFtZShiZXRhMD1iZXRhMCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGJldGEwaW5mPWJldGEwaW5mLAogICAgICAgICAgICAgICAgICAgICAgICBiZXRhMHN1cD1iZXRhMHN1cCwKICAgICAgICAgICAgICAgICAgICAgICAgYmV0YTE9YmV0YTEsIAogICAgICAgICAgICAgICAgICAgICAgICBiZXRhMWluZj1iZXRhMWluZiwKICAgICAgICAgICAgICAgICAgICAgICAgYmV0YTFzdXA9YmV0YTFzdXAsCiAgICAgICAgICAgICAgICAgICAgICAgIEQ9Mzo2KQoKZXN0aW1hdGVzCmBgYAoKClRoZSBmaXR0ZWQgcGFyYW1ldGVycyBhcmU6CiQkClxsZWZ0XHsKICBcYmVnaW57ZXFuYXJyYXkqfQogICAgXHdpZGVoYXR7XGJldGF9XzBeeygzKX0gPTAuOTgzICwmXHF1YWQgXHdpZGVoYXR7XGJldGF9XzFeeygzKX09LTAuOTgzLFxcIAogICAgXHdpZGVoYXR7XGJldGF9XzBeeyg0KX0gPTEuMzEwICAsJlxxdWFkIFx3aWRlaGF0e1xiZXRhfV8xXnsoNCl9PS0xLjMxMCxcXCAKICAgIFx3aWRlaGF0e1xiZXRhfV8wXnsoNSl9ID0xLjc4NSAsJlxxdWFkIFx3aWRlaGF0e1xiZXRhfV8xXnsoNSl9PS0xLjc4NSxcXCAKICAgIFx3aWRlaGF0e1xiZXRhfV8wXnsoNil9ID0yLjQwNSAsJlxxdWFkIFx3aWRlaGF0e1xiZXRhfV8xXnsoNil9PS0yLjQwNS5cXCAKICBcZW5ke2VxbmFycmF5Kn0KXHJpZ2h0LiAKJCQKCkxldCdzIHNlZSBob3cgdGhleSBiZWhhdmUuCmBgYHtyfQpwbG90LmJldGEwIDwtIGdncGxvdChkYXRhPWVzdGltYXRlcywgYWVzKHg9RCwgeT1iZXRhMCkpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGU9IkludGVyY2VwdCB2cy4gZW1iZWRkaW5nIGRpbWVuc2lvbiIsCiAgICB4PWV4cHJlc3Npb24oaXRhbGljKEQpKSwKICAgIHk9ZXhwcmVzc2lvbih3aWRlaGF0KGJldGEpWzBdKSkKcGxvdC5iZXRhMSA8LSBnZ3Bsb3QoZGF0YT1lc3RpbWF0ZXMsIGFlcyh4PUQsIHk9YmV0YTEpKSArCiAgZ2VvbV9wb2ludCgpICsKICAgIGxhYnModGl0bGU9IlNsb3BlIHZzIGVtYmVkZGluZyBkaW1lbnNpb24iLAogICAgeD1leHByZXNzaW9uKGl0YWxpYyhEKSksCiAgICB5PWV4cHJlc3Npb24od2lkZWhhdChiZXRhKVsxXSkpCmdyaWQuYXJyYW5nZShwbG90LmJldGEwLCBwbG90LmJldGExLCBucm93PTEpCmBgYAoKVGhlIGpvaW50IHZhcmlhdGlvbjoKYGBge3J9CmdncGxvdChkYXRhPWVzdGltYXRlcywgYWVzKHg9YmV0YTAsIHk9YmV0YTEpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSB5fngpICsKICBnZW9tX3BvaW50KHNpemU9MikgKwojICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPWJldGExaW5mLCB5bWF4PWJldGExc3VwKSkgKwojICBnZW9tX2Vycm9yYmFyaChhZXMoeG1pbj1iZXRhMGluZiwgeG1heD1iZXRhMHN1cCkpICsKICBnZW9tX2xhYmVsX3JlcGVsKGRhdGE9ZXN0aW1hdGVzLCBhZXMoeD1iZXRhMCwgeT1iZXRhMSwgbGFiZWw9RCksCiAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAieCIpICsKICBsYWJzKHRpdGxlPSJJbnRlcmNlcHQgdnMgU2xvcGUiLAogICAgeD1leHByZXNzaW9uKHdpZGVoYXQoYmV0YSlbMF0pLAogICAgeT1leHByZXNzaW9uKHdpZGVoYXQoYmV0YSlbMV0pKSArCiAgICBjb29yZF9maXhlZCgpCmBgYApXZSB2ZXJpZnkgdGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gJFx3aWRlaGF0e1xiZXRhfV8wJCBhbmQgJFx3aWRlaGF0e1xiZXRhfV8xJC4K