P R E A M B L E

  Bio 240 Biostatistics is a required course for Biology Majors in the BS 
  degree program at Lehman College of the City University of New York. 
  
  Nationwide, we recognize that skills in the statistical analysis and 
  graphical visualization of biological data, are essential. Biostatistics 
  is required for biology majors at the leading Colleges and Universities 
  across the USA. 
  
  Students -- if you've not had a statistics course or a course in computer
  programming, then get over it! 
  
  In Bio 240 if you show up, show up on time, pay attention, take notes, work 
  hard and don't cheat, then you'll acquire deep skills in Biostatistics and in
  R programming. If you have had a course in statistics and/or in programming 
  then you'll quickly learn R. Of course, all statistical and programming 
  environments have a learning curve. 
  
  Bio 240 provides the opportunity for you to exit the course functioning in R 
  coding for Biostatistics, at Biology Graduate School level, and I have case 
  studies to prove it.
  



Last rendered:   Thursday August 24, 2023 at 19:25:37

__________________


Bio 240. Biostatistics   Fall 2023  Dwight Kincaid, PhD   Lehman College CUNY, Bronx NY 10468 USA



R
data
graphs
statistics
writing about the results



1   Communication


email:   You already have my College email address. In Bio 240 we make frequent use of email for file transfers, Q & A, Tests and general communication.

Zoom:   Twenty minutes before each class, I email the Zoom meeting invitation with URL link.
Zoom sessions occupy the 4 hour class time for the section of Bio 240 that enjoys your formal registration.

Twitter:   https://twitter.com/LC_biostat    2,100+ Tweets dedicated to R, Data, Graphs, Biostatistics, Bio 240, Science, Career Development, and related topics.   In the transition from Twitter to X, glitches remain.

RPubs:   RPubs is a free website at https://rpubs.com and it’s handy for publishing R Markdown documents from within the RStudio IDE. RPubs enables the public to view and to comment on documents but not to download. However, the foo.Rmd source code of a document may be downloaded if the author allowed for same, in the document’s meta, YAML code. Go to https://rpubs.com/Bio240_Biostat to see my documents published there, so far. View the Syllabus at https://rpubs.com/Bio240_Biostat/Syllabus

At https://rpubs.com , see the most recently published documents, worldwide. Many of these (HTML, PDF, Word, slides, etc.) are student homework assignments! Entire courses are posted by faculty worldwide, and multilingual. Indeed, I may go that route for Bio 240, as my skills improve in HTML5, CSS3, SVG and JavaScript.

Blackboard:   Blackboard has very limited use in Bio 240. The Syllabus is posted there and I may use it to send Announcements. The 3 Test grades will be posted there but realize that I only use Blackboard to post your raw Test grades, not to tabulate averages or anything else.

phone :   currently not available, please use email.


__________________



We are not meeting in person for Bio 240, this term. Because I am Zoom cam shy, this photo is of yours truly 9 years ago, with a very alive lobster on the Bay of Fundy off Grand Manan Island in the Province of New Brunswick, Canada.

This lobster’s job was to impress tourists, not to be eaten.
It was returned to the ocean when we departed.

The Bay of Fundy has the highest tides in the world – 45 vertical feet where photo was taken. https://en.wikipedia.org/wiki/Bay_of_Fundy

Obviously I regret not having the crew remove the rubber bands before my wife took the photo, but I might have lost a finger as even its smaller, abdominal chelae were biting fiercely in revolt from being plucked from the sea.


Bay of Fundy, 2014

Bay of Fundy, 2014


Question:   Is Bio 240 a course in statistics or in computer programming?
Answer:   It’s both, because increasingly, the scientist, teacher, physician, investigator — must be able to do both.


__________________


2   College rules


The Undergraduate Bulletin is your contract with the College:
http://lehman.smartcatalogiq.com/2019-2021/Undergraduate-Bulletin ; it has the rules on degrees, majors, minors, and more.

College policy on Academic Integrity:
http://lehman.smartcatalogiq.com/en/2019-2021/Undergraduate-Bulletin/Academic-Services-and-Policies/Academic-Integrity

View:   http://lehman.smartcatalogiq.com/2019-2021/Undergraduate-Bulletin/Academic-Services-and-Policies/Undergraduate-Grading-Systems-and-Related-Policies/Grade-Appeals for Grade Appeals.





  the BRONX


 


__________________


3   Computers


A computer (Win or Mac, but not Chrome OS because it will not run R) is REQUIRED for this synchronous, online section of Bio 240.

If we were meeting in Davis 225, there are Windows desktop terminals available but most still prefer their less restrictive, personal laptop computer, which also allows you to take R and all the software and data with you, after the semester is over. In Davis 225 you would need your Lehman email account for wireless access, needed for downloading R and for downloading R packages across the semester.

We will download to each machine the free and open-source, R language and system for statistical analysis and graphics (https://www.r-project.org). I will demonstrate.

R was created by statisticians for statisticians; therefore, R is statistically correct and can be trusted to be so. However, R is now used by and contributed to, by a much wider range of folks, spanning all scholarly disciplines including even literature, audio, art, video and Wall Street.

R is becoming the statistical and graphical, computer language of choice for scientists worldwide, with Python, JavaScript and Julia (MIT) as worthy, free and open source competitors.

There are R packages enabling your code in native C, C++, Python, Julia or other languages, to run within R. An R “package” may contain any number of new functions, data sets, demos, documentation, links and other resources.

Because R was created for data, graphs and statistical computing; it is not a general purpose programming language. Indeed, some use R just for making graphs and this is a good place to start learning R, as we shall do so in Bio 240.

Explore the R website, https://www.r-project.org to learn about the immense, R environment. Check out the Task Views, The R Journal (https://journal.r-project.org/ peer reviewed, open access), free R Manuals, FAQs, Help/Search engines, annual Conferences, related projects (R Blog, R-Forge) and affiliated organizations such as Bioconductor https://www.bioconductor.org/ for bioinformatics.

Notice the rich, global and multilingual nature of the R environment.

You may follow R on Twitter, https://twitter.com/_r_foundation

During class I will demonstrate on a Windows OS laptop, the installation of R and the installation of contributed packages from among the 19,000+ packages that are vetted and available in the latest release, R version 4.2.2 (2022-10-31 ucrt).


A (real) computer is required – Win or Mac, but not Chrome OS because it can’t run R.
The College has a laptop loaner program. To apply, visit: https://lehman.edu/coronavirus/student.php
and click: Student Device Loan Application.

R logo

R logo

4   Active learning


For Spring 2023 my sections of Bio 240 remain, 100% online synchronous and hosted by Zoom meetings during the regularly scheduled class period that enjoys your formal registration.

Twenty minutes before each class, I email the Zoom URL link.

Bio 240 makes limited use of Blackboard (Syllabus, posting of Test grades). I will also email files to you, regularly.

Distance learning material includes my lectures and demonstrations, polls, handouts, data files, graphs, R Editor files, PDF files of readings, URL links, videos, pop quizzes and practice Tests.

We meet online in Zoom during the regularly scheduled class times for Bio 240 (Friday 2pm - 5:50pm; Saturday 10am - 1:50pm).

I begin each class exactly on time.

Top students show up, show up on time, pay attention, take notes, work hard and don’t cheat – thus moving their career development forward.


In class, you will participate in
      active learning   by   collaborative coding  in   R

The key to learning is to practice over-and-over on the computer, dealing with data, graphs and statistical methods in R, combined with willingness to engage R by trial-and-error and in real time, typing code at your computer along with me during class, as we write and debug code together.

A computer program is merely a text document that one has typed! All computer programs whether small or large, reside in a constant state of revision.

You must grapple with the subject matter and work hard during class and outside of class.

There are no term papers and no class presentations but you must spend considerable time working outside of class practicing data analysis and graphics by calling functions in R and constructing R Editor files (programs) for the practice problems. Otherwise, you will do poorly.

Your extended attention is required in Bio 240 just as it’s required in biological research and just as it’s required in your professional career development.



R Data Graphs Statistics Writing


“The process of preparing programs for a digital computer is especially attractive not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music”

Donald E. Knuth. 1973. The Art of Computer Programming, 2nd ed, Vol 1, Fundamental Algorithms. Professor Emeritus, Computer Science Department, Stanford University, CA

born 1938

born 1938

In Bio 240, I try to convince you that writing programs in R for dealing with biological data, “…can be an aesthetic experience much like composing poetry or music.”



__________________


5   Grading


Final average = ( Test 1 + Test 2 + Test 3 ) / 3

By the above formula, the average of the 3 formal Tests is 100% of the final grade.

Although not graded, data assignments, practice Tests, Zoom polls and other
activities, reflect material to keep you moving forward in the course.

The number of Tests, even the formula itself may change, reflecting internal as well as external factors that may be beyond our control during the pandemic.

There is no extra credit work in Bio 240, beyond the +2 to +10 points of extra credit questions that are at the end of each Test, usually. Therefore, please do not ask for extra credit work.

Tests are form fill PDF files that are downloaded to your machine, engaged, saved and then emailed back to me.

You must be able to handle form fill PDF files else you must drop Bio 240. This will be addressed on the first day of class.

While many apps, even browsers, can partially deal with form fill PDF files, the best one is Acrobat Reader DC which is free and by Adobe, the company that invented PDF:   https://get.adobe.com/reader/  

Acrobat Reader DC works on all operating systems; it’s what I use. Download it.

Tests are strictly timed at 4 hours and are not cumulative. 😀


          Final average    Letter grade        Details
     
            >= 90             A-, A          90 <= A- < 93      
                                             93 <= A  < 100
                                                  
            >= 80 & < 90      B-, B, B+      80 <= B- < 83  
                                             83 <= B  < 85  
                                             85 <= B+ < 90  
                                            
            >= 70 & < 80      C-, C, C+      70 <= C- < 73
                                             73 <= C  < 75
                                             75 <= C+ < 80
                                            
            >= 60 & < 70      D,  D+         60 <= D  < 65
                                             65 <= D+ < 70
                                             
             < 60             F                    F  < 60


How to succeed in Bio 240 Biostatistics

  ❶ Show up     ❷ Show up on time     ❸ Pay attention
  ❹ Take notes     ❺ Work hard     ❻ Ask questions
  ❼ Be honest, don't cheat     ❽ Practice, practice, practice



__________________


6   Textbooks


6.1   Required reading


6.2   Suggested


  • Verzani, John (2014) Using R for Introductory Statistics, 2nd ed. CRC Press, NY. 502 pages. $27 at Amazon. Dr. Verzani is a math Professor at College of Staten Island, CUNY.

  • Murrell, Paul (2019) R Graphics, 3rd ed. CRC Press, FL. 423 pages. $82 at Amazon. Paul Murrell is appreciated as the leading expert on R graphics and author of R packages, including grid which enables the packages lattice, ggplot2 and other advanced graphic environments. This comprehensive book is not for the fainthearted. However, his early chapters on base R graphics are fundamental, understandable and precisely demonstrated.

  • de Vries, A. and J. Meys (2015) R for Dummies, 2nd ed. John Wiley, NJ. paper, 418 pages. $19 at Amazon.

  • Navarro, Danielle (2015) Learning Statistics with R, Version 0.6. Creative Commons BY-SA license for free use. 613 pages. PDF download at:   https://learningstatisticswithr.com


6.3   Read online for free


books on Data, Graphs, Statistics, R programming

  • Chang, Winston (2019) R Graphics Cookbook Practical Recipes for Visualizing Data, 2nd ed. O’Reilly, CA. paper, 425 pages. $48 at Amazon. Read online for free at:   https://r-graphics.org

  • Long, J.D. and P. Teetor (2019) R Cookbook Proven Recipies for Data Analysis, Statistics, and Graphics, 2nd ed. O’Reilly, CA. paper, 579 pages. $41 at Amazon. Read online for free at:   https://rc2e.com

  • Wickham, H. and G. Grolemund (2017) R for Data Science Import, Tidy, Transform, Visualize, and Model Data. O’Reilly, CA. paper, 492 pages. $40 at Amazon. 2nd ed. in progress. Read online for free at:   https://r4ds.had.co.nz

  • Wickham, H. (2019) Advanced R, 2nd ed. Chapman & Hall/CRC, NY. paper, 604 pages. $42 at Amazon. Read online for free, at:   https://adv-r.hadley.nz/

  • Gillespie, C. and R. Lovelace (2016) Efficient R Programming a practical guide to smarter programming. O’Reilly, CA. paper, 222 pages. $24 at Amazon. Read online for free, at:   http://csgillespie.github.io/efficientR/

  • Grolemund, G. (2014) Hands-On Programming with R Write your own functions and simulations, O’Reilly, CA. paper, 230 pages. $26 at Amazon. Read online for free, at:   https://rstudio-education.github.io/hopr/

books on Reproducible Research and Interactive Apps

  • Xie, Y. (2015) Dynamic Documents with R and knitr, 2nd ed. Chapman & Hall/CRC, NY. paper, 294 pages. $40 at Amazon. Read online for free, at:   https://yihui.org/knitr/

  • Wickham, H. and Jenny Bryan (2023) R Packages Organize, test, document, and share your code, 2nd ed. O’Reilly, CA. paper. $60 at Amazon. Read online for free at:   https://r-pkgs.org/

  • Wickham H. (2021) Mastering shiny: build Interactive Apps, Reports & Dashboards, O’Reilly, CA. paper. 372 pages. $38 at Amazon. Read online for free at:   https://mastering-shiny.org

  • Xie, Y. (2016) bookdown Authoring books and Technical Documents with R Markdown. Chapman & Hall/CRC, NY. paper, 138 pages. $23 at Amazon. Read online for free, at:   https://bookdown.org/yihui/bookdown/

  • Xie, Y., A. Thomas and A.P. Hill (2017) blogdown Creating Websites with R Markdown. Chapman & Hall/CRC, NY. paper, 172 pages. $27 at Amazon. Read online for free at:   https://bookdown.org/yihui/blogdown/

  • Xie, Y., J.J. Allaire and G. Grolemund (2018) R Markdown The Definitive Guide. Chapman & Hall/CRC, NY. paper, 338 pages. $34 at Amazon. Read online for free, at:   https://bookdown.org/yihui/rmarkdown/


__________________


7   First reading assignment and other resources


7.1   Readings


Available as PDF files by my dropbox link:
https://www.dropbox.com/sh/qr1uowvfi8m0oae/AAC9oGH0KPmaYmU4y02MtKUZa?dl=0

Scan these 4 reading assignments

  1. Dalgaard, Peter (2008) — Ch 1. Basics,   Ch 2. The R Environment,   Ch 4. Descriptive statistics and graphics

  2. Murrell, Paul (2011) R Graphics. 2nd ed. — Ch 1. An Introduction to R Graphics,   Ch 2. Simple Usage of Traditional Graphics,   Ch 3. Customizing Traditional Graphics.
    This is not from his 3rd edition but content is nearly the same for these 3 chapters on base R graphics.

  3. Baldi & Moore (2009) The Practice of Statistics in the Life Sciences. — Ch 1. Picturing Distributions with Graphs,
    Ch 2. Describing Distributions with Numbers

  4. Sokal & Rohlf (1995) Biometry. 3rd ed. — Ch 2. Data in Biology,   Ch 4. Descriptive Statistics

Contributed by the R community, the R website (https://www.r-project.org/) has links for free books, pamphlets and information sheets.

__________________


7.2   Videos


Advice on learning to code to benefit your scientific career

Please watch this video at https://youtu.be/0L4CQUK--dA

In June 2021, the journal Nature presented a 60 minute Webcast on “Advice on learning to code to benefit your scientific career.” It had 3 speakers, Q&A, and R was emphasized along with Python. Much of what they discussed resonates with our learning path in Bio 240 Biostatistics.

Question: Do you know what FOSS stands for? I am proud to be a FOSS person.

__________________


Dr. Stephen Linn Chew.   How to Get the Most out of Studying

https://www.samford.edu/arts-and-sciences/directory/Chew-Stephen-Linn   – his website

__________________


Dr. Pardis Sabeti.   What is Statistics?

What is Statistics?   https://www.learner.org/series/against-all-odds-inside-statistics/what-is-statistics/   6 minutes

Designing experiments   https://www.learner.org/series/against-all-odds-inside-statistics/designing-experiments/   11 minutes. In Bio 240 we shall analyze data from observational studies as well as from experimental studies

Summary   https://www.learner.org/series/against-all-odds-inside-statistics/summary/   6 minutes


Stem plots   https://www.learner.org/series/against-all-odds-inside-statistics/stemplots-2/   11 minutes

Histograms   https://www.learner.org/series/against-all-odds-inside-statistics/histograms/   9 minutes

Boxplots   https://www.learner.org/series/against-all-odds-inside-statistics/boxplots/   9 minutes

Scatterplots   https://www.learner.org/series/against-all-odds-inside-statistics/scatterplots/   8 minutes


Measures of center   https://www.learner.org/series/against-all-odds-inside-statistics/measures-of-center/   8 minutes

Standard deviation   https://www.learner.org/series/against-all-odds-inside-statistics/standard-deviation/   9 minutes

Confidence intervals   https://www.learner.org/series/against-all-odds-inside-statistics/confidence-intervals/   10 minutes


Normal calculations   https://www.learner.org/series/against-all-odds-inside-statistics/normal-calculations/   12 minutes

Normal curves   https://www.learner.org/series/against-all-odds-inside-statistics/normal-curves/   12 minutes

Checking assumption of normality   https://www.learner.org/series/against-all-odds-inside-statistics/checking-assumption-of-normality/   10 minutes


Sampling distributions   https://www.learner.org/series/against-all-odds-inside-statistics/sampling-distributions/   12 minutes

Random variables   https://www.learner.org/series/against-all-odds-inside-statistics/random-variables/   11 minutes
Featuring the NASA Challenger disaster of 1986 caused by O-ring failure

Tests of significance   https://www.learner.org/series/against-all-odds-inside-statistics/tests-of-significance/   16 minutes

Small sample inference for one mean   https://www.learner.org/series/against-all-odds-inside-statistics/small-sample-inference-for-one-mean/   12 minutes

Comparing two means   https://www.learner.org/series/against-all-odds-inside-statistics/comparing-two-means/   11 minutes Featuring research by a CUNY Professor at Hunter College

One-way Anova   https://www.learner.org/series/against-all-odds-inside-statistics/one-way-anova/   12 minutes


Correlation   https://www.learner.org/series/against-all-odds-inside-statistics/correlation/   10 minutes

The question of causation   https://www.learner.org/series/against-all-odds-inside-statistics/the-question-of-causation/ 14 min Smoking and lung cancer

Fitting lines to data   https://www.learner.org/series/against-all-odds-inside-statistics/fitting-lines-to-data/ 10 minutes

Inference for regression   https://www.learner.org/series/against-all-odds-inside-statistics/inference-for-regression/ 13 minutes History of DDT and bird eggs


Introduction to probability   https://www.learner.org/series/against-all-odds-inside-statistics/introduction-to-probability/ 11 minutes

Probability models   https://www.learner.org/series/against-all-odds-inside-statistics/probability-models/ 10 minutes

Binomial distributions   https://www.learner.org/series/against-all-odds-inside-statistics/binomial-distributions/ 11 minutes

Inference for proportions   https://www.learner.org/series/against-all-odds-inside-statistics/inference-for-proportions/ 10 min

Inference for two-way tables   https://www.learner.org/series/against-all-odds-inside-statistics/inference-for-two-way-tables/ 10 minutes Dr. Sabeti’s lab work

Glossary   https://www.learner.org/series/against-all-odds-inside-statistics/glossary/


Note: The viewing order for Dr. Sabeti’s short, statistics videos is not that important. Each is introductory, quasi-independent and each uses real-world examples. There are 36 units, some with PDF transcript downloads. Units 34-36 are interactive applications. Interestingly, there is no coverage of effect size. As time allows, you may profit from engaging these 36 units that are optional for Bio 240.


Dr. Pardis Sabeti

She is a physician scientist, computational geneticist, prominent Ebola, Lassa fever and Covid-19 researcher, Professor at Harvard University and an Iranian American. She earned the PhD from Oxford University and MD from Harvard University.

What is Statistics is just one from the Against All Odds: Inside Statistics series of videos, all of which are short, excellent and with transcripts available as .pdf downloads.

https://www.sabetilab.org/pardissabeti/     – Her lab’s website

https://www.hsph.harvard.edu/pardis-sabeti/   – Professor Sabeti, Harvard T.H. Chan School of Public Health

https://oeb.harvard.edu/people/pardis-sabeti   – Professor Sabeti, Harvard Depart. Organismic & Evolutionary Biology

https://en.wikipedia.org/wiki/Pardis_Sabeti   – Wikipedia

https://www.hup.harvard.edu/catalog.php?isbn=9780674260474&content=toc – her 2021 book:
OUTBREAK CULTURE – The Ebola Crisis and the next epidemic

Free download: https://get.adobe.com/reader/ but I suggest not selecting any of the other ‘free’ offers in the dialog box.

__________________


Videos by the American Statistical Association

https://www.amstat.org/    (ASA Student membership is only $25 per year)




Some Speakers in the above, American Statistical Association (ASA) videos.

__________________


Dr. Talithia Williams

https://www.hmc.edu/mathematics/people/faculty/talithia-williams/ – Professor Williams, Harvey-Mudd College, CA

https://www.talithiawilliams.com/ – Professor Williams web page

https://www.talithiawilliams.com/book – Her latest book:   Power in Numbers, The Rebel Women of Mathematics

https://www.thegreatcourses.com/talithiawilliamsLearning Statistics: Concepts and Applications in R , 24 videos, $40


Own Your Body’s Data – 17 minute TED talk, February 2014

https://youtu.be/TDCYJ3_gx2w

__________________


Dr. Hans Rosling (1948 - 2017)

He invented “bubble graphs” which are 2D scatterplots that display 5 variables. He was Professor of International Health at Karolinska Institute, Sweden.

https://en.wikipedia.org/wiki/Hans_Rosling – Wikipedia biography

__________________


Video from The BBC and The Open University

When can you trust statistics? The modern world is littered with statistical noise. Here’s how to find the signal. 4:50 minutes
https://youtu.be/aPh3E8IoHzk

This video does not deal with Statistics from a scientific point of view. Rather, it examines how we as individuals in everyday life, may view and interpret Statistics as reported in the media across all topics, e.g., socio-economic, political. They promote:   be Calm and be wary of your Emotions, get Context, be Curious and consider the Source of the Data and of the Statistics. This advice also makes good sense for researchers on the bench, dealing with their own data and statistics.

__________________



8   Course units



  1. Getting started in base R with coding, data and graphs. Download latest version of R (https://www.r-project.org); I will demonstrate. I will also demonstrate how to install some of the packages beyond base R, that we will use in class, e.g., ISwR, psych, pwr, DAAG, DescTools, ellipse, gplots, hexbin, lattice, MASS, MVN.

    Learn interactive use of R Console, the R Editor and Graphics Window. Learn to call functions. Create foo.R R Editor files and foo.pdf graph files. Create well structured, readable, R Editor files (R programs) with comments, spacing, indentation, and the wise naming of variables and objects. Store data in R Editor files as vectors and data frames.
    Graphs: simple line graphs, point and line graphs, scatter plots, text annotation of graphs. Add your personal time stamp to graphs. We begin the course with small x, y data sets that are easy to understand.

    Across Bio 240 we create   3 types of graphs :
  • draft quality
  • presentation quality
  • publication quality

    Switching between these graph types is by the extremely important and standard practice :
    to comment in and to comment out lines of code, as we submit code chunks and call R functions.

  1. Univariate data, descriptive statistics, confidence intervals. Data visualization, descriptive statistics, normal distribution, central limit theorem, confidence intervals (traditional & bootstrap), Monte Carlo data simulation. Read/write .csv files.
    Graphs: histograms, kernel density estimates, histogram with normal fit, text annotation of graphs, EDA graphs.

  1. One-way data: Anova & related topics. Assess Anova assumptions; effect sizes (R-square, Variance Components, Cohen’s D); Confidence Intervals; t-tests; statistical power analysis (traditional and bootstrap); multiple comparisons following a significant Anova (planned, Tukey HSD, Dunnett’s test, Holm-Bonferroni method); nonparametric bootstrap Confidence Intervals evaluated by percentile method and BCA; permutation Anova; Kruskal-Wallis test; Wilcoxon test; Bayes Factor Anova; Monte Carlo data simulation. Save/load native R binary objects.
    Graphs: boxplots, means with error bars (SD, SEM, CI), EDA graphs.

  1. Computationally intensive methods. R code for permutation tests, nonparametric bootstrap confidence intervals, bootstrap power curves, Monte Carlo data simulation (hypothesis testing & learning), Bayes Factor (Anova, correlation, regression). Code benchmarking for speed. Parallel multicore computation.
    Graphs: visualization of the re/sampling process, performance and results of computationally intensive methods.

  1. Correlation. Parametric, nonparametric, assumptions, statistical power, bootstrap, permutation, data simulation, Bayesian approaches, distance (energy) correlation, outliers, clusters, leave-one-out analysis.
    Graphs: scatterplots with confidence ellipses, with lowess fit; 2D kernel density estimates (Bayesian and empirical); hexagonal binning, 3D graphs, EDA.

  1. Demonstrations. Multivariate visualization & analysis; coding for modal dialog boxes and flow chart diagrams; code bench marking & profiling; graph animation by GIF; parallel multicore & NVIDIA GPU computing. Multipurpose Monte Carlo data simulation for teaching and research. Strategies for memory and performance (time) issues in computationally intensive procedures with big data on small machines. Demonstration of lattice, ggplot2, plotly and other graphic systems beyond base R graphics. Reproducible Research demonstrations using R Markdown.

  1. Reproducible research using R Markdown. Getting started in literate programming with interactive HTML documents (web apps) that combine R code, data, results, graphs and prose. Indeed, this Syllabus is a plain text, R markdown file (.Rmd) that was rendered into a HTML file by Markdown, Knitr and Pandoc. I will demonstrate this process in class, as time allows. This will be our only use of RStudio (https://rstudio.com) the popular and powerful, yet overly complicated, IDE (Integrated Development Environment) that handles languages including R, Python, HTML, CSS, C++, JavaScript, LaTex, and more. RStudio promotes a dialect of R (the tidyverse) while my mission in Bio 240 is to get you started in base R. ——————————————————————————– This HTML syllabus file runs on any web browser on any operating system and does not require R to be installed on the computer in question. I realize all this sounds complicated but it’s the wave of the future and I can get you started on this Optional material, by providing templates and demonstrations.



Increasingly, R and its larger environment, interact well with other programming languages (e.g., C++, Python, Julia, SQL), commercial applications (e.g., RStudio, Amazon AWS) and graphical systems (e.g., JavaScript).




__________________



9   Learning goals

R
data
graphs
statistics
writing about the results

  1. Data-driven ability to use statistical reasoning in Biology by computer programming in R.

  2. Store, edit and manipulate data in standard formats and visualize in publication quality graphs using R. Read and write, standard .csv files of row-by-column data.

  3. Perform statistical analysis (traditional, computationally intensive, Bayesian) and express results as tables, graphs and writing appropriate for scientific journals.

  4. Ability to call R functions, deal with function arguments and interact with the objects returned by functions. Create, debug and run, well-structured and readable, R Editor files ( .R ,   i.e., R programs). Optional : Create new R functions as convenience wrappers for extant functions in R; create new R functions for new tasks.

  5. Write critical, statistical reviews of scientific journal papers relative to tables of statistics, graphs and their legends.

  6. Optional: Entry level ability in reproducible research using R Markdown to make small, HTML documents that combine R code, data, results, graphs and writing. RStudio makes this process tractable, albeit with a learning curve. I will demonstrate in class and provide templates. This is our only use for RStudio. For everything else in Bio 240, we use R (R Console, R Editor, R Graphics Window) because I want you close to the language itself, not to a commercial IDE that promotes a dialect of R.



After each Biostatistics class
  ask yourself these 3 questions

      ▶ What is the most important thing your learned?

      ▶ Name one thing you did not understand.

      ▶ What question remains in your mind?

🦁



10   Academic Integrity and Disability Statement


Academic Integrity Statement :   Lehman College School of Natural and Social Sciences. I will email it for you to consider and optionally, to return by email to me. It is a form fill PDF file.

Rather fail with honor than succeed by fraud   —   Sophocles (b. 497, d. 406 BC)

In Bio 240 you are on your personal honor to take Tests without cheating. To cheat is to give or to receive answers or help. The use of generative A.I. is cheating. Cheating is immoral, it is a sin. It can get you expelled from the College. Don’t do it, it’s not worth the consequences.

Cheating destroys career development. For instance, cheating vitiates letters of recommendation. Faculty may refuse to write a letter or may write a negative letter.

Remember, a recommendation letter for graduate school or professional school is evaluated several ways, including as a character reference. By definition, a cheater is a person of low character and graduate schools do not want this kind of person in their program, whether MS, PhD or MD.

Ask yourself : Do you want your child to be treated by an MD or taught by a Teacher, who cheated his or her way through college, graduate school and medical school?


Student Disability Statement :   “Lehman College commits to providing access to programs and curricula to all students. Students with disabilities who need classroom accommodations should register with Office of Student Disability Services, Shuster Hall room 238, 718-960-8441.”

__________________



11   Academic schedule, Spring 2023


11.1   General Information

Fall 2023   Undergraduate Academic Calendar   —   Lehman College,   City University of New York,   Bronx NY 10468


  Friday August 25                      --- Fall 2023 classes begin  
  
  September 1 thru 14                   --- Withdraw (grade of WD) period
                                                          
  Monday September 4                    --- College Closed, no classes; Labor Day
      
  September 15 thru 17                  --- no classes; a religious holiday
      
  September 24 thru 25                  --- no classes; a religious holiday
  
  Monday October 9                      --- College Closed; Columbus Day
                                                        
  Tuesday October 10                    --- All Classes follow a Monday schedule
  
  Wednesday November 22                 --- no classes
  
  November 23 thru 26                   --- no classes; Thanksgiving Holiday
  
  Monday December 11                    --- Last day of Classes & "W" grade deadline
  
  Tuesday December 12                   --- Reading Day
  
  Wednesday December 13                 --- Reading Day
                                            
  Thursday Dec. 14 thru Wed. Dec. 20    --- Final Examinations at Lehman College


11.2   FRIDAY Section, Bio 240

Friday pm section:   2 pm - 5:50 pm


  Friday Aug. 25  --- Class 1 ---  Get started in base R: coding, data, graphs, statistics I

  Friday Sept. 1  --- Class 2 ---   "     "      "     "     "     "     "         "      II

  Friday Sept. 8  --- Class 3 ---   "     "      "     "     "     "     "         "     III
      
  Friday Sept. 22 --- Class 4 ---   "     "      "     "     "     "     "         "      IV
  
  Friday Sept. 29 --- Class 5 ---  TEST 1
                           ___________________________________________


  Friday Oct. 6  --- Class 6 ---  ANOVA: concepts, history, calculations, Anova Table, F-
                                      distribution, significance test, assumptions, writing

  Friday Oct. 13 --- Class 7 ---  ANOVA: effect size (R-sq, Cohen D, Variance Components),
                                      Confidence Intervals by t-distribution & bootstrap,
                                      statistical power analysis: traditional & bootstrap

  Friday Oct. 20 --- Class 8  ---  Continued,...

  Friday Oct. 27 --- Class 9  ---  Multiple Comparisons following a significant Anova,
                                      planned vs. unplanned comparisons, Tukey HSD, 
                                      pairwise t-tests, Dunnett's Test, 
                                      Holm-Bonferroni method, graphical visualization

  Friday Nov. 3  --- Class 10 ---  Kruskal-Wallis & other nonparametric methods, Bayes
                                      Factor Anova, Permutation tests, Monte Carlo data
                                      simulation, graphical visualization of one-way data,
                                      writing about statistical & graphical results

  Friday Nov. 10 --- Class 11 ---  Continued,...


  Friday Nov. 17 --- Class 12 ---  TEST 2
                           ___________________________________________


  Friday Dec. 1   --- Class 13 --- Correlation, graphical visualization, related topics I

  Friday Dec. 8   --- Class 14 ---   "            "         "              "       "   II

  Friday Dec. 15  --- Class 15 --- TEST 3.  The Final Exam for FRIDAY Section  

Note:   Days for Test 1 and Test 2 are subject to change. Test topics are subject to change.


__________________


12   Welcome to Bio 240. Biostatistics

12.1   Introduction


Bio 240 is a required course for the Biology BS degree but not for the Biology BA.
But, changes are pending for the Biology BS to enable course substitutions for Bio 240.


Show up, show up on time, pay attention, take notes, work hard, ask questions, be honest & don’t cheat, plus practice, practice, practice,   and Bio 240 will enhance your professional career development far beyond being merely a required course. I have student case studies over the decades, to back this claim.


We meet the first class for the full period, so be prepared to work, to listen and to code collaboratively with me, in class.

Use your laptop or desktop computer for Zoom meetings. Phones, ipads and Chrome books handle Zoom but cannot run R.

Bio 240 is based on R and requires you to use R, for data analysis and graphics.

R runs well on Linux e.g., Ubuntu, but the look and feel is different so don’t use a Linux machine unless you’re somewhat comfortable at the command line of the Linux terminal and you’re willing/able to understand my projected, Windows coding in R during class, into same, in some third party text editor, say Notepad++ in Linux or Ubuntu’s native text editor or the Linux version of RStudio.

I routinely program R in Ubuntu using Notepad++ as text editor (instead of R Editor which doesn’t exist on the Linux side) and enjoy the speedup relative to running R on a Windows machine, other factors being equal.


Is Bio 240 a course in introductory statistics or a course in computer programming? It’s both, because these skills are needed by researchers in biology, in medicine and across all the sciences.


If you have experience in any computer programming language you will immediately take to R, find it easy, and enjoy the readable code.

If you have no programming experience then get over it, and get started in this class with R, as you advance your career development.


Coding in R is easier than you might think and it’s my job to make it so. For instance, in recent semesters among the coding neophytes in Bio 240, I brought several students in each section, up to Biology Doctoral student level in terms of statistics and programming in R. This semester you can achieve the same, if you work hard.


Whether one has had a statistics course before or not, seems to make little difference in Bio 240. Likewise for Calculus. In Bio 240 we use basic algebraic and symbolic thinking while letting R do the heavy lifting.

Disturbingly in recent semesters, some students did not know how to move files off and onto their hard drives using Lehman email and USB ports (e.g., USB flash drive). Others did not know the name or location of their working directory or what a working directory is.

Many refused to, or could not use their computer the way a scientist uses a computer – for instance, all apps out of RAM except the one being used, R in our case – and suffered OS freeze or glacial slowness, as a result. Also, avoid having multiple instances of R or it will eventually crash. Avoid docking R windows else confusion may ruin your R Session. An R Session is the period of time from when you open R to when you close R.

Many had trouble creating, naming and saving computer files properly and this is a serious issue during a Test, and in real life.

Please note that Windows machines must be configured so the user can know and “see” the full name of all files else one has difficulty reading files into R and trouble properly naming files. The default Win setting “hides” file extensions, like .csv, .R, .pdf. Mac OS assumes humans are smart enough to handle seeing the complete file name so it displays the complete file name, wisely. The file name includes the extension, e.g., foo.csv and foo.R are complete file names while foo is not.

If your Windows machine does not show you the complete name of any and all files, then do the following. Go to Settings to Update & Security to For developers to File Explorer, then make sure to click, such that the settings will show file extensions. Now you will see the full name of every file and you can write code in R to name/read/write files successfully and properly.

Obviously, all college students own laptop or desktop computers. Should you be in the market for one I can provide advice based on my 50+ years using computers. Be advised that Bio 240 does not require an expensive laptop computer but it cannot be Chrome OS because Chrome can’t run R.

Everything in Bio 240 runs on my old $169 ASUS laptop (11.6”, Win 10, 2 core Centrino CPU, 4 gb RAM). Although I was responsidle for bringing the first Apple computers to this campus in 1979, Macs are over-priced and more difficult to use and to maintain than Windows machines, at the present time; nevertheless, if you know how to use one like a scientist uses a computer, then Macs are fast and reliable, albeit too expensive.

As you know, the College is makes some laptops available to students during the pandemic – see your emails from the College on how to request one. Relative to Bio 240, avoid iPads and Chrome machines because they don’t run R, but they are Zoom compatible. I realize that a Chrome machine or iPad would be handy for courses other than Bio 240.


12.2   The Iceberg Teaching Model


Newfoundland, Canada

Newfoundland, Canada


The top of an iceberg looks large but it’s small compared to the bottom of the iceberg.
What’s more important, the top or the bottom?

I learned this firsthand in the 1970s in Newfoundland Canada. I recklessly scrambled over the edge of massive coastal boulders to inspect and touch a jostling iceberg fragment the size of a small house, that calved off the gigantic parental iceberg further out in the bay.

Icebergs look white. But, I was astonished that up close, the ice was crystal clear and mysterious, as I peared deeply within and pondered where it came from, how old it was, where it was going and how long it would last.

In Bio 240, of course there is required material reflected in Tests. And, I will expose you to much more — to the optional bottom of the iceberg for those pushing career development farther and faster than merely earning the grade of A or B.

Periodically across the term I’ll demonstrate a particular statistical method, a different type of graph or delve into some R coding strategy while announcing it’s bottom of the iceberg \({ }\) meaning optional. Some extra credit questions on tests might reflect the bottom of the iceberg.

Distribution of grades

The graph below, created in R, is a density histogram with kernel density estimate, of the final average grades for Spring 2020. Notice the peaked central tendency (positive kurtosis) and the heavy left-hand tail (negative skewness), relative to a normal distribution.

Don’t worry about understanding the graph and the descriptive statistics right now, because we will develop these things in detail, in class.


The two graphs below, visualize the distribution of final grades in Bio 240 for the Friday and Saturday sections, Fall 2022. The final average is the mean of the 3 Tests. I added 10 points to the final average of each student, as indicated on the graphs.

Notice that by the last day of class, n=10 had dropped from the Friday section with the “W” grade; and n=13 dropped from the Saturday section, all due to very low test grades. As a result, 85% earned A or B in the Friday section while 76% earned A or B in the Saturday section.

Interestingly, the median final grade (50th percentile) was nearly identical between the 2 sections: 90.88 for Friday, 90.97 for Saturday. The left graph is a boxplot and on the right, a kernel density graph. These graph types (histogram, boxplot, kernel density) are extremely common in scientific journal papers and you will become expert in coding for them in R.



__________________


13   Using R is easier than you might think



A proven way to begin learning R is to engage the simplest type of numeric data: \({ }\) the univariate. In other words, single samples of numeric data whether real data or simulated data. By engage I mean — how to type and store it in R code, how to read it in from an external file, how to manipulate it, how to graph it, how to analyze it statistically.

Indeed, this is exactly how I got started teaching myself R, years ago. After reading about R in the 2004, first edition of our textbook by Prof. Peter Dalgaard, I reasoned that if I could store small, numeric samples in an R Editor file, get descriptive statistics for these samples, as well as graphs like histograms, then I could probably move forward to handling and analyzing more complicated data sets in R. I did and you can to.

It’s not rocket science but it does require patience, copious practice, attention to detail, the ability to engage R coding in trial-and-error fashion plus observing our rules and conventions for building and debugging, clean, readable, well-structure and wisely commented code, as opposed to dreaded ugly code that’s hard to read, change, print and debug.

In class, we mostly use R to graph and analyze real data, and data that’s largely biological.

But, there’s enduring value in learning early on, how to create and use, fake data. The word fake might be misleading; here, it’s shorthand for: Monte Carlo data simulation from theoretical probability distributions. Early in this Section we use simulated data from the normal probability distribution. Then, we move into one-way data (merely sets of single samples) that’s simulated data as well as real data.


As engaging and meaningful as it is in its own right, writing code is not doing statistics.
One of the big advantages of working with R is that you can do quite bit of statistics with just a handful of functions and the simplest syntax. R is a tool that helps you keep moving forward. If you want to see something then plot it. If the data are in the wrong format, then mutate it.
John Chambers   2014 Keynote Address   UserR!


13.1   base R


Sorry, your browser does not support inline SVG. base R "base R" is what you get when R is installed! And, it includes around 15 packages ‑‑ utils, base, graphics, stats, stats4, grid, boot, grDevices, tools, tcltk, splines, parallel, methods, datasets, compiler.   Thousands of CRAN packages operate within base R.   In my opinion, it's best to learn base R first, before learning its dialects (e.g., RStudio, the tidyverse) and before learning other R graphical environments (e.g., grid-graphics, Lattice, ggplot2, plotly).   All agree base R contains more than can be taught in any, full year statistics course.

13.2   Univariate data

13.2.1   Get random sample from Normal Distribution

The line of R code below, y1 <- rnorm(60, 50, 9) draws a random sample of n=60 from the normal distribution of mean 50 and standard deviation 9.

Note the assignment operator <- that we use in R, not the equal character =.   But, we do use the equal sign for arguments in function calls.

Early on as you’re learning R, it pays to get comfortable generating fake data: \({\ }\) random draws from say, the normal distribution rnorm() , which is bell-shaped, the uniform distribution runif() , which is flat-topped, and the Weibull distribution rweibull() which is truncated on the left and skewed to the right.

I cannot be more serious. Generating and using fake data is not just a technique, it’s a way of life for the analyst!

It enables one to get numbers to explore and to learn a function in R, to test/verify/learn/compare competing statistical procedures, and to address questions about our observed data, such as, what might happen if I repeated many times, my data sampling design (by a similar sampling design in Monte Carlo) and statistical analysis sequence?

set.seed(123) # seed random number generator, for repeatability, as desired

# get 60 random numbers from normal distribution of mean 50, SD 9; assign to y1
y1 <- rnorm(60, 50, 9) # >?rnorm  for html documentation

y1  # print the sample at R Console
##  [1] 44.95572 47.92840 64.02837 50.63458 51.16359 65.43558 54.14825 38.61445
##  [9] 43.81832 45.98904 61.01674 53.23832 53.60694 50.99614 44.99743 66.08222
## [17] 54.48065 32.30045 56.31220 45.74488 40.38959 48.03823 40.76596 43.43998
## [25] 44.37465 34.81976 57.54008 51.38036 39.75677 61.28433 53.83818 47.34436
## [33] 58.05613 57.90320 57.39423 56.19776 54.98526 49.44279 47.24634 46.57576
## [41] 43.74764 48.12874 38.61143 69.52060 60.87166 39.89202 46.37404 45.80010
## [49] 57.01969 49.24968 52.27987 49.74308 49.61417 62.31742 47.96806 63.64824
## [57] 36.06122 55.26152 51.11469 51.94347

This is not the place for a formal treatment of the Normal Distribution, the most important probability distribution in all Statistics, although a brief introduction follows.

The Normal Distribution is defined by 2 parameters: its mean, \({mu}\) and Standard Deviation, \({sigma}\). It’s a continuous distribution, symmetrical about its central tendency. The so-called, standard normal distribution N(0, 1) has mean=0 and SD=1. Our fake data y1 is a random sample from N(50, 9), using standard notation.

\[\begin{align*} The\ PDF\ of\ the\ normal\ distribution:\ \ \ f(x) &= \frac{1}{\sqrt{2\pi\sigma^2}} e^{ - \frac{(x - \mu)^2} {2\sigma^2}} \\[1ex] \end{align*}\]

Click for more information on the Normal Distribution – click again to remove

The Normal Distribution is a continuous distribution extending from negative infinity to positive infinity, asymptotically. Its shape is symmetrical on either side of its mean. The mean, mode and median are the same number. Some call it the “bell-shaped” curve. The formula for the PDF (Probability Distribution Function) of the normal distribution is presented above — elsewhere, we develop various graphical visualizations and assessments of normality, using our custom R code as well as by calling functions from R packages.

The Normal Distribution is the most important distribution in all Statistics. There are important reasons why. First, many continuous measurement variables are normally distributed, such as human height. Second, the Central Limit Theorem holds that as sample size increases, the distribution of the sample means becomes normally distributed thus allowing traditional, 95% Confidence Intervals for population means to be calculated based on a single observed mean, using its Standard Error (SD/sqrt(n)) and the t-distribution. Third, many traditional, parametric statistical procedures (e.g., t-test, Anova, OLS linear regression, Pearson correlation) have assumptions, and one of these is that the observed data are normally distributed.

Mathematically and causally in the physical world, what makes a response variable normally distributed?

Think about human height – what causes it?
Obviously, there are environmental variables such as socio-economics, nutrition (its timing, quality, quantity) and there are genetic variables (many genes plus gender).

In brief, many causal factors each with small, additive effects and each factor independent of the others, generate a normal distribution. In math, the expansion of the binomial distribution generates the normal distribution, by the same process. Galton’s “bean box” from the late 19th Century, demonstrates this mechanically by machine but we will use a GIF animated simulation in R, using the “animation” package.

All statistics textbooks deliver solid treatments of the normal distribution, as well as say, Wikipedia, https://en.wikipedia.org/wiki/Normal_distribution



13.2.2   Descriptive Statistics


Recovering a standard set of descriptive statistics is always an early task in data analysis, and there are many different ways to do it. The describe() function in the psych package is handy. CRAN package psych is by Professor William Revelle, Department of Psychology, Northwestern University. His package has many functions. At the R Console, > ?describe brings up HTML documentation, in a format standardized across all funs in all CRAN packages. As an aside, we often abbreviate fun for function, arg for a function argument and foo for a dummy name say, foo.R as a generic R Editor file.

From its documentation, the describe() fun has these args, but here, we need only one arg, the first arg, which is the name of the univariate sample (numeric vector in R). In all R funs the most important args are listed first; args often have default values. When learning how to use a fun that’s new to us, we always begin with a minimal call to that function and explicitly add args to the fun call, as needed. Here, we need only one arg: y.

describe(x, na.rm=TRUE, interp=FALSE, skew=TRUE, ranges=TRUE, trim=.1, type=3, 
           check=TRUE, fast=NULL, quant=NULL, IQR=FALSE, omit=FALSE, data=NULL)

Round-off may be controlled if the object returned by describe() is printed using print() which is an extremely important and flexible, function in base R.

library(psych) # load package from hard drive, into memory at R Console
## Warning: package 'psych' was built under R version 4.2.3
describe(y1) # a fun in package 'psych'
##    vars  n  mean   sd median trimmed  mad  min   max range skew kurtosis   se
## X1    1 60 50.59 8.19  50.19    50.5 7.73 32.3 69.52 37.22 0.08    -0.46 1.06
print(describe(y1), digits=3) # print() is an important function in base R
##    vars  n   mean    sd median trimmed   mad  min    max range  skew kurtosis
## X1    1 60 50.591 8.193 50.189  50.505 7.728 32.3 69.521 37.22 0.082   -0.462
##       se
## X1 1.058

Alternatively, most R users write their own short functions for many things, including descriptive statistics. One of mine is new.stats() as defined in my, K funs UNIVARIATE.R an R Editor file of function definitions. The norm.test argument in the call to new.stats() turns on a batch of goodness of fit tests of normality, to inform the curious analyst.

new.stats(y1, data.name="sim data") # from: K funs UNIVARIATE.R
##               sim data
## N               60.000
## Mean            50.591
## SD               8.193
## CV%             16.195
## Min             32.300
## Max             69.521
## skew             0.082
## kurtosis        -0.462
## SEM              1.058
## LB.95%CI.mean   48.474
## UB.95%CI.mean   52.707
## Median          50.189
## 25th            45.558
## 75th            56.226
## IQR             10.668
new.stats(y1, norm.test=TRUE) # add normality tests
## $statistics
##                   y1
## N             60.000
## Mean          50.591
## SD             8.193
## CV%           16.195
## Min           32.300
## Max           69.521
## skew           0.082
## kurtosis      -0.462
## SEM            1.058
## LB.95%CI.mean 48.474
## UB.95%CI.mean 52.707
## Median        50.189
## 25th          45.558
## 75th          56.226
## IQR           10.668
## 
## $goodness.of.fit.tests.for.normality
##                                     p-value
## Shapiro-Wilk test                 0.9800224
## Robust Jarque-Berra test          0.8098829
## Anderson-Darling test             0.9791136
## Cramer-von Mises test             0.9742690
## Shapiro-Francia test              0.9930478
## Pearson test                      0.9301044
## D'Agostino test                   0.7708575
## Anscombe-Glynn test               0.6995321
## Bonett-Seier test                 0.8212358
## Kolmogorov-Smirnov test           0.9949754
## Lillifors Kolmogorov-Smirnov test 0.9583959


Descriptive Statistics Recovering a standard set of descriptive statistics for one or more samples, marks a beginning of statistical analysis. Descriptive stats are always reported in tables and/or in prose. At least 3 stats must be reported -- sample size, a stat of central tendency, a stat of variability. These may include on the moments side: n, mean, SD (or SEM) and on the quantile side: n, median, IQR. Other descriptive stats include min, max, Coefficient of Variation (CV = SD/mean), skewness (3rd moment, asymmetry) and kurtosis(4th moment, peakedness). "Descriptive statistics" lead to Effect Sizes, Confidence Intervals, and to significance tests or Bayesian analyses.

13.2.3   Histogram — visualization of the shape of the data

Let’s use a histogram to visualize the above sample y1 of n=60.

The histogam is a graph that’s well known and understood by all educated folks across all scholarly disciplines, worldwide. It’s taught in grade school.

Histograms are as instantly recognized as say, the words DNA and Homo sapiens. No matter the scientific journal or how advanced the topic of the research, histograms are used to visualize the distribution of the data.

I prove this point during class by showing you current issues of leading journals, including Science, Science Advances, PNAS, NEJM and Nature.

In statistics, what do we mean by a distribution? It’s the range of the data from the minimum to the maximum value; it’s the central tendency or peaks; it’s the dispersion of the data about the central tendency; it’s the data grouped into intervals spanning the range of the data. Histograms display the distribution of single samples of data.


For me, a histogram helps me see the “shape” of the data.


In R coding, Comments begin with the hashtag # and are ignored by R (code to the right of # is ignored). Comments are for the human. You will quickly learn to appreciate comments as you wisely lavish them on your code.

hist(y1) # frequency histogram of y1; minimal call to hist() which has many args
Distribution of y1 by a minimal call to hist( ), 'draft quality'

Distribution of y1 by a minimal call to hist( ), ‘draft quality’


The histogram above, graphs the tabular, “frequency distribution” which is calculated by a short function I wrote, freq.table() which extracts vectors from the hist() object. The function definition for freq.table() is listed below then the function is called and it returns a frequency distribution table for y1.


freq.table <- function(y=rnorm(1e2, 50, 10), roundoff=4, ... ){

  # -------------------------------------------------------------------
  #  ARGUMENTS     frequency distribution TABLE for a numeric vector
  #
  #  y         numeric vector for frequency distribution table
  #            missing values OK
  #
  #  roundoff  default: 4 decimal places
  #
  #  ...       args to hist() that's only used for extraction,  
  #                e.g., breaks=22, breaks="sturges", "scott", "fd"
  #
  #  Function RETURNS a data frame by EXTRACTION from hist() object  
  #  
  #  Note: for the bins, it's   > ... <=   'left open, right closed'
  #        function may be called devoid of arguments, as a DEMO
  #   
  #  AUTHOR: Dwight Kincaid, PhD   dwight.kincaid@lehman.cuny.edu
  # -------------------------------------------------------------------

  stopifnot(is.numeric(y), length(y) > 1)  # argument checking
  y <- y[!is.na(y)]                        # remove NA, missing values

  a <- hist(y, plot=FALSE, ...) # to extract from hist() object
  width    <- a$mids[2] - a$mids[1]                # Width of hist bins
  L.level  <- round(a$mids - (width/2), roundoff)  # vector: Lower bounds
  U.level  <- round(a$mids + (width/2), roundoff)  # vector: Upper bounds
  my.level <- paste(L.level, ",", U.level, sep="") # character vector

  N <- length(y) # N of response variable

  # frequency distribution table by extraction from hist() object 'a'
  dfr <- data.frame(interval  = 1:length(a$mids),
                    class     = my.level,  
                    midpt     = a$mids, 
                    FREQ      = a$counts,
                    rel.freq  = round(a$counts/N, roundoff),
                    cum.f     = cumsum(a$counts), 
                    cum.rel.f = round(cumsum(a$counts/N), roundoff),
                    density   = round(a$density, roundoff))

  return(dfr)   # data frame object returned 

} # end function definition


Continuing with y1 of n=60, let’s get the frequency distribution table for breaks=4 argument in the call to freq.table() which can pass arguments to hist() by its final, ... argument, often called dot-dot-dot.

# 'breaks' arg passed to hist() which may not deliver 'exactly' the breaks specified

freq.table(y1, breaks=4) 
##   interval class midpt FREQ rel.freq cum.f cum.rel.f density
## 1        1 30,40    35    7   0.1167     7    0.1167  0.0117
## 2        2 40,50    45   23   0.3833    30    0.5000  0.0383
## 3        3 50,60    55   21   0.3500    51    0.8500  0.0350
## 4        4 60,70    65    9   0.1500    60    1.0000  0.0150

Large sample sizes are not a problem for this function.

freq.table(rnorm(6e7), roundoff=8) # random sample of 60 million from N(0,1)
##    interval   class midpt     FREQ   rel.freq    cum.f  cum.rel.f    density
## 1         1 -6,-5.5 -5.75        1 0.00000002        1 0.00000002 0.00000003
## 2         2 -5.5,-5 -5.25       16 0.00000027       17 0.00000028 0.00000053
## 3         3 -5,-4.5 -4.75      162 0.00000270      179 0.00000298 0.00000540
## 4         4 -4.5,-4 -4.25     1684 0.00002807     1863 0.00003105 0.00005613
## 5         5 -4,-3.5 -3.75    11914 0.00019857    13777 0.00022962 0.00039713
## 6         6 -3.5,-3 -3.25    66875 0.00111458    80652 0.00134420 0.00222917
## 7         7 -3,-2.5 -2.75   291844 0.00486407   372496 0.00620827 0.00972813
## 8         8 -2.5,-2 -2.25   992429 0.01654048  1364925 0.02274875 0.03308097
## 9         9 -2,-1.5 -1.75  2643205 0.04405342  4008130 0.06680217 0.08810683
## 10       10 -1.5,-1 -1.25  5510111 0.09183518  9518241 0.15863735 0.18367037
## 11       11 -1,-0.5 -0.75  8996129 0.14993548 18514370 0.30857283 0.29987097
## 12       12  -0.5,0 -0.25 11484601 0.19141002 29998971 0.49998285 0.38282003
## 13       13   0,0.5  0.25 11482921 0.19138202 41481892 0.69136487 0.38276403
## 14       14   0.5,1  0.75  8994566 0.14990943 50476458 0.84127430 0.29981887
## 15       15   1,1.5  1.25  5512059 0.09186765 55988517 0.93314195 0.18373530
## 16       16   1.5,2  1.75  2644362 0.04407270 58632879 0.97721465 0.08814540
## 17       17   2,2.5  2.25   993882 0.01656470 59626761 0.99377935 0.03312940
## 18       18   2.5,3  2.75   292424 0.00487373 59919185 0.99865308 0.00974747
## 19       19   3,3.5  3.25    67017 0.00111695 59986202 0.99977003 0.00223390
## 20       20   3.5,4  3.75    11907 0.00019845 59998109 0.99996848 0.00039690
## 21       21   4,4.5  4.25     1685 0.00002808 59999794 0.99999657 0.00005617
## 22       22   4.5,5  4.75      188 0.00000313 59999982 0.99999970 0.00000627
## 23       23   5,5.5  5.25       18 0.00000030 60000000 1.00000000 0.00000060
Histogram Sorry, your browser does not support inline SVG. The histogram visualizes the frequency distribution table for a sample of numeric data. It reveals the "shape" of the data -- the center, the spread, the extremes, the peakedness, the asymmetry, and more.


13.2.4   Annotation of histogram

How hard would it be to annotate the above histogram with the sample mean and standard deviation, the p-value from Shapiro-Wilk test of normality, turn off the graph title, change the x-axis label, increase font size of the labels, rotate the y-axis labels, color the bars, and get rid of the black ink (sensu Edward Tufte) around the histogram bars? We use more arguments to our call of the function hist(). Function arguments are separated by commas. The mtext() and text() functions are handy for annotating graphs. Notice how I add a space after a comma in function calls; this is wise coding practice as it eases code editing and enhances readability; R does not need the space but the human does.

Functions and their arguments are small, reusable tools in R.


\({\Large\ To \ use\ R\ is\ to\ call\ functions\ }\) — John Chambers

m <- round(mean(y1), 2)           # get mean of y1 and round off to 2 decimals
s <- round(sd(y1), 3)             # get SD of y1 and round off
p <- round(shapiro.test(y1)$p, 3) # extract p-value, Shapiro-Wilk test of normality

hist(y1, 
     col="lightblue",    # color of histogram, default "lightgray"
     main=NULL,          # string for title of histogram; NULL omits it
     cex.lab=1.4, cex.axis=1.3, las=1,   # typography
     border="white",                     # color of lines around histogram bars
     xlab="Random sample from N(50, 9)") # x-axis label

clr <- "darkred" # color of text
mtext(paste("N =", length(y1)),           adj=.95, line= 0, cex=.91, col=clr)
mtext(paste("Mean =", m),                 adj=.95, line=-1, cex=.91, col=clr)
mtext(paste("SD =", s),                   adj=.95, line=-2, cex=.91, col=clr)
mtext(paste("Shapiro-Wilk test\np =", p), adj=.03, line=-1, cex=.91, col=clr)
Annotated histogram

Annotated histogram


13.2.5   Presentation quality histogram


A graph destined for a Poster or Presentation in class, at a scientific meeting or at an interview, often benefits from a graph title and by a small modest, personalized time stamp to denote credit/blame. Below is a call to hist() showing how to add the time stamp by a call to the mtext() function, using Arlo as investigator name.

While personalized time stamp and title are not appropriate for a publication quality graph, they are often desirable for a presentation quality graph.

Can you find Arlo’s personalized time stamp in the graph window below?

hist(y1, 
     col="coral", 
     border="white", 
     main="Preliminary Experiment #1",
     xlab="Random sample from N(50, 9)", 
     cex.lab=1.4, cex.axis=1.3, cex.main=2, col.main="black", las=1) # typography

# add time stamp, personalized
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.9, col="gray") 
Presentation quality histogram with personalized time stamp

Presentation quality histogram with personalized time stamp


Question: For graphs, what’s the difference between draft quality, presentation quality and publication quality? The answer concerns the structure of the graph itself, as well as the intended audience. In Bio 240 we use R to make all three types of graphs.


13.2.6   Kernel density estimate


Instead of a histogram, one may visualize the distribution of y1 by a kernel density estimate calculated by function density(). Below, we plot it using the workhorse graphing function in base R, plot().

dens <- density(y1) # get x,y coordinates of kernel density curve, fit to data y

plot(dens, xlab="Random sample from N(50, 10)", main="", col="red")
Kernel density estimate of the distribution of y1

Kernel density estimate of the distribution of y1


If desired, the kernel density estimate may be filled with a color using the polygon() function. The kernel density is a far more rigorous visualization of the distribution of a sample of data than the histogram. At the R Console, enter?density to view documentation for this function including its arguments, how it’s calculated and bibliographic references.

dens <- density(y1) # get x,y coordinates of kernel density curve fit to data

plot(dens, xlab="Random sample from N(50, 10)", main="")

polygon(dens, col="peru") # at R Console try > ?color for names of all 657 colors
Kernel density estimate, color filled

Kernel density estimate, color filled


13.2.7   Fit normal distribution to a sample


We could overlay the density histogram of y1 with the normal distribution PDF using the observed mean and standard deviation as its parameters. This is done to show the apparent normality of the observed data or to emphasize the lack of normality.

There are several ways to do this in R, I present one below.

Here, we expect our sample to be reasonably close to the normal PDF because the observed, n=60 is a random sample from the normal distribution. But we must remember that at relatively small sample size, random sampling often generates extremely unexpected distributions, not just in simulated data but in research data as well.

pts <- 250   # number of x,y points for the normal PDF curve

g <- hist(y1, plot=FALSE) # for plotting args

x <- seq(from=min(g$breaks), to=max(g$breaks), length=pts) # x-coord of normal PDF
y <- dnorm(x, mean(y1), sd(y1))                            # y-coord "   "      "

mx <- max(c(y, g$density))                     # get y-max for plotting

hist(y1, freq=FALSE, ylim=c(0, mx), main=NULL) # minimal, density histogram

lines(x, y, lwd=1.5, col="blue")               # add the normal PDF
Density histogram with normal fit

Density histogram with normal fit


Normal fit to density histogram This is commonly done on the research bench as well as in publication. For a perfectly normally distributed sample, the normal curve goes through the midpoint atop each histogram bar. This "normal fit" is not a formal test of normality, but remains a valued visualization of apparent departures from, or agreements with, normality.

13.2.8   EDA – exploratory data analysis


We often use EDA to help understand the data, to reveal something unforseen, to communicate to others and to stimulate research hypothesis generation.

EDA: Exploratory Data Analysis, was developed, if not created by John Tukey and associates in the 1970s. The influence of EDA on the entire field of statistics, remains profound. Analysts rely on EDA to learn about their data.

In data analysis, we often use this repeating loop :

\({\quad\quad \large\it {Research} \ {Hypotheses}\ \longleftrightarrow \ \Large \bf {E}\ {D}\ {A}\ \longleftrightarrow \ \large\it {Statistical} \ {Analysis/Modeling}}\)


My function EDA() in K funs UNIVARIATE.R makes the graphic window below, featuring graphs and statistical analyses, all to be taken as exploratory.

#source("C:\\Users\\dwigh\\Desktop\\K funs UNIVARIATE.R") # 'source' the file

EDA(y1, data.name="sim data, N(50, 9)") 
## Warning: package 'DescTools' was built under R version 4.2.3


13.2.9   Assess the normality of a sample

This is an interesting and diverse topic that benefits from statistical wisdom gained by experience in data analysis. It’s not the time nor place for a deep dive into it. Formerly, only traditional statistical hypothesis testing was used to answer the question, “are my data normally distributed as assumed by Anova?” Today, tests like the Shapiro-Wilk test of normality are still commonly reported.

Normal Quantile-Quantile plots have long been used to assess normality of observed data.

Increasingly, many place emphasis on the graphical visualization of an observed distribution versus simulated data of the same sample size, sampled from the normal distribution. I recently invented one such approach as seen below.

Below, see a visual assessment of the distribution of sample y1 relative to the normal distribution, using a novel function defined in my R Editor file: K funs UNIVARIATE.R

# Kincaid function using Monte Carlo data simulation to assess normality
Normal.kernel.band(y1, NS=500) 


13.3   One-way data

We simulate a one-way data set of 4 groups with total N=281. Two groups are random samples from the normal distribution (bell-shaped) and the other two groups are random samples from the uniform distribution (flat-topped).

A one-way data set is where a datum is classified by one criterion – its group membership. And, there can be any number of groups and any sample size per group.

We develop graphical visualizations and statistical analyses, both traditional, computationally intensive (permutation & bootstrap) and Bayesian (Bayes Factor Anova). Note that every time this .Rmd code is rendered in RStudio a different fake data set is generated because the set.seed() function is not used.

13.3.1   Multiple kernel density estimates

Another advantage of kernel density estimates over histograms is to visualize more than one distribution on the same graph, as we do below using simulated data (fake data) from the normal and uniform distributions. Plotting these 4 groups as histograms in the same graph would be an overlap mess.

set.seed(876)            # set seed for random number generator
x1 <- rnorm(50, 32, 5)   # sample from normal distribution     
x2 <- rnorm(51, 34, 7)   #                                    
x3 <- runif(100, 10, 45) # sample from uniform distribution   
x4 <- runif(80, 19, 30)  #                                 

x1 <- round(x1, 2); x2 <- round(x2, 2); x3 <- round(x3, 2); x4 <- round(x4, 2)

# organize our simulated, one-way data set into a DATA FRAME ----------------

response <- c(x1, x2, x3, x4) # numeric, response variable

# get grouping variable 
n <- c(length(x1), length(x2), length(x3), length(x4)) # vector of sample sizes
group    <- c(rep("x1", n[1]), rep("x2", n[2]), rep("x3", n[3]), rep("x4", n[4]))
group    <- factor(group, levels=c("x1", "x2", "x3", "x4")) # desired presentation order

sim.df   <- data.frame(response, group) # make data frame

str(sim.df)     # view structure of the object -- CHECKING
## 'data.frame':    281 obs. of  2 variables:
##  $ response: num  32.9 35.9 26.7 30.7 32.6 ...
##  $ group   : Factor w/ 4 levels "x1","x2","x3",..: 1 1 1 1 1 1 1 1 1 1 ...
summary(sim.df) # get simple stats -- CHECKING
##     response     group   
##  Min.   :10.21   x1: 50  
##  1st Qu.:23.31   x2: 51  
##  Median :28.82   x3:100  
##  Mean   :28.88   x4: 80  
##  3rd Qu.:34.12           
##  Max.   :54.23
head(sim.df)    # first 6 rows -- CHECKING
##   response group
## 1    32.85    x1
## 2    35.91    x1
## 3    26.68    x1
## 4    30.68    x1
## 5    32.57    x1
## 6    41.70    x1
tail(sim.df)    # last 6 rows -- CHECKING
##     response group
## 276    26.55    x4
## 277    22.42    x4
## 278    24.63    x4
## 279    23.94    x4
## 280    22.41    x4
## 281    27.67    x4
# some descriptive stats by some basic programming in R -----

n      <- tapply(response, group, length) # vector of sample sizes
Mean   <- tapply(response, group, mean)   # vector of means
SD     <- tapply(response, group, sd)     # SD
Min    <- tapply(response, group, min)    # minimum
Max    <- tapply(response, group, max)    # maximum
Median <- tapply(response, group, median) # median
iqr    <- tapply(response, group, IQR)    # IQR
CV     <- 100 * SD/Mean                   # Coefficient of Variation %
SEM    <- round(SD/sqrt(n), 4)            # standard error of the mean
Q1     <- tapply(response, group, quantile, probs=.25) # 25th percentile
Q3     <- tapply(response, group, quantile, probs=.75) # 75th    "

# stats per group ----- printed 2 different ways:  cbind() vs. rbind() ----
print(cbind(n, Mean, SD, CV, SEM, Min, Max, Median, iqr, Q1, Q3), digits=4) 
##      n  Mean     SD    CV    SEM   Min   Max Median    iqr    Q1    Q3
## x1  50 32.62  4.253 13.04 0.6015 23.14 44.17  32.67  4.153 30.12 34.28
## x2  51 33.82  5.577 16.49 0.7809 20.60 54.23  33.49  6.415 30.05 36.47
## x3 100 27.93 10.414 37.29 1.0414 10.21 44.59  27.82 17.775 19.05 36.83
## x4  80 24.58  3.125 12.71 0.3494 19.08 29.74  24.50  4.718 22.02 26.73
print(rbind(n, Mean, SD, CV, SEM, Min, Max, Median, iqr, Q1, Q3)) 
##               x1        x2        x3        x4
## n      50.000000 51.000000 100.00000 80.000000
## Mean   32.621600 33.822353  27.92920 24.582375
## SD      4.253431  5.576637  10.41364  3.124856
## CV     13.038695 16.488022  37.28585 12.711776
## SEM     0.601500  0.780900   1.04140  0.349400
## Min    23.140000 20.600000  10.21000 19.080000
## Max    44.170000 54.230000  44.59000 29.740000
## Median 32.670000 33.490000  27.82500 24.505000
## iqr     4.152500  6.415000  17.77500  4.717500
## Q1     30.125000 30.050000  19.05500 22.015000
## Q3     34.277500 36.465000  36.83000 26.732500
# get 512 x,y points for kernel density estimates ---------

d1 <- density(x1) 
d2 <- density(x2)
d3 <- density(x3)
d4 <- density(x4)

xlm <- range(c(d1$x, d2$x, d3$x, d4$x)) # get min, max for plotting
ylm <- range(c(d1$y, d2$y, d3$y, d4$y))

plot(d1, type="n", main="",               # get graph going
  xlim=xlm, ylim=ylm,                     # global x,y plotting ranges
  cex.lab=1.35, font.lab=2, cex.axis=1.2, # typography
  xlab="Simulated data from the Normal and Uniform distribution") 

lines(d1, col="black", lwd=3)  # add kernel density estimates ---------------
lines(d2, col="red",   lwd=3) 
lines(d3, col="blue",  lty=2, lwd=3)
lines(d4, col="green", lwd=3)

# legend with stats ---- by trial-and-error coding with mtext() -------------
cl  <- c("black", "red", "blue", "green")
lne <- c(-2.5, -3.5, -4.5, -5.5)
ad  <- c(.75, .81, .91, .98)

mtext(c("group", "N", "Mean", "SD"), line=-1, adj=ad, cex=.9)
mtext(c("x1", "x2", "x3", "x4"), line=lne, adj=.75, font=2 )
mtext(cl, line=lne, adj=.65, col=cl, cex=1.1)

mtext(c(n[1], round(Mean[1],2), round(SD[1],2)), line=-2.5, 
      adj=c(.82, .9, .98), cex=.9)
mtext(c(n[2], round(Mean[2],2), round(SD[2],2)), line=-3.5, 
      adj=c(.82, .9, .98), cex=.9)
mtext(c(n[3], round(Mean[3],2), round(SD[3],2)), line=-4.5, 
      adj=c(.82, .9, .98), cex=.9)
mtext(c(n[4], round(Mean[4],2), round(SD[4],2)), line=-5.5, 
      adj=c(.82, .9, .98), cex=.9)
Multiple kernel density estimates

Multiple kernel density estimates


The above graph of 4 kernel density estimates was done using base R graphics. Below, we use the ggplot2 package by Hadley Wickham. It uses Paul Murrell’s grid package, not base R.

The ggplot2 visualization environment is vast and powerful, but it’s beyond our time constraints and not my objective in Bio 240. However I will demonstrate ggplot2 graphics across the course, as time allows.

In my opinion, it’s best to learn base R graphics first, before learning other visualization environments such as lattice and ggplot2. The ggplot2 environment reflects software that is nearly a programming language in of itself. The base R graphics environment often meets our scientific and aesthetic graphing needs and does so within a simple and consistent coding pattern that allows a high level of control.

library(ggplot2) # load the package

my.colors <- c(x1="black", x2="red", x3="blue", x4="green")

# 4 kernel density lines, NO FILL

p1 <-  ggplot(sim.df, aes(x=response, color=group)) + geom_density(size=1.2) + 
              scale_colour_manual(values=my.colors)
print(p1)

# 4 kernel densities, FILLED 
p2 <- ggplot(sim.df, aes(x=response, fill=group)) + geom_density(alpha=.2) +
             scale_fill_manual(values=my.colors)
print(p2)

# 4 kernel densities, FILLED, x & y labels improved, xlim()
p3 <- ggplot(sim.df, aes(x=response, fill=group)) + geom_density(alpha=.2) + 
             xlab("Simulated data") + ylab("Density") + xlim(0, 60) + 
             scale_fill_manual(values=my.colors) + 
  #scale_fill_grey() +
  #scale_fill_viridis_d() +
  #scale_fill_brewer() +
  #scale_fill_hue(l=45) +
  #scale_fill_brewer(palette="Oranges") +
  #scale_fill_brewer(palette="Greys") +
  # scale_fill_brewer(palette="Blues") +
  # scale_fill_brewer(palette="Set1") +

             theme(axis.text=element_text(face="plain", colour="black", size=14), 
             axis.title=element_text(face="bold", size=20))  
       
 print(p3)


13.3.2   How do the 4 groups compare?

The BOXPLOT was invented by the late, great statistician and math Professor at Princeton University, JOHN TUKEY

boxplot(response ~ group, 
        boxwex=.6,              # width of boxes, default .8
        col=terrain.colors(4),  # color of box fill, default "gray"
        ylim=c(8, 55),          # specify min,max of y-axis to allow for sample sizes 
        xlab="Group", ylab="Response",    # x,y labels
        cex.lab=1.4, cex.axis=1.3, las=1) # typography

#mtext(paste("n =", n), adj=c(.125, .375, .625, .875)) # sample sizes atop graph
text(1:4, 8, paste("n =", n), cex=1.2) # sample sizes below boxplots 

It pays to master the boxplot, and its variants.

__________________


Analysis of Variance and Multiple Comparisons

anova(lm(response ~ group, data=sim.df)) # traditional, one-way Anova
## Analysis of Variance Table
## 
## Response: response
##            Df  Sum Sq Mean Sq F value    Pr(>F)    
## group       3  3513.7 1171.24  23.259 1.857e-13 ***
## Residuals 277 13948.8   50.36                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
aov.p <- anova(lm(response ~ group, data=sim.df))[1, 5] # extract p-value
cat("one-way Anova, full resolution p-value =", aov.p, "\n")
## one-way Anova, full resolution p-value = 1.856901e-13
TukeyHSD(aov(response ~ group), ordered=TRUE)    # Tukey test, Multiple Comparisons
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
##     factor levels have been ordered
## 
## Fit: aov(formula = response ~ group)
## 
## $group
##           diff        lwr       upr     p adj
## x3-x4 3.346825  0.5955828  6.098067 0.0099250
## x1-x4 8.039225  4.7326434 11.345807 0.0000000
## x2-x4 9.239978  5.9534061 12.526550 0.0000000
## x1-x3 4.692400  1.5155392  7.869261 0.0009511
## x2-x3 5.893153  2.7371242  9.049182 0.0000136
## x2-x1 1.200753 -2.4495437  4.851050 0.8302898
TukeyHSD(aov(response ~ group), ordered=TRUE)[1] # Tukey test, p-values, not rounded
## $group
##           diff        lwr       upr        p adj
## x3-x4 3.346825  0.5955828  6.098067 9.925005e-03
## x1-x4 8.039225  4.7326434 11.345807 7.641266e-09
## x2-x4 9.239978  5.9534061 12.526550 2.296408e-11
## x1-x3 4.692400  1.5155392  7.869261 9.510613e-04
## x2-x3 5.893153  2.7371242  9.049182 1.364760e-05
## x2-x1 1.200753 -2.4495437  4.851050 8.302898e-01
# default call is Holm-Bonferroni method, all pairwise, p-value adjustment
pairwise.t.test(response, group, p.adjust.method="holm") 
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  response and group 
## 
##    x1      x2      x3    
## x2 0.3959  -       -     
## x3 0.0005  9.2e-06 -     
## x4 6.4e-09 2.3e-11 0.0037
## 
## P value adjustment method: holm
# "planned" all pairwise comparisons, no adjustment of p-valyes
pairwise.t.test(response, group, p.adjust.method="none") 
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  response and group 
## 
##    x1      x2      x3     
## x2 0.39593 -       -      
## x3 0.00017 2.3e-06 -      
## x4 1.3e-09 3.8e-12 0.00185
## 
## P value adjustment method: none
kruskal.test(response, group)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  response and group
## Kruskal-Wallis chi-squared = 72.594, df = 3, p-value = 1.188e-15
cat("Kruskal-Wallis test, full resolution p-value =", 
    kruskal.test(response, group)$p.value, "\n")
## Kruskal-Wallis test, full resolution p-value = 1.18767e-15
library(gplots)
plotmeans(response ~ group, 
          connect=FALSE,      # connect means? default: TRUE
          n.label=FALSE,                 # add sample sizes
          main="Means with 95% CI",      # title
          xlab="Group", ylab="Response", # x,y labels
          # mean.labels=TRUE, digits=1, col="darkgray",  # print means
          cex.lab=1.4, cex.axis=1.3, cex.main=1.7, font.lab=2, # typography
          col.main="blue", font.main=1)                        # typography

# 'source' the R Editor file of new function definitions
source("C:\\Users\\dwigh\\Desktop\\K funs ONE WAY.R") 

Kincaid.perm.oneway(response, group, NS=5e5, describeF=FALSE)
## 
## ----------------------------------------------------------------------------
##  
## Kincaid.perm.oneway(y, x, NS, describeF, returnF)  --> for one-way data
## 
##  The Call: Kincaid.perm.oneway(response, group, NS = 5e+05, describeF = FALSE)
## 
## Test statistic: observed F from one-way Anova on observed data. 
## Null hypothesis same as in classical one-way Anova. Ho: means are equal
## 
## Start LOW on NS (e.g., 1e3), note time required then go HIGH.
##                       Thu Dec 15 21:36:54 2022 
## ----------------------------------------------------------------------------
## 
## TEST STATISTIC:
## 
## observed F = 23.25887 in classical one-way Anova
## 
## RESULTS: minutes elapsed = 4.9848 for NS = 5e+05 shuffles
## 
## NGE = 0   -->  number of null F-stats >= observed F-statistic
## NGE is size of right tail of null F distribution
## 
## p = 1.999996e-06 
##  achieved after NS = 5e+05 permutations of y,
##  holding constant, the grouping variable, x
## 
##                       Thu Dec 15 21:41:53 2022 
## ----------------------------------------------------------------------------
## 

Continuing with this fake, simulated one-way data of 4 groups, we are always interested in confidence intervals of the means. Below find the traditional, 95% CI for the 4 means calculated using normal theory (t-distribution).

CImeans.normaltheory(response, group, prob=.95)  #  from: K funs ONE WAY.R
## 
## 
## Means with 95% confidence intervals
##  using t-distribution
##          LB       UB     Mean   N
## x1 31.41279 33.83041 32.62160  50
## x2 32.25390 35.39081 33.82235  51
## x3 25.86291 29.99549 27.92920 100
## x4 23.88697 25.27778 24.58237  80

How would the boostrap confidence intervals of these 4 means, compare to the traditional confidence intervals? Notice that the confidence intervals are astonishingly similar – the boostrap just works! My function below, uses the bootstrap percentile method to calculate CI from the bootstrap distribution of the means.

bootCImeanOneWay(response, group, NS=2e5)  # from: K funs ONE WAY.R  
## 
## 
## = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
## 
## OUTPUT from:  bootCImeanOneWay()   by Prof. Dwight Kincaid, PhD 
## 
## The Call:     bootCImeanOneWay(response, group, NS = 2e+05)
## 
##   time stamp:   Thu Dec 15 21:42:07 2022 
## 
## Note:    the vector index is bootstrapped
## 
## BOOTSTRAP underway, patience...
## 
## Start LOW on NS, note time required, then go HIGH, as time is
## proportional. All the while, realize that the CI results from
## multiple runs can be averaged
## 
## minutes elapsed = 0.9155 
## 
## ---------------
## 95% confidence intervals of group means
## 
##                 x1           x2           x3           x4
## 2.5%      31.46245     32.33837     25.89000     23.89742
## 97.5%     33.81523     35.40476     29.96661     25.26944
## Mean      32.62160     33.82235     27.92920     24.58237
## N         50.00000     51.00000    100.00000     80.00000
## Min       23.14000     20.60000     10.21000     19.08000
## Max       44.17000     54.23000     44.59000     29.74000
## NS    200000.00000 200000.00000 200000.00000 200000.00000
## 
## ---------------
## 99% confidence intervals of group means
## 
##                 x1           x2           x3           x4
## 0.5%      31.10783     31.87571     25.25682     23.68519
## 99.5%     34.19861     35.95000     30.60965     25.48390
## Mean      32.62160     33.82235     27.92920     24.58237
## N         50.00000     51.00000    100.00000     80.00000
## Min       23.14000     20.60000     10.21000     19.08000
## Max       44.17000     54.23000     44.59000     29.74000
## NS    200000.00000 200000.00000 200000.00000 200000.00000
## ---------------
## 
## time stamp:   Thu Dec 15 21:43:02 2022 
## 
## = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


Effect SizeCohen’s d is a widely used, standardized effect size, as is R-square and Variance Components. One may wish to report these “statistics” with their 95% confidence intervals but I am not aware of formulaic methods for this that have much support among statisticians. Bootstrap to the rescue.

bootCohenD.oneway(response, group, NS=2e5)
## 
## -----------------------------------------------------------------
## OUTPUT from bootCohenD.oneway( )  by  Dwight Kincaid, PhD
## 
## The Call: 
## bootCohenD.oneway(response, group, NS = 2e+05)
## 
## 
## Observed, Cohen's D: 0.4983125 in one-way Anova

## STATS    for bootstrap distribution of Cohen's D
##  n: 2e+05     min, max: 0.311712 , 0.7842091 
##  mean: 0.5085103  median: 0.5068693 
##  SD: 0.04766198   skew: 0.2157265 
## 
## NS: 2e+05 bootstrap samples  minutes: 4.464 
## 
## Nonparametric, Percentile Bootstrap Confidence Intervals
## for Cohen's D in one-way Anova
## 
##                90% CI   95% CI    99% CI
## lower-bound 0.4330335 0.419604 0.3937449
## upper-bound 0.5896419 0.606727 0.6418604
## 
## Time stamp:  Thu Dec 15 21:47:30 2022 
## -----------------------------------------------------------------
bootRsq.oneway(response, group, NS=2e5)

boot.vc.oneway(response, group, data.name="Fake data", NS=1e5)
## 
## -----------------------------------------------------------------
## BOOTSTRAP Variance Components in one-way Anova
## 
##           time stamp:  Thu Dec 15 21:47:52 2022 
## The Call:
## boot.vc.oneway(response, group, data.name = "Fake data", NS = 1e+05)
## 
## Data set:  Fake data 
## 
## NS = 1e+05 bootstrap resamples from observed data frame
## Note:  the data frame 'row index' was resampled
## 
## Using the 'percentile method'
## the 95% confidence intervals are --
## 
## Explained VC%        observed: 24.61714 
##     2.5%    97.5% 
## 18.77828 32.88067 
## 
##  STATS   for bootstrap distribution of EXPLAINED VC%
##  min, max: 12.64455 , 42.30946 
##  mean: 25.48481  median: 25.35333 
##  SD: 3.601187  skew: 0.1918715 
## 
## Error VC%        observed: 75.38286 
##     2.5%    97.5% 
## 67.11933 81.22172 
## 
## CPU minutes: 2.948   for bootstrap resampling
## 
## Output from:  Kincaid.boot.vc.oneway()  by  Dwight Kincaid, PhD
## -----------------------------------------------------------------


Statistical power analysis – There a 2 ways: 1) traditional power analysis using normal theory after Cohen (1988) and 2) bootstrap power analysis. A power curve is the best way to visualize tabular output of any type of power analysis. Bootstrap power analysis uses no formulas and there are no assumptions. Traditional power analysis operates within the assumptions of the parametric method in question (one-way Anova, here); bootstrap power analysis, does not.

The pwr package has a function for traditional power analysis after Cohen (1988) by solving the power equations (non-central F-distribution) and assuming equal sample size per group, which our data does not reflect.

My wrapper function calls function pwr.anova.test() from this package to get power across a range of sample sizes and for alpha of .05, .01 and .001, and plot power curves with the table of results sent to the R Console.

powercurve.Cohen.oneway(response, group, low.n=4, high.n=24, by.n=2, 
                        data.name="sim fake data, 4 groups, total n=281")

##       total.N  N.per.group  pwr.at 05  pwr.at 01  pwr.at 001  Cohen's D
##  [1,]      16            4     0.2669     0.0900      0.0150      0.498
##  [2,]      24            6     0.4338     0.1936      0.0468      0.498
##  [3,]      32            8     0.5838     0.3183      0.1020      0.498
##  [4,]      40           10     0.7064     0.4480      0.1794      0.498
##  [5,]      48           12     0.8000     0.5697      0.2735      0.498
##  [6,]      56           14     0.8678     0.6758      0.3765      0.498
##  [7,]      64           16     0.9148     0.7630      0.4806      0.498
##  [8,]      72           18     0.9463     0.8314      0.5792      0.498
##  [9,]      80           20     0.9669     0.8829      0.6679      0.498
## [10,]      88           22     0.9799     0.9205      0.7442      0.498
## [11,]      96           24     0.9880     0.9470      0.8074      0.498
#powercurve.unbalanced.oneway(response, group, low.n=20, high.n=92, by.n=4, 
#                             data.name="sim fake data, 4 groups, total n=281")

To do bootstrap power analysis I resample the row indices of the data frame and for each sample the p-value from one-way Anova is recovered. The arguments in the function call (low.n, high.n, by.n) specify the range of sample sizes for which power is calculated for alpha of .05, .01 and .001, plotted as power curves with the table of results sent to the R Console.

NS is the number of bootstrap samples of the data frame for each sample size. Here, statistical power is simply the proportion of the NS number of Anova F-tests that were significant at .05, .01 and .001 level, at each sample size.

boot.powercurve.oneway(response, group, NS=2e4, low.n=20, high.n=92, by.n=4,
                       data.name="sim fake data, 4 groups, total n=281")
## 
## 
## Output from Kincaid function: boot.powercurve.oneway()
## 
## DATA:         sim fake data, 4 groups, total n=281 
## 
## observed total N:     281 
## Bootstrap resamples
##  for each, total sample size:     20000 
## Minutes needed:   8.93

##       total.N  pwr.at .05  pwr.at .01  pwr.at .001
##  [1,]      20       0.292       0.124        0.042
##  [2,]      24       0.372       0.158        0.050
##  [3,]      28       0.455       0.200        0.062
##  [4,]      32       0.547       0.255        0.076
##  [5,]      36       0.627       0.316        0.097
##  [6,]      40       0.712       0.396        0.130
##  [7,]      44       0.778       0.466        0.162
##  [8,]      48       0.838       0.545        0.210
##  [9,]      52       0.881       0.622        0.265
## [10,]      56       0.918       0.689        0.320
## [11,]      60       0.944       0.752        0.382
## [12,]      64       0.965       0.807        0.449
## [13,]      68       0.976       0.848        0.505
## [14,]      72       0.985       0.884        0.577
## [15,]      76       0.991       0.917        0.631
## [16,]      80       0.995       0.939        0.691
## [17,]      84       0.997       0.958        0.752
## [18,]      88       0.998       0.969        0.789
## [19,]      92       0.999       0.978        0.833


Bayes Factor Anova – The contributed R package, BayesFactor has functions for Bayes Factor Anova, correlation, linear regression and more. My function BayesFactorAnova.oneway() is merely a wrapper around function anovaBF() from BayesFactor.   Here, Bayes Factor Anova returned 39 billion times (0.02% Credible Interval) more support for heterogeneity (H1:) among the 4 means than for homogeneity (Ho:) among the means.

It’s helpful that Bayesian statisticians have written procedures that operate sort of within the conceptual framework of familiar, statistical models, including Anova; see Gelman, Andrew. (2005) Analysis of Variance — why it is more important than ever. Annals of Statistics, 33, pp. 1-53.

BayesFactorAnova(response, group)
## 
## -----------------------------------------------------------------
## BAYES FACTOR one-way ANOVA
## using library(BayesFactor)
##  anovaBF() is for fixed treatment or random effects Anova
## 
## A Bayes factor is a multiplicative factor of support for H1 vs. Ho
## In other words, support for means being different vs. being equal.
## 
## Documentation: > help(package=BayesFactor)    >?anovaBF 
## -----------------------------------------------------------------
## 
##  You specified an Anova model that's 'fixed effects'
## 
## Bayes factor analysis
## --------------
## [1] x : 39308364304 ±0.02%
## 
## Against denominator:
##   Intercept only 
## ---
## Bayes factor type: BFlinearModel, JZS


13.4   Bivariate data

13.4.1   Simple line graphs and scatter plots

Under development

13.4.2   Interactive graphs

R and R Markdown enable interactive graphs. The plotly package makes ggplot2 graphs, interactive. Hover over the points. Click on top legend for options. Click on the legend to de/select continents. Circle size is proportional to population size in 2007 for Life Expectancy vs. GDP per person in US dollars (first graph) and Life Expectancy vs. Population Size (second graph).

The data is from https://www.Gapminder.org, founded in 2005 in Stockholm by Dr.  Hans Rosling (Professor of International Health, Karolinska Institute) and his group.

He became world famous by his TED talks and videos, some of which we’ll view in Bio 240.
Professor Rosling’s last book was Factfulness: https://www.gapminder.org/factfulness-book/
Unfortunately, this type of interactive graph is beyond the time frame of Bio 240.

library(ggplot2)
library(plotly)
## Warning: package 'plotly' was built under R version 4.2.3
library(gapminder)
## Warning: package 'gapminder' was built under R version 4.2.3
p1 <- gapminder %>%
  filter(year==2007) %>%
  ggplot( aes(gdpPercap, lifeExp, size = pop, color=continent)) +
  geom_point() +
  scale_x_log10() +
  theme_bw()
 
ggplotly(p1)

Put cursor inside graph to interact & atop graph for menu

p2 <- gapminder %>%
  filter(year==2007) %>%
  ggplot( aes(pop, lifeExp, size = gdpPercap, color=continent)) +
  geom_point() +
  scale_x_log10() +
  theme_bw()
 
ggplotly(p2)

Put cursor inside graph to interact & atop graph for menu


13.4.3   Correlation

Under development

13.4.4   Regression

Under development

14   R Editor files – coding conventions in Bio 240


This semester you will be required to write many R programs (i.e., R Editor files, e.g., foo.R).

R Editor files are just plain text files of R code that we submit top-down, to the R Console for execution, interactively.

Each of these R Editor files this semester, is motivated by a different biological data set for which graphical visualization and statistical analysis are desired.

In Bio 240, statistical analysis refers to the exploratory and to the formal; to the parametric and nonparametric; the traditional and the computationally intensive (permutation, bootstrap, Monte Carlo simulation); and to the Bayesian.

Graphical visualization
obviously refers to graphs. R leads the world in the quantity, quality and diversity of its graphical programming environments.

The main focus of graphics in Bio 240 is on what we call base R graphics. But, I will introduce graph environments (e.g., hexbin, lattice, ggplot2) based on
the famous grid package by Paul Murrell or those based on JavaScript (e.g., plotly).

Initially, all this can be overwhelming if you’ve had no computer programming or statistical experience. However, it’s my job to make it easy by helping you get a foothold in R, including by starting small.

In our R coding workflow, it’s best to start small and fail faster. The sooner we accept and learn from our failures (R code that throws errors and/or does the wrong thing) the quicker we can turn them into successes (reliable code). This holds true for R programmers who are beginners as well as for those who are experts.


14.1   Introduction

Every class period I/you will write, debug and run code in R Editor files. We practice top-down coding and top-down debugging. leading to reliable, clean and readable code.

You will learn to appreciate the adage:   To lavish your code with comments is to code wisely.

Your R Editor files must conform to my coding conventions. After Bio 240 you may write all the illiterate, ugly code you wish – code that if given to others or even when viewed by you 6 months later, may likely appear as gibberish.

My mandatory coding conventions are in the treasured spirit of literate programming.

In Bio 240 for R, these conventions include:   valid & proper file names, comments, line spacing, line width of 85 characters max, indentation, content of first line of file, content of last line of file, valid names of objects, wise names of objects.

The ability to write, to debug and to run computer programs in R (R Editor files) is a major emphasis in Bio 240 and is required on each of the 3 Tests. It’s an accomplishment you will take with you beyond this course, and into your immediate and future, career development.

Using R and creating useful, R Editor files requires patience, attention to detail, much practice and comfort with trial-and-error. It’s that way with any programming language.

This past summer, as I struggled programming in R, HTML, CSS, JavaScript, LaTex and R Markdown – it was only by patience, practice and trial-and-error that anything was accomplished.

Sure, I am supposed to be an expert in R, but every day I write R code that throws errors at the R Console, I make poor coding decisions and my programming workflow is unwise. But, with patience and trial-and-error, I make progress in coding and getting reliable output.

Professors say writing is revision. The same holds for typing computer programs. If it takes an hour to write a good sentence in English, so what? It often takes me an hour. If it takes an hour to write several lines of proper R code, so what? In life, the good and the proper, are not easy and may not happen quickly.

Regardless of what a poem means, it must look good on the page. The same holds for computer programs. Writing a computer program is as creative, artistic and fulfilling as any human activity.

We seek R Editor files (programs: small or large) that are clear, clean, readable, printable, well-tested, bug-free, appropriately commented and a joy to view and to run. Those who work hard in Bio 240, will create R Editor files that make them proud.

As the semester proceeds in Bio 240, you may find yourself crafting R programs that will advance your career as you communicate these programs in your research lab, for employment opportunities or in your applications to professional and graduate schools.


R Editor files are the intellectual capital you craft, accumulate, use in Bio 240 and take with you, beyond Lehman College.


We wanted users to be able to begin in an interactive environment, where they did not consciously think of programming.  Then as their needs became clearer and their sophistication increased, they should be able to slide gradually into programming when the language and system aspects would become more important.”    — John Chambers



14.2   A small  x, y  data set


Given below, please inspect the very small x,y data set on a 65 year old female patient being treated for Osteoporosis with Alendronate which is a nitrogen containing bisphosphonate that binds to bone surfaces and promotes bone density increase.

Our task is to save this medical data in an R Editor file, graph it, explore it and perform statistical analysis.

A graph incorporating statistical analysis would inform her Physician on if the treatment was effective across the 7.7 years and if it should be continued.
Obviously, this is important to the patient and to the Doctor’s Hippocratic Oath.

In general, for very small sample sizes graphical visualization remains paramount. Often, we simply graph small data and let it speak for itself; this has always been acceptable in Science and in peer reviewed journals.

Also for small sample sizes, we proceed with statistical analysis using caution, realizing it may have little if any, inferential value beyond the data at hand.


“A 65 year old woman with low bone density in 2002 was treated with alendronate through the year 2009. Bone density was measured irregularly over this period.”   Source: p. 544-545 in Rosner, Bernard. 2016. Fundamentals of Biostatistics, 8th ed. Cengage, Boston. 927 pages. This textbook is used at Harvard’s medical school and related graduate programs.

Bone density (g/cm2)   by  Time (months)

Time is months since baseline. At each visit, bone density (g/cm2) was measured by DEXA scan, for lumbar spine and femoral neck (hip). Time is our x variable, paired with bone density as y.

Visit Time (months) Lumbar Spine g/cm2 Femoral Neck (hip), g/cm2
1 0 0.797 0.643
2 8 0.806 0.638
3 18 0.817 0.648
4 48 0.825 0.674
5 64 0.837 0.640
6 66 0.841 0.676
7 79 0.886 0.651
8 92 0.881 0.680


14.3   R Editor file – establish the file


Here I demonstrate best practices on how to establish R Editor files to store, graph and analyze data in Bio 240.

R Editor files are also called computer programs or scripts.

The content (lines of code) of an R Editor file is submitted in top-down fashion, to the R Console, for interactive execution. Later, we will source entire R Editor files constructed to run non-interactively; but, we first must learn interactive submission to the R Console, of single lines of code and of small code blocks, debugging and saving along the way.
This R Editor file created below, benefits from our mandatory, coding conventions in Bio 240.

Our coding conventions include:

1. valid and proper file names
2. comments
3. line spacing
4. line width: 85 characters max
5. indentation
6. content of first line of file
7. content of last line of file
8. valid names for objects
9. wise names for objects


  • We begin by writing the first line and the last line of the R Editor file. We save it with the student’s name as part of the filename, as required in Bio 240 for all R Editor files including for homework and on Tests.

  • Let’s name it, bone density Arlo.R realizing that all valid and proper, R Editor files have .R as the file extension. Aardvark.R would be a valid name (would not throw an error in R) but would be an unwise file name.

  • Before launching into writing lines of R code, it’s wise to take this first step of creating the file, with an appropriate name and made up of only 2 lines: a first line of comments and a final line of comments.

  • This is what our R Editor file presents, as first established and saved. It does nothing, it returns nothing.

# bone density Arlo.R    September 2, 2021    Arlo Atz, BS


# end.  bone density Arlo.R
  • Inspect the first line of the above file. It’s solely, a comment because it begins with the hashtag # for which R interprets everything to the right of it (on that line) as a comment and hence ignored. Comments are essential; comments help humans; R ignores them. More about comments later, as they have multiple uses.

  • What is the purpose of the first line of our R Editor file above?

    • it states the exact filename so you know what you are looking at and how to find it
    • the date indicates the version of the program and perhaps when last edited
    • author name

  • Inspect the last line of the above file. It’s also solely, a comment.

  • What is the purpose of the last line of the file?

    • it states that this line is indeed, the end of the file (the program)
    • it states the exact filename of the program so you know what you are reading and how to find it
    • Whether your program is 1/2 page or 10 pages long, you know all of it printed out or if viewing on the screen, you know you’re at the end of the file, if # end. foo Arlo.R is at the bottom

  • We are now ready to add R code between these 2 lines, typing it in top-down fashion, debugging top-down, and saving along the way.


14.4   R Editor file – save the data


  • Before storing the data as numeric vectors it’s wise to enter a few lines of comments explaining what is going on. It might seem obvious “what’s going on” but months later, the layout of the data and its source, may not be obvious.

  • Use the c() function to store the time variable as numeric vector time.
    Store lumbar spine bone density as spine and temporal neck (hip) bone density as hip.   I could have named these 3 numeric vectors Yonkers, Bronx and Australia which would not throw an error in R, but it would be unwise naming.

  • We seek short, informative names for variables and objects. I prefer simple names of lowercase.

  • The numeric vector is the fundamental data structure in R.

  • The c() function is the most commonly used function in R.

  • The c() function combines its arguments into a vector. Here, the args are data with each datum separated by a comma. Vectors may be numeric or character. Vectors may be combined to make more complicated data structures:   factor, matrix, data frame, list, array.

  • We call the cbind() function just to print a 3 column data matrix at R Console to allow a check for accuracy against the original data. Wrong data entry generates wrong answers.

  • The data are now stored in objects that allow graphing and statistical analysis to proceed. Everything in R is an object whether data, functions, output, graphs or whatever. Think of R objects as containers.

  • To use R is to call functions (John Chambers).


# bone density Arlo.R    August 26, 2021    Arlo Atz, BS

# Bone density was measured over 92 months in a 65 year old woman with low bone
# density, treated with Alendronate, 2002 through 2009. Bone mineral density 
# (g/cm^2) was measured for lumbar spine and femoral neck (hip) (Rosner, B. 2016).

time  <- c(0, 8, 18, 48, 64, 66, 79, 92)     # months from baseline

spine <- c(.797, .806, .817, .825, .837, .841, .886, .881) # spine bone density
hip   <- c(.643, .638, .648, .674, .64,  .676, .651, .68)  # hip    "     "

# view data at R Console to check carefully, versus original
cbind(time, spine, hip) 


# end.  bone density Arlo.R
  • The code chunk above, returns to the R Console, text output from the call to cbind() which binds our 3 numeric vectors by columns, into a matrix object and prints it at R Console, as given below.

  • We must always check that the data as saved in any computer program, exactly reflects our original data. Proofread it against the original. In Bio 240 and in any environment – errors in data entry produce wrong results. Obviously, this also holds true for Tests in Bio 240 where zero credit is given for wrong answers caused by student errors in data entry.

  • If desired, > time would print content of the time vector, > spine the spine vector and > hip the hip vector.

  • The 2 dimensional index that’s printed at R Console, [row, column] is not part of the data matrix; it’s put there to inform the viewer.

  • [1, ] indicates row 1, all columns. A missing integer in the row slot means all rows while a missing integer in the column slot means all columns.

  • Consider: [4,2] , it returns 0.825, the 4th row, 2nd column. Vectors are single indexed, [ ] while matrices and data frames are double indexed, row by column, [ , ].

  • In Bio 240 we use indexing for dealing with vectors, matrices and data frames. We also use indexing to extract information from objects returned from function calls. Indexing in R is just High School, algebraic thinking.

Output from cbind(time, spine, hip) :

##      time spine   hip
## [1,]    0 0.797 0.643
## [2,]    8 0.806 0.638
## [3,]   18 0.817 0.648
## [4,]   48 0.825 0.674
## [5,]   64 0.837 0.640
## [6,]   66 0.841 0.676
## [7,]   79 0.886 0.651
## [8,]   92 0.881 0.680


14.5   R Editor file – graph the data


My practice is to teach you R coding by demonstrating the natural workflow and evolution of short programs. (This is much better than only showing you finished, polished R programs.)

Ideally, we do this at the same time, as the Professor and the students type the same code, in what I call collaborative coding.

Collaborative coding is easy in the physical classroom yet more difficult in the online classroom, but still possible.

Computer programs develop by stages, by trial-and-error, by attention to detail, by coding experiments and by top-down debugging along the way.

This process results in clean, readable R code that executes without error and delivers mature graphs and trustworthy statistical results.

It’s utterly foolish to try to cut to the desired graphical and statistical end product, right from the programming get-go. Let this sentence burn-in.


Writing programs in R is similar to writing essays in English. Both involve symbolic thinking, outlines, rough drafts, multiple revisions, documentation and attention to detail.


14.5.1   Preliminary graphs

  • The plot() function is the workhorse graphing function in base R. It makes a variety of different graphs, it takes many arguments. Here, we plot the x,y data in a minimal call: plot(x, y) where the x arg is the name of our x numeric vector and y the name of the corresponding, y numeric vector. At the R Console, >?plot brings up extensive, HTML documentation for this extremely important graphing function.
# ------------------------
# preliminary scatterplots -------------------------------
# ------------------------

plot(time, spine) # 'spine' scatterplot: bone density by time
plot(time, hip)   # 'hip'   scatterplot:   "     "    "   "
  • The first line of code above, delivers a scatterplot for spine bone density (y) by time (x) – left graph below.

  • The second line of code, does the same for hip bone density by time – right graph. Examine these two graphs.

  • But, we want both sets of x,y points on the same graph and we want point-and-line graphs not scatterplots. Yet, we are encouraged and informed by these rough graphs. We’re making progress in visualizing the data.

  • Notice the scale of the y-axis on both scatterplots above. Clearly, spine bone density is much greater than hip bone density in this patient with Osteoporosis.

  • For both sets of points to fit in the same graph we need global min, max for bone density. A call to the range() function delivers. This function takes a numeric vector as its arg and returns the minimum and maximum of that vector. We use c(spine, hip) to create a numeric vector for the combined, spine and hip density data. In R, we may call functions within functions.

  • The new line of code below, delivers min, max (0.638 to 0.886 g/cm2) for the data set.

# both lines must fit in the same graph, so get global min,max for y
range(c(spine, hip))  # min, max: .638 to .886
## [1] 0.638 0.886


  • Now our task is to make a rough, minimal, draft quality, point-and-line graph for spine and for hip bone density. There are always different ways to accomplish the same thing in any programming language just as there are different ways to say “I love you” in any spoken language and experts disagree on the best way to do it.

  • In the first line of code below, we call plot() for the spine x,y data and then use the points() function in the second line to add the points for the hip. This gives us full control over the graph.

  • The arg type="b" specifies that both points and lines are called for. (The default for the type arg is type="p" for points only; type="l" delivers only the line, "c" is empty points joined by lines, "s" makes stairsteps, "h" for vertical lines, "n" makes no points or lines).

  • In the call to plot() we change the default scale for the y-axis by using the argument ylim=c(.6, .9) or by the argument ylim=range(c(spine, hip)); the latter is preferable, in case the data vectors are changed upstream in the program. The default for the x-axis scale looks fine but we could change it with the xlim=() arg, if desired.

  • In the second line of code the call to points() adds the x,y points for hip density by time. The pch=16 arg specifies black, solid circles, If this arg is omitted as we did in the call to plot() then the default value of pch=1 is used which returns an open circle for the points. (pch can take integers from 0 to 25, and beyond; see>?points for documentation)

# minimal graph as proof of concept --------------------------------
plot(time, spine, type="b", ylim=range(c(spine, hip)))  # spine data
points(time, hip, type="b", pch=16)                     # add hip data

  • Draft quality is what we have in the graph just above. It needs enhancement to make it publication quality or presentation quality. But, the hard work is over. The enhancements are relatively easy, given patience and some trial-and-error.

  • Axis labels need to be made proper, including with units of measurement and with larger font size. We might wish to rotate the y-axis tick labels. We often increase the font size of tick labels. Larger font size helps when graphs are reduced in print and helps when viewed on a poster or projected on a screen.

  • Publication quality refers to a graph intended for publication in a peer-reviewed scientific journal. Presentation quality refers to a graph intended for a professional, poster presentation or live seminar.

  • Publication quality graphs have no title and no personalized time stamp on the graph. Presentation quality graphs may enjoy informative titles and personalized time stamps to assign credit/blame for the graph and data in question.

  • We comment-in or comment-out args and lines of code to switch easily between publication and presentation quality graphs. More on that later. In short, mastering comment-in and comment-out is essential in coding across all programming languages.

  • Draft quality is self-explanatory. It’s where we begin with a graph. Draft quality is easy, happens quickly and is often sufficient for the bench and for viewing among your research collaborators.

14.5.2   Enhanced graphs with labels


Having established above, by minimal calls to both plot() and to points() that a pretty decent graph is made, we now expand these two calls by using more arguments.

The args in the code chunk below, are partly explained by comments in the code itself. This is wise programming as it saves one the trouble of >?plot to access the long, HTML documentation for the plot() function.

Remember:   arguments are separated by commas, except for the last arg in the call.

Some of the args below are self-explanatory, others have suggestive names, while others are oblique.

The best way to learn the arguments for a function is to use them, change them and see what happens in the output.

A nice thing is that most of the functions in base R graphics, e.g., plot, points, lines, abline, boxplot, stripchart, histogram, barplot, text, mtext, segments, arrows, title, legend, pie, symbols, dotchart, grid, polygon, coplot, sunflowerplot – share many of the same arguments.


  • The main arg is a string for graph title, if desired; and it has typographic args, cex.main, col.main and font.main for font size, font color and font type (regular, bold, bold italic), respectively.

  • The xlab and ylab args allow custom labels for x and y axis and they have typographic args, cex.lab, cex.axis, font.lab, and more.

  • The type arg specifies whether points alone are plotted, type="p" , points connected by lines type="b", lines connecting points but points not plotted type="l", type="n" does nothing and type="h" plots a bar from the bottom up to the point’s y coordinate.

  • Change the values for the col, cex and las args and see what happens.

# ----------------------------------------------------
# enhanced, point and line graph: 2 sets of x,y points --------------
#   with each line labeled within the graph    
# ----------------------------------------------------

plot(time, spine, 
  col="black",  # color of points; default, col="black"
  cex=1,        # size of symbol plotted; default, cex=1
  ylim=range(c(spine, hip)),  # adjust y-axis range
  xlim=c(-5, 100),            #   "    x-axis  "
  las=0,         # flip y-axis tick labels, las=1; default: 0
  type="b",      # default: type="p" points only; "b" both; "l" line only; "n", "h" 
  main="Bone density with Alendronate treatment\n65 year old female patient",
  xlab="Time from Baseline, months", 
  ylab="Bone Density, g/cm^2", 
  font.lab=2, cex.lab=1.4, cex.axis=1.2,  # label & axis typography
  cex.main=1.8, col.main="darkred"        # title typography
)

After the call to plot, the points function is called for the hip x,y data. Here, we add the pch arg which takes integers from 1 to 25 and more. When an arg is not explicitly used in a function call then the default value for that arg (specified in that function’s formal definition) is used, and the default for pch is pch=1 which specifies that the x,y coordinates are open circles; pch=16 returns a solid circle and this clearly distinguishes the spine from the hip data in the graph.

# add 2nd set of points with connecting line --------
points(time, hip, pch=16, type="b")

The text and mtext functions allow us to put text within the graph, text and in the margins of the graph mtext, although mtext may also be used to draw text within the Cartesian coordinate space. It pays to learn how to use these 2 functions.

For text() the first 2 args are x,y coordinates where you want the text to be drawn; the next arg is the string you want drawn. The args font, cex and col control font type (default: font=1 for regular, 2 for bold, 3 for italic, 4 for bold italic), font size (default: cex=1, cex=2 is twice as large, etc.) and font color (default: col="black").

Here we use the mtext() function to place a personalized time stamp along the lower right edge of the graph window, using reduced font size and gray color. This gives credit/blame to the investigator! For mtext() the first arg is the string you want to draw, the side arg is either 1, 2, 3 or 4 for lower side, left side, top side, right side of graph window, respectively. The adj arg specifies the left-right position of the text, where adj=0 is left justified and adj=1 right justified. The line arg has default of line=0 which is at the graph edge; line=4 is four lines below the bottom edge of the graph. The cex arg controls font size, as explained above, while the col arg controls text color.

# label each line ------------------------------------------
text(20, .85, "Lumbar Spine", font=1, cex=1.2, col="darkred")
text(20, .69, "Temporal Neck (hip)", font=1, cex=1.2, col="darkred")

# add personalized time stamp; good for presentation quality graph ---------
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")


The entire, R code chunk is below. It returns the enhanced graph – a graph one would be proud to display and to submit.

# ----------------------------------------------------
# enhanced, point and line graph: 2 sets of x,y points --------------
#   with each line labeled within the graph    
# ----------------------------------------------------

plot(time, spine, 
  col="black",  # color of points; default, col="black"
  cex=1,        # size of symbol plotted; default, cex=1
  ylim=range(c(spine, hip)),  # adjust y-axis range
  xlim=c(-5, 100),            #   "    x-axis  "
  las=0,         # flip y-axis tick labels, las=1; default: 0
  type="b",      # default: type="p" points only; "b" both; "l" line only; "n", "h" 
  main="Bone density with Alendronate treatment\n65 year old female patient",
  xlab="Time from Baseline, months", 
  ylab="Bone Density, g/cm^2", 
  font.lab=2, cex.lab=1.4, cex.axis=1.2,  # label & axis typography
  cex.main=1.8, col.main="darkred"        # title typography
)

# add 2nd set of points with connecting line --------
points(time, hip, pch=16, type="b")

# label each line ------------------------------------------
text(20, .85, "Lumbar Spine", font=1, cex=1.2, col="darkred")
text(20, .69, "Temporal Neck (hip)", font=1, cex=1.2, col="darkred")

# add personalized time stamp; good for presentation quality graph ---------
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")

Presentation quality graph with title, the 2 lines labeled within graph and personalized time stamp.

Question:   How do we modify the above code to make a Publication quality graph – one without a title and without the personalized time stamp?
Answer:   We comment out the main arg in plot() and we comment out the call to mtext() for the personalized time stamp.

In your interactive, R coding workflow you must master, comment out (to add the hashtag to the left of code to be ignored by R) and comment in (to remove the hastag) which activates the code.

plot(time, spine, 
  col="black",  # color of points; default, col="black"
  cex=1,        # size of symbol plotted; default, cex=1
  ylim=range(c(spine, hip)),  # adjust y-axis range
  xlim=c(-5, 100),            #   "    x-axis  "
  las=0,         # flip y-axis tick labels, las=1; default: 0
  type="b",      # default: type="p" points only; "b" both; "l" line only; "n", "h" 
  #main="Bone density with Alendronate treatment\n65 year old female patient",
  xlab="Time from Baseline, months", 
  ylab="Bone Density, g/cm^2", 
  font.lab=2, cex.lab=1.4, cex.axis=1.2,  # label & axis typography
  cex.main=1.8, col.main="darkred"        # title typography
)

# add 2nd set of points with connecting line --------
points(time, hip, pch=16, type="b")

# label each line ------------------------------------------
text(20, .85, "Lumbar Spine", font=1, cex=1.2, col="darkred")
text(20, .69, "Temporal Neck (hip)", font=1, cex=1.2, col="darkred")

# add personalized time stamp; good for presentation quality graph ---------
#mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")

Publication quality graph


14.5.3   Enhanced graphs with legends

# ------------------------------
# Enhanced GRAPH, using legend()  -- use of legend() is OPTIONAL in Bio 240 ---
#   BUT, adding labels within graphs and in graph margins, is required
# ------------------------------

cx1 <- 1.6; cx2 <- 1.2; cx3 <- 1.8  # vars for typography convenience
c1 <- "darkred"

plot(time, spine,
  type="b", 
  bty="l",  # type of 'box'; default: "o", "l", "7", "c", "u", "]"  
  ylim=c(.62, .9),   # x-axis range
  xlim=c(-5, 100),   # y-axis range
  cex=1.4, cex.lab=cx1, cex.axis=cx2, font.lab=1, # typography
  cex.main=cx3, col.main=c1, col.lab=c1,          # typography
  xlab="Time from Baseline, months",
 
  ylab="",   # turn-off y-axis label if doing it by mtext()
  #ylab="Bone Density, g/cm^2", 
  #ylab=expression("Bone Density, g/cm" ^2),

  main="Bone density with Alendronate treatment\n65 year old female patient"
  #main="65  year  old  female  patient", cex.main=cx3
)

# use mtext() for y-axis label to deal with crowding issue 
mtext(expression("Bone Density, g/cm" ^ 2), side=2,
      line=2.3, cex=cx1, col=c1, font=1)

points(time, hip, pch=16, cex=1.4, type="b") # add hip x,y data
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")

# ------------------------
# legend() takes many args --- Optional in Bio 240 -------
# ------------------------

legend(x=55, y=.79,   # x,y for top-left corner, by trial-and-error
  legend=c("Lumbar Spine", "Temporal Neck (hip)"), 
  pch=c(1, 16), cex=1.2, text.font=3, pt.cex=1.5,
  x.intersp=1.3, y.intersp=1.2, title.col="darkred",
  title="  Alendronate treatment  ")

Presentation quality graph using the legend() function.



Rather than using the legend() function, nice labels/legends are easily made using points() and text() and with greater flexibility, in my opinion.

# -----------------------
# ALTERNATIVE to legend() -- nice labels by points() and text() --
# -----------------------

plot(time, spine, cex=1.2, ylim=c(.6, .9), type="b", cex.lab=1.3,
     xlab="Time from Baseline, months", ylab="Bone Density, g/cm^2")
points(time, hip, cex=1.2, pch=16, type="b" )

points(60, .78, pch=1, cex=1.5)              # put label
text(62, .78, "Lumbar Spine", pos=4, font=3) # within graph

points(60, .75, pch=16, cex=1.5)             # label
text(62, .75, "Temporal Neck (hip)", pos=4, font=3)



The simple graph has brought more information to the data analyst’s mind than any other device.
John Tukey (1915-2000) Princeton University



14.5.4   Graphs with statistical results

Often, we wish to put statistical results within a graph, whether it’s draft quality, presentation quality or publication quality.

plot(time, spine, cex=1.2, ylim=c(.6, .9), type="b", cex.lab=1.3,
     xlab="Time from Baseline, months", ylab="Bone Density, g/cm^2")
points(time, hip, cex=1.2, pch=16, type="b" )

points(62, .78, pch=1, cex=1.5)              # put label
text(64, .78, "Lumbar Spine", pos=4, font=3) # within graph

points(62, .75, pch=16, cex=1.5)             # label
text(64, .75, "Temporal Neck (hip)", pos=4, font=3)


# add OLS linear regression fit with slope & p-value ----------

spine.reg <- lm(spine ~ time) # perform OLS linear regression, spine by time
hip.reg   <- lm(hip ~ time)   #  "      "    "      "        , hip by time

abline(spine.reg, col="gray", lwd=2, lty=2) # add linear regression fits
abline(hip.reg,   col="gray", lwd=2, lty=2)

#summary(spine.reg) # slope .0008802, r-sq .86 # inspect the regression object
#summary(hip.reg)   # slope .0003133, r-sq .38 #   "

# add stats within graph --------------------------------------------------

# add r-sq% with correlation p-value -------------------------
#text(13, .85, "r-sq = 86%\np = 0.00046(1)", cex=1) 
#text(13, .68, "r-sq = 38%\np = 0.052(1)", cex=1)   

# add linear regression slope, with p-value ------------------ 
#text(13, .85, "slope = .0008802 \np = 0.00046(1)", cex=1) 
#text(13, .68, "slope = .0003133 \np = 0.052(1)", cex=1)   

# add r-sq%, linear regression slope, with p-value ----------- 
text(13, .86, "r-sq = 86%\nslope = 0.0008802\np = 0.00046(1)", cex=1) 
text(13, .69, "r-sq = 38%\nslope = 0.0003133\np = 0.052(1)", cex=1)

mtext(paste("Bone density increased significantly with time\nfor Lumbar Spine",
            "but not for Hip"), side=3, line=1, cex=1.5, col="darkred")

mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")


14.5.5   Additional analysis

So far for this data set, we have stored and used vectors. Now, pouring the data into a row-by-column data frame object is needed to proceed.

# ---------------------
# construct data frame  of 12 rows by 3 columns: months, dens, bone ----------
# ---------------------

dens <- c(spine, hip) # combine response vectors into one numeric vector 
bone <- c(rep("spine", 8), rep("hip", 8)) # create matching, grouping variable

# change character vector 'bone' to a factor
# specify desired 'order' of factor levels
bone <- factor(bone, levels=c("spine", "hip"))
 
months <- c(time, time) # the 'months' column: numeric vector

dfr <- data.frame(months, dens, bone) # attach the 3 vectors as columns

str(dfr)     # checking
## 'data.frame':    16 obs. of  3 variables:
##  $ months: num  0 8 18 48 64 66 79 92 0 8 ...
##  $ dens  : num  0.797 0.806 0.817 0.825 0.837 0.841 0.886 0.881 0.643 0.638 ...
##  $ bone  : Factor w/ 2 levels "spine","hip": 1 1 1 1 1 1 1 1 2 2 ...
summary(dfr) # checking
##      months           dens           bone  
##  Min.   : 0.00   Min.   :0.6380   spine:8  
##  1st Qu.:15.50   1st Qu.:0.6502   hip  :8  
##  Median :56.00   Median :0.7385            
##  Mean   :46.88   Mean   :0.7462            
##  3rd Qu.:69.25   3rd Qu.:0.8280            
##  Max.   :92.00   Max.   :0.8860
dfr          # print data frame
##    months  dens  bone
## 1       0 0.797 spine
## 2       8 0.806 spine
## 3      18 0.817 spine
## 4      48 0.825 spine
## 5      64 0.837 spine
## 6      66 0.841 spine
## 7      79 0.886 spine
## 8      92 0.881 spine
## 9       0 0.643   hip
## 10      8 0.638   hip
## 11     18 0.648   hip
## 12     48 0.674   hip
## 13     64 0.640   hip
## 14     66 0.676   hip
## 15     79 0.651   hip
## 16     92 0.680   hip

We seek a batch of statistics for each of the two groups – the spine density x,y data set and the corresponding hip density data set. Having all the data organized in a data frame is always helpful and usually necessary.

14.6   R Editor file – the final program


As broken down and developed step-by-step in the Sections above, the complete R Editor file is available below in a scrolled window.

Read and study the code. Either type it in yourself (preferable), copy/paste it, or otherwise “acquire” this R Editor file. Own it by putting your name within the file name. Submit its code blocks, top-down and interactively at the R Console.

Experiment by changing the arguments in the graph functions and practice flipping between presentation quality and publication quality graphs, using comment in and comment out. Remember: >?fun.name

This R Editor file reflects a typical workflow we often follow in R code development. It’s well-commented throughout and retains the beginning, minimal calls and the intermediate code, not just the code for say, a final, high quality graph.

It also makes modest use of text output from R Console, pasted in as lines, commented out. This is a convenience, to inform the investigator while coding. In other words, to make it easy for the coder to see salient results that may provide guidance and ideas.

You may also notice this file contains more R code than explicitly explained above. And, it may have minor stylistic differences from the above, code block by code block breakdown.

(A substantial task would be to transform the contents of this R Editor file, into a new function.)



Click to scroll the entire R Editor file in a blue block – click again to remove

# bone density Arlo.R    January, 2022    Arlo Atz, BS

# Bone density was measured over 92 months in a 65 year old woman with low bone
# density, treated with Alendronate, 2002 through 2009. Bone mineral density 
# (g/cm^2) was measured for lumbar spine and femoral neck(hip) (Rosner, B. 2016).

time <- c(0, 8, 18, 48, 64, 66, 79, 92)  # months from baseline

spine <- c(.797, .806, .817, .825, .837, .841, .886, .881) # spine bone density
hip   <- c(.643, .638, .648, .674, .64,  .676, .651, .68)  # hip    "     "

# view data at R Console to check carefully, versus original
cbind(time, spine, hip)

#     time spine   hip
#[1,]    0 0.797 0.643
#[2,]    8 0.806 0.638
#[3,]   18 0.817 0.648
#[4,]   48 0.825 0.674
#[5,]   64 0.837 0.640
#[6,]   66 0.841 0.676
#[7,]   79 0.886 0.651
#[8,]   92 0.881 0.680

# ------------------------
# preliminary scatterplots -------------------------------
# ------------------------

plot(time, spine) # 'spine' scatterplot: bone density by time
plot(time, hip)   # 'hip'   scatterplot:   "    "     "   "

# both lines must fit in the same graph, so get global min,max for y
range(c(spine, hip))  # min, max: .638 to .886

# minimal graph as proof of concept ----------------------------
plot(time, spine, type="b", ylim=range(c(spine, hip))) # spine data
points(time, hip, type="b", pch=16)                    # add hip data


# ----------------------------------------------------
# Enhanced, point and line graph: 2 sets of x,y points --------------
#   with each line labeled within the graph    
# ----------------------------------------------------

plot(time, spine, 
  col="black",  # color of points; default, col="black"
  cex=1,        # size of symbol plotted; default, cex=1
  ylim=range(c(spine, hip)),  # adjust y-axis range
  xlim=c(-5, 100),            #   "    x-axis  "
  las=0,      # flip y-axis tick labels, las=1; default: las=0
  type="b",   # default: type="p" points only; "b" both; "l" line only; "n", "h" 
  main="Bone density with Alendronate treatment\n65 year old female patient",
  xlab="Time from Baseline, months", 
  ylab="Bone Density, g/cm^2", 
  font.lab=2, cex.lab=1.4, cex.axis=1.2,  # label & axis typography
  cex.main=1.8, col.main="darkred"       # title typography
)

# add 2nd set of points with connecting line --------
points(time, hip, pch=16, type="b")

# label each line ------------------------------------------
text(20, .85, "Lumbar Spine", font=1, cex=1.2, col="darkred")
text(20, .69, "Temporal Neck (hip)", font=1, cex=1.2, col="darkred")

# add personalized time stamp; good for presentation quality graph ---------
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")


# ------------------------------
# Enhanced GRAPH, using legend()  -- use of legend() is OPTIONAL in Bio 240 ---
#   BUT, adding labels within graphs and in graph margins, is required
# ------------------------------

cx1 <- 1.6; cx2 <- 1.2; cx3 <- 1.8  # vars for typography convenience
c1 <- "darkred"

plot(time, spine,
  type="b", 
  bty="l",  # type of 'box'; default: "o", "l", "7", "c", "u", "]"  
  ylim=c(.62, .9),   # x-axis range
  xlim=c(-5, 100),   # y-axis range
  cex=1.4, cex.lab=cx1, cex.axis=cx2, font.lab=1, # typography
  cex.main=cx3, col.main=c1, col.lab=c1,          # typography
  xlab="Time from Baseline, months",
 
  ylab="",   # turn-off y-axis label if doing it by mtext()
  #ylab="Bone Density, g/cm^2", 
  #ylab=expression("Bone Density, g/cm" ^2),

  main="Bone density with Alendronate treatment\n65 year old female patient"
  #main="65  year  old  female  patient", cex.main=cx3
)

# use mtext() for y-axis label to deal with crowding issue 
mtext(expression("Bone Density, g/cm" ^ 2), side=2,
      line=2.3, cex=cx1, col=c1, font=1)

points(time, hip, pch=16, cex=1.4, type="b") # add hip x,y data
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")

# ------------------------
# legend() takes many args --- Optional in Bio 240 -------
# ------------------------

legend(x=55, y=.79,   # x,y for top-left corner, by trial-and-error
  legend=c("Lumbar Spine", "Temporal Neck (hip)"), 
  pch=c(1, 16), cex=1.2, text.font=3, pt.cex=1.5,
  x.intersp=1.3, y.intersp=1.2, title.col="darkred",
  title="  Alendronate treatment  ")

# -----------------------
# ALTERNATIVE to legend() -- nice labels by points() and text() --
# -----------------------

plot(time, spine, cex=1.2, ylim=c(.6, .9), type="b", cex.lab=1.3,
     xlab="Time from Baseline, months", ylab="Bone Density, g/cm^2")
points(time, hip, cex=1.2, pch=16, type="b" )

points(62, .78, pch=1, cex=1.5)              # put label
text(64, .78, "Lumbar Spine", pos=4, font=3) # within graph

points(62, .75, pch=16, cex=1.5)             # label
text(64, .75, "Temporal Neck (hip)", pos=4, font=3)

# add OLS linear regression fit with slope & p-value ----------

spine.reg <- lm(spine ~ time) # perform OLS linear regression, spine by time
hip.reg   <- lm(hip ~ time)   #  "      "    "      "        , hip by time

abline(spine.reg, col="gray", lwd=2, lty=2) # add linear regression fits
abline(hip.reg,   col="gray", lwd=2, lty=2)

summary(spine.reg) # slope .0008802, r-sq .86 # inspect the regression object
summary(hip.reg)   # slope .0003133, r-sq .38 #   "

# add stats within graph --------------------------------------------------

# add r-sq% with correlation p-value -------------------------
#text(13, .85, "r-sq = 86%\np = 0.00046(1)", cex=1) 
#text(13, .68, "r-sq = 38%\np = 0.052(1)", cex=1)   

# add linear regression slope, with p-value ------------------ 
#text(13, .85, "slope = .0008802 \np = 0.00046(1)", cex=1) 
#text(13, .68, "slope = .0003133 \np = 0.052(1)", cex=1)   

# add r-sq%, linear regression slope, with p-value ----------- 
text(13, .86, "r-sq = 86%\nslope = 0.0008802\np = 0.00046(1)", cex=1) 
text(13, .69, "r-sq = 38%\nslope = 0.0003133\np = 0.052(1)", cex=1)

mtext(paste("Bone density increased significantly with time\nfor Lumbar Spine",
            "but not for Hip"), side=3, line=1, cex=1.5, col="darkred")

mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")


# ---------------------
# construct data frame  of 12 rows by 3 columns: months, dens, bone ----------
# ---------------------

dens <- c(spine, hip) # combine response vectors into one numeric vector 
bone <- c(rep("spine", 8), rep("hip", 8)) # create matching, grouping variable

# change character vector 'bone' to a factor
# specify desired 'order' of factor levels
bone <- factor(bone, levels=c("spine", "hip"))
 
months <- c(time, time) # the 'months' column: numeric vector

dfr <- data.frame(months, dens, bone) # attach the 3 vectors as columns

str(dfr)     # checking
summary(dfr) # checking
dfr          # print data frame

#   months  dens  bone
#1       0 0.797 spine
#2       8 0.806 spine
#3      18 0.817 spine
#4      48 0.825 spine
#5      64 0.837 spine
#6      66 0.841 spine
#7      79 0.886 spine
#8      92 0.881 spine
#9       0 0.643   hip
#10      8 0.638   hip
#11     18 0.648   hip
#12     48 0.674   hip
#13     64 0.640   hip
#14     66 0.676   hip
#15     79 0.651   hip
#16     92 0.680   hip
# -----------------------------------------


# ------------------------
# some statistics by group, by some R programming ------------
# ------------------------

#  >?tapply  # for documentation on this handy function

N      <- tapply(dens, bone, length) # vector of sample sizes per group
Mean   <- tapply(dens, bone, mean)   # means
Median <- tapply(dens, bone, median) # medians
SD     <- tapply(dens, bone, sd)     # standard deviations
Min    <- tapply(dens, bone, min)    # minimum
Max    <- tapply(dens, bone, max)    # maximum

spine.r <- cor(time, spine) # Pearson r, spine density vs. time
hip.r   <- cor(time, hip)   # Pearson r, hip density vs. time

p.spine <- cor.test(time, spine, alt="greater")$p.value # p-value of r, one-sided
p.hip   <- cor.test(time, hip, alt="greater")$p.value

LB.CI.spine <- cor.test(time, spine)$conf.int[1] # LB 95% CI of r
LB.CI.hip   <- cor.test(time, hip)$conf.int[1]

UB.CI.spine <- cor.test(time, spine)$conf.int[2] # UB 95% CI of r
UB.CI.hip   <- cor.test(time, hip)$conf.int[2]

# statistical power analysis by package 'pwr' ------------
# 'power of the test' for signif. of Pearson r at alpha .01, one-sided

library(pwr) # statistical power analysis by normal theory after Cohen

# statistical power of cor.test at alpha .01, one-sided ---------

pwr.spine <- pwr.r.test(n=8, r=cor(time, spine), sig.level=.01, 
                             alt="greater", power=NULL)$power
pwr.hip <- pwr.r.test(n=8, r=cor(time, hip), sig.level=.01, 
                           alt="greater", power=NULL)$power

# ----------------------------------------------
# pour stats by group (spine, hip) into a matrix to view -------
#     the NA is there just as a spacer
# ----------------------------------------------

mat <- rbind(N, Mean, Median, SD, Min, Max, NA,  
             Pearson.r=c(spine.r, hip.r),
             r.sq.percent=c(spine.r, hip.r)^2* 100,
             r.p.value1sided=c(p.spine, p.hip),
             r.LB.95.CI=c(LB.CI.spine, LB.CI.hip),
             r.UB.95.CI=c(UB.CI.spine, UB.CI.hip),
             r.power.01.one.sided=c(pwr.spine, pwr.hip) )
              
colnames(mat) <- c("Spine bone density", " Hip density")
print(format(mat, scientific=F, digits=3), quote=F)

#                     Spine bone density  Hip density
#N                     8.000000           8.000000   
#Mean                  0.836250           0.656250
#Median                0.831000           0.649500    
#SD                    0.032631           0.017474   
#Min                   0.797000           0.638000   
#Max                   0.886000           0.680000   
#                            NA                 NA   
#Pearson.r             0.927236           0.616283   
#r.sq.percent         85.976720          37.980533   
#r.p.value1sided       0.000456           0.051858   
#r.LB.95.CI            0.642130          -0.156242   
#r.UB.95.CI            0.987003           0.920990   
#r.power.01.one.sided  0.922672           0.247601    

# ----------------------------------
# two-way ANOVA to compare the means ------------------------
# ----------------------------------

anova(lm(dens ~ bone + factor(months), data=dfr)) # two-way ANOVA, no interaction

#Response: dens
#               Df   Sum Sq  Mean Sq  F value    Pr(>F)    
#bone            1 0.129600 0.129600 314.8907 4.451e-07 
#factor(months)  7 0.006710 0.000959   2.3291    0.1436    
#Residuals       7 0.002881 0.000412   
 
# comparison of mean, spine density vs. hip: diff= -.18, p=4.45e-7
# comparisons of mean density at month 0, against the other months
#       mean density, only different from time zero,  
#              at 79 months, p=.048 & 92 months, p=.021

summary(lm(dens ~ bone + factor(months), data=dfr))
#Coefficients:
#                 Estimate Std. Error t value Pr(>|t|)    
#(Intercept)       0.81000    0.01521  53.235 2.16e-10 
#bonehip          -0.18000    0.01014 -17.745 4.45e-07  <- highly significant 
#factor(months)8   0.00200    0.02029   0.099   0.9242    
#factor(months)18  0.01250    0.02029   0.616   0.5573    
#factor(months)48  0.02950    0.02029   1.454   0.1892    
#factor(months)64  0.01850    0.02029   0.912   0.3921    
#factor(months)66  0.03850    0.02029   1.898   0.0995   
#factor(months)79  0.04850    0.02029   2.391   0.0481  <- barely significant
#factor(months)92  0.06050    0.02029   2.982   0.0205  <- significant


# effect on two-way Anova, of removal of the last data point: month 92  -------
# ----------------------------------------

# dfr[c(-8, -16), ]   will delete row 8 and 16, and return all 3 columns

# r= .89745, p= .003058(1)     << spine >>
cor.test(~ dens + months, data=dfr[c(-8, -16), ], subset=bone=="spine", alt="greater") 

# r= .4587, p= .1503(1)        <<  hip  >>
cor.test(~ dens + months, data=dfr[c(-8, -16), ], subset=bone=="hip",  alt="greater") 

anova(lm(dens ~ bone + factor(months), data=dfr[c(-8, -16), ])) # two-way ANOVA no interaction

#Response: dens
#               Df   Sum Sq  Mean Sq  F value    Pr(>F)    
#bone            1 0.109651 0.109651 250.2507 4.047e-06 ***
#factor(months)  6 0.004029 0.000671   1.5324    0.3086    
#Residuals       6 0.002629 0.000438           

summary(lm(dens ~ bone + factor(months), data=dfr[c(-8, -16), ]))

# comparisons of mean density at time 0, against times: 8,18,48,64,66,79
#       mean density at 0 months not different from other months

#Coefficients:
#                 Estimate Std. Error t value Pr(>|t|)    
#(Intercept)       0.80850    0.01582  51.095 3.77e-09 
#bonehip          -0.17700    0.01119 -15.819 4.05e-06  <- highly significant
#factor(months)8   0.00200    0.02093   0.096   0.9270    
#factor(months)18  0.01250    0.02093   0.597   0.5722    
#factor(months)48  0.02950    0.02093   1.409   0.2084    
#factor(months)64  0.01850    0.02093   0.884   0.4108    
#factor(months)66  0.03850    0.02093   1.839   0.1155    
#factor(months)79  0.04850    0.02093   2.317   0.0597  <- not significant 


# --------------------------------------------
# is spine density correlated with hip density for this -------------------
#    65 yr. old female patient, across the 92 month period?
# --------------------------------------------

plot(spine, hip)
lines(lowess(spine, hip), col="red", type="l")
cor.test(spine, hip) # r= .4796  p= .2291(2) 

# ------------------------------------------------------------------------
# VISUALIZATION of Pearson r with 95% CI, for 
#               spine and hip, bone density by time data
# 
# NOTICE that by cor.test() the traditional 95% confidence intervals of 
# Pearson r, overlap considerably. This indicates the two correlations are
# not significantly different. 
#
# AND, due to small sample size, both 95% CIs are very wide.  
# ------------------------------------------------------------------------

# a draft quality plot to visualize the 2 Pearson r values 
# with their traditional lower and upper bound of 95% CIs

# two-sided cor.test() just for 95% CI of Pearson r -- conventional way
# the 2 Pearson 95% CIs overlap!

LB.CI.spine <- cor.test(time, spine)$conf.int[1]  # spine 95% CI=.642, .987
UB.CI.spine <- cor.test(time, spine)$conf.int[2]
 
LB.CI.hip <- cor.test(time, hip)$conf.int[1]  # hip 95% CI= -.156, .921
UB.CI.hip <- cor.test(time, hip)$conf.int[2]

spine.r <- cor(time, spine)
hip.r   <- cor(time, hip)

# prepare vectors for stripchart() graph 
#   of the 2 r values w/95% CIs          -------------------

y     <- c(cor(spine, time), cor(hip, time))
group <- c("Spine", "Hip")
group <- factor(group, levels=c("Spine", "Hip"))

stripchart(y ~ group, vertical=TRUE, 
  xlim=c(.2, 2.8), ylim=c(-.15, 1), pch=16, cex=2, 
  xlab="Bone Mineral Density", ylab="Pearson correlation",
  cex.lab=1.3, cex.axis=1.3, cex.main=1.5, 
  main="Pearson r with traditional, 95% Confidence intervals")

lines(x=c(1,1), y=c(LB.CI.spine, UB.CI.spine), lwd=3, col="lightblue") 
lines(x=c(2,2), y=c(LB.CI.hip, UB.CI.hip), lwd=3, col="lightblue") 
points(c(1,2), c(spine.r, hip.r), pch=16, cex=2) # intentional overplot

abline(h=c(0,1), lty=2) # add horizontal dotted lines at r=1, r=0 --------- 

mtext("SPINE bone density\nby time, n=8", line=-3.9, adj=.03, cex=1, col="red") 
mtext("HIP bone density\nby time, n=8", line=-10, adj=.95, cex=1, col="red") 

text(1.76, c(hip.r, UB.CI.hip, LB.CI.hip), 
  c(round(hip.r,3), round(UB.CI.hip,3), round(LB.CI.hip,3)), cex=1.2)

text(1.24, c(spine.r, UB.CI.spine, LB.CI.spine), 
  c(round(spine.r,3), round(UB.CI.spine,3), round(LB.CI.spine,3)), cex=1.2)

text(.6, .22, paste("Visualization of the\n2 correlations with 95% CIs", 
  "\nby Fisher's Z transform\nand t-distribution"), col="gray", srt=45)

text(1.5, .22, paste("Note the wide width of each CI\n",
  "and how much the\n2 Confidence Intervals\noverlap"), col="gray", srt=45)

text(2.5, -.01, "zero correlation", col="gray", cex=.8)
text(2.5, .99, "perfect, positive correlation", col="gray", cex=.8)


# ------------------------------------------------------------------
# PERMUTATION test for difference between the 2 Pearson CORRELATIONS 
#      for SPINE vs. HIP bone density by time
# ------------------------------------------------------------------

# Various formal tests for difference between two Pearson r values are 
# found and argued about in textbooks. But, this small sample is ideal 
# for a permutation test which if done properly, is unassailable.    

# .3109528, our test stat, delta Pearson's, spine.r minus hip.r
diff <- cor(spine, time) - cor(hip, time) 

# get standard normal deviates independently for each sample, spine & hip
densZ <- c((spine - mean(spine))/sd(spine), (hip - mean(hip))/sd(hip)) 
densZ

diff <- cor(time, densZ[1:8]) - cor(time, densZ[9:16])

# the 2 r values and 'diff' are the same but now data as Z scores, 
# is on the same scale for both spine and hip  

# the replicate() function is the loop iterator ----------------
# vectors for replicate() -- 
#      'time'  is n=8,  0 to 92 months
#      'denzZ' is n=16; n=8 spine, n=8 hip density
#
#  we  index densZ[1:8] for spine
#      index densZ[9:16] for hip


# number of permutations (shuffles) of global 'densZ' -- start low, go high
NS <- 1e5  

timer <- proc.time()[[3]]  # initialize timer for 'replicate' loop; grabs current time

null.diff <- replicate(NS, 
             {densZ <- sample(densZ); cor(time, densZ[1:8]) - cor(time, densZ[9:16])})

timer <- proc.time()[[3]] - timer # total seconds elapsed by replicate() loop
timer # seconds required

# query the 'null.diff' vector for how many are >= to test stat, 'diff' -----

NGE1 <- length(null.diff[null.diff >= diff])  # one-sided NGE, number greater >= to diff
p1   <- (NGE1 + 1)/(NS + 1)                   # one-sided p-value for difference
                                              # between the two, r values

NGE2 <- length(null.diff[abs(null.diff) >= abs(diff)]) # two-sided NGE
p2   <- (NGE2 + 1)/(NS + 1) # two-sided                # two-sided p-value

main.string <- paste("Distribution of Pearson correlation 'difference'",
                     "(spine r - hip r)\n",
                     "under global permutation of bone density Z-scores")

# visualize the null distribution of difference 
# between the two correlations, under permutation ----------------------

hist(null.diff, 
  main=main.string,
  col="lightblue", xlim=range(null.diff), 
  border="white",
  xlab="Null difference between correlations",
  cex.lab=1.3)

abline(v=diff, col="red", lwd=3)
mtext(paste("Test Statistic:  spine r - hip r  = ", round(diff,5)), 
      line=-.5, adj=.01)
mtext(paste("NS =", NS, "permutations"), line=-1.7, 
      adj=.05, cex=1, font=2, col="blue")

mtext("Pearson correlation for\nbone density by months", 
       line=-5.3, adj=.05, col="blue")
mtext("spine:  r = 0.927", line=-7, adj=.1, col="blue")
mtext("hip:  r = 0.616",   line=-8, adj=.132, col="blue")

mtext(paste("p =", signif(p1,4), "(1), NGE =", NGE1), line=-1, adj=.95)
mtext(paste("p =", signif(p2,4), "(2), NGE =", NGE2), line=-2, adj=.95)
mtext("p = (NGE + 1) / (NS + 1)", line=-3.5, adj=.95)

mtext("< Permutation Test >", line=-6.5, adj=1, font=2, col="blue")
mtext("null hypothesis:\nspine r  =  hip r", line=-9, adj=1, col="blue")
mtext("alternate hypotheses:\nspine r  =  hip r\nspine r  > hip r", 
      line=-12.5, adj=1, col="blue")

mtext("For NS --\nstart low, go high
      then check for\nstability of p-value
      in repeated runs",
      line=-20, adj=1, cex=.8, col="black")

mtext("Red line -- observed test statistic:  0.31095", side=1, line=4, 
       adj=0, cex=.9, col="red")
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.8, col="gray")
mtext(paste("Elapsed: ", signif(timer,4), "sec."), side=1, adj=1, line=2)



# NOTE: In any permutation test, we're concerned about stability of p-values in repeated
# runs at the same NS. We seek stable results, recognizing that the combinatorial outcome
# space may be vast. But here, it's rather low at 16!/(8!*8!)=12,500 possible, unique 
# global shuffles of bone density.  
# By R code:   > factorial(16)/(factorial(8)*factorial(8))   

# run of NS 1e5  p=.2838(1) ; p=.5733(2)  ; 3.85 seconds elapsed 
# run of NS 1e5  p=.2866(1) ; p=.5727(2)  ; 3.96 seconds elapsed 
# run of NS 1e5  p=.2880(1) ; p=.5762(2)  ; 3.80 seconds elapsed 
# run of NS 1e5  p=.2873(1) ; p=.5740(2)  ; 3.85 seconds elapsed 
# run of NS 1e5  p=.2887(1) ; p=.5763(2)  ; 3.56 seconds elapsed 

# --------
# box plot ------------------
# --------

boxplot(dens ~ bone, data=dfr, 
  xlab="65 year old female patient", 
  main="Alendronate treatment", cex.main=2, 
  ylab="Bone Density, g/cm^2", 
  cex.lab=1.45, cex.axis=1.5, col.lab="darkred", 
  names=c("Spine", "Hip"),
  col=c("gray", "lightblue"),
  ylim=c(.6, .9)) 

text(c(1,2), .6, "n = 8", cex=1.4)

# -------------------------------
# lowess fit through the points; locally weighted,
#   nonparametric nonlinear fit using lowess()    ---------
# -------------------------------

plot(time, spine, ylim=c(.6, .9), type="b", cex.lab=1.2,
    xlab="Time from Baseline, months", ylab="Bone Density, g/cm^2")
points(time, hip, pch=16, type="b" )

points(62, .78, pch=1, cex=1.5)
text(64, .78, "Lumbar Spine", pos=4, font=3)

points(62, .75, pch=16, cex=1.5)
text(64, .75, "Temporal Neck (hip)", pos=4, font=3)

lines(lowess(time, spine), lwd=2, col="red")
lines(lowess(time, hip), lwd=2, col="red")

# ------------------------
# Bayes Factor Correlation -------
# ------------------------

library(BayesFactor)

correlationBF(time, spine) # 10.14651 +- 0%
correlationBF(time, hip)   #  1.4675  +- 0%


# ------------------------------
# --------- SUMMARY ------------
# ------------------------------

# Bone density was significantly and strongly positively correlated with time, 
# for << lumbar spine >>  but not for temporal neck << hip >> 
#
spine.reg # slope, b = .0008802   b*12 months = +0.0106 g/cm^2 per year 
hip.reg   # slope, b = .0003133   b*12 months = +0.0038  "   "   "

# check Rosner on metrics for bone rate of increase

# 2.8 times, slope for spine v. hip, rate of bone density increase  
# spine density increased 2.8 times as fast as hip density, per unit of time 

# In OLS linear regression, the 60 month (5 year) rate of bone density increase
# was 0.0xx g/cm^2 for lumbar spine P=0.000xxx) but for temporal hip, bone 
# density increase was not significantly different from zero (p=0.10).   
# Need the 12 month rate, vs. Rosner comments 

# end.  bone density Arlo.R


14.7   R Editor file – writing about the results


We must be able to write about our statistical results and graphical visualizations, and write in a style suitable for peer-review at a scientific journal as well as write in a style for the more general public.

For many, writing about statistical results is the hardest part.

It’s fun to save and manipulate our data. It’s always exciting to see the discoveries and the revelations from our graphs and from our statistical analyses. It’s what we live for as scientists.

All these tasks are skills, skills learned by practice and by reading scientific papers and technical books, to see how our peers do it.

Expect to spend a great deal of time writing a paragraph (or page) about a data set. It’s not easy. For me, it’s never easy but it’s always fulfilling.

You may need to write two versions – a version for the general, college educated public and a version for scientific peer-review, the former rather informal and the latter, highly technical. Inspection of these two contrasting styles informs us on how best to communicate our results.

I start by writing a good, solid statistical sentence. If I can do this, I can write a paragraph. If I can write a good paragraph I can write a page about my statistical results. Start small – a single sentence. Along the way, we profit by having colleagues read and edit our writing!

14.8   R Editor file – Prospectus: a new function?


In an above Section, I wrote – “Also for small sample sizes, we proceed with statistical analysis using caution, realizing it may have little if any, inferential value beyond the data at hand.”

Here, the data at hand are important to this patient and to her Physician!

We realize the 65 year old female patient’s Physician is seriously motivated to understand as much as possible from the patient’s x,y data for bone density by time, for both spine and for hips, given Alendronate treatment across 92 months.

She wants to pursue formal statistical analysis coupled with graphical visualization and she has some ability in R programming.

Her questions include:

  • Did Alendronate treatment work? Did bone density increase?
  • Was the treatment effect large or small?
  • Did the time-rate-of-change in bone density meet medical benchmarks?
  • Was there a difference in bone density response for spine versus hip?
  • From the time zero baseline, how long did it take for a significant increase in bone density to occur, if ever?
  • Should Alendronate treatment continue, cease, or be paused for say 6 months?

She treats many elderly women for Osteoporosis. In addition to Alendronate, other drugs are prescribed depending on the situation.

She reasons that writing custom R code for the specific case of this 65 year old woman, was worth the effort and she is rightfully proud of her code. However, writing and curating, custom R code developed for each of her many Osteoporosis patients is simply not practical, and such a practice would be error prone.

She knows that given the correct, reliable, clean and readable code in her R editor file created for the data of this one patient, she could generalize that code into a new R function.

This new function could be called for the x,y data from any Osteoporosis patient, given any drug not just Alendronate and given any dose across any time course.

Such a function, say boneDensity() would have arguments including for input of x,y data and for different bone types, arguments for whether to save the graphs as a multipage PDF file and text output to a text file or simply displayed on the screen with prompts to scroll.

She understands that converting her multiple pages of custom R code into a function, will take time and considerable effort but would support her Osteoporosis medical practice and be of great value in guiding her decisions on Osteoporosis treatment.

She also knows that calling a function is always much less error prone, easier and faster than interactively executing a very long, custom code block that must be manually edited (e.g., name changes for variables) to deal with every different data set.

In this document I do not engage this function creation, as much as it appeals to me.

The creation of this new function would be appropriate for a Biology BS Honors project. If fully developed, it would be appropriate for a Master’s Degree thesis in Biology.

In my opinion, a person taking on this task should contact local Physicians who treat Osteoporosis, present their function with output, request anonymous data from the medical practice, and give the function to them for their use, as appropriate.

I am sure that Osteoporosis Physicians would have great suggestions for the improvement and enhancement of this new function, whether dealing with data, statistical analysis, graphics or other metrics. Students, such is the stuff upon which careers are built.


14.9   R Editor file – recapitulation


R Coding conventions


valid & proper file names
comments
line spacing
line width: 85 characters max
indentation
content of first line of file
content of last line of file
valid names for objects
wise names for objects


As you type each line of your R code, as you construct each function call and for every R Editor file you create whether a large or small file, keep the above 9 points in mind. These 9 are structural coding conventions.

The result will be clean, readable, well-structured code that’s easy to run, to debug, to maintain, to change and to distribute to your collaborators or to the public.


R Coding behavior


patience
trial-and-error
start small
minimal calls
top-down
debugging
attention to detail
practice
read & study code
paper copy of code


Successful R coding for the graphical and statistical analysis of data is our goal. It involves structural, coding conventions like the 9 pictured previously.

Just as important is our personal behavior. By this I refer to our habits, our frame of mind and our work ethic while coding.


Coding takes patience and the cultivation of trial-and-error behavior. But that’s not all.

Start small when learning a programming environment like R. I think it’s best to start with small data sets that are easy to visualize and hopefully, relatively easy to understand, such as biomedical data. Also, start small in terms of your graphical and statistical aspirations for these small data sets. This approach builds confidence as you learn.

Even when we’re accomplished in R, it still pays to start small. On a new graphing project for instance, we code in step-wise fashion from small, minimal calls, to the final, desired graphs while debugging, saving and laying in comments along the way.

Start small, fail fast remains a wise, workflow adage across all computer languages.

A minimal call to a function uses the minimum number of arguments, below which it simply will not execute. We do this as proof of concept. Unless we can get a function to return the minimal, we can’t get it to return the complicated.

Remember, some functions can be called with zero args, such as date(). Most functions require one or two arguments to run, e.g.,   str()   hist(y)    plot(x, y)   boxplot(y ~ x).

It is common for a call to plot() to have 15 or so arguments. But, if we enter all those args before any execution along the way, then expect to see bewildering, noninformative error messages that compound and cascade down your long function call, making it impossible to find the error(s).

Errors in coding are most often punctuation errors, then spelling errors, then mental thinking errors. And, coding errors such as these can be hard to see, just like it’s often hard to see typos in our English prose.

Whether we’re talking about a function that’s new to us or one we know well (e.g., plot), being able to get it to “work” by a minimal call is the place to begin. Then, to achieve our final objectives, we add/change args and perhaps call other functions such as text()   mtext()   points()   lines()   legend() — functions that add material to the graph window.

In our workflow, as we move forward from a minimal call, we save the minimal call in our program and proceed coding in top-down fashion, sending the call with each new arg added or changed. This is especially important if we are unsure about function syntax or unsure about our choices of values typed-in for args or if we don’t yet know what the best graph for our data should be. This is how interactive coding sessions proceed.

We submit to the R Console, the function call with each change. If it throws an error, we know the locus of the error – the last line or so of code entered, not 10 lines upstream. This is top-down de-bugging. It works. It may seem slow and tedious but it saves time in the long run. It works, it works, it works – learn it.

Coding in R requires attention to detail as you must follow the syntax rules of the language in terms of spelling, and punctuation, such as, , : , ::, ( ) { } [ ] \

Students often fail to realize that practice is essential in using R for data analysis and graphics. You must practice running a program on many different data sets.

To become self-sufficient in R, one must read and study code. It’s not enough just to be able to run an R program that you wrote or that another person wrote.

You need to understand the code in your/our R programs. This requires us to read carefully and to study deeply, the code, if our aim is self-sufficiency.

In the late 1970s a Math Professor taught me an important lesson – There is no substitute for sitting down in a quiet place with a pencil and a paper copy of your computer program.

Way back then, we were coding in Applesoft BASIC (me) on revolutionary Apple II microcomputers (5.25 inch floppy drive, 48 KB RAM with BASIC in ROM, and at a $2,500 price point) and in C (him) on a primitive mainframe.

Now, I use R (mostly) and increasingly HTML5, CSS3, JavaScript, SVG and LaTex. Interestingly, R has contributed packages that allow native code from Python, C, C++, Julia and other languages, to be executed within R, and this remains appealing for the future growth of Bio 240 and derivative courses.


15   Closing material


15.1   on word clouds

The 19,000+ contributed R packages enable wonderful things, apart from just “graphs” and statistics.”

I find word clouds useful for display of key words and vocabulary. Creating a word cloud is not “statistics.” It’s an artistic exercise requiring considerable trial-and-error in function calls and in the use of arguments, to get a pleasing image. Word clouds are not part of Bio 240 but my R code below will work for your own word clouds. Try it!

Question: Does this word cloud omit important keywords or concepts in this document? Does it have irrelevant words? If so, can you see how to change the code? You can copy/paste any of my R code you see here, into your own R Editor file and proceed.

library(wordcloud2) # load package for word clouds calculated in R by C++ & rendered 
                    # to HTML & JavaScropt. We don't need to know C++ or HTML for 
                    # this -- that's the job of function wordcloud2()

word <- c("R", "data", "graphs", "Biostatistics", "Fall 2023", "coding", "histogram", 
        "scatterplot", "box plot", "Zoom", "twitter", "email", "kernel density", 
        "covid-19", "CDC", "Lehman College", "Bio 240", "time stamp", "the Bronx", 
        "moving average", "for loop", "data frame", "literate programming", 
        "reproducible research", "ugly code", "buggy code", "plot()", "mtext()", 
        "text()", "str()", "lines()", "function", "arguments", "comments", "lowess fit", 
        "HTML", "JavaScript", "head()", "vector", "mean", "median", "standard deviation", 
        "skew", "kurtosis", "source()", "tail()", "Shapiro-Wilk test", "abline()", 
        "summary()", "cases", "file path", "explicit indexing", "word cloud", "RStudio", 
        ".csv file", "descriptive statistics", "distribution", "Donald Knuth", 
        "Peter Dalgaard", "Paul Murrell", "distance learning", "density()", "polygon()", 
        "rnorm()", "wordcloud2()", "data table", "RPubs", "Blackboard", "points()", 
        "effect size", "Anova", "correlation", "statistical power", "Bayes Factor", 
        "Tukey's test", "t-test", "multiple comparisons", "Dunnett's test", 
        "assumptions", "bootstrap", "permutation tests", "confidence interval") 

freq <- c(19,6,6,8,4,6,2,2,2, rep(1,73))  # arbitrary 'frequency' for each word

d <- data.frame(word, freq, row.names=word)  # n=82 words

wordcloud2(d, size=1.1)



15.2   ugly code is buggy code


“Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to humans what we want the computer to do.”

Donald E. Knuth. 1984. Literate Programming. The Computer Journal 27(2): 97-111.
Download free PDF of this paper from the journal: https://academic.oup.com/comjnl/article/27/2/97/343244
Dr. Knuth is Professor Emeritus, Computer Science Department, Stanford University.


Relative to the importance of writing well structured, clean and readable code in R, Dr. Andrew Gelman of Columbia University (NYC) wrote a blog post to Statistical Modeling, Causal inference, and Social Science on 8 July 2020. He is renowned as Professor of Statistics and lead author on the acclaimed new book (Andrew Gelman, Jennifer Hill, Aki Vehtari. 2020. Regression and Other Stories. Cambridge University Press, 550 pages). Convincingly, he maintains in this blog post that ugly code is buggy code.

\[\mathbb {\huge UGLY\quad code\quad is\quad BUGGY\quad code}\]

As illustrated by an example of his own sometimes buggy R code, he stresses that we want “…to avoid tripping up and even publishing erroneous results.

He continues, “Anyway, the point of this post is just to demonstrate how, with sloppy code, you really have to keep your hands on the wheel at all times. Even such simple fitting is hard to do if you’re not continually checking results against your expectations.”

Finally, “To return to the title of this post: Ugly code is buggy code not just because it’s easier to introduce bugs and harder to find them if your code is poorly structured. It’s also that, for code to be truly non-buggy, it doesn’t just have to be free of bugs. You also have to know it’s free of bugs, so that you can use it confidently.” (bold font added by Kincaid; view original story with interesting comments by searching “buggy code” at https://statmodeling.stat.columbia.edu, or see my 8/9/20 tweet @LC_biostat).

Consider my crude example below of why it’s so important to write clean, well-structured R code by making use of spacing, indentation and comments.

Let’s go back to section 14 and bring that code down here for the histogram annotated with descriptive statistics, p-value from the Shapiro-Wilk test of normality and a personalized time stamp.


\(\mathbb {\large Well\ Structured\ Code}\)   😄

y1 <- rnorm(60, 50, 9)   # 60 random numbers from normal distribution: mean 50, SD 9
m <- round(mean(y1), 2)           # get mean of y and round off to 2 decimals
s <- round(sd(y1), 3)             # get SD of y and round off
p <- round(shapiro.test(y1)$p, 3) # p-value from Shapiro-Wilk test of normality

hist(y1, 
     col="peru",         # color of histogram, default is "white"
     main=NULL,          # string for a title of histogram; NULL omits it
     cex.lab=1.4, cex.axis=1.3, las=1,   # typography of axes
     border="white",                     # color of lines around histogram bars
     xlab="Random sample from N(50, 9)") # x-axis label

clr <- "darkred" # color of text
mtext(paste("N =", length(y1)), adj=1, line=0,  cex=1, col=clr)
mtext(paste("Mean =", m),       adj=1, line=-1, cex=1, col=clr)
mtext(paste("SD =", s),         adj=1, line=-2, cex=1, col=clr)
mtext(paste(" Shapiro-Wilk p =", p), adj=0, line=0, cex=1, col=clr)
mtext(paste("Arlo: ", date()), side=1, adj=1, line=4, cex=.9,col="gray") # time stamp
mtext("clean, well structured code", side=3, line=2, col="black", font=2.2, cex=2.1)
13 lines of readable CODE to make the graph

13 lines of readable CODE to make the graph


The above code to make the graph is relatively easy to read, to understand, to de-bug, to change and to run. It resides on 13 lines.

\(\mathbb {\large Ugly\ Code}\)   😟

Now I turn this clean and readable, graph code into Ugly code by putting it all on one line. Why not? It’s debugged and works great. Why not condense it and make a shorter R program.

Below the Ugly code returns exactly the same graph as the clean code of 13 lines.

But, heaven forbid this condensed code should contain or acquire a bug – good luck finding the bug. And, since the structure of the function calls was destroyed by putting it all on one line, good luck trying to edit the code to make changes in the graph such as in colors, labels, font type and size, and so forth. Good luck trying to understand the code by looking at it sprawled across one line.

Line spacing, spreading out a long function call into several lines with indentation, along with liberal use of comments, generates code one can come back to in a month or in 6 months, read it and understand what you had in mind to start with; otherwise the code appears as gibberish.

The Ugly code of one long line (scrolled below) makes exactly the same graph as the well structured, 13 lines of code above.

hist(y1,col="peru",main=NULL,cex.lab=1.4,cex.axis=1.3,las=1,border="white",xlab="Random sample from N(50,9)");clr <- "darkred";mtext(paste("N =",length(y1)),adj=1,line=0,cex=1,col=clr);mtext(paste("Mean =",m),adj=1,line=-1,cex=1,col=clr);mtext(paste("SD =",s),adj=1,line=-2,cex=1,col=clr);mtext(paste(" Shapiro-Wilk p =", p),adj=0,line=0,cex=1,col=clr);mtext(paste("Arlo: ",date()),side=1,adj=1,line=4,cex=.9,col="gray"); mtext("U G L Y  C O D E", side=3, line=2, col="black", font=2, cex=2.5)
1 long line of unreadable CODE

1 long line of unreadable CODE


Writing code is like writing a poem to your mother-in-law; you are never satisfied; you never stop revising it.   All software resides under constant revision.   This applies equally to one of your many, relatively short, e.g., 1 or 2 pages, .R files that you will craft this semester, to my large .R files that define new functions useful for univariate data, one-way data, and for x,y data (K funs UNIVARIATE.R,   K funs ONE WAY.R,   K funs CORRELATION.R).   Even the code for base R itself, remains under constant revision.

“If debugging is the process of removing software bugs, then programming must be the process of putting them in.”
E. Dijkstra (1930, 2002) The originator of the structured programming movement, and more.

“Programmers often find that they spend more time debugging a program than actually writing it. Good debugging skills are invaluable,… Though debugging is an art rather than a science, it involves some fundamental principles.”
Norman Matloff (2011) The Art of R Programming, A Tour of Statistical Software

In Bio 240 we practice interactive, top-down coding and top-down debugging, using the write-execute loop between the R Editor and the R Console.   More advanced debugging strategies are beyond our time constraints in this course. Indeed, there are books on debugging and R packages devoted to it.

15.3   statistical wisdom


Across all biological and biomedical subject areas, we seek statistical wisdom in our research design, data acquisition, data wrangling, graphing, statistical analysis and in our ability to write about it all, in forms suitable for papers in peer-reviewed scientific journals and for formal presentations (poster sessions, live audience, interview).

The central path to statistical wisdom is to internalize, master and integrate a variety of contrasting, 1) statistical methods (traditional, nonparametric, computationally intensive, Bayesian) and 2) graphical visualizations, applied across many different data sets, of both small and large sample sizes.

We learn how to analyze data by analyzing data. Yes it’s largely, an acquired skill.

Statistical wisdom also involves wise naming for data variables, for R program files and for .csv data files.

As we study and learn, along our path to statistical wisdom, we soon identify 3 big things:  practice, practice, practice.

We enjoy a wonderful, empowering reality as we learn basic statistics writ large.

Early in any basic statistics course, we must master topics including, descriptive statistics (moments, quantiles), confidence intervals, effect sizes (e.g., Cohen’s d), statistical power analysis, and basic graphs (line graph, scatter plot, histogram, box plot, means with error bars, bar graphs). These are always used in scientific papers reflecting the latest cutting-edge research as published across the top, peer reviewed journals.

This stuff never goes out of date. Learning it is never wasted. It enhances your undergraduate Biology program at Lehman College. It helps make you competitive in professional career development.

The ability to handle data and do basic statistics and graphics by custom programming in R, enables research experiences, enhances postgraduate applications and keeps you on the fast track to success!

Hopefully, Bio 240. Biostatistics will help you move forward toward these goals.


15.4   final points


When you click on this HTML file, it opens in your web browser and R need not be present or running. This file will work on computers with any operating system (Win, macOS, Chrome OS, Linux distros).

The source code is a plain text file, a R markdown file .Rmd that is bound to HTML and JavaScript by the powerful R function knitr() and by pandoc (a Haskell library for document conversion to HTMl, ePub, PDF, OpenDocument, Word & PowerPoint, shiny web apps, and more). While pandoc is not part of R, it is downloaded by and made available automatically by RStudio which is the best environment for crafting reproducible research. Python programmers simply insert native Python code instead of R code in the code blocks.

As the semester proceeds you might find this entire, Syllabus HTML file handy for review of some topics covered in Bio 240.

Many Biology majors aspire to, and identify as pre-med. Some think computer programming is not relevant to the biomedical career path. Consider the statement in the picture below, from one of the world’s most prestigious medical facilities, The Cleveland Clinic (Cleveland, Ohio).


 Physicians who code could be the future of healthcare,... Physicians who code could be the future of healthcare,...

Physicians who code could be the future of healthcare,…


The journal \({\mathit Nature}\) is published in England, it covers all areas of science, it has an extremely high rejection rate on submitted papers and it compares favorably to our journal, \({\mathit Science}\) in terms of being arguably, the most prestigeous scientific journal in the world. Neither journal is open-access but both make some papers in each issue available to all.

\({\mathit Nature}\) has what it calls “collections” of papers, many of which are open-access. The collection, “Statistics for Biologists” is absolutely excellent. Find it from my August 26, 2020 twitter post, https://twitter.com/LC_biostat or visit https://www.nature.com/collections/qghhqm

\({\mathit Science}\) publishes \({\mathit Science\ Advances}\) which is completely open-access, multidisciplinary and is a highly recommended read for all of us. \({\mathit Science\ Advances}\) has a lively twitter site, https://twitter.com/ScienceAdvances and at https://advances.sciencemag.org each issue can be viewed free. You should regularly read \({\mathit Science\ Advances}\) to keep up with the scientific world as enjoyment and as part of your career development strategy. Remember, what courses require is only the top of the iceberg.

As a public service during the pandemic, \({\mathit Science}\) has a free site,
https://www.sciencemag.org/collections/coronavirus?IntCmp=coronavirussiderail-128 for “Coronavirus: Research, Commentary, and News” which provides open-access to many of their recent papers on covid-19.



Professional Career Development. In class I will discuss this topic which is optional material you will not be tested on.

It will involve case studies, advice from my experience, my personal stories, tips, ideas and challenges.

A solid career in science, medicine or science education does not happen automatically.

One reason I talk about career development in my classes is because when I was an undergraduate, no professors bothered to tell me these things. They either did not care, did not know, or both.


Succeed in your Career Development !

  ❶ Always show up & show up on time     ❷ Pay attention & take notes
  ❸ Work hard & ask questions       ❹ Be honest, don't cheat  
  ❺ Practice, practice, practice   ❻ Maintain a high GPA
  ❼ Join professional scientific societies & attend their meetings
  ❽ You must have a research experience to be competitive
  ❾ You should read books & journal papers, far beyond what's required


15.5   R Session information


To enhance the reproducibility of our R code in this document, we call the sessionInfo() function in base R. At the R Console enter >?sessionInfo for its documentation which will come up in your browser as an HTML file. This function returns a great deal of useful information about your current, R Session.

  sI <- sessionInfo()
  print(sI, locale=TRUE)
## R version 4.2.2 (2022-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 22621)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] wordcloud2_0.2.1       gapminder_1.0.0        plotly_4.10.2         
##  [4] BayesFactor_0.9.12-4.4 Matrix_1.6-0           coda_0.19-4           
##  [7] pwr_1.3-0              gplots_3.1.3           DescTools_0.99.49     
## [10] nortest_1.0-4          moments_0.14.1         psych_2.3.6           
## [13] ggwordcloud_0.5.0      ggplot2_3.4.2         
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.6         tidyr_1.3.0        sass_0.4.7         viridisLite_0.4.2 
##  [5] jsonlite_1.8.7     gtools_3.9.4       bslib_0.5.0        expm_0.999-7      
##  [9] gld_2.6.6          lmom_2.9           highr_0.10         cellranger_1.1.0  
## [13] yaml_2.3.7         pillar_1.9.0       lattice_0.21-8     glue_1.6.2        
## [17] digest_0.6.33      colorspace_2.1-0   htmltools_0.5.5    pkgconfig_2.0.3   
## [21] purrr_1.0.1        mvtnorm_1.2-2      scales_1.2.1       rootSolve_1.8.2.3 
## [25] MatrixModels_0.5-2 tibble_3.2.1       proxy_0.4-27       generics_0.1.3    
## [29] farver_2.1.1       ellipsis_0.3.2     cachem_1.0.8       withr_2.5.0       
## [33] pbapply_1.7-2      lazyeval_0.2.2     cli_3.6.0          mnormt_2.1.1      
## [37] magrittr_2.0.3     readxl_1.4.3       evaluate_0.21      fansi_1.0.4       
## [41] nlme_3.1-162       MASS_7.3-60        class_7.3-20       tools_4.2.2       
## [45] data.table_1.14.8  lifecycle_1.0.3    stringr_1.5.0      Exact_3.2         
## [49] munsell_0.5.0      compiler_4.2.2     jquerylib_0.1.4    e1071_1.7-13      
## [53] caTools_1.18.2     rlang_1.1.1        grid_4.2.2         rstudioapi_0.15.0 
## [57] htmlwidgets_1.6.2  crosstalk_1.2.0    bitops_1.0-7       labeling_0.4.2    
## [61] rmarkdown_2.23     boot_1.3-28.1      gtable_0.3.3       R6_2.5.1          
## [65] knitr_1.43         dplyr_1.1.2        fastmap_1.1.1      utf8_1.2.3        
## [69] KernSmooth_2.23-20 stringi_1.7.12     parallel_4.2.2     Rcpp_1.0.11       
## [73] vctrs_0.6.3        png_0.1-8          tidyselect_1.2.0   xfun_0.39
  # str(sI)  # comment-in for the STRUCTURE of the sessionInfo() object 

Question: Call the above R code using locale=FALSE and see what happens. Call the following functions, each with zero arguments: R.Version() , getRversion() , and R.home().   Then call R.version which is an operator that returns a list; compare it to the output from function R.Version() and inspect, str(R.Version). Remember that the invaluable and extremely commonly called, str function returns the structure of whatever object is named as its argument. Every class this semester, we will call the str function, for a variety of reasons.

__________________


The R website

https://r-project.orgClick to Explore it
  Click on CRAN where you install R
    Check out The R Journal
      Examine the Task Views
        Scan the thousands of contributed packages by A-Z name or by submission date




John Tukey (1915-2000)

John Tukey (1915-2000)


Finding the question is often more important than finding the answer.
— John Tukey, Princeton University and Bell Labs (1915 - 2000)




END of Bio 240 Syllabus, Fall 2023

R
data
graphs
statistics
writing about the results


Dwight Kincaid, PhD
Professor      

time stamp:   Thursday August 24, 2023 at 19:25:48
last rendered:   Thursday August 24, 2023 at 19:25:48

Bio 240. Biostatistics.   Fall 2023      Department of Biological Sciences   Lehman College   City University of New York   Bronx NY 10468 USA
LS0tDQp0aXRsZTogPGJyPjxicj4gJFxtYXRodHR7XEh1Z2UgU3lsbGFidXN9JCA8YnI+PGJyPjxicj4NCiAgICAgICBCaW8gMjQwICZuYnNwOyAkXG1hdGhjYWx7XExBUkdFIEJpb3N0YXRpc3RpY3N9JCA8YnI+PGJyPiANCiAgICAgICAzIGNyZWRpdHMgJm5ic3A7IDQgaG91cnMgJm5ic3A7IEZhbGwgMjAyMyA8YnI+PGJyPiANCg0Kc3VidGl0bGU6IERlcGFydG1lbnQgb2YgQmlvbG9naWNhbCBTY2llbmNlcywgJm5ic3A7IExlaG1hbiBDb2xsZWdlIDxicj4gDQogICAgICAgICAgQ2l0eSBVbml2ZXJzaXR5IG9mIE5ldyBZb3JrLCAmbmJzcDsgQnJvbngsICZuYnNwOyBOZXcgWW9yayAmbmJzcDsgDQogICAgICAgICAgMTA0NjggJm5ic3A7IFVTQSA8YnI+PGJyPiANCiAgICAgICAgICBCaW8gMjQwIGlzIHJlcXVpcmVkIGZvciB0aGUgQlMgZGVncmVlIGluIEJpb2xvZ3kgPGJyPjxicj4gICANCg0KYXV0aG9yOiA8YnI+IFByb2Zlc3NvciAmbmJzcDsgJFxtYXRoY2Fse1xIdWdlIER3aWdodFwgS2luY2FpZH0kICZuYnNwOyBQaEQgIA0KICAgICAgICA8YnI+PGJyPjxicj48YnI+ICANCiAgICAgICAgJFxtYXRoc2Z7XHNtYWxsIHNvdXJjZVwgY29kZVwgZmlsZTp9JCAgJmVtc3A7IA0KICAgICAgICAgICAgICAgYFN5bGxhYnVzX0Jpb18yNDAuUm1kYCA8YnI+IA0KICAgICAgICAgICAgICAgDQogICAgICAgICZlbXNwOyZlbXNwOyZlbXNwOyZuYnNwOyAkXG1hdGhzZntcc21hbGwgdGhpc1wgZmlsZTp9JCAgJmVtc3A7IA0KICAgICAgICAgICAgICAgYFN5bGxhYnVzX0Jpb18yNDAuaHRtbGAgJmVtc3A7IDxicj48YnI+IA0KICANCmRhdGU6ICAkXG1hdGhzZntcc21hbGwgZG9jdW1lbnRcIHJldmlzZWQ6fSQgICZuYnNwOyBBdWd1c3QgMjQsIDIwMjMgPGJyPjxicj48YnI+IA0KDQphYnN0cmFjdDogIHwgICAgICAgICMgdGhlIGNoYXJhY3RlcjogPiAgYWxzbyB3b3JrcyBsaWtlIHBpcGUgc3ltYm9sDQoNCiAgDQogIDxicj4gSW4gKipCaW8gMjQwKiogd2UgdXNlIHRoZSAqKlIqKiBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgZW52aXJvbm1lbnQgZm9yIHRoZSANCiAgZ3JhcGhpY2FsIHZpc3VhbGl6YXRpb24gYW5kIHN0YXRpc3RpY2FsIGFuYWx5c2lzIG9mIGJpb2xvZ2ljYWwgZGF0YS4gQSBjb21wdXRlciANCiAgaXMgcmVxdWlyZWQgKFdpbiBvciBNYWMsIGJ1dCBub3QgQ2hyb21lIE9TIGFzIGl0IGRvZXMgbm90IHJ1biAqKlIqKikuIFlvdSB3aWxsIA0KICBsZWFybiBob3cgdG8gd3JpdGUgcHJvZ3JhbXMgaW4gYmFzZSAqKlIqKiB0aGF0IGRlYWwgd2l0aCBkYXRhICgqc3RvcmUsIHJlYWQsIGVkaXQsIA0KICBtYW5pcHVsYXRlLCBncmFwaCwgZXhwbG9yZSwgYW5hbHl6ZSwgbW9kZWwqKS4gQmlvIDI0MCBpcyBiYXNlZCBvbiwgYW5kIHJlcXVpcmVzIA0KICB5b3UgdG8gbGVhcm4gdG8gdXNlICoqUioqIGluIHRoZSBhbmFseXNpcyBvZiBkYXRhLiA8YnI+ICANCiAgDQogIEJpbyAyNDAgKipMZWFybmluZyBHb2FsKiogOiAmbmJzcDsmbmJzcDsgRGF0YS1kcml2ZW4gYWJpbGl0eSB0byB1c2UgZ3JhcGhpY2FsIA0KICB2aXN1YWxpemF0aW9uIGFuZCBzdGF0aXN0aWNhbCByZWFzb25pbmcgaW4gQmlvbG9neSwgYnkgY3VzdG9tIGNvbXB1dGVyIA0KICBwcm9ncmFtbWluZyBpbiBiYXNlIFIuIDxicj4gIA0KICANCiAgKipSKiogaXMgZ2xvYmFsIGluIHJlYWNoLCBnbG9iYWxseSBjcm93ZC1zb3VyY2VkLCBtdWx0aWxpbmd1YWwsIHJldmlzZWQgZXZlcnkgNiANCiAgbW9udGhzIGFuZCByZW1haW5zIGZyZWUgYW5kIG9wZW4gc291cmNlIChodHRwczovL3d3dy5yLXByb2plY3Qub3JnKS4gKipSKiogKndhcyANCiAgd3JpdHRlbiBieSBzdGF0aXN0aWNpYW5zIGZvciBzdGF0aXN0aWNpYW5zKiBhbmQgY2FuIGJlIGNvdW50ZWQgb24gdG8gYmUgDQogICpzdGF0aXN0aWNhbGx5IGNvcnJlY3QqLiBBbGwgY29tbWVyY2lhbCBzdGF0aXN0aWNhbCBhcHBsaWNhdGlvbnMgKGUuZy4sIFNQU1MsIFNBUywgDQogIEpNUCwgU3RhdGEsIE1BVExBQiwgTWF0aGVtYXRpY2EsIEdyYXBoUGFkKSBhbmQgZXNwZWNpYWxseSBzcHJlYWRzaGVldHMgbGlrZSBFeGNlbCwgDQogIGFyZSBzaW1wbHkgbm90IGNvbXBldGl0aXZlIHdpdGggKipSKiogaW4gdGVybXMgb2YgZGVwdGgsIGJyZWFkdGgsIGlubm92YXRpb24gYW5kIA0KICBjdXR0aW5nLWVkZ2UgZmVhdHVyZXMuIFdpdGggcHJhY3RpY2UsICoqUioqIGlzIG5vdCBkaWZmaWN1bHQgdG8gdXNlLiA8YnI+ICANCiAgDQogIFRoaXMgc2VsZi1jb250YWluZWQgSFRNTCBmaWxlIGlzIHNwZWNpZmllZCBieSBhbmQgd2FzIHJlbmRlcmVkIGZyb20sIGEgDQogIDxtYXJrPi5SbWQ8L21hcms+IGZpbGUsIGFuICoqUiBNYXJrZG93bioqIGZpbGUsIHdoaWNoIGlzIGEgcGxhaW4gdGV4dCBmaWxlIA0KICBjb250YWluaW5nICoqUioqIGNvZGUgYW5kIHByb3NlICg8bWFyaz4uUm1kPC9tYXJrPiBzb3VyY2UgZmlsZSBkb3dubG9hZGFibGUgYnkgDQogICpDb2RlKiBidXR0b24sIHRvcCByaWdodCB0aGlzIHBhZ2UpLiBSIE1hcmtkb3duIGZpbGVzIGFyZSBlYXN5IHRvIHJlYWQgYW5kIA0KICByZWxhdGl2ZWx5IGVhc3kgdG8gd3JpdGUsIGdpdmVuIGEgZmV3IGRheXMgb2YgcHJhY3RpY2UuICoqUmVwcm9kdWNpYmxlIFJlc2VhcmNoKiogDQogIGlzIHRoaXMgbWVsZGluZyBvZiB3cml0aW5nLCBkYXRhLCBjb2RlLCBncmFwaHMgYW5kIHJlc3VsdHMsIHdpdGhpbiB0aGUgc2FtZSANCiAgZG9jdW1lbnQuIEl0J3MgdGhlIHdhdmUgb2YgdGhlIGZ1dHVyZSBpbiBTY2llbmNlIGJlY2F1c2UgKnJlcHJvZHVjaWJpbGl0eSBvZiANCiAgcmVzdWx0cyosIGdpdmVuIHRoZSBwcm9zZSwgY29tcHV0ZXIgcHJvZ3JhbSBhbmQgZGF0YSwgaXMgcGFyYW1vdW50LiBEdWUgdG8gDQogIHRpbWUgY29uc3RyYWludHMsIFJlcHJvZHVjaWJsZSBSZXNlYXJjaCBpcyBub3QgcGFydCBvZiBCaW8gMjQwIGJ1dCB0aGVyZSANCiAgd2lsbCBiZSBvcHRpb25hbCwgZXhwb3N1cmUgdG8gaXQuIDxicj4gIA0KICANCiAgU3R1ZHkgKipTZWN0aW9ucyAxLTEyKiogZm9yIGEgdHJhZGl0aW9uYWwgKlN5bGxhYnVzKi4gICANCiAgU3R1ZHkgKipTZWN0aW9ucyAxMyAmIDE0KiogZm9yICoqUioqIGNvZGluZywgIHJlbGV2YW50IHRvIHNvbWUgZ3JhcGhpY2FsIGFuZCANCiAgc3RhdGlzdGljYWwgbWV0aG9kcyB3ZSBjb3ZlciBpbiBCaW8gMjQwLiAgDQogIFN0dWR5ICoqU2VjdGlvbiAxNSoqIG9uIHdvcmQgY2xvdWRzLCBvbiB1Z2x5IGNvZGUgdmVyc3VzIGNsZWFuIHdlbGwgc3RydWN0dXJlZCANCiAgcmVhZGFibGUgY29kZSwgb24gY2FyZWVyIGRldmVsb3BtZW50IGFkdmljZSwgYW5kIG9uIHJlY292ZXJpbmcgUiBTZXNzaW9uIA0KICBpbmZvcm1hdGlvbi4gIA0KICANCiAgQ2xpY2sgb24gYSAqKlNlY3Rpb24qKiBqdXN0IGJlbG93IHRvIGdvIHRvIGl0LCBvciBzaW1wbHkgc2Nyb2xsIGRvd24gdGhpcyANCiAgZG9jdW1lbnQuIDxicj4gPGJyPiANCg0KICANCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogcmVhZGFibGUgICAgICMgZGVmYXVsdCBjZXJ1bGVhbiBqb3VybmFsIGZsYXRseSAgZGFya2x5IHJlYWRhYmxlICBzcGFjZWxhYiANCiAgICAgICAgICAgICAgICAgICAgICAgICMgdW5pdGVkICBjb3NtbyAgICBsdW1lbiAgIHBhcGVyICAgc2FuZHN0b25lICBzaW1wbGV4ICB5ZXRpDQogICAgaGlnaGxpZ2h0OiBkZWZhdWx0ICAjIHRhbmdvICAgcHlnbWVudHMga2F0ZSAgICB6ZW5idXJuICB0ZXh0bWF0ZSAgZGVmYXVsdCANCiAgICAgICAgICAgICAgICAgICAgICAgICMgbW9ub2Nocm9tZSAgZXNwcmVzc28gIGhhZGRvY2sgIGJyZWV6ZWRhcmsNCiAgICB0b2M6IHllcyAgICAgICAgICAgICMgVGFibGUgb2YgQ29udGVudHMNCiAgICB0b2NfZGVwdGg6IDQgICAgICAgICMgaW50ZWdlcg0KICAgIHRvY19mbG9hdDogbm8gICAgICAgIyBsb2dpY2FsLCB5ZXMgcHV0cyBpdCBvbiBsZWZ0IHBhbmVsDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZSAgICAjIHRydWUgIGZhbHNlDQogICAgY29kZV9mb2xkaW5nOiBzaG93ICAgICAjIHNob3cgIGhpZGUNCiAgICBhbHdheXNfYWxsb3dfaHRtbDogeWVzDQoNCi0tLQ0KDQoNCjxzdHlsZT4gICAgIA0KICAjc3R5bGVQUkVBTUJMRXsNCiAgICBkaXNwbGF5OiBibG9jazsgDQogICAgYm9yZGVyOiAuNXB4IHNvbGlkIGdyYXk7ICAgICAgLyogU1RZTEUgZm9yIG1vbm9zcGFjZSwgUiBjb2RlL3RleHQgYmxvY2sgKi8NCiAgICBmb250LWZhbWlseTogY291cmllcjsgICAgLyogc3RhdGljIGJsb2NrLCBOT1QgaW50ZXJhY3RpdmUgKi8NCiAgICBjb2xvcjogcmVkOyANCiAgICBiYWNrZ3JvdW5kOiBXaGl0ZVNtb2tlOyAvKiB3aGl0ZSBpdm9yeSBMaWdodFllbGxvdyBXaGl0ZVNtb2tlIGNvcm5zaWxrICovDQogICAgd2hpdGUtc3BhY2U6IHByZTsgDQogICAgZm9udC1zaXplOiAxMTAlOyAgDQogICAgbGluZS1oZWlnaHQ6IDEuMzU7fQ0KPC9zdHlsZT4NCg0KPHN0eWxlPiAgICAgDQogICNzdHlsZU15Q29kZUJsb2Nrew0KICAgIGRpc3BsYXk6IGJsb2NrOyANCiAgICBib3JkZXI6IC41cHggc29saWQgZ3JheTsgICAgICAvKiBTVFlMRSBmb3IgbW9ub3NwYWNlLCBSIGNvZGUvdGV4dCBibG9jayAqLw0KICAgIGZvbnQtZmFtaWx5OiBjb3VyaWVyOyAgICANCiAgICBjb2xvcjogYmxhY2s7IA0KICAgIGJhY2tncm91bmQ6IGNvcm5zaWxrOyAgIC8qIHdoaXRlIGl2b3J5IExpZ2h0WWVsbG93IFdoaXRlU21va2UgY29ybnNpbGsgKi8NCiAgICB3aGl0ZS1zcGFjZTogcHJlOyANCiAgICBmb250LXNpemU6IDk1JTsgIA0KICAgIGxpbmUtaGVpZ2h0OiAxLjM7fQ0KPC9zdHlsZT4NCg0KPHN0eWxlPiAgICAgDQogICNteUJMT0NLMXsNCiAgICBkaXNwbGF5OiBibG9jazsgDQogICAgYm9yZGVyOiAuNXB4IHNvbGlkIGxpZ2h0Z3JheTsgIC8qIFNUWUxFIGZvciBtb25vc3BhY2UsIFIgY29kZS90ZXh0IGJsb2NrICovDQogICAgZm9udC1mYW1pbHk6IGNvdXJpZXI7ICAgIA0KICAgIGNvbG9yOiBibHVlOyAgICAgICAgICAgICAgICAgIC8qICB0ZXh0IGNvbG9yOiBibGFjaywgbGlnaHRibHVlLCBibHVlICAqLw0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KICAgIHdoaXRlLXNwYWNlOiBwcmU7IA0KICAgIGZvbnQtc2l6ZTogMTEwJTsgIA0KICAgIGxpbmUtaGVpZ2h0OiAxLjM1O30NCjwvc3R5bGU+DQoNCjxzdHlsZT4gICAgIA0KICAjbXlCTE9DSzJ7DQogICAgZGlzcGxheTogYmxvY2s7IA0KICAgIGJvcmRlcjogLjVweCBzb2xpZCBsaWdodGdyYXk7ICAvKiBTVFlMRSBmb3IgbW9ub3NwYWNlLCBSIGNvZGUvdGV4dCBibG9jayAqLw0KICAgIGZvbnQtZmFtaWx5OiBjb3VyaWVyOyAgICANCiAgICBjb2xvcjogYmx1ZTsgICAgICAgICAgICAgICAgIC8qICB0ZXh0IGNvbG9yOiBibGFjaywgbGlnaHRibHVlLCBibHVlICAqLw0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KICAgIHdoaXRlLXNwYWNlOiBwcmU7IA0KICAgIGZvbnQtc2l6ZTogMTAwJTsgIA0KICAgIGxpbmUtaGVpZ2h0OiAxLjM1O30NCjwvc3R5bGU+DQoNCiAgDQo8YnI+ICAgDQo8cHJlIGlkPSJzdHlsZVBSRUFNQkxFIj4gDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Yj5QIFIgRSBBIE0gQiBMIEU8L2I+DQoNCiAgQmlvIDI0MCA8Yj5CaW9zdGF0aXN0aWNzPC9iPiBpcyBhIHJlcXVpcmVkIGNvdXJzZSBmb3IgQmlvbG9neSBNYWpvcnMgaW4gdGhlIEJTIA0KICBkZWdyZWUgcHJvZ3JhbSBhdCBMZWhtYW4gQ29sbGVnZSBvZiB0aGUgQ2l0eSBVbml2ZXJzaXR5IG9mIE5ldyBZb3JrLiANCiAgDQogIE5hdGlvbndpZGUsIHdlIHJlY29nbml6ZSB0aGF0IHNraWxscyBpbiB0aGUgc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIA0KICBncmFwaGljYWwgdmlzdWFsaXphdGlvbiBvZiBiaW9sb2dpY2FsIGRhdGEsIGFyZSBlc3NlbnRpYWwuIEJpb3N0YXRpc3RpY3MgDQogIGlzIHJlcXVpcmVkIGZvciBiaW9sb2d5IG1ham9ycyBhdCB0aGUgbGVhZGluZyBDb2xsZWdlcyBhbmQgVW5pdmVyc2l0aWVzIA0KICBhY3Jvc3MgdGhlIFVTQS4gDQogIA0KICBTdHVkZW50cyAtLSBpZiB5b3UndmUgbm90IGhhZCBhIHN0YXRpc3RpY3MgY291cnNlIG9yIGEgY291cnNlIGluIGNvbXB1dGVyDQogIHByb2dyYW1taW5nLCB0aGVuIGdldCBvdmVyIGl0ISANCiAgDQogIEluIEJpbyAyNDAgaWYgeW91IHNob3cgdXAsIHNob3cgdXAgb24gdGltZSwgcGF5IGF0dGVudGlvbiwgdGFrZSBub3Rlcywgd29yayANCiAgaGFyZCBhbmQgZG9uJ3QgY2hlYXQsIHRoZW4geW91J2xsIGFjcXVpcmUgZGVlcCBza2lsbHMgaW4gQmlvc3RhdGlzdGljcyBhbmQgaW4NCiAgUiBwcm9ncmFtbWluZy4gSWYgeW91IGhhdmUgaGFkIGEgY291cnNlIGluIHN0YXRpc3RpY3MgYW5kL29yIGluIHByb2dyYW1taW5nIA0KICB0aGVuIHlvdSdsbCBxdWlja2x5IGxlYXJuIFIuIE9mIGNvdXJzZSwgYWxsIHN0YXRpc3RpY2FsIGFuZCBwcm9ncmFtbWluZyANCiAgZW52aXJvbm1lbnRzIGhhdmUgYSBsZWFybmluZyBjdXJ2ZS4gDQogIA0KICBCaW8gMjQwIHByb3ZpZGVzIHRoZSBvcHBvcnR1bml0eSBmb3IgeW91IHRvIGV4aXQgdGhlIGNvdXJzZSBmdW5jdGlvbmluZyBpbiBSIA0KICBjb2RpbmcgZm9yIEJpb3N0YXRpc3RpY3MsIGF0IEJpb2xvZ3kgR3JhZHVhdGUgU2Nob29sIGxldmVsLCBhbmQgSSBoYXZlIGNhc2UgDQogIHN0dWRpZXMgdG8gcHJvdmUgaXQuDQogIA0KPC9wcmU+IA0KDQo8YnI+PGJyPiAgDQoNCg0KPCEtLSAgIC4uLi4gQ09NTUVOVFMgZm9yIEhUTUwuLi4uICAgLS0+DQoNCjwhLS0gTm90ZTogIFlBTUwgaGVhZGVyIGlzIHN1cnJvdW5kZWQgYnkgMyBoeXBoZW5zICAgLS0+DQoNCg0KPCEtLSAgIEphdmFTY3JpcHQgJiBDU1MgImNvZGUgY2h1bmsiIHRvIGNoYW5nZSBDT0xPUiBpbiBZQU1MICAtLT4gDQoNCmBgYHtqcywgZWNobz1GQUxTRX0NCg0KICAkKCcudGl0bGUnKSAgIC5jc3MoJ2NvbG9yJywgJ2RhcmtyZWQnKQ0KICAkKCcuc3VidGl0bGUnKS5jc3MoJ2NvbG9yJywgJ2RhcmtncmF5JykNCiAgJCgnLmF1dGhvcicpICAuY3NzKCdjb2xvcicsICdibGFjaycpDQogICQoJy5kYXRlJykgICAgLmNzcygnY29sb3InLCAnYmxhY2snKQ0KICAkKCcuYWJzdHJhY3QnKS5jc3MoJ2NvbG9yJywgJ2JsYWNrJykNCiAgLy8gIEphdmFTY3JpcHQgY29tbWVudC4gIEFMU08sIE5PVEUgdXNlIG9mIHJhdyBMYVRleCBpbiBZQU1MLCBmb3IgZm9udCBhbmQgc2l6ZSwNCiAgLy8gIGJ1dCBtaWdodCBiZSBlYXNpZXIgdG8gdXNlOiAgPFAgc3R5bGU9IiAgICAgIj4geW91ciB0ZXh0IGhlcmUgPC9wPg0KYGBgDQoNCg0KPCEtLSBjcmVhdGUgQ1NTIHN0eWxlIGZvciAiMiBjb2x1bW4iIG5ld3NwYXBlciBzdHlsZSB0ZXh0OyBjcmVhdGUgdGhlbiBjYWxsIC0tPg0KPHN0eWxlPiAubmV3c3BhcGVyMjJ7Y29sdW1uLWNvdW50OjI7IGNvbHVtbi1nYXA6ODBweDsgZm9udC1zaXplOjEwMCU7IA0KICAgICAgICBjb2x1bW4tcnVsZToxcHggc29saWQgbGlnaHRncmF5IH0gPC9zdHlsZT4gDQoNCjxzdHlsZT4gLm5ld3NwYXBlcjIze2NvbHVtbi1jb3VudDoyOyBjb2x1bW4tZ2FwOjUwcHg7IGZvbnQtc2l6ZToxMDAlOyANCiAgICAgICAgY29sdW1uLXJ1bGU6MXB4IHNvbGlkIGxpZ2h0Z3JheSB9IDwvc3R5bGU+IA0KDQo8c3R5bGU+IA0KI2JsYWNrbGluZXtjb2xvcjpibGFjazsgcGFkZGluZzoxcHg7IGZvbnQtc2l6ZToyMHB0OyB0ZXh0LWFsaWduOmNlbnRlcn0gPC9zdHlsZT4NCg0KKipMYXN0IHJlbmRlcmVkKio6ICZlbXNwOyBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVBICVCICVkLCAlWSBhdCAlSDolTTolUycpYCAgDQo8YnI+IA0KIA0KPHAgaWQ9ImJsYWNrbGluZSI+IF9fX19fX19fX19fX19fX19fXyA8L3A+IDxicj4gICAgICAgIDwhLS0gYmxhY2sgbGluZSAtLT4gDQoNCg0KPCEtLSAibXlIZWFkZXIxIiBjYW4gYmUgY2FsbGVkIHdoZW4gZGVzaXJlZDsgaXQncyBhIHJhdyBIVE1MICJpZCIgYXR0cmlidXRlIHBvaW50aW5nIA0KdG8gYSAic3R5bGUiIHRhZyB1c2VkIGJ5IEphdmFTY3JpcHQuIE5vdGUgdGhlIGhhc2h0YWcgZm9sbG93ZWQgYnkgeW91ciBkZXNpcmVkIG5hbWUsIA0KZm9sbG93ZWQgYnkgc3R5bGUgZGVmaW5pdGlvbiBlbmNsb3NlZCBieSB7IH0gJ3BhZGRpbmcnIGlzIGRpc3RhbmNlIHRleHQgaXMgZnJvbSB0b3AgDQomIGJvdHRvbTsgJ2NvbG9yJyBpcyB0ZXh0IGNvbG9yLiBDcmVhdGUgYXMgbWFueSBvZiB0aGVzZSBhcyBkZXNpcmVkLiAtLT4NCg0KPHN0eWxlPiAgICAgICAgICAgICAgICAgICAgICAgDQojbXlIZWFkZXIxIHsNCiAgYmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7IGNvbG9yOmJsYWNrOyBwYWRkaW5nOjEwcHg7IHRleHQtYWxpZ246IGNlbnRlcn0gDQo8L3N0eWxlPg0KDQo8c3R5bGU+ICAgICAgICAgICAgICAgICAgICAgICANCiNteUhlYWRlcjJ7YmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7IGNvbG9yOmJsYWNrOyBwYWRkaW5nOjEycHg7IHRleHQtYWxpZ246bGVmdDsgDQpsaW5lLWhlaWdodDoxNDAlfSANCjwvc3R5bGU+DQoNCjxzdHlsZT4gICAgICAgICAgICAgICAgICAgICAgIA0KI215SGVhZGVyM3tiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Ymx1ZTsgY29sb3I6cmVkOyBwYWRkaW5nOjEycHg7IHRleHQtYWxpZ246Y2VudGVyfSANCjwvc3R5bGU+DQoNCjxzdHlsZT4gICAgICAgICAgICAgICAgICAgICAgIA0KI215SGVhZGVyNHtiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Z3JheTsgY29sb3I6YmxhY2s7IHRleHQtYWxpZ246bGVmdDsgIA0KcGFkZGluZzoxNHB4IDE0cHggMTRweCAxNHB4OyBtYXJnaW46IDBweCAyNTBweCAxMHB4IDBweDt9IA0KPC9zdHlsZT4NCg0KPCEtLSAgSFRNTCBjb21tZW50cyBoZXJlICAtLT4NCg0KDQo8aDUgaWQ9Im15SGVhZGVyMSI+DQpCaW8gMjQwLiA8aT5CaW9zdGF0aXN0aWNzPC9pPiAmZW1zcDsgRmFsbCAyMDIzJmVtc3A7ICpEd2lnaHQgS2luY2FpZCosIFBoRCANCiZlbXNwOyBMZWhtYW4gQ29sbGVnZSBDVU5ZLCBCcm9ueCBOWSAxMDQ2OCBVU0ENCjwvaDU+DQoNCjxicj48YnI+IA0KDQo8IS0tIC4uLi4uLiBSIGNvZGUgY2h1bmtzIGVuY2xvc2VkIGJ5IDMgYmFjayB0aWNrcywgdG9wICYgYm90dG9tICAuLi4uLi4uLi4gLS0+DQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCiMgbG9hZCBwYWNrYWdlIGZvciB3b3JkIGNsb3VkcyBjb21wdXRlZCBieSBDKysgJiByZW5kZXJlZCB0byBIVE1MICYgSmF2YVNjcmlwdA0KbGlicmFyeShnZ3dvcmRjbG91ZCwgcXVpZXRseT1UUlVFLCB3YXJuLmNvbmZsaWN0cz1GQUxTRSkgDQpzZXQuc2VlZCgxMjM0KSAjIHJhbmRvbSBudW1iZXIgc2VlZCBmb3Igd29yZCBjbG91ZCByZXByb2R1Y2liaWxpdHksIGlmIGRlc2lyZWQNCg0Kd29yZCA8LSBjKCJSIiwgImJpb3N0YXQiLCAiQmlvIDI0MCIsICJGYWxsIDIwMjMiKSANCmZyZXEgPC0gYygxNCwgNiwgNCwgMSkgIyAnZnJlcXVlbmN5JyBvZiB0aGUgNCB3b3JkcyA9IHNpemUgb2Ygd29yZHMgaW4gY2xvdWQNCg0KZ2d3b3JkY2xvdWQod29yZCwgZnJlcSwgY29sb3JzPWMoImJsYWNrIiwgInJlZCIsICJibHVlIiwgImRhcmtncmVlbiIpLCBtaW4uZnJlcT0xLCANCiAgICAgICAgICAgIHNjYWxlPWMoMTQsIDEpLCByb3QucGVyPS41LCBvcmRlcmVkLmNvbG9ycz1UUlVFKQ0KDQpgYGANCg0KDQo8cCBzdHlsZT0iZm9udC1mYW1pbHk6ICdjb3VyaWVyIG5ldyc7IGZvbnQtc2l6ZTogMjhwdDsgZm9udC13ZWlnaHQ6IGJvbGQ7IA0KICAgICAgICAgIGNvbG9yOiBibHVlOyBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgcGFkZGluZzogMHB4OyBtYXJnaW4tcmlnaHQ6IDUwcHg7DQogICAgICAgICAgbWFyZ2luLWJvdHRvbTogMHB4OyANCiAgICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7IHRleHQtaW5kZW50OiAwcHg7IA0KICAgICAgICAgIHRleHQtc2hhZG93OiA0cHggMXB4IDFweCBsaWdodGdyYXk7Ij4NCiAgICAgICAgICBSPGJyPmRhdGE8YnI+Z3JhcGhzPGJyPnN0YXRpc3RpY3M8YnI+d3JpdGluZyBhYm91dCB0aGUgcmVzdWx0czwvcD48YnI+IA0KDQo8YnI+IA0KDQojICZuYnNwOyBDb21tdW5pY2F0aW9uICAgICAgICAgPCEtLSAgLi4uLi4gMXN0IHNlY3Rpb24gb2YgZG9jdW1lbnQgLi4uLi4gIC0tPiAgICAgICANCg0KPGJyPg0KDQoqKiplbWFpbCoqKjogJmVtc3A7IFlvdSBhbHJlYWR5IGhhdmUgbXkgQ29sbGVnZSBlbWFpbCBhZGRyZXNzLiBJbiBCaW8gMjQwIHdlIG1ha2UgDQpmcmVxdWVudCB1c2Ugb2YgZW1haWwgZm9yIGZpbGUgdHJhbnNmZXJzLCBRICYgQSwgVGVzdHMgYW5kIGdlbmVyYWwgY29tbXVuaWNhdGlvbi4NCjxicj48YnI+DQoNCioqKlpvb20qKio6ICZlbXNwOyBUd2VudHkgbWludXRlcyBiZWZvcmUgZWFjaCBjbGFzcywgSSBlbWFpbCB0aGUgWm9vbSANCm1lZXRpbmcgPHU+aW52aXRhdGlvbjwvdT4gd2l0aCBVUkwgbGluay4gPGJyPg0KWm9vbSBzZXNzaW9ucyBvY2N1cHkgdGhlIDQgaG91ciBjbGFzcyB0aW1lIGZvciB0aGUgc2VjdGlvbiBvZiBCaW8gMjQwIHRoYXQgZW5qb3lzIA0KeW91ciBmb3JtYWwgcmVnaXN0cmF0aW9uLiA8YnI+PGJyPg0KDQoqKipUd2l0dGVyKioqOiAmZW1zcDsgaHR0cHM6Ly90d2l0dGVyLmNvbS9MQ19iaW9zdGF0ICZlbXNwOyZuYnNwOyAyLDEwMCsgDQpUd2VldHMgZGVkaWNhdGVkIHRvIFIsIERhdGEsIEdyYXBocywgQmlvc3RhdGlzdGljcywgQmlvIDI0MCwgU2NpZW5jZSwgQ2FyZWVyIA0KRGV2ZWxvcG1lbnQsIGFuZCByZWxhdGVkIHRvcGljcy4gJm5ic3A7IEluIHRoZSB0cmFuc2l0aW9uIGZyb20gVHdpdHRlciB0byBYLCANCmdsaXRjaGVzIHJlbWFpbi4gPGJyPjxicj4gDQoNCioqKlJQdWJzKioqOiAmZW1zcDsgUlB1YnMgaXMgYSBmcmVlIHdlYnNpdGUgYXQgaHR0cHM6Ly9ycHVicy5jb20gYW5kIGl0J3MgaGFuZHkgZm9yIA0KcHVibGlzaGluZyAqKlIgTWFya2Rvd24qKiBkb2N1bWVudHMgZnJvbSB3aXRoaW4gdGhlIFJTdHVkaW8gSURFLiANClJQdWJzIGVuYWJsZXMgdGhlIHB1YmxpYyB0byB2aWV3IGFuZCB0byBjb21tZW50IG9uIGRvY3VtZW50cyBidXQgbm90IHRvIGRvd25sb2FkLiANCkhvd2V2ZXIsIHRoZSBgZm9vLlJtZGAgKipzb3VyY2UgY29kZSoqIG9mIGEgZG9jdW1lbnQgbWF5IGJlIGRvd25sb2FkZWQgaWYgdGhlIGF1dGhvciANCmFsbG93ZWQgZm9yIHNhbWUsIGluIHRoZSBkb2N1bWVudCdzIG1ldGEsIFlBTUwgY29kZS4gDQpHbyB0byBodHRwczovL3JwdWJzLmNvbS9CaW8yNDBfQmlvc3RhdCB0byBzZWUgbXkgZG9jdW1lbnRzIHB1Ymxpc2hlZCB0aGVyZSwgc28gZmFyLiANClZpZXcgdGhlICoqU3lsbGFidXMqKiBhdCBodHRwczovL3JwdWJzLmNvbS9CaW8yNDBfQmlvc3RhdC9TeWxsYWJ1cyAgDQoNCkF0IGh0dHBzOi8vcnB1YnMuY29tICwgc2VlIHRoZSBtb3N0IHJlY2VudGx5IHB1Ymxpc2hlZCBkb2N1bWVudHMsIHdvcmxkd2lkZS4gDQpNYW55IG9mIHRoZXNlIChIVE1MLCBQREYsIFdvcmQsIHNsaWRlcywgZXRjLikgYXJlIHN0dWRlbnQgaG9tZXdvcmsgYXNzaWdubWVudHMhIA0KRW50aXJlIGNvdXJzZXMgYXJlIHBvc3RlZCBieSBmYWN1bHR5IHdvcmxkd2lkZSwgYW5kIG11bHRpbGluZ3VhbC4gSW5kZWVkLCBJIG1heSBnbyANCnRoYXQgcm91dGUgZm9yIEJpbyAyNDAsIGFzIG15IHNraWxscyBpbXByb3ZlIGluIEhUTUw1LCBDU1MzLCBTVkcgYW5kIA0KSmF2YVNjcmlwdC4gIA0KPGJyPiANCg0KKioqQmxhY2tib2FyZCoqKjogJmVtc3A7IEJsYWNrYm9hcmQgaGFzIHZlcnkgbGltaXRlZCB1c2UgaW4gQmlvIDI0MC4gVGhlIFN5bGxhYnVzIA0KaXMgcG9zdGVkIHRoZXJlIGFuZCBJIG1heSB1c2UgaXQgdG8gc2VuZCBBbm5vdW5jZW1lbnRzLiBUaGUgMyBUZXN0IGdyYWRlcyB3aWxsIA0KYmUgcG9zdGVkIHRoZXJlIGJ1dCByZWFsaXplIHRoYXQgSSBvbmx5IHVzZSBCbGFja2JvYXJkIHRvICoqcG9zdCoqIHlvdXIgcmF3IFRlc3QgDQpncmFkZXMsIG5vdCB0byB0YWJ1bGF0ZSBhdmVyYWdlcyBvciBhbnl0aGluZyBlbHNlLiA8YnI+PGJyPiANCg0KKioqcGhvbmUqKiogOiAmZW1zcDsgY3VycmVudGx5IG5vdCBhdmFpbGFibGUsIHBsZWFzZSB1c2UgZW1haWwuDQoNCjxicj4gDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCiANCjxicj4NCg0KPHN0eWxlPiAubmV3c3BhcGVyMntjb2x1bW4tY291bnQ6MjsgY29sdW1uLWdhcDozMHB4OyBmb250LXNpemU6MTAwJTsgfSA8L3N0eWxlPiANCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjIiPg0KDQpXZSBhcmUgbm90IG1lZXRpbmcgaW4gcGVyc29uIGZvciBCaW8gMjQwLCB0aGlzIHRlcm0uIEJlY2F1c2UgSSBhbSBab29tIGNhbSBzaHksIHRoaXMgDQpwaG90byBpcyBvZiB5b3VycyB0cnVseSA5IHllYXJzIGFnbywgd2l0aCBhIHZlcnkgKmFsaXZlKiBsb2JzdGVyIG9uIHRoZSBCYXkgb2YgRnVuZHkgDQpvZmYgR3JhbmQgTWFuYW4gSXNsYW5kIGluIHRoZSBQcm92aW5jZSBvZiAqKk5ldyBCcnVuc3dpY2sqKiwgQ2FuYWRhLiANCg0KVGhpcyBsb2JzdGVyJ3Mgam9iIHdhcyB0byBpbXByZXNzIHRvdXJpc3RzLCBub3QgdG8gYmUgZWF0ZW4uIDxicj4NCkl0IHdhcyByZXR1cm5lZCB0byB0aGUgb2NlYW4gd2hlbiB3ZSBkZXBhcnRlZC4gDQoNClRoZSBCYXkgb2YgRnVuZHkgaGFzIHRoZSBoaWdoZXN0IHRpZGVzIGluIHRoZSB3b3JsZCAtLSA0NSB2ZXJ0aWNhbCBmZWV0IHdoZXJlIHBob3RvIA0Kd2FzIHRha2VuLiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXlfb2ZfRnVuZHkgDQoNCk9idmlvdXNseSBJIHJlZ3JldCBub3QgaGF2aW5nIHRoZSBjcmV3IHJlbW92ZSB0aGUgcnViYmVyIGJhbmRzIA0KYmVmb3JlIG15IHdpZmUgdG9vayB0aGUgcGhvdG8sIGJ1dCBJIG1pZ2h0IGhhdmUgbG9zdCBhIGZpbmdlciBhcyBldmVuIGl0cyBzbWFsbGVyLCANCmFiZG9taW5hbCBjaGVsYWUgd2VyZSBiaXRpbmcgZmllcmNlbHkgaW4gcmV2b2x0IGZyb20gYmVpbmcgcGx1Y2tlZCBmcm9tIHRoZSBzZWEuDQo8L2Rpdj48YnI+DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjI1JSIsIGZpZy5jYXA9IkJheSBvZiBGdW5keSwgMjAxNCIsIGZpZy5hbGlnbj0iY2VudGVyIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0NCiAgICAgICAgICAgICAgICAgICJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL0tpbmNhaWQgQmF5IG9mIEZ1bmR5LkpQRyIpDQpgYGANCg0KPGJyPiAgIA0KDQoqKlF1ZXN0aW9uKio6ICZuYnNwOyBJcyBCaW8gMjQwIGEgY291cnNlIGluICoqc3RhdGlzdGljcyoqIG9yIGluICoqY29tcHV0ZXIgDQpwcm9ncmFtbWluZyoqPyAgDQoqKkFuc3dlcioqOiAmZW1zcDsgSXQncyBib3RoLCBiZWNhdXNlIGluY3JlYXNpbmdseSwgdGhlIHNjaWVudGlzdCwgdGVhY2hlciwgDQpwaHlzaWNpYW4sIGludmVzdGlnYXRvciAtLS0gbXVzdCBiZSBhYmxlIHRvIGRvIGJvdGguICANCg0KPGJyPiAgDQoNCjwhLS0gLi4uLi4uICAqKiogIGRyYXdzIGEgdmVyeSB0aGluIGxpbmUsIGxlZnQgdG8gcmlnaHQgIC4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KIA0KIA0KPCEtLSAgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4uLi4uLi4uIDJuZCBTZWN0aW9uIG9mIGRvY3VtZW50IC4uLi4uLi4uLi4uLiAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gIC0tPg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQojICZuYnNwOyBDb2xsZWdlIHJ1bGVzICAgDQogICAgICAgICAgICAgICAgICAgICAgICANCjxicj4gDQpUaGUgKipVbmRlcmdyYWR1YXRlIEJ1bGxldGluKiogaXMgeW91ciBjb250cmFjdCB3aXRoIHRoZSBDb2xsZWdlKio6KiogIA0KaHR0cDovL2xlaG1hbi5zbWFydGNhdGFsb2dpcS5jb20vMjAxOS0yMDIxL1VuZGVyZ3JhZHVhdGUtQnVsbGV0aW4gOyBpdCBoYXMgdGhlIHJ1bGVzIA0Kb24gZGVncmVlcywgbWFqb3JzLCBtaW5vcnMsIGFuZCBtb3JlLiA8YnI+PGJyPiANCkNvbGxlZ2UgcG9saWN5IG9uICoqQWNhZGVtaWMgSW50ZWdyaXR5OioqICAgDQpodHRwOi8vbGVobWFuLnNtYXJ0Y2F0YWxvZ2lxLmNvbS9lbi8yMDE5LTIwMjEvVW5kZXJncmFkdWF0ZS1CdWxsZXRpbi9BY2FkZW1pYy1TZXJ2aWNlcy1hbmQtUG9saWNpZXMvQWNhZGVtaWMtSW50ZWdyaXR5DQoNClZpZXc6ICZuYnNwOyAgaHR0cDovL2xlaG1hbi5zbWFydGNhdGFsb2dpcS5jb20vMjAxOS0yMDIxL1VuZGVyZ3JhZHVhdGUtQnVsbGV0aW4vQWNhZGVtaWMtU2VydmljZXMtYW5kLVBvbGljaWVzL1VuZGVyZ3JhZHVhdGUtR3JhZGluZy1TeXN0ZW1zLWFuZC1SZWxhdGVkLVBvbGljaWVzL0dyYWRlLUFwcGVhbHMNCmZvciAqKkdyYWRlIEFwcGVhbHMqKi4gDQo8YnI+PGJyPiANCg0KDQpgYGB7PWh0bWx9DQoNCjxzdHlsZT4NCiAgLmRyb3Bkb3duIHtwb3NpdGlvbjogcmVsYXRpdmU7IGRpc3BsYXk6IGlubGluZS1ibG9jazt9DQogIA0KICAuZHJvcGRvd24tY29udGVudHtkaXNwbGF5OiBub25lOyBwb3NpdGlvbjogYWJzb2x1dGU7IGJhY2tncm91bmQtY29sb3I6IGNvcm5zaWxrOw0KICAgIGZvbnQtc2l6ZTogOTUlOyBmb250LWZhbWlseTogR2FyYW1vbmQsIEdlb3JnaWEsIFRpbWVzOw0KICAgIHBhZGRpbmc6IDEwcHggMjBweCAxMHB4IDIwcHg7IGJveC1zaGFkb3c6IDVweCA1cHggNXB4IGxpZ2h0Z3JheTsNCiAgICB3aWR0aDogNjUwcHg7IGxpbmUtaGVpZ2h0OiAxOyB3b3JkLXNwYWNpbmc6IDEwMCU7IGxldHRlci1zcGFjaW5nOiAxMDAlOw0KICAgIHotaW5kZXg6IDE7ICAgDQogICAgfQ0KICAgIA0KICAuZHJvcGRvd246aG92ZXIgIC5kcm9wZG93bi1jb250ZW50e2Rpc3BsYXk6IGJsb2NrfQ0KPC9zdHlsZT4NCg0KDQo8Ym9keT4NCjxkaXYgY2xhc3M9ImRyb3Bkb3duIj4NCiAgPHNwYW4+IEhvdmVyLW92ZXIgJm5ic3A7IDxiPiAmbmJzcDsgSEVSRSAmbmJzcDsgPC9iPiAmbmJzcDsgZm9yIGRldGFpbHMgb246ICZuYnNwOyANCiAgICA8Yj5HcmFkZSBBcHBlYWxzPC9iPjwvc3Bhbj4NCiAgICANCjxkaXYgY2xhc3M9ImRyb3Bkb3duLWNvbnRlbnQiPg0KDQogICAgPHA+PGI+R2VuZXJhbCBHcmFkZSBBcHBlYWxzPC9iPjwvcD4gIA0KICAgIDxwPlN0dWRlbnRzIG5vdCBzYXRpc2ZpZWQgd2l0aCBhIGdyYWRlIHJlY2VpdmVkIGluIGEgY291cnNlIHNob3VsZCBmaXJzdCBjb25zdWx0IA0KICAgIHRoZSBpbnN0cnVjdG9yIGludm9sdmVkLiBJdCBpcyB0aGUgaW5zdHJ1Y3RvcidzIHNvbGUganVkZ2VtZW50IHRoYXQgZGV0ZXJtaW5lcyB0aGUgDQogICAgZ3JhZGUgcmVjb3JkZWQgaW4gdGhlIE9mZmljZSBvZiB0aGUgUmVnaXN0cmFyLiBUaGUgaW5zdHJ1Y3RvcidzIGZpcnN0IGp1ZGdlbWVudCBpcyANCiAgICBhbHdheXMgdGFrZW4uIFNlY29uZCBhbmQgbGF0ZXIganVkZ2VtZW50cyByZXN1bHRpbmcgZnJvbSBwZXJzb25hbCBhcHBlYWxzIGFuZCANCiAgICBoYXJkc2hpcCBjbGFpbXMgYXJlIHJhcmVseSBob25vcmVkLiBPY2Nhc2lvbmFsIGVycm9ycyBkbyBvY2N1ciwgYW5kIHRoZXNlIGFyZSANCiAgICBhbHdheXMgY29ycmVjdGVkIHByb21wdGx5IHdoZW4gcHJvcGVybHkgY2VydGlmaWVkIGJ5IHRoZSBpbnN0cnVjdG9yIHRvIHRoZSBPZmZpY2UgDQogICAgb2YgQWNhZGVtaWMgU3RhbmRhcmRzLjwvcD4NCiAgDQogICAgPGI+IERlcGFydG1lbnRhbCBvZiBCaW9sb2dpY2FsIFNjaWVuY2VzOiAmbmJzcDsgR3JhZGUgQXBwZWFscyA8L2I+IA0KICAgIA0KICAgIDxwPldoZW4gYSBzdHVkZW50IGNvbnNpZGVycyBhIGdyYWRlIHVuanVzdCwgdGhlIHN0dWRlbnQgc2hvdWxkIGZpcnN0IGNvbmZlciB3aXRoIA0KICAgIHRoZSBpbnN0cnVjdG9yLiBTdHVkZW50cyBhcmUgcmVxdWlyZWQgdG8gaW5pdGlhdGUgZ3JhZGUgYXBwcGVhbHMgYmVmb3JlIHRoZSBlbmQgb2YgDQogICAgdGhlIGVpZ2h0IHdlZWsgb2YgYSBzZW1lc3RlciBmb2xsb3dpbmcgdGhlIGVudHJ5IG9mIGEgcGVybWFuZW50IGdyYWRlLiBJZiBhIHN0dWRlbnQgDQogICAgaXMgbm90IHNhdGlzZmllZCB3aXRoIHRoZSBvdXRjb21lLCB0aGUgc3R1ZGVudCBtYXkgYXBwZWFsIGluIHdyaXRpbmcgdG8gdGhlIA0KICAgIGRlcGFydG1lbnQgQ2hhaXIuPC9wPg0KICAgIDxwPiA8Yj4xLjwvYj4gVGhlIENoYWlyIHdpbGwgYXBwb2ludCBhIHJldmlldyBjb21taXR0ZWUgb2YgYXQgbGVhc3QgdHdvIGRlcGFydG1lbnQgbWVtYmVycyANCiAgICB3aG8sIHdpdGggdGhlIENoYWlyLCB3aWxsIHJldmlldyB0aGUgYXBwZWFsLiBUaGUgY29tbWl0dGVlIHdpbGwgZXhhbWluZSBhbGwgDQogICAgbWF0ZXJpYWxzIHJlbGV2YW50IHRvIHRoZSBhcHBlYWwsIHN1Ym1pdHRlZCBieSBib3RoIHRoZSBpbnN0cnVjdG9yIGFuZCB0aGUgc3R1ZGVudCwgDQogICAgYW5kIHdpbGwgcHJlcGFyZSBhIHdyaXR0ZW4gcmVwb3J0IG9mIGl0cyBmaW5kaW5ncywgZWl0aGVyIHN1c3RhaW5pbmcgdGhlIG9yaWdpbmFsIA0KICAgIGdyYWRlIG9yIHJlY29tbWVuZGluZyBhIGNoYW5nZS48L3A+DQogICAgPHA+IDxiPjIuPC9iPiBUaGUgQ2hhaXIgd2lsbCBub3RpZnkgdGhlIHN0dWRlbnQsIHRoZSBpbnN0cnVjdG9yLCBhbmQgdGhlIE9mZmljZSBvZiANCiAgICBBY2FkZW1pYyBTdGFuZGFyZHMgb2YgdGhlIGNvbW1pdHRlZSdzIGRlY2lzaW9uLiBJZiB0aGUgY29tbWl0dGVlIHJlY29tbWVuZHMgYSANCiAgICBncmFkZSBjaGFuZ2UsIHRoZSBDaGFpciB3aWxsIGluaXRpYXRlIGEgR3JhZGUgY29ycmVjdGlvbi48L3A+DQogICAgPHA+IDxiPjMuPC9iPiBUaGUgZGVjaXNpb24gb2YgdGhlIHJldmlldyBjb21taXR0ZWUgd2lsbCBiZSBiaW5kaW5nIG9uIGJvdGggcGFydGllcy48L3A+DQoNCjwvZGl2Pg0KPC9kaXY+DQoNCjxicj48YnI+DQoNCjxkaXYgY2xhc3M9ImRyb3Bkb3duIj4NCiAgPHNwYW4+IEhvdmVyLW92ZXIgJm5ic3A7IDxiPiAmbmJzcDsgSEVSRSAmbmJzcDsgPC9iPiAmbmJzcDsgZm9yIGRldGFpbHMgb246ICZuYnNwOyANCiAgICA8Yj5SZXF1ZXN0IGZvciBFeGVtcHRpb25zPC9iPiAoR2VuZXJhbCwgUmVsaWdpb3VzLCBIZWFsdGgsIFNwZWNpYWwgTmVlZHMpIDwvc3Bhbj4NCiAgICANCjxkaXYgY2xhc3M9ImRyb3Bkb3duLWNvbnRlbnQiPg0KDQo8cD5TdW1tZXIgMjAyMyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBEZXBhcnQuIG9mIEJpb2xvZ2ljYWwgU2NpZW5jZXMsIExlaG1hbiBDb2xsZWdlIENVTlk8L3A+DQoNCiAgPGI+R2VuZXJhbCBFeGVtcHRpb25zPC9iPjxicj4NCiAgPHA+QWxsIHN0dWRlbnRzIGFyZSByZXF1aXJlZCB0byByZXZpZXcgdGhlIGNvdXJzZSBzY2hlZHVsZSBhbmQgcmVjb3JkIGltcG9ydGFudCBkYXRlcyANCiAgZm9yIGV4YW1zLCBxdWl6emVzLCBhbmQgbGFicyBvbiB0aGUgU3lsbGFidXMuIEZvciBkZWF0aCBpbiB0aGUgZmFtaWx5IG9yIGVtZXJnZW5jeSANCiAgdHJhdmVscywgYWNjb21vZGF0aW9ucyB0aGF0IGFyZSBmZWFzaWJsZSB3aWxsIGJlIHByb3ZpZGVkIE9OTFkgd2l0aCBhIGRhdGVkIHdyaXR0ZW4gDQogIG5vdGlmaWNhdGlvbiBvZiB0aGUgZXZlbnQuDQogIDwvcD4NCiAgDQogIDxiPlJlbGlnaW91cyBFeGVtcHRpb25zPC9iPjxicj4NCiAgPHA+QWNjb21vZGF0aW9ucyBtdXN0IGJlIHJlcXVlc3RlZCBmcm9tIHRoZSA8aT5EaXZpc2lvbiBvZiBTdHVkZW50IEFmZmFpcnM8L2k+IChTaHVzdGVyIEhhbGwsIA0KICBSb29tIDIwNCkgb3IgY291cnNlIGluc3RydWN0b3IuIFRvIHByb3ZpZGUgYSB0aW1lbHkgcmVzb2x1dGlvbiwgaXQgaXMgc3Ryb25nbHkgDQogIHJlY29tbWVuZGVkIHRoYXQgcmVxdWVzdHMgYXJlIHN1Ym1pdHRlZCB3aXRoaW4gdGhlIGZpcnN0IHdlZWsgb2YgdGhlIHNlbWVzdGVyLg0KICA8L3A+DQoNCiAgPGI+TG9uZy10ZXJtIEhlYWx0aC1SZWxhdGVkIEV4ZW1wdGlvbnM8L2I+PGJyPg0KICA8cD5JZiB5b3UgZW5jb3VudGVyIGEgaGVhbHRoLXJlbGF0ZWQgaXNzdWUgZHVyaW5nIHRoZSBzZW1lc3RlciB0aGF0IG1heSBjYXVzZSB5b3UgdG8gbWlzcyANCiAgbW9yZSB0aGFuIHR3byBjbGFzc2VzIGluIGEgcm93LCBjb250YWN0IHlvdXIgZ2VuZXJhbCwgPGk+QWNhZGVtaWMgQWR2aXNvcjwvaT4gdG8gZGlzY3VzcyB5b3VyIA0KICBvcHRpb25zIGZvciB3aXRoZHJhd2luZyBmcm9tIHRoZSBjb3Vyc2Ugb3IgcmVtYWluaW5nIGluIHRoZSBjb3Vyc2UsIGFuZCBiZSBwcmVwYXJlZCANCiAgdG8gcHJvdmlkZSBvZmZpY2lhbCBtZWRpY2FsIGRvY3VtZW50YXRpb24uDQogIDwvcD4NCg0KICA8Yj5TcGVjaWFsLU5lZWRzIEV4ZW1wdGlvbnM8L2I+PGJyPg0KICA8cD5BY2NvbW9kYXRpb24gbXVzdCBiZSByZXF1ZXN0ZWQgdGhyb3VnaCB0aGUgPGk+T2ZmaWNlIG9mIFN0dWRlbnQgRGlzYWJpbGl0eSBTZXJ2aWNlczwvaT4gDQogIChTaHVzdGVyIEhhbGwsIFJvb20gMjM4KSBhbmQgYXBwcm92ZWQgYnkgdGhlIGluc3RydWN0b3Igd2l0aGluIHRoZSBmaXJzdCB0d28gDQogIHdlZWtzIG9mIHRoZSBzZW1lc3Rlci4NCiAgPC9wPiANCg0KICA8cD4gPGI+Tm90ZSAxOiAmbmJzcDs8L2I+IA0KICA8aT5UaGUgU3R1ZGVudCBIZWFsdGggQ2VudGVyPC9pPiBhdCBMZWhtYW4gQ29sbGVnZSBwcm92aWRlcyBoZWFsdGgtY2FyZSBzZXJ2aWNlcyB0byANCiAgYWxsIExlaG1hbiBzdHVkZW50cyBmcmVlIG9mIGNoYXJnZSBvciBmb3IgYSBzbWFsbCBmZWUuIDxpPlRoZSBDb3Vuc2VsaW5nIENlbnRlcjwvaT4gYXQgDQogIExlaG1hbiBpcyBhdmFpbGFibGUgdG8gYXNzaXN0IHN0dWRlbnRzIHdpdGggZW1vdGlvbmFsLCBkZXZlbG9wbWVudGFsLCBhbmQgcHN5Y2hvbG9naWNhbCANCiAgY29uY2VybnMuIEluIE5ldyBZb3JrIENpdHksIHNvbWUgaGVhbHRoLWNhcmUgc2VydmljZXMgYXJlIGFsc28gYXZhaWxhYmxlIHRvIGFsbCByZXNpZGVudHMgDQogIChnbyB0byBzaXRlIGZvcjogTllDIENBUkUpLg0KICA8L3A+IA0KDQogIDxwPiA8Yj5Ob3RlIDI6ICZuYnNwOzwvYj4NCiAgU3R1ZGVudHMgYXJlIHJlc3BvbnNpYmxlIGZvciBjaGVja2luZyB0aGVpciBMZWhtYW4gZW1haWwgd2hlcmUgaW1wb3J0YW50IGluZm9ybWF0aW9uIA0KICBpcyBzZW50IGJ5IHRoZSBpbnN0cnVjdG9yIGFuZCBDb2xsZWdlLiBXZSB3aWxsIG5vdCBiZSBhYmxlIHRvIGFjY29tb2RhdGUgeW91IGlmIHlvdSANCiAgbWlzc2VkIGFuIGVtYWlsIGZyb20gdGhlIENvbGxlZ2Ugd2l0aCBpbmZvcm1hdGlvbiB0aGF0IGFmZmVjdHMgeW91ciBjbGFzcyBhdHRlbmRhbmNlIA0KICBvciBwZXJmb3JtYW5jZS4gSWYgeW91IGhhdmUgZGlmZmljdWx0eSBhY2Nlc3NpbmcgeW91ciBMZWhtYW4gZW1haWwgYWNjb3VudCwgZm9sbG93IA0KICBpbnN0cnVjdGlvbnMgb25saW5lLiBGb3IgaGVscCwgY29udGFjdCA8Yj5JVCBTZXJ2aWNlcyBmb3IgU3R1ZGVudHM8L2I+IGFzIHNvb24gYXMgDQogIHBvc3NpYmxlIG9yIGVtYWlsIHRoZW0gYXQgPGI+aGVscC5kZXNrQGxlaG1hbi5jdW55LmVkdTwvYj4NCiAgPC9wPiANCiAgDQogIDwvZGl2Pg0KICA8L2Rpdj4NCg0KPC9ib2R5Pg0KDQpgYGANCiANCg0KPGJyPjxicj4gDQoNCmBgYHs9aHRtbH0NCg0KIDxpbWcgc3JjPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL0xlaG1hbkxvZ28ucG5nIiwgYWx0PSIiLCANCiAgICAgICAgICB3aWR0aD0iNTAwIiwgc3R5bGU9ImZsb2F0OmxlZnQiPg0KIDxpbWcgc3JjPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9MZWhtYW4gdmlldzEucG5nIiwgYWx0PSIiLCANCiAgICAgICAgICB3aWR0aD0iMzAwIiwgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAmZW1zcDsgdGhlIEJST05YDQogPGJyPiA8YnI+IDxicj4NCiANCmBgYA0KDQoNCg0KPGgxPiAmbmJzcDsgPGJyPjxicj48YnI+IDwvaDE+ICAgDQogDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCiAgICAgICAgICAgICAgICAgICAgDQoNCiMgJm5ic3A7IENvbXB1dGVycyAgICAgICAgICAgPCEtLSAuLi4uLi4uLi4uIDNyZCBzZWN0aW9uIG9mIGRvY3VtZW50IC4uLi4uLi4gLS0+ICANCg0KPGJyPiANCjxzdHlsZT4gLm5ld3NwYXBlcjN7Y29sdW1uLWNvdW50OjM7IGNvbHVtbi1nYXA6MzBweDsgZm9udC1zaXplOjEwMCU7IH0gPC9zdHlsZT4gDQoNCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjMiPg0KQSBjb21wdXRlciAoV2luIG9yIE1hYywgYnV0IG5vdCBDaHJvbWUgT1MgYmVjYXVzZSBpdCB3aWxsIG5vdCBydW4gUikgaXMgKipSRVFVSVJFRCoqIA0KZm9yIHRoaXMgc3luY2hyb25vdXMsICoqb25saW5lIHNlY3Rpb24qKiBvZiBCaW8gMjQwLiANCg0KSWYgd2Ugd2VyZSBtZWV0aW5nIGluIERhdmlzIDIyNSwgdGhlcmUgYXJlIFdpbmRvd3MgZGVza3RvcCB0ZXJtaW5hbHMgYXZhaWxhYmxlIA0KYnV0IG1vc3Qgc3RpbGwgcHJlZmVyIHRoZWlyIGxlc3MgcmVzdHJpY3RpdmUsIHBlcnNvbmFsIGxhcHRvcCBjb21wdXRlciwgd2hpY2ggYWxzbyANCmFsbG93cyB5b3UgdG8gdGFrZSBSIGFuZCBhbGwgdGhlIHNvZnR3YXJlIGFuZCBkYXRhIHdpdGggeW91LCBhZnRlciB0aGUgc2VtZXN0ZXIgaXMgDQpvdmVyLiBJbiBEYXZpcyAyMjUgeW91IHdvdWxkIG5lZWQgeW91ciBMZWhtYW4gZW1haWwgYWNjb3VudCBmb3Igd2lyZWxlc3MgYWNjZXNzLCANCm5lZWRlZCBmb3IgZG93bmxvYWRpbmcgUiBhbmQgZm9yIGRvd25sb2FkaW5nIFIgcGFja2FnZXMgYWNyb3NzIHRoZSBzZW1lc3Rlci4gDQoNCldlIHdpbGwgZG93bmxvYWQgdG8gZWFjaCBtYWNoaW5lIHRoZSBmcmVlIGFuZCBvcGVuLXNvdXJjZSwgUiBsYW5ndWFnZSBhbmQgc3lzdGVtIA0KZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGFuZCBncmFwaGljcyAoaHR0cHM6Ly93d3cuci1wcm9qZWN0Lm9yZykuIEkgd2lsbCBkZW1vbnN0cmF0ZS4gDQoNClIgd2FzIGNyZWF0ZWQgYnkgc3RhdGlzdGljaWFucyBmb3Igc3RhdGlzdGljaWFuczsgdGhlcmVmb3JlLCBSIGlzICoqKnN0YXRpc3RpY2FsbHkgDQpjb3JyZWN0KioqIGFuZCBjYW4gYmUgdHJ1c3RlZCB0byBiZSBzby4gSG93ZXZlciwgUiBpcyBub3cgdXNlZCBieSBhbmQgY29udHJpYnV0ZWQgDQp0bywgYnkgYSBtdWNoIHdpZGVyIHJhbmdlIG9mIGZvbGtzLCBzcGFubmluZyBhbGwgc2Nob2xhcmx5IGRpc2NpcGxpbmVzIGluY2x1ZGluZyANCmV2ZW4gbGl0ZXJhdHVyZSwgYXVkaW8sIGFydCwgdmlkZW8gYW5kIFdhbGwgU3RyZWV0Lg0KDQpSIGlzIGJlY29taW5nIHRoZSBzdGF0aXN0aWNhbCBhbmQgZ3JhcGhpY2FsLCBjb21wdXRlciBsYW5ndWFnZSBvZiBjaG9pY2UgZm9yIA0Kc2NpZW50aXN0cyB3b3JsZHdpZGUsIHdpdGggUHl0aG9uLCBKYXZhU2NyaXB0IGFuZCBKdWxpYSAoTUlUKSBhcyB3b3J0aHksIGZyZWUgYW5kIA0Kb3BlbiBzb3VyY2UgY29tcGV0aXRvcnMuICANCg0KVGhlcmUgYXJlIFIgcGFja2FnZXMgZW5hYmxpbmcgeW91ciBjb2RlIGluIG5hdGl2ZSBDLCBDKyssIFB5dGhvbiwgSnVsaWEgb3Igb3RoZXIgDQpsYW5ndWFnZXMsIHRvIHJ1biB3aXRoaW4gUi4gQW4gUiAicGFja2FnZSIgbWF5IGNvbnRhaW4gYW55IG51bWJlciBvZiBuZXcgDQpmdW5jdGlvbnMsIGRhdGEgc2V0cywgZGVtb3MsIGRvY3VtZW50YXRpb24sIGxpbmtzIGFuZCBvdGhlciByZXNvdXJjZXMuIA0KDQpCZWNhdXNlIFIgd2FzIGNyZWF0ZWQgZm9yIGRhdGEsIGdyYXBocyBhbmQgc3RhdGlzdGljYWwgY29tcHV0aW5nOyBpdCBpcyBub3QgYSANCmdlbmVyYWwgcHVycG9zZSBwcm9ncmFtbWluZyBsYW5ndWFnZS4gSW5kZWVkLCBzb21lIHVzZSBSIGp1c3QgZm9yIG1ha2luZyBncmFwaHMgYW5kIA0KdGhpcyBpcyBhIGdvb2QgcGxhY2UgdG8gc3RhcnQgbGVhcm5pbmcgUiwgYXMgd2Ugc2hhbGwgZG8gc28gaW4gQmlvIDI0MC4NCg0KRXhwbG9yZSB0aGUgUiB3ZWJzaXRlLCBodHRwczovL3d3dy5yLXByb2plY3Qub3JnIHRvIGxlYXJuIGFib3V0IHRoZSBpbW1lbnNlLCBSIA0KZW52aXJvbm1lbnQuIENoZWNrIG91dCB0aGUgKipUYXNrIFZpZXdzKiosICoqVGhlIFIgSm91cm5hbCoqIA0KKGh0dHBzOi8vam91cm5hbC5yLXByb2plY3Qub3JnLyBwZWVyIHJldmlld2VkLCBvcGVuIA0KYWNjZXNzKSwgZnJlZSBSIE1hbnVhbHMsIEZBUXMsIEhlbHAvU2VhcmNoIGVuZ2luZXMsIGFubnVhbCBDb25mZXJlbmNlcywgcmVsYXRlZCANCnByb2plY3RzIChSIEJsb2csIFItRm9yZ2UpIGFuZCBhZmZpbGlhdGVkIG9yZ2FuaXphdGlvbnMgDQpzdWNoIGFzICoqQmlvY29uZHVjdG9yKiogaHR0cHM6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy8gZm9yIGJpb2luZm9ybWF0aWNzLiANCg0KTm90aWNlIHRoZSByaWNoLCBnbG9iYWwgYW5kIG11bHRpbGluZ3VhbCBuYXR1cmUgb2YgdGhlIFIgZW52aXJvbm1lbnQuICANCg0KWW91IG1heSBmb2xsb3cgUiBvbiBUd2l0dGVyLCBodHRwczovL3R3aXR0ZXIuY29tL19yX2ZvdW5kYXRpb24gIA0KDQpEdXJpbmcgY2xhc3MgSSB3aWxsIGRlbW9uc3RyYXRlIG9uIGEgV2luZG93cyBPUyBsYXB0b3AsIHRoZSBpbnN0YWxsYXRpb24gb2YgUiBhbmQgDQp0aGUgaW5zdGFsbGF0aW9uIG9mIGNvbnRyaWJ1dGVkIHBhY2thZ2VzIGZyb20gYW1vbmcgdGhlIDE5LDAwMCsgcGFja2FnZXMgDQp0aGF0IGFyZSB2ZXR0ZWQgYW5kIGF2YWlsYWJsZSBpbiB0aGUgbGF0ZXN0IHJlbGVhc2UsIGByIFIuVmVyc2lvbigpJHZlcnNpb24uc3RyaW5nYC4gDQo8L2Rpdj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KPCEtLSBFTkQgMyBjb2x1bW4gbmV3c3BhcGVyIHN0eWxlIC0tPg0KDQo8YnI+DQo8c3BhbiBzdHlsZT0gImNvbG9yOiBkYXJrcmVkOyBmb250LWZhbWlseTogVmVyZGFuYSwgQXJpYWw7IGZvbnQtc2l6ZTogMTEwJTsgDQogICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDEzMCU7ICAiPg0KPHA+DQpBIChyZWFsKSBjb21wdXRlciBpcyByZXF1aXJlZCAtLSBXaW4gb3IgTWFjLCBidXQgbm90IENocm9tZSBPUyBiZWNhdXNlIGl0IGNhbid0IHJ1biBSLiANCjxicj5UaGUgQ29sbGVnZSBoYXMgYSBsYXB0b3AgbG9hbmVyIHByb2dyYW0uIFRvIGFwcGx5LCB2aXNpdDogICBodHRwczovL2xlaG1hbi5lZHUvY29yb25hdmlydXMvc3R1ZGVudC5waHAgPGJyPiANCmFuZCBjbGljazogPGk+U3R1ZGVudCBEZXZpY2UgTG9hbiBBcHBsaWNhdGlvbjwvaT4uDQo8L3A+PC9zcGFuPg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSIxNSUiLCBmaWcuY2FwPSJSIGxvZ28iLCBmaWcuYWxpZ249InJpZ2h0In0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9SLmpwZyIpDQpgYGANCg0KIA0KDQoNCiMgJm5ic3A7IEFjdGl2ZSBsZWFybmluZyAgICAgICAgPCEtLSAgLi4uLi4uLiA0dGggc2VjdGlvbiBvZiBkb2N1bWVudCAuLi4uLi4gLS0+DQoNCjxicj4gDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIzIj4NCkZvciBTcHJpbmcgMjAyMyBteSBzZWN0aW9ucyBvZiBCaW8gMjQwIHJlbWFpbiwgMTAwJSBvbmxpbmUgc3luY2hyb25vdXMgYW5kIGhvc3RlZCANCmJ5ICpab29tKiBtZWV0aW5ncyBkdXJpbmcgdGhlIHJlZ3VsYXJseSBzY2hlZHVsZWQgY2xhc3MgcGVyaW9kIHRoYXQgZW5qb3lzIHlvdXIgDQpmb3JtYWwgcmVnaXN0cmF0aW9uLiANCg0KVHdlbnR5IG1pbnV0ZXMgYmVmb3JlIGVhY2ggY2xhc3MsIEkgZW1haWwgdGhlIFpvb20gVVJMIGxpbmsuIA0KDQpCaW8gMjQwIG1ha2VzIGxpbWl0ZWQgdXNlIG9mIEJsYWNrYm9hcmQgKFN5bGxhYnVzLCBwb3N0aW5nIG9mIFRlc3QgZ3JhZGVzKS4gSSB3aWxsIA0KYWxzbyBlbWFpbCBmaWxlcyB0byB5b3UsIHJlZ3VsYXJseS4gDQoNCkRpc3RhbmNlIGxlYXJuaW5nIG1hdGVyaWFsIGluY2x1ZGVzIG15IGxlY3R1cmVzIGFuZCBkZW1vbnN0cmF0aW9ucywgcG9sbHMsIGhhbmRvdXRzLCBkYXRhIA0KZmlsZXMsIGdyYXBocywgUiBFZGl0b3IgZmlsZXMsIFBERiBmaWxlcyBvZiByZWFkaW5ncywgVVJMIGxpbmtzLCB2aWRlb3MsIHBvcCBxdWl6emVzIGFuZCANCnByYWN0aWNlIFRlc3RzLiANCg0KV2UgbWVldCBvbmxpbmUgaW4gWm9vbSBkdXJpbmcgdGhlIHJlZ3VsYXJseSBzY2hlZHVsZWQgY2xhc3MgdGltZXMgZm9yIEJpbyAyNDAgDQooRnJpZGF5IDJwbSAtIDU6NTBwbTsgU2F0dXJkYXkgMTBhbSAtIDE6NTBwbSkuIA0KDQoqKkkgYmVnaW4gZWFjaCBjbGFzcyBleGFjdGx5IG9uIHRpbWUuKiogDQoNClRvcCBzdHVkZW50cyBzaG93IHVwLCBzaG93IHVwIG9uIHRpbWUsIHBheSBhdHRlbnRpb24sIHRha2Ugbm90ZXMsIHdvcmsgaGFyZCBhbmQgZG9uJ3QgDQpjaGVhdCAtLSB0aHVzIG1vdmluZyB0aGVpciBjYXJlZXIgZGV2ZWxvcG1lbnQgZm9yd2FyZC4gDQo8L2Rpdj4gPGJyPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEVORCAgMyBjb2x1bW4gbmV3c3BhcGVyIHN0eWxlIC0tPg0KDQo+IEluIGNsYXNzLCB5b3Ugd2lsbCBwYXJ0aWNpcGF0ZSBpbiA8YnI+IA0KJmVtc3A7ICZlbXNwOyAmZW1zcDsgPGZvbnQgc2l6ZT0iNiI+ICphY3RpdmUgbGVhcm5pbmcqIDwvZm9udD4gICAmbmJzcDsgDQpieSAmbmJzcDsgPGZvbnQgc2l6ZT0iNyI+ICpjb2xsYWJvcmF0aXZlIGNvZGluZyogPC9mb250PiAmbmJzcDtpbiAmbmJzcDsgUiA8L2JyPiAgDQoNCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjMiPg0KVGhlIGtleSB0byBsZWFybmluZyBpcyB0byBwcmFjdGljZSBvdmVyLWFuZC1vdmVyIG9uIHRoZSBjb21wdXRlciwgZGVhbGluZyB3aXRoIGRhdGEsIA0KZ3JhcGhzIGFuZCBzdGF0aXN0aWNhbCBtZXRob2RzIGluIFIsIGNvbWJpbmVkIHdpdGggd2lsbGluZ25lc3MgdG8gZW5nYWdlIFIgYnkgDQp0cmlhbC1hbmQtZXJyb3IgYW5kIGluIHJlYWwgdGltZSwgdHlwaW5nIGNvZGUgYXQgeW91ciBjb21wdXRlciBhbG9uZyB3aXRoIG1lIGR1cmluZyANCmNsYXNzLCBhcyB3ZSB3cml0ZSBhbmQgZGVidWcgY29kZSB0b2dldGhlci4gDQoNCkEgY29tcHV0ZXIgcHJvZ3JhbSBpcyBtZXJlbHkgYSB0ZXh0IGRvY3VtZW50IHRoYXQgb25lIGhhcyB0eXBlZCEgQWxsIGNvbXB1dGVyIHByb2dyYW1zIA0Kd2hldGhlciBzbWFsbCBvciBsYXJnZSwgcmVzaWRlIGluIGEgY29uc3RhbnQgc3RhdGUgb2YgcmV2aXNpb24uIA0KDQpZb3UgbXVzdCBncmFwcGxlIHdpdGggdGhlIHN1YmplY3QgbWF0dGVyIGFuZCB3b3JrIGhhcmQgZHVyaW5nIGNsYXNzIA0KYW5kIG91dHNpZGUgb2YgY2xhc3MuDQoNClRoZXJlIGFyZSAqKm5vIHRlcm0gcGFwZXJzKiogYW5kICoqbm8gY2xhc3MgcHJlc2VudGF0aW9ucyoqIGJ1dCB5b3UgbXVzdCBzcGVuZCANCmNvbnNpZGVyYWJsZSB0aW1lIHdvcmtpbmcgb3V0c2lkZSBvZiBjbGFzcyBwcmFjdGljaW5nIGRhdGEgYW5hbHlzaXMgYW5kIGdyYXBoaWNzIA0KYnkgY2FsbGluZyBmdW5jdGlvbnMgaW4gUiBhbmQgY29uc3RydWN0aW5nIFIgRWRpdG9yIGZpbGVzIChwcm9ncmFtcykgZm9yIHRoZSANCnByYWN0aWNlIHByb2JsZW1zLiBPdGhlcndpc2UsIHlvdSB3aWxsIGRvIHBvb3JseS4gDQoNCllvdXIgKipleHRlbmRlZCBhdHRlbnRpb24qKiBpcyByZXF1aXJlZCBpbiBCaW8gMjQwIGp1c3QgYXMgaXQncyByZXF1aXJlZCBpbiANCmJpb2xvZ2ljYWwgcmVzZWFyY2ggYW5kIGp1c3QgYXMgaXQncyByZXF1aXJlZCBpbiB5b3VyIHByb2Zlc3Npb25hbCBjYXJlZXIgDQpkZXZlbG9wbWVudC4NCjwvZGl2PiA8YnI+ICAgICANCg0KPCEtLSAgIC4uLiBjb21tZW50LW91dCB0aGUgU1ZHIHllbGxvdyBib3hlcyAtLS0tLQ0KYGBgez1odG1sfQ0KDQo8c3ZnIHdpZHRoPSI2OTAiIGhlaWdodD0iMTMwIj4NCiAgPHJlY3QgeD0iMTAiIHk9IjUiIHdpZHRoPSI1MCIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiANCiAgICBzdHlsZT0iZmlsbDp5ZWxsb3c7IHN0cm9rZTpwaW5rOyBzdHJva2Utd2lkdGg6NSIvPg0KICA8cmVjdCB4PSIxNDAiIHk9IjUiIHdpZHRoPSIxMDUiIGhlaWdodD0iNzUiIHJ4PSI4IiByeT0iOCIgIA0KICAgIHN0eWxlPSJmaWxsOnllbGxvdzsgc3Ryb2tlOnBpbms7IHN0cm9rZS13aWR0aDo1Ii8+DQogIDxyZWN0IHg9IjMwMCIgeT0iNSIgd2lkdGg9IjE0NSIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4Ig0KICAgIHN0eWxlPSJmaWxsOnllbGxvdzsgc3Ryb2tlOnBpbms7IHN0cm9rZS13aWR0aDo1Ii8+DQogIDxyZWN0IHg9IjUwMCIgeT0iNSIgd2lkdGg9IjE4NSIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4Ig0KICAgIHN0eWxlPSJmaWxsOnllbGxvdzsgc3Ryb2tlOnBpbms7IHN0cm9rZS13aWR0aDo1Ii8+DQoNCiAgPHRleHQgaWQ9InN2Z1RleHQiLCB4PSIyMiIgeT0iNTQiIGZpbGw9ImJsYWNrIiAgZm9udC1mYW1pbHk9InZlcmRhbmEiIA0KICAgICAgIGZvbnQtc2l6ZT0iMzAiIGZvbnQtd2VpZ2h0PWJvbGQ+IFIgPC90ZXh0Pg0KICA8dGV4dCBpZD0ic3ZnVGV4dCIsIHg9IjE1NyIgeT0iNTQiIGZpbGw9ImJsYWNrIiBmb250LWZhbWlseT0idmVyZGFuYSIgDQogICAgICAgZm9udC1zaXplPSIzMCIgZm9udC13ZWlnaHQ9Ym9sZD4gZGF0YSA8L3RleHQ+DQogIDx0ZXh0IGlkPSJzdmdUZXh0IiwgeD0iMzE1IiB5PSI1NCIgZmlsbD0iYmxhY2siIGZvbnQtZmFtaWx5PSJ2ZXJkYW5hIg0KICAgICAgIGZvbnQtc2l6ZT0iMzAiIGZvbnQtd2VpZ2h0PWJvbGQ+IGdyYXBocyA8L3RleHQ+DQogIDx0ZXh0IGlkPSJzdmdUZXh0IiwgeD0iNTE2IiB5PSI1NCIgZmlsbD0iYmxhY2siIGZvbnQtZmFtaWx5PSJ2ZXJkYW5hIg0KICAgICAgIGZvbnQtc2l6ZT0iMzAiIGZvbnQtd2VpZ2h0PWJvbGQ+IHN0YXRpc3RpY3MgPC90ZXh0Pg0KPC9zdmc+DQoNCmBgYA0KLS0+DQoNCjxicj4gDQoNCmBgYHs9aHRtbH0NCg0KPHN2ZyB3aWR0aD0iOTAwIiBoZWlnaHQ9IjEzMCI+DQogIDxyZWN0IHg9IjEwIiAgeT0iNSIgd2lkdGg9IjU1IiAgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiBzdHlsZT0iZmlsbDpwdXJwbGU7Ii8+DQogIDxyZWN0IHg9IjE0MCIgeT0iNSIgd2lkdGg9IjEwNSIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiBzdHlsZT0iZmlsbDpwdXJwbGU7Ii8+DQogIDxyZWN0IHg9IjMwMCIgeT0iNSIgd2lkdGg9IjE0NSIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiBzdHlsZT0iZmlsbDpwdXJwbGU7Ii8+DQogIDxyZWN0IHg9IjUwMCIgeT0iNSIgd2lkdGg9IjE3NSIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiBzdHlsZT0iZmlsbDpwdXJwbGU7Ii8+DQogIDxyZWN0IHg9IjcyNSIgeT0iNSIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI3NSIgcng9IjgiIHJ5PSI4IiBzdHlsZT0iZmlsbDpwdXJwbGU7Ii8+DQoNCiAgPHRleHQgaWQ9InN2Z1RleHQiLCB4PSIyMiIgeT0iNTQiIGZpbGw9InllbGxvdyIgIGZvbnQtZmFtaWx5PSJBcmlhbCIgDQogICAgICAgZm9udC1zaXplPSIzNSIgZm9udC13ZWlnaHQ9Ym9sZD4gUiA8L3RleHQ+DQogIDx0ZXh0IGlkPSJzdmdUZXh0IiwgeD0iMTU3IiB5PSI1NCIgZmlsbD0ieWVsbG93IiBmb250LWZhbWlseT0iQXJpYWwiIA0KICAgICAgIGZvbnQtc2l6ZT0iMzUiIGZvbnQtd2VpZ2h0PWJvbGQ+IERhdGEgPC90ZXh0Pg0KICA8dGV4dCBpZD0ic3ZnVGV4dCIsIHg9IjMxMiIgeT0iNTQiIGZpbGw9InllbGxvdyIgZm9udC1mYW1pbHk9IkFyaWFsIg0KICAgICAgIGZvbnQtc2l6ZT0iMzUiIGZvbnQtd2VpZ2h0PWJvbGQ+IEdyYXBocyA8L3RleHQ+DQogIDx0ZXh0IGlkPSJzdmdUZXh0IiwgeD0iNTEwIiB5PSI1NCIgZmlsbD0ieWVsbG93IiBmb250LWZhbWlseT0iQXJpYWwiDQogICAgICAgZm9udC1zaXplPSIzNSIgZm9udC13ZWlnaHQ9Ym9sZD4gU3RhdGlzdGljcyA8L3RleHQ+DQogIDx0ZXh0IGlkPSJzdmdUZXh0IiwgeD0iNzQxIiB5PSI1NCIgZmlsbD0ieWVsbG93IiBmb250LWZhbWlseT0iQXJpYWwiDQogICAgICAgZm9udC1zaXplPSIzNSIgZm9udC13ZWlnaHQ9Ym9sZD4gV3JpdGluZyA8L3RleHQ+DQo8L3N2Zz4NCg0KYGBgDQo8YnI+IA0KDQo8IS0tICAgLi4uLi4uICBET05BTEQgS05VVEggcXVvdGF0aW9uICAuLi4uLi4gLS0+DQo+ICANCj4gPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBHYXJhbW9uZCwgVGltZXM7IGZvbnQtc2l6ZTogMTUwJTsgY29sb3I6IGRhcmtyZWQ7IA0KZm9udC1zdHlsZTogaXRhbGljOyBsaW5lLWhlaWdodDogOTUlOyAiPiAiVGhlIHByb2Nlc3Mgb2YgcHJlcGFyaW5nIHByb2dyYW1zIGZvciBhIGRpZ2l0YWwgY29tcHV0ZXIgDQppcyBlc3BlY2lhbGx5IGF0dHJhY3RpdmUgbm90IG9ubHkgYmVjYXVzZSBpdCBjYW4gYmUgZWNvbm9taWNhbGx5IGFuZCBzY2llbnRpZmljYWxseSANCnJld2FyZGluZywgYnV0IGFsc28gYmVjYXVzZSBpdCBjYW4gYmUgYW4gYWVzdGhldGljIGV4cGVyaWVuY2UgbXVjaCBsaWtlIGNvbXBvc2luZyANCnBvZXRyeSBvciBtdXNpYyIgPC9zcGFuPg0KPiAgDQo+Pj4gLS0tICoqRG9uYWxkIEUuIEtudXRoKiouIDE5NzMuICpUaGUgQXJ0IG9mIENvbXB1dGVyIFByb2dyYW1taW5nKiwgMm5kIGVkLCANClZvbCAxLCAqRnVuZGFtZW50YWwgQWxnb3JpdGhtcyouIFByb2Zlc3NvciBFbWVyaXR1cywgQ29tcHV0ZXIgU2NpZW5jZSBEZXBhcnRtZW50LCANClN0YW5mb3JkIFVuaXZlcnNpdHksIENBDQoNCiANCmBgYHtyLCBjYWNoZT1UUlVFLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjM1JSIsIGZpZy5jYXA9ImJvcm4gMTkzOCIsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLnNob3c9ImhvbGQifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvS251dGggMS5qcGciKQ0KYGBgDQoNCg0KPHAgc3R5bGU9ICJmb250LXNpemU6IDE0MCU7Ij4gSW4gQmlvIDI0MCwgSSB0cnkgdG8gY29udmluY2UgeW91IHRoYXQgd3JpdGluZyBwcm9ncmFtcyANCiAgaW4gUiBmb3IgZGVhbGluZyB3aXRoIGJpb2xvZ2ljYWwgZGF0YSwNCiAgPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBHYXJhbW9uZCwgVGltZXM7IGNvbG9yOiBkYXJrcmVkOyANCiAgZm9udC1zaXplOiAxNDAlOyBmb250LXN0eWxlOiBpdGFsaWM7IGxpbmUtaGVpZ2h0OiA5NSUiPg0KICAiLi4uY2FuIGJlIGFuIGFlc3RoZXRpYyBleHBlcmllbmNlIG11Y2ggbGlrZSBjb21wb3NpbmcgcG9ldHJ5IG9yIG11c2ljLiI8L3NwYW4+IA0KPC9wPg0KDQo8YnI+PGJyPg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQojICZuYnNwOyBHcmFkaW5nICAgICAgICAgIDwhLS0gIC4uLi4uLi4uLi4gRklGVEggc2VjdGlvbiBvZiBkb2N1bWVudCAuLi4uLi4uLi4uICAtLT4NCiAgICAgICAgICAgICAgICAgIA0KPGJyPiANCjxoMiBzdHlsZT0iY29sb3I6IGJsdWU7IGZvbnQtZmFtaWx5OiBHYXJhbW9uZDsgZm9udC13ZWlnaHQ6IG5vcm1hbDsgZm9udC1zaXplOiAzMnB4OyANCnRleHQtYWxpZ246IGNlbnRlcjsgd29yZC1zcGFjaW5nOiA3cHg7Ij4gDQpGaW5hbCBhdmVyYWdlID0gKCBUZXN0IDEgKyBUZXN0IDIgKyBUZXN0IDMgKSAvIDMgDQo8YnI+PGJyPjwvaDI+IA0KDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIzIj4NCg0KQnkgdGhlIGFib3ZlIGZvcm11bGEsIHRoZSBhdmVyYWdlIG9mIHRoZSAzIGZvcm1hbCBUZXN0cyBpcyAxMDAlIG9mIHRoZSBmaW5hbCBncmFkZS4gDQoNCkFsdGhvdWdoIG5vdCBncmFkZWQsIGRhdGEgYXNzaWdubWVudHMsIHByYWN0aWNlIFRlc3RzLCBab29tIHBvbGxzIGFuZCBvdGhlciAgDQphY3Rpdml0aWVzLCByZWZsZWN0IG1hdGVyaWFsIHRvIGtlZXAgeW91IG1vdmluZyBmb3J3YXJkIGluIHRoZSBjb3Vyc2UuIA0KDQpUaGUgbnVtYmVyIG9mIFRlc3RzLCBldmVuIHRoZSBmb3JtdWxhIGl0c2VsZiBtYXkgY2hhbmdlLCByZWZsZWN0aW5nIGludGVybmFsIA0KYXMgd2VsbCBhcyBleHRlcm5hbCBmYWN0b3JzIHRoYXQgbWF5IGJlIGJleW9uZCBvdXIgY29udHJvbCBkdXJpbmcgdGhlIHBhbmRlbWljLiAgDQoNClRoZXJlIGlzICoqKm5vIGV4dHJhIGNyZWRpdCB3b3JrKioqIGluIEJpbyAyNDAsIGJleW9uZCANCnRoZSArMiB0byArMTAgcG9pbnRzIG9mIGV4dHJhIGNyZWRpdCBxdWVzdGlvbnMgdGhhdCBhcmUgYXQgdGhlIGVuZCBvZiBlYWNoIA0KVGVzdCwgdXN1YWxseS4gVGhlcmVmb3JlLCBwbGVhc2UgZG8gbm90IGFzayBmb3IgZXh0cmEgY3JlZGl0IHdvcmsuICANCg0KVGVzdHMgYXJlICoqZm9ybSBmaWxsIFBERioqIGZpbGVzIHRoYXQgYXJlIGRvd25sb2FkZWQgdG8geW91ciBtYWNoaW5lLCBlbmdhZ2VkLCANCnNhdmVkIGFuZCB0aGVuIGVtYWlsZWQgYmFjayB0byBtZS4gDQoNCioqWW91IG11c3QgYmUgYWJsZSB0byBoYW5kbGUgZm9ybSBmaWxsIFBERiBmaWxlcyBlbHNlIHlvdSBtdXN0IGRyb3AgQmlvIDI0MCoqLiANClRoaXMgd2lsbCBiZSBhZGRyZXNzZWQgb24gdGhlIGZpcnN0IGRheSBvZiBjbGFzcy4gDQoNCldoaWxlIG1hbnkgYXBwcywgZXZlbiBicm93c2VycywgY2FuIHBhcnRpYWxseSBkZWFsIHdpdGggZm9ybSBmaWxsIFBERiBmaWxlcywgDQp0aGUgYmVzdCBvbmUgaXMgKipBY3JvYmF0IFJlYWRlciBEQyoqIHdoaWNoIGlzIGZyZWUgYW5kIGJ5IEFkb2JlLCB0aGUgY29tcGFueSANCnRoYXQgaW52ZW50ZWQgUERGOiAmbmJzcDsgaHR0cHM6Ly9nZXQuYWRvYmUuY29tL3JlYWRlci8gJm5ic3A7ICANCg0KQWNyb2JhdCBSZWFkZXIgREMgd29ya3Mgb24gYWxsIG9wZXJhdGluZyBzeXN0ZW1zOyBpdCdzIHdoYXQgSSB1c2UuIERvd25sb2FkIGl0LiANCg0KVGVzdHMgYXJlIHN0cmljdGx5IHRpbWVkIGF0ICoqNCBob3VycyoqIGFuZCBhcmUgbm90IGN1bXVsYXRpdmUuICYjMTI4NTEyOyANCjwvZGl2PiA8YnI+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRU5EICAzIGNvbHVtbiBuZXdzcGFwZXIgc3R5bGUgLS0+DQoNCmBgYA0KICAgICAgICAgIEZpbmFsIGF2ZXJhZ2UgICAgTGV0dGVyIGdyYWRlICAgICAgICBEZXRhaWxzDQogICAgIA0KICAgICAgICAgICAgPj0gOTAgICAgICAgICAgICAgQS0sIEEgICAgICAgICAgOTAgPD0gQS0gPCA5MyAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOTMgPD0gQSAgPCAxMDANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICA+PSA4MCAmIDwgOTAgICAgICBCLSwgQiwgQisgICAgICA4MCA8PSBCLSA8IDgzICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDgzIDw9IEIgIDwgODUgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgODUgPD0gQisgPCA5MCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgPj0gNzAgJiA8IDgwICAgICAgQy0sIEMsIEMrICAgICAgNzAgPD0gQy0gPCA3Mw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzMgPD0gQyAgPCA3NQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzUgPD0gQysgPCA4MA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgID49IDYwICYgPCA3MCAgICAgIEQsICBEKyAgICAgICAgIDYwIDw9IEQgIDwgNjUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDY1IDw9IEQrIDwgNzANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgIDwgNjAgICAgICAgICAgICAgRiAgICAgICAgICAgICAgICAgICAgRiAgPCA2MA0KYGBgDQoNCjxicj4gIA0KDQpgYGB7PWh0bWx9DQo8cCBzdHlsZT0iZm9udC1mYW1pbHk6IGNvbWljIHNhbnMgbXM7IGNvbG9yOiBibHVlOyBmb250LXNpemU6IDE4cHQ7DQogICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBjb3Juc2lsazsgd2lkdGg6IDU0MHB4OyANCiAgICAgICAgIGhlaWdodDogNTVweDsgcGFkZGluZy10b3A6IDEzcHg7ICAgDQogICAgICAgICBmb250LXdlaWdodDogYm9sZDsgdGV4dC1hbGlnbjogY2VudGVyOyI+DQogICANCiAgSG93IHRvIHN1Y2NlZWQgaW4gQmlvIDI0MCA8aT48dT5CaW9zdGF0aXN0aWNzPC91PjwvaT4gIA0KPC9wPg0KDQoNCjxwIHN0eWxlPSJsaW5lLWhlaWdodDogMTIwJTsgZm9udC1zaXplOiAxOHB0OyI+ICANCiAgICAmZW1zcDsgJiMxMDEwMjsgU2hvdyB1cCAmbmJzcDsgICAgICA8IS0tIHNvbGlkIGJsYWNrIGNpcmNsZXM7IHdoaXRlIGludGVnZXJzIC0tPg0KICAgICZlbXNwOyAmIzEwMTAzOyBTaG93IHVwIG9uIHRpbWUgJm5ic3A7IA0KICAgICZlbXNwOyAmIzEwMTA0OyBQYXkgYXR0ZW50aW9uIDxicj4gDQogICAgJmVtc3A7ICYjMTAxMDU7IFRha2Ugbm90ZXMgJm5ic3A7DQogICAgJmVtc3A7ICYjMTAxMDY7IFdvcmsgaGFyZCAmbmJzcDsgICANCiAgICAmZW1zcDsgJiMxMDEwNzsgQXNrIHF1ZXN0aW9ucyA8YnI+DQogICAgJmVtc3A7ICYjMTAxMDg7IEJlIGhvbmVzdCwgZG9uJ3QgY2hlYXQgJm5ic3A7DQogICAgJmVtc3A7ICYjMTAxMDk7IFByYWN0aWNlLCBwcmFjdGljZSwgcHJhY3RpY2UNCjwvcD4NCmBgYA0KDQo8YnI+PGJyPg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQoNCiMgJm5ic3A7IFRleHRib29rcyAgICAgICAgICAgIDwhLS0gIC4uLi4uLiA2dGggc2VjdGlvbiBvZiBkb2N1bWVudCAuLi4uLi4gIC0tPg0KPGJyPg0KDQojIyAmbmJzcDsgUmVxdWlyZWQgcmVhZGluZw0KPGJyPiANCg0KKiAqKkRhbGdhYXJkLCBQZXRlcioqICgyMDA4KSAqKkludHJvZHVjdG9yeSBTdGF0aXN0aWNzIHdpdGggUioqLCAybmQgZWQuIFNwcmluZ2VyLCANCk5ZLiBwYXBlciwgMzYzIHBhZ2VzLiAkNTYgYXQgQW1hem9uLiANCkJlY2F1c2UgYSBuZXcgZWRpdGlvbiBpcyBlbWluZW50LCBvbmUgbWF5IHZpZXcvZG93bmxvYWQgZnJvbSBoaXMgdW5pdmVyc2l0eSBhdDogICAgICANCmh0dHA6Ly93d3cuYWNhZGVtaWEuZGsvQmlvbG9naXNrQW50cm9wb2xvZ2kvRXBpZGVtaW9sb2dpL1BERi9JbnRyb2R1Y3RvcnlfU3RhdGlzdGljc193aXRoX1JfXzJuZF9lZC5wZGYNCm9yIHZpZXcgYXQgbXkgZHJvcGJveCBsaW5rLCBzZWUgKipGaXJzdCBhc3NpZ25tZW50KiouIFByb2Zlc3NvciBEYWxnYWFyZCANCm1haW50YWlucyBhIGdsb2JhbGx5IGltcG9ydGFudCBhbmQgcGl2b3RhbCByb2xlIGluIFIuIDxicj48YnI+ICANCg0KIyMgJm5ic3A7IFN1Z2dlc3RlZA0KPGJyPiANCg0KKiBWZXJ6YW5pLCBKb2huICgyMDE0KSAqKlVzaW5nIFIgZm9yIEludHJvZHVjdG9yeSBTdGF0aXN0aWNzKiosIDJuZCBlZC4gQ1JDIFByZXNzLCANCk5ZLiA1MDIgcGFnZXMuICQyNyBhdCBBbWF6b24uIERyLiBWZXJ6YW5pIGlzIGEgbWF0aCBQcm9mZXNzb3IgYXQgQ29sbGVnZSBvZiBTdGF0ZW4gDQpJc2xhbmQsIENVTlkuDQoNCiogTXVycmVsbCwgUGF1bCAoMjAxOSkgKipSIEdyYXBoaWNzLCAzcmQgZWQqKi4gQ1JDIFByZXNzLCBGTC4gNDIzIHBhZ2VzLiAkODIgYXQgDQpBbWF6b24uIFBhdWwgTXVycmVsbCBpcyBhcHByZWNpYXRlZCBhcyB0aGUgbGVhZGluZyBleHBlcnQgb24gUiBncmFwaGljcyBhbmQgYXV0aG9yIA0Kb2YgUiBwYWNrYWdlcywgaW5jbHVkaW5nIGBgYGdyaWRgYGAgd2hpY2ggZW5hYmxlcyB0aGUgcGFja2FnZXMgYGBgbGF0dGljZWBgYCwgDQpgYGBnZ3Bsb3QyYGBgIGFuZCBvdGhlciBhZHZhbmNlZCBncmFwaGljIGVudmlyb25tZW50cy4gVGhpcyBjb21wcmVoZW5zaXZlIGJvb2sgaXMgDQpub3QgZm9yIHRoZSBmYWludGhlYXJ0ZWQuIEhvd2V2ZXIsIGhpcyBlYXJseSBjaGFwdGVycyBvbiBiYXNlIFIgZ3JhcGhpY3MgYXJlIGZ1bmRhbWVudGFsLCANCnVuZGVyc3RhbmRhYmxlIGFuZCBwcmVjaXNlbHkgZGVtb25zdHJhdGVkLg0KDQoqIGRlIFZyaWVzLCBBLiBhbmQgSi4gTWV5cyAoMjAxNSkgKipSIGZvciBEdW1taWVzKiosIDJuZCBlZC4gSm9obiBXaWxleSwgTkouIHBhcGVyLCANCjQxOCBwYWdlcy4gJDE5IGF0IEFtYXpvbi4NCg0KKiBOYXZhcnJvLCBEYW5pZWxsZSAoMjAxNSkgKipMZWFybmluZyBTdGF0aXN0aWNzIHdpdGggUioqLCBWZXJzaW9uIDAuNi4gQ3JlYXRpdmUgDQpDb21tb25zIEJZLVNBIGxpY2Vuc2UgZm9yIGZyZWUgdXNlLiA2MTMgcGFnZXMuIA0KUERGIGRvd25sb2FkIGF0OiAmbmJzcDsgaHR0cHM6Ly9sZWFybmluZ3N0YXRpc3RpY3N3aXRoci5jb20gDQoNCjxicj4gDQoNCiMjICZuYnNwOyBSZWFkIG9ubGluZSBmb3IgZnJlZQ0KPGJyPg0KDQoqKmJvb2tzIG9uIERhdGEsIEdyYXBocywgU3RhdGlzdGljcywgUiBwcm9ncmFtbWluZyoqDQoNCiogQ2hhbmcsIFdpbnN0b24gKDIwMTkpICoqUiBHcmFwaGljcyBDb29rYm9vayoqICpQcmFjdGljYWwgUmVjaXBlcyBmb3IgVmlzdWFsaXppbmcgDQpEYXRhKiwgMm5kIGVkLiBPJ1JlaWxseSwgQ0EuIHBhcGVyLCA0MjUgcGFnZXMuICQ0OCBhdCBBbWF6b24uDQoqUmVhZCBvbmxpbmUgZm9yIGZyZWUqIGF0OiAmbmJzcDsgaHR0cHM6Ly9yLWdyYXBoaWNzLm9yZyANCg0KKiBMb25nLCBKLkQuIGFuZCBQLiBUZWV0b3IgKDIwMTkpICoqUiBDb29rYm9vayoqICpQcm92ZW4gUmVjaXBpZXMgZm9yIERhdGEgDQpBbmFseXNpcywgU3RhdGlzdGljcywgYW5kIEdyYXBoaWNzKiwgMm5kIGVkLiBPJ1JlaWxseSwgQ0EuIHBhcGVyLCA1NzkgcGFnZXMuIA0KJDQxIGF0IEFtYXpvbi4gKlJlYWQgb25saW5lIGZvciBmcmVlKiBhdDogJm5ic3A7IGh0dHBzOi8vcmMyZS5jb20NCg0KKiBXaWNraGFtLCBILiBhbmQgRy4gR3JvbGVtdW5kICgyMDE3KSAqKlIgZm9yIERhdGEgU2NpZW5jZSoqICpJbXBvcnQsIFRpZHksIA0KVHJhbnNmb3JtLCBWaXN1YWxpemUsIGFuZCBNb2RlbCBEYXRhKi4gTydSZWlsbHksIENBLiBwYXBlciwgNDkyIHBhZ2VzLiANCiQ0MCBhdCBBbWF6b24uIDJuZCBlZC4gaW4gcHJvZ3Jlc3MuICAqUmVhZCBvbmxpbmUgZm9yIGZyZWUqIGF0OiAmbmJzcDsgaHR0cHM6Ly9yNGRzLmhhZC5jby5ueg0KDQoqIFdpY2toYW0sIEguICgyMDE5KSAqKkFkdmFuY2VkIFIqKiwgMm5kIGVkLiBDaGFwbWFuICYgSGFsbC9DUkMsIE5ZLiBwYXBlciwgNjA0IA0KcGFnZXMuICQ0MiBhdCBBbWF6b24uICpSZWFkIG9ubGluZSBmb3IgZnJlZSosIGF0OiAmbmJzcDsgaHR0cHM6Ly9hZHYtci5oYWRsZXkubnovDQoNCiogR2lsbGVzcGllLCBDLiBhbmQgUi4gTG92ZWxhY2UgKDIwMTYpICoqRWZmaWNpZW50IFIgUHJvZ3JhbW1pbmcqKiAqYSBwcmFjdGljYWwgDQpndWlkZSB0byBzbWFydGVyIHByb2dyYW1taW5nKi4gTydSZWlsbHksIENBLiBwYXBlciwgMjIyIHBhZ2VzLiANCiQyNCBhdCBBbWF6b24uICpSZWFkIG9ubGluZSBmb3IgZnJlZSosIGF0OiAmbmJzcDsgaHR0cDovL2NzZ2lsbGVzcGllLmdpdGh1Yi5pby9lZmZpY2llbnRSLw0KDQoqIEdyb2xlbXVuZCwgRy4gKDIwMTQpICoqSGFuZHMtT24gUHJvZ3JhbW1pbmcgd2l0aCBSKiogKldyaXRlIHlvdXIgb3duIGZ1bmN0aW9ucyANCmFuZCBzaW11bGF0aW9ucyosIE8nUmVpbGx5LCBDQS4gcGFwZXIsIDIzMCBwYWdlcy4gDQokMjYgYXQgQW1hem9uLiAqUmVhZCBvbmxpbmUgZm9yIGZyZWUqLCBhdDogJm5ic3A7IGh0dHBzOi8vcnN0dWRpby1lZHVjYXRpb24uZ2l0aHViLmlvL2hvcHIvDQoNCioqYm9va3Mgb24gUmVwcm9kdWNpYmxlIFJlc2VhcmNoKiogYW5kICoqSW50ZXJhY3RpdmUgQXBwcyoqDQoNCiogWGllLCBZLiAoMjAxNSkgKipEeW5hbWljIERvY3VtZW50cyB3aXRoIFIgYW5kIGtuaXRyKiosIDJuZCBlZC4gQ2hhcG1hbiAmIEhhbGwvQ1JDLCANCk5ZLiBwYXBlciwgMjk0IHBhZ2VzLiAkNDAgYXQgQW1hem9uLiAgKlJlYWQgb25saW5lIGZvciBmcmVlKiwgYXQ6ICZuYnNwOw0KaHR0cHM6Ly95aWh1aS5vcmcva25pdHIvDQoNCiogV2lja2hhbSwgSC4gYW5kIEplbm55IEJyeWFuICgyMDIzKSAqKlIgUGFja2FnZXMqKiAqT3JnYW5pemUsIHRlc3QsIGRvY3VtZW50LCBhbmQgc2hhcmUgeW91ciBjb2RlKiwgMm5kIGVkLiBPJ1JlaWxseSwgQ0EuIHBhcGVyLiAkNjAgYXQgQW1hem9uLiAqUmVhZCBvbmxpbmUgZm9yIGZyZWUqIGF0OiAmbmJzcDsNCmh0dHBzOi8vci1wa2dzLm9yZy8NCg0KKiBXaWNraGFtIEguICgyMDIxKSAqKk1hc3RlcmluZyBzaGlueTogYnVpbGQgSW50ZXJhY3RpdmUgQXBwcywgUmVwb3J0cyAmIERhc2hib2FyZHMqKiwgDQpPJ1JlaWxseSwgQ0EuIHBhcGVyLiAzNzIgcGFnZXMuICQzOCBhdCBBbWF6b24uICpSZWFkIG9ubGluZSBmb3IgZnJlZSogYXQ6ICZuYnNwOw0KaHR0cHM6Ly9tYXN0ZXJpbmctc2hpbnkub3JnDQoNCiogWGllLCBZLiAoMjAxNikgKipib29rZG93bioqICpBdXRob3JpbmcgYm9va3MgYW5kIFRlY2huaWNhbCBEb2N1bWVudHMgd2l0aCBSIA0KTWFya2Rvd24qLiBDaGFwbWFuICYgSGFsbC9DUkMsIE5ZLiBwYXBlciwgMTM4IHBhZ2VzLiAkMjMgYXQgQW1hem9uLiANCipSZWFkIG9ubGluZSBmb3IgZnJlZSosIGF0OiAmbmJzcDsgaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vDQoNCiogWGllLCBZLiwgQS4gVGhvbWFzIGFuZCBBLlAuIEhpbGwgKDIwMTcpICoqYmxvZ2Rvd24qKiAqQ3JlYXRpbmcgV2Vic2l0ZXMgd2l0aCBSIA0KTWFya2Rvd24qLiBDaGFwbWFuICYgSGFsbC9DUkMsIE5ZLiBwYXBlciwgMTcyIHBhZ2VzLiAkMjcgYXQgQW1hem9uLiAqUmVhZCBvbmxpbmUgDQpmb3IgZnJlZSogYXQ6ICZuYnNwOyBodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ibG9nZG93bi8NCg0KKiBYaWUsIFkuLCBKLkouIEFsbGFpcmUgYW5kIEcuIEdyb2xlbXVuZCAoMjAxOCkgKipSIE1hcmtkb3duKiogKlRoZSBEZWZpbml0aXZlIA0KR3VpZGUqLiBDaGFwbWFuICYgSGFsbC9DUkMsIE5ZLiBwYXBlciwgMzM4IHBhZ2VzLiAkMzQgYXQgQW1hem9uLiAqUmVhZCBvbmxpbmUgZm9yIA0KZnJlZSosIGF0OiAmbmJzcDsgaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLw0KDQo8YnI+ICANCg0KPHAgaWQ9ImJsYWNrbGluZSI+IF9fX19fX19fX19fX19fX19fXyA8L3A+IDxicj4gICAgICAgIDwhLS0gYmxhY2sgbGluZSAtLT4gDQoNCg0KIyAmbmJzcDsgRmlyc3QgcmVhZGluZyBhc3NpZ25tZW50IGFuZCBvdGhlciByZXNvdXJjZXMgICAgPCEtLSAgLi4gN3RoIHNlY3Rpb24gLi4gIC0tPg0KDQo8YnI+IA0KDQojIyAmbmJzcDsgUmVhZGluZ3MgICAgICA8IS0tIG15IENVTlkgZHJvcGJveCBhY2NvdW50IC0tPg0KPGJyPiANCipBdmFpbGFibGUgYXMgUERGIGZpbGVzIGJ5IG15IGRyb3Bib3ggbGluayo6ICANCmh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NoL3FyMXVvd3ZmaThtMG9hZS9BQUM5b0dIMEtQbWFZbVU0eTAyTXRLVVphP2RsPTANCg0KKipTY2FuKiogKnRoZXNlIDQgcmVhZGluZyBhc3NpZ25tZW50cyogDQoNCjEuIERhbGdhYXJkLCBQZXRlciAoMjAwOCkgLS0tIENoIDEuIEJhc2ljcywgJm5ic3A7IENoIDIuIFRoZSBSIEVudmlyb25tZW50LCAmbmJzcDsgDQpDaCA0LiBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFuZCBncmFwaGljcw0KDQoyLiBNdXJyZWxsLCBQYXVsICgyMDExKSBSIEdyYXBoaWNzLiAybmQgZWQuIC0tLSBDaCAxLiBBbiBJbnRyb2R1Y3Rpb24gdG8gUiBHcmFwaGljcywgDQombmJzcDsgQ2ggMi4gU2ltcGxlIFVzYWdlIG9mIFRyYWRpdGlvbmFsIEdyYXBoaWNzLCAmbmJzcDsJQ2ggMy4gQ3VzdG9taXppbmcgDQpUcmFkaXRpb25hbCBHcmFwaGljcy4gPGJyPiBUaGlzIGlzIG5vdCBmcm9tIGhpcyAzcmQgZWRpdGlvbiBidXQgY29udGVudCBpcyBuZWFybHkgDQp0aGUgc2FtZSBmb3IgdGhlc2UgMyBjaGFwdGVycyBvbiBiYXNlIFIgZ3JhcGhpY3MuIA0KDQozLiBCYWxkaSAmIE1vb3JlICgyMDA5KSBUaGUgUHJhY3RpY2Ugb2YgU3RhdGlzdGljcyBpbiB0aGUgTGlmZSBTY2llbmNlcy4gLS0tCUNoIDEuIA0KUGljdHVyaW5nIERpc3RyaWJ1dGlvbnMgd2l0aCBHcmFwaHMsIDxicj4gQ2ggMi4gRGVzY3JpYmluZyBEaXN0cmlidXRpb25zIHdpdGggTnVtYmVycw0KDQo0LiBTb2thbCAmIFJvaGxmCSgxOTk1KSBCaW9tZXRyeS4gM3JkIGVkLiAtLS0JQ2ggMi4gRGF0YSBpbiBCaW9sb2d5LCAmbmJzcDsgDQpDaCA0LiBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQoNCg0KQ29udHJpYnV0ZWQgYnkgdGhlIFIgY29tbXVuaXR5LCB0aGUgUiB3ZWJzaXRlIChodHRwczovL3d3dy5yLXByb2plY3Qub3JnLykgaGFzIGxpbmtzIA0KZm9yIGZyZWUgYm9va3MsIHBhbXBobGV0cyBhbmQgaW5mb3JtYXRpb24gc2hlZXRzLiANCg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQoNCiMjICZuYnNwOyBWaWRlb3MgDQoNCjxicj4gDQoNCj4gQWR2aWNlIG9uIGxlYXJuaW5nIHRvIGNvZGUgdG8gYmVuZWZpdCB5b3VyIHNjaWVudGlmaWMgY2FyZWVyICANCg0KUGxlYXNlIHdhdGNoIHRoaXMgdmlkZW8gYXQgaHR0cHM6Ly95b3V0dS5iZS8wTDRDUVVLLS1kQSANCg0KSW4gSnVuZSAyMDIxLCB0aGUgam91cm5hbCAqTmF0dXJlKiBwcmVzZW50ZWQgYSA2MCBtaW51dGUgV2ViY2FzdCBvbiAiQWR2aWNlIG9uIA0KbGVhcm5pbmcgdG8gY29kZSB0byBiZW5lZml0IHlvdXIgc2NpZW50aWZpYyBjYXJlZXIuIiBJdCBoYWQgMyBzcGVha2VycywgUSZBLCBhbmQgDQpSIHdhcyBlbXBoYXNpemVkIGFsb25nIHdpdGggUHl0aG9uLiBNdWNoIG9mIHdoYXQgdGhleSBkaXNjdXNzZWQgcmVzb25hdGVzIHdpdGggb3VyIA0KbGVhcm5pbmcgcGF0aCBpbiBCaW8gMjQwICpCaW9zdGF0aXN0aWNzKi4gDQoNCioqUXVlc3Rpb24qKjogRG8geW91IGtub3cgd2hhdCBGT1NTIHN0YW5kcyBmb3I/IEkgYW0gcHJvdWQgdG8gYmUgYSBGT1NTIHBlcnNvbi4gIA0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQo+IERyLiBTdGVwaGVuIExpbm4gQ2hldy4gJm5ic3A7IEhvdyB0byBHZXQgdGhlIE1vc3Qgb3V0IG9mIFN0dWR5aW5nIA0KDQpodHRwczovL3d3dy5zYW1mb3JkLmVkdS9hcnRzLWFuZC1zY2llbmNlcy9kaXJlY3RvcnkvQ2hldy1TdGVwaGVuLUxpbm4gICZuYnNwOyAtLSBoaXMgd2Vic2l0ZQ0KDQoNCisgPHU+T3ZlcnZpZXcgVmlkZW88L3U+OiAmbmJzcDsgKkRldmVsb3BpbmcgYSBNaW5kc2V0IGZvciBTdWNjZXNzZnVsIExlYXJuaW5nKiANCiZlbXNwOyA3OjU2IG1pbnV0ZXMgIA0KaHR0cHM6Ly95b3V0dS5iZS9odHY2ZWFwMS1fTT9saXN0PVBMODU3MDhFNkVBMjM2RTNEQg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjIwJSIsIGZpZy5hbGlnbj0iY2VudGVyIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0NCiAgICAgICAgICAgICAgICAgICJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9DaGV3MS5qcGciKQ0KYGBgDQoNCg0KKiBWaWRlbyAxLiAmbmJzcDsgKkJlbGllZnMgVGhhdCBNYWtlIFlvdSBGYWlsLi4uT3IgU3VjY2VlZCogICANCmh0dHBzOi8veW91dHUuYmUvUkg5NWgzNk5DaEkgICAgJmVtc3A7IDY6NTQgbWludXRlcw0KDQoqIFZpZGVvIDIuICZuYnNwOyAqV2hhdCBTdHVkZW50cyBTaG91bGQgVW5kZXJzdGFuZCBBYm91dCBIb3cgUGVvcGxlIExlYXJuKiAgIA0KaHR0cHM6Ly95b3V0dS5iZS85Tzd5N1hFQzY2TSAgICAmZW1zcDsgNzoxNSBtaW51dGVzDQoNCiogVmlkZW8gMy4gJm5ic3A7ICpDb2duaXRpdmUgUHJpbmNpcGxlcyBGb3IgT3B0aW1pemluZyBMZWFybmluZyogIA0KaHR0cHM6Ly95b3V0dS5iZS8xeGVIaDVEbkNJdyAgICAmZW1zcDsgNTo0NSBtaW51dGVzDQoNCiogVmlkZW8gNC4gJm5ic3A7ICpQdXR0aW5nIFRoZSBQcmluY2lwbGVzIEZvciBPcHRpbWl6aW5nIExlYXJuaW5nIEludG8gUHJhY3RpY2UqICANCmh0dHBzOi8veW91dHUuYmUvRTlHck94aFlaZFEgICAgJmVtc3A7IDk6MTcgbWludXRlcw0KDQoqIFZpZGVvIDUuICZuYnNwOyAqSSBCbGV3IFRoZSBFeGFtLCBOb3cgV2hhdD8qICAgDQpodHRwczovL3lvdXR1LmJlLy1RVlJpTWtkUnNVICAgICZlbXNwOyA3OjI5IG1pbnV0ZXMNCg0KKiBEb3dubG9hZCB0aGUgPHU+VGVhY2hpbmcgR3VpZGU8L3U+IGJ5IERyLiBDaGV3LiAmbmJzcDsgMTUgcGFnZXMgIA0KaHR0cHM6Ly93d3cuc2FtZm9yZC5lZHUvZGVwYXJ0bWVudHMvZmlsZXMvQWNhZGVtaWNfU3VjY2Vzc19DZW50ZXIvSG93LXRvLVN0dWR5LVRlYWNoaW5nX1Jlc291cmNlcy5wZGYNCg0KPHAgaWQ9ImJsYWNrbGluZSI+IF9fX19fX19fX19fX19fX19fXyA8L3A+IDxicj4gICAgICAgIDwhLS0gYmxhY2sgbGluZSBjZW50ZXJlZCAtLT4gDQoNCg0KPiBEci4gUGFyZGlzIFNhYmV0aS4gJm5ic3A7IFdoYXQgaXMgU3RhdGlzdGljcz8NCg0KPCEtLSAuLi4gPGg0PiBWaWRlb3MgZnJvbSBBbm5lbmJlcmcgTGVhcm5lciAtLSBodHRwczovL3d3dy5sZWFybmVyLm9yZyA8L2g0PiAuLi4gLS0+DQoNCldoYXQgaXMgU3RhdGlzdGljcz8gJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3Mvd2hhdC1pcy1zdGF0aXN0aWNzLw0KJm5ic3A7IDYgbWludXRlcyA8YnI+ICANCg0KRGVzaWduaW5nIGV4cGVyaW1lbnRzICZuYnNwOyANCmh0dHBzOi8vd3d3LmxlYXJuZXIub3JnL3Nlcmllcy9hZ2FpbnN0LWFsbC1vZGRzLWluc2lkZS1zdGF0aXN0aWNzL2Rlc2lnbmluZy1leHBlcmltZW50cy8NCiZuYnNwOyAxMSBtaW51dGVzLiANCkluIEJpbyAyNDAgd2Ugc2hhbGwgYW5hbHl6ZSBkYXRhIGZyb20gb2JzZXJ2YXRpb25hbCBzdHVkaWVzIGFzIHdlbGwgDQphcyBmcm9tIGV4cGVyaW1lbnRhbCBzdHVkaWVzIA0KDQpTdW1tYXJ5ICZuYnNwOyANCmh0dHBzOi8vd3d3LmxlYXJuZXIub3JnL3Nlcmllcy9hZ2FpbnN0LWFsbC1vZGRzLWluc2lkZS1zdGF0aXN0aWNzL3N1bW1hcnkvDQombmJzcDsgNiBtaW51dGVzIDxicj4gDQoNCioqKiAgDQoNClN0ZW0gcGxvdHMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3Mvc3RlbXBsb3RzLTIvDQombmJzcDsgMTEgbWludXRlcyANCg0KSGlzdG9ncmFtcyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9oaXN0b2dyYW1zLw0KJm5ic3A7IDkgbWludXRlcyANCg0KQm94cGxvdHMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvYm94cGxvdHMvDQombmJzcDsgOSBtaW51dGVzDQoNClNjYXR0ZXJwbG90cyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9zY2F0dGVycGxvdHMvDQombmJzcDsgOCBtaW51dGVzDQoNCioqKiANCk1lYXN1cmVzIG9mIGNlbnRlciAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9tZWFzdXJlcy1vZi1jZW50ZXIvDQombmJzcDsgOCBtaW51dGVzIA0KDQpTdGFuZGFyZCBkZXZpYXRpb24gJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3Mvc3RhbmRhcmQtZGV2aWF0aW9uLw0KJm5ic3A7IDkgbWludXRlcw0KDQpDb25maWRlbmNlIGludGVydmFscyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9jb25maWRlbmNlLWludGVydmFscy8NCiZuYnNwOyAxMCBtaW51dGVzDQoNCioqKg0KTm9ybWFsIGNhbGN1bGF0aW9ucyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9ub3JtYWwtY2FsY3VsYXRpb25zLw0KJm5ic3A7IDEyIG1pbnV0ZXMNCg0KTm9ybWFsIGN1cnZlcyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9ub3JtYWwtY3VydmVzLw0KJm5ic3A7IDEyIG1pbnV0ZXMNCg0KQ2hlY2tpbmcgYXNzdW1wdGlvbiBvZiBub3JtYWxpdHkgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvY2hlY2tpbmctYXNzdW1wdGlvbi1vZi1ub3JtYWxpdHkvDQombmJzcDsgMTAgbWludXRlcw0KDQoqKioNClNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3Mvc2FtcGxpbmctZGlzdHJpYnV0aW9ucy8NCiZuYnNwOyAxMiBtaW51dGVzDQoNClJhbmRvbSB2YXJpYWJsZXMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvcmFuZG9tLXZhcmlhYmxlcy8NCiZuYnNwOyAxMSBtaW51dGVzICANCkZlYXR1cmluZyB0aGUgTkFTQSBDaGFsbGVuZ2VyIGRpc2FzdGVyIG9mIDE5ODYgY2F1c2VkIGJ5IE8tcmluZyBmYWlsdXJlDQoNClRlc3RzIG9mIHNpZ25pZmljYW5jZSAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy90ZXN0cy1vZi1zaWduaWZpY2FuY2UvDQombmJzcDsgMTYgbWludXRlcw0KDQpTbWFsbCBzYW1wbGUgaW5mZXJlbmNlIGZvciBvbmUgbWVhbiAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9zbWFsbC1zYW1wbGUtaW5mZXJlbmNlLWZvci1vbmUtbWVhbi8NCiZuYnNwOyAxMiBtaW51dGVzDQoNCkNvbXBhcmluZyB0d28gbWVhbnMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvY29tcGFyaW5nLXR3by1tZWFucy8NCiZuYnNwOyAxMSBtaW51dGVzDQpGZWF0dXJpbmcgcmVzZWFyY2ggYnkgYSBDVU5ZIFByb2Zlc3NvciBhdCBIdW50ZXIgQ29sbGVnZQ0KDQpPbmUtd2F5IEFub3ZhICZuYnNwOyANCmh0dHBzOi8vd3d3LmxlYXJuZXIub3JnL3Nlcmllcy9hZ2FpbnN0LWFsbC1vZGRzLWluc2lkZS1zdGF0aXN0aWNzL29uZS13YXktYW5vdmEvDQombmJzcDsgMTIgbWludXRlcw0KDQoqKiogDQpDb3JyZWxhdGlvbiAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9jb3JyZWxhdGlvbi8NCiZuYnNwOyAxMCBtaW51dGVzDQoNClRoZSBxdWVzdGlvbiBvZiBjYXVzYXRpb24gJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvdGhlLXF1ZXN0aW9uLW9mLWNhdXNhdGlvbi8NCjE0IG1pbiANClNtb2tpbmcgYW5kIGx1bmcgY2FuY2VyIA0KDQpGaXR0aW5nIGxpbmVzIHRvIGRhdGEgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvZml0dGluZy1saW5lcy10by1kYXRhLw0KMTAgbWludXRlcyANCg0KSW5mZXJlbmNlIGZvciByZWdyZXNzaW9uICZuYnNwOyANCmh0dHBzOi8vd3d3LmxlYXJuZXIub3JnL3Nlcmllcy9hZ2FpbnN0LWFsbC1vZGRzLWluc2lkZS1zdGF0aXN0aWNzL2luZmVyZW5jZS1mb3ItcmVncmVzc2lvbi8NCjEzIG1pbnV0ZXMgDQpIaXN0b3J5IG9mIEREVCBhbmQgYmlyZCBlZ2dzDQoNCioqKiANCkludHJvZHVjdGlvbiB0byBwcm9iYWJpbGl0eSAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9pbnRyb2R1Y3Rpb24tdG8tcHJvYmFiaWxpdHkvDQoxMSBtaW51dGVzDQoNClByb2JhYmlsaXR5IG1vZGVscyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9wcm9iYWJpbGl0eS1tb2RlbHMvDQoxMCBtaW51dGVzDQoNCkJpbm9taWFsIGRpc3RyaWJ1dGlvbnMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvYmlub21pYWwtZGlzdHJpYnV0aW9ucy8NCjExIG1pbnV0ZXMNCg0KSW5mZXJlbmNlIGZvciBwcm9wb3J0aW9ucyAmbmJzcDsgDQpodHRwczovL3d3dy5sZWFybmVyLm9yZy9zZXJpZXMvYWdhaW5zdC1hbGwtb2Rkcy1pbnNpZGUtc3RhdGlzdGljcy9pbmZlcmVuY2UtZm9yLXByb3BvcnRpb25zLw0KMTAgbWluDQoNCkluZmVyZW5jZSBmb3IgdHdvLXdheSB0YWJsZXMgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvaW5mZXJlbmNlLWZvci10d28td2F5LXRhYmxlcy8NCjEwIG1pbnV0ZXMgDQpEci4gU2FiZXRpJ3MgbGFiIHdvcmsNCg0KR2xvc3NhcnkgJm5ic3A7IA0KaHR0cHM6Ly93d3cubGVhcm5lci5vcmcvc2VyaWVzL2FnYWluc3QtYWxsLW9kZHMtaW5zaWRlLXN0YXRpc3RpY3MvZ2xvc3NhcnkvDQoNCg0KKioqDQogDQoqKk5vdGU6KiogVGhlIHZpZXdpbmcgb3JkZXIgZm9yIERyLiBTYWJldGkncyBzaG9ydCwgc3RhdGlzdGljcyB2aWRlb3MgaXMgbm90IHRoYXQgDQppbXBvcnRhbnQuIEVhY2ggaXMgaW50cm9kdWN0b3J5LCBxdWFzaS1pbmRlcGVuZGVudCBhbmQgZWFjaCB1c2VzIHJlYWwtd29ybGQgZXhhbXBsZXMuIA0KVGhlcmUgYXJlIDM2IHVuaXRzLCBzb21lIHdpdGggUERGIHRyYW5zY3JpcHQgZG93bmxvYWRzLiBVbml0cyAzNC0zNiBhcmUgaW50ZXJhY3RpdmUgYXBwbGljYXRpb25zLiBJbnRlcmVzdGluZ2x5LCB0aGVyZSBpcyBubyBjb3ZlcmFnZSBvZiAqZWZmZWN0IHNpemUqLiBBcyB0aW1lIGFsbG93cywgDQp5b3UgbWF5IHByb2ZpdCBmcm9tIGVuZ2FnaW5nIHRoZXNlIDM2IHVuaXRzIHRoYXQgYXJlICoqb3B0aW9uYWwqKiBmb3IgQmlvIDI0MC4NCg0KPGJyPiANCjxoND4gRHIuIFBhcmRpcyBTYWJldGk8L2g0PiANCg0KU2hlIGlzIGEgcGh5c2ljaWFuIHNjaWVudGlzdCwgY29tcHV0YXRpb25hbCBnZW5ldGljaXN0LCBwcm9taW5lbnQgRWJvbGEsIExhc3NhIGZldmVyIA0KYW5kIENvdmlkLTE5IHJlc2VhcmNoZXIsIFByb2Zlc3NvciBhdCBIYXJ2YXJkIFVuaXZlcnNpdHkgYW5kIGFuIElyYW5pYW4gQW1lcmljYW4uIA0KU2hlIGVhcm5lZCB0aGUgUGhEIGZyb20gT3hmb3JkIFVuaXZlcnNpdHkgYW5kIE1EIGZyb20gSGFydmFyZCBVbml2ZXJzaXR5LiA8YnI+ICAgDQoqV2hhdCBpcyBTdGF0aXN0aWNzKiBpcyBqdXN0IG9uZSBmcm9tIHRoZSAqKkFnYWluc3QgQWxsIE9kZHM6IEluc2lkZSBTdGF0aXN0aWNzKiogDQpzZXJpZXMgb2YgdmlkZW9zLCBhbGwgb2Ygd2hpY2ggYXJlIHNob3J0LCBleGNlbGxlbnQgYW5kIHdpdGggdHJhbnNjcmlwdHMgDQphdmFpbGFibGUgYXMgLnBkZiBkb3dubG9hZHMuIDxicj4gICANCg0KDQpodHRwczovL3d3dy5zYWJldGlsYWIub3JnL3BhcmRpc3NhYmV0aS8gJm5ic3A7ICZuYnNwOyAtLSBIZXIgbGFiJ3Mgd2Vic2l0ZQ0KDQpodHRwczovL3d3dy5oc3BoLmhhcnZhcmQuZWR1L3BhcmRpcy1zYWJldGkvICZuYnNwOyAtLSBQcm9mZXNzb3IgU2FiZXRpLCBIYXJ2YXJkIFQuSC4gDQpDaGFuIFNjaG9vbCBvZiBQdWJsaWMgSGVhbHRoIA0KDQpodHRwczovL29lYi5oYXJ2YXJkLmVkdS9wZW9wbGUvcGFyZGlzLXNhYmV0aSAmbmJzcDsgLS0gUHJvZmVzc29yIFNhYmV0aSwgDQpIYXJ2YXJkIERlcGFydC4gT3JnYW5pc21pYyAmIEV2b2x1dGlvbmFyeSBCaW9sb2d5DQoNCmh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BhcmRpc19TYWJldGkgICZuYnNwOyAtLSBXaWtpcGVkaWENCg0KaHR0cHM6Ly93d3cuaHVwLmhhcnZhcmQuZWR1L2NhdGFsb2cucGhwP2lzYm49OTc4MDY3NDI2MDQ3NCZjb250ZW50PXRvYyAtLSBoZXIgMjAyMSANCmJvb2s6IDxicj4gT1VUQlJFQUsgQ1VMVFVSRSAtLSBUaGUgRWJvbGEgQ3Jpc2lzIGFuZCB0aGUgbmV4dCBlcGlkZW1pYw0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI0MCUiLCBmaWcuYWxpZ249InJpZ2h0In0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0NCiAgICAgICAgICAgICAgICAgICJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9wYXJkaXMtc2FiZXRpMS5qcGciKQ0KYGBgDQoNCkZyZWUgZG93bmxvYWQ6IGh0dHBzOi8vZ2V0LmFkb2JlLmNvbS9yZWFkZXIvIGJ1dCBJIHN1Z2dlc3Qgbm90IHNlbGVjdGluZyBhbnkgb2YgdGhlIG90aGVyIOKAmGZyZWXigJkgb2ZmZXJzIGluIHRoZSBkaWFsb2cgYm94Lg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KPiBWaWRlb3MgYnkgdGhlIEFtZXJpY2FuIFN0YXRpc3RpY2FsIEFzc29jaWF0aW9uDQoNCmh0dHBzOi8vd3d3LmFtc3RhdC5vcmcvICZlbXNwOyZuYnNwOyAoQVNBIFN0dWRlbnQgbWVtYmVyc2hpcCBpcyBvbmx5ICQyNSBwZXIgeWVhcikgPGJyPiANCg0KKiBXaHkgWW91IE5lZWQgdG8gU3R1ZHkgU3RhdGlzdGljcy4gMyBtaW51dGVzICZuYnNwOyBodHRwczovL3lvdXR1LmJlL3dWMEtzN2FTN1lJDQoNCiogVGhpcyBpcyBTdGF0aXN0aWNzOiBHZW5ldmVyYSBBbGxlbi4gMTo0MSBtaW51dGVzICZuYnNwOyBodHRwczovL3lvdXR1LmJlL3hVUmtUS3REcV9NDQoNCiogVGhpcyBpcyBTdGF0aXN0aWNzOiBDaGFuZHJhIEVyZG1hbi4gMTo0MCBtaW51dGVzICZuYnNwOyBodHRwczovL3lvdXR1LmJlL3VzczdNWGNwSGFRDQoNCiogVGhpcyBpcyBTdGF0aXN0aWNzOiBSb2dlciBQZW5nLiAxOjUwIG1pbnV0ZXMgJm5ic3A7IGh0dHBzOi8veW91dHUuYmUvV01EQVIyYlpFcDANCg0KKiBTdGF0aXN0aWNpYW5zIE1ha2luZyBhIERpZmZlcmVuY2UuIDM6MDggbWludXRlcyAmbmJzcDsgaHR0cHM6Ly95b3V0dS5iZS9fRW5vVHZueDJnUQ0KDQoqIExpbmtlZEluIERhdGEgU2NpZW50aXN0IFRhbGtzIFN0YXRpc3RpY3MuIDE6NTEgbWludXRlcyAmbmJzcDsgaHR0cHM6Ly95b3V0dS5iZS9qZjJZWVRMLXdZRQ0KDQoqIERyLiBTdWRpcHRhIFJveSAtLSBXaHkgc3RhdGlzdGljcyBtYXR0ZXIgZm9yIGV2ZXJ5b25lLiAwOjMwIG1pbnV0ZXMgDQombmJzcDsgaHR0cHM6Ly95b3V0dS5iZS9VS2dZTklIdG1ONA0KDQoqIFN0YXRpc3RpY2lhbnMgaW4gT3RoZXIgRmllbGRzLiAzOjA4IG1pbnV0ZXMgJm5ic3A7IGh0dHBzOi8veW91dHUuYmUvTnFuZ2JzUzBpS1kNCg0KKiBXb3JsZCBTdGF0aXN0aWNzIERheTogU3RhdGlzdGljcyBBbGwgQXJvdW5kIFVzLiBieSBVLlMuIENlbnN1cyBCdXJlYXUuIDU6MzkgbWludXRlcw0KJm5ic3A7IGh0dHBzOi8veW91dHUuYmUvcGlTQ2trU3ZvTW8NCg0KPGJyPiANCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iMzAlIiwgZmlnLmFsaWduPSJkZWZhdWx0IiwgZmlnLnNob3c9ImhvbGQifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9jaGFuZHJhLWVyZG1hbjEuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL05hdGFsaWUtUm90ZWxsaS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvZ2VuZXZlcmEtYWxsZW4xLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9yb2dlci1wZW5nMS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvZGVlcGFrLWt1bWFyMS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvZG9taW5pcXVlLXdpbGxpYW1zMS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvbWVnYW4tcHJpY2UxLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9NZWdhblByaWNlMS5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvc3VkaXB0YS1yb3kxLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9jYXJsLWJpYWxpazEuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL3NhbWFudGhhLWxlZS1taW5nLWNoaXUxLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9kYW5uaWEtZ3V6bWFuMS5qcGciKQ0KDQpgYGANCjxicj48YnI+IFNvbWUgU3BlYWtlcnMgaW4gdGhlIGFib3ZlLCAqQW1lcmljYW4gU3RhdGlzdGljYWwgQXNzb2NpYXRpb24qIChBU0EpIHZpZGVvcy4gDQoNCjxwIGlkPSJibGFja2xpbmUiPiBfX19fX19fX19fX19fX19fX18gPC9wPiA8YnI+ICAgICAgICA8IS0tIGJsYWNrIGxpbmUgLS0+IA0KDQoNCg0KPiBEci4gVGFsaXRoaWEgV2lsbGlhbXMNCg0KaHR0cHM6Ly93d3cuaG1jLmVkdS9tYXRoZW1hdGljcy9wZW9wbGUvZmFjdWx0eS90YWxpdGhpYS13aWxsaWFtcy8gLS0gUHJvZmVzc29yIFdpbGxpYW1zLCBIYXJ2ZXktTXVkZCBDb2xsZWdlLCBDQQ0KDQpodHRwczovL3d3dy50YWxpdGhpYXdpbGxpYW1zLmNvbS8gLS0gUHJvZmVzc29yIFdpbGxpYW1zIHdlYiBwYWdlDQoNCmh0dHBzOi8vd3d3LnRhbGl0aGlhd2lsbGlhbXMuY29tL2Jvb2sgLS0gSGVyIGxhdGVzdCBib29rOiAmbmJzcDsNCipQb3dlciBpbiBOdW1iZXJzLCBUaGUgUmViZWwgV29tZW4gb2YgTWF0aGVtYXRpY3MqDQoNCmh0dHBzOi8vd3d3LnRoZWdyZWF0Y291cnNlcy5jb20vdGFsaXRoaWF3aWxsaWFtcyAtLSAqTGVhcm5pbmcgU3RhdGlzdGljczogQ29uY2VwdHMgDQphbmQgQXBwbGljYXRpb25zIGluIFIqICwgMjQgdmlkZW9zLCAkNDANCg0KPGJyPiANCjxwPioqKk93biBZb3VyIEJvZHkncyBEYXRhKioqIC0tIDE3IG1pbnV0ZSBURUQgdGFsaywgRmVicnVhcnkgMjAxNDwvcD4gDQpodHRwczovL3lvdXR1LmJlL1REQ1lKM19neDJ3DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjQwJSIsIGZpZy5hbGlnbj0iY2VudGVyIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0NCiAgICAgICAgICAgICAgICAgICJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi90YWxpdGhpYS13aWxsaWFtczEuanBnIikNCmBgYA0KDQoNCg0KPHAgaWQ9ImJsYWNrbGluZSI+IF9fX19fX19fX19fX19fX19fXyA8L3A+IDxicj4gICAgICAgIDwhLS0gYmxhY2sgbGluZSAtLT4gDQoNCg0KPiBEci4gSGFucyBSb3NsaW5nICgxOTQ4IC0gMjAxNykNCg0KSGUgaW52ZW50ZWQgImJ1YmJsZSBncmFwaHMiIHdoaWNoIGFyZSAyRCBzY2F0dGVycGxvdHMgdGhhdCBkaXNwbGF5IDUgdmFyaWFibGVzLiANCkhlIHdhcyBQcm9mZXNzb3Igb2YgSW50ZXJuYXRpb25hbCBIZWFsdGggYXQgS2Fyb2xpbnNrYSBJbnN0aXR1dGUsIFN3ZWRlbi4gDQoNCmh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0hhbnNfUm9zbGluZyAtLSBXaWtpcGVkaWEgYmlvZ3JhcGh5DQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduPSJjZW50ZXIifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPQ0KICAgICAgICAgICAgICAgICAgIkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL2hhbnMtcm9zbGluZzEuanBnIikNCmBgYA0KDQoNCiogSEFOUyBST1NMSU5HLCAyMDAgQ291bnRyaWVzLCAyMDAgWWVhcnMsIDQgTWludXRlcy4gNDo0NyBtaW51dGVzICZuYnNwOyANCmh0dHBzOi8veW91dHUuYmUvamJrU1JMWVNvam8NCg0KKiBGbG9yZW5jZSBOaWdodGluZ2FsZTogSm95IG9mIFN0YXRzLiAzOjQyIG1pbnV0ZXMgJm5ic3A7IA0KaHR0cHM6Ly95b3V0dS5iZS95aFgwT1IxX1ZmYw0KDQoqIEF2ZXJhZ2VzOiBKb3kgb2YgU3RhdHMuIDM6MTcgbWludXRlcyAmbmJzcDsgDQpodHRwczovL3lvdXR1LmJlL2hVR1VXci1UalI4DQoNCiogQ3JpbWUgU3BvdHRpbmc6IEpveSBvZiBTdGF0cy4gNDo1OCBtaW51dGVzICZuYnNwOyANCmh0dHBzOi8veW91dHUuYmUvZW4yaXg5ZjhjZU0NCg0KKiBDb3JyZWxhdGlvbjogSm95IG9mIFN0YXRzLiAzOjM4IG1pbnV0ZXMgJm5ic3A7IA0KaHR0cHM6Ly95b3V0dS5iZS82UnpETUVXNW9tYw0KDQoqIEF1dG9tYXRpYyB0cmFuc2xhdGlvbjogSm95IG9mIFN0YXRzLiA0OjA5IG1pbnV0ZXMgJm5ic3A7IA0KaHR0cHM6Ly95b3V0dS5iZS9BRWFjLWpQNUVobw0KDQoNCjxwIGlkPSJibGFja2xpbmUiPiBfX19fX19fX19fX19fX19fX18gPC9wPiA8YnI+ICAgICAgICA8IS0tIGJsYWNrIGxpbmUgLS0+IA0KDQo+IFZpZGVvIGZyb20gVGhlIEJCQyBhbmQgVGhlIE9wZW4gVW5pdmVyc2l0eQ0KDQpXaGVuIGNhbiB5b3UgdHJ1c3Qgc3RhdGlzdGljcz8gVGhlIG1vZGVybiB3b3JsZCBpcyBsaXR0ZXJlZCB3aXRoIHN0YXRpc3RpY2FsIG5vaXNlLiANCkhlcmUncyBob3cgdG8gZmluZCB0aGUgc2lnbmFsLiA0OjUwIG1pbnV0ZXMgIA0KaHR0cHM6Ly95b3V0dS5iZS9hUGgzRThJb0h6aw0KPGJyPjxicj4NClRoaXMgdmlkZW8gZG9lcyBub3QgZGVhbCB3aXRoICoqU3RhdGlzdGljcyoqIGZyb20gYSBzY2llbnRpZmljIHBvaW50IG9mIHZpZXcuIA0KUmF0aGVyLCBpdCBleGFtaW5lcyBob3cgd2UgYXMgaW5kaXZpZHVhbHMgaW4gZXZlcnlkYXkgbGlmZSwgbWF5IHZpZXcgYW5kIGludGVycHJldCANCioqU3RhdGlzdGljcyoqIGFzIHJlcG9ydGVkIGluIHRoZSBtZWRpYSBhY3Jvc3MgYWxsIHRvcGljcywgZS5nLiwgc29jaW8tZWNvbm9taWMsIA0KcG9saXRpY2FsLiBUaGV5IHByb21vdGU6ICZuYnNwOyBiZSAqKkNhbG0qKiBhbmQgYmUgd2FyeSBvZiB5b3VyICoqRW1vdGlvbnMqKiwgZ2V0IA0KKipDb250ZXh0KiosIGJlICoqQ3VyaW91cyoqIGFuZCBjb25zaWRlciB0aGUgKipTb3VyY2UqKiBvZiB0aGUgKipEYXRhKiogYW5kIG9mIHRoZSANCioqU3RhdGlzdGljcyoqLiBUaGlzIGFkdmljZSBhbHNvIG1ha2VzIGdvb2Qgc2Vuc2UgZm9yIHJlc2VhcmNoZXJzIG9uIHRoZSBiZW5jaCwgDQpkZWFsaW5nIHdpdGggdGhlaXIgb3duIGRhdGEgYW5kIHN0YXRpc3RpY3MuIA0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQo8YnI+ICANCg0KIyAmbmJzcDsgQ291cnNlIHVuaXRzICAgICAgICAgIDwhLS0gIC4uLi4uLiA4dGggc2VjdGlvbiBvZiBkb2N1bWVudCAuLi4uLi4gIC0tPg0KDQo8YnI+ICANCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjIyIj4NCjEuICoqR2V0dGluZyBzdGFydGVkIGluIGJhc2UgUiB3aXRoIGNvZGluZywgZGF0YSBhbmQgZ3JhcGhzKiouIERvd25sb2FkIGxhdGVzdCB2ZXJzaW9uIA0Kb2YgUiAoaHR0cHM6Ly93d3cuci1wcm9qZWN0Lm9yZyk7IEkgd2lsbCBkZW1vbnN0cmF0ZS4gSSB3aWxsIGFsc28gZGVtb25zdHJhdGUgaG93IHRvIA0KaW5zdGFsbCBzb21lIG9mIHRoZSAqKnBhY2thZ2VzKiogYmV5b25kIGJhc2UgUiwgdGhhdCB3ZSB3aWxsIHVzZSBpbiBjbGFzcywgZS5nLiwgSVN3UiwgDQpwc3ljaCwgcHdyLCBEQUFHLCBEZXNjVG9vbHMsIGVsbGlwc2UsIGdwbG90cywgaGV4YmluLCBsYXR0aWNlLCBNQVNTLCBNVk4uIDxicj48YnI+IA0KTGVhcm4gaW50ZXJhY3RpdmUgdXNlIG9mIFIgQ29uc29sZSwgdGhlIFIgRWRpdG9yIGFuZCBHcmFwaGljcyBXaW5kb3cuIExlYXJuIHRvIGNhbGwgDQpmdW5jdGlvbnMuIENyZWF0ZSA8bWFyaz4gYGZvby5SYCA8L21hcms+IFIgRWRpdG9yIGZpbGVzIGFuZCA8bWFyaz5gZm9vLnBkZmA8L21hcms+IA0KZ3JhcGggZmlsZXMuIENyZWF0ZSB3ZWxsIHN0cnVjdHVyZWQsIHJlYWRhYmxlLCBSIEVkaXRvciBmaWxlcyAoUiBwcm9ncmFtcykgd2l0aCANCmNvbW1lbnRzLCBzcGFjaW5nLCBpbmRlbnRhdGlvbiwgYW5kIHRoZSAqd2lzZSBuYW1pbmcqIG9mIHZhcmlhYmxlcyBhbmQgb2JqZWN0cy4gDQpTdG9yZSBkYXRhIGluIFIgRWRpdG9yIGZpbGVzIGFzIHZlY3RvcnMgYW5kIGRhdGEgZnJhbWVzLiANCjxicj4gKipHcmFwaHM6Kiogc2ltcGxlIGxpbmUgZ3JhcGhzLCBwb2ludCBhbmQgbGluZSBncmFwaHMsIHNjYXR0ZXIgcGxvdHMsIHRleHQgDQphbm5vdGF0aW9uIG9mIGdyYXBocy4gQWRkIHlvdXIgcGVyc29uYWwgdGltZSBzdGFtcCB0byBncmFwaHMuIFdlIGJlZ2luIHRoZSBjb3Vyc2UgDQp3aXRoIHNtYWxsICp4LCB5KiBkYXRhIHNldHMgdGhhdCBhcmUgZWFzeSB0byB1bmRlcnN0YW5kLiA8YnI+ICANCkFjcm9zcyBCaW8gMjQwIHdlIGNyZWF0ZSAmbmJzcDsgKjMgdHlwZXMgb2YgZ3JhcGhzKiAqKjoqKiA8YnI+IA0KKiAqKmRyYWZ0IHF1YWxpdHkqKiA8YnI+DQoqICoqcHJlc2VudGF0aW9uIHF1YWxpdHkqKjxicj4NCiogKipwdWJsaWNhdGlvbiBxdWFsaXR5KiogPGJyPjxicj4gDQpTd2l0Y2hpbmcgYmV0d2VlbiB0aGVzZSBncmFwaCB0eXBlcyBpcyBieSB0aGUgKmV4dHJlbWVseSBpbXBvcnRhbnQqIGFuZCANCipzdGFuZGFyZCBwcmFjdGljZSogKio6KiogPGJyPiB0byAqKmNvbW1lbnQgaW4qKiBhbmQgdG8gKipjb21tZW50IG91dCoqIA0KbGluZXMgb2YgY29kZSwgYXMgd2Ugc3VibWl0IGNvZGUgY2h1bmtzIGFuZCBjYWxsIFIgZnVuY3Rpb25zLiANCg0KKioqDQoyLiAqKlVuaXZhcmlhdGUgZGF0YSwgZGVzY3JpcHRpdmUgc3RhdGlzdGljcywgY29uZmlkZW5jZSBpbnRlcnZhbHMqKi4gRGF0YSANCnZpc3VhbGl6YXRpb24sIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MsIG5vcm1hbCBkaXN0cmlidXRpb24sIGNlbnRyYWwgbGltaXQgdGhlb3JlbSwgDQpjb25maWRlbmNlIGludGVydmFscyAodHJhZGl0aW9uYWwgJiBib290c3RyYXApLCBNb250ZSBDYXJsbyBkYXRhIHNpbXVsYXRpb24uIA0KUmVhZC93cml0ZSA8bWFyaz4uY3N2PC9tYXJrPiBmaWxlcy4gDQo8YnI+KipHcmFwaHMqKjogaGlzdG9ncmFtcywga2VybmVsIA0KZGVuc2l0eSBlc3RpbWF0ZXMsIGhpc3RvZ3JhbSB3aXRoIG5vcm1hbCBmaXQsIHRleHQgYW5ub3RhdGlvbiBvZiBncmFwaHMsIA0KRURBIGdyYXBocy4NCg0KKioqDQozLiAqKk9uZS13YXkgZGF0YTogQW5vdmEgJiByZWxhdGVkIHRvcGljcyoqLiAgQXNzZXNzIEFub3ZhIGFzc3VtcHRpb25zOyBlZmZlY3Qgc2l6ZXMgDQooUi1zcXVhcmUsIFZhcmlhbmNlIENvbXBvbmVudHMsIENvaGVuJ3MgRCk7IENvbmZpZGVuY2UgSW50ZXJ2YWxzOyB0LXRlc3RzOyBzdGF0aXN0aWNhbCANCnBvd2VyIGFuYWx5c2lzICh0cmFkaXRpb25hbCBhbmQgYm9vdHN0cmFwKTsgbXVsdGlwbGUgY29tcGFyaXNvbnMgZm9sbG93aW5nIGEgDQpzaWduaWZpY2FudCBBbm92YSAocGxhbm5lZCwgVHVrZXkgSFNELCBEdW5uZXR0J3MgdGVzdCwgSG9sbS1Cb25mZXJyb25pIG1ldGhvZCk7IA0Kbm9ucGFyYW1ldHJpYyBib290c3RyYXAgQ29uZmlkZW5jZSBJbnRlcnZhbHMgZXZhbHVhdGVkIGJ5IHBlcmNlbnRpbGUgbWV0aG9kIGFuZCBCQ0E7IA0KcGVybXV0YXRpb24gQW5vdmE7IEtydXNrYWwtV2FsbGlzIHRlc3Q7IFdpbGNveG9uIHRlc3Q7IEJheWVzIEZhY3RvciBBbm92YTsgTW9udGUgDQpDYXJsbyBkYXRhIHNpbXVsYXRpb24uIFNhdmUvbG9hZCBuYXRpdmUgUiBiaW5hcnkgb2JqZWN0cy4NCjxicj4qKkdyYXBocyoqOiBib3hwbG90cywgbWVhbnMgd2l0aCBlcnJvciBiYXJzIChTRCwgU0VNLCBDSSksIA0KRURBIGdyYXBocy4NCg0KKioqDQo0LiAqKkNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgbWV0aG9kcyoqLiBSIGNvZGUgZm9yIHBlcm11dGF0aW9uIHRlc3RzLCANCm5vbnBhcmFtZXRyaWMgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBib290c3RyYXAgcG93ZXIgY3VydmVzLCBNb250ZSBDYXJsbyANCmRhdGEgc2ltdWxhdGlvbiAoaHlwb3RoZXNpcyB0ZXN0aW5nICYgbGVhcm5pbmcpLCBCYXllcyBGYWN0b3IgDQooQW5vdmEsIGNvcnJlbGF0aW9uLCByZWdyZXNzaW9uKS4gQ29kZSBiZW5jaG1hcmtpbmcgZm9yIHNwZWVkLiBQYXJhbGxlbCBtdWx0aWNvcmUgDQpjb21wdXRhdGlvbi4gDQo8YnI+KipHcmFwaHMqKjogdmlzdWFsaXphdGlvbiBvZiB0aGUgcmUvc2FtcGxpbmcgcHJvY2VzcywgcGVyZm9ybWFuY2UgYW5kIA0KcmVzdWx0cyBvZiBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIG1ldGhvZHMuIA0KDQoqKioNCjUuICoqQ29ycmVsYXRpb24qKi4gUGFyYW1ldHJpYywgbm9ucGFyYW1ldHJpYywgYXNzdW1wdGlvbnMsIHN0YXRpc3RpY2FsIHBvd2VyLCANCmJvb3RzdHJhcCwgcGVybXV0YXRpb24sIGRhdGEgc2ltdWxhdGlvbiwgQmF5ZXNpYW4gYXBwcm9hY2hlcywgZGlzdGFuY2UgKGVuZXJneSkgDQpjb3JyZWxhdGlvbiwgb3V0bGllcnMsIGNsdXN0ZXJzLCBsZWF2ZS1vbmUtb3V0IGFuYWx5c2lzLg0KPGJyPioqR3JhcGhzKio6IHNjYXR0ZXJwbG90cyANCndpdGggY29uZmlkZW5jZSBlbGxpcHNlcywgd2l0aCBsb3dlc3MgZml0OyAyRCBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZXMgKEJheWVzaWFuIA0KYW5kIGVtcGlyaWNhbCk7IGhleGFnb25hbCBiaW5uaW5nLCAzRCBncmFwaHMsIEVEQS4gDQoNCioqKg0KNi4gKipEZW1vbnN0cmF0aW9ucyoqLiBNdWx0aXZhcmlhdGUgdmlzdWFsaXphdGlvbiAmIGFuYWx5c2lzOyBjb2RpbmcgZm9yIG1vZGFsIA0KZGlhbG9nIGJveGVzIGFuZCBmbG93IGNoYXJ0IGRpYWdyYW1zOyBjb2RlIGJlbmNoIG1hcmtpbmcgJiBwcm9maWxpbmc7IGdyYXBoIA0KYW5pbWF0aW9uIGJ5IEdJRjsgcGFyYWxsZWwgbXVsdGljb3JlICYgTlZJRElBIEdQVSBjb21wdXRpbmcuIE11bHRpcHVycG9zZSBNb250ZSBDYXJsbyANCmRhdGEgc2ltdWxhdGlvbiBmb3IgdGVhY2hpbmcgYW5kIHJlc2VhcmNoLiBTdHJhdGVnaWVzIGZvciBtZW1vcnkgYW5kIHBlcmZvcm1hbmNlIA0KKHRpbWUpIGlzc3VlcyBpbiBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIHByb2NlZHVyZXMgd2l0aCBiaWcgZGF0YSBvbiBzbWFsbCANCm1hY2hpbmVzLiBEZW1vbnN0cmF0aW9uIG9mIGxhdHRpY2UsIGdncGxvdDIsIHBsb3RseSBhbmQgb3RoZXIgZ3JhcGhpYyBzeXN0ZW1zIGJleW9uZCANCmJhc2UgUiBncmFwaGljcy4gUmVwcm9kdWNpYmxlIFJlc2VhcmNoIGRlbW9uc3RyYXRpb25zIHVzaW5nIFIgTWFya2Rvd24uDQoNCioqKg0KNy4gKipSZXByb2R1Y2libGUgcmVzZWFyY2ggdXNpbmcgUiBNYXJrZG93bioqLiBHZXR0aW5nIHN0YXJ0ZWQgaW4gbGl0ZXJhdGUgDQpwcm9ncmFtbWluZyB3aXRoIGludGVyYWN0aXZlIEhUTUwgZG9jdW1lbnRzICh3ZWIgYXBwcykgdGhhdCBjb21iaW5lIFIgY29kZSwgZGF0YSwgDQpyZXN1bHRzLCBncmFwaHMgYW5kIHByb3NlLiBJbmRlZWQsIHRoaXMgU3lsbGFidXMgaXMgYSBwbGFpbiB0ZXh0LCBSIG1hcmtkb3duIGZpbGUgDQooPG1hcms+LlJtZDwvbWFyaz4pIHRoYXQgd2FzIHJlbmRlcmVkIGludG8gYSBIVE1MIGZpbGUgYnkgTWFya2Rvd24sIEtuaXRyIGFuZCBQYW5kb2MuIA0KSSB3aWxsIGRlbW9uc3RyYXRlIHRoaXMgcHJvY2VzcyBpbiBjbGFzcywgYXMgdGltZSBhbGxvd3MuIFRoaXMgd2lsbCBiZSBvdXIgb25seSB1c2Ugb2YgDQoqKlJTdHVkaW8qKiAoaHR0cHM6Ly9yc3R1ZGlvLmNvbSkgdGhlIHBvcHVsYXIgYW5kIHBvd2VyZnVsLCB5ZXQgb3Zlcmx5IGNvbXBsaWNhdGVkLCANCioqSURFKiogKCoqSSoqbnRlZ3JhdGVkICoqRCoqZXZlbG9wbWVudCAqKkUqKm52aXJvbm1lbnQpIHRoYXQgaGFuZGxlcyBsYW5ndWFnZXMgDQppbmNsdWRpbmcgUiwgUHl0aG9uLCBIVE1MLCBDU1MsIEMrKywgSmF2YVNjcmlwdCwgTGFUZXgsIGFuZCBtb3JlLiBSU3R1ZGlvIHByb21vdGVzIGEgDQpkaWFsZWN0IG9mIFIgKHRoZSB0aWR5dmVyc2UpIHdoaWxlIG15IG1pc3Npb24gaW4gQmlvIDI0MCBpcyB0byBnZXQgeW91IHN0YXJ0ZWQgDQppbiBiYXNlIFIuIA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gDQoqKlRoaXMgSFRNTCBzeWxsYWJ1cyBmaWxlKiogcnVucyBvbiBhbnkgd2ViIGJyb3dzZXIgb24gYW55IG9wZXJhdGluZyBzeXN0ZW0gYW5kIA0KZG9lcyBub3QgcmVxdWlyZSBSIHRvIGJlIGluc3RhbGxlZCBvbiB0aGUgY29tcHV0ZXIgaW4gcXVlc3Rpb24uIEkgcmVhbGl6ZSBhbGwgdGhpcyANCnNvdW5kcyBjb21wbGljYXRlZCBidXQgaXQncyB0aGUgd2F2ZSBvZiB0aGUgZnV0dXJlIGFuZCBJIGNhbiBnZXQgeW91IHN0YXJ0ZWQgb24gdGhpcyANCioqT3B0aW9uYWwqKiBtYXRlcmlhbCwgYnkgcHJvdmlkaW5nIHRlbXBsYXRlcyBhbmQgZGVtb25zdHJhdGlvbnMuIA0KDQoqKioNCg0KPC9kaXY+DQo8YnI+PGJyPiAgDQoNCjwhLS0gcHV0IGxvZ29zIGJlbG93IHRleHQgLS0+IA0KDQo8aDM+SW5jcmVhc2luZ2x5LCBSIGFuZCBpdHMgbGFyZ2VyIGVudmlyb25tZW50LCBpbnRlcmFjdCB3ZWxsIHdpdGggb3RoZXIgDQpwcm9ncmFtbWluZyBsYW5ndWFnZXMgKGUuZy4sIEMrKywgUHl0aG9uLCBKdWxpYSwgU1FMKSwgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMgDQooZS5nLiwgUlN0dWRpbywgQW1hem9uIEFXUykgYW5kIGdyYXBoaWNhbCBzeXN0ZW1zIChlLmcuLCBKYXZhU2NyaXB0KS48L2gzPjxicj4NCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iOSUiLCBmaWcuYWxpZ249ImRlZmF1bHQiLCBmaWcuc2hvdz0iaG9sZCJ9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvYi5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9oZXhfcm1hcmtkb3duLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL2tuaXRyLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9NdXJyZWxsIDNyZC5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUyBGYWxsIDIwMjIvbGF0dGljZS5qcGciKQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL2dncGxvdDIucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvc2hpbnkucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvYm9va2Rvd24ucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvYmxvZ2Rvd24ucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvSFRNTDVfbG9nby5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9DU1MucG5nIikNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvamF2YXNjcmlwdC1sb2dvLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9SU3R1ZGlvLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9SU1MucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL2JpZy1kYXRhMS5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvU1FMLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9ib290c3RyYXAyLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9wZXJtdXRhdGlvbjEucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL3JlZ3Jlc3Npb24xLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9iYXllc2lhbjEuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL21hY2hpbmUtbGVhcm5pbmcxLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9BSS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvc3RhdDEuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL2Jpb3N0YXQxLmpwZyIpDQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvamF2YXNjcmlwdC5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9qc29uLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL0xhdGV4LnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTIEZhbGwgMjAyMi9LbnV0aCAxLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTIEZhbGwgMjAyMi9LbnV0aCAzLnBuZyIpDQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvQysrLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL2p1bGlhLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL3B5dGhvbi5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9Ud2l0dGVyLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL1BERi5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9wYW5kb2MucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvSGFza2VsbDIucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvd29yZDEucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvcG93ZXJwb2ludDIucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvcG5hcy5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9uYXR1cmUuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvQVNBLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL0FBQVMucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvc2NpZW5jZS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9KQU1BLnN2ZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL05FSk0ucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvQy5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9mb3J0cmFuLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL0dpdEh1Yi5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9mb3NzLmpwZWciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9MaWJyZU9mZmljZS5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9hbm92YS5qcGciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9jb3JyZWxhdGlvbi5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9oaXN0b2dyYW0ucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvYm94cGxvdC5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9zY2F0dGVycGxvdDMucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvQmF5ZXNGYWN0b3IucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvdWJ1bnR1LnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL01hYy5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9XaW4yLnBuZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTL25vdGVwYWQrKy5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9SUHVicyBsb2dvLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTIEZhbGwgMjAyMi9DaGFtYmVycyAxLmpwZyIpDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1NZTExBQlVTIEZhbGwgMjAyMi9hd3NfbG9nb19zbWlsZV8xMjAweDYzMC5wbmciKQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUyBGYWxsIDIwMjIvU1FMX2xvZ28ucG5nIikNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9SbG9nby5zdmciKQ0KDQpgYGAgDQoNCg0KPCEtLSAgICFbbXkuY2FwdGlvbl0oQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9SbG9nby5zdmcpICAtLT4gDQoNCjxicj4gIA0KDQo8IS0tIEluc2VydCByYXcgSFRNTCBjb2RlIC0tPg0KDQo8IS0tIDxwIHN0eWxlPSJmb250LWZhbWlseTogJ2NvdXJpZXIgbmV3JzsgZm9udC1zaXplOiA2MHB0OyBmb250LXdlaWdodDogYm9sZDsgDQogICAgICAgICAgY29sb3I6IGJsdWU7IGJhY2tncm91bmQtY29sb3I6IHdoaXRlOyBwYWRkaW5nOiAyMHB4Ow0KICAgICAgICAgIHRleHQtYWxpZ246IGxlZnQ7IHRleHQtaW5kZW50OiAwcHg7IA0KICAgICAgICAgIHRleHQtc2hhZG93OiA0cHggMnB4IDJweCBncmF5OyI+DQogICAgICAgICAgUiA8YnI+ZGF0YTxicj5ncmFwaHM8YnI+c3RhdGlzdGljczwvcD48YnI+PGJyPiAgLS0+IA0KDQo8IS0tIDxwIHN0eWxlPSJmb250LWZhbWlseTogJ2NvdXJpZXIgbmV3JzsgZm9udC1zaXplOiA1N3B0OyBmb250LXdlaWdodDogYm9sZDsgDQogICAgICAgICAgY29sb3I6IGJsdWU7IGJhY2tncm91bmQtY29sb3I6IHdoaXRlOyBwYWRkaW5nOiAyMHB4Ow0KICAgICAgICAgIHRleHQtYWxpZ246IGxlZnQ7IHRleHQtaW5kZW50OiAwcHg7IA0KICAgICAgICAgIHRleHQtc2hhZG93OiA0cHggMnB4IDJweCBncmF5OyI+DQogICAgICAgICAgUiA8YnI+ZGF0YTxicj5ncmFwaHM8YnI+c3RhdGlzdGljczxicj53cml0aW5nIHRoZSByZXN1bHRzPC9wPjxicj48YnI+ICAtLT4gDQoNCjxicj4gDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCjxicj4gDQoNCg0KDQojICZuYnNwOyBMZWFybmluZyBnb2FscyAgICAgICA8IS0tICAuLi4uLi4gOXRoIHNlY3Rpb24gb2YgZG9jdW1lbnQgLi4uLi4uICAtLT4NCg0KPHAgc3R5bGU9ImZvbnQtZmFtaWx5OiAnY291cmllciBuZXcnOyBmb250LXNpemU6IDMwcHQ7IGZvbnQtd2VpZ2h0OiBib2xkOyANCiAgICAgICAgICBjb2xvcjogYmx1ZTsgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IHBhZGRpbmc6IDIwcHg7DQogICAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyOyB0ZXh0LWluZGVudDogMHB4OyANCiAgICAgICAgICB0ZXh0LXNoYWRvdzogM3B4IDFweCAxcHggZ3JheTsiPg0KICAgICAgICAgIFI8YnI+ZGF0YTxicj5ncmFwaHM8YnI+c3RhdGlzdGljczxicj53cml0aW5nIGFib3V0IHRoZSByZXN1bHRzPC9wPiANCg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMjMiPiANCjEuIERhdGEtZHJpdmVuIGFiaWxpdHkgdG8gdXNlIHN0YXRpc3RpY2FsIHJlYXNvbmluZyBpbiBCaW9sb2d5IGJ5IGNvbXB1dGVyIA0KcHJvZ3JhbW1pbmcgaW4gUi4gIA0KDQoyLiBTdG9yZSwgZWRpdCBhbmQgbWFuaXB1bGF0ZSBkYXRhIGluIHN0YW5kYXJkIGZvcm1hdHMgYW5kIHZpc3VhbGl6ZSBpbiBwdWJsaWNhdGlvbiANCnF1YWxpdHkgZ3JhcGhzIHVzaW5nIFIuIFJlYWQgYW5kIHdyaXRlLCBzdGFuZGFyZCA8bWFyaz4gLmNzdiA8L21hcms+IGZpbGVzIG9mIA0Kcm93LWJ5LWNvbHVtbiBkYXRhLiAgDQoNCjMuIFBlcmZvcm0gc3RhdGlzdGljYWwgYW5hbHlzaXMgKHRyYWRpdGlvbmFsLCBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlLCBCYXllc2lhbikgDQphbmQgZXhwcmVzcyByZXN1bHRzIGFzIHRhYmxlcywgZ3JhcGhzIGFuZCB3cml0aW5nIGFwcHJvcHJpYXRlIGZvciBzY2llbnRpZmljIA0Kam91cm5hbHMuIA0KDQo0LiBBYmlsaXR5IHRvIGNhbGwgUiBmdW5jdGlvbnMsIGRlYWwgd2l0aCBmdW5jdGlvbiBhcmd1bWVudHMgYW5kIGludGVyYWN0IHdpdGggdGhlIA0Kb2JqZWN0cyByZXR1cm5lZCBieSBmdW5jdGlvbnMuIENyZWF0ZSwgZGVidWcgYW5kIHJ1biwgd2VsbC1zdHJ1Y3R1cmVkIGFuZCByZWFkYWJsZSwgDQpSIEVkaXRvciBmaWxlcyAoPG1hcms+IC5SIDwvbWFyaz4gLCAmbmJzcDsgaS5lLiwgUiBwcm9ncmFtcykuICoqT3B0aW9uYWwgOioqIENyZWF0ZSANCm5ldyBSIGZ1bmN0aW9ucyBhcyBjb252ZW5pZW5jZSB3cmFwcGVycyBmb3IgZXh0YW50IGZ1bmN0aW9ucyBpbiBSOyBjcmVhdGUgbmV3IFIgDQpmdW5jdGlvbnMgZm9yIG5ldyB0YXNrcy4gDQo8YnI+ICANCjUuIFdyaXRlIGNyaXRpY2FsLCBzdGF0aXN0aWNhbCByZXZpZXdzIG9mIHNjaWVudGlmaWMgam91cm5hbCBwYXBlcnMgcmVsYXRpdmUgdG8gDQp0YWJsZXMgb2Ygc3RhdGlzdGljcywgZ3JhcGhzIGFuZCB0aGVpciBsZWdlbmRzLiANCg0KNi4gKipPcHRpb25hbCoqOiBFbnRyeSBsZXZlbCBhYmlsaXR5IGluICpyZXByb2R1Y2libGUgcmVzZWFyY2gqIHVzaW5nIFIgTWFya2Rvd24gDQp0byBtYWtlIHNtYWxsLCBIVE1MIGRvY3VtZW50cyB0aGF0IGNvbWJpbmUgUiBjb2RlLCBkYXRhLCByZXN1bHRzLCBncmFwaHMgDQphbmQgd3JpdGluZy4gUlN0dWRpbyBtYWtlcyB0aGlzIHByb2Nlc3MgdHJhY3RhYmxlLCBhbGJlaXQgd2l0aCBhIGxlYXJuaW5nIGN1cnZlLiBJIA0Kd2lsbCBkZW1vbnN0cmF0ZSBpbiBjbGFzcyBhbmQgcHJvdmlkZSB0ZW1wbGF0ZXMuIFRoaXMgaXMgb3VyIG9ubHkgdXNlIGZvciBSU3R1ZGlvLiANCkZvciBldmVyeXRoaW5nIGVsc2UgaW4gQmlvIDI0MCwgd2UgdXNlIFIgKFIgQ29uc29sZSwgUiBFZGl0b3IsIFIgR3JhcGhpY3MgV2luZG93KSANCmJlY2F1c2UgSSB3YW50IHlvdSBjbG9zZSB0byB0aGUgbGFuZ3VhZ2UgaXRzZWxmLCBub3QgdG8gYSBjb21tZXJjaWFsIElERSANCnRoYXQgcHJvbW90ZXMgYSBkaWFsZWN0IG9mIFIuIA0KDQo8L2Rpdj4NCg0KPGJyPjxicj4gIA0KDQo+Pj4gPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5Oidjb21pYyBzYW5zIG1zJzsgZm9udC1zaXplOjIwMCUiPg0KJmVuc3A7ICoqQWZ0ZXIgZWFjaCBCaW9zdGF0aXN0aWNzIGNsYXNzIDxicj4NCiZlbnNwOyBhc2sgeW91cnNlbGYgdGhlc2UgMyBxdWVzdGlvbnMqKiA8L3NwYW4+IA0KDQoNCjxoND4gDQogIDxzcGFuIHN0eWxlPSdmb250LXNpemU6MjJwdDsnID4gDQogICZlbXNwOyZlbXNwOyZlbXNwOyZlbXNwOyZlbXNwOw0KICAmIzk2NTQ7IFdoYXQgaXMgdGhlIG1vc3QgaW1wb3J0YW50IHRoaW5nIHlvdXIgbGVhcm5lZD8gPC9zcGFuPiAgDQogIA0KICA8c3BhbiBzdHlsZT0nZm9udC1zaXplOjIycHQ7JyA+IA0KICAmZW1zcDsmZW1zcDsmZW1zcDsmZW1zcDsmZW1zcDsNCiAgJiM5NjU0OyBOYW1lIG9uZSB0aGluZyB5b3UgZGlkIG5vdCB1bmRlcnN0YW5kLiA8L3NwYW4+ICANCiAgDQogIDxzcGFuIHN0eWxlPSdmb250LXNpemU6MjJwdDsnID4gDQogICZlbXNwOyZlbXNwOyZlbXNwOyZlbXNwOyZlbXNwOw0KICAmIzk2NTQ7IFdoYXQgcXVlc3Rpb24gcmVtYWlucyBpbiB5b3VyIG1pbmQ/IDwvc3Bhbj4gIA0KPC9oND4NCg0KPHNwYW4gc3R5bGU9J2ZvbnQtc2l6ZTo1NXB4OyB0ZXh0LWFsaWduOnJpZ2h0OycgPiAmIzEyOTQwOTsgPC9zcGFuPiAgPCEtLSBsaW9uIC0tPg0KDQoNCjwhLS0gPHNwYW4gc3R5bGU9J2ZvbnQtc2l6ZTo1MHB4OyB0ZXh0LWFsaWduOnJpZ2h0OycgPiAmIzEyOTQwOTsgPC9zcGFuPiAgIGxpb24gIC0tPg0KPCEtLSA8c3BhbiBzdHlsZT0nZm9udC1zaXplOjUwcHg7IHRleHQtYWxpZ246cmlnaHQ7JyA+ICYjMTI4MDQ3OyA8L3NwYW4+ICAgdGlnZXIgLS0+DQo8IS0tIDxzcGFuIHN0eWxlPSdmb250LXNpemU6NTBweDsgdGV4dC1hbGlnbjpyaWdodDsnID4gJiMxMjgwNTQ7IDwvc3Bhbj4gICBkb2cgICAtLT4NCg0KPGJyPiA8YnI+IA0KDQojICZuYnNwOyBBY2FkZW1pYyBJbnRlZ3JpdHkgYW5kIERpc2FiaWxpdHkgU3RhdGVtZW50ICAgPCEtLSAuLi4gMTB0aCBzZWN0aW9uIC4uLiAtLT4NCg0KPGJyPg0KKipBY2FkZW1pYyBJbnRlZ3JpdHkgU3RhdGVtZW50IDoqKiAmbmJzcDsgTGVobWFuIENvbGxlZ2UgU2Nob29sIG9mIE5hdHVyYWwgYW5kIFNvY2lhbCANClNjaWVuY2VzLiBJIHdpbGwgZW1haWwgaXQgZm9yIHlvdSB0byBjb25zaWRlciBhbmQgb3B0aW9uYWxseSwgdG8gcmV0dXJuIGJ5IGVtYWlsIA0KdG8gbWUuIEl0IGlzIGEgZm9ybSBmaWxsIFBERiBmaWxlLjxicj48YnI+IA0KDQo+ICZlbXNwOyA8aT5SYXRoZXIgZmFpbCB3aXRoIGhvbm9yIHRoYW4gc3VjY2VlZCBieSBmcmF1ZDwvaT4gJm5ic3A7IC0tLSAmbmJzcDsgDQpTb3Bob2NsZXMgKGIuIDQ5NywgZC4gNDA2IEJDKQ0KDQo8cCBzdHlsZT0iY29sb3I6IGRhcmtibHVlOyBmb250LWZhbWlseTogQ291cmllciBOZXc7IGZvbnQtc2l6ZTogMTNwdDsiPiAgICAgDQpJbiAqKkJpbyAyNDAqKiB5b3UgYXJlIG9uIHlvdXIgcGVyc29uYWwgaG9ub3IgdG8gdGFrZSBUZXN0cyB3aXRob3V0IGNoZWF0aW5nLiANClRvIGNoZWF0IGlzIHRvIGdpdmUgb3IgdG8gcmVjZWl2ZSBhbnN3ZXJzIG9yIGhlbHAuIFRoZSB1c2Ugb2YgZ2VuZXJhdGl2ZSBBLkkuIGlzIA0KY2hlYXRpbmcuIENoZWF0aW5nIGlzIGltbW9yYWwsIGl0IGlzIGEgc2luLiBJdCBjYW4gZ2V0IHlvdSBleHBlbGxlZCBmcm9tIHRoZSBDb2xsZWdlLiANCkRvbid0IGRvIGl0LCBpdCdzIG5vdCB3b3J0aCB0aGUgY29uc2VxdWVuY2VzLjxicj4gDQoNCkNoZWF0aW5nIGRlc3Ryb3lzIGNhcmVlciBkZXZlbG9wbWVudC4gRm9yIGluc3RhbmNlLCBjaGVhdGluZyB2aXRpYXRlcyBsZXR0ZXJzIG9mIA0KcmVjb21tZW5kYXRpb24uIEZhY3VsdHkgbWF5IHJlZnVzZSB0byB3cml0ZSBhIGxldHRlciBvciBtYXkgd3JpdGUgYSANCm5lZ2F0aXZlIGxldHRlci48YnI+DQoNClJlbWVtYmVyLCBhIHJlY29tbWVuZGF0aW9uIGxldHRlciBmb3IgZ3JhZHVhdGUgc2Nob29sIG9yIHByb2Zlc3Npb25hbCBzY2hvb2wgaXMgDQpldmFsdWF0ZWQgc2V2ZXJhbCB3YXlzLCBpbmNsdWRpbmcgYXMgYSBjaGFyYWN0ZXIgIHJlZmVyZW5jZS4gQnkgZGVmaW5pdGlvbiwgYSANCmNoZWF0ZXIgaXMgYSBwZXJzb24gb2YgbG93IGNoYXJhY3RlciBhbmQgZ3JhZHVhdGUgc2Nob29scyBkbyBub3Qgd2FudCB0aGlzIGtpbmQgb2YgDQpwZXJzb24gaW4gdGhlaXIgcHJvZ3JhbSwgd2hldGhlciBNUywgUGhEIG9yIE1ELiA8YnI+IA0KDQo8Yj5Bc2sgeW91cnNlbGY8L2I+IDogRG8geW91IHdhbnQgeW91ciBjaGlsZCB0byBiZSB0cmVhdGVkIGJ5IGFuIE1EIG9yIA0KdGF1Z2h0IGJ5IGEgVGVhY2hlciwgd2hvIGNoZWF0ZWQgaGlzIG9yIGhlciB3YXkgdGhyb3VnaCBjb2xsZWdlLCBncmFkdWF0ZSBzY2hvb2wgDQphbmQgbWVkaWNhbCBzY2hvb2w/PGJyPjxicj4NCjwvcD4NCg0KPGJyPiANCioqU3R1ZGVudCBEaXNhYmlsaXR5IFN0YXRlbWVudCA6KiogJm5ic3A7ICIqTGVobWFuIENvbGxlZ2UgY29tbWl0cyB0byBwcm92aWRpbmcgYWNjZXNzIA0KdG8gcHJvZ3JhbXMgYW5kIGN1cnJpY3VsYSB0byBhbGwgc3R1ZGVudHMuIFN0dWRlbnRzIHdpdGggZGlzYWJpbGl0aWVzIHdobyBuZWVkIA0KY2xhc3Nyb29tIGFjY29tbW9kYXRpb25zIHNob3VsZCByZWdpc3RlciB3aXRoICoqT2ZmaWNlIG9mIFN0dWRlbnQgRGlzYWJpbGl0eSANClNlcnZpY2VzKiosIFNodXN0ZXIgSGFsbCByb29tIDIzOCwgNzE4LTk2MC04NDQxKi4iDQo8YnI+PGJyPg0KDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCjxicj4NCg0KIyAmbmJzcDsgQWNhZGVtaWMgc2NoZWR1bGUsIFNwcmluZyAyMDIzICAgICAgICAgICA8IS0tIC4uLi4uIDExdGggc2VjdGlvbiAuLi4uLiAtLT4NCjxicj4gICAgDQoNCiMjICZuYnNwOyBHZW5lcmFsIEluZm9ybWF0aW9uICAgICAgIDwhLS0gLi4uIEdFTkVSQUwgIEFDQURFTUlDICBDQUxFTkRBUiAuLi4gLS0+DQoNCipGYWxsIDIwMjMgJm5ic3A7IDx1PlVuZGVyZ3JhZHVhdGUgQWNhZGVtaWMgQ2FsZW5kYXI8L3U+KiAgJm5ic3A7IC0tLSAgJm5ic3A7IA0KTGVobWFuIENvbGxlZ2UsICZuYnNwOyBDaXR5IFVuaXZlcnNpdHkgb2YgTmV3IFlvcmssICZuYnNwOyBCcm9ueCBOWSAxMDQ2OCAgDQoNCjxwcmUgaWQ9Im15QkxPQ0sxIj4NCg0KICBGcmlkYXkgQXVndXN0IDI1ICAgICAgICAgICAgICAgICAgICAgIC0tLSBGYWxsIDIwMjMgY2xhc3NlcyBiZWdpbiAgDQogIA0KICBTZXB0ZW1iZXIgMSB0aHJ1IDE0ICAgICAgICAgICAgICAgICAgIC0tLSBXaXRoZHJhdyAoZ3JhZGUgb2YgV0QpIHBlcmlvZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBNb25kYXkgU2VwdGVtYmVyIDQgICAgICAgICAgICAgICAgICAgIC0tLSBDb2xsZWdlIENsb3NlZCwgbm8gY2xhc3NlczsgTGFib3IgRGF5DQogICAgICANCiAgU2VwdGVtYmVyIDE1IHRocnUgMTcgICAgICAgICAgICAgICAgICAtLS0gbm8gY2xhc3NlczsgYSByZWxpZ2lvdXMgaG9saWRheQ0KICAgICAgDQogIFNlcHRlbWJlciAyNCB0aHJ1IDI1ICAgICAgICAgICAgICAgICAgLS0tIG5vIGNsYXNzZXM7IGEgcmVsaWdpb3VzIGhvbGlkYXkNCiAgDQogIE1vbmRheSBPY3RvYmVyIDkgICAgICAgICAgICAgICAgICAgICAgLS0tIENvbGxlZ2UgQ2xvc2VkOyBDb2x1bWJ1cyBEYXkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIFR1ZXNkYXkgT2N0b2JlciAxMCAgICAgICAgICAgICAgICAgICAgLS0tIEFsbCBDbGFzc2VzIGZvbGxvdyBhIE1vbmRheSBzY2hlZHVsZQ0KICANCiAgV2VkbmVzZGF5IE5vdmVtYmVyIDIyICAgICAgICAgICAgICAgICAtLS0gbm8gY2xhc3Nlcw0KICANCiAgTm92ZW1iZXIgMjMgdGhydSAyNiAgICAgICAgICAgICAgICAgICAtLS0gbm8gY2xhc3NlczsgVGhhbmtzZ2l2aW5nIEhvbGlkYXkNCiAgDQogIE1vbmRheSBEZWNlbWJlciAxMSAgICAgICAgICAgICAgICAgICAgLS0tIExhc3QgZGF5IG9mIENsYXNzZXMgJiAiVyIgZ3JhZGUgZGVhZGxpbmUNCiAgDQogIFR1ZXNkYXkgRGVjZW1iZXIgMTIgICAgICAgICAgICAgICAgICAgLS0tIFJlYWRpbmcgRGF5DQogIA0KICBXZWRuZXNkYXkgRGVjZW1iZXIgMTMgICAgICAgICAgICAgICAgIC0tLSBSZWFkaW5nIERheQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgVGh1cnNkYXkgRGVjLiAxNCB0aHJ1IFdlZC4gRGVjLiAyMCAgICAtLS0gRmluYWwgRXhhbWluYXRpb25zIGF0IExlaG1hbiBDb2xsZWdlDQoNCjwvcHJlPg0KDQo8YnI+ICAgDQoNCiMjICZuYnNwOyBGUklEQVkgU2VjdGlvbiwgQmlvIDI0MCAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLiBGcmlkYXkgLi4uLiAtLT4NCipGcmlkYXkgcG0gc2VjdGlvbjogJm5ic3A7IDIgcG0gLSAgNTo1MCBwbSogDQoNCjxwcmUgaWQ9Im15QkxPQ0syIj4NCg0KICBGcmlkYXkgQXVnLiAyNSAgLS0tIENsYXNzIDEgLS0tICBHZXQgc3RhcnRlZCBpbiBiYXNlIFI6IGNvZGluZywgZGF0YSwgZ3JhcGhzLCBzdGF0aXN0aWNzIEkNCg0KICBGcmlkYXkgU2VwdC4gMSAgLS0tIENsYXNzIDIgLS0tICAgIiAgICAgIiAgICAgICIgICAgICIgICAgICIgICAgICIgICAgICIgICAgICAgICAiICAgICAgSUkNCg0KICBGcmlkYXkgU2VwdC4gOCAgLS0tIENsYXNzIDMgLS0tICAgIiAgICAgIiAgICAgICIgICAgICIgICAgICIgICAgICIgICAgICIgICAgICAgICAiICAgICBJSUkNCiAgICAgIA0KICBGcmlkYXkgU2VwdC4gMjIgLS0tIENsYXNzIDQgLS0tICAgIiAgICAgIiAgICAgICIgICAgICIgICAgICIgICAgICIgICAgICIgICAgICAgICAiICAgICAgSVYNCiAgDQogIEZyaWRheSBTZXB0LiAyOSAtLS0gQ2xhc3MgNSAtLS0gIFRFU1QgMQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNCiAgRnJpZGF5IE9jdC4gNiAgLS0tIENsYXNzIDYgLS0tICBBTk9WQTogY29uY2VwdHMsIGhpc3RvcnksIGNhbGN1bGF0aW9ucywgQW5vdmEgVGFibGUsIEYtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgc2lnbmlmaWNhbmNlIHRlc3QsIGFzc3VtcHRpb25zLCB3cml0aW5nDQoNCiAgRnJpZGF5IE9jdC4gMTMgLS0tIENsYXNzIDcgLS0tICBBTk9WQTogZWZmZWN0IHNpemUgKFItc3EsIENvaGVuIEQsIFZhcmlhbmNlIENvbXBvbmVudHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWRlbmNlIEludGVydmFscyBieSB0LWRpc3RyaWJ1dGlvbiAmIGJvb3RzdHJhcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGlzdGljYWwgcG93ZXIgYW5hbHlzaXM6IHRyYWRpdGlvbmFsICYgYm9vdHN0cmFwDQoNCiAgRnJpZGF5IE9jdC4gMjAgLS0tIENsYXNzIDggIC0tLSAgQ29udGludWVkLC4uLg0KDQogIEZyaWRheSBPY3QuIDI3IC0tLSBDbGFzcyA5ICAtLS0gIE11bHRpcGxlIENvbXBhcmlzb25zIGZvbGxvd2luZyBhIHNpZ25pZmljYW50IEFub3ZhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFubmVkIHZzLiB1bnBsYW5uZWQgY29tcGFyaXNvbnMsIFR1a2V5IEhTRCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhaXJ3aXNlIHQtdGVzdHMsIER1bm5ldHQncyBUZXN0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSG9sbS1Cb25mZXJyb25pIG1ldGhvZCwgZ3JhcGhpY2FsIHZpc3VhbGl6YXRpb24NCg0KICBGcmlkYXkgTm92LiAzICAtLS0gQ2xhc3MgMTAgLS0tICBLcnVza2FsLVdhbGxpcyAmIG90aGVyIG5vbnBhcmFtZXRyaWMgbWV0aG9kcywgQmF5ZXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFjdG9yIEFub3ZhLCBQZXJtdXRhdGlvbiB0ZXN0cywgTW9udGUgQ2FybG8gZGF0YQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW11bGF0aW9uLCBncmFwaGljYWwgdmlzdWFsaXphdGlvbiBvZiBvbmUtd2F5IGRhdGEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRpbmcgYWJvdXQgc3RhdGlzdGljYWwgJiBncmFwaGljYWwgcmVzdWx0cw0KDQogIEZyaWRheSBOb3YuIDEwIC0tLSBDbGFzcyAxMSAtLS0gIENvbnRpbnVlZCwuLi4NCg0KDQogIEZyaWRheSBOb3YuIDE3IC0tLSBDbGFzcyAxMiAtLS0gIFRFU1QgMg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNCiAgRnJpZGF5IERlYy4gMSAgIC0tLSBDbGFzcyAxMyAtLS0gQ29ycmVsYXRpb24sIGdyYXBoaWNhbCB2aXN1YWxpemF0aW9uLCByZWxhdGVkIHRvcGljcyBJDQoNCiAgRnJpZGF5IERlYy4gOCAgIC0tLSBDbGFzcyAxNCAtLS0gICAiICAgICAgICAgICAgIiAgICAgICAgICIgICAgICAgICAgICAgICIgICAgICAgIiAgIElJDQoNCiAgRnJpZGF5IERlYy4gMTUgIC0tLSBDbGFzcyAxNSAtLS0gVEVTVCAzLiAgVGhlIEZpbmFsIEV4YW0gZm9yIEZSSURBWSBTZWN0aW9uICANCg0KPC9wcmU+DQoNCg0KKipOb3RlKio6ICZuYnNwOyBEYXlzIGZvciBUZXN0IDEgYW5kIFRlc3QgMiBhcmUgc3ViamVjdCB0byBjaGFuZ2UuIFRlc3QgdG9waWNzIGFyZSBzdWJqZWN0IA0KdG8gY2hhbmdlLg0KDQo8YnI+IA0KICANCjxwIGlkPSJibGFja2xpbmUiPiBfX19fX19fX19fX19fX19fX18gPC9wPiA8YnI+ICAgICAgICA8IS0tIGJsYWNrIGxpbmUgLS0+IA0KDQoNCiMgJm5ic3A7IFdlbGNvbWUgdG8gQmlvIDI0MC4gKkJpb3N0YXRpc3RpY3MqICAgICAgIDwhLS0gLi4uLi4gMTJ0aCBzZWN0aW9uIC4uLi4uIC0tPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyMgJm5ic3A7IEludHJvZHVjdGlvbg0KDQo8YnI+DQoNCj4gKipCaW8gMjQwKiogaXMgYSByZXF1aXJlZCBjb3Vyc2UgZm9yIHRoZSBCaW9sb2d5ICoqQlMqKiBkZWdyZWUgYnV0IG5vdCBmb3IgdGhlIEJpb2xvZ3kgDQoqKkJBKiouIDxicj4gDQpCdXQsIGNoYW5nZXMgYXJlIHBlbmRpbmcgZm9yIHRoZSBCaW9sb2d5ICoqQlMqKiB0byBlbmFibGUgY291cnNlIHN1YnN0aXR1dGlvbnMgZm9yICoqQmlvIDI0MCoqLg0KDQo8YnI+DQo8aDUgaWQ9Im15SGVhZGVyMiI+DQogICpTaG93IHVwLCBzaG93IHVwIG9uIHRpbWUsIHBheSBhdHRlbnRpb24sIHRha2Ugbm90ZXMsIHdvcmsgaGFyZCwgYXNrIHF1ZXN0aW9ucywgDQogIGJlIGhvbmVzdCAmIGRvbid0IGNoZWF0LCBwbHVzIHByYWN0aWNlLCBwcmFjdGljZSwgcHJhY3RpY2UsKiAmbmJzcDsgYW5kIEJpbyAyNDAgDQogIHdpbGwgZW5oYW5jZSB5b3VyIHByb2Zlc3Npb25hbCBjYXJlZXIgZGV2ZWxvcG1lbnQgZmFyIGJleW9uZCBiZWluZyBtZXJlbHkgYSANCiAgcmVxdWlyZWQgY291cnNlLiBJIGhhdmUgc3R1ZGVudCBjYXNlIHN0dWRpZXMgb3ZlciB0aGUgZGVjYWRlcywgdG8gYmFjayB0aGlzIGNsYWltLiANCjwvaDU+PGJyPiANCg0KDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyIj4NCldlIG1lZXQgdGhlIGZpcnN0IGNsYXNzIGZvciB0aGUgZnVsbCBwZXJpb2QsIHNvIGJlIHByZXBhcmVkIHRvIHdvcmssIHRvIGxpc3RlbiBhbmQgdG8gDQpjb2RlIGNvbGxhYm9yYXRpdmVseSB3aXRoIG1lLCBpbiBjbGFzcy4gDQoNClVzZSB5b3VyIGxhcHRvcCBvciBkZXNrdG9wIGNvbXB1dGVyIGZvciBab29tIG1lZXRpbmdzLiANClBob25lcywgaXBhZHMgYW5kIENocm9tZSBib29rcyBoYW5kbGUgWm9vbSBidXQgY2Fubm90IHJ1biBSLiANCg0KKipCaW8gMjQwIGlzIGJhc2VkIG9uIFIgYW5kIHJlcXVpcmVzIHlvdSB0byB1c2UgUiwgZm9yIGRhdGEgYW5hbHlzaXMgYW5kIGdyYXBoaWNzLioqIA0KICANClIgcnVucyB3ZWxsIG9uICoqTGludXgqKiBlLmcuLCBVYnVudHUsIGJ1dCB0aGUgbG9vayBhbmQgZmVlbCBpcyBkaWZmZXJlbnQgc28gZG9u4oCZdCANCnVzZSBhIExpbnV4IG1hY2hpbmUgdW5sZXNzIHlvdSdyZSBzb21ld2hhdCBjb21mb3J0YWJsZSBhdCB0aGUgY29tbWFuZCBsaW5lIG9mIHRoZSANCkxpbnV4IHRlcm1pbmFsIGFuZCB5b3UncmUgd2lsbGluZy9hYmxlIHRvIHVuZGVyc3RhbmQgbXkgcHJvamVjdGVkLCBXaW5kb3dzIGNvZGluZyBpbiANClIgZHVyaW5nIGNsYXNzLCBpbnRvIHNhbWUsIGluIHNvbWUgdGhpcmQgcGFydHkgdGV4dCBlZGl0b3IsIHNheSBOb3RlcGFkKysgaW4gTGludXggb3IgDQpVYnVudHUncyBuYXRpdmUgdGV4dCBlZGl0b3Igb3IgdGhlIExpbnV4IHZlcnNpb24gb2YgUlN0dWRpby4gDQoNCkkgcm91dGluZWx5IHByb2dyYW0gUiBpbiBVYnVudHUgdXNpbmcgTm90ZXBhZCsrIGFzIA0KdGV4dCBlZGl0b3IgKGluc3RlYWQgb2YgUiBFZGl0b3Igd2hpY2ggZG9lc24ndCBleGlzdCBvbiB0aGUgTGludXggc2lkZSkgYW5kIGVuam95IA0KdGhlIHNwZWVkdXAgcmVsYXRpdmUgdG8gcnVubmluZyBSIG9uIGEgV2luZG93cyBtYWNoaW5lLCBvdGhlciBmYWN0b3JzIGJlaW5nIGVxdWFsLiAgIA0KPC9kaXY+PGJyPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRU5EIDIgY29sdW1uIG5ld3NwYXBlciBzdHlsZSAtLT4NCg0KPGg1IGlkPSJteUhlYWRlcjIiPg0KICBJcyBCaW8gMjQwIGEgY291cnNlIGluIDx1PmludHJvZHVjdG9yeSBzdGF0aXN0aWNzPC91PiBvciBhIGNvdXJzZSBpbiANCiAgPHU+Y29tcHV0ZXIgcHJvZ3JhbW1pbmc8L3U+PyBJdOKAmXMgYm90aCwgYmVjYXVzZSB0aGVzZSBza2lsbHMgYXJlIG5lZWRlZCBieSANCiAgcmVzZWFyY2hlcnMgaW4gYmlvbG9neSwgaW4gbWVkaWNpbmUgYW5kIGFjcm9zcyBhbGwgdGhlIHNjaWVuY2VzLiANCjwvaDU+PGJyPiANCg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMiI+DQpJZiB5b3UgaGF2ZSBleHBlcmllbmNlIGluIGFueSBjb21wdXRlciBwcm9ncmFtbWluZyBsYW5ndWFnZSB5b3Ugd2lsbCBpbW1lZGlhdGVseSANCnRha2UgdG8gUiwgZmluZCBpdCBlYXN5LCBhbmQgZW5qb3kgdGhlIHJlYWRhYmxlIGNvZGUuIA0KDQpJZiB5b3UgaGF2ZSBubyBwcm9ncmFtbWluZyBleHBlcmllbmNlIHRoZW4gZ2V0IG92ZXIgaXQsIGFuZCBnZXQgc3RhcnRlZCBpbiB0aGlzIA0KY2xhc3Mgd2l0aCBSLCBhcyB5b3UgYWR2YW5jZSB5b3VyIGNhcmVlciBkZXZlbG9wbWVudC4gDQo8L2Rpdj48YnI+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFTkQgMiBjb2x1bW4gbmV3c3BhcGVyIHN0eWxlIC0tPg0KDQo8aDUgaWQ9Im15SGVhZGVyMiI+DQogIENvZGluZyBpbiBSIGlzIGVhc2llciB0aGFuIHlvdSBtaWdodCB0aGluayBhbmQgaXTigJlzIG15IGpvYiB0byBtYWtlIGl0IHNvLiBGb3IgDQogIGluc3RhbmNlLCBpbiByZWNlbnQgc2VtZXN0ZXJzIGFtb25nIHRoZSBjb2RpbmcgbmVvcGh5dGVzIGluIEJpbyAyNDAsIEkgYnJvdWdodCANCiAgc2V2ZXJhbCBzdHVkZW50cyBpbiBlYWNoIHNlY3Rpb24sIHVwIHRvIEJpb2xvZ3kgRG9jdG9yYWwgc3R1ZGVudCBsZXZlbCBpbiB0ZXJtcyBvZiANCiAgc3RhdGlzdGljcyBhbmQgcHJvZ3JhbW1pbmcgaW4gUi4gVGhpcyBzZW1lc3RlciB5b3UgY2FuIGFjaGlldmUgdGhlIHNhbWUsIGlmIA0KICB5b3Ugd29yayBoYXJkLg0KPC9oNT48YnI+IA0KDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyIj4NCldoZXRoZXIgb25lIGhhcyBoYWQgYSBzdGF0aXN0aWNzIGNvdXJzZSBiZWZvcmUgb3Igbm90LCBzZWVtcyB0byBtYWtlIGxpdHRsZSANCmRpZmZlcmVuY2UgaW4gQmlvIDI0MC4gTGlrZXdpc2UgZm9yIENhbGN1bHVzLiBJbiBCaW8gMjQwIHdlIHVzZSBiYXNpYyBhbGdlYnJhaWMgDQphbmQgc3ltYm9saWMgdGhpbmtpbmcgd2hpbGUgbGV0dGluZyBSIGRvIHRoZSBoZWF2eSBsaWZ0aW5nLiAgIA0KDQpEaXN0dXJiaW5nbHkgaW4gcmVjZW50IHNlbWVzdGVycywgc29tZSBzdHVkZW50cyBkaWQgbm90IGtub3cgaG93IHRvIG1vdmUgZmlsZXMgb2ZmIA0KYW5kIG9udG8gdGhlaXIgaGFyZCBkcml2ZXMgdXNpbmcgTGVobWFuIGVtYWlsIGFuZCBVU0IgcG9ydHMgKGUuZy4sIFVTQiBmbGFzaCBkcml2ZSkuIA0KT3RoZXJzIGRpZCBub3Qga25vdyB0aGUgbmFtZSBvciBsb2NhdGlvbiBvZiB0aGVpciAqKndvcmtpbmcgZGlyZWN0b3J5Kiogb3Igd2hhdCBhIA0Kd29ya2luZyBkaXJlY3RvcnkgaXMuIA0KDQpNYW55IHJlZnVzZWQgdG8sIG9yIGNvdWxkIG5vdCB1c2UgdGhlaXIgY29tcHV0ZXIgdGhlIHdheSBhIHNjaWVudGlzdCB1c2VzIGEgDQpjb21wdXRlciDigJMgZm9yIGluc3RhbmNlLCBhbGwgYXBwcyBvdXQgb2YgUkFNIGV4Y2VwdCB0aGUgb25lIGJlaW5nIHVzZWQsIFIgaW4gb3VyIA0KY2FzZSAtLSBhbmQgc3VmZmVyZWQgT1MgZnJlZXplIG9yIGdsYWNpYWwgc2xvd25lc3MsIGFzIGEgcmVzdWx0LiBBbHNvLCBhdm9pZCANCmhhdmluZyAqbXVsdGlwbGUgaW5zdGFuY2VzKiBvZiBSIG9yIGl0IHdpbGwgZXZlbnR1YWxseSBjcmFzaC4gQXZvaWQgKmRvY2tpbmcqIA0KUiB3aW5kb3dzIGVsc2UgY29uZnVzaW9uIG1heSBydWluIHlvdXIgUiBTZXNzaW9uLiBBbiBSIFNlc3Npb24gaXMgdGhlIHBlcmlvZCANCm9mIHRpbWUgZnJvbSB3aGVuIHlvdSBvcGVuIFIgdG8gd2hlbiB5b3UgY2xvc2UgUi4NCg0KTWFueSBoYWQgdHJvdWJsZSBjcmVhdGluZywgbmFtaW5nIGFuZCBzYXZpbmcgY29tcHV0ZXIgZmlsZXMgcHJvcGVybHkgYW5kIHRoaXMgaXMgYSANCnNlcmlvdXMgaXNzdWUgZHVyaW5nIGEgVGVzdCwgYW5kIGluIHJlYWwgbGlmZS4gDQoNClBsZWFzZSBub3RlIHRoYXQgV2luZG93cyBtYWNoaW5lcyBtdXN0IGJlIGNvbmZpZ3VyZWQgc28gdGhlIHVzZXIgY2FuIGtub3cgYW5kIOKAnHNlZeKAnSANCnRoZSBmdWxsIG5hbWUgb2YgYWxsIGZpbGVzIGVsc2Ugb25lIGhhcyBkaWZmaWN1bHR5IHJlYWRpbmcgZmlsZXMgaW50byBSIGFuZCB0cm91YmxlIA0KcHJvcGVybHkgbmFtaW5nIGZpbGVzLiBUaGUgZGVmYXVsdCBXaW4gc2V0dGluZyAiaGlkZXMiIGZpbGUgZXh0ZW5zaW9ucywgbGlrZSAuY3N2LCANCi5SLCAucGRmLiBNYWMgT1MgYXNzdW1lcyBodW1hbnMgYXJlIHNtYXJ0IGVub3VnaCB0byBoYW5kbGUgc2VlaW5nIHRoZSBjb21wbGV0ZSBmaWxlIA0KbmFtZSBzbyBpdCBkaXNwbGF5cyB0aGUgY29tcGxldGUgZmlsZSBuYW1lLCB3aXNlbHkuIFRoZSBmaWxlIG5hbWUgaW5jbHVkZXMgdGhlIA0KZXh0ZW5zaW9uLCBlLmcuLCAqKmZvby5jc3YqKiBhbmQgKipmb28uUioqIGFyZSBjb21wbGV0ZSBmaWxlIG5hbWVzIHdoaWxlICoqZm9vKiogDQppcyBub3QuDQoNCklmIHlvdXIgV2luZG93cyBtYWNoaW5lIGRvZXMgbm90IHNob3cgeW91IHRoZSAqKmNvbXBsZXRlIG5hbWUqKiBvZiBhbnkgYW5kIGFsbCANCmZpbGVzLCB0aGVuIGRvIHRoZSBmb2xsb3dpbmcuIEdvIHRvICpTZXR0aW5ncyogdG8gKlVwZGF0ZSAmIFNlY3VyaXR5KiB0byAqRm9yIA0KZGV2ZWxvcGVycyogdG8gKkZpbGUgRXhwbG9yZXIqLCB0aGVuIG1ha2Ugc3VyZSB0byBjbGljaywgc3VjaCB0aGF0IHRoZSBzZXR0aW5ncyANCndpbGwgKnNob3cgZmlsZSBleHRlbnNpb25zKi4gTm93IHlvdSB3aWxsIHNlZSB0aGUgZnVsbCBuYW1lIG9mIGV2ZXJ5IGZpbGUgYW5kIHlvdSANCmNhbiB3cml0ZSBjb2RlIGluIFIgdG8gbmFtZS9yZWFkL3dyaXRlIGZpbGVzIHN1Y2Nlc3NmdWxseSBhbmQgcHJvcGVybHkuICANCg0KT2J2aW91c2x5LCBhbGwgY29sbGVnZSBzdHVkZW50cyBvd24gbGFwdG9wIG9yIGRlc2t0b3AgY29tcHV0ZXJzLiBTaG91bGQgeW91IGJlIGluIA0KdGhlIG1hcmtldCBmb3Igb25lIEkgY2FuIHByb3ZpZGUgYWR2aWNlIGJhc2VkIG9uIG15IDUwKyB5ZWFycyB1c2luZyBjb21wdXRlcnMuIA0KQmUgYWR2aXNlZCB0aGF0IEJpbyAyNDAgZG9lcyBub3QgcmVxdWlyZSBhbiBleHBlbnNpdmUgbGFwdG9wIGNvbXB1dGVyIGJ1dCBpdCBjYW5ub3QgDQpiZSBDaHJvbWUgT1MgYmVjYXVzZSBDaHJvbWUgY2FuJ3QgcnVuIFIuIA0KDQpFdmVyeXRoaW5nIGluIEJpbyAyNDAgcnVucyBvbiBteSBvbGQgJDE2OSBBU1VTIGxhcHRvcCAoMTEuNuKAnSwgV2luIDEwLCAyIGNvcmUgDQpDZW50cmlubyBDUFUsIDQgZ2IgUkFNKS4gQWx0aG91Z2ggSSB3YXMgcmVzcG9uc2lkbGUgZm9yIGJyaW5naW5nIHRoZSBmaXJzdCBBcHBsZSANCmNvbXB1dGVycyB0byB0aGlzIGNhbXB1cyBpbiAxOTc5LCBNYWNzIGFyZSBvdmVyLXByaWNlZCBhbmQgbW9yZSBkaWZmaWN1bHQgdG8gdXNlIGFuZCANCnRvIG1haW50YWluIHRoYW4gV2luZG93cyBtYWNoaW5lcywgYXQgdGhlIHByZXNlbnQgdGltZTsgbmV2ZXJ0aGVsZXNzLCBpZiB5b3Uga25vdyANCmhvdyB0byB1c2Ugb25lIGxpa2UgYSBzY2llbnRpc3QgdXNlcyBhIGNvbXB1dGVyLCB0aGVuIE1hY3MgYXJlIGZhc3QgYW5kIHJlbGlhYmxlLCANCmFsYmVpdCB0b28gZXhwZW5zaXZlLiANCg0KQXMgeW91IGtub3csIHRoZSBDb2xsZWdlIGlzIG1ha2VzIHNvbWUgbGFwdG9wcyBhdmFpbGFibGUgdG8gc3R1ZGVudHMgZHVyaW5nIA0KdGhlIHBhbmRlbWljIC0tIHNlZSB5b3VyIGVtYWlscyBmcm9tIHRoZSBDb2xsZWdlIG9uIGhvdyB0byByZXF1ZXN0IG9uZS4gUmVsYXRpdmUgdG8gDQpCaW8gMjQwLCBhdm9pZCBpUGFkcyBhbmQgQ2hyb21lIG1hY2hpbmVzIGJlY2F1c2UgdGhleSBkb24ndCBydW4gUiwgYnV0IHRoZXkgYXJlIFpvb20gDQpjb21wYXRpYmxlLiBJIHJlYWxpemUgdGhhdCBhIENocm9tZSBtYWNoaW5lIG9yIGlQYWQgd291bGQgYmUgDQpoYW5keSBmb3IgY291cnNlcyBvdGhlciB0aGFuIEJpbyAyNDAuICANCjwvZGl2Pjxicj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRU5EIDIgY29sdW1uIG5ld3NwYXBlciBzdHlsZSAtLT4gIA0KDQojIyAmbmJzcDsgVGhlIEljZWJlcmcgVGVhY2hpbmcgTW9kZWwgICAgICAgICAgICAgIDwhLS0gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gLS0+DQoNCjxicj4gIA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI2MCUiLCBmaWcuY2FwPSJOZXdmb3VuZGxhbmQsIENhbmFkYSIsIGZpZy5hbGlnbj0iY2VudGVyIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0iQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TWUxMQUJVUy9OZmxkLmpwZyIpDQpgYGANCg0KPGJyPiAgDQoNCj4gVGhlICoqKnRvcCoqKiBvZiBhbiBpY2ViZXJnIGxvb2tzIGxhcmdlIGJ1dCBpdCdzIHNtYWxsIGNvbXBhcmVkIHRvIHRoZSAqKipib3R0b20qKiogDQpvZiB0aGUgaWNlYmVyZy4gPGJyPiBXaGF0J3MgbW9yZSBpbXBvcnRhbnQsIHRoZSB0b3Agb3IgdGhlIGJvdHRvbT8gDQoNCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjIiPg0KSSBsZWFybmVkIHRoaXMgZmlyc3RoYW5kIGluIHRoZSAxOTcwcyBpbiBOZXdmb3VuZGxhbmQgQ2FuYWRhLiBJIHJlY2tsZXNzbHkgDQpzY3JhbWJsZWQgb3ZlciB0aGUgZWRnZSBvZiBtYXNzaXZlIGNvYXN0YWwgYm91bGRlcnMgdG8gaW5zcGVjdCBhbmQgdG91Y2ggYSBqb3N0bGluZyANCmljZWJlcmcgZnJhZ21lbnQgdGhlIHNpemUgb2YgYSBzbWFsbCBob3VzZSwgdGhhdCBjYWx2ZWQgb2ZmIHRoZSBnaWdhbnRpYyBwYXJlbnRhbCANCmljZWJlcmcgZnVydGhlciBvdXQgaW4gdGhlIGJheS4gDQoNCkljZWJlcmdzIGxvb2sgd2hpdGUuIEJ1dCwgSSB3YXMgYXN0b25pc2hlZCB0aGF0IHVwIA0KY2xvc2UsIHRoZSBpY2Ugd2FzIGNyeXN0YWwgY2xlYXIgYW5kIG15c3RlcmlvdXMsIGFzIEkgcGVhcmVkIGRlZXBseSB3aXRoaW4gYW5kIA0KcG9uZGVyZWQgd2hlcmUgaXQgY2FtZSBmcm9tLCBob3cgb2xkIGl0IHdhcywgd2hlcmUgaXQgd2FzIGdvaW5nIGFuZCBob3cgbG9uZyBpdCANCndvdWxkIGxhc3QuICANCiANCkluIEJpbyAyNDAsIG9mIGNvdXJzZSB0aGVyZSBpcyAqKnJlcXVpcmVkKiogbWF0ZXJpYWwgcmVmbGVjdGVkIGluIFRlc3RzLiBBbmQsIEkgDQp3aWxsIGV4cG9zZSB5b3UgdG8gbXVjaCBtb3JlIC0tLSB0byB0aGUgKipvcHRpb25hbCoqIGJvdHRvbSBvZiB0aGUgaWNlYmVyZyBmb3IgDQp0aG9zZSBwdXNoaW5nIGNhcmVlciBkZXZlbG9wbWVudCBmYXJ0aGVyIGFuZCBmYXN0ZXIgdGhhbiBtZXJlbHkgZWFybmluZyB0aGUgDQpncmFkZSBvZiBBIG9yIEIuIA0KDQpQZXJpb2RpY2FsbHkgYWNyb3NzIHRoZSB0ZXJtIEknbGwgZGVtb25zdHJhdGUgYSBwYXJ0aWN1bGFyIHN0YXRpc3RpY2FsIA0KbWV0aG9kLCBhIGRpZmZlcmVudCB0eXBlIG9mIGdyYXBoIG9yIGRlbHZlIGludG8gc29tZSBSIGNvZGluZyBzdHJhdGVneSB3aGlsZSANCmFubm91bmNpbmcgaXQncyAqKmJvdHRvbSBvZiB0aGUgaWNlYmVyZyoqICR7IH0kIG1lYW5pbmcgKipvcHRpb25hbCoqLiBTb21lIGV4dHJhIA0KY3JlZGl0IHF1ZXN0aW9ucyBvbiB0ZXN0cyBtaWdodCByZWZsZWN0IHRoZSBib3R0b20gb2YgdGhlIGljZWJlcmcuDQo8L2Rpdj4NCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iOTAlIiwgZmlnLmNhcD0iICIsIGZpZy5hbGlnbj0iY2VudGVyIn0NCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvV2hpdGVib2FyZC0wMS5wbmciKQ0KYGBgDQoNCj4gKipEaXN0cmlidXRpb24gb2YgZ3JhZGVzKiogICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyIj4NClRoZSBncmFwaCBiZWxvdywgY3JlYXRlZCBpbiBSLCBpcyBhIGRlbnNpdHkgKipoaXN0b2dyYW0qKiB3aXRoIGtlcm5lbCBkZW5zaXR5IA0KZXN0aW1hdGUsIG9mIHRoZSBmaW5hbCBhdmVyYWdlIGdyYWRlcyBmb3IgU3ByaW5nIDIwMjAuIE5vdGljZSB0aGUgcGVha2VkIGNlbnRyYWwgDQp0ZW5kZW5jeSAocG9zaXRpdmUga3VydG9zaXMpIGFuZCB0aGUgaGVhdnkgbGVmdC1oYW5kIHRhaWwgKG5lZ2F0aXZlIHNrZXduZXNzKSwgDQpyZWxhdGl2ZSB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24uIA0KDQpEb24ndCB3b3JyeSBhYm91dCB1bmRlcnN0YW5kaW5nIHRoZSBncmFwaCBhbmQgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgcmlnaHQgDQpub3csIGJlY2F1c2Ugd2Ugd2lsbCBkZXZlbG9wIHRoZXNlIHRoaW5ncyBpbiBkZXRhaWwsIGluIGNsYXNzLg0KPC9kaXY+DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjYwJSIsIGZpZy5jYXA9IiAiLCBmaWcuYWxpZ249ImNlbnRlciJ9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9DQogICAgICAgICAgICAgICAgIkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvaGlzdG9ncmFtIGdyYWRlcyBTcHJpbmcgMjAyMC5wbmciKQ0KYGBgDQoNCjxicj4NCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjIiPg0KVGhlIHR3byBncmFwaHMgYmVsb3csIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGdyYWRlcyBpbiBCaW8gMjQwIGZvciB0aGUgDQpGcmlkYXkgYW5kIFNhdHVyZGF5IHNlY3Rpb25zLCBGYWxsIDIwMjIuIFRoZSBmaW5hbCBhdmVyYWdlIGlzIHRoZSBtZWFuIG9mIHRoZSAzIFRlc3RzLiANCkkgYWRkZWQgMTAgcG9pbnRzIHRvIHRoZSBmaW5hbCBhdmVyYWdlIG9mIGVhY2ggc3R1ZGVudCwgYXMgaW5kaWNhdGVkIG9uIHRoZSBncmFwaHMuIA0KDQpOb3RpY2UgdGhhdCBieSB0aGUgbGFzdCBkYXkgb2YgY2xhc3MsIG49MTAgaGFkIGRyb3BwZWQgZnJvbSB0aGUgRnJpZGF5IHNlY3Rpb24gd2l0aCANCnRoZSAiVyIgZ3JhZGU7IGFuZCBuPTEzIGRyb3BwZWQgZnJvbSB0aGUgU2F0dXJkYXkgc2VjdGlvbiwgYWxsIGR1ZSB0byB2ZXJ5IGxvdyANCnRlc3QgZ3JhZGVzLiBBcyBhIHJlc3VsdCwgODUlIGVhcm5lZCBBIG9yIEIgaW4gdGhlIEZyaWRheSBzZWN0aW9uIHdoaWxlIDc2JSBlYXJuZWQgDQpBIG9yIEIgaW4gdGhlIFNhdHVyZGF5IHNlY3Rpb24uIA0KDQpJbnRlcmVzdGluZ2x5LCB0aGUgbWVkaWFuIGZpbmFsIGdyYWRlICg1MHRoIHBlcmNlbnRpbGUpIHdhcyBuZWFybHkgaWRlbnRpY2FsIGJldHdlZW4gDQp0aGUgMiBzZWN0aW9uczogOTAuODggZm9yIEZyaWRheSwgOTAuOTcgZm9yIFNhdHVyZGF5LiBUaGUgbGVmdCBncmFwaCBpcyBhICoqYm94cGxvdCoqIA0KYW5kIG9uIHRoZSByaWdodCwgYSAqKmtlcm5lbCBkZW5zaXR5KiogZ3JhcGguIFRoZXNlIGdyYXBoIHR5cGVzIChoaXN0b2dyYW0sIGJveHBsb3QsIA0Ka2VybmVsIGRlbnNpdHkpIGFyZSBleHRyZW1lbHkgY29tbW9uIGluIHNjaWVudGlmaWMgam91cm5hbCBwYXBlcnMgYW5kIHlvdSB3aWxsIA0KYmVjb21lIGV4cGVydCBpbiBjb2RpbmcgZm9yIHRoZW0gaW4gUi4NCjwvZGl2Pg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249ImRlZmF1bHQifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aD0NCiAgICAgICAgICAgICAgICAiQzovVXNlcnMvZHdpZ2gvRGVza3RvcC9TeWxsYWJ1cyBGYWxsIDIwMjIvYm94cGxvdCBGYWxsIDIwMjIucG5nIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9DQogICAgICAgICAgICAgICAgIkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU3lsbGFidXMgRmFsbCAyMDIyL2tlcm5lbCBGYWxsIDIwMjIucG5nIikNCg0KYGBgDQoNCg0KPGJyPiAgDQo8cCBpZD0iYmxhY2tsaW5lIj4gX19fX19fX19fX19fX19fX19fIDwvcD4gPGJyPiAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQo8IS0tICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyAgLS0+DQo8IS0tICAgRU5EIG9mIHRyYWRpdGlvbmFsIFNZTExBQlVTICAgICAgICAgICAgICAgICAgICAuLi4uLi4uLi4uLi4uLiAgLS0+DQo8IS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+DQo8IS0tICAuLi4uLi4uICBUSEUgUiBDT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4uLi4uLi4uLi4uLiAgLS0+DQo8IS0tICAuLi4uLi4uLi4uLi4uLi4uLiAgIENoVU5LIFNFQ1RJT05TICAgICAgICAgICAgICAuLi4uLi4uLi4uLi4uLiAgLS0+DQo8IS0tICAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gICAgYmVnaW4gICAgICAuLi4uLi4uLi4uLi4uICAgLS0+DQo8IS0tICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyAgLS0+DQoNCg0KIyAmbmJzcDsgVXNpbmcgUiBpcyBlYXNpZXIgdGhhbiB5b3UgbWlnaHQgdGhpbmsgICAgPCEtLSAuLi4uLiAxM3RoIHNlY3Rpb24gLi4uLi4gLS0+DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojICdzb3VyY2UnIHRoZSBSIEVkaXRvciBmaWxlIHdpdGggZnVuIGRlZmluaXRpb25zDQpzb3VyY2UoIkM6XFxVc2Vyc1xcZHdpZ2hcXERlc2t0b3BcXEsgZnVucyBVTklWQVJJQVRFLlIiKSANCg0Kc291cmNlKCJDOlxcVXNlcnNcXGR3aWdoXFxEZXNrdG9wXFxLIGZ1bnMgT05FIFdBWS5SIikNCmBgYA0KDQo8YnI+ICAgIA0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMiI+DQpBIHByb3ZlbiB3YXkgdG8gYmVnaW4gbGVhcm5pbmcgUiBpcyB0byBlbmdhZ2UgdGhlIHNpbXBsZXN0IHR5cGUgb2YgbnVtZXJpYyBkYXRhOiANCiR7IH0kIHRoZSAqKnVuaXZhcmlhdGUqKi4gSW4gb3RoZXIgd29yZHMsIHNpbmdsZSBzYW1wbGVzIG9mIG51bWVyaWMgZGF0YSB3aGV0aGVyIHJlYWwgDQpkYXRhIG9yIHNpbXVsYXRlZCBkYXRhLiBCeSAqKmVuZ2FnZSoqIEkgbWVhbiAtLS0gaG93IHRvIHR5cGUgYW5kIHN0b3JlIGl0IGluIFIgY29kZSwgDQpob3cgdG8gcmVhZCBpdCBpbiBmcm9tIGFuIGV4dGVybmFsIGZpbGUsIGhvdyB0byBtYW5pcHVsYXRlIGl0LCBob3cgdG8gZ3JhcGggaXQsIA0KaG93IHRvIGFuYWx5emUgaXQgc3RhdGlzdGljYWxseS4gDQoNCkluZGVlZCwgdGhpcyBpcyBleGFjdGx5IGhvdyBJIGdvdCBzdGFydGVkIHRlYWNoaW5nIG15c2VsZiBSLCB5ZWFycyBhZ28uIEFmdGVyIA0KcmVhZGluZyBhYm91dCBSIGluIHRoZSAyMDA0LCBmaXJzdCBlZGl0aW9uIG9mIG91ciB0ZXh0Ym9vayBieSBQcm9mLiBQZXRlciBEYWxnYWFyZCwgDQpJIHJlYXNvbmVkIHRoYXQgaWYgSSBjb3VsZCBzdG9yZSBzbWFsbCwgbnVtZXJpYyBzYW1wbGVzIGluIGFuIFIgRWRpdG9yIGZpbGUsIGdldCANCmRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIHRoZXNlIHNhbXBsZXMsIGFzIHdlbGwgYXMgZ3JhcGhzIGxpa2UgaGlzdG9ncmFtcywgdGhlbiBJIA0KY291bGQgcHJvYmFibHkgbW92ZSBmb3J3YXJkIHRvIGhhbmRsaW5nIGFuZCBhbmFseXppbmcgbW9yZSBjb21wbGljYXRlZCBkYXRhIHNldHMgaW4gUi4gDQpJIGRpZCBhbmQgeW91IGNhbiB0by4gDQoNCkl0J3Mgbm90IHJvY2tldCBzY2llbmNlIGJ1dCBpdCBkb2VzIHJlcXVpcmUgcGF0aWVuY2UsIGNvcGlvdXMgcHJhY3RpY2UsIGF0dGVudGlvbiB0byANCmRldGFpbCwgdGhlIGFiaWxpdHkgdG8gZW5nYWdlIFIgY29kaW5nIGluIHRyaWFsLWFuZC1lcnJvciBmYXNoaW9uIHBsdXMgb2JzZXJ2aW5nIG91ciANCnJ1bGVzIGFuZCBjb252ZW50aW9ucyBmb3IgYnVpbGRpbmcgYW5kIGRlYnVnZ2luZywgY2xlYW4sIHJlYWRhYmxlLCB3ZWxsLXN0cnVjdHVyZSBhbmQgDQp3aXNlbHkgY29tbWVudGVkIGNvZGUsIGFzIG9wcG9zZWQgdG8gZHJlYWRlZCAqKnVnbHkgY29kZSoqIHRoYXQncyBoYXJkIHRvIHJlYWQsIA0KY2hhbmdlLCBwcmludCBhbmQgZGVidWcuICAgIA0KDQpJbiBjbGFzcywgd2UgbW9zdGx5IHVzZSBSIHRvIGdyYXBoIGFuZCBhbmFseXplICoqcmVhbCoqIGRhdGEsIGFuZCBkYXRhIHRoYXQncyANCmxhcmdlbHkgYmlvbG9naWNhbC4gDQoNCkJ1dCwgdGhlcmUncyBlbmR1cmluZyB2YWx1ZSBpbiBsZWFybmluZyBlYXJseSBvbiwgaG93IHRvIGNyZWF0ZSBhbmQgdXNlLCAqKmZha2UqKiANCmRhdGEuIFRoZSB3b3JkIGZha2UgbWlnaHQgYmUgbWlzbGVhZGluZzsgaGVyZSwgaXQncyBzaG9ydGhhbmQgZm9yOiAqKipNb250ZSBDYXJsbyoqKiANCipkYXRhIHNpbXVsYXRpb24gZnJvbSB0aGVvcmV0aWNhbCBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb25zLiogRWFybHkgaW4gdGhpcyAqKlNlY3Rpb24qKiANCndlIHVzZSBzaW11bGF0ZWQgZGF0YSBmcm9tIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uLiBUaGVuLCB3ZSBtb3ZlIGludG8gDQoqKm9uZS13YXkgZGF0YSoqIChtZXJlbHkgc2V0cyBvZiBzaW5nbGUgc2FtcGxlcykgdGhhdCdzIHNpbXVsYXRlZCBkYXRhIGFzIHdlbGwgYXMgDQpyZWFsIGRhdGEuDQo8L2Rpdj4NCjxicj4gICANCg0KDQo8cCBzdHlsZT0iZm9udC1zaXplOiAxNTAlOyBmb250LWZhbWlseTogR2FyYW1vbmQsIEdlb3JnaWE7IGZvbnQtc3R5bGU6IGl0YWxpYzsgDQpjb2xvcjogUGVydTsgdGV4dC1hbGlnbjogY2VudGVyOyBsaW5lLWhlaWdodDogMTA1JSINCj4gQXMgZW5nYWdpbmcgYW5kIG1lYW5pbmdmdWwgYXMgaXQgaXMgaW4gaXRzIG93biByaWdodCwgd3JpdGluZyBjb2RlIGlzIG5vdCBkb2luZyANCnN0YXRpc3RpY3MuPGJyPiBPbmUgb2YgdGhlIGJpZyBhZHZhbnRhZ2VzIG9mIHdvcmtpbmcgd2l0aCBSIGlzIHRoYXQgeW91IGNhbiBkbyBxdWl0ZSBiaXQgDQpvZiBzdGF0aXN0aWNzIHdpdGgganVzdCBhIGhhbmRmdWwgb2YgZnVuY3Rpb25zIGFuZCB0aGUgc2ltcGxlc3Qgc3ludGF4LiBSIGlzIGEgdG9vbCANCnRoYXQgaGVscHMgeW91IGtlZXAgbW92aW5nIGZvcndhcmQuIElmIHlvdSB3YW50IHRvIHNlZSBzb21ldGhpbmcgdGhlbiBwbG90IGl0LiBJZiANCnRoZSBkYXRhIGFyZSBpbiB0aGUgd3JvbmcgZm9ybWF0LCB0aGVuIG11dGF0ZSBpdC4gPGJyPg0KPGI+Sm9obiBDaGFtYmVyczwvYj4gJm5ic3A7IDIwMTQgS2V5bm90ZSBBZGRyZXNzICZuYnNwOyBVc2VyUiE8L3A+IA0KDQo8YnI+IA0KDQojIyAmbmJzcDsgYmFzZSBSICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi5jb21tZW50cy4uLi4uLi4gLS0+DQoNCjxicj4NCg0KPCEtLSAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLiAtLT4NCjwhLS0gLi4uLi4uLi4gYSByYXcsIFNWRyBjb2RlIGNodW5rIG9uICJiYXNlIFIiIC4uLi4uLi4uLi4gLS0+DQo8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQpgYGB7PWh0bWx9DQogICAgDQo8c3ZnIGhlaWdodD0iMjEwIiB3aWR0aD0iODAwIiA+DQogIDxkZWZzPg0KICAgIDxmaWx0ZXIgaWQ9ImZpbHRlckJhc2UiIHg9IjAiIHk9IjAiPg0KICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNSIvPg0KICAgICAgPGZlT2Zmc2V0IGR4PSI1IiBkeT0iNSIvPg0KICAgIDwvZmlsdGVyPg0KICA8L2RlZnM+DQogIDxyZWN0IHdpZHRoPSIxNTAiIGhlaWdodD0iMTUwIiBmaWxsPSJncmV5IiBmaWx0ZXI9InVybCgjZmlsdGVyQmFzZSkiIC8+DQogIDxyZWN0IHdpZHRoPSIxNTAiIGhlaWdodD0iMTUwIiBmaWxsPSJ5ZWxsb3ciIHN0cm9rZT0iYmxhY2siIC8+DQogICAgIFNvcnJ5LCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBpbmxpbmUgU1ZHLiAgDQogICAgDQogIDx0ZXh0IGZpbGw9ImJsYWNrIiBmb250LXNpemU9MjJwdCBmb250LWZhbWlseT0iQXJpYWwgYmxhY2siIFZlcmRhbmEgDQogICAgIHg9MjIgeT04ND4gYmFzZSBSIDwvdGV4dD4NCiAgICAgDQogIDx0ZXh0IGR5PTQgeD0xODcgeT0xNSBmb250LXNpemU9MThwdCBmb250LXN0eWxlPWl0YWxpYyBmb250LXdlaWdodD1ib2xkPiANCiAgICAiYmFzZSBSIiBpcyB3aGF0IHlvdSBnZXQgd2hlbiBSIGlzIGluc3RhbGxlZCE8L3RleHQ+DQogICAgDQogIDx0ZXh0IHg9MTkwIHk9NDMgZm9udC1zaXplPTEycHQgZm9udC1zdHlsZT1pdGFsaWM+DQogICAgQW5kLCBpdCBpbmNsdWRlcyBhcm91bmQgMTUgcGFja2FnZXMgJiM4MjA5OyYjODIwOTsgdXRpbHMsIGJhc2UsIGdyYXBoaWNzLCBzdGF0cywgDQogICAgc3RhdHM0LCBncmlkLCBib290LDwvdGV4dD4NCiAgPHRleHQgeD0xOTAgeT02NCBmb250LXNpemU9MTJwdCBmb250LXN0eWxlPWl0YWxpYz4NCiAgICBnckRldmljZXMsIHRvb2xzLCB0Y2x0aywgc3BsaW5lcywgcGFyYWxsZWwsIG1ldGhvZHMsIGRhdGFzZXRzLCBjb21waWxlci4gDQogICAgJm5ic3A7IFRob3VzYW5kcyBvZjwvdGV4dD4NCiAgPHRleHQgeD0xOTAgeT04NSBmb250LXNpemU9MTJwdCBmb250LXN0eWxlPWl0YWxpYz4gDQogICAgQ1JBTiBwYWNrYWdlcyBvcGVyYXRlIHdpdGhpbiBiYXNlIFIuICZuYnNwOyBJbiBteSBvcGluaW9uLCBpdCdzIGJlc3QgdG8gbGVhcm4gDQogICAgYmFzZSBSIGZpcnN0LDwvdGV4dD4NCiAgPHRleHQgeD0xOTAgeT0xMDYgZm9udC1zaXplPTEycHQgZm9udC1zdHlsZT1pdGFsaWM+IA0KICAgIGJlZm9yZSBsZWFybmluZyBpdHMgZGlhbGVjdHMgKGUuZy4sIFJTdHVkaW8sIHRoZSB0aWR5dmVyc2UpIGFuZCBiZWZvcmUgbGVhcm5pbmcgDQogICAgb3RoZXI8L3RleHQ+DQogIDx0ZXh0IHg9MTkwIHk9MTI3IGZvbnQtc2l6ZT0xMnB0IGZvbnQtc3R5bGU9aXRhbGljPiANCiAgICBSIGdyYXBoaWNhbCBlbnZpcm9ubWVudHMgKGUuZy4sIGdyaWQtZ3JhcGhpY3MsIExhdHRpY2UsIGdncGxvdDIsIHBsb3RseSkuICZuYnNwOw0KICAgIEFsbCBhZ3JlZTwvdGV4dD4gDQogIDx0ZXh0IHg9MTkwIHk9MTQ4IGZvbnQtc2l6ZT0xMnB0IGZvbnQtc3R5bGU9aXRhbGljPg0KICAgIGJhc2UgUiBjb250YWlucyBtb3JlIHRoYW4gY2FuIGJlIHRhdWdodCBpbiBhbnksIGZ1bGwgeWVhciANCiAgICBzdGF0aXN0aWNzIGNvdXJzZS48L3RleHQ+DQo8L3N2Zz4NCmBgYA0KDQoNCiMjICZuYnNwOyBVbml2YXJpYXRlIGRhdGEgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gLi4uLi4uLmNvbW1lbnRzLi4uLi4uLiAtLT4NCg0KIyMjICZuYnNwOyBHZXQgcmFuZG9tIHNhbXBsZSBmcm9tIE5vcm1hbCBEaXN0cmlidXRpb24NCg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMiI+DQpUaGUgbGluZSBvZiBSIGNvZGUgYmVsb3csIGAgeTEgPC0gcm5vcm0oNjAsIDUwLCA5KSBgIGRyYXdzIGEgKipyYW5kb20gc2FtcGxlKiogb2YgDQpuPTYwIGZyb20gdGhlICoqbm9ybWFsIGRpc3RyaWJ1dGlvbioqIG9mIG1lYW4gNTAgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiA5LiANCg0KTm90ZSB0aGUgKiphc3NpZ25tZW50IG9wZXJhdG9yKiogYCA8LSBgICB0aGF0IHdlIHVzZSBpbiBSLCBub3QgdGhlIGVxdWFsIA0KY2hhcmFjdGVyIGAgPSBgLiAmbmJzcDsgQnV0LCB3ZSBkbyB1c2UgdGhlIGVxdWFsIHNpZ24gZm9yIGFyZ3VtZW50cyBpbiBmdW5jdGlvbiBjYWxscy4gDQogIA0KRWFybHkgb24gYXMgeW91J3JlIGxlYXJuaW5nIFIsIGl0IHBheXMgdG8gZ2V0IGNvbWZvcnRhYmxlIGdlbmVyYXRpbmcgKipmYWtlKiogDQpkYXRhOiAke1wgfSQgcmFuZG9tIGRyYXdzIGZyb20gc2F5LCB0aGUgKm5vcm1hbCBkaXN0cmlidXRpb24qIGAgcm5vcm0oKWAgLCB3aGljaCANCmlzIGJlbGwtc2hhcGVkLCB0aGUgKnVuaWZvcm0gZGlzdHJpYnV0aW9uKiBgIHJ1bmlmKClgICwgd2hpY2ggaXMgZmxhdC10b3BwZWQsIGFuZCANCnRoZSAqV2VpYnVsbCogZGlzdHJpYnV0aW9uIGAgcndlaWJ1bGwoKWAgd2hpY2ggaXMgdHJ1bmNhdGVkIG9uIHRoZSBsZWZ0IGFuZCANCnNrZXdlZCB0byB0aGUgcmlnaHQuIA0KDQpJIGNhbm5vdCBiZSBtb3JlIHNlcmlvdXMuIEdlbmVyYXRpbmcgYW5kIHVzaW5nICoqZmFrZSoqIGRhdGEgaXMgbm90IGp1c3QgYSANCioqdGVjaG5pcXVlKiosIGl0J3MgYSB3YXkgb2YgbGlmZSBmb3IgdGhlIGFuYWx5c3QhIA0KDQpJdCBlbmFibGVzIG9uZSB0byBnZXQgbnVtYmVycyB0byBleHBsb3JlIGFuZCB0byBsZWFybiBhIGZ1bmN0aW9uIGluIFIsIHRvIA0KdGVzdC92ZXJpZnkvbGVhcm4vY29tcGFyZSBjb21wZXRpbmcgc3RhdGlzdGljYWwgcHJvY2VkdXJlcywgYW5kIHRvIGFkZHJlc3MgcXVlc3Rpb25zIA0KYWJvdXQgb3VyIG9ic2VydmVkIGRhdGEsIHN1Y2ggYXMsICp3aGF0IG1pZ2h0IGhhcHBlbiBpZiBJIHJlcGVhdGVkIG1hbnkgdGltZXMsIG15IA0KZGF0YSBzYW1wbGluZyBkZXNpZ24gKGJ5IGEgc2ltaWxhciBzYW1wbGluZyBkZXNpZ24gaW4gTW9udGUgQ2FybG8pIGFuZCBzdGF0aXN0aWNhbCANCmFuYWx5c2lzIHNlcXVlbmNlKj8gICANCjwvZGl2PiANCg0KYGBge3IgY2FjaGU9RkFMU0UsIGNvbW1lbnQ9IiMjIiwgaGlnaGxpZ2h0PVRSVUUsIHByb21wdD1GQUxTRSwgdGlkeT1GQUxTRX0NCg0Kc2V0LnNlZWQoMTIzKSAjIHNlZWQgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IsIGZvciByZXBlYXRhYmlsaXR5LCBhcyBkZXNpcmVkDQoNCiMgZ2V0IDYwIHJhbmRvbSBudW1iZXJzIGZyb20gbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiBtZWFuIDUwLCBTRCA5OyBhc3NpZ24gdG8geTENCnkxIDwtIHJub3JtKDYwLCA1MCwgOSkgIyA+P3Jub3JtICBmb3IgaHRtbCBkb2N1bWVudGF0aW9uDQoNCnkxICAjIHByaW50IHRoZSBzYW1wbGUgYXQgUiBDb25zb2xlDQoNCmBgYA0KDQoNCjwhLS0gIG1hdGggTGFUZXggZm9udCBzaXplIDEwIGxldmVsczogc21hbGwsIG5vcm1hbHNpemUsIExhcmdlLCBMQVJHRSwgaHVnZSwgSHVnZSAtLT4gIA0KDQpcZXZlcnlkaXNwbGF5XGV4cGFuZGFmdGVye1x0aGVcZXZlcnlkaXNwbGF5XEh1Z2UgfSANCg0KPCEtLSBcYmVnaW57YWxpZ24qfQ0KcCh4O1xtdSxcc2lnbWFeMikgDQomPSBcZnJhY3sxfXtcc3FydHsyXHBpXHNpZ21hXjJ9fSBcZXhwXGJpZ2dsKCAtIFxmcmFjeyAoeCAtIFxtdSleMiB9IHsyIFxzaWdtYV4yfSBcYmlnZ3IpIFxcWzFleF0NClxlbmR7YWxpZ24qfSAgLS0+DQoNClRoaXMgaXMgbm90IHRoZSBwbGFjZSBmb3IgYSBmb3JtYWwgdHJlYXRtZW50IG9mIHRoZSAqKk5vcm1hbCBEaXN0cmlidXRpb24qKiwgdGhlIG1vc3QgDQppbXBvcnRhbnQgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGluIGFsbCAqU3RhdGlzdGljcyosIGFsdGhvdWdoIGEgYnJpZWYgDQppbnRyb2R1Y3Rpb24gZm9sbG93cy4gDQoNClRoZSAqKk5vcm1hbCBEaXN0cmlidXRpb24qKiBpcyBkZWZpbmVkIGJ5IDIgcGFyYW1ldGVyczogaXRzIG1lYW4sICR7bXV9JCBhbmQgDQpTdGFuZGFyZCBEZXZpYXRpb24sICR7c2lnbWF9JC4gSXQncyBhIGNvbnRpbnVvdXMgZGlzdHJpYnV0aW9uLCBzeW1tZXRyaWNhbCBhYm91dCANCml0cyBjZW50cmFsIHRlbmRlbmN5LiBUaGUgc28tY2FsbGVkLCAqc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbiogKipOKDAsIDEpKiogaGFzIA0KbWVhbj0wIGFuZCBTRD0xLiBPdXIgZmFrZSBkYXRhIGAgeTEgYCBpcyBhIHJhbmRvbSBzYW1wbGUgZnJvbSAqKk4oNTAsIDkpKiosIHVzaW5nIA0Kc3RhbmRhcmQgbm90YXRpb24uDQoNCg0KXGJlZ2lue2FsaWduKn0gVGhlXCBQREZcIG9mXCB0aGVcIG5vcm1hbFwgZGlzdHJpYnV0aW9uOlwgXCBcIGYoeCkgDQomPSBcZnJhY3sxfXtcc3FydHsyXHBpXHNpZ21hXjJ9fSBlXnsgLSBcZnJhY3soeCAtIFxtdSleMn0gezJcc2lnbWFeMn19IFxcWzFleF0NClxlbmR7YWxpZ24qfQ0KDQoNCjwhLS0gLi4uLi4uLiBhIDxkZXRhaWxzPiBkaXNjbG9zdXJlIGJveCB3aXRoIGEgIHZpc2libGUsIDxzdW1tYXJ5PiBoZWFkaW5nIHdpdGggLi4uDQogICAgIC4uLi4uLi4gYSAncG9pbnRlcicgdG8gY2xpY2sgLi4uLi4uLi4uLi4uLi4uLi4uLiAtLT4gDQogDQo8c3R5bGU+DQovKiAgIDwhLS0gZGV0YWlscz4gc3VtbWFyeXsgICAgICAgZGVmaW5lZCBkb3duIGFyb3VuZCBsaW5lIDM1MDAgIC0tPg0KICAgPCEtLSAgcGFkZGluZzogMnB4OyAgICAgICAgICAgICAgIC0tPg0KICAgPCEtLSAgYmFja2dyb3VuZC1jb2xvcjogR3JheTsgICAgICAtLT4NCiAgIDwhLS0gIGJveC1zaGFkb3c6IDJweCAycHggNnB4ICNiYmJiYmI7IGJvcmRlci1yYWRpdXM6IDEwcHggMTBweCAxMHB4IDEwcHg7IC0tPg0KICAgPCEtLSAgY29sb3I6IGJsYWNrOyAgICAtLT4NCiAgIDwhLS0gIGN1cnNvcjogcG9pbnRlcjsgLS0+DQogICA8IS0tICB9ICAgICAgICAgICAgICAgIC0tPg0KKi8NCg0KZGV0YWlscz4gcHsNCiAgd2lkdGg6IDcwMHB4OyAgDQogIGJhY2tncm91bmQtY29sb3I6IExpZ2h0R3JheTsgZm9udC1mYW1pbHk6IGNvbWljIHNhbnMgbXM7IGZvbnQtc2l6ZTogMTA1JTsNCiAgcGFkZGluZzogMTVweDsgbWFyZ2luOiAwOyBib3JkZXItcmFkaXVzOiAxMHB4IDEwcHggMTBweCAxMHB4OyBjb2xvcjogcmVkOw0KICBib3gtc2hhZG93OiAycHggMnB4IDZweCBibGFjazsNCn0gDQo8L3N0eWxlPg0KDQo8ZGV0YWlscz4NCiAgPHN1bW1hcnk+Q2xpY2sgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIA0KICA8c3Ryb25nPk5vcm1hbCBEaXN0cmlidXRpb248L3N0cm9uZz4gLS0gY2xpY2sgYWdhaW4gdG8gcmVtb3ZlIDwvc3VtbWFyeT4NCiAgDQogIDxwPlRoZSBOb3JtYWwgRGlzdHJpYnV0aW9uIGlzIGEgY29udGludW91cyBkaXN0cmlidXRpb24gZXh0ZW5kaW5nIGZyb20gbmVnYXRpdmUgDQogIGluZmluaXR5IHRvIHBvc2l0aXZlIGluZmluaXR5LCBhc3ltcHRvdGljYWxseS4gSXRzIHNoYXBlIGlzIHN5bW1ldHJpY2FsIG9uIGVpdGhlciANCiAgc2lkZSBvZiBpdHMgbWVhbi4gVGhlICoqbWVhbioqLCAqKm1vZGUqKiBhbmQgKiptZWRpYW4qKiBhcmUgdGhlIHNhbWUgbnVtYmVyLiBTb21lIA0KICBjYWxsIGl0IHRoZSAiYmVsbC1zaGFwZWQiIGN1cnZlLiBUaGUgZm9ybXVsYSBmb3IgdGhlIFBERiAoKipQKipyb2JhYmlsaXR5ICoqRCoqaXN0cmlidXRpb24gDQogICoqRioqdW5jdGlvbikgb2YgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gaXMgcHJlc2VudGVkIGFib3ZlIC0tLSBlbHNld2hlcmUsIHdlIA0KICBkZXZlbG9wIHZhcmlvdXMgZ3JhcGhpY2FsIHZpc3VhbGl6YXRpb25zIGFuZCBhc3Nlc3NtZW50cyBvZiBub3JtYWxpdHksIHVzaW5nIG91ciANCiAgY3VzdG9tIFIgY29kZSBhcyB3ZWxsIGFzIGJ5IGNhbGxpbmcgZnVuY3Rpb25zIGZyb20gUiBwYWNrYWdlcy4gPGJyPiAgDQogIFRoZSBOb3JtYWwgRGlzdHJpYnV0aW9uIGlzIHRoZSBtb3N0IGltcG9ydGFudCBkaXN0cmlidXRpb24gaW4gYWxsIFN0YXRpc3RpY3MuIFRoZXJlIA0KICBhcmUgaW1wb3J0YW50IHJlYXNvbnMgd2h5LiA8dT5GaXJzdDwvdT4sIG1hbnkgY29udGludW91cyBtZWFzdXJlbWVudCB2YXJpYWJsZXMgYXJlIA0KICBub3JtYWxseSBkaXN0cmlidXRlZCwgc3VjaCBhcyBodW1hbiBoZWlnaHQuIDx1PlNlY29uZDwvdT4sIHRoZSAqKkNlbnRyYWwgTGltaXQgVGhlb3JlbSoqIA0KICBob2xkcyB0aGF0IGFzIHNhbXBsZSBzaXplIGluY3JlYXNlcywgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW5zIGJlY29tZXMgbm9ybWFsbHkgDQogIGRpc3RyaWJ1dGVkIHRodXMgYWxsb3dpbmcgdHJhZGl0aW9uYWwsIDk1JSBDb25maWRlbmNlIEludGVydmFscyBmb3IgcG9wdWxhdGlvbiBtZWFucyANCiAgdG8gYmUgY2FsY3VsYXRlZCBiYXNlZCBvbiBhIHNpbmdsZSBvYnNlcnZlZCBtZWFuLCB1c2luZyBpdHMgU3RhbmRhcmQgRXJyb3IgKFNEL3NxcnQobikpIA0KICBhbmQgdGhlIHQtZGlzdHJpYnV0aW9uLiA8dT5UaGlyZDwvdT4sIG1hbnkgdHJhZGl0aW9uYWwsIHBhcmFtZXRyaWMgc3RhdGlzdGljYWwgDQogIHByb2NlZHVyZXMgKGUuZy4sIHQtdGVzdCwgQW5vdmEsIE9MUyBsaW5lYXIgcmVncmVzc2lvbiwgUGVhcnNvbiBjb3JyZWxhdGlvbikgaGF2ZSANCiAgYXNzdW1wdGlvbnMsIGFuZCBvbmUgb2YgdGhlc2UgaXMgdGhhdCB0aGUgb2JzZXJ2ZWQgZGF0YSBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIDxicj4gIA0KICBNYXRoZW1hdGljYWxseSBhbmQgY2F1c2FsbHkgaW4gdGhlIHBoeXNpY2FsIHdvcmxkLCB3aGF0IG1ha2VzIGEgPHU+cmVzcG9uc2UgdmFyaWFibGU8L3U+IA0KICBub3JtYWxseSBkaXN0cmlidXRlZD8gIA0KICA8YnI+VGhpbmsgYWJvdXQgKipodW1hbiBoZWlnaHQqKiAtLSB3aGF0IGNhdXNlcyBpdD8gPGJyPiBPYnZpb3VzbHksIHRoZXJlIGFyZSANCiAgZW52aXJvbm1lbnRhbCB2YXJpYWJsZXMgc3VjaCBhcyBzb2Npby1lY29ub21pY3MsIG51dHJpdGlvbiAoaXRzIHRpbWluZywgcXVhbGl0eSwgDQogIHF1YW50aXR5KSBhbmQgdGhlcmUgYXJlIGdlbmV0aWMgdmFyaWFibGVzIChtYW55IGdlbmVzIHBsdXMgZ2VuZGVyKS48YnI+ICANCiAgSW4gYnJpZWYsIG1hbnkgY2F1c2FsIGZhY3RvcnMgZWFjaCB3aXRoIHNtYWxsLCBhZGRpdGl2ZSBlZmZlY3RzIGFuZCBlYWNoIA0KICBmYWN0b3IgaW5kZXBlbmRlbnQgb2YgdGhlIG90aGVycywgZ2VuZXJhdGUgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBJbiBtYXRoLCANCiAgdGhlIGV4cGFuc2lvbiBvZiB0aGUgYmlub21pYWwgZGlzdHJpYnV0aW9uIGdlbmVyYXRlcyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgDQogIGJ5IHRoZSBzYW1lIHByb2Nlc3MuIEdhbHRvbidzICJiZWFuIGJveCIgZnJvbSB0aGUgbGF0ZSAxOXRoIENlbnR1cnksIA0KICBkZW1vbnN0cmF0ZXMgdGhpcyBtZWNoYW5pY2FsbHkgYnkgbWFjaGluZSBidXQgd2Ugd2lsbCB1c2UgYSBHSUYgYW5pbWF0ZWQgc2ltdWxhdGlvbiANCiAgaW4gUiwgdXNpbmcgdGhlICJhbmltYXRpb24iIHBhY2thZ2UuIDxicj48YnI+QWxsIHN0YXRpc3RpY3MgdGV4dGJvb2tzIGRlbGl2ZXIgc29saWQgDQogIHRyZWF0bWVudHMgb2YgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24sIGFzIHdlbGwgYXMgc2F5LCANCiAgV2lraXBlZGlhLCBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ob3JtYWxfZGlzdHJpYnV0aW9uIA0KICA8L3A+DQogIA0KPC9kZXRhaWxzPiAgDQoNCg0KDQoNCg0KDQoNCiANCjxicj48YnI+ICANCg0KIyMjICZuYnNwOyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzICANCg0KPGJyPiANClJlY292ZXJpbmcgYSBzdGFuZGFyZCBzZXQgb2YgPGI+ZGVzY3JpcHRpdmUgc3RhdGlzdGljczwvYj4gaXMgYWx3YXlzIGFuIGVhcmx5IHRhc2sgDQppbiBkYXRhIGFuYWx5c2lzLCBhbmQgdGhlcmUgYXJlIG1hbnkgZGlmZmVyZW50IHdheXMgdG8gZG8gaXQuIFRoZSBgZGVzY3JpYmUoKSBgIA0KZnVuY3Rpb24gaW4gdGhlIGBwc3ljaCBgIHBhY2thZ2UgaXMgaGFuZHkuIENSQU4gcGFja2FnZSBgIHBzeWNoIGAgaXMgYnkgUHJvZmVzc29yIA0KV2lsbGlhbSBSZXZlbGxlLCBEZXBhcnRtZW50IG9mIFBzeWNob2xvZ3ksIE5vcnRod2VzdGVybiBVbml2ZXJzaXR5LiBIaXMgcGFja2FnZSBoYXMgDQptYW55IGZ1bmN0aW9ucy4gQXQgdGhlIFIgQ29uc29sZSwgYD4gP2Rlc2NyaWJlYCAgYnJpbmdzIHVwIEhUTUwgZG9jdW1lbnRhdGlvbiwgaW4gYSANCmZvcm1hdCBzdGFuZGFyZGl6ZWQgYWNyb3NzIGFsbCBmdW5zIGluIGFsbCBDUkFOIHBhY2thZ2VzLiANCkFzIGFuIGFzaWRlLCB3ZSBvZnRlbiBhYmJyZXZpYXRlIDxtYXJrPiBmdW4gPC9tYXJrPiAgZm9yIGZ1bmN0aW9uLCA8bWFyaz4gYXJnIDwvbWFyaz4gDQpmb3IgYSBmdW5jdGlvbiBhcmd1bWVudCBhbmQgPG1hcms+IGZvbyA8L21hcms+IGZvciBhIGR1bW15IG5hbWUgc2F5LCA8bWFyaz4gZm9vLlIgPC9tYXJrPiANCmFzIGEgZ2VuZXJpYyBSIEVkaXRvciBmaWxlLg0KDQpGcm9tIGl0cyBkb2N1bWVudGF0aW9uLCB0aGUgYGRlc2NyaWJlKClgIGZ1biBoYXMgdGhlc2UgYXJncywgYnV0IGhlcmUsIHdlIG5lZWQgb25seSANCm9uZSBhcmcsIHRoZSBmaXJzdCBhcmcsIHdoaWNoIGlzIHRoZSBuYW1lIG9mIHRoZSB1bml2YXJpYXRlIHNhbXBsZSAobnVtZXJpYyANCnZlY3RvciBpbiBSKS4gSW4gYWxsIFIgZnVucyB0aGUgbW9zdCBpbXBvcnRhbnQgYXJncyBhcmUgbGlzdGVkIGZpcnN0OyBhcmdzIG9mdGVuIA0KaGF2ZSBkZWZhdWx0IHZhbHVlcy4gV2hlbiBsZWFybmluZyBob3cgdG8gdXNlIGEgZnVuIHRoYXQncyBuZXcgdG8gdXMsIHdlIGFsd2F5cyBiZWdpbiANCndpdGggYSBtaW5pbWFsIGNhbGwgdG8gdGhhdCBmdW5jdGlvbiBhbmQgZXhwbGljaXRseSBhZGQgYXJncyB0byB0aGUgZnVuIGNhbGwsIGFzIA0KbmVlZGVkLiBIZXJlLCB3ZSBuZWVkIG9ubHkgb25lIGFyZzogYHlgLg0KDQo8cHJlPmRlc2NyaWJlKHgsIG5hLnJtPVRSVUUsIGludGVycD1GQUxTRSwgc2tldz1UUlVFLCByYW5nZXM9VFJVRSwgdHJpbT0uMSwgdHlwZT0zLCANCiAgICAgICAgICAgY2hlY2s9VFJVRSwgZmFzdD1OVUxMLCBxdWFudD1OVUxMLCBJUVI9RkFMU0UsIG9taXQ9RkFMU0UsIGRhdGE9TlVMTCk8L3ByZT4NCg0KUm91bmQtb2ZmIG1heSBiZSBjb250cm9sbGVkIGlmIHRoZSBvYmplY3QgcmV0dXJuZWQgYnkgYGRlc2NyaWJlKCkgYCBpcyBwcmludGVkIA0KdXNpbmcgYCBwcmludCgpIGAgd2hpY2ggaXMgYW4gZXh0cmVtZWx5IGltcG9ydGFudCBhbmQgZmxleGlibGUsIGZ1bmN0aW9uIGluIGJhc2UgUi4gDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHBzeWNoKSAjIGxvYWQgcGFja2FnZSBmcm9tIGhhcmQgZHJpdmUsIGludG8gbWVtb3J5IGF0IFIgQ29uc29sZQ0KDQpkZXNjcmliZSh5MSkgIyBhIGZ1biBpbiBwYWNrYWdlICdwc3ljaCcNCg0KcHJpbnQoZGVzY3JpYmUoeTEpLCBkaWdpdHM9MykgIyBwcmludCgpIGlzIGFuIGltcG9ydGFudCBmdW5jdGlvbiBpbiBiYXNlIFINCg0KYGBgDQoNCkFsdGVybmF0aXZlbHksIG1vc3QgUiB1c2VycyB3cml0ZSB0aGVpciBvd24gc2hvcnQgZnVuY3Rpb25zIGZvciBtYW55IHRoaW5ncywgDQppbmNsdWRpbmcgZGVzY3JpcHRpdmUgc3RhdGlzdGljcy4gT25lIG9mIG1pbmUgaXMgYG5ldy5zdGF0cygpYCBhcyBkZWZpbmVkIGluIG15LCANCmBLIGZ1bnMgVU5JVkFSSUFURS5SIGAgYW4gUiBFZGl0b3IgZmlsZSBvZiBmdW5jdGlvbiBkZWZpbml0aW9ucy4gVGhlIGBub3JtLnRlc3RgIA0KYXJndW1lbnQgaW4gdGhlIGNhbGwgdG8gYG5ldy5zdGF0cygpYCB0dXJucyBvbiBhIGJhdGNoIG9mIGdvb2RuZXNzIG9mIGZpdCB0ZXN0cyANCm9mIG5vcm1hbGl0eSwgdG8gaW5mb3JtIHRoZSBjdXJpb3VzIGFuYWx5c3QuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQpuZXcuc3RhdHMoeTEsIGRhdGEubmFtZT0ic2ltIGRhdGEiKSAjIGZyb206IEsgZnVucyBVTklWQVJJQVRFLlINCg0KbmV3LnN0YXRzKHkxLCBub3JtLnRlc3Q9VFJVRSkgIyBhZGQgbm9ybWFsaXR5IHRlc3RzDQpgYGANCjxicj4gIA0KDQo8IS0tICBibHVlIGVsbGlwc2UgLSByYWRpYWwgZ3JhZGllbnQgZm9yIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MgLi4uLi4uLi4uLi4uLi4gLS0+DQoNCmBgYHs9aHRtbH0NCg0KPHN2ZyBoZWlnaHQ9IjI1MCIgd2lkdGg9IjkxMCI+DQogIDxkZWZzPg0KICAgIDxyYWRpYWxHcmFkaWVudCBpZD0iZ3JhZDMiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSIgZng9IjUwJSIgZnk9IjUwJSI+DQogICAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjpyZ2IoMjU1LDI1NSwyNTUpO3N0b3Atb3BhY2l0eTowIiAvPg0KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjpyZ2IoMCwwLDI1NSk7c3RvcC1vcGFjaXR5OjEiIC8+DQogICAgPC9yYWRpYWxHcmFkaWVudD4NCiAgPC9kZWZzPg0KICA8ZWxsaXBzZSBjeD0iMTcwIiBjeT0iNzUiIHJ4PSIxMzAiIHJ5PSI3MyIgZmlsbD0idXJsKCNncmFkMykiIC8+DQogIDx0ZXh0IGZpbGw9ImJsYWNrIiBmb250LXNpemU9MjJwdCBmb250LWZhbWlseT0iQXJpYWwgYmxhY2siPg0KICANCiAgPHRzcGFuIHg9ODAgIHk9NjQ+ICAgICBEZXNjcmlwdGl2ZSA8L3RzcGFuPg0KICA8dHNwYW4geD0xMTYgIGR5PTEuNGVtPiAgU3RhdGlzdGljcyAgPC90c3Bhbj4NCiAgPC90ZXh0Pg0KICANCiAgPHRleHQgeD0yODAgeT0wIGR5PTFlbSBmb250LXNpemU9MTNwdCBmb250LXN0eWxlPWl0YWxpYz4NCiAgPHRzcGFuPiBSZWNvdmVyaW5nIGEgc3RhbmRhcmQgc2V0IG9mIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIG9uZSBvciBtb3JlIHNhbXBsZXMsPC90c3Bhbj4gDQogIDx0c3BhbiB4PTMwMCBkeT0xLjFlbT5tYXJrcyBhIGJlZ2lubmluZyBvZiBzdGF0aXN0aWNhbCBhbmFseXNpcy4gRGVzY3JpcHRpdmUgc3RhdHMgYXJlIGFsd2F5czwvdHNwYW4+DQogIDx0c3BhbiB4PTMyMCBkeT0xLjFlbT5yZXBvcnRlZCBpbiB0YWJsZXMgYW5kL29yIGluIHByb3NlLiBBdCBsZWFzdCAzIHN0YXRzIG11c3QgYmUgcmVwb3J0ZWQgLS08L3RzcGFuPg0KICA8dHNwYW4geD0zMjAgZHk9MS4xZW0+c2FtcGxlIHNpemUsIGEgc3RhdCBvZiBjZW50cmFsIHRlbmRlbmN5LCBhIHN0YXQgb2YgdmFyaWFiaWxpdHkuIFRoZXNlIG1heTwvdHNwYW4+DQogIDx0c3BhbiB4PTMyMCBkeT0xLjFlbT5pbmNsdWRlIG9uIHRoZSBtb21lbnRzIHNpZGU6IG4sIG1lYW4sIFNEIChvciBTRU0pIGFuZCBvbiB0aGUgcXVhbnRpbGU8L3RzcGFuPg0KICA8dHNwYW4geD0zMjAgZHk9MS4xZW0+c2lkZTogbiwgbWVkaWFuLCBJUVIuIE90aGVyIGRlc2NyaXB0aXZlIHN0YXRzIGluY2x1ZGUgbWluLCBtYXgsIENvZWZmaWNpZW50PC90c3Bhbj4NCiAgPHRzcGFuIHg9MzAwIGR5PTEuMWVtPm9mIFZhcmlhdGlvbiAoQ1YgPSBTRC9tZWFuKSwgc2tld25lc3MgKDNyZCBtb21lbnQsIGFzeW1tZXRyeSkgPC90c3Bhbj4NCiAgPHRzcGFuIHg9MjgwIGR5PTEuMWVtPmFuZCBrdXJ0b3Npcyg0dGggbW9tZW50LCBwZWFrZWRuZXNzKS48L3RzcGFuPg0KICANCiAgPHRzcGFuIHg9MzUgZHk9MS4xZW0+IkRlc2NyaXB0aXZlIHN0YXRpc3RpY3MiIGxlYWQgdG8gRWZmZWN0IFNpemVzLCBDb25maWRlbmNlIEludGVydmFscywgYW5kICANCiAgICB0byBzaWduaWZpY2FuY2UgdGVzdHMgb3IgQmF5ZXNpYW4gYW5hbHlzZXMuPC90c3Bhbj4NCiAgPC90ZXh0PiANCjwvc3ZnPg0KDQpgYGANCg0KDQoNCiMjIyAmbmJzcDsgSGlzdG9ncmFtIC0tLSB2aXN1YWxpemF0aW9uIG9mIHRoZSBzaGFwZSBvZiB0aGUgZGF0YSAgPCEtLSAuLiAxMy4xLjIgLi4gLS0+DQoNCj4gTGV0J3MgdXNlIGEgKipoaXN0b2dyYW0qKiB0byB2aXN1YWxpemUgdGhlIGFib3ZlIHNhbXBsZSBgeTFgIG9mIG49NjAuIA0KDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyIj4NClRoZSBoaXN0b2dhbSBpcyBhIGdyYXBoIHRoYXQncyB3ZWxsIGtub3duIGFuZCB1bmRlcnN0b29kIGJ5IGFsbCBlZHVjYXRlZCANCmZvbGtzIGFjcm9zcyBhbGwgc2Nob2xhcmx5IGRpc2NpcGxpbmVzLCB3b3JsZHdpZGUuIEl0J3MgdGF1Z2h0IGluIGdyYWRlIHNjaG9vbC4gIDxicj4gICANCkhpc3RvZ3JhbXMgYXJlIGFzIGluc3RhbnRseSByZWNvZ25pemVkIGFzIHNheSwgdGhlIHdvcmRzICpETkEqIGFuZCAqSG9tbyANCnNhcGllbnMqLiBObyBtYXR0ZXIgdGhlIHNjaWVudGlmaWMgam91cm5hbCBvciBob3cgYWR2YW5jZWQgdGhlIHRvcGljIG9mIHRoZSByZXNlYXJjaCwgDQpoaXN0b2dyYW1zIGFyZSB1c2VkIHRvIHZpc3VhbGl6ZSB0aGUgKipkaXN0cmlidXRpb24qKiBvZiB0aGUgZGF0YS4gIA0KPGJyPiANCkkgcHJvdmUgdGhpcyBwb2ludCBkdXJpbmcgY2xhc3MgYnkgc2hvd2luZyB5b3UgDQpjdXJyZW50IGlzc3VlcyBvZiBsZWFkaW5nIGpvdXJuYWxzLCBpbmNsdWRpbmcgKlNjaWVuY2UqLCAqU2NpZW5jZSBBZHZhbmNlcyosIA0KKlBOQVMqLCAqTkVKTSogYW5kICpOYXR1cmUqLiANCg0KSW4gc3RhdGlzdGljcywgd2hhdCBkbyB3ZSBtZWFuIGJ5IGEgKipkaXN0cmlidXRpb24qKj8gSXQncyB0aGUgcmFuZ2Ugb2YgdGhlIGRhdGEgDQpmcm9tIHRoZSBtaW5pbXVtIHRvIHRoZSBtYXhpbXVtIHZhbHVlOyBpdCdzIHRoZSBjZW50cmFsIHRlbmRlbmN5IG9yIHBlYWtzOyBpdCdzIA0KdGhlIGRpc3BlcnNpb24gb2YgdGhlIGRhdGEgYWJvdXQgdGhlIGNlbnRyYWwgdGVuZGVuY3k7IGl0J3MgdGhlIGRhdGEgZ3JvdXBlZCANCmludG8gaW50ZXJ2YWxzIHNwYW5uaW5nIHRoZSByYW5nZSBvZiB0aGUgZGF0YS4gSGlzdG9ncmFtcyBkaXNwbGF5IHRoZSANCmRpc3RyaWJ1dGlvbiBvZiBzaW5nbGUgc2FtcGxlcyBvZiBkYXRhLiANCjwvZGl2PiA8YnI+IA0KDQo+ICoqRm9yIG1lLCBhIGhpc3RvZ3JhbSBoZWxwcyBtZSBzZWUgdGhlICJzaGFwZSIgb2YgdGhlIGRhdGEuKiogICAgIA0KDQo8YnI+IA0KDQpJbiBSIGNvZGluZywgKipDb21tZW50cyoqIGJlZ2luIHdpdGggdGhlIGhhc2h0YWcgKiojKiogYW5kIGFyZSBpZ25vcmVkIGJ5IFIgDQooY29kZSB0byB0aGUgcmlnaHQgb2YgIyBpcyBpZ25vcmVkKS4gQ29tbWVudHMgYXJlIGZvciB0aGUgaHVtYW4uIFlvdSB3aWxsIA0KcXVpY2tseSBsZWFybiB0byBhcHByZWNpYXRlIGNvbW1lbnRzIGFzIHlvdSB3aXNlbHkgbGF2aXNoIHRoZW0gb24geW91ciBjb2RlLg0KDQoNCg0KYGBge3IsIGZpZy5jYXA9IkRpc3RyaWJ1dGlvbiBvZiB5MSBieSBhIG1pbmltYWwgY2FsbCB0byBoaXN0KCApLCAnZHJhZnQgcXVhbGl0eScifQ0KDQpoaXN0KHkxKSAjIGZyZXF1ZW5jeSBoaXN0b2dyYW0gb2YgeTE7IG1pbmltYWwgY2FsbCB0byBoaXN0KCkgd2hpY2ggaGFzIG1hbnkgYXJncw0KDQpgYGANCg0KPGJyPiAgDQoNClRoZSBoaXN0b2dyYW0gYWJvdmUsIGdyYXBocyB0aGUgdGFidWxhciwgImZyZXF1ZW5jeSBkaXN0cmlidXRpb24iIHdoaWNoIGlzIGNhbGN1bGF0ZWQgDQpieSBhIHNob3J0IGZ1bmN0aW9uIEkgd3JvdGUsIGAgZnJlcS50YWJsZSgpIGAgd2hpY2ggPHU+ZXh0cmFjdHM8L3U+IHZlY3RvcnMgZnJvbSB0aGUgDQpgIGhpc3QoKSBgIG9iamVjdC4gVGhlIGZ1bmN0aW9uIGRlZmluaXRpb24gZm9yIGBmcmVxLnRhYmxlKCkgYCBpcyBsaXN0ZWQgYmVsb3cgDQp0aGVuIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgYW5kIGl0IHJldHVybnMgYSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIHRhYmxlIGZvciBgIHkxIGAuDQoNCg0KPCEtLSBwcmludCBmdW4gZGVmIGZvciBmcmVxLnRhYmxlKCkgZnJvbSAnSyBmdW5zIFVOSVZBUklBVEUuUicgYnkgcGFzdGUgaGVyZSAtLT4NCjxicj4NCg0KPHByZSBpZD0ic3R5bGVNeUNvZGVCbG9jayI+DQpmcmVxLnRhYmxlIDwtIGZ1bmN0aW9uKHk9cm5vcm0oMWUyLCA1MCwgMTApLCByb3VuZG9mZj00LCAuLi4gKXsNCg0KICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiAgIyAgQVJHVU1FTlRTICAgICBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIFRBQkxFIGZvciBhIG51bWVyaWMgdmVjdG9yDQogICMNCiAgIyAgeSAgICAgICAgIG51bWVyaWMgdmVjdG9yIGZvciBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIHRhYmxlDQogICMgICAgICAgICAgICBtaXNzaW5nIHZhbHVlcyBPSw0KICAjDQogICMgIHJvdW5kb2ZmICBkZWZhdWx0OiA0IGRlY2ltYWwgcGxhY2VzDQogICMNCiAgIyAgLi4uICAgICAgIGFyZ3MgdG8gaGlzdCgpIHRoYXQncyBvbmx5IHVzZWQgZm9yIGV4dHJhY3Rpb24sICANCiAgIyAgICAgICAgICAgICAgICBlLmcuLCBicmVha3M9MjIsIGJyZWFrcz0ic3R1cmdlcyIsICJzY290dCIsICJmZCINCiAgIw0KICAjICBGdW5jdGlvbiBSRVRVUk5TIGEgZGF0YSBmcmFtZSBieSBFWFRSQUNUSU9OIGZyb20gaGlzdCgpIG9iamVjdCAgDQogICMgIA0KICAjICBOb3RlOiBmb3IgdGhlIGJpbnMsIGl0J3MgICA+IC4uLiA8PSAgICdsZWZ0IG9wZW4sIHJpZ2h0IGNsb3NlZCcNCiAgIyAgICAgICAgZnVuY3Rpb24gbWF5IGJlIGNhbGxlZCBkZXZvaWQgb2YgYXJndW1lbnRzLCBhcyBhIERFTU8NCiAgIyAgIA0KICAjICBBVVRIT1I6IER3aWdodCBLaW5jYWlkLCBQaEQgICBkd2lnaHQua2luY2FpZEBsZWhtYW4uY3VueS5lZHUNCiAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiAgc3RvcGlmbm90KGlzLm51bWVyaWMoeSksIGxlbmd0aCh5KSA+IDEpICAjIGFyZ3VtZW50IGNoZWNraW5nDQogIHkgPC0geVshaXMubmEoeSldICAgICAgICAgICAgICAgICAgICAgICAgIyByZW1vdmUgTkEsIG1pc3NpbmcgdmFsdWVzDQoNCiAgYSA8LSBoaXN0KHksIHBsb3Q9RkFMU0UsIC4uLikgIyB0byBleHRyYWN0IGZyb20gaGlzdCgpIG9iamVjdA0KICB3aWR0aCAgICA8LSBhJG1pZHNbMl0gLSBhJG1pZHNbMV0gICAgICAgICAgICAgICAgIyBXaWR0aCBvZiBoaXN0IGJpbnMNCiAgTC5sZXZlbCAgPC0gcm91bmQoYSRtaWRzIC0gKHdpZHRoLzIpLCByb3VuZG9mZikgICMgdmVjdG9yOiBMb3dlciBib3VuZHMNCiAgVS5sZXZlbCAgPC0gcm91bmQoYSRtaWRzICsgKHdpZHRoLzIpLCByb3VuZG9mZikgICMgdmVjdG9yOiBVcHBlciBib3VuZHMNCiAgbXkubGV2ZWwgPC0gcGFzdGUoTC5sZXZlbCwgIiwiLCBVLmxldmVsLCBzZXA9IiIpICMgY2hhcmFjdGVyIHZlY3Rvcg0KDQogIE4gPC0gbGVuZ3RoKHkpICMgTiBvZiByZXNwb25zZSB2YXJpYWJsZQ0KDQogICMgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiB0YWJsZSBieSBleHRyYWN0aW9uIGZyb20gaGlzdCgpIG9iamVjdCAnYScNCiAgZGZyIDwtIGRhdGEuZnJhbWUoaW50ZXJ2YWwgID0gMTpsZW5ndGgoYSRtaWRzKSwNCiAgICAgICAgICAgICAgICAgICAgY2xhc3MgICAgID0gbXkubGV2ZWwsICANCiAgICAgICAgICAgICAgICAgICAgbWlkcHQgICAgID0gYSRtaWRzLCANCiAgICAgICAgICAgICAgICAgICAgRlJFUSAgICAgID0gYSRjb3VudHMsDQogICAgICAgICAgICAgICAgICAgIHJlbC5mcmVxICA9IHJvdW5kKGEkY291bnRzL04sIHJvdW5kb2ZmKSwNCiAgICAgICAgICAgICAgICAgICAgY3VtLmYgICAgID0gY3Vtc3VtKGEkY291bnRzKSwgDQogICAgICAgICAgICAgICAgICAgIGN1bS5yZWwuZiA9IHJvdW5kKGN1bXN1bShhJGNvdW50cy9OKSwgcm91bmRvZmYpLA0KICAgICAgICAgICAgICAgICAgICBkZW5zaXR5ICAgPSByb3VuZChhJGRlbnNpdHksIHJvdW5kb2ZmKSkNCg0KICByZXR1cm4oZGZyKSAgICMgZGF0YSBmcmFtZSBvYmplY3QgcmV0dXJuZWQgDQoNCn0gIyBlbmQgZnVuY3Rpb24gZGVmaW5pdGlvbg0KDQo8L3ByZT4NCg0KPGJyPiANCkNvbnRpbnVpbmcgd2l0aCBgIHkxIGAgb2Ygbj02MCwgbGV0J3MgZ2V0IHRoZSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIHRhYmxlIGZvciANCmBicmVha3M9NGAgYXJndW1lbnQgaW4gdGhlIGNhbGwgdG8gYGZyZXEudGFibGUoKWAgd2hpY2ggY2FuIHBhc3MgYXJndW1lbnRzIHRvIA0KYGhpc3QoKWAgYnkgaXRzIGZpbmFsLCBgLi4uYCBhcmd1bWVudCwgb2Z0ZW4gY2FsbGVkICpkb3QtZG90LWRvdCouIA0KDQpgYGB7cn0NCiMgJ2JyZWFrcycgYXJnIHBhc3NlZCB0byBoaXN0KCkgd2hpY2ggbWF5IG5vdCBkZWxpdmVyICdleGFjdGx5JyB0aGUgYnJlYWtzIHNwZWNpZmllZA0KDQpmcmVxLnRhYmxlKHkxLCBicmVha3M9NCkgDQoNCmBgYA0KDQpMYXJnZSBzYW1wbGUgc2l6ZXMgYXJlIG5vdCBhIHByb2JsZW0gZm9yIHRoaXMgZnVuY3Rpb24uDQoNCmBgYHtyIGNhY2hlPVRSVUV9DQoNCmZyZXEudGFibGUocm5vcm0oNmU3KSwgcm91bmRvZmY9OCkgIyByYW5kb20gc2FtcGxlIG9mIDYwIG1pbGxpb24gZnJvbSBOKDAsMSkNCg0KYGBgDQoNCmBgYHs9aHRtbH0NCg0KPCEtLSAgYmx1ZSBlbGxpcHNlIC0gcmFkaWFsIGdyYWRpZW50IGZvciAnSGlzdG9ncmFtJyB0ZXh0IC4uLi4uLi4uLi4uLiAtLT4NCg0KPHN2ZyBoZWlnaHQ9IjE1MCIgd2lkdGg9IjgwMCI+DQogIDxkZWZzPg0KICAgIDxyYWRpYWxHcmFkaWVudCBpZD0iZ3JhZDMiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSIgZng9IjUwJSIgZnk9IjUwJSI+DQogICAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjpyZ2IoMjU1LDI1NSwyNTUpO3N0b3Atb3BhY2l0eTowIiAvPg0KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjpyZ2IoMCwwLDI1NSk7c3RvcC1vcGFjaXR5OjEiIC8+DQogICAgPC9yYWRpYWxHcmFkaWVudD4NCiAgPC9kZWZzPg0KICA8ZWxsaXBzZSBjeD0iMjAwIiBjeT0iNzAiIHJ4PSIxMjAiIHJ5PSI1NSIgZmlsbD0idXJsKCNncmFkMykiIC8+DQogIDx0ZXh0IGZpbGw9ImJsYWNrIiBmb250LXNpemU9MjJwdCBmb250LWZhbWlseT0iQXJpYWwgYmxhY2siIHg9IjEyNSIgeT0iODIiPkhpc3RvZ3JhbTwvdGV4dD4NCiAgICBTb3JyeSwgeW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgaW5saW5lIFNWRy4NCiAgDQogIDx0ZXh0IHg9MzQwIHk9MjAgZHk9MWVtIGZvbnQtc2l6ZT0xNHB0IGZvbnQtc3R5bGU9aXRhbGljPg0KICA8dHNwYW4+IFRoZSBoaXN0b2dyYW0gdmlzdWFsaXplcyB0aGUgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbjwvdHNwYW4+IA0KICA8dHNwYW4geD0zNDAgZHk9MS40ZW0+dGFibGUgZm9yIGEgc2FtcGxlIG9mIG51bWVyaWMgZGF0YS4gSXQgcmV2ZWFscyB0aGU8L3RzcGFuPg0KICA8dHNwYW4geD0zNDAgZHk9MS40ZW0+InNoYXBlIiBvZiB0aGUgZGF0YSAtLSB0aGUgY2VudGVyLCB0aGUgc3ByZWFkLCB0aGU8L3RzcGFuPg0KICA8dHNwYW4geD0zNDAgZHk9MS40ZW0+ZXh0cmVtZXMsIHRoZSBwZWFrZWRuZXNzLCB0aGUgYXN5bW1ldHJ5LCBhbmQgbW9yZS48L3RzcGFuPg0KICA8L3RleHQ+DQogIA0KPC9zdmc+DQpgYGANCg0KPGJyPiAgDQoNCiMjIyAmbmJzcDsgQW5ub3RhdGlvbiBvZiBoaXN0b2dyYW0gICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQpIb3cgaGFyZCB3b3VsZCBpdCBiZSB0byBhbm5vdGF0ZSB0aGUgYWJvdmUgaGlzdG9ncmFtIHdpdGggdGhlIHNhbXBsZSBtZWFuIGFuZCANCnN0YW5kYXJkIGRldmlhdGlvbiwgdGhlIHAtdmFsdWUgZnJvbSBTaGFwaXJvLVdpbGsgdGVzdCBvZiBub3JtYWxpdHksIHR1cm4gb2ZmIHRoZSANCmdyYXBoIHRpdGxlLCBjaGFuZ2UgdGhlIHgtYXhpcyBsYWJlbCwgaW5jcmVhc2UgZm9udCBzaXplIG9mIHRoZSBsYWJlbHMsIHJvdGF0ZSB0aGUgDQp5LWF4aXMgbGFiZWxzLCBjb2xvciB0aGUgYmFycywgYW5kIGdldCByaWQgb2YgdGhlIGJsYWNrIGluayAoKnNlbnN1KiBFZHdhcmQgVHVmdGUpIA0KYXJvdW5kIHRoZSBoaXN0b2dyYW0gYmFycz8gV2UgdXNlIG1vcmUgYXJndW1lbnRzIHRvIG91ciBjYWxsIG9mIHRoZSAqKmZ1bmN0aW9uKiogDQpgaGlzdCgpYC4gRnVuY3Rpb24gKiphcmd1bWVudHMqKiBhcmUgc2VwYXJhdGVkIGJ5IGNvbW1hcy4gVGhlIGBtdGV4dCgpYCBhbmQgYCB0ZXh0KCkgYCANCmZ1bmN0aW9ucyBhcmUgaGFuZHkgZm9yIGFubm90YXRpbmcgZ3JhcGhzLiBOb3RpY2UgaG93IEkgYWRkIGEgKipzcGFjZSoqIGFmdGVyIGEgDQoqKmNvbW1hKiogaW4gZnVuY3Rpb24gY2FsbHM7IHRoaXMgaXMgd2lzZSBjb2RpbmcgcHJhY3RpY2UgYXMgaXQgZWFzZXMgY29kZSBlZGl0aW5nIA0KYW5kIGVuaGFuY2VzIHJlYWRhYmlsaXR5OyBSIGRvZXMgbm90ICpuZWVkKiB0aGUgc3BhY2UgYnV0IHRoZSBodW1hbiBkb2VzLiANCg0KRnVuY3Rpb25zIGFuZCB0aGVpciBhcmd1bWVudHMgYXJlICoqc21hbGwqKiwgKipyZXVzYWJsZSB0b29scyoqIGluIFIuIA0KDQo8YnI+ICANCg0KDQo+ICR7XExhcmdlXCBUbyBcIHVzZVwgUlwgaXNcIHRvXCBjYWxsXCBmdW5jdGlvbnNcIH0kICAgPCEtLSBsYXJnZSBMYXJnZSBMQVJHRSAtLT4NCj4gLS0tIEpvaG4gQ2hhbWJlcnMNCg0KYGBge3IsIGZpZy5jYXA9IkFubm90YXRlZCBoaXN0b2dyYW0ifQ0KDQptIDwtIHJvdW5kKG1lYW4oeTEpLCAyKSAgICAgICAgICAgIyBnZXQgbWVhbiBvZiB5MSBhbmQgcm91bmQgb2ZmIHRvIDIgZGVjaW1hbHMNCnMgPC0gcm91bmQoc2QoeTEpLCAzKSAgICAgICAgICAgICAjIGdldCBTRCBvZiB5MSBhbmQgcm91bmQgb2ZmDQpwIDwtIHJvdW5kKHNoYXBpcm8udGVzdCh5MSkkcCwgMykgIyBleHRyYWN0IHAtdmFsdWUsIFNoYXBpcm8tV2lsayB0ZXN0IG9mIG5vcm1hbGl0eQ0KDQpoaXN0KHkxLCANCiAgICAgY29sPSJsaWdodGJsdWUiLCAgICAjIGNvbG9yIG9mIGhpc3RvZ3JhbSwgZGVmYXVsdCAibGlnaHRncmF5Ig0KICAgICBtYWluPU5VTEwsICAgICAgICAgICMgc3RyaW5nIGZvciB0aXRsZSBvZiBoaXN0b2dyYW07IE5VTEwgb21pdHMgaXQNCiAgICAgY2V4LmxhYj0xLjQsIGNleC5heGlzPTEuMywgbGFzPTEsICAgIyB0eXBvZ3JhcGh5DQogICAgIGJvcmRlcj0id2hpdGUiLCAgICAgICAgICAgICAgICAgICAgICMgY29sb3Igb2YgbGluZXMgYXJvdW5kIGhpc3RvZ3JhbSBiYXJzDQogICAgIHhsYWI9IlJhbmRvbSBzYW1wbGUgZnJvbSBOKDUwLCA5KSIpICMgeC1heGlzIGxhYmVsDQoNCmNsciA8LSAiZGFya3JlZCIgIyBjb2xvciBvZiB0ZXh0DQptdGV4dChwYXN0ZSgiTiA9IiwgbGVuZ3RoKHkxKSksICAgICAgICAgICBhZGo9Ljk1LCBsaW5lPSAwLCBjZXg9LjkxLCBjb2w9Y2xyKQ0KbXRleHQocGFzdGUoIk1lYW4gPSIsIG0pLCAgICAgICAgICAgICAgICAgYWRqPS45NSwgbGluZT0tMSwgY2V4PS45MSwgY29sPWNscikNCm10ZXh0KHBhc3RlKCJTRCA9IiwgcyksICAgICAgICAgICAgICAgICAgIGFkaj0uOTUsIGxpbmU9LTIsIGNleD0uOTEsIGNvbD1jbHIpDQptdGV4dChwYXN0ZSgiU2hhcGlyby1XaWxrIHRlc3RcbnAgPSIsIHApLCBhZGo9LjAzLCBsaW5lPS0xLCBjZXg9LjkxLCBjb2w9Y2xyKQ0KDQpgYGANCg0KPGJyPiAgDQoNCiMjIyAmbmJzcDsgUHJlc2VudGF0aW9uIHF1YWxpdHkgaGlzdG9ncmFtICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KPGJyPg0KDQo+IEEgZ3JhcGggZGVzdGluZWQgZm9yIGEgKlBvc3Rlciogb3IgKlByZXNlbnRhdGlvbiogaW4gY2xhc3MsIGF0IGEgc2NpZW50aWZpYyANCm1lZXRpbmcgb3IgYXQgYW4gaW50ZXJ2aWV3LCBvZnRlbiBiZW5lZml0cyBmcm9tIGEgZ3JhcGggKnRpdGxlKiBhbmQgYnkgYSBzbWFsbCANCm1vZGVzdCwgKnBlcnNvbmFsaXplZCB0aW1lIHN0YW1wKiB0byBkZW5vdGUgY3JlZGl0L2JsYW1lLiBCZWxvdyBpcyBhIGNhbGwgdG8gDQpgaGlzdCgpYCBzaG93aW5nIGhvdyB0byBhZGQgdGhlIHRpbWUgc3RhbXAgYnkgYSBjYWxsIHRvIHRoZSBgbXRleHQoKWAgZnVuY3Rpb24sIA0KdXNpbmcgKkFybG8qIGFzIGludmVzdGlnYXRvciBuYW1lLiANCj4NCj4gV2hpbGUgKipwZXJzb25hbGl6ZWQgdGltZSBzdGFtcCoqIGFuZCAqKnRpdGxlKiogYXJlIG5vdCBhcHByb3ByaWF0ZSBmb3IgYSANCioqcHVibGljYXRpb24gcXVhbGl0eSoqIGdyYXBoLCB0aGV5IGFyZSBvZnRlbiBkZXNpcmFibGUgZm9yIGEgKipwcmVzZW50YXRpb24gDQpxdWFsaXR5KiogZ3JhcGguDQo+DQo+IENhbiB5b3UgZmluZCBBcmxvJ3MgcGVyc29uYWxpemVkIHRpbWUgc3RhbXAgaW4gdGhlIGdyYXBoIHdpbmRvdyBiZWxvdz8NCg0KYGBge3IsIGZpZy5jYXA9IlByZXNlbnRhdGlvbiBxdWFsaXR5IGhpc3RvZ3JhbSB3aXRoIHBlcnNvbmFsaXplZCB0aW1lIHN0YW1wIn0NCg0KaGlzdCh5MSwgDQogICAgIGNvbD0iY29yYWwiLCANCiAgICAgYm9yZGVyPSJ3aGl0ZSIsIA0KICAgICBtYWluPSJQcmVsaW1pbmFyeSBFeHBlcmltZW50ICMxIiwNCiAgICAgeGxhYj0iUmFuZG9tIHNhbXBsZSBmcm9tIE4oNTAsIDkpIiwgDQogICAgIGNleC5sYWI9MS40LCBjZXguYXhpcz0xLjMsIGNleC5tYWluPTIsIGNvbC5tYWluPSJibGFjayIsIGxhcz0xKSAjIHR5cG9ncmFwaHkNCg0KIyBhZGQgdGltZSBzdGFtcCwgcGVyc29uYWxpemVkDQptdGV4dChwYXN0ZSgiQXJsbzogIiwgZGF0ZSgpKSwgc2lkZT0xLCBhZGo9MSwgbGluZT00LCBjZXg9LjksIGNvbD0iZ3JheSIpIA0KDQpgYGANCg0KPGJyPiANCg0KKipRdWVzdGlvbioqOiBGb3IgZ3JhcGhzLCB3aGF0J3MgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiAqKmRyYWZ0KiogcXVhbGl0eSwgDQoqKnByZXNlbnRhdGlvbioqIHF1YWxpdHkgYW5kICoqcHVibGljYXRpb24qKiBxdWFsaXR5PyBUaGUgYW5zd2VyIGNvbmNlcm5zIHRoZSANCnN0cnVjdHVyZSBvZiB0aGUgZ3JhcGggaXRzZWxmLCBhcyB3ZWxsIGFzIHRoZSBpbnRlbmRlZCBhdWRpZW5jZS4gSW4gQmlvIDI0MCB3ZSANCnVzZSBSIHRvIG1ha2UgYWxsIHRocmVlIHR5cGVzIG9mIGdyYXBocy4gDQoNCjxicj4gIA0KDQojIyMgJm5ic3A7IEtlcm5lbCBkZW5zaXR5IGVzdGltYXRlICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KPGJyPiANCg0KPiBJbnN0ZWFkIG9mIGEgaGlzdG9ncmFtLCBvbmUgbWF5IHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGB5MWAgYnkgYSANCioqa2VybmVsIGRlbnNpdHkgZXN0aW1hdGUqKiBjYWxjdWxhdGVkIGJ5IGZ1bmN0aW9uIGBkZW5zaXR5KClgLiBCZWxvdywgd2UgcGxvdCANCml0IHVzaW5nIHRoZSB3b3JraG9yc2UgZ3JhcGhpbmcgZnVuY3Rpb24gaW4gYmFzZSBSLCBgcGxvdCgpYC4NCg0KYGBge3IsIGZpZy53aWR0aD00LCBmaWcuY2FwPSJLZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mIHkxIn0NCg0KZGVucyA8LSBkZW5zaXR5KHkxKSAjIGdldCB4LHkgY29vcmRpbmF0ZXMgb2Yga2VybmVsIGRlbnNpdHkgY3VydmUsIGZpdCB0byBkYXRhIHkNCg0KcGxvdChkZW5zLCB4bGFiPSJSYW5kb20gc2FtcGxlIGZyb20gTig1MCwgMTApIiwgbWFpbj0iIiwgY29sPSJyZWQiKQ0KDQpgYGANCg0KPGJyPiANCg0KPiBJZiBkZXNpcmVkLCB0aGUga2VybmVsIGRlbnNpdHkgZXN0aW1hdGUgbWF5IGJlIGZpbGxlZCB3aXRoIGEgKipjb2xvcioqIHVzaW5nIA0KdGhlIGBwb2x5Z29uKClgIGZ1bmN0aW9uLiBUaGUga2VybmVsIGRlbnNpdHkgaXMgYSBmYXIgbW9yZSByaWdvcm91cyB2aXN1YWxpemF0aW9uIA0Kb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIHNhbXBsZSBvZiBkYXRhIHRoYW4gdGhlIGhpc3RvZ3JhbS4gQXQgdGhlIFIgQ29uc29sZSwgDQplbnRlcmA/ZGVuc2l0eWAgdG8gdmlldyBkb2N1bWVudGF0aW9uIGZvciB0aGlzIGZ1bmN0aW9uIGluY2x1ZGluZyBpdHMgYXJndW1lbnRzLCANCmhvdyBpdCdzIGNhbGN1bGF0ZWQgYW5kIGJpYmxpb2dyYXBoaWMgcmVmZXJlbmNlcy4NCg0KYGBge3IsIGZpZy53aWR0aD00LCBmaWcuY2FwPSJLZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSwgY29sb3IgZmlsbGVkIn0NCg0KZGVucyA8LSBkZW5zaXR5KHkxKSAjIGdldCB4LHkgY29vcmRpbmF0ZXMgb2Yga2VybmVsIGRlbnNpdHkgY3VydmUgZml0IHRvIGRhdGENCg0KcGxvdChkZW5zLCB4bGFiPSJSYW5kb20gc2FtcGxlIGZyb20gTig1MCwgMTApIiwgbWFpbj0iIikNCg0KcG9seWdvbihkZW5zLCBjb2w9InBlcnUiKSAjIGF0IFIgQ29uc29sZSB0cnkgPiA/Y29sb3IgZm9yIG5hbWVzIG9mIGFsbCA2NTcgY29sb3JzDQoNCmBgYA0KPGJyPiANCg0KIyMjICZuYnNwOyBGaXQgbm9ybWFsIGRpc3RyaWJ1dGlvbiB0byBhIHNhbXBsZSAgICAgIDwhLS0gLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KPGJyPiANCg0KPiBXZSBjb3VsZCBvdmVybGF5IHRoZSBkZW5zaXR5IGhpc3RvZ3JhbSBvZiB5MSB3aXRoIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIFBERiANCnVzaW5nIHRoZSBvYnNlcnZlZCBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gYXMgaXRzIHBhcmFtZXRlcnMuIFRoaXMgaXMgZG9uZSANCnRvIHNob3cgdGhlIGFwcGFyZW50IG5vcm1hbGl0eSBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSBvciB0byBlbXBoYXNpemUgdGhlIGxhY2sgb2YgDQpub3JtYWxpdHkuIA0KPg0KPiBUaGVyZSBhcmUgc2V2ZXJhbCB3YXlzIHRvIGRvIHRoaXMgaW4gUiwgSSBwcmVzZW50IG9uZSBiZWxvdy4NCj4NCj4gSGVyZSwgd2UgZXhwZWN0IG91ciBzYW1wbGUgdG8gYmUgcmVhc29uYWJseSBjbG9zZSB0byB0aGUgbm9ybWFsIFBERiBiZWNhdXNlIA0KdGhlIG9ic2VydmVkLCBuPTYwIGlzIGEgcmFuZG9tIHNhbXBsZSBmcm9tIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLiBCdXQgd2UgbXVzdCANCnJlbWVtYmVyIHRoYXQgYXQgcmVsYXRpdmVseSBzbWFsbCBzYW1wbGUgc2l6ZSwgKioqcmFuZG9tIHNhbXBsaW5nKioqIG9mdGVuIA0KZ2VuZXJhdGVzIGV4dHJlbWVseSB1bmV4cGVjdGVkIGRpc3RyaWJ1dGlvbnMsIG5vdCBqdXN0IGluIHNpbXVsYXRlZCBkYXRhIGJ1dCBpbiANCnJlc2VhcmNoIGRhdGEgYXMgd2VsbC4gDQoNCmBgYHtyLCBmaWcuY2FwPSJEZW5zaXR5IGhpc3RvZ3JhbSB3aXRoIG5vcm1hbCBmaXQifQ0KDQpwdHMgPC0gMjUwICAgIyBudW1iZXIgb2YgeCx5IHBvaW50cyBmb3IgdGhlIG5vcm1hbCBQREYgY3VydmUNCg0KZyA8LSBoaXN0KHkxLCBwbG90PUZBTFNFKSAjIGZvciBwbG90dGluZyBhcmdzDQoNCnggPC0gc2VxKGZyb209bWluKGckYnJlYWtzKSwgdG89bWF4KGckYnJlYWtzKSwgbGVuZ3RoPXB0cykgIyB4LWNvb3JkIG9mIG5vcm1hbCBQREYNCnkgPC0gZG5vcm0oeCwgbWVhbih5MSksIHNkKHkxKSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5LWNvb3JkICIgICAiICAgICAgIg0KDQpteCA8LSBtYXgoYyh5LCBnJGRlbnNpdHkpKSAgICAgICAgICAgICAgICAgICAgICMgZ2V0IHktbWF4IGZvciBwbG90dGluZw0KDQpoaXN0KHkxLCBmcmVxPUZBTFNFLCB5bGltPWMoMCwgbXgpLCBtYWluPU5VTEwpICMgbWluaW1hbCwgZGVuc2l0eSBoaXN0b2dyYW0NCg0KbGluZXMoeCwgeSwgbHdkPTEuNSwgY29sPSJibHVlIikgICAgICAgICAgICAgICAjIGFkZCB0aGUgbm9ybWFsIFBERg0KDQpgYGANCjxicj4gDQo8IS0tICBibHVlIGVsbGlwc2UgLSByYWRpYWwgZ3JhZGllbnQgZm9yIE5vcm1hbCBmaXQgdG8gaGlzdG9ncmFtIC4uLi4uLi4uLi4uLi4uIC0tPg0KDQpgYGB7PWh0bWx9DQoNCjxzdmcgaGVpZ2h0PSIyNTAiIHdpZHRoPSI4NDAiPg0KICA8ZGVmcz4NCiAgICA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQzIiBjeD0iNTAlIiBjeT0iNTAlIiByPSI1MCUiIGZ4PSI1MCUiIGZ5PSI1MCUiPg0KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6cmdiKDI1NSwyNTUsMjU1KTtzdG9wLW9wYWNpdHk6MCIgLz4NCiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6cmdiKDAsMCwyNTUpO3N0b3Atb3BhY2l0eToxIiAvPg0KICAgIDwvcmFkaWFsR3JhZGllbnQ+DQogIDwvZGVmcz4NCiAgPGVsbGlwc2UgY3g9IjIwMCIgY3k9Ijc1IiByeD0iMTYwIiByeT0iNzMiIGZpbGw9InVybCgjZ3JhZDMpIiAvPg0KICA8dGV4dCBmaWxsPSJibGFjayIgZm9udC1zaXplPTIwcHQgZm9udC1mYW1pbHk9IkFyaWFsIGJsYWNrIj4NCiAgDQogIDx0c3BhbiB4PTEwNSAgeT02Mj4gICAgICAgTm9ybWFsIGZpdCB0byAgIDwvdHNwYW4+DQogIDx0c3BhbiB4PTcwICBkeT0xLjRlbT4gZGVuc2l0eSBoaXN0b2dyYW0gPC90c3Bhbj4NCiAgPC90ZXh0Pg0KICANCiAgPHRleHQgeD0zODAgeT0wIGR5PTFlbSBmb250LXNpemU9MTNwdCBmb250LXN0eWxlPWl0YWxpYz4NCiAgPHRzcGFuPiBUaGlzIGlzIGNvbW1vbmx5IGRvbmUgb24gdGhlIHJlc2VhcmNoIGJlbmNoIGFzIHdlbGwgYXMgaW48L3RzcGFuPiANCiAgPHRzcGFuIHg9MzgwIGR5PTEuNGVtPnB1YmxpY2F0aW9uLiBGb3IgYSBwZXJmZWN0bHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgc2FtcGxlLDwvdHNwYW4+DQogIDx0c3BhbiB4PTM4MCBkeT0xLjRlbT50aGUgbm9ybWFsIGN1cnZlIGdvZXMgdGhyb3VnaCB0aGUgbWlkcG9pbnQgYXRvcCBlYWNoIDwvdHNwYW4+DQogIDx0c3BhbiB4PTM4MCBkeT0xLjRlbT5oaXN0b2dyYW0gYmFyLiBUaGlzICJub3JtYWwgZml0IiBpcyBub3QgYSBmb3JtYWwgdGVzdCBvZjwvdHNwYW4+DQogIDx0c3BhbiB4PTM4MCBkeT0xLjRlbT5ub3JtYWxpdHksIGJ1dCByZW1haW5zIGEgdmFsdWVkIHZpc3VhbGl6YXRpb24gb2YgPC90c3Bhbj4NCiAgPHRzcGFuIHg9MzgwIGR5PTEuNGVtPmFwcGFyZW50IGRlcGFydHVyZXMgZnJvbSwgb3IgYWdyZWVtZW50cyB3aXRoLCBub3JtYWxpdHkuPC90c3Bhbj4NCiAgPC90ZXh0PiANCjwvc3ZnPg0KYGBgDQoNCiMjIyAmbmJzcDsgRURBIC0tIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgICAgICAgPCEtLSAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLiAtLT4NCjxicj4gDQoNCldlIG9mdGVuIHVzZSAqKkVEQSoqIHRvIGhlbHAgdW5kZXJzdGFuZCB0aGUgZGF0YSwgdG8gcmV2ZWFsIHNvbWV0aGluZyB1bmZvcnNlZW4sIA0KdG8gY29tbXVuaWNhdGUgdG8gb3RoZXJzIGFuZCB0byBzdGltdWxhdGUgcmVzZWFyY2ggaHlwb3RoZXNpcyBnZW5lcmF0aW9uLiANCg0KKipFREEqKjogRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcywgd2FzIGRldmVsb3BlZCwgaWYgbm90IGNyZWF0ZWQgYnkgKipKb2huIFR1a2V5KiogDQphbmQgYXNzb2NpYXRlcyBpbiB0aGUgMTk3MHMuIFRoZSBpbmZsdWVuY2Ugb2YgRURBIG9uIHRoZSBlbnRpcmUgZmllbGQgb2Ygc3RhdGlzdGljcywgDQpyZW1haW5zIHByb2ZvdW5kLiBBbmFseXN0cyByZWx5IG9uIEVEQSB0byBsZWFybiBhYm91dCB0aGVpciBkYXRhLiAgDQoNCkluIGRhdGEgYW5hbHlzaXMsIHdlIG9mdGVuIHVzZSB0aGlzIHJlcGVhdGluZyBsb29wIDogIA0KPGJyPiAgDQoNCjwhLS0gcmF3IExhVGVYIGNvZGUgLS0+DQoke1xxdWFkXHF1YWQgICANClxsYXJnZVxpdCB7UmVzZWFyY2h9IFwge0h5cG90aGVzZXN9XCBcbG9uZ2xlZnRyaWdodGFycm93IFwgXExhcmdlIFxiZiB7RX1cIHtEfVwgDQp7QX1cIFxsb25nbGVmdHJpZ2h0YXJyb3cgXCBcbGFyZ2VcaXQge1N0YXRpc3RpY2FsfSBcIHtBbmFseXNpcy9Nb2RlbGluZ319JCANCg0KPGJyPg0KTXkgZnVuY3Rpb24gYEVEQSgpYCBpbiAqKksgZnVucyBVTklWQVJJQVRFLlIqKiBtYWtlcyB0aGUgZ3JhcGhpYyB3aW5kb3cgYmVsb3csIA0KZmVhdHVyaW5nIGdyYXBocyBhbmQgc3RhdGlzdGljYWwgYW5hbHlzZXMsIGFsbCB0byBiZSB0YWtlbiBhcyBleHBsb3JhdG9yeS4gIA0KDQpgYGB7ciBmaWcud2lkdGg9OC41LCBmaWcuYXNwPTEsIG1lc3NhZ2U9RkFMU0V9DQoNCiNzb3VyY2UoIkM6XFxVc2Vyc1xcZHdpZ2hcXERlc2t0b3BcXEsgZnVucyBVTklWQVJJQVRFLlIiKSAjICdzb3VyY2UnIHRoZSBmaWxlDQoNCkVEQSh5MSwgZGF0YS5uYW1lPSJzaW0gZGF0YSwgTig1MCwgOSkiKSANCg0KYGBgDQoNCjxicj4gDQoNCiMjIyAmbmJzcDsgQXNzZXNzIHRoZSBub3JtYWxpdHkgb2YgYSBzYW1wbGUgICAgICAgIDwhLS0gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gLS0+DQoNClRoaXMgaXMgYW4gaW50ZXJlc3RpbmcgYW5kIGRpdmVyc2UgdG9waWMgdGhhdCBiZW5lZml0cyBmcm9tIHN0YXRpc3RpY2FsIHdpc2RvbSANCmdhaW5lZCBieSBleHBlcmllbmNlIGluIGRhdGEgYW5hbHlzaXMuIEl0J3Mgbm90IHRoZSB0aW1lIG5vciBwbGFjZSBmb3IgYSBkZWVwIA0KZGl2ZSBpbnRvIGl0LiBGb3JtZXJseSwgb25seSB0cmFkaXRpb25hbCBzdGF0aXN0aWNhbCBoeXBvdGhlc2lzIHRlc3Rpbmcgd2FzIHVzZWQgDQp0byBhbnN3ZXIgdGhlIHF1ZXN0aW9uLCAiYXJlIG15IGRhdGEgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYXMgYXNzdW1lZCBieSBBbm92YT8iIA0KVG9kYXksIHRlc3RzIGxpa2UgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IG9mIG5vcm1hbGl0eSBhcmUgc3RpbGwgY29tbW9ubHkgcmVwb3J0ZWQuIA0KDQpOb3JtYWwgUXVhbnRpbGUtUXVhbnRpbGUgcGxvdHMgaGF2ZSBsb25nIGJlZW4gdXNlZCB0byBhc3Nlc3Mgbm9ybWFsaXR5IG9mIA0Kb2JzZXJ2ZWQgZGF0YS4gDQoNCkluY3JlYXNpbmdseSwgbWFueSBwbGFjZSBlbXBoYXNpcyBvbiB0aGUgZ3JhcGhpY2FsIHZpc3VhbGl6YXRpb24gb2YgYW4gb2JzZXJ2ZWQgDQpkaXN0cmlidXRpb24gdmVyc3VzIHNpbXVsYXRlZCBkYXRhIG9mIHRoZSBzYW1lIHNhbXBsZSBzaXplLCBzYW1wbGVkIGZyb20gdGhlIA0Kbm9ybWFsIGRpc3RyaWJ1dGlvbi4gSSByZWNlbnRseSBpbnZlbnRlZCBvbmUgc3VjaCBhcHByb2FjaCBhcyBzZWVuIGJlbG93LiAgDQoNCkJlbG93LCBzZWUgYSB2aXN1YWwgYXNzZXNzbWVudCBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBgeTFgIHJlbGF0aXZlIHRvIHRoZSANCm5vcm1hbCBkaXN0cmlidXRpb24sIHVzaW5nIGEgbm92ZWwgZnVuY3Rpb24gZGVmaW5lZCBpbiBteSBSIEVkaXRvciBmaWxlOiANCioqSyBmdW5zIFVOSVZBUklBVEUuUioqICANCg0KYGBge3IgY2FjaGU9RkFMU0UsIGZpZy5jYXA9IiAiLCBmaWcud2lkdGg9OC41LCBmaWcuYXNwPS44fQ0KDQojIEtpbmNhaWQgZnVuY3Rpb24gdXNpbmcgTW9udGUgQ2FybG8gZGF0YSBzaW11bGF0aW9uIHRvIGFzc2VzcyBub3JtYWxpdHkNCk5vcm1hbC5rZXJuZWwuYmFuZCh5MSwgTlM9NTAwKSANCg0KYGBgDQoNCg0KPGJyPiANCg0KIyMgJm5ic3A7IE9uZS13YXkgZGF0YSAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLmNvbW1lbnRzLi4uLi4uLi4gLS0+DQoNCldlIHNpbXVsYXRlIGEgb25lLXdheSBkYXRhIHNldCBvZiA0IGdyb3VwcyB3aXRoIHRvdGFsIE49MjgxLiBUd28gZ3JvdXBzIGFyZSANCnJhbmRvbSBzYW1wbGVzIGZyb20gdGhlICoqKm5vcm1hbCBkaXN0cmlidXRpb24qKiogKGJlbGwtc2hhcGVkKSBhbmQgdGhlIG90aGVyIA0KdHdvIGdyb3VwcyBhcmUgcmFuZG9tIHNhbXBsZXMgZnJvbSB0aGUgKioqdW5pZm9ybSBkaXN0cmlidXRpb24qKiogKGZsYXQtdG9wcGVkKS4gDQoNCkEgb25lLXdheSBkYXRhIHNldCBpcyB3aGVyZSBhIGRhdHVtIGlzIGNsYXNzaWZpZWQgYnkgb25lIGNyaXRlcmlvbiAtLSA8dT5pdHMgZ3JvdXAgDQptZW1iZXJzaGlwPC91Pi4gQW5kLCB0aGVyZSBjYW4gYmUgYW55IG51bWJlciBvZiBncm91cHMgYW5kIGFueSBzYW1wbGUgc2l6ZSBwZXIgDQpncm91cC4gDQoNCldlIGRldmVsb3AgZ3JhcGhpY2FsIHZpc3VhbGl6YXRpb25zIGFuZCBzdGF0aXN0aWNhbCBhbmFseXNlcywgYm90aCB0cmFkaXRpb25hbCwgDQpjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIChwZXJtdXRhdGlvbiAmIGJvb3RzdHJhcCkgYW5kIEJheWVzaWFuIChCYXllcyBGYWN0b3IgDQpBbm92YSkuIE5vdGUgdGhhdCBldmVyeSB0aW1lIHRoaXMgYC5SbWRgIGNvZGUgaXMgcmVuZGVyZWQgaW4gUlN0dWRpbyBhIGRpZmZlcmVudCANCioqZmFrZSoqIGRhdGEgc2V0IGlzIGdlbmVyYXRlZCBiZWNhdXNlIHRoZSBgIHNldC5zZWVkKClgIGZ1bmN0aW9uIGlzIG5vdCB1c2VkLg0KDQojIyMgJm5ic3A7IE11bHRpcGxlIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRlcyAgICAgPCEtLSAuLi4uLi4uLi4uLi4uIC0tPg0KDQpBbm90aGVyIGFkdmFudGFnZSBvZiAqKmtlcm5lbCBkZW5zaXR5IGVzdGltYXRlcyoqIG92ZXIgKipoaXN0b2dyYW1zKiogaXMgdG8gDQp2aXN1YWxpemUgbW9yZSB0aGFuIG9uZSBkaXN0cmlidXRpb24gb24gdGhlIHNhbWUgZ3JhcGgsIGFzIHdlIGRvIGJlbG93IHVzaW5nIA0Kc2ltdWxhdGVkIGRhdGEgKGZha2UgZGF0YSkgZnJvbSB0aGUgbm9ybWFsIGFuZCB1bmlmb3JtIGRpc3RyaWJ1dGlvbnMuIFBsb3R0aW5nIA0KdGhlc2UgNCBncm91cHMgYXMgaGlzdG9ncmFtcyBpbiB0aGUgc2FtZSBncmFwaCB3b3VsZCBiZSBhbiBvdmVybGFwIG1lc3MuICANCg0KYGBge3IgZmlnLmNhcD0iTXVsdGlwbGUga2VybmVsIGRlbnNpdHkgZXN0aW1hdGVzIiwgZmlnLndpZHRoPTguNSwgZmlnLmFzcD0uOH0NCg0Kc2V0LnNlZWQoODc2KSAgICAgICAgICAgICMgc2V0IHNlZWQgZm9yIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yDQp4MSA8LSBybm9ybSg1MCwgMzIsIDUpICAgIyBzYW1wbGUgZnJvbSBub3JtYWwgZGlzdHJpYnV0aW9uICAgICANCngyIDwtIHJub3JtKDUxLCAzNCwgNykgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQp4MyA8LSBydW5pZigxMDAsIDEwLCA0NSkgIyBzYW1wbGUgZnJvbSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiAgIA0KeDQgPC0gcnVuaWYoODAsIDE5LCAzMCkgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCg0KeDEgPC0gcm91bmQoeDEsIDIpOyB4MiA8LSByb3VuZCh4MiwgMik7IHgzIDwtIHJvdW5kKHgzLCAyKTsgeDQgPC0gcm91bmQoeDQsIDIpDQoNCiMgb3JnYW5pemUgb3VyIHNpbXVsYXRlZCwgb25lLXdheSBkYXRhIHNldCBpbnRvIGEgREFUQSBGUkFNRSAtLS0tLS0tLS0tLS0tLS0tDQoNCnJlc3BvbnNlIDwtIGMoeDEsIHgyLCB4MywgeDQpICMgbnVtZXJpYywgcmVzcG9uc2UgdmFyaWFibGUNCg0KIyBnZXQgZ3JvdXBpbmcgdmFyaWFibGUgDQpuIDwtIGMobGVuZ3RoKHgxKSwgbGVuZ3RoKHgyKSwgbGVuZ3RoKHgzKSwgbGVuZ3RoKHg0KSkgIyB2ZWN0b3Igb2Ygc2FtcGxlIHNpemVzDQpncm91cCAgICA8LSBjKHJlcCgieDEiLCBuWzFdKSwgcmVwKCJ4MiIsIG5bMl0pLCByZXAoIngzIiwgblszXSksIHJlcCgieDQiLCBuWzRdKSkNCmdyb3VwICAgIDwtIGZhY3Rvcihncm91cCwgbGV2ZWxzPWMoIngxIiwgIngyIiwgIngzIiwgIng0IikpICMgZGVzaXJlZCBwcmVzZW50YXRpb24gb3JkZXINCg0Kc2ltLmRmICAgPC0gZGF0YS5mcmFtZShyZXNwb25zZSwgZ3JvdXApICMgbWFrZSBkYXRhIGZyYW1lDQoNCnN0cihzaW0uZGYpICAgICAjIHZpZXcgc3RydWN0dXJlIG9mIHRoZSBvYmplY3QgLS0gQ0hFQ0tJTkcNCnN1bW1hcnkoc2ltLmRmKSAjIGdldCBzaW1wbGUgc3RhdHMgLS0gQ0hFQ0tJTkcNCmhlYWQoc2ltLmRmKSAgICAjIGZpcnN0IDYgcm93cyAtLSBDSEVDS0lORw0KdGFpbChzaW0uZGYpICAgICMgbGFzdCA2IHJvd3MgLS0gQ0hFQ0tJTkcNCg0KDQojIHNvbWUgZGVzY3JpcHRpdmUgc3RhdHMgYnkgc29tZSBiYXNpYyBwcm9ncmFtbWluZyBpbiBSIC0tLS0tDQoNCm4gICAgICA8LSB0YXBwbHkocmVzcG9uc2UsIGdyb3VwLCBsZW5ndGgpICMgdmVjdG9yIG9mIHNhbXBsZSBzaXplcw0KTWVhbiAgIDwtIHRhcHBseShyZXNwb25zZSwgZ3JvdXAsIG1lYW4pICAgIyB2ZWN0b3Igb2YgbWVhbnMNClNEICAgICA8LSB0YXBwbHkocmVzcG9uc2UsIGdyb3VwLCBzZCkgICAgICMgU0QNCk1pbiAgICA8LSB0YXBwbHkocmVzcG9uc2UsIGdyb3VwLCBtaW4pICAgICMgbWluaW11bQ0KTWF4ICAgIDwtIHRhcHBseShyZXNwb25zZSwgZ3JvdXAsIG1heCkgICAgIyBtYXhpbXVtDQpNZWRpYW4gPC0gdGFwcGx5KHJlc3BvbnNlLCBncm91cCwgbWVkaWFuKSAjIG1lZGlhbg0KaXFyICAgIDwtIHRhcHBseShyZXNwb25zZSwgZ3JvdXAsIElRUikgICAgIyBJUVINCkNWICAgICA8LSAxMDAgKiBTRC9NZWFuICAgICAgICAgICAgICAgICAgICMgQ29lZmZpY2llbnQgb2YgVmFyaWF0aW9uICUNClNFTSAgICA8LSByb3VuZChTRC9zcXJ0KG4pLCA0KSAgICAgICAgICAgICMgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4NClExICAgICA8LSB0YXBwbHkocmVzcG9uc2UsIGdyb3VwLCBxdWFudGlsZSwgcHJvYnM9LjI1KSAjIDI1dGggcGVyY2VudGlsZQ0KUTMgICAgIDwtIHRhcHBseShyZXNwb25zZSwgZ3JvdXAsIHF1YW50aWxlLCBwcm9icz0uNzUpICMgNzV0aCAgICAiDQoNCiMgc3RhdHMgcGVyIGdyb3VwIC0tLS0tIHByaW50ZWQgMiBkaWZmZXJlbnQgd2F5czogIGNiaW5kKCkgdnMuIHJiaW5kKCkgLS0tLQ0KcHJpbnQoY2JpbmQobiwgTWVhbiwgU0QsIENWLCBTRU0sIE1pbiwgTWF4LCBNZWRpYW4sIGlxciwgUTEsIFEzKSwgZGlnaXRzPTQpIA0KDQpwcmludChyYmluZChuLCBNZWFuLCBTRCwgQ1YsIFNFTSwgTWluLCBNYXgsIE1lZGlhbiwgaXFyLCBRMSwgUTMpKSANCg0KDQojIGdldCA1MTIgeCx5IHBvaW50cyBmb3Iga2VybmVsIGRlbnNpdHkgZXN0aW1hdGVzIC0tLS0tLS0tLQ0KDQpkMSA8LSBkZW5zaXR5KHgxKSANCmQyIDwtIGRlbnNpdHkoeDIpDQpkMyA8LSBkZW5zaXR5KHgzKQ0KZDQgPC0gZGVuc2l0eSh4NCkNCg0KeGxtIDwtIHJhbmdlKGMoZDEkeCwgZDIkeCwgZDMkeCwgZDQkeCkpICMgZ2V0IG1pbiwgbWF4IGZvciBwbG90dGluZw0KeWxtIDwtIHJhbmdlKGMoZDEkeSwgZDIkeSwgZDMkeSwgZDQkeSkpDQoNCnBsb3QoZDEsIHR5cGU9Im4iLCBtYWluPSIiLCAgICAgICAgICAgICAgICMgZ2V0IGdyYXBoIGdvaW5nDQogIHhsaW09eGxtLCB5bGltPXlsbSwgICAgICAgICAgICAgICAgICAgICAjIGdsb2JhbCB4LHkgcGxvdHRpbmcgcmFuZ2VzDQogIGNleC5sYWI9MS4zNSwgZm9udC5sYWI9MiwgY2V4LmF4aXM9MS4yLCAjIHR5cG9ncmFwaHkNCiAgeGxhYj0iU2ltdWxhdGVkIGRhdGEgZnJvbSB0aGUgTm9ybWFsIGFuZCBVbmlmb3JtIGRpc3RyaWJ1dGlvbiIpIA0KDQpsaW5lcyhkMSwgY29sPSJibGFjayIsIGx3ZD0zKSAgIyBhZGQga2VybmVsIGRlbnNpdHkgZXN0aW1hdGVzIC0tLS0tLS0tLS0tLS0tLQ0KbGluZXMoZDIsIGNvbD0icmVkIiwgICBsd2Q9MykgDQpsaW5lcyhkMywgY29sPSJibHVlIiwgIGx0eT0yLCBsd2Q9MykNCmxpbmVzKGQ0LCBjb2w9ImdyZWVuIiwgbHdkPTMpDQoNCiMgbGVnZW5kIHdpdGggc3RhdHMgLS0tLSBieSB0cmlhbC1hbmQtZXJyb3IgY29kaW5nIHdpdGggbXRleHQoKSAtLS0tLS0tLS0tLS0tDQpjbCAgPC0gYygiYmxhY2siLCAicmVkIiwgImJsdWUiLCAiZ3JlZW4iKQ0KbG5lIDwtIGMoLTIuNSwgLTMuNSwgLTQuNSwgLTUuNSkNCmFkICA8LSBjKC43NSwgLjgxLCAuOTEsIC45OCkNCg0KbXRleHQoYygiZ3JvdXAiLCAiTiIsICJNZWFuIiwgIlNEIiksIGxpbmU9LTEsIGFkaj1hZCwgY2V4PS45KQ0KbXRleHQoYygieDEiLCAieDIiLCAieDMiLCAieDQiKSwgbGluZT1sbmUsIGFkaj0uNzUsIGZvbnQ9MiApDQptdGV4dChjbCwgbGluZT1sbmUsIGFkaj0uNjUsIGNvbD1jbCwgY2V4PTEuMSkNCg0KbXRleHQoYyhuWzFdLCByb3VuZChNZWFuWzFdLDIpLCByb3VuZChTRFsxXSwyKSksIGxpbmU9LTIuNSwgDQogICAgICBhZGo9YyguODIsIC45LCAuOTgpLCBjZXg9LjkpDQptdGV4dChjKG5bMl0sIHJvdW5kKE1lYW5bMl0sMiksIHJvdW5kKFNEWzJdLDIpKSwgbGluZT0tMy41LCANCiAgICAgIGFkaj1jKC44MiwgLjksIC45OCksIGNleD0uOSkNCm10ZXh0KGMoblszXSwgcm91bmQoTWVhblszXSwyKSwgcm91bmQoU0RbM10sMikpLCBsaW5lPS00LjUsIA0KICAgICAgYWRqPWMoLjgyLCAuOSwgLjk4KSwgY2V4PS45KQ0KbXRleHQoYyhuWzRdLCByb3VuZChNZWFuWzRdLDIpLCByb3VuZChTRFs0XSwyKSksIGxpbmU9LTUuNSwgDQogICAgICBhZGo9YyguODIsIC45LCAuOTgpLCBjZXg9LjkpDQoNCg0KDQpgYGANCg0KPGJyPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAgIGdncGxvdDIgaW50cm8gICAtLT4NCg0KPiBUaGUgYWJvdmUgZ3JhcGggb2YgNCBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZXMgd2FzIGRvbmUgdXNpbmcgKipiYXNlIFIgZ3JhcGhpY3MqKi4gDQpCZWxvdywgd2UgdXNlIHRoZSBgZ2dwbG90MmAgcGFja2FnZSBieSBIYWRsZXkgV2lja2hhbS4gSXQgdXNlcyBQYXVsIE11cnJlbGwncyANCmBncmlkYCBwYWNrYWdlLCBub3QgYmFzZSBSLiANCg0KVGhlIGBnZ3Bsb3QyYCB2aXN1YWxpemF0aW9uIGVudmlyb25tZW50IGlzIHZhc3QgYW5kIHBvd2VyZnVsLCBidXQgaXQncyBiZXlvbmQgb3VyIA0KdGltZSBjb25zdHJhaW50cyBhbmQgbm90IG15IG9iamVjdGl2ZSBpbiBCaW8gMjQwLiBIb3dldmVyIEkgd2lsbCANCmRlbW9uc3RyYXRlIGBnZ3Bsb3QyYCBncmFwaGljcyBhY3Jvc3MgdGhlIGNvdXJzZSwgYXMgdGltZSBhbGxvd3MuIA0KDQpJbiBteSBvcGluaW9uLCBpdCdzIGJlc3QgdG8gbGVhcm4gYmFzZSBSIGdyYXBoaWNzIGZpcnN0LCBiZWZvcmUgbGVhcm5pbmcgb3RoZXIgDQp2aXN1YWxpemF0aW9uIGVudmlyb25tZW50cyBzdWNoIGFzIGBsYXR0aWNlYCBhbmQgYGdncGxvdDJgLiBUaGUgYGdncGxvdDJgIA0KZW52aXJvbm1lbnQgcmVmbGVjdHMgc29mdHdhcmUgdGhhdCBpcyBuZWFybHkgYSBwcm9ncmFtbWluZyBsYW5ndWFnZSBpbiBvZiBpdHNlbGYuIA0KVGhlIGJhc2UgUiBncmFwaGljcyBlbnZpcm9ubWVudCBvZnRlbiBtZWV0cyBvdXIgc2NpZW50aWZpYyBhbmQgYWVzdGhldGljIGdyYXBoaW5nIA0KbmVlZHMgYW5kIGRvZXMgc28gd2l0aGluIGEgc2ltcGxlIGFuZCBjb25zaXN0ZW50IGNvZGluZyBwYXR0ZXJuIHRoYXQgYWxsb3dzIGEgDQpoaWdoIGxldmVsIG9mIGNvbnRyb2wuICANCg0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShnZ3Bsb3QyKSAjIGxvYWQgdGhlIHBhY2thZ2UNCg0KbXkuY29sb3JzIDwtIGMoeDE9ImJsYWNrIiwgeDI9InJlZCIsIHgzPSJibHVlIiwgeDQ9ImdyZWVuIikNCg0KIyA0IGtlcm5lbCBkZW5zaXR5IGxpbmVzLCBOTyBGSUxMDQoNCnAxIDwtICBnZ3Bsb3Qoc2ltLmRmLCBhZXMoeD1yZXNwb25zZSwgY29sb3I9Z3JvdXApKSArIGdlb21fZGVuc2l0eShzaXplPTEuMikgKyANCiAgICAgICAgICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9bXkuY29sb3JzKQ0KcHJpbnQocDEpDQoNCiANCiMgNCBrZXJuZWwgZGVuc2l0aWVzLCBGSUxMRUQgDQpwMiA8LSBnZ3Bsb3Qoc2ltLmRmLCBhZXMoeD1yZXNwb25zZSwgZmlsbD1ncm91cCkpICsgZ2VvbV9kZW5zaXR5KGFscGhhPS4yKSArDQogICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPW15LmNvbG9ycykNCnByaW50KHAyKQ0KIA0KDQojIDQga2VybmVsIGRlbnNpdGllcywgRklMTEVELCB4ICYgeSBsYWJlbHMgaW1wcm92ZWQsIHhsaW0oKQ0KcDMgPC0gZ2dwbG90KHNpbS5kZiwgYWVzKHg9cmVzcG9uc2UsIGZpbGw9Z3JvdXApKSArIGdlb21fZGVuc2l0eShhbHBoYT0uMikgKyANCiAgICAgICAgICAgICB4bGFiKCJTaW11bGF0ZWQgZGF0YSIpICsgeWxhYigiRGVuc2l0eSIpICsgeGxpbSgwLCA2MCkgKyANCiAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9bXkuY29sb3JzKSArIA0KICAjc2NhbGVfZmlsbF9ncmV5KCkgKw0KICAjc2NhbGVfZmlsbF92aXJpZGlzX2QoKSArDQogICNzY2FsZV9maWxsX2JyZXdlcigpICsNCiAgI3NjYWxlX2ZpbGxfaHVlKGw9NDUpICsNCiAgI3NjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGU9Ik9yYW5nZXMiKSArDQogICNzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJHcmV5cyIpICsNCiAgIyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJCbHVlcyIpICsNCiAgIyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKw0KDQogICAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChmYWNlPSJwbGFpbiIsIGNvbG91cj0iYmxhY2siLCBzaXplPTE0KSwgDQogICAgICAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIHNpemU9MjApKSAgDQogICAgICAgDQogcHJpbnQocDMpDQogDQpgYGANCg0KPGJyPiAgDQoNCiMjIyAmbmJzcDsgSG93IGRvIHRoZSA0IGdyb3VwcyBjb21wYXJlPyANCg0KICA8aDIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6eWVsbG93OyBjb2xvcjpibHVlOyBmb250LXNpemU6MThwdDsgDQogICAgZm9udC1mYW1pbHk6J2NvbWljIHNhbnMgbXMnICwgaW1wYWN0OyBwYWRkaW5nOjEycHggMTJweCAxMnB4IDEycHg7IGJvcmRlcjo1cHggc29saWQgZ3JheTsgDQogICAgdGV4dC1hbGlnbjpjZW50ZXI7IHdvcmQtc3BhY2luZzoxLjc7IGxldHRlci1zcGFjaW5nOm5vcm1hbDsgZm9udC13ZWlnaHQ6bm9ybWFsOyI+DQogICAgVGhlIEJPWFBMT1Qgd2FzIGludmVudGVkIGJ5IHRoZSBsYXRlLCBncmVhdCBzdGF0aXN0aWNpYW4gYW5kIG1hdGggUHJvZmVzc29yIGF0IA0KICAgIFByaW5jZXRvbiBVbml2ZXJzaXR5LCBKT0hOIFRVS0VZPC9oMj4NCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpib3hwbG90KHJlc3BvbnNlIH4gZ3JvdXAsIA0KICAgICAgICBib3h3ZXg9LjYsICAgICAgICAgICAgICAjIHdpZHRoIG9mIGJveGVzLCBkZWZhdWx0IC44DQogICAgICAgIGNvbD10ZXJyYWluLmNvbG9ycyg0KSwgICMgY29sb3Igb2YgYm94IGZpbGwsIGRlZmF1bHQgImdyYXkiDQogICAgICAgIHlsaW09Yyg4LCA1NSksICAgICAgICAgICMgc3BlY2lmeSBtaW4sbWF4IG9mIHktYXhpcyB0byBhbGxvdyBmb3Igc2FtcGxlIHNpemVzIA0KICAgICAgICB4bGFiPSJHcm91cCIsIHlsYWI9IlJlc3BvbnNlIiwgICAgIyB4LHkgbGFiZWxzDQogICAgICAgIGNleC5sYWI9MS40LCBjZXguYXhpcz0xLjMsIGxhcz0xKSAjIHR5cG9ncmFwaHkNCg0KI210ZXh0KHBhc3RlKCJuID0iLCBuKSwgYWRqPWMoLjEyNSwgLjM3NSwgLjYyNSwgLjg3NSkpICMgc2FtcGxlIHNpemVzIGF0b3AgZ3JhcGgNCnRleHQoMTo0LCA4LCBwYXN0ZSgibiA9IiwgbiksIGNleD0xLjIpICMgc2FtcGxlIHNpemVzIGJlbG93IGJveHBsb3RzIA0KYGBgDQo8aDM+SXQgcGF5cyB0byBtYXN0ZXIgdGhlIGJveHBsb3QsIGFuZCBpdHMgdmFyaWFudHMuPC9oMz4NCg0KPHAgaWQ9ImJsYWNrbGluZSI+IF9fX19fX19fX19fX19fX19fXyA8L3A+IDxicj4gICAgICAgIDwhLS0gYmxhY2sgbGluZSAtLT4gDQoNCg0KPGgzPkFuYWx5c2lzIG9mIFZhcmlhbmNlIGFuZCBNdWx0aXBsZSBDb21wYXJpc29uczwvaDM+DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmFub3ZhKGxtKHJlc3BvbnNlIH4gZ3JvdXAsIGRhdGE9c2ltLmRmKSkgIyB0cmFkaXRpb25hbCwgb25lLXdheSBBbm92YQ0KYW92LnAgPC0gYW5vdmEobG0ocmVzcG9uc2UgfiBncm91cCwgZGF0YT1zaW0uZGYpKVsxLCA1XSAjIGV4dHJhY3QgcC12YWx1ZQ0KY2F0KCJvbmUtd2F5IEFub3ZhLCBmdWxsIHJlc29sdXRpb24gcC12YWx1ZSA9IiwgYW92LnAsICJcbiIpDQoNClR1a2V5SFNEKGFvdihyZXNwb25zZSB+IGdyb3VwKSwgb3JkZXJlZD1UUlVFKSAgICAjIFR1a2V5IHRlc3QsIE11bHRpcGxlIENvbXBhcmlzb25zDQpUdWtleUhTRChhb3YocmVzcG9uc2UgfiBncm91cCksIG9yZGVyZWQ9VFJVRSlbMV0gIyBUdWtleSB0ZXN0LCBwLXZhbHVlcywgbm90IHJvdW5kZWQNCg0KIyBkZWZhdWx0IGNhbGwgaXMgSG9sbS1Cb25mZXJyb25pIG1ldGhvZCwgYWxsIHBhaXJ3aXNlLCBwLXZhbHVlIGFkanVzdG1lbnQNCnBhaXJ3aXNlLnQudGVzdChyZXNwb25zZSwgZ3JvdXAsIHAuYWRqdXN0Lm1ldGhvZD0iaG9sbSIpIA0KDQojICJwbGFubmVkIiBhbGwgcGFpcndpc2UgY29tcGFyaXNvbnMsIG5vIGFkanVzdG1lbnQgb2YgcC12YWx5ZXMNCnBhaXJ3aXNlLnQudGVzdChyZXNwb25zZSwgZ3JvdXAsIHAuYWRqdXN0Lm1ldGhvZD0ibm9uZSIpIA0KDQprcnVza2FsLnRlc3QocmVzcG9uc2UsIGdyb3VwKQ0KY2F0KCJLcnVza2FsLVdhbGxpcyB0ZXN0LCBmdWxsIHJlc29sdXRpb24gcC12YWx1ZSA9IiwgDQogICAga3J1c2thbC50ZXN0KHJlc3BvbnNlLCBncm91cCkkcC52YWx1ZSwgIlxuIikNCg0KbGlicmFyeShncGxvdHMpDQpwbG90bWVhbnMocmVzcG9uc2UgfiBncm91cCwgDQogICAgICAgICAgY29ubmVjdD1GQUxTRSwgICAgICAjIGNvbm5lY3QgbWVhbnM/IGRlZmF1bHQ6IFRSVUUNCiAgICAgICAgICBuLmxhYmVsPUZBTFNFLCAgICAgICAgICAgICAgICAgIyBhZGQgc2FtcGxlIHNpemVzDQogICAgICAgICAgbWFpbj0iTWVhbnMgd2l0aCA5NSUgQ0kiLCAgICAgICMgdGl0bGUNCiAgICAgICAgICB4bGFiPSJHcm91cCIsIHlsYWI9IlJlc3BvbnNlIiwgIyB4LHkgbGFiZWxzDQogICAgICAgICAgIyBtZWFuLmxhYmVscz1UUlVFLCBkaWdpdHM9MSwgY29sPSJkYXJrZ3JheSIsICAjIHByaW50IG1lYW5zDQogICAgICAgICAgY2V4LmxhYj0xLjQsIGNleC5heGlzPTEuMywgY2V4Lm1haW49MS43LCBmb250LmxhYj0yLCAjIHR5cG9ncmFwaHkNCiAgICAgICAgICBjb2wubWFpbj0iYmx1ZSIsIGZvbnQubWFpbj0xKSAgICAgICAgICAgICAgICAgICAgICAgICMgdHlwb2dyYXBoeQ0KDQpgYGANCg0KYGBge3IgcGVybV9yLCBjYWNoZT1UUlVFLCBldmFsPVRSVUV9DQoNCiMgJ3NvdXJjZScgdGhlIFIgRWRpdG9yIGZpbGUgb2YgbmV3IGZ1bmN0aW9uIGRlZmluaXRpb25zDQpzb3VyY2UoIkM6XFxVc2Vyc1xcZHdpZ2hcXERlc2t0b3BcXEsgZnVucyBPTkUgV0FZLlIiKSANCg0KS2luY2FpZC5wZXJtLm9uZXdheShyZXNwb25zZSwgZ3JvdXAsIE5TPTVlNSwgZGVzY3JpYmVGPUZBTFNFKQ0KDQpgYGANCg0KQ29udGludWluZyB3aXRoIHRoaXMgZmFrZSwgc2ltdWxhdGVkIG9uZS13YXkgZGF0YSBvZiA0IGdyb3Vwcywgd2UgYXJlIGFsd2F5cyANCmludGVyZXN0ZWQgaW4gKipjb25maWRlbmNlIGludGVydmFscyoqIG9mIHRoZSBtZWFucy4gQmVsb3cgZmluZCB0aGUgdHJhZGl0aW9uYWwsIA0KOTUlIENJIGZvciB0aGUgNCBtZWFucyBjYWxjdWxhdGVkIHVzaW5nIG5vcm1hbCB0aGVvcnkgKHQtZGlzdHJpYnV0aW9uKS4NCg0KYGBge3IgZXZhbD1UUlVFfQ0KDQpDSW1lYW5zLm5vcm1hbHRoZW9yeShyZXNwb25zZSwgZ3JvdXAsIHByb2I9Ljk1KSAgIyAgZnJvbTogSyBmdW5zIE9ORSBXQVkuUg0KDQpgYGANCg0KSG93IHdvdWxkIHRoZSAqKmJvb3N0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzKiogb2YgdGhlc2UgNCBtZWFucywgY29tcGFyZSB0byB0aGUgDQp0cmFkaXRpb25hbCBjb25maWRlbmNlIGludGVydmFscz8gTm90aWNlIHRoYXQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSANCmFzdG9uaXNoaW5nbHkgc2ltaWxhciAtLSB0aGUgYm9vc3RyYXAganVzdCB3b3JrcyEgTXkgZnVuY3Rpb24gYmVsb3csIHVzZXMgdGhlIA0KYm9vdHN0cmFwICAqKnBlcmNlbnRpbGUgbWV0aG9kKiogdG8gY2FsY3VsYXRlIENJIGZyb20gdGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gDQpvZiB0aGUgbWVhbnMuIA0KDQpgYGB7ciBib290X0NJLCBjYWNoZT1UUlVFLCBldmFsPVRSVUV9DQoNCmJvb3RDSW1lYW5PbmVXYXkocmVzcG9uc2UsIGdyb3VwLCBOUz0yZTUpICAjIGZyb206IEsgZnVucyBPTkUgV0FZLlIgIA0KDQpgYGANCjxicj4gDQoNCioqRWZmZWN0IFNpemUqKiAtLSAqKkNvaGVuJ3MgZCoqIGlzIGEgd2lkZWx5IHVzZWQsIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZSwgDQphcyBpcyBSLXNxdWFyZSBhbmQgVmFyaWFuY2UgQ29tcG9uZW50cy4gT25lIG1heSB3aXNoIHRvIHJlcG9ydCB0aGVzZSAic3RhdGlzdGljcyIgDQp3aXRoIHRoZWlyIDk1JSBjb25maWRlbmNlIGludGVydmFscyBidXQgSSBhbSBub3QgYXdhcmUgb2YgZm9ybXVsYWljIG1ldGhvZHMgZm9yIA0KdGhpcyB0aGF0IGhhdmUgbXVjaCBzdXBwb3J0IGFtb25nIHN0YXRpc3RpY2lhbnMuIEJvb3RzdHJhcCB0byB0aGUgcmVzY3VlLiANCg0KYGBge3IgYm9vdF9Db2hlbl9Sc3EsIGNhY2hlPVRSVUUsIGV2YWw9VFJVRX0NCg0KYm9vdENvaGVuRC5vbmV3YXkocmVzcG9uc2UsIGdyb3VwLCBOUz0yZTUpDQoNCmJvb3RSc3Eub25ld2F5KHJlc3BvbnNlLCBncm91cCwgTlM9MmU1KQ0KDQpgYGANCg0KYGBge3IgYm9vdF9WQywgY2FjaGU9VFJVRSwgZXZhbD1UUlVFLCBmaWcuaGVpZ2h0PTd9DQoNCmJvb3QudmMub25ld2F5KHJlc3BvbnNlLCBncm91cCwgZGF0YS5uYW1lPSJGYWtlIGRhdGEiLCBOUz0xZTUpDQoNCmBgYA0KDQo8YnI+IA0KDQoqKlN0YXRpc3RpY2FsIHBvd2VyIGFuYWx5c2lzKiogLS0gVGhlcmUgYSAyIHdheXM6IDEpIHRyYWRpdGlvbmFsIHBvd2VyIGFuYWx5c2lzIA0KdXNpbmcgbm9ybWFsIHRoZW9yeSBhZnRlciBDb2hlbiAoMTk4OCkgYW5kIDIpIGJvb3RzdHJhcCBwb3dlciBhbmFseXNpcy4gQSBwb3dlciANCmN1cnZlIGlzIHRoZSBiZXN0IHdheSB0byB2aXN1YWxpemUgdGFidWxhciBvdXRwdXQgb2YgYW55IHR5cGUgb2YgcG93ZXIgYW5hbHlzaXMuIA0KQm9vdHN0cmFwIHBvd2VyIGFuYWx5c2lzIHVzZXMgbm8gZm9ybXVsYXMgYW5kIHRoZXJlIGFyZSBubyBhc3N1bXB0aW9ucy4gVHJhZGl0aW9uYWwgDQpwb3dlciBhbmFseXNpcyBvcGVyYXRlcyB3aXRoaW4gdGhlIGFzc3VtcHRpb25zIG9mIHRoZSBwYXJhbWV0cmljIG1ldGhvZCBpbiBxdWVzdGlvbiANCihvbmUtd2F5IEFub3ZhLCBoZXJlKTsgYm9vdHN0cmFwIHBvd2VyIGFuYWx5c2lzLCBkb2VzIG5vdC4gDQoNClRoZSAqKnB3cioqIHBhY2thZ2UgaGFzIGEgZnVuY3Rpb24gZm9yIHRyYWRpdGlvbmFsIHBvd2VyIGFuYWx5c2lzIGFmdGVyIENvaGVuIA0KKDE5ODgpIGJ5IHNvbHZpbmcgdGhlIHBvd2VyIGVxdWF0aW9ucyAobm9uLWNlbnRyYWwgRi1kaXN0cmlidXRpb24pIGFuZCBhc3N1bWluZyANCmVxdWFsIHNhbXBsZSBzaXplIHBlciBncm91cCwgd2hpY2ggb3VyIGRhdGEgZG9lcyBub3QgcmVmbGVjdC4gDQoNCk15IHdyYXBwZXIgZnVuY3Rpb24gY2FsbHMgZnVuY3Rpb24gYHB3ci5hbm92YS50ZXN0KClgIGZyb20gdGhpcyBwYWNrYWdlIHRvIGdldCBwb3dlciBhY3Jvc3MgYSByYW5nZSBvZiBzYW1wbGUgc2l6ZXMgYW5kIGZvciBhbHBoYSBvZiAuMDUsIC4wMSBhbmQgLjAwMSwgYW5kIHBsb3QgcG93ZXIgY3VydmVzIA0Kd2l0aCB0aGUgdGFibGUgb2YgcmVzdWx0cyBzZW50IHRvIHRoZSBSIENvbnNvbGUuDQoNCmBgYHtyIGV2YWw9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KcG93ZXJjdXJ2ZS5Db2hlbi5vbmV3YXkocmVzcG9uc2UsIGdyb3VwLCBsb3cubj00LCBoaWdoLm49MjQsIGJ5Lm49MiwgDQogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLm5hbWU9InNpbSBmYWtlIGRhdGEsIDQgZ3JvdXBzLCB0b3RhbCBuPTI4MSIpDQoNCiNwb3dlcmN1cnZlLnVuYmFsYW5jZWQub25ld2F5KHJlc3BvbnNlLCBncm91cCwgbG93Lm49MjAsIGhpZ2gubj05MiwgYnkubj00LCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEubmFtZT0ic2ltIGZha2UgZGF0YSwgNCBncm91cHMsIHRvdGFsIG49MjgxIikNCmBgYA0KDQpUbyBkbyAqKmJvb3RzdHJhcCBwb3dlciBhbmFseXNpcyoqIEkgcmVzYW1wbGUgdGhlIHJvdyBpbmRpY2VzIG9mIHRoZSBkYXRhIGZyYW1lIGFuZCANCmZvciBlYWNoIHNhbXBsZSB0aGUgcC12YWx1ZSBmcm9tIG9uZS13YXkgQW5vdmEgaXMgcmVjb3ZlcmVkLiBUaGUgYXJndW1lbnRzIGluIHRoZSANCmZ1bmN0aW9uIGNhbGwgKGBsb3cubmAsIGBoaWdoLm5gLCBgYnkubmApIHNwZWNpZnkgdGhlIHJhbmdlIG9mIHNhbXBsZSBzaXplcyBmb3IgDQp3aGljaCBwb3dlciBpcyBjYWxjdWxhdGVkIGZvciBhbHBoYSBvZiAuMDUsIC4wMSBhbmQgLjAwMSwgcGxvdHRlZCBhcyBwb3dlciBjdXJ2ZXMgDQp3aXRoIHRoZSB0YWJsZSBvZiByZXN1bHRzIHNlbnQgdG8gdGhlIFIgQ29uc29sZS4gDQoNCk5TIGlzIHRoZSBudW1iZXIgb2YgYm9vdHN0cmFwIHNhbXBsZXMgb2YgdGhlIGRhdGEgZnJhbWUgZm9yIGVhY2ggc2FtcGxlIHNpemUuIEhlcmUsIA0Kc3RhdGlzdGljYWwgcG93ZXIgaXMgc2ltcGx5IHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBOUyBudW1iZXIgb2YgQW5vdmEgRi10ZXN0cyB0aGF0IA0Kd2VyZSBzaWduaWZpY2FudCBhdCAuMDUsIC4wMSBhbmQgLjAwMSBsZXZlbCwgYXQgZWFjaCBzYW1wbGUgc2l6ZS4gDQoNCmBgYHtyIGJvb3RfcG93ZXIsIGNhY2hlPVRSVUUsIGV2YWw9VFJVRX0NCg0KYm9vdC5wb3dlcmN1cnZlLm9uZXdheShyZXNwb25zZSwgZ3JvdXAsIE5TPTJlNCwgbG93Lm49MjAsIGhpZ2gubj05MiwgYnkubj00LA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhLm5hbWU9InNpbSBmYWtlIGRhdGEsIDQgZ3JvdXBzLCB0b3RhbCBuPTI4MSIpDQpgYGANCjxicj4gDQoNCioqQmF5ZXMgRmFjdG9yIEFub3ZhKiogLS0gVGhlIGNvbnRyaWJ1dGVkIFIgcGFja2FnZSwgYCBCYXllc0ZhY3RvciBgIGhhcyANCmZ1bmN0aW9ucyBmb3IgQmF5ZXMgRmFjdG9yIEFub3ZhLCBjb3JyZWxhdGlvbiwgbGluZWFyIHJlZ3Jlc3Npb24gYW5kIG1vcmUuIE15IA0KZnVuY3Rpb24gYCBCYXllc0ZhY3RvckFub3ZhLm9uZXdheSgpIGAgaXMgbWVyZWx5IGEgd3JhcHBlciBhcm91bmQgZnVuY3Rpb24gDQpgIGFub3ZhQkYoKSBgIGZyb20gYCBCYXllc0ZhY3RvcmAuICAmbmJzcDsgSGVyZSwgQmF5ZXMgRmFjdG9yIEFub3ZhIHJldHVybmVkIDM5IGJpbGxpb24gdGltZXMgDQooMC4wMiUgQ3JlZGlibGUgSW50ZXJ2YWwpIG1vcmUgc3VwcG9ydCBmb3IgaGV0ZXJvZ2VuZWl0eSAoSDE6KSBhbW9uZyB0aGUgNCBtZWFucyANCnRoYW4gZm9yIGhvbW9nZW5laXR5IChIbzopIGFtb25nIHRoZSBtZWFucy4gDQoNCkl0J3MgaGVscGZ1bCB0aGF0IEJheWVzaWFuIHN0YXRpc3RpY2lhbnMgaGF2ZSB3cml0dGVuIHByb2NlZHVyZXMgdGhhdCBvcGVyYXRlIHNvcnQgDQpvZiB3aXRoaW4gdGhlIGNvbmNlcHR1YWwgZnJhbWV3b3JrIG9mIGZhbWlsaWFyLCBzdGF0aXN0aWNhbCBtb2RlbHMsIGluY2x1ZGluZyBBbm92YTsgDQpzZWUgKipHZWxtYW4sIEFuZHJldyoqLiAoMjAwNSkgICpBbmFseXNpcyBvZiBWYXJpYW5jZSDigJQgd2h5IGl0IGlzIG1vcmUgaW1wb3J0YW50IA0KdGhhbiBldmVyKi4gKipBbm5hbHMgb2YgU3RhdGlzdGljcyoqLCAzMywgcHAuIDEtNTMuIA0KICANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KDQpCYXllc0ZhY3RvckFub3ZhKHJlc3BvbnNlLCBncm91cCkNCg0KYGBgDQoNCg0KPGJyPiAgIA0KDQojIyAmbmJzcDsgQml2YXJpYXRlIGRhdGEgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQojIyMgJm5ic3A7IFNpbXBsZSBsaW5lIGdyYXBocyBhbmQgc2NhdHRlciBwbG90cw0KVW5kZXIgZGV2ZWxvcG1lbnQgICANCg0KIyMjICZuYnNwOyBJbnRlcmFjdGl2ZSBncmFwaHMgDQoNClIgYW5kIFIgTWFya2Rvd24gZW5hYmxlIGludGVyYWN0aXZlIGdyYXBocy4gVGhlICoqcGxvdGx5KiogcGFja2FnZSBtYWtlcyBnZ3Bsb3QyIA0KZ3JhcGhzLCBpbnRlcmFjdGl2ZS4gSG92ZXIgb3ZlciB0aGUgcG9pbnRzLiBDbGljayBvbiB0b3AgbGVnZW5kIGZvciBvcHRpb25zLiBDbGljayANCm9uIHRoZSBsZWdlbmQgdG8gZGUvc2VsZWN0IGNvbnRpbmVudHMuIENpcmNsZSBzaXplIGlzIHByb3BvcnRpb25hbCB0byBwb3B1bGF0aW9uIA0Kc2l6ZSBpbiAyMDA3IGZvciBMaWZlIEV4cGVjdGFuY3kgdnMuIEdEUCBwZXIgcGVyc29uIGluIFVTIGRvbGxhcnMgKGZpcnN0IGdyYXBoKSANCmFuZCBMaWZlIEV4cGVjdGFuY3kgdnMuIFBvcHVsYXRpb24gU2l6ZSAoc2Vjb25kIGdyYXBoKS4gIA0KDQpUaGUgZGF0YSBpcyBmcm9tIGh0dHBzOi8vd3d3LkdhcG1pbmRlci5vcmcsIGZvdW5kZWQgaW4gMjAwNSBpbiBTdG9ja2hvbG0gYnkgRHIuIA0KSGFucyBSb3NsaW5nIChQcm9mZXNzb3Igb2YgSW50ZXJuYXRpb25hbCBIZWFsdGgsIEthcm9saW5za2EgSW5zdGl0dXRlKSBhbmQgaGlzIA0KZ3JvdXAuICANCg0KSGUgYmVjYW1lIHdvcmxkIGZhbW91cyBieSBoaXMgVEVEIHRhbGtzIGFuZCB2aWRlb3MsIHNvbWUgb2Ygd2hpY2ggd2UnbGwgdmlldyBpbiANCkJpbyAyNDAuIDxicj4gUHJvZmVzc29yIFJvc2xpbmcncyBsYXN0IGJvb2sgd2FzICpGYWN0ZnVsbmVzcyo6IA0KaHR0cHM6Ly93d3cuZ2FwbWluZGVyLm9yZy9mYWN0ZnVsbmVzcy1ib29rLyAgPGJyPiANClVuZm9ydHVuYXRlbHksIHRoaXMgdHlwZSBvZiBpbnRlcmFjdGl2ZSBncmFwaCBpcyBiZXlvbmQgdGhlIHRpbWUgZnJhbWUgb2YgQmlvIDI0MC4gIA0KPGJyPiANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9NiwgZmlnLmNhcD0iUHV0IGN1cnNvciBpbnNpZGUgZ3JhcGggdG8gaW50ZXJhY3QgJiBhdG9wIGdyYXBoIGZvciBtZW51In0NCg0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGdhcG1pbmRlcikNCiANCnAxIDwtIGdhcG1pbmRlciAlPiUNCiAgZmlsdGVyKHllYXI9PTIwMDcpICU+JQ0KICBnZ3Bsb3QoIGFlcyhnZHBQZXJjYXAsIGxpZmVFeHAsIHNpemUgPSBwb3AsIGNvbG9yPWNvbnRpbmVudCkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgc2NhbGVfeF9sb2cxMCgpICsNCiAgdGhlbWVfYncoKQ0KIA0KZ2dwbG90bHkocDEpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9NiwgZmlnLmNhcD0iUHV0IGN1cnNvciBpbnNpZGUgZ3JhcGggdG8gaW50ZXJhY3QgJiBhdG9wIGdyYXBoIGZvciBtZW51In0NCg0KcDIgPC0gZ2FwbWluZGVyICU+JQ0KICBmaWx0ZXIoeWVhcj09MjAwNykgJT4lDQogIGdncGxvdCggYWVzKHBvcCwgbGlmZUV4cCwgc2l6ZSA9IGdkcFBlcmNhcCwgY29sb3I9Y29udGluZW50KSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBzY2FsZV94X2xvZzEwKCkgKw0KICB0aGVtZV9idygpDQogDQpnZ3Bsb3RseShwMikNCmBgYA0KDQo8YnI+IA0KDQojIyMgJm5ic3A7IENvcnJlbGF0aW9uDQpVbmRlciBkZXZlbG9wbWVudCANCg0KIyMjICZuYnNwOyBSZWdyZXNzaW9uDQpVbmRlciBkZXZlbG9wbWVudCANCg0KIyAmbmJzcDsgUiBFZGl0b3IgZmlsZXMgLS0gPGk+Y29kaW5nIGNvbnZlbnRpb25zIGluIEJpbyAyNDA8L2k+ICAgDQoNCjxicj4gDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyMiI+DQo8cCBzdHlsZT0iZm9udC1mYW1pbHk6Z2FyYW1vbmQ7IGZvbnQtc2l6ZToyM3B4OyBmb250LXN0eWxlOml0YWxpYzsgY29sb3I6ZGFya3JlZDsNCmxpbmUtaGVpZ2h0OjEuMTsgbGV0dGVyLXNwYWNpbmc6MXB4OyB0ZXh0LWFsaWduOmxlZnQ7IHdvcmQtc3BhY2luZzo1cHg7IA0KdGV4dC1pbmRlbnQ6MHB4OyAiPiANCg0KVGhpcyBzZW1lc3RlciB5b3Ugd2lsbCBiZSByZXF1aXJlZCB0byB3cml0ZSBtYW55IDxiPlIgcHJvZ3JhbXM8L2I+IChpLmUuLCANCjxiPiBSIEVkaXRvciBmaWxlczwvYj4sIGUuZy4sIGZvby5SKS4gDQo8YnI+PGJyPg0KUiBFZGl0b3IgZmlsZXMgYXJlIGp1c3QgPGI+cGxhaW4gdGV4dCBmaWxlczwvYj4gb2YgUiBjb2RlIA0KdGhhdCB3ZSBzdWJtaXQgdG9wLWRvd24sIHRvIHRoZSBSIENvbnNvbGUgZm9yIGV4ZWN1dGlvbiwgKippbnRlcmFjdGl2ZWx5KiouIA0KPGJyPjxicj4gDQpFYWNoIG9mIHRoZXNlIFIgRWRpdG9yIGZpbGVzIHRoaXMgc2VtZXN0ZXIsIGlzIG1vdGl2YXRlZCBieSBhIGRpZmZlcmVudCANCjxiPmJpb2xvZ2ljYWwgZGF0YSBzZXQ8L2I+IGZvciB3aGljaCBncmFwaGljYWwgdmlzdWFsaXphdGlvbiBhbmQgc3RhdGlzdGljYWwgDQphbmFseXNpcyBhcmUgZGVzaXJlZC4gPGJyPjxicj4gDQpJbiBCaW8gMjQwLCA8Yj5zdGF0aXN0aWNhbCBhbmFseXNpczwvYj4gcmVmZXJzIHRvIHRoZSBleHBsb3JhdG9yeSBhbmQgdG8gdGhlIGZvcm1hbDsgDQp0byB0aGUgcGFyYW1ldHJpYyBhbmQgbm9ucGFyYW1ldHJpYzsgdGhlIHRyYWRpdGlvbmFsIGFuZCB0aGUgY29tcHV0YXRpb25hbGx5IA0KaW50ZW5zaXZlIChwZXJtdXRhdGlvbiwgYm9vdHN0cmFwLCBNb250ZSBDYXJsbyBzaW11bGF0aW9uKTsgYW5kIHRvIHRoZSBCYXllc2lhbi4gDQo8Yj48YnI+PGJyPg0KR3JhcGhpY2FsIHZpc3VhbGl6YXRpb248L2I+IG9idmlvdXNseSByZWZlcnMgdG8gZ3JhcGhzLiBSIGxlYWRzIHRoZSB3b3JsZCBpbiB0aGUgDQpxdWFudGl0eSwgcXVhbGl0eSBhbmQgZGl2ZXJzaXR5IG9mIGl0cyBncmFwaGljYWwgcHJvZ3JhbW1pbmcgZW52aXJvbm1lbnRzLiANCjxicj48YnI+DQpUaGUgbWFpbiBmb2N1cyBvZiBncmFwaGljcyBpbiBCaW8gMjQwIGlzIG9uIHdoYXQgd2UgY2FsbCA8Yj5iYXNlIFIgZ3JhcGhpY3M8L2I+LiANCkJ1dCwgSSB3aWxsIGludHJvZHVjZSBncmFwaCBlbnZpcm9ubWVudHMgKGUuZy4sIGhleGJpbiwgbGF0dGljZSwgZ2dwbG90MikgYmFzZWQgb24gIA0KdGhlIGZhbW91cyA8Yj5ncmlkPC9iPiBwYWNrYWdlIGJ5IFBhdWwgTXVycmVsbCBvciB0aG9zZSBiYXNlZCBvbiBKYXZhU2NyaXB0IA0KKGUuZy4sIHBsb3RseSkuDQo8YnI+PGJyPiANCkluaXRpYWxseSwgYWxsIHRoaXMgY2FuIGJlIG92ZXJ3aGVsbWluZyBpZiB5b3UndmUgaGFkIG5vIGNvbXB1dGVyIHByb2dyYW1taW5nIG9yIA0Kc3RhdGlzdGljYWwgZXhwZXJpZW5jZS4gSG93ZXZlciwgaXQncyBteSBqb2IgdG8gbWFrZSBpdCBlYXN5IGJ5IGhlbHBpbmcgeW91IGdldCBhIA0KZm9vdGhvbGQgaW4gUiwgaW5jbHVkaW5nIGJ5IHN0YXJ0aW5nIDxiPnNtYWxsPC9iPi4gDQo8YnI+PGJyPg0KSW4gb3VyIFIgY29kaW5nIHdvcmtmbG93LCBpdCdzIGJlc3QgdG8gKipzdGFydCBzbWFsbCoqIGFuZCAqKmZhaWwgZmFzdGVyKiouIFRoZSANCnNvb25lciB3ZSBhY2NlcHQgYW5kIGxlYXJuIGZyb20gb3VyICoqZmFpbHVyZXMqKiAoUiBjb2RlIHRoYXQgdGhyb3dzIGVycm9ycyBhbmQvb3IgDQpkb2VzIHRoZSB3cm9uZyB0aGluZykgdGhlIHF1aWNrZXIgd2UgY2FuIHR1cm4gdGhlbSBpbnRvICoqc3VjY2Vzc2VzKiogDQoocmVsaWFibGUgY29kZSkuIFRoaXMgaG9sZHMgdHJ1ZSBmb3IgUiBwcm9ncmFtbWVycyB3aG8gYXJlIGJlZ2lubmVycyBhcyB3ZWxsIGFzIA0KZm9yIHRob3NlIHdobyBhcmUgZXhwZXJ0cy4gDQo8L3A+DQo8L2Rpdj4gPGJyPiANCg0KIyMgJm5ic3A7IEludHJvZHVjdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSAuLi4uLi4uLi4uLiAtLT4gDQoNCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjMiPg0KRXZlcnkgY2xhc3MgcGVyaW9kIEkveW91IHdpbGwgd3JpdGUsIGRlYnVnIGFuZCBydW4gY29kZSBpbiBSIEVkaXRvciBmaWxlcy4gV2UgDQpwcmFjdGljZSAqKnRvcC1kb3duKiogY29kaW5nIGFuZCB0b3AtZG93biBkZWJ1Z2dpbmcuIGxlYWRpbmcgdG8gcmVsaWFibGUsIGNsZWFuIA0KYW5kIHJlYWRhYmxlIGNvZGUuIA0KDQpZb3Ugd2lsbCBsZWFybiB0byBhcHByZWNpYXRlIHRoZSBhZGFnZTogJm5ic3A7ICpUbyBsYXZpc2ggeW91ciBjb2RlIHdpdGggDQoqKmNvbW1lbnRzKiogaXMgdG8gY29kZSB3aXNlbHkuKg0KDQpZb3VyICoqUiBFZGl0b3IgZmlsZXMqKiBtdXN0IGNvbmZvcm0gdG8gbXkgKipjb2RpbmcgY29udmVudGlvbnMqKi4gQWZ0ZXIgQmlvIDI0MCANCnlvdSBtYXkgd3JpdGUgYWxsIHRoZSBpbGxpdGVyYXRlLCB1Z2x5IGNvZGUgeW91IHdpc2ggLS0gY29kZSB0aGF0IGlmIGdpdmVuIHRvIG90aGVycyANCm9yIGV2ZW4gd2hlbiB2aWV3ZWQgYnkgeW91IDYgbW9udGhzIGxhdGVyLCBtYXkgbGlrZWx5IGFwcGVhciBhcyBnaWJiZXJpc2guIA0KDQpNeSBtYW5kYXRvcnkgY29kaW5nIGNvbnZlbnRpb25zIGFyZSBpbiB0aGUgdHJlYXN1cmVkIHNwaXJpdCBvZiANCioqbGl0ZXJhdGUgcHJvZ3JhbW1pbmcuKiogDQoNCkluIEJpbyAyNDAgZm9yIFIsIHRoZXNlIGNvbnZlbnRpb25zIGluY2x1ZGU6ICZuYnNwOyANCip2YWxpZCAmIHByb3BlciBmaWxlIG5hbWVzLCBjb21tZW50cywgbGluZSBzcGFjaW5nLCBsaW5lIHdpZHRoIG9mIDg1IGNoYXJhY3RlcnMgbWF4LCANCmluZGVudGF0aW9uLCBjb250ZW50IG9mIGZpcnN0IGxpbmUgb2YgZmlsZSwgY29udGVudCBvZiBsYXN0IGxpbmUgb2YgZmlsZSwgdmFsaWQgDQpuYW1lcyBvZiBvYmplY3RzLCB3aXNlIG5hbWVzIG9mIG9iamVjdHMuKiANCg0KVGhlIGFiaWxpdHkgdG8gPHU+d3JpdGU8L3U+LCB0byA8dT5kZWJ1ZzwvdT4gYW5kIHRvIDx1PnJ1bjwvdT4gY29tcHV0ZXIgcHJvZ3JhbXMgaW4gDQpSIChSIEVkaXRvciBmaWxlcykgaXMgYSBtYWpvciBlbXBoYXNpcyBpbiBCaW8gMjQwIGFuZCBpcyByZXF1aXJlZCBvbiBlYWNoIG9mIHRoZSAzIA0KVGVzdHMuIEl0J3MgYW4gYWNjb21wbGlzaG1lbnQgeW91IHdpbGwgdGFrZSB3aXRoIHlvdSBiZXlvbmQgdGhpcyBjb3Vyc2UsIGFuZCBpbnRvIA0KeW91ciBpbW1lZGlhdGUgYW5kIGZ1dHVyZSwgY2FyZWVyIGRldmVsb3BtZW50LiANCg0KVXNpbmcgUiBhbmQgY3JlYXRpbmcgdXNlZnVsLCBSIEVkaXRvciBmaWxlcyByZXF1aXJlcyAqKnBhdGllbmNlKiosICoqYXR0ZW50aW9uIHRvIA0KZGV0YWlsKiosIG11Y2ggKipwcmFjdGljZSoqIGFuZCBjb21mb3J0IHdpdGggKip0cmlhbC1hbmQtZXJyb3IuKiogSXQncyB0aGF0IHdheSB3aXRoIA0KYW55IHByb2dyYW1taW5nIGxhbmd1YWdlLiANCg0KVGhpcyBwYXN0IHN1bW1lciwgYXMgSSBzdHJ1Z2dsZWQgcHJvZ3JhbW1pbmcgaW4gUiwgSFRNTCwgQ1NTLCBKYXZhU2NyaXB0LCBMYVRleCBhbmQgDQpSIE1hcmtkb3duIC0tIGl0IHdhcyBvbmx5IGJ5IHBhdGllbmNlLCBwcmFjdGljZSBhbmQgdHJpYWwtYW5kLWVycm9yIHRoYXQgYW55dGhpbmcgDQp3YXMgYWNjb21wbGlzaGVkLiANCg0KU3VyZSwgSSBhbSBzdXBwb3NlZCB0byBiZSBhbiBleHBlcnQgaW4gUiwgYnV0IGV2ZXJ5IGRheSBJIHdyaXRlIFIgY29kZSB0aGF0IHRocm93cyANCmVycm9ycyBhdCB0aGUgUiBDb25zb2xlLCBJIG1ha2UgcG9vciBjb2RpbmcgZGVjaXNpb25zIGFuZCBteSBwcm9ncmFtbWluZyB3b3JrZmxvdyBpcyANCnVud2lzZS4gQnV0LCB3aXRoIHBhdGllbmNlIGFuZCB0cmlhbC1hbmQtZXJyb3IsIEkgbWFrZSBwcm9ncmVzcyBpbiBjb2RpbmcgYW5kIA0KZ2V0dGluZyByZWxpYWJsZSBvdXRwdXQuIA0KDQpQcm9mZXNzb3JzIHNheSAqd3JpdGluZyBpcyByZXZpc2lvbiouIFRoZSBzYW1lIGhvbGRzIGZvciB0eXBpbmcgY29tcHV0ZXIgcHJvZ3JhbXMuIA0KSWYgaXQgdGFrZXMgYW4gaG91ciB0byB3cml0ZSBhIGdvb2Qgc2VudGVuY2UgaW4gRW5nbGlzaCwgc28gd2hhdD8gSXQgb2Z0ZW4gdGFrZXMgbWUgDQphbiBob3VyLiBJZiBpdCB0YWtlcyBhbiBob3VyIHRvIHdyaXRlIHNldmVyYWwgbGluZXMgb2YgcHJvcGVyIFIgY29kZSwgc28gd2hhdD8gDQpJbiBsaWZlLCB0aGUgZ29vZCBhbmQgdGhlIHByb3BlciwgYXJlIG5vdCBlYXN5IGFuZCBtYXkgbm90IGhhcHBlbiBxdWlja2x5LiANCg0KUmVnYXJkbGVzcyBvZiB3aGF0IGEgcG9lbSBtZWFucywgKml0IG11c3QgbG9vayBnb29kIG9uIHRoZSBwYWdlLiogVGhlIHNhbWUgaG9sZHMgZm9yIA0KY29tcHV0ZXIgcHJvZ3JhbXMuIFdyaXRpbmcgYSBjb21wdXRlciBwcm9ncmFtIGlzIGFzIGNyZWF0aXZlLCBhcnRpc3RpYyBhbmQgDQpmdWxmaWxsaW5nIGFzIGFueSBodW1hbiBhY3Rpdml0eS4gDQogDQpXZSBzZWVrIFIgRWRpdG9yIGZpbGVzIChwcm9ncmFtczogc21hbGwgb3IgbGFyZ2UpIHRoYXQgYXJlIGNsZWFyLCBjbGVhbiwgDQpyZWFkYWJsZSwgcHJpbnRhYmxlLCB3ZWxsLXRlc3RlZCwgYnVnLWZyZWUsIGFwcHJvcHJpYXRlbHkgY29tbWVudGVkIGFuZCBhIGpveSB0byANCnZpZXcgYW5kIHRvIHJ1bi4gVGhvc2Ugd2hvIHdvcmsgaGFyZCBpbiBCaW8gMjQwLCB3aWxsIGNyZWF0ZSBSIEVkaXRvciBmaWxlcyB0aGF0IA0KbWFrZSB0aGVtIHByb3VkLiANCg0KQXMgdGhlIHNlbWVzdGVyIHByb2NlZWRzIGluIEJpbyAyNDAsIHlvdSBtYXkgZmluZCB5b3Vyc2VsZiBjcmFmdGluZyBSIHByb2dyYW1zIHRoYXQgDQp3aWxsIGFkdmFuY2UgeW91ciBjYXJlZXIgYXMgeW91IGNvbW11bmljYXRlIHRoZXNlIHByb2dyYW1zIGluIHlvdXIgcmVzZWFyY2ggbGFiLCANCmZvciBlbXBsb3ltZW50IG9wcG9ydHVuaXRpZXMgb3IgaW4geW91ciBhcHBsaWNhdGlvbnMgdG8gcHJvZmVzc2lvbmFsIGFuZCANCmdyYWR1YXRlIHNjaG9vbHMuIA0KPC9kaXY+DQoNCjxicj4gDQo8c3R5bGU+DQoubXlEaXZ7DQogIGJvcmRlcjogNHB4IG91dHNldCByZWQ7DQogIGJvcmRlci1yYWRpdXM6IDEwcHg7DQogIGJhY2tncm91bmQtY29sb3I6IGxpZ2h0Ymx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICANCiAgZm9udC1mYW1pbHk6ICJHYXJhbW9uZCIgYm9sZDsNCiAgZm9udC1zaXplOiAyOHB4Ow0KICBjb2xvcjogZGFya3JlZDsNCiAgd29yZC1zcGFjaW5nOiA1cHg7DQogIA0KICBtYXJnaW46IDIwcHg7DQogIHBhZGRpbmc6IDE1cHg7DQp9DQo8L3N0eWxlPg0KDQo8ZGl2IGNsYXNzPSJteURpdiI+DQogIDxwPiA8dT5SIEVkaXRvciBmaWxlczwvdT4gYXJlIHRoZSA8dT5pbnRlbGxlY3R1YWwgY2FwaXRhbDwvdT4geW91IGNyYWZ0LCANCiAgYWNjdW11bGF0ZSwgdXNlIGluIEJpbyAyNDAgYW5kIHRha2Ugd2l0aCB5b3UsIGJleW9uZCBMZWhtYW4gQ29sbGVnZS48L3A+IA0KPC9kaXY+DQo8YnI+DQoNCj4gIipXZSB3YW50ZWQgdXNlcnMgdG8gYmUgYWJsZSB0byBiZWdpbiBpbiBhbiAqKmludGVyYWN0aXZlIGVudmlyb25tZW50KiosIHdoZXJlIHRoZXkgDQpkaWQgbm90IGNvbnNjaW91c2x5IHRoaW5rIG9mIHByb2dyYW1taW5nLiAmbmJzcDtUaGVuIGFzIHRoZWlyIG5lZWRzIGJlY2FtZSBjbGVhcmVyIA0KYW5kIHRoZWlyIHNvcGhpc3RpY2F0aW9uIGluY3JlYXNlZCwgdGhleSBzaG91bGQgYmUgYWJsZSAqKnRvIHNsaWRlIGdyYWR1YWxseSBpbnRvIA0KcHJvZ3JhbW1pbmcqKiB3aGVuIHRoZSBsYW5ndWFnZSBhbmQgc3lzdGVtIGFzcGVjdHMgd291bGQgYmVjb21lIG1vcmUgDQppbXBvcnRhbnQuKiIgJm5ic3A7Jm5ic3A7IC0tLSBKb2huIENoYW1iZXJzIA0KDQo8YnI+PGJyPiANCg0KDQojIyAmbmJzcDsgQSBzbWFsbCAmbmJzcDt4LCB5Jm5ic3A7IGRhdGEgc2V0DQoNCjxicj4gDQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyMiI+DQo8cCBzdHlsZT0iZm9udC1mYW1pbHk6Z2FyYW1vbmQ7IGZvbnQtc2l6ZToyM3B4OyBmb250LXN0eWxlOml0YWxpYzsgY29sb3I6ZGFya3JlZDsNCmxpbmUtaGVpZ2h0OjEuMTsgbGV0dGVyLXNwYWNpbmc6MXB4OyB0ZXh0LWFsaWduOmxlZnQ7IHdvcmQtc3BhY2luZzo1cHg7IA0KdGV4dC1pbmRlbnQ6MHB4OyAiPg0KDQpHaXZlbiBiZWxvdywgcGxlYXNlIGluc3BlY3QgdGhlIHZlcnkgc21hbGwgPGk+eCx5PC9pPiBkYXRhIHNldCBvbiBhIDY1IHllYXIgb2xkIA0KZmVtYWxlIHBhdGllbnQgYmVpbmcgdHJlYXRlZCBmb3IgT3N0ZW9wb3Jvc2lzIHdpdGggQWxlbmRyb25hdGUgd2hpY2ggaXMgYSANCm5pdHJvZ2VuIGNvbnRhaW5pbmcgYmlzcGhvc3Bob25hdGUgdGhhdCBiaW5kcyB0byBib25lIHN1cmZhY2VzIGFuZCBwcm9tb3RlcyBib25lIA0KZGVuc2l0eSBpbmNyZWFzZS4gDQo8YnI+PGJyPiANCjxiPk91ciB0YXNrIGlzIHRvIHNhdmUgdGhpcyBtZWRpY2FsIGRhdGEgaW4gYW4gUiBFZGl0b3IgZmlsZSwgZ3JhcGggaXQsIGV4cGxvcmUgaXQgDQphbmQgcGVyZm9ybSBzdGF0aXN0aWNhbCBhbmFseXNpcy48L2I+IA0KPGJyPjxicj4gDQpBIGdyYXBoIGluY29ycG9yYXRpbmcgc3RhdGlzdGljYWwgYW5hbHlzaXMgd291bGQgaW5mb3JtIGhlciBQaHlzaWNpYW4gb24gaWYgdGhlIA0KdHJlYXRtZW50IHdhcyBlZmZlY3RpdmUgYWNyb3NzIHRoZSA3LjcgeWVhcnMgYW5kIGlmIGl0IHNob3VsZCBiZSBjb250aW51ZWQuICANCk9idmlvdXNseSwgdGhpcyBpcyBpbXBvcnRhbnQgdG8gdGhlIHBhdGllbnQgYW5kIHRvIHRoZSBEb2N0b3IncyBIaXBwb2NyYXRpYyBPYXRoLiANCjxicj48YnI+DQpJbiBnZW5lcmFsLCBmb3IgdmVyeSBzbWFsbCBzYW1wbGUgc2l6ZXMgPGI+Z3JhcGhpY2FsIHZpc3VhbGl6YXRpb248L2I+IHJlbWFpbnMgDQpwYXJhbW91bnQuIE9mdGVuLCB3ZSBzaW1wbHkgZ3JhcGggc21hbGwgZGF0YSBhbmQgbGV0IGl0IHNwZWFrIGZvciBpdHNlbGY7IHRoaXMgDQpoYXMgYWx3YXlzIGJlZW4gYWNjZXB0YWJsZSBpbiBTY2llbmNlIGFuZCBpbiBwZWVyIHJldmlld2VkIGpvdXJuYWxzLg0KPGJyPjxicj4NCkFsc28gZm9yIHNtYWxsIHNhbXBsZSBzaXplcywgd2UgcHJvY2VlZCB3aXRoIHN0YXRpc3RpY2FsIGFuYWx5c2lzIHVzaW5nIGNhdXRpb24sIA0KcmVhbGl6aW5nIGl0IG1heSBoYXZlIGxpdHRsZSBpZiBhbnksIGluZmVyZW50aWFsIHZhbHVlIGJleW9uZCB0aGUgZGF0YSBhdCBoYW5kLiANCjwvcD4NCjwvZGl2PiA8YnI+IA0KDQoqIkEgNjUgeWVhciBvbGQgd29tYW4gd2l0aCBsb3cgYm9uZSBkZW5zaXR5IGluIDIwMDIgd2FzIHRyZWF0ZWQgd2l0aCBhbGVuZHJvbmF0ZSANCnRocm91Z2ggdGhlIHllYXIgMjAwOS4gQm9uZSBkZW5zaXR5IHdhcyBtZWFzdXJlZCBpcnJlZ3VsYXJseSBvdmVyIHRoaXMgcGVyaW9kLiIqIA0KJm5ic3A7IFNvdXJjZTogcC4gNTQ0LTU0NSA8dT5pbjwvdT4gUm9zbmVyLCBCZXJuYXJkLiAyMDE2LiA8dT5GdW5kYW1lbnRhbHMgb2YgDQpCaW9zdGF0aXN0aWNzPC91PiwgOHRoIGVkLiBDZW5nYWdlLCBCb3N0b24uIDkyNyBwYWdlcy4gVGhpcyB0ZXh0Ym9vayBpcyB1c2VkIGF0IA0KSGFydmFyZCdzIG1lZGljYWwgc2Nob29sIGFuZCByZWxhdGVkIGdyYWR1YXRlIHByb2dyYW1zLiANCjxicj48YnI+DQoNCjxoND4gQm9uZSBkZW5zaXR5IChnL2NtXjJeKSAmbmJzcDsgYnkmbmJzcDsgVGltZSAobW9udGhzKTwvaDQ+ICANCg0KKipUaW1lKiogaXMgbW9udGhzIHNpbmNlIGJhc2VsaW5lLiBBdCBlYWNoIHZpc2l0LCAqKmJvbmUgZGVuc2l0eSoqIChnL2NtXjJeKSB3YXMgDQptZWFzdXJlZCBieSBERVhBIHNjYW4sIGZvciAqKmx1bWJhciBzcGluZSoqIGFuZCAqKmZlbW9yYWwgbmVjayAoaGlwKSoqLiANClRpbWUgaXMgb3VyICoqKngqKiogdmFyaWFibGUsIHBhaXJlZCB3aXRoIGJvbmUgZGVuc2l0eSBhcyAqKip5KioqLiANCg0KfCBWaXNpdCAgfCBUaW1lIChtb250aHMpIHwgTHVtYmFyIFNwaW5lIGcvY21eMl4gIHwgIEZlbW9yYWwgTmVjayAoaGlwKSwgZy9jbV4yXnwNCnwtLS0tLS0tOnw6LS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8DQp8IDEgICAgICB8IDAgICAgICAgICAgICAgfCAgMC43OTcgICAgICAgICAgICAgICAgfCAgMC42NDMgICAgICAgICAgICAgICAgICAgICAgfA0KfCAyICAgICAgfCA4ICAgICAgICAgICAgIHwgIDAuODA2ICAgICAgICAgICAgICAgIHwgIDAuNjM4ICAgICAgICAgICAgICAgICAgICAgIHwNCnwgMyAgICAgIHwgMTggICAgICAgICAgICB8ICAwLjgxNyAgICAgICAgICAgICAgICB8ICAwLjY0OCAgICAgICAgICAgICAgICAgICAgICB8DQp8IDQgICAgICB8IDQ4ICAgICAgICAgICAgfCAgMC44MjUgICAgICAgICAgICAgICAgfCAgMC42NzQgICAgICAgICAgICAgICAgICAgICAgfA0KfCA1ICAgICAgfCA2NCAgICAgICAgICAgIHwgIDAuODM3ICAgICAgICAgICAgICAgIHwgIDAuNjQwICAgICAgICAgICAgICAgICAgICAgIHwNCnwgNiAgICAgIHwgNjYgICAgICAgICAgICB8ICAwLjg0MSAgICAgICAgICAgICAgICB8ICAwLjY3NiAgICAgICAgICAgICAgICAgICAgICB8DQp8IDcgICAgICB8IDc5ICAgICAgICAgICAgfCAgMC44ODYgICAgICAgICAgICAgICAgfCAgMC42NTEgICAgICAgICAgICAgICAgICAgICAgfA0KfCA4ICAgICAgfCA5MiAgICAgICAgICAgIHwgIDAuODgxICAgICAgICAgICAgICAgIHwgIDAuNjgwICAgICAgICAgICAgICAgICAgICAgIHwNCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjQwJSIsIGRwaT0yMDAsIGZpZy5hbGlnbj0iZGVmYXVsdCJ9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvbHVtYmFyIHNwaW5lIDEuanBnIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvZmVtb3JhbCBuZWNrIGZyYWN0dXJlLmpwZyIpDQoNCmBgYA0KDQoNCjxicj4gDQoNCiMjICZuYnNwOyBSIEVkaXRvciBmaWxlIC0tIDxpPmVzdGFibGlzaCB0aGUgZmlsZTwvaT4gIA0KPGJyPg0KDQo8c3R5bGU+IC5uZXdzcGFwZXIyMntjb2x1bW4tY291bnQ6MjsgY29sdW1uLWdhcDo4MHB4OyBmb250LXNpemU6MTAwJTsgDQpjb2x1bW4tcnVsZToxcHggc29saWQgbGlnaHRncmF5IH0gPC9zdHlsZT4gDQo8IS0tICA8ZGl2IGNsYXNzPSJuZXdzcGFwZXIyMiI+ICAtLT4gDQoNCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjIyIj4NCjxwIHN0eWxlPSJmb250LWZhbWlseTpnYXJhbW9uZDsgZm9udC1zaXplOjIzcHg7IGZvbnQtc3R5bGU6aXRhbGljOyBjb2xvcjpkYXJrcmVkOw0KbGluZS1oZWlnaHQ6MS4xOyBsZXR0ZXItc3BhY2luZzoxcHg7IHRleHQtYWxpZ246bGVmdDsgd29yZC1zcGFjaW5nOjVweDsgDQp0ZXh0LWluZGVudDowcHg7ICI+IA0KDQpIZXJlIEkgZGVtb25zdHJhdGUgPHU+YmVzdCBwcmFjdGljZXM8L3U+IG9uIGhvdyB0byBlc3RhYmxpc2ggKipSIEVkaXRvciBmaWxlcyoqIA0KdG8gc3RvcmUsIGdyYXBoIGFuZCBhbmFseXplIGRhdGEgaW4gQmlvIDI0MC4gPGJyPjxicj4gUiBFZGl0b3IgZmlsZXMgYXJlIGFsc28gDQpjYWxsZWQgY29tcHV0ZXIgcHJvZ3JhbXMgb3Igc2NyaXB0cy4gPGJyPiAgDQpUaGUgY29udGVudCAobGluZXMgb2YgY29kZSkgb2YgYW4gUiBFZGl0b3IgZmlsZSANCmlzIHN1Ym1pdHRlZCBpbiB0b3AtZG93biBmYXNoaW9uLCB0byB0aGUgUiBDb25zb2xlLCBmb3IgaW50ZXJhY3RpdmUgZXhlY3V0aW9uLiANCkxhdGVyLCB3ZSB3aWxsICoqc291cmNlKiogZW50aXJlIFIgRWRpdG9yIGZpbGVzIGNvbnN0cnVjdGVkIHRvIHJ1biANCm5vbi1pbnRlcmFjdGl2ZWx5OyBidXQsIHdlIGZpcnN0IG11c3QgbGVhcm4gKippbnRlcmFjdGl2ZSBzdWJtaXNzaW9uKiogdG8gdGhlIFIgDQpDb25zb2xlLCBvZiBzaW5nbGUgbGluZXMgb2YgY29kZSBhbmQgb2Ygc21hbGwgY29kZSBibG9ja3MsIGRlYnVnZ2luZyBhbmQgc2F2aW5nIA0KYWxvbmcgdGhlIHdheS4gDQo8YnI+DQpUaGlzIFIgRWRpdG9yIGZpbGUgY3JlYXRlZCBiZWxvdywgYmVuZWZpdHMgZnJvbSBvdXIgbWFuZGF0b3J5LCANCjx1PmNvZGluZyBjb252ZW50aW9uczwvdT4gaW4gQmlvIDI0MC4gDQo8YnI+PGJyPg0KPHU+T3VyIGNvZGluZyBjb252ZW50aW9ucyBpbmNsdWRlPC91PjogPGJyPjxicj4NCjEuIHZhbGlkIGFuZCBwcm9wZXIgZmlsZSBuYW1lcyAgDQoyLiBjb21tZW50cyAgICAgICAgICAgICAgICAgICANCjMuIGxpbmUgc3BhY2luZyAgIA0KNC4gbGluZSB3aWR0aDogODUgY2hhcmFjdGVycyBtYXggIA0KNS4gaW5kZW50YXRpb24gIA0KNi4gY29udGVudCBvZiBmaXJzdCBsaW5lIG9mIGZpbGUgIA0KNy4gY29udGVudCBvZiBsYXN0IGxpbmUgb2YgZmlsZSAgDQo4LiB2YWxpZCBuYW1lcyBmb3Igb2JqZWN0cyAgDQo5LiB3aXNlIG5hbWVzIGZvciBvYmplY3RzICAgICAgICANCjwvZGl2Pg0KDQo8YnI+IA0KDQoqIFdlIGJlZ2luIGJ5IHdyaXRpbmcgdGhlICoqZmlyc3QgbGluZSoqIGFuZCB0aGUgKipsYXN0IGxpbmUqKiBvZiB0aGUgUiBFZGl0b3IgZmlsZS4gDQpXZSBzYXZlIGl0IHdpdGggdGhlIHN0dWRlbnQncyBuYW1lIGFzIHBhcnQgb2YgdGhlIGZpbGVuYW1lLCBhcyByZXF1aXJlZCBpbiBCaW8gMjQwIA0KZm9yIGFsbCBSIEVkaXRvciBmaWxlcyBpbmNsdWRpbmcgZm9yIGhvbWV3b3JrIGFuZCBvbiBUZXN0cy4gDQoNCiogTGV0J3MgbmFtZSBpdCwgKipib25lIGRlbnNpdHkgQXJsby5SKiogcmVhbGl6aW5nIHRoYXQgYWxsIHZhbGlkIGFuZCBwcm9wZXIsIFIgDQpFZGl0b3IgZmlsZXMgaGF2ZSAqKi5SKiogYXMgdGhlIGZpbGUgZXh0ZW5zaW9uLiAqKkFhcmR2YXJrLlIqKiB3b3VsZCBiZSBhIHZhbGlkIA0KbmFtZSAod291bGQgbm90ICoqdGhyb3cgYW4gZXJyb3IqKiBpbiBSKSBidXQgd291bGQgYmUgYW4gKip1bndpc2UqKiBmaWxlIG5hbWUuIA0KDQoqIEJlZm9yZSBsYXVuY2hpbmcgaW50byB3cml0aW5nIGxpbmVzIG9mIFIgY29kZSwgaXQncyB3aXNlIHRvIHRha2UgDQp0aGlzIGZpcnN0IHN0ZXAgb2YgY3JlYXRpbmcgdGhlIGZpbGUsIHdpdGggYW4gYXBwcm9wcmlhdGUgbmFtZSBhbmQgbWFkZSB1cCBvZiBvbmx5IA0KMiBsaW5lczogYSBmaXJzdCBsaW5lIG9mIGNvbW1lbnRzIGFuZCBhIGZpbmFsIGxpbmUgb2YgY29tbWVudHMuICANCg0KKiBUaGlzIGlzIHdoYXQgb3VyIFIgRWRpdG9yIGZpbGUgcHJlc2VudHMsIGFzIGZpcnN0IGVzdGFibGlzaGVkIGFuZCBzYXZlZC4gSXQgZG9lcyANCm5vdGhpbmcsIGl0IHJldHVybnMgbm90aGluZy4gDQoNCmBgYA0KIyBib25lIGRlbnNpdHkgQXJsby5SICAgIFNlcHRlbWJlciAyLCAyMDIxICAgIEFybG8gQXR6LCBCUw0KDQoNCiMgZW5kLiAgYm9uZSBkZW5zaXR5IEFybG8uUg0KYGBgDQoNCg0KKiBJbnNwZWN0IHRoZSA8dT4qKmZpcnN0IGxpbmUqKjwvdT4gb2YgdGhlIGFib3ZlIGZpbGUuIEl0J3Mgc29sZWx5LCBhICoqY29tbWVudCoqIA0KYmVjYXVzZSBpdCBiZWdpbnMgd2l0aCB0aGUgaGFzaHRhZyBgI2AgZm9yIHdoaWNoIFIgaW50ZXJwcmV0cyBldmVyeXRoaW5nIHRvIHRoZSByaWdodCANCm9mIGl0IChvbiB0aGF0IGxpbmUpIGFzIGEgY29tbWVudCBhbmQgaGVuY2UgaWdub3JlZC4gQ29tbWVudHMgYXJlIGVzc2VudGlhbDsgDQpjb21tZW50cyBoZWxwIGh1bWFuczsgUiBpZ25vcmVzIHRoZW0uIE1vcmUgYWJvdXQgKipjb21tZW50cyoqIGxhdGVyLCBhcyB0aGV5IGhhdmUgDQptdWx0aXBsZSB1c2VzLiAgDQoNCiogV2hhdCBpcyB0aGUgKipwdXJwb3NlKiogb2YgdGhlIDx1PioqZmlyc3QgbGluZSoqPC91PiBvZiBvdXIgUiBFZGl0b3IgZmlsZSBhYm92ZT8gDQogICsgaXQgc3RhdGVzIHRoZSAqKmV4YWN0IGZpbGVuYW1lKiogc28geW91IGtub3cgd2hhdCB5b3UgYXJlIGxvb2tpbmcgYXQgYW5kIGhvdyANCiAgICB0byBmaW5kIGl0DQogICsgdGhlICoqZGF0ZSoqIGluZGljYXRlcyB0aGUgdmVyc2lvbiBvZiB0aGUgcHJvZ3JhbSBhbmQgcGVyaGFwcyB3aGVuIGxhc3QgZWRpdGVkDQogICsgKiphdXRob3IqKiBuYW1lIDxicj4NCjxicj4gDQoNCiogSW5zcGVjdCB0aGUgPHU+KipsYXN0IGxpbmUqKjwvdT4gb2YgdGhlIGFib3ZlIGZpbGUuIEl0J3MgYWxzbyBzb2xlbHksIGEgDQoqKmNvbW1lbnQqKi4NCiogV2hhdCBpcyB0aGUgKipwdXJwb3NlKiogb2YgdGhlIDx1PioqbGFzdCBsaW5lKio8L3U+IG9mIHRoZSBmaWxlPw0KICArIGl0IHN0YXRlcyB0aGF0IHRoaXMgbGluZSBpcyBpbmRlZWQsIHRoZSAqKmVuZCoqIG9mIHRoZSBmaWxlICh0aGUgcHJvZ3JhbSkNCiAgKyBpdCBzdGF0ZXMgdGhlICoqZXhhY3QgZmlsZW5hbWUqKiBvZiB0aGUgcHJvZ3JhbSBzbyB5b3Uga25vdyB3aGF0IHlvdSBhcmUgDQogICAgcmVhZGluZyBhbmQgaG93IHRvIGZpbmQgaXQgIA0KICArIFdoZXRoZXIgeW91ciBwcm9ncmFtIGlzIDEvMiBwYWdlIG9yIDEwIHBhZ2VzIGxvbmcsIHlvdSBrbm93IGFsbCBvZiBpdCBwcmludGVkIA0KICAgIG91dCBvciBpZiB2aWV3aW5nIG9uIHRoZSBzY3JlZW4sIHlvdSBrbm93IHlvdSdyZSBhdCB0aGUgZW5kIG9mIHRoZSBmaWxlLCBpZiANCiAgICBgIyBlbmQuIGZvbyBBcmxvLlJgIGlzIGF0IHRoZSBib3R0b20gIA0KPGJyPg0KKiBXZSBhcmUgbm93IHJlYWR5IHRvIGFkZCBSIGNvZGUgYmV0d2VlbiB0aGVzZSAyIGxpbmVzLCB0eXBpbmcgaXQgaW4gdG9wLWRvd24gDQpmYXNoaW9uLCBkZWJ1Z2dpbmcgdG9wLWRvd24sIGFuZCBzYXZpbmcgYWxvbmcgdGhlIHdheS4gDQoNCg0KPGJyPiANCg0KIyMgJm5ic3A7IFIgRWRpdG9yIGZpbGUgLS0gPGk+c2F2ZSB0aGUgZGF0YTwvaT4NCjxicj4NCg0KKiBCZWZvcmUgc3RvcmluZyB0aGUgZGF0YSBhcyAqKm51bWVyaWMgdmVjdG9ycyoqIGl0J3Mgd2lzZSB0byBlbnRlciBhIGZldyBsaW5lcyBvZiANCioqY29tbWVudHMqKiBleHBsYWluaW5nIHdoYXQgaXMgZ29pbmcgb24uIEl0IG1pZ2h0IHNlZW0gb2J2aW91cyAid2hhdCdzIGdvaW5nIG9uIiANCmJ1dCBtb250aHMgbGF0ZXIsIHRoZSBsYXlvdXQgb2YgdGhlIGRhdGEgYW5kIGl0cyBzb3VyY2UsIG1heSBub3QgYmUgb2J2aW91cy4gDQoNCiogVXNlIHRoZSBgYygpYCBmdW5jdGlvbiB0byBzdG9yZSB0aGUgdGltZSB2YXJpYWJsZSBhcyAqKm51bWVyaWMgdmVjdG9yKiogYHRpbWVgLiAgDQpTdG9yZSBsdW1iYXIgc3BpbmUgYm9uZSBkZW5zaXR5IGFzIGBzcGluZWAgYW5kIHRlbXBvcmFsIG5lY2sgKGhpcCkgYm9uZSBkZW5zaXR5IGFzIA0KYGhpcGAuICZuYnNwOyBJIGNvdWxkIGhhdmUgbmFtZWQgdGhlc2UgMyBudW1lcmljIHZlY3RvcnMgWW9ua2VycywgQnJvbnggYW5kIA0KQXVzdHJhbGlhIHdoaWNoIHdvdWxkIG5vdCAqKnRocm93IGFuIGVycm9yKiogaW4gUiwgYnV0IGl0IHdvdWxkIGJlIA0KKip1bndpc2UgbmFtaW5nKiouIA0KDQoqIFdlIHNlZWsgc2hvcnQsIGluZm9ybWF0aXZlIG5hbWVzIGZvciB2YXJpYWJsZXMgYW5kIG9iamVjdHMuIEkgcHJlZmVyIHNpbXBsZSANCm5hbWVzIG9mIGxvd2VyY2FzZS4gDQoNCiogVGhlIG51bWVyaWMgdmVjdG9yIGlzIHRoZSBmdW5kYW1lbnRhbCAqKmRhdGEgc3RydWN0dXJlKiogaW4gUi4NCg0KKiBUaGUgYGMoKWAgZnVuY3Rpb24gaXMgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBmdW5jdGlvbiBpbiBSLiANCg0KKiBUaGUgYGMoKWAgZnVuY3Rpb24gKipjb21iaW5lcyoqIGl0cyBhcmd1bWVudHMgaW50byBhIHZlY3Rvci4gSGVyZSwgdGhlIGFyZ3MgYXJlIA0KZGF0YSB3aXRoIGVhY2ggZGF0dW0gc2VwYXJhdGVkIGJ5IGEgY29tbWEuIFZlY3RvcnMgbWF5IGJlIG51bWVyaWMgb3IgY2hhcmFjdGVyLiANClZlY3RvcnMgbWF5IGJlIGNvbWJpbmVkIHRvIG1ha2UgbW9yZSBjb21wbGljYXRlZCBkYXRhIHN0cnVjdHVyZXM6ICZuYnNwOyBmYWN0b3IsIA0KbWF0cml4LCBkYXRhIGZyYW1lLCBsaXN0LCBhcnJheS4gDQoNCiogV2UgY2FsbCB0aGUgYGNiaW5kKClgIGZ1bmN0aW9uIGp1c3QgdG8gcHJpbnQgYSAzIGNvbHVtbiBkYXRhIG1hdHJpeCBhdCBSIENvbnNvbGUgDQp0byBhbGxvdyBhIGNoZWNrIGZvciBhY2N1cmFjeSBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBkYXRhLiBXcm9uZyBkYXRhIGVudHJ5IGdlbmVyYXRlcyANCndyb25nIGFuc3dlcnMuIA0KDQoqIFRoZSBkYXRhIGFyZSBub3cgc3RvcmVkIGluIG9iamVjdHMgdGhhdCBhbGxvdyBncmFwaGluZyBhbmQgc3RhdGlzdGljYWwgDQphbmFseXNpcyB0byBwcm9jZWVkLiBFdmVyeXRoaW5nIGluIFIgaXMgYW4gKipvYmplY3QqKiB3aGV0aGVyIGRhdGEsIGZ1bmN0aW9ucywgDQpvdXRwdXQsIGdyYXBocyBvciB3aGF0ZXZlci4gVGhpbmsgb2YgUiBvYmplY3RzIGFzIGNvbnRhaW5lcnMuICANCg0KKiBUbyB1c2UgUiBpcyB0byBjYWxsIGZ1bmN0aW9ucyAoSm9obiBDaGFtYmVycykuIA0KDQo8YnI+IA0KDQpgYGANCiMgYm9uZSBkZW5zaXR5IEFybG8uUiAgICBBdWd1c3QgMjYsIDIwMjEgICAgQXJsbyBBdHosIEJTDQoNCiMgQm9uZSBkZW5zaXR5IHdhcyBtZWFzdXJlZCBvdmVyIDkyIG1vbnRocyBpbiBhIDY1IHllYXIgb2xkIHdvbWFuIHdpdGggbG93IGJvbmUNCiMgZGVuc2l0eSwgdHJlYXRlZCB3aXRoIEFsZW5kcm9uYXRlLCAyMDAyIHRocm91Z2ggMjAwOS4gQm9uZSBtaW5lcmFsIGRlbnNpdHkgDQojIChnL2NtXjIpIHdhcyBtZWFzdXJlZCBmb3IgbHVtYmFyIHNwaW5lIGFuZCBmZW1vcmFsIG5lY2sgKGhpcCkgKFJvc25lciwgQi4gMjAxNikuDQoNCnRpbWUgIDwtIGMoMCwgOCwgMTgsIDQ4LCA2NCwgNjYsIDc5LCA5MikgICAgICMgbW9udGhzIGZyb20gYmFzZWxpbmUNCg0Kc3BpbmUgPC0gYyguNzk3LCAuODA2LCAuODE3LCAuODI1LCAuODM3LCAuODQxLCAuODg2LCAuODgxKSAjIHNwaW5lIGJvbmUgZGVuc2l0eQ0KaGlwICAgPC0gYyguNjQzLCAuNjM4LCAuNjQ4LCAuNjc0LCAuNjQsICAuNjc2LCAuNjUxLCAuNjgpICAjIGhpcCAgICAiICAgICAiDQoNCiMgdmlldyBkYXRhIGF0IFIgQ29uc29sZSB0byBjaGVjayBjYXJlZnVsbHksIHZlcnN1cyBvcmlnaW5hbA0KY2JpbmQodGltZSwgc3BpbmUsIGhpcCkgDQoNCg0KIyBlbmQuICBib25lIGRlbnNpdHkgQXJsby5SDQpgYGANCg0KKiBUaGUgPGI+Y29kZSBjaHVuayBhYm92ZTwvYj4sIHJldHVybnMgdG8gdGhlIFIgQ29uc29sZSwgdGV4dCBvdXRwdXQgZnJvbSB0aGUgY2FsbCANCnRvIGBjYmluZCgpYCB3aGljaCBiaW5kcyBvdXIgMyBudW1lcmljIHZlY3RvcnMgYnkgY29sdW1ucywgaW50byBhICoqbWF0cml4Kiogb2JqZWN0IA0KYW5kIHByaW50cyBpdCBhdCBSIENvbnNvbGUsIGFzIGdpdmVuIGJlbG93LiANCg0KKiAqV2UgbXVzdCBhbHdheXMgY2hlY2sgdGhhdCB0aGUgZGF0YSBhcyBzYXZlZCBpbiBhbnkgY29tcHV0ZXIgcHJvZ3JhbSwgDQo8dT5leGFjdGx5PC91PiByZWZsZWN0cyBvdXIgb3JpZ2luYWwgZGF0YSouIFByb29mcmVhZCBpdCBhZ2FpbnN0IHRoZSBvcmlnaW5hbC4gDQpJbiBCaW8gMjQwIGFuZCBpbiBhbnkgZW52aXJvbm1lbnQgLS0gKiplcnJvcnMqKiBpbiBkYXRhIGVudHJ5IHByb2R1Y2UgDQoqKndyb25nIHJlc3VsdHMqKi4gT2J2aW91c2x5LCB0aGlzIGFsc28gaG9sZHMgdHJ1ZSBmb3IgVGVzdHMgaW4gQmlvIDI0MCB3aGVyZSB6ZXJvIA0KY3JlZGl0IGlzIGdpdmVuIGZvciB3cm9uZyBhbnN3ZXJzIGNhdXNlZCBieSBzdHVkZW50IGVycm9ycyBpbiBkYXRhIGVudHJ5LiAgDQoNCiogSWYgZGVzaXJlZCwgYD4gdGltZWAgd291bGQgcHJpbnQgY29udGVudCBvZiB0aGUgdGltZSB2ZWN0b3IsIGA+IHNwaW5lYCB0aGUgDQpzcGluZSB2ZWN0b3IgYW5kIGA+IGhpcGAgdGhlIGhpcCB2ZWN0b3IuDQoNCiogVGhlIDIgZGltZW5zaW9uYWwgaW5kZXggdGhhdCdzIHByaW50ZWQgYXQgUiBDb25zb2xlLCBbcm93LCBjb2x1bW5dIGlzIG5vdCBwYXJ0IA0Kb2YgdGhlIGRhdGEgbWF0cml4OyBpdCdzIHB1dCB0aGVyZSB0byBpbmZvcm0gdGhlIHZpZXdlci4gIA0KDQoqIGBbMSwgXWAgaW5kaWNhdGVzICpyb3cgMSwgYWxsIGNvbHVtbnMqLiBBIG1pc3NpbmcgaW50ZWdlciBpbiB0aGUgcm93IHNsb3QgbWVhbnMgDQoqYWxsIHJvd3MqIHdoaWxlIGEgbWlzc2luZyBpbnRlZ2VyIGluIHRoZSBjb2x1bW4gc2xvdCBtZWFucyAqYWxsIGNvbHVtbnMqLiANCg0KKiBDb25zaWRlcjogYFs0LDJdYCAsIGl0IHJldHVybnMgMC44MjUsIHRoZSA0dGggcm93LCAybmQgY29sdW1uLiBWZWN0b3JzIGFyZSANCnNpbmdsZSAgaW5kZXhlZCwgYFsgXWAgd2hpbGUgbWF0cmljZXMgYW5kIGRhdGEgZnJhbWVzIGFyZSBkb3VibGUgaW5kZXhlZCwgcm93IGJ5IA0KY29sdW1uLCBgWyAsIF1gLiANCg0KKiBJbiBCaW8gMjQwIHdlIHVzZSBpbmRleGluZyBmb3IgZGVhbGluZyB3aXRoIHZlY3RvcnMsIG1hdHJpY2VzIGFuZCBkYXRhIGZyYW1lcy4gDQpXZSBhbHNvIHVzZSBpbmRleGluZyB0byBleHRyYWN0IGluZm9ybWF0aW9uIGZyb20gb2JqZWN0cyByZXR1cm5lZCBmcm9tIGZ1bmN0aW9uIA0KY2FsbHMuIEluZGV4aW5nIGluIFIgaXMganVzdCBIaWdoIFNjaG9vbCwgYWxnZWJyYWljIHRoaW5raW5nLiANCg0KT3V0cHV0IGZyb20gYGNiaW5kKHRpbWUsIHNwaW5lLCBoaXApYCA6IA0KDQpgYGB7ciBlY2hvPUZ9DQoNCnRpbWUgPC0gYygwLCA4LCAxOCwgNDgsIDY0LCA2NiwgNzksIDkyKSAgIyBtb250aHMgZnJvbSBiYXNlbGluZQ0KDQpzcGluZSA8LSBjKC43OTcsIC44MDYsIC44MTcsIC44MjUsIC44MzcsIC44NDEsIC44ODYsIC44ODEpICMgYm9uZSBkZW5zaXR5DQpoaXAgICA8LSBjKC42NDMsIC42MzgsIC42NDgsIC42NzQsIC42NCwgIC42NzYsIC42NTEsIC42OCkNCg0KY2JpbmQodGltZSwgc3BpbmUsIGhpcCkNCmBgYA0KDQo8YnI+IA0KDQojIyAmbmJzcDsgUiBFZGl0b3IgZmlsZSAtLSA8aT5ncmFwaCB0aGUgZGF0YTwvaT4NCjxicj4NCg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMjIiPg0KPHAgc3R5bGU9ImZvbnQtZmFtaWx5OmdhcmFtb25kOyBmb250LXNpemU6MjNweDsgZm9udC1zdHlsZTppdGFsaWM7IGNvbG9yOmRhcmtyZWQ7DQpsaW5lLWhlaWdodDoxLjE7IGxldHRlci1zcGFjaW5nOjFweDsgdGV4dC1hbGlnbjpsZWZ0OyB3b3JkLXNwYWNpbmc6NXB4OyANCnRleHQtaW5kZW50OjBweDsgIj4NCk15IHByYWN0aWNlIGlzIHRvIHRlYWNoIHlvdSBSIGNvZGluZyBieSBkZW1vbnN0cmF0aW5nIHRoZSBuYXR1cmFsIHdvcmtmbG93IGFuZCANCmV2b2x1dGlvbiBvZiBzaG9ydCBwcm9ncmFtcy4gKFRoaXMgaXMgbXVjaCBiZXR0ZXIgdGhhbiBvbmx5IHNob3dpbmcgeW91IGZpbmlzaGVkLCANCnBvbGlzaGVkIFIgcHJvZ3JhbXMuKSANCjxicj48YnI+DQpJZGVhbGx5LCB3ZSBkbyB0aGlzIGF0IHRoZSBzYW1lIHRpbWUsIGFzIHRoZSBQcm9mZXNzb3IgDQphbmQgdGhlIHN0dWRlbnRzIHR5cGUgdGhlIHNhbWUgY29kZSwgaW4gd2hhdCBJIGNhbGwgPGI+Y29sbGFib3JhdGl2ZSBjb2Rpbmc8L2I+LiANCjxicj48YnI+DQpDb2xsYWJvcmF0aXZlIGNvZGluZyBpcyBlYXN5IGluIHRoZSBwaHlzaWNhbCBjbGFzc3Jvb20geWV0IG1vcmUgZGlmZmljdWx0IGluIHRoZSANCm9ubGluZSBjbGFzc3Jvb20sIGJ1dCBzdGlsbCBwb3NzaWJsZS4gDQo8YnI+PGJyPg0KQ29tcHV0ZXIgcHJvZ3JhbXMgZGV2ZWxvcCBieSBzdGFnZXMsIGJ5IHRyaWFsLWFuZC1lcnJvciwgYnkgYXR0ZW50aW9uIHRvIGRldGFpbCwgDQpieSBjb2RpbmcgZXhwZXJpbWVudHMgYW5kIGJ5IHRvcC1kb3duIGRlYnVnZ2luZyBhbG9uZyB0aGUgd2F5LiANCjxicj48YnI+DQpUaGlzIHByb2Nlc3MgcmVzdWx0cyBpbiBjbGVhbiwgcmVhZGFibGUgUiBjb2RlIHRoYXQgZXhlY3V0ZXMgd2l0aG91dCBlcnJvciBhbmQgDQpkZWxpdmVycyA8Yj5tYXR1cmUgZ3JhcGhzPC9iPiBhbmQgPGI+dHJ1c3R3b3J0aHkgc3RhdGlzdGljYWwgcmVzdWx0czwvYj4uIA0KPGJyPjxicj4NCkl0J3MgdXR0ZXJseSBmb29saXNoIHRvIHRyeSB0byBjdXQgdG8gdGhlIGRlc2lyZWQgZ3JhcGhpY2FsIGFuZCBzdGF0aXN0aWNhbCBlbmQgDQpwcm9kdWN0LCByaWdodCBmcm9tIHRoZSBwcm9ncmFtbWluZyBnZXQtZ28uIExldCB0aGlzIHNlbnRlbmNlIGJ1cm4taW4uICANCjxicj48YnI+DQpXcml0aW5nIHByb2dyYW1zIGluIFIgaXMgc2ltaWxhciB0byB3cml0aW5nIGVzc2F5cyBpbiBFbmdsaXNoLiBCb3RoIGludm9sdmUgDQpzeW1ib2xpYyB0aGlua2luZywgb3V0bGluZXMsIHJvdWdoIGRyYWZ0cywgbXVsdGlwbGUgcmV2aXNpb25zLCBkb2N1bWVudGF0aW9uIA0KYW5kIGF0dGVudGlvbiB0byBkZXRhaWwuDQo8L2Rpdj4NCg0KPGJyPg0KDQojIyMgJm5ic3A7IFByZWxpbWluYXJ5IGdyYXBocyANCg0KKiBUaGUgYHBsb3QoKWAgZnVuY3Rpb24gaXMgdGhlIHdvcmtob3JzZSBncmFwaGluZyBmdW5jdGlvbiBpbiBiYXNlIFIuIEl0IG1ha2VzIA0KYSB2YXJpZXR5IG9mIGRpZmZlcmVudCBncmFwaHMsIGl0IHRha2VzIG1hbnkgYXJndW1lbnRzLiBIZXJlLCB3ZSBwbG90IHRoZSANCip4LHkqIGRhdGEgaW4gYSBtaW5pbWFsIGNhbGw6IGBwbG90KHgsIHkpYCB3aGVyZSB0aGUgYHhgIGFyZyBpcyB0aGUgbmFtZSBvZiBvdXIgDQp4IG51bWVyaWMgdmVjdG9yIGFuZCBgeWAgdGhlIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcsIHkgbnVtZXJpYyB2ZWN0b3IuIA0KQXQgdGhlIFIgQ29uc29sZSwgYD4/cGxvdGAgYnJpbmdzIHVwIGV4dGVuc2l2ZSwgSFRNTCBkb2N1bWVudGF0aW9uIGZvciB0aGlzIA0KZXh0cmVtZWx5IGltcG9ydGFudCBncmFwaGluZyBmdW5jdGlvbi4gDQoNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgcHJlbGltaW5hcnkgc2NhdHRlcnBsb3RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnBsb3QodGltZSwgc3BpbmUpICMgJ3NwaW5lJyBzY2F0dGVycGxvdDogYm9uZSBkZW5zaXR5IGJ5IHRpbWUNCnBsb3QodGltZSwgaGlwKSAgICMgJ2hpcCcgICBzY2F0dGVycGxvdDogICAiICAgICAiICAgICIgICAiDQpgYGANCg0KKiBUaGUgPHU+KipmaXJzdCBsaW5lKio8L3U+IG9mIGNvZGUgYWJvdmUsIGRlbGl2ZXJzIGEgc2NhdHRlcnBsb3QgZm9yIHNwaW5lIA0KYm9uZSBkZW5zaXR5ICh5KSBieSB0aW1lICh4KSAtLSA8Yj5sZWZ0IGdyYXBoPC9iPiBiZWxvdy4gDQoNCiogVGhlIDx1Pioqc2Vjb25kIGxpbmUqKjwvdT4gb2YgY29kZSwgZG9lcyB0aGUgc2FtZSBmb3IgaGlwIGJvbmUgZGVuc2l0eSBieSANCnRpbWUgLS0gPGI+cmlnaHQgZ3JhcGg8L2I+LiBFeGFtaW5lIHRoZXNlIHR3byBncmFwaHMuIA0KDQoqIEJ1dCwgd2Ugd2FudCBib3RoIHNldHMgb2YgeCx5IHBvaW50cyBvbiB0aGUgc2FtZSBncmFwaCBhbmQgd2Ugd2FudCANCioqcG9pbnQtYW5kLWxpbmUqKiBncmFwaHMgbm90ICoqc2NhdHRlcnBsb3RzKiouIFlldCwgd2UgYXJlIGVuY291cmFnZWQgYW5kIA0KaW5mb3JtZWQgYnkgdGhlc2Ugcm91Z2ggZ3JhcGhzLiBXZSdyZSBtYWtpbmcgcHJvZ3Jlc3MgaW4gdmlzdWFsaXppbmcgdGhlIGRhdGEuDQoNCmBgYHtyIGVjaG89RiwgZmlnLndpZHRoPTQuNjUsIGZpZy5hbGlnbj0iZGVmYXVsdCJ9DQpwbG90KHRpbWUsIHNwaW5lKSAjICdzcGluZScgc2NhdHRlcnBsb3Q6IGJvbmUgZGVuc2l0eSBieSB0aW1lDQpwbG90KHRpbWUsIGhpcCkgICAjICdoaXAnICAgc2NhdHRlcnBsb3Q6ICAiICAgICAiICAgICAiICAgICINCg0KYGBgDQoNCiogTm90aWNlIHRoZSBzY2FsZSBvZiB0aGUgKnktYXhpcyogb24gYm90aCBzY2F0dGVycGxvdHMgYWJvdmUuIENsZWFybHksIHNwaW5lIGJvbmUgDQpkZW5zaXR5IGlzIG11Y2ggZ3JlYXRlciB0aGFuIGhpcCBib25lIGRlbnNpdHkgaW4gdGhpcyBwYXRpZW50IHdpdGggT3N0ZW9wb3Jvc2lzLiANCg0KKiBGb3IgYm90aCBzZXRzIG9mIHBvaW50cyB0byBmaXQgaW4gdGhlIHNhbWUgZ3JhcGggd2UgbmVlZCBnbG9iYWwgbWluLCBtYXggZm9yIA0KYm9uZSBkZW5zaXR5LiBBIGNhbGwgdG8gdGhlIGByYW5nZSgpYCBmdW5jdGlvbiBkZWxpdmVycy4gVGhpcyBmdW5jdGlvbiB0YWtlcyBhIA0KbnVtZXJpYyB2ZWN0b3IgYXMgaXRzIGFyZyBhbmQgcmV0dXJucyB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBvZiB0aGF0IHZlY3Rvci4gV2UgDQp1c2UgYGMoc3BpbmUsIGhpcClgIHRvIGNyZWF0ZSBhIG51bWVyaWMgdmVjdG9yIGZvciB0aGUgY29tYmluZWQsIHNwaW5lIGFuZCBoaXAgDQpkZW5zaXR5IGRhdGEuIEluIFIsIHdlIG1heSBjYWxsIGZ1bmN0aW9ucyB3aXRoaW4gZnVuY3Rpb25zLiANCg0KKiBUaGUgbmV3IGxpbmUgb2YgY29kZSBiZWxvdywgZGVsaXZlcnMgbWluLCBtYXggKDAuNjM4IHRvIDAuODg2IGcvY21eMl4pIGZvciANCnRoZSBkYXRhIHNldC4NCg0KYGBge3J9DQojIGJvdGggbGluZXMgbXVzdCBmaXQgaW4gdGhlIHNhbWUgZ3JhcGgsIHNvIGdldCBnbG9iYWwgbWluLG1heCBmb3IgeQ0KcmFuZ2UoYyhzcGluZSwgaGlwKSkgICMgbWluLCBtYXg6IC42MzggdG8gLjg4Ng0KYGBgDQoNCjxicj4gDQoNCiogTm93IG91ciB0YXNrIGlzIHRvIG1ha2UgYSByb3VnaCwgbWluaW1hbCwgKipkcmFmdCBxdWFsaXR5KiosIHBvaW50LWFuZC1saW5lIGdyYXBoIA0KZm9yIHNwaW5lIGFuZCBmb3IgaGlwIGJvbmUgZGVuc2l0eS4gVGhlcmUgYXJlIGFsd2F5cyBkaWZmZXJlbnQgd2F5cyB0byBhY2NvbXBsaXNoIA0KdGhlIHNhbWUgdGhpbmcgaW4gYW55IHByb2dyYW1taW5nIGxhbmd1YWdlIGp1c3QgYXMgdGhlcmUgYXJlICBkaWZmZXJlbnQgd2F5cyB0byBzYXkgDQoiSSBsb3ZlIHlvdSIgaW4gYW55IHNwb2tlbiBsYW5ndWFnZSBhbmQgZXhwZXJ0cyBkaXNhZ3JlZSBvbiB0aGUgYmVzdCB3YXkgdG8gZG8gaXQuICANCg0KKiBJbiB0aGUgPHU+KipmaXJzdCBsaW5lKio8L3U+IG9mIGNvZGUgYmVsb3csIHdlIGNhbGwgYHBsb3QoKWAgZm9yIHRoZSBzcGluZSB4LHkgDQpkYXRhIGFuZCB0aGVuIHVzZSB0aGUgYHBvaW50cygpYCBmdW5jdGlvbiBpbiB0aGUgPHU+c2Vjb25kIGxpbmU8L3U+IHRvICoqYWRkKiogDQp0aGUgcG9pbnRzIGZvciB0aGUgaGlwLiBUaGlzIGdpdmVzIHVzIGZ1bGwgY29udHJvbCBvdmVyIHRoZSBncmFwaC4gDQoNCiogVGhlIGFyZyBgdHlwZT0iYiJgIHNwZWNpZmllcyB0aGF0ICoqYm90aCoqIHBvaW50cyBhbmQgbGluZXMgYXJlIGNhbGxlZCBmb3IuIA0KKFRoZSBkZWZhdWx0IGZvciB0aGUgYHR5cGVgIGFyZyBpcyBgdHlwZT0icCJgIGZvciBwb2ludHMgb25seTsgYHR5cGU9ImwiYCANCmRlbGl2ZXJzIG9ubHkgdGhlIGxpbmUsIGAiYyJgIGlzIGVtcHR5IHBvaW50cyBqb2luZWQgYnkgbGluZXMsIGAicyJgIG1ha2VzIA0Kc3RhaXJzdGVwcywgYCJoImAgZm9yIHZlcnRpY2FsIGxpbmVzLCBgIm4iYCBtYWtlcyBubyBwb2ludHMgb3IgbGluZXMpLg0KDQoqIEluIHRoZSBjYWxsIHRvIGBwbG90KClgIHdlIGNoYW5nZSB0aGUgZGVmYXVsdCBzY2FsZSBmb3IgdGhlIHktYXhpcyANCmJ5IHVzaW5nIHRoZSBhcmd1bWVudCBgeWxpbT1jKC42LCAuOSlgIG9yIGJ5IHRoZSBhcmd1bWVudCANCmB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpYDsgdGhlIGxhdHRlciBpcyBwcmVmZXJhYmxlLCBpbiBjYXNlIHRoZSBkYXRhIHZlY3RvcnMgDQphcmUgY2hhbmdlZCB1cHN0cmVhbSBpbiB0aGUgcHJvZ3JhbS4gVGhlIGRlZmF1bHQgZm9yIHRoZSB4LWF4aXMgc2NhbGUgbG9va3MgZmluZSANCmJ1dCB3ZSBjb3VsZCBjaGFuZ2UgaXQgd2l0aCB0aGUgYHhsaW09KClgIGFyZywgaWYgZGVzaXJlZC4gDQoNCiogSW4gdGhlIDx1Pioqc2Vjb25kIGxpbmUqKjwvdT4gb2YgY29kZSB0aGUgY2FsbCB0byBgcG9pbnRzKClgIGFkZHMgdGhlIHgseSBwb2ludHMgDQpmb3IgaGlwIGRlbnNpdHkgYnkgdGltZS4gVGhlIGBwY2g9MTZgIGFyZyBzcGVjaWZpZXMgYmxhY2ssIHNvbGlkIGNpcmNsZXMsIElmIHRoaXMgDQphcmcgaXMgb21pdHRlZCBhcyB3ZSBkaWQgaW4gdGhlIGNhbGwgdG8gYHBsb3QoKWAgdGhlbiB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBgcGNoPTFgIA0KaXMgdXNlZCB3aGljaCByZXR1cm5zIGFuIG9wZW4gY2lyY2xlIGZvciB0aGUgcG9pbnRzLiAoYHBjaGAgY2FuIHRha2UgaW50ZWdlcnMgZnJvbSANCjAgdG8gMjUsIGFuZCBiZXlvbmQ7IHNlZWA+P3BvaW50c2AgZm9yIGRvY3VtZW50YXRpb24pDQoNCmBgYHtyIGVjaG89VCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NywgZmlnLmFsaWduPSJjZW50ZXIifQ0KIyBtaW5pbWFsIGdyYXBoIGFzIHByb29mIG9mIGNvbmNlcHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCnBsb3QodGltZSwgc3BpbmUsIHR5cGU9ImIiLCB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpKSAgIyBzcGluZSBkYXRhDQpwb2ludHModGltZSwgaGlwLCB0eXBlPSJiIiwgcGNoPTE2KSAgICAgICAgICAgICAgICAgICAgICMgYWRkIGhpcCBkYXRhDQoNCmBgYA0KDQoqICoqRHJhZnQgcXVhbGl0eSoqIGlzIHdoYXQgd2UgaGF2ZSBpbiB0aGUgZ3JhcGgganVzdCBhYm92ZS4gSXQgbmVlZHMgDQoqKmVuaGFuY2VtZW50KiogdG8gbWFrZSBpdCAqKnB1YmxpY2F0aW9uIHF1YWxpdHkqKiBvciAqKnByZXNlbnRhdGlvbiBxdWFsaXR5KiouIA0KQnV0LCB0aGUgaGFyZCB3b3JrIGlzIG92ZXIuIFRoZSBlbmhhbmNlbWVudHMgYXJlIHJlbGF0aXZlbHkgZWFzeSwgZ2l2ZW4gcGF0aWVuY2UgDQphbmQgc29tZSB0cmlhbC1hbmQtZXJyb3IuIA0KDQoqICoqQXhpcyBsYWJlbHMqKiBuZWVkIHRvIGJlIG1hZGUgcHJvcGVyLCBpbmNsdWRpbmcgd2l0aCB1bml0cyBvZiBtZWFzdXJlbWVudCBhbmQgDQp3aXRoIGxhcmdlciBmb250IHNpemUuIFdlIG1pZ2h0IHdpc2ggdG8gcm90YXRlIHRoZSB5LWF4aXMgdGljayBsYWJlbHMuIFdlIG9mdGVuIA0KaW5jcmVhc2UgdGhlIGZvbnQgc2l6ZSBvZiB0aWNrIGxhYmVscy4gKipMYXJnZXIgZm9udCBzaXplKiogaGVscHMgd2hlbiBncmFwaHMgDQphcmUgcmVkdWNlZCBpbiBwcmludCBhbmQgaGVscHMgd2hlbiB2aWV3ZWQgb24gYSBwb3N0ZXIgb3IgcHJvamVjdGVkIG9uIGEgc2NyZWVuLiANCg0KKiAqKlB1YmxpY2F0aW9uIHF1YWxpdHkqKiByZWZlcnMgdG8gYSBncmFwaCBpbnRlbmRlZCBmb3IgcHVibGljYXRpb24gaW4gYSANCnBlZXItcmV2aWV3ZWQgc2NpZW50aWZpYyBqb3VybmFsLiAqKlByZXNlbnRhdGlvbiBxdWFsaXR5KiogcmVmZXJzIHRvIGEgZ3JhcGggDQppbnRlbmRlZCBmb3IgYSBwcm9mZXNzaW9uYWwsIHBvc3RlciBwcmVzZW50YXRpb24gb3IgbGl2ZSBzZW1pbmFyLiANCg0KKiBQdWJsaWNhdGlvbiBxdWFsaXR5IGdyYXBocyBoYXZlIG5vIHRpdGxlIGFuZCBubyBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcCBvbiB0aGUgDQpncmFwaC4gUHJlc2VudGF0aW9uIHF1YWxpdHkgZ3JhcGhzIG1heSBlbmpveSBpbmZvcm1hdGl2ZSB0aXRsZXMgYW5kIHBlcnNvbmFsaXplZCANCnRpbWUgc3RhbXBzIHRvIGFzc2lnbiBjcmVkaXQvYmxhbWUgZm9yIHRoZSBncmFwaCBhbmQgZGF0YSBpbiBxdWVzdGlvbi4gDQoNCiogV2UgKipjb21tZW50LWluKiogb3IgKipjb21tZW50LW91dCoqIGFyZ3MgYW5kIGxpbmVzIG9mIGNvZGUgdG8gc3dpdGNoIGVhc2lseSANCmJldHdlZW4gcHVibGljYXRpb24gYW5kIHByZXNlbnRhdGlvbiBxdWFsaXR5IGdyYXBocy4gTW9yZSBvbiB0aGF0IGxhdGVyLiBJbiBzaG9ydCwgDQptYXN0ZXJpbmcgKipjb21tZW50LWluKiogYW5kICoqY29tbWVudC1vdXQqKiBpcyBlc3NlbnRpYWwgaW4gY29kaW5nIGFjcm9zcyANCmFsbCBwcm9ncmFtbWluZyBsYW5ndWFnZXMuDQoNCiogKipEcmFmdCBxdWFsaXR5KiogaXMgc2VsZi1leHBsYW5hdG9yeS4gSXQncyB3aGVyZSB3ZSBiZWdpbiB3aXRoIGEgZ3JhcGguIA0KRHJhZnQgcXVhbGl0eSBpcyBlYXN5LCBoYXBwZW5zIHF1aWNrbHkgYW5kIGlzIG9mdGVuIHN1ZmZpY2llbnQgZm9yIHRoZSBiZW5jaCBhbmQgDQpmb3Igdmlld2luZyBhbW9uZyB5b3VyIHJlc2VhcmNoIGNvbGxhYm9yYXRvcnMuIDxicj48YnI+DQoNCiMjIyAmbmJzcDsgRW5oYW5jZWQgZ3JhcGhzIHdpdGggbGFiZWxzIA0KDQo8YnI+DQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIzIj4gDQoNCkhhdmluZyBlc3RhYmxpc2hlZCBhYm92ZSwgYnkgbWluaW1hbCBjYWxscyB0byBib3RoIGBwbG90KClgIGFuZCB0byBgcG9pbnRzKClgIA0KdGhhdCBhIHByZXR0eSBkZWNlbnQgZ3JhcGggaXMgbWFkZSwgd2Ugbm93IGV4cGFuZCB0aGVzZSB0d28gY2FsbHMgYnkgdXNpbmcgbW9yZSANCmFyZ3VtZW50cy4NCg0KVGhlIGFyZ3MgaW4gdGhlIGNvZGUgY2h1bmsgYmVsb3csIGFyZSBwYXJ0bHkgZXhwbGFpbmVkIGJ5IGNvbW1lbnRzIGluIHRoZSBjb2RlIA0KaXRzZWxmLiBUaGlzIGlzIHdpc2UgcHJvZ3JhbW1pbmcgYXMgaXQgc2F2ZXMgb25lIHRoZSB0cm91YmxlIG9mIGA+P3Bsb3RgIHRvIA0KYWNjZXNzIHRoZSBsb25nLCBIVE1MIGRvY3VtZW50YXRpb24gZm9yIHRoZSBgcGxvdCgpYCBmdW5jdGlvbi4gDQoNClJlbWVtYmVyOiAmbmJzcDsgYXJndW1lbnRzIGFyZSBzZXBhcmF0ZWQgYnkgY29tbWFzLCBleGNlcHQgZm9yIHRoZSBsYXN0IGFyZyBpbiANCnRoZSBjYWxsLiANCg0KU29tZSBvZiB0aGUgYXJncyBiZWxvdyBhcmUgc2VsZi1leHBsYW5hdG9yeSwgb3RoZXJzIGhhdmUgc3VnZ2VzdGl2ZSBuYW1lcywgDQp3aGlsZSBvdGhlcnMgYXJlIG9ibGlxdWUuIA0KDQpUaGUgYmVzdCB3YXkgdG8gbGVhcm4gdGhlIGFyZ3VtZW50cyBmb3IgYSBmdW5jdGlvbiBpcyB0byB1c2UgdGhlbSwgY2hhbmdlIHRoZW0gDQphbmQgc2VlIHdoYXQgaGFwcGVucyBpbiB0aGUgb3V0cHV0LiANCg0KQSBuaWNlIHRoaW5nIGlzIHRoYXQgbW9zdCBvZiB0aGUgZnVuY3Rpb25zIGluICpiYXNlIFIgZ3JhcGhpY3MqLCBlLmcuLCBgcGxvdGAsIA0KYHBvaW50c2AsIGBsaW5lc2AsIGBhYmxpbmVgLCBgYm94cGxvdGAsIGBzdHJpcGNoYXJ0YCwgYGhpc3RvZ3JhbWAsIGBiYXJwbG90YCwgYHRleHRgLCBgbXRleHRgLCBgc2VnbWVudHNgLCBgYXJyb3dzYCwgYHRpdGxlYCwgYGxlZ2VuZGAsIGBwaWVgLCBgc3ltYm9sc2AsIGBkb3RjaGFydGAsIA0KYGdyaWRgLCBgcG9seWdvbmAsIGBjb3Bsb3RgLCBgc3VuZmxvd2VycGxvdGAgLS0gc2hhcmUgbWFueSBvZiB0aGUgc2FtZSBhcmd1bWVudHMuIA0KPC9kaXY+IA0KPGJyPiANCg0KKiBUaGUgYG1haW5gIGFyZyBpcyBhIHN0cmluZyBmb3IgZ3JhcGggdGl0bGUsIGlmIGRlc2lyZWQ7IGFuZCBpdCBoYXMgdHlwb2dyYXBoaWMgDQphcmdzLCBgY2V4Lm1haW5gLCBgY29sLm1haW5gIGFuZCBgZm9udC5tYWluYCBmb3IgZm9udCBzaXplLCBmb250IGNvbG9yIGFuZCBmb250IA0KdHlwZSAocmVndWxhciwgYm9sZCwgYm9sZCBpdGFsaWMpLCByZXNwZWN0aXZlbHkuIA0KDQoqIFRoZSBgeGxhYmAgYW5kIGB5bGFiYCBhcmdzIGFsbG93IGN1c3RvbSBsYWJlbHMgZm9yIHggYW5kIHkgYXhpcyBhbmQgdGhleSBoYXZlIA0KdHlwb2dyYXBoaWMgYXJncywgYGNleC5sYWJgLCAgYGNleC5heGlzYCwgIGBmb250LmxhYmAsIGFuZCBtb3JlLiANCg0KKiBUaGUgYHR5cGVgIGFyZyBzcGVjaWZpZXMgd2hldGhlciBwb2ludHMgYWxvbmUgYXJlIHBsb3R0ZWQsIGB0eXBlPSJwImAgLCBwb2ludHMgDQpjb25uZWN0ZWQgYnkgbGluZXMgYHR5cGU9ImIiYCwgbGluZXMgY29ubmVjdGluZyBwb2ludHMgYnV0IHBvaW50cyBub3QgcGxvdHRlZCANCmB0eXBlPSJsImAsIGB0eXBlPSJuImAgZG9lcyBub3RoaW5nIGFuZCBgdHlwZT0iaCJgIHBsb3RzIGEgYmFyIGZyb20gdGhlIGJvdHRvbSB1cCANCnRvIHRoZSBwb2ludCdzIHkgY29vcmRpbmF0ZS4NCg0KKiBDaGFuZ2UgdGhlIHZhbHVlcyBmb3IgdGhlIGBjb2xgLCBgY2V4YCBhbmQgYGxhc2AgYXJncyBhbmQgc2VlIHdoYXQgaGFwcGVucy4gDQoNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGVuaGFuY2VkLCBwb2ludCBhbmQgbGluZSBncmFwaDogMiBzZXRzIG9mIHgseSBwb2ludHMgLS0tLS0tLS0tLS0tLS0NCiMgICB3aXRoIGVhY2ggbGluZSBsYWJlbGVkIHdpdGhpbiB0aGUgZ3JhcGggICAgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KcGxvdCh0aW1lLCBzcGluZSwgDQogIGNvbD0iYmxhY2siLCAgIyBjb2xvciBvZiBwb2ludHM7IGRlZmF1bHQsIGNvbD0iYmxhY2siDQogIGNleD0xLCAgICAgICAgIyBzaXplIG9mIHN5bWJvbCBwbG90dGVkOyBkZWZhdWx0LCBjZXg9MQ0KICB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpLCAgIyBhZGp1c3QgeS1heGlzIHJhbmdlDQogIHhsaW09YygtNSwgMTAwKSwgICAgICAgICAgICAjICAgIiAgICB4LWF4aXMgICINCiAgbGFzPTAsICAgICAgICAgIyBmbGlwIHktYXhpcyB0aWNrIGxhYmVscywgbGFzPTE7IGRlZmF1bHQ6IDANCiAgdHlwZT0iYiIsICAgICAgIyBkZWZhdWx0OiB0eXBlPSJwIiBwb2ludHMgb25seTsgImIiIGJvdGg7ICJsIiBsaW5lIG9ubHk7ICJuIiwgImgiIA0KICBtYWluPSJCb25lIGRlbnNpdHkgd2l0aCBBbGVuZHJvbmF0ZSB0cmVhdG1lbnRcbjY1IHllYXIgb2xkIGZlbWFsZSBwYXRpZW50IiwNCiAgeGxhYj0iVGltZSBmcm9tIEJhc2VsaW5lLCBtb250aHMiLCANCiAgeWxhYj0iQm9uZSBEZW5zaXR5LCBnL2NtXjIiLCANCiAgZm9udC5sYWI9MiwgY2V4LmxhYj0xLjQsIGNleC5heGlzPTEuMiwgICMgbGFiZWwgJiBheGlzIHR5cG9ncmFwaHkNCiAgY2V4Lm1haW49MS44LCBjb2wubWFpbj0iZGFya3JlZCIgICAgICAgICMgdGl0bGUgdHlwb2dyYXBoeQ0KKQ0KYGBgDQpBZnRlciB0aGUgY2FsbCB0byBgcGxvdGAsIHRoZSBgcG9pbnRzYCBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIHRoZSBoaXAgeCx5IGRhdGEuIA0KSGVyZSwgd2UgYWRkIHRoZSBgcGNoYCBhcmcgd2hpY2ggdGFrZXMgaW50ZWdlcnMgZnJvbSAxIHRvIDI1IGFuZCBtb3JlLiBXaGVuIGFuIGFyZyANCmlzIG5vdCBleHBsaWNpdGx5IHVzZWQgaW4gYSBmdW5jdGlvbiBjYWxsIHRoZW4gdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoYXQgYXJnIA0KKHNwZWNpZmllZCBpbiB0aGF0IGZ1bmN0aW9uJ3MgZm9ybWFsIGRlZmluaXRpb24pIGlzIHVzZWQsIGFuZCB0aGUgZGVmYXVsdCBmb3IgcGNoIA0KaXMgYHBjaD0xYCB3aGljaCBzcGVjaWZpZXMgdGhhdCB0aGUgeCx5IGNvb3JkaW5hdGVzIGFyZSBvcGVuIGNpcmNsZXM7IGBwY2g9MTZgIA0KcmV0dXJucyBhIHNvbGlkIGNpcmNsZSBhbmQgdGhpcyBjbGVhcmx5IGRpc3Rpbmd1aXNoZXMgdGhlIHNwaW5lIGZyb20gdGhlIGhpcCBkYXRhIA0KaW4gdGhlIGdyYXBoLiAgDQoNCmBgYA0KIyBhZGQgMm5kIHNldCBvZiBwb2ludHMgd2l0aCBjb25uZWN0aW5nIGxpbmUgLS0tLS0tLS0NCnBvaW50cyh0aW1lLCBoaXAsIHBjaD0xNiwgdHlwZT0iYiIpDQpgYGANClRoZSBgdGV4dGAgYW5kIGBtdGV4dGAgZnVuY3Rpb25zIGFsbG93IHVzIHRvIHB1dCB0ZXh0IHdpdGhpbiB0aGUgZ3JhcGgsIGB0ZXh0YCBhbmQgDQppbiB0aGUgbWFyZ2lucyBvZiB0aGUgZ3JhcGggYG10ZXh0YCwgYWx0aG91Z2ggYG10ZXh0YCBtYXkgYWxzbyBiZSB1c2VkIHRvIGRyYXcgDQp0ZXh0IHdpdGhpbiB0aGUgQ2FydGVzaWFuIGNvb3JkaW5hdGUgc3BhY2UuIEl0IHBheXMgdG8gbGVhcm4gaG93IHRvIHVzZSB0aGVzZSAyIA0KZnVuY3Rpb25zLiANCg0KRm9yIGB0ZXh0KClgIHRoZSBmaXJzdCAyIGFyZ3MgYXJlIHgseSBjb29yZGluYXRlcyB3aGVyZSB5b3Ugd2FudCB0aGUgDQp0ZXh0IHRvIGJlIGRyYXduOyB0aGUgbmV4dCBhcmcgaXMgdGhlIHN0cmluZyB5b3Ugd2FudCBkcmF3bi4gVGhlIGFyZ3MgYGZvbnRgLCANCmBjZXhgIGFuZCBgY29sYCBjb250cm9sICoqZm9udCB0eXBlKiogKGRlZmF1bHQ6IGBmb250PTFgIGZvciByZWd1bGFyLCBgMmAgZm9yIGJvbGQsIA0KYDNgIGZvciBpdGFsaWMsIGA0YCBmb3IgYm9sZCBpdGFsaWMpLCAqKmZvbnQgc2l6ZSoqIChkZWZhdWx0OiBgY2V4PTFgLCBgY2V4PTJgIGlzIA0KdHdpY2UgYXMgbGFyZ2UsIGV0Yy4pIGFuZCAqKmZvbnQgY29sb3IqKiAoZGVmYXVsdDogYGNvbD0iYmxhY2siYCkuDQoNCkhlcmUgd2UgdXNlIHRoZSBgbXRleHQoKWAgZnVuY3Rpb24gdG8gcGxhY2UgYSBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcCBhbG9uZyB0aGUgDQpsb3dlciByaWdodCBlZGdlIG9mIHRoZSBncmFwaCB3aW5kb3csIHVzaW5nIHJlZHVjZWQgZm9udCBzaXplIGFuZCBncmF5IGNvbG9yLiBUaGlzIA0KZ2l2ZXMgY3JlZGl0L2JsYW1lIHRvIHRoZSBpbnZlc3RpZ2F0b3IhIEZvciBgbXRleHQoKWAgdGhlIGZpcnN0IGFyZyBpcyB0aGUgc3RyaW5nIA0KeW91IHdhbnQgdG8gZHJhdywgdGhlIGBzaWRlYCBhcmcgaXMgZWl0aGVyIDEsIDIsIDMgb3IgNCBmb3IgbG93ZXIgc2lkZSwgbGVmdCBzaWRlLCANCnRvcCBzaWRlLCByaWdodCBzaWRlIG9mIGdyYXBoIHdpbmRvdywgcmVzcGVjdGl2ZWx5LiBUaGUgYGFkamAgYXJnIHNwZWNpZmllcyB0aGUgDQpsZWZ0LXJpZ2h0IHBvc2l0aW9uIG9mIHRoZSB0ZXh0LCB3aGVyZSBgYWRqPTBgIGlzIGxlZnQganVzdGlmaWVkIGFuZCBgYWRqPTFgIHJpZ2h0IA0KanVzdGlmaWVkLiBUaGUgYGxpbmVgIGFyZyBoYXMgZGVmYXVsdCBvZiBgbGluZT0wYCB3aGljaCBpcyBhdCB0aGUgZ3JhcGggZWRnZTsgDQpgbGluZT00YCBpcyBmb3VyIGxpbmVzIGJlbG93IHRoZSBib3R0b20gZWRnZSBvZiB0aGUgZ3JhcGguIFRoZSBgY2V4YCBhcmcgY29udHJvbHMgDQpmb250IHNpemUsIGFzIGV4cGxhaW5lZCBhYm92ZSwgd2hpbGUgdGhlIGBjb2xgIGFyZyBjb250cm9scyB0ZXh0IGNvbG9yLiANCg0KYGBgDQojIGxhYmVsIGVhY2ggbGluZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCnRleHQoMjAsIC44NSwgIkx1bWJhciBTcGluZSIsIGZvbnQ9MSwgY2V4PTEuMiwgY29sPSJkYXJrcmVkIikNCnRleHQoMjAsIC42OSwgIlRlbXBvcmFsIE5lY2sgKGhpcCkiLCBmb250PTEsIGNleD0xLjIsIGNvbD0iZGFya3JlZCIpDQoNCiMgYWRkIHBlcnNvbmFsaXplZCB0aW1lIHN0YW1wOyBnb29kIGZvciBwcmVzZW50YXRpb24gcXVhbGl0eSBncmFwaCAtLS0tLS0tLS0NCm10ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOCwgY29sPSJncmF5IikNCg0KYGBgDQoNCjxicj4gDQpUaGUgZW50aXJlLCBSIGNvZGUgY2h1bmsgaXMgYmVsb3cuIEl0IHJldHVybnMgdGhlIGVuaGFuY2VkIGdyYXBoIC0tIGEgZ3JhcGggb25lIA0Kd291bGQgYmUgcHJvdWQgdG8gZGlzcGxheSBhbmQgdG8gc3VibWl0LiAgDQoNCmBgYHtyIGVjaG89VCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NywgZmlnLmFsaWduPSJjZW50ZXIifQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGVuaGFuY2VkLCBwb2ludCBhbmQgbGluZSBncmFwaDogMiBzZXRzIG9mIHgseSBwb2ludHMgLS0tLS0tLS0tLS0tLS0NCiMgICB3aXRoIGVhY2ggbGluZSBsYWJlbGVkIHdpdGhpbiB0aGUgZ3JhcGggICAgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KcGxvdCh0aW1lLCBzcGluZSwgDQogIGNvbD0iYmxhY2siLCAgIyBjb2xvciBvZiBwb2ludHM7IGRlZmF1bHQsIGNvbD0iYmxhY2siDQogIGNleD0xLCAgICAgICAgIyBzaXplIG9mIHN5bWJvbCBwbG90dGVkOyBkZWZhdWx0LCBjZXg9MQ0KICB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpLCAgIyBhZGp1c3QgeS1heGlzIHJhbmdlDQogIHhsaW09YygtNSwgMTAwKSwgICAgICAgICAgICAjICAgIiAgICB4LWF4aXMgICINCiAgbGFzPTAsICAgICAgICAgIyBmbGlwIHktYXhpcyB0aWNrIGxhYmVscywgbGFzPTE7IGRlZmF1bHQ6IDANCiAgdHlwZT0iYiIsICAgICAgIyBkZWZhdWx0OiB0eXBlPSJwIiBwb2ludHMgb25seTsgImIiIGJvdGg7ICJsIiBsaW5lIG9ubHk7ICJuIiwgImgiIA0KICBtYWluPSJCb25lIGRlbnNpdHkgd2l0aCBBbGVuZHJvbmF0ZSB0cmVhdG1lbnRcbjY1IHllYXIgb2xkIGZlbWFsZSBwYXRpZW50IiwNCiAgeGxhYj0iVGltZSBmcm9tIEJhc2VsaW5lLCBtb250aHMiLCANCiAgeWxhYj0iQm9uZSBEZW5zaXR5LCBnL2NtXjIiLCANCiAgZm9udC5sYWI9MiwgY2V4LmxhYj0xLjQsIGNleC5heGlzPTEuMiwgICMgbGFiZWwgJiBheGlzIHR5cG9ncmFwaHkNCiAgY2V4Lm1haW49MS44LCBjb2wubWFpbj0iZGFya3JlZCIgICAgICAgICMgdGl0bGUgdHlwb2dyYXBoeQ0KKQ0KDQojIGFkZCAybmQgc2V0IG9mIHBvaW50cyB3aXRoIGNvbm5lY3RpbmcgbGluZSAtLS0tLS0tLQ0KcG9pbnRzKHRpbWUsIGhpcCwgcGNoPTE2LCB0eXBlPSJiIikNCg0KIyBsYWJlbCBlYWNoIGxpbmUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0ZXh0KDIwLCAuODUsICJMdW1iYXIgU3BpbmUiLCBmb250PTEsIGNleD0xLjIsIGNvbD0iZGFya3JlZCIpDQp0ZXh0KDIwLCAuNjksICJUZW1wb3JhbCBOZWNrIChoaXApIiwgZm9udD0xLCBjZXg9MS4yLCBjb2w9ImRhcmtyZWQiKQ0KDQojIGFkZCBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcDsgZ29vZCBmb3IgcHJlc2VudGF0aW9uIHF1YWxpdHkgZ3JhcGggLS0tLS0tLS0tDQptdGV4dChwYXN0ZSgiQXJsbzogIiwgZGF0ZSgpKSwgc2lkZT0xLCBhZGo9MSwgbGluZT00LCBjZXg9LjgsIGNvbD0iZ3JheSIpDQoNCmBgYA0KDQoNCjx1PlByZXNlbnRhdGlvbiBxdWFsaXR5IGdyYXBoPC91PiB3aXRoIHRpdGxlLCB0aGUgMiBsaW5lcyBsYWJlbGVkIHdpdGhpbiBncmFwaCANCmFuZCBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcC4gDQo8YnI+PGJyPiANCg0KKipRdWVzdGlvbjoqKiAmbmJzcDsgSG93IGRvIHdlIG1vZGlmeSB0aGUgYWJvdmUgY29kZSB0byBtYWtlIGEgPHU+UHVibGljYXRpb24gDQpxdWFsaXR5IGdyYXBoPC91PiAtLSBvbmUgd2l0aG91dCBhIHRpdGxlIGFuZCB3aXRob3V0IHRoZSBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcD8gIA0KKipBbnN3ZXI6KiogJm5ic3A7IFdlICoqY29tbWVudCBvdXQqKiB0aGUgYG1haW5gIGFyZyBpbiBgcGxvdCgpYCBhbmQgd2UgDQoqKmNvbW1lbnQgb3V0KiogdGhlIGNhbGwgdG8gYG10ZXh0KClgIGZvciB0aGUgcGVyc29uYWxpemVkIHRpbWUgc3RhbXAuIA0KDQpJbiB5b3VyIGludGVyYWN0aXZlLCBSIGNvZGluZyB3b3JrZmxvdyB5b3UgbXVzdCBtYXN0ZXIsICoqY29tbWVudCBvdXQqKiANCih0byBhZGQgdGhlIGhhc2h0YWcgdG8gdGhlIGxlZnQgb2YgY29kZSB0byBiZSBpZ25vcmVkIGJ5IFIpIGFuZCAqKmNvbW1lbnQgaW4qKiANCih0byByZW1vdmUgdGhlIGhhc3RhZykgd2hpY2ggYWN0aXZhdGVzIHRoZSBjb2RlLiANCg0KYGBge3IgZWNobz1ULCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03LCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy5zaG93PSJob2xkIn0NCg0KcGxvdCh0aW1lLCBzcGluZSwgDQogIGNvbD0iYmxhY2siLCAgIyBjb2xvciBvZiBwb2ludHM7IGRlZmF1bHQsIGNvbD0iYmxhY2siDQogIGNleD0xLCAgICAgICAgIyBzaXplIG9mIHN5bWJvbCBwbG90dGVkOyBkZWZhdWx0LCBjZXg9MQ0KICB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpLCAgIyBhZGp1c3QgeS1heGlzIHJhbmdlDQogIHhsaW09YygtNSwgMTAwKSwgICAgICAgICAgICAjICAgIiAgICB4LWF4aXMgICINCiAgbGFzPTAsICAgICAgICAgIyBmbGlwIHktYXhpcyB0aWNrIGxhYmVscywgbGFzPTE7IGRlZmF1bHQ6IDANCiAgdHlwZT0iYiIsICAgICAgIyBkZWZhdWx0OiB0eXBlPSJwIiBwb2ludHMgb25seTsgImIiIGJvdGg7ICJsIiBsaW5lIG9ubHk7ICJuIiwgImgiIA0KICAjbWFpbj0iQm9uZSBkZW5zaXR5IHdpdGggQWxlbmRyb25hdGUgdHJlYXRtZW50XG42NSB5ZWFyIG9sZCBmZW1hbGUgcGF0aWVudCIsDQogIHhsYWI9IlRpbWUgZnJvbSBCYXNlbGluZSwgbW9udGhzIiwgDQogIHlsYWI9IkJvbmUgRGVuc2l0eSwgZy9jbV4yIiwgDQogIGZvbnQubGFiPTIsIGNleC5sYWI9MS40LCBjZXguYXhpcz0xLjIsICAjIGxhYmVsICYgYXhpcyB0eXBvZ3JhcGh5DQogIGNleC5tYWluPTEuOCwgY29sLm1haW49ImRhcmtyZWQiICAgICAgICAjIHRpdGxlIHR5cG9ncmFwaHkNCikNCg0KIyBhZGQgMm5kIHNldCBvZiBwb2ludHMgd2l0aCBjb25uZWN0aW5nIGxpbmUgLS0tLS0tLS0NCnBvaW50cyh0aW1lLCBoaXAsIHBjaD0xNiwgdHlwZT0iYiIpDQoNCiMgbGFiZWwgZWFjaCBsaW5lIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KdGV4dCgyMCwgLjg1LCAiTHVtYmFyIFNwaW5lIiwgZm9udD0xLCBjZXg9MS4yLCBjb2w9ImRhcmtyZWQiKQ0KdGV4dCgyMCwgLjY5LCAiVGVtcG9yYWwgTmVjayAoaGlwKSIsIGZvbnQ9MSwgY2V4PTEuMiwgY29sPSJkYXJrcmVkIikNCg0KIyBhZGQgcGVyc29uYWxpemVkIHRpbWUgc3RhbXA7IGdvb2QgZm9yIHByZXNlbnRhdGlvbiBxdWFsaXR5IGdyYXBoIC0tLS0tLS0tLQ0KI210ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOCwgY29sPSJncmF5IikNCg0KYGBgDQo8dT5QdWJsaWNhdGlvbiBxdWFsaXR5IGdyYXBoPC91Pg0KDQoNCjxicj4gDQoNCiMjIyAmbmJzcDsgRW5oYW5jZWQgZ3JhcGhzIHdpdGggbGVnZW5kcyANCg0KDQpgYGB7ciBlY2hvPVQsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTcsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLnNob3c9ImhvbGQifQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBFbmhhbmNlZCBHUkFQSCwgdXNpbmcgbGVnZW5kKCkgIC0tIHVzZSBvZiBsZWdlbmQoKSBpcyBPUFRJT05BTCBpbiBCaW8gMjQwIC0tLQ0KIyAgIEJVVCwgYWRkaW5nIGxhYmVscyB3aXRoaW4gZ3JhcGhzIGFuZCBpbiBncmFwaCBtYXJnaW5zLCBpcyByZXF1aXJlZA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KY3gxIDwtIDEuNjsgY3gyIDwtIDEuMjsgY3gzIDwtIDEuOCAgIyB2YXJzIGZvciB0eXBvZ3JhcGh5IGNvbnZlbmllbmNlDQpjMSA8LSAiZGFya3JlZCINCg0KcGxvdCh0aW1lLCBzcGluZSwNCiAgdHlwZT0iYiIsIA0KICBidHk9ImwiLCAgIyB0eXBlIG9mICdib3gnOyBkZWZhdWx0OiAibyIsICJsIiwgIjciLCAiYyIsICJ1IiwgIl0iICANCiAgeWxpbT1jKC42MiwgLjkpLCAgICMgeC1heGlzIHJhbmdlDQogIHhsaW09YygtNSwgMTAwKSwgICAjIHktYXhpcyByYW5nZQ0KICBjZXg9MS40LCBjZXgubGFiPWN4MSwgY2V4LmF4aXM9Y3gyLCBmb250LmxhYj0xLCAjIHR5cG9ncmFwaHkNCiAgY2V4Lm1haW49Y3gzLCBjb2wubWFpbj1jMSwgY29sLmxhYj1jMSwgICAgICAgICAgIyB0eXBvZ3JhcGh5DQogIHhsYWI9IlRpbWUgZnJvbSBCYXNlbGluZSwgbW9udGhzIiwNCiANCiAgeWxhYj0iIiwgICAjIHR1cm4tb2ZmIHktYXhpcyBsYWJlbCBpZiBkb2luZyBpdCBieSBtdGV4dCgpDQogICN5bGFiPSJCb25lIERlbnNpdHksIGcvY21eMiIsIA0KICAjeWxhYj1leHByZXNzaW9uKCJCb25lIERlbnNpdHksIGcvY20iIF4yKSwNCg0KICBtYWluPSJCb25lIGRlbnNpdHkgd2l0aCBBbGVuZHJvbmF0ZSB0cmVhdG1lbnRcbjY1IHllYXIgb2xkIGZlbWFsZSBwYXRpZW50Ig0KICAjbWFpbj0iNjUgIHllYXIgIG9sZCAgZmVtYWxlICBwYXRpZW50IiwgY2V4Lm1haW49Y3gzDQopDQoNCiMgdXNlIG10ZXh0KCkgZm9yIHktYXhpcyBsYWJlbCB0byBkZWFsIHdpdGggY3Jvd2RpbmcgaXNzdWUgDQptdGV4dChleHByZXNzaW9uKCJCb25lIERlbnNpdHksIGcvY20iIF4gMiksIHNpZGU9MiwNCiAgICAgIGxpbmU9Mi4zLCBjZXg9Y3gxLCBjb2w9YzEsIGZvbnQ9MSkNCg0KcG9pbnRzKHRpbWUsIGhpcCwgcGNoPTE2LCBjZXg9MS40LCB0eXBlPSJiIikgIyBhZGQgaGlwIHgseSBkYXRhDQptdGV4dChwYXN0ZSgiQXJsbzogIiwgZGF0ZSgpKSwgc2lkZT0xLCBhZGo9MSwgbGluZT00LCBjZXg9LjgsIGNvbD0iZ3JheSIpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGxlZ2VuZCgpIHRha2VzIG1hbnkgYXJncyAtLS0gT3B0aW9uYWwgaW4gQmlvIDI0MCAtLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpsZWdlbmQoeD01NSwgeT0uNzksICAgIyB4LHkgZm9yIHRvcC1sZWZ0IGNvcm5lciwgYnkgdHJpYWwtYW5kLWVycm9yDQogIGxlZ2VuZD1jKCJMdW1iYXIgU3BpbmUiLCAiVGVtcG9yYWwgTmVjayAoaGlwKSIpLCANCiAgcGNoPWMoMSwgMTYpLCBjZXg9MS4yLCB0ZXh0LmZvbnQ9MywgcHQuY2V4PTEuNSwNCiAgeC5pbnRlcnNwPTEuMywgeS5pbnRlcnNwPTEuMiwgdGl0bGUuY29sPSJkYXJrcmVkIiwNCiAgdGl0bGU9IiAgQWxlbmRyb25hdGUgdHJlYXRtZW50ICAiKQ0KDQpgYGANClByZXNlbnRhdGlvbiBxdWFsaXR5IGdyYXBoIHVzaW5nIHRoZSBgbGVnZW5kKClgIGZ1bmN0aW9uLg0KDQo8YnI+PGJyPiAgDQoNClJhdGhlciB0aGFuIHVzaW5nIHRoZSBgbGVnZW5kKClgIGZ1bmN0aW9uLCBuaWNlIGxhYmVscy9sZWdlbmRzIGFyZSBlYXNpbHkgbWFkZSANCnVzaW5nIGBwb2ludHMoKWAgYW5kIGB0ZXh0KClgIGFuZCB3aXRoIGdyZWF0ZXIgZmxleGliaWxpdHksIGluIG15IG9waW5pb24uIA0KDQpgYGB7ciBlY2hvPVQsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTcsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLnNob3c9ImhvbGQifQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEFMVEVSTkFUSVZFIHRvIGxlZ2VuZCgpIC0tIG5pY2UgbGFiZWxzIGJ5IHBvaW50cygpIGFuZCB0ZXh0KCkgLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KcGxvdCh0aW1lLCBzcGluZSwgY2V4PTEuMiwgeWxpbT1jKC42LCAuOSksIHR5cGU9ImIiLCBjZXgubGFiPTEuMywNCiAgICAgeGxhYj0iVGltZSBmcm9tIEJhc2VsaW5lLCBtb250aHMiLCB5bGFiPSJCb25lIERlbnNpdHksIGcvY21eMiIpDQpwb2ludHModGltZSwgaGlwLCBjZXg9MS4yLCBwY2g9MTYsIHR5cGU9ImIiICkNCg0KcG9pbnRzKDYwLCAuNzgsIHBjaD0xLCBjZXg9MS41KSAgICAgICAgICAgICAgIyBwdXQgbGFiZWwNCnRleHQoNjIsIC43OCwgIkx1bWJhciBTcGluZSIsIHBvcz00LCBmb250PTMpICMgd2l0aGluIGdyYXBoDQoNCnBvaW50cyg2MCwgLjc1LCBwY2g9MTYsIGNleD0xLjUpICAgICAgICAgICAgICMgbGFiZWwNCnRleHQoNjIsIC43NSwgIlRlbXBvcmFsIE5lY2sgKGhpcCkiLCBwb3M9NCwgZm9udD0zKQ0KDQpgYGANCg0KPGJyPjxicj4NCjxwIHN0eWxlPSJmb250LWZhbWlseTogJ2NvbWljIHNhbnMgbXMnOyBmb250LXNpemU6IDE1cHQ7IGZvbnQtd2VpZ2h0OiBub3JtYWw7IA0KICAgICAgICAgIGNvbG9yOiBkYXJrcmVkOyB0ZXh0LWFsaWduOiByaWdodDsiPg0KPGk+VGhlIHNpbXBsZSBncmFwaCBoYXMgYnJvdWdodCBtb3JlIGluZm9ybWF0aW9uIHRvIHRoZSBkYXRhIGFuYWx5c3QncyBtaW5kIHRoYW4gYW55IA0Kb3RoZXIgZGV2aWNlLjwvaT48YnI+Sm9obiBUdWtleSAoMTkxNS0yMDAwKSBQcmluY2V0b24gVW5pdmVyc2l0eTwvcD4NCjxicj48YnI+DQoNCiANCg0KPCEtLSBjb21tZW50ZWQgb3V0IC4uLi4uLi4uLi4NCiAgPiANCiAgPipUaGUgc2ltcGxlIGdyYXBoIGhhcyBicm91Z2h0IG1vcmUgaW5mb3JtYXRpb24gdG8gdGhlIGRhdGEgYW5hbHlzdCdzIG1pbmQgdGhhbiBhbnkgDQogIG90aGVyIGRldmljZS4qDQogID4gLS0tIEpvaG4gVHVrZXkgKDE5MTUtMjAwMCkgUHJpbmNldG9uIFVuaXZlcnNpdHkgDQogIDxicj4NCi0tPg0KDQoNCiMjIyAmbmJzcDsgR3JhcGhzIHdpdGggc3RhdGlzdGljYWwgcmVzdWx0cyANCg0KT2Z0ZW4sIHdlIHdpc2ggdG8gcHV0IHN0YXRpc3RpY2FsIHJlc3VsdHMgd2l0aGluIGEgZ3JhcGgsIHdoZXRoZXIgaXQncyBkcmFmdCANCnF1YWxpdHksIHByZXNlbnRhdGlvbiBxdWFsaXR5IG9yIHB1YmxpY2F0aW9uIHF1YWxpdHkuIA0KDQpgYGB7ciBlY2hvPVQsIGZpZy53aWR0aD03LjUsIGZpZy5oZWlnaHQ9NywgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuc2hvdz0iaG9sZCJ9DQoNCnBsb3QodGltZSwgc3BpbmUsIGNleD0xLjIsIHlsaW09YyguNiwgLjkpLCB0eXBlPSJiIiwgY2V4LmxhYj0xLjMsDQogICAgIHhsYWI9IlRpbWUgZnJvbSBCYXNlbGluZSwgbW9udGhzIiwgeWxhYj0iQm9uZSBEZW5zaXR5LCBnL2NtXjIiKQ0KcG9pbnRzKHRpbWUsIGhpcCwgY2V4PTEuMiwgcGNoPTE2LCB0eXBlPSJiIiApDQoNCnBvaW50cyg2MiwgLjc4LCBwY2g9MSwgY2V4PTEuNSkgICAgICAgICAgICAgICMgcHV0IGxhYmVsDQp0ZXh0KDY0LCAuNzgsICJMdW1iYXIgU3BpbmUiLCBwb3M9NCwgZm9udD0zKSAjIHdpdGhpbiBncmFwaA0KDQpwb2ludHMoNjIsIC43NSwgcGNoPTE2LCBjZXg9MS41KSAgICAgICAgICAgICAjIGxhYmVsDQp0ZXh0KDY0LCAuNzUsICJUZW1wb3JhbCBOZWNrIChoaXApIiwgcG9zPTQsIGZvbnQ9MykNCg0KDQojIGFkZCBPTFMgbGluZWFyIHJlZ3Jlc3Npb24gZml0IHdpdGggc2xvcGUgJiBwLXZhbHVlIC0tLS0tLS0tLS0NCg0Kc3BpbmUucmVnIDwtIGxtKHNwaW5lIH4gdGltZSkgIyBwZXJmb3JtIE9MUyBsaW5lYXIgcmVncmVzc2lvbiwgc3BpbmUgYnkgdGltZQ0KaGlwLnJlZyAgIDwtIGxtKGhpcCB+IHRpbWUpICAgIyAgIiAgICAgICIgICAgIiAgICAgICIgICAgICAgICwgaGlwIGJ5IHRpbWUNCg0KYWJsaW5lKHNwaW5lLnJlZywgY29sPSJncmF5IiwgbHdkPTIsIGx0eT0yKSAjIGFkZCBsaW5lYXIgcmVncmVzc2lvbiBmaXRzDQphYmxpbmUoaGlwLnJlZywgICBjb2w9ImdyYXkiLCBsd2Q9MiwgbHR5PTIpDQoNCiNzdW1tYXJ5KHNwaW5lLnJlZykgIyBzbG9wZSAuMDAwODgwMiwgci1zcSAuODYgIyBpbnNwZWN0IHRoZSByZWdyZXNzaW9uIG9iamVjdA0KI3N1bW1hcnkoaGlwLnJlZykgICAjIHNsb3BlIC4wMDAzMTMzLCByLXNxIC4zOCAjICAgIg0KDQojIGFkZCBzdGF0cyB3aXRoaW4gZ3JhcGggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBhZGQgci1zcSUgd2l0aCBjb3JyZWxhdGlvbiBwLXZhbHVlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiN0ZXh0KDEzLCAuODUsICJyLXNxID0gODYlXG5wID0gMC4wMDA0NigxKSIsIGNleD0xKSANCiN0ZXh0KDEzLCAuNjgsICJyLXNxID0gMzglXG5wID0gMC4wNTIoMSkiLCBjZXg9MSkgICANCg0KIyBhZGQgbGluZWFyIHJlZ3Jlc3Npb24gc2xvcGUsIHdpdGggcC12YWx1ZSAtLS0tLS0tLS0tLS0tLS0tLS0gDQojdGV4dCgxMywgLjg1LCAic2xvcGUgPSAuMDAwODgwMiBcbnAgPSAwLjAwMDQ2KDEpIiwgY2V4PTEpIA0KI3RleHQoMTMsIC42OCwgInNsb3BlID0gLjAwMDMxMzMgXG5wID0gMC4wNTIoMSkiLCBjZXg9MSkgICANCg0KIyBhZGQgci1zcSUsIGxpbmVhciByZWdyZXNzaW9uIHNsb3BlLCB3aXRoIHAtdmFsdWUgLS0tLS0tLS0tLS0gDQp0ZXh0KDEzLCAuODYsICJyLXNxID0gODYlXG5zbG9wZSA9IDAuMDAwODgwMlxucCA9IDAuMDAwNDYoMSkiLCBjZXg9MSkgDQp0ZXh0KDEzLCAuNjksICJyLXNxID0gMzglXG5zbG9wZSA9IDAuMDAwMzEzM1xucCA9IDAuMDUyKDEpIiwgY2V4PTEpDQoNCm10ZXh0KHBhc3RlKCJCb25lIGRlbnNpdHkgaW5jcmVhc2VkIHNpZ25pZmljYW50bHkgd2l0aCB0aW1lXG5mb3IgTHVtYmFyIFNwaW5lIiwNCiAgICAgICAgICAgICJidXQgbm90IGZvciBIaXAiKSwgc2lkZT0zLCBsaW5lPTEsIGNleD0xLjUsIGNvbD0iZGFya3JlZCIpDQoNCm10ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOCwgY29sPSJncmF5IikNCg0KYGBgDQoNCjxicj4gDQoNCiMjIyAmbmJzcDsgQWRkaXRpb25hbCBhbmFseXNpcw0KDQpTbyBmYXIgZm9yIHRoaXMgZGF0YSBzZXQsIHdlIGhhdmUgc3RvcmVkIGFuZCB1c2VkIHZlY3RvcnMuIE5vdywgcG91cmluZyB0aGUgZGF0YSANCmludG8gYSByb3ctYnktY29sdW1uICoqZGF0YSBmcmFtZSoqIG9iamVjdCBpcyBuZWVkZWQgdG8gcHJvY2VlZC4gIA0KDQpgYGB7cn0NCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgY29uc3RydWN0IGRhdGEgZnJhbWUgIG9mIDEyIHJvd3MgYnkgMyBjb2x1bW5zOiBtb250aHMsIGRlbnMsIGJvbmUgLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KZGVucyA8LSBjKHNwaW5lLCBoaXApICMgY29tYmluZSByZXNwb25zZSB2ZWN0b3JzIGludG8gb25lIG51bWVyaWMgdmVjdG9yIA0KYm9uZSA8LSBjKHJlcCgic3BpbmUiLCA4KSwgcmVwKCJoaXAiLCA4KSkgIyBjcmVhdGUgbWF0Y2hpbmcsIGdyb3VwaW5nIHZhcmlhYmxlDQoNCiMgY2hhbmdlIGNoYXJhY3RlciB2ZWN0b3IgJ2JvbmUnIHRvIGEgZmFjdG9yDQojIHNwZWNpZnkgZGVzaXJlZCAnb3JkZXInIG9mIGZhY3RvciBsZXZlbHMNCmJvbmUgPC0gZmFjdG9yKGJvbmUsIGxldmVscz1jKCJzcGluZSIsICJoaXAiKSkNCiANCm1vbnRocyA8LSBjKHRpbWUsIHRpbWUpICMgdGhlICdtb250aHMnIGNvbHVtbjogbnVtZXJpYyB2ZWN0b3INCg0KZGZyIDwtIGRhdGEuZnJhbWUobW9udGhzLCBkZW5zLCBib25lKSAjIGF0dGFjaCB0aGUgMyB2ZWN0b3JzIGFzIGNvbHVtbnMNCg0Kc3RyKGRmcikgICAgICMgY2hlY2tpbmcNCnN1bW1hcnkoZGZyKSAjIGNoZWNraW5nDQpkZnIgICAgICAgICAgIyBwcmludCBkYXRhIGZyYW1lDQoNCmBgYA0KDQpXZSBzZWVrIGEgYmF0Y2ggb2Ygc3RhdGlzdGljcyBmb3IgZWFjaCBvZiB0aGUgdHdvIGdyb3VwcyAtLSB0aGUgc3BpbmUgZGVuc2l0eSB4LHkgDQpkYXRhIHNldCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgaGlwIGRlbnNpdHkgZGF0YSBzZXQuIEhhdmluZyBhbGwgdGhlIGRhdGEgb3JnYW5pemVkIA0KaW4gYSBkYXRhIGZyYW1lIGlzIGFsd2F5cyBoZWxwZnVsIGFuZCB1c3VhbGx5IG5lY2Vzc2FyeS4gDQoNCg0KIyMgJm5ic3A7IFIgRWRpdG9yIGZpbGUgLS0gPGk+dGhlIGZpbmFsIHByb2dyYW08L2k+DQoNCjxicj4NCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjMiPg0KDQpBcyBicm9rZW4gZG93biBhbmQgZGV2ZWxvcGVkIHN0ZXAtYnktc3RlcCBpbiB0aGUgU2VjdGlvbnMgYWJvdmUsIHRoZSBjb21wbGV0ZSAqKlIgDQpFZGl0b3IgZmlsZSoqIGlzIGF2YWlsYWJsZSBiZWxvdyBpbiBhIHNjcm9sbGVkIHdpbmRvdy4gDQoNClJlYWQgYW5kIHN0dWR5IHRoZSBjb2RlLiBFaXRoZXIgdHlwZSBpdCBpbiB5b3Vyc2VsZiAocHJlZmVyYWJsZSksIGNvcHkvcGFzdGUgaXQsIA0Kb3Igb3RoZXJ3aXNlICJhY3F1aXJlIiB0aGlzIFIgRWRpdG9yIGZpbGUuIE93biBpdCBieSBwdXR0aW5nIHlvdXIgbmFtZSB3aXRoaW4gDQp0aGUgZmlsZSBuYW1lLiBTdWJtaXQgaXRzIGNvZGUgYmxvY2tzLCB0b3AtZG93biBhbmQgaW50ZXJhY3RpdmVseSBhdCB0aGUgUiANCkNvbnNvbGUuIA0KDQpFeHBlcmltZW50IGJ5IGNoYW5naW5nIHRoZSBhcmd1bWVudHMgaW4gdGhlIGdyYXBoIGZ1bmN0aW9ucyBhbmQgcHJhY3RpY2UgDQpmbGlwcGluZyBiZXR3ZWVuIHByZXNlbnRhdGlvbiBxdWFsaXR5IGFuZCBwdWJsaWNhdGlvbiBxdWFsaXR5IGdyYXBocywgdXNpbmcgDQoqY29tbWVudCBpbiogYW5kICpjb21tZW50IG91dCouIFJlbWVtYmVyOiBgID4/ZnVuLm5hbWVgIA0KDQpUaGlzIFIgRWRpdG9yIGZpbGUgcmVmbGVjdHMgYSB0eXBpY2FsICoqd29ya2Zsb3cqKiB3ZSBvZnRlbiBmb2xsb3cgaW4gUiBjb2RlIA0KZGV2ZWxvcG1lbnQuIEl0J3Mgd2VsbC1jb21tZW50ZWQgdGhyb3VnaG91dCBhbmQgcmV0YWlucyB0aGUgYmVnaW5uaW5nLCBtaW5pbWFsIA0KY2FsbHMgYW5kIHRoZSBpbnRlcm1lZGlhdGUgY29kZSwgbm90IGp1c3QgdGhlIGNvZGUgZm9yIHNheSwgYSBmaW5hbCwgaGlnaCBxdWFsaXR5IA0KZ3JhcGguIA0KDQpJdCBhbHNvIG1ha2VzIG1vZGVzdCB1c2Ugb2YgdGV4dCBvdXRwdXQgZnJvbSBSIENvbnNvbGUsIHBhc3RlZCBpbiBhcyBsaW5lcywgDQpjb21tZW50ZWQgb3V0LiBUaGlzIGlzIGEgY29udmVuaWVuY2UsIHRvIGluZm9ybSB0aGUgaW52ZXN0aWdhdG9yIHdoaWxlIGNvZGluZy4gDQpJbiBvdGhlciB3b3JkcywgdG8gbWFrZSBpdCBlYXN5IGZvciB0aGUgY29kZXIgdG8gc2VlIHNhbGllbnQgcmVzdWx0cyB0aGF0IG1heSANCnByb3ZpZGUgZ3VpZGFuY2UgYW5kIGlkZWFzLiANCg0KWW91IG1heSBhbHNvIG5vdGljZSB0aGlzIGZpbGUgY29udGFpbnMgbW9yZSBSIGNvZGUgdGhhbiBleHBsaWNpdGx5IGV4cGxhaW5lZCBhYm92ZS4gDQpBbmQsIGl0IG1heSBoYXZlIG1pbm9yIHN0eWxpc3RpYyBkaWZmZXJlbmNlcyBmcm9tIHRoZSBhYm92ZSwgY29kZSBibG9jayBieSBjb2RlIA0KYmxvY2sgYnJlYWtkb3duLiANCg0KKEEgc3Vic3RhbnRpYWwgdGFzayB3b3VsZCBiZSB0byB0cmFuc2Zvcm0gdGhlIGNvbnRlbnRzIG9mIHRoaXMgDQpSIEVkaXRvciBmaWxlLCBpbnRvIGEgbmV3IGZ1bmN0aW9uLikgDQo8L2Rpdj4NCjxicj4gIA0KDQo8IS0tIHRoZSA8ZGV0YWlscz4gaHRtbCB0YWcgaXMgYSAnZGlzY2xvc3VyZScgd2lkZ2V0LCB0byBjbGljayB0byByZXZlYWwgIC0tPiANCjwhLS0gdGhlIDxzdW1tYXJ5PiB0YWcgaXMgdGhlICd2aXNpYmxlIGhlYWRpbmcnIHRvIGNsaWNrIGZvciA8ZGV0YWlscz4gICAtLT4gDQoNCjxkZXRhaWxzPg0KPGJyPiAgDQoNCjxzdHlsZT4NCmRldGFpbHM+IHN1bW1hcnl7IA0KICBwYWRkaW5nOiAxMHB4OyANCiAgd2lkdGg6IDc1MHB4OyANCiAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5OyANCiAgYm9yZGVyOiAxLjVweCByZWQ7IGJvcmRlci1zdHlsZTogc29saWQ7DQogIGJveC1zaGFkb3c6IDVweCA1cHggMXB4ICNiYmJiYmI7DQogIGNvbG9yOiBibGFjazsgZm9udC1mYW1pbHk6IFZlcmRhbmE7IGZvbnQtc2l6ZTogMTAwJTsgDQogIGN1cnNvcjogcG9pbnRlcjsNCn0NCjwvc3R5bGU+DQoNCjxzdW1tYXJ5PkNsaWNrIHRvIHNjcm9sbCB0aGUgZW50aXJlICoqUiBFZGl0b3IgZmlsZSoqIGluIGEgYmx1ZSBibG9jayAtLSBjbGljayANCmFnYWluIHRvIHJlbW92ZQ0KPC9zdW1tYXJ5Pg0KDQoNCjwhLS0gIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KPCEtLSAgICAgIHRleHQgYmxvY2sgb2YgdGhlIGVudGlyZSBSIEVkaXRvciBmaWxlLCBzY3JvbGxlZCAgICAgLS0+IA0KPCEtLSAgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gLS0+DQoNCg0KYGBge3N0eWxlPSJtYXgtaGVpZ2h0OiA3MDBweDsgbWF4LXdpZHRoOiA5MDBweDsgZm9udC1mYW1pbHk6IENvdXJpZXI7IA0KICAgIGZvbnQtc2l6ZTogOTAlOyBiYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGJsdWU7In0NCg0KIyBib25lIGRlbnNpdHkgQXJsby5SICAgIEphbnVhcnksIDIwMjIgICAgQXJsbyBBdHosIEJTDQoNCiMgQm9uZSBkZW5zaXR5IHdhcyBtZWFzdXJlZCBvdmVyIDkyIG1vbnRocyBpbiBhIDY1IHllYXIgb2xkIHdvbWFuIHdpdGggbG93IGJvbmUNCiMgZGVuc2l0eSwgdHJlYXRlZCB3aXRoIEFsZW5kcm9uYXRlLCAyMDAyIHRocm91Z2ggMjAwOS4gQm9uZSBtaW5lcmFsIGRlbnNpdHkgDQojIChnL2NtXjIpIHdhcyBtZWFzdXJlZCBmb3IgbHVtYmFyIHNwaW5lIGFuZCBmZW1vcmFsIG5lY2soaGlwKSAoUm9zbmVyLCBCLiAyMDE2KS4NCg0KdGltZSA8LSBjKDAsIDgsIDE4LCA0OCwgNjQsIDY2LCA3OSwgOTIpICAjIG1vbnRocyBmcm9tIGJhc2VsaW5lDQoNCnNwaW5lIDwtIGMoLjc5NywgLjgwNiwgLjgxNywgLjgyNSwgLjgzNywgLjg0MSwgLjg4NiwgLjg4MSkgIyBzcGluZSBib25lIGRlbnNpdHkNCmhpcCAgIDwtIGMoLjY0MywgLjYzOCwgLjY0OCwgLjY3NCwgLjY0LCAgLjY3NiwgLjY1MSwgLjY4KSAgIyBoaXAgICAgIiAgICAgIg0KDQojIHZpZXcgZGF0YSBhdCBSIENvbnNvbGUgdG8gY2hlY2sgY2FyZWZ1bGx5LCB2ZXJzdXMgb3JpZ2luYWwNCmNiaW5kKHRpbWUsIHNwaW5lLCBoaXApDQoNCiMgICAgIHRpbWUgc3BpbmUgICBoaXANCiNbMSxdICAgIDAgMC43OTcgMC42NDMNCiNbMixdICAgIDggMC44MDYgMC42MzgNCiNbMyxdICAgMTggMC44MTcgMC42NDgNCiNbNCxdICAgNDggMC44MjUgMC42NzQNCiNbNSxdICAgNjQgMC44MzcgMC42NDANCiNbNixdICAgNjYgMC44NDEgMC42NzYNCiNbNyxdICAgNzkgMC44ODYgMC42NTENCiNbOCxdICAgOTIgMC44ODEgMC42ODANCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgcHJlbGltaW5hcnkgc2NhdHRlcnBsb3RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnBsb3QodGltZSwgc3BpbmUpICMgJ3NwaW5lJyBzY2F0dGVycGxvdDogYm9uZSBkZW5zaXR5IGJ5IHRpbWUNCnBsb3QodGltZSwgaGlwKSAgICMgJ2hpcCcgICBzY2F0dGVycGxvdDogICAiICAgICIgICAgICIgICAiDQoNCiMgYm90aCBsaW5lcyBtdXN0IGZpdCBpbiB0aGUgc2FtZSBncmFwaCwgc28gZ2V0IGdsb2JhbCBtaW4sbWF4IGZvciB5DQpyYW5nZShjKHNwaW5lLCBoaXApKSAgIyBtaW4sIG1heDogLjYzOCB0byAuODg2DQoNCiMgbWluaW1hbCBncmFwaCBhcyBwcm9vZiBvZiBjb25jZXB0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCnBsb3QodGltZSwgc3BpbmUsIHR5cGU9ImIiLCB5bGltPXJhbmdlKGMoc3BpbmUsIGhpcCkpKSAjIHNwaW5lIGRhdGENCnBvaW50cyh0aW1lLCBoaXAsIHR5cGU9ImIiLCBwY2g9MTYpICAgICAgICAgICAgICAgICAgICAjIGFkZCBoaXAgZGF0YQ0KDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBFbmhhbmNlZCwgcG9pbnQgYW5kIGxpbmUgZ3JhcGg6IDIgc2V0cyBvZiB4LHkgcG9pbnRzIC0tLS0tLS0tLS0tLS0tDQojICAgd2l0aCBlYWNoIGxpbmUgbGFiZWxlZCB3aXRoaW4gdGhlIGdyYXBoICAgIA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnBsb3QodGltZSwgc3BpbmUsIA0KICBjb2w9ImJsYWNrIiwgICMgY29sb3Igb2YgcG9pbnRzOyBkZWZhdWx0LCBjb2w9ImJsYWNrIg0KICBjZXg9MSwgICAgICAgICMgc2l6ZSBvZiBzeW1ib2wgcGxvdHRlZDsgZGVmYXVsdCwgY2V4PTENCiAgeWxpbT1yYW5nZShjKHNwaW5lLCBoaXApKSwgICMgYWRqdXN0IHktYXhpcyByYW5nZQ0KICB4bGltPWMoLTUsIDEwMCksICAgICAgICAgICAgIyAgICIgICAgeC1heGlzICAiDQogIGxhcz0wLCAgICAgICMgZmxpcCB5LWF4aXMgdGljayBsYWJlbHMsIGxhcz0xOyBkZWZhdWx0OiBsYXM9MA0KICB0eXBlPSJiIiwgICAjIGRlZmF1bHQ6IHR5cGU9InAiIHBvaW50cyBvbmx5OyAiYiIgYm90aDsgImwiIGxpbmUgb25seTsgIm4iLCAiaCIgDQogIG1haW49IkJvbmUgZGVuc2l0eSB3aXRoIEFsZW5kcm9uYXRlIHRyZWF0bWVudFxuNjUgeWVhciBvbGQgZmVtYWxlIHBhdGllbnQiLA0KICB4bGFiPSJUaW1lIGZyb20gQmFzZWxpbmUsIG1vbnRocyIsIA0KICB5bGFiPSJCb25lIERlbnNpdHksIGcvY21eMiIsIA0KICBmb250LmxhYj0yLCBjZXgubGFiPTEuNCwgY2V4LmF4aXM9MS4yLCAgIyBsYWJlbCAmIGF4aXMgdHlwb2dyYXBoeQ0KICBjZXgubWFpbj0xLjgsIGNvbC5tYWluPSJkYXJrcmVkIiAgICAgICAjIHRpdGxlIHR5cG9ncmFwaHkNCikNCg0KIyBhZGQgMm5kIHNldCBvZiBwb2ludHMgd2l0aCBjb25uZWN0aW5nIGxpbmUgLS0tLS0tLS0NCnBvaW50cyh0aW1lLCBoaXAsIHBjaD0xNiwgdHlwZT0iYiIpDQoNCiMgbGFiZWwgZWFjaCBsaW5lIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KdGV4dCgyMCwgLjg1LCAiTHVtYmFyIFNwaW5lIiwgZm9udD0xLCBjZXg9MS4yLCBjb2w9ImRhcmtyZWQiKQ0KdGV4dCgyMCwgLjY5LCAiVGVtcG9yYWwgTmVjayAoaGlwKSIsIGZvbnQ9MSwgY2V4PTEuMiwgY29sPSJkYXJrcmVkIikNCg0KIyBhZGQgcGVyc29uYWxpemVkIHRpbWUgc3RhbXA7IGdvb2QgZm9yIHByZXNlbnRhdGlvbiBxdWFsaXR5IGdyYXBoIC0tLS0tLS0tLQ0KbXRleHQocGFzdGUoIkFybG86ICIsIGRhdGUoKSksIHNpZGU9MSwgYWRqPTEsIGxpbmU9NCwgY2V4PS44LCBjb2w9ImdyYXkiKQ0KDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEVuaGFuY2VkIEdSQVBILCB1c2luZyBsZWdlbmQoKSAgLS0gdXNlIG9mIGxlZ2VuZCgpIGlzIE9QVElPTkFMIGluIEJpbyAyNDAgLS0tDQojICAgQlVULCBhZGRpbmcgbGFiZWxzIHdpdGhpbiBncmFwaHMgYW5kIGluIGdyYXBoIG1hcmdpbnMsIGlzIHJlcXVpcmVkDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpjeDEgPC0gMS42OyBjeDIgPC0gMS4yOyBjeDMgPC0gMS44ICAjIHZhcnMgZm9yIHR5cG9ncmFwaHkgY29udmVuaWVuY2UNCmMxIDwtICJkYXJrcmVkIg0KDQpwbG90KHRpbWUsIHNwaW5lLA0KICB0eXBlPSJiIiwgDQogIGJ0eT0ibCIsICAjIHR5cGUgb2YgJ2JveCc7IGRlZmF1bHQ6ICJvIiwgImwiLCAiNyIsICJjIiwgInUiLCAiXSIgIA0KICB5bGltPWMoLjYyLCAuOSksICAgIyB4LWF4aXMgcmFuZ2UNCiAgeGxpbT1jKC01LCAxMDApLCAgICMgeS1heGlzIHJhbmdlDQogIGNleD0xLjQsIGNleC5sYWI9Y3gxLCBjZXguYXhpcz1jeDIsIGZvbnQubGFiPTEsICMgdHlwb2dyYXBoeQ0KICBjZXgubWFpbj1jeDMsIGNvbC5tYWluPWMxLCBjb2wubGFiPWMxLCAgICAgICAgICAjIHR5cG9ncmFwaHkNCiAgeGxhYj0iVGltZSBmcm9tIEJhc2VsaW5lLCBtb250aHMiLA0KIA0KICB5bGFiPSIiLCAgICMgdHVybi1vZmYgeS1heGlzIGxhYmVsIGlmIGRvaW5nIGl0IGJ5IG10ZXh0KCkNCiAgI3lsYWI9IkJvbmUgRGVuc2l0eSwgZy9jbV4yIiwgDQogICN5bGFiPWV4cHJlc3Npb24oIkJvbmUgRGVuc2l0eSwgZy9jbSIgXjIpLA0KDQogIG1haW49IkJvbmUgZGVuc2l0eSB3aXRoIEFsZW5kcm9uYXRlIHRyZWF0bWVudFxuNjUgeWVhciBvbGQgZmVtYWxlIHBhdGllbnQiDQogICNtYWluPSI2NSAgeWVhciAgb2xkICBmZW1hbGUgIHBhdGllbnQiLCBjZXgubWFpbj1jeDMNCikNCg0KIyB1c2UgbXRleHQoKSBmb3IgeS1heGlzIGxhYmVsIHRvIGRlYWwgd2l0aCBjcm93ZGluZyBpc3N1ZSANCm10ZXh0KGV4cHJlc3Npb24oIkJvbmUgRGVuc2l0eSwgZy9jbSIgXiAyKSwgc2lkZT0yLA0KICAgICAgbGluZT0yLjMsIGNleD1jeDEsIGNvbD1jMSwgZm9udD0xKQ0KDQpwb2ludHModGltZSwgaGlwLCBwY2g9MTYsIGNleD0xLjQsIHR5cGU9ImIiKSAjIGFkZCBoaXAgeCx5IGRhdGENCm10ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOCwgY29sPSJncmF5IikNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgbGVnZW5kKCkgdGFrZXMgbWFueSBhcmdzIC0tLSBPcHRpb25hbCBpbiBCaW8gMjQwIC0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmxlZ2VuZCh4PTU1LCB5PS43OSwgICAjIHgseSBmb3IgdG9wLWxlZnQgY29ybmVyLCBieSB0cmlhbC1hbmQtZXJyb3INCiAgbGVnZW5kPWMoIkx1bWJhciBTcGluZSIsICJUZW1wb3JhbCBOZWNrIChoaXApIiksIA0KICBwY2g9YygxLCAxNiksIGNleD0xLjIsIHRleHQuZm9udD0zLCBwdC5jZXg9MS41LA0KICB4LmludGVyc3A9MS4zLCB5LmludGVyc3A9MS4yLCB0aXRsZS5jb2w9ImRhcmtyZWQiLA0KICB0aXRsZT0iICBBbGVuZHJvbmF0ZSB0cmVhdG1lbnQgICIpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQUxURVJOQVRJVkUgdG8gbGVnZW5kKCkgLS0gbmljZSBsYWJlbHMgYnkgcG9pbnRzKCkgYW5kIHRleHQoKSAtLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpwbG90KHRpbWUsIHNwaW5lLCBjZXg9MS4yLCB5bGltPWMoLjYsIC45KSwgdHlwZT0iYiIsIGNleC5sYWI9MS4zLA0KICAgICB4bGFiPSJUaW1lIGZyb20gQmFzZWxpbmUsIG1vbnRocyIsIHlsYWI9IkJvbmUgRGVuc2l0eSwgZy9jbV4yIikNCnBvaW50cyh0aW1lLCBoaXAsIGNleD0xLjIsIHBjaD0xNiwgdHlwZT0iYiIgKQ0KDQpwb2ludHMoNjIsIC43OCwgcGNoPTEsIGNleD0xLjUpICAgICAgICAgICAgICAjIHB1dCBsYWJlbA0KdGV4dCg2NCwgLjc4LCAiTHVtYmFyIFNwaW5lIiwgcG9zPTQsIGZvbnQ9MykgIyB3aXRoaW4gZ3JhcGgNCg0KcG9pbnRzKDYyLCAuNzUsIHBjaD0xNiwgY2V4PTEuNSkgICAgICAgICAgICAgIyBsYWJlbA0KdGV4dCg2NCwgLjc1LCAiVGVtcG9yYWwgTmVjayAoaGlwKSIsIHBvcz00LCBmb250PTMpDQoNCiMgYWRkIE9MUyBsaW5lYXIgcmVncmVzc2lvbiBmaXQgd2l0aCBzbG9wZSAmIHAtdmFsdWUgLS0tLS0tLS0tLQ0KDQpzcGluZS5yZWcgPC0gbG0oc3BpbmUgfiB0aW1lKSAjIHBlcmZvcm0gT0xTIGxpbmVhciByZWdyZXNzaW9uLCBzcGluZSBieSB0aW1lDQpoaXAucmVnICAgPC0gbG0oaGlwIH4gdGltZSkgICAjICAiICAgICAgIiAgICAiICAgICAgIiAgICAgICAgLCBoaXAgYnkgdGltZQ0KDQphYmxpbmUoc3BpbmUucmVnLCBjb2w9ImdyYXkiLCBsd2Q9MiwgbHR5PTIpICMgYWRkIGxpbmVhciByZWdyZXNzaW9uIGZpdHMNCmFibGluZShoaXAucmVnLCAgIGNvbD0iZ3JheSIsIGx3ZD0yLCBsdHk9MikNCg0Kc3VtbWFyeShzcGluZS5yZWcpICMgc2xvcGUgLjAwMDg4MDIsIHItc3EgLjg2ICMgaW5zcGVjdCB0aGUgcmVncmVzc2lvbiBvYmplY3QNCnN1bW1hcnkoaGlwLnJlZykgICAjIHNsb3BlIC4wMDAzMTMzLCByLXNxIC4zOCAjICAgIg0KDQojIGFkZCBzdGF0cyB3aXRoaW4gZ3JhcGggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBhZGQgci1zcSUgd2l0aCBjb3JyZWxhdGlvbiBwLXZhbHVlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiN0ZXh0KDEzLCAuODUsICJyLXNxID0gODYlXG5wID0gMC4wMDA0NigxKSIsIGNleD0xKSANCiN0ZXh0KDEzLCAuNjgsICJyLXNxID0gMzglXG5wID0gMC4wNTIoMSkiLCBjZXg9MSkgICANCg0KIyBhZGQgbGluZWFyIHJlZ3Jlc3Npb24gc2xvcGUsIHdpdGggcC12YWx1ZSAtLS0tLS0tLS0tLS0tLS0tLS0gDQojdGV4dCgxMywgLjg1LCAic2xvcGUgPSAuMDAwODgwMiBcbnAgPSAwLjAwMDQ2KDEpIiwgY2V4PTEpIA0KI3RleHQoMTMsIC42OCwgInNsb3BlID0gLjAwMDMxMzMgXG5wID0gMC4wNTIoMSkiLCBjZXg9MSkgICANCg0KIyBhZGQgci1zcSUsIGxpbmVhciByZWdyZXNzaW9uIHNsb3BlLCB3aXRoIHAtdmFsdWUgLS0tLS0tLS0tLS0gDQp0ZXh0KDEzLCAuODYsICJyLXNxID0gODYlXG5zbG9wZSA9IDAuMDAwODgwMlxucCA9IDAuMDAwNDYoMSkiLCBjZXg9MSkgDQp0ZXh0KDEzLCAuNjksICJyLXNxID0gMzglXG5zbG9wZSA9IDAuMDAwMzEzM1xucCA9IDAuMDUyKDEpIiwgY2V4PTEpDQoNCm10ZXh0KHBhc3RlKCJCb25lIGRlbnNpdHkgaW5jcmVhc2VkIHNpZ25pZmljYW50bHkgd2l0aCB0aW1lXG5mb3IgTHVtYmFyIFNwaW5lIiwNCiAgICAgICAgICAgICJidXQgbm90IGZvciBIaXAiKSwgc2lkZT0zLCBsaW5lPTEsIGNleD0xLjUsIGNvbD0iZGFya3JlZCIpDQoNCm10ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOCwgY29sPSJncmF5IikNCg0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBjb25zdHJ1Y3QgZGF0YSBmcmFtZSAgb2YgMTIgcm93cyBieSAzIGNvbHVtbnM6IG1vbnRocywgZGVucywgYm9uZSAtLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpkZW5zIDwtIGMoc3BpbmUsIGhpcCkgIyBjb21iaW5lIHJlc3BvbnNlIHZlY3RvcnMgaW50byBvbmUgbnVtZXJpYyB2ZWN0b3IgDQpib25lIDwtIGMocmVwKCJzcGluZSIsIDgpLCByZXAoImhpcCIsIDgpKSAjIGNyZWF0ZSBtYXRjaGluZywgZ3JvdXBpbmcgdmFyaWFibGUNCg0KIyBjaGFuZ2UgY2hhcmFjdGVyIHZlY3RvciAnYm9uZScgdG8gYSBmYWN0b3INCiMgc3BlY2lmeSBkZXNpcmVkICdvcmRlcicgb2YgZmFjdG9yIGxldmVscw0KYm9uZSA8LSBmYWN0b3IoYm9uZSwgbGV2ZWxzPWMoInNwaW5lIiwgImhpcCIpKQ0KIA0KbW9udGhzIDwtIGModGltZSwgdGltZSkgIyB0aGUgJ21vbnRocycgY29sdW1uOiBudW1lcmljIHZlY3Rvcg0KDQpkZnIgPC0gZGF0YS5mcmFtZShtb250aHMsIGRlbnMsIGJvbmUpICMgYXR0YWNoIHRoZSAzIHZlY3RvcnMgYXMgY29sdW1ucw0KDQpzdHIoZGZyKSAgICAgIyBjaGVja2luZw0Kc3VtbWFyeShkZnIpICMgY2hlY2tpbmcNCmRmciAgICAgICAgICAjIHByaW50IGRhdGEgZnJhbWUNCg0KIyAgIG1vbnRocyAgZGVucyAgYm9uZQ0KIzEgICAgICAgMCAwLjc5NyBzcGluZQ0KIzIgICAgICAgOCAwLjgwNiBzcGluZQ0KIzMgICAgICAxOCAwLjgxNyBzcGluZQ0KIzQgICAgICA0OCAwLjgyNSBzcGluZQ0KIzUgICAgICA2NCAwLjgzNyBzcGluZQ0KIzYgICAgICA2NiAwLjg0MSBzcGluZQ0KIzcgICAgICA3OSAwLjg4NiBzcGluZQ0KIzggICAgICA5MiAwLjg4MSBzcGluZQ0KIzkgICAgICAgMCAwLjY0MyAgIGhpcA0KIzEwICAgICAgOCAwLjYzOCAgIGhpcA0KIzExICAgICAxOCAwLjY0OCAgIGhpcA0KIzEyICAgICA0OCAwLjY3NCAgIGhpcA0KIzEzICAgICA2NCAwLjY0MCAgIGhpcA0KIzE0ICAgICA2NiAwLjY3NiAgIGhpcA0KIzE1ICAgICA3OSAwLjY1MSAgIGhpcA0KIzE2ICAgICA5MiAwLjY4MCAgIGhpcA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIHNvbWUgc3RhdGlzdGljcyBieSBncm91cCwgYnkgc29tZSBSIHByb2dyYW1taW5nIC0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyAgPj90YXBwbHkgICMgZm9yIGRvY3VtZW50YXRpb24gb24gdGhpcyBoYW5keSBmdW5jdGlvbg0KDQpOICAgICAgPC0gdGFwcGx5KGRlbnMsIGJvbmUsIGxlbmd0aCkgIyB2ZWN0b3Igb2Ygc2FtcGxlIHNpemVzIHBlciBncm91cA0KTWVhbiAgIDwtIHRhcHBseShkZW5zLCBib25lLCBtZWFuKSAgICMgbWVhbnMNCk1lZGlhbiA8LSB0YXBwbHkoZGVucywgYm9uZSwgbWVkaWFuKSAjIG1lZGlhbnMNClNEICAgICA8LSB0YXBwbHkoZGVucywgYm9uZSwgc2QpICAgICAjIHN0YW5kYXJkIGRldmlhdGlvbnMNCk1pbiAgICA8LSB0YXBwbHkoZGVucywgYm9uZSwgbWluKSAgICAjIG1pbmltdW0NCk1heCAgICA8LSB0YXBwbHkoZGVucywgYm9uZSwgbWF4KSAgICAjIG1heGltdW0NCg0Kc3BpbmUuciA8LSBjb3IodGltZSwgc3BpbmUpICMgUGVhcnNvbiByLCBzcGluZSBkZW5zaXR5IHZzLiB0aW1lDQpoaXAuciAgIDwtIGNvcih0aW1lLCBoaXApICAgIyBQZWFyc29uIHIsIGhpcCBkZW5zaXR5IHZzLiB0aW1lDQoNCnAuc3BpbmUgPC0gY29yLnRlc3QodGltZSwgc3BpbmUsIGFsdD0iZ3JlYXRlciIpJHAudmFsdWUgIyBwLXZhbHVlIG9mIHIsIG9uZS1zaWRlZA0KcC5oaXAgICA8LSBjb3IudGVzdCh0aW1lLCBoaXAsIGFsdD0iZ3JlYXRlciIpJHAudmFsdWUNCg0KTEIuQ0kuc3BpbmUgPC0gY29yLnRlc3QodGltZSwgc3BpbmUpJGNvbmYuaW50WzFdICMgTEIgOTUlIENJIG9mIHINCkxCLkNJLmhpcCAgIDwtIGNvci50ZXN0KHRpbWUsIGhpcCkkY29uZi5pbnRbMV0NCg0KVUIuQ0kuc3BpbmUgPC0gY29yLnRlc3QodGltZSwgc3BpbmUpJGNvbmYuaW50WzJdICMgVUIgOTUlIENJIG9mIHINClVCLkNJLmhpcCAgIDwtIGNvci50ZXN0KHRpbWUsIGhpcCkkY29uZi5pbnRbMl0NCg0KIyBzdGF0aXN0aWNhbCBwb3dlciBhbmFseXNpcyBieSBwYWNrYWdlICdwd3InIC0tLS0tLS0tLS0tLQ0KIyAncG93ZXIgb2YgdGhlIHRlc3QnIGZvciBzaWduaWYuIG9mIFBlYXJzb24gciBhdCBhbHBoYSAuMDEsIG9uZS1zaWRlZA0KDQpsaWJyYXJ5KHB3cikgIyBzdGF0aXN0aWNhbCBwb3dlciBhbmFseXNpcyBieSBub3JtYWwgdGhlb3J5IGFmdGVyIENvaGVuDQoNCiMgc3RhdGlzdGljYWwgcG93ZXIgb2YgY29yLnRlc3QgYXQgYWxwaGEgLjAxLCBvbmUtc2lkZWQgLS0tLS0tLS0tDQoNCnB3ci5zcGluZSA8LSBwd3Iuci50ZXN0KG49OCwgcj1jb3IodGltZSwgc3BpbmUpLCBzaWcubGV2ZWw9LjAxLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PSJncmVhdGVyIiwgcG93ZXI9TlVMTCkkcG93ZXINCnB3ci5oaXAgPC0gcHdyLnIudGVzdChuPTgsIHI9Y29yKHRpbWUsIGhpcCksIHNpZy5sZXZlbD0uMDEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PSJncmVhdGVyIiwgcG93ZXI9TlVMTCkkcG93ZXINCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIHBvdXIgc3RhdHMgYnkgZ3JvdXAgKHNwaW5lLCBoaXApIGludG8gYSBtYXRyaXggdG8gdmlldyAtLS0tLS0tDQojICAgICB0aGUgTkEgaXMgdGhlcmUganVzdCBhcyBhIHNwYWNlcg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCm1hdCA8LSByYmluZChOLCBNZWFuLCBNZWRpYW4sIFNELCBNaW4sIE1heCwgTkEsICANCiAgICAgICAgICAgICBQZWFyc29uLnI9YyhzcGluZS5yLCBoaXAuciksDQogICAgICAgICAgICAgci5zcS5wZXJjZW50PWMoc3BpbmUuciwgaGlwLnIpXjIqIDEwMCwNCiAgICAgICAgICAgICByLnAudmFsdWUxc2lkZWQ9YyhwLnNwaW5lLCBwLmhpcCksDQogICAgICAgICAgICAgci5MQi45NS5DST1jKExCLkNJLnNwaW5lLCBMQi5DSS5oaXApLA0KICAgICAgICAgICAgIHIuVUIuOTUuQ0k9YyhVQi5DSS5zcGluZSwgVUIuQ0kuaGlwKSwNCiAgICAgICAgICAgICByLnBvd2VyLjAxLm9uZS5zaWRlZD1jKHB3ci5zcGluZSwgcHdyLmhpcCkgKQ0KICAgICAgICAgICAgICANCmNvbG5hbWVzKG1hdCkgPC0gYygiU3BpbmUgYm9uZSBkZW5zaXR5IiwgIiBIaXAgZGVuc2l0eSIpDQpwcmludChmb3JtYXQobWF0LCBzY2llbnRpZmljPUYsIGRpZ2l0cz0zKSwgcXVvdGU9RikNCg0KIyAgICAgICAgICAgICAgICAgICAgIFNwaW5lIGJvbmUgZGVuc2l0eSAgSGlwIGRlbnNpdHkNCiNOICAgICAgICAgICAgICAgICAgICAgOC4wMDAwMDAgICAgICAgICAgIDguMDAwMDAwICAgDQojTWVhbiAgICAgICAgICAgICAgICAgIDAuODM2MjUwICAgICAgICAgICAwLjY1NjI1MA0KI01lZGlhbiAgICAgICAgICAgICAgICAwLjgzMTAwMCAgICAgICAgICAgMC42NDk1MDAgICAgDQojU0QgICAgICAgICAgICAgICAgICAgIDAuMDMyNjMxICAgICAgICAgICAwLjAxNzQ3NCAgIA0KI01pbiAgICAgICAgICAgICAgICAgICAwLjc5NzAwMCAgICAgICAgICAgMC42MzgwMDAgICANCiNNYXggICAgICAgICAgICAgICAgICAgMC44ODYwMDAgICAgICAgICAgIDAuNjgwMDAwICAgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BICAgICAgICAgICAgICAgICBOQSAgIA0KI1BlYXJzb24uciAgICAgICAgICAgICAwLjkyNzIzNiAgICAgICAgICAgMC42MTYyODMgICANCiNyLnNxLnBlcmNlbnQgICAgICAgICA4NS45NzY3MjAgICAgICAgICAgMzcuOTgwNTMzICAgDQojci5wLnZhbHVlMXNpZGVkICAgICAgIDAuMDAwNDU2ICAgICAgICAgICAwLjA1MTg1OCAgIA0KI3IuTEIuOTUuQ0kgICAgICAgICAgICAwLjY0MjEzMCAgICAgICAgICAtMC4xNTYyNDIgICANCiNyLlVCLjk1LkNJICAgICAgICAgICAgMC45ODcwMDMgICAgICAgICAgIDAuOTIwOTkwICAgDQojci5wb3dlci4wMS5vbmUuc2lkZWQgIDAuOTIyNjcyICAgICAgICAgICAwLjI0NzYwMSAgICANCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIHR3by13YXkgQU5PVkEgdG8gY29tcGFyZSB0aGUgbWVhbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KYW5vdmEobG0oZGVucyB+IGJvbmUgKyBmYWN0b3IobW9udGhzKSwgZGF0YT1kZnIpKSAjIHR3by13YXkgQU5PVkEsIG5vIGludGVyYWN0aW9uDQoNCiNSZXNwb25zZTogZGVucw0KIyAgICAgICAgICAgICAgIERmICAgU3VtIFNxICBNZWFuIFNxICBGIHZhbHVlICAgIFByKD5GKSAgICANCiNib25lICAgICAgICAgICAgMSAwLjEyOTYwMCAwLjEyOTYwMCAzMTQuODkwNyA0LjQ1MWUtMDcgDQojZmFjdG9yKG1vbnRocykgIDcgMC4wMDY3MTAgMC4wMDA5NTkgICAyLjMyOTEgICAgMC4xNDM2ICAgIA0KI1Jlc2lkdWFscyAgICAgICA3IDAuMDAyODgxIDAuMDAwNDEyICAgDQogDQojIGNvbXBhcmlzb24gb2YgbWVhbiwgc3BpbmUgZGVuc2l0eSB2cy4gaGlwOiBkaWZmPSAtLjE4LCBwPTQuNDVlLTcNCiMgY29tcGFyaXNvbnMgb2YgbWVhbiBkZW5zaXR5IGF0IG1vbnRoIDAsIGFnYWluc3QgdGhlIG90aGVyIG1vbnRocw0KIyAgICAgICBtZWFuIGRlbnNpdHksIG9ubHkgZGlmZmVyZW50IGZyb20gdGltZSB6ZXJvLCAgDQojICAgICAgICAgICAgICBhdCA3OSBtb250aHMsIHA9LjA0OCAmIDkyIG1vbnRocywgcD0uMDIxDQoNCnN1bW1hcnkobG0oZGVucyB+IGJvbmUgKyBmYWN0b3IobW9udGhzKSwgZGF0YT1kZnIpKQ0KI0NvZWZmaWNpZW50czoNCiMgICAgICAgICAgICAgICAgIEVzdGltYXRlIFN0ZC4gRXJyb3IgdCB2YWx1ZSBQcig+fHR8KSAgICANCiMoSW50ZXJjZXB0KSAgICAgICAwLjgxMDAwICAgIDAuMDE1MjEgIDUzLjIzNSAyLjE2ZS0xMCANCiNib25laGlwICAgICAgICAgIC0wLjE4MDAwICAgIDAuMDEwMTQgLTE3Ljc0NSA0LjQ1ZS0wNyAgPC0gaGlnaGx5IHNpZ25pZmljYW50IA0KI2ZhY3Rvcihtb250aHMpOCAgIDAuMDAyMDAgICAgMC4wMjAyOSAgIDAuMDk5ICAgMC45MjQyICAgIA0KI2ZhY3Rvcihtb250aHMpMTggIDAuMDEyNTAgICAgMC4wMjAyOSAgIDAuNjE2ICAgMC41NTczICAgIA0KI2ZhY3Rvcihtb250aHMpNDggIDAuMDI5NTAgICAgMC4wMjAyOSAgIDEuNDU0ICAgMC4xODkyICAgIA0KI2ZhY3Rvcihtb250aHMpNjQgIDAuMDE4NTAgICAgMC4wMjAyOSAgIDAuOTEyICAgMC4zOTIxICAgIA0KI2ZhY3Rvcihtb250aHMpNjYgIDAuMDM4NTAgICAgMC4wMjAyOSAgIDEuODk4ICAgMC4wOTk1ICAgDQojZmFjdG9yKG1vbnRocyk3OSAgMC4wNDg1MCAgICAwLjAyMDI5ICAgMi4zOTEgICAwLjA0ODEgIDwtIGJhcmVseSBzaWduaWZpY2FudA0KI2ZhY3Rvcihtb250aHMpOTIgIDAuMDYwNTAgICAgMC4wMjAyOSAgIDIuOTgyICAgMC4wMjA1ICA8LSBzaWduaWZpY2FudA0KDQoNCiMgZWZmZWN0IG9uIHR3by13YXkgQW5vdmEsIG9mIHJlbW92YWwgb2YgdGhlIGxhc3QgZGF0YSBwb2ludDogbW9udGggOTIgIC0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIGRmcltjKC04LCAtMTYpLCBdICAgd2lsbCBkZWxldGUgcm93IDggYW5kIDE2LCBhbmQgcmV0dXJuIGFsbCAzIGNvbHVtbnMNCg0KIyByPSAuODk3NDUsIHA9IC4wMDMwNTgoMSkgICAgIDw8IHNwaW5lID4+DQpjb3IudGVzdCh+IGRlbnMgKyBtb250aHMsIGRhdGE9ZGZyW2MoLTgsIC0xNiksIF0sIHN1YnNldD1ib25lPT0ic3BpbmUiLCBhbHQ9ImdyZWF0ZXIiKSANCg0KIyByPSAuNDU4NywgcD0gLjE1MDMoMSkgICAgICAgIDw8ICBoaXAgID4+DQpjb3IudGVzdCh+IGRlbnMgKyBtb250aHMsIGRhdGE9ZGZyW2MoLTgsIC0xNiksIF0sIHN1YnNldD1ib25lPT0iaGlwIiwgIGFsdD0iZ3JlYXRlciIpIA0KDQphbm92YShsbShkZW5zIH4gYm9uZSArIGZhY3Rvcihtb250aHMpLCBkYXRhPWRmcltjKC04LCAtMTYpLCBdKSkgIyB0d28td2F5IEFOT1ZBIG5vIGludGVyYWN0aW9uDQoNCiNSZXNwb25zZTogZGVucw0KIyAgICAgICAgICAgICAgIERmICAgU3VtIFNxICBNZWFuIFNxICBGIHZhbHVlICAgIFByKD5GKSAgICANCiNib25lICAgICAgICAgICAgMSAwLjEwOTY1MSAwLjEwOTY1MSAyNTAuMjUwNyA0LjA0N2UtMDYgKioqDQojZmFjdG9yKG1vbnRocykgIDYgMC4wMDQwMjkgMC4wMDA2NzEgICAxLjUzMjQgICAgMC4zMDg2ICAgIA0KI1Jlc2lkdWFscyAgICAgICA2IDAuMDAyNjI5IDAuMDAwNDM4ICAgICAgICAgICANCg0Kc3VtbWFyeShsbShkZW5zIH4gYm9uZSArIGZhY3Rvcihtb250aHMpLCBkYXRhPWRmcltjKC04LCAtMTYpLCBdKSkNCg0KIyBjb21wYXJpc29ucyBvZiBtZWFuIGRlbnNpdHkgYXQgdGltZSAwLCBhZ2FpbnN0IHRpbWVzOiA4LDE4LDQ4LDY0LDY2LDc5DQojICAgICAgIG1lYW4gZGVuc2l0eSBhdCAwIG1vbnRocyBub3QgZGlmZmVyZW50IGZyb20gb3RoZXIgbW9udGhzDQoNCiNDb2VmZmljaWVudHM6DQojICAgICAgICAgICAgICAgICBFc3RpbWF0ZSBTdGQuIEVycm9yIHQgdmFsdWUgUHIoPnx0fCkgICAgDQojKEludGVyY2VwdCkgICAgICAgMC44MDg1MCAgICAwLjAxNTgyICA1MS4wOTUgMy43N2UtMDkgDQojYm9uZWhpcCAgICAgICAgICAtMC4xNzcwMCAgICAwLjAxMTE5IC0xNS44MTkgNC4wNWUtMDYgIDwtIGhpZ2hseSBzaWduaWZpY2FudA0KI2ZhY3Rvcihtb250aHMpOCAgIDAuMDAyMDAgICAgMC4wMjA5MyAgIDAuMDk2ICAgMC45MjcwICAgIA0KI2ZhY3Rvcihtb250aHMpMTggIDAuMDEyNTAgICAgMC4wMjA5MyAgIDAuNTk3ICAgMC41NzIyICAgIA0KI2ZhY3Rvcihtb250aHMpNDggIDAuMDI5NTAgICAgMC4wMjA5MyAgIDEuNDA5ICAgMC4yMDg0ICAgIA0KI2ZhY3Rvcihtb250aHMpNjQgIDAuMDE4NTAgICAgMC4wMjA5MyAgIDAuODg0ICAgMC40MTA4ICAgIA0KI2ZhY3Rvcihtb250aHMpNjYgIDAuMDM4NTAgICAgMC4wMjA5MyAgIDEuODM5ICAgMC4xMTU1ICAgIA0KI2ZhY3Rvcihtb250aHMpNzkgIDAuMDQ4NTAgICAgMC4wMjA5MyAgIDIuMzE3ICAgMC4wNTk3ICA8LSBub3Qgc2lnbmlmaWNhbnQgDQoNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBpcyBzcGluZSBkZW5zaXR5IGNvcnJlbGF0ZWQgd2l0aCBoaXAgZGVuc2l0eSBmb3IgdGhpcyAtLS0tLS0tLS0tLS0tLS0tLS0tDQojICAgIDY1IHlyLiBvbGQgZmVtYWxlIHBhdGllbnQsIGFjcm9zcyB0aGUgOTIgbW9udGggcGVyaW9kPw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpwbG90KHNwaW5lLCBoaXApDQpsaW5lcyhsb3dlc3Moc3BpbmUsIGhpcCksIGNvbD0icmVkIiwgdHlwZT0ibCIpDQpjb3IudGVzdChzcGluZSwgaGlwKSAjIHI9IC40Nzk2ICBwPSAuMjI5MSgyKSANCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgVklTVUFMSVpBVElPTiBvZiBQZWFyc29uIHIgd2l0aCA5NSUgQ0ksIGZvciANCiMgICAgICAgICAgICAgICBzcGluZSBhbmQgaGlwLCBib25lIGRlbnNpdHkgYnkgdGltZSBkYXRhDQojIA0KIyBOT1RJQ0UgdGhhdCBieSBjb3IudGVzdCgpIHRoZSB0cmFkaXRpb25hbCA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMgb2YgDQojIFBlYXJzb24gciwgb3ZlcmxhcCBjb25zaWRlcmFibHkuIFRoaXMgaW5kaWNhdGVzIHRoZSB0d28gY29ycmVsYXRpb25zIGFyZQ0KIyBub3Qgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQuIA0KIw0KIyBBTkQsIGR1ZSB0byBzbWFsbCBzYW1wbGUgc2l6ZSwgYm90aCA5NSUgQ0lzIGFyZSB2ZXJ5IHdpZGUuICANCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgYSBkcmFmdCBxdWFsaXR5IHBsb3QgdG8gdmlzdWFsaXplIHRoZSAyIFBlYXJzb24gciB2YWx1ZXMgDQojIHdpdGggdGhlaXIgdHJhZGl0aW9uYWwgbG93ZXIgYW5kIHVwcGVyIGJvdW5kIG9mIDk1JSBDSXMNCg0KIyB0d28tc2lkZWQgY29yLnRlc3QoKSBqdXN0IGZvciA5NSUgQ0kgb2YgUGVhcnNvbiByIC0tIGNvbnZlbnRpb25hbCB3YXkNCiMgdGhlIDIgUGVhcnNvbiA5NSUgQ0lzIG92ZXJsYXAhDQoNCkxCLkNJLnNwaW5lIDwtIGNvci50ZXN0KHRpbWUsIHNwaW5lKSRjb25mLmludFsxXSAgIyBzcGluZSA5NSUgQ0k9LjY0MiwgLjk4Nw0KVUIuQ0kuc3BpbmUgPC0gY29yLnRlc3QodGltZSwgc3BpbmUpJGNvbmYuaW50WzJdDQogDQpMQi5DSS5oaXAgPC0gY29yLnRlc3QodGltZSwgaGlwKSRjb25mLmludFsxXSAgIyBoaXAgOTUlIENJPSAtLjE1NiwgLjkyMQ0KVUIuQ0kuaGlwIDwtIGNvci50ZXN0KHRpbWUsIGhpcCkkY29uZi5pbnRbMl0NCg0Kc3BpbmUuciA8LSBjb3IodGltZSwgc3BpbmUpDQpoaXAuciAgIDwtIGNvcih0aW1lLCBoaXApDQoNCiMgcHJlcGFyZSB2ZWN0b3JzIGZvciBzdHJpcGNoYXJ0KCkgZ3JhcGggDQojICAgb2YgdGhlIDIgciB2YWx1ZXMgdy85NSUgQ0lzICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KeSAgICAgPC0gYyhjb3Ioc3BpbmUsIHRpbWUpLCBjb3IoaGlwLCB0aW1lKSkNCmdyb3VwIDwtIGMoIlNwaW5lIiwgIkhpcCIpDQpncm91cCA8LSBmYWN0b3IoZ3JvdXAsIGxldmVscz1jKCJTcGluZSIsICJIaXAiKSkNCg0Kc3RyaXBjaGFydCh5IH4gZ3JvdXAsIHZlcnRpY2FsPVRSVUUsIA0KICB4bGltPWMoLjIsIDIuOCksIHlsaW09YygtLjE1LCAxKSwgcGNoPTE2LCBjZXg9MiwgDQogIHhsYWI9IkJvbmUgTWluZXJhbCBEZW5zaXR5IiwgeWxhYj0iUGVhcnNvbiBjb3JyZWxhdGlvbiIsDQogIGNleC5sYWI9MS4zLCBjZXguYXhpcz0xLjMsIGNleC5tYWluPTEuNSwgDQogIG1haW49IlBlYXJzb24gciB3aXRoIHRyYWRpdGlvbmFsLCA5NSUgQ29uZmlkZW5jZSBpbnRlcnZhbHMiKQ0KDQpsaW5lcyh4PWMoMSwxKSwgeT1jKExCLkNJLnNwaW5lLCBVQi5DSS5zcGluZSksIGx3ZD0zLCBjb2w9ImxpZ2h0Ymx1ZSIpIA0KbGluZXMoeD1jKDIsMiksIHk9YyhMQi5DSS5oaXAsIFVCLkNJLmhpcCksIGx3ZD0zLCBjb2w9ImxpZ2h0Ymx1ZSIpIA0KcG9pbnRzKGMoMSwyKSwgYyhzcGluZS5yLCBoaXAuciksIHBjaD0xNiwgY2V4PTIpICMgaW50ZW50aW9uYWwgb3ZlcnBsb3QNCg0KYWJsaW5lKGg9YygwLDEpLCBsdHk9MikgIyBhZGQgaG9yaXpvbnRhbCBkb3R0ZWQgbGluZXMgYXQgcj0xLCByPTAgLS0tLS0tLS0tIA0KDQptdGV4dCgiU1BJTkUgYm9uZSBkZW5zaXR5XG5ieSB0aW1lLCBuPTgiLCBsaW5lPS0zLjksIGFkaj0uMDMsIGNleD0xLCBjb2w9InJlZCIpIA0KbXRleHQoIkhJUCBib25lIGRlbnNpdHlcbmJ5IHRpbWUsIG49OCIsIGxpbmU9LTEwLCBhZGo9Ljk1LCBjZXg9MSwgY29sPSJyZWQiKSANCg0KdGV4dCgxLjc2LCBjKGhpcC5yLCBVQi5DSS5oaXAsIExCLkNJLmhpcCksIA0KICBjKHJvdW5kKGhpcC5yLDMpLCByb3VuZChVQi5DSS5oaXAsMyksIHJvdW5kKExCLkNJLmhpcCwzKSksIGNleD0xLjIpDQoNCnRleHQoMS4yNCwgYyhzcGluZS5yLCBVQi5DSS5zcGluZSwgTEIuQ0kuc3BpbmUpLCANCiAgYyhyb3VuZChzcGluZS5yLDMpLCByb3VuZChVQi5DSS5zcGluZSwzKSwgcm91bmQoTEIuQ0kuc3BpbmUsMykpLCBjZXg9MS4yKQ0KDQp0ZXh0KC42LCAuMjIsIHBhc3RlKCJWaXN1YWxpemF0aW9uIG9mIHRoZVxuMiBjb3JyZWxhdGlvbnMgd2l0aCA5NSUgQ0lzIiwgDQogICJcbmJ5IEZpc2hlcidzIFogdHJhbnNmb3JtXG5hbmQgdC1kaXN0cmlidXRpb24iKSwgY29sPSJncmF5Iiwgc3J0PTQ1KQ0KDQp0ZXh0KDEuNSwgLjIyLCBwYXN0ZSgiTm90ZSB0aGUgd2lkZSB3aWR0aCBvZiBlYWNoIENJXG4iLA0KICAiYW5kIGhvdyBtdWNoIHRoZVxuMiBDb25maWRlbmNlIEludGVydmFsc1xub3ZlcmxhcCIpLCBjb2w9ImdyYXkiLCBzcnQ9NDUpDQoNCnRleHQoMi41LCAtLjAxLCAiemVybyBjb3JyZWxhdGlvbiIsIGNvbD0iZ3JheSIsIGNleD0uOCkNCnRleHQoMi41LCAuOTksICJwZXJmZWN0LCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiIsIGNvbD0iZ3JheSIsIGNleD0uOCkNCg0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBQRVJNVVRBVElPTiB0ZXN0IGZvciBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIDIgUGVhcnNvbiBDT1JSRUxBVElPTlMgDQojICAgICAgZm9yIFNQSU5FIHZzLiBISVAgYm9uZSBkZW5zaXR5IGJ5IHRpbWUNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgVmFyaW91cyBmb3JtYWwgdGVzdHMgZm9yIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gUGVhcnNvbiByIHZhbHVlcyBhcmUgDQojIGZvdW5kIGFuZCBhcmd1ZWQgYWJvdXQgaW4gdGV4dGJvb2tzLiBCdXQsIHRoaXMgc21hbGwgc2FtcGxlIGlzIGlkZWFsIA0KIyBmb3IgYSBwZXJtdXRhdGlvbiB0ZXN0IHdoaWNoIGlmIGRvbmUgcHJvcGVybHksIGlzIHVuYXNzYWlsYWJsZS4gICAgDQoNCiMgLjMxMDk1MjgsIG91ciB0ZXN0IHN0YXQsIGRlbHRhIFBlYXJzb24ncywgc3BpbmUuciBtaW51cyBoaXAucg0KZGlmZiA8LSBjb3Ioc3BpbmUsIHRpbWUpIC0gY29yKGhpcCwgdGltZSkgDQoNCiMgZ2V0IHN0YW5kYXJkIG5vcm1hbCBkZXZpYXRlcyBpbmRlcGVuZGVudGx5IGZvciBlYWNoIHNhbXBsZSwgc3BpbmUgJiBoaXANCmRlbnNaIDwtIGMoKHNwaW5lIC0gbWVhbihzcGluZSkpL3NkKHNwaW5lKSwgKGhpcCAtIG1lYW4oaGlwKSkvc2QoaGlwKSkgDQpkZW5zWg0KDQpkaWZmIDwtIGNvcih0aW1lLCBkZW5zWlsxOjhdKSAtIGNvcih0aW1lLCBkZW5zWls5OjE2XSkNCg0KIyB0aGUgMiByIHZhbHVlcyBhbmQgJ2RpZmYnIGFyZSB0aGUgc2FtZSBidXQgbm93IGRhdGEgYXMgWiBzY29yZXMsIA0KIyBpcyBvbiB0aGUgc2FtZSBzY2FsZSBmb3IgYm90aCBzcGluZSBhbmQgaGlwICANCg0KIyB0aGUgcmVwbGljYXRlKCkgZnVuY3Rpb24gaXMgdGhlIGxvb3AgaXRlcmF0b3IgLS0tLS0tLS0tLS0tLS0tLQ0KIyB2ZWN0b3JzIGZvciByZXBsaWNhdGUoKSAtLSANCiMgICAgICAndGltZScgIGlzIG49OCwgIDAgdG8gOTIgbW9udGhzDQojICAgICAgJ2RlbnpaJyBpcyBuPTE2OyBuPTggc3BpbmUsIG49OCBoaXAgZGVuc2l0eQ0KIw0KIyAgd2UgIGluZGV4IGRlbnNaWzE6OF0gZm9yIHNwaW5lDQojICAgICAgaW5kZXggZGVuc1pbOToxNl0gZm9yIGhpcA0KDQoNCiMgbnVtYmVyIG9mIHBlcm11dGF0aW9ucyAoc2h1ZmZsZXMpIG9mIGdsb2JhbCAnZGVuc1onIC0tIHN0YXJ0IGxvdywgZ28gaGlnaA0KTlMgPC0gMWU1ICANCg0KdGltZXIgPC0gcHJvYy50aW1lKClbWzNdXSAgIyBpbml0aWFsaXplIHRpbWVyIGZvciAncmVwbGljYXRlJyBsb29wOyBncmFicyBjdXJyZW50IHRpbWUNCg0KbnVsbC5kaWZmIDwtIHJlcGxpY2F0ZShOUywgDQogICAgICAgICAgICAge2RlbnNaIDwtIHNhbXBsZShkZW5zWik7IGNvcih0aW1lLCBkZW5zWlsxOjhdKSAtIGNvcih0aW1lLCBkZW5zWls5OjE2XSl9KQ0KDQp0aW1lciA8LSBwcm9jLnRpbWUoKVtbM11dIC0gdGltZXIgIyB0b3RhbCBzZWNvbmRzIGVsYXBzZWQgYnkgcmVwbGljYXRlKCkgbG9vcA0KdGltZXIgIyBzZWNvbmRzIHJlcXVpcmVkDQoNCiMgcXVlcnkgdGhlICdudWxsLmRpZmYnIHZlY3RvciBmb3IgaG93IG1hbnkgYXJlID49IHRvIHRlc3Qgc3RhdCwgJ2RpZmYnIC0tLS0tDQoNCk5HRTEgPC0gbGVuZ3RoKG51bGwuZGlmZltudWxsLmRpZmYgPj0gZGlmZl0pICAjIG9uZS1zaWRlZCBOR0UsIG51bWJlciBncmVhdGVyID49IHRvIGRpZmYNCnAxICAgPC0gKE5HRTEgKyAxKS8oTlMgKyAxKSAgICAgICAgICAgICAgICAgICAjIG9uZS1zaWRlZCBwLXZhbHVlIGZvciBkaWZmZXJlbmNlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBiZXR3ZWVuIHRoZSB0d28sIHIgdmFsdWVzDQoNCk5HRTIgPC0gbGVuZ3RoKG51bGwuZGlmZlthYnMobnVsbC5kaWZmKSA+PSBhYnMoZGlmZildKSAjIHR3by1zaWRlZCBOR0UNCnAyICAgPC0gKE5HRTIgKyAxKS8oTlMgKyAxKSAjIHR3by1zaWRlZCAgICAgICAgICAgICAgICAjIHR3by1zaWRlZCBwLXZhbHVlDQoNCm1haW4uc3RyaW5nIDwtIHBhc3RlKCJEaXN0cmlidXRpb24gb2YgUGVhcnNvbiBjb3JyZWxhdGlvbiAnZGlmZmVyZW5jZSciLA0KICAgICAgICAgICAgICAgICAgICAgIihzcGluZSByIC0gaGlwIHIpXG4iLA0KICAgICAgICAgICAgICAgICAgICAgInVuZGVyIGdsb2JhbCBwZXJtdXRhdGlvbiBvZiBib25lIGRlbnNpdHkgWi1zY29yZXMiKQ0KDQojIHZpc3VhbGl6ZSB0aGUgbnVsbCBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW5jZSANCiMgYmV0d2VlbiB0aGUgdHdvIGNvcnJlbGF0aW9ucywgdW5kZXIgcGVybXV0YXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpoaXN0KG51bGwuZGlmZiwgDQogIG1haW49bWFpbi5zdHJpbmcsDQogIGNvbD0ibGlnaHRibHVlIiwgeGxpbT1yYW5nZShudWxsLmRpZmYpLCANCiAgYm9yZGVyPSJ3aGl0ZSIsDQogIHhsYWI9Ik51bGwgZGlmZmVyZW5jZSBiZXR3ZWVuIGNvcnJlbGF0aW9ucyIsDQogIGNleC5sYWI9MS4zKQ0KDQphYmxpbmUodj1kaWZmLCBjb2w9InJlZCIsIGx3ZD0zKQ0KbXRleHQocGFzdGUoIlRlc3QgU3RhdGlzdGljOiAgc3BpbmUgciAtIGhpcCByICA9ICIsIHJvdW5kKGRpZmYsNSkpLCANCiAgICAgIGxpbmU9LS41LCBhZGo9LjAxKQ0KbXRleHQocGFzdGUoIk5TID0iLCBOUywgInBlcm11dGF0aW9ucyIpLCBsaW5lPS0xLjcsIA0KICAgICAgYWRqPS4wNSwgY2V4PTEsIGZvbnQ9MiwgY29sPSJibHVlIikNCg0KbXRleHQoIlBlYXJzb24gY29ycmVsYXRpb24gZm9yXG5ib25lIGRlbnNpdHkgYnkgbW9udGhzIiwgDQogICAgICAgbGluZT0tNS4zLCBhZGo9LjA1LCBjb2w9ImJsdWUiKQ0KbXRleHQoInNwaW5lOiAgciA9IDAuOTI3IiwgbGluZT0tNywgYWRqPS4xLCBjb2w9ImJsdWUiKQ0KbXRleHQoImhpcDogIHIgPSAwLjYxNiIsICAgbGluZT0tOCwgYWRqPS4xMzIsIGNvbD0iYmx1ZSIpDQoNCm10ZXh0KHBhc3RlKCJwID0iLCBzaWduaWYocDEsNCksICIoMSksIE5HRSA9IiwgTkdFMSksIGxpbmU9LTEsIGFkaj0uOTUpDQptdGV4dChwYXN0ZSgicCA9Iiwgc2lnbmlmKHAyLDQpLCAiKDIpLCBOR0UgPSIsIE5HRTIpLCBsaW5lPS0yLCBhZGo9Ljk1KQ0KbXRleHQoInAgPSAoTkdFICsgMSkgLyAoTlMgKyAxKSIsIGxpbmU9LTMuNSwgYWRqPS45NSkNCg0KbXRleHQoIjwgUGVybXV0YXRpb24gVGVzdCA+IiwgbGluZT0tNi41LCBhZGo9MSwgZm9udD0yLCBjb2w9ImJsdWUiKQ0KbXRleHQoIm51bGwgaHlwb3RoZXNpczpcbnNwaW5lIHIgID0gIGhpcCByIiwgbGluZT0tOSwgYWRqPTEsIGNvbD0iYmx1ZSIpDQptdGV4dCgiYWx0ZXJuYXRlIGh5cG90aGVzZXM6XG5zcGluZSByICA9ICBoaXAgclxuc3BpbmUgciAgPiBoaXAgciIsIA0KICAgICAgbGluZT0tMTIuNSwgYWRqPTEsIGNvbD0iYmx1ZSIpDQoNCm10ZXh0KCJGb3IgTlMgLS1cbnN0YXJ0IGxvdywgZ28gaGlnaA0KICAgICAgdGhlbiBjaGVjayBmb3JcbnN0YWJpbGl0eSBvZiBwLXZhbHVlDQogICAgICBpbiByZXBlYXRlZCBydW5zIiwNCiAgICAgIGxpbmU9LTIwLCBhZGo9MSwgY2V4PS44LCBjb2w9ImJsYWNrIikNCg0KbXRleHQoIlJlZCBsaW5lIC0tIG9ic2VydmVkIHRlc3Qgc3RhdGlzdGljOiAgMC4zMTA5NSIsIHNpZGU9MSwgbGluZT00LCANCiAgICAgICBhZGo9MCwgY2V4PS45LCBjb2w9InJlZCIpDQptdGV4dChwYXN0ZSgiQXJsbzogIiwgZGF0ZSgpKSwgc2lkZT0xLCBhZGo9MSwgbGluZT00LCBjZXg9LjgsIGNvbD0iZ3JheSIpDQptdGV4dChwYXN0ZSgiRWxhcHNlZDogIiwgc2lnbmlmKHRpbWVyLDQpLCAic2VjLiIpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTIpDQoNCg0KDQojIE5PVEU6IEluIGFueSBwZXJtdXRhdGlvbiB0ZXN0LCB3ZSdyZSBjb25jZXJuZWQgYWJvdXQgc3RhYmlsaXR5IG9mIHAtdmFsdWVzIGluIHJlcGVhdGVkDQojIHJ1bnMgYXQgdGhlIHNhbWUgTlMuIFdlIHNlZWsgc3RhYmxlIHJlc3VsdHMsIHJlY29nbml6aW5nIHRoYXQgdGhlIGNvbWJpbmF0b3JpYWwgb3V0Y29tZQ0KIyBzcGFjZSBtYXkgYmUgdmFzdC4gQnV0IGhlcmUsIGl0J3MgcmF0aGVyIGxvdyBhdCAxNiEvKDghKjghKT0xMiw1MDAgcG9zc2libGUsIHVuaXF1ZSANCiMgZ2xvYmFsIHNodWZmbGVzIG9mIGJvbmUgZGVuc2l0eS4gIA0KIyBCeSBSIGNvZGU6ICAgPiBmYWN0b3JpYWwoMTYpLyhmYWN0b3JpYWwoOCkqZmFjdG9yaWFsKDgpKSAgIA0KDQojIHJ1biBvZiBOUyAxZTUgIHA9LjI4MzgoMSkgOyBwPS41NzMzKDIpICA7IDMuODUgc2Vjb25kcyBlbGFwc2VkIA0KIyBydW4gb2YgTlMgMWU1ICBwPS4yODY2KDEpIDsgcD0uNTcyNygyKSAgOyAzLjk2IHNlY29uZHMgZWxhcHNlZCANCiMgcnVuIG9mIE5TIDFlNSAgcD0uMjg4MCgxKSA7IHA9LjU3NjIoMikgIDsgMy44MCBzZWNvbmRzIGVsYXBzZWQgDQojIHJ1biBvZiBOUyAxZTUgIHA9LjI4NzMoMSkgOyBwPS41NzQwKDIpICA7IDMuODUgc2Vjb25kcyBlbGFwc2VkIA0KIyBydW4gb2YgTlMgMWU1ICBwPS4yODg3KDEpIDsgcD0uNTc2MygyKSAgOyAzLjU2IHNlY29uZHMgZWxhcHNlZCANCg0KIyAtLS0tLS0tLQ0KIyBib3ggcGxvdCAtLS0tLS0tLS0tLS0tLS0tLS0NCiMgLS0tLS0tLS0NCg0KYm94cGxvdChkZW5zIH4gYm9uZSwgZGF0YT1kZnIsIA0KICB4bGFiPSI2NSB5ZWFyIG9sZCBmZW1hbGUgcGF0aWVudCIsIA0KICBtYWluPSJBbGVuZHJvbmF0ZSB0cmVhdG1lbnQiLCBjZXgubWFpbj0yLCANCiAgeWxhYj0iQm9uZSBEZW5zaXR5LCBnL2NtXjIiLCANCiAgY2V4LmxhYj0xLjQ1LCBjZXguYXhpcz0xLjUsIGNvbC5sYWI9ImRhcmtyZWQiLCANCiAgbmFtZXM9YygiU3BpbmUiLCAiSGlwIiksDQogIGNvbD1jKCJncmF5IiwgImxpZ2h0Ymx1ZSIpLA0KICB5bGltPWMoLjYsIC45KSkgDQoNCnRleHQoYygxLDIpLCAuNiwgIm4gPSA4IiwgY2V4PTEuNCkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGxvd2VzcyBmaXQgdGhyb3VnaCB0aGUgcG9pbnRzOyBsb2NhbGx5IHdlaWdodGVkLA0KIyAgIG5vbnBhcmFtZXRyaWMgbm9ubGluZWFyIGZpdCB1c2luZyBsb3dlc3MoKSAgICAtLS0tLS0tLS0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpwbG90KHRpbWUsIHNwaW5lLCB5bGltPWMoLjYsIC45KSwgdHlwZT0iYiIsIGNleC5sYWI9MS4yLA0KICAgIHhsYWI9IlRpbWUgZnJvbSBCYXNlbGluZSwgbW9udGhzIiwgeWxhYj0iQm9uZSBEZW5zaXR5LCBnL2NtXjIiKQ0KcG9pbnRzKHRpbWUsIGhpcCwgcGNoPTE2LCB0eXBlPSJiIiApDQoNCnBvaW50cyg2MiwgLjc4LCBwY2g9MSwgY2V4PTEuNSkNCnRleHQoNjQsIC43OCwgIkx1bWJhciBTcGluZSIsIHBvcz00LCBmb250PTMpDQoNCnBvaW50cyg2MiwgLjc1LCBwY2g9MTYsIGNleD0xLjUpDQp0ZXh0KDY0LCAuNzUsICJUZW1wb3JhbCBOZWNrIChoaXApIiwgcG9zPTQsIGZvbnQ9MykNCg0KbGluZXMobG93ZXNzKHRpbWUsIHNwaW5lKSwgbHdkPTIsIGNvbD0icmVkIikNCmxpbmVzKGxvd2Vzcyh0aW1lLCBoaXApLCBsd2Q9MiwgY29sPSJyZWQiKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBCYXllcyBGYWN0b3IgQ29ycmVsYXRpb24gLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KbGlicmFyeShCYXllc0ZhY3RvcikNCg0KY29ycmVsYXRpb25CRih0aW1lLCBzcGluZSkgIyAxMC4xNDY1MSArLSAwJQ0KY29ycmVsYXRpb25CRih0aW1lLCBoaXApICAgIyAgMS40Njc1ICArLSAwJQ0KDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIC0tLS0tLS0tLSBTVU1NQVJZIC0tLS0tLS0tLS0tLQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBCb25lIGRlbnNpdHkgd2FzIHNpZ25pZmljYW50bHkgYW5kIHN0cm9uZ2x5IHBvc2l0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHRpbWUsIA0KIyBmb3IgPDwgbHVtYmFyIHNwaW5lID4+ICBidXQgbm90IGZvciB0ZW1wb3JhbCBuZWNrIDw8IGhpcCA+PiANCiMNCnNwaW5lLnJlZyAjIHNsb3BlLCBiID0gLjAwMDg4MDIgICBiKjEyIG1vbnRocyA9ICswLjAxMDYgZy9jbV4yIHBlciB5ZWFyIA0KaGlwLnJlZyAgICMgc2xvcGUsIGIgPSAuMDAwMzEzMyAgIGIqMTIgbW9udGhzID0gKzAuMDAzOCAgIiAgICIgICAiDQoNCiMgY2hlY2sgUm9zbmVyIG9uIG1ldHJpY3MgZm9yIGJvbmUgcmF0ZSBvZiBpbmNyZWFzZQ0KDQojIDIuOCB0aW1lcywgc2xvcGUgZm9yIHNwaW5lIHYuIGhpcCwgcmF0ZSBvZiBib25lIGRlbnNpdHkgaW5jcmVhc2UgIA0KIyBzcGluZSBkZW5zaXR5IGluY3JlYXNlZCAyLjggdGltZXMgYXMgZmFzdCBhcyBoaXAgZGVuc2l0eSwgcGVyIHVuaXQgb2YgdGltZSANCg0KIyBJbiBPTFMgbGluZWFyIHJlZ3Jlc3Npb24sIHRoZSA2MCBtb250aCAoNSB5ZWFyKSByYXRlIG9mIGJvbmUgZGVuc2l0eSBpbmNyZWFzZQ0KIyB3YXMgMC4weHggZy9jbV4yIGZvciBsdW1iYXIgc3BpbmUgUD0wLjAwMHh4eCkgYnV0IGZvciB0ZW1wb3JhbCBoaXAsIGJvbmUgDQojIGRlbnNpdHkgaW5jcmVhc2Ugd2FzIG5vdCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIHplcm8gKHA9MC4xMCkuICAgDQojIE5lZWQgdGhlIDEyIG1vbnRoIHJhdGUsIHZzLiBSb3NuZXIgY29tbWVudHMgDQoNCiMgZW5kLiAgYm9uZSBkZW5zaXR5IEFybG8uUg0KDQpgYGANCg0KPC9kZXRhaWxzPiAgIA0KDQo8IS0tICBlbmQgb2YgIDxkZXRhaWxzPiAgZGlzY2xvc3VyZSB3aGljaCBjYW4gaGF2ZSBhbnl0aGluZyAtLT4NCg0KPGJyPiANCg0KIyMgJm5ic3A7IFIgRWRpdG9yIGZpbGUgLS0gPGk+d3JpdGluZyBhYm91dCB0aGUgcmVzdWx0czwvaT4gDQoNCjxicj4NCjxkaXYgY2xhc3M9Im5ld3NwYXBlcjMiPg0KDQpXZSBtdXN0IGJlIGFibGUgdG8gd3JpdGUgYWJvdXQgb3VyIHN0YXRpc3RpY2FsIHJlc3VsdHMgYW5kIGdyYXBoaWNhbCANCnZpc3VhbGl6YXRpb25zLCBhbmQgd3JpdGUgaW4gYSBzdHlsZSBzdWl0YWJsZSBmb3IgcGVlci1yZXZpZXcgYXQgYSBzY2llbnRpZmljIA0Kam91cm5hbCBhcyB3ZWxsIGFzIHdyaXRlIGluIGEgc3R5bGUgZm9yIHRoZSBtb3JlIGdlbmVyYWwgcHVibGljLiANCg0KRm9yIG1hbnksICoqKndyaXRpbmcqKiogYWJvdXQgc3RhdGlzdGljYWwgcmVzdWx0cyBpcyB0aGUgaGFyZGVzdCBwYXJ0LiANCg0KSXQncyBmdW4gdG8gc2F2ZSBhbmQgbWFuaXB1bGF0ZSBvdXIgZGF0YS4gSXQncyBhbHdheXMgZXhjaXRpbmcgdG8gc2VlIHRoZSANCmRpc2NvdmVyaWVzIGFuZCB0aGUgcmV2ZWxhdGlvbnMgZnJvbSBvdXIgZ3JhcGhzIGFuZCBmcm9tIG91ciBzdGF0aXN0aWNhbCBhbmFseXNlcy4gDQpJdCdzIHdoYXQgd2UgbGl2ZSBmb3IgYXMgc2NpZW50aXN0cy4gDQoNCkFsbCB0aGVzZSB0YXNrcyBhcmUgc2tpbGxzLCBza2lsbHMgbGVhcm5lZCBieSBwcmFjdGljZSBhbmQgYnkgcmVhZGluZyBzY2llbnRpZmljIA0KcGFwZXJzIGFuZCB0ZWNobmljYWwgYm9va3MsIHRvIHNlZSBob3cgb3VyIHBlZXJzIGRvIGl0Lg0KDQpFeHBlY3QgdG8gc3BlbmQgYSBncmVhdCBkZWFsIG9mIHRpbWUgd3JpdGluZyBhIHBhcmFncmFwaCAob3IgcGFnZSkgYWJvdXQgYSBkYXRhIHNldC4gDQpJdCdzIG5vdCBlYXN5LiBGb3IgbWUsIGl0J3MgbmV2ZXIgZWFzeSBidXQgaXQncyBhbHdheXMgZnVsZmlsbGluZy4gDQoNCllvdSBtYXkgbmVlZCB0byB3cml0ZSB0d28gdmVyc2lvbnMgLS0gYSB2ZXJzaW9uIGZvciB0aGUgZ2VuZXJhbCwgY29sbGVnZSBlZHVjYXRlZCANCnB1YmxpYyBhbmQgYSB2ZXJzaW9uIGZvciBzY2llbnRpZmljIHBlZXItcmV2aWV3LCB0aGUgZm9ybWVyIHJhdGhlciBpbmZvcm1hbCBhbmQgdGhlICBsYXR0ZXIsIGhpZ2hseSB0ZWNobmljYWwuIEluc3BlY3Rpb24gb2YgdGhlc2UgdHdvIGNvbnRyYXN0aW5nIHN0eWxlcyBpbmZvcm1zIHVzIG9uIA0KaG93IGJlc3QgdG8gY29tbXVuaWNhdGUgb3VyIHJlc3VsdHMuIA0KDQpJIHN0YXJ0IGJ5IHdyaXRpbmcgYSBnb29kLCBzb2xpZCBzdGF0aXN0aWNhbCBzZW50ZW5jZS4gSWYgSSBjYW4gZG8gdGhpcywgSSBjYW4gDQp3cml0ZSBhIHBhcmFncmFwaC4gSWYgSSBjYW4gd3JpdGUgYSBnb29kIHBhcmFncmFwaCBJIGNhbiB3cml0ZSBhIHBhZ2UgYWJvdXQgbXkgDQpzdGF0aXN0aWNhbCByZXN1bHRzLiBTdGFydCBzbWFsbCAtLSBhIHNpbmdsZSBzZW50ZW5jZS4gQWxvbmcgdGhlIHdheSwgd2UgcHJvZml0IA0KYnkgaGF2aW5nIGNvbGxlYWd1ZXMgcmVhZCBhbmQgZWRpdCBvdXIgd3JpdGluZyEgDQoNCjwvZGl2PiANCg0KIyMgJm5ic3A7IFIgRWRpdG9yIGZpbGUgLS0gPGk+UHJvc3BlY3R1czogYSBuZXcgZnVuY3Rpb24/PC9pPiANCg0KPGJyPg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMyI+IA0KDQpJbiBhbiBhYm92ZSBTZWN0aW9uLCBJIHdyb3RlIC0tDQoqKioiQWxzbyBmb3Igc21hbGwgc2FtcGxlIHNpemVzLCB3ZSBwcm9jZWVkIHdpdGggc3RhdGlzdGljYWwgYW5hbHlzaXMgdXNpbmcgY2F1dGlvbiwgDQpyZWFsaXppbmcgaXQgbWF5IGhhdmUgbGl0dGxlIGlmIGFueSwgaW5mZXJlbnRpYWwgdmFsdWUgYmV5b25kIHRoZSBkYXRhIGF0IA0KaGFuZC4iKioqIA0KDQpIZXJlLCB0aGUgPHU+KmRhdGEgYXQgaGFuZCo8L3U+IGFyZSBpbXBvcnRhbnQgdG8gdGhpcyBwYXRpZW50IGFuZCB0byBoZXIgUGh5c2ljaWFuISANCg0KV2UgcmVhbGl6ZSB0aGUgNjUgeWVhciBvbGQgZmVtYWxlIHBhdGllbnQncyBQaHlzaWNpYW4gaXMgc2VyaW91c2x5IG1vdGl2YXRlZCB0byANCnVuZGVyc3RhbmQgYXMgbXVjaCBhcyBwb3NzaWJsZSBmcm9tIHRoZSBwYXRpZW50J3MgeCx5IGRhdGEgZm9yIGJvbmUgZGVuc2l0eSBieSB0aW1lLCANCmZvciBib3RoIHNwaW5lIGFuZCBmb3IgaGlwcywgZ2l2ZW4gQWxlbmRyb25hdGUgdHJlYXRtZW50IGFjcm9zcyA5MiBtb250aHMuICANCg0KU2hlIHdhbnRzIHRvIHB1cnN1ZSBmb3JtYWwgc3RhdGlzdGljYWwgYW5hbHlzaXMgY291cGxlZCB3aXRoIGdyYXBoaWNhbCB2aXN1YWxpemF0aW9uIA0KYW5kIHNoZSBoYXMgc29tZSBhYmlsaXR5IGluIFIgcHJvZ3JhbW1pbmcuIA0KDQpIZXIgcXVlc3Rpb25zIGluY2x1ZGU6DQoNCiogRGlkIEFsZW5kcm9uYXRlIHRyZWF0bWVudCB3b3JrPyBEaWQgYm9uZSBkZW5zaXR5IGluY3JlYXNlPyAgDQoqIFdhcyB0aGUgdHJlYXRtZW50IGVmZmVjdCBsYXJnZSBvciBzbWFsbD8gIA0KKiBEaWQgdGhlIHRpbWUtcmF0ZS1vZi1jaGFuZ2UgaW4gYm9uZSBkZW5zaXR5IG1lZXQgbWVkaWNhbCBiZW5jaG1hcmtzPyANCiogV2FzIHRoZXJlIGEgZGlmZmVyZW5jZSBpbiBib25lIGRlbnNpdHkgcmVzcG9uc2UgZm9yIHNwaW5lIHZlcnN1cyBoaXA/IA0KKiBGcm9tIHRoZSB0aW1lIHplcm8gYmFzZWxpbmUsIGhvdyBsb25nIGRpZCBpdCB0YWtlIGZvciBhIDx1PnNpZ25pZmljYW50PC91PiANCmluY3JlYXNlIGluIGJvbmUgZGVuc2l0eSB0byBvY2N1ciwgaWYgZXZlcj8gDQoqIFNob3VsZCBBbGVuZHJvbmF0ZSB0cmVhdG1lbnQgY29udGludWUsIGNlYXNlLCBvciBiZSBwYXVzZWQgZm9yIHNheSA2IG1vbnRocz8gDQoNClNoZSB0cmVhdHMgbWFueSBlbGRlcmx5IHdvbWVuIGZvciBPc3Rlb3Bvcm9zaXMuIEluIGFkZGl0aW9uIHRvIEFsZW5kcm9uYXRlLCBvdGhlciANCmRydWdzIGFyZSBwcmVzY3JpYmVkIGRlcGVuZGluZyBvbiB0aGUgc2l0dWF0aW9uLiANCg0KU2hlIHJlYXNvbnMgdGhhdCB3cml0aW5nIGN1c3RvbSBSIGNvZGUgDQpmb3IgdGhlIHNwZWNpZmljIGNhc2Ugb2YgdGhpcyA2NSB5ZWFyIG9sZCB3b21hbiwgd2FzIHdvcnRoIHRoZSBlZmZvcnQgYW5kIHNoZSBpcyANCnJpZ2h0ZnVsbHkgcHJvdWQgb2YgaGVyIGNvZGUuIEhvd2V2ZXIsIHdyaXRpbmcgYW5kIGN1cmF0aW5nLCBjdXN0b20gUiBjb2RlIGRldmVsb3BlZCANCmZvciBlYWNoIG9mIGhlciBtYW55IE9zdGVvcG9yb3NpcyBwYXRpZW50cyBpcyBzaW1wbHkgbm90IHByYWN0aWNhbCwgYW5kIHN1Y2ggYSANCnByYWN0aWNlIHdvdWxkIGJlIGVycm9yIHByb25lLiAgDQoNClNoZSBrbm93cyB0aGF0IGdpdmVuIHRoZSBjb3JyZWN0LCByZWxpYWJsZSwgY2xlYW4gYW5kIHJlYWRhYmxlIGNvZGUgaW4gDQpoZXIgUiBlZGl0b3IgZmlsZSBjcmVhdGVkIGZvciB0aGUgZGF0YSBvZiB0aGlzIG9uZSBwYXRpZW50LCBzaGUgY291bGQgDQoqKmdlbmVyYWxpemUqKiB0aGF0IGNvZGUgaW50byBhICoqbmV3IFIgZnVuY3Rpb24qKi4gDQoNClRoaXMgbmV3IGZ1bmN0aW9uIGNvdWxkIGJlIGNhbGxlZCBmb3IgdGhlIHgseSBkYXRhIGZyb20gYW55IE9zdGVvcG9yb3NpcyBwYXRpZW50LCANCmdpdmVuIGFueSBkcnVnIG5vdCBqdXN0IEFsZW5kcm9uYXRlIGFuZCBnaXZlbiBhbnkgZG9zZSBhY3Jvc3MgYW55IHRpbWUgY291cnNlLiANCg0KU3VjaCBhIGZ1bmN0aW9uLCBzYXkgYGJvbmVEZW5zaXR5KClgIHdvdWxkIGhhdmUgYXJndW1lbnRzIGluY2x1ZGluZyBmb3IgaW5wdXQgb2YgDQp4LHkgZGF0YSBhbmQgZm9yIGRpZmZlcmVudCBib25lIHR5cGVzLCBhcmd1bWVudHMgZm9yIHdoZXRoZXIgdG8gc2F2ZSB0aGUgIGdyYXBocyBhcyANCmEgbXVsdGlwYWdlIFBERiBmaWxlIGFuZCB0ZXh0IG91dHB1dCB0byBhIHRleHQgZmlsZSBvciBzaW1wbHkgZGlzcGxheWVkIG9uIHRoZSANCnNjcmVlbiB3aXRoIHByb21wdHMgdG8gc2Nyb2xsLiANCg0KU2hlIHVuZGVyc3RhbmRzIHRoYXQgY29udmVydGluZyBoZXIgbXVsdGlwbGUgcGFnZXMgb2YgY3VzdG9tIFIgY29kZSBpbnRvIGEgDQpmdW5jdGlvbiwgd2lsbCB0YWtlIHRpbWUgYW5kIGNvbnNpZGVyYWJsZSBlZmZvcnQgYnV0IHdvdWxkIHN1cHBvcnQgaGVyIE9zdGVvcG9yb3NpcyANCm1lZGljYWwgcHJhY3RpY2UgYW5kIGJlIG9mIGdyZWF0IHZhbHVlIGluIGd1aWRpbmcgaGVyIGRlY2lzaW9ucyBvbiBPc3Rlb3Bvcm9zaXMgDQp0cmVhdG1lbnQuIA0KDQpTaGUgYWxzbyBrbm93cyB0aGF0IGNhbGxpbmcgYSBmdW5jdGlvbiBpcyBhbHdheXMgbXVjaCBsZXNzIGVycm9yIHByb25lLCBlYXNpZXIgYW5kIA0KZmFzdGVyIHRoYW4gaW50ZXJhY3RpdmVseSBleGVjdXRpbmcgYSB2ZXJ5IGxvbmcsIGN1c3RvbSBjb2RlIGJsb2NrIHRoYXQgbXVzdCBiZSANCm1hbnVhbGx5IGVkaXRlZCAoZS5nLiwgbmFtZSBjaGFuZ2VzIGZvciB2YXJpYWJsZXMpIHRvIGRlYWwgd2l0aCBldmVyeSBkaWZmZXJlbnQgDQpkYXRhIHNldC4gDQoNCkluIHRoaXMgZG9jdW1lbnQgSSBkbyBub3QgZW5nYWdlIHRoaXMgZnVuY3Rpb24gY3JlYXRpb24sIGFzIG11Y2ggYXMgaXQgYXBwZWFscyB0byBtZS4gDQoNClRoZSBjcmVhdGlvbiBvZiB0aGlzIG5ldyBmdW5jdGlvbiB3b3VsZCBiZSBhcHByb3ByaWF0ZSBmb3IgYSBCaW9sb2d5IEJTIEhvbm9ycyANCnByb2plY3QuIElmIGZ1bGx5IGRldmVsb3BlZCwgaXQgd291bGQgYmUgYXBwcm9wcmlhdGUgZm9yIGEgTWFzdGVyJ3MgRGVncmVlIHRoZXNpcyANCmluIEJpb2xvZ3kuIA0KDQpJbiBteSBvcGluaW9uLCBhIHBlcnNvbiB0YWtpbmcgb24gdGhpcyB0YXNrIHNob3VsZCBjb250YWN0IGxvY2FsIFBoeXNpY2lhbnMgd2hvIA0KdHJlYXQgT3N0ZW9wb3Jvc2lzLCBwcmVzZW50IHRoZWlyIGZ1bmN0aW9uIHdpdGggb3V0cHV0LCByZXF1ZXN0IGFub255bW91cyBkYXRhIGZyb20gDQp0aGUgbWVkaWNhbCBwcmFjdGljZSwgYW5kIGdpdmUgdGhlIGZ1bmN0aW9uIHRvIHRoZW0gZm9yIHRoZWlyIHVzZSwgYXMgYXBwcm9wcmlhdGUuIA0KDQpJIGFtIHN1cmUgdGhhdCBPc3Rlb3Bvcm9zaXMgUGh5c2ljaWFucyB3b3VsZCBoYXZlIGdyZWF0IHN1Z2dlc3Rpb25zIGZvciB0aGUgDQppbXByb3ZlbWVudCBhbmQgZW5oYW5jZW1lbnQgb2YgdGhpcyBuZXcgZnVuY3Rpb24sIHdoZXRoZXIgZGVhbGluZyB3aXRoIGRhdGEsIA0Kc3RhdGlzdGljYWwgYW5hbHlzaXMsIGdyYXBoaWNzIG9yIG90aGVyIG1ldHJpY3MuIFN0dWRlbnRzLCBzdWNoIGlzIHRoZSBzdHVmZiB1cG9uIHdoaWNoIA0KY2FyZWVycyBhcmUgYnVpbHQuIA0KPC9kaXY+DQo8YnI+DQoNCiMjICZuYnNwOyBSIEVkaXRvciBmaWxlIC0tIDxpPnJlY2FwaXR1bGF0aW9uPC9pPiAgDQo8YnI+IA0KDQo8cCBzdHlsZT0iY29sb3I6IGRhcmtibHVlOyBmb250LWZhbWlseTogQ291cmllcjsgZm9udC1zaXplOiA0MnB4OyANCiAgICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7IHdvcmQtc3BhY2luZzogOHB4OyI+IA0KICAgICAgICAgIDxiPiBSIENvZGluZyA8dT5jb252ZW50aW9uczwvdT4gPC9iPiAgDQo8L3A+DQoNCg0KPGJyPiANCg0KPCEtLSAuLi4gY29kaW5nIENPTlZFTlRJT05TIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gLS0+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCjwhLS0gIEJFR0lOIGEgYmxvY2stbGV2ZWwgZ3JpZCBjb250YWluZXIgaW4gSFRNTCAtLT4NCjwhLS0gZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBhdXRvIGF1dG8gYXV0bzsgICAzMjBweCAyNTBweCAzMjBweCAtLT4gDQoNCjxzdHlsZT4gDQouZ3JpZC1jb250YWluZXIxIHsNCiAgZGlzcGxheTogZ3JpZDsgDQogIGdyaWQtdGVtcGxhdGUtY29sdW1uczogMzIwcHggMjUwcHggMzIwcHg7ICAgICANCiAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRibHVlOyBjb2xvcjogZGFya3JlZDsNCiAgcGFkZGluZzogMTBweDsgZm9udC1mYW1pbHk6IFRpbWVzOyBmb250LXN0eWxlOiBpdGFsaWM7IA0KfQ0KDQouZ3JpZC1pdGVtew0KICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7IA0KICBwYWRkaW5nOiAyMHB4OyBmb250LXNpemU6IDM1cHg7IHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCjwvc3R5bGU+DQoNCg0KPGRpdiBjbGFzcz0iZ3JpZC1jb250YWluZXIxIj4NCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gdmFsaWQgJiBwcm9wZXIgZmlsZSBuYW1lcyA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IGNvbW1lbnRzIDwvZGl2PiANCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gbGluZSBzcGFjaW5nIDwvZGl2PiANCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gbGluZSB3aWR0aDogODUgY2hhcmFjdGVycyBtYXggPC9kaXY+IA0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiBpbmRlbnRhdGlvbiA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IGNvbnRlbnQgb2YgZmlyc3QgbGluZSBvZiBmaWxlIDwvZGl2PiANCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gY29udGVudCBvZiBsYXN0IGxpbmUgb2YgZmlsZSA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IHZhbGlkIG5hbWVzIGZvciBvYmplY3RzIDwvZGl2PiANCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gd2lzZSBuYW1lcyBmb3Igb2JqZWN0cyA8L2Rpdj4gDQo8L2Rpdj4NCg0KPCEtLSAgRU5EIGEgYmxvY2stbGV2ZWwgZ3JpZCBjb250YWluZXIgaW4gSFRNTCAtLT4NCg0KPGgzPiA8YnI+IEFzIHlvdSB0eXBlIGVhY2ggbGluZSBvZiB5b3VyIFIgY29kZSwgYXMgeW91IGNvbnN0cnVjdCBlYWNoIGZ1bmN0aW9uIGNhbGwgDQphbmQgZm9yIGV2ZXJ5IFIgRWRpdG9yIGZpbGUgeW91IGNyZWF0ZSB3aGV0aGVyIGEgbGFyZ2Ugb3Igc21hbGwgZmlsZSwga2VlcCB0aGUgYWJvdmUgDQo5IHBvaW50cyBpbiBtaW5kLiBUaGVzZSA5IGFyZSA8dT5zdHJ1Y3R1cmFsPC91PiBjb2RpbmcgY29udmVudGlvbnMuIDwvaDM+ICANCjxoMz4gVGhlIHJlc3VsdCB3aWxsIGJlIGNsZWFuLCByZWFkYWJsZSwgd2VsbC1zdHJ1Y3R1cmVkIGNvZGUgdGhhdCdzIA0KZWFzeSB0byBydW4sIHRvIGRlYnVnLCB0byBtYWludGFpbiwgdG8gY2hhbmdlIGFuZCB0byBkaXN0cmlidXRlIHRvIHlvdXIgDQpjb2xsYWJvcmF0b3JzIG9yIHRvIHRoZSBwdWJsaWMuIDwvaDM+DQoNCjxicj4gDQoNCg0KPCEtLSAuLi4gY29kaW5nIEJFSEFWSU9SIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLiAtLT4NCg0KDQo8cCBzdHlsZT0iY29sb3I6IGRhcmtyZWQ7IGZvbnQtZmFtaWx5OiBDb3VyaWVyOyBmb250LXNpemU6IDQycHg7IA0KICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjsgd29yZC1zcGFjaW5nOiA4cHg7Ij4gDQogICAgICAgICAgPGI+IFIgQ29kaW5nIDx1PmJlaGF2aW9yPC91PiA8L2I+ICANCjwvcD4NCg0KPGJyPiANCg0KPCEtLSAgQkVHSU4gYSBibG9jay1sZXZlbCBncmlkIGNvbnRhaW5lciBpbiBIVE1MIC0tPg0KPCEtLSBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IGF1dG8gYXV0byBhdXRvOyAgIDMyMHB4IDI1MHB4IDMyMHB4IC0tPiANCg0KPHN0eWxlPiANCi5ncmlkLWNvbnRhaW5lcjIgew0KICBkaXNwbGF5OiBncmlkOyANCiAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBhdXRvIGF1dG87ICAgICANCiAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5OyBjb2xvcjogYmx1ZTsNCiAgcGFkZGluZzogMTBweDsgZm9udC1mYW1pbHk6IENvdXJpZXI7IGZvbnQtd2VpZ2h0OiBub3JtYWw7IA0KfQ0KDQouZ3JpZC1pdGVtew0KICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7IA0KICBwYWRkaW5nOiAyMHB4OyBmb250LXNpemU6IDM1cHg7IHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCjwvc3R5bGU+DQoNCg0KPGRpdiBjbGFzcz0iZ3JpZC1jb250YWluZXIyIj4NCiAgPGRpdiBjbGFzcz0iZ3JpZC1pdGVtIj4gcGF0aWVuY2UgPC9kaXY+IA0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiB0cmlhbC1hbmQtZXJyb3IgPC9kaXY+IA0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiBzdGFydCBzbWFsbCA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IG1pbmltYWwgY2FsbHMgPC9kaXY+IA0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiB0b3AtZG93biA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IGRlYnVnZ2luZyA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IGF0dGVudGlvbiB0byBkZXRhaWwgPC9kaXY+IA0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiBwcmFjdGljZSA8L2Rpdj4gDQogIDxkaXYgY2xhc3M9ImdyaWQtaXRlbSI+IHJlYWQgJiBzdHVkeSBjb2RlIDwvZGl2Pg0KICA8ZGl2IGNsYXNzPSJncmlkLWl0ZW0iPiBwYXBlciBjb3B5IG9mIGNvZGUgPC9kaXY+DQo8L2Rpdj4NCg0KPCEtLSAgRU5EIGEgYmxvY2stbGV2ZWwgZ3JpZCBjb250YWluZXIgaW4gSFRNTCAtLT4NCg0KDQo8aDM+IDxicj4gU3VjY2Vzc2Z1bCBSIGNvZGluZyBmb3IgdGhlIGdyYXBoaWNhbCBhbmQgc3RhdGlzdGljYWwgYW5hbHlzaXMgb2YgZGF0YSBpcyANCm91ciBnb2FsLiBJdCBpbnZvbHZlcyA8dT5zdHJ1Y3R1cmFsPC91PiwgPHU+Y29kaW5nIGNvbnZlbnRpb25zPC91PiBsaWtlIHRoZSA5IA0KcGljdHVyZWQgcHJldmlvdXNseS4gPC9oMz4gIA0KPGgzPiBKdXN0IGFzIGltcG9ydGFudCBpcyBvdXIgcGVyc29uYWwgPHU+YmVoYXZpb3I8L3U+LiBCeSB0aGlzIEkgcmVmZXIgdG8gb3VyIA0KaGFiaXRzLCBvdXIgZnJhbWUgb2YgbWluZCBhbmQgb3VyIHdvcmsgZXRoaWMgd2hpbGUgY29kaW5nLiA8L2gzPg0KDQo8YnI+DQo8ZGl2IGNsYXNzPSJuZXdzcGFwZXIzIj4gDQpDb2RpbmcgdGFrZXMgKipwYXRpZW5jZSoqIGFuZCB0aGUgY3VsdGl2YXRpb24gb2YgKip0cmlhbC1hbmQtZXJyb3IqKiBiZWhhdmlvci4gDQpCdXQgdGhhdCdzIG5vdCBhbGwuIA0KDQoqKlN0YXJ0IHNtYWxsKiogd2hlbiBsZWFybmluZyBhIHByb2dyYW1taW5nIGVudmlyb25tZW50IGxpa2UgUi4gSSB0aGluayBpdCdzIGJlc3QgDQp0byBzdGFydCB3aXRoIHNtYWxsIGRhdGEgc2V0cyB0aGF0IGFyZSBlYXN5IHRvIHZpc3VhbGl6ZSBhbmQgaG9wZWZ1bGx5LCByZWxhdGl2ZWx5IA0KZWFzeSB0byB1bmRlcnN0YW5kLCBzdWNoIGFzIGJpb21lZGljYWwgZGF0YS4gQWxzbywgc3RhcnQgc21hbGwgaW4gdGVybXMgb2YgeW91ciANCmdyYXBoaWNhbCBhbmQgc3RhdGlzdGljYWwgYXNwaXJhdGlvbnMgZm9yIHRoZXNlIHNtYWxsIGRhdGEgc2V0cy4gVGhpcyBhcHByb2FjaCANCmJ1aWxkcyBjb25maWRlbmNlIGFzIHlvdSBsZWFybi4gDQoNCkV2ZW4gd2hlbiB3ZSdyZSBhY2NvbXBsaXNoZWQgaW4gUiwgaXQgc3RpbGwgcGF5cyB0byBzdGFydCBzbWFsbC4gT24gYSBuZXcgZ3JhcGhpbmcgDQpwcm9qZWN0IGZvciBpbnN0YW5jZSwgd2UgY29kZSBpbiBzdGVwLXdpc2UgZmFzaGlvbiBmcm9tIHNtYWxsLCBtaW5pbWFsIGNhbGxzLCB0byB0aGUgDQpmaW5hbCwgZGVzaXJlZCBncmFwaHMgd2hpbGUgZGVidWdnaW5nLCBzYXZpbmcgYW5kIGxheWluZyBpbiBjb21tZW50cyBhbG9uZyB0aGUgd2F5LiANCg0KKlN0YXJ0IHNtYWxsLCBmYWlsIGZhc3QqIHJlbWFpbnMgYSB3aXNlLCB3b3JrZmxvdyBhZGFnZSBhY3Jvc3MgYWxsIGNvbXB1dGVyIA0KbGFuZ3VhZ2VzLiANCg0KQSAqKm1pbmltYWwgY2FsbCoqIHRvIGEgZnVuY3Rpb24gdXNlcyB0aGUgbWluaW11bSBudW1iZXIgb2YgYXJndW1lbnRzLCBiZWxvdyANCndoaWNoIGl0IHNpbXBseSB3aWxsIG5vdCBleGVjdXRlLiBXZSBkbyB0aGlzIGFzICpwcm9vZiBvZiBjb25jZXB0Ki4gVW5sZXNzIHdlIGNhbiANCmdldCBhIGZ1bmN0aW9uIHRvIHJldHVybiB0aGUgbWluaW1hbCwgd2UgY2FuJ3QgZ2V0IGl0IHRvIHJldHVybiB0aGUgY29tcGxpY2F0ZWQuICAgDQoNClJlbWVtYmVyLCBzb21lIGZ1bmN0aW9ucyBjYW4gYmUgY2FsbGVkIHdpdGggemVybyBhcmdzLCBzdWNoIGFzIGAgZGF0ZSgpYC4gTW9zdCANCmZ1bmN0aW9ucyByZXF1aXJlIG9uZSBvciB0d28gYXJndW1lbnRzIHRvIHJ1biwgZS5nLiwgDQombmJzcDsgYHN0cigpYCAmbmJzcDsgYGhpc3QoeSlgICZuYnNwOyZuYnNwOyAgYHBsb3QoeCwgeSlgICZuYnNwOyBgYm94cGxvdCh5IH4geClgLiANCg0KSXQgaXMgY29tbW9uIGZvciBhIGNhbGwgdG8gYHBsb3QoKWAgdG8gaGF2ZSAxNSBvciBzbyBhcmd1bWVudHMuIEJ1dCwgaWYgd2UgZW50ZXIgYWxsIA0KdGhvc2UgYXJncyBiZWZvcmUgYW55IGV4ZWN1dGlvbiBhbG9uZyB0aGUgd2F5LCB0aGVuIGV4cGVjdCB0byBzZWUgYmV3aWxkZXJpbmcsIA0Kbm9uaW5mb3JtYXRpdmUgZXJyb3IgbWVzc2FnZXMgdGhhdCBjb21wb3VuZCBhbmQgY2FzY2FkZSBkb3duIHlvdXIgbG9uZyBmdW5jdGlvbiANCmNhbGwsIG1ha2luZyBpdCBpbXBvc3NpYmxlIHRvIGZpbmQgdGhlIGVycm9yKHMpLiANCg0KRXJyb3JzIGluIGNvZGluZyBhcmUgbW9zdCBvZnRlbiAqKnB1bmN0dWF0aW9uIGVycm9ycyoqLCB0aGVuICoqc3BlbGxpbmcgZXJyb3JzKiosIA0KdGhlbiBtZW50YWwgKip0aGlua2luZyBlcnJvcnMqKi4gQW5kLCBjb2RpbmcgZXJyb3JzIHN1Y2ggYXMgdGhlc2UgY2FuIGJlIGhhcmQgdG8gDQpzZWUsIGp1c3QgbGlrZSBpdCdzIG9mdGVuIGhhcmQgdG8gc2VlIHR5cG9zIGluIG91ciBFbmdsaXNoIHByb3NlLiANCg0KV2hldGhlciB3ZSdyZSB0YWxraW5nIGFib3V0IGEgZnVuY3Rpb24gdGhhdCdzIG5ldyB0byB1cyBvciBvbmUgd2Uga25vdyB3ZWxsIA0KKGUuZy4sIGBwbG90YCksIGJlaW5nIGFibGUgdG8gZ2V0IGl0IHRvICJ3b3JrIiBieSBhICoqbWluaW1hbCBjYWxsKiogDQppcyB0aGUgcGxhY2UgdG8gYmVnaW4uIFRoZW4sIHRvIGFjaGlldmUgb3VyIGZpbmFsIG9iamVjdGl2ZXMsIHdlIGFkZC9jaGFuZ2UgYXJncyANCmFuZCBwZXJoYXBzIGNhbGwgb3RoZXIgZnVuY3Rpb25zIHN1Y2ggYXMgYHRleHQoKWAgJm5ic3A7IGBtdGV4dCgpYCAmbmJzcDsgDQpgcG9pbnRzKClgICZuYnNwOyBgbGluZXMoKWAgJm5ic3A7IGBsZWdlbmQoKWAgLS0tIGZ1bmN0aW9ucyB0aGF0IGFkZCANCm1hdGVyaWFsIHRvIHRoZSBncmFwaCB3aW5kb3cuIA0KDQpJbiBvdXIgKip3b3JrZmxvdyoqLCBhcyB3ZSBtb3ZlIGZvcndhcmQgZnJvbSBhIG1pbmltYWwgY2FsbCwgd2Ugc2F2ZSB0aGUgbWluaW1hbCANCmNhbGwgaW4gb3VyIHByb2dyYW0gYW5kIHByb2NlZWQgY29kaW5nIGluICoqdG9wLWRvd24qKiBmYXNoaW9uLCBzZW5kaW5nIHRoZSBjYWxsIA0Kd2l0aCBlYWNoIG5ldyBhcmcgYWRkZWQgb3IgY2hhbmdlZC4gVGhpcyBpcyBlc3BlY2lhbGx5IGltcG9ydGFudCBpZiB3ZSBhcmUgdW5zdXJlIA0KYWJvdXQgZnVuY3Rpb24gc3ludGF4IG9yIHVuc3VyZSBhYm91dCBvdXIgY2hvaWNlcyBvZiB2YWx1ZXMgdHlwZWQtaW4gZm9yIGFyZ3Mgb3IgDQppZiB3ZSBkb24ndCB5ZXQga25vdyB3aGF0IHRoZSBiZXN0IGdyYXBoIGZvciBvdXIgZGF0YSBzaG91bGQgYmUuIFRoaXMgaXMgaG93IA0KaW50ZXJhY3RpdmUgY29kaW5nIHNlc3Npb25zIHByb2NlZWQuICANCg0KV2Ugc3VibWl0IHRvIHRoZSBSIENvbnNvbGUsIHRoZSBmdW5jdGlvbiBjYWxsIHdpdGggZWFjaCBjaGFuZ2UuIElmIGl0IHRocm93cyBhbiANCmVycm9yLCB3ZSBrbm93IHRoZSBsb2N1cyBvZiB0aGUgZXJyb3IgLS0gdGhlIGxhc3QgbGluZSBvciBzbyBvZiBjb2RlIGVudGVyZWQsIG5vdCANCjEwIGxpbmVzIHVwc3RyZWFtLiBUaGlzIGlzIHRvcC1kb3duICoqZGUtYnVnZ2luZy4qKiBJdCB3b3Jrcy4gSXQgbWF5IHNlZW0gc2xvdyBhbmQgDQp0ZWRpb3VzIGJ1dCBpdCBzYXZlcyB0aW1lIGluIHRoZSBsb25nIHJ1bi4gSXQgd29ya3MsIGl0IHdvcmtzLCBpdCB3b3JrcyAtLSBsZWFybiBpdC4gIA0KDQpDb2RpbmcgaW4gUiByZXF1aXJlcyAqKmF0dGVudGlvbiB0byBkZXRhaWwqKiBhcyB5b3UgbXVzdCBmb2xsb3cgdGhlIHN5bnRheCANCnJ1bGVzIG9mIHRoZSBsYW5ndWFnZSBpbiB0ZXJtcyBvZiBzcGVsbGluZywgYW5kIHB1bmN0dWF0aW9uLCBzdWNoIA0KYXMsIGAsIDogLCA6OiwgKCApIHsgfSBbIF0gXGAgIDxicj48YnI+IA0KDQpTdHVkZW50cyBvZnRlbiBmYWlsIHRvIHJlYWxpemUgdGhhdCAqKnByYWN0aWNlKiogaXMgZXNzZW50aWFsIGluIHVzaW5nIFIgZm9yIGRhdGEgDQphbmFseXNpcyBhbmQgZ3JhcGhpY3MuIFlvdSBtdXN0IHByYWN0aWNlIHJ1bm5pbmcgYSBwcm9ncmFtIG9uIG1hbnkgZGlmZmVyZW50IA0KZGF0YSBzZXRzLiANCg0KVG8gYmVjb21lIHNlbGYtc3VmZmljaWVudCBpbiBSLCBvbmUgbXVzdCAqKnJlYWQgYW5kIHN0dWR5IGNvZGUqKi4gSXQncyBub3QgZW5vdWdoIA0KanVzdCB0byBiZSBhYmxlIHRvIHJ1biBhbiBSIHByb2dyYW0gdGhhdCB5b3Ugd3JvdGUgb3IgdGhhdCBhbm90aGVyIHBlcnNvbiB3cm90ZS4gDQoNCllvdSBuZWVkIHRvICp1bmRlcnN0YW5kKiB0aGUgY29kZSBpbiB5b3VyL291ciBSIHByb2dyYW1zLiBUaGlzIHJlcXVpcmVzIHVzIHRvIA0KcmVhZCBjYXJlZnVsbHkgYW5kIHRvIHN0dWR5IGRlZXBseSwgdGhlIGNvZGUsIGlmIG91ciBhaW0gaXMgc2VsZi1zdWZmaWNpZW5jeS4gDQoNCkluIHRoZSBsYXRlIDE5NzBzIGEgTWF0aCBQcm9mZXNzb3IgdGF1Z2h0IG1lIGFuIGltcG9ydGFudCBsZXNzb24gDQotLSAqKipUaGVyZSBpcyBubyBzdWJzdGl0dXRlIGZvciBzaXR0aW5nIGRvd24gaW4gYSBxdWlldCBwbGFjZSB3aXRoIGEgcGVuY2lsIGFuZCBhIA0KcGFwZXIgY29weSBvZiB5b3VyIGNvbXB1dGVyIHByb2dyYW0qKiouIA0KDQpXYXkgYmFjayB0aGVuLCB3ZSB3ZXJlIGNvZGluZyBpbiANCkFwcGxlc29mdCBCQVNJQyAobWUpIG9uIHJldm9sdXRpb25hcnkgQXBwbGUgSUkgbWljcm9jb21wdXRlcnMgKDUuMjUgaW5jaCBmbG9wcHkgDQpkcml2ZSwgNDggS0IgUkFNIHdpdGggQkFTSUMgaW4gUk9NLCBhbmQgYXQgYSAkMiw1MDAgcHJpY2UgcG9pbnQpIGFuZCBpbiBDIChoaW0pIG9uIA0KYSBwcmltaXRpdmUgIG1haW5mcmFtZS4gDQoNCk5vdywgSSB1c2UgUiAobW9zdGx5KSBhbmQgaW5jcmVhc2luZ2x5IEhUTUw1LCBDU1MzLCBKYXZhU2NyaXB0LCBTVkcgYW5kIExhVGV4LiANCkludGVyZXN0aW5nbHksIFIgaGFzIGNvbnRyaWJ1dGVkIHBhY2thZ2VzIHRoYXQgYWxsb3cgbmF0aXZlIGNvZGUgZnJvbSBQeXRob24sIEMsIEMrKywgDQpKdWxpYSBhbmQgb3RoZXIgbGFuZ3VhZ2VzLCB0byBiZSBleGVjdXRlZCB3aXRoaW4gUiwgYW5kIHRoaXMgcmVtYWlucyBhcHBlYWxpbmcgZm9yIA0KdGhlIGZ1dHVyZSBncm93dGggb2YgQmlvIDI0MCBhbmQgZGVyaXZhdGl2ZSBjb3Vyc2VzLiAgDQo8L2Rpdj4NCjxicj4NCg0KDQoNCiMgJm5ic3A7IENsb3NpbmcgbWF0ZXJpYWwgICAgICAgICAgICAgICAgICAgICAgPCEtLSAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLiAtLT4NCg0KPGJyPiANCg0KIyMgJm5ic3A7IG9uIHdvcmQgY2xvdWRzICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQpUaGUgMTksMDAwKyBjb250cmlidXRlZCBSIHBhY2thZ2VzIGVuYWJsZSB3b25kZXJmdWwgdGhpbmdzLCBhcGFydCBmcm9tIA0KanVzdCAiZ3JhcGhzIiBhbmQgc3RhdGlzdGljcy4iICANCg0KSSBmaW5kICoqd29yZCBjbG91ZHMqKiB1c2VmdWwgZm9yIGRpc3BsYXkgb2Yga2V5IHdvcmRzIGFuZCB2b2NhYnVsYXJ5LiBDcmVhdGluZyBhIA0Kd29yZCBjbG91ZCBpcyBub3QgInN0YXRpc3RpY3MuIiBJdCdzIGFuIGFydGlzdGljIGV4ZXJjaXNlIHJlcXVpcmluZyANCmNvbnNpZGVyYWJsZSB0cmlhbC1hbmQtZXJyb3IgaW4gZnVuY3Rpb24gY2FsbHMgYW5kIGluIHRoZSB1c2Ugb2YgYXJndW1lbnRzLCB0byBnZXQgYSANCnBsZWFzaW5nIGltYWdlLiBXb3JkIGNsb3VkcyBhcmUgbm90IHBhcnQgb2YgQmlvIDI0MCBidXQgbXkgUiBjb2RlIGJlbG93IHdpbGwgd29yayANCmZvciB5b3VyIG93biB3b3JkIGNsb3Vkcy4gVHJ5IGl0ISANCg0KKipRdWVzdGlvbioqOiBEb2VzIHRoaXMgd29yZCBjbG91ZCBvbWl0IGltcG9ydGFudCBrZXl3b3JkcyBvciBjb25jZXB0cyBpbiB0aGlzIA0KZG9jdW1lbnQ/IERvZXMgaXQgaGF2ZSBpcnJlbGV2YW50IHdvcmRzPyBJZiBzbywgY2FuIHlvdSBzZWUgaG93IHRvIGNoYW5nZSB0aGUgY29kZT8gDQpZb3UgY2FuIGNvcHkvcGFzdGUgYW55IG9mIG15IFIgY29kZSB5b3Ugc2VlIGhlcmUsIGludG8geW91ciBvd24gUiBFZGl0b3IgZmlsZSANCmFuZCBwcm9jZWVkLiANCg0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQoNCmxpYnJhcnkod29yZGNsb3VkMikgIyBsb2FkIHBhY2thZ2UgZm9yIHdvcmQgY2xvdWRzIGNhbGN1bGF0ZWQgaW4gUiBieSBDKysgJiByZW5kZXJlZCANCiAgICAgICAgICAgICAgICAgICAgIyB0byBIVE1MICYgSmF2YVNjcm9wdC4gV2UgZG9uJ3QgbmVlZCB0byBrbm93IEMrKyBvciBIVE1MIGZvciANCiAgICAgICAgICAgICAgICAgICAgIyB0aGlzIC0tIHRoYXQncyB0aGUgam9iIG9mIGZ1bmN0aW9uIHdvcmRjbG91ZDIoKQ0KDQp3b3JkIDwtIGMoIlIiLCAiZGF0YSIsICJncmFwaHMiLCAiQmlvc3RhdGlzdGljcyIsICJGYWxsIDIwMjMiLCAiY29kaW5nIiwgImhpc3RvZ3JhbSIsIA0KICAgICAgICAic2NhdHRlcnBsb3QiLCAiYm94IHBsb3QiLCAiWm9vbSIsICJ0d2l0dGVyIiwgImVtYWlsIiwgImtlcm5lbCBkZW5zaXR5IiwgDQogICAgICAgICJjb3ZpZC0xOSIsICJDREMiLCAiTGVobWFuIENvbGxlZ2UiLCAiQmlvIDI0MCIsICJ0aW1lIHN0YW1wIiwgInRoZSBCcm9ueCIsIA0KICAgICAgICAibW92aW5nIGF2ZXJhZ2UiLCAiZm9yIGxvb3AiLCAiZGF0YSBmcmFtZSIsICJsaXRlcmF0ZSBwcm9ncmFtbWluZyIsIA0KICAgICAgICAicmVwcm9kdWNpYmxlIHJlc2VhcmNoIiwgInVnbHkgY29kZSIsICJidWdneSBjb2RlIiwgInBsb3QoKSIsICJtdGV4dCgpIiwgDQogICAgICAgICJ0ZXh0KCkiLCAic3RyKCkiLCAibGluZXMoKSIsICJmdW5jdGlvbiIsICJhcmd1bWVudHMiLCAiY29tbWVudHMiLCAibG93ZXNzIGZpdCIsIA0KICAgICAgICAiSFRNTCIsICJKYXZhU2NyaXB0IiwgImhlYWQoKSIsICJ2ZWN0b3IiLCAibWVhbiIsICJtZWRpYW4iLCAic3RhbmRhcmQgZGV2aWF0aW9uIiwgDQogICAgICAgICJza2V3IiwgImt1cnRvc2lzIiwgInNvdXJjZSgpIiwgInRhaWwoKSIsICJTaGFwaXJvLVdpbGsgdGVzdCIsICJhYmxpbmUoKSIsIA0KICAgICAgICAic3VtbWFyeSgpIiwgImNhc2VzIiwgImZpbGUgcGF0aCIsICJleHBsaWNpdCBpbmRleGluZyIsICJ3b3JkIGNsb3VkIiwgIlJTdHVkaW8iLCANCiAgICAgICAgIi5jc3YgZmlsZSIsICJkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIiwgImRpc3RyaWJ1dGlvbiIsICJEb25hbGQgS251dGgiLCANCiAgICAgICAgIlBldGVyIERhbGdhYXJkIiwgIlBhdWwgTXVycmVsbCIsICJkaXN0YW5jZSBsZWFybmluZyIsICJkZW5zaXR5KCkiLCAicG9seWdvbigpIiwgDQogICAgICAgICJybm9ybSgpIiwgIndvcmRjbG91ZDIoKSIsICJkYXRhIHRhYmxlIiwgIlJQdWJzIiwgIkJsYWNrYm9hcmQiLCAicG9pbnRzKCkiLCANCiAgICAgICAgImVmZmVjdCBzaXplIiwgIkFub3ZhIiwgImNvcnJlbGF0aW9uIiwgInN0YXRpc3RpY2FsIHBvd2VyIiwgIkJheWVzIEZhY3RvciIsIA0KICAgICAgICAiVHVrZXkncyB0ZXN0IiwgInQtdGVzdCIsICJtdWx0aXBsZSBjb21wYXJpc29ucyIsICJEdW5uZXR0J3MgdGVzdCIsIA0KICAgICAgICAiYXNzdW1wdGlvbnMiLCAiYm9vdHN0cmFwIiwgInBlcm11dGF0aW9uIHRlc3RzIiwgImNvbmZpZGVuY2UgaW50ZXJ2YWwiKSANCg0KZnJlcSA8LSBjKDE5LDYsNiw4LDQsNiwyLDIsMiwgcmVwKDEsNzMpKSAgIyBhcmJpdHJhcnkgJ2ZyZXF1ZW5jeScgZm9yIGVhY2ggd29yZA0KDQpkIDwtIGRhdGEuZnJhbWUod29yZCwgZnJlcSwgcm93Lm5hbWVzPXdvcmQpICAjIG49ODIgd29yZHMNCg0Kd29yZGNsb3VkMihkLCBzaXplPTEuMSkNCg0KYGBgDQoNCjxicj4gPGJyPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KDQojIyAmbmJzcDsgdWdseSBjb2RlIGlzIGJ1Z2d5IGNvZGUgICAgICAgICA8IS0tIGEgc2VudGVuY2UgYnkgRHIuIEFuZHJldyBHZWxtYW4gLS0+DQoNCjxicj4NCg0KICANCioiTGV0IHVzIGNoYW5nZSBvdXIgdHJhZGl0aW9uYWwgYXR0aXR1ZGUgdG8gdGhlIGNvbnN0cnVjdGlvbiBvZiBwcm9ncmFtczogDQpJbnN0ZWFkIG9mIGltYWdpbmluZyB0aGF0IG91ciBtYWluIHRhc2sgaXMgdG8gaW5zdHJ1Y3QgYSBjb21wdXRlciB3aGF0IHRvIGRvLCANCmxldCB1cyBjb25jZW50cmF0ZSByYXRoZXIgb24gZXhwbGFpbmluZyB0byBodW1hbnMgd2hhdCB3ZSB3YW50IHRoZSBjb21wdXRlciB0byBkby4iKg0KIA0KLS0tICoqRG9uYWxkIEUuIEtudXRoKiouIDE5ODQuICpMaXRlcmF0ZSBQcm9ncmFtbWluZyouIFRoZSBDb21wdXRlciBKb3VybmFsIA0KMjcoMik6IDk3LTExMS4gPGJyPiBEb3dubG9hZCBmcmVlIFBERiBvZiB0aGlzIHBhcGVyIGZyb20gdGhlIGpvdXJuYWw6IA0KaHR0cHM6Ly9hY2FkZW1pYy5vdXAuY29tL2NvbWpubC9hcnRpY2xlLzI3LzIvOTcvMzQzMjQ0ICANCkRyLiBLbnV0aCBpcyBQcm9mZXNzb3IgRW1lcml0dXMsIENvbXB1dGVyIFNjaWVuY2UgRGVwYXJ0bWVudCwgU3RhbmZvcmQgVW5pdmVyc2l0eS4gDQoNCjxicj4NCg0KUmVsYXRpdmUgdG8gdGhlIGltcG9ydGFuY2Ugb2Ygd3JpdGluZyB3ZWxsIHN0cnVjdHVyZWQsIGNsZWFuIGFuZCByZWFkYWJsZSBjb2RlIA0KaW4gUiwgRHIuIEFuZHJldyBHZWxtYW4gb2YgQ29sdW1iaWEgVW5pdmVyc2l0eSAoTllDKSB3cm90ZSBhIGJsb2cgcG9zdCB0byANCioqU3RhdGlzdGljYWwgTW9kZWxpbmcsIENhdXNhbCBpbmZlcmVuY2UsIGFuZCBTb2NpYWwgU2NpZW5jZSoqIG9uIDggSnVseSAyMDIwLiANCkhlIGlzIHJlbm93bmVkIGFzIFByb2Zlc3NvciBvZiBTdGF0aXN0aWNzIGFuZCBsZWFkIGF1dGhvciBvbiB0aGUgYWNjbGFpbWVkIG5ldyANCmJvb2sgKEFuZHJldyBHZWxtYW4sIEplbm5pZmVyIEhpbGwsIEFraSBWZWh0YXJpLiAyMDIwLiAqKlJlZ3Jlc3Npb24gYW5kIE90aGVyIA0KU3RvcmllcyoqLiBDYW1icmlkZ2UgVW5pdmVyc2l0eSBQcmVzcywgNTUwIHBhZ2VzKS4gQ29udmluY2luZ2x5LCBoZSBtYWludGFpbnMgDQppbiB0aGlzIGJsb2cgcG9zdCB0aGF0IHVnbHkgY29kZSBpcyBidWdneSBjb2RlLiAgDQoNCiQkXG1hdGhiYiB7XGh1Z2UgVUdMWVxxdWFkIGNvZGVccXVhZCBpc1xxdWFkIEJVR0dZXHF1YWQgY29kZX0kJA0KDQpBcyBpbGx1c3RyYXRlZCBieSBhbiBleGFtcGxlIG9mIGhpcyBvd24gc29tZXRpbWVzIGJ1Z2d5IFIgY29kZSwgaGUgc3RyZXNzZXMgDQp0aGF0IHdlIHdhbnQgIioqKi4uLnRvIGF2b2lkIHRyaXBwaW5nIHVwIGFuZCBldmVuIHB1Ymxpc2hpbmcgZXJyb25lb3VzIHJlc3VsdHMuKioqIg0KDQpIZSBjb250aW51ZXMsICJBbnl3YXksIHRoZSBwb2ludCBvZiB0aGlzIHBvc3QgaXMganVzdCB0byBkZW1vbnN0cmF0ZSBob3csIHdpdGggDQoqKipzbG9wcHkgY29kZSoqKiwgeW91IHJlYWxseSBoYXZlIHRvIGtlZXAgeW91ciBoYW5kcyBvbiB0aGUgd2hlZWwgYXQgYWxsIHRpbWVzLiANCkV2ZW4gc3VjaCBzaW1wbGUgZml0dGluZyBpcyBoYXJkIHRvIGRvIGlmIHlvdSdyZSBub3QgY29udGludWFsbHkgY2hlY2tpbmcgcmVzdWx0cyANCmFnYWluc3QgeW91ciBleHBlY3RhdGlvbnMuIg0KDQpGaW5hbGx5LCAiVG8gcmV0dXJuIHRvIHRoZSB0aXRsZSBvZiB0aGlzIHBvc3Q6ICoqKlVnbHkgY29kZSBpcyBidWdneSBjb2RlKioqIA0Kbm90IGp1c3QgYmVjYXVzZSBpdCdzIGVhc2llciB0byBpbnRyb2R1Y2UgYnVncyBhbmQgaGFyZGVyIHRvIGZpbmQgdGhlbSBpZiB5b3VyIA0KY29kZSBpcyAqKipwb29ybHkgc3RydWN0dXJlZCoqKi4gSXQncyBhbHNvIHRoYXQsIGZvciBjb2RlIHRvIGJlIHRydWx5IG5vbi1idWdneSwgDQppdCBkb2Vzbid0IGp1c3QgaGF2ZSB0byBiZSBmcmVlIG9mIGJ1Z3MuICoqKllvdSBhbHNvIGhhdmUgdG8ga25vdyoqKiBpdCdzIGZyZWUgDQpvZiBidWdzLCBzbyB0aGF0IHlvdSBjYW4gdXNlIGl0IGNvbmZpZGVudGx5LiIgKGJvbGQgZm9udCBhZGRlZCBieSBLaW5jYWlkOyB2aWV3IA0Kb3JpZ2luYWwgc3Rvcnkgd2l0aCBpbnRlcmVzdGluZyBjb21tZW50cyBieSBzZWFyY2hpbmcgImJ1Z2d5IGNvZGUiIGF0IA0KaHR0cHM6Ly9zdGF0bW9kZWxpbmcuc3RhdC5jb2x1bWJpYS5lZHUsIG9yIHNlZSBteSA4LzkvMjAgdHdlZXQgQExDX2Jpb3N0YXQpLg0KDQpDb25zaWRlciBteSBjcnVkZSBleGFtcGxlIGJlbG93IG9mIHdoeSBpdCdzIHNvIGltcG9ydGFudCB0byB3cml0ZSBjbGVhbiwgDQp3ZWxsLXN0cnVjdHVyZWQgUiBjb2RlIGJ5IG1ha2luZyB1c2Ugb2Ygc3BhY2luZywgaW5kZW50YXRpb24gYW5kIGNvbW1lbnRzLiANCg0KTGV0J3MgZ28gYmFjayB0byBzZWN0aW9uIDE0IGFuZCBicmluZyB0aGF0IGNvZGUgZG93biBoZXJlIGZvciB0aGUgaGlzdG9ncmFtIA0KYW5ub3RhdGVkIHdpdGggZGVzY3JpcHRpdmUgc3RhdGlzdGljcywgcC12YWx1ZSBmcm9tIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBvZiANCm5vcm1hbGl0eSBhbmQgYSBwZXJzb25hbGl6ZWQgdGltZSBzdGFtcC4gDQoNCjxicj4gIA0KDQo8IS0tIGxlZnQganVzdGlmaWVkIExhVGV4ICYgZW1vamkgLS0+DQoNCjxoMT4gJFxtYXRoYmIge1xsYXJnZSBXZWxsXCBTdHJ1Y3R1cmVkXCBDb2RlfSQgJm5ic3A7ICYjMTI4NTE2OyA8L2gxPiANCg0KDQoNCjwhLS0gIG1hdGhiYiAgbWF0aGl0ICBtYXRoYmYgIGJvbGRzeW1ib2wgIA0KICAgICAgc21hbGwgU21hbGwgU01BTEwgIGxhcmdlIExhcmdlIExBUkdFIGh1Z2UgSHVnZSBIVUdFDQogICAgICANCiAgICAgICR7XExhcmdlXCBXZWxsXCBzdHJ1Y3R1cmVkXCBjb2RlfSQgICAgICAgICAgICAgIGxlZnQganVzdGlmaWVkDQogICAgICANCiAgICAgICQkXG1hdGhiYiB7XExhcmdlIFdlbGxcIFN0cnVjdHVyZWRcIENvZGV9JCQgICAgIGNlbnRlcmVkDQogICAgICAkJFxtYXRoYmYge1xMYXJnZSBXZWxsXCBzdHJ1Y3R1cmVkXCBjb2RlfSQkIA0KICAgICAgJCRcYm9sZHN5bWJvbCB7XExhcmdlIFdlbGxcIHN0cnVjdHVyZWRcIGNvZGV9JCQgDQotLT4gDQoNCg0KDQpgYGB7ciBvdXQud2lkdGg9IjYwJSIsIGZpZy5jYXA9IjEzIGxpbmVzIG9mIHJlYWRhYmxlIENPREUgdG8gbWFrZSB0aGUgZ3JhcGgifQ0KDQp5MSA8LSBybm9ybSg2MCwgNTAsIDkpICAgIyA2MCByYW5kb20gbnVtYmVycyBmcm9tIG5vcm1hbCBkaXN0cmlidXRpb246IG1lYW4gNTAsIFNEIDkNCm0gPC0gcm91bmQobWVhbih5MSksIDIpICAgICAgICAgICAjIGdldCBtZWFuIG9mIHkgYW5kIHJvdW5kIG9mZiB0byAyIGRlY2ltYWxzDQpzIDwtIHJvdW5kKHNkKHkxKSwgMykgICAgICAgICAgICAgIyBnZXQgU0Qgb2YgeSBhbmQgcm91bmQgb2ZmDQpwIDwtIHJvdW5kKHNoYXBpcm8udGVzdCh5MSkkcCwgMykgIyBwLXZhbHVlIGZyb20gU2hhcGlyby1XaWxrIHRlc3Qgb2Ygbm9ybWFsaXR5DQoNCmhpc3QoeTEsIA0KICAgICBjb2w9InBlcnUiLCAgICAgICAgICMgY29sb3Igb2YgaGlzdG9ncmFtLCBkZWZhdWx0IGlzICJ3aGl0ZSINCiAgICAgbWFpbj1OVUxMLCAgICAgICAgICAjIHN0cmluZyBmb3IgYSB0aXRsZSBvZiBoaXN0b2dyYW07IE5VTEwgb21pdHMgaXQNCiAgICAgY2V4LmxhYj0xLjQsIGNleC5heGlzPTEuMywgbGFzPTEsICAgIyB0eXBvZ3JhcGh5IG9mIGF4ZXMNCiAgICAgYm9yZGVyPSJ3aGl0ZSIsICAgICAgICAgICAgICAgICAgICAgIyBjb2xvciBvZiBsaW5lcyBhcm91bmQgaGlzdG9ncmFtIGJhcnMNCiAgICAgeGxhYj0iUmFuZG9tIHNhbXBsZSBmcm9tIE4oNTAsIDkpIikgIyB4LWF4aXMgbGFiZWwNCg0KY2xyIDwtICJkYXJrcmVkIiAjIGNvbG9yIG9mIHRleHQNCm10ZXh0KHBhc3RlKCJOID0iLCBsZW5ndGgoeTEpKSwgYWRqPTEsIGxpbmU9MCwgIGNleD0xLCBjb2w9Y2xyKQ0KbXRleHQocGFzdGUoIk1lYW4gPSIsIG0pLCAgICAgICBhZGo9MSwgbGluZT0tMSwgY2V4PTEsIGNvbD1jbHIpDQptdGV4dChwYXN0ZSgiU0QgPSIsIHMpLCAgICAgICAgIGFkaj0xLCBsaW5lPS0yLCBjZXg9MSwgY29sPWNscikNCm10ZXh0KHBhc3RlKCIgU2hhcGlyby1XaWxrIHAgPSIsIHApLCBhZGo9MCwgbGluZT0wLCBjZXg9MSwgY29sPWNscikNCm10ZXh0KHBhc3RlKCJBcmxvOiAiLCBkYXRlKCkpLCBzaWRlPTEsIGFkaj0xLCBsaW5lPTQsIGNleD0uOSxjb2w9ImdyYXkiKSAjIHRpbWUgc3RhbXANCm10ZXh0KCJjbGVhbiwgd2VsbCBzdHJ1Y3R1cmVkIGNvZGUiLCBzaWRlPTMsIGxpbmU9MiwgY29sPSJibGFjayIsIGZvbnQ9Mi4yLCBjZXg9Mi4xKQ0KDQpgYGANCg0KPGJyPiAgDQoNClRoZSBhYm92ZSBjb2RlIHRvIG1ha2UgdGhlIGdyYXBoIGlzIHJlbGF0aXZlbHkgZWFzeSB0byByZWFkLCB0byB1bmRlcnN0YW5kLCB0byANCmRlLWJ1ZywgdG8gY2hhbmdlIGFuZCB0byBydW4uIEl0IHJlc2lkZXMgb24gMTMgbGluZXMuICA8YnI+PGJyPiANCg0KPCEtLSBsZWZ0IGp1c3RpZmllZCBodG1sLCBMYVRleCAmIGVtb2ppIC0tPg0KPGgxPiAkXG1hdGhiYiB7XGxhcmdlIFVnbHlcIENvZGV9JCAmbmJzcDsgJiMxMjg1NDM7IDwvaDE+IA0KDQoNCk5vdyBJIHR1cm4gdGhpcyBjbGVhbiBhbmQgcmVhZGFibGUsIGdyYXBoIGNvZGUgaW50byAqKlVnbHkgY29kZSoqIGJ5IHB1dHRpbmcgDQppdCBhbGwgb24gb25lIGxpbmUuIFdoeSBub3Q/IEl0J3MgZGVidWdnZWQgYW5kIHdvcmtzIGdyZWF0LiBXaHkgbm90IGNvbmRlbnNlIGl0IA0KYW5kIG1ha2UgYSBzaG9ydGVyIFIgcHJvZ3JhbS4NCg0KQmVsb3cgdGhlICoqVWdseSBjb2RlKiogcmV0dXJucyBleGFjdGx5IHRoZSBzYW1lIGdyYXBoIGFzIHRoZSBjbGVhbiBjb2RlIG9mIA0KKioxMyBsaW5lcyoqLiANCg0KQnV0LCBoZWF2ZW4gZm9yYmlkIHRoaXMgY29uZGVuc2VkIGNvZGUgc2hvdWxkIGNvbnRhaW4gb3IgYWNxdWlyZSBhIGJ1ZyAtLSBnb29kIA0KbHVjayBmaW5kaW5nIHRoZSBidWcuIEFuZCwgc2luY2UgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZnVuY3Rpb24gY2FsbHMgd2FzIA0KZGVzdHJveWVkIGJ5IHB1dHRpbmcgaXQgYWxsIG9uIG9uZSBsaW5lLCBnb29kIGx1Y2sgdHJ5aW5nIHRvIGVkaXQgdGhlIGNvZGUgdG8gDQptYWtlIGNoYW5nZXMgaW4gdGhlIGdyYXBoIHN1Y2ggYXMgaW4gY29sb3JzLCBsYWJlbHMsIGZvbnQgdHlwZSBhbmQgc2l6ZSwgYW5kIHNvIA0KZm9ydGguIEdvb2QgbHVjayB0cnlpbmcgdG8gdW5kZXJzdGFuZCB0aGUgY29kZSBieSBsb29raW5nIGF0IGl0IHNwcmF3bGVkIGFjcm9zcyANCm9uZSBsaW5lLiANCg0KTGluZSBzcGFjaW5nLCBzcHJlYWRpbmcgb3V0IGEgbG9uZyBmdW5jdGlvbiBjYWxsIGludG8gc2V2ZXJhbCBsaW5lcyB3aXRoIA0KaW5kZW50YXRpb24sIGFsb25nIHdpdGggbGliZXJhbCB1c2Ugb2YgY29tbWVudHMsIGdlbmVyYXRlcyBjb2RlIG9uZSBjYW4gY29tZSANCmJhY2sgdG8gaW4gYSBtb250aCBvciBpbiA2IG1vbnRocywgcmVhZCBpdCBhbmQgdW5kZXJzdGFuZCB3aGF0IHlvdSBoYWQgaW4gbWluZCANCnRvIHN0YXJ0IHdpdGg7IG90aGVyd2lzZSB0aGUgY29kZSBhcHBlYXJzIGFzIGdpYmJlcmlzaC4gDQoNClRoZSAqKlVnbHkgY29kZSoqIG9mIG9uZSBsb25nIGxpbmUgKHNjcm9sbGVkIGJlbG93KSBtYWtlcyBleGFjdGx5IHRoZSBzYW1lIGdyYXBoIA0KYXMgdGhlIHdlbGwgc3RydWN0dXJlZCwgMTMgbGluZXMgb2YgY29kZSBhYm92ZS4NCg0KYGBge3IsIG91dC53aWR0aD0iNjAlIiwgZmlnLmNhcD0iMSBsb25nIGxpbmUgb2YgdW5yZWFkYWJsZSBDT0RFIn0NCg0KaGlzdCh5MSxjb2w9InBlcnUiLG1haW49TlVMTCxjZXgubGFiPTEuNCxjZXguYXhpcz0xLjMsbGFzPTEsYm9yZGVyPSJ3aGl0ZSIseGxhYj0iUmFuZG9tIHNhbXBsZSBmcm9tIE4oNTAsOSkiKTtjbHIgPC0gImRhcmtyZWQiO210ZXh0KHBhc3RlKCJOID0iLGxlbmd0aCh5MSkpLGFkaj0xLGxpbmU9MCxjZXg9MSxjb2w9Y2xyKTttdGV4dChwYXN0ZSgiTWVhbiA9IixtKSxhZGo9MSxsaW5lPS0xLGNleD0xLGNvbD1jbHIpO210ZXh0KHBhc3RlKCJTRCA9IixzKSxhZGo9MSxsaW5lPS0yLGNleD0xLGNvbD1jbHIpO210ZXh0KHBhc3RlKCIgU2hhcGlyby1XaWxrIHAgPSIsIHApLGFkaj0wLGxpbmU9MCxjZXg9MSxjb2w9Y2xyKTttdGV4dChwYXN0ZSgiQXJsbzogIixkYXRlKCkpLHNpZGU9MSxhZGo9MSxsaW5lPTQsY2V4PS45LGNvbD0iZ3JheSIpOyBtdGV4dCgiVSBHIEwgWSAgQyBPIEQgRSIsIHNpZGU9MywgbGluZT0yLCBjb2w9ImJsYWNrIiwgZm9udD0yLCBjZXg9Mi41KQ0KDQpgYGANCg0KPGJyPg0KKldyaXRpbmcgY29kZSogaXMgbGlrZSB3cml0aW5nIGEgcG9lbSB0byB5b3VyIG1vdGhlci1pbi1sYXc7IHlvdSBhcmUgKm5ldmVyIHNhdGlzZmllZCo7IA0KeW91ICpuZXZlciBzdG9wIHJldmlzaW5nKiBpdC4gJm5ic3A7IEFsbCBzb2Z0d2FyZSByZXNpZGVzIHVuZGVyICpjb25zdGFudCByZXZpc2lvbiouICZuYnNwOyBUaGlzIA0KYXBwbGllcyBlcXVhbGx5IHRvIG9uZSBvZiB5b3VyIG1hbnksIHJlbGF0aXZlbHkgc2hvcnQsIGUuZy4sIDEgb3IgMiBwYWdlcywgKiouUioqIA0KZmlsZXMgdGhhdCB5b3Ugd2lsbCBjcmFmdCB0aGlzIHNlbWVzdGVyLCB0byBteSBsYXJnZSAgKiouUioqIGZpbGVzIHRoYXQgZGVmaW5lIG5ldyANCmZ1bmN0aW9ucyB1c2VmdWwgZm9yIHVuaXZhcmlhdGUgZGF0YSwgb25lLXdheSBkYXRhLCBhbmQgZm9yIHgseSBkYXRhIA0KKEsgZnVucyBVTklWQVJJQVRFLlIsICZuYnNwOyBLIGZ1bnMgT05FIFdBWS5SLCAmbmJzcDsgSyBmdW5zIENPUlJFTEFUSU9OLlIpLiAmbmJzcDsgDQpFdmVuIHRoZSBjb2RlIGZvciA8Yj5iYXNlIFI8L2I+IGl0c2VsZiwgcmVtYWlucyB1bmRlciBjb25zdGFudCByZXZpc2lvbi4gPGJyPiAgIA0KDQoqIklmIGRlYnVnZ2luZyBpcyB0aGUgcHJvY2VzcyBvZiByZW1vdmluZyBzb2Z0d2FyZSBidWdzLCB0aGVuIHByb2dyYW1taW5nIG11c3QgYmUgDQp0aGUgcHJvY2VzcyBvZiBwdXR0aW5nIHRoZW0gaW4uIiogPGJyPiANCi0tLSAqKkUuIERpamtzdHJhKiogKDE5MzAsIDIwMDIpIFRoZSBvcmlnaW5hdG9yIG9mIHRoZSBzdHJ1Y3R1cmVkIHByb2dyYW1taW5nIA0KbW92ZW1lbnQsIGFuZCBtb3JlLg0KPGJyPiANCg0KKiJQcm9ncmFtbWVycyBvZnRlbiBmaW5kIHRoYXQgdGhleSBzcGVuZCBtb3JlIHRpbWUgZGVidWdnaW5nIGEgcHJvZ3JhbSB0aGFuIGFjdHVhbGx5IA0Kd3JpdGluZyBpdC4gR29vZCBkZWJ1Z2dpbmcgc2tpbGxzIGFyZSBpbnZhbHVhYmxlLC4uLiBUaG91Z2ggZGVidWdnaW5nIGlzIGFuIGFydCANCnJhdGhlciB0aGFuIGEgc2NpZW5jZSwgaXQgaW52b2x2ZXMgc29tZSBmdW5kYW1lbnRhbCBwcmluY2lwbGVzLiIqIDxicj4gDQotLS0gKipOb3JtYW4gTWF0bG9mZioqICgyMDExKSBUaGUgQXJ0IG9mIFIgUHJvZ3JhbW1pbmcsIEEgVG91ciBvZiBTdGF0aXN0aWNhbCBTb2Z0d2FyZQ0KDQpJbiBCaW8gMjQwIHdlIHByYWN0aWNlICppbnRlcmFjdGl2ZSosICp0b3AtZG93biBjb2RpbmcqIGFuZCAqdG9wLWRvd24gZGVidWdnaW5nKiwgDQp1c2luZyB0aGUgKndyaXRlLWV4ZWN1dGUgbG9vcCogYmV0d2VlbiB0aGUgUiBFZGl0b3IgYW5kIHRoZSBSIENvbnNvbGUuICZuYnNwOyBNb3JlIA0KYWR2YW5jZWQgZGVidWdnaW5nIHN0cmF0ZWdpZXMgYXJlIGJleW9uZCBvdXIgdGltZSBjb25zdHJhaW50cyBpbiB0aGlzIGNvdXJzZS4gDQpJbmRlZWQsIHRoZXJlIGFyZSBib29rcyBvbiBkZWJ1Z2dpbmcgYW5kIFIgcGFja2FnZXMgZGV2b3RlZCB0byBpdC4gPGJyPjxicj4gDQoNCg0KIyMgJm5ic3A7IHN0YXRpc3RpY2FsIHdpc2RvbSAgICAgICAgICAgPCEtLSAuLi4uLi4uLi4uIHNlY3Rpb24gMTUuMyAuLi4uLi4uLi4uIC0tPg0KPGJyPiANCg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMyI+DQpBY3Jvc3MgYWxsIGJpb2xvZ2ljYWwgYW5kIGJpb21lZGljYWwgc3ViamVjdCBhcmVhcywgd2Ugc2VlayAqKipzdGF0aXN0aWNhbCANCndpc2RvbSoqKiBpbiBvdXIgcmVzZWFyY2ggZGVzaWduLCBkYXRhIGFjcXVpc2l0aW9uLCBkYXRhIHdyYW5nbGluZywgZ3JhcGhpbmcsIA0Kc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIGluIG91ciBhYmlsaXR5IHRvIHdyaXRlIGFib3V0IGl0IGFsbCwgaW4gZm9ybXMgc3VpdGFibGUgDQpmb3IgcGFwZXJzIGluIHBlZXItcmV2aWV3ZWQgc2NpZW50aWZpYyBqb3VybmFscyBhbmQgZm9yIGZvcm1hbCBwcmVzZW50YXRpb25zIA0KKHBvc3RlciBzZXNzaW9ucywgbGl2ZSBhdWRpZW5jZSwgaW50ZXJ2aWV3KS4gDQoNClRoZSBjZW50cmFsIHBhdGggdG8gc3RhdGlzdGljYWwgd2lzZG9tIGlzIHRvIDx1PmludGVybmFsaXplPC91PiwgPHU+bWFzdGVyPC91PiBhbmQgDQo8dT5pbnRlZ3JhdGU8L3U+IGEgdmFyaWV0eSBvZiBjb250cmFzdGluZywgMSkgPGI+c3RhdGlzdGljYWwgbWV0aG9kczwvYj4gDQoodHJhZGl0aW9uYWwsIG5vbnBhcmFtZXRyaWMsIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUsIEJheWVzaWFuKSBhbmQgMikgPGI+Z3JhcGhpY2FsIA0KdmlzdWFsaXphdGlvbnM8L2I+LCBhcHBsaWVkIGFjcm9zcyBtYW55IGRpZmZlcmVudCBkYXRhIHNldHMsIG9mIGJvdGggc21hbGwgYW5kIA0KbGFyZ2Ugc2FtcGxlIHNpemVzLiANCg0KV2UgbGVhcm4gaG93IHRvIGFuYWx5emUgZGF0YSBieSBhbmFseXppbmcgZGF0YS4gWWVzIGl0J3MgbGFyZ2VseSwgYW4gYWNxdWlyZWQgc2tpbGwuICAgDQoNClN0YXRpc3RpY2FsIHdpc2RvbSBhbHNvIGludm9sdmVzIHdpc2UgbmFtaW5nIGZvciBkYXRhIHZhcmlhYmxlcywgZm9yIFIgcHJvZ3JhbSANCmZpbGVzIGFuZCBmb3IgPG1hcms+IC5jc3YgPC9tYXJrPiBkYXRhIGZpbGVzLg0KDQpBcyB3ZSBzdHVkeSBhbmQgbGVhcm4sIGFsb25nIG91ciBwYXRoIHRvIHN0YXRpc3RpY2FsIHdpc2RvbSwgd2Ugc29vbiBpZGVudGlmeSAzIA0KYmlnIHRoaW5nczogJm5ic3A7KnByYWN0aWNlLCBwcmFjdGljZSwgcHJhY3RpY2UqLiANCg0KV2UgZW5qb3kgYSB3b25kZXJmdWwsIGVtcG93ZXJpbmcgcmVhbGl0eSBhcyB3ZSBsZWFybiA8aT5iYXNpYyBzdGF0aXN0aWNzPC9pPiANCndyaXQgbGFyZ2UuIA0KDQpFYXJseSBpbiBhbnkgYmFzaWMgc3RhdGlzdGljcyBjb3Vyc2UsIHdlIG11c3QgbWFzdGVyIHRvcGljcyBpbmNsdWRpbmcsIA0KZGVzY3JpcHRpdmUgc3RhdGlzdGljcyAobW9tZW50cywgcXVhbnRpbGVzKSwgY29uZmlkZW5jZSBpbnRlcnZhbHMsIGVmZmVjdCBzaXplcyANCihlLmcuLCBDb2hlbuKAmXMgKmQqKSwgc3RhdGlzdGljYWwgcG93ZXIgYW5hbHlzaXMsIGFuZCBiYXNpYyBncmFwaHMgKGxpbmUgZ3JhcGgsIHNjYXR0ZXIgDQpwbG90LCBoaXN0b2dyYW0sIGJveCBwbG90LCBtZWFucyB3aXRoIGVycm9yIGJhcnMsIGJhciBncmFwaHMpLiBUaGVzZSBhcmUgKiphbHdheXMgdXNlZCoqIGluIA0Kc2NpZW50aWZpYyBwYXBlcnMgcmVmbGVjdGluZyB0aGUgbGF0ZXN0IGN1dHRpbmctZWRnZSByZXNlYXJjaCBhcyBwdWJsaXNoZWQgYWNyb3NzIA0KdGhlIHRvcCwgcGVlciByZXZpZXdlZCBqb3VybmFscy4gDQoNClRoaXMgc3R1ZmYgKipuZXZlciBnb2VzIG91dCBvZiBkYXRlLioqIExlYXJuaW5nIGl0IGlzICoqbmV2ZXIgd2FzdGVkLioqIEl0IGVuaGFuY2VzIA0KeW91ciB1bmRlcmdyYWR1YXRlIEJpb2xvZ3kgcHJvZ3JhbSBhdCBMZWhtYW4gQ29sbGVnZS4gSXQgaGVscHMgbWFrZSB5b3UgDQpjb21wZXRpdGl2ZSBpbiBwcm9mZXNzaW9uYWwgY2FyZWVyIGRldmVsb3BtZW50LiANCg0KVGhlIGFiaWxpdHkgdG8gaGFuZGxlIGRhdGEgYW5kIGRvIGJhc2ljIHN0YXRpc3RpY3MgYW5kIGdyYXBoaWNzIGJ5IGN1c3RvbSANCnByb2dyYW1taW5nIGluIDxiPlI8L2I+LCBlbmFibGVzIHJlc2VhcmNoIGV4cGVyaWVuY2VzLCBlbmhhbmNlcyBwb3N0Z3JhZHVhdGUgDQphcHBsaWNhdGlvbnMgYW5kIGtlZXBzIHlvdSBvbiB0aGUgZmFzdCB0cmFjayB0byBzdWNjZXNzISANCg0KSG9wZWZ1bGx5LCAqKkJpbyAyNDAuIEJpb3N0YXRpc3RpY3MqKiB3aWxsIGhlbHAgeW91IG1vdmUgZm9yd2FyZCB0b3dhcmQgdGhlc2UgZ29hbHMuDQo8L2Rpdj4NCjxicj4NCg0KIyMgJm5ic3A7IGZpbmFsIHBvaW50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uIC0tPg0KPGJyPg0KPGRpdiBjbGFzcz0ibmV3c3BhcGVyMiI+DQpXaGVuIHlvdSBjbGljayBvbiB0aGlzIEhUTUwgZmlsZSwgaXQgb3BlbnMgaW4geW91ciB3ZWIgYnJvd3NlciBhbmQgUiBuZWVkIG5vdCANCmJlIHByZXNlbnQgb3IgcnVubmluZy4gVGhpcyBmaWxlIHdpbGwgd29yayBvbiBjb21wdXRlcnMgd2l0aCBhbnkgb3BlcmF0aW5nIHN5c3RlbSANCihXaW4sIG1hY09TLCBDaHJvbWUgT1MsIExpbnV4IGRpc3Ryb3MpLiANCg0KVGhlICoqc291cmNlIGNvZGUqKiBpcyBhIHBsYWluIHRleHQgZmlsZSwgYSBSIG1hcmtkb3duIGZpbGUgYGBgLlJtZGBgYCB0aGF0IGlzIA0KYm91bmQgdG8gSFRNTCBhbmQgSmF2YVNjcmlwdCBieSB0aGUgcG93ZXJmdWwgUiBmdW5jdGlvbiBgYGBrbml0cigpYGBgIGFuZCBieSANCmBgYHBhbmRvY2BgYCAoYSBIYXNrZWxsIGxpYnJhcnkgZm9yIGRvY3VtZW50IGNvbnZlcnNpb24gdG8gSFRNbCwgZVB1YiwgDQpQREYsIE9wZW5Eb2N1bWVudCwgV29yZCAmIFBvd2VyUG9pbnQsIHNoaW55IHdlYiBhcHBzLCBhbmQgbW9yZSkuIFdoaWxlIA0KYGBgcGFuZG9jYGBgIGlzIG5vdCBwYXJ0IG9mIFIsIGl0IGlzIGRvd25sb2FkZWQgYnkgYW5kIG1hZGUgYXZhaWxhYmxlIA0KYXV0b21hdGljYWxseSBieSAqKlJTdHVkaW8qKiB3aGljaCBpcyB0aGUgYmVzdCBlbnZpcm9ubWVudCBmb3IgY3JhZnRpbmcgDQoqKnJlcHJvZHVjaWJsZSByZXNlYXJjaCoqLiBQeXRob24gcHJvZ3JhbW1lcnMgc2ltcGx5IGluc2VydCBuYXRpdmUgUHl0aG9uIGNvZGUgDQppbnN0ZWFkIG9mIFIgY29kZSBpbiB0aGUgY29kZSBibG9ja3MuICANCg0KKipBcyB0aGUgc2VtZXN0ZXIgcHJvY2VlZHMgeW91IG1pZ2h0IGZpbmQgdGhpcyBlbnRpcmUsIFN5bGxhYnVzIEhUTUwgZmlsZSBoYW5keSBmb3IgDQpyZXZpZXcgb2Ygc29tZSB0b3BpY3MgY292ZXJlZCBpbiBCaW8gMjQwLioqIA0KDQpNYW55IEJpb2xvZ3kgbWFqb3JzIGFzcGlyZSB0bywgYW5kIGlkZW50aWZ5IGFzICoqcHJlLW1lZCoqLiBTb21lIHRoaW5rICpjb21wdXRlciANCnByb2dyYW1taW5nKiBpcyBub3QgcmVsZXZhbnQgdG8gdGhlIGJpb21lZGljYWwgY2FyZWVyIHBhdGguIENvbnNpZGVyIHRoZSANCnN0YXRlbWVudCBpbiB0aGUgcGljdHVyZSBiZWxvdywgZnJvbSBvbmUgb2YgdGhlIHdvcmxkJ3MgbW9zdCBwcmVzdGlnaW91cyBtZWRpY2FsIA0KZmFjaWxpdGllcywgKipUaGUgQ2xldmVsYW5kIENsaW5pYyoqIChDbGV2ZWxhbmQsIE9oaW8pLg0KPC9kaXY+PGJyPiANCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjUwJSIsIGZpZy5jYXA9IiBQaHlzaWNpYW5zIHdobyBjb2RlIGNvdWxkIGJlIHRoZSBmdXR1cmUgb2YgaGVhbHRoY2FyZSwuLi4iLCBmaWcuc2hvdz0iaG9sZCJ9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvR0VEQzA5MDIuSlBHIikNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGg9IkM6L1VzZXJzL2R3aWdoL0Rlc2t0b3AvU1lMTEFCVVMvQ2xldmVsYW5kX0NsaW5pY18xLmpwZyIpDQoNCmBgYA0KDQo8YnI+ICAgDQoNClRoZSBqb3VybmFsICR7XG1hdGhpdCBOYXR1cmV9JCBpcyBwdWJsaXNoZWQgaW4gRW5nbGFuZCwgaXQgY292ZXJzIGFsbCBhcmVhcyANCm9mIHNjaWVuY2UsIGl0IGhhcyBhbiBleHRyZW1lbHkgaGlnaCByZWplY3Rpb24gcmF0ZSBvbiBzdWJtaXR0ZWQgcGFwZXJzIGFuZCBpdCANCmNvbXBhcmVzIGZhdm9yYWJseSB0byBvdXIgam91cm5hbCwgJHtcbWF0aGl0IFNjaWVuY2V9JCBpbiB0ZXJtcyBvZiBiZWluZyANCmFyZ3VhYmx5LCB0aGUgbW9zdCBwcmVzdGlnZW91cyBzY2llbnRpZmljIGpvdXJuYWwgaW4gdGhlIHdvcmxkLiBOZWl0aGVyIGpvdXJuYWwgDQppcyBvcGVuLWFjY2VzcyBidXQgYm90aCBtYWtlIHNvbWUgcGFwZXJzIGluIGVhY2ggaXNzdWUgYXZhaWxhYmxlIHRvIGFsbC4gDQoNCiR7XG1hdGhpdCBOYXR1cmV9JCBoYXMgd2hhdCBpdCBjYWxscyAiY29sbGVjdGlvbnMiIG9mIHBhcGVycywgbWFueSBvZiB3aGljaCANCmFyZSBvcGVuLWFjY2Vzcy4gVGhlIGNvbGxlY3Rpb24sICJTdGF0aXN0aWNzIGZvciBCaW9sb2dpc3RzIiBpcyBhYnNvbHV0ZWx5IA0KZXhjZWxsZW50LiBGaW5kIGl0IGZyb20gbXkgQXVndXN0IDI2LCAyMDIwIHR3aXR0ZXIgcG9zdCwgDQpodHRwczovL3R3aXR0ZXIuY29tL0xDX2Jpb3N0YXQgb3IgdmlzaXQgaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9jb2xsZWN0aW9ucy9xZ2hocW0gDQoNCiR7XG1hdGhpdCBTY2llbmNlfSQgcHVibGlzaGVzICR7XG1hdGhpdCBTY2llbmNlXCBBZHZhbmNlc30kIHdoaWNoIGlzIGNvbXBsZXRlbHkgDQpvcGVuLWFjY2VzcywgbXVsdGlkaXNjaXBsaW5hcnkgYW5kIGlzIGEgaGlnaGx5IHJlY29tbWVuZGVkIHJlYWQgZm9yIGFsbCBvZiB1cy4gDQoke1xtYXRoaXQgU2NpZW5jZVwgQWR2YW5jZXN9JCBoYXMgYSBsaXZlbHkgdHdpdHRlciBzaXRlLCANCmh0dHBzOi8vdHdpdHRlci5jb20vU2NpZW5jZUFkdmFuY2VzIGFuZCBhdCBodHRwczovL2FkdmFuY2VzLnNjaWVuY2VtYWcub3JnIGVhY2ggDQppc3N1ZSBjYW4gYmUgdmlld2VkIGZyZWUuIFlvdSBzaG91bGQgcmVndWxhcmx5IHJlYWQgJHtcbWF0aGl0IFNjaWVuY2VcIEFkdmFuY2VzfSQgDQp0byBrZWVwIHVwIHdpdGggdGhlIHNjaWVudGlmaWMgd29ybGQgYXMgZW5qb3ltZW50IGFuZCBhcyBwYXJ0IG9mIHlvdXIgY2FyZWVyIA0KZGV2ZWxvcG1lbnQgc3RyYXRlZ3kuIFJlbWVtYmVyLCB3aGF0IGNvdXJzZXMgKipyZXF1aXJlKiogaXMgb25seSB0aGUgdG9wIG9mIHRoZSANCmljZWJlcmcuIA0KDQpBcyBhIHB1YmxpYyBzZXJ2aWNlIGR1cmluZyB0aGUgcGFuZGVtaWMsICR7XG1hdGhpdCBTY2llbmNlfSQgaGFzIGEgZnJlZSBzaXRlLCAgIA0KaHR0cHM6Ly93d3cuc2NpZW5jZW1hZy5vcmcvY29sbGVjdGlvbnMvY29yb25hdmlydXM/SW50Q21wPWNvcm9uYXZpcnVzc2lkZXJhaWwtMTI4IA0KZm9yICJDb3JvbmF2aXJ1czogUmVzZWFyY2gsIENvbW1lbnRhcnksIGFuZCBOZXdzIiB3aGljaCBwcm92aWRlcyBvcGVuLWFjY2VzcyB0byANCm1hbnkgb2YgdGhlaXIgcmVjZW50IHBhcGVycyBvbiBjb3ZpZC0xOS4NCg0KPGJyPiA8YnI+ICANCg0KKipQcm9mZXNzaW9uYWwgQ2FyZWVyIERldmVsb3BtZW50KiouIEluIGNsYXNzIEkgd2lsbCBkaXNjdXNzIHRoaXMgdG9waWMgd2hpY2ggDQppcyBvcHRpb25hbCBtYXRlcmlhbCB5b3Ugd2lsbCBub3QgYmUgdGVzdGVkIG9uLg0KDQpJdCB3aWxsIGludm9sdmUgY2FzZSBzdHVkaWVzLCBhZHZpY2UgZnJvbSBteSBleHBlcmllbmNlLCBteSBwZXJzb25hbCBzdG9yaWVzLCANCnRpcHMsIGlkZWFzIGFuZCBjaGFsbGVuZ2VzLiANCg0KQSBzb2xpZCBjYXJlZXIgaW4gc2NpZW5jZSwgbWVkaWNpbmUgb3Igc2NpZW5jZSBlZHVjYXRpb24gZG9lcyBub3QgaGFwcGVuIA0KYXV0b21hdGljYWxseS4gDQoNCk9uZSByZWFzb24gSSB0YWxrIGFib3V0IGNhcmVlciBkZXZlbG9wbWVudCBpbiBteSBjbGFzc2VzIGlzIGJlY2F1c2Ugd2hlbiBJIHdhcyANCmFuIHVuZGVyZ3JhZHVhdGUsIG5vIHByb2Zlc3NvcnMgYm90aGVyZWQgdG8gdGVsbCBtZSB0aGVzZSB0aGluZ3MuIFRoZXkgZWl0aGVyIGRpZCANCm5vdCBjYXJlLCBkaWQgbm90IGtub3csIG9yIGJvdGguIA0KIA0KPGJyPg0KDQoNCg0KYGBgez1odG1sfQ0KPHAgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb21pYyBzYW5zIG1zOyBjb2xvcjogZGFya3JlZDsgZm9udC1zaXplOiAxOHB0Ow0KICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogY29ybnNpbGs7IHdpZHRoOiA2NTBweDsgDQogICAgICAgICBoZWlnaHQ6IDYwcHg7IHBhZGRpbmctdG9wOiAxM3B4OyAgIA0KICAgICAgICAgZm9udC13ZWlnaHQ6IG5vcm1hbDsgdGV4dC1hbGlnbjogY2VudGVyOyI+DQogICANCiAgU3VjY2VlZCBpbiB5b3VyIDxiPkNhcmVlciBEZXZlbG9wbWVudCAhPC9iPiAgDQo8L3A+DQoNCg0KPHAgc3R5bGU9ImxpbmUtaGVpZ2h0OiAxNTAlOyBmb250LXNpemU6IDE3cHQ7IGNvbG9yOiBibHVlOyBmb250LWZhbWlseTogY29taWMgc2FucyBtcyI+ICANCiAgICAmbmJzcDsgJiMxMDEwMjsgQWx3YXlzIHNob3cgdXAgJiBzaG93IHVwIG9uIHRpbWUgJm5ic3A7DQogICAgJmVtc3A7ICYjMTAxMDM7IFBheSBhdHRlbnRpb24gJiB0YWtlIG5vdGVzIDxicj4NCiAgICAmbmJzcDsgJiMxMDEwNDsgV29yayBoYXJkICYgYXNrIHF1ZXN0aW9ucyAmZW1zcDsgJm5ic3A7ICAgIA0KICAgICZlbXNwOyAmIzEwMTA1OyBCZSBob25lc3QsIGRvbid0IGNoZWF0ICZuYnNwOyA8YnI+DQogICAgJm5ic3A7ICYjMTAxMDY7IFByYWN0aWNlLCBwcmFjdGljZSwgcHJhY3RpY2UgJmVtc3A7ICANCiAgICAmIzEwMTA3OyBNYWludGFpbiBhIGhpZ2ggR1BBIDxicj4NCiAgICAmbmJzcDsgJiMxMDEwODsgSm9pbiBwcm9mZXNzaW9uYWwgc2NpZW50aWZpYyBzb2NpZXRpZXMgJiBhdHRlbmQgdGhlaXIgbWVldGluZ3M8YnI+IA0KICAgICZuYnNwOyAmIzEwMTA5OyBZb3UgbXVzdCBoYXZlIGEgcmVzZWFyY2ggZXhwZXJpZW5jZSB0byBiZSBjb21wZXRpdGl2ZTxicj4NCiAgICAmbmJzcDsgJiMxMDExMDsgWW91IHNob3VsZCByZWFkIGJvb2tzICYgam91cm5hbCBwYXBlcnMsIGZhciBiZXlvbmQgd2hhdCdzIHJlcXVpcmVkDQo8L3A+DQpgYGANCg0KDQo8YnI+DQoNCg0KIyMgJm5ic3A7IFIgU2Vzc2lvbiBpbmZvcm1hdGlvbiAgICAgICAgICA8IS0tICAgICAgIC0tPiANCg0KPGJyPiANClRvIGVuaGFuY2UgdGhlIDxmb250IHNpemU9NCI+KioqcmVwcm9kdWNpYmlsaXR5KioqPC9mb250PiBvZiBvdXIgUiBjb2RlIGluIHRoaXMgDQpkb2N1bWVudCwgd2UgY2FsbCB0aGUgYHNlc3Npb25JbmZvKClgIGZ1bmN0aW9uIGluIGJhc2UgUi4gQXQgdGhlIFIgQ29uc29sZSBlbnRlciANCmA+P3Nlc3Npb25JbmZvYCBmb3IgaXRzIGRvY3VtZW50YXRpb24gd2hpY2ggd2lsbCBjb21lIHVwIGluIHlvdXIgYnJvd3NlciBhcyBhbiBIVE1MIA0KZmlsZS4gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgZ3JlYXQgZGVhbCBvZiB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgeW91ciBjdXJyZW50LCANClIgU2Vzc2lvbi4gICANCg0KYGBge3J9DQogIHNJIDwtIHNlc3Npb25JbmZvKCkNCiAgcHJpbnQoc0ksIGxvY2FsZT1UUlVFKQ0KICAjIHN0cihzSSkgICMgY29tbWVudC1pbiBmb3IgdGhlIFNUUlVDVFVSRSBvZiB0aGUgc2Vzc2lvbkluZm8oKSBvYmplY3QgDQpgYGANCioqUXVlc3Rpb24qKjogQ2FsbCB0aGUgYWJvdmUgUiBjb2RlIHVzaW5nIGBsb2NhbGU9RkFMU0VgIGFuZCBzZWUgd2hhdCBoYXBwZW5zLiBDYWxsIA0KdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMsIGVhY2ggd2l0aCB6ZXJvIGFyZ3VtZW50czogYFIuVmVyc2lvbigpYCAsIGBnZXRSdmVyc2lvbigpYCAsIA0KYW5kIGBSLmhvbWUoKWAuICZuYnNwOyBUaGVuIGNhbGwgYFIudmVyc2lvbmAgd2hpY2ggaXMgYW4gKm9wZXJhdG9yKiB0aGF0IHJldHVybnMgYSANCmxpc3Q7IGNvbXBhcmUgaXQgdG8gdGhlIG91dHB1dCBmcm9tIGZ1bmN0aW9uIGBSLlZlcnNpb24oKWAgYW5kIGluc3BlY3QsIA0KYHN0cihSLlZlcnNpb24pYC4gUmVtZW1iZXIgdGhhdCB0aGUgaW52YWx1YWJsZSBhbmQgZXh0cmVtZWx5IGNvbW1vbmx5IGNhbGxlZCwgYHN0cmAgDQpmdW5jdGlvbiByZXR1cm5zIHRoZSAqKnN0cnVjdHVyZSoqIG9mIHdoYXRldmVyIG9iamVjdCBpcyBuYW1lZCBhcyBpdHMgYXJndW1lbnQuIA0KRXZlcnkgY2xhc3MgdGhpcyBzZW1lc3Rlciwgd2Ugd2lsbCBjYWxsIHRoZSBgc3RyYCBmdW5jdGlvbiwgZm9yIGEgdmFyaWV0eSBvZiANCnJlYXNvbnMuIA0KDQoNCjxwIGlkPSJibGFja2xpbmUiPiBfX19fX19fX19fX19fX19fX18gPC9wPiA8YnI+ICAgICAgICAgPCEtLSBibGFjayBsaW5lIC0tPiANCg0KDQo8aDI+VGhlIFIgd2Vic2l0ZTwvaDI+DQo8cCBpZD0ibXlIZWFkZXI0Ij4NCmh0dHBzOi8vci1wcm9qZWN0Lm9yZyAgJmVtc3A7ICoqQ2xpY2sgdG8gRXhwbG9yZSBpdCoqIDxicj4gDQomZW1zcDsgQ2xpY2sgb24gKipDUkFOKiogd2hlcmUgeW91IGluc3RhbGwgUjxicj4gDQomZW1zcDsgJm5ic3A7IENoZWNrIG91dCA8aT5UaGUgUiBKb3VybmFsPC9pPiAgIA0KJmVtc3A7ICZuYnNwOyAmbmJzcDsgRXhhbWluZSB0aGUgKipUYXNrIFZpZXdzKio8YnI+IA0KJmVtc3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IFNjYW4gdGhlIHRob3VzYW5kcyBvZiBjb250cmlidXRlZCAqKnBhY2thZ2VzKiogYnkgQS1aIG5hbWUgDQpvciBieSBzdWJtaXNzaW9uIGRhdGUNCjwvcD4NCjxicj48YnI+PGJyPiAgDQoNCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MCUiLCBmaWcuY2FwPSJKb2huIFR1a2V5ICgxOTE1LTIwMDApIiwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuc2hvdz0iaG9sZCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoPSJDOi9Vc2Vycy9kd2lnaC9EZXNrdG9wL1N5bGxhYnVzIEZhbGwgMjAyMi9UdWtleSBxdW90ZTEuanBnIikNCmBgYA0KDQo8YnI+IA0KDQo+IA0KPiAqRmluZGluZyB0aGUgcXVlc3Rpb24gaXMgb2Z0ZW4gbW9yZSBpbXBvcnRhbnQgdGhhbiBmaW5kaW5nIHRoZSBhbnN3ZXIuKiAgIA0KPiAtLS0gSm9obiBUdWtleSwgUHJpbmNldG9uIFVuaXZlcnNpdHkgYW5kIEJlbGwgTGFicyAoMTkxNSAtIDIwMDApIA0KPg0KDQoNCjwhLS0gICA8cCBzdHlsZT0iZm9udC1mYW1pbHk6ICdjb3VyaWVyIG5ldyc7IGZvbnQtc2l6ZTogNDBwdDsgZm9udC13ZWlnaHQ6IGJvbGQ7IA0KICAgICAgICAgIGNvbG9yOiByZWQ7IGJhY2tncm91bmQtY29sb3I6IHdoaXRlOyBwYWRkaW5nOiAwcHg7IA0KICAgICAgICAgIG1hcmdpbi10b3A6IDBweDsgbWFyZ2luLXJpZ2h0OiAxOTBweDsgbWFyZ2luLWJvdHRvbTogMHB4OyBtYXJnaW4tbGVmdDogMHB4Ow0KICAgICAgICAgIHRleHQtYWxpZ246IHJpZ2h0OyB0ZXh0LWluZGVudDogMHB4OyANCiAgICAgICAgICB0ZXh0LXNoYWRvdzogNHB4IDJweCAycHggZ3JheTsiPg0KICAgICAgICAgIFI8YnI+ZGF0YTxicj5ncmFwaHM8YnI+c3RhdGlzdGljczwvcD4gICAtLT4NCg0KPGJyPjxicj4gIA0KKipFTkQgb2YgQmlvIDI0MCBTeWxsYWJ1cywgRmFsbCAyMDIzKiogIA0KDQo8cCBzdHlsZT0iZm9udC1mYW1pbHk6ICdjb3VyaWVyIG5ldyc7IGZvbnQtc2l6ZTogMjhwdDsgZm9udC13ZWlnaHQ6IGJvbGQ7IA0KICAgICAgICAgIGNvbG9yOiByZWQ7IGJhY2tncm91bmQtY29sb3I6IHdoaXRlOyBwYWRkaW5nOiAwcHg7IG1hcmdpbi1yaWdodDogMzAwcHg7DQogICAgICAgICAgbWFyZ2luLWJvdHRvbTogMHB4OyANCiAgICAgICAgICB0ZXh0LWFsaWduOiByaWdodDsgdGV4dC1pbmRlbnQ6IDBweDsgDQogICAgICAgICAgdGV4dC1zaGFkb3c6IDNweCAxcHggMXB4IGdyYXk7Ij4NCiAgICAgICAgICBSPGJyPmRhdGE8YnI+Z3JhcGhzPGJyPnN0YXRpc3RpY3M8YnI+d3JpdGluZyBhYm91dCB0aGUgcmVzdWx0czwvcD48YnI+ICANCg0KDQo8IS0tICAke1xsYXJnZVwgUHJvZmVzc29yXCBEd2lnaHRcIEtpbmNhaWQsXCBQaER9JCAgLS0+DQoNCipEd2lnaHQgS2luY2FpZCosIFBoRCAgDQpQcm9mZXNzb3IgJmVtc3A7JmVtc3A7JmVtc3A7JmVtc3A7JmVtc3A7IGR3aWdodC5raW5jYWlkQGxlaG1hbi5jdW55LmVkdQ0KDQoqKnRpbWUgc3RhbXA6KiogJm5ic3A7IGByIGZvcm1hdChTeXMudGltZSgpLCAnJUEgJUIgJWQsICVZIGF0ICVIOiVNOiVTJylgICANCioqbGFzdCByZW5kZXJlZCoqOiAmbmJzcDsgYHIgZm9ybWF0KFN5cy50aW1lKCksICclQSAlQiAlZCwgJVkgYXQgJUg6JU06JVMnKWAgIA0KPGJyPg0KDQo8aDYgaWQ9Im15SGVhZGVyMSI+DQpCaW8gMjQwLiA8aT5CaW9zdGF0aXN0aWNzLjwvaT4gJmVtc3A7IEZhbGwgMjAyMyAmZW1zcDsmZW1zcDsmZW1zcDsmZW1zcDsNCkRlcGFydG1lbnQgb2YgQmlvbG9naWNhbCBTY2llbmNlcyAmZW1zcDsNCkxlaG1hbiBDb2xsZWdlICZlbXNwOyBDaXR5IFVuaXZlcnNpdHkgb2YgTmV3IFlvcmsgJmVtc3A7IEJyb254IE5ZIDEwNDY4IFVTQSANCjwvaDY+DQoNCjwhLS0gICAgIGVuZC4gIFN5bGxhYnVzIFNwcmluZyAyMDIzLlJtZCAgICAtLT4=