To experiment with the concepts of non-paramteric, data analysis, we will work with the shrimps dataset.

1 The shrimps dataset

A dataset on PCBs (Polychlorinated biphenyls) accumulation in the adipose tissue of shrimps.

PCBs are often present in coolants, and are know to accumulate easily in the adipose tissue of shrimps. In this experiment, two groups of 18 samples (each 100 grams) of shrimps each were cultivated in different conditions, one control condition and one condition where the medium was poluted with PCBs.

Load the required R libraries

library(tidyverse)
## ── Attaching packages ──────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.2.1     ✓ purrr   0.3.3
## ✓ tibble  2.1.3     ✓ dplyr   0.8.3
## ✓ tidyr   1.0.0     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.4.0
## ── Conflicts ─────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

2 Import the data

shrimps <- read.table("https://raw.githubusercontent.com/GTPB/PSLS20/master/data/shrimps.txt",header = TRUE)

3 Initial exploration of the data

glimpse(shrimps)
## Observations: 36
## Variables: 2
## $ PCB.conc <dbl> 29.7, 24.5, 97.7, 39.1, 22.6, 32.4, 27.7, 100.1, 40.1, 23.3,…
## $ group    <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, …

4 Data tidying

shrimps <- shrimps %>%
  mutate(group = as.factor(group))

5 Goal

The research question is; is there an effect of the growth condition on the PCB concentration in the adipose tissue of shrimps. Note that the PCB concentrations were measured in pg/g adipose tissue.

6 Data visualization

The first step is to explore the data.

shrimps %>%
  count(group)
## # A tibble: 2 x 2
##   group     n
##   <fct> <int>
## 1 1        18
## 2 2        18

Visualize the data:

shrimps %>% 
  ggplot(aes(x=group,y=PCB.conc,fill=group)) + 
  scale_fill_brewer(palette="RdGy") +
  theme_bw() +
  geom_boxplot(outlier.shape=NA) + 
  geom_jitter(width = 0.2) +
  ggtitle("Boxplot of the PCB concentrations in two groups of shrimps") +
  ylab("PCB concentration (pg/g)") + 
  stat_summary(fun.y=mean, geom="point", shape=5, size=3, color="black", fill="black")

We can see that for group 1 we have 4 very clear outliers in the data. These values were double-checked (i.e for typing errors), but there was no reason found to believe that these values are incorrect.

As we have seen in the second tutorial, a good way for testing the research hypothesis is to perform an unpaired two-sample t-test to find out whether there is a significant difference in the mean PCB concentrations between both groups of samples. Before we can do this, we must check if all the required assumptions are met.

  1. The observations are independent of each other (in both groups)
  2. The data (PCB.conc) must be normally distributed (in both groups)

The first assumption is met, as we randomly selected shrimps and submitted them to one of two growth conditions. No underlying correlation patterns are expected.

We can check the second assumption with a QQ-plot.

shrimps %>% 
  ggplot(aes(sample=PCB.conc)) +
  geom_qq() +
  geom_qq_line() + 
  facet_grid(~group)

We clearly see that we have strong deviations from normality. Many datapoints do not lie near the quantile-quantile line. As such, we may conclude that our data is not normally distributed. In addition, the visualization with the boxplots shows that the variability is quite different between the two groups.

As such, we are not allowed to perform the t-test. As an alternative, we may perform a non-parametric test, such as the Wilcoxon rank-sum test.

6.1 Wilcoxon rank-sum test

The Wilcoxon rank-sum test (or the Mann-Whitney U test, which is equivalent) is an important non-parametric data analysis method.In rank-based tests, the data \(Y_i\) is first transformed to its ranked equivalent \[ R_i=R(Y_i) = \#\{Y_j: Y_j\leq Y_i; j=1,\ldots, n\}. \]

Ranks are very robust to outliers. For instance, it doesn’t matter if the highest value in an hypothetical dataset has a value of 10 or 100; it will keep the same rank (highest rank).

Note that there might be tied values in the data, e.g., if two samples of shrimps have an equal concentration of PCBs. In this case, the Wilcoxon rank-sum test will compute mid-ranks, which are calculated as follows; \[R(Y_i) = \frac{\sum\limits_{\forall j : Y_j=Y_i}R(Y_j)}{\#{\forall j:Y_j=Y_i}} \] i.e., the midrank is equal to the mean of the ranks of equal observations.

After compting the ranks and midranks, the Wilcoxon test will compare the mean rank between both treatment groups:

PCB_1 <- shrimps %>%
  filter(group == "1") %>%
  pull(PCB.conc)

PCB_2 <- shrimps %>%
  filter(group == "2") %>%
  pull(PCB.conc)

wilcox.test(PCB_1,PCB_2)
## 
##  Wilcoxon rank sum test
## 
## data:  PCB_1 and PCB_2
## W = 88, p-value = 0.01871
## alternative hypothesis: true location shift is not equal to 0

or, equivalently;

wilcox.test(PCB.conc~group, data = shrimps)
## 
##  Wilcoxon rank sum test
## 
## data:  PCB.conc by group
## W = 88, p-value = 0.01871
## alternative hypothesis: true location shift is not equal to 0

We find that the test is significant on the 5% significance level (p = 0.01871). The value W=88 could be calculated manually as the sum of the ranks of the PCB concentration values that belong to shrimps of group 1.

The interpretation of the Wilcoxon rank-sum test is slightly more challenging than that of a t-test. Since we are not using average values in this test, we cannot interpret the results in terms of means (as with the t-test). In contrast, we work with ranks, and we will interpret the results in terms of the probabilistic index.

The null hypothesis of the Wilcoxon test states that the distributions of the probability density functions are equal for both groups:

\[ H_0: f_1 = f_2 \]

In words: the distribution of PCB concentrations in shrimps are equal for both treatment conditions.

or, equivalently,

The probability that a random observation of a PCB concentration derived from a sample of shrimps that was grown in the control condition is larger than or equal to than a random observation of a PCB concentration derived from a sample of shrimps that was grown in the other condition is equal to 50%.

The alternative hypothesis can be formulated as

\[ H_1: P(Y_{i1} \geq Y_{i2}) \ne 1/2 \]

In words: The probability that a random observation of a PCB concentration derived from a sample of shrimps that was grown in the control condition is larger than or equal to than a random observation of a PCB concentration derived from a sample of shrimps that was grown in the other condition is not equal to 50%.

We can manually calculate this probability, that is 50% under the null hypothesis, based on the observed test statistic.

n1 <- n2 <- 18 #18 observations in each group
WObs <- wilcox.test(PCB.conc~group, data=shrimps)$statistic # get the observed test statistic
WObs/(n1*n2)
##         W 
## 0.2716049

We can see taht the point estimation of this probability is 27.2%.

We can interpret this as follows;

The probability that the PCB concentration in a random shrimp that was grown in the control condition is greater than or equal to the PCB concentration in a random shrimp that was grown in the treatment condition is equal to 27.2%.

This chance is significantly different from 50% on the 5% significance level (p = 0.01871).

LS0tCnRpdGxlOiAiVHV0b3JpYWwgNS4zOiBOb24tcGFyYW1ldHJpYyBhbmFseXNpcyBvbiB0aGUgc2hyaW1wcyBkYXRhc2V0IiAgIApvdXRwdXQ6CiAgICBodG1sX2RvY3VtZW50OgogICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlICAgIAogICAgICB0aGVtZTogY29zbW8KICAgICAgdG9jOiB0cnVlCiAgICAgIHRvY19mbG9hdDogdHJ1ZQogICAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQotLS0KClRvIGV4cGVyaW1lbnQgd2l0aCB0aGUgY29uY2VwdHMgb2Ygbm9uLXBhcmFtdGVyaWMsCmRhdGEgYW5hbHlzaXMsIHdlIHdpbGwgd29yayB3aXRoIHRoZSBzaHJpbXBzIGRhdGFzZXQuCgojIFRoZSBzaHJpbXBzIGRhdGFzZXQKCkEgZGF0YXNldCBvbiBQQ0JzIChQb2x5Y2hsb3JpbmF0ZWQgYmlwaGVueWxzKSBhY2N1bXVsYXRpb24KaW4gdGhlIGFkaXBvc2UgdGlzc3VlIG9mIHNocmltcHMuCgpQQ0JzIGFyZSBvZnRlbiBwcmVzZW50IGluIGNvb2xhbnRzLCBhbmQgYXJlIGtub3cgdG8gYWNjdW11bGF0ZQplYXNpbHkgaW4gdGhlIGFkaXBvc2UgdGlzc3VlIG9mIHNocmltcHMuIEluIHRoaXMgZXhwZXJpbWVudCwgdHdvCmdyb3VwcyBvZiAxOCBzYW1wbGVzIChlYWNoIDEwMCBncmFtcykgb2Ygc2hyaW1wcyBlYWNoIHdlcmUgY3VsdGl2YXRlZCAKaW4gZGlmZmVyZW50IGNvbmRpdGlvbnMsIG9uZSBjb250cm9sIGNvbmRpdGlvbiBhbmQgb25lIGNvbmRpdGlvbiAKd2hlcmUgdGhlIG1lZGl1bSB3YXMgcG9sdXRlZCB3aXRoIFBDQnMuCgpMb2FkIHRoZSByZXF1aXJlZCBSIGxpYnJhcmllcwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCiMgSW1wb3J0IHRoZSBkYXRhCgpgYGB7cn0Kc2hyaW1wcyA8LSByZWFkLnRhYmxlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vR1RQQi9QU0xTMjAvbWFzdGVyL2RhdGEvc2hyaW1wcy50eHQiLGhlYWRlciA9IFRSVUUpCmBgYAoKIyBJbml0aWFsIGV4cGxvcmF0aW9uIG9mIHRoZSBkYXRhCgpgYGB7cn0KZ2xpbXBzZShzaHJpbXBzKQpgYGAKCiMgRGF0YSB0aWR5aW5nCgpgYGB7cn0Kc2hyaW1wcyA8LSBzaHJpbXBzICU+JQogIG11dGF0ZShncm91cCA9IGFzLmZhY3Rvcihncm91cCkpCmBgYAoKIyBHb2FsCgpUaGUgcmVzZWFyY2ggcXVlc3Rpb24gaXM7IGlzIHRoZXJlIGFuIGVmZmVjdCBvZiB0aGUgCmdyb3d0aCBjb25kaXRpb24gb24gdGhlIFBDQiBjb25jZW50cmF0aW9uIGluIHRoZSBhZGlwb3NlIAp0aXNzdWUgb2Ygc2hyaW1wcy4gTm90ZSB0aGF0IHRoZSBQQ0IgY29uY2VudHJhdGlvbnMgd2VyZSAKbWVhc3VyZWQgaW4gcGcvZyBhZGlwb3NlIHRpc3N1ZS4KCiMgRGF0YSB2aXN1YWxpemF0aW9uCgpUaGUgZmlyc3Qgc3RlcCBpcyB0byBleHBsb3JlIHRoZSBkYXRhLgoKYGBge3J9CnNocmltcHMgJT4lCiAgY291bnQoZ3JvdXApCmBgYAoKVmlzdWFsaXplIHRoZSBkYXRhOgoKYGBge3J9CnNocmltcHMgJT4lIAogIGdncGxvdChhZXMoeD1ncm91cCx5PVBDQi5jb25jLGZpbGw9Z3JvdXApKSArIAogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGU9IlJkR3kiKSArCiAgdGhlbWVfYncoKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGU9TkEpICsgCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIpICsKICBnZ3RpdGxlKCJCb3hwbG90IG9mIHRoZSBQQ0IgY29uY2VudHJhdGlvbnMgaW4gdHdvIGdyb3VwcyBvZiBzaHJpbXBzIikgKwogIHlsYWIoIlBDQiBjb25jZW50cmF0aW9uIChwZy9nKSIpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGdlb209InBvaW50Iiwgc2hhcGU9NSwgc2l6ZT0zLCBjb2xvcj0iYmxhY2siLCBmaWxsPSJibGFjayIpCmBgYAoKV2UgY2FuIHNlZSB0aGF0IGZvciBncm91cCAxIHdlIGhhdmUgNCB2ZXJ5IGNsZWFyIG91dGxpZXJzCmluIHRoZSBkYXRhLiBUaGVzZSB2YWx1ZXMgd2VyZSBkb3VibGUtY2hlY2tlZCAoaS5lIGZvcgp0eXBpbmcgZXJyb3JzKSwgYnV0IHRoZXJlIHdhcyBubyByZWFzb24gZm91bmQgdG8gYmVsaWV2ZQp0aGF0IHRoZXNlIHZhbHVlcyBhcmUgaW5jb3JyZWN0LgoKQXMgd2UgaGF2ZSBzZWVuIGluIHRoZSBzZWNvbmQgdHV0b3JpYWwsIGEgZ29vZCB3YXkgZm9yCnRlc3RpbmcgdGhlIHJlc2VhcmNoIGh5cG90aGVzaXMgaXMgdG8gcGVyZm9ybSBhbiB1bnBhaXJlZAp0d28tc2FtcGxlIHQtdGVzdCB0byBmaW5kIG91dCB3aGV0aGVyIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQKZGlmZmVyZW5jZSBpbiB0aGUgbWVhbiBQQ0IgY29uY2VudHJhdGlvbnMgYmV0d2VlbiBib3RoIGdyb3VwcwpvZiBzYW1wbGVzLiBCZWZvcmUgd2UgY2FuIGRvIHRoaXMsIHdlIG11c3QgY2hlY2sgaWYgYWxsIHRoZSAKcmVxdWlyZWQgYXNzdW1wdGlvbnMgYXJlIG1ldC4KCjEuIFRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIgKGluIGJvdGggZ3JvdXBzKQoyLiBUaGUgZGF0YSAoUENCLmNvbmMpIG11c3QgYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgKGluIGJvdGggZ3JvdXBzKQoKVGhlIGZpcnN0IGFzc3VtcHRpb24gaXMgbWV0LCBhcyB3ZSByYW5kb21seSBzZWxlY3RlZCBzaHJpbXBzIGFuZApzdWJtaXR0ZWQgdGhlbSB0byBvbmUgb2YgdHdvIGdyb3d0aCBjb25kaXRpb25zLiBObyB1bmRlcmx5aW5nCmNvcnJlbGF0aW9uIHBhdHRlcm5zIGFyZSBleHBlY3RlZC4KCldlIGNhbiBjaGVjayB0aGUgc2Vjb25kIGFzc3VtcHRpb24gd2l0aCBhIFFRLXBsb3QuCgpgYGB7cn0Kc2hyaW1wcyAlPiUgCiAgZ2dwbG90KGFlcyhzYW1wbGU9UENCLmNvbmMpKSArCiAgZ2VvbV9xcSgpICsKICBnZW9tX3FxX2xpbmUoKSArIAogIGZhY2V0X2dyaWQofmdyb3VwKQpgYGAKCldlIGNsZWFybHkgc2VlIHRoYXQgd2UgaGF2ZSBzdHJvbmcgZGV2aWF0aW9ucyBmcm9tCm5vcm1hbGl0eS4gTWFueSBkYXRhcG9pbnRzIGRvIG5vdCBsaWUgbmVhciB0aGUgcXVhbnRpbGUtcXVhbnRpbGUKbGluZS4gQXMgc3VjaCwgd2UgbWF5IGNvbmNsdWRlIHRoYXQgb3VyIGRhdGEgaXMgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgpJbiBhZGRpdGlvbiwgdGhlIHZpc3VhbGl6YXRpb24gd2l0aCB0aGUgYm94cGxvdHMgc2hvd3MgdGhhdCB0aGUKdmFyaWFiaWxpdHkgaXMgcXVpdGUgZGlmZmVyZW50IGJldHdlZW4gdGhlIHR3byBncm91cHMuCgpBcyBzdWNoLCB3ZSBhcmUgbm90IGFsbG93ZWQgdG8gcGVyZm9ybSB0aGUgdC10ZXN0LiAKQXMgYW4gYWx0ZXJuYXRpdmUsIHdlIG1heSBwZXJmb3JtIGEgbm9uLXBhcmFtZXRyaWMKdGVzdCwgc3VjaCBhcyB0aGUgV2lsY294b24gcmFuay1zdW0gdGVzdC4KCiMjIFdpbGNveG9uIHJhbmstc3VtIHRlc3QKClRoZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IChvciB0aGUgTWFubi1XaGl0bmV5IFUgdGVzdCwKd2hpY2ggaXMgZXF1aXZhbGVudCkgaXMgYW4gaW1wb3J0YW50IG5vbi1wYXJhbWV0cmljIGRhdGEKYW5hbHlzaXMgbWV0aG9kLkluIHJhbmstYmFzZWQgdGVzdHMsIHRoZSBkYXRhICRZX2kkIGlzCmZpcnN0IHRyYW5zZm9ybWVkIHRvIGl0cyByYW5rZWQgZXF1aXZhbGVudApcWyBSX2k9UihZX2kpID0gXCNce1lfajogWV9qXGxlcSBZX2k7IGo9MSxcbGRvdHMsIG5cfS4gXF0KClJhbmtzIGFyZSB2ZXJ5IHJvYnVzdCB0byBvdXRsaWVycy4gRm9yIGluc3RhbmNlLCBpdCBkb2Vzbid0Cm1hdHRlciBpZiB0aGUgaGlnaGVzdCB2YWx1ZSBpbiBhbiBoeXBvdGhldGljYWwgZGF0YXNldCBoYXMgYSAKdmFsdWUgb2YgMTAgb3IgMTAwOyBpdCB3aWxsIGtlZXAgdGhlIHNhbWUgcmFuayAoaGlnaGVzdCByYW5rKS4KCk5vdGUgdGhhdCB0aGVyZSBtaWdodCBiZSB0aWVkIHZhbHVlcyBpbiB0aGUgZGF0YSwgZS5nLiwgaWYKdHdvIHNhbXBsZXMgb2Ygc2hyaW1wcyBoYXZlIGFuIGVxdWFsIGNvbmNlbnRyYXRpb24gb2YgUENCcy4KSW4gdGhpcyBjYXNlLCB0aGUgV2lsY294b24gcmFuay1zdW0gdGVzdCB3aWxsIGNvbXB1dGUKbWlkLXJhbmtzLCB3aGljaCBhcmUgY2FsY3VsYXRlZCBhcyBmb2xsb3dzOwpcW1IoWV9pKSA9IFxmcmFje1xzdW1cbGltaXRzX3tcZm9yYWxsIGogOiBZX2o9WV9pfVIoWV9qKX17XCN7XGZvcmFsbCBqOllfaj1ZX2l9fSAgXF0KaS5lLiwgdGhlIG1pZHJhbmsgaXMgZXF1YWwgdG8gdGhlIG1lYW4gb2YgdGhlIHJhbmtzIG9mIGVxdWFsCm9ic2VydmF0aW9ucy4KCkFmdGVyIGNvbXB0aW5nIHRoZSByYW5rcyBhbmQgbWlkcmFua3MsIHRoZSBXaWxjb3hvbiB0ZXN0IHdpbGwKY29tcGFyZSB0aGUgbWVhbiByYW5rIGJldHdlZW4gYm90aCB0cmVhdG1lbnQgZ3JvdXBzOgoKYGBge3J9ClBDQl8xIDwtIHNocmltcHMgJT4lCiAgZmlsdGVyKGdyb3VwID09ICIxIikgJT4lCiAgcHVsbChQQ0IuY29uYykKClBDQl8yIDwtIHNocmltcHMgJT4lCiAgZmlsdGVyKGdyb3VwID09ICIyIikgJT4lCiAgcHVsbChQQ0IuY29uYykKCndpbGNveC50ZXN0KFBDQl8xLFBDQl8yKQpgYGAKCm9yLCBlcXVpdmFsZW50bHk7CgpgYGB7cn0Kd2lsY294LnRlc3QoUENCLmNvbmN+Z3JvdXAsIGRhdGEgPSBzaHJpbXBzKQpgYGAKIApXZSBmaW5kIHRoYXQgdGhlIHRlc3QgaXMgc2lnbmlmaWNhbnQgb24gdGhlIDUlCnNpZ25pZmljYW5jZSBsZXZlbCAocCA9IDAuMDE4NzEpLiBUaGUgdmFsdWUgVz04OApjb3VsZCBiZSBjYWxjdWxhdGVkIG1hbnVhbGx5IGFzIHRoZSBzdW0gb2YgdGhlIHJhbmtzCm9mIHRoZSBQQ0IgY29uY2VudHJhdGlvbiB2YWx1ZXMgdGhhdCBiZWxvbmcgdG8gCnNocmltcHMgb2YgZ3JvdXAgMS4KClRoZSBpbnRlcnByZXRhdGlvbiBvZiB0aGUgV2lsY294b24gcmFuay1zdW0gdGVzdCBpcwpzbGlnaHRseSBtb3JlIGNoYWxsZW5naW5nIHRoYW4gdGhhdCBvZiBhIHQtdGVzdC4KU2luY2Ugd2UgYXJlIG5vdCB1c2luZyBhdmVyYWdlIHZhbHVlcyBpbiB0aGlzIHRlc3QsCndlIGNhbm5vdCBpbnRlcnByZXQgdGhlIHJlc3VsdHMgaW4gdGVybXMgb2YgbWVhbnMKKGFzIHdpdGggdGhlIHQtdGVzdCkuIEluIGNvbnRyYXN0LCB3ZSB3b3JrIHdpdGggcmFua3MsCmFuZCB3ZSB3aWxsIGludGVycHJldCB0aGUgcmVzdWx0cyBpbiB0ZXJtcyBvZiB0aGUKKnByb2JhYmlsaXN0aWMgaW5kZXgqLgoKVGhlIG51bGwgaHlwb3RoZXNpcyBvZiB0aGUgV2lsY294b24gdGVzdCBzdGF0ZXMgdGhhdAp0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgcHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbnMKYXJlIGVxdWFsIGZvciBib3RoIGdyb3VwczoKClxbIEhfMDogZl8xID0gZl8yIFxdCgpJbiB3b3JkczogdGhlIGRpc3RyaWJ1dGlvbiBvZiBQQ0IgY29uY2VudHJhdGlvbnMgaW4gCnNocmltcHMgYXJlIGVxdWFsIGZvciBib3RoIHRyZWF0bWVudCBjb25kaXRpb25zLgoKb3IsIGVxdWl2YWxlbnRseSwKClRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgcmFuZG9tIG9ic2VydmF0aW9uIG9mIGEgUENCCmNvbmNlbnRyYXRpb24gZGVyaXZlZCBmcm9tIGEgc2FtcGxlIG9mIHNocmltcHMgdGhhdAp3YXMgZ3Jvd24gaW4gdGhlIGNvbnRyb2wgY29uZGl0aW9uICppcyBsYXJnZXIgdGhhbiBvciBlcXVhbCB0byoKdGhhbiBhIHJhbmRvbSBvYnNlcnZhdGlvbiBvZiBhIFBDQiBjb25jZW50cmF0aW9uIApkZXJpdmVkIGZyb20gYSBzYW1wbGUgb2Ygc2hyaW1wcyB0aGF0IHdhcyBncm93biBpbiAKdGhlIG90aGVyIGNvbmRpdGlvbiAqaXMgZXF1YWwgdG8gNTAlKi4KClRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGNhbiBiZSBmb3JtdWxhdGVkIGFzCgpcWyBIXzE6IFAoWV97aTF9IFxnZXEgWV97aTJ9KSBcbmUgMS8yIFxdCgpJbiB3b3JkczogVGhlIHByb2JhYmlsaXR5IHRoYXQgYSByYW5kb20gb2JzZXJ2YXRpb24gb2YgYSAKUENCIGNvbmNlbnRyYXRpb24gZGVyaXZlZCBmcm9tIGEgc2FtcGxlIG9mIHNocmltcHMgdGhhdAp3YXMgZ3Jvd24gaW4gdGhlIGNvbnRyb2wgY29uZGl0aW9uICppcyBsYXJnZXIgdGhhbiBvciBlcXVhbCB0byoKdGhhbiBhIHJhbmRvbSBvYnNlcnZhdGlvbiBvZiBhIFBDQiBjb25jZW50cmF0aW9uIApkZXJpdmVkIGZyb20gYSBzYW1wbGUgb2Ygc2hyaW1wcyB0aGF0IHdhcyBncm93biBpbiAKdGhlIG90aGVyIGNvbmRpdGlvbiAqaXMgbm90IGVxdWFsIHRvIDUwJSouCgpXZSBjYW4gbWFudWFsbHkgY2FsY3VsYXRlIHRoaXMgcHJvYmFiaWxpdHksIHRoYXQgaXMgNTAlIAp1bmRlciB0aGUgbnVsbCBoeXBvdGhlc2lzLCBiYXNlZCBvbiB0aGUgb2JzZXJ2ZWQgdGVzdCBzdGF0aXN0aWMuCgpgYGB7cn0KbjEgPC0gbjIgPC0gMTggIzE4IG9ic2VydmF0aW9ucyBpbiBlYWNoIGdyb3VwCldPYnMgPC0gd2lsY294LnRlc3QoUENCLmNvbmN+Z3JvdXAsIGRhdGE9c2hyaW1wcykkc3RhdGlzdGljICMgZ2V0IHRoZSBvYnNlcnZlZCB0ZXN0IHN0YXRpc3RpYwpXT2JzLyhuMSpuMikKYGBgCgpXZSBjYW4gc2VlIHRhaHQgdGhlIHBvaW50IGVzdGltYXRpb24gb2YgdGhpcyBwcm9iYWJpbGl0eSAKaXMgYHIgcm91bmQoV09icy8objEqbjIpLDMpKjEwMGAlLgoKV2UgY2FuIGludGVycHJldCB0aGlzIGFzIGZvbGxvd3M7CgpUaGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgUENCIGNvbmNlbnRyYXRpb24gaW4gYSByYW5kb20Kc2hyaW1wIHRoYXQgd2FzIGdyb3duIGluIHRoZSBjb250cm9sIGNvbmRpdGlvbiBpcyAKZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBQQ0IgY29uY2VudHJhdGlvbiBpbiBhIHJhbmRvbQpzaHJpbXAgdGhhdCB3YXMgZ3Jvd24gaW4gdGhlIHRyZWF0bWVudCBjb25kaXRpb24gaXMKZXF1YWwgdG8gMjcuMiUuCgpUaGlzIGNoYW5jZSBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIDUwJSBvbiB0aGUKNSUgc2lnbmlmaWNhbmNlIGxldmVsIChwID0gMC4wMTg3MSkuCgoKCgoKCg==