I’ve looked at the code from various groups in the WAR/moderation
debate, wondering why they get different results. The answer is clear:
it’s because no one is running the regression correctly.
Currently, the three main parties in the debate are
- Lakshya Jain from Split Ticket. See his original
post in the debate and a later
response.
- Adam Bonica and Jake Grumbach from Stanford and UC Berkeley,
respectively. See their response to Jain here.
I’ll refer to them as BG for convenience.
- G. Elliot Morris, who writes Strength in Numbers, along with Mark
Rieke. He has two posts here
and here,
where the bulk of the argument is awkwardly behind a paywall.
Two groups have released code, which I have used to check the
analyses (thank you!):
You can also download my code for this article– just click the
dropdown by the title.
All of these groups have been analysing the effect of moderation
using an invalid regression approach. The approach has two steps:
- Run a regression predicting candidates’ election vote shares.
Crucially, this regression does not include ideology as a
predictor.
(This also describes Morris/Rieke’s Bayesian model,
which is essentially a regression.)
- Label the residuals from the first regression “WAR” (wins above
replacement), and run another regression that predicts WAR using
ideology.
Statistically, this is not recommended. To measure the effect of a
variable, we nearly always run one regression. Even in rarer
cases where we fit multiple regression equations, the regressions are
fit jointly. This two-step procedure is not a standard method in
statistics. And the nonstandard approach has caused a big problem: it
leads all the results to be contaminated by omitted variable bias.
The big mistake is that everyone has been running this regression
(the first step), but they leave out ideology. When you do this, the
other predictors that are correlated with ideology soak up part of the
effect of ideology into their own coefficients (omitted variable bias).
Then when fitting the second regression, much of the effect of ideology
has already been removed.
Why do Bonica and Grumbach find that ideology has no effect? It’s
because they included many more predictors that are correlated with
ideology, and those predictors soaked up more of the effect of ideology.
The same also applies to Morris/Rieke’s analysis, because they also
include more predictors. Lakshya’s original WAR model includes
fewer predictors, so the omitted variable bias is less severe in his
analysis.
The goal is to find the effect of ideology on vote share. So,
fundamentally, we should run one regression that predicts vote
share, using ideology as a predictor. Then we can check the coefficient
on ideology to find its effect on the vote share. It is incorrect to use
WAR for this!
Below I show the results from both the BG and Split Ticket versions
of the analysis, comparing the two-step analysis (incorrect) to the
correct one-step estimate. The error bars are the 95% confidence
interval for the coefficient:

We can see that, when done correctly, BG’s results are consistent
with Lakshya’s results. Both BG’s and Lakshya’s approach find that
moderation increases vote share.
We can also see that, when done correctly, the effect of moderation
is detectable (statistically significant). This directly contradicts
Elliot Morris, who has insisted that the confidence interval contains
both large negative and large positive effects. When the analysis is
done correctly, the effect of moderation is not hugely
uncertain. Instead we can see that it is highly likely to increase vote
share.
To get a sense of how large this effect is in practice, I’m plotting
the ideology scores of the Democrats below (hover to see the names):
So we’re seeing that, with both versions of this model, moving from a
relatively extreme to moderate Democrat – an increase of 1 to 1.5 on the
ideology scale – would increase the vote share by around 1% (which is a
2% vote differential).
To some extent we can blame Lakshya for this two-step problem, since
he introduced the two-step procedure that others then copied. But the
results show that it wasn’t much of a problem for his analysis anyway,
and only became serious when other people added more predictors.
So what about WAR?
There’s a broader takeaway here– if you include many predictors in
your WAR model, you are likely to get inaccurate WAR numbers. The WAR
you get will be missing many aspects of candidate quality, due to
omitted variable bias. It’s not just the moderation results, the WAR
values themselves are likely to be messed up! Only Lakshya’s WAR seems
reliable, due to having few predictors.
So this suggests the two new versions of WAR
(BG and Strength in Numbers) cannot be trusted. To make
progress over Lakshya’s original numbers, WAR modelers need to think
much more carefully about how to measure candidate quality, and what
attributes count as candidate quality in the first place. Throwing in
more predictors can easily make WAR worse, not better.
Other issues
That’s not the only statistical issue plaguing this debate. Here are
a few more that have only been addressed inconsistently.
Spillover effects: Imagine a district in Ohio.
Without changing anything within the district, we swap out all other
Democratic politicians across the country with Alexandria Ocasio-Cortez.
Would that change the votes in Ohio? Of course it would!
This shows that candidate moderation has spillover effects outside of
the candidate’s district, and these spillover effects are likely to be
large. Currently no one in this discussion is attempting to measure
these spillover effects. That means all of these estimates should be
considered lower bound estimates of the total impact of
moderation.
Inaccuracy of ideology scores: I think many people
in this debate are far too credulous of the ideology scores coming from
political science. DW-NOMINATE, the most widely used ideology score in
political science, incorrectly
marks the squad as moderate Democrats. There are also questions
about the accuracy of another popular ideology score, the CFscores
(which are derived from campaign donations), especially in recent
elections. BG, Morris, and myself in this article, all use Bonica’s
“composite scores” which are heavily
dependent on DW-NOMINATE and various CF scores. Generally, if these
scores are inaccurate, we will underestimate the effect of
moderation.
The scores I find most credible are GGUM and text-based
scores. But these aren’t widely available at the moment (GGUM takes
days just to estimate a single congress *sigh*). GGUM gives the original
squad members the most extreme left scores in congress, while you can
see above that Bonica’s composite scores do not put the squad farthest
left.
Lakshya’s approach of comparing groups/caucuses is a good robustness
check that should work even if the ideology scores are inaccurate.
Causal inference: Some other predictors in these
regressions may themselves be caused in part by moderation. For example,
if moderation causes incumbency because moderates are more likely to get
elected, then the causal impact of moderation is higher than
what we estimated here. On the other hand, if nominating moderates
causes Republicans to nominate more moderate candidates in response,
then the causal impact of moderation on vote share is lower
than what we estimated here. (Though I would consider more moderate
Republicans to be a positive side effect!) After accounting for this,
the result we estimated could be meaningfully different than the full
causal effect, and it’s not clear if the causal effect is higher or
lower.
LS0tCnRpdGxlOiAiRXZlcnlvbmUncyB3cm9uZyBhYm91dCBXQVIgYW5kIG1vZGVyYXRpb24iCmF1dGhvcjogIldpbGxpYW0gTWF5IgpkYXRlOiAiQXVndXN0IDIzcmQsIDIwMjUiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEYpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKIyBsaWJyYXJ5KHRleHJlZykKbGlicmFyeShnZ3Bsb3QyKQoKIyBUaGlzIHNlY3Rpb24gY29waWVzIHRoZSBwcmVwcm9jZXNzaW5nIGZyb20gdGhlIEJvbmljYS9HcnVtYmFjaCBjb2RlLCBhbmQgYWxzbwojIHJlYWRzIHRoZWlyIGRhdGFzZXQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9hYm9uaWNhL1dBUi1BbmFseXNpcy1pZGVvbG9neQoKIyBSZWFkIGFuZCBwcmVwcm9jZXNzIGRhdGEKd2FyX2RhdGEgPC0gcmVhZC5jc3YoJ3dhcl9kaW1lX21lcmdlZC5jc3YnKQp3YXJfZGF0YSRzdGF0ZV9kaXN0ICAgICA8LSBwYXN0ZSh3YXJfZGF0YSRzdGF0ZV9uYW1lLCB3YXJfZGF0YSRkaXN0cmljdCwgc2VwID0gIl8iKQp3YXJfZGF0YSRkZW1fdm90ZV9zaGFyZSA8LSAxMDAgKiB3YXJfZGF0YSRkZW1fdm90ZV9zaGFyZQp3YXJfZGF0YSRkZW1fcHJlc192cyA8LSAxMDAgKiB3YXJfZGF0YSRkZW1fcHJlc192cwoKIyBtb2RlbF9kYXRhIDwtIGR1bW15X2NvbHMod2FyX2RhdGEsIHNlbGVjdF9jb2x1bW5zID0gInN0YXRlX25hbWUiKQptb2RlbF9kYXRhIDwtIHdhcl9kYXRhCgptb2RlbF9kYXRhJGRlbV90ZW51cmVfc3EgPC0gbW9kZWxfZGF0YSRkZW1fdGVudXJlXjIKbW9kZWxfZGF0YSRzbWFsbF9zdGF0ZV9pbmN1bWJlbnRfdGVudXJlIDwtIGFzLm51bWVyaWMobW9kZWxfZGF0YSRpc19zbWFsbF9zdGF0ZSAqIG1vZGVsX2RhdGEkZGVtX3RlbnVyZSkKbW9kZWxfZGF0YSRzbWFsbF9zdGF0ZV9pbmN1bWJlbnQgICAgICAgIDwtIGFzLmludGVnZXIobW9kZWxfZGF0YSRzbWFsbF9zdGF0ZV9pbmN1bWJlbnRfdGVudXJlID4gMCkKCm1vZGVsX2RhdGEkbG9nX2NmX2RpZmYgPSBsb2cxcChtb2RlbF9kYXRhJGRlbV90b3RhbF9yZWNlaXB0cykgLSBsb2cxcChtb2RlbF9kYXRhJHJlcF90b3RhbF9yZWNlaXB0cykKbW9kZWxfZGF0YSRyZXBfaW5jIDwtIGFzLm51bWVyaWMobW9kZWxfZGF0YSRyZXBfaW5jID09ICdJJykKbW9kZWxfZGF0YSRkZW1faW5jIDwtIGFzLm51bWVyaWMobW9kZWxfZGF0YSRkZW1faW5jID09ICdJJykKbW9kZWxfZGF0YSRyZXBfaW5jW2lzLm5hKG1vZGVsX2RhdGEkcmVwX2luYyldIDwtMCAKbW9kZWxfZGF0YSRkZW1faW5jW2lzLm5hKG1vZGVsX2RhdGEkZGVtX2luYyldIDwtMCAKCiMgbW9kZWxfZGF0YSA8LSBtb2RlbF9kYXRhICU+JQojICAgZ3JvdXBfYnkoc3RhdGVfZGlzdCkgJT4lCiMgICBtdXRhdGUoZGVtX3ZvdGVfc2hhcmVfbGFnID0gbGFnKGRlbV92b3RlX3NoYXJlLCBuID0gMSwgb3JkZXJfYnkgPSBzdGF0ZV9kaXN0KSkgJT4lCiMgICB1bmdyb3VwKCkgJT4lCiMgICBhcy5kYXRhLmZyYW1lKCkKIyBeIHRoZSBvcmlnaW5hbCBjb2RlIGRvZXNuJ3Qgd29yaywgaGVyZSdzIHdvcmtpbmcgY29kZToKbW9kZWxfZGF0YV9sYWdnZWQgPSBtb2RlbF9kYXRhICU+JQogIHRyYW5zZm9ybShsYWdnZWRfZGVtX3ByZXNfdnMgPSBkZW1fcHJlc192cykgJT4lCiAgc3Vic2V0KHNlbGVjdCA9IGMoWWVhciwgc3RhdGVfZGlzdCwgbGFnZ2VkX2RlbV9wcmVzX3ZzKSkKbW9kZWxfZGF0YSA9IG1vZGVsX2RhdGEgJT4lCiAgdHJhbnNmb3JtKGxhZ2dlZF95ZWFyID0gWWVhciAtIDIpICU+JQogIG1lcmdlKG1vZGVsX2RhdGFfbGFnZ2VkLCBieS54ID0gYygnbGFnZ2VkX3llYXInLCAnc3RhdGVfZGlzdCcpLAogICAgICAgIGJ5LnkgPSBjKCdZZWFyJywgJ3N0YXRlX2Rpc3QnKSwgYWxsLnggPSBUUlVFLCBhbGwueSA9IEZBTFNFKQpgYGAKCkkndmUgbG9va2VkIGF0IHRoZSBjb2RlIGZyb20gdmFyaW91cyBncm91cHMgaW4gdGhlIFdBUi9tb2RlcmF0aW9uIGRlYmF0ZSwKd29uZGVyaW5nIHdoeSB0aGV5IGdldCBkaWZmZXJlbnQgcmVzdWx0cy4gVGhlIGFuc3dlciBpcyBjbGVhcjogaXQncyBiZWNhdXNlIG5vCm9uZSBpcyBydW5uaW5nIHRoZSByZWdyZXNzaW9uIGNvcnJlY3RseS4KCkN1cnJlbnRseSwgdGhlIHRocmVlIG1haW4gcGFydGllcyBpbiB0aGUgZGViYXRlIGFyZQoKLSBMYWtzaHlhIEphaW4gZnJvbSBTcGxpdCBUaWNrZXQuIFNlZSBoaXMgW29yaWdpbmFsCiAgcG9zdF0oaHR0cHM6Ly9zcGxpdC10aWNrZXQub3JnLzIwMjUvMDMvMTcvYXJlLW1vZGVyYXRlcy1tb3JlLWVsZWN0YWJsZS8pIGluCiAgdGhlIGRlYmF0ZSBhbmQgW2EgbGF0ZXIKICByZXNwb25zZV0oaHR0cHM6Ly9zcGxpdC10aWNrZXQub3JnLzIwMjUvMDgvMTUvZGVjb25zdHJ1Y3Rpbmctd2FyLykuCi0gQWRhbSBCb25pY2EgYW5kIEpha2UgR3J1bWJhY2ggZnJvbSBTdGFuZm9yZCBhbmQgVUMgQmVya2VsZXksIHJlc3BlY3RpdmVseS4gU2VlCiAgdGhlaXIgcmVzcG9uc2UgdG8gSmFpbgogIFtoZXJlXShodHRwczovL2RhdGE0ZGVtb2NyYWN5LnN1YnN0YWNrLmNvbS9wL2RvLW1vZGVyYXRlcy1kby1iZXR0ZXIpLiBJJ2xsCiAgcmVmZXIgdG8gdGhlbSBhcyBCRyBmb3IgY29udmVuaWVuY2UuCi0gRy4gRWxsaW90IE1vcnJpcywgd2hvIHdyaXRlcyBTdHJlbmd0aCBpbiBOdW1iZXJzLCBhbG9uZyB3aXRoIE1hcmsgUmlla2UuIEhlCiAgaGFzIHR3byBwb3N0cyBbaGVyZV0oaHR0cHM6Ly93d3cuZ2VsbGlvdHRtb3JyaXMuY29tL3AvbW9kZXJhdGlvbi1pcy1vdmVycmF0ZWQpCiAgYW5kCiAgW2hlcmVdKGh0dHBzOi8vd3d3LmdlbGxpb3R0bW9ycmlzLmNvbS9wL2RhdGEtb3Zlci1kb2dtYS1hLXJlcGx5LXRvLW1hdHQteWdsZXNpYXMpLAogIHdoZXJlIHRoZSBidWxrIG9mIHRoZSBhcmd1bWVudCBpcyBhd2t3YXJkbHkgYmVoaW5kIGEgcGF5d2FsbC4KClR3byBncm91cHMgaGF2ZSByZWxlYXNlZCBjb2RlLCB3aGljaCBJIGhhdmUgdXNlZCB0byBjaGVjayB0aGUgYW5hbHlzZXMgKHRoYW5rCnlvdSEpOgoKLSBCb25pY2EgYW5kIEdydW1iYWNoOgogIFtnaXRodWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9hYm9uaWNhL1dBUi1BbmFseXNpcy1pZGVvbG9neSkKLSBNb3JyaXMgYW5kIFJpZWtlOiBbZ2l0aHViXShodHRwczovL2dpdGh1Yi5jb20vbWFya2pyaWVrZS8yMDI2LXdhcikKCllvdSBjYW4gYWxzbyBkb3dubG9hZCBteSBjb2RlIGZvciB0aGlzIGFydGljbGUtLSBqdXN0IGNsaWNrIHRoZSBkcm9wZG93biBieSB0aGUKdGl0bGUuCgpBbGwgb2YgdGhlc2UgZ3JvdXBzIGhhdmUgYmVlbiBhbmFseXNpbmcgdGhlIGVmZmVjdCBvZiBtb2RlcmF0aW9uIHVzaW5nIGFuCmludmFsaWQgcmVncmVzc2lvbiBhcHByb2FjaC4gVGhlIGFwcHJvYWNoIGhhcyB0d28gc3RlcHM6CgoxLiBSdW4gYSByZWdyZXNzaW9uIHByZWRpY3RpbmcgY2FuZGlkYXRlcycgZWxlY3Rpb24gdm90ZSBzaGFyZXMuIENydWNpYWxseSwgdGhpcwogICByZWdyZXNzaW9uICpkb2VzIG5vdCBpbmNsdWRlIGlkZW9sb2d5IGFzIGEgcHJlZGljdG9yKi4gfn4oVGhpcyBhbHNvIGRlc2NyaWJlcwogICBNb3JyaXMvUmlla2UncyBCYXllc2lhbiBtb2RlbCwgd2hpY2ggaXMgZXNzZW50aWFsbHkgYSByZWdyZXNzaW9uLil+fltebXJdCjIuIExhYmVsIHRoZSByZXNpZHVhbHMgZnJvbSB0aGUgZmlyc3QgcmVncmVzc2lvbiAiV0FSIiAod2lucyBhYm92ZSByZXBsYWNlbWVudCksCiAgIGFuZCBydW4gYW5vdGhlciByZWdyZXNzaW9uIHRoYXQgcHJlZGljdHMgV0FSIHVzaW5nIGlkZW9sb2d5LgoKW15tcl06IEkgdG9vayBhIGNsb3NlciBsb29rIGFuZCByZWFsaXplZCBNb3JyaXMgYW5kIFJpZWtlIHVzZSBhIGRpZmZlcmVudCB0eXBlIG9mIG1vZGVsLCBzbyB0aGlzIGNyaXRpY2lzbSBtYXkgbm90IGFwcGx5IHRvIHRoZWlyIG1vZGVsLgoKU3RhdGlzdGljYWxseSwgdGhpcyBpcyBub3QgcmVjb21tZW5kZWQuIFRvIG1lYXN1cmUgdGhlIGVmZmVjdCBvZiBhIHZhcmlhYmxlLCB3ZQpuZWFybHkgYWx3YXlzIHJ1biAqb25lKiByZWdyZXNzaW9uLiBFdmVuIGluIHJhcmVyIGNhc2VzIHdoZXJlIHdlIGZpdCBtdWx0aXBsZQpyZWdyZXNzaW9uIGVxdWF0aW9ucywgdGhlIHJlZ3Jlc3Npb25zIGFyZSBmaXQgam9pbnRseS4gVGhpcyB0d28tc3RlcCBwcm9jZWR1cmUKaXMgbm90IGEgc3RhbmRhcmQgbWV0aG9kIGluIHN0YXRpc3RpY3MuIEFuZCB0aGUgbm9uc3RhbmRhcmQgYXBwcm9hY2ggaGFzIGNhdXNlZAphIGJpZyBwcm9ibGVtOiBpdCBsZWFkcyBhbGwgdGhlIHJlc3VsdHMgdG8gYmUgY29udGFtaW5hdGVkIGJ5IG9taXR0ZWQgdmFyaWFibGUKYmlhcy4KClRoZSBiaWcgbWlzdGFrZSBpcyB0aGF0IGV2ZXJ5b25lIGhhcyBiZWVuIHJ1bm5pbmcgdGhpcyByZWdyZXNzaW9uICh0aGUgZmlyc3QKc3RlcCksIGJ1dCB0aGV5IGxlYXZlIG91dCBpZGVvbG9neS4gV2hlbiB5b3UgZG8gdGhpcywgdGhlIG90aGVyIHByZWRpY3RvcnMgdGhhdAphcmUgY29ycmVsYXRlZCB3aXRoIGlkZW9sb2d5IHNvYWsgdXAgcGFydCBvZiB0aGUgZWZmZWN0IG9mIGlkZW9sb2d5IGludG8gdGhlaXIKb3duIGNvZWZmaWNpZW50cyAob21pdHRlZCB2YXJpYWJsZSBiaWFzKS4gVGhlbiB3aGVuIGZpdHRpbmcgdGhlIHNlY29uZApyZWdyZXNzaW9uLCBtdWNoIG9mIHRoZSBlZmZlY3Qgb2YgaWRlb2xvZ3kgaGFzIGFscmVhZHkgYmVlbiByZW1vdmVkLgoKV2h5IGRvIEJvbmljYSBhbmQgR3J1bWJhY2ggZmluZCB0aGF0IGlkZW9sb2d5IGhhcyBubyBlZmZlY3Q/IEl0J3MgYmVjYXVzZSB0aGV5CmluY2x1ZGVkIG1hbnkgbW9yZSBwcmVkaWN0b3JzIHRoYXQgYXJlIGNvcnJlbGF0ZWQgd2l0aCBpZGVvbG9neSwgYW5kIHRob3NlCnByZWRpY3RvcnMgc29ha2VkIHVwIG1vcmUgb2YgdGhlIGVmZmVjdCBvZiBpZGVvbG9neS4gfn5UaGUgc2FtZSBhbHNvIGFwcGxpZXMgdG8KTW9ycmlzL1JpZWtlJ3MgYW5hbHlzaXMsIGJlY2F1c2UgdGhleSBhbHNvIGluY2x1ZGUgbW9yZSBwcmVkaWN0b3JzLn5+IExha3NoeWEncwpvcmlnaW5hbCBXQVIgbW9kZWwgaW5jbHVkZXMgZmV3ZXIgcHJlZGljdG9ycywgc28gdGhlIG9taXR0ZWQgdmFyaWFibGUgYmlhcyBpcwpsZXNzIHNldmVyZSBpbiBoaXMgYW5hbHlzaXMuCgpUaGUgZ29hbCBpcyB0byBmaW5kIHRoZSBlZmZlY3Qgb2YgaWRlb2xvZ3kgb24gdm90ZSBzaGFyZS4gU28sIGZ1bmRhbWVudGFsbHksIHdlCnNob3VsZCBydW4gKm9uZSogcmVncmVzc2lvbiB0aGF0IHByZWRpY3RzIHZvdGUgc2hhcmUsIHVzaW5nIGlkZW9sb2d5IGFzIGEKcHJlZGljdG9yLiBUaGVuIHdlIGNhbiBjaGVjayB0aGUgY29lZmZpY2llbnQgb24gaWRlb2xvZ3kgdG8gZmluZCBpdHMgZWZmZWN0IG9uCnRoZSB2b3RlIHNoYXJlLiBJdCBpcyBpbmNvcnJlY3QgdG8gdXNlIFdBUiBmb3IgdGhpcyEKCkJlbG93IEkgc2hvdyB0aGUgcmVzdWx0cyBmcm9tIGJvdGggdGhlIEJHIGFuZCBTcGxpdCBUaWNrZXQgdmVyc2lvbnMgb2YgdGhlCmFuYWx5c2lzLCBjb21wYXJpbmcgdGhlIHR3by1zdGVwIGFuYWx5c2lzIChpbmNvcnJlY3QpIHRvIHRoZSBjb3JyZWN0IG9uZS1zdGVwCmVzdGltYXRlLltebWlzc2luZ2ZpbGVzXSBUaGUgZXJyb3IgYmFycyBhcmUgdGhlIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUKY29lZmZpY2llbnQ6CgpbXm1pc3NpbmdmaWxlc106IEkgZGlkbid0IHJ1biB0aGUgU3RyZW5ndGggaW4gTnVtYmVycyBtb2RlbCBiZWNhdXNlIHRoZXkgZG9uJ3QKICAgIHByb3ZpZGUgdGhlIGRhdGEgZmlsZXMgbmVlZGVkIHRvIHJlcHJvZHVjZSBpdC4gSSBtYWRlIGEgZmV3IG90aGVyCiAgICBzaW1wbGlmaWNhdGlvbnMgdG8gbWFrZSB0aGlzIGVhc3kgdG8gcnVuIG92ZXIgdGhlIHdlZWtlbmQtLSBpbnN0ZWFkIG9mIEJHJ3MKICAgIGdsbW5ldCBJIGp1c3QgcmFuIGEgbGluZWFyIHJlZ3Jlc3Npb24gKGl0J3MgZmluZSBmb3IgdGhpcyksIGFuZCBJIHVzZWQKICAgIEJvbmljYSdzIGNvbXBvc2l0ZSBzY29yZSBhcyB0aGUgbWVhc3VyZSBvZiBpZGVvbG9neS4gRm9yIHRoZSBTcGxpdCBUaWNrZXQKICAgIHZlcnNpb24sIEknbSBhbHNvIG5vdCBzdXJlIEkgaGF2ZSB0aGUgZXhhY3QgZm9ybSBvZiB0aGUgbGFnZ2VkIHZhbHVlIExha3NoeWEKICAgIHVzZXMuIEkganVzdCB1c2VkIGxhZ2dlZCBwcmVzaWRlbnRpYWwgdm90ZSBzaGFyZS4gVGhlIHJlZ3Jlc3Npb24gb25seQogICAgaW5jbHVkZXMgMjAyNCwgYmVjYXVzZSB3ZSdyZSBmb2N1c2VkIG9uIHRoZSBtb3N0IHJlY2VudCByZXN1bHRzLgoKYGBge3Igb21pdHRlZC1iaWFzLXJlc3VsdHN9Cm1kYXQyMDI0ID0gbW9kZWxfZGF0YVttb2RlbF9kYXRhJGN5Y2xlID09IDIwMjQsIF0KCnR3b19zdGVwX2xtID0gZnVuY3Rpb24oeSwgeHZhcnMsIGRhdCkgewogIG0xID0gbG0oeSB+IC4sIGRhdFssIHh2YXJzXSwgbmEuYWN0aW9uID0gbmEuZXhjbHVkZSkKICB3YXIgPSByZXNpZChtMSkKICBsbSh3YXIgfiBkZW1fY29tcG9zaXRlLCBkYXRbLCAnZGVtX2NvbXBvc2l0ZScsIGRyb3AgPSBGQUxTRV0pCn0KCmdldF9pZGVvX2NvZWZzID0gZnVuY3Rpb24oeSwgeHZhcnMpIHsKICByZWdyX2RhdCA9IG1kYXQyMDI0CiAgbV8yc3RlcCA9IHR3b19zdGVwX2xtKHksIHh2YXJzLCByZWdyX2RhdCkKICBtXzFzdGVwID0gbG0oeSB+IC4sIHJlZ3JfZGF0WywgYygnZGVtX2NvbXBvc2l0ZScsIHh2YXJzKV0pCiAgb3V0ID0gcmJpbmQoc3VtbWFyeShtXzJzdGVwKSRjb2VmZmljaWVudHMsCiAgICAgICAgICAgICAgc3VtbWFyeShtXzFzdGVwKSRjb2VmZmljaWVudHMpCiAgb3V0ID0gb3V0W3Jvdy5uYW1lcyhvdXQpID09ICdkZW1fY29tcG9zaXRlJywgXQogIG91dCAlPiUKICAgIGFzLmRhdGEuZnJhbWUgJT4lCiAgICB0cmFuc2Zvcm0obW9kZWwgPSBjKCcyLXN0ZXAgKGluY29ycmVjdCknLCAnMS1zdGVwIChjb3JyZWN0KScpKQp9Cgp4X2JnID0gYygiZGVtX2luYyIsICJyZXBfaW5jIiwgImRlbV9wcmVzX3ZzIiwgInJlcF9jZnNjb3JlIiwgImxvZ19jZl9kaWZmIiwKICAgICAgICAgImlzX3NtYWxsX3N0YXRlIiwgImRlbV90ZW51cmUiLCAiZGVtX3RlbnVyZV9zcSIsCiAgICAgICAgICJzbWFsbF9zdGF0ZV9pbmN1bWJlbnQiLCAic21hbGxfc3RhdGVfaW5jdW1iZW50X3RlbnVyZSIsICJzdGF0ZV9uYW1lIikKeF9zdCA9IGMoImRlbV9pbmMiLCAicmVwX2luYyIsICdsYWdnZWRfZGVtX3ByZXNfdnMnKQoKcmVzX2JnID0gZ2V0X2lkZW9fY29lZnMobWRhdDIwMjQkZGVtX3ZvdGVfc2hhcmUsIHhfYmcpCnJlc19zdCA9IGdldF9pZGVvX2NvZWZzKHdpdGgobWRhdDIwMjQsIGRlbV92b3RlX3NoYXJlIC0gZGVtX3ByZXNfdnMpLCB4X3N0KQpyZXNfYmckR3JvdXAgPSAnQkcnCnJlc19zdCRHcm91cCA9ICdTcGxpdCBUaWNrZXQnCnJlc19hbGwgPSByYmluZChyZXNfc3QsIHJlc19iZykKIyBwcmludChyZXNfYWxsKQoKZ2dwbG90KHJlc19hbGwsIGFlcyh4ID0gR3JvdXAsIHkgPSBFc3RpbWF0ZSwgZmlsbCA9IG1vZGVsKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gJ2RvZGdlJywgc3RhdCA9ICdpZGVudGl0eScpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gRXN0aW1hdGUgLSBgU3RkLiBFcnJvcmAgKiAxLjk2LAogICAgICAgICAgICAgICAgICAgIHltYXggPSBFc3RpbWF0ZSArIGBTdGQuIEVycm9yYCAqIDEuOTYpLAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC45KSwgd2lkdGggPSAuNSwKICAgICAgICAgICAgICAgIGNvbG9yID0gJyM0NDQ0NDQnKSArCiAgeWxhYignJSBjaGFuZ2UgaW4gdm90ZSBzaGFyZSBwZXIgdW5pdCBjaGFuZ2UgaW4gaWRlb2xvZ3lcbigyMDI0IGVsZWN0aW9ucyknKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSh0eXBlID0gcGFsZXR0ZS5jb2xvcnMoKVszOjJdKQpgYGAKCldlIGNhbiBzZWUgdGhhdCwgd2hlbiBkb25lIGNvcnJlY3RseSwgQkcncyByZXN1bHRzIGFyZSBjb25zaXN0ZW50IHdpdGggTGFrc2h5YSdzCnJlc3VsdHMuIEJvdGggQkcncyBhbmQgTGFrc2h5YSdzIGFwcHJvYWNoIGZpbmQgdGhhdCBtb2RlcmF0aW9uIGluY3JlYXNlcyB2b3RlCnNoYXJlLgoKV2UgY2FuIGFsc28gc2VlIHRoYXQsIHdoZW4gZG9uZSBjb3JyZWN0bHksIHRoZSBlZmZlY3Qgb2YgbW9kZXJhdGlvbiBpcwpkZXRlY3RhYmxlIChzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KS4gVGhpcyBkaXJlY3RseSBjb250cmFkaWN0cyBFbGxpb3QgTW9ycmlzLAp3aG8gaGFzIGluc2lzdGVkIHRoYXQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY29udGFpbnMgYm90aCBsYXJnZSBuZWdhdGl2ZSBhbmQKbGFyZ2UgcG9zaXRpdmUgZWZmZWN0cy4gV2hlbiB0aGUgYW5hbHlzaXMgaXMgZG9uZSBjb3JyZWN0bHksIHRoZSBlZmZlY3Qgb2YKbW9kZXJhdGlvbiBpcyAqbm90KiBodWdlbHkgdW5jZXJ0YWluLiBJbnN0ZWFkIHdlIGNhbiBzZWUgdGhhdCBpdCBpcyBoaWdobHkKbGlrZWx5IHRvIGluY3JlYXNlIHZvdGUgc2hhcmUuCgpUbyBnZXQgYSBzZW5zZSBvZiBob3cgbGFyZ2UgdGhpcyBlZmZlY3QgaXMgaW4gcHJhY3RpY2UsIEknbSBwbG90dGluZyB0aGUKaWRlb2xvZ3kgc2NvcmVzIG9mIHRoZSBEZW1vY3JhdHMgYmVsb3cgKGhvdmVyIHRvIHNlZSB0aGUgbmFtZXMpOgoKPCEtLSBgYGB7ciBzY29yZXN9IC0tPgo8IS0tIGhpc3QobWRhdDIwMjQkZGVtX2NvbXBvc2l0ZSwgYnJlYWtzPTEwKSAtLT4KPCEtLSBgYGAgLS0+CgpgYGB7ciBzY29yZXMyLCBvdXQud2lkdGg9IjgwMHB4Iiwgb3V0LmhlaWdodD0iMjUwcHgiLCB3YXJuaW5nPUZBTFNFfQojIGZvbGxvd2luZyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TcXVhZF8oVS5TLl9Db25ncmVzcykKc3F1YWRfbWVtYmVycyA9IGMoCiAgICAnT2Nhc2lvLUNvcnRleicsCiAgICAnb21hcicsCiAgICAncHJlc3NsZXknLAogICAgJ3RsYWliJywKICAgICdjYXNhcicsCiAgICAnU3VtbWVyIExlZScsCiAgICAnRGVsaWEgUmFtaXJleicKKQpzcXVhZF9ncmVwID0gcGFzdGUodG9sb3dlcihzcXVhZF9tZW1iZXJzKSwgY29sbGFwc2UgPSAnfCcpCiMgZm9sbG93aW5nIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JsdWVfRG9nX0NvYWxpdGlvbiNDdXJyZW50X21lbWJlcnMKYmx1ZV9kb2dzID0gYygKICAgICdNaWtlIFRob21wc29uJywKICAgICdBZGFtIEdyYXknLAogICAgJ0ppbSBDb3N0YScsCiAgICAnTG91IENvcnJlYScsCiAgICAnU2FuZm9yZCBCaXNob3AnLAogICAgJ0phcmVkIEdvbGRlbicsCiAgICAnSm9zaCBHb3R0aGVpbWVyJywKICAgICdIZW5yeSBDdWVsbGFyJywKICAgICdNYXJpZSBHbHVlc2Vua2FtcCBQZXJleicsCiAgICAnVmljZW50ZSBHb256YWxleicKKQpibHVlZG9nX2dyZXAgPSBwYXN0ZSh0b2xvd2VyKGJsdWVfZG9ncyksIGNvbGxhcHNlID0gJ3wnKQoKbWRhdDIwMjQgJT4lCiAgdHJhbnNmb3JtKHNxdWFkID0gZ3JlcGwoc3F1YWRfZ3JlcCwgRGVtb2NyYXQsIGlnbm9yZS5jYXNlID0gVFJVRSksCiAgICAgICAgICAgIGJsdWVfZG9nID0gZ3JlcGwoYmx1ZWRvZ19ncmVwLCBEZW1vY3JhdCwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lCiAgdHJhbnNmb3JtKGdyb3VwID0gaWZlbHNlKHNxdWFkLCAnU3F1YWQnLCBpZmVsc2UoYmx1ZV9kb2csICdCbHVlIERvZycsICdPdGhlcicpKSkgJT4lCiAgcGxvdF9seSh0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLCBkYXRhID0gLiwKICAgICAgICAgIHggPSB+ZGVtX2NvbXBvc2l0ZSwgeSA9IGppdHRlcihyZXAoMCwgbnJvdyhtZGF0MjAyNCkpLCAuNSksCiAgICAgICAgICB0ZXh0ID0gfnBhc3RlKERlbW9jcmF0LCAnPGJyPlNjb3JlOicsIHJvdW5kKGRlbV9jb21wb3NpdGUsIDIpKSwKICAgICAgICAgIGNvbG9yID0gfmdyb3VwLAogICAgICAgICAgY29sb3JzID0gYygncHVycGxlJywgJyM3Nzc3NzcnLCAncmVkJyksCiAgICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSA3LCBvcGFjaXR5ID0gMC43KSkgJT4lCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZSA9ICdCb25pY2EgY29tcG9zaXRlIHNjb3JlJyksCiAgICAgICAgICMgeS1heGlzIGlzIG1lYW5pbmdsZXNzCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICIiLCB6ZXJvbGluZSA9IEZBTFNFLCBzaG93bGluZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgc2hvd3RpY2tsYWJlbHMgPSBGQUxTRSwgc2hvd2dyaWQgPSBGQUxTRSkpCmBgYAoKU28gd2UncmUgc2VlaW5nIHRoYXQsIHdpdGggYm90aCB2ZXJzaW9ucyBvZiB0aGlzIG1vZGVsLCBtb3ZpbmcgZnJvbSBhIHJlbGF0aXZlbHkKZXh0cmVtZSB0byBtb2RlcmF0ZSBEZW1vY3JhdCAtLSBhbiBpbmNyZWFzZSBvZiAxIHRvIDEuNSBvbiB0aGUgaWRlb2xvZ3kgc2NhbGUgLS0Kd291bGQgaW5jcmVhc2UgdGhlIHZvdGUgc2hhcmUgYnkgYXJvdW5kIDElICh3aGljaCBpcyBhIDIlIHZvdGUgZGlmZmVyZW50aWFsKS4KClRvIHNvbWUgZXh0ZW50IHdlIGNhbiBibGFtZSBMYWtzaHlhIGZvciB0aGlzIHR3by1zdGVwIHByb2JsZW0sIHNpbmNlIGhlCmludHJvZHVjZWQgdGhlIHR3by1zdGVwIHByb2NlZHVyZSB0aGF0IG90aGVycyB0aGVuIGNvcGllZC4gQnV0IHRoZSByZXN1bHRzIHNob3cKdGhhdCBpdCB3YXNuJ3QgbXVjaCBvZiBhIHByb2JsZW0gZm9yIGhpcyBhbmFseXNpcyBhbnl3YXksIGFuZCBvbmx5IGJlY2FtZQpzZXJpb3VzIHdoZW4gb3RoZXIgcGVvcGxlIGFkZGVkIG1vcmUgcHJlZGljdG9ycy4KCgojIyBTbyB3aGF0IGFib3V0IFdBUj8KClRoZXJlJ3MgYSBicm9hZGVyIHRha2Vhd2F5IGhlcmUtLSBpZiB5b3UgaW5jbHVkZSBtYW55IHByZWRpY3RvcnMgaW4geW91ciBXQVIKbW9kZWwsIHlvdSBhcmUgbGlrZWx5IHRvIGdldCBpbmFjY3VyYXRlIFdBUiBudW1iZXJzLiBUaGUgV0FSIHlvdSBnZXQgd2lsbCBiZQptaXNzaW5nIG1hbnkgYXNwZWN0cyBvZiBjYW5kaWRhdGUgcXVhbGl0eSwgZHVlIHRvIG9taXR0ZWQgdmFyaWFibGUgYmlhcy4gSXQncwpub3QganVzdCB0aGUgbW9kZXJhdGlvbiByZXN1bHRzLCB0aGUgV0FSIHZhbHVlcyB0aGVtc2VsdmVzIGFyZSBsaWtlbHkgdG8gYmUKbWVzc2VkIHVwISBPbmx5IExha3NoeWEncyBXQVIgc2VlbXMgcmVsaWFibGUsIGR1ZSB0byBoYXZpbmcgZmV3IHByZWRpY3RvcnMuCgpTbyB0aGlzIHN1Z2dlc3RzIHRoZSB+fnR3b35+IG5ldyB2ZXJzaW9ufn5zfn4gb2YgV0FSIChCRyB+fmFuZCBTdHJlbmd0aCBpbiBOdW1iZXJzfn4pIGNhbm5vdApiZSB0cnVzdGVkLiBUbyBtYWtlIHByb2dyZXNzIG92ZXIgTGFrc2h5YSdzIG9yaWdpbmFsIG51bWJlcnMsIFdBUiBtb2RlbGVycyBuZWVkCnRvIHRoaW5rIG11Y2ggbW9yZSBjYXJlZnVsbHkgYWJvdXQgaG93IHRvIG1lYXN1cmUgY2FuZGlkYXRlIHF1YWxpdHksIGFuZCB3aGF0CmF0dHJpYnV0ZXMgY291bnQgYXMgY2FuZGlkYXRlIHF1YWxpdHkgaW4gdGhlIGZpcnN0IHBsYWNlLiBUaHJvd2luZyBpbiBtb3JlCnByZWRpY3RvcnMgY2FuIGVhc2lseSBtYWtlIFdBUiAqd29yc2UqLCBub3QgYmV0dGVyLgoKCiMjIE90aGVyIGlzc3VlcwoKVGhhdCdzIG5vdCB0aGUgb25seSBzdGF0aXN0aWNhbCBpc3N1ZSBwbGFndWluZyB0aGlzIGRlYmF0ZS4gSGVyZSBhcmUgYSBmZXcgbW9yZQp0aGF0IGhhdmUgb25seSBiZWVuIGFkZHJlc3NlZCBpbmNvbnNpc3RlbnRseS4KCioqU3BpbGxvdmVyIGVmZmVjdHM6KiogSW1hZ2luZSBhIGRpc3RyaWN0IGluIE9oaW8uIFdpdGhvdXQgY2hhbmdpbmcgYW55dGhpbmcKd2l0aGluIHRoZSBkaXN0cmljdCwgd2Ugc3dhcCBvdXQgYWxsIG90aGVyIERlbW9jcmF0aWMgcG9saXRpY2lhbnMgYWNyb3NzIHRoZQpjb3VudHJ5IHdpdGggQWxleGFuZHJpYSBPY2FzaW8tQ29ydGV6LiBXb3VsZCB0aGF0IGNoYW5nZSB0aGUgdm90ZXMgaW4gT2hpbz8gT2YKY291cnNlIGl0IHdvdWxkIQoKVGhpcyBzaG93cyB0aGF0IGNhbmRpZGF0ZSBtb2RlcmF0aW9uIGhhcyBzcGlsbG92ZXIgZWZmZWN0cyBvdXRzaWRlIG9mIHRoZQpjYW5kaWRhdGUncyBkaXN0cmljdCwgYW5kIHRoZXNlIHNwaWxsb3ZlciBlZmZlY3RzIGFyZSBsaWtlbHkgdG8gYmUgbGFyZ2UuCkN1cnJlbnRseSBubyBvbmUgaW4gdGhpcyBkaXNjdXNzaW9uIGlzIGF0dGVtcHRpbmcgdG8gbWVhc3VyZSB0aGVzZSBzcGlsbG92ZXIKZWZmZWN0cy4gVGhhdCBtZWFucyBhbGwgb2YgdGhlc2UgZXN0aW1hdGVzIHNob3VsZCBiZSBjb25zaWRlcmVkICpsb3dlciBib3VuZAplc3RpbWF0ZXMqIG9mIHRoZSB0b3RhbCBpbXBhY3Qgb2YgbW9kZXJhdGlvbi4KCioqSW5hY2N1cmFjeSBvZiBpZGVvbG9neSBzY29yZXM6KiogSSB0aGluayBtYW55IHBlb3BsZSBpbiB0aGlzIGRlYmF0ZSBhcmUgZmFyCnRvbyBjcmVkdWxvdXMgb2YgdGhlIGlkZW9sb2d5IHNjb3JlcyBjb21pbmcgZnJvbSBwb2xpdGljYWwgc2NpZW5jZS4gRFctTk9NSU5BVEUsCnRoZSBtb3N0IHdpZGVseSB1c2VkIGlkZW9sb2d5IHNjb3JlIGluIHBvbGl0aWNhbCBzY2llbmNlLCBbaW5jb3JyZWN0bHkgbWFya3MgdGhlCnNxdWFkIGFzIG1vZGVyYXRlCkRlbW9jcmF0c10oaHR0cHM6Ly92b3Rldmlldy5jb20vYXJ0aWNsZXMvT2Nhc2lvLUNvcnRlel9PbWFyX1ByZXNzbGV5X1RsYWliKS4KVGhlcmUgYXJlIGFsc28gcXVlc3Rpb25zIGFib3V0IHRoZSBhY2N1cmFjeSBvZiBhbm90aGVyIHBvcHVsYXIgaWRlb2xvZ3kgc2NvcmUsCnRoZSBDRnNjb3JlcyAod2hpY2ggYXJlIGRlcml2ZWQgZnJvbSBjYW1wYWlnbiBkb25hdGlvbnMpLCBlc3BlY2lhbGx5IGluIHJlY2VudAplbGVjdGlvbnMuIEJHLCBNb3JyaXMsIGFuZCBteXNlbGYgaW4gdGhpcyBhcnRpY2xlLCBhbGwgdXNlIEJvbmljYSdzICJjb21wb3NpdGUKc2NvcmVzIiB3aGljaCBhcmUgW2hlYXZpbHkgZGVwZW5kZW50IG9uCkRXLU5PTUlOQVRFXShodHRwczovL2Jza3kuYXBwL3Byb2ZpbGUvd21heS5ic2t5LnNvY2lhbC9wb3N0LzNsd2tibGI1bXIyMmcpIGFuZAp2YXJpb3VzIENGIHNjb3Jlcy4gR2VuZXJhbGx5LCBpZiB0aGVzZSBzY29yZXMgYXJlIGluYWNjdXJhdGUsIHdlIHdpbGwKdW5kZXJlc3RpbWF0ZSB0aGUgZWZmZWN0IG9mIG1vZGVyYXRpb24uCgpUaGUgc2NvcmVzIEkgZmluZCBtb3N0IGNyZWRpYmxlIGFyZSBbR0dVTV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTcvcGFuLjIwMjIuMzMpCmFuZCBbdGV4dC1iYXNlZApzY29yZXNdKGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL3NvbDMvcGFwZXJzLmNmbT9hYnN0cmFjdF9pZD00MzUwNTUwKS4gQnV0IHRoZXNlCmFyZW4ndCB3aWRlbHkgYXZhaWxhYmxlIGF0IHRoZSBtb21lbnQgKEdHVU0gdGFrZXMgZGF5cyBqdXN0IHRvIGVzdGltYXRlIGEgc2luZ2xlCmNvbmdyZXNzIFwqc2lnaFwqKS4gR0dVTSBnaXZlcyB0aGUgb3JpZ2luYWwgc3F1YWQgbWVtYmVycyB0aGUgbW9zdCBleHRyZW1lIGxlZnQKc2NvcmVzIGluIGNvbmdyZXNzLCB3aGlsZSB5b3UgY2FuIHNlZSBhYm92ZSB0aGF0IEJvbmljYSdzIGNvbXBvc2l0ZSBzY29yZXMgZG8Kbm90IHB1dCB0aGUgc3F1YWQgZmFydGhlc3QgbGVmdC4KCkxha3NoeWEncyBhcHByb2FjaCBvZiBjb21wYXJpbmcgZ3JvdXBzL2NhdWN1c2VzIGlzIGEgZ29vZCByb2J1c3RuZXNzIGNoZWNrIHRoYXQKc2hvdWxkIHdvcmsgZXZlbiBpZiB0aGUgaWRlb2xvZ3kgc2NvcmVzIGFyZSBpbmFjY3VyYXRlLgoKKipDYXVzYWwgaW5mZXJlbmNlOioqIFNvbWUgb3RoZXIgcHJlZGljdG9ycyBpbiB0aGVzZSByZWdyZXNzaW9ucyBtYXkgdGhlbXNlbHZlcwpiZSBjYXVzZWQgaW4gcGFydCBieSBtb2RlcmF0aW9uLiBGb3IgZXhhbXBsZSwgaWYgbW9kZXJhdGlvbiBjYXVzZXMgaW5jdW1iZW5jeQpiZWNhdXNlIG1vZGVyYXRlcyBhcmUgbW9yZSBsaWtlbHkgdG8gZ2V0IGVsZWN0ZWQsIHRoZW4gdGhlIGNhdXNhbCBpbXBhY3Qgb2YKbW9kZXJhdGlvbiBpcyAqaGlnaGVyKiB0aGFuIHdoYXQgd2UgZXN0aW1hdGVkIGhlcmUuIE9uIHRoZSBvdGhlciBoYW5kLCBpZgpub21pbmF0aW5nIG1vZGVyYXRlcyBjYXVzZXMgUmVwdWJsaWNhbnMgdG8gbm9taW5hdGUgbW9yZSBtb2RlcmF0ZSBjYW5kaWRhdGVzIGluCnJlc3BvbnNlLCB0aGVuIHRoZSBjYXVzYWwgaW1wYWN0IG9mIG1vZGVyYXRpb24gb24gdm90ZSBzaGFyZSBpcyAqbG93ZXIqIHRoYW4Kd2hhdCB3ZSBlc3RpbWF0ZWQgaGVyZS4gKFRob3VnaCBJIHdvdWxkIGNvbnNpZGVyIG1vcmUgbW9kZXJhdGUgUmVwdWJsaWNhbnMgdG8gYmUKYSBwb3NpdGl2ZSBzaWRlIGVmZmVjdCEpIEFmdGVyIGFjY291bnRpbmcgZm9yIHRoaXMsIHRoZSByZXN1bHQgd2UgZXN0aW1hdGVkCmNvdWxkIGJlIG1lYW5pbmdmdWxseSBkaWZmZXJlbnQgdGhhbiB0aGUgZnVsbCBjYXVzYWwgZWZmZWN0LCBhbmQgaXQncyBub3QgY2xlYXIKaWYgdGhlIGNhdXNhbCBlZmZlY3QgaXMgaGlnaGVyIG9yIGxvd2VyLgo=