For this first exercise you will be examining how you can use various software for geospatial analysis and graphical display of spatial data. Because of the variety and availability of operating systems in use today, each of the exercises in this course can be completed in either ArcGIS Pro, QGIS, or R. Each of these software have their pro’s and con’s but for simplicity purposes here is a table that might suggest which software would be best for you:

ArcGIS Pro QGIS R
Available on Windows PC Only Available for PC, Mac, or Linux (limited) Available for PC, Mac, Linux, ChromeOS, iOS, or Android via web modern browser
Available by subscription only Open Source Open Source
Graphical User Interface with built-in functionality for Python; add-ons available for statistical languages Graphical User Interface with built-in functionality for Python; use of plug-ins for other languages and analyses Scripting language, mostly used for statistical purpose; packages expand its use to other applications such as geospatial analyses
Widely used in academia, government, and industry jobs Widely used in academia and industry Predominantly used in academia, research, and specialized industry jobs
Help available at ESRI.com and through various outlets via a google search Help available at QGIS.org and through sites like stackoverflow.com or other sites via google search Help available through individual package documentation and sites like stackoverflow.com or other sites via google search

For the purposes of this course, you can complete the laboratory exercises in any of these software. There will be drop-down menus in every lab color-coded for the three software. Ultimately, you will have access to all of this material during and after the course and while the steps might be different between each version the outcomes will be the same. So if you choose to complete the course with one software you can always go back and complete the work in another software in your own time.

While all of the software will be available on the computers in McCord 210, if you choose to use ArcGIS Pro you will need to contact the APSU GIS Center with your student information to obtain a one year license for your personal computer. QGIS is available for download using this link. If you are completing the course in R you will not need to install any software, however you will need a Google account and access to the Chrome browser. When using R you will be completing all of the lab exercises in the Google Colaboratory and will access everything you need from the exercise pages on GitHub.

More information for each software and the steps to complete this exercise can be found below. Be sure to follow the color-coded drop-down for the specific software you are using for the lab.

View information for ArcGIS Pro

ArcGIS Pro is a proprietary software from ESRI. Student access is available in McCord 210 and several other computer labs on campus. If you wish to obtain the software for use on your personal computer (Windows-based PC only) you will need to contact the APSU GIS Center at 601 N 2nd St, Clarksville, TN 37040, (931) 221-7500. Please have your APSU student ID and A# available for verification prior to obtaining a license. Please contact the GIS Center if you have any issues downloading or installing the software.


View information for QGIS

If you will be using QGIS for the exercises you will need to have the software installed on your computer. QGIS is available for PCs, Mac, and Linux computers. You can find the appropriate download for your operating system here:

When installing on macOS for the first time you may need to go to Systems Preferences > Security and Privacy and on the General tab “Allow apps downloaded from” App Store and identified developers and click Open Anyway. Please contact your instructor if you have any issues downloading or installing the software.


View information for R

You will be completing the R portion of each exercise using the Google Colaboratory Executable Environment. Colaboratory, or “colab” for short, is based on the popular Jupyter Notebooks and allows you to write and execute R or Python in your browser, with:

  • Zero configuration required
  • Free access to GPUs
  • Easy sharing

Each colab notebook is separated into code cells and text cells. A code cell is used to write and execute a script interactively. Each text cell uses simple markdown syntax for creating plain text information. You can easily share the notebook like other Google Drive based documents by clicking the “Share” link in the upper right-hand portion of the window.

Before beginning each exercise using R, you will need to open the Exercise Colab Notebook and alter the URL to view/edit the file in colab. To do this you will navigate to the exercise’s GitHub page; in this case https://github.com/chrismgentry/GIS1-Exercise-2. In the list of folders and files you will find a file that will always be identified as GIS1_EX followed by the exercise number and a .ipynb file extension. So for this exercise it will be GIS1_EX2.ipynb

Finding the Google Colab file on GitHub


When you locate the file, click on the name to open the ipy notebook. In the resulting window, click on the URL and insert tocolab immediately after github in the address. So the new URL for this exercise should now read:
https://githubtocolab.com/chrismgentry/GIS-Exercise-2/blob/main/GIS1_EX2.ipynb

Converting ipy file to colab


Click enter/return and the file should now open inside of Colab. Your screen might have a slightly different appearance, but you should see the Exercise 2, GIS 1 header indicating you are in the correct notebook.

Converting ipy file to colab


Each time you open these colab notebooks, or if you have not interacted with the notebook for an extended period of time, you will need to make sure the environment is connected and all of the sample script has been run. To do this go to Runtime > Run all (or click CRTL+F9) and run the notebook. This may take a moment to complete so be patient until the last code cell has been executed. You should see a green check mark with an allocation of RAM and Disk as shown by horizontal bars which will indicate you are connected. In each section of code there is a Run cell  Run cell button button that will allow you to run the individual code cells. This button will have a rotating loading symbol Run cell button while the code cell is being executed. Once it is complete the box will return to the run state and there may be an output visible depending on the script. You can add your own text or code cells to a notebook simply by moving your cursor slowly over the notebook to reveal the code/text option bar or by going to Insert > Code cell/Text cell.

Adding Text or Code Blocks


By clicking within each code or text cell you can edit the contains and adjust the properties using the various preset option controls.

Edit block properties


You should practice adding and removing cells, editing their content, and rearranging the order of the cells. This will help familiarize you with notebook tools and allow you to manipulate notebooks in these exercises and create your own notebooks in the future.

For each new exercise there will be a colab notebook available. Within the notebook will be sample code for you to run, code cells for you to complete as part of the exercise and questions to be answered within labeled text cells. Detailed directions will be available on the individual exercise webpage. Each completed exercise will have completed code and question sections and the notebook link shared for a grade.

1 The Introduction

The Tennessee Valley Authority (TVA) and Tennessee Department of Environment and Conservation (TDEC) are considering a partnership to increase the number of electric vehicle charging stations across the state. With destinations such as Nashville, Memphis, Gatlinburg and the Great Smoky Mountains, Bristol Motor Speedway, Signal Mountain and the Tennessee Aquarium, tourism is a major part of the state’s economy. So accommodating residents and visitors with electric vehicles as well as creating a network for those traveling the states major interstates (I-65, I-40, I-24, I-75, etc.) is of utmost importance.

TDEC says this network of charging stations will also promote electric vehicle growth by giving drivers confidence they will have easy access to refueling while away from home, eliminating so-called “range anxiety” that keeps many consumers from considering electric vehicles as viable transportation. TVA says electric vehicle adoption will spur jobs and economic investment in the region, keep refueling dollars in the local economy, reduce the regions largest source of carbon emissions, and save drivers and fleets money.

So TVA and TDEC have asked you to develop a map showing the number of public electric vehicle charging stations in the continental United States. This will help them understand what the nations current infrastructure looks like and how Tennessee currently compares to neighboring states. It will also help TVA and TDEC determine approximately how many additional stations they should add.

In this exercise you will:

  • Navigate software used for geospatial analysis
  • Examine attributes of various datasets
  • Learn how to graphically display spatial data
  • Create a cartographically sound product

Software specific directions can be found for each step below. Please submit the answer to the questions and your final map by the due date.

1.1 Step One: The Data

In this step you will learn how to obtain data, load it into the software, examine the attributes, and make a simple display.

View Directions in ArcGIS Pro

The purpose of this exercise is to help familiarize you with the ArcGIS Pro program. With this software, you will have the ability to view, create, and edit geographic data, query spatial data, examine spatial relationships, and create publishable maps. To launch ArcGIS Pro, click on the start menu and search for the ArcGIS Folder. Within the folder click on the ArcGIS Pro icon to open.

Data Download from GitHub


After the initial splash screen, you’ll be greeted with a screen that allows you to open previous recently saved projects, new map templates, and view various resources from ESRI. For this exercise you will begin by clicking Map under the New > Blank Templates section in the middle of the screen.

ArcGIS Pro Open Screen


This will open a new Create a New Project  screen that will ask you to give your new project a name and a location on your computer to save the project. At this point I would recommend creating a folder somewhere on your PC to store all of your GIS1 exercises. If you are in a GIS class using a networked folder, be sure to have that folder mapped and save all of your data under the project folder for this exercise. This will make them easier to locate later on.

Project name and location


After establishing the project, a project file and several folders will be created in your folder, and your screen should appear similar to this:

New project


While your screen might appear slightly different, you should have a basemap in the center section, a list of objects under Map in the Contents section on the left (frequently called a table of contents), and possibly a blank section on the right. For this exercise you will need to download the Electric Vehicle Charging Station data from the GitHub Repository by clicking on the download button at this link and saving it in your exercise folder created above. Once the download is complete you will need to unzip the file by using right-click > extract all on the zipped folder.

Data Download from GitHub


This data should now be available for use in your project. To add the information to your map project, navigate to the Map tab on the menu bar and find the Add Data button. From here you can click the drop-down menu and see all of the options. For this example you will click Data, Add data to the map.

Add data button


Similar to other PC-based GUI interfaces, a new window will open where you will navigate to your data folder and double-click or single-click and click OK to add the data.

Add data


This will add the data to your map and it will appear in the table of contents. Your screen should now look similar to the one below (colors may vary):

EV Dataset View


With this dataset added, you can now begin to explore some of the basic tools for navigating and analyzing the map data. Some information or tools are available in the map view while some are located in each of the various tabs (Map, Insert, Analysis, View, Edit, Imagery, and Share). Additionally, some tabs or information will only become available when data is selected. For example, while on the Map tab, if you select the ev_data in the table of contents you will see that Appearance, Labeling, and Data tabs all appear. If you select either the World Topographic Map or World Hillshade only Appearance is added. If you select Map in the table of contents then all additional options are removed.

Along the bottom of the map view there are several tools available including:

Representative Fraction Unit-less relation between map units and real-world units (e.g. 1 unit equals 30,000 units)
Snapping Moving a feature to match or coincide exactly with another point or feature’s coordinates when your pointer is within a specified distance or tolerance
Constraints Limits imposed on a model to maintain data integrity
Grid A network of parallel and perpendicular lines superimposed on a map and used for reference
Inference Analyzes the segment of the active sketch over which the pointer is hovering and displays inferred geometric constraints
Corrections Set grid corrections and offset
X,Y Coordinates X,Y location of the cursor; can be set to decimal degrees, degrees minutes seconds, degree decimal minutes, military grid reference system, national grid, or universal transverse mercator
Selected Features Depicts the number of items selected from a feature set
Pausing Drawing Stops the drawing of layers on the map view
Refresh Reloads the map view

Map View Toolbar


The mouse can be used to navigate around the map view. The left-click button is used to pan or move the map around the screen and view pop-ups, the scroll wheel is used to zoom or rotate/tilt (3D), and righ-click is used for continuous zoom by clicking and moving the cursor up to zoom out and down to zoom in.

Explore


On the Map tab there are a number of tools you should become familiar with as they will be useful throughout this course and beyond. Along with the Add Data button you have already used, the Fixed Zoom In/Out tools  Fixed Zoom Tools are used to adjust the level of zoom. The Full Extent tool  Full Extent Tool is used to adjust the level of zoom to include the extent of all datasets. The Previous Extent tool  Previous Extent Tool is used to return the level of zoom to the previous level. There are a number of other tools you will use on this tab in future exercises. You should explore the different buttons on this tab to see what they do.

Map Toolbar


For this exercise you will familiarize yourself with another useful tool that allows you to examine information regarding the dataset. First, click on the ev_data layer in the table of contents. Next, click on the Explore  button Explore Button and move the cursor over the map. Your cursor will become a hand with pointed finger. If you click on the state of Tennessee a pop-up window will appear that provides data about the state.

Explore


You can scroll down on the data in the pop-up window and examine each attribute in the table. Along the bottom of the window you will see tools that can be used to: print the information for the selected feature Print the pop-up for this feature, toggle selection on/off for the feature Toggle selection on/off for this feature, flash the selected feature Flash selected feature, and to zoom to the selected feature Zoom to selected feature.

This method is helpful for getting information about a specific portion of the dataset. You can view all of the underlying information in the attribute table by right-clicking on the ev_data layer in the table of contents and clicking on Attribute Table.

Explore


Alternatively while the ev_data layer is selected in the table of contents you should see three new tabs highlighted in orange (color may vary) and titled Feature Layer. Under the Data tab you should see the Attribute Table tool.

Map Toolbar


Whichever method you used to open the attribute table you should now have a new section on your screen that displays the attribute data for all of the features in the dataset. In a future exercise you will learn how to sort, query, and edit information within the attribute table. For now, examine the numerous variables available for each state. What is the column name and range of values for the electric vehicle charging stations?
Hint: This information will be needed in the next section.

Attribute Table


Question No. 1
Using the explore tool, what is the population of Tennessee in 2010 (POP2010)? What percentage of the population is female?

Using the attribute table, find the area (SQMI ) of Colorado. How much larger is it than Wyoming?
Type your answers in a word document. The answers will need to be submitted at the conclusion of this lab.

View Directions in QGIS

The purpose of this exercise is to help familiarize you with the QGIS program. With this software, you will have the ability to view, create, and edit geographic data, query spatial data, examine spatial relationships, and create publishable maps. In these directions I will post images from both PC (on the left) and macOS (on the right) for each step. While your set-up may differ slightly, the configurations and layout of the tools should be similar.

When you begin a new exercise it would be beneficial to create a new folder specifically for the data and project files associated with the lab. This will help you to organize your data and be able to quickly refer back to it in later exercises. For this exercise you will need to download the Electric Vehicle Charging Station data from the GitHub Repository by clicking on the download button at this link and saving it in your exercise folder. Once the download is complete you will need to unzip the file by using double-click on macOS or right-click > extract all on PC.

Data Download from GitHub


To start the QGIS program press the Start Menu > QGIS or launch the application from the Mac Launchpad. It might be beneficial to create a shortcut on the desktop or add it to your dock for quicker access in the future. As the program loads, the opening screen will be extremely useful to you while working on future projects, however, for this exercise we will select New Empty Project.

QGIS Start Screen


The screen depicted below is separated into two sections. To the left there is the Browser and Layers sections, and on the right is the Map Canvas. Your version may vary slightly from the images. There are a number of ways to add data, but in this example we are going to use the browser window to connect to our project data folder.

QGIS Start Screen


In the Browser window on the left, navigate to the folder where you saved and unzipped the exercise data folder. Once you locate a folder in folder in the browser, you can use control+click (macOS) or right-click (PC) to Add as a favorite. This will link it to the favorites drop-down in the browser window giving you quicker future access. To add the data, you will navigate to the ev_data.shp file and then click-and-drag it to the map canvas. You will be able to add all types of data in this same way. If there is a pop-up window that mentions transformations go ahead and click OK. While the look of the US in this dataset is less than ideal, the purpose of this exercise is to ensure you know how to display data and basic tools for navigating the software. Transformations will be discussed further in a couple weeks after a lecture on projections and coordinate systems. For now, leave it with option 1 and click OK.

QGIS Start Screen


Your screen should now look similar to the screens below (colors may vary). Notice that the longitude and latitude values at the bottom of the screen adjust as you move your cursor.

QGIS Map Canvas


You can now begin to explore some of the basic tools for navigating the map canvas such as:

  • Zoom in and out with the Fixed Zoom Tools
  • Fixed Zoom Tools
  • Pan tool to postion the map on the screen
  • Pan Tool
  • Map scale where you can adjust the map scale (level of zoom) manually
  • Map Scale
  • Zoom full button which will adjust the view to accommodate all datasets
  • Zoom Full


    Use these tools to zoom in and out, reposition the map on the screen, and return to the current view using the zoom full button.

    Another useful tool is the identify features cursor which uses an icon with a lowercase i in a blue circle Identify Features . This option extracts information for a selected feature from the attribute table of the selected layer.

    Identify Cursor


    If you wanted to view the entire underlying dataset you could control-click (macOS) or right-click (PC) on the active layer and select Open attribute table. In a future exercise you will learn how to sort, query, and edit information within the attribute table. For now, examine the numerous variables available for each state. What is the column name and range of values for the electric vehicle charging stations?
    Hint: This information will be needed in the next section.

    Attribute Table


    Question No. 1
    Using the identify tool, what is the population of Tennessee in 2010? What percentage of the population is female?

    Using the attribute table, find the area (SQMI ) of Colorado. How much larger is it than Wyoming?
    Type your answers in a word document. The answers will need to be submitted at the conclusion of this lab.

    View Directions in R

    For each exercise in R you will need to load various packages that are used to complete analyses and graphical output. Generally these packages will be preloaded in the colab notebook however in subsequent labs you may need to install certain packages to complete the exercises. To install a package in R you use the following function where (“x”) is the name of a specific package.

    install.packages("x")

    Once the package has been installed, it will need to be loaded using a similar function:

    library("x")

    In the colab notebook for this exercise you will see where three packages tidyverse, maps, and ggsn were installed and loaded. Now that you have the packages required for the exercise you will need to add the data. For this lab the data consists of state names, abbreviations, and the number of electric vehicle recharing stations. To avoid the need to download the data, you will the read.csv() function and a URL to import the data. Using the head() function will allow you to view the first few lines of any dataset.

    evs <- read.csv('https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/ev_stations.csv')
    head(evs)

    In the script above you will see the use of  <-. This is an operator used to create an object that can be used in later steps. If the script was written as read.csv('https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/ev_stations.csv') the dataset would have been read and immediately displayed on the screen. However, it would not have been available for subsequent analyses. In colab, you can create your own code block and test it out to see the results. Since you need this information for later, it is important to use  <- to create an object out of the imported data. In this, and future exercises, you will see that operator used frequently to create objects for analysis.

    In order to create a map of electrical vehicle charging stations per state you need to obtain information for the states and create a new object. The tidyverse package is a retainer for a number of individual packages including the Grammar of Graphics or ggplot2 package. This package will frequently be used to display your data, but it also contains geographic information for the US. You can obtain that information by using the map_data function. In a new code block, you can use ?map_data to view help information on the function. Alternatively you can view the documentation for any package or function by searching the package or function name and cran (Comprehensive R Archive Network). For this function you would search map_data cran and the first link is likely to be the RDocumentation page for the function. Within this documentation you will find the arguments available for the function and example scripts. So to create an object that contains information for the continental US you can use:

    us <- map_data('state')

    Using the Grammar of Graphics package, ggplot2, you can create a visualization of this data. Here is that script:

    ggplot(us) + 
      geom_polygon(aes(x=long, y=lat, group=group), color = "white")

    In this script you identified that you wanted to use ggplot to visualize the us object you created in the previous step. Next ggplot needs to know what sort of object to draw. This is done by using the geom_ function followed by a type of geometry. They include point, line, polygon and other geometries such as histograms, boxplots, violin plots for statistics, or contours, rasters, and tiles for three dimensional data. So for this step you used geom_polygon. Next, ggplot needs to know how the data should be displayed. If you create a new code block and type str(us) you can see the structure of the data and a few of the variables. You will notice the dataset contains long (longitude), lat (latitude), group, order, region (the state names), and subregion. So in ggplot you provide a series of aesthetics using aes() to direct ggplot on how to display the data. In this case, x = long, y = lat, and you need to tell it to organize the groups by the category group. If you leave out group for this specific script, ggplot will be unsure what order to draw the polygons and your map will not appear correctly. color = "white" tells ggplot to use white borders for the individual states. What do you think would happen if you change the word color to fill ? In the resulting image, ggplot used the information from your aesthetics to draw the polygons and automate labels for the x and y axes. In a later step you will learn how to customize those labels.

    It may seem as if this is a difficult way to view the data. In other software with a graphical user interface (GUI) you would most likely click open, navigate to the folder containing the data, double-click on that dataset, and then it would appear on your screen. Essentially, every time you click “open” on a GUI interface, it is executing a specific set of scripts to 1.) open the navigation window, 2.) allow the selected file to be imported, and 3.) then display the information on your screen. What you did above in three lines of code was to tell ggplot to 1.) create an object called us and 2.) display it on the screen with some specific parameters. The benefit of completing this in R versus something with a GUI interface is, if you had three more similar datasets to view, you would simply change US to another object and re-run the script. To repeat the process in a GUI interface you would need to repeat all of the steps from the beginning. This might not seem like much for three steps, but what if your visualization had twenty steps, as many do? In R you would still simply change the dataset and run the same script, but in other programs you would need to repeat the same twenty steps for each dataset. Additionally, if a colleague wanted to display some data in the same way, you can either copy and paste the code or type out each of the twenty steps with directions. Which of these seems to be more consistently repeatable? Once you begin to understand the syntax (order or arrangement of words and phrases to form proper scripts) you will be more easily able to interpret sample scripts and fix errors in your own code.

    Question No. 1
    You used ggplot(us) + geom_polygon(aes(x=long, y=lat, group=group), color = "white") to create the visualization in this step. What script would you use to make the same map but with black borders and blue states? Add a code cell below this one, type the script, and run it to view the output. Hint: color = “…..”, fill = “…..”

    1.2 Step Two: The Analysis

    In this step you will organize and display the data in order to prepare it for the final visualization.

    View Directions in ArcGIS Pro

    Now that you have the data displayed on the screen and understand how to access the underlying data, you need to customize the view so you can see the spatial distribution of electric vehicle charging stations in the US. As you may have guessed by now, there are a number of different ways to access the symbology tool needed to change how the data is displayed.

    1. Right-click on ev_data in the table of contents and click Symbology
    2. With ev_data selected in the table of contents click on the Apperance Tab and click the Symbology button
    3. With ev_data selected in the table of contents click on the Symbology tab at the bottom of the right side panel of the screen.

    All three of these methods will show the symbology options in a panel on the right side of the screen. From here you will need to change the Primary Symbology from Single Symbol to Graduated Color. This can also be done by clicking on the drop-down menu for Symbology in the Apperance Tab.

    Symbology

    After selecting Graduated Colors you will have several other options available in the symbology window. In order to sort by the number of electric vehicle charging stations per state you will need to change the Field category to ev_station. Next, in the Method category to Geometric Interval. Because of the range of values, choosing this option will help to balance out the bias of larger values. In the Classes category choose 5. Finally using the drop-down menu next to Color Scheme, select a color option for your visualization.

    Symbology options


    Depending on the color scheme you chose, your screen should now look similar to this:

    Symbology

    On the left in the table of contents beneath the ev_data  layer you will see the range of values represented by each color matching those values for each individual state on your map. At this point you should save your work. This can be done by going to the Project Tab > Save , using the CRTL+S  keyboard shortcut, or using the quick save button Save project  to save your current project.

    Question No. 2
    In this step you used a Graduated Colors  symbology to visualize the data and organized the values using a Geometric Interval method. There are several other options within Method that could have been selected as a display method such as:

    Symbology methods


    Adjusting the Method value, describe how the visualization changes with each of these different options.
    Record your answers and submit at the conclusion of the lab.

    View Directions in QGIS

    Now that you have the data displayed on the screen and understand how to access the underlying data, you need to customize the view so you can see the spatial distribution of electric vehicle charging stations in the US. To begin you will need to control-click (macOS) or right-click (PC) on the ev_data in your layers and click on properties.

    Right Click Properties


    In the resulting window you will need to go to the Symbology tab (1.) in the left-hand menu. In this window you can change the fill of the polygons and change their opacity (or level of transparency). You can also adjust the symbology of your dataset. Those options are available in a selection bar at the top of the window. For this dataset they are:

  • No Symbol
  • No Symbols
  • Single Symbol
  • Single Symbol
  • Categorized
  • Categorized Symbols
  • Graduated
  • Graduated Symbols
  • Rule-based
  • Rule Based Symbols
  • Inverted Polygons
  • Inverted Polygon Symbols
  • 2.5 D
  • 2.5 D Symbols


    For this specific data you will choose Graduated (2.) since the data needs to be displayed by a range of numeric values. Next you will select the ev_station variable (3.) in the dataset. In the drop-down for the Color ramp option you have a number of color options to choose. For this example select Viridis (4.). Do you recall what the range of values for the ev_station data? Because the largest value is greater than 30,000 and the smallest value is around 100, you will need to set the Mode to a logarithmic scale (5.) to properly display the data while avoiding a bias of the larger values. Change the Classes to 6 (6.) and click OK (7.).

    Symbology Properties

    Because the macOS and PC versions are identical only one image is shown.


    Your screen should now look similar to this:

    Graduated Data

    At this point you should save your work. Whether using macOS or PC, on the menu bar go to Project > Save As… and save your project in the folder you create for this exercise.

    Question No. 2
    In this step you used a Graduated symbology to visualize the data and organized the values logarithmically. There were several other options within mode menu.

  • Equal Count (Quantile)
  • Equal Count
  • Equal Interval
  • Equal Interval
  • Logarithmic Scale
  • Logarithmic Scale
  • Natural Breaks (Jenks)
  • Natural BReaks (Jenks)
  • Pretty Breaks
  • Pretty Breaks
  • Standard Deviation
  • Standard Deviation
    Adjusting the mode value, describe how the visualization changes with each of these different options.
    Record your answers and submit at the conclusion of the lab.

    View Directions in R

    Now that you have datasets for electric vehicle charging stations (object = evs) and the continental US (object = us), you need to combined that data to allow for the states to be color coded based on the number of charging stations per state. To do this you will use a function called merge from the base R functions that will allow you to combine the information from the evs and us into a single dataset that contains information from both based on a common variable. So to start you will need to determine what variable(s) are contained within each dataset. You have seen how to examine datasets using both head() and str() already in this exercise. Create a new code block and examine the structure of each dataset. You will see that there is a column for state name in each except they are labeled differently. This is important information you will need to properly merge the datasets.

    To do this you will first create an object (<-) with a new name, then with the merge function set the following arguments:

    • x, which is the first data set
    • y, which is the second dataset
    • by.x, identifies the column to use for the merge in x
    • by.y, identifies the column to use for the merge in y
    • all = TRUE, which tells the function to retain all data

    So your final script will be:

    states <- merge(x = us, y = evs, by.x = "region", by.y = "state", all = TRUE)
    head(states)

    Now you will see the columns for evs and abbreviation included in the us dataset. This new dataset will be what you use to visualize the information in the next step.

    Question No. 2
    Using summary(states) in a new code cell, what are the largest and smallest number of electric vehicle charging stations?

    1.3 Step Three: The Visualization

    You will learn how to create a graphical display of your data that includes cartographic elements such as legend, scale bar, north arrow, etc.

    View directions in ArcGIS Pro

    Now it’s time to turn your data into a map. From the Insert Tab click on the New Layout button New layout button and choose a paper layout. For this exercise you should choose ANSI - Landscape, Letter 8.5” x 11”. This will open a new section where you will add the data, title, legend, north arrow, scale bar, and your name and date. If you have a large enough screen, you can right-click on the new layout Layout tab and select Float. This will create a new window that you can resize while keeping the primary screen open. Otherwise, resize the layout section as necessary by moving your cursor between the two sections to adjust the border.

    Side-by-side Map and Layout

    Whether viewing the new layout in a new window or section on the map page, click on the Insert tab and choose the Map Frame button. From there, select the map that has a representative fraction and has an image of the data from the map view.

    Map Insert Tab

    When placed over the layout our cursor will become cross-hairs (+). Use it to draw the location of the map on the layout.

    Insert the map frame

    Your map will now be imported to the layout. To zoom in or out you can adjust the representative fraction at the bottom of the layout or on the Layout tab use the fixed zoom tools Fixed zoom tools to change the level of zoom.

    Map Layout Tab

    To adjust the location of the data, click the Activate button Navigate Button and use the Explore Button Navigate Button to click and drag and move the data on the map frame on the layout. When finished adjusting the view deactivate the layout by clicking the Close activated map frame button Close activate map frame to return to the map layout. After you have adjusted the zoom and positioning your layout should look like this:

    Map and Layout

    In order to complete a basic map you will need to add a north arrow Add north arrow, scale bar Add scale, legend Add legend, and text Add text to include a title and the name and date of the map creator. Each of these items works essentially the same as adding the map data. When you click on each tool you can use your cursor to draw its location on the map. You will notice with the north arrow and scale bar there is a drop-down menu that allows you to select the specific style.

    Drop-down information for north arrow and scale bar

    Each time you add an element such as a north arrow or scale bar, you will notice the section on the right will provide a number of different options to customize the element. Depending on the element you are adding there will be different buttons such as:

    Options Options button Allows you to make elements visible or locked, change the title of the element, adjust the labels, or add columns
    Display Display button Lets you adjust the border, background, or add a shadow to the element
    Placement Placement button Allows you to fine tune adjust the location of the element on the map and change the appearance and format of the text symbol of the element
    Properties Properties button This is specific to the scale bar and lets you adjust the number of divisions, numbers, marks, and bars of the element
    Arrangement Arrangement button Legend arrangement options allows you to adjust the fitting strategy, word wrap, and spacing of items within the element


    Add element options for north arrow

    These will provide additional customization options for each element. When adding the Legend, notice that the information from the layer is added to the element. While you will examine how to customize all elements in future exercises, for this lab you will edit the names of the layer name and heading for the layer. This will update the information automatically in the legend. To begin, click once on the ev_data layer name in the table of contents. This will select the item. By single clicking an additional time (not double-clicking) it will allow you to directly edit the data.

    Edit layer name and heading


    Rename the layer Charging Stations and rename the ev_station heading to Number per State. Depending on placement and symbology color, your legend should now look like this:

    New legend layer name and heading


    Depending on where you placed your elements and customizations you employed, you should now have a completed map that includes all of the necessary elements discussed above.

    Exercise 2 example map

    Question No. 3
    What is the largest and smallest number of electric vehicle charging stations?

    View directions in QGIS

    Now it’s time to turn your data into a map. From the menu bar in either macOS or PC click Program > New Print Layout. This will open a new window where you will add the data, title, legend, north arrow, scale bar, and your name and date.

    New Print Layout

    It will first ask you to create a print layout title. After you input a title clock OK.

    Name Print Layout

    In the new window you will see a blank layout page. If you control-click (macOS) or right-click (PC) on the page you will see options for Page Properties… that allows you to adjust the page size, orientation (landscape or portrait), or customize the width and height and provide a background color to the layout.There will also be an option to Manage Guides for Page… which will allow you to add or remove Horizontal or Vertical Guides that will help align items on the layout.

    To add your data to the layout you will use the Add map tool Add Map Button that is located in the column of tools on the left side of the screen. When you select this tool and hover over the page layout your cursor will become a plus symbol. You will use this to draw a bounding box on the page layout that will serve as the location for the map data.

    Add Map Box

    Once you have drawn the map box, the information displayed on the map canvas will be added to the print layout. Your screen should now look similar to this:

    Map canvas displayed on print layout

    In order to complete a basic map you will now need to add a north arrow Add North Arrow , scale bar Add Scale Bar , legend Add Legend , and text Add Text  to include a title and the name and date of the map creator. Each of these items works essentially the same as adding the map data. They can also be added through Add Item in the menu bar. There are several other buttons you should familiarize yourself with on the layout page such as:

    Pan Pan Layout The Pan Tool is used to shift the map canvas. This is useful when the canvas is larger than your display due to the level of zoom
    Zoom Layout Zoom The Zoom Tool is used to increase the magnification of the map canvas, but is not used to zoom in on the data
    Move Item Content Move Item Content The Move Item Content Tool is used to move the map information within the bounding box and allows you zoom in and out on the map data
    Select/Move Item Select and Move Item The Select/Move Item Tool is used to move items such as the north arrow on the map canvas
    Lock/Unlock Items Lock and Unlock All Items Locking items keeps any changes from being made to the items on the layout
    Group/Ungroup Items Group and Ungroup Items These tools allow selected items to be grouped in order to remain together when moved
    Raise/Align Items Rearrange and Align Items These tools allow for items to be placed above or below another in their hierarchy or allows selected items to be aligned


    Once you choose the object you want to add, your cursor becomes a plus symbol and you are then able to draw the object in the desired location. Once you have placed each of the items, select any one, and in the control-click (macOS) or right-click (PC) menu choose Item Properties. This will open a new menu to the right of the screen that allows you to edit various properties like the symbol for the north arrow, scale bar units, legend item arrangement, and the text variables for the title, name and date.

    Item Properties Menu

    Take your time to examine the various options within each of the properties menus. As you continue to make maps you will become more familiar with these menus and begin to develop your own style for each item. Hint: do not make the north arrow too large. At this point you should save the project.

    Because the electric vehicle charging station data was organized logarithmically you can see that the values are displayed in scientific notation. Additionally, the display heading is the same as the name of the dataset. So to correct that you will return to the map canvas. If at any point you accidentally close the Print layout you can always open it again by clicking Show Layout Manager Add Scale Bar  on the main toolbar. In the window select the layout you created and click Show.

    Back in the layers area, control-click (macOS) or right-click (PC) on the ev_data layer and go to Properties and the Symbology tab on the left. from there you will see the options you selected earlier in the exercise. In the classes section, you will see three (3) columns of information: Symbol, Values, and Legend. The information in Legend can be edited by simply double-clicking on the text. Edit each legend entry to match the information in the values column. When you have completed click OK.

    Altering legend information in symbology window

    Finally, control-click or right-click on the dataset in layers and click Rename Layer. Give it a name that is representative of the dataset such as “Electric Vehicle Charging Stations”. Now return to your layout. If the information has not been updated, click the Refresh View button Refresh View  on the toolbar. Your layout should update with all of the changes you made in the Symbology Tab. You may also need to adjust the size of the legend now that you have edited the data. This is just one of a number of different ways to edit information for datasets. In future exercises you will examine other editing methods. You should now have a completed map that includes all of the necessary elements discussed above.

    Exercise 1 Final Map

    Question No. 3
    What is the largest and smallest number of electric vehicle charging stations?

    View directions in R

    With this new dataset you are now ready to create a map to examine the distribution of electric vehicle charging stations across the country. In step one you used a very simple script to display the us data.

    ggplot(us) + 
      geom_polygon(aes(x=long, y=lat, group=group), color = "white")

    A similar script would allow you to quickly visualize the data ggplot(states) + geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white"), however, you need to add a number of elements in order to create a map such as a scale bar, north arrow, title, etc. Additionally, you can customize other components to provide a better overall visualization.

    Earlier in the notebook we installed the ggsn package. This package allows you to add “north symbols and scale bars for maps created with ‘ggplot2’ or ‘ggmap’.” So you can build on the script above to create a map of the information in the states dataset. To begin, run the script above with the added fill argument to see the outcome:

    ggplot(states) + geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white")

    One thing you will notice is that the categories are very difficult to distinguish. Because you have wide ranging data in the evs_count column only the largest value is showing. A simple fix to this would be to take the common logarithm of the data to standardize the values by removing the skewness towards larger numbers. The function scale-viridis scales the data and provides a color map designed to be perceived by viewers with common forms of color blindness. So you can add scale_fill_viridis_c(option = "D", trans = "log10") to the script above where:

    • scale_fill_viridis_c is a fill pattern for continuous data
    • option = “D” is the default color option
      • There are five color options available with this function
        • A = magma
        • B = inferno
        • C = plasma
        • D = viridis
        • E = cividis
    • trans = “log10” transforms the data using common logarithm, other options are available; see documentation

    The new script should now look like this:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10")

    Now that you are able to visualize the separations in the data you can add additional information. You can start with customizing the labels, map title, and legend title. This can all be completed by adding a single line of code containing all of the text information for those items:

    ggplot(states) + 
        geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations")

    Feel free to edit the label names and the color option in the script to provide your own customizations. Next you need to add a scale bar and north arrow. To view the available options for the north arrow type northSymbols() into a new code block. The numeric values below each symbol will be used in the script to identify the specific style you choose. Because the north arrow, north, is specifically related to the map data you need to provide the following arguments:

    • dataset
    • symbol, identified by the numerical value from northSymbols()
    • location, indicating where to base the location on the map
    • anchor, coordinates for the symbol position on the map (based off the location)
    • scale, the symbol size as a proportion of the map size

    So your new script will look like:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25))

    In this example, location = "bottomleft" means the location of the north arrow will be based from the bottom left of the symbol and ``anchor = c(x = -70, y = 25)``` is the geographic location on the map to draw the symbol. For example, if the anchors were set at -100 and 40 the symbol would be draw on the Nebraska/Kansas border. Feel free to adjust the anchor points to draw the north arrow in your preferred location.

    Now you need to add a scale bar. Many of the arguments used for the north arrow are duplicated for scalebar

    • dataset
    • location, indicating where to base the location on the map
    • anchor, coordinates for the symbol position on the map (based off the location)
    • distance for each unit of the scale bar
    • unit of measurement such as mi, km, etc.
    • transform (TRUE/FALSE), assumes the coordinates are in decimal degrees
    • model, choice of ellipsoid; which will be discussed later in the semester
    • st.size, scale bar size
    • st.dist, distance between the scale bar and the scale bar’s text, as a proportion of the y axis
    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25)) + 
      scalebar(states, dist = 250, dist_unit = "mi", transform = TRUE, model = "WGS84", location = "bottomleft", st.dist = 0.05, st.size = 2, anchor = c(x=-125,y=27))

    As with all of the other customizations above, feel free to adjust the units, distance, text distance, and size based on your own style.

    Finally, you will need to add text to the map to indicate the name of the person who created the map and the date. In the future you will possibly include references or other text based information. There are a number of different ways you will explore for adding text information to your maps, such as caption = in labs, but for this example you will use annotate(). Similar to the north arrow and scale bar, there will be a:

    • x and y argument to set the location
    • size to indicate the font size
    • label for the text you wish to include; to create a character return to move text to a new line you should use “\n” where you want the text to move to a new line

    Your final script should now look similar to this:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25)) + 
      scalebar(states, dist = 250, dist_unit = "mi", transform = TRUE, model = "WGS84", location = "bottomleft", st.dist = 0.05, st.size = 2, anchor = c(x=-125,y=27)) +
      annotate("text", x = -90, y = 25, label = "Chris Gentry\n August 2021", size = 2)

    There is an exhaustive amount of modifications that can be applied to the map above, but for now you have the minimum information required to create a map of similar kinds of data. In future exercises you will use various function to customize the look of your maps.

    Question No. 3
    How does the dist =  argument in the scalebar function relate specifically to the distance of the scale bar on your map? How would changing the value alter the appearance?

    1.4 Step Four: Your Turn

    After a rash of severe weather over the past few years the Montgomery County Emergency Management Agency has asked you to provide a map detailing the number of reported tornadoes in each Tennessee county over the past several decades. This information will be shared with neighboring counties in middle Tennessee as a part of severe weather education campaign designed to inform communities about the risk of tornadoes in the region. The map should include all of the elements included on your previous map of electric vehicle charging stations such as:

    • Title
    • Scale
    • North Arrow
    • Legend
    • Name/Date of Cartographer

    Software specific directions can be found for each step below. Please submit the answer to the questions you answered above as well as your final tornado map by the due date.

    View directions in ArcGIS Pro

    This portion of the exercise is meant to reinforce the skills you learned in the first part of the lab. The steps to complete your final map will be to:

    1. Download and unzip the tornadoes dataset
    2. Create a new map project
    3. Add the data to your layers
    4. Use the symbology tab to color the counties by number of tornadoes (tornado_co)
    5. Map the data including all the necessary elements added above

    To begin this portion of the exercise you will need to download the tornado dataset. Remember you can use the pop-up tool or the attribute table to examine the information. When you have completed your map, click the Share Tab and click Layout to save your map.

    Export map as image

    You will have a new Export section on the right-side of the screen. In the Properties options change the File Type to *.jpg. This will allow you to add it to your word document and be submitted at the end of this exercise. In Name click the browse button Browse button to save layout to save the layout. It will default to the project folder and you can provide a name to identify the file. When done click Save in the browser window, leave the other options as the default setting, and Export at the bottom of the section.

    Question No. 4
    Which county had the highest number of reported tornadoes?
    Hint: Remember you can sort the data in any column by clicking on the column header.

    View directions in QGIS

    This portion of the exercise is meant to reinforce the skills you learned in the first part of the lab. The steps to complete your final map will be to:

    1. Download and unzip the tornadoes dataset
    2. Create a new map project
    3. Add the data to your layers
    4. Use the symbology tab to color the counties by number of tornadoes (tornado_co)
    5. Map the data including all the necessary elements added above

    To begin this portion of the exercise you will need to download the tornado dataset. Remember you can use the identity tool or the attribute table to examine the information. When you have completed your map, click Project > Export as Image… on PC or Project > Import/Export > Export Map to Image… on macOS to save your map as a *.jpg. This will allow you to add it to your word document and be submitted at the end of this exercise.

    Export map as image

    Question No. 4
    Which county had the highest number of reported tornadoes?
    Hint: Remember you can sort the data in any column by clicking on the column header.

    View directions in R

    This portion of the exercise is meant to reinforce the skills you learned in the first part of the lab. The steps to complete your final map will be to:

    1. Create an object from the tornadoes dataset
    2. Obtain a dataset of Tennessee counties
    3. Determine which columns can be used to merge the datasets
    4. Map out the data using ggplot

    To begin this portion of the exercise you will need this URL to the comma delimited dataset:

    https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/tn_tornadoes.csv

    This data represents the number of reported tornadoes in each county from 1950-2020. As in step one of the exercise, you can use the <- operator to create a new object and the read.csv() function with the link to the dataset to import the data. Remember you can use head() or str() to examine the information.

    To obtain county information for the State of Tennessee you should use the following script:

    tn <- map_data('county', region = "tennessee")
    head(tn)

    If you search for map_data in the ggplot2 documentation you will find an example of a script used to isolate information for the State of Iowa that can be adapted for any state in the dataset. Remember when working with scripts, Google is your friend! All it requires is asking the correct question to find some example code online that can help guide you. There are numerous possible answers to the same problem so don’t hesitate to try other methods.

    Using the example code from step two, you will need to merge the two datasets into a new object based on a common variable such as Hint…hint county name.

    Finally, by adapting the ggplot code in step four, you can map the information for tornado_count for each county in Tennessee. In order to limit the scope of your map to just the state you should add the following script to your modified ggplot code from above:

    coord_fixed(xlim = c(-90,-82), ylim = c(35, 37))

    The coord_fixed() function limits the axes based on specified values. The values are based on the units of measure of the data. In this can you see where the x axis is limited (xlim) from -82° to -90° west longitude and the y axis is limited (ylim) from 35° to 37° north latitude. If you omit this script your map will likely have a “smashed” appearance. For creating maps in R it is generally advisable to set the x and y coordinates to ensure proper display of your data. Remember you will need to adjust the anchor points of your name and date text, north arrow and scale bar to fit the current map view. Additionally, the title and legend text should also reflect the information depicted on your map.

    Question No. 4
    Which county had the highest number of reported tornadoes?
    Type subset(tn_tornadoes, tornado_count == max(tornado_count)) into a new code cell or use Google to search for a county map of Tennessee to determine county locations on your map.
    Hint: Replace tn_tornadoes in the code above with the object you created by merging the tornado and counties datasets.

    2 The Write-Up

    The Montgomery County Emergency Management Agency has asked you to provide a map detailing the number of reported tornadoes in each Tennessee county over the past several decades. Based on the map you create above, complete a lab write-up that addresses the following questions:

    • Provide the names of the five (5) counties that recorded the most tornadoes during that time frame
    • Describe which regions of Tennessee had the fewest reported tornadoes
    • Inform MCEMA which metropolitan regions could be most impacted by future severe weather events

    When complete, send a link to your Colab Notebook or email the word document or PDF with answers to Questions 1-4 and your completed map.

    LS0tDQp0aXRsZTogIkV4ZXJjaXNlIDI6IEdldHRpbmcgdG8ga25vdy4uLiA8YnI+PHNtYWxsPkdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU3lzdGVtcyAxIExhYjwvc21hbGw+PC9icj4iDQphdXRob3I6ICJHRU9HIDMxNTAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgcm93cy5wcmludDogMTANCiAgICB0aGVtZTogY29zbW8NCiAgICBoaWdobGlnaHQ6IGJyZWV6ZWRhcmsNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KICBtb2RlOiBnZm0NCi0tLQ0KDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogNDBweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5hdXRob3IgeyANCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi56b29tIHsNCiAgdHJhbnNmb3JtLW9yaWdpbjogNDAlIDUwJSAwOw0KICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gLjJzOw0KICBtYXJnaW46IDAgYXV0bzsNCn0NCg0KLnpvb20gaW1new0KCXdpZHRoOmF1dG87DQoJaGVpZ2h0OmF1dG87DQp9DQoNCi56b29tOmhvdmVyIHsNCiAgdHJhbnNmb3JtOiBzY2FsZSgyKTsNCn0NCg0KdGgsIHRkIHtwYWRkaW5nOiA1cHg7fQ0KDQo8L3N0eWxlPg0KYGBgDQoNCjxocj48L2hyPg0KDQpGb3IgdGhpcyBmaXJzdCBleGVyY2lzZSB5b3Ugd2lsbCBiZSBleGFtaW5pbmcgaG93IHlvdSBjYW4gdXNlIHZhcmlvdXMgc29mdHdhcmUgZm9yIGdlb3NwYXRpYWwgYW5hbHlzaXMgYW5kIGdyYXBoaWNhbCBkaXNwbGF5IG9mIHNwYXRpYWwgZGF0YS4gQmVjYXVzZSBvZiB0aGUgdmFyaWV0eSBhbmQgYXZhaWxhYmlsaXR5IG9mIG9wZXJhdGluZyBzeXN0ZW1zIGluIHVzZSB0b2RheSwgZWFjaCBvZiB0aGUgZXhlcmNpc2VzIGluIHRoaXMgY291cnNlIGNhbiBiZSBjb21wbGV0ZWQgaW4gZWl0aGVyICoqW0FyY0dJUyBQcm9de3N0eWxlPSJjb2xvcjojZmY0NTAwIn0qKiwgKipbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0qKiwgb3IgKipbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0qKi4gRWFjaCBvZiB0aGVzZSBzb2Z0d2FyZSBoYXZlIHRoZWlyIHBybydzIGFuZCBjb24ncyBidXQgZm9yIHNpbXBsaWNpdHkgcHVycG9zZXMgaGVyZSBpcyBhIHRhYmxlIHRoYXQgbWlnaHQgc3VnZ2VzdCB3aGljaCBzb2Z0d2FyZSB3b3VsZCBiZSBiZXN0IGZvciB5b3U6DQoNCnwgW0FyY0dJUyBQcm9de3N0eWxlPSJjb2xvcjojZmY0NTAwIn0gfCBbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0gfCBbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0gfA0KfCAtLS0gfCAtLS0gfCAtLS0gfA0KfCBBdmFpbGFibGUgb24gPHU+V2luZG93cyBQQyBPbmx5PC91PiB8IEF2YWlsYWJsZSBmb3IgUEMsIE1hYywgb3IgTGludXggKGxpbWl0ZWQpIHwgQXZhaWxhYmxlIGZvciBQQywgTWFjLCBMaW51eCwgQ2hyb21lT1MsIGlPUywgb3IgQW5kcm9pZCB2aWEgd2ViIG1vZGVybiBicm93c2VyfA0KfCBBdmFpbGFibGUgYnkgc3Vic2NyaXB0aW9uIG9ubHkgfCBPcGVuIFNvdXJjZSB8IE9wZW4gU291cmNlIHwNCnwgR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlIHdpdGggYnVpbHQtaW4gZnVuY3Rpb25hbGl0eSBmb3IgUHl0aG9uOyBhZGQtb25zIGF2YWlsYWJsZSBmb3Igc3RhdGlzdGljYWwgbGFuZ3VhZ2VzIHwgR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlIHdpdGggYnVpbHQtaW4gZnVuY3Rpb25hbGl0eSBmb3IgUHl0aG9uOyB1c2Ugb2YgcGx1Zy1pbnMgZm9yIG90aGVyIGxhbmd1YWdlcyBhbmQgYW5hbHlzZXMgfCBTY3JpcHRpbmcgbGFuZ3VhZ2UsIG1vc3RseSB1c2VkIGZvciBzdGF0aXN0aWNhbCBwdXJwb3NlOyBwYWNrYWdlcyBleHBhbmQgaXRzIHVzZSB0byBvdGhlciBhcHBsaWNhdGlvbnMgc3VjaCBhcyBnZW9zcGF0aWFsIGFuYWx5c2VzIHwNCnwgV2lkZWx5IHVzZWQgaW4gYWNhZGVtaWEsIGdvdmVybm1lbnQsIGFuZCBpbmR1c3RyeSBqb2JzIHwgV2lkZWx5IHVzZWQgaW4gYWNhZGVtaWEgYW5kIGluZHVzdHJ5IHwgUHJlZG9taW5hbnRseSB1c2VkIGluIGFjYWRlbWlhLCByZXNlYXJjaCwgYW5kIHNwZWNpYWxpemVkIGluZHVzdHJ5IGpvYnMgfA0KSGVscCBhdmFpbGFibGUgYXQgW0VTUkkuY29tXShodHRwczovL3Byby5hcmNnaXMuY29tL2VuL3Byby1hcHAvbGF0ZXN0L2hlbHAvbWFpbi93ZWxjb21lLXRvLXRoZS1hcmNnaXMtcHJvLWFwcC1oZWxwLmh0bSkgYW5kIHRocm91Z2ggdmFyaW91cyBvdXRsZXRzIHZpYSBhIGdvb2dsZSBzZWFyY2ggfCBIZWxwIGF2YWlsYWJsZSBhdCBbUUdJUy5vcmddKGh0dHBzOi8vZG9jcy5xZ2lzLm9yZy8zLjE2L2VuL2RvY3MvdXNlcl9tYW51YWwvKSBhbmQgdGhyb3VnaCBzaXRlcyBsaWtlIHN0YWNrb3ZlcmZsb3cuY29tIG9yIG90aGVyIHNpdGVzIHZpYSBnb29nbGUgc2VhcmNoIHwgSGVscCBhdmFpbGFibGUgdGhyb3VnaCBpbmRpdmlkdWFsIHBhY2thZ2UgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9hdmFpbGFibGVfcGFja2FnZXNfYnlfbmFtZS5odG1sKSBhbmQgc2l0ZXMgbGlrZSBzdGFja292ZXJmbG93LmNvbSBvciBvdGhlciBzaXRlcyB2aWEgZ29vZ2xlIHNlYXJjaA0KDQpGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgY291cnNlLCB5b3UgY2FuIGNvbXBsZXRlIHRoZSBsYWJvcmF0b3J5IGV4ZXJjaXNlcyBpbiBhbnkgb2YgdGhlc2Ugc29mdHdhcmUuIFRoZXJlIHdpbGwgYmUgZHJvcC1kb3duIG1lbnVzIGluIGV2ZXJ5IGxhYiBjb2xvci1jb2RlZCBmb3IgdGhlIHRocmVlIHNvZnR3YXJlLiBVbHRpbWF0ZWx5LCB5b3Ugd2lsbCBoYXZlIGFjY2VzcyB0byBhbGwgb2YgdGhpcyBtYXRlcmlhbCBkdXJpbmcgYW5kIGFmdGVyIHRoZSBjb3Vyc2UgYW5kIHdoaWxlIHRoZSBzdGVwcyBtaWdodCBiZSBkaWZmZXJlbnQgYmV0d2VlbiBlYWNoIHZlcnNpb24gdGhlIG91dGNvbWVzIHdpbGwgYmUgdGhlIHNhbWUuIFNvIGlmIHlvdSBjaG9vc2UgdG8gY29tcGxldGUgdGhlIGNvdXJzZSB3aXRoIG9uZSBzb2Z0d2FyZSB5b3UgY2FuIGFsd2F5cyBnbyBiYWNrIGFuZCBjb21wbGV0ZSB0aGUgd29yayBpbiBhbm90aGVyIHNvZnR3YXJlIGluIHlvdXIgb3duIHRpbWUuDQoNCldoaWxlIGFsbCBvZiB0aGUgc29mdHdhcmUgd2lsbCBiZSBhdmFpbGFibGUgb24gdGhlIGNvbXB1dGVycyBpbiBNY0NvcmQgMjEwLCBpZiB5b3UgY2hvb3NlIHRvIHVzZSAqKltBcmNHSVMgUHJvXXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9KiogeW91IHdpbGwgbmVlZCB0byBjb250YWN0IHRoZSBBUFNVIEdJUyBDZW50ZXIgd2l0aCB5b3VyIHN0dWRlbnQgaW5mb3JtYXRpb24gdG8gb2J0YWluIGEgb25lIHllYXIgbGljZW5zZSBmb3IgeW91ciBwZXJzb25hbCBjb21wdXRlci4gKipbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0qKiBpcyBhdmFpbGFibGUgZm9yIGRvd25sb2FkIHVzaW5nIHRoaXMgKipbbGlua10oaHR0cHM6Ly9xZ2lzLm9yZy9lbi9zaXRlL2ZvcnVzZXJzL2Rvd25sb2FkLmh0bWwpe3N0eWxlPSJjb2xvcjogIzAwNjQwMCJ9KiouIElmIHlvdSBhcmUgY29tcGxldGluZyB0aGUgY291cnNlIGluICoqW1Jde3N0eWxlPSJjb2xvcjogIzY0OTVFRCJ9KiogeW91IHdpbGwgbm90IG5lZWQgdG8gaW5zdGFsbCBhbnkgc29mdHdhcmUsIGhvd2V2ZXIgeW91IHdpbGwgbmVlZCBhIFtHb29nbGUgYWNjb3VudF0oaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL3NpZ251cC92Mi93ZWJjcmVhdGVhY2NvdW50KSBhbmQgYWNjZXNzIHRvIHRoZSBbQ2hyb21lIGJyb3dzZXJdKGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vY2hyb21lLykuIFdoZW4gdXNpbmcgKipbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0qKiB5b3Ugd2lsbCBiZSBjb21wbGV0aW5nIGFsbCBvZiB0aGUgbGFiIGV4ZXJjaXNlcyBpbiB0aGUgW0dvb2dsZSBDb2xhYm9yYXRvcnldKGh0dHBzOi8vY29sYWIucmVzZWFyY2guZ29vZ2xlLmNvbS8pIGFuZCB3aWxsIGFjY2VzcyBldmVyeXRoaW5nIHlvdSBuZWVkIGZyb20gdGhlIGV4ZXJjaXNlIHBhZ2VzIG9uIF9HaXRIdWJfLg0KDQpNb3JlIGluZm9ybWF0aW9uIGZvciBlYWNoIHNvZnR3YXJlIGFuZCB0aGUgc3RlcHMgdG8gY29tcGxldGUgdGhpcyBleGVyY2lzZSBjYW4gYmUgZm91bmQgYmVsb3cuIEJlIHN1cmUgdG8gZm9sbG93IHRoZSBjb2xvci1jb2RlZCBkcm9wLWRvd24gZm9yIHRoZSBzcGVjaWZpYyBzb2Z0d2FyZSB5b3UgYXJlIHVzaW5nIGZvciB0aGUgbGFiLiANCg0KPGRldGFpbHM+DQo8c3VtbWFyeT48YmlnPlZpZXcgaW5mb3JtYXRpb24gZm9yIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQo8Yj5bQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifTwvYj4gaXMgYSBwcm9wcmlldGFyeSBzb2Z0d2FyZSBmcm9tIFtFU1JJXShodHRwczovL3d3dy5lc3JpLmNvbS9lbi11cy9ob21lKS4gU3R1ZGVudCBhY2Nlc3MgaXMgYXZhaWxhYmxlIGluIE1jQ29yZCAyMTAgYW5kIHNldmVyYWwgb3RoZXIgY29tcHV0ZXIgbGFicyBvbiBjYW1wdXMuIElmIHlvdSB3aXNoIHRvIG9idGFpbiB0aGUgc29mdHdhcmUgZm9yIHVzZSBvbiB5b3VyIHBlcnNvbmFsIGNvbXB1dGVyIChXaW5kb3dzLWJhc2VkIFBDIG9ubHkpIHlvdSB3aWxsIG5lZWQgdG8gY29udGFjdCB0aGUgW0FQU1UgR0lTIENlbnRlcl0oaHR0cHM6Ly93d3cuYXBzdWdpcy5vcmcvKSBhdCA2MDEgTiAybmQgU3QsIENsYXJrc3ZpbGxlLCBUTiAzNzA0MCwgKDkzMSkgMjIxLTc1MDAuIFBsZWFzZSBoYXZlIHlvdXIgQVBTVSBzdHVkZW50IElEIGFuZCBBIyBhdmFpbGFibGUgZm9yIHZlcmlmaWNhdGlvbiBwcmlvciB0byBvYnRhaW5pbmcgYSBsaWNlbnNlLiBQbGVhc2UgY29udGFjdCB0aGUgR0lTIENlbnRlciBpZiB5b3UgaGF2ZSBhbnkgaXNzdWVzIGRvd25sb2FkaW5nIG9yIGluc3RhbGxpbmcgdGhlIHNvZnR3YXJlLg0KDQo8L2RldGFpbHM+DQo8aHI+PC9ocj4NCg0KPGRldGFpbHM+DQo8c3VtbWFyeT48YmlnPlZpZXcgaW5mb3JtYXRpb24gZm9yIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0gPC9iPjwvYmlnPjwvc3VtbWFyeT4NCg0KSWYgeW91IHdpbGwgYmUgdXNpbmcgPGI+W1FHSVNde3N0eWxlPSJjb2xvcjogIzAwNjQwMCJ9PC9iPiBmb3IgdGhlIGV4ZXJjaXNlcyB5b3Ugd2lsbCBuZWVkIHRvIGhhdmUgdGhlIHNvZnR3YXJlIGluc3RhbGxlZCBvbiB5b3VyIGNvbXB1dGVyLiAqKlFHSVMqKiBpcyBhdmFpbGFibGUgZm9yIFBDcywgTWFjLCBhbmQgTGludXggY29tcHV0ZXJzLiBZb3UgY2FuIGZpbmQgdGhlIGFwcHJvcHJpYXRlIGRvd25sb2FkIGZvciB5b3VyIG9wZXJhdGluZyBzeXN0ZW0gaGVyZToNCg0KLSBbUEMgdmVyc2lvbiwgMy4xNl0oaHR0cHM6Ly9xZ2lzLm9yZy9kb3dubG9hZHMvUUdJUy1PU0dlbzRXLTMuMTYuNi0xLVNldHVwLXg4Nl82NC5leGUpDQotIFttYWNPUyB2ZXJzaW9uLCAzLjE2XShodHRwczovL3FnaXMub3JnL2Rvd25sb2Fkcy9tYWNvcy9xZ2lzLW1hY29zLWx0ci5kbWcpDQotIFtMaW51eCB2ZXJzaW9uLCAzLnhdKGh0dHBzOi8vcWdpcy5vcmcvZW4vc2l0ZS9mb3J1c2Vycy9hbGxkb3dubG9hZHMuaHRtbCNsaW51eCkNCg0KV2hlbiBpbnN0YWxsaW5nIG9uIF9tYWNPU18gZm9yIHRoZSBmaXJzdCB0aW1lIHlvdSBtYXkgbmVlZCB0byBnbyB0byBfU3lzdGVtcyBQcmVmZXJlbmNlcyA+IFNlY3VyaXR5IGFuZCBQcml2YWN5XyBhbmQgb24gdGhlIF9HZW5lcmFsXyB0YWIgIkFsbG93IGFwcHMgZG93bmxvYWRlZCBmcm9tIiBfQXBwIFN0b3JlIGFuZCBpZGVudGlmaWVkIGRldmVsb3BlcnNfIGFuZCBjbGljayBfT3BlbiBBbnl3YXlfLiBQbGVhc2UgY29udGFjdCB5b3VyIGluc3RydWN0b3IgaWYgeW91IGhhdmUgYW55IGlzc3VlcyBkb3dubG9hZGluZyBvciBpbnN0YWxsaW5nIHRoZSBzb2Z0d2FyZS4NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBpbmZvcm1hdGlvbiBmb3IgPGI+IFtSXXtzdHlsZT0iY29sb3I6ICM2NDk1RUQifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCllvdSB3aWxsIGJlIGNvbXBsZXRpbmcgdGhlIDxiPltSXXtzdHlsZT0iY29sb3I6ICM2NDk1RUQifTwvYj4gcG9ydGlvbiBvZiBlYWNoIGV4ZXJjaXNlIHVzaW5nIHRoZSBfW0dvb2dsZSBDb2xhYm9yYXRvcnkgRXhlY3V0YWJsZSBFbnZpcm9ubWVudF0oaHR0cHM6Ly9jb2xhYi5yZXNlYXJjaC5nb29nbGUuY29tLylfLiBDb2xhYm9yYXRvcnksIG9yIF8iY29sYWIiXyBmb3Igc2hvcnQsIGlzIGJhc2VkIG9uIHRoZSBwb3B1bGFyIEp1cHl0ZXIgTm90ZWJvb2tzIGFuZCBhbGxvd3MgeW91IHRvIHdyaXRlIGFuZCBleGVjdXRlICoqUioqIG9yIF9QeXRob25fIGluIHlvdXIgYnJvd3Nlciwgd2l0aDoNCg0KLSBaZXJvIGNvbmZpZ3VyYXRpb24gcmVxdWlyZWQNCi0gRnJlZSBhY2Nlc3MgdG8gR1BVcw0KLSBFYXN5IHNoYXJpbmcNCg0KRWFjaCBfY29sYWJfIG5vdGVib29rIGlzIHNlcGFyYXRlZCBpbnRvIGNvZGUgY2VsbHMgYW5kIHRleHQgY2VsbHMuIEEgY29kZSBjZWxsIGlzIHVzZWQgdG8gd3JpdGUgYW5kIGV4ZWN1dGUgYSBzY3JpcHQgaW50ZXJhY3RpdmVseS4gRWFjaCB0ZXh0IGNlbGwgdXNlcyBzaW1wbGUgW21hcmtkb3duXShodHRwczovL3d3dy5tYXJrZG93bmd1aWRlLm9yZy8pIHN5bnRheCBmb3IgY3JlYXRpbmcgcGxhaW4gdGV4dCBpbmZvcm1hdGlvbi4gWW91IGNhbiBlYXNpbHkgc2hhcmUgdGhlIG5vdGVib29rIGxpa2Ugb3RoZXIgR29vZ2xlIERyaXZlIGJhc2VkIGRvY3VtZW50cyBieSBjbGlja2luZyB0aGUgIlNoYXJlIiBsaW5rIGluIHRoZSB1cHBlciByaWdodC1oYW5kIHBvcnRpb24gb2YgdGhlIHdpbmRvdy4NCg0KQmVmb3JlIGJlZ2lubmluZyBlYWNoIGV4ZXJjaXNlIHVzaW5nICoqUioqLCB5b3Ugd2lsbCBuZWVkIHRvIG9wZW4gdGhlIFtFeGVyY2lzZSBDb2xhYiBOb3RlYm9va10oaHR0cHM6Ly9naXRodWJ0b2NvbGFiLmNvbS9jaHJpc21nZW50cnkvR0lTLUV4ZXJjaXNlLTIvYmxvYi9tYWluL0dJUzFfRVgyLmlweW5iKSBhbmQgYWx0ZXIgdGhlIFVSTCB0byB2aWV3L2VkaXQgdGhlIGZpbGUgaW4gY29sYWIuIFRvIGRvIHRoaXMgeW91IHdpbGwgbmF2aWdhdGUgdG8gdGhlIGV4ZXJjaXNlJ3MgR2l0SHViIHBhZ2U7IGluIHRoaXMgY2FzZSBbaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTJdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc21nZW50cnkvR0lTMS1FeGVyY2lzZS0yKS4gSW4gdGhlIGxpc3Qgb2YgZm9sZGVycyBhbmQgZmlsZXMgeW91IHdpbGwgZmluZCBhIGZpbGUgdGhhdCB3aWxsIGFsd2F5cyBiZSBpZGVudGlmaWVkIGFzIF9HSVMxX0VYXyBmb2xsb3dlZCBieSB0aGUgZXhlcmNpc2UgbnVtYmVyIGFuZCBhIF8uaXB5bmJfIGZpbGUgZXh0ZW5zaW9uLiBTbyBmb3IgdGhpcyBleGVyY2lzZSBpdCB3aWxsIGJlIFtHSVMxX0VYMi5pcHluYl0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvYmxvYi9tYWluL0dJUzFfRVgyLmlweW5iKQ0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9yLWdpdGh1Yi1pcHktbG9jYXRpb24ucG5nIiBhbHQ9IkZpbmRpbmcgdGhlIEdvb2dsZSBDb2xhYiBmaWxlIG9uIEdpdEh1YiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCldoZW4geW91IGxvY2F0ZSB0aGUgZmlsZSwgY2xpY2sgb24gdGhlIG5hbWUgdG8gb3BlbiB0aGUgX2lweV8gbm90ZWJvb2suIEluIHRoZSByZXN1bHRpbmcgd2luZG93LCBjbGljayBvbiB0aGUgVVJMIGFuZCBpbnNlcnQgKip0b2NvbGFiKiogaW1tZWRpYXRlbHkgYWZ0ZXIgX2dpdGh1Yl8gaW4gdGhlIGFkZHJlc3MuIFNvIHRoZSBuZXcgVVJMIGZvciB0aGlzIGV4ZXJjaXNlIHNob3VsZCBub3cgcmVhZDo8YnI+IGBgYGh0dHBzOi8vZ2l0aHVidG9jb2xhYi5jb20vY2hyaXNtZ2VudHJ5L0dJUy1FeGVyY2lzZS0yL2Jsb2IvbWFpbi9HSVMxX0VYMi5pcHluYmBgYCANCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1naXRodWItdG9jb2xhYi5wbmciIGFsdD0iQ29udmVydGluZyBpcHkgZmlsZSB0byBjb2xhYiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCkNsaWNrIGVudGVyL3JldHVybiBhbmQgdGhlIGZpbGUgc2hvdWxkIG5vdyBvcGVuIGluc2lkZSBvZiBfQ29sYWJfLiBZb3VyIHNjcmVlbiBtaWdodCBoYXZlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IGFwcGVhcmFuY2UsIGJ1dCB5b3Ugc2hvdWxkIHNlZSB0aGUgRXhlcmNpc2UgMiwgR0lTIDEgaGVhZGVyIGluZGljYXRpbmcgeW91IGFyZSBpbiB0aGUgY29ycmVjdCBub3RlYm9vay4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1jb2xhYi5wbmciIGFsdD0iQ29udmVydGluZyBpcHkgZmlsZSB0byBjb2xhYiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCkVhY2ggdGltZSB5b3Ugb3BlbiB0aGVzZSBjb2xhYiBub3RlYm9va3MsIG9yIGlmIHlvdSBoYXZlIG5vdCBpbnRlcmFjdGVkIHdpdGggdGhlIG5vdGVib29rIGZvciBhbiBleHRlbmRlZCBwZXJpb2Qgb2YgdGltZSwgeW91IHdpbGwgbmVlZCB0byBtYWtlIHN1cmUgdGhlIGVudmlyb25tZW50IGlzIGNvbm5lY3RlZCBhbmQgYWxsIG9mIHRoZSBzYW1wbGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi4gVG8gZG8gdGhpcyBnbyB0byBfUnVudGltZSA+IFJ1biBhbGxfIChvciBjbGljayBDUlRMK0Y5KSBhbmQgcnVuIHRoZSBub3RlYm9vay4gVGhpcyBtYXkgdGFrZSBhIG1vbWVudCB0byBjb21wbGV0ZSBzbyBiZSBwYXRpZW50IHVudGlsIHRoZSBsYXN0IGNvZGUgY2VsbCBoYXMgYmVlbiBleGVjdXRlZC4gWW91IHNob3VsZCBzZWUgYSBncmVlbiBjaGVjayBtYXJrIHdpdGggYW4gYWxsb2NhdGlvbiBvZiBSQU0gYW5kIERpc2sgYXMgc2hvd24gYnkgaG9yaXpvbnRhbCBiYXJzIHdoaWNoIHdpbGwgaW5kaWNhdGUgeW91IGFyZSBjb25uZWN0ZWQuIEluIGVhY2ggc2VjdGlvbiBvZiBjb2RlIHRoZXJlIGlzIGEgKipSdW4gY2VsbCoqICZuYnNwOzxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItcnVuLWNvZGUucG5nIiBhbHQ9IlJ1biBjZWxsIGJ1dHRvbiIgd2lkdGg9IjE1IiBoZWlnaHQ9IjE1Ij4gYnV0dG9uIHRoYXQgd2lsbCBhbGxvdyB5b3UgdG8gcnVuIHRoZSBpbmRpdmlkdWFsIGNvZGUgY2VsbHMuIFRoaXMgYnV0dG9uIHdpbGwgaGF2ZSBhIHJvdGF0aW5nIGxvYWRpbmcgc3ltYm9sIDxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItbG9hZGluZy5wbmciIGFsdD0iUnVuIGNlbGwgYnV0dG9uIiB3aWR0aD0iMTUiIGhlaWdodD0iMTUiPiB3aGlsZSB0aGUgY29kZSBjZWxsIGlzIGJlaW5nIGV4ZWN1dGVkLiBPbmNlIGl0IGlzIGNvbXBsZXRlIHRoZSBib3ggd2lsbCByZXR1cm4gdG8gdGhlIHJ1biBzdGF0ZSBhbmQgdGhlcmUgbWF5IGJlIGFuIG91dHB1dCB2aXNpYmxlIGRlcGVuZGluZyBvbiB0aGUgc2NyaXB0LiBZb3UgY2FuIGFkZCB5b3VyIG93biB0ZXh0IG9yIGNvZGUgY2VsbHMgdG8gYSBub3RlYm9vayBzaW1wbHkgYnkgbW92aW5nIHlvdXIgY3Vyc29yIHNsb3dseSBvdmVyIHRoZSBub3RlYm9vayB0byByZXZlYWwgdGhlIGNvZGUvdGV4dCBvcHRpb24gYmFyIG9yIGJ5IGdvaW5nIHRvIF9JbnNlcnQgPiBDb2RlIGNlbGwvVGV4dCBjZWxsXy4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1jb2xhYi1jb2RlLXRleHQucG5nIiBhbHQ9IkFkZGluZyBUZXh0IG9yIENvZGUgQmxvY2tzIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPg0KPGJyPg0KQnkgY2xpY2tpbmcgd2l0aGluIGVhY2ggY29kZSBvciB0ZXh0IGNlbGwgeW91IGNhbiBlZGl0IHRoZSBjb250YWlucyBhbmQgYWRqdXN0IHRoZSBwcm9wZXJ0aWVzIHVzaW5nIHRoZSB2YXJpb3VzIHByZXNldCBvcHRpb24gY29udHJvbHMuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItYmxvY2stc2V0dGluZ3MucG5nIiBhbHQ9IkVkaXQgYmxvY2sgcHJvcGVydGllcyIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCllvdSBzaG91bGQgcHJhY3RpY2UgYWRkaW5nIGFuZCByZW1vdmluZyBjZWxscywgZWRpdGluZyB0aGVpciBjb250ZW50LCBhbmQgcmVhcnJhbmdpbmcgdGhlIG9yZGVyIG9mIHRoZSBjZWxscy4gVGhpcyB3aWxsIGhlbHAgZmFtaWxpYXJpemUgeW91IHdpdGggbm90ZWJvb2sgdG9vbHMgYW5kIGFsbG93IHlvdSB0byBtYW5pcHVsYXRlIG5vdGVib29rcyBpbiB0aGVzZSBleGVyY2lzZXMgYW5kIGNyZWF0ZSB5b3VyIG93biBub3RlYm9va3MgaW4gdGhlIGZ1dHVyZS4NCg0KRm9yIGVhY2ggbmV3IGV4ZXJjaXNlIHRoZXJlIHdpbGwgYmUgYSBjb2xhYiBub3RlYm9vayBhdmFpbGFibGUuIFdpdGhpbiB0aGUgbm90ZWJvb2sgd2lsbCBiZSBzYW1wbGUgY29kZSBmb3IgeW91IHRvIHJ1biwgY29kZSBjZWxscyBmb3IgeW91IHRvIGNvbXBsZXRlIGFzIHBhcnQgb2YgdGhlIGV4ZXJjaXNlIGFuZCBxdWVzdGlvbnMgdG8gYmUgYW5zd2VyZWQgd2l0aGluIGxhYmVsZWQgdGV4dCBjZWxscy4gRGV0YWlsZWQgZGlyZWN0aW9ucyB3aWxsIGJlIGF2YWlsYWJsZSBvbiB0aGUgaW5kaXZpZHVhbCBleGVyY2lzZSB3ZWJwYWdlLiBFYWNoIGNvbXBsZXRlZCBleGVyY2lzZSB3aWxsIGhhdmUgY29tcGxldGVkIGNvZGUgYW5kIHF1ZXN0aW9uIHNlY3Rpb25zIGFuZCB0aGUgbm90ZWJvb2sgbGluayBzaGFyZWQgZm9yIGEgZ3JhZGUuDQoNCjwvZGV0YWlscz4NCg0KIyBUaGUgSW50cm9kdWN0aW9uDQoNClRoZSBUZW5uZXNzZWUgVmFsbGV5IEF1dGhvcml0eSAoVFZBKSBhbmQgVGVubmVzc2VlIERlcGFydG1lbnQgb2YgRW52aXJvbm1lbnQgYW5kIENvbnNlcnZhdGlvbiAoVERFQykgYXJlIGNvbnNpZGVyaW5nIGEgcGFydG5lcnNoaXAgdG8gaW5jcmVhc2UgdGhlIG51bWJlciBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIGFjcm9zcyB0aGUgc3RhdGUuIFdpdGggZGVzdGluYXRpb25zIHN1Y2ggYXMgTmFzaHZpbGxlLCBNZW1waGlzLCBHYXRsaW5idXJnIGFuZCB0aGUgR3JlYXQgU21va3kgTW91bnRhaW5zLCBCcmlzdG9sIE1vdG9yIFNwZWVkd2F5LCBTaWduYWwgTW91bnRhaW4gYW5kIHRoZSBUZW5uZXNzZWUgQXF1YXJpdW0sIHRvdXJpc20gaXMgYSBtYWpvciBwYXJ0IG9mIHRoZSBzdGF0ZSdzIGVjb25vbXkuIFNvIGFjY29tbW9kYXRpbmcgcmVzaWRlbnRzIGFuZCB2aXNpdG9ycyB3aXRoIGVsZWN0cmljIHZlaGljbGVzIGFzIHdlbGwgYXMgY3JlYXRpbmcgYSBuZXR3b3JrIGZvciB0aG9zZSB0cmF2ZWxpbmcgdGhlIHN0YXRlcyBtYWpvciBpbnRlcnN0YXRlcyAoSS02NSwgSS00MCwgSS0yNCwgSS03NSwgZXRjLikgaXMgb2YgdXRtb3N0IGltcG9ydGFuY2UuIA0KDQpUREVDIHNheXMgdGhpcyBuZXR3b3JrIG9mIGNoYXJnaW5nIHN0YXRpb25zIHdpbGwgYWxzbyBwcm9tb3RlIGVsZWN0cmljIHZlaGljbGUgZ3Jvd3RoIGJ5IGdpdmluZyBkcml2ZXJzIGNvbmZpZGVuY2UgdGhleSB3aWxsIGhhdmUgZWFzeSBhY2Nlc3MgdG8gcmVmdWVsaW5nIHdoaWxlIGF3YXkgZnJvbSBob21lLCBlbGltaW5hdGluZyBzby1jYWxsZWQg4oCccmFuZ2UgYW54aWV0eeKAnSB0aGF0IGtlZXBzIG1hbnkgY29uc3VtZXJzIGZyb20gY29uc2lkZXJpbmcgZWxlY3RyaWMgdmVoaWNsZXMgYXMgdmlhYmxlIHRyYW5zcG9ydGF0aW9uLiBUVkEgc2F5cyBlbGVjdHJpYyB2ZWhpY2xlIGFkb3B0aW9uIHdpbGwgc3B1ciBqb2JzIGFuZCBlY29ub21pYyBpbnZlc3RtZW50IGluIHRoZSByZWdpb24sIGtlZXAgcmVmdWVsaW5nIGRvbGxhcnMgaW4gdGhlIGxvY2FsIGVjb25vbXksIHJlZHVjZSB0aGUgcmVnaW9ucyBsYXJnZXN0IHNvdXJjZSBvZiBjYXJib24gZW1pc3Npb25zLCBhbmQgc2F2ZSBkcml2ZXJzIGFuZCBmbGVldHMgbW9uZXkuDQoNClNvIFRWQSBhbmQgVERFQyBoYXZlIGFza2VkIHlvdSB0byBkZXZlbG9wIGEgbWFwIHNob3dpbmcgdGhlIG51bWJlciBvZiBwdWJsaWMgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBpbiB0aGUgY29udGluZW50YWwgVW5pdGVkIFN0YXRlcy4gVGhpcyB3aWxsIGhlbHAgdGhlbSB1bmRlcnN0YW5kIHdoYXQgdGhlIG5hdGlvbnMgY3VycmVudCBpbmZyYXN0cnVjdHVyZSBsb29rcyBsaWtlIGFuZCBob3cgVGVubmVzc2VlIGN1cnJlbnRseSBjb21wYXJlcyB0byBuZWlnaGJvcmluZyBzdGF0ZXMuIEl0IHdpbGwgYWxzbyBoZWxwIFRWQSBhbmQgVERFQyBkZXRlcm1pbmUgYXBwcm94aW1hdGVseSBob3cgbWFueSBhZGRpdGlvbmFsIHN0YXRpb25zIHRoZXkgc2hvdWxkIGFkZC4gDQoNCkluIHRoaXMgZXhlcmNpc2UgeW91IHdpbGw6DQoNCi0gICBOYXZpZ2F0ZSBzb2Z0d2FyZSB1c2VkIGZvciBnZW9zcGF0aWFsIGFuYWx5c2lzDQotICAgRXhhbWluZSBhdHRyaWJ1dGVzIG9mIHZhcmlvdXMgZGF0YXNldHMNCi0gICBMZWFybiBob3cgdG8gZ3JhcGhpY2FsbHkgZGlzcGxheSBzcGF0aWFsIGRhdGENCi0gICBDcmVhdGUgYSBjYXJ0b2dyYXBoaWNhbGx5IHNvdW5kIHByb2R1Y3QNCg0KU29mdHdhcmUgc3BlY2lmaWMgZGlyZWN0aW9ucyBjYW4gYmUgZm91bmQgZm9yIGVhY2ggc3RlcCBiZWxvdy4gUGxlYXNlIHN1Ym1pdCB0aGUgYW5zd2VyIHRvIHRoZSBxdWVzdGlvbnMgYW5kIHlvdXIgZmluYWwgbWFwIGJ5IHRoZSBkdWUgZGF0ZS4NCg0KIyMgU3RlcCBPbmU6IFRoZSBEYXRhDQoNCkluIHRoaXMgc3RlcCB5b3Ugd2lsbCBsZWFybiBob3cgdG8gb2J0YWluIGRhdGEsIGxvYWQgaXQgaW50byB0aGUgc29mdHdhcmUsIGV4YW1pbmUgdGhlIGF0dHJpYnV0ZXMsIGFuZCBtYWtlIGEgc2ltcGxlIGRpc3BsYXkuDQoNCjxkZXRhaWxzPg0KPHN1bW1hcnk+PGJpZz5WaWV3IERpcmVjdGlvbnMgaW4gPGI+IFtBcmNHSVMgUHJvXXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9IDwvYj48L2JpZz48L3N1bW1hcnk+DQoNClRoZSBwdXJwb3NlIG9mIHRoaXMgZXhlcmNpc2UgaXMgdG8gaGVscCBmYW1pbGlhcml6ZSB5b3Ugd2l0aCB0aGUgW0FyY0dJUyBQcm9de3N0eWxlPSJjb2xvcjojZmY0NTAwIn0gcHJvZ3JhbS4gV2l0aCB0aGlzIHNvZnR3YXJlLCB5b3Ugd2lsbCBoYXZlIHRoZSBhYmlsaXR5IHRvIHZpZXcsIGNyZWF0ZSwgYW5kIGVkaXQgZ2VvZ3JhcGhpYyBkYXRhLCBxdWVyeSBzcGF0aWFsIGRhdGEsIGV4YW1pbmUgc3BhdGlhbCByZWxhdGlvbnNoaXBzLCBhbmQgY3JlYXRlIHB1Ymxpc2hhYmxlIG1hcHMuIFRvIGxhdW5jaCBBcmNHSVMgUHJvLCBjbGljayBvbiB0aGUgc3RhcnQgbWVudSBhbmQgc2VhcmNoIGZvciB0aGUgQXJjR0lTIEZvbGRlci4gV2l0aGluIHRoZSBmb2xkZXIgY2xpY2sgb24gdGhlICoqQXJjR0lTIFBybyoqIGljb24gdG8gb3Blbi4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLXByby5wbmciIGFsdD0iRGF0YSBEb3dubG9hZCBmcm9tIEdpdEh1YiIgd2lkdGg9IjI2MCIgaGVpZ2h0PSIzMjAiPjwvcD48YnI+DQoNCkFmdGVyIHRoZSBpbml0aWFsIHNwbGFzaCBzY3JlZW4sIHlvdSdsbCBiZSBncmVldGVkIHdpdGggYSBzY3JlZW4gdGhhdCBhbGxvd3MgeW91IHRvIG9wZW4gcHJldmlvdXMgcmVjZW50bHkgc2F2ZWQgcHJvamVjdHMsIG5ldyBtYXAgdGVtcGxhdGVzLCBhbmQgdmlldyB2YXJpb3VzIHJlc291cmNlcyBmcm9tIEVTUkkuIEZvciB0aGlzIGV4ZXJjaXNlIHlvdSB3aWxsIGJlZ2luIGJ5IGNsaWNraW5nICoqTWFwKiogdW5kZXIgdGhlIF9OZXcgPiBCbGFuayBUZW1wbGF0ZXNfIHNlY3Rpb24gaW4gdGhlIG1pZGRsZSBvZiB0aGUgc2NyZWVuLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtc3BsYXNoLXNjcmVlbi5wbmciIGFsdD0iQXJjR0lTIFBybyBPcGVuIFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNClRoaXMgd2lsbCBvcGVuIGEgbmV3IF9DcmVhdGUgYSBOZXcgUHJvamVjdF8mbmJzcDsgc2NyZWVuIHRoYXQgd2lsbCBhc2sgeW91IHRvIGdpdmUgeW91ciBuZXcgcHJvamVjdCBhIG5hbWUgYW5kIGEgbG9jYXRpb24gb24geW91ciBjb21wdXRlciB0byBzYXZlIHRoZSBwcm9qZWN0LiBBdCB0aGlzIHBvaW50IEkgd291bGQgcmVjb21tZW5kIGNyZWF0aW5nIGEgZm9sZGVyIHNvbWV3aGVyZSBvbiB5b3VyIFBDIHRvIHN0b3JlIGFsbCBvZiB5b3VyIF9HSVMxXyBleGVyY2lzZXMuIElmIHlvdSBhcmUgaW4gYSBHSVMgY2xhc3MgdXNpbmcgYSBuZXR3b3JrZWQgZm9sZGVyLCBiZSBzdXJlIHRvIGhhdmUgdGhhdCBmb2xkZXIgbWFwcGVkIGFuZCBzYXZlIGFsbCBvZiB5b3VyIGRhdGEgdW5kZXIgdGhlIHByb2plY3QgZm9sZGVyIGZvciB0aGlzIGV4ZXJjaXNlLiBUaGlzIHdpbGwgbWFrZSB0aGVtIGVhc2llciB0byBsb2NhdGUgbGF0ZXIgb24uDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1uZXctcHJvamVjdC5wbmciIGFsdD0iUHJvamVjdCBuYW1lIGFuZCBsb2NhdGlvbiIgd2lkdGg9IjUyMCIgaGVpZ2h0PSIxNzUiPjwvcD48YnI+DQoNCkFmdGVyIGVzdGFibGlzaGluZyB0aGUgcHJvamVjdCwgYSBwcm9qZWN0IGZpbGUgYW5kIHNldmVyYWwgZm9sZGVycyB3aWxsIGJlIGNyZWF0ZWQgaW4geW91ciBmb2xkZXIsIGFuZCB5b3VyIHNjcmVlbiBzaG91bGQgYXBwZWFyIHNpbWlsYXIgdG8gdGhpczoNCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLW9wZW4tcHJvamVjdC5wbmciIGFsdD0iTmV3IHByb2plY3QiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+PGJyPg0KDQpXaGlsZSB5b3VyIHNjcmVlbiBtaWdodCBhcHBlYXIgc2xpZ2h0bHkgZGlmZmVyZW50LCB5b3Ugc2hvdWxkIGhhdmUgYSBiYXNlbWFwIGluIHRoZSBjZW50ZXIgc2VjdGlvbiwgYSBsaXN0IG9mIG9iamVjdHMgdW5kZXIgX01hcF8gaW4gdGhlIF9Db250ZW50c18gc2VjdGlvbiBvbiB0aGUgbGVmdCAoZnJlcXVlbnRseSBjYWxsZWQgYSB0YWJsZSBvZiBjb250ZW50cyksIGFuZCBwb3NzaWJseSBhIGJsYW5rIHNlY3Rpb24gb24gdGhlIHJpZ2h0LiBGb3IgdGhpcyBleGVyY2lzZSB5b3Ugd2lsbCBuZWVkIHRvIGRvd25sb2FkIHRoZSBfRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9uXyBkYXRhIGZyb20gdGhlIFtHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIpe3N0eWxlPSJjb2xvcjojMDAwMDAwIn0gYnkgY2xpY2tpbmcgb24gdGhlIGRvd25sb2FkIGJ1dHRvbiBhdCA8Yj5bdGhpcyBsaW5rXShodHRwczovL2dpdGh1Yi5jb20vY2hyaXNtZ2VudHJ5L0dJUzEtRXhlcmNpc2UtMi9ibG9iL21haW4vRGF0YS9TaGFwZWZpbGVzL2V2X2RhdGEuemlwKXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9PC9iPiBhbmQgc2F2aW5nIGl0IGluIHlvdXIgZXhlcmNpc2UgZm9sZGVyIGNyZWF0ZWQgYWJvdmUuIE9uY2UgdGhlIGRvd25sb2FkIGlzIGNvbXBsZXRlIHlvdSB3aWxsIG5lZWQgdG8gdW56aXAgdGhlIGZpbGUgYnkgdXNpbmcgX3JpZ2h0LWNsaWNrID4gZXh0cmFjdCBhbGxfIG9uIHRoZSB6aXBwZWQgZm9sZGVyLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9naXRodWItZGF0YS1kb3dubG9hZC5wbmciIGFsdD0iRGF0YSBEb3dubG9hZCBmcm9tIEdpdEh1YiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNClRoaXMgZGF0YSBzaG91bGQgbm93IGJlIGF2YWlsYWJsZSBmb3IgdXNlIGluIHlvdXIgcHJvamVjdC4gVG8gYWRkIHRoZSBpbmZvcm1hdGlvbiB0byB5b3VyIG1hcCBwcm9qZWN0LCBuYXZpZ2F0ZSB0byB0aGUgKipNYXAqKiB0YWIgb24gdGhlIG1lbnUgYmFyIGFuZCBmaW5kIHRoZSBfQWRkIERhdGFfIGJ1dHRvbi4gRnJvbSBoZXJlIHlvdSBjYW4gY2xpY2sgdGhlIGRyb3AtZG93biBtZW51IGFuZCBzZWUgYWxsIG9mIHRoZSBvcHRpb25zLiBGb3IgdGhpcyBleGFtcGxlIHlvdSB3aWxsIGNsaWNrIF9EYXRhLCBBZGQgZGF0YSB0byB0aGUgbWFwLl8NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWFkZC1kYXRhLWJ1dHRvbi5wbmciIGFsdD0iQWRkIGRhdGEgYnV0dG9uIiB3aWR0aD0iMjQwIiBoZWlnaHQ9IjYyNSI+PC9wPjxicj4NCg0KU2ltaWxhciB0byBvdGhlciBQQy1iYXNlZCBHVUkgaW50ZXJmYWNlcywgYSBuZXcgd2luZG93IHdpbGwgb3BlbiB3aGVyZSB5b3Ugd2lsbCBuYXZpZ2F0ZSB0byB5b3VyIGRhdGEgZm9sZGVyIGFuZCBkb3VibGUtY2xpY2sgb3Igc2luZ2xlLWNsaWNrIGFuZCBjbGljayBPSyB0byBhZGQgdGhlIGRhdGEuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1hZGQtZGF0YS5wbmciIGFsdD0iQWRkIGRhdGEiIHdpZHRoPSI2NzUiIGhlaWdodD0iNDY1Ij48L3A+PGJyPg0KDQpUaGlzIHdpbGwgYWRkIHRoZSBkYXRhIHRvIHlvdXIgbWFwIGFuZCBpdCB3aWxsIGFwcGVhciBpbiB0aGUgdGFibGUgb2YgY29udGVudHMuIFlvdXIgc2NyZWVuIHNob3VsZCBub3cgbG9vayBzaW1pbGFyIHRvIHRoZSBvbmUgYmVsb3cgKGNvbG9ycyBtYXkgdmFyeSk6DQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1kYXRhLXZpZXcucG5nIiBhbHQ9IkVWIERhdGFzZXQgVmlldyIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNCldpdGggdGhpcyBkYXRhc2V0IGFkZGVkLCB5b3UgY2FuIG5vdyBiZWdpbiB0byBleHBsb3JlIHNvbWUgb2YgdGhlIGJhc2ljIHRvb2xzIGZvciBuYXZpZ2F0aW5nIGFuZCBhbmFseXppbmcgdGhlIG1hcCBkYXRhLiBTb21lIGluZm9ybWF0aW9uIG9yIHRvb2xzIGFyZSBhdmFpbGFibGUgaW4gdGhlIG1hcCB2aWV3IHdoaWxlIHNvbWUgYXJlIGxvY2F0ZWQgaW4gZWFjaCBvZiB0aGUgdmFyaW91cyB0YWJzIChNYXAsIEluc2VydCwgQW5hbHlzaXMsIFZpZXcsIEVkaXQsIEltYWdlcnksIGFuZCBTaGFyZSkuIEFkZGl0aW9uYWxseSwgc29tZSB0YWJzIG9yIGluZm9ybWF0aW9uIHdpbGwgb25seSBiZWNvbWUgYXZhaWxhYmxlIHdoZW4gZGF0YSBpcyBzZWxlY3RlZC4gRm9yIGV4YW1wbGUsIHdoaWxlIG9uIHRoZSAqKk1hcCoqIHRhYiwgaWYgeW91IHNlbGVjdCB0aGUgX2V2X2RhdGFfIGluIHRoZSB0YWJsZSBvZiBjb250ZW50cyB5b3Ugd2lsbCBzZWUgdGhhdCAqKkFwcGVhcmFuY2UsIExhYmVsaW5nLCBhbmQgRGF0YSoqIHRhYnMgYWxsIGFwcGVhci4gSWYgeW91IHNlbGVjdCBlaXRoZXIgdGhlIF9Xb3JsZCBUb3BvZ3JhcGhpYyBNYXBfIG9yIF9Xb3JsZCBIaWxsc2hhZGVfIG9ubHkgKipBcHBlYXJhbmNlKiogaXMgYWRkZWQuIElmIHlvdSBzZWxlY3QgX01hcF8gaW4gdGhlIHRhYmxlIG9mIGNvbnRlbnRzIHRoZW4gYWxsIGFkZGl0aW9uYWwgb3B0aW9ucyBhcmUgcmVtb3ZlZC4gDQoNCkFsb25nIHRoZSBib3R0b20gb2YgdGhlIG1hcCB2aWV3IHRoZXJlIGFyZSBzZXZlcmFsIHRvb2xzIGF2YWlsYWJsZSBpbmNsdWRpbmc6IA0KDQo8dGFibGUgc3R5bGU9IndpZHRoOjEwMCUiPg0KICA8Y29sZ3JvdXA+DQogICAgICAgPGNvbCBzdHlsZT0id2lkdGg6IDMwJTsiPg0KICAgICAgIDxjb2wgc3R5bGU9IndpZHRoOiA3MCU7Ij4NCiAgPC9jb2xncm91cD4NCiAgPHRyPg0KICAgIDx0ZD5SZXByZXNlbnRhdGl2ZSBGcmFjdGlvbjwvdGQ+DQogICAgPHRkPlVuaXQtbGVzcyByZWxhdGlvbiBiZXR3ZWVuIG1hcCB1bml0cyBhbmQgcmVhbC13b3JsZCB1bml0cyAoZS5nLiAxIHVuaXQgZXF1YWxzIDMwLDAwMCB1bml0cyk8L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPlNuYXBwaW5nPC90ZD4NCiAgICA8dGQ+TW92aW5nIGEgZmVhdHVyZSB0byBtYXRjaCBvciBjb2luY2lkZSBleGFjdGx5IHdpdGggYW5vdGhlciBwb2ludCBvciBmZWF0dXJlJ3MgY29vcmRpbmF0ZXMgd2hlbiB5b3VyIHBvaW50ZXIgaXMgd2l0aGluIGEgc3BlY2lmaWVkIGRpc3RhbmNlIG9yIHRvbGVyYW5jZTwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+Q29uc3RyYWludHM8L3RkPg0KICAgIDx0ZD5MaW1pdHMgaW1wb3NlZCBvbiBhIG1vZGVsIHRvIG1haW50YWluIGRhdGEgaW50ZWdyaXR5PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5HcmlkPC90ZD4NCiAgICA8dGQ+QSBuZXR3b3JrIG9mIHBhcmFsbGVsIGFuZCBwZXJwZW5kaWN1bGFyIGxpbmVzIHN1cGVyaW1wb3NlZCBvbiBhIG1hcCBhbmQgdXNlZCBmb3IgcmVmZXJlbmNlPC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5JbmZlcmVuY2U8L3RkPg0KICAgIDx0ZD5BbmFseXplcyB0aGUgc2VnbWVudCBvZiB0aGUgYWN0aXZlIHNrZXRjaCBvdmVyIHdoaWNoIHRoZSBwb2ludGVyIGlzIGhvdmVyaW5nIGFuZCBkaXNwbGF5cyBpbmZlcnJlZCBnZW9tZXRyaWMgY29uc3RyYWludHM8L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPkNvcnJlY3Rpb25zPC90ZD4NCiAgICA8dGQ+U2V0IGdyaWQgY29ycmVjdGlvbnMgYW5kIG9mZnNldDwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+WCxZIENvb3JkaW5hdGVzPC90ZD4NCiAgICA8dGQ+WCxZIGxvY2F0aW9uIG9mIHRoZSBjdXJzb3I7IGNhbiBiZSBzZXQgdG8gZGVjaW1hbCBkZWdyZWVzLCBkZWdyZWVzIG1pbnV0ZXMgc2Vjb25kcywgZGVncmVlIGRlY2ltYWwgbWludXRlcywgbWlsaXRhcnkgZ3JpZCByZWZlcmVuY2Ugc3lzdGVtLCBuYXRpb25hbCBncmlkLCBvciB1bml2ZXJzYWwgdHJhbnN2ZXJzZSBtZXJjYXRvcjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+U2VsZWN0ZWQgRmVhdHVyZXM8L3RkPg0KICAgIDx0ZD5EZXBpY3RzIHRoZSBudW1iZXIgb2YgaXRlbXMgc2VsZWN0ZWQgZnJvbSBhIGZlYXR1cmUgc2V0PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5QYXVzaW5nIERyYXdpbmc8L3RkPg0KICAgIDx0ZD5TdG9wcyB0aGUgZHJhd2luZyBvZiBsYXllcnMgb24gdGhlIG1hcCB2aWV3PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5SZWZyZXNoPC90ZD4NCiAgICA8dGQ+UmVsb2FkcyB0aGUgbWFwIHZpZXc8L3RkPg0KICA8L3RyPg0KPC90YWJsZT4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWRhdGEtdmlldy10b29sYmFyLW1hcmt1cC5wbmciIGFsdD0iTWFwIFZpZXcgVG9vbGJhciIgc3R5bGU9IndpZHRoOjEwMCUiPjwvZGl2PjwvcD48YnI+DQoNClRoZSBtb3VzZSBjYW4gYmUgdXNlZCB0byBuYXZpZ2F0ZSBhcm91bmQgdGhlIG1hcCB2aWV3LiBUaGUgbGVmdC1jbGljayBidXR0b24gaXMgdXNlZCB0byBwYW4gb3IgbW92ZSB0aGUgbWFwIGFyb3VuZCB0aGUgc2NyZWVuIGFuZCB2aWV3IHBvcC11cHMsIHRoZSBzY3JvbGwgd2hlZWwgaXMgdXNlZCB0byB6b29tIG9yIHJvdGF0ZS90aWx0ICgzRCksIGFuZCByaWdoLWNsaWNrIGlzIHVzZWQgZm9yIGNvbnRpbnVvdXMgem9vbSBieSBjbGlja2luZyBhbmQgbW92aW5nIHRoZSBjdXJzb3IgdXAgdG8gem9vbSBvdXQgYW5kIGRvd24gdG8gem9vbSBpbi4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWV4cGxvcmUtdG9vbC5wbmciIGFsdD0iRXhwbG9yZSIgd2lkdGg9IjQxNSIgaGVpZ2h0PSIzNTAiPjwvcD48YnI+DQoNCk9uIHRoZSAqKk1hcCoqIHRhYiB0aGVyZSBhcmUgYSBudW1iZXIgb2YgdG9vbHMgeW91IHNob3VsZCBiZWNvbWUgZmFtaWxpYXIgd2l0aCBhcyB0aGV5IHdpbGwgYmUgdXNlZnVsIHRocm91Z2hvdXQgdGhpcyBjb3Vyc2UgYW5kIGJleW9uZC4gQWxvbmcgd2l0aCB0aGUgX0FkZCBEYXRhXyBidXR0b24geW91IGhhdmUgYWxyZWFkeSB1c2VkLCB0aGUgX0ZpeGVkIFpvb20gSW4vT3V0XyB0b29scyZuYnNwOyA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtem9vbS10b29scy5wbmciIGFsdD0iRml4ZWQgWm9vbSBUb29scyIgd2lkdGg9IjQwIiBoZWlnaHQ9IjIwIj4gYXJlIHVzZWQgdG8gYWRqdXN0IHRoZSBsZXZlbCBvZiB6b29tLiBUaGUgX0Z1bGwgRXh0ZW50XyB0b29sJm5ic3A7IDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1mdWxsLWV4dGVudC5wbmciIGFsdD0iRnVsbCBFeHRlbnQgVG9vbCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4gaXMgdXNlZCB0byBhZGp1c3QgdGhlIGxldmVsIG9mIHpvb20gdG8gaW5jbHVkZSB0aGUgZXh0ZW50IG9mIGFsbCBkYXRhc2V0cy4gVGhlIF9QcmV2aW91cyBFeHRlbnRfIHRvb2wmbmJzcDsgPGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLXByZXZpb3VzLWV4dGVudC5wbmciIGFsdD0iUHJldmlvdXMgRXh0ZW50IFRvb2wiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+IGlzIHVzZWQgdG8gcmV0dXJuIHRoZSBsZXZlbCBvZiB6b29tIHRvIHRoZSBwcmV2aW91cyBsZXZlbC4gVGhlcmUgYXJlIGEgbnVtYmVyIG9mIG90aGVyIHRvb2xzIHlvdSB3aWxsIHVzZSBvbiB0aGlzIHRhYiBpbiBmdXR1cmUgZXhlcmNpc2VzLiBZb3Ugc2hvdWxkIGV4cGxvcmUgdGhlIGRpZmZlcmVudCBidXR0b25zIG9uIHRoaXMgdGFiIHRvIHNlZSB3aGF0IHRoZXkgZG8uDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1tYXAtcmliYm9uLnBuZyIgYWx0PSJNYXAgVG9vbGJhciIgc3R5bGU9IndpZHRoOjEwMCUiPjwvZGl2PjwvcD48YnI+DQoNCkZvciB0aGlzIGV4ZXJjaXNlIHlvdSB3aWxsIGZhbWlsaWFyaXplIHlvdXJzZWxmIHdpdGggYW5vdGhlciB1c2VmdWwgdG9vbCB0aGF0IGFsbG93cyB5b3UgdG8gZXhhbWluZSBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlIGRhdGFzZXQuIEZpcnN0LCBjbGljayBvbiB0aGUgX2V2X2RhdGFfIGxheWVyIGluIHRoZSB0YWJsZSBvZiBjb250ZW50cy4gTmV4dCwgY2xpY2sgb24gdGhlIF9FeHBsb3JlXyZuYnNwOyBidXR0b24gPGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWV4cGxvcmUtYnV0dG9uLnBuZyIgYWx0PSJFeHBsb3JlIEJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4gYW5kIG1vdmUgdGhlIGN1cnNvciBvdmVyIHRoZSBtYXAuIFlvdXIgY3Vyc29yIHdpbGwgYmVjb21lIGEgaGFuZCB3aXRoIHBvaW50ZWQgZmluZ2VyLiBJZiB5b3UgY2xpY2sgb24gdGhlIHN0YXRlIG9mIFRlbm5lc3NlZSBhIHBvcC11cCB3aW5kb3cgd2lsbCBhcHBlYXIgdGhhdCBwcm92aWRlcyBkYXRhIGFib3V0IHRoZSBzdGF0ZS4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWlkZW50aWZ5LXRvb2wucG5nIiBhbHQ9IkV4cGxvcmUiIHdpZHRoPSI2MjUiIGhlaWdodD0iMzgwIj48L3A+PGJyPg0KDQpZb3UgY2FuIHNjcm9sbCBkb3duIG9uIHRoZSBkYXRhIGluIHRoZSBwb3AtdXAgd2luZG93IGFuZCBleGFtaW5lIGVhY2ggYXR0cmlidXRlIGluIHRoZSB0YWJsZS4gQWxvbmcgdGhlIGJvdHRvbSBvZiB0aGUgd2luZG93IHlvdSB3aWxsIHNlZSB0b29scyB0aGF0IGNhbiBiZSB1c2VkIHRvOiBwcmludCB0aGUgaW5mb3JtYXRpb24gZm9yIHRoZSBzZWxlY3RlZCBmZWF0dXJlIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1wb3AtdXAtcHJpbnQucG5nIiBhbHQ9IlByaW50IHRoZSBwb3AtdXAgZm9yIHRoaXMgZmVhdHVyZSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4sIHRvZ2dsZSBzZWxlY3Rpb24gb24vb2ZmIGZvciB0aGUgZmVhdHVyZSA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtcG9wLXVwLXNlbGVjdC5wbmciIGFsdD0iVG9nZ2xlIHNlbGVjdGlvbiBvbi9vZmYgZm9yIHRoaXMgZmVhdHVyZSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4sIGZsYXNoIHRoZSBzZWxlY3RlZCBmZWF0dXJlIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1wb3AtdXAtZmxhc2gucG5nIiBhbHQ9IkZsYXNoIHNlbGVjdGVkIGZlYXR1cmUiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+LCBhbmQgdG8gem9vbSB0byB0aGUgc2VsZWN0ZWQgZmVhdHVyZSA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtcG9wLXVwLXpvb20ucG5nIiBhbHQ9Ilpvb20gdG8gc2VsZWN0ZWQgZmVhdHVyZSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4uDQoNClRoaXMgbWV0aG9kIGlzIGhlbHBmdWwgZm9yIGdldHRpbmcgaW5mb3JtYXRpb24gYWJvdXQgYSBzcGVjaWZpYyBwb3J0aW9uIG9mIHRoZSBkYXRhc2V0LiBZb3UgY2FuIHZpZXcgYWxsIG9mIHRoZSB1bmRlcmx5aW5nIGluZm9ybWF0aW9uIGluIHRoZSBhdHRyaWJ1dGUgdGFibGUgYnkgcmlnaHQtY2xpY2tpbmcgb24gdGhlIF9ldl9kYXRhXyBsYXllciBpbiB0aGUgdGFibGUgb2YgY29udGVudHMgYW5kIGNsaWNraW5nIG9uICoqQXR0cmlidXRlIFRhYmxlKiouDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1yYy1hdHRyaWJ1dGUtdGFibGUucG5nIiBhbHQ9IkV4cGxvcmUiIHdpZHRoPSIzNDUiIGhlaWdodD0iMjAwIj48L3A+PGJyPg0KDQpBbHRlcm5hdGl2ZWx5IHdoaWxlIHRoZSBfZXZfZGF0YV8gbGF5ZXIgaXMgc2VsZWN0ZWQgaW4gdGhlIHRhYmxlIG9mIGNvbnRlbnRzIHlvdSBzaG91bGQgc2VlIHRocmVlIG5ldyB0YWJzIGhpZ2hsaWdodGVkIGluIG9yYW5nZSAoY29sb3IgbWF5IHZhcnkpIGFuZCB0aXRsZWQgKipGZWF0dXJlIExheWVyKiouIFVuZGVyIHRoZSAqKkRhdGEqKiB0YWIgeW91IHNob3VsZCBzZWUgdGhlIF9BdHRyaWJ1dGUgVGFibGVfIHRvb2wuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1kYXRhLXJpYmJvbi5wbmciIGFsdD0iTWFwIFRvb2xiYXIiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+PGJyPg0KDQpXaGljaGV2ZXIgbWV0aG9kIHlvdSB1c2VkIHRvIG9wZW4gdGhlIGF0dHJpYnV0ZSB0YWJsZSB5b3Ugc2hvdWxkIG5vdyBoYXZlIGEgbmV3IHNlY3Rpb24gb24geW91ciBzY3JlZW4gdGhhdCBkaXNwbGF5cyB0aGUgYXR0cmlidXRlIGRhdGEgZm9yIGFsbCBvZiB0aGUgZmVhdHVyZXMgaW4gdGhlIGRhdGFzZXQuIEluIGEgZnV0dXJlIGV4ZXJjaXNlIHlvdSB3aWxsIGxlYXJuIGhvdyB0byBzb3J0LCBxdWVyeSwgYW5kIGVkaXQgaW5mb3JtYXRpb24gd2l0aGluIHRoZSBhdHRyaWJ1dGUgdGFibGUuIEZvciBub3csIGV4YW1pbmUgdGhlIG51bWVyb3VzIHZhcmlhYmxlcyBhdmFpbGFibGUgZm9yIGVhY2ggc3RhdGUuIFdoYXQgaXMgdGhlIGNvbHVtbiBuYW1lIGFuZCByYW5nZSBvZiB2YWx1ZXMgZm9yIHRoZSBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zPzxicj4NCjxzbWFsbD5IaW50OiBUaGlzIGluZm9ybWF0aW9uIHdpbGwgYmUgbmVlZGVkIGluIHRoZSBuZXh0IHNlY3Rpb24uPC9zbWFsbD4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWF0dHJpYnV0ZS10YWJsZS5wbmciIGFsdD0iQXR0cmlidXRlIFRhYmxlIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPjxicj4NCg0KPGI+PGJpZz5RdWVzdGlvbiBOby4gMTwvYmlnPjwvYj4NCjxibG9ja3F1b3RlPg0KVXNpbmcgdGhlIGV4cGxvcmUgdG9vbCwgd2hhdCBpcyB0aGUgcG9wdWxhdGlvbiBvZiBUZW5uZXNzZWUgaW4gMjAxMCAoUE9QMjAxMCk/IFdoYXQgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiBpcyBmZW1hbGU/PGJyPjxicj4NClVzaW5nIHRoZSBhdHRyaWJ1dGUgdGFibGUsIGZpbmQgdGhlIGFyZWEgKF9TUU1JXyZuYnNwOykgb2YgQ29sb3JhZG8uIEhvdyBtdWNoIGxhcmdlciBpcyBpdCB0aGFuIFd5b21pbmc/DQo8L2Jsb2NrcXVvdGU+DQoNClR5cGUgeW91ciBhbnN3ZXJzIGluIGEgd29yZCBkb2N1bWVudC4gVGhlIGFuc3dlcnMgd2lsbCBuZWVkIHRvIGJlIHN1Ym1pdHRlZCBhdCB0aGUgY29uY2x1c2lvbiBvZiB0aGlzIGxhYi4NCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiMwMDY0MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpUaGUgcHVycG9zZSBvZiB0aGlzIGV4ZXJjaXNlIGlzIHRvIGhlbHAgZmFtaWxpYXJpemUgeW91IHdpdGggdGhlIFtRR0lTXXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9IHByb2dyYW0uIFdpdGggdGhpcyBzb2Z0d2FyZSwgeW91IHdpbGwgaGF2ZSB0aGUgYWJpbGl0eSB0byB2aWV3LCBjcmVhdGUsIGFuZCBlZGl0IGdlb2dyYXBoaWMgZGF0YSwgcXVlcnkgc3BhdGlhbCBkYXRhLCBleGFtaW5lIHNwYXRpYWwgcmVsYXRpb25zaGlwcywgYW5kIGNyZWF0ZSBwdWJsaXNoYWJsZSBtYXBzLiBJbiB0aGVzZSBkaXJlY3Rpb25zIEkgd2lsbCBwb3N0IGltYWdlcyBmcm9tIGJvdGggUEMgKG9uIHRoZSBsZWZ0KSBhbmQgbWFjT1MgKG9uIHRoZSByaWdodCkgZm9yIGVhY2ggc3RlcC4gV2hpbGUgeW91ciBzZXQtdXAgbWF5IGRpZmZlciBzbGlnaHRseSwgdGhlIGNvbmZpZ3VyYXRpb25zIGFuZCBsYXlvdXQgb2YgdGhlIHRvb2xzIHNob3VsZCBiZSBzaW1pbGFyLg0KDQpXaGVuIHlvdSBiZWdpbiBhIG5ldyBleGVyY2lzZSBpdCB3b3VsZCBiZSBiZW5lZmljaWFsIHRvIGNyZWF0ZSBhIG5ldyBmb2xkZXIgc3BlY2lmaWNhbGx5IGZvciB0aGUgZGF0YSBhbmQgcHJvamVjdCBmaWxlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGxhYi4gVGhpcyB3aWxsIGhlbHAgeW91IHRvIG9yZ2FuaXplIHlvdXIgZGF0YSBhbmQgYmUgYWJsZSB0byBxdWlja2x5IHJlZmVyIGJhY2sgdG8gaXQgaW4gbGF0ZXIgZXhlcmNpc2VzLiBGb3IgdGhpcyBleGVyY2lzZSB5b3Ugd2lsbCBuZWVkIHRvIGRvd25sb2FkIHRoZSBfRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9uXyBkYXRhIGZyb20gdGhlIFtHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIpe3N0eWxlPSJjb2xvcjojMDAwMDAwIn0gYnkgY2xpY2tpbmcgb24gdGhlIGRvd25sb2FkIGJ1dHRvbiBhdCA8Yj5bdGhpcyBsaW5rXShodHRwczovL2dpdGh1Yi5jb20vY2hyaXNtZ2VudHJ5L0dJUzEtRXhlcmNpc2UtMi9ibG9iL21haW4vRGF0YS9TaGFwZWZpbGVzL2V2X2RhdGEuemlwKXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9PC9iPiBhbmQgc2F2aW5nIGl0IGluIHlvdXIgZXhlcmNpc2UgZm9sZGVyLiBPbmNlIHRoZSBkb3dubG9hZCBpcyBjb21wbGV0ZSB5b3Ugd2lsbCBuZWVkIHRvIHVuemlwIHRoZSBmaWxlIGJ5IHVzaW5nIF9kb3VibGUtY2xpY2tfIG9uIG1hY09TIG9yIF9yaWdodC1jbGljayA+IGV4dHJhY3QgYWxsXyBvbiBQQy4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvZ2l0aHViLWRhdGEtZG93bmxvYWQucG5nIiBhbHQ9IkRhdGEgRG93bmxvYWQgZnJvbSBHaXRIdWIiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+PGJyPg0KDQpUbyBzdGFydCB0aGUgUUdJUyBwcm9ncmFtIHByZXNzIHRoZSBfU3RhcnQgTWVudSA+IFFHSVNfIG9yIGxhdW5jaCB0aGUgYXBwbGljYXRpb24gZnJvbSB0aGUgX01hYyBMYXVuY2hwYWRfLiBJdCBtaWdodCBiZSBiZW5lZmljaWFsIHRvIGNyZWF0ZSBhIHNob3J0Y3V0IG9uIHRoZSBkZXNrdG9wIG9yIGFkZCBpdCB0byB5b3VyIGRvY2sgZm9yIHF1aWNrZXIgYWNjZXNzIGluIHRoZSBmdXR1cmUuIEFzIHRoZSBwcm9ncmFtIGxvYWRzLCB0aGUgb3BlbmluZyBzY3JlZW4gd2lsbCBiZSBleHRyZW1lbHkgdXNlZnVsIHRvIHlvdSB3aGlsZSB3b3JraW5nIG9uIGZ1dHVyZSBwcm9qZWN0cywgaG93ZXZlciwgZm9yIHRoaXMgZXhlcmNpc2Ugd2Ugd2lsbCBzZWxlY3QgKipOZXcgRW1wdHkgUHJvamVjdCoqLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48ZGl2IGNsYXNzPSJ6b29tIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXRlbXAucG5nIiBhbHQ9IlFHSVMgU3RhcnQgU2NyZWVuIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPjxicj4NCg0KVGhlIHNjcmVlbiBkZXBpY3RlZCBiZWxvdyBpcyBzZXBhcmF0ZWQgaW50byB0d28gc2VjdGlvbnMuIFRvIHRoZSBsZWZ0IHRoZXJlIGlzIHRoZSBfQnJvd3Nlcl8gYW5kIF9MYXllcnNfIHNlY3Rpb25zLCBhbmQgb24gdGhlIHJpZ2h0IGlzIHRoZSBfTWFwIENhbnZhc18uIFlvdXIgdmVyc2lvbiBtYXkgdmFyeSBzbGlnaHRseSBmcm9tIHRoZSBpbWFnZXMuIFRoZXJlIGFyZSBhIG51bWJlciBvZiB3YXlzIHRvIGFkZCBkYXRhLCBidXQgaW4gdGhpcyBleGFtcGxlIHdlIGFyZSBnb2luZyB0byB1c2UgdGhlIGJyb3dzZXIgd2luZG93IHRvIGNvbm5lY3QgdG8gb3VyIHByb2plY3QgZGF0YSBmb2xkZXIuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtcHJvai5wbmciIGFsdD0iUUdJUyBTdGFydCBTY3JlZW4iIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+PGJyPg0KDQpJbiB0aGUgX0Jyb3dzZXJfIHdpbmRvdyBvbiB0aGUgbGVmdCwgbmF2aWdhdGUgdG8gdGhlIGZvbGRlciB3aGVyZSB5b3Ugc2F2ZWQgYW5kIHVuemlwcGVkIHRoZSBleGVyY2lzZSBkYXRhIGZvbGRlci4gT25jZSB5b3UgbG9jYXRlIGEgZm9sZGVyIGluIGZvbGRlciBpbiB0aGUgYnJvd3NlciwgeW91IGNhbiB1c2UgY29udHJvbCtjbGljayAobWFjT1MpIG9yIHJpZ2h0LWNsaWNrIChQQykgdG8gKipBZGQgYXMgYSBmYXZvcml0ZSoqLiBUaGlzIHdpbGwgbGluayBpdCB0byB0aGUgZmF2b3JpdGVzIGRyb3AtZG93biBpbiB0aGUgYnJvd3NlciB3aW5kb3cgZ2l2aW5nIHlvdSBxdWlja2VyIGZ1dHVyZSBhY2Nlc3MuIFRvIGFkZCB0aGUgZGF0YSwgeW91IHdpbGwgbmF2aWdhdGUgdG8gdGhlICoqZXZfZGF0YS5zaHAqKiBmaWxlIGFuZCB0aGVuIGNsaWNrLWFuZC1kcmFnIGl0IHRvIHRoZSBtYXAgY2FudmFzLiBZb3Ugd2lsbCBiZSBhYmxlIHRvIGFkZCBhbGwgdHlwZXMgb2YgZGF0YSBpbiB0aGlzIHNhbWUgd2F5LiBJZiB0aGVyZSBpcyBhIHBvcC11cCB3aW5kb3cgdGhhdCBtZW50aW9ucyB0cmFuc2Zvcm1hdGlvbnMgZ28gYWhlYWQgYW5kIGNsaWNrIE9LLiBXaGlsZSB0aGUgbG9vayBvZiB0aGUgVVMgaW4gdGhpcyBkYXRhc2V0IGlzIGxlc3MgdGhhbiBpZGVhbCwgdGhlIHB1cnBvc2Ugb2YgdGhpcyBleGVyY2lzZSBpcyB0byBlbnN1cmUgeW91IGtub3cgaG93IHRvIGRpc3BsYXkgZGF0YSBhbmQgYmFzaWMgdG9vbHMgZm9yIG5hdmlnYXRpbmcgdGhlIHNvZnR3YXJlLiBUcmFuc2Zvcm1hdGlvbnMgd2lsbCBiZSBkaXNjdXNzZWQgZnVydGhlciBpbiBhIGNvdXBsZSB3ZWVrcyBhZnRlciBhIGxlY3R1cmUgb24gcHJvamVjdGlvbnMgYW5kIGNvb3JkaW5hdGUgc3lzdGVtcy4gRm9yIG5vdywgbGVhdmUgaXQgd2l0aCBvcHRpb24gMSBhbmQgY2xpY2sgT0suDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtdHJhbnNmb3JtYXRpb25zLnBuZyIgYWx0PSJRR0lTIFN0YXJ0IFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNCllvdXIgc2NyZWVuIHNob3VsZCBub3cgbG9vayBzaW1pbGFyIHRvIHRoZSBzY3JlZW5zIGJlbG93IChjb2xvcnMgbWF5IHZhcnkpLiBOb3RpY2UgdGhhdCB0aGUgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSB2YWx1ZXMgYXQgdGhlIGJvdHRvbSBvZiB0aGUgc2NyZWVuIGFkanVzdCBhcyB5b3UgbW92ZSB5b3VyIGN1cnNvci4gDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtc3RhdGVzLnBuZyIgYWx0PSJRR0lTIE1hcCBDYW52YXMiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+PGJyPg0KDQpZb3UgY2FuIG5vdyBiZWdpbiB0byBleHBsb3JlIHNvbWUgb2YgdGhlIGJhc2ljIHRvb2xzIGZvciBuYXZpZ2F0aW5nIHRoZSBfbWFwIGNhbnZhc18gc3VjaCBhczoNCg0KPHRhYmxlIHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbi1sZWZ0OmF1dG87bWFyZ2luLXJpZ2h0OmF1dG87Ij4NCiAgPHRyPg0KICAgIDx0ZD48bGk+Wm9vbSBpbiBhbmQgb3V0IHdpdGggdGhlIDxpPkZpeGVkIFpvb20gVG9vbHM8L2k+PC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWZpeGVkLXpvb20ucG5nIiBhbHQ9IkZpeGVkIFpvb20gVG9vbHMiIHdpZHRoPSI0MCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+PGk+UGFuIHRvb2w8L2k+IHRvIHBvc3Rpb24gdGhlIG1hcCBvbiB0aGUgc2NyZWVuPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXBhbi5wbmciIGFsdD0iUGFuIFRvb2wiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+PGk+TWFwIHNjYWxlPC9pPiB3aGVyZSB5b3UgY2FuIGFkanVzdCB0aGUgbWFwIHNjYWxlIChsZXZlbCBvZiB6b29tKSBtYW51YWxseTwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1tYXAtc2NhbGUucG5nIiBhbHQ9Ik1hcCBTY2FsZSIgd2lkdGg9IjgwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT48aT5ab29tIGZ1bGw8L2k+IGJ1dHRvbiB3aGljaCB3aWxsIGFkanVzdCB0aGUgdmlldyB0byBhY2NvbW1vZGF0ZSBhbGwgZGF0YXNldHM8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtZnVsbC1leHRlbnQucG5nIiBhbHQ9Ilpvb20gRnVsbCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KPC90YWJsZT4NCjxicj4NClVzZSB0aGVzZSB0b29scyB0byB6b29tIGluIGFuZCBvdXQsIHJlcG9zaXRpb24gdGhlIG1hcCBvbiB0aGUgc2NyZWVuLCBhbmQgcmV0dXJuIHRvIHRoZSBjdXJyZW50IHZpZXcgdXNpbmcgdGhlIF96b29tIGZ1bGxfIGJ1dHRvbi4NCg0KQW5vdGhlciB1c2VmdWwgdG9vbCBpcyB0aGUgKippZGVudGlmeSBmZWF0dXJlcyoqIGN1cnNvciB3aGljaCB1c2VzIGFuIGljb24gd2l0aCBhIGxvd2VyY2FzZSBfaV8gaW4gYSBbYmx1ZSBjaXJjbGVde3N0eWxlPSJjb2xvcjojNjQ5NUVEIn0gPGltZyBzcmM9ICJJbWFnZXMvcWdpcy1pZGVudGlmeS5wbmciIGFsdD0iSWRlbnRpZnkgRmVhdHVyZXMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+IC4gVGhpcyBvcHRpb24gZXh0cmFjdHMgaW5mb3JtYXRpb24gZm9yIGEgc2VsZWN0ZWQgZmVhdHVyZSBmcm9tIHRoZSBhdHRyaWJ1dGUgdGFibGUgb2YgdGhlIHNlbGVjdGVkIGxheWVyLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48ZGl2IGNsYXNzPSJ6b29tIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXRlbm5lc3NlZS5wbmciIGFsdD0iSWRlbnRpZnkgQ3Vyc29yIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPjxicj4NCg0KSWYgeW91IHdhbnRlZCB0byB2aWV3IHRoZSBlbnRpcmUgdW5kZXJseWluZyBkYXRhc2V0IHlvdSBjb3VsZCBjb250cm9sLWNsaWNrIChtYWNPUykgb3IgcmlnaHQtY2xpY2sgKFBDKSBvbiB0aGUgYWN0aXZlIGxheWVyIGFuZCBzZWxlY3QgKipPcGVuIGF0dHJpYnV0ZSB0YWJsZSoqLiBJbiBhIGZ1dHVyZSBleGVyY2lzZSB5b3Ugd2lsbCBsZWFybiBob3cgdG8gc29ydCwgcXVlcnksIGFuZCBlZGl0IGluZm9ybWF0aW9uIHdpdGhpbiB0aGUgYXR0cmlidXRlIHRhYmxlLiBGb3Igbm93LCBleGFtaW5lIHRoZSBudW1lcm91cyB2YXJpYWJsZXMgYXZhaWxhYmxlIGZvciBlYWNoIHN0YXRlLiBXaGF0IGlzIHRoZSBjb2x1bW4gbmFtZSBhbmQgcmFuZ2Ugb2YgdmFsdWVzIGZvciB0aGUgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucz8gPGJyPg0KPHNtYWxsPjxpPkhpbnQ6IFRoaXMgaW5mb3JtYXRpb24gd2lsbCBiZSBuZWVkZWQgaW4gdGhlIG5leHQgc2VjdGlvbi48L2k+PC9zbWFsbD4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1hdHRyaWJ1dGVzLnBuZyIgYWx0PSJBdHRyaWJ1dGUgVGFibGUiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+PGJyPg0KDQo8Yj48YmlnPlF1ZXN0aW9uIE5vLiAxPC9iaWc+PC9iPg0KPGJsb2NrcXVvdGU+DQpVc2luZyB0aGUgaWRlbnRpZnkgdG9vbCwgd2hhdCBpcyB0aGUgcG9wdWxhdGlvbiBvZiBUZW5uZXNzZWUgaW4gMjAxMD8gV2hhdCBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGF0aW9uIGlzIGZlbWFsZT88YnI+PGJyPg0KVXNpbmcgdGhlIGF0dHJpYnV0ZSB0YWJsZSwgZmluZCB0aGUgYXJlYSAoX1NRTUlfJm5ic3A7KSBvZiBDb2xvcmFkby4gSG93IG11Y2ggbGFyZ2VyIGlzIGl0IHRoYW4gV3lvbWluZz8NCjwvYmxvY2txdW90ZT4NCg0KVHlwZSB5b3VyIGFuc3dlcnMgaW4gYSB3b3JkIGRvY3VtZW50LiBUaGUgYW5zd2VycyB3aWxsIG5lZWQgdG8gYmUgc3VibWl0dGVkIGF0IHRoZSBjb25jbHVzaW9uIG9mIHRoaXMgbGFiLg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPg0KPHN1bW1hcnk+PGJpZz5WaWV3IERpcmVjdGlvbnMgaW4gPGI+IFtSXXtzdHlsZT0iY29sb3I6IzY0OTVFRCJ9IDwvYj48L2JpZz48L3N1bW1hcnk+DQoNCkZvciBlYWNoIGV4ZXJjaXNlIGluICoqUioqIHlvdSB3aWxsIG5lZWQgdG8gbG9hZCB2YXJpb3VzIHBhY2thZ2VzIHRoYXQgYXJlIHVzZWQgdG8gY29tcGxldGUgYW5hbHlzZXMgYW5kIGdyYXBoaWNhbCBvdXRwdXQuIEdlbmVyYWxseSB0aGVzZSBwYWNrYWdlcyB3aWxsIGJlIHByZWxvYWRlZCBpbiB0aGUgY29sYWIgbm90ZWJvb2sgaG93ZXZlciBpbiBzdWJzZXF1ZW50IGxhYnMgeW91IG1heSBuZWVkIHRvIGluc3RhbGwgY2VydGFpbiBwYWNrYWdlcyB0byBjb21wbGV0ZSB0aGUgZXhlcmNpc2VzLiBUbyBpbnN0YWxsIGEgcGFja2FnZSBpbiAqKlIqKiB5b3UgdXNlIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gd2hlcmUgKCJ4IikgaXMgdGhlIG5hbWUgb2YgYSBzcGVjaWZpYyBwYWNrYWdlLg0KDQpgYGANCmluc3RhbGwucGFja2FnZXMoIngiKQ0KYGBgDQpPbmNlIHRoZSBwYWNrYWdlIGhhcyBiZWVuIGluc3RhbGxlZCwgaXQgd2lsbCBuZWVkIHRvIGJlIGxvYWRlZCB1c2luZyBhIHNpbWlsYXIgZnVuY3Rpb246DQoNCmBgYA0KbGlicmFyeSgieCIpDQpgYGANCkluIHRoZSBjb2xhYiBub3RlYm9vayBmb3IgdGhpcyBleGVyY2lzZSB5b3Ugd2lsbCBzZWUgd2hlcmUgdGhyZWUgcGFja2FnZXMgX3RpZHl2ZXJzZSwgbWFwcywgYW5kIGdnc25fIHdlcmUgaW5zdGFsbGVkIGFuZCBsb2FkZWQuIE5vdyB0aGF0IHlvdSBoYXZlIHRoZSBwYWNrYWdlcyByZXF1aXJlZCBmb3IgdGhlIGV4ZXJjaXNlIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHRoZSBkYXRhLiBGb3IgdGhpcyBsYWIgdGhlIGRhdGEgY29uc2lzdHMgb2Ygc3RhdGUgbmFtZXMsIGFiYnJldmlhdGlvbnMsIGFuZCB0aGUgbnVtYmVyIG9mIGVsZWN0cmljIHZlaGljbGUgcmVjaGFyaW5nIHN0YXRpb25zLiBUbyBhdm9pZCB0aGUgbmVlZCB0byBkb3dubG9hZCB0aGUgZGF0YSwgeW91IHdpbGwgdGhlIGBgYHJlYWQuY3N2KClgYGAgZnVuY3Rpb24gYW5kIGEgVVJMIHRvIGltcG9ydCB0aGUgZGF0YS4gVXNpbmcgdGhlIGBgYGhlYWQoKWBgYCBmdW5jdGlvbiB3aWxsIGFsbG93IHlvdSB0byB2aWV3IHRoZSBmaXJzdCBmZXcgbGluZXMgb2YgYW55IGRhdGFzZXQuDQoNCmBgYHtyIGRhdGEsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmV2cyA8LSByZWFkLmNzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvbWFpbi9EYXRhL2V2X3N0YXRpb25zLmNzdicpDQpoZWFkKGV2cykNCmBgYA0KDQpJbiB0aGUgc2NyaXB0IGFib3ZlIHlvdSB3aWxsIHNlZSB0aGUgdXNlIG9mICZuYnNwOyoqPC0qKi4gVGhpcyBpcyBhbiBvcGVyYXRvciB1c2VkIHRvIGNyZWF0ZSBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBpbiBsYXRlciBzdGVwcy4gSWYgdGhlIHNjcmlwdCB3YXMgd3JpdHRlbiBhcyBgYGByZWFkLmNzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvbWFpbi9EYXRhL2V2X3N0YXRpb25zLmNzdicpYGBgIHRoZSBkYXRhc2V0IHdvdWxkIGhhdmUgYmVlbiByZWFkIGFuZCBpbW1lZGlhdGVseSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbi4gSG93ZXZlciwgaXQgd291bGQgbm90IGhhdmUgYmVlbiBhdmFpbGFibGUgZm9yIHN1YnNlcXVlbnQgYW5hbHlzZXMuIEluIGNvbGFiLCB5b3UgY2FuIGNyZWF0ZSB5b3VyIG93biBjb2RlIGJsb2NrIGFuZCB0ZXN0IGl0IG91dCB0byBzZWUgdGhlIHJlc3VsdHMuIFNpbmNlIHlvdSBuZWVkIHRoaXMgaW5mb3JtYXRpb24gZm9yIGxhdGVyLCBpdCBpcyBpbXBvcnRhbnQgdG8gdXNlICZuYnNwOyoqPC0qKiB0byBjcmVhdGUgYW4gb2JqZWN0IG91dCBvZiB0aGUgaW1wb3J0ZWQgZGF0YS4gSW4gdGhpcywgYW5kIGZ1dHVyZSBleGVyY2lzZXMsIHlvdSB3aWxsIHNlZSB0aGF0IG9wZXJhdG9yIHVzZWQgZnJlcXVlbnRseSB0byBjcmVhdGUgb2JqZWN0cyBmb3IgYW5hbHlzaXMuIA0KDQpJbiBvcmRlciB0byBjcmVhdGUgYSBtYXAgb2YgZWxlY3RyaWNhbCB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIHBlciBzdGF0ZSB5b3UgbmVlZCB0byBvYnRhaW4gaW5mb3JtYXRpb24gZm9yIHRoZSBzdGF0ZXMgYW5kIGNyZWF0ZSBhIG5ldyBvYmplY3QuIFRoZSBgYGB0aWR5dmVyc2VgYGAgcGFja2FnZSBpcyBhIHJldGFpbmVyIGZvciBhIG51bWJlciBvZiBpbmRpdmlkdWFsIHBhY2thZ2VzIGluY2x1ZGluZyB0aGUgX0dyYW1tYXIgb2YgR3JhcGhpY3NfIG9yIF9nZ3Bsb3QyXyBwYWNrYWdlLiBUaGlzIHBhY2thZ2Ugd2lsbCBmcmVxdWVudGx5IGJlIHVzZWQgdG8gZGlzcGxheSB5b3VyIGRhdGEsIGJ1dCBpdCBhbHNvIGNvbnRhaW5zIGdlb2dyYXBoaWMgaW5mb3JtYXRpb24gZm9yIHRoZSBVUy4gWW91IGNhbiBvYnRhaW4gdGhhdCBpbmZvcm1hdGlvbiBieSB1c2luZyB0aGUgYGBgbWFwX2RhdGFgYGAgZnVuY3Rpb24uIEluIGEgbmV3IGNvZGUgYmxvY2ssIHlvdSBjYW4gdXNlIGBgYD9tYXBfZGF0YWBgYCB0byB2aWV3IGhlbHAgaW5mb3JtYXRpb24gb24gdGhlIGZ1bmN0aW9uLiBBbHRlcm5hdGl2ZWx5IHlvdSBjYW4gdmlldyB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgYW55IHBhY2thZ2Ugb3IgZnVuY3Rpb24gYnkgc2VhcmNoaW5nIHRoZSBwYWNrYWdlIG9yIGZ1bmN0aW9uIG5hbWUgYW5kIGNyYW4gXyhDb21wcmVoZW5zaXZlIFIgQXJjaGl2ZSBOZXR3b3JrKV8uIEZvciB0aGlzIGZ1bmN0aW9uIHlvdSB3b3VsZCBzZWFyY2ggYGBgbWFwX2RhdGEgY3JhbmBgYCBhbmQgdGhlIGZpcnN0IGxpbmsgaXMgbGlrZWx5IHRvIGJlIHRoZSBbUkRvY3VtZW50YXRpb24gcGFnZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2dncGxvdDIvdmVyc2lvbnMvMy4zLjMvdG9waWNzL21hcF9kYXRhKSBmb3IgdGhlIGZ1bmN0aW9uLiBXaXRoaW4gdGhpcyBkb2N1bWVudGF0aW9uIHlvdSB3aWxsIGZpbmQgdGhlIGFyZ3VtZW50cyBhdmFpbGFibGUgZm9yIHRoZSBmdW5jdGlvbiBhbmQgZXhhbXBsZSBzY3JpcHRzLiBTbyB0byBjcmVhdGUgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gZm9yIHRoZSBjb250aW5lbnRhbCBVUyB5b3UgY2FuIHVzZToNCg0KYGBge3Igc3RhdGVzLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp1cyA8LSBtYXBfZGF0YSgnc3RhdGUnKQ0KYGBgDQoNClVzaW5nIHRoZSBfR3JhbW1hciBvZiBHcmFwaGljc18gcGFja2FnZSwgYGBgZ2dwbG90MmBgYCwgeW91IGNhbiBjcmVhdGUgYSB2aXN1YWxpemF0aW9uIG9mIHRoaXMgZGF0YS4gSGVyZSBpcyB0aGF0IHNjcmlwdDoNCg0KYGBge3Igc3RhdGVzIG1hcCwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KHVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwKSwgY29sb3IgPSAid2hpdGUiKQ0KYGBgDQpJbiB0aGlzIHNjcmlwdCB5b3UgaWRlbnRpZmllZCB0aGF0IHlvdSB3YW50ZWQgdG8gdXNlIGBgYGdncGxvdGBgYCB0byB2aXN1YWxpemUgdGhlICoqdXMqKiBvYmplY3QgeW91IGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHN0ZXAuIE5leHQgYGBgZ2dwbG90YGBgIG5lZWRzIHRvIGtub3cgd2hhdCBzb3J0IG9mIG9iamVjdCB0byBkcmF3LiBUaGlzIGlzIGRvbmUgYnkgdXNpbmcgdGhlIGBgYGdlb21fYGBgIGZ1bmN0aW9uIGZvbGxvd2VkIGJ5IGEgdHlwZSBvZiBnZW9tZXRyeS4gVGhleSBpbmNsdWRlIHBvaW50LCBsaW5lLCBwb2x5Z29uIGFuZCBvdGhlciBnZW9tZXRyaWVzIHN1Y2ggYXMgaGlzdG9ncmFtcywgYm94cGxvdHMsIHZpb2xpbiBwbG90cyBmb3Igc3RhdGlzdGljcywgb3IgY29udG91cnMsIHJhc3RlcnMsIGFuZCB0aWxlcyBmb3IgdGhyZWUgZGltZW5zaW9uYWwgZGF0YS4gU28gZm9yIHRoaXMgc3RlcCB5b3UgdXNlZCBgYGBnZW9tX3BvbHlnb25gYGAuIE5leHQsIGBgYGdncGxvdGBgYCBuZWVkcyB0byBrbm93IGhvdyB0aGUgZGF0YSBzaG91bGQgYmUgZGlzcGxheWVkLiBJZiB5b3UgY3JlYXRlIGEgbmV3IGNvZGUgYmxvY2sgYW5kIHR5cGUgYGBgc3RyKHVzKWBgYCB5b3UgY2FuIHNlZSB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhIGFuZCBhIGZldyBvZiB0aGUgdmFyaWFibGVzLiBZb3Ugd2lsbCBub3RpY2UgdGhlIGRhdGFzZXQgY29udGFpbnMgX2xvbmdfIChsb25naXR1ZGUpLCBfbGF0XyAobGF0aXR1ZGUpLCBfZ3JvdXBfLCBfb3JkZXJfLCBfcmVnaW9uXyAodGhlIHN0YXRlIG5hbWVzKSwgYW5kIF9zdWJyZWdpb25fLiBTbyBpbiBgYGBnZ3Bsb3RgYGAgeW91IHByb3ZpZGUgYSBzZXJpZXMgb2YgYWVzdGhldGljcyB1c2luZyBgYGBhZXMoKWBgYCB0byBkaXJlY3QgYGBgZ2dwbG90YGBgIG9uIGhvdyB0byBkaXNwbGF5IHRoZSBkYXRhLiBJbiB0aGlzIGNhc2UsIGBgYHggPSBsb25nLCB5ID0gbGF0YGBgLCBhbmQgeW91IG5lZWQgdG8gdGVsbCBpdCB0byBvcmdhbml6ZSB0aGUgZ3JvdXBzIGJ5IHRoZSBjYXRlZ29yeSBncm91cC4gSWYgeW91IGxlYXZlIG91dCBfZ3JvdXBfIGZvciB0aGlzIHNwZWNpZmljIHNjcmlwdCwgYGBgZ2dwbG90YGBgIHdpbGwgYmUgdW5zdXJlIHdoYXQgb3JkZXIgdG8gZHJhdyB0aGUgcG9seWdvbnMgYW5kIHlvdXIgbWFwIHdpbGwgbm90IGFwcGVhciBjb3JyZWN0bHkuIGBgYGNvbG9yID0gIndoaXRlImBgYCB0ZWxscyBgYGBnZ3Bsb3RgYGAgdG8gdXNlIHdoaXRlIGJvcmRlcnMgZm9yIHRoZSBpbmRpdmlkdWFsIHN0YXRlcy4gV2hhdCBkbyB5b3UgdGhpbmsgd291bGQgaGFwcGVuIGlmIHlvdSBjaGFuZ2UgdGhlIHdvcmQgKipfY29sb3JfKiogdG8gKipfZmlsbF8qKiZuYnNwOz8gSW4gdGhlIHJlc3VsdGluZyBpbWFnZSwgYGBgZ2dwbG90YGBgIHVzZWQgdGhlIGluZm9ybWF0aW9uIGZyb20geW91ciBhZXN0aGV0aWNzIHRvIGRyYXcgdGhlIHBvbHlnb25zIGFuZCBhdXRvbWF0ZSBsYWJlbHMgZm9yIHRoZSB4IGFuZCB5IGF4ZXMuIEluIGEgbGF0ZXIgc3RlcCB5b3Ugd2lsbCBsZWFybiBob3cgdG8gY3VzdG9taXplIHRob3NlIGxhYmVscy4NCg0KSXQgbWF5IHNlZW0gYXMgaWYgdGhpcyBpcyBhIGRpZmZpY3VsdCB3YXkgdG8gdmlldyB0aGUgZGF0YS4gSW4gb3RoZXIgc29mdHdhcmUgd2l0aCBhIGdyYXBoaWNhbCB1c2VyIGludGVyZmFjZSAoR1VJKSB5b3Ugd291bGQgbW9zdCBsaWtlbHkgY2xpY2sgb3BlbiwgbmF2aWdhdGUgdG8gdGhlIGZvbGRlciBjb250YWluaW5nIHRoZSBkYXRhLCBkb3VibGUtY2xpY2sgb24gdGhhdCBkYXRhc2V0LCBhbmQgdGhlbiBpdCB3b3VsZCBhcHBlYXIgb24geW91ciBzY3JlZW4uIEVzc2VudGlhbGx5LCBldmVyeSB0aW1lIHlvdSBjbGljayAib3BlbiIgb24gYSBHVUkgaW50ZXJmYWNlLCBpdCBpcyBleGVjdXRpbmcgYSBzcGVjaWZpYyBzZXQgb2Ygc2NyaXB0cyB0byAxLikgb3BlbiB0aGUgbmF2aWdhdGlvbiB3aW5kb3csIDIuKSBhbGxvdyB0aGUgc2VsZWN0ZWQgZmlsZSB0byBiZSBpbXBvcnRlZCwgYW5kIDMuKSB0aGVuIGRpc3BsYXkgdGhlIGluZm9ybWF0aW9uIG9uIHlvdXIgc2NyZWVuLiBXaGF0IHlvdSBkaWQgYWJvdmUgaW4gdGhyZWUgbGluZXMgb2YgY29kZSB3YXMgdG8gdGVsbCBgYGBnZ3Bsb3RgYGAgdG8gMS4pIGNyZWF0ZSBhbiBvYmplY3QgY2FsbGVkIF91c18gYW5kIDIuKSBkaXNwbGF5IGl0IG9uIHRoZSBzY3JlZW4gd2l0aCBzb21lIHNwZWNpZmljIHBhcmFtZXRlcnMuIFRoZSBiZW5lZml0IG9mIGNvbXBsZXRpbmcgdGhpcyBpbiAqKlIqKiB2ZXJzdXMgc29tZXRoaW5nIHdpdGggYSBHVUkgaW50ZXJmYWNlIGlzLCBpZiB5b3UgaGFkIHRocmVlIG1vcmUgc2ltaWxhciBkYXRhc2V0cyB0byB2aWV3LCB5b3Ugd291bGQgc2ltcGx5IGNoYW5nZSBfVVNfIHRvIGFub3RoZXIgb2JqZWN0IGFuZCByZS1ydW4gdGhlIHNjcmlwdC4gVG8gcmVwZWF0IHRoZSBwcm9jZXNzIGluIGEgR1VJIGludGVyZmFjZSB5b3Ugd291bGQgbmVlZCB0byByZXBlYXQgYWxsIG9mIHRoZSBzdGVwcyBmcm9tIHRoZSBiZWdpbm5pbmcuIFRoaXMgbWlnaHQgbm90IHNlZW0gbGlrZSBtdWNoIGZvciB0aHJlZSBzdGVwcywgYnV0IHdoYXQgaWYgeW91ciB2aXN1YWxpemF0aW9uIGhhZCB0d2VudHkgc3RlcHMsIGFzIG1hbnkgZG8/IEluICoqUioqIHlvdSB3b3VsZCBzdGlsbCBzaW1wbHkgY2hhbmdlIHRoZSBkYXRhc2V0IGFuZCBydW4gdGhlIHNhbWUgc2NyaXB0LCBidXQgaW4gb3RoZXIgcHJvZ3JhbXMgeW91IHdvdWxkIG5lZWQgdG8gcmVwZWF0IHRoZSBzYW1lIHR3ZW50eSBzdGVwcyBmb3IgZWFjaCBkYXRhc2V0LiBBZGRpdGlvbmFsbHksIGlmIGEgY29sbGVhZ3VlIHdhbnRlZCB0byBkaXNwbGF5IHNvbWUgZGF0YSBpbiB0aGUgc2FtZSB3YXksIHlvdSBjYW4gZWl0aGVyIGNvcHkgYW5kIHBhc3RlIHRoZSBjb2RlIG9yIHR5cGUgb3V0IGVhY2ggb2YgdGhlIHR3ZW50eSBzdGVwcyB3aXRoIGRpcmVjdGlvbnMuIFdoaWNoIG9mIHRoZXNlIHNlZW1zIHRvIGJlIG1vcmUgY29uc2lzdGVudGx5IHJlcGVhdGFibGU/IE9uY2UgeW91IGJlZ2luIHRvIHVuZGVyc3RhbmQgdGhlIHN5bnRheCAob3JkZXIgb3IgYXJyYW5nZW1lbnQgb2Ygd29yZHMgYW5kIHBocmFzZXMgdG8gZm9ybSBwcm9wZXIgc2NyaXB0cykgeW91IHdpbGwgYmUgbW9yZSBlYXNpbHkgYWJsZSB0byBpbnRlcnByZXQgc2FtcGxlIHNjcmlwdHMgYW5kIGZpeCBlcnJvcnMgaW4geW91ciBvd24gY29kZS4NCg0KPGJpZz48Yj5RdWVzdGlvbiBOby4gMTwvYj48L2JpZz4NCjxibG9ja3F1b3RlPg0KWW91IHVzZWQgYGBgZ2dwbG90KHVzKSArIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvciA9ICJ3aGl0ZSIpYGBgIHRvIGNyZWF0ZSB0aGUgdmlzdWFsaXphdGlvbiBpbiB0aGlzIHN0ZXAuIFdoYXQgc2NyaXB0IHdvdWxkIHlvdSB1c2UgdG8gbWFrZSB0aGUgc2FtZSBtYXAgYnV0IHdpdGggX2JsYWNrXyBib3JkZXJzIGFuZCBfYmx1ZV8gc3RhdGVzPyBBZGQgYSBjb2RlIGNlbGwgYmVsb3cgdGhpcyBvbmUsIHR5cGUgdGhlIHNjcmlwdCwgYW5kIHJ1biBpdCB0byB2aWV3IHRoZSBvdXRwdXQuDQo8c21hbGw+SGludDogY29sb3IgPSAiLi4uLi4iLCBmaWxsID0gIi4uLi4uIjwvc21hbGw+DQo8L2Jsb2NrcXVvdGU+DQoNCjwvZGV0YWlscz4NCg0KIyMgU3RlcCBUd286IFRoZSBBbmFseXNpcw0KDQpJbiB0aGlzIHN0ZXAgeW91IHdpbGwgb3JnYW5pemUgYW5kIGRpc3BsYXkgdGhlIGRhdGEgaW4gb3JkZXIgdG8gcHJlcGFyZSBpdCBmb3IgdGhlIGZpbmFsIHZpc3VhbGl6YXRpb24uIA0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpOb3cgdGhhdCB5b3UgaGF2ZSB0aGUgZGF0YSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbiBhbmQgdW5kZXJzdGFuZCBob3cgdG8gYWNjZXNzIHRoZSB1bmRlcmx5aW5nIGRhdGEsIHlvdSBuZWVkIHRvIGN1c3RvbWl6ZSB0aGUgdmlldyBzbyB5b3UgY2FuIHNlZSB0aGUgc3BhdGlhbCBkaXN0cmlidXRpb24gb2YgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBpbiB0aGUgVVMuIEFzIHlvdSBtYXkgaGF2ZSBndWVzc2VkIGJ5IG5vdywgdGhlcmUgYXJlIGEgbnVtYmVyIG9mIGRpZmZlcmVudCB3YXlzIHRvIGFjY2VzcyB0aGUgc3ltYm9sb2d5IHRvb2wgbmVlZGVkIHRvIGNoYW5nZSBob3cgdGhlIGRhdGEgaXMgZGlzcGxheWVkLiANCg0KMS4gUmlnaHQtY2xpY2sgb24gX2V2X2RhdGFfIGluIHRoZSB0YWJsZSBvZiBjb250ZW50cyBhbmQgY2xpY2sgKipTeW1ib2xvZ3kqKg0KMi4gV2l0aCBfZXZfZGF0YV8gc2VsZWN0ZWQgaW4gdGhlIHRhYmxlIG9mIGNvbnRlbnRzIGNsaWNrIG9uIHRoZSBfQXBwZXJhbmNlXyBUYWIgYW5kIGNsaWNrIHRoZSAqKlN5bWJvbG9neSoqIGJ1dHRvbg0KMy4gV2l0aCBfZXZfZGF0YV8gc2VsZWN0ZWQgaW4gdGhlIHRhYmxlIG9mIGNvbnRlbnRzIGNsaWNrIG9uIHRoZSAqKlN5bWJvbG9neSoqIHRhYiBhdCB0aGUgYm90dG9tIG9mIHRoZSByaWdodCBzaWRlIHBhbmVsIG9mIHRoZSBzY3JlZW4uDQoNCkFsbCB0aHJlZSBvZiB0aGVzZSBtZXRob2RzIHdpbGwgc2hvdyB0aGUgc3ltYm9sb2d5IG9wdGlvbnMgaW4gYSBwYW5lbCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgc2NyZWVuLiBGcm9tIGhlcmUgeW91IHdpbGwgbmVlZCB0byBjaGFuZ2UgdGhlIF9QcmltYXJ5IFN5bWJvbG9neV8gZnJvbSAqKlNpbmdsZSBTeW1ib2wqKiB0byAqKkdyYWR1YXRlZCBDb2xvcioqLiBUaGlzIGNhbiBhbHNvIGJlIGRvbmUgYnkgY2xpY2tpbmcgb24gdGhlIGRyb3AtZG93biBtZW51IGZvciAqKlN5bWJvbG9neSoqIGluIHRoZSBfQXBwZXJhbmNlXyBUYWIuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1zeW1ib2xvZ3ktdGFiLnBuZyIgYWx0PSJTeW1ib2xvZ3kiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+DQoNCkFmdGVyIHNlbGVjdGluZyBfR3JhZHVhdGVkIENvbG9yc18geW91IHdpbGwgaGF2ZSBzZXZlcmFsIG90aGVyIG9wdGlvbnMgYXZhaWxhYmxlIGluIHRoZSBzeW1ib2xvZ3kgd2luZG93LiBJbiBvcmRlciB0byBzb3J0IGJ5IHRoZSBudW1iZXIgb2YgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBwZXIgc3RhdGUgeW91IHdpbGwgbmVlZCB0byBjaGFuZ2UgdGhlIF9GaWVsZF8gY2F0ZWdvcnkgdG8gKipldl9zdGF0aW9uKiouIE5leHQsIGluIHRoZSBfTWV0aG9kXyBjYXRlZ29yeSB0byAqKkdlb21ldHJpYyBJbnRlcnZhbCoqLiBCZWNhdXNlIG9mIHRoZSByYW5nZSBvZiB2YWx1ZXMsIGNob29zaW5nIHRoaXMgb3B0aW9uIHdpbGwgaGVscCB0byBiYWxhbmNlIG91dCB0aGUgYmlhcyBvZiBsYXJnZXIgdmFsdWVzLiBJbiB0aGUgX0NsYXNzZXNfIGNhdGVnb3J5IGNob29zZSA1LiBGaW5hbGx5IHVzaW5nIHRoZSBkcm9wLWRvd24gbWVudSBuZXh0IHRvIF9Db2xvciBTY2hlbWVfLCBzZWxlY3QgYSBjb2xvciBvcHRpb24gZm9yIHlvdXIgdmlzdWFsaXphdGlvbi4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLXZpcmlkaXMucG5nIiBhbHQ9IlN5bWJvbG9neSBvcHRpb25zIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjUyNSI+PC9wPjxicj4NCg0KRGVwZW5kaW5nIG9uIHRoZSBjb2xvciBzY2hlbWUgeW91IGNob3NlLCB5b3VyIHNjcmVlbiBzaG91bGQgbm93IGxvb2sgc2ltaWxhciB0byB0aGlzOg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZXYtZGlzcGxheS5wbmciIGFsdD0iU3ltYm9sb2d5IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPg0KDQpPbiB0aGUgbGVmdCBpbiB0aGUgdGFibGUgb2YgY29udGVudHMgYmVuZWF0aCB0aGUgX2V2X2RhdGFfJm5ic3A7IGxheWVyIHlvdSB3aWxsIHNlZSB0aGUgcmFuZ2Ugb2YgdmFsdWVzIHJlcHJlc2VudGVkIGJ5IGVhY2ggY29sb3IgbWF0Y2hpbmcgdGhvc2UgdmFsdWVzIGZvciBlYWNoIGluZGl2aWR1YWwgc3RhdGUgb24geW91ciBtYXAuIEF0IHRoaXMgcG9pbnQgeW91IHNob3VsZCBzYXZlIHlvdXIgd29yay4gVGhpcyBjYW4gYmUgZG9uZSBieSBnb2luZyB0byB0aGUgX1Byb2plY3QgVGFiID4gU2F2ZV8mbmJzcDssIHVzaW5nIHRoZSBfQ1JUTCtTXyZuYnNwOyBrZXlib2FyZCBzaG9ydGN1dCwgb3IgdXNpbmcgdGhlIHF1aWNrIHNhdmUgYnV0dG9uIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1xdWljay1zYXZlLnBuZyIgYWx0PSJTYXZlIHByb2plY3QiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+Jm5ic3A7IHRvIHNhdmUgeW91ciBjdXJyZW50IHByb2plY3QuDQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDI8L2I+PC9iaWc+PGJyPg0KSW4gdGhpcyBzdGVwIHlvdSB1c2VkIGEgX0dyYWR1YXRlZCBDb2xvcnNfJm5ic3A7IHN5bWJvbG9neSB0byB2aXN1YWxpemUgdGhlIGRhdGEgYW5kIG9yZ2FuaXplZCB0aGUgdmFsdWVzIHVzaW5nIGEgKipHZW9tZXRyaWMgSW50ZXJ2YWwqKiBtZXRob2QuIFRoZXJlIGFyZSBzZXZlcmFsIG90aGVyIG9wdGlvbnMgd2l0aGluIF9NZXRob2RfIHRoYXQgY291bGQgaGF2ZSBiZWVuIHNlbGVjdGVkIGFzIGEgZGlzcGxheSBtZXRob2Qgc3VjaCBhczogDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1zeW1ib2xvZ3ktbWV0aG9kLnBuZyIgYWx0PSJTeW1ib2xvZ3kgbWV0aG9kcyIgd2lkdGg9IjIyNSIgaGVpZ2h0PSI0MTAiPjwvcD48YnI+DQoNCjxibG9ja3F1b3RlPg0KQWRqdXN0aW5nIHRoZSBfTWV0aG9kXyB2YWx1ZSwgZGVzY3JpYmUgaG93IHRoZSB2aXN1YWxpemF0aW9uIGNoYW5nZXMgd2l0aCBlYWNoIG9mIHRoZXNlIGRpZmZlcmVudCBvcHRpb25zLg0KPC9ibG9ja3F1b3RlPg0KDQpSZWNvcmQgeW91ciBhbnN3ZXJzIGFuZCBzdWJtaXQgYXQgdGhlIGNvbmNsdXNpb24gb2YgdGhlIGxhYi4NCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiMwMDY0MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpOb3cgdGhhdCB5b3UgaGF2ZSB0aGUgZGF0YSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbiBhbmQgdW5kZXJzdGFuZCBob3cgdG8gYWNjZXNzIHRoZSB1bmRlcmx5aW5nIGRhdGEsIHlvdSBuZWVkIHRvIGN1c3RvbWl6ZSB0aGUgdmlldyBzbyB5b3UgY2FuIHNlZSB0aGUgc3BhdGlhbCBkaXN0cmlidXRpb24gb2YgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBpbiB0aGUgVVMuIFRvIGJlZ2luIHlvdSB3aWxsIG5lZWQgdG8gY29udHJvbC1jbGljayAobWFjT1MpIG9yIHJpZ2h0LWNsaWNrIChQQykgb24gdGhlICoqZXZfZGF0YSoqIGluIHlvdXIgX2xheWVyc18gYW5kIGNsaWNrIG9uIHByb3BlcnRpZXMuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtcmNwcm9wZXJ0aWVzLnBuZyIgYWx0PSJSaWdodCBDbGljayBQcm9wZXJ0aWVzIiBzdHlsZT0id2lkdGg6NjAlIj48L3A+PGJyPg0KDQpJbiB0aGUgcmVzdWx0aW5nIHdpbmRvdyB5b3Ugd2lsbCBuZWVkIHRvIGdvIHRvIHRoZSAqKlN5bWJvbG9neSoqIHRhYiAoPGk+MS48L2k+KSBpbiB0aGUgbGVmdC1oYW5kIG1lbnUuIEluIHRoaXMgd2luZG93IHlvdSBjYW4gY2hhbmdlIHRoZSBmaWxsIG9mIHRoZSBwb2x5Z29ucyBhbmQgY2hhbmdlIHRoZWlyIG9wYWNpdHkgKG9yIGxldmVsIG9mIHRyYW5zcGFyZW5jeSkuIFlvdSBjYW4gYWxzbyBhZGp1c3QgdGhlIHN5bWJvbG9neSBvZiB5b3VyIGRhdGFzZXQuIFRob3NlIG9wdGlvbnMgYXJlIGF2YWlsYWJsZSBpbiBhIHNlbGVjdGlvbiBiYXIgYXQgdGhlIHRvcCBvZiB0aGUgd2luZG93LiBGb3IgdGhpcyBkYXRhc2V0IHRoZXkgYXJlOg0KDQo8dGFibGUgc3R5bGU9IndpZHRoOjUwJTttYXJnaW4tbGVmdDphdXRvO21hcmdpbi1yaWdodDphdXRvOyI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPk5vIFN5bWJvbDwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1uby1zeW1ib2xzLnBuZyIgYWx0PSJObyBTeW1ib2xzIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPlNpbmdsZSBTeW1ib2w8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtc2luZ2xlLXN5bWJvbC5wbmciIGFsdD0iU2luZ2xlIFN5bWJvbCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5DYXRlZ29yaXplZDwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1jYXRlZ29yaXplZC1zeW1ib2wucG5nIiBhbHQ9IkNhdGVnb3JpemVkIFN5bWJvbHMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+R3JhZHVhdGVkPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWdyYWR1YXRlZC1zeW1ib2wucG5nIiBhbHQ9IkdyYWR1YXRlZCBTeW1ib2xzIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPlJ1bGUtYmFzZWQ8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtcnVsZS1iYXNlZC1zeW1ib2wucG5nIiBhbHQ9IlJ1bGUgQmFzZWQgU3ltYm9scyIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5JbnZlcnRlZCBQb2x5Z29uczwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1pbnZwb2x5LXN5bWJvbC5wbmciIGFsdD0iSW52ZXJ0ZWQgUG9seWdvbiBTeW1ib2xzIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPjIuNSBEPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLTI1RC1zeW1ib2wucG5nIiBhbHQ9IjIuNSBEIFN5bWJvbHMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCjwvdGFibGU+DQo8YnI+DQpGb3IgdGhpcyBzcGVjaWZpYyBkYXRhIHlvdSB3aWxsIGNob29zZSBfR3JhZHVhdGVkXyAoPGk+Mi48L2k+KSBzaW5jZSB0aGUgZGF0YSBuZWVkcyB0byBiZSBkaXNwbGF5ZWQgYnkgYSByYW5nZSBvZiBudW1lcmljIHZhbHVlcy4gTmV4dCB5b3Ugd2lsbCBzZWxlY3QgdGhlICoqZXZfc3RhdGlvbioqIHZhcmlhYmxlICg8aT4zLjwvaT4pIGluIHRoZSBkYXRhc2V0LiBJbiB0aGUgZHJvcC1kb3duIGZvciB0aGUgX0NvbG9yIHJhbXBfIG9wdGlvbiB5b3UgaGF2ZSBhIG51bWJlciBvZiBjb2xvciBvcHRpb25zIHRvIGNob29zZS4gRm9yIHRoaXMgZXhhbXBsZSBzZWxlY3QgKipWaXJpZGlzKiogKDxpPjQuPC9pPikuICBEbyB5b3UgcmVjYWxsIHdoYXQgdGhlIHJhbmdlIG9mIHZhbHVlcyBmb3IgdGhlICoqZXZfc3RhdGlvbioqIGRhdGE/IEJlY2F1c2UgdGhlIGxhcmdlc3QgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDMwLDAwMCBhbmQgdGhlIHNtYWxsZXN0IHZhbHVlIGlzIGFyb3VuZCAxMDAsIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHRoZSBfTW9kZV8gdG8gYSBfbG9nYXJpdGhtaWMgc2NhbGVfICg8aT41LjwvaT4pIHRvIHByb3Blcmx5IGRpc3BsYXkgdGhlIGRhdGEgd2hpbGUgYXZvaWRpbmcgYSBiaWFzIG9mIHRoZSBsYXJnZXIgdmFsdWVzLiBDaGFuZ2UgdGhlIF9DbGFzc2VzXyB0byA2ICg8aT42LjwvaT4pIGFuZCBjbGljayAqKk9LKiogKDxpPjcuPC9pPikuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtc3ltYm9sb2d5LW9wdGlvbnMucG5nIiBhbHQ9IlN5bWJvbG9neSBQcm9wZXJ0aWVzIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KPHAgYWxpZ249ImNlbnRlciI+PHNtYWxsPjxiPkJlY2F1c2UgdGhlIG1hY09TIGFuZCBQQyB2ZXJzaW9ucyBhcmUgaWRlbnRpY2FsIG9ubHkgb25lIGltYWdlIGlzIHNob3duLjwvYj48L3NtYWxsPjwvcD48YnI+DQoNCllvdXIgc2NyZWVuIHNob3VsZCBub3cgbG9vayBzaW1pbGFyIHRvIHRoaXM6DQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtdmlyaWRpcy5wbmciIGFsdD0iR3JhZHVhdGVkIERhdGEiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+DQoNCkF0IHRoaXMgcG9pbnQgeW91IHNob3VsZCBzYXZlIHlvdXIgd29yay4gV2hldGhlciB1c2luZyBtYWNPUyBvciBQQywgb24gdGhlIG1lbnUgYmFyIGdvIHRvIF9Qcm9qZWN0ID4gU2F2ZSBBcy4uLl8gYW5kIHNhdmUgeW91ciBwcm9qZWN0IGluIHRoZSBmb2xkZXIgeW91IGNyZWF0ZSBmb3IgdGhpcyBleGVyY2lzZS4NCg0KPGJpZz48Yj5RdWVzdGlvbiBOby4gMjwvYj48L2JpZz48YnI+DQpJbiB0aGlzIHN0ZXAgeW91IHVzZWQgYSBfR3JhZHVhdGVkXyBzeW1ib2xvZ3kgdG8gdmlzdWFsaXplIHRoZSBkYXRhIGFuZCBvcmdhbml6ZWQgdGhlIHZhbHVlcyBfbG9nYXJpdGhtaWNhbGx5Xy4gVGhlcmUgd2VyZSBzZXZlcmFsIG90aGVyIG9wdGlvbnMgd2l0aGluIF9tb2RlXyBtZW51LiANCg0KPHRhYmxlIHN0eWxlPSJ3aWR0aDo3NSU7bWFyZ2luLWxlZnQ6YXV0bzttYXJnaW4tcmlnaHQ6YXV0bzsiPg0KICA8dHI+DQogICAgPHRkPjxsaT5FcXVhbCBDb3VudCAoUXVhbnRpbGUpPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWVxdWFsLWNvdW50LnBuZyIgYWx0PSJFcXVhbCBDb3VudCIgd2lkdGg9IjE0MCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+RXF1YWwgSW50ZXJ2YWw8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtZXF1YWwtaW50ZXJ2YWwucG5nIiBhbHQ9IkVxdWFsIEludGVydmFsIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5Mb2dhcml0aG1pYyBTY2FsZTwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1sb2ctc2NhbGUucG5nIiBhbHQ9IkxvZ2FyaXRobWljIFNjYWxlIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5OYXR1cmFsIEJyZWFrcyAoSmVua3MpPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWplbmtzLnBuZyIgYWx0PSJOYXR1cmFsIEJSZWFrcyAoSmVua3MpIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5QcmV0dHkgQnJlYWtzPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXByZXR0eS1icmVha3MucG5nIiBhbHQ9IlByZXR0eSBCcmVha3MiIHdpZHRoPSIxNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPlN0YW5kYXJkIERldmlhdGlvbjwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1zZC5wbmciIGFsdD0iU3RhbmRhcmQgRGV2aWF0aW9uIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KPC90YWJsZT4NCg0KPGJsb2NrcXVvdGU+DQpBZGp1c3RpbmcgdGhlIF9tb2RlXyB2YWx1ZSwgZGVzY3JpYmUgaG93IHRoZSB2aXN1YWxpemF0aW9uIGNoYW5nZXMgd2l0aCBlYWNoIG9mIHRoZXNlIGRpZmZlcmVudCBvcHRpb25zLg0KPC9ibG9ja3F1b3RlPg0KUmVjb3JkIHlvdXIgYW5zd2VycyBhbmQgc3VibWl0IGF0IHRoZSBjb25jbHVzaW9uIG9mIHRoZSBsYWIuDQo8L2RldGFpbHM+DQo8aHI+PC9ocj4NCg0KPGRldGFpbHM+DQo8c3VtbWFyeT48YmlnPlZpZXcgRGlyZWN0aW9ucyBpbiA8Yj4gW1Jde3N0eWxlPSJjb2xvcjojNjQ5NUVEIn0gPC9iPjwvYmlnPjwvc3VtbWFyeT4NCg0KTm93IHRoYXQgeW91IGhhdmUgZGF0YXNldHMgZm9yIGVsZWN0cmljIHZlaGljbGUgY2hhcmdpbmcgc3RhdGlvbnMgKG9iamVjdCA9ICoqZXZzKiopIGFuZCB0aGUgY29udGluZW50YWwgVVMgKG9iamVjdCA9ICoqdXMqKiksIHlvdSBuZWVkIHRvIGNvbWJpbmVkIHRoYXQgZGF0YSB0byBhbGxvdyBmb3IgdGhlIHN0YXRlcyB0byBiZSBjb2xvciBjb2RlZCBiYXNlZCBvbiB0aGUgbnVtYmVyIG9mIGNoYXJnaW5nIHN0YXRpb25zIHBlciBzdGF0ZS4gVG8gZG8gdGhpcyB5b3Ugd2lsbCB1c2UgYSBmdW5jdGlvbiBjYWxsZWQgYGBgbWVyZ2VgYGAgZnJvbSB0aGUgYmFzZSAqKlIqKiBmdW5jdGlvbnMgdGhhdCB3aWxsIGFsbG93IHlvdSB0byBjb21iaW5lIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSAqKmV2cyoqIGFuZCAqKnVzKiogaW50byBhIHNpbmdsZSBkYXRhc2V0IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gZnJvbSBib3RoIGJhc2VkIG9uIGEgY29tbW9uIHZhcmlhYmxlLiBTbyB0byBzdGFydCB5b3Ugd2lsbCBuZWVkIHRvIGRldGVybWluZSB3aGF0IHZhcmlhYmxlKHMpIGFyZSBjb250YWluZWQgd2l0aGluIGVhY2ggZGF0YXNldC4gWW91IGhhdmUgc2VlbiBob3cgdG8gZXhhbWluZSBkYXRhc2V0cyB1c2luZyBib3RoIGBgYGhlYWQoKWBgYCBhbmQgYGBgc3RyKClgYGAgYWxyZWFkeSBpbiB0aGlzIGV4ZXJjaXNlLiBDcmVhdGUgYSBuZXcgY29kZSBibG9jayBhbmQgZXhhbWluZSB0aGUgc3RydWN0dXJlIG9mIGVhY2ggZGF0YXNldC4gWW91IHdpbGwgc2VlIHRoYXQgdGhlcmUgaXMgYSBjb2x1bW4gZm9yIHN0YXRlIG5hbWUgaW4gZWFjaCBleGNlcHQgdGhleSBhcmUgbGFiZWxlZCBkaWZmZXJlbnRseS4gVGhpcyBpcyBpbXBvcnRhbnQgaW5mb3JtYXRpb24geW91IHdpbGwgbmVlZCB0byBwcm9wZXJseSBgYGBtZXJnZWBgYCB0aGUgZGF0YXNldHMuDQoNClRvIGRvIHRoaXMgeW91IHdpbGwgZmlyc3QgY3JlYXRlIGFuIG9iamVjdCAoKio8LSoqKSB3aXRoIGEgbmV3IG5hbWUsIHRoZW4gd2l0aCB0aGUgYGBgbWVyZ2VgYGAgZnVuY3Rpb24gc2V0IHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOg0KDQotIHgsIHdoaWNoIGlzIHRoZSBmaXJzdCBkYXRhIHNldA0KLSB5LCB3aGljaCBpcyB0aGUgc2Vjb25kIGRhdGFzZXQNCi0gYnkueCwgaWRlbnRpZmllcyB0aGUgY29sdW1uIHRvIHVzZSBmb3IgdGhlIG1lcmdlIGluIHgNCi0gYnkueSwgaWRlbnRpZmllcyB0aGUgY29sdW1uIHRvIHVzZSBmb3IgdGhlIG1lcmdlIGluIHkNCi0gYWxsID0gVFJVRSwgd2hpY2ggdGVsbHMgdGhlIGZ1bmN0aW9uIHRvIHJldGFpbiBhbGwgZGF0YQ0KDQpTbyB5b3VyIGZpbmFsIHNjcmlwdCB3aWxsIGJlOg0KDQpgYGB7ciBtZXJnZWQgZGF0YXNldHMsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnN0YXRlcyA8LSBtZXJnZSh4ID0gdXMsIHkgPSBldnMsIGJ5LnggPSAicmVnaW9uIiwgYnkueSA9ICJzdGF0ZSIsIGFsbCA9IFRSVUUpDQpoZWFkKHN0YXRlcykNCmBgYA0KDQpOb3cgeW91IHdpbGwgc2VlIHRoZSBjb2x1bW5zIGZvciAqKmV2cyoqIGFuZCAqKmFiYnJldmlhdGlvbioqIGluY2x1ZGVkIGluIHRoZSAqKnVzKiogZGF0YXNldC4gVGhpcyBuZXcgZGF0YXNldCB3aWxsIGJlIHdoYXQgeW91IHVzZSB0byB2aXN1YWxpemUgdGhlIGluZm9ybWF0aW9uIGluIHRoZSBuZXh0IHN0ZXAuDQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDI8L2I+PC9iaWc+DQo8YmxvY2txdW90ZT4NClVzaW5nIGBgYHN1bW1hcnkoc3RhdGVzKWBgYCBpbiBhIG5ldyBjb2RlIGNlbGwsIHdoYXQgYXJlIHRoZSBsYXJnZXN0IGFuZCBzbWFsbGVzdCBudW1iZXIgb2YgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucz8NCjwvYmxvY2txdW90ZT4NCg0KPC9kZXRhaWxzPg0KDQoNCiMjIFN0ZXAgVGhyZWU6IFRoZSBWaXN1YWxpemF0aW9uDQoNCllvdSB3aWxsIGxlYXJuIGhvdyB0byBjcmVhdGUgYSBncmFwaGljYWwgZGlzcGxheSBvZiB5b3VyIGRhdGEgdGhhdCBpbmNsdWRlcyBjYXJ0b2dyYXBoaWMgZWxlbWVudHMgc3VjaCBhcyBsZWdlbmQsIHNjYWxlIGJhciwgbm9ydGggYXJyb3csIGV0Yy4NCg0KPGRldGFpbHM+PHN1bW1hcnk+PGJpZz5WaWV3IGRpcmVjdGlvbnMgaW4gPGI+IFtBcmNHSVMgUHJvXXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9IDwvYj48L3NwYW4+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpOb3cgaXTigJlzIHRpbWUgdG8gdHVybiB5b3VyIGRhdGEgaW50byBhIG1hcC4gRnJvbSB0aGUgX0luc2VydF8gVGFiIGNsaWNrIG9uIHRoZSAqKk5ldyBMYXlvdXQqKiBidXR0b24gPGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLW5ldy1sYXlvdXQtYnV0dG9uLnBuZyIgYWx0PSJOZXcgbGF5b3V0IGJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4gYW5kIGNob29zZSBhIHBhcGVyIGxheW91dC4gRm9yIHRoaXMgZXhlcmNpc2UgeW91IHNob3VsZCBjaG9vc2UgX0FOU0kgLSBMYW5kc2NhcGUsIExldHRlciA4LjUiIHggMTEiXy4gVGhpcyB3aWxsIG9wZW4gYSBuZXcgc2VjdGlvbiB3aGVyZSB5b3Ugd2lsbCBhZGQgdGhlIGRhdGEsIHRpdGxlLCBsZWdlbmQsIG5vcnRoIGFycm93LCBzY2FsZSBiYXIsIGFuZCB5b3VyIG5hbWUgYW5kIGRhdGUuIElmIHlvdSBoYXZlIGEgbGFyZ2UgZW5vdWdoIHNjcmVlbiwgeW91IGNhbiByaWdodC1jbGljayBvbiB0aGUgbmV3IGxheW91dCA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtbGF5b3V0LnBuZyIgYWx0PSJMYXlvdXQgdGFiIiB3aWR0aD0iODAiIGhlaWdodD0iMjAiPiBhbmQgc2VsZWN0ICoqRmxvYXQqKi4gVGhpcyB3aWxsIGNyZWF0ZSBhIG5ldyB3aW5kb3cgdGhhdCB5b3UgY2FuIHJlc2l6ZSB3aGlsZSBrZWVwaW5nIHRoZSBwcmltYXJ5IHNjcmVlbiBvcGVuLiBPdGhlcndpc2UsIHJlc2l6ZSB0aGUgbGF5b3V0IHNlY3Rpb24gYXMgbmVjZXNzYXJ5IGJ5IG1vdmluZyB5b3VyIGN1cnNvciBiZXR3ZWVuIHRoZSB0d28gc2VjdGlvbnMgdG8gYWRqdXN0IHRoZSBib3JkZXIuIA0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtbGF5b3V0LW1hcC5wbmciIGFsdD0iU2lkZS1ieS1zaWRlIE1hcCBhbmQgTGF5b3V0IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPg0KDQpXaGV0aGVyIHZpZXdpbmcgdGhlIG5ldyBsYXlvdXQgaW4gYSBuZXcgd2luZG93IG9yIHNlY3Rpb24gb24gdGhlIG1hcCBwYWdlLCBjbGljayBvbiB0aGUgX0luc2VydF8gdGFiIGFuZCBjaG9vc2UgdGhlICoqTWFwIEZyYW1lKiogYnV0dG9uLiBGcm9tIHRoZXJlLCBzZWxlY3QgdGhlIG1hcCB0aGF0IGhhcyBhIHJlcHJlc2VudGF0aXZlIGZyYWN0aW9uIGFuZCBoYXMgYW4gaW1hZ2Ugb2YgdGhlIGRhdGEgZnJvbSB0aGUgbWFwIHZpZXcuIA0KDQo8cCBhbGlnbj0iY2VudGVyIj48ZGl2IGNsYXNzPSJ6b29tIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtbWFwLWluc2VydC1yaWJib24ucG5nIiBhbHQ9Ik1hcCBJbnNlcnQgVGFiIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpXaGVuIHBsYWNlZCBvdmVyIHRoZSBsYXlvdXQgb3VyIGN1cnNvciB3aWxsIGJlY29tZSBjcm9zcy1oYWlycyAoKykuIFVzZSBpdCB0byBkcmF3IHRoZSBsb2NhdGlvbiBvZiB0aGUgbWFwIG9uIHRoZSBsYXlvdXQuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1kcmF3LW1hcC1mcmFtZS5wbmciIGFsdD0iSW5zZXJ0IHRoZSBtYXAgZnJhbWUiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+DQoNCllvdXIgbWFwIHdpbGwgbm93IGJlIGltcG9ydGVkIHRvIHRoZSBsYXlvdXQuIFRvIHpvb20gaW4gb3Igb3V0IHlvdSBjYW4gYWRqdXN0IHRoZSByZXByZXNlbnRhdGl2ZSBmcmFjdGlvbiBhdCB0aGUgYm90dG9tIG9mIHRoZSBsYXlvdXQgb3Igb24gdGhlIF9MYXlvdXRfIHRhYiB1c2UgdGhlICoqZml4ZWQgem9vbSoqIHRvb2xzIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy16b29tLXRvb2xzLnBuZyIgYWx0PSJGaXhlZCB6b29tIHRvb2xzIiB3aWR0aD0iNDAiIGhlaWdodD0iMjAiPiB0byBjaGFuZ2UgdGhlIGxldmVsIG9mIHpvb20uIA0KDQo8cCBhbGlnbj0iY2VudGVyIj48ZGl2IGNsYXNzPSJ6b29tIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtbWFwLWxheW91dC1yaWJib24ucG5nIiBhbHQ9Ik1hcCBMYXlvdXQgVGFiIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpUbyBhZGp1c3QgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhLCBjbGljayB0aGUgKipBY3RpdmF0ZSoqIGJ1dHRvbiA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtYWN0aXZhdGUtYnV0dG9uLnBuZyIgYWx0PSJOYXZpZ2F0ZSBCdXR0b24iIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+IGFuZCB1c2UgdGhlICoqRXhwbG9yZSBCdXR0b24qKiA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZXhwbG9yZS1idXR0b24ucG5nIiBhbHQ9Ik5hdmlnYXRlIEJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4gdG8gY2xpY2sgYW5kIGRyYWcgYW5kIG1vdmUgdGhlIGRhdGEgb24gdGhlIG1hcCBmcmFtZSBvbiB0aGUgbGF5b3V0LiBXaGVuIGZpbmlzaGVkIGFkanVzdGluZyB0aGUgdmlldyBkZWFjdGl2YXRlIHRoZSBsYXlvdXQgYnkgY2xpY2tpbmcgdGhlIF9DbG9zZSBhY3RpdmF0ZWQgbWFwIGZyYW1lXyBidXR0b24gPGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLXJldHVybi1sYXlvdXQucG5nIiBhbHQ9IkNsb3NlIGFjdGl2YXRlIG1hcCBmcmFtZSIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIyMCI+IHRvIHJldHVybiB0byB0aGUgbWFwIGxheW91dC4gQWZ0ZXIgeW91IGhhdmUgYWRqdXN0ZWQgdGhlIHpvb20gYW5kIHBvc2l0aW9uaW5nIHlvdXIgbGF5b3V0IHNob3VsZCBsb29rIGxpa2UgdGhpczoNCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWxheW91dC1pbWFnZS5wbmciIGFsdD0iTWFwIGFuZCBMYXlvdXQiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+DQoNCkluIG9yZGVyIHRvIGNvbXBsZXRlIGEgYmFzaWMgbWFwIHlvdSB3aWxsIG5lZWQgdG8gYWRkIGEgbm9ydGggYXJyb3cgPGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLW5vcnRoLWJ1dHRvbi5wbmciIGFsdD0iQWRkIG5vcnRoIGFycm93IiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPiwgc2NhbGUgYmFyIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1zY2FsZS1idXR0b24ucG5nIiBhbHQ9IkFkZCBzY2FsZSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4sIGxlZ2VuZCA8aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtbGVnZW5kLWJ1dHRvbi5wbmciIGFsdD0iQWRkIGxlZ2VuZCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4sIGFuZCB0ZXh0IDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy10ZXh0LWJ1dHRvbi5wbmciIGFsdD0iQWRkIHRleHQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+IHRvIGluY2x1ZGUgYSB0aXRsZSBhbmQgdGhlIG5hbWUgYW5kIGRhdGUgb2YgdGhlIG1hcCBjcmVhdG9yLiBFYWNoIG9mIHRoZXNlIGl0ZW1zIHdvcmtzIGVzc2VudGlhbGx5IHRoZSBzYW1lIGFzIGFkZGluZyB0aGUgbWFwIGRhdGEuIFdoZW4geW91IGNsaWNrIG9uIGVhY2ggdG9vbCB5b3UgY2FuIHVzZSB5b3VyIGN1cnNvciB0byBkcmF3IGl0cyBsb2NhdGlvbiBvbiB0aGUgbWFwLiBZb3Ugd2lsbCBub3RpY2Ugd2l0aCB0aGUgbm9ydGggYXJyb3cgYW5kIHNjYWxlIGJhciB0aGVyZSBpcyBhIGRyb3AtZG93biBtZW51IHRoYXQgYWxsb3dzIHlvdSB0byBzZWxlY3QgdGhlIHNwZWNpZmljIHN0eWxlLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtaXRlbS1kcm9wLWRvd24ucG5nIiBhbHQ9IkRyb3AtZG93biBpbmZvcm1hdGlvbiBmb3Igbm9ydGggYXJyb3cgYW5kIHNjYWxlIGJhciIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCg0KRWFjaCB0aW1lIHlvdSBhZGQgYW4gZWxlbWVudCBzdWNoIGFzIGEgbm9ydGggYXJyb3cgb3Igc2NhbGUgYmFyLCB5b3Ugd2lsbCBub3RpY2UgdGhlIHNlY3Rpb24gb24gdGhlIHJpZ2h0IHdpbGwgcHJvdmlkZSBhIG51bWJlciBvZiBkaWZmZXJlbnQgb3B0aW9ucyB0byBjdXN0b21pemUgdGhlIGVsZW1lbnQuIERlcGVuZGluZyBvbiB0aGUgZWxlbWVudCB5b3UgYXJlIGFkZGluZyB0aGVyZSB3aWxsIGJlIGRpZmZlcmVudCBidXR0b25zIHN1Y2ggYXM6DQoNCjx0YWJsZSBzdHlsZT0id2lkdGg6MTAwJSI+DQogIDxjb2xncm91cD4NCiAgICAgICA8Y29sIHN0eWxlPSJ3aWR0aDogMjAlOyI+DQogICAgICAgPGNvbCBzdHlsZT0id2lkdGg6IDEwJTsiPg0KICAgICAgIDxjb2wgc3R5bGU9IndpZHRoOiA3MCU7Ij4NCiAgPC9jb2xncm91cD4NCiAgPHRyPg0KICAgIDx0ZD5PcHRpb25zPC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWVsZW1lbnQtb3B0aW9ucy5wbmciIGFsdD0iT3B0aW9ucyBidXR0b24iIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgICA8dGQ+QWxsb3dzIHlvdSB0byBtYWtlIGVsZW1lbnRzIHZpc2libGUgb3IgbG9ja2VkLCBjaGFuZ2UgdGhlIHRpdGxlIG9mIHRoZSBlbGVtZW50LCBhZGp1c3QgdGhlIGxhYmVscywgb3IgYWRkIGNvbHVtbnM8L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPkRpc3BsYXk8L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZWxlbWVudC1kaXNwbGF5LnBuZyIgYWx0PSJEaXNwbGF5IGJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICAgIDx0ZD5MZXRzIHlvdSBhZGp1c3QgdGhlIGJvcmRlciwgYmFja2dyb3VuZCwgb3IgYWRkIGEgc2hhZG93IHRvIHRoZSBlbGVtZW50PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5QbGFjZW1lbnQ8L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZWxlbWVudC1wbGFjZW1lbnQucG5nIiBhbHQ9IlBsYWNlbWVudCBidXR0b24iIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgICA8dGQ+QWxsb3dzIHlvdSB0byBmaW5lIHR1bmUgYWRqdXN0IHRoZSBsb2NhdGlvbiBvZiB0aGUgZWxlbWVudCBvbiB0aGUgbWFwIGFuZCBjaGFuZ2UgdGhlIGFwcGVhcmFuY2UgIGFuZCBmb3JtYXQgb2YgdGhlIHRleHQgc3ltYm9sIG9mIHRoZSBlbGVtZW50PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5Qcm9wZXJ0aWVzPC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWVsZW1lbnQtcHJvcGVydGllcy5wbmciIGFsdD0iUHJvcGVydGllcyBidXR0b24iIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgICA8dGQ+VGhpcyBpcyBzcGVjaWZpYyB0byB0aGUgc2NhbGUgYmFyIGFuZCBsZXRzIHlvdSBhZGp1c3QgdGhlIG51bWJlciBvZiBkaXZpc2lvbnMsIG51bWJlcnMsIG1hcmtzLCBhbmQgYmFycyBvZiB0aGUgZWxlbWVudDwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+QXJyYW5nZW1lbnQ8L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZWxlbWVudC1hcnJhbmdlbWVudHMucG5nIiBhbHQ9IkFycmFuZ2VtZW50IGJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICAgIDx0ZD5MZWdlbmQgYXJyYW5nZW1lbnQgb3B0aW9ucyBhbGxvd3MgeW91IHRvIGFkanVzdCB0aGUgZml0dGluZyBzdHJhdGVneSwgd29yZCB3cmFwLCBhbmQgc3BhY2luZyBvZiBpdGVtcyB3aXRoaW4gdGhlIGVsZW1lbnQ8L3RkPg0KICA8L3RyPg0KPC90YWJsZT48YnI+DQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1hZGQtZWxlbWVudHMucG5nIiBhbHQ9IkFkZCBlbGVtZW50IG9wdGlvbnMgZm9yIG5vcnRoIGFycm93IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpUaGVzZSB3aWxsIHByb3ZpZGUgYWRkaXRpb25hbCBjdXN0b21pemF0aW9uIG9wdGlvbnMgZm9yIGVhY2ggZWxlbWVudC4gV2hlbiBhZGRpbmcgdGhlICoqTGVnZW5kKiosIG5vdGljZSB0aGF0IHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBsYXllciBpcyBhZGRlZCB0byB0aGUgZWxlbWVudC4gV2hpbGUgeW91IHdpbGwgZXhhbWluZSBob3cgdG8gY3VzdG9taXplIGFsbCBlbGVtZW50cyBpbiBmdXR1cmUgZXhlcmNpc2VzLCBmb3IgdGhpcyBsYWIgeW91IHdpbGwgZWRpdCB0aGUgbmFtZXMgb2YgdGhlIF9sYXllciBuYW1lXyBhbmQgX2hlYWRpbmdfIGZvciB0aGUgbGF5ZXIuIFRoaXMgd2lsbCB1cGRhdGUgdGhlIGluZm9ybWF0aW9uIGF1dG9tYXRpY2FsbHkgaW4gdGhlIGxlZ2VuZC4gVG8gYmVnaW4sIGNsaWNrIG9uY2Ugb24gdGhlIF9ldl9kYXRhXyBsYXllciBuYW1lIGluIHRoZSB0YWJsZSBvZiBjb250ZW50cy4gVGhpcyB3aWxsIHNlbGVjdCB0aGUgaXRlbS4gQnkgc2luZ2xlIGNsaWNraW5nIGFuIGFkZGl0aW9uYWwgdGltZSAobm90IGRvdWJsZS1jbGlja2luZykgaXQgd2lsbCBhbGxvdyB5b3UgdG8gZGlyZWN0bHkgZWRpdCB0aGUgZGF0YS4gDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1lZGl0LWxlZ2VuZC10ZXh0LnBuZyIgYWx0PSJFZGl0IGxheWVyIG5hbWUgYW5kIGhlYWRpbmciIHdpZHRoPSI0NTUiIGhlaWdodD0iMzMwIj48L3A+PGJyPg0KDQpSZW5hbWUgdGhlIGxheWVyICoqQ2hhcmdpbmcgU3RhdGlvbnMqKiBhbmQgcmVuYW1lIHRoZSBfZXZfc3RhdGlvbl8gaGVhZGluZyB0byAqKk51bWJlciBwZXIgU3RhdGUqKi4gRGVwZW5kaW5nIG9uIHBsYWNlbWVudCBhbmQgc3ltYm9sb2d5IGNvbG9yLCB5b3VyIGxlZ2VuZCBzaG91bGQgbm93IGxvb2sgbGlrZSB0aGlzOg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9hcmNnaXMtZWRpdGVkLWxlZ2VuZC5wbmciIGFsdD0iTmV3IGxlZ2VuZCBsYXllciBuYW1lIGFuZCBoZWFkaW5nIiB3aWR0aD0iMTkwIiBoZWlnaHQ9IjE4NSI+PC9wPjxicj4NCg0KRGVwZW5kaW5nIG9uIHdoZXJlIHlvdSBwbGFjZWQgeW91ciBlbGVtZW50cyBhbmQgY3VzdG9taXphdGlvbnMgeW91IGVtcGxveWVkLCB5b3Ugc2hvdWxkIG5vdyBoYXZlIGEgY29tcGxldGVkIG1hcCB0aGF0IGluY2x1ZGVzIGFsbCBvZiB0aGUgbmVjZXNzYXJ5IGVsZW1lbnRzIGRpc2N1c3NlZCBhYm92ZS4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvYXJjZ2lzLWV4Mi1tYXAucG5nIiBhbHQ9IkV4ZXJjaXNlIDIgZXhhbXBsZSBtYXAiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+DQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDM8L2I+PC9iaWc+DQo8YmxvY2txdW90ZT4NCldoYXQgaXMgdGhlIGxhcmdlc3QgYW5kIHNtYWxsZXN0IG51bWJlciBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zPw0KPC9ibG9ja3F1b3RlPg0KDQo8L2RldGFpbHM+DQo8aHI+PC9ocj4NCg0KPGRldGFpbHM+PHN1bW1hcnk+PGJpZz5WaWV3IGRpcmVjdGlvbnMgaW4gPGI+IFtRR0lTXXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9IDwvYj48L3NwYW4+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpOb3cgaXQncyB0aW1lIHRvIHR1cm4geW91ciBkYXRhIGludG8gYSBtYXAuIEZyb20gdGhlIG1lbnUgYmFyIGluIGVpdGhlciBtYWNPUyBvciBQQyBjbGljayBfUHJvZ3JhbSA+IE5ldyBQcmludCBMYXlvdXRfLiBUaGlzIHdpbGwgb3BlbiBhIG5ldyB3aW5kb3cgd2hlcmUgeW91IHdpbGwgYWRkIHRoZSBkYXRhLCB0aXRsZSwgbGVnZW5kLCBub3J0aCBhcnJvdywgc2NhbGUgYmFyLCBhbmQgeW91ciBuYW1lIGFuZCBkYXRlLiANCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1uZXctcHJpbnQtbGF5ZXIucG5nIiBhbHQ9Ik5ldyBQcmludCBMYXlvdXQiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L2Rpdj48L3A+DQoNCkl0IHdpbGwgZmlyc3QgYXNrIHlvdSB0byBjcmVhdGUgYSBwcmludCBsYXlvdXQgdGl0bGUuIEFmdGVyIHlvdSBpbnB1dCBhIHRpdGxlIGNsb2NrIE9LLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLW5hbWUtcHJpbnQtbGF5b3V0LnBuZyIgYWx0PSJOYW1lIFByaW50IExheW91dCIgc3R5bGU9IndpZHRoOjgwJSI+PC9wPg0KDQpJbiB0aGUgbmV3IHdpbmRvdyB5b3Ugd2lsbCBzZWUgYSBibGFuayBsYXlvdXQgcGFnZS4gSWYgeW91IGNvbnRyb2wtY2xpY2sgKG1hY09TKSBvciByaWdodC1jbGljayAoUEMpIG9uIHRoZSBwYWdlIHlvdSB3aWxsIHNlZSBvcHRpb25zIGZvciAqKlBhZ2UgUHJvcGVydGllcy4uLioqIHRoYXQgYWxsb3dzIHlvdSB0byBhZGp1c3QgdGhlIHBhZ2Ugc2l6ZSwgb3JpZW50YXRpb24gKGxhbmRzY2FwZSBvciBwb3J0cmFpdCksIG9yIGN1c3RvbWl6ZSB0aGUgd2lkdGggYW5kIGhlaWdodCBhbmQgcHJvdmlkZSBhIGJhY2tncm91bmQgY29sb3IgdG8gdGhlIGxheW91dC5UaGVyZSB3aWxsIGFsc28gYmUgYW4gb3B0aW9uIHRvICoqTWFuYWdlIEd1aWRlcyBmb3IgUGFnZS4uLioqIHdoaWNoIHdpbGwgYWxsb3cgeW91IHRvIGFkZCBvciByZW1vdmUgX0hvcml6b250YWxfIG9yIF9WZXJ0aWNhbCBHdWlkZXNfIHRoYXQgd2lsbCBoZWxwIGFsaWduIGl0ZW1zIG9uIHRoZSBsYXlvdXQuDQoNClRvIGFkZCB5b3VyIGRhdGEgdG8gdGhlIGxheW91dCB5b3Ugd2lsbCB1c2UgdGhlICoqQWRkIG1hcCoqIHRvb2wgPGltZyBzcmM9ICJJbWFnZXMvcWdpcy1hZGQtbWFwLnBuZyIgYWx0PSJBZGQgTWFwIEJ1dHRvbiIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4gdGhhdCBpcyBsb2NhdGVkIGluIHRoZSBjb2x1bW4gb2YgdG9vbHMgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgc2NyZWVuLiBXaGVuIHlvdSBzZWxlY3QgdGhpcyB0b29sIGFuZCBob3ZlciBvdmVyIHRoZSBwYWdlIGxheW91dCB5b3VyIGN1cnNvciB3aWxsIGJlY29tZSBhIHBsdXMgc3ltYm9sLiBZb3Ugd2lsbCB1c2UgdGhpcyB0byBkcmF3IGEgYm91bmRpbmcgYm94IG9uIHRoZSBwYWdlIGxheW91dCB0aGF0IHdpbGwgc2VydmUgYXMgdGhlIGxvY2F0aW9uIGZvciB0aGUgbWFwIGRhdGEuIA0KDQo8cCBhbGlnbj0iY2VudGVyIj48ZGl2IGNsYXNzPSJ6b29tIj48aW1nIHNyYz0iSW1hZ2VzL3FnaXMtYWRkLW1hcC1ib3gucG5nIiBhbHQ9IkFkZCBNYXAgQm94IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpPbmNlIHlvdSBoYXZlIGRyYXduIHRoZSBtYXAgYm94LCB0aGUgaW5mb3JtYXRpb24gZGlzcGxheWVkIG9uIHRoZSBtYXAgY2FudmFzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHByaW50IGxheW91dC4gWW91ciBzY3JlZW4gc2hvdWxkIG5vdyBsb29rIHNpbWlsYXIgdG8gdGhpczoNCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9IkltYWdlcy9xZ2lzLW1hcC1hZGRlZC5wbmciIGFsdD0iTWFwIGNhbnZhcyBkaXNwbGF5ZWQgb24gcHJpbnQgbGF5b3V0IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpJbiBvcmRlciB0byBjb21wbGV0ZSBhIGJhc2ljIG1hcCB5b3Ugd2lsbCBub3cgbmVlZCB0byBhZGQgYSBub3J0aCBhcnJvdyA8aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWFkZC1ub3J0aC1hcnJvdy5wbmciIGFsdD0iQWRkIE5vcnRoIEFycm93IiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPiZuYnNwOywgc2NhbGUgYmFyIDxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtYWRkLXNjYWxlLWJhci5wbmciIGFsdD0iQWRkIFNjYWxlIEJhciIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4mbmJzcDssIGxlZ2VuZCA8aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWFkZC1sZWdlbmQucG5nIiBhbHQ9IkFkZCBMZWdlbmQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+Jm5ic3A7LCBhbmQgdGV4dCA8aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWFkZC10ZXh0LnBuZyIgYWx0PSJBZGQgVGV4dCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj4mbmJzcDsgdG8gaW5jbHVkZSBhIHRpdGxlIGFuZCB0aGUgbmFtZSBhbmQgZGF0ZSBvZiB0aGUgbWFwIGNyZWF0b3IuIEVhY2ggb2YgdGhlc2UgaXRlbXMgd29ya3MgZXNzZW50aWFsbHkgdGhlIHNhbWUgYXMgYWRkaW5nIHRoZSBtYXAgZGF0YS4gVGhleSBjYW4gYWxzbyBiZSBhZGRlZCB0aHJvdWdoIF9BZGQgSXRlbV8gaW4gdGhlIG1lbnUgYmFyLiBUaGVyZSBhcmUgc2V2ZXJhbCBvdGhlciBidXR0b25zIHlvdSBzaG91bGQgZmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCBvbiB0aGUgbGF5b3V0IHBhZ2Ugc3VjaCBhczogDQoNCjx0YWJsZSBzdHlsZT0id2lkdGg6MTAwJSI+DQogIDxjb2xncm91cD4NCiAgICAgICA8Y29sIHN0eWxlPSJ3aWR0aDogMjAlOyI+DQogICAgICAgPGNvbCBzdHlsZT0id2lkdGg6IDEwJTsiPg0KICAgICAgIDxjb2wgc3R5bGU9IndpZHRoOiA3MCU7Ij4NCiAgPC9jb2xncm91cD4NCiAgPHRyPg0KICAgIDx0ZD5QYW48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXBhbi1sYXlvdXQucG5nIiBhbHQ9IlBhbiBMYXlvdXQiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgICA8dGQ+VGhlIDxpPlBhbiBUb29sPC9pPiBpcyB1c2VkIHRvIHNoaWZ0IHRoZSBtYXAgY2FudmFzLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHRoZSBjYW52YXMgaXMgbGFyZ2VyIHRoYW4geW91ciBkaXNwbGF5IGR1ZSB0byB0aGUgbGV2ZWwgb2Ygem9vbTwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+Wm9vbTwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtbGF5b3V0LXpvb20ucG5nIiBhbHQ9IkxheW91dCBab29tIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogICAgPHRkPlRoZSA8aT5ab29tIFRvb2w8L2k+IGlzIHVzZWQgdG8gaW5jcmVhc2UgdGhlIG1hZ25pZmljYXRpb24gb2YgdGhlIG1hcCBjYW52YXMsIGJ1dCBpcyBub3QgdXNlZCB0byB6b29tIGluIG9uIHRoZSBkYXRhPC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5Nb3ZlIEl0ZW0gQ29udGVudDwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtbW92ZS1pdGVtLWNvbnRlbnQucG5nIiBhbHQ9Ik1vdmUgSXRlbSBDb250ZW50IiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogICAgPHRkPlRoZSA8aT5Nb3ZlIEl0ZW0gQ29udGVudCBUb29sPC9pPiBpcyB1c2VkIHRvIG1vdmUgdGhlIG1hcCBpbmZvcm1hdGlvbiB3aXRoaW4gdGhlIGJvdW5kaW5nIGJveCBhbmQgYWxsb3dzIHlvdSB6b29tIGluIGFuZCBvdXQgb24gdGhlIG1hcCBkYXRhPC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5TZWxlY3QvTW92ZSBJdGVtPC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1zZWxlY3QtbW92ZS5wbmciIGFsdD0iU2VsZWN0IGFuZCBNb3ZlIEl0ZW0iIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgICA8dGQ+VGhlIDxpPlNlbGVjdC9Nb3ZlIEl0ZW0gVG9vbDwvaT4gaXMgdXNlZCB0byBtb3ZlIGl0ZW1zIHN1Y2ggYXMgdGhlIG5vcnRoIGFycm93IG9uIHRoZSBtYXAgY2FudmFzPC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5Mb2NrL1VubG9jayBJdGVtczwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtbG9jay1idXR0b25zLnBuZyIgYWx0PSJMb2NrIGFuZCBVbmxvY2sgQWxsIEl0ZW1zIiB3aWR0aD0iNDQiIGhlaWdodD0iMjAiPjwvdGQ+DQogICAgPHRkPkxvY2tpbmcgaXRlbXMga2VlcHMgYW55IGNoYW5nZXMgZnJvbSBiZWluZyBtYWRlIHRvIHRoZSBpdGVtcyBvbiB0aGUgbGF5b3V0PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD5Hcm91cC9Vbmdyb3VwIEl0ZW1zPC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1ncm91cC1idXR0b25zLnBuZyIgYWx0PSJHcm91cCBhbmQgVW5ncm91cCBJdGVtcyIgd2lkdGg9IjQ0IiBoZWlnaHQ9IjIwIj48L3RkPg0KICAgIDx0ZD5UaGVzZSA8aT50b29sczwvaT4gYWxsb3cgc2VsZWN0ZWQgaXRlbXMgdG8gYmUgZ3JvdXBlZCBpbiBvcmRlciB0byByZW1haW4gdG9nZXRoZXIgd2hlbiBtb3ZlZDwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+UmFpc2UvQWxpZ24gSXRlbXM8L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWFycmFuZ2UtYnV0dG9ucy5wbmciIGFsdD0iUmVhcnJhbmdlIGFuZCBBbGlnbiBJdGVtcyIgd2lkdGg9IjQ0IiBoZWlnaHQ9IjIwIj48L3RkPg0KICAgIDx0ZD5UaGVzZSA8aT50b29sczwvaT4gYWxsb3cgZm9yIGl0ZW1zIHRvIGJlIHBsYWNlZCBhYm92ZSBvciBiZWxvdyBhbm90aGVyIGluIHRoZWlyIGhpZXJhcmNoeSBvciBhbGxvd3Mgc2VsZWN0ZWQgaXRlbXMgdG8gYmUgYWxpZ25lZDwvdGQ+DQogIDwvdHI+DQo8L3RhYmxlPjxicj4NCg0KT25jZSB5b3UgY2hvb3NlIHRoZSBvYmplY3QgeW91IHdhbnQgdG8gYWRkLCB5b3VyIGN1cnNvciBiZWNvbWVzIGEgcGx1cyBzeW1ib2wgYW5kIHlvdSBhcmUgdGhlbiBhYmxlIHRvIGRyYXcgdGhlIG9iamVjdCBpbiB0aGUgZGVzaXJlZCBsb2NhdGlvbi4gT25jZSB5b3UgaGF2ZSBwbGFjZWQgZWFjaCBvZiB0aGUgaXRlbXMsIHNlbGVjdCBhbnkgb25lLCBhbmQgaW4gdGhlIGNvbnRyb2wtY2xpY2sgKG1hY09TKSBvciByaWdodC1jbGljayAoUEMpIG1lbnUgY2hvb3NlICoqSXRlbSBQcm9wZXJ0aWVzKiouIFRoaXMgd2lsbCBvcGVuIGEgbmV3IG1lbnUgdG8gdGhlIHJpZ2h0IG9mIHRoZSBzY3JlZW4gdGhhdCBhbGxvd3MgeW91IHRvIGVkaXQgdmFyaW91cyBwcm9wZXJ0aWVzIGxpa2UgdGhlIHN5bWJvbCBmb3IgdGhlIG5vcnRoIGFycm93LCBzY2FsZSBiYXIgdW5pdHMsIGxlZ2VuZCBpdGVtIGFycmFuZ2VtZW50LCBhbmQgdGhlIHRleHQgdmFyaWFibGVzIGZvciB0aGUgdGl0bGUsIG5hbWUgYW5kIGRhdGUuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSJJbWFnZXMvcWdpcy1pdGVtLXByb3BlcnRpZXMucG5nIiBhbHQ9Ikl0ZW0gUHJvcGVydGllcyBNZW51IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpUYWtlIHlvdXIgdGltZSB0byBleGFtaW5lIHRoZSB2YXJpb3VzIG9wdGlvbnMgd2l0aGluIGVhY2ggb2YgdGhlIHByb3BlcnRpZXMgbWVudXMuIEFzIHlvdSBjb250aW51ZSB0byBtYWtlIG1hcHMgeW91IHdpbGwgYmVjb21lIG1vcmUgZmFtaWxpYXIgd2l0aCB0aGVzZSBtZW51cyBhbmQgYmVnaW4gdG8gZGV2ZWxvcCB5b3VyIG93biBzdHlsZSBmb3IgZWFjaCBpdGVtLiA8c21hbGw+PGk+SGludDogZG8gbm90IG1ha2UgdGhlIG5vcnRoIGFycm93IHRvbyBsYXJnZS48L2k+PC9zbWFsbD4gQXQgdGhpcyBwb2ludCB5b3Ugc2hvdWxkIHNhdmUgdGhlIHByb2plY3QuIA0KDQpCZWNhdXNlIHRoZSBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb24gZGF0YSB3YXMgb3JnYW5pemVkIGxvZ2FyaXRobWljYWxseSB5b3UgY2FuIHNlZSB0aGF0IHRoZSB2YWx1ZXMgYXJlIGRpc3BsYXllZCBpbiBzY2llbnRpZmljIG5vdGF0aW9uLiBBZGRpdGlvbmFsbHksIHRoZSBkaXNwbGF5IGhlYWRpbmcgaXMgdGhlIHNhbWUgYXMgdGhlIG5hbWUgb2YgdGhlIGRhdGFzZXQuIFNvIHRvIGNvcnJlY3QgdGhhdCB5b3Ugd2lsbCByZXR1cm4gdG8gdGhlIG1hcCBjYW52YXMuIElmIGF0IGFueSBwb2ludCB5b3UgYWNjaWRlbnRhbGx5IGNsb3NlIHRoZSBfUHJpbnQgbGF5b3V0XyB5b3UgY2FuIGFsd2F5cyBvcGVuIGl0IGFnYWluIGJ5IGNsaWNraW5nICoqU2hvdyBMYXlvdXQgTWFuYWdlcioqIDxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtbGF5b3V0LW1hbmFnZXIucG5nIiBhbHQ9IkFkZCBTY2FsZSBCYXIiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+Jm5ic3A7IG9uIHRoZSBtYWluIHRvb2xiYXIuIEluIHRoZSB3aW5kb3cgc2VsZWN0IHRoZSBsYXlvdXQgeW91IGNyZWF0ZWQgYW5kIGNsaWNrIF9TaG93Xy4gDQoNCkJhY2sgaW4gdGhlIGxheWVycyBhcmVhLCBjb250cm9sLWNsaWNrIChtYWNPUykgb3IgcmlnaHQtY2xpY2sgKFBDKSBvbiB0aGUgKipldl9kYXRhKiogbGF5ZXIgYW5kIGdvIHRvIF9Qcm9wZXJ0aWVzXyBhbmQgdGhlIF9TeW1ib2xvZ3lfIHRhYiBvbiB0aGUgbGVmdC4gZnJvbSB0aGVyZSB5b3Ugd2lsbCBzZWUgdGhlIG9wdGlvbnMgeW91IHNlbGVjdGVkIGVhcmxpZXIgaW4gdGhlIGV4ZXJjaXNlLiBJbiB0aGUgY2xhc3NlcyBzZWN0aW9uLCB5b3Ugd2lsbCBzZWUgdGhyZWUgKDMpIGNvbHVtbnMgb2YgaW5mb3JtYXRpb246IFN5bWJvbCwgVmFsdWVzLCBhbmQgTGVnZW5kLiBUaGUgaW5mb3JtYXRpb24gaW4gX0xlZ2VuZF8gY2FuIGJlIGVkaXRlZCBieSBzaW1wbHkgZG91YmxlLWNsaWNraW5nIG9uIHRoZSB0ZXh0LiBFZGl0IGVhY2ggbGVnZW5kIGVudHJ5IHRvIG1hdGNoIHRoZSBpbmZvcm1hdGlvbiBpbiB0aGUgdmFsdWVzIGNvbHVtbi4gV2hlbiB5b3UgaGF2ZSBjb21wbGV0ZWQgY2xpY2sgT0suDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPjxpbWcgc3JjPSJJbWFnZXMvcWdpcy1zeW1ib2xvZ3kucG5nIiBhbHQ9IkFsdGVyaW5nIGxlZ2VuZCBpbmZvcm1hdGlvbiBpbiBzeW1ib2xvZ3kgd2luZG93IiBzdHlsZT0id2lkdGg6MTAwJSI+PC9kaXY+PC9wPg0KDQpGaW5hbGx5LCBjb250cm9sLWNsaWNrIG9yIHJpZ2h0LWNsaWNrIG9uIHRoZSBkYXRhc2V0IGluIGxheWVycyBhbmQgY2xpY2sgX1JlbmFtZSBMYXllcl8uIEdpdmUgaXQgYSBuYW1lIHRoYXQgaXMgcmVwcmVzZW50YXRpdmUgb2YgdGhlIGRhdGFzZXQgc3VjaCBhcyAiRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9ucyIuIE5vdyByZXR1cm4gdG8geW91ciBsYXlvdXQuIElmIHRoZSBpbmZvcm1hdGlvbiBoYXMgbm90IGJlZW4gdXBkYXRlZCwgY2xpY2sgdGhlIF9SZWZyZXNoIFZpZXdfIGJ1dHRvbiA8aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXJlZnJlc2gtdmlldy5wbmciIGFsdD0iUmVmcmVzaCBWaWV3IiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPiZuYnNwOyBvbiB0aGUgdG9vbGJhci4gWW91ciBsYXlvdXQgc2hvdWxkIHVwZGF0ZSB3aXRoIGFsbCBvZiB0aGUgY2hhbmdlcyB5b3UgbWFkZSBpbiB0aGUgX1N5bWJvbG9neSBUYWJfLiBZb3UgbWF5IGFsc28gbmVlZCB0byBhZGp1c3QgdGhlIHNpemUgb2YgdGhlIGxlZ2VuZCBub3cgdGhhdCB5b3UgaGF2ZSBlZGl0ZWQgdGhlIGRhdGEuIFRoaXMgaXMganVzdCBvbmUgb2YgYSBudW1iZXIgb2YgZGlmZmVyZW50IHdheXMgdG8gZWRpdCBpbmZvcm1hdGlvbiBmb3IgZGF0YXNldHMuIEluIGZ1dHVyZSBleGVyY2lzZXMgeW91IHdpbGwgZXhhbWluZSBvdGhlciBlZGl0aW5nIG1ldGhvZHMuIFlvdSBzaG91bGQgbm93IGhhdmUgYSBjb21wbGV0ZWQgbWFwIHRoYXQgaW5jbHVkZXMgYWxsIG9mIHRoZSBuZWNlc3NhcnkgZWxlbWVudHMgZGlzY3Vzc2VkIGFib3ZlLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0iSW1hZ2VzL3FnaXMtZXgxLWZpbmFsLW1hcC5wbmciIGFsdD0iRXhlcmNpc2UgMSBGaW5hbCBNYXAiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+DQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDM8L2I+PC9iaWc+DQo8YmxvY2txdW90ZT4NCldoYXQgaXMgdGhlIGxhcmdlc3QgYW5kIHNtYWxsZXN0IG51bWJlciBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zPw0KPC9ibG9ja3F1b3RlPg0KDQo8L2RldGFpbHM+DQo8aHI+PC9ocj4NCg0KPGRldGFpbHM+PHN1bW1hcnk+PGJpZz5WaWV3IGRpcmVjdGlvbnMgaW4gPGI+IFtSXXtzdHlsZT0iY29sb3I6IzY0OTVFRCJ9IDwvYj48L3NwYW4+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpXaXRoIHRoaXMgbmV3IGRhdGFzZXQgeW91IGFyZSBub3cgcmVhZHkgdG8gY3JlYXRlIGEgbWFwIHRvIGV4YW1pbmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIGFjcm9zcyB0aGUgY291bnRyeS4gSW4gc3RlcCBvbmUgeW91IHVzZWQgYSB2ZXJ5IHNpbXBsZSBzY3JpcHQgdG8gZGlzcGxheSB0aGUgKip1cyoqIGRhdGEuICANCg0KYGBgDQpnZ3Bsb3QodXMpICsgDQogIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvciA9ICJ3aGl0ZSIpDQpgYGANCg0KQSBzaW1pbGFyIHNjcmlwdCB3b3VsZCBhbGxvdyB5b3UgdG8gcXVpY2tseSB2aXN1YWxpemUgdGhlIGRhdGEgYGBgZ2dwbG90KHN0YXRlcykgKyBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKWBgYCwgaG93ZXZlciwgeW91IG5lZWQgdG8gYWRkIGEgbnVtYmVyIG9mIGVsZW1lbnRzIGluIG9yZGVyIHRvIGNyZWF0ZSBhIG1hcCBzdWNoIGFzIGEgc2NhbGUgYmFyLCBub3J0aCBhcnJvdywgdGl0bGUsIGV0Yy4gQWRkaXRpb25hbGx5LCB5b3UgY2FuIGN1c3RvbWl6ZSBvdGhlciBjb21wb25lbnRzIHRvIHByb3ZpZGUgYSBiZXR0ZXIgb3ZlcmFsbCB2aXN1YWxpemF0aW9uLg0KDQpFYXJsaWVyIGluIHRoZSBub3RlYm9vayB3ZSBpbnN0YWxsZWQgdGhlIGBgYGdnc25gYGAgcGFja2FnZS4gVGhpcyBwYWNrYWdlIGFsbG93cyB5b3UgdG8gYWRkICJub3J0aCBzeW1ib2xzIGFuZCBzY2FsZSBiYXJzIGZvciBtYXBzIGNyZWF0ZWQgd2l0aCAnZ2dwbG90Micgb3IgJ2dnbWFwJy4iIFNvIHlvdSBjYW4gYnVpbGQgb24gdGhlIHNjcmlwdCBhYm92ZSB0byBjcmVhdGUgYSBtYXAgb2YgdGhlIGluZm9ybWF0aW9uIGluIHRoZSAqKnN0YXRlcyoqIGRhdGFzZXQuIFRvIGJlZ2luLCBydW4gdGhlIHNjcmlwdCBhYm92ZSB3aXRoIHRoZSBhZGRlZCAqKmZpbGwqKiBhcmd1bWVudCB0byBzZWUgdGhlIG91dGNvbWU6DQoNCmBgYHtyIGJhc2ljIGV2cyBtYXAsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgZ2VvbV9wb2x5Z29uKGFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCwgZmlsbCA9IGV2c19jb3VudCksIGNvbG9yID0gIndoaXRlIikNCmBgYA0KDQpPbmUgdGhpbmcgeW91IHdpbGwgbm90aWNlIGlzIHRoYXQgdGhlIGNhdGVnb3JpZXMgYXJlIHZlcnkgZGlmZmljdWx0IHRvIGRpc3Rpbmd1aXNoLiBCZWNhdXNlIHlvdSBoYXZlIHdpZGUgcmFuZ2luZyBkYXRhIGluIHRoZSBfZXZzX2NvdW50XyBjb2x1bW4gb25seSB0aGUgbGFyZ2VzdCB2YWx1ZSBpcyBzaG93aW5nLiBBIHNpbXBsZSBmaXggdG8gdGhpcyB3b3VsZCBiZSB0byB0YWtlIHRoZSBjb21tb24gbG9nYXJpdGhtIG9mIHRoZSBkYXRhIHRvIHN0YW5kYXJkaXplIHRoZSB2YWx1ZXMgYnkgcmVtb3ZpbmcgdGhlIHNrZXduZXNzIHRvd2FyZHMgbGFyZ2VyIG51bWJlcnMuIFRoZSBmdW5jdGlvbiBgYGBzY2FsZS12aXJpZGlzYGBgIHNjYWxlcyB0aGUgZGF0YSBhbmQgcHJvdmlkZXMgYSBjb2xvciBtYXAgZGVzaWduZWQgdG8gYmUgcGVyY2VpdmVkIGJ5IHZpZXdlcnMgd2l0aCBjb21tb24gZm9ybXMgb2YgY29sb3IgYmxpbmRuZXNzLiBTbyB5b3UgY2FuIGFkZCBgYGBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiRCIsIHRyYW5zID0gImxvZzEwIilgYGAgdG8gdGhlIHNjcmlwdCBhYm92ZSB3aGVyZToNCg0KLSBzY2FsZV9maWxsX3ZpcmlkaXNfYyBpcyBhIGZpbGwgcGF0dGVybiBmb3IgY29udGludW91cyBkYXRhDQotIG9wdGlvbiA9ICJEIiBpcyB0aGUgZGVmYXVsdCBjb2xvciBvcHRpb24NCiAgLSBUaGVyZSBhcmUgZml2ZSBjb2xvciBvcHRpb25zIGF2YWlsYWJsZSB3aXRoIHRoaXMgZnVuY3Rpb24NCiAgICAtIEEgPSBtYWdtYQ0KICAgIC0gQiA9IGluZmVybm8NCiAgICAtIEMgPSBwbGFzbWENCiAgICAtIEQgPSB2aXJpZGlzDQogICAgLSBFID0gY2l2aWRpcw0KLSB0cmFucyA9ICJsb2cxMCIgdHJhbnNmb3JtcyB0aGUgZGF0YSB1c2luZyBjb21tb24gbG9nYXJpdGhtLCBvdGhlciBvcHRpb25zIGFyZSBhdmFpbGFibGU7IHNlZSBkb2N1bWVudGF0aW9uDQoNClRoZSBuZXcgc2NyaXB0IHNob3VsZCBub3cgbG9vayBsaWtlIHRoaXM6DQoNCmBgYHtyIGxvZyBldnMgbWFwLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3Qoc3RhdGVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKQ0KYGBgDQoNCk5vdyB0aGF0IHlvdSBhcmUgYWJsZSB0byB2aXN1YWxpemUgdGhlIHNlcGFyYXRpb25zIGluIHRoZSBkYXRhIHlvdSBjYW4gYWRkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uIFlvdSBjYW4gc3RhcnQgd2l0aCBjdXN0b21pemluZyB0aGUgbGFiZWxzLCBtYXAgdGl0bGUsIGFuZCBsZWdlbmQgdGl0bGUuIFRoaXMgY2FuIGFsbCBiZSBjb21wbGV0ZWQgYnkgYWRkaW5nIGEgc2luZ2xlIGxpbmUgb2YgY29kZSBjb250YWluaW5nIGFsbCBvZiB0aGUgdGV4dCBpbmZvcm1hdGlvbiBmb3IgdGhvc2UgaXRlbXM6DQoNCmBgYHtyIGxvZyBtYXAgdyB0aXRsZXMsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgDQogICAgZ2VvbV9wb2x5Z29uKGFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCwgZmlsbCA9IGV2c19jb3VudCksIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiRCIsIHRyYW5zID0gImxvZzEwIikgKyANCiAgbGFicyh4PSJMb25naXR1ZGUiLHk9IkxhdGl0dWRlIiwgdGl0bGU9Ik51bWJlciBvZiBFbGVjdHJpYyBWZWhpY2xlIENoYXJnaW5nIFN0YXRpb25zIFBlciBTdGF0ZSIsIGZpbGwgPSAiTm8uIG9mIFN0YXRpb25zIikNCmBgYA0KDQpGZWVsIGZyZWUgdG8gZWRpdCB0aGUgbGFiZWwgbmFtZXMgYW5kIHRoZSBjb2xvciBvcHRpb24gaW4gdGhlIHNjcmlwdCB0byBwcm92aWRlIHlvdXIgb3duIGN1c3RvbWl6YXRpb25zLiBOZXh0IHlvdSBuZWVkIHRvIGFkZCBhIHNjYWxlIGJhciBhbmQgbm9ydGggYXJyb3cuIFRvIHZpZXcgdGhlIGF2YWlsYWJsZSBvcHRpb25zIGZvciB0aGUgbm9ydGggYXJyb3cgdHlwZSBgYGBub3J0aFN5bWJvbHMoKWBgYCBpbnRvIGEgbmV3IGNvZGUgYmxvY2suIFRoZSBudW1lcmljIHZhbHVlcyBiZWxvdyBlYWNoIHN5bWJvbCB3aWxsIGJlIHVzZWQgaW4gdGhlIHNjcmlwdCB0byBpZGVudGlmeSB0aGUgc3BlY2lmaWMgc3R5bGUgeW91IGNob29zZS4gQmVjYXVzZSB0aGUgbm9ydGggYXJyb3csIGBgYG5vcnRoYGBgLCBpcyBzcGVjaWZpY2FsbHkgcmVsYXRlZCB0byB0aGUgbWFwIGRhdGEgeW91IG5lZWQgdG8gcHJvdmlkZSB0aGUgZm9sbG93aW5nIGFyZ3VtZW50czoNCg0KLSBkYXRhc2V0DQotIHN5bWJvbCwgaWRlbnRpZmllZCBieSB0aGUgbnVtZXJpY2FsIHZhbHVlIGZyb20gYGBgbm9ydGhTeW1ib2xzKClgYGANCi0gbG9jYXRpb24sIGluZGljYXRpbmcgd2hlcmUgdG8gYmFzZSB0aGUgbG9jYXRpb24gb24gdGhlIG1hcA0KLSBhbmNob3IsIGNvb3JkaW5hdGVzIGZvciB0aGUgc3ltYm9sIHBvc2l0aW9uIG9uIHRoZSBtYXAgKGJhc2VkIG9mZiB0aGUgbG9jYXRpb24pDQotIHNjYWxlLCB0aGUgc3ltYm9sIHNpemUgYXMgYSBwcm9wb3J0aW9uIG9mIHRoZSBtYXAgc2l6ZSANCg0KU28geW91ciBuZXcgc2NyaXB0IHdpbGwgbG9vayBsaWtlOg0KDQpgYGB7ciBtYXAgdGl0bGVzIG5vcnRoLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3Qoc3RhdGVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKSArIA0KICBsYWJzKHg9IkxvbmdpdHVkZSIseT0iTGF0aXR1ZGUiLCB0aXRsZT0iTnVtYmVyIG9mIEVsZWN0cmljIFZlaGljbGUgQ2hhcmdpbmcgU3RhdGlvbnMgUGVyIFN0YXRlIiwgZmlsbCA9ICJOby4gb2YgU3RhdGlvbnMiKSArDQogIG5vcnRoKHN0YXRlcywgbG9jYXRpb24gPSAiYm90dG9tbGVmdCIsIHNjYWxlID0gMC4wNSwgc3ltYm9sID0gMTIsIGFuY2hvciA9IGMoeD0gLTcwLCB5PSAyNSkpDQpgYGANCkluIHRoaXMgZXhhbXBsZSwgYGBgbG9jYXRpb24gPSAiYm90dG9tbGVmdCJgYGAgbWVhbnMgdGhlIGxvY2F0aW9uIG9mIHRoZSBfbm9ydGggYXJyb3dfIHdpbGwgYmUgYmFzZWQgZnJvbSB0aGUgYm90dG9tIGxlZnQgb2YgdGhlIHN5bWJvbCBhbmQgYGBhbmNob3IgPSBjKHggPSAtNzAsIHkgPSAyNSlgYGAgaXMgdGhlIGdlb2dyYXBoaWMgbG9jYXRpb24gb24gdGhlIG1hcCB0byBkcmF3IHRoZSBzeW1ib2wuIEZvciBleGFtcGxlLCBpZiB0aGUgX2FuY2hvcnNfIHdlcmUgc2V0IGF0IC0xMDAgYW5kIDQwIHRoZSBzeW1ib2wgd291bGQgYmUgZHJhdyBvbiB0aGUgTmVicmFza2EvS2Fuc2FzIGJvcmRlci4gRmVlbCBmcmVlIHRvIGFkanVzdCB0aGUgYW5jaG9yIHBvaW50cyB0byBkcmF3IHRoZSBub3J0aCBhcnJvdyBpbiB5b3VyIHByZWZlcnJlZCBsb2NhdGlvbi4NCg0KTm93IHlvdSBuZWVkIHRvIGFkZCBhIHNjYWxlIGJhci4gTWFueSBvZiB0aGUgYXJndW1lbnRzIHVzZWQgZm9yIHRoZSBub3J0aCBhcnJvdyBhcmUgZHVwbGljYXRlZCBmb3IgYGBgc2NhbGViYXJgYGANCg0KLSBkYXRhc2V0DQotIGxvY2F0aW9uLCBpbmRpY2F0aW5nIHdoZXJlIHRvIGJhc2UgdGhlIGxvY2F0aW9uIG9uIHRoZSBtYXANCi0gYW5jaG9yLCBjb29yZGluYXRlcyBmb3IgdGhlIHN5bWJvbCBwb3NpdGlvbiBvbiB0aGUgbWFwIChiYXNlZCBvZmYgdGhlIGxvY2F0aW9uKQ0KLSBkaXN0YW5jZSBmb3IgZWFjaCB1bml0IG9mIHRoZSBzY2FsZSBiYXINCi0gdW5pdCBvZiBtZWFzdXJlbWVudCBzdWNoIGFzIG1pLCBrbSwgZXRjLg0KLSB0cmFuc2Zvcm0gKFRSVUUvRkFMU0UpLCBhc3N1bWVzIHRoZSBjb29yZGluYXRlcyBhcmUgaW4gZGVjaW1hbCBkZWdyZWVzDQotIG1vZGVsLCBjaG9pY2Ugb2YgZWxsaXBzb2lkOyB3aGljaCB3aWxsIGJlIGRpc2N1c3NlZCBsYXRlciBpbiB0aGUgc2VtZXN0ZXINCi0gc3Quc2l6ZSwgc2NhbGUgYmFyIHNpemUNCi0gc3QuZGlzdCwgZGlzdGFuY2UgYmV0d2VlbiB0aGUgc2NhbGUgYmFyIGFuZCB0aGUgc2NhbGUgYmFy4oCZcyB0ZXh0LCBhcyBhIHByb3BvcnRpb24gb2YgdGhlIHkgYXhpcw0KDQpgYGB7ciBtYXAgdGl0bGVzIG5vcnRoIHNjYWxlLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3Qoc3RhdGVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKSArIA0KICBsYWJzKHg9IkxvbmdpdHVkZSIseT0iTGF0aXR1ZGUiLCB0aXRsZT0iTnVtYmVyIG9mIEVsZWN0cmljIFZlaGljbGUgQ2hhcmdpbmcgU3RhdGlvbnMgUGVyIFN0YXRlIiwgZmlsbCA9ICJOby4gb2YgU3RhdGlvbnMiKSArDQogIG5vcnRoKHN0YXRlcywgbG9jYXRpb24gPSAiYm90dG9tbGVmdCIsIHNjYWxlID0gMC4wNSwgc3ltYm9sID0gMTIsIGFuY2hvciA9IGMoeD0gLTcwLCB5PSAyNSkpICsgDQogIHNjYWxlYmFyKHN0YXRlcywgZGlzdCA9IDI1MCwgZGlzdF91bml0ID0gIm1pIiwgdHJhbnNmb3JtID0gVFJVRSwgbW9kZWwgPSAiV0dTODQiLCBsb2NhdGlvbiA9ICJib3R0b21sZWZ0Iiwgc3QuZGlzdCA9IDAuMDUsIHN0LnNpemUgPSAyLCBhbmNob3IgPSBjKHg9LTEyNSx5PTI3KSkNCmBgYA0KDQpBcyB3aXRoIGFsbCBvZiB0aGUgb3RoZXIgY3VzdG9taXphdGlvbnMgYWJvdmUsIGZlZWwgZnJlZSB0byBhZGp1c3QgdGhlIHVuaXRzLCBkaXN0YW5jZSwgdGV4dCBkaXN0YW5jZSwgYW5kIHNpemUgYmFzZWQgb24geW91ciBvd24gc3R5bGUuDQoNCkZpbmFsbHksIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHRleHQgdG8gdGhlIG1hcCB0byBpbmRpY2F0ZSB0aGUgbmFtZSBvZiB0aGUgcGVyc29uIHdobyBjcmVhdGVkIHRoZSBtYXAgYW5kIHRoZSBkYXRlLiBJbiB0aGUgZnV0dXJlIHlvdSB3aWxsIHBvc3NpYmx5IGluY2x1ZGUgcmVmZXJlbmNlcyBvciBvdGhlciB0ZXh0IGJhc2VkIGluZm9ybWF0aW9uLiBUaGVyZSBhcmUgYSBudW1iZXIgb2YgZGlmZmVyZW50IHdheXMgeW91IHdpbGwgZXhwbG9yZSBmb3IgYWRkaW5nIHRleHQgaW5mb3JtYXRpb24gdG8geW91ciBtYXBzLCBzdWNoIGFzIGBgYGNhcHRpb24gPSBgYGAgaW4gbGFicywgYnV0IGZvciB0aGlzIGV4YW1wbGUgeW91IHdpbGwgdXNlIGBgYGFubm90YXRlKClgYGAuIFNpbWlsYXIgdG8gdGhlIG5vcnRoIGFycm93IGFuZCBzY2FsZSBiYXIsIHRoZXJlIHdpbGwgYmUgYToNCg0KLSBfeF8gYW5kIF95XyBhcmd1bWVudCB0byBzZXQgdGhlIGxvY2F0aW9uDQotIHNpemUgdG8gaW5kaWNhdGUgdGhlIGZvbnQgc2l6ZQ0KLSBsYWJlbCBmb3IgdGhlIHRleHQgeW91IHdpc2ggdG8gaW5jbHVkZTsgdG8gY3JlYXRlIGEgY2hhcmFjdGVyIHJldHVybiB0byBtb3ZlIHRleHQgdG8gYSBuZXcgbGluZSB5b3Ugc2hvdWxkIHVzZSAiXFxuIiB3aGVyZSB5b3Ugd2FudCB0aGUgdGV4dCB0byBtb3ZlIHRvIGEgbmV3IGxpbmUNCg0KWW91ciBmaW5hbCBzY3JpcHQgc2hvdWxkIG5vdyBsb29rIHNpbWlsYXIgdG8gdGhpczoNCg0KYGBge3IgZmluYWwgbWFwLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3Qoc3RhdGVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKSArIA0KICBsYWJzKHg9IkxvbmdpdHVkZSIseT0iTGF0aXR1ZGUiLCB0aXRsZT0iTnVtYmVyIG9mIEVsZWN0cmljIFZlaGljbGUgQ2hhcmdpbmcgU3RhdGlvbnMgUGVyIFN0YXRlIiwgZmlsbCA9ICJOby4gb2YgU3RhdGlvbnMiKSArDQogIG5vcnRoKHN0YXRlcywgbG9jYXRpb24gPSAiYm90dG9tbGVmdCIsIHNjYWxlID0gMC4wNSwgc3ltYm9sID0gMTIsIGFuY2hvciA9IGMoeD0gLTcwLCB5PSAyNSkpICsgDQogIHNjYWxlYmFyKHN0YXRlcywgZGlzdCA9IDI1MCwgZGlzdF91bml0ID0gIm1pIiwgdHJhbnNmb3JtID0gVFJVRSwgbW9kZWwgPSAiV0dTODQiLCBsb2NhdGlvbiA9ICJib3R0b21sZWZ0Iiwgc3QuZGlzdCA9IDAuMDUsIHN0LnNpemUgPSAyLCBhbmNob3IgPSBjKHg9LTEyNSx5PTI3KSkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSAtOTAsIHkgPSAyNSwgbGFiZWwgPSAiQ2hyaXMgR2VudHJ5XG4gQXVndXN0IDIwMjEiLCBzaXplID0gMikNCmBgYA0KDQpUaGVyZSBpcyBhbiBleGhhdXN0aXZlIGFtb3VudCBvZiBtb2RpZmljYXRpb25zIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gdGhlIG1hcCBhYm92ZSwgYnV0IGZvciBub3cgeW91IGhhdmUgdGhlIG1pbmltdW0gaW5mb3JtYXRpb24gcmVxdWlyZWQgdG8gY3JlYXRlIGEgbWFwIG9mIHNpbWlsYXIga2luZHMgb2YgZGF0YS4gSW4gZnV0dXJlIGV4ZXJjaXNlcyB5b3Ugd2lsbCB1c2UgdmFyaW91cyBmdW5jdGlvbiB0byBjdXN0b21pemUgdGhlIGxvb2sgb2YgeW91ciBtYXBzLiANCg0KPGI+PGJpZz5RdWVzdGlvbiBOby4gMzwvYmlnPjwvYj4NCjxibG9ja3F1b3RlPg0KSG93IGRvZXMgdGhlIF9kaXN0ID0gXyAmbmJzcDthcmd1bWVudCBpbiB0aGUgYGBgc2NhbGViYXJgYGAgZnVuY3Rpb24gcmVsYXRlIHNwZWNpZmljYWxseSB0byB0aGUgZGlzdGFuY2Ugb2YgdGhlIHNjYWxlIGJhciBvbiB5b3VyIG1hcD8gSG93IHdvdWxkIGNoYW5naW5nIHRoZSB2YWx1ZSBhbHRlciB0aGUgYXBwZWFyYW5jZT8NCjwvYmxvY2txdW90ZT4NCg0KPC9kZXRhaWxzPg0KDQojIyBTdGVwIEZvdXI6IFlvdXIgVHVybg0KDQpBZnRlciBhIHJhc2ggb2Ygc2V2ZXJlIHdlYXRoZXIgb3ZlciB0aGUgcGFzdCBmZXcgeWVhcnMgdGhlIE1vbnRnb21lcnkgQ291bnR5IEVtZXJnZW5jeSBNYW5hZ2VtZW50IEFnZW5jeSBoYXMgYXNrZWQgeW91IHRvIHByb3ZpZGUgYSBtYXAgZGV0YWlsaW5nIHRoZSBudW1iZXIgb2YgcmVwb3J0ZWQgdG9ybmFkb2VzIGluIGVhY2ggVGVubmVzc2VlIGNvdW50eSBvdmVyIHRoZSBwYXN0IHNldmVyYWwgZGVjYWRlcy4gVGhpcyBpbmZvcm1hdGlvbiB3aWxsIGJlIHNoYXJlZCB3aXRoIG5laWdoYm9yaW5nIGNvdW50aWVzIGluIG1pZGRsZSBUZW5uZXNzZWUgYXMgYSBwYXJ0IG9mIHNldmVyZSB3ZWF0aGVyIGVkdWNhdGlvbiBjYW1wYWlnbiBkZXNpZ25lZCB0byBpbmZvcm0gY29tbXVuaXRpZXMgYWJvdXQgdGhlIHJpc2sgb2YgdG9ybmFkb2VzIGluIHRoZSByZWdpb24uIFRoZSBtYXAgc2hvdWxkIGluY2x1ZGUgYWxsIG9mIHRoZSBlbGVtZW50cyBpbmNsdWRlZCBvbiB5b3VyIHByZXZpb3VzIG1hcCBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIHN1Y2ggYXM6DQoNCi0gVGl0bGUNCi0gU2NhbGUNCi0gTm9ydGggQXJyb3cNCi0gTGVnZW5kDQotIE5hbWUvRGF0ZSBvZiBDYXJ0b2dyYXBoZXINCg0KU29mdHdhcmUgc3BlY2lmaWMgZGlyZWN0aW9ucyBjYW4gYmUgZm91bmQgZm9yIGVhY2ggc3RlcCBiZWxvdy4gUGxlYXNlIHN1Ym1pdCB0aGUgYW5zd2VyIHRvIHRoZSBxdWVzdGlvbnMgeW91IGFuc3dlcmVkIGFib3ZlIGFzIHdlbGwgYXMgeW91ciBmaW5hbCB0b3JuYWRvIG1hcCBieSB0aGUgZHVlIGRhdGUuDQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBkaXJlY3Rpb25zIGluIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCg0KVGhpcyBwb3J0aW9uIG9mIHRoZSBleGVyY2lzZSBpcyBtZWFudCB0byByZWluZm9yY2UgdGhlIHNraWxscyB5b3UgbGVhcm5lZCBpbiB0aGUgZmlyc3QgcGFydCBvZiB0aGUgbGFiLiBUaGUgc3RlcHMgdG8gY29tcGxldGUgeW91ciBmaW5hbCBtYXAgd2lsbCBiZSB0bzoNCg0KMS4gRG93bmxvYWQgYW5kIHVuemlwIHRoZSB0b3JuYWRvZXMgZGF0YXNldA0KMi4gQ3JlYXRlIGEgbmV3IG1hcCBwcm9qZWN0DQozLiBBZGQgdGhlIGRhdGEgdG8geW91ciBsYXllcnMNCjQuIFVzZSB0aGUgc3ltYm9sb2d5IHRhYiB0byBjb2xvciB0aGUgY291bnRpZXMgYnkgbnVtYmVyIG9mIHRvcm5hZG9lcyAoKip0b3JuYWRvX2NvKiopDQo1LiBNYXAgdGhlIGRhdGEgaW5jbHVkaW5nIGFsbCB0aGUgbmVjZXNzYXJ5IGVsZW1lbnRzIGFkZGVkIGFib3ZlDQoNClRvIGJlZ2luIHRoaXMgcG9ydGlvbiBvZiB0aGUgZXhlcmNpc2UgeW91IHdpbGwgbmVlZCB0byBkb3dubG9hZCB0aGUgW3Rvcm5hZG8gZGF0YXNldF0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvcmF3L21haW4vRGF0YS9TaGFwZWZpbGVzL3Rvcm5hZG9fZGF0YS56aXApLiBSZW1lbWJlciB5b3UgY2FuIHVzZSB0aGUgcG9wLXVwIHRvb2wgb3IgdGhlIGF0dHJpYnV0ZSB0YWJsZSB0byBleGFtaW5lIHRoZSBpbmZvcm1hdGlvbi4gV2hlbiB5b3UgaGF2ZSBjb21wbGV0ZWQgeW91ciBtYXAsIGNsaWNrIHRoZSBfU2hhcmUgVGFiXyBhbmQgY2xpY2sgX0xheW91dF8gdG8gc2F2ZSB5b3VyIG1hcC4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGRpdiBjbGFzcz0iem9vbSI+PGltZyBzcmM9IkltYWdlcy9hcmNnaXMtaW1hZ2Utc2F2ZS5wbmciIGFsdD0iRXhwb3J0IG1hcCBhcyBpbWFnZSIgc3R5bGU9IndpZHRoOjEwMCUiPjwvZGl2PjwvcD4NCg0KWW91IHdpbGwgaGF2ZSBhIG5ldyAqKkV4cG9ydCoqIHNlY3Rpb24gb24gdGhlIHJpZ2h0LXNpZGUgb2YgdGhlIHNjcmVlbi4gSW4gdGhlIF9Qcm9wZXJ0aWVzXyBvcHRpb25zIGNoYW5nZSB0aGUgX0ZpbGUgVHlwZV8gdG8gX1wqLmpwZ18uIFRoaXMgd2lsbCBhbGxvdyB5b3UgdG8gYWRkIGl0IHRvIHlvdXIgd29yZCBkb2N1bWVudCBhbmQgYmUgc3VibWl0dGVkIGF0IHRoZSBlbmQgb2YgdGhpcyBleGVyY2lzZS4gSW4gX05hbWVfIGNsaWNrIHRoZSBicm93c2UgYnV0dG9uIDxpbWcgc3JjPSAiSW1hZ2VzL2FyY2dpcy1icm93c2UtYnV0dG9uLnBuZyIgYWx0PSJCcm93c2UgYnV0dG9uIHRvIHNhdmUgbGF5b3V0IiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPiB0byBzYXZlIHRoZSBsYXlvdXQuIEl0IHdpbGwgZGVmYXVsdCB0byB0aGUgcHJvamVjdCBmb2xkZXIgYW5kIHlvdSBjYW4gcHJvdmlkZSBhIG5hbWUgdG8gaWRlbnRpZnkgdGhlIGZpbGUuIFdoZW4gZG9uZSBjbGljayBfU2F2ZV8gaW4gdGhlIGJyb3dzZXIgd2luZG93LCBsZWF2ZSB0aGUgb3RoZXIgb3B0aW9ucyBhcyB0aGUgZGVmYXVsdCBzZXR0aW5nLCBhbmQgKipFeHBvcnQqKiBhdCB0aGUgYm90dG9tIG9mIHRoZSBzZWN0aW9uLg0KDQo8YmlnPjxiPlF1ZXN0aW9uIE5vLiA0PC9iPjwvYmlnPg0KPGJsb2NrcXVvdGU+DQpXaGljaCBjb3VudHkgaGFkIHRoZSBoaWdoZXN0IG51bWJlciBvZiByZXBvcnRlZCB0b3JuYWRvZXM/PGJyPg0KPHNtYWxsPkhpbnQ6IFJlbWVtYmVyIHlvdSBjYW4gc29ydCB0aGUgZGF0YSBpbiBhbnkgY29sdW1uIGJ5IGNsaWNraW5nIG9uIHRoZSBjb2x1bW4gaGVhZGVyLjwvc21hbGw+DQo8L2Jsb2NrcXVvdGU+DQoNCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz48c3VtbWFyeT48YmlnPlZpZXcgZGlyZWN0aW9ucyBpbiA8Yj4gW1FHSVNde3N0eWxlPSJjb2xvcjojMDA2NDAwIn0gPC9iPjwvc3Bhbj48L2JpZz48L3N1bW1hcnk+DQoNClRoaXMgcG9ydGlvbiBvZiB0aGUgZXhlcmNpc2UgaXMgbWVhbnQgdG8gcmVpbmZvcmNlIHRoZSBza2lsbHMgeW91IGxlYXJuZWQgaW4gdGhlIGZpcnN0IHBhcnQgb2YgdGhlIGxhYi4gVGhlIHN0ZXBzIHRvIGNvbXBsZXRlIHlvdXIgZmluYWwgbWFwIHdpbGwgYmUgdG86DQoNCjEuIERvd25sb2FkIGFuZCB1bnppcCB0aGUgdG9ybmFkb2VzIGRhdGFzZXQNCjIuIENyZWF0ZSBhIG5ldyBtYXAgcHJvamVjdA0KMy4gQWRkIHRoZSBkYXRhIHRvIHlvdXIgbGF5ZXJzDQo0LiBVc2UgdGhlIHN5bWJvbG9neSB0YWIgdG8gY29sb3IgdGhlIGNvdW50aWVzIGJ5IG51bWJlciBvZiB0b3JuYWRvZXMgKCoqdG9ybmFkb19jbyoqKQ0KNS4gTWFwIHRoZSBkYXRhIGluY2x1ZGluZyBhbGwgdGhlIG5lY2Vzc2FyeSBlbGVtZW50cyBhZGRlZCBhYm92ZQ0KDQpUbyBiZWdpbiB0aGlzIHBvcnRpb24gb2YgdGhlIGV4ZXJjaXNlIHlvdSB3aWxsIG5lZWQgdG8gZG93bmxvYWQgdGhlIFt0b3JuYWRvIGRhdGFzZXRdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc21nZW50cnkvR0lTMS1FeGVyY2lzZS0yL3Jhdy9tYWluL0RhdGEvU2hhcGVmaWxlcy90b3JuYWRvX2RhdGEuemlwKS4gUmVtZW1iZXIgeW91IGNhbiB1c2UgdGhlIGlkZW50aXR5IHRvb2wgb3IgdGhlIGF0dHJpYnV0ZSB0YWJsZSB0byBleGFtaW5lIHRoZSBpbmZvcm1hdGlvbi4gV2hlbiB5b3UgaGF2ZSBjb21wbGV0ZWQgeW91ciBtYXAsIGNsaWNrIF9Qcm9qZWN0ID4gRXhwb3J0IGFzIEltYWdlLi4uXyBvbiBQQyBvciBfUHJvamVjdCA+IEltcG9ydC9FeHBvcnQgPiBFeHBvcnQgTWFwIHRvIEltYWdlLi4uXyBvbiBtYWNPUyB0byBzYXZlIHlvdXIgbWFwIGFzIGEgX1wqLmpwZ18uIFRoaXMgd2lsbCBhbGxvdyB5b3UgdG8gYWRkIGl0IHRvIHlvdXIgd29yZCBkb2N1bWVudCBhbmQgYmUgc3VibWl0dGVkIGF0IHRoZSBlbmQgb2YgdGhpcyBleGVyY2lzZS4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9IkltYWdlcy9xZ2lzLWltYWdlLXNhdmUucG5nIiBhbHQ9IkV4cG9ydCBtYXAgYXMgaW1hZ2UiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+DQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDQ8L2I+PC9iaWc+DQo8YmxvY2txdW90ZT4NCldoaWNoIGNvdW50eSBoYWQgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHJlcG9ydGVkIHRvcm5hZG9lcz88YnI+DQo8c21hbGw+SGludDogUmVtZW1iZXIgeW91IGNhbiBzb3J0IHRoZSBkYXRhIGluIGFueSBjb2x1bW4gYnkgY2xpY2tpbmcgb24gdGhlIGNvbHVtbiBoZWFkZXIuPC9zbWFsbD4NCjwvYmxvY2txdW90ZT4NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBkaXJlY3Rpb25zIGluIDxiPiBbUl17c3R5bGU9ImNvbG9yOiM2NDk1RUQifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCg0KVGhpcyBwb3J0aW9uIG9mIHRoZSBleGVyY2lzZSBpcyBtZWFudCB0byByZWluZm9yY2UgdGhlIHNraWxscyB5b3UgbGVhcm5lZCBpbiB0aGUgZmlyc3QgcGFydCBvZiB0aGUgbGFiLiBUaGUgc3RlcHMgdG8gY29tcGxldGUgeW91ciBmaW5hbCBtYXAgd2lsbCBiZSB0bzoNCg0KMS4gQ3JlYXRlIGFuIG9iamVjdCBmcm9tIHRoZSB0b3JuYWRvZXMgZGF0YXNldA0KMi4gT2J0YWluIGEgZGF0YXNldCBvZiBUZW5uZXNzZWUgY291bnRpZXMNCjMuIERldGVybWluZSB3aGljaCBjb2x1bW5zIGNhbiBiZSB1c2VkIHRvIGBgYG1lcmdlYGBgIHRoZSBkYXRhc2V0cw0KNC4gTWFwIG91dCB0aGUgZGF0YSB1c2luZyBgYGBnZ3Bsb3RgYGANCg0KDQpUbyBiZWdpbiB0aGlzIHBvcnRpb24gb2YgdGhlIGV4ZXJjaXNlIHlvdSB3aWxsIG5lZWQgdGhpcyBVUkwgdG8gdGhlIGNvbW1hIGRlbGltaXRlZCBkYXRhc2V0Og0KDQpodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY2hyaXNtZ2VudHJ5L0dJUzEtRXhlcmNpc2UtMi9tYWluL0RhdGEvdG5fdG9ybmFkb2VzLmNzdg0KDQpUaGlzIGRhdGEgcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHJlcG9ydGVkIHRvcm5hZG9lcyBpbiBlYWNoIGNvdW50eSBmcm9tIDE5NTAtMjAyMC4gQXMgaW4gc3RlcCBvbmUgb2YgdGhlIGV4ZXJjaXNlLCB5b3UgY2FuIHVzZSB0aGUgKio8LSoqIG9wZXJhdG9yIHRvIGNyZWF0ZSBhIG5ldyBvYmplY3QgYW5kIHRoZSBgYGByZWFkLmNzdigpYGBgIGZ1bmN0aW9uIHdpdGggdGhlIGxpbmsgdG8gdGhlIGRhdGFzZXQgdG8gaW1wb3J0IHRoZSBkYXRhLiBSZW1lbWJlciB5b3UgY2FuIHVzZSBgYGBoZWFkKClgYGAgb3IgYGBgc3RyKClgYGAgdG8gZXhhbWluZSB0aGUgaW5mb3JtYXRpb24uDQoNClRvIG9idGFpbiBjb3VudHkgaW5mb3JtYXRpb24gZm9yIHRoZSBTdGF0ZSBvZiBUZW5uZXNzZWUgeW91IHNob3VsZCB1c2UgdGhlIGZvbGxvd2luZyBzY3JpcHQ6DQoNCmBgYHtyIHRlbm5lc3NlZSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0biA8LSBtYXBfZGF0YSgnY291bnR5JywgcmVnaW9uID0gInRlbm5lc3NlZSIpDQpoZWFkKHRuKQ0KYGBgDQoNCklmIHlvdSBzZWFyY2ggZm9yIF9tYXBfZGF0YV8gaW4gdGhlICoqZ2dwbG90MioqIFtkb2N1bWVudGF0aW9uXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2dwbG90Mi9nZ3Bsb3QyLnBkZikgeW91IHdpbGwgZmluZCBhbiBleGFtcGxlIG9mIGEgc2NyaXB0IHVzZWQgdG8gaXNvbGF0ZSBpbmZvcm1hdGlvbiBmb3IgdGhlIFN0YXRlIG9mIElvd2EgdGhhdCBjYW4gYmUgYWRhcHRlZCBmb3IgYW55IHN0YXRlIGluIHRoZSBkYXRhc2V0LiBSZW1lbWJlciB3aGVuIHdvcmtpbmcgd2l0aCBzY3JpcHRzLCBHb29nbGUgaXMgeW91ciBmcmllbmQhIEFsbCBpdCByZXF1aXJlcyBpcyBhc2tpbmcgdGhlIGNvcnJlY3QgcXVlc3Rpb24gdG8gZmluZCBzb21lIGV4YW1wbGUgY29kZSBvbmxpbmUgdGhhdCBjYW4gaGVscCBndWlkZSB5b3UuIFRoZXJlIGFyZSBudW1lcm91cyBwb3NzaWJsZSBhbnN3ZXJzIHRvIHRoZSBzYW1lIHByb2JsZW0gc28gZG9uJ3QgaGVzaXRhdGUgdG8gdHJ5IG90aGVyIG1ldGhvZHMuDQoNClVzaW5nIHRoZSBleGFtcGxlIGNvZGUgZnJvbSBzdGVwIHR3bywgeW91IHdpbGwgbmVlZCB0byBgYGBtZXJnZWBgYCB0aGUgdHdvIGRhdGFzZXRzIGludG8gYSBuZXcgb2JqZWN0IGJhc2VkIG9uIGEgY29tbW9uIHZhcmlhYmxlIHN1Y2ggYXMgPHNtYWxsPjxpPkhpbnQuLi5oaW50PC9pPjwvc21hbGw+IGNvdW50eSBuYW1lLg0KDQpGaW5hbGx5LCBieSBhZGFwdGluZyB0aGUgYGBgZ2dwbG90YGBgIGNvZGUgaW4gc3RlcCBmb3VyLCB5b3UgY2FuIG1hcCB0aGUgaW5mb3JtYXRpb24gZm9yIF90b3JuYWRvX2NvdW50XyBmb3IgZWFjaCBjb3VudHkgaW4gVGVubmVzc2VlLiBJbiBvcmRlciB0byBsaW1pdCB0aGUgc2NvcGUgb2YgeW91ciBtYXAgdG8ganVzdCB0aGUgc3RhdGUgeW91IHNob3VsZCBhZGQgdGhlIGZvbGxvd2luZyBzY3JpcHQgdG8geW91ciBtb2RpZmllZCBgYGBnZ3Bsb3RgYGAgY29kZSBmcm9tIGFib3ZlOg0KDQpgYGANCmNvb3JkX2ZpeGVkKHhsaW0gPSBjKC05MCwtODIpLCB5bGltID0gYygzNSwgMzcpKQ0KYGBgDQoNClRoZSBgYGBjb29yZF9maXhlZCgpYGBgIGZ1bmN0aW9uIGxpbWl0cyB0aGUgYXhlcyBiYXNlZCBvbiBzcGVjaWZpZWQgdmFsdWVzLiBUaGUgdmFsdWVzIGFyZSBiYXNlZCBvbiB0aGUgdW5pdHMgb2YgbWVhc3VyZSBvZiB0aGUgZGF0YS4gSW4gdGhpcyBjYW4geW91IHNlZSB3aGVyZSB0aGUgKip4IGF4aXMqKiBpcyBsaW1pdGVkIChfeGxpbV8pIGZyb20gLTgyJmRlZzsgdG8gLTkwJmRlZzsgd2VzdCBsb25naXR1ZGUgYW5kIHRoZSAqKnkgYXhpcyoqIGlzIGxpbWl0ZWQgKF95bGltXykgZnJvbSAzNSZkZWc7IHRvIDM3JmRlZzsgbm9ydGggbGF0aXR1ZGUuIElmIHlvdSBvbWl0IHRoaXMgc2NyaXB0IHlvdXIgbWFwIHdpbGwgbGlrZWx5IGhhdmUgYSAic21hc2hlZCIgYXBwZWFyYW5jZS4gRm9yIGNyZWF0aW5nIG1hcHMgaW4gKipSKiogaXQgaXMgZ2VuZXJhbGx5IGFkdmlzYWJsZSB0byBzZXQgdGhlIF94XyBhbmQgX3lfIGNvb3JkaW5hdGVzIHRvIGVuc3VyZSBwcm9wZXIgZGlzcGxheSBvZiB5b3VyIGRhdGEuIFJlbWVtYmVyIHlvdSB3aWxsIG5lZWQgdG8gYWRqdXN0IHRoZSBhbmNob3IgcG9pbnRzIG9mIHlvdXIgX25hbWUgYW5kIGRhdGVfIHRleHQsIF9ub3J0aCBhcnJvd18gYW5kIF9zY2FsZSBiYXJfIHRvIGZpdCB0aGUgY3VycmVudCBtYXAgdmlldy4gQWRkaXRpb25hbGx5LCB0aGUgX3RpdGxlXyBhbmQgX2xlZ2VuZCB0ZXh0XyBzaG91bGQgYWxzbyByZWZsZWN0IHRoZSBpbmZvcm1hdGlvbiBkZXBpY3RlZCBvbiB5b3VyIG1hcC4NCg0KPGJpZz48Yj5RdWVzdGlvbiBOby4gNDwvYj48L2JpZz4NCjxibG9ja3F1b3RlPg0KV2hpY2ggY291bnR5IGhhZCB0aGUgaGlnaGVzdCBudW1iZXIgb2YgcmVwb3J0ZWQgdG9ybmFkb2VzPzxicj4NClR5cGUgYGBgc3Vic2V0KHRuX3Rvcm5hZG9lcywgdG9ybmFkb19jb3VudCA9PSBtYXgodG9ybmFkb19jb3VudCkpYGBgIGludG8gYSBuZXcgY29kZSBjZWxsIG9yIHVzZSBHb29nbGUgdG8gc2VhcmNoIGZvciBhIGNvdW50eSBtYXAgb2YgVGVubmVzc2VlIHRvIGRldGVybWluZSBjb3VudHkgbG9jYXRpb25zIG9uIHlvdXIgbWFwLjxicj4gDQo8c21hbGw+SGludDogUmVwbGFjZSAqKnRuX3Rvcm5hZG9lcyoqIGluIHRoZSBjb2RlIGFib3ZlIHdpdGggdGhlIG9iamVjdCB5b3UgY3JlYXRlZCBieSBtZXJnaW5nIHRoZSB0b3JuYWRvIGFuZCBjb3VudGllcyBkYXRhc2V0cy48L3NtYWxsPg0KPC9ibG9ja3F1b3RlPg0KDQo8L2RldGFpbHM+DQoNCiMgVGhlIFdyaXRlLVVwDQpUaGUgTW9udGdvbWVyeSBDb3VudHkgRW1lcmdlbmN5IE1hbmFnZW1lbnQgQWdlbmN5IGhhcyBhc2tlZCB5b3UgdG8gcHJvdmlkZSBhIG1hcCBkZXRhaWxpbmcgdGhlIG51bWJlciBvZiByZXBvcnRlZCB0b3JuYWRvZXMgaW4gZWFjaCBUZW5uZXNzZWUgY291bnR5IG92ZXIgdGhlIHBhc3Qgc2V2ZXJhbCBkZWNhZGVzLiBCYXNlZCBvbiB0aGUgbWFwIHlvdSBjcmVhdGUgYWJvdmUsIGNvbXBsZXRlIGEgbGFiIHdyaXRlLXVwIHRoYXQgYWRkcmVzc2VzIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOg0KDQotIFByb3ZpZGUgdGhlIG5hbWVzIG9mIHRoZSBmaXZlICg1KSBjb3VudGllcyB0aGF0IHJlY29yZGVkIHRoZSBtb3N0IHRvcm5hZG9lcyBkdXJpbmcgdGhhdCB0aW1lIGZyYW1lDQotIERlc2NyaWJlIHdoaWNoIHJlZ2lvbnMgb2YgVGVubmVzc2VlIGhhZCB0aGUgZmV3ZXN0IHJlcG9ydGVkIHRvcm5hZG9lcyANCi0gSW5mb3JtIE1DRU1BIHdoaWNoIG1ldHJvcG9saXRhbiByZWdpb25zIGNvdWxkIGJlIG1vc3QgaW1wYWN0ZWQgYnkgZnV0dXJlIHNldmVyZSB3ZWF0aGVyIGV2ZW50cw0KDQpXaGVuIGNvbXBsZXRlLCBzZW5kIGEgbGluayB0byB5b3VyIF9Db2xhYiBOb3RlYm9va18gb3IgZW1haWwgdGhlIHdvcmQgZG9jdW1lbnQgb3IgUERGIHdpdGggYW5zd2VycyB0byBRdWVzdGlvbnMgMS00IGFuZCB5b3VyIGNvbXBsZXRlZCBtYXAu