Introduction

This section will cover basic aspects of data manipulation, such as recoding a variable, selecting data, and calculating a new variable. At the end, there is a note about the statistical calculations considering the design effect.

About the AmericasBarometer datasets

The data that we are going to use should be cited as follows: Source: AmericasBarometer by the Latin American Public Opinion Project (LAPOP), wwww.LapopSurveys.org.

In this section a dataset is loaded. This dataset is hosted in the “materials_edu” repository of LAPOP’s GitHub account. Through the library rio and the command import, this database can be imported from this repository, using the following code. The dataset is imported into the object “lapop21”. This dataset has an extension .RData and when it is imported, variables are defined as type double (“dbl”), which is a type of variable that allows decimals, different from type integer, “int”, that only accept integers.

library(rio)
lapop21 = import("https://raw.github.com/lapop-central/materials_edu/main/lapop21.RData")

The dataset for the previous round of the AmericasBarometer is also in this repository. We can load and call it “lapop18”. It is necessary to clarify that this dataset, imported from a SPSS file, loads variables as type numeric (“num”).

lapop18 = import("https://raw.github.com/lapop-central/materials_edu/main/LAPOP_AB_Merge_2018_v1.0.sav")

Recoding a variable

In this section we will use the report “The Pulse of Democracy” that presents the results for the 2021 round of the AmericasBarometer, available here. This report presents the results on support for democracy in the Americas. These results are based on the variable called ING4 in the dataset. This variable is worded as follows:

ING4. Changing the subject again, democracy may have problems, but it is better than any other form of government. To what extent do you agree or disagree with this statement?

This variable is measured in a 1-7 scale, where 1 means “strongly disagree” and 7 means “strongly agree”. Then, values from 5 to 7 are recoded as support for democracy. To see the distribution of responses to this variable, you can use the table command.

table(lapop21$ing4)
## 
##     1     2     3     4     5     6     7 
##  5704  2567  4980  8177 13886  8390 16759

In this way, the observations (absolute frequencies) are calculated for each value of the variable. To calculate the percentage of people who support democracy, we have to recode this variable and create a new one. It means that the original ING4, in a 1-7 scale, has to be recoded in a new variable following this rule:

  1. Values between 1-4 of ING4 become 0 in a new variable ing4r
  2. Values between 5-7 of ING4 become 1 in a new variable ing4r

An example of how this recoded data is presented in the report can be seen in Graph 1.1. This shows the percentage of citizens who support democracy by country. That is, the percentage of respondents who answered between 5 and 7 to the ING4 question in each country is shown. According to the recoding, this graph would represent the percentage of respondents who register a 1 in the recoded variable.

In the report The Pulse of Democracy for the 2018/19 round, available here, it is presented a similar figure, using the same variable and the same rule for recoding.

To recode a variable in R there are several ways. One of the most efficient ways to do this is by using the command recode from the car package. The dplyr package has also a recode command that can confuse R. To avoid confusion we will specify in the syntax car::recode recoding. The recoded variable is recorded as “lapop21$ing4rec”. Then, the command table is used to describe this new variable.

library(car)
lapop21$ing4rec <- car::recode(lapop21$ing4, "1:4=0; 5:7=1")
table(lapop21$ing4rec)
## 
##     0     1 
## 21428 39035

If the observations between 1 and 4 of the original variable are added (1699 + 1470 + 3003 + 6089), we see that it is the result equals the observations in value 0 of the new variable (12261), as it was written in the recoding. It should also be noted that the dataset in the Environment now has one more variable, totaling 1826 variables.

Selection of observations

The Figure 1.1 shows that support for democracy goes from a high of 80% in Uruguay to a low of 46% in Haiti. To replicate result corresponding to Uruguay, we can select observations from this country. According to codification of variable “pais”, Uruguay is coded as 14.

Selection of observations in R can be done in several ways. One way is to use brackets. Other way is to use the command subset. With this command, we select observations from this country and we save this selection in a new dataframe “lapop1”. We have 3009 observations in Uruguay and 1826 variables.

lapop1 = subset(lapop21, pais==14)
table(lapop1$pais)
## 
##   14 
## 3009

With this selection of data, you can calculate the percentages (relative frequencies) using the command prop.table. This command gives us the relative frequencies (in values between 0 and 1) of a frecuency table calculated with table. These relative frequencies are multiplied by 100 to reproduce the percentage in each country. In this case, the brackets […] are used to make the selection of cases from each country.

prop.table(table(lapop1$ing4rec[lapop1$pais==14]))*100
## 
##        0        1 
## 15.47499 84.52501

These results are percentages (between 0 and 100), but include many decimal places. To round to one decimal, as shown in Graph 1.2, you can use the command round, where all the previous syntax is nested. In this command, you have to specify the number of decimal places you want, which in this case is 1.

round(prop.table(table(lapop1$ing4rec[lapop1$pais==14]))*100, 1)
## 
##    0    1 
## 15.5 84.5

According to this result, 84.5% of Uruguayans support democracy. This result is different from what it is reported in Figure 1.1, where reported value is 80%. This difference is due to the fact that our procedures do not include the effect of complex design features, such as weights, stratification, and cluster sampling. Below, we present procedures to reproduce precise reported results.

The report for the 2018/19 wave indicates “Figure 1.2 displays the percent of individuals in each country that expresses support for democracy in 2018/19. Support for democracy ranges from a low of 45% in Honduras to a high of 76.2% in Uruguay.” (p. 11).

For replicating these results about Honduras and Uruguay for the 2018/19 round, we can select observations for these two countries. According to the questionnaire, available HERE, Honduras is coded as 4 and Uruguay as 14 in variable “pais”, that is imported as a numeric variable.

We include the operator “or”, that is written as “|” in R. In this way, we can select observations from Honduras or Uruguay using pais==4 | pais==14. The description of variable “pais” shows that it includes only observations for Honduras (2) and Uruguay (14).

lapop2 = subset(lapop18, pais==4 | pais==14)
table(lapop2$pais)
## 
##    4   14 
## 1560 1581

The new dataframe “lapop2” has 3141 observations and 84 variables. It does not include a recoded variable for support for democracy. We proceed to include it.

lapop2$ing4rec <- car::recode(lapop2$ing4, "1:4=0; 5:7=1")

With this variable, we can follow the same procedures as before: produce a relative frequency table.

prop.table(table(lapop2$ing4rec[lapop2$pais==4]))*100
## 
##        0        1 
## 54.98995 45.01005
prop.table(table(lapop2$ing4rec[lapop2$pais==14]))*100
## 
##        0        1 
## 23.80641 76.19359

And then, we include rounding.

round(prop.table(table(lapop2$ing4rec[lapop2$pais==4]))*100, 1)
## 
##  0  1 
## 55 45
round(prop.table(table(lapop2$ing4rec[lapop2$pais==14]))*100, 1)
## 
##    0    1 
## 23.8 76.2

With this code, we have reproduced results for countries in the extremes of Figure 1.2. In this case, results are similar to the ones reported in the figure in the report.

Both reports also indicate that the United States and Canada are excluded from the calculations. The dataset loaded as “lapop18” includes all the countries in the round. To exclude these two countries, we have to select the countries that are NOT USA and Canada. This new selection can be saved in a new dataframe or it can be overwritten in the original dataframe, as it is done in this case because the exclusion of these countries is for all the calculations that follow. According to the questionnaire, USA has the code 40 and Canada, the code 41 in the variable “pais”. To exclude them, countries with a code of less than 40 (or 35 or less) must be included. For this we can again use the subset command.

lapop18 <- subset(lapop18, pais<=35)

It can be observed in the Environment that the observations of the “lapop18” dataframe are reduced after running this code, since the observations of repondents in these two countries have been eliminated. The number of observations goes from 31,050 to 28,042, a number that coincides with that of the dataset in .RData format that we used in the previous module and that we indicated that it did not include these countries.

In the same way, we can proceed in the 2021 wave dataset. After this, observations decrease to 60,661.

lapop21 = subset(lapop21, pais<=35)

Calculating a variable

A frequent LAPOP practice with the AmericasBarometer data is the rescaling of variables. The report’s chapter on democratic legitimacy provides examples of this rescaling with variables related to support for the system. To calculate this index for system support, we work with a set of five variables:

B1. To what extent do you think the courts of (country) guarantee a fair trial? . To what extent do you respect the political institutions of (country)?

B2. To what extend do you respect the political institutions of (country)?

B3. To what extent do you think the basic rights of the citizen are well protected by the political system of (country)?

B4. To what extent are you proud to live under the political system of (country)?

B6. To what extent do you think the political system of (country) should be supported?

As the report indicates “For each question, the original scale from 1 (” Not at all “) to 7 (”A lot”) is recoded on a 0-100 scale, in such a way that 0 indicates the lowest level of support for the political system and 100 is the highest level of support for the political system. This new scale follows the typical LAPOP recoding and can be interpreted as a measure of support in units, or degrees, on a continuous scale ranging from 0 to 100” (p. 34). To check the original scale of these variables, we can describe these variables using the table command.

table(lapop18$b1)
## 
##    1    2    3    4    5    6    7 
## 4089 4067 5881 6137 4215 1631 1371
table(lapop18$b2)
## 
##    1    2    3    4    5    6    7 
## 2861 2152 2998 4153 5182 4448 5679
table(lapop18$b3)
## 
##    1    2    3    4    5    6    7 
## 5080 4096 5153 5349 4219 2061 1491
table(lapop18$b4)
## 
##    1    2    3    4    5    6    7 
## 5095 3206 3743 4557 4326 3041 3584
table(lapop18$b6)
## 
##    1    2    3    4    5    6    7 
## 3713 2325 2971 4277 4616 3868 5572

It is observed that all the variables run on a scale from 1 to 7. To rescale a variable from an original scale from 1 to 7 to another from 0 to 100, the first thing to do is subtract 1 unit, so the variable would have a scale of 0 to 6, then divide it by 6, with which would vary between 0 and 1 and, finally, multiply it by 100. this is:

Rescaled variable = ((original variable -1)/6)*100

lapop18$b1rec <- ((lapop18$b1-1)/6)*100
lapop18$b2rec <- ((lapop18$b2-1)/6)*100
lapop18$b3rec <- ((lapop18$b3-1)/6)*100
lapop18$b4rec <- ((lapop18$b4-1)/6)*100
lapop18$b6rec <- ((lapop18$b6-1)/6)*100
table(lapop18$b1rec)
## 
##                0 16.6666666666667 33.3333333333333               50 
##             4089             4067             5881             6137 
## 66.6666666666667 83.3333333333333              100 
##             4215             1631             1371

With this transformation, it is observed that the 4,089 interviewees who scored 1 in question B1 now have a score of 0. The 4,067 who scored 2 now have a score of 16.67, that is 2-1=1/6=0.1667*100=16.67. This same operation could be done with the car :: recode command, following this recoding rule:

  • Value of 1 in original variable is recoded as 0 in new variable
  • Value of 2 in original variable is recoded as 16.67 in new variable
  • Value of 3 in original variable is recoded as 33.33 in new variable
  • Value of 4 in original variable is recoded as 50 in new variable
  • Value of 5 in original variable is recoded as 66.67 in new variable
  • Value of 6 in original variable is recoded as 83.33 in new variable
  • Value of 7 in original variable is recoded as 100 in new variable

This way of recoding, however, is not very efficient. It is simpler to use the formula to calculate the recoding. To calculate the system support index, the report indicates that “The system support index is the average of five questions: B1, B2, B3, B4 and B6” (p.46). In other words, with the rescaled variables, the average of these five variables has to be calculated for each individual (that is, in each row of the dataset). This could be done by calculating the average manually.

System support = (b1rec + b2rec + b3rec + b4rec + b6rec)/5

In R we have the command rowMeans that is used to calculate averages of certain columns for each row. The syntax [, 86:90] indicates that the average calculation will be performed by rows for all rows and using columns 86 to 90 of the “lapop18” dataframe (the calculation could be done for some particular rows by defining [ row_n: row_m, 86:90]). This average is saved in a new variable “support”, which is described.

lapop18$apoyo = rowMeans(lapop18[,85:89])
table(lapop18$apoyo)
## 
##                0 3.33333333333333 6.66666666666667               10 
##              634              368              439              525 
## 13.3333333333333 16.6666666666667               20 23.3333333333333 
##              527              550              834              745 
## 26.6666666666667               30 33.3333333333333 36.6666666666667 
##              810              911             1063             1086 
##               40 43.3333333333333 46.6666666666667               50 
##             1287             1317             1254             1487 
## 53.3333333333333 56.6666666666667               60 63.3333333333333 
##             1397             1408             1449             1243 
## 66.6666666666667               70 73.3333333333333 76.6666666666667 
##             1227             1113              988              827 
##               80 83.3333333333333 86.6666666666667               90 
##              820              572              445              369 
## 93.3333333333333 96.6666666666667              100 
##              245              131              210

With this index, it is possible to calculate the average support for the system for the last round of the AmericasBarometer, as well as the averages for each of the variables that are included in the index. The mean command is used for the average and the na.rm = T specification is used to tell the command not to take into account the missing values of these variables. These statistics will be seen in more detail in other documents.

mean(lapop18$apoyo, na.rm=T) #system support
## [1] 48.79419
mean(lapop18$b1rec, na.rm=T) #courts guarantee fair trial
## [1] 41.06032
mean(lapop18$b2rec, na.rm=T) #Respect for institutions
## [1] 59.23937
mean(lapop18$b3rec, na.rm=T) #Basic rights are protected
## [1] 40.42406
mean(lapop18$b4rec, na.rm=T) #Pride in the political system
## [1] 47.41096
mean(lapop18$b6rec, na.rm=T) #The political system should be supported
## [1] 56.28337

These results are those shown in Figure 2.1 for the 2018/19 round.

Condicionally calculating a variable

Sometimes the calculation of a variable does not only require the numerical transformation of the original variable, but the values of the new variable depend on the values of other variables. For example, the chapter “Social networks and political attitudes” of the report “The Pulse of Democracy” presents the results for the variables “WhatsApp user”, “Twitter user” and “Facebook user”. To calculate these variables, footnote 7 of this chapter indicates: “For each platform, we identify users with a combination of two sets of survey questions. First, we identify users as those who respond positively to the questions, SMEDIA1/SMEDIA4/SMEDIA7. Do you have a Facebook/Twitter/WhatsApp account? Then, we recode as non-users those who respond”never” to the follow-up questions, SMEDIA2/SMEDIA5/SMEDIA8. How often do you see content on Facebook/Twitter/WhatsApp?” (p. 64).

That is, the user is not only the one who has an account (SMEDIA1 = 1), but the one who uses it with a certain frequency (SMEDIA2 = 1, 2, 3, 4). In this way, the non-user can have an account, but never use it. Therefore, the variable “user” depends on the values of 2 variables. The rule for coding is:

  • Facebook user = 1 (he/she is a user) if SMEDIA1 = 1 (he/she has an account) and SMEDIA2 <= 4 (he/she uses it with some frequency)

  • Facebook user = 0 (he/she is not a user) if SMEDIA2 = 2 (he/she doesn´t have an account) or SMEDIA2 = 5 ( he/she has an account but never uses it)

This rule transforms into the following R syntax, which uses the command ìfelse. This syntax includes the condition to assign values of 1 to a new variable and assigns all other observations the value of 0. These new variables are described using the table command to generate the absolute frequencies,the prop.table command for the relative frequencies and the round command to round the decimals. These commands will be seen in more detail in the following documents.

lapop18$fb_user <- ifelse(lapop18$smedia1==1 & lapop18$smedia2<=4, 1, 0)
lapop18$tw_user <- ifelse(lapop18$smedia4==1 & lapop18$smedia5<=4, 1, 0)
lapop18$wa_user <- ifelse(lapop18$smedia7==1 & lapop18$smedia8<=4, 1, 0)
round(prop.table(table(lapop18$fb_user))*100, 1)
## 
##    0    1 
## 43.8 56.2
round(prop.table(table(lapop18$tw_user))*100, 1)
## 
##    0    1 
## 92.1  7.9
round(prop.table(table(lapop18$wa_user))*100, 1)
## 
##    0    1 
## 35.8 64.2

These results are those presented in Graph 3.1 of the report in the form of pie charts. These types of graphs will be seen in the next section.

Design effect observation

Both the results for system support and those of social network users differ from those that appear in the report for two reasons. First, about support the system, because “Cross-time values are calculated including only those countries the AmericasBarometer has surveyed consistently since 2006: Argentina, Brazil, Bolivia, Chile, Colombia, Costa Rica , the Dominican Republic, Ecuador, El Salvador, Guatemala, Honduras, Jamaica, Mexico, Nicaragua, Panama, Paraguay, Peru, Uruguay” (p.46). The code only filters the last round, which includes countries that are not on that list, such as the United States or Canada. On the other hand, the calculations reported in the publication include the use of survey weights, which have not been included in these calculations, but which will be incorporated in other documents (see here).

Summary

In this document we have seen the basic elements of data manipulation and transformation using the AmericasBarometer datasets. A variable has been recoded using the recode command, cases have been selected using subset and a new variable has been calculated algebraically and with the ifelse command.

LS0tCnRpdGxlOiAiRGF0YSBtYW5pcHVsYXRpb24gdXNpbmcgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGRhdGEiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgI2NvZGVfZm9sZGluZzogaGlkZQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRSkKYGBgCgpgYGB7Y3NzIGNvbG9yLCBlY2hvPUZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTogZmxleDt9CmgxIHtjb2xvcjogIzMzNjZDQzt9CmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgc2VjdGlvbiB3aWxsIGNvdmVyIGJhc2ljIGFzcGVjdHMgb2YgZGF0YSBtYW5pcHVsYXRpb24sIHN1Y2ggYXMgcmVjb2RpbmcgYSB2YXJpYWJsZSwgc2VsZWN0aW5nIGRhdGEsIGFuZCBjYWxjdWxhdGluZyBhIG5ldyB2YXJpYWJsZS4KQXQgdGhlIGVuZCwgdGhlcmUgaXMgYSBub3RlIGFib3V0IHRoZSBzdGF0aXN0aWNhbCBjYWxjdWxhdGlvbnMgY29uc2lkZXJpbmcgdGhlIGRlc2lnbiBlZmZlY3QuCgojIEFib3V0IHRoZSBBbWVyaWNhc0Jhcm9tZXRlciBkYXRhc2V0cwoKVGhlIGRhdGEgdGhhdCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHNob3VsZCBiZSBjaXRlZCBhcyBmb2xsb3dzOiBTb3VyY2U6IEFtZXJpY2FzQmFyb21ldGVyIGJ5IHRoZSBMYXRpbiBBbWVyaWNhbiBQdWJsaWMgT3BpbmlvbiBQcm9qZWN0IChMQVBPUCksIHd3d3cuTGFwb3BTdXJ2ZXlzLm9yZy4KCkluIHRoaXMgc2VjdGlvbiBhIGRhdGFzZXQgaXMgbG9hZGVkLgpUaGlzIGRhdGFzZXQgaXMgaG9zdGVkIGluIHRoZSAibWF0ZXJpYWxzX2VkdSIgcmVwb3NpdG9yeSBvZiBMQVBPUCdzIEdpdEh1YiBhY2NvdW50LgpUaHJvdWdoIHRoZSBsaWJyYXJ5IGByaW9gIGFuZCB0aGUgY29tbWFuZCBgaW1wb3J0YCwgdGhpcyBkYXRhYmFzZSBjYW4gYmUgaW1wb3J0ZWQgZnJvbSB0aGlzIHJlcG9zaXRvcnksIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZS4KVGhlIGRhdGFzZXQgaXMgaW1wb3J0ZWQgaW50byB0aGUgb2JqZWN0ICJsYXBvcDIxIi4KVGhpcyBkYXRhc2V0IGhhcyBhbiBleHRlbnNpb24gLlJEYXRhIGFuZCB3aGVuIGl0IGlzIGltcG9ydGVkLCB2YXJpYWJsZXMgYXJlIGRlZmluZWQgYXMgdHlwZSBkb3VibGUgKCJkYmwiKSwgd2hpY2ggaXMgYSB0eXBlIG9mIHZhcmlhYmxlIHRoYXQgYWxsb3dzIGRlY2ltYWxzLCBkaWZmZXJlbnQgZnJvbSB0eXBlIGludGVnZXIsICJpbnQiLCB0aGF0IG9ubHkgYWNjZXB0IGludGVnZXJzLgoKYGBge3IgYmFzZX0KbGlicmFyeShyaW8pCmxhcG9wMjEgPSBpbXBvcnQoImh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vbGFwb3AtY2VudHJhbC9tYXRlcmlhbHNfZWR1L21haW4vbGFwb3AyMS5SRGF0YSIpCmBgYAoKVGhlIGRhdGFzZXQgZm9yIHRoZSBwcmV2aW91cyByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgaXMgYWxzbyBpbiB0aGlzIHJlcG9zaXRvcnkuCldlIGNhbiBsb2FkIGFuZCBjYWxsIGl0ICJsYXBvcDE4Ii4KSXQgaXMgbmVjZXNzYXJ5IHRvIGNsYXJpZnkgdGhhdCB0aGlzIGRhdGFzZXQsIGltcG9ydGVkIGZyb20gYSBTUFNTIGZpbGUsIGxvYWRzIHZhcmlhYmxlcyBhcyB0eXBlIG51bWVyaWMgKCJudW0iKS4KCmBgYHtyIGJhc2UxOH0KbGFwb3AxOCA9IGltcG9ydCgiaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9sYXBvcC1jZW50cmFsL21hdGVyaWFsc19lZHUvbWFpbi9MQVBPUF9BQl9NZXJnZV8yMDE4X3YxLjAuc2F2IikKYGBgCgojIFJlY29kaW5nIGEgdmFyaWFibGUKCkluIHRoaXMgc2VjdGlvbiB3ZSB3aWxsIHVzZSB0aGUgcmVwb3J0ICJUaGUgUHVsc2Ugb2YgRGVtb2NyYWN5IiB0aGF0IHByZXNlbnRzIHRoZSByZXN1bHRzIGZvciB0aGUgMjAyMSByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIsIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDIxLzIwMjFfTEFQT1BfQW1lcmljYXNCYXJvbWV0ZXJfMjAyMV9QdWxzZV9vZl9EZW1vY3JhY3kucGRmKS4KVGhpcyByZXBvcnQgcHJlc2VudHMgdGhlIHJlc3VsdHMgb24gc3VwcG9ydCBmb3IgZGVtb2NyYWN5IGluIHRoZSBBbWVyaWNhcy4KVGhlc2UgcmVzdWx0cyBhcmUgYmFzZWQgb24gdGhlIHZhcmlhYmxlIGNhbGxlZCBJTkc0IGluIHRoZSBkYXRhc2V0LgpUaGlzIHZhcmlhYmxlIGlzIHdvcmRlZCBhcyBmb2xsb3dzOgoKSU5HNC4KKkNoYW5naW5nIHRoZSBzdWJqZWN0IGFnYWluLCBkZW1vY3JhY3kgbWF5IGhhdmUgcHJvYmxlbXMsIGJ1dCBpdCBpcyBiZXR0ZXIgdGhhbiBhbnkgb3RoZXIgZm9ybSBvZiBnb3Zlcm5tZW50LiBUbyB3aGF0IGV4dGVudCBkbyB5b3UgYWdyZWUgb3IgZGlzYWdyZWUgd2l0aCB0aGlzIHN0YXRlbWVudD8qCgpUaGlzIHZhcmlhYmxlIGlzIG1lYXN1cmVkIGluIGEgMS03IHNjYWxlLCB3aGVyZSAxIG1lYW5zICJzdHJvbmdseSBkaXNhZ3JlZSIgYW5kIDcgbWVhbnMgInN0cm9uZ2x5IGFncmVlIi4KVGhlbiwgdmFsdWVzIGZyb20gNSB0byA3IGFyZSByZWNvZGVkIGFzIHN1cHBvcnQgZm9yIGRlbW9jcmFjeS4KVG8gc2VlIHRoZSBkaXN0cmlidXRpb24gb2YgcmVzcG9uc2VzIHRvIHRoaXMgdmFyaWFibGUsIHlvdSBjYW4gdXNlIHRoZSBgdGFibGVgIGNvbW1hbmQuCgpgYGB7ciBkZXNjcmliaW5nIGluZzR9CnRhYmxlKGxhcG9wMjEkaW5nNCkKYGBgCgpJbiB0aGlzIHdheSwgdGhlIG9ic2VydmF0aW9ucyAoYWJzb2x1dGUgZnJlcXVlbmNpZXMpIGFyZSBjYWxjdWxhdGVkIGZvciBlYWNoIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KVG8gY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIHBlb3BsZSB3aG8gc3VwcG9ydCBkZW1vY3JhY3ksIHdlIGhhdmUgdG8gcmVjb2RlIHRoaXMgdmFyaWFibGUgYW5kIGNyZWF0ZSBhIG5ldyBvbmUuCkl0IG1lYW5zIHRoYXQgdGhlIG9yaWdpbmFsIElORzQsIGluIGEgMS03IHNjYWxlLCBoYXMgdG8gYmUgcmVjb2RlZCBpbiBhIG5ldyB2YXJpYWJsZSBmb2xsb3dpbmcgdGhpcyBydWxlOgoKMS4gIFZhbHVlcyBiZXR3ZWVuIDEtNCBvZiBJTkc0IGJlY29tZSAwIGluIGEgbmV3IHZhcmlhYmxlIGluZzRyCjIuICBWYWx1ZXMgYmV0d2VlbiA1LTcgb2YgSU5HNCBiZWNvbWUgMSBpbiBhIG5ldyB2YXJpYWJsZSBpbmc0cgoKQW4gZXhhbXBsZSBvZiBob3cgdGhpcyByZWNvZGVkIGRhdGEgaXMgcHJlc2VudGVkIGluIHRoZSByZXBvcnQgY2FuIGJlIHNlZW4gaW4gR3JhcGggMS4xLgpUaGlzIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIGNpdGl6ZW5zIHdobyBzdXBwb3J0IGRlbW9jcmFjeSBieSBjb3VudHJ5LgpUaGF0IGlzLCB0aGUgcGVyY2VudGFnZSBvZiByZXNwb25kZW50cyB3aG8gYW5zd2VyZWQgYmV0d2VlbiA1IGFuZCA3IHRvIHRoZSBJTkc0IHF1ZXN0aW9uIGluIGVhY2ggY291bnRyeSBpcyBzaG93bi4KQWNjb3JkaW5nIHRvIHRoZSByZWNvZGluZywgdGhpcyBncmFwaCB3b3VsZCByZXByZXNlbnQgdGhlIHBlcmNlbnRhZ2Ugb2YgcmVzcG9uZGVudHMgd2hvIHJlZ2lzdGVyIGEgMSBpbiB0aGUgcmVjb2RlZCB2YXJpYWJsZS4KCiFbXShGaWd1cmUxLjEucG5nKXt3aWR0aD0iNTYzIn0KCkluIHRoZSByZXBvcnQgVGhlIFB1bHNlIG9mIERlbW9jcmFjeSBmb3IgdGhlIDIwMTgvMTkgcm91bmQsIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDE4LzIwMTgtMTlfQW1lcmljYXNCYXJvbWV0ZXJfUmVnaW9uYWxfUmVwb3J0XzEwLjEzLjE5LnBkZiksIGl0IGlzIHByZXNlbnRlZCBhIHNpbWlsYXIgZmlndXJlLCB1c2luZyB0aGUgc2FtZSB2YXJpYWJsZSBhbmQgdGhlIHNhbWUgcnVsZSBmb3IgcmVjb2RpbmcuCgohW10oRmlndXJlMS4yLnBuZyl7d2lkdGg9IjQzNSJ9CgpUbyByZWNvZGUgYSB2YXJpYWJsZSBpbiBSIHRoZXJlIGFyZSBzZXZlcmFsIHdheXMuCk9uZSBvZiB0aGUgbW9zdCBlZmZpY2llbnQgd2F5cyB0byBkbyB0aGlzIGlzIGJ5IHVzaW5nIHRoZSBjb21tYW5kIGByZWNvZGVgIGZyb20gdGhlIGBjYXJgIHBhY2thZ2UuClRoZSBgZHBseXJgIHBhY2thZ2UgaGFzIGFsc28gYSBgcmVjb2RlYCBjb21tYW5kIHRoYXQgY2FuIGNvbmZ1c2UgUi4KVG8gYXZvaWQgY29uZnVzaW9uIHdlIHdpbGwgc3BlY2lmeSBpbiB0aGUgc3ludGF4IGBjYXI6OnJlY29kZWAgcmVjb2RpbmcuClRoZSByZWNvZGVkIHZhcmlhYmxlIGlzIHJlY29yZGVkIGFzICJsYXBvcDIxXCRpbmc0cmVjIi4KVGhlbiwgdGhlIGNvbW1hbmQgYHRhYmxlYCBpcyB1c2VkIHRvIGRlc2NyaWJlIHRoaXMgbmV3IHZhcmlhYmxlLgoKYGBge3IgcmVjb2Rpbmd9CmxpYnJhcnkoY2FyKQpsYXBvcDIxJGluZzRyZWMgPC0gY2FyOjpyZWNvZGUobGFwb3AyMSRpbmc0LCAiMTo0PTA7IDU6Nz0xIikKdGFibGUobGFwb3AyMSRpbmc0cmVjKQpgYGAKCklmIHRoZSBvYnNlcnZhdGlvbnMgYmV0d2VlbiAxIGFuZCA0IG9mIHRoZSBvcmlnaW5hbCB2YXJpYWJsZSBhcmUgYWRkZWQgKDE2OTkgKyAxNDcwICsgMzAwMyArIDYwODkpLCB3ZSBzZWUgdGhhdCBpdCBpcyB0aGUgcmVzdWx0IGVxdWFscyB0aGUgb2JzZXJ2YXRpb25zIGluIHZhbHVlIDAgb2YgdGhlIG5ldyB2YXJpYWJsZSAoMTIyNjEpLCBhcyBpdCB3YXMgd3JpdHRlbiBpbiB0aGUgcmVjb2RpbmcuCkl0IHNob3VsZCBhbHNvIGJlIG5vdGVkIHRoYXQgdGhlIGRhdGFzZXQgaW4gdGhlIEVudmlyb25tZW50IG5vdyBoYXMgb25lIG1vcmUgdmFyaWFibGUsIHRvdGFsaW5nIDE4MjYgdmFyaWFibGVzLgoKIyBTZWxlY3Rpb24gb2Ygb2JzZXJ2YXRpb25zCgpUaGUgRmlndXJlIDEuMSBzaG93cyB0aGF0IHN1cHBvcnQgZm9yIGRlbW9jcmFjeSBnb2VzIGZyb20gYSBoaWdoIG9mIDgwJSBpbiBVcnVndWF5IHRvIGEgbG93IG9mIDQ2JSBpbiBIYWl0aS4KVG8gcmVwbGljYXRlIHJlc3VsdCBjb3JyZXNwb25kaW5nIHRvIFVydWd1YXksIHdlIGNhbiBzZWxlY3Qgb2JzZXJ2YXRpb25zIGZyb20gdGhpcyBjb3VudHJ5LgpBY2NvcmRpbmcgdG8gY29kaWZpY2F0aW9uIG9mIHZhcmlhYmxlICJwYWlzIiwgVXJ1Z3VheSBpcyBjb2RlZCBhcyAxNC4KCiFbXShjb3VudHJ5LnBuZyl7d2lkdGg9IjUxNSJ9CgpTZWxlY3Rpb24gb2Ygb2JzZXJ2YXRpb25zIGluIFIgY2FuIGJlIGRvbmUgaW4gc2V2ZXJhbCB3YXlzLgpPbmUgd2F5IGlzIHRvIHVzZSBicmFja2V0cy4KT3RoZXIgd2F5IGlzIHRvIHVzZSB0aGUgY29tbWFuZCBgc3Vic2V0YC4KV2l0aCB0aGlzIGNvbW1hbmQsIHdlIHNlbGVjdCBvYnNlcnZhdGlvbnMgZnJvbSB0aGlzIGNvdW50cnkgYW5kIHdlIHNhdmUgdGhpcyBzZWxlY3Rpb24gaW4gYSBuZXcgZGF0YWZyYW1lICJsYXBvcDEiLgpXZSBoYXZlIDMwMDkgb2JzZXJ2YXRpb25zIGluIFVydWd1YXkgYW5kIDE4MjYgdmFyaWFibGVzLgoKYGBge3IgVXJ1fQpsYXBvcDEgPSBzdWJzZXQobGFwb3AyMSwgcGFpcz09MTQpCnRhYmxlKGxhcG9wMSRwYWlzKQpgYGAKCldpdGggdGhpcyBzZWxlY3Rpb24gb2YgZGF0YSwgeW91IGNhbiBjYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2VzIChyZWxhdGl2ZSBmcmVxdWVuY2llcykgdXNpbmcgdGhlIGNvbW1hbmQgYHByb3AudGFibGVgLgpUaGlzIGNvbW1hbmQgZ2l2ZXMgdXMgdGhlIHJlbGF0aXZlIGZyZXF1ZW5jaWVzIChpbiB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxKSBvZiBhIGZyZWN1ZW5jeSB0YWJsZSBjYWxjdWxhdGVkIHdpdGggYHRhYmxlYC4KVGhlc2UgcmVsYXRpdmUgZnJlcXVlbmNpZXMgYXJlIG11bHRpcGxpZWQgYnkgMTAwIHRvIHJlcHJvZHVjZSB0aGUgcGVyY2VudGFnZSBpbiBlYWNoIGNvdW50cnkuCkluIHRoaXMgY2FzZSwgdGhlIGJyYWNrZXRzIGBb4oCmXWAgYXJlIHVzZWQgdG8gbWFrZSB0aGUgc2VsZWN0aW9uIG9mIGNhc2VzIGZyb20gZWFjaCBjb3VudHJ5LgoKYGBge3IgcGVyY2VudH0KcHJvcC50YWJsZSh0YWJsZShsYXBvcDEkaW5nNHJlY1tsYXBvcDEkcGFpcz09MTRdKSkqMTAwCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgcGVyY2VudGFnZXMgKGJldHdlZW4gMCBhbmQgMTAwKSwgYnV0IGluY2x1ZGUgbWFueSBkZWNpbWFsIHBsYWNlcy4KVG8gcm91bmQgdG8gb25lIGRlY2ltYWwsIGFzIHNob3duIGluIEdyYXBoIDEuMiwgeW91IGNhbiB1c2UgdGhlIGNvbW1hbmQgYHJvdW5kYCwgd2hlcmUgYWxsIHRoZSBwcmV2aW91cyBzeW50YXggaXMgbmVzdGVkLgpJbiB0aGlzIGNvbW1hbmQsIHlvdSBoYXZlIHRvIHNwZWNpZnkgdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB5b3Ugd2FudCwgd2hpY2ggaW4gdGhpcyBjYXNlIGlzIDEuCgpgYGB7ciByb3VuZH0Kcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDEkaW5nNHJlY1tsYXBvcDEkcGFpcz09MTRdKSkqMTAwLCAxKQpgYGAKCkFjY29yZGluZyB0byB0aGlzIHJlc3VsdCwgODQuNSUgb2YgVXJ1Z3VheWFucyBzdXBwb3J0IGRlbW9jcmFjeS4KVGhpcyByZXN1bHQgaXMgZGlmZmVyZW50IGZyb20gd2hhdCBpdCBpcyByZXBvcnRlZCBpbiBGaWd1cmUgMS4xLCB3aGVyZSByZXBvcnRlZCB2YWx1ZSBpcyA4MCUuClRoaXMgZGlmZmVyZW5jZSBpcyBkdWUgdG8gdGhlIGZhY3QgdGhhdCBvdXIgcHJvY2VkdXJlcyBkbyBub3QgaW5jbHVkZSB0aGUgZWZmZWN0IG9mIGNvbXBsZXggZGVzaWduIGZlYXR1cmVzLCBzdWNoIGFzIHdlaWdodHMsIHN0cmF0aWZpY2F0aW9uLCBhbmQgY2x1c3RlciBzYW1wbGluZy4KQmVsb3csIHdlIHByZXNlbnQgcHJvY2VkdXJlcyB0byByZXByb2R1Y2UgcHJlY2lzZSByZXBvcnRlZCByZXN1bHRzLgoKVGhlIHJlcG9ydCBmb3IgdGhlIDIwMTgvMTkgd2F2ZSBpbmRpY2F0ZXMgIkZpZ3VyZSAxLjIgZGlzcGxheXMgdGhlIHBlcmNlbnQgb2YgaW5kaXZpZHVhbHMgaW4gZWFjaCBjb3VudHJ5IHRoYXQgZXhwcmVzc2VzIHN1cHBvcnQgZm9yIGRlbW9jcmFjeSBpbiAyMDE4LzE5LiBTdXBwb3J0IGZvciBkZW1vY3JhY3kgcmFuZ2VzIGZyb20gYSBsb3cgb2YgNDUlIGluIEhvbmR1cmFzIHRvIGEgaGlnaCBvZiA3Ni4yJSBpbiBVcnVndWF5LiIgKHAuIDExKS4KCkZvciByZXBsaWNhdGluZyB0aGVzZSByZXN1bHRzIGFib3V0IEhvbmR1cmFzIGFuZCBVcnVndWF5IGZvciB0aGUgMjAxOC8xOSByb3VuZCwgd2UgY2FuIHNlbGVjdCBvYnNlcnZhdGlvbnMgZm9yIHRoZXNlIHR3byBjb3VudHJpZXMuCkFjY29yZGluZyB0byB0aGUgcXVlc3Rpb25uYWlyZSwgYXZhaWxhYmxlIEhFUkUsIEhvbmR1cmFzIGlzIGNvZGVkIGFzIDQgYW5kIFVydWd1YXkgYXMgMTQgaW4gdmFyaWFibGUgInBhaXMiLCB0aGF0IGlzIGltcG9ydGVkIGFzIGEgbnVtZXJpYyB2YXJpYWJsZS4KCldlIGluY2x1ZGUgdGhlIG9wZXJhdG9yICJvciIsIHRoYXQgaXMgd3JpdHRlbiBhcyAiXHwiIGluIFIuCkluIHRoaXMgd2F5LCB3ZSBjYW4gc2VsZWN0IG9ic2VydmF0aW9ucyBmcm9tIEhvbmR1cmFzIG9yIFVydWd1YXkgdXNpbmcgYHBhaXM9PTQgfCBwYWlzPT0xNGAuClRoZSBkZXNjcmlwdGlvbiBvZiB2YXJpYWJsZSAicGFpcyIgc2hvd3MgdGhhdCBpdCBpbmNsdWRlcyBvbmx5IG9ic2VydmF0aW9ucyBmb3IgSG9uZHVyYXMgKDIpIGFuZCBVcnVndWF5ICgxNCkuCgpgYGB7ciBzZWxlY3R9CmxhcG9wMiA9IHN1YnNldChsYXBvcDE4LCBwYWlzPT00IHwgcGFpcz09MTQpCnRhYmxlKGxhcG9wMiRwYWlzKQpgYGAKClRoZSBuZXcgZGF0YWZyYW1lICJsYXBvcDIiIGhhcyAzMTQxIG9ic2VydmF0aW9ucyBhbmQgODQgdmFyaWFibGVzLgpJdCBkb2VzIG5vdCBpbmNsdWRlIGEgcmVjb2RlZCB2YXJpYWJsZSBmb3Igc3VwcG9ydCBmb3IgZGVtb2NyYWN5LgpXZSBwcm9jZWVkIHRvIGluY2x1ZGUgaXQuCgpgYGB7ciBpbmc0fQpsYXBvcDIkaW5nNHJlYyA8LSBjYXI6OnJlY29kZShsYXBvcDIkaW5nNCwgIjE6ND0wOyA1Ojc9MSIpCmBgYAoKV2l0aCB0aGlzIHZhcmlhYmxlLCB3ZSBjYW4gZm9sbG93IHRoZSBzYW1lIHByb2NlZHVyZXMgYXMgYmVmb3JlOiBwcm9kdWNlIGEgcmVsYXRpdmUgZnJlcXVlbmN5IHRhYmxlLgoKYGBge3IgcmVsYXRpdmV9CnByb3AudGFibGUodGFibGUobGFwb3AyJGluZzRyZWNbbGFwb3AyJHBhaXM9PTRdKSkqMTAwCnByb3AudGFibGUodGFibGUobGFwb3AyJGluZzRyZWNbbGFwb3AyJHBhaXM9PTE0XSkpKjEwMApgYGAKCkFuZCB0aGVuLCB3ZSBpbmNsdWRlIHJvdW5kaW5nLgoKYGBge3Igcm91bmQyfQpyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMiRpbmc0cmVjW2xhcG9wMiRwYWlzPT00XSkpKjEwMCwgMSkKcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDIkaW5nNHJlY1tsYXBvcDIkcGFpcz09MTRdKSkqMTAwLCAxKQpgYGAKCldpdGggdGhpcyBjb2RlLCB3ZSBoYXZlIHJlcHJvZHVjZWQgcmVzdWx0cyBmb3IgY291bnRyaWVzIGluIHRoZSBleHRyZW1lcyBvZiBGaWd1cmUgMS4yLgpJbiB0aGlzIGNhc2UsIHJlc3VsdHMgYXJlIHNpbWlsYXIgdG8gdGhlIG9uZXMgcmVwb3J0ZWQgaW4gdGhlIGZpZ3VyZSBpbiB0aGUgcmVwb3J0LgoKQm90aCByZXBvcnRzIGFsc28gaW5kaWNhdGUgdGhhdCB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgQ2FuYWRhIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBjYWxjdWxhdGlvbnMuClRoZSBkYXRhc2V0IGxvYWRlZCBhcyAibGFwb3AxOCIgaW5jbHVkZXMgYWxsIHRoZSBjb3VudHJpZXMgaW4gdGhlIHJvdW5kLgpUbyBleGNsdWRlIHRoZXNlIHR3byBjb3VudHJpZXMsIHdlIGhhdmUgdG8gc2VsZWN0IHRoZSBjb3VudHJpZXMgdGhhdCBhcmUgTk9UIFVTQSBhbmQgQ2FuYWRhLgpUaGlzIG5ldyBzZWxlY3Rpb24gY2FuIGJlIHNhdmVkIGluIGEgbmV3IGRhdGFmcmFtZSBvciBpdCBjYW4gYmUgb3ZlcndyaXR0ZW4gaW4gdGhlIG9yaWdpbmFsIGRhdGFmcmFtZSwgYXMgaXQgaXMgZG9uZSBpbiB0aGlzIGNhc2UgYmVjYXVzZSB0aGUgZXhjbHVzaW9uIG9mIHRoZXNlIGNvdW50cmllcyBpcyBmb3IgYWxsIHRoZSBjYWxjdWxhdGlvbnMgdGhhdCBmb2xsb3cuCkFjY29yZGluZyB0byB0aGUgcXVlc3Rpb25uYWlyZSwgVVNBIGhhcyB0aGUgY29kZSA0MCBhbmQgQ2FuYWRhLCB0aGUgY29kZSA0MSBpbiB0aGUgdmFyaWFibGUgInBhaXMiLgpUbyBleGNsdWRlIHRoZW0sIGNvdW50cmllcyB3aXRoIGEgY29kZSBvZiBsZXNzIHRoYW4gNDAgKG9yIDM1IG9yIGxlc3MpIG11c3QgYmUgaW5jbHVkZWQuCkZvciB0aGlzIHdlIGNhbiBhZ2FpbiB1c2UgdGhlIGBzdWJzZXRgIGNvbW1hbmQuCgpgYGB7ciBkcm9wIFVTQSBDYW5hZGF9CmxhcG9wMTggPC0gc3Vic2V0KGxhcG9wMTgsIHBhaXM8PTM1KQpgYGAKCkl0IGNhbiBiZSBvYnNlcnZlZCBpbiB0aGUgRW52aXJvbm1lbnQgdGhhdCB0aGUgb2JzZXJ2YXRpb25zIG9mIHRoZSAibGFwb3AxOCIgZGF0YWZyYW1lIGFyZSByZWR1Y2VkIGFmdGVyIHJ1bm5pbmcgdGhpcyBjb2RlLCBzaW5jZSB0aGUgb2JzZXJ2YXRpb25zIG9mIHJlcG9uZGVudHMgaW4gdGhlc2UgdHdvIGNvdW50cmllcyBoYXZlIGJlZW4gZWxpbWluYXRlZC4KVGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgZ29lcyBmcm9tIDMxLDA1MCB0byAyOCwwNDIsIGEgbnVtYmVyIHRoYXQgY29pbmNpZGVzIHdpdGggdGhhdCBvZiB0aGUgZGF0YXNldCBpbiAuUkRhdGEgZm9ybWF0IHRoYXQgd2UgdXNlZCBpbiB0aGUgcHJldmlvdXMgbW9kdWxlIGFuZCB0aGF0IHdlIGluZGljYXRlZCB0aGF0IGl0IGRpZCBub3QgaW5jbHVkZSB0aGVzZSBjb3VudHJpZXMuCgpJbiB0aGUgc2FtZSB3YXksIHdlIGNhbiBwcm9jZWVkIGluIHRoZSAyMDIxIHdhdmUgZGF0YXNldC4KQWZ0ZXIgdGhpcywgb2JzZXJ2YXRpb25zIGRlY3JlYXNlIHRvIDYwLDY2MS4KCmBgYHtyIGRyb3AgMjAyMX0KbGFwb3AyMSA9IHN1YnNldChsYXBvcDIxLCBwYWlzPD0zNSkKYGBgCgojIENhbGN1bGF0aW5nIGEgdmFyaWFibGUKCkEgZnJlcXVlbnQgTEFQT1AgcHJhY3RpY2Ugd2l0aCB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgZGF0YSBpcyB0aGUgcmVzY2FsaW5nIG9mIHZhcmlhYmxlcy4KVGhlIHJlcG9ydCdzIGNoYXB0ZXIgb24gZGVtb2NyYXRpYyBsZWdpdGltYWN5IHByb3ZpZGVzIGV4YW1wbGVzIG9mIHRoaXMgcmVzY2FsaW5nIHdpdGggdmFyaWFibGVzIHJlbGF0ZWQgdG8gc3VwcG9ydCBmb3IgdGhlIHN5c3RlbS4KVG8gY2FsY3VsYXRlIHRoaXMgaW5kZXggZm9yIHN5c3RlbSBzdXBwb3J0LCB3ZSB3b3JrIHdpdGggYSBzZXQgb2YgZml2ZSB2YXJpYWJsZXM6CgpCMS4KVG8gd2hhdCBleHRlbnQgZG8geW91IHRoaW5rIHRoZSBjb3VydHMgb2YgKGNvdW50cnkpIGd1YXJhbnRlZSBhIGZhaXIgdHJpYWw/Ci4gVG8gd2hhdCBleHRlbnQgZG8geW91IHJlc3BlY3QgdGhlIHBvbGl0aWNhbCBpbnN0aXR1dGlvbnMgb2YgKGNvdW50cnkpPwoKQjIuClRvIHdoYXQgZXh0ZW5kIGRvIHlvdSByZXNwZWN0IHRoZSBwb2xpdGljYWwgaW5zdGl0dXRpb25zIG9mIChjb3VudHJ5KT8KCkIzLgpUbyB3aGF0IGV4dGVudCBkbyB5b3UgdGhpbmsgdGhlIGJhc2ljIHJpZ2h0cyBvZiB0aGUgY2l0aXplbiBhcmUgd2VsbCBwcm90ZWN0ZWQgYnkgdGhlIHBvbGl0aWNhbCBzeXN0ZW0gb2YgKGNvdW50cnkpPwoKQjQuClRvIHdoYXQgZXh0ZW50IGFyZSB5b3UgcHJvdWQgdG8gbGl2ZSB1bmRlciB0aGUgcG9saXRpY2FsIHN5c3RlbSBvZiAoY291bnRyeSk/CgpCNi4KVG8gd2hhdCBleHRlbnQgZG8geW91IHRoaW5rIHRoZSBwb2xpdGljYWwgc3lzdGVtIG9mIChjb3VudHJ5KSBzaG91bGQgYmUgc3VwcG9ydGVkPwoKQXMgdGhlIHJlcG9ydCBpbmRpY2F0ZXMgIkZvciBlYWNoIHF1ZXN0aW9uLCB0aGUgb3JpZ2luYWwgc2NhbGUgZnJvbSAxICgiIE5vdCBhdCBhbGwgIikgdG8gNyAoIkEgbG90IikgaXMgcmVjb2RlZCBvbiBhIDAtMTAwIHNjYWxlLCBpbiBzdWNoIGEgd2F5IHRoYXQgMCBpbmRpY2F0ZXMgdGhlIGxvd2VzdCBsZXZlbCBvZiBzdXBwb3J0IGZvciB0aGUgcG9saXRpY2FsIHN5c3RlbSBhbmQgMTAwIGlzIHRoZSBoaWdoZXN0IGxldmVsIG9mIHN1cHBvcnQgZm9yIHRoZSBwb2xpdGljYWwgc3lzdGVtLiBUaGlzIG5ldyBzY2FsZSBmb2xsb3dzIHRoZSB0eXBpY2FsIExBUE9QIHJlY29kaW5nIGFuZCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgYSBtZWFzdXJlIG9mIHN1cHBvcnQgaW4gdW5pdHMsIG9yIGRlZ3JlZXMsIG9uIGEgY29udGludW91cyBzY2FsZSByYW5naW5nIGZyb20gMCB0byAxMDAiIChwLiAzNCkuClRvIGNoZWNrIHRoZSBvcmlnaW5hbCBzY2FsZSBvZiB0aGVzZSB2YXJpYWJsZXMsIHdlIGNhbiBkZXNjcmliZSB0aGVzZSB2YXJpYWJsZXMgdXNpbmcgdGhlIGB0YWJsZWAgY29tbWFuZC4KCmBgYHtyIGRlc2NyaWJpbmcyfQp0YWJsZShsYXBvcDE4JGIxKQp0YWJsZShsYXBvcDE4JGIyKQp0YWJsZShsYXBvcDE4JGIzKQp0YWJsZShsYXBvcDE4JGI0KQp0YWJsZShsYXBvcDE4JGI2KQpgYGAKCkl0IGlzIG9ic2VydmVkIHRoYXQgYWxsIHRoZSB2YXJpYWJsZXMgcnVuIG9uIGEgc2NhbGUgZnJvbSAxIHRvIDcuClRvIHJlc2NhbGUgYSB2YXJpYWJsZSBmcm9tIGFuIG9yaWdpbmFsIHNjYWxlIGZyb20gMSB0byA3IHRvIGFub3RoZXIgZnJvbSAwIHRvIDEwMCwgdGhlIGZpcnN0IHRoaW5nIHRvIGRvIGlzIHN1YnRyYWN0IDEgdW5pdCwgc28gdGhlIHZhcmlhYmxlIHdvdWxkIGhhdmUgYSBzY2FsZSBvZiAwIHRvIDYsIHRoZW4gZGl2aWRlIGl0IGJ5IDYsIHdpdGggd2hpY2ggd291bGQgdmFyeSBiZXR3ZWVuIDAgYW5kIDEgYW5kLCBmaW5hbGx5LCBtdWx0aXBseSBpdCBieSAxMDAuCnRoaXMgaXM6CgpSZXNjYWxlZCB2YXJpYWJsZSA9ICgob3JpZ2luYWwgdmFyaWFibGUgLTEpLzYpXCoxMDAKCmBgYHtyIGNhbGN1bGF0ZX0KbGFwb3AxOCRiMXJlYyA8LSAoKGxhcG9wMTgkYjEtMSkvNikqMTAwCmxhcG9wMTgkYjJyZWMgPC0gKChsYXBvcDE4JGIyLTEpLzYpKjEwMApsYXBvcDE4JGIzcmVjIDwtICgobGFwb3AxOCRiMy0xKS82KSoxMDAKbGFwb3AxOCRiNHJlYyA8LSAoKGxhcG9wMTgkYjQtMSkvNikqMTAwCmxhcG9wMTgkYjZyZWMgPC0gKChsYXBvcDE4JGI2LTEpLzYpKjEwMAp0YWJsZShsYXBvcDE4JGIxcmVjKQpgYGAKCldpdGggdGhpcyB0cmFuc2Zvcm1hdGlvbiwgaXQgaXMgb2JzZXJ2ZWQgdGhhdCB0aGUgNCwwODkgaW50ZXJ2aWV3ZWVzIHdobyBzY29yZWQgMSBpbiBxdWVzdGlvbiBCMSBub3cgaGF2ZSBhIHNjb3JlIG9mIDAuClRoZSA0LDA2NyB3aG8gc2NvcmVkIDIgbm93IGhhdmUgYSBzY29yZSBvZiAxNi42NywgdGhhdCBpcyAyLTE9MS82PTAuMTY2N1wqMTAwPTE2LjY3LgpUaGlzIHNhbWUgb3BlcmF0aW9uIGNvdWxkIGJlIGRvbmUgd2l0aCB0aGUgYGNhciA6OiByZWNvZGVgIGNvbW1hbmQsIGZvbGxvd2luZyB0aGlzIHJlY29kaW5nIHJ1bGU6CgotICAgVmFsdWUgb2YgMSBpbiBvcmlnaW5hbCB2YXJpYWJsZSBpcyByZWNvZGVkIGFzIDAgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiAyIGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMTYuNjcgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiAzIGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMzMuMzMgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA0IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgNTAgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA1IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgNjYuNjcgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA2IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgODMuMzMgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA3IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMTAwIGluIG5ldyB2YXJpYWJsZQoKVGhpcyB3YXkgb2YgcmVjb2RpbmcsIGhvd2V2ZXIsIGlzIG5vdCB2ZXJ5IGVmZmljaWVudC4KSXQgaXMgc2ltcGxlciB0byB1c2UgdGhlIGZvcm11bGEgdG8gY2FsY3VsYXRlIHRoZSByZWNvZGluZy4KVG8gY2FsY3VsYXRlIHRoZSBzeXN0ZW0gc3VwcG9ydCBpbmRleCwgdGhlIHJlcG9ydCBpbmRpY2F0ZXMgdGhhdCAiVGhlIHN5c3RlbSBzdXBwb3J0IGluZGV4IGlzIHRoZSBhdmVyYWdlIG9mIGZpdmUgcXVlc3Rpb25zOiBCMSwgQjIsIEIzLCBCNCBhbmQgQjYiIChwLjQ2KS4KSW4gb3RoZXIgd29yZHMsIHdpdGggdGhlIHJlc2NhbGVkIHZhcmlhYmxlcywgdGhlIGF2ZXJhZ2Ugb2YgdGhlc2UgZml2ZSB2YXJpYWJsZXMgaGFzIHRvIGJlIGNhbGN1bGF0ZWQgZm9yIGVhY2ggaW5kaXZpZHVhbCAodGhhdCBpcywgaW4gZWFjaCByb3cgb2YgdGhlIGRhdGFzZXQpLgpUaGlzIGNvdWxkIGJlIGRvbmUgYnkgY2FsY3VsYXRpbmcgdGhlIGF2ZXJhZ2UgbWFudWFsbHkuCgpTeXN0ZW0gc3VwcG9ydCA9IChiMXJlYyArIGIycmVjICsgYjNyZWMgKyBiNHJlYyArIGI2cmVjKS81CgpJbiBSIHdlIGhhdmUgdGhlIGNvbW1hbmQgYHJvd01lYW5zYCB0aGF0IGlzIHVzZWQgdG8gY2FsY3VsYXRlIGF2ZXJhZ2VzIG9mIGNlcnRhaW4gY29sdW1ucyBmb3IgZWFjaCByb3cuClRoZSBzeW50YXggYFssIDg2OjkwXWAgaW5kaWNhdGVzIHRoYXQgdGhlIGF2ZXJhZ2UgY2FsY3VsYXRpb24gd2lsbCBiZSBwZXJmb3JtZWQgYnkgcm93cyBmb3IgYWxsIHJvd3MgYW5kIHVzaW5nIGNvbHVtbnMgODYgdG8gOTAgb2YgdGhlICJsYXBvcDE4IiBkYXRhZnJhbWUgKHRoZSBjYWxjdWxhdGlvbiBjb3VsZCBiZSBkb25lIGZvciBzb21lIHBhcnRpY3VsYXIgcm93cyBieSBkZWZpbmluZyBgWyByb3dfbjogcm93X20sIDg2OjkwXWApLgpUaGlzIGF2ZXJhZ2UgaXMgc2F2ZWQgaW4gYSBuZXcgdmFyaWFibGUgInN1cHBvcnQiLCB3aGljaCBpcyBkZXNjcmliZWQuCgpgYGB7ciBzeXN0ZW0gc3VwcG9ydH0KbGFwb3AxOCRhcG95byA9IHJvd01lYW5zKGxhcG9wMThbLDg1Ojg5XSkKdGFibGUobGFwb3AxOCRhcG95bykKYGBgCgpXaXRoIHRoaXMgaW5kZXgsIGl0IGlzIHBvc3NpYmxlIHRvIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBzdXBwb3J0IGZvciB0aGUgc3lzdGVtIGZvciB0aGUgbGFzdCByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIsIGFzIHdlbGwgYXMgdGhlIGF2ZXJhZ2VzIGZvciBlYWNoIG9mIHRoZSB2YXJpYWJsZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4gdGhlIGluZGV4LgpUaGUgYG1lYW5gIGNvbW1hbmQgaXMgdXNlZCBmb3IgdGhlIGF2ZXJhZ2UgYW5kIHRoZSBgbmEucm0gPSBUYCBzcGVjaWZpY2F0aW9uIGlzIHVzZWQgdG8gdGVsbCB0aGUgY29tbWFuZCBub3QgdG8gdGFrZSBpbnRvIGFjY291bnQgdGhlIG1pc3NpbmcgdmFsdWVzIG9mIHRoZXNlIHZhcmlhYmxlcy4KVGhlc2Ugc3RhdGlzdGljcyB3aWxsIGJlIHNlZW4gaW4gbW9yZSBkZXRhaWwgaW4gb3RoZXIgZG9jdW1lbnRzLgoKYGBge3Igc3lzdGVtIHN1cHBvcnQgMjAxOC8xOX0KbWVhbihsYXBvcDE4JGFwb3lvLCBuYS5ybT1UKSAjc3lzdGVtIHN1cHBvcnQKbWVhbihsYXBvcDE4JGIxcmVjLCBuYS5ybT1UKSAjY291cnRzIGd1YXJhbnRlZSBmYWlyIHRyaWFsCm1lYW4obGFwb3AxOCRiMnJlYywgbmEucm09VCkgI1Jlc3BlY3QgZm9yIGluc3RpdHV0aW9ucwptZWFuKGxhcG9wMTgkYjNyZWMsIG5hLnJtPVQpICNCYXNpYyByaWdodHMgYXJlIHByb3RlY3RlZAptZWFuKGxhcG9wMTgkYjRyZWMsIG5hLnJtPVQpICNQcmlkZSBpbiB0aGUgcG9saXRpY2FsIHN5c3RlbQptZWFuKGxhcG9wMTgkYjZyZWMsIG5hLnJtPVQpICNUaGUgcG9saXRpY2FsIHN5c3RlbSBzaG91bGQgYmUgc3VwcG9ydGVkCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgdGhvc2Ugc2hvd24gaW4gRmlndXJlIDIuMSBmb3IgdGhlIDIwMTgvMTkgcm91bmQuCgohW10oRmlndXJlMi4xLnBuZyl7d2lkdGg9IjYyMiJ9CgojIENvbmRpY2lvbmFsbHkgY2FsY3VsYXRpbmcgYSB2YXJpYWJsZQoKU29tZXRpbWVzIHRoZSBjYWxjdWxhdGlvbiBvZiBhIHZhcmlhYmxlIGRvZXMgbm90IG9ubHkgcmVxdWlyZSB0aGUgbnVtZXJpY2FsIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBvcmlnaW5hbCB2YXJpYWJsZSwgYnV0IHRoZSB2YWx1ZXMgb2YgdGhlIG5ldyB2YXJpYWJsZSBkZXBlbmQgb24gdGhlIHZhbHVlcyBvZiBvdGhlciB2YXJpYWJsZXMuCkZvciBleGFtcGxlLCB0aGUgY2hhcHRlciAiU29jaWFsIG5ldHdvcmtzIGFuZCBwb2xpdGljYWwgYXR0aXR1ZGVzIiBvZiB0aGUgcmVwb3J0ICJUaGUgUHVsc2Ugb2YgRGVtb2NyYWN5IiBwcmVzZW50cyB0aGUgcmVzdWx0cyBmb3IgdGhlIHZhcmlhYmxlcyAiV2hhdHNBcHAgdXNlciIsICJUd2l0dGVyIHVzZXIiIGFuZCAiRmFjZWJvb2sgdXNlciIuClRvIGNhbGN1bGF0ZSB0aGVzZSB2YXJpYWJsZXMsIGZvb3Rub3RlIDcgb2YgdGhpcyBjaGFwdGVyIGluZGljYXRlczogIkZvciBlYWNoIHBsYXRmb3JtLCB3ZSBpZGVudGlmeSB1c2VycyB3aXRoIGEgY29tYmluYXRpb24gb2YgdHdvIHNldHMgb2Ygc3VydmV5IHF1ZXN0aW9ucy4gRmlyc3QsIHdlIGlkZW50aWZ5IHVzZXJzIGFzIHRob3NlIHdobyByZXNwb25kIHBvc2l0aXZlbHkgdG8gdGhlIHF1ZXN0aW9ucywgU01FRElBMS9TTUVESUE0L1NNRURJQTcuIERvIHlvdSBoYXZlIGEgRmFjZWJvb2svVHdpdHRlci9XaGF0c0FwcCBhY2NvdW50PyBUaGVuLCB3ZSByZWNvZGUgYXMgbm9uLXVzZXJzIHRob3NlIHdobyByZXNwb25kIm5ldmVyIiB0byB0aGUgZm9sbG93LXVwIHF1ZXN0aW9ucywgU01FRElBMi9TTUVESUE1L1NNRURJQTguIEhvdyBvZnRlbiBkbyB5b3Ugc2VlIGNvbnRlbnQgb24gRmFjZWJvb2svVHdpdHRlci9XaGF0c0FwcD8iIChwLiA2NCkuCgohW10oc21lZGlhLnBuZyl7d2lkdGg9IjUzMSJ9CgpUaGF0IGlzLCB0aGUgdXNlciBpcyBub3Qgb25seSB0aGUgb25lIHdobyBoYXMgYW4gYWNjb3VudCAoU01FRElBMSA9IDEpLCBidXQgdGhlIG9uZSB3aG8gdXNlcyBpdCB3aXRoIGEgY2VydGFpbiBmcmVxdWVuY3kgKFNNRURJQTIgPSAxLCAyLCAzLCA0KS4KSW4gdGhpcyB3YXksIHRoZSBub24tdXNlciBjYW4gaGF2ZSBhbiBhY2NvdW50LCBidXQgbmV2ZXIgdXNlIGl0LgpUaGVyZWZvcmUsIHRoZSB2YXJpYWJsZSAidXNlciIgZGVwZW5kcyBvbiB0aGUgdmFsdWVzIG9mIDIgdmFyaWFibGVzLgpUaGUgcnVsZSBmb3IgY29kaW5nIGlzOgoKLSAgIEZhY2Vib29rIHVzZXIgPSAxIChoZS9zaGUgaXMgYSB1c2VyKSBpZiBTTUVESUExID0gMSAoaGUvc2hlIGhhcyBhbiBhY2NvdW50KSBhbmQgU01FRElBMiBcPD0gNCAoaGUvc2hlIHVzZXMgaXQgd2l0aCBzb21lIGZyZXF1ZW5jeSkKCi0gICBGYWNlYm9vayB1c2VyID0gMCAoaGUvc2hlIGlzIG5vdCBhIHVzZXIpIGlmIFNNRURJQTIgPSAyIChoZS9zaGUgZG9lc27CtHQgaGF2ZSBhbiBhY2NvdW50KSBvciBTTUVESUEyID0gNSAoIGhlL3NoZSBoYXMgYW4gYWNjb3VudCBidXQgbmV2ZXIgdXNlcyBpdCkKClRoaXMgcnVsZSB0cmFuc2Zvcm1zIGludG8gdGhlIGZvbGxvd2luZyBSIHN5bnRheCwgd2hpY2ggdXNlcyB0aGUgY29tbWFuZCBgw6xmZWxzZWAuClRoaXMgc3ludGF4IGluY2x1ZGVzIHRoZSBjb25kaXRpb24gdG8gYXNzaWduIHZhbHVlcyBvZiAxIHRvIGEgbmV3IHZhcmlhYmxlIGFuZCBhc3NpZ25zIGFsbCBvdGhlciBvYnNlcnZhdGlvbnMgdGhlIHZhbHVlIG9mIDAuClRoZXNlIG5ldyB2YXJpYWJsZXMgYXJlIGRlc2NyaWJlZCB1c2luZyB0aGUgYHRhYmxlYCBjb21tYW5kIHRvIGdlbmVyYXRlIHRoZSBhYnNvbHV0ZSBmcmVxdWVuY2llcyx0aGUgYHByb3AudGFibGVgIGNvbW1hbmQgZm9yIHRoZSByZWxhdGl2ZSBmcmVxdWVuY2llcyBhbmQgdGhlIGByb3VuZGAgY29tbWFuZCB0byByb3VuZCB0aGUgZGVjaW1hbHMuClRoZXNlIGNvbW1hbmRzIHdpbGwgYmUgc2VlbiBpbiBtb3JlIGRldGFpbCBpbiB0aGUgZm9sbG93aW5nIGRvY3VtZW50cy4KCmBgYHtyIHVzZXJzLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxhcG9wMTgkZmJfdXNlciA8LSBpZmVsc2UobGFwb3AxOCRzbWVkaWExPT0xICYgbGFwb3AxOCRzbWVkaWEyPD00LCAxLCAwKQpsYXBvcDE4JHR3X3VzZXIgPC0gaWZlbHNlKGxhcG9wMTgkc21lZGlhND09MSAmIGxhcG9wMTgkc21lZGlhNTw9NCwgMSwgMCkKbGFwb3AxOCR3YV91c2VyIDwtIGlmZWxzZShsYXBvcDE4JHNtZWRpYTc9PTEgJiBsYXBvcDE4JHNtZWRpYTg8PTQsIDEsIDApCnJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AxOCRmYl91c2VyKSkqMTAwLCAxKQpyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkdHdfdXNlcikpKjEwMCwgMSkKcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHdhX3VzZXIpKSoxMDAsIDEpCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgdGhvc2UgcHJlc2VudGVkIGluIEdyYXBoIDMuMSBvZiB0aGUgcmVwb3J0IGluIHRoZSBmb3JtIG9mIHBpZSBjaGFydHMuClRoZXNlIHR5cGVzIG9mIGdyYXBocyB3aWxsIGJlIHNlZW4gaW4gdGhlIG5leHQgc2VjdGlvbi4KCiFbXShGaWd1cmUzLjEucG5nKXt3aWR0aD0iMzA5In0KCiMgRGVzaWduIGVmZmVjdCBvYnNlcnZhdGlvbgoKQm90aCB0aGUgcmVzdWx0cyBmb3Igc3lzdGVtIHN1cHBvcnQgYW5kIHRob3NlIG9mIHNvY2lhbCBuZXR3b3JrIHVzZXJzIGRpZmZlciBmcm9tIHRob3NlIHRoYXQgYXBwZWFyIGluIHRoZSByZXBvcnQgZm9yIHR3byByZWFzb25zLgpGaXJzdCwgYWJvdXQgc3VwcG9ydCB0aGUgc3lzdGVtLCBiZWNhdXNlICJDcm9zcy10aW1lIHZhbHVlcyBhcmUgY2FsY3VsYXRlZCBpbmNsdWRpbmcgb25seSB0aG9zZSBjb3VudHJpZXMgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGhhcyBzdXJ2ZXllZCBjb25zaXN0ZW50bHkgc2luY2UgMjAwNjogQXJnZW50aW5hLCBCcmF6aWwsIEJvbGl2aWEsIENoaWxlLCBDb2xvbWJpYSwgQ29zdGEgUmljYSAsIHRoZSBEb21pbmljYW4gUmVwdWJsaWMsIEVjdWFkb3IsIEVsIFNhbHZhZG9yLCBHdWF0ZW1hbGEsIEhvbmR1cmFzLCBKYW1haWNhLCBNZXhpY28sIE5pY2FyYWd1YSwgUGFuYW1hLCBQYXJhZ3VheSwgUGVydSwgVXJ1Z3VheSIgKHAuNDYpLgpUaGUgY29kZSBvbmx5IGZpbHRlcnMgdGhlIGxhc3Qgcm91bmQsIHdoaWNoIGluY2x1ZGVzIGNvdW50cmllcyB0aGF0IGFyZSBub3Qgb24gdGhhdCBsaXN0LCBzdWNoIGFzIHRoZSBVbml0ZWQgU3RhdGVzIG9yIENhbmFkYS4KT24gdGhlIG90aGVyIGhhbmQsIHRoZSBjYWxjdWxhdGlvbnMgcmVwb3J0ZWQgaW4gdGhlIHB1YmxpY2F0aW9uIGluY2x1ZGUgdGhlIHVzZSBvZiBzdXJ2ZXkgd2VpZ2h0cywgd2hpY2ggaGF2ZSBub3QgYmVlbiBpbmNsdWRlZCBpbiB0aGVzZSBjYWxjdWxhdGlvbnMsIGJ1dCB3aGljaCB3aWxsIGJlIGluY29ycG9yYXRlZCBpbiBvdGhlciBkb2N1bWVudHMgKHNlZSBbaGVyZV0oaHR0cHM6Ly9ycHVicy5jb20vYXJ0dXJvX21hbGRvbmFkby83Mjg2MjYpKS4KCiMgU3VtbWFyeQoKSW4gdGhpcyBkb2N1bWVudCB3ZSBoYXZlIHNlZW4gdGhlIGJhc2ljIGVsZW1lbnRzIG9mIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCB0cmFuc2Zvcm1hdGlvbiB1c2luZyB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgZGF0YXNldHMuCkEgdmFyaWFibGUgaGFzIGJlZW4gcmVjb2RlZCB1c2luZyB0aGUgYHJlY29kZWAgY29tbWFuZCwgY2FzZXMgaGF2ZSBiZWVuIHNlbGVjdGVkIHVzaW5nIGBzdWJzZXRgIGFuZCBhIG5ldyB2YXJpYWJsZSBoYXMgYmVlbiBjYWxjdWxhdGVkIGFsZ2VicmFpY2FsbHkgYW5kIHdpdGggdGhlIGBpZmVsc2VgIGNvbW1hbmQuCg==