Summary
This notebook simulates the estimated yearly learning gains and
yearly payment for a single IP. I first use the draft evaluation design
and other inputs to simulate the outcome of each data collection round.
I then use these simulated data to simulate yearly payments based on a
simple payment formula.
We have opted to use a simulation approach rather than a typical
power calculation approach as the a) typical power calculations are
focused on ensuring results will be found statistically significant
which is not a concern here, b) typical power calculations don’t account
for the effect of payment formulas, and c) it would be difficult to
account for the intricacies of the complicated yearly evaluation design
using power calculations.
Overall, we find that the current evaluation design (and most
plausible evaluation designs which measure yearly marginal impact on
learning) leads to extremely high expected payments. On
average, investors would be paid 5x what they should be paid. The high
expected payment is due to the high uncertainty of yearly estimated
learning gains and the implicit minimum payment of 0. (We assume that
investors won’t be required to ever pay the outcome payers.)
We also find that payments are extremely variable.
For example, there is a 7.1% chance that payment will be 10x what they
should be paid.
Changes to the evaluation design and payment formula matter
have much greater impact on expected payments than minor changes to
targets. A final takeaway from these simulations is that the
design
To fix these issues, we recommend instead using a
cohort-based evaluation design which does not seek to measure marginal
yearly impact on learning. At the end of this page, we
reproduce the simulations using an alternate evaluation design which
still produces annual estimates
Alternatively, shifting to an overall, rather than yearly,
evaluation approach would both significantly reduce cost while also
increasing evaluation precision. This would also allow DIB
partners to focus less on technical issues and more on overall targets.
As these simulations show, if using an annual payment formula DIB
partners need to understand the sampling error of estimates, correlation
of estimates across payment rounds, and the interaction of these things
with the payment formula or else they likely will be very surprised the
results. Shifting to an overall evaluation approach would mean that DIB
partners would not need to understand these detailed technical
issues.
Current Evaluation Design
The table below shows the current draft evaluation design.

Simulation Approach and Inputs
To simulate yearly estimated learning gains and yearly payments, I
first simulate each year + grade data collection point (i.e. each cell
in the evaluation design figure above) using the hypothesized true
effect and the estimated variance of the measured effect.
For example, the red cell in the figure above represents the
different in mean learning levels between treatment and control schools
for year 2, grade 2 students \(\Delta
\bar{y}_{g2,y2}\). If we believe that the true effect of the
intervention over 2 years is T and the standard error of this
measurement is se and assume our estimate is normally distributed then
our estimate of this quantity has the distribution
\[\widehat{\Delta \bar{y}_{g2,y2}} \sim
N(T, se)\]
We can then simulate estimated learning gains and payments by drawing
multiple values from the distribution of measured learning gains for
each year + grade data collection round.
True Effect Sizes and Targets by Year
I assume that the true effect sizes vary by grade but not by
year.
- .15 in grade 1
- .05 in grade 2
- .025 in grade 3
I assume that the targets are based on the true effects. This means
that the targets by year (assuming equal sample from each grade)
are:
- Year 1 target = (.15+.025)/2=.0875
- Years 2, and 3 target = (.15+.05)/2=.1
- Year 4 target =(.05+.025)/2=0.0375
Accounting for Measurement Sampling Error
If we take a random sample of J schools with K students per school to
estimate mean learning levels y, then the variance of the estimate of
the mean (i.e. the square of the standard error) of y is:
\[ V(\bar{y}) = SE^2=
\sigma_y^2\left(\frac{\rho}{J}+\frac{(1-\rho)}{JK}\right)=\sigma_y^2*(A+B)
\] Where \(\sigma_y\) is the
variance of the outcome variable and \(\rho\) is intra-class correlation
(ICC).
For each grade + year data collection point, we calculate
\[
\Delta \bar{y}=\bar{y}_{treat}-\bar{y}_{control}
\]
Since we sample schools in treatment and control independently, the
two terms on the right are independent of each other and thus the
variance of their difference is just the sum of their variances.
Since we are calculating the standard error of standard effect sizes,
we take \(\sigma\) to be 1. In
addition, when estimating effects, we will use covariates to reduce
variance. After setting \(\sigma\) to
1, taking into account the effects of covariates our variance is
\[ V(\Delta \bar{y}) =
2A(1-R_J^2)+2B(1-R_K^2) \]
Where:
- \(R_J^2\) is the R squared from a
regression of the outcome on the school-level covariates (e.g. UDISE
information). I use .2 in the calculations below but this is just a
guess.
- \(R_K^2\) is the R squared from a
regression of the outcome on the student-level covariates. I use .2 in
the calculations below but this is just a guess.
In addition, while beginning of year grade + year data collection
points are all independent since schools are resampled, data collection
points at the end of year are correlated across grades since data
collection will happen at the same schools for two grades. We account
for this by drawing from a multivariate normal distribution with a
correlation of .5 across grades. (Note that the estimate of the
correlation is based on my intuition as estimating this would require
detailed analysis of a dataset with multiple years of learning
levels.)
Calculations
library(MASS)
# sampling inputs
J <- 65 # Number of schools per arm
K <- 25 # Number of students per school
rho <- 0.15
rsj <- .2
rsk <- .2
rsl <- .63
corr <- .5
Sigma <- matrix(c(1,corr, corr, 1), ncol = 2)
# variance calculations
A <- rho/J
B <- (1-rho)/(J*K)
var <- 2*A*(1-rsj)+2*B*(1-rsk)
se = var^.5
# Effect size and target inputs
effect_year1 = .15
effect_year2 = .05
effect_year3 = .025
target_year1 = .0875
target_year2 = .1
target_year3 = .0375
# Simulations
# note that g2y0e indicates that the draw is for grade 2, year 0, end of year
num_sims <- 100000
# year 0
g2y0e <- rnorm(n = num_sims, mean = .2, sd = se)
# year 1
g1y1b <- rnorm(n = num_sims, mean = 0, sd = se)
y1e <- mvrnorm(n = num_sims, mu = c(.225, .15), Sigma = Sigma)
g3y1e <- y1e[,1]
g1y1e <- y1e[,2]
# year 2
g1y2b <- rnorm(n = num_sims, mean = 0, sd = se)
y2e <- mvrnorm(n = num_sims, mu = c(.2, .15), Sigma = Sigma)
g2y2e <- y2e[,1]
g1y2e <- y2e[,2]
# year 3
g1y3b <- rnorm(n = num_sims, mean = 0, sd = se)
y3e <- mvrnorm(n = num_sims, mu = c(.2, .15), Sigma = Sigma)
g2y3e <- y3e[,1]
g1y3e <- y3e[,2]
# year 4
y4e <- mvrnorm(n = num_sims, mu = c(.225, .2), Sigma = Sigma)
g3y4e <- y4e[,1]
g2y4e <- y4e[,2]
# Payment calculation
est_effect_y1 <- ((g3y1e-g2y0e)+(g1y1e-g1y1b))/2
est_effect_y2 <- ((g2y2e-g1y1e)+(g1y2e-g1y2b))/2
est_effect_y3 <- ((g2y3e-g1y2e)+(g1y3e-g1y3b))/2
est_effect_y4 <- ((g3y4e-g2y4e)+(g2y4e-g1y3e))/2
# Check that mean estimated effect is similar to targets
print("Mean estimated effect y1 vs target of .0875:")
[1] "Mean estimated effect y1 vs target of .0875:"
round(mean(est_effect_y1),4)
[1] 0.0898
print("Mean estimated effect y2 vs target of .1:")
[1] "Mean estimated effect y2 vs target of .1:"
round(mean(est_effect_y2),4)
[1] 0.1008
print("Mean estimated effect y3 vs target of .1:")
[1] "Mean estimated effect y3 vs target of .1:"
round(mean(est_effect_y3),4)
[1] 0.1001
print("Mean estimated effect y4 vs target of .0375:")
[1] "Mean estimated effect y4 vs target of .0375:"
round(mean(est_effect_y4),4)
[1] 0.0384
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
-- Attaching packages -------------------------------------------------------------- tidyverse 1.3.1 --
√ ggplot2 3.3.5 √ purrr 0.3.4
√ tibble 3.1.6 √ dplyr 1.0.8
√ tidyr 1.2.0 √ stringr 1.4.0
√ readr 2.0.2 √ forcats 0.5.1
Warning: package ‘tibble’ was built under R version 4.1.2
Warning: package ‘tidyr’ was built under R version 4.1.2
Warning: package ‘dplyr’ was built under R version 4.1.2
-- Conflicts ----------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag() masks stats::lag()
x dplyr::select() masks MASS::select()
# Calculate payment assuming minimum payment of 0
payment_y1 <- pmax(0, est_effect_y1/(4*.0875))
payment_y2 <- pmax(0, est_effect_y2/(4*.1))
payment_y3 <- pmax(0, est_effect_y3/(4*.1))
payment_y4 <- pmax(0, est_effect_y4/(4*.0375))
total_payment = payment_y1+payment_y2+payment_y3+payment_y4
mean(total_payment)
[1] 5.39108
# histogram of total payment
ggplot(tibble(p = total_payment), aes(x = p)) +
geom_histogram(binwidth = .2) +
geom_vline(xintercept = 1, color = "red")+
labs(x = "Total Payment", y = "Frequency", caption = "Red line indicates what the investors should be paid", title = "Expected Payment w/ Current Evaluation Design")

# For completeness, calculate expected payment
payment_y1_nomin <- est_effect_y1/(4*.0875)
payment_y2_nomin <- est_effect_y2/(4*.1)
payment_y3_nomin <- est_effect_y3/(4*.1)
payment_y4_nomin <- est_effect_y4/(4*.0375)
total_payment_nomin = payment_y1_nomin+payment_y2_nomin+payment_y3_nomin+payment_y4_nomin
mean(total_payment_nomin)
[1] 1.014725
# histogram of total payment
ggplot(tibble(p = total_payment_nomin), aes(x = p)) +
geom_histogram(binwidth = .2) +
geom_vline(xintercept = 1, color = "red")+
labs(x = "Total Payment", y = "Frequency", title = "Expected Payment with Potential Negative Payments", caption = "Red line indicates what the investors should be paid")

Alternate Evaluation Design
The code below simulates measured learning gains and payments using
the same assumptions but with a slightly different, cohort-based
evaluation design.

# first cohort
g1y0b <- rnorm(n = num_sims, mean = 0, sd = se)
g2y1e <- rnorm(n = num_sims, mean = .2, sd = se)
est_effect_c1 <- g2y1e-g1y0b
# second cohort
g1y1b <- rnorm(n = num_sims, mean = 0, sd = se)
g2y2e <- rnorm(n = num_sims, mean = .2, sd = se)
est_effect_c2 <- g2y2e-g1y1b
# third cohort
g1y2b <- rnorm(n = num_sims, mean = 0, sd = se)
g2y3e <- rnorm(n = num_sims, mean = .2, sd = se)
est_effect_c3 <- g2y3e-g1y2b
# fourth cohort
g1y3b <- rnorm(n = num_sims, mean = 0, sd = se)
g2y4e <- rnorm(n = num_sims, mean = .2, sd = se)
est_effect_c4 <- g2y4e-g1y3b
payment_y1 <- pmax(0, est_effect_c1/.8)
payment_y2 <- pmax(0, est_effect_c2/.8)
payment_y3 <- pmax(0, est_effect_c3/.8)
payment_y4 <- pmax(0, est_effect_c4/.8)
total_payment = payment_y1+payment_y2+payment_y3+payment_y4
mean(total_payment)
[1] 1.003594
# histogram of total payment
ggplot(tibble(p = total_payment), aes(x = p)) +
geom_histogram(binwidth = .02) +
geom_vline(xintercept = 1, color = "red")+
labs(x = "Total Payment", y = "Frequency")

# For completeness, calculate expected payment with no minimum
payment_y1_nomin <- est_effect_c1/.8
payment_y2_nomin <- est_effect_c2/.8
payment_y3_nomin <- est_effect_c3/.8
payment_y4_nomin <- est_effect_c4/.8
total_payment_nomin = payment_y1_nomin+payment_y2_nomin+payment_y3_nomin+payment_y4_nomin
mean(total_payment_nomin)
[1] 1.000516
# histogram of total payment
ggplot(tibble(p = total_payment_nomin), aes(x = p)) +
geom_histogram(binwidth = .02) +
geom_vline(xintercept = 1, color = "red")+
labs(x = "Total Payment", y = "Frequency", title = "Expected Payment with Potential Negative Payments")

NA
NA
LS0tDQp0aXRsZTogIkIyU09GIFNhbXBsZSBTaW11bGF0aW9ucyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMgU3VtbWFyeQ0KDQpUaGlzIG5vdGVib29rIHNpbXVsYXRlcyB0aGUgZXN0aW1hdGVkIHllYXJseSBsZWFybmluZyBnYWlucyBhbmQgeWVhcmx5IHBheW1lbnQgZm9yIGEgc2luZ2xlIElQLiBJIGZpcnN0IHVzZSB0aGUgZHJhZnQgZXZhbHVhdGlvbiBkZXNpZ24gYW5kIG90aGVyIGlucHV0cyB0byBzaW11bGF0ZSB0aGUgb3V0Y29tZSBvZiBlYWNoIGRhdGEgY29sbGVjdGlvbiByb3VuZC4gSSB0aGVuIHVzZSB0aGVzZSBzaW11bGF0ZWQgZGF0YSB0byBzaW11bGF0ZSB5ZWFybHkgcGF5bWVudHMgYmFzZWQgb24gYSBzaW1wbGUgcGF5bWVudCBmb3JtdWxhLg0KDQpXZSBoYXZlIG9wdGVkIHRvIHVzZSBhIHNpbXVsYXRpb24gYXBwcm9hY2ggcmF0aGVyIHRoYW4gYSB0eXBpY2FsIHBvd2VyIGNhbGN1bGF0aW9uIGFwcHJvYWNoIGFzIHRoZSBhKSB0eXBpY2FsIHBvd2VyIGNhbGN1bGF0aW9ucyBhcmUgZm9jdXNlZCBvbiBlbnN1cmluZyByZXN1bHRzIHdpbGwgYmUgZm91bmQgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCB3aGljaCBpcyBub3QgYSBjb25jZXJuIGhlcmUsIGIpIHR5cGljYWwgcG93ZXIgY2FsY3VsYXRpb25zIGRvbid0IGFjY291bnQgZm9yIHRoZSBlZmZlY3Qgb2YgcGF5bWVudCBmb3JtdWxhcywgYW5kIGMpIGl0IHdvdWxkIGJlIGRpZmZpY3VsdCB0byBhY2NvdW50IGZvciB0aGUgaW50cmljYWNpZXMgb2YgdGhlIGNvbXBsaWNhdGVkIHllYXJseSBldmFsdWF0aW9uIGRlc2lnbiB1c2luZyBwb3dlciBjYWxjdWxhdGlvbnMuDQoNCioqT3ZlcmFsbCwgd2UgZmluZCB0aGF0IHRoZSBjdXJyZW50IGV2YWx1YXRpb24gZGVzaWduIChhbmQgbW9zdCBwbGF1c2libGUgZXZhbHVhdGlvbiBkZXNpZ25zIHdoaWNoIG1lYXN1cmUgeWVhcmx5IG1hcmdpbmFsIGltcGFjdCBvbiBsZWFybmluZykgbGVhZHMgdG8gZXh0cmVtZWx5IGhpZ2ggZXhwZWN0ZWQgcGF5bWVudHMuKiogT24gYXZlcmFnZSwgaW52ZXN0b3JzIHdvdWxkIGJlIHBhaWQgNXggd2hhdCB0aGV5IHNob3VsZCBiZSBwYWlkLiBUaGUgaGlnaCBleHBlY3RlZCBwYXltZW50IGlzIGR1ZSB0byB0aGUgaGlnaCB1bmNlcnRhaW50eSBvZiB5ZWFybHkgZXN0aW1hdGVkIGxlYXJuaW5nIGdhaW5zIGFuZCB0aGUgaW1wbGljaXQgbWluaW11bSBwYXltZW50IG9mIDAuIChXZSBhc3N1bWUgdGhhdCBpbnZlc3RvcnMgd29uJ3QgYmUgcmVxdWlyZWQgdG8gZXZlciBwYXkgdGhlIG91dGNvbWUgcGF5ZXJzLikNCg0KKipXZSBhbHNvIGZpbmQgdGhhdCBwYXltZW50cyBhcmUgZXh0cmVtZWx5IHZhcmlhYmxlKiouIEZvciBleGFtcGxlLCB0aGVyZSBpcyBhIDcuMSUgY2hhbmNlIHRoYXQgcGF5bWVudCB3aWxsIGJlIDEweCB3aGF0IHRoZXkgc2hvdWxkIGJlIHBhaWQuDQoNCioqQ2hhbmdlcyB0byB0aGUgZXZhbHVhdGlvbiBkZXNpZ24gYW5kIHBheW1lbnQgZm9ybXVsYSBtYXR0ZXIgaGF2ZSBtdWNoIGdyZWF0ZXIgaW1wYWN0IG9uIGV4cGVjdGVkIHBheW1lbnRzIHRoYW4gbWlub3IgY2hhbmdlcyB0byB0YXJnZXRzKiouIEEgZmluYWwgdGFrZWF3YXkgZnJvbSB0aGVzZSBzaW11bGF0aW9ucyBpcyB0aGF0IHRoZSBkZXNpZ24NCg0KKipUbyBmaXggdGhlc2UgaXNzdWVzLCB3ZSByZWNvbW1lbmQgaW5zdGVhZCB1c2luZyBhIGNvaG9ydC1iYXNlZCBldmFsdWF0aW9uIGRlc2lnbiB3aGljaCBkb2VzIG5vdCBzZWVrIHRvIG1lYXN1cmUgbWFyZ2luYWwgeWVhcmx5IGltcGFjdCBvbiBsZWFybmluZyoqLiBBdCB0aGUgZW5kIG9mIHRoaXMgcGFnZSwgd2UgcmVwcm9kdWNlIHRoZSBzaW11bGF0aW9ucyB1c2luZyBhbiBhbHRlcm5hdGUgZXZhbHVhdGlvbiBkZXNpZ24gd2hpY2ggc3RpbGwgcHJvZHVjZXMgYW5udWFsIGVzdGltYXRlcw0KDQoqKkFsdGVybmF0aXZlbHksIHNoaWZ0aW5nIHRvIGFuIG92ZXJhbGwsIHJhdGhlciB0aGFuIHllYXJseSwgZXZhbHVhdGlvbiBhcHByb2FjaCB3b3VsZCBib3RoIHNpZ25pZmljYW50bHkgcmVkdWNlIGNvc3Qgd2hpbGUgYWxzbyBpbmNyZWFzaW5nIGV2YWx1YXRpb24gcHJlY2lzaW9uKiouIFRoaXMgd291bGQgYWxzbyBhbGxvdyBESUIgcGFydG5lcnMgdG8gZm9jdXMgbGVzcyBvbiB0ZWNobmljYWwgaXNzdWVzIGFuZCBtb3JlIG9uIG92ZXJhbGwgdGFyZ2V0cy4gQXMgdGhlc2Ugc2ltdWxhdGlvbnMgc2hvdywgaWYgdXNpbmcgYW4gYW5udWFsIHBheW1lbnQgZm9ybXVsYSBESUIgcGFydG5lcnMgbmVlZCB0byB1bmRlcnN0YW5kIHRoZSBzYW1wbGluZyBlcnJvciBvZiBlc3RpbWF0ZXMsIGNvcnJlbGF0aW9uIG9mIGVzdGltYXRlcyBhY3Jvc3MgcGF5bWVudCByb3VuZHMsIGFuZCB0aGUgaW50ZXJhY3Rpb24gb2YgdGhlc2UgdGhpbmdzIHdpdGggdGhlIHBheW1lbnQgZm9ybXVsYSBvciBlbHNlIHRoZXkgbGlrZWx5IHdpbGwgYmUgdmVyeSBzdXJwcmlzZWQgdGhlIHJlc3VsdHMuIFNoaWZ0aW5nIHRvIGFuIG92ZXJhbGwgZXZhbHVhdGlvbiBhcHByb2FjaCB3b3VsZCBtZWFuIHRoYXQgRElCIHBhcnRuZXJzIHdvdWxkIG5vdCBuZWVkIHRvIHVuZGVyc3RhbmQgdGhlc2UgZGV0YWlsZWQgdGVjaG5pY2FsIGlzc3Vlcy4NCg0KIyBDdXJyZW50IEV2YWx1YXRpb24gRGVzaWduDQoNClRoZSB0YWJsZSBiZWxvdyBzaG93cyB0aGUgY3VycmVudCBkcmFmdCBldmFsdWF0aW9uIGRlc2lnbi4NCg0KIVtdKGltYWdlcy9wYXN0ZS0wQTA3QTFCQS5wbmcpDQoNCiMgU2ltdWxhdGlvbiBBcHByb2FjaCBhbmQgSW5wdXRzDQoNClRvIHNpbXVsYXRlIHllYXJseSBlc3RpbWF0ZWQgbGVhcm5pbmcgZ2FpbnMgYW5kIHllYXJseSBwYXltZW50cywgSSBmaXJzdCBzaW11bGF0ZSBlYWNoIHllYXIgKyBncmFkZSBkYXRhIGNvbGxlY3Rpb24gcG9pbnQgKGkuZS4gZWFjaCBjZWxsIGluIHRoZSBldmFsdWF0aW9uIGRlc2lnbiBmaWd1cmUgYWJvdmUpIHVzaW5nIHRoZSBoeXBvdGhlc2l6ZWQgdHJ1ZSBlZmZlY3QgYW5kIHRoZSBlc3RpbWF0ZWQgdmFyaWFuY2Ugb2YgdGhlIG1lYXN1cmVkIGVmZmVjdC4NCg0KRm9yIGV4YW1wbGUsIHRoZSByZWQgY2VsbCBpbiB0aGUgZmlndXJlIGFib3ZlIHJlcHJlc2VudHMgdGhlIGRpZmZlcmVudCBpbiBtZWFuIGxlYXJuaW5nIGxldmVscyBiZXR3ZWVuIHRyZWF0bWVudCBhbmQgY29udHJvbCBzY2hvb2xzIGZvciB5ZWFyIDIsIGdyYWRlIDIgc3R1ZGVudHMgJFxEZWx0YSBcYmFye3l9X3tnMix5Mn0kLiBJZiB3ZSBiZWxpZXZlIHRoYXQgdGhlIHRydWUgZWZmZWN0IG9mIHRoZSBpbnRlcnZlbnRpb24gb3ZlciAyIHllYXJzIGlzIFQgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGlzIG1lYXN1cmVtZW50IGlzIHNlIGFuZCBhc3N1bWUgb3VyIGVzdGltYXRlIGlzIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHRoZW4gb3VyIGVzdGltYXRlIG9mIHRoaXMgcXVhbnRpdHkgaGFzIHRoZSBkaXN0cmlidXRpb24NCg0KJCRcd2lkZWhhdHtcRGVsdGEgXGJhcnt5fV97ZzIseTJ9fSBcc2ltIE4oVCwgc2UpJCQNCg0KV2UgY2FuIHRoZW4gc2ltdWxhdGUgZXN0aW1hdGVkIGxlYXJuaW5nIGdhaW5zIGFuZCBwYXltZW50cyBieSBkcmF3aW5nIG11bHRpcGxlIHZhbHVlcyBmcm9tIHRoZSBkaXN0cmlidXRpb24gb2YgbWVhc3VyZWQgbGVhcm5pbmcgZ2FpbnMgZm9yIGVhY2ggeWVhciArIGdyYWRlIGRhdGEgY29sbGVjdGlvbiByb3VuZC4NCg0KIyMgVHJ1ZSBFZmZlY3QgU2l6ZXMgYW5kIFRhcmdldHMgYnkgWWVhcg0KDQpJIGFzc3VtZSB0aGF0IHRoZSB0cnVlIGVmZmVjdCBzaXplcyB2YXJ5IGJ5IGdyYWRlIGJ1dCBub3QgYnkgeWVhci4NCg0KLSAgIC4xNSBpbiBncmFkZSAxDQotICAgLjA1IGluIGdyYWRlIDINCi0gICAuMDI1IGluIGdyYWRlIDMNCg0KSSBhc3N1bWUgdGhhdCB0aGUgdGFyZ2V0cyBhcmUgYmFzZWQgb24gdGhlIHRydWUgZWZmZWN0cy4gVGhpcyBtZWFucyB0aGF0IHRoZSB0YXJnZXRzIGJ5IHllYXIgKGFzc3VtaW5nIGVxdWFsIHNhbXBsZSBmcm9tIGVhY2ggZ3JhZGUpIGFyZToNCg0KLSAgIFllYXIgMSB0YXJnZXQgPSAoLjE1Ky4wMjUpLzI9LjA4NzUNCi0gICBZZWFycyAyLCBhbmQgMyB0YXJnZXQgPSAoLjE1Ky4wNSkvMj0uMQ0KLSAgIFllYXIgNCB0YXJnZXQgPSguMDUrLjAyNSkvMj0wLjAzNzUNCg0KIyMgUGF5bWVudCBGb3JtdWxhDQoNCkkgYXNzdW1lIHBheW1lbnQgPSBlc3RpbWF0ZWQgZWZmZWN0IC8gKDRcKnRhcmdldCkgd2l0aCBhIG1pbmltdW0gb2YgMC4gU28gaWYgdGhlIGVzdGltYXRlZCBlZmZlY3QgaXMgZXF1YWwgdG8gdGhlIHRhcmdldCBpbiBhbGwgNCB5ZWFycywgdGhlIHBheW1lbnQgaXMgMS4NCg0KIyMgQWNjb3VudGluZyBmb3IgTWVhc3VyZW1lbnQgU2FtcGxpbmcgRXJyb3INCg0KSWYgd2UgdGFrZSBhIHJhbmRvbSBzYW1wbGUgb2YgSiBzY2hvb2xzIHdpdGggSyBzdHVkZW50cyBwZXIgc2Nob29sIHRvIGVzdGltYXRlIG1lYW4gbGVhcm5pbmcgbGV2ZWxzIHksIHRoZW4gdGhlIHZhcmlhbmNlIG9mIHRoZSBlc3RpbWF0ZSBvZiB0aGUgbWVhbiAoaS5lLiB0aGUgc3F1YXJlIG9mIHRoZSBzdGFuZGFyZCBlcnJvcikgb2YgeSBpczoNCg0KJCQgVihcYmFye3l9KSA9IFNFXjI9IFxzaWdtYV95XjJcbGVmdChcZnJhY3tccmhvfXtKfStcZnJhY3soMS1ccmhvKX17Skt9XHJpZ2h0KT1cc2lnbWFfeV4yKihBK0IpICQkIFdoZXJlICRcc2lnbWFfeSQgaXMgdGhlIHZhcmlhbmNlIG9mIHRoZSBvdXRjb21lIHZhcmlhYmxlIGFuZCAkXHJobyQgaXMgaW50cmEtY2xhc3MgY29ycmVsYXRpb24gKElDQykuDQoNCkZvciBlYWNoIGdyYWRlICsgeWVhciBkYXRhIGNvbGxlY3Rpb24gcG9pbnQsIHdlIGNhbGN1bGF0ZQ0KDQokJA0KXERlbHRhIFxiYXJ7eX09XGJhcnt5fV97dHJlYXR9LVxiYXJ7eX1fe2NvbnRyb2x9DQokJA0KDQpTaW5jZSB3ZSBzYW1wbGUgc2Nob29scyBpbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgaW5kZXBlbmRlbnRseSwgdGhlIHR3byB0ZXJtcyBvbiB0aGUgcmlnaHQgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIgYW5kIHRodXMgdGhlIHZhcmlhbmNlIG9mIHRoZWlyIGRpZmZlcmVuY2UgaXMganVzdCB0aGUgc3VtIG9mIHRoZWlyIHZhcmlhbmNlcy4NCg0KU2luY2Ugd2UgYXJlIGNhbGN1bGF0aW5nIHRoZSBzdGFuZGFyZCBlcnJvciBvZiBzdGFuZGFyZCBlZmZlY3Qgc2l6ZXMsIHdlIHRha2UgJFxzaWdtYSQgdG8gYmUgMS4gSW4gYWRkaXRpb24sIHdoZW4gZXN0aW1hdGluZyBlZmZlY3RzLCB3ZSB3aWxsIHVzZSBjb3ZhcmlhdGVzIHRvIHJlZHVjZSB2YXJpYW5jZS4gQWZ0ZXIgc2V0dGluZyAkXHNpZ21hJCB0byAxLCB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBlZmZlY3RzIG9mIGNvdmFyaWF0ZXMgb3VyIHZhcmlhbmNlIGlzDQoNCiQkIFYoXERlbHRhIFxiYXJ7eX0pID0gMkEoMS1SX0peMikrMkIoMS1SX0teMikgJCQNCg0KV2hlcmU6DQoNCjEuICAkUl9KXjIkIGlzIHRoZSBSIHNxdWFyZWQgZnJvbSBhIHJlZ3Jlc3Npb24gb2YgdGhlIG91dGNvbWUgb24gdGhlIHNjaG9vbC1sZXZlbCBjb3ZhcmlhdGVzIChlLmcuIFVESVNFIGluZm9ybWF0aW9uKS4gSSB1c2UgLjIgaW4gdGhlIGNhbGN1bGF0aW9ucyBiZWxvdyBidXQgdGhpcyBpcyBqdXN0IGEgZ3Vlc3MuDQoyLiAgJFJfS14yJCBpcyB0aGUgUiBzcXVhcmVkIGZyb20gYSByZWdyZXNzaW9uIG9mIHRoZSBvdXRjb21lIG9uIHRoZSBzdHVkZW50LWxldmVsIGNvdmFyaWF0ZXMuIEkgdXNlIC4yIGluIHRoZSBjYWxjdWxhdGlvbnMgYmVsb3cgYnV0IHRoaXMgaXMganVzdCBhIGd1ZXNzLg0KDQpJbiBhZGRpdGlvbiwgd2hpbGUgYmVnaW5uaW5nIG9mIHllYXIgZ3JhZGUgKyB5ZWFyIGRhdGEgY29sbGVjdGlvbiBwb2ludHMgYXJlIGFsbCBpbmRlcGVuZGVudCBzaW5jZSBzY2hvb2xzIGFyZSByZXNhbXBsZWQsIGRhdGEgY29sbGVjdGlvbiBwb2ludHMgYXQgdGhlIGVuZCBvZiB5ZWFyIGFyZSBjb3JyZWxhdGVkIGFjcm9zcyBncmFkZXMgc2luY2UgZGF0YSBjb2xsZWN0aW9uIHdpbGwgaGFwcGVuIGF0IHRoZSBzYW1lIHNjaG9vbHMgZm9yIHR3byBncmFkZXMuIFdlIGFjY291bnQgZm9yIHRoaXMgYnkgZHJhd2luZyBmcm9tIGEgbXVsdGl2YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBhIGNvcnJlbGF0aW9uIG9mIC41IGFjcm9zcyBncmFkZXMuIChOb3RlIHRoYXQgdGhlIGVzdGltYXRlIG9mIHRoZSBjb3JyZWxhdGlvbiBpcyBiYXNlZCBvbiBteSBpbnR1aXRpb24gYXMgZXN0aW1hdGluZyB0aGlzIHdvdWxkIHJlcXVpcmUgZGV0YWlsZWQgYW5hbHlzaXMgb2YgYSBkYXRhc2V0IHdpdGggbXVsdGlwbGUgeWVhcnMgb2YgbGVhcm5pbmcgbGV2ZWxzLikNCg0KIyBDYWxjdWxhdGlvbnMNCg0KYGBge3J9DQpsaWJyYXJ5KE1BU1MpDQoNCiMgc2FtcGxpbmcgaW5wdXRzDQpKIDwtIDY1ICMgTnVtYmVyIG9mIHNjaG9vbHMgcGVyIGFybQ0KSyA8LSAyNSAjIE51bWJlciBvZiBzdHVkZW50cyBwZXIgc2Nob29sDQpyaG8gPC0gMC4xNSANCnJzaiA8LSAuMg0KcnNrIDwtIC4yDQpyc2wgPC0gLjYzDQpjb3JyIDwtIC41DQpTaWdtYSA8LSBtYXRyaXgoYygxLGNvcnIsIGNvcnIsIDEpLCBuY29sID0gMikNCg0KIyB2YXJpYW5jZSBjYWxjdWxhdGlvbnMNCkEgPC0gcmhvL0oNCkIgPC0gKDEtcmhvKS8oSipLKQ0KdmFyIDwtIDIqQSooMS1yc2opKzIqQiooMS1yc2spDQpzZSA9IHZhcl4uNQ0KDQojIEVmZmVjdCBzaXplIGFuZCB0YXJnZXQgaW5wdXRzDQplZmZlY3RfeWVhcjEgPSAuMTUNCmVmZmVjdF95ZWFyMiA9IC4wNQ0KZWZmZWN0X3llYXIzID0gLjAyNQ0KDQp0YXJnZXRfeWVhcjEgPSAuMDg3NQ0KdGFyZ2V0X3llYXIyID0gLjENCnRhcmdldF95ZWFyMyA9IC4wMzc1DQoNCg0KIyBTaW11bGF0aW9ucw0KIyBub3RlIHRoYXQgZzJ5MGUgaW5kaWNhdGVzIHRoYXQgdGhlIGRyYXcgaXMgZm9yIGdyYWRlIDIsIHllYXIgMCwgZW5kIG9mIHllYXINCm51bV9zaW1zIDwtIDEwMDAwMA0KDQojIHllYXIgMA0KZzJ5MGUgPC0gcm5vcm0obiA9IG51bV9zaW1zLCBtZWFuID0gLjIsIHNkID0gc2UpDQoNCiMgeWVhciAxDQpnMXkxYiA8LSBybm9ybShuID0gbnVtX3NpbXMsIG1lYW4gPSAwLCBzZCA9IHNlKQ0KeTFlIDwtIG12cm5vcm0obiA9IG51bV9zaW1zLCBtdSA9IGMoLjIyNSwgLjE1KSwgU2lnbWEgPSBTaWdtYSkNCmczeTFlIDwtIHkxZVssMV0NCmcxeTFlIDwtIHkxZVssMl0NCg0KIyB5ZWFyIDINCmcxeTJiIDwtIHJub3JtKG4gPSBudW1fc2ltcywgbWVhbiA9IDAsIHNkID0gc2UpDQp5MmUgPC0gbXZybm9ybShuID0gbnVtX3NpbXMsIG11ID0gYyguMiwgLjE1KSwgU2lnbWEgPSBTaWdtYSkNCmcyeTJlIDwtIHkyZVssMV0NCmcxeTJlIDwtIHkyZVssMl0NCg0KIyB5ZWFyIDMNCmcxeTNiIDwtIHJub3JtKG4gPSBudW1fc2ltcywgbWVhbiA9IDAsIHNkID0gc2UpDQp5M2UgPC0gbXZybm9ybShuID0gbnVtX3NpbXMsIG11ID0gYyguMiwgLjE1KSwgU2lnbWEgPSBTaWdtYSkNCmcyeTNlIDwtIHkzZVssMV0NCmcxeTNlIDwtIHkzZVssMl0NCg0KIyB5ZWFyIDQNCnk0ZSA8LSBtdnJub3JtKG4gPSBudW1fc2ltcywgbXUgPSBjKC4yMjUsIC4yKSwgU2lnbWEgPSBTaWdtYSkNCmczeTRlIDwtIHk0ZVssMV0NCmcyeTRlIDwtIHk0ZVssMl0NCg0KIyBQYXltZW50IGNhbGN1bGF0aW9uDQplc3RfZWZmZWN0X3kxIDwtICgoZzN5MWUtZzJ5MGUpKyhnMXkxZS1nMXkxYikpLzINCmVzdF9lZmZlY3RfeTIgPC0gKChnMnkyZS1nMXkxZSkrKGcxeTJlLWcxeTJiKSkvMg0KZXN0X2VmZmVjdF95MyA8LSAoKGcyeTNlLWcxeTJlKSsoZzF5M2UtZzF5M2IpKS8yDQplc3RfZWZmZWN0X3k0IDwtICgoZzN5NGUtZzJ5NGUpKyhnMnk0ZS1nMXkzZSkpLzINCg0KIyBDaGVjayB0aGF0IG1lYW4gZXN0aW1hdGVkIGVmZmVjdCBpcyBzaW1pbGFyIHRvIHRhcmdldHMNCnByaW50KCJNZWFuIGVzdGltYXRlZCBlZmZlY3QgeTEgdnMgdGFyZ2V0IG9mIC4wODc1OiIpDQpyb3VuZChtZWFuKGVzdF9lZmZlY3RfeTEpLDQpDQpwcmludCgiTWVhbiBlc3RpbWF0ZWQgZWZmZWN0IHkyIHZzIHRhcmdldCBvZiAuMToiKQ0Kcm91bmQobWVhbihlc3RfZWZmZWN0X3kyKSw0KQ0KcHJpbnQoIk1lYW4gZXN0aW1hdGVkIGVmZmVjdCB5MyB2cyB0YXJnZXQgb2YgLjE6IikNCnJvdW5kKG1lYW4oZXN0X2VmZmVjdF95MyksNCkNCnByaW50KCJNZWFuIGVzdGltYXRlZCBlZmZlY3QgeTQgdnMgdGFyZ2V0IG9mIC4wMzc1OiIpDQpyb3VuZChtZWFuKGVzdF9lZmZlY3RfeTQpLDQpDQoNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQojIENhbGN1bGF0ZSBwYXltZW50IGFzc3VtaW5nIG1pbmltdW0gcGF5bWVudCBvZiAwDQpwYXltZW50X3kxIDwtIHBtYXgoMCwgZXN0X2VmZmVjdF95MS8oNCouMDg3NSkpDQpwYXltZW50X3kyIDwtIHBtYXgoMCwgZXN0X2VmZmVjdF95Mi8oNCouMSkpDQpwYXltZW50X3kzIDwtIHBtYXgoMCwgZXN0X2VmZmVjdF95My8oNCouMSkpDQpwYXltZW50X3k0IDwtIHBtYXgoMCwgZXN0X2VmZmVjdF95NC8oNCouMDM3NSkpDQoNCnRvdGFsX3BheW1lbnQgPSBwYXltZW50X3kxK3BheW1lbnRfeTIrcGF5bWVudF95MytwYXltZW50X3k0DQptZWFuKHRvdGFsX3BheW1lbnQpDQoNCiMgaGlzdG9ncmFtIG9mIHRvdGFsIHBheW1lbnQNCmdncGxvdCh0aWJibGUocCA9IHRvdGFsX3BheW1lbnQpLCBhZXMoeCA9IHApKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IC4yKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGNvbG9yID0gInJlZCIpKw0KICBsYWJzKHggPSAiVG90YWwgUGF5bWVudCIsIHkgPSAiRnJlcXVlbmN5IiwgY2FwdGlvbiA9ICJSZWQgbGluZSBpbmRpY2F0ZXMgd2hhdCB0aGUgaW52ZXN0b3JzIHNob3VsZCBiZSBwYWlkIiwgdGl0bGUgPSAiRXhwZWN0ZWQgUGF5bWVudCB3LyBDdXJyZW50IEV2YWx1YXRpb24gRGVzaWduIikgICAgDQoNCiMgRm9yIGNvbXBsZXRlbmVzcywgY2FsY3VsYXRlIGV4cGVjdGVkIHBheW1lbnQgDQpwYXltZW50X3kxX25vbWluIDwtIGVzdF9lZmZlY3RfeTEvKDQqLjA4NzUpDQpwYXltZW50X3kyX25vbWluIDwtIGVzdF9lZmZlY3RfeTIvKDQqLjEpDQpwYXltZW50X3kzX25vbWluIDwtIGVzdF9lZmZlY3RfeTMvKDQqLjEpDQpwYXltZW50X3k0X25vbWluIDwtIGVzdF9lZmZlY3RfeTQvKDQqLjAzNzUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KdG90YWxfcGF5bWVudF9ub21pbiA9IHBheW1lbnRfeTFfbm9taW4rcGF5bWVudF95Ml9ub21pbitwYXltZW50X3kzX25vbWluK3BheW1lbnRfeTRfbm9taW4NCm1lYW4odG90YWxfcGF5bWVudF9ub21pbikNCg0KIyBoaXN0b2dyYW0gb2YgdG90YWwgcGF5bWVudA0KZ2dwbG90KHRpYmJsZShwID0gdG90YWxfcGF5bWVudF9ub21pbiksIGFlcyh4ID0gcCkpICsgDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gLjIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAicmVkIikrDQogIGxhYnMoeCA9ICJUb3RhbCBQYXltZW50IiwgeSA9ICJGcmVxdWVuY3kiLCB0aXRsZSA9ICJFeHBlY3RlZCBQYXltZW50IHdpdGggUG90ZW50aWFsIE5lZ2F0aXZlIFBheW1lbnRzIiwgY2FwdGlvbiA9ICJSZWQgbGluZSBpbmRpY2F0ZXMgd2hhdCB0aGUgaW52ZXN0b3JzIHNob3VsZCBiZSBwYWlkIikgICAgDQoNCmBgYA0KDQojIEFsdGVybmF0ZSBFdmFsdWF0aW9uIERlc2lnbg0KDQpUaGUgY29kZSBiZWxvdyBzaW11bGF0ZXMgbWVhc3VyZWQgbGVhcm5pbmcgZ2FpbnMgYW5kIHBheW1lbnRzIHVzaW5nIHRoZSBzYW1lIGFzc3VtcHRpb25zIGJ1dCB3aXRoIGEgc2xpZ2h0bHkgZGlmZmVyZW50LCBjb2hvcnQtYmFzZWQgZXZhbHVhdGlvbiBkZXNpZ24uDQoNCiFbXShpbWFnZXMvcGFzdGUtNkY1MzkwRDUucG5nKQ0KDQpgYGB7cn0NCiMgZmlyc3QgY29ob3J0DQpnMXkwYiA8LSBybm9ybShuID0gbnVtX3NpbXMsIG1lYW4gPSAwLCBzZCA9IHNlKQ0KZzJ5MWUgPC0gcm5vcm0obiA9IG51bV9zaW1zLCBtZWFuID0gLjIsIHNkID0gc2UpDQplc3RfZWZmZWN0X2MxIDwtIGcyeTFlLWcxeTBiDQoNCiMgc2Vjb25kIGNvaG9ydA0KZzF5MWIgPC0gcm5vcm0obiA9IG51bV9zaW1zLCBtZWFuID0gMCwgc2QgPSBzZSkNCmcyeTJlIDwtIHJub3JtKG4gPSBudW1fc2ltcywgbWVhbiA9IC4yLCBzZCA9IHNlKQ0KZXN0X2VmZmVjdF9jMiA8LSBnMnkyZS1nMXkxYg0KDQojIHRoaXJkIGNvaG9ydA0KZzF5MmIgPC0gcm5vcm0obiA9IG51bV9zaW1zLCBtZWFuID0gMCwgc2QgPSBzZSkNCmcyeTNlIDwtIHJub3JtKG4gPSBudW1fc2ltcywgbWVhbiA9IC4yLCBzZCA9IHNlKQ0KZXN0X2VmZmVjdF9jMyA8LSBnMnkzZS1nMXkyYg0KDQojIGZvdXJ0aCBjb2hvcnQNCmcxeTNiIDwtIHJub3JtKG4gPSBudW1fc2ltcywgbWVhbiA9IDAsIHNkID0gc2UpDQpnMnk0ZSA8LSBybm9ybShuID0gbnVtX3NpbXMsIG1lYW4gPSAuMiwgc2QgPSBzZSkNCmVzdF9lZmZlY3RfYzQgPC0gZzJ5NGUtZzF5M2INCg0KcGF5bWVudF95MSA8LSBwbWF4KDAsIGVzdF9lZmZlY3RfYzEvLjgpDQpwYXltZW50X3kyIDwtIHBtYXgoMCwgZXN0X2VmZmVjdF9jMi8uOCkNCnBheW1lbnRfeTMgPC0gcG1heCgwLCBlc3RfZWZmZWN0X2MzLy44KQ0KcGF5bWVudF95NCA8LSBwbWF4KDAsIGVzdF9lZmZlY3RfYzQvLjgpDQoNCnRvdGFsX3BheW1lbnQgPSBwYXltZW50X3kxK3BheW1lbnRfeTIrcGF5bWVudF95MytwYXltZW50X3k0DQptZWFuKHRvdGFsX3BheW1lbnQpDQoNCiMgaGlzdG9ncmFtIG9mIHRvdGFsIHBheW1lbnQNCmdncGxvdCh0aWJibGUocCA9IHRvdGFsX3BheW1lbnQpLCBhZXMoeCA9IHApKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IC4wMikgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBjb2xvciA9ICJyZWQiKSsNCiAgbGFicyh4ID0gIlRvdGFsIFBheW1lbnQiLCB5ID0gIkZyZXF1ZW5jeSIpDQoNCiMgRm9yIGNvbXBsZXRlbmVzcywgY2FsY3VsYXRlIGV4cGVjdGVkIHBheW1lbnQgd2l0aCBubyBtaW5pbXVtDQpwYXltZW50X3kxX25vbWluIDwtIGVzdF9lZmZlY3RfYzEvLjgNCnBheW1lbnRfeTJfbm9taW4gPC0gZXN0X2VmZmVjdF9jMi8uOA0KcGF5bWVudF95M19ub21pbiA8LSBlc3RfZWZmZWN0X2MzLy44DQpwYXltZW50X3k0X25vbWluIDwtIGVzdF9lZmZlY3RfYzQvLjgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQp0b3RhbF9wYXltZW50X25vbWluID0gcGF5bWVudF95MV9ub21pbitwYXltZW50X3kyX25vbWluK3BheW1lbnRfeTNfbm9taW4rcGF5bWVudF95NF9ub21pbg0KbWVhbih0b3RhbF9wYXltZW50X25vbWluKQ0KDQojIGhpc3RvZ3JhbSBvZiB0b3RhbCBwYXltZW50DQpnZ3Bsb3QodGliYmxlKHAgPSB0b3RhbF9wYXltZW50X25vbWluKSwgYWVzKHggPSBwKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAuMDIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAicmVkIikrDQogIGxhYnMoeCA9ICJUb3RhbCBQYXltZW50IiwgeSA9ICJGcmVxdWVuY3kiLCB0aXRsZSA9ICJFeHBlY3RlZCBQYXltZW50IHdpdGggUG90ZW50aWFsIE5lZ2F0aXZlIFBheW1lbnRzIikgIA0KDQoNCmBgYA0K