Initial RMD Start Date: 2024-04-24
Last Updated: 2024-07-31
Print Date: 2025-07-12
TABLE OF CONTENTS
Utilize the Table of Contents (TOC) menu on the left to scroll
through the different sections and help navigate this report. You can
click on the title to go directly to the section.
If you’re viewing the PDF version, the Table of Contents stays at the
top of this report. To go directly to a section, copy and paste the
title into the search box. Use the following shortcut keys to help
navigate with ease:
Shortcut Keys:
- Hold
Ctrl
and press the Home
key to go to
the top of the page.
- Hold
Ctrl
and press the End
key to go to
the bottom of the page.
- Hold
Ctrl
and press the F
key to search
for specific text or strings of text.
- Press the
Esc
key to quickly exit the search box.
About This Report
This report is published on RPubs. KDF stands for Ken Does Fitness. Refer to
References at the bottom of this page for cited sources. The RMD file to
produce this report, and some of the figures from this report, may be
found in the Google Drive folder .
This report systematically records and analyzes workout statistics to
enhance individual and collective performance by achieving the following
goals:
- Track and Improve Performance - Regularly measuring workout
statistics helps individuals monitor progress, set realistic goals, and
tailor training plans for optimal results.
- Informed Decision Making - Detailed data analysis allows for
personalized adjustments in training loads, reducing the risk of injury
and enhancing overall performance.
- Foster Healthy Competition - Comparing personal performance over
time and with peers creates a motivating and competitive environment
that encourages continuous improvement.
- Data-Driven Insights - Identifying trends and patterns in
performance metrics helps athletes make informed adjustments to their
training for sustained improvement and injury prevention.
Pros
|
Cons
|
Enhanced performance tracking: Helps monitor progress and identify
strengths and weaknesses.
|
Resource intensive: Requires time and effort for accurate data entry and
maintenance.
|
Motivation and accountability: Sets clear benchmarks and goals, boosting
motivation.
|
Potential for misinterpretation: Incorrect data analysis can lead to
wrong conclusions.
|
Data-driven decision making: Informs better training choices based on
data analysis.
|
Privacy concerns: Risks of handling personal performance data
insecurely.
|
Facilitates comparison and competition: Encourages healthy competition
and self-improvement.
|
Emphasis on quantitative metrics: May overlook qualitative aspects like
mental well-being and enjoyment.
|
Formatting - This report is initially printed as one continuous page
in HTML format and may appear differently when viewed in PDF format.
Terminology - The terms activity, workout, and exercise may be used
interchangeably in this context, even though they have distinct
meanings.
Data Assumptions - The data used for analyses assumes each set of
exercise is performed to Rep Max (RM), which isn’t always the case,
particularly if the individual isn’t aiming to perform the set to RM.
Assuming each set of exercise is performed to Rep Max helps standardize
data and provide clear insights into maximal strength, which is
beneficial for benchmarking and tracking progress. However, it can also
lead to inaccuracies, potential overtraining, and misleading data if not
all exercises are performed to failure. Balancing the use of 1RM
assumptions with realistic training practices is essential for accurate
performance assessment and effective training programming.
STRENGTH STANDARDS
Strength Standards provide valuable benchmarks for assessing an
individual’s performance in key strength exercises that are widely
practiced in fitness and strength training. These standards categorize
performance levels based on either amount of weight executed relative to
bodyweight, or repetitions executed, and are segmented by gender and
experience levels. By comparing an individual’s performance against
these established standards, trainers and athletes can identify
strengths and weaknesses in their training regimens, set realistic
goals, and measure progress in a structured manner.
Strength Standards Overview
Several strength standards are readily available online:
Finding accurate strength standards depends on the demographic,
exercise type, and required accuracy. Each has its pros and cons: some
cater to specific demographics, others focus on certain exercises, and
their credibility affects reliability. Usability and comprehensive data
for benchmarking are crucial, as are regular updates to reflect current
trends. Considering these factors helps trainers and athletes choose the
best standards for assessing and improving performance.
Pros
|
Cons
|
Benchmarking: Strength standards provide clear benchmarks to measure
progress and set goals.
|
Generic: Strength standards can be too generic and may not account for
individual differences in genetics, body composition, and training
history.
|
Motivation: Seeing how your performance stacks up against established
standards can be highly motivating.
|
Pressure: They can create undue pressure to meet certain benchmarks,
potentially leading to injury or burnout.
|
Guidance: They offer guidance on what is considered strong or weak for
different exercises, helping you tailor your training accordingly.
|
Outdated Information: Some standards may be based on outdated
information or not reflect recent advancements in sports science.
|
Comparison: They allow for meaningful comparisons between individuals,
helping to identify strengths and weaknesses.
|
Not Comprehensive: They might not cover all exercises or account for
different training goals, such as hypertrophy versus strength.
|
Structured Training: Strength standards can help in designing more
structured and effective training programs.
|
Misleading: For beginners, strength standards can be misleading if they
don’t account for the starting point or rate of progress appropriate for
different fitness levels.
|
I’ve compiled some of the standards into an Excel file. This allows for
comparison between personal performance measures and the specified
strength standards. I recommend consulting each source for confirmation
on the latest version, as the structure or numbers may have changed over
time.
Standards Categories
The standards compiled are separated into categories, as shown in the
following table, making it easy to determine which exercise to use as a
benchmark.
Categories
|
Categories
|
Push Ups
|
Romanian Deadlift
|
Bench Press
|
T Bar Row
|
Incline Bench Press
|
Press
|
Pull Ups
|
Barbell Shoulder Press
|
Lat Pulldown
|
Dumbbell Shoulder Press
|
Deadlift
|
Military Press
|
Strength Standards List
Below is the list of Strength Standards compiled into the SS Excel
file.
This file references the source of each standard table. We’ll delve into
Mark Rippetoe’s Starting Strength Standards, as his and his colleagues’
methods and research are based on comprehensive and technical
information.
Strength Standard
|
Category
|
Male Barbell Curl Std 1RM By Age Strengthlevel
|
Barbell Curl
|
Male Barbell Curl Std 1RM By Bodyweight Strengthlevel
|
Barbell Curl
|
Male Barbell Curl Std 1RM Strengthlevel
|
Barbell Curl
|
Male Barbell Shoulder Press Std 1RM By Age Strengthlevel
|
Barbell Shoulder Press
|
Male Barbell Shoulder Press Std 1RM By Bodyweight Strengthlevel
|
Barbell Shoulder Press
|
Male Barbell Shoulder Press Std 1RM Strengthlevel
|
Barbell Shoulder Press
|
Male Bench Press Std 1RM By Age Strengthlevel
|
Bench Press
|
Male Bench Press Std 1RM By Bodyweight Mark Rippetoe
|
Bench Press
|
Male Bench Press Std 1RM By Bodyweight Strengthlevel
|
Bench Press
|
Male Bench Press Std 1RM Strengthlevel
|
Bench Press
|
Male Deadlift Std 1RM By Age Strengthlevel
|
Deadlift
|
Male Deadlift Std 1RM By Bodyweight Mark Rippetoe
|
Deadlift
|
Male Deadlift Std 1RM By Bodyweight Strengthlevel
|
Deadlift
|
Male Deadlift Std 1RM Strengthlevel
|
Deadlift
|
Male Dumbbell Shoulder Press Std 1RM By Age Strengthlevel
|
Dumbbell Shoulder Press
|
Male Dumbbell Shoulder Press Std 1RM By Bodyweight Strengthlevel
|
Dumbbell Shoulder Press
|
Male Dumbbell Shoulder Press Std 1RM Strengthlevel
|
Dumbbell Shoulder Press
|
Male Incline Bench Press Std 1RM By Age Strengthlevel
|
Incline Bench Press
|
Male Incline Bench Press Std 1RM By Bodyweight Strengthlevel
|
Incline Bench Press
|
Male Incline Bench Press Std 1RM Strengthlevel
|
Incline Bench Press
|
Male Lat Pulldown Std 1RM By Age Strengthlevel
|
Lat Pulldown
|
Male Lat Pulldown Std 1RM By Bodyweight Strengthlevel
|
Lat Pulldown
|
Male Lat Pulldown Std 1RM Strengthlevel
|
Lat Pulldown
|
Male Military Press Std 1RM By Age Strengthlevel
|
Military Press
|
Male Military Press Std 1RM By Bodyweight Strengthlevel
|
Military Press
|
Male Military Press Std 1RM Strengthlevel
|
Military Press
|
Named Range List
|
Named Ranges
|
Male Press Std 1RM By Bodyweight Mark Rippetoe
|
Press
|
Male Pull Ups Std 1RM Strengthlevel
|
Pull Ups
|
Male Pull Ups Std 1RM Weight By Age Strengthlevel
|
Pull Ups
|
Male Pull Ups Std 1RM Weight By Bodyweight Strengthlevel
|
Pull Ups
|
Male Pull Ups Std Reps By Age Strengthlevel
|
Pull Ups
|
Male Pull Ups Std Reps By Bodyweight Strengthlevel
|
Pull Ups
|
Male Push Ups Std Reps By Age Strengthlevel
|
Push Ups
|
Male Push Ups Std Reps By Bodyweight Strengthlevel
|
Push Ups
|
Male Push Ups Std Reps Strengthlevel
|
Push Ups
|
Male Romanian Deadlift Std 1RM By Age Strengthlevel
|
Romanian Deadlift
|
Male Romanian Deadlift Std 1RM By Bodyweight Strengthlevel
|
Romanian Deadlift
|
Male Romanian Deadlift Std 1RM Strengthlevel
|
Romanian Deadlift
|
Male Squat Std 1RM By Age Strengthlevel
|
Squat
|
Male Squat Std 1RM By Bodyweight Mark Rippetoe
|
Squat
|
Male Squat Std 1RM By Bodyweight Strengthlevel
|
Squat
|
Male Squat Std 1RM Strengthlevel
|
Squat
|
Male T Bar Row Std 1RM By Age Strengthlevel
|
T Bar Row
|
Male T Bar Row Std 1RM By Bodyweight Strengthlevel
|
T Bar Row
|
Male T Bar Row Std 1RM Strengthlevel
|
T Bar Row
|
MARK RIPPETOE’S STANDARDS
Mark Rippetoe’s Strength Standard: 1 Rep Max By Bodyweight.
Here we utilize Mark Rippetoe’s Strength Standards to benchmark
individual performance against established criteria for primary strength
exercises. These standards are instrumental in evaluating an
individual’s lifting capabilities in relation to their bodyweight and
training experience. By doing so, we can effectively gauge progress,
pinpoint areas that need improvement, and tailor training programs to
better meet the specific strength goals of each individual.
The exercises use the technique described in “Starting Strength:
Basic Barbell Training, 3rd ed.” The Bluebook may be purchased through
The Aasgaard Company online store and on Amazon in various mediums
(paperback, Kindle, audio). All lifts are performed with the barbell, as
indicated by the book title.
This project has been a continuous process of editing, updating, and
reviewing as I progress. After considering both StrengthLevel.com and
Mark Rippetoe’s Standards via an article by Legion Athletics, I decided
to utilize Mark Rippetoe’s Standards to create visual plot benchmarks.
(My primary goal is to create spider charts for creative and visually
motivating targets.) However, the Legion Athletics article lacked
information on how these measures are obtained and what techniques or
instruments are used in executing these standards.
I emailed rip@startingstrength.com for clarification regarding
the Male Overhead Shoulder Press Strength Standards and was advised to
“Ignore this table. It is invalid, and we haven’t used it in 20 years.
As you would know if you had read the blue book.” Upon further research,
Mark Rippetoe confirmed the changes in categories on Starting Strength
Forum
from the previous outdated categories (Beginner, Novice, Intermediate,
Advanced, and Elite) to the current Cat. I through Cat. V.
To properly utilize these standards, it is recommended to review
“Starting Strength: Basic Barbell Training” and “Practical
Programming for Strength Training.” The most recent and relevant 3rd editions
(2012) are available on their website, as well as in different mediums
on Amazon. You can download online book samples to determine if Starting
Strength suits your needs.
Strength Standard
|
Category
|
Male Bench Press Std 1RM By Bodyweight Mark Rippetoe
|
Bench Press
|
Male Deadlift Std 1RM By Bodyweight Mark Rippetoe
|
Deadlift
|
Male Press Std 1RM By Bodyweight Mark Rippetoe
|
Press
|
Male Squat Std 1RM By Bodyweight Mark Rippetoe
|
Squat
|
There are five Starting Strength Standards, with the Power Clean
excluded in this report. Each of the four remaining Standards is
presented below, followed by a plot to visualize performances for
comparison and motivation.
Male Bench Press Std 1RM By Bodyweight Mark Rippetoe
Bodyweight (lb)
|
Cat. I
|
Cat. II
|
Cat. III
|
Cat. IV
|
Cat. V
|
114
|
84
|
107
|
130
|
179
|
222
|
123
|
91
|
116
|
142
|
194
|
242
|
132
|
98
|
125
|
153
|
208
|
260
|
148
|
109
|
140
|
172
|
234
|
291
|
165
|
119
|
152
|
187
|
255
|
319
|
181
|
128
|
164
|
201
|
275
|
343
|
198
|
135
|
173
|
213
|
289
|
362
|
220
|
142
|
183
|
225
|
306
|
381
|
242
|
149
|
190
|
232
|
316
|
395
|
275
|
153
|
196
|
239
|
325
|
407
|
319
|
156
|
199
|
244
|
333
|
416
|
320+
|
159
|
204
|
248
|
340
|
425
|

Male Deadlift Std 1RM By Bodyweight Mark Rippetoe
Bodyweight (lb)
|
Cat. I
|
Cat. II
|
Cat. III
|
Cat. IV
|
Cat. V
|
114
|
97
|
179
|
204
|
299
|
387
|
123
|
105
|
194
|
222
|
320
|
414
|
132
|
113
|
209
|
239
|
342
|
438
|
148
|
126
|
234
|
269
|
380
|
482
|
165
|
137
|
254
|
293
|
411
|
518
|
181
|
148
|
274
|
315
|
438
|
548
|
198
|
156
|
289
|
333
|
457
|
567
|
220
|
164
|
305
|
351
|
479
|
586
|
242
|
172
|
318
|
363
|
490
|
596
|
275
|
176
|
326
|
373
|
499
|
602
|
319
|
180
|
333
|
381
|
506
|
608
|
320+
|
183
|
340
|
388
|
512
|
617
|

Male Press Std 1RM By Bodyweight Mark Rippetoe
Bodyweight (lb)
|
Cat. I
|
Cat. II
|
Cat. III
|
Cat. IV
|
Cat. V
|
114
|
53
|
72
|
90
|
107
|
129
|
123
|
57
|
78
|
98
|
116
|
141
|
132
|
61
|
84
|
105
|
125
|
151
|
148
|
69
|
94
|
119
|
140
|
169
|
165
|
75
|
102
|
129
|
153
|
186
|
181
|
81
|
110
|
138
|
164
|
218
|
198
|
85
|
116
|
146
|
173
|
234
|
220
|
89
|
122
|
155
|
183
|
255
|
242
|
93
|
127
|
159
|
189
|
264
|
275
|
96
|
131
|
164
|
194
|
272
|
319
|
98
|
133
|
167
|
199
|
278
|
320+
|
100
|
136
|
171
|
203
|
284
|

Male Squat Std 1RM By Bodyweight Mark Rippetoe
Bodyweight (lb)
|
Cat. I
|
Cat. II
|
Cat. III
|
Cat. IV
|
Cat. V
|
114
|
78
|
144
|
174
|
240
|
320
|
123
|
84
|
155
|
190
|
259
|
346
|
132
|
91
|
168
|
205
|
278
|
369
|
148
|
101
|
188
|
230
|
313
|
410
|
165
|
110
|
204
|
250
|
342
|
445
|
181
|
119
|
220
|
269
|
367
|
479
|
198
|
125
|
232
|
285
|
387
|
504
|
220
|
132
|
244
|
301
|
409
|
532
|
242
|
137
|
255
|
311
|
423
|
551
|
275
|
141
|
261
|
319
|
435
|
567
|
319
|
144
|
267
|
326
|
445
|
580
|
320+
|
147
|
272
|
332
|
454
|
593
|

1RM CALCULATOR
This 1RM Conversion Table from Strength Level displays the
Repetition Percentages of 1RM, helping to calculate the approximate
one-rep max (1RM). The one-rep max is the maximum weight you can lift
for a single repetition for a given exercise.
Repetitions
|
Percentage of 1RM
|
Example: Weight and Repetition if 1RM is 150
|
Example: Weight at 1RM if 5RM is 45
|
1
|
100%
|
150.0
|
50.6
|
2
|
97%
|
145.5
|
49.0
|
3
|
94%
|
141.0
|
47.5
|
4
|
92%
|
138.0
|
46.5
|
5
|
89%
|
133.5
|
45.0
|
6
|
86%
|
129.0
|
43.5
|
7
|
83%
|
124.5
|
42.0
|
8
|
81%
|
121.5
|
41.0
|
9
|
78%
|
117.0
|
39.4
|
10
|
75%
|
112.5
|
37.9
|
11
|
73%
|
109.5
|
36.9
|
12
|
71%
|
106.5
|
35.9
|
13
|
70%
|
105.0
|
35.4
|
14
|
68%
|
102.0
|
34.4
|
15
|
67%
|
100.5
|
33.9
|
16
|
65%
|
97.5
|
32.9
|
17
|
64%
|
96.0
|
32.4
|
18
|
63%
|
94.5
|
31.9
|
19
|
61%
|
91.5
|
30.8
|
20
|
60%
|
90.0
|
30.3
|
21
|
59%
|
88.5
|
29.8
|
22
|
58%
|
87.0
|
29.3
|
23
|
57%
|
85.5
|
28.8
|
24
|
56%
|
84.0
|
28.3
|
25
|
55%
|
82.5
|
27.8
|
26
|
54%
|
81.0
|
27.3
|
27
|
53%
|
79.5
|
26.8
|
28
|
52%
|
78.0
|
26.3
|
29
|
51%
|
76.5
|
25.8
|
30
|
50%
|
75.0
|
25.3
|
How to Calculate Your 1RM
To calculate the One Rep Max (1RM) based on the weight lifted and the
number of repetitions performed, use the following formula: Y lbs at X
Reps / % at X Reps = Y lbs 1RM
For example, if you did 5 reps at 200 lbs, and 5 reps corresponds to
89%, then 200 lbs / 0.89 = ~225 lbs 1RM
How to Calculate Your X-RM
To calculate the X Repetition Max (X-RM) from a given number of
repetitions and weight lifted, first calculate the 1RM, then use the 1RM
to get the X-RM. We do this through the following formula: Y lbs at X
Reps / % at X Reps = Y lbs 1RM
Then multiply by the percentage of your target repetitions to get
X-RM: 1RM * % at Target Reps = Y lbs X-RM
For example, if you did 5 reps at 45 lbs, and 5 reps corresponds to
89%, and you want to find the 3RM: First, calculate the 1RM: 45 lbs /
0.89 = ~50.56 lbs 1RM Then calculate the 3RM using the 3 rep percentage
(94%): 50.56 lbs * 0.94 = ~47.53 lbs 3RM
KDF WORKBOOK
A Brief Overview
This project derives data from the primary workbook, named KDF (Ken
Does Fitness). For years, I recorded my personal
performance to recall my previous workouts for the next session, as I
often had trouble remembering the weights used. As I started learning
analytics and coding methods, I wanted to apply those techniques to
something personal and applicable, which led to this report. It has
indeed been a learning process. Not to mention, the data cleaning and
organization have also been a time-consuming process. As of 2025-07-12,
the contents of this workbook include a combination of performance data,
formulas, code, and reference resources. Until a separate file with a
more user-friendly experience is available without the necessary
back-end coding information, this file will have to suffice.
The following table from KDF addresses the primary sheets helpful in
improving workout performance and performance analyses. Some of the
sheets listed serve as sections in this report.
TABLE OF CONTENTS
|
EXPLANATION
|
Date_Notes
|
Contains date-specific notes and entries, used for tracking progress,
gaps in progress, and important events.
|
Vitals
|
Records vital statistics such as weight, body measurements, and other
health-related data.
|
Raw_Data
|
Stores the unprocessed data collected from various sources with little
analysis calculations performed.
|
Stats_Specific
|
Contains specific statistical analyses or summaries derived from the raw
data. Using the Primary Drop Down Table helps draws the statistics
for the drafted Target Goal, the Last Exercise performed, date-specified
statistics for Past Exercises, and a 1RM Convertor based on mentioned
statistics to serve as a benchmark goal to help finish off that last set
of exercise. Available on the mobile Excel app, replacing the Pivot
Table as it is unavailable on certain mobile versions of the
app. *This workbook is set to View; you’ll need to “Edit a copy” and
save this file to filter criteria and properly explore this sheet.
|
Raw_Data_Pivot
|
Provides pivot tables created from the raw data for summarizing and
analyzing data trends. Pivot Table is useful, but some mobile
versions or phones, does not support ability to change criteria with
Pivot Tables. Unable to find solution to properly utilize Pivot
Tables on the mobile phone app. Therefore Stats_Specific datasheet was
created for mobile review and filtering using the drop-down menu.
|
Demographic
|
Includes demographic information about individuals or groups, such as
age, gender, and other relevant characteristics.
|
DEMOGRAPHIC
This section includes demographic information about individuals or
groups, such as age, gender, and other relevant characteristics. Lists
information for individuals with at least one set of data in the
workbook.
Name
|
Birthdate
|
Age
|
City
|
Alex
|
1996-03-04
|
28
|
Santa Barbara
|
Josh
|
1991-11-03
|
33
|
Santa Barbara
|
Kendrick
|
1992-05-24
|
32
|
Santa Barbara
|
Lucien
|
1995-05-04
|
29
|
Los Angeles
|
Nathan
|
1992-06-11
|
32
|
Los Angeles
|
Sam
|
NA
|
NA
|
NA
|
Test Dummy
|
1986-06-09
|
38
|
San Diego
|
VITALS
The “Vitals” section tracks key health metrics such as weight, body
measurements, and heart rate to monitor progress, set personalized
fitness goals, and identify patterns or potential health risks. By
providing a comprehensive view of an individual’s health, it enables
data-driven decisions for adjusting fitness plans and ensures a balanced
approach to achieving long-term fitness goals. Regular updates and
visual tools like charts help in understanding trends and motivating
continued effort. If performance data is the brain of this report, then
vitals are the heart—pun intended.
Vitals Category
The Vitals columns provide a list of measurement categories available
for further analysis.
Entries
|
Entries
|
Date
|
Weight lbs
|
Time
|
Height
|
Name
|
Body Fat %
|
Systolic Blood Pressure (Top Number 120)
|
BMI
|
Diastolic Blood Pressure (Bottom Number 80)
|
Subjective Symptoms
|
Pulse
|
Other Notes
|
Heart Rate
|
|
Individuals with a Vital
Alex |
Josh |
Kendrick |
Lucien |
Test Dummy |
BODYWEIGHT
An individual’s bodyweight is used to match performance measurements
with Mark Rippetoe’s Strength Standards mentioned earlier in this
report. Bodyweight allows for simple techniques and methods to assess
performance, such as when hitting plateaus or experiencing changes in
bodyweight.
All Bodyweight Over Time
The plot displays all bodyweight measurements over time, with all
individuals plotted on a single graph. Individuals represented by just a
dot and no line have only one measurement recorded, indicating that more
data is required; any two points will create a line.
Name
|
Date Range
|
Entries
|
Min BW
|
Min BW Date
|
Max BW
|
Max BW Date
|
Alex
|
2023-10-04 to 2024-07-31
|
15
|
175.0
|
2024-07-31
|
196.0
|
2024-05-08
|
Josh
|
2024-03-05 to 2024-06-06
|
2
|
185.0
|
2024-03-05
|
190.0
|
2024-06-06
|
Kendrick
|
2023-09-05 to 2024-07-31
|
95
|
130.3
|
2023-09-22
|
141.8
|
2024-02-11
|
Lucien
|
2024-02-06 to 2024-05-05
|
2
|
155.0
|
2024-02-06
|
160.0
|
2024-05-05
|
Test Dummy
|
2023-08-20 to 2024-01-05
|
5
|
158.0
|
2024-01-02
|
169.0
|
2023-08-20
|

Individual Bodyweight Over Time
These visualizations allow us to:
- Track the bodyweight trends of each individual.
- Identify key metrics such as the minimum and maximum bodyweight, and
the number of measurements taken.
- Understand how bodyweight changes over time may correlate with
performance in strength exercises and other fitness metrics.
- By comparing these plots with strength standards, demographic
information, and other performance data, we can gain valuable insights
into each individual’s progress and areas needing improvement.





Individual Bodyweight Over Last 2 Weeks
Unable to plot all individuals in one figure as each individual’s
last 2-week date range differs from one another. The average bodyweight
over the date range is presented in the subtitles.





Avg Bodyweight Over Last 2 Weeks
Side by side comparison between individuals.
Name
|
Age At Avg BW
|
Average Bodyweight (lbs)
|
Date Range
|
Alex
|
29
|
175.00
|
2024-07-18 to 2024-07-31
|
Josh
|
33
|
190.00
|
2024-05-24 to 2024-06-06
|
Kendrick
|
33
|
133.46
|
2024-07-18 to 2024-07-31
|
Lucien
|
29
|
160.00
|
2024-04-22 to 2024-05-05
|
Test Dummy
|
38
|
160.68
|
2023-12-23 to 2024-01-05
|

Avg Bodyweight by Age
This plot displays data for all individuals. This dataset–age vs
bodyweight–is seems limited in isolation. With other data points and
contextion information it can offer valuable insights,particularly if
used it can still offer valuable insights when used alongside other data
points and contextual information. Its usefulness largely depends on how
it’s interpreted and integrated into a broader analysis framework.

DATA ENTRIES
The meat and potatoes. Without this, what’s the point?
Column Entries
The following columns from the Raw Data sheet in the KDF Workbook are
shown below. Nearly all columns are utilized for analyses, although
some, like “Duration,” are rarely recorded. Most of my workouts are
focused on strength training rather than cardio and endurance training.
Volume measures have also not been a primary focus compared to 1RM
(one-rep max), which serves as a requirement for comparison with 1RM
strength standards.
Column Names
|
Column Names
|
Date
|
Barbell_Weight
|
Day
|
Total_Weight
|
Name
|
Raw_Reps
|
Position
|
Final_Reps
|
Instrument
|
1RM_Calculated_Weight
|
Activity
|
Volume
|
Lateral_Movement_Performed
|
Duration
|
Variation
|
TIMEVALUE
|
Grip
|
Distance
|
Set_#
|
Notes
|
Weight
|
|
Exercise Variations List
Entries from raw_data
are extracted for further
analysis. Whether indoors or outdoors, using calisthenics or equipment,
performing aerobic or anaerobic exercises, there are countless exercises
and ways to perform them. These exercises vary in instruments and
positions used, requiring different muscle activation.
Not included in the lists are entries pertaining to different grips
(wide, mid, close, underhand, overhand, neutral, and alternate, such as
for deadlifts). A Wide Grip Bicep Curl utilizes external rotation,
limits the range of motion allowing for heavier weights, places more
stress on the elbow joints, emphasizes the short head of the biceps, and
engages the upper back and shoulders. In contrast, a Close Grip Bicep
Curl utilizes internal rotation, allows for a greater range of motion,
focuses on the long head of the biceps, and engages the forearm
muscles.
Positions
Incorporating different positions into a workout routine can enhance
muscle development, improve functional strength, and reduce the risk of
overuse injuries by ensuring a balanced workout.
Positions
|
Positions
|
Bent Over
|
Seated
|
Decline Bench
|
Seated Back Pad
|
Flat Bench
|
Seated Front Pad
|
Incline Bench
|
Side-Lying
|
Kneeled
|
Standing
|
Prone
|
|
Instruments
Using a variety of instruments in workouts can help target different
muscle groups more effectively, provide varied resistance, and offer
safer and more efficient exercise options.
Instruments
|
Instruments
|
Instruments
|
Ab Crunch Machine
|
Full Crunch Machine
|
Machine (Loaded)
|
Barbell
|
Hack Squat Machine (Loaded)
|
Machine (Nitro Pec Fly / Rear Delt)
|
Barbell (Loaded)
|
Hammer Strength Machine
|
Plate
|
Bicep Curl Machine
|
Hip Abduction Machine
|
Plyo Box
|
Cable
|
Horizontal Leg Press Machine
|
Preacher Pad
|
Cable Bar
|
Hyperextension Bench
|
Preacher Pad, Dumbell
|
Cable EZ Bar
|
Iso-Lateral Incline Press Machine (Loaded)
|
Prone Leg Curl Machine
|
Cable Handle
|
Isolateral Row Machine
|
Pull-Up Bar
|
Cable Handle (Doube Pulley)
|
Kettlebell
|
Resistance Band
|
Cable Rope
|
Lat Pulldown Bar
|
Smith Machine (Loaded)
|
Cable Rope (Long)
|
Lat Pulldown Bar (Double Pulley)
|
Straight Barbell
|
Cable Straight Bar
|
Lat Pulldown Bar (Mag Grip)
|
T-Bar Row Landmine
|
Cable V-bar
|
Lat Pulldown Bar (Mag Grip) (Double Pulley)
|
Track Lane 6
|
Cable V-bar (Double Pulley)
|
Leg Curl Machine
|
Trap Bar (Loaded)
|
Dumbbell
|
Leg Extension Machine
|
Treadmill
|
EZ Bar
|
Leg Press Machine (Loaded)
|
|
EZ Bar (Loaded)
|
Machine
|
|
Activities
The following activities (or exercises) have been entered into the
Raw Data. Other activities are available but have not been performed.
Some, such as “Track Lane 6,” are specific to location and time
duration. Other activities are universally available, such as Chest
Press and Lat Pulldown. However, when time is a factor, sometimes you’ve
got to pivot and improvise your workout with other types of
exercises.
Activities
|
Activities
|
Activities
|
Abdominal Crunch
|
High-Bar Squat
|
Plate Curls
|
Abdominal Crunch (Arm & Leg Pull)
|
High Chest Fly
|
Pull-Up
|
Arnold Press
|
Hip Abduction
|
Push-up
|
Back Extension
|
Hip Thrust
|
Push Press
|
Behind The Neck Press
|
Jump
|
Rear Delt Fly
|
Bench Row
|
Kettlebell Swing (One Handed)
|
Row
|
Bicep Curl
|
Kettlebell Swing (Two Handed)
|
Run
|
Box Jump 30”
|
Lat Pulldown
|
Run (Nona’s->Mission)
|
Box Jump 36”
|
Lateral Shoulder Raise
|
Run (Nona’s<-Mission)
|
Box Jump 39”
|
Leg Curl
|
Run (Treadmill)
|
Box Jump 40”
|
Leg Extension
|
Shoulder Raise
|
Box Jump 42”
|
Leg Press
|
Shoulder Shrug
|
Cable Y Raise
|
Low-Bar Squat
|
Side Bend
|
Calf Raise
|
Low Chest Fly
|
Side Leg Circles
|
Chest Fly
|
Low Row
|
Skull Crusher
|
Chest Press
|
Lunge
|
Sprint
|
Crunch
|
Military Press
|
Squat
|
Deadlift
|
Oblique Twist
|
Straight Arm Lat Pulldown
|
Diagonal Shoulder Raise
|
Oblique Twist Down
|
Tricep Pulldown
|
Face Pull
|
Oblique Twist Up
|
Tricep Pushdown
|
Face Pull with External Rotation
|
One Arm Oblique Crunch
|
Upright Row
|
Face Pull with Externatl Rotation
|
Overhead Shoulder Press
|
Wrist Curl
|
Front Shoulder Raise
|
Overhead Tricep Extension
|
|
Hammer Curl
|
Pallof Press
|
|
STATS TO STANDARDS
Performance measures are evaluated to match Standards.
1RM Table - Avg L2W & ATH
The following table reports the average one-repetition maximum (1RM)
for each individual across each specified exercise (“Selected Criteria”)
over the last two weeks (L2W). The data for the last two weeks serves as
a benchmark for the next workout. As the saying goes, “You’re only as
good as your last.”
The table also reports highest 1RM over all time (ATH) for each
selected criterion, accompanied by the last date the highest 1RM was
achieved.
The 1RM is calculated based on weight executed per set and the number
of reps, using the 1RM Conversion Table.
All calculations assume the standard barbell (Olympic barbell) weight
of 45 pounds (20.4 kg).
Keep in mind there are many variables affecting performance. One of
these variables includes grip (wide, alternating, overhand, etc.). One
individual may use alternating grips (left underhand/right overhand, or
vice-versa) when performing deadlifts to maximize weight execution.
Another individual might utilize an overhand grip. Someone else may
perform a combination of alternating grip and overhand grip. The
following datasets and figures do not account for these differences.
Selected Criteria
|
Index
|
Name
|
Average 1RM (lbs)
|
Date Range (Last 2 Weeks)
|
Highest 1RM All Time (lbs)
|
Last Date Highest 1RM All Time
|
Flat Bench Barbell Chest Press
|
1
|
Alex
|
185.83
|
2024-07-18 to 2024-07-31
|
228.40
|
2024-01-13
|
Flat Bench Barbell Chest Press
|
1
|
Josh
|
213.15
|
2024-04-25 to 2024-05-08
|
253.09
|
2023-09-13
|
Flat Bench Barbell Chest Press
|
1
|
Kendrick
|
152.97
|
2024-07-20 to 2024-08-02
|
174.70
|
2024-02-07
|
Flat Bench Barbell Chest Press
|
1
|
Nathan
|
162.92
|
2023-04-07 to 2023-04-20
|
162.92
|
2023-04-20
|
Barbell Deadlift
|
2
|
Alex
|
224.51
|
2024-07-18 to 2024-07-31
|
261.63
|
2023-12-17
|
Barbell Deadlift
|
2
|
Josh
|
236.38
|
2023-10-27 to 2023-11-09
|
275.28
|
2023-10-18
|
Barbell Deadlift
|
2
|
Kendrick
|
219.21
|
2024-07-18 to 2024-07-31
|
267.44
|
2024-02-14
|
Barbell Overhead Shoulder Press
|
3
|
Alex
|
106.09
|
2024-06-29 to 2024-07-12
|
110.47
|
2024-07-12
|
Barbell Overhead Shoulder Press
|
3
|
Kendrick
|
72.33
|
2024-07-13 to 2024-07-26
|
87.21
|
2024-01-02
|
Barbell Squat
|
4
|
Alex
|
185.75
|
2024-07-02 to 2024-07-15
|
191.86
|
2024-07-15
|
Barbell Squat
|
4
|
Kendrick
|
173.99
|
2024-07-13 to 2024-07-26
|
207.87
|
2024-02-12
|
NOTES FOR FUTURE IMPLEMENTATION
Power BI vs. RStudio (R Programming)
Creating this report requires knowledge in managing the different
coding structure–it requires knowing R. It can be replicated through
other programs, and by doing so may enhance the overall experience. Such
is the case with Power BI but in a different aspect.
Power BI is better suited for creating interactive dashboards and
visualizations quickly and sharing them easily with non-technical
stakeholders. It is user-friendly and integrates well with other
Microsoft products, making it ideal for business environments that
require regular reporting and real-time data updates.
R Studio, on the other hand, is ideal for in-depth data analysis,
complex statistical modeling, and projects that require extensive data
manipulation and custom analyses. It offers greater flexibility and is
more powerful for advanced analytics, although it requires programming
knowledge and may have a steeper learning curve.
If the primary goal is to perform advanced statistical analysis and
custom modeling, R Studio would be more appropriate. However, if the
goal is to create interactive, shareable dashboards and reports, Power
BI might be the better choice. This is a toss coin, as my intent is to
provide both advanced statistical analysis and custom modeling as I
learn to further utilize the program, but also allow others the
availability to interact with their data, should that time ever
come.
Prospective Statistical Analyses
More advanced statistical measurements are available to derive from
the dataset. I’ve included a general list of ideas to explore. Some
ideas require a larger demographic group, and others necessitate the use
of technological devices (watches and phone apps). At the time of
publishing, I am working on plotting multiple variables on one plot. One
includes plotting Average Bodyweight (y) and Daily Average 1RM (y) over
time (x). This will help explore any correlation and causation between
variables. Findings are expected to provide adaptable insights into
daily routines and habits.
Dual Y-axis Plot
This type of plot allows you to visualize two different y-variables
against the same x-variable
Average Bodyweight and Daily Average 1RM over time
- Plot = Selected Criteria for Individual
- Y-variable = Avg Bodyweight
- Requires creating new df from Vitals; Daily_Avg_Bodyweight (Avg BW
of all measures on each date)
- Y-variable = Daily Avg 1RM
- Requires creating new df from Raw Data; Daily_Avg_1RM (Avg 1RM of
all sets on each date)
- X-variable = Date (day/month)
- Imagine plot similar to Webull Comparison Quotes structure
Daily Average 1RM and # Daily Sets over time for Selected
Criteria
- Plot = Selected Criteria for Individual
- Y-variable = Daily Average 1RM
- Consider to sub Daily with Weekly or Monthly Average 1RM
- Consider to sub Average 1RM with Highest 1RM
- Y-variable = Daily Sets Performed
- Consider to sub Daily Sets with Weekly or Monthly Sets
- A larger and consistent number of sets performed is expected
correlate or maintain 1RM measures.
- Gaps in number of sets performed is expected to correlate with
decreased 1RM measures

Stacked Bar Chart
Loop plots for each individual. Show [total] value of a category and
segments that bar to show the proportion of different sub-categories
within that [total] value.
% Sets of Selected Criteria by ATH 1RM and Avg 1RM
- Value = % sets performed (ie 2% of all sets performed)
- Sub-category = ATH 1RM as the full bar (ie Chest Press 174.70,
Deadlift 267.44)
- Sub-category = Avg 1RM L2W as percentage of ATH 1RM (ie Chest Press
152.71, Deadlift 219.21)
- Category = Selected Criteria (Chest Press, Deadlift, etc.)
- *Avg 1RM L2W as percentage of ATH 1RM may not be the best dataset to
compare with respect to % sets of selected criteria performed. Consider
other Sub-categories for comparison.
Other Charts
Vertical Bar Chart
- Usage: Comparing the frequency or count of different exercise
types.
- Example: Number of sessions for each exercise type (e.g., Bench
Press, Deadlift, Squat, Press).
Horizontal Bar Chart:
- Comparing the frequency or count of different exercise types with
long labels.
- Example: Number of sessions for each exercise type, displayed
horizontally for better readability.
Stacked Bar Chart:
- Usage: Showing the composition of sets within each exercise.
- Example: Number of sets performed for each exercise type, broken
down by reps range (e.g., 1-5 reps, 6-10 reps, 11+ reps).
Grouped (Clustered) Bar Chart:
- Usage: Comparing the average 1RM (one-repetition maximum) for
different exercises across multiple individuals.
- Example: Average 1RM for Bench Press, Deadlift, Squat, and Press for
Alex, Kendrick, and Josh.
100% Stacked Bar Chart:
- Usage: Showing the percentage composition of total workouts by
exercise type.
- Example: Percentage of total workouts made up by Bench Press,
Deadlift, Squat, and Press.
Diverging Bar Chart:
- Usage: Displaying positive and negative performance changes in
different exercises.
- Example: Performance improvement or decline in 1RM for each exercise
type over a period.
Lollipop Chart:
- Usage: Showing average bodyweight for each individual.
- Example: Average bodyweight of Alex, Kendrick, and Josh represented
as dots on lines.
Dot Plot:
- Usage: Showing the performance scores (e.g., 1RM) for different
exercises.
- Example: Performance scores for Bench Press, Deadlift, Squat, and
Press for each individual.
Variable Width Bar Chart:
- Usage: Showing the volume of weight lifted where the width
represents the number of sessions.
- Example: Total weight lifted in Bench Press, Deadlift, Squat, and
Press with bar width representing the number of sessions.
Waterfall Chart:
- Usage: Showing the cumulative effect of different exercise sessions
on total weight lifted.
- Example: Cumulative total weight lifted over time for different
exercises.
Pareto Chart:
- Usage: Highlighting the most significant exercises contributing to
total weight lifted.
- Example: Total weight lifted for each exercise type in descending
order with a line showing cumulative percentage.
Gantt Chart:
- Usage: Project planning and tracking progress over time.
- Example: Workout schedule showing the timeline for different
exercises and sets over a month.
Histogram:
- Usage: Showing the frequency distribution of bodyweight.
- Example: Distribution of bodyweight entries over the last
month.
Mosaic Plot:
- Usage: Displaying the relationship between exercise type and the
number of sets performed.
- Example: Visualization of how different exercises are associated
with the number of sets performed.
Utilization of Datasets
Longitudinal Analysis of Training Progress:
- Objective: To track and analyze the training progress over an
extended period.
- Implementation: Utilize time series analysis to monitor changes in
1RM and bodyweight over time. This will help identify trends, plateaus,
and periods of significant improvement. Applying smoothing techniques
and ARIMA models can aid in forecasting future performance based on
historical data.
Correlation and Causation Studies:
- Objective: To understand the relationship between different
variables.
- Implementation: Perform correlation analysis to investigate the
relationships between bodyweight, training frequency, nutritional
intake, and 1RM performance. Follow up with regression analysis to
identify potential causal relationships and quantify the impact of
various factors on strength gains.
Comparative Analysis Across Different Demographics:
- Objective: To compare performance metrics across different
demographics such as age, gender, and training experience.
- Implementation: Use t-tests and ANOVA to compare 1RM performance and
bodyweight across different demographic groups. This can help tailor
training programs to specific groups and improve overall
effectiveness.
Enhanced Visualization Techniques:
- Objective: To create more insightful and interactive
visualizations.
- Implementation: Incorporate advanced visualization libraries such as
plotly for interactive plots that allow for deeper exploration of the
data. This can include dynamic plots where users can filter and view
specific subsets of the data.
Predictive Modeling for Performance Optimization:
- Objective: To develop models that predict performance outcomes and
optimize training regimens.
- Implementation: Apply machine learning techniques such as random
forests, support vector machines, or neural networks to predict 1RM
performance based on a range of input variables. These models can be
used to suggest optimal training loads and volumes for individuals.
Cluster Analysis for Identifying Training Patterns:
- Objective: To identify distinct training patterns and group similar
individuals.
- Implementation: Use clustering techniques such as K-means clustering
to identify groups of individuals with similar training patterns and
performance metrics. This can help in customizing training programs for
different clusters based on their unique characteristics.
Survival Analysis for Training Attrition:
- Objective: To analyze the dropout rates and factors affecting
training adherence.
- Implementation: Perform survival analysis to study the
time-to-dropout for trainees and identify factors that influence
training adherence. This can guide interventions aimed at reducing
dropout rates and improving long-term training commitment.
Principal Component Analysis (PCA) for Dimensionality Reduction:
- Objective: To simplify complex datasets and identify key performance
indicators.
- Implementation: Apply PCA to reduce the dimensionality of your
dataset while retaining most of the variance. This can help in
identifying key variables that most influence training outcomes and
performance.
Nutrition and Recovery Analysis:
- Objective: To study the impact of nutrition and recovery on
performance.
- Implementation: Collect and analyze data on dietary intake, sleep
patterns, and recovery methods. Use regression analysis to determine how
these factors influence strength gains and overall performance.
Benchmarking and Standard Development:
- Objective: To establish performance benchmarks and standards for
different populations.
- Implementation: Utilize the collected data to develop performance
standards and benchmarks. This can involve creating percentile ranks and
performance categories that can be used for setting realistic goals and
expectations for trainees.
Data Collection Enhancements
Incorporating Wearable Technology:
- Utilize wearable devices to collect real-time data on heart rate,
sleep quality, and daily activity levels. This data can provide deeper
insights into how lifestyle factors influence training performance.
Detailed Nutritional Logging:
- Implement a system for detailed nutritional logging, allowing for
the collection of data on macronutrient and micronutrient intake.
Analyzing this data can help optimize dietary plans to support training
goals.
Psychological and Motivational Assessments:
- Regularly assess psychological factors such as motivation, stress
levels, and mental fatigue. Understanding the psychological aspects of
training can provide a more holistic view of an individual’s performance
and adherence to the training program.
Recovery and Injury Data:
- Collect data on recovery strategies and injury occurrences.
Analyzing this information can help in developing injury prevention
programs and optimizing recovery protocols to enhance performance.
Advanced Biometric Data:
- Incorporate the collection of advanced biometric data such as blood
markers, hormone levels, and muscle oxygenation. This can provide a
deeper understanding of physiological responses to training.
REFERENCES
LS0tDQp0aXRsZTogIlByb2plY3QgS0RGIg0KYXV0aG9yOiAnQXV0aG9yOiBLZW5kcmljayBUaGFtJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgICBwbGFjZW1lbnQ6IHRvcA0KICAgICAgdG9jX3N1YnRyZWU6IHllcyAgIyBFbnN1cmVzIHRoYXQgc3ViLXNlY3Rpb25zIGFyZSBoaWRkZW4gdW50aWwgdGhlIHByaW1hcnkgc2VjdGlvbiBpcyBjbGlja2VkDQogICAgIyBjb2RlX2ZvbGRpbmc6IGhpZGUgICAjIEhpZGUgdGhlIGNvZGUgYnkgZGVmYXVsdA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUgICMgQWRkIGEgYnV0dG9uIHRvIGRvd25sb2FkIHRoZSBSIGNvZGUgICAgDQotLS0NCg0KSW5pdGlhbCBSTUQgU3RhcnQgRGF0ZTogMjAyNC0wNC0yNA0KDQpMYXN0IFVwZGF0ZWQ6IDIwMjQtMDctMzENCg0KUHJpbnQgRGF0ZTogYHIgU3lzLkRhdGUoKWANCg0KPCEtLSAjIFJNRCBTZXR1cCAtLT4NCg0KPHN0eWxlPg0KDQovKiBSZWR1Y2UgdGhlIGZvbnQgc2l6ZSBvZiB0aGUgVE9DICovDQp7DQogIGZvbnQtc2l6ZTogMC45MGVtOyAvKiBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkICovDQp9DQoNCi8qIEFkZCBib3JkZXJzIGFuZCBzcGFjaW5nIHRvIGFsbCBmaWd1cmVzICovDQppbWcgew0KICBib3JkZXI6IDFweCBzb2xpZCAjZGRkOyAvKiBTcGVjaWZ5IGJvcmRlciBzdHlsZSAqLw0KICBwYWRkaW5nOiA1cHg7IC8qIEFkZCBwYWRkaW5nIGFyb3VuZCB0aGUgZmlndXJlcyAqLw0KICBib3JkZXItcmFkaXVzOiA1cHg7IC8qIEFkZCByb3VuZGVkIGNvcm5lcnMgdG8gdGhlIGJvcmRlciAqLw0KICBkaXNwbGF5OiBibG9jazsgLyogRW5zdXJlIHRoZSBpbWFnZSBpcyB0cmVhdGVkIGFzIGEgYmxvY2sgZWxlbWVudCB0byByZXNwZWN0IG1hcmdpbiAqLw0KICBtYXJnaW4tYm90dG9tOiAyMHB4OyAvKiBBZGQgYm90dG9tIG1hcmdpbiB0byBlYWNoIGltYWdlIGZvciBzcGFjaW5nICovDQp9DQoNCi8qIEFkZCBib3JkZXJzIHRvIGFsbCB0YWJsZXMgKi8NCnRhYmxlIHsNCiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgLyogQ29sbGFwc2UgYm9yZGVycyBpbnRvIGEgc2luZ2xlIGJvcmRlciAqLw0KICBib3JkZXI6IDFweCBzb2xpZCAjZGRkOyAvKiBTcGVjaWZ5IGJvcmRlciBzdHlsZSAqLw0KICBtYXJnaW4tYm90dG9tOiAyMHB4OyAvKiBBZGQgYm90dG9tIG1hcmdpbiB0byBlYWNoIHRhYmxlIGZvciBzcGFjaW5nICovDQp9DQoNCi8qIEFkZCBib3JkZXJzIHRvIHRhYmxlIGNlbGxzICovDQp0aCwgdGQgew0KICBib3JkZXI6IDFweCBzb2xpZCAjZGRkOyAvKiBTcGVjaWZ5IGJvcmRlciBzdHlsZSBmb3IgdGFibGUgY2VsbHMgKi8NCiAgcGFkZGluZzogOHB4OyAvKiBBZGQgcGFkZGluZyBpbnNpZGUgdGhlIHRhYmxlIGNlbGxzICovDQogIHRleHQtYWxpZ246IGxlZnQ7IC8qIEFsaWduIHRleHQgdG8gdGhlIGxlZnQgd2l0aGluIHRhYmxlIGNlbGxzICovDQp9DQoNCg0KLyogRW5zdXJpbmcgYWxsIGNvbHVtbiBoZWFkZXJzIGFyZSBhbGlnbmVkIHRvIHRoZSBsZWZ0ICovDQp0YWJsZS5rYWJsZS10YWJsZSB0aCwgdGFibGUua2FibGUtdGFibGUgdGQgew0KICAgdGV4dC1hbGlnbjogbGVmdCAhaW1wb3J0YW50Ow0KfQ0KDQoNCi8qIEFwcGx5IHN0eWxlcyB0byBhbGwgaGVhZGVycyAqLw0KdGggew0KICBwb3NpdGlvbjogc3RpY2t5OyAvKiBFbnN1cmUgaGVhZGVycyBzdGljayB3aGVuIHNjcm9sbGluZyAqLw0KICB0b3A6IDA7IC8qIFBvc2l0aW9uIGhlYWRlcnMgYXQgdGhlIHRvcCAqLw0KICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjJmMmYyOyAvKiBCYWNrZ3JvdW5kIGNvbG9yIGZvciBoZWFkZXJzICovDQogIHotaW5kZXg6IDk5OTsgLyogRW5zdXJlIGhlYWRlcnMgc3RheSBvbiB0b3Agb2Ygb3RoZXIgZWxlbWVudHMgKi8NCn0NCg0KLyogQXBwbHkgc3R5bGVzIHRvIGFsbCB0YWJsZXMgKi8NCnRhYmxlIHsNCiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgLyogQ29sbGFwc2UgYm9yZGVycyBpbnRvIGEgc2luZ2xlIGJvcmRlciAqLw0KICBib3JkZXI6IDFweCBzb2xpZCAjZGRkOyAvKiBTcGVjaWZ5IGJvcmRlciBzdHlsZSAqLw0KfQ0KDQovKiBBcHBseSBzdHlsZXMgdG8gdGFibGUgY2VsbHMgKi8NCnRoLCB0ZCB7DQogIGJvcmRlcjogMXB4IHNvbGlkICNkZGQ7IC8qIFNwZWNpZnkgYm9yZGVyIHN0eWxlIGZvciB0YWJsZSBjZWxscyAqLw0KICBwYWRkaW5nOiA4cHg7IC8qIEFkZCBwYWRkaW5nIGluc2lkZSB0aGUgdGFibGUgY2VsbHMgKi8NCiAgdGV4dC1hbGlnbjogbGVmdDsgLyogQWxpZ24gdGV4dCB0byB0aGUgbGVmdCB3aXRoaW4gdGFibGUgY2VsbHMgKi8NCn0NCg0KLyogU3R5bGUgdGFibGVzIHdpdGggYWx0ZXJuYXRpbmcgc3RyaXBlZCByb3dzICovDQp0YWJsZSB7DQogIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7DQogIHdpZHRoOiAxMDAlOw0KfQ0KDQp0aCwgdGQgew0KICBib3JkZXI6IDFweCBzb2xpZCAjZGRkZGRkOw0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KICBwYWRkaW5nOiA4cHg7DQp9DQoNCi8qIEFkZCBhbHRlcm5hdGluZyBiYWNrZ3JvdW5kIGNvbG9ycyB0byB0YWJsZSByb3dzICovDQp0cjpudGgtY2hpbGQoZXZlbikgew0KICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjJmMmYyOw0KfQ0KDQp0cjpudGgtY2hpbGQob2RkKSB7DQogIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7IC8qIFdoaXRlIGJhY2tncm91bmQgZm9yIG9kZCByb3dzICovDQp9DQoNCjwvc3R5bGU+DQoNCmBgYHtyIGRlZmF1bHRfY2h1bmtfb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0NCiMgU2V0IHJlcG9zaXRvcnkgYW5kIGRlZmF1bHQgY2h1bmsgb3B0aW9ucw0Kb3B0aW9ucyhyZXBvcyA9IGMoQ1JBTiA9ICJodHRwczovL2Nsb3VkLnItcHJvamVjdC5vcmciKSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvPUZBTFNFLCBldmFsPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSkNCmBgYA0KDQo8IS0tIA0KT3B0aW9ucyBzdWNoIGFzIGVjaG8sIG1lc3NhZ2UsIHdhcm5pbmcsIHJlc3VsdHMsIGluY2x1ZGUsIGV2YWwsIGNhY2hlLCBhbmQgbW9yZS4gDQoNCi0gZWNobzogU2hvdyBvciBoaWRlIGNvZGUgaW4gdGhlIG91dHB1dCAoZWNobyA9IEZBTFNFIGhpZGVzIHRoZSBjb2RlKS4NCi0gbWVzc2FnZTogU2hvdyBvciBoaWRlIG1lc3NhZ2VzIGluIHRoZSBvdXRwdXQgKG1lc3NhZ2UgPSBGQUxTRSBzdXBwcmVzc2VzIG1lc3NhZ2VzKS4NCi0gd2FybmluZzogU2hvdyBvciBoaWRlIHdhcm5pbmdzIGluIHRoZSBvdXRwdXQgKHdhcm5pbmcgPSBGQUxTRSBzdXBwcmVzc2VzIHdhcm5pbmdzKS4NCi0gcmVzdWx0czogQ29udHJvbCBob3cgcmVzdWx0cyBhcmUgc2hvd246DQogIC0gJ21hcmt1cCc6IERpc3BsYXkgcmVzdWx0cyBhcyB0aGV5IGFyZS4NCiAgLSAnYXNpcyc6IEluY2x1ZGUgcmVzdWx0cyBhcyByYXcgSFRNTCBvciBMYVRlWC4NCiAgLSAnaGlkZSc6IEhpZGUgcmVzdWx0cyBmcm9tIG91dHB1dC4NCi0gaW5jbHVkZTogSW5jbHVkZSBvciBleGNsdWRlIGJvdGggY29kZSBhbmQgcmVzdWx0cyBmcm9tIHRoZSBvdXRwdXQgKGluY2x1ZGUgPSBGQUxTRSBleGNsdWRlcyBldmVyeXRoaW5nKS4NCi0gZXZhbDogRXZhbHVhdGUgdGhlIGNvZGUgY2h1bmsgb3Igbm90IChldmFsID0gRkFMU0UgcHJldmVudHMgY29kZSBleGVjdXRpb24pLg0KLSBjYWNoZTogQ2FjaGUgdGhlIHJlc3VsdHMgb2YgdGhlIGNodW5rIHRvIHNwZWVkIHVwIHJlbmRlcmluZyAoY2FjaGUgPSBUUlVFIGVuYWJsZXMgY2FjaGluZykuDQotIGZpZy5jYXA6IEFkZCBhIGNhcHRpb24gdG8gZ3JhcGhpY2FsIG91dHB1dHMuDQotIG91dC53aWR0aC9vdXQuaGVpZ2h0OiBTZXQgdGhlIG91dHB1dCBzaXplIG9mIHBsb3RzLg0KLSBjb2xsYXBzZTogQ29uY2F0ZW5hdGUgdGV4dHVhbCBvdXRwdXQgaW50byBhIHNpbmdsZSBibG9jay4NCi0gdGlkeTogVGlkeSB1cCB0aGUgZGlzcGxheSBvZiBjb2RlIG9yIHJlc3VsdHMgKHRpZHkgPSBUUlVFIHRpZGllcyB0aGUgb3V0cHV0KS4NCi0tPg0KDQpgYGB7ciBwYWNrYWdlc19hbmRfbGlicmFyaWVzLCBldmFsPVRSVUV9DQoNCiMgTGlzdCBvZiBhbGwgcmVxdWlyZWQgbGlicmFyaWVzDQpyZXF1aXJlZF9saWJyYXJpZXMgPC0gYygiZ2dwbG90MiIsICJzdHJpbmdyIiwgInJlYWR4bCIsICJkcGx5ciIsICJsdWJyaWRhdGUiLCAiaG1zIiwgIm9wZW54bHN4IiwgIndyaXRleGwiLCAicm1hcmtkb3duIiwgImtuaXRyIiwgImthYmxlRXh0cmEiLCAiZ2duZXdzY2FsZSIsICJncmlkRXh0cmEiKQ0KDQojIGdncGxvdDIgICAgIGZvciAnZGVjbGFyYXRpdmVseScgY3JlYXRpbmcgZ3JhcGhpY3MsIGJhc2VkIG9uICJUaGUgR3JhbW1hciBvZiBHcmFwaGljcyIuIA0KIyBzdHJpbmdyICAgICBmb3Igd29ya2luZyB3aXRoIHN0cmluZ3MsIGkuZS4sIGNoYXJhY3RlciBkYXRhLg0KIyByZWFkeGwgICAgICBmb3IgcmVhZGluZyBFeGNlbCBmaWxlcyBieSBwcm92aWRpbmcgYSB3YXkgdG8gcmVhZCB4bHMgYW5kIHhsc3ggZmlsZXMgaW50byBSIHdpdGhvdXQgZGVwZW5kZW5jaWVzIG9uIGV4dGVybmFsIHNvZnR3YXJlLg0KIyBkcGx5ciAgICAgICBmb3IgZGF0YSBtYW5pcHVsYXRpb24sIHByb3ZpZGluZyBhIGNvbnNpc3RlbnQgc2V0IG9mIHZlcmJzIHRoYXQgaGVscCB5b3Ugc29sdmUgdGhlIG1vc3QgY29tbW9uIGRhdGEgbWFuaXB1bGF0aW9uIGNoYWxsZW5nZXMuDQojIGx1YnJpZGF0ZSAgIGZvciB3b3JraW5nIHdpdGggZGF0ZXMgYW5kIHRpbWVzIGluIFIuDQojIGhtcyAgICAgICAgIGZvciBzdG9yaW5nIHRpbWUtb2YtZGF5IHZhbHVlcyBhbmQgaW50ZXJmYWNpbmcgdGhlc2UgdmFsdWVzIHdpdGggYmFzZSBSJ3MgZGF0ZS10aW1lIGNsYXNzZXMuDQojIG9wZW54bHN4ICAgIGZvciByZWFkaW5nIGZyb20gYW5kIHdyaXRpbmcgdG8gTWljcm9zb2Z0IEV4Y2VsIC54bHN4IGZpbGVzLiBJdCBwcm92aWRlcyBtb3JlIGZ1bmN0aW9uYWxpdHkgdGhhbiBqdXN0IGhhbmRsaW5nIGRhdGE7IGl0IGFsc28gYWxsb3dzIHlvdSB0byBtb2RpZnkgdmFyaW91cyBhc3BlY3RzIG9mIHRoZSBFeGNlbCBmaWxlIGl0c2VsZi4NCiMgd3JpdGV4bCAgICAgZm9yIGEgZmFzdCBhbmQgcG9ydGFibGUgd2F5IHRvIHdyaXRlIGRhdGEgZnJhbWVzIHRvIEV4Y2VsIC54bHN4IGZpbGVzLCBmb2N1c2luZyBzb2xlbHkgb24gd3JpdGluZyBkYXRhIHdpdGhvdXQgYW55IGRlcGVuZGVuY2llcy4NCiMgcm1hcmtkb3duICAgZm9yIGR5bmFtaWMgcmVwb3J0IGdlbmVyYXRpb24gZnJvbSBSLiBJdCBpbnRlZ3JhdGVzIHRoZSBjb3JlIHN5bnRheCBvZiBtYXJrZG93biAoYSBzaW1wbGUgbWFya3VwIGxhbmd1YWdlKSB3aXRoIFIgY29kZSwgYWxsb3dpbmcgZm9yIHRoZSBhdXRvbWF0aWMgdXBkYXRlIG9mIHJlcG9ydHMgdG8gcmVmbGVjdCBkYXRhIGNoYW5nZXMgYW5kIGFuYWx5c2lzIHVwZGF0ZXMuDQojIGtuaXRyICAgICAgIGZvciB1c2luZyBmdW5jdGlvbnMgc3VjaCBhcyBrYWJsZSgpIHRvIGZvcm1hdCBkYXRhZnJhbWVzIGFzIG1hcmtkb3duIHRhYmxlcy4gDQojIGthYmxlRXh0cmEgIGZvciBlbmhhbmNlZCBmdW5jdGlvbmFsaXR5IGZvciBzdHlsaW5nIHRhYmxlcyBzdWNoIGFzIGRpc3BsYXlpbmcgY29sdW1ucyBldmVubHkNCiMgZ2duZXdzY2FsZSAgZm9yIGNyZWF0aW5nIG5ldyBjb2xvciBwYWxldHRlcyBhbmQgbW9yZQ0KIyBncmlkRXh0cmENCg0KIyBDaGVjayB3aGljaCBsaWJyYXJpZXMgYXJlIG5vdCBpbnN0YWxsZWQNCmluc3RhbGxlZF9saWJzIDwtIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKQ0KbGlicmFyaWVzX3RvX2luc3RhbGwgPC0gcmVxdWlyZWRfbGlicmFyaWVzWyFyZXF1aXJlZF9saWJyYXJpZXMgJWluJSBpbnN0YWxsZWRfbGlic10NCg0KIyBJbnN0YWxsIG1pc3NpbmcgbGlicmFyaWVzDQppZihsZW5ndGgobGlicmFyaWVzX3RvX2luc3RhbGwpID4gMCkgew0KICBpbnN0YWxsLnBhY2thZ2VzKGxpYnJhcmllc190b19pbnN0YWxsKQ0KfQ0KDQojIExvYWQgYWxsIHJlcXVpcmVkIGxpYnJhcmllcw0KbGFwcGx5KHJlcXVpcmVkX2xpYnJhcmllcywgbGlicmFyeSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KYGBgDQoNCg0KIyBUQUJMRSBPRiBDT05URU5UUw0KVXRpbGl6ZSB0aGUgVGFibGUgb2YgQ29udGVudHMgKFRPQykgbWVudSBvbiB0aGUgbGVmdCB0byBzY3JvbGwgdGhyb3VnaCB0aGUgZGlmZmVyZW50IHNlY3Rpb25zIGFuZCBoZWxwIG5hdmlnYXRlIHRoaXMgcmVwb3J0LiBZb3UgY2FuIGNsaWNrIG9uIHRoZSB0aXRsZSB0byBnbyBkaXJlY3RseSB0byB0aGUgc2VjdGlvbi4NCg0KSWYgeW91J3JlIHZpZXdpbmcgdGhlIFBERiB2ZXJzaW9uLCB0aGUgVGFibGUgb2YgQ29udGVudHMgc3RheXMgYXQgdGhlIHRvcCBvZiB0aGlzIHJlcG9ydC4gVG8gZ28gZGlyZWN0bHkgdG8gYSBzZWN0aW9uLCBjb3B5IGFuZCBwYXN0ZSB0aGUgdGl0bGUgaW50byB0aGUgc2VhcmNoIGJveC4gVXNlIHRoZSBmb2xsb3dpbmcgc2hvcnRjdXQga2V5cyB0byBoZWxwIG5hdmlnYXRlIHdpdGggZWFzZToNCg0KU2hvcnRjdXQgS2V5czoNCg0KLSBIb2xkIGBDdHJsYCBhbmQgcHJlc3MgdGhlIGBIb21lYCBrZXkgdG8gZ28gdG8gdGhlIHRvcCBvZiB0aGUgcGFnZS4NCi0gSG9sZCBgQ3RybGAgYW5kIHByZXNzIHRoZSBgRW5kYCBrZXkgdG8gZ28gdG8gdGhlIGJvdHRvbSBvZiB0aGUgcGFnZS4NCi0gSG9sZCBgQ3RybGAgYW5kIHByZXNzIHRoZSBgRmAga2V5IHRvIHNlYXJjaCBmb3Igc3BlY2lmaWMgdGV4dCBvciBzdHJpbmdzIG9mIHRleHQuDQotIFByZXNzIHRoZSBgRXNjYCBrZXkgdG8gcXVpY2tseSBleGl0IHRoZSBzZWFyY2ggYm94Lg0KDQojIyBBYm91dCBUaGlzIFJlcG9ydCANCg0KVGhpcyByZXBvcnQgaXMgcHVibGlzaGVkIG9uIFJQdWJzW14xXS4gS0RGIHN0YW5kcyBmb3IgS2VuIERvZXMgRml0bmVzcy4gUmVmZXIgdG8gUmVmZXJlbmNlcyBhdCB0aGUgYm90dG9tIG9mIHRoaXMgcGFnZSBmb3IgY2l0ZWQgc291cmNlcy4gVGhlIFJNRCBmaWxlIHRvIHByb2R1Y2UgdGhpcyByZXBvcnQsIGFuZCBzb21lIG9mIHRoZSBmaWd1cmVzIGZyb20gdGhpcyByZXBvcnQsIG1heSBiZSBmb3VuZCBpbiB0aGUgR29vZ2xlIERyaXZlIGZvbGRlciBbXjJdLiANCg0KVGhpcyByZXBvcnQgc3lzdGVtYXRpY2FsbHkgcmVjb3JkcyBhbmQgYW5hbHl6ZXMgd29ya291dCBzdGF0aXN0aWNzIHRvIGVuaGFuY2UgaW5kaXZpZHVhbCBhbmQgY29sbGVjdGl2ZSBwZXJmb3JtYW5jZSBieSBhY2hpZXZpbmcgdGhlIGZvbGxvd2luZyBnb2FsczoNCg0KLSBUcmFjayBhbmQgSW1wcm92ZSBQZXJmb3JtYW5jZSAtIFJlZ3VsYXJseSBtZWFzdXJpbmcgd29ya291dCBzdGF0aXN0aWNzIGhlbHBzIGluZGl2aWR1YWxzIG1vbml0b3IgcHJvZ3Jlc3MsIHNldCByZWFsaXN0aWMgZ29hbHMsIGFuZCB0YWlsb3IgdHJhaW5pbmcgcGxhbnMgZm9yIG9wdGltYWwgcmVzdWx0cy4NCi0gSW5mb3JtZWQgRGVjaXNpb24gTWFraW5nIC0gRGV0YWlsZWQgZGF0YSBhbmFseXNpcyBhbGxvd3MgZm9yIHBlcnNvbmFsaXplZCBhZGp1c3RtZW50cyBpbiB0cmFpbmluZyBsb2FkcywgcmVkdWNpbmcgdGhlIHJpc2sgb2YgaW5qdXJ5IGFuZCBlbmhhbmNpbmcgb3ZlcmFsbCBwZXJmb3JtYW5jZS4NCi0gRm9zdGVyIEhlYWx0aHkgQ29tcGV0aXRpb24gLSBDb21wYXJpbmcgcGVyc29uYWwgcGVyZm9ybWFuY2Ugb3ZlciB0aW1lIGFuZCB3aXRoIHBlZXJzIGNyZWF0ZXMgYSBtb3RpdmF0aW5nIGFuZCBjb21wZXRpdGl2ZSBlbnZpcm9ubWVudCB0aGF0IGVuY291cmFnZXMgY29udGludW91cyBpbXByb3ZlbWVudC4NCi0gRGF0YS1Ecml2ZW4gSW5zaWdodHMgLSBJZGVudGlmeWluZyB0cmVuZHMgYW5kIHBhdHRlcm5zIGluIHBlcmZvcm1hbmNlIG1ldHJpY3MgaGVscHMgYXRobGV0ZXMgbWFrZSBpbmZvcm1lZCBhZGp1c3RtZW50cyB0byB0aGVpciB0cmFpbmluZyBmb3Igc3VzdGFpbmVkIGltcHJvdmVtZW50IGFuZCBpbmp1cnkgcHJldmVudGlvbi4NCg0KYGBge3IgcmVwb3J0c19wbmMsIGV2YWw9VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcw0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KIyBEZWZpbmUgdGhlIHByb3MgYW5kIGNvbnMgYXMgbGlzdHMNCnByb3MgPC0gYygiRW5oYW5jZWQgcGVyZm9ybWFuY2UgdHJhY2tpbmc6IEhlbHBzIG1vbml0b3IgcHJvZ3Jlc3MgYW5kIGlkZW50aWZ5IHN0cmVuZ3RocyBhbmQgd2Vha25lc3Nlcy4iLA0KICAgICAgICAgICJNb3RpdmF0aW9uIGFuZCBhY2NvdW50YWJpbGl0eTogU2V0cyBjbGVhciBiZW5jaG1hcmtzIGFuZCBnb2FscywgYm9vc3RpbmcgbW90aXZhdGlvbi4iLA0KICAgICAgICAgICJEYXRhLWRyaXZlbiBkZWNpc2lvbiBtYWtpbmc6IEluZm9ybXMgYmV0dGVyIHRyYWluaW5nIGNob2ljZXMgYmFzZWQgb24gZGF0YSBhbmFseXNpcy4iLA0KICAgICAgICAgICJGYWNpbGl0YXRlcyBjb21wYXJpc29uIGFuZCBjb21wZXRpdGlvbjogRW5jb3VyYWdlcyBoZWFsdGh5IGNvbXBldGl0aW9uIGFuZCBzZWxmLWltcHJvdmVtZW50LiIpDQoNCg0KY29ucyA8LSBjKCJSZXNvdXJjZSBpbnRlbnNpdmU6IFJlcXVpcmVzIHRpbWUgYW5kIGVmZm9ydCBmb3IgYWNjdXJhdGUgZGF0YSBlbnRyeSBhbmQgbWFpbnRlbmFuY2UuIiwNCiAgICAgICAgICAiUG90ZW50aWFsIGZvciBtaXNpbnRlcnByZXRhdGlvbjogSW5jb3JyZWN0IGRhdGEgYW5hbHlzaXMgY2FuIGxlYWQgdG8gd3JvbmcgY29uY2x1c2lvbnMuIiwNCiAgICAgICAgICAiUHJpdmFjeSBjb25jZXJuczogUmlza3Mgb2YgaGFuZGxpbmcgcGVyc29uYWwgcGVyZm9ybWFuY2UgZGF0YSBpbnNlY3VyZWx5LiIsDQogICAgICAgICAgIkVtcGhhc2lzIG9uIHF1YW50aXRhdGl2ZSBtZXRyaWNzOiBNYXkgb3Zlcmxvb2sgcXVhbGl0YXRpdmUgYXNwZWN0cyBsaWtlIG1lbnRhbCB3ZWxsLWJlaW5nIGFuZCBlbmpveW1lbnQuIikNCg0KIyBDb21iaW5lIHRoZSBwcm9zIGFuZCBjb25zIGludG8gYSBkYXRhIGZyYW1lDQpyZXBvcnRzX3BuYyA8LSBkYXRhLmZyYW1lKA0KICBQcm9zID0gcHJvcywNCiAgQ29ucyA9IGNvbnMsDQogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQ0KKQ0KDQojIFByaW50IHRoZSB0YWJsZSB1c2luZyBrYWJsZSBhbmQga2FibGVFeHRyYQ0Ka2FibGUocmVwb3J0c19wbmMsIGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRkFMU0UsIGNvbC5uYW1lcyA9IGMoIlByb3MiLCAiQ29ucyIpKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IFRSVUUpICU+JQ0KICBjb2x1bW5fc3BlYygxLCB3aWR0aCA9ICI1MCUiKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSAiNTAlIikNCg0KYGBgDQoNCkZvcm1hdHRpbmcgLSBUaGlzIHJlcG9ydCBpcyBpbml0aWFsbHkgcHJpbnRlZCBhcyBvbmUgY29udGludW91cyBwYWdlIGluIEhUTUwgZm9ybWF0IGFuZCBtYXkgYXBwZWFyIGRpZmZlcmVudGx5IHdoZW4gdmlld2VkIGluIFBERiBmb3JtYXQuDQoNClRlcm1pbm9sb2d5IC0gVGhlIHRlcm1zIGFjdGl2aXR5LCB3b3Jrb3V0LCBhbmQgZXhlcmNpc2UgbWF5IGJlIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IGluIHRoaXMgY29udGV4dCwgZXZlbiB0aG91Z2ggdGhleSBoYXZlIGRpc3RpbmN0IG1lYW5pbmdzLg0KDQpEYXRhIEFzc3VtcHRpb25zIC0gVGhlIGRhdGEgdXNlZCBmb3IgYW5hbHlzZXMgYXNzdW1lcyBlYWNoIHNldCBvZiBleGVyY2lzZSBpcyBwZXJmb3JtZWQgdG8gUmVwIE1heCAoUk0pLCB3aGljaCBpc24ndCBhbHdheXMgdGhlIGNhc2UsIHBhcnRpY3VsYXJseSBpZiB0aGUgaW5kaXZpZHVhbCBpc24ndCBhaW1pbmcgdG8gcGVyZm9ybSB0aGUgc2V0IHRvIFJNLiBBc3N1bWluZyBlYWNoIHNldCBvZiBleGVyY2lzZSBpcyBwZXJmb3JtZWQgdG8gUmVwIE1heCBoZWxwcyBzdGFuZGFyZGl6ZSBkYXRhIGFuZCBwcm92aWRlIGNsZWFyIGluc2lnaHRzIGludG8gbWF4aW1hbCBzdHJlbmd0aCwgd2hpY2ggaXMgYmVuZWZpY2lhbCBmb3IgYmVuY2htYXJraW5nIGFuZCB0cmFja2luZyBwcm9ncmVzcy4gSG93ZXZlciwgaXQgY2FuIGFsc28gbGVhZCB0byBpbmFjY3VyYWNpZXMsIHBvdGVudGlhbCBvdmVydHJhaW5pbmcsIGFuZCBtaXNsZWFkaW5nIGRhdGEgaWYgbm90IGFsbCBleGVyY2lzZXMgYXJlIHBlcmZvcm1lZCB0byBmYWlsdXJlLiBCYWxhbmNpbmcgdGhlIHVzZSBvZiAxUk0gYXNzdW1wdGlvbnMgd2l0aCByZWFsaXN0aWMgdHJhaW5pbmcgcHJhY3RpY2VzIGlzIGVzc2VudGlhbCBmb3IgYWNjdXJhdGUgcGVyZm9ybWFuY2UgYXNzZXNzbWVudCBhbmQgZWZmZWN0aXZlIHRyYWluaW5nIHByb2dyYW1taW5nLg0KDQo8IS0tIExpbmtzIHdpbGwgYXBwZWFyIGJhY2sgdG8gYmFjaywgdHdpY2UgaW4gYSByb3cgd2hlbiBIVE1MIGZvcm1hdCBpcyBTYXZlZCBBcyBQREYuIC0tPg0KDQo8IS0tIEV4cGxhaW4gdGhlIG9yaWdpbiBhbmQgZGV2ZWxvcG1lbnQgcHJvY2VzcyBvZiB0aGlzIHJlcG9ydCwgZm9yIHByb3NwZWN0aXZlIGVtcGxveWVycyAtLT4NCg0KIyBTVFJFTkdUSCBTVEFOREFSRFMNCg0KU3RyZW5ndGggU3RhbmRhcmRzIHByb3ZpZGUgdmFsdWFibGUgYmVuY2htYXJrcyBmb3IgYXNzZXNzaW5nIGFuIGluZGl2aWR1YWwncyBwZXJmb3JtYW5jZSBpbiBrZXkgc3RyZW5ndGggZXhlcmNpc2VzIHRoYXQgYXJlIHdpZGVseSBwcmFjdGljZWQgaW4gZml0bmVzcyBhbmQgc3RyZW5ndGggdHJhaW5pbmcuIFRoZXNlIHN0YW5kYXJkcyBjYXRlZ29yaXplIHBlcmZvcm1hbmNlIGxldmVscyBiYXNlZCBvbiBlaXRoZXIgYW1vdW50IG9mIHdlaWdodCBleGVjdXRlZCByZWxhdGl2ZSB0byBib2R5d2VpZ2h0LCBvciByZXBldGl0aW9ucyBleGVjdXRlZCwgYW5kIGFyZSBzZWdtZW50ZWQgYnkgZ2VuZGVyIGFuZCBleHBlcmllbmNlIGxldmVscy4gQnkgY29tcGFyaW5nIGFuIGluZGl2aWR1YWwncyBwZXJmb3JtYW5jZSBhZ2FpbnN0IHRoZXNlIGVzdGFibGlzaGVkIHN0YW5kYXJkcywgdHJhaW5lcnMgYW5kIGF0aGxldGVzIGNhbiBpZGVudGlmeSBzdHJlbmd0aHMgYW5kIHdlYWtuZXNzZXMgaW4gdGhlaXIgdHJhaW5pbmcgcmVnaW1lbnMsIHNldCByZWFsaXN0aWMgZ29hbHMsIGFuZCBtZWFzdXJlIHByb2dyZXNzIGluIGEgc3RydWN0dXJlZCBtYW5uZXIuDQoNCiMjIFN0cmVuZ3RoIFN0YW5kYXJkcyBPdmVydmlldyANCg0KU2V2ZXJhbCBzdHJlbmd0aCBzdGFuZGFyZHMgYXJlIHJlYWRpbHkgYXZhaWxhYmxlIG9ubGluZToNCg0KLSBFeFJ4IFN0cmVuZ3RoIFN0YW5kYXJkczogPGh0dHBzOi8vZXhyeC5uZXQvVGVzdGluZy9XZWlnaHRMaWZ0aW5nL1N0cmVuZ3RoU3RhbmRhcmRzPg0KLSBTdHJlbmd0aExldmVsLmNvbSBTdHJlbmd0aCBTdGFuZGFyZHM6IDxodHRwczovL3N0cmVuZ3RobGV2ZWwuY29tL3N0cmVuZ3RoLXN0YW5kYXJkcz4NCi0gU3ltbWV0cmljIFN0cmVuZ3RoOiA8aHR0cHM6Ly9zeW1tZXRyaWNzdHJlbmd0aC5jb20vPg0KLSBNYXJrIFJpcHBldG9lJ3MgU3RyZW5ndGggU3RhbmRhcmRzOiA8aHR0cHM6Ly9zdGFydGluZ3N0cmVuZ3RoLmNvbS9maWxlcy9zdGFuZGFyZHMucGRmPg0KDQpGaW5kaW5nIGFjY3VyYXRlIHN0cmVuZ3RoIHN0YW5kYXJkcyBkZXBlbmRzIG9uIHRoZSBkZW1vZ3JhcGhpYywgZXhlcmNpc2UgdHlwZSwgYW5kIHJlcXVpcmVkIGFjY3VyYWN5LiBFYWNoIGhhcyBpdHMgcHJvcyBhbmQgY29uczogc29tZSBjYXRlciB0byBzcGVjaWZpYyBkZW1vZ3JhcGhpY3MsIG90aGVycyBmb2N1cyBvbiBjZXJ0YWluIGV4ZXJjaXNlcywgYW5kIHRoZWlyIGNyZWRpYmlsaXR5IGFmZmVjdHMgcmVsaWFiaWxpdHkuIFVzYWJpbGl0eSBhbmQgY29tcHJlaGVuc2l2ZSBkYXRhIGZvciBiZW5jaG1hcmtpbmcgYXJlIGNydWNpYWwsIGFzIGFyZSByZWd1bGFyIHVwZGF0ZXMgdG8gcmVmbGVjdCBjdXJyZW50IHRyZW5kcy4gQ29uc2lkZXJpbmcgdGhlc2UgZmFjdG9ycyBoZWxwcyB0cmFpbmVycyBhbmQgYXRobGV0ZXMgY2hvb3NlIHRoZSBiZXN0IHN0YW5kYXJkcyBmb3IgYXNzZXNzaW5nIGFuZCBpbXByb3ZpbmcgcGVyZm9ybWFuY2UuDQoNCmBgYHtyIHN0cmVuZ3RoX3N0YW5kYXJkc19wbmMsIGV2YWw9VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcw0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KIyBEZWZpbmUgdGhlIHByb3MgYW5kIGNvbnMgYXMgbGlzdHMNCnByb3MgPC0gYygiQmVuY2htYXJraW5nOiBTdHJlbmd0aCBzdGFuZGFyZHMgcHJvdmlkZSBjbGVhciBiZW5jaG1hcmtzIHRvIG1lYXN1cmUgcHJvZ3Jlc3MgYW5kIHNldCBnb2Fscy4iLA0KICAgICAgICAgICJNb3RpdmF0aW9uOiBTZWVpbmcgaG93IHlvdXIgcGVyZm9ybWFuY2Ugc3RhY2tzIHVwIGFnYWluc3QgZXN0YWJsaXNoZWQgc3RhbmRhcmRzIGNhbiBiZSBoaWdobHkgbW90aXZhdGluZy4iLA0KICAgICAgICAgICJHdWlkYW5jZTogVGhleSBvZmZlciBndWlkYW5jZSBvbiB3aGF0IGlzIGNvbnNpZGVyZWQgc3Ryb25nIG9yIHdlYWsgZm9yIGRpZmZlcmVudCBleGVyY2lzZXMsIGhlbHBpbmcgeW91IHRhaWxvciB5b3VyIHRyYWluaW5nIGFjY29yZGluZ2x5LiIsDQogICAgICAgICAgIkNvbXBhcmlzb246IFRoZXkgYWxsb3cgZm9yIG1lYW5pbmdmdWwgY29tcGFyaXNvbnMgYmV0d2VlbiBpbmRpdmlkdWFscywgaGVscGluZyB0byBpZGVudGlmeSBzdHJlbmd0aHMgYW5kIHdlYWtuZXNzZXMuIiwNCiAgICAgICAgICAiU3RydWN0dXJlZCBUcmFpbmluZzogU3RyZW5ndGggc3RhbmRhcmRzIGNhbiBoZWxwIGluIGRlc2lnbmluZyBtb3JlIHN0cnVjdHVyZWQgYW5kIGVmZmVjdGl2ZSB0cmFpbmluZyBwcm9ncmFtcy4iKQ0KDQpjb25zIDwtIGMoIkdlbmVyaWM6IFN0cmVuZ3RoIHN0YW5kYXJkcyBjYW4gYmUgdG9vIGdlbmVyaWMgYW5kIG1heSBub3QgYWNjb3VudCBmb3IgaW5kaXZpZHVhbCBkaWZmZXJlbmNlcyBpbiBnZW5ldGljcywgYm9keSBjb21wb3NpdGlvbiwgYW5kIHRyYWluaW5nIGhpc3RvcnkuIiwNCiAgICAgICAgICAiUHJlc3N1cmU6IFRoZXkgY2FuIGNyZWF0ZSB1bmR1ZSBwcmVzc3VyZSB0byBtZWV0IGNlcnRhaW4gYmVuY2htYXJrcywgcG90ZW50aWFsbHkgbGVhZGluZyB0byBpbmp1cnkgb3IgYnVybm91dC4iLA0KICAgICAgICAgICJPdXRkYXRlZCBJbmZvcm1hdGlvbjogU29tZSBzdGFuZGFyZHMgbWF5IGJlIGJhc2VkIG9uIG91dGRhdGVkIGluZm9ybWF0aW9uIG9yIG5vdCByZWZsZWN0IHJlY2VudCBhZHZhbmNlbWVudHMgaW4gc3BvcnRzIHNjaWVuY2UuIiwNCiAgICAgICAgICAiTm90IENvbXByZWhlbnNpdmU6IFRoZXkgbWlnaHQgbm90IGNvdmVyIGFsbCBleGVyY2lzZXMgb3IgYWNjb3VudCBmb3IgZGlmZmVyZW50IHRyYWluaW5nIGdvYWxzLCBzdWNoIGFzIGh5cGVydHJvcGh5IHZlcnN1cyBzdHJlbmd0aC4iLA0KICAgICAgICAgICJNaXNsZWFkaW5nOiBGb3IgYmVnaW5uZXJzLCBzdHJlbmd0aCBzdGFuZGFyZHMgY2FuIGJlIG1pc2xlYWRpbmcgaWYgdGhleSBkb27igJl0IGFjY291bnQgZm9yIHRoZSBzdGFydGluZyBwb2ludCBvciByYXRlIG9mIHByb2dyZXNzIGFwcHJvcHJpYXRlIGZvciBkaWZmZXJlbnQgZml0bmVzcyBsZXZlbHMuIikNCg0KIyBDb21iaW5lIHRoZSBwcm9zIGFuZCBjb25zIGludG8gYSBkYXRhIGZyYW1lDQpzdHJlbmd0aF9zdGFuZGFyZHNfcG5jIDwtIGRhdGEuZnJhbWUoDQogIFByb3MgPSBwcm9zLA0KICBDb25zID0gY29ucywNCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFDQopDQoNCiMgUHJpbnQgdGhlIHRhYmxlIHVzaW5nIGthYmxlIGFuZCBrYWJsZUV4dHJhDQprYWJsZShzdHJlbmd0aF9zdGFuZGFyZHNfcG5jLCBmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEZBTFNFLCBjb2wubmFtZXMgPSBjKCJQcm9zIiwgIkNvbnMiKSkgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiNTAlIikgJT4lDQogIGNvbHVtbl9zcGVjKDIsIHdpZHRoID0gIjUwJSIpDQoNCmBgYA0KSSd2ZSBjb21waWxlZCBzb21lIG9mIHRoZSBzdGFuZGFyZHMgaW50byBhbiBFeGNlbCBmaWxlW14zXS4gVGhpcyBhbGxvd3MgZm9yIGNvbXBhcmlzb24gYmV0d2VlbiBwZXJzb25hbCBwZXJmb3JtYW5jZSBtZWFzdXJlcyBhbmQgdGhlIHNwZWNpZmllZCBzdHJlbmd0aCBzdGFuZGFyZHMuIEkgcmVjb21tZW5kIGNvbnN1bHRpbmcgZWFjaCBzb3VyY2UgZm9yIGNvbmZpcm1hdGlvbiBvbiB0aGUgbGF0ZXN0IHZlcnNpb24sIGFzIHRoZSBzdHJ1Y3R1cmUgb3IgbnVtYmVycyBtYXkgaGF2ZSBjaGFuZ2VkIG92ZXIgdGltZS4gDQoNCmBgYHtyIHJlYWRfc3RyZW5ndGhfc3RhbmRhcmRzLCBldmFsPVRSVUV9DQoNCiMgRmlsZSBQYXRoIERlZmluaXRpb246IFRoZSBzY3JpcHQgZGVmaW5lcyBhIHBhdGggdG8gYW4gRXhjZWwgZmlsZSBjb250YWluaW5nICJTdHJlbmd0aCBTdGFuZGFyZHMiLg0KZmlsZV9wYXRoX3N0cmVuZ3RoX3N0YW5kYXJkcyA8LSAiQzovL1VzZXJzLy9rZW5kci8vT25lRHJpdmUvL0RvY3VtZW50cy8vRGF0YSBBbmFseXRpY3MvL0tlbkRvZXNGaXRuZXNzL1N0cmVuZ3RoIFN0YW5kYXJkcyBGaW5hbC54bHNtIg0KDQojIFdvcmtib29rIExvYWRpbmc6IExvYWRzIHRoZSBFeGNlbCB3b3JrYm9vayBpbnRvIFIgdXNpbmcgdGhlIG9wZW54bHN4IHBhY2thZ2UsIHdoaWNoIHByb3ZpZGVzIG1vcmUgYWR2YW5jZWQgY29udHJvbCBvdmVyIEV4Y2VsIGZpbGVzIHRoYW4gcmVhZHhsLg0Kc3RyZW5ndGhfc3RhbmRhcmRzIDwtIGxvYWRXb3JrYm9vayhmaWxlX3BhdGhfc3RyZW5ndGhfc3RhbmRhcmRzKQ0KYGBgDQoNCiMjIFN0YW5kYXJkcyBDYXRlZ29yaWVzICANClRoZSBzdGFuZGFyZHMgY29tcGlsZWQgYXJlIHNlcGFyYXRlZCBpbnRvIGNhdGVnb3JpZXMsIGFzIHNob3duIGluIHRoZSBmb2xsb3dpbmcgdGFibGUsIG1ha2luZyBpdCBlYXN5IHRvIGRldGVybWluZSB3aGljaCBleGVyY2lzZSB0byB1c2UgYXMgYSBiZW5jaG1hcmsuDQoNCmBgYHtyIHN0cmVuZ3RoX3N0YW5kYXJkc19zaGVldF9uYW1lcywgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIFNoZWV0IE5hbWVzIERpc3BsYXk6IFJldHJpZXZlcyBhbmQgZGlzcGxheXMgdGhlIG5hbWVzIG9mIHNoZWV0cyB3aXRoaW4gdGhlIEV4Y2VsIHdvcmtib29rIHRvIGhlbHAgaWRlbnRpZnkgYXZhaWxhYmxlIGRhdGEuDQoNCiMgQ2hlY2sgdG8gY29uZmlybSB3aGljaCBudW1iZXIgb2YgbmFtZXMgdG8gZGlzcGxheQ0KIyBuYW1lcyhzdHJlbmd0aF9zdGFuZGFyZHMpDQoNCiMgRGlzcGxheSBzcGVjaWZpYyBlbGVtZW50cyBmcm9tIHRoZSBzdHJlbmd0aF9zdGFuZGFyZHMgb2JqZWN0IHdpdGggSW5kZXhpbmcNCm5hbWVzX3N1YnNldF9zdHJlbmd0aF9zdGFuZGFyZHMgPC0gbmFtZXMoc3RyZW5ndGhfc3RhbmRhcmRzKVs0OjE1XQ0KbmFtZXNfc3Vic2V0X3N0cmVuZ3RoX3N0YW5kYXJkc19nc3ViID0gZ3N1YigiXyIsIiAiLCBuYW1lc19zdWJzZXRfc3RyZW5ndGhfc3RhbmRhcmRzKQ0KIyBuYW1lc19zdWJzZXRfc3RyZW5ndGhfc3RhbmRhcmRzDQoNCiMgQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgbmFtZXMNCm51bV9uYW1lcyA8LSBsZW5ndGgobmFtZXNfc3Vic2V0X3N0cmVuZ3RoX3N0YW5kYXJkc19nc3ViKQ0KDQojIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIG5hbWVzIHBlciBjb2x1bW4NCm5hbWVzX3Blcl9jb2x1bW4gPC0gY2VpbGluZyhudW1fbmFtZXMgLyAyKQ0KDQojIFNwbGl0IHRoZSBuYW1lcyBpbnRvIHR3byBjb2x1bW5zDQpjb2x1bW5fMSA8LSBuYW1lc19zdWJzZXRfc3RyZW5ndGhfc3RhbmRhcmRzX2dzdWJbMTptaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKV0NCmNvbHVtbl8yIDwtIG5hbWVzX3N1YnNldF9zdHJlbmd0aF9zdGFuZGFyZHNfZ3N1YlsobWluKG5hbWVzX3Blcl9jb2x1bW4sIG51bV9uYW1lcykgKyAxKTpudW1fbmFtZXNdDQoNCiMgUGFkIHRoZSBzaG9ydGVyIGNvbHVtbiB3aXRoIE5BIHZhbHVlcyBpZiBuZWNlc3NhcnkNCmlmKGxlbmd0aChjb2x1bW5fMSkgPCBsZW5ndGgoY29sdW1uXzIpKSB7DQogIGNvbHVtbl8xIDwtIGMoY29sdW1uXzEsIHJlcCgiIiwgbGVuZ3RoKGNvbHVtbl8yKSAtIGxlbmd0aChjb2x1bW5fMSkpKQ0KfSBlbHNlIGlmKGxlbmd0aChjb2x1bW5fMikgPCBsZW5ndGgoY29sdW1uXzEpKSB7DQogIGNvbHVtbl8yIDwtIGMoY29sdW1uXzIsIHJlcCgiIiwgbGVuZ3RoKGNvbHVtbl8xKSAtIGxlbmd0aChjb2x1bW5fMikpKQ0KfQ0KICANCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHR3byBjb2x1bW5zDQpuYW1lc19zdWJzZXRfc3RyZW5ndGhfc3RhbmRhcmRzX2dzdWJfZGYgPC0gZGF0YS5mcmFtZShDb2x1bW5fMSA9IGNvbHVtbl8xLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uXzIgPSBjb2x1bW5fMikNCg0KIyBDYWxjdWxhdGUgdGhlIHdpZHRoIGR5bmFtaWNhbGx5DQpjb2xfd2lkdGggPC0gcGFzdGUwKDEwMCAvIG5jb2wobmFtZXNfc3Vic2V0X3N0cmVuZ3RoX3N0YW5kYXJkc19nc3ViX2RmKSwgIiUiKQ0KDQojIFByaW50IHRoZSBkYXRhIGZyYW1lIHVzaW5nIGtuaXRyOjprYWJsZQ0Ka25pdHI6OmthYmxlKG5hbWVzX3N1YnNldF9zdHJlbmd0aF9zdGFuZGFyZHNfZ3N1Yl9kZiwgZm9ybWF0ID0gIm1hcmtkb3duIiwgY29sLm5hbWVzID0gYygiQ2F0ZWdvcmllcyIsICJDYXRlZ29yaWVzIikpICU+JQ0KICBjb2x1bW5fc3BlYygxOjIsIHdpZHRoID0gY29sX3dpZHRoLCBleHRyYV9jc3MgPSAidGV4dC1hbGlnbjogbGVmdDsiKQ0KDQpgYGANCg0KDQojIyBTdHJlbmd0aCBTdGFuZGFyZHMgTGlzdCANCkJlbG93IGlzIHRoZSBsaXN0IG9mIFN0cmVuZ3RoIFN0YW5kYXJkcyBjb21waWxlZCBpbnRvIHRoZSBTUyBFeGNlbCBmaWxlW14zXS4gVGhpcyBmaWxlIHJlZmVyZW5jZXMgdGhlIHNvdXJjZSBvZiBlYWNoIHN0YW5kYXJkIHRhYmxlLiBXZSdsbCBkZWx2ZSBpbnRvIE1hcmsgUmlwcGV0b2UncyBTdGFydGluZyBTdHJlbmd0aCBTdGFuZGFyZHMsIGFzIGhpcyBhbmQgaGlzIGNvbGxlYWd1ZXMnIG1ldGhvZHMgYW5kIHJlc2VhcmNoIGFyZSBiYXNlZCBvbiBjb21wcmVoZW5zaXZlIGFuZCB0ZWNobmljYWwgaW5mb3JtYXRpb24uDQoNCmBgYHtyIG5hbWVkX3JhbmdlcywgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQpsaWJyYXJ5KG9wZW54bHN4KQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojIFJlYWQgTmFtZWQgUmFuZ2VzOiBSZWFkcyBhIHNwZWNpZmljIHNoZWV0IG5hbWVkICJOYW1lZF9SYW5nZXMiIHRoYXQgcHJlc3VtYWJseSBjb250YWlucyBtZXRhZGF0YSBhYm91dCBvdGhlciBuYW1lZCByYW5nZXMgaW4gdGhlIHdvcmtib29rLiBJdCBrZWVwcyBvbmx5IHRoZSBjb2x1bW5zIHJlbGF0ZWQgdG8gbmFtZWQgcmFuZ2VzIGFuZCB0aGVpciByZXNwZWN0aXZlIHNoZWV0cy4NCm5hbWVkX3JhbmdlcyA8LSByZWFkX2V4Y2VsKGZpbGVfcGF0aF9zdHJlbmd0aF9zdGFuZGFyZHMsIHNoZWV0ID0gIk5hbWVkX1JhbmdlcyIpDQpzaGVldF9uYW1lc19maWx0ZXJlZCA8LSB1bmlxdWUobmFtZWRfcmFuZ2VzJGBDYXRlZ29yeSBTaGVldGApDQpuYW1lZF9yYW5nZXMgPC0gbmFtZWRfcmFuZ2VzW25hbWVkX3JhbmdlcyRgQ2F0ZWdvcnkgU2hlZXRgICVpbiUgc2hlZXRfbmFtZXNfZmlsdGVyZWQsIGMoIlN0cmVuZ3RoIFN0YW5kYXJkIiwgIkNhdGVnb3J5IFNoZWV0IildDQoNCiMgRGlzcGxheSB0aGUgbW9kaWZpZWQgJ1N0cmVuZ3RoIFN0YW5kYXJkJyBjb2x1bW4gd2l0aCBzcGFjZXMgaW5zdGVhZCBvZiB1bmRlcnNjb3Jlcw0Kc3RyZW5ndGhfc3RhbmRhcmRzX2xpc3RfZGlzcGxheSA8LSBuYW1lZF9yYW5nZXMgJT4lDQogIG11dGF0ZShgU3RyZW5ndGggU3RhbmRhcmRgID0gZ3N1YigiXyIsICIgIiwgYFN0cmVuZ3RoIFN0YW5kYXJkYCkpICU+JQ0KICBtdXRhdGUoYENhdGVnb3J5IE5hbWVgID0gZ3N1YigiXyIsICIgIiwgYENhdGVnb3J5IFNoZWV0YCkpICU+JQ0KICBzZWxlY3QoLWBDYXRlZ29yeSBTaGVldGApICAjIFRoaXMgZXhjbHVkZXMgdGhlICdDYXRlZ29yeSBTaGVldCcgY29sdW1uDQoNCiMgVmlldyB0aGUgZGF0YSBmcmFtZSBpZiBuZWVkZWQgKG5vdCBkdXJpbmcga25pdHRpbmcpLiBWaWV3IGZ1bmN0aW9uIG9wZW5zIHRoZSByYXdfZGF0YSBkYXRhZnJhbWUgaW4gdGhlIFJTdHVkaW8gZGF0YSB2aWV3ZXIgZm9yIGludGVyYWN0aXZlIGV4cGxvcmF0aW9uLg0KVmlldyhuYW1lZF9yYW5nZXMpDQpWaWV3KHN0cmVuZ3RoX3N0YW5kYXJkc19saXN0X2Rpc3BsYXkpDQoNCiMgRGVmaW5lIHRoZSByYXRpb3MgYW5kIHRvdGFsIHdpZHRoIGZvciBjb2x1bW4gd2lkdGhzDQp0b3RhbF93aWR0aCA8LSAxMDANCnJhdGlvX3N0cmVuZ3RoX3N0YW5kYXJkcyA8LSAyDQpyYXRpb19jYXRlZ29yeSA8LSAxLjI1DQp0b3RhbF9yYXRpbyA8LSByYXRpb19zdHJlbmd0aF9zdGFuZGFyZHMgKyByYXRpb19jYXRlZ29yeQ0KDQojIENhbGN1bGF0ZSB0aGUgY29sdW1uIHdpZHRocw0Kd2lkdGhfc3RyZW5ndGhfc3RhbmRhcmRzIDwtIChyYXRpb19zdHJlbmd0aF9zdGFuZGFyZHMgLyB0b3RhbF9yYXRpbykgKiB0b3RhbF93aWR0aA0Kd2lkdGhfY2F0ZWdvcnkgPC0gKHJhdGlvX2NhdGVnb3J5IC8gdG90YWxfcmF0aW8pICogdG90YWxfd2lkdGgNCg0KIyBQcmludCB0aGUgZGF0YWZyYW1lIHVzaW5nIGthYmxlIGZvciBhIG5pY2VseSBmb3JtYXR0ZWQgbWFya2Rvd24gdGFibGUuDQprYWJsZShzdHJlbmd0aF9zdGFuZGFyZHNfbGlzdF9kaXNwbGF5LCBmb3JtYXQgPSAiaHRtbCIsIGNvbC5uYW1lcyA9IGMoIlN0cmVuZ3RoIFN0YW5kYXJkIiwgIkNhdGVnb3J5IikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSBwYXN0ZTAod2lkdGhfc3RyZW5ndGhfc3RhbmRhcmRzLCAiJSIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSBwYXN0ZTAod2lkdGhfY2F0ZWdvcnksICIlIikpDQoNCiMgQ3JlYXRlIGxpc3RzIHRvIHN0b3JlIGRhdGEgZnJhbWVzDQpuYW1lZF9yYW5nZXNfbGlzdCA8LSBsaXN0KCkNCm5hbWVkX3Jhbmdlc19zaGVldHNfbGlzdCA8LSBsaXN0KCkNCg0KIyBMb29wIHRocm91Z2ggdGhlIG5hbWVkIHJhbmdlcw0KZm9yIChpIGluIDE6bnJvdyhuYW1lZF9yYW5nZXMpKSB7DQogIG5hbWVkX3JhbmdlX3ZhbHVlIDwtIG5hbWVkX3JhbmdlcyRgU3RyZW5ndGggU3RhbmRhcmRgW2ldDQogIG5hbWVkX3JhbmdlX3NoZWV0X3ZhbHVlIDwtIG5hbWVkX3JhbmdlcyRgQ2F0ZWdvcnkgU2hlZXRgW2ldDQogIG5hbWVkX3JhbmdlX2xvd2VyIDwtIHRvbG93ZXIoZ3N1YigiICIsICJfIiwgbmFtZWRfcmFuZ2VfdmFsdWUpKQ0KICBuYW1lZF9yYW5nZV9zaGVldF9sb3dlciA8LSB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIG5hbWVkX3JhbmdlX3NoZWV0X3ZhbHVlKSkNCiAgDQogIGlmIChuYW1lZF9yYW5nZV9zaGVldF92YWx1ZSA9PSAiTmFtZWRfUmFuZ2VzIikgew0KICAgIG5leHQgICMgU2tpcCBpdGVyYXRpb24gaWYgdGhlIHNoZWV0IGlzICJOYW1lZF9SYW5nZXMiIHRvIGF2b2lkIHJlZHVuZGFuY3kNCiAgfQ0KICANCiAgIyBSZWFkIGRhdGEgZnJvbSB0aGUgbmFtZWQgcmFuZ2UNCiAgbmFtZWRfcmFuZ2VfZGF0YSA8LSB0cnlDYXRjaCh7DQogICAgcmVhZC54bHN4KGZpbGVfcGF0aF9zdHJlbmd0aF9zdGFuZGFyZHMsIG5hbWVkUmVnaW9uID0gbmFtZWRfcmFuZ2VfdmFsdWUpDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgIG1lc3NhZ2UocGFzdGUoIldhcm5pbmc6IFdvcmtib29rIGhhcyBubyBzdWNoIG5hbWVkIHJlZ2lvbjoiLCBuYW1lZF9yYW5nZV92YWx1ZSkpDQogICAgTlVMTA0KICB9KQ0KICANCiAgaWYgKCFpcy5udWxsKG5hbWVkX3JhbmdlX2RhdGEpICYmIGlzLmRhdGEuZnJhbWUobmFtZWRfcmFuZ2VfZGF0YSkpIHsNCiAgICAjIFVwZGF0ZSBjb2x1bW4gbmFtZXMNCiAgICBjb2xuYW1lcyhuYW1lZF9yYW5nZV9kYXRhKSA8LSBnc3ViKCJcXC4iLCAiICIsIGNvbG5hbWVzKG5hbWVkX3JhbmdlX2RhdGEpKQ0KICAgICMgU3RvcmUgdGhlIGRhdGEgZnJhbWUgaW4gdGhlIGxpc3QNCiAgICBuYW1lZF9yYW5nZXNfbGlzdFtbbmFtZWRfcmFuZ2VfbG93ZXJdXSA8LSBuYW1lZF9yYW5nZV9kYXRhDQogICAgIyBBc3NpZ24gdGhlIGRhdGEgZnJhbWUgdG8gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCB3aXRoIHRoZSBsb3dlciBjYXNlIG5hbWUNCiAgICBhc3NpZ24obmFtZWRfcmFuZ2VfbG93ZXIsIG5hbWVkX3JhbmdlX2RhdGEsIGVudmlyID0gLkdsb2JhbEVudikNCiAgfQ0KICANCiAgIyBSZWFkIGRhdGEgZnJvbSB0aGUgc2hlZXQNCiAgbmFtZWRfcmFuZ2Vfc2hlZXRfZGF0YSA8LSB0cnlDYXRjaCh7DQogICAgcmVhZC54bHN4KGZpbGVfcGF0aF9zdHJlbmd0aF9zdGFuZGFyZHMsIHNoZWV0ID0gbmFtZWRfcmFuZ2Vfc2hlZXRfdmFsdWUpDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgIG1lc3NhZ2UocGFzdGUoIldhcm5pbmc6IFdvcmtib29rIGhhcyBubyBzdWNoIHNoZWV0OiIsIG5hbWVkX3JhbmdlX3NoZWV0X3ZhbHVlKSkNCiAgICBOVUxMDQogIH0pDQogIA0KICBpZiAoIWlzLm51bGwobmFtZWRfcmFuZ2Vfc2hlZXRfZGF0YSkgJiYgaXMuZGF0YS5mcmFtZShuYW1lZF9yYW5nZV9zaGVldF9kYXRhKSkgew0KICAgICMgVXBkYXRlIGNvbHVtbiBuYW1lcw0KICAgIGNvbG5hbWVzKG5hbWVkX3JhbmdlX3NoZWV0X2RhdGEpIDwtIGdzdWIoIlxcLiIsICIgIiwgY29sbmFtZXMobmFtZWRfcmFuZ2Vfc2hlZXRfZGF0YSkpDQogICAgIyBTdG9yZSB0aGUgZGF0YSBmcmFtZSBpbiB0aGUgbGlzdA0KICAgIG5hbWVkX3Jhbmdlc19zaGVldHNfbGlzdFtbbmFtZWRfcmFuZ2Vfc2hlZXRfbG93ZXJdXSA8LSBuYW1lZF9yYW5nZV9zaGVldF9kYXRhDQogICAgIyBBc3NpZ24gdGhlIGRhdGEgZnJhbWUgdG8gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCB3aXRoIHRoZSBsb3dlciBjYXNlIG5hbWUNCiAgICBhc3NpZ24obmFtZWRfcmFuZ2Vfc2hlZXRfbG93ZXIsIG5hbWVkX3JhbmdlX3NoZWV0X2RhdGEsIGVudmlyID0gLkdsb2JhbEVudikNCiAgfQ0KfQ0KDQojIERpc3BsYXkgdGhlIHN0cnVjdHVyZSBvZiB0aGUgbGlzdHMNCiMgc3RyKG5hbWVkX3Jhbmdlc19saXN0KQ0KIyBzdHIobmFtZWRfcmFuZ2VzX3NoZWV0c19saXN0KQ0KDQojIE9wdGlvbmFsOiBWaWV3IHRoZSBjb250ZW50cyBvZiB0aGUgbGlzdHMgaW4gUlN0dWRpbyBWaWV3ZXINCiMgSW5zdGVhZCBvZiB2aWV3aW5nIHRoZSB3aG9sZSBsaXN0LCB2aWV3IGluZGl2aWR1YWwgZGF0YSBmcmFtZXMNCiMgVW5jb21tZW50IHRoZSBiZWxvdyBsaW5lcyB0byB2aWV3IHNwZWNpZmljIG5hbWVkIHJhbmdlcyBvciBzaGVldHMNCiMgVmlldyhuYW1lZF9yYW5nZXNfbGlzdFtbIm1hbGVfYmFyYmVsbF9jdXJsX3N0ZF8xcm1fYnlfYWdlX3N0cmVuZ3RobGV2ZWwiXV0pDQojIFZpZXcobWFsZV9iYXJiZWxsX2N1cmxfc3RkXzFybV9ieV9hZ2Vfc3RyZW5ndGhsZXZlbCkNCg0KYGBgDQoNCiMgTUFSSyBSSVBQRVRPRSdTIFNUQU5EQVJEUw0KDQpNYXJrIFJpcHBldG9lJ3MgU3RyZW5ndGggU3RhbmRhcmQ6IDEgUmVwIE1heCBCeSBCb2R5d2VpZ2h0LiAgDQoNCkhlcmUgd2UgdXRpbGl6ZSBNYXJrIFJpcHBldG9lJ3MgU3RyZW5ndGggU3RhbmRhcmRzW140XSB0byBiZW5jaG1hcmsgaW5kaXZpZHVhbCBwZXJmb3JtYW5jZSBhZ2FpbnN0IGVzdGFibGlzaGVkIGNyaXRlcmlhIGZvciBwcmltYXJ5IHN0cmVuZ3RoIGV4ZXJjaXNlcy4gVGhlc2Ugc3RhbmRhcmRzIGFyZSBpbnN0cnVtZW50YWwgaW4gZXZhbHVhdGluZyBhbiBpbmRpdmlkdWFsJ3MgbGlmdGluZyBjYXBhYmlsaXRpZXMgaW4gcmVsYXRpb24gdG8gdGhlaXIgYm9keXdlaWdodCBhbmQgdHJhaW5pbmcgZXhwZXJpZW5jZS4gQnkgZG9pbmcgc28sIHdlIGNhbiBlZmZlY3RpdmVseSBnYXVnZSBwcm9ncmVzcywgcGlucG9pbnQgYXJlYXMgdGhhdCBuZWVkIGltcHJvdmVtZW50LCBhbmQgdGFpbG9yIHRyYWluaW5nIHByb2dyYW1zIHRvIGJldHRlciBtZWV0IHRoZSBzcGVjaWZpYyBzdHJlbmd0aCBnb2FscyBvZiBlYWNoIGluZGl2aWR1YWwuDQoNClRoZSBleGVyY2lzZXMgdXNlIHRoZSB0ZWNobmlxdWUgZGVzY3JpYmVkIGluICJTdGFydGluZyBTdHJlbmd0aDogQmFzaWMgQmFyYmVsbCBUcmFpbmluZywgM3JkIGVkLiIgVGhlIEJsdWVib29rIG1heSBiZSBwdXJjaGFzZWQgdGhyb3VnaCBUaGUgQWFzZ2FhcmQgQ29tcGFueSBvbmxpbmUgc3RvcmVbXjVdIGFuZCBvbiBBbWF6b24gaW4gdmFyaW91cyBtZWRpdW1zIChwYXBlcmJhY2ssIEtpbmRsZSwgYXVkaW8pLiBBbGwgbGlmdHMgYXJlIHBlcmZvcm1lZCB3aXRoIHRoZSBiYXJiZWxsLCBhcyBpbmRpY2F0ZWQgYnkgdGhlIGJvb2sgdGl0bGUuDQoNClRoaXMgcHJvamVjdCBoYXMgYmVlbiBhIGNvbnRpbnVvdXMgcHJvY2VzcyBvZiBlZGl0aW5nLCB1cGRhdGluZywgYW5kIHJldmlld2luZyBhcyBJIHByb2dyZXNzLiBBZnRlciBjb25zaWRlcmluZyBib3RoIFN0cmVuZ3RoTGV2ZWwuY29tIGFuZCBNYXJrIFJpcHBldG9lJ3MgU3RhbmRhcmRzIHZpYSBhbiBhcnRpY2xlIGJ5IExlZ2lvbiBBdGhsZXRpY3NbXjZdLCBJIGRlY2lkZWQgdG8gdXRpbGl6ZSBNYXJrIFJpcHBldG9lJ3MgU3RhbmRhcmRzIHRvIGNyZWF0ZSB2aXN1YWwgcGxvdCBiZW5jaG1hcmtzLiAoTXkgcHJpbWFyeSBnb2FsIGlzIHRvIGNyZWF0ZSBzcGlkZXIgY2hhcnRzIGZvciBjcmVhdGl2ZSBhbmQgdmlzdWFsbHkgbW90aXZhdGluZyB0YXJnZXRzLikgSG93ZXZlciwgdGhlIExlZ2lvbiBBdGhsZXRpY3MgYXJ0aWNsZSBsYWNrZWQgaW5mb3JtYXRpb24gb24gaG93IHRoZXNlIG1lYXN1cmVzIGFyZSBvYnRhaW5lZCBhbmQgd2hhdCB0ZWNobmlxdWVzIG9yIGluc3RydW1lbnRzIGFyZSB1c2VkIGluIGV4ZWN1dGluZyB0aGVzZSBzdGFuZGFyZHMuDQoNCkkgZW1haWxlZCByaXBAc3RhcnRpbmdzdHJlbmd0aC5jb20gZm9yIGNsYXJpZmljYXRpb24gcmVnYXJkaW5nIHRoZSBNYWxlIE92ZXJoZWFkIFNob3VsZGVyIFByZXNzIFN0cmVuZ3RoIFN0YW5kYXJkcyBhbmQgd2FzIGFkdmlzZWQgdG8gIklnbm9yZSB0aGlzIHRhYmxlLiBJdCBpcyBpbnZhbGlkLCBhbmQgd2UgaGF2ZW7igJl0IHVzZWQgaXQgaW4gMjAgeWVhcnMuIEFzIHlvdSB3b3VsZCBrbm93IGlmIHlvdSBoYWQgcmVhZCB0aGUgYmx1ZSBib29rLiIgVXBvbiBmdXJ0aGVyIHJlc2VhcmNoLCBNYXJrIFJpcHBldG9lIGNvbmZpcm1lZCB0aGUgY2hhbmdlcyBpbiBjYXRlZ29yaWVzIG9uIFN0YXJ0aW5nIFN0cmVuZ3RoIEZvcnVtW143XSBmcm9tIHRoZSBwcmV2aW91cyBvdXRkYXRlZCBjYXRlZ29yaWVzIChCZWdpbm5lciwgTm92aWNlLCBJbnRlcm1lZGlhdGUsIEFkdmFuY2VkLCBhbmQgRWxpdGUpIHRvIHRoZSBjdXJyZW50IENhdC4gSSB0aHJvdWdoIENhdC4gVi4NCg0KVG8gcHJvcGVybHkgdXRpbGl6ZSB0aGVzZSBzdGFuZGFyZHMsIGl0IGlzIHJlY29tbWVuZGVkIHRvIHJldmlldyAiU3RhcnRpbmcgU3RyZW5ndGg6IEJhc2ljIEJhcmJlbGwgVHJhaW5pbmciW144XSBhbmQgIlByYWN0aWNhbCBQcm9ncmFtbWluZyBmb3IgU3RyZW5ndGggVHJhaW5pbmcuIlteOV0gVGhlIG1vc3QgcmVjZW50IGFuZCByZWxldmFudCAzcmQgZWRpdGlvbnMgKDIwMTIpIGFyZSBhdmFpbGFibGUgb24gdGhlaXIgd2Vic2l0ZSwgYXMgd2VsbCBhcyBpbiBkaWZmZXJlbnQgbWVkaXVtcyBvbiBBbWF6b24uIFlvdSBjYW4gZG93bmxvYWQgb25saW5lIGJvb2sgc2FtcGxlcyB0byBkZXRlcm1pbmUgaWYgU3RhcnRpbmcgU3RyZW5ndGggc3VpdHMgeW91ciBuZWVkcy4NCg0KYGBge3IgbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCwgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIENvZGUgZXh0cmFjdHMgYW5kIHJlZmluZXMgYSBzdWJzZXQgb2YgZGF0YSByZWxhdGVkIHRvICJNYXJrIFJpcHBldG9lIiBzdGFuZGFyZHMgZnJvbSBhIGJyb2FkZXIgZGF0YXNldCwgbWFraW5nIGl0IG1vcmUgYWNjZXNzaWJsZSBhbmQgZWFzaWVyIHRvIHdvcmsgd2l0aCBieSBjbGVhbmluZyB1cCB0aGUgY2F0ZWdvcnkgbmFtZXMgZm9yIGZ1cnRoZXIgYW5hbHlzaXMgb3IgcmVwb3J0aW5nDQoNCiMgc3Vic2V0KCkgZmlsdGVycyByb3dzIGZyb20gdGhlIG5hbWVkX3JhbmdlcyBkYXRhZnJhbWUuDQojIGdyZXBsKCkgY2hlY2tzIGVhY2ggZW50cnkgaW4gdGhlICJTdHJlbmd0aCBTdGFuZGFyZCIgY29sdW1uIGZvciB0aGUgc3Vic3RyaW5nIA0KbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCA8LSBzdWJzZXQobmFtZWRfcmFuZ2VzLCBncmVwbCgiTWFya19SaXBwZXRvZSIsIGBTdHJlbmd0aCBTdGFuZGFyZGApKQ0KDQojIFBpcGUgT3BlcmF0b3IgKCU+JSkgaXMgdXNlZCB0byBwYXNzIHRoZSByZXN1bHQgb2Ygb25lIGZ1bmN0aW9uIHRvIHRoZSBuZXh0LiBJdCBoZWxwcyBpbiB3cml0aW5nIGNsZWFuZXIgYW5kIG1vcmUgcmVhZGFibGUgY29kZSwgZXNwZWNpYWxseSB3aGVuIHBlcmZvcm1pbmcgbXVsdGlwbGUgb3BlcmF0aW9ucyBvbiBhIGRhdGFzZXQuDQojIGdzdWIoIl8iLCAiICIsIENhdGVnb3J5IFNoZWV0KSByZXBsYWNlcyB1bmRlcnNjb3JlcyAoXykgd2l0aCBzcGFjZXMgaW4gdGhlIENhdGVnb3J5IFNoZWV0IGNvbHVtbi4NCiMgTmV3IGNvbHVtbiBpcyBjcmVhdGVkLiANCm1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QgPC0gbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCAlPiUNCiAgbXV0YXRlKGBDYXRlZ29yeSBOYW1lYCA9IGdzdWIoIl8iLCAiICIsIGBDYXRlZ29yeSBTaGVldGApKQ0KDQojIERpc3BsYXkgdGhlIG1vZGlmaWVkICdTdHJlbmd0aCBTdGFuZGFyZCcgY29sdW1uIHdpdGggc3BhY2VzIGluc3RlYWQgb2YgdW5kZXJzY29yZXMNCmRpc3BsYXlfbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCA8LSBtYXJrX3JpcHBldG9lX3N0YW5kYXJkc19saXN0ICU+JQ0KICBtdXRhdGUoYFN0cmVuZ3RoIFN0YW5kYXJkYCA9IGdzdWIoIl8iLCAiICIsIGBTdHJlbmd0aCBTdGFuZGFyZGApKSAlPiUNCiAgc2VsZWN0KC1gQ2F0ZWdvcnkgU2hlZXRgKSAgIyBUaGlzIGV4Y2x1ZGVzIHRoZSAnQ2F0ZWdvcnkgU2hlZXQnIGNvbHVtbg0KDQojIFRoZSBWaWV3IGZ1bmN0aW9uIGlzIHVzZWQgdG8gb3BlbiB0aGUgcmF3X2RhdGEgZGF0YWZyYW1lIGluIHRoZSBSU3R1ZGlvIGRhdGEgdmlld2VyIGZvciBpbnRlcmFjdGl2ZSBleHBsb3JhdGlvbi4NClZpZXcobWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCkgI1J1biB0aGlzIGxpbmUgb2YgY29kZSB0byB2aWV3IHRhYmxlLiANCg0KIyBQcmludCBmb3IgcmVmZXJlbmNlLiANCiMgcHJpbnQobWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCkNCiMgcHJpbnQoZGlzcGxheV9tYXJrX3JpcHBldG9lX3N0YW5kYXJkc19saXN0KQ0KDQojIERlZmluZSB0aGUgcmF0aW9zIGFuZCB0b3RhbCB3aWR0aCBmb3IgY29sdW1uIHdpZHRocw0KdG90YWxfd2lkdGggPC0gMTAwDQpyYXRpb19zdHJlbmd0aF9zdGFuZGFyZHMgPC0gMg0KcmF0aW9fY2F0ZWdvcnkgPC0gMS4yNQ0KdG90YWxfcmF0aW8gPC0gcmF0aW9fc3RyZW5ndGhfc3RhbmRhcmRzICsgcmF0aW9fY2F0ZWdvcnkNCg0KIyBDYWxjdWxhdGUgdGhlIGNvbHVtbiB3aWR0aHMNCndpZHRoX3N0cmVuZ3RoX3N0YW5kYXJkcyA8LSAocmF0aW9fc3RyZW5ndGhfc3RhbmRhcmRzIC8gdG90YWxfcmF0aW8pICogdG90YWxfd2lkdGgNCndpZHRoX2NhdGVnb3J5IDwtIChyYXRpb19jYXRlZ29yeSAvIHRvdGFsX3JhdGlvKSAqIHRvdGFsX3dpZHRoDQoNCiMgUHJpbnQgdGhlIGRhdGFmcmFtZSB1c2luZyBrYWJsZSBmb3IgYSBuaWNlbHkgZm9ybWF0dGVkIG1hcmtkb3duIHRhYmxlLg0Ka2FibGUoZGlzcGxheV9tYXJrX3JpcHBldG9lX3N0YW5kYXJkc19saXN0LCBmb3JtYXQgPSAiaHRtbCIsIGNvbC5uYW1lcyA9IGMoIlN0cmVuZ3RoIFN0YW5kYXJkIiwgIkNhdGVnb3J5IikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSBwYXN0ZTAod2lkdGhfc3RyZW5ndGhfc3RhbmRhcmRzLCAiJSIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSBwYXN0ZTAod2lkdGhfY2F0ZWdvcnksICIlIikpDQoNCg0KYGBgDQoNClRoZXJlIGFyZSBmaXZlIFN0YXJ0aW5nIFN0cmVuZ3RoIFN0YW5kYXJkcywgd2l0aCB0aGUgUG93ZXIgQ2xlYW4gZXhjbHVkZWQgaW4gdGhpcyByZXBvcnQuIEVhY2ggb2YgdGhlIGZvdXIgcmVtYWluaW5nIFN0YW5kYXJkcyBpcyBwcmVzZW50ZWQgYmVsb3csIGZvbGxvd2VkIGJ5IGEgcGxvdCB0byB2aXN1YWxpemUgcGVyZm9ybWFuY2VzIGZvciBjb21wYXJpc29uIGFuZCBtb3RpdmF0aW9uLg0KDQpgYGB7ciBtYXJrX3JpcHBldG9lX3N0YW5kYXJkc190YWJsZXNfYW5kX3Bsb3RzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCg0KIyBLZWVwIGZpZy53aWR0aD0xMCBmb3IgUERGIGRpc3BsYXkgKHZpYSBicm93c2VyID4gU2F2ZSBBcyBQREYpLiBXaGlsZSBmaWcud2lkdGg9OSAoaW5zdGVhZCBvZiAxMCkgZml0cyB3aWR0aCBvZiBvdXRwdXQsIHNhdmluZyBhcyBQREYgd2l0aCBmaWcud2lkdGg9OSB3aWxsIHJlc3VsdCBpbiBzbWFsbCBmaWd1cmU7IHdpZHRoPTEwIHdpbGwgZmlsbCB0aGUgUERGIHBhZ2UuDQoNCiMgTG9hZCB0aGUgcmVxdWlyZWQgcGFja2FnZXMgaWYgbm90IGFscmVhZHkgaW5zdGFsbGVkDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkgIyBFbnN1cmUga2FibGVFeHRyYSBpcyBsb2FkZWQgZm9yIHN0eWxpbmcNCg0KIyBGdW5jdGlvbiB0byBnZW5lcmF0ZSBnZ3Bsb3QgZm9yIGVhY2ggZGF0YSBmcmFtZQ0KZ2VuZXJhdGVfZ2dwbG90IDwtIGZ1bmN0aW9uKGRhdGEsIGNhdGVnb3J5X25hbWUsIG1hcmtfcmlwcGV0b2Vfc3RyZW5ndGhfc3RhbmRhcmQpIHsNCiAgZGF0YV9udW1iZXIgPC0gZGF0YSAlPiUNCiAgICBtdXRhdGUoQm9keXdlaWdodCA9IGFzLm51bWVyaWMoZ3N1YigiW14wLTldIiwgIiIsIEJvZHl3ZWlnaHQpKSkNCg0KICAjIFJlbmFtZSBjb2x1bW5zIHRvIHJlbW92ZSBkb3VibGUgcGVyaW9kcw0KICBjb2xuYW1lcyhkYXRhX251bWJlcikgPC0gZ3N1YigiXFwuXFwuIiwgIi4gIiwgY29sbmFtZXMoZGF0YV9udW1iZXIpKQ0KDQogICMgUHJpbnQgY29sdW1uIG5hbWVzIGZvciBkZWJ1Z2dpbmcNCiAgIyBwcmludChjb2xuYW1lcyhkYXRhX251bWJlcikpDQogICAgDQogIGdncGxvdChkYXRhX251bWJlciwgYWVzKHggPSBCb2R5d2VpZ2h0KSkgKw0KICAgIGdlb21fcmliYm9uKGFlcyh5bWluID0gYENhdC4gSWAsIHltYXggPSBgQ2F0LiBJSWApLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuMikgKw0KICAgIGdlb21fcmliYm9uKGFlcyh5bWluID0gYENhdC4gSUlgLCB5bWF4ID0gYENhdC4gSUlJYCksIGZpbGwgPSAiZ3JlZW4iLCBhbHBoYSA9IDAuMikgKw0KICAgIGdlb21fcmliYm9uKGFlcyh5bWluID0gYENhdC4gSUlJYCwgeW1heCA9IGBDYXQuIElWYCksIGZpbGwgPSAib3JhbmdlIiwgYWxwaGEgPSAwLjIpICsNCiAgICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IGBDYXQuIElWYCwgeW1heCA9IGBDYXQuIFZgKSwgZmlsbCA9ICJyZWQiLCBhbHBoYSA9IDAuMikgKw0KICAgIGdlb21fcmliYm9uKGFlcyh5bWluID0gYENhdC4gVmAsIHltYXggPSBJbmYpLCBmaWxsID0gInB1cnBsZSIsIGFscGhhID0gMC4yKSArDQogICAgDQogICAgIyBGaWxsIHRoZSByZW1haW5pbmcgbm9uLWNvbG9yZWQgcGFydA0KICAgIGdlb21fcmliYm9uKGFlcyh5bWluID0gLUluZiwgeW1heCA9IGBDYXQuIElgKSwgZmlsbCA9ICJncmF5IiwgYWxwaGEgPSAwLjIpICsNCiAgICANCiAgICAjIENyZWF0ZSBsaW5lcw0KICAgIGdlb21fbGluZShhZXMoeSA9IGBDYXQuIElgKSwgY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAxKSArDQogICAgZ2VvbV9saW5lKGFlcyh5ID0gYENhdC4gSUlgKSwgY29sb3IgPSAiZ3JlZW4iLCBzaXplID0gMSkgKw0KICAgIGdlb21fbGluZShhZXMoeSA9IGBDYXQuIElJSWApLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplID0gMSkgKw0KICAgIGdlb21fbGluZShhZXMoeSA9IGBDYXQuIElWYCksIGNvbG9yID0gInJlZCIsIHNpemUgPSAxKSArDQogICAgZ2VvbV9saW5lKGFlcyh5ID0gYENhdC4gVmApLCBjb2xvciA9ICJwdXJwbGUiLCBzaXplID0gMSkgKw0KICAgIA0KICAgICMgU2V0IGxhYmVscw0KICAgIGxhYnMoDQogICAgICB4ID0gIkJvZHl3ZWlnaHQgKGxiKSIsDQogICAgICB5ID0gIjFSTSBXZWlnaHQgTG9hZCBFeGVjdXRpb24iLA0KICAgICAgdGl0bGUgPSBwYXN0ZSgiTWFsZSIsIGNhdGVnb3J5X25hbWUsICJTdGFuZGFyZHMiKSwNCiAgICAgIHN1YnRpdGxlID0gIkNvbXBhcmlzb24gb2YgU3RyZW5ndGggU3RhbmRhcmRzIEFjcm9zcyBFeHBlcmllbmNlIExldmVscyIsDQogICAgICBjYXB0aW9uID0gcGFzdGUoIlNvdXJjZToiLCBtYXJrX3JpcHBldG9lX3N0cmVuZ3RoX3N0YW5kYXJkKSAjIENoYW5nZSBTb3VyY2UgaW5mbyBQUk4NCiAgICApICsNCiAgICANCiAgICAjIEFkZCBtb3JlIG1hcmtlcnMgb24gdGhlIHktYXhpcyBhdCBpbmNyZW1lbnRzIG9mIDIwDQogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA5OTksIGJ5ID0gMjApKSArDQogICAgIyBBZGQgbW9yZSBtYXJrZXJzIG9uIHRoZSB4LWF4aXMgYXQgaW5jcmVtZW50cyBvZiAxMA0KICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgOTk5LCBieSA9IDEwKSkgKw0KICAgIA0KICAgICMgQWRkIHRleHQgbGFiZWxzIGZvciBza2lsbCBsZXZlbHMgd2l0aCBtYXRjaGluZyBjb2xvcnMNCiAgICBnZW9tX3RleHQoYWVzKHggPSBtYXgoQm9keXdlaWdodCksIHkgPSBtaW4oYENhdC4gSWApLCBsYWJlbCA9ICIiKSwgY29sb3IgPSAiZGltZ3JheSIsIHZqdXN0ID0gLTEpICsNCiAgICBnZW9tX3RleHQoYWVzKHggPSBtYXgoQm9keXdlaWdodCksIHkgPSBtYXgoYENhdC4gSWApLCBsYWJlbCA9ICJDYXQuIEkiKSwgY29sb3IgPSAiZGFya2JsdWUiLCB2anVzdCA9IC0xKSArDQogICAgZ2VvbV90ZXh0KGFlcyh4ID0gbWF4KEJvZHl3ZWlnaHQpLCB5ID0gbWF4KGBDYXQuIElJYCksIGxhYmVsID0gIkNhdC4gSUkiKSwgY29sb3IgPSAiZGFya2dyZWVuIiwgdmp1c3QgPSAtMSkgKw0KICAgIGdlb21fdGV4dChhZXMoeCA9IG1heChCb2R5d2VpZ2h0KSwgeSA9IG1heChgQ2F0LiBJSUlgKSwgbGFiZWwgPSAiQ2F0LiBJSUkiKSwgY29sb3IgPSAiZGFya29yYW5nZSIsIHZqdXN0ID0gLTEpICsNCiAgICBnZW9tX3RleHQoYWVzKHggPSBtYXgoQm9keXdlaWdodCksIHkgPSBtYXgoYENhdC4gSVZgKSwgbGFiZWwgPSAiQ2F0LiBJViIpLCBjb2xvciA9ICJkYXJrcmVkIiwgdmp1c3QgPSAtMSkgKw0KICAgIGdlb21fdGV4dChhZXMoeCA9IG1heChCb2R5d2VpZ2h0KSwgeSA9IG1heChgQ2F0LiBWYCksIGxhYmVsID0gIkNhdC4gViIpLCBjb2xvciA9ICJwdXJwbGUiLCB2anVzdCA9IC0xKSArDQogICAgDQogICAgIyBDdXN0b21pemUgdGhlbWUNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIHRoZW1lKA0KICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE2KSwNCiAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxMiksDQogICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDEsICJjbSIpDQogICAgKQ0KfQ0KDQojIExpc3RzIHRvIHN0b3JlIHRoZSBwbG90cyBhbmQgdGFibGVzDQpwbG90c19saXN0X3N0cmVuZ3RoX3N0YW5kYXJkc19tYXJrX3JpcHBldG9lIDwtIGxpc3QoKQ0KdGFibGVzX2xpc3Rfc3RyZW5ndGhfc3RhbmRhcmRzX21hcmtfcmlwcGV0b2UgPC0gbGlzdCgpDQoNCiMgQ2hlY2sgYW5kIGNyZWF0ZSB0aGUgJ3Bsb3RzJyBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdA0KaWYgKCFkaXIuZXhpc3RzKCJwbG90cyIpKSB7DQogIGRpci5jcmVhdGUoInBsb3RzIikNCn0NCg0KIyBDaGVjayBhbmQgY3JlYXRlIHRoZSAndGFibGVzJyBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdA0KaWYgKCFkaXIuZXhpc3RzKCJ0YWJsZXMiKSkgew0KICBkaXIuY3JlYXRlKCJ0YWJsZXMiKQ0KfQ0KDQojIExvb3AgdGhyb3VnaCBlYWNoIG5hbWVkIHJhbmdlIGZyb20gdGhlIGZpbHRlcmVkIG1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QgZGF0YWZyYW1lDQpmb3IgKGkgaW4gMTpucm93KG1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QpKSB7DQogIHN0cmVuZ3RoX3N0YW5kYXJkX25hbWVkX3JhbmdlIDwtIG1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QkYFN0cmVuZ3RoIFN0YW5kYXJkYFtpXQ0KICBjYXRlZ29yeV9uYW1lIDwtIG1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QkYENhdGVnb3J5IE5hbWVgW2ldDQogIA0KICAjIExvYWQgdGhlIGRhdGEgZnJvbSB0aGUgbmFtZWQgcmFuZ2UNCiAgZGF0YV9mcmFtZSA8LSByZWFkV29ya2Jvb2soc3RyZW5ndGhfc3RhbmRhcmRzLCBuYW1lZFJlZ2lvbiA9IHN0cmVuZ3RoX3N0YW5kYXJkX25hbWVkX3JhbmdlKQ0KICANCiAgIyBDaGVjayBpZiB0aGUgJ0JvZHl3ZWlnaHQnIGNvbHVtbiBleGlzdHMgaW4gdGhlIGRhdGEgZnJhbWUNCiAgaWYgKCEiQm9keXdlaWdodCIgJWluJSBjb2xuYW1lcyhkYXRhX2ZyYW1lKSkgew0KICAgIGNhdChwYXN0ZSgiU2tpcHBpbmciLCBzdHJlbmd0aF9zdGFuZGFyZF9uYW1lZF9yYW5nZSwgIi0gJ0JvZHl3ZWlnaHQnIGNvbHVtbiBtaXNzaW5nLlxuIikpDQogICAgbmV4dA0KICB9DQoNCiAgIyBFbnN1cmUgY29sdW1uIG5hbWVzIGFyZSB0cmltbWVkIG9mIHdoaXRlc3BhY2UNCiAgY29sbmFtZXMoZGF0YV9mcmFtZSkgPC0gdHJpbXdzKGNvbG5hbWVzKGRhdGFfZnJhbWUpKQ0KDQogICMgUmVuYW1lIGNvbHVtbnMgdG8gcmVtb3ZlIGRvdWJsZSBwZXJpb2RzIGZvciBib3RoIHRhYmxlIGFuZCBwbG90DQogIGNvbG5hbWVzKGRhdGFfZnJhbWUpIDwtIGdzdWIoIlxcLlxcLiIsICIuICIsIGNvbG5hbWVzKGRhdGFfZnJhbWUpKQ0KDQogICMgRm9ybWF0IHRoZSB0aXRsZSBvZiB0aGUgcGxvdCBhbmQgaGVhZCBvZiB0aGUgdGFibGUgdXNpbmcgdGhlIGNsZWFuZWQgY2F0ZWdvcnkgbmFtZQ0KICBmb3JtYXR0ZWRfaGVhZGVyIDwtIGdzdWIoIl8iLCAiICIsIHN0cmVuZ3RoX3N0YW5kYXJkX25hbWVkX3JhbmdlKQ0KDQogICMgR2VuZXJhdGUgdGhlIHBsb3QNCiAgcGxvdCA8LSBnZW5lcmF0ZV9nZ3Bsb3QoZGF0YV9mcmFtZSwgY2F0ZWdvcnlfbmFtZSwgc3RyZW5ndGhfc3RhbmRhcmRfbmFtZWRfcmFuZ2UpDQogIA0KICAjIFByaW50IHRoZSBuYW1lIG9mIHRoZSBuYW1lZCByYW5nZSBhcyBhIG1hcmtkb3duIGhlYWRlcg0KICBjYXQocGFzdGUwKCJcblxuPGg0PiAiLCBmb3JtYXR0ZWRfaGVhZGVyLCAiPC9oND5cbiIpKQ0KDQogICMgUmVuYW1lICdCb2R5d2VpZ2h0JyBjb2x1bW4gdG8gJ0JvZHl3ZWlnaHQgKGxiKScNCiAgbmFtZXMoZGF0YV9mcmFtZSlbbmFtZXMoZGF0YV9mcmFtZSkgPT0gIkJvZHl3ZWlnaHQiXSA8LSAiQm9keXdlaWdodCAobGIpIg0KDQogICMgUHJpbnQgdGhlIHBsb3QNCiAgcHJpbnQocGxvdCkNCg0KICAjIFNhdmUgdGhlIHBsb3QgdG8gdGhlIGxpc3QNCiAgcGxvdHNfbGlzdF9zdHJlbmd0aF9zdGFuZGFyZHNfbWFya19yaXBwZXRvZVtbZm9ybWF0dGVkX2hlYWRlcl1dIDwtIHBsb3QNCg0KICAjIE91dHB1dCB0aGUgZGF0YSBmcmFtZSBhcyBhIG1hcmtkb3duIHRhYmxlIHdpdGggZXZlbiBjb2x1bW4gd2lkdGhzDQogIHByaW50KA0KICAgIHRhYmxlX2h0bWwgPC0ga2FibGUoZGF0YV9mcmFtZSwgZm9ybWF0ID0gImh0bWwiLCBhbGlnbiA9ICdsJykgJT4lDQogICAgICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgICAgIGNvbHVtbl9zcGVjKDE6bmNvbChkYXRhX2ZyYW1lKSwgd2lkdGggPSBwYXN0ZTAoMTAwIC8gbmNvbChkYXRhX2ZyYW1lKSwgIiUiKSkNCiAgKQ0KICANCiAgIyBTYXZlIHRoZSB0YWJsZSB0byB0aGUgbGlzdA0KICB0YWJsZXNfbGlzdF9zdHJlbmd0aF9zdGFuZGFyZHNfbWFya19yaXBwZXRvZVtbZm9ybWF0dGVkX2hlYWRlcl1dIDwtIHRhYmxlX2h0bWwNCg0KICAjIE9wdGlvbmFsbHkgc2F2ZSB0aGUgcGxvdCBhbmQgdGFibGUNCiAgZ2dzYXZlKGZpbGVuYW1lID0gcGFzdGUwKCJwbG90cy8iLCB0b2xvd2VyKHN0cmVuZ3RoX3N0YW5kYXJkX25hbWVkX3JhbmdlKSwgIi5wbmciKSwgcGxvdCA9IHBsb3QsIHdpZHRoID0gMTIsIGhlaWdodCA9IDgpDQoNCiAgIyBTYXZlIHRoZSBkYXRhIGZyYW1lIGFzIGEgQ1NWIGZpbGUNCiAgd3JpdGUuY3N2KGRhdGFfZnJhbWUsIGZpbGUgPSBwYXN0ZTAoInRhYmxlcy8iLCB0b2xvd2VyKHN0cmVuZ3RoX3N0YW5kYXJkX25hbWVkX3JhbmdlKSwgIi5jc3YiKSwgcm93Lm5hbWVzID0gRkFMU0UpDQp9DQoNCiMgRXhhbXBsZSBvZiBob3cgdG8gcmVjYWxsIGFuZCBwcmludCBhIHNwZWNpZmljIHBsb3QgYW5kIHRhYmxlIGZyb20gdGhlIGxpc3RzDQojIHByaW50KHBsb3RzX2xpc3Rfc3RyZW5ndGhfc3RhbmRhcmRzX21hcmtfcmlwcGV0b2VbWyJNYWxlIEJlbmNoIFByZXNzIFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIl1dKQ0KIyBwcmludCh0YWJsZXNfbGlzdF9zdHJlbmd0aF9zdGFuZGFyZHNfbWFya19yaXBwZXRvZSkNCiMgcHJpbnQodGFibGVzX2xpc3Rfc3RyZW5ndGhfc3RhbmRhcmRzX21hcmtfcmlwcGV0b2VbIk1hbGUgQmVuY2ggUHJlc3MgU3RkIDFSTSBCeSBCb2R5d2VpZ2h0IE1hcmsgUmlwcGV0b2UiXSkNCiMgY2F0KGFzLmNoYXJhY3Rlcih0YWJsZXNfbGlzdF9zdHJlbmd0aF9zdGFuZGFyZHNfbWFya19yaXBwZXRvZVtbIk1hbGUgQmVuY2ggUHJlc3MgU3RkIDFSTSBCeSBCb2R5d2VpZ2h0IE1hcmsgUmlwcGV0b2UiXV0pKQ0KDQpgYGANCg0KIyAxUk0gQ0FMQ1VMQVRPUiANClRoaXMgMVJNIENvbnZlcnNpb24gVGFibGUgZnJvbSBTdHJlbmd0aCBMZXZlbFteMTBdIGRpc3BsYXlzIHRoZSBSZXBldGl0aW9uIFBlcmNlbnRhZ2VzIG9mIDFSTSwgaGVscGluZyB0byBjYWxjdWxhdGUgdGhlIGFwcHJveGltYXRlIG9uZS1yZXAgbWF4ICgxUk0pLiBUaGUgb25lLXJlcCBtYXggaXMgdGhlIG1heGltdW0gd2VpZ2h0IHlvdSBjYW4gbGlmdCBmb3IgYSBzaW5nbGUgcmVwZXRpdGlvbiBmb3IgYSBnaXZlbiBleGVyY2lzZS4NCg0KYGBge3IgY2FsY3VsYXRvcl8xcm0sIGV2YWw9VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQoNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCmZpbGVfcGF0aF8xcm1fY2FsY3VsYXRvciA8LSAiQzovL1VzZXJzLy9rZW5kci8vT25lRHJpdmUvL0RvY3VtZW50cy8vRGF0YSBBbmFseXRpY3MvL0tlbkRvZXNGaXRuZXNzLy8xUk0gQ2FsY3VsYXRvci54bHNtIg0KDQpzaGVldF9uYW1lc18xcm1fY2FsY3VsYXRvciA8LSBleGNlbF9zaGVldHMoZmlsZV9wYXRoXzFybV9jYWxjdWxhdG9yKSAjIFVwZGF0ZSBzZWxlY3RlZCBzaGVldHMgYXMgbmVlZGVkLg0KDQojIFVzZSBrbml0cjo6a2FibGUgdG8gZm9ybWF0IGFzIGEgbWFya2Rvd24gdGFibGUNCiMga25pdHI6OmthYmxlKHNoZWV0X25hbWVzXzFybV9jYWxjdWxhdG9yLCBmb3JtYXQgPSAibWFya2Rvd24iLCBjb2wubmFtZXMgPSAiU2hlZXRzIikgDQoNCiMgUmVhZCBOYW1lZCBSYW5nZXM6IFJlYWRzIGEgc3BlY2lmaWMgc2hlZXQgbmFtZWQgIk5hbWVkX1JhbmdlcyIgdGhhdCBwcmVzdW1hYmx5IGNvbnRhaW5zIG1ldGFkYXRhIGFib3V0IG90aGVyIG5hbWVkIHJhbmdlcyBpbiB0aGUgd29ya2Jvb2suIEl0IGtlZXBzIG9ubHkgdGhlIGNvbHVtbnMgcmVsYXRlZCB0byBuYW1lZCByYW5nZXMgYW5kIHRoZWlyIHJlc3BlY3RpdmUgc2hlZXRzLg0KbmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yIDwtIHJlYWRfZXhjZWwoZmlsZV9wYXRoXzFybV9jYWxjdWxhdG9yLCBzaGVldCA9ICJOYW1lZF9SYW5nZXMiKQ0Kc2hlZXRfbmFtZXNfZmlsdGVyZWQgPC0gdW5pcXVlKG5hbWVkX3Jhbmdlc18xcm1fY2FsY3VsYXRvciRgTmFtZWQgUmFuZ2UgU2hlZXRgKQ0KbmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yIDwtIG5hbWVkX3Jhbmdlc18xcm1fY2FsY3VsYXRvcltuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3IkYE5hbWVkIFJhbmdlIFNoZWV0YCAlaW4lIHNoZWV0X25hbWVzX2ZpbHRlcmVkLCBjKCJOYW1lZCBSYW5nZSIsICJOYW1lZCBSYW5nZSBTaGVldCIpXQ0KDQojIFZpZXcgdGhlIGRhdGEgZnJhbWUgaWYgbmVlZGVkIChub3QgZHVyaW5nIGtuaXR0aW5nKS4gVmlldyBmdW5jdGlvbiBvcGVucyB0aGUgcmF3X2RhdGEgZGF0YWZyYW1lIGluIHRoZSBSU3R1ZGlvIGRhdGEgdmlld2VyIGZvciBpbnRlcmFjdGl2ZSBleHBsb3JhdGlvbi4NCiMgVmlldyhuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3IpDQoNCm51bV9jb2x1bW5zIDwtIG5jb2wobmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yKQ0KY29sdW1uX3dpZHRoIDwtIDEwMCAvIG51bV9jb2x1bW5zDQoNCiMgRGlzcGxheSB0aGUgZGF0YWZyYW1lIHVzaW5nIGtuaXRyOjprYWJsZSANCiMga25pdHI6OmthYmxlKG5hbWVkX3Jhbmdlc18xcm1fY2FsY3VsYXRvciwgZm9ybWF0ID0gIm1hcmtkb3duIiwgY29sLm5hbWVzID0gYygiTmFtZWQgUmFuZ2UiLCAiTmFtZWQgUmFuZ2UgU2hlZXQiKSkgJT4lDQojICAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSkgJT4lDQojICAgY29sdW1uX3NwZWMoMTpudW1fY29sdW1ucywgd2lkdGggPSBwYXN0ZTAoY29sdW1uX3dpZHRoLCAiJSIpKQ0KDQojIENyZWF0ZSBsaXN0cyB0byBzdG9yZSBkYXRhIGZyYW1lcw0KbmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yX2xpc3QgPC0gbGlzdCgpDQpuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3Jfc2hlZXRzX2xpc3QgPC0gbGlzdCgpDQoNCiMgTG9vcCB0aHJvdWdoIHRoZSBuYW1lZCByYW5nZXMNCmZvciAoaSBpbiAxOm5yb3cobmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yKSkgew0KICBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl92YWx1ZSA8LSBuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3IkYE5hbWVkIFJhbmdlYFtpXQ0KICBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF92YWx1ZSA8LSBuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3IkYE5hbWVkIFJhbmdlIFNoZWV0YFtpXQ0KICANCiAgIyBTa2lwIGlmIGFueSB2YWx1ZXMgYXJlIG1pc3NpbmcNCiAgaWYgKGlzLm5hKG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3ZhbHVlKSB8fCBpcy5uYShuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF92YWx1ZSkpIHsNCiAgICBuZXh0DQogIH0NCiAgDQogIG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX2xvd2VyIDwtIHRvbG93ZXIoZ3N1YigiICIsICJfIiwgbmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3JfdmFsdWUpKQ0KICBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF9sb3dlciA8LSB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X3ZhbHVlKSkNCiAgDQogIGlmIChuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF92YWx1ZSA9PSAiTmFtZWRfUmFuZ2VzIikgew0KICAgIG5leHQgICMgU2tpcCBpdGVyYXRpb24gaWYgdGhlIHNoZWV0IGlzICJOYW1lZF9SYW5nZXMiIHRvIGF2b2lkIHJlZHVuZGFuY3kNCiAgfQ0KICANCiAgIyBSZWFkIGRhdGEgZnJvbSB0aGUgbmFtZWQgcmFuZ2UNCiAgbmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3JfZGF0YSA8LSB0cnlDYXRjaCh7DQogICAgcmVhZC54bHN4KGZpbGVfcGF0aF8xcm1fY2FsY3VsYXRvciwgbmFtZWRSZWdpb24gPSBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl92YWx1ZSkNCiAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7DQogICAgbWVzc2FnZShwYXN0ZSgiV2FybmluZzogV29ya2Jvb2sgaGFzIG5vIHN1Y2ggbmFtZWQgcmVnaW9uOiIsIG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3ZhbHVlKSkNCiAgICBOVUxMDQogIH0pDQogIA0KICBpZiAoIWlzLm51bGwobmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3JfZGF0YSkgJiYgaXMuZGF0YS5mcmFtZShuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9kYXRhKSkgew0KICAgICMgVXBkYXRlIGNvbHVtbiBuYW1lcw0KICAgIGNvbG5hbWVzKG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX2RhdGEpIDwtIGdzdWIoIlxcLiIsICIgIiwgY29sbmFtZXMobmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3JfZGF0YSkpDQogICAgIyBTdG9yZSB0aGUgZGF0YSBmcmFtZSBpbiB0aGUgbGlzdA0KICAgIG5hbWVkX3Jhbmdlc18xcm1fY2FsY3VsYXRvcl9saXN0W1tuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9sb3dlcl1dIDwtIG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX2RhdGENCiAgICAjIEFzc2lnbiB0aGUgZGF0YSBmcmFtZSB0byB0aGUgZ2xvYmFsIGVudmlyb25tZW50IHdpdGggdGhlIGxvd2VyIGNhc2UgbmFtZQ0KICAgIGFzc2lnbihuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9sb3dlciwgbmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3JfZGF0YSwgZW52aXIgPSAuR2xvYmFsRW52KQ0KICB9DQogIA0KICAjIFJlYWQgZGF0YSBmcm9tIHRoZSBzaGVldA0KICBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF9kYXRhIDwtIHRyeUNhdGNoKHsNCiAgICByZWFkLnhsc3goZmlsZV9wYXRoXzFybV9jYWxjdWxhdG9yLCBzaGVldCA9IG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X3ZhbHVlKQ0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICBtZXNzYWdlKHBhc3RlKCJXYXJuaW5nOiBXb3JrYm9vayBoYXMgbm8gc3VjaCBzaGVldDoiLCBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF92YWx1ZSkpDQogICAgTlVMTA0KICB9KQ0KICANCiAgaWYgKCFpcy5udWxsKG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X2RhdGEpICYmIGlzLmRhdGEuZnJhbWUobmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3Jfc2hlZXRfZGF0YSkpIHsNCiAgICAjIFVwZGF0ZSBjb2x1bW4gbmFtZXMNCiAgICBjb2xuYW1lcyhuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF9kYXRhKSA8LSBnc3ViKCJcXC4iLCAiICIsIGNvbG5hbWVzKG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X2RhdGEpKQ0KICAgICMgU3RvcmUgdGhlIGRhdGEgZnJhbWUgaW4gdGhlIGxpc3QNCiAgICBuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3Jfc2hlZXRzX2xpc3RbW25hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X2xvd2VyXV0gPC0gbmFtZWRfcmFuZ2VfMXJtX2NhbGN1bGF0b3Jfc2hlZXRfZGF0YQ0KICAgICMgQXNzaWduIHRoZSBkYXRhIGZyYW1lIHRvIHRoZSBnbG9iYWwgZW52aXJvbm1lbnQgd2l0aCB0aGUgbG93ZXIgY2FzZSBuYW1lDQogICAgYXNzaWduKG5hbWVkX3JhbmdlXzFybV9jYWxjdWxhdG9yX3NoZWV0X2xvd2VyLCBuYW1lZF9yYW5nZV8xcm1fY2FsY3VsYXRvcl9zaGVldF9kYXRhLCBlbnZpciA9IC5HbG9iYWxFbnYpDQogIH0NCn0NCg0KIyBEaXNwbGF5IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGxpc3RzDQojIHN0cihuYW1lZF9yYW5nZXNfMXJtX2NhbGN1bGF0b3JfbGlzdCkNCiMgc3RyKG5hbWVkX3Jhbmdlc18xcm1fY2FsY3VsYXRvcl9zaGVldHNfbGlzdCkNCg0KIyBPcHRpb25hbDogVmlldyB0aGUgY29udGVudHMgb2YgdGhlIGxpc3RzIGluIFJTdHVkaW8gVmlld2VyDQojIEluc3RlYWQgb2Ygdmlld2luZyB0aGUgd2hvbGUgbGlzdCwgdmlldyBpbmRpdmlkdWFsIGRhdGEgZnJhbWVzDQojIFVuY29tbWVudCB0aGUgYmVsb3cgbGluZXMgdG8gdmlldyBzcGVjaWZpYyBuYW1lZCByYW5nZXMgb3Igc2hlZXRzDQojIFZpZXcobmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yX2xpc3RbWyJkZW1vZ3JhcGhpYyJdXSkNCg0KIyBrbml0cjo6a2FibGUobmFtZWRfcmFuZ2VzXzFybV9jYWxjdWxhdG9yLCBmb3JtYXQgPSAibWFya2Rvd24iKSANCiMgUmVuYW1lIHRoZSBjb2x1bW4NCmNvbG5hbWVzKGNhbGN1bGF0b3JfMXJtX2J5X3BlcmNlbnRhZ2Vfc3RyZW5ndGhfbGV2ZWwpWzJdIDwtICJQZXJjZW50YWdlIG9mIDFSTSINCg0KIyBSZXBsYWNlIHBlcmlvZHMgd2l0aCBzcGFjZXMgaW4gdGhlIGNvbHVtbiBuYW1lcw0KY29sbmFtZXMoY2FsY3VsYXRvcl8xcm1fYnlfcGVyY2VudGFnZV9zdHJlbmd0aF9sZXZlbCkgPC0gZ3N1YigiXFwuIiwgIiAiLCBjb2xuYW1lcyhjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsKSkNCg0KIyBGb3JtYXQgdGhlIFBlcmNlbnRhZ2Ugb2YgMVJNIGNvbHVtbiBhcyBwZXJjZW50YWdlcyB3aXRob3V0IGRlY2ltYWwgcGxhY2VzDQpjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsJGBQZXJjZW50YWdlIG9mIDFSTWAgPC0gcGFzdGUwKA0KICByb3VuZChjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsJGBQZXJjZW50YWdlIG9mIDFSTWAgKiAxMDApLCAiJSINCikNCg0KIyBTZXQgdGhlIGxhc3QgdHdvIGNvbHVtbnMgdG8gMSBkZWNpbWFsIHBsYWNlIGlmIHRoZXkgZXhpc3QNCmlmIChuY29sKGNhbGN1bGF0b3JfMXJtX2J5X3BlcmNlbnRhZ2Vfc3RyZW5ndGhfbGV2ZWwpID4gMikgew0KICBjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsWywgKG5jb2woY2FsY3VsYXRvcl8xcm1fYnlfcGVyY2VudGFnZV9zdHJlbmd0aF9sZXZlbCktMSk6bmNvbChjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsKV0gPC0gDQogICAgcm91bmQoY2FsY3VsYXRvcl8xcm1fYnlfcGVyY2VudGFnZV9zdHJlbmd0aF9sZXZlbFssIChuY29sKGNhbGN1bGF0b3JfMXJtX2J5X3BlcmNlbnRhZ2Vfc3RyZW5ndGhfbGV2ZWwpLTEpOm5jb2woY2FsY3VsYXRvcl8xcm1fYnlfcGVyY2VudGFnZV9zdHJlbmd0aF9sZXZlbCldLCAxKQ0KfQ0KDQojIFVzZSBrbml0cjo6a2FibGUgdG8gZm9ybWF0IGFzIGEgbWFya2Rvd24gdGFibGUNCmtuaXRyOjprYWJsZShjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsLCBmb3JtYXQgPSAiaHRtbCIsIGFsaWduID0gcmVwKCdsJywgbmNvbChjYWxjdWxhdG9yXzFybV9ieV9wZXJjZW50YWdlX3N0cmVuZ3RoX2xldmVsKSkpICU+JSAgIyBVc2UgJ2h0bWwnIGZvcm1hdCBmb3Iga2FibGVfc3R5bGluZw0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUgICMgRW5zdXJlIGZ1bGwtd2lkdGggdGFibGUgd2l0aCBlcXVhbCBjb2x1bW4gd2lkdGgNCiAgY29sdW1uX3NwZWMoMTpuY29sKGNhbGN1bGF0b3JfMXJtX2J5X3BlcmNlbnRhZ2Vfc3RyZW5ndGhfbGV2ZWwpLCB3aWR0aCA9IHBhc3RlMCgxMDAgLyBuY29sKGNhbGN1bGF0b3JfMXJtX2J5X3BlcmNlbnRhZ2Vfc3RyZW5ndGhfbGV2ZWwpLCAiJSIpKQ0KDQpjYXQoIlxuXG4jIyMgSG93IHRvIENhbGN1bGF0ZSBZb3VyIDFSTVxuIikNCmNhdCgiVG8gY2FsY3VsYXRlIHRoZSBPbmUgUmVwIE1heCAoMVJNKSBiYXNlZCBvbiB0aGUgd2VpZ2h0IGxpZnRlZCBhbmQgdGhlIG51bWJlciBvZiByZXBldGl0aW9ucyBwZXJmb3JtZWQsIHVzZSB0aGUgZm9sbG93aW5nIGZvcm11bGE6XG4iKQ0KY2F0KCJZIGxicyBhdCBYIFJlcHMgLyAlIGF0IFggUmVwcyA9IFkgbGJzIDFSTVxuIikNCmNhdCgiXG5Gb3IgZXhhbXBsZSwgaWYgeW91IGRpZCA1IHJlcHMgYXQgMjAwIGxicywgYW5kIDUgcmVwcyBjb3JyZXNwb25kcyB0byA4OSUsIHRoZW4gXG4iKQ0KY2F0KCIyMDAgbGJzIC8gMC44OSA9IH4yMjUgbGJzIDFSTVxuIikNCg0KY2F0KCJcblxuIyMjIEhvdyB0byBDYWxjdWxhdGUgWW91ciBYLVJNXG4iKQ0KY2F0KCJUbyBjYWxjdWxhdGUgdGhlIFggUmVwZXRpdGlvbiBNYXggKFgtUk0pIGZyb20gYSBnaXZlbiBudW1iZXIgb2YgcmVwZXRpdGlvbnMgYW5kIHdlaWdodCBsaWZ0ZWQsIGZpcnN0IGNhbGN1bGF0ZSB0aGUgMVJNLCB0aGVuIHVzZSB0aGUgMVJNIHRvIGdldCB0aGUgWC1STS4gV2UgZG8gdGhpcyB0aHJvdWdoIHRoZSBmb2xsb3dpbmcgZm9ybXVsYTpcbiIpDQpjYXQoIlkgbGJzIGF0IFggUmVwcyAvICUgYXQgWCBSZXBzID0gWSBsYnMgMVJNXG4iKQ0KY2F0KCJcblRoZW4gbXVsdGlwbHkgYnkgdGhlIHBlcmNlbnRhZ2Ugb2YgeW91ciB0YXJnZXQgcmVwZXRpdGlvbnMgdG8gZ2V0IFgtUk06XG4iKQ0KY2F0KCIxUk0gKiAlIGF0IFRhcmdldCBSZXBzID0gWSBsYnMgWC1STVxuIikNCmNhdCgiXG5Gb3IgZXhhbXBsZSwgaWYgeW91IGRpZCA1IHJlcHMgYXQgNDUgbGJzLCBhbmQgNSByZXBzIGNvcnJlc3BvbmRzIHRvIDg5JSwgYW5kIHlvdSB3YW50IHRvIGZpbmQgdGhlIDNSTTpcbiIpDQpjYXQoIkZpcnN0LCBjYWxjdWxhdGUgdGhlIDFSTTpcbiIpDQpjYXQoIjQ1IGxicyAvIDAuODkgPSB+NTAuNTYgbGJzIDFSTVxuIikNCmNhdCgiVGhlbiBjYWxjdWxhdGUgdGhlIDNSTSB1c2luZyB0aGUgMyByZXAgcGVyY2VudGFnZSAoOTQlKTpcbiIpDQpjYXQoIjUwLjU2IGxicyAqIDAuOTQgPSB+NDcuNTMgbGJzIDNSTVxuIikNCg0KYGBgDQoNCiMgS0RGIFdPUktCT09LDQojIyBBIEJyaWVmIE92ZXJ2aWV3IA0KDQpUaGlzIHByb2plY3QgZGVyaXZlcyBkYXRhIGZyb20gdGhlIHByaW1hcnkgd29ya2Jvb2ssIG5hbWVkIEtERiAoS2VuIERvZXMgRml0bmVzcylbXjExXS4gRm9yIHllYXJzLCBJIHJlY29yZGVkIG15IHBlcnNvbmFsIHBlcmZvcm1hbmNlIHRvIHJlY2FsbCBteSBwcmV2aW91cyB3b3Jrb3V0cyBmb3IgdGhlIG5leHQgc2Vzc2lvbiwgYXMgSSBvZnRlbiBoYWQgdHJvdWJsZSByZW1lbWJlcmluZyB0aGUgd2VpZ2h0cyB1c2VkLiBBcyBJIHN0YXJ0ZWQgbGVhcm5pbmcgYW5hbHl0aWNzIGFuZCBjb2RpbmcgbWV0aG9kcywgSSB3YW50ZWQgdG8gYXBwbHkgdGhvc2UgdGVjaG5pcXVlcyB0byBzb21ldGhpbmcgcGVyc29uYWwgYW5kIGFwcGxpY2FibGUsIHdoaWNoIGxlZCB0byB0aGlzIHJlcG9ydC4gSXQgaGFzIGluZGVlZCBiZWVuIGEgbGVhcm5pbmcgcHJvY2Vzcy4gTm90IHRvIG1lbnRpb24sIHRoZSBkYXRhIGNsZWFuaW5nIGFuZCBvcmdhbml6YXRpb24gaGF2ZSBhbHNvIGJlZW4gYSB0aW1lLWNvbnN1bWluZyBwcm9jZXNzLiBBcyBvZiBgciBTeXMuRGF0ZSgpYCwgdGhlIGNvbnRlbnRzIG9mIHRoaXMgd29ya2Jvb2sgaW5jbHVkZSBhIGNvbWJpbmF0aW9uIG9mIHBlcmZvcm1hbmNlIGRhdGEsIGZvcm11bGFzLCBjb2RlLCBhbmQgcmVmZXJlbmNlIHJlc291cmNlcy4gVW50aWwgYSBzZXBhcmF0ZSBmaWxlIHdpdGggYSBtb3JlIHVzZXItZnJpZW5kbHkgZXhwZXJpZW5jZSBpcyBhdmFpbGFibGUgd2l0aG91dCB0aGUgbmVjZXNzYXJ5IGJhY2stZW5kIGNvZGluZyBpbmZvcm1hdGlvbiwgdGhpcyBmaWxlIHdpbGwgaGF2ZSB0byBzdWZmaWNlLg0KDQpgYGB7ciByZWFkX2tlbl9kb2VzX2ZpdG5lc3MsIGV2YWw9VFJVRX0NCg0KIyBSZWFkIEV4Y2VsIGZpbGUgYW5kIERlZmluZSBmaWxlIHBhdGguDQojIFJlcGxhY2UgXCB3aXRoIC8vIChXaW5kb3dzIGNvbXBhdGliaWxpdHkpLiANCmZpbGVfcGF0aF9rZGYgPC0gIkM6Ly9Vc2Vycy8va2VuZHIvL09uZURyaXZlLy9Eb2N1bWVudHMvL0RhdGEgQW5hbHl0aWNzLy9LZW5Eb2VzRml0bmVzcy8vS2VuIERvZXMgRml0bmVzcyBGaW5hbC54bHN4Ig0KDQojIFJhdyBTdHJpbmcgTGl0ZXJhbDogU3VwcG9zZWRseSB5b3UgY2FuIGFsc28gdXNlIGEgcmF3IHN0cmluZyBsaXRlcmFsIGJ5IHByZWZpeGluZyB0aGUgc3RyaW5nIHdpdGggciBvciBSLiBUaGlzIHRlbGxzIFIgdG8gaW50ZXJwcmV0IHRoZSBzdHJpbmcgYXMtaXMsIHdpdGhvdXQgcHJvY2Vzc2luZyBlc2NhcGUgc2VxdWVuY2VzLiBIb3dldmVyLCBkb2luZyB0aGUgZm9sbG93aW5nIG1ldGhvZCBiZWxvdyBtYXkgcmVzdWx0IGluICJtYWxmb3JtZWQgcmF3IHN0cmluZyBsaXRlcmFsICg8aW5wdXQ+OjE6MTYpIiBhcyBpdCBoYXMgZm9yIG1lLiBUaGVyZWZvcmUgY29uc2lkZXIgdG8gdXNlIHRoZSBtZXRob2QgYWJvdmUgaW5zdGVhZC4NCmBgYA0KDQpgYGB7ciBuYW1lZF9yYW5nZXNfa2RmLCBldmFsPVRSVUUsIHJlc3VsdHM9J2hpZGUnfQ0KDQpsaWJyYXJ5KG9wZW54bHN4KQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojIFNldCB0aGUgZmlsZSBwYXRoDQojIGZpbGVfcGF0aF9rZGYgPC0gInlvdXJfZmlsZV9wYXRoX2hlcmUueGxzeCINCg0KIyBSZWFkIE5hbWVkIFJhbmdlczogUmVhZHMgYSBzcGVjaWZpYyBzaGVldCBuYW1lZCAiTmFtZWRfUmFuZ2VzIiB0aGF0IHByZXN1bWFibHkgY29udGFpbnMgbWV0YWRhdGEgYWJvdXQgb3RoZXIgbmFtZWQgcmFuZ2VzIGluIHRoZSB3b3JrYm9vay4gSXQga2VlcHMgb25seSB0aGUgY29sdW1ucyByZWxhdGVkIHRvIG5hbWVkIHJhbmdlcyBhbmQgdGhlaXIgcmVzcGVjdGl2ZSBzaGVldHMuDQpuYW1lZF9yYW5nZXNfa2RmIDwtIHJlYWRfZXhjZWwoZmlsZV9wYXRoX2tkZiwgc2hlZXQgPSAiTmFtZWRfUmFuZ2VzIikNCnNoZWV0X25hbWVzX2ZpbHRlcmVkIDwtIHVuaXF1ZShuYW1lZF9yYW5nZXNfa2RmJGBOYW1lZCBSYW5nZSBTaGVldGApDQpuYW1lZF9yYW5nZXNfa2RmIDwtIG5hbWVkX3Jhbmdlc19rZGZbbmFtZWRfcmFuZ2VzX2tkZiRgTmFtZWQgUmFuZ2UgU2hlZXRgICVpbiUgc2hlZXRfbmFtZXNfZmlsdGVyZWQsIGMoIk5hbWVkIFJhbmdlIiwgIk5hbWVkIFJhbmdlIFNoZWV0IildDQoNCiMgVmlldyB0aGUgZGF0YSBmcmFtZSBpZiBuZWVkZWQgKG5vdCBkdXJpbmcga25pdHRpbmcpLiBWaWV3IGZ1bmN0aW9uIG9wZW5zIHRoZSByYXdfZGF0YSBkYXRhZnJhbWUgaW4gdGhlIFJTdHVkaW8gZGF0YSB2aWV3ZXIgZm9yIGludGVyYWN0aXZlIGV4cGxvcmF0aW9uLg0KVmlldyhuYW1lZF9yYW5nZXNfa2RmKQ0KDQojIERpc3BsYXkgdGhlIGRhdGFmcmFtZSB1c2luZyBrbml0cjo6a2FibGUgDQpudW1fY29sdW1ucyA8LSBuY29sKG5hbWVkX3Jhbmdlc19rZGYpDQpjb2x1bW5fd2lkdGggPC0gMTAwIC8gbnVtX2NvbHVtbnMNCg0KIyBEaXNwbGF5IHRoZSBkYXRhZnJhbWUgdXNpbmcga25pdHI6OmthYmxlIA0Ka25pdHI6OmthYmxlKG5hbWVkX3Jhbmdlc19rZGYsIGZvcm1hdCA9ICJtYXJrZG93biIsIGNvbC5uYW1lcyA9IGMoIk5hbWVkIFJhbmdlIiwgIk5hbWVkIFJhbmdlIFNoZWV0IikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMTpudW1fY29sdW1ucywgd2lkdGggPSBwYXN0ZTAoY29sdW1uX3dpZHRoLCAiJSIpKQ0KDQojIE5hbWVkIFJhbmdlcyBMb3dlciBDYXNlIEFzc2lnbm1lbnQgLSBEeW5hbWljIERhdGEgTG9hZGluZyBhbmQgVmFyaWFibGUgQXNzaWdubWVudA0KIyAtIExvb3AgVGhyb3VnaCBOYW1lZCBSYW5nZXM6IFRoZSBzY3JpcHQgaXRlcmF0ZXMgb3ZlciBlYWNoIHJvdyBvZiB0aGUgbmFtZWRfcmFuZ2VzX2tkZiBkYXRhZnJhbWUuIEZvciBlYWNoIHJvdywgaXQgcmVhZHMgdGhlIGFjdHVhbCBkYXRhIGZyb20gdGhlIEV4Y2VsIHdvcmtib29rIGZvciBib3RoIHRoZSBuYW1lZCByYW5nZSBhbmQgaXRzIGNvcnJlc3BvbmRpbmcgc2hlZXQuDQojIC0gQ29uZGl0aW9uYWwgU2tpcHBpbmc6IElmIHRoZSBzaGVldCBmb3IgYSBuYW1lZCByYW5nZSBpcyBpdHNlbGYgIk5hbWVkX1JhbmdlcyIsIHRoZSBsb29wIHNraXBzIHRvIHRoZSBuZXh0IGl0ZXJhdGlvbiB0byBhdm9pZCByZWR1bmRhbmN5IG9yIHBvdGVudGlhbCBlcnJvcnMuDQojIC0gRHluYW1pYyBWYXJpYWJsZSBBc3NpZ25tZW50OiBVc2luZyB0aGUgYXNzaWduKCkgZnVuY3Rpb24sIGl0IGR5bmFtaWNhbGx5IGNyZWF0ZXMgdmFyaWFibGVzIGluIHRoZSBSIGVudmlyb25tZW50IG5hbWVkIGFmdGVyIGVhY2ggbmFtZWQgcmFuZ2UgYW5kIHNoZWV0LiBUaGlzIGlzIGRvbmUgaW4gbG93ZXJjYXNlIHRvIHN0YW5kYXJkaXplIHZhcmlhYmxlIG5hbWVzLg0KIyAtIFJlYWRpbmcgRGF0YTogRGF0YSBpcyByZWFkIGludG8gdGhlc2UgZHluYW1pY2FsbHkgbmFtZWQgdmFyaWFibGVzIHVzaW5nIHRoZSByZWFkLnhsc3goKSBmdW5jdGlvbiwgd2hpY2ggY2FuIGFjY2VzcyBib3RoIHNwZWNpZmljIG5hbWVkIHJhbmdlcyBhbmQgZW50aXJlIHNoZWV0cy4NCg0KIyBDcmVhdGUgbGlzdHMgdG8gc3RvcmUgZGF0YSBmcmFtZXMNCm5hbWVkX3Jhbmdlc19rZGZfbGlzdCA8LSBsaXN0KCkNCm5hbWVkX3Jhbmdlc19rZGZfc2hlZXRzX2xpc3QgPC0gbGlzdCgpDQoNCiMgTG9vcCB0aHJvdWdoIHRoZSBuYW1lZCByYW5nZXMNCmZvciAoaSBpbiAxOm5yb3cobmFtZWRfcmFuZ2VzX2tkZikpIHsNCiAgbmFtZWRfcmFuZ2Vfa2RmX3ZhbHVlIDwtIG5hbWVkX3Jhbmdlc19rZGYkYE5hbWVkIFJhbmdlYFtpXQ0KICBuYW1lZF9yYW5nZV9rZGZfc2hlZXRfdmFsdWUgPC0gbmFtZWRfcmFuZ2VzX2tkZiRgTmFtZWQgUmFuZ2UgU2hlZXRgW2ldDQogIG5hbWVkX3JhbmdlX2tkZl9sb3dlciA8LSB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIG5hbWVkX3JhbmdlX2tkZl92YWx1ZSkpDQogIG5hbWVkX3JhbmdlX2tkZl9zaGVldF9sb3dlciA8LSB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIG5hbWVkX3JhbmdlX2tkZl9zaGVldF92YWx1ZSkpDQogIA0KICBpZiAobmFtZWRfcmFuZ2Vfa2RmX3NoZWV0X3ZhbHVlID09ICJOYW1lZF9SYW5nZXMiKSB7DQogICAgbmV4dCAgIyBTa2lwIGl0ZXJhdGlvbiBpZiB0aGUgc2hlZXQgaXMgIk5hbWVkX1JhbmdlcyIgdG8gYXZvaWQgcmVkdW5kYW5jeQ0KICB9DQogIA0KICAjIFJlYWQgZGF0YSBmcm9tIHRoZSBuYW1lZCByYW5nZQ0KICBuYW1lZF9yYW5nZV9rZGZfZGF0YSA8LSB0cnlDYXRjaCh7DQogICAgcmVhZC54bHN4KGZpbGVfcGF0aF9rZGYsIG5hbWVkUmVnaW9uID0gbmFtZWRfcmFuZ2Vfa2RmX3ZhbHVlKQ0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICBtZXNzYWdlKHBhc3RlKCJXYXJuaW5nOiBXb3JrYm9vayBoYXMgbm8gc3VjaCBuYW1lZCByZWdpb246IiwgbmFtZWRfcmFuZ2Vfa2RmX3ZhbHVlKSkNCiAgICBOVUxMDQogIH0pDQogIA0KICBpZiAoIWlzLm51bGwobmFtZWRfcmFuZ2Vfa2RmX2RhdGEpICYmIGlzLmRhdGEuZnJhbWUobmFtZWRfcmFuZ2Vfa2RmX2RhdGEpKSB7DQogICAgIyBVcGRhdGUgY29sdW1uIG5hbWVzDQogICAgY29sbmFtZXMobmFtZWRfcmFuZ2Vfa2RmX2RhdGEpIDwtIGdzdWIoIlxcLiIsICIgIiwgY29sbmFtZXMobmFtZWRfcmFuZ2Vfa2RmX2RhdGEpKQ0KICAgICMgU3RvcmUgdGhlIGRhdGEgZnJhbWUgaW4gdGhlIGxpc3QNCiAgICBuYW1lZF9yYW5nZXNfa2RmX2xpc3RbW25hbWVkX3JhbmdlX2tkZl9sb3dlcl1dIDwtIG5hbWVkX3JhbmdlX2tkZl9kYXRhDQogICAgIyBBc3NpZ24gdGhlIGRhdGEgZnJhbWUgdG8gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCB3aXRoIHRoZSBsb3dlciBjYXNlIG5hbWUNCiAgICBhc3NpZ24obmFtZWRfcmFuZ2Vfa2RmX2xvd2VyLCBuYW1lZF9yYW5nZV9rZGZfZGF0YSwgZW52aXIgPSAuR2xvYmFsRW52KQ0KICB9DQogIA0KICAjIFJlYWQgZGF0YSBmcm9tIHRoZSBzaGVldA0KICBuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSA8LSB0cnlDYXRjaCh7DQogICAgcmVhZC54bHN4KGZpbGVfcGF0aF9rZGYsIHNoZWV0ID0gbmFtZWRfcmFuZ2Vfa2RmX3NoZWV0X3ZhbHVlKQ0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICBtZXNzYWdlKHBhc3RlKCJXYXJuaW5nOiBXb3JrYm9vayBoYXMgbm8gc3VjaCBzaGVldDoiLCBuYW1lZF9yYW5nZV9rZGZfc2hlZXRfdmFsdWUpKQ0KICAgIE5VTEwNCiAgfSkNCiAgDQogIGlmICghaXMubnVsbChuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSkgJiYgaXMuZGF0YS5mcmFtZShuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSkpIHsNCiAgICAjIFVwZGF0ZSBjb2x1bW4gbmFtZXMNCiAgICBjb2xuYW1lcyhuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSkgPC0gZ3N1YigiXFwuIiwgIiAiLCBjb2xuYW1lcyhuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSkpDQogICAgIyBTdG9yZSB0aGUgZGF0YSBmcmFtZSBpbiB0aGUgbGlzdA0KICAgIG5hbWVkX3Jhbmdlc19rZGZfc2hlZXRzX2xpc3RbW25hbWVkX3JhbmdlX2tkZl9zaGVldF9sb3dlcl1dIDwtIG5hbWVkX3JhbmdlX2tkZl9zaGVldF9kYXRhDQogICAgIyBBc3NpZ24gdGhlIGRhdGEgZnJhbWUgdG8gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCB3aXRoIHRoZSBsb3dlciBjYXNlIG5hbWUNCiAgICBhc3NpZ24obmFtZWRfcmFuZ2Vfa2RmX3NoZWV0X2xvd2VyLCBuYW1lZF9yYW5nZV9rZGZfc2hlZXRfZGF0YSwgZW52aXIgPSAuR2xvYmFsRW52KQ0KICB9DQp9DQoNCiMgRGlzcGxheSB0aGUgc3RydWN0dXJlIG9mIHRoZSBsaXN0cw0KIyBzdHIobmFtZWRfcmFuZ2VzX2tkZl9saXN0KQ0KIyBzdHIobmFtZWRfcmFuZ2VzX2tkZl9zaGVldHNfbGlzdCkNCg0KIyBPcHRpb25hbDogVmlldyB0aGUgY29udGVudHMgb2YgdGhlIGxpc3RzIGluIFJTdHVkaW8gVmlld2VyDQojIEluc3RlYWQgb2Ygdmlld2luZyB0aGUgd2hvbGUgbGlzdCwgdmlldyBpbmRpdmlkdWFsIGRhdGEgZnJhbWVzDQojIFVuY29tbWVudCB0aGUgYmVsb3cgbGluZXMgdG8gdmlldyBzcGVjaWZpYyBuYW1lZCByYW5nZXMgb3Igc2hlZXRzDQojIFZpZXcobmFtZWRfcmFuZ2VzX2tkZl9saXN0W1siZGVtb2dyYXBoaWMiXV0pDQojIFZpZXcoZGVtb2dyYXBoaWMpDQoNCiMga25pdHI6OmthYmxlKG5hbWVkX3Jhbmdlc19rZGYsIGZvcm1hdCA9ICJtYXJrZG93biIpIA0KDQoNCmBgYA0KDQpUaGUgZm9sbG93aW5nIHRhYmxlIGZyb20gS0RGIGFkZHJlc3NlcyB0aGUgcHJpbWFyeSBzaGVldHMgaGVscGZ1bCBpbiBpbXByb3Zpbmcgd29ya291dCBwZXJmb3JtYW5jZSBhbmQgcGVyZm9ybWFuY2UgYW5hbHlzZXMuIFNvbWUgb2YgdGhlIHNoZWV0cyBsaXN0ZWQgc2VydmUgYXMgc2VjdGlvbnMgaW4gdGhpcyByZXBvcnQuDQoNCmBgYHtyIHRhYmxlX29mX2NvbnRlbnRzX25yICwgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQpjb2xuYW1lcyh0YWJsZV9vZl9jb250ZW50c19ucilbMl0gPC0gIkVYUExBTkFUSU9OIiANCnRhYmxlX29mX2NvbnRlbnRzX25yIDwtIHRhYmxlX29mX2NvbnRlbnRzX25yICU+JQ0KICBzZWxlY3QoLWBDb2RpbmcgTm90ZXNgKQ0KIyBwcmludCh0YWJsZV9vZl9jb250ZW50c19ucikNCiMgVmlldyh0YWJsZV9vZl9jb250ZW50c19ucikNCiMgc3RyKHRhYmxlX29mX2NvbnRlbnRzX25yKQ0KDQojIEZpbHRlciBUT0MgZm9yIGRpc3BsYXkgYnkgZmlsdGVyaW5nIHRvIHRoZSBzcGVjaWZpYyByb3dzLg0KdGFibGVfb2ZfY29udGVudHNfbnJfZGlzcGxheSA8LSB0YWJsZV9vZl9jb250ZW50c19uclsyOjcsIF0NCg0KIyBNYWludGFpbiBsaW5lIGJyZWFrcyBpbiBjaGFyYWN0ZXIgY29sdW1ucw0KdGFibGVfb2ZfY29udGVudHNfbnJfZGlzcGxheSA8LSB0YWJsZV9vZl9jb250ZW50c19ucl9kaXNwbGF5ICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCB+Z3N1YigiXG4iLCAiPGJyPiIsIC4pKQ0KDQojIEtuaXQgdGFibGUgd2l0aG91dCByb3cgbmFtZXMNCmtuaXRyOjprYWJsZSh0YWJsZV9vZl9jb250ZW50c19ucl9kaXNwbGF5LCBmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZT1GQUxTRSwgcm93Lm5hbWVzID0gRkFMU0UpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKQ0KDQpgYGANCg0KIyBERU1PR1JBUEhJQw0KVGhpcyBzZWN0aW9uIGluY2x1ZGVzIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uIGFib3V0IGluZGl2aWR1YWxzIG9yIGdyb3Vwcywgc3VjaCBhcyBhZ2UsIGdlbmRlciwgYW5kIG90aGVyIHJlbGV2YW50IGNoYXJhY3RlcmlzdGljcy4gTGlzdHMgaW5mb3JtYXRpb24gZm9yIGluZGl2aWR1YWxzIHdpdGggYXQgbGVhc3Qgb25lIHNldCBvZiBkYXRhIGluIHRoZSB3b3JrYm9vay4gDQoNCmBgYHtyIGRlbW9ncmFwaGljLCBldmFsPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCg0KIyBwcmludChkZW1vZ3JhcGhpY19ucikNCiMgVmlldyhkZW1vZ3JhcGhpY19ucikNCiMgc3RyKGRlbW9ncmFwaGljX25yKQ0KDQojIFVwZGF0ZSBhbGwgY2hhcmFjdGVyIGNvbHVtbnMgYW5kIHJlcGxhY2UgYW55IGluc3RhbmNlIG9mICItIiB3aXRoIE5BLiBWYWx1ZXMgbG9vayBiZXR0ZXIgd2l0aCBOQSB0aGFuIGFuIGVtcHR5IHN0cmluZy4NCmRlbW9ncmFwaGljX25yIDwtIGRlbW9ncmFwaGljX25yICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCB+bmFfaWYoLiwgIi0iKSkNCg0KIyBSZW1vdmUgcm93cyB3aGVyZSBOYW1lIGlzIE5BDQpkZW1vZ3JhcGhpY19uciA8LSBkZW1vZ3JhcGhpY19uciAlPiUNCiAgZmlsdGVyKCFpcy5uYShOYW1lKSkNCg0KIyBDb252ZXJ0IEJpcnRoZGF0ZSBjb2x1bW4gZnJvbSBjaGFyYWN0ZXIgdG8gbnVtZXJpYyBhbmQgdGhlbiB0byBEYXRlIGZvcm1hdA0KZGVtb2dyYXBoaWNfbnIkJ0JpcnRoZGF0ZScgPC0gYXMubnVtZXJpYyhkZW1vZ3JhcGhpY19uciQnQmlydGhkYXRlJykNCmRlbW9ncmFwaGljX25yJCdCaXJ0aGRhdGUnIDwtIGFzLkRhdGUoZGVtb2dyYXBoaWNfbnIkJ0JpcnRoZGF0ZScsIG9yaWdpbiA9ICIxOTcwLTAxLTAxIikgDQoNCiMgQWRqdXN0IHRoZSBkYXRlcyBieSBzdWJ0cmFjdGluZyBYIHllYXJzDQpkZW1vZ3JhcGhpY19uciRgQmlydGhkYXRlYCA8LSBkZW1vZ3JhcGhpY19uciRgQmlydGhkYXRlYCAtIHllYXJzKDcwKQ0KDQojIFZlcmlmeSB0aGUgY29udmVyc2lvbg0KIyBoZWFkKGRlbW9ncmFwaGljX25yJGBCaXJ0aGRhdGVgKQ0KDQojIFNlbGVjdCB0aGUgc3BlY2lmaWMgY29sdW1ucw0KZGVtb2dyYXBoaWNfbnIgPC0gZGVtb2dyYXBoaWNfbnIgJT4lDQogIHNlbGVjdChOYW1lLCBCaXJ0aGRhdGUsIEFnZSwgQ2l0eSkgJT4lDQogIGFycmFuZ2UoTmFtZSkNCg0KIyBwcmludChkZW1vZ3JhcGhpY19ucikNCiMgc3RyKGRlbW9ncmFwaGljX25yKQ0KIyBWaWV3KGRlbW9ncmFwaGljX25yKQ0KDQojIENyZWF0ZSBkZW1vZ3JhcGhpY19kaXNwbGF5IGZvciBkaXNwbGF5aW5nIHRoZSB0YWJsZQ0KZGVtb2dyYXBoaWNfZGlzcGxheSA8LSBkZW1vZ3JhcGhpY19uciAlPiUNCiAgbXV0YXRlKE5hbWUgPSBnc3ViKCJfIiwgIiAiLCBOYW1lKSkNCg0KIyBEaXNwbGF5IHRoZSB0YWJsZSB1c2luZyBrbml0cjo6a2FibGUNCmtuaXRyOjprYWJsZShkZW1vZ3JhcGhpY19kaXNwbGF5LCBmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEZBTFNFKSAlPiUNCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSkgJT4lDQogICMgY29sdW1uX3NwZWMoMTpudW1fY29sdW1ucywgd2lkdGggPSBwYXN0ZTAoY29sdW1uX3dpZHRoLCAiJSIpKSAlPiUgIyBFcXVhbCBjb2x1bW4gd2lkdGgNCiAgcHJpbnQoKQ0KDQojIHN0cihkZW1vZ3JhcGhpY19ucikNCiMgc3RyKGRlbW9ncmFwaGljX2Rpc3BsYXkpDQpgYGANCg0KIyBWSVRBTFMNClRoZSAiVml0YWxzIiBzZWN0aW9uIHRyYWNrcyBrZXkgaGVhbHRoIG1ldHJpY3Mgc3VjaCBhcyB3ZWlnaHQsIGJvZHkgbWVhc3VyZW1lbnRzLCBhbmQgaGVhcnQgcmF0ZSB0byBtb25pdG9yIHByb2dyZXNzLCBzZXQgcGVyc29uYWxpemVkIGZpdG5lc3MgZ29hbHMsIGFuZCBpZGVudGlmeSBwYXR0ZXJucyBvciBwb3RlbnRpYWwgaGVhbHRoIHJpc2tzLiBCeSBwcm92aWRpbmcgYSBjb21wcmVoZW5zaXZlIHZpZXcgb2YgYW4gaW5kaXZpZHVhbCdzIGhlYWx0aCwgaXQgZW5hYmxlcyBkYXRhLWRyaXZlbiBkZWNpc2lvbnMgZm9yIGFkanVzdGluZyBmaXRuZXNzIHBsYW5zIGFuZCBlbnN1cmVzIGEgYmFsYW5jZWQgYXBwcm9hY2ggdG8gYWNoaWV2aW5nIGxvbmctdGVybSBmaXRuZXNzIGdvYWxzLiBSZWd1bGFyIHVwZGF0ZXMgYW5kIHZpc3VhbCB0b29scyBsaWtlIGNoYXJ0cyBoZWxwIGluIHVuZGVyc3RhbmRpbmcgdHJlbmRzIGFuZCBtb3RpdmF0aW5nIGNvbnRpbnVlZCBlZmZvcnQuIElmIHBlcmZvcm1hbmNlIGRhdGEgaXMgdGhlIGJyYWluIG9mIHRoaXMgcmVwb3J0LCB0aGVuIHZpdGFscyBhcmUgdGhlIGhlYXJ04oCUcHVuIGludGVuZGVkLg0KDQo8IS0tICMjIFZpdGFscyBEYXRhZnJhbWUtLT4NCmBgYHtyIHZpdGFsc19kZl90cmFuc2Zvcm1hdGlvbiwgZXZhbD1UUlVFfQ0KDQojIFNlbGVjdCB0aGUgZGVzaXJlZCBzaGVldA0Kc2VsZWN0ZWRfc2hlZXQgPC0gIlZpdGFscyINCnZpdGFsc19kYXRhIDwtIHJlYWRfZXhjZWwoZmlsZV9wYXRoX2tkZiwgc2hlZXQgPSBzZWxlY3RlZF9zaGVldCkNCg0KIyBEaXNwbGF5IGZpcnN0IGZldyByb3dzIGFuZCBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFmcmFtZS4gUnVuIGZvciBjb25maXJtYXRpb24gYXMgbmVlZGVkLg0KIyBoZWFkKHZpdGFsc19kYXRhKQ0KIyBzdHIodml0YWxzX2RhdGEpDQoNCiMgQ29udmVydCBzZWxlY3RlZCBjb2x1bW5zIHRvIG51bWVyaWMNCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gY29udmVydCBjb2x1bW5zIHRvIG51bWVyaWMsIGhhbmRsaW5nIG5vbi1udW1lcmljIHZhbHVlcyBncmFjZWZ1bGx5LiBJbiB0aGlzIGFwcHJvYWNoLCB0aGUgY29udmVydF90b19udW1lcmljIGZ1bmN0aW9uIGNoZWNrcyBmb3Igbm9uLW51bWVyaWMgYW5kIGluZmluaXRlIHZhbHVlcyBhZnRlciBhdHRlbXB0aW5nIHRoZSBjb252ZXJzaW9uIHVzaW5nIGFzLm51bWVyaWMuIFRoaXMgaGVscHMgZW5zdXJlIHRoYXQgcHJvYmxlbWF0aWMgdmFsdWVzIGFyZSByZXBsYWNlZCB3aXRoIE5BLCBhbmQgdGhlIGNvbHVtbiByZXRhaW5zIGl0cyBudW1lcmljIG5hdHVyZS4NCmNvbnZlcnRfdG9fbnVtZXJpYyA8LSBmdW5jdGlvbih4KSB7DQogIG51bWVyaWNfdmFsdWVzIDwtIGFzLm51bWVyaWMoeCkgICAgICAgIyBUcnkgY29udmVydGluZyB0byBudW1lcmljDQogIGlmZWxzZShpcy5uYShudW1lcmljX3ZhbHVlcykgfCBpcy5pbmZpbml0ZShudW1lcmljX3ZhbHVlcyksIE5BLCBudW1lcmljX3ZhbHVlcykgIyBSZXR1cm4gTkEgaWYgY29udmVyc2lvbiBmYWlscyBvciByZXN1bHRzIGluIGluZmluaXRlDQp9DQoNCiMgQXBwbHkgdGhlIGNvbnZlcnNpb24gZnVuY3Rpb24gdG8gc3BlY2lmaWMgY29sdW1ucyBpbiB0aGUgdml0YWxzIGRhdGENCnZpdGFsc19kYXRhIDwtIHZpdGFsc19kYXRhICU+JQ0KICBtdXRhdGVfYXQodmFycyhgU3lzdG9saWNfQmxvb2RfUHJlc3N1cmVfKFRvcF9OdW1iZXJfMTIwKWAsIGBEaWFzdG9saWNfQmxvb2RfUHJlc3N1cmVfKEJvdHRvbV9OdW1iZXJfODApYCwgUHVsc2UsIEhlYXJ0X1JhdGUsIEJNSSwgYEJvZHlfRmF0XyVgKSwgY29udmVydF90b19udW1lcmljKQ0KDQojIENvbnZlcnQgJ0RhdGUnIGNvbHVtbiB0byBkYXRlIGZvcm1hdA0Kdml0YWxzX2RhdGEkRGF0ZSA8LSBhcy5EYXRlKHZpdGFsc19kYXRhJERhdGUsIGZvcm1hdCA9ICIlbS8lZC8lWSIpDQoNCiMgSGFuZGxlIG1pc3NpbmcgdGltZSB2YWx1ZXMgYW5kIGNvbnZlcnQgdGltZSB0byBobXMgZm9ybWF0DQojIHZpdGFsc19kYXRhJFRpbWUgPC0gaG1zKHZpdGFsc19kYXRhJFRpbWUpICNDb2RlIEJhZDsgIkVycm9yOiBBbGwgYXJndW1lbnRzIG11c3QgYmUgbnVtZXJpYyBvciBOQSIgVGhlcmVmb3JlOg0Kdml0YWxzX2RhdGEkVGltZSA8LSBpZmVsc2Uodml0YWxzX2RhdGEkVGltZSA9PSAiLSIsIE5BLCB2aXRhbHNfZGF0YSRUaW1lKQ0Kdml0YWxzX2RhdGEkVGltZSA8LSBhcy5udW1lcmljKHZpdGFsc19kYXRhJFRpbWUpICAgICAgICAgICAgICAgICMgQ29udmVydCB0aW1lIHRvIG51bWVyaWMgYXNzdW1pbmcgaXQncyBpbiBhIHN1aXRhYmxlIGZvcm1hdA0Kdml0YWxzX2RhdGEkVGltZSA8LSBhc19obXModml0YWxzX2RhdGEkVGltZSAqIDg2NDAwKSAgICAgICAgICAgICMgQ29udmVydCBudW1lcmljIHRpbWUgdG8gaG1zIGZvcm1hdCAoc2Vjb25kcyBpbiBhIGRheSkgIA0KDQojIFRoZSBWaWV3IGZ1bmN0aW9uIGlzIHVzZWQgdG8gb3BlbiB0aGUgcmF3X2RhdGEgZGF0YWZyYW1lIGluIHRoZSBSU3R1ZGlvIGRhdGEgdmlld2VyIGZvciBpbnRlcmFjdGl2ZSBleHBsb3JhdGlvbi4NClZpZXcodml0YWxzX2RhdGEpICNSdW4gdGhpcyBsaW5lIG9mIGNvZGUgdG8gdmlldyB0YWJsZS4gRG9lcyBub3QgYXBwbHkgd2l0aCBrbml0Lg0KDQojIFRoZSBwcmludCBmdW5jdGlvbiBpcyB1c2VkIHRvIGRpc3BsYXkgdGhlIHRyYW5zZm9ybWVkIHJhd19kYXRhIGRhdGFmcmFtZSBpbiB0aGUgUiBjb25zb2xlLg0KcHJpbnQodml0YWxzX2RhdGEpDQoNCiMgc3RyIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZGlzcGxheSB0aGUgc3RydWN0dXJlIG9mIHRoZSByYXdfZGF0YSBkYXRhZnJhbWUuDQpzdHIodml0YWxzX2RhdGEpDQpgYGANCg0KDQojIyBWaXRhbHMgQ2F0ZWdvcnkgDQpUaGUgVml0YWxzIGNvbHVtbnMgcHJvdmlkZSBhIGxpc3Qgb2YgbWVhc3VyZW1lbnQgY2F0ZWdvcmllcyBhdmFpbGFibGUgZm9yIGZ1cnRoZXIgYW5hbHlzaXMuDQoNCmBgYHtyIHZpdGFsc19kZl9jb2x1bW5zLCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQoNCiMgRGlzcGxheSB0aGUgbW9kaWZpZWQgY29sdW1uIG5hbWVzIHdpdGggc3BhY2VzIGluc3RlYWQgb2YgdW5kZXJzY29yZXMNCnZpdGFsc19jb2x1bW5zIDwtIHZpdGFsc19kYXRhDQojIFJlcGxhY2UgdW5kZXJzY29yZXMgd2l0aCBzcGFjZXMgaW4gY29sdW1uIG5hbWVzDQpjb2xuYW1lcyh2aXRhbHNfY29sdW1ucykgPC0gZ3N1YigiXyIsICIgIiwgY29sbmFtZXModml0YWxzX2NvbHVtbnMpKQ0KDQojIEV4dHJhY3QgY29sdW1uIG5hbWVzIHZpdGFsc19jb2x1bW5zDQpjb2x1bW5fbmFtZXMgPC0gY29sbmFtZXModml0YWxzX2NvbHVtbnMpDQojIHByaW50KGNvbHVtbl9uYW1lcykNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcw0KbnVtX25hbWVzIDwtIGxlbmd0aChjb2x1bW5fbmFtZXMpDQoNCiMgQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgbmFtZXMgcGVyIGNvbHVtbg0KbmFtZXNfcGVyX2NvbHVtbiA8LSBjZWlsaW5nKG51bV9uYW1lcyAvIDIpDQoNCiMgU3BsaXQgdGhlIG5hbWVzIGludG8gdHdvIGNvbHVtbnMNCmNvbHVtbl8xIDwtIGNvbHVtbl9uYW1lc1sxOm1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpXQ0KY29sdW1uXzIgPC0gY29sdW1uX25hbWVzWyhtaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKSArIDEpOm51bV9uYW1lc10NCg0KIyBQYWQgdGhlIHNob3J0ZXIgY29sdW1uIHdpdGggTkEgdmFsdWVzIGlmIG5lY2Vzc2FyeQ0KaWYobGVuZ3RoKGNvbHVtbl8xKSA8IGxlbmd0aChjb2x1bW5fMikpIHsNCiAgY29sdW1uXzEgPC0gYyhjb2x1bW5fMSwgcmVwKCIiLCBsZW5ndGgoY29sdW1uXzIpIC0gbGVuZ3RoKGNvbHVtbl8xKSkpDQp9IGVsc2UgaWYobGVuZ3RoKGNvbHVtbl8yKSA8IGxlbmd0aChjb2x1bW5fMSkpIHsNCiAgY29sdW1uXzIgPC0gYyhjb2x1bW5fMiwgcmVwKCIiLCBsZW5ndGgoY29sdW1uXzEpIC0gbGVuZ3RoKGNvbHVtbl8yKSkpDQp9DQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHR3byBjb2x1bW5zDQpjb2x1bW5fbmFtZXNfZGYgPC0gZGF0YS5mcmFtZShDb2x1bW5fMSA9IGNvbHVtbl8xLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uXzIgPSBjb2x1bW5fMikNCg0KIyBDYWxjdWxhdGUgdGhlIHdpZHRoIGR5bmFtaWNhbGx5DQpjb2xfd2lkdGggPC0gcGFzdGUwKDEwMCAvIG5jb2woY29sdW1uX25hbWVzX2RmKSwgIiUiKQ0KDQojIFByaW50IHRoZSBkYXRhIGZyYW1lIHVzaW5nIGtuaXRyOjprYWJsZQ0Ka25pdHI6OmthYmxlKGNvbHVtbl9uYW1lc19kZiwgZm9ybWF0ID0gIm1hcmtkb3duIiwgY29sLm5hbWVzID0gYygiRW50cmllcyIsICJFbnRyaWVzIikpICU+JQ0KICBjb2x1bW5fc3BlYygxOjIsIHdpZHRoID0gY29sX3dpZHRoLCBleHRyYV9jc3MgPSAidGV4dC1hbGlnbjogbGVmdDsiKQ0KDQpgYGANCg0KIyMgSW5kaXZpZHVhbHMgd2l0aCBhIFZpdGFsDQpgYGB7ciB2aXRhbHNfZGF0YV91bmlxdWVfbmFtZSwgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIFVuaXF1ZSBOYW1lcyBFeHRyYWN0aW9uOiBFeHRyYWN0cyBhbmQgcHJpbnRzIHVuaXF1ZSBuYW1lcyBmcm9tIHRoZSBOYW1lIGNvbHVtbiB0byBpZGVudGlmeSBkaXN0aW5jdCBpbmRpdmlkdWFscyBpbiB0aGUgZGF0YXNldC4NCnZpdGFsc19kYXRhX3VuaXF1ZV9uYW1lIDwtIGdzdWIoIl8iLCAiICIsIHZpdGFsc19kYXRhJE5hbWUpDQp2aXRhbHNfZGF0YV91bmlxdWVfbmFtZSA8LSBzb3J0KHVuaXF1ZSh2aXRhbHNfZGF0YV91bmlxdWVfbmFtZSkpDQp2aXRhbHNfZGF0YV91bmlxdWVfbmFtZSA8LSBkYXRhLmZyYW1lKEluZGl2aWR1YWxzID0gdml0YWxzX2RhdGFfdW5pcXVlX25hbWUpDQoNCg0KIyBVc2Uga25pdHI6OmthYmxlIHRvIGZvcm1hdCBhcyBhIG1hcmtkb3duIHRhYmxlDQprbml0cjo6a2FibGUodml0YWxzX2RhdGFfdW5pcXVlX25hbWUsIGZvcm1hdCA9ICJtYXJrZG93biIsICJJbmRpdmlkdWFscyIpIA0KDQojIFByaW50IGZvciByZWZlcmVuY2UNCiMgcHJpbnQodml0YWxzX2RhdGFfdW5pcXVlX25hbWUpIA0KYGBgDQoNCiMgQk9EWVdFSUdIVCANCg0KQW4gaW5kaXZpZHVhbCdzIGJvZHl3ZWlnaHQgaXMgdXNlZCB0byBtYXRjaCBwZXJmb3JtYW5jZSBtZWFzdXJlbWVudHMgd2l0aCBNYXJrIFJpcHBldG9lJ3MgU3RyZW5ndGggU3RhbmRhcmRzIG1lbnRpb25lZCBlYXJsaWVyIGluIHRoaXMgcmVwb3J0LiBCb2R5d2VpZ2h0IGFsbG93cyBmb3Igc2ltcGxlIHRlY2huaXF1ZXMgYW5kIG1ldGhvZHMgdG8gYXNzZXNzIHBlcmZvcm1hbmNlLCBzdWNoIGFzIHdoZW4gaGl0dGluZyBwbGF0ZWF1cyBvciBleHBlcmllbmNpbmcgY2hhbmdlcyBpbiBib2R5d2VpZ2h0LiAgDQoNCiMjIEFsbCBCb2R5d2VpZ2h0IE92ZXIgVGltZQ0KDQpUaGUgcGxvdCBkaXNwbGF5cyBhbGwgYm9keXdlaWdodCBtZWFzdXJlbWVudHMgb3ZlciB0aW1lLCB3aXRoIGFsbCBpbmRpdmlkdWFscyBwbG90dGVkIG9uIGEgc2luZ2xlIGdyYXBoLiBJbmRpdmlkdWFscyByZXByZXNlbnRlZCBieSBqdXN0IGEgZG90IGFuZCBubyBsaW5lIGhhdmUgb25seSBvbmUgbWVhc3VyZW1lbnQgcmVjb3JkZWQsIGluZGljYXRpbmcgdGhhdCBtb3JlIGRhdGEgaXMgcmVxdWlyZWQ7IGFueSB0d28gcG9pbnRzIHdpbGwgY3JlYXRlIGEgbGluZS4NCg0KPCEtLQ0KUExBTjogQ29uc2lkZXIgdG8gdXBkYXRlIGNvZGUgZm9yIEF2ZXJhZ2UgVml0YWxzIChBdmcgV2VpZ2h0LCBBdmcgSGVpZ2h0LCBldGMpIGlmIG11bHRpcGxlIGVudHJpZXMgZXhpc3Qgb24gdGhlIHNhbWUgZGF0ZS4gVW5hYmxlIHRvIGZpZ3VyZSBvdXQgYXMgb2YgMDUvMTAvMjAyNC4NCi0tPg0KDQpgYGB7ciB0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUsIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCg0KIyBFbnN1cmUgdGhlIG5lY2Vzc2FyeSBsaWJyYXJpZXMgYXJlIGxvYWRlZA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCg0KIyBEZWZpbmUgYSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIGRhdGUgcmFuZ2UsIG51bWJlciBvZiBlbnRyaWVzLCBhbmQgYm9keXdlaWdodCBtZXRyaWNzIGZvciBlYWNoIGluZGl2aWR1YWwNCmFzc2lnbl9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUgPC0gZnVuY3Rpb24odml0YWxzX2RhdGEpIHsNCiAgdml0YWxzX2RhdGFfd2VpZ2h0X2xicyA8LSB2aXRhbHNfZGF0YVshaXMubmEoYXMubnVtZXJpYyh2aXRhbHNfZGF0YSRXZWlnaHRfbGJzKSksIF0NCiAgdml0YWxzX2RhdGFfd2VpZ2h0X2xic191bmlxdWVfbmFtZXMgPC0gdW5pcXVlKHZpdGFsc19kYXRhX3dlaWdodF9sYnMkTmFtZSkNCiAgDQogICMgSW5pdGlhbGl6ZSBhIGRhdGEgZnJhbWUgdG8gc3RvcmUgdGhlIHJlc3VsdHMNCiAgdGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lIDwtIGRhdGEuZnJhbWUoTmFtZSA9IGNoYXJhY3RlcigpLCBBZ2UgPSBudW1lcmljKCksIERhdGVfUmFuZ2UgPSBjaGFyYWN0ZXIoKSwgRW50cmllcyA9IG51bWVyaWMoKSwgTWluX0JXID0gbnVtZXJpYygpLCBNaW5fQldfRGF0ZSA9IGNoYXJhY3RlcigpLCBNYXhfQlcgPSBudW1lcmljKCksIE1heF9CV19EYXRlID0gY2hhcmFjdGVyKCksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCiAgDQogICMgTG9vcCB0aHJvdWdoIGVhY2ggaW5kaXZpZHVhbCB0byBjb21waWxlIGRhdGUgcmFuZ2UgYW5kIG51bWJlciBvZiBlbnRyaWVzIGluZm9ybWF0aW9uDQogIGZvciAobmFtZSBpbiB2aXRhbHNfZGF0YV93ZWlnaHRfbGJzX3VuaXF1ZV9uYW1lcykgew0KICAgICMgU3Vic2V0IGRhdGEgZm9yIHRoZSBjdXJyZW50IGluZGl2aWR1YWwNCiAgICBpbmRpdmlkdWFsX2RhdGEgPC0gc3Vic2V0KHZpdGFsc19kYXRhX3dlaWdodF9sYnMsIE5hbWUgPT0gbmFtZSkNCiAgICANCiAgICAjIENhbGN1bGF0ZSBkYXRlIHJhbmdlIGFuZCBudW1iZXIgb2YgZW50cmllcw0KICAgIGRhdGVfcmFuZ2UgPC0gcGFzdGUobWluKGluZGl2aWR1YWxfZGF0YSREYXRlKSwgbWF4KGluZGl2aWR1YWxfZGF0YSREYXRlKSwgc2VwID0gIiB0byAiKQ0KICAgIG51bWJlcl9vZl9lbnRyaWVzIDwtIG5yb3coaW5kaXZpZHVhbF9kYXRhKQ0KICAgIA0KICAgICMgQ2FsY3VsYXRlIG1pbiBhbmQgbWF4IGJvZHl3ZWlnaHQgYW5kIHRoZWlyIHJlc3BlY3RpdmUgZGF0ZXMNCiAgICBtaW5fYm9keXdlaWdodCA8LSBtaW4oaW5kaXZpZHVhbF9kYXRhJFdlaWdodF9sYnMsIG5hLnJtID0gVFJVRSkNCiAgICBtaW5fYm9keXdlaWdodF9kYXRlIDwtIGluZGl2aWR1YWxfZGF0YSREYXRlW3doaWNoLm1pbihpbmRpdmlkdWFsX2RhdGEkV2VpZ2h0X2xicyldDQogICAgbWF4X2JvZHl3ZWlnaHQgPC0gbWF4KGluZGl2aWR1YWxfZGF0YSRXZWlnaHRfbGJzLCBuYS5ybSA9IFRSVUUpDQogICAgbWF4X2JvZHl3ZWlnaHRfZGF0ZSA8LSBpbmRpdmlkdWFsX2RhdGEkRGF0ZVt3aGljaC5tYXgoaW5kaXZpZHVhbF9kYXRhJFdlaWdodF9sYnMpXQ0KICAgIA0KICAgICMgQWRkIHRoZSByZXN1bHRzIHRvIHRoZSBkYXRhIGZyYW1lDQogICAgdGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lIDwtIHJiaW5kKHRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSwgZGF0YS5mcmFtZShOYW1lID0gbmFtZSwgRGF0ZV9SYW5nZSA9IGRhdGVfcmFuZ2UsIEVudHJpZXMgPSBudW1iZXJfb2ZfZW50cmllcywgTWluX0JXID0gbWluX2JvZHl3ZWlnaHQsIE1pbl9CV19EYXRlID0gbWluX2JvZHl3ZWlnaHRfZGF0ZSwgTWF4X0JXID0gbWF4X2JvZHl3ZWlnaHQsIE1heF9CV19EYXRlID0gbWF4X2JvZHl3ZWlnaHRfZGF0ZSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKSkNCiAgfQ0KDQogICMgU29ydCB0aGUgcmVzdWx0cyBieSBOYW1lDQogIHRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSA8LSB0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUgJT4lDQogICAgYXJyYW5nZShOYW1lKQ0KICANCiAgIyBSZXR1cm4gdGhlIHJlc3VsdHMgZGF0YSBmcmFtZQ0KICByZXR1cm4odGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lKQ0KfQ0KDQojIENhbGwgdGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgcmVzdWx0cw0KdGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lIDwtIGFzc2lnbl9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUodml0YWxzX2RhdGEpDQoNCiMgUGVyZm9ybSBhIGxlZnQgam9pbiB0byBjb21iaW5lIHRoZSBkYXRhIGZyYW1lcyBiYXNlZCBvbiB0aGUgTmFtZSBjb2x1bW4NCnRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSA8LSBsZWZ0X2pvaW4odGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lLCBkZW1vZ3JhcGhpY19uciwgYnkgPSAiTmFtZSIpDQoNCiMgU2VsZWN0IGFuZCBvcmRlciB0aGUgY29sdW1ucw0KdGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lIDwtIHRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSAlPiUNCiAgc2VsZWN0KE5hbWUsIERhdGVfUmFuZ2UsIEVudHJpZXMsIE1pbl9CVywgTWluX0JXX0RhdGUsIE1heF9CVywgTWF4X0JXX0RhdGUpDQoNCiMgUmVuYW1lIGNvbHVtbnMgdG8gcmVwbGFjZSB1bmRlcnNjb3JlcyB3aXRoIHNwYWNlcw0KY29sbmFtZXModGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lKSA8LSBnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUpKQ0KDQojIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGNvbHVtbnMNCm5jb2x1bW5zIDwtIG5jb2wodGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lKQ0KY29sdW1uX3dpZHRoIDwtIDEwMCAvIG5jb2x1bW5zDQoNCiMgU3Vic3RpdHV0ZSB1bmRlcnNjb3JlcyB3aXRoIHNwYWNlcyBpbiB0aGUgTmFtZSBjb2x1bW4gb2Ygdml0YWxzX2RhdGENCnRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSROYW1lIDwtIGdzdWIoIl8iLCAiICIsIHRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSROYW1lKQ0KDQojIFByaW50IHRoZSBjb21iaW5lZCB0YWJsZSB1c2luZyBrbml0cjo6a2FibGUNCmtuaXRyOjprYWJsZSh0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUsIGZvcm1hdCA9ICJodG1sIiwgYWxpZ24gPSBjKCJsIiwgImwiLCAibCIsICJyIiwgImwiLCAiciIsICJsIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKQ0KDQojIHN0cih0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUpDQoNCmBgYA0KDQpgYGB7ciBwbG90X2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTcsIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCg0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCiMgQ3JlYXRlIGEgY29sb3IgcGFsZXR0ZSB1c2luZyBSQ29sb3JCcmV3ZXIncyAiRGFyazIiIChvciBhbm90aGVyIHN1aXRhYmxlIHBhbGV0dGUpDQpjb2xvcl9wYWxldHRlIDwtIGJyZXdlci5wYWwobiA9IG1pbig4LCBsZW5ndGgodW5pcXVlKHZpdGFsc19kYXRhJE5hbWUpKSksICJEYXJrMiIpDQppZiAobGVuZ3RoKHVuaXF1ZSh2aXRhbHNfZGF0YSROYW1lKSkgPiA4KSB7DQogIGNvbG9yX3BhbGV0dGUgPC0gcmVwKGNvbG9yX3BhbGV0dGUsIGxlbmd0aC5vdXQgPSBsZW5ndGgodW5pcXVlKHZpdGFsc19kYXRhJE5hbWUpKSkNCn0NCm5hbWVzKGNvbG9yX3BhbGV0dGUpIDwtIHVuaXF1ZSh2aXRhbHNfZGF0YSROYW1lKQ0KDQojIEN1c3RvbSBkYXRlIGxhYmVsIGZ1bmN0aW9uIHRvIGFkZCBhIG5ld2xpbmUgYmV0d2VlbiB0aGUgbW9udGggYW5kIHRoZSB5ZWFyDQpkYXRlX2xhYmVsX2Z1bmMgPC0gZnVuY3Rpb24oeCkgew0KICBmb3JtYXQoeCwgIiViXG4lWSIpICAjIERpc3BsYXlzIGFzICJTZXBcbjIwMjMiLCBzZXBhcmF0aW5nIG1vbnRoIGFuZCB5ZWFyIHdpdGggYSBuZXdsaW5lDQp9DQoNCiMgRXh0ZW5kIHRoZSB4LWF4aXMgYnkgWC1hZGRpdGlvbmFsIG1vbnRocyB1c2luZyBsdWJyaWRhdGUuDQpleHRlbmRfbW9udGhzIDwtIDENCg0KIyBDcmVhdGUgYSBtb2RpZmllZCBOYW1lIGNvbHVtbiBmb3IgbGVnZW5kIGRpc3BsYXkNCnZpdGFsc19kYXRhJE5hbWVfTGVnZW5kIDwtIGdzdWIoIl8iLCAiICIsIHZpdGFsc19kYXRhJE5hbWUpDQoNCiMgRklSU1QgUExPVCANCiMgQm9keXdlaWdodCBvdmVyIHRpbWUgZm9yIGFsbCBpbmRpdmlkdWFscyB3aXRoIHR3byBleHRyYSBncmlkIGxpbmVzIG9uIHRoZSB4LWF4aXMNCmFsbF9kYXRhX21heF9kYXRlIDwtIG1heCh2aXRhbHNfZGF0YSREYXRlLCBuYS5ybSA9IFRSVUUpDQpleHRlbmRlZF9hbGxfZGF0YV9tYXhfZGF0ZSA8LSBhbGxfZGF0YV9tYXhfZGF0ZSArIG1vbnRocyhleHRlbmRfbW9udGhzKQ0KZmlyc3RfcGxvdCA8LSBnZ3Bsb3Qodml0YWxzX2RhdGEsIGFlcyh4ID0gRGF0ZSwgeSA9IFdlaWdodF9sYnMsIGNvbG9yID0gTmFtZV9MZWdlbmQpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gdml0YWxzX2RhdGEgJT4lIGdyb3VwX2J5KE5hbWUpICU+JSBmaWx0ZXIoRGF0ZSA9PSBtaW4oRGF0ZSkgfCBEYXRlID09IG1heChEYXRlKSksIA0KICAgICAgICAgICBhZXMoeCA9IERhdGUsIHkgPSBXZWlnaHRfbGJzLCBmaWxsID0gTmFtZV9MZWdlbmQpLCBzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAzKSArICAjIEFkZCBtYXJrZXIgb24gZmlyc3QgYW5kIGxhc3QgZGF0YSBwb2ludA0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSBtb250aCIsIGxhYmVscyA9IGRhdGVfbGFiZWxfZnVuYywNCiAgICAgICAgICAgICAgIGxpbWl0cyA9IGMobWluKHZpdGFsc19kYXRhJERhdGUsIG5hLnJtID0gVFJVRSksIGV4dGVuZGVkX2FsbF9kYXRhX21heF9kYXRlKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpudW1iZXJfZm9ybWF0KGFjY3VyYWN5ID0gMC4xKSkgKyAgIyBBZGp1c3QgeS1heGlzIHRvIDFzdCBkZWNpbWFsDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzZXROYW1lcyhjb2xvcl9wYWxldHRlLCBnc3ViKCJfIiwgIiAiLCBuYW1lcyhjb2xvcl9wYWxldHRlKSkpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNldE5hbWVzKGNvbG9yX3BhbGV0dGUsIGdzdWIoIl8iLCAiICIsIG5hbWVzKGNvbG9yX3BhbGV0dGUpKSkpICsgICMgTWF0Y2hpbmcgZmlsbCBjb2xvcnMgd2l0aCBjb2xvciBwYWxldHRlDQogIGxhYnModGl0bGUgPSAiQm9keXdlaWdodCBPdmVyIFRpbWUgZm9yIEFsbCBJbmRpdmlkdWFscyIsDQogICAgICAgeCA9ICJEYXRlIiwNCiAgICAgICB5ID0gIldlaWdodCAobGJzKSIsDQogICAgICAgY29sb3IgPSAiTmFtZSIsDQogICAgICAgZmlsbCA9ICJOYW1lIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIG1pbm9yIGdyaWQgbGluZXMgb24gdGhlIHgtYXhpcw0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyZXk5MCIpKSAgIyBNYWtlIGdyaWQgbGluZXMgbGlnaHRlcg0KDQojIFByaW50IHRoZSBmaXJzdCBwbG90DQpwcmludChmaXJzdF9wbG90KQ0KDQojIE1hcmtkb3duIHNlcGFyYXRvciB0byBhZGQgc3BhY2luZyBiZXR3ZWVuIHBsb3RzDQpjYXQoIlxuXG4iKQ0KDQpgYGANCg0KIyMgSW5kaXZpZHVhbCBCb2R5d2VpZ2h0IE92ZXIgVGltZQ0KDQpUaGVzZSB2aXN1YWxpemF0aW9ucyBhbGxvdyB1cyB0bzoNCg0KLSBUcmFjayB0aGUgYm9keXdlaWdodCB0cmVuZHMgb2YgZWFjaCBpbmRpdmlkdWFsLg0KLSBJZGVudGlmeSBrZXkgbWV0cmljcyBzdWNoIGFzIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGJvZHl3ZWlnaHQsIGFuZCB0aGUgbnVtYmVyIG9mIG1lYXN1cmVtZW50cyB0YWtlbi4NCi0gVW5kZXJzdGFuZCBob3cgYm9keXdlaWdodCBjaGFuZ2VzIG92ZXIgdGltZSBtYXkgY29ycmVsYXRlIHdpdGggcGVyZm9ybWFuY2UgaW4gc3RyZW5ndGggZXhlcmNpc2VzIGFuZCBvdGhlciBmaXRuZXNzIG1ldHJpY3MuDQotIEJ5IGNvbXBhcmluZyB0aGVzZSBwbG90cyB3aXRoIHN0cmVuZ3RoIHN0YW5kYXJkcywgZGVtb2dyYXBoaWMgaW5mb3JtYXRpb24sIGFuZCBvdGhlciBwZXJmb3JtYW5jZSBkYXRhLCB3ZSBjYW4gZ2FpbiB2YWx1YWJsZSBpbnNpZ2h0cyBpbnRvIGVhY2ggaW5kaXZpZHVhbCdzIHByb2dyZXNzIGFuZCBhcmVhcyBuZWVkaW5nIGltcHJvdmVtZW50Lg0KDQpgYGB7ciBwbG90X2luZGl2aWR1YWxfYm9keXdlaWdodF9vdmVyX3RpbWUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQoNCiMgU0VDT05EIFBMT1RTIChMT09QKQ0KIyBTZWNvbmQ6IExvb3AgdGhyb3VnaCBlYWNoIGluZGl2aWR1YWwgdG8gY3JlYXRlIHNlcGFyYXRlIHBsb3RzIHdpdGggdHdvIGV4dHJhIGdyaWQgbGluZXMgb24gdGhlIHgtYXhpcw0KcGxvdHNfbGlzdCA8LSBsaXN0KCkNCmluZGl2aWR1YWxfbmFtZXMgPC0gdW5pcXVlKHZpdGFsc19kYXRhJE5hbWUpDQoNCiMgTWVyZ2UgdGhlIHRhYmxlX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSBkYXRhIGZyYW1lIHdpdGggaW5kaXZpZHVhbF9kYXRhDQp0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUgPC0gYXNzaWduX2FsbF9ib2R5d2VpZ2h0X292ZXJfdGltZSh2aXRhbHNfZGF0YSkNCg0KZm9yIChuYW1lIGluIGluZGl2aWR1YWxfbmFtZXMpIHsNCiAgIyBTdWJzZXQgZGF0YSBmb3IgdGhlIGN1cnJlbnQgaW5kaXZpZHVhbA0KICBpbmRpdmlkdWFsX2RhdGEgPC0gc3Vic2V0KHZpdGFsc19kYXRhLCBOYW1lID09IG5hbWUpDQogIA0KICAjIEV4dGVuZCB0aGUgeC1heGlzIGJ5IFggYWRkaXRpb25hbCBtb250aChzKQ0KICBtYXhfZGF0ZV9pbmRpdmlkdWFsIDwtIG1heChpbmRpdmlkdWFsX2RhdGEkRGF0ZSwgbmEucm0gPSBUUlVFKQ0KICBleHRlbmRlZF9pbmRpdmlkdWFsX21heF9kYXRlIDwtIG1heF9kYXRlX2luZGl2aWR1YWwgKyBtb250aHMoZXh0ZW5kX21vbnRocykNCiAgDQogICMgR2V0IG1ldHJpY3MgZm9yIHRoZSBjdXJyZW50IGluZGl2aWR1YWwgZnJvbSB0aGUgdGFibGVfYWxsX2JvZHl3ZWlnaHRfb3Zlcl90aW1lDQogIGluZGl2aWR1YWxfbWV0cmljcyA8LSB0YWJsZV9hbGxfYm9keXdlaWdodF9vdmVyX3RpbWUgJT4lIGZpbHRlcihOYW1lID09IG5hbWUpDQogIG1pbl9ib2R5d2VpZ2h0IDwtIGluZGl2aWR1YWxfbWV0cmljcyRNaW5fQlcNCiAgbWluX2JvZHl3ZWlnaHRfZGF0ZSA8LSBpbmRpdmlkdWFsX21ldHJpY3MkTWluX0JXX0RhdGUNCiAgbWF4X2JvZHl3ZWlnaHQgPC0gaW5kaXZpZHVhbF9tZXRyaWNzJE1heF9CVw0KICBtYXhfYm9keXdlaWdodF9kYXRlIDwtIGluZGl2aWR1YWxfbWV0cmljcyRNYXhfQldfRGF0ZQ0KICBkYXRlX3JhbmdlIDwtIGluZGl2aWR1YWxfbWV0cmljcyREYXRlX1JhbmdlDQogIG51bWJlcl9vZl9lbnRyaWVzIDwtIGluZGl2aWR1YWxfbWV0cmljcyRFbnRyaWVzDQogIA0KICAjIENyZWF0ZSBhIHBsb3QgZm9yIHRoZSBjdXJyZW50IGluZGl2aWR1YWwgd2l0aCB0d28gZXh0cmEgZ3JpZCBsaW5lcyBvbiB0aGUgeC1heGlzDQogIHBsb3QgPC0gZ2dwbG90KGluZGl2aWR1YWxfZGF0YSwgYWVzKHggPSBEYXRlLCB5ID0gV2VpZ2h0X2xicykpICsNCiAgICBnZW9tX2xpbmUoY29sb3IgPSBjb2xvcl9wYWxldHRlW25hbWVdKSArDQogICAgZ2VvbV9wb2ludChkYXRhID0gaW5kaXZpZHVhbF9kYXRhICU+JSBmaWx0ZXIoRGF0ZSA9PSBtaW4oRGF0ZSkgfCBEYXRlID09IG1heChEYXRlKSksIA0KICAgICAgICAgICBhZXMoeCA9IERhdGUsIHkgPSBXZWlnaHRfbGJzLCBmaWxsID0gTmFtZV9MZWdlbmQpLCBzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAzKSArICAjIEFkZCBtYXJrZXIgb24gZmlyc3QgYW5kIGxhc3QgZGF0YSBwb2ludA0KICAgIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIiwgbGFiZWxzID0gZGF0ZV9sYWJlbF9mdW5jLCBsaW1pdHMgPSBjKG1pbihpbmRpdmlkdWFsX2RhdGEkRGF0ZSwgbmEucm0gPSBUUlVFKSwgZXh0ZW5kZWRfaW5kaXZpZHVhbF9tYXhfZGF0ZSkpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpudW1iZXJfZm9ybWF0KGFjY3VyYWN5ID0gMC4xKSkgKyAgIyBBZGp1c3QgeS1heGlzIHRvIDFzdCBkZWNpbWFsDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHNldE5hbWVzKGNvbG9yX3BhbGV0dGUsIGdzdWIoIl8iLCAiICIsIG5hbWVzKGNvbG9yX3BhbGV0dGUpKSkpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzZXROYW1lcyhjb2xvcl9wYWxldHRlLCBnc3ViKCJfIiwgIiAiLCBuYW1lcyhjb2xvcl9wYWxldHRlKSkpKSArICAjIE1hdGNoaW5nIGZpbGwgY29sb3JzIHdpdGggY29sb3IgcGFsZXR0ZQ0KICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiQm9keXdlaWdodCBPdmVyIFRpbWUgZm9yIiwgZ3N1YigiXyIsICIgIiwgbmFtZSkpLA0KICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZSgiICAgIE1pbiBCb2R5d2VpZ2h0OiIsIG1pbl9ib2R5d2VpZ2h0LCAibGJzIG9uIiwgbWluX2JvZHl3ZWlnaHRfZGF0ZSwgIlxuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICIgICBNYXggQm9keXdlaWdodDoiLCBtYXhfYm9keXdlaWdodCwgImxicyBvbiIsIG1heF9ib2R5d2VpZ2h0X2RhdGUsICJcbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICIgICBEYXRlIFJhbmdlOiIsIGRhdGVfcmFuZ2UsICJcbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICIgICBDb3VudDoiLCBudW1iZXJfb2ZfZW50cmllcywgIlxuXG4iLCBzZXAgPSAiICIpLA0KICAgICAgICAgeCA9ICJEYXRlIiwNCiAgICAgICAgIHkgPSAiV2VpZ2h0IChsYnMpIikgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIG1pbm9yIGdyaWQgbGluZXMgb24gdGhlIHgtYXhpcw0KICAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTkwIiksICAjIE1ha2UgZ3JpZCBsaW5lcyBsaWdodGVyDQogICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMC44NSAqIDEyLCBmYWNlID0gIml0YWxpYyIpKSArIA0KICAgIGd1aWRlcyhjb2xvciA9IEZBTFNFLCBmaWxsID0gRkFMU0UpICAjIFJlbW92ZSBsZWdlbmRzIGZvciBjb2xvciBhbmQgZmlsbA0KICANCiAgIyBQcmludCBlYWNoIHBsb3Qgc2VwYXJhdGVseQ0KICBwcmludChwbG90KQ0KICANCiAgIyBNYXJrZG93biBzZXBhcmF0b3IgdG8gYWRkIHNwYWNpbmcgYmV0d2VlbiBwbG90cw0KICBjYXQoIlxuXG4iKQ0KICANCiAgIyBPcHRpb25hbGx5LCBhZGQgdGhlIHBsb3QgdG8gYSBsaXN0IGlmIHlvdSB3YW50IHRvIGZ1cnRoZXIgbWFuaXB1bGF0ZSBvciBzYXZlIHRoZW0NCiAgcGxvdHNfbGlzdFtbbmFtZV1dIDwtIHBsb3QNCn0NCg0KYGBgDQoNCiMjIEluZGl2aWR1YWwgQm9keXdlaWdodCBPdmVyIExhc3QgMiBXZWVrcw0KDQpVbmFibGUgdG8gcGxvdCBhbGwgaW5kaXZpZHVhbHMgaW4gb25lIGZpZ3VyZSBhcyBlYWNoIGluZGl2aWR1YWwncyBsYXN0IDItd2VlayBkYXRlIHJhbmdlIGRpZmZlcnMgZnJvbSBvbmUgYW5vdGhlci4gVGhlIGF2ZXJhZ2UgYm9keXdlaWdodCBvdmVyIHRoZSBkYXRlIHJhbmdlIGlzIHByZXNlbnRlZCBpbiB0aGUgc3VidGl0bGVzLg0KDQpgYGB7ciBib2R5d2VpZ2h0X292ZXJfdGltZV9sYXN0XzJ3aywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTcsIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCg0KIyBDdXN0b20gZGF0ZSBsYWJlbCBmdW5jdGlvbiB0byBhZGQgYSBuZXdsaW5lIGJldHdlZW4gdGhlIG1vbnRoIGFuZCB0aGUgeWVhciwgaW5jbHVkaW5nIHRoZSB5ZWFyIG9uIHRoZSBmaXJzdCBsYWJlbA0KZGF0ZV9sYWJlbF9mdW5jIDwtIGZ1bmN0aW9uKHgpIHsNCiAgbGFiZWxzIDwtIGZvcm1hdCh4LCAiJWJcbiVkIikgIyBEaXNwbGF5cyBhcyAiU2VwXG4xNSIsIHNlcGFyYXRpbmcgbW9udGggYW5kIHllYXIgd2l0aCBhIG5ld2xpbmUNCiAgbGFiZWxzWzFdIDwtIHBhc3RlMChsYWJlbHNbMV0sICJcbiIsIGZvcm1hdCh4WzFdLCAiJVkiKSkgICMgQXBwZW5kIHRoZSB5ZWFyIHRvIHRoZSBmaXJzdCBsYWJlbA0KICByZXR1cm4obGFiZWxzKQ0KfQ0KDQojIEV4dGVuZCB0aGUgeC1heGlzIGJ5IFgtYWRkaXRpb25hbCBtb250aHMgdXNpbmcgbHVicmlkYXRlLg0KZXh0ZW5kX21vbnRocyA8LSAxDQoNCiMgU2VsZWN0IHJvd3Mgd2hlcmUgV2VpZ2h0X2xicyBpcyBub3QgTkEgYW5kIGNvbnZlcnQgdG8gbnVtZXJpYyBqdXN0IGluIGNhc2UuDQp2aXRhbHNfZGF0YV93ZWlnaHRfbGJzIDwtIHZpdGFsc19kYXRhWyFpcy5uYShhcy5udW1lcmljKHZpdGFsc19kYXRhJFdlaWdodF9sYnMpKSwgXQ0KIyBFeHRyYWN0IHVuaXF1ZSBuYW1lcyBmcm9tIHRoZSBkYXRhDQp2aXRhbHNfZGF0YV93ZWlnaHRfbGJzX3VuaXF1ZV9uYW1lcyA8LSB1bmlxdWUodml0YWxzX2RhdGFfd2VpZ2h0X2xicyROYW1lKQ0KDQojIENhbGN1bGF0ZSBudW1iZXIgb2YgZW50cmllcyBmb3IgZWFjaCBpbmRpdmlkdWFsDQpudW1iZXJfb2ZfZW50cmllcyA8LSB0YWJsZSh2aXRhbHNfZGF0YSROYW1lKQ0KDQojIExvb3AgdGhyb3VnaCBlYWNoIGluZGl2aWR1YWwgdG8gY3JlYXRlIHNlcGFyYXRlIHBsb3RzIHdpdGggdHdvIGV4dHJhIGdyaWQgbGluZXMgb24gdGhlIHgtYXhpcw0KcGxvdHNfbGlzdCA8LSBsaXN0KCkNCmluZGl2aWR1YWxfbmFtZXMgPC0gdW5pcXVlKHZpdGFsc19kYXRhJE5hbWUpDQoNCmZvciAobmFtZSBpbiBpbmRpdmlkdWFsX25hbWVzKSB7DQogICMgU3Vic2V0IGRhdGEgZm9yIHRoZSBjdXJyZW50IGluZGl2aWR1YWwNCiAgaW5kaXZpZHVhbF9kYXRhIDwtIHN1YnNldCh2aXRhbHNfZGF0YSwgTmFtZSA9PSBuYW1lKQ0KICANCiAgbWluX2RhdGUgPC0gbWluKGluZGl2aWR1YWxfZGF0YSREYXRlKQ0KICBtYXhfZGF0ZSA8LSBtYXgoaW5kaXZpZHVhbF9kYXRhJERhdGUpDQogIG1pbl9kYXRlX2xhc3RfMndrIDwtIG1heF9kYXRlIC0gMTMNCiAgdml0YWxzX2xhc3RfMndrIDwtIHN1YnNldCAoaW5kaXZpZHVhbF9kYXRhLCBEYXRlID49IG1pbl9kYXRlX2xhc3RfMndrICYgRGF0ZSA8PSBtYXhfZGF0ZSkNCiAgICANCiAgIyBDYWxjdWxhdGUgYXZlcmFnZSBib2R5d2VpZ2h0IG92ZXIgdGhlIGxhc3QgMiB3ZWVrcw0KICBhdmdfYm9keXdlaWdodF9sYXN0XzJ3ayA8LSBtZWFuKHZpdGFsc19sYXN0XzJ3ayRXZWlnaHRfbGJzLCBuYS5ybSA9IFRSVUUpDQogIGRhdGVfcmFuZ2UgPC0gcGFzdGUobWluX2RhdGVfbGFzdF8yd2ssIG1heF9kYXRlLCBzZXAgPSAiIHRvICIpDQogICAgDQogICMgQ2FsY3VsYXRlIG51bWJlciBvZiBlbnRyaWVzIGZvciB0aGUgbGFzdCAyIHdlZWtzDQogIG51bWJlcl9vZl9lbnRyaWVzIDwtIG5yb3codml0YWxzX2xhc3RfMndrKQ0KICANCiAgIyBDcmVhdGUgYSBwbG90IGZvciB0aGUgbGFzdCAyIHdlZWtzIG9mIGRhdGEgZm9yIHRoZSBjdXJyZW50IGluZGl2aWR1YWwNCiAgcGxvdCA8LSBnZ3Bsb3Qodml0YWxzX2xhc3RfMndrLCBhZXMoeCA9IERhdGUsIHkgPSBXZWlnaHRfbGJzKSkgKw0KICAgIGdlb21fbGluZShjb2xvciA9IGNvbG9yX3BhbGV0dGVbbmFtZV0pICsNCiAgICBnZW9tX3BvaW50KGRhdGEgPSB2aXRhbHNfbGFzdF8yd2tbMSxdLCBhZXMoeCA9IERhdGUsIHkgPSBXZWlnaHRfbGJzLCBmaWxsID0gTmFtZSksIHNoYXBlID0gMjEsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDMpICsgICMgQWRkIG1hcmtlciBvbiBmaXJzdCBkYXRhIHBvaW50DQogICAgZ2VvbV9wb2ludChkYXRhID0gdml0YWxzX2xhc3RfMndrW25yb3codml0YWxzX2xhc3RfMndrKSxdLCBhZXMoeCA9IERhdGUsIHkgPSBXZWlnaHRfbGJzLCBmaWxsID0gTmFtZSksIHNoYXBlID0gMjEsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDMpICsgICMgQWRkIG1hcmtlciBvbiBsYXN0IGRhdGEgcG9pbnQNCiAgICBzY2FsZV94X2RhdGUoYnJlYWtzID0gc2VxKG1pbih2aXRhbHNfbGFzdF8yd2skRGF0ZSksIG1heCh2aXRhbHNfbGFzdF8yd2skRGF0ZSksIGJ5ID0gIjEgZGF5IiksDQogICAgICAgICAgICAgICAgIGxhYmVscyA9IGRhdGVfbGFiZWxfZnVuYywNCiAgICAgICAgICAgICAgICAgbGltaXRzID0gYyhtaW4odml0YWxzX2xhc3RfMndrJERhdGUsIG5hLnJtID0gVFJVRSksIG1heCh2aXRhbHNfbGFzdF8yd2skRGF0ZSwgbmEucm0gPSBUUlVFKSkpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpudW1iZXJfZm9ybWF0KGFjY3VyYWN5ID0gMC4xKSkgKyAgIyBBZGp1c3QgeS1heGlzIHRvIDFzdCBkZWNpbWFsDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX3BhbGV0dGVbbmFtZV0pICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9wYWxldHRlW25hbWVdKSArICAjIE1hdGNoaW5nIGZpbGwgY29sb3JzIHdpdGggY29sb3IgcGFsZXR0ZQ0KICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiQm9keXdlaWdodCBPdmVyIExhc3QgMiBXZWVrcyBmb3IiLCBnc3ViKCJfIiwgIiAiLCBuYW1lKSksDQogICAgICAgICBzdWJ0aXRsZSA9IHBhc3RlKCIgICAgQXZlcmFnZSBCb2R5d2VpZ2h0OiIsIHJvdW5kKGF2Z19ib2R5d2VpZ2h0X2xhc3RfMndrLCAyKSwgImxic1xuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIERhdGUgUmFuZ2U6IiwgZGF0ZV9yYW5nZSwgIlxuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIENvdW50OiIsIG51bWJlcl9vZl9lbnRyaWVzLCAiXG5cbiIsIHNlcCA9ICIgIiksDQogICAgICAgICB4ID0gIkRhdGUiLA0KICAgICAgICAgeSA9ICJXZWlnaHQgKGxicykiKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgbWlub3IgZ3JpZCBsaW5lcyBvbiB0aGUgeC1heGlzDQogICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5OTAiKSwgIyBNYWtlIGdyaWQgbGluZXMgbGlnaHRlcg0KICAgICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDAuODUgKiAxMiwgZmFjZSA9ICJpdGFsaWMiKSkgKyANCiAgICBndWlkZXMoY29sb3IgPSBGQUxTRSwgZmlsbCA9IEZBTFNFKSAgIyBSZW1vdmUgbGVnZW5kcyBmb3IgY29sb3IgYW5kIGZpbGwNCiAgDQogICMgUHJpbnQgZWFjaCBwbG90IHNlcGFyYXRlbHkNCiAgcHJpbnQocGxvdCkNCiAgDQogICMgTWFya2Rvd24gc2VwYXJhdG9yIHRvIGFkZCBzcGFjaW5nIGJldHdlZW4gcGxvdHMNCiAgY2F0KCJcblxuIikNCiAgDQogICMgT3B0aW9uYWxseSwgYWRkIHRoZSBwbG90IHRvIGEgbGlzdCBpZiB5b3Ugd2FudCB0byBmdXJ0aGVyIG1hbmlwdWxhdGUgb3Igc2F2ZSB0aGVtDQogIHBsb3RzX2xpc3RbW25hbWVdXSA8LSBwbG90DQp9DQoNCmBgYA0KDQojIyBBdmcgQm9keXdlaWdodCBPdmVyIExhc3QgMiBXZWVrcw0KU2lkZSBieSBzaWRlIGNvbXBhcmlzb24gYmV0d2VlbiBpbmRpdmlkdWFscy4NCg0KYGBge3IgdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIEVuc3VyZSB0aGUgbmVjZXNzYXJ5IGxpYnJhcmllcyBhcmUgbG9hZGVkDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGFuZCBhc3NpZ24gYXZlcmFnZSBib2R5d2VpZ2h0IHZhcmlhYmxlcw0KYXNzaWduX2F2ZXJhZ2VfYm9keXdlaWdodCA8LSBmdW5jdGlvbih2aXRhbHNfZGF0YSkgew0KICB2aXRhbHNfZGF0YV93ZWlnaHRfbGJzIDwtIHZpdGFsc19kYXRhWyFpcy5uYShhcy5udW1lcmljKHZpdGFsc19kYXRhJFdlaWdodF9sYnMpKSwgXQ0KICB2aXRhbHNfZGF0YV93ZWlnaHRfbGJzX3VuaXF1ZV9uYW1lcyA8LSB1bmlxdWUodml0YWxzX2RhdGFfd2VpZ2h0X2xicyROYW1lKQ0KICANCiAgIyBJbml0aWFsaXplIGEgZGF0YSBmcmFtZSB0byBzdG9yZSB0aGUgcmVzdWx0cw0KICB0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2sgPC0gZGF0YS5mcmFtZShOYW1lID0gY2hhcmFjdGVyKCksIEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXayA9IG51bWVyaWMoKSwgRGF0ZV9SYW5nZSA9IGNoYXJhY3RlcigpLCBBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2sgPSBudW1lcmljKCksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCiAgDQogICMgTG9vcCB0aHJvdWdoIGVhY2ggaW5kaXZpZHVhbCB0byBjb21waWxlIGF2ZXJhZ2UgYm9keXdlaWdodCBpbmZvcm1hdGlvbg0KICBmb3IgKG5hbWUgaW4gdml0YWxzX2RhdGFfd2VpZ2h0X2xic191bmlxdWVfbmFtZXMpIHsNCiAgICAjIFN1YnNldCBkYXRhIGZvciB0aGUgY3VycmVudCBpbmRpdmlkdWFsDQogICAgaW5kaXZpZHVhbF9kYXRhIDwtIHN1YnNldCh2aXRhbHNfZGF0YV93ZWlnaHRfbGJzLCBOYW1lID09IG5hbWUpDQogICAgDQogICAgbWluX2RhdGUgPC0gbWluKGluZGl2aWR1YWxfZGF0YSREYXRlKQ0KICAgIG1heF9kYXRlIDwtIG1heChpbmRpdmlkdWFsX2RhdGEkRGF0ZSkNCiAgICBtaW5fZGF0ZV9sYXN0XzJ3ayA8LSBtYXhfZGF0ZSAtIDEzDQogICAgdml0YWxzX2xhc3RfMndrIDwtIHN1YnNldCAoaW5kaXZpZHVhbF9kYXRhLCBEYXRlID49IG1pbl9kYXRlX2xhc3RfMndrICYgRGF0ZSA8PSBtYXhfZGF0ZSkNCiAgICANCiAgICAjIENhbGN1bGF0ZSBhdmVyYWdlIGJvZHl3ZWlnaHQgb3ZlciB0aGUgbGFzdCAyIHdlZWtzDQogICAgYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2sgPC0gbWVhbih2aXRhbHNfbGFzdF8yd2skV2VpZ2h0X2xicywgbmEucm0gPSBUUlVFKQ0KICAgIGRhdGVfcmFuZ2UgPC0gcGFzdGUobWluX2RhdGVfbGFzdF8yd2ssIG1heF9kYXRlLCBzZXAgPSAiIHRvICIpDQogICAgDQogICAgIyBDYWxjdWxhdGUgdGhlIGFnZSBhdCB0aGUgdGltZSBvZiB0aGUgYXZlcmFnZSBib2R5d2VpZ2h0IG1lYXN1cmVtZW50DQogICAgYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2tfZGF0ZSA8LSBtYXgodml0YWxzX2xhc3RfMndrJERhdGUsIG5hLnJtID0gVFJVRSkNCiAgICBiaXJ0aGRhdGUgPC0gZGVtb2dyYXBoaWNfbnIkQmlydGhkYXRlW2RlbW9ncmFwaGljX25yJE5hbWUgPT0gbmFtZV0NCiAgICBhZ2VfYXRfYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2sgPC0gYXMubnVtZXJpYyhkaWZmdGltZShhdmdfYm9keXdlaWdodF9sYXN0XzJ3a19kYXRlLCBiaXJ0aGRhdGUsIHVuaXRzID0gIndlZWtzIikpIC8gNTIuMjUNCiAgICANCiAgICAjIEFkZCB0aGUgcmVzdWx0cyB0byB0aGUgZGF0YSBmcmFtZQ0KICAgIHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayA8LSByYmluZCh0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2ssIGRhdGEuZnJhbWUoTmFtZSA9IGdzdWIoIl8iLCAiICIsIG5hbWUpLCBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2sgPSByb3VuZChhdmdfYm9keXdlaWdodF9sYXN0XzJ3aywgMiksIERhdGVfUmFuZ2UgPSBkYXRlX3JhbmdlLCBBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2sgPSBjZWlsaW5nKGFnZV9hdF9hdmdfYm9keXdlaWdodF9sYXN0XzJ3ayksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkpDQogICAgDQogICAgIyBEZWZpbmUgdmFyaWFibGUgbmFtZXMgZm9yIGF2ZXJhZ2UgYm9keXdlaWdodCwgZGF0ZSByYW5nZSwgYW5kIGFnZSBhdCBhdmVyYWdlIGJvZHl3ZWlnaHQNCiAgICBhdmdfYm9keXdlaWdodF9sYXN0XzJ3a192YXJfbmFtZSA8LSBwYXN0ZSgiYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2siLCB0b2xvd2VyKG5hbWUpLCBzZXAgPSAiXyIpDQogICAgZGF0ZV9yYW5nZV92YXJfbmFtZSA8LSBwYXN0ZSgiYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2tfZGF0ZV9yYW5nZSIsIHRvbG93ZXIobmFtZSksIHNlcCA9ICJfIikNCiAgICBhZ2VfdmFyX25hbWUgPC0gcGFzdGUoImFnZV9hdF9hdmdfYm9keXdlaWdodF9sYXN0XzJ3ayIsIHRvbG93ZXIobmFtZSksIHNlcCA9ICJfIikNCiAgICANCiAgICAjIEFzc2lnbiBjYWxjdWxhdGVkIHZhbHVlcyB0byB0aGUgY29ycmVzcG9uZGluZyB2YXJpYWJsZXMNCiAgICBhc3NpZ24oYXZnX2JvZHl3ZWlnaHRfbGFzdF8yd2tfdmFyX25hbWUsIGF2Z19ib2R5d2VpZ2h0X2xhc3RfMndrLCBlbnZpciA9IC5HbG9iYWxFbnYpDQogICAgYXNzaWduKGRhdGVfcmFuZ2VfdmFyX25hbWUsIGRhdGVfcmFuZ2UsIGVudmlyID0gLkdsb2JhbEVudikNCiAgICBhc3NpZ24oYWdlX3Zhcl9uYW1lLCBjZWlsaW5nKGFnZV9hdF9hdmdfYm9keXdlaWdodF9sYXN0XzJ3ayksIGVudmlyID0gLkdsb2JhbEVudikNCiAgfQ0KDQogICMgU29ydCB0aGUgcmVzdWx0cyBieSBOYW1lDQogIHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayA8LSB0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2sgJT4lDQogICAgYXJyYW5nZShOYW1lKQ0KICANCiAgIyBSZXR1cm4gdGhlIHJlc3VsdHMgZGF0YSBmcmFtZQ0KICByZXR1cm4odGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrKQ0KfQ0KDQojIENhbGwgdGhlIGZ1bmN0aW9uIHRvIHBlcmZvcm0gdGhlIGFzc2lnbm1lbnRzIGFuZCBnZXQgdGhlIHJlc3VsdHMNCnRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayA8LSBhc3NpZ25fYXZlcmFnZV9ib2R5d2VpZ2h0KHZpdGFsc19kYXRhKQ0KDQojIFBlcmZvcm0gYSBsZWZ0IGpvaW4gdG8gY29tYmluZSB0aGUgZGF0YSBmcmFtZXMgYmFzZWQgb24gdGhlIE5hbWUgY29sdW1uDQp0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2sgPC0gbGVmdF9qb2luKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgZGVtb2dyYXBoaWNfbnIsIGJ5ID0gIk5hbWUiKQ0KDQojIFNlbGVjdCBhbmQgb3JkZXIgdGhlIGNvbHVtbnMNCnRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayA8LSB0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2sgJT4lDQogIHNlbGVjdChOYW1lLCBBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2ssIEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXaywgRGF0ZV9SYW5nZSkNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBjb2x1bW5zDQpuY29sdW1ucyA8LSBuY29sKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aykNCg0KIyBEZWZpbmUgdGhlIGNvbHVtbiB3aWR0aCByYXRpb3MNCmNvbHVtbl9yYXRpb3MgPC0gYygxLCAxLCAxLjUsIDEuNSkNCg0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIHJhdGlvDQp0b3RhbF9yYXRpbyA8LSBzdW0oY29sdW1uX3JhdGlvcykNCg0KIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2Ugd2lkdGggZm9yIGVhY2ggY29sdW1uDQpjb2x1bW5fd2lkdGhzIDwtIChjb2x1bW5fcmF0aW9zIC8gdG90YWxfcmF0aW8pICogMTAwDQoNCiMgUHJpbnQgdGhlIGNvbWJpbmVkIHRhYmxlIHVzaW5nIGtuaXRyOjprYWJsZQ0Ka25pdHI6OmthYmxlKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgZm9ybWF0ID0gImh0bWwiLCBjb2wubmFtZXMgPSBjKCJOYW1lIiwgIkFnZSBBdCBBdmcgQlciLCAiQXZlcmFnZSBCb2R5d2VpZ2h0IChsYnMpIiwgIkRhdGUgUmFuZ2UiKSwgYWxpZ24gPSBjKCJsIiwgImwiLCAibCIsICJsIikpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSBwYXN0ZTAoY29sdW1uX3dpZHRoc1sxXSwgIiUiKSkgJT4lDQogIGNvbHVtbl9zcGVjKDIsIHdpZHRoID0gcGFzdGUwKGNvbHVtbl93aWR0aHNbMl0sICIlIikpICU+JQ0KICBjb2x1bW5fc3BlYygzLCB3aWR0aCA9IHBhc3RlMChjb2x1bW5fd2lkdGhzWzNdLCAiJSIpKSAlPiUNCiAgY29sdW1uX3NwZWMoNCwgd2lkdGggPSBwYXN0ZTAoY29sdW1uX3dpZHRoc1s0XSwgIiUiKSkNCg0KIyBzdHIodGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrKQ0KDQpgYGANCg0KDQo8IS0tIEJhciBHcmFwaC0tPg0KYGBge3IgcGxvdF9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2ssIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQoNCiMgRW5zdXJlIE5hbWUgY29sdW1uIGhhcyBjb25zaXN0ZW50IG5hbWVzDQp0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skTmFtZSA8LSBnc3ViKCJfIiwgIiAiLCB0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skTmFtZSkNCg0KIyBVcGRhdGUgdGhlIGNvbG9yIHBhbGV0dGUgdG8gZW5zdXJlIGFsbCBuYW1lcyBhcmUgaW5jbHVkZWQNCmNvbG9yX3BhbGV0dGUgPC0gYnJld2VyLnBhbChuID0gbWluKDgsIGxlbmd0aCh1bmlxdWUodGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJE5hbWUpKSksICJEYXJrMiIpDQppZiAobGVuZ3RoKHVuaXF1ZSh0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skTmFtZSkpID4gOCkgew0KICBjb2xvcl9wYWxldHRlIDwtIHJlcChjb2xvcl9wYWxldHRlLCBsZW5ndGgub3V0ID0gbGVuZ3RoKHVuaXF1ZSh0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skTmFtZSkpKQ0KfQ0KbmFtZXMoY29sb3JfcGFsZXR0ZSkgPC0gdW5pcXVlKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayROYW1lKQ0KDQojIFBsb3QgdGhlIHJlc3VsdHMgdXNpbmcgZ2dwbG90Mg0KcGxvdF9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2sgPC0gZ2dwbG90KHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgYWVzKHggPSBOYW1lLCB5ID0gQXZlcmFnZV9Cb2R5d2VpZ2h0X0xhc3RfMldrLCBmaWxsID0gTmFtZSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2ssICIgbGJzXG4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCb2R5d2VpZ2h0XG5cbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXRlIFJhbmdlIFxuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViKCIgdG8uKiIsICIiLCBEYXRlX1JhbmdlKSwgIlxuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvXG4iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIoIi4qIHRvICIsICIiLCBEYXRlX1JhbmdlKSwgIlxuXG4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFnZV9BdF9BdmdfQm9keXdlaWdodF9MYXN0XzJXaywgIiB5ZWFycyBvbGQiKSksIA0KICAgICAgICAgICAgdmp1c3QgPSAxLjUsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JfcGFsZXR0ZSkgKyAgIyBNYXRjaGluZyBmaWxsIGNvbG9ycyB3aXRoIGNvbG9yIHBhbGV0dGUNCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEJvZHl3ZWlnaHQgT3ZlciBMYXN0IDIgV2Vla3MiLCB5ID0gIkF2ZXJhZ2UgQm9keXdlaWdodCAobGJzKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE2KSwgICMgTGFyZ2VyIGZvbnQgc2l6ZSBmb3IgdGhlIHRpdGxlDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgeC1heGlzIHRpdGxlDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksICAjIEZvbnQgc2l6ZSBmb3IgeS1heGlzIHRpdGxlDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgICMgRm9udCBzaXplIGZvciB4LWF4aXMgdGV4dDsgRm9yIGJvbGQgLSBmYWNlID0gImJvbGQiDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgICMgRm9udCBzaXplIGZvciB5LWF4aXMgdGV4dA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgICMgUmVtb3ZlIGxlZ2VuZA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJsaWdodGJsdWUiLCBjb2xvciA9IE5BKSwgICMgTGlnaHQgYmx1ZSBiYWNrZ3JvdW5kDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjUpLCAgIyBXaGl0ZSBtYWpvciBncmlkIGxpbmVzDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjUpICAjIFdoaXRlIG1pbm9yIGdyaWQgbGluZXMNCiAgKQ0KDQojIFByaW50IHRoZSBwbG90DQpwcmludChwbG90X2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aykNCg0KDQpgYGANCg0KIyMgQXZnIEJvZHl3ZWlnaHQgYnkgQWdlDQpUaGlzIHBsb3QgZGlzcGxheXMgZGF0YSBmb3IgYWxsIGluZGl2aWR1YWxzLiBUaGlzIGRhdGFzZXQtLWFnZSB2cyBib2R5d2VpZ2h0LS1pcyBzZWVtcyBsaW1pdGVkIGluIGlzb2xhdGlvbi4gV2l0aCBvdGhlciBkYXRhIHBvaW50cyBhbmQgY29udGV4dGlvbiBpbmZvcm1hdGlvbiBpdCBjYW4gb2ZmZXIgdmFsdWFibGUgaW5zaWdodHMscGFydGljdWxhcmx5IGlmIHVzZWQgIGl0IGNhbiBzdGlsbCBvZmZlciB2YWx1YWJsZSBpbnNpZ2h0cyB3aGVuIHVzZWQgYWxvbmdzaWRlIG90aGVyIGRhdGEgcG9pbnRzIGFuZCBjb250ZXh0dWFsIGluZm9ybWF0aW9uLiBJdHMgdXNlZnVsbmVzcyBsYXJnZWx5IGRlcGVuZHMgb24gaG93IGl0J3MgaW50ZXJwcmV0ZWQgYW5kIGludGVncmF0ZWQgaW50byBhIGJyb2FkZXIgYW5hbHlzaXMgZnJhbWV3b3JrLg0KDQo8IS0tIFBsYW4gdG8gY3JlYXRlIHNldCBvZiBob3Jpem9udGFsIGJhciBjaGFydHMsIG9uZSBmb3IgYm9keXdlaWdodCwgYW5vdGhlciBmb3IgZm9yIGFnZS4gU2hvdWxkIGxvb2sgbGlrZSBjb2x1bW4gbGVmdCA9IG5hbWVzLCBjb2x1bW4gbWlkZGxlID0gYm9keXdlaWdodCwgPSBjb2x1bW4gcmlnaHQgPSBhZ2UuIC0tPiANCg0KYGBge3IgcGxvdF9hdmdfYm9keXdlaWdodF9ieV9hZ2UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQoNCiMgRW5zdXJlIHRoZSBuZWNlc3NhcnkgbGlicmFyaWVzIGFyZSBsb2FkZWQNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KDQojIEVuc3VyZSBOYW1lIGNvbHVtbiBoYXMgY29uc2lzdGVudCBuYW1lcw0KdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJE5hbWUgPC0gZ3N1YigiXyIsICIgIiwgdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJE5hbWUpDQoNCiMgVXBkYXRlIHRoZSBjb2xvciBwYWxldHRlIHRvIGVuc3VyZSBhbGwgbmFtZXMgYXJlIGluY2x1ZGVkDQpjb2xvcl9wYWxldHRlIDwtIGJyZXdlci5wYWwobiA9IG1pbig4LCBsZW5ndGgodW5pcXVlKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayROYW1lKSkpLCAiRGFyazIiKQ0KaWYgKGxlbmd0aCh1bmlxdWUodGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJE5hbWUpKSA+IDgpIHsNCiAgY29sb3JfcGFsZXR0ZSA8LSByZXAoY29sb3JfcGFsZXR0ZSwgbGVuZ3RoLm91dCA9IGxlbmd0aCh1bmlxdWUodGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJE5hbWUpKSkNCn0NCm5hbWVzKGNvbG9yX3BhbGV0dGUpIDwtIHVuaXF1ZSh0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skTmFtZSkNCg0KIyBDb252ZXJ0IEFnZSB0byBudW1lcmljIA0KdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJEFnZV9BdF9BdmdfQm9keXdlaWdodF9MYXN0XzJXayA8LSBhcy5udW1lcmljKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayRBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2spDQoNCiMgQ2FsY3VsYXRlIG1pbiBhbmQgbWF4IGFnZXMgd2l0aCBidWZmZXINCm1pbl9hZ2UgPC0gbWluKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayRBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2ssIG5hLnJtID0gVFJVRSkgLSA0DQptYXhfYWdlIDwtIG1heCh0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2skQWdlX0F0X0F2Z19Cb2R5d2VpZ2h0X0xhc3RfMldrLCBuYS5ybSA9IFRSVUUpICsgNA0KDQojIENhbGN1bGF0ZSBtaW4gYW5kIG1heCBib2R5d2VpZ2h0cyB3aXRoIGJ1ZmZlcg0KbWluX2JvZHl3ZWlnaHQgPC0gZmxvb3IobWluKHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3ayRBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2ssIG5hLnJtID0gVFJVRSkgLyAxMCkgKiAxMA0KbWF4X2JvZHl3ZWlnaHQgPC0gY2VpbGluZyhtYXgodGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrJEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXaywgbmEucm0gPSBUUlVFKSAvIDEwKSAqIDEwDQoNCiMgQ3JlYXRlIGEgcGxvdCBmb3IgQm9keXdlaWdodCBieSBBZ2UNCnBsb3RfYWdlX2J5X2JvZHl3ZWlnaHQgPC0gZ2dwbG90KHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgYWVzKHggPSBBZ2VfQXRfQXZnX0JvZHl3ZWlnaHRfTGFzdF8yV2ssIHkgPSBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2ssIGNvbG9yID0gTmFtZSwgZmlsbCA9IE5hbWUpKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDUsIHNoYXBlID0gMjEsIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JfcGFsZXR0ZSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9wYWxldHRlKSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKG1pbl9hZ2UsIG1heF9hZ2UpLCBicmVha3MgPSBzZXEobWluX2FnZSwgbWF4X2FnZSwgYnkgPSAyKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYyhtaW5fYm9keXdlaWdodCwgbWF4X2JvZHl3ZWlnaHQpLCBicmVha3MgPSBzZXEobWluX2JvZHl3ZWlnaHQsIG1heF9ib2R5d2VpZ2h0LCBieSA9IDEwKSkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgQm9keXdlaWdodCBieSBBZ2UsIExhc3QgMiBXZWVrcyIsIHggPSAiQWdlIiwgeSA9ICJBdmVyYWdlIEJvZHl3ZWlnaHQgKGxicykiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxNiksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgbWlub3IgZ3JpZCBsaW5lcyBvbiB0aGUgeC1heGlzDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTkwIiksICMgTWFrZSBncmlkIGxpbmVzIGxpZ2h0ZXINCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMC44NSAqIDEyLCBmYWNlID0gIml0YWxpYyIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSANCg0KIyBQcmludCB0aGUgcGxvdA0KcHJpbnQocGxvdF9hZ2VfYnlfYm9keXdlaWdodCkNCg0KYGBgDQoNCiMgREFUQSBFTlRSSUVTIA0KVGhlIG1lYXQgYW5kIHBvdGF0b2VzLiBXaXRob3V0IHRoaXMsIHdoYXQncyB0aGUgcG9pbnQ/DQoNCmBgYHtyIHJhd19kYXRhX3RyYW5zZm9ybWF0aW9uLCBldmFsPVRSVUUsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIFNlbGVjdCB0aGUgZGVzaXJlZCBzaGVldA0Kc2VsZWN0ZWRfc2hlZXQgPC0gIlJhd19EYXRhIg0KcmF3X2RhdGEgPC0gcmVhZF9leGNlbChmaWxlX3BhdGhfa2RmLCBzaGVldCA9IHNlbGVjdGVkX3NoZWV0KQ0KDQojIERpc3BsYXkgZmlyc3QgZmV3IHJvd3MgYW5kIHN0cnVjdHVyZSBvZiB0aGUgZGF0YWZyYW1lLiBSdW4gZm9yIGNvbmZpcm1hdGlvbiBhcyBuZWVkZWQuDQojIGhlYWQocmF3X2RhdGEpDQojIHN0cihyYXdfZGF0YSkNCg0KIyBNYXJrZG93biBzZXBhcmF0b3IgdG8gYWRkIHNwYWNpbmcgYmV0d2VlbiBwbG90cw0KY2F0KCJcblxuIikNCg0KIyBDb252ZXJ0IHNlbGVjdGVkIGNvbHVtbnMgdG8gbnVtZXJpYw0KcmF3X2RhdGEgPC0gcmF3X2RhdGEgJT4lDQogIG11dGF0ZV9hdCh2YXJzKFdlaWdodCwgQmFyYmVsbF9XZWlnaHQsIFRvdGFsX1dlaWdodCwgRmluYWxfUmVwcywgYDFSTV9DYWxjdWxhdGVkX1dlaWdodGAsIFZvbHVtZSwgVElNRVZBTFVFKSwgYXMubnVtZXJpYykNCg0KIyBDb252ZXJ0IERhdGUgY29sdW1uIHRvIERhdGUgZm9ybWF0DQpyYXdfZGF0YSREYXRlIDwtIGFzLkRhdGUocmF3X2RhdGEkRGF0ZSwgZm9ybWF0ID0gIiVtLyVkLyVZIikgI0NvZGUgT0sgYXMgRGF0ZSAiMjAyMy0wMy0yOSINCiMgRm9sbG93aW5nIERhdGUgY29udmVyc2lvbnMgYmVsb3cgd2VyZSBlaXRoZXIgdW5zdWNjZXNzZnVsIG9yIHVuZGVzaXJhYmxlLiBVbmFibGUgdG8gZ2V0IHByb3BlciBjb2RlIGFzIERhdGUgIk1NL0REL1lZWVkiLiBUaGVyZWZvcmUgc2V0dGxlZCB3aXRoIHRoZSBhYm92ZSBEYXRlIGNvbnZlcnNpb24gYXMgIllZWVktTU0tREQuIg0KIyByYXdfZGF0YSREYXRlIDwtIG1keShyYXdfZGF0YSREYXRlKSAjQ2FtZSBCYWQ7IHJlc3VsdCBOQSAtIERvIE5vdCBVc2UgDQojIHJhd19kYXRhJERhdGUgPC0gZm9ybWF0KHJhd19kYXRhJERhdGUsIGZvcm1hdCA9ICIlbS8lZC8lWSIpICNDb2RlIE9LIGFzIGNociAiMDMvMjkvMjAyMyINCg0KIyBIYW5kbGUgbWlzc2luZyBEdXJhdGlvbiB2YWx1ZXMNCiMgcmF3X2RhdGEkRHVyYXRpb24gPC0gaG1zKHJhd19kYXRhJER1cmF0aW9uKSAjQ29kZSBCYWQ7ICJFcnJvcjogQWxsIGFyZ3VtZW50cyBtdXN0IGJlIG51bWVyaWMgb3IgTkEiLiBTaW5jZSBlcnJvcnMgZXhpc3QsIGl0IGlzIGJlc3QgdG8gcHJvY2VlZCB3aXRoIHRoZSBmb2xsb3dpbmc6IA0KcmF3X2RhdGEkRHVyYXRpb24gPC0gaWZlbHNlKHJhd19kYXRhJER1cmF0aW9uID09ICItIiwgTkEsIHJhd19kYXRhJER1cmF0aW9uKSAjQ29kZSBPSzsgdGhpcyBhbGxvd3MgbmV4dCBzdGVwIGhtcygpIG9yIGFzX2htcygpDQoNCiMgQ29udmVydCBEdXJhdGlvbiB0byBudW1lcmljIGFuZCB0aGVuIHRvIGhtcyBmb3JtYXQNCnJhd19kYXRhJER1cmF0aW9uIDwtIGFzLm51bWVyaWMocmF3X2RhdGEkRHVyYXRpb24pICNDb2RlIE9LOyBzYW1lIHJlc3VsdCBhcyBpZiBjb252ZXJ0aW5nIHRvIGRhdGEgdHlwZSBOdW1iZXIgaW4gRXhjZWwNCnJhd19kYXRhJER1cmF0aW9uIDwtIGFzX2htcyhyYXdfZGF0YSREdXJhdGlvbiAqIDg2NDAwKSAjQ29kZSBPSzsgbnVtZXJpYyBpcyBmaXJzdCBtdWx0aXBsaWVkIGJ5IHRoZSBudW1iZXIgb2Ygc2VjcyBpbiBhIGRheS4NCiAgICAjIE5vdGU6IGBhcy5obXMoKWAgd2FzIGRlcHJlY2F0ZWQgaW4gaG1zIDAuNS4wLlRoZXJlZm9yZSB1c2VkIGBhc19obXMoKWAgaW5zdGVhZC4NCiAgICAjIENvbnNpZGVyIHRvIGNoZWNrIGZvciBlcnJvcnM6IG9yaWdpbmFsIENTViBmaWxlIGhhZCBvbmUgdmFsdWUgIjA6MDE6NDU6MDQiIGluc3RlYWQgb2YgIjA6MDE6NDUuMDQiIHJlc3VsdGluZyBpbiBlcnJvciBhbmQgdGhlcmVmb3JlIGhhZCBub3QgY29udmVydGVkIHRvIG51bWVyaWMgY2hyLiBJc3N1ZSBoYXMgYmVlbiByZXNvbHZlZCBmb3IgZGF0YSB0cmFuc2Zvcm1hdGlvbi4NCg0KIyBGb3JtYXQgRHVyYXRpb24gY29sdW1uIChvcHRpb25hbCkNCmZvcm1hdHRlZF9kdXJhdGlvbiA8LSBzcHJpbnRmKCIlMDJkOiUwMmQ6JTA1LjJmIiwgaG91cihyYXdfZGF0YSREdXJhdGlvbiksIG1pbnV0ZShyYXdfZGF0YSREdXJhdGlvbiksIHNlY29uZChyYXdfZGF0YSREdXJhdGlvbikpICNNYXkgbm90IGJlIG5lY2Vzc2FyeS4NCg0KIyBUaGUgVmlldyBmdW5jdGlvbiBpcyB1c2VkIHRvIG9wZW4gdGhlIHJhd19kYXRhIGRhdGFmcmFtZSBpbiB0aGUgUlN0dWRpbyBkYXRhIHZpZXdlciBmb3IgaW50ZXJhY3RpdmUgZXhwbG9yYXRpb24uDQpWaWV3KHJhd19kYXRhKSAjUnVuIHRoaXMgbGluZSBvZiBjb2RlIHRvIHZpZXcgdGFibGUuIERvZXMgbm90IGFwcGx5IHdpdGgga25pdC4NCg0KIyBUaGUgcHJpbnQgZnVuY3Rpb24gaXMgdXNlZCB0byBkaXNwbGF5IHRoZSB0cmFuc2Zvcm1lZCByYXdfZGF0YSBkYXRhZnJhbWUgaW4gdGhlIFIgY29uc29sZS4NCiMgcHJpbnQocmF3X2RhdGEpDQoNCiMgc3RyIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZGlzcGxheSB0aGUgc3RydWN0dXJlIG9mIHRoZSByYXdfZGF0YSBkYXRhZnJhbWUuDQojIHN0cihyYXdfZGF0YSkNCmBgYA0KDQojIyBDb2x1bW4gRW50cmllcw0KVGhlIGZvbGxvd2luZyBjb2x1bW5zIGZyb20gdGhlIFJhdyBEYXRhIHNoZWV0IGluIHRoZSBLREYgV29ya2Jvb2sgYXJlIHNob3duIGJlbG93LiBOZWFybHkgYWxsIGNvbHVtbnMgYXJlIHV0aWxpemVkIGZvciBhbmFseXNlcywgYWx0aG91Z2ggc29tZSwgbGlrZSAiRHVyYXRpb24sIiBhcmUgcmFyZWx5IHJlY29yZGVkLiBNb3N0IG9mIG15IHdvcmtvdXRzIGFyZSBmb2N1c2VkIG9uIHN0cmVuZ3RoIHRyYWluaW5nIHJhdGhlciB0aGFuIGNhcmRpbyBhbmQgZW5kdXJhbmNlIHRyYWluaW5nLiBWb2x1bWUgbWVhc3VyZXMgaGF2ZSBhbHNvIG5vdCBiZWVuIGEgcHJpbWFyeSBmb2N1cyBjb21wYXJlZCB0byAxUk0gKG9uZS1yZXAgbWF4KSwgd2hpY2ggc2VydmVzIGFzIGEgcmVxdWlyZW1lbnQgZm9yIGNvbXBhcmlzb24gd2l0aCAxUk0gc3RyZW5ndGggc3RhbmRhcmRzLg0KDQpgYGB7ciByYXdfZGF0YV9jb2x1bW5zLCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQoNCiMjIFBsYW46IE1lcmdlIGhlYWRlci9jb2x1bW4ubmFtZXMgaWYgdGhlIHNhbWUuIFVuYWJsZSB0byBmaWd1cmUgb3V0IDA1LzExLzIwMjQuDQoNCiMgRXh0cmFjdCBjb2x1bW4gbmFtZXMgdml0YWxzX2RhdGENCmNvbHVtbl9uYW1lcyA8LSBjb2xuYW1lcyhyYXdfZGF0YSkNCiMgcHJpbnQoY29sdW1uX25hbWVzKQ0KIyBzdHIoY29sdW1uX25hbWVzKQ0KDQojIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIG5hbWVzDQpudW1fbmFtZXMgPC0gbGVuZ3RoKGNvbHVtbl9uYW1lcykNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcyBwZXIgY29sdW1uDQpuYW1lc19wZXJfY29sdW1uIDwtIGNlaWxpbmcobnVtX25hbWVzIC8gMikNCg0KIyBTcGxpdCB0aGUgbmFtZXMgaW50byB0d28gY29sdW1ucw0KY29sdW1uXzEgPC0gY29sdW1uX25hbWVzWzE6bWluKG5hbWVzX3Blcl9jb2x1bW4sIG51bV9uYW1lcyldDQpjb2x1bW5fMiA8LSBjb2x1bW5fbmFtZXNbKG1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpICsgMSk6bnVtX25hbWVzXQ0KDQojIFBhZCB0aGUgc2hvcnRlciBjb2x1bW4gd2l0aCBOQSB2YWx1ZXMgaWYgbmVjZXNzYXJ5DQppZihsZW5ndGgoY29sdW1uXzEpIDwgbGVuZ3RoKGNvbHVtbl8yKSkgew0KICBjb2x1bW5fMSA8LSBjKGNvbHVtbl8xLCByZXAoIiIsIGxlbmd0aChjb2x1bW5fMikgLSBsZW5ndGgoY29sdW1uXzEpKSkNCn0gZWxzZSBpZihsZW5ndGgoY29sdW1uXzIpIDwgbGVuZ3RoKGNvbHVtbl8xKSkgew0KICBjb2x1bW5fMiA8LSBjKGNvbHVtbl8yLCByZXAoIiIsIGxlbmd0aChjb2x1bW5fMSkgLSBsZW5ndGgoY29sdW1uXzIpKSkNCn0NCg0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggdHdvIGNvbHVtbnMNCmNvbHVtbl9uYW1lc19kZiA8LSBkYXRhLmZyYW1lKENvbHVtbl8xID0gY29sdW1uXzEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW5fMiA9IGNvbHVtbl8yKQ0KDQojIENhbGN1bGF0ZSB0aGUgd2lkdGggZHluYW1pY2FsbHkNCmNvbF93aWR0aCA8LSBwYXN0ZTAoMTAwIC8gbmNvbChjb2x1bW5fbmFtZXNfZGYpLCAiJSIpDQoNCiMgUHJpbnQgdGhlIGRhdGEgZnJhbWUgdXNpbmcga25pdHI6OmthYmxlDQprbml0cjo6a2FibGUoY29sdW1uX25hbWVzX2RmLCBmb3JtYXQgPSAibWFya2Rvd24iLCBjb2wubmFtZXMgPSBjKCJDb2x1bW4gTmFtZXMiLCAiQ29sdW1uIE5hbWVzIikpICU+JQ0KDQogIGNvbHVtbl9zcGVjKDE6Miwgd2lkdGggPSBjb2xfd2lkdGgsIGV4dHJhX2NzcyA9ICJ0ZXh0LWFsaWduOiBsZWZ0OyIpDQoNCmBgYA0KDQojIyBFeGVyY2lzZSBWYXJpYXRpb25zIExpc3QNCg0KRW50cmllcyBmcm9tIGByYXdfZGF0YWAgYXJlIGV4dHJhY3RlZCBmb3IgZnVydGhlciBhbmFseXNpcy4gV2hldGhlciBpbmRvb3JzIG9yIG91dGRvb3JzLCB1c2luZyBjYWxpc3RoZW5pY3Mgb3IgZXF1aXBtZW50LCBwZXJmb3JtaW5nIGFlcm9iaWMgb3IgYW5hZXJvYmljIGV4ZXJjaXNlcywgdGhlcmUgYXJlIGNvdW50bGVzcyBleGVyY2lzZXMgYW5kIHdheXMgdG8gcGVyZm9ybSB0aGVtLiBUaGVzZSBleGVyY2lzZXMgdmFyeSBpbiBpbnN0cnVtZW50cyBhbmQgcG9zaXRpb25zIHVzZWQsIHJlcXVpcmluZyBkaWZmZXJlbnQgbXVzY2xlIGFjdGl2YXRpb24uDQoNCk5vdCBpbmNsdWRlZCBpbiB0aGUgbGlzdHMgYXJlIGVudHJpZXMgcGVydGFpbmluZyB0byBkaWZmZXJlbnQgZ3JpcHMgKHdpZGUsIG1pZCwgY2xvc2UsIHVuZGVyaGFuZCwgb3ZlcmhhbmQsIG5ldXRyYWwsIGFuZCBhbHRlcm5hdGUsIHN1Y2ggYXMgZm9yIGRlYWRsaWZ0cykuIEEgV2lkZSBHcmlwIEJpY2VwIEN1cmwgdXRpbGl6ZXMgZXh0ZXJuYWwgcm90YXRpb24sIGxpbWl0cyB0aGUgcmFuZ2Ugb2YgbW90aW9uIGFsbG93aW5nIGZvciBoZWF2aWVyIHdlaWdodHMsIHBsYWNlcyBtb3JlIHN0cmVzcyBvbiB0aGUgZWxib3cgam9pbnRzLCBlbXBoYXNpemVzIHRoZSBzaG9ydCBoZWFkIG9mIHRoZSBiaWNlcHMsIGFuZCBlbmdhZ2VzIHRoZSB1cHBlciBiYWNrIGFuZCBzaG91bGRlcnMuIEluIGNvbnRyYXN0LCBhIENsb3NlIEdyaXAgQmljZXAgQ3VybCB1dGlsaXplcyBpbnRlcm5hbCByb3RhdGlvbiwgYWxsb3dzIGZvciBhIGdyZWF0ZXIgcmFuZ2Ugb2YgbW90aW9uLCBmb2N1c2VzIG9uIHRoZSBsb25nIGhlYWQgb2YgdGhlIGJpY2VwcywgYW5kIGVuZ2FnZXMgdGhlIGZvcmVhcm0gbXVzY2xlcy5bXjEyXSBbXjEzXQ0KDQpgYGB7ciB1bmlxdWVfY3JpdGVyaWEsIGV2YWw9VFJVRX0NCg0KcmF3X2RhdGFfdW5pcXVlX25hbWUgPC0gc29ydCh1bmlxdWUocmF3X2RhdGEkTmFtZSkpDQpyYXdfZGF0YV91bmlxdWVfcG9zaXRpb24gPC0gc29ydCh1bmlxdWUocmF3X2RhdGEkUG9zaXRpb24pKQ0KcmF3X2RhdGFfdW5pcXVlX2luc3RydW1lbnQgPC0gc29ydCh1bmlxdWUocmF3X2RhdGEkSW5zdHJ1bWVudCkpDQpyYXdfZGF0YV91bmlxdWVfYWN0aXZpdHkgPC0gc29ydCh1bmlxdWUocmF3X2RhdGEkQWN0aXZpdHkpKQ0KDQojIEZpbHRlciBvdXQgIi0iIGZyb20gcmF3X2RhdGFfdW5pcXVlJ3MNCnJhd19kYXRhX3VuaXF1ZV9uYW1lIDwtIHJhd19kYXRhX3VuaXF1ZV9uYW1lW3Jhd19kYXRhX3VuaXF1ZV9uYW1lICE9ICItIl0NCnJhd19kYXRhX3VuaXF1ZV9wb3NpdGlvbiA8LSByYXdfZGF0YV91bmlxdWVfcG9zaXRpb25bcmF3X2RhdGFfdW5pcXVlX3Bvc2l0aW9uICE9ICItIl0NCnJhd19kYXRhX3VuaXF1ZV9pbnN0cnVtZW50IDwtIHJhd19kYXRhX3VuaXF1ZV9pbnN0cnVtZW50W3Jhd19kYXRhX3VuaXF1ZV9pbnN0cnVtZW50ICE9ICItIl0NCnJhd19kYXRhX3VuaXF1ZV9hY3Rpdml0eSA8LSByYXdfZGF0YV91bmlxdWVfYWN0aXZpdHlbcmF3X2RhdGFfdW5pcXVlX2FjdGl2aXR5ICE9ICItIl0NCg0KYGBgDQoNCjwhLS1JbmRpdmlkdWFscyBlbnRlcmVkOg0KYGBge3IgcmF3X2RhdGFfdW5pcXVlX25hbWUsIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCiMgSU5ESVZJRFVBTFMgRU5URVJFRDoNCiMgcHJpbnQocmF3X2RhdGFfdW5pcXVlX25hbWUpDQoNCiMgUHJpbnQgdGhlIGRhdGEgZnJhbWUgdXNpbmcga25pdHI6OmthYmxlDQprbml0cjo6a2FibGUocmF3X2RhdGFfdW5pcXVlX25hbWUsIGZvcm1hdCA9ICJtYXJrZG93biIsIGNvbC5uYW1lcyA9ICJJbmRpdmlkdWFscyIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAgIyBFbnN1cmUgZnVsbC13aWR0aCB0YWJsZSB3aXRoIGVxdWFsIGNvbHVtbiB3aWR0aA0KDQpgYGANCi0tPg0KDQojIyBQb3NpdGlvbnMNCkluY29ycG9yYXRpbmcgZGlmZmVyZW50IHBvc2l0aW9ucyBpbnRvIGEgd29ya291dCByb3V0aW5lIGNhbiBlbmhhbmNlIG11c2NsZSBkZXZlbG9wbWVudCwgaW1wcm92ZSBmdW5jdGlvbmFsIHN0cmVuZ3RoLCBhbmQgcmVkdWNlIHRoZSByaXNrIG9mIG92ZXJ1c2UgaW5qdXJpZXMgYnkgZW5zdXJpbmcgYSBiYWxhbmNlZCB3b3Jrb3V0Lg0KDQpgYGB7ciByYXdfZGF0YV91bmlxdWVfcG9zaXRpb24sIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCiMgUE9TSVRJT05TIFVTRUQ6DQojIHByaW50KHJhd19kYXRhX3VuaXF1ZV9wb3NpdGlvbikNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcw0KbnVtX25hbWVzIDwtIGxlbmd0aChyYXdfZGF0YV91bmlxdWVfcG9zaXRpb24pDQoNCiMgQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgbmFtZXMgcGVyIGNvbHVtbg0KbmFtZXNfcGVyX2NvbHVtbiA8LSBjZWlsaW5nKG51bV9uYW1lcyAvIDIpDQoNCiMgU3BsaXQgdGhlIG5hbWVzIGludG8gdHdvIGNvbHVtbnMNCmNvbHVtbl8xIDwtIHJhd19kYXRhX3VuaXF1ZV9wb3NpdGlvblsxOm1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpXQ0KY29sdW1uXzIgPC0gcmF3X2RhdGFfdW5pcXVlX3Bvc2l0aW9uWyhtaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKSArIDEpOm51bV9uYW1lc10NCg0KIyBQYWQgdGhlIHNob3J0ZXIgY29sdW1uIHdpdGggTkEgdmFsdWVzIGlmIG5lY2Vzc2FyeQ0KaWYobGVuZ3RoKGNvbHVtbl8xKSA8IGxlbmd0aChjb2x1bW5fMikpIHsNCiAgY29sdW1uXzEgPC0gYyhjb2x1bW5fMSwgcmVwKCIiLCBsZW5ndGgoY29sdW1uXzIpIC0gbGVuZ3RoKGNvbHVtbl8xKSkpDQp9IGVsc2UgaWYobGVuZ3RoKGNvbHVtbl8yKSA8IGxlbmd0aChjb2x1bW5fMSkpIHsNCiAgY29sdW1uXzIgPC0gYyhjb2x1bW5fMiwgcmVwKCIiLCBsZW5ndGgoY29sdW1uXzEpIC0gbGVuZ3RoKGNvbHVtbl8yKSkpDQp9DQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHR3byBjb2x1bW5zDQpyYXdfZGF0YV91bmlxdWVfcG9zaXRpb25fZGYgPC0gZGF0YS5mcmFtZShDb2x1bW5fMSA9IGNvbHVtbl8xLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uXzIgPSBjb2x1bW5fMikNCg0KIyBDYWxjdWxhdGUgdGhlIHdpZHRoIGR5bmFtaWNhbGx5DQpjb2xfd2lkdGggPC0gcGFzdGUwKDEwMCAvIG5jb2wocmF3X2RhdGFfdW5pcXVlX3Bvc2l0aW9uX2RmKSwgIiUiKQ0KDQojIFByaW50IHRoZSBkYXRhIGZyYW1lIHVzaW5nIGtuaXRyOjprYWJsZQ0Ka25pdHI6OmthYmxlKHJhd19kYXRhX3VuaXF1ZV9wb3NpdGlvbl9kZiwgZm9ybWF0ID0gIm1hcmtkb3duIiwgY29sLm5hbWVzID0gYygiUG9zaXRpb25zIiwgIlBvc2l0aW9ucyIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMToyLCB3aWR0aCA9IGNvbF93aWR0aCwgZXh0cmFfY3NzID0gInRleHQtYWxpZ246IGxlZnQ7IikNCg0KYGBgDQoNCiMjIEluc3RydW1lbnRzIA0KVXNpbmcgYSB2YXJpZXR5IG9mIGluc3RydW1lbnRzIGluIHdvcmtvdXRzIGNhbiBoZWxwIHRhcmdldCBkaWZmZXJlbnQgbXVzY2xlIGdyb3VwcyBtb3JlIGVmZmVjdGl2ZWx5LCBwcm92aWRlIHZhcmllZCByZXNpc3RhbmNlLCBhbmQgb2ZmZXIgc2FmZXIgYW5kIG1vcmUgZWZmaWNpZW50IGV4ZXJjaXNlIG9wdGlvbnMuDQoNCmBgYHtyIHJhd19kYXRhX3VuaXF1ZV9pbnN0cnVtZW50LCBldmFsPVRSVUUsIHJlc3VsdHM9J21hcmt1cCd9DQojIElOU1RSVU1FTlRTIFVTRUQ6IA0KIyBwcmludChyYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudCkNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcw0KbnVtX25hbWVzIDwtIGxlbmd0aChyYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudCkNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcyBwZXIgY29sdW1uDQpuYW1lc19wZXJfY29sdW1uIDwtIGNlaWxpbmcobnVtX25hbWVzIC8gMykNCg0KIyBTcGxpdCB0aGUgbmFtZXMgaW50byB0aHJlZSBjb2x1bW5zDQpjb2x1bW5fMSA8LSByYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudFsxOm1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpXQ0KY29sdW1uXzIgPC0gcmF3X2RhdGFfdW5pcXVlX2luc3RydW1lbnRbKG1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpICsgMSk6KDIgKiBtaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKSldDQpjb2x1bW5fMyA8LSByYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudFsoKDIgKiBtaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKSkgKyAxKTpudW1fbmFtZXNdDQoNCiMgUGFkIHRoZSBzaG9ydGVyIGNvbHVtbnMgd2l0aCBOQSB2YWx1ZXMgaWYgbmVjZXNzYXJ5DQptYXhfbGVuZ3RoIDwtIG1heChsZW5ndGgoY29sdW1uXzEpLCBsZW5ndGgoY29sdW1uXzIpLCBsZW5ndGgoY29sdW1uXzMpKQ0KY29sdW1uXzEgPC0gYyhjb2x1bW5fMSwgcmVwKCIiLCBtYXhfbGVuZ3RoIC0gbGVuZ3RoKGNvbHVtbl8xKSkpDQpjb2x1bW5fMiA8LSBjKGNvbHVtbl8yLCByZXAoIiIsIG1heF9sZW5ndGggLSBsZW5ndGgoY29sdW1uXzIpKSkNCmNvbHVtbl8zIDwtIGMoY29sdW1uXzMsIHJlcCgiIiwgbWF4X2xlbmd0aCAtIGxlbmd0aChjb2x1bW5fMykpKQ0KDQojIENyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCB0d28gY29sdW1ucw0KcmF3X2RhdGFfdW5pcXVlX2luc3RydW1lbnRfZGYgPC0gZGF0YS5mcmFtZShDb2x1bW5fMSA9IGNvbHVtbl8xLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW5fMiA9IGNvbHVtbl8yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW5fMyA9IGNvbHVtbl8zKQ0KDQojIENhbGN1bGF0ZSB0aGUgd2lkdGggZHluYW1pY2FsbHkNCmNvbF93aWR0aCA8LSBwYXN0ZTAoMTAwIC8gbmNvbChyYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudF9kZiksICIlIikNCg0KIyBQcmludCB0aGUgZGF0YSBmcmFtZSB1c2luZyBrbml0cjo6a2FibGUNCmtuaXRyOjprYWJsZShyYXdfZGF0YV91bmlxdWVfaW5zdHJ1bWVudF9kZiwgZm9ybWF0ID0gIm1hcmtkb3duIiwgY29sLm5hbWVzID0gYygiSW5zdHJ1bWVudHMiLCAiSW5zdHJ1bWVudHMiLCAiSW5zdHJ1bWVudHMiKSkgJT4lDQogIGNvbHVtbl9zcGVjKDE6Mywgd2lkdGggPSBjb2xfd2lkdGgsIGV4dHJhX2NzcyA9ICJ0ZXh0LWFsaWduOiBsZWZ0OyIpDQoNCmBgYA0KDQojIyBBY3Rpdml0aWVzIA0KVGhlIGZvbGxvd2luZyBhY3Rpdml0aWVzIChvciBleGVyY2lzZXMpIGhhdmUgYmVlbiBlbnRlcmVkIGludG8gdGhlIFJhdyBEYXRhLiBPdGhlciBhY3Rpdml0aWVzIGFyZSBhdmFpbGFibGUgYnV0IGhhdmUgbm90IGJlZW4gcGVyZm9ybWVkLiBTb21lLCBzdWNoIGFzIOKAnFRyYWNrIExhbmUgNizigJ0gYXJlIHNwZWNpZmljIHRvIGxvY2F0aW9uIGFuZCB0aW1lIGR1cmF0aW9uLiBPdGhlciBhY3Rpdml0aWVzIGFyZSB1bml2ZXJzYWxseSBhdmFpbGFibGUsIHN1Y2ggYXMgQ2hlc3QgUHJlc3MgYW5kIExhdCBQdWxsZG93bi4gSG93ZXZlciwgd2hlbiB0aW1lIGlzIGEgZmFjdG9yLCBzb21ldGltZXMgeW914oCZdmUgZ290IHRvIHBpdm90IGFuZCBpbXByb3Zpc2UgeW91ciB3b3Jrb3V0IHdpdGggb3RoZXIgdHlwZXMgb2YgZXhlcmNpc2VzLg0KDQpgYGB7ciByYXdfZGF0YV91bmlxdWVfYWN0aXZpdHksIGV2YWw9VFJVRSwgcmVzdWx0cz0nbWFya3VwJ30NCiMgQUNUSVZJVElFUyBQRVJGT1JNRUQNCiMgcHJpbnQocmF3X2RhdGFfdW5pcXVlX2FjdGl2aXR5KQ0KDQojIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIG5hbWVzDQpudW1fbmFtZXMgPC0gbGVuZ3RoKHJhd19kYXRhX3VuaXF1ZV9hY3Rpdml0eSkNCg0KIyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBuYW1lcyBwZXIgY29sdW1uDQpuYW1lc19wZXJfY29sdW1uIDwtIGNlaWxpbmcobnVtX25hbWVzIC8gMykNCg0KIyBTcGxpdCB0aGUgbmFtZXMgaW50byB0aHJlZSBjb2x1bW5zDQpjb2x1bW5fMSA8LSByYXdfZGF0YV91bmlxdWVfYWN0aXZpdHlbMTptaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKV0NCmNvbHVtbl8yIDwtIHJhd19kYXRhX3VuaXF1ZV9hY3Rpdml0eVsobWluKG5hbWVzX3Blcl9jb2x1bW4sIG51bV9uYW1lcykgKyAxKTooMiAqIG1pbihuYW1lc19wZXJfY29sdW1uLCBudW1fbmFtZXMpKV0NCmNvbHVtbl8zIDwtIHJhd19kYXRhX3VuaXF1ZV9hY3Rpdml0eVsoKDIgKiBtaW4obmFtZXNfcGVyX2NvbHVtbiwgbnVtX25hbWVzKSkgKyAxKTpudW1fbmFtZXNdDQoNCiMgUGFkIHRoZSBzaG9ydGVyIGNvbHVtbnMgd2l0aCBOQSB2YWx1ZXMgaWYgbmVjZXNzYXJ5DQptYXhfbGVuZ3RoIDwtIG1heChsZW5ndGgoY29sdW1uXzEpLCBsZW5ndGgoY29sdW1uXzIpLCBsZW5ndGgoY29sdW1uXzMpKQ0KY29sdW1uXzEgPC0gYyhjb2x1bW5fMSwgcmVwKCIiLCBtYXhfbGVuZ3RoIC0gbGVuZ3RoKGNvbHVtbl8xKSkpDQpjb2x1bW5fMiA8LSBjKGNvbHVtbl8yLCByZXAoIiIsIG1heF9sZW5ndGggLSBsZW5ndGgoY29sdW1uXzIpKSkNCmNvbHVtbl8zIDwtIGMoY29sdW1uXzMsIHJlcCgiIiwgbWF4X2xlbmd0aCAtIGxlbmd0aChjb2x1bW5fMykpKQ0KDQojIENyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCB0d28gY29sdW1ucw0KcmF3X2RhdGFfdW5pcXVlX2FjdGl2aXR5X2RmIDwtIGRhdGEuZnJhbWUoQ29sdW1uXzEgPSBjb2x1bW5fMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbHVtbl8yID0gY29sdW1uXzIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW5fMyA9IGNvbHVtbl8zKQ0KDQojIENhbGN1bGF0ZSB0aGUgd2lkdGggZHluYW1pY2FsbHkNCmNvbF93aWR0aCA8LSBwYXN0ZTAoMTAwIC8gbmNvbChyYXdfZGF0YV91bmlxdWVfYWN0aXZpdHlfZGYpLCAiJSIpDQoNCiMgUHJpbnQgdGhlIGRhdGEgZnJhbWUgdXNpbmcga25pdHI6OmthYmxlDQprbml0cjo6a2FibGUocmF3X2RhdGFfdW5pcXVlX2FjdGl2aXR5X2RmLCBmb3JtYXQgPSAibWFya2Rvd24iLCBjb2wubmFtZXMgPSBjKCJBY3Rpdml0aWVzIiwgIkFjdGl2aXRpZXMiLCAiQWN0aXZpdGllcyIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMTozLCB3aWR0aCA9IGNvbF93aWR0aCwgZXh0cmFfY3NzID0gInRleHQtYWxpZ246IGxlZnQ7IikNCmBgYA0KDQojIFBFUkZPUk1BTkNFIEFOQUxZU0VTIA0KIyMgV2VpZ2h0cyBFeGVjdXRlZCBPdmVyIFRpbWUsIDMtNC01KyBSZXBzDQoNClRoaXMgc2V0IG9mIHN0YXRpc3RpY3MgaXMgaWRlYWwgZm9yIGF0aGxldGVzIG9yIHRyYWluZXJzIHdobyB3YW50IHRvIHRyYWNrIHBlcmZvcm1hbmNlIG92ZXIgdGltZSwgcGFydGljdWxhcmx5IGluIG9ic2VydmluZyBob3cgbWF4aW11bSBsaWZ0aW5nIGNhcGFjaXR5IGV2b2x2ZXMgYWNyb3NzIGRpZmZlcmVudCB3b3Jrb3V0cyBhbmQgcmVwIHRocmVzaG9sZHMuIFRoZSB2aXN1YWxpemF0aW9ucyBhbmQgc3RhdGlzdGljcyBnZW5lcmF0ZWQgY2FuIGFzc2lzdCBpbiBhZGp1c3RpbmcgdHJhaW5pbmcgcHJvZ3JhbXMgYmFzZWQgb24gb2JzZXJ2ZWQgdHJlbmRzIGFuZCBwZXJmb3JtYW5jZSBwbGF0ZWF1cy4NCg0KVGhlIGZvbGxvd2luZyBmaWd1cmVzIGFyZSBpbnNwaXJlZCBieSB0aGUgNXg1IFRyYWluaW5nIE1vZGVsLiBGcm9tIGFyb3VuZCBTZXB0ZW1iZXIgMjAyMyB0byBBcHJpbCAyMDI0LCBJIHByaW1hcmlseSBmb2N1c2VkIG9uIDUgc2V0cyBvZiA1IHJlcHMsIGluY3JlbWVudGFsbHkgYWRkaW5nIHdlaWdodCBhZnRlciBzdWNjZXNzZnVsbHkgZXhlY3V0aW5nIDUgcmVwcy4gSSBkaWQgbm90IGFkaGVyZSB0byBhIHNpbmdsZSBhcHByb2FjaCBmb3IgcGVyZm9ybWluZyB0aGUgNXg1J3MsIGFzIHRoZXJlIGFyZSB2YXJpb3VzIHBlcnNwZWN0aXZlcyBhbmQgd29ya291dCBtb2RlbHMuIEZvciBpbnN0YW5jZSwgaW4gaGlzICJUaGUgNcOXNSBXb3Jrb3V0IEV4cGxhaW5lZCIgKDIwMjMpIGFydGljbGVbXjE0XSwgQ29sdWNjaSBleHBsb3JlcyB0aGUgNXg1IHdvcmtvdXQgcHJvZ3JhbS4gSGUgbWVudGlvbnMgaXRzIGhpc3Rvcnkgd2l0aCBSZWcgUGFyayB3aG9tIHByb3Bvc2VkIHN0YXJ0aW5nIHdpdGggcHJvZ3Jlc3NpdmVseSBoZWF2aWVyIHdhcm0tdXAgc2V0cyBmb3IgdGhlIGZpcnN0IHR3byBzZXRzLCBmb2xsb3dlZCBieSB0aHJlZSBzZXRzIGF0IHRoZSBzYW1lIGhlYXZpZXIgd2VpZ2h0IGZvciB0aGUgZmluYWwgdGhyZWUgc2V0cy4gDQoNClRoZSA1w5c1IHdvcmtvdXQgcHJvZ3JhbSBpcyBkZXNpZ25lZCB0byBidWlsZCBtdXNjbGUgc2l6ZSBhbmQgc3RyZW5ndGggYnkgZm9jdXNpbmcgb24gcGVyZm9ybWluZyBmaXZlIHNldHMgb2YgZml2ZSByZXBldGl0aW9ucyBvZiBtYWpvciBjb21wb3VuZCBleGVyY2lzZXMgbGlrZSBzcXVhdHMsIGJlbmNoIHByZXNzZXMsIGFuZCBkZWFkbGlmdHMuIEl0IGVtcGhhc2l6ZXMgdXNpbmcgcHJvZ3Jlc3NpdmVseSBoZWF2aWVyIHdlaWdodHMgd2l0aCBhZGVxdWF0ZSByZXN0IGludGVydmFscyB0byBlbnN1cmUgcHJvcGVyIHJlY292ZXJ5IGFuZCBlZmZpY2llbnQgbXVzY2xlIGRldmVsb3BtZW50LiBUaGlzIHJvdXRpbmUgaXMgcGFydGljdWxhcmx5IGJlbmVmaWNpYWwgZm9yIGJlZ2lubmVycyB0byBlc3RhYmxpc2ggYSBzb2xpZCBzdHJlbmd0aCBmb3VuZGF0aW9uIGFuZCBmb3IgZXhwZXJpZW5jZWQgbGlmdGVycyBsb29raW5nIHRvIG1haW50YWluIG9yIGluY3JlYXNlIG11c2NsZSBtYXNzIGFuZCBzdHJlbmd0aC4gDQoNCiMjIE1ldHJpY3MgVGFibGUNClRoZSBmb2xsb3dpbmcgdGFibGVzIGFuZCBwbG90cyBoaWdobGlnaHQgcGVyZm9ybWFuY2Ugb3ZlciB0aW1lIGZvciB3b3Jrb3V0cyBiYXNlZCBvbiBzZWxlY3RlZCBjcml0ZXJpYS4gVGhpcyB0YWJsZSBzZXJ2ZXMgYXMgYSByZWZlcmVuY2UgZm9yIGhvdyBlYWNoIG1ldHJpYyBtYXkgYmUgdXNlZCB0byBjb21wYXJlIHdpdGggdGhlIG90aGVycy4NCg0KYGBge3Igc3RhdGlzdGljc190YWJsZV9ndWlkZSwgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30gIA0KDQojIEVuc3VyZSB0aGUgbmVjZXNzYXJ5IGxpYnJhcmllcyBhcmUgbG9hZGVkDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCiMgUHJpbnQgdGhlIHN0YXRpc3RpY3MgZm9yIHRoZSBjdXJyZW50IHBsb3QgYXMgYSB0YWJsZQ0Kc3RhdGlzdGljc190YWJsZSA8LSBkYXRhLmZyYW1lKA0KICBNZXRyaWMgPSBjKA0KICAgICJBdmVyYWdlIFdlaWdodCBFeGVjdXRlZCBQZXIgU2V0IiwNCiAgICAiQXZlcmFnZSAxUk0gQ2FsY3VsYXRlZCBXZWlnaHQgUGVyIFNldCIsDQogICAgIkhpZ2hlc3QgMVJNIENhbGN1bGF0ZWQgV2VpZ2h0IiwNCiAgICAiSGlnaGVzdCAxUk0gQ2FsY3VsYXRlZCBXZWlnaHQiLA0KICAgICJIaWdoZXN0IFdlaWdodCBFeGVjdXRlZCBhdCA1KyBSZXBzIg0KICApLA0KDQogIFJhbmdlID0gYygNCiAgICAiTGFzdCAyIFdlZWtzIiwNCiAgICAiTGFzdCAyIFdlZWtzIiwNCiAgICAiTGFzdCAyIFdlZWtzIiwNCiAgICAiQWxsIFRpbWUiLA0KICAgICJBbGwgVGltZSINCiAgKSwNCiAgDQogIEV4cGxhbmF0aW9uID0gYygNCiAgICAiUHJvdmlkZXMgY29udGV4dCB0byB0aGUgQXZlcmFnZSAxUk0gQ2FsY3VsYXRlZCBXZWlnaHQgTGFzdCAyIFdlZWtzIGJ5IGluZGljYXRpbmcgdGhlIGF2ZXJhZ2UgZWZmb3J0IHBlciBzZXQiLA0KICAgICJIZWxwcyB0byBnYXVnZSBpZiByZWNlbnQgdHJhaW5pbmcgc2Vzc2lvbnMgaGF2ZSBiZWVuIGVmZmVjdGl2ZSBpbiBtYWludGFpbmluZyBvciBpbmNyZWFzaW5nIHN0cmVuZ3RoIGxldmVscywgY29tcGFyZWQgdG8gdGhlIGF2ZXJhZ2Ugd2VpZ2h0cyBleGVjdXRlZCBwZXIgc2V0LiIsDQogICAgIkluZGljYXRlcyB0aGUgaGlnaGVzdCBzdHJlbmd0aCBhY2hpZXZlbWVudCBpbiB0aGUgcmVjZW50IHBlcmlvZCBhbmQgY2FuIGJlIGNvbXBhcmVkIGFnYWluc3QgdGhlIGFsbC10aW1lIDFSTSB0byBzZWUgaWYgcmVjZW50IHRyYWluaW5nIGlzIGFsaWduaW5nIHdpdGggcGVhayBoaXN0b3JpY2FsIHBlcmZvcm1hbmNlLiIsDQogICAgIlByb3ZpZGVzIGEgcmVmZXJlbmNlIHBvaW50IGZvciBldmFsdWF0aW5nIGN1cnJlbnQgcGVyZm9ybWFuY2UgdHJlbmRzLiBGb3IgaW5zdGFuY2UsIGNvbXBhcmluZyB0aGUgSGlnaGVzdCAxUk0gQ2FsY3VsYXRlZCBXZWlnaHQgTGFzdCAyIFdlZWtzIHRvIHRoaXMgdmFsdWUgc2hvd3MgaWYgY3VycmVudCBzdHJlbmd0aCBsZXZlbHMgYXJlIGFwcHJvYWNoaW5nLCBtYWludGFpbmluZywgb3IgZmFsbGluZyBzaG9ydCBvZiBwZWFrIGhpc3RvcmljYWwgcGVyZm9ybWFuY2UuIFRoaXMgQVRIIChhbGwgdGltZSBoaWdoKSBtZXRyaWMgaXMgdGhlIG9uZSB0byBiZSBjb25zdGFudGx5IHN0cml2aW5nIHRvIG1lZXQsIGlmIG5vdCBzdXJwYXNzLiBSZXZpZXdpbmcgdGhlIHRpbWVsaW5lIGFzIHRvIHdoZW4gQVRIJ3Mgb2NjdXJlZCBoZWxwcyB0byBwcm92aWRlIGluc2lnaHQgaW50byB0aGUgcGF0dGVybnMgYW5kIGV2ZW50cyB0aGF0IHJlc3VsdGVkIGluIGVpdGhlciBncm93dGgsIG1haW50ZW5hbmNlLCBvciBkZWNsaW5lLiBGb3IgZXhhbXBsZSwgYSB0cmlwIHgyIHdlZWtzIG91dCBvZiB0aGUgY291bnRyeSB3YXMgYWNjb21wYW5pZWQgYnkgZGVjbGluZSBpbiBzdHJlbmd0aC1iYXNlZCBhY3Rpdml0aWVzLCBsZWFkaW5nIHRvIGEgZGVjbGluZSBvbiBwZXJmb3JtYW5jZS4iLA0KICAgICJUaGlzIG1ldHJpYyBjb21wbGVtZW50cyB0aGUgMVJNIHZhbHVlcyBieSBwcm92aWRpbmcgaW5zaWdodCBpbnRvIHN0cmVuZ3RoIGVuZHVyYW5jZS4gQ29tcGFyaW5nIGl0IHdpdGggdGhlIEF2ZXJhZ2UgV2VpZ2h0IEV4ZWN1dGVkIFBlciBTZXQgTGFzdCAyIFdlZWtzIGNhbiBpbmRpY2F0ZSBpbXByb3ZlbWVudHMgb3IgZGVjbGluZXMgaW4gc3VzdGFpbmVkIHN0cmVuZ3RoIG92ZXIgdGltZS4gIg0KICApDQopDQoNCiMgUHJpbnQgdGhlIHRhYmxlIHVzaW5nIGtuaXRyOjprYWJsZQ0Ka2FibGUoc3RhdGlzdGljc190YWJsZSwgZm9ybWF0ID0gImh0bWwiLCB0YWJsZS5hdHRyID0gImNsYXNzPSd0YWJsZSB0YWJsZS1zdHJpcGVkJyIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiMiUiKSAlPiUNCiAgY29sdW1uX3NwZWMoMiwgd2lkdGggPSAiMC41JSIpICU+JQ0KICBjb2x1bW5fc3BlYygzLCB3aWR0aCA9ICIzJSIpIA0KDQpgYGANCg0KVGhlIGZvbGxvd2luZyBwbG90cyBkaXNwbGF5IHRoZSBUb3RhbCBXZWlnaHQgUGVyIFNldC4gRGF0YSBwb2ludHMgcmVwcmVzZW50IHNldHMgcGVyZm9ybWVkIGF0IDMsIDQsIGFuZCA1KyByZXBzLg0KDQotIERhdGEgcG9pbnRzIGFyZSBpbnRlbnRpb25hbGx5IGNvbG9yZWQ6DQogICAgLSBSZWQgbWVhbnMgU3RvcC4NCiAgICAtIEdyZWVuIG1lYW5zIEdvLg0KDQotIEFmdGVyIDUrIHJlcHMgKHJlZCBkb3QpIGhhdmUgYmVlbiBtZXQsIHRoZSB3ZWlnaHQgaXMgaW5jcmVhc2VkLg0KLSBJZiBlaXRoZXIgNCByZXBzIChibHVlIGRvdCkgb3IgMyByZXBzIChncmVlbiBkb3QpIGhhdmUgYmVlbiBtZXQsIHRoZSB3ZWlnaHQgc3RheXMgdGhlIHNhbWUuDQoNClRoZXNlIHZpc3VhbGl6YXRpb25zIGhlbHAgdHJhY2sgcHJvZ3Jlc3MgYW5kIG1ha2UgZGF0YS1kcml2ZW4gZGVjaXNpb25zIGFib3V0IGFkanVzdGluZyB3ZWlnaHRzIGJhc2VkIG9uIHBlcmZvcm1hbmNlLiBCeSBvYnNlcnZpbmcgdGhlIHRyZW5kcyBhbmQgcGF0dGVybnMgaW4gdGhlc2UgcGxvdHMsIG9uZSBjYW4gZW5zdXJlIHRoYXQgdHJhaW5pbmcgaW50ZW5zaXR5IGlzIGFwcHJvcHJpYXRlbHkgYWRqdXN0ZWQgdG8gbWVldCBwZXJmb3JtYW5jZSBnb2Fscy4NCg0KIyMgUGVyZm9ybWFuY2VzIE92ZXIgVGltZSwgU2VsZWN0ZWQgQ3JpdGVyaWENCg0KTm90IGFsbCBkYXRhcG9pbnRzIGluIHRoaXMgc2VjdGlvbiB3ZXJlIHBlcmZvcm1lZCB1c2luZyA1eDUgUk0uIFNvbWUgZXhlcmNpc2VzLCBsaWtlIEhhbW1lciBDdXJscyBvciBMYXQgUHVsbGRvd25zLCB3ZXJlIHNvbWV0aW1lcyBwZXJmb3JtZWQgaW4gc2V0cyBvZiA4LTEyKyByZXBzLCByZXF1aXJpbmcgbGVzcyB3ZWlnaHQgYW5kIHByb2R1Y2luZyBub3RpY2VhYmxlIGRpZmZlcmVuY2VzIGluIHdlaWdodCBsb2FkIGV4ZWN1dGlvbiBvbiB0aGUgcGxvdHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IGV2aWRlbnQgaW4gS2VuZHJpY2sncyBMYXQgUHVsbGRvd24gcGxvdC4gT3RoZXJzLCBzdWNoIGFzIEtlbmRyaWNrJ3MgRmxhdCBCZW5jaCBCYXJiZWxsIENoZXN0IFByZXNzLCBzaG93IGEgZ3JhZHVhbCByaXNlIGluIHBlcmZvcm1hbmNlLCB3aGljaCBpcyBtb3JlIGFjY3VyYXRlIGFuZCByZWZsZWN0cyBkcm9wcyBpbiBwZXJmb3JtYW5jZSBhbmQgYWJzZW5jZXMgb2YgZGF0YXBvaW50cyBkdWUgdG8gbGlmZSBldmVudHMgYW5kIGRlY3JlYXNlcyBpbiBleGVyY2lzZSBmcmVxdWVuY3kuIEdlbmVyYWxseSwgZXhlcmNpc2VzIHRoYXQgc2hvdyBhIGhpZ2hlciBpbmNsaW5lIGFuZ2xlLCBzdWNoIGFzIEtlbmRyaWNrJ3MgQmFyYmVsbCBTcXVhdCBhbmQgS2VuZHJpY2sncyBCYXJiZWxsIERlYWRsaWZ0LCBleGhpYml0IGZhc3Rlci10aGFuLW5vcm1hbCBpbmNyZWFzZXMgaW4gd2VpZ2h0IG92ZXIgdGltZS4gVGhpcyBmYXN0ZXItdGhhbi1ub3JtYWwgaW5jcmVhc2UgaW4gd2VpZ2h0IG1heSBiZSBkdWUgdG8gc3RhcnRpbmcgbG93IGR1ZSB0byB1bmNlcnRhaW50eSB3aXRoIHRoZSBhbW91bnQgb2Ygd2VpZ2h0IHJlcXVpcmVkIGZvciBtYXggZXhlY3V0aW9uIGFuZCB0aGUgbmVlZCB0byBhdm9pZCBpbmp1cnksIG9yIGl0IGNvdWxkIGJlIGNhdXNlZCBieSAiYmVnaW5uZXIgZ2FpbnMuIg0KDQpUaGlzIHZhcmlhbmNlIGNhbiBsZWFkIHRvIG1pc2xlYWRpbmcgaW50ZXJwcmV0YXRpb25zIHdoZW4gY29tcGFyaW5nIHBlcmZvcm1hbmNlIGFjcm9zcyBkaWZmZXJlbnQgZXhlcmNpc2VzIGFuZCByZXAgcmFuZ2VzLiBGb3IgYWNjdXJhdGUgY29tcGFyaXNvbiwgaXQncyBiZXN0IHRvIHJldmlldyBzZWN0aW9ucyBjb250YWluaW5nIDEtUmVwIE1heCAoMVJNKSBkYXRhLCB3aGljaCBwcm92aWRlIGEgc3RhbmRhcmRpemVkIG1lYXN1cmUgZm9yIGV2YWx1YXRpbmcgcGVyZm9ybWFuY2UgYmV0d2VlbiBkaWZmZXJlbnQgc2V0cyBhbmQgb24gYSBkYWlseSBiYXNpcy4gQnkgZm9jdXNpbmcgb24gMVJNLCB5b3UgZW5zdXJlIGNvbnNpc3RlbmN5IGFuZCBjb21wYXJhYmlsaXR5LCBtaXRpZ2F0aW5nIHRoZSBpc3N1ZXMgY2F1c2VkIGJ5IHZhcmllZCByZXAgcmFuZ2VzIGluIG90aGVyIGV4ZXJjaXNlcy4NCg0KPCEtLQ0KIyMjIEV4cGxhbmF0aW9uOg0KDQpNdWx0aXBsZSBQZXJmb3JtYW5jZXMgT3ZlciBUaW1lLCBTZWxlY3RlZCBDcml0ZXJpYQ0KDQotIERhdGEgRnJhbWUgU2V0dXA6IFRoZSBjcml0ZXJpYV9saXN0IGluY2x1ZGVzIE5BIGZvciBvcHRpb25hbCBjcml0ZXJpYSBsaWtlICJQb3NpdGlvbiwiIHdoZXJlIGZpbHRlcmluZyBzaG91bGQgYmUgc2tpcHBlZC4NCi0gQ29uZGl0aW9uYWwgRmlsdGVyaW5nOiBUaGUgcGxvdHRpbmcgZnVuY3Rpb24gY2hlY2tzIGlmIGVhY2ggY3JpdGVyaW9uIGlzIG5vdCBOQSBiZWZvcmUgYXBwbHlpbmcgaXQgYXMgYSBmaWx0ZXIuIFRoaXMgcHJldmVudHMgdW53YW50ZWQgZmlsdGVyaW5nIGFuZCBlbnN1cmVzIHRoYXQgb25seSBzcGVjaWZpZWQgY3JpdGVyaWEgYWZmZWN0IHRoZSBkYXRhc2V0Lg0KLSBQbG90dGluZzogUGxvdHMgYXJlIHN0aWxsIGdlbmVyYXRlZCBiYXNlZCBvbiB0aGUgYXZhaWxhYmxlIHN1YnNldCBvZiBkYXRhIGFmdGVyIGFwcGx5aW5nIHRoZSByZWxldmFudCBmaWx0ZXJzLg0KDQpUaGlzIGFwcHJvYWNoIGdpdmVzIHRoZSBmbGV4aWJpbGl0eSB0byBkZWZpbmUgZWFjaCBwbG90J3MgY3JpdGVyaWEgZHluYW1pY2FsbHksIGluY2x1ZGluZyBvciBleGNsdWRpbmcgZmlsdGVycyBhcyBuZWVkZWQgcGVyIHBsb3Qgd2l0aG91dCBhbHRlcmluZyB0aGUgb3ZlcmFsbCBzdHJ1Y3R1cmUgb2YgdGhlIGNvZGUuDQotLT4NCg0KYGBge3IgcGVyZm9ybWFuY2Vfb3Zlcl90aW1lX3Bsb3RzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCg0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojIERlZmluZSBhIGxpc3Qgb3IgZGF0YWZyYW1lIG9mIGRpZmZlcmVudCBjcml0ZXJpYSB3aXRoIE5BIGZvciBvcHRpb25hbCBjcml0ZXJpYQ0KIyBQbGFjZSBOQSB3aGVyZSB5b3UgZG9uJ3Qgd2FudCB0byBmaWx0ZXIgaW4gY3JpdGVyaWFfc2V0cyANCiMgVXNlIFxcKCoqKlxcKSBmb3IgcGFyZW50aGVzZXMuDQojIGV4Y2x1ZGVfKioqIHRvIHNwZWNpZnkgZXhjbHVzaW9uIGRpcmVjdGx5IHdpdGhpbiBsaXN0IGRlZmluaXRpb24gZm9yIGNyaXRlcmlhLiANCiMgQXR0ZW1wdGluZyB0byB1c2UgYXJyYXkgdG8gaGFuZGxlIHBvdGVudGlhbGx5IG11bHRpcGxlIGNyaXRlcmlhIChpZSBgYWN0aXZpdGllcyA9IGMoIkJpY2VwIEN1cmwiLCAiSGFtbWVyIEN1cmwiKWAgdXNpbmcgc2FwcGx5IGFuZCBjb21iaW5pbmcgcmVzdWx0cyB3aXRoIGFueSgpIGhhcyBiZWVuIHVuc3VjY2Vzc2Z1bCBhbmQgdGltZS1jb25zdW1pbmcgZm9yIHJldmlldzsgY29uc2lkZXIgdG8gcmV2aWV3IGFnYWluIGFzIGl0IGlzICBzdWl0YWJsZSBmb3Igc2NlbmFyaW9zIHdoZXJlIG11bHRpcGxlIGNyaXRlcmlhIGNhbiBhcHBseSB0byBhIHNpbmdsZSBhdHRyaWJ1dGUuIEFzIGFuIGFsdGVybmF0aXZlIGNvbnNpZGVyIHRvIHVzZSAiTkEiIHdpdGggImV4Y2x1ZGVfIi4NCg0KIyBDb21tb24gY3JpdGVyaWEgaW5mb3JtYXRpb24NCmNvbW1vbl9jcml0ZXJpYSA8LSBsaXN0KA0KICBuYW1lID0gIktlbmRyaWNrIg0KKQ0KDQojIEFkZGl0aW9uYWwgbm90ZXMgZm9yIGZ1dHVyZSBmaWx0ZXJpbmcgLSANCiMgRGVmaW5lIHNwZWNpZmljIGNyaXRlcmlhIHdpdGhvdXQgdGhlICduYW1lJyBmaWVsZC4gSW5jbHVkZSAnbmFtZScgZm9yIGV4Y2VwdGlvbnMNCiMgW2luc3RydW1lbnQgPSAiQmFyYmVsbCBcXChMb2FkZWRcXCldICMgU3BlY2lmeWluZyBzdHJpbmdzIGNvbnRhaW5pbmcgcGFyZW50aGVzaXMgYnkgaW5jbHVkaW5nIGJhY2suIA0KIyBbaW5zdHJ1bWVudCA9ICIuKkJhcmJlbGwuKiJdICAjIFVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBhbnkgdmFyaWF0aW9uIG9mICJCYXJiZWxsIi4gU3BlY2lmeWluZyAiQmFyYmVsbCAoTG9hZGVkKSIgaW5zdGVhZCBvZiAiQmFyYmVsbCIgZmlsdGVycyB0aGUgZGF0YS4gIkJhcmJlbGwiIHdpbGwgaW5jbHVkZSBhbGwgc3RyaW5ncywgc2ltaWxhciB0byAiLipCYXJiZWxsLioiIHdoaWNoIG1heSBub3QgYmUgdXNlZnVsIGlmIGxvb2tpbmcgdG8gZXhjbHVkZSBjZXJ0YWluIGRhdGEgKGllIFN0cmFpZ2h0IEJhcmJlbGwpLiANCiMgW2V4Y2x1ZGVfaW5zdHJ1bWVudCA9ICJEb3VibGUgUHVsbGV5Il0gICMgRXhjbHVkZSBhIHNpbmdsZSBjcml0ZXJpYS4gQXR0ZW1wdGluZyB0byBleGNsdWRlIG11bHRpcGxlIGNyaXRlcmlhIHN1Y2ggYXMgW2V4Y2x1ZGVfaW5zdHJ1bWVudCA9IGMoY3JpdGVyaWFfb25lLCBjcml0ZXJpYV8yKV0gdW5zdWNjZXNzZnVsLiBDb25zaWRlciB0byB0cnkgY29kZSBhZ2FpbiBpbiBmdXR1cmUuIA0KDQoNCmNyaXRlcmlhX3NldHMgPC0gbGlzdCgNCiAgbGlzdCgNCiAgICBwb3NpdGlvbiA9IE5BLA0KICAgIGluc3RydW1lbnQgPSAiQmFyYmVsbCIsDQogICAgYWN0aXZpdHkgPSAiU3F1YXQiDQogICksDQogIGxpc3QoDQogICAgcG9zaXRpb24gPSAiRmxhdCBCZW5jaCIsDQogICAgaW5zdHJ1bWVudCA9ICJCYXJiZWxsIiwNCiAgICBhY3Rpdml0eSA9ICJDaGVzdCBQcmVzcyINCiAgKSwNCiAgbGlzdCgNCiAgICBwb3NpdGlvbiA9IE5BLA0KICAgIGluc3RydW1lbnQgPSAiQmFyYmVsbCIsDQogICAgYWN0aXZpdHkgPSAiRGVhZGxpZnQiDQogICksDQogIGxpc3QoDQogICAgcG9zaXRpb24gPSBOQSwNCiAgICBpbnN0cnVtZW50ID0gIi4qQmFyYmVsbC4qIiwgICMgVXNlIGEgcmVndWxhciBleHByZXNzaW9uIHRvIG1hdGNoIGFueSB2YXJpYXRpb24gb2YgIkJhcmJlbGwiDQogICAgYWN0aXZpdHkgPSAiT3ZlcmhlYWQgU2hvdWxkZXIgUHJlc3MiDQogICksDQogIGxpc3QoDQogICAgcG9zaXRpb24gPSBOQSwNCiAgICBpbnN0cnVtZW50ID0gIkxhdCBQdWxsZG93biBCYXIiLA0KICAgIGV4Y2x1ZGVfaW5zdHJ1bWVudCA9ICJEb3VibGUgUHVsbGV5IiwNCiAgICBhY3Rpdml0eSA9ICJMYXQgUHVsbGRvd24iDQogICksDQogIGxpc3QoDQogICAgbmFtZSA9ICJBbGV4IiwNCiAgICBwb3NpdGlvbiA9ICJGbGF0IEJlbmNoIiwNCiAgICBpbnN0cnVtZW50ID0gIkJhcmJlbGwgXFwoTG9hZGVkXFwpIiwNCiAgICBhY3Rpdml0eSA9ICJDaGVzdCBQcmVzcyINCiAgKSwNCiAgbGlzdCgNCiAgICBwb3NpdGlvbiA9IE5BLA0KICAgIGluc3RydW1lbnQgPSAiQmFyYmVsbCIsDQogICAgYWN0aXZpdHkgPSAiQmljZXAgQ3VybCINCiAgKSwNCiAgbGlzdCgNCiAgICBwb3NpdGlvbiA9IE5BLA0KICAgIGluc3RydW1lbnQgPSAiQ2FibGUiLA0KICAgIGFjdGl2aXR5ID0gIkhhbW1lciBDdXJsIg0KICApDQogICMgQWRkaXRpb25hbCBjcml0ZXJpYSBzZXRzIGNhbiBiZSBhZGRlZCBoZXJlIHdpdGhvdXQgcmVwZWF0aW5nIHRoZSAnbmFtZScNCikNCg0KIyBGdW5jdGlvbiB0byBjbGVhbiB1cCBsYWJlbCBzdHJpbmdzOg0KIyBUbyB1cGRhdGUgdGhlIHByb3ZpZGVkIGNvZGUgc28gdGhhdCBpdCBkb2VzIG5vdCBkaXNwbGF5IGVzY2FwZWQgcGFyZW50aGVzZXMgXFwoIGFuZCBcXCkgaW4gdGhlIHBsb3QgbGFiZWxzL3RpdGxlcywgeW91IGNhbiBpbnRyb2R1Y2UgYSBjbGVhbmluZyBzdGVwIGZvciB0aGUgbGFiZWxzLiBUaGlzIGNhbiBiZSBkb25lIHVzaW5nIHRoZSBnc3ViIGZ1bmN0aW9uIHRvIHJlbW92ZSBvciByZXBsYWNlIHRoZSBlc2NhcGUgY2hhcmFjdGVycyBiZWZvcmUgdXNpbmcgdGhlbSBpbiB0aGUgcGxvdCBsYWJlbHMuIA0KY2xlYW5fbGFiZWwgPC0gZnVuY3Rpb24obGFiZWwpIHsNCiAgZ3N1YigiXFxcXHxcXC58XFwqIiwgIiIsIGxhYmVsKSAgIyBSZW1vdmUgdGhlIGVzY2FwZSBjaGFyYWN0ZXJzIGZvciBwYXJlbnRoZXNlcyBhbmQgIi4qIg0KfQ0KDQojIERlZmluZSBhIHBsb3R0aW5nIGZ1bmN0aW9uIHRoYXQgdGFrZXMgY3JpdGVyaWFfc2V0cyBhcyBhbiBhcmd1bWVudCBhbmQgY2hlY2tzIGZvciBOQQ0KZ2VuZXJhdGVfcGxvdCA8LSBmdW5jdGlvbihjcml0ZXJpYV9zZXRzKSB7DQoNCiAgIyBJZiAnbmFtZScgaXMgbm90IGluIHRoZSBjcml0ZXJpYSwgdXNlIHRoZSBjb21tb24gJ25hbWUnDQogIGlmICghIm5hbWUiICVpbiUgbmFtZXMoY3JpdGVyaWFfc2V0cykpIHsNCiAgICBjcml0ZXJpYV9zZXRzJG5hbWUgPC0gY29tbW9uX2NyaXRlcmlhJG5hbWUNCiAgfQ0KICANCiAgIyBTdGFydCBmaWx0ZXJpbmcgd2l0aCBtYW5kYXRvcnkgY3JpdGVyaWFfc2V0cyAoTmFtZSBpbiB0aGlzIGNhc2UpDQogIHJhd19kYXRhX2NyaXRlcmlhIDwtIHJhd19kYXRhICU+JQ0KICAgIGZpbHRlcihncmVwbChjcml0ZXJpYV9zZXRzJG5hbWUsIE5hbWUsIGlnbm9yZS5jYXNlID0gVFJVRSkpDQoNCiAgIyBDb25kaXRpb25hbGx5IGFkZCBmaWx0ZXJzIGlmIGNyaXRlcmlhX3NldHMgYXJlIG5vdCBOQQ0KICAjIEZpbHRlcmluZyBmb3IgaW5zdHJ1bWVudCB3aXRoIGluY2x1c2lvbiBhbmQgc3BlY2lmaWMgZXhjbHVzaW9uIGNyaXRlcmlhDQogIGlmICghaXMubmEoY3JpdGVyaWFfc2V0cyRwb3NpdGlvbikgJiYgY3JpdGVyaWFfc2V0cyRwb3NpdGlvbiAhPSAiIikgew0KICAgIHJhd19kYXRhX2NyaXRlcmlhIDwtIHJhd19kYXRhX2NyaXRlcmlhICU+JQ0KICAgICAgZmlsdGVyKGdyZXBsKGNyaXRlcmlhX3NldHMkcG9zaXRpb24sIFBvc2l0aW9uLCBpZ25vcmUuY2FzZSA9IFRSVUUpKQ0KICAgICAgaWYgKCFpcy5udWxsKGNyaXRlcmlhX3NldHMkZXhjbHVkZV9wb3NpdGlvbikpIHsNCiAgICAgICAgcmF3X2RhdGFfY3JpdGVyaWEgPC0gcmF3X2RhdGFfY3JpdGVyaWEgJT4lDQogICAgICAgICAgZmlsdGVyKCFncmVwbChjcml0ZXJpYV9zZXRzJGV4Y2x1ZGVfcG9zaXRpb24sIFBvc2l0aW9uLCBpZ25vcmUuY2FzZSA9IFRSVUUpKQ0KICAgICAgfQ0KICB9DQogIA0KICBpZiAoIWlzLm5hKGNyaXRlcmlhX3NldHMkaW5zdHJ1bWVudCkgJiYgY3JpdGVyaWFfc2V0cyRpbnN0cnVtZW50ICE9ICIiKSB7DQogICAgcmF3X2RhdGFfY3JpdGVyaWEgPC0gcmF3X2RhdGFfY3JpdGVyaWEgJT4lDQogICAgICBmaWx0ZXIoZ3JlcGwoY3JpdGVyaWFfc2V0cyRpbnN0cnVtZW50LCBJbnN0cnVtZW50LCBpZ25vcmUuY2FzZSA9IFRSVUUpKQ0KICAgICAgIGlmICghaXMubnVsbChjcml0ZXJpYV9zZXRzJGV4Y2x1ZGVfaW5zdHJ1bWVudCkpIHsNCiAgICAgICAgcmF3X2RhdGFfY3JpdGVyaWEgPC0gcmF3X2RhdGFfY3JpdGVyaWEgJT4lDQogICAgICAgICAgZmlsdGVyKCFncmVwbChjcml0ZXJpYV9zZXRzJGV4Y2x1ZGVfaW5zdHJ1bWVudCwgSW5zdHJ1bWVudCwgaWdub3JlLmNhc2UgPSBUUlVFKSkNCiAgICAgIH0NCiAgfQ0KICANCiAgaWYgKCFpcy5uYShjcml0ZXJpYV9zZXRzJGFjdGl2aXR5KSAmJiBjcml0ZXJpYV9zZXRzJGFjdGl2aXR5ICE9ICIiKSB7DQogICAgcmF3X2RhdGFfY3JpdGVyaWEgPC0gcmF3X2RhdGFfY3JpdGVyaWEgJT4lDQogICAgICBmaWx0ZXIoZ3JlcGwoY3JpdGVyaWFfc2V0cyRhY3Rpdml0eSwgQWN0aXZpdHksIGlnbm9yZS5jYXNlID0gVFJVRSkpDQogICAgICAgaWYgKCFpcy5udWxsKGNyaXRlcmlhX3NldHMkZXhjbHVkZV9hY3Rpdml0eSkpIHsNCiAgICAgICAgcmF3X2RhdGFfY3JpdGVyaWEgPC0gcmF3X2RhdGFfY3JpdGVyaWEgJT4lDQogICAgICAgICAgZmlsdGVyKCFncmVwbChjcml0ZXJpYV9zZXRzJGV4Y2x1ZGVfYWN0aXZpdHksIEFjdGl2aXR5LCBpZ25vcmUuY2FzZSA9IFRSVUUpKQ0KICAgICAgfQ0KICB9DQoNCiAgZmlsdGVyZWRfZGF0YV9yZXBzXzUgPC0gc3Vic2V0KHJhd19kYXRhX2NyaXRlcmlhLCBGaW5hbF9SZXBzID49IDUpDQogIGZpbHRlcmVkX2RhdGFfcmVwc180IDwtIHN1YnNldChyYXdfZGF0YV9jcml0ZXJpYSwgRmluYWxfUmVwcyA+PSA0KQ0KICBmaWx0ZXJlZF9kYXRhX3JlcHNfMyA8LSBzdWJzZXQocmF3X2RhdGFfY3JpdGVyaWEsIEZpbmFsX1JlcHMgPj0gMykNCiAgDQogIG1heF93ZWlnaHRfcmVwc181IDwtIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfNSRUb3RhbF9XZWlnaHQpDQogIG1heF93ZWlnaHRfcmVwc180IDwtIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfNCRUb3RhbF9XZWlnaHQpDQogIG1heF93ZWlnaHRfcmVwc18zIDwtIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfMyRUb3RhbF9XZWlnaHQpDQoNCiAgcmVncmVzc2lvbl9saW5lX3JlcHNfNSA8LSBsbShUb3RhbF9XZWlnaHQgfiBEYXRlLCBkYXRhID0gZmlsdGVyZWRfZGF0YV9yZXBzXzUpDQogIHJlZ3Jlc3Npb25fbGluZV9yZXBzXzQgPC0gbG0oVG90YWxfV2VpZ2h0IH4gRGF0ZSwgZGF0YSA9IGZpbHRlcmVkX2RhdGFfcmVwc180KQ0KICByZWdyZXNzaW9uX2xpbmVfcmVwc18zIDwtIGxtKFRvdGFsX1dlaWdodCB+IERhdGUsIGRhdGEgPSBmaWx0ZXJlZF9kYXRhX3JlcHNfMykNCiAgDQogIHNsb3BlX3JlcHNfNSA8LSBjb2VmKHJlZ3Jlc3Npb25fbGluZV9yZXBzXzUpWzJdDQogIHNsb3BlX3JlcHNfNCA8LSBjb2VmKHJlZ3Jlc3Npb25fbGluZV9yZXBzXzQpWzJdDQogIHNsb3BlX3JlcHNfMyA8LSBjb2VmKHJlZ3Jlc3Npb25fbGluZV9yZXBzXzMpWzJdDQogIA0KICBzbG9wZV9zaWduX3JlcHNfNSA8LSBpZmVsc2Uoc2xvcGVfcmVwc181ID49IDAsICIrIiwgIi0iKQ0KICBzbG9wZV9zaWduX3JlcHNfNCA8LSBpZmVsc2Uoc2xvcGVfcmVwc180ID49IDAsICIrIiwgIi0iKQ0KICBzbG9wZV9zaWduX3JlcHNfMyA8LSBpZmVsc2Uoc2xvcGVfcmVwc18zID49IDAsICIrIiwgIi0iKQ0KICANCiAgc3VidGl0bGVfbGVmdF9yZXBzXzUgPC0gc3RyX3BhZChwYXN0ZSgiSGlnaGVzdCBXZWlnaHQgRXhlY3V0ZWQgQXQgNSsgUmVwczoiLCBtYXhfd2VpZ2h0X3JlcHNfNSwgImxicy4iKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBuY2hhcigiSGlnaGVzdCBXZWlnaHQgRXhlY3V0ZWQgQXQgNSsgUmVwczogIiksIHNpZGUgPSAibGVmdCIpDQogIHN1YnRpdGxlX2xlZnRfcmVwc180IDwtIHN0cl9wYWQocGFzdGUoIkhpZ2hlc3QgV2VpZ2h0IEV4ZWN1dGVkIEF0IDQgUmVwczoiLCBtYXhfd2VpZ2h0X3JlcHNfNCwgImxicy4iKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBuY2hhcigiSGlnaGVzdCBXZWlnaHQgRXhlY3V0ZWQgQXQgNCBSZXBzOiAiKSwgc2lkZSA9ICJsZWZ0IikNCiAgc3VidGl0bGVfbGVmdF9yZXBzXzMgPC0gc3RyX3BhZChwYXN0ZSgiSGlnaGVzdCBXZWlnaHQgRXhlY3V0ZWQgQXQgMyBSZXBzOiIsIG1heF93ZWlnaHRfcmVwc18zLCAibGJzLiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IG5jaGFyKCJIaWdoZXN0IFdlaWdodCBFeGVjdXRlZCBBdCAzIFJlcHM6ICIpLCBzaWRlID0gImxlZnQiKQ0KICANCiAgc3VidGl0bGVfcmlnaHRfcmVwc181IDwtIHN0cl9wYWQocGFzdGUoIlNsb3BlOiIsIHNsb3BlX3NpZ25fcmVwc181LCBhYnMocm91bmQoc2xvcGVfcmVwc181LCAzKSksICJsYnMgcGVyIGRheSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBuY2hhcigiU2xvcGU6ICIpLCBzaWRlID0gInJpZ2h0IikNCiAgc3VidGl0bGVfcmlnaHRfcmVwc180IDwtIHN0cl9wYWQocGFzdGUoIlNsb3BlOiIsIHNsb3BlX3NpZ25fcmVwc180LCBhYnMocm91bmQoc2xvcGVfcmVwc180LCAzKSksICJsYnMgcGVyIGRheSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBuY2hhcigiU2xvcGU6ICIpLCBzaWRlID0gInJpZ2h0IikNCiAgc3VidGl0bGVfcmlnaHRfcmVwc18zIDwtIHN0cl9wYWQocGFzdGUoIlNsb3BlOiIsIHNsb3BlX3NpZ25fcmVwc18zLCBhYnMocm91bmQoc2xvcGVfcmVwc18zLCAzKSksICJsYnMgcGVyIGRheSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBuY2hhcigiU2xvcGU6ICIpLCBzaWRlID0gInJpZ2h0IikNCiAgDQogIG1pbl9kYXRlIDwtIG1pbihjKG1pbihmaWx0ZXJlZF9kYXRhX3JlcHNfNSREYXRlKSwgDQogICAgICAgICAgICAgICAgICAgIG1pbihmaWx0ZXJlZF9kYXRhX3JlcHNfNCREYXRlKSwgDQogICAgICAgICAgICAgICAgICAgIG1pbihmaWx0ZXJlZF9kYXRhX3JlcHNfMyREYXRlKSkpDQogIG1heF9kYXRlIDwtIG1heChjKG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfNSREYXRlKSwgDQogICAgICAgICAgICAgICAgICAgIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfNCREYXRlKSwgDQogICAgICAgICAgICAgICAgICAgIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfMyREYXRlKSkpDQogIGRhdGVfcmFuZ2UgPC0gcGFzdGUoIkRhdGUgUmFuZ2UgIiwgZm9ybWF0KG1pbl9kYXRlLCAiJW0vJWQvJVkiKSwgIiB0byAiLCBmb3JtYXQobWF4X2RhdGUsICIlbS8lZC8lWSIpKQ0KDQogIGNsZWFuX2xhYmVsX3RpdGxlID0gcGFzdGUoY3JpdGVyaWFfc2V0cyRuYW1lLA0KICAgICAgICAgICAgICAgICItIiwNCiAgICAgICAgICAgICAgICBpZmVsc2UoaXMubmEoY3JpdGVyaWFfc2V0cyRwb3NpdGlvbiksICIiLCBjbGVhbl9sYWJlbChjcml0ZXJpYV9zZXRzJHBvc2l0aW9uKSksIA0KICAgICAgICAgICAgICAgIGlmZWxzZShpcy5uYShjcml0ZXJpYV9zZXRzJGluc3RydW1lbnQpLCAiIiwgY2xlYW5fbGFiZWwoY3JpdGVyaWFfc2V0cyRpbnN0cnVtZW50KSksIA0KICAgICAgICAgICAgICAgIGlmZWxzZShpcy5uYShjcml0ZXJpYV9zZXRzJGFjdGl2aXR5KSwgIiIsIGNsZWFuX2xhYmVsKGNyaXRlcmlhX3NldHMkYWN0aXZpdHkpKSAgDQogICkgIA0KDQogIHBsb3QgPC0gZ2dwbG90KCkgKw0KICAgIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcmVkX2RhdGFfcmVwc18zLCBhZXMoeCA9IERhdGUsIHkgPSBUb3RhbF9XZWlnaHQsIGNvbG9yID0gIjMiKSwNCiAgICAgICAgICAgICAgIHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9IG1heCwgc2l6ZSA9IDMpICsNCiAgICBnZW9tX3Ntb290aChkYXRhID0gZmlsdGVyZWRfZGF0YV9yZXBzXzMsIGFlcyh4ID0gRGF0ZSwgeSA9IFRvdGFsX1dlaWdodCksIA0KICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gIiMwMDgwMDAiLCBzaXplID0gMSkgKw0KICAgIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcmVkX2RhdGFfcmVwc180LCBhZXMoeCA9IERhdGUsIHkgPSBUb3RhbF9XZWlnaHQsIGNvbG9yID0gIjQiKSwNCiAgICAgICAgICAgICAgIHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9IG1heCwgc2l6ZSA9IDMpICsNCiAgICBnZW9tX3Ntb290aChkYXRhID0gZmlsdGVyZWRfZGF0YV9yZXBzXzQsIGFlcyh4ID0gRGF0ZSwgeSA9IFRvdGFsX1dlaWdodCksIA0KICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gIiMxZjc4YjQiLCBzaXplID0gMSkgKw0KICAgIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcmVkX2RhdGFfcmVwc181LCBhZXMoeCA9IERhdGUsIHkgPSBUb3RhbF9XZWlnaHQsIGNvbG9yID0gIjUrIiksDQogICAgICAgICAgICAgICBzdGF0ID0gInN1bW1hcnkiLCBmdW4gPSBtYXgsIHNpemUgPSAzKSArDQogICAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcmVkX2RhdGFfcmVwc181LCBhZXMoeCA9IERhdGUsIHkgPSBUb3RhbF9XZWlnaHQpLCANCiAgICAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICIjZTMxYTFjIiwgc2l6ZSA9IDEpICsNCiAgICANCiAgICBsYWJzKHRpdGxlID0gY2xlYW5fbGFiZWxfdGl0bGUsDQogICAgICAgICB4ID0gIkRhdGUiLCANCiAgICAgICAgIHkgPSAiV2VpZ2h0IChsYnMpIEV4ZWN1dGVkIiwNCiAgICAgICAgIHN1YnRpdGxlID0gcGFzdGUoZGF0ZV9yYW5nZSwgIlxuIiwgc3VidGl0bGVfbGVmdF9yZXBzXzUsICIgIiwgc3VidGl0bGVfcmlnaHRfcmVwc181LCAiXG4iLCBzdWJ0aXRsZV9sZWZ0X3JlcHNfNCwgIiAiLCBzdWJ0aXRsZV9yaWdodF9yZXBzXzQsICJcbiIsIHN1YnRpdGxlX2xlZnRfcmVwc18zLCAiICIsIHN1YnRpdGxlX3JpZ2h0X3JlcHNfMyksDQogICAgICAgICBjb2xvciA9ICJNaW5pbXVtIFJlcHMiDQogICAgKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBzY2FsZV94X2RhdGUobGFiZWxzID0gc2NhbGVzOjpkYXRlX2Zvcm1hdCgiJW0vJWQvJVkiKSwgZGF0ZV9icmVha3MgPSAiMSB3ZWVrIikgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMC44NSAqIDE2LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAwLjg1ICogMTIsIGZhY2UgPSAiaXRhbGljIiksDQogICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMC44NSAqIDE0KSwNCiAgICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDAuODUgKiAxMCksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgICAgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIiwNCiAgICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiDQogICAgKSArDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIjMiID0gIiMwMDgwMDAiLCAiNCIgPSAiIzFmNzhiNCIsICI1KyIgPSAiI2UzMWExYyIpLCBuYW1lID0gIk1pbmltdW0gUmVwcyIpDQoNCiAgIyBDYWxjdWxhdGUgbWF4IDFSTSB3ZWlnaHRzIGFuZCBjb3JyZXNwb25kaW5nIGRhdGVzDQogIG1heF8xcm1fYWxsX3RpbWUgPC0gbWF4KHJhd19kYXRhX2NyaXRlcmlhJGAxUk1fQ2FsY3VsYXRlZF9XZWlnaHRgLCBuYS5ybSA9IFRSVUUpIA0KICBsYXN0X2RhdGVfbWF4XzFybV9hbGxfdGltZSA8LSBtYXgocmF3X2RhdGFfY3JpdGVyaWEkRGF0ZVtyYXdfZGF0YV9jcml0ZXJpYSRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCA9PSBtYXhfMXJtX2FsbF90aW1lXSwgbmEucm0gPSBUUlVFKSAjIE1vc3QgcmVjZW50IGRhdGUgZm9yIGhpZ2hlc3QgMVJNIG92ZXIgYWxsIHRpbWUuDQoNCiAgIyBNb3N0IHJlY2VudCBkYXRlIGZvciBoaWdoZXN0IFRvdGFsIFdlaWdodCBleGVjdXRlZCBhdCA1KyByZXBzLiANCiAgbGFzdF9kYXRlX21heF93ZWlnaHRfcmVwc181IDwtIG1heChmaWx0ZXJlZF9kYXRhX3JlcHNfNSREYXRlW2ZpbHRlcmVkX2RhdGFfcmVwc181JFRvdGFsX1dlaWdodCA9PSBtYXhfd2VpZ2h0X3JlcHNfNV0sIG5hLnJtID0gVFJVRSkNCiAgICAgIA0KICAjIERhdGEgZm9yIGxhc3QgMiB3ZWVrcw0KICBtaW5fZGF0ZV9sYXN0XzJ3ayA8LSBtYXhfZGF0ZSAtIDEzDQogIHJhd19kYXRhX2xhc3RfMndrIDwtIHN1YnNldChyYXdfZGF0YV9jcml0ZXJpYSwgRGF0ZSA+PSBtaW5fZGF0ZV9sYXN0XzJ3ayAmIERhdGUgPD0gbWF4X2RhdGUpDQogIA0KICBtYXhfMXJtX2xhc3RfMndrIDwtIG1heChyYXdfZGF0YV9sYXN0XzJ3ayRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCwgbmEucm0gPSBUUlVFKQ0KICBsYXN0X2RhdGVfbWF4XzFybV9sYXN0XzJ3ayA8LSBtYXgocmF3X2RhdGFfbGFzdF8yd2skRGF0ZVtyYXdfZGF0YV9sYXN0XzJ3ayRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCA9PSBtYXhfMXJtX2xhc3RfMndrXSwgbmEucm0gPSBUUlVFKSAjIE1vc3QgcmVjZW50IGRhdGUgZm9yIGhpZ2hlc3QgMVJNIG92ZXIgbGFzdCAyIHdlZWtzLiANCg0KICBhdmdfd2VpZ2h0X2V4ZWN1dGVkX3Blcl9zZXRfbGFzdF8yd2sgPC0gbWVhbihyYXdfZGF0YV9sYXN0XzJ3ayRUb3RhbF9XZWlnaHQsIG5hLnJtID0gVFJVRSkNCiAgYXZnXzFybV9jYWxjdWxhdGVkX3dlaWdodF9sYXN0XzJ3ayA8LSBtZWFuKHJhd19kYXRhX2xhc3RfMndrJGAxUk1fQ2FsY3VsYXRlZF9XZWlnaHRgLCBuYS5ybSA9IFRSVUUpDQogIA0KICAjIFByaW50IHRoZSBzdGF0aXN0aWNzIGZvciB0aGUgY3VycmVudCBwbG90IGFzIGEgdGFibGUNCiAgc3RhdGlzdGljc190YWJsZSA8LSBkYXRhLmZyYW1lKA0KICAgIE1ldHJpYyA9IGMoDQogICAgICAiQXZlcmFnZSBXZWlnaHQgRXhlY3V0ZWQgUGVyIFNldDoiLA0KICAgICAgIkF2ZXJhZ2UgMVJNIENhbGN1bGF0ZWQgV2VpZ2h0IFBlciBTZXQ6IiwNCiAgICAgICJIaWdoZXN0IDFSTSBDYWxjdWxhdGVkIFdlaWdodDoiLA0KICAgICAgIkhpZ2hlc3QgMVJNIENhbGN1bGF0ZWQgV2VpZ2h0OiIsDQogICAgICAiSGlnaGVzdCBXZWlnaHQgRXhlY3V0ZWQgYXQgNSsgUmVwczoiDQogICAgKSwNCg0KICAgIGBWYWx1ZSAobGJzKWAgPSBjKA0KICAgICAgcGFzdGUocm91bmQoYXZnX3dlaWdodF9leGVjdXRlZF9wZXJfc2V0X2xhc3RfMndrLCAyKSksDQogICAgICBwYXN0ZShyb3VuZChhdmdfMXJtX2NhbGN1bGF0ZWRfd2VpZ2h0X2xhc3RfMndrLCAyKSksDQogICAgICBwYXN0ZShyb3VuZChtYXhfMXJtX2xhc3RfMndrLDIpKSwNCiAgICAgIHBhc3RlKHJvdW5kKG1heF8xcm1fYWxsX3RpbWUsMikpLA0KICAgICAgcGFzdGUocm91bmQobWF4X3dlaWdodF9yZXBzXzUsMikpDQogICAgKSwNCiAgICANCiAgICBSYW5nZSA9IGMoDQogICAgICAiTGFzdCAyIFdlZWtzIiwNCiAgICAgICJMYXN0IDIgV2Vla3MiLA0KICAgICAgIkxhc3QgMiBXZWVrcyIsDQogICAgICAiQWxsIFRpbWUiLA0KICAgICAgIkFsbCBUaW1lIg0KICAgICksDQogICAgDQogICAgRGF0ZSA9IGMoDQogICAgICBwYXN0ZShmb3JtYXQobWluX2RhdGVfbGFzdF8yd2ssICIlbS8lZC8lWSIpLCAiIHRvICIgLCBmb3JtYXQobWF4X2RhdGUsICIlbS8lZC8lWSIpKSwNCiAgICAgIHBhc3RlKGZvcm1hdChtaW5fZGF0ZV9sYXN0XzJ3aywgIiVtLyVkLyVZIiksICIgdG8gIiAsIGZvcm1hdChtYXhfZGF0ZSwgIiVtLyVkLyVZIikpLA0KICAgICAgZm9ybWF0KGxhc3RfZGF0ZV9tYXhfMXJtX2xhc3RfMndrLCAiJW0vJWQvJVkiKSwNCiAgICAgIGZvcm1hdChsYXN0X2RhdGVfbWF4XzFybV9hbGxfdGltZSwgIiVtLyVkLyVZIiksDQogICAgICBmb3JtYXQobGFzdF9kYXRlX21heF93ZWlnaHRfcmVwc181LCAiJW0vJWQvJVkiKQ0KICAgICkNCiAgKQ0KICANCiAgIyBVcGRhdGUgdGhlIGNvbHVtbiBuYW1lDQogIGNvbG5hbWVzKHN0YXRpc3RpY3NfdGFibGUpWzFdIDwtIHBhc3RlKGNsZWFuX2xhYmVsX3RpdGxlKQ0KICANCiAgY2F0KHBhc3RlMCgiXG5cbjxoND4gIiwgY2xlYW5fbGFiZWxfdGl0bGUsICI8L2g0PlxuIikpDQogIHByaW50KA0KICAgIGthYmxlKHN0YXRpc3RpY3NfdGFibGUsIGZvcm1hdCA9ICJodG1sIiwgYWxpZ24gPSAnbCcpICU+JQ0KICAgICAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSkgJT4lDQogICAgICBjb2x1bW5fc3BlYygxOm5jb2woc3RhdGlzdGljc190YWJsZSksIHdpZHRoID0gcGFzdGUwKDEwMCAvIG5jb2woc3RhdGlzdGljc190YWJsZSkpKQ0KICApDQogIA0KICBwbG90IDwtIHBsb3QgKyB0aGVtZSgNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuOCksIGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDEpKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMS4yKSwgZmFjZSA9ICJib2xkIiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDEpKQ0KICApDQoNCiAgIyBQcmludCB0aGUgcGxvdCBpbW1lZGlhdGVseSBhZnRlciB0aGUgc3RhdGlzdGljcw0KICAjIFRvIGVuc3VyZSB0aGF0IHRoZSBvdXRwdXQgb2YgZWFjaCBwbG90IGlzIHByaW50ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaXRzIGNvcnJlc3BvbmRpbmcgc3VtbWFyeSBzdGF0aXN0aWNzLCBpbnRlZ3JhdGUgdGhlIHByaW50aW5nIG9mIHRoZSBzdGF0aXN0aWNzIHdpdGggdGhlIHBsb3Qgd2l0aGluIHRoZSBsb29wLiBUaGUgcHJpbnQgZnVuY3Rpb24gd2lsbCBwcmludCB0aGUgcGxvdCB0byB0aGUgUiBjb25zb2xlIG9yIHZpZXdlciBwYW5lLCBkZXBlbmRpbmcgb24gdGhlIHNldHVwLg0KICBwcmludChwbG90KQ0KfQ0KDQojIExvb3Agb3ZlciBlYWNoIHNldCBvZiBjcml0ZXJpYV9zZXRzIGFuZCBnZW5lcmF0ZSBhIHBsb3QgYWxvbmcgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHN0YXRpc3RpY3MNCmludmlzaWJsZShsYXBwbHkoY3JpdGVyaWFfc2V0cywgZnVuY3Rpb24oY3JpdGVyaWEpIHsNCiAgZ2VuZXJhdGVfcGxvdChjcml0ZXJpYSkNCn0pKQ0KDQoNCmBgYA0KDQojIFNUQVRTIFRPIFNUQU5EQVJEUw0KDQpQZXJmb3JtYW5jZSBtZWFzdXJlcyBhcmUgZXZhbHVhdGVkIHRvIG1hdGNoIFN0YW5kYXJkcy4gIA0KDQo8IS0tIA0KUExBTjogRE8gQSBTRVBBUkFURSBNQVggMVJNIFBFUkZPUk1BTkNFIENPTVBBUklTT04gKElOU1RFQUQgT0YgQVZHIDFSTSkNCi0tPg0KDQojIyBJbnRlZ3JhdGluZyBQZXJmb3JtYW5jZSBNZXRyaWNzIHdpdGggTWFyayBSaXBwZXRvZSBTdHJlbmd0aCBTdGFuZGFyZHMgDQoNClBlcmZvcm1hbmNlIG1lYXN1cmVzIGFyZSBldmFsdWF0ZWQgdG8gbWF0Y2ggc3RhbmRhcmRzLiBUaGlzIHNlY3Rpb24gY29tYmluZXMgcHJhY3RpY2FsIHdvcmtvdXQgZGF0YSBhbmFseXNpcyB3aXRoIE1hcmsgUmlwcGV0b2UncyBTdHJlbmd0aCBTdGFuZGFyZHMuIFRoZSBzdGFuZGFyZHMgYXJlIGVzc2VudGlhbCBmb3IgZXZhbHVhdGluZyBhbmQgY29udGV4dHVhbGl6aW5nIGluZGl2aWR1YWwgZml0bmVzcyBhY2hpZXZlbWVudHMgYWdhaW5zdCBzdGFuZGFyZGl6ZWQgY3JpdGVyaWEuDQoNCkZvciBhIGhpZ2hlciBxdWFsaXR5IG9mIHBlcnNvbmFsIHBlcmZvcm1hbmNlIGNvbXBhcmlzb24sIHdlIGRlZmluZSBzcGVjaWZpYyBjcml0ZXJpYSB0byBtYXRjaCB0aGUgc3RhbmRhcmRzIHByZXNlbnRlZCBieSBNYXJrLiBTaG91bGQgd2UgY2hvb3NlLCB3ZSBjYW4gc3BlY2lmeSBvdXIgY3JpdGVyaWEgZm9yIEZsYXQgQmVuY2ggRHVtYmJlbGwgQ2hlc3QgUHJlc3Mgb3IgSW5jbGluZSBCZW5jaCBEdW1iYmVsbCBDaGVzdCBQcmVzcywgZWFjaCBsaWtlbHkgcmVxdWlyaW5nIGRpZmZlcmVudCB3ZWlnaHRzIGFuZCBudW1iZXJzIG9mIHJlcHMgZm9yIGV4ZWN1dGlvbi4gQXMgYSByZW1pbmRlciwgTWFyayBSaXBwZXRvZSdzIHRyYWluaW5nIHV0aWxpemVzIHRoZSBiYXJiZWxsIGFzIHRoZSBpbnN0cnVtZW50IGZvciBncm93dGguIEJ5IGV4cGxhaW5pbmcgaW4gZGV0YWlsIHRoZSBCZW5jaCBQcmVzcyBpbiBoaXMgU3RhcnRpbmcgU3RyZW5ndGggYm9vayBbXjVdLCB3ZSBrbm93IHRoZSBzdHJlbmd0aCBzdGFuZGFyZCBpcyBtZWFzdXJlZCB2aWEgdGhlIGZsYXQgYmVuY2guIFRoZXJlZm9yZSwgd2Ugc3BlY2lmeSBGbGF0IEJlbmNoIEJhcmJlbGwgKExvYWRlZCkgQ2hlc3QgUHJlc3MgaW4gb3VyIGNyaXRlcmlhIHRvIGNvbXBhcmUgd2l0aCBNYXJrIFJpcHBldG9lJ3MgMVJNIE1hbGUgQmVuY2ggUHJlc3MgU3RhbmRhcmRzLg0KDQpgYGB7ciBzZXR1cF9wZXJmb3JtYW5jZV9vbl9tYXJrX3JpcHBldG9lX3N0YW5kYXJkcywgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIFNldHVwIGFuZCBMaWJyYXJ5IEltcG9ydDogDQojIEFsbCBuZWNlc3NhcnkgUiBwYWNrYWdlcyAoZHBseXIsIHRpZHlyLCByZWFkciwgbHVicmlkYXRlKSBzaG91bGQgYmUgaW5zdGFsbGVkIGFuZCBsb2FkZWQuIFRoZXNlIGxpYnJhcmllcyBhcmUgY3JpdGljYWwgZm9yIGRhdGEgbWFuaXB1bGF0aW9uIChkcGx5ciksIGRhdGEgdGlkeWluZyAodGlkeXIpLCBoYW5kbGluZyBkYXRlIG9iamVjdHMgKGx1YnJpZGF0ZSksIGFuZCByZWFkaW5nIGRhdGEgKHJlYWRyKS4NCg0KIyBEZWZpbmUgRXhlcmNpc2UgQ3JpdGVyaWE6IA0KIyBBIGxpc3QgbmFtZWQgZXhlcmNpc2VfY3JpdGVyaWEgaXMgZGVmaW5lZCB3aGVyZSBlYWNoIGV4ZXJjaXNlIChlLmcuLCBCZW5jaCBQcmVzcywgU3F1YXQpIGhhcyBzcGVjaWZpYyBjcml0ZXJpYSBzdWNoIGFzIHBvc2l0aW9uLCBpbnN0cnVtZW50LCBhbmQgYWN0aXZpdHkgcGF0dGVybi4gVGhpcyBtYW51YWwgc2V0dXAgYWlkcyBpbiBmaWx0ZXJpbmcgdGhlIHdvcmtvdXQgZGF0YSBiYXNlZCBvbiB0aGUgcHJlZGVmaW5lZCBzdGFuZGFyZHMuIA0KIyBOb3RlOiBNYXJrIFJpcHBldG9lJ3MgU3RhbmRhcmRzIGRvZXMgbm90IHNwZWNpZnkgcG9zaXRpb25pbmcgKGZsYXQgYmVuY2gsIGluY2xpbmUgYmVuY2gsIHN0YW5kaW5nKSBub3IgaW5zdHJ1bWVudCB1c2VkIChiYXJiZWxsLCBkdW1iYmVsbCkuIFRoZXNlIGFkZGl0aW9uYWwgY3JpdGVyaWEgaXMgZGVmaW5lZCBpbnRvIHRoZSBsaXN0LiANCg0KIyBDcmVhdGluZyBDcml0ZXJpYSBTdHJpbmdzOiANCiMgQSBmdW5jdGlvbiBpcyBkZXZlbG9wZWQgdG8gY29udmVydCB0aGUgZXhlcmNpc2UgY3JpdGVyaWEgaW50byBhIHNpbmdsZSBzdHJpbmcgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZmlsdGVyaW5nIG9yIGRpc3BsYXlpbmcuIFRoaXMgZnVuY3Rpb24gdGFrZXMgaW50byBhY2NvdW50IHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUgZXhlcmNpc2UgbGlrZSBwb3NpdGlvbiwgaW5zdHJ1bWVudCwgYW5kIGFjdGl2aXR5LCBjb25jYXRlbmF0aW5nIHRoZW0gaW50byBhIHJlYWRhYmxlIHN0cmluZy4NCg0KIyBNYXRjaGluZyBDcml0ZXJpYSB3aXRoIFN0YW5kYXJkczoNCiMgVGhlIGZ1bmN0aW9uIGNyZWF0ZV9jcml0ZXJpYV9zdHJpbmcgaXMgYXBwbGllZCByb3ctd2lzZSB0byB0aGUgbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfbGlzdCBkYXRhZnJhbWUsIHdoaWNoIGlzIGxpa2VseSBhIGRhdGFzZXQgY29udGFpbmluZyBwcmVkZWZpbmVkIHN0YW5kYXJkcyBmb3IgZGlmZmVyZW50IGV4ZXJjaXNlcy4gVGhpcyBhcHBsaWNhdGlvbiBlbnJpY2hlcyB0aGUgZGF0YWZyYW1lIGJ5IGFkZGluZyBhIFNlbGVjdGVkIENyaXRlcmlhIHRoYXQgcHJvdmlkZXMgaHVtYW4tcmVhZGFibGUgY3JpdGVyaWEgZm9yIGVhY2ggc3RhbmRhcmQuDQoNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShrbml0cikNCg0KIyBEZWZpbmUgRXhlcmNpc2UgQ3JpdGVyaWE6IA0KZXhlcmNpc2VfY3JpdGVyaWEgPC0gbGlzdCgNCiAgIkJlbmNoIFByZXNzIiA9IGxpc3QoUG9zaXRpb24gPSAiRmxhdCBCZW5jaCIsIEluc3RydW1lbnQgPSAiQmFyYmVsbCIsIEFjdGl2aXR5ID0gIkNoZXN0IFByZXNzIiksDQogICJQcmVzcyIgPSBsaXN0KEluc3RydW1lbnQgPSAiQmFyYmVsbCIsIEFjdGl2aXR5ID0gIk92ZXJoZWFkIFNob3VsZGVyIFByZXNzIiksDQogICJTcXVhdCIgPSBsaXN0KEluc3RydW1lbnQgPSAiQmFyYmVsbCIsIEFjdGl2aXR5ID0gIlNxdWF0IiksDQogICJEZWFkbGlmdCIgPSBsaXN0KEluc3RydW1lbnQgPSAiQmFyYmVsbCIsIEFjdGl2aXR5ID0gIkRlYWRsaWZ0IikNCikNCg0KIyBGdW5jdGlvbiB0byBjcmVhdGUgY3JpdGVyaWEgc3RyaW5ncw0KY3JlYXRlX2NyaXRlcmlhX3N0cmluZyA8LSBmdW5jdGlvbihjYXRlZ29yeV9uYW1lKSB7DQogIGNyaXRlcmlhIDwtIGV4ZXJjaXNlX2NyaXRlcmlhW1tjYXRlZ29yeV9uYW1lXV0NCiAgaWYgKGlzLm51bGwoY3JpdGVyaWEpKSByZXR1cm4oTkEpDQogIA0KICBjcml0ZXJpYV9zdHJpbmdzIDwtIGMoKQ0KICBpZiAoIWlzLm51bGwoY3JpdGVyaWEkUG9zaXRpb24pKSB7DQogICAgbW9kaWZpZWRfcG9zaXRpb24gPC0gZ3N1YigiXFwuXFwqKC4qPylcXC5cXCoiLCAiXFwxIiwgY3JpdGVyaWEkUG9zaXRpb24pDQogICAgY3JpdGVyaWFfc3RyaW5ncyA8LSBjKGNyaXRlcmlhX3N0cmluZ3MsIG1vZGlmaWVkX3Bvc2l0aW9uKQ0KICB9DQogIGlmICghaXMubnVsbChjcml0ZXJpYSRJbnN0cnVtZW50KSkgew0KICAgIG1vZGlmaWVkX2luc3RydW1lbnQgPC0gZ3N1YigiXFwuXFwqKC4qPylcXC5cXCoiLCAiXFwxIiwgY3JpdGVyaWEkSW5zdHJ1bWVudCkNCiAgICBjcml0ZXJpYV9zdHJpbmdzIDwtIGMoY3JpdGVyaWFfc3RyaW5ncywgbW9kaWZpZWRfaW5zdHJ1bWVudCkNCiAgfQ0KICBpZiAoIWlzLm51bGwoY3JpdGVyaWEkQWN0aXZpdHkpKSB7DQogICAgbW9kaWZpZWRfYWN0aXZpdHkgPC0gZ3N1YigiXFwuXFwqKC4qPylcXC5cXCoiLCAiXFwxIiwgY3JpdGVyaWEkQWN0aXZpdHkpDQogICAgY3JpdGVyaWFfc3RyaW5ncyA8LSBjKGNyaXRlcmlhX3N0cmluZ3MsIG1vZGlmaWVkX2FjdGl2aXR5KQ0KICB9DQogIA0KICByZXR1cm4ocGFzdGUoY3JpdGVyaWFfc3RyaW5ncywgY29sbGFwc2UgPSAiICIpKQ0KfQ0KDQojIEFwcGx5IGNyaXRlcmlhIHN0cmluZyBjcmVhdGlvbiBhbmQgcmVtb3ZlICdDYXRlZ29yeSBTaGVldCcNCm1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2NyaXRlcmlhX21hdGNoIDwtIG1hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzX2xpc3QgJT4lDQogIHJvd3dpc2UoKSAlPiUNCiAgbXV0YXRlKGBTZWxlY3RlZCBDcml0ZXJpYWAgPSBjcmVhdGVfY3JpdGVyaWFfc3RyaW5nKGBDYXRlZ29yeSBOYW1lYCkpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHNlbGVjdCgtYENhdGVnb3J5IFNoZWV0YCkgICMgVGhpcyBleGNsdWRlcyB0aGUgJ0NhdGVnb3J5IFNoZWV0JyBjb2x1bW4NCg0KIyBBZGQgSW5kZXggdG8gc3RhbmRhcmRzDQptYXJrX3JpcHBldG9lX3N0YW5kYXJkc19jcml0ZXJpYV9tYXRjaCA8LSBtYXJrX3JpcHBldG9lX3N0YW5kYXJkc19jcml0ZXJpYV9tYXRjaCAlPiUNCiAgbXV0YXRlKEluZGV4ID0gcm93X251bWJlcigpKQ0KDQojIERpc3BsYXkgdGhlIG1vZGlmaWVkICdTdHJlbmd0aCBTdGFuZGFyZCcgY29sdW1uIHdpdGggc3BhY2VzIGluc3RlYWQgb2YgdW5kZXJzY29yZXMNCmRpc3BsYXlfbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfY3JpdGVyaWFfbWF0Y2ggPC0gbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfY3JpdGVyaWFfbWF0Y2ggJT4lDQogIG11dGF0ZShgU3RyZW5ndGggU3RhbmRhcmRgID0gZ3N1YigiXyIsICIgIiwgYFN0cmVuZ3RoIFN0YW5kYXJkYCkpDQoNCiMgVXNlIGtuaXRyOjprYWJsZSB0byBmb3JtYXQgYXMgYSBtYXJrZG93biB0YWJsZQ0Ka25pdHI6OmthYmxlKGRpc3BsYXlfbWFya19yaXBwZXRvZV9zdGFuZGFyZHNfY3JpdGVyaWFfbWF0Y2gsIGZvcm1hdCA9ICJtYXJrZG93biIsIGNhcHRpb24gPSAiU3BlY2lmaWVkIENyaXRlcmlhIHdpdGggU3RhbmRhcmRzIEZvciBSZWZlcmVuY2UiKQ0KIyBwcmludChtYXJrX3JpcHBldG9lX3N0YW5kYXJkc19jcml0ZXJpYV9tYXRjaCkgIyBQcmludCB0aWJibGUgZm9yIHJlZmVyZW5jZQ0KDQpgYGANCg0KIyMgMVJNIFRhYmxlIC0gQXZnIEwyVyAmIEFUSCANClRoZSBmb2xsb3dpbmcgdGFibGUgcmVwb3J0cyB0aGUgYXZlcmFnZSBvbmUtcmVwZXRpdGlvbiBtYXhpbXVtICgxUk0pIGZvciBlYWNoIGluZGl2aWR1YWwgYWNyb3NzIGVhY2ggc3BlY2lmaWVkIGV4ZXJjaXNlICgiU2VsZWN0ZWQgQ3JpdGVyaWEiKSBvdmVyIHRoZSBsYXN0IHR3byB3ZWVrcyAoTDJXKS4gVGhlIGRhdGEgZm9yIHRoZSBsYXN0IHR3byB3ZWVrcyBzZXJ2ZXMgYXMgYSBiZW5jaG1hcmsgZm9yIHRoZSBuZXh0IHdvcmtvdXQuIEFzIHRoZSBzYXlpbmcgZ29lcywgIllvdSdyZSBvbmx5IGFzIGdvb2QgYXMgeW91ciBsYXN0LiINCg0KVGhlIHRhYmxlIGFsc28gcmVwb3J0cyBoaWdoZXN0IDFSTSBvdmVyIGFsbCB0aW1lIChBVEgpIGZvciBlYWNoIHNlbGVjdGVkIGNyaXRlcmlvbiwgYWNjb21wYW5pZWQgYnkgdGhlIGxhc3QgZGF0ZSB0aGUgaGlnaGVzdCAxUk0gd2FzIGFjaGlldmVkLg0KDQpUaGUgMVJNIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gd2VpZ2h0IGV4ZWN1dGVkIHBlciBzZXQgYW5kIHRoZSBudW1iZXIgb2YgcmVwcywgdXNpbmcgdGhlIDFSTSBDb252ZXJzaW9uIFRhYmxlW14xMF0uDQoNCkFsbCBjYWxjdWxhdGlvbnMgYXNzdW1lIHRoZSBzdGFuZGFyZCBiYXJiZWxsIChPbHltcGljIGJhcmJlbGwpIHdlaWdodCBvZiA0NSBwb3VuZHMgKDIwLjQga2cpLg0KDQpLZWVwIGluIG1pbmQgdGhlcmUgYXJlIG1hbnkgdmFyaWFibGVzIGFmZmVjdGluZyBwZXJmb3JtYW5jZS4gT25lIG9mIHRoZXNlIHZhcmlhYmxlcyBpbmNsdWRlcyBncmlwICh3aWRlLCBhbHRlcm5hdGluZywgb3ZlcmhhbmQsIGV0Yy4pLiBPbmUgaW5kaXZpZHVhbCBtYXkgdXNlIGFsdGVybmF0aW5nIGdyaXBzIChsZWZ0IHVuZGVyaGFuZC9yaWdodCBvdmVyaGFuZCwgb3IgdmljZS12ZXJzYSkgd2hlbiBwZXJmb3JtaW5nIGRlYWRsaWZ0cyB0byBtYXhpbWl6ZSB3ZWlnaHQgZXhlY3V0aW9uLiBBbm90aGVyIGluZGl2aWR1YWwgbWlnaHQgdXRpbGl6ZSBhbiBvdmVyaGFuZCBncmlwLiBTb21lb25lIGVsc2UgbWF5IHBlcmZvcm0gYSBjb21iaW5hdGlvbiBvZiBhbHRlcm5hdGluZyBncmlwIGFuZCBvdmVyaGFuZCBncmlwLiBUaGUgZm9sbG93aW5nIGRhdGFzZXRzIGFuZCBmaWd1cmVzIGRvIG5vdCBhY2NvdW50IGZvciB0aGVzZSBkaWZmZXJlbmNlcy4NCg0KPCEtLSBQbGFuIA0KUExBTjogQ3JlYXRlIGNvZGUgdG8gc2F2ZSBwbG90cyBhcyBmaWxlLioqDQotLT4gDQoNCmBgYHtyIHRhYmxlXzFybV9wZXJmb3JtYW5jZV9vbl9tYXJrX3JpcHBldG9lX3N0YW5kYXJkcywgZXZhbD1UUlVFLCByZXN1bHRzPSdtYXJrdXAnfQ0KDQojIFRoaXMgYmxvY2sgb2YgUiBjb2RlIGFkanVzdHMgdGhlIGFwcHJvYWNoIHRvIGFuYWx5emluZyB0aGUgYXZlcmFnZSBvbmUtcmVwZXRpdGlvbiBtYXhpbXVtICgxUk0pIGZvciBlYWNoIGluZGl2aWR1YWwgb3ZlciB0aGUgbGFzdCB0d28gd2Vla3MgZnJvbSB0aGUgbW9zdCByZWNlbnQgZGF0ZSBvZiBlYWNoIHNwZWNpZmljIGV4ZXJjaXNlLg0KDQojIFRoaXMgYmxvY2sgb2YgUiBjb2RlIHBlcmZvcm1zIGEgZGV0YWlsZWQgYW5hbHlzaXMgYW5kIHJlcG9ydGluZyBvZiB0aGUgYXZlcmFnZSBvbmUtcmVwZXRpdGlvbiBtYXhpbXVtICgxUk0pIGZvciBlYWNoIGluZGl2aWR1YWwgaW4gdGhlIGRhdGFzZXQgb3ZlciB0aGUgbGFzdCB0d28gd2Vla3MgZm9yIHNwZWNpZmljIGV4ZXJjaXNlcy4gVGhlIHJlcG9ydCBpbmNsdWRlcyBzZXZlcmFsIGRldGFpbHMgYWJvdXQgZWFjaCBleGVyY2lzZSwgc3VjaCBhcyB0aGUgbnVtYmVyIG9mIHNldHMsIG51bWJlciBvZiB3b3Jrb3V0IGRheXMsIGFuZCB0aGUgYWN0dWFsIGRhdGUgcmFuZ2Ugb2YgdGhlIHdvcmtvdXRzLiANCg0KIyBjYXQoIkFWRVJBR0UgMSBSRVAgTUFYIEZPUiBMQVNUIDIgV0VFS1MgT0YgREFUQSBcbiIpDQojIGNhdCgiTm90ZTogMVJNIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gV2VpZ2h0IEV4ZWN1dGVkIFBlciBTZXQsIE51bWJlciBvZiBSZXBzLCBhbmQgYSBDb252ZXJzaW9uIFRhYmxlIGZvciBSZXBldGl0aW9uIFBlcmNlbnRhZ2VzIG9mIDFSTSAoc291cmNlOiBodHRwczovL3N0cmVuZ3RobGV2ZWwuY29tL29uZS1yZXAtbWF4LWNhbGN1bGF0b3IgYXMgb2YgMDIvMjAyNCkuXG5cbiIpDQoNCg0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCiMgRmlsdGVyaW5nIERhdGENCnJhd19kYXRhIDwtIHJhd19kYXRhICU+JQ0KICBtdXRhdGUoYDFSTV9DYWxjdWxhdGVkX1dlaWdodGAgPSBhcy5udW1lcmljKGAxUk1fQ2FsY3VsYXRlZF9XZWlnaHRgLCB3YXJuID0gRkFMU0UpKSAlPiUNCiAgZmlsdGVyKCFpcy5uYShgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCkpICU+JQ0KICBtdXRhdGUoRGF0ZSA9IGFzLkRhdGUoRGF0ZSwgZm9ybWF0PSIlbS8lZC8lWSIpKQ0KDQojIFVuaXF1ZSBuYW1lcyB2ZWN0b3INCnVuaXF1ZV9uYW1lcyA8LSB1bmlxdWUocmF3X2RhdGEkTmFtZSkNCg0KIyBDcmVhdGUgQ3JpdGVyaWEgU3RyaW5ncw0KY3JlYXRlX2NyaXRlcmlhX3N0cmluZyA8LSBmdW5jdGlvbihjYXRlZ29yeV9uYW1lKSB7DQogIGNyaXRlcmlhIDwtIGV4ZXJjaXNlX2NyaXRlcmlhW1tjYXRlZ29yeV9uYW1lXV0NCiAgaWYgKGlzLm51bGwoY3JpdGVyaWEpKSByZXR1cm4oTkEpDQogIGNyaXRlcmlhX3N0cmluZ3MgPC0gYygpDQogIGlmICghaXMubnVsbChjcml0ZXJpYSRQb3NpdGlvbikpIGNyaXRlcmlhX3N0cmluZ3MgPC0gYXBwZW5kKGNyaXRlcmlhX3N0cmluZ3MsIGNyaXRlcmlhJFBvc2l0aW9uKQ0KICBpZiAoIWlzLm51bGwoY3JpdGVyaWEkSW5zdHJ1bWVudCkpIGNyaXRlcmlhX3N0cmluZ3MgPC0gYXBwZW5kKGNyaXRlcmlhX3N0cmluZ3MsIGNyaXRlcmlhJEluc3RydW1lbnQpDQogIGlmICghaXMubnVsbChjcml0ZXJpYSRBY3Rpdml0eSkpIHsNCiAgICBtb2RpZmllZF9hY3Rpdml0eSA8LSBnc3ViKCJcXC5cXCooLio/KVxcLlxcKiIsICJcXDEiLCBjcml0ZXJpYSRBY3Rpdml0eSkNCiAgICBjcml0ZXJpYV9zdHJpbmdzIDwtIGFwcGVuZChjcml0ZXJpYV9zdHJpbmdzLCBtb2RpZmllZF9hY3Rpdml0eSkNCiAgfQ0KICByZXR1cm4oZ3N1YigiXyIsICIgIiwgcGFzdGUoY3JpdGVyaWFfc3RyaW5ncywgY29sbGFwc2UgPSAiICIpKSkNCn0NCg0KIyBGdW5jdGlvbiB0byBleHBhbmQgc3RhbmRhcmRzIHdpdGggcGVyZm9ybWFuY2UgZGF0YQ0KZXhwYW5kX3N0YW5kYXJkc193aXRoX3BlcmZvcm1hbmNlIDwtIGZ1bmN0aW9uKHN0YW5kYXJkcywgcmF3X2RhdGEsIHVuaXF1ZV9uYW1lcywgZXhlcmNpc2VfY3JpdGVyaWEpIHsNCiAgcGVyZm9ybWFuY2VfZGF0YSA8LSBsaXN0KCkNCiAgZm9yIChuYW1lIGluIHVuaXF1ZV9uYW1lcykgew0KICAgIGZvciAoZXhlcmNpc2UgaW4gbmFtZXMoZXhlcmNpc2VfY3JpdGVyaWEpKSB7DQogICAgICBjcml0ZXJpYSA8LSBleGVyY2lzZV9jcml0ZXJpYVtbZXhlcmNpc2VdXQ0KICAgICAgc2VsZWN0ZWRfY3JpdGVyaWEgPC0gY3JlYXRlX2NyaXRlcmlhX3N0cmluZyhleGVyY2lzZSkNCiAgICAgIA0KICAgICAgIyBGaWx0ZXIgcmF3X2RhdGEgYnkgbmFtZSBhbmQgZXhlcmNpc2UgY3JpdGVyaWENCiAgICAgIHJhd19kYXRhX2NyaXRlcmlhIDwtIHJhd19kYXRhICU+JQ0KICAgICAgICBmaWx0ZXIoTmFtZSA9PSBuYW1lKSAlPiUNCiAgICAgICAgZmlsdGVyKGlmICghaXMubnVsbChjcml0ZXJpYSRQb3NpdGlvbikpIFBvc2l0aW9uID09IGNyaXRlcmlhJFBvc2l0aW9uIGVsc2UgVFJVRSwNCiAgICAgICAgICAgICAgIGdyZXBsKGNyaXRlcmlhJEluc3RydW1lbnQsIEluc3RydW1lbnQsIGlnbm9yZS5jYXNlID0gVFJVRSksDQogICAgICAgICAgICAgICBncmVwbChjcml0ZXJpYSRBY3Rpdml0eSwgQWN0aXZpdHksIGlnbm9yZS5jYXNlID0gVFJVRSkpDQogICAgICANCiAgICAgICMgTW9zdCByZWNlbnQgd29ya291dCBkYXRlIGZvciB0aGUgc3BlY2lmaWMgZXhlcmNpc2UNCiAgICAgIGluZGl2aWR1YWxfbWF4X2RhdGUgPC0gbWF4KHJhd19kYXRhX2NyaXRlcmlhJERhdGUsIG5hLnJtID0gVFJVRSkNCiAgICAgIA0KICAgICAgIyBGaWx0ZXIgZm9yIHRoZSBsYXN0IHR3byB3ZWVrcyBmcm9tIHRoZSBtb3N0IHJlY2VudCBkYXRlIG9mIHRoZSBleGVyY2lzZQ0KICAgICAgaW5kaXZpZHVhbF9taW5fZGF0ZV9sYXN0XzJ3ayA8LSBpbmRpdmlkdWFsX21heF9kYXRlIC0gZGF5cygxMykNCiAgICAgIHJhd19kYXRhX2NyaXRlcmlhX2xhc3RfMndrIDwtIHJhd19kYXRhX2NyaXRlcmlhICU+JQ0KICAgICAgICBmaWx0ZXIoRGF0ZSA+PSBpbmRpdmlkdWFsX21pbl9kYXRlX2xhc3RfMndrICYgRGF0ZSA8PSBpbmRpdmlkdWFsX21heF9kYXRlKQ0KICAgICAgDQogICAgICBhdmdfMXJtX2xhc3RfMndrIDwtIGlmKG5yb3cocmF3X2RhdGFfY3JpdGVyaWFfbGFzdF8yd2spID4gMCkgcm91bmQobWVhbihyYXdfZGF0YV9jcml0ZXJpYV9sYXN0XzJ3ayRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCwgbmEucm0gPSBUUlVFKSwgMikgZWxzZSAiTm8gZGF0YSBhdmFpbGFibGUiDQogICAgICBkYXRlX3JhbmdlIDwtIGlmKG5yb3cocmF3X2RhdGFfY3JpdGVyaWFfbGFzdF8yd2spID4gMCkgcGFzdGUoaW5kaXZpZHVhbF9taW5fZGF0ZV9sYXN0XzJ3aywgaW5kaXZpZHVhbF9tYXhfZGF0ZSwgc2VwID0gIiB0byAiKSBlbHNlICJObyBkYXRhIGF2YWlsYWJsZSINCiAgICAgIG51bV9zZXRzIDwtIG5yb3cocmF3X2RhdGFfY3JpdGVyaWFfbGFzdF8yd2spDQogICAgICBudW1fd29ya291dF9kYXlzIDwtIGxlbmd0aCh1bmlxdWUocmF3X2RhdGFfY3JpdGVyaWFfbGFzdF8yd2skRGF0ZSkpDQogICAgICANCiAgICAgICMgQ2FsY3VsYXRlIGhpZ2hlc3QgMVJNIGFsbCB0aW1lIGFuZCB0aGUgY29ycmVzcG9uZGluZyBkYXRlDQogICAgICBtYXhfMXJtX2FsbF90aW1lIDwtIGlmIChucm93KHJhd19kYXRhX2NyaXRlcmlhKSA+IDApIG1heChyYXdfZGF0YV9jcml0ZXJpYSRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCwgbmEucm0gPSBUUlVFKSBlbHNlIE5BDQogICAgICBtYXhfMXJtX2FsbF90aW1lX2RhdGUgPC0gaWYgKCFpcy5uYShtYXhfMXJtX2FsbF90aW1lKSkgew0KICAgICAgICBtYXgocmF3X2RhdGFfY3JpdGVyaWEkRGF0ZVtyYXdfZGF0YV9jcml0ZXJpYSRgMVJNX0NhbGN1bGF0ZWRfV2VpZ2h0YCA9PSBtYXhfMXJtX2FsbF90aW1lXSwgbmEucm0gPSBUUlVFKQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgTkENCiAgICAgIH0NCiAgICAgIA0KIyAgICAgIEV4Y2x1ZGUgZm9yIGRpc3BsYXkgcHVycG9zZXMuIFJlZmVyIHRvIHRoZSB0YWJsZSBmb3Igc2FtZSBkYXRhLiANCiMgICAgICBjYXQoIkNhdGVnb3J5IE5hbWU6IiwgZXhlcmNpc2UsICJcbiIpDQojICAgICAgY2F0KCJTZWxlY3RlZCBDcml0ZXJpYToiLCBzZWxlY3RlZF9jcml0ZXJpYSwgIlxuIikNCiMgICAgICBjYXQoIkF2ZXJhZ2UgMVJNIChsYnMpOiIsIGlmZWxzZShpcy5uYW4oYXZnXzFybV9sYXN0XzJ3aykgfCBudW1fc2V0cyA9PSAwLCAiTm8gZGF0YSBhdmFpbGFibGUiLCByb3VuZChhdmdfMXJtX2xhc3RfMndrLCAyKSksICJcbiIpDQojICAgICAgY2F0KCJEYXRlIFJhbmdlIChMYXN0IDIgV2Vla3Mgb2YgRGF0YSk6IiwgZGF0ZV9yYW5nZSwgIlxuIikNCiMgICAgICBjYXQoIkJhc2VkIG9uIiwgbnVtX3NldHMsICJzZXRzXG4iKQ0KIyAgICAgIGNhdCgiQmFzZWQgb24iLCBudW1fd29ya291dF9kYXlzLCAid29ya291dCBkYXlzXG4iKQ0KIyAgICAgIGNhdCgiSGlnaGVzdCAxUk0gQWxsIFRpbWUgKGxicyk6IiwgaWZlbHNlKGlzLm5hKG1heF8xcm1fYWxsX3RpbWUpLCAiTm8gZGF0YSBhdmFpbGFibGUiLCByb3VuZChtYXhfMXJtX2FsbF90aW1lLCAyKSksICJcbiIpDQojICAgICAgY2F0KCJEYXRlIG9mIExhc3QgMVJNIEFUSDoiLCBpZmVsc2UoaXMubmEobWF4XzFybV9hbGxfdGltZV9kYXRlKSwgIk5vIGRhdGEgYXZhaWxhYmxlIiwgZm9ybWF0KG1heF8xcm1fYWxsX3RpbWVfZGF0ZSwgIiVZLSVtLSVkIikpLCAiXG4iKQ0KIyAgICAgIGNhdCgiLVxuIikNCg0KICAgICAgcGVyZm9ybWFuY2VfZGF0YVtbbGVuZ3RoKHBlcmZvcm1hbmNlX2RhdGEpICsgMV1dIDwtIHRpYmJsZSgNCiAgICAgICAgTmFtZSA9IG5hbWUsDQogICAgICAgIGBDYXRlZ29yeSBOYW1lYCA9IGV4ZXJjaXNlLA0KICAgICAgICBgU2VsZWN0ZWQgQ3JpdGVyaWFgID0gc2VsZWN0ZWRfY3JpdGVyaWEsDQogICAgICAgIGBBdmVyYWdlIDFSTSAobGJzKWAgPSBpZmVsc2UoaXMubnVtZXJpYyhhdmdfMXJtX2xhc3RfMndrKSwgc3ByaW50ZigiJS4yZiIsIGF2Z18xcm1fbGFzdF8yd2spLCBhdmdfMXJtX2xhc3RfMndrKSwNCiAgICAgICAgYERhdGUgUmFuZ2UgKExhc3QgMiBXZWVrcylgID0gZGF0ZV9yYW5nZSwNCiAgICAgICAgYE51bWJlciBvZiBTZXRzYCA9IG51bV9zZXRzLA0KICAgICAgICBgTnVtYmVyIG9mIERheXNgID0gbnVtX3dvcmtvdXRfZGF5cywNCiAgICAgICAgYEhpZ2hlc3QgMVJNIEFsbCBUaW1lIChsYnMpYCA9IGlmZWxzZShpcy5udW1lcmljKG1heF8xcm1fYWxsX3RpbWUpLCBzcHJpbnRmKCIlLjJmIiwgbWF4XzFybV9hbGxfdGltZSksIG1heF8xcm1fYWxsX3RpbWUpLA0KICAgICAgICBgTGFzdCBEYXRlIEhpZ2hlc3QgMVJNIEFsbCBUaW1lYCA9IGlmZWxzZSghaXMubmEobWF4XzFybV9hbGxfdGltZV9kYXRlKSwgZm9ybWF0KG1heF8xcm1fYWxsX3RpbWVfZGF0ZSwgIiVZLSVtLSVkIiksICJObyBkYXRhIGF2YWlsYWJsZSIpLA0KICAgICAgICBJbmRleCA9IG1hdGNoKGV4ZXJjaXNlLCBzdGFuZGFyZHMkYENhdGVnb3J5IE5hbWVgKSAjIFVzZSBtYXRjaCB0byBmaW5kIHRoZSBvcmlnaW5hbCBvcmRlcg0KICAgICAgKQ0KICAgIH0NCiAgfQ0KDQogIGNvbWJpbmVkX3BlcmZvcm1hbmNlX2RhdGEgPC0gYmluZF9yb3dzKHBlcmZvcm1hbmNlX2RhdGEpDQogIGV4cGFuZGVkX3N0YW5kYXJkcyA8LSBzdGFuZGFyZHMgJT4lDQogICAgcmlnaHRfam9pbihjb21iaW5lZF9wZXJmb3JtYW5jZV9kYXRhLCBieSA9IGMoIkNhdGVnb3J5IE5hbWUiLCAiU2VsZWN0ZWQgQ3JpdGVyaWEiLCAiSW5kZXgiKSkgJT4lDQogICAgYXJyYW5nZShOYW1lLCBJbmRleCkgIyBTb3J0IGJ5IE5hbWUgYW5kIHRoZW4gYnkgdGhlIG9yaWdpbmFsIG9yZGVyDQogIHJldHVybihleHBhbmRlZF9zdGFuZGFyZHMpDQp9DQoNCiMgRXhlY3V0ZSBhbmQgZGlzcGxheSByZXN1bHRzDQpwZXJmb3JtYW5jZV9vbl9tYXJrX3JpcHBldG9lX3N0YW5kYXJkcyA8LSBleHBhbmRfc3RhbmRhcmRzX3dpdGhfcGVyZm9ybWFuY2UobWFya19yaXBwZXRvZV9zdGFuZGFyZHNfY3JpdGVyaWFfbWF0Y2gsIHJhd19kYXRhLCB1bmlxdWVfbmFtZXMsIGV4ZXJjaXNlX2NyaXRlcmlhKQ0KDQojIE1vZGlmeSB0aGUgJ1N0cmVuZ3RoIFN0YW5kYXJkcycgY29sdW1uIGZvciBkaXNwbGF5IHB1cnBvc2VzIGJ5IHJlcGxhY2luZyAiXyIgd2l0aCAiICINCnBlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzIDwtIHBlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzICU+JQ0KICBtdXRhdGUoYFN0cmVuZ3RoIFN0YW5kYXJkYCA9IGdzdWIoIl8iLCAiICIsIGBTdHJlbmd0aCBTdGFuZGFyZGApKSAlPiUNCiAgYXJyYW5nZSgNCiAgICBgSW5kZXhgLCAgIyBBc2NlbmRpbmcgYnkgZGVmYXVsdA0KICAgIGBOYW1lYA0KICAgICMgZGVzYyhgQXZlcmFnZSAxUk0gKGxicylgICMgRGVzY2VuZGluZw0KICApDQoNCiMgU2VsZWN0IHNwZWNpZmljIGNvbHVtbnMgZm9yIGRpc3BsYXkNCmRpc3BsYXlfcGVyZm9ybWFuY2Vfb25fbWFya19yaXBwZXRvZV9zdGFuZGFyZHMgPC0gcGVyZm9ybWFuY2Vfb25fbWFya19yaXBwZXRvZV9zdGFuZGFyZHMgJT4lDQogIHNlbGVjdChgU2VsZWN0ZWQgQ3JpdGVyaWFgLCANCiAgICAgICAgIGBJbmRleGAsDQogICAgICAgICBgTmFtZWAsDQogICAgICAgICBgQXZlcmFnZSAxUk0gKGxicylgLCANCiAgICAgICAgIGBEYXRlIFJhbmdlIChMYXN0IDIgV2Vla3MpYCwgDQogICAgICAgICBgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKGxicylgLCANCiAgICAgICAgIGBMYXN0IERhdGUgSGlnaGVzdCAxUk0gQWxsIFRpbWVgKSAlPiUNCiAgZmlsdGVyX2FsbChhbGxfdmFycyguICE9ICJObyBkYXRhIGF2YWlsYWJsZSIgJiAhaXMubmEoLikpKQ0KDQojIERpc3BsYXkgdGhlIGZpcnN0IGZldyByb3dzIG9mIHRoZSBkYXRhZnJhbWUNCiMgaGVhZChwZXJmb3JtYW5jZV9vbl9tYXJrX3JpcHBldG9lX3N0YW5kYXJkcykNCg0KIyBVc2Uga2FibGUgYW5kIGthYmxlRXh0cmEgZm9yIGZvcm1hdHRpbmcgb2YgdGFibGUgb3V0cHV0DQprYWJsZShkaXNwbGF5X3BlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzLCAiaHRtbCIsIGFsaWduID0gJ2wnKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIA0KICAgICAgICAgICAgICAgIGZpeGVkX3RoZWFkID0gVFJVRSkgJT4lDQogIGNvbHVtbl9zcGVjKDE6bmNvbChkaXNwbGF5X3BlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzKSwgd2lkdGggPSAiYXV0byIpDQoNCiMgUHJpbnQgdGhlIGNvbHVtbiBoZWFkZXJzIHRvIGNob29zZSBEeW5hbWljIE9yZGVyaW5nLiANCmNvbHVtbl9oZWFkZXJzIDwtIGNvbG5hbWVzKHBlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzKQ0KY29sdW1uX2hlYWRlcnNfZGlzcGxheSA8LSBjb2xuYW1lcyhkaXNwbGF5X3BlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzKQ0KIyBwcmludChjb2x1bW5faGVhZGVycykNCiMgcHJpbnQoY29sdW1uX2hlYWRlcnNfZGlzcGxheSkNCg0KYGBgDQoNCiMjIEluZGl2aWR1YWwgUGVyZm9ybWFuY2UgVGFibGVzDQpGaWx0ZXJlZCByZXN1bHRzIGFyZSBncm91cGVkIGJ5IGluZGl2aWR1YWwuIFNvbWUgaW5kaXZpZHVhbHMgZG8gbm90IGhhdmUgcmVjb3JkZWQgZGF0YSB0aGF0IG1lZXRzIHRoZSBjcml0ZXJpYS4NCg0KYGBge3IgaW5kaXZpZHVhbF90YWJsZV9wZXJmb3JtYW5jZV90b19tYXJrX3JpcHBldG9lX3N0YW5kYXJkcywgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCg0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojIExvb3AgdGhyb3VnaCBlYWNoIHVuaXF1ZSBuYW1lIGFuZCBnZW5lcmF0ZSBhIHRhYmxlIGZvciBlYWNoDQpmb3IgKGkgaW4gc2VxX2Fsb25nKHVuaXF1ZShkaXNwbGF5X3BlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzJE5hbWUpKSkgew0KICANCiAgbmFtZSA8LSB1bmlxdWUoZGlzcGxheV9wZXJmb3JtYW5jZV9vbl9tYXJrX3JpcHBldG9lX3N0YW5kYXJkcyROYW1lKVtpXQ0KICANCiAgIyBBZGQgdGhpcyBjb25kaXRpb25hbCBjaGVjayB0byBwcm9jZXNzIG9ubHkgIkFsZXgiDQogICMgaWYgKG5hbWUgPT0gIkFsZXgiKSB7DQoNCiAgIyBGaWx0ZXIgdGhlIHJlc3VsdHMgZm9yIHRoZSBjdXJyZW50IG5hbWUNCiAgaW5kaXZpZHVhbF9wZXJmb3JtYW5jZSA8LSBkaXNwbGF5X3BlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzICU+JQ0KICAgIGZpbHRlcihOYW1lID09IG5hbWUpICU+JQ0KICAgIHNlbGVjdCgtTmFtZSkgICMgUmVtb3ZlIHRoZSAiTmFtZSIgY29sdW1uIGZvciB0aGUgdGFibGUNCiAgDQogICMgUHJpbnQgdGhlIHNlY3Rpb24gaGVhZGVyDQogIGNhdChwYXN0ZTAoIlxuXG48aDQ+IiwgbmFtZSwgIiAtIDFSTSBQZXJmb3JtYW5jZSA8L2g0PlxuXG4iKSkNCiAgDQogICMgVXNlIGthYmxlIGFuZCBrYWJsZUV4dHJhIGZvciBmb3JtYXR0aW5nIG9mIHRhYmxlIG91dHB1dA0KICBrYWJsZShpbmRpdmlkdWFsX3BlcmZvcm1hbmNlLCAiaHRtbCIsIGFsaWduID0gJ2wnKSAlPiUgDQogICAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICBmaXhlZF90aGVhZCA9IFRSVUUpICU+JQ0KICAgIGNvbHVtbl9zcGVjKDE6bmNvbChpbmRpdmlkdWFsX3BlcmZvcm1hbmNlKSwgd2lkdGggPSAiYXV0byIpICU+JQ0KICAgIHByaW50KCkgICMgUHJpbnQgZWFjaCB0YWJsZQ0KICANCiAgY2F0KCJcblxuIikNCn0NCg0KYGBgDQoNCg0KIyAxUk0gUGxvdHMgLSBQZXJmb3JtYW5jZSBPdmVyIFN0YW5kYXJkcyANClBlcmZvcm1hbmNlIGlzIHBsb3R0ZWQgb3ZlciBNYXJrIFJpcHBldG9lJ3MgU3RyZW5ndGggU3RhbmRhcmRzLg0KDQpTb21lIGNvbnNpZGVyYXRpb25zIGZvciB0aGUgZm9sbG93aW5nIHBsb3RzOg0KDQotIEF2ZXJhZ2UgMVJNIGZvciBlYWNoIGluZGl2aWR1YWwgaXMgYmFzZWQgb24gZGF0YSBmcm9tIHRoZSBsYXN0IDIgd2Vla3MgKEwyVykuIEFzIHByZXNlbnRlZCBpbiB0aGUgMVJNIFRhYmxlIGFib3ZlLCBkYXRlIHJhbmdlcyBiZXR3ZWVuIGVhY2ggaW5kaXZpZHVhbCBkaWZmZXIsIHJhbmdpbmcgZnJvbSBhIGZldyB3ZWVrcyB0byBzZXZlcmFsIG1vbnRocyBvciBldmVuIHllYXJzLiBEZXNwaXRlIHRoZXNlIGRpZmZlcmVuY2VzLCB0aGlzIHBsb3QgaXMgc3RpbGwgYmVuZWZpY2lhbCBmb3IgY29tcGFyaW5nIHBlcmZvcm1hbmNlIGFtb25nIGluZGl2aWR1YWxzLCBmb3N0ZXJpbmcgZnJpZW5kbHkgY29tcGV0aXRpb24sIGFuZCBtb3RpdmF0aW5nIGFjdGlvbiB0b3dhcmQgaGlnaGVyIHBlcmZvcm1hbmNlLg0KDQotIEhpZ2hlc3QgMVJNIChBVEggLSBBbGwgVGltZSBIaWdocykgZm9yIGVhY2ggaW5kaXZpZHVhbCBpcyBiYXNlZCBvbiBkYXRhIGZyb20gYWxsIGVudHJpZXMuDQoNCi0gQXZlcmFnZSBCb2R5d2VpZ2h0IHJlcHJlc2VudHMgZGF0YSBmcm9tIHRoZSBsYXN0IDIgd2Vla3Mgb2YgZW50cmllcyBmb3IgZWFjaCBpbmRpdmlkdWFsLiBUaGUgZm9sbG93aW5nIHBsb3RzIGFuZCBDYXRlZ29yeSBMZXZlbHMgdXNlIEF2ZXJhZ2UgQm9keXdlaWdodCBmb3IgYm90aCBBdmVyYWdlIDFSTSBMMlcgYW5kIEFUSCBleGVjdXRpb25zLiBTZXBhcmF0ZSBjYWxjdWxhdGlvbnMgYXJlIHJlcXVpcmVkIHRvIG9idGFpbiBCb2R5d2VpZ2h0IGF0IHRoZSB0aW1lIHdoZW4gQXZlcmFnZSAxUk0gTDJXIHdhcyBleGVjdXRlZCBhbmQgQm9keXdlaWdodCB3aGVuIEFUSCAxUk0gd2FzIGV4ZWN1dGVkLg0KDQotIFRoZSBkYXRlIGFuZCBkYXRlIHJhbmdlcyBmb3IgQXZlcmFnZSBCb2R5d2VpZ2h0IChsYnMpIGFuZCAxUk0gc3RhdGlzdGljcyBtYXkgbm90IGFsaWduLiBGb3IgZXhhbXBsZTogDQogICAgLSBEYXRlIFJhbmdlIGZvciBBdmVyYWdlIDFSTSBMMlc6IDIwMjMtMTAtMjcgdG8gMjAyMy0xMS0wOQkJDQogICAgLSBEYXRlIGZvciBBVEggMVJNOiAyMDIzLTEwLTE4CQ0KICAgIC0gRGF0ZSBSYW5nZSBmb3IgQXZlcmFnZSBCb2R5d2VpZ2h0IEwyVzogMjAyNC0wNS0yNCB0byAyMDI0LTA2LTA2DQogICAgLSBGdXJ0aGVyIGNhbGN1bGF0aW9ucyBhcmUgcmVxdWlyZWQgdG8gYWxpZ24gdGhlIGRhdGUgcmFuZ2VzIGJldHdlZW4gYm9keXdlaWdodCBhbmQgcGVyZm9ybWFuY2UsIGFsbG93aW5nIGdyZWF0ZXIgcmVsaWFiaWxpdHkgaW4gdGhlIDFSTSB3ZWlnaHQgZXhlY3V0aW9uLXRvLWJvZHl3ZWlnaHQgcmF0aW8uDQoNCiMjIEF2ZXJhZ2UgMVJNIExhc3QgMiBXZWVrcyAoTDJXKQ0KDQpgYGB7ciBhdmdfMXJtX2xhc3RfMndrX29uX3N0YW5kYXJkcywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTcsIGV2YWw9VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQoNCiMgRW5zdXJlIHRoZSBuZWNlc3NhcnkgbGlicmFyaWVzIGFyZSBsb2FkZWQNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCiMgTG9hZCB0aGUgc3RhbmRhcmRzIHRhYmxlcyBhbmQgc3RvcmUgdGhlbSBpbiBhIGxpc3QNCnN0YW5kYXJkc190YWJsZXMgPC0gbGlzdCgNCiAgIm1hbGVfYmVuY2hfcHJlc3Nfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiID0gbWFsZV9iZW5jaF9wcmVzc19zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSwNCiAgIm1hbGVfZGVhZGxpZnRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiID0gbWFsZV9kZWFkbGlmdF9zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSwNCiAgIm1hbGVfcHJlc3Nfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiID0gbWFsZV9wcmVzc19zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSwNCiAgIm1hbGVfc3F1YXRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiID0gbWFsZV9zcXVhdF9zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZQ0KKQ0KDQojIEZ1bmN0aW9uIHRvIGZpbmQgY2F0ZWdvcnkgbGV2ZWwNCmZpbmRfY2F0ZWdvcnlfbGV2ZWwgPC0gZnVuY3Rpb24od2VpZ2h0LCBidywgc3RhbmRhcmRzX3RhYmxlKSB7DQogIHN0YW5kYXJkcyA8LSBzdGFuZGFyZHNfdGFibGVzW1tzdGFuZGFyZHNfdGFibGVdXQ0KICBpZiAoaXMubnVsbChzdGFuZGFyZHMpKSB7DQogICAgc3RvcCgiU3RhbmRhcmRzIHRhYmxlIG5vdCBmb3VuZC4iKQ0KICB9DQogIA0KICAjIFByaW50IGZvciBkZWJ1Z2dpbmcNCiAgIyBwcmludChzdGFuZGFyZHMpDQogICMgcHJpbnQoYncpDQogIA0KICByb3VuZGVkX2J3IDwtIHN0YW5kYXJkcyAlPiUgZmlsdGVyKGBCb2R5d2VpZ2h0YCA+PSBidykgJT4lIHNsaWNlKDEpICU+JSBwdWxsKGBCb2R5d2VpZ2h0YCkNCiAgY2F0ZWdvcmllcyA8LSBzdGFuZGFyZHMgJT4lIGZpbHRlcihgQm9keXdlaWdodGAgPT0gcm91bmRlZF9idykNCiAgDQogICMgUHJpbnQgZm9yIGRlYnVnZ2luZw0KICAjIHByaW50KGNhdGVnb3JpZXMpDQogIA0KICAjIENvbHVtbiBuYW1lcyBpbiB0aGUgc3RhbmRhcmRzIHRhYmxlcyBoYXZlIGV4dHJhIHNwYWNlcywgc3VjaCBhcyAiQ2F0IEkiIGluc3RlYWQgb2YgIkNhdCBJIg0KICBjYXRlZ29yeSA8LSBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJYCwgIkJlbG93IENhdC4gSSIsDQogICAgICAgICAgICAgICBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJSWAsICJDYXQuIEkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSUlJYCwgIkNhdC4gSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSVZgLCAiQ2F0LiBJSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgVmAsICJDYXQuIElWIiwgIkNhdC4gViIpKSkpKQ0KICByZXR1cm4oY2F0ZWdvcnkpDQp9DQoNCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gYWRkIGRhdGEgcG9pbnRzIHRvIGV4aXN0aW5nIHBsb3RzIGFuZCBnZW5lcmF0ZSBhIHRhYmxlDQphZGRfYm9keXdlaWdodF9hbmRfMXJtX3RvX3Bsb3QgPC0gZnVuY3Rpb24oZXhpc3RpbmdfcGxvdCwgcGVyZm9ybWFuY2VfZGF0YSwgdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBzdGFuZGFyZHNfdGFibGUpIHsNCiAgIyBGaWx0ZXIgYW5kIGpvaW4gdGhlIGRhdGENCiAgY29tYmluZWRfZGF0YSA8LSBwZXJmb3JtYW5jZV9kYXRhICU+JQ0KICAgIGlubmVyX2pvaW4odGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBieSA9ICJOYW1lIikgJT4lDQogICAgbXV0YXRlKGBBdmVyYWdlIDFSTSAobGJzKWAgPSBhcy5udW1lcmljKGBBdmVyYWdlIDFSTSAobGJzKWApKSAlPiUNCiAgICBmaWx0ZXIoIWlzLm5hKGBBdmVyYWdlIDFSTSAobGJzKWApICYgYEF2ZXJhZ2UgMVJNIChsYnMpYCAhPSAiTm8gZGF0YSBhdmFpbGFibGUiKSAlPiUNCiAgICBtdXRhdGUoQ2F0ZWdvcnlfTGV2ZWxfTDJXID0gbWFwcGx5KGZpbmRfY2F0ZWdvcnlfbGV2ZWwsIGBBdmVyYWdlIDFSTSAobGJzKWAsIGBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2tgLCBNb3JlQXJncyA9IGxpc3Qoc3RhbmRhcmRzX3RhYmxlID0gc3RhbmRhcmRzX3RhYmxlKSkpDQoNCiAgIyBQcmludCBmb3IgZGVidWdnaW5nDQogICMgcHJpbnQoY29tYmluZWRfZGF0YSkNCiAgDQogICMgQWRkIHBvaW50cyB0byB0aGUgZXhpc3RpbmcgcGxvdA0KICB1cGRhdGVkX3Bsb3QgPC0gZXhpc3RpbmdfcGxvdCArDQogICAgZ2VvbV9wb2ludChkYXRhID0gY29tYmluZWRfZGF0YSwgYWVzKHggPSBgQXZlcmFnZV9Cb2R5d2VpZ2h0X0xhc3RfMldrYCwgeSA9IGBBdmVyYWdlIDFSTSAobGJzKWAsIGNvbG9yID0gTmFtZSwgZmlsbCA9IE5hbWUpLCANCiAgICAgICAgICAgICAgIHNpemUgPSA0LCBzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIpICsNCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JfcGFsZXR0ZSkgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yX3BhbGV0dGUpICsNCiAgICBsYWJzKGNvbG9yID0gIk5hbWUiLCBmaWxsID0gIk5hbWUiKSArDQogICAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwgIyBEZWNyZWFzZSBsZWdlbmQgdGV4dCBzaXplDQogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksICMgRGVjcmVhc2UgbGVnZW5kIHRpdGxlIHNpemUNCiAgICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuNSwgImNtIikpICMgRGVjcmVhc2UgbGVnZW5kIGtleSBzaXplDQoNCiAgIyBDcmVhdGUgYSB0YWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgY29sdW1ucw0KICB0YWJsZV9kYXRhIDwtIGNvbWJpbmVkX2RhdGEgJT4lDQogICAgc2VsZWN0KE5hbWUsIA0KICAgICAgICAgICBgQXZlcmFnZSAxUk0gKGxicylgLCANCiAgICAgICAgICAgYERhdGUgUmFuZ2UgKExhc3QgMiBXZWVrcylgLCANCiAgICAgICAgICAgYEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXa2AsIA0KICAgICAgICAgICBEYXRlX1JhbmdlLA0KICAgICAgICAgICBDYXRlZ29yeV9MZXZlbF9MMlcpICU+JQ0KICAgIHJlbmFtZSgNCiAgICAgICAgYERhdGUgUmFuZ2VgID0gYERhdGUgUmFuZ2UgKExhc3QgMiBXZWVrcylgLA0KICAgICAgICBgQXZnIEJXIEwyVyAobGJzKWAgPSBgQXZlcmFnZV9Cb2R5d2VpZ2h0X0xhc3RfMldrYCwNCiAgICAgICAgQ2F0ZWdvcnlfTGV2ZWwgPSBDYXRlZ29yeV9MZXZlbF9MMlcNCiAgICAgICAgKQ0KDQogICMgVXBkYXRlIHRhYmxlIGZ1cnRoZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbHVtbnMNCiAgdGFibGVfZGF0YSA8LSB0YWJsZV9kYXRhICU+JQ0KICAgIHNlbGVjdChOYW1lLCANCiAgICAgICAgICAgYEF2ZXJhZ2UgMVJNIChsYnMpYCwgDQogICAgICAgICAgICMgYERhdGUgUmFuZ2VgLCANCiAgICAgICAgICAgYEF2ZyBCVyBMMlcgKGxicylgLCANCiAgICAgICAgICAgQ2F0ZWdvcnlfTGV2ZWwNCiAgICAgICAgICAgIyBEYXRlX1JhbmdlDQogICAgICAgICAgICkNCiAgDQogICMgU3Vic3RpdHV0ZSB1bmRlcnNjb3JlcyB3aXRoIHNwYWNlcyBpbiBjb2x1bW4gbmFtZXMNCiAgY29sbmFtZXModGFibGVfZGF0YSkgPC0gZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGVfZGF0YSkpDQogIA0KICAjIFByaW50IHRoZSBjb21iaW5lZCB0YWJsZSB1c2luZyBrbml0cjo6a2FibGUNCiAgbnVtX2NvbHMgPC0gbmNvbCh0YWJsZV9kYXRhKQ0KICB0YWJsZV9odG1sIDwtIGthYmxlKHRhYmxlX2RhdGEsIGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRkFMU0UsIGFsaWduID0gJ2wnKSAlPiUNCiAgICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgICBjb2x1bW5fc3BlYygxOm51bV9jb2xzLCB3aWR0aCA9IHBhc3RlMCgxMDAgLyBudW1fY29scywgIiUiKSwgZXh0cmFfY3NzID0gInRleHQtYWxpZ246IGxlZnQ7IikNCiAgDQogIHJldHVybihsaXN0KHBsb3QgPSB1cGRhdGVkX3Bsb3QsIHRhYmxlID0gdGFibGVfaHRtbCwgdGFibGVfZGF0YSA9IHRhYmxlX2RhdGEpKQ0KfQ0KDQojIFJldHJpZXZlIGV4aXN0aW5nIHBsb3RzIGFuZCB0aXRsZXMNCmV4aXN0aW5nX3Bsb3RzIDwtIHBsb3RzX2xpc3Rfc3RyZW5ndGhfc3RhbmRhcmRzX21hcmtfcmlwcGV0b2UNCnBsb3RfdGl0bGVzIDwtIG5hbWVzKGV4aXN0aW5nX3Bsb3RzKQ0KDQojIE1hcCBwbG90IHRpdGxlcyB0byBzdGFuZGFyZHMgdGFibGUgbmFtZXMNCnBsb3RfdG9fc3RhbmRhcmRzX3RhYmxlIDwtIGxpc3QoDQogICJNYWxlIEJlbmNoIFByZXNzIFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiA9ICJtYWxlX2JlbmNoX3ByZXNzX3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiwNCiAgIk1hbGUgRGVhZGxpZnQgU3RkIDFSTSBCeSBCb2R5d2VpZ2h0IE1hcmsgUmlwcGV0b2UiID0gIm1hbGVfZGVhZGxpZnRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiLA0KICAiTWFsZSBQcmVzcyBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIgPSAibWFsZV9wcmVzc19zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSIsDQogICJNYWxlIFNxdWF0IFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiA9ICJtYWxlX3NxdWF0X3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIg0KKQ0KDQojIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIHN0YW5kYXJkIGFuZCBhZGQgZGF0YSBwb2ludHMgdG8gdGhlIGV4aXN0aW5nIHBsb3RzDQpmb3IgKHBsb3RfdGl0bGUgaW4gcGxvdF90aXRsZXMpIHsNCiAgDQogICMgRmlsdGVyIHBlcmZvcm1hbmNlIGRhdGEgZm9yIHRoZSBjdXJyZW50IHN0YW5kYXJkDQogIHBlcmZvcm1hbmNlX2RhdGEgPC0gZmlsdGVyKHBlcmZvcm1hbmNlX29uX21hcmtfcmlwcGV0b2Vfc3RhbmRhcmRzLCBgU3RyZW5ndGggU3RhbmRhcmRgID09IHBsb3RfdGl0bGUpDQogIA0KICAjIEdldCB0aGUgZXhpc3RpbmcgcGxvdA0KICBleGlzdGluZ19wbG90IDwtIGV4aXN0aW5nX3Bsb3RzW1twbG90X3RpdGxlXV0NCiAgDQogICMgR2V0IHRoZSBjb3JyZXNwb25kaW5nIHN0YW5kYXJkcyB0YWJsZSBuYW1lDQogIHN0YW5kYXJkc190YWJsZSA8LSBwbG90X3RvX3N0YW5kYXJkc190YWJsZVtbcGxvdF90aXRsZV1dDQogIA0KICAjIEFkZCBib2R5d2VpZ2h0IGFuZCAxUk0gZGF0YSBwb2ludHMgdG8gdGhlIGV4aXN0aW5nIHBsb3QNCiAgcmVzdWx0IDwtIGFkZF9ib2R5d2VpZ2h0X2FuZF8xcm1fdG9fcGxvdChleGlzdGluZ19wbG90LCBwZXJmb3JtYW5jZV9kYXRhLCB0YWJsZV9hdmdfYm9keXdlaWdodHNfbGFzdF8yd2ssIHN0YW5kYXJkc190YWJsZSkNCiAgDQogIGNsZWFuX3RpdGxlIDwtIChzdWIoIiBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIsICIgU3RhbmRhcmRzLCBBdmcgMVJNIEwyVyIsIHBsb3RfdGl0bGUpKQ0KICBjYXQocGFzdGUwKCJcblxuPGg0PiIsIGNsZWFuX3RpdGxlLCAiPC9oND5cblxuIikpDQoNCiAgIyBQcmludCB0aGUgdXBkYXRlZCBwbG90DQogIHByaW50KHJlc3VsdCRwbG90KQ0KICANCiAgIyBQcmludCB0aGUgdGFibGUNCiAgcHJpbnQocmVzdWx0JHRhYmxlKQ0KICANCiAgIyBTYXZlIHRoZSBwbG90DQogICMgcGxvdF9maWxlbmFtZSA8LSBwYXN0ZTAoInBsb3RzL2F2Z18xcm1fbGFzdF8yd2tfb25fIiwgdG9sb3dlcihnc3ViKCIgIiwgIl8iLCBwbG90X3RpdGxlKSksICJfIiwgU3lzLkRhdGUoKSwgIi5wbmciKQ0KICAjIGdnc2F2ZShwbG90X2ZpbGVuYW1lLCBwbG90ID0gcmVzdWx0JHBsb3QsIHdpZHRoID0gMTAsIGhlaWdodCA9IDcpDQogIA0KICAjIFNhdmUgdGhlIHRhYmxlDQogICMgdGFibGVfZmlsZW5hbWUgPC0gcGFzdGUwKCJ0YWJsZXMvYXZnXzFybV9sYXN0XzJ3a19vbl8iLCB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIHBsb3RfdGl0bGUpKSwgIl8iLCBTeXMuRGF0ZSgpLCAiLmNzdiIpDQogICMgd3JpdGUuY3N2KHJlc3VsdCR0YWJsZV9kYXRhLCBmaWxlID0gdGFibGVfZmlsZW5hbWUsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KfQ0KDQpgYGANCg0KIyMgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKEFUSCkNCg0KYGBge3IgaGlnaGVzdF8xcm1fYWxsX3RpbWVfb25fc3RhbmRhcmRzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCg0KIyBFbnN1cmUgdGhlIG5lY2Vzc2FyeSBsaWJyYXJpZXMgYXJlIGxvYWRlZA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KIyBGdW5jdGlvbiB0byBmaW5kIGNhdGVnb3J5IGxldmVsIGZvciBBVEgNCmZpbmRfY2F0ZWdvcnlfbGV2ZWxfYXRoIDwtIGZ1bmN0aW9uKHdlaWdodCwgYncsIHN0YW5kYXJkc190YWJsZSkgew0KICBzdGFuZGFyZHMgPC0gc3RhbmRhcmRzX3RhYmxlc1tbc3RhbmRhcmRzX3RhYmxlXV0NCiAgaWYgKGlzLm51bGwoc3RhbmRhcmRzKSkgew0KICAgIHN0b3AoIlN0YW5kYXJkcyB0YWJsZSBub3QgZm91bmQuIikNCiAgfQ0KICANCiAgcm91bmRlZF9idyA8LSBzdGFuZGFyZHMgJT4lIGZpbHRlcihgQm9keXdlaWdodGAgPj0gYncpICU+JSBzbGljZSgxKSAlPiUgcHVsbChgQm9keXdlaWdodGApDQogIGNhdGVnb3JpZXMgPC0gc3RhbmRhcmRzICU+JSBmaWx0ZXIoYEJvZHl3ZWlnaHRgID09IHJvdW5kZWRfYncpDQogIA0KICBjYXRlZ29yeSA8LSBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJYCwgIkJlbG93IENhdC4gSSIsDQogICAgICAgICAgICAgICBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJSWAsICJDYXQuIEkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSUlJYCwgIkNhdC4gSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSVZgLCAiQ2F0LiBJSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgVmAsICJDYXQuIElWIiwgIkNhdC4gViIpKSkpKQ0KICByZXR1cm4oY2F0ZWdvcnkpDQp9DQoNCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gYWRkIGRhdGEgcG9pbnRzIHRvIGV4aXN0aW5nIHBsb3RzIGFuZCBnZW5lcmF0ZSBhIHRhYmxlIGZvciBBVEgNCmFkZF9ib2R5d2VpZ2h0X2FuZF8xcm1fdG9fcGxvdF9hdGggPC0gZnVuY3Rpb24oZXhpc3RpbmdfcGxvdCwgcGVyZm9ybWFuY2VfZGF0YSwgdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBzdGFuZGFyZHNfdGFibGUpIHsNCiAgIyBGaWx0ZXIgYW5kIGpvaW4gdGhlIGRhdGENCiAgY29tYmluZWRfZGF0YSA8LSBwZXJmb3JtYW5jZV9kYXRhICU+JQ0KICAgIGlubmVyX2pvaW4odGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBieSA9ICJOYW1lIikgJT4lDQogICAgbXV0YXRlKGAxUk0gQVRIIChsYnMpYCA9IGFzLm51bWVyaWMoYEhpZ2hlc3QgMVJNIEFsbCBUaW1lIChsYnMpYCkpICU+JQ0KICAgIGZpbHRlcighaXMubmEoYDFSTSBBVEggKGxicylgKSAmIGAxUk0gQVRIIChsYnMpYCAhPSAiTm8gZGF0YSBhdmFpbGFibGUiKSAlPiUNCiAgICBtdXRhdGUoQ2F0ZWdvcnlfTGV2ZWxfQVRIID0gbWFwcGx5KGZpbmRfY2F0ZWdvcnlfbGV2ZWxfYXRoLCBgMVJNIEFUSCAobGJzKWAsIGBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2tgLCBNb3JlQXJncyA9IGxpc3Qoc3RhbmRhcmRzX3RhYmxlID0gc3RhbmRhcmRzX3RhYmxlKSkpDQoNCiAgIyBBZGQgcG9pbnRzIHRvIHRoZSBleGlzdGluZyBwbG90DQogIHVwZGF0ZWRfcGxvdCA8LSBleGlzdGluZ19wbG90ICsNCiAgICBnZW9tX3BvaW50KGRhdGEgPSBjb21iaW5lZF9kYXRhLCBhZXMoeCA9IGBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2tgLCB5ID0gYDFSTSBBVEggKGxicylgLCBjb2xvciA9IE5hbWUsIGZpbGwgPSBOYW1lKSwgDQogICAgICAgICAgICAgICBzaXplID0gNCwgc2hhcGUgPSAyNCwgY29sb3IgPSAiYmxhY2siKSArDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX3BhbGV0dGUpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9wYWxldHRlKSArDQogICAgbGFicyhjb2xvciA9ICJOYW1lIiwgZmlsbCA9ICJOYW1lIikgKw0KICAgIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksICMgRGVjcmVhc2UgbGVnZW5kIHRleHQgc2l6ZQ0KICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLCAjIERlY3JlYXNlIGxlZ2VuZCB0aXRsZSBzaXplDQogICAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjUsICJjbSIpKSAjIERlY3JlYXNlIGxlZ2VuZCBrZXkgc2l6ZQ0KDQogICMgQ3JlYXRlIGEgdGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbHVtbnMNCiAgdGFibGVfZGF0YSA8LSBjb21iaW5lZF9kYXRhICU+JQ0KICAgIHNlbGVjdChOYW1lLCANCiAgICAgICAgICAgYEhpZ2hlc3QgMVJNIEFsbCBUaW1lIChsYnMpYCwgDQogICAgICAgICAgIGBMYXN0IERhdGUgSGlnaGVzdCAxUk0gQWxsIFRpbWVgLCANCiAgICAgICAgICAgYEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXa2AsIA0KICAgICAgICAgICBgRGF0ZSBSYW5nZSAoTGFzdCAyIFdlZWtzKWAsDQogICAgICAgICAgIENhdGVnb3J5X0xldmVsX0FUSCkgJT4lDQogICAgcmVuYW1lKA0KICAgICAgICBgMVJNIEFUSCAobGJzKWAgPSBgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKGxicylgLA0KICAgICAgICBEYXRlID0gYExhc3QgRGF0ZSBIaWdoZXN0IDFSTSBBbGwgVGltZWAsDQogICAgICAgIGBBdmcgQlcgTDJXIChsYnMpYCA9IGBBdmVyYWdlX0JvZHl3ZWlnaHRfTGFzdF8yV2tgLA0KICAgICAgICBgRGF0ZSBSYW5nZWAgPSBgRGF0ZSBSYW5nZSAoTGFzdCAyIFdlZWtzKWAsDQogICAgICAgIENhdGVnb3J5X0xldmVsID0gQ2F0ZWdvcnlfTGV2ZWxfQVRIDQogICAgICAgICkNCg0KICAgIyBVcGRhdGUgdGFibGUgZnVydGhlciB3aXRoIHRoZSBzcGVjaWZpZWQgY29sdW1ucw0KICAgIHRhYmxlX2RhdGEgPC0gdGFibGVfZGF0YSAlPiUNCiAgICAgIHNlbGVjdChOYW1lLCANCiAgICAgICAgICAgICBgMVJNIEFUSCAobGJzKWAsIA0KICAgICAgICAgICAgICMgRGF0ZSwgDQogICAgICAgICAgICAgYEF2ZyBCVyBMMlcgKGxicylgLCANCiAgICAgICAgICAgICBDYXRlZ29yeV9MZXZlbA0KICAgICAgICAgICAgICMgRGF0ZV9SYW5nZQ0KICAgICAgICAgICAgICkNCiAgDQogICMgU3Vic3RpdHV0ZSB1bmRlcnNjb3JlcyB3aXRoIHNwYWNlcyBpbiBjb2x1bW4gbmFtZXMNCiAgY29sbmFtZXModGFibGVfZGF0YSkgPC0gZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGVfZGF0YSkpDQogIA0KICAjIFByaW50IHRoZSBjb21iaW5lZCB0YWJsZSB1c2luZyBrbml0cjo6a2FibGUNCiAgbnVtX2NvbHMgPC0gbmNvbCh0YWJsZV9kYXRhKQ0KICB0YWJsZV9odG1sIDwtIGthYmxlKHRhYmxlX2RhdGEsIGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRkFMU0UsIGFsaWduID0gJ2wnKSAlPiUNCiAgICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUNCiAgICBjb2x1bW5fc3BlYygxOm51bV9jb2xzLCB3aWR0aCA9IHBhc3RlMCgxMDAgLyBudW1fY29scywgIiUiKSwgZXh0cmFfY3NzID0gInRleHQtYWxpZ246IGxlZnQ7IikNCg0KICByZXR1cm4obGlzdChwbG90ID0gdXBkYXRlZF9wbG90LCB0YWJsZSA9IHRhYmxlX2h0bWwsIHRhYmxlX2RhdGEgPSB0YWJsZV9kYXRhKSkNCn0NCg0KIyBSZXRyaWV2ZSBleGlzdGluZyBwbG90cyBhbmQgdGl0bGVzDQpleGlzdGluZ19wbG90cyA8LSBwbG90c19saXN0X3N0cmVuZ3RoX3N0YW5kYXJkc19tYXJrX3JpcHBldG9lDQpwbG90X3RpdGxlcyA8LSBuYW1lcyhleGlzdGluZ19wbG90cykNCg0KIyBNYXAgcGxvdCB0aXRsZXMgdG8gc3RhbmRhcmRzIHRhYmxlIG5hbWVzDQpwbG90X3RvX3N0YW5kYXJkc190YWJsZSA8LSBsaXN0KA0KICAiTWFsZSBCZW5jaCBQcmVzcyBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIgPSAibWFsZV9iZW5jaF9wcmVzc19zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSIsDQogICJNYWxlIERlYWRsaWZ0IFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiA9ICJtYWxlX2RlYWRsaWZ0X3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiwNCiAgIk1hbGUgUHJlc3MgU3RkIDFSTSBCeSBCb2R5d2VpZ2h0IE1hcmsgUmlwcGV0b2UiID0gIm1hbGVfcHJlc3Nfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiLA0KICAiTWFsZSBTcXVhdCBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIgPSAibWFsZV9zcXVhdF9zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSINCikNCg0KIyBJdGVyYXRlIHRocm91Z2ggZWFjaCBzdGFuZGFyZCBhbmQgYWRkIGRhdGEgcG9pbnRzIHRvIHRoZSBleGlzdGluZyBwbG90cyBmb3IgQVRIDQpmb3IgKHBsb3RfdGl0bGUgaW4gcGxvdF90aXRsZXMpIHsNCiAgIyBGaWx0ZXIgcGVyZm9ybWFuY2UgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc3RhbmRhcmQNCiAgcGVyZm9ybWFuY2VfZGF0YSA8LSBmaWx0ZXIocGVyZm9ybWFuY2Vfb25fbWFya19yaXBwZXRvZV9zdGFuZGFyZHMsIGBTdHJlbmd0aCBTdGFuZGFyZGAgPT0gcGxvdF90aXRsZSkNCiAgDQogICMgR2V0IHRoZSBleGlzdGluZyBwbG90DQogIGV4aXN0aW5nX3Bsb3QgPC0gZXhpc3RpbmdfcGxvdHNbW3Bsb3RfdGl0bGVdXQ0KICANCiAgIyBHZXQgdGhlIGNvcnJlc3BvbmRpbmcgc3RhbmRhcmRzIHRhYmxlIG5hbWUNCiAgc3RhbmRhcmRzX3RhYmxlIDwtIHBsb3RfdG9fc3RhbmRhcmRzX3RhYmxlW1twbG90X3RpdGxlXV0NCiAgDQogICMgQWRkIGJvZHl3ZWlnaHQgYW5kIDFSTSBkYXRhIHBvaW50cyB0byB0aGUgZXhpc3RpbmcgcGxvdCBmb3IgQVRIDQogIHJlc3VsdCA8LSBhZGRfYm9keXdlaWdodF9hbmRfMXJtX3RvX3Bsb3RfYXRoKGV4aXN0aW5nX3Bsb3QsIHBlcmZvcm1hbmNlX2RhdGEsIHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgc3RhbmRhcmRzX3RhYmxlKQ0KDQogIGNsZWFuX3RpdGxlIDwtIChzdWIoIiBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIsICIgU3RhbmRhcmRzLCAxUk0gQVRIIiwgcGxvdF90aXRsZSkpDQogIGNhdChwYXN0ZTAoIlxuXG48aDQ+IiwgY2xlYW5fdGl0bGUsICI8L2g0PlxuXG4iKSkNCiAgDQogICMgUHJpbnQgdGhlIHVwZGF0ZWQgcGxvdA0KICBwcmludChyZXN1bHQkcGxvdCkNCiAgDQogICMgUHJpbnQgdGhlIHRhYmxlDQogIHByaW50KHJlc3VsdCR0YWJsZSkNCiAgDQogICMgU2F2ZSB0aGUgcGxvdA0KICAjIHBsb3RfZmlsZW5hbWUgPC0gcGFzdGUwKCJwbG90cy9oaWdoZXN0XzFybV9hbGxfdGltZV9vbl8iLCB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIHBsb3RfdGl0bGUpKSwgIl8iLCBTeXMuRGF0ZSgpLCAiLnBuZyIpDQogICMgZ2dzYXZlKHBsb3RfZmlsZW5hbWUsIHBsb3QgPSByZXN1bHQkcGxvdCwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNykNCiAgDQogICMgU2F2ZSB0aGUgdGFibGUNCiAgIyB0YWJsZV9maWxlbmFtZSA8LSBwYXN0ZTAoInRhYmxlcy9oaWdoZXN0XzFybV9hbGxfdGltZV9vbl8iLCB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIHBsb3RfdGl0bGUpKSwgIl8iLCBTeXMuRGF0ZSgpLCAiLmNzdiIpDQogICMgd3JpdGUuY3N2KHJlc3VsdCR0YWJsZV9kYXRhLCBmaWxlID0gdGFibGVfZmlsZW5hbWUsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KfQ0KDQpgYGANCg0KIyMgTDJXICYgQVRIIC0gU2lkZSBCeSBTaWRlIA0KUGVyZm9ybWFuY2UgbWVhc3VyZXMgZm9yIEF2ZXJhZ2UgMVJNIExhc3QgMiBXZWVrcyAoTDJXKSBhbmQgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKEFUSCkgYXJlIG1lcmdlZCBpbnRvIG9uZSBwbG90IGZvciBzaWRlLWJ5LXNpZGUgY29tcGFyaXNvbi4gVGhpcyB2aXN1YWxpemF0aW9uIGhlbHBzIGluZGl2aWR1YWxzIHJlYWNoIGhpZ2hlciBwZXJmb3JtYW5jZSBieSBoaWdobGlnaHRpbmcgcmVjZW50IHBlcmZvcm1hbmNlIGFuZCBpZGVudGlmeWluZyBwZXJzb25hbCBiZXN0cywgdGhlcmVieSBmb3N0ZXJpbmcgaGVhbHRoeSBjb21wZXRpdGlvbiBhbmQgbW90aXZhdGluZyBjb25zaXN0ZW50IHByb2dyZXNzLg0KDQpUaGlzIGNvbWJpbmVkIHBsb3QgYWxsb3dzIGZvciBhbiBlYXN5IGNvbXBhcmlzb24gb2YgcmVjZW50IHBlcmZvcm1hbmNlIGFuZCBhbGwtdGltZSBiZXN0cywgcHJvdmlkaW5nIGEgY2xlYXIgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIGVhY2ggaW5kaXZpZHVhbCdzIHByb2dyZXNzIGFuZCBwb3RlbnRpYWwuIEJ5IHVuZGVyc3RhbmRpbmcgdGhlc2UgbWV0cmljcywgaW5kaXZpZHVhbHMgY2FuIGlkZW50aWZ5IGFyZWFzIGZvciBpbXByb3ZlbWVudCBhbmQgc2V0IGdvYWxzIHRvIHN1cnBhc3MgdGhlaXIgcGVyc29uYWwgYmVzdHMsIHVsdGltYXRlbHkgbGV2ZWxpbmcgdXAgdGhlaXIgcGVyZm9ybWFuY2UuDQoNCk5vdGU6IEVhY2ggZXhlcmNpc2UgcGxvdCBpcyBmb2xsb3dlZCBieSBpdHMgdGFibGUgZm9yIHJlZmVyZW5jZS4gDQoNClVzaW5nIEF2ZXJhZ2UgMVJNIExhc3QgMiBXZWVrcyAoTDJXKSBmb3IgdHJhaW5pbmcgcHVycG9zZXMgaXMgbW9yZSBlZmZlY3RpdmUgdGhhbiBjb21wYXJpbmcgSGlnaGVzdCAxUk0gTGFzdCAyIFdlZWtzIHRvIDFSTSBBbGwgVGltZSBIaWdoIChBVEgpLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGF2ZXJhZ2UgMVJNIG92ZXIgdGhlIGxhc3QgdHdvIHdlZWtzIHByb3ZpZGVzIGEgbW9yZSBjb25zaXN0ZW50IGFuZCByZWFsaXN0aWMgbWVhc3VyZSBvZiBjdXJyZW50IHN0cmVuZ3RoIGxldmVscywgd2hpY2ggY2FuIGJlIGluZmx1ZW5jZWQgYnkgdmFyaW91cyBmYWN0b3JzIHN1Y2ggYXMgZmF0aWd1ZSwgcmVjb3ZlcnksIGFuZCBkYWlseSBwZXJmb3JtYW5jZSB2YXJpYWJpbGl0eS4gUmVseWluZyBzb2xlbHkgb24gdGhlIGhpZ2hlc3QgMVJNIG1heSBub3QgYWNjdXJhdGVseSByZWZsZWN0IHRydWUgcGVyZm9ybWFuY2UgY2FwYWJpbGl0eSBhbmQgY2FuIGxlYWQgdG8gdW5yZWFsaXN0aWMgdHJhaW5pbmcgbG9hZHMgYW5kIHBvdGVudGlhbCBvdmVydHJhaW5pbmcuIA0KDQpgYGB7ciBhdmdfMXJtX19sMndfYW5kX2F0aF8xcm1fb25fc3RhbmRhcmRzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCg0KIyBFbnN1cmUgdGhlIG5lY2Vzc2FyeSBsaWJyYXJpZXMgYXJlIGxvYWRlZA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KIyBEZWZpbmUgY29sb3IgcGFsZXR0ZXMNCmNvbG9yX3BhbGV0dGVfbDJ3IDwtIGMoIkFsZXggLSBBdmcgTDJXIiA9ICIjMWY3N2I0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICJLZW5kcmljayAtIEF2ZyBMMlciID0gIiNmZjdmMGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIkx1Y2llbiAtIEF2ZyBMMlciID0gIiM5NDY3YmQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIkpvc2ggLSBBdmcgTDJXIiA9ICIjOGM1NjRiIikNCmNvbG9yX3BhbGV0dGVfYXRoIDwtIGMoIkFsZXggLSBBVEgiID0gIiMyY2EwMmMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIktlbmRyaWNrIC0gQVRIIiA9ICIjZDYyNzI4IiwgDQogICAgICAgICAgICAgICAgICAgICAgICJMdWNpZW4gLSBBVEgiID0gIiNlMzc3YzIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIkpvc2ggLSBBVEgiID0gIiM3ZjdmN2YiKQ0KDQojIExvYWQgdGhlIHN0YW5kYXJkcyB0YWJsZXMgYW5kIHN0b3JlIHRoZW0gaW4gYSBsaXN0DQpzdGFuZGFyZHNfdGFibGVzIDwtIGxpc3QoDQogICJtYWxlX2JlbmNoX3ByZXNzX3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiA9IG1hbGVfYmVuY2hfcHJlc3Nfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UsDQogICJtYWxlX2RlYWRsaWZ0X3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiA9IG1hbGVfZGVhZGxpZnRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UsDQogICJtYWxlX3ByZXNzX3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiA9IG1hbGVfcHJlc3Nfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UsDQogICJtYWxlX3NxdWF0X3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiA9IG1hbGVfc3F1YXRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UNCikNCg0KIyBGdW5jdGlvbiB0byBmaW5kIGNhdGVnb3J5IGxldmVsDQpmaW5kX2NhdGVnb3J5X2xldmVsIDwtIGZ1bmN0aW9uKHdlaWdodCwgYncsIHN0YW5kYXJkc190YWJsZSkgew0KICBzdGFuZGFyZHMgPC0gc3RhbmRhcmRzX3RhYmxlc1tbc3RhbmRhcmRzX3RhYmxlXV0NCiAgaWYgKGlzLm51bGwoc3RhbmRhcmRzKSkgew0KICAgIHN0b3AoIlN0YW5kYXJkcyB0YWJsZSBub3QgZm91bmQuIikNCiAgfQ0KICANCiAgcm91bmRlZF9idyA8LSBzdGFuZGFyZHMgJT4lIGZpbHRlcihgQm9keXdlaWdodGAgPj0gYncpICU+JSBzbGljZSgxKSAlPiUgcHVsbChgQm9keXdlaWdodGApDQogIGNhdGVnb3JpZXMgPC0gc3RhbmRhcmRzICU+JSBmaWx0ZXIoYEJvZHl3ZWlnaHRgID09IHJvdW5kZWRfYncpDQogIA0KICBjYXRlZ29yeSA8LSBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJYCwgIkJlbG93IENhdC4gSSIsDQogICAgICAgICAgICAgICBpZmVsc2Uod2VpZ2h0IDwgY2F0ZWdvcmllcyRgQ2F0ICBJSWAsICJDYXQuIEkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSUlJYCwgIkNhdC4gSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgSVZgLCAiQ2F0LiBJSUkiLA0KICAgICAgICAgICAgICAgaWZlbHNlKHdlaWdodCA8IGNhdGVnb3JpZXMkYENhdCAgVmAsICJDYXQuIElWIiwgIkNhdC4gViIpKSkpKQ0KICByZXR1cm4oY2F0ZWdvcnkpDQp9DQoNCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gYWRkIGRhdGEgcG9pbnRzIHRvIGV4aXN0aW5nIHBsb3RzDQphZGRfYm9keXdlaWdodF9hbmRfMXJtX3RvX3Bsb3QgPC0gZnVuY3Rpb24oZXhpc3RpbmdfcGxvdCwgcGVyZm9ybWFuY2VfZGF0YSwgdGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBzdGFuZGFyZHNfdGFibGUpIHsNCiAgIyBGaWx0ZXIgYW5kIGpvaW4gdGhlIGRhdGENCiAgY29tYmluZWRfZGF0YSA8LSBwZXJmb3JtYW5jZV9kYXRhICU+JQ0KICAgIGlubmVyX2pvaW4odGFibGVfYXZnX2JvZHl3ZWlnaHRzX2xhc3RfMndrLCBieSA9ICJOYW1lIikgJT4lDQogICAgbXV0YXRlKGBBdmVyYWdlIDFSTSAobGJzKWAgPSBhcy5udW1lcmljKGBBdmVyYWdlIDFSTSAobGJzKWApLA0KICAgICAgICAgICBgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKGxicylgID0gYXMubnVtZXJpYyhgSGlnaGVzdCAxUk0gQWxsIFRpbWUgKGxicylgKSkgJT4lDQogICAgZmlsdGVyKCFpcy5uYShgQXZlcmFnZSAxUk0gKGxicylgKSAmIGBBdmVyYWdlIDFSTSAobGJzKWAgIT0gIk5vIGRhdGEgYXZhaWxhYmxlIikgJT4lDQogICAgbXV0YXRlKE5hbWVfQXZnX0wyVyA9IHBhc3RlKE5hbWUsICItIEF2ZyBMMlciKSwgDQogICAgICAgICAgIE5hbWVfQVRIID0gcGFzdGUoTmFtZSwgIi0gQVRIIiksDQogICAgICAgICAgIENhdGVnb3J5X0xldmVsX0wyVyA9IG1hcHBseShmaW5kX2NhdGVnb3J5X2xldmVsLCBgQXZlcmFnZSAxUk0gKGxicylgLCBgQXZlcmFnZV9Cb2R5d2VpZ2h0X0xhc3RfMldrYCwgTW9yZUFyZ3MgPSBsaXN0KHN0YW5kYXJkc190YWJsZSA9IHN0YW5kYXJkc190YWJsZSkpLA0KICAgICAgICAgICBDYXRlZ29yeV9MZXZlbF9BVEggPSBtYXBwbHkoZmluZF9jYXRlZ29yeV9sZXZlbCwgYEhpZ2hlc3QgMVJNIEFsbCBUaW1lIChsYnMpYCwgYEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXa2AsIE1vcmVBcmdzID0gbGlzdChzdGFuZGFyZHNfdGFibGUgPSBzdGFuZGFyZHNfdGFibGUpKSkNCg0KICAjIEFkZCBwb2ludHMgdG8gdGhlIGV4aXN0aW5nIHBsb3QNCiAgdXBkYXRlZF9wbG90IDwtIGV4aXN0aW5nX3Bsb3QgKw0KICAgIGdlb21fcG9pbnQoZGF0YSA9IGNvbWJpbmVkX2RhdGEsIGFlcyh4ID0gQXZlcmFnZV9Cb2R5d2VpZ2h0X0xhc3RfMldrLCB5ID0gYEF2ZXJhZ2UgMVJNIChsYnMpYCwgY29sb3IgPSBOYW1lX0F2Z19MMlcsIGZpbGwgPSBOYW1lX0F2Z19MMlcpLCANCiAgICAgICAgICAgICAgIHNpemUgPSA0LCBzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIpICsNCiAgICBnZW9tX3BvaW50KGRhdGEgPSBjb21iaW5lZF9kYXRhLCBhZXMoeCA9IEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXaywgeSA9IGBIaWdoZXN0IDFSTSBBbGwgVGltZSAobGJzKWAsIGNvbG9yID0gTmFtZV9BVEgsIGZpbGwgPSBOYW1lX0FUSCksIA0KICAgICAgICAgICAgICAgc2l6ZSA9IDQsIHNoYXBlID0gMjQsIGNvbG9yID0gImJsYWNrIikgKw0KICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNvbG9yX3BhbGV0dGVfbDJ3LCBjb2xvcl9wYWxldHRlX2F0aCkpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGNvbG9yX3BhbGV0dGVfbDJ3LCBjb2xvcl9wYWxldHRlX2F0aCkpICsNCiAgICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAxKSwgZmlsbCA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDIpKSArDQogICAgbGFicyhjb2xvciA9ICJOYW1lIiwgZmlsbCA9ICJOYW1lIikgKw0KICAgIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksICMgRGVjcmVhc2UgbGVnZW5kIHRleHQgc2l6ZQ0KICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLCAjIERlY3JlYXNlIGxlZ2VuZCB0aXRsZSBzaXplDQogICAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjUsICJjbSIpKSAjIERlY3JlYXNlIGxlZ2VuZCBrZXkgc2l6ZQ0KDQogIA0KICAjIENyZWF0ZSBhIHRhYmxlIHdpdGggdGhlIHNwZWNpZmllZCBjb2x1bW5zDQogIHRhYmxlX2RhdGEgPC0gY29tYmluZWRfZGF0YSAlPiUNCiAgICBzZWxlY3QoTmFtZSwgDQogICAgICAgICAgIGBBdmVyYWdlIDFSTSAobGJzKWAsIA0KICAgICAgICAgICBgRGF0ZSBSYW5nZSAoTGFzdCAyIFdlZWtzKWAsIA0KICAgICAgICAgICBDYXRlZ29yeV9MZXZlbF9MMlcsDQogICAgICAgICAgIGBIaWdoZXN0IDFSTSBBbGwgVGltZSAobGJzKWAsIA0KICAgICAgICAgICBgTGFzdCBEYXRlIEhpZ2hlc3QgMVJNIEFsbCBUaW1lYCwgDQogICAgICAgICAgIENhdGVnb3J5X0xldmVsX0FUSCwNCiAgICAgICAgICAgYEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXa2AsIA0KICAgICAgICAgICBEYXRlX1JhbmdlKSAlPiUNCiAgICByZW5hbWUoDQogICAgICAgIGBEYXRlIFJhbmdlIEwyV2AgPSBgRGF0ZSBSYW5nZSAoTGFzdCAyIFdlZWtzKWAsDQogICAgICAgIGAxUk0gQVRIIChsYnMpYCA9IGBIaWdoZXN0IDFSTSBBbGwgVGltZSAobGJzKWAsDQogICAgICAgIGBEYXRlIEFUSGAgPSBgTGFzdCBEYXRlIEhpZ2hlc3QgMVJNIEFsbCBUaW1lYCwNCiAgICAgICAgYEF2ZyBCVyBMMlcgKGxicylgID0gYEF2ZXJhZ2VfQm9keXdlaWdodF9MYXN0XzJXa2ANCiAgICAgICAgKQ0KICANCiAgIyBVcGRhdGUgdGFibGUgZnVydGhlciB3aXRoIHRoZSBzcGVjaWZpZWQgY29sdW1ucw0KICB0YWJsZV9kYXRhIDwtIHRhYmxlX2RhdGEgJT4lDQogICAgc2VsZWN0KE5hbWUsIA0KICAgICAgICAgICBgQXZlcmFnZSAxUk0gKGxicylgLCANCiAgICAgICAgICAgIyBgRGF0ZSBSYW5nZSBMMldgLCANCiAgICAgICAgICAgQ2F0ZWdvcnlfTGV2ZWxfTDJXLA0KICAgICAgICAgICBgMVJNIEFUSCAobGJzKWAsIA0KICAgICAgICAgICAjIGBEYXRlIEFUSGAsIA0KICAgICAgICAgICBDYXRlZ29yeV9MZXZlbF9BVEgsDQogICAgICAgICAgIGBBdmcgQlcgTDJXIChsYnMpYCANCiAgICAgICAgICAgIyBgRGF0ZV9SYW5nZWANCiAgICAgICAgICAgKQ0KICANCiAgIyBTdWJzdGl0dXRlIHVuZGVyc2NvcmVzIHdpdGggc3BhY2VzIGluIGNvbHVtbiBuYW1lcw0KICBjb2xuYW1lcyh0YWJsZV9kYXRhKSA8LSBnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZV9kYXRhKSkNCg0KICAjIFByaW50IHRoZSBjb21iaW5lZCB0YWJsZSB1c2luZyBrbml0cjo6a2FibGUNCiAgdGFibGVfaHRtbCA8LSBrYWJsZSh0YWJsZV9kYXRhLCBmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEZBTFNFLCBhbGlnbiA9ICdsJykgJT4lDQogICAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSkgJT4lDQogICAgY29sdW1uX3NwZWMoMTpuY29sKHRhYmxlX2RhdGEpLCBleHRyYV9jc3MgPSAidGV4dC1hbGlnbjogbGVmdDsiKQ0KDQogIHJldHVybihsaXN0KHBsb3QgPSB1cGRhdGVkX3Bsb3QsIHRhYmxlID0gdGFibGVfaHRtbCwgdGFibGVfZGF0YSA9IHRhYmxlX2RhdGEpKQ0KfQ0KDQojIFJldHJpZXZlIGV4aXN0aW5nIHBsb3RzIGFuZCB0aXRsZXMNCmV4aXN0aW5nX3Bsb3RzIDwtIHBsb3RzX2xpc3Rfc3RyZW5ndGhfc3RhbmRhcmRzX21hcmtfcmlwcGV0b2UNCnBsb3RfdGl0bGVzIDwtIG5hbWVzKGV4aXN0aW5nX3Bsb3RzKQ0KDQojIE1hcCBwbG90IHRpdGxlcyB0byBzdGFuZGFyZHMgdGFibGUgbmFtZXMNCnBsb3RfdG9fc3RhbmRhcmRzX3RhYmxlIDwtIGxpc3QoDQogICJNYWxlIEJlbmNoIFByZXNzIFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiA9ICJtYWxlX2JlbmNoX3ByZXNzX3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIiwNCiAgIk1hbGUgRGVhZGxpZnQgU3RkIDFSTSBCeSBCb2R5d2VpZ2h0IE1hcmsgUmlwcGV0b2UiID0gIm1hbGVfZGVhZGxpZnRfc3RkXzFybV9ieV9ib2R5d2VpZ2h0X21hcmtfcmlwcGV0b2UiLA0KICAiTWFsZSBQcmVzcyBTdGQgMVJNIEJ5IEJvZHl3ZWlnaHQgTWFyayBSaXBwZXRvZSIgPSAibWFsZV9wcmVzc19zdGRfMXJtX2J5X2JvZHl3ZWlnaHRfbWFya19yaXBwZXRvZSIsDQogICJNYWxlIFNxdWF0IFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiA9ICJtYWxlX3NxdWF0X3N0ZF8xcm1fYnlfYm9keXdlaWdodF9tYXJrX3JpcHBldG9lIg0KKQ0KDQojIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIHN0YW5kYXJkIGFuZCBhZGQgZGF0YSBwb2ludHMgdG8gdGhlIGV4aXN0aW5nIHBsb3RzDQpmb3IgKHBsb3RfdGl0bGUgaW4gcGxvdF90aXRsZXMpIHsNCiAgIyBGaWx0ZXIgcGVyZm9ybWFuY2UgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc3RhbmRhcmQNCiAgcGVyZm9ybWFuY2VfZGF0YSA8LSBmaWx0ZXIocGVyZm9ybWFuY2Vfb25fbWFya19yaXBwZXRvZV9zdGFuZGFyZHMsIGBTdHJlbmd0aCBTdGFuZGFyZGAgPT0gcGxvdF90aXRsZSkNCiAgDQogICMgR2V0IHRoZSBleGlzdGluZyBwbG90DQogIGV4aXN0aW5nX3Bsb3QgPC0gZXhpc3RpbmdfcGxvdHNbW3Bsb3RfdGl0bGVdXQ0KICANCiAgIyBHZXQgdGhlIGNvcnJlc3BvbmRpbmcgc3RhbmRhcmRzIHRhYmxlIG5hbWUNCiAgc3RhbmRhcmRzX3RhYmxlIDwtIHBsb3RfdG9fc3RhbmRhcmRzX3RhYmxlW1twbG90X3RpdGxlXV0NCiAgDQogICMgQWRkIGJvZHl3ZWlnaHQgYW5kIDFSTSBkYXRhIHBvaW50cyB0byB0aGUgZXhpc3RpbmcgcGxvdA0KICByZXN1bHQgPC0gYWRkX2JvZHl3ZWlnaHRfYW5kXzFybV90b19wbG90KGV4aXN0aW5nX3Bsb3QsIHBlcmZvcm1hbmNlX2RhdGEsIHRhYmxlX2F2Z19ib2R5d2VpZ2h0c19sYXN0XzJ3aywgc3RhbmRhcmRzX3RhYmxlKQ0KICANCiAgY2xlYW5fdGl0bGUgPC0gKHN1YigiIFN0ZCAxUk0gQnkgQm9keXdlaWdodCBNYXJrIFJpcHBldG9lIiwgIiBTdGFuZGFyZHMsIEF2ZyAxUk0gTDJXICYgMVJNIEFUSCIsIHBsb3RfdGl0bGUpKQ0KICBjYXQocGFzdGUwKCJcblxuPGg0PiIsIGNsZWFuX3RpdGxlLCAiPC9oND5cblxuIikpDQoNCiAgIyBQcmludCB0aGUgdXBkYXRlZCBwbG90DQogIHByaW50KHJlc3VsdCRwbG90KQ0KICANCiAgIyBQcmludCB0aGUgdGFibGUNCiAgcHJpbnQocmVzdWx0JHRhYmxlKQ0KICANCiAgIyBTYXZlIHRoZSBwbG90DQogIHBsb3RfZmlsZW5hbWUgPC0gcGFzdGUwKCJwbG90cy9hdmdfMXJtX2wyd19hbmRfYXRoXzFybV9vbl9fIiwgdG9sb3dlcihnc3ViKCIgIiwgIl8iLCBwbG90X3RpdGxlKSksICJfIiwgU3lzLkRhdGUoKSwgIi5wbmciKQ0KICBnZ3NhdmUocGxvdF9maWxlbmFtZSwgcGxvdCA9IHJlc3VsdCRwbG90LCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA3KQ0KICANCiAgIyBTYXZlIHRoZSB0YWJsZSBkYXRhIHRvIENTVg0KICB0YWJsZV9maWxlbmFtZSA8LSBwYXN0ZTAoInRhYmxlcy9hdmdfMXJtX2wyd19hbmRfYXRoXzFybV9vbl8iLCB0b2xvd2VyKGdzdWIoIiAiLCAiXyIsIHBsb3RfdGl0bGUpKSwgIl8iLCBTeXMuRGF0ZSgpLCAiLmNzdiIpDQogIHdyaXRlLmNzdihyZXN1bHQkdGFibGVfZGF0YSwgZmlsZSA9IHRhYmxlX2ZpbGVuYW1lLCByb3cubmFtZXMgPSBGQUxTRSkNCn0NCg0KYGBgDQoNCg0KDQo8IS0tICMgVEVTVCAgDQoNCmBgYHtyIHRlc3RfcGVyZm9ybWFuY2VfYW5kX2JvZHl3ZWlnaHRfb3Zlcl90aW1lLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgZXZhbD1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQoNCg0KIyBFbnN1cmUgdGhlIG5lY2Vzc2FyeSBsaWJyYXJpZXMgYXJlIGxvYWRlZA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCiMgUmVuYW1lIHRoZSBjb2x1bW4gaW4gdml0YWxzX2RhdGFfd2VpZ2h0X2xicyBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBsZWF2ZSB1bmNoYW5nZWQNCnZpdGFsc19kYXRhX3dlaWdodF9sYnMgPC0gdml0YWxzX2RhdGFfd2VpZ2h0X2xicyAlPiUNCiAgcmVuYW1lX3dpdGgofmlmZWxzZSguID09ICJXZWlnaHRfbGJzIiwgIkJvZHl3ZWlnaHQgKGxicykiLCAuKSkNCg0KIyBGaWx0ZXIgYm9keXdlaWdodCBkYXRhIGZvciBLZW5kcmljayBhbmQgY2FsY3VsYXRlIERhaWx5IEF2ZXJhZ2UgQm9keXdlaWdodA0Ka2VuZHJpY2tfYm9keXdlaWdodF9kYXRhIDwtIHZpdGFsc19kYXRhX3dlaWdodF9sYnMgJT4lDQogIGZpbHRlcihOYW1lID09ICJLZW5kcmljayIpICU+JQ0KICBncm91cF9ieShEYXRlKSAlPiUNCiAgc3VtbWFyaXplKERhaWx5X0F2Z19CVyA9IG1lYW4oYEJvZHl3ZWlnaHQgKGxicylgLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgdW5ncm91cCgpDQoNCiMgUHJpbnQgdW5pcXVlIHZhbHVlcyB0byBkZWJ1ZyBjcml0ZXJpYSBtYXRjaGluZw0KcHJpbnQoIlVuaXF1ZSB2YWx1ZXMgaW4gUG9zaXRpb24gY29sdW1uOiIpDQpwcmludCh1bmlxdWUoa2VuZHJpY2tfcGVyZm9ybWFuY2VfZGF0YSRQb3NpdGlvbikpDQoNCnByaW50KCJVbmlxdWUgdmFsdWVzIGluIEluc3RydW1lbnQgY29sdW1uOiIpDQpwcmludCh1bmlxdWUoa2VuZHJpY2tfcGVyZm9ybWFuY2VfZGF0YSRJbnN0cnVtZW50KSkNCg0KcHJpbnQoIlVuaXF1ZSB2YWx1ZXMgaW4gQWN0aXZpdHkgY29sdW1uOiIpDQpwcmludCh1bmlxdWUoa2VuZHJpY2tfcGVyZm9ybWFuY2VfZGF0YSRBY3Rpdml0eSkpDQoNCiMgRGVmaW5lIEV4ZXJjaXNlIENyaXRlcmlhIChhZGp1c3RlZCBiYXNlZCBvbiB0aGUgdW5pcXVlIHZhbHVlcyBpbiB0aGUgZGF0YXNldCkNCmV4ZXJjaXNlX2NyaXRlcmlhIDwtIGxpc3QoDQogICJCZW5jaCBQcmVzcyIgPSBsaXN0KFBvc2l0aW9uID0gIkZsYXQgQmVuY2giLCBJbnN0cnVtZW50ID0gIkJhcmJlbGwiLCBBY3Rpdml0eSA9ICJDaGVzdCBQcmVzcyIpLA0KICAiUHJlc3MiID0gbGlzdChJbnN0cnVtZW50ID0gIkJhcmJlbGwiLCBBY3Rpdml0eSA9ICJPdmVyaGVhZCBTaG91bGRlciBQcmVzcyIpLA0KICAiU3F1YXQiID0gbGlzdChJbnN0cnVtZW50ID0gIkJhcmJlbGwiLCBBY3Rpdml0eSA9ICJTcXVhdCIpLA0KICAiRGVhZGxpZnQiID0gbGlzdChJbnN0cnVtZW50ID0gIkJhcmJlbGwiLCBBY3Rpdml0eSA9ICJEZWFkbGlmdCIpDQopDQoNCiMgRmlsdGVyIHBlcmZvcm1hbmNlIGRhdGEgZm9yIEtlbmRyaWNrDQprZW5kcmlja19wZXJmb3JtYW5jZV9kYXRhIDwtIHJhd19kYXRhICU+JQ0KICBmaWx0ZXIoTmFtZSA9PSAiS2VuZHJpY2siKQ0KDQojIEZ1bmN0aW9uIHRvIGFwcGx5IHRoZSBjcml0ZXJpYSBmaWx0ZXINCmFwcGx5X2NyaXRlcmlhX2ZpbHRlciA8LSBmdW5jdGlvbihkYXRhLCBjcml0ZXJpYSkgew0KICBpZiAoIWlzLm51bGwoY3JpdGVyaWEkUG9zaXRpb24pKSB7DQogICAgZGF0YSA8LSBkYXRhICU+JSBmaWx0ZXIoUG9zaXRpb24gPT0gY3JpdGVyaWEkUG9zaXRpb24pDQogIH0NCiAgaWYgKCFpcy5udWxsKGNyaXRlcmlhJEluc3RydW1lbnQpKSB7DQogICAgZGF0YSA8LSBkYXRhICU+JSBmaWx0ZXIoSW5zdHJ1bWVudCA9PSBjcml0ZXJpYSRJbnN0cnVtZW50KQ0KICB9DQogIGlmICghaXMubnVsbChjcml0ZXJpYSRBY3Rpdml0eSkpIHsNCiAgICBkYXRhIDwtIGRhdGEgJT4lIGZpbHRlcihBY3Rpdml0eSA9PSBjcml0ZXJpYSRBY3Rpdml0eSkNCiAgfQ0KICByZXR1cm4oZGF0YSkNCn0NCg0KIyBMb29wIHRocm91Z2ggZWFjaCBleGVyY2lzZSBjcml0ZXJpYQ0KZm9yIChleGVyY2lzZSBpbiBuYW1lcyhleGVyY2lzZV9jcml0ZXJpYSkpIHsNCiAgY3JpdGVyaWEgPC0gZXhlcmNpc2VfY3JpdGVyaWFbW2V4ZXJjaXNlXV0NCiAgDQogICMgUHJpbnQgY3JpdGVyaWEgZm9yIGRlYnVnZ2luZw0KICBwcmludChwYXN0ZSgiQXBwbHlpbmcgY3JpdGVyaWEgZm9yIiwgZXhlcmNpc2UpKQ0KICBwcmludChjcml0ZXJpYSkNCiAgDQogICMgQXBwbHkgY3JpdGVyaWEgZmlsdGVyIHRvIHBlcmZvcm1hbmNlIGRhdGENCiAgZmlsdGVyZWRfcGVyZm9ybWFuY2VfZGF0YSA8LSBhcHBseV9jcml0ZXJpYV9maWx0ZXIoa2VuZHJpY2tfcGVyZm9ybWFuY2VfZGF0YSwgY3JpdGVyaWEpDQogIA0KICAjIFByaW50IHN1bW1hcnkgb2YgZmlsdGVyZWRfcGVyZm9ybWFuY2VfZGF0YSBmb3IgZGVidWdnaW5nDQogIHByaW50KHBhc3RlKCJGaWx0ZXJlZCBkYXRhIGZvciIsIGV4ZXJjaXNlKSkNCiAgcHJpbnQoc3VtbWFyeShmaWx0ZXJlZF9wZXJmb3JtYW5jZV9kYXRhKSkNCiAgDQogICMgQ2FsY3VsYXRlIERhaWx5IEF2ZXJhZ2UgMVJNIGZvciB0aGUgY3VycmVudCBjcml0ZXJpYQ0KICBkYWlseV9hdmdfMXJtX2RhdGEgPC0gZmlsdGVyZWRfcGVyZm9ybWFuY2VfZGF0YSAlPiUNCiAgICBncm91cF9ieShEYXRlKSAlPiUNCiAgICBzdW1tYXJpemUoRGFpbHlfQXZnXzFSTSA9IG1lYW4oYDFSTV9DYWxjdWxhdGVkX1dlaWdodGAsIG5hLnJtID0gVFJVRSkpICU+JQ0KICAgIHVuZ3JvdXAoKQ0KICANCiAgIyBQcmludCBzdW1tYXJ5IG9mIGRhaWx5X2F2Z18xcm1fZGF0YQ0KICBwcmludChwYXN0ZSgiU3VtbWFyeSBmb3IiLCBleGVyY2lzZSkpDQogIHByaW50KHN1bW1hcnkoZGFpbHlfYXZnXzFybV9kYXRhKSkNCiAgDQogICMgTWVyZ2UgdGhlIGRhdGFzZXRzIG9uIERhdGUNCiAga2VuZHJpY2tfY29tYmluZWRfZGF0YSA8LSBkYWlseV9hdmdfMXJtX2RhdGEgJT4lDQogICAgZnVsbF9qb2luKGtlbmRyaWNrX2JvZHl3ZWlnaHRfZGF0YSwgYnkgPSAiRGF0ZSIpDQogIA0KICAjIEhhbmRsZSBtaXNzaW5nIGRhdGEgYnkgZmlsbGluZyBnYXBzDQogIGtlbmRyaWNrX2NvbWJpbmVkX2RhdGEgPC0ga2VuZHJpY2tfY29tYmluZWRfZGF0YSAlPiUNCiAgICBhcnJhbmdlKERhdGUpICU+JQ0KICAgIHRpZHlyOjpmaWxsKERhaWx5X0F2Z18xUk0sIERhaWx5X0F2Z19CVywgLmRpcmVjdGlvbiA9ICJkb3dudXAiKQ0KICANCiAgIyBQbG90IERhaWx5IEF2ZXJhZ2UgMVJNIGFuZCBCb2R5d2VpZ2h0IG92ZXIgdGltZSBmb3IgS2VuZHJpY2sNCiAgcCA8LSBnZ3Bsb3Qoa2VuZHJpY2tfY29tYmluZWRfZGF0YSwgYWVzKHggPSBEYXRlKSkgKw0KICAgIGdlb21fbGluZShhZXMoeSA9IERhaWx5X0F2Z18xUk0sIGNvbG9yID0gIkRhaWx5IEF2ZyAxUk0iKSwgc2l6ZSA9IDEpICsNCiAgICBnZW9tX2xpbmUoYWVzKHkgPSBEYWlseV9BdmdfQlcsIGNvbG9yID0gIkRhaWx5IEF2ZyBCVyIpLCBzaXplID0gMSkgKw0KICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJEYWlseSBBdmcgMVJNIiA9ICJibHVlIiwgIkRhaWx5IEF2ZyBCVyIgPSAicmVkIikpICsNCiAgICBsYWJzKHRpdGxlID0gcGFzdGUoIktlbmRyaWNrJ3MgRGFpbHkgQXZnIDFSTSBhbmQgQm9keXdlaWdodCBPdmVyIFRpbWUgZm9yIiwgZXhlcmNpc2UpLA0KICAgICAgICAgeCA9ICJEYXRlIiwNCiAgICAgICAgIHkgPSAiVmFsdWUiLA0KICAgICAgICAgY29sb3IgPSAiTWV0cmljIikgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgdGhlbWUoDQogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTYpLA0KICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDEsICJjbSIpDQogICAgKQ0KICANCiAgcHJpbnQocCkNCn0NCg0KDQpgYGANCi0tPiANCg0KIyBOT1RFUyBGT1IgRlVUVVJFIElNUExFTUVOVEFUSU9ODQoNCiMjIFBvd2VyIEJJIHZzLiBSU3R1ZGlvIChSIFByb2dyYW1taW5nKQ0KQ3JlYXRpbmcgdGhpcyByZXBvcnQgcmVxdWlyZXMga25vd2xlZGdlIGluIG1hbmFnaW5nIHRoZSBkaWZmZXJlbnQgY29kaW5nIHN0cnVjdHVyZS0taXQgcmVxdWlyZXMga25vd2luZyBSLiBJdCBjYW4gYmUgcmVwbGljYXRlZCB0aHJvdWdoIG90aGVyIHByb2dyYW1zLCBhbmQgYnkgZG9pbmcgc28gbWF5IGVuaGFuY2UgdGhlIG92ZXJhbGwgZXhwZXJpZW5jZS4gU3VjaCBpcyB0aGUgY2FzZSB3aXRoIFBvd2VyIEJJIGJ1dCBpbiBhIGRpZmZlcmVudCBhc3BlY3QuDQoNClBvd2VyIEJJIGlzIGJldHRlciBzdWl0ZWQgZm9yIGNyZWF0aW5nIGludGVyYWN0aXZlIGRhc2hib2FyZHMgYW5kIHZpc3VhbGl6YXRpb25zIHF1aWNrbHkgYW5kIHNoYXJpbmcgdGhlbSBlYXNpbHkgd2l0aCBub24tdGVjaG5pY2FsIHN0YWtlaG9sZGVycy4gSXQgaXMgdXNlci1mcmllbmRseSBhbmQgaW50ZWdyYXRlcyB3ZWxsIHdpdGggb3RoZXIgTWljcm9zb2Z0IHByb2R1Y3RzLCBtYWtpbmcgaXQgaWRlYWwgZm9yIGJ1c2luZXNzIGVudmlyb25tZW50cyB0aGF0IHJlcXVpcmUgcmVndWxhciByZXBvcnRpbmcgYW5kIHJlYWwtdGltZSBkYXRhIHVwZGF0ZXMuDQoNClIgU3R1ZGlvLCBvbiB0aGUgb3RoZXIgaGFuZCwgaXMgaWRlYWwgZm9yIGluLWRlcHRoIGRhdGEgYW5hbHlzaXMsIGNvbXBsZXggc3RhdGlzdGljYWwgbW9kZWxpbmcsIGFuZCBwcm9qZWN0cyB0aGF0IHJlcXVpcmUgZXh0ZW5zaXZlIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCBjdXN0b20gYW5hbHlzZXMuIEl0IG9mZmVycyBncmVhdGVyIGZsZXhpYmlsaXR5IGFuZCBpcyBtb3JlIHBvd2VyZnVsIGZvciBhZHZhbmNlZCBhbmFseXRpY3MsIGFsdGhvdWdoIGl0IHJlcXVpcmVzIHByb2dyYW1taW5nIGtub3dsZWRnZSBhbmQgbWF5IGhhdmUgYSBzdGVlcGVyIGxlYXJuaW5nIGN1cnZlLg0KDQpJZiB0aGUgcHJpbWFyeSBnb2FsIGlzIHRvIHBlcmZvcm0gYWR2YW5jZWQgc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIGN1c3RvbSBtb2RlbGluZywgUiBTdHVkaW8gd291bGQgYmUgbW9yZSBhcHByb3ByaWF0ZS4gSG93ZXZlciwgaWYgdGhlIGdvYWwgaXMgdG8gY3JlYXRlIGludGVyYWN0aXZlLCBzaGFyZWFibGUgZGFzaGJvYXJkcyBhbmQgcmVwb3J0cywgUG93ZXIgQkkgbWlnaHQgYmUgdGhlIGJldHRlciBjaG9pY2UuIFRoaXMgaXMgYSB0b3NzIGNvaW4sIGFzIG15IGludGVudCBpcyB0byBwcm92aWRlIGJvdGggYWR2YW5jZWQgc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIGN1c3RvbSBtb2RlbGluZyBhcyBJIGxlYXJuIHRvIGZ1cnRoZXIgdXRpbGl6ZSB0aGUgcHJvZ3JhbSwgYnV0IGFsc28gYWxsb3cgb3RoZXJzIHRoZSBhdmFpbGFiaWxpdHkgdG8gaW50ZXJhY3Qgd2l0aCB0aGVpciBkYXRhLCBzaG91bGQgdGhhdCB0aW1lIGV2ZXIgY29tZS4gDQoNCiMjIFByb3NwZWN0aXZlIFN0YXRpc3RpY2FsIEFuYWx5c2VzIA0KTW9yZSBhZHZhbmNlZCBzdGF0aXN0aWNhbCBtZWFzdXJlbWVudHMgYXJlIGF2YWlsYWJsZSB0byBkZXJpdmUgZnJvbSB0aGUgZGF0YXNldC4gSSd2ZSBpbmNsdWRlZCBhIGdlbmVyYWwgbGlzdCBvZiBpZGVhcyB0byBleHBsb3JlLiBTb21lIGlkZWFzIHJlcXVpcmUgYSBsYXJnZXIgZGVtb2dyYXBoaWMgZ3JvdXAsIGFuZCBvdGhlcnMgbmVjZXNzaXRhdGUgdGhlIHVzZSBvZiB0ZWNobm9sb2dpY2FsIGRldmljZXMgKHdhdGNoZXMgYW5kIHBob25lIGFwcHMpLiBBdCB0aGUgdGltZSBvZiBwdWJsaXNoaW5nLCBJIGFtIHdvcmtpbmcgb24gcGxvdHRpbmcgbXVsdGlwbGUgdmFyaWFibGVzIG9uIG9uZSBwbG90LiBPbmUgaW5jbHVkZXMgcGxvdHRpbmcgQXZlcmFnZSBCb2R5d2VpZ2h0ICh5KSBhbmQgRGFpbHkgQXZlcmFnZSAxUk0gKHkpIG92ZXIgdGltZSAoeCkuIFRoaXMgd2lsbCBoZWxwIGV4cGxvcmUgYW55IGNvcnJlbGF0aW9uIGFuZCBjYXVzYXRpb24gYmV0d2VlbiB2YXJpYWJsZXMuIEZpbmRpbmdzIGFyZSBleHBlY3RlZCB0byBwcm92aWRlIGFkYXB0YWJsZSBpbnNpZ2h0cyBpbnRvIGRhaWx5IHJvdXRpbmVzIGFuZCBoYWJpdHMuIA0KDQojIyMgRHVhbCBZLWF4aXMgUGxvdA0KVGhpcyB0eXBlIG9mIHBsb3QgYWxsb3dzIHlvdSB0byB2aXN1YWxpemUgdHdvIGRpZmZlcmVudCB5LXZhcmlhYmxlcyBhZ2FpbnN0IHRoZSBzYW1lIHgtdmFyaWFibGUgDQoNCkF2ZXJhZ2UgQm9keXdlaWdodCBhbmQgRGFpbHkgQXZlcmFnZSAxUk0gb3ZlciB0aW1lDQoNCiAgLSBQbG90ID0gU2VsZWN0ZWQgQ3JpdGVyaWEgZm9yIEluZGl2aWR1YWwNCiAgLSBZLXZhcmlhYmxlID0gQXZnIEJvZHl3ZWlnaHQNCiAgICAgIC0gUmVxdWlyZXMgY3JlYXRpbmcgbmV3IGRmIGZyb20gVml0YWxzOyBEYWlseV9BdmdfQm9keXdlaWdodCAoQXZnIEJXIG9mIGFsbCBtZWFzdXJlcyBvbiBlYWNoIGRhdGUpDQogIC0gWS12YXJpYWJsZSA9IERhaWx5IEF2ZyAxUk0gDQogICAgICAtIFJlcXVpcmVzIGNyZWF0aW5nIG5ldyBkZiBmcm9tIFJhdyBEYXRhOyBEYWlseV9BdmdfMVJNIChBdmcgMVJNIG9mIGFsbCBzZXRzIG9uIGVhY2ggZGF0ZSkNCiAgLSBYLXZhcmlhYmxlID0gRGF0ZSAoZGF5L21vbnRoKQ0KICAtIEltYWdpbmUgcGxvdCBzaW1pbGFyIHRvIFdlYnVsbCBDb21wYXJpc29uIFF1b3RlcyBzdHJ1Y3R1cmUNCiAgDQoNCkRhaWx5IEF2ZXJhZ2UgMVJNIGFuZCAjIERhaWx5IFNldHMgb3ZlciB0aW1lIGZvciBTZWxlY3RlZCBDcml0ZXJpYSANCg0KICAtIFBsb3QgPSBTZWxlY3RlZCBDcml0ZXJpYSBmb3IgSW5kaXZpZHVhbA0KICAtIFktdmFyaWFibGUgPSBEYWlseSBBdmVyYWdlIDFSTQ0KICAgICAgLSBDb25zaWRlciB0byBzdWIgRGFpbHkgd2l0aCBXZWVrbHkgb3IgTW9udGhseSBBdmVyYWdlIDFSTSANCiAgICAgIC0gQ29uc2lkZXIgdG8gc3ViIEF2ZXJhZ2UgMVJNIHdpdGggSGlnaGVzdCAxUk0gDQogIC0gWS12YXJpYWJsZSA9IERhaWx5IFNldHMgUGVyZm9ybWVkDQogICAgICAtIENvbnNpZGVyIHRvIHN1YiBEYWlseSBTZXRzIHdpdGggV2Vla2x5IG9yIE1vbnRobHkgU2V0cw0KICAgICAgLSBBIGxhcmdlciBhbmQgY29uc2lzdGVudCBudW1iZXIgb2Ygc2V0cyBwZXJmb3JtZWQgaXMgZXhwZWN0ZWQgY29ycmVsYXRlIG9yIG1haW50YWluIDFSTSBtZWFzdXJlcy4NCiAgICAgIC0gR2FwcyBpbiBudW1iZXIgb2Ygc2V0cyBwZXJmb3JtZWQgaXMgZXhwZWN0ZWQgdG8gY29ycmVsYXRlIHdpdGggZGVjcmVhc2VkIDFSTSBtZWFzdXJlcw0KDQpgYGB7ciBzYW1wbGUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBldmFsPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KDQojIEluc3RhbGwgZ2dwdWJyIHBhY2thZ2UgaWYgbm90IGFscmVhZHkgaW5zdGFsbGVkDQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImdncHViciIsIHF1aWV0bHkgPSBUUlVFKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3B1YnIiKQ0KfQ0KDQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGdncHVicikNCg0KIyBDcmVhdGUgdGhlIGRhdGFzZXQNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAgRGF0ZSA9IGFzLkRhdGUoYygnMjAyMy0wMS0wMScsICcyMDIzLTAxLTAyJywgJzIwMjMtMDEtMDMnLCAnMjAyMy0wMS0wNCcsIA0KICAgICAgICAgICAgICAgICAgICcyMDIzLTAxLTA1JywgJzIwMjMtMDEtMDYnLCAnMjAyMy0wMS0wNycsICcyMDIzLTAxLTA4JywgDQogICAgICAgICAgICAgICAgICAgJzIwMjMtMDEtMDknLCAnMjAyMy0wMS0xMCcpKSwNCiAgQXZlcmFnZV9Cb2R5d2VpZ2h0ID0gYyg3MCwgNzEsIDcwLCA3MC41LCA3MS4yLCA3MC44LCA3MC41LCA3MSwgNzEuNSwgNzAuNyksDQogIERhaWx5X0F2ZXJhZ2VfMVJNID0gYygxNTAsIDE1MiwgMTUxLCAxNTMsIDE1NSwgMTU0LCAxNTMsIDE1NiwgMTU4LCAxNTcpDQopDQoNCiMgRGV0ZXJtaW5lIHRoZSB5LWF4aXMgbGltaXRzIGZvciBib3RoIHZhcmlhYmxlcw0KeTFfbWluIDwtIG1pbihkYXRhJERhaWx5X0F2ZXJhZ2VfMVJNKSAtIDENCnkxX21heCA8LSBtYXgoZGF0YSREYWlseV9BdmVyYWdlXzFSTSkgKyAxDQp5Ml9taW4gPC0gbWluKGRhdGEkQXZlcmFnZV9Cb2R5d2VpZ2h0KSAtIDENCnkyX21heCA8LSBtYXgoZGF0YSRBdmVyYWdlX0JvZHl3ZWlnaHQpICsgMQ0KDQojIFNjYWxpbmcgZnVuY3Rpb24gZm9yIHRoZSBzZWNvbmRhcnkgYXhpcw0Kc2NhbGVfZmFjdG9yIDwtICh5Ml9tYXggLSB5Ml9taW4pIC8gKHkxX21heCAtIHkxX21pbikNCg0KIyBEZWZpbmUgdGhlIGRhdGUgbGFiZWwgZnVuY3Rpb24gdG8gYWRkIGEgbmV3bGluZSBiZXR3ZWVuIHRoZSBtb250aCBhbmQgdGhlIGRheSAgDQpkYXRlX2xhYmVsX2Z1bmMgPC0gZnVuY3Rpb24oeCkgew0KICBsYWJlbHMgPC0gZm9ybWF0KHgsICIlYlxuJWQiKSAjIERpc3BsYXlzIGFzICJTZXBcbjE1Iiwgc2VwYXJhdGluZyBtb250aCBhbmQgZGF5IHdpdGggYSBuZXdsaW5lDQogIGxhYmVsc1sxXSA8LSBwYXN0ZTAobGFiZWxzWzFdLCAiXG4iLCBmb3JtYXQoeFsxXSwgIiVZIikpICAjIEFwcGVuZCB0aGUgeWVhciB0byB0aGUgZmlyc3QgbGFiZWwNCiAgcmV0dXJuKGxhYmVscykNCn0NCg0KIyBDcmVhdGUgdGhlIHBsb3QNCnAgPC0gZ2dwbG90KGRhdGEsIGFlcyh4ID0gRGF0ZSkpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gRGFpbHlfQXZlcmFnZV8xUk0sIGNvbG9yID0gIkRhaWx5IEF2ZXJhZ2UgMVJNIikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gKEF2ZXJhZ2VfQm9keXdlaWdodCAtIHkyX21pbikgLyBzY2FsZV9mYWN0b3IgKyB5MV9taW4sIGNvbG9yID0gIkF2ZXJhZ2UgQm9keXdlaWdodCIpKSArDQogIGdlb21fcG9pbnQoYWVzKHkgPSBEYWlseV9BdmVyYWdlXzFSTSwgY29sb3IgPSAiRGFpbHkgQXZlcmFnZSAxUk0iKSwgc2l6ZSA9IDMsIGRhdGEgPSBkYXRhW2MoMSwgbnJvdyhkYXRhKSksIF0pICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IChBdmVyYWdlX0JvZHl3ZWlnaHQgLSB5Ml9taW4pIC8gc2NhbGVfZmFjdG9yICsgeTFfbWluLCBjb2xvciA9ICJBdmVyYWdlIEJvZHl3ZWlnaHQiKSwgc2l6ZSA9IDMsIGRhdGEgPSBkYXRhW2MoMSwgbnJvdyhkYXRhKSksIF0pICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSAiRGFpbHkgQXZlcmFnZSAxUk0iLA0KICAgIGxpbWl0cyA9IGMoeTFfbWluLCB5MV9tYXgpLA0KICAgIGxhYmVscyA9IHNjYWxlczo6bnVtYmVyX2Zvcm1hdChhY2N1cmFjeSA9IDAuMSksDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gKiBzY2FsZV9mYWN0b3IgKyB5Ml9taW4sIG5hbWUgPSAiQXZlcmFnZSBCb2R5d2VpZ2h0IChrZykiLCBsYWJlbHMgPSBzY2FsZXM6Om51bWJlcl9mb3JtYXQoYWNjdXJhY3kgPSAwLjEpKQ0KICApICsNCiAgc2NhbGVfeF9kYXRlKA0KICAgIGJyZWFrcyA9IHNlcShtaW4oZGF0YSREYXRlKSwgbWF4KGRhdGEkRGF0ZSksIGJ5ID0gIjEgZGF5IiksDQogICAgbWlub3JfYnJlYWtzID0gc2VxKG1pbihkYXRhJERhdGUpLCBtYXgoZGF0YSREYXRlKSwgYnkgPSAiMSBkYXkiKSwNCiAgICBsYWJlbHMgPSBkYXRlX2xhYmVsX2Z1bmMNCiAgKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCgNCiAgICBuYW1lID0gIlZhcmlhYmxlcyIsDQogICAgdmFsdWVzID0gYygiRGFpbHkgQXZlcmFnZSAxUk0iID0gImJsdWUiLCAiQXZlcmFnZSBCb2R5d2VpZ2h0IiA9ICJyZWQiKQ0KICApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJBdmVyYWdlIEJvZHl3ZWlnaHQgYW5kIERhaWx5IEF2ZXJhZ2UgMVJNIE92ZXIgVGltZSIsDQogICAgeCA9ICIiICMgRGF0ZSBvciBvdGhlciBpZiBkZXNpcmVkDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRpdGxlLnkucmlnaHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAicmVkIiwgbWFyZ2luID0gbWFyZ2luKGwgPSAxNSkpLA0KICAgIGF4aXMudGl0bGUueS5sZWZ0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsdWUiLCBtYXJnaW4gPSBtYXJnaW4ociA9IDE1KSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gNSkpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTgwIiksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5OTAiKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTgwIiksDQogICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyZXk5MCIpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5ODAiKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTkwIiksDQogICAgYXhpcy50aWNrcy5sZW5ndGggPSB1bml0KDAuMiwgImNtIiksDQogICAgYXhpcy50ZXh0LnkubGVmdCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4ociA9IDIpKSwgIyBBZGp1c3QgbWFyZ2luIGhlcmUNCiAgICBheGlzLnRleHQueS5yaWdodCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4obCA9IDIpKSwgIyBBZGp1c3QgbWFyZ2luIGhlcmUNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAuNSkpLCAgIyBBZGQgc29tZSBtYXJnaW4gdG8geC1heGlzIGxhYmVscyBmb3IgYmV0dGVyIHJlYWRhYmlsaXR5LA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQuc3BhY2luZy54ID0gdW5pdCgwLjUsICdjbScpDQogICkNCg0KIyBBcnJhbmdlIHRoZSBwbG90IGFuZCB0aGUgbGVnZW5kDQpnZ2FycmFuZ2UocCwgbmNvbCA9IDEsIGxlZ2VuZCA9ICJ0b3AiKQ0KDQoNCmBgYA0KDQo8IS0tDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIiwgbGFiZWxzID0gZGF0ZV9sYWJlbF9mdW5jLA0KICAgICAgICAgICAgICAgbGltaXRzID0gYyhtaW4odml0YWxzX2RhdGEkRGF0ZSwgbmEucm0gPSBUUlVFKSwgZXh0ZW5kZWRfYWxsX2RhdGFfbWF4X2RhdGUpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6Om51bWJlcl9mb3JtYXQoYWNjdXJhY3kgPSAwLjEpKSArICAjIEFkanVzdCB5LWF4aXMgdG8gMXN0IGRlY2ltYWwNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHNldE5hbWVzKGNvbG9yX3BhbGV0dGUsIGdzdWIoIl8iLCAiICIsIG5hbWVzKGNvbG9yX3BhbGV0dGUpKSkpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc2V0TmFtZXMoY29sb3JfcGFsZXR0ZSwgZ3N1YigiXyIsICIgIiwgbmFtZXMoY29sb3JfcGFsZXR0ZSkpKSkgKyAgIyBNYXRjaGluZyBmaWxsIGNvbG9ycyB3aXRoIGNvbG9yIHBhbGV0dGUNCiAgbGFicyh0aXRsZSA9ICJCb2R5d2VpZ2h0IE92ZXIgVGltZSBmb3IgQWxsIEluZGl2aWR1YWxzIiwNCiAgICAgICB4ID0gIkRhdGUiLA0KICAgICAgIHkgPSAiV2VpZ2h0IChsYnMpIiwNCiAgICAgICBjb2xvciA9ICJOYW1lIiwNCiAgICAgICBmaWxsID0gIk5hbWUiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgbWlub3IgZ3JpZCBsaW5lcyBvbiB0aGUgeC1heGlzDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleTkwIikpICAjIE1ha2UgZ3JpZCBsaW5lcyBsaWdodGVyDQotLT4NCg0KDQo8IS0tIA0Kc2NhbGVfeF9kYXRlKGJyZWFrcyBieSB4MSBtb250aCAodGhlIGRhdGEgd2lsbCBiZSBzcHJlYWQgb3V0IG92ZXIgbW9udGhzKS4gDQpDcmVhdGUgZ2VvbV9tYXJrZXQ7IEFkZCBtYXJrZXIgb24gZmlyc3QgZGF0YSBwb2ludCBhbmQgbGFzdCBkYXRhIHBvaW50DQotLT4NCg0KIyMjIFN0YWNrZWQgQmFyIENoYXJ0IA0KTG9vcCBwbG90cyBmb3IgZWFjaCBpbmRpdmlkdWFsLiBTaG93IFt0b3RhbF0gdmFsdWUgb2YgYSBjYXRlZ29yeSBhbmQgc2VnbWVudHMgdGhhdCBiYXIgdG8gc2hvdyB0aGUgcHJvcG9ydGlvbiBvZiBkaWZmZXJlbnQgc3ViLWNhdGVnb3JpZXMgd2l0aGluIHRoYXQgW3RvdGFsXSB2YWx1ZS4NCg0KJSBTZXRzIG9mIFNlbGVjdGVkIENyaXRlcmlhIGJ5IEFUSCAxUk0gYW5kIEF2ZyAxUk0gDQoNCiAgLSBWYWx1ZSA9ICUgc2V0cyBwZXJmb3JtZWQgKGllIDIlIG9mIGFsbCBzZXRzIHBlcmZvcm1lZCkNCiAgLSBTdWItY2F0ZWdvcnkgPSBBVEggMVJNIGFzIHRoZSBmdWxsIGJhciAoaWUgQ2hlc3QgUHJlc3MgMTc0LjcwLCBEZWFkbGlmdCAyNjcuNDQpDQogIC0gU3ViLWNhdGVnb3J5ID0gQXZnIDFSTSBMMlcgYXMgcGVyY2VudGFnZSBvZiBBVEggMVJNIChpZSBDaGVzdCBQcmVzcyAxNTIuNzEsIERlYWRsaWZ0IDIxOS4yMSkNCiAgLSBDYXRlZ29yeSA9IFNlbGVjdGVkIENyaXRlcmlhIChDaGVzdCBQcmVzcywgRGVhZGxpZnQsIGV0Yy4pDQogIC0gKkF2ZyAxUk0gTDJXIGFzIHBlcmNlbnRhZ2Ugb2YgQVRIIDFSTSBtYXkgbm90IGJlIHRoZSBiZXN0IGRhdGFzZXQgdG8gY29tcGFyZSB3aXRoIHJlc3BlY3QgdG8gJSBzZXRzIG9mIHNlbGVjdGVkIGNyaXRlcmlhIHBlcmZvcm1lZC4gQ29uc2lkZXIgb3RoZXIgU3ViLWNhdGVnb3JpZXMgZm9yIGNvbXBhcmlzb24uDQogIA0KIyMjIE90aGVyIENoYXJ0cw0KDQpWZXJ0aWNhbCBCYXIgQ2hhcnQNCg0KLSBVc2FnZTogQ29tcGFyaW5nIHRoZSBmcmVxdWVuY3kgb3IgY291bnQgb2YgZGlmZmVyZW50IGV4ZXJjaXNlIHR5cGVzLg0KLSBFeGFtcGxlOiBOdW1iZXIgb2Ygc2Vzc2lvbnMgZm9yIGVhY2ggZXhlcmNpc2UgdHlwZSAoZS5nLiwgQmVuY2ggUHJlc3MsIERlYWRsaWZ0LCBTcXVhdCwgUHJlc3MpLg0KDQpIb3Jpem9udGFsIEJhciBDaGFydDoNCg0KLSBDb21wYXJpbmcgdGhlIGZyZXF1ZW5jeSBvciBjb3VudCBvZiBkaWZmZXJlbnQgZXhlcmNpc2UgdHlwZXMgd2l0aCBsb25nIGxhYmVscy4NCi0gRXhhbXBsZTogTnVtYmVyIG9mIHNlc3Npb25zIGZvciBlYWNoIGV4ZXJjaXNlIHR5cGUsIGRpc3BsYXllZCBob3Jpem9udGFsbHkgZm9yIGJldHRlciByZWFkYWJpbGl0eS4NCg0KU3RhY2tlZCBCYXIgQ2hhcnQ6DQoNCi0gVXNhZ2U6IFNob3dpbmcgdGhlIGNvbXBvc2l0aW9uIG9mIHNldHMgd2l0aGluIGVhY2ggZXhlcmNpc2UuDQotIEV4YW1wbGU6IE51bWJlciBvZiBzZXRzIHBlcmZvcm1lZCBmb3IgZWFjaCBleGVyY2lzZSB0eXBlLCBicm9rZW4gZG93biBieSByZXBzIHJhbmdlIChlLmcuLCAxLTUgcmVwcywgNi0xMCByZXBzLCAxMSsgcmVwcykuDQoNCkdyb3VwZWQgKENsdXN0ZXJlZCkgQmFyIENoYXJ0Og0KDQotIFVzYWdlOiBDb21wYXJpbmcgdGhlIGF2ZXJhZ2UgMVJNIChvbmUtcmVwZXRpdGlvbiBtYXhpbXVtKSBmb3IgZGlmZmVyZW50IGV4ZXJjaXNlcyBhY3Jvc3MgbXVsdGlwbGUgaW5kaXZpZHVhbHMuDQotIEV4YW1wbGU6IEF2ZXJhZ2UgMVJNIGZvciBCZW5jaCBQcmVzcywgRGVhZGxpZnQsIFNxdWF0LCBhbmQgUHJlc3MgZm9yIEFsZXgsIEtlbmRyaWNrLCBhbmQgSm9zaC4NCg0KMTAwJSBTdGFja2VkIEJhciBDaGFydDoNCg0KLSBVc2FnZTogU2hvd2luZyB0aGUgcGVyY2VudGFnZSBjb21wb3NpdGlvbiBvZiB0b3RhbCB3b3Jrb3V0cyBieSBleGVyY2lzZSB0eXBlLg0KLSBFeGFtcGxlOiBQZXJjZW50YWdlIG9mIHRvdGFsIHdvcmtvdXRzIG1hZGUgdXAgYnkgQmVuY2ggUHJlc3MsIERlYWRsaWZ0LCBTcXVhdCwgYW5kIFByZXNzLg0KDQpEaXZlcmdpbmcgQmFyIENoYXJ0Og0KDQotIFVzYWdlOiBEaXNwbGF5aW5nIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBwZXJmb3JtYW5jZSBjaGFuZ2VzIGluIGRpZmZlcmVudCBleGVyY2lzZXMuDQotIEV4YW1wbGU6IFBlcmZvcm1hbmNlIGltcHJvdmVtZW50IG9yIGRlY2xpbmUgaW4gMVJNIGZvciBlYWNoIGV4ZXJjaXNlIHR5cGUgb3ZlciBhIHBlcmlvZC4NCg0KTG9sbGlwb3AgQ2hhcnQ6DQoNCi0gVXNhZ2U6IFNob3dpbmcgYXZlcmFnZSBib2R5d2VpZ2h0IGZvciBlYWNoIGluZGl2aWR1YWwuDQotIEV4YW1wbGU6IEF2ZXJhZ2UgYm9keXdlaWdodCBvZiBBbGV4LCBLZW5kcmljaywgYW5kIEpvc2ggcmVwcmVzZW50ZWQgYXMgZG90cyBvbiBsaW5lcy4NCg0KRG90IFBsb3Q6DQoNCi0gVXNhZ2U6IFNob3dpbmcgdGhlIHBlcmZvcm1hbmNlIHNjb3JlcyAoZS5nLiwgMVJNKSBmb3IgZGlmZmVyZW50IGV4ZXJjaXNlcy4NCi0gRXhhbXBsZTogUGVyZm9ybWFuY2Ugc2NvcmVzIGZvciBCZW5jaCBQcmVzcywgRGVhZGxpZnQsIFNxdWF0LCBhbmQgUHJlc3MgZm9yIGVhY2ggaW5kaXZpZHVhbC4NCg0KVmFyaWFibGUgV2lkdGggQmFyIENoYXJ0Og0KDQotIFVzYWdlOiBTaG93aW5nIHRoZSB2b2x1bWUgb2Ygd2VpZ2h0IGxpZnRlZCB3aGVyZSB0aGUgd2lkdGggcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHNlc3Npb25zLg0KLSBFeGFtcGxlOiBUb3RhbCB3ZWlnaHQgbGlmdGVkIGluIEJlbmNoIFByZXNzLCBEZWFkbGlmdCwgU3F1YXQsIGFuZCBQcmVzcyB3aXRoIGJhciB3aWR0aCByZXByZXNlbnRpbmcgdGhlIG51bWJlciBvZiBzZXNzaW9ucy4NCg0KV2F0ZXJmYWxsIENoYXJ0Og0KDQotIFVzYWdlOiBTaG93aW5nIHRoZSBjdW11bGF0aXZlIGVmZmVjdCBvZiBkaWZmZXJlbnQgZXhlcmNpc2Ugc2Vzc2lvbnMgb24gdG90YWwgd2VpZ2h0IGxpZnRlZC4NCi0gRXhhbXBsZTogQ3VtdWxhdGl2ZSB0b3RhbCB3ZWlnaHQgbGlmdGVkIG92ZXIgdGltZSBmb3IgZGlmZmVyZW50IGV4ZXJjaXNlcy4NCg0KUGFyZXRvIENoYXJ0Og0KDQotIFVzYWdlOiBIaWdobGlnaHRpbmcgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZXhlcmNpc2VzIGNvbnRyaWJ1dGluZyB0byB0b3RhbCB3ZWlnaHQgbGlmdGVkLg0KLSBFeGFtcGxlOiBUb3RhbCB3ZWlnaHQgbGlmdGVkIGZvciBlYWNoIGV4ZXJjaXNlIHR5cGUgaW4gZGVzY2VuZGluZyBvcmRlciB3aXRoIGEgbGluZSBzaG93aW5nIGN1bXVsYXRpdmUgcGVyY2VudGFnZS4NCg0KR2FudHQgQ2hhcnQ6DQoNCi0gVXNhZ2U6IFByb2plY3QgcGxhbm5pbmcgYW5kIHRyYWNraW5nIHByb2dyZXNzIG92ZXIgdGltZS4NCi0gRXhhbXBsZTogV29ya291dCBzY2hlZHVsZSBzaG93aW5nIHRoZSB0aW1lbGluZSBmb3IgZGlmZmVyZW50IGV4ZXJjaXNlcyBhbmQgc2V0cyBvdmVyIGEgbW9udGguDQoNCkhpc3RvZ3JhbToNCg0KLSBVc2FnZTogU2hvd2luZyB0aGUgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiBvZiBib2R5d2VpZ2h0Lg0KLSBFeGFtcGxlOiBEaXN0cmlidXRpb24gb2YgYm9keXdlaWdodCBlbnRyaWVzIG92ZXIgdGhlIGxhc3QgbW9udGguDQoNCk1vc2FpYyBQbG90Og0KDQotIFVzYWdlOiBEaXNwbGF5aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBleGVyY2lzZSB0eXBlIGFuZCB0aGUgbnVtYmVyIG9mIHNldHMgcGVyZm9ybWVkLg0KLSBFeGFtcGxlOiBWaXN1YWxpemF0aW9uIG9mIGhvdyBkaWZmZXJlbnQgZXhlcmNpc2VzIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIG51bWJlciBvZiBzZXRzIHBlcmZvcm1lZC4NCg0KIyMgVXRpbGl6YXRpb24gb2YgRGF0YXNldHMNCg0KTG9uZ2l0dWRpbmFsIEFuYWx5c2lzIG9mIFRyYWluaW5nIFByb2dyZXNzOg0KDQotIE9iamVjdGl2ZTogVG8gdHJhY2sgYW5kIGFuYWx5emUgdGhlIHRyYWluaW5nIHByb2dyZXNzIG92ZXIgYW4gZXh0ZW5kZWQgcGVyaW9kLg0KLSBJbXBsZW1lbnRhdGlvbjogVXRpbGl6ZSB0aW1lIHNlcmllcyBhbmFseXNpcyB0byBtb25pdG9yIGNoYW5nZXMgaW4gMVJNIGFuZCBib2R5d2VpZ2h0IG92ZXIgdGltZS4gVGhpcyB3aWxsIGhlbHAgaWRlbnRpZnkgdHJlbmRzLCBwbGF0ZWF1cywgYW5kIHBlcmlvZHMgb2Ygc2lnbmlmaWNhbnQgaW1wcm92ZW1lbnQuIEFwcGx5aW5nIHNtb290aGluZyB0ZWNobmlxdWVzIGFuZCBBUklNQSBtb2RlbHMgY2FuIGFpZCBpbiBmb3JlY2FzdGluZyBmdXR1cmUgcGVyZm9ybWFuY2UgYmFzZWQgb24gaGlzdG9yaWNhbCBkYXRhLg0KDQpDb3JyZWxhdGlvbiBhbmQgQ2F1c2F0aW9uIFN0dWRpZXM6DQoNCi0gT2JqZWN0aXZlOiBUbyB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBkaWZmZXJlbnQgdmFyaWFibGVzLg0KLSBJbXBsZW1lbnRhdGlvbjogUGVyZm9ybSBjb3JyZWxhdGlvbiBhbmFseXNpcyB0byBpbnZlc3RpZ2F0ZSB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGJvZHl3ZWlnaHQsIHRyYWluaW5nIGZyZXF1ZW5jeSwgbnV0cml0aW9uYWwgaW50YWtlLCBhbmQgMVJNIHBlcmZvcm1hbmNlLiBGb2xsb3cgdXAgd2l0aCByZWdyZXNzaW9uIGFuYWx5c2lzIHRvIGlkZW50aWZ5IHBvdGVudGlhbCBjYXVzYWwgcmVsYXRpb25zaGlwcyBhbmQgcXVhbnRpZnkgdGhlIGltcGFjdCBvZiB2YXJpb3VzIGZhY3RvcnMgb24gc3RyZW5ndGggZ2FpbnMuDQoNCkNvbXBhcmF0aXZlIEFuYWx5c2lzIEFjcm9zcyBEaWZmZXJlbnQgRGVtb2dyYXBoaWNzOg0KDQotIE9iamVjdGl2ZTogVG8gY29tcGFyZSBwZXJmb3JtYW5jZSBtZXRyaWNzIGFjcm9zcyBkaWZmZXJlbnQgZGVtb2dyYXBoaWNzIHN1Y2ggYXMgYWdlLCBnZW5kZXIsIGFuZCB0cmFpbmluZyBleHBlcmllbmNlLg0KLSBJbXBsZW1lbnRhdGlvbjogVXNlIHQtdGVzdHMgYW5kIEFOT1ZBIHRvIGNvbXBhcmUgMVJNIHBlcmZvcm1hbmNlIGFuZCBib2R5d2VpZ2h0IGFjcm9zcyBkaWZmZXJlbnQgZGVtb2dyYXBoaWMgZ3JvdXBzLiBUaGlzIGNhbiBoZWxwIHRhaWxvciB0cmFpbmluZyBwcm9ncmFtcyB0byBzcGVjaWZpYyBncm91cHMgYW5kIGltcHJvdmUgb3ZlcmFsbCBlZmZlY3RpdmVuZXNzLg0KDQpFbmhhbmNlZCBWaXN1YWxpemF0aW9uIFRlY2huaXF1ZXM6DQoNCi0gT2JqZWN0aXZlOiBUbyBjcmVhdGUgbW9yZSBpbnNpZ2h0ZnVsIGFuZCBpbnRlcmFjdGl2ZSB2aXN1YWxpemF0aW9ucy4NCi0gSW1wbGVtZW50YXRpb246IEluY29ycG9yYXRlIGFkdmFuY2VkIHZpc3VhbGl6YXRpb24gbGlicmFyaWVzIHN1Y2ggYXMgcGxvdGx5IGZvciBpbnRlcmFjdGl2ZSBwbG90cyB0aGF0IGFsbG93IGZvciBkZWVwZXIgZXhwbG9yYXRpb24gb2YgdGhlIGRhdGEuIFRoaXMgY2FuIGluY2x1ZGUgZHluYW1pYyBwbG90cyB3aGVyZSB1c2VycyBjYW4gZmlsdGVyIGFuZCB2aWV3IHNwZWNpZmljIHN1YnNldHMgb2YgdGhlIGRhdGEuDQoNClByZWRpY3RpdmUgTW9kZWxpbmcgZm9yIFBlcmZvcm1hbmNlIE9wdGltaXphdGlvbjoNCg0KLSBPYmplY3RpdmU6IFRvIGRldmVsb3AgbW9kZWxzIHRoYXQgcHJlZGljdCBwZXJmb3JtYW5jZSBvdXRjb21lcyBhbmQgb3B0aW1pemUgdHJhaW5pbmcgcmVnaW1lbnMuDQotIEltcGxlbWVudGF0aW9uOiBBcHBseSBtYWNoaW5lIGxlYXJuaW5nIHRlY2huaXF1ZXMgc3VjaCBhcyByYW5kb20gZm9yZXN0cywgc3VwcG9ydCB2ZWN0b3IgbWFjaGluZXMsIG9yIG5ldXJhbCBuZXR3b3JrcyB0byBwcmVkaWN0IDFSTSBwZXJmb3JtYW5jZSBiYXNlZCBvbiBhIHJhbmdlIG9mIGlucHV0IHZhcmlhYmxlcy4gVGhlc2UgbW9kZWxzIGNhbiBiZSB1c2VkIHRvIHN1Z2dlc3Qgb3B0aW1hbCB0cmFpbmluZyBsb2FkcyBhbmQgdm9sdW1lcyBmb3IgaW5kaXZpZHVhbHMuDQoNCkNsdXN0ZXIgQW5hbHlzaXMgZm9yIElkZW50aWZ5aW5nIFRyYWluaW5nIFBhdHRlcm5zOg0KDQotIE9iamVjdGl2ZTogVG8gaWRlbnRpZnkgZGlzdGluY3QgdHJhaW5pbmcgcGF0dGVybnMgYW5kIGdyb3VwIHNpbWlsYXIgaW5kaXZpZHVhbHMuDQotIEltcGxlbWVudGF0aW9uOiBVc2UgY2x1c3RlcmluZyB0ZWNobmlxdWVzIHN1Y2ggYXMgSy1tZWFucyBjbHVzdGVyaW5nIHRvIGlkZW50aWZ5IGdyb3VwcyBvZiBpbmRpdmlkdWFscyB3aXRoIHNpbWlsYXIgdHJhaW5pbmcgcGF0dGVybnMgYW5kIHBlcmZvcm1hbmNlIG1ldHJpY3MuIFRoaXMgY2FuIGhlbHAgaW4gY3VzdG9taXppbmcgdHJhaW5pbmcgcHJvZ3JhbXMgZm9yIGRpZmZlcmVudCBjbHVzdGVycyBiYXNlZCBvbiB0aGVpciB1bmlxdWUgY2hhcmFjdGVyaXN0aWNzLg0KDQpTdXJ2aXZhbCBBbmFseXNpcyBmb3IgVHJhaW5pbmcgQXR0cml0aW9uOg0KDQotIE9iamVjdGl2ZTogVG8gYW5hbHl6ZSB0aGUgZHJvcG91dCByYXRlcyBhbmQgZmFjdG9ycyBhZmZlY3RpbmcgdHJhaW5pbmcgYWRoZXJlbmNlLg0KLSBJbXBsZW1lbnRhdGlvbjogUGVyZm9ybSBzdXJ2aXZhbCBhbmFseXNpcyB0byBzdHVkeSB0aGUgdGltZS10by1kcm9wb3V0IGZvciB0cmFpbmVlcyBhbmQgaWRlbnRpZnkgZmFjdG9ycyB0aGF0IGluZmx1ZW5jZSB0cmFpbmluZyBhZGhlcmVuY2UuIFRoaXMgY2FuIGd1aWRlIGludGVydmVudGlvbnMgYWltZWQgYXQgcmVkdWNpbmcgZHJvcG91dCByYXRlcyBhbmQgaW1wcm92aW5nIGxvbmctdGVybSB0cmFpbmluZyBjb21taXRtZW50Lg0KDQpQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzIChQQ0EpIGZvciBEaW1lbnNpb25hbGl0eSBSZWR1Y3Rpb246DQoNCi0gT2JqZWN0aXZlOiBUbyBzaW1wbGlmeSBjb21wbGV4IGRhdGFzZXRzIGFuZCBpZGVudGlmeSBrZXkgcGVyZm9ybWFuY2UgaW5kaWNhdG9ycy4NCi0gSW1wbGVtZW50YXRpb246IEFwcGx5IFBDQSB0byByZWR1Y2UgdGhlIGRpbWVuc2lvbmFsaXR5IG9mIHlvdXIgZGF0YXNldCB3aGlsZSByZXRhaW5pbmcgbW9zdCBvZiB0aGUgdmFyaWFuY2UuIFRoaXMgY2FuIGhlbHAgaW4gaWRlbnRpZnlpbmcga2V5IHZhcmlhYmxlcyB0aGF0IG1vc3QgaW5mbHVlbmNlIHRyYWluaW5nIG91dGNvbWVzIGFuZCBwZXJmb3JtYW5jZS4NCg0KTnV0cml0aW9uIGFuZCBSZWNvdmVyeSBBbmFseXNpczoNCg0KLSBPYmplY3RpdmU6IFRvIHN0dWR5IHRoZSBpbXBhY3Qgb2YgbnV0cml0aW9uIGFuZCByZWNvdmVyeSBvbiBwZXJmb3JtYW5jZS4NCi0gSW1wbGVtZW50YXRpb246IENvbGxlY3QgYW5kIGFuYWx5emUgZGF0YSBvbiBkaWV0YXJ5IGludGFrZSwgc2xlZXAgcGF0dGVybnMsIGFuZCByZWNvdmVyeSBtZXRob2RzLiBVc2UgcmVncmVzc2lvbiBhbmFseXNpcyB0byBkZXRlcm1pbmUgaG93IHRoZXNlIGZhY3RvcnMgaW5mbHVlbmNlIHN0cmVuZ3RoIGdhaW5zIGFuZCBvdmVyYWxsIHBlcmZvcm1hbmNlLg0KDQpCZW5jaG1hcmtpbmcgYW5kIFN0YW5kYXJkIERldmVsb3BtZW50Og0KDQotIE9iamVjdGl2ZTogVG8gZXN0YWJsaXNoIHBlcmZvcm1hbmNlIGJlbmNobWFya3MgYW5kIHN0YW5kYXJkcyBmb3IgZGlmZmVyZW50IHBvcHVsYXRpb25zLg0KLSBJbXBsZW1lbnRhdGlvbjogVXRpbGl6ZSB0aGUgY29sbGVjdGVkIGRhdGEgdG8gZGV2ZWxvcCBwZXJmb3JtYW5jZSBzdGFuZGFyZHMgYW5kIGJlbmNobWFya3MuIFRoaXMgY2FuIGludm9sdmUgY3JlYXRpbmcgcGVyY2VudGlsZSByYW5rcyBhbmQgcGVyZm9ybWFuY2UgY2F0ZWdvcmllcyB0aGF0IGNhbiBiZSB1c2VkIGZvciBzZXR0aW5nIHJlYWxpc3RpYyBnb2FscyBhbmQgZXhwZWN0YXRpb25zIGZvciB0cmFpbmVlcy4NCg0KKipEYXRhIENvbGxlY3Rpb24gRW5oYW5jZW1lbnRzKioNCg0KSW5jb3Jwb3JhdGluZyBXZWFyYWJsZSBUZWNobm9sb2d5OiANCg0KLSBVdGlsaXplIHdlYXJhYmxlIGRldmljZXMgdG8gY29sbGVjdCByZWFsLXRpbWUgZGF0YSBvbiBoZWFydCByYXRlLCBzbGVlcCBxdWFsaXR5LCBhbmQgZGFpbHkgYWN0aXZpdHkgbGV2ZWxzLiBUaGlzIGRhdGEgY2FuIHByb3ZpZGUgZGVlcGVyIGluc2lnaHRzIGludG8gaG93IGxpZmVzdHlsZSBmYWN0b3JzIGluZmx1ZW5jZSB0cmFpbmluZyBwZXJmb3JtYW5jZS4NCg0KRGV0YWlsZWQgTnV0cml0aW9uYWwgTG9nZ2luZzogDQoNCi0gSW1wbGVtZW50IGEgc3lzdGVtIGZvciBkZXRhaWxlZCBudXRyaXRpb25hbCBsb2dnaW5nLCBhbGxvd2luZyBmb3IgdGhlIGNvbGxlY3Rpb24gb2YgZGF0YSBvbiBtYWNyb251dHJpZW50IGFuZCBtaWNyb251dHJpZW50IGludGFrZS4gQW5hbHl6aW5nIHRoaXMgZGF0YSBjYW4gaGVscCBvcHRpbWl6ZSBkaWV0YXJ5IHBsYW5zIHRvIHN1cHBvcnQgdHJhaW5pbmcgZ29hbHMuDQoNClBzeWNob2xvZ2ljYWwgYW5kIE1vdGl2YXRpb25hbCBBc3Nlc3NtZW50czogDQoNCi0gUmVndWxhcmx5IGFzc2VzcyBwc3ljaG9sb2dpY2FsIGZhY3RvcnMgc3VjaCBhcyBtb3RpdmF0aW9uLCBzdHJlc3MgbGV2ZWxzLCBhbmQgbWVudGFsIGZhdGlndWUuIFVuZGVyc3RhbmRpbmcgdGhlIHBzeWNob2xvZ2ljYWwgYXNwZWN0cyBvZiB0cmFpbmluZyBjYW4gcHJvdmlkZSBhIG1vcmUgaG9saXN0aWMgdmlldyBvZiBhbiBpbmRpdmlkdWFs4oCZcyBwZXJmb3JtYW5jZSBhbmQgYWRoZXJlbmNlIHRvIHRoZSB0cmFpbmluZyBwcm9ncmFtLg0KDQpSZWNvdmVyeSBhbmQgSW5qdXJ5IERhdGE6IA0KDQotIENvbGxlY3QgZGF0YSBvbiByZWNvdmVyeSBzdHJhdGVnaWVzIGFuZCBpbmp1cnkgb2NjdXJyZW5jZXMuIEFuYWx5emluZyB0aGlzIGluZm9ybWF0aW9uIGNhbiBoZWxwIGluIGRldmVsb3BpbmcgaW5qdXJ5IHByZXZlbnRpb24gcHJvZ3JhbXMgYW5kIG9wdGltaXppbmcgcmVjb3ZlcnkgcHJvdG9jb2xzIHRvIGVuaGFuY2UgcGVyZm9ybWFuY2UuDQoNCkFkdmFuY2VkIEJpb21ldHJpYyBEYXRhOiANCg0KLSBJbmNvcnBvcmF0ZSB0aGUgY29sbGVjdGlvbiBvZiBhZHZhbmNlZCBiaW9tZXRyaWMgZGF0YSBzdWNoIGFzIGJsb29kIG1hcmtlcnMsIGhvcm1vbmUgbGV2ZWxzLCBhbmQgbXVzY2xlIG94eWdlbmF0aW9uLiBUaGlzIGNhbiBwcm92aWRlIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgcGh5c2lvbG9naWNhbCByZXNwb25zZXMgdG8gdHJhaW5pbmcuDQoNCiMgUkVGRVJFTkNFUyANCg0KPCEtLSANClRoZXJlIGFyZSBtdWx0aXBsZSByZWZlcmVuY2VzIGFib3ZlIGZvciB0aGUgc2FtZSBub3RhdGlvbiBiZWxvdy4gUiBoYXMgZGVmYXVsdCBzZXR0aW5ncyB0byBhc3NpZ24gb25lIG5vdGF0aW9uIHBlciByZWZlcmVuY2UsIHdoaWxlIGtlZXBpbmcgdGhlIG9yZGVyIHlvdSBoYXZlIGRlc2lnbmVkLiBGb3IgZXhhbXBsZSBbXjNdIGlzIHVzZWQgYXQgbGVhc3QgdHdpY2UsIGJ1dCB3aWxsIGFwcGVhciBhcyBbXjNdIGFuZCBbXjRdIGluIHRoZSBrbml0IHByb2R1Y3QuIFRoZSBmb2xsb3dpbmcgbnVtYmVycyB3aWxsIGJ1bXAgdXAuIFNhbWUgZ29lcyBmb3IgT25lIFJlcCBNYXggQ2FsY3VsYXRvciBbXjEwXSwgd2hpY2ggYXQgdGltZSBvZiByZXZpZXcgcHJpbnRzIGFzIFteMTFdIGFuZCBbXjE0XS4gQW5ub3RhdGlvbiBudW1iZXJzIG1heSBoYXZlIGNoYW5nZWQgYnV0IGhvcGVmdWxseSB5b3UgdW5kZXJzdGFuZCBteSBwb2ludC4NCi0tPg0KDQpbXjFdOiBUaGFtLCBLLiAoMjAyNCkuICpLREY6IFN0cmVuZ3RoIGFuZCBCb2R5d2VpZ2h0IFBlcmZvcm1hbmNlIEFuYWx5c2lzIChgciBTeXMuRGF0ZSgpYCkuKiBSUHVicyBieSBSU3R1ZGlvLiBSZXRyaWV2ZWQgZnJvbSA8aHR0cHM6Ly9ycHVicy5jb20vS2VuRG9lc0RhdGEvPi4NCg0KW14yXTogVGhhbSwgSy4gKDIwMjQpLiAqS0RGIChLRU4gRE9FUyBGSVRORVNTKS4qIEdvb2dsZSBEcml2ZS4gQXZhaWxhYmxlIGF0IDxodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZHJpdmUvZm9sZGVycy8xLTQxRkpfYzQxS2o3S2FLMGgxYUo1RUJ2RWhQd3dJc2k/dXNwPXNoYXJpbmc+DQoNClteM106IFRoYW0sIEsuICgyMDI0KS4gKlN0cmVuZ3RoIFN0YW5kYXJkcyBGaW5hbC54bHNtLiogS2VuIERvZXMgRGF0YS4gUmV0cmlldmVkIGZyb20gPGh0dHBzOi8vMWRydi5tcy94L3MhQXNZWVpBOW5MOGxmOENLNms2ckFQM0xTa3ZyeT9lPXlsQVJYaT4uDQoNClteNF06IFJpcHBldG9lLCBNLiAoMjAxMikuICpTdHJlbmd0aCBTdGFuZGFyZHMuKiBTdGFydGluZyBTdHJlbmd0aC4gUmV0cmlldmVkIGZyb20gPGh0dHBzOi8vc3RhcnRpbmdzdHJlbmd0aC5jb20vZmlsZXMvc3RhbmRhcmRzLnBkZj4uDQoNClteNV06IFJpcHBldG9lLCBNLiAoMjAxNykuICpTdGFydGluZyBTdHJlbmd0aDogQmFzaWMgQmFyYmVsbCBUcmFpbmluZyAoM3JkIGVkLikuKiBUaGUgQWFzZ2FhcmQgQ29tcGFueS4gUmV0cmlldmVkIGZyb20gPGh0dHBzOi8vYWFzZ2FhcmRjby5jb20vc3RvcmUvYm9va3MtcG9zdGVycy1kdmQvYm9va3Mvc3RhcnRpbmctc3RyZW5ndGgtYmFzaWMtYmFyYmVsbC10cmFpbmluZy8+Lg0KDQpbXjZdOiBMZWdpb24gQXRobGV0aWNzLiAoMjAxOSkuICpUaGVzZSBBcmUgdGhlIEJlc3QgU3RyZW5ndGggU3RhbmRhcmRzIG9uIHRoZSBJbnRlcm5ldC4qIFJldHJpZXZlZCBmcm9tIDxodHRwczovL2xlZ2lvbmF0aGxldGljcy5jb20vc3RyZW5ndGgtc3RhbmRhcmRzLz4uDQoNClteN106IFJpcHBldG9lLCBNLiAoMjAxMikuICpUaGUgU3RyZW5ndGggU3RhbmRhcmRzIFRhYmxlcyBhcmUgYmFjayB1cC4qIFN0YXJ0aW5nIFN0cmVuZ3RoIEZvcnVtLiBSZXRyaWV2ZWQgZnJvbSA8aHR0cHM6Ly9zdGFydGluZ3N0cmVuZ3RoLmNvbS9yZXNvdXJjZXMvZm9ydW0vbWFyay1yaXBwZXRvZS1xLWFuZC1hLzMzMDI5LXN0cmVuZ3RoLXN0YW5kYXJkcy10YWJsZXMuaHRtbD4uDQoNClteOF06IFJpcHBldG9lLCBNLiAoMjAxNykuICpTdGFydGluZyBTdHJlbmd0aDogQmFzaWMgQmFyYmVsbCBUcmFpbmluZywgM3JkIEVkaXRpb24qIGJ5IE1hcmsgUmlwcGV0b2UuIEF2YWlsYWJsZSBhdCA8aHR0cHM6Ly93d3cuYW1hem9uLmNvbS9TdGFydGluZy1TdHJlbmd0aC1NYXJrLVJpcHBldG9lLWVib29rL2RwL0IwMDZYSlI1WkEvcmVmPXNyXzFfMT9jcmlkPTIxNTIxWVhCS1g0QUkmZGliPWV5SjJJam9pTVNKOS4xcVRlaF84REpocURteHJyYWptalRiTGlRei13UGFLT2lmZ2k3ODdNN1d1ck54d1V3S1ZiaFFhZEpFdzhXZHUyeWdEUDhYMEQyM1k1eEdxRVpBSjJMNWx1RXcwZ3ZDSUl5dVRtdWdZWl9iUm1HMzVocUxSUGxiT3lReDRlNXBSZjJ3Vm9HbnNRUHpGUUVmRU9scmhpSEtwOEJTV0N1UWtmMlJFTEZLU09MUU80OUZxOFk1N1BVX011UG05Z2U5MVVjQzNlYm1DWjhwQ1dIbXFiVVVSTjZ0eW9jRFQtQ1IzWmFRQUtQSlhubVlQc29jQ1A0ano0WV9RVExFMWhlY3NrOFZ1dWdmM0hJQmpCV2tPVk1aRm1TRGxTOXVqVnhxRjR2UnFDN0dzVkpsdy5fOWpOcGxwZDlMNlBQRnprN1dNQy1uU0RmV1hQaG1ja0ZpaWFNU3dhQ3lvPi4NCg0KW145XTogUmlwcGV0b2UsIE0uICpQcmFjdGljYWwgUHJvZ3JhbW1pbmcgZm9yIFN0cmVuZ3RoIFRyYWluaW5nLCAzcmQgRWRpdGlvbiogYnkgTWFyayBSaXBwZXRvZS4gQXZhaWxhYmxlIGF0IDxodHRwczovL3d3dy5hbWF6b24uY29tL1ByYWN0aWNhbC1Qcm9ncmFtbWluZy1TdHJlbmd0aC1UcmFpbmluZy1SaXBwZXRvZS1lYm9vay9kcC9CMDBJVThZRVRXL3JlZj1zcl8xXzI/Y3JpZD0yMTUyMVlYQktYNEFJJmRpYj1leUoySWpvaU1TSjkuMXFUZWhfOERKaHFEbXhycmFqbWpUYkxpUXotd1BhS09pZmdpNzg3TTdXdXJOeHdVd0tWYmhRYWRKRXc4V2R1MnlnRFA4WDBEMjNZNXhHcUVaQUoyTDVsdUV3MGd2Q0lJeXVUbXVnWVpfYlJtRzM1aHFMUlBsYk95UXg0ZTVwUmYyd1ZvR25zUVB6RlFFZkVPbHJoaUhLcDhCU1dDdVFrZjJSRUxGS1NPTFFPNDlGcThZNTdQVV9NdVBtOWdlOTFVY0MzZWJtQ1o4cENXSG1xYlVVUk42dHlvY0RULUNSM1phUUFLUEpYbm1ZUHNvY0NQNGp6NFlfUVRMRTFoZWNzazhWdXVnZjNISUJqQldrT1ZNWkZtU0RsUzl1alZ4cUY0dlJxQzdHc1ZKbHcuXzlqTnBscGQ5TDZQUEZ6azdXTUMtblNEZldYUGhtY2tGaWlhTVN3YUN5bz4uDQoNClteMTBdOiBTdHJlbmd0aCBMZXZlbC4gKG4uZC4pLiAqT25lIFJlcCBNYXggQ2FsY3VsYXRvci4qIFJldHJpZXZlZCBmcm9tIDxodHRwczovL3N0cmVuZ3RobGV2ZWwuY29tL29uZS1yZXAtbWF4LWNhbGN1bGF0b3I+Lg0KDQpbXjExXTogVGhhbSwgSy4gKDIwMjQpLiAqS2VuIERvZXMgRml0bmVzcyBGaW5hbC54bHNtLiogUmV0cmlldmVkIGZyb20gPGh0dHBzOi8vMWRydi5tcy94L3MhQXNZWVpBOW5MOGxmOHliVE54bFctMmM2c0RYQj9lPUtMZmhUND4uDQoNClteMTJdOiBGbGV4IFN0YWZmLiAoMjAyMykuICpXaWRlLUdyaXAgdnMuIENsb3NlLUdyaXAgQmFyYmVsbCBDdXJscy4qIE11c2NsZSAmIEZpdG5lc3MuIFJldHJpZXZlZCBmcm9tIDxodHRwczovL3d3dy5tdXNjbGVhbmRmaXRuZXNzLmNvbS9mbGV4b25saW5lL3RyYWluaW5nL3dpZGUtZ3JpcC12cy1jbG9zZS1ncmlwLWJhcmJlbGwtY3VybHMvPi4NCg0KW14xM106IFR1ZmZXcmFwcyBFZGl0b3JzLiAoMjAyMykuICpDbG9zZS1HcmlwIHZzLiBXaWRlLUdyaXAgQmljZXAgQ3VybHM6IENob29zaW5nIHRoZSBSaWdodCBHcmlwIGZvciBNYXhpbXVtIFJlc3VsdHMuKiBUdWZmV3JhcHMuIFJldHJpZXZlZCBmcm9tIDxodHRwczovL3d3dy50dWZmd3JhcHMuY29tL2Jsb2dzL25ld3MvY2xvc2UtZ3JpcC12cy13aWRlLWdyaXAtYmljZXAtY3VybHMtY2hvb3NpbmctdGhlLXJpZ2h0LWdyaXAtZm9yLW1heGltdW0tcmVzdWx0cz4uDQoNClteMTRdOiBDb2x1Y2NpLCBDLiAoMjAyMykuICpUaGUgNcOXNSBXb3Jrb3V0IEV4cGxhaW5lZDogVGhlIENsYXNzaWMgUHJvZ3JhbSBmb3IgU2l6ZSBhbmQgU3RyZW5ndGguKiBCcmVha2luZyBNdXNjbGUuIFJldHJpZXZlZCBmcm9tIDxodHRwczovL2JyZWFraW5nbXVzY2xlLmNvbS81LXgtNS13b3Jrb3V0LWV4cGxhaW5lZC8+Lg0KDQoNCg==