View the latest recording of this lecture

In this lecture we introduce linear models with two factors.

We look at the formulation of such models, and consider significance tests for the factors.

Estimation for models with two (or more) factors can be performed by the method of least squares in the usual way.

Fitted values and residuals are also defined as usual.

A Main Effects Model for Two Factors

Suppose that there are two factors, A and B, which may be related to the response variable.

The most straightforward way of modelling these factors is to assume that their effects are additive.

This leads to what can be termed the main effects two-way model.

The rationale for using the phrase main effects will become clear when we look at interactions between factors.

Model for Two Factors as a Multiple Linear Regression

Written in the same way as was done for the one factor model:

\[Y_i = \mu + \alpha_2 z_{Ai2} + \ldots + \alpha_K z_{AiK} + \beta_2 z_{Bi2} + \ldots + \beta_L z_{BiL} + \varepsilon_i~~~~~(i=1,2,\ldots,n)\] where \[z_{Aij} = \left \{ \begin{array}{ll} 1 & \mbox{unit } i \mbox{ observed at level } j \mbox{ of } A\\ 0 & \mbox{otherwise} \end{array} \right .\] and \[z_{Bij} = \left \{ \begin{array}{ll} 1 & \mbox{unit } i \mbox{ observed at level } j \mbox{ of } B\\ 0 & \mbox{otherwise} \end{array} \right .\]

No \(\alpha_1 z_{Ai1}\) and \(\beta_1 z_{Bi1}\) as we assume treatment constraints. That is, \(\alpha_1 = 0\) and \(\beta_1 = 0\).

Tests for Main Effects in a Two-Way Model

In a two factor model we are usually interested in testing for the statistical significance of both factors.

The importance of a factor may depend upon other factors in the model, in the same way that the importance of a numerical predictor in a multiple linear regression model depends upon the other explanatory variables in the model.

The importance of the factors can be assessed by comparing appropriate nested models using F tests.

Models Under Consideration

There are a number of possible main effects models based on at most two factors A and B:

  • Both A and B have an effect on the response: \[M_{AB}:~~Y_i = \mu + \alpha_2 z_{Ai2} + \ldots + \alpha_K z_{AiK} + \beta_2 z_{Bi2} + \ldots + \beta_L z_{BiL} + \varepsilon_i\]
  • Only A has an effect on the response: \[M_A:~~Y_i = \mu + \alpha_2 z_{Ai2} + \ldots + \alpha_K z_{AiK} + \varepsilon_i\]
  • Only B has an effect on the response: \[M_B:~~Y_i = \mu + \beta_2 z_{Bi2} + \ldots + \beta_L z_{BiL} + \varepsilon_i\]
  • Neither A nor B have an effect on the response: \[M_0:~~Y_i = \mu + \varepsilon_i\]

Testing for the Importance of B adjusted for A

This involves comparing the nested models \(M_{AB}\) and \(M_A\).

This can be done by testing \[H_0:~~\beta_2 = \beta_3 = \cdots = \beta_L = 0\] versus

\[H_1:~~\beta_2, \beta_3, \cdots, \beta_L \mbox{ not all zero}\]

The appropriate F test statistic (on \(L-1, n-K-L+1\) degrees of freedom) is

\[F = \frac{(RSS_{A} - RSS_{AB})/(L-1)}{RSS_{AB}/(n-K-L+1)}\]

As usual, large values of this F statistic provide evidence against \(H_0\) (hence give small p-values).

The relevant figures for this F test can be displayed in an ANOVA table.

ANOVA Tables for Two Factor Main Effects Model

Df Sum Sq Mean Sq F value P value
Factor A K-1 SSA MSA fA PA
Factor B (adj. A) L-1 \(SSB|A\) \(MSB|A\) \(f_{B|A}\) \(P_{B|A}\)
Residual n-K-L+1 RSS RMS
Total n-1 TSS

The residual row refers to residuals from model MAB.

The row for factor A gives the F statistic for testing the importance of A without adjusting for B.

The second row gives the F statistic for testing the importance of B adjusted for A as just discussed.

We can construct a new ANOVA table with first two rows swapped in order to test for A adjusted for B.

Example: Foster Feeding Rats

In this example, we are looking at a dataset on baby rats fed by foster mothers. Genotype (A, B, I or J) are recorded for both rat and foster mother. The weight of baby rats is recorded at a given age. The factors are genotypes of rat and mother. Does weight depend on either?

who likes rats?
who likes rats?

Analysis of the Data

Download ratgene.csv

## Rat <- read.csv(file = "ratgene.csv", header = TRUE)
head(Rat)
  Rat Mother Weight
1   A      A   61.5
2   A      A   68.2
3   A      A   64.0
4   A      A   65.0
5   A      A   59.7
6   A      B   55.0

Let’s first fit a two-way model with Rat variable first, and Mother variable second.

Rat.lm.1 <- lm(Weight ~ Rat + Mother, data = Rat)
anova(Rat.lm.1)
Analysis of Variance Table

Response: Weight
          Df Sum Sq Mean Sq F value   Pr(>F)   
Rat        3   60.2  20.052  0.3317 0.802470   
Mother     3  775.1 258.360  4.2732 0.008861 **
Residuals 54 3264.9  60.461                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(Rat.lm.1)

Call:
lm(formula = Weight ~ Rat + Mother, data = Rat)

Residuals:
    Min      1Q  Median      3Q     Max 
-18.425  -5.584   2.499   5.416  13.745 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   56.909      2.478  22.964   <2e-16 ***
RatB          -2.025      2.795  -0.725   0.4719    
RatI          -2.654      2.827  -0.939   0.3520    
RatJ          -2.021      2.757  -0.733   0.4668    
MotherB        3.516      2.862   1.229   0.2246    
MotherI       -1.832      2.767  -0.662   0.5107    
MotherJ       -6.755      2.810  -2.404   0.0197 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.776 on 54 degrees of freedom
Multiple R-squared:  0.2037,    Adjusted R-squared:  0.1152 
F-statistic: 2.302 on 6 and 54 DF,  p-value: 0.04732

This first model indicates that the genotype of the rat is unimportant (P=0.802), but that the genotype of the foster mother adjusted for the genotype of the rat is statistically significant (P=0.00886).

Now we fit the model with Mother variable first, and Rat variable second.

Rat.lm.2 <- lm(Weight ~ Mother + Rat, data = Rat)
anova(Rat.lm.2)
Analysis of Variance Table

Response: Weight
          Df Sum Sq Mean Sq F value   Pr(>F)   
Mother     3  771.6 257.202  4.2540 0.009055 **
Rat        3   63.6  21.211  0.3508 0.788698   
Residuals 54 3264.9  60.461                    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(Rat.lm.2)

Call:
lm(formula = Weight ~ Mother + Rat, data = Rat)

Residuals:
    Min      1Q  Median      3Q     Max 
-18.425  -5.584   2.499   5.416  13.745 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   56.909      2.478  22.964   <2e-16 ***
MotherB        3.516      2.862   1.229   0.2246    
MotherI       -1.832      2.767  -0.662   0.5107    
MotherJ       -6.755      2.810  -2.404   0.0197 *  
RatB          -2.025      2.795  -0.725   0.4719    
RatI          -2.654      2.827  -0.939   0.3520    
RatJ          -2.021      2.757  -0.733   0.4668    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.776 on 54 degrees of freedom
Multiple R-squared:  0.2037,    Adjusted R-squared:  0.1152 
F-statistic: 2.302 on 6 and 54 DF,  p-value: 0.04732

There is little change in p-values when we alter the order of the terms to get the second model. Note that zero change only occurs in a special case (next lecture).

Comments and Conclusions

Overall, it seems clear that weight is not associated with genotype of the rat, so whether we adjust for this term is pretty much immaterial.

Weight is clearly associated with genotype of the foster mother.

Genotype A is reference level (baseline) for both Mother and Rat genotypes.

The summary() command (which gives parameter estimates) suggests that genotype J makes for poor foster mothers.

Fitted Values for the Rats Model

  1. Calculate the fitted value for genotype A rat with genotype J foster mother.

  2. Calculate the fitted value for genotype J rat with genotype A foster mother.

  3. Calculate the fitted value for genotype B rat with genotype B foster mother.

LS0tDQp0aXRsZTogIkxlY3R1cmUgMjI6IEludHJvZHVjdGlvbiB0byB0aGUgVHdvIEZhY3RvciBNb2RlbCINCnN1YnRpdGxlOiAxNjEuMjUxIFJlZ3Jlc3Npb24gTW9kZWxsaW5nDQphdXRob3I6ICJQcmVzZW50ZWQgYnkgSm9uYXRoYW4gR29kZnJleSA8YS5qLmdvZGZyZXlAbWFzc2V5LmFjLm56PiIgIA0KZGF0ZTogIldlZWsgOCBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCg0KW1ZpZXcgdGhlIGxhdGVzdCByZWNvcmRpbmcgb2YgdGhpcyBsZWN0dXJlXShodHRwczovL1ItUmVzb3VyY2VzLm1hc3NleS5hYy5uei92aWRlb3MvMjUxTDIyLm1wNCkNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0KPCEtLS0gY291bGQgc3dpdGNoIGRhdGEgc291cmNlIHRvIE1BU1M6Omdlbm90eXBlIC0tLT4NCg0KSW4gdGhpcyBsZWN0dXJlIHdlIGludHJvZHVjZSBsaW5lYXIgbW9kZWxzIHdpdGggdHdvIGZhY3RvcnMuDQoNCldlIGxvb2sgYXQgdGhlIGZvcm11bGF0aW9uIG9mIHN1Y2ggbW9kZWxzLCBhbmQgY29uc2lkZXIgc2lnbmlmaWNhbmNlDQogICAgdGVzdHMgZm9yIHRoZSBmYWN0b3JzLg0KDQpFc3RpbWF0aW9uIGZvciBtb2RlbHMgd2l0aCB0d28gKG9yIG1vcmUpIGZhY3RvcnMgY2FuIGJlIHBlcmZvcm1lZCBieQ0KICAgIHRoZSBtZXRob2Qgb2YgbGVhc3Qgc3F1YXJlcyBpbiB0aGUgdXN1YWwgd2F5Lg0KDQpGaXR0ZWQgdmFsdWVzIGFuZCByZXNpZHVhbHMgYXJlIGFsc28gZGVmaW5lZCBhcyB1c3VhbC4NCg0KIyMgQSBNYWluIEVmZmVjdHMgTW9kZWwgZm9yIFR3byBGYWN0b3JzDQoNClN1cHBvc2UgdGhhdCB0aGVyZSBhcmUgdHdvIGZhY3RvcnMsICpBKiBhbmQgKkIqLCB3aGljaCBtYXkgYmUNCiAgICByZWxhdGVkIHRvIHRoZSByZXNwb25zZSB2YXJpYWJsZS4NCg0KVGhlIG1vc3Qgc3RyYWlnaHRmb3J3YXJkIHdheSBvZiBtb2RlbGxpbmcgdGhlc2UgZmFjdG9ycyBpcyB0byBhc3N1bWUNCiAgICB0aGF0IHRoZWlyIGVmZmVjdHMgYXJlIGFkZGl0aXZlLg0KDQpUaGlzIGxlYWRzIHRvIHdoYXQgY2FuIGJlIHRlcm1lZCB0aGUgbWFpbiBlZmZlY3RzDQogICAgdHdvLXdheSBtb2RlbC4NCg0KVGhlIHJhdGlvbmFsZSBmb3IgdXNpbmcgdGhlIHBocmFzZSBtYWluIGVmZmVjdHMgd2lsbA0KICAgIGJlY29tZSBjbGVhciB3aGVuIHdlIGxvb2sgYXQgaW50ZXJhY3Rpb25zIGJldHdlZW4gZmFjdG9ycy4NCg0KIyMjIE1vZGVsIGZvciBUd28gRmFjdG9ycyBhcyBhIE11bHRpcGxlIExpbmVhciBSZWdyZXNzaW9uDQoNCldyaXR0ZW4gaW4gdGhlIHNhbWUgd2F5IGFzIHdhcyBkb25lIGZvciB0aGUgb25lIGZhY3RvciBtb2RlbDoNCg0KJCRZX2kgPSBcbXUgKyBcYWxwaGFfMiB6X3tBaTJ9ICsgXGxkb3RzICsgXGFscGhhX0sgel97QWlLfSANCiArIFxiZXRhXzIgel97QmkyfSArIFxsZG90cyArIFxiZXRhX0wgel97QmlMfSArIFx2YXJlcHNpbG9uX2l+fn5+fihpPTEsMixcbGRvdHMsbikkJA0Kd2hlcmUgJCR6X3tBaWp9ID0gDQpcbGVmdCBceyANClxiZWdpbnthcnJheX17bGx9DQoxICYgXG1ib3h7dW5pdCB9IGkgXG1ib3h7IG9ic2VydmVkIGF0IGxldmVsIH0gaiBcbWJveHsgb2YgfSBBXFwNCjAgJiBcbWJveHtvdGhlcndpc2V9DQpcZW5ke2FycmF5fQ0KXHJpZ2h0IC4kJCBhbmQgJCR6X3tCaWp9ID0gDQpcbGVmdCBceyANClxiZWdpbnthcnJheX17bGx9DQoxICYgXG1ib3h7dW5pdCB9IGkgXG1ib3h7IG9ic2VydmVkIGF0IGxldmVsIH0gaiBcbWJveHsgb2YgfSBCXFwNCjAgJiBcbWJveHtvdGhlcndpc2V9DQpcZW5ke2FycmF5fQ0KXHJpZ2h0IC4kJA0KDQpObyAkXGFscGhhXzEgel97QWkxfSQgYW5kICRcYmV0YV8xIHpfe0JpMX0kIGFzIHdlIGFzc3VtZSB0cmVhdG1lbnQNCmNvbnN0cmFpbnRzLiBUaGF0IGlzLCAkXGFscGhhXzEgPSAwJCBhbmQgJFxiZXRhXzEgPSAwJC4NCg0KIyMjIFRlc3RzIGZvciBNYWluIEVmZmVjdHMgaW4gYSBUd28tV2F5IE1vZGVsDQoNCkluIGEgdHdvIGZhY3RvciBtb2RlbCB3ZSBhcmUgdXN1YWxseSBpbnRlcmVzdGVkIGluIHRlc3RpbmcgZm9yIHRoZQ0KICAgIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBvZiBib3RoIGZhY3RvcnMuDQoNClRoZSBpbXBvcnRhbmNlIG9mIGEgZmFjdG9yIG1heSBkZXBlbmQgdXBvbiBvdGhlciBmYWN0b3JzIGluIHRoZQ0KICAgIG1vZGVsLCBpbiB0aGUgc2FtZSB3YXkgdGhhdCB0aGUgaW1wb3J0YW5jZSBvZiBhIG51bWVyaWNhbCBwcmVkaWN0b3INCiAgICBpbiBhIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIGRlcGVuZHMgdXBvbiB0aGUgb3RoZXINCiAgICBleHBsYW5hdG9yeSB2YXJpYWJsZXMgaW4gdGhlIG1vZGVsLg0KDQpUaGUgaW1wb3J0YW5jZSBvZiB0aGUgZmFjdG9ycyBjYW4gYmUgYXNzZXNzZWQgYnkgY29tcGFyaW5nDQogICAgYXBwcm9wcmlhdGUgbmVzdGVkIG1vZGVscyB1c2luZyAqRiogdGVzdHMuDQoNCiMjIyBNb2RlbHMgVW5kZXIgQ29uc2lkZXJhdGlvbg0KDQpUaGVyZSBhcmUgYSBudW1iZXIgb2YgcG9zc2libGUgbWFpbiBlZmZlY3RzIG1vZGVscyBiYXNlZCBvbiBhdCBtb3N0IHR3bw0KZmFjdG9ycyBBIGFuZCBCOg0KDQotIEJvdGggQSBhbmQgQiBoYXZlIGFuIGVmZmVjdCBvbiB0aGUgcmVzcG9uc2U6ICQkTV97QUJ9On5+WV9pID0gXG11ICsgXGFscGhhXzIgel97QWkyfSArIFxsZG90cyArIFxhbHBoYV9LIHpfe0FpS30gKyBcYmV0YV8yIHpfe0JpMn0gKyBcbGRvdHMgKyBcYmV0YV9MIHpfe0JpTH0gKyBcdmFyZXBzaWxvbl9pJCQNCi0gT25seSBBIGhhcyBhbiBlZmZlY3Qgb24gdGhlIHJlc3BvbnNlOiAkJE1fQTp+fllfaSA9IFxtdSArIFxhbHBoYV8yIHpfe0FpMn0gKyBcbGRvdHMgKyBcYWxwaGFfSyB6X3tBaUt9ICsgXHZhcmVwc2lsb25faSQkDQotIE9ubHkgQiBoYXMgYW4gZWZmZWN0IG9uIHRoZSByZXNwb25zZTogJCRNX0I6fn5ZX2kgPSBcbXUgKyBcYmV0YV8yIHpfe0JpMn0gKyBcbGRvdHMgKyBcYmV0YV9MIHpfe0JpTH0gKyBcdmFyZXBzaWxvbl9pJCQNCi0gTmVpdGhlciBBIG5vciBCIGhhdmUgYW4gZWZmZWN0IG9uIHRoZSByZXNwb25zZTogJCRNXzA6fn5ZX2kgPSBcbXUgKyBcdmFyZXBzaWxvbl9pJCQNCg0KIyMjIFRlc3RpbmcgZm9yIHRoZSBJbXBvcnRhbmNlIG9mICpCKiBhZGp1c3RlZCBmb3IgKkEqDQoNClRoaXMgaW52b2x2ZXMgY29tcGFyaW5nIHRoZSBuZXN0ZWQgbW9kZWxzICRNX3tBQn0kIGFuZCAkTV9BJC4NCg0KVGhpcyBjYW4gYmUgZG9uZSBieSB0ZXN0aW5nDQokJEhfMDp+flxiZXRhXzIgPSBcYmV0YV8zID0gXGNkb3RzID0gXGJldGFfTCA9IDAkJA0KdmVyc3VzDQoNCiQkSF8xOn5+XGJldGFfMiwgXGJldGFfMywgXGNkb3RzLCBcYmV0YV9MIFxtYm94eyBub3QgYWxsIHplcm99JCQNCg0KVGhlIGFwcHJvcHJpYXRlICpGKiB0ZXN0IHN0YXRpc3RpYyAob24gJEwtMSwgbi1LLUwrMSQgZGVncmVlcyBvZg0KICAgIGZyZWVkb20pIGlzDQoNCiQkRiA9IFxmcmFjeyhSU1Nfe0F9IC0gUlNTX3tBQn0pLyhMLTEpfXtSU1Nfe0FCfS8obi1LLUwrMSl9JCQNCg0KQXMgdXN1YWwsIGxhcmdlIHZhbHVlcyBvZiB0aGlzICpGKiBzdGF0aXN0aWMgcHJvdmlkZSBldmlkZW5jZQ0KICAgIGFnYWluc3QgJEhfMCQgKGhlbmNlIGdpdmUgc21hbGwgKnAqLXZhbHVlcykuDQoNClRoZSByZWxldmFudCBmaWd1cmVzIGZvciB0aGlzICpGKiB0ZXN0IGNhbiBiZSBkaXNwbGF5ZWQgaW4gYW4gQU5PVkENCiAgICB0YWJsZS4NCg0KIyMjIEFOT1ZBIFRhYmxlcyBmb3IgVHdvIEZhY3RvciBNYWluIEVmZmVjdHMgTW9kZWwNCg0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgIERmICAgICAgfCAgICBTdW0gU3EgfCAgIE1lYW4gU3EgfCAgICAgRiB2YWx1ZSB8ICAgICBQIHZhbHVlIHwNCnwgOi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IDotLS0tLS0tLS06IHwgLS0tLS0tLS06IHwgLS0tLS0tLS06IHwgLS0tLS0tLS0tLTogfCAtLS0tLS0tLS0tOiB8DQp8IEZhY3RvciAqQSogICAgICAgICAgICAgIHwgICAqSy0xKiAgIHwgICAqU1NBKiB8ICAgKk1TQSogfCAgICAgKmZ+QX4qIHwgICAgICpQfkF+KiB8DQp8IEZhY3RvciAqQiogKGFkai4gKkEqKSB8ICAgKkwtMSogICB8ICRTU0J8QSQgfCAkTVNCfEEkIHwgJGZfe0J8QX0kIHwgJFBfe0J8QX0kIHwNCnwgUmVzaWR1YWwgICAgICAgICAgICAgICAgICB8ICpuLUstTCsxKiB8ICAgKlJTUyogfCAgICpSTVMqIHwgICAgICAgICAgICAgfCAgICAgICAgICAgICB8DQp8IFRvdGFsICAgICAgICAgICAgICAgICAgICAgfCAgICpuLTEqICAgfCAgICpUU1MqIHwgICAgICAgICAgIHwgICAgICAgICAgICAgfCAgICAgICAgICAgICB8DQoNClRoZSByZXNpZHVhbCByb3cgcmVmZXJzIHRvIHJlc2lkdWFscyBmcm9tIG1vZGVsICpNfkFCfiouDQoNClRoZSByb3cgZm9yIGZhY3RvciAqQSogZ2l2ZXMgdGhlICpGKiBzdGF0aXN0aWMgZm9yIHRlc3RpbmcgdGhlDQogICAgaW1wb3J0YW5jZSBvZiAqQSogd2l0aG91dCBhZGp1c3RpbmcgZm9yICpCKi4NCg0KVGhlIHNlY29uZCByb3cgZ2l2ZXMgdGhlICpGKiBzdGF0aXN0aWMgZm9yIHRlc3RpbmcgdGhlIGltcG9ydGFuY2UNCiAgICBvZiAqQiogYWRqdXN0ZWQgZm9yICpBKiBhcyBqdXN0IGRpc2N1c3NlZC4NCg0KV2UgY2FuIGNvbnN0cnVjdCBhIG5ldyBBTk9WQSB0YWJsZSB3aXRoIGZpcnN0IHR3byByb3dzIHN3YXBwZWQgaW4gb3JkZXINCiAgICB0byB0ZXN0IGZvciAqQSogYWRqdXN0ZWQgZm9yICpCKi4NCg0KIyMgRXhhbXBsZTogRm9zdGVyIEZlZWRpbmcgUmF0cw0KDQoNCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSBhcmUgbG9va2luZyBhdCBhIGRhdGFzZXQgb24gYmFieSByYXRzIGZlZCBieSBmb3N0ZXIgbW90aGVycy4NCkdlbm90eXBlIChBLCBCLCBJIG9yIEopIGFyZSByZWNvcmRlZCBmb3IgYm90aCByYXQgYW5kIGZvc3RlciBtb3RoZXIuDQpUaGUgd2VpZ2h0IG9mIGJhYnkgcmF0cyBpcyByZWNvcmRlZCBhdCBhIGdpdmVuIGFnZS4NClRoZSBmYWN0b3JzIGFyZSBnZW5vdHlwZXMgb2YgcmF0IGFuZCBtb3RoZXIuIERvZXMgd2VpZ2h0IGRlcGVuZCBvbiBlaXRoZXI/DQoNCiFbd2hvIGxpa2VzIHJhdHM/XSguLi9ncmFwaGljcy9yYXRzLmpwZykNCg0KDQoNCg0KIyMjIEFuYWx5c2lzIG9mIHRoZSBEYXRhDQoNCmByIHhmdW46OmVtYmVkX2ZpbGUoIi4uLy4uL2RhdGEvcmF0Z2VuZS5jc3YiKWANCg0KYGBge3IgUmF0LmRhdGEsIGVjaG89LTEsIGV2YWw9LTJ9DQpSYXQgPC0gcmVhZC5jc3YoZmlsZT0iLi4vLi4vZGF0YS9yYXRnZW5lLmNzdiIsIGhlYWRlcj1UUlVFKQ0KUmF0IDwtIHJlYWQuY3N2KGZpbGU9InJhdGdlbmUuY3N2IiwgaGVhZGVyPVRSVUUpDQpoZWFkKFJhdCkNCmBgYA0KDQpMZXQncyBmaXJzdCBmaXQgYSB0d28td2F5IG1vZGVsIHdpdGggYFJhdGAgdmFyaWFibGUgZmlyc3QsIGFuZCBgTW90aGVyYCB2YXJpYWJsZSBzZWNvbmQuIA0KDQpgYGB7ciBSYXQubG0uMX0NClJhdC5sbS4xIDwtIGxtKFdlaWdodCB+ICAgUmF0ICsgTW90aGVyLCBkYXRhPVJhdCkNCmFub3ZhKFJhdC5sbS4xKQ0Kc3VtbWFyeShSYXQubG0uMSkNCmBgYA0KDQpUaGlzIGZpcnN0IG1vZGVsIGluZGljYXRlcyB0aGF0IHRoZSBnZW5vdHlwZSBvZiB0aGUgcmF0IGlzIHVuaW1wb3J0YW50DQogICAgKCpQPTAuODAyKiksIGJ1dCB0aGF0IHRoZSBnZW5vdHlwZSBvZiB0aGUgZm9zdGVyIG1vdGhlciBhZGp1c3RlZCBmb3INCiAgICB0aGUgZ2Vub3R5cGUgb2YgdGhlIHJhdCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50ICgqUD0wLjAwODg2KikuDQoNCk5vdyB3ZSBmaXQgdGhlIG1vZGVsIHdpdGggYE1vdGhlcmAgdmFyaWFibGUgZmlyc3QsIGFuZCBgUmF0YCB2YXJpYWJsZSBzZWNvbmQuIA0KDQoNCmBgYHtyIFJhdC5sbS4yfQ0KUmF0LmxtLjIgPC0gbG0oV2VpZ2h0IH4gIE1vdGhlciArIFJhdCAgLCBkYXRhPVJhdCkNCmFub3ZhKFJhdC5sbS4yKQ0Kc3VtbWFyeShSYXQubG0uMikNCmBgYA0KDQpUaGVyZSBpcyBsaXR0bGUgY2hhbmdlIGluICpwKi12YWx1ZXMgd2hlbiB3ZSBhbHRlciB0aGUgb3JkZXIgb2YgdGhlIHRlcm1zIHRvIGdldCB0aGUgc2Vjb25kIG1vZGVsLiBOb3RlIHRoYXQgemVybyBjaGFuZ2Ugb25seSBvY2N1cnMgaW4gYSBzcGVjaWFsIGNhc2UgKG5leHQgbGVjdHVyZSkuDQoNCg0KIyMjIENvbW1lbnRzIGFuZCBDb25jbHVzaW9ucw0KDQpPdmVyYWxsLCBpdCBzZWVtcyBjbGVhciB0aGF0IHdlaWdodCBpcyBub3QgYXNzb2NpYXRlZCB3aXRoIGdlbm90eXBlDQogICAgb2YgdGhlIHJhdCwgc28gd2hldGhlciB3ZSBhZGp1c3QgZm9yIHRoaXMgdGVybSBpcyBwcmV0dHkgbXVjaA0KICAgIGltbWF0ZXJpYWwuDQoNCldlaWdodCBpcyBjbGVhcmx5IGFzc29jaWF0ZWQgd2l0aCBnZW5vdHlwZSBvZiB0aGUgZm9zdGVyIG1vdGhlci4NCg0KR2Vub3R5cGUgQSBpcyByZWZlcmVuY2UgbGV2ZWwgKGJhc2VsaW5lKSBmb3IgYm90aCBgTW90aGVyYCBhbmQgYFJhdGAgZ2Vub3R5cGVzLg0KDQpUaGUgYHN1bW1hcnkoKWAgY29tbWFuZCAod2hpY2ggZ2l2ZXMgcGFyYW1ldGVyIGVzdGltYXRlcykgc3VnZ2VzdHMgdGhhdA0KICAgIGdlbm90eXBlIEogbWFrZXMgZm9yIHBvb3IgZm9zdGVyIG1vdGhlcnMuDQoNCiMjIyBGaXR0ZWQgVmFsdWVzIGZvciB0aGUgUmF0cyBNb2RlbA0KDQoxLiAgQ2FsY3VsYXRlIHRoZSBmaXR0ZWQgdmFsdWUgZm9yIGdlbm90eXBlIEEgcmF0IHdpdGggZ2Vub3R5cGUgSiBmb3N0ZXINCiAgICBtb3RoZXIuDQoNCjIuICBDYWxjdWxhdGUgdGhlIGZpdHRlZCB2YWx1ZSBmb3IgZ2Vub3R5cGUgSiByYXQgd2l0aCBnZW5vdHlwZSBBIGZvc3Rlcg0KICAgIG1vdGhlci4NCg0KMy4gIENhbGN1bGF0ZSB0aGUgZml0dGVkIHZhbHVlIGZvciBnZW5vdHlwZSBCIHJhdCB3aXRoIGdlbm90eXBlIEIgZm9zdGVyDQogICAgbW90aGVyLg0KDQo=