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 RPubs1. 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 2.

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 file3. 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 file4. 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 Standards5 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 store6 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 Athletics7, 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 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 Forum8 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”9 and “Practical Programming for Strength Training.”10 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 Level11 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)12. 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

Individuals
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.13 14

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

PERFORMANCE ANALYSES

Weights Executed Over Time, 3-4-5+ Reps

This set of statistics is ideal for athletes or trainers who want to track performance over time, particularly in observing how maximum lifting capacity evolves across different workouts and rep thresholds. The visualizations and statistics generated can assist in adjusting training programs based on observed trends and performance plateaus.

The following figures are inspired by the 5x5 Training Model. From around September 2023 to April 2024, I primarily focused on 5 sets of 5 reps, incrementally adding weight after successfully executing 5 reps. I did not adhere to a single approach for performing the 5x5’s, as there are various perspectives and workout models. For instance, in his “The 5×5 Workout Explained” (2023) article15, Colucci explores the 5x5 workout program. He mentions its history with Reg Park whom proposed starting with progressively heavier warm-up sets for the first two sets, followed by three sets at the same heavier weight for the final three sets.

The 5×5 workout program is designed to build muscle size and strength by focusing on performing five sets of five repetitions of major compound exercises like squats, bench presses, and deadlifts. It emphasizes using progressively heavier weights with adequate rest intervals to ensure proper recovery and efficient muscle development. This routine is particularly beneficial for beginners to establish a solid strength foundation and for experienced lifters looking to maintain or increase muscle mass and strength.

Metrics Table

The following tables and plots highlight performance over time for workouts based on selected criteria. This table serves as a reference for how each metric may be used to compare with the others.

Metric Range Explanation
Average Weight Executed Per Set Last 2 Weeks Provides context to the Average 1RM Calculated Weight Last 2 Weeks by indicating the average effort per set
Average 1RM Calculated Weight Per Set Last 2 Weeks Helps to gauge if recent training sessions have been effective in maintaining or increasing strength levels, compared to the average weights executed per set.
Highest 1RM Calculated Weight Last 2 Weeks Indicates the highest strength achievement in the recent period and can be compared against the all-time 1RM to see if recent training is aligning with peak historical performance.
Highest 1RM Calculated Weight All Time Provides a reference point for evaluating current performance trends. For instance, comparing the Highest 1RM Calculated Weight Last 2 Weeks to this value shows if current strength levels are approaching, maintaining, or falling short of peak historical performance. This ATH (all time high) metric is the one to be constantly striving to meet, if not surpass. Reviewing the timeline as to when ATH’s occured helps to provide insight into the patterns and events that resulted in either growth, maintenance, or decline. For example, a trip x2 weeks out of the country was accompanied by decline in strength-based activities, leading to a decline on performance.
Highest Weight Executed at 5+ Reps All Time This metric complements the 1RM values by providing insight into strength endurance. Comparing it with the Average Weight Executed Per Set Last 2 Weeks can indicate improvements or declines in sustained strength over time.

The following plots display the Total Weight Per Set. Data points represent sets performed at 3, 4, and 5+ reps.

  • Data points are intentionally colored:
    • Red means Stop.
    • Green means Go.
  • After 5+ reps (red dot) have been met, the weight is increased.
  • If either 4 reps (blue dot) or 3 reps (green dot) have been met, the weight stays the same.

These visualizations help track progress and make data-driven decisions about adjusting weights based on performance. By observing the trends and patterns in these plots, one can ensure that training intensity is appropriately adjusted to meet performance goals.

Performances Over Time, Selected Criteria

Not all datapoints in this section were performed using 5x5 RM. Some exercises, like Hammer Curls or Lat Pulldowns, were sometimes performed in sets of 8-12+ reps, requiring less weight and producing noticeable differences in weight load execution on the plots. This is particularly evident in Kendrick’s Lat Pulldown plot. Others, such as Kendrick’s Flat Bench Barbell Chest Press, show a gradual rise in performance, which is more accurate and reflects drops in performance and absences of datapoints due to life events and decreases in exercise frequency. Generally, exercises that show a higher incline angle, such as Kendrick’s Barbell Squat and Kendrick’s Barbell Deadlift, exhibit faster-than-normal increases in weight over time. This faster-than-normal increase in weight may be due to starting low due to uncertainty with the amount of weight required for max execution and the need to avoid injury, or it could be caused by “beginner gains.”

This variance can lead to misleading interpretations when comparing performance across different exercises and rep ranges. For accurate comparison, it’s best to review sections containing 1-Rep Max (1RM) data, which provide a standardized measure for evaluating performance between different sets and on a daily basis. By focusing on 1RM, you ensure consistency and comparability, mitigating the issues caused by varied rep ranges in other exercises.

Kendrick - Barbell Squat

Kendrick - Barbell Squat Value..lbs. Range Date
Average Weight Executed Per Set: 151.67 Last 2 Weeks 07/13/2024 to 07/26/2024
Average 1RM Calculated Weight Per Set: 173.99 Last 2 Weeks 07/13/2024 to 07/26/2024
Highest 1RM Calculated Weight: 185.39 Last 2 Weeks 07/26/2024
Highest 1RM Calculated Weight: 207.87 All Time 02/12/2024
Highest Weight Executed at 5+ Reps: 185 All Time 02/12/2024

Kendrick - Flat Bench Barbell Chest Press

Kendrick - Flat Bench Barbell Chest Press Value..lbs. Range Date
Average Weight Executed Per Set: 138.12 Last 2 Weeks 07/20/2024 to 08/02/2024
Average 1RM Calculated Weight Per Set: 152.97 Last 2 Weeks 07/20/2024 to 08/02/2024
Highest 1RM Calculated Weight: 162.92 Last 2 Weeks 08/02/2024
Highest 1RM Calculated Weight: 174.7 All Time 02/07/2024
Highest Weight Executed at 5+ Reps: 155 All Time 02/02/2024

Kendrick - Barbell Deadlift

Kendrick - Barbell Deadlift Value..lbs. Range Date
Average Weight Executed Per Set: 189.44 Last 2 Weeks 07/18/2024 to 07/31/2024
Average 1RM Calculated Weight Per Set: 219.21 Last 2 Weeks 07/18/2024 to 07/31/2024
Highest 1RM Calculated Weight: 224.72 Last 2 Weeks 07/25/2024
Highest 1RM Calculated Weight: 267.44 All Time 02/14/2024
Highest Weight Executed at 5+ Reps: 235 All Time 02/14/2024

Kendrick - Barbell Overhead Shoulder Press

Kendrick - Barbell Overhead Shoulder Press Value..lbs. Range Date
Average Weight Executed Per Set: 63.89 Last 2 Weeks 07/13/2024 to 07/26/2024
Average 1RM Calculated Weight Per Set: 72.33 Last 2 Weeks 07/13/2024 to 07/26/2024
Highest 1RM Calculated Weight: 75.58 Last 2 Weeks 07/26/2024
Highest 1RM Calculated Weight: 87.21 All Time 01/02/2024
Highest Weight Executed at 5+ Reps: 75 All Time 01/08/2024

Kendrick - Lat Pulldown Bar Lat Pulldown

Kendrick - Lat Pulldown Bar Lat Pulldown Value..lbs. Range Date
Average Weight Executed Per Set: 115 Last 2 Weeks 07/04/2024 to 07/17/2024
Average 1RM Calculated Weight Per Set: 131.16 Last 2 Weeks 07/04/2024 to 07/17/2024
Highest 1RM Calculated Weight: 133.33 Last 2 Weeks 07/17/2024
Highest 1RM Calculated Weight: 173.91 All Time 01/06/2024
Highest Weight Executed at 5+ Reps: 140 All Time 02/14/2024

Alex - Flat Bench Barbell (Loaded) Chest Press

Alex - Flat Bench Barbell (Loaded) Chest Press Value..lbs. Range Date
Average Weight Executed Per Set: 160.71 Last 2 Weeks 07/18/2024 to 07/31/2024
Average 1RM Calculated Weight Per Set: 185.83 Last 2 Weeks 07/18/2024 to 07/31/2024
Highest 1RM Calculated Weight: 198.8 Last 2 Weeks 07/31/2024
Highest 1RM Calculated Weight: 228.4 All Time 01/13/2024
Highest Weight Executed at 5+ Reps: 185 All Time 01/28/2024

Kendrick - Barbell Bicep Curl

Kendrick - Barbell Bicep Curl Value..lbs. Range Date
Average Weight Executed Per Set: 60 Last 2 Weeks 01/17/2024 to 01/30/2024
Average 1RM Calculated Weight Per Set: 72.1 Last 2 Weeks 01/17/2024 to 01/30/2024
Highest 1RM Calculated Weight: 74.07 Last 2 Weeks 01/30/2024
Highest 1RM Calculated Weight: 74.07 All Time 01/30/2024
Highest Weight Executed at 5+ Reps: 60 All Time 01/30/2024

Kendrick - Cable Hammer Curl

Kendrick - Cable Hammer Curl Value..lbs. Range Date
Average Weight Executed Per Set: 40 Last 2 Weeks 06/17/2024 to 06/30/2024
Average 1RM Calculated Weight Per Set: 51.23 Last 2 Weeks 06/17/2024 to 06/30/2024
Highest 1RM Calculated Weight: 52.47 Last 2 Weeks 06/30/2024
Highest 1RM Calculated Weight: 66.86 All Time 12/28/2023
Highest Weight Executed at 5+ Reps: 57.5 All Time 12/28/2023

STATS TO STANDARDS

Performance measures are evaluated to match Standards.

Integrating Performance Metrics with Mark Rippetoe Strength Standards

Performance measures are evaluated to match standards. This section combines practical workout data analysis with Mark Rippetoe’s Strength Standards. The standards are essential for evaluating and contextualizing individual fitness achievements against standardized criteria.

For a higher quality of personal performance comparison, we define specific criteria to match the standards presented by Mark. Should we choose, we can specify our criteria for Flat Bench Dumbbell Chest Press or Incline Bench Dumbbell Chest Press, each likely requiring different weights and numbers of reps for execution. As a reminder, Mark Rippetoe’s training utilizes the barbell as the instrument for growth. By explaining in detail the Bench Press in his Starting Strength book 16, we know the strength standard is measured via the flat bench. Therefore, we specify Flat Bench Barbell (Loaded) Chest Press in our criteria to compare with Mark Rippetoe’s 1RM Male Bench Press Standards.

Specified Criteria with Standards For Reference
Strength Standard Category Name Selected Criteria Index
Male Bench Press Std 1RM By Bodyweight Mark Rippetoe Bench Press Flat Bench Barbell Chest Press 1
Male Deadlift Std 1RM By Bodyweight Mark Rippetoe Deadlift Barbell Deadlift 2
Male Press Std 1RM By Bodyweight Mark Rippetoe Press Barbell Overhead Shoulder Press 3
Male Squat Std 1RM By Bodyweight Mark Rippetoe Squat Barbell Squat 4

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 Table17.

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

Individual Performance Tables

Filtered results are grouped by individual. Some individuals do not have recorded data that meets the criteria.

Alex - 1RM Performance

Selected Criteria Index 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 185.83 2024-07-18 to 2024-07-31 228.40 2024-01-13
Barbell Deadlift 2 224.51 2024-07-18 to 2024-07-31 261.63 2023-12-17
Barbell Overhead Shoulder Press 3 106.09 2024-06-29 to 2024-07-12 110.47 2024-07-12
Barbell Squat 4 185.75 2024-07-02 to 2024-07-15 191.86 2024-07-15

Josh - 1RM Performance

Selected Criteria Index 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 213.15 2024-04-25 to 2024-05-08 253.09 2023-09-13
Barbell Deadlift 2 236.38 2023-10-27 to 2023-11-09 275.28 2023-10-18

Kendrick - 1RM Performance

Selected Criteria Index 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 152.97 2024-07-20 to 2024-08-02 174.70 2024-02-07
Barbell Deadlift 2 219.21 2024-07-18 to 2024-07-31 267.44 2024-02-14
Barbell Overhead Shoulder Press 3 72.33 2024-07-13 to 2024-07-26 87.21 2024-01-02
Barbell Squat 4 173.99 2024-07-13 to 2024-07-26 207.87 2024-02-12

Nathan - 1RM Performance

Selected Criteria Index 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 162.92 2023-04-07 to 2023-04-20 162.92 2023-04-20

1RM Plots - Performance Over Standards

Performance is plotted over Mark Rippetoe’s Strength Standards.

Some considerations for the following plots:

  • Average 1RM for each individual is based on data from the last 2 weeks (L2W). As presented in the 1RM Table above, date ranges between each individual differ, ranging from a few weeks to several months or even years. Despite these differences, this plot is still beneficial for comparing performance among individuals, fostering friendly competition, and motivating action toward higher performance.

  • Highest 1RM (ATH - All Time Highs) for each individual is based on data from all entries.

  • Average Bodyweight represents data from the last 2 weeks of entries for each individual. The following plots and Category Levels use Average Bodyweight for both Average 1RM L2W and ATH executions. Separate calculations are required to obtain Bodyweight at the time when Average 1RM L2W was executed and Bodyweight when ATH 1RM was executed.

  • The date and date ranges for Average Bodyweight (lbs) and 1RM statistics may not align. For example:

    • Date Range for Average 1RM L2W: 2023-10-27 to 2023-11-09
    • Date for ATH 1RM: 2023-10-18
    • Date Range for Average Bodyweight L2W: 2024-05-24 to 2024-06-06
    • Further calculations are required to align the date ranges between bodyweight and performance, allowing greater reliability in the 1RM weight execution-to-bodyweight ratio.

Average 1RM Last 2 Weeks (L2W)

Male Bench Press Standards, Avg 1RM L2W

Name Average 1RM (lbs) Avg BW L2W (lbs) Category Level
Alex 185.83 175.00 Cat. II
Josh 213.15 190.00 Cat. III
Kendrick 152.97 133.46 Cat. II

Male Deadlift Standards, Avg 1RM L2W

Name Average 1RM (lbs) Avg BW L2W (lbs) Category Level
Alex 224.51 175.00 Cat. I
Josh 236.38 190.00 Cat. I
Kendrick 219.21 133.46 Cat. I

Male Press Standards, Avg 1RM L2W

Name Average 1RM (lbs) Avg BW L2W (lbs) Category Level
Alex 106.09 175.00 Cat. I
Kendrick 72.33 133.46 Cat. I

Male Squat Standards, Avg 1RM L2W

Name Average 1RM (lbs) Avg BW L2W (lbs) Category Level
Alex 185.75 175.00 Cat. I
Kendrick 173.99 133.46 Cat. I

Highest 1RM All Time (ATH)

Male Bench Press Standards, 1RM ATH

Name 1RM ATH (lbs) Avg BW L2W (lbs) Category Level
Alex 228.40 175.00 Cat. III
Josh 253.09 190.00 Cat. III
Kendrick 174.70 133.46 Cat. III

Male Deadlift Standards, 1RM ATH

Name 1RM ATH (lbs) Avg BW L2W (lbs) Category Level
Alex 261.63 175.00 Cat. I
Josh 275.28 190.00 Cat. I
Kendrick 267.44 133.46 Cat. II

Male Press Standards, 1RM ATH

Name 1RM ATH (lbs) Avg BW L2W (lbs) Category Level
Alex 110.47 175.00 Cat. II
Kendrick 87.21 133.46 Cat. I

Male Squat Standards, 1RM ATH

Name 1RM ATH (lbs) Avg BW L2W (lbs) Category Level
Alex 191.86 175.00 Cat. I
Kendrick 207.87 133.46 Cat. II

L2W & ATH - Side By Side

Performance measures for Average 1RM Last 2 Weeks (L2W) and Highest 1RM All Time (ATH) are merged into one plot for side-by-side comparison. This visualization helps individuals reach higher performance by highlighting recent performance and identifying personal bests, thereby fostering healthy competition and motivating consistent progress.

This combined plot allows for an easy comparison of recent performance and all-time bests, providing a clear visual representation of each individual’s progress and potential. By understanding these metrics, individuals can identify areas for improvement and set goals to surpass their personal bests, ultimately leveling up their performance.

Note: Each exercise plot is followed by its table for reference.

Using Average 1RM Last 2 Weeks (L2W) for training purposes is more effective than comparing Highest 1RM Last 2 Weeks to 1RM All Time High (ATH). This is because the average 1RM over the last two weeks provides a more consistent and realistic measure of current strength levels, which can be influenced by various factors such as fatigue, recovery, and daily performance variability. Relying solely on the highest 1RM may not accurately reflect true performance capability and can lead to unrealistic training loads and potential overtraining.

Male Bench Press Standards, Avg 1RM L2W & 1RM ATH

Name Average 1RM (lbs) Category Level L2W 1RM ATH (lbs) Category Level ATH Avg BW L2W (lbs)
Alex 185.83 Cat. II 228.40 Cat. III 175.00
Josh 213.15 Cat. III 253.09 Cat. III 190.00
Kendrick 152.97 Cat. II 174.70 Cat. III 133.46

Male Deadlift Standards, Avg 1RM L2W & 1RM ATH

Name Average 1RM (lbs) Category Level L2W 1RM ATH (lbs) Category Level ATH Avg BW L2W (lbs)
Alex 224.51 Cat. I 261.63 Cat. I 175.00
Josh 236.38 Cat. I 275.28 Cat. I 190.00
Kendrick 219.21 Cat. I 267.44 Cat. II 133.46

Male Press Standards, Avg 1RM L2W & 1RM ATH

Name Average 1RM (lbs) Category Level L2W 1RM ATH (lbs) Category Level ATH Avg BW L2W (lbs)
Alex 106.09 Cat. I 110.47 Cat. II 175.00
Kendrick 72.33 Cat. I 87.21 Cat. I 133.46

Male Squat Standards, Avg 1RM L2W & 1RM ATH

Name Average 1RM (lbs) Category Level L2W 1RM ATH (lbs) Category Level ATH Avg BW L2W (lbs)
Alex 185.75 Cat. I 191.86 Cat. I 175.00
Kendrick 173.99 Cat. I 207.87 Cat. II 133.46

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


  1. Tham, K. (2024). KDF: Strength and Bodyweight Performance Analysis (2025-07-12). RPubs by RStudio. Retrieved from https://rpubs.com/KenDoesData/.↩︎

  2. Tham, K. (2024). KDF (KEN DOES FITNESS). Google Drive. Available at https://drive.google.com/drive/folders/1-41FJ_c41Kj7KaK0h1aJ5EBvEhPwwIsi?usp=sharing↩︎

  3. Tham, K. (2024). Strength Standards Final.xlsm. Ken Does Data. Retrieved from https://1drv.ms/x/s!AsYYZA9nL8lf8CK6k6rAP3LSkvry?e=ylARXi.↩︎

  4. Tham, K. (2024). Strength Standards Final.xlsm. Ken Does Data. Retrieved from https://1drv.ms/x/s!AsYYZA9nL8lf8CK6k6rAP3LSkvry?e=ylARXi.↩︎

  5. Rippetoe, M. (2012). Strength Standards. Starting Strength. Retrieved from https://startingstrength.com/files/standards.pdf.↩︎

  6. Rippetoe, M. (2017). Starting Strength: Basic Barbell Training (3rd ed.). The Aasgaard Company. Retrieved from https://aasgaardco.com/store/books-posters-dvd/books/starting-strength-basic-barbell-training/.↩︎

  7. Legion Athletics. (2019). These Are the Best Strength Standards on the Internet. Retrieved from https://legionathletics.com/strength-standards/.↩︎

  8. Rippetoe, M. (2012). The Strength Standards Tables are back up. Starting Strength Forum. Retrieved from https://startingstrength.com/resources/forum/mark-rippetoe-q-and-a/33029-strength-standards-tables.html.↩︎

  9. Rippetoe, M. (2017). Starting Strength: Basic Barbell Training, 3rd Edition by Mark Rippetoe. Available at https://www.amazon.com/Starting-Strength-Mark-Rippetoe-ebook/dp/B006XJR5ZA/ref=sr_1_1?crid=21521YXBKX4AI&dib=eyJ2IjoiMSJ9.1qTeh_8DJhqDmxrrajmjTbLiQz-wPaKOifgi787M7WurNxwUwKVbhQadJEw8Wdu2ygDP8X0D23Y5xGqEZAJ2L5luEw0gvCIIyuTmugYZ_bRmG35hqLRPlbOyQx4e5pRf2wVoGnsQPzFQEfEOlrhiHKp8BSWCuQkf2RELFKSOLQO49Fq8Y57PU_MuPm9ge91UcC3ebmCZ8pCWHmqbUURN6tyocDT-CR3ZaQAKPJXnmYPsocCP4jz4Y_QTLE1hecsk8Vuugf3HIBjBWkOVMZFmSDlS9ujVxqF4vRqC7GsVJlw._9jNplpd9L6PPFzk7WMC-nSDfWXPhmckFiiaMSwaCyo.↩︎

  10. Rippetoe, M. Practical Programming for Strength Training, 3rd Edition by Mark Rippetoe. Available at https://www.amazon.com/Practical-Programming-Strength-Training-Rippetoe-ebook/dp/B00IU8YETW/ref=sr_1_2?crid=21521YXBKX4AI&dib=eyJ2IjoiMSJ9.1qTeh_8DJhqDmxrrajmjTbLiQz-wPaKOifgi787M7WurNxwUwKVbhQadJEw8Wdu2ygDP8X0D23Y5xGqEZAJ2L5luEw0gvCIIyuTmugYZ_bRmG35hqLRPlbOyQx4e5pRf2wVoGnsQPzFQEfEOlrhiHKp8BSWCuQkf2RELFKSOLQO49Fq8Y57PU_MuPm9ge91UcC3ebmCZ8pCWHmqbUURN6tyocDT-CR3ZaQAKPJXnmYPsocCP4jz4Y_QTLE1hecsk8Vuugf3HIBjBWkOVMZFmSDlS9ujVxqF4vRqC7GsVJlw._9jNplpd9L6PPFzk7WMC-nSDfWXPhmckFiiaMSwaCyo.↩︎

  11. Strength Level. (n.d.). One Rep Max Calculator. Retrieved from https://strengthlevel.com/one-rep-max-calculator.↩︎

  12. Tham, K. (2024). Ken Does Fitness Final.xlsm. Retrieved from https://1drv.ms/x/s!AsYYZA9nL8lf8ybTNxlW-2c6sDXB?e=KLfhT4.↩︎

  13. Flex Staff. (2023). Wide-Grip vs. Close-Grip Barbell Curls. Muscle & Fitness. Retrieved from https://www.muscleandfitness.com/flexonline/training/wide-grip-vs-close-grip-barbell-curls/.↩︎

  14. TuffWraps Editors. (2023). Close-Grip vs. Wide-Grip Bicep Curls: Choosing the Right Grip for Maximum Results. TuffWraps. Retrieved from https://www.tuffwraps.com/blogs/news/close-grip-vs-wide-grip-bicep-curls-choosing-the-right-grip-for-maximum-results.↩︎

  15. Colucci, C. (2023). The 5×5 Workout Explained: The Classic Program for Size and Strength. Breaking Muscle. Retrieved from https://breakingmuscle.com/5-x-5-workout-explained/.↩︎

  16. Rippetoe, M. (2017). Starting Strength: Basic Barbell Training (3rd ed.). The Aasgaard Company. Retrieved from https://aasgaardco.com/store/books-posters-dvd/books/starting-strength-basic-barbell-training/.↩︎

  17. Strength Level. (n.d.). One Rep Max Calculator. Retrieved from https://strengthlevel.com/one-rep-max-calculator.↩︎

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==