Rex W. Douglass PhD 1 2

[@RexDouglass]

3/30/2020

[Working Draft. COMMENTS WELCOME!]3

Introduction

How should non-epidemiologists publicly discuss COVID-19 data and models? When leaders and citizens are especially sensitive to signals on public health, what is our intellectual responsibility to defer to the analysis of more expert speakers? I argue that our responsibility during crisis is the same as it was before; to do good work, to the best of our abilities, with the scientific principles of curiosity and honesty. Alternative shorthands like ‘staying in your lane’ are a poor decision rule for sorting good work from bad, and they ignore the very messy process that underlies real-world scientific inquiry. Lane-keeping is a poor way to learn and become a better consumer of expert findings, and gate-keeping is a missed opportunity to provide the public goods of feedback and review. To demonstrate the point, this note provides a detailed review of a recent piece “Coronavirus Perspective” (Epstein 2020a). By applying and illustrating data science principles point for point to this non-epidemiological take on epidemiological questions, it is hoped that the reader will take away not why they should avoid working on new topics but rather how they should approach those topics in an honest, curious, and rigorous way.

Epstein (2020a, 2020b)

Epstein (2020a) argues that the U.S. ought to shift from a loose shelter in place style quarantine to a more limited shelter in place for just vulnerable populations. He provides two primary rationales. First, the number of cases and number of deaths both in the U.S. and worldwide are likely to be small. Second, mortality for under 60 is relatively low. Together, the two ideas suggest that restrictions on all groups is overkill and some compromise weaker position is preferred. He reiterates this position in a number of interviews. In a follow up piece Epstein (2020b) doubles down on the core argument that the direct health costs of the disease will be moderate and a weakened response should be preferred, “allowing the virus to run its course—is a better path forward for the economy.” After the U.K. briefly flirted with this approach before rejecting it, the option is being circulated publicly at the federal level in the U.S. and this text specifically is reportedly popular among some U.S. policy makers and refered to as a competing projection. For that reason it serves a prime case for consideration on how to think about non-epidemiologists talking about scientific question that are decidedly out of their lane.

Lesson 1: Actually Care About the Answer to a Question

Epstein (2020a) frames itself as being contrarian rather than curious about the true state of the world.

Much of the current analysis does not explain how and why rates of infection and death will spike, so I think that it is important to offer a dissenting voice.

These are deeply contrarian estimates.

Perhaps my analysis is all wrong, even deeply flawed. But the stakes are too high to continue on the current course without reexamining the data and the erroneous models that are predicting doom.

Science is about being curious about the true state of the world, and through application of evidence and methods, forming new more true beliefs than we held the day before. Contrarianism is not a search for truth, it’s a search for political influence in a market that rewards diversity of opinion for diversity’s sake. Performative controversy, fake horse races, hypotheses that don’t follow from theory, no examination of model fit or out of sample performance, and so on, are immediate red flags the author doesn’t actually care what the right answer is.

As a consumer of analysis, the second I can tell the author doesn’t actually care about the answer to the underlying question, they’re dead to me.

As a producer of analysis, the struggle is how to think about and do science alongside actors who generate controversy out of self-interest using a lot of the same language as science. The only real solution is to learn how to tell good work from bad work no matter the wrapping.

Lesson 2: Pose a Question and Propose a Research Design that Can Answer It

Instead of an assertion, we should present Epstein’s idea as a concrete research question: What will the number of deaths from COVID-19 in the United States be by say September 1? To be concrete, here are our outcomes, confirmed COVID-19 cases (red) and deaths (black) compiled by Johns Hopkins CSSE.

To make this easier to compare across time and across countries, let’s log transform the outcome and change date to number of days since the 100th reported case. This puts our forcasting horizon at about 180 days from the start of the U.S. episode.

Two immediate things to take away are first, we are interested specifically in deaths and are forced to understand spread of all cases incidentally as a means to understand deaths. The second is that our forecasting horizon is far. A lot can happen between now and then, and experts have wildly varying expectations about what will actually happen in this window. Even though there is a great deal of expert certainty about the underlying mechanics, what will happen or more precisely what we will choose to let happen, are unknowns.

Lesson 3: Use Failures of Your Predictions to Revise your Model

In the first draft of the piece dated and posted March 16, 2020 Epstein (2020a) predicts the following about future counts of deaths:

From this available data, it seems more probable than not that the total number of cases world-wide will peak out at well under 1 million, with the total number of deaths at under 50,000 (up about eightfold). In the United States, if the total death toll increases at about the same rate, the current 67 deaths should translate into about 500 deaths at the end. Of course, every life lost is a tragedy—and the potential loss of 50,000 lives world-wide would be appalling—but those deaths stemming from the coronavirus are not more tragic than others, so that the same social calculus applies here that should apply in other cases.

This is great. It makes a sharp testable prediction that we can use to validate in a timely manner a radical alternate model of disease spread.4

When the fatality number passed 500, Epstein edited the online copy of the original March 16th piece to read 5,000 instead and added a footnote

From this available data, it seems more probable than not that the total number of cases world-wide will peak out at well under 1 million, with the total number of deaths at under 50,000 (up about eightfold). In the United States, if the total death toll increases at about the same rate, the current 67 deaths should reach about 5000 (or twn percent of my estimated world total, which may also turn out to be low). [See correction & addendum at the end of this essay.]5

Correction & Addendum, added March 24, 2020: That estimate is ten times greater than the 500 number I erroneously put in the initial draft of the essay, and it, too, could prove somewhat optimistic. But any possible error rate in this revised projection should be kept in perspective. The current U.S. death toll stands at 592 as of noon on March 24, 2020, out of about 47,000 cases. So my adjusted figure, however tweaked, remains both far lower, and I believe far more accurate, than the common claim that there could be a million dead in the U.S. from well over 150 million coronavirus cases before the epidemic runs its course.

And then published a follow up note saying he really meant to type 2,500 the first time.

In my column last week, I predicted that the world would eventually see about 50,000 deaths from the novel coronavirus, and the United States about 500. These two numbers are clearly not in sync. If the first number holds, the total US deaths should be about 4 to 5 percent of that total, or about 2,000–2,500 deaths. The current numbers are getting larger, so it is possible both figures will move up in a rough proportion from even that revised estimate.

This is not great. This alters the prediction but does not bother to alter the logic which led to the calculation. Multiplying the then global death count by 8 would lead to a global prediction of 50,000 and so multiplying the then U.S. death count of 67 by 8 would be 536, hence the forecast of 500. Likewise the 50,000 global total is left unchanged. Simply adding zeros to the prediction every time it is proven wrong doesn’t alter the underlying model given in the same sentence.

Don’t do this. When you feel comfortable enough to share your predictions publicly, create a concrete record and stick by it. You can always make new predictions based on new models, but don’t go back and massage past predictions after the fact. The temptation to try to gaslight others (and yourself) that you were really right the entire time is too great.6

We can visually examine this prediction in light of the data up to now, adding global counts of cases and deaths, and marking the predicted maximums in the March 16th draft and then the revised March 24th draft.

These forecasts in light of the actual data trajectory should immediately give you pause. For the United States, it would require a very soon departure from the current exponential trend which wasn’t visible yet in either the confirmed or death trends. The U.S. trend in deaths was actually accelerating slightly here.

For the world, growth starts off exponential, levels off, and then goes exponential again as it reaches a new part of the world. For Epstein’s 50k estimate to be true, the trend in Europe and the U.S. would have to start leveling off now, and there would have to not be an exponential growth when the disease fully hits Latin America, Africa, and South East Asia. As of this writing the world is already three quarters to that prediction of a million confirmed cases. It’s not that these outcomes aren’t possible, it’s that it’s unclear what in the time trend up until now or in the theory suggests that’s what is about to happen.

Lesson 4: Form Meaningful Prior Beliefs with a Thorough Literature Review

Thanks to the growing revolution in Open Science and preprint outlets like medrxiv.org and arxiv.org, the barrier to performing a decent review of recent COVID-19 research is membership in an academic institution with Google Scholar access, like Starbucks, Southwest Airlines, or your bathroom.

Don’t Use Straw Men to Represent the State of the Art.

The piece begins with an incorrect and on face unlikely summary of the current state of the art

Right now, the overwhelming consensus, based upon the most recent reports, is that the rate of infection will continue to increase so that the most severe interventions are needed to control what will under the worst of circumstances turn into a high rate of death.

Much of the current analysis does not explain how and why rates of infection and death will spike, so I think that it is important to offer a dissenting voice.

Only two citations are provided. The first is an educational infographic in the opinion section of the NYT. It includes a direct quote from the scientific consultants not to interpret the model as a production forecast

“The point of a model like this is not to try to predict the future but to help people understand why we may need to change our behaviors or restrict our movements, and also to give people a sense of the sort of effect these changes can have,”

The second is a medium blog post, by an MBA/engineer who runs an education website, and collects a number of plots and infographics on COVID-19 from around the web.

If these two examples are representative of something other than the scientific state of the art, e.g. media commentary, then they should be cited specifically in that context and then followed by the long list of actual state of the art academic research that ought to be in the popular discourse. Instead, these two sources are presented as straw men.

Don’t claim the state of the art ignores factors that it actually takes into account.

Epstein’s central criticism is that the epidemiological models at the heart of the scientific consensus share an absurd and incorrect assumption that the rate of the spread of the disease, R0, remains constant over time. R0 is the number of persons, an infected person is likely to pass the disease on to, where above 1 means the diseases will accelerate in growth in the population, 1 means it will remain constant, and below 1 means it will slowly die out. The R0 for COVID-19 is estimated to lie somewhere between 2 and 3 at the start of outbreak in an area.

He believes that state of the art epidemiological models predict very high infection and death rates, because they erroneously set R0 as a fixed constant, and do not adjust it downward over time as individuals and government take action to reduce the spread.

Plainly, no. That is not what state of the art epidemiological models do, and that’s not why they reach high predictions of cases and deaths.

The easiest way to tell that that interpretation is wrong is to simply think through what a time constant, greater than 1, R0 implies. It would mean the disease’s progression never slows down, the entire population of 330 million Americans eventually catch it, with a fatality rate of 1% producing 3.3 million fatalities.

The NYT’s infographic he cites suggests 100 million infected and 1 million dead. So R0 mechanically must not remain constant, it must decline from the initial value (R0=2.3 in that model).

The second easiest way to tell that that interpretation is wrong is to actually read the article where it directly specifies a schedule of R0 reduction based on “mild intervention”

The mild intervention as modeled here is where we are now in the United States: It is a status quo in which some gatherings are canceled and there is promotion of social distancing and work from home, but with inadequate testing and unaddressed supply shortages.

The third easiest way to tell that that interpretation is wrong, is to look at any of the COVID-19 pandemic models available online or in published research and see how they handle R0 over time.

For example COVID-19 Scenarios out of the University of Basel allows you to choose between strong, moderate, weak, none, or a user customizable schedule of R0 decline. Epidemic Envisioner in development at MIT has 7 different possible decay functions for R0 to choose from. The Epidemic Calculator allows you to vary the timing of an intervention and its effect on R0. The Swiss-epidemic-model explicitly compares the effect of reducing transmission rates starting today over a range of values from 0 to 100%.

The agent based model behind the Imperial College study examines many different adaptive non-government strategies including case isolation in the home after individual symptoms, voluntary home quarantine if anyone has symptoms, social distancing for those over 70, and social distancing for the entire population. With those in place, it still predicts an 81% infection rate and 2.2 million deaths. The Framework for Reconstructing Epidemiological Dynamics (FRED) out of the University of Pittsburgh is also agent based and takes into account adaptive response that drive R0 down over time. Or this stochastic transmission model fit to data from Wuhan and has a time varying R0. Prem et al. 2020 simulate lifting the control measures in Wuhan, with a fixed R0, but transmission modeled directly by intergenerational mixing as restrictions are lifted again over time.

In general, COVID-19 models, certainly models in production, take into account changes in R0 over time. More precisely, the high end models simulate the direct behaviors that lead to transmissions, of which R0 is a summary statistic. Default parameters are usually set to current levels of mitigation. The completely unmitigated case is no longer a relevant counterfactual, as the world now knows about the disease, and the relevant policy choices are between greater and lesser degrees of mitigation.

Don’t get basic facts wrong.

The piece repeats twice the incorrect fact that COVID-19 has a “relatively short (two-week) incubation period.” Even a cursory search would point to estimates of an incubation period of about 5 days, and an even shorter serial interval of about 4.5 days.

Better yet, when starting research on a new area, reading one of the many existing literature reviews for lay audiences would explain the difference between a serial interval and an incubation period, the time until infectious and the time until symptomatic, and that COVID-19 is particularly dangerous precisely because many people can pass on the disease prior to knowing they have it.

Don’t cherry pick data.

Epstein (2020) chooses to focus on the Case Fatality Rate of South Korea, ostensibly not because its relatively low estimate of 0.92% fits his story, but because its more comprehensive testing makes it more accurate.

It is instructive to see how this analysis fares by taking into account the Korean data, which is more complete than the American data. South Korea has been dealing with the coronavirus since January 20. Since that time, the Korean government has administered a total of 261,335 tests to its citizens. In press releases updated every day, the Korean CDC is reporting (as of March 15) 8,162 total infections against 75 deaths for an overall mortality rate of 0.92 percent.

Selecting on data quality is problematic because South Korea’s draconian testing regime is part of its success in combating COVID-19 and its low CFR. Looking for your car keys under the streetlight not because that’s where they are but that’s where you can see is a universally problematic approach to scientific inquiry, especially so where measurement, governance, and disaster all are strongly related.

Cherry picking a case with good data and good news also misrepresents certainty over the measure. Estimating the Case Fatality Ratio CFR is difficult and can change in either direction over time as data come in. The CFR may not be knowable for months.

Because of this actual CFR estimates for COVID-19 vary wildly across countries. There are heroic attempts to combine several different kinds of data taking into account undercounting to estimate the CFR for cases we care about like China, and they are still finding CFRs north of 1% (1.6%).

Take the consensus explanation seriously.

There are at least two types of fatalities from COVID-19. The first are persons who receive adequate medical care but die anyway. The second are persons who would have survived but received insufficient or degraded medical care.

There is a vein of research on why COVID-19 actually kills you, which in addition to age finds specific vulnerabilities like hypertension, heart disease, diabetes, cardiovascular disease, cancer, chronic respiratory disease, and kidney impairment. The mechanism by which COVID-19 kills includes pneumonia as well as myocardial injury. It may also damage the liver.

Stress on the lungs necessitates oxygen, ventilation, and even intubation which places an enormous strain on healthcare resources. Hospitalization rates in early U.S. CDC data are 25%, and are currently 12% in New York. A proper literature review would find growing , evidence for a relationship between available health resources and mortality. Including that Italy took the start of the disease quite seriously. Further, the early U.S. data show older than 65 accounting for 80% of deaths but only 45% of hospitalizations and 53% of ICU admissions. Young Americans are more likely to survive, but many still require medical intervention to do so.

This is the cause for the sudden spike in mortality reported in the scientific consensus. It’s why the alternative proposal of sheltering in place only older Americans wouldn’t work. Doing so wouldn’t even remove half of the current burden on the healthcare system, and would instead greatly add to it when most adults under 60 contract the disease together at about the same time, and 10% of them head to the hospital at about the same time.

Lesson 5: Don’t Form Strong Prior Beliefs Based on Cherry Picked Data

In setting up our research design, we want to predict U.S. cases but we want to base that prediction on a model fit more broadly on other representative data.

For example, Epstein sets up this small comparison between early U.S. death rates in Washington to peak death rates in Italy or China.

What, then, does all of this portend for the future of COVID-19 in the United States? Good news is more likely than bad, notwithstanding the models that predict otherwise. The deaths in Washington have risen only slowly, even as the number of infections mount.

We should instead phrase this as a question, how does the U.S.’s growth rate in COVID-19 deaths compare to elsewhere? Is early data from one or more states likely to be representative of the U.S. average rate?

To answer this question, we compare each country and each U.S. state side by side, aligning their episodes by the first date each crossed 100 confirmed cases. We fit a linear trend line to the cumulative count of deaths in each country (log transformed). From the slope of that line we can calculate the day over day average percent change in deaths in each location.

Here are the raw data for countries with more than 100 cases, with coloring and trend lines fit to the 4 suggested case comparisons, Italy, China, Washington State, and the U.S. as a whole.

And here is the distribution of average growth rates in deaths in the first 30 days across countries and U.S. states.

In answer to the first question, the U.S. growth rate in deaths is 24.48% which is above the median across countries 18.8%. The U.S. rate is below Italy (29.32%) and China (29.58%), but just below.7

In answer to the second question, Washington State was and continues to be an example of lower growth in death rates (11.7%), which at half of the average U.S. rate is not representative of the country as a whole.8

The Epstein piece goes on to say

The New York cases have been identified for long enough that they should have produced more deaths if the coronavirus was as dangerous as is commonly believed.

I don’t entirely know what this sentence is supposed to mean, but New York’s day on day growth in fatalities is the second highest in the world in these data, just behind Massachusetts at 52.28%.

The lesson here being that intentionally looking for early “good news” means necessarily ignoring actual news relevant to the research question.9

Lesson 6: Be Specific and Concrete About Your Theory

To proceed further, we need to attempt to distill Richard Epstein’s Model of Epidemiology and Disease (here after REMED). Getting REMED requires holding several simple but contradictory ideas at the same time.

The first idea is that the one full cycle of COVID-19 spread and decline, China, is representative of future inflection points for other countries. Overlay the China curve, the China curve breaks, so another country’s curve should break similarly too. (CHINA_INFLECTION)

Overlooked is the good news coming out of China, where the latest report shows 16 new cases and 14 new deaths, suggesting that the number of deaths in the currently unresolved group will be lower than the 5.3 percent conversion rate in the cases resolved to date. In my view, we will see a similar decline in Italy, for reasons that I shall outline in the remainder of this article.

In dealing with this point, it is critical to note that the rapid decline in the incidence of new cases and death in China suggests that cases in Italy will not continue to rise exponentially over the next several weeks.

The second is that, in contrast, the high death rate of China is not representative, it’s idiosyncratic and not what should be expected in other countries because of its high rate of smoking and pollution (SMOKERS, POLLUTION).

My own guess is that the percentage of deaths will decline in Korea for the same reasons that they are expected to decline in the United States. It is highly unlikely that there will ever be a repetition of the explosive situation in Wuhan, where air quality is poorer and smoking rates are higher.

Italy’s death rate is also not representative, it’s idiosyncratic and not what should be expected in other countries. (ITALY)10

Moreover, it is unlikely that the healthcare system in the United States will be compromised in the same fashion as the Italian healthcare system in the wake of its quick viral spread.

The third idea is that China’s heavy-handed policy response is not why its growth curve in deaths broke, and presumably neither will Italy’s heavy handed policy response be responsible when it breaks as well. Therefore he argues, the U.S. should not copy them. (POLICY)

As of March 16, the data from the United States falls short of justifying the draconian measures that are now being implemented. As of two days ago, 39 states have declared states of emergency, and they have been joined at the federal level with President Trump’s recent declaration to the same effect. These declarations are meant to endow governments with the power to impose quarantines and travel bans, close schools, restrict public gatherings, shut down major sporting events, stop public meetings, and close restaurants and bars. Private institutions are imposing similar restrictions. The one-two punch of public and private restrictions has caused a huge jolt to the economy.

The irony here is that even though self-help measures like avoiding crowded spaces make abundant sense, the massive public controls do not. In light of the available raw data, public officials have gone overboard.

My own guess is that the percentage of deaths will decline in Korea for the same reasons that they are expected to decline in the United States.

Despite saying multiple times elsewhere policy does have an independent effect

Various institutional measures, both private and public, have also slowed down the transmission rate.

The amount of voluntary and forced separation in the United States has gotten very extensive very quickly, which should influence rates of infection sooner rather than later.

The fourth idea is the growth and decline curves of COVID-19 are a function of time, and naturally will burn itself out because of

  1. Societal Response (ADAPTATION)

But once people are aware of the disease, they will start to make powerful adaptive responses, including washing their hands and keeping their distance from people known or likely to be carrying the infection. Various institutional measures, both private and public, have also slowed down the transmission rate.

  1. Seasonality (SEASONALITY)

And finally, the model explicitly ignores the possibility that the totals will decline as the weather gets warmer.

  1. Natural selection will breed weaker COVID-19 (WEAKENING)11

At some tipping point, the most virulent viruses will be more likely to kill their hosts before the virus can spread. In contrast, the milder versions of the virus will wreak less damage to their host and thus will survive over the longer time span needed to spread from one person to another. Hence the rate of transmission will trend downward, as will the severity of the virus. It is a form of natural selection.

Given that the coronavirus can spread through droplets and contact, the consequences of selection should manifest themselves more quickly than they did for AIDS.

  1. Natural selection will remove weaker humans (SUSCEPTIBLE)

Nor does the model recognize that if the most vulnerable people are hit first, subsequent iterations will be slower because the remaining pool of individuals is more resistant to infection.

Summary

To get REMED means to believe that:

Let that sink in.

Lesson 7: Choose Enough Cases to Actually Test Your Theory

We can formalize REMED as a series of equations

The rate of deaths at time t is a function of the distance before or after when China’s inflection took place, the degree of societal adaptation, how much the disease has evolved to become less deadly, the number of suceptible people still left in the population, and the season.

\(\partial DEATHS_t =F(CHINAINFLECTION, ADAPTATION,WEAKENING,SUSCEPTIBLE,SEASONALITY, Time)\)

The total number of expected DEATHS in country c, however, is just a function of the policy chosen, smoking population, pollution, and whether or not you are the country of Italy.

\(DEATHS_c=F(Policy, Smokers, Pollution, Italy)\)

Almost all social sciences grad students will be forced to read King, Keohane, and Verba (1997) or something similar in their first year which details how to do small n case selection with an eye toward having enough cases and the right cases to test your explanations. We can express this directly by coding the available cases and putting them into a table.12

Country Deaths Policy Pollution Smoking Italy
China 3,296 Shelter in Place High 2043 No
Italy 9,134* Shelter in Place Low 1493.3 Yes
U.S. 1,475* Shelter in Place Low 1016.6 No

A number of problems should become immediately apparent. First, the number of observations with a final episode count of deaths is just 1, China. Both Italy and the U.S. still show an increasing count. Further, we have 4 different explanations to test but only 1 or at most 2 data points. We don’t have enough degrees of freedom to mathematically demonstrate a relationship between total deaths and every one of these explanations.

Second, we don’t have any variation on the dependent variable, both Italy and China have a high death toll.13 The sample does not include any examples of low death toll countries for us to infer from.

Third, we don’t have variation on the independent variable of interest, policy, either. All three of these countries have shelter in place style policies of one form or another. And, both China’s and Italy’s are more extreme, not less, than the U.S. so far.

We could start to improve on this. First, collapse smoking and pollution into a single lung health index, or for convenience choose just smoking. Second, drop the idiosyncratic explanation for Italy just being different somehow. Third, expand the sample of cases to include variation on both the dependent AND independent variable. That is, we need examples of countries with low death totals. We also need examples of countries with no shelter in place. Here’s what that looks like for the set of countries that have made it to 30 days since 100 confirmed cases.

Country Deaths_at_30_Days Shelter_In_Place Smoking
U.S. ? Yes 1,016.6
Italy 6077 Yes 1493.3
Iran 2234 No 936.5
China 1766 Yes 2,043
South Korea 94 No 1,667
Japan 35 No 1,583

Smoking no longer seems to explain China’s high deaths, Iran has less smoking but a high death count, and South Korea and Japan both have high smoking but a low death count.

Likewise, two of the high death rate countries, Italy and China, have a shelter in place policy, but the third Iran does not. Neither of the low death rate countries South Korea and Japan have a shelter in place policy. Japan’s slow but increasing growth rate remains a mystery but might simply be on a delayed slope.

This stresses the limits of this kind of simple pattern matching exercise. High death rates also cause shelter in place policies. South Korea which pursued early sophisticated containment was able to forgo the need to switch to a delay policy. A simple cross-sectional comparison of countries isn’t sufficient to tell us whether a shelter in place policy worked.

In sum, cross-national analogies are insufficient to answer this research question. What we need are the fine grained time-series cross-sectional data and simulations that empidimiologists are using to construct concrete counterfactuals to guide policy makers.

Lesson 8: Convey Uncertainty with Specificity not Doublespeak

The Epstein piece presents itself as if its communicating confidence and uncertainty, e.g. using the words likely/unlikely/probable/guess 9 times. There are mathematical ways of explicitly communicating uncertainty, and where that uncertainty lies in measurement, parameter, or prediction. There are even ways of communicating uncertainty to a qualitative audience, e.g. the CIA’s desperate mapping from probabilities to adjectives for lay policymakers.

There is also a wrong way to convey uncertainty which is to pepper your language with contradictory hedging and doublespeak that generates uncertainty in the reader’s mind about what you actually mean.

For example:

That estimate is ten times greater than the 500 number I erroneously put in the initial draft of the essay, and it, too, could prove somewhat optimistic.

Epstein’s first guess was immediately wrong, so here’s a new guess that might also be immediately wrong.

Perhaps my analysis is all wrong, even deeply flawed. But the stakes are too high to continue on the current course without reexamining the data and the erroneous models that are predicting doom.

The stakes are too high not to say completely flawed things!

Don’t do this. It’s not honestly conveying uncertainty, it’s attempting to cover your ass from being held accountable later.

Conclusion

The challenge in reviewing analyses like these lies in their incurious and insincere construction. They’re not an earnest search for scientific truth in themselves, they’re at best a Socratic call for others to point out mistakes and explain the state of the art. Epstein explicitly frames his approach to inquiry as the construction of arguments and not rigorous study.

I don’t care who’s a professional or not you don’t win an argument by showing you got a PhD you win an argument by entering into a public debate with people who disagree.14

That is not a viable or preferred way to collectively learn about COVID-19. It is an order of magnitude less effort to spam poorly constructed hypotheticals than it is to deconstruct them. This review took a substantial amount of time, and in the meantime the original piece was poorly revised, several interviews and a podcast were released, and a second post trying to cover for the first went live.15 More will no doubt soon continue to move the goal posts and argument. In a world where actual life or death policy analysis is being treated like a high school debate round, the only strategic move is to step back, slow down, and draw methodological lessons for our students and colleagues that will apply to a broad set of current and future analyses.

Epstein (2020a,2020a2,2020b) and analysis like it shouldn’t be rejected because the author is out of their lane. It should be rejected because it’s bad work. I’m not an epidemiologist either, but even as just as a lowly social scientist, I can show lots of different specific ways that the analysis fails to meet basic standards of scientific inference. An epidemiologist would have even more detailed empirically relevant issues to point out. In this current time of crisis, we should resist the urge to gate-keep and instead encourage honesty, curiosity, high standards, and good work. Even blatantly incurious and bad work can serve as a pedagogical tool to train young researchers what not to do. We need to take these opportunities to learn so that we are all smarter and better prepared for the next crisis.


  1. If you found this note useful, please consider donating a few minutes to contribute examples of government COVID-19 quarantine measures to the TIGR Project↩︎

  2. Director of the Machine Learning for Social Science Lab, Center for Peace and Security Studies, University of California San Diego↩︎

  3. Acknowledgments: I thank a good chunk of the NYU Law Class of 2013 for suggesting the subject of this review, and am grateful for many helpful comments and corrections from friends and colleagues.↩︎

  4. Can you imagine if this turned out to be right? Someone has to be holding the winning lotto number, and picking long odds outcomes can be high risk high reward.↩︎

  5. Typos are verbatim.↩︎

  6. And hilarious.↩︎

  7. This plot and sentence are the most sensitive to new incoming data because the U.S. is so early in its outbreak. Between runs, the U.S. average rate of increase in deaths has risen several percent to above the median and closer to Italy and China. A few countries with only a few days of data have pulled back from outliers to within the rest of the distribution. The reader is encouraged to run the R code themselves downloadable directly from this notebook and regenerate the figures based on the latest data.↩︎

  8. Some of these states entered their episode after the article was posted on March 16th. Where possible I will try to give leeway in that regard, but on the other hand one of the immediate consequences of cherry picking early data from one state is that you’ll be shown immediately wrong when a few more days of data come in.↩︎

  9. Left as an exercise to the reader to see how hard exactly you have to squint before you see “good news” from these data.↩︎

  10. The implied variable is unknown because neither the sentence nor linked NYT article provides an argument for why the U.S. health system is different or should perform better than the Italian health system. The implied theoretical variable remains a mystery. https://web.archive.org/web/20200319191049/https://www.nytimes.com/2020/03/12/world/europe/12italy-coronavirus-health-care.html↩︎

  11. I defer to actual epidemiologists to tackle this idea. My current understanding is that COVID-19 is asymptomatic in as many as 80% of cases, it’s not killing those hosts before it spreads. It’s also communicable up to a couple of days before symptoms do emerge in those who are symptomatic, it’s spreading before killing those hosts as well. And the people who it is killing are heading to hospitals first, where it’s being transmitted to healthcare workers at alarming rates. This strikes me as a basic lack of understanding about how fitness constraints encourage change in agents over time. Banking on it to occur in a timeline soon enough to avoid a peak in cases in the U.S., without citing a single empirical work, is willfully ignorant.↩︎

  12. Smoking coded as cigarette consumption per person per year from Wikipedia, https://en.wikipedia.org/wiki/List_of_countries_by_cigarette_consumption_per_capita ↩︎

  13. What counts as low is a moving target because the original piece predicted only 500 for the U.S. and said it wasn’t likely to reach the high number of China’s because China had more smokers. Now Italy’s high death count is the new high. But he forecasts 5,000 for the U.S. which would then make it the new high. But this is contrast to the NYT estimate of a million, so maybe these are all really low. In either case, there’s still no variation on the dependent variable. ↩︎

  14. In this friendly interview for Reason he brags about being able to win arguments through content and not appeals to authority, but a couple of days later in an unfriendly interview with The New Yorker he literally challenges the journalist to compare resumes, “You just don’t know anything about anything. You’re a journalist. Would you like to compare your résumé to mine?” Tells like this are very convenient signals for separating speakers who are sincere but wrong from speakers who are insincere grifters. https://www.newyorker.com/news/q-and-a/the-contrarian-coronavirus-theory-that-informed-the-trump-administration↩︎

  15. And the schema for the underlying COVID-19 data changed breaking a lot of code.↩︎

LS0tCnRpdGxlOiAiSG93IHRvIGJlIEN1cmlvdXMgSW5zdGVhZCBvZiBDb250cmFyaWFuIEFib3V0IENPVklELTE5OiBFaWdodCBEYXRhIFNjaWVuY2UgTGVzc29ucyBGcm9tICdDb3JvbmF2aXJ1cyBQZXJzcGVjdGl2ZScgKEVwc3RlaW4gMjAyMCkiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKZGF0ZTogCmF1dGhvcjogCmFmZmlsaWF0aW9uOiBEaXJlY3RvciwgTWFjaGluZSBMZWFybmluZyBmb3IgU29jaWFsIFNjaWVuY2UgTGFiLCBDZW50ZXIgZm9yIFBlYWNlIGFuZCBTZWN1cml0eSBTdHVkaWVzLCBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEgU2FuIERpZWdvCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYmxvY2txdW90ZSB7CiAgICBwYWRkaW5nOiAxMHB4IDIwcHg7CiAgICBtYXJnaW46IDAgMCAyMHB4OwogICAgZm9udC1zaXplOiAxNHB4OwogICAgYm9yZGVyLWxlZnQ6IDVweCBzb2xpZCAjZWVlOwp9Cjwvc3R5bGU+CgoKKipSZXggVy4gRG91Z2xhc3MgUGhEKiogXltJZiB5b3UgZm91bmQgdGhpcyBub3RlIHVzZWZ1bCwgcGxlYXNlIGNvbnNpZGVyIGRvbmF0aW5nIGEgZmV3IG1pbnV0ZXMgdG8gY29udHJpYnV0ZSBleGFtcGxlcyBvZiBnb3Zlcm5tZW50IENPVklELTE5IHF1YXJhbnRpbmUgbWVhc3VyZXMgdG8gdGhlIFtUSUdSIFByb2plY3RdKGh0dHBzOi8vZ2l0aHViLmNvbS9yZXhkb3VnbGFzcy9USUdSKV0gCiBeW0RpcmVjdG9yIG9mIHRoZSBNYWNoaW5lIExlYXJuaW5nIGZvciBTb2NpYWwgU2NpZW5jZSBMYWIsIENlbnRlciBmb3IgUGVhY2UgYW5kIFNlY3VyaXR5IFN0dWRpZXMsIFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSBTYW4gRGllZ29dCgpbW0BSZXhEb3VnbGFzc11dKGh0dHBzOi8vdHdpdHRlci5jb20vUmV4RG91Z2xhc3Mvc3RhdHVzLzEyNDM3MjMxMjAzODIzMTY1NTApCgoqKjMvMzAvMjAyMCoqIAoKW1dvcmtpbmcgRHJhZnQuIENPTU1FTlRTIFdFTENPTUUhXV5bQWNrbm93bGVkZ21lbnRzOiBJIHRoYW5rIGEgZ29vZCBjaHVuayBvZiB0aGUgTllVIExhdyBDbGFzcyBvZiAyMDEzIGZvciBzdWdnZXN0aW5nIHRoZSBzdWJqZWN0IG9mIHRoaXMgcmV2aWV3LCBhbmQgYW0gZ3JhdGVmdWwgZm9yIG1hbnkgaGVscGZ1bCBjb21tZW50cyBhbmQgY29ycmVjdGlvbnMgZnJvbSBmcmllbmRzIGFuZCBjb2xsZWFndWVzLl0KCgoKYGBge3IsIGVjaG89RiwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGdnaGlnaGxpZ2h0KQoKYGBgCgpgYGB7ciwgZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoUjApICAjIGNvbnNpZGVyIG1vdmluZyBhbGwgbGlicmFyeSBjb21tYW5kcyB0byB0b3AgLS0gdGhpcyBvbmUgd2FzIGluIGEgbG9vcCBiZWxvdwojVW50aWwgdGhlIFUuUy4gc3RhdGVzIG9uZSBnb2VzIGxpdmUgaGF2ZSB0byBwdWxsIGl0IGZyb20gaGVyZQpjb25maXJtZWRfb2xkIDwtIHJlYWRfY3N2KHVybCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5L21hc3Rlci9hcmNoaXZlZF9kYXRhL2FyY2hpdmVkX3RpbWVfc2VyaWVzL3RpbWVfc2VyaWVzXzE5LWNvdmlkLUNvbmZpcm1lZF9hcmNoaXZlZF8wMzI1LmNzdiIpKSAjdXNpbmcgdGhlIGFyY2hpdmVkIGNvcHkgZnJvbSB0b2RheSBiZWNhdXNlIHRoZXkgaGF2ZW4ndCBwb3N0ZWQgdGhlIHNlcGVyYXRlIFUuUy4gZGF0YSB5ZXQKZGVhdGhzX29sZCA8LSByZWFkX2Nzdih1cmwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOS9tYXN0ZXIvYXJjaGl2ZWRfZGF0YS9hcmNoaXZlZF90aW1lX3Nlcmllcy90aW1lX3Nlcmllc18xOS1jb3ZpZC1EZWF0aHNfYXJjaGl2ZWRfMDMyNS5jc3YiKSkKI3JlY292ZXJlZCA8LSByZWFkX2Nzdih1cmwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOS9tYXN0ZXIvYXJjaGl2ZWRfZGF0YS9hcmNoaXZlZF90aW1lX3Nlcmllcy90aW1lX3Nlcmllc18xOS1jb3ZpZC1SZWNvdmVyZWRfYXJjaGl2ZWRfMDMyNS5jc3YiKSkKY29uZmlybWVkX29sZF9sb25nIDwtIHBpdm90X2xvbmdlcihjb25maXJtZWRfb2xkLCBuYW1lc190byA9ICJkYXRlIiwgY29scyA9IGVuZHNfd2l0aCgiMjAiKSwgdmFsdWVzX3RvID0gImNvbmZpcm1lZCIpCmRlYXRoc19vbGRfbG9uZyA8LSBwaXZvdF9sb25nZXIoZGVhdGhzX29sZCwgbmFtZXNfdG8gPSAiZGF0ZSIsIGNvbHMgPSBlbmRzX3dpdGgoIjIwIiksIHZhbHVlc190byA9ICJkZWF0aHMiKQojcmVjb3ZlcmVkX2xvbmcgPC0gcGl2b3RfbG9uZ2VyKHJlY292ZXJlZCwgbmFtZXNfdG8gPSAiZGF0ZSIsIGNvbHMgPSBlbmRzX3dpdGgoIjIwIiksIHZhbHVlc190byA9ICJyZWNvdmVyZWQiKQoKIwojaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5L21hc3Rlci9jc3NlX2NvdmlkXzE5X2RhdGEvY3NzZV9jb3ZpZF8xOV90aW1lX3Nlcmllcy90aW1lX3Nlcmllc19jb3ZpZDE5X2RlYXRoc19nbG9iYWwuY3N2CmNvbmZpcm1lZCA8LSByZWFkX2Nzdih1cmwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOS9tYXN0ZXIvY3NzZV9jb3ZpZF8xOV9kYXRhL2Nzc2VfY292aWRfMTlfdGltZV9zZXJpZXMvdGltZV9zZXJpZXNfY292aWQxOV9jb25maXJtZWRfZ2xvYmFsLmNzdiIpKSAjdXNpbmcgdGhlIGFyY2hpdmVkIGNvcHkgZnJvbSB0b2RheSBiZWNhdXNlIHRoZXkgaGF2ZW4ndCBwb3N0ZWQgdGhlIHNlcGVyYXRlIFUuUy4gZGF0YSB5ZXQKZGVhdGhzIDwtIHJlYWRfY3N2KHVybCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5L21hc3Rlci9jc3NlX2NvdmlkXzE5X2RhdGEvY3NzZV9jb3ZpZF8xOV90aW1lX3Nlcmllcy90aW1lX3Nlcmllc19jb3ZpZDE5X2RlYXRoc19nbG9iYWwuY3N2IikpCgpjb25maXJtZWRfbG9uZyA8LSBwaXZvdF9sb25nZXIoY29uZmlybWVkLCBuYW1lc190byA9ICJkYXRlIiwgY29scyA9IGVuZHNfd2l0aCgiMjAiKSwgdmFsdWVzX3RvID0gImNvbmZpcm1lZCIpCmRlYXRoc19sb25nIDwtIHBpdm90X2xvbmdlcihkZWF0aHMsIG5hbWVzX3RvID0gImRhdGUiLCBjb2xzID0gZW5kc193aXRoKCIyMCIpLCB2YWx1ZXNfdG8gPSAiZGVhdGhzIikKI3JlY292ZXJlZF9sb25nIDwtIHBpdm90X2xvbmdlcihyZWNvdmVyZWQsIG5hbWVzX3RvID0gImRhdGUiLCBjb2xzID0gZW5kc193aXRoKCIyMCIpLCB2YWx1ZXNfdG8gPSAicmVjb3ZlcmVkIikKCldITyA8LSByZWFkX2Nzdih1cmwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kYXRhc2V0cy9jb3ZpZC0xOS9tYXN0ZXIvZGF0YS9jb3VudHJpZXMtYWdncmVnYXRlZC5jc3YiKSkKCiNQdXNoIHRoZSBDaGluZXNlIGNvdW50IGJhY2sgdG8gdW5kZXIgMTAwCiNodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS8yMDE5JUUyJTgwJTkzMjBfY29yb25hdmlydXNfcGFuZGVtaWNfaW5fbWFpbmxhbmRfQ2hpbmEKZWFybHlfY2hpbmVzZSA8LSBkYXRhLmZyYW1lKAogIGRhdGVfYXNkYXRlPXltZCgiMjAyMC0wMS0yMiIpLTc6MSwKICBjb25maXJtZWQ9Yyg0MSw0NSw2MiwxMjEsMTk4LDI5MSw0NDApLAogIGRlYXRocz1jKDAsMCwwLDAsMCwwLDApCikKZWFybHlfY2hpbmVzZSRjb3VudHJ5ID0gIkNoaW5hIgoKYWxsX2xvbmcgPC0gYmluZF9yb3dzKAogICAgICAgICAgICAgIGRlYXRoc19sb25nICU+JSBmdWxsX2pvaW4oY29uZmlybWVkX2xvbmcpICAlPiUKICAgICAgICAgICAgICAjZnVsbF9qb2luKHJlY292ZXJlZF9sb25nKSAlPiUKICAgICAgICAgICAgICAjZmlsdGVyKGNvbmZpcm1lZD4wKSAlPiUgCiAgICAgICAgICAgIAogICAgICAgICAgICAgIG11dGF0ZShkYXRlX2FzZGF0ZSA9IG1keShzdHJfcmVwbGFjZShkYXRlLCIyMCQiLCIyMDIwIikpKSAlPiUgCiAgICAgICAgICAgICAgcmVuYW1lKGNvdW50cnk9YENvdW50cnkvUmVnaW9uYCwgc3RhdGU9YFByb3ZpbmNlL1N0YXRlYCkgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKCFjb3VudHJ5ICVpbiUgYygiRnJvbSBEaWFtb25kIFByaW5jZXNzIiwiRGlhbW9uZCBQcmluY2VzcyIsIkNydWlzZSBTaGlwIikpLAogICAgICAgICAgICAgIAogICAgICAgICAgICAgIGVhcmx5X2NoaW5lc2UKICAgICAgICAgICAgKSAKCgoKcGFkZGVkIDwtIGFsbF9sb25nICU+JQogICAgICAgICAgICB0aWR5cjo6ZXhwYW5kKCBjb3VudHJ5LCBkYXRlX2FzZGF0ZT1taW4oYWxsX2xvbmckZGF0ZV9hc2RhdGUpKzA6MjIzICkgJT4lIGRpc3RpbmN0KCkKCmNvdW50cmllc19sb25nIDwtIHBhZGRlZCAlPiUgbGVmdF9qb2luKGFsbF9sb25nKSAlPiUKICAgICAgICAgICAgICAgICAgYXJyYW5nZShjb3VudHJ5LCBkYXRlX2FzZGF0ZSkgJT4lCiAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGNvdW50cnksZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgICAgICAgIHN1bW1hcml6ZShkZWF0aHM9c3VtKGRlYXRocywgbmEucm09VCksIGNvbmZpcm1lZD1zdW0oY29uZmlybWVkLCBuYS5ybT1UKSkgJT4lCiAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUKICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoY291bnRyeSkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9jdW1tYXg9Y3VtbWF4KGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzFfY29uZmlybWVkPWN1bXN1bShjb25maXJtZWRfY3VtbWF4PjApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV81MF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+NTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPWN1bXN1bShjb25maXJtZWRfY3VtbWF4PjEwMCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+NTAwKSkgJT4lCgogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfY3VtbWF4PWN1bW1heChkZWF0aHMpKSAlPiUgICAgICAgIAogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzFfZGVhdGhzPWN1bXN1bShkZWF0aHNfY3VtbWF4PjApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV81MF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+NTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMDBfZGVhdGhzPWN1bXN1bShkZWF0aHNfY3VtbWF4PjEwMCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+NTAwKSkgJT4lCiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9mZD1jb25maXJtZWQtbGFnKGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfZmQ9ZGVhdGhzLWxhZyhkZWF0aHMpKSAlPiUKICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICBhcnJhbmdlKGNvdW50cnksIGRhdGVfYXNkYXRlKSAlPiUKICAgICAgCiAgICAgICAgICAgICAgICAgICNmaWx0ZXIoZGF5c19zaW5jZV8xX2NvbmZpcm1lZD4wKSAlPiUKICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoY291bnRyeSkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9tYXg9bWF4KGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICB1bmdyb3VwKCkgJT4lCiAgICAgICAKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRlYXRocz1pZmVsc2UoZGVhdGhzPT0wICYgZGVhdGhzX2N1bW1heD4wLCBOQSxkZWF0aHMpKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZD1pZmVsc2UoY29uZmlybWVkPT0wICYgY29uZmlybWVkX2N1bW1heD4wLCBOQSxjb25maXJtZWQpKSAKCnVzX2xvbmcgPC0gZGVhdGhzX29sZF9sb25nICU+JSBmdWxsX2pvaW4oY29uZmlybWVkX29sZF9sb25nKSAgJT4lCiAgICAgICAgICAgICAgICBtdXRhdGUoZGF0ZV9hc2RhdGUgPSBtZHkoc3RyX3JlcGxhY2UoZGF0ZSwiMjAkIiwiMjAyMCIpKSkgJT4lIAogICAgICAgICAgICAgICAgcmVuYW1lKGNvdW50cnk9YENvdW50cnkvUmVnaW9uYCwgc3RhdGU9YFByb3ZpbmNlL1N0YXRlYCkgJT4lCiAgICAgICAgICAgICAgICBmaWx0ZXIoIWNvdW50cnkgJWluJSBjKCJGcm9tIERpYW1vbmQgUHJpbmNlc3MiLCJEaWFtb25kIFByaW5jZXNzIiwiQ3J1aXNlIFNoaXAiKSkgJT4lIAogICAgICAgICAgICAgICAgZmlsdGVyKGNvdW50cnkgJWluJSAiVVMiKSAlPiUKICAgICAgICAgICAgICAgIGZpbHRlcihzdGF0ZSE9IlVTIikgICAjdGhleSB3ZW50IGFuZCBhZGRlZCB0aGUgVVMgYXMgYSBzdGF0ZQogICAgICAgCnVzX2xvbmcgPC0gcGFkZGVkICU+JQogICAgICAgICAgIGxlZnRfam9pbih1c19sb25nKSAlPiUgCiAgICAgICAgICBmaWx0ZXIoY291bnRyeSAlaW4lICJVUyIpICU+JQogICAgICAgICAgZmlsdGVyKHN0YXRlIT0iVVMiKSAlPiUgICN0aGV5IHdlbnQgYW5kIGFkZGVkIHRoZSBVUyBhcyBhIHN0YXRlCiAKICAgICAgICAgICAgICAgICAgYXJyYW5nZShjb3VudHJ5LCBzdGF0ZSxkYXRlX2FzZGF0ZSkgJT4lCiAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGNvdW50cnksc3RhdGUsZGF0ZV9hc2RhdGUpICU+JQogICAgICAgICAgICAgICAgICAgIHN1bW1hcml6ZShkZWF0aHM9c3VtKGRlYXRocywgbmEucm09VCksIGNvbmZpcm1lZD1zdW0oY29uZmlybWVkLCBuYS5ybT1UKSkgJT4lCiAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUKICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoY291bnRyeSxzdGF0ZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9jdW1tYXg9Y3VtbWF4KGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzFfY29uZmlybWVkPWN1bXN1bShjb25maXJtZWRfY3VtbWF4PjApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV81MF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+NTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPWN1bXN1bShjb25maXJtZWRfY3VtbWF4PjEwMCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+NTAwKSkgJT4lCgogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfY3VtbWF4PWN1bW1heChkZWF0aHMpKSAlPiUgICAgICAgIAogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzFfZGVhdGhzPWN1bXN1bShkZWF0aHNfY3VtbWF4PjApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV81MF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+NTApKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMDBfZGVhdGhzPWN1bXN1bShkZWF0aHNfY3VtbWF4PjEwMCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+NTAwKSkgJT4lCiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGNvbmZpcm1lZF9mZD1jb25maXJtZWQtbGFnKGNvbmZpcm1lZCkpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfZmQ9ZGVhdGhzLWxhZyhkZWF0aHMpKSAlPiUKICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICBhcnJhbmdlKGNvdW50cnksIGRhdGVfYXNkYXRlKSAlPiUKICAgICAgCiAgICAgICAgICAgICAgICAgICNmaWx0ZXIoZGF5c19zaW5jZV8xX2NvbmZpcm1lZD4wKSAlPiUKICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoY291bnRyeSwgc3RhdGUpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfbWF4PW1heChjb25maXJtZWQpKSAlPiUKICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHM9aWZlbHNlKGRlYXRocz09MCwgTkEsZGVhdGhzKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWQ9aWZlbHNlKGNvbmZpcm1lZD09MCwgTkEsY29uZmlybWVkKSkgCgp1c19zdGF0ZXNfbG9uZyA8LSB1c19sb25nICU+JSBmaWx0ZXIoIXN0cl9kZXRlY3Qoc3RhdGUsIiwiKSkKI3RhYmxlKHVzX3N0YXRlc19sb25nJGNvdW50cnkpCiN0YWJsZSh1c19zdGF0ZXNfbG9uZyRzdGF0ZSkKCmNvdW50cmllc19hbmRfdXNfc3RhdGVzIDwtIGJpbmRfcm93cyhjb3VudHJpZXNfbG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzX3N0YXRlc19sb25nKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHByZWZlcmVkX2xhYmVsID0gaWZlbHNlKCBpcy5uYShzdGF0ZSkgfCBzdGF0ZT09JycgfCBzdGF0ZT09IlVTIiwgICBjb3VudHJ5LCBwYXN0ZTAoc3RhdGUsICIsICIsIGNvdW50cnkpICkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZShwcmVmZXJlZF9sYWJlbCwgZGF0ZV9hc2RhdGUpCgojdGFibGUoY291bnRyaWVzX2FuZF91c19zdGF0ZXMkY291bnRyeSkKI3RhYmxlKGNvdW50cmllc19hbmRfdXNfc3RhdGVzJHN0YXRlKQojdGFibGUoY291bnRyaWVzX2FuZF91c19zdGF0ZXMkcHJlZmVyZWRfbGFiZWwpCgojV2VyZSB3ZSBkb3VibGUgY291bnRpbmc/Cgp3b3JsZF9sb25nIDwtIGRlYXRoc19sb25nICU+JSAKICAgICAgICAgICAgICBmdWxsX2pvaW4oY29uZmlybWVkX2xvbmcpICU+JSAKICAgICAgICAgICAgICBmdWxsX2pvaW4ocmVjb3ZlcmVkX2xvbmcpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25maXJtZWQ+MCkgJT4lIAogICAgICAgICAgICAKICAgICAgICAgICAgICBtdXRhdGUoZGF0ZV9hc2RhdGUgPSBtZHkoc3RyX3JlcGxhY2UoZGF0ZSwiMjAkIiwiMjAyMCIpKSkgJT4lIAogICAgICAgICAgICAgIHJlbmFtZShjb3VudHJ5PWBDb3VudHJ5L1JlZ2lvbmAsIHN0YXRlPWBQcm92aW5jZS9TdGF0ZWApICMlPiUKICAgICAgICAgICAgICAjZmlsdGVyKCFzdGF0ZSAlaW4lIGMoIkZyb20gRGlhbW9uZCBQcmluY2VzcyIsIkRpYW1vbmQgUHJpbmNlc3MiKSkgJT4lCiAgCndvcmxkX2xvbmcgPC0gcGFkZGVkICU+JSBsZWZ0X2pvaW4oYWxsX2xvbmcpICU+JQogICAgICAgICAgICAgICAgICBncm91cF9ieShkYXRlX2FzZGF0ZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplKGRlYXRocz1zdW0oZGVhdGhzLCBuYS5ybT1UKSwgY29uZmlybWVkPXN1bShjb25maXJtZWQsIG5hLnJtPVQpKSAlPiUKICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICBhcnJhbmdlKGRhdGVfYXNkYXRlKSAlPiUKCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWRfY3VtbWF4PWN1bW1heChjb25maXJtZWQpKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRheXNfc2luY2VfMV9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+MCkpICU+JQogICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRheXNfc2luY2VfNTBfY29uZmlybWVkPWN1bXN1bShjb25maXJtZWRfY3VtbWF4PjUwKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+MTAwKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9jb25maXJtZWQ9Y3Vtc3VtKGNvbmZpcm1lZF9jdW1tYXg+NTAwKSkgJT4lCgogICAgICAgICAgICAgICAgICBtdXRhdGUoZGVhdGhzX2N1bW1heD1jdW1tYXgoZGVhdGhzKSkgJT4lICAgICAgICAKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRheXNfc2luY2VfMV9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+MCkpICU+JQogICAgICAgICAgICAgICAgICBtdXRhdGUoZGF5c19zaW5jZV8xMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+MTApKSAlPiUKICAgICAgICAgICAgICAgICAgbXV0YXRlKGRheXNfc2luY2VfNTBfZGVhdGhzPWN1bXN1bShkZWF0aHNfY3VtbWF4PjUwKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzEwMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+MTAwKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkYXlzX3NpbmNlXzUwMF9kZWF0aHM9Y3Vtc3VtKGRlYXRoc19jdW1tYXg+NTAwKSkgJT4lCiAgICAgIAogICAgICAgICAgICAgICAgICBtdXRhdGUoY29uZmlybWVkX2ZkPWNvbmZpcm1lZC1sYWcoY29uZmlybWVkKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHNfZmQ9ZGVhdGhzLWxhZyhkZWF0aHMpKSAlPiUKICAgICAgICAgICAgICAgICAgYXJyYW5nZShkYXRlX2FzZGF0ZSkgJT4lCiAgCiAgICAgICAgICAgICAgICAgIG11dGF0ZShkZWF0aHM9aWZlbHNlKGRlYXRocz09MCwgTkEsZGVhdGhzKSkgJT4lCiAgICAgICAgICAgICAgICAgIG11dGF0ZShjb25maXJtZWQ9aWZlbHNlKGNvbmZpcm1lZD09MCwgTkEsY29uZmlybWVkKSkKCgpgYGAKCiMgSW50cm9kdWN0aW9uIAoKSG93IHNob3VsZCBub24tZXBpZGVtaW9sb2dpc3RzIHB1YmxpY2x5IGRpc2N1c3MgQ09WSUQtMTkgZGF0YSBhbmQgbW9kZWxzPyBXaGVuIGxlYWRlcnMgYW5kIGNpdGl6ZW5zIGFyZSBlc3BlY2lhbGx5IHNlbnNpdGl2ZSB0byBzaWduYWxzIG9uIHB1YmxpYyBoZWFsdGgsIHdoYXQgaXMgb3VyIGludGVsbGVjdHVhbCByZXNwb25zaWJpbGl0eSB0byBkZWZlciB0byB0aGUgYW5hbHlzaXMgb2YgbW9yZSBleHBlcnQgc3BlYWtlcnM/IEkgYXJndWUgdGhhdCBvdXIgcmVzcG9uc2liaWxpdHkgZHVyaW5nIGNyaXNpcyBpcyB0aGUgc2FtZSBhcyBpdCB3YXMgYmVmb3JlOyB0byBkbyBnb29kIHdvcmssIHRvIHRoZSBiZXN0IG9mIG91ciBhYmlsaXRpZXMsIHdpdGggdGhlIHNjaWVudGlmaWMgcHJpbmNpcGxlcyBvZiBjdXJpb3NpdHkgYW5kIGhvbmVzdHkuIEFsdGVybmF0aXZlIHNob3J0aGFuZHMgbGlrZSAnc3RheWluZyBpbiB5b3VyIGxhbmUnIGFyZSBhIHBvb3IgZGVjaXNpb24gcnVsZSBmb3Igc29ydGluZyBnb29kIHdvcmsgZnJvbSBiYWQsIGFuZCB0aGV5IGlnbm9yZSB0aGUgdmVyeSBtZXNzeSBwcm9jZXNzIHRoYXQgdW5kZXJsaWVzIHJlYWwtd29ybGQgc2NpZW50aWZpYyBpbnF1aXJ5LiBMYW5lLWtlZXBpbmcgaXMgYSBwb29yIHdheSB0byBsZWFybiBhbmQgYmVjb21lIGEgYmV0dGVyIGNvbnN1bWVyIG9mIGV4cGVydCBmaW5kaW5ncywgYW5kIGdhdGUta2VlcGluZyBpcyBhIG1pc3NlZCBvcHBvcnR1bml0eSB0byBwcm92aWRlIHRoZSBwdWJsaWMgZ29vZHMgb2YgZmVlZGJhY2sgYW5kIHJldmlldy4gVG8gZGVtb25zdHJhdGUgdGhlIHBvaW50LCB0aGlzIG5vdGUgcHJvdmlkZXMgYSBkZXRhaWxlZCByZXZpZXcgb2YgYSByZWNlbnQgcGllY2UgIltDb3JvbmF2aXJ1cyBQZXJzcGVjdGl2ZV0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMjAwMzE5MTY1NTIyL2h0dHBzOi8vd3d3Lmhvb3Zlci5vcmcvcmVzZWFyY2gvY29yb25hdmlydXMtaXNudC1wYW5kZW1pYykiIChFcHN0ZWluIDIwMjBhKS4gQnkgYXBwbHlpbmcgYW5kIGlsbHVzdHJhdGluZyBkYXRhIHNjaWVuY2UgcHJpbmNpcGxlcyBwb2ludCBmb3IgcG9pbnQgdG8gdGhpcyBub24tZXBpZGVtaW9sb2dpY2FsIHRha2Ugb24gZXBpZGVtaW9sb2dpY2FsIHF1ZXN0aW9ucywgaXQgaXMgaG9wZWQgdGhhdCB0aGUgcmVhZGVyIHdpbGwgdGFrZSBhd2F5IG5vdCB3aHkgdGhleSBzaG91bGQgYXZvaWQgd29ya2luZyBvbiBuZXcgdG9waWNzIGJ1dCByYXRoZXIgaG93IHRoZXkgc2hvdWxkIGFwcHJvYWNoIHRob3NlIHRvcGljcyBpbiBhbiBob25lc3QsIGN1cmlvdXMsIGFuZCByaWdvcm91cyB3YXkuIAoKIyBFcHN0ZWluICgyMDIwYSwgMjAyMGIpCgpFcHN0ZWluIChbMjAyMGFdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDIwMDMxOTE2NTUyMi9odHRwczovL3d3dy5ob292ZXIub3JnL3Jlc2VhcmNoL2Nvcm9uYXZpcnVzLWlzbnQtcGFuZGVtaWMpKSBhcmd1ZXMgdGhhdCB0aGUgVS5TLiBvdWdodCB0byBzaGlmdCBmcm9tIGEgbG9vc2Ugc2hlbHRlciBpbiBwbGFjZSBzdHlsZSBxdWFyYW50aW5lIHRvIGEgbW9yZSBsaW1pdGVkIHNoZWx0ZXIgaW4gcGxhY2UgZm9yIGp1c3QgdnVsbmVyYWJsZSBwb3B1bGF0aW9ucy4gSGUgcHJvdmlkZXMgdHdvIHByaW1hcnkgcmF0aW9uYWxlcy4gRmlyc3QsIHRoZSBudW1iZXIgb2YgY2FzZXMgYW5kIG51bWJlciBvZiBkZWF0aHMgYm90aCBpbiB0aGUgVS5TLiBhbmQgd29ybGR3aWRlIGFyZSBsaWtlbHkgdG8gYmUgc21hbGwuIFNlY29uZCwgbW9ydGFsaXR5IGZvciB1bmRlciA2MCBpcyByZWxhdGl2ZWx5IGxvdy4gVG9nZXRoZXIsIHRoZSB0d28gaWRlYXMgc3VnZ2VzdCB0aGF0IHJlc3RyaWN0aW9ucyBvbiBhbGwgZ3JvdXBzIGlzIG92ZXJraWxsIGFuZCBzb21lIGNvbXByb21pc2Ugd2Vha2VyIHBvc2l0aW9uIGlzIHByZWZlcnJlZC4gSGUgcmVpdGVyYXRlcyB0aGlzIHBvc2l0aW9uIGluIGEgbnVtYmVyIG9mIFtpbnRlcnZpZXdzXShodHRwczovL3JlYXNvbi5jb20vdmlkZW8vZG9udC1leHBlY3QtbWlsbGlvbnMtdG8tZGllLWZyb20tY29yb25hdmlydXMtc2F5cy1yaWNoYXJkLWVwc3RlaW4vKS4gSW4gYSBmb2xsb3cgdXAgcGllY2UgRXBzdGVpbiAoWzIwMjBiXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAyMDAzMTkxNjU1MjIvaHR0cHM6Ly93d3cuaG9vdmVyLm9yZy9yZXNlYXJjaC9jb3JvbmF2aXJ1cy1pc250LXBhbmRlbWljKSkgZG91YmxlcyBkb3duIG9uIHRoZSBjb3JlIGFyZ3VtZW50IHRoYXQgdGhlIGRpcmVjdCBoZWFsdGggY29zdHMgb2YgdGhlIGRpc2Vhc2Ugd2lsbCBiZSBtb2RlcmF0ZSBhbmQgYSB3ZWFrZW5lZCByZXNwb25zZSBzaG91bGQgYmUgcHJlZmVycmVkLCAiYWxsb3dpbmcgdGhlIHZpcnVzIHRvIHJ1biBpdHMgY291cnNl4oCUaXMgYSBiZXR0ZXIgcGF0aCBmb3J3YXJkIGZvciB0aGUgZWNvbm9teS4iIEFmdGVyIHRoZSBVLksuIGJyaWVmbHkgZmxpcnRlZCB3aXRoIHRoaXMgYXBwcm9hY2ggYmVmb3JlIHJlamVjdGluZyBpdCwgdGhlIG9wdGlvbiBpcyBiZWluZyBjaXJjdWxhdGVkIHB1YmxpY2x5IGF0IHRoZSBmZWRlcmFsIGxldmVsIGluIHRoZSBVLlMuIGFuZCB0aGlzIHRleHQgc3BlY2lmaWNhbGx5IGlzIHJlcG9ydGVkbHkgW3BvcHVsYXIgYW1vbmcgc29tZSBVLlMuIHBvbGljeSBtYWtlcnNdKGh0dHBzOi8vd3d3Lndhc2hpbmd0b25wb3N0LmNvbS9wb2xpdGljcy90cnVtcC1zaWduYWxzLWdyb3dpbmctd2VhcmluZXNzLXdpdGgtc29jaWFsLWRpc3RhbmNpbmctYW5kLW90aGVyLXN0ZXBzLWFkdm9jYXRlZC1ieS1oZWFsdGgtb2ZmaWNpYWxzLzIwMjAvMDMvMjMvMDkyMGVhMGEtNmNmYy0xMWVhLWEzZWMtNzBkNzQ3OWQ4M2YwX3N0b3J5Lmh0bWwpIGFuZCByZWZlcmVkIHRvIGFzIGEgW2NvbXBldGluZyBwcm9qZWN0aW9uXShodHRwczovL3RoZWZlZGVyYWxpc3QuY29tLzIwMjAvMDMvMTkvd2lsbC10aGUtY29zdHMtb2YtYS1ncmVhdC1kZXByZXNzaW9uLW91dHdlaWdoLXRoZS1yaXNrcy1vZi1jb3JvbmF2aXJ1cy8pLiBGb3IgdGhhdCByZWFzb24gaXQgc2VydmVzIGEgcHJpbWUgY2FzZSBmb3IgY29uc2lkZXJhdGlvbiBvbiBob3cgdG8gdGhpbmsgYWJvdXQgbm9uLWVwaWRlbWlvbG9naXN0cyB0YWxraW5nIGFib3V0IHNjaWVudGlmaWMgcXVlc3Rpb24gdGhhdCBhcmUgZGVjaWRlZGx5IG91dCBvZiB0aGVpciBsYW5lLgoKIyBMZXNzb24gMTogQWN0dWFsbHkgQ2FyZSBBYm91dCB0aGUgQW5zd2VyIHRvIGEgUXVlc3Rpb24KCkVwc3RlaW4gKFsyMDIwYV0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMjAwMzE5MTY1NTIyL2h0dHBzOi8vd3d3Lmhvb3Zlci5vcmcvcmVzZWFyY2gvY29yb25hdmlydXMtaXNudC1wYW5kZW1pYykpIGZyYW1lcyBpdHNlbGYgYXMgYmVpbmcgY29udHJhcmlhbiByYXRoZXIgdGhhbiBjdXJpb3VzIGFib3V0IHRoZSB0cnVlIHN0YXRlIG9mIHRoZSB3b3JsZC4KCj4gTXVjaCBvZiB0aGUgY3VycmVudCBhbmFseXNpcyBkb2VzIG5vdCBleHBsYWluIGhvdyBhbmQgd2h5IHJhdGVzIG9mIGluZmVjdGlvbiBhbmQgZGVhdGggd2lsbCBzcGlrZSwgc28gSSB0aGluayB0aGF0IGl0IGlzIGltcG9ydGFudCB0byBvZmZlciBhIGRpc3NlbnRpbmcgdm9pY2UuCgo+IFRoZXNlIGFyZSBkZWVwbHkgY29udHJhcmlhbiBlc3RpbWF0ZXMuCgo+IFBlcmhhcHMgbXkgYW5hbHlzaXMgaXMgYWxsIHdyb25nLCBldmVuIGRlZXBseSBmbGF3ZWQuIEJ1dCB0aGUgc3Rha2VzIGFyZSB0b28gaGlnaCB0byBjb250aW51ZSBvbiB0aGUgY3VycmVudCBjb3Vyc2Ugd2l0aG91dCByZWV4YW1pbmluZyB0aGUgZGF0YSBhbmQgdGhlIGVycm9uZW91cyBtb2RlbHMgdGhhdCBhcmUgcHJlZGljdGluZyBkb29tLgoKU2NpZW5jZSBpcyBhYm91dCBiZWluZyBjdXJpb3VzIGFib3V0IHRoZSB0cnVlIHN0YXRlIG9mIHRoZSB3b3JsZCwgYW5kIHRocm91Z2ggYXBwbGljYXRpb24gb2YgZXZpZGVuY2UgYW5kIG1ldGhvZHMsIGZvcm1pbmcgbmV3IG1vcmUgdHJ1ZSBiZWxpZWZzIHRoYW4gd2UgaGVsZCB0aGUgZGF5IGJlZm9yZS4gIENvbnRyYXJpYW5pc20gaXMgbm90IGEgc2VhcmNoIGZvciB0cnV0aCwgaXQncyBhIHNlYXJjaCBmb3IgcG9saXRpY2FsIGluZmx1ZW5jZSBpbiBhIG1hcmtldCB0aGF0IHJld2FyZHMgZGl2ZXJzaXR5IG9mIG9waW5pb24gZm9yIGRpdmVyc2l0eSdzIHNha2UuIFBlcmZvcm1hdGl2ZSBjb250cm92ZXJzeSwgZmFrZSBob3JzZSByYWNlcywgaHlwb3RoZXNlcyB0aGF0IGRvbid0IGZvbGxvdyBmcm9tIHRoZW9yeSwgbm8gZXhhbWluYXRpb24gb2YgbW9kZWwgZml0IG9yIG91dCBvZiBzYW1wbGUgcGVyZm9ybWFuY2UsIGFuZCBzbyBvbiwgYXJlIGltbWVkaWF0ZSByZWQgZmxhZ3MgdGhlIGF1dGhvciBkb2Vzbid0IGFjdHVhbGx5IGNhcmUgd2hhdCB0aGUgcmlnaHQgYW5zd2VyIGlzLgoKQXMgYSBjb25zdW1lciBvZiBhbmFseXNpcywgdGhlIHNlY29uZCBJIGNhbiB0ZWxsIHRoZSBhdXRob3IgZG9lc24ndCBhY3R1YWxseSBjYXJlIGFib3V0IHRoZSBhbnN3ZXIgdG8gdGhlIHVuZGVybHlpbmcgcXVlc3Rpb24sIHRoZXkncmUgZGVhZCB0byBtZS4gCgpBcyBhIHByb2R1Y2VyIG9mIGFuYWx5c2lzLCB0aGUgc3RydWdnbGUgaXMgaG93IHRvIHRoaW5rIGFib3V0IGFuZCBkbyBzY2llbmNlIGFsb25nc2lkZSBhY3RvcnMgd2hvIGdlbmVyYXRlIGNvbnRyb3ZlcnN5IG91dCBvZiBzZWxmLWludGVyZXN0IHVzaW5nIGEgbG90IG9mIHRoZSBzYW1lIGxhbmd1YWdlIGFzIHNjaWVuY2UuIFRoZSBvbmx5IHJlYWwgc29sdXRpb24gaXMgdG8gbGVhcm4gaG93IHRvIHRlbGwgZ29vZCB3b3JrIGZyb20gYmFkIHdvcmsgbm8gbWF0dGVyIHRoZSB3cmFwcGluZy4gCgojIExlc3NvbiAyOiBQb3NlIGEgUXVlc3Rpb24gYW5kIFByb3Bvc2UgYSBSZXNlYXJjaCBEZXNpZ24gdGhhdCBDYW4gQW5zd2VyIEl0CgpJbnN0ZWFkIG9mIGFuIGFzc2VydGlvbiwgd2Ugc2hvdWxkIHByZXNlbnQgRXBzdGVpbidzIGlkZWEgYXMgYSBjb25jcmV0ZSByZXNlYXJjaCBxdWVzdGlvbjogV2hhdCB3aWxsIHRoZSBudW1iZXIgb2YgZGVhdGhzIGZyb20gQ09WSUQtMTkgaW4gdGhlIFVuaXRlZCBTdGF0ZXMgYmUgYnkgc2F5IFNlcHRlbWJlciAxPyBUbyBiZSBjb25jcmV0ZSwgaGVyZSBhcmUgb3VyIG91dGNvbWVzLCBjb25maXJtZWQgQ09WSUQtMTkgY2FzZXMgKHJlZCkgYW5kIGRlYXRocyAoYmxhY2spIGNvbXBpbGVkIGJ5IFtKb2hucyBIb3BraW5zIENTU0VdKGh0dHBzOi8vZ2l0aHViLmNvbS9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOSkuCgpgYGB7ciwgZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0gRiwgd2FybmluZz1GQUxTRX0KCmxpYnJhcnkoZ2dwbG90MikKcDEgPC0gY291bnRyaWVzX2xvbmcgJT4lIGZpbHRlcihjb3VudHJ5ICVpbiUgIlVTIikgJT4lIAogICAgICBmaWx0ZXIoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPjApICAlPiUgZ2dwbG90KCkgKyBnZW9tX3BvaW50KGFlcyh4PWRhdGVfYXNkYXRlLCB5PWNvbmZpcm1lZCksIGNvbG9yPSJyZWQiKSAgKyB4bGFiKCJEYXRlIikgKyB0aGVtZV9idygpICsgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hX2Zvcm1hdCgpKSArCiAgICAgIHNjYWxlX3hfZGF0ZShsYWJlbHMgPSBkYXRlX2Zvcm1hdCgiJW0tJWQiKSwgYnJlYWtzPSdtb250aHMnKQoKcDIgPC0gY291bnRyaWVzX2xvbmcgJT4lIGZpbHRlcihjb3VudHJ5ICVpbiUgIlVTIikgJT4lCiAgICAgIGZpbHRlcihkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQ+MCkgICU+JSBnZ3Bsb3QoKSArIGdlb21fcG9pbnQoYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzKSkgKyB4bGFiKCJEYXRlIikgKyB0aGVtZV9idygpICsgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9ICBjb21tYV9mb3JtYXQoKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9eW1kKCIyMDIwLTA5LTAxIikgLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2w9ImJsYWNrIikgKwogICAgICBhbm5vdGF0ZSgidGV4dCIsIHggPSB5bWQoIjIwMjAtMDktMDEiKS00LCB5ID0gNzAwLCBsYWJlbCA9ICJWYWx1ZSBhdCB0aGlzIGRhdGUgaXMgd2hhdCB3ZSB3YW50IHRvIGtub3ciLCBjb2xvcj0iYmxhY2siLCBzaXplPTIuNSwgYW5nbGU9OTApICsKICAgICAgc2NhbGVfeF9kYXRlKGxhYmVscyA9IGRhdGVfZm9ybWF0KCIlbS0lZCIpLCBicmVha3M9J21vbnRocycpCgpwX2NvbWJpbmVkIDwtIGNvdW50cmllc19sb25nICU+JSBmaWx0ZXIoY291bnRyeSAlaW4lICJVUyIpICU+JQogICAgICBmaWx0ZXIoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPjApICAlPiUgCiAgICAgIGdncGxvdCgpICsgCiAgICAgIGdlb21fcG9pbnQoYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9Y29uZmlybWVkKSwgY29sb3I9InJlZCIpICsgCiAgICAgIGdlb21fcG9pbnQoYWVzKHg9ZGF0ZV9hc2RhdGUsIHk9ZGVhdGhzKSwgY29sb3I9ImJsYWNrIikgKwogICAgICB4bGFiKCJEYXRlIikgKyB0aGVtZV9idygpICsgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9ICBjb21tYV9mb3JtYXQoKSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9eW1kKCIyMDIwLTA5LTAxIikgLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2w9ImJsYWNrIikgKwogICAgICBhbm5vdGF0ZSgidGV4dCIsIHggPSB5bWQoIjIwMjAtMDktMDEiKS00LCB5ID0gMTUwMDAwLCBsYWJlbCA9ICJWYWx1ZSBhdCB0aGlzIGRhdGUgaXMgd2hhdCB3ZSB3YW50IHRvIGtub3ciLCBjb2xvcj0iYmxhY2siLCBzaXplPTUsIGFuZ2xlPTkwKSArCiAgICAgIHNjYWxlX3hfZGF0ZShsYWJlbHMgPSBkYXRlX2Zvcm1hdCgiJW0tJWQiKSwgYnJlYWtzPSdtb250aHMnKSArIHlsYWIoIkNvdW50IikKCgpgYGAKCmBgYHtyLCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSBULCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuYWxpZ249ImNlbnRlciJ9CmxpYnJhcnkocGF0Y2h3b3JrKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCJwYXRjaHdvcmsiKQpwYXRjaHdvcmsgPC0gcF9jb21iaW5lZCAjKHAxICsgcDIpIApwYXRjaHdvcmsgKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAnVW5pdGVkIFN0YXRlcyBDb3ZpZC0xOSBDYXNlcyAocmVkKSBhbmQgRGVhdGhzIChibGFjayknIywKICAjc3VidGl0bGUgPSAnVGhlc2UgMyBwbG90cyB3aWxsIHJldmVhbCB5ZXQtdW50b2xkIHNlY3JldHMgYWJvdXQgb3VyIGJlbG92ZWQgZGF0YS1zZXQnLAogICNjYXB0aW9uID0gJycKKQpgYGAKVG8gbWFrZSB0aGlzIGVhc2llciB0byBjb21wYXJlIGFjcm9zcyB0aW1lIGFuZCBhY3Jvc3MgY291bnRyaWVzLCBsZXQncyBsb2cgdHJhbnNmb3JtIHRoZSBvdXRjb21lIGFuZCBjaGFuZ2UgZGF0ZSB0byBudW1iZXIgb2YgZGF5cyBzaW5jZSB0aGUgMTAwdGggcmVwb3J0ZWQgY2FzZS4gVGhpcyBwdXRzIG91ciBmb3JjYXN0aW5nIGhvcml6b24gYXQgYWJvdXQgMTgwIGRheXMgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIFUuUy4gZXBpc29kZS4KCmBgYHtyLCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSBGLCB3YXJuaW5nPUZBTFNFfQoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNvd3Bsb3QpCnAxIDwtIGNvdW50cmllc19sb25nICU+JSBmaWx0ZXIoY291bnRyeSAlaW4lICJVUyIpICU+JSBmaWx0ZXIoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPjApICU+JSBnZ3Bsb3QoKSArIGdlb21fcG9pbnQoYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWNvbmZpcm1lZCksIGNvbG9yPSJyZWQiKSAgKyB4bGFiKCJEYXlzIFNpbmNlIDEwMCBDb25maXJtZWQiKSArIHRoZW1lX2J3KCkgKyBzY2FsZV95X2xvZzEwKGxhYmVscyA9IGNvbW1hKQpwMiA8LSBjb3VudHJpZXNfbG9uZyAlPiUgZmlsdGVyKGNvdW50cnkgJWluJSAiVVMiKSAlPiUgZmlsdGVyKGRheXNfc2luY2VfMTAwX2NvbmZpcm1lZD4wKSAlPiUgIGdncGxvdCgpICsgZ2VvbV9wb2ludChhZXMoeD1kYXlzX3NpbmNlXzEwMF9jb25maXJtZWQsIHk9ZGVhdGhzKSkgKyB4bGFiKCJEYXlzIFNpbmNlIDEwMCBDb25maXJtZWQiKSArIHRoZW1lX2J3KCkgICsgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBjb21tYSkgKwogICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTgwICwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sPSJibGFjayIpICsKICAgICAgYW5ub3RhdGUoInRleHQiLCB4ID0gMTgwLTUsIHkgPSAyMDAsIGxhYmVsID0gIlZhbHVlIGF0IHRoaXMgZGF0ZSBpcyB3aGF0IHdlIHdhbnQgdG8ga25vdyIsIGNvbG9yPSJibGFjayIsIHNpemU9Mi41LCBhbmdsZT05MCkKCgpwX2NvbWJpbmVkIDwtIGNvdW50cmllc19sb25nICU+JSBmaWx0ZXIoY291bnRyeSAlaW4lICJVUyIpICU+JQogICAgICAgICAgICAgIGZpbHRlcihkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQ+MCkgICU+JSAKICAgICAgICAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgICAgICAgIGdlb21fcG9pbnQoYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWNvbmZpcm1lZCksIGNvbG9yPSJyZWQiKSArIAogICAgICAgICAgICAgIGdlb21fcG9pbnQoYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWRlYXRocyksIGNvbG9yPSJibGFjayIpICsKICAgICAgICAgICAgICB4bGFiKCJEYXlzIFNpbmNlIDEwMCBDb25maXJtZWQiKSArCiAgICAgICAgICAgICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE4MCAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbD0iYmxhY2siKSArCiAgICAgICAgICAgICAgYW5ub3RhdGUoInRleHQiLCB4ID0gMTgwLTUsIHkgPSAxMDAwLCBsYWJlbCA9ICJWYWx1ZSBhdCB0aGlzIGRhdGUgaXMgd2hhdCB3ZSB3YW50IHRvIGtub3ciLCBjb2xvcj0iYmxhY2siLCBzaXplPTUsIGFuZ2xlPTkwKSArCiAgICAgICAgICAgICAgI3NjYWxlX3hfZGF0ZShsYWJlbHMgPSBkYXRlX2Zvcm1hdCgiJW0tJWQiKSwgYnJlYWtzPSdtb250aHMnKSArIAogICAgICAgICAgICAgIHlsYWIoIkNvdW50IikgKyAKICAgICAgICAgICAgICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IGNvbW1hX2Zvcm1hdCgpKSArIHRoZW1lX2J3KCkKCgoKYGBgCgpgYGB7ciwgZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0gVCwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgZmlnLmFsaWduPSJjZW50ZXIifQpsaWJyYXJ5KHBhdGNod29yaykgOyAjaW5zdGFsbC5wYWNrYWdlcygicGF0Y2h3b3JrIikKcGF0Y2h3b3JrIDwtIHBfY29tYmluZWQgIyAocDEgKyBwMikgCnBhdGNod29yayArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdVbml0ZWQgU3RhdGVzIENvdmlkLTE5IENhc2VzIGFuZCBEZWF0aHMnLAogIHN1YnRpdGxlID0gJ0xvZyBzY2FsZSwgYW5kIGRheXMgc2luY2UgMTAwIGNvbmZpcm1lZCBjYXNlcycjLAogICNjYXB0aW9uID0gJycKKQoKYGBgClR3byBpbW1lZGlhdGUgdGhpbmdzIHRvIHRha2UgYXdheSBhcmUgZmlyc3QsIHdlIGFyZSBpbnRlcmVzdGVkIHNwZWNpZmljYWxseSBpbiBkZWF0aHMgYW5kIGFyZSBmb3JjZWQgdG8gdW5kZXJzdGFuZCBzcHJlYWQgb2YgYWxsIGNhc2VzIGluY2lkZW50YWxseSBhcyBhIG1lYW5zIHRvIHVuZGVyc3RhbmQgZGVhdGhzLiBUaGUgc2Vjb25kIGlzIHRoYXQgb3VyIGZvcmVjYXN0aW5nIGhvcml6b24gaXMgKipmYXIqKi4gQSBsb3QgY2FuIGhhcHBlbiBiZXR3ZWVuIG5vdyBhbmQgdGhlbiwgYW5kIGV4cGVydHMgaGF2ZSBbd2lsZGx5IHZhcnlpbmcgZXhwZWN0YXRpb25zXShodHRwczovL2ZpdmV0aGlydHllaWdodC5jb20vZmVhdHVyZXMvZXhwZXJ0cy1zYXktdGhlLWNvcm9uYXZpcnVzLW91dGxvb2staGFzLXdvcnNlbmVkLWJ1dC10aGUtdHJhamVjdG9yeS1pcy1zdGlsbC11bmNsZWFyLykgYWJvdXQgd2hhdCB3aWxsIGFjdHVhbGx5IGhhcHBlbiBpbiB0aGlzIHdpbmRvdy4gRXZlbiB0aG91Z2ggdGhlcmUgaXMgYSBncmVhdCBkZWFsIG9mIGV4cGVydCBjZXJ0YWludHkgYWJvdXQgdGhlIHVuZGVybHlpbmcgbWVjaGFuaWNzLCB3aGF0IHdpbGwgaGFwcGVuIG9yIG1vcmUgcHJlY2lzZWx5IHdoYXQgd2Ugd2lsbCBjaG9vc2UgdG8gbGV0IGhhcHBlbiwgYXJlIHVua25vd25zLgoKIyBMZXNzb24gMzogVXNlIEZhaWx1cmVzIG9mIFlvdXIgUHJlZGljdGlvbnMgdG8gUmV2aXNlIHlvdXIgTW9kZWwKCkluIHRoZSBmaXJzdCBkcmFmdCBvZiB0aGUgcGllY2UgZGF0ZWQgYW5kIHBvc3RlZCBNYXJjaCAxNiwgMjAyMCBFcHN0ZWluIChbMjAyMGFdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDIwMDMxOTE2NTUyMi9odHRwczovL3d3dy5ob292ZXIub3JnL3Jlc2VhcmNoL2Nvcm9uYXZpcnVzLWlzbnQtcGFuZGVtaWMpKSBwcmVkaWN0cyB0aGUgZm9sbG93aW5nIGFib3V0IGZ1dHVyZSBjb3VudHMgb2YgZGVhdGhzOgoKPiBGcm9tIHRoaXMgYXZhaWxhYmxlIGRhdGEsIGl0IHNlZW1zIG1vcmUgcHJvYmFibGUgdGhhbiBub3QgdGhhdCB0aGUgdG90YWwgbnVtYmVyIG9mIGNhc2VzIHdvcmxkLXdpZGUgd2lsbCBwZWFrIG91dCBhdCB3ZWxsIHVuZGVyIDEgbWlsbGlvbiwgd2l0aCB0aGUgdG90YWwgbnVtYmVyIG9mIGRlYXRocyBhdCB1bmRlciA1MCwwMDAgKHVwIGFib3V0IGVpZ2h0Zm9sZCkuIEluIHRoZSBVbml0ZWQgU3RhdGVzLCBpZiB0aGUgdG90YWwgZGVhdGggdG9sbCBpbmNyZWFzZXMgYXQgYWJvdXQgdGhlIHNhbWUgcmF0ZSwgdGhlIGN1cnJlbnQgNjcgZGVhdGhzIHNob3VsZCB0cmFuc2xhdGUgaW50byBhYm91dCA1MDAgZGVhdGhzIGF0IHRoZSBlbmQuIE9mIGNvdXJzZSwgZXZlcnkgbGlmZSBsb3N0IGlzIGEgdHJhZ2VkeeKAlGFuZCB0aGUgcG90ZW50aWFsIGxvc3Mgb2YgNTAsMDAwIGxpdmVzIHdvcmxkLXdpZGUgd291bGQgYmUgYXBwYWxsaW5n4oCUYnV0IHRob3NlIGRlYXRocyBzdGVtbWluZyBmcm9tIHRoZSBjb3JvbmF2aXJ1cyBhcmUgbm90IG1vcmUgdHJhZ2ljIHRoYW4gb3RoZXJzLCBzbyB0aGF0IHRoZSBzYW1lIHNvY2lhbCBjYWxjdWx1cyBhcHBsaWVzIGhlcmUgdGhhdCBzaG91bGQgYXBwbHkgaW4gb3RoZXIgY2FzZXMuIAoKVGhpcyBpcyBncmVhdC4gSXQgbWFrZXMgYSBzaGFycCB0ZXN0YWJsZSBwcmVkaWN0aW9uIHRoYXQgd2UgY2FuIHVzZSB0byB2YWxpZGF0ZSBpbiBhIHRpbWVseSBtYW5uZXIgYSByYWRpY2FsIGFsdGVybmF0ZSBtb2RlbCBvZiBkaXNlYXNlIHNwcmVhZC5eW0NhbiB5b3UgaW1hZ2luZSBpZiB0aGlzIHR1cm5lZCBvdXQgdG8gYmUgcmlnaHQ/IFNvbWVvbmUgaGFzIHRvIGJlIGhvbGRpbmcgdGhlIHdpbm5pbmcgbG90dG8gbnVtYmVyLCBhbmQgcGlja2luZyBsb25nIG9kZHMgb3V0Y29tZXMgY2FuIGJlIGhpZ2ggcmlzayBoaWdoIHJld2FyZC5dCgpXaGVuIHRoZSBmYXRhbGl0eSBudW1iZXIgcGFzc2VkIDUwMCwgRXBzdGVpbiBbZWRpdGVkXShodHRwczovL3dlYmNhY2hlLmdvb2dsZXVzZXJjb250ZW50LmNvbS9zZWFyY2g/cT1jYWNoZTotcVE3Vk1wcUZSVUo6aHR0cHM6Ly93d3cuaG9vdmVyLm9yZy9yZXNlYXJjaC9jb3JvbmF2aXJ1cy1pc250LXBhbmRlbWljKyZjZD0xJmhsPWVuJmN0PWNsbmsmZ2w9dXMpIHRoZSBvbmxpbmUgY29weSBvZiB0aGUgb3JpZ2luYWwgTWFyY2ggMTZ0aCBwaWVjZSB0byByZWFkIDUsMDAwIGluc3RlYWQgYW5kIGFkZGVkIGEgZm9vdG5vdGUKCj4gRnJvbSB0aGlzIGF2YWlsYWJsZSBkYXRhLCBpdCBzZWVtcyBtb3JlIHByb2JhYmxlIHRoYW4gbm90IHRoYXQgdGhlIHRvdGFsIG51bWJlciBvZiBjYXNlcyB3b3JsZC13aWRlIHdpbGwgcGVhayBvdXQgYXQgd2VsbCB1bmRlciAxIG1pbGxpb24sIHdpdGggdGhlIHRvdGFsIG51bWJlciBvZiBkZWF0aHMgYXQgdW5kZXIgNTAsMDAwICh1cCBhYm91dCBlaWdodGZvbGQpLiBJbiB0aGUgVW5pdGVkIFN0YXRlcywgaWYgdGhlIHRvdGFsIGRlYXRoIHRvbGwgaW5jcmVhc2VzIGF0IGFib3V0IHRoZSBzYW1lIHJhdGUsIHRoZSBjdXJyZW50IDY3IGRlYXRocyBzaG91bGQgcmVhY2ggYWJvdXQgNTAwMCAob3IgdHduIHBlcmNlbnQgb2YgbXkgZXN0aW1hdGVkIHdvcmxkIHRvdGFsLCB3aGljaCBtYXkgYWxzbyB0dXJuIG91dCB0byBiZSBsb3cpLiBbU2VlIGNvcnJlY3Rpb24gJiBhZGRlbmR1bSBhdCB0aGUgZW5kIG9mIHRoaXMgZXNzYXkuXV5bVHlwb3MgYXJlIHZlcmJhdGltLl0KCj4gQ29ycmVjdGlvbiAmIEFkZGVuZHVtLCBhZGRlZCBNYXJjaCAyNCwgMjAyMDogVGhhdCBlc3RpbWF0ZSBpcyB0ZW4gdGltZXMgZ3JlYXRlciB0aGFuIHRoZSA1MDAgbnVtYmVyIEkgZXJyb25lb3VzbHkgcHV0IGluIHRoZSBpbml0aWFsIGRyYWZ0IG9mIHRoZSBlc3NheSwgYW5kIGl0LCB0b28sIGNvdWxkIHByb3ZlIHNvbWV3aGF0IG9wdGltaXN0aWMuIEJ1dCBhbnkgcG9zc2libGUgZXJyb3IgcmF0ZSBpbiB0aGlzIHJldmlzZWQgcHJvamVjdGlvbiBzaG91bGQgYmUga2VwdCBpbiBwZXJzcGVjdGl2ZS4gVGhlIGN1cnJlbnQgVS5TLiBkZWF0aCB0b2xsIHN0YW5kcyBhdCA1OTIgYXMgb2Ygbm9vbiBvbiBNYXJjaCAyNCwgMjAyMCwgb3V0IG9mIGFib3V0IDQ3LDAwMCBjYXNlcy4gU28gbXkgYWRqdXN0ZWQgZmlndXJlLCBob3dldmVyIHR3ZWFrZWQsIHJlbWFpbnMgYm90aCBmYXIgbG93ZXIsIGFuZCBJIGJlbGlldmUgZmFyIG1vcmUgYWNjdXJhdGUsIHRoYW4gdGhlIGNvbW1vbiBjbGFpbSB0aGF0IHRoZXJlIGNvdWxkIGJlIGEgbWlsbGlvbiBkZWFkIGluIHRoZSBVLlMuIGZyb20gd2VsbCBvdmVyIDE1MCBtaWxsaW9uIGNvcm9uYXZpcnVzIGNhc2VzIGJlZm9yZSB0aGUgZXBpZGVtaWMgcnVucyBpdHMgY291cnNlLgoKQW5kIHRoZW4gcHVibGlzaGVkIGEgW2ZvbGxvdyB1cCBub3RlXShodHRwczovL3JlYXNvbi5jb20vMjAyMC8wMy8yNC9yaWNoYXJkLWVwc3RlaW4tY29wcy10by1hLXN0dXBpZC1nYWZmZS1pbi1jb250cm92ZXJzaWFsLWNvcm9uYXZpcnVzLWVzc2F5LXRoYXQtY2F1Z2h0LXRydW1wLWFkbWluLWF0dGVudGlvbi8pIHNheWluZyBoZSByZWFsbHkgbWVhbnQgdG8gdHlwZSAyLDUwMCB0aGUgZmlyc3QgdGltZS4KCiA+IEluIG15IGNvbHVtbiBsYXN0IHdlZWssIEkgcHJlZGljdGVkIHRoYXQgdGhlIHdvcmxkIHdvdWxkIGV2ZW50dWFsbHkgc2VlIGFib3V0IDUwLDAwMCBkZWF0aHMgZnJvbSB0aGUgbm92ZWwgY29yb25hdmlydXMsIGFuZCB0aGUgVW5pdGVkIFN0YXRlcyBhYm91dCA1MDAuIFRoZXNlIHR3byBudW1iZXJzIGFyZSBjbGVhcmx5IG5vdCBpbiBzeW5jLiBJZiB0aGUgZmlyc3QgbnVtYmVyIGhvbGRzLCB0aGUgdG90YWwgVVMgZGVhdGhzIHNob3VsZCBiZSBhYm91dCA0IHRvIDUgcGVyY2VudCBvZiB0aGF0IHRvdGFsLCBvciBhYm91dCAyLDAwMOKAkzIsNTAwIGRlYXRocy4gVGhlIGN1cnJlbnQgbnVtYmVycyBhcmUgZ2V0dGluZyBsYXJnZXIsIHNvIGl0IGlzIHBvc3NpYmxlIGJvdGggZmlndXJlcyB3aWxsIG1vdmUgdXAgaW4gYSByb3VnaCBwcm9wb3J0aW9uIGZyb20gZXZlbiB0aGF0IHJldmlzZWQgZXN0aW1hdGUuIAoKVGhpcyBpcyBub3QgZ3JlYXQuICBUaGlzIGFsdGVycyB0aGUgcHJlZGljdGlvbiBidXQgZG9lcyBub3QgYm90aGVyIHRvIGFsdGVyIHRoZSBsb2dpYyB3aGljaCBsZWQgdG8gdGhlIGNhbGN1bGF0aW9uLiBNdWx0aXBseWluZyB0aGUgdGhlbiBnbG9iYWwgZGVhdGggY291bnQgYnkgOCB3b3VsZCBsZWFkIHRvIGEgZ2xvYmFsIHByZWRpY3Rpb24gb2YgNTAsMDAwIGFuZCBzbyBtdWx0aXBseWluZyB0aGUgdGhlbiBVLlMuIGRlYXRoIGNvdW50IG9mIDY3IGJ5IDggd291bGQgYmUgNTM2LCBoZW5jZSB0aGUgZm9yZWNhc3Qgb2YgNTAwLiBMaWtld2lzZSB0aGUgNTAsMDAwIGdsb2JhbCB0b3RhbCBpcyBsZWZ0IHVuY2hhbmdlZC4gU2ltcGx5IGFkZGluZyB6ZXJvcyB0byB0aGUgcHJlZGljdGlvbiBldmVyeSB0aW1lIGl0IGlzIHByb3ZlbiB3cm9uZyBkb2Vzbid0IGFsdGVyIHRoZSB1bmRlcmx5aW5nIG1vZGVsIGdpdmVuIGluIHRoZSBzYW1lIHNlbnRlbmNlLiAKCkRvbid0IGRvIHRoaXMuIFdoZW4geW91IGZlZWwgY29tZm9ydGFibGUgZW5vdWdoIHRvIHNoYXJlIHlvdXIgcHJlZGljdGlvbnMgcHVibGljbHksIGNyZWF0ZSBhIGNvbmNyZXRlIHJlY29yZCBhbmQgc3RpY2sgYnkgaXQuIFlvdSBjYW4gYWx3YXlzIG1ha2UgbmV3IHByZWRpY3Rpb25zIGJhc2VkIG9uIG5ldyBtb2RlbHMsIGJ1dCBkb24ndCBnbyBiYWNrIGFuZCBtYXNzYWdlIHBhc3QgcHJlZGljdGlvbnMgYWZ0ZXIgdGhlIGZhY3QuIFRoZSB0ZW1wdGF0aW9uIHRvIHRyeSB0byBnYXNsaWdodCBvdGhlcnMgKGFuZCB5b3Vyc2VsZikgdGhhdCB5b3Ugd2VyZSByZWFsbHkgcmlnaHQgdGhlIGVudGlyZSB0aW1lIGlzIHRvbyBncmVhdC5eW0FuZCBoaWxhcmlvdXMuXQoKV2UgY2FuIHZpc3VhbGx5IGV4YW1pbmUgdGhpcyBwcmVkaWN0aW9uIGluIGxpZ2h0IG9mIHRoZSBkYXRhIHVwIHRvIG5vdywgYWRkaW5nIGdsb2JhbCBjb3VudHMgb2YgY2FzZXMgYW5kIGRlYXRocywgYW5kIG1hcmtpbmcgdGhlIHByZWRpY3RlZCBtYXhpbXVtcyBpbiB0aGUgTWFyY2ggMTZ0aCBkcmFmdCBhbmQgdGhlbiB0aGUgcmV2aXNlZCBNYXJjaCAyNHRoIGRyYWZ0LgoKYGBge3IsIGVjaG89RiwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9IEYsIHdhcm5pbmc9RkFMU0V9CgoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNvd3Bsb3QpCnAxIDwtIGNvdW50cmllc19sb25nICU+JSBmaWx0ZXIoY291bnRyeSAlaW4lICJVUyIpICU+JSBmaWx0ZXIoZGF5c19zaW5jZV8xMDBfY29uZmlybWVkPjApICAlPiUgZ2dwbG90KCkgKwogICAgICAgICAgZ2VvbV9wb2ludChhZXMoeD1kYXlzX3NpbmNlXzEwMF9jb25maXJtZWQsIHk9Y29uZmlybWVkKSwgY29sb3I9InJlZCIpICsgCiAgICAgICAgICBnZW9tX3BvaW50KGFlcyh4PWRheXNfc2luY2VfMTAwX2NvbmZpcm1lZCwgeT1kZWF0aHMpLCBjb2xvcj0iYmxhY2siKSArIAogICAgICAgICAgeGxhYigiRGF5cyBTaW5jZSAxMDAgQ29uZmlybWVkIikgKyAKICAgICAgICAgIHRoZW1lX2J3KCkgICsgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBjb21tYSkgICsgeGxpbSgwLDEwMCkgKwogICAgICAgICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNTAwLCBzdGF0ID0gJ2hsaW5lJywgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sPSJibGFjayIpICsKICAgICAgICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUwMDAsIHN0YXQgPSAnaGxpbmUnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2w9ImJsYWNrIikgKwogICAgICAgICAgZ2d0aXRsZSgiVW5pdGVkIFN0YXRlcyIpICsgCiAgICAgICAgICBhbm5vdGF0ZSgidGV4dCIsIHggPSA4MCwgeSA9IDcwMCwgbGFiZWwgPSAiUHJlZGljdGlvbiBtYWRlIG9uIE1hcmNoIDE2IiwgY29sb3I9ImJsYWNrIiwgc2l6ZT0yLjUpICArIAogICAgICAgICAgYW5ub3RhdGUoInRleHQiLCB4ID0gODAsIHkgPSA3MDAwLCBsYWJlbCA9ICJQcmVkaWN0aW9uIG1hZGUgb24gTWFyY2ggMjQiLCBjb2xvcj0iYmxhY2siLCBzaXplPTIuNSkgKyB5bGFiKCIiKQoKcDIgPC0gd29ybGRfbG9uZyAlPiUgZmlsdGVyKGRheXNfc2luY2VfMTAwX2NvbmZpcm1lZD4wKSAlPiUgZ2dwbG90KCkgKwogICAgICAgICAgZ2VvbV9wb2ludChhZXMoeD1kYXlzX3NpbmNlXzEwMF9jb25maXJtZWQsIHk9Y29uZmlybWVkKSwgY29sb3I9InJlZCIpICsgCiAgICAgICAgICBnZW9tX3BvaW50KGFlcyh4PWRheXNfc2luY2VfMTAwX2NvbmZpcm1lZCwgeT1kZWF0aHMpLCBjb2xvcj0iYmxhY2siKSArIAogICAgICAgICAgeGxhYigiRGF5cyBTaW5jZSAxMDAgQ29uZmlybWVkIikgKyB0aGVtZV9idygpICsgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBjb21tYSkgKyB4bGltKDAsMTAwKSArCiAgICAgICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1MDAwMCwgc3RhdCA9ICdobGluZScsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbD0iYmxhY2siKSArCiAgICAgICAgICBnZ3RpdGxlKCJXb3JsZCIpICsgCiAgICAgICAgICBhbm5vdGF0ZSgidGV4dCIsIHggPSA4MCwgeSA9IDY1MDAwLCBsYWJlbCA9ICJQcmVkaWN0aW9uIG1hZGUgb24gTWFyY2ggMTYgYW5kIE1hcmNoIDI0IiwgY29sb3I9ImJsYWNrIiwgc2l6ZT0yLjUpICArIHlsYWIoIiIpCgoKYGBgCgpgYGB7ciwgZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0gVCwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KCmxpYnJhcnkocGF0Y2h3b3JrKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCJwYXRjaHdvcmsiKQpwYXRjaHdvcmsgPC0gKHAxICkgCnBhdGNod29yayArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdVbml0ZWQgU3RhdGVzIENvdmlkLTE5IENhc2VzIChyZWQpIGFuZCBEZWF0aHMgKGJsYWNrKScsCiAgc3VidGl0bGUgPSAiRXBzdGVpbidzIFByZWRpY3RlZCBNYXhpbXVtIFRvdGFsIERlYXRocyAoTWFyY2ggMTYgYW5kIHRoZW4gdXBkYXRlZCBvbiBNYXJjaCAyNCkiLAogICNjYXB0aW9uID0gJycKKQoKYGBgClRoZXNlIGZvcmVjYXN0cyBpbiBsaWdodCBvZiB0aGUgYWN0dWFsIGRhdGEgdHJhamVjdG9yeSBzaG91bGQgaW1tZWRpYXRlbHkgZ2l2ZSB5b3UgcGF1c2UuIEZvciB0aGUgVW5pdGVkIFN0YXRlcywgaXQgd291bGQgcmVxdWlyZSBhIHZlcnkgc29vbiBkZXBhcnR1cmUgZnJvbSB0aGUgY3VycmVudCBleHBvbmVudGlhbCB0cmVuZCB3aGljaCB3YXNuJ3QgdmlzaWJsZSB5ZXQgaW4gZWl0aGVyIHRoZSBjb25maXJtZWQgb3IgZGVhdGggdHJlbmRzLiBUaGUgVS5TLiB0cmVuZCBpbiBkZWF0aHMgd2FzIGFjdHVhbGx5IGFjY2VsZXJhdGluZyBzbGlnaHRseSBoZXJlLgoKYGBge3IsIGVjaG89RiwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9IFQsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9CgpsaWJyYXJ5KHBhdGNod29yaykgOyAjaW5zdGFsbC5wYWNrYWdlcygicGF0Y2h3b3JrIikKcGF0Y2h3b3JrIDwtIChwMiApIApwYXRjaHdvcmsgKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAnR2xvYmFsIENvdmlkLTE5IENhc2VzIChyZWQpIGFuZCBEZWF0aHMgKGJsYWNrKScsCiAgc3VidGl0bGUgPSAiRXBzdGVpbidzIFByZWRpY3RlZCBNYXhpbXVtIFRvdGFsIERlYXRocyAoTWFyY2ggMTYpIiwKICAjY2FwdGlvbiA9ICcnCikKCmBgYApGb3IgdGhlIHdvcmxkLCBncm93dGggc3RhcnRzIG9mZiBleHBvbmVudGlhbCwgbGV2ZWxzIG9mZiwgYW5kIHRoZW4gZ29lcyBleHBvbmVudGlhbCBhZ2FpbiBhcyBpdCByZWFjaGVzIGEgbmV3IHBhcnQgb2YgdGhlIHdvcmxkLiBGb3IgRXBzdGVpbidzIDUwayBlc3RpbWF0ZSB0byBiZSB0cnVlLCB0aGUgdHJlbmQgaW4gRXVyb3BlIGFuZCB0aGUgVS5TLiB3b3VsZCBoYXZlIHRvIHN0YXJ0IGxldmVsaW5nIG9mZiBub3csIGFuZCB0aGVyZSB3b3VsZCBoYXZlIHRvIG5vdCBiZSBhbiBleHBvbmVudGlhbCBncm93dGggd2hlbiB0aGUgZGlzZWFzZSBmdWxseSBoaXRzIExhdGluIEFtZXJpY2EsIEFmcmljYSwgYW5kIFNvdXRoIEVhc3QgQXNpYS4gQXMgb2YgdGhpcyB3cml0aW5nIHRoZSB3b3JsZCBpcyBhbHJlYWR5IHRocmVlIHF1YXJ0ZXJzIHRvIHRoYXQgcHJlZGljdGlvbiBvZiBhIG1pbGxpb24gY29uZmlybWVkIGNhc2VzLiBJdCdzIG5vdCB0aGF0IHRoZXNlIG91dGNvbWVzIGFyZW4ndCBwb3NzaWJsZSwgaXQncyB0aGF0IGl0J3MgdW5jbGVhciB3aGF0IGluIHRoZSB0aW1lIHRyZW5kIHVwIHVudGlsIG5vdyBvciBpbiB0aGUgdGhlb3J5IHN1Z2dlc3RzIHRoYXQncyB3aGF0IGlzIGFib3V0IHRvIGhhcHBlbi4KCmBgYHtyLCBldmFsPUYsZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpsaWJyYXJ5KGdyb3d0aHJhdGVzKQpncm93X2xvZ2lzdGljX3lzaGlmdCA8LSBmdW5jdGlvbih0aW1lLCBwYXJtcykgewogIHdpdGgoYXMubGlzdChwYXJtcyksIHsKICAgIHkgPC0gKEsgKiB5MCkgLyAoeTAgKyAoSyAtIHkwKSAqIGV4cCgtbXVtYXggKiB0aW1lKSkgKyB5X3NoaWZ0CiAgICBhcy5tYXRyaXgoZGF0YS5mcmFtZSh0aW1lID0gdGltZSwgeSA9IHkpKQogIH0pCn0KCiNodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ3Jvd3RocmF0ZXMvdmlnbmV0dGVzL1VzZXJfbW9kZWxzLmh0bWwKI3RpbWUgPC0gMToxMAojb3V0IDwtIGdyb3dfbG9naXN0aWNfeXNoaWZ0KHRpbWUsIHBhcm1zID0gbGlzdCh5MCA9IDEsIG11bWF4ID0gMC41LCBLID0gMTAsIHlfc2hpZnQgPSAyKSkKI3Bsb3QodGltZSwgb3V0WywgInkiXSwgdHlwZSA9ICJiIikKCmdyb3dfbG9naXN0aWNfeXNoaWZ0IDwtIGdyb3d0aG1vZGVsKGdyb3dfbG9naXN0aWNfeXNoaWZ0LCBjKCJ5MCIsICJtdW1heCIsICJLIiwgInlfc2hpZnQiKSkKZml0IDwtIGZpdF9ncm93dGhtb2RlbChncm93X2xvZ2lzdGljX3lzaGlmdCwKICAgICAgICAgICAgICAgICAgICAgICBwID0gYyh5MCA9IDEsIG11bWF4ID0gMC4xLCAgSz01MDAwLCB5X3NoaWZ0ID0gMSksCiAgICAgICAgICAgICAgICAgICAgICAgdGltZSA9IHVzX2xvbmcgJT4lIGZpbHRlcihkYXlzX3NpbmNlXzFfY29uZmlybWVkPjEgJiAhaXMubmEoZGVhdGhzKSkgJT4lIHB1bGwoZGF5c19zaW5jZV8xX2NvbmZpcm1lZCksCiAgICAgICAgICAgICAgICAgICAgICAgeSA9IHVzX2xvbmcgJT4lIGZpbHRlcihkYXlzX3NpbmNlXzFfY29uZmlybWVkPjEgJiAhaXMubmEoZGVhdGhzKSkgJT4lIHB1bGwoZGVhdGhzKSApCnBsb3QoZml0KQp1c19sb25nJHlfaGF0X2RlYXRocyA8LSBwcmVkaWN0KGZpdCx0aW1lPXVzX2xvbmckZGF5c19zaW5jZV8xX2NvbmZpcm1lZClbLCd5J10KCmZpdCA8LSBmaXRfZ3Jvd3RobW9kZWwoZ3Jvd19sb2dpc3RpY195c2hpZnQsCiAgICAgICAgICAgICAgICAgICAgICAgcCA9IGMoeTAgPSAxLCBtdW1heCA9IDAuMSwgSz01MDAwLCB5X3NoaWZ0ID0gMSksCiAgICAgICAgICAgICAgICAgICAgICAgd2hpY2g9YygieTAiLCAibXVtYXgiLCAieV9zaGlmdCIpLAogICAgICAgICAgICAgICAgICAgICAgIHRpbWUgPSB1c19sb25nJGRheXNfc2luY2VfMV9jb25maXJtZWQsIHkgPSB1c19sb25nJGRlYXRocykKcGxvdChmaXQpCgoKYGBgCgojIExlc3NvbiA0OiBGb3JtIE1lYW5pbmdmdWwgUHJpb3IgQmVsaWVmcyB3aXRoIGEgVGhvcm91Z2ggTGl0ZXJhdHVyZSBSZXZpZXcKClRoYW5rcyB0byB0aGUgZ3Jvd2luZyByZXZvbHV0aW9uIGluIE9wZW4gU2NpZW5jZSBhbmQgcHJlcHJpbnQgb3V0bGV0cyBsaWtlIG1lZHJ4aXYub3JnIGFuZCBhcnhpdi5vcmcsIHRoZSBiYXJyaWVyIHRvIHBlcmZvcm1pbmcgYSBkZWNlbnQgcmV2aWV3IG9mIHJlY2VudCBDT1ZJRC0xOSByZXNlYXJjaCBpcyBtZW1iZXJzaGlwIGluIGFuIGFjYWRlbWljIGluc3RpdHV0aW9uIHdpdGggR29vZ2xlIFNjaG9sYXIgYWNjZXNzLCBsaWtlIFN0YXJidWNrcywgU291dGh3ZXN0IEFpcmxpbmVzLCBvciB5b3VyIGJhdGhyb29tLgoKKipEb24ndCBVc2UgU3RyYXcgTWVuIHRvIFJlcHJlc2VudCB0aGUgU3RhdGUgb2YgdGhlIEFydC4qKgoKVGhlIHBpZWNlIGJlZ2lucyB3aXRoIGFuIGluY29ycmVjdCBhbmQgb24gZmFjZSB1bmxpa2VseSBzdW1tYXJ5IG9mIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBhcnQKCj4gUmlnaHQgbm93LCB0aGUgb3ZlcndoZWxtaW5nIGNvbnNlbnN1cywgYmFzZWQgdXBvbiB0aGUgbW9zdCByZWNlbnQgcmVwb3J0cywgaXMgdGhhdCB0aGUgcmF0ZSBvZiBpbmZlY3Rpb24gd2lsbCBjb250aW51ZSB0byBpbmNyZWFzZSBzbyB0aGF0IHRoZSBtb3N0IHNldmVyZSBpbnRlcnZlbnRpb25zIGFyZSBuZWVkZWQgdG8gY29udHJvbCB3aGF0IHdpbGwgdW5kZXIgdGhlIHdvcnN0IG9mIGNpcmN1bXN0YW5jZXMgdHVybiBpbnRvIGEgaGlnaCByYXRlIG9mIGRlYXRoLiAKCj4gTXVjaCBvZiB0aGUgY3VycmVudCBhbmFseXNpcyBkb2VzIG5vdCBleHBsYWluIGhvdyBhbmQgd2h5IHJhdGVzIG9mIGluZmVjdGlvbiBhbmQgZGVhdGggd2lsbCBzcGlrZSwgc28gSSB0aGluayB0aGF0IGl0IGlzIGltcG9ydGFudCB0byBvZmZlciBhIGRpc3NlbnRpbmcgdm9pY2UuCgpPbmx5IHR3byBjaXRhdGlvbnMgYXJlIHByb3ZpZGVkLiBUaGUgW2ZpcnN0XShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAyMDAzMTkxODEyMDYvaHR0cHM6Ly93d3cubnl0aW1lcy5jb20vaW50ZXJhY3RpdmUvMjAyMC8wMy8xMy9vcGluaW9uL2Nvcm9uYXZpcnVzLXRydW1wLXJlc3BvbnNlLmh0bWwpIGlzIGFuIGVkdWNhdGlvbmFsIGluZm9ncmFwaGljIGluIHRoZSBvcGluaW9uIHNlY3Rpb24gb2YgdGhlIE5ZVC4gSXQgaW5jbHVkZXMgYSBkaXJlY3QgcXVvdGUgZnJvbSB0aGUgc2NpZW50aWZpYyBjb25zdWx0YW50cyBub3QgdG8gaW50ZXJwcmV0IHRoZSBtb2RlbCBhcyBhIHByb2R1Y3Rpb24gZm9yZWNhc3QKCj4g4oCcVGhlIHBvaW50IG9mIGEgbW9kZWwgbGlrZSB0aGlzIGlzIG5vdCB0byB0cnkgdG8gcHJlZGljdCB0aGUgZnV0dXJlIGJ1dCB0byBoZWxwIHBlb3BsZSB1bmRlcnN0YW5kIHdoeSB3ZSBtYXkgbmVlZCB0byBjaGFuZ2Ugb3VyIGJlaGF2aW9ycyBvciByZXN0cmljdCBvdXIgbW92ZW1lbnRzLCBhbmQgYWxzbyB0byBnaXZlIHBlb3BsZSBhIHNlbnNlIG9mIHRoZSBzb3J0IG9mIGVmZmVjdCB0aGVzZSBjaGFuZ2VzIGNhbiBoYXZlLOKAnQoKVGhlIFtzZWNvbmRdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDIwMDMxOTIwMjAyNi9odHRwczovL21lZGl1bS5jb20vQHRvbWFzcHVleW8vY29yb25hdmlydXMtYWN0LXRvZGF5LW9yLXBlb3BsZS13aWxsLWRpZS1mNGQzZDljZDk5Y2EpIGlzIGEgbWVkaXVtIGJsb2cgcG9zdCwgYnkgYW4gTUJBL2VuZ2luZWVyIHdobyBydW5zIGFuIGVkdWNhdGlvbiB3ZWJzaXRlLCBhbmQgY29sbGVjdHMgYSBudW1iZXIgb2YgcGxvdHMgYW5kIGluZm9ncmFwaGljcyBvbiBDT1ZJRC0xOSBmcm9tIGFyb3VuZCB0aGUgd2ViLgoKSWYgdGhlc2UgdHdvIGV4YW1wbGVzIGFyZSByZXByZXNlbnRhdGl2ZSBvZiBzb21ldGhpbmcgb3RoZXIgdGhhbiB0aGUgc2NpZW50aWZpYyBzdGF0ZSBvZiB0aGUgYXJ0LCBlLmcuIG1lZGlhIGNvbW1lbnRhcnksIHRoZW4gdGhleSBzaG91bGQgYmUgY2l0ZWQgc3BlY2lmaWNhbGx5IGluIHRoYXQgY29udGV4dCBhbmQgdGhlbiBmb2xsb3dlZCBieSB0aGUgbG9uZyBsaXN0IG9mIGFjdHVhbCBzdGF0ZSBvZiB0aGUgYXJ0IGFjYWRlbWljIHJlc2VhcmNoIHRoYXQgb3VnaHQgdG8gYmUgaW4gdGhlIHBvcHVsYXIgZGlzY291cnNlLiBJbnN0ZWFkLCB0aGVzZSB0d28gc291cmNlcyBhcmUgcHJlc2VudGVkIGFzIHN0cmF3IG1lbi4KCioqRG9uJ3QgY2xhaW0gdGhlIHN0YXRlIG9mIHRoZSBhcnQgaWdub3JlcyBmYWN0b3JzIHRoYXQgaXQgYWN0dWFsbHkgdGFrZXMgaW50byBhY2NvdW50LioqCgpFcHN0ZWluJ3MgY2VudHJhbCBjcml0aWNpc20gaXMgdGhhdCB0aGUgZXBpZGVtaW9sb2dpY2FsIG1vZGVscyBhdCB0aGUgaGVhcnQgb2YgdGhlIHNjaWVudGlmaWMgY29uc2Vuc3VzIHNoYXJlIGFuIGFic3VyZCBhbmQgaW5jb3JyZWN0IGFzc3VtcHRpb24gdGhhdCB0aGUgcmF0ZSBvZiB0aGUgc3ByZWFkIG9mIHRoZSBkaXNlYXNlLCBSMCwgcmVtYWlucyBjb25zdGFudCBvdmVyIHRpbWUuIFIwIGlzIHRoZSBudW1iZXIgb2YgcGVyc29ucywgYW4gaW5mZWN0ZWQgcGVyc29uIGlzIGxpa2VseSB0byBwYXNzIHRoZSBkaXNlYXNlIG9uIHRvLCB3aGVyZSBhYm92ZSAxIG1lYW5zIHRoZSBkaXNlYXNlcyB3aWxsIGFjY2VsZXJhdGUgaW4gZ3Jvd3RoIGluIHRoZSBwb3B1bGF0aW9uLCAxIG1lYW5zIGl0IHdpbGwgcmVtYWluIGNvbnN0YW50LCBhbmQgYmVsb3cgMSBtZWFucyBpdCB3aWxsIHNsb3dseSBkaWUgb3V0LiBUaGUgUjAgZm9yIENPVklELTE5IGlzIGVzdGltYXRlZCB0byBsaWUgc29tZXdoZXJlIGJldHdlZW4gMiBhbmQgMyBhdCB0aGUgc3RhcnQgb2Ygb3V0YnJlYWsgaW4gYW4gYXJlYS4KCkhlIGJlbGlldmVzIHRoYXQgc3RhdGUgb2YgdGhlIGFydCBlcGlkZW1pb2xvZ2ljYWwgbW9kZWxzIHByZWRpY3QgdmVyeSBoaWdoIGluZmVjdGlvbiBhbmQgZGVhdGggcmF0ZXMsIGJlY2F1c2UgdGhleSBlcnJvbmVvdXNseSBzZXQgUjAgYXMgYSBmaXhlZCBjb25zdGFudCwgYW5kIGRvIG5vdCBhZGp1c3QgaXQgZG93bndhcmQgb3ZlciB0aW1lIGFzIGluZGl2aWR1YWxzIGFuZCBnb3Zlcm5tZW50IHRha2UgYWN0aW9uIHRvIHJlZHVjZSB0aGUgc3ByZWFkLgoKUGxhaW5seSwgbm8uIFRoYXQgaXMgbm90IHdoYXQgc3RhdGUgb2YgdGhlIGFydCBlcGlkZW1pb2xvZ2ljYWwgbW9kZWxzIGRvLCBhbmQgdGhhdCdzIG5vdCB3aHkgdGhleSByZWFjaCBoaWdoIHByZWRpY3Rpb25zIG9mIGNhc2VzIGFuZCBkZWF0aHMuIAoKVGhlIGVhc2llc3Qgd2F5IHRvIHRlbGwgdGhhdCB0aGF0IGludGVycHJldGF0aW9uIGlzIHdyb25nIGlzIHRvIHNpbXBseSB0aGluayB0aHJvdWdoIHdoYXQgYSB0aW1lIGNvbnN0YW50LCBncmVhdGVyIHRoYW4gMSwgUjAgaW1wbGllcy4gSXQgd291bGQgbWVhbiB0aGUgZGlzZWFzZSdzIHByb2dyZXNzaW9uIG5ldmVyIHNsb3dzIGRvd24sIHRoZSBlbnRpcmUgcG9wdWxhdGlvbiBvZiAzMzAgbWlsbGlvbiBBbWVyaWNhbnMgZXZlbnR1YWxseSBjYXRjaCBpdCwgd2l0aCBhIGZhdGFsaXR5IHJhdGUgb2YgMSUgcHJvZHVjaW5nIDMuMyBtaWxsaW9uIGZhdGFsaXRpZXMuCgpUaGUgTllUJ3MgaW5mb2dyYXBoaWMgaGUgY2l0ZXMgc3VnZ2VzdHMgMTAwIG1pbGxpb24gaW5mZWN0ZWQgYW5kIDEgbWlsbGlvbiBkZWFkLiBTbyBSMCBtZWNoYW5pY2FsbHkgbXVzdCBub3QgcmVtYWluIGNvbnN0YW50LCBpdCBtdXN0IGRlY2xpbmUgZnJvbSB0aGUgaW5pdGlhbCB2YWx1ZSAoUjA9Mi4zIGluIHRoYXQgbW9kZWwpLgoKVGhlIHNlY29uZCBlYXNpZXN0IHdheSB0byB0ZWxsIHRoYXQgdGhhdCBpbnRlcnByZXRhdGlvbiBpcyB3cm9uZyBpcyB0byBhY3R1YWxseSByZWFkIHRoZSBhcnRpY2xlIHdoZXJlIGl0IGRpcmVjdGx5IHNwZWNpZmllcyBhIHNjaGVkdWxlIG9mIFIwIHJlZHVjdGlvbiBiYXNlZCBvbiAibWlsZCBpbnRlcnZlbnRpb24iCgo+IFRoZSBtaWxkIGludGVydmVudGlvbiBhcyBtb2RlbGVkIGhlcmUgaXMgd2hlcmUgd2UgYXJlIG5vdyBpbiB0aGUgVW5pdGVkIFN0YXRlczogSXQgaXMgYSBzdGF0dXMgcXVvIGluIHdoaWNoIHNvbWUgZ2F0aGVyaW5ncyBhcmUgY2FuY2VsZWQgYW5kIHRoZXJlIGlzIHByb21vdGlvbiBvZiBzb2NpYWwgZGlzdGFuY2luZyBhbmQgd29yayBmcm9tIGhvbWUsIGJ1dCB3aXRoIGluYWRlcXVhdGUgdGVzdGluZyBhbmQgdW5hZGRyZXNzZWQgc3VwcGx5IHNob3J0YWdlcy4KClRoZSB0aGlyZCBlYXNpZXN0IHdheSB0byB0ZWxsIHRoYXQgdGhhdCBpbnRlcnByZXRhdGlvbiBpcyB3cm9uZywgaXMgdG8gbG9vayBhdCBhbnkgb2YgdGhlIENPVklELTE5IHBhbmRlbWljIG1vZGVscyBhdmFpbGFibGUgb25saW5lIG9yIGluIHB1Ymxpc2hlZCByZXNlYXJjaCBhbmQgc2VlIGhvdyB0aGV5IGhhbmRsZSBSMCBvdmVyIHRpbWUuCgpGb3IgZXhhbXBsZSBbQ09WSUQtMTkgU2NlbmFyaW9zXShodHRwczovL25laGVybGFiLm9yZy9jb3ZpZDE5Lykgb3V0IG9mIHRoZSBVbml2ZXJzaXR5IG9mIEJhc2VsIGFsbG93cyB5b3UgdG8gY2hvb3NlIGJldHdlZW4gc3Ryb25nLCBtb2RlcmF0ZSwgd2Vhaywgbm9uZSwgb3IgYSB1c2VyIGN1c3RvbWl6YWJsZSBzY2hlZHVsZSBvZiBSMCBkZWNsaW5lLiBFcGlkZW1pYyBFbnZpc2lvbmVyIGluIGRldmVsb3BtZW50IGF0IE1JVCBoYXMgNyBkaWZmZXJlbnQgcG9zc2libGUgZGVjYXkgZnVuY3Rpb25zIGZvciBSMCB0byBjaG9vc2UgZnJvbS4gVGhlIFtFcGlkZW1pYyBDYWxjdWxhdG9yXShodHRwOi8vZ2FiZ29oLmdpdGh1Yi5pby9DT1ZJRC9pbmRleC5odG1sKSBhbGxvd3MgeW91IHRvIHZhcnkgdGhlIHRpbWluZyBvZiBhbiBpbnRlcnZlbnRpb24gYW5kIGl0cyBlZmZlY3Qgb24gUjAuIFRoZSBbU3dpc3MtZXBpZGVtaWMtbW9kZWxdKGh0dHBzOi8vaXNwbWJlcm4uZ2l0aHViLmlvL2NvdmlkLTE5L3N3aXNzLWVwaWRlbWljLW1vZGVsLykgZXhwbGljaXRseSBjb21wYXJlcyB0aGUgZWZmZWN0IG9mIHJlZHVjaW5nIHRyYW5zbWlzc2lvbiByYXRlcyBzdGFydGluZyB0b2RheSBvdmVyIGEgcmFuZ2Ugb2YgdmFsdWVzIGZyb20gMCB0byAxMDAlLgoKVGhlIGFnZW50IGJhc2VkIG1vZGVsIGJlaGluZCB0aGUgW0ltcGVyaWFsIENvbGxlZ2Ugc3R1ZHldKGh0dHBzOi8vd3d3LmltcGVyaWFsLmFjLnVrL21lZGlhL2ltcGVyaWFsLWNvbGxlZ2UvbWVkaWNpbmUvc3BoL2lkZS9naWRhLWZlbGxvd3NoaXBzL0ltcGVyaWFsLUNvbGxlZ2UtQ09WSUQxOS1OUEktbW9kZWxsaW5nLTE2LTAzLTIwMjAucGRmKSBleGFtaW5lcyBtYW55IGRpZmZlcmVudCBhZGFwdGl2ZSBub24tZ292ZXJubWVudCBzdHJhdGVnaWVzIGluY2x1ZGluZyBjYXNlIGlzb2xhdGlvbiBpbiB0aGUgaG9tZSBhZnRlciBpbmRpdmlkdWFsIHN5bXB0b21zLCB2b2x1bnRhcnkgaG9tZSBxdWFyYW50aW5lIGlmIGFueW9uZSBoYXMgc3ltcHRvbXMsIHNvY2lhbCBkaXN0YW5jaW5nIGZvciB0aG9zZSBvdmVyIDcwLCBhbmQgc29jaWFsIGRpc3RhbmNpbmcgZm9yIHRoZSBlbnRpcmUgcG9wdWxhdGlvbi4gV2l0aCB0aG9zZSBpbiBwbGFjZSwgaXQgc3RpbGwgcHJlZGljdHMgYW4gODElIGluZmVjdGlvbiByYXRlIGFuZCAyLjIgbWlsbGlvbiBkZWF0aHMuIFRoZSBbRnJhbWV3b3JrIGZvciBSZWNvbnN0cnVjdGluZyBFcGlkZW1pb2xvZ2ljYWwgRHluYW1pY3MgKEZSRUQpXShodHRwczovL3d3dy5wb3N0LWdhemV0dGUuY29tL25ld3MvaGVhbHRoLzIwMjAvMDMvMjcvQ09WSUQtMTktY29yb25hdmlydXMtVW5pdmVyc2l0eS1QaXR0c2J1cmdoLWhvc3BpdGFsaXphdGlvbi1GUkVELXBhbmRlbWljLW1vZGVsLWNhc2Utc3R1ZHkvc3Rvcmllcy8yMDIwMDMyMzAwNjcpIG91dCBvZiB0aGUgVW5pdmVyc2l0eSBvZiBQaXR0c2J1cmdoIGlzIGFsc28gYWdlbnQgYmFzZWQgYW5kIHRha2VzIGludG8gYWNjb3VudCBhZGFwdGl2ZSByZXNwb25zZSB0aGF0IGRyaXZlIFIwIGRvd24gb3ZlciB0aW1lLiBPciB0aGlzIFtzdG9jaGFzdGljIHRyYW5zbWlzc2lvbiBtb2RlbF0oaHR0cHM6Ly93d3cudGhlbGFuY2V0LmNvbS9qb3VybmFscy9sYW5pbmYvYXJ0aWNsZS9QSUlTMTQ3My0zMDk5KDIwKTMwMTQ0LTQvZnVsbHRleHQpIGZpdCB0byBkYXRhIGZyb20gV3VoYW4gYW5kIGhhcyBhIHRpbWUgdmFyeWluZyBSMC4gW1ByZW0gZXQgYWwuIDIwMjBdKGh0dHBzOi8vd3d3LnRoZWxhbmNldC5jb20vam91cm5hbHMvbGFucHViL2FydGljbGUvUElJUzI0NjgtMjY2NygyMCkzMDA3My02L2Z1bGx0ZXh0KSBzaW11bGF0ZSBsaWZ0aW5nIHRoZSBjb250cm9sIG1lYXN1cmVzIGluIFd1aGFuLCB3aXRoIGEgZml4ZWQgUjAsIGJ1dCB0cmFuc21pc3Npb24gbW9kZWxlZCBkaXJlY3RseSBieSBpbnRlcmdlbmVyYXRpb25hbCBtaXhpbmcgYXMgcmVzdHJpY3Rpb25zIGFyZSBsaWZ0ZWQgYWdhaW4gb3ZlciB0aW1lLiAKCkluIGdlbmVyYWwsIENPVklELTE5IG1vZGVscywgY2VydGFpbmx5IG1vZGVscyBpbiBwcm9kdWN0aW9uLCB0YWtlIGludG8gYWNjb3VudCBjaGFuZ2VzIGluIFIwIG92ZXIgdGltZS4gTW9yZSBwcmVjaXNlbHksIHRoZSBoaWdoIGVuZCBtb2RlbHMgc2ltdWxhdGUgdGhlIGRpcmVjdCBiZWhhdmlvcnMgdGhhdCBsZWFkIHRvIHRyYW5zbWlzc2lvbnMsIG9mIHdoaWNoIFIwIGlzIGEgc3VtbWFyeSBzdGF0aXN0aWMuIERlZmF1bHQgcGFyYW1ldGVycyBhcmUgdXN1YWxseSBzZXQgdG8gY3VycmVudCBsZXZlbHMgb2YgbWl0aWdhdGlvbi4gVGhlIGNvbXBsZXRlbHkgdW5taXRpZ2F0ZWQgY2FzZSBpcyBubyBsb25nZXIgYSByZWxldmFudCBjb3VudGVyZmFjdHVhbCwgYXMgdGhlIHdvcmxkIG5vdyBrbm93cyBhYm91dCB0aGUgZGlzZWFzZSwgYW5kIHRoZSByZWxldmFudCBwb2xpY3kgY2hvaWNlcyBhcmUgYmV0d2VlbiBncmVhdGVyIGFuZCBsZXNzZXIgZGVncmVlcyBvZiBtaXRpZ2F0aW9uLgoKKipEb24ndCBnZXQgYmFzaWMgZmFjdHMgd3JvbmcuKioKClRoZSBwaWVjZSByZXBlYXRzIHR3aWNlIHRoZSBpbmNvcnJlY3QgZmFjdCB0aGF0IENPVklELTE5IGhhcyBhICJyZWxhdGl2ZWx5IHNob3J0ICh0d28td2VlaykgaW5jdWJhdGlvbiBwZXJpb2QuIiBbRXZlbl0oaHR0cHM6Ly93d3cuc2NpZW5jZWRpcmVjdC5jb20vc2NpZW5jZS9hcnRpY2xlL3BpaS9TMTIwMTk3MTIyMDMwMTE5MykgIGEgIFtjdXJzb3J5XShodHRwczovL3BhcGVycy5zc3JuLmNvbS9zb2wzL3BhcGVycy5jZm0/YWJzdHJhY3RfaWQ9MzUzOTY5NCkgc2VhcmNoIFt3b3VsZF0oaHR0cHM6Ly93d3cubWVkcnhpdi5vcmcvY29udGVudC8xMC4xMTAxLzIwMjAuMDIuMTkuMjAwMjU0NTJ2NCkgcG9pbnQgW3RvXShodHRwczovL3d3dy5tZWRyeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvMjAyMC4wMi4yMS4yMDAyNjU1OXYxKSBlc3RpbWF0ZXMgb2YgYW4gaW5jdWJhdGlvbiBwZXJpb2Qgb2YgYWJvdXQgNSBkYXlzLCBhbmQgYW4gZXZlbiBzaG9ydGVyIHNlcmlhbCBpbnRlcnZhbCBvZiBhYm91dCA0LjUgZGF5cy4KCkJldHRlciB5ZXQsIHdoZW4gc3RhcnRpbmcgcmVzZWFyY2ggb24gYSBuZXcgYXJlYSwgcmVhZGluZyBvbmUgb2YgdGhlIG1hbnkgZXhpc3RpbmcgW2xpdGVyYXR1cmUgcmV2aWV3c10oaHR0cHM6Ly93d3cudGhlbGFuY2V0LmNvbS9qb3VybmFscy9sYW5jZXQvYXJ0aWNsZS9QSUlTMDE0MC02NzM2KDIwKTMwNTY3LTUvZnVsbHRleHQpIGZvciBsYXkgYXVkaWVuY2VzIHdvdWxkIGV4cGxhaW4gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBhIHNlcmlhbCBpbnRlcnZhbCBhbmQgYW4gaW5jdWJhdGlvbiBwZXJpb2QsIHRoZSB0aW1lIHVudGlsIGluZmVjdGlvdXMgYW5kIHRoZSB0aW1lIHVudGlsIHN5bXB0b21hdGljLCBhbmQgdGhhdCBDT1ZJRC0xOSBpcyBwYXJ0aWN1bGFybHkgZGFuZ2Vyb3VzIHByZWNpc2VseSBiZWNhdXNlIG1hbnkgcGVvcGxlIGNhbiBwYXNzIG9uIHRoZSBkaXNlYXNlIHByaW9yIHRvIGtub3dpbmcgdGhleSBoYXZlIGl0LgoKKipEb24ndCBjaGVycnkgcGljayBkYXRhLioqCgpFcHN0ZWluICgyMDIwKSBjaG9vc2VzIHRvIGZvY3VzIG9uIHRoZSBDYXNlIEZhdGFsaXR5IFJhdGUgb2YgU291dGggS29yZWEsIG9zdGVuc2libHkgbm90IGJlY2F1c2UgaXRzIHJlbGF0aXZlbHkgbG93IGVzdGltYXRlIG9mIDAuOTIlIGZpdHMgaGlzIHN0b3J5LCBidXQgYmVjYXVzZSBpdHMgbW9yZSBjb21wcmVoZW5zaXZlIHRlc3RpbmcgbWFrZXMgaXQgbW9yZSBhY2N1cmF0ZS4KCj4gSXQgaXMgaW5zdHJ1Y3RpdmUgdG8gc2VlIGhvdyB0aGlzIGFuYWx5c2lzIGZhcmVzIGJ5IHRha2luZyBpbnRvIGFjY291bnQgdGhlIEtvcmVhbiBkYXRhLCB3aGljaCBpcyBtb3JlIGNvbXBsZXRlIHRoYW4gdGhlIEFtZXJpY2FuIGRhdGEuIFNvdXRoIEtvcmVhIGhhcyBiZWVuIGRlYWxpbmcgd2l0aCB0aGUgY29yb25hdmlydXMgc2luY2UgSmFudWFyeSAyMC4gU2luY2UgdGhhdCB0aW1lLCB0aGUgS29yZWFuIGdvdmVybm1lbnQgaGFzIGFkbWluaXN0ZXJlZCBhIHRvdGFsIG9mIDI2MSwzMzUgdGVzdHMgdG8gaXRzIGNpdGl6ZW5zLiBJbiBwcmVzcyByZWxlYXNlcyB1cGRhdGVkIGV2ZXJ5IGRheSwgdGhlIEtvcmVhbiBDREMgaXMgcmVwb3J0aW5nIChhcyBvZiBNYXJjaCAxNSkgOCwxNjIgdG90YWwgaW5mZWN0aW9ucyBhZ2FpbnN0IDc1IGRlYXRocyBmb3IgYW4gb3ZlcmFsbCBtb3J0YWxpdHkgcmF0ZSBvZiAwLjkyIHBlcmNlbnQuIAoKU2VsZWN0aW5nIG9uIGRhdGEgcXVhbGl0eSBpcyBwcm9ibGVtYXRpYyBiZWNhdXNlIFNvdXRoIEtvcmVhJ3MgZHJhY29uaWFuIHRlc3RpbmcgcmVnaW1lIGlzIHBhcnQgb2YgaXRzIHN1Y2Nlc3MgaW4gY29tYmF0aW5nIENPVklELTE5IGFuZCBpdHMgbG93IENGUi4gTG9va2luZyBmb3IgeW91ciBjYXIga2V5cyB1bmRlciB0aGUgc3RyZWV0bGlnaHQgbm90IGJlY2F1c2UgdGhhdCdzIHdoZXJlIHRoZXkgYXJlIGJ1dCB0aGF0J3Mgd2hlcmUgeW91IGNhbiBzZWUgaXMgYSB1bml2ZXJzYWxseSBwcm9ibGVtYXRpYyBhcHByb2FjaCB0byBzY2llbnRpZmljIGlucXVpcnksIGVzcGVjaWFsbHkgc28gd2hlcmUgbWVhc3VyZW1lbnQsIGdvdmVybmFuY2UsIGFuZCBkaXNhc3RlciBhbGwgYXJlIHN0cm9uZ2x5IHJlbGF0ZWQuIAoKQ2hlcnJ5IHBpY2tpbmcgYSBjYXNlIHdpdGggZ29vZCBkYXRhIGFuZCBnb29kIG5ld3MgYWxzbyBtaXNyZXByZXNlbnRzIGNlcnRhaW50eSBvdmVyIHRoZSBtZWFzdXJlLiBFc3RpbWF0aW5nIHRoZSBDYXNlIEZhdGFsaXR5IFJhdGlvIENGUiBpcyBkaWZmaWN1bHQgYW5kIGNhbiBjaGFuZ2UgaW4gW2VpdGhlciBkaXJlY3Rpb25dKGh0dHBzOi8vd3d3LnJhbmQub3JnL2Jsb2cvMjAyMC8wMy9lc3RpbWF0ZXMtb2YtY292aWQtMTlzLWZhdGFsaXR5LXJhdGUtbWlnaHQtY2hhbmdlLWFuZC5odG1sKSBvdmVyIHRpbWUgYXMgZGF0YSBjb21lIGluLiBUaGUgQ0ZSIG1heSBub3QgYmUga25vd2FibGUgW2ZvciBtb250aHNdKGh0dHBzOi8vd3d3LmhpbmRhd2kuY29tL2pvdXJuYWxzL2NtbW0vMjAxMi85Nzg5MDEvKS4gIAoKQmVjYXVzZSBvZiB0aGlzIGFjdHVhbCBDRlIgZXN0aW1hdGVzIGZvciBDT1ZJRC0xOSBbdmFyeSB3aWxkbHkgYWNyb3NzIGNvdW50cmllc10oaHR0cHM6Ly93d3cuY2VibS5uZXQvZ2xvYmFsLWNvdmlkLTE5LWNhc2UtZmF0YWxpdHktcmF0ZXMvKS4gVGhlcmUgYXJlIFtoZXJvaWMgYXR0ZW1wdHNdKGh0dHBzOi8vd3d3Lm1lZHJ4aXYub3JnL2NvbnRlbnQvbWVkcnhpdi9lYXJseS8yMDIwLzAzLzA2LzIwMjAuMDMuMDQuMjAwMzExMDQuZnVsbC5wZGYpIHRvIGNvbWJpbmUgc2V2ZXJhbCBkaWZmZXJlbnQga2luZHMgb2YgZGF0YSB0YWtpbmcgaW50byBhY2NvdW50IFt1bmRlcmNvdW50aW5nXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3BtYy9hcnRpY2xlcy9QTUM0NzA3NTYwLykgdG8gZXN0aW1hdGUgdGhlIENGUiBmb3IgY2FzZXMgd2UgY2FyZSBhYm91dCBsaWtlIENoaW5hLCBhbmQgdGhleSBhcmUgc3RpbGwgZmluZGluZyBDRlJzIG5vcnRoIG9mIDElICgxLjYlKS4gCgoqKlRha2UgdGhlIGNvbnNlbnN1cyBleHBsYW5hdGlvbiBzZXJpb3VzbHkuKioKClRoZXJlIGFyZSBhdCBsZWFzdCB0d28gdHlwZXMgb2YgZmF0YWxpdGllcyBmcm9tIENPVklELTE5LiBUaGUgZmlyc3QgYXJlIHBlcnNvbnMgd2hvIHJlY2VpdmUgYWRlcXVhdGUgbWVkaWNhbCBjYXJlIGJ1dCBkaWUgYW55d2F5LiBUaGUgc2Vjb25kIGFyZSBwZXJzb25zIHdobyB3b3VsZCBoYXZlIHN1cnZpdmVkIGJ1dCByZWNlaXZlZCBpbnN1ZmZpY2llbnQgb3IgZGVncmFkZWQgbWVkaWNhbCBjYXJlLgoKVGhlcmUgaXMgYSB2ZWluIG9mIHJlc2VhcmNoIG9uIHdoeSBDT1ZJRC0xOSBhY3R1YWxseSBraWxscyB5b3UsIHdoaWNoIGluIGFkZGl0aW9uIHRvIGFnZSBmaW5kcyBzcGVjaWZpYyB2dWxuZXJhYmlsaXRpZXMgbGlrZSBoeXBlcnRlbnNpb24sIGhlYXJ0IGRpc2Vhc2UsIGRpYWJldGVzLCBbY2FyZGlvdmFzY3VsYXIgZGlzZWFzZV0oaHR0cHM6Ly93d3cubWVkcnhpdi5vcmcvY29udGVudC8xMC4xMTAxLzIwMjAuMDIuMjQuMjAwMjcyNjh2MSksIGNhbmNlciwgY2hyb25pYyByZXNwaXJhdG9yeSBkaXNlYXNlLCBhbmQgW2tpZG5leSBpbXBhaXJtZW50XShodHRwczovL3d3dy5tZWRyeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvMjAyMC4wMi4xOC4yMDAyMzI0MnYxKS4gVGhlIG1lY2hhbmlzbSBieSB3aGljaCBDT1ZJRC0xOSBraWxscyBpbmNsdWRlcyBwbmV1bW9uaWEgYXMgd2VsbCBhcyBbbXlvY2FyZGlhbF0oaHR0cHM6Ly93d3cubWVkcnhpdi5vcmcvY29udGVudC8xMC4xMTAxLzIwMjAuMDIuMjYuMjAwMjg1ODl2MSkgW2luanVyeV0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9zNDE1NjktMDIwLTAzNjAtNSkuIEl0IG1heSBhbHNvIFtkYW1hZ2UgdGhlIGxpdmVyXShodHRwczovL3d3dy50aGVsYW5jZXQuY29tL2pvdXJuYWxzL2xhbmdhcy9hcnRpY2xlL1BJSVMyNDY4LTEyNTMoMjApMzAwNTctMS9mdWxsdGV4dCkuCgpTdHJlc3Mgb24gdGhlIGx1bmdzIG5lY2Vzc2l0YXRlcyBveHlnZW4sIHZlbnRpbGF0aW9uLCBhbmQgZXZlbiBpbnR1YmF0aW9uIHdoaWNoIHBsYWNlcyBhbiBlbm9ybW91cyBzdHJhaW4gb24gaGVhbHRoY2FyZSByZXNvdXJjZXMuIEhvc3BpdGFsaXphdGlvbiByYXRlcyBpbiBlYXJseSBVLlMuIENEQyBkYXRhIGFyZSBbMjUlXShodHRwczovL3d3dy5pbmRlcGVuZGVudC5jby51ay9uZXdzL3dvcmxkL2FtZXJpY2FzL2Nvcm9uYXZpcnVzLW5ldy15b3JrLWhvc3BpdGFsLWNhc2VzLXRvZGF5LW1hcC1kZWNyZWFzZS1jb3ZpZC0xOS1hOTQyNTExMS5odG1sKSwgYW5kIGFyZSBjdXJyZW50bHkgWzEyJSBpbiBOZXcgWW9ya10oaHR0cHM6Ly93d3cuaW5kZXBlbmRlbnQuY28udWsvbmV3cy93b3JsZC9hbWVyaWNhcy9jb3JvbmF2aXJ1cy1uZXcteW9yay1ob3NwaXRhbC1jYXNlcy10b2RheS1tYXAtZGVjcmVhc2UtY292aWQtMTktYTk0MjUxMTEuaHRtbCkuIEEgcHJvcGVyIGxpdGVyYXR1cmUgcmV2aWV3IHdvdWxkIGZpbmQgW2dyb3dpbmddKGh0dHBzOi8vd3d3LnRoZWxhbmNldC5jb20vam91cm5hbHMvbGFuZ2xvL2FydGljbGUvUElJUzIyMTQtMTA5WCgyMCkzMDA2OC0xL2Z1bGx0ZXh0I2ZpZzEpICwgW2V2aWRlbmNlXShodHRwczovL3d3dy5tZWRyeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvMjAyMC4wMi4yNi4yMDAyODQ3MnYzKSBmb3IgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhdmFpbGFibGUgaGVhbHRoIHJlc291cmNlcyBhbmQgbW9ydGFsaXR5LiBJbmNsdWRpbmcgdGhhdCBJdGFseSB0b29rIHRoZSBzdGFydCBvZiB0aGUgZGlzZWFzZSBbcXVpdGUgc2VyaW91c2x5XShodHRwczovL2phbWFuZXR3b3JrLmNvbS9qb3VybmFscy9qYW1hL2Z1bGxhcnRpY2xlLzI3NjMxODgpLiBGdXJ0aGVyLCB0aGUgW2Vhcmx5IFUuUy4gZGF0YV0oaHR0cHM6Ly93d3cuY2RjLmdvdi9tbXdyL3ZvbHVtZXMvNjkvd3IvbW02OTEyZTIuaHRtKSBzaG93IG9sZGVyIHRoYW4gNjUgYWNjb3VudGluZyBmb3IgODAlIG9mIGRlYXRocyBidXQgb25seSA0NSUgb2YgaG9zcGl0YWxpemF0aW9ucyBhbmQgNTMlIG9mIElDVSBhZG1pc3Npb25zLiBZb3VuZyBBbWVyaWNhbnMgYXJlIG1vcmUgbGlrZWx5IHRvIHN1cnZpdmUsIGJ1dCBtYW55IHN0aWxsIHJlcXVpcmUgbWVkaWNhbCBpbnRlcnZlbnRpb24gdG8gZG8gc28uCgpUaGlzIGlzIHRoZSBjYXVzZSBmb3IgdGhlIHN1ZGRlbiBzcGlrZSBpbiBtb3J0YWxpdHkgcmVwb3J0ZWQgaW4gdGhlIHNjaWVudGlmaWMgY29uc2Vuc3VzLiBJdCdzIHdoeSB0aGUgYWx0ZXJuYXRpdmUgcHJvcG9zYWwgb2Ygc2hlbHRlcmluZyBpbiBwbGFjZSBvbmx5IG9sZGVyIEFtZXJpY2FucyB3b3VsZG4ndCB3b3JrLiBEb2luZyBzbyB3b3VsZG4ndCBldmVuIHJlbW92ZSBoYWxmIG9mIHRoZSBjdXJyZW50IGJ1cmRlbiBvbiB0aGUgaGVhbHRoY2FyZSBzeXN0ZW0sIGFuZCB3b3VsZCBpbnN0ZWFkIGdyZWF0bHkgYWRkIHRvIGl0IHdoZW4gbW9zdCBhZHVsdHMgdW5kZXIgNjAgY29udHJhY3QgdGhlIGRpc2Vhc2UgdG9nZXRoZXIgYXQgYWJvdXQgdGhlIHNhbWUgdGltZSwgYW5kIDEwJSBvZiB0aGVtIGhlYWQgdG8gdGhlIGhvc3BpdGFsIGF0IGFib3V0IHRoZSBzYW1lIHRpbWUuIAoKIyBMZXNzb24gNTogRG9uJ3QgRm9ybSBTdHJvbmcgUHJpb3IgQmVsaWVmcyBCYXNlZCBvbiBDaGVycnkgUGlja2VkIERhdGEKCkluIHNldHRpbmcgdXAgb3VyIHJlc2VhcmNoIGRlc2lnbiwgd2Ugd2FudCB0byBwcmVkaWN0IFUuUy4gY2FzZXMgYnV0IHdlIHdhbnQgdG8gYmFzZSB0aGF0IHByZWRpY3Rpb24gb24gYSBtb2RlbCBmaXQgbW9yZSBicm9hZGx5IG9uIG90aGVyIHJlcHJlc2VudGF0aXZlIGRhdGEuIAoKRm9yIGV4YW1wbGUsIEVwc3RlaW4gc2V0cyB1cCB0aGlzIHNtYWxsIGNvbXBhcmlzb24gYmV0d2VlbiBlYXJseSBVLlMuIGRlYXRoIHJhdGVzIGluIFdhc2hpbmd0b24gdG8gcGVhayBkZWF0aCByYXRlcyBpbiBJdGFseSBvciBDaGluYS4KCj4gV2hhdCwgdGhlbiwgZG9lcyBhbGwgb2YgdGhpcyBwb3J0ZW5kIGZvciB0aGUgZnV0dXJlIG9mIENPVklELTE5IGluIHRoZSBVbml0ZWQgU3RhdGVzPyBHb29kIG5ld3MgaXMgbW9yZSBsaWtlbHkgdGhhbiBiYWQsIG5vdHdpdGhzdGFuZGluZyB0aGUgbW9kZWxzIHRoYXQgcHJlZGljdCBvdGhlcndpc2UuIFRoZSBkZWF0aHMgaW4gV2FzaGluZ3RvbiBoYXZlIHJpc2VuIG9ubHkgc2xvd2x5LCBldmVuIGFzIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucyBtb3VudC4gCgpXZSBzaG91bGQgaW5zdGVhZCBwaHJhc2UgdGhpcyBhcyBhIHF1ZXN0aW9uLCBob3cgZG9lcyB0aGUgVS5TLidzIGdyb3d0aCByYXRlIGluIENPVklELTE5IGRlYXRocyBjb21wYXJlIHRvIGVsc2V3aGVyZT8gSXMgZWFybHkgZGF0YSBmcm9tIG9uZSBvciBtb3JlIHN0YXRlcyBsaWtlbHkgdG8gYmUgcmVwcmVzZW50YXRpdmUgb2YgdGhlIFUuUy4gYXZlcmFnZSByYXRlPyAKClRvIGFuc3dlciB0aGlzIHF1ZXN0aW9uLCB3ZSBjb21wYXJlIGVhY2ggY291bnRyeSBhbmQgZWFjaCBVLlMuIHN0YXRlIHNpZGUgYnkgc2lkZSwgYWxpZ25pbmcgdGhlaXIgZXBpc29kZXMgYnkgdGhlIGZpcnN0IGRhdGUgZWFjaCBjcm9zc2VkIDEwMCBjb25maXJtZWQgY2FzZXMuIFdlIGZpdCBhIGxpbmVhciB0cmVuZCBsaW5lIHRvIHRoZSBjdW11bGF0aXZlIGNvdW50IG9mIGRlYXRocyBpbiBlYWNoIGNvdW50cnkgKGxvZyB0cmFuc2Zvcm1lZCkuIEZyb20gdGhlIHNsb3BlIG9mIHRoYXQgbGluZSB3ZSBjYW4gY2FsY3VsYXRlIHRoZSBkYXkgb3ZlciBkYXkgYXZlcmFnZSBwZXJjZW50IGNoYW5nZSBpbiBkZWF0aHMgaW4gZWFjaCBsb2NhdGlvbi4KCkhlcmUgYXJlIHRoZSByYXcgZGF0YSBmb3IgY291bnRyaWVzIHdpdGggbW9yZSB0aGFuIDEwMCBjYXNlcywgd2l0aCBjb2xvcmluZyBhbmQgdHJlbmQgbGluZXMgZml0IHRvIHRoZSA0IHN1Z2dlc3RlZCBjYXNlIGNvbXBhcmlzb25zLCBJdGFseSwgQ2hpbmEsIFdhc2hpbmd0b24gU3RhdGUsIGFuZCB0aGUgVS5TLiBhcyBhIHdob2xlLiAKCmBgYHtyLCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPUYsIHdhcm5pbmc9RkFMU0V9CgpyZXF1aXJlKHNjYWxlcykKbGlicmFyeShnZ2hpZ2hsaWdodCk7ICNpbnN0YWxsLnBhY2thZ2VzKCdnZ2hpZ2hsaWdodCcpCm9wdGlvbnMoZ2doaWdobGlnaHRfbWF4X2xhYmVscz0xMDAwKQoKY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCA8LSBjb3VudHJpZXNfYW5kX3VzX3N0YXRlcyAlPiUgZmlsdGVyKGRheXNfc2luY2VfMTAwX2NvbmZpcm1lZD4wKSAlPiUgZmlsdGVyKGRheXNfc2luY2VfMTAwX2NvbmZpcm1lZDwzMCkgICU+JSBmaWx0ZXIoIWlzLm5hKGRlYXRocykpICMlPiUKICAgICAgICAgICAgICAgICAgICAgI2RwbHlyOjpmaWx0ZXIocHJlZmVyZWRfbGFiZWwgJWluJSBjKCJXYXNoaW5ndG9uLCBVUyIsIlVTIiwiSXRhbHkiLCJDaGluYSIpKSAjaWYgdGhlIGxhc3QgZG90IGlzIE5BIGl0IHdvbid0IGxhYmVsIGl0IQoKdXNfYW5kX3VzX3N0YXRlc19maXJzdDMwIDwtIGNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzAgJT4lIGZpbHRlcihjb3VudHJ5PT0iVVMiKQogIApsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGJyb29tKQpkZkhvdXIgPSBjb3VudHJpZXNfYW5kX3VzX3N0YXRlc19maXJzdDMwICU+JSBkcGx5cjo6c2VsZWN0KHByZWZlcmVkX2xhYmVsLGNvbmZpcm1lZCwgZGVhdGhzLCBjb25maXJtZWRfbWF4LCBkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQgKSAlPiUgbmEub21pdCgpICU+JSBncm91cF9ieShwcmVmZXJlZF9sYWJlbCkgJT4lIGRvKGZpdEhvdXIgPSBsbShsb2coZGVhdGhzKzEpIH4gZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCBkYXRhID0gLikpCmRmSG91ckNvZWYgPSB0aWR5KGRmSG91ciwgZml0SG91cikgJT4lIGRwbHlyOjpmaWx0ZXIodGVybSAlaW4lICJkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQiKSAlPiUgdW5ncm91cCgpIApkZkhvdXJDb2VmJHBlcmNlbnRfY2hhbmdlIDwtIHJvdW5kKChleHAoZGZIb3VyQ29lZiRlc3RpbWF0ZSktMSkqMTAwLDIpIApzbG9wZXNfY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCA8LSBkZkhvdXJDb2VmICU+JSBkcGx5cjo6c2VsZWN0KHByZWZlcmVkX2xhYmVsLCBwZXJjZW50X2NoYW5nZSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHByZWZlcmVkX2xhYmVsPWZjdF9yZW9yZGVyKHByZWZlcmVkX2xhYmVsLCBwZXJjZW50X2NoYW5nZSkgKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyU+JSBmaWx0ZXIoIXBlcmNlbnRfY2hhbmdlID09IDApCgpzbG9wZXNfY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCAlPiUgZmlsdGVyKCFzdHJfZGV0ZWN0KHByZWZlcmVkX2xhYmVsLCJVUyQiKSkgJT4lCiAgZmlsdGVyKHBlcmNlbnRfY2hhbmdlIT0wKSAlPiUgcHVsbChwZXJjZW50X2NoYW5nZSkgJT4lIHF1YW50aWxlKCkKCmNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzBfY292YXJpYXRlcyA8LSBjb3VudHJpZXNfYW5kX3VzX3N0YXRlc19maXJzdDMwICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKHNsb3Blc19jb3VudHJpZXNfYW5kX3VzX3N0YXRlc19maXJzdDMwKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUocHJlZmVyZWRfbGFiZWw9ZmN0X3Jlb3JkZXIocHJlZmVyZWRfbGFiZWwsIHBlcmNlbnRfY2hhbmdlKSApIAoKcF9zbG9wZXNfY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCA9IHNsb3Blc19jb3VudHJpZXNfYW5kX3VzX3N0YXRlc19maXJzdDMwICAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighcGVyY2VudF9jaGFuZ2UgPT0gMCkgICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1wZXJjZW50X2NoYW5nZSwgeT1wcmVmZXJlZF9sYWJlbCwgY29sb3I9cHJlZmVyZWRfbGFiZWwpKSArIGdlb21fcG9pbnQoKSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYigiQXZlcmFnZSBEYXkgb3ZlciBEYXkgUGVyY2VudCBHcm93dGggaW4gRGVhdGhzIChGaXJzdCAzMCBEYXlzKSIpICsgdGhlbWVfYncoKSArIHlsYWIoIiIpICArIAogIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2doaWdobGlnaHQocHJlZmVyZWRfbGFiZWwgJWluJSBjKCJXYXNoaW5ndG9uLCBVUyIsIkl0YWx5IiwiQ2hpbmEiLCJVUyIpICwgIyJOZXcgWW9yaywgVVMiICMsICJVUyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbF9wYXJhbXMgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnQuYWxwaGE9MCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKI3Bfc2xvcGVzX2NvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzAgPSBzbG9wZXNfY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCAlPiUKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoKSArIGdlb21fZGVuc2l0eShhZXMoeD1wZXJjZW50X2NoYW5nZSkpICsgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYigiQXZlcmFnZSBEYXkgb3ZlciBEYXkgUGVyY2VudCBHcm93dGggaW4gRGVhdGhzIChGaXJzdCAzMCBEYXlzKSIpICsgdGhlbWVfYncoKSAKCnAxIDwtIGNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzBfY292YXJpYXRlcyAlPiUKICAgICAgIGdncGxvdCgpICsgCiAgICAgICBndWlkZXMoY29sb3I9RkFMU0UpICsKICAgICAgIGdlb21fbGluZShkYXRhPWNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzBfY292YXJpYXRlcywgCiAgICAgICAgICAgICAgICBhZXMoeD1kYXlzX3NpbmNlXzEwMF9jb25maXJtZWQsIHk9ZGVhdGhzLCBjb2xvcj1wcmVmZXJlZF9sYWJlbCApKSArCiAgICAgICAjZ2VvbV9sYWJlbChkYXRhPWNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzAsIAogICAgICAgIyAgICAgICAgYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWRlYXRocywgY29sb3I9cHJlZmVyZWRfbGFiZWwgKSkgJT4lCiAgICAgICBnZW9tX3Ntb290aChkYXRhPWNvdW50cmllc19hbmRfdXNfc3RhdGVzX2ZpcnN0MzBfY292YXJpYXRlcyAlPiUKICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihwcmVmZXJlZF9sYWJlbCAlaW4lIGMoIldhc2hpbmd0b24sIFVTIiwiVVMiLCJJdGFseSIsIkNoaW5hIikpLCAjIk5ldyBZb3JrLCBVUyIKICAgICAgICAgICAgICAgICAgICAgYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWRlYXRocywgY29sb3I9cHJlZmVyZWRfbGFiZWwpICwgbWV0aG9kID0gbG0sIHNlID0gRkFMU0UsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgCiAgCiAgICAgICBnZ2hpZ2hsaWdodChwcmVmZXJlZF9sYWJlbCAlaW4lIGMoIldhc2hpbmd0b24sIFVTIiwiSXRhbHkiLCJDaGluYSIsIlVTIikgLCAjIk5ldyBZb3JrLCBVUyIgIywgIlVTIgogICAgICAgICAgICAgICAgICAgIGxhYmVsX3BhcmFtcyA9CiAgICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgICAgICAgICAgc2VnbWVudC5hbHBoYT0wKQogICAgICAgICAgICAgICAgICApICsKICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsIDMwLCBieSA9IDUpKSArIAogICAgICAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBjb21tYV9mb3JtYXQoKSkgKyAKICAKICAgICAgIHhsYWIoIkRheXMgU2luY2UgMTAwIENvbmZpcm1lZCIpICsgCiAgICAgICB5bGFiKCJOdW1iZXIgb2YgRGVhdGhzIikgKwogICAgICAgdGhlbWVfYncoKQoKCnAyIDwtIHVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMCAlPiUgCiAgICAgICBnZ3Bsb3QoKSArIAogICAgICAgZ3VpZGVzKGNvbG9yPUZBTFNFKSArCiAgICAgICBnZW9tX2xpbmUoZGF0YT11c19hbmRfdXNfc3RhdGVzX2ZpcnN0MzAsIAogICAgICAgICAgICAgICAgYWVzKHg9ZGF5c19zaW5jZV8xMDBfY29uZmlybWVkLCB5PWRlYXRocywgY29sb3I9cHJlZmVyZWRfbGFiZWwgKSkgKwogICAgICAgI2dlb21fbGFiZWwoZGF0YT1jb3VudHJpZXNfYW5kX3VzX3N0YXRlc19maXJzdDMwLCAKICAgICAgICMgICAgICAgIGFlcyh4PWRheXNfc2luY2VfMTAwX2NvbmZpcm1lZCwgeT1kZWF0aHMsIGNvbG9yPXByZWZlcmVkX2xhYmVsICkpICU+JQogICAgICAgZ2VvbV9zbW9vdGgoZGF0YT11c19hbmRfdXNfc3RhdGVzX2ZpcnN0MzAgJT4lCiAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIocHJlZmVyZWRfbGFiZWwgJWluJSBjKCJXYXNoaW5ndG9uLCBVUyIsIlVTIiwiTmV3IFlvcmssIFVTIikpLCAjCiAgICAgICAgICAgICAgICAgICAgIGFlcyh4PWRheXNfc2luY2VfMTAwX2NvbmZpcm1lZCwgeT1kZWF0aHMsIGNvbG9yPXByZWZlcmVkX2xhYmVsKSAsIG1ldGhvZCA9IGxtLCBzZSA9IEZBTFNFLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArIAogIAogICAgICAgZ2doaWdobGlnaHQoI3ByZWZlcmVkX2xhYmVsICVpbiUgYygiV2FzaGluZ3RvbiwgVVMiLCJJdGFseSIsIkNoaW5hIikgLCAjIk5ldyBZb3JrLCBVUyIgIywgIlVTIgogICAgICAgICAgICAgICAgICAgIGxhYmVsX3BhcmFtcyA9CiAgICAgICAgICAgICAgICAgICAgICBsaXN0KAogICAgICAgICAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgICAgICAgICAgc2VnbWVudC5hbHBoYT0wKQogICAgICAgICAgICAgICAgICApICsKICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsIDMwLCBieSA9IDUpKSArIAogICAgICAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBjb21tYV9mb3JtYXQoKSkgKyAKICAKICAgICAgIHhsYWIoIkRheXMgU2luY2UgMTAwIENvbmZpcm1lZCIpICsgCiAgICAgICB5bGFiKCJOdW1iZXIgb2YgRGVhdGhzIikgKwogICAgICAgdGhlbWVfYncoKQoKCgoKYGBgCgoKYGBge3IsIGVjaG89RiwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9VCwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KCmxpYnJhcnkocGF0Y2h3b3JrKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCJwYXRjaHdvcmsiKQpwYXRjaHdvcmsgPC0gcDEgCnBhdGNod29yayArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdHcm93dGggUmF0ZSBpbiBDT1ZJRC0xOSBEZWF0aHMnLAogIHN1YnRpdGxlID0gIiIjLAogICNjYXB0aW9uID0gJycKKQoKYGBgCgoKQW5kIGhlcmUgaXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhdmVyYWdlIGdyb3d0aCByYXRlcyBpbiBkZWF0aHMgaW4gdGhlIGZpcnN0IDMwIGRheXMgYWNyb3NzIGNvdW50cmllcyBhbmQgVS5TLiBzdGF0ZXMuCgpgYGB7ciwgZWNobz1GLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzID1ULCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0xM30KCmxpYnJhcnkocGF0Y2h3b3JrKSA7ICNpbnN0YWxsLnBhY2thZ2VzKCJwYXRjaHdvcmsiKQpwYXRjaHdvcmsgPC0gcF9zbG9wZXNfY291bnRyaWVzX2FuZF91c19zdGF0ZXNfZmlyc3QzMApwYXRjaHdvcmsgKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAnTmF0aW9uYWwgR3Jvd3RoIFJhdGUgaW4gQ09WSUQtMTkgRGVhdGhzJywKICBzdWJ0aXRsZSA9ICIiIywKICAjY2FwdGlvbiA9ICcnCikKYGBgCgpJbiBhbnN3ZXIgdG8gdGhlIGZpcnN0IHF1ZXN0aW9uLCB0aGUgVS5TLiBncm93dGggcmF0ZSBpbiBkZWF0aHMgaXMgMjQuNDglIHdoaWNoIGlzIGFib3ZlIHRoZSBtZWRpYW4gYWNyb3NzIGNvdW50cmllcyAxOC44JS4gVGhlIFUuUy4gcmF0ZSBpcyBiZWxvdyBJdGFseSAoMjkuMzIlKSBhbmQgQ2hpbmEgKDI5LjU4JSksIGJ1dCBqdXN0IGJlbG93Ll5bVGhpcyBwbG90IGFuZCBzZW50ZW5jZSBhcmUgdGhlIG1vc3Qgc2Vuc2l0aXZlIHRvIG5ldyBpbmNvbWluZyBkYXRhIGJlY2F1c2UgdGhlIFUuUy4gaXMgc28gZWFybHkgaW4gaXRzIG91dGJyZWFrLiBCZXR3ZWVuIHJ1bnMsIHRoZSBVLlMuIGF2ZXJhZ2UgcmF0ZSBvZiBpbmNyZWFzZSBpbiBkZWF0aHMgaGFzIHJpc2VuIHNldmVyYWwgcGVyY2VudCB0byBhYm92ZSB0aGUgbWVkaWFuIGFuZCBjbG9zZXIgdG8gSXRhbHkgYW5kIENoaW5hLiBBIGZldyBjb3VudHJpZXMgd2l0aCBvbmx5IGEgZmV3IGRheXMgb2YgZGF0YSBoYXZlIHB1bGxlZCBiYWNrIGZyb20gb3V0bGllcnMgdG8gd2l0aGluIHRoZSByZXN0IG9mIHRoZSBkaXN0cmlidXRpb24uIFRoZSByZWFkZXIgaXMgZW5jb3VyYWdlZCB0byBydW4gdGhlIFIgY29kZSB0aGVtc2VsdmVzIGRvd25sb2FkYWJsZSBkaXJlY3RseSBmcm9tIHRoaXMgbm90ZWJvb2sgYW5kIHJlZ2VuZXJhdGUgdGhlIGZpZ3VyZXMgYmFzZWQgb24gdGhlIGxhdGVzdCBkYXRhLl0KCkluIGFuc3dlciB0byB0aGUgc2Vjb25kIHF1ZXN0aW9uLCBXYXNoaW5ndG9uIFN0YXRlIHdhcyBhbmQgY29udGludWVzIHRvIGJlIGFuIGV4YW1wbGUgb2YgbG93ZXIgZ3Jvd3RoIGluIGRlYXRoIHJhdGVzICgxMS43JSksIHdoaWNoIGF0IGhhbGYgb2YgdGhlIGF2ZXJhZ2UgVS5TLiByYXRlIGlzIG5vdCByZXByZXNlbnRhdGl2ZSBvZiB0aGUgY291bnRyeSBhcyBhIHdob2xlLl5bU29tZSBvZiB0aGVzZSBzdGF0ZXMgZW50ZXJlZCB0aGVpciBlcGlzb2RlIGFmdGVyIHRoZSBhcnRpY2xlIHdhcyBwb3N0ZWQgb24gTWFyY2ggMTZ0aC4gV2hlcmUgcG9zc2libGUgSSB3aWxsIHRyeSB0byBnaXZlIGxlZXdheSBpbiB0aGF0IHJlZ2FyZCwgYnV0IG9uIHRoZSBvdGhlciBoYW5kIG9uZSBvZiB0aGUgaW1tZWRpYXRlIGNvbnNlcXVlbmNlcyBvZiBjaGVycnkgcGlja2luZyBlYXJseSBkYXRhIGZyb20gb25lIHN0YXRlIGlzIHRoYXQgeW91J2xsIGJlIHNob3duIGltbWVkaWF0ZWx5IHdyb25nIHdoZW4gYSBmZXcgbW9yZSBkYXlzIG9mIGRhdGEgY29tZSBpbi5dCgpUaGUgRXBzdGVpbiBwaWVjZSBnb2VzIG9uIHRvIHNheQoKPiBUaGUgTmV3IFlvcmsgY2FzZXMgaGF2ZSBiZWVuIGlkZW50aWZpZWQgZm9yIGxvbmcgZW5vdWdoIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBwcm9kdWNlZCBtb3JlIGRlYXRocyBpZiB0aGUgY29yb25hdmlydXMgd2FzIGFzIGRhbmdlcm91cyBhcyBpcyBjb21tb25seSBiZWxpZXZlZC4KCkkgZG9uJ3QgZW50aXJlbHkga25vdyB3aGF0IHRoaXMgc2VudGVuY2UgaXMgc3VwcG9zZWQgdG8gbWVhbiwgYnV0IE5ldyBZb3JrJ3MgZGF5IG9uIGRheSBncm93dGggaW4gZmF0YWxpdGllcyBpcyB0aGUgc2Vjb25kIGhpZ2hlc3QgaW4gdGhlIHdvcmxkIGluIHRoZXNlIGRhdGEsIGp1c3QgYmVoaW5kIE1hc3NhY2h1c2V0dHMgYXQgNTIuMjglLgoKVGhlIGxlc3NvbiBoZXJlIGJlaW5nIHRoYXQgaW50ZW50aW9uYWxseSBsb29raW5nIGZvciBlYXJseSAiZ29vZCBuZXdzIiBtZWFucyBuZWNlc3NhcmlseSBpZ25vcmluZyBhY3R1YWwgbmV3cyByZWxldmFudCB0byB0aGUgcmVzZWFyY2ggcXVlc3Rpb24uXlsgTGVmdCBhcyBhbiBleGVyY2lzZSB0byB0aGUgcmVhZGVyIHRvIHNlZSBob3cgaGFyZCBleGFjdGx5IHlvdSBoYXZlIHRvIHNxdWludCBiZWZvcmUgeW91IHNlZSAiZ29vZCBuZXdzIiBmcm9tIHRoZXNlIGRhdGEuXQoKCmBgYHtyLCBldmFsPUYgLCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPVQsIHdhcm5pbmc9RkFMU0V9CgpwMiA8LSBzbG9wZXMgJT4lIGdncGxvdChhZXMoeD1lc3RpbWF0ZSkpICsgZ2VvbV9kZW5zaXR5KCkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdD1zbG9wZXMgJT4lIGZpbHRlcihjb3VudHJ5PT0iVVMiKSAlPiUgcHVsbChlc3RpbWF0ZSkgKSArIAogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IHNsb3BlcyAlPiUgZmlsdGVyKGNvdW50cnk9PSJVUyIpICU+JSBwdWxsKGVzdGltYXRlKSwgeSA9IDIuNSwgbGFiZWwgPSAiVS5TLiIsIGNvbG9yPSJibGFjayIsIHNpemU9Mi41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PXNsb3BlcyAlPiUgZmlsdGVyKGNvdW50cnk9PSJDaGluYSIpICU+JSBwdWxsKGVzdGltYXRlKSApICsgCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gc2xvcGVzICU+JSBmaWx0ZXIoY291bnRyeT09IkNoaW5hIikgJT4lIHB1bGwoZXN0aW1hdGUpLCB5ID0gMi41LCBsYWJlbCA9ICJDaGluYSIsIGNvbG9yPSJibGFjayIsIHNpemU9Mi41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PXNsb3BlcyAlPiUgZmlsdGVyKGNvdW50cnk9PSJJdGFseSIpICU+JSBwdWxsKGVzdGltYXRlKSApICsgCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gc2xvcGVzICU+JSBmaWx0ZXIoY291bnRyeT09Ikl0YWx5IikgJT4lIHB1bGwoZXN0aW1hdGUpLCB5ID0gMi41LCBsYWJlbCA9ICJJdGFseSIsIGNvbG9yPSJibGFjayIsIHNpemU9Mi41KSArCiAgeGxhYigiR3Jvd3RoIFJhdGVzIGluIERlYXRocyBvdmVyIGZpcnN0IDMwIGRheXMiKSArIHRoZW1lX2J3KCkgCgpgYGAKCmBgYHtyLCBldmFsPUYsIGVjaG89RiwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cyA9IFQsIHdhcm5pbmc9RkFMU0V9CgpsaWJyYXJ5KHBhdGNod29yaykgOyAjaW5zdGFsbC5wYWNrYWdlcygicGF0Y2h3b3JrIikKcGF0Y2h3b3JrIDwtIChwMiApIApwYXRjaHdvcmsgKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAnSXRhbHkgQ292aWQtMTkgQ29uZmlybWVkIGFuZCBEZWF0aHMnLAogIHN1YnRpdGxlID0gIiIsCiAgI2NhcHRpb24gPSAnJwopCgpgYGAKCiMgTGVzc29uIDY6IEJlIFNwZWNpZmljIGFuZCBDb25jcmV0ZSBBYm91dCBZb3VyIFRoZW9yeSAKClRvIHByb2NlZWQgZnVydGhlciwgd2UgbmVlZCB0byBhdHRlbXB0IHRvIGRpc3RpbGwgUmljaGFyZCBFcHN0ZWluJ3MgTW9kZWwgb2YgRXBpZGVtaW9sb2d5IGFuZCBEaXNlYXNlIChoZXJlIGFmdGVyIFJFTUVEKS4gR2V0dGluZyBSRU1FRCByZXF1aXJlcyBob2xkaW5nIHNldmVyYWwgc2ltcGxlIGJ1dCBjb250cmFkaWN0b3J5IGlkZWFzIGF0IHRoZSBzYW1lIHRpbWUuCgpUaGUgZmlyc3QgaWRlYSBpcyB0aGF0IHRoZSBvbmUgZnVsbCBjeWNsZSBvZiBDT1ZJRC0xOSBzcHJlYWQgYW5kIGRlY2xpbmUsIENoaW5hLCBpcyByZXByZXNlbnRhdGl2ZSBvZiBmdXR1cmUgaW5mbGVjdGlvbiBwb2ludHMgZm9yIG90aGVyIGNvdW50cmllcy4gT3ZlcmxheSB0aGUgQ2hpbmEgY3VydmUsIHRoZSBDaGluYSBjdXJ2ZSBicmVha3MsIHNvIGFub3RoZXIgY291bnRyeSdzIGN1cnZlIHNob3VsZCBicmVhayBzaW1pbGFybHkgdG9vLiAoKkNISU5BX0lORkxFQ1RJT04qKQoKPiBPdmVybG9va2VkIGlzIHRoZSBnb29kIG5ld3MgY29taW5nIG91dCBvZiBDaGluYSwgd2hlcmUgdGhlIGxhdGVzdCByZXBvcnQgc2hvd3MgMTYgbmV3IGNhc2VzIGFuZCAxNCBuZXcgZGVhdGhzLCBzdWdnZXN0aW5nIHRoYXQgdGhlIG51bWJlciBvZiBkZWF0aHMgaW4gdGhlIGN1cnJlbnRseSB1bnJlc29sdmVkIGdyb3VwIHdpbGwgYmUgbG93ZXIgdGhhbiB0aGUgNS4zIHBlcmNlbnQgY29udmVyc2lvbiByYXRlIGluIHRoZSBjYXNlcyByZXNvbHZlZCB0byBkYXRlLiBJbiBteSB2aWV3LCB3ZSB3aWxsIHNlZSBhIHNpbWlsYXIgZGVjbGluZSBpbiBJdGFseSwgZm9yIHJlYXNvbnMgdGhhdCBJIHNoYWxsIG91dGxpbmUgaW4gdGhlIHJlbWFpbmRlciBvZiB0aGlzIGFydGljbGUuCgo+IEluIGRlYWxpbmcgd2l0aCB0aGlzIHBvaW50LCBpdCBpcyBjcml0aWNhbCB0byBub3RlIHRoYXQgdGhlIHJhcGlkIGRlY2xpbmUgaW4gdGhlIGluY2lkZW5jZSBvZiBuZXcgY2FzZXMgYW5kIGRlYXRoIGluIENoaW5hIHN1Z2dlc3RzIHRoYXQgY2FzZXMgaW4gSXRhbHkgd2lsbCBub3QgY29udGludWUgdG8gcmlzZSBleHBvbmVudGlhbGx5IG92ZXIgdGhlIG5leHQgc2V2ZXJhbCB3ZWVrcy4KClRoZSBzZWNvbmQgaXMgdGhhdCwgaW4gY29udHJhc3QsIHRoZSBoaWdoIGRlYXRoIHJhdGUgb2YgQ2hpbmEgaXMgbm90IHJlcHJlc2VudGF0aXZlLCBpdCdzIGlkaW9zeW5jcmF0aWMgYW5kIG5vdCB3aGF0IHNob3VsZCBiZSBleHBlY3RlZCBpbiBvdGhlciBjb3VudHJpZXMgYmVjYXVzZSBvZiBpdHMgaGlnaCByYXRlIG9mIHNtb2tpbmcgYW5kIHBvbGx1dGlvbiAoKlNNT0tFUlMqLCAqUE9MTFVUSU9OKikuCgo+IE15IG93biBndWVzcyBpcyB0aGF0IHRoZSBwZXJjZW50YWdlIG9mIGRlYXRocyB3aWxsIGRlY2xpbmUgaW4gS29yZWEgZm9yIHRoZSBzYW1lIHJlYXNvbnMgdGhhdCB0aGV5IGFyZSBleHBlY3RlZCB0byBkZWNsaW5lIGluIHRoZSBVbml0ZWQgU3RhdGVzLiBJdCBpcyBoaWdobHkgdW5saWtlbHkgdGhhdCB0aGVyZSB3aWxsIGV2ZXIgYmUgYSByZXBldGl0aW9uIG9mIHRoZSBleHBsb3NpdmUgc2l0dWF0aW9uIGluIFd1aGFuLCB3aGVyZSBhaXIgcXVhbGl0eSBpcyBwb29yZXIgYW5kIHNtb2tpbmcgcmF0ZXMgYXJlIGhpZ2hlci4KCkl0YWx5J3MgZGVhdGggcmF0ZSBpcyBhbHNvIG5vdCByZXByZXNlbnRhdGl2ZSwgaXQncyBpZGlvc3luY3JhdGljIGFuZCBub3Qgd2hhdCBzaG91bGQgYmUgZXhwZWN0ZWQgaW4gb3RoZXIgY291bnRyaWVzLiAoKklUQUxZKileW1RoZSBpbXBsaWVkIHZhcmlhYmxlIGlzIHVua25vd24gYmVjYXVzZSBuZWl0aGVyIHRoZSBzZW50ZW5jZSBub3IgbGlua2VkIE5ZVCBhcnRpY2xlIHByb3ZpZGVzIGFuIGFyZ3VtZW50IGZvciB3aHkgdGhlIFUuUy4gaGVhbHRoIHN5c3RlbSBpcyBkaWZmZXJlbnQgb3Igc2hvdWxkIHBlcmZvcm0gYmV0dGVyIHRoYW4gdGhlIEl0YWxpYW4gaGVhbHRoIHN5c3RlbS4gVGhlIGltcGxpZWQgdGhlb3JldGljYWwgdmFyaWFibGUgcmVtYWlucyBhIG15c3RlcnkuIGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDIwMDMxOTE5MTA0OS9odHRwczovL3d3dy5ueXRpbWVzLmNvbS8yMDIwLzAzLzEyL3dvcmxkL2V1cm9wZS8xMml0YWx5LWNvcm9uYXZpcnVzLWhlYWx0aC1jYXJlLmh0bWxdCgo+IE1vcmVvdmVyLCBpdCBpcyB1bmxpa2VseSB0aGF0IHRoZSBoZWFsdGhjYXJlIHN5c3RlbSBpbiB0aGUgVW5pdGVkIFN0YXRlcyB3aWxsIGJlIGNvbXByb21pc2VkIGluIHRoZSBzYW1lIGZhc2hpb24gYXMgdGhlIEl0YWxpYW4gaGVhbHRoY2FyZSBzeXN0ZW0gaW4gdGhlIHdha2Ugb2YgaXRzIHF1aWNrIHZpcmFsIHNwcmVhZC4KClRoZSB0aGlyZCBpZGVhIGlzIHRoYXQgQ2hpbmEncyBoZWF2eS1oYW5kZWQgcG9saWN5IHJlc3BvbnNlIGlzIG5vdCB3aHkgaXRzIGdyb3d0aCBjdXJ2ZSBpbiBkZWF0aHMgYnJva2UsIGFuZCBwcmVzdW1hYmx5IG5laXRoZXIgd2lsbCBJdGFseSdzIGhlYXZ5IGhhbmRlZCBwb2xpY3kgcmVzcG9uc2UgYmUgcmVzcG9uc2libGUgd2hlbiBpdCBicmVha3MgYXMgd2VsbC4gVGhlcmVmb3JlIGhlIGFyZ3VlcywgdGhlIFUuUy4gc2hvdWxkIG5vdCBjb3B5IHRoZW0uICgqUE9MSUNZKikKCj4gQXMgb2YgTWFyY2ggMTYsIHRoZSBkYXRhIGZyb20gdGhlIFVuaXRlZCBTdGF0ZXMgZmFsbHMgc2hvcnQgb2YganVzdGlmeWluZyB0aGUgZHJhY29uaWFuIG1lYXN1cmVzIHRoYXQgYXJlIG5vdyBiZWluZyBpbXBsZW1lbnRlZC4gQXMgb2YgdHdvIGRheXMgYWdvLCAzOSBzdGF0ZXMgaGF2ZSBkZWNsYXJlZCBzdGF0ZXMgb2YgZW1lcmdlbmN5LCBhbmQgdGhleSBoYXZlIGJlZW4gam9pbmVkIGF0IHRoZSBmZWRlcmFsIGxldmVsIHdpdGggUHJlc2lkZW50IFRydW1w4oCZcyByZWNlbnQgZGVjbGFyYXRpb24gdG8gdGhlIHNhbWUgZWZmZWN0LiBUaGVzZSBkZWNsYXJhdGlvbnMgYXJlIG1lYW50IHRvIGVuZG93IGdvdmVybm1lbnRzIHdpdGggdGhlIHBvd2VyIHRvIGltcG9zZSBxdWFyYW50aW5lcyBhbmQgdHJhdmVsIGJhbnMsIGNsb3NlIHNjaG9vbHMsIHJlc3RyaWN0IHB1YmxpYyBnYXRoZXJpbmdzLCBzaHV0IGRvd24gbWFqb3Igc3BvcnRpbmcgZXZlbnRzLCBzdG9wIHB1YmxpYyBtZWV0aW5ncywgYW5kIGNsb3NlIHJlc3RhdXJhbnRzIGFuZCBiYXJzLiBQcml2YXRlIGluc3RpdHV0aW9ucyBhcmUgaW1wb3Npbmcgc2ltaWxhciByZXN0cmljdGlvbnMuIFRoZSBvbmUtdHdvIHB1bmNoIG9mIHB1YmxpYyBhbmQgcHJpdmF0ZSByZXN0cmljdGlvbnMgaGFzIGNhdXNlZCBhIGh1Z2Ugam9sdCB0byB0aGUgZWNvbm9teS4KCj4gVGhlIGlyb255IGhlcmUgaXMgdGhhdCBldmVuIHRob3VnaCBzZWxmLWhlbHAgbWVhc3VyZXMgbGlrZSBhdm9pZGluZyBjcm93ZGVkIHNwYWNlcyBtYWtlIGFidW5kYW50IHNlbnNlLCB0aGUgbWFzc2l2ZSBwdWJsaWMgY29udHJvbHMgZG8gbm90LiBJbiBsaWdodCBvZiB0aGUgYXZhaWxhYmxlIHJhdyBkYXRhLCBwdWJsaWMgb2ZmaWNpYWxzIGhhdmUgZ29uZSBvdmVyYm9hcmQuIAoKPiBNeSBvd24gZ3Vlc3MgaXMgdGhhdCB0aGUgcGVyY2VudGFnZSBvZiBkZWF0aHMgd2lsbCBkZWNsaW5lIGluIEtvcmVhIGZvciB0aGUgc2FtZSByZWFzb25zIHRoYXQgdGhleSBhcmUgZXhwZWN0ZWQgdG8gZGVjbGluZSBpbiB0aGUgVW5pdGVkIFN0YXRlcy4KCkRlc3BpdGUgc2F5aW5nIG11bHRpcGxlIHRpbWVzIGVsc2V3aGVyZSBwb2xpY3kgZG9lcyBoYXZlIGFuIGluZGVwZW5kZW50IGVmZmVjdAoKPiBWYXJpb3VzIGluc3RpdHV0aW9uYWwgbWVhc3VyZXMsIGJvdGggcHJpdmF0ZSBhbmQgcHVibGljLCBoYXZlIGFsc28gc2xvd2VkIGRvd24gdGhlIHRyYW5zbWlzc2lvbiByYXRlLgoKPiBUaGUgYW1vdW50IG9mIHZvbHVudGFyeSBhbmQgZm9yY2VkIHNlcGFyYXRpb24gaW4gdGhlIFVuaXRlZCBTdGF0ZXMgaGFzIGdvdHRlbiB2ZXJ5IGV4dGVuc2l2ZSB2ZXJ5IHF1aWNrbHksIHdoaWNoIHNob3VsZCBpbmZsdWVuY2UgcmF0ZXMgb2YgaW5mZWN0aW9uIHNvb25lciByYXRoZXIgdGhhbiBsYXRlci4KClRoZSBmb3VydGggaWRlYSBpcyB0aGUgZ3Jvd3RoIGFuZCBkZWNsaW5lIGN1cnZlcyBvZiBDT1ZJRC0xOSBhcmUgYSBmdW5jdGlvbiBvZiB0aW1lLCBhbmQgbmF0dXJhbGx5IHdpbGwgYnVybiBpdHNlbGYgb3V0IGJlY2F1c2Ugb2YgCgpBKSBTb2NpZXRhbCBSZXNwb25zZSAoKkFEQVBUQVRJT04qKQoKPiBCdXQgb25jZSBwZW9wbGUgYXJlIGF3YXJlIG9mIHRoZSBkaXNlYXNlLCB0aGV5IHdpbGwgc3RhcnQgdG8gbWFrZSBwb3dlcmZ1bCBhZGFwdGl2ZSByZXNwb25zZXMsIGluY2x1ZGluZyB3YXNoaW5nIHRoZWlyIGhhbmRzIGFuZCBrZWVwaW5nIHRoZWlyIGRpc3RhbmNlIGZyb20gcGVvcGxlIGtub3duIG9yIGxpa2VseSB0byBiZSBjYXJyeWluZyB0aGUgaW5mZWN0aW9uLiBWYXJpb3VzIGluc3RpdHV0aW9uYWwgbWVhc3VyZXMsIGJvdGggcHJpdmF0ZSBhbmQgcHVibGljLCBoYXZlIGFsc28gc2xvd2VkIGRvd24gdGhlIHRyYW5zbWlzc2lvbiByYXRlLgoKQikgU2Vhc29uYWxpdHkgKCpTRUFTT05BTElUWSopCgo+IEFuZCBmaW5hbGx5LCB0aGUgbW9kZWwgZXhwbGljaXRseSBpZ25vcmVzIHRoZSBwb3NzaWJpbGl0eSB0aGF0IHRoZSB0b3RhbHMgd2lsbCBkZWNsaW5lIGFzIHRoZSB3ZWF0aGVyIGdldHMgd2FybWVyLgoKQykgTmF0dXJhbCBzZWxlY3Rpb24gd2lsbCBicmVlZCB3ZWFrZXIgQ09WSUQtMTkgKCpXRUFLRU5JTkcqKV5bSSBkZWZlciB0byBhY3R1YWwgZXBpZGVtaW9sb2dpc3RzIHRvIHRhY2tsZSB0aGlzIGlkZWEuIE15IGN1cnJlbnQgdW5kZXJzdGFuZGluZyBpcyB0aGF0IENPVklELTE5IGlzIGFzeW1wdG9tYXRpYyBpbiBhcyBtYW55IGFzIDgwJSBvZiBjYXNlcywgaXQncyBub3Qga2lsbGluZyB0aG9zZSBob3N0cyBiZWZvcmUgaXQgc3ByZWFkcy4gSXQncyBhbHNvIGNvbW11bmljYWJsZSB1cCB0byBhIGNvdXBsZSBvZiBkYXlzIGJlZm9yZSBzeW1wdG9tcyBkbyBlbWVyZ2UgaW4gdGhvc2Ugd2hvIGFyZSBzeW1wdG9tYXRpYywgaXQncyBzcHJlYWRpbmcgYmVmb3JlIGtpbGxpbmcgdGhvc2UgaG9zdHMgYXMgd2VsbC4gQW5kIHRoZSBwZW9wbGUgd2hvIGl0IGlzIGtpbGxpbmcgYXJlIGhlYWRpbmcgdG8gaG9zcGl0YWxzIGZpcnN0LCB3aGVyZSBpdCdzIGJlaW5nIHRyYW5zbWl0dGVkIHRvIGhlYWx0aGNhcmUgd29ya2VycyBhdCBhbGFybWluZyByYXRlcy4gVGhpcyBzdHJpa2VzIG1lIGFzIGEgYmFzaWMgbGFjayBvZiB1bmRlcnN0YW5kaW5nIGFib3V0IGhvdyBmaXRuZXNzIGNvbnN0cmFpbnRzIGVuY291cmFnZSBjaGFuZ2UgaW4gYWdlbnRzIG92ZXIgdGltZS4gQmFua2luZyBvbiBpdCB0byBvY2N1ciBpbiBhIHRpbWVsaW5lIHNvb24gZW5vdWdoIHRvIGF2b2lkIGEgcGVhayBpbiBjYXNlcyBpbiB0aGUgVS5TLiwgd2l0aG91dCBjaXRpbmcgYSBzaW5nbGUgZW1waXJpY2FsIHdvcmssIGlzIHdpbGxmdWxseSBpZ25vcmFudC5dCgo+QXQgc29tZSB0aXBwaW5nIHBvaW50LCB0aGUgbW9zdCB2aXJ1bGVudCB2aXJ1c2VzIHdpbGwgYmUgbW9yZSBsaWtlbHkgdG8ga2lsbCB0aGVpciBob3N0cyBiZWZvcmUgdGhlIHZpcnVzIGNhbiBzcHJlYWQuIEluIGNvbnRyYXN0LCB0aGUgbWlsZGVyIHZlcnNpb25zIG9mIHRoZSB2aXJ1cyB3aWxsIHdyZWFrIGxlc3MgZGFtYWdlIHRvIHRoZWlyIGhvc3QgYW5kIHRodXMgd2lsbCBzdXJ2aXZlIG92ZXIgdGhlIGxvbmdlciB0aW1lIHNwYW4gbmVlZGVkIHRvIHNwcmVhZCBmcm9tIG9uZSBwZXJzb24gdG8gYW5vdGhlci4gSGVuY2UgdGhlIHJhdGUgb2YgdHJhbnNtaXNzaW9uIHdpbGwgdHJlbmQgZG93bndhcmQsIGFzIHdpbGwgdGhlIHNldmVyaXR5IG9mIHRoZSB2aXJ1cy4gSXQgaXMgYSBmb3JtIG9mIG5hdHVyYWwgc2VsZWN0aW9uLgoKPiBHaXZlbiB0aGF0IHRoZSBjb3JvbmF2aXJ1cyBjYW4gc3ByZWFkIHRocm91Z2ggZHJvcGxldHMgYW5kIGNvbnRhY3QsIHRoZSBjb25zZXF1ZW5jZXMgb2Ygc2VsZWN0aW9uIHNob3VsZCBtYW5pZmVzdCB0aGVtc2VsdmVzIG1vcmUgcXVpY2tseSB0aGFuIHRoZXkgZGlkIGZvciBBSURTLgoKRCkgTmF0dXJhbCBzZWxlY3Rpb24gd2lsbCByZW1vdmUgd2Vha2VyIGh1bWFucyAoKlNVU0NFUFRJQkxFKikKCj4gTm9yIGRvZXMgdGhlIG1vZGVsIHJlY29nbml6ZSB0aGF0IGlmIHRoZSBtb3N0IHZ1bG5lcmFibGUgcGVvcGxlIGFyZSBoaXQgZmlyc3QsIHN1YnNlcXVlbnQgaXRlcmF0aW9ucyB3aWxsIGJlIHNsb3dlciBiZWNhdXNlIHRoZSByZW1haW5pbmcgcG9vbCBvZiBpbmRpdmlkdWFscyBpcyBtb3JlIHJlc2lzdGFudCB0byBpbmZlY3Rpb24uCgoqKlN1bW1hcnkqKgoKVG8gZ2V0IFJFTUVEIG1lYW5zIHRvIGJlbGlldmUgdGhhdDogCgoqIE9uZSBjYXNlLCBDaGluYSwgcHJlZGljdHMgZnV0dXJlIHRyZW5kcyBpbiBDT1ZJRC0xOSBjYXNlcyBpbiB0aGUgVS5TLiBhbmQgZWxzZXdoZXJlLgoKKiBCdXQgbmVpdGhlciBDaGluYSBub3IgSXRhbHkgcHJlZGljdHMgZnV0dXJlIGxldmVscyBvZiBkZWF0aHMgaW4gdGhlIFUuUy4gYW5kIGVsc2V3aGVyZS4gCgoqIEFuZCBzaW11bHRhbmVvdXNseSwgdGhlIG1lY2hhbmlzbSBiZWhpbmQgdGhlIHRyZW5kIGluIENoaW5hIHdhcyBtb3JlIG5hdHVyZSB0aGFuIHBvbGljeS4gCgoqIFNvIHRoZSBVLlMuIGNhbiBhdm9pZCBlbmFjdGluZyB0aG9zZSBwb2xpY2llcyBhbmQgc3RpbGwgZXhwZWN0IHRvIHNlZSB0aGUgc2FtZSBkcm9wIGluIGNhc2VzLgoKTGV0IHRoYXQgc2luayBpbi4KCiMgTGVzc29uIDc6IENob29zZSBFbm91Z2ggQ2FzZXMgdG8gQWN0dWFsbHkgVGVzdCBZb3VyIFRoZW9yeQoKV2UgY2FuIGZvcm1hbGl6ZSBSRU1FRCBhcyBhIHNlcmllcyBvZiBlcXVhdGlvbnMKClRoZSByYXRlIG9mIGRlYXRocyBhdCB0aW1lIHQgaXMgYSBmdW5jdGlvbiBvZiB0aGUgZGlzdGFuY2UgYmVmb3JlIG9yIGFmdGVyIHdoZW4gQ2hpbmEncyBpbmZsZWN0aW9uIHRvb2sgcGxhY2UsIHRoZSBkZWdyZWUgb2Ygc29jaWV0YWwgYWRhcHRhdGlvbiwgaG93IG11Y2ggdGhlIGRpc2Vhc2UgaGFzIGV2b2x2ZWQgdG8gYmVjb21lIGxlc3MgZGVhZGx5LCB0aGUgbnVtYmVyIG9mIHN1Y2VwdGlibGUgcGVvcGxlIHN0aWxsIGxlZnQgaW4gdGhlIHBvcHVsYXRpb24sIGFuZCB0aGUgc2Vhc29uLgoKJFxwYXJ0aWFsIERFQVRIU190ID1GKENISU5BSU5GTEVDVElPTiwgQURBUFRBVElPTixXRUFLRU5JTkcsU1VTQ0VQVElCTEUsU0VBU09OQUxJVFksIFRpbWUpJAoKVGhlIHRvdGFsIG51bWJlciBvZiBleHBlY3RlZCBERUFUSFMgaW4gY291bnRyeSBjLCBob3dldmVyLCBpcyBqdXN0IGEgZnVuY3Rpb24gb2YgdGhlIHBvbGljeSBjaG9zZW4sIHNtb2tpbmcgcG9wdWxhdGlvbiwgcG9sbHV0aW9uLCBhbmQgd2hldGhlciBvciBub3QgeW91IGFyZSB0aGUgY291bnRyeSBvZiBJdGFseS4KCiRERUFUSFNfYz1GKFBvbGljeSwgU21va2VycywgUG9sbHV0aW9uLCBJdGFseSkkCgpBbG1vc3QgYWxsIHNvY2lhbCBzY2llbmNlcyBncmFkIHN0dWRlbnRzIHdpbGwgYmUgZm9yY2VkIHRvIHJlYWQgW0tpbmcsIEtlb2hhbmUsIGFuZCBWZXJiYSAoMTk5NyldKGh0dHBzOi8vcHJlc3MucHJpbmNldG9uLmVkdS9ib29rcy9wYXBlcmJhY2svOTc4MDY5MTAzNDcxMy9kZXNpZ25pbmctc29jaWFsLWlucXVpcnkpIG9yIHNvbWV0aGluZyBzaW1pbGFyIGluIHRoZWlyIGZpcnN0IHllYXIgd2hpY2ggZGV0YWlscyBob3cgdG8gZG8gc21hbGwgbiBjYXNlIHNlbGVjdGlvbiB3aXRoIGFuIGV5ZSB0b3dhcmQgaGF2aW5nIGVub3VnaCBjYXNlcyBhbmQgdGhlIHJpZ2h0IGNhc2VzIHRvIHRlc3QgeW91ciBleHBsYW5hdGlvbnMuIFdlIGNhbiBleHByZXNzIHRoaXMgZGlyZWN0bHkgYnkgY29kaW5nIHRoZSBhdmFpbGFibGUgY2FzZXMgYW5kIHB1dHRpbmcgdGhlbSBpbnRvIGEgdGFibGUuXltTbW9raW5nIGNvZGVkIGFzIGNpZ2FyZXR0ZSBjb25zdW1wdGlvbiBwZXIgcGVyc29uIHBlciB5ZWFyIGZyb20gV2lraXBlZGlhLCBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX2NvdW50cmllc19ieV9jaWdhcmV0dGVfY29uc3VtcHRpb25fcGVyX2NhcGl0YSBdCgpgYGB7ciwgZXZhbD1ULCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSBGLCB3YXJuaW5nPUZBTFNFfQoKI2luc3RhbGwucGFja2FnZXMoJ2RhdGFwYXN0YScpCmxpYnJhcnkoZGF0YXBhc3RhKQp4IDwtIGRhdGEuZnJhbWUoCiAgQ291bnRyeT1jKCdDaGluYScsJ0l0YWx5JywnVS5TLicpLAogIERlYXRocz1jKCczLDI5NicsJzksMTM0KicsJzEsNDc1KicpLAogIFBvbGljeT1jKCdTaGVsdGVyIGluIFBsYWNlJywnU2hlbHRlciBpbiBQbGFjZScsJ1NoZWx0ZXIgaW4gUGxhY2UnKSwKICBQb2xsdXRpb249YygnSGlnaCcsJ0xvdycsJ0xvdycpLAogIFNtb2tpbmc9YygnMjA0MycsJzE0OTMuMycsJzEwMTYuNicpLAogIEl0YWx5PWMoJ05vJywnWWVzJywnTm8nKQopCgpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpOyAjaW5zdGFsbC5wYWNrYWdlcygna2FibGVFeHRyYScpCgpgYGAKCmBgYHtyLCBldmFsPVQsIGVjaG89RiwgbWVzc2FnZT1GLCByZXN1bHRzID0gVCwgd2FybmluZz1GQUxTRX0KeCAlPiUKICBrYWJsZSgpICU+JQogIGthYmxlX3N0eWxpbmcoKQoKYGBgCgpBIG51bWJlciBvZiBwcm9ibGVtcyBzaG91bGQgYmVjb21lIGltbWVkaWF0ZWx5IGFwcGFyZW50LiBGaXJzdCwgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgd2l0aCBhIGZpbmFsIGVwaXNvZGUgY291bnQgb2YgZGVhdGhzIGlzIGp1c3QgMSwgQ2hpbmEuIEJvdGggSXRhbHkgYW5kIHRoZSBVLlMuIHN0aWxsIHNob3cgYW4gaW5jcmVhc2luZyBjb3VudC4gRnVydGhlciwgd2UgaGF2ZSA0IGRpZmZlcmVudCBleHBsYW5hdGlvbnMgdG8gdGVzdCBidXQgb25seSAxIG9yIGF0IG1vc3QgMiBkYXRhIHBvaW50cy4gV2UgZG9uJ3QgaGF2ZSBlbm91Z2ggZGVncmVlcyBvZiBmcmVlZG9tIHRvIG1hdGhlbWF0aWNhbGx5IGRlbW9uc3RyYXRlIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gdG90YWwgZGVhdGhzIGFuZCBldmVyeSBvbmUgb2YgdGhlc2UgZXhwbGFuYXRpb25zLgoKU2Vjb25kLCB3ZSBkb24ndCBoYXZlIGFueSB2YXJpYXRpb24gb24gdGhlIGRlcGVuZGVudCB2YXJpYWJsZSwgYm90aCBJdGFseSBhbmQgQ2hpbmEgaGF2ZSBhIGhpZ2ggZGVhdGggdG9sbC5eW1doYXQgY291bnRzIGFzIGxvdyBpcyBhIG1vdmluZyB0YXJnZXQgYmVjYXVzZSB0aGUgb3JpZ2luYWwgcGllY2UgcHJlZGljdGVkIG9ubHkgNTAwIGZvciB0aGUgVS5TLiBhbmQgc2FpZCBpdCB3YXNuJ3QgbGlrZWx5IHRvIHJlYWNoIHRoZSBoaWdoIG51bWJlciBvZiBDaGluYSdzIGJlY2F1c2UgQ2hpbmEgaGFkIG1vcmUgc21va2Vycy4gTm93IEl0YWx5J3MgaGlnaCBkZWF0aCBjb3VudCBpcyB0aGUgbmV3IGhpZ2guIEJ1dCBoZSBmb3JlY2FzdHMgNSwwMDAgZm9yIHRoZSBVLlMuIHdoaWNoIHdvdWxkIHRoZW4gbWFrZSBpdCB0aGUgbmV3IGhpZ2guIEJ1dCB0aGlzIGlzIGNvbnRyYXN0IHRvIHRoZSBOWVQgZXN0aW1hdGUgb2YgYSBtaWxsaW9uLCBzbyBtYXliZSB0aGVzZSBhcmUgYWxsIHJlYWxseSBsb3cuIEluIGVpdGhlciBjYXNlLCB0aGVyZSdzIHN0aWxsIG5vIHZhcmlhdGlvbiBvbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLiBdIFRoZSBzYW1wbGUgZG9lcyBub3QgaW5jbHVkZSBhbnkgZXhhbXBsZXMgb2YgbG93IGRlYXRoIHRvbGwgY291bnRyaWVzIGZvciB1cyB0byBpbmZlciBmcm9tLgoKVGhpcmQsIHdlIGRvbid0IGhhdmUgdmFyaWF0aW9uIG9uIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZSBvZiBpbnRlcmVzdCwgcG9saWN5LCBlaXRoZXIuIEFsbCB0aHJlZSBvZiB0aGVzZSBjb3VudHJpZXMgaGF2ZSBzaGVsdGVyIGluIHBsYWNlIHN0eWxlIHBvbGljaWVzIG9mIG9uZSBmb3JtIG9yIGFub3RoZXIuIEFuZCwgYm90aCBDaGluYSdzIGFuZCBJdGFseSdzIGFyZSBtb3JlIGV4dHJlbWUsIG5vdCBsZXNzLCB0aGFuIHRoZSBVLlMuIHNvIGZhci4KCldlIGNvdWxkIHN0YXJ0IHRvIGltcHJvdmUgb24gdGhpcy4gRmlyc3QsIGNvbGxhcHNlIHNtb2tpbmcgYW5kIHBvbGx1dGlvbiBpbnRvIGEgc2luZ2xlIGx1bmcgaGVhbHRoIGluZGV4LCBvciBmb3IgY29udmVuaWVuY2UgY2hvb3NlIGp1c3Qgc21va2luZy4gU2Vjb25kLCBkcm9wIHRoZSBpZGlvc3luY3JhdGljIGV4cGxhbmF0aW9uIGZvciBJdGFseSBqdXN0IGJlaW5nIGRpZmZlcmVudCBzb21laG93LiBUaGlyZCwgZXhwYW5kIHRoZSBzYW1wbGUgb2YgY2FzZXMgdG8gaW5jbHVkZSB2YXJpYXRpb24gb24gYm90aCB0aGUgZGVwZW5kZW50IEFORCBpbmRlcGVuZGVudCB2YXJpYWJsZS4gVGhhdCBpcywgd2UgbmVlZCBleGFtcGxlcyBvZiBjb3VudHJpZXMgd2l0aCBsb3cgZGVhdGggdG90YWxzLiBXZSBhbHNvIG5lZWQgZXhhbXBsZXMgb2YgY291bnRyaWVzIHdpdGggbm8gc2hlbHRlciBpbiBwbGFjZS4gSGVyZSdzIHdoYXQgdGhhdCBsb29rcyBsaWtlIGZvciB0aGUgc2V0IG9mIGNvdW50cmllcyB0aGF0IGhhdmUgbWFkZSBpdCB0byAzMCBkYXlzIHNpbmNlIDEwMCBjb25maXJtZWQgY2FzZXMuCgpgYGB7ciwgZXZhbD1ULCBlY2hvPUYsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHMgPSBGLCB3YXJuaW5nPUZBTFNFfQoKdGVtcCA8LSBjb3VudHJpZXNfbG9uZyAlPiUgZHBseXI6OmZpbHRlcighaXMubmEoZGVhdGhzKSAmICFpcy5uYShjb25maXJtZWQpICkgJT4lIGZpbHRlcihkYXlzX3NpbmNlXzEwMF9jb25maXJtZWQ9PTMwKQoKbGlicmFyeShkYXRhcGFzdGEpCngyIDwtIGRhdGEuZnJhbWUoCiAgQ291bnRyeT1jKCdVLlMuJywgJ0l0YWx5JywgJ0lyYW4nLCdDaGluYScsICJTb3V0aCBLb3JlYSIsIkphcGFuIiksCiAgRGVhdGhzX2F0XzMwX0RheXM9YygnPycsICc2MDc3JywnMjIzNCcsJzE3NjYnLCc5NCcsJzM1JyksCiAgU2hlbHRlcl9Jbl9QbGFjZT1jKCdZZXMnLCdZZXMnLCdObycsJ1llcycsJ05vJywnTm8nKSwKICBTbW9raW5nPWMoJzEsMDE2LjYnLCcxNDkzLjMnLCc5MzYuNScsIjIsMDQzIiwiMSw2NjciLCIxLDU4MyIpCikKCmBgYAoKYGBge3IsIGV2YWw9VCwgZWNobz1GLCBtZXNzYWdlPUYsIHJlc3VsdHMgPSBULCB3YXJuaW5nPUZBTFNFfQp4MiAlPiUKICBrYWJsZSgpICU+JQogIGthYmxlX3N0eWxpbmcoKQoKYGBgCgpTbW9raW5nIG5vIGxvbmdlciBzZWVtcyB0byBleHBsYWluIENoaW5hJ3MgaGlnaCBkZWF0aHMsIElyYW4gaGFzIGxlc3Mgc21va2luZyBidXQgYSBoaWdoIGRlYXRoIGNvdW50LCBhbmQgU291dGggS29yZWEgYW5kIEphcGFuIGJvdGggaGF2ZSBoaWdoIHNtb2tpbmcgYnV0IGEgbG93IGRlYXRoIGNvdW50LgoKTGlrZXdpc2UsIHR3byBvZiB0aGUgaGlnaCBkZWF0aCByYXRlIGNvdW50cmllcywgSXRhbHkgYW5kIENoaW5hLCBoYXZlIGEgc2hlbHRlciBpbiBwbGFjZSBwb2xpY3ksIGJ1dCB0aGUgdGhpcmQgSXJhbiBkb2VzIG5vdC4gTmVpdGhlciBvZiB0aGUgbG93IGRlYXRoIHJhdGUgY291bnRyaWVzIFNvdXRoIEtvcmVhIGFuZCBKYXBhbiBoYXZlIGEgc2hlbHRlciBpbiBwbGFjZSBwb2xpY3kuIEphcGFuJ3Mgc2xvdyBidXQgaW5jcmVhc2luZyBncm93dGggcmF0ZSByZW1haW5zIGEgbXlzdGVyeSBidXQgbWlnaHQgc2ltcGx5IGJlIG9uIGEgZGVsYXllZCBzbG9wZS4KClRoaXMgc3RyZXNzZXMgdGhlIGxpbWl0cyBvZiB0aGlzIGtpbmQgb2Ygc2ltcGxlIHBhdHRlcm4gbWF0Y2hpbmcgZXhlcmNpc2UuIEhpZ2ggZGVhdGggcmF0ZXMgYWxzbyBjYXVzZSBzaGVsdGVyIGluIHBsYWNlIHBvbGljaWVzLiBTb3V0aCBLb3JlYSB3aGljaCBwdXJzdWVkIGVhcmx5IHNvcGhpc3RpY2F0ZWQgY29udGFpbm1lbnQgd2FzIGFibGUgdG8gZm9yZ28gdGhlIG5lZWQgdG8gc3dpdGNoIHRvIGEgZGVsYXkgcG9saWN5LiBBIHNpbXBsZSBjcm9zcy1zZWN0aW9uYWwgY29tcGFyaXNvbiBvZiBjb3VudHJpZXMgaXNuJ3Qgc3VmZmljaWVudCB0byB0ZWxsIHVzIHdoZXRoZXIgYSBzaGVsdGVyIGluIHBsYWNlIHBvbGljeSB3b3JrZWQuIAoKSW4gc3VtLCBjcm9zcy1uYXRpb25hbCBhbmFsb2dpZXMgYXJlIGluc3VmZmljaWVudCB0byBhbnN3ZXIgdGhpcyByZXNlYXJjaCBxdWVzdGlvbi4gV2hhdCB3ZSBuZWVkIGFyZSB0aGUgZmluZSBncmFpbmVkIHRpbWUtc2VyaWVzIGNyb3NzLXNlY3Rpb25hbCBkYXRhIGFuZCBzaW11bGF0aW9ucyB0aGF0IGVtcGlkaW1pb2xvZ2lzdHMgYXJlIHVzaW5nIHRvIGNvbnN0cnVjdCBjb25jcmV0ZSBjb3VudGVyZmFjdHVhbHMgdG8gZ3VpZGUgcG9saWN5IG1ha2Vycy4KCiMgTGVzc29uIDg6IENvbnZleSBVbmNlcnRhaW50eSB3aXRoIFNwZWNpZmljaXR5IG5vdCBEb3VibGVzcGVhawoKVGhlIEVwc3RlaW4gcGllY2UgcHJlc2VudHMgaXRzZWxmIGFzIGlmIGl0cyBjb21tdW5pY2F0aW5nIGNvbmZpZGVuY2UgYW5kIHVuY2VydGFpbnR5LCBlLmcuIHVzaW5nIHRoZSB3b3JkcyBsaWtlbHkvdW5saWtlbHkvcHJvYmFibGUvZ3Vlc3MgOSB0aW1lcy4gVGhlcmUgYXJlIG1hdGhlbWF0aWNhbCB3YXlzIG9mIGV4cGxpY2l0bHkgY29tbXVuaWNhdGluZyB1bmNlcnRhaW50eSwgYW5kIHdoZXJlIHRoYXQgdW5jZXJ0YWludHkgbGllcyBpbiBtZWFzdXJlbWVudCwgcGFyYW1ldGVyLCBvciBwcmVkaWN0aW9uLiBUaGVyZSBhcmUgZXZlbiB3YXlzIG9mIGNvbW11bmljYXRpbmcgdW5jZXJ0YWludHkgdG8gYSBxdWFsaXRhdGl2ZSBhdWRpZW5jZSwgZS5nLiB0aGUgQ0lBJ3MgW2Rlc3BlcmF0ZSBtYXBwaW5nXShodHRwczovL3d3dy5jaWEuZ292L2xpYnJhcnkvY2VudGVyLWZvci10aGUtc3R1ZHktb2YtaW50ZWxsaWdlbmNlL2NzaS1wdWJsaWNhdGlvbnMvYm9va3MtYW5kLW1vbm9ncmFwaHMvc2hlcm1hbi1rZW50LWFuZC10aGUtYm9hcmQtb2YtbmF0aW9uYWwtZXN0aW1hdGVzLWNvbGxlY3RlZC1lc3NheXMvNndvcmRzLmh0bWwpIGZyb20gcHJvYmFiaWxpdGllcyB0byBhZGplY3RpdmVzIGZvciBsYXkgcG9saWN5bWFrZXJzLiAKClRoZXJlIGlzIGFsc28gYSB3cm9uZyB3YXkgdG8gY29udmV5IHVuY2VydGFpbnR5IHdoaWNoIGlzIHRvIHBlcHBlciB5b3VyIGxhbmd1YWdlIHdpdGggY29udHJhZGljdG9yeSBoZWRnaW5nIGFuZCBkb3VibGVzcGVhayB0aGF0IGdlbmVyYXRlcyB1bmNlcnRhaW50eSBpbiB0aGUgcmVhZGVyJ3MgbWluZCBhYm91dCB3aGF0IHlvdSBhY3R1YWxseSBtZWFuLiAKCkZvciBleGFtcGxlOgoKPiBUaGF0IGVzdGltYXRlIGlzIHRlbiB0aW1lcyBncmVhdGVyIHRoYW4gdGhlIDUwMCBudW1iZXIgSSBlcnJvbmVvdXNseSBwdXQgaW4gdGhlIGluaXRpYWwgZHJhZnQgb2YgdGhlIGVzc2F5LCBhbmQgaXQsIHRvbywgY291bGQgcHJvdmUgc29tZXdoYXQgb3B0aW1pc3RpYy4gCgpFcHN0ZWluJ3MgZmlyc3QgZ3Vlc3Mgd2FzIGltbWVkaWF0ZWx5IHdyb25nLCBzbyBoZXJlJ3MgYSBuZXcgZ3Vlc3MgdGhhdCBtaWdodCBhbHNvIGJlIGltbWVkaWF0ZWx5IHdyb25nLgoKPiBQZXJoYXBzIG15IGFuYWx5c2lzIGlzIGFsbCB3cm9uZywgZXZlbiBkZWVwbHkgZmxhd2VkLiBCdXQgdGhlIHN0YWtlcyBhcmUgdG9vIGhpZ2ggdG8gY29udGludWUgb24gdGhlIGN1cnJlbnQgY291cnNlIHdpdGhvdXQgcmVleGFtaW5pbmcgdGhlIGRhdGEgYW5kIHRoZSBlcnJvbmVvdXMgbW9kZWxzIHRoYXQgYXJlIHByZWRpY3RpbmcgZG9vbS4KClRoZSBzdGFrZXMgYXJlIHRvbyBoaWdoIG5vdCB0byBzYXkgY29tcGxldGVseSBmbGF3ZWQgdGhpbmdzIQoKRG9uJ3QgZG8gdGhpcy4gSXQncyBub3QgaG9uZXN0bHkgY29udmV5aW5nIHVuY2VydGFpbnR5LCBpdCdzIGF0dGVtcHRpbmcgdG8gY292ZXIgeW91ciBhc3MgZnJvbSBiZWluZyBoZWxkIGFjY291bnRhYmxlIGxhdGVyLgoKIyBDb25jbHVzaW9uCgpUaGUgY2hhbGxlbmdlIGluIHJldmlld2luZyBhbmFseXNlcyBsaWtlIHRoZXNlIGxpZXMgaW4gdGhlaXIgaW5jdXJpb3VzIGFuZCBpbnNpbmNlcmUgY29uc3RydWN0aW9uLiBUaGV5J3JlIG5vdCBhbiBlYXJuZXN0IHNlYXJjaCBmb3Igc2NpZW50aWZpYyB0cnV0aCBpbiB0aGVtc2VsdmVzLCB0aGV5J3JlIGF0IGJlc3QgYSBTb2NyYXRpYyBjYWxsIGZvciBvdGhlcnMgdG8gcG9pbnQgb3V0IG1pc3Rha2VzIGFuZCBleHBsYWluIHRoZSBzdGF0ZSBvZiB0aGUgYXJ0LiBFcHN0ZWluIFtleHBsaWNpdGx5IGZyYW1lc10oaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1iQ25UMm93YzFaOCkgaGlzIGFwcHJvYWNoIHRvIGlucXVpcnkgYXMgdGhlIGNvbnN0cnVjdGlvbiBvZiBhcmd1bWVudHMgYW5kIG5vdCByaWdvcm91cyBzdHVkeS4KCj4gSSBkb24ndCBjYXJlIHdobydzIGEgcHJvZmVzc2lvbmFsIG9yIG5vdCB5b3UgZG9uJ3Qgd2luIGFuIGFyZ3VtZW50IGJ5IHNob3dpbmcgeW91IGdvdCBhIFBoRCB5b3Ugd2luIGFuIGFyZ3VtZW50IGJ5IGVudGVyaW5nIGludG8gYSBwdWJsaWMgZGViYXRlIHdpdGggcGVvcGxlIHdobyBkaXNhZ3JlZS5eW0luIHRoaXMgZnJpZW5kbHkgaW50ZXJ2aWV3IGZvciBSZWFzb24gaGUgYnJhZ3MgYWJvdXQgYmVpbmcgYWJsZSB0byB3aW4gYXJndW1lbnRzIHRocm91Z2ggY29udGVudCBhbmQgbm90IGFwcGVhbHMgdG8gYXV0aG9yaXR5LCBidXQgYSBjb3VwbGUgb2YgZGF5cyBsYXRlciBpbiBhbiB1bmZyaWVuZGx5IGludGVydmlldyB3aXRoIFRoZSBOZXcgWW9ya2VyIGhlIGxpdGVyYWxseSBjaGFsbGVuZ2VzIHRoZSBqb3VybmFsaXN0IHRvIGNvbXBhcmUgcmVzdW1lcywgIllvdSBqdXN0IGRvbuKAmXQga25vdyBhbnl0aGluZyBhYm91dCBhbnl0aGluZy4gWW914oCZcmUgYSBqb3VybmFsaXN0LiBXb3VsZCB5b3UgbGlrZSB0byBjb21wYXJlIHlvdXIgcsOpc3Vtw6kgdG8gbWluZT8iIFRlbGxzIGxpa2UgdGhpcyBhcmUgdmVyeSBjb252ZW5pZW50IHNpZ25hbHMgZm9yIHNlcGFyYXRpbmcgc3BlYWtlcnMgd2hvIGFyZSBzaW5jZXJlIGJ1dCB3cm9uZyBmcm9tIHNwZWFrZXJzIHdobyBhcmUgaW5zaW5jZXJlIGdyaWZ0ZXJzLiAgIGh0dHBzOi8vd3d3Lm5ld3lvcmtlci5jb20vbmV3cy9xLWFuZC1hL3RoZS1jb250cmFyaWFuLWNvcm9uYXZpcnVzLXRoZW9yeS10aGF0LWluZm9ybWVkLXRoZS10cnVtcC1hZG1pbmlzdHJhdGlvbl0KClRoYXQgaXMgbm90IGEgdmlhYmxlIG9yIHByZWZlcnJlZCB3YXkgdG8gY29sbGVjdGl2ZWx5IGxlYXJuIGFib3V0IENPVklELTE5LiBJdCBpcyBhbiBbb3JkZXIgb2YgbWFnbml0dWRlIGxlc3MgZWZmb3J0XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9HaXNoX2dhbGxvcCkgdG8gc3BhbSBwb29ybHkgY29uc3RydWN0ZWQgaHlwb3RoZXRpY2FscyB0aGFuIGl0IGlzIHRvIGRlY29uc3RydWN0IHRoZW0uIFRoaXMgcmV2aWV3IHRvb2sgYSBzdWJzdGFudGlhbCBhbW91bnQgb2YgdGltZSwgYW5kIGluIHRoZSBtZWFudGltZSB0aGUgb3JpZ2luYWwgcGllY2Ugd2FzIHBvb3JseSByZXZpc2VkLCBzZXZlcmFsIGludGVydmlld3MgYW5kIGEgcG9kY2FzdCB3ZXJlIHJlbGVhc2VkLCBhbmQgYSBzZWNvbmQgcG9zdCB0cnlpbmcgdG8gY292ZXIgZm9yIHRoZSBmaXJzdCB3ZW50IGxpdmUuXltBbmQgdGhlIHNjaGVtYSBmb3IgdGhlIHVuZGVybHlpbmcgQ09WSUQtMTkgZGF0YSBjaGFuZ2VkIGJyZWFraW5nIGEgbG90IG9mIGNvZGUuXSBNb3JlIHdpbGwgbm8gZG91YnQgc29vbiBjb250aW51ZSB0byBtb3ZlIHRoZSBnb2FsIHBvc3RzIGFuZCBhcmd1bWVudC4gSW4gYSB3b3JsZCB3aGVyZSBhY3R1YWwgbGlmZSBvciBkZWF0aCBwb2xpY3kgYW5hbHlzaXMgaXMgYmVpbmcgdHJlYXRlZCBsaWtlIGEgaGlnaCBzY2hvb2wgZGViYXRlIHJvdW5kLCB0aGUgb25seSBzdHJhdGVnaWMgbW92ZSBpcyB0byBzdGVwIGJhY2ssIHNsb3cgZG93biwgYW5kIGRyYXcgbWV0aG9kb2xvZ2ljYWwgbGVzc29ucyBmb3Igb3VyIHN0dWRlbnRzIGFuZCBjb2xsZWFndWVzIHRoYXQgd2lsbCBhcHBseSB0byBhIGJyb2FkIHNldCBvZiBjdXJyZW50IGFuZCBmdXR1cmUgYW5hbHlzZXMuCgpFcHN0ZWluICgyMDIwYSwyMDIwYTIsMjAyMGIpIGFuZCBhbmFseXNpcyBsaWtlIGl0IHNob3VsZG4ndCBiZSByZWplY3RlZCBiZWNhdXNlIHRoZSBhdXRob3IgaXMgb3V0IG9mIHRoZWlyIGxhbmUuIEl0IHNob3VsZCBiZSByZWplY3RlZCBiZWNhdXNlIGl0J3MgYmFkIHdvcmsuIEknbSBub3QgYW4gZXBpZGVtaW9sb2dpc3QgZWl0aGVyLCBidXQgZXZlbiBhcyBqdXN0IGFzIGEgbG93bHkgc29jaWFsIHNjaWVudGlzdCwgSSBjYW4gc2hvdyBsb3RzIG9mIGRpZmZlcmVudCBzcGVjaWZpYyB3YXlzIHRoYXQgdGhlIGFuYWx5c2lzIGZhaWxzIHRvIG1lZXQgYmFzaWMgc3RhbmRhcmRzIG9mIHNjaWVudGlmaWMgaW5mZXJlbmNlLiBBbiBlcGlkZW1pb2xvZ2lzdCB3b3VsZCBoYXZlIGV2ZW4gbW9yZSBkZXRhaWxlZCBlbXBpcmljYWxseSByZWxldmFudCBpc3N1ZXMgdG8gcG9pbnQgb3V0LiBJbiB0aGlzIGN1cnJlbnQgdGltZSBvZiBjcmlzaXMsIHdlIHNob3VsZCByZXNpc3QgdGhlIHVyZ2UgdG8gZ2F0ZS1rZWVwIGFuZCBpbnN0ZWFkIGVuY291cmFnZSBob25lc3R5LCBjdXJpb3NpdHksIGhpZ2ggc3RhbmRhcmRzLCBhbmQgZ29vZCB3b3JrLiBFdmVuIGJsYXRhbnRseSBpbmN1cmlvdXMgYW5kIGJhZCB3b3JrIGNhbiBzZXJ2ZSBhcyBhIHBlZGFnb2dpY2FsIHRvb2wgdG8gdHJhaW4geW91bmcgcmVzZWFyY2hlcnMgd2hhdCBub3QgdG8gZG8uIFdlIG5lZWQgdG8gdGFrZSB0aGVzZSBvcHBvcnR1bml0aWVzIHRvIGxlYXJuIHNvIHRoYXQgd2UgYXJlIGFsbCBzbWFydGVyIGFuZCBiZXR0ZXIgcHJlcGFyZWQgZm9yIHRoZSBuZXh0IGNyaXNpcy4KCgoKCg==