Predicting the Patch: Do Winrate, Pickrate, or Hot Topics in the Overwatch Forums Predict Future Balance Changes?

Hi everyone, Sine’s Stats back with another question: can we predict future Overwatch balance changes with publicly available data? Overwatch 2 and it’s associated changes–whether it be the 5v5 format, role passives, nerfing CC, or comments on specific heroes–have caused a big uproar in the community. It’s one of the few topics I’ve seen permeate into places like r/OverwatchUniversity–a community that usually focuses on improvement over balance complaints–but it’s certainly not the first time forum-based communities have commented en masse about game balance. Today, I’m going to use data from Overbuff, Patch Notes, and the Overwatch Forums to see whether a user keeping up-to-date on these platforms might potentially be more informed about upcoming balance changes than one who doesn’t.

TL;DR - Main Takeaways

This blurb ended up pretty length, so here are the main takeaways of my findings!

Overwatch Forums

  • It’s not your imagination, the Official Forums are a hotbed for change/buff/nerf posts.
  • The most (in)famous heroes on the Official Forums lately are Genji, Mercy, McCree, Sombra, and Rein.
  • For some reason, the Forums really love Mercy (and Junkrat?) and they really hate Doomfist.
  • Calls for nerfs/buffs align really well with the various metas we’ve seen- Sigma/Ball, McCree, etc.
  • Some heroes are simultaneously called for nerfs/buffs, usually because they’re weak but hated (Genji, Hanzo, Reaper) or begrudgingly necessary (Rein)

Relationship with Balance Changes

  • Winrates are predictive of balance changes in a nonlinear way
  • Being a tank or healer is predictive of getting rebalanced during this study period
  • Number of Replies to a post and calls for nerfs are marginally predictive of getting rebalanced, but their predictive power goes away after you include winrates and pickrates. Forums topics do not significantly affect balance changes!

The Forums

Unlike r/OverwatchUniversity, r/CompetitiveOverwatch, or r/Overwatch, the Overwatch General Forums seem extremely concentrated on the balance of the game. When I visit the official forums, I get the sense that the vast majority of posts are about whether game updates will be or have been good or completely destructive of the game. This might be a way to connect with other players, develop and change one’s opinions, but do these constant discussion efforts effect change? Is my intuition even right, that there are a lot of comments about balance and hero changes, or am I just prone to noticing those posts? I decided to dig a little deeper.

The Data

To check it out, I scraped Overwatch Forum General Discussion post titles, number of views, and number of replies from 11-01-2020 to 5-28-2021. I wound up with a dataset of 30317 unique posts in that timespan, which spans just about 8 Overwatch retail patches.

The Hot Topics

The first thing I was interested in is what are people talking about?. To get a sense of the “hot topics” in the Overwatch Forums General Discussion, I generated a Word Cloud of the most mentioned words in post titles that appeared in the timespan of my data, shown in Figure 1. Word Clouds are a graphical display of the most frequently mentioned words, where relative frequency is indicated by the size of the words. Right away, we can see that the most mentioned words are Overwatch, game, OW2, tank, need, change, nerf, and buff. It looks like intuition is right, that game updates are the hottest topics in the forums.

Figure 1. WordCloud of most common word mentions in the Overwatch Forum titles from 11-01-2020 to 5-28-2021. Figure 2. WordCloud of most common hero mentions in the Overwatch Forum titles from 11-01-2020 to 5-28-2021.

But since we don’t have any data on OW2 or the upcoming tank changes, let’s concentrate on hero-specific changes that have been made. To get a sense of the hot-topic heroes, we can also take a look at the most frequently mentioned heroes in forum post titles (shown in Figure 2). We can see right away that the most (in)famous heroes are Genji, Mercy, McCree, Sombra, Sigma, Reaper and Rein. The frequency of hero mentions might tell us about, for example, the forum demographic or the state of a hero. But to assess which it is, we need to dig a little more into how these heroes are regarded when they’re mentioned.

Hero Sentiment

As a first pass, we’re going to check whether post title is more likely to be positive or negative in nature when a hero is mentioned. We evaluate this with a metric called sentiment.

Calculating the Sentiment

To calculate the sentiment, we’re going to use Python’s Natural Language Processing Toolkit (NLTK). This package uses a model called VADER to predict the sentiment of social media text as a number ranging from -1 (entirely negative) to 1 (entirely positive). I’ll leave it up to you guys to explore how exactly the model is trained ;).

Some Examples

However, there are some difficulties with this model. For example, sentiment predictions are often quite bad at predicting sarcasm, generalizing to very field specific lingo (buff/nerf would likely not be given a score), and the sentiment could easily capture positive or negative attitudes about non-balance features (e.g. skins). To get a better sense of this, let me show you some hero-specific examples:

Top Positive Examples Score Top Negative Examples Score
To me, no hard counter heroes like Widow is a great s… .934 KIll, kill, kIll Genji -.944
The best way to help Genji without buff: show DAMAGE VALUES .926 Dead Junkrat should STAY DEAD! -.892
Super Genji, Super Hog and now Super Bap .914 Rein suicide charge resulting in 1 kill = POTG - .881
Mccree TOP MOST picked hero in all ranks and 2nd most picked hero in GM .913 Dva mech kill is the worst balance change since brig -.869
The Best Sym Buff that will make her super fun .908 Ball is so unbelievably broken i hate comp now -.837

Here, we see the good and the bad of our sentiment measure. Firstly, the negative sentiments look pretty good. All of the statements are clearly expressing negative feelings about or aspects of the hero mentioned. However, the positive sentiments are a mixed bag. The top two and the fifth look reasonable, positive ideas associated with particular heroes, but the third is clearly a misinterpretation of the word “super”, and the fourth is attempting to convey something negative (i.e. overabundance) about McCree. These sentiment predictions aren’t going to be perfect, but the hope is that more often not we’ll get the appropriate association.

Sentiment Distribution

To get a sense of what our sentiment measure looks like overall, let’s take a look at the distributions of sentiment across every hero that was mentioned in our forum data during the time period using box plots (shown in Figure 3). Very high level interpretation of the box plots: the location of the box shows where most of the sentiment is concentrated, and the spread of the box (and “lines” coming out of the box) shows how variable the sentiment is.

Figure 3. Box plots of Overwatch of Forum title sentiment mentioning a specific hero from 11-01-2020 to 5-28-2021.

There’s no doubt that our sentiment is a noisy measure, but there are a few things that stand out. Firstly, mercy has an overwhelmingly positive sentiment, and there is very little variation. It seems like the forums generally like mercy. This might be because there are a lot of healers or mercy mains that use the forums, or it might be because she tends to have had the most positive changes associated with her (e.g. balance, skins, etc.) during the time frame. The second most positively regarded hero is somewhat surprisingly Junkrat, though there seem to be less observations overall about him. For example, there are no outliers (individual dots) and the distribution is relatively tight. Finally, the most obviously negative sentiment is associated with Doomfist. This can come from folks disliking Doomfist, disliking that he is supposedly under- or over-powered, etc. Whatever it is, it’s negative.

There is certainly more curating one could do of the sentiment, but let’s save that for another time. For now we’ll just try and find out if there is some indication of a relationship between this sentiment measure and future patches.

Calls for Nerfs and Buffs

As stated above, though it often agrees with intuition, there are multiple difficulties associated with our sentiment measure. If our interest is how forum discussion predicts future patches, could instead use a simpler approach getting at the heart of the matter: how often is a hero name mentioned in the same title as the words “buff” or “nerf”?.

Figure 4 and Figure 5 show Word Clouds of hero names appearing in the same title as the words “buff” and “nerf”, respectively, from 11-01-2020 to 5-28-2021. The top heroes in the “buff” category are Genji, Orisa, Reaper, Moira, Dva, and Sombra. The top heroes in the “nerf” category are McCree, Ball, Sigma, Mercy, and Reaper. s

Figure 4. Word Cloud of most common heros mentioned in Overwatch Forums titles along with the word “buff” from 11-01-2020 to 5-28-2021. Figure 5. Word Cloud of most common heros mentioned in Overwatch Forums titles along with the word “nerf” from 11-01-2020 to 5-28-2021.

These track extremely well with the time period- the sigma-ball tank meta and now the McCree meta, so not altogether suprising, but there are some curiousities. For example, how is Mercy often being cited in unison with nerfs while having a largely positive sentiment? Or, how is reaper in the top heroes mentioned for both “buffs” and “nerfs”? Since the first question might have in large part to do with cosmetics (which is outside of our scope of interest), let’s focus on the second.

Figure 6. Frequencies of Overwatch Forum titles mentioning “buff” or “nerf” along with specific hero name from 11-01-2020 to 5-28-2021.

Figure 6 shows the frequencies of post titles mentioning “buff” or “nerf” side-by-side and by hero name in our time period. Again, the calls for “buffs” and “nerfs” track well with the metas that have appeared, but some heroes seem more hotly contested than others. The most contested (i.e. most even splits between calls for buffs and nerfs) are Hanzo, Rein, Reaper, and Genji. Of course, these points of contention can come from various sources, like the feeling of “fairness” of play for the user versus the opponent (e.g. Genji, Hanzo), or a somewhat miserable play experience on both sides (e.g. Rein, Reaper). Ultimately, while there are multiple reasons for it, this is clearly capturing different variation than sentiment, so let’s include it in our analysis as well.

Overbuff Metrics

Of course, it’s possible that forum activity is a noisy reflection of simple, objective, and accessible metrics associated with hero balance. To test this, I scrape Overbuff Winrates and Pickrates for each hero and each elo over the 6 month period 10-18-2020 to 4-18-2020. Overbuff does have the potential for sample selection issues, particularly after the option of profile privitization (an issue we’ll dig into later), it’s the best a lot of us have public access to.

A Note on Winrates

We’ve all heard the anecdotes. Winrates go up, until heroes start getting double-picked, and then they start to increase. When heroes become to strong, they are often mirrored, forcing their winrates to zero. To account for this (and somewhat test for it), instead of using just winrate we’ll be using a quadratic winrate term in what follows.

Predicting the Patch

The Data

To answer whether forum activity, win rate and pick rate can predict future balance changes, I’ll integrate the above two data sources (Forum data and Overbuff data) with information from 7 balance patches (10/29, 11/17, 11/19, 12/10, 1/28, 2/18, 3/11). The final dataset will be a balance patch by hero dataset consisting of the following aggregate explanatory metrics: total views, total replies, average sentiment, total buff posts, total nerf posts, average win rate (by elo), and average pick rate (by elo), aggregated over the time window after the prior balance patch and before the next balance patch.

Our dependent variable will be a 0/1 variable on whether the hero recieved a change in the next two balance patches. Due to the relatively low sample size (\(32 \times 7\)), I do not attempt to distinguish positive from negative balance changes for now.

The Method

Given the variables listed above, I’ll conduct three seperate logistic regressions. First, regressing a future balance change on win rates and pick rates by elo. Second, regressing a future balance change on forum metrics. Finally, I’ll regress a future balance change on the combination of the two data sources. This last regression will give us an idea of if forum metrics can provide additional predictive validity over and above just win rates or pick rates.

Predicting Changes with Pickrate and Winrate

First up is the following model

\[P(\text{Future Balance Change} | \text{Aggregate WR/PR Data}) = g(\beta_0 + \sum_{\text{elos}} (\beta_1^{\text{elo}}WR_{\text{elo}} + \beta_2^{\text{elo}}PR_{\text{elo}}) + \varepsilon)\]

where \(g\) handles the fact that our outcome is a \(0/1\) variable. Then we’ll use some post-processing to get the average effects of each of our variables on the probability of a future balance change.

vars mean lower upper
Avg. WR -0.0324868 -0.7346612 0.6696876
Avg. WR2 0.3435003 -0.0079146 0.6949151
Avg. PR 1.5870687 -1.5057089 4.6798462
Bronze WR 0.0584433 -0.1230573 0.2399439
Bronze WR2 -0.0482074 -0.1327486 0.0363339
Bronze PR -0.3625222 -0.9543633 0.2293189
Silv. WR 0.0111743 -0.2302079 0.2525566
Silv. WR2 -0.1321387 -0.2905082 0.0262308
Silv. PR -0.0848494 -1.6619060 1.4922071
Gold WR -0.1799870 -0.5659191 0.2059451
Gold WR2 -0.1567373 -0.3787129 0.0652384
Gold PR -0.6589242 -2.9354520 1.6176036
Plat WR 0.0328308 -0.3418315 0.4074931
Plat WR2 -0.0918695 -0.2220211 0.0382822
Plat PR -0.5003072 -1.9199234 0.9193089
Diam. WR 0.0808547 -0.2201565 0.3818659
Diam. WR2 0.0938898 -0.0813438 0.2691235
Diam PR -0.3624998 -1.5584335 0.8334339
Mast WR 0.1046181 -0.0590011 0.2682374
Mast WR2 -0.0882321 -0.2118841 0.0354198
Mast PR -0.0758558 -0.4601865 0.3084748
Healer 0.2380775 -0.0228934 0.4990485
Tank 0.3319556 0.1528026 0.5111085

Here we see a significant nonlinear relationship between winrates and future balance changes. Moral of the story: don’t listen to people telling you winrates don’t matter, they just aren’t as easily interpreted!

Predicting Changes with Forum Data

Second we have

\[P(\text{Future Balance Change} | \text{Forum Data}) = g(\beta_0 + \beta_1 \text{Sentiment} + \beta_2\text{Buffs} + \beta_3\text{Nerfs} + \beta_4\text{Views} + \beta_4\text{Replies} + \varepsilon)\]

where again \(g\) handles the fact that our outcome is a \(0/1\) variable. Then we’ll use some post-processing to get the average effects of each of our variables on the probability of a future balance change.

vars mean lower upper
Replies -0.0019925 -0.3442328 0.3402478
Replies2 0.0301375 -0.0372320 0.0975071
Views -0.0057345 -0.2609346 0.2494657
Sentiment -0.0052091 -0.0790481 0.0686300
“Buff” 0.0212186 -0.0511389 0.0935761
“Nerf” -0.0415746 -0.2026093 0.1194601
“Nerf”2 0.0238220 -0.0187653 0.0664094
Healer -0.0140269 -0.1897619 0.1617082
Tank 0.2600947 0.0663256 0.4538638

Here we see marginally significant effects of the number of topic replies and the number of posts calling for nerfs on future balance changes, but they are not statistically significant (at 95% confidence).

Predicting Changes with Everything

Lastly we have

\[P(\text{Future Balance Change} | \text{All Data}) = g(\beta_0 + \vec{\beta}_1 \vec{F} + \vec{\beta}_2 \vec{PR} + \vec{\beta}_3 \vec{WR} +\varepsilon)\]

where again \(g\) handles the fact that our outcome is a \(0/1\) variable, \(F\) is all of our forum variables and \(WR/PR\) are the winrates/pickrates for all of our elos.

vars mean lower upper
Replies 0.2883689 -0.1637780 0.7405158
Replies2 -0.0351596 -0.1307498 0.0604305
Views 0.0430104 -0.2199064 0.3059272
Sentiment 0.0079231 -0.0683564 0.0842027
“Buff” -0.0172377 -0.1052137 0.0707383
“Nerf” -0.0684674 -0.2108674 0.0739326
“Nerf”2 0.0088853 -0.0370518 0.0548225
Avg. WR 0.3529789 -0.4127360 1.1186939
Avg. WR2 0.4278046 0.0292879 0.8263213
Avg. PR 0.1311060 -3.1246112 3.3868232
Bronze WR 0.0176470 -0.1566686 0.1919626
Bronze WR2 -0.1029205 -0.2191266 0.0132855
Bronze PR -0.6465270 -1.3228893 0.0298353
Silv. WR 0.0140570 -0.2223770 0.2504910
Silv. WR2 -0.1708302 -0.3434631 0.0018027
Silv. PR 1.5287636 -0.4620864 3.5196135
Gold WR -0.3015441 -0.7502623 0.1471742
Gold WR2 -0.1409125 -0.3465935 0.0647684
Gold PR -1.0689632 -3.2627248 1.1247983
Plat WR -0.2272664 -0.6224207 0.1678880
Plat WR2 -0.0122763 -0.1301495 0.1055970
Plat PR -0.7988460 -1.9888325 0.3911406
Diam. WR 0.1054151 -0.2004750 0.4113052
Diam. WR2 0.0210498 -0.1522999 0.1943996
Diam PR 0.0494570 -1.0371827 1.1360967
Mast WR 0.0369549 -0.1313352 0.2052450
Mast WR2 -0.1255782 -0.2703998 0.0192433
Mast PR 0.1548599 -0.2757008 0.5854206
Healer 0.3576286 0.0976392 0.6176181
Tank 0.2122334 -0.0034956 0.4279624

Finally, while we see significance in winrates and pickrates by elo, any marginal significance of forum characteristics is captured by objective and more easily interpreted variables. Don’t waste your time worrying about the Overwatch Forums mob!

Conclusions

Phew, that turned into quite the report. Let’s go through a short summary of the findings. Firstly, it’s not your imagination, the Official Forums are a hotbed for change/buff/nerf posts. The most (in)famous heroes on the Official Forums lately are Genji, Mercy, McCree, Sombra, and Rein. Moreover, for some reason the Forums really love Mercy (and Junkrat?) and they really hate Doomfist. While calls for nerfs/buffs align really well with the various metas we’ve seen- Sigma/Ball, McCree, etc, some heroes are simultaneously called for nerfs/buffs, usually because they’re weak but hated (Genji, Hanzo, Reaper) or begrudgingly necessary (Rein).

In terms of balance, I find evidence that winrates are predictive of balance changes in a nonlinear way. Moreover, being a tank or healer is predictive of getting rebalanced during this study period. Finally, while number of Replies to a post and calls for nerfs are marginally predictive of getting rebalanced, their predictive power goes away after you include winrates and pickrates. Forums topics do not significantly affect balance changes if you just look at the facts!

Until Next Time!

LS0tCnRpdGxlOiAiUHJlZGljdGluZyB0aGUgUGF0Y2giCmF1dGhvcjogIlNpbmUncyBTdGF0cyIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG9wZW5pbnRybykKYGBgCgojIF8qKlByZWRpY3RpbmcgdGhlIFBhdGNoOiBEbyBXaW5yYXRlLCBQaWNrcmF0ZSwgb3IgSG90IFRvcGljcyBpbiB0aGUgT3ZlcndhdGNoIEZvcnVtcyBQcmVkaWN0IEZ1dHVyZSBCYWxhbmNlIENoYW5nZXM/KipfCgpIaSBldmVyeW9uZSwgU2luZSdzIFN0YXRzIGJhY2sgd2l0aCBhbm90aGVyIHF1ZXN0aW9uOiAqY2FuIHdlIHByZWRpY3QgZnV0dXJlIE92ZXJ3YXRjaCBiYWxhbmNlIGNoYW5nZXMgd2l0aCBwdWJsaWNseSBhdmFpbGFibGUgZGF0YT8qICBPdmVyd2F0Y2ggMiBhbmQgaXQncyBhc3NvY2lhdGVkIGNoYW5nZXMtLXdoZXRoZXIgaXQgYmUgdGhlIDV2NSBmb3JtYXQsIHJvbGUgcGFzc2l2ZXMsIG5lcmZpbmcgQ0MsIG9yIGNvbW1lbnRzIG9uIHNwZWNpZmljIGhlcm9lcy0taGF2ZSBjYXVzZWQgYSBiaWcgdXByb2FyIGluIHRoZSBjb21tdW5pdHkuIEl0J3Mgb25lIG9mIHRoZSBmZXcgdG9waWNzIEkndmUgc2VlbiBwZXJtZWF0ZSBpbnRvIHBsYWNlcyBsaWtlICoqci9PdmVyd2F0Y2hVbml2ZXJzaXR5KiotLWEgY29tbXVuaXR5IHRoYXQgdXN1YWxseSBmb2N1c2VzIG9uIGltcHJvdmVtZW50IG92ZXIgYmFsYW5jZSBjb21wbGFpbnRzLS1idXQgaXQncyBjZXJ0YWlubHkgbm90IHRoZSBmaXJzdCB0aW1lIGZvcnVtLWJhc2VkIGNvbW11bml0aWVzIGhhdmUgY29tbWVudGVkIGVuIG1hc3NlIGFib3V0IGdhbWUgYmFsYW5jZS4gVG9kYXksIEknbSBnb2luZyB0byB1c2UgZGF0YSBmcm9tIE92ZXJidWZmLCBQYXRjaCBOb3RlcywgYW5kIHRoZSBPdmVyd2F0Y2ggRm9ydW1zIHRvIHNlZSB3aGV0aGVyIGEgdXNlciBrZWVwaW5nIHVwLXRvLWRhdGUgb24gdGhlc2UgcGxhdGZvcm1zIG1pZ2h0IHBvdGVudGlhbGx5IGJlIG1vcmUgaW5mb3JtZWQgYWJvdXQgdXBjb21pbmcgYmFsYW5jZSBjaGFuZ2VzIHRoYW4gb25lIHdobyAgZG9lc24ndC4KCiMjICoqVEw7RFIgLSBNYWluIFRha2Vhd2F5cyoqCgpUaGlzIGJsdXJiIGVuZGVkIHVwIHByZXR0eSBsZW5ndGgsIHNvIGhlcmUgYXJlIHRoZSAqKm1haW4gdGFrZWF3YXlzKiogb2YgbXkgZmluZGluZ3MhCgoqKk92ZXJ3YXRjaCBGb3J1bXMqKgoKICAtIEl0J3Mgbm90IHlvdXIgaW1hZ2luYXRpb24sIHRoZSBPZmZpY2lhbCBGb3J1bXMgYXJlIGEgaG90YmVkIGZvciBjaGFuZ2UvYnVmZi9uZXJmIHBvc3RzLgogIC0gVGhlIG1vc3QgKGluKWZhbW91cyBoZXJvZXMgb24gdGhlIE9mZmljaWFsIEZvcnVtcyBsYXRlbHkgYXJlIEdlbmppLCBNZXJjeSwgTWNDcmVlLCBTb21icmEsIGFuZCBSZWluLgogIC0gRm9yIHNvbWUgcmVhc29uLCB0aGUgRm9ydW1zICpyZWFsbHkqIGxvdmUgTWVyY3kgKGFuZCBKdW5rcmF0PykgYW5kIHRoZXkgKnJlYWxseSogaGF0ZSBEb29tZmlzdC4KICAtIENhbGxzIGZvciBuZXJmcy9idWZmcyBhbGlnbiByZWFsbHkgd2VsbCB3aXRoIHRoZSB2YXJpb3VzIG1ldGFzIHdlJ3ZlIHNlZW4tIFNpZ21hL0JhbGwsIE1jQ3JlZSwgZXRjLiAKICAtIFNvbWUgaGVyb2VzIGFyZSBzaW11bHRhbmVvdXNseSBjYWxsZWQgZm9yIG5lcmZzL2J1ZmZzLCB1c3VhbGx5IGJlY2F1c2UgdGhleSdyZSB3ZWFrIGJ1dCBoYXRlZCAoR2VuamksIEhhbnpvLCBSZWFwZXIpIG9yIGJlZ3J1ZGdpbmdseSBuZWNlc3NhcnkgKFJlaW4pCgoqKlJlbGF0aW9uc2hpcCB3aXRoIEJhbGFuY2UgQ2hhbmdlcyoqCgogIC0gV2lucmF0ZXMgKmFyZSBwcmVkaWN0aXZlIG9mIGJhbGFuY2UgY2hhbmdlcyBpbiBhIG5vbmxpbmVhciB3YXkqCiAgLSBCZWluZyBhICp0YW5rIG9yIGhlYWxlciBpcyBwcmVkaWN0aXZlIG9mIGdldHRpbmcgcmViYWxhbmNlZCogZHVyaW5nIHRoaXMgc3R1ZHkgcGVyaW9kCiAgLSAqTnVtYmVyIG9mIFJlcGxpZXMgdG8gYSBwb3N0KiBhbmQgKmNhbGxzIGZvciBuZXJmcyogYXJlIG1hcmdpbmFsbHkgcHJlZGljdGl2ZSBvZiBnZXR0aW5nIHJlYmFsYW5jZWQsIGJ1dCB0aGVpciBwcmVkaWN0aXZlIHBvd2VyIGdvZXMgYXdheSBhZnRlciB5b3UgaW5jbHVkZSB3aW5yYXRlcyBhbmQgcGlja3JhdGVzLiBGb3J1bXMgdG9waWNzIGRvIG5vdCBzaWduaWZpY2FudGx5IGFmZmVjdCBiYWxhbmNlIGNoYW5nZXMhIAogIAogIAoKIyMgKipUaGUgRm9ydW1zKioKClVubGlrZSByL092ZXJ3YXRjaFVuaXZlcnNpdHksIHIvQ29tcGV0aXRpdmVPdmVyd2F0Y2gsIG9yIHIvT3ZlcndhdGNoLCB0aGUgT3ZlcndhdGNoIEdlbmVyYWwgRm9ydW1zIHNlZW0gZXh0cmVtZWx5IGNvbmNlbnRyYXRlZCBvbiB0aGUgYmFsYW5jZSBvZiB0aGUgZ2FtZS4gV2hlbiBJIHZpc2l0IHRoZSBvZmZpY2lhbCBmb3J1bXMsIEkgZ2V0IHRoZSBzZW5zZSB0aGF0IHRoZSAqdmFzdCBtYWpvcml0eSogb2YgcG9zdHMgYXJlIGFib3V0IHdoZXRoZXIgZ2FtZSB1cGRhdGVzIHdpbGwgYmUgb3IgaGF2ZSBiZWVuIGdvb2Qgb3IgY29tcGxldGVseSBkZXN0cnVjdGl2ZSBvZiB0aGUgZ2FtZS4gVGhpcyBtaWdodCBiZSBhIHdheSB0byBjb25uZWN0IHdpdGggb3RoZXIgcGxheWVycywgZGV2ZWxvcCBhbmQgY2hhbmdlIG9uZSdzIG9waW5pb25zLCBidXQgZG8gdGhlc2UgY29uc3RhbnQgZGlzY3Vzc2lvbiBlZmZvcnRzIGVmZmVjdCBjaGFuZ2U/IElzIG15IGludHVpdGlvbiBldmVuIHJpZ2h0LCB0aGF0IHRoZXJlIGFyZSBhIGxvdCBvZiBjb21tZW50cyBhYm91dCBiYWxhbmNlIGFuZCBoZXJvIGNoYW5nZXMsIG9yIGFtIEkganVzdCBwcm9uZSB0byBub3RpY2luZyB0aG9zZSBwb3N0cz8gSSBkZWNpZGVkIHRvIGRpZyBhIGxpdHRsZSBkZWVwZXIuCgojIyMgKipUaGUgRGF0YSoqCgpUbyBjaGVjayBpdCBvdXQsIEkgc2NyYXBlZCBPdmVyd2F0Y2ggRm9ydW0gR2VuZXJhbCBEaXNjdXNzaW9uIHBvc3QgdGl0bGVzLCBudW1iZXIgb2Ygdmlld3MsIGFuZCBudW1iZXIgb2YgcmVwbGllcyBmcm9tIDExLTAxLTIwMjAgdG8gNS0yOC0yMDIxLiBJIHdvdW5kIHVwIHdpdGggYSBkYXRhc2V0IG9mIDMwMzE3IHVuaXF1ZSBwb3N0cyBpbiB0aGF0IHRpbWVzcGFuLCB3aGljaCBzcGFucyBqdXN0IGFib3V0IDggT3ZlcndhdGNoIHJldGFpbCBwYXRjaGVzLgoKIyMjICoqVGhlIEhvdCBUb3BpY3MqKgoKVGhlIGZpcnN0IHRoaW5nIEkgd2FzIGludGVyZXN0ZWQgaW4gaXMgKndoYXQgYXJlIHBlb3BsZSB0YWxraW5nIGFib3V0PyouIFRvIGdldCBhIHNlbnNlIG9mIHRoZSAiaG90IHRvcGljcyIgaW4gdGhlIE92ZXJ3YXRjaCBGb3J1bXMgR2VuZXJhbCBEaXNjdXNzaW9uLCBJIGdlbmVyYXRlZCBhIFdvcmQgQ2xvdWQgb2YgdGhlIG1vc3QgbWVudGlvbmVkIHdvcmRzIGluIHBvc3QgdGl0bGVzIHRoYXQgYXBwZWFyZWQgaW4gdGhlIHRpbWVzcGFuIG9mIG15IGRhdGEsIHNob3duIGluICoqRmlndXJlIDEqKi4gV29yZCBDbG91ZHMgYXJlIGEgZ3JhcGhpY2FsIGRpc3BsYXkgb2YgdGhlIG1vc3QgZnJlcXVlbnRseSBtZW50aW9uZWQgd29yZHMsIHdoZXJlIHJlbGF0aXZlIGZyZXF1ZW5jeSBpcyBpbmRpY2F0ZWQgYnkgdGhlIHNpemUgb2YgdGhlIHdvcmRzLiBSaWdodCBhd2F5LCB3ZSBjYW4gc2VlIHRoYXQgdGhlIG1vc3QgbWVudGlvbmVkIHdvcmRzIGFyZSAqT3ZlcndhdGNoLCBnYW1lLCBPVzIsIHRhbmssIG5lZWQsIGNoYW5nZSwgbmVyZiwqIGFuZCAqYnVmZiouIEl0IGxvb2tzIGxpa2UgaW50dWl0aW9uIGlzIHJpZ2h0LCB0aGF0IGdhbWUgdXBkYXRlcyBhcmUgdGhlIGhvdHRlc3QgdG9waWNzIGluIHRoZSBmb3J1bXMuIAoKCgp8ICFbXSgvdXNlcnMvbXdvbGZmL2Rlc2t0b3Avb3dfaWNvbnMvaG90X3RvcGljcy5wbmcpfCAhW10oL3VzZXJzL213b2xmZi9kZXNrdG9wL293X2ljb25zL2hvdF90b3BpY19oZXJvZXMucG5nKSB8Cnw6LS06fDotLTp8CnwqKkZpZ3VyZSAxLioqIFdvcmRDbG91ZCBvZiBtb3N0IGNvbW1vbiB3b3JkIG1lbnRpb25zIGluIHRoZSBPdmVyd2F0Y2ggRm9ydW0gdGl0bGVzIGZyb20gMTEtMDEtMjAyMCB0byA1LTI4LTIwMjEufCAqKkZpZ3VyZSAyLioqIFdvcmRDbG91ZCBvZiBtb3N0IGNvbW1vbiBoZXJvIG1lbnRpb25zIGluIHRoZSBPdmVyd2F0Y2ggRm9ydW0gdGl0bGVzIGZyb20gMTEtMDEtMjAyMCB0byA1LTI4LTIwMjEufAoKCkJ1dCBzaW5jZSB3ZSBkb24ndCBoYXZlIGFueSBkYXRhIG9uIE9XMiBvciB0aGUgdXBjb21pbmcgdGFuayBjaGFuZ2VzLCBsZXQncyBjb25jZW50cmF0ZSBvbiBoZXJvLXNwZWNpZmljIGNoYW5nZXMgdGhhdCBoYXZlIGJlZW4gbWFkZS4gVG8gZ2V0IGEgc2Vuc2Ugb2YgdGhlIGhvdC10b3BpYyBoZXJvZXMsIHdlIGNhbiBhbHNvIHRha2UgYSBsb29rIGF0IHRoZSBtb3N0IGZyZXF1ZW50bHkgbWVudGlvbmVkIGhlcm9lcyBpbiBmb3J1bSBwb3N0IHRpdGxlcyAoc2hvd24gaW4gKipGaWd1cmUgMioqKS4gV2UgY2FuIHNlZSByaWdodCBhd2F5IHRoYXQgdGhlIG1vc3QgKGluKWZhbW91cyBoZXJvZXMgYXJlIEdlbmppLCBNZXJjeSwgTWNDcmVlLCBTb21icmEsIFNpZ21hLCBSZWFwZXIgYW5kIFJlaW4uIFRoZSBmcmVxdWVuY3kgb2YgaGVybyBtZW50aW9ucyBtaWdodCB0ZWxsIHVzIGFib3V0LCBmb3IgZXhhbXBsZSwgdGhlIGZvcnVtIGRlbW9ncmFwaGljIG9yIHRoZSBzdGF0ZSBvZiBhIGhlcm8uIEJ1dCB0byBhc3Nlc3Mgd2hpY2ggaXQgaXMsIHdlIG5lZWQgdG8gZGlnIGEgbGl0dGxlIG1vcmUgaW50byBob3cgdGhlc2UgaGVyb2VzIGFyZSByZWdhcmRlZCB3aGVuIHRoZXkncmUgbWVudGlvbmVkLgoKIyMjICoqSGVybyBTZW50aW1lbnQqKgoKQXMgYSBmaXJzdCBwYXNzLCB3ZSdyZSBnb2luZyB0byBjaGVjayB3aGV0aGVyIHBvc3QgdGl0bGUgaXMgbW9yZSBsaWtlbHkgdG8gYmUgcG9zaXRpdmUgb3IgbmVnYXRpdmUgaW4gbmF0dXJlIHdoZW4gYSBoZXJvIGlzIG1lbnRpb25lZC4gV2UgZXZhbHVhdGUgdGhpcyB3aXRoIGEgbWV0cmljIGNhbGxlZCAqc2VudGltZW50Ki4KCiMjIyMgKipDYWxjdWxhdGluZyB0aGUgU2VudGltZW50KioKClRvIGNhbGN1bGF0ZSB0aGUgc2VudGltZW50LCB3ZSdyZSBnb2luZyB0byB1c2UgUHl0aG9uJ3MgTmF0dXJhbCBMYW5ndWFnZSBQcm9jZXNzaW5nIFRvb2xraXQgKE5MVEspLiBUaGlzIHBhY2thZ2UgdXNlcyBhIG1vZGVsIGNhbGxlZCBbVkFERVJdKGh0dHBzOi8vb2pzLmFhYWkub3JnL2luZGV4LnBocC9JQ1dTTS9hcnRpY2xlL3ZpZXcvMTQ1NTApIHRvIHByZWRpY3QgdGhlIHNlbnRpbWVudCBvZiBzb2NpYWwgbWVkaWEgdGV4dCBhcyBhIG51bWJlciByYW5naW5nIGZyb20gLTEgKGVudGlyZWx5IG5lZ2F0aXZlKSB0byAxIChlbnRpcmVseSBwb3NpdGl2ZSkuIEknbGwgbGVhdmUgaXQgdXAgdG8geW91IGd1eXMgdG8gZXhwbG9yZSBob3cgZXhhY3RseSB0aGUgbW9kZWwgaXMgdHJhaW5lZCA7KS4KCiMjIyMgKipTb21lIEV4YW1wbGVzKioKCkhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lIGRpZmZpY3VsdGllcyB3aXRoIHRoaXMgbW9kZWwuIEZvciBleGFtcGxlLCBzZW50aW1lbnQgcHJlZGljdGlvbnMgYXJlIG9mdGVuIHF1aXRlIGJhZCBhdCBwcmVkaWN0aW5nIHNhcmNhc20sIGdlbmVyYWxpemluZyB0byB2ZXJ5IGZpZWxkIHNwZWNpZmljIGxpbmdvIChidWZmL25lcmYgd291bGQgbGlrZWx5IG5vdCBiZSBnaXZlbiBhIHNjb3JlKSwgYW5kIHRoZSBzZW50aW1lbnQgY291bGQgZWFzaWx5IGNhcHR1cmUgcG9zaXRpdmUgb3IgbmVnYXRpdmUgYXR0aXR1ZGVzIGFib3V0IG5vbi1iYWxhbmNlIGZlYXR1cmVzIChlLmcuIHNraW5zKS4gVG8gZ2V0IGEgYmV0dGVyIHNlbnNlIG9mIHRoaXMsIGxldCBtZSBzaG93IHlvdSBzb21lIGhlcm8tc3BlY2lmaWMgZXhhbXBsZXM6Cgp8VG9wIFBvc2l0aXZlIEV4YW1wbGVzIHwgU2NvcmUgfCBUb3AgTmVnYXRpdmUgRXhhbXBsZXMgfCBTY29yZSB8Cnw6LS06fDotLTp8Oi0tOnw6LS06fAp8IFRvIG1lLCBubyBoYXJkIGNvdW50ZXIgaGVyb2VzIGxpa2UgV2lkb3cgaXMgYSBncmVhdCBzLi4uIHwgLjkzNCB8IEtJbGwsIGtpbGwsIGtJbGwgR2VuamkgfCAtLjk0NCB8CnwgVGhlIGJlc3Qgd2F5IHRvIGhlbHAgR2Vuamkgd2l0aG91dCBidWZmOiBzaG93IERBTUFHRSBWQUxVRVMgfCAuOTI2IHwgRGVhZCBKdW5rcmF0IHNob3VsZCBTVEFZIERFQUQhIHwgLS44OTIgfAp8IFN1cGVyIEdlbmppLCBTdXBlciBIb2cgYW5kIG5vdyBTdXBlciBCYXAgfCAuOTE0IHwgUmVpbiBzdWljaWRlIGNoYXJnZSByZXN1bHRpbmcgaW4gMSBraWxsID0gUE9URyB8IC0gLjg4MSB8CnwgTWNjcmVlIFRPUCBNT1NUIHBpY2tlZCBoZXJvIGluIGFsbCByYW5rcyBhbmQgMm5kIG1vc3QgcGlja2VkIGhlcm8gaW4gR00gfCAuOTEzIHwgRHZhIG1lY2gga2lsbCBpcyB0aGUgd29yc3QgYmFsYW5jZSBjaGFuZ2Ugc2luY2UgYnJpZyB8IC0uODY5IHwKfCBUaGUgQmVzdCBTeW0gQnVmZiB0aGF0IHdpbGwgbWFrZSBoZXIgc3VwZXIgZnVuIHwgLjkwOCB8IEJhbGwgaXMgc28gdW5iZWxpZXZhYmx5IGJyb2tlbiBpIGhhdGUgY29tcCBub3cgfCAtLjgzNyB8CgpIZXJlLCB3ZSBzZWUgdGhlIGdvb2QgYW5kIHRoZSBiYWQgb2Ygb3VyIHNlbnRpbWVudCBtZWFzdXJlLiBGaXJzdGx5LCB0aGUgbmVnYXRpdmUgc2VudGltZW50cyBsb29rIHByZXR0eSBnb29kLiBBbGwgb2YgdGhlIHN0YXRlbWVudHMgYXJlIGNsZWFybHkgZXhwcmVzc2luZyBuZWdhdGl2ZSBmZWVsaW5ncyBhYm91dCBvciBhc3BlY3RzIG9mIHRoZSBoZXJvIG1lbnRpb25lZC4gSG93ZXZlciwgdGhlIHBvc2l0aXZlIHNlbnRpbWVudHMgYXJlIGEgbWl4ZWQgYmFnLiBUaGUgdG9wIHR3byBhbmQgdGhlIGZpZnRoIGxvb2sgcmVhc29uYWJsZSwgcG9zaXRpdmUgaWRlYXMgYXNzb2NpYXRlZCB3aXRoIHBhcnRpY3VsYXIgaGVyb2VzLCBidXQgdGhlIHRoaXJkIGlzIGNsZWFybHkgYSBtaXNpbnRlcnByZXRhdGlvbiBvZiB0aGUgd29yZCAic3VwZXIiLCBhbmQgdGhlIGZvdXJ0aCBpcyBhdHRlbXB0aW5nIHRvIGNvbnZleSBzb21ldGhpbmcgbmVnYXRpdmUgKGkuZS4gb3ZlcmFidW5kYW5jZSkgYWJvdXQgTWNDcmVlLiBUaGVzZSBzZW50aW1lbnQgcHJlZGljdGlvbnMgYXJlbid0IGdvaW5nIHRvIGJlIHBlcmZlY3QsIGJ1dCB0aGUgaG9wZSBpcyB0aGF0IG1vcmUgb2Z0ZW4gbm90IHdlJ2xsIGdldCB0aGUgYXBwcm9wcmlhdGUgYXNzb2NpYXRpb24uCgojIyMjICoqU2VudGltZW50IERpc3RyaWJ1dGlvbioqCgpUbyBnZXQgYSBzZW5zZSBvZiB3aGF0IG91ciBzZW50aW1lbnQgbWVhc3VyZSBsb29rcyBsaWtlIG92ZXJhbGwsIGxldCdzIHRha2UgYSBsb29rIGF0IHRoZSBkaXN0cmlidXRpb25zIG9mIHNlbnRpbWVudCBhY3Jvc3MgZXZlcnkgaGVybyB0aGF0IHdhcyBtZW50aW9uZWQgaW4gb3VyIGZvcnVtIGRhdGEgZHVyaW5nIHRoZSB0aW1lIHBlcmlvZCB1c2luZyBbYm94IHBsb3RzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Cb3hfcGxvdCkgKHNob3duIGluICoqRmlndXJlIDMqKikuIFZlcnkgaGlnaCBsZXZlbCBpbnRlcnByZXRhdGlvbiBvZiB0aGUgYm94IHBsb3RzOiB0aGUgbG9jYXRpb24gb2YgdGhlIGJveCBzaG93cyB3aGVyZSBtb3N0IG9mIHRoZSBzZW50aW1lbnQgaXMgY29uY2VudHJhdGVkLCBhbmQgdGhlIHNwcmVhZCBvZiB0aGUgYm94IChhbmQgImxpbmVzIiBjb21pbmcgb3V0IG9mIHRoZSBib3gpIHNob3dzIGhvdyB2YXJpYWJsZSB0aGUgc2VudGltZW50IGlzLiAKCgp8IVtdKC91c2Vycy9td29sZmYvZGVza3RvcC9vd19pY29ucy9zZW50aW1lbnRfYm94LnBuZyl8Cnw6LS06fAp8KipGaWd1cmUgMy4qKiBCb3ggcGxvdHMgb2YgT3ZlcndhdGNoIG9mIEZvcnVtIHRpdGxlIHNlbnRpbWVudCBtZW50aW9uaW5nIGEgc3BlY2lmaWMgaGVybyBmcm9tIDExLTAxLTIwMjAgdG8gNS0yOC0yMDIxLnwKClRoZXJlJ3Mgbm8gZG91YnQgdGhhdCBvdXIgc2VudGltZW50IGlzIGEgbm9pc3kgbWVhc3VyZSwgYnV0IHRoZXJlIGFyZSBhIGZldyB0aGluZ3MgdGhhdCBzdGFuZCBvdXQuIEZpcnN0bHksIG1lcmN5IGhhcyBhbiBvdmVyd2hlbG1pbmdseSBwb3NpdGl2ZSBzZW50aW1lbnQsIGFuZCB0aGVyZSBpcyB2ZXJ5IGxpdHRsZSB2YXJpYXRpb24uIEl0IHNlZW1zIGxpa2UgdGhlIGZvcnVtcyBnZW5lcmFsbHkgbGlrZSBtZXJjeS4gVGhpcyBtaWdodCBiZSBiZWNhdXNlIHRoZXJlIGFyZSBhIGxvdCBvZiBoZWFsZXJzIG9yIG1lcmN5IG1haW5zIHRoYXQgdXNlIHRoZSBmb3J1bXMsIG9yIGl0IG1pZ2h0IGJlIGJlY2F1c2Ugc2hlIHRlbmRzIHRvIGhhdmUgaGFkIHRoZSBtb3N0IHBvc2l0aXZlIGNoYW5nZXMgYXNzb2NpYXRlZCB3aXRoIGhlciAoZS5nLiBiYWxhbmNlLCBza2lucywgZXRjLikgZHVyaW5nIHRoZSB0aW1lIGZyYW1lLiBUaGUgc2Vjb25kIG1vc3QgcG9zaXRpdmVseSByZWdhcmRlZCBoZXJvIGlzIHNvbWV3aGF0IHN1cnByaXNpbmdseSBKdW5rcmF0LCB0aG91Z2ggdGhlcmUgc2VlbSB0byBiZSBsZXNzIG9ic2VydmF0aW9ucyBvdmVyYWxsIGFib3V0IGhpbS4gRm9yIGV4YW1wbGUsIHRoZXJlIGFyZSBubyBvdXRsaWVycyAoaW5kaXZpZHVhbCBkb3RzKSBhbmQgdGhlIGRpc3RyaWJ1dGlvbiBpcyByZWxhdGl2ZWx5IHRpZ2h0LiBGaW5hbGx5LCB0aGUgbW9zdCBvYnZpb3VzbHkgbmVnYXRpdmUgc2VudGltZW50IGlzIGFzc29jaWF0ZWQgd2l0aCBEb29tZmlzdC4gVGhpcyBjYW4gY29tZSBmcm9tIGZvbGtzIGRpc2xpa2luZyBEb29tZmlzdCwgZGlzbGlraW5nIHRoYXQgaGUgaXMgc3VwcG9zZWRseSB1bmRlci0gb3Igb3Zlci1wb3dlcmVkLCBldGMuIFdoYXRldmVyIGl0IGlzLCBpdCdzIG5lZ2F0aXZlLgoKVGhlcmUgaXMgY2VydGFpbmx5IG1vcmUgY3VyYXRpbmcgb25lIGNvdWxkIGRvIG9mIHRoZSBzZW50aW1lbnQsIGJ1dCBsZXQncyBzYXZlIHRoYXQgZm9yIGFub3RoZXIgdGltZS4gRm9yIG5vdyB3ZSdsbCBqdXN0IHRyeSBhbmQgZmluZCBvdXQgaWYgdGhlcmUgaXMgc29tZSBpbmRpY2F0aW9uIG9mIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhpcyBzZW50aW1lbnQgbWVhc3VyZSBhbmQgZnV0dXJlIHBhdGNoZXMuCgoKIyMjICoqQ2FsbHMgZm9yIE5lcmZzIGFuZCBCdWZmcyoqCgpBcyBzdGF0ZWQgYWJvdmUsIHRob3VnaCBpdCBvZnRlbiBhZ3JlZXMgd2l0aCBpbnR1aXRpb24sIHRoZXJlIGFyZSBtdWx0aXBsZSBkaWZmaWN1bHRpZXMgYXNzb2NpYXRlZCB3aXRoIG91ciBzZW50aW1lbnQgbWVhc3VyZS4gSWYgb3VyIGludGVyZXN0IGlzIGhvdyBmb3J1bSBkaXNjdXNzaW9uIHByZWRpY3RzIGZ1dHVyZSBwYXRjaGVzLCBjb3VsZCBpbnN0ZWFkIHVzZSBhIHNpbXBsZXIgYXBwcm9hY2ggZ2V0dGluZyBhdCB0aGUgaGVhcnQgb2YgdGhlIG1hdHRlcjogKmhvdyBvZnRlbiBpcyBhIGhlcm8gbmFtZSBtZW50aW9uZWQgaW4gdGhlIHNhbWUgdGl0bGUgYXMgdGhlIHdvcmRzICJidWZmIiBvciAibmVyZiI/Ki4KCioqRmlndXJlIDQqKiBhbmQgKipGaWd1cmUgNSoqIHNob3cgV29yZCBDbG91ZHMgb2YgaGVybyBuYW1lcyBhcHBlYXJpbmcgaW4gdGhlIHNhbWUgdGl0bGUgYXMgdGhlIHdvcmRzICJidWZmIiBhbmQgIm5lcmYiLCByZXNwZWN0aXZlbHksIGZyb20gMTEtMDEtMjAyMCB0byA1LTI4LTIwMjEuIFRoZSB0b3AgaGVyb2VzIGluIHRoZSAiYnVmZiIgY2F0ZWdvcnkgYXJlIEdlbmppLCBPcmlzYSwgUmVhcGVyLCBNb2lyYSwgRHZhLCBhbmQgU29tYnJhLiBUaGUgdG9wIGhlcm9lcyBpbiB0aGUgIm5lcmYiIGNhdGVnb3J5IGFyZSBNY0NyZWUsIEJhbGwsIFNpZ21hLCBNZXJjeSwgYW5kIFJlYXBlci4gcwoKfCFbXSgvdXNlcnMvbXdvbGZmL2Rlc2t0b3Avb3dfaWNvbnMvYnVmZmNsb3VkLnBuZyl8IVtdKC91c2Vycy9td29sZmYvZGVza3RvcC9vd19pY29ucy9uZXJmY2xvdWQucG5nKXwKfDotLTp8Oi0tOnwKfCoqRmlndXJlIDQqKi4gV29yZCBDbG91ZCBvZiBtb3N0IGNvbW1vbiBoZXJvcyBtZW50aW9uZWQgaW4gT3ZlcndhdGNoIEZvcnVtcyB0aXRsZXMgYWxvbmcgd2l0aCB0aGUgd29yZCAiYnVmZiIgZnJvbSAxMS0wMS0yMDIwIHRvIDUtMjgtMjAyMS58ICoqRmlndXJlIDUuKiogV29yZCBDbG91ZCBvZiBtb3N0IGNvbW1vbiBoZXJvcyBtZW50aW9uZWQgaW4gT3ZlcndhdGNoIEZvcnVtcyB0aXRsZXMgYWxvbmcgd2l0aCB0aGUgd29yZCAibmVyZiIgZnJvbSAxMS0wMS0yMDIwIHRvIDUtMjgtMjAyMS4gfAoKClRoZXNlIHRyYWNrIGV4dHJlbWVseSB3ZWxsIHdpdGggdGhlIHRpbWUgcGVyaW9kLSB0aGUgc2lnbWEtYmFsbCB0YW5rIG1ldGEgYW5kIG5vdyB0aGUgTWNDcmVlIG1ldGEsIHNvIG5vdCBhbHRvZ2V0aGVyIHN1cHJpc2luZywgYnV0IHRoZXJlIGFyZSBzb21lIGN1cmlvdXNpdGllcy4gRm9yIGV4YW1wbGUsIGhvdyBpcyBNZXJjeSBvZnRlbiBiZWluZyBjaXRlZCBpbiB1bmlzb24gd2l0aCBuZXJmcyB3aGlsZSBoYXZpbmcgYSBsYXJnZWx5IHBvc2l0aXZlIHNlbnRpbWVudD8gT3IsIGhvdyBpcyByZWFwZXIgaW4gdGhlIHRvcCBoZXJvZXMgbWVudGlvbmVkIGZvciBib3RoICJidWZmcyIgYW5kICJuZXJmcyI/IFNpbmNlIHRoZSBmaXJzdCBxdWVzdGlvbiBtaWdodCBoYXZlIGluIGxhcmdlIHBhcnQgdG8gZG8gd2l0aCBjb3NtZXRpY3MgKHdoaWNoIGlzIG91dHNpZGUgb2Ygb3VyIHNjb3BlIG9mIGludGVyZXN0KSwgbGV0J3MgZm9jdXMgb24gdGhlIHNlY29uZC4gCgp8IVtdKC91c2Vycy9td29sZmYvZGVza3RvcC9vd19pY29ucy9uZXJmYnVmZnMucG5nKXwKfDotLTp8CnwqKkZpZ3VyZSA2LioqIEZyZXF1ZW5jaWVzIG9mIE92ZXJ3YXRjaCBGb3J1bSB0aXRsZXMgbWVudGlvbmluZyAiYnVmZiIgb3IgIm5lcmYiIGFsb25nIHdpdGggc3BlY2lmaWMgaGVybyBuYW1lIGZyb20gMTEtMDEtMjAyMCB0byA1LTI4LTIwMjEufAoKKipGaWd1cmUgNioqIHNob3dzIHRoZSBmcmVxdWVuY2llcyBvZiBwb3N0IHRpdGxlcyBtZW50aW9uaW5nICJidWZmIiBvciAibmVyZiIgc2lkZS1ieS1zaWRlIGFuZCBieSBoZXJvIG5hbWUgaW4gb3VyIHRpbWUgcGVyaW9kLiBBZ2FpbiwgdGhlIGNhbGxzIGZvciAiYnVmZnMiIGFuZCAibmVyZnMiIHRyYWNrIHdlbGwgd2l0aCB0aGUgbWV0YXMgdGhhdCBoYXZlIGFwcGVhcmVkLCBidXQgc29tZSBoZXJvZXMgc2VlbSBtb3JlIGhvdGx5IGNvbnRlc3RlZCB0aGFuIG90aGVycy4gVGhlIG1vc3QgY29udGVzdGVkIChpLmUuIG1vc3QgZXZlbiBzcGxpdHMgYmV0d2VlbiBjYWxscyBmb3IgYnVmZnMgYW5kIG5lcmZzKSBhcmUgSGFuem8sIFJlaW4sIFJlYXBlciwgYW5kIEdlbmppLiBPZiBjb3Vyc2UsIHRoZXNlIHBvaW50cyBvZiBjb250ZW50aW9uIGNhbiBjb21lIGZyb20gdmFyaW91cyBzb3VyY2VzLCBsaWtlIHRoZSBmZWVsaW5nIG9mICJmYWlybmVzcyIgb2YgcGxheSBmb3IgdGhlIHVzZXIgdmVyc3VzIHRoZSBvcHBvbmVudCAoZS5nLiBHZW5qaSwgSGFuem8pLCBvciBhIHNvbWV3aGF0IG1pc2VyYWJsZSBwbGF5IGV4cGVyaWVuY2Ugb24gYm90aCBzaWRlcyAoZS5nLiBSZWluLCBSZWFwZXIpLiBVbHRpbWF0ZWx5LCB3aGlsZSB0aGVyZSBhcmUgbXVsdGlwbGUgcmVhc29ucyBmb3IgaXQsIHRoaXMgaXMgY2xlYXJseSBjYXB0dXJpbmcgZGlmZmVyZW50IHZhcmlhdGlvbiB0aGFuIHNlbnRpbWVudCwgc28gbGV0J3MgaW5jbHVkZSBpdCBpbiBvdXIgYW5hbHlzaXMgYXMgd2VsbC4gCgojIyAqKk92ZXJidWZmIE1ldHJpY3MqKgoKT2YgY291cnNlLCBpdCdzIHBvc3NpYmxlIHRoYXQgZm9ydW0gYWN0aXZpdHkgaXMgYSBub2lzeSByZWZsZWN0aW9uIG9mIHNpbXBsZSwgb2JqZWN0aXZlLCBhbmQgYWNjZXNzaWJsZSBtZXRyaWNzIGFzc29jaWF0ZWQgd2l0aCBoZXJvIGJhbGFuY2UuIFRvIHRlc3QgdGhpcywgSSBzY3JhcGUgT3ZlcmJ1ZmYgV2lucmF0ZXMgYW5kIFBpY2tyYXRlcyBmb3IgZWFjaCBoZXJvIGFuZCBlYWNoIGVsbyBvdmVyIHRoZSA2IG1vbnRoIHBlcmlvZCAxMC0xOC0yMDIwIHRvIDQtMTgtMjAyMC4gT3ZlcmJ1ZmYgZG9lcyBoYXZlIHRoZSBwb3RlbnRpYWwgZm9yIHNhbXBsZSBzZWxlY3Rpb24gaXNzdWVzLCBwYXJ0aWN1bGFybHkgYWZ0ZXIgdGhlIG9wdGlvbiBvZiBwcm9maWxlIHByaXZpdGl6YXRpb24gKGFuIGlzc3VlIHdlJ2xsIGRpZyBpbnRvIGxhdGVyKSwgaXQncyB0aGUgYmVzdCBhIGxvdCBvZiB1cyBoYXZlIHB1YmxpYyBhY2Nlc3MgdG8uCgojIyMgQSBOb3RlIG9uIFdpbnJhdGVzCgpXZSd2ZSBhbGwgaGVhcmQgdGhlIGFuZWNkb3Rlcy4gV2lucmF0ZXMgZ28gdXAsIHVudGlsIGhlcm9lcyBzdGFydCBnZXR0aW5nIGRvdWJsZS1waWNrZWQsIGFuZCB0aGVuIHRoZXkgc3RhcnQgdG8gaW5jcmVhc2UuIFdoZW4gaGVyb2VzIGJlY29tZSB0byBzdHJvbmcsIHRoZXkgYXJlIG9mdGVuIG1pcnJvcmVkLCBmb3JjaW5nIHRoZWlyIHdpbnJhdGVzIHRvIHplcm8uIFRvIGFjY291bnQgZm9yIHRoaXMgKGFuZCBzb21ld2hhdCB0ZXN0IGZvciBpdCksIGluc3RlYWQgb2YgdXNpbmcganVzdCB3aW5yYXRlIHdlJ2xsIGJlIHVzaW5nIGEgcXVhZHJhdGljIHdpbnJhdGUgdGVybSBpbiB3aGF0IGZvbGxvd3MuCgojIyAqKlByZWRpY3RpbmcgdGhlIFBhdGNoKioKCgoKIyMjICoqVGhlIERhdGEqKgoKVG8gYW5zd2VyIHdoZXRoZXIgZm9ydW0gYWN0aXZpdHksIHdpbiByYXRlIGFuZCBwaWNrIHJhdGUgY2FuIHByZWRpY3QgZnV0dXJlIGJhbGFuY2UgY2hhbmdlcywgSSdsbCBpbnRlZ3JhdGUgdGhlIGFib3ZlIHR3byBkYXRhIHNvdXJjZXMgKEZvcnVtIGRhdGEgYW5kIE92ZXJidWZmIGRhdGEpIHdpdGggaW5mb3JtYXRpb24gZnJvbSA3IGJhbGFuY2UgcGF0Y2hlcyAoMTAvMjksIDExLzE3LCAxMS8xOSwgMTIvMTAsIDEvMjgsIDIvMTgsIDMvMTEpLiBUaGUgZmluYWwgZGF0YXNldCB3aWxsIGJlIGEgYmFsYW5jZSBwYXRjaCBieSBoZXJvIGRhdGFzZXQgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nIGFnZ3JlZ2F0ZSBleHBsYW5hdG9yeSBtZXRyaWNzOiB0b3RhbCB2aWV3cywgdG90YWwgcmVwbGllcywgYXZlcmFnZSBzZW50aW1lbnQsIHRvdGFsIGJ1ZmYgcG9zdHMsIHRvdGFsIG5lcmYgcG9zdHMsIGF2ZXJhZ2Ugd2luIHJhdGUgKGJ5IGVsbyksIGFuZCBhdmVyYWdlIHBpY2sgcmF0ZSAoYnkgZWxvKSwgYWdncmVnYXRlZCBvdmVyIHRoZSB0aW1lIHdpbmRvdyBhZnRlciB0aGUgcHJpb3IgYmFsYW5jZSBwYXRjaCBhbmQgYmVmb3JlIHRoZSBuZXh0IGJhbGFuY2UgcGF0Y2guIAoKT3VyIGRlcGVuZGVudCB2YXJpYWJsZSB3aWxsIGJlIGEgMC8xIHZhcmlhYmxlIG9uIHdoZXRoZXIgdGhlIGhlcm8gcmVjaWV2ZWQgYSBjaGFuZ2UgaW4gdGhlIG5leHQgdHdvIGJhbGFuY2UgcGF0Y2hlcy4gRHVlIHRvIHRoZSByZWxhdGl2ZWx5IGxvdyBzYW1wbGUgc2l6ZSAoJDMyIFx0aW1lcyA3JCksIEkgZG8gbm90IGF0dGVtcHQgdG8gZGlzdGluZ3Vpc2ggcG9zaXRpdmUgZnJvbSBuZWdhdGl2ZSBiYWxhbmNlIGNoYW5nZXMgZm9yIG5vdy4KCgpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0Kb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpCm9wdGlvbnMoZHBseXIud2Fybi5jb25mbGljdHMgPSBGQUxTRSkKCiMgUmVhZCBpbiBGb3J1bSBEYXRhCmRmIDwtIHJlYWQuY3N2MignL3VzZXJzL213b2xmZi9kZXNrdG9wL293Zl9kYXRhLmNzdicsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGLCBzZXA9JywnKQoKIyBSZWFkIGluIFRyZW5kIERhdGUKb3dfY3N2IDwtIHJlYWQuY3N2KCcvdXNlcnMvbXdvbGZmL2Rlc2t0b3Avb3dfdHJlbmRfYWxsX2NsZWFuLmNzdicpCm93X2NzdiRYMCA8LSBhcy5udW1lcmljKG93X2NzdiRYMCkKb3dfY3N2JFgxIDwtIGFzLm51bWVyaWMob3dfY3N2JFgxKQpjb2xuYW1lcyhvd19jc3YpIDwtIGMoJ0luZGV4JywgJ1dpbnJhdGUnLCAnUGlja3JhdGUnLCAnRWxvJywgJ0hlcm8nKQpvd19jc3YkRGF0ZSA8LSBhcy5EYXRlKCIyMDIwLTEwLTE4IikgKyBvd19jc3YkSW5kZXgKCiMgUmVhZCBpbiBQYXRjaCBOb3RlIERhdGEKcGF0Y2hfbm90ZXMgPC0gcmVhZC5jc3YoJy91c2Vycy9td29sZmYvZGVza3RvcC9zY3JhcGVkX3BhdGNoX25vdGVzLmNzdicpCmhlcm9fZGF0ZSA8LSBwYXRjaF9ub3Rlc1ssYygnRGF0ZScsICdIZXJvZXMnKV0KaGVyb19kYXRlIDwtIGhlcm9fZGF0ZVtvcmRlcihoZXJvX2RhdGUkSGVyb2VzKSwgXQpoZXJvX2RhdGUkZGF0ZV9udW0gPC0gYXMuRGF0ZShoZXJvX2RhdGUkRGF0ZSwgZm9ybWF0ID0gJyAlQiAlZCwgJVknKQpoZXJvX2RhdGUgPC0gaGVyb19kYXRlWyxjKCdIZXJvZXMnLCAnZGF0ZV9udW0nKV0KYGBgCgoKIyMjICoqVGhlIE1ldGhvZCoqCgpHaXZlbiB0aGUgdmFyaWFibGVzIGxpc3RlZCBhYm92ZSwgSSdsbCBjb25kdWN0IHRocmVlIHNlcGVyYXRlIGxvZ2lzdGljIHJlZ3Jlc3Npb25zLiBGaXJzdCwgcmVncmVzc2luZyBhIGZ1dHVyZSBiYWxhbmNlIGNoYW5nZSBvbiB3aW4gcmF0ZXMgYW5kIHBpY2sgcmF0ZXMgYnkgZWxvLiBTZWNvbmQsIHJlZ3Jlc3NpbmcgYSBmdXR1cmUgYmFsYW5jZSBjaGFuZ2Ugb24gZm9ydW0gbWV0cmljcy4gRmluYWxseSwgSSdsbCByZWdyZXNzIGEgZnV0dXJlIGJhbGFuY2UgY2hhbmdlIG9uIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgdHdvIGRhdGEgc291cmNlcy4gVGhpcyBsYXN0IHJlZ3Jlc3Npb24gd2lsbCBnaXZlIHVzIGFuIGlkZWEgb2YgaWYgZm9ydW0gbWV0cmljcyBjYW4gcHJvdmlkZSAqYWRkaXRpb25hbCogcHJlZGljdGl2ZSB2YWxpZGl0eSBvdmVyIGFuZCBhYm92ZSBqdXN0IHdpbiByYXRlcyBvciBwaWNrIHJhdGVzLgoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cmhlcm9fZGF0ZVssJ3BhdGNoZWQnXSA8LSAxCmhlcm9fZGF0ZSA8LSBoZXJvX2RhdGVbb3JkZXIoaGVyb19kYXRlJGRhdGVfbnVtKSxdICU+JSBwaXZvdF93aWRlcihuYW1lc19mcm9tPWRhdGVfbnVtLCB2YWx1ZXNfZnJvbT1wYXRjaGVkKQoKZm9yIChjb2wgaW4gY29sbmFtZXMoaGVyb19kYXRlKVsyOjhdKXsKICBoZXJvX2RhdGVbaXMubmEoaGVyb19kYXRlWyxjb2xdKSxjb2xdIDwtIDAKfQpkYXRlcyA8LSBjb2xuYW1lcyhoZXJvX2RhdGUpWzI6OF0KCiMgR2V0IG1ldHJpY3MgZnJvbSBGb3J1bXMgRGF0YQpkZlssJ1gnXSA8LSBOVUxMCmZvcihpZHggaW4gMjo4KXsKICB0cnlDYXRjaChkZlssZGF0ZXNbaWR4XV0gPC0gYXMuRGF0ZShkZiRkYXRlKSA8IGFzLkRhdGUoZGF0ZXNbaWR4XSkgJiBhcy5EYXRlKGRmJGRhdGUpID49IGFzLkRhdGUoZGF0ZXNbaWR4IC0gMV0pLCBlcnJvcj1mdW5jdGlvbihlKXsKICAgIAogIH0pCn0KZGZbLGRhdGVzWzFdXSA8LSBhcy5EYXRlKGRmJGRhdGUpIDwgYXMuRGF0ZShkYXRlc1sxXSkKCnBhdGNoMSA8LSBkZltkZlssZGF0ZXNbMV1dID09IFRSVUUsXQpwYXRjaDIgPC0gZGZbZGZbLGRhdGVzWzJdXSA9PSBUUlVFLF0KcGF0Y2gzIDwtIGRmW2RmWyxkYXRlc1szXV0gPT0gVFJVRSxdCnBhdGNoNCA8LSBkZltkZlssZGF0ZXNbNF1dID09IFRSVUUsXQpwYXRjaDUgPC0gZGZbZGZbLGRhdGVzWzVdXSA9PSBUUlVFLF0KcGF0Y2g2IDwtIGRmW2RmWyxkYXRlc1s2XV0gPT0gVFJVRSxdCnBhdGNoNyA8LSBkZltkZlssZGF0ZXNbN11dID09IFRSVUUsXQoKCmxpYnJhcnkoc3RyaW5ncikKY29sbGFwc2VfZGF0YSA8LSBmdW5jdGlvbihwYXRjaDIpewogIHBhdGNoMiRoZXJvX2J1ZmZfaW5kID0gYXMuaW50ZWdlcihwYXRjaDIkaGVyb19wb3N0MiA9PSBwYXRjaDIkaGVyb19idWZmICYgcGF0Y2gyJGhlcm9fcG9zdDIgIT0gJycpCiAgcGF0Y2gyJGhlcm9fbmVyZl9pbmQgPSBhcy5pbnRlZ2VyKHBhdGNoMiRoZXJvX3Bvc3QyID09IHBhdGNoMiRoZXJvX25lcmYgICYgcGF0Y2gyJGhlcm9fcG9zdDIgIT0gJycpCiAgcGF0Y2gyJHJlcGxpZXNbZ3JlcGwoJ2snLCBwYXRjaDIkcmVwbGllcyldID0gYXMubnVtZXJpYyhnc3ViKCdrJywgJycsIHBhdGNoMiRyZXBsaWVzW2dyZXBsKCdrJywgcGF0Y2gyJHJlcGxpZXMpXSkpICogMTAwMAogIHBhdGNoMiR2aWV3c1tncmVwbCgnaycsIHBhdGNoMiR2aWV3cyldID0gYXMubnVtZXJpYyhnc3ViKCdrJywgJycsIHBhdGNoMiR2aWV3c1tncmVwbCgnaycsIHBhdGNoMiR2aWV3cyldKSkgKiAxMDAwCiAgcmV0dXJuKHBhdGNoMiAlPiUgZ3JvdXBfYnkoaGVyb19wb3N0MikgJT4lCiAgICBzdW1tYXJpemUoYWxsX3JlcGxpZXM9c3VtKGFzLm51bWVyaWMocmVwbGllcykpLCBhbGxfdmlld3M9c3VtKGFzLm51bWVyaWModmlld3MpKSwgCiAgICAgICAgICAgICBhdmdfbmVnPW1lYW4oYXMubnVtZXJpYyhuZWcpLCBuYS5ybT1UKSwgYXZnX25ldT1tZWFuKGFzLm51bWVyaWMobmV1LjEpLCBuYS5ybT1UKSwgYXZnX3Bvcz1tZWFuKGFzLm51bWVyaWMocG9zKSwgbmEucm09VCksIGF2Z19jb21wb3VuZD1tZWFuKGFzLm51bWVyaWMoY29tcG91bmQpLCBuYS5ybT1UKSwKICAgICAgICAgICAgc3VtX2J1ZmY9c3VtKGhlcm9fYnVmZl9pbmQpLCBzdW1fbmVyZj1zdW0oaGVyb19uZXJmX2luZCkpKQp9CgpoZXJvX2RhdGUkaGVyb19wb3N0MiA8LSB0b2xvd2VyKGhlcm9fZGF0ZSRIZXJvZXMpCmhlcm9fZGF0ZSRwYXRjaGVkID0gMQoKcGF0Y2gyX2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoMikgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1syXV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2gzX2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoMykgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1syXV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2g0X2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoNCkgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1s0XV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2g1X2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoNSkgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1s1XV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2g2X2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoNSkgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1s2XV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2g3X2NvbGxhcHNlZCA8LSBjb2xsYXBzZV9kYXRhKHBhdGNoNSkgJT4lIGxlZnRfam9pbihoZXJvX2RhdGVbaGVyb19kYXRlWyxkYXRlc1s3XV0gPT0gMSxjKCdoZXJvX3Bvc3QyJywgJ3BhdGNoZWQnKV0sIGJ5PSdoZXJvX3Bvc3QyJykKCmFsbF9wYXRjaGVzIDwtIGJpbmRfcm93cygKICBwYXRjaDJfY29sbGFwc2VkLCBwYXRjaDNfY29sbGFwc2VkLCBwYXRjaDRfY29sbGFwc2VkLCBwYXRjaDVfY29sbGFwc2VkLAogIHBhdGNoNl9jb2xsYXBzZWQsIHBhdGNoN19jb2xsYXBzZWQpCmFsbF9wYXRjaGVzIDwtIGFsbF9wYXRjaGVzW2FsbF9wYXRjaGVzJGhlcm9fcG9zdDIgIT0gJycsXQphbGxfcGF0Y2hlcyRwYXRjaGVkW2lzLm5hKGFsbF9wYXRjaGVzJHBhdGNoZWQpXSA8LSAwCmBgYAoKCmBgYHtyLCBlY2hvPUZBTFNFfQpmb3IoaWR4IGluIDI6OCl7CiAgdHJ5Q2F0Y2goCiAgb3dfY3N2WyxkYXRlc1tpZHhdXSA8LSBhcy5EYXRlKG93X2NzdiREYXRlKSA8IGFzLkRhdGUoZGF0ZXNbaWR4XSkgJiBhcy5EYXRlKG93X2NzdiREYXRlKSA+PSBhcy5EYXRlKGRhdGVzW2lkeCAtIDFdKSwKICBlcnJvcj1mdW5jdGlvbihlKXsKICAgIAogIH0pCn0Kb3dfY3N2WyxkYXRlc1sxXV0gPC0gYXMuRGF0ZShvd19jc3YkZGF0ZSkgPCBhcy5EYXRlKGRhdGVzWzFdKQoKCgpwYXRjaDEgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbMV1dID09IFRSVUUsXQpwYXRjaDIgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbMl1dID09IFRSVUUsXQpwYXRjaDMgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbM11dID09IFRSVUUsXQpwYXRjaDQgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbNF1dID09IFRSVUUsXQpwYXRjaDUgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbNV1dID09IFRSVUUsXQpwYXRjaDYgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbNl1dID09IFRSVUUsXQpwYXRjaDcgPC0gb3dfY3N2W293X2NzdlssZGF0ZXNbN11dID09IFRSVUUsXQoKCmxpYnJhcnkoc3RyaW5ncikKY29sbGFwc2VfZGF0YTIgPC0gZnVuY3Rpb24ocGF0Y2gyKXsKICBwYXRjaDJbLCdoZXJvX3Bvc3QyJ10gPC0gcGF0Y2gyJEhlcm8KICBwYXRjaDIgPC0gcGF0Y2gyWyxjKCdXaW5yYXRlJywgJ1BpY2tyYXRlJywgJ0VsbycsICdoZXJvX3Bvc3QyJyldCiAgcGF0Y2gyIDwtIHBhdGNoMiAlPiUgZ3JvdXBfYnkoaGVyb19wb3N0MiwgRWxvKSAlPiUKICAgIHN1bW1hcml6ZShhdmdfd3I9bWVhbihXaW5yYXRlLCBuYS5ybT1UKSwgYXZnX3ByPW1lYW4oUGlja3JhdGUsIG5hLnJtPVQpKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb209RWxvLCB2YWx1ZXNfZnJvbT1jKGF2Z193ciwgYXZnX3ByKSwgbmFtZXNfc2VwPScuJykKICByZXR1cm4ocGF0Y2gyKQp9CgpwYXRjaDJfY29sbGFwc2VkMiA8LSBjb2xsYXBzZV9kYXRhMihwYXRjaDIpCnBhdGNoM19jb2xsYXBzZWQyIDwtIGNvbGxhcHNlX2RhdGEyKHBhdGNoMykKcGF0Y2g0X2NvbGxhcHNlZDIgPC0gY29sbGFwc2VfZGF0YTIocGF0Y2g0KQpwYXRjaDVfY29sbGFwc2VkMiA8LSBjb2xsYXBzZV9kYXRhMihwYXRjaDUpCnBhdGNoNl9jb2xsYXBzZWQyIDwtIGNvbGxhcHNlX2RhdGEyKHBhdGNoNikKcGF0Y2g3X2NvbGxhcHNlZDIgPC0gY29sbGFwc2VfZGF0YTIocGF0Y2g3KQoKcGF0Y2gyX2Z1bGwgPC0gcGF0Y2gyX2NvbGxhcHNlZCAlPiUgbGVmdF9qb2luKHBhdGNoMl9jb2xsYXBzZWQyLCBieT0naGVyb19wb3N0MicpCnBhdGNoM19mdWxsIDwtIHBhdGNoM19jb2xsYXBzZWQgJT4lIGxlZnRfam9pbihwYXRjaDNfY29sbGFwc2VkMiwgYnk9J2hlcm9fcG9zdDInKQpwYXRjaDRfZnVsbCA8LSBwYXRjaDRfY29sbGFwc2VkICU+JSBsZWZ0X2pvaW4ocGF0Y2g0X2NvbGxhcHNlZDIsIGJ5PSdoZXJvX3Bvc3QyJykKcGF0Y2g1X2Z1bGwgPC0gcGF0Y2g1X2NvbGxhcHNlZCAlPiUgbGVmdF9qb2luKHBhdGNoNV9jb2xsYXBzZWQyLCBieT0naGVyb19wb3N0MicpCnBhdGNoNl9mdWxsIDwtIHBhdGNoNl9jb2xsYXBzZWQgJT4lIGxlZnRfam9pbihwYXRjaDZfY29sbGFwc2VkMiwgYnk9J2hlcm9fcG9zdDInKQpwYXRjaDdfZnVsbCA8LSBwYXRjaDdfY29sbGFwc2VkICU+JSBsZWZ0X2pvaW4ocGF0Y2g3X2NvbGxhcHNlZDIsIGJ5PSdoZXJvX3Bvc3QyJykKCnBhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdiYXB0aXN0ZScsICdwYXRjaGVkJ10gPSAxCnBhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdsdWNpbycsICdwYXRjaGVkJ10gPSAxCnBhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdiYWxsJywgJ3BhdGNoZWQnXSA9IDEKcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J2R2YScsICdwYXRjaGVkJ10gPSAxCnBhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdyZWluJywgJ3BhdGNoZWQnXSA9IDEKCiNwYXRjaDJfZnVsbFtwYXRjaDJfZnVsbCRoZXJvX3Bvc3QyPT0nZWNobycsICdwYXRjaGVkJ10gPSAtMQojcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J3RyYWNlcicsICdwYXRjaGVkJ10gPSAtMQojcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J3plbnlhdHRhJywgJ3BhdGNoZWQnXSA9IC0xCiNwYXRjaDJfZnVsbFtwYXRjaDJfZnVsbCRoZXJvX3Bvc3QyPT0nb3Jpc2EnLCAncGF0Y2hlZCddID0gMQojcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J3JlYXBlcicsICdwYXRjaGVkJ10gPSAxCiNwYXRjaDJfZnVsbFtwYXRjaDJfZnVsbCRoZXJvX3Bvc3QyPT0nd2luc3RvbicsICdwYXRjaGVkJ10gPSAxCgojcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J2dlbmppJywgJ3BhdGNoZWQnXSA9IDEKI3BhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdtZWknLCAncGF0Y2hlZCddID0gMQojcGF0Y2gyX2Z1bGxbcGF0Y2gyX2Z1bGwkaGVyb19wb3N0Mj09J3BoYXJhaCcsICdwYXRjaGVkJ10gPSAxCiNwYXRjaDJfZnVsbFtwYXRjaDJfZnVsbCRoZXJvX3Bvc3QyPT0ncmVhcGVyJywgJ3BhdGNoZWQnXSA9IDEKI3BhdGNoMl9mdWxsW3BhdGNoMl9mdWxsJGhlcm9fcG9zdDI9PSdzaWdtYScsICdwYXRjaGVkJ10gPSAxCiNwYXRjaDJfZnVsbFtwYXRjaDJfZnVsbCRoZXJvX3Bvc3QyPT0nemFyeWEnLCAncGF0Y2hlZCddID0gLTEKCnBhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdiYXB0aXN0ZScsICdwYXRjaGVkJ10gPSAtMQpwYXRjaDRfZnVsbFtwYXRjaDRfZnVsbCRoZXJvX3Bvc3QyPT0ncmVpbicsICdwYXRjaGVkJ10gPSAxCnBhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdkdmEnLCAncGF0Y2hlZCddID0gMQpwYXRjaDRfZnVsbFtwYXRjaDRfZnVsbCRoZXJvX3Bvc3QyPT0nZWNobycsICdwYXRjaGVkJ10gPSAtMQpwYXRjaDRfZnVsbFtwYXRjaDRfZnVsbCRoZXJvX3Bvc3QyPT0ndHJhY2VyJywgJ3BhdGNoZWQnXSA9IC0xCnBhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSd6ZW55YXR0YScsICdwYXRjaGVkJ10gPSAtMQojcGF0Y2g0X2Z1bGxbcGF0Y2g0X2Z1bGwkaGVyb19wb3N0Mj09J29yaXNhJywgJ3BhdGNoZWQnXSA9IDEKI3BhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdyZWFwZXInLCAncGF0Y2hlZCddID0gMQojcGF0Y2g0X2Z1bGxbcGF0Y2g0X2Z1bGwkaGVyb19wb3N0Mj09J3dpbnN0b24nLCAncGF0Y2hlZCddID0gMQojcGF0Y2g0X2Z1bGxbcGF0Y2g0X2Z1bGwkaGVyb19wb3N0Mj09J2dlbmppJywgJ3BhdGNoZWQnXSA9IDEKI3BhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdtZWknLCAncGF0Y2hlZCddID0gMQojcGF0Y2g0X2Z1bGxbcGF0Y2g0X2Z1bGwkaGVyb19wb3N0Mj09J3BoYXJhaCcsICdwYXRjaGVkJ10gPSAxCiNwYXRjaDRfZnVsbFtwYXRjaDRfZnVsbCRoZXJvX3Bvc3QyPT0ncmVhcGVyJywgJ3BhdGNoZWQnXSA9IDEKI3BhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdzaWdtYScsICdwYXRjaGVkJ10gPSAxCiNwYXRjaDRfZnVsbFtwYXRjaDRfZnVsbCRoZXJvX3Bvc3QyPT0nemFyeWEnLCAncGF0Y2hlZCddID0gLTEKI3BhdGNoNF9mdWxsW3BhdGNoNF9mdWxsJGhlcm9fcG9zdDI9PSdiYWxsJywgJ3BhdGNoZWQnXSA9IC0xCgoKCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdlY2hvJywgJ3BhdGNoZWQnXSA9IC0xCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSd0cmFjZXInLCAncGF0Y2hlZCddID0gLTEKcGF0Y2g1X2Z1bGxbcGF0Y2g1X2Z1bGwkaGVyb19wb3N0Mj09J3plbnlhdHRhJywgJ3BhdGNoZWQnXSA9IC0xCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdvcmlzYScsICdwYXRjaGVkJ10gPSAxCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdyZWFwZXInLCAncGF0Y2hlZCddID0gMQpwYXRjaDVfZnVsbFtwYXRjaDVfZnVsbCRoZXJvX3Bvc3QyPT0nd2luc3RvbicsICdwYXRjaGVkJ10gPSAxCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdnZW5qaScsICdwYXRjaGVkJ10gPSAxCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdtZWknLCAncGF0Y2hlZCddID0gMQpwYXRjaDVfZnVsbFtwYXRjaDVfZnVsbCRoZXJvX3Bvc3QyPT0ncGhhcmFoJywgJ3BhdGNoZWQnXSA9IDEKcGF0Y2g1X2Z1bGxbcGF0Y2g1X2Z1bGwkaGVyb19wb3N0Mj09J3JlYXBlcicsICdwYXRjaGVkJ10gPSAxCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSdzaWdtYScsICdwYXRjaGVkJ10gPSAxCnBhdGNoNV9mdWxsW3BhdGNoNV9mdWxsJGhlcm9fcG9zdDI9PSd6YXJ5YScsICdwYXRjaGVkJ10gPSAtMQpwYXRjaDVfZnVsbFtwYXRjaDVfZnVsbCRoZXJvX3Bvc3QyPT0nYmFsbCcsICdwYXRjaGVkJ10gPSAtMQoKCgpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0nb3Jpc2EnLCAncGF0Y2hlZCddID0gMQpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0ncmVhcGVyJywgJ3BhdGNoZWQnXSA9IDEKcGF0Y2g2X2Z1bGxbcGF0Y2g2X2Z1bGwkaGVyb19wb3N0Mj09J3dpbnN0b24nLCAncGF0Y2hlZCddID0gMQpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0nZ2VuamknLCAncGF0Y2hlZCddID0gMQpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0nbWVpJywgJ3BhdGNoZWQnXSA9IDEKcGF0Y2g2X2Z1bGxbcGF0Y2g2X2Z1bGwkaGVyb19wb3N0Mj09J3BoYXJhaCcsICdwYXRjaGVkJ10gPSAxCnBhdGNoNl9mdWxsW3BhdGNoNl9mdWxsJGhlcm9fcG9zdDI9PSdyZWFwZXInLCAncGF0Y2hlZCddID0gMQpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0nc2lnbWEnLCAncGF0Y2hlZCddID0gMQpwYXRjaDZfZnVsbFtwYXRjaDZfZnVsbCRoZXJvX3Bvc3QyPT0nemFyeWEnLCAncGF0Y2hlZCddID0gLTEKCgphbGxfcGF0Y2hlZF9mdWxsIDwtIGJpbmRfcm93cygKICBwYXRjaDJfZnVsbCwgcGF0Y2gzX2Z1bGwsIHBhdGNoNF9mdWxsLCBwYXRjaDVfZnVsbCwKICBwYXRjaDZfZnVsbCwgcGF0Y2g3X2Z1bGwpCmFsbF9wYXRjaGVkX2Z1bGwgPC0gYWxsX3BhdGNoZWRfZnVsbFthbGxfcGF0Y2hlZF9mdWxsJGhlcm9fcG9zdDIgIT0gJycsXQphbGxfcGF0Y2hlZF9mdWxsW2lzLm5hKGFsbF9wYXRjaGVkX2Z1bGwkcGF0Y2hlZCksICdwYXRjaGVkJ10gPC0gMAphbGxfcGF0Y2hlZF9mdWxsJHBhdGNoZWQgPC0gYWJzKGFsbF9wYXRjaGVkX2Z1bGwkcGF0Y2hlZCkKCnRhbmtfaGVyb2VzID0gYygncmVpbicsICd3aW5zdG9uJywgJ3JvYWRob2cnLCAnc2lnbWEnLCAnemFyeWEnLCAnb3Jpc2EnLCAnZHZhJywgJ2JhbGwnKQpoZWFsZXJfaGVyb2VzID0gYygnYW5hJywgJ21lcmN5JywgJ2x1Y2lvJywgJ2JhcHRpc3RlJywgJ3plbnlhdHRhJywgJ21vaXJhJywgJ2JyaWdpdHRlJykKYWxsX3BhdGNoZWRfZnVsbCRyb2xlIDwtICdkcHMnCmFsbF9wYXRjaGVkX2Z1bGwkcm9sZVthbGxfcGF0Y2hlZF9mdWxsJGhlcm9fcG9zdDIgJWluJSB0YW5rX2hlcm9lc10gPC0gJ3RhbmsnCmFsbF9wYXRjaGVkX2Z1bGwkcm9sZVthbGxfcGF0Y2hlZF9mdWxsJGhlcm9fcG9zdDIgJWluJSBoZWFsZXJfaGVyb2VzXSA8LSAnaGVhbGVyJwphbGxfcGF0Y2hlZF9mdWxsJHJvbGUgPC0gYXMuZmFjdG9yKGFsbF9wYXRjaGVkX2Z1bGwkcm9sZSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KbGlicmFyeShtZngpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShicm9vbSkKbGlicmFyeShyYW5kb21Gb3Jlc3QpCmxpYnJhcnkoY2FyZXQpCmBgYAojIyMgKipQcmVkaWN0aW5nIENoYW5nZXMgd2l0aCBQaWNrcmF0ZSBhbmQgV2lucmF0ZSoqCgpGaXJzdCB1cCBpcyB0aGUgZm9sbG93aW5nIG1vZGVsCgokJFAoXHRleHR7RnV0dXJlIEJhbGFuY2UgQ2hhbmdlfSB8IFx0ZXh0e0FnZ3JlZ2F0ZSBXUi9QUiBEYXRhfSkgPSBnKFxiZXRhXzAgKyBcc3VtX3tcdGV4dHtlbG9zfX0gKFxiZXRhXzFee1x0ZXh0e2Vsb319V1Jfe1x0ZXh0e2Vsb319ICsgXGJldGFfMl57XHRleHR7ZWxvfX1QUl97XHRleHR7ZWxvfX0pICsgXHZhcmVwc2lsb24pJCQKCndoZXJlICRnJCBoYW5kbGVzIHRoZSBmYWN0IHRoYXQgb3VyIG91dGNvbWUgaXMgYSAkMC8xJCB2YXJpYWJsZS4gVGhlbiB3ZSdsbCB1c2Ugc29tZSBwb3N0LXByb2Nlc3NpbmcgdG8gZ2V0IHRoZSBhdmVyYWdlIGVmZmVjdHMgb2YgZWFjaCBvZiBvdXIgdmFyaWFibGVzIG9uIHRoZSBwcm9iYWJpbGl0eSBvZiBhIGZ1dHVyZSBiYWxhbmNlIGNoYW5nZS4KCmBgYHtyLCBlY2hvPUZBTFNFfQpub3JtYWxpemUgPC0gZnVuY3Rpb24oeCl7CiAgcmV0dXJuICgoeCAtIG1lYW4oeCwgbmEucm09VCkpL3NkKHgsIG5hLnJtPVQpKQp9CgphbGxfcGF0Y2hlZF9ub3JtIDwtIGFsbF9wYXRjaGVkX2Z1bGwgJT4lIG11dGF0ZV9hdCgKICBjKGNvbG5hbWVzKGFsbF9wYXRjaGVkX2Z1bGwpWzI6OV0sY29sbmFtZXMoYWxsX3BhdGNoZWRfZnVsbClbMTE6MjZdKSwKICBub3JtYWxpemUpCgphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5hbGwubWlzcyA8LSBhcy5pbnRlZ2VyKGlzLm5hKGFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmFsbCkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmFsbC5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuYWxsKSkKYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IuYWxsW2FsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmFsbC5taXNzID09IDFdIDwtIDAKYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuYWxsW2FsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmFsbC5taXNzID09IDFdIDwtIDAKCgphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5icm9uemUubWlzcyA8LSBhcy5pbnRlZ2VyKGlzLm5hKGFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmJyb256ZSkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmJyb256ZS5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuYnJvbnplKSkKYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IuYnJvbnplW2FsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmJyb256ZS5taXNzID09IDFdIDwtIDAKYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuYnJvbnplW2FsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmJyb256ZS5taXNzID09IDFdIDwtIDAKCmFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLnNpbHZlci5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3Iuc2lsdmVyKSkKYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuc2lsdmVyLm1pc3MgPC0gYXMuaW50ZWdlcihpcy5uYShhbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5zaWx2ZXIpKQphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5zaWx2ZXJbYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3Iuc2lsdmVyLm1pc3MgPT0gMV0gPC0gMAphbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5zaWx2ZXJbYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuc2lsdmVyLm1pc3MgPT0gMV0gPC0gMAoKYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IuZ29sZC5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IuZ29sZCkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmdvbGQubWlzcyA8LSBhcy5pbnRlZ2VyKGlzLm5hKGFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmdvbGQpKQphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5nb2xkW2FsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmdvbGQubWlzcyA9PSAxXSA8LSAwCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmdvbGRbYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuZ29sZC5taXNzID09IDFdIDwtIDAKCmFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLnBsYXQubWlzcyA8LSBhcy5pbnRlZ2VyKGlzLm5hKGFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLnBsYXQpKQphbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5wbGF0Lm1pc3MgPC0gYXMuaW50ZWdlcihpcy5uYShhbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5wbGF0KSkKYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IucGxhdFthbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5wbGF0Lm1pc3MgPT0gMV0gPC0gMAphbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5wbGF0W2FsbF9wYXRjaGVkX25vcm0kYXZnX3ByLnBsYXQubWlzcyA9PSAxXSA8LSAwCgphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5kaWFtLm1pc3MgPC0gYXMuaW50ZWdlcihpcy5uYShhbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5kaWFtKSkKYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuZGlhbS5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuZGlhbSkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmRpYW1bYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IuZGlhbS5taXNzID09IDFdIDwtIDAKYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIuZGlhbVthbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5kaWFtLm1pc3MgPT0gMV0gPC0gMAoKYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IubWFzdC5taXNzIDwtIGFzLmludGVnZXIoaXMubmEoYWxsX3BhdGNoZWRfbm9ybSRhdmdfd3IubWFzdCkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLm1hc3QubWlzcyA8LSBhcy5pbnRlZ2VyKGlzLm5hKGFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLm1hc3QpKQphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5tYXN0W2FsbF9wYXRjaGVkX25vcm0kYXZnX3dyLm1hc3QubWlzcyA9PSAxXSA8LSAwCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLm1hc3RbYWxsX3BhdGNoZWRfbm9ybSRhdmdfcHIubWFzdC5taXNzID09IDFdIDwtIDAKCmFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmdtLm1pc3MgPC0gYXMuaW50ZWdlcihpcy5uYShhbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci5nbSkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3ByLmdtLm1pc3MgPC0gYXMuaW50ZWdlcihpcy5uYShhbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5nbSkpCmFsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmdtW2FsbF9wYXRjaGVkX25vcm0kYXZnX3dyLmdtLm1pc3MgPT0gMV0gPC0gMAphbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5nbVthbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci5nbS5taXNzID09IDFdIDwtIDAKCgphbGxfcGF0Y2hlZF9ub3JtJGF2Z19wci4gPC0gTlVMTAphbGxfcGF0Y2hlZF9ub3JtJGF2Z193ci4gPC0gTlVMTAoKCm1vZGVsMSA8LSBnbG0oCiAgcGF0Y2hlZCB+IHBvbHkoYXZnX3dyLmFsbCwyLHJhdz1UKSAgKyBhdmdfcHIuYWxsICsgCiAgICAgICAgICAgIHBvbHkoYXZnX3dyLmJyb256ZSwyLHJhdz1UKSArIGF2Z19wci5icm9uemUgKwogICAgICAgICAgICBwb2x5KGF2Z193ci5zaWx2ZXIsMixyYXc9VCkgKyBhdmdfcHIuc2lsdmVyICsKICAgICAgICAgICAgcG9seShhdmdfd3IuZ29sZCwyLHJhdz1UKSArIGF2Z19wci5nb2xkICsKICAgICAgICAgICAgcG9seShhdmdfd3IucGxhdCwyLHJhdz1UKSArIGF2Z19wci5wbGF0ICsKICAgICAgICAgICAgcG9seShhdmdfd3IuZGlhbSwyLHJhdz1UKSArIGF2Z19wci5kaWFtICsKICAgICAgICAgICAgcG9seShhdmdfd3IubWFzdCwyLHJhdz1UKSArIGF2Z19wci5tYXN0ICsKICAgICAgICAgICAgI2F2Z193ci5nbSArIEkoYXZnX3dyLmdtXjIpICsgYXZnX3ByLmdtICsgCiAgICAgICAgICAgIHJvbGUgKwogICAgICAgICAgICBhdmdfd3IuYWxsLm1pc3MgKyAKICAgICAgICAgICAgYXZnX3dyLmJyb256ZS5taXNzICsgYXZnX3ByLmJyb256ZS5taXNzICsKICAgICAgICAgICAgYXZnX3dyLnNpbHZlci5taXNzICsKICAgICAgICAgICAgYXZnX3dyLmdvbGQubWlzcyAKICAgICwgZGF0YT1hbGxfcGF0Y2hlZF9ub3JtLCBmYW1pbHk9Ymlub21pYWwobGluaz0ibG9naXQiKSkKCnJlc2lkdWFsX3Bsb3QgPC0gZnVuY3Rpb24odmFyaWFibGUsIG1vZGVsKXsKICBwbG90KHZhcmlhYmxlLHJlc2lkdWFscyhtb2RlbCksY29sPWMoImJsdWUiLCJyZWQiKVsxK2FsbF9wYXRjaGVkX25vcm0kcGF0Y2hlZF0pCiAgbGluZXMobG93ZXNzKHZhcmlhYmxlLHJlc2lkdWFscyhtb2RlbCkpLGNvbD0iYmxhY2siLGx3ZD0yKQogIGxpbmVzKGxvd2Vzcyh2YXJpYWJsZVthbGxfcGF0Y2hlZF9ub3JtJHBhdGNoZWQ9PTBdLHJlc2lkdWFscyhtb2RlbClbYWxsX3BhdGNoZWRfbm9ybSRwYXRjaGVkPT0wXSksY29sPSJibHVlIikKICBsaW5lcyhsb3dlc3ModmFyaWFibGVbYWxsX3BhdGNoZWRfbm9ybSRwYXRjaGVkPT0xXSxyZXNpZHVhbHMobW9kZWwpW2FsbF9wYXRjaGVkX25vcm0kcGF0Y2hlZD09MV0pLGNvbD0icmVkIikKICBhYmxpbmUoaD0wLGx0eT0yLGNvbD0iZ3JleSIpCn0KCgptZngxIDwtIGxvZ2l0bWZ4KG1vZGVsMSwgZGF0YT1hbGxfcGF0Y2hlZF9ub3JtLCBhdG1lYW49RkFMU0UpCmVzdCA8LSBtZngxJG1meGVzdApwYXIobWZyb3c9YygxLDEpKQpvdXQgPC0gZGF0YS5mcmFtZShtZWFuPWVzdFssMV0sCiAgICAgICAgICAgICAgICAgIGxvd2VyPWVzdFssMV0tMS45Niplc3RbLDJdLAogICAgICAgICAgICAgICAgICB1cHBlcj1lc3RbLDFdKzEuOTYqZXN0WywyXSkKb3V0IDwtIG91dFsxOjIzLF0KCm91dCR2YXJzIDwtIGMoJ0F2Zy4gV1InLCAnQXZnLiBXUjInLCAnQXZnLiBQUicsCiAgICAgICAgICAgICAgJ0Jyb256ZSBXUicsICdCcm9uemUgV1IyICcsJ0Jyb256ZSBQUicsCiAgICAgICAgICAgICAgJ1NpbHYuIFdSJywgJ1NpbHYuIFdSMicsICdTaWx2LiBQUicsCiAgICAgICAgICAgICAgJ0dvbGQgV1InLCAnR29sZCBXUjInLCdHb2xkIFBSJywKICAgICAgICAgICAgICAnUGxhdCBXUicsICdQbGF0IFdSMicsICdQbGF0IFBSJywKICAgICAgICAgICAgICAnRGlhbS4gV1InLCAnRGlhbS4gV1IyJywgJ0RpYW0gUFInLAogICAgICAgICAgICAgICdNYXN0IFdSJywgJ01hc3QgV1IyJywKICAgICAgICAgICAgICAnTWFzdCBQUicsICdIZWFsZXInLCAnVGFuaycpIywgCiMgICAgICAgICAgICAgICdBdmcuIFdSIE1pc3MnLCAjJ0F2Zy4gUFIgTWlzcycsCiMgICAgICAgICAgICAgICdCcm9uemUgV1IgTWlzcycsICdCcm9uemUgUFIgTWlzcycsICdTaWx2LgojICAgICAgICAgICAgICBXUiBNaXNzJywgIydTaWx2LiBQUiBNaXNzJywKIyAgICAgICAgICAgICAgJ0dvbGQgV1IgTWlzcycpIywgJ0dvbGQgUFIgTWlzcycsICdQbGF0IFdSIE1pc3MnLCAnUGxhdCBQUiBNaXNzJywgJ0RpYW0uIFdSIAojICAgICAgICAgICAgICBNaXNzJywgJ0RpYW0gUFIgTWlzcycsCiMgICAgICAgICAgICAgICdNYXN0IFdSIE1pc3MnLCAnTWFzdCBQUiBNaXNzJykKb3V0JHZhcnMgPC0gZmFjdG9yKG91dCR2YXJzLCBsZXZlbHM9dW5pcXVlKG91dCR2YXJzKSkKCnJvd25hbWVzKG91dCkgPC0gTlVMTApvdXQgPC0gb3V0WyxjKCd2YXJzJywgJ21lYW4nLCAnbG93ZXInLCAndXBwZXInKV0Ka2FibGUob3V0KQoKZ2dwbG90KGRhdGE9b3V0WzE6MjMsXSwgbWFwcGluZz1hZXMoeD12YXJzLCB5PW1lYW4pKSArIAogICAgZ2VvbV9wb2ludChzaGFwZT0yMSwgY29sb3I9J2dyYXk1MCcsIGZpbGw9J2JsYWNrJykgKyAKICAgIGdlb21fcG9pbnRyYW5nZSgKICAgICAgZGF0YT1vdXQsIG1hcHBpbmc9YWVzKHltaW4gPSBsb3dlciwgeW1heCA9IHVwcGVyKSwgc2hhcGU9MjEsIGNvbD0nZ3JheTUwJywKICAgICAgZmlsbD0nYmxhY2snKSArIGdlb21faGxpbmUoeWludGVyY2VwdD0wKSArCiAgdGhlbWVfYncoKSArCiAgeGxhYignVmFyaWFibGVzJykgKyB5bGFiKCdNYXJnaW5hbCBFZmZlY3RzJykgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTkwKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTgsIGZhbWlseT0nVGltZXMnKSkKCgojIENoZWNrIGFzc3VtcHRpb25zCm15ZGF0YSA8LSBhbGxfcGF0Y2hlZF9ub3JtICU+JQogIGRwbHlyOjpzZWxlY3RfaWYoaXMubnVtZXJpYykgCnByb2JhYmlsaXRpZXMgPC0gcHJlZGljdChtb2RlbDEsIGRhdGE9bXlkYXRhLCB0eXBlID0gInJlc3BvbnNlIikKcHJlZGljdG9ycyA8LSBjb2xuYW1lcyhteWRhdGEpCiMgQmluZCB0aGUgbG9naXQgYW5kIHRpZHlpbmcgdGhlIGRhdGEgZm9yIHBsb3QKbXlkYXRhIDwtIG15ZGF0YSAlPiUKICBtdXRhdGUobG9naXQgPSBsb2cocHJvYmFiaWxpdGllcy8oMS1wcm9iYWJpbGl0aWVzKSkpICU+JQogIGdhdGhlcihrZXkgPSAicHJlZGljdG9ycyIsIHZhbHVlID0gInByZWRpY3Rvci52YWx1ZSIsIC1sb2dpdCkKI2dncGxvdChteWRhdGEsIGFlcyhsb2dpdCwgcHJlZGljdG9yLnZhbHVlKSkrCiMgIGdlb21fcG9pbnQoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjUpICsKIyAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIikgKyAKIyAgdGhlbWVfYncoKSArIAojICBmYWNldF93cmFwKH5wcmVkaWN0b3JzLCBzY2FsZXMgPSAiZnJlZV95IikKCiNwbG90KG1vZGVsMSwgd2hpY2ggPSA0LCBpZC5uID0gMykKCmBgYAoKSGVyZSB3ZSBzZWUgYSBzaWduaWZpY2FudCBub25saW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gd2lucmF0ZXMgYW5kIGZ1dHVyZSBiYWxhbmNlIGNoYW5nZXMuIE1vcmFsIG9mIHRoZSBzdG9yeTogZG9uJ3QgbGlzdGVuIHRvIHBlb3BsZSB0ZWxsaW5nIHlvdSB3aW5yYXRlcyBkb24ndCBtYXR0ZXIsIHRoZXkganVzdCBhcmVuJ3QgYXMgZWFzaWx5IGludGVycHJldGVkIQoKIyMjICoqUHJlZGljdGluZyBDaGFuZ2VzIHdpdGggRm9ydW0gRGF0YSoqCgoKU2Vjb25kIHdlIGhhdmUgCgokJFAoXHRleHR7RnV0dXJlIEJhbGFuY2UgQ2hhbmdlfSB8IFx0ZXh0e0ZvcnVtIERhdGF9KSA9IGcoXGJldGFfMCArIFxiZXRhXzEgXHRleHR7U2VudGltZW50fSArIFxiZXRhXzJcdGV4dHtCdWZmc30gKyBcYmV0YV8zXHRleHR7TmVyZnN9ICsgXGJldGFfNFx0ZXh0e1ZpZXdzfSArIFxiZXRhXzRcdGV4dHtSZXBsaWVzfSArIFx2YXJlcHNpbG9uKSQkCgp3aGVyZSBhZ2FpbiAkZyQgaGFuZGxlcyB0aGUgZmFjdCB0aGF0IG91ciBvdXRjb21lIGlzIGEgJDAvMSQgdmFyaWFibGUuIFRoZW4gd2UnbGwgdXNlIHNvbWUgcG9zdC1wcm9jZXNzaW5nIHRvIGdldCB0aGUgYXZlcmFnZSBlZmZlY3RzIG9mIGVhY2ggb2Ygb3VyIHZhcmlhYmxlcyBvbiB0aGUgcHJvYmFiaWxpdHkgb2YgYSBmdXR1cmUgYmFsYW5jZSBjaGFuZ2UuCgpgYGB7ciwgZWNobz1GQUxTRX0KbW9kZWwyIDwtIGdsbSgKICBwYXRjaGVkIH4gcG9seShhbGxfcmVwbGllcywgMiwgcmF3PVQpICsgYWxsX3ZpZXdzICsgYXZnX2NvbXBvdW5kICsgCiAgICAgICAgICAgIHN1bV9idWZmICsgcG9seShzdW1fbmVyZiwyLHJhdz1UKSArIHJvbGUKICAgICwgZGF0YT1hbGxfcGF0Y2hlZF9ub3JtLCBmYW1pbHk9Ymlub21pYWwobGluaz0ibG9naXQiKSkKbWZ4MiA8LSBsb2dpdG1meChtb2RlbDIsIGRhdGE9YWxsX3BhdGNoZWRfbm9ybSwgYXRtZWFuPUZBTFNFKQplc3QgPC0gbWZ4MiRtZnhlc3QKcGFyKG1mcm93PWMoMSwxKSkKb3V0IDwtIGRhdGEuZnJhbWUobWVhbj1lc3RbLDFdLAogICAgICAgICAgICAgICAgICBsb3dlcj1lc3RbLDFdLTEuOTYqZXN0WywyXSwKICAgICAgICAgICAgICAgICAgdXBwZXI9ZXN0WywxXSsxLjk2KmVzdFssMl0pCgpvdXQkdmFycyA8LSBjKCdSZXBsaWVzJywgJ1JlcGxpZXMyJywgJ1ZpZXdzJywgJ1NlbnRpbWVudCcsICciQnVmZiInLCAnIk5lcmYiJywgJyJOZXJmIjInLCAnSGVhbGVyJywgJ1RhbmsnKQpvdXQkdmFycyA8LSBmYWN0b3Iob3V0JHZhcnMsIGxldmVscyA9IHVuaXF1ZShvdXQkdmFycykpCnJvd25hbWVzKG91dCkgPC0gTlVMTApvdXQgPC0gb3V0WyxjKCd2YXJzJywgJ21lYW4nLCAnbG93ZXInLCAndXBwZXInKV0Ka2FibGUob3V0KQoKZ2dwbG90KGRhdGE9b3V0LCBtYXBwaW5nPWFlcyh4PXZhcnMsIHk9bWVhbikpICsgCiAgICBnZW9tX3BvaW50KHNoYXBlPTIxLCBjb2xvcj0nZ3JheTUwJywgZmlsbD0nYmxhY2snKSArIAogICAgZ2VvbV9wb2ludHJhbmdlKAogICAgICBkYXRhPW91dCwgbWFwcGluZz1hZXMoeW1pbiA9IGxvd2VyLCB5bWF4ID0gdXBwZXIpLCBzaGFwZT0yMSwgY29sPSdncmF5NTAnLAogICAgICBmaWxsPSdibGFjaycpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTApICsKICB0aGVtZV9idygpICsKICB4bGFiKCdWYXJpYWJsZXMnKSArIHlsYWIoJ01hcmdpbmFsIEVmZmVjdHMnKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9OTApLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCwgZmFtaWx5PSdUaW1lcycpKQpgYGAKSGVyZSB3ZSBzZWUgbWFyZ2luYWxseSBzaWduaWZpY2FudCBlZmZlY3RzIG9mIHRoZSBudW1iZXIgb2YgdG9waWMgcmVwbGllcyBhbmQgdGhlIG51bWJlciBvZiBwb3N0cyBjYWxsaW5nIGZvciBuZXJmcyBvbiBmdXR1cmUgYmFsYW5jZSBjaGFuZ2VzLCBidXQgdGhleSBhcmUgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKGF0IDk1JSBjb25maWRlbmNlKS4KCiMjIyAqKlByZWRpY3RpbmcgQ2hhbmdlcyB3aXRoIEV2ZXJ5dGhpbmcqKgoKCkxhc3RseSB3ZSBoYXZlIAoKJCRQKFx0ZXh0e0Z1dHVyZSBCYWxhbmNlIENoYW5nZX0gfCBcdGV4dHtBbGwgRGF0YX0pID0gZyhcYmV0YV8wICsgXHZlY3tcYmV0YX1fMSBcdmVje0Z9ICsgXHZlY3tcYmV0YX1fMiBcdmVje1BSfSArIFx2ZWN7XGJldGF9XzMgXHZlY3tXUn0gK1x2YXJlcHNpbG9uKSQkCgp3aGVyZSBhZ2FpbiAkZyQgaGFuZGxlcyB0aGUgZmFjdCB0aGF0IG91ciBvdXRjb21lIGlzIGEgJDAvMSQgdmFyaWFibGUsICRGJCBpcyAqYWxsKiBvZiBvdXIgZm9ydW0gdmFyaWFibGVzIGFuZCAkV1IvUFIkIGFyZSB0aGUgd2lucmF0ZXMvcGlja3JhdGVzIGZvciAqYWxsKiBvZiBvdXIgZWxvcy4gCmBgYHtyLCBlY2hvPUZBTFNFfQptb2RlbDMgPC0gZ2xtKAogIHBhdGNoZWQgfiBwb2x5KGFsbF9yZXBsaWVzLCAyLCByYXc9VCkgKyBhbGxfdmlld3MgKyBhdmdfY29tcG91bmQgKyAKICAgICAgICAgICAgc3VtX2J1ZmYgKyBwb2x5KHN1bV9uZXJmLDIscmF3PVQpICsgCiAgICAgICAgICAgIHBvbHkoYXZnX3dyLmFsbCwyLHJhdz1UKSAgKyBhdmdfcHIuYWxsICsgCiAgICAgICAgICAgIHBvbHkoYXZnX3dyLmJyb256ZSwyLHJhdz1UKSArIGF2Z19wci5icm9uemUgKwogICAgICAgICAgICBwb2x5KGF2Z193ci5zaWx2ZXIsMixyYXc9VCkgKyBhdmdfcHIuc2lsdmVyICsKICAgICAgICAgICAgcG9seShhdmdfd3IuZ29sZCwyLHJhdz1UKSArIGF2Z19wci5nb2xkICsKICAgICAgICAgICAgcG9seShhdmdfd3IucGxhdCwyLHJhdz1UKSArIGF2Z19wci5wbGF0ICsKICAgICAgICAgICAgcG9seShhdmdfd3IuZGlhbSwyLHJhdz1UKSArIGF2Z19wci5kaWFtICsKICAgICAgICAgICAgcG9seShhdmdfd3IubWFzdCwyLHJhdz1UKSArIGF2Z19wci5tYXN0ICsKICAgICAgICAgICAgcm9sZSArCiAgICAgICAgICAgIGF2Z193ci5hbGwubWlzcyArCiAgICAgICAgICAgIGF2Z193ci5icm9uemUubWlzcyArIGF2Z19wci5icm9uemUubWlzcyArCiAgICAgICAgICAgIGF2Z193ci5zaWx2ZXIubWlzcyAgKwogICAgICAgICAgICBhdmdfd3IuZ29sZC5taXNzCiAgICAsIGRhdGE9YWxsX3BhdGNoZWRfbm9ybSwgZmFtaWx5PWJpbm9taWFsKGxpbms9ImxvZ2l0IikpCm1meDMgPC0gbG9naXRtZngobW9kZWwzLCBkYXRhPWFsbF9wYXRjaGVkX25vcm0sIGF0bWVhbj1GQUxTRSkKZXN0IDwtIG1meDMkbWZ4ZXN0CnBhcihtZnJvdz1jKDEsMSkpCm91dCA8LSBkYXRhLmZyYW1lKG1lYW49ZXN0WywxXSwKICAgICAgICAgICAgICAgICAgbG93ZXI9ZXN0WywxXS0xLjk2KmVzdFssMl0sCiAgICAgICAgICAgICAgICAgIHVwcGVyPWVzdFssMV0rMS45Niplc3RbLDJdKQpvdXQgPC0gb3V0WzE6MzAsXQpvdXQkdmFycyA8LSBjKCdSZXBsaWVzJywgJ1JlcGxpZXMyJywgJ1ZpZXdzJywgJ1NlbnRpbWVudCcsICciQnVmZiInLCAnIk5lcmYiJywgJyJOZXJmIjInLCAnQXZnLiBXUicsICdBdmcuIFdSMicsICdBdmcuIFBSJywgJ0Jyb256ZSBXUicsICdCcm9uemUgV1IyJywgJ0Jyb256ZSBQUicsICdTaWx2LiBXUicsIAogICAgICAgICAgICAgICdTaWx2LiBXUjInLCAnU2lsdi4gUFInLAogICAgICAgICAgICAgICdHb2xkIFdSJywgJ0dvbGQgV1IyJywgJ0dvbGQgUFInLCAnUGxhdCBXUicsICdQbGF0IFdSMicsCiAgICAgICAgICAgICAgJ1BsYXQgUFInLAogICAgICAgICAgICAgICdEaWFtLiBXUicsICdEaWFtLiBXUjInLCAnRGlhbSBQUicsCiAgICAgICAgICAgICAgJ01hc3QgV1InLCAnTWFzdCBXUjInLCdNYXN0IFBSJywgJ0hlYWxlcicsICdUYW5rJykKIyAgICAgICAgICAgICAgJ0F2Zy4gV1IgTWlzcycsICdBdmcuIFBSIE1pc3MnLCAnQnJvbnplIFdSIE1pc3MnLCAnQnJvbnplIFBSIE1pc3MnLCAnU2lsdi4KIyAgICAgICAgICAgICAgV1IgTWlzcycsICdTaWx2LiBQUiBNaXNzJywKIyAgICAgICAgICAgICAgJ0dvbGQgV1IgTWlzcycsICdHb2xkIFBSIE1pc3MnLCAnUGxhdCBXUiBNaXNzJywgJ1BsYXQgUFIgTWlzcycsICdEaWFtLiBXUiAKIyAgICAgICAgICAgICAgTWlzcycsICdEaWFtIFBSIE1pc3MnLAojICAgICAgICAgICAgICAnTWFzdCBXUiBNaXNzJywgJ01hc3QgUFIgTWlzcycpCm91dCR2YXJzIDwtIGZhY3RvcihvdXQkdmFycywgbGV2ZWxzPXVuaXF1ZShvdXQkdmFycykpCnJvd25hbWVzKG91dCkgPC0gTlVMTApvdXQgPC0gb3V0WyxjKCd2YXJzJywgJ21lYW4nLCAnbG93ZXInLCAndXBwZXInKV0Ka2FibGUob3V0KQoKZ2dwbG90KGRhdGE9b3V0LCBtYXBwaW5nPWFlcyh4PXZhcnMsIHk9bWVhbikpICsgCiAgICBnZW9tX3BvaW50KHNoYXBlPTIxLCBjb2xvcj0nZ3JheTUwJywgZmlsbD0nYmxhY2snKSArIAogICAgZ2VvbV9wb2ludHJhbmdlKAogICAgICBkYXRhPW91dCwgbWFwcGluZz1hZXMoeW1pbiA9IGxvd2VyLCB5bWF4ID0gdXBwZXIpLCBzaGFwZT0yMSwgY29sPSdncmF5NTAnLAogICAgICBmaWxsPSdibGFjaycpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTApICsKICB0aGVtZV9idygpICsKICB4bGFiKCdWYXJpYWJsZXMnKSArIHlsYWIoJ01hcmdpbmFsIEVmZmVjdHMnKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9OTApLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xOCwgZmFtaWx5PSdUaW1lcycpKQpgYGAKCkZpbmFsbHksIHdoaWxlIHdlIHNlZSBzaWduaWZpY2FuY2UgaW4gd2lucmF0ZXMgYW5kIHBpY2tyYXRlcyBieSBlbG8sIGFueSBtYXJnaW5hbCBzaWduaWZpY2FuY2Ugb2YgZm9ydW0gY2hhcmFjdGVyaXN0aWNzIGlzIGNhcHR1cmVkIGJ5IG9iamVjdGl2ZSBhbmQgbW9yZSBlYXNpbHkgaW50ZXJwcmV0ZWQgdmFyaWFibGVzLiBEb24ndCB3YXN0ZSB5b3VyIHRpbWUgd29ycnlpbmcgYWJvdXQgdGhlIE92ZXJ3YXRjaCBGb3J1bXMgbW9iIQoKIyMgKipDb25jbHVzaW9ucyoqCgpQaGV3LCB0aGF0IHR1cm5lZCBpbnRvIHF1aXRlIHRoZSByZXBvcnQuIExldCdzIGdvIHRocm91Z2ggYSBzaG9ydCBzdW1tYXJ5IG9mIHRoZSBmaW5kaW5ncy4gRmlyc3RseSwgaXQncyBub3QgeW91ciBpbWFnaW5hdGlvbiwgdGhlIE9mZmljaWFsIEZvcnVtcyBhcmUgYSBob3RiZWQgZm9yIGNoYW5nZS9idWZmL25lcmYgcG9zdHMuIFRoZSBtb3N0IChpbilmYW1vdXMgaGVyb2VzIG9uIHRoZSBPZmZpY2lhbCBGb3J1bXMgbGF0ZWx5IGFyZSBHZW5qaSwgTWVyY3ksIE1jQ3JlZSwgU29tYnJhLCBhbmQgUmVpbi4gTW9yZW92ZXIsIGZvciBzb21lIHJlYXNvbiB0aGUgRm9ydW1zICpyZWFsbHkqIGxvdmUgTWVyY3kgKGFuZCBKdW5rcmF0PykgYW5kIHRoZXkgKnJlYWxseSogaGF0ZSBEb29tZmlzdC4gV2hpbGUgY2FsbHMgZm9yIG5lcmZzL2J1ZmZzIGFsaWduIHJlYWxseSB3ZWxsIHdpdGggdGhlIHZhcmlvdXMgbWV0YXMgd2UndmUgc2Vlbi0gU2lnbWEvQmFsbCwgTWNDcmVlLCBldGMsIHNvbWUgaGVyb2VzIGFyZSBzaW11bHRhbmVvdXNseSBjYWxsZWQgZm9yIG5lcmZzL2J1ZmZzLCB1c3VhbGx5IGJlY2F1c2UgdGhleSdyZSB3ZWFrIGJ1dCBoYXRlZCAoR2VuamksIEhhbnpvLCBSZWFwZXIpIG9yIGJlZ3J1ZGdpbmdseSBuZWNlc3NhcnkgKFJlaW4pLgoKSW4gdGVybXMgb2YgYmFsYW5jZSwgSSBmaW5kIGV2aWRlbmNlIHRoYXQgd2lucmF0ZXMgKmFyZSBwcmVkaWN0aXZlIG9mIGJhbGFuY2UgY2hhbmdlcyBpbiBhIG5vbmxpbmVhciB3YXkqLiBNb3Jlb3ZlciwgYmVpbmcgYSAqdGFuayBvciBoZWFsZXIgaXMgcHJlZGljdGl2ZSBvZiBnZXR0aW5nIHJlYmFsYW5jZWQqIGR1cmluZyB0aGlzIHN0dWR5IHBlcmlvZC4gRmluYWxseSwgd2hpbGUgKm51bWJlciBvZiBSZXBsaWVzIHRvIGEgcG9zdCogYW5kICpjYWxscyBmb3IgbmVyZnMqIGFyZSBtYXJnaW5hbGx5IHByZWRpY3RpdmUgb2YgZ2V0dGluZyByZWJhbGFuY2VkLCB0aGVpciBwcmVkaWN0aXZlIHBvd2VyIGdvZXMgYXdheSBhZnRlciB5b3UgaW5jbHVkZSB3aW5yYXRlcyBhbmQgcGlja3JhdGVzLiBGb3J1bXMgdG9waWNzIGRvIG5vdCBzaWduaWZpY2FudGx5IGFmZmVjdCBiYWxhbmNlIGNoYW5nZXMgaWYgeW91IGp1c3QgbG9vayBhdCB0aGUgZmFjdHMhIAoKCgpVbnRpbCBOZXh0IFRpbWUhCgogIAo=