Results

  1. Topic modeling gave us two clear dimensions: politics and economics.

  2. The most important topic was COVID-19 followed by an economy related topic. There is a significant overlap between these.

  3. Other topics include: climate change and sustainable development, technological development, the European Union, international relations (with an emphasis on China and Iran), the Israeli-Palestinian conflict, North American politics, Russian and Eastern European politics, and a last topic that is composed of a series of open letters signed by academics, politicians and people related to international institutions. This last topic is linked to the effect that the pandemic had on the relationship between developed and developing countries.

  4. During the sentiment analysis we detected two periods of the year 2020, in which negative feelings predominated. Between March and June due to the pandemic, and in October related to the North American presidential elections and the claims of electoral fraud.

  5. Regarding emotions: fear and sadness went up in March, because of the arrival of COVID to North America. On the other hand, confidence and anticipation dominated in October due to the expectations that were generated by the electoral victory of Joe Biden. In the same period, anger, sadness and fear also increased due to the uncertainty that was triggered as a result of Donalds Trump’s refusal to accept the electoral results.

Intro

Project Syndicate is a website that publishes opinion columns with authors from all over the world. They define themselves as The World’s Opinion Page. On the about page they mention that:

“Project Syndicate produces and delivers original, high-quality commentaries to a global audience. Featuring exclusive contributions by prominent political leaders, policymakers, scholars, business leaders, and civic activists from around the world.”

For this reason, I considered it the perfect portal to analyze in order to find the important topics of 2020. With this objective, I did topic modeling using the LDA algorithm. In addition, I performed sentiment analysis (polarity and emotions) using the sentimentR package of R. The database was collected by doing web scrapping with theRselenium package.

Topic Modeling

In order to find the most important topics discussed in 2020, I used the Latent Dirichlet Allocation (LDA), which is a popular method for modeling topics. It is important to remember that it treats each article as a mixture of topics and each topic as a mixture of words. This allows documents to overlap in terms of content, rather than separating them into distinct groups.

The algorithm was run with k = 10, which means that it tried to identify 10 topics. There are probably more topics, to find an optimal number the model can be trained just how a machine learning model would be trained. Unfortunately, this is computationally expensive (takes a long time), so I decided to only search for 10 topics. Here are the results:

LDAvis

The intertopic distance map is a way of visualizing the topics on a 2-dimensional plane. The dimension of these topics, represented by the size of the circle, is proportional to the number of words that belong to each topic. The circles, which represent the topics, are plotted based on the words that they consist of . Therefore, when there are two topics close together, this means that they have many words in common. The horizontal dimension (PC2) separates ‘political’ topics (left) from ‘economics/COVID related’ topics (right). The vertical dimension (PC1) separates the documents that are opinion columns, below, from the “open letters”, above.

The bar graph on the right shows, by default, the 30 most important terms. The bars indicate the total frequency of the term across all articles. “Salient” is a specific measure that is defined below the graph, it can be thought of as a metric used to identify the most informative or useful words to identify the topics in a database. A higher “saliency” value indicates that the word is more useful for identifying a specific topic.

It is possible to adjust the words that appear in the bar graph, by moving the λ (lambda) slider. When the values are close to 0, the less frequent but more unique terms of the selected topic are highlighted. Lambda values closer to 1 highlight terms that are more frequent in the topic but may not be exclusive to it.

Topics

The first topic is clearly about the pandemic and it is the most important one (in terms of size) of the past year, which is not a surprise at all. The second topic is about economic issues and there is an overlap between these first two topics, which makes sense given the economic uncertainty that was unleashed in various parts of the world in the wake of the pandemic. Topic 3 is related to climate change and sustainable development, as suggested by the words: climate, global, development, food, africa, water or energy.

Topic 4 at first glance seems to be about economics just like topic 2. To compare these two topics,I used the per-topic-per-word probabilities, called β (“beta” ). To find the terms with the greatest difference in β between the topics, the rate of the logarithm of 2 was used: log2 (β2 / β1).

When comparing both topics, it seems that topic 4 (red) is about technology. One of the most important words in this topic is workers, which is explained by the number of articles written about the impact of technology on employment during the pandemic. It seems, on the other hand, that topic 2 (blue) has a greater focus on the international economy due to words like ECB (European Central Bank), G20 or Currency).

At first it seems that topic 5 is about China, but after a more detailed analysis I found out that Iran is also an important keyword of this topic. This may seem confusing at first but since other defining keywords of this topic (war, global, international, power, and security) are very common in literature on international relations, this topic is possibly about IR and or geopolitics.

Topic 6 is about American politics as the words Trump, Biden and Americans seem to suggest. Topic 7 is related to the European Union. It’s located in both horizontal dimensions, so it is possible to think that it is a topic that deals with both political and economic aspects. Number 8 deals with themes related to Russia and Eastern Europe. There is a certain proximity to topic 6, which may be due to the impeachment process to which Donald Trump was subjected. Topic nine appears to be about the Israeli-Palestinian conflict. Something interesting is that there are also many words related to gender issues. This may be a sign of poor semantic coherence, which, could be is a sign that the number of topics I have is likely to be less than optimal.

The most mysterious topic is number 9 (red). Looking at the most relevant terms of the topic it is difficult to get an idea about its content. Since some of the keywords in this topic (economics, global; world bank) are similar to those found in Topic 2 (blue) I decided to compare these two groups.

It is difficult to find any meaning when looking at the terms that differentiate the two topics. So I decided to explore the articles that have a high probability of belonging to topic 10.

Looking at the titles, I got the impression that the articles were about how the economic relationship between rich and developing countries was affected by the pandemic. I analyzed the articles in detail, I found that they were open letters. These were signed by many people. Next to the name of the signatories there was always a small mention of the position that they had, that is why the words, president, minister, professor, secretary or director were so frequent in this topic.

Topics Over Time

The graph above is a heatmap that shows the percentage of articles by topic during the months of the year. The first thing that stands out is that topics 1 and 2 have a peak between March and May, because that’s when COVID19 reached the United States. This caused concern about the effect that the pandemic could have on the economy, which is the reason why the percentage of topic 2 (economy) also increased.

On the other hand, topic 6, North American politics, has a predominance in the months of October, November and December due to the presidential elections and Donald Trump’s refusal to accept the results of these. The assassination of Qassem Suleimani (an Iranian military officer, who was a member of the Islamic Revolutionary Guard Corps) in January 2020 is what causes the topic of international relations to peak in that month. There is another small peak in July due to a series of events related to Chinese international politics.

First, Iran announced that it was negotiating a bilateral agreement with China that included areas such as: trade, energy, infrastructure, telecommunications and even military cooperation. Second, the UK decided to ban Huawei from its 5G network. Third, the decision to impose a national security law in Hong Kong. Fourth, the bilateral tensions that followed an armed confrontation between China and India in the Ladakh region, which resulted in the death of soldiers from both sides.

Topic 8, Russia and Eastern Europe, peaked in August due to the protests that occurred after the Belarusian president announced that he had won the presidencial election with 80% of the votes. The other peak occurred in February because at the beginning of that month the first impeachment of Donald Trump concluded. The impeachment was carried out in response to the Trump-Ukraine scandal, Trump, allegedly, pressured the Ukrainian government to investigate Hunter Biden, the son of then-presidential candidate Joe Biden.

Topic 3, sustainability, peaked in September due to an event called The Green Recovery, according to Project Syndicate this was a “virtual sustainability event” which was broadcasted live in September of 2020. Possibly there were a number of columns published that month that were linked to the event. The first day of the event can be seen here

Sentiment Analysis

A sentiment analysis was performed using the sentimentR package. First, a polarity analysis was carried out, negative feelings versus positive feelings. The sentimentR package calculates the feelings within each article analysing all the sentences from the text. The specific way in which a score is assigned to an article can be reviewed in this link. The important thing is to know that positive values correspond to positive feelings and negative values correspond to negative feelings. We calculated the average sentiment score of the articles by month, these are the results we found:

The first thing that stands out is the clear effect the pandemic had had on the feelings of Project Syndicate columnists. The score was negative from March to May. Another occasion when the score dropped was in October due to the presidential elections in the United States and specifically due to Donald Trump’s refusal to accept the results. The second thing that was analyzed were emotions, not just polarity, in order to see specifically what happened, here is a graph with the results.

With the arrival of COVID to the United States and Europe, emotions such as fear and sadness increased. It seems that sadness has a longer peak, remaining stable until May. While confidence, happiness, and anticipation increased- mainly due to the expectations generated by Joe Biden’s victory - Trump’s refusal to accept the results caused feelings of anger, sadness and fear to also increased.

Final thoughts

This exploratory analysis sheds some light on the news events of 2020. It is fascinating to see the effects of the most defining events of the year had: the Pandemic and the North American elections, both in topic modeling and sentiment analysis.

Looking at the most important events of the beginning of the year, I need to mention the assassination of Qassem Soleimani and the impeachment of Donald Trump. With the arrival of COVID to the United States and Europe, everything changed. The agenda was dominated by this topic and by the economic consequences that the pandemic was going to have. Towards the end of the year the US presidential elections and Donald Trump’s subsequent refusal to accept his defeat came to the fore.

Finally, in the sentiments analysis and in the topic modeling there is room for improvement. First of all, the dictionaries of sentiment and emotions can be better adapted to have more adequate results. Furthermore, it is possible to add more topics to better understand which were the topics that were present on public discussion in 2020.

LS0tDQp0aXRsZTogIlRvcGljIE1vZGVsaW5nIGFuZCBTZW50aW1lbnQgQW5hbHlzaXMgb2YgMjAyMCBOZXdzIg0KYXV0aG9yOiAiSm9zw6kgUGXDsWEgUyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQo8c3R5bGU+DQoNCmJvZHl7DQogdGV4dC1hbGlnbjoganVzdGlmeTsNCn0NCg0KPC9zdHlsZT4NCg0KIyMgUmVzdWx0cw0KDQoNCjEpIFRvcGljIG1vZGVsaW5nIGdhdmUgdXMgdHdvIGNsZWFyIGRpbWVuc2lvbnM6IHBvbGl0aWNzIGFuZCBlY29ub21pY3MuDQoNCjIpIFRoZSBtb3N0IGltcG9ydGFudCB0b3BpYyB3YXMgQ09WSUQtMTkgZm9sbG93ZWQgYnkgYW4gZWNvbm9teSByZWxhdGVkIHRvcGljLiBUaGVyZSBpcyBhIHNpZ25pZmljYW50IG92ZXJsYXAgYmV0d2VlbiB0aGVzZS4gDQoNCjMpIE90aGVyIHRvcGljcyBpbmNsdWRlOiBjbGltYXRlIGNoYW5nZSBhbmQgc3VzdGFpbmFibGUgZGV2ZWxvcG1lbnQsIHRlY2hub2xvZ2ljYWwgZGV2ZWxvcG1lbnQsIHRoZSBFdXJvcGVhbiBVbmlvbiwgaW50ZXJuYXRpb25hbCByZWxhdGlvbnMgKHdpdGggYW4gZW1waGFzaXMgb24gQ2hpbmEgYW5kIElyYW4pLCB0aGUgSXNyYWVsaS1QYWxlc3RpbmlhbiBjb25mbGljdCwgTm9ydGggQW1lcmljYW4gcG9saXRpY3MsIFJ1c3NpYW4gYW5kIEVhc3Rlcm4gRXVyb3BlYW4gcG9saXRpY3MsIGFuZCBhIGxhc3QgdG9waWMgdGhhdCBpcyBjb21wb3NlZCBvZiBhIHNlcmllcyBvZiBvcGVuIGxldHRlcnMgc2lnbmVkIGJ5IGFjYWRlbWljcywgcG9saXRpY2lhbnMgYW5kIHBlb3BsZSByZWxhdGVkIHRvIGludGVybmF0aW9uYWwgaW5zdGl0dXRpb25zLiBUaGlzIGxhc3QgdG9waWMgaXMgbGlua2VkIHRvIHRoZSBlZmZlY3QgdGhhdCB0aGUgcGFuZGVtaWMgaGFkIG9uIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBkZXZlbG9wZWQgYW5kIGRldmVsb3BpbmcgY291bnRyaWVzLg0KDQo0KSBEdXJpbmcgdGhlIHNlbnRpbWVudCBhbmFseXNpcyB3ZSBkZXRlY3RlZCB0d28gcGVyaW9kcyBvZiB0aGUgeWVhciAyMDIwLCBpbiB3aGljaCBuZWdhdGl2ZSBmZWVsaW5ncyBwcmVkb21pbmF0ZWQuIEJldHdlZW4gTWFyY2ggYW5kIEp1bmUgZHVlIHRvIHRoZSBwYW5kZW1pYywgYW5kIGluIE9jdG9iZXIgcmVsYXRlZCB0byB0aGUgTm9ydGggQW1lcmljYW4gcHJlc2lkZW50aWFsIGVsZWN0aW9ucyBhbmQgdGhlIGNsYWltcyBvZiBlbGVjdG9yYWwgZnJhdWQuDQoNCjUpIFJlZ2FyZGluZyBlbW90aW9uczogZmVhciBhbmQgc2FkbmVzcyB3ZW50IHVwIGluIE1hcmNoLCBiZWNhdXNlIG9mIHRoZSBhcnJpdmFsIG9mIENPVklEIHRvIE5vcnRoIEFtZXJpY2EuIE9uIHRoZSBvdGhlciBoYW5kLCBjb25maWRlbmNlIGFuZCBhbnRpY2lwYXRpb24gZG9taW5hdGVkIGluIE9jdG9iZXIgZHVlIHRvIHRoZSBleHBlY3RhdGlvbnMgdGhhdCB3ZXJlIGdlbmVyYXRlZCBieSB0aGUgZWxlY3RvcmFsIHZpY3Rvcnkgb2YgSm9lIEJpZGVuLiBJbiB0aGUgc2FtZSBwZXJpb2QsIGFuZ2VyLCBzYWRuZXNzIGFuZCBmZWFyIGFsc28gaW5jcmVhc2VkIGR1ZSB0byB0aGUgdW5jZXJ0YWludHkgdGhhdCB3YXMgdHJpZ2dlcmVkIGFzIGEgcmVzdWx0IG9mIERvbmFsZHMgVHJ1bXAncyByZWZ1c2FsIHRvIGFjY2VwdCB0aGUgZWxlY3RvcmFsIHJlc3VsdHMuDQoNCg0KIyMgSW50cm8NCg0KIVtdKGh0dHBzOi8vd3d3LnByb2plY3Qtc3luZGljYXRlLm9yZy9pbWFnZXMvcHMtdGhlLXdvcmxkcy1vcGluaW9uLXBhZ2UucG5nKQ0KDQpbUHJvamVjdCBTeW5kaWNhdGVdKGh0dHBzOi8vd3d3LnByb2plY3Qtc3luZGljYXRlLm9yZy8pIGlzIGEgd2Vic2l0ZSB0aGF0IHB1Ymxpc2hlcyBvcGluaW9uIGNvbHVtbnMgd2l0aCBhdXRob3JzIGZyb20gYWxsIG92ZXIgdGhlIHdvcmxkLiBUaGV5IGRlZmluZSB0aGVtc2VsdmVzIGFzICoqVGhlIFdvcmxkJ3MgT3BpbmlvbiBQYWdlKiouIE9uIHRoZSBbYWJvdXRdKGh0dHBzOi8vd3d3LnByb2plY3Qtc3luZGljYXRlLm9yZy9hYm91dCkgcGFnZSB0aGV5IG1lbnRpb24gdGhhdDoNCg0KKiJQcm9qZWN0IFN5bmRpY2F0ZSBwcm9kdWNlcyBhbmQgZGVsaXZlcnMgb3JpZ2luYWwsIGhpZ2gtcXVhbGl0eSBjb21tZW50YXJpZXMgdG8gYSBnbG9iYWwgYXVkaWVuY2UuIEZlYXR1cmluZyBleGNsdXNpdmUgY29udHJpYnV0aW9ucyBieSBwcm9taW5lbnQgcG9saXRpY2FsIGxlYWRlcnMsIHBvbGljeW1ha2Vycywgc2Nob2xhcnMsIGJ1c2luZXNzIGxlYWRlcnMsIGFuZCBjaXZpYyBhY3RpdmlzdHMgZnJvbSBhcm91bmQgdGhlIHdvcmxkLiIqDQoNCkZvciB0aGlzIHJlYXNvbiwgSSBjb25zaWRlcmVkIGl0IHRoZSBwZXJmZWN0IHBvcnRhbCB0byBhbmFseXplIGluIG9yZGVyIHRvIGZpbmQgdGhlIGltcG9ydGFudCB0b3BpY3Mgb2YgMjAyMC4gV2l0aCB0aGlzIG9iamVjdGl2ZSwgSSBkaWQgdG9waWMgbW9kZWxpbmcgdXNpbmcgdGhlIExEQSBhbGdvcml0aG0uIEluIGFkZGl0aW9uLCBJIHBlcmZvcm1lZCBzZW50aW1lbnQgYW5hbHlzaXMgKHBvbGFyaXR5IGFuZCBlbW90aW9ucykgdXNpbmcgdGhlIGBzZW50aW1lbnRSYCBwYWNrYWdlIG9mIFIuIFRoZSBkYXRhYmFzZSB3YXMgY29sbGVjdGVkIGJ5IGRvaW5nIHdlYiBzY3JhcHBpbmcgd2l0aCB0aGVgIFJzZWxlbml1bWAgcGFja2FnZS4NCg0KIyMgVG9waWMgTW9kZWxpbmcNCg0KDQpJbiBvcmRlciB0byBmaW5kIHRoZSBtb3N0IGltcG9ydGFudCB0b3BpY3MgZGlzY3Vzc2VkIGluIDIwMjAsIEkgdXNlZCB0aGUgKipMYXRlbnQgRGlyaWNobGV0IEFsbG9jYXRpb24qKiAoTERBKSwgd2hpY2ggaXMgYSBwb3B1bGFyIG1ldGhvZCBmb3IgbW9kZWxpbmcgdG9waWNzLiBJdCBpcyBpbXBvcnRhbnQgdG8gcmVtZW1iZXIgdGhhdCBpdCB0cmVhdHMgZWFjaCBhcnRpY2xlIGFzIGEgbWl4dHVyZSBvZiB0b3BpY3MgYW5kIGVhY2ggdG9waWMgYXMgYSBtaXh0dXJlIG9mIHdvcmRzLiBUaGlzIGFsbG93cyBkb2N1bWVudHMgdG8gb3ZlcmxhcCBpbiB0ZXJtcyBvZiBjb250ZW50LCByYXRoZXIgdGhhbiBzZXBhcmF0aW5nIHRoZW0gaW50byBkaXN0aW5jdCBncm91cHMuDQoNClRoZSBhbGdvcml0aG0gd2FzIHJ1biB3aXRoIGsgPSAxMCwgd2hpY2ggbWVhbnMgdGhhdCBpdCB0cmllZCB0byBpZGVudGlmeSAxMCB0b3BpY3MuIFRoZXJlIGFyZSBwcm9iYWJseSBtb3JlIHRvcGljcywgdG8gZmluZCBhbiBvcHRpbWFsIG51bWJlciB0aGUgbW9kZWwgY2FuIGJlIHRyYWluZWQganVzdCBob3cgYSBtYWNoaW5lIGxlYXJuaW5nIG1vZGVsIHdvdWxkIGJlIHRyYWluZWQuIFVuZm9ydHVuYXRlbHksIHRoaXMgaXMgY29tcHV0YXRpb25hbGx5IGV4cGVuc2l2ZSAodGFrZXMgYSBsb25nIHRpbWUpLCBzbyBJIGRlY2lkZWQgdG8gb25seSBzZWFyY2ggZm9yIDEwIHRvcGljcy4gSGVyZSBhcmUgdGhlIHJlc3VsdHM6DQoNCg0KPGhlYWQ+DQogIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCiAgPHRpdGxlPkxEQXZpczwvdGl0bGU+DQogIDxzY3JpcHQgc3JjPSJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSm9zZVBlbmFTL3NvbWUtZGF0YS9tYWluL2QzLnYzLmpzIj48L3NjcmlwdD4NCiAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Kb3NlUGVuYVMvc29tZS1kYXRhL21haW4vbGRhdmlzLmpzIj48L3NjcmlwdD4NCiAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ibGRhLmNzcyI+DQogIDwvaGVhZD4NCiAgDQogIDxib2R5Pg0KICA8ZGl2IGlkID0gImxkYSI+PC9kaXY+DQogIDxzY3JpcHQ+DQogIHZhciB2aXMgPSBuZXcgTERBdmlzKCIjbGRhIiwgImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Kb3NlUGVuYVMvc29tZS1kYXRhL21haW4vbGRhLmpzb24iKTsNCjwvc2NyaXB0Pg0KICA8L2JvZHk+DQogIA0KVGhlIGludGVydG9waWMgZGlzdGFuY2UgbWFwIGlzIGEgd2F5IG9mIHZpc3VhbGl6aW5nIHRoZSB0b3BpY3Mgb24gYSAyLWRpbWVuc2lvbmFsIHBsYW5lLiBUaGUgZGltZW5zaW9uIG9mIHRoZXNlIHRvcGljcywgcmVwcmVzZW50ZWQgYnkgdGhlIHNpemUgb2YgdGhlIGNpcmNsZSwgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2Ygd29yZHMgdGhhdCBiZWxvbmcgdG8gZWFjaCB0b3BpYy4gVGhlIGNpcmNsZXMsIHdoaWNoIHJlcHJlc2VudCB0aGUgdG9waWNzLCBhcmUgcGxvdHRlZCBiYXNlZCBvbiB0aGUgd29yZHMgdGhhdCB0aGV5IGNvbnNpc3Qgb2YNCi4gVGhlcmVmb3JlLCB3aGVuIHRoZXJlIGFyZSB0d28gdG9waWNzIGNsb3NlIHRvZ2V0aGVyLCB0aGlzIG1lYW5zIHRoYXQgdGhleSBoYXZlIG1hbnkgd29yZHMgaW4gY29tbW9uLiBUaGUgaG9yaXpvbnRhbCBkaW1lbnNpb24gKFBDMikgc2VwYXJhdGVzIOKAmHBvbGl0aWNhbOKAmSB0b3BpY3MgKGxlZnQpIGZyb20g4oCYZWNvbm9taWNzL0NPVklEIHJlbGF0ZWTigJkgdG9waWNzIChyaWdodCkuIFRoZSB2ZXJ0aWNhbCBkaW1lbnNpb24gKFBDMSkgc2VwYXJhdGVzIHRoZSBkb2N1bWVudHMgdGhhdCBhcmUgb3BpbmlvbiBjb2x1bW5zLCBiZWxvdywgZnJvbSB0aGUg4oCcb3BlbiBsZXR0ZXJz4oCdLCBhYm92ZS4NCg0KVGhlIGJhciBncmFwaCBvbiB0aGUgcmlnaHQgc2hvd3MsIGJ5IGRlZmF1bHQsIHRoZSAzMCBtb3N0IGltcG9ydGFudCB0ZXJtcy4gVGhlIGJhcnMgaW5kaWNhdGUgdGhlIHRvdGFsIGZyZXF1ZW5jeSBvZiB0aGUgdGVybSBhY3Jvc3MgYWxsIGFydGljbGVzLiAqIlNhbGllbnQiKiBpcyBhIHNwZWNpZmljIG1lYXN1cmUgdGhhdCBpcyBkZWZpbmVkIGJlbG93IHRoZSBncmFwaCwgaXQgY2FuIGJlIHRob3VnaHQgb2YgYXMgYSBtZXRyaWMgdXNlZCB0byBpZGVudGlmeSB0aGUgbW9zdCBpbmZvcm1hdGl2ZSBvciB1c2VmdWwgd29yZHMgdG8gaWRlbnRpZnkgdGhlIHRvcGljcyBpbiBhIGRhdGFiYXNlLiBBIGhpZ2hlciAqInNhbGllbmN5IiogdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIHdvcmQgaXMgbW9yZSB1c2VmdWwgZm9yIGlkZW50aWZ5aW5nIGEgc3BlY2lmaWMgdG9waWMuDQoNCkl0IGlzIHBvc3NpYmxlIHRvIGFkanVzdCB0aGUgd29yZHMgdGhhdCBhcHBlYXIgaW4gdGhlIGJhciBncmFwaCwgYnkgbW92aW5nIHRoZSDOuyAobGFtYmRhKSBzbGlkZXIuIFdoZW4gdGhlIHZhbHVlcyBhcmUgY2xvc2UgdG8gMCwgdGhlIGxlc3MgZnJlcXVlbnQgYnV0IG1vcmUgdW5pcXVlIHRlcm1zIG9mIHRoZSBzZWxlY3RlZCB0b3BpYyBhcmUgaGlnaGxpZ2h0ZWQuIExhbWJkYSB2YWx1ZXMgY2xvc2VyIHRvIDEgaGlnaGxpZ2h0IHRlcm1zIHRoYXQgYXJlIG1vcmUgZnJlcXVlbnQgaW4gdGhlIHRvcGljIGJ1dCBtYXkgbm90IGJlIGV4Y2x1c2l2ZSB0byBpdC4gDQoNCiMjIyBUb3BpY3MNCg0KVGhlIGZpcnN0IHRvcGljIGlzIGNsZWFybHkgYWJvdXQgdGhlIHBhbmRlbWljIGFuZCBpdCBpcyB0aGUgbW9zdCBpbXBvcnRhbnQgb25lIChpbiB0ZXJtcyBvZiBzaXplKSBvZiB0aGUgcGFzdCB5ZWFyLCB3aGljaCBpcyBub3QgYSBzdXJwcmlzZSBhdCBhbGwuIFRoZSBzZWNvbmQgdG9waWMgaXMgYWJvdXQgZWNvbm9taWMgaXNzdWVzIGFuZCB0aGVyZSBpcyBhbiBvdmVybGFwIGJldHdlZW4gdGhlc2UgZmlyc3QgdHdvIHRvcGljcywgd2hpY2ggbWFrZXMgc2Vuc2UgZ2l2ZW4gdGhlIGVjb25vbWljIHVuY2VydGFpbnR5IHRoYXQgd2FzIHVubGVhc2hlZCBpbiB2YXJpb3VzIHBhcnRzIG9mIHRoZSB3b3JsZCBpbiB0aGUgd2FrZSBvZiB0aGUgcGFuZGVtaWMuIFRvcGljIDMgaXMgcmVsYXRlZCB0byBjbGltYXRlIGNoYW5nZSBhbmQgc3VzdGFpbmFibGUgZGV2ZWxvcG1lbnQsIGFzIHN1Z2dlc3RlZCBieSB0aGUgd29yZHM6ICoqY2xpbWF0ZSwgZ2xvYmFsLCBkZXZlbG9wbWVudCwgZm9vZCwgYWZyaWNhLCB3YXRlcioqIG9yICoqZW5lcmd5KiouDQoNCg0KVG9waWMgNCBhdCBmaXJzdCBnbGFuY2Ugc2VlbXMgdG8gYmUgYWJvdXQgZWNvbm9taWNzIGp1c3QgbGlrZSB0b3BpYyAyLiBUbyBjb21wYXJlIHRoZXNlIHR3byB0b3BpY3MsSSB1c2VkIHRoZSAqKnBlci10b3BpYy1wZXItd29yZCoqIHByb2JhYmlsaXRpZXMsIGNhbGxlZCDOsiAoKiJiZXRhIiogKS4gVG8gZmluZCB0aGUgdGVybXMgd2l0aCB0aGUgZ3JlYXRlc3QgZGlmZmVyZW5jZSBpbiDOsiBiZXR3ZWVuIHRoZSB0b3BpY3MsIHRoZSByYXRlIG9mIHRoZSBsb2dhcml0aG0gb2YgMiB3YXMgdXNlZDogbG9nMiAozrIyIC8gzrIxKS4NCg0KDQpXaGVuIGNvbXBhcmluZyBib3RoIHRvcGljcywgaXQgc2VlbXMgdGhhdCB0b3BpYyA0IChyZWQpIGlzIGFib3V0IHRlY2hub2xvZ3kuIE9uZSBvZiB0aGUgbW9zdCBpbXBvcnRhbnQgd29yZHMgaW4gdGhpcyB0b3BpYyBpcyAqd29ya2VycyosIHdoaWNoIGlzIGV4cGxhaW5lZCBieSB0aGUgbnVtYmVyIG9mIGFydGljbGVzIHdyaXR0ZW4gYWJvdXQgdGhlIGltcGFjdCBvZiB0ZWNobm9sb2d5IG9uIGVtcGxveW1lbnQgZHVyaW5nIHRoZSBwYW5kZW1pYy4gSXQgc2VlbXMsIG9uIHRoZSBvdGhlciBoYW5kLCB0aGF0IHRvcGljIDIgKGJsdWUpIGhhcyBhIGdyZWF0ZXIgZm9jdXMgb24gdGhlIGludGVybmF0aW9uYWwgZWNvbm9teSBkdWUgdG8gd29yZHMgbGlrZSAqRUNCIChFdXJvcGVhbiBDZW50cmFsIEJhbmspLCBHMjAgb3IgQ3VycmVuY3kpKi4NCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLmFsaWduID0gJ2NlbnRlcid9DQoNCmJldGFfc3ByZWFkIDwtIGFwX3RvcGljcyAlPiUNCiAgbXV0YXRlKHRvcGljID0gcGFzdGUwKCJ0b3BpYyIsIHRvcGljKSkgJT4lDQogIHNwcmVhZCh0b3BpYywgYmV0YSkgJT4lDQogIGZpbHRlcih0b3BpYzEgPiAuMDAxIHwgdG9waWM0ID4gLjAwMSkgJT4lDQogIG11dGF0ZShsb2dfcmF0aW8gPSBsb2cyKHRvcGljMSAvIHRvcGljNCkpDQoNCmJldGFfc3ByZWFkICU+JQ0KICBncm91cF9ieShkaXJlY3Rpb24gPSBsb2dfcmF0aW8gPiAwKSAlPiUNCiAgdG9wX24oMTAsIGFicyhsb2dfcmF0aW8pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodGVybSA9IHJlb3JkZXIodGVybSwgbG9nX3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMobG9nX3JhdGlvLCB0ZXJtLCBmaWxsID0gbG9nX3JhdGlvID4gMCkpICsNCiAgZ2VvbV9jb2woKSArDQogIGxhYnMoeCA9ICJMb2cyIHJhdGlvIG9mIGJldGEgaW4gdG9waWMgNCAvIHRvcGljIDIiLCB5ID0gTlVMTCkrDQogIHRoZW1lX2xpZ2h0KCkrdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsNCiAgZ2d0aXRsZSgiVGVybXMgdGhhdCBoYWQgdGhlIGdyZWF0ZXN0IGRpZmZlcmVuY2UgaW4gzrIgYmV0d2VlbiB0b3BpYyA0IGFuZCB0b3BpYyAyIikNCg0KYGBgDQoNCkF0IGZpcnN0IGl0IHNlZW1zIHRoYXQgdG9waWMgNSBpcyBhYm91dCBDaGluYSwgYnV0IGFmdGVyIGEgbW9yZSBkZXRhaWxlZCBhbmFseXNpcyBJIGZvdW5kIG91dCB0aGF0IElyYW4gaXMgYWxzbyBhbiBpbXBvcnRhbnQga2V5d29yZCBvZiB0aGlzIHRvcGljLiBUaGlzIG1heSBzZWVtIGNvbmZ1c2luZyBhdCBmaXJzdCBidXQgc2luY2Ugb3RoZXIgZGVmaW5pbmcga2V5d29yZHMgb2YgdGhpcyB0b3BpYyAod2FyLCBnbG9iYWwsIGludGVybmF0aW9uYWwsIHBvd2VyLCBhbmQgc2VjdXJpdHkpIGFyZSB2ZXJ5IGNvbW1vbiBpbiBsaXRlcmF0dXJlIG9uIGludGVybmF0aW9uYWwgcmVsYXRpb25zLCB0aGlzIHRvcGljIGlzIHBvc3NpYmx5IGFib3V0IElSIGFuZCBvciBnZW9wb2xpdGljcy4NCg0KVG9waWMgNiBpcyBhYm91dCBBbWVyaWNhbiBwb2xpdGljcyBhcyB0aGUgd29yZHMgKlRydW1wLCBCaWRlbiogYW5kICpBbWVyaWNhbnMqIHNlZW0gdG8gc3VnZ2VzdC4gVG9waWMgNyBpcyByZWxhdGVkIHRvIHRoZSBFdXJvcGVhbiBVbmlvbi4gSXTigJlzIGxvY2F0ZWQgaW4gYm90aCBob3Jpem9udGFsIGRpbWVuc2lvbnMsIHNvIGl0IGlzIHBvc3NpYmxlIHRvIHRoaW5rIHRoYXQgaXQgaXMgYSB0b3BpYyB0aGF0IGRlYWxzIHdpdGggYm90aCBwb2xpdGljYWwgYW5kIGVjb25vbWljIGFzcGVjdHMuIE51bWJlciA4IGRlYWxzIHdpdGggdGhlbWVzIHJlbGF0ZWQgdG8gUnVzc2lhIGFuZCBFYXN0ZXJuIEV1cm9wZS4gVGhlcmUgaXMgYSBjZXJ0YWluIHByb3hpbWl0eSB0byB0b3BpYyA2LCB3aGljaCBtYXkgYmUgZHVlIHRvIHRoZSAqaW1wZWFjaG1lbnQqIHByb2Nlc3MgdG8gd2hpY2ggRG9uYWxkIFRydW1wIHdhcyBzdWJqZWN0ZWQuIFRvcGljIG5pbmUgYXBwZWFycyB0byBiZSBhYm91dCB0aGUgSXNyYWVsaS1QYWxlc3RpbmlhbiBjb25mbGljdC4gU29tZXRoaW5nIGludGVyZXN0aW5nIGlzIHRoYXQgdGhlcmUgYXJlIGFsc28gbWFueSB3b3JkcyByZWxhdGVkIHRvIGdlbmRlciBpc3N1ZXMuIFRoaXMgbWF5IGJlIGEgc2lnbiBvZiBwb29yIHNlbWFudGljIGNvaGVyZW5jZSwgd2hpY2gsIGNvdWxkIGJlIGlzIGEgc2lnbiB0aGF0IHRoZSBudW1iZXIgb2YgdG9waWNzIEkgaGF2ZSBpcyBsaWtlbHkgdG8gYmUgbGVzcyB0aGFuIG9wdGltYWwuDQoNClRoZSBtb3N0IG15c3RlcmlvdXMgdG9waWMgaXMgbnVtYmVyIDkgKHJlZCkuIExvb2tpbmcgYXQgdGhlIG1vc3QgcmVsZXZhbnQgdGVybXMgb2YgdGhlIHRvcGljIGl0IGlzIGRpZmZpY3VsdCB0byBnZXQgYW4gaWRlYSBhYm91dCBpdHMgY29udGVudC4gU2luY2Ugc29tZSBvZiB0aGUga2V5d29yZHMgaW4gdGhpcyB0b3BpYyAoZWNvbm9taWNzLCBnbG9iYWw7IHdvcmxkIGJhbmspIGFyZSBzaW1pbGFyIHRvIHRob3NlIGZvdW5kIGluIFRvcGljIDIgKGJsdWUpIEkgZGVjaWRlZCB0byBjb21wYXJlIHRoZXNlIHR3byBncm91cHMuDQoNCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KDQpiZXRhX3NwcmVhZCA8LSBhcF90b3BpY3MgJT4lDQogIG11dGF0ZSh0b3BpYyA9IHBhc3RlMCgidG9waWMiLCB0b3BpYykpICU+JQ0KICBzcHJlYWQodG9waWMsIGJldGEpICU+JQ0KICBmaWx0ZXIodG9waWMxID4gLjAwMSB8IHRvcGljMyA+IC4wMDEpICU+JQ0KICBtdXRhdGUobG9nX3JhdGlvID0gbG9nMih0b3BpYzEgLyB0b3BpYzMpKQ0KDQpiZXRhX3NwcmVhZCAlPiUNCiAgZ3JvdXBfYnkoZGlyZWN0aW9uID0gbG9nX3JhdGlvID4gMCkgJT4lDQogIHRvcF9uKDEwLCBhYnMobG9nX3JhdGlvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHRlcm0gPSByZW9yZGVyKHRlcm0sIGxvZ19yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKGxvZ19yYXRpbywgdGVybSwgZmlsbCA9IGxvZ19yYXRpbyA+IDApKSArDQogIGdlb21fY29sKCkgKw0KICBsYWJzKHggPSAiTG9nMiByYXRpbyBvZiBiZXRhIGluIHRvcGljIDEwIC8gdG9waWMgMiIsIHkgPSBOVUxMKSsNCiAgdGhlbWVfbGlnaHQoKSt0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKw0KICBnZ3RpdGxlKCJUZXJtcyB0aGF0IGhhZCB0aGUgZ3JlYXRlc3QgZGlmZmVyZW5jZSBpbiDOsiBiZXR3ZWVuIHRvcGljIDEwIGFuZCB0b3BpYyAyIikNCmBgYA0KDQpJdCBpcyBkaWZmaWN1bHQgdG8gZmluZCBhbnkgbWVhbmluZyB3aGVuIGxvb2tpbmcgYXQgdGhlIHRlcm1zIHRoYXQgZGlmZmVyZW50aWF0ZSB0aGUgdHdvIHRvcGljcy4gU28gSSBkZWNpZGVkIHRvIGV4cGxvcmUgdGhlIGFydGljbGVzIHRoYXQgaGF2ZSBhIGhpZ2ggcHJvYmFiaWxpdHkgb2YgYmVsb25naW5nIHRvIHRvcGljIDEwLg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIGFwX2RvY3VtZW50cyU+JQ0KICBhcnJhbmdlKGRlc2MoZG9jdW1lbnQpKSAlPiUgZmlsdGVyKHRvcGljPT0zJmdhbW1hPjAuOCkNCmBgYA0KDQpMb29raW5nIGF0IHRoZSB0aXRsZXMsIEkgZ290IHRoZSBpbXByZXNzaW9uIHRoYXQgdGhlIGFydGljbGVzIHdlcmUgYWJvdXQgaG93IHRoZSBlY29ub21pYyByZWxhdGlvbnNoaXAgYmV0d2VlbiByaWNoIGFuZCBkZXZlbG9waW5nIGNvdW50cmllcyB3YXMgYWZmZWN0ZWQgYnkgdGhlIHBhbmRlbWljLiBJIGFuYWx5emVkIHRoZSBhcnRpY2xlcyBpbiBkZXRhaWwsIEkgZm91bmQgdGhhdCB0aGV5IHdlcmUgb3BlbiBsZXR0ZXJzLiBUaGVzZSB3ZXJlIHNpZ25lZCBieSBtYW55IHBlb3BsZS4gTmV4dCB0byB0aGUgbmFtZSBvZiB0aGUgc2lnbmF0b3JpZXMgdGhlcmUgd2FzIGFsd2F5cyBhIHNtYWxsIG1lbnRpb24gb2YgdGhlIHBvc2l0aW9uIHRoYXQgdGhleSBoYWQsIHRoYXQgaXMgd2h5IHRoZSB3b3JkcywgKnByZXNpZGVudCwgbWluaXN0ZXIsIHByb2Zlc3Nvciwgc2VjcmV0YXJ5KiBvciAqZGlyZWN0b3IqIHdlcmUgc28gZnJlcXVlbnQgaW4gdGhpcyB0b3BpYy4NCg0KDQojIyMgVG9waWNzIE92ZXIgVGltZQ0KICAgDQpgYGB7cixmaWcuYWxpZ24gPSAnY2VudGVyJyxlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRX0NCg0KbW9udGhfd29yZHMgJT4lIG11dGF0ZShnYW1tYTE9aWZlbHNlKGdhbW1hPjAuOCwxLDApKSU+JQ0KICBncm91cF9ieSgNCiAgICBtb250aCA9IG1vbnRoKGRhdGUyKSwNCiAgICB0b3BpYykgJT4lDQogIHN1bW1hcmlzZShnYW1tYTEgPSBtZWFuKGdhbW1hMSkpICU+JQ0KICBtdXRhdGUodG9waWM9IGNhc2Vfd2hlbih0b3BpYyA9PSAxIH4gMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9waWMgPT0gMiB+IDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHRvcGljID09IDMgfiAxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9waWMgPT0gNCB+IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHRvcGljID09IDUgfiA4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICB0b3BpYyA9PSA2IH4gOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9waWMgPT0gNyB+IDcsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHRvcGljID09IDggfiA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICB0b3BpYyA9PSA5IH4gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9waWMgPT0gMTAgfiAzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKGFzLmZhY3Rvcihtb250aCksIGFzLmZhY3Rvcih0b3BpYyksIGZpbGwgPSBnYW1tYTEpKSArDQogIGdlb21fdGlsZShhbHBoYSA9IDAuOSkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgbGFicyhmaWxsID0gIkFydGljbGVzICUiLCB4ID0gIm1vbnRoIG9mIHRoZSB5ZWFyIiwgeSA9ICJ0b3BpYyIpKw0KICB0aGVtZV9saWdodCgpKyANCiAgZ2d0aXRsZSgiQXJ0aWNsZXMgYnkgVG9waWMgYW5kIE1vbnRoIikNCiAgIA0KYGBgDQoNClRoZSBncmFwaCBhYm92ZSBpcyBhICpoZWF0bWFwKiB0aGF0IHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIGFydGljbGVzIGJ5IHRvcGljIGR1cmluZyB0aGUgbW9udGhzIG9mIHRoZSB5ZWFyLiBUaGUgZmlyc3QgdGhpbmcgdGhhdCBzdGFuZHMgb3V0IGlzIHRoYXQgdG9waWNzIDEgYW5kIDIgaGF2ZSBhIHBlYWsgYmV0d2VlbiBNYXJjaCBhbmQgTWF5LCBiZWNhdXNlIHRoYXTigJlzIHdoZW4gQ09WSUQxOSByZWFjaGVkIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGlzIGNhdXNlZCBjb25jZXJuIGFib3V0IHRoZSBlZmZlY3QgdGhhdCB0aGUgcGFuZGVtaWMgY291bGQgaGF2ZSBvbiB0aGUgZWNvbm9teSwgd2hpY2ggaXMgdGhlIHJlYXNvbiB3aHkgdGhlIHBlcmNlbnRhZ2Ugb2YgdG9waWMgMiAoZWNvbm9teSkgYWxzbyBpbmNyZWFzZWQuDQoNCk9uIHRoZSBvdGhlciBoYW5kLCB0b3BpYyA2LCBOb3J0aCBBbWVyaWNhbiBwb2xpdGljcywgaGFzIGEgcHJlZG9taW5hbmNlIGluIHRoZSBtb250aHMgb2YgT2N0b2JlciwgTm92ZW1iZXIgYW5kIERlY2VtYmVyIGR1ZSB0byB0aGUgcHJlc2lkZW50aWFsIGVsZWN0aW9ucyBhbmQgRG9uYWxkIFRydW1wJ3MgcmVmdXNhbCB0byBhY2NlcHQgdGhlIHJlc3VsdHMgb2YgdGhlc2UuIFRoZSBhc3Nhc3NpbmF0aW9uIG9mIFFhc3NlbSBTdWxlaW1hbmkgKGFuIElyYW5pYW4gbWlsaXRhcnkgb2ZmaWNlciwgd2hvIHdhcyBhIG1lbWJlciBvZiB0aGUgSXNsYW1pYyBSZXZvbHV0aW9uYXJ5IEd1YXJkIENvcnBzKSBpbiBKYW51YXJ5IDIwMjAgaXMgd2hhdCBjYXVzZXMgdGhlIHRvcGljIG9mIGludGVybmF0aW9uYWwgcmVsYXRpb25zIHRvIHBlYWsgaW4gdGhhdCBtb250aC4gVGhlcmUgaXMgYW5vdGhlciBzbWFsbCBwZWFrIGluIEp1bHkgZHVlIHRvIGEgc2VyaWVzIG9mIGV2ZW50cyByZWxhdGVkIHRvIENoaW5lc2UgaW50ZXJuYXRpb25hbCBwb2xpdGljcy4NCg0KRmlyc3QsIElyYW4gYW5ub3VuY2VkIHRoYXQgaXQgd2FzIG5lZ290aWF0aW5nIGEgYmlsYXRlcmFsIGFncmVlbWVudCB3aXRoIENoaW5hIHRoYXQgaW5jbHVkZWQgYXJlYXMgc3VjaCBhczogdHJhZGUsIGVuZXJneSwgaW5mcmFzdHJ1Y3R1cmUsIHRlbGVjb21tdW5pY2F0aW9ucyBhbmQgZXZlbiBtaWxpdGFyeSBjb29wZXJhdGlvbi4gU2Vjb25kLCB0aGUgVUsgZGVjaWRlZCB0byBiYW4gSHVhd2VpIGZyb20gaXRzIDVHIG5ldHdvcmsuIFRoaXJkLCB0aGUgZGVjaXNpb24gdG8gaW1wb3NlIGEgbmF0aW9uYWwgc2VjdXJpdHkgbGF3IGluIEhvbmcgS29uZy4gRm91cnRoLCB0aGUgYmlsYXRlcmFsIHRlbnNpb25zIHRoYXQgZm9sbG93ZWQgYW4gYXJtZWQgY29uZnJvbnRhdGlvbiBiZXR3ZWVuIENoaW5hIGFuZCBJbmRpYSBpbiB0aGUgTGFkYWtoIHJlZ2lvbiwgd2hpY2ggcmVzdWx0ZWQgaW4gdGhlIGRlYXRoIG9mIHNvbGRpZXJzIGZyb20gYm90aCBzaWRlcy4NCg0KVG9waWMgOCwgUnVzc2lhIGFuZCBFYXN0ZXJuIEV1cm9wZSwgcGVha2VkIGluIEF1Z3VzdCBkdWUgdG8gdGhlIHByb3Rlc3RzIHRoYXQgb2NjdXJyZWQgYWZ0ZXIgdGhlIEJlbGFydXNpYW4gcHJlc2lkZW50IGFubm91bmNlZCB0aGF0IGhlIGhhZCB3b24gdGhlIHByZXNpZGVuY2lhbCBlbGVjdGlvbiB3aXRoIDgwJSBvZiB0aGUgdm90ZXMuIFRoZSBvdGhlciBwZWFrIG9jY3VycmVkIGluIEZlYnJ1YXJ5IGJlY2F1c2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGF0IG1vbnRoIHRoZSBmaXJzdCAqaW1wZWFjaG1lbnQqIG9mIERvbmFsZCBUcnVtcCBjb25jbHVkZWQuIFRoZSAqaW1wZWFjaG1lbnQqIHdhcyBjYXJyaWVkIG91dCBpbiByZXNwb25zZSB0byB0aGUgVHJ1bXAtVWtyYWluZSBzY2FuZGFsLCBUcnVtcCwgYWxsZWdlZGx5LCBwcmVzc3VyZWQgdGhlIFVrcmFpbmlhbiBnb3Zlcm5tZW50IHRvIGludmVzdGlnYXRlIEh1bnRlciBCaWRlbiwgdGhlIHNvbiBvZiB0aGVuLXByZXNpZGVudGlhbCBjYW5kaWRhdGUgSm9lIEJpZGVuLg0KDQpUb3BpYyAzLCBzdXN0YWluYWJpbGl0eSwgcGVha2VkIGluIFNlcHRlbWJlciBkdWUgdG8gYW4gZXZlbnQgY2FsbGVkICpUaGUgR3JlZW4gUmVjb3ZlcnkqLCBhY2NvcmRpbmcgdG8gUHJvamVjdCBTeW5kaWNhdGUgdGhpcyB3YXMgYSAqInZpcnR1YWwgc3VzdGFpbmFiaWxpdHkgZXZlbnQiKiB3aGljaCB3YXMgYnJvYWRjYXN0ZWQgbGl2ZSBpbiBTZXB0ZW1iZXIgb2YgMjAyMC4gUG9zc2libHkgdGhlcmUgd2VyZSBhIG51bWJlciBvZiBjb2x1bW5zIHB1Ymxpc2hlZCB0aGF0IG1vbnRoIHRoYXQgd2VyZSBsaW5rZWQgdG8gdGhlIGV2ZW50LiBUaGUgZmlyc3QgZGF5IG9mIHRoZSBldmVudCBjYW4gYmUgc2VlbiBbaGVyZV0oaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1ZRk1OMkRBX05oSSZhYl9jaGFubmVsPVByb2plY3RTeW5kaWNhdGUpDQoNCg0KDQojIyBTZW50aW1lbnQgQW5hbHlzaXMNCg0KQSBzZW50aW1lbnQgYW5hbHlzaXMgd2FzIHBlcmZvcm1lZCB1c2luZyB0aGUgYHNlbnRpbWVudFJgIHBhY2thZ2UuIEZpcnN0LCBhIHBvbGFyaXR5IGFuYWx5c2lzIHdhcyBjYXJyaWVkIG91dCwgbmVnYXRpdmUgZmVlbGluZ3MgdmVyc3VzIHBvc2l0aXZlIGZlZWxpbmdzLiBUaGUgc2VudGltZW50UiBwYWNrYWdlIGNhbGN1bGF0ZXMgdGhlIGZlZWxpbmdzIHdpdGhpbiBlYWNoIGFydGljbGUgYW5hbHlzaW5nIGFsbCB0aGUgc2VudGVuY2VzIGZyb20gdGhlIHRleHQuIFRoZSBzcGVjaWZpYyB3YXkgaW4gd2hpY2ggYSBzY29yZSBpcyBhc3NpZ25lZCB0byBhbiBhcnRpY2xlIGNhbiBiZSByZXZpZXdlZCBpbiB0aGlzIFtsaW5rXShodHRwczovL2dpdGh1Yi5jb20vdHJpbmtlci9zZW50aW1lbnRyKS4gVGhlIGltcG9ydGFudCB0aGluZyBpcyB0byBrbm93IHRoYXQgcG9zaXRpdmUgdmFsdWVzIGNvcnJlc3BvbmQgdG8gcG9zaXRpdmUgZmVlbGluZ3MgYW5kIG5lZ2F0aXZlIHZhbHVlcyBjb3JyZXNwb25kIHRvIG5lZ2F0aXZlIGZlZWxpbmdzLiBXZSBjYWxjdWxhdGVkIHRoZSBhdmVyYWdlIHNlbnRpbWVudCBzY29yZSBvZiB0aGUgYXJ0aWNsZXMgYnkgbW9udGgsIHRoZXNlIGFyZSB0aGUgcmVzdWx0cyB3ZSBmb3VuZDoNCg0KYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuNX0NCg0KcG9sYXJpZGFkICU+JSBncm91cF9ieSh0aXRsZSxkYXRlMikgJT4lIA0KICBzdW1tYXJpemUoYXZnX3NlbnRpbWVudD1tZWFuKHNlbnRpbWVudCkpICU+JSBncm91cF9ieShtb250aD1mbG9vcl9kYXRlKGRhdGUyLCAibW9udGgiKSkgJT4lIA0KICBzdW1tYXJpemUoYXZnX3NlbnRpbWVudD1tZWFuKGF2Z19zZW50aW1lbnQpKSAlPiUgDQogIHBsb3RfbHkoIHggPSB+bW9udGgpICU+JSBhZGRfdHJhY2UoeSA9IH5hdmdfc2VudGltZW50LCBuYW1lID0gJ3RyYWNlIDAnLG1vZGUgPSAnbGluZXMnKSU+JSANCiAgbGF5b3V0KHRpdGxlID0gIlNlbnRpbWVudCBBbmFseXNpcyAoUG9sYXJpdHkpIDIwMjAiKQ0KYGBgDQoNClRoZSBmaXJzdCB0aGluZyB0aGF0IHN0YW5kcyBvdXQgaXMgdGhlIGNsZWFyIGVmZmVjdCB0aGUgcGFuZGVtaWMgaGFkIGhhZCBvbiB0aGUgZmVlbGluZ3Mgb2YgUHJvamVjdCBTeW5kaWNhdGUgY29sdW1uaXN0cy4gVGhlIHNjb3JlIHdhcyBuZWdhdGl2ZSBmcm9tIE1hcmNoIHRvIE1heS4gQW5vdGhlciBvY2Nhc2lvbiB3aGVuIHRoZSBzY29yZSBkcm9wcGVkIHdhcyBpbiBPY3RvYmVyIGR1ZSB0byB0aGUgcHJlc2lkZW50aWFsIGVsZWN0aW9ucyBpbiB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgc3BlY2lmaWNhbGx5IGR1ZSB0byBEb25hbGQgVHJ1bXAncyByZWZ1c2FsIHRvIGFjY2VwdCB0aGUgcmVzdWx0cy4gVGhlIHNlY29uZCB0aGluZyB0aGF0IHdhcyBhbmFseXplZCB3ZXJlIGVtb3Rpb25zLCBub3QganVzdCBwb2xhcml0eSwgaW4gb3JkZXIgdG8gc2VlIHNwZWNpZmljYWxseSB3aGF0IGhhcHBlbmVkLCBoZXJlIGlzIGEgZ3JhcGggd2l0aCB0aGUgcmVzdWx0cy4NCg0KDQpgYGB7cixlY2hvPUZBTFNFLCBmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuMiwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuYWxpZ24gPSAnY2VudGVyJ30NCg0KdHJ1c3Q8LWVtb2Npb25lcyAlPiUgDQogIGdyb3VwX2J5KG1vbnRoPWZsb29yX2RhdGUoZGF0ZTIsICJtb250aCIpLGVtb3Rpb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpemUoYXZlX2Vtb3Rpb249bWVhbihhdmVfZW1vdGlvbikpJT4lIA0KICBmaWx0ZXIoZW1vdGlvbl90eXBlPT0idHJ1c3QiKSAlPiUgc2VsZWN0KGF2ZV9lbW90aW9uKQ0KDQpzYWRuZXNzPC1lbW9jaW9uZXMgJT4lIA0KICBncm91cF9ieShtb250aD1mbG9vcl9kYXRlKGRhdGUyLCAibW9udGgiKSxlbW90aW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXplKGF2ZV9lbW90aW9uPW1lYW4oYXZlX2Vtb3Rpb24pKSU+JSANCiAgZmlsdGVyKGVtb3Rpb25fdHlwZT09InNhZG5lc3MiKSAlPiUgc2VsZWN0KGF2ZV9lbW90aW9uKQ0KDQphbnRpY2lwYXRpb248LWVtb2Npb25lcyAlPiUgDQogIGdyb3VwX2J5KG1vbnRoPWZsb29yX2RhdGUoZGF0ZTIsICJtb250aCIpLGVtb3Rpb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpemUoYXZlX2Vtb3Rpb249bWVhbihhdmVfZW1vdGlvbikpJT4lIA0KICBmaWx0ZXIoZW1vdGlvbl90eXBlPT0iYW50aWNpcGF0aW9uIikgJT4lIHNlbGVjdChhdmVfZW1vdGlvbikNCg0KZGlzZ3VzdDwtZW1vY2lvbmVzICU+JSANCiAgZ3JvdXBfYnkobW9udGg9Zmxvb3JfZGF0ZShkYXRlMiwgIm1vbnRoIiksZW1vdGlvbl90eXBlKSAlPiUgDQogIHN1bW1hcml6ZShhdmVfZW1vdGlvbj1tZWFuKGF2ZV9lbW90aW9uKSklPiUgDQogIGZpbHRlcihlbW90aW9uX3R5cGU9PSJkaXNndXN0IikgJT4lIHNlbGVjdChhdmVfZW1vdGlvbikNCg0KZmVhcjwtZW1vY2lvbmVzICU+JSANCiAgZ3JvdXBfYnkobW9udGg9Zmxvb3JfZGF0ZShkYXRlMiwgIm1vbnRoIiksZW1vdGlvbl90eXBlKSAlPiUgDQogIHN1bW1hcml6ZShhdmVfZW1vdGlvbj1tZWFuKGF2ZV9lbW90aW9uKSklPiUgDQogIGZpbHRlcihlbW90aW9uX3R5cGU9PSJmZWFyIikgJT4lIHNlbGVjdChhdmVfZW1vdGlvbikNCg0Kam95PC1lbW9jaW9uZXMgJT4lIA0KICBncm91cF9ieShtb250aD1mbG9vcl9kYXRlKGRhdGUyLCAibW9udGgiKSxlbW90aW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXplKGF2ZV9lbW90aW9uPW1lYW4oYXZlX2Vtb3Rpb24pKSU+JSANCiAgZmlsdGVyKGVtb3Rpb25fdHlwZT09ImpveSIpICU+JSBzZWxlY3QoYXZlX2Vtb3Rpb24pDQoNCnN1cnByaXNlPC1lbW9jaW9uZXMgJT4lIA0KICBncm91cF9ieShtb250aD1mbG9vcl9kYXRlKGRhdGUyLCAibW9udGgiKSxlbW90aW9uX3R5cGUpICU+JSANCiAgc3VtbWFyaXplKGF2ZV9lbW90aW9uPW1lYW4oYXZlX2Vtb3Rpb24pKSU+JSANCiAgZmlsdGVyKGVtb3Rpb25fdHlwZT09InN1cnByaXNlIikgJT4lIHNlbGVjdChhdmVfZW1vdGlvbikNCg0KYW5nZXI8LWVtb2Npb25lcyAlPiUgDQogIGdyb3VwX2J5KG1vbnRoPWZsb29yX2RhdGUoZGF0ZTIsICJtb250aCIpLGVtb3Rpb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpemUoYXZlX2Vtb3Rpb249bWVhbihhdmVfZW1vdGlvbikpJT4lIA0KICBmaWx0ZXIoZW1vdGlvbl90eXBlPT0iYW5nZXIiKSAlPiUgc2VsZWN0KGF2ZV9lbW90aW9uKQ0KDQpmZWNoYTwtdHJ1c3QgJT4lIHNlbGVjdChtb250aCkNCg0KZGF0YSA8LSBkYXRhLmZyYW1lKGZlY2hhLCB0cnVzdCwgc2FkbmVzcyxhbnRpY2lwYXRpb24sZGlzZ3VzdCxmZWFyLGpveSxzdXJwcmlzZSxhbmdlcikNCg0KcGxvdF9seShkYXRhLCB4ID0gfm1vbnRoKSAlPiUgYWRkX3RyYWNlKHkgPSB+YXZlX2Vtb3Rpb24sIG5hbWUgPSAnVHJ1c3QnLG1vZGUgPSAnbGluZXMnKSU+JSANCiAgbGF5b3V0KHRpdGxlID0gIlNlbnRpbWVudCBBbmFseXNpcyAoUG9sYXJpdHkpIDIwMjAiKSU+JSANCiAgYWRkX3RyYWNlKHkgPSB+YXZlX2Vtb3Rpb24uMSwgbmFtZSA9ICdTYWRuZXNzJyxtb2RlID0gJ2xpbmVzJykgJT4lICANCiAgYWRkX3RyYWNlKHkgPSB+YXZlX2Vtb3Rpb24uMiwgbmFtZSA9ICdBbnRpY2lwYXRpb24nLG1vZGUgPSAnbGluZXMnKSAlPiUgIA0KICBhZGRfdHJhY2UoeSA9IH5hdmVfZW1vdGlvbi4zLCBuYW1lID0gJ0Rpc2d1c3QnLG1vZGUgPSAnbGluZXMnKSAlPiUgIA0KICBhZGRfdHJhY2UoeSA9IH5hdmVfZW1vdGlvbi40LCBuYW1lID0gJ0ZlYXInLG1vZGUgPSAnbGluZXMnKSAlPiUgIA0KICBhZGRfdHJhY2UoeSA9IH5hdmVfZW1vdGlvbi41LCBuYW1lID0gJ0pveScsbW9kZSA9ICdsaW5lcycpICU+JSAgDQogIGFkZF90cmFjZSh5ID0gfmF2ZV9lbW90aW9uLjYsIG5hbWUgPSAnU3VycHJpc2UnLG1vZGUgPSAnbGluZXMnKSU+JSAgDQogIGFkZF90cmFjZSh5ID0gfmF2ZV9lbW90aW9uLjcsIG5hbWUgPSAnQW5nZXInLG1vZGUgPSAnbGluZXMnKSU+JSANCiAgbGF5b3V0KHRpdGxlID0gIlNlbnRpbWVudCBBbmFseXNpcyBCeSBFbW90aW9ucyAyMDIwIikNCg0KYGBgDQoNCg0KV2l0aCB0aGUgYXJyaXZhbCBvZiBDT1ZJRCB0byB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgRXVyb3BlLCBlbW90aW9ucyBzdWNoIGFzIGZlYXIgYW5kIHNhZG5lc3MgaW5jcmVhc2VkLiBJdCBzZWVtcyB0aGF0IHNhZG5lc3MgaGFzIGEgbG9uZ2VyIHBlYWssIHJlbWFpbmluZyBzdGFibGUgdW50aWwgTWF5LiBXaGlsZSBjb25maWRlbmNlLCBoYXBwaW5lc3MsIGFuZCBhbnRpY2lwYXRpb24gaW5jcmVhc2VkLSBtYWlubHkgZHVlIHRvIHRoZSBleHBlY3RhdGlvbnMgZ2VuZXJhdGVkIGJ5IEpvZSBCaWRlbuKAmXMgdmljdG9yeSAtIFRydW1w4oCZcyByZWZ1c2FsIHRvIGFjY2VwdCB0aGUgcmVzdWx0cyBjYXVzZWQgZmVlbGluZ3Mgb2YgYW5nZXIsIHNhZG5lc3MgYW5kIGZlYXIgdG8gYWxzbyBpbmNyZWFzZWQuDQoNCiMjIEZpbmFsIHRob3VnaHRzDQoNClRoaXMgZXhwbG9yYXRvcnkgYW5hbHlzaXMgc2hlZHMgc29tZSBsaWdodCBvbiB0aGUgbmV3cyBldmVudHMgb2YgMjAyMC4gSXQgaXMgZmFzY2luYXRpbmcgdG8gc2VlIHRoZSBlZmZlY3RzIG9mIHRoZSBtb3N0IGRlZmluaW5nIGV2ZW50cyBvZiB0aGUgeWVhciBoYWQ6IHRoZSBQYW5kZW1pYyBhbmQgdGhlIE5vcnRoIEFtZXJpY2FuIGVsZWN0aW9ucywgYm90aCBpbiB0b3BpYyBtb2RlbGluZyBhbmQgc2VudGltZW50IGFuYWx5c2lzLg0KDQpMb29raW5nIGF0IHRoZSBtb3N0IGltcG9ydGFudCBldmVudHMgb2YgdGhlIGJlZ2lubmluZyBvZiB0aGUgeWVhciwgSSBuZWVkIHRvIG1lbnRpb24gdGhlIGFzc2Fzc2luYXRpb24gb2YgUWFzc2VtIFNvbGVpbWFuaSBhbmQgdGhlIGltcGVhY2htZW50IG9mIERvbmFsZCBUcnVtcC4gV2l0aCB0aGUgYXJyaXZhbCBvZiBDT1ZJRCB0byB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgRXVyb3BlLCBldmVyeXRoaW5nIGNoYW5nZWQuIFRoZSBhZ2VuZGEgd2FzIGRvbWluYXRlZCBieSB0aGlzIHRvcGljIGFuZCBieSB0aGUgZWNvbm9taWMgY29uc2VxdWVuY2VzIHRoYXQgdGhlIHBhbmRlbWljIHdhcyBnb2luZyB0byBoYXZlLiBUb3dhcmRzIHRoZSBlbmQgb2YgdGhlIHllYXIgdGhlIFVTIHByZXNpZGVudGlhbCBlbGVjdGlvbnMgYW5kIERvbmFsZCBUcnVtcCdzIHN1YnNlcXVlbnQgcmVmdXNhbCB0byBhY2NlcHQgaGlzIGRlZmVhdCBjYW1lIHRvIHRoZSBmb3JlLg0KDQpGaW5hbGx5LCBpbiB0aGUgc2VudGltZW50cyBhbmFseXNpcyBhbmQgaW4gdGhlIHRvcGljIG1vZGVsaW5nIHRoZXJlIGlzIHJvb20gZm9yIGltcHJvdmVtZW50LiBGaXJzdCBvZiBhbGwsIHRoZSBkaWN0aW9uYXJpZXMgb2Ygc2VudGltZW50IGFuZCBlbW90aW9ucyBjYW4gYmUgYmV0dGVyIGFkYXB0ZWQgdG8gaGF2ZSBtb3JlIGFkZXF1YXRlIHJlc3VsdHMuIEZ1cnRoZXJtb3JlLCBpdCBpcyBwb3NzaWJsZSB0byBhZGQgbW9yZSB0b3BpY3MgdG8gYmV0dGVyIHVuZGVyc3RhbmQgd2hpY2ggd2VyZSB0aGUgdG9waWNzIHRoYXQgd2VyZSBwcmVzZW50IG9uIHB1YmxpYyBkaXNjdXNzaW9uIGluIDIwMjAuDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K