class <- tibble(
age = c(32, 30, 32, 29, 24, 38, 25, 24, 48, 29, 22, 29, 24, 28, 24, 25, 25,
22, 25, 24, 25, 24, 23, 24, 31, 24, 29, 24, 22, 23, 26, 23, 24, 25,
24, 33, 27, 25, 26, 26, 26, 26, 26, 27, 24, 43, 25, 24, 27, 28, 29,
24, 26, 28, 25, 24, 26, 24, 26, 31, 24, 26, 31, 34, 26, 25, 27, NA),
gender = c(2, 1, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1,
1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1, 2,
1, NA),
ht_in = c(70, 63, 62, 67, 67, 58, 64, 69, 65, 68, 63, 68, 69, 66, 67, 65,
64, 75, 67, 63, 60, 67, 64, 73, 62, 69, 67, 62, 68, 66, 66, 62,
64, 68, NA, 68, 70, 68, 68, 66, 71, 61, 62, 64, 64, 63, 67, 66,
69, 76, NA, 63, 64, 65, 65, 71, 66, 65, 65, 71, 64, 71, 60, 62,
61, 69, 66, NA),
wt_lbs = c(216, 106, 145, 195, 143, 125, 138, 140, 158, 167, 145, 297, 146,
125, 111, 125, 130, 182, 170, 121, 98, 150, 132, 250, 137, 124,
186, 148, 134, 155, 122, 142, 110, 132, 188, 176, 188, 166, 136,
147, 178, 125, 102, 140, 139, 60, 147, 147, 141, 232, 186, 212,
110, 110, 115, 154, 140, 150, 130, NA, 171, 156, 92, 122, 102,
163, 141, NA)
) %>%
mutate(gender = factor(gender, levels = c(1, 2), labels = c("Female", "Male"))) %>%
print()
Categorizing continuous variables
When conducting an analysis, there are often times when we want or need to group a continuous variable into discrete categories. Common examples in epidemiologic research include creating age groups or body mass index (BMI) categories. I’ll demonstrate both below.
class <- class %>%
mutate(
age_group = if_else(age < 30, 1, 2, NA_real_),
age_group = factor(age_group, labels = c("Younger than 30", "30 and Older"))
) %>%
select(age, age_group, everything())
class
Here’s what we did above:
- We added a new variable to the class data frame called “age_group.” In this case, every person who has a non-missing value of age…
class <- class %>%
mutate(
bmi = (wt_lbs / ht_in^2 * 703),
bmi_3cat = case_when(
bmi < 25 ~ 1,
bmi >= 25 & bmi < 30 ~ 2, # Make sure to type "bmi" twice!
bmi >= 30 ~ 3
)
)
class
So far, you’ve learned to read in data and create SAS data sets. However, up to this point you have generally had to accept the data just as it is. In this lesson you will begin to manipulate the data, so that it’s more useful for your specific needs. As SAS programmers there will often be times that you want to modify your data or your analysis in some way based on the value of one or more variables. Maybe you only want to look at female participants in your data set, or individuals of a certain age. Perhaps you decide that you want to create a variable that represents the region of the country someone is from, based on knowledge of the state they are from. These are just a couple of examples of an almost infinite number of ways in which you can use conditional processing in SAS. It’s called conditional processing because you type in a set of conditions, SAS evaluates those conditions and then executes or does not execute some process or procedure based on whether or not these conditions are met. As a silly example, let’s say that I want my daughter to wear a raincoat if it’s raining outside. So I give her a command: “If it’s raining outside, make sure to wear your raincoat please.” In this hypothetical fantasy world, she then says, “yes, dad,” goes to the window to see if it’s raining and then either puts on, or does not put on her raincoat depending on if the condition (raining) is met. Another commonly used term for conditional processing is “if-then statements,” or “if-then-else statements.” Just like I have to tell my daughter to put on a raincoat, I have to issue SAS commands in order to get the results I want. In order for SAS to execute these commands for conditional processing, I have to put them in a form that SAS understands. One such form is the IF-THEN-ELSE statement. So, if SAS were my daughter, I would say if it’s raining outside, then put on a raincoat. If it’s not raining outside, then don’t put on a raincoat. More generally, the IF-THEN statement can be written in this way. The IF-THEN statement executes a SAS statement for observations that meet certain conditions. In the IF-THEN statement the expression is a sequence of operands and operators. They define a condition for selecting observations. The statement after the keyword THEN can be any executable SAS statement, such as the assignment statement. In this example, the expression tests the values of two variables - systolic blood pressure and diastolic blood pressure. The statement after the keyword THEN assigns a value to the variable hypertension. Expressions can include variables like job_title and ht_in. They can also include constants. Constants can have character values like married or single, or they can be numeric. Character constants must be enclosed in quotation marks, but numeric constants should not. Taken together, the variables and constants make up the operands of an expression. Additionally, expressions use operators to specify the conditions that SAS will evaluate. These are examples of commonly used comparison operators. Comparison operators compare a variable with a constant or another variable.You can use either the symbol or the mnemonic in your code. Look over these examples of comparison operators used in IF-THEN statements. Here is a list of commonly used arithmetic operators, and some examples of how they may be used in IF-THEN statements. As these examples demonstrate, both comparison and arithmetic operators can be used in the same statement. Logical operators combine or modify expressions. You can use either the symbol or the mnemonic in your code. Here you can see the logical operators that are available, and a few examples of how the may be used in a IF-THEN statements. When using Boolean operators , remember that the “and” operator has precedence over the or operator. That is, a statement such as the following: If x and y or z Is equivalent to: If (x and y) or z If you want to perform the “or” operation before the “and” operation, use parentheses like this: If x and (y or z) As a side note: the “not” operator, which wasn’t demonstrated here, has the highest precedence of all. You were already introduced to assignment statements in the last module. As a reminder, you can use an assignment statement in any DATA step to transform variables, create variables, calculate new values for variables, and more. To do this, the assignment statement evaluates an expression and assigns the resulting value to a variable. The general form of the assignment statement is shown here. In this example, let’s say that you discover that three mosquito traps were misclassified as light traps when they were actually chemical attractant traps. You write a SAS program to change trap type from 2 to 1 for these three traps. When you run this program, the IF-THEN statement will execute once for each observation in the data set. If the trap number doesn’t equal the specified value, the value of type doesn’t change for that observation. In this case, the value of trap in the program data vector does not match the value in the first IF-THEN statement, so the value of type remains 2. The expression in the next two IF-THEN statements are also false, so type continues to have a value of 2 for this observation. Next SAS reaches the RUN statement, writes the observation currently in the program data vector out to the temporary SAS data set called example, and then reads in the next observation from ntrhd.mosquito into the PDV. All the expressions are false for this observation as well. Eventually SAS gets to this observation. This time, the condition in the first IF-THEN statement is true. So, SAS changes the value of type to one for this observation. The remaining IF-THEN statements are false for this observation. Notice that these IF-THEN statements are mutually exclusive. No more than one of them can be true at a time. Therefore, once SAS encounters a true statement, checking the other statements is a waste of time and computing power. Adding the keyword ELSE is much more efficient. When you specify else, and one condition is true, SAS skips the remaining conditions. Now you are going to prepare and import the data from a survey like the one you took on the first day of this course. You will use this data to practice conditional processing using IF-THEN-ELSE statements. So here you essentially have two rows with variable names: The first row gives a generic Letter/Number name, and second row gives the entire text of each survey question. Which do you think is better for your purposes? Then you can see that there are some character variables containing some sort of automatically generated response id, name, ip address, and some other stuff that you don’t really care about. Next you see that start date and end date are filled with a bunch of hashtags. All this means is that the column isn’t wide enough to display the data. If you double click the line in the column header between column h and column i, and between column I and column j, they will widen and the data will be displayed. That’s interesting. Notice anything different about these dates? They include the date and the time that the survey was started and completed. Finally, you see all of your substantive questions and values representing your responses. But look at Q11 and Q12. Are these numeric variables or character variables? How will you deal with these? Now you could ahead and do all the coding necessary to read this into to SAS as a .cvs file; however, I think it’s much easier to save it as a excel file and import it into SAS. Remember, you always want to keep the original raw data file intact, so the first thing you will do is “Save as” In the ‘save as’ menu you can ahead and accomplish a couple things. First, let’s name the new file something more simple. Next, let’s go ahead and convert this into an excel file using the “format” drop-down menu. Now let’s take care of the two header rows. I’ll start by deleting the very wordy second row. Why you’re at it, let’s go ahead and get rid of the first 7 columns. I’m not really interested in any of this information. Now you have something that should be a little bit more straightforward to import into SAS. There are other changes that you could make right here in the excel file; however, for instructional purposes I would like you to make these changes in SAS. So, let’s save this once more, and then import it into SAS. I have already created a new SAS library called class. I have also imported the class survey data using the import wizard, and saved the new SAS data set in the class library. And here is the data. Notice that there are no unique identifiers associated with each observation. Let’s go ahead and give each participant an id number. To assign sequential numbers to observations in a data set in SAS, create a variable using N. You’ve already learned that N is created in the PDV, but not output to the new SAS data set. In this program we are creating a new variable in the PDV and setting it equal to the value of N for each observation. Although N still isn’t written to the SAS data set survey2, the variable id is, and it contains the value of N for each observation. This is a really handy way of creating a sequentially numbered variable in SAS. Now it is not necessary to make id the first variable in the SAS data set. However, by convention, this is usually done, and it’s something I like to do. One, of many different ways to do this is with the RETAIN statement in a data step. You simply type the keyword retain, and then type the variables in the order you want them. Any variables that aren’t specifically listed in the RETAIN statement will come after the variables listed in the retain statement and remain in their current order. Then, to improve readability, you will go ahead and rename your variables, label your variables, and format your variables. Now your data is a little more user friendly, and you can continue on with conditional processing. For starters, in your class survey data there was a question that asked about the number of children under age 18 living in your home. Let’s say that you are really just interested in knowing if you have no children, one child, or more than one child – and you want to create a new variable called child3cat (for 3 categories) that captures this information. You can do this using IF-THEN statements. Here you see a common first attempt at completing this task. You are telling SAS if the value for the variable children is less than 1, then the value for the variable child3cat (which SAS will create if it doesn’t already exist) in the same observation should equal 0. Next if the value for the variable children is equal to 1, then the value for the variable child3cat in the same observation should equal 1. And finally, if the value for children is greater than 1, then the value for the variable child3cat in the same observation should equal 2. So you can see that the variable child3cat was created, but you have a problem. SAS is categorizing students who didn’t answer the question about children as having no children. And it’s possible that they don’t have any children, but you don’t have any way of knowing that, do you? Well, this is the frequency procedure. It starts the SAS keyword FREQ, followed by the data set containing your data. Instead of a VAR statement, PROC FREQ uses the TABLE statement. This will make more sense when you create two-way tables. For now you may just want to memorize this difference. Let’s run it. As you can see, the FREQ procedure with one variable in the table statement produces a one-way frequency table. In the first column is the variable name and the categories for that variable. In the second column is the frequency, or number of times, that category is observed in the data. In the third column is the percent of the observations for that variable that fall within each respective category. The third and fourth columns are the cumulative frequency and percent respectively. Finally, notice at the bottom that SAS tells you the number of missing observations for this variable. Now let’s compare this to your recoded 3-category variable. Before you run the second PROC FREQ, I want to point out that the way you have the table statement coded here tells SAS that you want two separate one-way frequency tables. One for the variable children, and one for the variable child3cat. Notice any problems? You should. The frequencies of people without any children don’t match because you didn’t consider that SAS counts missing as the minimum value in your program. So, here is one way to fix this issue. This example is the easiest way. Just change the first if statement to read “if children equals zero then child3cat equals zero. But, other times, it may not be this straightforward. Here is another way you can write your code. Now you are telling SAS to code child3cat as zero if the value for children is greater than missing and it is also less than 1. Notice that you must type the word”children" before both logical expressions. And just to be sure you believe me, let’s run PROC FREQ again. There, now they match. Earlier you learned about the efficiency of adding the keyword ELSE to your IF-THEN statements. To take efficiency even one step further, you can code this data step in the following way: Here the first if statement uses the missing function. The missing function returns a value of true if the argument - the variable in parentheses – is missing, and a value of false if it is not missing. Then it moves on and evaluates the remaining if statements until one comes back true. Notice that you no longer need the “if children greater than missing” part to the second if statement. This is because missing has already been evaluated AND you are using if-then-else statements instead of just if-then statements. Now complete this practice using IF-THEN-ELSE statements This completes the video on conditional processing. It is almost impossible to overstate the importance of understanding how to manage your data using IF-THEN-ELSE statements. You will use them every time you conduct any sort of analysis in the real world, and a mistake in your conditional logic will likely invalidate all of your results. I encourage you to practice, practice, and then practice some more. The best way to reduce your chances of making a mistake in your conditional processing is experience.
LS0tCnRpdGxlOiAiQ29uZGl0aW9uYWwgUHJvY2Vzc2luZyIKYXV0aG9yOiAiQnJhZCBDYW5uZWxsIgpkYXRlOiAiQ3JlYXRlZDogMjAxOS0wNy0yMCA8YnI+IFVwZGF0ZWQ6IGByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNzczogIi4uLy4uL2Nzcy9sbS1tYXJrZG93bi1zdHlsZXMuY3NzIgotLS0KCmBgYHtyIGVjaG89RkFMU0V9CiMgTG9hZCB0aGUgVGlkeXZlcnNlIHBhY2thZ2UKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKYGBge3J9CmNsYXNzIDwtIHRpYmJsZSgKICBhZ2UgICAgPSBjKDMyLCAzMCwgMzIsIDI5LCAyNCwgMzgsIDI1LCAyNCwgNDgsIDI5LCAyMiwgMjksIDI0LCAyOCwgMjQsIDI1LCAyNSwgCiAgICAgICAgICAgICAyMiwgMjUsIDI0LCAyNSwgMjQsIDIzLCAyNCwgMzEsIDI0LCAyOSwgMjQsIDIyLCAyMywgMjYsIDIzLCAyNCwgMjUsIAogICAgICAgICAgICAgMjQsIDMzLCAyNywgMjUsIDI2LCAyNiwgMjYsIDI2LCAyNiwgMjcsIDI0LCA0MywgMjUsIDI0LCAyNywgMjgsIDI5LCAKICAgICAgICAgICAgIDI0LCAyNiwgMjgsIDI1LCAyNCwgMjYsIDI0LCAyNiwgMzEsIDI0LCAyNiwgMzEsIDM0LCAyNiwgMjUsIDI3LCBOQSksCiAgZ2VuZGVyID0gYygyLCAxLCAxLCAyLCAxLCAxLCAxLCAyLCAyLCAyLCAxLCAxLCAyLCAxLCAxLCAxLCAxLCAyLCAyLCAxLCAxLCAxLCAKICAgICAgICAgICAgIDEsIDIsIDEsIDEsIDIsIDEsIDEsIDEsIDIsIDEsIDEsIDIsIDIsIDEsIDIsIDIsIDEsIDIsIDIsIDEsIDEsIDEsIAogICAgICAgICAgICAgMSwgMSwgMSwgMSwgMSwgMiwgMiwgMSwgMSwgMSwgMSwgMiwgMiwgMSwgMSwgMiwgMSwgMiwgMSwgMSwgMSwgMiwgCiAgICAgICAgICAgICAxLCBOQSksCiAgaHRfaW4gID0gYyg3MCwgNjMsIDYyLCA2NywgNjcsIDU4LCA2NCwgNjksIDY1LCA2OCwgNjMsIDY4LCA2OSwgNjYsIDY3LCA2NSwgCiAgICAgICAgICAgICA2NCwgNzUsIDY3LCA2MywgNjAsIDY3LCA2NCwgNzMsIDYyLCA2OSwgNjcsIDYyLCA2OCwgNjYsIDY2LCA2MiwgCiAgICAgICAgICAgICA2NCwgNjgsIE5BLCA2OCwgNzAsIDY4LCA2OCwgNjYsIDcxLCA2MSwgNjIsIDY0LCA2NCwgNjMsIDY3LCA2NiwgCiAgICAgICAgICAgICA2OSwgNzYsIE5BLCA2MywgNjQsIDY1LCA2NSwgNzEsIDY2LCA2NSwgNjUsIDcxLCA2NCwgNzEsIDYwLCA2MiwgCiAgICAgICAgICAgICA2MSwgNjksIDY2LCBOQSksCiAgd3RfbGJzID0gYygyMTYsIDEwNiwgMTQ1LCAxOTUsIDE0MywgMTI1LCAxMzgsIDE0MCwgMTU4LCAxNjcsIDE0NSwgMjk3LCAxNDYsIAogICAgICAgICAgICAgMTI1LCAxMTEsIDEyNSwgMTMwLCAxODIsIDE3MCwgMTIxLCA5OCwgMTUwLCAxMzIsIDI1MCwgMTM3LCAxMjQsIAogICAgICAgICAgICAgMTg2LCAxNDgsIDEzNCwgMTU1LCAxMjIsIDE0MiwgMTEwLCAxMzIsIDE4OCwgMTc2LCAxODgsIDE2NiwgMTM2LCAKICAgICAgICAgICAgIDE0NywgMTc4LCAxMjUsIDEwMiwgMTQwLCAxMzksIDYwLCAxNDcsIDE0NywgMTQxLCAyMzIsIDE4NiwgMjEyLCAKICAgICAgICAgICAgIDExMCwgMTEwLCAxMTUsIDE1NCwgMTQwLCAxNTAsIDEzMCwgTkEsIDE3MSwgMTU2LCA5MiwgMTIyLCAxMDIsIAogICAgICAgICAgICAgMTYzLCAxNDEsIE5BKQopICU+JSAKICBtdXRhdGUoZ2VuZGVyID0gZmFjdG9yKGdlbmRlciwgbGV2ZWxzID0gYygxLCAyKSwgbGFiZWxzID0gYygiRmVtYWxlIiwgIk1hbGUiKSkpICU+JSAKICBwcmludCgpCmBgYAoKIyBDYXRlZ29yaXppbmcgY29udGludW91cyB2YXJpYWJsZXMKCjwhLS0gSW4gZ2VuZXJhbCwgcXVhbnRpbGVzIGFyZSBhIGJhZCBpZGVhLiBBZ2FpbnN0IHF1YW50aWxlczogY2F0ZWdvcml6YXRpb24gb2YgY29udGludW91cyB2YXJpYWJsZXMgaW4gZXBpZGVtaW9sb2dpYyByZXNlYXJjaCwgYW5kIGl0cyBkaXNjb250ZW50cyAtLT4KCjwhLS0gR2V0IHRoZSBlcXVhdGlvbiBmb3IgY2FsY3VsYXRpbmcgQk1JICBodHRwczovL3d3dy5jZGMuZ292L2hlYWx0aHl3ZWlnaHQvYXNzZXNzaW5nL2JtaS9hZHVsdF9ibWkvaW5kZXguaHRtbCNJbnRlcnByZXRlZCAtLT4KCjwhLS0gQ2F0ZWdvcml6ZSBCTUkgaW50byAzIGxldmVscyBodHRwczovL3d3dy5jZGMuZ292L29iZXNpdHkvYWR1bHQvZGVmaW5pbmcuaHRtbCAtLT4KCldoZW4gY29uZHVjdGluZyBhbiBhbmFseXNpcywgdGhlcmUgYXJlIG9mdGVuIHRpbWVzIHdoZW4gd2Ugd2FudCBvciBuZWVkIHRvIGdyb3VwIGEgY29udGludW91cyB2YXJpYWJsZSBpbnRvIGRpc2NyZXRlIGNhdGVnb3JpZXMuIENvbW1vbiBleGFtcGxlcyBpbiBlcGlkZW1pb2xvZ2ljIHJlc2VhcmNoIGluY2x1ZGUgY3JlYXRpbmcgYWdlIGdyb3VwcyBvciBib2R5IG1hc3MgaW5kZXggKEJNSSkgY2F0ZWdvcmllcy4gSSdsbCBkZW1vbnN0cmF0ZSBib3RoIGJlbG93LgoKPCEtLSBJbnNlcnQgc2xpZGUgYWJvdXQgaWZfZWxzZSgpIGZ1bmN0aW9uIC0tPgoKYGBge3J9CmNsYXNzIDwtIGNsYXNzICU+JSAKICBtdXRhdGUoCiAgICBhZ2VfZ3JvdXAgPSBpZl9lbHNlKGFnZSA8IDMwLCAxLCAyLCBOQV9yZWFsXyksCiAgICBhZ2VfZ3JvdXAgPSBmYWN0b3IoYWdlX2dyb3VwLCBsYWJlbHMgPSBjKCJZb3VuZ2VyIHRoYW4gMzAiLCAiMzAgYW5kIE9sZGVyIikpCiAgKSAlPiUgCiAgc2VsZWN0KGFnZSwgYWdlX2dyb3VwLCBldmVyeXRoaW5nKCkpCmNsYXNzCmBgYAoKKipIZXJlJ3Mgd2hhdCB3ZSBkaWQgYWJvdmU6KiogCgoqIFdlIGFkZGVkIGEgbmV3IHZhcmlhYmxlIHRvIHRoZSBjbGFzcyBkYXRhIGZyYW1lIGNhbGxlZCAiYWdlX2dyb3VwLiIgSW4gdGhpcyBjYXNlLCBldmVyeSBwZXJzb24gd2hvIGhhcyBhIG5vbi1taXNzaW5nIHZhbHVlIG9mIGFnZS4uLgoKCmBgYHtyfQpjbGFzcyA8LSBjbGFzcyAlPiUgCiAgbXV0YXRlKAogICAgYm1pID0gKHd0X2xicyAvIGh0X2luXjIgKiA3MDMpLAogICAgYm1pXzNjYXQgPSBjYXNlX3doZW4oCiAgICAgIGJtaSA8IDI1ICAgICAgICAgICAgIH4gMSwKICAgICAgYm1pID49IDI1ICYgYm1pIDwgMzAgfiAyLCAjIE1ha2Ugc3VyZSB0byB0eXBlICJibWkiIHR3aWNlIQogICAgICBibWkgPj0gMzAgICAgICAgICAgICB+IDMgCiAgICApCiAgKQpjbGFzcwpgYGAKCgpTbyBmYXIsIHlvdeKAmXZlIGxlYXJuZWQgdG8gcmVhZCBpbiBkYXRhIGFuZCBjcmVhdGUgU0FTIGRhdGEgc2V0cy4gSG93ZXZlciwgdXAgdG8gdGhpcyBwb2ludCB5b3UgaGF2ZSBnZW5lcmFsbHkgaGFkIHRvIGFjY2VwdCB0aGUgZGF0YSBqdXN0IGFzIGl0IGlzLiBJbiB0aGlzIGxlc3NvbiB5b3Ugd2lsbCBiZWdpbiB0byBtYW5pcHVsYXRlIHRoZSBkYXRhLCBzbyB0aGF0IGl04oCZcyBtb3JlIHVzZWZ1bCBmb3IgeW91ciBzcGVjaWZpYyBuZWVkcy4gCkFzIFNBUyBwcm9ncmFtbWVycyB0aGVyZSB3aWxsIG9mdGVuIGJlIHRpbWVzIHRoYXQgeW91IHdhbnQgdG8gbW9kaWZ5IHlvdXIgZGF0YSBvciB5b3VyIGFuYWx5c2lzIGluIHNvbWUgd2F5IGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBvbmUgb3IgbW9yZSB2YXJpYWJsZXMuCk1heWJlIHlvdSBvbmx5IHdhbnQgdG8gbG9vayBhdCBmZW1hbGUgcGFydGljaXBhbnRzIGluIHlvdXIgZGF0YSBzZXQsIG9yIGluZGl2aWR1YWxzIG9mIGEgY2VydGFpbiBhZ2UuIFBlcmhhcHMgeW91IGRlY2lkZSB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZSBhIHZhcmlhYmxlIHRoYXQgcmVwcmVzZW50cyB0aGUgcmVnaW9uIG9mIHRoZSBjb3VudHJ5IHNvbWVvbmUgaXMgZnJvbSwgYmFzZWQgb24ga25vd2xlZGdlIG9mIHRoZSBzdGF0ZSB0aGV5IGFyZSBmcm9tLiAKVGhlc2UgYXJlIGp1c3QgYSBjb3VwbGUgb2YgZXhhbXBsZXMgb2YgYW4gYWxtb3N0IGluZmluaXRlIG51bWJlciBvZiB3YXlzIGluIHdoaWNoIHlvdSBjYW4gdXNlIGNvbmRpdGlvbmFsIHByb2Nlc3NpbmcgaW4gU0FTLiBJdOKAmXMgY2FsbGVkIGNvbmRpdGlvbmFsIHByb2Nlc3NpbmcgYmVjYXVzZSB5b3UgdHlwZSBpbiBhIHNldCBvZiBjb25kaXRpb25zLCBTQVMgZXZhbHVhdGVzIHRob3NlIGNvbmRpdGlvbnMgYW5kIHRoZW4gZXhlY3V0ZXMgb3IgZG9lcyBub3QgZXhlY3V0ZSBzb21lIHByb2Nlc3Mgb3IgcHJvY2VkdXJlIGJhc2VkIG9uIHdoZXRoZXIgb3Igbm90IHRoZXNlIGNvbmRpdGlvbnMgYXJlIG1ldC4KQXMgYSBzaWxseSBleGFtcGxlLCBsZXTigJlzIHNheSB0aGF0IEkgd2FudCBteSBkYXVnaHRlciB0byB3ZWFyIGEgcmFpbmNvYXQgaWYgaXTigJlzIHJhaW5pbmcgb3V0c2lkZS4gU28gSSBnaXZlIGhlciBhIGNvbW1hbmQ6IOKAnElmIGl04oCZcyByYWluaW5nIG91dHNpZGUsIG1ha2Ugc3VyZSB0byB3ZWFyIHlvdXIgcmFpbmNvYXQgcGxlYXNlLuKAnSBJbiB0aGlzIGh5cG90aGV0aWNhbCBmYW50YXN5IHdvcmxkLCBzaGUgdGhlbiBzYXlzLCDigJx5ZXMsIGRhZCzigJ0gZ29lcyB0byB0aGUgd2luZG93IHRvIHNlZSBpZiBpdOKAmXMgcmFpbmluZyBhbmQgdGhlbiBlaXRoZXIgcHV0cyBvbiwgb3IgZG9lcyBub3QgcHV0IG9uIGhlciByYWluY29hdCBkZXBlbmRpbmcgb24gaWYgdGhlIGNvbmRpdGlvbiAocmFpbmluZykgaXMgbWV0LgpBbm90aGVyIGNvbW1vbmx5IHVzZWQgdGVybSBmb3IgY29uZGl0aW9uYWwgcHJvY2Vzc2luZyBpcyDigJxpZi10aGVuIHN0YXRlbWVudHMs4oCdIG9yIOKAnGlmLXRoZW4tZWxzZSBzdGF0ZW1lbnRzLuKAnSBKdXN0IGxpa2UgSSBoYXZlIHRvIHRlbGwgbXkgZGF1Z2h0ZXIgdG8gcHV0IG9uIGEgcmFpbmNvYXQsIEkgaGF2ZSB0byBpc3N1ZSBTQVMgY29tbWFuZHMgaW4gb3JkZXIgdG8gZ2V0IHRoZSByZXN1bHRzIEkgd2FudC4gSW4gb3JkZXIgZm9yIFNBUyB0byBleGVjdXRlIHRoZXNlIGNvbW1hbmRzIGZvciBjb25kaXRpb25hbCBwcm9jZXNzaW5nLCBJIGhhdmUgdG8gcHV0IHRoZW0gaW4gYSBmb3JtIHRoYXQgU0FTIHVuZGVyc3RhbmRzLiBPbmUgc3VjaCBmb3JtIGlzIHRoZSBJRi1USEVOLUVMU0Ugc3RhdGVtZW50LgpTbywgaWYgU0FTIHdlcmUgbXkgZGF1Z2h0ZXIsIEkgd291bGQgc2F5IGlmIGl04oCZcyByYWluaW5nIG91dHNpZGUsIHRoZW4gcHV0IG9uIGEgcmFpbmNvYXQuIElmIGl04oCZcyBub3QgcmFpbmluZyBvdXRzaWRlLCB0aGVuIGRvbuKAmXQgcHV0IG9uIGEgcmFpbmNvYXQuCk1vcmUgZ2VuZXJhbGx5LCB0aGUgSUYtVEhFTiBzdGF0ZW1lbnQgY2FuIGJlIHdyaXR0ZW4gaW4gdGhpcyB3YXkuIFRoZSBJRi1USEVOIHN0YXRlbWVudCBleGVjdXRlcyBhIFNBUyBzdGF0ZW1lbnQgZm9yIG9ic2VydmF0aW9ucyB0aGF0IG1lZXQgY2VydGFpbiBjb25kaXRpb25zLiBJbiB0aGUgSUYtVEhFTiBzdGF0ZW1lbnQgdGhlIGV4cHJlc3Npb24gaXMgYSBzZXF1ZW5jZSBvZiBvcGVyYW5kcyBhbmQgb3BlcmF0b3JzLiBUaGV5IGRlZmluZSBhIGNvbmRpdGlvbiBmb3Igc2VsZWN0aW5nIG9ic2VydmF0aW9ucy4gVGhlIHN0YXRlbWVudCBhZnRlciB0aGUga2V5d29yZCBUSEVOIGNhbiBiZSBhbnkgZXhlY3V0YWJsZSBTQVMgc3RhdGVtZW50LCBzdWNoIGFzIHRoZSBhc3NpZ25tZW50IHN0YXRlbWVudC4KSW4gdGhpcyBleGFtcGxlLCB0aGUgZXhwcmVzc2lvbiB0ZXN0cyB0aGUgdmFsdWVzIG9mIHR3byB2YXJpYWJsZXMgLSBzeXN0b2xpYyBibG9vZCBwcmVzc3VyZSBhbmQgZGlhc3RvbGljIGJsb29kIHByZXNzdXJlLiBUaGUgc3RhdGVtZW50IGFmdGVyIHRoZSBrZXl3b3JkIFRIRU4gYXNzaWducyBhIHZhbHVlIHRvIHRoZSB2YXJpYWJsZSBoeXBlcnRlbnNpb24uCkV4cHJlc3Npb25zIGNhbiBpbmNsdWRlIHZhcmlhYmxlcyBsaWtlIGpvYl90aXRsZSBhbmQgaHRfaW4uIFRoZXkgY2FuIGFsc28gaW5jbHVkZSBjb25zdGFudHMuIENvbnN0YW50cyBjYW4gaGF2ZSBjaGFyYWN0ZXIgdmFsdWVzIGxpa2UgbWFycmllZCBvciBzaW5nbGUsIG9yIHRoZXkgY2FuIGJlIG51bWVyaWMuIENoYXJhY3RlciBjb25zdGFudHMgbXVzdCBiZSBlbmNsb3NlZCBpbiBxdW90YXRpb24gbWFya3MsIGJ1dCBudW1lcmljIGNvbnN0YW50cyBzaG91bGQgbm90LiBUYWtlbiB0b2dldGhlciwgdGhlIHZhcmlhYmxlcyBhbmQgY29uc3RhbnRzIG1ha2UgdXAgdGhlIG9wZXJhbmRzIG9mIGFuIGV4cHJlc3Npb24uIEFkZGl0aW9uYWxseSwgZXhwcmVzc2lvbnMgdXNlIG9wZXJhdG9ycyB0byBzcGVjaWZ5IHRoZSBjb25kaXRpb25zIHRoYXQgU0FTIHdpbGwgZXZhbHVhdGUuClRoZXNlIGFyZSBleGFtcGxlcyBvZiBjb21tb25seSB1c2VkIGNvbXBhcmlzb24gb3BlcmF0b3JzLiBDb21wYXJpc29uIG9wZXJhdG9ycyBjb21wYXJlIGEgdmFyaWFibGUgd2l0aCBhIGNvbnN0YW50IG9yIGFub3RoZXIgdmFyaWFibGUuWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBzeW1ib2wgb3IgdGhlIG1uZW1vbmljIGluIHlvdXIgY29kZS4KTG9vayBvdmVyIHRoZXNlIGV4YW1wbGVzIG9mIGNvbXBhcmlzb24gb3BlcmF0b3JzIHVzZWQgaW4gSUYtVEhFTiBzdGF0ZW1lbnRzLgpIZXJlIGlzIGEgbGlzdCBvZiBjb21tb25seSB1c2VkIGFyaXRobWV0aWMgb3BlcmF0b3JzLCBhbmQgc29tZSBleGFtcGxlcyBvZiBob3cgdGhleSBtYXkgYmUgdXNlZCBpbiBJRi1USEVOIHN0YXRlbWVudHMuIEFzIHRoZXNlIGV4YW1wbGVzIGRlbW9uc3RyYXRlLCBib3RoIGNvbXBhcmlzb24gYW5kIGFyaXRobWV0aWMgb3BlcmF0b3JzIGNhbiBiZSB1c2VkIGluIHRoZSBzYW1lIHN0YXRlbWVudC4KTG9naWNhbCBvcGVyYXRvcnMgY29tYmluZSBvciBtb2RpZnkgZXhwcmVzc2lvbnMuIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgc3ltYm9sIG9yIHRoZSBtbmVtb25pYyBpbiB5b3VyIGNvZGUuIEhlcmUgeW91IGNhbiBzZWUgdGhlIGxvZ2ljYWwgb3BlcmF0b3JzIHRoYXQgYXJlIGF2YWlsYWJsZSwgYW5kIGEgZmV3IGV4YW1wbGVzIG9mIGhvdyB0aGUgbWF5IGJlIHVzZWQgaW4gYSBJRi1USEVOIHN0YXRlbWVudHMuCldoZW4gdXNpbmcgQm9vbGVhbiBvcGVyYXRvcnMgLCByZW1lbWJlciB0aGF0IHRoZSDigJxhbmTigJ0gb3BlcmF0b3IgaGFzIHByZWNlZGVuY2Ugb3ZlciB0aGUgb3Igb3BlcmF0b3IuIApUaGF0IGlzLCBhIHN0YXRlbWVudCBzdWNoIGFzIHRoZSBmb2xsb3dpbmc6CklmIHggYW5kIHkgb3IgegpJcyBlcXVpdmFsZW50IHRvOgpJZiAoeCBhbmQgeSkgb3IgegpJZiB5b3Ugd2FudCB0byBwZXJmb3JtIHRoZSDigJxvcuKAnSBvcGVyYXRpb24gYmVmb3JlIHRoZSDigJxhbmTigJ0gb3BlcmF0aW9uLCB1c2UgcGFyZW50aGVzZXMgbGlrZSB0aGlzOgpJZiB4IGFuZCAoeSBvciB6KQpBcyBhIHNpZGUgbm90ZTogdGhlIOKAnG5vdOKAnSBvcGVyYXRvciwgd2hpY2ggd2FzbuKAmXQgZGVtb25zdHJhdGVkIGhlcmUsIGhhcyB0aGUgaGlnaGVzdCBwcmVjZWRlbmNlIG9mIGFsbC4KWW91IHdlcmUgYWxyZWFkeSBpbnRyb2R1Y2VkIHRvIGFzc2lnbm1lbnQgc3RhdGVtZW50cyBpbiB0aGUgbGFzdCBtb2R1bGUuIEFzIGEgcmVtaW5kZXIsIHlvdSBjYW4gdXNlIGFuIGFzc2lnbm1lbnQgc3RhdGVtZW50IGluIGFueSBEQVRBIHN0ZXAgdG8gdHJhbnNmb3JtIHZhcmlhYmxlcywgY3JlYXRlIHZhcmlhYmxlcywgY2FsY3VsYXRlIG5ldyB2YWx1ZXMgZm9yIHZhcmlhYmxlcywgYW5kIG1vcmUuIFRvIGRvIHRoaXMsIHRoZSBhc3NpZ25tZW50IHN0YXRlbWVudCBldmFsdWF0ZXMgYW4gZXhwcmVzc2lvbiBhbmQgYXNzaWducyB0aGUgcmVzdWx0aW5nIHZhbHVlIHRvIGEgdmFyaWFibGUuIFRoZSBnZW5lcmFsIGZvcm0gb2YgdGhlIGFzc2lnbm1lbnQgc3RhdGVtZW50IGlzIHNob3duIGhlcmUuCkluIHRoaXMgZXhhbXBsZSwgbGV04oCZcyBzYXkgdGhhdCB5b3UgZGlzY292ZXIgdGhhdCB0aHJlZSBtb3NxdWl0byB0cmFwcyB3ZXJlIG1pc2NsYXNzaWZpZWQgYXMgbGlnaHQgdHJhcHMgd2hlbiB0aGV5IHdlcmUgYWN0dWFsbHkgY2hlbWljYWwgYXR0cmFjdGFudCB0cmFwcy4gWW91IHdyaXRlIGEgU0FTIHByb2dyYW0gdG8gY2hhbmdlIHRyYXAgdHlwZSBmcm9tIDIgdG8gMSBmb3IgdGhlc2UgdGhyZWUgdHJhcHMuIApXaGVuIHlvdSBydW4gdGhpcyBwcm9ncmFtLCB0aGUgSUYtVEhFTiBzdGF0ZW1lbnQgd2lsbCBleGVjdXRlIG9uY2UgZm9yIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIGRhdGEgc2V0LiBJZiB0aGUgdHJhcCBudW1iZXIgZG9lc27igJl0IGVxdWFsIHRoZSBzcGVjaWZpZWQgdmFsdWUsIHRoZSB2YWx1ZSBvZiB0eXBlIGRvZXNu4oCZdCBjaGFuZ2UgZm9yIHRoYXQgb2JzZXJ2YXRpb24uIEluIHRoaXMgY2FzZSwgdGhlIHZhbHVlIG9mIHRyYXAgaW4gdGhlIHByb2dyYW0gZGF0YSB2ZWN0b3IgZG9lcyBub3QgbWF0Y2ggdGhlIHZhbHVlIGluIHRoZSBmaXJzdCBJRi1USEVOIHN0YXRlbWVudCwgc28gdGhlIHZhbHVlIG9mIHR5cGUgcmVtYWlucyAyLiBUaGUgZXhwcmVzc2lvbiBpbiB0aGUgbmV4dCB0d28gSUYtVEhFTiBzdGF0ZW1lbnRzIGFyZSBhbHNvIGZhbHNlLCBzbyB0eXBlIGNvbnRpbnVlcyB0byBoYXZlIGEgdmFsdWUgb2YgMiBmb3IgdGhpcyBvYnNlcnZhdGlvbi4gTmV4dCBTQVMgcmVhY2hlcyB0aGUgUlVOIHN0YXRlbWVudCwgd3JpdGVzIHRoZSBvYnNlcnZhdGlvbiBjdXJyZW50bHkgaW4gdGhlIHByb2dyYW0gZGF0YSB2ZWN0b3Igb3V0IHRvIHRoZSB0ZW1wb3JhcnkgU0FTIGRhdGEgc2V0IGNhbGxlZCBleGFtcGxlLAphbmQgdGhlbiByZWFkcyBpbiB0aGUgbmV4dCBvYnNlcnZhdGlvbiBmcm9tIG50cmhkLm1vc3F1aXRvIGludG8gdGhlIFBEVi4gQWxsIHRoZSBleHByZXNzaW9ucyBhcmUgZmFsc2UgZm9yIHRoaXMgb2JzZXJ2YXRpb24gYXMgd2VsbC4KRXZlbnR1YWxseSBTQVMgZ2V0cyB0byB0aGlzIG9ic2VydmF0aW9uLiBUaGlzIHRpbWUsIHRoZSBjb25kaXRpb24gaW4gdGhlIGZpcnN0IElGLVRIRU4gc3RhdGVtZW50IGlzIHRydWUuClNvLCBTQVMgY2hhbmdlcyB0aGUgdmFsdWUgb2YgdHlwZSB0byBvbmUgZm9yIHRoaXMgb2JzZXJ2YXRpb24uIFRoZSByZW1haW5pbmcgSUYtVEhFTiBzdGF0ZW1lbnRzIGFyZSBmYWxzZSBmb3IgdGhpcyBvYnNlcnZhdGlvbi4gTm90aWNlIHRoYXQgdGhlc2UgSUYtVEhFTiBzdGF0ZW1lbnRzIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuIE5vIG1vcmUgdGhhbiBvbmUgb2YgdGhlbSBjYW4gYmUgdHJ1ZSBhdCBhIHRpbWUuIFRoZXJlZm9yZSwgb25jZSBTQVMgZW5jb3VudGVycyBhIHRydWUgc3RhdGVtZW50LCBjaGVja2luZyB0aGUgb3RoZXIgc3RhdGVtZW50cyBpcyBhIHdhc3RlIG9mIHRpbWUgYW5kIGNvbXB1dGluZyBwb3dlci4KQWRkaW5nIHRoZSBrZXl3b3JkIEVMU0UgaXMgbXVjaCBtb3JlIGVmZmljaWVudC4gV2hlbiB5b3Ugc3BlY2lmeSBlbHNlLCBhbmQgb25lIGNvbmRpdGlvbiBpcyB0cnVlLCBTQVMgc2tpcHMgdGhlIHJlbWFpbmluZyBjb25kaXRpb25zLgpOb3cgeW91IGFyZSBnb2luZyB0byBwcmVwYXJlIGFuZCBpbXBvcnQgdGhlIGRhdGEgZnJvbSBhIHN1cnZleSBsaWtlIHRoZSBvbmUgeW91IHRvb2sgb24gdGhlIGZpcnN0IGRheSBvZiB0aGlzIGNvdXJzZS4gWW91IHdpbGwgdXNlIHRoaXMgZGF0YSB0byBwcmFjdGljZSBjb25kaXRpb25hbCBwcm9jZXNzaW5nIHVzaW5nIElGLVRIRU4tRUxTRSBzdGF0ZW1lbnRzLgpTbyBoZXJlIHlvdSBlc3NlbnRpYWxseSBoYXZlIHR3byByb3dzIHdpdGggdmFyaWFibGUgbmFtZXM6IFRoZSBmaXJzdCByb3cgZ2l2ZXMgYSBnZW5lcmljIExldHRlci9OdW1iZXIgbmFtZSwgYW5kIHNlY29uZCByb3cgZ2l2ZXMgdGhlIGVudGlyZSB0ZXh0IG9mIGVhY2ggc3VydmV5IHF1ZXN0aW9uLiAKV2hpY2ggZG8geW91IHRoaW5rIGlzIGJldHRlciBmb3IgeW91ciBwdXJwb3Nlcz8KVGhlbiB5b3UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSBzb21lIGNoYXJhY3RlciB2YXJpYWJsZXMgY29udGFpbmluZyBzb21lIHNvcnQgb2YgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgcmVzcG9uc2UgaWQsIG5hbWUsIGlwIGFkZHJlc3MsIGFuZCBzb21lIG90aGVyIHN0dWZmIHRoYXQgeW91IGRvbuKAmXQgcmVhbGx5IGNhcmUgYWJvdXQuIApOZXh0IHlvdSBzZWUgdGhhdCBzdGFydCBkYXRlIGFuZCBlbmQgZGF0ZSBhcmUgZmlsbGVkIHdpdGggYSBidW5jaCBvZiBoYXNodGFncy4gQWxsIHRoaXMgbWVhbnMgaXMgdGhhdCB0aGUgY29sdW1uIGlzbuKAmXQgd2lkZSBlbm91Z2ggdG8gZGlzcGxheSB0aGUgZGF0YS4gSWYgeW91IGRvdWJsZSBjbGljayB0aGUgbGluZSBpbiB0aGUgY29sdW1uIGhlYWRlciBiZXR3ZWVuIGNvbHVtbiBoIGFuZCBjb2x1bW4gaSwgYW5kIGJldHdlZW4gY29sdW1uIEkgYW5kIGNvbHVtbiBqLCB0aGV5IHdpbGwgd2lkZW4gYW5kIHRoZSBkYXRhIHdpbGwgYmUgZGlzcGxheWVkLgpUaGF04oCZcyBpbnRlcmVzdGluZy4gTm90aWNlIGFueXRoaW5nIGRpZmZlcmVudCBhYm91dCB0aGVzZSBkYXRlcz8gVGhleSBpbmNsdWRlIHRoZSBkYXRlIGFuZCB0aGUgdGltZSB0aGF0IHRoZSBzdXJ2ZXkgd2FzIHN0YXJ0ZWQgYW5kIGNvbXBsZXRlZC4KRmluYWxseSwgeW91IHNlZSBhbGwgb2YgeW91ciBzdWJzdGFudGl2ZSBxdWVzdGlvbnMgYW5kIHZhbHVlcyByZXByZXNlbnRpbmcgeW91ciByZXNwb25zZXMuIEJ1dCBsb29rIGF0IFExMSBhbmQgUTEyLiAKQXJlIHRoZXNlIG51bWVyaWMgdmFyaWFibGVzIG9yIGNoYXJhY3RlciB2YXJpYWJsZXM/IEhvdyB3aWxsIHlvdSBkZWFsIHdpdGggdGhlc2U/Ck5vdyB5b3UgY291bGQgYWhlYWQgYW5kIGRvIGFsbCB0aGUgY29kaW5nIG5lY2Vzc2FyeSB0byByZWFkIHRoaXMgaW50byB0byBTQVMgYXMgYSAuY3ZzIGZpbGU7IGhvd2V2ZXIsIEkgdGhpbmsgaXTigJlzIG11Y2ggZWFzaWVyIHRvIHNhdmUgaXQgYXMgYSBleGNlbCBmaWxlIGFuZCBpbXBvcnQgaXQgaW50byBTQVMuIFJlbWVtYmVyLCB5b3UgYWx3YXlzIHdhbnQgdG8ga2VlcCB0aGUgb3JpZ2luYWwgcmF3IGRhdGEgZmlsZSBpbnRhY3QsIHNvIHRoZSBmaXJzdCB0aGluZyB5b3Ugd2lsbCBkbyBpcyDigJxTYXZlIGFz4oCdCkluIHRoZSDigJhzYXZlIGFz4oCZIG1lbnUgeW91IGNhbiBhaGVhZCBhbmQgYWNjb21wbGlzaCBhIGNvdXBsZSB0aGluZ3MuIEZpcnN0LCBsZXTigJlzIG5hbWUgdGhlIG5ldyBmaWxlIHNvbWV0aGluZyBtb3JlIHNpbXBsZS4KTmV4dCwgbGV04oCZcyBnbyBhaGVhZCBhbmQgY29udmVydCB0aGlzIGludG8gYW4gZXhjZWwgZmlsZSB1c2luZyB0aGUg4oCcZm9ybWF04oCdIGRyb3AtZG93biBtZW51LgpOb3cgbGV04oCZcyB0YWtlIGNhcmUgb2YgdGhlIHR3byBoZWFkZXIgcm93cy4gSeKAmWxsIHN0YXJ0IGJ5IGRlbGV0aW5nIHRoZSB2ZXJ5IHdvcmR5IHNlY29uZCByb3cuCldoeSB5b3XigJlyZSBhdCBpdCwgbGV04oCZcyBnbyBhaGVhZCBhbmQgZ2V0IHJpZCBvZiB0aGUgZmlyc3QgNyBjb2x1bW5zLiBJ4oCZbSBub3QgcmVhbGx5IGludGVyZXN0ZWQgaW4gYW55IG9mIHRoaXMgaW5mb3JtYXRpb24uCk5vdyB5b3UgaGF2ZSBzb21ldGhpbmcgdGhhdCBzaG91bGQgYmUgYSBsaXR0bGUgYml0IG1vcmUgc3RyYWlnaHRmb3J3YXJkIHRvIGltcG9ydCBpbnRvIFNBUy4gVGhlcmUgYXJlIG90aGVyIGNoYW5nZXMgdGhhdCB5b3UgY291bGQgbWFrZSByaWdodCBoZXJlIGluIHRoZSBleGNlbCBmaWxlOyBob3dldmVyLCBmb3IgaW5zdHJ1Y3Rpb25hbCBwdXJwb3NlcyBJIHdvdWxkIGxpa2UgeW91IHRvIG1ha2UgdGhlc2UgY2hhbmdlcyBpbiBTQVMuIFNvLCBsZXTigJlzIHNhdmUgdGhpcyBvbmNlIG1vcmUsIGFuZCB0aGVuIGltcG9ydCBpdCBpbnRvIFNBUy4KSSBoYXZlIGFscmVhZHkgY3JlYXRlZCBhIG5ldyBTQVMgbGlicmFyeSBjYWxsZWQgY2xhc3MuIEkgaGF2ZSBhbHNvIGltcG9ydGVkIHRoZSBjbGFzcyBzdXJ2ZXkgZGF0YSB1c2luZyB0aGUgaW1wb3J0IHdpemFyZCwgYW5kIHNhdmVkIHRoZSBuZXcgU0FTIGRhdGEgc2V0IGluIHRoZSBjbGFzcyBsaWJyYXJ5LgpBbmQgaGVyZSBpcyB0aGUgZGF0YS4gTm90aWNlIHRoYXQgdGhlcmUgYXJlIG5vIHVuaXF1ZSBpZGVudGlmaWVycyBhc3NvY2lhdGVkIHdpdGggZWFjaCBvYnNlcnZhdGlvbi4gTGV04oCZcyBnbyBhaGVhZCBhbmQgZ2l2ZSBlYWNoIHBhcnRpY2lwYW50IGFuIGlkIG51bWJlci4KVG8gYXNzaWduIHNlcXVlbnRpYWwgbnVtYmVycyB0byBvYnNlcnZhdGlvbnMgaW4gYSBkYXRhIHNldCBpbiBTQVMsIGNyZWF0ZSBhIHZhcmlhYmxlIHVzaW5nIF9OXy4gWW914oCZdmUgYWxyZWFkeSBsZWFybmVkIHRoYXQgX05fIGlzIGNyZWF0ZWQgaW4gdGhlIFBEViwgYnV0IG5vdCBvdXRwdXQgdG8gdGhlIG5ldyBTQVMgZGF0YSBzZXQuIEluIHRoaXMgcHJvZ3JhbSB3ZSBhcmUgY3JlYXRpbmcgYSBuZXcgdmFyaWFibGUgaW4gdGhlIFBEViBhbmQgc2V0dGluZyBpdCBlcXVhbCB0byB0aGUgdmFsdWUgb2YgX05fIGZvciBlYWNoIG9ic2VydmF0aW9uLiBBbHRob3VnaCBfTl8gc3RpbGwgaXNu4oCZdCB3cml0dGVuIHRvIHRoZSBTQVMgZGF0YSBzZXQgc3VydmV5MiwgdGhlIHZhcmlhYmxlIGlkIGlzLCBhbmQgaXQgY29udGFpbnMgdGhlIHZhbHVlIG9mIF9OXyBmb3IgZWFjaCBvYnNlcnZhdGlvbi4gVGhpcyBpcyBhIHJlYWxseSBoYW5keSB3YXkgb2YgY3JlYXRpbmcgYSBzZXF1ZW50aWFsbHkgbnVtYmVyZWQgdmFyaWFibGUgaW4gU0FTLgpOb3cgaXQgaXMgbm90IG5lY2Vzc2FyeSB0byBtYWtlIGlkIHRoZSBmaXJzdCB2YXJpYWJsZSBpbiB0aGUgU0FTIGRhdGEgc2V0LiBIb3dldmVyLCBieSBjb252ZW50aW9uLCB0aGlzIGlzIHVzdWFsbHkgZG9uZSwgYW5kIGl04oCZcyBzb21ldGhpbmcgSSBsaWtlIHRvIGRvLiBPbmUsIG9mIG1hbnkgZGlmZmVyZW50IHdheXMgdG8gZG8gdGhpcyBpcyB3aXRoIHRoZSBSRVRBSU4gc3RhdGVtZW50IGluIGEgZGF0YSBzdGVwLiBZb3Ugc2ltcGx5IHR5cGUgdGhlIGtleXdvcmQgcmV0YWluLCBhbmQgdGhlbiB0eXBlIHRoZSB2YXJpYWJsZXMgaW4gdGhlIG9yZGVyIHlvdSB3YW50IHRoZW0uIEFueSB2YXJpYWJsZXMgdGhhdCBhcmVu4oCZdCBzcGVjaWZpY2FsbHkgbGlzdGVkIGluIHRoZSBSRVRBSU4gc3RhdGVtZW50IHdpbGwgY29tZSBhZnRlciB0aGUgdmFyaWFibGVzIGxpc3RlZCBpbiB0aGUgcmV0YWluIHN0YXRlbWVudCBhbmQgcmVtYWluIGluIHRoZWlyIGN1cnJlbnQgb3JkZXIuClRoZW4sIHRvIGltcHJvdmUgcmVhZGFiaWxpdHksIHlvdSB3aWxsIGdvIGFoZWFkIGFuZCByZW5hbWUgeW91ciB2YXJpYWJsZXMsIGxhYmVsIHlvdXIgdmFyaWFibGVzLCBhbmQgZm9ybWF0IHlvdXIgdmFyaWFibGVzLgpOb3cgeW91ciBkYXRhIGlzIGEgbGl0dGxlIG1vcmUgdXNlciBmcmllbmRseSwgYW5kIHlvdSBjYW4gY29udGludWUgb24gd2l0aCBjb25kaXRpb25hbCBwcm9jZXNzaW5nLgpGb3Igc3RhcnRlcnMsIGluIHlvdXIgY2xhc3Mgc3VydmV5IGRhdGEgdGhlcmUgd2FzIGEgcXVlc3Rpb24gdGhhdCBhc2tlZCBhYm91dCB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuIHVuZGVyIGFnZSAxOCBsaXZpbmcgaW4geW91ciBob21lLiBMZXTigJlzIHNheSB0aGF0IHlvdSBhcmUgcmVhbGx5IGp1c3QgaW50ZXJlc3RlZCBpbiBrbm93aW5nIGlmIHlvdSBoYXZlIG5vIGNoaWxkcmVuLCBvbmUgY2hpbGQsIG9yIG1vcmUgdGhhbiBvbmUgY2hpbGQg4oCTIGFuZCB5b3Ugd2FudCB0byBjcmVhdGUgYSBuZXcgdmFyaWFibGUgY2FsbGVkIGNoaWxkM2NhdCAoZm9yIDMgY2F0ZWdvcmllcykgdGhhdCBjYXB0dXJlcyB0aGlzIGluZm9ybWF0aW9uLiBZb3UgY2FuIGRvIHRoaXMgdXNpbmcgSUYtVEhFTiBzdGF0ZW1lbnRzLgpIZXJlIHlvdSBzZWUgYSBjb21tb24gZmlyc3QgYXR0ZW1wdCBhdCBjb21wbGV0aW5nIHRoaXMgdGFzay4gWW91IGFyZSB0ZWxsaW5nIFNBUyBpZiB0aGUgdmFsdWUgZm9yIHRoZSB2YXJpYWJsZSBjaGlsZHJlbiBpcyBsZXNzIHRoYW4gMSwgdGhlbiB0aGUgdmFsdWUgZm9yIHRoZSB2YXJpYWJsZSBjaGlsZDNjYXQgKHdoaWNoIFNBUyB3aWxsIGNyZWF0ZSBpZiBpdCBkb2VzbuKAmXQgYWxyZWFkeSBleGlzdCkgaW4gdGhlIHNhbWUgb2JzZXJ2YXRpb24gc2hvdWxkIGVxdWFsIDAuIE5leHQgaWYgdGhlIHZhbHVlIGZvciB0aGUgdmFyaWFibGUgY2hpbGRyZW4gaXMgZXF1YWwgdG8gMSwgdGhlbiB0aGUgdmFsdWUgZm9yIHRoZSB2YXJpYWJsZSBjaGlsZDNjYXQgaW4gdGhlIHNhbWUgb2JzZXJ2YXRpb24gc2hvdWxkIGVxdWFsIDEuIEFuZCBmaW5hbGx5LCBpZiB0aGUgdmFsdWUgZm9yIGNoaWxkcmVuIGlzIGdyZWF0ZXIgdGhhbiAxLCB0aGVuIHRoZSB2YWx1ZSBmb3IgdGhlIHZhcmlhYmxlIGNoaWxkM2NhdCBpbiB0aGUgc2FtZSBvYnNlcnZhdGlvbiBzaG91bGQgZXF1YWwgMi4gClNvIHlvdSBjYW4gc2VlIHRoYXQgdGhlIHZhcmlhYmxlIGNoaWxkM2NhdCB3YXMgY3JlYXRlZCwgYnV0IHlvdSBoYXZlIGEgcHJvYmxlbS4gU0FTIGlzIGNhdGVnb3JpemluZyBzdHVkZW50cyB3aG8gZGlkbuKAmXQgYW5zd2VyIHRoZSBxdWVzdGlvbiBhYm91dCBjaGlsZHJlbiBhcyBoYXZpbmcgbm8gY2hpbGRyZW4uIEFuZCBpdCdzIHBvc3NpYmxlIHRoYXQgdGhleSBkb24ndCBoYXZlIGFueSBjaGlsZHJlbiwgYnV0IHlvdSBkb24ndCBoYXZlIGFueSB3YXkgb2Yga25vd2luZyB0aGF0LCBkbyB5b3U/CldlbGwsIHRoaXMgaXMgdGhlIGZyZXF1ZW5jeSBwcm9jZWR1cmUuIEl0IHN0YXJ0cyB0aGUgU0FTIGtleXdvcmQgRlJFUSwgZm9sbG93ZWQgYnkgdGhlIGRhdGEgc2V0IGNvbnRhaW5pbmcgeW91ciBkYXRhLiBJbnN0ZWFkIG9mIGEgVkFSIHN0YXRlbWVudCwgUFJPQyBGUkVRIHVzZXMgdGhlIFRBQkxFIHN0YXRlbWVudC4gVGhpcyB3aWxsIG1ha2UgbW9yZSBzZW5zZSB3aGVuIHlvdSBjcmVhdGUgdHdvLXdheSB0YWJsZXMuIEZvciBub3cgeW91IG1heSBqdXN0IHdhbnQgdG8gbWVtb3JpemUgdGhpcyBkaWZmZXJlbmNlLiBMZXQncyBydW4gaXQuCkFzIHlvdSBjYW4gc2VlLCB0aGUgRlJFUSBwcm9jZWR1cmUgd2l0aCBvbmUgdmFyaWFibGUgaW4gdGhlIHRhYmxlIHN0YXRlbWVudCBwcm9kdWNlcyBhIG9uZS13YXkgZnJlcXVlbmN5IHRhYmxlLiBJbiB0aGUgZmlyc3QgY29sdW1uIGlzIHRoZSB2YXJpYWJsZSBuYW1lIGFuZCB0aGUgY2F0ZWdvcmllcyBmb3IgdGhhdCB2YXJpYWJsZS4gSW4gdGhlIHNlY29uZCBjb2x1bW4gaXMgdGhlIGZyZXF1ZW5jeSwgb3IgbnVtYmVyIG9mIHRpbWVzLCB0aGF0IGNhdGVnb3J5IGlzIG9ic2VydmVkIGluIHRoZSBkYXRhLiBJbiB0aGUgdGhpcmQgY29sdW1uIGlzIHRoZSBwZXJjZW50IG9mIHRoZSBvYnNlcnZhdGlvbnMgZm9yIHRoYXQgdmFyaWFibGUgdGhhdCBmYWxsIHdpdGhpbiBlYWNoIHJlc3BlY3RpdmUgY2F0ZWdvcnkuIFRoZSB0aGlyZCBhbmQgZm91cnRoIGNvbHVtbnMgYXJlIHRoZSBjdW11bGF0aXZlIGZyZXF1ZW5jeSBhbmQgcGVyY2VudCByZXNwZWN0aXZlbHkuIEZpbmFsbHksIG5vdGljZSBhdCB0aGUgYm90dG9tIHRoYXQgU0FTIHRlbGxzIHlvdSB0aGUgbnVtYmVyIG9mIG1pc3Npbmcgb2JzZXJ2YXRpb25zIGZvciB0aGlzIHZhcmlhYmxlLiBOb3cgbGV0J3MgY29tcGFyZSB0aGlzIHRvIHlvdXIgcmVjb2RlZCAzLWNhdGVnb3J5IHZhcmlhYmxlLgpCZWZvcmUgeW91IHJ1biB0aGUgc2Vjb25kIFBST0MgRlJFUSwgSSB3YW50IHRvIHBvaW50IG91dCB0aGF0IHRoZSB3YXkgeW91IGhhdmUgdGhlIHRhYmxlIHN0YXRlbWVudCBjb2RlZCBoZXJlIHRlbGxzIFNBUyB0aGF0IHlvdSB3YW50IHR3byBzZXBhcmF0ZSBvbmUtd2F5IGZyZXF1ZW5jeSB0YWJsZXMuIE9uZSBmb3IgdGhlIHZhcmlhYmxlIGNoaWxkcmVuLCBhbmQgb25lIGZvciB0aGUgdmFyaWFibGUgY2hpbGQzY2F0LgpOb3RpY2UgYW55IHByb2JsZW1zPyAKWW91IHNob3VsZC4gVGhlIGZyZXF1ZW5jaWVzIG9mIHBlb3BsZSB3aXRob3V0IGFueSBjaGlsZHJlbiBkb27igJl0IG1hdGNoIGJlY2F1c2UgeW91IGRpZG7igJl0IGNvbnNpZGVyIHRoYXQgU0FTIGNvdW50cyBtaXNzaW5nIGFzIHRoZSBtaW5pbXVtIHZhbHVlIGluIHlvdXIgcHJvZ3JhbS4gU28sIGhlcmUgaXMgb25lIHdheSB0byBmaXggdGhpcyBpc3N1ZS4KVGhpcyBleGFtcGxlIGlzIHRoZSBlYXNpZXN0IHdheS4gSnVzdCBjaGFuZ2UgdGhlIGZpcnN0IGlmIHN0YXRlbWVudCB0byByZWFkICJpZiBjaGlsZHJlbiBlcXVhbHMgemVybyB0aGVuIGNoaWxkM2NhdCBlcXVhbHMgemVyby4gQnV0LCBvdGhlciB0aW1lcywgaXQgbWF5IG5vdCBiZSB0aGlzIHN0cmFpZ2h0Zm9yd2FyZC4gSGVyZSBpcyBhbm90aGVyIHdheSB5b3UgY2FuIHdyaXRlIHlvdXIgY29kZS4KTm93IHlvdSBhcmUgdGVsbGluZyBTQVMgdG8gY29kZSBjaGlsZDNjYXQgYXMgemVybyBpZiB0aGUgdmFsdWUgZm9yIGNoaWxkcmVuIGlzIGdyZWF0ZXIgdGhhbiBtaXNzaW5nIGFuZCBpdCBpcyBhbHNvIGxlc3MgdGhhbiAxLiBOb3RpY2UgdGhhdCB5b3UgbXVzdCB0eXBlIHRoZSB3b3JkICJjaGlsZHJlbiIgYmVmb3JlIGJvdGggbG9naWNhbCBleHByZXNzaW9ucy4gQW5kIGp1c3QgdG8gYmUgc3VyZSB5b3UgYmVsaWV2ZSBtZSwgbGV04oCZcyBydW4gUFJPQyBGUkVRIGFnYWluLgpUaGVyZSwgbm93IHRoZXkgbWF0Y2guCkVhcmxpZXIgeW91IGxlYXJuZWQgYWJvdXQgdGhlIGVmZmljaWVuY3kgb2YgYWRkaW5nIHRoZSBrZXl3b3JkIEVMU0UgdG8geW91ciBJRi1USEVOIHN0YXRlbWVudHMuIFRvIHRha2UgZWZmaWNpZW5jeSBldmVuIG9uZSBzdGVwIGZ1cnRoZXIsIHlvdSBjYW4gY29kZSB0aGlzIGRhdGEgc3RlcCBpbiB0aGUgZm9sbG93aW5nIHdheTogSGVyZSB0aGUgZmlyc3QgaWYgc3RhdGVtZW50IHVzZXMgdGhlIG1pc3NpbmcgZnVuY3Rpb24uIFRoZSBtaXNzaW5nIGZ1bmN0aW9uIHJldHVybnMgYSB2YWx1ZSBvZiB0cnVlIGlmIHRoZSBhcmd1bWVudCAtIHRoZSB2YXJpYWJsZSBpbiBwYXJlbnRoZXNlcyDigJMgaXMgbWlzc2luZywgYW5kIGEgdmFsdWUgb2YgZmFsc2UgaWYgaXQgaXMgbm90IG1pc3NpbmcuIFRoZW4gaXQgbW92ZXMgb24gYW5kIGV2YWx1YXRlcyB0aGUgcmVtYWluaW5nIGlmIHN0YXRlbWVudHMgdW50aWwgb25lIGNvbWVzIGJhY2sgdHJ1ZS4gTm90aWNlIHRoYXQgeW91IG5vIGxvbmdlciBuZWVkIHRoZSAiaWYgY2hpbGRyZW4gZ3JlYXRlciB0aGFuIG1pc3NpbmciIHBhcnQgdG8gdGhlIHNlY29uZCBpZiBzdGF0ZW1lbnQuIFRoaXMgaXMgYmVjYXVzZSBtaXNzaW5nIGhhcyBhbHJlYWR5IGJlZW4gZXZhbHVhdGVkIEFORCB5b3UgYXJlIHVzaW5nIGlmLXRoZW4tZWxzZSBzdGF0ZW1lbnRzIGluc3RlYWQgb2YganVzdCBpZi10aGVuIHN0YXRlbWVudHMuCk5vdyBjb21wbGV0ZSB0aGlzIHByYWN0aWNlIHVzaW5nIElGLVRIRU4tRUxTRSBzdGF0ZW1lbnRzClRoaXMgY29tcGxldGVzIHRoZSB2aWRlbyBvbiBjb25kaXRpb25hbCBwcm9jZXNzaW5nLiBJdCBpcyBhbG1vc3QgaW1wb3NzaWJsZSB0byBvdmVyc3RhdGUgdGhlIGltcG9ydGFuY2Ugb2YgdW5kZXJzdGFuZGluZyBob3cgdG8gbWFuYWdlIHlvdXIgZGF0YSB1c2luZyBJRi1USEVOLUVMU0Ugc3RhdGVtZW50cy4gWW91IHdpbGwgdXNlIHRoZW0gZXZlcnkgdGltZSB5b3UgY29uZHVjdCBhbnkgc29ydCBvZiBhbmFseXNpcyBpbiB0aGUgcmVhbCB3b3JsZCwgYW5kIGEgbWlzdGFrZSBpbiB5b3VyIGNvbmRpdGlvbmFsIGxvZ2ljIHdpbGwgbGlrZWx5IGludmFsaWRhdGUgYWxsIG9mIHlvdXIgcmVzdWx0cy4gSSBlbmNvdXJhZ2UgeW91IHRvIHByYWN0aWNlLCBwcmFjdGljZSwgYW5kIHRoZW4gcHJhY3RpY2Ugc29tZSBtb3JlLiBUaGUgYmVzdCB3YXkgdG8gcmVkdWNlIHlvdXIgY2hhbmNlcyBvZiBtYWtpbmcgYSBtaXN0YWtlIGluIHlvdXIgY29uZGl0aW9uYWwgcHJvY2Vzc2luZyBpcyBleHBlcmllbmNlLgo=