Converting Word
Documents to PDFs
Before converting forms to pdfs, all required edits to the document
should be made in Microsoft Word. Edits of content or formatting should
be completed and finalized in Word before converting the document to a
pdf. To convert a Word document to a pdf, complete the following
steps:
- Open the document in Microsoft Word
- Click the “File” tab in the top left corner within the Word
interface
- Select “Save as ADOBE PDF”
- Name the new pdf accordingly
Editing pdfs in
Adobe
Open pdf in Adobe Acrobat Pro 2020
- Note: Editing of pdfs must be done in Adobe Acrobat Pro
2020, not Adobe Acrobat
Under the “Tools” tab in the top left corner of the Adobe
interface, find the heading “Forms & Signatures” and select “Prepare
Form”
Select “Start” to begin scanning and preparation of the
pdf
The “Prepare Form” tool bar should now be visible, allowing for
the addition of text fields, radio buttons, check boxes, and
more
Adding Text Fields,
Radio Buttons, and Check Boxes
- Text fields should be implemented when:
- Textual or numeric information must be manually entered
- A calculated field is required
- Radio buttons should be implemented whenever possible
- Radio buttons allow for only one selection out of a group of options
- Radio buttons thus should be used for imitation, comprehension,
practice, and test trial fields within pdfs
- In order to prevent human error, radio buttons should be applied to
as many variables as possible
- Calculated fields can be derived from radio buttons
- Check boxes should only be used when necessary
- Check boxes allow for multiple selections within a group
- Check boxes should not be used for trials fields
within pdfs unless multiple answers can be selected for a given
trial
- Calculated fields can be derived from check boxes
- Action buttons should be implemented when a specific action is
needed to be carried out. These actions typically include:
- Reseting a field(s)/form
- Hiding/Revealing a field(s)
Naming Convention for
Variables in Adobe
- Variable names should be in all lowercase with no spaces and
underscores separating words
- Keep variable names as consistent as possible across forms with
similar variables
- The following are common names for variables which should be used
when applicable:
- Identifying information:
- TCID:
tcid
- Wave:
wave
- Coder Name:
coder_name
- Date Coded:
date_coded
- Coder:
coder
(for 1, 2, 3 variable)
- Was TC given the opportunity to play the task:
given_opp_to_play
- Did TC play the task:
play_task
- PC Present:
pc_present
- Did TC pass the imitation trials:
pass_imitation
- Did TC pass the comprehension check:
pass_comprehension
- Did TC pass the practice trials:
pass_practiceX
- Start time:
task_start_time
- Stop time:
task_stop_time
- Length of administration:
task_length
- Coder 1/2/3:
initials_date_coderX
- Task Trials
- Imitation Trials:
imitation_trials_x
- Imitation Trials Second Administration:
imitation_trials_readmin_x
- Comprehension Check:
comp_checkX_x
- Practice Trials:
practice_trialsX_x
- Test Trials:
test_trialsX_x
- Note: “X” signifies the round/block of the trials while “x”
signifies the trial number within that round/block (ex:
practice_trials2_7
). An “X” within the variable name is
only necessary if there are multiple rounds/blocks for the trial. Thus,
if there is only one round of imitation trials, those trials should be
simply named test_trials
rather than
test_trials1
.
- Trial Totals
- Total Incorrect:
total_incorrect_task_trials
- Total Initially incorrect, but changed to correct:
total_initially_task_trials
- Total Correct:
total_correct_task_trials
- Total No Response:
total_noresponse_task_trials
- Total Uncodeable:
total_uncodeable_task_trials
- Total # of Scoreable Trials Played:
total_scored_task_trials
- Note: “task_trials” should be replaced with whether the
round/block of trials is
imitation_trials
,
comp_check
, practice_trials
, or
test_trials
.
Naming Convention
for Check Boxes
Check boxes can be named in such a way that they act similar to radio
buttons, allowing only one selection out of a group of check boxes.= A
group of check boxes can be formatted as radio buttons through the
following steps:
- Input the same variable name for each check box within the
group to be formatted
- Right click on each check box and select “Properties”
- Under the “Options” tab, set the “Export Value” for each check box
according to the following values:
- “Correct” column = 2
- “Incorrect” column = 0
- “Initially incorrect but changed response to correct” column =
1
- “No response” column = -9
- “Uncodeable” column = 9
- With each check box named the same but also each with a different
export value, the group of check boxes should now operate similar to a
group of radio buttons
- Within the group, only one check box should be able to be
selected
- Additionally, the selection should be able to be unselected
- While both groups of radio buttons and this form of groups of check
boxes operate the same way and permit only one selection within the
group, groups of check boxes provide an advantage by allowing for
deselection of the value. Within groups of radio buttons, as soon as a
button is selected, the group of buttons cannot be reset or deselected.
This usage of groups of check buttons may be useful going forward and
should be considered when creating new coding forms.
- Note: Creating calculated fields from groups of check boxes
will follow the same procedure as creating calcuated fields
from radio buttons. Thus, it is important to ensure the export
values for each check box follow the values listed in Step 3.
Hiding and Revealing
Fields in Adobe
Fields can be hidden and revealed within Adobe documents. To do such,
complete the following steps:
- Right click on the field to be hidden
- Select “Properties”
- Under the “General” tab, navigate to the “Common Properties” box at
the bottom of the tab
- For “Form Field:” select
Hidden
from the drop-down
menu
- Now, when previewing the document, the selected field should be
hidden from user view
- In order to make the field visible to users again, complete steps
1-4, but instead of selecting
Hidden
for “Form Field:”,
select Visible
- The field should now be visible to users
Creating Actions in
Adobe
Radio buttons, check boxes, text fields, and action buttons can all
be assigned specific actions upon clicking them. The most common actions
used are: * Clearing or reseting a field(s) or an entire form *
Hiding/revealing a field(s)
To assign a radio button, check box, text field, or action button an
action, complete the following steps:
- Right click on the object (the radio button/check box/text
field/action button in question) to which an action is to be
assigned
- Select the “Actions” tab
- Within the “Add an Action” interface, for “Select Trigger:” ensure
the response of
Mouse Up
is selected
- This configures the action to be executed when the object is clicked
upon with the user’s mouse
- Within the “Add an Action” interface, for “Select Action:” choose
the desired action to be assigned to the object from the drop-down menu
- To clear/reset a field:
- To hide/reveal a field:
- Within the “Add an Action” interface, select “Add…” to implement the
chosen action to the object
- Upon clicking add, a separate window will appear asking you to
specify which fields the action should be applied to
- If clearing/reseting a field:
- Mark all the check boxes of all the fields to be rest
- Select “OK”
- If hiding/revealing a field:
- Select the name of the field to be hidden/revealed
- On the right, select the radio button selection for whether the
action should
Show
or Hide
the field
- Select “OK”
- Upon selection of “OK,” the action should now appear within the
“Action” box at the bottom of the tab
- In order to edit the action, select the action to be edited and then
select “Edit” at the bottom of the interface
- Multiple actions can be assigned to the same object. Thus, repeat
steps 1-6 as many times as needed to assign the necessary actions to a
given object
Creating Calculated
Fields
Adobe Acrobat both includes its own functions for creating calculated
fields and allows for the implementation of custom calculation scripts
within forms. While the calculation features are built-in to Adobe, the
custom calculation scripts must be written using the programming
language JavaScript. The following sections detail how to create
different types of calculated fields.
Creating Calculated
Fields from Check Boxes
Prepare the check boxes for calculation:
Provide the check boxes from which the field will be calculated
with appropriate variable names, closely following standard naming convention for variables
when possible
For each check box, an export value must be assigned. The export
value will determine what numeric value the check box will carry
throughout calculation. To set the export value, complete the following
steps:
- Select and right-click on the check box and select “Properties”
- In the Properties menu, select the “Options” tab
- In the “Export Value:” field, enter the numeric value the check box
should reflect
Select the text field which must be turned into a calculated
field
Right-click on the field and select “Properties”
Select the “Calculate” tab within the Properties menu
Select the “Value is the mathematical operators
of
the following fields” radio button
- Note: The appropriate
mathematical operator
should be selected according to the desired final calculation from the
drop down list of “sum (+),” “product (x),” “average,” “minimum,” or
“maximum”
Select “Pick…” and then check the variable names of the check
boxes to be calculated
Breaking Down the
Calculation Script
var v1 = getField("variable_group_name").value
var v2 = getField("variable_group_name2").value
var v3 = getField("variable_group_name3").value
var v4 = getField("variable_group_name4").value
if (v1 == X) {
total = 1;
} else {
total = 0;
}
if (v2 == X) {
total2 = 1;
} else {
total2 = 0;
}
if (v3 == X) {
total3 = 1;
} else {
total3 = 0;
}
if (v4 == X) {
total4 = 1;
} else {
total4 = 0;
}
event.value = total + total2 + total3 + total4
The calculation script for radio buttons can be broken down into
three parts:
Defining the Variables
var v1 = getField("variable_group_name").value
var v2 = getField("variable_group_name2").value
var v3 = getField("variable_group_name3").value
var v4 = getField("variable_group_name4").value
- This portion of the script defines the variables from which
information is being pulled from. In nearly all cases the variables
being pulled from will be the groups of radio buttons for each
trial.
- The line
var v1 = getField("variable_group_name").value
defines the selected radio button in “variable_group_name” as
var v1
(variable 1) within this script and pulls the
choice value from each group
- Thus, within each
getField()
, the name of each group of
radio buttons should be added in quotations
- Note: The number being pulled through this function
directly corresponds to the choice value defined for each radio button
in the group of radio of radio buttons. This is why it is crucial to
define choice values according to the same naming convention for
radio buttons
- Each
var vX
should reflect a trial on the form. Thus,
if there are 15 test trials, there should be 15 lines of code from
var v1
to var v15
with the name for each group
of radio buttons inputed in getField("")
for each
variable
Defining the Selected Values
if (v1 == X) {
total = 1;
} else {
total = 0;
}
if (v2 == X) {
total2 = 1;
} else {
total2 = 0;
}
if (v3 == X) {
total3 = 1;
} else {
total3 = 0;
}
if (v4 == X) {
total4 = 1;
} else {
total4 = 0;
}
- This portion of code utilizes if/else statements in order to create
the total value for each field
- In
v1 == X
and each subsequent v == X
, the
X
should be replaced with the choice value
of the radio button from the group of radio buttons that corresponds to
the desired field you are calculating
For example, if a total correct field is being calculated, the
code should read:
if (v1 == 2) {
total = 1;
} else {
total = 0;
}
if (v2 == 2) {
total2 = 1;
} else {
total2 = 0;
}
Because a total correct field is being calculated, the choice
value of 2 should be inputed as this is the choice value which
corresponds to “Correct” (see naming convention for
radio buttons)
The value of 2 would be inputed for each if/else statement for
each variable. Thus, if there were 15 variables, there should be 15
if/else statements v1 == 2
to
v15 == 2
- The if/else statement for each variable defines that if the value
pulled by the
getField()
function matches the inputted
choice value for the variable then the total for that variable becomes
equal to 1. If it does not match, the the total becomes equal to 0.
Defining the Total
event.value = total + total2 + total3 + total4
- This portion of code defines the calculation to take place in the
field
- The
event.value
determines what appears in the text
box
- This line of code adds together the totals defined in the if/else
statements. This produces the final calculated value for the field.
- The number of totals added together should correspond to the number
of variables. Thus, if there are 15 trials, then the final line of code
should read:
event.value = total + total2 + total3 + total4 + total5 + total6 + total7 + total8 + total9 + total10 + total11 + total12 + total13 + total14 + total15
The following is an example script for a calculated
“total_correct_test_trials” field, calculated from 15 trials:
var v1 = getField("test_trials_1").value
var v2 = getField("test_trials_2").value
var v3 = getField("test_trials_3").value
var v4 = getField("test_trials_4").value
var v5 = getField("test_trials_5").value
var v6 = getField("test_trials_6").value
var v7 = getField("test_trials_7").value
var v8 = getField("test_trials_8").value
var v9 = getField("test_trials_9").value
var v10 = getField("test_trials_10").value
var v11 = getField("test_trials_11").value
var v12 = getField("test_trials_12").value
var v13 = getField("test_trials_13").value
var v14 = getField("test_trials_14").value
var v15 = getField("test_trials_15").value
if (v1 == 2) {
total = 1;
} else {
total = 0;
}
if (v2 == 2) {
total2 = 1;
} else {
total2 = 0;
}
if (v3 == 2) {
total3 = 1;
} else {
total3 = 0;
}
if (v4 == 2) {
total4 = 1;
} else {
total4 = 0;
}
if (v5 == 2) {
total5 = 1;
} else {
total5 = 0;
}
if (v6 == 2) {
total6 = 1;
} else {
total6 = 0;
}
if (v7 == 2) {
total7 = 1;
} else {
total7 = 0;
}
if (v8 == 2) {
total8 = 1;
} else {
total8 = 0;
}
if (v9 == 2) {
total9 = 1;
} else {
total9 = 0;
}
if (v10 == 2) {
total10 = 1;
} else {
total10 = 0;
}
if (v11 == 2) {
total11 = 1;
} else {
total11 = 0;
}
if (v12 == 2) {
total12 = 1;
} else {
total12 = 0;
}
if (v13 == 2) {
total13 = 1;
} else {
total13 = 0;
}
if (v14 == 2) {
total14 = 1;
} else {
total14 = 0;
}
if (v15 == 2) {
total15 = 1;
} else {
total15 = 0;
}
event.value = total + total2 + total3 + total4 + total5 + total6 + total7 + total8 + total9 + total10 + total11 + total12 + total13 + total14 + total15
Time Calculations in
Adobe
Calculating a time based on two other times can be accomplished
within Adobe. To do this, custom calculation scripts using the language
JavaScript must be implemented.
Creating Time
Calculations in Adobe
- First, ensure all fields from which the time calculations are to be
made from or applied to have been formatted into the desired time
format. To do this:
- Right click on the field and select “Properties”
- Navigate to the “Format” tab
- For “Select format category:” select
Time
- In the “Time Options” interface that appears, select the desired
time format
- Repeat this for every field that the time calculations will be made
from or applied to
- The following calculation script calculates time in the
HH:MM:ss
format
- Select the field in which the time calculation will occur
- Right click on the field and select “Properties”
- Select the “Calculate” tab
- Select the “Custom calculation script:” radio button
- Select “Edit…” and input the desired time calculation script
The following script details how to calculate X second intervals
based on an inputted starting time. The times within this script follow
the HH:MM:ss
time format. The following script can easily
be modified to calculate different length intervals or to use different
time formats.
var timestarted = this.getField("start_time_field").valueAsString;
var timeSplit = timestarted.split(":") ;
var totalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1));
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + "INTERVAL LENGTH X");
hours = Math.floor(newtotalSec/3600);
minutes = Math.floor((newtotalSec % 3600)/60);
seconds = newtotalSec % 60;
timeOutput = hours + ":" + minutes + ":" + seconds;
event.value = timeOutput
- Proceed to Breaking Down the Time Calculation Script to gain a
greater understanding of the script
Breaking Down the
Time Calculation Script
var timestarted = this.getField("start_time_field").valueAsString;
var timeSplit = timestarted.split(":") ;
var totalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1));
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + "INTERVAL LENGTH X");
hours = Math.floor(newtotalSec/3600);
minutes = Math.floor((newtotalSec % 3600)/60);
seconds = newtotalSec % 60;
timeOutput = hours + ":" + minutes + ":" + seconds;
event.value = timeOutput
The time calculation script can be broken down into three parts:
- Defining the Start Time
var timestarted = this.getField("start_time_field").valueAsString;
var timeSplit = timestarted.split(":") ;
var totalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1));
- This portion of the script defines the initial time from which the
time calculation is to be done
- The line
var timestarted = this.getField("start_time_field").valueAsString;
imports the desired start time from the variable
start_time_field
. This imported time should be in the
HH:MM:ss
time format
- The line
var timeSplit = timestarted.split(":") ;
then
removes the colons from this imported time, leaving the time as
HH MM ss
. This is stored as a new variable,
timesplit
- Finally, the line
var totalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1));
converts this imported time to be all in seconds. At this point
in the script, the imported start time has now been converted to a total
time in seconds
- The following operators are used in this line of code:
[0]
, [1]
, and [2]
[0]
retrives the first portion of the variable
timesplit
- Thus,
timeSplit[0]
returns the value of HH
from the variable of timesplit
- Multiplying this value of hours by 3600 in turn converts the hours
to seconds
[1]
retrieves the second portion of the variable
timesplit
- Thus,
timeSplit[1]
returns the value of MM
from the variable of timesplit
- Multiplying this value of minutes by 60 in turn converts the minutes
to seconds
[2]
retrieves the second portion of the variable
timesplit
- Thus,
timeSplit[2]
returns the value of ss
from the variable of timesplit
- Multiplying this value of seconds by 1 leaves the time in
seconds
- Defining the New Time
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + "INTERVAL LENGTH X");
hours = Math.floor(newtotalSec/3600);
minutes = Math.floor((newtotalSec % 3600)/60);
seconds = newtotalSec % 60;
- This portion of the script defines the new time to be calculated
from the start time
- The line
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + "INTERVAL LENGTH X");
calculates a new time in seconds by adding X amount of seconds to the
initial start time in seconds
(timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1)
converts the initial start time to be a total of seconds
+ "INTERVAL LENGTH X"
adds X amount of seconds to this
start time total of seconds to result in the new desired calculated time
- Thus, if the desired calculated time is to be 25 seconds after the
start time, the line of code should look like the following:
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + 25);
- The lines of code following this line convert this new total of time
of seconds into hours, minutes, and seconds
hours = Math.floor(newtotalSec/3600);
converts the new
total start time in seconds into hours
- The function
Math.floor()
rounds the number in hours
down, leaving only the number of hours with no decimal value
- Thus, if the new total time of seoonds converts into 2.56 hours, the
Math.floor()
returns a value of 2 hours
minutes = Math.floor((newtotalSec % 3600)/60);
converts
the new total start time of seconds into minutes
- The operator
%
is the remainder operator and returns
only the remainder after integer division is completed
- Thus,
newtotalSec % 3600
returns only the remainder of
seconds that did not divide wholly into hours. Dividing this value by
60, leaves the remainder in minutes.
seconds = newtotalSec % 60;
returns the remainder of
seconds that did not divide wholly into hours or minutes
- Thus, this leaves the number of seconds to be left in
HH:MM:ss
format
- After these three lines of code, three new variables have been
created: the number of hours, minutes, and seconds in the new total
start time of seconds
- Defining the Time Output
timeOutput = hours + ":" + minutes + ":" + seconds;
event.value = timeOutput
- This portion of the script defines the final time calculated in
HH:MM:ss
time format
- The line
timeOutput = hours + ":" + minutes + ":" + seconds;
defines
a new variable of the new total time in HH:MM:ss
time
format
- This line takes the previously defined variables of
hours
, minutes
, and seconds
and
adds colons between them to give the new total calculated time in
HH:MM:ss
time format
- The line
event.value = timeOutput
then defines the new
total time in HH:MM:ss
to be the output value of the
field
The following is an example script for creating a new calculated time
10 seconds after the start time:
var timestarted = this.getField("task_start_time").valueAsString;
var timeSplit = timestarted.split(":") ;
var totalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1));
var newtotalSec = ((timeSplit[0]*3600) + (timeSplit[1]*60) + (timeSplit[2]*1) + 10);
hours = Math.floor(newtotalSec/3600);
minutes = Math.floor((newtotalSec % 3600)/60);
seconds = newtotalSec % 60;
timeOutput = hours + ":" + minutes + ":" + seconds;
event.value = timeOutput
Note. When creating multiple time calculated fields, each
field should be calculated off of the intitial time. Calculated time
fields should NOT be calculated off each
other. For example, if five calculated time fields must be created, each
10 seconds apart from each other, one should not
calculate each time field 10 seconds based off the previously calculated
time. Instead, each field should be calculated based off of the initial
start time. Thus, the first calculated field should add 10 seconds to
the initial start time. The second calculated field should add 20
seconds based off the initial start time. The third calculated
field should add 30 seconds based off the initial start time. And so
forth. This ensures that no errors occur from calculating times based
off times in fields that are already being calculated.
Note. Time calculated fields cannot be overwritten. One
cannot manually overwrite the calculated time in a field with an
alternative time. The field will always read the time calculated
according to the inputted script. This should be kept in mind when
creating multiple field that feature X second consecutive intervals. If
at any point the intervals should be interrupted and a new time must be
manually entered, it cannot be done. A potential means to work around
this issue is found in the Token/Bead Sort example.
The Perfect
Example: Token/Bead Sort
The Token/Bead Sort coding form provides a perfect example of time
calculations, action buttons, and hidden fields at play. Token/Bead Sort
consists of 18 ten second intervals. All of these intervals occur after
a specified start time and should always be 10 seconds apart. However,
if an interruption should occur during the task, a new start time must
be entered into one of the intervals from which the following intervals
should calculated from. Due to the time fields being calculated, the
time values cannot be manually overwritten. The following solution is
implemented to work around this:
- Time calculations are made for each of the initial 18 intervals
- Each of these intervals calculate from the intial start time
- Thus, the first interval calculates ten seconds from the initial
start time, the second interval 20 seconds from the start time, the
third interval 30 seconds from the start time, etc.
- When the initial time is inputted, each of these intervals calculate
automatically
- A second set of text fields are made for each of these 18 intervals
- These fields have no calculations applied to them
- These 18 fields are set to be hidden from user view
- These 18 fields serve to allow for manually entry of a time in case
of an interruption
- The 18 fields are positioned over the initial 18 fields which do the
contain the calculations
- A set of 18 buttons are created, one for each interval
- Each button corresponds to an interval and is configured with
actions to hide the calculated time interval it corresponds to and show
the second text time field which allows for manual entry that it
corresponds to
- Each of these buttons serves to hide the calculated time field for
the interval in which the interruption occurs and all the following
intervals
- Each button also shows the second time text field which allows for
manual entry and also reveals the manual entry fields for all the
following intervals
- Each of these buttons is also set to be hidden from user view
- At the top of the coding form, the radio buttons for the “Was there
an interruption in the task?” question are assigned actions
- If “Yes” is selected, the 18 buttons are revealed and shown to the
user
- If “No” is selected, the 18 buttons are hidden
- Thus, when the user selects that an interruption occurred, the 18
buttons appear and allow the user to select the interval in which the
interruption occurred. When the button is pressed, the automatically
calculated time fields are hidden for that interval and subsequent
intervals, and the fields that allow for manual entry are shown for that
interval and subsequent intervals. This allows for time calculations to
be implemented even when interruptions occur
- Refer to the Token/Bead Sort coding form in order to gain further
understanding of this setup
Calculating the
Highest Level from a Row of Values
The following script returns the highest level of a behavior. For
example, a behavior may be coded for the number of times it occurs at
different levels of intensity. If one wants the highest level of
intensity the behavior occurred at, regardless of the number of times it
occurred, the following script can be utilized:
Note. The following script was created for a unique
situation. Essentially, the script utilizes multiple if/else statements.
How to employ if/else statements and conditionals are outlines above.
Thus the explanation of how this specific script operates is less
technical and brief. The building blocks of how to understand this
script at a more technical level are provided above.
var v1= getField("intensity_of_behavior_1").value
var v2= getField("intensity_of_behavior_2").value
var v3= getField("intensity_of_behavior_3").value
var v4= getField("intensity_of_behavior_4").value
var v5= getField("intensity_of_behavior_5").value
var v6= getField("intensity_of_behavior_6").value
if (v6 > 0) {
total6 = 6;
} else {
total6 = 0;
}
if ((v5 > 0) && (v6 <= 0)) {
total5 = 5;
} else {
total5 = 0;
}
if ((v4 > 0) && (v6 <= 0) && (v5 <= 0)) {
total4 = 4;
} else {
total4 = 0;
}
if ((v3 > 0) && (v6 <= 0) && (v5 <= 0) && (v4 <= 0)){
total3 = 3;
} else {
total3 = 0;
}
if ((v2 > 0) && (v6 <= 0) && (v5 <= 0) && (v4 <= 0) && (v3 <= 0)){
total2 = 2;
} else {
total2 = 0;
}
if ((v1 > 0) && (v6 <= 0) && (v5 <= 0) && (v4 <= 0) && (v3 <= 0) && (v2 <= 0)){
total = 1;
} else {
total = 0;
}
event.value = total + total2 + total3 + total4 + total5 + total6
- The above script uses if/else statements to determine the highest
level at which the behaviors occurs
- Double ampersands are used to create conditional statements with
multiple conditions
- Plainly, the above script asks whether the behavior occurs at least
once at each level of intensity
- If the behavior occurs at the highest level of intensity, the total
returns a 6 which signifies the highest level of intensity
- If the behavior does not occur at the highest level, it asks whether
there is a value present for the second highest level. If there is, the
total returns a 5 which significes the second highest level of
intensity
- If the behavior does not occur at the second highest level, it asks
whether there is a value for the third highest. If not at the third
highest, it asks at the fourth highest, and so forth.
- This script may be modified to be employed in a variety of
situations
- The above script can be found in the Parental Sensitivity and
Parental Intrusiveness Coding Forms
- These forms should be studied in order to gain greater understanding
of the specific context for which this script was created and how might
it be applied to other contexts
How To Split PDF Files
into Multiple Documents
- Open the PDF in Acrobat DC, and then choose Tools > Organize
Pages or choose Organize Pages from the right pane.
- The Organize Pages toolset is displayed in the secondary
toolbar.
- In the secondary toolbar, click “Split”.
- A new toolbar appears below the secondary toolbar with the commands
specific to the Split operation.
- In this secondary toolbar, choose “Split” to see the document
splitting options.
- In the “Split By” drop-down list, select the criteria for dividing
the document:
- Number Of Pages: Specify the maximum number of pages for each
document in the split.
- This is the most helpful option when trying to separate large
scanned PDF packets into individual files. Just specify the number of
pages as “1” (if the individual documents are only one page),“2” (if the
documents are double sided), etc.
- File Size: Specify the maximum file size for each document in the
split.
- Top-level Bookmarks: If the document includes bookmarks, creates one
document for every top-level bookmark.
- To specify a target folder for the split files and filename
preferences, click “Output Options”. Specify the folder in the lab drive
that the files should be saved to, and then click OK.
Optional: To apply the same split to multiple documents,
click “Split Multiple Files”. In the Split Documents dialog box, click
either “Add Files”, and choose “Add Files”, “Add Folders”, or “Add Open
Files”. Select the files or folder, and then click OK.
LS0tCnRpdGxlOiAiQWRvYmUgQmVzdCBQcmFjdGljZSBHdWlkZSIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsCiAgZXJyb3IgPSBUUlVFLAogIGNvbW1lbnQgPSAiIiwKICBjbGFzcy5zb3VyY2UgPSAiZm9sZC1zaG93IikKYGBgCgojIEFkb2JlIEJlc3QgUHJhY3RpY2VzCgotIE5hbWUgdmFyaWFibGVzIGFsbCBsb3dlcmNhc2Ugd2l0aCBubyBzcGFjZXM7IHVzZSB1bmRlcnNjb3JlcyBpZiBzZXBhcmF0aW5nIHdvcmRzCi0gVXNlIHJhZGlvIGJ1dHRvbnMgd2hlbmV2ZXIgcG9zc2libGUKLSBVc2UgdGhlIGBhbGlnbmAgZmVhdHVyZSBhbmQgYG1hdGNoIHNpemVgIHRvIHdoZW4gY3JlYXRpbmcgdmFyaWFibGVzCi0gV2hlbiBjcmVhdGluZyBmb3JtcyBpbiBXb3JkLCBnaXZlIHNwYWNlIGZvciB0aGUgQWRvYmUgYnV0dG9ucyB0aGF0IHdpbGwgZXZlbnR1YWxseSBiZSBjcmVhdGVkCi0gTWFrZSBzdXJlIHlvdSBhcmUgdXNpbmcgc2FtZSBuYW1pbmcgY29udmVudGlvbnMKICAgIC0gYHRjaWRgCiAgICAtIGB3YXZlYAogICAgLSBgY29kZXJfbmFtZWAKICAgIC0gYGRhdGVfY29kZWRgCiAgICAtIGBjb2RlcmAgKGZvciAxLCAyLCAzIHZhcmlhYmxlKQogICAgLSBgZ2l2ZW5fb3BwX3RvX3BsYXlgCiAgICAtIGBwbGF5X3Rhc2tgCiAgICAtIGBwY19wcmVzZW50YAogICAgLSBgdGFza19zdGFydF90aW1lYAogICAgLSBgdGFza19zdG9wX3RpbWVgCiAgICAtIGB0YXNrX2xlbmd0aGAKLSBLZWVwIGl0IGNsZWFuCi0gS2VlcCBjb25zaXN0ZW50IG5hbWluZyBjb252ZW50aW9ucyB3aXRoaW4gKGFuZCBhY3Jvc3MpIGZvcm1zCi0gRm9yIGZvbnRzIGluIHRoZSBmaWVsZHMsIGluIGdlbmVyYWwsIHVzZSBhdXRvLgpIb3dldmVyLCB0aGlzIGNhbiBiZSBjaGFuZ2VkIGlmIHByb2JsZW1hdGljLiAKLSBUbyByZXNldCBmb3JtcywgY29weSBhbmQgcGFzdGUgdGhlIHZhcmlhYmxlcywgdGhlbiBkZWxldGUgd2hhdCB5b3UgcGFzdGVkLCBhbmQgaXQgd2lsbCBiZSBjbGVhcmVkLgotIENhbGN1bGF0ZWQgZmllbGRzIHNob3VsZCAqKipOT1QqKiogYmUgY2FsY3VsYXRlZCBvZmYgb2YgYWxyZWFkeSBjYWxjdWxhdGVkIGZpZWxkcy4KRmllbGRzIHNob3VsZCBvbmx5IGJlIGNhbGN1bGF0ZWQgb2ZmIG9mIGZpZWxkcyB0aGF0IGFyZSBtYW51YWxseSBpbnB1dHRlZC4KRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhpcywgc2VlIGNyZWF0aW5nIFt0aW1lIGNhbGN1bGF0aW9uc10oYWRvYmUuaHRtbCN0aW1lY2FsY3VsYXRpb25zKQoKIyBDb252ZXJ0aW5nIFdvcmQgRG9jdW1lbnRzIHRvIFBERnMKCkJlZm9yZSBjb252ZXJ0aW5nIGZvcm1zIHRvIHBkZnMsIGFsbCByZXF1aXJlZCBlZGl0cyB0byB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIG1hZGUgaW4gTWljcm9zb2Z0IFdvcmQuCkVkaXRzIG9mIGNvbnRlbnQgb3IgZm9ybWF0dGluZyBzaG91bGQgYmUgY29tcGxldGVkIGFuZCBmaW5hbGl6ZWQgaW4gV29yZCBiZWZvcmUgY29udmVydGluZyB0aGUgZG9jdW1lbnQgdG8gYSBwZGYuClRvIGNvbnZlcnQgYSBXb3JkIGRvY3VtZW50IHRvIGEgcGRmLCBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKMS4gT3BlbiB0aGUgZG9jdW1lbnQgaW4gTWljcm9zb2Z0IFdvcmQKMS4gQ2xpY2sgdGhlICJGaWxlIiB0YWIgaW4gdGhlIHRvcCBsZWZ0IGNvcm5lciB3aXRoaW4gdGhlIFdvcmQgaW50ZXJmYWNlCjEuIFNlbGVjdCAiU2F2ZSBhcyBBRE9CRSBQREYiCjEuIE5hbWUgdGhlIG5ldyBwZGYgYWNjb3JkaW5nbHkKCiMgRWRpdGluZyBwZGZzIGluIEFkb2JlCgoxLiBPcGVuIHBkZiBpbiBBZG9iZSBBY3JvYmF0IFBybyAyMDIwCgogICAtICpOb3RlOiogRWRpdGluZyBvZiBwZGZzIG11c3QgYmUgZG9uZSBpbiBBZG9iZSBBY3JvYmF0IFBybyAyMDIwLCAqKipub3QqKiogQWRvYmUgQWNyb2JhdAoKMS4gVW5kZXIgdGhlICJUb29scyIgdGFiIGluIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIEFkb2JlIGludGVyZmFjZSwgZmluZCB0aGUgaGVhZGluZyAiRm9ybXMgJiBTaWduYXR1cmVzIiBhbmQgc2VsZWN0ICJQcmVwYXJlIEZvcm0iCgoxLiBTZWxlY3QgIlN0YXJ0IiB0byBiZWdpbiBzY2FubmluZyBhbmQgcHJlcGFyYXRpb24gb2YgdGhlIHBkZgoKMS4gVGhlICJQcmVwYXJlIEZvcm0iIHRvb2wgYmFyIHNob3VsZCBub3cgYmUgdmlzaWJsZSwgYWxsb3dpbmcgZm9yIHRoZSBhZGRpdGlvbiBvZiB0ZXh0IGZpZWxkcywgcmFkaW8gYnV0dG9ucywgY2hlY2sgYm94ZXMsIGFuZCBtb3JlCgojIyBBZGRpbmcgVGV4dCBGaWVsZHMsIFJhZGlvIEJ1dHRvbnMsIGFuZCBDaGVjayBCb3hlcwoKMS4gVGV4dCBmaWVsZHMgc2hvdWxkIGJlIGltcGxlbWVudGVkIHdoZW46CiAgIDEuIFRleHR1YWwgb3IgbnVtZXJpYyBpbmZvcm1hdGlvbiBtdXN0IGJlIG1hbnVhbGx5IGVudGVyZWQKICAgMS4gQSBjYWxjdWxhdGVkIGZpZWxkIGlzIHJlcXVpcmVkCjEuIFJhZGlvIGJ1dHRvbnMgc2hvdWxkIGJlIGltcGxlbWVudGVkIHdoZW5ldmVyIHBvc3NpYmxlCiAgIC0gUmFkaW8gYnV0dG9ucyBhbGxvdyBmb3Igb25seSBvbmUgc2VsZWN0aW9uIG91dCBvZiBhIGdyb3VwIG9mIG9wdGlvbnMKICAgICAgLSBSYWRpbyBidXR0b25zIHRodXMgc2hvdWxkIGJlIHVzZWQgZm9yIGltaXRhdGlvbiwgY29tcHJlaGVuc2lvbiwgcHJhY3RpY2UsIGFuZCB0ZXN0IHRyaWFsIGZpZWxkcyB3aXRoaW4gcGRmcwogICAtIEluIG9yZGVyIHRvIHByZXZlbnQgaHVtYW4gZXJyb3IsIHJhZGlvIGJ1dHRvbnMgc2hvdWxkIGJlIGFwcGxpZWQgdG8gYXMgbWFueSB2YXJpYWJsZXMgYXMgcG9zc2libGUKICAgLSBDYWxjdWxhdGVkIGZpZWxkcyBjYW4gYmUgZGVyaXZlZCBmcm9tIHJhZGlvIGJ1dHRvbnMKMS4gQ2hlY2sgYm94ZXMgc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIG5lY2Vzc2FyeQogICAtIENoZWNrIGJveGVzIGFsbG93IGZvciBtdWx0aXBsZSBzZWxlY3Rpb25zIHdpdGhpbiBhIGdyb3VwCiAgIC0gQ2hlY2sgYm94ZXMgc2hvdWxkICoqbm90KiogYmUgdXNlZCBmb3IgdHJpYWxzIGZpZWxkcyB3aXRoaW4gcGRmcyB1bmxlc3MgbXVsdGlwbGUgYW5zd2VycyBjYW4gYmUgc2VsZWN0ZWQgZm9yIGEgZ2l2ZW4gdHJpYWwKICAgLSBDYWxjdWxhdGVkIGZpZWxkcyBjYW4gYmUgZGVyaXZlZCBmcm9tIGNoZWNrIGJveGVzCjEuIEFjdGlvbiBidXR0b25zIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB3aGVuIGEgc3BlY2lmaWMgYWN0aW9uIGlzIG5lZWRlZCB0byBiZSBjYXJyaWVkIG91dC4KVGhlc2UgYWN0aW9ucyB0eXBpY2FsbHkgaW5jbHVkZToKICAgKiBSZXNldGluZyBhIGZpZWxkKHMpL2Zvcm0KICAgKiBIaWRpbmcvUmV2ZWFsaW5nIGEgZmllbGQocykKCiMjIE5hbWluZyBDb252ZW50aW9uIGZvciBWYXJpYWJsZXMgaW4gQWRvYmUgeyNuYW1pbmd2YXJpYWJsZXN9CgoxLiBWYXJpYWJsZSBuYW1lcyBzaG91bGQgYmUgaW4gYWxsIGxvd2VyY2FzZSB3aXRoIG5vIHNwYWNlcyBhbmQgdW5kZXJzY29yZXMgc2VwYXJhdGluZyB3b3JkcwoxLiBLZWVwIHZhcmlhYmxlIG5hbWVzIGFzIGNvbnNpc3RlbnQgYXMgcG9zc2libGUgYWNyb3NzIGZvcm1zIHdpdGggc2ltaWxhciB2YXJpYWJsZXMKMS4gVGhlIGZvbGxvd2luZyBhcmUgY29tbW9uIG5hbWVzIGZvciB2YXJpYWJsZXMgd2hpY2ggc2hvdWxkIGJlIHVzZWQgd2hlbiBhcHBsaWNhYmxlOgogICAtIElkZW50aWZ5aW5nIGluZm9ybWF0aW9uOgogICAgICAtIFRDSUQ6IGB0Y2lkYAogICAgICAtIFdhdmU6IGB3YXZlYAogICAgICAtIENvZGVyIE5hbWU6IGBjb2Rlcl9uYW1lYAogICAgICAtIERhdGUgQ29kZWQ6IGBkYXRlX2NvZGVkYAogICAgICAtIENvZGVyOiBgY29kZXJgIChmb3IgMSwgMiwgMyB2YXJpYWJsZSkKICAgICAgLSBXYXMgVEMgZ2l2ZW4gdGhlIG9wcG9ydHVuaXR5IHRvIHBsYXkgdGhlIHRhc2s6IGBnaXZlbl9vcHBfdG9fcGxheWAKICAgICAgLSBEaWQgVEMgcGxheSB0aGUgdGFzazogYHBsYXlfdGFza2AKICAgICAgLSBQQyBQcmVzZW50OiBgcGNfcHJlc2VudGAKICAgICAgLSBEaWQgVEMgcGFzcyB0aGUgaW1pdGF0aW9uIHRyaWFsczogYHBhc3NfaW1pdGF0aW9uYAogICAgICAtIERpZCBUQyBwYXNzIHRoZSBjb21wcmVoZW5zaW9uIGNoZWNrOiBgcGFzc19jb21wcmVoZW5zaW9uYAogICAgICAtIERpZCBUQyBwYXNzIHRoZSBwcmFjdGljZSB0cmlhbHM6IGBwYXNzX3ByYWN0aWNlWGAKICAgICAgLSBTdGFydCB0aW1lOiBgdGFza19zdGFydF90aW1lYAogICAgICAtIFN0b3AgdGltZTogYHRhc2tfc3RvcF90aW1lYAogICAgICAtIExlbmd0aCBvZiBhZG1pbmlzdHJhdGlvbjogYHRhc2tfbGVuZ3RoYAogICAgICAtIENvZGVyIDEvMi8zOiBgaW5pdGlhbHNfZGF0ZV9jb2RlclhgCiAgIC0gVGFzayBUcmlhbHMKICAgICAgLSBJbWl0YXRpb24gVHJpYWxzOiBgaW1pdGF0aW9uX3RyaWFsc194YAogICAgICAtIEltaXRhdGlvbiBUcmlhbHMgU2Vjb25kIEFkbWluaXN0cmF0aW9uOiBgaW1pdGF0aW9uX3RyaWFsc19yZWFkbWluX3hgCiAgICAgIC0gQ29tcHJlaGVuc2lvbiBDaGVjazogYGNvbXBfY2hlY2tYX3hgCiAgICAgIC0gUHJhY3RpY2UgVHJpYWxzOiBgcHJhY3RpY2VfdHJpYWxzWF94YAogICAgICAtIFRlc3QgVHJpYWxzOiBgdGVzdF90cmlhbHNYX3hgCiAgICAgIC0gKk5vdGU6KiAiWCIgc2lnbmlmaWVzIHRoZSByb3VuZC9ibG9jayBvZiB0aGUgdHJpYWxzIHdoaWxlICJ4IiBzaWduaWZpZXMgdGhlIHRyaWFsIG51bWJlciB3aXRoaW4gdGhhdCByb3VuZC9ibG9jayAoZXg6IGBwcmFjdGljZV90cmlhbHMyXzdgKS4KICAgICAgQW4gIlgiIHdpdGhpbiB0aGUgdmFyaWFibGUgbmFtZSBpcyBvbmx5IG5lY2Vzc2FyeSBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgcm91bmRzL2Jsb2NrcyBmb3IgdGhlIHRyaWFsLgogICAgICBUaHVzLCBpZiB0aGVyZSBpcyBvbmx5IG9uZSByb3VuZCBvZiBpbWl0YXRpb24gdHJpYWxzLCB0aG9zZSB0cmlhbHMgc2hvdWxkIGJlIHNpbXBseSBuYW1lZCBgdGVzdF90cmlhbHNgIHJhdGhlciB0aGFuIGB0ZXN0X3RyaWFsczFgLgogICAtIFRyaWFsIFRvdGFscwogICAgICAtIFRvdGFsIEluY29ycmVjdDogYHRvdGFsX2luY29ycmVjdF90YXNrX3RyaWFsc2AKICAgICAgLSBUb3RhbCBJbml0aWFsbHkgaW5jb3JyZWN0LCBidXQgY2hhbmdlZCB0byBjb3JyZWN0OiBgdG90YWxfaW5pdGlhbGx5X3Rhc2tfdHJpYWxzYAogICAgICAtIFRvdGFsIENvcnJlY3Q6IGB0b3RhbF9jb3JyZWN0X3Rhc2tfdHJpYWxzYAogICAgICAtIFRvdGFsIE5vIFJlc3BvbnNlOiBgdG90YWxfbm9yZXNwb25zZV90YXNrX3RyaWFsc2AKICAgICAgLSBUb3RhbCBVbmNvZGVhYmxlOiBgdG90YWxfdW5jb2RlYWJsZV90YXNrX3RyaWFsc2AKICAgICAgLSBUb3RhbCAjIG9mIFNjb3JlYWJsZSBUcmlhbHMgUGxheWVkOiBgdG90YWxfc2NvcmVkX3Rhc2tfdHJpYWxzYAogICAgICAtICpOb3RlOiogInRhc2tfdHJpYWxzIiBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCB3aGV0aGVyIHRoZSByb3VuZC9ibG9jayBvZiB0cmlhbHMgaXMgYGltaXRhdGlvbl90cmlhbHNgLCBgY29tcF9jaGVja2AsIGBwcmFjdGljZV90cmlhbHNgLCBvciBgdGVzdF90cmlhbHNgLgoKIyMjIE5hbWluZyBDb252ZW50aW9uIGZvciBSYWRpbyBCdXR0b25zIHsjbmFtaW5nY29udmVudGlvbnJhZGlvYnV0dG9uc30KCjEuIEluIG9yZGVyIHRvIGNyZWF0ZSBjYWxjdWxhdGVkIGZpZWxkcyBmb3IgdHJpYWwgdG90YWxzLCByYWRpbyBidXR0b24gIkNob2ljZSBWYWx1ZXMiIG11c3QgYmUgbWFudWFsbHkgc2V0LgpUbyBmYWNpbGl0YXRlIHRoZSBwcm9jZXNzLCB0aGlzIHNob3VsZCBiZSBkb25lIGFmdGVyIGFsaWduaW5nIGVhY2ggZ3JvdXAgb2YgcmFkaW8gYnV0dG9ucyBmb3IgZWFjaCB0cmlhbCB1bmRlciBlYWNoIFRDIHJlc3BvbnNlIGZvciB0aGUgdHJpYWwuCkZvciBleGFtcGxlLCB0aGVyZSBzaG91bGQgYmUgYSBjb2x1bW4gb2YgcmFkaW8gYnV0dG9ucyB1bmRlciB0aGUgIkNvcnJlY3QiIGxhYmVsIHdpdGhpbiB0aGUgdHJpYWwncyBncmlkIHdpdGggZWFjaCByYWRpbyBidXR0b24gaW4gdGhpcyBjb2x1bW4gcmVwcmVzZW50aW5nIHRoZSAiQ29ycmVjdCIgY2hvaWNlIGZvciBhIGRpZmZlcmVudCBncm91cCBvZiByYWRpbyBidXR0b25zLgpBIGNvbHVtbiBvZiBidXR0b25zIHNob3VsZCBiZSBwcmVzZW50IGZvciAiSW5jb3JyZWN0LCIgIk5vIFJlc3BvbnNlLCIgYW5kIHNvIGZvcnRoLgpUaHVzLCBlYWNoIGdyb3VwIG9mIHJhZGlvIGJ1dHRvbnMgc2hvdWxkIGJlIGFsaWduZWQgaG9yaXpvbnRhbGx5LCB3aXRoIGVhY2ggYnV0dG9uIHJlZmxlY3RpbmcgYSBkaWZmZXJlbnQgVEMgcmVzcG9uc2UuClRoZXNlIGdyb3VwcyBzaG91bGQgdGhlbiBiZSBzdGFja2VkIGludG8gYSBjb2x1bW4gd2l0aCBlYWNoIGNvbHVtbiByZXByZXNlbnRpbmcgdGhlIHJlc3BvbnNlIGFjcm9zcyB0cmlhbHMuClRoZSBDaG9pY2UgVmFsdWVzIGNhbiB0aGVuIGJlIHNldCB0aHJvdWdoIHRoZSBmb2xsb3dpbmcgc3RlcHM6CiAgIAogICAxLiBTZWxlY3QgdGhlIGVudGlyZSBjb2x1bW4gdW5kZXIgYSBjZXJ0YWluIFRDIHJlc3BvbnNlIChleC4gc2VsZWN0IHRoZSBlbnRpcmUgY29sdW1uIG9mIHJhZGlvIGJ1dHRvbnMgdW5kZXIgIkNvcnJlY3QiKQogICAxLiBSaWdodC1jbGljayBvbiB0aGUgc2VsZWN0ZWQgY29sdW1uIG9mIHJhZGlvIGJ1dHRvbnMgYW5kIHNlbGVjdCAiUHJvcGVydGllcyIKICAgMS4gVW5kZXIgdGhlICJPcHRpb25zIiB0YWIsIHNldCB0aGUgIlJhZGlvIEJ1dHRvbiBDaG9pY2UiIGFjY29yZGluZyB0byB0aGUgZm9sbG93aW5nIHZhbHVlczoKICAgICAgLSAiQ29ycmVjdCIgY29sdW1uID0gMgogICAgICAtICJJbmNvcnJlY3QiIGNvbHVtbiA9IDAKICAgICAgLSAiSW5pdGlhbGx5IGluY29ycmVjdCBidXQgY2hhbmdlZCByZXNwb25zZSB0byBjb3JyZWN0IiBjb2x1bW4gPSAxCiAgICAgIC0gIk5vIHJlc3BvbnNlIiBjb2x1bW4gPSAtOQogICAgICAtICJVbmNvZGVhYmxlIiBjb2x1bW4gPSA5CiAgIDEuIFNldCBhbGwgY29sdW1ucyB3aXRoIHRoZWlyIGFwcHJvcHJpYXRlIHJhZGlvIGJ1dHRvbiBjaG9pY2UgdmFsdWUKICAgLSAqTm90ZToqIFdoaWxlIGNhbGN1bGF0ZWQgZmllbGRzIGNhbiBiZSBkZXJpdmVkIGZyb20gZGlmZmVyZW50IHJhZGlvIGJ1dHRvbiBjaG9pY2UgdmFsdWVzLCBpdCBpcyBpbXBlcmF0aXZlIHRvIGFzc2lnbiB0aGUgYnV0dG9uIGNob2ljZXMgYWNjb3JkaW5nIHRvIHRoZXNlIHZhbHVlcy4KICAgVGhpcyBhbGxvd3MgZm9yIGNvbnNpc3RlbmN5IGFjcm9zcyBwZGZzIGFuZCB0aGUgYWJpbGl0eSB0byBzbW9vdGhseSBib3Jyb3cgY29kZSBmb3IgY2FsY3VsYXRlZCBmaWVsZHMuCgojIyMgTmFtaW5nIENvbnZlbnRpb24gZm9yIENoZWNrIEJveGVzIHsjbmFtaW5nY29udmVudGlvbmNoZWNrYm94ZXN9CgpDaGVjayBib3hlcyBjYW4gYmUgbmFtZWQgaW4gc3VjaCBhIHdheSB0aGF0IHRoZXkgYWN0IHNpbWlsYXIgdG8gcmFkaW8gYnV0dG9ucywgYWxsb3dpbmcgb25seSBvbmUgc2VsZWN0aW9uIG91dCBvZiBhIGdyb3VwIG9mIGNoZWNrIGJveGVzLj0KQSBncm91cCBvZiBjaGVjayBib3hlcyBjYW4gYmUgZm9ybWF0dGVkIGFzIHJhZGlvIGJ1dHRvbnMgdGhyb3VnaCB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKMS4gSW5wdXQgdGhlICpzYW1lKiB2YXJpYWJsZSBuYW1lIGZvciBlYWNoIGNoZWNrIGJveCB3aXRoaW4gdGhlIGdyb3VwIHRvIGJlIGZvcm1hdHRlZAoxLiBSaWdodCBjbGljayBvbiBlYWNoIGNoZWNrIGJveCBhbmQgc2VsZWN0ICJQcm9wZXJ0aWVzIgoxLiBVbmRlciB0aGUgIk9wdGlvbnMiIHRhYiwgc2V0IHRoZSAiRXhwb3J0IFZhbHVlIiBmb3IgZWFjaCBjaGVjayBib3ggYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgogICAgICAtICJDb3JyZWN0IiBjb2x1bW4gPSAyCiAgICAgIC0gIkluY29ycmVjdCIgY29sdW1uID0gMAogICAgICAtICJJbml0aWFsbHkgaW5jb3JyZWN0IGJ1dCBjaGFuZ2VkIHJlc3BvbnNlIHRvIGNvcnJlY3QiIGNvbHVtbiA9IDEKICAgICAgLSAiTm8gcmVzcG9uc2UiIGNvbHVtbiA9IC05CiAgICAgIC0gIlVuY29kZWFibGUiIGNvbHVtbiA9IDkKMS4gV2l0aCBlYWNoIGNoZWNrIGJveCBuYW1lZCB0aGUgc2FtZSBidXQgYWxzbyBlYWNoIHdpdGggYSBkaWZmZXJlbnQgZXhwb3J0IHZhbHVlLCB0aGUgZ3JvdXAgb2YgY2hlY2sgYm94ZXMgc2hvdWxkIG5vdyBvcGVyYXRlIHNpbWlsYXIgdG8gYSBncm91cCBvZiByYWRpbyBidXR0b25zCiAgIC0gV2l0aGluIHRoZSBncm91cCwgb25seSBvbmUgY2hlY2sgYm94IHNob3VsZCBiZSBhYmxlIHRvIGJlIHNlbGVjdGVkCiAgIC0gQWRkaXRpb25hbGx5LCB0aGUgc2VsZWN0aW9uIHNob3VsZCBiZSBhYmxlIHRvIGJlIHVuc2VsZWN0ZWQKMS4gV2hpbGUgYm90aCBncm91cHMgb2YgcmFkaW8gYnV0dG9ucyBhbmQgdGhpcyBmb3JtIG9mIGdyb3VwcyBvZiBjaGVjayBib3hlcyBvcGVyYXRlIHRoZSBzYW1lIHdheSBhbmQgcGVybWl0IG9ubHkgb25lIHNlbGVjdGlvbiB3aXRoaW4gdGhlIGdyb3VwLCBncm91cHMgb2YgY2hlY2sgYm94ZXMgcHJvdmlkZSBhbiBhZHZhbnRhZ2UgYnkgYWxsb3dpbmcgZm9yIGRlc2VsZWN0aW9uIG9mIHRoZSB2YWx1ZS4KV2l0aGluIGdyb3VwcyBvZiByYWRpbyBidXR0b25zLCBhcyBzb29uIGFzIGEgYnV0dG9uIGlzIHNlbGVjdGVkLCB0aGUgZ3JvdXAgb2YgYnV0dG9ucyBjYW5ub3QgYmUgcmVzZXQgb3IgZGVzZWxlY3RlZC4KVGhpcyB1c2FnZSBvZiBncm91cHMgb2YgY2hlY2sgYnV0dG9ucyBtYXkgYmUgdXNlZnVsIGdvaW5nIGZvcndhcmQgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIHdoZW4gY3JlYXRpbmcgbmV3IGNvZGluZyBmb3Jtcy4KICAgLSAqTm90ZToqIENyZWF0aW5nIGNhbGN1bGF0ZWQgZmllbGRzIGZyb20gZ3JvdXBzIG9mIGNoZWNrIGJveGVzIHdpbGwgZm9sbG93IHRoZSBzYW1lIHByb2NlZHVyZSBhcyBbY3JlYXRpbmcgY2FsY3VhdGVkIGZpZWxkcyBmcm9tIHJhZGlvIGJ1dHRvbnNdKGFkb2JlLmh0bWwjY3JlYXRlY2FsY3VsYXRlZHJhZGlvYnV0dG9ucykuCiAgIFRodXMsIGl0IGlzIGltcG9ydGFudCB0byBlbnN1cmUgdGhlIGV4cG9ydCB2YWx1ZXMgZm9yIGVhY2ggY2hlY2sgYm94IGZvbGxvdyB0aGUgdmFsdWVzIGxpc3RlZCBpbiBTdGVwIDMuCgoKIyMgSGlkaW5nIGFuZCBSZXZlYWxpbmcgRmllbGRzIGluIEFkb2JlIHsjaGlkZGVuZmllbGRzfQoKRmllbGRzIGNhbiBiZSBoaWRkZW4gYW5kIHJldmVhbGVkIHdpdGhpbiBBZG9iZSBkb2N1bWVudHMuClRvIGRvIHN1Y2gsIGNvbXBsZXRlIHRoZSBmb2xsb3dpbmcgc3RlcHM6CgoxLiBSaWdodCBjbGljayBvbiB0aGUgZmllbGQgdG8gYmUgaGlkZGVuCjEuIFNlbGVjdCAiUHJvcGVydGllcyIKMS4gVW5kZXIgdGhlICJHZW5lcmFsIiB0YWIsIG5hdmlnYXRlIHRvIHRoZSAiQ29tbW9uIFByb3BlcnRpZXMiIGJveCBhdCB0aGUgYm90dG9tIG9mIHRoZSB0YWIKMS4gRm9yICJGb3JtIEZpZWxkOiIgc2VsZWN0IGBIaWRkZW5gIGZyb20gdGhlIGRyb3AtZG93biBtZW51CjEuIE5vdywgd2hlbiBwcmV2aWV3aW5nIHRoZSBkb2N1bWVudCwgdGhlIHNlbGVjdGVkIGZpZWxkIHNob3VsZCBiZSBoaWRkZW4gZnJvbSB1c2VyIHZpZXcKMS4gSW4gb3JkZXIgdG8gbWFrZSB0aGUgZmllbGQgdmlzaWJsZSB0byB1c2VycyBhZ2FpbiwgY29tcGxldGUgc3RlcHMgMS00LCBidXQgaW5zdGVhZCBvZiBzZWxlY3RpbmcgYEhpZGRlbmAgZm9yICJGb3JtIEZpZWxkOiIsIHNlbGVjdCBgVmlzaWJsZWAKMS4gVGhlIGZpZWxkIHNob3VsZCBub3cgYmUgdmlzaWJsZSB0byB1c2VycwoKIyMgQ3JlYXRpbmcgQWN0aW9ucyBpbiBBZG9iZQoKUmFkaW8gYnV0dG9ucywgY2hlY2sgYm94ZXMsIHRleHQgZmllbGRzLCBhbmQgYWN0aW9uIGJ1dHRvbnMgY2FuIGFsbCBiZSBhc3NpZ25lZCBzcGVjaWZpYyBhY3Rpb25zIHVwb24gY2xpY2tpbmcgdGhlbS4gVGhlIG1vc3QgY29tbW9uIGFjdGlvbnMgdXNlZCBhcmU6CiAgICogQ2xlYXJpbmcgb3IgcmVzZXRpbmcgYSBmaWVsZChzKSBvciBhbiBlbnRpcmUgZm9ybQogICAqIEhpZGluZy9yZXZlYWxpbmcgYSBmaWVsZChzKQoKVG8gYXNzaWduIGEgcmFkaW8gYnV0dG9uLCBjaGVjayBib3gsIHRleHQgZmllbGQsIG9yIGFjdGlvbiBidXR0b24gYW4gYWN0aW9uLCBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKMS4gUmlnaHQgY2xpY2sgb24gdGhlIG9iamVjdCAodGhlIHJhZGlvIGJ1dHRvbi9jaGVjayBib3gvdGV4dCBmaWVsZC9hY3Rpb24gYnV0dG9uIGluIHF1ZXN0aW9uKSB0byB3aGljaCBhbiBhY3Rpb24gaXMgdG8gYmUgYXNzaWduZWQKMS4gU2VsZWN0IHRoZSAiQWN0aW9ucyIgdGFiCjEuIFdpdGhpbiB0aGUgIkFkZCBhbiBBY3Rpb24iIGludGVyZmFjZSwgZm9yICJTZWxlY3QgVHJpZ2dlcjoiIGVuc3VyZSB0aGUgcmVzcG9uc2Ugb2YgYE1vdXNlIFVwYCBpcyBzZWxlY3RlZAogICAqIFRoaXMgY29uZmlndXJlcyB0aGUgYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIHdoZW4gdGhlIG9iamVjdCBpcyBjbGlja2VkIHVwb24gd2l0aCB0aGUgdXNlcidzIG1vdXNlCjEuIFdpdGhpbiB0aGUgIkFkZCBhbiBBY3Rpb24iIGludGVyZmFjZSwgZm9yICJTZWxlY3QgQWN0aW9uOiIgY2hvb3NlIHRoZSBkZXNpcmVkIGFjdGlvbiB0byBiZSBhc3NpZ25lZCB0byB0aGUgb2JqZWN0IGZyb20gdGhlIGRyb3AtZG93biBtZW51CiAgICogVG8gY2xlYXIvcmVzZXQgYSBmaWVsZDoKICAgICAgKiBTZWxlY3QgYFJlc2V0IGEgZm9ybWAKICAgKiBUbyBoaWRlL3JldmVhbCBhIGZpZWxkOgogICAgICAqIFNlbGVjdCBgU2hvdy9oaWRlIGEgZmllbGRgCjEuIFdpdGhpbiB0aGUgIkFkZCBhbiBBY3Rpb24iIGludGVyZmFjZSwgc2VsZWN0ICJBZGQuLi4iIHRvIGltcGxlbWVudCB0aGUgY2hvc2VuIGFjdGlvbiB0byB0aGUgb2JqZWN0CiAgICogVXBvbiBjbGlja2luZyBhZGQsIGEgc2VwYXJhdGUgd2luZG93IHdpbGwgYXBwZWFyIGFza2luZyB5b3UgdG8gc3BlY2lmeSB3aGljaCBmaWVsZHMgdGhlIGFjdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0bwogICAqIElmIGNsZWFyaW5nL3Jlc2V0aW5nIGEgZmllbGQ6CiAgICAgICogTWFyayBhbGwgdGhlIGNoZWNrIGJveGVzIG9mIGFsbCB0aGUgZmllbGRzIHRvIGJlIHJlc3QKICAgICAgKiBTZWxlY3QgIk9LIgogICAqIElmIGhpZGluZy9yZXZlYWxpbmcgYSBmaWVsZDoKICAgICAgKiBTZWxlY3QgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGJlIGhpZGRlbi9yZXZlYWxlZAogICAgICAqIE9uIHRoZSByaWdodCwgc2VsZWN0IHRoZSByYWRpbyBidXR0b24gc2VsZWN0aW9uIGZvciB3aGV0aGVyIHRoZSBhY3Rpb24gc2hvdWxkIGBTaG93YCBvciBgSGlkZWAgdGhlIGZpZWxkCiAgICAgICogU2VsZWN0ICJPSyIKMS4gVXBvbiBzZWxlY3Rpb24gb2YgIk9LLCIgdGhlIGFjdGlvbiBzaG91bGQgbm93IGFwcGVhciB3aXRoaW4gdGhlICJBY3Rpb24iIGJveCBhdCB0aGUgYm90dG9tIG9mIHRoZSB0YWIKMS4gSW4gb3JkZXIgdG8gZWRpdCB0aGUgYWN0aW9uLCBzZWxlY3QgdGhlIGFjdGlvbiB0byBiZSBlZGl0ZWQgYW5kIHRoZW4gc2VsZWN0ICJFZGl0IiBhdCB0aGUgYm90dG9tIG9mIHRoZSBpbnRlcmZhY2UKMS4gTXVsdGlwbGUgYWN0aW9ucyBjYW4gYmUgYXNzaWduZWQgdG8gdGhlIHNhbWUgb2JqZWN0LgpUaHVzLCByZXBlYXQgc3RlcHMgMS02IGFzIG1hbnkgdGltZXMgYXMgbmVlZGVkIHRvIGFzc2lnbiB0aGUgbmVjZXNzYXJ5IGFjdGlvbnMgdG8gYSBnaXZlbiBvYmplY3QKCgojIENyZWF0aW5nIENhbGN1bGF0ZWQgRmllbGRzCgpBZG9iZSBBY3JvYmF0IGJvdGggaW5jbHVkZXMgaXRzIG93biBmdW5jdGlvbnMgZm9yIGNyZWF0aW5nIGNhbGN1bGF0ZWQgZmllbGRzIGFuZCBhbGxvd3MgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjdXN0b20gY2FsY3VsYXRpb24gc2NyaXB0cyB3aXRoaW4gZm9ybXMuCldoaWxlIHRoZSBjYWxjdWxhdGlvbiBmZWF0dXJlcyBhcmUgYnVpbHQtaW4gdG8gQWRvYmUsIHRoZSBjdXN0b20gY2FsY3VsYXRpb24gc2NyaXB0cyBtdXN0IGJlIHdyaXR0ZW4gdXNpbmcgdGhlIHByb2dyYW1taW5nIGxhbmd1YWdlIEphdmFTY3JpcHQuClRoZSBmb2xsb3dpbmcgc2VjdGlvbnMgZGV0YWlsIGhvdyB0byBjcmVhdGUgZGlmZmVyZW50IHR5cGVzIG9mIGNhbGN1bGF0ZWQgZmllbGRzLgoKIyMgQ3JlYXRpbmcgQ2FsY3VsYXRlZCBGaWVsZHMgZnJvbSBSYWRpbyBCdXR0b25zIHsjY3JlYXRlY2FsY3VsYXRlZHJhZGlvYnV0dG9uc30KCjEuIEZpcnN0LCBlbnN1cmUgdGhlIHJhZGlvIGJ1dHRvbnMgYW5kIHRoZWlyIGNob2ljZSB2YWx1ZXMgYXJlIGFwcHJvcHJpYXRlbHkgc2V0IGFjY29yZGluZyB0byB0aGUgW25hbWluZyBjb252ZW50aW9uIGZvciByYWRpbyBidXR0b25zXShhZG9iZS5odG1sI25hbWluZ2NvbnZlbnRpb25yYWRpb2J1dHRvbnMpCjEuIFNlbGVjdCB0aGUgdGV4dCBmaWVsZCB3aGljaCBtdXN0IGJlIHR1cm5lZCBpbnRvIGEgY2FsY3VsYXRlZCBmaWVsZAoxLiBSaWdodC1jbGljayBvbiB0aGUgZmllbGQgYW5kIHNlbGVjdCAiUHJvcGVydGllcyIKMS4gU2VsZWN0IHRoZSAiQ2FsY3VsYXRlIiB0YWIgd2l0aGluIHRoZSBQcm9wZXJ0aWVzIG1lbnUKMS4gU2VsZWN0IHRoZSAiQ3VzdG9tIGNhbGN1bGF0aW9uIHNjcmlwdDoiIHJhZGlvIGJ1dHRvbgoxLiBTZWxlY3QgIkVkaXQuLi4iIGFuZCBpbnB1dCB0aGUgZGVzaXJlZCBjYWxjdWxhdGlvbiBzY3JpcHQKICAgLSBUaGUgZm9sbG93aW5nIHNjcmlwdCBzaG91bGQgYmUgYXBwbGllZCBpbiBvcmRlciB0byBjYWxjdWxhdGUgcmFkaW8gYnV0dG9uczoKCiAgIGBgYAogICB2YXIgdjEgPSBnZXRGaWVsZCgidmFyaWFibGVfZ3JvdXBfbmFtZSIpLnZhbHVlCiAgIHZhciB2MiA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ncm91cF9uYW1lMiIpLnZhbHVlCiAgIHZhciB2MyA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ncm91cF9uYW1lMyIpLnZhbHVlCiAgIHZhciB2NCA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ncm91cF9uYW1lNCIpLnZhbHVlCgogICBpZiAodjEgPT0gWCkgeyAKICAgdG90YWwgPSAxOwogICB9IGVsc2UgewogICB0b3RhbCA9IDA7CiAgIH0KCiAgIGlmICh2MiA9PSBYKSB7CiAgIHRvdGFsMiA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsMiA9IDA7CiAgIH0KCiAgIGlmICh2MyA9PSBYKSB7CiAgIHRvdGFsMyA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsMyA9IDA7CiAgIH0KCiAgIGlmICh2NCA9PSBYKSB7CiAgIHRvdGFsNCA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsNCA9IDA7CiAgIH0KCiAgIGV2ZW50LnZhbHVlID0gdG90YWwgKyB0b3RhbDIgKyB0b3RhbDMgKyB0b3RhbDQKICAgYGBgCiAgIC0gVGhpcyBzY3JpcHQgc2hvdWxkIGJlIGZpdCBhY2NvcmRpbmcgdG8gaG93IG1hbnkgdHJpYWxzL3ZhcmlhYmxlcyBtdXN0IGJlIGNhbGN1bGF0ZWQgZnJvbQogICAtIFByb2NlZWQgdG8gW0JyZWFraW5nIERvd24gdGhlIENhbGN1bGF0aW9uIFNjcmlwdF0oYWRvYmUuaHRtbCNicmVha2luZ2Rvd25zY3JpcHQpIHRvIGdhaW4gYSBncmVhdGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHNjcmlwdAoKIyMgQ3JlYXRpbmcgQ2FsY3VsYXRlZCBGaWVsZHMgZnJvbSBSYWRpbyBCdXR0b25zOiBWaWRlbwoKV2F0Y2ggdGhlIGZvbGxvd2luZyB2aWRlbyBpbiBvcmRlciB0byBvYnNlcnZlIGFuIGV4YW1wbGUgb2YgY3JlYXRpbmcgY2FsY3VsYXRlZCBmaWVsZHMgZnJvbSByYWRpbyBidXR0b25zOgo8YnI+Cjxicj4KCjx2aWRlbyB3aWR0aD0iMTAwJSIgY29udHJvbHM9IiIgcHJlbG9hZD0ibm9uZSI+Cjxzb3VyY2Ugc3JjPSJpbWFnZXMvY3JlYXRpbmdfY2FsY3VsYXRlZF9maWVsZHNfaW5fYWRvYmUubXA0IiB0eXBlPSJ2aWRlby9tcDQiPgo8L3ZpZGVvPgoKIyMgQ3JlYXRpbmcgQ2FsY3VsYXRlZCBGaWVsZHMgZnJvbSBDaGVjayBCb3hlcwoKMS4gUHJlcGFyZSB0aGUgY2hlY2sgYm94ZXMgZm9yIGNhbGN1bGF0aW9uOgoKICAgMS4gUHJvdmlkZSB0aGUgY2hlY2sgYm94ZXMgZnJvbSB3aGljaCB0aGUgZmllbGQgd2lsbCBiZSBjYWxjdWxhdGVkIHdpdGggYXBwcm9wcmlhdGUgdmFyaWFibGUgbmFtZXMsIGNsb3NlbHkgZm9sbG93aW5nIHN0YW5kYXJkIFtuYW1pbmcgY29udmVudGlvbiBmb3IgdmFyaWFibGVzXShhZG9iZS5odG1sI25hbWluZ3ZhcmlhYmxlcykgd2hlbiBwb3NzaWJsZQogICAKICAgMS4gRm9yIGVhY2ggY2hlY2sgYm94LCBhbiBleHBvcnQgdmFsdWUgbXVzdCBiZSBhc3NpZ25lZC4KICAgVGhlIGV4cG9ydCB2YWx1ZSB3aWxsIGRldGVybWluZSB3aGF0IG51bWVyaWMgdmFsdWUgdGhlIGNoZWNrIGJveCB3aWxsIGNhcnJ5IHRocm91Z2hvdXQgY2FsY3VsYXRpb24uCiAgIFRvIHNldCB0aGUgZXhwb3J0IHZhbHVlLCBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKICAgICAgMS4gU2VsZWN0IGFuZCByaWdodC1jbGljayBvbiB0aGUgY2hlY2sgYm94IGFuZCBzZWxlY3QgIlByb3BlcnRpZXMiCiAgICAgIDEuIEluIHRoZSBQcm9wZXJ0aWVzIG1lbnUsIHNlbGVjdCB0aGUgIk9wdGlvbnMiIHRhYgogICAgICAxLiBJbiB0aGUgIkV4cG9ydCBWYWx1ZToiIGZpZWxkLCBlbnRlciB0aGUgbnVtZXJpYyB2YWx1ZSB0aGUgY2hlY2sgYm94IHNob3VsZCByZWZsZWN0CgoxLiBTZWxlY3QgdGhlIHRleHQgZmllbGQgd2hpY2ggbXVzdCBiZSB0dXJuZWQgaW50byBhIGNhbGN1bGF0ZWQgZmllbGQKMS4gUmlnaHQtY2xpY2sgb24gdGhlIGZpZWxkIGFuZCBzZWxlY3QgIlByb3BlcnRpZXMiCjEuIFNlbGVjdCB0aGUgIkNhbGN1bGF0ZSIgdGFiIHdpdGhpbiB0aGUgUHJvcGVydGllcyBtZW51CjEuIFNlbGVjdCB0aGUgIlZhbHVlIGlzIHRoZSBgbWF0aGVtYXRpY2FsIG9wZXJhdG9yc2Agb2YgdGhlIGZvbGxvd2luZyBmaWVsZHMiIHJhZGlvIGJ1dHRvbgogICAtICpOb3RlOiogVGhlIGFwcHJvcHJpYXRlIGBtYXRoZW1hdGljYWwgb3BlcmF0b3JgIHNob3VsZCBiZSBzZWxlY3RlZCBhY2NvcmRpbmcgdG8gdGhlIGRlc2lyZWQgZmluYWwgY2FsY3VsYXRpb24gZnJvbSB0aGUgZHJvcCBkb3duIGxpc3Qgb2YgInN1bSAoKyksIiAicHJvZHVjdCAoeCksIiAiYXZlcmFnZSwiICJtaW5pbXVtLCIgb3IgIm1heGltdW0iCjEuIFNlbGVjdCAiUGljay4uLiIgYW5kIHRoZW4gY2hlY2sgdGhlIHZhcmlhYmxlIG5hbWVzIG9mIHRoZSBjaGVjayBib3hlcyB0byBiZSBjYWxjdWxhdGVkCgojIyBCcmVha2luZyBEb3duIHRoZSBDYWxjdWxhdGlvbiBTY3JpcHQgeyNicmVha2luZ2Rvd25zY3JpcHR9CgpgYGAKdmFyIHYxID0gZ2V0RmllbGQoInZhcmlhYmxlX2dyb3VwX25hbWUiKS52YWx1ZQp2YXIgdjIgPSBnZXRGaWVsZCgidmFyaWFibGVfZ3JvdXBfbmFtZTIiKS52YWx1ZQp2YXIgdjMgPSBnZXRGaWVsZCgidmFyaWFibGVfZ3JvdXBfbmFtZTMiKS52YWx1ZQp2YXIgdjQgPSBnZXRGaWVsZCgidmFyaWFibGVfZ3JvdXBfbmFtZTQiKS52YWx1ZQoKaWYgKHYxID09IFgpIHsgCnRvdGFsID0gMTsKfSBlbHNlIHsKdG90YWwgPSAwOwp9CgppZiAodjIgPT0gWCkgewp0b3RhbDIgPSAxOwp9IGVsc2Ugewp0b3RhbDIgPSAwOwp9CgppZiAodjMgPT0gWCkgewp0b3RhbDMgPSAxOwp9IGVsc2Ugewp0b3RhbDMgPSAwOwp9CgppZiAodjQgPT0gWCkgewp0b3RhbDQgPSAxOwp9IGVsc2Ugewp0b3RhbDQgPSAwOwp9CgpldmVudC52YWx1ZSA9IHRvdGFsICsgdG90YWwyICsgdG90YWwzICsgdG90YWw0CmBgYApUaGUgY2FsY3VsYXRpb24gc2NyaXB0IGZvciByYWRpbyBidXR0b25zIGNhbiBiZSBicm9rZW4gZG93biBpbnRvIHRocmVlIHBhcnRzOgoKMS4gRGVmaW5pbmcgdGhlIFZhcmlhYmxlcwoKICAgYGBgCiAgIHZhciB2MSA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ncm91cF9uYW1lIikudmFsdWUKICAgdmFyIHYyID0gZ2V0RmllbGQoInZhcmlhYmxlX2dyb3VwX25hbWUyIikudmFsdWUKICAgdmFyIHYzID0gZ2V0RmllbGQoInZhcmlhYmxlX2dyb3VwX25hbWUzIikudmFsdWUKICAgdmFyIHY0ID0gZ2V0RmllbGQoInZhcmlhYmxlX2dyb3VwX25hbWU0IikudmFsdWUKICAgYGBgCgogICAtIFRoaXMgcG9ydGlvbiBvZiB0aGUgc2NyaXB0IGRlZmluZXMgdGhlIHZhcmlhYmxlcyBmcm9tIHdoaWNoIGluZm9ybWF0aW9uIGlzIGJlaW5nIHB1bGxlZCBmcm9tLgogICBJbiBuZWFybHkgYWxsIGNhc2VzIHRoZSB2YXJpYWJsZXMgYmVpbmcgcHVsbGVkIGZyb20gd2lsbCBiZSB0aGUgZ3JvdXBzIG9mIHJhZGlvIGJ1dHRvbnMgZm9yIGVhY2ggdHJpYWwuCiAgIC0gVGhlIGxpbmUgYHZhciB2MSA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ncm91cF9uYW1lIikudmFsdWVgIGRlZmluZXMgdGhlIHNlbGVjdGVkIHJhZGlvIGJ1dHRvbiBpbiAidmFyaWFibGVfZ3JvdXBfbmFtZSIgYXMgYHZhciB2MWAgKHZhcmlhYmxlIDEpIHdpdGhpbiB0aGlzIHNjcmlwdCBhbmQgcHVsbHMgdGhlICoqY2hvaWNlIHZhbHVlKiogZnJvbSBlYWNoIGdyb3VwCiAgICAgIC0gVGh1cywgd2l0aGluIGVhY2ggYGdldEZpZWxkKClgLCB0aGUgbmFtZSBvZiBlYWNoIGdyb3VwIG9mIHJhZGlvIGJ1dHRvbnMgc2hvdWxkIGJlIGFkZGVkIGluIHF1b3RhdGlvbnMKICAgICAgLSAqTm90ZToqIFRoZSBudW1iZXIgYmVpbmcgcHVsbGVkIHRocm91Z2ggdGhpcyBmdW5jdGlvbiBkaXJlY3RseSBjb3JyZXNwb25kcyB0byB0aGUgY2hvaWNlIHZhbHVlIGRlZmluZWQgZm9yIGVhY2ggcmFkaW8gYnV0dG9uIGluIHRoZSBncm91cCBvZiByYWRpbyBvZiByYWRpbyBidXR0b25zLgogICAgICBUaGlzIGlzIHdoeSBpdCBpcyBjcnVjaWFsIHRvIGRlZmluZSBjaG9pY2UgdmFsdWVzIGFjY29yZGluZyB0byB0aGUgc2FtZSBbbmFtaW5nIGNvbnZlbnRpb24gZm9yIHJhZGlvIGJ1dHRvbnNdKGFkb2JlLmh0bWwjbmFtaW5nY29udmVudGlvbnJhZGlvYnV0dG9ucykKICAgLSBFYWNoIGB2YXIgdlhgIHNob3VsZCByZWZsZWN0IGEgdHJpYWwgb24gdGhlIGZvcm0uCiAgIFRodXMsIGlmIHRoZXJlIGFyZSAxNSB0ZXN0IHRyaWFscywgdGhlcmUgc2hvdWxkIGJlIDE1IGxpbmVzIG9mIGNvZGUgZnJvbSBgdmFyIHYxYCB0byBgdmFyIHYxNWAgd2l0aCB0aGUgbmFtZSBmb3IgZWFjaCBncm91cCBvZiByYWRpbyBidXR0b25zIGlucHV0ZWQgaW4gYGdldEZpZWxkKCIiKWAgZm9yIGVhY2ggdmFyaWFibGUKCjIuIERlZmluaW5nIHRoZSBTZWxlY3RlZCBWYWx1ZXMKCiAgIGBgYAogICBpZiAodjEgPT0gWCkgeyAKICAgdG90YWwgPSAxOwogICB9IGVsc2UgewogICB0b3RhbCA9IDA7CiAgIH0KCiAgIGlmICh2MiA9PSBYKSB7CiAgIHRvdGFsMiA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsMiA9IDA7CiAgIH0KCiAgIGlmICh2MyA9PSBYKSB7CiAgIHRvdGFsMyA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsMyA9IDA7CiAgIH0KCiAgIGlmICh2NCA9PSBYKSB7CiAgIHRvdGFsNCA9IDE7CiAgIH0gZWxzZSB7CiAgIHRvdGFsNCA9IDA7CiAgIH0KICAgYGBgCiAgIC0gVGhpcyBwb3J0aW9uIG9mIGNvZGUgdXRpbGl6ZXMgaWYvZWxzZSBzdGF0ZW1lbnRzIGluIG9yZGVyIHRvIGNyZWF0ZSB0aGUgdG90YWwgdmFsdWUgZm9yIGVhY2ggZmllbGQKICAgLSBJbiBgdjEgPT0gWGAgYW5kIGVhY2ggc3Vic2VxdWVudCBgdiA9PSBYYCwgdGhlIGBYYCBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCB0aGUgKipjaG9pY2UgdmFsdWUqKiBvZiB0aGUgcmFkaW8gYnV0dG9uIGZyb20gdGhlIGdyb3VwIG9mIHJhZGlvIGJ1dHRvbnMgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZGVzaXJlZCBmaWVsZCB5b3UgYXJlIGNhbGN1bGF0aW5nCiAgICAgIC0gRm9yIGV4YW1wbGUsIGlmIGEgdG90YWwgY29ycmVjdCBmaWVsZCBpcyBiZWluZyBjYWxjdWxhdGVkLCB0aGUgY29kZSBzaG91bGQgcmVhZDoKCiAgICAgICAgIGBgYAogICAgICAgICBpZiAodjEgPT0gMikgeyAKICAgICAgICAgdG90YWwgPSAxOwogICAgICAgICB9IGVsc2UgewogICAgICAgICB0b3RhbCA9IDA7CiAgICAgICAgIH0KCiAgICAgICAgIGlmICh2MiA9PSAyKSB7CiAgICAgICAgIHRvdGFsMiA9IDE7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgIHRvdGFsMiA9IDA7CiAgICAgICAgIH0KICAgICAgICAgYGBgCgogICAgICAtIEJlY2F1c2UgYSB0b3RhbCBjb3JyZWN0IGZpZWxkIGlzIGJlaW5nIGNhbGN1bGF0ZWQsIHRoZSBjaG9pY2UgdmFsdWUgb2YgMiBzaG91bGQgYmUgaW5wdXRlZCBhcyB0aGlzIGlzIHRoZSBjaG9pY2UgdmFsdWUgd2hpY2ggY29ycmVzcG9uZHMgdG8gIkNvcnJlY3QiIChzZWUgW25hbWluZyBjb252ZW50aW9uIGZvciByYWRpbyBidXR0b25zXShhZG9iZS5odG1sI25hbWluZ2NvbnZlbnRpb25yYWRpb2J1dHRvbnMpKQogICAgICAtIFRoZSB2YWx1ZSBvZiAyIHdvdWxkIGJlIGlucHV0ZWQgZm9yIGVhY2ggaWYvZWxzZSBzdGF0ZW1lbnQgZm9yIGVhY2ggdmFyaWFibGUuCiAgICAgIFRodXMsIGlmIHRoZXJlIHdlcmUgMTUgdmFyaWFibGVzLCB0aGVyZSBzaG91bGQgYmUgMTUgaWYvZWxzZSBzdGF0ZW1lbnRzIGB2MSA9PSAyYCB0byBgdjE1ID09IDJgCiAgIC0gVGhlIGlmL2Vsc2Ugc3RhdGVtZW50IGZvciBlYWNoIHZhcmlhYmxlIGRlZmluZXMgdGhhdCBpZiB0aGUgdmFsdWUgcHVsbGVkIGJ5IHRoZSBgZ2V0RmllbGQoKWAgZnVuY3Rpb24gbWF0Y2hlcyB0aGUgaW5wdXR0ZWQgY2hvaWNlIHZhbHVlIGZvciB0aGUgdmFyaWFibGUgdGhlbiB0aGUgdG90YWwgZm9yIHRoYXQgdmFyaWFibGUgYmVjb21lcyBlcXVhbCB0byAxLgogICBJZiBpdCBkb2VzIG5vdCBtYXRjaCwgdGhlIHRoZSB0b3RhbCBiZWNvbWVzIGVxdWFsIHRvIDAuCgozLiBEZWZpbmluZyB0aGUgVG90YWwKCmBgYApldmVudC52YWx1ZSA9IHRvdGFsICsgdG90YWwyICsgdG90YWwzICsgdG90YWw0CmBgYAoKLSBUaGlzIHBvcnRpb24gb2YgY29kZSBkZWZpbmVzIHRoZSBjYWxjdWxhdGlvbiB0byB0YWtlIHBsYWNlIGluIHRoZSBmaWVsZAogICAtIFRoZSBgZXZlbnQudmFsdWVgIGRldGVybWluZXMgd2hhdCBhcHBlYXJzIGluIHRoZSB0ZXh0IGJveAotIFRoaXMgbGluZSBvZiBjb2RlIGFkZHMgdG9nZXRoZXIgdGhlIHRvdGFscyBkZWZpbmVkIGluIHRoZSBpZi9lbHNlIHN0YXRlbWVudHMuClRoaXMgcHJvZHVjZXMgdGhlIGZpbmFsIGNhbGN1bGF0ZWQgdmFsdWUgZm9yIHRoZSBmaWVsZC4KLSBUaGUgbnVtYmVyIG9mIHRvdGFscyBhZGRlZCB0b2dldGhlciBzaG91bGQgY29ycmVzcG9uZCB0byB0aGUgbnVtYmVyIG9mIHZhcmlhYmxlcy4KVGh1cywgaWYgdGhlcmUgYXJlIDE1IHRyaWFscywgdGhlbiB0aGUgZmluYWwgbGluZSBvZiBjb2RlIHNob3VsZCByZWFkOgogICBgYGAKICAgZXZlbnQudmFsdWUgPSB0b3RhbCArIHRvdGFsMiArIHRvdGFsMyArIHRvdGFsNCArIHRvdGFsNSArIHRvdGFsNiArIHRvdGFsNyArIHRvdGFsOCArIHRvdGFsOSArIHRvdGFsMTAgKyB0b3RhbDExICsgdG90YWwxMiArIHRvdGFsMTMgKyB0b3RhbDE0ICsgdG90YWwxNQogICBgYGAKClRoZSBmb2xsb3dpbmcgaXMgYW4gZXhhbXBsZSBzY3JpcHQgZm9yIGEgY2FsY3VsYXRlZCAidG90YWxfY29ycmVjdF90ZXN0X3RyaWFscyIgZmllbGQsIGNhbGN1bGF0ZWQgZnJvbSAxNSB0cmlhbHM6CgpgYGAKdmFyIHYxID0gZ2V0RmllbGQoInRlc3RfdHJpYWxzXzEiKS52YWx1ZQp2YXIgdjIgPSBnZXRGaWVsZCgidGVzdF90cmlhbHNfMiIpLnZhbHVlCnZhciB2MyA9IGdldEZpZWxkKCJ0ZXN0X3RyaWFsc18zIikudmFsdWUKdmFyIHY0ID0gZ2V0RmllbGQoInRlc3RfdHJpYWxzXzQiKS52YWx1ZQp2YXIgdjUgPSBnZXRGaWVsZCgidGVzdF90cmlhbHNfNSIpLnZhbHVlCnZhciB2NiA9IGdldEZpZWxkKCJ0ZXN0X3RyaWFsc182IikudmFsdWUKdmFyIHY3ID0gZ2V0RmllbGQoInRlc3RfdHJpYWxzXzciKS52YWx1ZQp2YXIgdjggPSBnZXRGaWVsZCgidGVzdF90cmlhbHNfOCIpLnZhbHVlCnZhciB2OSA9IGdldEZpZWxkKCJ0ZXN0X3RyaWFsc185IikudmFsdWUKdmFyIHYxMCA9IGdldEZpZWxkKCJ0ZXN0X3RyaWFsc18xMCIpLnZhbHVlCnZhciB2MTEgPSBnZXRGaWVsZCgidGVzdF90cmlhbHNfMTEiKS52YWx1ZQp2YXIgdjEyID0gZ2V0RmllbGQoInRlc3RfdHJpYWxzXzEyIikudmFsdWUKdmFyIHYxMyA9IGdldEZpZWxkKCJ0ZXN0X3RyaWFsc18xMyIpLnZhbHVlCnZhciB2MTQgPSBnZXRGaWVsZCgidGVzdF90cmlhbHNfMTQiKS52YWx1ZQp2YXIgdjE1ID0gZ2V0RmllbGQoInRlc3RfdHJpYWxzXzE1IikudmFsdWUKCgppZiAodjEgPT0gMikgewogIHRvdGFsID0gMTsKfSBlbHNlIHsKICB0b3RhbCA9IDA7Cn0KCmlmICh2MiA9PSAyKSB7CiAgdG90YWwyID0gMTsKfSBlbHNlIHsKICB0b3RhbDIgPSAwOwp9CgppZiAodjMgPT0gMikgewogIHRvdGFsMyA9IDE7Cn0gZWxzZSB7CiAgdG90YWwzID0gMDsKfQoKaWYgKHY0ID09IDIpIHsKICB0b3RhbDQgPSAxOwp9IGVsc2UgewogIHRvdGFsNCA9IDA7Cn0KCmlmICh2NSA9PSAyKSB7CiAgdG90YWw1ID0gMTsKfSBlbHNlIHsKICB0b3RhbDUgPSAwOwp9CgppZiAodjYgPT0gMikgewogIHRvdGFsNiA9IDE7Cn0gZWxzZSB7CiAgdG90YWw2ID0gMDsKfQoKaWYgKHY3ID09IDIpIHsKICB0b3RhbDcgPSAxOwp9IGVsc2UgewogIHRvdGFsNyA9IDA7Cn0KCmlmICh2OCA9PSAyKSB7CiAgdG90YWw4ID0gMTsKfSBlbHNlIHsKICB0b3RhbDggPSAwOwp9CgppZiAodjkgPT0gMikgewogIHRvdGFsOSA9IDE7Cn0gZWxzZSB7CiAgdG90YWw5ID0gMDsKfQoKaWYgKHYxMCA9PSAyKSB7CiAgdG90YWwxMCA9IDE7Cn0gZWxzZSB7CiAgdG90YWwxMCA9IDA7Cn0KCmlmICh2MTEgPT0gMikgewogIHRvdGFsMTEgPSAxOwp9IGVsc2UgewogIHRvdGFsMTEgPSAwOwp9CgppZiAodjEyID09IDIpIHsKICB0b3RhbDEyID0gMTsKfSBlbHNlIHsKICB0b3RhbDEyID0gMDsKfQoKaWYgKHYxMyA9PSAyKSB7CiAgdG90YWwxMyA9IDE7Cn0gZWxzZSB7CiAgdG90YWwxMyA9IDA7Cn0KCmlmICh2MTQgPT0gMikgewogIHRvdGFsMTQgPSAxOwp9IGVsc2UgewogIHRvdGFsMTQgPSAwOwp9CgppZiAodjE1ID09IDIpIHsKICB0b3RhbDE1ID0gMTsKfSBlbHNlIHsKICB0b3RhbDE1ID0gMDsKfQoKZXZlbnQudmFsdWUgPSB0b3RhbCArIHRvdGFsMiArIHRvdGFsMyArIHRvdGFsNCArIHRvdGFsNSArIHRvdGFsNiArIHRvdGFsNyArIHRvdGFsOCArIHRvdGFsOSArIHRvdGFsMTAgKyB0b3RhbDExICsgdG90YWwxMiArIHRvdGFsMTMgKyB0b3RhbDE0ICsgdG90YWwxNQpgYGAKCiMjIENyZWF0aW5nIENhbGN1bGF0ZWQgRmllbGRzIHdpdGggQ29uZGl0aW9uYWwgRm9ybWF0dGluZwoKRm9yIGNhc2VzIHdoZXJlIGEgY2FsY3VsYXRlZCB0b3RhbCBjYW4gY2hhbmdlIGZyb20gYSBtYW51YWxseS1pbnB1dCB2YXJpYWJsZSwgYW4gYWx0ZXJlZCBzY3JpcHQgbXVzdCBiZSB1c2VkLgo8YnI+CgpGb3IgZXhhbXBsZSwgYSBjYWxjdWxhdGVkIGZpZWxkIGNhbiBiZSBjcmVhdGVkIGZvciB0aGUgdG90YWwgbnVtYmVyIG9mIGNvcnJlY3QgcmVzcG9uc2VzIGEgcGFydGljaXBhbnQgZ2l2ZXMgdG8gYSBzdGltdWx1cy4KSWYgd2hhdCBxdWFsaWZpZXMgYXMgYSAiY29ycmVjdCIgcmVzcG9uc2UgZGVwZW5kcyBvbiBhIHZhcmlhYmxlIHRoYXQgY2FuIGJlIG1hbnVhbGx5IGNoYW5nZWQsIHRoZSBvcmlnaW5hbCBjYWxjdWxhdGlvbiBzY3JpcHQgd2lsbCByZXN1bHQgaW4gYW4gaW5hY2N1cmF0ZSB0b3RhbC4KPGJyPgoKVGh1cywgdGhlIGFsdGVyZWQgc2NyaXB0ZWQgbXVzdCBzaG93IHRoYXQgdGhlIHZhbHVlIG9mIHRoZSBjYWxjdWxhdGVkIHRvdGFsIGlzIGNvbmRpdGlvbmFsIG9uIGFub3RoZXIgdmFyaWFibGUuClRoZSB2YWx1ZSBvZiBgVmFyaWFibGUgWGAgaXMgZGVwZW5kZW50IG9uIHRoZSB2YWx1ZSBvZiBgVmFyaWFibGUgWWAuClRoaXMgY2FuIGJlIGFjY29tcGxpc2hlZCB0aHJvdWdoIHRoZSB1c2FnZSBvZiBpZi9lbHNlIGNvbW1hbmRzIGluIEphdmFTY3JpcHQuCjxicj4KClByb3ZpZGVkIGJlbG93IGlzIGFuIGV4YW1wbGUgb2YgYSBjYWxjdWxhdGlvbiBzY3JpcHQgd2l0aCBjb25kaXRpb25hbCBmb3JtYXR0aW5nOgo8YnI+CgpgYGAKdmFyIHYxPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lIikudmFsdWUKdmFyIHYyPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMiIpLnZhbHVlCnZhciB2Mz0gZ2V0RmllbGQoInZhcmlhYmxlX1hfZ3JvdXBfbmFtZTMiKS52YWx1ZQp2YXIgdjQ9IGdldEZpZWxkKCJ2YXJpYWJsZV9YX2dyb3VwX25hbWU0IikudmFsdWUKdmFyIHY1PSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lNSIpLnZhbHVlCnZhciB2Nj0gZ2V0RmllbGQoInZhcmlhYmxlX1hfZ3JvdXBfbmFtZTYiKS52YWx1ZQp2YXIgdjc9IGdldEZpZWxkKCJ2YXJpYWJsZV9YX2dyb3VwX25hbWU3IikudmFsdWUKdmFyIHY4PSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lOCIpLnZhbHVlCnZhciB2OT0gZ2V0RmllbGQoInZhcmlhYmxlX1hfZ3JvdXBfbmFtZTkiKS52YWx1ZQp2YXIgdjEwPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTAiKS52YWx1ZQp2YXIgdjExPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTEiKS52YWx1ZQp2YXIgdjEyPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTIiKS52YWx1ZQp2YXIgdjEzPSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTMiKS52YWx1ZQp2YXIgdjE0PSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTQiKS52YWx1ZQp2YXIgdjE1PSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTUiKS52YWx1ZQp2YXIgdjE2PSBnZXRGaWVsZCgidmFyaWFibGVfWF9ncm91cF9uYW1lMTYiKS52YWx1ZQoKCnZhciB2MTc9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUiKS52YWx1ZQp2YXIgdjE4PSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lMiIpLnZhbHVlCnZhciB2MTk9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUzIikudmFsdWUKdmFyIHYyMD0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTQiKS52YWx1ZQp2YXIgdjIxPSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lNSIpLnZhbHVlCnZhciB2MjI9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWU2IikudmFsdWUKdmFyIHYyMz0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTciKS52YWx1ZQp2YXIgdjI0PSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lOCIpLnZhbHVlCnZhciB2MjU9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWU5IikudmFsdWUKdmFyIHYyNj0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTEwIikudmFsdWUKdmFyIHYyNz0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTExIikudmFsdWUKdmFyIHYyOD0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTEyIikudmFsdWUKdmFyIHYyOT0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTEzIikudmFsdWUKdmFyIHYzMD0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTE0IikudmFsdWUKdmFyIHYzMT0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTE1IikudmFsdWUKdmFyIHYzMj0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTE2IikudmFsdWUKCmlmKHYxNyA9PSBZMSl7CglpZiAodjEgPT0gWDIpewogICAgCQl0b3RhbD0xCgl9ZWxzZXsKICAgIAkJdG90YWw9MAoJfQp9ZWxzZXsKCWlmICh2MSA9PSBYMSl7CiAgICAJCXRvdGFsPTEKCX1lbHNlewogICAgCQl0b3RhbD0wCgl9Cn0KCmlmKHYxOCA9PSBZMil7CglpZiAodjIgPT0gWDEpewogICAgCQl0b3RhbDI9MQoJfWVsc2V7CiAgICAJCXRvdGFsMj0wCgl9Cn1lbHNlewoJaWYgKHYyID09IFgyKXsKICAgIAkJdG90YWwyPTEKCX1lbHNlewogICAgCQl0b3RhbDI9MAoJfQp9CgppZih2MTkgPT0gWTIpewoJaWYgKHYzID09IFgxKXsKICAgIAkJdG90YWwzPTEKCX1lbHNlewogICAgCQl0b3RhbDM9MAoJfQp9ZWxzZXsKCWlmICh2MyA9PSBYMil7CiAgICAJCXRvdGFsMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwzPTAKCX0KfQoKaWYodjIwID09IFkxKXsKCWlmICh2NCA9PSBYMil7CiAgICAJCXRvdGFsND0xCgl9ZWxzZXsKICAgIAkJdG90YWw0PTAKCX0KfWVsc2V7CglpZiAodjQgPT0gWDEpewogICAgCQl0b3RhbDQ9MQoJfWVsc2V7CiAgICAJCXRvdGFsND0wCgl9Cn0KCmlmKHYyMSA9PSBZMil7CglpZiAodjUgPT0gWDEpewogICAgCQl0b3RhbDU9MQoJfWVsc2V7CiAgICAJCXRvdGFsNT0wCgl9Cn1lbHNlewoKCWlmICh2NSA9PSBYMil7CiAgICAJCXRvdGFsNT0xCgl9ZWxzZXsKICAgIAkJdG90YWw1PTAKCX0KfQoKaWYodjIyID09IFkyKXsKCWlmICh2NiA9PSBYMSl7CiAgICAJCXRvdGFsNj0xCgl9ZWxzZXsKICAgIAkJdG90YWw2PTAKCX0KfWVsc2V7CglpZiAodjYgPT0gWDIpewogICAgCQl0b3RhbDY9MQoJfWVsc2V7CiAgICAJCXRvdGFsNj0wCgl9Cn0KCmlmKHYyMyA9PSBZMSl7CglpZiAodjcgPT0gWDIpewogICAJCSB0b3RhbDc9MQoJfWVsc2V7CiAgICAJCXRvdGFsNz0wCgl9Cn1lbHNlewoJaWYgKHY3ID09IFgxKXsKICAgCQkgdG90YWw3PTEKCX1lbHNlewogICAgCQl0b3RhbDc9MAoJfQp9CgppZih2MjQgPT0gWTEpewoJaWYgKHY4ID09IFgyKXsKICAgIAkJdG90YWw4PTEKCX1lbHNlewogICAJCSB0b3RhbDg9MAoJfQp9ZWxzZXsKCWlmICh2OCA9PSBYMSl7CiAgICAJCXRvdGFsOD0xCgl9ZWxzZXsKICAgCQkgdG90YWw4PTAKCX0KfQoKaWYodjI1ID09IFkxKXsKCWlmICh2OSA9PSBYMil7CiAgIAkJIHRvdGFsOT0xCgl9ZWxzZXsKICAgIAkJdG90YWw5PTAKCX0KfWVsc2V7CglpZiAodjkgPT0gWDEpewogICAJCSB0b3RhbDk9MQoJfWVsc2V7CiAgICAJCXRvdGFsOT0wCgl9Cn0KCmlmKHYyNiA9PSBZMil7CglpZiAodjEwID09IFgxKXsKICAgIAkJdG90YWwxMD0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMD0wCgl9Cn1lbHNlewoJaWYgKHYxMCA9PSBYMil7CiAgICAJCXRvdGFsMTA9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTA9MAoJfQp9CgppZih2MjcgPT0gWTEpewoJaWYgKHYxMSA9PSBYMil7CiAgICAJCXRvdGFsMTE9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTE9MAoJfQp9ZWxzZXsKCWlmICh2MTEgPT0gWDEpewogICAgCQl0b3RhbDExPTEKCX1lbHNlewogICAgCQl0b3RhbDExPTAKCX0KfQoKaWYodjI4ID09IFkyKXsKCWlmICh2MTIgPT0gWDEpewogICAgCQl0b3RhbDEyPTEKCX1lbHNlewogICAJCSB0b3RhbDEyPTAKCX0KfWVsc2V7CglpZiAodjEyID09IFgyKXsKICAgIAkJdG90YWwxMj0xCgl9ZWxzZXsKICAgCQkgdG90YWwxMj0wCgl9Cn0KCmlmKHYyOSA9PSBZMil7CglpZiAodjEzID09IFgxKXsKICAgIAkJdG90YWwxMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMz0wCgl9Cn1lbHNlewoJaWYgKHYxMyA9PSBYMil7CiAgICAJCXRvdGFsMTM9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTM9MAoJfQp9CgppZih2MzAgPT0gWTEpewoJaWYgKHYxNCA9PSBYMil7CiAgICAJCXRvdGFsMTQ9MQoJfWVsc2V7CgkJdG90YWwxND0wCgl9Cn1lbHNlewoJaWYgKHYxNCA9PSBYMSl7CgkJdG90YWwxND0xCgl9ZWxzZXsKICAgIAkJdG90YWwxND0wCgl9Cn0KCmlmKHYzMSA9PSBZMSl7CglpZiAodjE1ID09IFgyKXsKICAgIAkJdG90YWwxNT0xCgl9ZWxzZXsKICAgIAkJdG90YWwxNT0wCgl9Cn1lbHNlewoJaWYgKHYxNSA9PSBYMSl7CiAgICAJCXRvdGFsMTU9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTU9MAoJfQp9CgppZih2MzIgPT0gWTIpewoJaWYgKHYxNiA9PSBYMSl7CiAgICAJCXRvdGFsMTY9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTY9MAoJfQp9ZWxzZXsKCWlmICh2MTYgPT0gWDIpewogICAgCQl0b3RhbDE2PTEKCX1lbHNlewogICAgCQl0b3RhbDE2PTAKCX0KfQoKCmV2ZW50LnZhbHVlPXRvdGFsK3RvdGFsMit0b3RhbDMrdG90YWw0K3RvdGFsNSt0b3RhbDYrdG90YWw3K3RvdGFsOCt0b3RhbDkrdG90YWwxMCt0b3RhbDExK3RvdGFsMTIrdG90YWwxMyt0b3RhbDE0K3RvdGFsMTUrdG90YWwxNgpgYGAKPGJyPgoKIyMgQnJlYWtpbmcgRG93biB0aGUgQ29uZGl0aW9uYWwgRm9ybWF0dGluZyBDYWxjdWxhdGlvbiBTY3JpcHQKCk5vdGljZSB0aGUgW3RyYWRpdGlvbmFsIGNhbGN1bGF0aW9uIHNjcmlwdF0oYWRvYmUuaHRtbCNicmVha2luZ2Rvd25zY3JpcHQpIGlzIHByZXNlbnQgd2l0aGluIHRoaXMgc2NyaXB0LgpIb3dldmVyLCBhZGRpdGlvbmFsIGlmL2Vsc2UgY29tbWFuZHMgYXJlIGltcGxlbWVudGVkIGluIG9yZGVyIHRvIGFjY291bnQgZm9yIHRoZSBkZXBlbmRlbmNlIG9uIGFub3RoZXIgdmFyaWFibGUuCkJlZm9yZSBwcm9jZWVkaW5nIHdpdGggdGhpcyBzZWN0aW9uLCBhbiB1bmRlcnN0YW5kaW5nIG9mIHRoZSBbdHJhZGl0aW9uYWwgY2FsY3VsYXRpb24gc2NyaXB0XShhZG9iZS5odG1sI2JyZWFraW5nZG93bnNjcmlwdCkgc2hvdWxkIGJlIG9idGFpbmVkLgpJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb24sIFZhcmlhYmxlIFggcmVmZXJzIHRvIHRoZSB2YXJpYWJsZSB3aGljaCBpcyBjb250aW5nZW50IG9uIHRoZSB2YWx1ZSBvZiBhbm90aGVyIHZhcmlhYmxlLCBWYXJpYWJsZSBZLgpUaHVzLCB0aGUgY29uZGl0aW9uYWwgZm9ybWF0dGluZyBpcyBkZXNjcmliZWQgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSB2YWx1ZSBvZiBhIFZhcmlhYmxlIFggaXMgZGVwZW5kZW50IG9uIHRoZSB2YWx1ZSBvZiBWYXJpYWJsZSBZLgo8YnI+CgpUaGUgY29uZGl0aW9uYWwgZm9ybWF0dGluZyBjYWxjdWxhdGlvbiBzY3JpcHQgZmVhdHVyZXMgdHdvIG1ham9yIGFsdGVyYXRpb25zOgoKMS4gRGVmaW5pbmcgdGhlIEFkZGl0aW9uYWwgVmFyaWFibGUKCiAgIGBgYAogICB2YXIgdjE3PSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lIikudmFsdWUKICAgdmFyIHYxOD0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTIiKS52YWx1ZQogICB2YXIgdjE5PSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lMyIpLnZhbHVlCiAgIHZhciB2MjA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWU0IikudmFsdWUKICAgdmFyIHYyMT0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTUiKS52YWx1ZQogICB2YXIgdjIyPSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lNiIpLnZhbHVlCiAgIHZhciB2MjM9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWU3IikudmFsdWUKICAgdmFyIHYyND0gZ2V0RmllbGQoInZhcmlhYmxlX1lfZ3JvdXBfbmFtZTgiKS52YWx1ZQogICB2YXIgdjI1PSBnZXRGaWVsZCgidmFyaWFibGVfWV9ncm91cF9uYW1lOSIpLnZhbHVlCiAgIHZhciB2MjY9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxMCIpLnZhbHVlCiAgIHZhciB2Mjc9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxMSIpLnZhbHVlCiAgIHZhciB2Mjg9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxMiIpLnZhbHVlCiAgIHZhciB2Mjk9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxMyIpLnZhbHVlCiAgIHZhciB2MzA9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxNCIpLnZhbHVlCiAgIHZhciB2MzE9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxNSIpLnZhbHVlCiAgIHZhciB2MzI9IGdldEZpZWxkKCJ2YXJpYWJsZV9ZX2dyb3VwX25hbWUxNiIpLnZhbHVlCiAgIGBgYAogICAKICAgLSBUaGlzIGFkZGl0aW9uIHRvIHRoZSBzY3JpcHQgaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGFjY29tb2RhdGUgZm9yIHRoZSBhZGRpdGlvbmFsIFZhcmlhYmxlIFkgYnkgd2hpY2ggdGhlIGNhbGN1bGF0ZWQgdG90YWwgaXMgY29udGluZ2VudAogICAtIEFuIGFkZGl0aW9uYWwgMTYgdmFyaWFibGVzIG11c3QgYmUgYWRkZWQsIG9uZSBmb3IgZWFjaCBvZiB0aGUgMTYgZ3JvdXBzIG9mIFZhcmlhYmxlIFggKHYxLXYxNikuCiAgIEVhY2ggb2YgdGhlc2UgbmV3IGB2YXJgIGNvbW1hbmRzIGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUgb3JpZ2luYWwgMTYgYHZhcmAgY29tbWFuZHMgZm9yIFZhcmlhYmxlIFggYW5kIHB1bGxzIGVhY2ggdHJpYWwncyB2YWx1ZSBmb3IgVmFyaWFibGUgWSB1cG9uIHdoaWNoIHRoZSB0b3RhbCBpcyBkZXBlbmRlbnQuCiAgIC0gVGh1cyBmb3IgYSBmb3JtIHdpdGggMTYgdGVzdCB0cmlhbHMsIHRoZXJlIHNob3VsZCBiZSAzMiB0b3RhbCBsaW5lcyBvZiBjb2RlOiAxNiB3aGljaCBjb3JyZXNwb25kIHRvIHRoZSBvcmlnaW5hbCAxNiBncm91cHMgb2YgcmFkaW8gYnV0dG9ucyBmb3IgVmFyaWFibGUgWCB3aGljaCByZWZsZWN0IGEgcmVzcG9uc2UgZm9yIGVhY2ggdHJpYWwsIGFuZCBhbiBhZGRpdGlvbmFsIDE2IHdoaWNoIGNvcnJlc3BvbmQgdG8gdGhlIG1hbnVhbGx5IGlucHV0IHJlc3BvbnNlIGZvciBWYXJpYWJsZSBZIHVwb24gd2hpY2ggdGhlIGNhbGN1bGF0ZWQgdG90YWwgaXMgY29uZGl0aW9uYWwKCjEuIENyZWF0aW5nIHRoZSBDb25kaXRpb25hbCBGb3JtYXR0aW5nIHVzaW5nIElmL0Vsc2UgQ29tbWFuZHMKCiAgIGBgYAogICBpZih2MTcgPT0gWTEpewoJICAgaWYgKHYxID09IFgyKXsKICAgIAkJICAgdG90YWw9MQoJICAgfWVsc2V7CiAgICAJCSAgIHRvdGFsPTAKCSAgIH0KICAgfWVsc2V7CgkgICBpZiAodjEgPT0gWDEpewogICAgCQkgICB0b3RhbD0xCgkgICB9ZWxzZXsKICAgIAkJICAgdG90YWw9MAoJICAgfQogICB9CgogICBpZih2MTggPT0gWTIpewoJICAgaWYgKHYyID09IFgxKXsKICAgIAkJICAgdG90YWwyPTEKCSAgIH1lbHNlewogICAgCQkgICB0b3RhbDI9MAoJICAgfQogICB9ZWxzZXsKCSAgIGlmICh2MiA9PSBYMil7CiAgICAJCSAgIHRvdGFsMj0xCgkgICB9ZWxzZXsKICAgIAkJICAgdG90YWwyPTAKCSAgIH0KICAgfQogICAuLi4KICAgYGBgCgogICAtIFRoaXMgYWx0ZXJhdGlvbiB0byB0aGUgc2NyaXB0IHV0aWxpemVzIGlmL2Vsc2UgY29tbWFuZHMgdG8gZXN0YWJsaXNoIGNvbnRpbmdlbmN5IG9uIFZhcmlhYmxlIFkKICAgLSBBcyBvdXRsaW5lZCBpbiB0aGUgW0JyZWFraW5nIERvd24gdGhlIENhbGN1bGF0aW9uIFNjcmlwdF0oYWRvYmUuaHRtbCNicmVha2luZ2Rvd25zY3JpcHQpIHNlY3Rpb24sIHRoZSBpZi9lbHNlIHN0YXRlbWVudHMgb3BlcmF0ZSBpbiB0aGUgc2FtZSBtYW5uZXIgYW5kIGZvbGxvdyB0aGUgc2FtZSBwcm9jZWR1cmVzLgogICBIb3dldmVyLCBub3RpY2UgYW4gYWRkaXRpb25hbCBpZi9lbHNlIHN0YXRlbWVudCBpcyBwcmVzZW50IGZvciBlYWNoIHRyaWFsIGFuZCBzdXJyb3VuZHMgdGhlIG9yaWdpbmFsIGlmL2Vsc2Ugc3RhdGVtZW50OgogICAKICAgICAgYGBgCiAgICAgIGlmKHYxNyA9PSBZMSl7ICAgICAgIDwtLS0tLS0tLS0tLS0gU1RBUlQgT0YgT1ZFUkFSQ0hJTkcgSUYgU1RBVEVNRU5UCgkgICAgICBpZiAodjEgPT0gWDIpeyAgICAgIyBPcmlnaW5hbCBpZi9lbHNlIHN0YXRlbWVudAogICAgCQkgICAgICB0b3RhbD0xCgkgICAgICB9ZWxzZXsKICAgIAkJICAgICAgdG90YWw9MAoJICAgICAgfQogICAgICB9ZWxzZXsgICAgICAgICAgICAgICA8LS0tLS0tLS0tLS0tIFNUQVJUIE9GIE9WRVJBUkNISU5HIEVMU0UgU1RBVEVNRU5UCgkgICAgICBpZiAodjEgPT0gWDEpeyAgICAgIyBTZWNvbmQgb3JpZ2luYWwgaWYvZWxzZSBzdGF0ZW1lbnQKICAgIAkJICAgICAgdG90YWw9MQoJICAgICAgfWVsc2V7CiAgICAJCSAgICAgIHRvdGFsPTAKCSAgICAgIH0KICAgICAgfSAgICAgICAgICAgICAgICAgICAgPC0tLS0tLS0tLS0tLSBFTkQgT0YgT1ZFUkFSQ0hJTkcgSUYvRUxTRSBTVEFURU1FTlQKICAgICAgCiAgICAgIGBgYAoKICAgLSBUaGUgb3ZlcmFyY2hpbmcgaWYvZWxzZSBzdGF0ZW1lbnQgaXMgY2VudGVyZWQgYXJvdW5kIHRoZSB2YXJpYWJsZSB3aGljaCBkZWZpbmVzIHRoZSBjb25kaXRpb25hbCBmb3JtYXR0aW5nLCBWYXJpYWJsZSBZLCB0aHVzIHRoZSBgaWYodiA9PSBZKXtgIHNob3VsZCBvbmx5IHJlZmVyZW5jZSBgdmFyIHYxN2AgdG8gYHZhciB2MzJgCiAgIC0gV2l0aGluIHRoZSBvdmVyYXJjaGluZyBpZi9lbHNlIHN0YXRlbWVudCwgYFkxYCBhbmQgYFkyYCByZXByZXNlbnQgdGhlICoqY2hvaWNlIHZhbHVlKiogb2YgdGhlIGZpZWxkIGJlaW5nIHB1bGxlZCBmcm9tIGZvciBWYXJpYWJsZSBZCiAgIAogICAgICAtIEZvciB0aGUgb3JpZ2luYWwgaWYvZWxzZSBzdGF0ZW1lbnRzIHdpdGhpbiB0aGUgb3ZlcmFyY2hpbmcgaWYvZWxzZSBzdGF0ZW1lbnQsIGBYMWAgYW5kIGBYMmAgc3RpbGwgcmVmbGVjdCB0aGUgZGVzaXJlZCAqKmNob2ljZSB2YWx1ZSoqIG9mIHRoZSByYWRpbyBidXR0b24gZnJvbSB0aGUgZ3JvdXAgb2YgcmFkaW8gYnV0dG9ucyB0aGF0IGNvcnJlc3BvbmQgdG8gdGhlIGRlc2lyZWQgZmllbGQgeW91IGFyZSBjYWxjdWxhdGluZyBmb3IgVmFyaWFibGUgWAoKICAgLSBUaGUgY29uZGl0aW9uYWwgZm9ybWF0dGluZyBlbWVyZ2VzIGZyb20gZGVmaW5pbmcgdGhlIGBZYCBpbiBgaWYodiA9PSBZKXtgIGFzIGBZMWAgb3IgYFkyYAogICAgICAKICAgICAgLSBOb3RpY2UsIHRoZXJlIGFyZSB0d28gaWYvZWxzZSBzdGF0ZW1lbnRzIHdpdGhpbiB0aGUgb3ZlcmFyY2hpbmcgaWYvZWxzZSBzdGF0ZW1lbnQuCiAgICAgIEVhY2ggb2YgdGhlc2Ugc2Vjb25kYXJ5IGlmL2Vsc2Ugc3RhdGVtZW50cyBkZWZpbmUgYSBkaWZmZXJlbnQgb3V0Y29tZSAtIGluIHRoaXMgaW5zdGFuY2UsIHRoZSBvdXRjb21lcyBhcmUgImlmIGB2MSA9PSBYMmAgdGhlbiBgdG90YWwgPSAxYCIgYW5kICJpZiBgdjEgPT0gWDFgIHRoZW4gYHRvdGFsID0gMWAiCiAgICAgIFdoaWNoIG91dGNvbWUgaXMgc2VsZWN0ZWQgaXMgZGVwZW5kZW50IG9uIHRoZSBkZWZpbml0aW9uIG9mIGBZYCBpbiBgaWYodiA9PSBZKXtgLgogICAgICAtIFRodXMsIGZvciB0aGUgZXhhbXBsZSBzY3JpcHQgYWJvdmUsIGlmIGB2MTcgPT0gWTFgLCB0aGVuIHRoZSBmaXJzdCBvdXRjb21lIG9mICJpZiBgdjEgPT0gWDJgIHRoZW4gYHRvdGFsID0gMWAiIHdpbGwgYmUgdGhlIHJlc3VsdCwgYnV0IGlmIGB2MTdgIGVxdWFscyBhbnl0aGluZyBlbHNlIGJlc2lkZXMgYFkxYCwgdGhlbiB0aGUgc2Vjb25kIG91dGNvbWUgb2YgImlmIGB2MSA9PSBYMWAgdGhlbiBgdG90YWwgPSAxYCIgd2lsbCBiZSB0aGUgcmVzdWx0CiAgICAgIC0gVGhlIGZpbmFsIHJlc3VsdCBpcyBjb25kaXRpb25hbCBmb3JtYXR0aW5nIGFzIHRoZSBjYWxjdWxhdGVkIHRvdGFsIGZvciBlYWNoIHRyaWFsIG9mIFZhcmlhYmxlIFggaXMgdWx0aW1hdGVseSBkZXBlbmRlbnQgb24gdGhlIHZhbHVlIG9mIFZhcmlhYmxlIFkKICAgCgojIyBDb25kaXRpb25hbCBGb3JtYXR0aW5nIENhbGN1bGF0aW9uIFNjcmlwdDogQW4gRXhhbXBsZQoKTGlzdGVkIGJlbG93IGlzIGEgc3BlY2lmaWMgZXhhbXBsZSB3aGVyZSB0aGUgY29uZGl0aW9uYWwgZm9ybWF0dGluZyBjYWxjdWxhdGlvbiBzY3JpcHQgaXMgbmVjZXNzYXJ5Ogo8YnI+CgojIyMgVGhlIFNjZW5hcmlvCgpBIGNhbGN1bGF0ZWQgZmllbGQgZm9yIHRoZSB0b3RhbCBudW1iZXIgb2YgY29ycmVjdCByZXNwb25zZXMgb3V0IG9mIDE2IHRyaWFscyBpcyBuZWVkZWQuCjxicj4KCkZvciBlYWNoIHRyaWFsLCBhbiBleHBlcmltZW50ZXIgdGFwcyB0aGUgdGFibGUgZWl0aGVyIG9uZSB0aW1lIG9yIHR3byB0aW1lcy4KSW4gcmVzcG9uc2UgdG8gdGhlIGV4cGVyaW1lbnRlcidzIGFkbWluaXN0cmF0aW9uLCB0aGUgcGFydGljaXBhbnQgaXMgZXhwZWN0ZWQgdG8gdGFwIHRoZSB0YWJsZSB0aGUgb3Bwb3NpdGUgbnVtYmVyIG9mIHRpbWVzLgo8YnI+CgpJZiB0aGUgZXhwZXJpbWVudGVyIHRhcHMgdGhlIHRhYmxlIG9uY2UsIHRoZSBwYXJ0aWNpcGFudCBzaG91bGQgdGFwIHRoZSB0YWJsZSB0d2ljZTsgaWYgdGhlIGV4cGVyaW1lbnRlciB0YXBzIHRoZSB0YWJsZSB0d2ljZSwgdGhlIHBhcnRpY2lwYW50IHRhcHMgdGhlIHRhYmxlIG9uY2UuCkEgcmVzcG9uc2UgaXMgY29ycmVjdCBpZiB0aGUgcGFydGljcGFudCBzdWNjZXNzZnVsbHkgdGFwcyB0aGUgdGFibGUgdGhlIG9wcG9zaXRlIG51bWJlciBvZiB0aW1lcyBhcyB0aGUgZXhwZXJpbWVudGVyLgo8YnI+CgpUaHVzLCB0aGUgY29ycmVjdCByZXNwb25zZSBpcyBub3QgYWx3YXlzIG9uZSB0YXAgb3IgdHdvIHRhcHMuCkluc3RlYWQsIHdoZXRoZXIgdGhlIHJlc3BvbnNlIGlzIGNvcnJlY3QgaXMgY29udGluZ2VudCBvbiB0aGUgZXhwZXJpbWVudGVyJ3MgYWRtaW5pc3RyYXRpb24gYW5kIGhvdyBtYW55IHRpbWVzIHRoZSBleHBlcmltZW50ZXIgdGFwcyB0aGUgdGFibGUuCkFzIGEgcmVzdWx0LCBjb25kaXRpb25hbCBmb3JtYXR0aW5nIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBjYWxjdWxhdGUgdGhlIHRvdGFsIG51bWJlciBvZiBjb3JyZWN0IHJlc3BvbnNlcyBhY3Jvc3MgdGhlIDE2IHRyaWFscy4KCiMjIyBUaGUgVmFyaWFibGVzCgotIGBWYXJpYWJsZSBYYCA9IHBhcnRpY2lwYW50J3MgcmVzcG9uc2VzICh0aGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBwYXJ0aWNpcGFudCB0YXBzIHRoZSB0YWJsZSkKLSBgVmFyaWFibGUgWWAgPSBleHBlcmltZW50ZXIncyBhZG1pbmlzdHJhdGlvbiAodGhlIG51bWJlciBvZiB0aW1lcyB0aGUgZXhwZXJpbWVudGVyIHRhcHBlZCB0aGUgdGFibGUpCi0gYFgxYCA9IGNob2ljZSB2YWx1ZSBvZiByYWRpbyBidXR0b24gcmVmbGVjdGluZyB0aGUgYWN0aW9uIG9mIHRoZSBwYXJ0aWNpcGFudCB0YXBwaW5nIHRoZSB0YWJsZSBvbmNlIC0gaW4gdGhpcyBjYXNlLCAqKjEqKgotIGBYMmAgPSBjaG9pY2UgdmFsdWUgb2YgcmFkaW8gYnV0dG9uIHJlZmxlY3RpbmcgdGhlIGFjdGlvbiBvZiB0aGUgcGFydGljaXBhbnQgdGFwcGluZyB0aGUgdGFibGUgdHdpY2UgLSBpbiB0aGlzIGNhc2UsICoqMioqCi0gYFkxYCA9IGNob2ljZSB2YWx1ZSBvZiB0aGUgZmllbGQgcmVmbGVjdGluZyB0aGUgZXhwZXJpbWVudGVyIHRhcHBlZCB0aGUgdGFibGUgb25jZSAtIGluIHRoaXMgY2FzZSwgKioxKioKLSBgWTJgID0gY2hvaWNlIHZhbHVlIG9mIHRoZSBmaWVsZCByZWZsZWN0aW5nIHRoZSBleHBlcmltZW50ZXIgdGFwcGVkIHRoZSB0YWJsZSBvbmNlIC0gaW4gdGhpcyBjYXNlLCAqKjIqKgogCiMjIyBUaGUgU2NyaXB0CgpUaGUgY2FsY3VsYXRpb24gc2NyaXB0IGZvciB0aGUgYWJvdmUgc2NlbmFyaW8gY2FuIGJlIHdyaXR0ZW4gYXMgc3VjaDoKPGJyPgoKYGBgCnZhciB2MT0gZ2V0RmllbGQoInBhcnRpY2lwYW50X3Jlc3BvbnNlIikudmFsdWUKdmFyIHYyPSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2UyIikudmFsdWUKdmFyIHYzPSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2UzIikudmFsdWUKdmFyIHY0PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U0IikudmFsdWUKdmFyIHY1PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U1IikudmFsdWUKdmFyIHY2PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U2IikudmFsdWUKdmFyIHY3PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U3IikudmFsdWUKdmFyIHY4PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U4IikudmFsdWUKdmFyIHY5PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2U5IikudmFsdWUKdmFyIHYxMD0gZ2V0RmllbGQoInBhcnRpY2lwYW50X3Jlc3BvbnNlMTAiKS52YWx1ZQp2YXIgdjExPSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2UxMSIpLnZhbHVlCnZhciB2MTI9IGdldEZpZWxkKCJwYXJ0aWNpcGFudF9yZXNwb25zZTEyIikudmFsdWUKdmFyIHYxMz0gZ2V0RmllbGQoInBhcnRpY2lwYW50X3Jlc3BvbnNlMTMiKS52YWx1ZQp2YXIgdjE0PSBnZXRGaWVsZCgicGFydGljaXBhbnRfcmVzcG9uc2UxNCIpLnZhbHVlCnZhciB2MTU9IGdldEZpZWxkKCJwYXJ0aWNpcGFudF9yZXNwb25zZTE1IikudmFsdWUKdmFyIHYxNj0gZ2V0RmllbGQoInBhcnRpY2lwYW50X3Jlc3BvbnNlMTYiKS52YWx1ZQoKCnZhciB2MTc9IGdldEZpZWxkKCJleHBlcmltZW50ZXJfYWRtaW5pc3RyYXRpb24iKS52YWx1ZQp2YXIgdjE4PSBnZXRGaWVsZCgiZXhwZXJpbWVudGVyX2FkbWluaXN0cmF0aW9uMiIpLnZhbHVlCnZhciB2MTk9IGdldEZpZWxkKCJleHBlcmltZW50ZXJfYWRtaW5pc3RyYXRpb24zIikudmFsdWUKdmFyIHYyMD0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjQiKS52YWx1ZQp2YXIgdjIxPSBnZXRGaWVsZCgiZXhwZXJpbWVudGVyX2FkbWluaXN0cmF0aW9uNSIpLnZhbHVlCnZhciB2MjI9IGdldEZpZWxkKCJleHBlcmltZW50ZXJfYWRtaW5pc3RyYXRpb242IikudmFsdWUKdmFyIHYyMz0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjciKS52YWx1ZQp2YXIgdjI0PSBnZXRGaWVsZCgiZXhwZXJpbWVudGVyX2FkbWluaXN0cmF0aW9uOCIpLnZhbHVlCnZhciB2MjU9IGdldEZpZWxkKCJleHBlcmltZW50ZXJfYWRtaW5pc3RyYXRpb245IikudmFsdWUKdmFyIHYyNj0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjEwIikudmFsdWUKdmFyIHYyNz0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjExIikudmFsdWUKdmFyIHYyOD0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjEyIikudmFsdWUKdmFyIHYyOT0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjEzIikudmFsdWUKdmFyIHYzMD0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjE0IikudmFsdWUKdmFyIHYzMT0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjE1IikudmFsdWUKdmFyIHYzMj0gZ2V0RmllbGQoImV4cGVyaW1lbnRlcl9hZG1pbmlzdHJhdGlvbjE2IikudmFsdWUKCmlmKHYxNyA9PSAxKXsKCWlmICh2MSA9PSAyKXsKICAgIAkJdG90YWw9MQoJfWVsc2V7CiAgICAJCXRvdGFsPTAKCX0KfWVsc2V7CglpZiAodjEgPT0gMSl7CiAgICAJCXRvdGFsPTEKCX1lbHNlewogICAgCQl0b3RhbD0wCgl9Cn0KCmlmKHYxOCA9PSAyKXsKCWlmICh2MiA9PSAxKXsKICAgIAkJdG90YWwyPTEKCX1lbHNlewogICAgCQl0b3RhbDI9MAoJfQp9ZWxzZXsKCWlmICh2MiA9PSAyKXsKICAgIAkJdG90YWwyPTEKCX1lbHNlewogICAgCQl0b3RhbDI9MAoJfQp9CgppZih2MTkgPT0gMil7CglpZiAodjMgPT0gMSl7CiAgICAJCXRvdGFsMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwzPTAKCX0KfWVsc2V7CglpZiAodjMgPT0gMil7CiAgICAJCXRvdGFsMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwzPTAKCX0KfQoKaWYodjIwID09IDEpewoJaWYgKHY0ID09IDIpewogICAgCQl0b3RhbDQ9MQoJfWVsc2V7CiAgICAJCXRvdGFsND0wCgl9Cn1lbHNlewoJaWYgKHY0ID09IDEpewogICAgCQl0b3RhbDQ9MQoJfWVsc2V7CiAgICAJCXRvdGFsND0wCgl9Cn0KCmlmKHYyMSA9PSAyKXsKCWlmICh2NSA9PSAxKXsKICAgIAkJdG90YWw1PTEKCX1lbHNlewogICAgCQl0b3RhbDU9MAoJfQp9ZWxzZXsKCWlmICh2NSA9PSAyKXsKICAgIAkJdG90YWw1PTEKCX1lbHNlewogICAgCQl0b3RhbDU9MAoJfQp9CgppZih2MjIgPT0gMil7CglpZiAodjYgPT0gMSl7CiAgICAJCXRvdGFsNj0xCgl9ZWxzZXsKICAgIAkJdG90YWw2PTAKCX0KfWVsc2V7CglpZiAodjYgPT0gMil7CiAgICAJCXRvdGFsNj0xCgl9ZWxzZXsKICAgIAkJdG90YWw2PTAKCX0KfQoKaWYodjIzID09IDEpewoJaWYgKHY3ID09IDIpewogICAJCSB0b3RhbDc9MQoJfWVsc2V7CiAgICAJCXRvdGFsNz0wCgl9Cn1lbHNlewoJaWYgKHY3ID09IDEpewogICAJCSB0b3RhbDc9MQoJfWVsc2V7CiAgICAJCXRvdGFsNz0wCgl9Cn0KCmlmKHYyNCA9PSAxKXsKCWlmICh2OCA9PSAyKXsKICAgIAkJdG90YWw4PTEKCX1lbHNlewogICAJCSB0b3RhbDg9MAoJfQp9ZWxzZXsKCWlmICh2OCA9PSAxKXsKICAgIAkJdG90YWw4PTEKCX1lbHNlewogICAJCSB0b3RhbDg9MAoJfQp9CgppZih2MjUgPT0gMSl7CglpZiAodjkgPT0gMil7CiAgIAkJIHRvdGFsOT0xCgl9ZWxzZXsKICAgIAkJdG90YWw5PTAKCX0KfWVsc2V7CglpZiAodjkgPT0gMSl7CiAgIAkJIHRvdGFsOT0xCgl9ZWxzZXsKICAgIAkJdG90YWw5PTAKCX0KfQoKaWYodjI2ID09IDIpewoJaWYgKHYxMCA9PSAxKXsKICAgIAkJdG90YWwxMD0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMD0wCgl9Cn1lbHNlewoJaWYgKHYxMCA9PSAyKXsKICAgIAkJdG90YWwxMD0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMD0wCgl9Cn0KCmlmKHYyNyA9PSAxKXsKCWlmICh2MTEgPT0gMil7CiAgICAJCXRvdGFsMTE9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTE9MAoJfQp9ZWxzZXsKCWlmICh2MTEgPT0gMSl7CiAgICAJCXRvdGFsMTE9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTE9MAoJfQp9CgppZih2MjggPT0gMil7CglpZiAodjEyID09IDEpewogICAgCQl0b3RhbDEyPTEKCX1lbHNlewogICAJCSB0b3RhbDEyPTAKCX0KfWVsc2V7CglpZiAodjEyID09IDIpewogICAgCQl0b3RhbDEyPTEKCX1lbHNlewogICAJCSB0b3RhbDEyPTAKCX0KfQoKaWYodjI5ID09IDIpewoJaWYgKHYxMyA9PSAxKXsKICAgIAkJdG90YWwxMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMz0wCgl9Cn1lbHNlewoJaWYgKHYxMyA9PSAyKXsKICAgIAkJdG90YWwxMz0xCgl9ZWxzZXsKICAgIAkJdG90YWwxMz0wCgl9Cn0KCmlmKHYzMCA9PSAxKXsKCWlmICh2MTQgPT0gMil7CiAgICAJCXRvdGFsMTQ9MQoJfWVsc2V7CgkJdG90YWwxND0wCgl9Cn1lbHNlewoJaWYgKHYxNCA9PSAxKXsKCQl0b3RhbDE0PTEKCX1lbHNlewogICAgCQl0b3RhbDE0PTAKCX0KfQoKaWYodjMxID09IDEpewoJaWYgKHYxNSA9PSAyKXsKICAgIAkJdG90YWwxNT0xCgl9ZWxzZXsKICAgIAkJdG90YWwxNT0wCgl9Cn1lbHNlewoJaWYgKHYxNSA9PSAxKXsKICAgIAkJdG90YWwxNT0xCgl9ZWxzZXsKICAgIAkJdG90YWwxNT0wCgl9Cn0KCmlmKHYzMiA9PSAyKXsKCWlmICh2MTYgPT0gMSl7CiAgICAJCXRvdGFsMTY9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTY9MAoJfQp9ZWxzZXsKCWlmICh2MTYgPT0gMil7CiAgICAJCXRvdGFsMTY9MQoJfWVsc2V7CiAgICAJCXRvdGFsMTY9MAoJfQp9CgoKZXZlbnQudmFsdWU9dG90YWwrdG90YWwyK3RvdGFsMyt0b3RhbDQrdG90YWw1K3RvdGFsNit0b3RhbDcrdG90YWw4K3RvdGFsOSt0b3RhbDEwK3RvdGFsMTErdG90YWwxMit0b3RhbDEzK3RvdGFsMTQrdG90YWwxNSt0b3RhbDE2CmBgYAoKIyMgVGltZSBDYWxjdWxhdGlvbnMgaW4gQWRvYmUgeyN0aW1lY2FsY3VsYXRpb25zfQoKQ2FsY3VsYXRpbmcgYSB0aW1lIGJhc2VkIG9uIHR3byBvdGhlciB0aW1lcyBjYW4gYmUgYWNjb21wbGlzaGVkIHdpdGhpbiBBZG9iZS4KVG8gZG8gdGhpcywgY3VzdG9tIGNhbGN1bGF0aW9uIHNjcmlwdHMgdXNpbmcgdGhlIGxhbmd1YWdlIEphdmFTY3JpcHQgbXVzdCBiZSBpbXBsZW1lbnRlZC4KCiMjIyBDcmVhdGluZyBUaW1lIENhbGN1bGF0aW9ucyBpbiBBZG9iZQoKMS4gRmlyc3QsIGVuc3VyZSBhbGwgZmllbGRzIGZyb20gd2hpY2ggdGhlIHRpbWUgY2FsY3VsYXRpb25zIGFyZSB0byBiZSBtYWRlIGZyb20gb3IgYXBwbGllZCB0byBoYXZlIGJlZW4gZm9ybWF0dGVkIGludG8gdGhlIGRlc2lyZWQgdGltZSBmb3JtYXQuClRvIGRvIHRoaXM6CiAgIDEuIFJpZ2h0IGNsaWNrIG9uIHRoZSBmaWVsZCBhbmQgc2VsZWN0ICJQcm9wZXJ0aWVzIgogICAxLiBOYXZpZ2F0ZSB0byB0aGUgIkZvcm1hdCIgdGFiCiAgIDEuIEZvciAiU2VsZWN0IGZvcm1hdCBjYXRlZ29yeToiIHNlbGVjdCBgVGltZWAKICAgMS4gSW4gdGhlICJUaW1lIE9wdGlvbnMiIGludGVyZmFjZSB0aGF0IGFwcGVhcnMsIHNlbGVjdCB0aGUgZGVzaXJlZCB0aW1lIGZvcm1hdAogICAxLiBSZXBlYXQgdGhpcyBmb3IgZXZlcnkgZmllbGQgdGhhdCB0aGUgdGltZSBjYWxjdWxhdGlvbnMgd2lsbCBiZSBtYWRlIGZyb20gb3IgYXBwbGllZCB0bwogICAxLiBUaGUgZm9sbG93aW5nIGNhbGN1bGF0aW9uIHNjcmlwdCBjYWxjdWxhdGVzIHRpbWUgaW4gdGhlIGBISDpNTTpzc2AgZm9ybWF0CjEuIFNlbGVjdCB0aGUgZmllbGQgaW4gd2hpY2ggdGhlIHRpbWUgY2FsY3VsYXRpb24gd2lsbCBvY2N1cgoxLiBSaWdodCBjbGljayBvbiB0aGUgZmllbGQgYW5kIHNlbGVjdCAiUHJvcGVydGllcyIKMS4gU2VsZWN0IHRoZSAiQ2FsY3VsYXRlIiB0YWIKMS4gU2VsZWN0IHRoZSAiQ3VzdG9tIGNhbGN1bGF0aW9uIHNjcmlwdDoiIHJhZGlvIGJ1dHRvbgoxLiBTZWxlY3QgIkVkaXQuLi4iIGFuZCBpbnB1dCB0aGUgZGVzaXJlZCB0aW1lIGNhbGN1bGF0aW9uIHNjcmlwdAoKVGhlIGZvbGxvd2luZyBzY3JpcHQgZGV0YWlscyBob3cgdG8gY2FsY3VsYXRlIFggc2Vjb25kIGludGVydmFscyBiYXNlZCBvbiBhbiBpbnB1dHRlZCBzdGFydGluZyB0aW1lLgpUaGUgdGltZXMgd2l0aGluIHRoaXMgc2NyaXB0IGZvbGxvdyB0aGUgYEhIOk1NOnNzYCB0aW1lIGZvcm1hdC4KVGhlIGZvbGxvd2luZyBzY3JpcHQgY2FuIGVhc2lseSBiZSBtb2RpZmllZCB0byBjYWxjdWxhdGUgZGlmZmVyZW50IGxlbmd0aCBpbnRlcnZhbHMgb3IgdG8gdXNlIGRpZmZlcmVudCB0aW1lIGZvcm1hdHMuCgpgYGAKdmFyIHRpbWVzdGFydGVkID0gdGhpcy5nZXRGaWVsZCgic3RhcnRfdGltZV9maWVsZCIpLnZhbHVlQXNTdHJpbmc7Cgp2YXIgdGltZVNwbGl0ID0gdGltZXN0YXJ0ZWQuc3BsaXQoIjoiKSA7Cgp2YXIgdG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSk7Cgp2YXIgbmV3dG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSArICJJTlRFUlZBTCBMRU5HVEggWCIpOwoKaG91cnMgPSBNYXRoLmZsb29yKG5ld3RvdGFsU2VjLzM2MDApOwoKbWludXRlcyA9IE1hdGguZmxvb3IoKG5ld3RvdGFsU2VjICUgMzYwMCkvNjApOwoKc2Vjb25kcyA9IG5ld3RvdGFsU2VjICUgNjA7Cgp0aW1lT3V0cHV0ID0gaG91cnMgKyAiOiIgKyBtaW51dGVzICsgIjoiICsgc2Vjb25kczsKCmV2ZW50LnZhbHVlID0gdGltZU91dHB1dApgYGAKCiAgICogUHJvY2VlZCB0byBCcmVha2luZyBEb3duIHRoZSBUaW1lIENhbGN1bGF0aW9uIFNjcmlwdCB0byBnYWluIGEgZ3JlYXRlciB1bmRlcnN0YW5kaW5nIG9mIHRoZSBzY3JpcHQKCiMjIyBCcmVha2luZyBEb3duIHRoZSBUaW1lIENhbGN1bGF0aW9uIFNjcmlwdAoKYGBgCnZhciB0aW1lc3RhcnRlZCA9IHRoaXMuZ2V0RmllbGQoInN0YXJ0X3RpbWVfZmllbGQiKS52YWx1ZUFzU3RyaW5nOwoKdmFyIHRpbWVTcGxpdCA9IHRpbWVzdGFydGVkLnNwbGl0KCI6IikgOwoKdmFyIHRvdGFsU2VjID0gKCh0aW1lU3BsaXRbMF0qMzYwMCkgKyAodGltZVNwbGl0WzFdKjYwKSArICh0aW1lU3BsaXRbMl0qMSkpOwoKdmFyIG5ld3RvdGFsU2VjID0gKCh0aW1lU3BsaXRbMF0qMzYwMCkgKyAodGltZVNwbGl0WzFdKjYwKSArICh0aW1lU3BsaXRbMl0qMSkgKyAiSU5URVJWQUwgTEVOR1RIIFgiKTsKCmhvdXJzID0gTWF0aC5mbG9vcihuZXd0b3RhbFNlYy8zNjAwKTsKCm1pbnV0ZXMgPSBNYXRoLmZsb29yKChuZXd0b3RhbFNlYyAlIDM2MDApLzYwKTsKCnNlY29uZHMgPSBuZXd0b3RhbFNlYyAlIDYwOwoKdGltZU91dHB1dCA9IGhvdXJzICsgIjoiICsgbWludXRlcyArICI6IiArIHNlY29uZHM7CgpldmVudC52YWx1ZSA9IHRpbWVPdXRwdXQKYGBgCgpUaGUgdGltZSBjYWxjdWxhdGlvbiBzY3JpcHQgY2FuIGJlIGJyb2tlbiBkb3duIGludG8gdGhyZWUgcGFydHM6CgoxLiBEZWZpbmluZyB0aGUgU3RhcnQgVGltZQoKYGBgCnZhciB0aW1lc3RhcnRlZCA9IHRoaXMuZ2V0RmllbGQoInN0YXJ0X3RpbWVfZmllbGQiKS52YWx1ZUFzU3RyaW5nOwoKdmFyIHRpbWVTcGxpdCA9IHRpbWVzdGFydGVkLnNwbGl0KCI6IikgOwoKdmFyIHRvdGFsU2VjID0gKCh0aW1lU3BsaXRbMF0qMzYwMCkgKyAodGltZVNwbGl0WzFdKjYwKSArICh0aW1lU3BsaXRbMl0qMSkpOwpgYGAKCiAgICogVGhpcyBwb3J0aW9uIG9mIHRoZSBzY3JpcHQgZGVmaW5lcyB0aGUgaW5pdGlhbCB0aW1lIGZyb20gd2hpY2ggdGhlIHRpbWUgY2FsY3VsYXRpb24gaXMgdG8gYmUgZG9uZQogICAqIFRoZSBsaW5lIGB2YXIgdGltZXN0YXJ0ZWQgPSB0aGlzLmdldEZpZWxkKCJzdGFydF90aW1lX2ZpZWxkIikudmFsdWVBc1N0cmluZztgIGltcG9ydHMgdGhlIGRlc2lyZWQgc3RhcnQgdGltZSBmcm9tIHRoZSB2YXJpYWJsZSBgc3RhcnRfdGltZV9maWVsZGAuCiAgIFRoaXMgaW1wb3J0ZWQgdGltZSBzaG91bGQgYmUgaW4gdGhlIGBISDpNTTpzc2AgdGltZSBmb3JtYXQKICAgKiBUaGUgbGluZSBgdmFyIHRpbWVTcGxpdCA9IHRpbWVzdGFydGVkLnNwbGl0KCI6IikgO2AgdGhlbiByZW1vdmVzIHRoZSBjb2xvbnMgZnJvbSB0aGlzIGltcG9ydGVkIHRpbWUsIGxlYXZpbmcgdGhlIHRpbWUgYXMgYEhIIE1NIHNzYC4KICAgVGhpcyBpcyBzdG9yZWQgYXMgYSBuZXcgdmFyaWFibGUsIGB0aW1lc3BsaXRgCiAgICogRmluYWxseSwgdGhlIGxpbmUgYHZhciB0b3RhbFNlYyA9ICgodGltZVNwbGl0WzBdKjM2MDApICsgKHRpbWVTcGxpdFsxXSo2MCkgKyAodGltZVNwbGl0WzJdKjEpKTtgIGNvbnZlcnRzIHRoaXMgaW1wb3J0ZWQgdGltZSB0byBiZSBhbGwgaW4gKnNlY29uZHMqLgogICBBdCB0aGlzIHBvaW50IGluIHRoZSBzY3JpcHQsIHRoZSBpbXBvcnRlZCBzdGFydCB0aW1lIGhhcyBub3cgYmVlbiBjb252ZXJ0ZWQgdG8gYSB0b3RhbCB0aW1lIGluIHNlY29uZHMKICAgICAgKiBUaGUgZm9sbG93aW5nIG9wZXJhdG9ycyBhcmUgdXNlZCBpbiB0aGlzIGxpbmUgb2YgY29kZTogYFswXWAsIGBbMV1gLCBhbmQgYFsyXWAKICAgICAgKiBgWzBdYCByZXRyaXZlcyB0aGUgZmlyc3QgcG9ydGlvbiBvZiB0aGUgdmFyaWFibGUgYHRpbWVzcGxpdGAKICAgICAgICAgKiBUaHVzLCBgdGltZVNwbGl0WzBdYCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBgSEhgIGZyb20gdGhlIHZhcmlhYmxlIG9mIGB0aW1lc3BsaXRgCiAgICAgICAgICogTXVsdGlwbHlpbmcgdGhpcyB2YWx1ZSBvZiBob3VycyBieSAzNjAwIGluIHR1cm4gY29udmVydHMgdGhlIGhvdXJzIHRvIHNlY29uZHMKICAgICAgKiBgWzFdYCByZXRyaWV2ZXMgdGhlIHNlY29uZCBwb3J0aW9uIG9mIHRoZSB2YXJpYWJsZSBgdGltZXNwbGl0YAogICAgICAgICAqIFRodXMsIGB0aW1lU3BsaXRbMV1gIHJldHVybnMgdGhlIHZhbHVlIG9mIGBNTWAgZnJvbSB0aGUgdmFyaWFibGUgb2YgYHRpbWVzcGxpdGAKICAgICAgICAgKiBNdWx0aXBseWluZyB0aGlzIHZhbHVlIG9mIG1pbnV0ZXMgYnkgNjAgaW4gdHVybiBjb252ZXJ0cyB0aGUgbWludXRlcyB0byBzZWNvbmRzCiAgICAgICogYFsyXWAgcmV0cmlldmVzIHRoZSBzZWNvbmQgcG9ydGlvbiBvZiB0aGUgdmFyaWFibGUgYHRpbWVzcGxpdGAKICAgICAgICAgKiBUaHVzLCBgdGltZVNwbGl0WzJdYCByZXR1cm5zIHRoZSB2YWx1ZSBvZiBgc3NgIGZyb20gdGhlIHZhcmlhYmxlIG9mIGB0aW1lc3BsaXRgCiAgICAgICAgICogTXVsdGlwbHlpbmcgdGhpcyB2YWx1ZSBvZiBzZWNvbmRzIGJ5IDEgbGVhdmVzIHRoZSB0aW1lIGluIHNlY29uZHMKCjEuIERlZmluaW5nIHRoZSBOZXcgVGltZQoKYGBgCnZhciBuZXd0b3RhbFNlYyA9ICgodGltZVNwbGl0WzBdKjM2MDApICsgKHRpbWVTcGxpdFsxXSo2MCkgKyAodGltZVNwbGl0WzJdKjEpICsgIklOVEVSVkFMIExFTkdUSCBYIik7Cgpob3VycyA9IE1hdGguZmxvb3IobmV3dG90YWxTZWMvMzYwMCk7CgptaW51dGVzID0gTWF0aC5mbG9vcigobmV3dG90YWxTZWMgJSAzNjAwKS82MCk7CgpzZWNvbmRzID0gbmV3dG90YWxTZWMgJSA2MDsKYGBgCgogICAqIFRoaXMgcG9ydGlvbiBvZiB0aGUgc2NyaXB0IGRlZmluZXMgdGhlIG5ldyB0aW1lIHRvIGJlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgc3RhcnQgdGltZQogICAqIFRoZSBsaW5lIGB2YXIgbmV3dG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSArICJJTlRFUlZBTCBMRU5HVEggWCIpO2AgY2FsY3VsYXRlcyBhIG5ldyB0aW1lIGluIHNlY29uZHMgYnkgYWRkaW5nIFggYW1vdW50IG9mIHNlY29uZHMgdG8gdGhlIGluaXRpYWwgc3RhcnQgdGltZSBpbiBzZWNvbmRzCiAgICAgICogYCh0aW1lU3BsaXRbMF0qMzYwMCkgKyAodGltZVNwbGl0WzFdKjYwKSArICh0aW1lU3BsaXRbMl0qMSlgIGNvbnZlcnRzIHRoZSBpbml0aWFsIHN0YXJ0IHRpbWUgdG8gYmUgYSB0b3RhbCBvZiBzZWNvbmRzCiAgICAgICogYCsgIklOVEVSVkFMIExFTkdUSCBYImAgYWRkcyBYIGFtb3VudCBvZiBzZWNvbmRzIHRvIHRoaXMgc3RhcnQgdGltZSB0b3RhbCBvZiBzZWNvbmRzIHRvIHJlc3VsdCBpbiB0aGUgbmV3IGRlc2lyZWQgY2FsY3VsYXRlZCB0aW1lCiAgICAgICAgICogVGh1cywgaWYgdGhlIGRlc2lyZWQgY2FsY3VsYXRlZCB0aW1lIGlzIHRvIGJlIDI1IHNlY29uZHMgYWZ0ZXIgdGhlIHN0YXJ0IHRpbWUsIHRoZSBsaW5lIG9mIGNvZGUgc2hvdWxkIGxvb2sgbGlrZSB0aGUgZm9sbG93aW5nOgogICAgICAgICAgICAqIGB2YXIgbmV3dG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSArIDI1KTtgCiAgICogVGhlIGxpbmVzIG9mIGNvZGUgZm9sbG93aW5nIHRoaXMgbGluZSBjb252ZXJ0IHRoaXMgbmV3IHRvdGFsIG9mIHRpbWUgb2Ygc2Vjb25kcyBpbnRvIGhvdXJzLCBtaW51dGVzLCBhbmQgc2Vjb25kcwogICAgICAqIGBob3VycyA9IE1hdGguZmxvb3IobmV3dG90YWxTZWMvMzYwMCk7YCBjb252ZXJ0cyB0aGUgbmV3IHRvdGFsIHN0YXJ0IHRpbWUgaW4gc2Vjb25kcyBpbnRvIGhvdXJzCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIGBNYXRoLmZsb29yKClgIHJvdW5kcyB0aGUgbnVtYmVyIGluIGhvdXJzIGRvd24sIGxlYXZpbmcgb25seSB0aGUgbnVtYmVyIG9mIGhvdXJzIHdpdGggbm8gZGVjaW1hbCB2YWx1ZQogICAgICAgICAqIFRodXMsIGlmIHRoZSBuZXcgdG90YWwgdGltZSBvZiBzZW9vbmRzIGNvbnZlcnRzIGludG8gMi41NiBob3VycywgdGhlIGBNYXRoLmZsb29yKClgIHJldHVybnMgYSB2YWx1ZSBvZiAyIGhvdXJzCiAgICAgICogYG1pbnV0ZXMgPSBNYXRoLmZsb29yKChuZXd0b3RhbFNlYyAlIDM2MDApLzYwKTtgIGNvbnZlcnRzIHRoZSBuZXcgdG90YWwgc3RhcnQgdGltZSBvZiBzZWNvbmRzIGludG8gbWludXRlcwogICAgICAgICAqIFRoZSBvcGVyYXRvciBgJWAgaXMgdGhlIHJlbWFpbmRlciBvcGVyYXRvciBhbmQgcmV0dXJucyBvbmx5IHRoZSByZW1haW5kZXIgYWZ0ZXIgaW50ZWdlciBkaXZpc2lvbiBpcyBjb21wbGV0ZWQKICAgICAgICAgKiBUaHVzLCBgbmV3dG90YWxTZWMgJSAzNjAwYCByZXR1cm5zIG9ubHkgdGhlIHJlbWFpbmRlciBvZiBzZWNvbmRzIHRoYXQgZGlkIG5vdCBkaXZpZGUgd2hvbGx5IGludG8gaG91cnMuIERpdmlkaW5nIHRoaXMgdmFsdWUgYnkgNjAsIGxlYXZlcyB0aGUgcmVtYWluZGVyIGluIG1pbnV0ZXMuCiAgICAgICogYHNlY29uZHMgPSBuZXd0b3RhbFNlYyAlIDYwO2AgcmV0dXJucyB0aGUgcmVtYWluZGVyIG9mIHNlY29uZHMgdGhhdCBkaWQgbm90IGRpdmlkZSB3aG9sbHkgaW50byBob3VycyBvciBtaW51dGVzCiAgICAgICAgICogVGh1cywgdGhpcyBsZWF2ZXMgdGhlIG51bWJlciBvZiBzZWNvbmRzIHRvIGJlIGxlZnQgaW4gYEhIOk1NOnNzYCBmb3JtYXQKICAgICAgKiBBZnRlciB0aGVzZSB0aHJlZSBsaW5lcyBvZiBjb2RlLCB0aHJlZSBuZXcgdmFyaWFibGVzIGhhdmUgYmVlbiBjcmVhdGVkOiB0aGUgbnVtYmVyIG9mIGhvdXJzLCBtaW51dGVzLCBhbmQgc2Vjb25kcyBpbiB0aGUgbmV3IHRvdGFsIHN0YXJ0IHRpbWUgb2Ygc2Vjb25kcwoKMS4gRGVmaW5pbmcgdGhlIFRpbWUgT3V0cHV0CgpgYGAKdGltZU91dHB1dCA9IGhvdXJzICsgIjoiICsgbWludXRlcyArICI6IiArIHNlY29uZHM7CgpldmVudC52YWx1ZSA9IHRpbWVPdXRwdXQKYGBgCgogICAqIFRoaXMgcG9ydGlvbiBvZiB0aGUgc2NyaXB0IGRlZmluZXMgdGhlIGZpbmFsIHRpbWUgY2FsY3VsYXRlZCBpbiBgSEg6TU06c3NgIHRpbWUgZm9ybWF0CiAgICogVGhlIGxpbmUgYHRpbWVPdXRwdXQgPSBob3VycyArICI6IiArIG1pbnV0ZXMgKyAiOiIgKyBzZWNvbmRzO2AgZGVmaW5lcyBhIG5ldyB2YXJpYWJsZSBvZiB0aGUgbmV3IHRvdGFsIHRpbWUgaW4gYEhIOk1NOnNzYCB0aW1lIGZvcm1hdAogICAgICAqIFRoaXMgbGluZSB0YWtlcyB0aGUgcHJldmlvdXNseSBkZWZpbmVkIHZhcmlhYmxlcyBvZiBgaG91cnNgLCBgbWludXRlc2AsIGFuZCBgc2Vjb25kc2AgYW5kIGFkZHMgY29sb25zIGJldHdlZW4gdGhlbSB0byBnaXZlIHRoZSBuZXcgdG90YWwgY2FsY3VsYXRlZCB0aW1lIGluIGBISDpNTTpzc2AgdGltZSBmb3JtYXQKICAgKiBUaGUgbGluZSBgZXZlbnQudmFsdWUgPSB0aW1lT3V0cHV0YCB0aGVuIGRlZmluZXMgdGhlIG5ldyB0b3RhbCB0aW1lIGluIGBISDpNTTpzc2AgdG8gYmUgdGhlIG91dHB1dCB2YWx1ZSBvZiB0aGUgZmllbGQKClRoZSBmb2xsb3dpbmcgaXMgYW4gZXhhbXBsZSBzY3JpcHQgZm9yIGNyZWF0aW5nIGEgbmV3IGNhbGN1bGF0ZWQgdGltZSAxMCBzZWNvbmRzIGFmdGVyIHRoZSBzdGFydCB0aW1lOgoKYGBgCnZhciB0aW1lc3RhcnRlZCA9IHRoaXMuZ2V0RmllbGQoInRhc2tfc3RhcnRfdGltZSIpLnZhbHVlQXNTdHJpbmc7Cgp2YXIgdGltZVNwbGl0ID0gdGltZXN0YXJ0ZWQuc3BsaXQoIjoiKSA7Cgp2YXIgdG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSk7Cgp2YXIgbmV3dG90YWxTZWMgPSAoKHRpbWVTcGxpdFswXSozNjAwKSArICh0aW1lU3BsaXRbMV0qNjApICsgKHRpbWVTcGxpdFsyXSoxKSArIDEwKTsKCmhvdXJzID0gTWF0aC5mbG9vcihuZXd0b3RhbFNlYy8zNjAwKTsKCm1pbnV0ZXMgPSBNYXRoLmZsb29yKChuZXd0b3RhbFNlYyAlIDM2MDApLzYwKTsKCnNlY29uZHMgPSBuZXd0b3RhbFNlYyAlIDYwOwoKdGltZU91dHB1dCA9IGhvdXJzICsgIjoiICsgbWludXRlcyArICI6IiArIHNlY29uZHM7CgpldmVudC52YWx1ZSA9IHRpbWVPdXRwdXQKYGBgCgoqTm90ZS4qIFdoZW4gY3JlYXRpbmcgbXVsdGlwbGUgdGltZSBjYWxjdWxhdGVkIGZpZWxkcywgZWFjaCBmaWVsZCBzaG91bGQgYmUgY2FsY3VsYXRlZCBvZmYgb2YgdGhlIGludGl0aWFsIHRpbWUuCkNhbGN1bGF0ZWQgdGltZSBmaWVsZHMgc2hvdWxkICoqKk5PVCoqKiBiZSBjYWxjdWxhdGVkIG9mZiBlYWNoIG90aGVyLgpGb3IgZXhhbXBsZSwgaWYgZml2ZSBjYWxjdWxhdGVkIHRpbWUgZmllbGRzIG11c3QgYmUgY3JlYXRlZCwgZWFjaCAxMCBzZWNvbmRzIGFwYXJ0IGZyb20gZWFjaCBvdGhlciwgb25lIHNob3VsZCAqKm5vdCoqIGNhbGN1bGF0ZSBlYWNoIHRpbWUgZmllbGQgMTAgc2Vjb25kcyBiYXNlZCBvZmYgdGhlIHByZXZpb3VzbHkgY2FsY3VsYXRlZCB0aW1lLgpJbnN0ZWFkLCBlYWNoIGZpZWxkIHNob3VsZCBiZSBjYWxjdWxhdGVkIGJhc2VkIG9mZiBvZiB0aGUgaW5pdGlhbCBzdGFydCB0aW1lLgpUaHVzLCB0aGUgZmlyc3QgY2FsY3VsYXRlZCBmaWVsZCBzaG91bGQgYWRkIDEwIHNlY29uZHMgdG8gdGhlIGluaXRpYWwgc3RhcnQgdGltZS4KVGhlIHNlY29uZCBjYWxjdWxhdGVkIGZpZWxkIHNob3VsZCBhZGQgMjAgc2Vjb25kcyAqYmFzZWQgb2ZmIHRoZSBpbml0aWFsIHN0YXJ0IHRpbWUqLgpUaGUgdGhpcmQgY2FsY3VsYXRlZCBmaWVsZCBzaG91bGQgYWRkIDMwIHNlY29uZHMgYmFzZWQgb2ZmIHRoZSBpbml0aWFsIHN0YXJ0IHRpbWUuCkFuZCBzbyBmb3J0aC4KVGhpcyBlbnN1cmVzIHRoYXQgbm8gZXJyb3JzIG9jY3VyIGZyb20gY2FsY3VsYXRpbmcgdGltZXMgYmFzZWQgb2ZmIHRpbWVzIGluIGZpZWxkcyB0aGF0IGFyZSBhbHJlYWR5IGJlaW5nIGNhbGN1bGF0ZWQuCgo8YnI+CgoqTm90ZS4qIFRpbWUgY2FsY3VsYXRlZCBmaWVsZHMgY2Fubm90IGJlIG92ZXJ3cml0dGVuLgpPbmUgY2Fubm90IG1hbnVhbGx5IG92ZXJ3cml0ZSB0aGUgY2FsY3VsYXRlZCB0aW1lIGluIGEgZmllbGQgd2l0aCBhbiBhbHRlcm5hdGl2ZSB0aW1lLgpUaGUgZmllbGQgd2lsbCBhbHdheXMgcmVhZCB0aGUgdGltZSBjYWxjdWxhdGVkIGFjY29yZGluZyB0byB0aGUgaW5wdXR0ZWQgc2NyaXB0LgpUaGlzIHNob3VsZCBiZSBrZXB0IGluIG1pbmQgd2hlbiBjcmVhdGluZyBtdWx0aXBsZSBmaWVsZCB0aGF0IGZlYXR1cmUgWCBzZWNvbmQgY29uc2VjdXRpdmUgaW50ZXJ2YWxzLgpJZiBhdCBhbnkgcG9pbnQgdGhlIGludGVydmFscyBzaG91bGQgYmUgaW50ZXJydXB0ZWQgYW5kIGEgbmV3IHRpbWUgbXVzdCBiZSBtYW51YWxseSBlbnRlcmVkLCBpdCBjYW5ub3QgYmUgZG9uZS4KQSBwb3RlbnRpYWwgbWVhbnMgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSBpcyBmb3VuZCBpbiB0aGUgVG9rZW4vQmVhZCBTb3J0IGV4YW1wbGUuCgojIyMgVGhlIFBlcmZlY3QgRXhhbXBsZTogVG9rZW4vQmVhZCBTb3J0CgpUaGUgVG9rZW4vQmVhZCBTb3J0IGNvZGluZyBmb3JtIHByb3ZpZGVzIGEgcGVyZmVjdCBleGFtcGxlIG9mIHRpbWUgY2FsY3VsYXRpb25zLCBhY3Rpb24gYnV0dG9ucywgYW5kIGhpZGRlbiBmaWVsZHMgYXQgcGxheS4KVG9rZW4vQmVhZCBTb3J0IGNvbnNpc3RzIG9mIDE4IHRlbiBzZWNvbmQgaW50ZXJ2YWxzLgpBbGwgb2YgdGhlc2UgaW50ZXJ2YWxzIG9jY3VyIGFmdGVyIGEgc3BlY2lmaWVkIHN0YXJ0IHRpbWUgYW5kIHNob3VsZCBhbHdheXMgYmUgMTAgc2Vjb25kcyBhcGFydC4KSG93ZXZlciwgaWYgYW4gaW50ZXJydXB0aW9uIHNob3VsZCBvY2N1ciBkdXJpbmcgdGhlIHRhc2ssIGEgbmV3IHN0YXJ0IHRpbWUgbXVzdCBiZSBlbnRlcmVkIGludG8gb25lIG9mIHRoZSBpbnRlcnZhbHMgZnJvbSB3aGljaCB0aGUgZm9sbG93aW5nIGludGVydmFscyBzaG91bGQgY2FsY3VsYXRlZCBmcm9tLgpEdWUgdG8gdGhlIHRpbWUgZmllbGRzIGJlaW5nIGNhbGN1bGF0ZWQsIHRoZSB0aW1lIHZhbHVlcyBjYW5ub3QgYmUgbWFudWFsbHkgb3ZlcndyaXR0ZW4uClRoZSBmb2xsb3dpbmcgc29sdXRpb24gaXMgaW1wbGVtZW50ZWQgdG8gd29yayBhcm91bmQgdGhpczoKCjEuIFRpbWUgY2FsY3VsYXRpb25zIGFyZSBtYWRlIGZvciBlYWNoIG9mIHRoZSBpbml0aWFsIDE4IGludGVydmFscwogICAqIEVhY2ggb2YgdGhlc2UgaW50ZXJ2YWxzIGNhbGN1bGF0ZSBmcm9tIHRoZSBpbnRpYWwgc3RhcnQgdGltZQogICAgICAqIFRodXMsIHRoZSBmaXJzdCBpbnRlcnZhbCBjYWxjdWxhdGVzIHRlbiBzZWNvbmRzIGZyb20gdGhlIGluaXRpYWwgc3RhcnQgdGltZSwgdGhlIHNlY29uZCBpbnRlcnZhbCAyMCBzZWNvbmRzIGZyb20gdGhlIHN0YXJ0IHRpbWUsIHRoZSB0aGlyZCBpbnRlcnZhbCAzMCBzZWNvbmRzIGZyb20gdGhlIHN0YXJ0IHRpbWUsIGV0Yy4KICAgKiBXaGVuIHRoZSBpbml0aWFsIHRpbWUgaXMgaW5wdXR0ZWQsIGVhY2ggb2YgdGhlc2UgaW50ZXJ2YWxzIGNhbGN1bGF0ZSBhdXRvbWF0aWNhbGx5CjEuIEEgc2Vjb25kIHNldCBvZiB0ZXh0IGZpZWxkcyBhcmUgbWFkZSBmb3IgZWFjaCBvZiB0aGVzZSAxOCBpbnRlcnZhbHMKICAgKiBUaGVzZSBmaWVsZHMgaGF2ZSBubyBjYWxjdWxhdGlvbnMgYXBwbGllZCB0byB0aGVtCiAgICogVGhlc2UgMTggZmllbGRzIGFyZSBzZXQgdG8gYmUgW2hpZGRlbl0oYWRvYmUuaHRtbCNoaWRkZW5maWVsZHMpIGZyb20gdXNlciB2aWV3CiAgICogVGhlc2UgMTggZmllbGRzIHNlcnZlIHRvIGFsbG93IGZvciBtYW51YWxseSBlbnRyeSBvZiBhIHRpbWUgaW4gY2FzZSBvZiBhbiBpbnRlcnJ1cHRpb24KICAgKiBUaGUgMTggZmllbGRzIGFyZSBwb3NpdGlvbmVkIG92ZXIgdGhlIGluaXRpYWwgMTggZmllbGRzIHdoaWNoIGRvIHRoZSBjb250YWluIHRoZSBjYWxjdWxhdGlvbnMKMS4gQSBzZXQgb2YgMTggYnV0dG9ucyBhcmUgY3JlYXRlZCwgb25lIGZvciBlYWNoIGludGVydmFsCiAgICogRWFjaCBidXR0b24gY29ycmVzcG9uZHMgdG8gYW4gaW50ZXJ2YWwgYW5kIGlzIGNvbmZpZ3VyZWQgd2l0aCBhY3Rpb25zIHRvIGhpZGUgdGhlIGNhbGN1bGF0ZWQgdGltZSBpbnRlcnZhbCBpdCBjb3JyZXNwb25kcyB0byBhbmQgc2hvdyB0aGUgc2Vjb25kIHRleHQgdGltZSBmaWVsZCB3aGljaCBhbGxvd3MgZm9yIG1hbnVhbCBlbnRyeSB0aGF0IGl0IGNvcnJlc3BvbmRzIHRvCiAgICogRWFjaCBvZiB0aGVzZSBidXR0b25zIHNlcnZlcyB0byBoaWRlIHRoZSBjYWxjdWxhdGVkIHRpbWUgZmllbGQgZm9yIHRoZSBpbnRlcnZhbCBpbiB3aGljaCB0aGUgaW50ZXJydXB0aW9uIG9jY3VycyBhbmQgYWxsIHRoZSBmb2xsb3dpbmcgaW50ZXJ2YWxzCiAgICogRWFjaCBidXR0b24gYWxzbyBzaG93cyB0aGUgc2Vjb25kIHRpbWUgdGV4dCBmaWVsZCB3aGljaCBhbGxvd3MgZm9yIG1hbnVhbCBlbnRyeSBhbmQgYWxzbyByZXZlYWxzIHRoZSBtYW51YWwgZW50cnkgZmllbGRzIGZvciBhbGwgdGhlIGZvbGxvd2luZyBpbnRlcnZhbHMKICAgKiBFYWNoIG9mIHRoZXNlIGJ1dHRvbnMgaXMgYWxzbyBzZXQgdG8gYmUgaGlkZGVuIGZyb20gdXNlciB2aWV3CjEuIEF0IHRoZSB0b3Agb2YgdGhlIGNvZGluZyBmb3JtLCB0aGUgcmFkaW8gYnV0dG9ucyBmb3IgdGhlICJXYXMgdGhlcmUgYW4gaW50ZXJydXB0aW9uIGluIHRoZSB0YXNrPyIgcXVlc3Rpb24gYXJlIGFzc2lnbmVkIGFjdGlvbnMKICAgKiBJZiAiWWVzIiBpcyBzZWxlY3RlZCwgdGhlIDE4IGJ1dHRvbnMgYXJlIHJldmVhbGVkIGFuZCBzaG93biB0byB0aGUgdXNlcgogICAqIElmICJObyIgaXMgc2VsZWN0ZWQsIHRoZSAxOCBidXR0b25zIGFyZSBoaWRkZW4KICAgKiBUaHVzLCB3aGVuIHRoZSB1c2VyIHNlbGVjdHMgdGhhdCBhbiBpbnRlcnJ1cHRpb24gb2NjdXJyZWQsIHRoZSAxOCBidXR0b25zIGFwcGVhciBhbmQgYWxsb3cgdGhlIHVzZXIgdG8gc2VsZWN0IHRoZSBpbnRlcnZhbCBpbiB3aGljaCB0aGUgaW50ZXJydXB0aW9uIG9jY3VycmVkLgogICBXaGVuIHRoZSBidXR0b24gaXMgcHJlc3NlZCwgdGhlIGF1dG9tYXRpY2FsbHkgY2FsY3VsYXRlZCB0aW1lIGZpZWxkcyBhcmUgaGlkZGVuIGZvciB0aGF0IGludGVydmFsIGFuZCBzdWJzZXF1ZW50IGludGVydmFscywgYW5kIHRoZSBmaWVsZHMgdGhhdCBhbGxvdyBmb3IgbWFudWFsIGVudHJ5IGFyZSBzaG93biBmb3IgdGhhdCBpbnRlcnZhbCBhbmQgc3Vic2VxdWVudCBpbnRlcnZhbHMuCiAgIFRoaXMgYWxsb3dzIGZvciB0aW1lIGNhbGN1bGF0aW9ucyB0byBiZSBpbXBsZW1lbnRlZCBldmVuIHdoZW4gaW50ZXJydXB0aW9ucyBvY2N1cgoxLiBSZWZlciB0byB0aGUgVG9rZW4vQmVhZCBTb3J0IGNvZGluZyBmb3JtIGluIG9yZGVyIHRvIGdhaW4gZnVydGhlciB1bmRlcnN0YW5kaW5nIG9mIHRoaXMgc2V0dXAKCiMjIENhbGN1bGF0aW5nIHRoZSBIaWdoZXN0IExldmVsIGZyb20gYSBSb3cgb2YgVmFsdWVzCgpUaGUgZm9sbG93aW5nIHNjcmlwdCByZXR1cm5zIHRoZSBoaWdoZXN0IGxldmVsIG9mIGEgYmVoYXZpb3IuCkZvciBleGFtcGxlLCBhIGJlaGF2aW9yIG1heSBiZSBjb2RlZCBmb3IgdGhlIG51bWJlciBvZiB0aW1lcyBpdCBvY2N1cnMgYXQgZGlmZmVyZW50IGxldmVscyBvZiBpbnRlbnNpdHkuCklmIG9uZSB3YW50cyB0aGUgaGlnaGVzdCBsZXZlbCBvZiBpbnRlbnNpdHkgdGhlIGJlaGF2aW9yIG9jY3VycmVkIGF0LCByZWdhcmRsZXNzIG9mIHRoZSBudW1iZXIgb2YgdGltZXMgaXQgb2NjdXJyZWQsIHRoZSBmb2xsb3dpbmcgc2NyaXB0IGNhbiBiZSB1dGlsaXplZDoKCipOb3RlLiogVGhlIGZvbGxvd2luZyBzY3JpcHQgd2FzIGNyZWF0ZWQgZm9yIGEgdW5pcXVlIHNpdHVhdGlvbi4KRXNzZW50aWFsbHksIHRoZSBzY3JpcHQgdXRpbGl6ZXMgbXVsdGlwbGUgaWYvZWxzZSBzdGF0ZW1lbnRzLgpIb3cgdG8gZW1wbG95IGlmL2Vsc2Ugc3RhdGVtZW50cyBhbmQgY29uZGl0aW9uYWxzIGFyZSBvdXRsaW5lcyBhYm92ZS4KVGh1cyB0aGUgZXhwbGFuYXRpb24gb2YgaG93IHRoaXMgc3BlY2lmaWMgc2NyaXB0IG9wZXJhdGVzIGlzIGxlc3MgdGVjaG5pY2FsIGFuZCBicmllZi4KVGhlIGJ1aWxkaW5nIGJsb2NrcyBvZiBob3cgdG8gdW5kZXJzdGFuZCB0aGlzIHNjcmlwdCBhdCBhIG1vcmUgdGVjaG5pY2FsIGxldmVsIGFyZSBwcm92aWRlZCBhYm92ZS4KCgpgYGAKdmFyIHYxPSBnZXRGaWVsZCgiaW50ZW5zaXR5X29mX2JlaGF2aW9yXzEiKS52YWx1ZQp2YXIgdjI9IGdldEZpZWxkKCJpbnRlbnNpdHlfb2ZfYmVoYXZpb3JfMiIpLnZhbHVlCnZhciB2Mz0gZ2V0RmllbGQoImludGVuc2l0eV9vZl9iZWhhdmlvcl8zIikudmFsdWUKdmFyIHY0PSBnZXRGaWVsZCgiaW50ZW5zaXR5X29mX2JlaGF2aW9yXzQiKS52YWx1ZQp2YXIgdjU9IGdldEZpZWxkKCJpbnRlbnNpdHlfb2ZfYmVoYXZpb3JfNSIpLnZhbHVlCnZhciB2Nj0gZ2V0RmllbGQoImludGVuc2l0eV9vZl9iZWhhdmlvcl82IikudmFsdWUKCgppZiAodjYgPiAwKSB7CiAgdG90YWw2ID0gNjsKfSBlbHNlIHsKICB0b3RhbDYgPSAwOwp9CgoKaWYgKCh2NSA+IDApICYmICh2NiA8PSAwKSkgewogIHRvdGFsNSA9IDU7Cn0gZWxzZSB7CiAgdG90YWw1ID0gMDsKfQoKCmlmICgodjQgPiAwKSAmJiAodjYgPD0gMCkgJiYgKHY1IDw9IDApKSB7CiAgdG90YWw0ID0gNDsKfSBlbHNlIHsKICB0b3RhbDQgPSAwOwp9CgppZiAoKHYzID4gMCkgJiYgKHY2IDw9IDApICYmICh2NSA8PSAwKSAmJiAodjQgPD0gMCkpewogIHRvdGFsMyA9IDM7Cn0gZWxzZSB7CiAgdG90YWwzID0gMDsKfQoKaWYgKCh2MiA+IDApICYmICh2NiA8PSAwKSAmJiAodjUgPD0gMCkgJiYgKHY0IDw9IDApICYmICh2MyA8PSAwKSl7CiAgdG90YWwyID0gMjsKfSBlbHNlIHsKICB0b3RhbDIgPSAwOwp9CgppZiAoKHYxID4gMCkgJiYgKHY2IDw9IDApICYmICh2NSA8PSAwKSAmJiAodjQgPD0gMCkgJiYgKHYzIDw9IDApICYmICh2MiA8PSAwKSl7CiAgdG90YWwgPSAxOwp9IGVsc2UgewogIHRvdGFsID0gMDsKfQoKZXZlbnQudmFsdWUgPSB0b3RhbCArIHRvdGFsMiArIHRvdGFsMyArIHRvdGFsNCArIHRvdGFsNSArIHRvdGFsNgpgYGAKCiAgICogVGhlIGFib3ZlIHNjcmlwdCB1c2VzIGlmL2Vsc2Ugc3RhdGVtZW50cyB0byBkZXRlcm1pbmUgdGhlIGhpZ2hlc3QgbGV2ZWwgYXQgd2hpY2ggdGhlIGJlaGF2aW9ycyBvY2N1cnMKICAgICAgKiBEb3VibGUgYW1wZXJzYW5kcyBhcmUgdXNlZCB0byBjcmVhdGUgY29uZGl0aW9uYWwgc3RhdGVtZW50cyB3aXRoIG11bHRpcGxlIGNvbmRpdGlvbnMKICAgKiBQbGFpbmx5LCB0aGUgYWJvdmUgc2NyaXB0IGFza3Mgd2hldGhlciB0aGUgYmVoYXZpb3Igb2NjdXJzIGF0IGxlYXN0IG9uY2UgYXQgZWFjaCBsZXZlbCBvZiBpbnRlbnNpdHkKICAgICAgKiBJZiB0aGUgYmVoYXZpb3Igb2NjdXJzIGF0IHRoZSBoaWdoZXN0IGxldmVsIG9mIGludGVuc2l0eSwgdGhlIHRvdGFsIHJldHVybnMgYSA2IHdoaWNoIHNpZ25pZmllcyB0aGUgaGlnaGVzdCBsZXZlbCBvZiBpbnRlbnNpdHkKICAgICAgKiBJZiB0aGUgYmVoYXZpb3IgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGhpZ2hlc3QgbGV2ZWwsIGl0IGFza3Mgd2hldGhlciB0aGVyZSBpcyBhIHZhbHVlIHByZXNlbnQgZm9yIHRoZSBzZWNvbmQgaGlnaGVzdCBsZXZlbC4KICAgICAgSWYgdGhlcmUgaXMsIHRoZSB0b3RhbCByZXR1cm5zIGEgNSB3aGljaCBzaWduaWZpY2VzIHRoZSBzZWNvbmQgaGlnaGVzdCBsZXZlbCBvZiBpbnRlbnNpdHkKICAgICAgKiBJZiB0aGUgYmVoYXZpb3IgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIHNlY29uZCBoaWdoZXN0IGxldmVsLCBpdCBhc2tzIHdoZXRoZXIgdGhlcmUgaXMgYSB2YWx1ZSBmb3IgdGhlIHRoaXJkIGhpZ2hlc3QuCiAgICAgIElmIG5vdCBhdCB0aGUgdGhpcmQgaGlnaGVzdCwgaXQgYXNrcyBhdCB0aGUgZm91cnRoIGhpZ2hlc3QsIGFuZCBzbyBmb3J0aC4KICAgKiBUaGlzIHNjcmlwdCBtYXkgYmUgbW9kaWZpZWQgdG8gYmUgZW1wbG95ZWQgaW4gYSB2YXJpZXR5IG9mIHNpdHVhdGlvbnMKICAgKiBUaGUgYWJvdmUgc2NyaXB0IGNhbiBiZSBmb3VuZCBpbiB0aGUgUGFyZW50YWwgU2Vuc2l0aXZpdHkgYW5kIFBhcmVudGFsIEludHJ1c2l2ZW5lc3MgQ29kaW5nIEZvcm1zCiAgICAgICogVGhlc2UgZm9ybXMgc2hvdWxkIGJlIHN0dWRpZWQgaW4gb3JkZXIgdG8gZ2FpbiBncmVhdGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHNwZWNpZmljIGNvbnRleHQgZm9yIHdoaWNoIHRoaXMgc2NyaXB0IHdhcyBjcmVhdGVkIGFuZCBob3cgbWlnaHQgaXQgYmUgYXBwbGllZCB0byBvdGhlciBjb250ZXh0cwoKCiMgSG93IFRvIFNwbGl0IFBERiBGaWxlcyBpbnRvIE11bHRpcGxlIERvY3VtZW50cwoKMS4gT3BlbiB0aGUgUERGIGluIEFjcm9iYXQgREMsIGFuZCB0aGVuIGNob29zZSBUb29scyA+IE9yZ2FuaXplIFBhZ2VzIG9yIGNob29zZSBPcmdhbml6ZSBQYWdlcyBmcm9tIHRoZSByaWdodCBwYW5lLgogICAtIFRoZSBPcmdhbml6ZSBQYWdlcyB0b29sc2V0IGlzIGRpc3BsYXllZCBpbiB0aGUgc2Vjb25kYXJ5IHRvb2xiYXIuCjEuIEluIHRoZSBzZWNvbmRhcnkgdG9vbGJhciwgY2xpY2sg4oCcU3BsaXTigJ0uCiAgIC0gQSBuZXcgdG9vbGJhciBhcHBlYXJzIGJlbG93IHRoZSBzZWNvbmRhcnkgdG9vbGJhciB3aXRoIHRoZSBjb21tYW5kcyBzcGVjaWZpYyB0byB0aGUgU3BsaXQgb3BlcmF0aW9uLgoxLiBJbiB0aGlzIHNlY29uZGFyeSB0b29sYmFyLCBjaG9vc2Ug4oCcU3BsaXTigJ0gdG8gc2VlIHRoZSBkb2N1bWVudCBzcGxpdHRpbmcgb3B0aW9ucy4KMS4gSW4gdGhlIOKAnFNwbGl0IEJ54oCdIGRyb3AtZG93biBsaXN0LCBzZWxlY3QgdGhlIGNyaXRlcmlhIGZvciBkaXZpZGluZyB0aGUgZG9jdW1lbnQ6CiAgIC0gTnVtYmVyIE9mIFBhZ2VzOiBTcGVjaWZ5IHRoZSBtYXhpbXVtIG51bWJlciBvZiBwYWdlcyBmb3IgZWFjaCBkb2N1bWVudCBpbiB0aGUgc3BsaXQuCiAgICAgIC0gVGhpcyBpcyB0aGUgbW9zdCBoZWxwZnVsIG9wdGlvbiB3aGVuIHRyeWluZyB0byBzZXBhcmF0ZSBsYXJnZSBzY2FubmVkIFBERiBwYWNrZXRzIGludG8gaW5kaXZpZHVhbCBmaWxlcy4KICAgICAgSnVzdCBzcGVjaWZ5IHRoZSBudW1iZXIgb2YgcGFnZXMgYXMg4oCcMeKAnSAoaWYgdGhlIGluZGl2aWR1YWwgZG9jdW1lbnRzIGFyZSBvbmx5IG9uZSBwYWdlKSzigJwy4oCdIChpZiB0aGUgZG9jdW1lbnRzIGFyZSBkb3VibGUgc2lkZWQpLCBldGMuCiAgIC0gRmlsZSBTaXplOiBTcGVjaWZ5IHRoZSBtYXhpbXVtIGZpbGUgc2l6ZSBmb3IgZWFjaCBkb2N1bWVudCBpbiB0aGUgc3BsaXQuCiAgIC0gVG9wLWxldmVsIEJvb2ttYXJrczogSWYgdGhlIGRvY3VtZW50IGluY2x1ZGVzIGJvb2ttYXJrcywgY3JlYXRlcyBvbmUgZG9jdW1lbnQgZm9yIGV2ZXJ5IHRvcC1sZXZlbCBib29rbWFyay4KMS4gVG8gc3BlY2lmeSBhIHRhcmdldCBmb2xkZXIgZm9yIHRoZSBzcGxpdCBmaWxlcyBhbmQgZmlsZW5hbWUgcHJlZmVyZW5jZXMsIGNsaWNrIOKAnE91dHB1dCBPcHRpb25z4oCdLgpTcGVjaWZ5IHRoZSBmb2xkZXIgaW4gdGhlIGxhYiBkcml2ZSB0aGF0IHRoZSBmaWxlcyBzaG91bGQgYmUgc2F2ZWQgdG8sIGFuZCB0aGVuIGNsaWNrIE9LLgoKKk9wdGlvbmFsOiogVG8gYXBwbHkgdGhlIHNhbWUgc3BsaXQgdG8gbXVsdGlwbGUgZG9jdW1lbnRzLCBjbGljayDigJxTcGxpdCBNdWx0aXBsZSBGaWxlc+KAnS4KSW4gdGhlIFNwbGl0IERvY3VtZW50cyBkaWFsb2cgYm94LCBjbGljayBlaXRoZXIg4oCcQWRkIEZpbGVz4oCdLCBhbmQgY2hvb3NlIOKAnEFkZCBGaWxlc+KAnSwg4oCcQWRkIEZvbGRlcnPigJ0sIG9yIOKAnEFkZCBPcGVuIEZpbGVz4oCdLgpTZWxlY3QgdGhlIGZpbGVzIG9yIGZvbGRlciwgYW5kIHRoZW4gY2xpY2sgT0suCg==