5.1

Given the fitted response function

\[\begin{aligned} \hat{y} = 72.0 + 3.6x_1 - 2.5x_2 \end{aligned}\]

which is found to fit well in a localized region of \((x_1, x_2)\).

  1. Plot contours of constant response, \(y\), in the \((x_1, x_2)\) plane.
library(plotly)
x1 <- seq(0, 10, by=0.1)
x2 <- seq(0, 10, by=0.1)
y <- 72 +3.6*x1-2.5*x2
z <- cbind(x1, x2, y)
p <- plot_ly(z = z) %>% add_surface()
p
  1. Calculate and plot the path of the steepest ascend generated from this response function. Use \(x_1\) to determine the path, with \(\Delta x_1 = 1\).
library(qualityTools)
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 72 +3.6*dset$A-2.5*dset$B
response(set) <- y
set
sa <- steepAscent(factors = c("A", "B"), response="y", data=set)

Steepest Ascent for set 
sa_set <- as.data.frame(sa)
y_hat <- 72 +3.6*sa_set$A.real-2.5*sa_set$B.real
response(sa) <- y_hat
sa
plot(sa)

5.2

Suppose a fitted first-order model is given by:

\[\begin{aligned} y=25+4x_1+3x_2-2.5x_3 \end{aligned}\]

Suppose we wish to maximize the response. Calculate several points along the path of the steepest ascent

set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
set
sa <- steepAscent(factors = c("A", "B", "C"), response="y", data=set)

Steepest Ascent for set 
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
plot(sa)

5.3

Reconsider the model in Exercise 5.1. Construct a path of steepest ascent, using \(x_2\) to define the path, with \(\Delta x_2=1\)

set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 72 +3.6*dset$A-2.5*dset$B
response(set) <- y
sa_1 <- steepAscent(factors = c("A", "B"), response="y", data=set)

Steepest Ascent for set 
sa_1_set <- as.data.frame(sa_1)
y_hat <- 72 +3.6*sa_1_set$A.real-2.5*sa_1_set$B.real
response(sa_1) <- y_hat
sa_2 <- steepAscent(factors = c("B", "A"), response="y", data=set)

Steepest Ascent for set 
sa_2_set <- as.data.frame(sa_2)
y_hat <- 72 +3.6*sa_2_set$A.real-2.5*sa_2_set$B.real
response(sa_2) <- y_hat
d_sa2 <- as.data.frame(sa_2)
plot(sa_1, type="b")
lines(d_sa2$Delta,d_sa2$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("Delta X1", "Delta X2"), col=c("black", "blue"), lty=1:2)

  1. How different are the two paths that you have constructed?

\(\Delta x_2\) has bigger values faster than \(\Delta x_1\)

5.4

Consider the injection molding experiment in Example 5.2

  1. Use the coded design units to determine how far the points Base \(+4\Delta\) is from the design center.
set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
sa <- steepAscent(factors = c("A", "B", "C"), size=4, response="y", data=set)

Steepest Ascent for set 
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
sa_original <- steepAscent(factors = c("A", "B", "C"), response="y", data=set)

Steepest Ascent for set 
d_sa <- as.data.frame(sa_original)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa_original) <- y_hat
sa_original
d_sa_original <- as.data.frame(sa_original)
plot(sa, type="b")
lines(d_sa_original$Delta,d_sa_original$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("+4 Delta", "+1 Delta"), col=c("black", "blue"), lty=1:2)

  1. Suppose that we had selected \(x_2\) to express the points on the path of steepest descent with \(\Delta x_2=1\). Recompute the points in Table E5.4. Use the point Base \(+4\Delta\), and compute the distance of this point from the design center.
set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
sa <- steepAscent(factors = c("B", "A", "C"), size=4, response="y", data=set)

Steepest Ascent for set 
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
sa_original <- steepAscent(factors = c("B", "A", "C"), response="y", data=set)

Steepest Ascent for set 
d_sa <- as.data.frame(sa_original)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa_original) <- y_hat
sa_original
d_sa_original <- as.data.frame(sa_original)
plot(sa, type="b")
lines(d_sa_original$Delta,d_sa_original$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("+4 Delta", "+1 Delta"), col=c("black", "blue"), lty=1:2)

  1. How different are the two points you have computed?

The points have the same center in 25, but then the dispersion is really big being \(+4\Delta\) having a value of 225 units, meanwhile the default \(\Delta\) only reaches until 33 untis.

5.5

In a metallurgy experiment it is desired to test the effect of four factors and their interactions on the concentration (percent by weight) of a particular phosphorus compound in costing material. The variables are: A, percent phosphorus in the refinement; B, percent remelted material; C, fluxing time, and D, holding time. The four factors are varied in a 24 factorial experiment with two castings taken at each factor combination. The 32 castings were made in random order, and the data are shown in this table:

Treatment Replication I Replication II Total
(1) 30.3 28.6 58.9
a 28.5 31.4 59.9
b 24.5 25.6 50.1
ab 25.9 27.2 53.1
c 24.8 23.4 48.2
ac 26.9 23.8 50.7
bc 24.8 27.8 52.6
abc 22.2 24.9 47.1
d 31.7 33.5 65.2
ad 24.6 26.2 50.8
bd 27.6 30.6 58.2
abd 26.3 27.8 54.1
cd 29.9 27.7 57.6
acd 26.8 24.2 51.0
bcd 26.4 24.9 51.3
abcd 26.9 29.3 56.2
Total 428.1 436.9 865.0
results <- c (58.9, 59.9, 50.1, 53.1, 48.2, 50.7, 52.6, 47.1, 65.2, 50.8, 58.2, 54.1, 57.6, 51, 51.3, 56.2, 865)
set <- facDesign(k=4)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- results[unlist(runOrd(set))]
response(set) <- total
set

With the table we need to create the function using lm

df <- as.data.frame(data)
func <- lm(total ~ A + B + C + D, data=df)
func

Call:
lm(formula = total ~ A + B + C + D, data = df)

Coefficients:
(Intercept)            A            B            C            D  
    54.0625      -1.4375      -0.3750       0.3875       0.3500  

With this we get the final equation which is:

\[\begin{aligned} y = 54.0625 -1.4375x_1 - 0.3750x_2 + 0.3875x_3 + 0.3500x_4 \end{aligned}\]
  1. Construct a table of the path of steepest ascent in the coded design variables.
sa <- steepAscent(factors = c("A", "B", "C","D"), response="total", data=data)

Steepest Ascent for data 
d_sa <- as.data.frame(sa)
y_hat <- 54.0625 - 1.4375*d_sa$A.coded - 0.3750*d_sa$B.coded + 0.3875*d_sa$C.coded + 0.35*d_sa$D.coded
response(sa) <- y_hat
sa

5.6

Consider the \(2^2\) factorial design featured in the illustration in Figure 3.1 in Chapter 3. Factor A is the concentration of a reactant, factor B is the feed rate, and the response is the viscosity of the output material. As one can tell by the computed effects and the analysis of variance shown, the main effects dominate in the analysis. Using the following table:

Combination I II III IV Total
A low, B low 145 148 147 140 580
A high, B low 158 152 155 152 617
A low, B high 135 138 141 139 553
A high, B high 150 152 146 149 597
  1. Fit a first-order model
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- c(553, 617, 597, 580)
response(set) <- total
set

Now we create the function using a lineal regresion

lm_source <- as.data.frame(set)
lm_model <- lm(total~A+B, data=lm_source)
lm_model

Call:
lm(formula = total ~ A + B, data = lm_source)

Coefficients:
(Intercept)            A            B  
     586.75        20.25       -11.75  

So the function is:

\[\begin{aligned} y = 586.75 + 20.25x_1 - 11.75x_2 \end{aligned}\]
  1. Compute and plot the path of steepest ascent.
sa <- steepAscent(factors = c("A", "B"), response="total", data=set)

Steepest Ascent for set 
sa_source <- as.data.frame(sa)
y_hat <- 586.75 + 20.25*sa_source$A.real - 11.75*sa_source$B.real
response(sa) <- y_hat
sa

c)Suppose that in the metric of the coded variables, the concentration cannot exceed 3.5 and the feed rate cannot go below -2.7. Show the practical path of steepest ascent—that is, the path that takes account of these constraints.

set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- c(553, 617, 597, 580)
response(set) <- total
lows(set) <- c(-2.7, -2.7)
highs(set) <- c(3.5, 3.5)
set
sa <- steepAscent(factors = c("A", "B"), size=0.1, response="total", data=set)

Steepest Ascent for set 
sa_source <- as.data.frame(sa)
y_hat <- 586.75 + 20.25*sa_source$A.real - 11.75*sa_source$B.real
response(sa) <- y_hat
sa

5.7

It is stated in the text that the development of the path of steepest ascent makes use of the assumption that the model is truly first-order in nature. However, even if there is a modest amount of curvature or interaction in the system, the use of steepest ascent can be extremely useful in determining a future experimental region. Suppose that in a system involving \(x_1\) and \(x_2\) the actual model is given by:

\[\begin{aligned} E(y) = 14 + 5x_1 - 10x_2 + 3x_1x_2 \end{aligned}\]

Assume that \(x_1\) and \(x_2\) are in coded form:

  1. Show a plot of the path of steepest ascent (based on actual parameters) if the interaction is ignored.
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
set_source <- as.data.frame(set)
e_y <- 14 + 5*set_source$A - 10*set_source$B 
response(set) <- e_y
sa_linear <- steepAscent(factors = c("A", "B"), response="e_y", data=set)

Steepest Ascent for set 
sa_source <- as.data.frame(sa_linear)
y_hat <- 14 + 5*sa_source$A.coded - 10*sa_source$B.coded 
response(sa_linear) <- y_hat
plot(sa_linear, type="b")

  1. Show a plot of the path of steepest ascent for the model with interaction. Note that this path is not linear
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
set_source <- as.data.frame(set)
e_y <- 14 + 5*set_source$A - 10*set_source$B + 3*set_source$A*set_source$B
response(set) <- e_y
sa_interaction <- steepAscent(factors = c("A", "B"), response="e_y", data=set)

Steepest Ascent for set 
sa_source <- as.data.frame(sa_interaction)
y_hat <- 14 + 5*sa_source$A.coded - 10*sa_source$B.coded + 3*sa_source$A.coded*sa_source$B.coded
response(sa_interaction) <- y_hat
plot(sa_interaction, type="b")

  1. Comment on the difference in the two paths.

This Graph explains better the difference

sa_interaction_source <- as.data.frame(sa_interaction)
plot(sa_linear, type="b")
lines(sa_interaction_source$Delta,sa_interaction_source$y_hat, col="blue", type="b", lty=2)
legend(0, 35,legend = c("No Interaction", "Interaction"), col=c("black", "blue"), lty=1:2)

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWEgMiwgUHJveWVjdG8iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyA1LjEgCgpHaXZlbiB0aGUgZml0dGVkIHJlc3BvbnNlIGZ1bmN0aW9uCgpcYmVnaW57YWxpZ25lZH0KICBcaGF0e3l9ID0gNzIuMCArIDMuNnhfMSAtIDIuNXhfMgpcZW5ke2FsaWduZWR9Cgp3aGljaCBpcyBmb3VuZCB0byBmaXQgd2VsbCBpbiBhIGxvY2FsaXplZCByZWdpb24gb2YgJCh4XzEsIHhfMikkLgoKYSkgUGxvdCBjb250b3VycyBvZiBjb25zdGFudCByZXNwb25zZSwgJHkkLCBpbiB0aGUgJCh4XzEsIHhfMikkIHBsYW5lLgoKYGBge3J9CmxpYnJhcnkocGxvdGx5KQp4MSA8LSBzZXEoMCwgMTAsIGJ5PTAuMSkKeDIgPC0gc2VxKDAsIDEwLCBieT0wLjEpCnkgPC0gNzIgKzMuNip4MS0yLjUqeDIKCnogPC0gY2JpbmQoeDEsIHgyLCB5KQoKcCA8LSBwbG90X2x5KHogPSB6KSAlPiUgYWRkX3N1cmZhY2UoKQpwCmBgYAoKYikgQ2FsY3VsYXRlIGFuZCBwbG90IHRoZSBwYXRoIG9mIHRoZSBzdGVlcGVzdCBhc2NlbmQgZ2VuZXJhdGVkIGZyb20gdGhpcyByZXNwb25zZSBmdW5jdGlvbi4gVXNlICR4XzEkIHRvIGRldGVybWluZSB0aGUgcGF0aCwgd2l0aCAkXERlbHRhIHhfMSA9IDEkLgoKYGBge3J9CmxpYnJhcnkocXVhbGl0eVRvb2xzKQoKc2V0IDwtIGZhY0Rlc2lnbihrPTIpCgpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKCnkgPC0gNzIgKzMuNipkc2V0JEEtMi41KmRzZXQkQgoKcmVzcG9uc2Uoc2V0KSA8LSB5CgpzZXQKYGBgCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV9zZXQgPC0gYXMuZGF0YS5mcmFtZShzYSkKCnlfaGF0IDwtIDcyICszLjYqc2Ffc2V0JEEucmVhbC0yLjUqc2Ffc2V0JEIucmVhbAoKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYApgYGB7cn0KcGxvdChzYSkKYGBgCgojIyMgNS4yCgpTdXBwb3NlIGEgZml0dGVkIGZpcnN0LW9yZGVyIG1vZGVsIGlzIGdpdmVuIGJ5OgoKXGJlZ2lue2FsaWduZWR9CiAgeT0yNSs0eF8xKzN4XzItMi41eF8zClxlbmR7YWxpZ25lZH0KClN1cHBvc2Ugd2Ugd2lzaCB0byBtYXhpbWl6ZSB0aGUgcmVzcG9uc2UuIENhbGN1bGF0ZSBzZXZlcmFsIHBvaW50cyBhbG9uZyB0aGUgcGF0aCBvZiB0aGUgc3RlZXBlc3QgYXNjZW50CgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTMpCmRzZXQgPC0gYXMuZGF0YS5mcmFtZShzZXQpCgp5IDwtIDI1KzQqZHNldCRBKzMqZHNldCRCLTIuNSpkc2V0JEMKCnJlc3BvbnNlKHNldCkgPC0geQoKc2V0CmBgYApgYGB7cn0Kc2EgPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIsICJDIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpkX3NhIDwtIGFzLmRhdGEuZnJhbWUoc2EpCgp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCgpyZXNwb25zZShzYSkgPC0geV9oYXQKCnNhCmBgYAoKYGBge3J9CnBsb3Qoc2EpCmBgYAoKIyMjIDUuMwoKUmVjb25zaWRlciB0aGUgbW9kZWwgaW4gRXhlcmNpc2UgNS4xLiBDb25zdHJ1Y3QgYSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCwgdXNpbmcgJHhfMiQgdG8gZGVmaW5lIHRoZSBwYXRoLCB3aXRoICRcRGVsdGEgeF8yPTEkCgphKSAKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0yKQoKZHNldCA8LSBhcy5kYXRhLmZyYW1lKHNldCkKCgp5IDwtIDcyICszLjYqZHNldCRBLTIuNSpkc2V0JEIKCnJlc3BvbnNlKHNldCkgPC0geQoKc2FfMSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV8xX3NldCA8LSBhcy5kYXRhLmZyYW1lKHNhXzEpCgp5X2hhdCA8LSA3MiArMy42KnNhXzFfc2V0JEEucmVhbC0yLjUqc2FfMV9zZXQkQi5yZWFsCgpyZXNwb25zZShzYV8xKSA8LSB5X2hhdAoKc2FfMiA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQiIsICJBIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV8yX3NldCA8LSBhcy5kYXRhLmZyYW1lKHNhXzIpCgp5X2hhdCA8LSA3MiArMy42KnNhXzJfc2V0JEEucmVhbC0yLjUqc2FfMl9zZXQkQi5yZWFsCgpyZXNwb25zZShzYV8yKSA8LSB5X2hhdAoKZF9zYTIgPC0gYXMuZGF0YS5mcmFtZShzYV8yKQoKcGxvdChzYV8xLCB0eXBlPSJiIikKbGluZXMoZF9zYTIkRGVsdGEsZF9zYTIkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDc2LGxlZ2VuZCA9IGMoIkRlbHRhIFgxIiwgIkRlbHRhIFgyIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoKYikgSG93IGRpZmZlcmVudCBhcmUgdGhlIHR3byBwYXRocyB0aGF0IHlvdSBoYXZlIGNvbnN0cnVjdGVkPwoKKiokXERlbHRhIHhfMiQgaGFzIGJpZ2dlciB2YWx1ZXMgZmFzdGVyIHRoYW4gJFxEZWx0YSB4XzEkKioKCiMjIyA1LjQKCkNvbnNpZGVyIHRoZSBpbmplY3Rpb24gbW9sZGluZyBleHBlcmltZW50IGluIEV4YW1wbGUgNS4yCgphKSBVc2UgdGhlIGNvZGVkIGRlc2lnbiB1bml0cyB0byBkZXRlcm1pbmUgaG93IGZhciB0aGUgcG9pbnRzIEJhc2UgJCs0XERlbHRhJCBpcyBmcm9tIHRoZSBkZXNpZ24gY2VudGVyLgoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0zKQpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKeSA8LSAyNSs0KmRzZXQkQSszKmRzZXQkQi0yLjUqZHNldCRDCgpyZXNwb25zZShzZXQpIDwtIHkKCnNhIDwtIHN0ZWVwQXNjZW50KGZhY3RvcnMgPSBjKCJBIiwgIkIiLCAiQyIpLCBzaXplPTQsIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCmRfc2EgPC0gYXMuZGF0YS5mcmFtZShzYSkKeV9oYXQgPC0gMjUrNCpkX3NhJEEucmVhbCszKmRfc2EkQi5yZWFsLTIuNSpkX3NhJEMucmVhbApyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCmBgYHtyfQpzYV9vcmlnaW5hbCA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiwgIkMiKSwgcmVzcG9uc2U9InkiLCBkYXRhPXNldCkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhX29yaWdpbmFsKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhX29yaWdpbmFsKSA8LSB5X2hhdApzYV9vcmlnaW5hbApgYGAKCmBgYHtyfQpkX3NhX29yaWdpbmFsIDwtIGFzLmRhdGEuZnJhbWUoc2Ffb3JpZ2luYWwpCgpwbG90KHNhLCB0eXBlPSJiIikKbGluZXMoZF9zYV9vcmlnaW5hbCREZWx0YSxkX3NhX29yaWdpbmFsJHlfaGF0LCBjb2w9ImJsdWUiLCB0eXBlPSJiIiwgbHR5PTIpCmxlZ2VuZCgwLCA3NixsZWdlbmQgPSBjKCIrNCBEZWx0YSIsICIrMSBEZWx0YSIpLCBjb2w9YygiYmxhY2siLCAiYmx1ZSIpLCBsdHk9MToyKQpgYGAKCmIpIFN1cHBvc2UgdGhhdCB3ZSBoYWQgc2VsZWN0ZWQgJHhfMiQgdG8gZXhwcmVzcyB0aGUgcG9pbnRzIG9uIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGRlc2NlbnQgd2l0aCAgJFxEZWx0YSB4XzI9MSQuIFJlY29tcHV0ZSB0aGUgcG9pbnRzIGluIFRhYmxlIEU1LjQuIFVzZSB0aGUgcG9pbnQgQmFzZSAkKzRcRGVsdGEkLCBhbmQgY29tcHV0ZSB0aGUgZGlzdGFuY2Ugb2YgdGhpcyBwb2ludCBmcm9tIHRoZSBkZXNpZ24gY2VudGVyLgoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0zKQpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKeSA8LSAyNSs0KmRzZXQkQSszKmRzZXQkQi0yLjUqZHNldCRDCgpyZXNwb25zZShzZXQpIDwtIHkKCnNhIDwtIHN0ZWVwQXNjZW50KGZhY3RvcnMgPSBjKCJCIiwgIkEiLCAiQyIpLCBzaXplPTQsIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCmRfc2EgPC0gYXMuZGF0YS5mcmFtZShzYSkKeV9oYXQgPC0gMjUrNCpkX3NhJEEucmVhbCszKmRfc2EkQi5yZWFsLTIuNSpkX3NhJEMucmVhbApyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCgpgYGB7cn0KZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhKSA8LSB5X2hhdApzYQpgYGAKCmBgYHtyfQpzYV9vcmlnaW5hbCA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQiIsICJBIiwgIkMiKSwgcmVzcG9uc2U9InkiLCBkYXRhPXNldCkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhX29yaWdpbmFsKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhX29yaWdpbmFsKSA8LSB5X2hhdApzYV9vcmlnaW5hbApgYGAKCmBgYHtyfQpkX3NhX29yaWdpbmFsIDwtIGFzLmRhdGEuZnJhbWUoc2Ffb3JpZ2luYWwpCnBsb3Qoc2EsIHR5cGU9ImIiKQpsaW5lcyhkX3NhX29yaWdpbmFsJERlbHRhLGRfc2Ffb3JpZ2luYWwkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDc2LGxlZ2VuZCA9IGMoIis0IERlbHRhIiwgIisxIERlbHRhIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoKQykgSG93IGRpZmZlcmVudCBhcmUgdGhlIHR3byBwb2ludHMgeW91IGhhdmUgY29tcHV0ZWQ/CgoqKlRoZSBwb2ludHMgaGF2ZSB0aGUgc2FtZSBjZW50ZXIgaW4gMjUsIGJ1dCB0aGVuIHRoZSBkaXNwZXJzaW9uIGlzIHJlYWxseSBiaWcgYmVpbmcgJCs0XERlbHRhJCBoYXZpbmcgYSB2YWx1ZSBvZiAyMjUgdW5pdHMsIG1lYW53aGlsZSB0aGUgZGVmYXVsdCAkXERlbHRhJCBvbmx5IHJlYWNoZXMgdW50aWwgMzMgdW50aXMuKioKCiMjIyA1LjUKCkluIGEgbWV0YWxsdXJneSBleHBlcmltZW50IGl0IGlzIGRlc2lyZWQgdG8gdGVzdCB0aGUgZWZmZWN0IG9mIGZvdXIgZmFjdG9ycyBhbmQgdGhlaXIgaW50ZXJhY3Rpb25zIG9uIHRoZSBjb25jZW50cmF0aW9uIChwZXJjZW50IGJ5IHdlaWdodCkgb2YgYSBwYXJ0aWN1bGFyIHBob3NwaG9ydXMgY29tcG91bmQgaW4gY29zdGluZyBtYXRlcmlhbC4gVGhlIHZhcmlhYmxlcyBhcmU6IEEsIHBlcmNlbnQgcGhvc3Bob3J1cyBpbiB0aGUgcmVmaW5lbWVudDsgQiwgcGVyY2VudCByZW1lbHRlZCBtYXRlcmlhbDsgQywgZmx1eGluZyB0aW1lLCBhbmQgRCwgaG9sZGluZyB0aW1lLiBUaGUgZm91cgpmYWN0b3JzIGFyZSB2YXJpZWQgaW4gYSAyNCBmYWN0b3JpYWwgZXhwZXJpbWVudCB3aXRoIHR3byBjYXN0aW5ncyB0YWtlbiBhdCBlYWNoIGZhY3RvciBjb21iaW5hdGlvbi4gVGhlIDMyIGNhc3RpbmdzIHdlcmUgbWFkZSBpbiByYW5kb20gb3JkZXIsIGFuZCB0aGUgZGF0YSBhcmUgc2hvd24gaW4gdGhpcyB0YWJsZToKCnwgVHJlYXRtZW50IHwgUmVwbGljYXRpb24gSSB8IFJlcGxpY2F0aW9uIElJIHwgVG90YWwgfAp8Oi0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLTp8Oi0tLS0tOnwKfCAoMSkgfCAzMC4zIHwgMjguNiB8IDU4LjkgfAp8IGEgfCAyOC41IHwgMzEuNCB8IDU5LjkgfAp8IGIgfCAyNC41IHwgMjUuNiB8IDUwLjEgfAp8IGFiIHwgMjUuOSB8IDI3LjIgfCA1My4xIHwKfCBjIHwgMjQuOCB8IDIzLjQgfCA0OC4yIHwKfCBhYyB8IDI2LjkgfCAyMy44IHwgNTAuNyB8CnwgYmMgfCAyNC44IHwgMjcuOCB8IDUyLjYgfAp8IGFiYyB8IDIyLjIgfCAyNC45IHwgNDcuMSB8CnwgZCB8IDMxLjcgfCAzMy41IHwgNjUuMiB8CnwgYWQgfCAyNC42IHwgMjYuMiB8IDUwLjggfAp8IGJkIHwgMjcuNiB8IDMwLjYgfCA1OC4yIHwKfCBhYmQgfCAyNi4zIHwgMjcuOCB8IDU0LjEgfAp8IGNkIHwgMjkuOSB8IDI3LjcgfCA1Ny42IHwKfCBhY2QgfCAyNi44IHwgMjQuMiB8IDUxLjAgfAp8IGJjZCB8IDI2LjQgfCAyNC45IHwgNTEuMyB8CnwgYWJjZCB8IDI2LjkgfCAyOS4zIHwgNTYuMiB8CnwgVG90YWwgfCA0MjguMSB8IDQzNi45IHwgODY1LjAgfAoKYGBge3J9CnJlc3VsdHMgPC0gYyAoNTguOSwgNTkuOSwgNTAuMSwgNTMuMSwgNDguMiwgNTAuNywgNTIuNiwgNDcuMSwgNjUuMiwgNTAuOCwgNTguMiwgNTQuMSwgNTcuNiwgNTEsIDUxLjMsIDU2LjIsIDg2NSkKCnNldCA8LSBmYWNEZXNpZ24oaz00KQoKdG90YWwgPC0gcmVzdWx0c1t1bmxpc3QocnVuT3JkKHNldCkpXQoKcmVzcG9uc2Uoc2V0KSA8LSB0b3RhbAoKc2V0CmBgYApXaXRoIHRoZSB0YWJsZSB3ZSBuZWVkIHRvIGNyZWF0ZSB0aGUgZnVuY3Rpb24gdXNpbmcgbG0KCmBgYHtyfQpkZiA8LSBhcy5kYXRhLmZyYW1lKGRhdGEpCgpmdW5jIDwtIGxtKHRvdGFsIH4gQSArIEIgKyBDICsgRCwgZGF0YT1kZikKZnVuYwpgYGAKV2l0aCB0aGlzIHdlIGdldCB0aGUgZmluYWwgZXF1YXRpb24gd2hpY2ggaXM6CgpcYmVnaW57YWxpZ25lZH0KICB5ID0gNTQuMDYyNSAtMS40Mzc1eF8xIC0gMC4zNzUweF8yICsgMC4zODc1eF8zICsgMC4zNTAweF80ClxlbmR7YWxpZ25lZH0KCmIpIENvbnN0cnVjdCBhIHRhYmxlIG9mIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCBpbiB0aGUgY29kZWQgZGVzaWduIHZhcmlhYmxlcy4KCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiwgIkMiLCJEIiksIHJlc3BvbnNlPSJ0b3RhbCIsIGRhdGE9ZGF0YSkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhKQp5X2hhdCA8LSA1NC4wNjI1IC0gMS40Mzc1KmRfc2EkQS5jb2RlZCAtIDAuMzc1MCpkX3NhJEIuY29kZWQgKyAwLjM4NzUqZF9zYSRDLmNvZGVkICsgMC4zNSpkX3NhJEQuY29kZWQKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYAoKIyMjIDUuNgoKQ29uc2lkZXIgdGhlICQyXjIkIGZhY3RvcmlhbCBkZXNpZ24gZmVhdHVyZWQgaW4gdGhlIGlsbHVzdHJhdGlvbiBpbiBGaWd1cmUgMy4xIGluIENoYXB0ZXIgMy4gRmFjdG9yIEEgaXMgdGhlIGNvbmNlbnRyYXRpb24gb2YgYSByZWFjdGFudCwgZmFjdG9yIEIgaXMgdGhlIGZlZWQgcmF0ZSwgYW5kIHRoZSByZXNwb25zZSBpcyB0aGUgdmlzY29zaXR5IG9mIHRoZSBvdXRwdXQgbWF0ZXJpYWwuIEFzIG9uZSBjYW4gdGVsbCBieSB0aGUgY29tcHV0ZWQgZWZmZWN0cyBhbmQgdGhlIGFuYWx5c2lzIG9mIHZhcmlhbmNlIHNob3duLCB0aGUgbWFpbiBlZmZlY3RzIGRvbWluYXRlIGluIHRoZSBhbmFseXNpcy4gVXNpbmcgdGhlIGZvbGxvd2luZyB0YWJsZToKCnwgQ29tYmluYXRpb24gfCBJIHwgSUkgfCBJSUkgfCBJViB8IFRvdGFsIHwKfDotLS0tLS0tLS0tLTp8Oi06fDotLTp8Oi0tLTp8Oi0tOnw6LS0tLS06fAp8QSBsb3csIEIgbG93IHwgMTQ1IHwgMTQ4IHwgMTQ3IHwgMTQwIHwgNTgwIHwKfEEgaGlnaCwgQiBsb3cgfCAxNTggfCAxNTIgfCAxNTUgfCAxNTIgfCA2MTcgfAp8QSBsb3csIEIgaGlnaCB8IDEzNSB8IDEzOCB8IDE0MSB8IDEzOSB8IDU1MyB8CnxBIGhpZ2gsIEIgaGlnaCB8IDE1MCB8IDE1MiB8IDE0NiB8IDE0OSB8IDU5NyB8CgphKSBGaXQgYSBmaXJzdC1vcmRlciBtb2RlbAoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0yKQp0b3RhbCA8LSBjKDU1MywgNjE3LCA1OTcsIDU4MCkKcmVzcG9uc2Uoc2V0KSA8LSB0b3RhbApzZXQKYGBgCgpOb3cgd2UgY3JlYXRlIHRoZSBmdW5jdGlvbiB1c2luZyBhIGxpbmVhbCByZWdyZXNpb24KYGBge3J9CmxtX3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNldCkKbG1fbW9kZWwgPC0gbG0odG90YWx+QStCLCBkYXRhPWxtX3NvdXJjZSkKbG1fbW9kZWwKYGBgCgpTbyB0aGUgZnVuY3Rpb24gaXM6CgpcYmVnaW57YWxpZ25lZH0KICB5ID0gNTg2Ljc1ICsgMjAuMjV4XzEgLSAxMS43NXhfMgpcZW5ke2FsaWduZWR9CgpiKSBDb21wdXRlIGFuZCBwbG90IHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudC4KCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ0b3RhbCIsIGRhdGE9c2V0KQpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYSkKCnlfaGF0IDwtIDU4Ni43NSArIDIwLjI1KnNhX3NvdXJjZSRBLnJlYWwgLSAxMS43NSpzYV9zb3VyY2UkQi5yZWFsCgpyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCgpjKVN1cHBvc2UgdGhhdCBpbiB0aGUgbWV0cmljIG9mIHRoZSBjb2RlZCB2YXJpYWJsZXMsIHRoZSBjb25jZW50cmF0aW9uIGNhbm5vdCBleGNlZWQgMy41IGFuZCB0aGUgZmVlZCByYXRlIGNhbm5vdCBnbyBiZWxvdyAtMi43LiBTaG93IHRoZSBwcmFjdGljYWwgcGF0aCBvZiBzdGVlcGVzdCBhc2NlbnTigJR0aGF0IGlzLCB0aGUgcGF0aCB0aGF0IHRha2VzIGFjY291bnQgb2YgdGhlc2UgY29uc3RyYWludHMuCgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTIpCnRvdGFsIDwtIGMoNTUzLCA2MTcsIDU5NywgNTgwKQpyZXNwb25zZShzZXQpIDwtIHRvdGFsCmxvd3Moc2V0KSA8LSBjKC0yLjcsIC0yLjcpCmhpZ2hzKHNldCkgPC0gYygzLjUsIDMuNSkKc2V0CgpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHNpemU9MC4xLCByZXNwb25zZT0idG90YWwiLCBkYXRhPXNldCkKc2Ffc291cmNlIDwtIGFzLmRhdGEuZnJhbWUoc2EpCgp5X2hhdCA8LSA1ODYuNzUgKyAyMC4yNSpzYV9zb3VyY2UkQS5yZWFsIC0gMTEuNzUqc2Ffc291cmNlJEIucmVhbAoKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYAoKIyMjIDUuNwoKSXQgaXMgc3RhdGVkIGluIHRoZSB0ZXh0IHRoYXQgdGhlIGRldmVsb3BtZW50IG9mIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCBtYWtlcyB1c2Ugb2YgdGhlIGFzc3VtcHRpb24gdGhhdCB0aGUgbW9kZWwgaXMgdHJ1bHkgZmlyc3Qtb3JkZXIgaW4gbmF0dXJlLiBIb3dldmVyLCBldmVuIGlmIHRoZXJlIGlzIGEgbW9kZXN0IGFtb3VudCBvZiBjdXJ2YXR1cmUgb3IgaW50ZXJhY3Rpb24gaW4gdGhlIHN5c3RlbSwgdGhlIHVzZSBvZiBzdGVlcGVzdCBhc2NlbnQgY2FuIGJlIGV4dHJlbWVseSB1c2VmdWwgaW4gZGV0ZXJtaW5pbmcgYSBmdXR1cmUgZXhwZXJpbWVudGFsIHJlZ2lvbi4gU3VwcG9zZSB0aGF0IGluIGEgc3lzdGVtIGludm9sdmluZyAkeF8xJCBhbmQgJHhfMiQgdGhlIGFjdHVhbCBtb2RlbCBpcyBnaXZlbiBieToKClxiZWdpbnthbGlnbmVkfQogIEUoeSkgPSAxNCArIDV4XzEgLSAxMHhfMiArIDN4XzF4XzIKXGVuZHthbGlnbmVkfQoKQXNzdW1lIHRoYXQgJHhfMSQgYW5kICR4XzIkIGFyZSBpbiBjb2RlZCBmb3JtOgoKYSkgU2hvdyBhIHBsb3Qgb2YgdGhlIHBhdGggb2Ygc3RlZXBlc3QgYXNjZW50IChiYXNlZCBvbiBhY3R1YWwgcGFyYW1ldGVycykgaWYgdGhlIGludGVyYWN0aW9uIGlzIGlnbm9yZWQuCgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTIpCnNldF9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzZXQpCgplX3kgPC0gMTQgKyA1KnNldF9zb3VyY2UkQSAtIDEwKnNldF9zb3VyY2UkQiAKCnJlc3BvbnNlKHNldCkgPC0gZV95CgpzYV9saW5lYXIgPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIpLCByZXNwb25zZT0iZV95IiwgZGF0YT1zZXQpCgpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYV9saW5lYXIpCgp5X2hhdCA8LSAxNCArIDUqc2Ffc291cmNlJEEuY29kZWQgLSAxMCpzYV9zb3VyY2UkQi5jb2RlZCAKCnJlc3BvbnNlKHNhX2xpbmVhcikgPC0geV9oYXQKCnBsb3Qoc2FfbGluZWFyLCB0eXBlPSJiIikKYGBgCgpiKSBTaG93IGEgcGxvdCBvZiB0aGUgcGF0aCBvZiBzdGVlcGVzdCBhc2NlbnQgZm9yIHRoZSBtb2RlbCB3aXRoIGludGVyYWN0aW9uLiBOb3RlIHRoYXQgdGhpcyBwYXRoIGlzIG5vdCBsaW5lYXIKCmBgYHtyfQpzZXQgPC0gZmFjRGVzaWduKGs9MikKc2V0X3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNldCkKCmVfeSA8LSAxNCArIDUqc2V0X3NvdXJjZSRBIC0gMTAqc2V0X3NvdXJjZSRCICsgMypzZXRfc291cmNlJEEqc2V0X3NvdXJjZSRCCgpyZXNwb25zZShzZXQpIDwtIGVfeQoKc2FfaW50ZXJhY3Rpb24gPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIpLCByZXNwb25zZT0iZV95IiwgZGF0YT1zZXQpCgpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYV9pbnRlcmFjdGlvbikKCnlfaGF0IDwtIDE0ICsgNSpzYV9zb3VyY2UkQS5jb2RlZCAtIDEwKnNhX3NvdXJjZSRCLmNvZGVkICsgMypzYV9zb3VyY2UkQS5jb2RlZCpzYV9zb3VyY2UkQi5jb2RlZAoKcmVzcG9uc2Uoc2FfaW50ZXJhY3Rpb24pIDwtIHlfaGF0CgpwbG90KHNhX2ludGVyYWN0aW9uLCB0eXBlPSJiIikKYGBgCgpjKSBDb21tZW50IG9uIHRoZSBkaWZmZXJlbmNlIGluIHRoZSB0d28gcGF0aHMuCgoqKlRoaXMgR3JhcGggZXhwbGFpbnMgYmV0dGVyIHRoZSBkaWZmZXJlbmNlKioKYGBge3J9CnNhX2ludGVyYWN0aW9uX3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNhX2ludGVyYWN0aW9uKQpwbG90KHNhX2xpbmVhciwgdHlwZT0iYiIpCmxpbmVzKHNhX2ludGVyYWN0aW9uX3NvdXJjZSREZWx0YSxzYV9pbnRlcmFjdGlvbl9zb3VyY2UkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDM1LGxlZ2VuZCA9IGMoIk5vIEludGVyYWN0aW9uIiwgIkludGVyYWN0aW9uIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoK