For this practical, we will use data from a sample of the Teaching dataset of The Longitudinal Study of Young People in England, 2004-2006 available here.

We will be fitting a series of school value-added models, which are one of the most prominent examples of multilevel models applied in education research.

A traditional school value-added model is a model that attempts to isolate the “school effects” from the inherent variability/heterogeneity of the pupils. It attempts to ascertain what schools add to the progress of their pupils beyond what is expected of them, given their circumstances.



Typical workflow setup and data preparation

1.1. Define a working directory

You can use any directory in your computer. As in the example below:

setwd("C:/myfolder")

Remember to download the data to the folder you will define as working directory, as this makes matters easier.

1.2. Load packages

You can always load packages later on, but it is a good practice to load packages at the beginning of the session on the top of your script or R markdown file.

In this practical, we will use the packages haven, lme4 and ggplot2. Remember that if you haven’t installed them before, you need to do so before you call the library function:

install.packages("haven")
install.packages("lme4")
install.packages("ggplot2")
install.packages("dplyr")

Then you load them as such:

library(haven)
library(lme4)
library(ggplot2)
library(dplyr)

1.3. Read in data

You can download the data from the UKDS website. There are two SPSS datasets and we will be using the one named “lsype_15000_final_2011_05_04.sav”.

You can also download the file from the link below, but this link will stop working by the end of the session, so make sure to register and download the data from the UKDS if you want to continue working with this dataset.

To read this dataset into R, we need to use the package haven:

ype<-read_sav("https://github.com/A-mora/MLM_summer-school/raw/main/data/lsype_15000_final_2011_05_04.sav")



Select variables to use

In England and Wales, the Department for Education (DfE) publishes periodically the so-called performance tables, in which schools are assessed (and classified) according to the progress that their pupils make from one stage to another. Secondary schools are judged on the GCSE results of their pupils and the progress they made since the end of primary, when they sat the KS2 tests.

We will select the variables: pupilid, schoolID, ks2stand (KS2 scores), ks4stand (GCSE scores), gender, fsm and indschool.

For this, we need to use the function select of the dplyr package:

valueadded <- select(ype, pupilid, schoolID, 
                     ks2stand, ks4stand, gender, 
                     fsm) 



Task 1: Relationship between KS2 and GCSE

Plot the relationship between KS2 and GCSE scores

plot1 <- ggplot(valueadded, aes(x=ks2stand, y=ks4stand)) +
geom_point() + geom_smooth(aes(x=ks2stand, y=ks4stand), method = "lm")

plot1

Questions:

1.1 What can you observe in the plot?

Answer: The relationship between KS2 and GCSE scores is as expected: in general, the better the KS2 score, the better the GCSE score. Nevertheless, there is plenty of variability.

1.2 How correlated are KS2 and GCSE scores?

Answer: Obtain the correlation between scores. This indicates a moderate positive correlation as hinted by the previous plot.

cor(valueadded$ks2stand, valueadded$ks4stand, use="comp")
## [1] 0.6714863



Task 2: Variance components (empty) model

Fit an empty multilevel model of pupils within schools

library(lme4)

We will use the lmer functions, which stands for “linear mixed effects regression”. The basic syntax follows the conventions of most R packages running regression. You specify an outcome regressed ~ on variables. Each variable you add needs to be preceded by a + sign. You specify the data.

Note that we will use Maximum Likelihood (ML), not Restricted Maximum Likelihood (REML). REML is the default in lmer, so we need to specify REML = FALSE

Random effects are added within brackets after the fixed effects. 1 indicates that the constant is allowed to vary freely. The random effects are specified like this: (1|level2id). If you want to want random slopes, you specify (1 + variable|level2id)

m0 <- lmer(ks4stand ~ 1 + (1|schoolID), data = valueadded, REML = F)

summary(m0)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ 1 + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
## 111792.8 111815.7 -55893.4 111786.8    15401 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -3.7751 -0.6241  0.0163  0.6378  4.0338 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept) 24.33    4.932   
##  Residual             75.85    8.709   
## Number of obs: 15404, groups:  schoolID, 657
## 
## Fixed effects:
##             Estimate Std. Error t value
## (Intercept)  -0.1125     0.2057  -0.547

This model is called “type 0” value-added model in the literature

Question

2.1. What is the proportion of variation that lies between schools in the empty model?

Answer: You should use the following equation:

\[VPC = \frac{\sigma_u^2}{\sigma_u^2 + \sigma_e^2}\] where \(\sigma_u^2\) is the variance at the school level and \(\sigma_e^2\) is the variance at the pupil level.

Replacing the values:

\[VPC = \frac{24.33}{24.33 + 75.85} = 24.28 \]

2.2. What does that value mean?

Answer: Approximately 24% of the total variance can be attributed to differences between schools.


Task 3: Is the MLM better than a single-level model?

To assess the statistical significance of the MLM, we need to compare it to a single-level model. To fit a single-level model, we type:

single <- lm(ks4stand ~ 1 , data = valueadded)

summary(single)
## 
## Call:
## lm(formula = ks4stand ~ 1, data = valueadded)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -23.026  -7.026  -0.026   6.974  38.974 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  0.02577    0.07999   0.322    0.747
## 
## Residual standard error: 9.928 on 15403 degrees of freedom
##   (366 observations deleted due to missingness)

These results are not very interesting in themselves, so we move on extract the loglikelihood and compare to the MLM.

L1 <- as.numeric(logLik(single)) # store this as numerical to re-use
L2 <- as.numeric(logLik(m0))

(D <- 2*(L2-L1)) # this is the deviance, we put it within brackets to print it immediately
## [1] 2641.369
pchisq(q=D, df=1, lower.tail=F) # To find the p-value
## [1] 0

Question

3.1. Is the addition of the school level statistically significant?

Answer: Yes it is! Even if you hadn’t done the loglikelihood test, the VPC of 24% is strong evidence of the relevance of school effects.

3.2. What does this mean in practice?

Answer: It means that it is extremely important to control for the rather large variability between schools in your models.


LS0tDQp0aXRsZTogIkludHJvIHRvIE1MTTogUHJhY3RpY2FsIDEiDQphdXRob3I6IFBhdHJpY2lvIFRyb25jb3NvIGFuZCBBbmEgTW9yYWxlcy1Hw7NtZXoNCmRhdGU6ICJKdW5lIDIwMjQiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGhpZ2hsaWdodGVyOiBudWxsDQogICAgdGhlbWU6IGNvc21vDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGZvbnRzaXplOiAxMnB0DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQpGb3IgdGhpcyBwcmFjdGljYWwsIHdlIHdpbGwgdXNlIGRhdGEgZnJvbSBhIHNhbXBsZSBvZiB0aGUgVGVhY2hpbmcgZGF0YXNldCBvZiBUaGUgTG9uZ2l0dWRpbmFsIFN0dWR5IG9mIFlvdW5nIFBlb3BsZSBpbiBFbmdsYW5kLCAyMDA0LTIwMDYNCmF2YWlsYWJsZSBbKipoZXJlKipdKGh0dHBzOi8vYmV0YS51a2RhdGFzZXJ2aWNlLmFjLnVrL2RhdGFjYXRhbG9ndWUvc3R1ZGllcy9zdHVkeT9pZD02NjYwKS4NCg0KV2Ugd2lsbCBiZSBmaXR0aW5nIGEgc2VyaWVzIG9mIHNjaG9vbCB2YWx1ZS1hZGRlZCBtb2RlbHMsIHdoaWNoIGFyZSBvbmUgb2YgdGhlIG1vc3QgcHJvbWluZW50IGV4YW1wbGVzIG9mIG11bHRpbGV2ZWwgbW9kZWxzIGFwcGxpZWQgaW4gZWR1Y2F0aW9uIHJlc2VhcmNoLg0KDQpBIHRyYWRpdGlvbmFsIHNjaG9vbCB2YWx1ZS1hZGRlZCBtb2RlbCBpcyBhIG1vZGVsIHRoYXQgYXR0ZW1wdHMgdG8gaXNvbGF0ZSB0aGUgInNjaG9vbCBlZmZlY3RzIiBmcm9tIHRoZSBpbmhlcmVudCB2YXJpYWJpbGl0eS9oZXRlcm9nZW5laXR5IG9mIHRoZSBwdXBpbHMuIEl0IGF0dGVtcHRzIHRvIGFzY2VydGFpbiB3aGF0IHNjaG9vbHMgYWRkIHRvIHRoZSBwcm9ncmVzcyBvZiB0aGVpciBwdXBpbHMgYmV5b25kIHdoYXQgaXMgZXhwZWN0ZWQgb2YgdGhlbSwgZ2l2ZW4gdGhlaXIgY2lyY3Vtc3RhbmNlcy4NCg0KPGJyPg0KDQoqKioNCg0KIyBUeXBpY2FsIHdvcmtmbG93IHNldHVwIGFuZCBkYXRhIHByZXBhcmF0aW9uDQoNCiMjIDEuMS4gRGVmaW5lIGEgd29ya2luZyBkaXJlY3RvcnkNCg0KWW91IGNhbiB1c2UgYW55IGRpcmVjdG9yeSBpbiB5b3VyIGNvbXB1dGVyLiBBcyBpbiB0aGUgZXhhbXBsZSBiZWxvdzoNCg0KYGBge3IsIGV2YWw9Rn0NCnNldHdkKCJDOi9teWZvbGRlciIpDQpgYGANCg0KUmVtZW1iZXIgdG8gZG93bmxvYWQgdGhlIGRhdGEgdG8gdGhlIGZvbGRlciB5b3Ugd2lsbCBkZWZpbmUgYXMgd29ya2luZyBkaXJlY3RvcnksIGFzIHRoaXMgbWFrZXMgbWF0dGVycyBlYXNpZXIuDQoNCiMjIDEuMi4gTG9hZCBwYWNrYWdlcw0KDQpZb3UgY2FuIGFsd2F5cyBsb2FkIHBhY2thZ2VzIGxhdGVyIG9uLCBidXQgaXQgaXMgYSBnb29kIHByYWN0aWNlIHRvIGxvYWQgcGFja2FnZXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2Vzc2lvbiBvbiB0aGUgdG9wIG9mIHlvdXIgc2NyaXB0IG9yIFIgbWFya2Rvd24gZmlsZS4NCg0KSW4gdGhpcyBwcmFjdGljYWwsIHdlIHdpbGwgdXNlIHRoZSBwYWNrYWdlcyBgaGF2ZW5gLCBgbG1lNGAgYW5kIGBnZ3Bsb3QyYC4gUmVtZW1iZXIgdGhhdCBpZiB5b3UgaGF2ZW4ndCBpbnN0YWxsZWQgdGhlbSBiZWZvcmUsIHlvdSBuZWVkIHRvIGRvIHNvIGJlZm9yZSB5b3UgY2FsbCB0aGUgYGxpYnJhcnlgIGZ1bmN0aW9uOg0KDQpgYGB7fQ0KaW5zdGFsbC5wYWNrYWdlcygiaGF2ZW4iKQ0KaW5zdGFsbC5wYWNrYWdlcygibG1lNCIpDQppbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCmBgYA0KDQpUaGVuIHlvdSBsb2FkIHRoZW0gYXMgc3VjaDoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KbGlicmFyeShoYXZlbikNCmxpYnJhcnkobG1lNCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KIyMgMS4zLiBSZWFkIGluIGRhdGEgDQoNCllvdSBjYW4gZG93bmxvYWQgdGhlIGRhdGEgZnJvbSAgdGhlIFsqKlVLRFMgd2Vic2l0ZSoqXShodHRwczovL2JldGEudWtkYXRhc2VydmljZS5hYy51ay9kYXRhY2F0YWxvZ3VlL3N0dWRpZXMvc3R1ZHk/aWQ9NjY2MCkuIFRoZXJlIGFyZSB0d28gU1BTUyBkYXRhc2V0cyBhbmQgd2Ugd2lsbCBiZSB1c2luZyB0aGUgb25lIG5hbWVkICJsc3lwZV8xNTAwMF9maW5hbF8yMDExXzA1XzA0LnNhdiIuDQoNCllvdSBjYW4gYWxzbyBkb3dubG9hZCB0aGUgZmlsZSBmcm9tIHRoZSBsaW5rIGJlbG93LCBidXQgdGhpcyBsaW5rIHdpbGwgc3RvcCB3b3JraW5nIGJ5IHRoZSBlbmQgb2YgdGhlIHNlc3Npb24sIHNvIG1ha2Ugc3VyZSB0byByZWdpc3RlciBhbmQgZG93bmxvYWQgdGhlIGRhdGEgZnJvbSB0aGUgVUtEUyBpZiB5b3Ugd2FudCB0byBjb250aW51ZSB3b3JraW5nIHdpdGggdGhpcyBkYXRhc2V0Lg0KDQpUbyByZWFkIHRoaXMgZGF0YXNldCBpbnRvIFIsIHdlIG5lZWQgdG8gdXNlIHRoZSBwYWNrYWdlIGBoYXZlbmA6DQoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KeXBlPC1yZWFkX3NhdigiaHR0cHM6Ly9naXRodWIuY29tL0EtbW9yYS9NTE1fc3VtbWVyLXNjaG9vbC9yYXcvbWFpbi9kYXRhL2xzeXBlXzE1MDAwX2ZpbmFsXzIwMTFfMDVfMDQuc2F2IikNCmBgYA0KDQo8YnI+DQoNCioqKg0KDQojIyBTZWxlY3QgdmFyaWFibGVzIHRvIHVzZQ0KDQpJbiBFbmdsYW5kIGFuZCBXYWxlcywgdGhlIERlcGFydG1lbnQgZm9yIEVkdWNhdGlvbiAoRGZFKSBwdWJsaXNoZXMgcGVyaW9kaWNhbGx5IHRoZSBzby1jYWxsZWQgcGVyZm9ybWFuY2UgdGFibGVzLCBpbiB3aGljaCBzY2hvb2xzIGFyZSBhc3Nlc3NlZCAoYW5kIGNsYXNzaWZpZWQpIGFjY29yZGluZyB0byB0aGUgcHJvZ3Jlc3MgdGhhdCB0aGVpciBwdXBpbHMgbWFrZSBmcm9tIG9uZSBzdGFnZSB0byBhbm90aGVyLiBTZWNvbmRhcnkgc2Nob29scyBhcmUganVkZ2VkIG9uIHRoZSBHQ1NFIHJlc3VsdHMgb2YgdGhlaXIgcHVwaWxzIGFuZCB0aGUgcHJvZ3Jlc3MgdGhleSBtYWRlIHNpbmNlIHRoZSBlbmQgb2YgcHJpbWFyeSwgd2hlbiB0aGV5IHNhdCB0aGUgS1MyIHRlc3RzLg0KDQpXZSB3aWxsIHNlbGVjdCB0aGUgdmFyaWFibGVzOiBwdXBpbGlkLCBzY2hvb2xJRCwga3Myc3RhbmQgKEtTMiBzY29yZXMpLCBrczRzdGFuZCAoR0NTRSBzY29yZXMpLCBnZW5kZXIsIGZzbSBhbmQgaW5kc2Nob29sLg0KDQpGb3IgdGhpcywgd2UgbmVlZCB0byB1c2UgdGhlIGZ1bmN0aW9uIGBzZWxlY3RgIG9mIHRoZSBgZHBseXJgIHBhY2thZ2U6DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KdmFsdWVhZGRlZCA8LSBzZWxlY3QoeXBlLCBwdXBpbGlkLCBzY2hvb2xJRCwgDQogICAgICAgICAgICAgICAgICAgICBrczJzdGFuZCwga3M0c3RhbmQsIGdlbmRlciwgDQogICAgICAgICAgICAgICAgICAgICBmc20pIA0KDQpgYGANCg0KPGJyPg0KDQoqKioNCg0KIyBUYXNrIDE6IFJlbGF0aW9uc2hpcCBiZXR3ZWVuIEtTMiBhbmQgR0NTRQ0KDQpQbG90IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBLUzIgYW5kIEdDU0Ugc2NvcmVzDQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KcGxvdDEgPC0gZ2dwbG90KHZhbHVlYWRkZWQsIGFlcyh4PWtzMnN0YW5kLCB5PWtzNHN0YW5kKSkgKw0KZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoYWVzKHg9a3Myc3RhbmQsIHk9a3M0c3RhbmQpLCBtZXRob2QgPSAibG0iKQ0KDQpwbG90MQ0KDQpgYGANCg0KIyMjIFF1ZXN0aW9uczoNCg0KMS4xIFdoYXQgY2FuIHlvdSBvYnNlcnZlIGluIHRoZSBwbG90Pw0KDQoqKkFuc3dlcjoqKiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gS1MyIGFuZCBHQ1NFIHNjb3JlcyBpcyBhcyBleHBlY3RlZDogaW4gZ2VuZXJhbCwgdGhlIGJldHRlciB0aGUgS1MyIHNjb3JlLCB0aGUgYmV0dGVyIHRoZSBHQ1NFIHNjb3JlLiBOZXZlcnRoZWxlc3MsIHRoZXJlIGlzIHBsZW50eSBvZiB2YXJpYWJpbGl0eS4NCg0KMS4yIEhvdyBjb3JyZWxhdGVkIGFyZSBLUzIgYW5kIEdDU0Ugc2NvcmVzPw0KDQoqKkFuc3dlcjoqKiBPYnRhaW4gdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gc2NvcmVzLiBUaGlzIGluZGljYXRlcyBhIG1vZGVyYXRlIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGFzIGhpbnRlZCBieSB0aGUgcHJldmlvdXMgcGxvdC4NCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KY29yKHZhbHVlYWRkZWQka3Myc3RhbmQsIHZhbHVlYWRkZWQka3M0c3RhbmQsIHVzZT0iY29tcCIpDQpgYGANCg0KPGJyPg0KDQoqKioNCg0KIyBUYXNrIDI6IFZhcmlhbmNlIGNvbXBvbmVudHMgKGVtcHR5KSBtb2RlbA0KDQpGaXQgYW4gZW1wdHkgbXVsdGlsZXZlbCBtb2RlbCBvZiBwdXBpbHMgd2l0aGluIHNjaG9vbHMNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KbGlicmFyeShsbWU0KQ0KYGBgDQoNCldlIHdpbGwgdXNlIHRoZSBgbG1lcmAgZnVuY3Rpb25zLCB3aGljaCBzdGFuZHMgZm9yICJsaW5lYXIgbWl4ZWQgZWZmZWN0cyByZWdyZXNzaW9uIi4NClRoZSBiYXNpYyBzeW50YXggZm9sbG93cyB0aGUgY29udmVudGlvbnMgb2YgbW9zdCBSIHBhY2thZ2VzIHJ1bm5pbmcgcmVncmVzc2lvbi4gWW91IHNwZWNpZnkgYW4gb3V0Y29tZSByZWdyZXNzZWQgYH5gIG9uIHZhcmlhYmxlcy4gRWFjaCB2YXJpYWJsZSB5b3UgYWRkIG5lZWRzIHRvIGJlIHByZWNlZGVkIGJ5IGEgYCtgIHNpZ24uIFlvdSBzcGVjaWZ5IHRoZSBkYXRhLg0KDQpOb3RlIHRoYXQgd2Ugd2lsbCB1c2UgTWF4aW11bSBMaWtlbGlob29kIChNTCksIG5vdCBSZXN0cmljdGVkIE1heGltdW0gTGlrZWxpaG9vZCAoUkVNTCkuIFJFTUwgaXMgdGhlIGRlZmF1bHQgaW4gbG1lciwgc28gd2UgbmVlZCB0byBzcGVjaWZ5IGBSRU1MID0gRkFMU0VgDQoNClJhbmRvbSBlZmZlY3RzIGFyZSBhZGRlZCB3aXRoaW4gYnJhY2tldHMgYWZ0ZXIgdGhlIGZpeGVkIGVmZmVjdHMuIGAxYCBpbmRpY2F0ZXMgdGhhdCB0aGUgY29uc3RhbnQgaXMgYWxsb3dlZCB0byB2YXJ5IGZyZWVseS4gVGhlIHJhbmRvbSBlZmZlY3RzIGFyZSBzcGVjaWZpZWQgbGlrZSB0aGlzOiBgKDF8bGV2ZWwyaWQpYC4gSWYgeW91IHdhbnQgdG8gd2FudCByYW5kb20gc2xvcGVzLCB5b3Ugc3BlY2lmeSBgKDEgKyB2YXJpYWJsZXxsZXZlbDJpZClgDQoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KDQptMCA8LSBsbWVyKGtzNHN0YW5kIH4gMSArICgxfHNjaG9vbElEKSwgZGF0YSA9IHZhbHVlYWRkZWQsIFJFTUwgPSBGKQ0KDQpzdW1tYXJ5KG0wKQ0KDQpgYGANCg0KVGhpcyBtb2RlbCBpcyBjYWxsZWQgInR5cGUgMCIgdmFsdWUtYWRkZWQgbW9kZWwgaW4gdGhlIGxpdGVyYXR1cmUNCg0KIyMjIFF1ZXN0aW9uDQoNCjIuMS4gV2hhdCBpcyB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYXRpb24gdGhhdCBsaWVzIGJldHdlZW4gc2Nob29scyBpbiB0aGUgZW1wdHkgbW9kZWw/DQoNCioqQW5zd2VyOioqIFlvdSBzaG91bGQgdXNlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb246DQoNCiQkVlBDID0gXGZyYWN7XHNpZ21hX3VeMn17XHNpZ21hX3VeMiArIFxzaWdtYV9lXjJ9JCQNCndoZXJlICRcc2lnbWFfdV4yJCBpcyB0aGUgdmFyaWFuY2UgYXQgdGhlIHNjaG9vbCBsZXZlbCBhbmQgJFxzaWdtYV9lXjIkIGlzIHRoZSB2YXJpYW5jZSBhdCB0aGUgcHVwaWwgbGV2ZWwuDQoNClJlcGxhY2luZyB0aGUgdmFsdWVzOg0KDQokJFZQQyA9IFxmcmFjezI0LjMzfXsyNC4zMyArIDc1Ljg1fSA9IDI0LjI4ICQkDQoNCjIuMi4gV2hhdCBkb2VzIHRoYXQgdmFsdWUgbWVhbj8NCg0KKipBbnN3ZXI6KiogQXBwcm94aW1hdGVseSAyNCUgb2YgdGhlIHRvdGFsIHZhcmlhbmNlIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIGRpZmZlcmVuY2VzIGJldHdlZW4gc2Nob29scy4NCg0KPGJyPg0KDQojIFRhc2sgMzogSXMgdGhlIE1MTSBiZXR0ZXIgdGhhbiBhIHNpbmdsZS1sZXZlbCBtb2RlbD8NCg0KVG8gYXNzZXNzIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIE1MTSwgd2UgbmVlZCB0byBjb21wYXJlIGl0IHRvIGEgc2luZ2xlLWxldmVsIG1vZGVsLiBUbyBmaXQgYSBzaW5nbGUtbGV2ZWwgbW9kZWwsIHdlIHR5cGU6DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0Kc2luZ2xlIDwtIGxtKGtzNHN0YW5kIH4gMSAsIGRhdGEgPSB2YWx1ZWFkZGVkKQ0KDQpzdW1tYXJ5KHNpbmdsZSkNCg0KYGBgDQoNClRoZXNlIHJlc3VsdHMgYXJlIG5vdCB2ZXJ5IGludGVyZXN0aW5nIGluIHRoZW1zZWx2ZXMsIHNvIHdlIG1vdmUgb24gZXh0cmFjdCB0aGUgbG9nbGlrZWxpaG9vZCBhbmQgY29tcGFyZSB0byB0aGUgTUxNLg0KDQpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUZ9DQoNCkwxIDwtIGFzLm51bWVyaWMobG9nTGlrKHNpbmdsZSkpICMgc3RvcmUgdGhpcyBhcyBudW1lcmljYWwgdG8gcmUtdXNlDQpMMiA8LSBhcy5udW1lcmljKGxvZ0xpayhtMCkpDQoNCihEIDwtIDIqKEwyLUwxKSkgIyB0aGlzIGlzIHRoZSBkZXZpYW5jZSwgd2UgcHV0IGl0IHdpdGhpbiBicmFja2V0cyB0byBwcmludCBpdCBpbW1lZGlhdGVseQ0KDQpwY2hpc3EocT1ELCBkZj0xLCBsb3dlci50YWlsPUYpICMgVG8gZmluZCB0aGUgcC12YWx1ZQ0KDQpgYGANCg0KIyMjIFF1ZXN0aW9uDQoNCjMuMS4gSXMgdGhlIGFkZGl0aW9uIG9mIHRoZSBzY2hvb2wgbGV2ZWwgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudD8NCg0KKipBbnN3ZXI6KiogWWVzIGl0IGlzISBFdmVuIGlmIHlvdSBoYWRuJ3QgZG9uZSB0aGUgbG9nbGlrZWxpaG9vZCB0ZXN0LCB0aGUgVlBDIG9mIDI0JSBpcyBzdHJvbmcgZXZpZGVuY2Ugb2YgdGhlIHJlbGV2YW5jZSBvZiBzY2hvb2wgZWZmZWN0cy4NCg0KMy4yLiBXaGF0IGRvZXMgdGhpcyBtZWFuIGluIHByYWN0aWNlPw0KDQoqKkFuc3dlcjoqKiBJdCBtZWFucyB0aGF0IGl0IGlzIGV4dHJlbWVseSBpbXBvcnRhbnQgdG8gY29udHJvbCBmb3IgdGhlIHJhdGhlciBsYXJnZSB2YXJpYWJpbGl0eSBiZXR3ZWVuIHNjaG9vbHMgaW4geW91ciBtb2RlbHMuDQoNCioqKg==