1 Introduction

This is a brief guide to using the pwr1 package by way of a few examples.

Recall that for a statistical test the following factors are inter-related:

  1. The desired level of significance, \(\alpha\) = P(Type I error)
  2. The power of the test, (1 - \(\beta\)) = 1 - P(Type II error)
  3. The sample size, \(n\)
  4. The minimal effect size of interest
  5. The variance in the response variable

Thus knowing any four factors will provide an estimate for the remaining fifth factor.

In base R the stats package has some functions for calculating power, namely:

  • power.t.test(),
  • power.prop.test(), and
  • power.anova.test().

The pwr package includes substitutes for these functions plus a few more.

1.1 pwr package

The pwr package has various functions useful for power calculations. The first four below overlap with the above-mentioned stats package functions:

  1. pwr.t.test() 1-, 2-sample, and paired t-test
  2. pwr.t2n.test() 2-sample t-test
  3. pwr.2p.test() 2-sample test of proportions (equal size)
  4. pwr.anova.test() balanced 1-way ANOVA
  5. pwr.2p2n.test() 2-sample test of proportions (unequal size)
  6. pwr.p.test() 1-sample test of proportions
  7. pwr.r.test() correlation test
  8. pwr.chisq.test() chi-squared goodness of fit or association test
  9. pwr.f2.test() test of linear model coefficients

One difference between the base stats and the pwr functions is that the latter generally expects standardised (Cohen2) effect sizes as an argument rather than sample statistics such as proportions, means, or variances.

More detailed documentation on the pwr package can be found in its vignette on CRAN.

Install the pwr package using the install.packages() command:

install.packages("pwr")
# Load the pwr package
library(pwr)

2 Examples

2.1 Multiple linear regression

The model for multiple linear regression is as follows:

\[y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_p x_p\]

The null hypothesis is that none of the \(p\) explanatory variables \(x_i\) explain any of the variability in the response variable \(y\). This would mean their regression coefficients, \(\beta_i\), are all statistically indistinguishable from zero.

The alternative hypothesis is that at least one of the coefficients is not equal to zero.

\(H_0: \beta_i = 0, \quad \forall i = 1, 2, \dots, p.\)

\(H_A: \textrm{At least one}\; \beta_i \ne 0,\; \textrm{for}\;i = 1, 2, \dots, p.\)

The pwr function for calculating sample sizes for multiple linear regression is pwr.f2.test().

# List the arguments to the pwr.f2.test() function
args(pwr.f2.test)
## function (u = NULL, v = NULL, f2 = NULL, sig.level = 0.05, power = NULL) 
## NULL

The (numerator) degrees of freedom, \(u\), is the number of coefficients you have in your model.

The (denominator) degrees of freedom, \(v\), is the number of error degrees of freedom \(v = n − u − 1\). Rearranging gives an expression for sample size \(n = v + u + 1\) (always rounding up to the next integer).

The effect size \(f^2 = \frac{R^2}{1−R^2}\), where \(R^2\) is the coefficient of determination, otherwise understood as the proportion of variance in the response variable explained by the multiple regression model.

2.1.1 Determining effect size \(f^2\)

One way to determine the effect size parameter is by first hypothesising an \(R^2\) value, i.e., the proportion of variance that the model will explain.

For example, if we have:

  • six explanatory variables,
  • \(R^2 = 20\%\) which gives \(f^2 = \frac{0.2}{1 - 0.2} = 0.25\),
  • significance level of \(\alpha = 5\%\), and
  • power of \(1 - \beta = 0.8\),

then passing these to the pwr.f2.test() function:

pwr.f2.test(u = 6, 
            f2 = 0.2/(1 - 0.2), 
            sig.level = 0.05, 
            power = 0.8)
## 
##      Multiple regression power calculation 
## 
##               u = 6
##               v = 54.09317
##              f2 = 0.25
##       sig.level = 0.05
##           power = 0.8

we get a \(v = 55\) (rounding up).

From this we can calculate the sample size: \(n = v + u + 1 = 55 + 6 + 1 = 62\).

2.1.2 Cohen’s suggested \(f^2\) values

Alternatively, Cohen (1982)3 suggests that \(f^2\) values of 0.02, 0.15, and 0.35 represent small, medium, and large effect sizes respectively.

These values are conveniently stored in the pwr package and retrieved using the cohen.ES() function:

# Retrieve Cohen's suggested effect sizes
cohen.ES(test = "f2", size = "small")
## 
##      Conventional effect size from Cohen (1982) 
## 
##            test = f2
##            size = small
##     effect.size = 0.02
cohen.ES(test = "f2", size = "medium")
## 
##      Conventional effect size from Cohen (1982) 
## 
##            test = f2
##            size = medium
##     effect.size = 0.15
cohen.ES(test = "f2", size = "large")
## 
##      Conventional effect size from Cohen (1982) 
## 
##            test = f2
##            size = large
##     effect.size = 0.35

Therefore we have:

  • six explanatory variables,
  • \(f^2 = 0.35\) (large effect size)
  • significance level of \(\alpha = 5\%\), and
  • power of \(1 - \beta = 0.8\).
pwr.f2.test(u = 6, 
            f2 = 0.35, 
            sig.level = 0.05, 
            power = 0.8)
## 
##      Multiple regression power calculation 
## 
##               u = 6
##               v = 38.62994
##              f2 = 0.35
##       sig.level = 0.05
##           power = 0.8

Calculating the sample size \(n = v + u + 1 = 39 + 6 + 1 = 46\), i.e., to achieve a power of 80% and be able to detect a large effect size, a sample size of 46 is needed.

2.2 Balanced ANOVA

ANOVA where each group has the same number of samples, i.e., balanced.

Null hypothesis is that the means of each group are all the same.

Alternative hypothesis is that the mean of at least one group is significantly different.

\(H_0: \mu_1 = \mu_2 = \dots = \mu_k\)

\(H_A: \textrm{at least one}\; \mu_i\; \textrm{is different from the others}\)

# If we want to detect even a small difference
cohen.ES(test = "anov", size = "small")
## 
##      Conventional effect size from Cohen (1982) 
## 
##            test = anov
##            size = small
##     effect.size = 0.1

Therefore we have

  • \(k = 3\) groups,
  • \(f = 0.1\) (small effect size)
  • significance level of \(\alpha = 5\%\), and
  • power of \(1 - \beta = 0.8\).
pwr.anova.test(k = 3, 
               f = 0.1, 
               sig.level = 0.05, 
               power = 0.8)
## 
##      Balanced one-way analysis of variance power calculation 
## 
##               k = 3
##               n = 322.157
##               f = 0.1
##       sig.level = 0.05
##           power = 0.8
## 
## NOTE: n is number in each group

Therefore to have 80% power and be able to detect a small difference in effects between groups, 323 samples are needed in each group. That makes a total of 969 samples! Large numbers of samples are needed if you want to detect small effects reliably.

2.3 Two-sample t-Test

For a two-sample t-test where each group has the same number of samples, the null hypothesis is that the means of both groups are all the same.

The alternative hypothesis is that the mean of group 2 is larger.

\(H_0: \mu_1 = \mu_2\)

\(H_A: \mu_1 < \mu_2\)

# Looking for a large effect size
pwr.t.test(d = cohen.ES(test = "t", size = "large")$effect.size, 
           power = 0.80, 
           sig.level = 0.05, 
           alternative = "greater")
## 
##      Two-sample t test power calculation 
## 
##               n = 20.03277
##               d = 0.8
##       sig.level = 0.05
##           power = 0.8
##     alternative = greater
## 
## NOTE: n is number in *each* group

The required sample size is \(n = 21 \times 2 = 42\).

# Compare result with built-in R function
power.t.test(n = 20, 
             sd = 1, 
             sig.level = 0.05, 
             power = 0.8, 
             alternative = "one")
## 
##      Two-sample t test power calculation 
## 
##               n = 20
##           delta = 0.8006829
##              sd = 1
##       sig.level = 0.05
##           power = 0.8
##     alternative = one.sided
## 
## NOTE: n is number in *each* group

Working backwards from sample size, we see that the power.t.test() returns a similar effect size estimate as the pwr function.


  1. pwr package↩︎

  2. Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed.). Hillsdale, NJ: Lawrence Erlbaum.↩︎

  3. Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed.). Hillsdale, NJ: Lawrence Erlbaum.↩︎

LS0tDQp0aXRsZTogImBwd3JgIFBhY2thZ2UgUHJpbWVyIg0KYXV0aG9yOiAiW1NoaWggQ2hpbmcgRnVdKGh0dHBzOi8vc2hpaGNoaW5nZnUuY29tKSINCmRhdGU6ICJNYXJjaCAyMDIwIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICBoaWdobGlnaHQ6IGhhZGRvY2sNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQprbml0OiANCiAgKGZ1bmN0aW9uKGlucHV0X2ZpbGUsIGVuY29kaW5nKSB7DQogICAgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRfZmlsZSwNCiAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZz1lbmNvZGluZywNCiAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZmlsZT1maWxlLnBhdGgoZGlybmFtZShpbnB1dF9maWxlKSwgJ2RvY3MnLCAnaW5kZXguaHRtbCcpKX0pDQotLS0NCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBpcyBhIGJyaWVmIGd1aWRlIHRvIHVzaW5nIHRoZSBgcHdyYFtecHdyXSBwYWNrYWdlIGJ5IHdheSBvZiBhIGZldyBleGFtcGxlcy4NCg0KUmVjYWxsIHRoYXQgZm9yIGEgc3RhdGlzdGljYWwgdGVzdCB0aGUgZm9sbG93aW5nIGZhY3RvcnMgYXJlIGludGVyLXJlbGF0ZWQ6DQoNCjEuIFRoZSBkZXNpcmVkIGxldmVsIG9mIHNpZ25pZmljYW5jZSwgJFxhbHBoYSQgPSBQKFR5cGUgSSBlcnJvcikNCjIuIFRoZSBwb3dlciBvZiB0aGUgdGVzdCwgKDEgLSAkXGJldGEkKSA9IDEgLSBQKFR5cGUgSUkgZXJyb3IpDQozLiBUaGUgc2FtcGxlIHNpemUsICRuJA0KNC4gVGhlIG1pbmltYWwgZWZmZWN0IHNpemUgb2YgaW50ZXJlc3QNCjUuIFRoZSB2YXJpYW5jZSBpbiB0aGUgcmVzcG9uc2UgdmFyaWFibGUNCg0KVGh1cyBrbm93aW5nIGFueSBmb3VyIGZhY3RvcnMgd2lsbCBwcm92aWRlIGFuIGVzdGltYXRlIGZvciB0aGUgcmVtYWluaW5nIGZpZnRoIGZhY3Rvci4NCg0KSW4gYmFzZSBgUmAgdGhlIGBzdGF0c2AgcGFja2FnZSBoYXMgc29tZSBmdW5jdGlvbnMgZm9yIGNhbGN1bGF0aW5nIHBvd2VyLCBuYW1lbHk6IA0KDQotIGBwb3dlci50LnRlc3QoKWAsIA0KLSBgcG93ZXIucHJvcC50ZXN0KClgLCBhbmQgDQotIGBwb3dlci5hbm92YS50ZXN0KClgLiANCg0KVGhlIGBwd3JgIHBhY2thZ2UgaW5jbHVkZXMgc3Vic3RpdHV0ZXMgZm9yIHRoZXNlIGZ1bmN0aW9ucyBwbHVzIGEgZmV3IG1vcmUuDQoNCg0KIyMgYHB3cmAgcGFja2FnZQ0KDQpUaGUgYHB3cmAgcGFja2FnZSBoYXMgdmFyaW91cyBmdW5jdGlvbnMgdXNlZnVsIGZvciBwb3dlciBjYWxjdWxhdGlvbnMuIFRoZSBmaXJzdCBmb3VyIGJlbG93IG92ZXJsYXAgd2l0aCB0aGUgYWJvdmUtbWVudGlvbmVkIGBzdGF0c2AgcGFja2FnZSBmdW5jdGlvbnM6DQoNCjEuIGBwd3IudC50ZXN0KClgIDEtLCAyLXNhbXBsZSwgYW5kIHBhaXJlZCB0LXRlc3QNCjIuIGBwd3IudDJuLnRlc3QoKWAgMi1zYW1wbGUgdC10ZXN0DQozLiBgcHdyLjJwLnRlc3QoKWAgMi1zYW1wbGUgdGVzdCBvZiBwcm9wb3J0aW9ucyAoZXF1YWwgc2l6ZSkNCjQuIGBwd3IuYW5vdmEudGVzdCgpYCBiYWxhbmNlZCAxLXdheSBBTk9WQQ0KNS4gYHB3ci4ycDJuLnRlc3QoKWAgMi1zYW1wbGUgdGVzdCBvZiBwcm9wb3J0aW9ucyAodW5lcXVhbCBzaXplKQ0KNi4gYHB3ci5wLnRlc3QoKWAgMS1zYW1wbGUgdGVzdCBvZiBwcm9wb3J0aW9ucw0KNy4gYHB3ci5yLnRlc3QoKWAgY29ycmVsYXRpb24gdGVzdA0KOC4gYHB3ci5jaGlzcS50ZXN0KClgIGNoaS1zcXVhcmVkIGdvb2RuZXNzIG9mIGZpdCBvciBhc3NvY2lhdGlvbiB0ZXN0DQo5LiBgcHdyLmYyLnRlc3QoKWAgdGVzdCBvZiBsaW5lYXIgbW9kZWwgY29lZmZpY2llbnRzDQoNCk9uZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGJhc2UgYHN0YXRzYCBhbmQgdGhlIGBwd3JgIGZ1bmN0aW9ucyBpcyB0aGF0IHRoZSBsYXR0ZXIgZ2VuZXJhbGx5IGV4cGVjdHMgc3RhbmRhcmRpc2VkIChDb2hlblteY29oZW5dKSBlZmZlY3Qgc2l6ZXMgYXMgYW4gYXJndW1lbnQgcmF0aGVyIHRoYW4gc2FtcGxlIHN0YXRpc3RpY3Mgc3VjaCBhcyBwcm9wb3J0aW9ucywgbWVhbnMsIG9yIHZhcmlhbmNlcy4NCg0KTW9yZSBkZXRhaWxlZCBkb2N1bWVudGF0aW9uIG9uIHRoZSBgcHdyYCBwYWNrYWdlIGNhbiBiZSBmb3VuZCBpbiBpdHMgdmlnbmV0dGUgb24gW0NSQU5dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9wd3IvdmlnbmV0dGVzL3B3ci12aWduZXR0ZS5odG1sKS4NCg0KSW5zdGFsbCB0aGUgYHB3cmAgcGFja2FnZSB1c2luZyB0aGUgYGluc3RhbGwucGFja2FnZXMoKWAgY29tbWFuZDoNCg0KYGBge3IgZXZhbD1GQUxTRX0NCmluc3RhbGwucGFja2FnZXMoInB3ciIpDQpgYGANCg0KYGBge3J9DQojIExvYWQgdGhlIHB3ciBwYWNrYWdlDQpsaWJyYXJ5KHB3cikNCmBgYA0KDQojIEV4YW1wbGVzDQoNCiMjIE11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uDQoNClRoZSBtb2RlbCBmb3IgbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gaXMgYXMgZm9sbG93czoNCg0KJCR5ID0gXGJldGFfMCArIFxiZXRhXzEgeF8xICsgXGJldGFfMiB4XzIgKyBcZG90cyArIFxiZXRhX3AgeF9wJCQNCg0KVGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0aGF0IG5vbmUgb2YgdGhlICRwJCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgJHhfaSQgZXhwbGFpbiBhbnkgb2YgdGhlIHZhcmlhYmlsaXR5IGluIHRoZSByZXNwb25zZSB2YXJpYWJsZSAkeSQuIFRoaXMgd291bGQgbWVhbiB0aGVpciByZWdyZXNzaW9uIGNvZWZmaWNpZW50cywgJFxiZXRhX2kkLCBhcmUgYWxsIHN0YXRpc3RpY2FsbHkgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSB6ZXJvLg0KDQpUaGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyBpcyB0aGF0ICphdCBsZWFzdCBvbmUqIG9mIHRoZSBjb2VmZmljaWVudHMgaXMgbm90IGVxdWFsIHRvIHplcm8uIA0KDQokSF8wOiBcYmV0YV9pID0gMCwgXHF1YWQgXGZvcmFsbCBpID0gMSwgMiwgXGRvdHMsIHAuJA0KDQokSF9BOiBcdGV4dHJte0F0IGxlYXN0IG9uZX1cOyBcYmV0YV9pIFxuZSAwLFw7IFx0ZXh0cm17Zm9yfVw7aSA9IDEsIDIsIFxkb3RzLCBwLiQNCg0KDQpUaGUgYHB3cmAgZnVuY3Rpb24gZm9yIGNhbGN1bGF0aW5nIHNhbXBsZSBzaXplcyBmb3IgbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gaXMgYHB3ci5mMi50ZXN0KClgLg0KDQpgYGB7cn0NCiMgTGlzdCB0aGUgYXJndW1lbnRzIHRvIHRoZSBwd3IuZjIudGVzdCgpIGZ1bmN0aW9uDQphcmdzKHB3ci5mMi50ZXN0KQ0KYGBgDQoNClRoZSAobnVtZXJhdG9yKSBkZWdyZWVzIG9mIGZyZWVkb20sICR1JCwgaXMgdGhlIG51bWJlciBvZiBjb2VmZmljaWVudHMgeW91IGhhdmUgaW4geW91ciBtb2RlbC4gDQoNClRoZSAoZGVub21pbmF0b3IpIGRlZ3JlZXMgb2YgZnJlZWRvbSwgJHYkLCBpcyB0aGUgbnVtYmVyIG9mIGVycm9yIGRlZ3JlZXMgb2YgZnJlZWRvbSAkdiA9IG4g4oiSIHUg4oiSIDEkLiBSZWFycmFuZ2luZyBnaXZlcyBhbiBleHByZXNzaW9uIGZvciBzYW1wbGUgc2l6ZSAkbiA9IHYgKyB1ICsgMSQgKGFsd2F5cyByb3VuZGluZyBfdXBfIHRvIHRoZSBuZXh0IGludGVnZXIpLg0KDQpUaGUgZWZmZWN0IHNpemUgJGZeMiA9IFxmcmFje1JeMn17MeKIklJeMn0kLCB3aGVyZSAkUl4yJCBpcyB0aGUgY29lZmZpY2llbnQgb2YgZGV0ZXJtaW5hdGlvbiwgb3RoZXJ3aXNlIHVuZGVyc3Rvb2QgYXMgdGhlIHByb3BvcnRpb24gb2YgdmFyaWFuY2UgaW4gdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGV4cGxhaW5lZCBieSB0aGUgbXVsdGlwbGUgcmVncmVzc2lvbiBtb2RlbC4gDQoNCiMjIyBEZXRlcm1pbmluZyBlZmZlY3Qgc2l6ZSAkZl4yJA0KDQpPbmUgd2F5IHRvIGRldGVybWluZSB0aGUgZWZmZWN0IHNpemUgcGFyYW1ldGVyIGlzIGJ5IGZpcnN0IGh5cG90aGVzaXNpbmcgYW4gJFJeMiQgdmFsdWUsIGkuZS4sIHRoZSBwcm9wb3J0aW9uIG9mIHZhcmlhbmNlIHRoYXQgdGhlIG1vZGVsIHdpbGwgZXhwbGFpbi4NCg0KRm9yIGV4YW1wbGUsIGlmIHdlIGhhdmU6DQoNCi0gc2l4IGV4cGxhbmF0b3J5IHZhcmlhYmxlcywgDQotICRSXjIgPSAyMFwlJCB3aGljaCBnaXZlcyAkZl4yID0gXGZyYWN7MC4yfXsxIC0gMC4yfSA9IDAuMjUkLA0KLSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgJFxhbHBoYSA9IDVcJSQsIGFuZA0KLSBwb3dlciBvZiAkMSAtIFxiZXRhID0gMC44JCwNCg0KdGhlbiBwYXNzaW5nIHRoZXNlIHRvIHRoZSBgcHdyLmYyLnRlc3QoKWAgZnVuY3Rpb246DQoNCmBgYHtyfQ0KcHdyLmYyLnRlc3QodSA9IDYsIA0KICAgICAgICAgICAgZjIgPSAwLjIvKDEgLSAwLjIpLCANCiAgICAgICAgICAgIHNpZy5sZXZlbCA9IDAuMDUsIA0KICAgICAgICAgICAgcG93ZXIgPSAwLjgpDQpgYGANCg0Kd2UgZ2V0IGEgJHYgPSA1NSQgKHJvdW5kaW5nIHVwKS4gDQoNCkZyb20gdGhpcyB3ZSBjYW4gY2FsY3VsYXRlIHRoZSBzYW1wbGUgc2l6ZTogJG4gPSB2ICsgdSArIDEgPSA1NSArIDYgKyAxID0gNjIkLiANCg0KIyMjIENvaGVuJ3Mgc3VnZ2VzdGVkICRmXjIkIHZhbHVlcw0KDQpBbHRlcm5hdGl2ZWx5LCBDb2hlbiAoMTk4MilbXmNvaGVuXSBzdWdnZXN0cyB0aGF0ICRmXjIkIHZhbHVlcyBvZiAwLjAyLCAwLjE1LCBhbmQgMC4zNSByZXByZXNlbnQgc21hbGwsIG1lZGl1bSwgYW5kIGxhcmdlIGVmZmVjdCBzaXplcyByZXNwZWN0aXZlbHkuDQoNClRoZXNlIHZhbHVlcyBhcmUgY29udmVuaWVudGx5IHN0b3JlZCBpbiB0aGUgYHB3cmAgcGFja2FnZSBhbmQgcmV0cmlldmVkIHVzaW5nIHRoZSBgY29oZW4uRVMoKWAgZnVuY3Rpb246DQoNCmBgYHtyfQ0KIyBSZXRyaWV2ZSBDb2hlbidzIHN1Z2dlc3RlZCBlZmZlY3Qgc2l6ZXMNCmNvaGVuLkVTKHRlc3QgPSAiZjIiLCBzaXplID0gInNtYWxsIikNCmNvaGVuLkVTKHRlc3QgPSAiZjIiLCBzaXplID0gIm1lZGl1bSIpDQpjb2hlbi5FUyh0ZXN0ID0gImYyIiwgc2l6ZSA9ICJsYXJnZSIpDQpgYGANCg0KVGhlcmVmb3JlIHdlIGhhdmU6IA0KDQotIHNpeCBleHBsYW5hdG9yeSB2YXJpYWJsZXMsIA0KLSAkZl4yID0gMC4zNSQgKGxhcmdlIGVmZmVjdCBzaXplKQ0KLSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgJFxhbHBoYSA9IDVcJSQsIGFuZA0KLSBwb3dlciBvZiAkMSAtIFxiZXRhID0gMC44JC4NCg0KDQpgYGB7cn0NCnB3ci5mMi50ZXN0KHUgPSA2LCANCiAgICAgICAgICAgIGYyID0gMC4zNSwgDQogICAgICAgICAgICBzaWcubGV2ZWwgPSAwLjA1LCANCiAgICAgICAgICAgIHBvd2VyID0gMC44KQ0KYGBgDQoNCkNhbGN1bGF0aW5nIHRoZSBzYW1wbGUgc2l6ZSAkbiA9IHYgKyB1ICsgMSA9IDM5ICsgNiArIDEgPSA0NiQsIGkuZS4sIHRvIGFjaGlldmUgYSBwb3dlciBvZiA4MCUgYW5kIGJlIGFibGUgdG8gZGV0ZWN0IGEgbGFyZ2UgZWZmZWN0IHNpemUsIGEgc2FtcGxlIHNpemUgb2YgNDYgaXMgbmVlZGVkLg0KDQoNCiMjIEJhbGFuY2VkIEFOT1ZBDQoNCkFOT1ZBIHdoZXJlIGVhY2ggZ3JvdXAgaGFzIHRoZSBzYW1lIG51bWJlciBvZiBzYW1wbGVzLCBpLmUuLCBfYmFsYW5jZWRfLg0KDQpOdWxsIGh5cG90aGVzaXMgaXMgdGhhdCB0aGUgbWVhbnMgb2YgZWFjaCBncm91cCBhcmUgYWxsIHRoZSBzYW1lLg0KDQpBbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGlzIHRoYXQgdGhlIG1lYW4gb2YgYXQgbGVhc3Qgb25lIGdyb3VwIGlzIHNpZ25pZmljYW50bHkgZGlmZmVyZW50Lg0KDQokSF8wOiBcbXVfMSA9IFxtdV8yID0gXGRvdHMgPSBcbXVfayQNCg0KJEhfQTogXHRleHRybXthdCBsZWFzdCBvbmV9XDsgXG11X2lcOyBcdGV4dHJte2lzIGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlcnN9JA0KDQoNCmBgYHtyfQ0KIyBJZiB3ZSB3YW50IHRvIGRldGVjdCBldmVuIGEgc21hbGwgZGlmZmVyZW5jZQ0KY29oZW4uRVModGVzdCA9ICJhbm92Iiwgc2l6ZSA9ICJzbWFsbCIpDQpgYGANCg0KVGhlcmVmb3JlIHdlIGhhdmUgDQoNCi0gJGsgPSAzJCBncm91cHMsDQotICRmID0gMC4xJCAoc21hbGwgZWZmZWN0IHNpemUpDQotIHNpZ25pZmljYW5jZSBsZXZlbCBvZiAkXGFscGhhID0gNVwlJCwgYW5kDQotIHBvd2VyIG9mICQxIC0gXGJldGEgPSAwLjgkLiANCg0KDQpgYGB7cn0NCnB3ci5hbm92YS50ZXN0KGsgPSAzLCANCiAgICAgICAgICAgICAgIGYgPSAwLjEsIA0KICAgICAgICAgICAgICAgc2lnLmxldmVsID0gMC4wNSwgDQogICAgICAgICAgICAgICBwb3dlciA9IDAuOCkNCmBgYA0KDQpUaGVyZWZvcmUgdG8gaGF2ZSA4MCUgcG93ZXIgYW5kIGJlIGFibGUgdG8gZGV0ZWN0IGEgc21hbGwgZGlmZmVyZW5jZSBpbiBlZmZlY3RzIGJldHdlZW4gZ3JvdXBzLCAzMjMgc2FtcGxlcyBhcmUgbmVlZGVkIGluIGVhY2ggZ3JvdXAuIFRoYXQgbWFrZXMgYSB0b3RhbCBvZiA5Njkgc2FtcGxlcyEgTGFyZ2UgbnVtYmVycyBvZiBzYW1wbGVzIGFyZSBuZWVkZWQgaWYgeW91IHdhbnQgdG8gZGV0ZWN0IHNtYWxsIGVmZmVjdHMgcmVsaWFibHkuDQoNCg0KIyMgVHdvLXNhbXBsZSB0LVRlc3QNCg0KRm9yIGEgdHdvLXNhbXBsZSB0LXRlc3Qgd2hlcmUgZWFjaCBncm91cCBoYXMgdGhlIHNhbWUgbnVtYmVyIG9mIHNhbXBsZXMsIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgdGhhdCB0aGUgbWVhbnMgb2YgYm90aCBncm91cHMgYXJlIGFsbCB0aGUgc2FtZS4NCg0KVGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgaXMgdGhhdCB0aGUgbWVhbiBvZiBncm91cCAyIGlzIGxhcmdlci4NCg0KJEhfMDogXG11XzEgPSBcbXVfMiQNCg0KJEhfQTogXG11XzEgPCBcbXVfMiQNCg0KDQpgYGB7cn0NCiMgTG9va2luZyBmb3IgYSBsYXJnZSBlZmZlY3Qgc2l6ZQ0KcHdyLnQudGVzdChkID0gY29oZW4uRVModGVzdCA9ICJ0Iiwgc2l6ZSA9ICJsYXJnZSIpJGVmZmVjdC5zaXplLCANCiAgICAgICAgICAgcG93ZXIgPSAwLjgwLCANCiAgICAgICAgICAgc2lnLmxldmVsID0gMC4wNSwgDQogICAgICAgICAgIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKQ0KYGBgDQoNClRoZSByZXF1aXJlZCBzYW1wbGUgc2l6ZSBpcyAkbiA9IDIxIFx0aW1lcyAyID0gNDIkLg0KDQoNCmBgYHtyfQ0KIyBDb21wYXJlIHJlc3VsdCB3aXRoIGJ1aWx0LWluIFIgZnVuY3Rpb24NCnBvd2VyLnQudGVzdChuID0gMjAsIA0KICAgICAgICAgICAgIHNkID0gMSwgDQogICAgICAgICAgICAgc2lnLmxldmVsID0gMC4wNSwgDQogICAgICAgICAgICAgcG93ZXIgPSAwLjgsIA0KICAgICAgICAgICAgIGFsdGVybmF0aXZlID0gIm9uZSIpDQpgYGANCg0KV29ya2luZyBiYWNrd2FyZHMgZnJvbSBzYW1wbGUgc2l6ZSwgd2Ugc2VlIHRoYXQgdGhlIGBwb3dlci50LnRlc3QoKWAgcmV0dXJucyBhIHNpbWlsYXIgZWZmZWN0IHNpemUgZXN0aW1hdGUgYXMgdGhlIGBwd3JgIGZ1bmN0aW9uLg0KDQpbXnB3cl06IFtgcHdyYF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3B3ci8pIHBhY2thZ2UNCg0KW15jb2hlbl06IENvaGVuLCBKLiAoMTk4OCkuIFN0YXRpc3RpY2FsIHBvd2VyIGFuYWx5c2lzIGZvciB0aGUgYmVoYXZpb3JhbCBzY2llbmNlcyAoMm5kIGVkLikuIEhpbGxzZGFsZSwgTko6IExhd3JlbmNlIEVybGJhdW0uDQo=