Introduction

This report provides a detailed workflow of the project on Homestead Tax Exemption entitlement assistance outreach, for the City of Philadelphia Office of Philly Stat 360 and Office of Innovation and Technology. The aim of the project is design an algorithm-driven outreach campaign that can cost effectively identify homeowners who are likely to be eligible for the Homestead Tax Exemption but are not participating in the program. The project aims to allow our clients to understand where these properties are located, potential outreach strategies, and the associated costs and benefits.

These relevant properties who are identified as most likely eligible for the Homestead Exemption but not taking up the program, are also thought to be more likely to be subject to “tangled titles,” or family-rental arrangements that require an affidavit to waive need for a rental license.

Background on Property Tax in Philadelphia

Property tax in Philadelphia is 1.3998% of the property value, as assessed by the Office of Property Assessment,for the 2025 tax year. This is made up of 0.6159% (City of Philadelphia) and 0.7839% (School District) The taxes are due March 31st yearly.

Background on Homestead Exemption

The Homestead Exemption reduces the taxable portion of a homeowner’s property assessment by up to $100,000, saving up to $1,399 on real estate taxes annually. The bill signed aimed to lessen the financial burden of new property assessments on Philadelphia homeowners, whose property values increased by an average of 31% after the city delayed the annual calculations for three years due to the pandemic.

Eligibility for the Homestead Exemption is as follows:

A homeowner is Ineligible if a homeowner is already enrolled in these alternative real estate tax relief/abatement programs: • Longtime Owner Occupants Program (LOOP), an income-based program for homeowners who experience a substantial increase in their property assessment. • 10-year residential tax abatement program, although one can only apply for Homestead Exemption after the abatement is over

Programs that can be used in conjunction with the homestead exemption include • Owner-Occupied Real Estate Tax Payment Agreement (OOPA) • Senior Citizen Real Estate Tax Freeze • Low-Income Real Estate Tax Freeze • Real Estate Tax Installment Plan • Tax Credits for Active-Duty Reserve and National Guard Members

Tangled Titles

An issue of concern that may result in a long-term resident not being able to claim for homestead exemption is tangled titles, which occur when a long-term resident effectively functions as a homeowner but lacks legal ownership of the property. This often happens when a family member who owned the property passes away, and the necessary legal processes to formalize the ownership transfer were never completed, leaving the resident ineligible for the exemption. However, Philadelphia has a conditional Homestead Exemption of three years for such cases while the legal transfer of ownership is resolved.

Significance of Outreach

Currently, no focused or strategic efforts are being carried out by to identify and reach homeowners who is not enrolled in the Homestead Exemption. Through an accurate identification of eligible homeowners, a cost-effective and efficient targeted outreach will be possible, enabling these homeowners to be made aware of and receive support in keeping their home.

Exploratory Data Analysis

Dependent Variable - Homestead Exemption

The primary dataset used is the Property and Assessment History publicly available for download on OpenDataPhilly. Six relevant datasets are merged with this primary dataset with common identifying keys such as the parcel number in order to include useful predictor variables in the model predicting for homeowners most likely eligible but not currently enrolled in the Homestead Exemption.

Every observation in the Property and Assessment History dataset is one property in Philadelphia, with a total of 584,049 properties and 79 features. As this dataset is updated daily, the one used for this project is updated as of 31 January 2025.

There is a column homestead_exemption within this dataset which indicates the taxable portion amount removed from the property assessment of the house. It should be noted that there are 14 properties that had a homestead exemption larger then $100,000, the maximum possible amount, which is suspected to be a clerical error and has been flagged to the PhillyStat360 team. The dependent variable for the model is derived from this feature by creating a binary variable on whether or not the property is currently enrolled in the homestead exemption program, indicated by a non-zero value. There are 246,853 properties with a homestead exemption.

The dataset was filtered to include only properties that are under residential zoning codes. Properties with owners that are organizations and companies, such as owner names containing ‘non profit’ or ‘office’ or ‘church’, were also removed. This is to align with the eligibility criteria of the Homestead Exemption program, which should be for individual homeowners who live in their own property.

Homestead Rate by Census Tract

First, we take a look at the distribution of homestead exemption rates by census tract.

Quantitative Distribution

The distribution of homestead exemption rates across census tracts is approximately normal, with most tracts clustered between 30% and 50%. A notable decline occurs below the 30% threshold, and very few tracts fall below 20%. Tracts with exemption rates under 30% may indicate low participation. If these areas are primarily residential, such figures may warrant targeted outreach or further investigation into potential barriers to enrollment.

Spatial Distribution

Spatially, homestead exemption rates tend to be lower in the central areas of the city compared to the outskirts. This pattern likely reflects a higher proportion of rental or non-residential properties in the urban core, which are less eligible for exemptions. In contrast, peripheral neighborhoods—with more owner-occupied housing—generally exhibit higher rates of participation.

Predictors

Current Property Characteristics

We examine several property-level characteristics that may influence eligibility or participation in the Homestead Exemption program, including ownership status (e.g., corporate ownership) and whether the owner’s mailing address matches the property address.

One of the key eligibility criteria for the Homestead Exemption is that the property must serve as the homeowner’s primary residence. To approximate this, we explore the match between the mailing street address (mailing_street) and the property location address (location) and use it as an predictor. A matching address may suggests that the owner resides at the property.

Another important factor is owner participation in other tax relief programs. Properties already receiving benefits from programs such as LOOP (Longtime Owner Occupants Program) or the Residential Tax Abatement are generally ineligible for the Homestead Exemption. To capture this, we use the exempt-building variable. If this value is non-zero and the property is not enrolled in the Homestead Exemption, it may indicate participation in one of these alternative programs.

The Homestead Exemption also requires that a property is not used exclusively for business or rental purposes—partial use is allowed. We operationalize this rule with two binary variables. We explore its rental Potential by defining the presence of an active rental license and business potential by defining the presence of a business license (excluding rental licenses).

Same Address

Properties enrolled in the Homestead Exemption are more likely to have the owner’s mailing address match the property address, indicating primary residence.

Owner Count Address

Enrolled properties are more likely to be owned by individuals or entities with fewer than 10 properties, suggesting smaller-scale ownership.

Rental Licenses

The Business Licenses & Commercial Activity Licenses dataset from OpenDataPhilly was combined using matching parcel ID. It was found that properties receiving the exemption tend not to hold active rental licenses.

Commertial Licenses

Properties receiving the exemption tend not to have active commercial (non-rental) business licenses.

Historical Property Characteristics

We also examine the historical characteristics of properties, focusing on transfer history and assessment trends over time. The Real Estate Transfers dataset from OpenDataPhilly was combined using matching OPA Account Numbers, while the Assessment History dataset from OpenDataPhilly was combined using matching parcel IDs.

Using residential property assessment data from 2015 to 2025, we compare properties with and without Homestead Exemptions in terms of their average market value and the variability (standard deviation) of that value. This allows us to assess whether exempt properties tend to be more stable or differ systematically in value.

We also analyze year-over-year changes in taxable building values to identify typical patterns of property tax growth, as well as deviations potentially linked to major economic events.

Additionally, we explore property transfer records to better understand the ownership dynamics of exempt properties. We compare exemption rates across different deed types to investigate whether certain forms of property transfer are more commonly associated with exemption enrollment.

Market Value

Properties without exemptions have significantly higher average market values ($304,731 compared to $182,169) and higher variability ($78,513 versus $42,479). This suggests that non-exempt properties tend to have higher market values and experience greater market fluctuations over time. In contrast, exempt properties have lower but much more stable market values, meaning homeowners without exemptions are less vulnerable to sudden market shocks.

Property Transfer Types

Property transfer deed types were also examined in relation to each property. Properties associated with “Deed - Deceased” and “Satisfaction of Mortgage” exhibited notably higher exemption rates. These deed types typically reflect intra-family transfers, inheritance, or mortgage settlements, aligning with common pathways to exemption eligibility. Logistic regression analysis confirmed deed type as a significant predictor of exemption status. Selected deed types can be encoded as binary features for use in predictive modeling.

Recently Transfer

On average, 20.07% of properties without a homestead exemption had a transfer in the past two years, compared to 16.17% of those with an exemption. This indicates that properties without exemptions tend to have a slightly higher likelihood of recent transactions.

Neighborhood Demographic Characteristics

To contextualize individual property patterns within broader neighborhood trends, we also incorporate demographic and financial indicators at the census tract level. Although not formally part of the Homestead Exemption eligibility criteria, these characteristics may influence awareness, application behavior, and outreach effectiveness.

We draw on American Community Survey (ACS) 5-year estimates to include median home value and owner-occupancy rate. Median home value captures the relative wealth of a neighborhood and may correlate with a homeowner’s perceived need for or interest in the exemption. Owner occupancy provides a proxy for residential stability and investment in place—areas with higher rates may be more likely to have eligible and engaged homeowners.

Zoning composition is used to approximate the land use context of each tract. A higher proportion of residential zoning suggests more eligible properties, while mixed-use or commercially dominated areas may contain fewer owner-occupied homes.

We also include tax balance data to capture financial stress at the neighborhood level. This was using the Real Estate Tax Balances dataset from OpenDataPhilly, combining it with the property dataset using zip code. Specifically, we calculate the percentage of properties within each tract that have outstanding tax balances, including principal, penalties, and interest. While this is not a stated criterion for the Homestead Exemption, high levels of tax delinquency may reflect broader socioeconomic challenges—such as lower income, limited English proficiency, or low institutional trust—that influence exemption participation.

Median Home Value

Properties with the Homestead Exemption are typically located in census tracts where the median home value ranges between $200,000 and $400,000, which is generally higher than in tracts without exemptions. However, census tracts with median home values exceeding $400,000 tend to have fewer properties with exemptions, suggesting that wealthier neighborhoods may have lower participation in the program.

Owner Occupancy

Notably, higher rates of owner occupancy don’t automatically translate to higher program participation. This suggests that other factors beyond home ownership - such as awareness of the program, ease of enrollment, or demographic characteristics - may play more significant roles in determining participation rates. These insights can help guide targeted outreach efforts to increase program enrollment among eligible homeowners who are currently missing out on this tax benefit.

Zoning Analysis

Census tracts with single-family zoning, both detached and attached, have the highest percentage of properties with the Homestead Exemption. In contrast, multi-family or mixed-use residential zones tend to have fewer properties enrolled in the exemption program.

Tax Balance Rate

Properties with the Homestead Exemption are more likely to be located in census tracts where fewer properties have outstanding tax balances, particularly in tracts where the tax balance rate is less than 10%.

Modeling

We use the identified property and neighborhood characteristics as predictor variables to model the likelihood that a property receives the Homestead Exemption. The goal is to better understand the key factors associated with exemption status and to identify potentially eligible properties that are not currently enrolled.

We test several classification models, including K-Nearest Neighbors (KNN) and Random Forest, and iteratively refine our feature set. Spatial indicators such as longitude, latitude, and spatial lag terms are incorporated to capture geographic patterns in exemption participation. Our best-performing model is based on XGBoost, which provides the highest predictive accuracy.

Correlation Matrix

We begin by selecting and loading the relevant data, then generate a correlation matrix to gain an initial understanding of the relationships between variables.

Split Dataset

Next, we split the dataset into two parts: 75% for training and 25% for testing. The training set is used to build models using various methods, while the testing set is used to evaluate model performance and identify the most accurate one.

Add Spatial Lag For Training

To prevent data leakage, spatial lag variables need to be calculated separately for the training and test datasets. If spatial information from the test set is used during the training phase, the model would “see” part of the test data’s structure in advance, leading to overfitting and failing to reflect the true generalization ability of the model.

Therefore, in this analysis, we first split the data and then independently calculate the spatial adjacency relationships and spatial lag values for each subset. This approach not only better reflects real-world scenarios (where the model only has access to the training data for prediction) but also improves the accuracy and reliability of model evaluation.

Cross Validation

To ensure the robustness of our model and account for geographic variation, we implement grouped cross-validation using group_vfold_cv(). In this case, we use LOGOCV (Leave-One-Group-Out Cross Validation) based on the geographic_ward variable, which allows us to evaluate model performance across different neighborhood groups.

Before modeling, we also create a preprocessing recipe that includes one-hot encoding for categorical variables, removal of zero-variance predictors, and normalization (centering and scaling) for numeric predictors.

XGBoost Model

We train an XGBoost classification model to predict exemption eligibility, using a grid search to tune key hyperparameters (mtry and min_n). The model is built within a workflow that includes preprocessing steps such as dummy encoding and feature scaling. We apply group-based cross-validation by geographic ward to evaluate model performance and select the best combination of parameters based on accuracy. The finalized model is then fitted on the entire training set and evaluated on the holdout test set. Predictions from both cross-validation and the final test set are collected for further analysis.

Based on the feature importance plot from the XGBoost model, the variable same_address, indicating whether the owner’s mailing address matches the property address, is by far the most influential predictor of exemption status. This likely reflects that owner-occupied properties are more likely to apply for and receive exemptions. Other top predictors include rental_license, suggesting that properties with rental licenses are less likely to receive exemptions, and measures of property value such as sd_market_value (standard deviation of assessed value), avg_market_value, and median_home_value at the tract level, which reflect both property characteristics and neighborhood affordability. Spatial indicators likelag_exemption, lat_4326, and lon_4326 also contribute significantly, showing that spatial clustering and geographic location influence exemption patterns. Overall, a mix of ownership status, rental activity, assessed value, and spatial and demographic context most strongly shape exemption eligibility.

Predict

We use the final model to predict eligibility for exemptions across all properties. We set a 50% probability threshold: properties with predicted probabilities below 50% are classified as ineligible, while those above 50% are classified as eligible. This allows us to compare our predictions with the current exemption status.

As shown, properties without exemptions (marked in red) follow a clear bimodal distribution. The right peak represents the 153,982 properties correctly predicted as ineligible. The left peak highlights over 75,708 properties that are likely eligible for exemption but are currently missing out. These are the properties we will target for outreach.

For properties that already have exemptions (marked in green), there is a single peak, which is expected. This peak corresponds to the 205,780 properties predicted as eligible. The right tail represents 34,006 properties that are incorrectly predicted as ineligible despite having exemptions. We aim to minimize this misclassification. The model performs well in minimizing errors, achieving an 85.8% accuracy in predicting eligible properties with exemptions.

The model’s sensitivity—its ability to correctly identify current exemption holders—is high and consistent across most demographic groups, with rates around 86% and false negative rates (misses) around 14%. Performance is similar for both Majority White and Majority Non-White tracts, as well as across income, foreign-born, and limited English groups.

However, the model is less effective in certain areas: Low Education tracts: Sensitivity drops to 78.6%, with a higher false negative rate of 21.4%. Low Senior Population tracts: Sensitivity is much lower at 52.5%, with nearly half of exemption holders missed (FN rate 47.5%). These results suggest that while the model performs equitably for most groups, additional attention may be needed to ensure residents in tracts with lower education levels or fewer seniors are not overlooked in outreach efforts.

Missed Exemption Opportunities

We focus on false positive properties—those predicted as eligible but currently not receiving an exemption. These properties are key targets for outreach, as they may be missing out on exemption opportunities. At a 0.5 threshold, this amounts to 75,708 houses.

Spatial Density of Missed Exemptions

A density map reveals clustering patterns of missed exemptions across the city. Southwest and North Philadelphia emerge as notable hotspots, suggesting spatial barriers or inequities in exemption uptake. These areas may benefit from additional support or communication efforts.

DBSCAN

DBSCAN, Density-Based Spatial Clustering of Applications with Noise, was also used to explore the spatial distribution of missed exemption opportunities. It is a clustering algorithm that groups data points which are close to each other based on a density criterion. DBSCAN hotspots are regions where there is at least a specified minimum number of points are located within a defined radius (espsilon) from each other. In this case, the minimum number of points was set at 20 and the epsilon at 300 meters. This algorithm is stricter and tends to ignore areas that are high-density but more dispersed. Only dense clusters of closely packed points are identified.

Moran’s I

The local Moran’s I shows two high-high clusters in South and North Philadelphia, indicating areas where properties with missed exemption opportunities are concentrated. In contrast, there are low-low clusters in the city center and Northwest Philadelphia, where fewer such properties are located. In other areas, p-values are above 0.1, so the results aren’t statistically significant.

Demographic

In terms of demographic accorss census tract, the model’s false positive rates—used to guide outreach—show mixed patterns of equity across demographic groups. While the rates are relatively consistent across racial groups (33.0% for Majority White vs 31.9% for Majority Non-White) and language proficiency levels (33.0% for High Limited English vs 33.3% for Low Limited English), there are notable disparities in other areas.

Tracts with lower education levels show significantly lower FP rates (20.0% vs 33.1% in high education areas), and areas with fewer seniors have dramatically lower rates (7.3% vs 33.1% in high senior areas).

Additionally, there’s a slight bias toward wealthier areas (34.8% in Above Average Income vs 31.1% in Below Average Income). These patterns suggest that while the model maintains equity across some demographic dimensions, it may be under-predicting potential exemptions in areas with lower education levels and fewer seniors.

This could reflect true differences in eligibility, but it’s important to monitor these groups to ensure they are not inadvertently underserved. The model’s performance in areas with high foreign-born populations (32.9% FP rate) is relatively equitable compared to low foreign-born areas (35.7%), though the small number of properties in low foreign-born tracts (2,635) makes this comparison less reliable.

Outreach Strategies

Three main potential outreach strategies are proposed. The costs for each of these strategies were then estimated based on existing cost structure references.

The first potential strategy is a direct mailing campaign, which involves sending flyers out to all properties identified as false positives by the model. The flyer would contain information on what the homestead exemption program is, its eligibility criteria, instructions on how to apply, and relevant contact information, translated across different languages.

The next potential strategy is a door-knocking campaign. This involves going door-to-door to identified properties and having canvassers knock on the doors, sharing with homeowners who respond about the homestead exemption program. This face-to-face interaction can highly effective in raising awareness about the program, how to apply to it, and directly address any queries or doubts that the homeowner may have about it. From July 2023 to June 2024, the City of Philadelphia conducted a door-knocking campaign under the Overdose Awareness Canvassing and Trusted Community Messenger Program. Door-knocking is proposed to be conducted for high potential areas with clusters of missed homestead exemption opportunities. This optimizes limited resources in travel time and costs between properties for door knocking. This campaign would therefore only target the 12,302 homes identified in the two clusters, Northeast and South Philadelphia, which have 6,669 and 6,362 target outreach homes respectively.

Another potential strategy is to reach out to community organizations to educate organization leaders and staff about the exemption program, who can then spread the word to their members and the immediate local community about it. This may include community centres or religious organizations, such as the City of Life church in South Philadelphia.

The estimated costs of the outreach strategies were calculated based on the cost structures from the Opioid Response Unit Door-Knocking Campaign and USPS Direct Mail Advertising cost calculator.

Door Knocking:

  • Fixed Costs: Personnel + Supplies
  • Variable Costs: labor $34.80 /hour × (Properties ÷ 10 homes/hr)
  • Indirect Costs: 10% of total direct costs
  • Weekly Capacity: 1,600 homes (8 staff × 20 hrs × 10 homes/hr)

Direct Mailing:

  • Fixed Costs: Personnel + Design + Supplies
  • Variable Costs: Printing $0.09 per piece | Mailing $0.29 per piece
  • Indirect Costs: 10% of total direct costs

The potential benefits of such outreach campaigns are vast. Based on the Data and Marketing Association, the average response rate to a direct mailing campaign ranges between 4 and 9%. With an assumption that 5% of all homeowners we outreach to then successfully enroll into a homestead exemption, the total direct benefit in homeowner savings would be Number of Properties × 0.05 × (up to) $1,399. Using this formula, there can be up to $5,295,774.60 of savings across the homeowners. Majority of the homestead exemptions have been observed to receive the maximum eligible exemption. Comparing this to the total outreach cost for a direct mailing campaign of $35,861, the outreach can bring massive public benefit for a relatively small amount. Furthermore, this estimate does not even include the huge unquantified benefits of increased housing stability for homeowners and their families. This reduces transience and encourages owner occupancy and long term residency, which supports consistent neighborhood networks, fostering more engaged and invested local communities. Owner-occupied homes are also more likely to be well-maintained as there is greater incentive to upkeep the property, which benefits neighborhood aesthetics and property values.

It is then explored how the use of the model compares to an alternative approach of a filtered list of properties. The properties are filtered to residential-only, non-corporation owned properties with the same address as its mailing address. This results in 333,623 properties, which would cost $143,669 to execute solely the direct mailing campaign. Using a machine learning model to identify properties to reach out to substantially narrows down the target number, allowing for huge cost-savings and an effective use of limited resources. The spatial analysis of false positives also allow for more targeted door-knocking to take place.

Dashboard

Our dashboard Homestead Exemption Outreach Explorer is for Philly Stat 360 and potential outreach campaign managers to explore where properties predicted to be likely eligible for the Homestead Exemption program are located, as well as neighborhood profiles of areas. The threshold slider allows one to change the eligibility threshold of the model, where a lower value indicates a more lenient threshold which would include more properties in the census tract, while a higher value indicates a stricter threshold. The exported spreadsheet contains all addresses and owner names of the properties in the selected census tract, based on the chosen threshold level.

Additional features include the address search bar function and the community sites toggle button. Community sites include places of worship, libraries, marketplaces and community centers, extracted from OpenStreetMap. These are potential locations that canvassers can reach out to and partner, including requesting support for disseminating information about the Homestead Exemption program, as well as putting up informational material such as posters in these locations.

One of the census trait characteristics shown in the dashboard is most dominant non-English language spoken in the census tract, along with the percentage of residents who speak it. This can be particularly useful for campaign managers when organizing outreach strategies, such as ensuring canvassers who can speak that particular language conduct outreach in the area to more effectively raise awareness about the Homestead Exemption program to the potential homeowners.

Conclusion

This project aimed to identify homeowners in Philadelphia likely to be eligible but not yet enrolled for the Homestead Exemption program. Through the creation of a machine learning model and a web application dashboard, the hope is for this project to support a data-driven targeted outreach approach that is cost-efficient and able to allow homeowners to receive tax savings. It should be noted that this current model was unable to factor in existing enrollment of a property in the 10-year residential tax abatement or LOOP program, which would make the program ineligible for the Homestead Exemption program. If future access to this data from the Office of Property Assessment can be obtained, this may improve the model further. Nevertheless, the project has provided a model with strong potential and proven the immense benefits stood to be gained by currently unenrolled homeowners at a relatively low cost of outreach. Successfully identifying these homeowners can also allow the City of Philadelphia to provide further benefits such as home upgrading subsidies for these homeowners. Ultimately, it is hoped that ensuring more eligible homeowners are made aware of and can take up the Homeowner Exemption program can offer greater stability, preserve community ties and reduce financial burden for these homeowners.

LS0tDQp0aXRsZTogIk9wdGltaXppbmcgRW50aXRsZW1lbnQgQXNzaXN0YW5jZSBPdXRyZWFjaCB0byBIb21lb3duZXJzIg0KYXV0aG9yOiAiQ2xhdWRpYSBMb3csIEhhb3l1IFpodSwgUmFjaGVsIE1pZGdldHQsIFdlbmp1biBaaHUiDQpkYXRlOiAiMjAyNS0wNS0wOSINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6bWF0ZXJpYWw6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybiANCiAgICBjc3M6IGNzcy9jdXN0b21fdGhlbWUuY3NzICAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgcmVzdWx0cz0naGlkZScsIGNhY2hlID0gRkFMU0UpDQoNCmxpYnJhcnkodGlkeWNlbnN1cykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHNwZGVwKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoY2thbnIpDQpsaWJyYXJ5KEZOTikNCmxpYnJhcnkoZ3JpZCkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShnZ2NvcnJwbG90KSANCmxpYnJhcnkoY29ycnIpICAgIA0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShqdG9vbHMpICAgDQpsaWJyYXJ5KGdnc3RhbmNlKQ0KbGlicmFyeShnZ3B1YnIpIA0KbGlicmFyeShicm9vbS5taXhlZCkNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShjb3JycikNCmxpYnJhcnkoY2xhc3NJbnQpDQpsaWJyYXJ5KHN0YXJnYXplcikNCmxpYnJhcnkoUlNvY3JhdGEpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShrbml0cikgDQpsaWJyYXJ5KHBzY2wpDQpsaWJyYXJ5KHBsb3RST0MpDQpsaWJyYXJ5KHBST0MpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoc3RhcmdhemVyKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoa25pdHIpIA0KbGlicmFyeShwc2NsKQ0KbGlicmFyeShwbG90Uk9DKQ0KbGlicmFyeShwUk9DKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGd0KQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoaGVyZSkNCg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQpyb290LmRpciA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vdXJiYW5TcGF0aWFsL1B1YmxpYy1Qb2xpY3ktQW5hbHl0aWNzLUxhbmRpbmcvbWFzdGVyL0RBVEEvIg0Kc291cmNlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vdXJiYW5TcGF0aWFsL1B1YmxpYy1Qb2xpY3ktQW5hbHl0aWNzLUxhbmRpbmcvbWFzdGVyL2Z1bmN0aW9ucy5yIikNCg0KIyBJbmZsYXRpb24gYWRqdXN0DQppbmZsYXRpb25BZGp1c3QyMDE3IDwtIDEuMDIxMw0KaW5mbGF0aW9uQWRqdXN0MjAxOCA8LSAxLjAyNDQNCg0KIyBTZXQgdXAgdGhlbWUgYW5kIG9wdGlvbnMNCmNvbG9yczIgPC0gYygiMCIgPSAiI2U0MjUyNCIsICIxIiA9ICIjMDBBREE5IikNCmNvbG9yczYgPC0gYygiI2U0MjUyNCIsICIjZWE3MzU3IiwgICIjZjBiNDhiIiwgIiM5NmQyYzciLCAiIzQxYzNiNCIsICIjMDBBREE5IikNCg0KbWFwX3RoZW1lIDwtIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQpiYXNlX3RoZW1lIDwtIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5OTAiKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwgDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApDQogICkNCg0Kb3B0aW9ucyh0aWdyaXNfdXNlX2NhY2hlID0gVFJVRSkNCm9wdGlvbnMoc2NpcGVuID0gOTk5KQ0KYGBgDQoNCiMgSW50cm9kdWN0aW9uDQoNClRoaXMgcmVwb3J0IHByb3ZpZGVzIGEgZGV0YWlsZWQgd29ya2Zsb3cgb2YgdGhlIHByb2plY3Qgb24gSG9tZXN0ZWFkIFRheCBFeGVtcHRpb24gZW50aXRsZW1lbnQgYXNzaXN0YW5jZSBvdXRyZWFjaCwgZm9yIHRoZSBDaXR5IG9mIFBoaWxhZGVscGhpYSBPZmZpY2Ugb2YgUGhpbGx5IFN0YXQgMzYwIGFuZCBPZmZpY2Ugb2YgSW5ub3ZhdGlvbiBhbmQgVGVjaG5vbG9neS4gVGhlIGFpbSBvZiB0aGUgcHJvamVjdCBpcyBkZXNpZ24gYW4gYWxnb3JpdGhtLWRyaXZlbiBvdXRyZWFjaCBjYW1wYWlnbiB0aGF0IGNhbiBjb3N0IGVmZmVjdGl2ZWx5IGlkZW50aWZ5IGhvbWVvd25lcnMgd2hvIGFyZSBsaWtlbHkgdG8gYmUgZWxpZ2libGUgZm9yIHRoZSBbSG9tZXN0ZWFkIFRheCBFeGVtcHRpb25dKGh0dHBzOi8vd3d3LnBoaWxhLmdvdi9zZXJ2aWNlcy9wYXltZW50cy1hc3Npc3RhbmNlLXRheGVzL3RheGVzL3Byb3BlcnR5LWFuZC1yZWFsLWVzdGF0ZS10YXhlcy9nZXQtcmVhbC1lc3RhdGUtdGF4LXJlbGllZi9nZXQtdGhlLWhvbWVzdGVhZC1leGVtcHRpb24vKSBidXQgYXJlIG5vdCBwYXJ0aWNpcGF0aW5nIGluIHRoZSBwcm9ncmFtLiBUaGUgcHJvamVjdCBhaW1zIHRvIGFsbG93IG91ciBjbGllbnRzIHRvIHVuZGVyc3RhbmQgd2hlcmUgdGhlc2UgcHJvcGVydGllcyBhcmUgbG9jYXRlZCwgcG90ZW50aWFsIG91dHJlYWNoIHN0cmF0ZWdpZXMsIGFuZCB0aGUgYXNzb2NpYXRlZCBjb3N0cyBhbmQgYmVuZWZpdHMuDQoNCiFbXShybWRfcG5nL2ljb24xLjAucG5nKQ0KDQpUaGVzZSByZWxldmFudCBwcm9wZXJ0aWVzIHdobyBhcmUgaWRlbnRpZmllZCBhcyBtb3N0IGxpa2VseSBlbGlnaWJsZSBmb3IgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gYnV0IG5vdCB0YWtpbmcgdXAgdGhlIHByb2dyYW0sIGFyZSBhbHNvIHRob3VnaHQgdG8gYmUgbW9yZSBsaWtlbHkgdG8gYmUgc3ViamVjdCB0byDigJx0YW5nbGVkIHRpdGxlcyzigJ0gb3IgZmFtaWx5LXJlbnRhbCBhcnJhbmdlbWVudHMgdGhhdCByZXF1aXJlIGFuIGFmZmlkYXZpdCB0byB3YWl2ZSBuZWVkIGZvciBhIHJlbnRhbCBsaWNlbnNlLg0KDQojIyBCYWNrZ3JvdW5kIG9uIFByb3BlcnR5IFRheCBpbiBQaGlsYWRlbHBoaWENCg0KUHJvcGVydHkgdGF4IGluIFBoaWxhZGVscGhpYSBpcyAqKjEuMzk5OCUgb2YgdGhlIHByb3BlcnR5IHZhbHVlKiosIGFzIGFzc2Vzc2VkIGJ5IHRoZSBPZmZpY2Ugb2YgUHJvcGVydHkgQXNzZXNzbWVudCxmb3IgdGhlIDIwMjUgdGF4IHllYXIuIFRoaXMgaXMgbWFkZSB1cCBvZiAwLjYxNTklIChDaXR5IG9mIFBoaWxhZGVscGhpYSkgYW5kIDAuNzgzOSUgKFNjaG9vbCBEaXN0cmljdCkNClRoZSB0YXhlcyBhcmUgZHVlIE1hcmNoIDMxc3QgeWVhcmx5Lg0KDQohW10ocm1kX3BuZy90YXgucG5nKQ0KDQojIyBCYWNrZ3JvdW5kIG9uIEhvbWVzdGVhZCBFeGVtcHRpb24NClRoZSBIb21lc3RlYWQgRXhlbXB0aW9uIHJlZHVjZXMgdGhlIHRheGFibGUgcG9ydGlvbiBvZiBhIGhvbWVvd25lcidzIHByb3BlcnR5IGFzc2Vzc21lbnQgYnkgdXAgdG8gJDEwMCwwMDAsIHNhdmluZyB1cCB0byAkMSwzOTkgb24gcmVhbCBlc3RhdGUgdGF4ZXMgYW5udWFsbHkuIFRoZSBiaWxsIHNpZ25lZCBhaW1lZCB0byBsZXNzZW4gdGhlIGZpbmFuY2lhbCBidXJkZW4gb2YgbmV3IHByb3BlcnR5IGFzc2Vzc21lbnRzIG9uIFBoaWxhZGVscGhpYSBob21lb3duZXJzLCB3aG9zZSBwcm9wZXJ0eSB2YWx1ZXMgaW5jcmVhc2VkIGJ5IGFuIGF2ZXJhZ2Ugb2YgMzElIGFmdGVyIHRoZSBjaXR5IGRlbGF5ZWQgdGhlIGFubnVhbCBjYWxjdWxhdGlvbnMgZm9yIHRocmVlIHllYXJzIGR1ZSB0byB0aGUgcGFuZGVtaWMuDQoNCkVsaWdpYmlsaXR5IGZvciB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbiBpcyBhcyBmb2xsb3dzOg0KDQohW10ocm1kX3BuZy9lbGlnaWJpbGl0eS5wbmcpDQoNCkEgaG9tZW93bmVyIGlzIEluZWxpZ2libGUgaWYgYSBob21lb3duZXIgaXMgYWxyZWFkeSBlbnJvbGxlZCBpbiB0aGVzZSBhbHRlcm5hdGl2ZSByZWFsIGVzdGF0ZSB0YXggcmVsaWVmL2FiYXRlbWVudCBwcm9ncmFtczoNCuKAoglMb25ndGltZSBPd25lciBPY2N1cGFudHMgUHJvZ3JhbSAoTE9PUCksIGFuCWluY29tZS1iYXNlZCBwcm9ncmFtIGZvciBob21lb3duZXJzIHdobyBleHBlcmllbmNlIGEgc3Vic3RhbnRpYWwgaW5jcmVhc2UgaW4gdGhlaXIgcHJvcGVydHkgYXNzZXNzbWVudC4NCuKAogkxMC15ZWFyIHJlc2lkZW50aWFsIHRheCBhYmF0ZW1lbnQgcHJvZ3JhbSwgYWx0aG91Z2ggb25lIGNhbiBvbmx5IGFwcGx5IGZvciBIb21lc3RlYWQgRXhlbXB0aW9uIGFmdGVyIHRoZSBhYmF0ZW1lbnQgaXMgb3Zlcg0KDQohW10ocm1kX3BuZy9pbmVsaWdpYmxlLnBuZykNCg0KUHJvZ3JhbXMgdGhhdCBjYW4gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBob21lc3RlYWQgZXhlbXB0aW9uIGluY2x1ZGUgDQrigKIJT3duZXItT2NjdXBpZWQgUmVhbCBFc3RhdGUgVGF4IFBheW1lbnQgQWdyZWVtZW50IChPT1BBKQ0K4oCiCVNlbmlvciBDaXRpemVuIFJlYWwgRXN0YXRlIFRheCBGcmVlemUNCuKAoglMb3ctSW5jb21lIFJlYWwgRXN0YXRlIFRheCBGcmVlemUNCuKAoglSZWFsIEVzdGF0ZSBUYXggSW5zdGFsbG1lbnQgUGxhbg0K4oCiIFRheCBDcmVkaXRzIGZvciBBY3RpdmUtRHV0eSBSZXNlcnZlIGFuZCBOYXRpb25hbCBHdWFyZCBNZW1iZXJzDQoNCiMjIFRhbmdsZWQgVGl0bGVzDQpBbiBpc3N1ZSBvZiBjb25jZXJuIHRoYXQgbWF5IHJlc3VsdCBpbiBhIGxvbmctdGVybSByZXNpZGVudCBub3QgYmVpbmcgYWJsZSB0byBjbGFpbSBmb3IgaG9tZXN0ZWFkIGV4ZW1wdGlvbiBpcyB0YW5nbGVkIHRpdGxlcywgd2hpY2ggb2NjdXIgd2hlbiBhIGxvbmctdGVybSByZXNpZGVudCBlZmZlY3RpdmVseSBmdW5jdGlvbnMgYXMgYSBob21lb3duZXIgYnV0IGxhY2tzIGxlZ2FsIG93bmVyc2hpcCBvZiB0aGUgcHJvcGVydHkuIFRoaXMgb2Z0ZW4gaGFwcGVucyB3aGVuIGEgZmFtaWx5IG1lbWJlciB3aG8gb3duZWQgdGhlIHByb3BlcnR5IHBhc3NlcyBhd2F5LCBhbmQgdGhlIG5lY2Vzc2FyeSBsZWdhbCBwcm9jZXNzZXMgdG8gZm9ybWFsaXplIHRoZSBvd25lcnNoaXAgdHJhbnNmZXIgd2VyZSBuZXZlciBjb21wbGV0ZWQsIGxlYXZpbmcgdGhlIHJlc2lkZW50IGluZWxpZ2libGUgZm9yIHRoZSBleGVtcHRpb24uIEhvd2V2ZXIsIFBoaWxhZGVscGhpYSBoYXMgYSBjb25kaXRpb25hbCBIb21lc3RlYWQgRXhlbXB0aW9uIG9mIHRocmVlIHllYXJzIGZvciBzdWNoIGNhc2VzIHdoaWxlIHRoZSBsZWdhbCB0cmFuc2ZlciBvZiBvd25lcnNoaXAgaXMgcmVzb2x2ZWQuDQoNCiMjIFNpZ25pZmljYW5jZSBvZiBPdXRyZWFjaCANCkN1cnJlbnRseSwgbm8gZm9jdXNlZCBvciBzdHJhdGVnaWMgZWZmb3J0cyBhcmUgYmVpbmcgY2FycmllZCBvdXQgYnkgdG8gaWRlbnRpZnkgYW5kIHJlYWNoIGhvbWVvd25lcnMgd2hvIGlzIG5vdCBlbnJvbGxlZCBpbiB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbi4gVGhyb3VnaCBhbiBhY2N1cmF0ZSBpZGVudGlmaWNhdGlvbiBvZiBlbGlnaWJsZSBob21lb3duZXJzLCBhIGNvc3QtZWZmZWN0aXZlIGFuZCBlZmZpY2llbnQgdGFyZ2V0ZWQgb3V0cmVhY2ggd2lsbCBiZSBwb3NzaWJsZSwgZW5hYmxpbmcgdGhlc2UgaG9tZW93bmVycyB0byBiZSBtYWRlIGF3YXJlIG9mIGFuZCByZWNlaXZlIHN1cHBvcnQgaW4ga2VlcGluZyB0aGVpciBob21lLg0KDQojIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KIyMgRGVwZW5kZW50IFZhcmlhYmxlIC0gSG9tZXN0ZWFkIEV4ZW1wdGlvbg0KDQpUaGUgcHJpbWFyeSBkYXRhc2V0IHVzZWQgaXMgdGhlIFByb3BlcnR5IGFuZCBBc3Nlc3NtZW50IEhpc3RvcnkgcHVibGljbHkgYXZhaWxhYmxlIGZvciBkb3dubG9hZCBvbiBbT3BlbkRhdGFQaGlsbHldKGh0dHBzOi8vb3BlbmRhdGFwaGlsbHkub3JnLykuIFNpeCByZWxldmFudCBkYXRhc2V0cyBhcmUgbWVyZ2VkIHdpdGggdGhpcyBwcmltYXJ5IGRhdGFzZXQgd2l0aCBjb21tb24gaWRlbnRpZnlpbmcga2V5cyBzdWNoIGFzIHRoZSBwYXJjZWwgbnVtYmVyIGluIG9yZGVyIHRvIGluY2x1ZGUgdXNlZnVsIHByZWRpY3RvciB2YXJpYWJsZXMgaW4gdGhlIG1vZGVsIHByZWRpY3RpbmcgZm9yIGhvbWVvd25lcnMgbW9zdCBsaWtlbHkgZWxpZ2libGUgYnV0IG5vdCBjdXJyZW50bHkgZW5yb2xsZWQgaW4gdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24uDQoNCkV2ZXJ5IG9ic2VydmF0aW9uIGluIHRoZSBQcm9wZXJ0eSBhbmQgQXNzZXNzbWVudCBIaXN0b3J5IGRhdGFzZXQgaXMgb25lIHByb3BlcnR5IGluIFBoaWxhZGVscGhpYSwgd2l0aCBhIHRvdGFsIG9mIDU4NCwwNDkgcHJvcGVydGllcyBhbmQgNzkgZmVhdHVyZXMuIEFzIHRoaXMgZGF0YXNldCBpcyB1cGRhdGVkIGRhaWx5LCB0aGUgb25lIHVzZWQgZm9yIHRoaXMgcHJvamVjdCBpcyB1cGRhdGVkIGFzIG9mIDMxIEphbnVhcnkgMjAyNS4gDQoNClRoZXJlIGlzIGEgY29sdW1uIGBob21lc3RlYWRfZXhlbXB0aW9uYCB3aXRoaW4gdGhpcyBkYXRhc2V0IHdoaWNoIGluZGljYXRlcyB0aGUgdGF4YWJsZSBwb3J0aW9uIGFtb3VudCByZW1vdmVkIGZyb20gdGhlIHByb3BlcnR5IGFzc2Vzc21lbnQgb2YgdGhlIGhvdXNlLiBJdCBzaG91bGQgYmUgbm90ZWQgdGhhdCB0aGVyZSBhcmUgMTQgcHJvcGVydGllcyB0aGF0IGhhZCBhIGhvbWVzdGVhZCBleGVtcHRpb24gbGFyZ2VyIHRoZW4gJDEwMCwwMDAsIHRoZSBtYXhpbXVtIHBvc3NpYmxlIGFtb3VudCwgd2hpY2ggaXMgc3VzcGVjdGVkIHRvIGJlIGEgY2xlcmljYWwgZXJyb3IgYW5kIGhhcyBiZWVuIGZsYWdnZWQgdG8gdGhlIFBoaWxseVN0YXQzNjAgdGVhbS4gVGhlIGRlcGVuZGVudCB2YXJpYWJsZSBmb3IgdGhlIG1vZGVsIGlzIGRlcml2ZWQgZnJvbSB0aGlzIGZlYXR1cmUgYnkgY3JlYXRpbmcgYSBiaW5hcnkgdmFyaWFibGUgb24gd2hldGhlciBvciBub3QgdGhlIHByb3BlcnR5IGlzIGN1cnJlbnRseSBlbnJvbGxlZCBpbiB0aGUgaG9tZXN0ZWFkIGV4ZW1wdGlvbiBwcm9ncmFtLCBpbmRpY2F0ZWQgYnkgYSBub24temVybyB2YWx1ZS4gVGhlcmUgYXJlIDI0Niw4NTMgcHJvcGVydGllcyB3aXRoIGEgaG9tZXN0ZWFkIGV4ZW1wdGlvbi4NCg0KIVtdKHJtZF9wbmcvYnJpZWZfb3ZlcnZpZXcucG5nKQ0KDQpgYGB7ciByZWFkIGRhdGEsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCnByb3BlcnRpZXMgPC0gZnJlYWQoImRhdGEvb3BhX3Byb3BlcnRpZXNfcHVibGljLmNzdiIpDQpjZW5zdXNfdHJhY3RzIDwtIHN0X3JlYWQoIkRhdGEvcGhpbGFfY2Vuc3VzMS5ncGtnIikNCmBgYA0KVGhlIGRhdGFzZXQgd2FzIGZpbHRlcmVkIHRvIGluY2x1ZGUgb25seSBwcm9wZXJ0aWVzIHRoYXQgYXJlIHVuZGVyIHJlc2lkZW50aWFsIHpvbmluZyBjb2Rlcy4gUHJvcGVydGllcyB3aXRoIG93bmVycyB0aGF0IGFyZSBvcmdhbml6YXRpb25zIGFuZCBjb21wYW5pZXMsIHN1Y2ggYXMgb3duZXIgbmFtZXMgY29udGFpbmluZyAnbm9uIHByb2ZpdCcgb3IgJ29mZmljZScgb3IgJ2NodXJjaCcsIHdlcmUgYWxzbyByZW1vdmVkLiBUaGlzIGlzIHRvIGFsaWduIHdpdGggdGhlIGVsaWdpYmlsaXR5IGNyaXRlcmlhIG9mIHRoZSBIb21lc3RlYWQgRXhlbXB0aW9uIHByb2dyYW0sIHdoaWNoIHNob3VsZCBiZSBmb3IgaW5kaXZpZHVhbCBob21lb3duZXJzIHdobyBsaXZlIGluIHRoZWlyIG93biBwcm9wZXJ0eS4NCg0KYGBge3IgcHJlcGFyZSBwcm9wZXJ0eSBkYXRhLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQoNCiMgRmlsdGVyaW5nIHRvIHJlc2lkZW50aWFsIHByb3BlcnRpZXMNCmZpbHRlcmVkX3Byb3BlcnRpZXNfcmVzb25seSA8LSBwcm9wZXJ0aWVzICU+JSANCiAgbXV0YXRlKGV4ZW1wdGlvbiA9IGlmZWxzZShob21lc3RlYWRfZXhlbXB0aW9uID09IDAsIDAsIDEpKSU+JQ0KICBtdXRhdGUoaXNfcmVzaWRlbnRpYWwgPSBpZmVsc2Uoem9uaW5nICVpbiUgYygNCiAgIlJNMSIsICJSTTIiLCAiUk0zIiwgIlJNNCIsDQogICJSU0ExIiwgIlJTQTIiLCAiUlNBMyIsICJSU0E0IiwgIlJTQTUiLCAiUlNBNiIsIA0KICAiUlNEMSIsICJSU0QyIiwgIlJTRDMiLCANCiAgIlJNMXxSU0E1IiwgIlJTRDF8UlNEMyIsICJSU0E1fFJTQTUiLA0KICAiUlRBMSIsIA0KICAiQ01YMSIsICJDTVgyIiwgIkNNWDIuNSIsICJDTVgzIiwgIkNNWDQiLCAiQ01YNSIsICJJUk1YIiksIDEsIDApKQ0KDQojIFN0ZXAgMTogSWRlbnRpZnkgb3duZXJzIHRvIHJlbW92ZQ0Kb3duZXJzdG9yZW1vdmUgPC0gcHJvcGVydGllcyAlPiUNCiAgZ3JvdXBfYnkob3duZXJfMSkgJT4lDQogIHN1bW1hcmlzZShwcm9wZXJ0eV9jb3VudCA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGZpbHRlcihzdHJfZGV0ZWN0KG93bmVyXzEsICIgTExDIHwgTExDfFJFQUwgRVNUQVRFfEFTU09DfEhBTEFCVUdJIElOQ3xJTlZFU1RNRU5UfENIVVJDSHwxMjI5LTEyNDcgTk9SVEggMjdUSCBTVHxLSU5HUyBISUdIV0FZfFZJTExBR0V8DQogIEFDUVVJU0lUSU9OfFBBUlRORVJTfDIxMDEgV0FTSElOR1RPTiBBVkVOVUUgTEx8Q0hBSSBOVVRTIExQfFJFQUxUWXxQUk9QRVJUSUVTfFNQRUNJQUwgUEVPUExFIElOIE5PUlRIRUF8Q09NUEFOWXxTUEVDSUFMfA0KICBMQU5EIFRSVVNUfFRSVVNUfFNJRU5BIFBMQUNFIFBMQU5ORUQgQ09NTVV8Tk9SUklTIFNRVUFSRSBORUlHSEJPUkhPT3wyMDEtNTkgTk9SVEggRUlHSFRIfFBSRVBBUkFUT1J8SU5WRVNUT1JTfA0KICBQT0lOVCBCUkVFWkV8V1BSRSBJSUkgTCBQfE5BVElPTkFMfEFSQ0ggVi1URU1QTEUgMTZUSCBTVFJFRVR8Tk9SVEggRk9VUlRIIFNUUkVFVHxCQU5LRVJTIFRSVVNUfENPTU1PTlMgQVQgUE9JTlQgQlJFRVpFfA0KICBWRVRFUkFOfFBSRVNFUlZBVElPTnxDT05ET01JTklVTXwxOTkgSFVOVElORyBQQVJLfEFQQVJUTUVOVHxIT0xESU5HU3wgTCBQfENPVVJUfFNDSE9PTHxTRVJWSUNFU3xIQUJJVEFUIEZPUiBIVU1BTklUWXxDT01NSVRURUV8QkFQVElTVHwNCiAgQ09MTEVHRXxBQ1FVSVNJVElPTnxERUxFT3xBTVRSQUt8UkVOVEFMU3xQQVJUSUNJUEFUSU9OfFNQUklORyBBUlRTfFNFUFRBfFdBU0hJTkdUT04gU1FVQVJFfEZBSVJNT1VOVCBQQVJLfFBBUktJTkd8DQogIEFSQ0ggVkkgLSBURU1QTEV8VEhFIExPRlRTfEZVTkQgfFdIQVJUT04gQ09VUlR8R1JPVVB8UEVOVEVDT1NUfFJBRCBESVZFUlNJRklFRCBSRUlUIElOQ3xDT01NT05TfExJTUlURUR8UEVOTkEgfEZJUlNUfENPTlRSQUNUT1J8UE9JTlQgQlJFRVpFfEJPT1RTVFJBUHxSSVRURU5IT1VTRXwNCiAgSEFCSVRBVCBGT1IgSFVNQU5JVFl8REVMQVdBUkUgUklWRVJ8RU5URVJQUklTRVN8Q09NTVVOSVRZfEZPVU5EQVRJT058QkVMTCBURUxFUEhPTkUgQ098Q0VOVEVSfFBBUlRORVJTfERFVkVMT1BNRU5UfA0KICBWRVQgQUZGQUlSU3xGRURFUkFMfFdPUktGT1JDRXxQRU5ORE9UfElOVkVTVE9SU3xHRU9SR0UgV09PRFdBUkQgSU5DfEhBUlJJU09OIElOQ3xKREogRlVORHxBRkZPUkRBQkxFfElOVEVSU1RBVEV8IElOQyB8QklPIExVQ0tZIFNUQVIgSU5DfExFQU5OQSBJTkN8RUxFQkFIIElOQ3xCRU5HRU1JTkkgQ09OU1VMVEFOVFMgSU5DfEJVSUxERVJTfEtPUkVBTiBDT01NVU5JVFkgREVWRUxPUE18REVWRUxPUEVSU3wNCiAgUE9SVEZPTElPfFJFU0lERU5USUFMfFBISUxMWXxQUk9KRUNUfE1BTkFHRU1FTlR8VU1PSkEgSU5DfEFTU04gSU5DfERFTEFXQVJFIFZBTExFWXxBUkNIIFZJIC0gVEVNUExFIE4gR1JBVFp8U1VQUExZfExPRlRTfFNUUkVFVHxPRkZJQ0V8IExQfENJVFl8VkVOVFVSRVN8DQogIFVOSVRFRCBTVEFURVMgT0YgQU1FUklDQXxQSElMQXxOT04gUFJPRklUfEFTU098SE9VU0V8TkVJR0hCT1JIT09EfFBBVEggSU5DfFVOSVZ8SE9VU0lOR3xQUk9QRVJUWXxDT01NT05XRUFMVEh8Q09OUkFJTHxDT01NRVJDRXwNCiAgVkVOVFVSRVN8VU5JVEVEfENPUlJJRE9SfFNRVUFSRXxDSVZJQ3xBUk1ZfFNBTFZBVElPTnxQRU5OU1lMVkFOSUF8QURNSU5JU1RSQVRPUnxUT1dOSE9NRVN8Q0JNfFJFTlRBTHxBTUVSSUNBIElOQ3xTVCBGUkFOQ0lTIElOTnxIT01FT1dORVJTSElQfA0KICBJTlNUSVRVVEV8UkVTT1VSQ0VTfENPTlNUUlVDVElPTnxMIFB8VFJBTlNQT1JUQVRJT058Q1NYfERSRVhFTHxQQVNTWVVOS3xDT0xMRUdFfFdJU1RFUkNPUiBJTkN8U0lFTkEgUExBQ0UgUFVEfEVRVUlUWXwgQ0FQSVRBTHxFWFBPUlR8U1RSQVdCRVJSWSBNQU5TSU9OfDctRUxFVkVOfEtFRVAgUExVR0dJTkcgVEhSRUUgSU5DfE9VVFNPVVJDRSAyMDAwIElOQ3xDSEFJIDE4IElOQ3xZIEUgUiBBIElOQyB8V09STER8QURNSU58VSBTIE9GIEFNRVJJQ0F8QVVUSE9SSVRZfA0KICBTRVBUQXxBUFRTfCBMVER8Q09SUCIpKSAlPiUNCiAgcHVsbChvd25lcl8xKSAgIyBFeHRyYWN0IHRoZSBsaXN0IG9mIG93bmVycyB0byByZW1vdmUNCg0KIyBTdGVwIDI6IEZpbHRlciBvdXQgcHJvcGVydGllcyBvd25lZCBieSB0aGVzZSBvd25lcnMNCmZpbHRlcmVkX3Byb3BlcnRpZXMgPC0gZmlsdGVyZWRfcHJvcGVydGllc19yZXNvbmx5ICU+JQ0KICBmaWx0ZXIoIW93bmVyXzEgJWluJSBvd25lcnN0b3JlbW92ZSkNCg0KIyBMb29rIGludG8gZXhlbXB0aW9uIHN0YXR1cyBieSB6b25pbmcgY29kZQ0KZXhlbXB0aW9uYnl6b25pbmcgPC0gZmlsdGVyZWRfcHJvcGVydGllcyAlPiUNCiAgZ3JvdXBfYnkoem9uaW5nLCBleGVtcHRpb24pICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGV4ZW1wdGlvbiwgdmFsdWVzX2Zyb20gPSBjb3VudCwgdmFsdWVzX2ZpbGwgPSBsaXN0KGNvdW50ID0gMCkpICU+JQ0KICByZW5hbWUoTm9fRXhlbXB0aW9uID0gYDBgLCBFeGVtcHRpb24gPSBgMWApDQoNCnJlc2lkZW50aWFsX3Byb3BlcnRpZXMgPC0gZmlsdGVyZWRfcHJvcGVydGllcyAlPiUgZmlsdGVyKGlzX3Jlc2lkZW50aWFsID09IDEpDQpgYGANCg0KYGBge3IgcHJlcGFyZSBzZiBkYXRhLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQojIyMjIFRyYW5zZm9ybSB0byBnZW9kYXRhIGluIGJvdGggMjI3MiBhbmQgNDMyNiBwbGFuZXMNCnByb3BlcnRpZXNfc2YgPC0gc3RfYXNfc2YocmVzaWRlbnRpYWxfcHJvcGVydGllcywgd2t0ID0gInNoYXBlIiwgY3JzID0gMjI3MikNCg0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSBwcm9wZXJ0aWVzX3NmICU+JQ0KICBtdXRhdGUoDQogICAgeF8yMjcyID0gc3RfY29vcmRpbmF0ZXMoLilbLDFdLCAgIyBYIGNvb3JkaW5hdGUgaW4gRVBTRzoyMjcyDQogICAgeV8yMjcyID0gc3RfY29vcmRpbmF0ZXMoLilbLDJdICAgIyBZIGNvb3JkaW5hdGUgaW4gRVBTRzoyMjcyDQogICkgJT4lDQogIHN0X3RyYW5zZm9ybShjcnMgPSA0MzI2KSAlPiUNCiAgbXV0YXRlKA0KICAgIGxvbl80MzI2ID0gc3RfY29vcmRpbmF0ZXMoLilbLDFdLCAgIyBMb25naXR1ZGUgaW4gRVBTRzo0MzI2DQogICAgbGF0XzQzMjYgPSBzdF9jb29yZGluYXRlcyguKVssMl0gICAjIExhdGl0dWRlIGluIEVQU0c6NDMyNg0KICApICU+JQ0KICBzdF9kcm9wX2dlb21ldHJ5KCkNCg0KY2Vuc3VzX3RyYWN0cyA8LSBzdF90cmFuc2Zvcm0oY2Vuc3VzX3RyYWN0cywgMjI3MikgJT4lIA0KICBtdXRhdGUob3duZXJfb2NjX3JhdGUgPSAob3duZXJfaGggLyBvY2N1cGllZF91bml0cykqIDEwMCkNCg0KcHJvcGVydGllc190cmFjdCA8LSBzdF9qb2luKHByb3BlcnRpZXNfc2YsIGNlbnN1c190cmFjdHMpDQoNCiMgQ3JlYXRlIHRyYWN0IHN1bW1hcnkNCnRyYWN0X3N1bW1hcnkgPC0gcHJvcGVydGllc190cmFjdCAlPiUNCiAgZ3JvdXBfYnkoR0VPSUQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcHJvcGVydGllcyA9IG4oKSwNCiAgICBob21lc3RlYWRfY291bnQgPSBzdW0oaG9tZXN0ZWFkX2V4ZW1wdGlvbiA+IDAsIG5hLnJtID0gVFJVRSksDQogICAgcGN0X2hvbWVzdGVhZCA9IChob21lc3RlYWRfY291bnQgLyB0b3RhbF9wcm9wZXJ0aWVzKSAqIDEwMCwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkgJT4lDQogIHN0X2Ryb3BfZ2VvbWV0cnkoKQ0KDQojIENyZWF0ZSBmaW5hbCBlbnJpY2hlZCBkYXRhc2V0DQpjZW5zdXNfdHJhY3RzX2VucmljaGVkIDwtIGNlbnN1c190cmFjdHMgJT4lDQogIGxlZnRfam9pbih0cmFjdF9zdW1tYXJ5LCBieSA9ICJHRU9JRCIpDQoNCmNlbnN1c190cmFjdHNfZW5yaWNoZWQgPC0gY2Vuc3VzX3RyYWN0c19lbnJpY2hlZCAlPiUNCiAgbXV0YXRlKA0KICAgIG93bmVyX29jY19yYXRlID0gKGNlbnN1c190cmFjdHNfZW5yaWNoZWQkb3duZXJfaGggLyBjZW5zdXNfdHJhY3RzX2VucmljaGVkJG9jY3VwaWVkX3VuaXRzKSAqIDEwMA0KICApDQpgYGANCg0KIyMjIEhvbWVzdGVhZCBSYXRlIGJ5IENlbnN1cyBUcmFjdCB7LnRhYnNldH0NCg0KRmlyc3QsIHdlIHRha2UgYSBsb29rIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgaG9tZXN0ZWFkIGV4ZW1wdGlvbiByYXRlcyBieSBjZW5zdXMgdHJhY3QuDQoNCiMjIyMgUXVhbnRpdGF0aXZlIERpc3RyaWJ1dGlvbiB7LnVubnVtYmVyZWR9DQogDQpUaGUgZGlzdHJpYnV0aW9uIG9mIGhvbWVzdGVhZCBleGVtcHRpb24gcmF0ZXMgYWNyb3NzIGNlbnN1cyB0cmFjdHMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwsIHdpdGggbW9zdCB0cmFjdHMgY2x1c3RlcmVkIGJldHdlZW4gMzAlIGFuZCA1MCUuIEEgbm90YWJsZSBkZWNsaW5lIG9jY3VycyBiZWxvdyB0aGUgMzAlIHRocmVzaG9sZCwgYW5kIHZlcnkgZmV3IHRyYWN0cyBmYWxsIGJlbG93IDIwJS4gVHJhY3RzIHdpdGggZXhlbXB0aW9uIHJhdGVzIHVuZGVyIDMwJSBtYXkgaW5kaWNhdGUgbG93IHBhcnRpY2lwYXRpb24uIElmIHRoZXNlIGFyZWFzIGFyZSBwcmltYXJpbHkgcmVzaWRlbnRpYWwsIHN1Y2ggZmlndXJlcyBtYXkgd2FycmFudCB0YXJnZXRlZCBvdXRyZWFjaCBvciBmdXJ0aGVyIGludmVzdGlnYXRpb24gaW50byBwb3RlbnRpYWwgYmFycmllcnMgdG8gZW5yb2xsbWVudC4NCg0KYGBge3IgUXVhbnRpdGF0aXZlIERpc3RyaWJ1dGlvbiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KY2Vuc3VzX3RyYWN0c19maWx0ZXJlZCA8LSBjZW5zdXNfdHJhY3RzX2VucmljaGVkICU+JQ0KICBmaWx0ZXIocG9wX2RlbnNpdHkgPiAwICYgdG90YWxfcHJvcGVydGllcyA+PSAzMCkgICMgMzAgcHJvcGVydGllcyBtaW5pbXVtDQoNCmNlbnN1c190cmFjdHNfaW52YWxpZCA8LSBjZW5zdXNfdHJhY3RzX2VucmljaGVkICU+JQ0KICBmaWx0ZXIocG9wX2RlbnNpdHkgPT0gMCB8IHRvdGFsX3Byb3BlcnRpZXMgPCAzMCkgICMgSW5jbHVkZSBsb3cgcHJvcGVydHkgY291bnRzIGluICJpbnZhbGlkIg0KDQpnZ3Bsb3QoY2Vuc3VzX3RyYWN0c19lbnJpY2hlZCAlPiUgZmlsdGVyKHBvcF9kZW5zaXR5ID4gMCksDQogICAgICAgYWVzKHggPSBwY3RfaG9tZXN0ZWFkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbSgNCiAgICBiaW53aWR0aCA9IDUsIGZpbGwgPSAiIzAwQURBOSIsIGNvbG9yID0gIndoaXRlIg0KICApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgSG9tZXN0ZWFkIEV4ZW1wdGlvbiBSYXRlcyBBY3Jvc3MgUGhpbGFkZWxwaGlhIENlbnN1cyBUcmFjdHMiLA0KICAgIHN1YnRpdGxlID0gIkV4Y2x1ZGluZyBaZXJvIFBvcHVsYXRpb24gRGVuc2l0eSBUcmFjdHMiLA0KICAgIHggPSAiUGVyY2VudGFnZSBvZiBQcm9wZXJ0aWVzIHdpdGggSG9tZXN0ZWFkIEV4ZW1wdGlvbiIsDQogICAgeSA9ICJOdW1iZXIgb2YgQ2Vuc3VzIFRyYWN0cyINCiAgKSArDQogIGJhc2VfdGhlbWUgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCkpDQpgYGANCg0KIyMjIyBTcGF0aWFsIERpc3RyaWJ1dGlvbiB7LnVubnVtYmVyZWR9DQoNClNwYXRpYWxseSwgaG9tZXN0ZWFkIGV4ZW1wdGlvbiByYXRlcyB0ZW5kIHRvIGJlIGxvd2VyIGluIHRoZSBjZW50cmFsIGFyZWFzIG9mIHRoZSBjaXR5IGNvbXBhcmVkIHRvIHRoZSBvdXRza2lydHMuIFRoaXMgcGF0dGVybiBsaWtlbHkgcmVmbGVjdHMgYSBoaWdoZXIgcHJvcG9ydGlvbiBvZiByZW50YWwgb3Igbm9uLXJlc2lkZW50aWFsIHByb3BlcnRpZXMgaW4gdGhlIHVyYmFuIGNvcmUsIHdoaWNoIGFyZSBsZXNzIGVsaWdpYmxlIGZvciBleGVtcHRpb25zLiBJbiBjb250cmFzdCwgcGVyaXBoZXJhbCBuZWlnaGJvcmhvb2Rz4oCUd2l0aCBtb3JlIG93bmVyLW9jY3VwaWVkIGhvdXNpbmfigJRnZW5lcmFsbHkgZXhoaWJpdCBoaWdoZXIgcmF0ZXMgb2YgcGFydGljaXBhdGlvbi4NCg0KYGBge3IgU3BhdGlhbCBEaXN0cmlidXRpb24sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmN1c3RvbV9jb2xvcnMgPC0gYygiPDIwJSIgPSAiI2U0MjUyNCIsICAgICANCiAgICAgICAgICAgICAgICAgICAiMjAtMzAlIiA9ICIjZWE3MzU3IiwgICAgDQogICAgICAgICAgICAgICAgICAgIjMwLTQwJSIgPSAiI2YwYjQ4YiIsICAgDQogICAgICAgICAgICAgICAgICAgIjQwLTUwJSIgPSAiIzk2ZDJjNyIsICAgDQogICAgICAgICAgICAgICAgICAgIjUwLTYwJSIgPSAiIzQxYzNiNCIsICAgIA0KICAgICAgICAgICAgICAgICAgICI+NjAlIiA9ICIjMDBBREE5IikNCg0KZ2dwbG90KGNlbnN1c190cmFjdHNfZW5yaWNoZWQgJT4lDQogICAgICAgICBtdXRhdGUocGN0X2hvbWVzdGVhZCA9IGNhc2Vfd2hlbigNCiAgICAgICAgICAgcG9wX2RlbnNpdHkgPCAyMDAwIHwgdG90YWxfcHJvcGVydGllcyA8IDEwMCB+IE5BX3JlYWxfLA0KICAgICAgICAgICBUUlVFIH4gcGN0X2hvbWVzdGVhZCkpKSArDQogIGdlb21fc2YoYWVzKGZpbGwgPSBjdXQocGN0X2hvbWVzdGVhZCwgDQogICAgICAgICAgICAgIGJyZWFrcyA9IGMoMCwgMjAsIDMwLCA0MCwgNTAsIDYwLCAxMDApLA0KICAgICAgICAgICAgICBsYWJlbHMgPSBjKCI8MjAlIiwgIjIwLTMwJSIsICIzMC00MCUiLCAiNDAtNTAlIiwgIjUwLTYwJSIsICI+NjAlIikpKSwNCiAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwoDQogICAgbmFtZSA9ICJIb21lc3RlYWRcbkV4ZW1wdGlvbiBSYXRlIiwNCiAgICB2YWx1ZXMgPSBjdXN0b21fY29sb3JzLA0KICAgIG5hLnZhbHVlID0gImdyYXk5NSIsDQogICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpDQogICkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkhvbWVzdGVhZCBFeGVtcHRpb24gUmF0ZXMgQWNyb3NzIFBoaWxhZGVscGhpYSIsDQogICAgc3VidGl0bGUgPSAiQnkgQ2Vuc3VzIFRyYWN0IiwNCiAgICBjYXB0aW9uID0gIkdyYXkgdHJhY3RzIGluZGljYXRlIHBvcHVsYXRpb24gZGVuc2l0eSA8IDIsMDAwIHBlciBzcS4gbWlsZSBvciBmZXdlciB0aGFuIDEwMCBwcm9wZXJ0aWVzIg0KICApICsNCiAgYmFzZV90aGVtZSArDQogIHRoZW1lKA0KICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0Ig0KICApDQpgYGANCg0KYGBge3IgQUREX1NwYXRpYWxfbGFnLCBldmFsPUZBTFNFfQ0Ka25uX25iIDwtIGtubjJuYihrbmVhcm5laWdoKHhnYl9mdWxsX3ByZWRfc2YsIGsgPSA0LCB1c2Vfa2RfdHJlZSA9IEZBTFNFKSkNCg0KZXhlbXB0aW9uX2RhdGEgPC0gYXMuZmFjdG9yKHByb3BlcnRpZXNfZnVsbF9wcmVkX3NmJGV4ZW1wdGlvbikNCmpvaW5fY291bnRfdGVzdCA8LSBqb2luY291bnQudGVzdChleGVtcHRpb25fZGF0YSwgbGlzdHcgPSBuYjJsaXN0dyhrbm5fbmIsIHN0eWxlID0gIkIiKSkNCg0KbHcgPC0gbmIybGlzdHcoa25uX25iLCBzdHlsZSA9ICJXIikgDQpwcm9wZXJ0aWVzX2Z1bGxfcHJlZF9zZiRsYWdfZXhlbXB0aW9uIDwtIGxhZy5saXN0dyhsdywgcHJvcGVydGllc19mdWxsX3ByZWRfc2YkZXhlbXB0aW9uKQ0KYGBgDQoNCg0KIyMgUHJlZGljdG9ycw0KDQojIyMgQ3VycmVudCBQcm9wZXJ0eSBDaGFyYWN0ZXJpc3RpY3Mgey50YWJzZXR9DQoNCldlIGV4YW1pbmUgc2V2ZXJhbCBwcm9wZXJ0eS1sZXZlbCBjaGFyYWN0ZXJpc3RpY3MgdGhhdCBtYXkgaW5mbHVlbmNlIGVsaWdpYmlsaXR5IG9yIHBhcnRpY2lwYXRpb24gaW4gdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gcHJvZ3JhbSwgaW5jbHVkaW5nIG93bmVyc2hpcCBzdGF0dXMgKGUuZy4sIGNvcnBvcmF0ZSBvd25lcnNoaXApIGFuZCB3aGV0aGVyIHRoZSBvd25lcidzIG1haWxpbmcgYWRkcmVzcyBtYXRjaGVzIHRoZSBwcm9wZXJ0eSBhZGRyZXNzLg0KDQpPbmUgb2YgdGhlIGtleSBlbGlnaWJpbGl0eSBjcml0ZXJpYSBmb3IgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gaXMgdGhhdCB0aGUgcHJvcGVydHkgbXVzdCBzZXJ2ZSBhcyB0aGUgaG9tZW93bmVy4oCZcyBwcmltYXJ5IHJlc2lkZW5jZS4gVG8gYXBwcm94aW1hdGUgdGhpcywgd2UgZXhwbG9yZSB0aGUgbWF0Y2ggYmV0d2VlbiB0aGUgbWFpbGluZyBzdHJlZXQgYWRkcmVzcyAoYG1haWxpbmdfc3RyZWV0YCkgYW5kIHRoZSBwcm9wZXJ0eSBsb2NhdGlvbiBhZGRyZXNzIChgbG9jYXRpb25gKSBhbmQgdXNlIGl0IGFzIGFuIHByZWRpY3Rvci4gQSBtYXRjaGluZyBhZGRyZXNzIG1heSBzdWdnZXN0cyB0aGF0IHRoZSBvd25lciByZXNpZGVzIGF0IHRoZSBwcm9wZXJ0eS4NCg0KQW5vdGhlciBpbXBvcnRhbnQgZmFjdG9yIGlzIG93bmVyIHBhcnRpY2lwYXRpb24gaW4gb3RoZXIgdGF4IHJlbGllZiBwcm9ncmFtcy4gUHJvcGVydGllcyBhbHJlYWR5IHJlY2VpdmluZyBiZW5lZml0cyBmcm9tIHByb2dyYW1zIHN1Y2ggYXMgTE9PUCAoTG9uZ3RpbWUgT3duZXIgT2NjdXBhbnRzIFByb2dyYW0pIG9yIHRoZSBSZXNpZGVudGlhbCBUYXggQWJhdGVtZW50IGFyZSBnZW5lcmFsbHkgaW5lbGlnaWJsZSBmb3IgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24uIFRvIGNhcHR1cmUgdGhpcywgd2UgdXNlIHRoZSBleGVtcHQtYnVpbGRpbmcgdmFyaWFibGUuIElmIHRoaXMgdmFsdWUgaXMgbm9uLXplcm8gYW5kIHRoZSBwcm9wZXJ0eSBpcyBub3QgZW5yb2xsZWQgaW4gdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24sIGl0IG1heSBpbmRpY2F0ZSBwYXJ0aWNpcGF0aW9uIGluIG9uZSBvZiB0aGVzZSBhbHRlcm5hdGl2ZSBwcm9ncmFtcy4NCg0KVGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gYWxzbyByZXF1aXJlcyB0aGF0IGEgcHJvcGVydHkgaXMgbm90IHVzZWQgZXhjbHVzaXZlbHkgZm9yIGJ1c2luZXNzIG9yIHJlbnRhbCBwdXJwb3Nlc+KAlHBhcnRpYWwgdXNlIGlzIGFsbG93ZWQuIFdlIG9wZXJhdGlvbmFsaXplIHRoaXMgcnVsZSB3aXRoIHR3byBiaW5hcnkgdmFyaWFibGVzLiBXZSBleHBsb3JlIGl0cyByZW50YWwgUG90ZW50aWFsIGJ5IGRlZmluaW5nIHRoZSBwcmVzZW5jZSBvZiBhbiBhY3RpdmUgcmVudGFsIGxpY2Vuc2UgYW5kIGJ1c2luZXNzIHBvdGVudGlhbCBieSBkZWZpbmluZyB0aGUgcHJlc2VuY2Ugb2YgYSBidXNpbmVzcyBsaWNlbnNlIChleGNsdWRpbmcgcmVudGFsIGxpY2Vuc2VzKS4NCg0KIyMjIyBTYW1lIEFkZHJlc3Mgey51bm51bWJlcmVkfQ0KDQpQcm9wZXJ0aWVzIGVucm9sbGVkIGluIHRoZSBIb21lc3RlYWQgRXhlbXB0aW9uIGFyZSBtb3JlIGxpa2VseSB0byBoYXZlIHRoZSBvd25lcidzIG1haWxpbmcgYWRkcmVzcyBtYXRjaCB0aGUgcHJvcGVydHkgYWRkcmVzcywgaW5kaWNhdGluZyBwcmltYXJ5IHJlc2lkZW5jZS4gDQoNCmBgYHtyIHNhbWVfYWRkcmVzcywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSByZXNpZGVudGlhbF9wcm9wZXJ0aWVzICU+JSANCiAgbXV0YXRlKHNhbWVfYWRkcmVzcyA9IGlmZWxzZShtYWlsaW5nX3N0cmVldCA9PSBsb2NhdGlvbiwgMSwgMCkpDQoNCmdncGxvdChyZXNpZGVudGlhbF9wcm9wZXJ0aWVzLCBhZXMoeCA9IHNhbWVfYWRkcmVzcywgZmlsbCA9IGFzLmZhY3RvcihleGVtcHRpb24pKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JzMiwgbGFiZWxzID0gYygiTm8gRXhlbXB0aW9uIiwgIldpdGggRXhlbXB0aW9uIikpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJNYWlsaW5nIEFkZHJlc3MgTWF0Y2hlcyBQcm9wZXJ0eSBBZGRyZXNzIiwNCiAgICB4ID0gIkFkZHJlc3MgTWF0Y2giLA0KICAgIHkgPSAiQ291bnQiLA0KICAgIGZpbGwgPSAiSG9tZXN0ZWFkIEV4ZW1wdGlvbiINCiAgKSArDQogIGJhc2VfdGhlbWUNCmBgYA0KDQojIyMjIE93bmVyIENvdW50IEFkZHJlc3Mgey51bm51bWJlcmVkfQ0KDQpFbnJvbGxlZCBwcm9wZXJ0aWVzIGFyZSBtb3JlIGxpa2VseSB0byBiZSBvd25lZCBieSBpbmRpdmlkdWFscyBvciBlbnRpdGllcyB3aXRoIGZld2VyIHRoYW4gMTAgcHJvcGVydGllcywgc3VnZ2VzdGluZyBzbWFsbGVyLXNjYWxlIG93bmVyc2hpcC4NCg0KYGBge3Igb3duZXJfY291bnQsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCiMjIENvdW50IHRoZSBudW1iZXIgb2YgcHJvcGVydGllcyBieSBvd25lcl8xDQpvd25lcl9wcm9wZXJ0eV9jb3VudCA8LSBmaWx0ZXJlZF9wcm9wZXJ0aWVzICU+JQ0KICBncm91cF9ieShvd25lcl8xKSAlPiUNCiAgc3VtbWFyaXNlKHByb3BlcnR5X2NvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgYXJyYW5nZShkZXNjKHByb3BlcnR5X2NvdW50KSklPiUNCiAgbXV0YXRlKG93bmVyX2NvdW50ID0gaWZlbHNlKHByb3BlcnR5X2NvdW50ID49IDEwLCAxLCAwKSkNCg0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSByZXNpZGVudGlhbF9wcm9wZXJ0aWVzICU+JQ0KICBsZWZ0X2pvaW4ob3duZXJfcHJvcGVydHlfY291bnQgJT4lZHBseXI6OnNlbGVjdChvd25lcl8xLCBvd25lcl9jb3VudCksIA0KICAgICAgICAgICAgYnkgPSAib3duZXJfMSIpICU+JQ0KICBtdXRhdGUob3duZXJfY291bnQgPSBpZmVsc2UoaXMubmEob3duZXJfY291bnQpLCAwLCBvd25lcl9jb3VudCkpDQoNCmdncGxvdChyZXNpZGVudGlhbF9wcm9wZXJ0aWVzLCBhZXMoeCA9IGFzLmZhY3Rvcihvd25lcl9jb3VudCksIGZpbGwgPSBhcy5mYWN0b3IoZXhlbXB0aW9uKSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yczIsIGxhYmVscyA9IGMoIk5vIEV4ZW1wdGlvbiIsICJXaXRoIEV4ZW1wdGlvbiIpKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiT3duZXIgQ291bnQgYnkgSG9tZXN0ZWFkIEV4ZW1wdGlvbiIsDQogICAgeCA9ICJPd25lciBDb3VudCA+IDEwIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkhvbWVzdGVhZCBFeGVtcHRpb24iDQogICkgKw0KICBiYXNlX3RoZW1lDQpgYGANCg0KIyMjIyBSZW50YWwgTGljZW5zZXMgey51bm51bWJlcmVkfQ0KDQpUaGUgQnVzaW5lc3MgTGljZW5zZXMgJiBDb21tZXJjaWFsIEFjdGl2aXR5IExpY2Vuc2VzIGRhdGFzZXQgZnJvbSBPcGVuRGF0YVBoaWxseSB3YXMgY29tYmluZWQgdXNpbmcgbWF0Y2hpbmcgcGFyY2VsIElELiBJdCB3YXMgZm91bmQgdGhhdCBwcm9wZXJ0aWVzIHJlY2VpdmluZyB0aGUgZXhlbXB0aW9uIHRlbmQgbm90IHRvIGhvbGQgYWN0aXZlIHJlbnRhbCBsaWNlbnNlcy4NCg0KYGBge3IgcmVudGFsIGxpY2Vuc2UsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmJ1c2luZXNzX2xpY2Vuc2U8LXN0X3JlYWQoIkRhdGEvYnVzaW5lc3NfbGljZW5zZXMuZ2VvanNvbiIpDQoNCnJlbnRhbF9saWNlbnNlPC1idXNpbmVzc19saWNlbnNlJT4lDQogIGZpbHRlcihsaWNlbnNldHlwZT09IlJlbnRhbCIsDQogICAgICAgICBsaWNlbnNlc3RhdHVzICVpbiUgYygiQWN0aXZlIikpJT4lDQogIGRwbHlyOjpzZWxlY3Qob3BhX2FjY291bnRfbnVtKSU+JQ0KICBzdF9kcm9wX2dlb21ldHJ5KCklPiUNCiAgZGlzdGluY3QoKSAlPiUgDQogIGZpbHRlcighaXMubmEob3BhX2FjY291bnRfbnVtKSkgJT4lIA0KICBtdXRhdGUocmVudGFsX2xpY2Vuc2UgPSAxKSAgDQoNCnByb3BlcnRpZXNfcmVudGFsIDwtIHByb3BlcnRpZXNfc2YgJT4lDQogIG11dGF0ZShwYXJjZWxfbnVtYmVyID0gYXMuY2hhcmFjdGVyKHBhcmNlbF9udW1iZXIpKSU+JQ0KICBsZWZ0X2pvaW4ocmVudGFsX2xpY2Vuc2UsIGJ5ID0gYygicGFyY2VsX251bWJlciIgPSAib3BhX2FjY291bnRfbnVtIikpJT4lDQogIG11dGF0ZShyZW50YWxfbGljZW5zZSA9IHJlcGxhY2VfbmEocmVudGFsX2xpY2Vuc2UsIDApKQ0KDQpyZXNpZGVudGlhbF9wcm9wZXJ0aWVzIDwtIHJlc2lkZW50aWFsX3Byb3BlcnRpZXMgJT4lDQogIGxlZnRfam9pbihwcm9wZXJ0aWVzX3JlbnRhbCU+JXN0X2Ryb3BfZ2VvbWV0cnkoKSU+JWRwbHlyOjpzZWxlY3Qob2JqZWN0aWQscmVudGFsX2xpY2Vuc2UpLCANCiAgICAgICAgICAgIGJ5ID0gYygib2JqZWN0aWQiID0gIm9iamVjdGlkIikpDQoNCmdncGxvdChwcm9wZXJ0aWVzX3JlbnRhbCwgDQogICAgICAgYWVzKHggPSBmYWN0b3IocmVudGFsX2xpY2Vuc2UpLCBmaWxsID0gYXMuZmFjdG9yKGV4ZW1wdGlvbikpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMyLCBsYWJlbHMgPSBjKCJObyBFeGVtcHRpb24iLCAiV2l0aCBFeGVtcHRpb24iKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlJlbnRhbCBMaWNlbnNlcyBieSBIb21lc3RlYWQgRXhlbXB0aW9uIiwNCiAgICB4ID0gIlJlbnRhbCBMaWNlbnNlIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkhvbWVzdGVhZCBFeGVtcHRpb24iDQogICkgKw0KICBiYXNlX3RoZW1lDQpgYGANCg0KIyMjIyBDb21tZXJ0aWFsIExpY2Vuc2VzIHsudW5udW1iZXJlZH0NCg0KUHJvcGVydGllcyByZWNlaXZpbmcgdGhlIGV4ZW1wdGlvbiB0ZW5kIG5vdCB0byBoYXZlIGFjdGl2ZSBjb21tZXJjaWFsIChub24tcmVudGFsKSBidXNpbmVzcyBsaWNlbnNlcy4NCg0KYGBge3IgQnVzaW5lc3MgTGljZW5zZSBFeGNsdWRlIFJlbnRhbCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KY29tbWVyY2lhbF9saWNlbnNlPC1idXNpbmVzc19saWNlbnNlJT4lDQogIGZpbHRlcihsaWNlbnNlc3RhdHVzICVpbiUgYygiQWN0aXZlIikpJT4lDQogIGZpbHRlcihsaWNlbnNldHlwZSAlaW4lIGMoDQogICAgIkZvb2QgQ2F0ZXJlciIsDQogICAgIkZvb2QgRXN0YWJsaXNobWVudCwgUmV0YWlsIFBlcm0gTG9jYXRpb24gKExhcmdlKSIsDQogICAgIkZvb2QgRXN0YWJsaXNobWVudCwgUmV0YWlsIFBlcm1hbmVudCBMb2NhdGlvbiIsDQogICAgIkZvb2QgTWFudWZhY3R1cmVyIC8gV2hvbGVzYWxlciIsDQogICAgIkZvb2QgUHJlcGFyaW5nIGFuZCBTZXJ2aW5nIiwNCiAgICAiRm9vZCBQcmVwYXJpbmcgYW5kIFNlcnZpbmcgKDMwKyBTRUFUUykiLA0KICAgICJNb3RvciBWZWhpY2xlIFJlcGFpciAvIFJldGFpbCBNb2JpbGUgRGlzcGVuc2luZyIsDQogICAgIlBhd24gU2hvcCIsDQogICAgIlByZWNpb3VzIE1ldGFsIERlYWxlciIsDQogICAgIlB1YmxpYyBHYXJhZ2UgLyBQYXJraW5nIExvdCIsDQogICAgIlJlc2lkZW50aWFsIFByb3BlcnR5IFdob2xlc2FsZXIiLA0KICAgICJUaXJlIERlYWxlciIsDQogICAgIlRvdyBDb21wYW55IiwNCiAgICAiVmFjYW50IENvbW1lcmNpYWwgUHJvcGVydHkiDQogICkpJT4lDQogIGRwbHlyOjpzZWxlY3Qob3BhX2FjY291bnRfbnVtKSU+JQ0KICBzdF9kcm9wX2dlb21ldHJ5KCklPiUNCiAgZGlzdGluY3QoKSAlPiUgDQogIGZpbHRlcighaXMubmEob3BhX2FjY291bnRfbnVtKSkgJT4lIA0KICBtdXRhdGUoY29tbWVyY2lhbF9saWNlbnNlID0gMSkgDQoNCnByb3BlcnRpZXNfY29tbWVyY2lhbCA8LSBwcm9wZXJ0aWVzX3NmICU+JQ0KICBtdXRhdGUocGFyY2VsX251bWJlciA9IGFzLmNoYXJhY3RlcihwYXJjZWxfbnVtYmVyKSklPiUNCiAgbGVmdF9qb2luKGNvbW1lcmNpYWxfbGljZW5zZSwgYnkgPSBjKCJwYXJjZWxfbnVtYmVyIiA9ICJvcGFfYWNjb3VudF9udW0iKSklPiUNCiAgbXV0YXRlKGNvbW1lcmNpYWxfbGljZW5zZSA9IHJlcGxhY2VfbmEoY29tbWVyY2lhbF9saWNlbnNlLCAwKSkNCg0KDQpyZXNpZGVudGlhbF9wcm9wZXJ0aWVzIDwtIHJlc2lkZW50aWFsX3Byb3BlcnRpZXMgJT4lDQogIGxlZnRfam9pbihwcm9wZXJ0aWVzX2NvbW1lcmNpYWwlPiUNCiAgICAgICAgICAgICAgc3RfZHJvcF9nZW9tZXRyeSgpJT4lDQogICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3Qob2JqZWN0aWQsY29tbWVyY2lhbF9saWNlbnNlKSwgDQogICAgICAgICAgICBieSA9IGMoIm9iamVjdGlkIiA9ICJvYmplY3RpZCIpKQ0KDQpnZ3Bsb3QocHJvcGVydGllc19jb21tZXJjaWFsLCANCiAgICAgICBhZXMoeCA9IGZhY3Rvcihjb21tZXJjaWFsX2xpY2Vuc2UpLCBmaWxsID0gYXMuZmFjdG9yKGV4ZW1wdGlvbikpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMyLCBsYWJlbHMgPSBjKCJObyBFeGVtcHRpb24iLCAiV2l0aCBFeGVtcHRpb24iKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkNvbW1lcmNpYWwgTGljZW5zZXMgYnkgSG9tZXN0ZWFkIEV4ZW1wdGlvbiIsDQogICAgeCA9ICJDb21tZXJjaWFsIExpY2Vuc2UgKEV4Y2x1ZGUgUmVudGFsKSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJIb21lc3RlYWQgRXhlbXB0aW9uIg0KICApICsNCiAgYmFzZV90aGVtZQ0KYGBgDQoNCiMjIyBIaXN0b3JpY2FsIFByb3BlcnR5IENoYXJhY3RlcmlzdGljcyB7LnRhYnNldH0NCg0KV2UgYWxzbyBleGFtaW5lIHRoZSBoaXN0b3JpY2FsIGNoYXJhY3RlcmlzdGljcyBvZiBwcm9wZXJ0aWVzLCBmb2N1c2luZyBvbiB0cmFuc2ZlciBoaXN0b3J5IGFuZCBhc3Nlc3NtZW50IHRyZW5kcyBvdmVyIHRpbWUuIFRoZSBSZWFsIEVzdGF0ZSBUcmFuc2ZlcnMgZGF0YXNldCBmcm9tIE9wZW5EYXRhUGhpbGx5IHdhcyBjb21iaW5lZCB1c2luZyBtYXRjaGluZyBPUEEgQWNjb3VudCBOdW1iZXJzLCB3aGlsZSB0aGUgQXNzZXNzbWVudCBIaXN0b3J5IGRhdGFzZXQgZnJvbSBPcGVuRGF0YVBoaWxseSB3YXMgY29tYmluZWQgdXNpbmcgbWF0Y2hpbmcgcGFyY2VsIElEcy4NCg0KVXNpbmcgcmVzaWRlbnRpYWwgcHJvcGVydHkgYXNzZXNzbWVudCBkYXRhIGZyb20gMjAxNSB0byAyMDI1LCB3ZSBjb21wYXJlIHByb3BlcnRpZXMgd2l0aCBhbmQgd2l0aG91dCBIb21lc3RlYWQgRXhlbXB0aW9ucyBpbiB0ZXJtcyBvZiB0aGVpciBhdmVyYWdlIG1hcmtldCB2YWx1ZSBhbmQgdGhlIHZhcmlhYmlsaXR5IChzdGFuZGFyZCBkZXZpYXRpb24pIG9mIHRoYXQgdmFsdWUuIFRoaXMgYWxsb3dzIHVzIHRvIGFzc2VzcyB3aGV0aGVyIGV4ZW1wdCBwcm9wZXJ0aWVzIHRlbmQgdG8gYmUgbW9yZSBzdGFibGUgb3IgZGlmZmVyIHN5c3RlbWF0aWNhbGx5IGluIHZhbHVlLg0KDQpXZSBhbHNvIGFuYWx5emUgeWVhci1vdmVyLXllYXIgY2hhbmdlcyBpbiB0YXhhYmxlIGJ1aWxkaW5nIHZhbHVlcyB0byBpZGVudGlmeSB0eXBpY2FsIHBhdHRlcm5zIG9mIHByb3BlcnR5IHRheCBncm93dGgsIGFzIHdlbGwgYXMgZGV2aWF0aW9ucyBwb3RlbnRpYWxseSBsaW5rZWQgdG8gbWFqb3IgZWNvbm9taWMgZXZlbnRzLg0KDQpBZGRpdGlvbmFsbHksIHdlIGV4cGxvcmUgcHJvcGVydHkgdHJhbnNmZXIgcmVjb3JkcyB0byBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgb3duZXJzaGlwIGR5bmFtaWNzIG9mIGV4ZW1wdCBwcm9wZXJ0aWVzLiBXZSBjb21wYXJlIGV4ZW1wdGlvbiByYXRlcyBhY3Jvc3MgZGlmZmVyZW50IGRlZWQgdHlwZXMgdG8gaW52ZXN0aWdhdGUgd2hldGhlciBjZXJ0YWluIGZvcm1zIG9mIHByb3BlcnR5IHRyYW5zZmVyIGFyZSBtb3JlIGNvbW1vbmx5IGFzc29jaWF0ZWQgd2l0aCBleGVtcHRpb24gZW5yb2xsbWVudC4NCg0KIyMjIyBNYXJrZXQgVmFsdWUgey51bm51bWJlcmVkfSANCg0KUHJvcGVydGllcyB3aXRob3V0IGV4ZW1wdGlvbnMgaGF2ZSBzaWduaWZpY2FudGx5IGhpZ2hlciBhdmVyYWdlIG1hcmtldCB2YWx1ZXMgKCQzMDQsNzMxIGNvbXBhcmVkIHRvICQxODIsMTY5KSBhbmQgaGlnaGVyIHZhcmlhYmlsaXR5ICgkNzgsNTEzIHZlcnN1cyAkNDIsNDc5KS4gVGhpcyBzdWdnZXN0cyB0aGF0IG5vbi1leGVtcHQgcHJvcGVydGllcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIG1hcmtldCB2YWx1ZXMgYW5kIGV4cGVyaWVuY2UgZ3JlYXRlciBtYXJrZXQgZmx1Y3R1YXRpb25zIG92ZXIgdGltZS4gSW4gY29udHJhc3QsIGV4ZW1wdCBwcm9wZXJ0aWVzIGhhdmUgbG93ZXIgYnV0IG11Y2ggbW9yZSBzdGFibGUgbWFya2V0IHZhbHVlcywgbWVhbmluZyBob21lb3duZXJzIHdpdGhvdXQgZXhlbXB0aW9ucyBhcmUgbGVzcyB2dWxuZXJhYmxlIHRvIHN1ZGRlbiBtYXJrZXQgc2hvY2tzLg0KDQpgYGB7ciBNYXJrZXRfVmFsdWUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCiMgTG9hZCBhbmQgaW5zcGVjdCB0aGUgYXNzZXNzbWVudHMgZGF0YXNldA0KYXNzZXNzbWVudHMyIDwtIGZyZWFkKCJEYXRhL2Fzc2Vzc21lbnRzLmNzdiIpDQoNCiMgTWVyZ2UgcHJvcGVydGllcyBhbmQgYXNzZXNzbWVudHMgZGF0YSBieSBwYXJjZWxfbnVtYmVyDQpjbGVhbmVkX3Byb3BlcnRpZXMgPC0gZmlsdGVyZWRfcHJvcGVydGllcyAlPiUNCiAgZHBseXI6OnNlbGVjdChwYXJjZWxfbnVtYmVyLCBleGVtcHRpb24sIGlzX3Jlc2lkZW50aWFsLCBzaGFwZSkNCmFzc2Vzc21lbnRfY29tYmluZWQgPC0gYXNzZXNzbWVudHMyICU+JQ0KICBsZWZ0X2pvaW4oY2xlYW5lZF9wcm9wZXJ0aWVzLCBieSA9ICJwYXJjZWxfbnVtYmVyIikNCg0KIyBGaWx0ZXIgdGhlIGNvbWJpbmVkIGRhdGFzZXQgdG8gaW5jbHVkZSBvbmx5IHJlc2lkZW50aWFsIHByb3BlcnRpZXMNCnJlc2lkZW50aWFsX2Fzc2Vzc21lbnRfY29tYmluZWQgPC0gYXNzZXNzbWVudF9jb21iaW5lZCAlPiUNCiAgZmlsdGVyKGlzX3Jlc2lkZW50aWFsID09IDEpDQoNCiMgU3VtbWFyaXplIGtleSBtZXRyaWNzIGZvciBlYWNoIHBhcmNlbDogbWVhbiwgZ3Jvd3RoIHJhdGUsIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24NCnJlc2lkZW50aWFsX3N1bW1hcnkgPC0gcmVzaWRlbnRpYWxfYXNzZXNzbWVudF9jb21iaW5lZCAlPiUNCiAgZ3JvdXBfYnkocGFyY2VsX251bWJlcikgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBhdmdfbWFya2V0X3ZhbHVlID0gbWVhbihtYXJrZXRfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2RfbWFya2V0X3ZhbHVlID0gc2QobWFya2V0X3ZhbHVlLCBuYS5ybSA9IFRSVUUpDQogICkNCg0KIyBBZGQgZXhlbXB0aW9uIGFuZCByZXNpZGVudGlhbCBzdGF0dXMgdG8gdGhlIHN1bW1hcnkgZGF0YXNldA0KcmVzaWRlbnRpYWxfc3VtbWFyeSA8LSByZXNpZGVudGlhbF9zdW1tYXJ5ICU+JQ0KICBsZWZ0X2pvaW4oDQogICAgcmVzaWRlbnRpYWxfYXNzZXNzbWVudF9jb21iaW5lZCAlPiUNCiAgICAgIGRwbHlyOjpzZWxlY3QocGFyY2VsX251bWJlciwgZXhlbXB0aW9uLCBpc19yZXNpZGVudGlhbCwgc2hhcGUpICU+JQ0KICAgICAgZGlzdGluY3QocGFyY2VsX251bWJlciwgLmtlZXBfYWxsID0gVFJVRSksICAjIEtlZXAgb25lIHJvdyBwZXIgcGFyY2VsX251bWJlcg0KICAgIGJ5ID0gInBhcmNlbF9udW1iZXIiDQogICkNCg0KI2pvaW4gdG8gZGF0YXNldA0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSByZXNpZGVudGlhbF9wcm9wZXJ0aWVzICU+JQ0KICBsZWZ0X2pvaW4ocmVzaWRlbnRpYWxfc3VtbWFyeSAlPiUNCiAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChwYXJjZWxfbnVtYmVyLGF2Z19tYXJrZXRfdmFsdWUsc2RfbWFya2V0X3ZhbHVlKSwgDQogICAgICAgICAgICBieSA9IGMoInBhcmNlbF9udW1iZXIiID0gInBhcmNlbF9udW1iZXIiKSkNCg0KIyBBbmFseXNpcyBieSBFeGVtcHRpb24gU3RhdHVzDQojIFN1bW1hcml6ZSBtZXRyaWNzIGJ5IGV4ZW1wdGlvbiBzdGF0dXMNCnJlc2lkZW50aWFsX3N1bW1hcnlfYW5hbHlzaXMgPC0gcmVzaWRlbnRpYWxfc3VtbWFyeSAlPiUNCiAgZ3JvdXBfYnkoZXhlbXB0aW9uKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGF2Z19tYXJrZXRfdmFsdWUgPSBtZWFuKGF2Z19tYXJrZXRfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2RfbWFya2V0X3ZhbHVlID0gbWVhbihzZF9tYXJrZXRfdmFsdWUsIG5hLnJtID0gVFJVRSkNCiAgKSANCg0Kc3VtbWFyeV9maWx0ZXJlZCA8LSByZXNpZGVudGlhbF9zdW1tYXJ5X2FuYWx5c2lzICU+JQ0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IC1leGVtcHRpb24sIA0KICAgIG5hbWVzX3RvID0gIm1ldHJpYyIsIA0KICAgIHZhbHVlc190byA9ICJ2YWx1ZSINCiAgKSU+JQ0KICBmaWx0ZXIobWV0cmljICVpbiUgYygiYXZnX21hcmtldF92YWx1ZSIsICJzZF9tYXJrZXRfdmFsdWUiKSkNCg0KZ2dwbG90KHN1bW1hcnlfZmlsdGVyZWQsIGFlcyh4ID0gbWV0cmljLCB5ID0gdmFsdWUsIGZpbGwgPSBhcy5mYWN0b3IoZXhlbXB0aW9uKSwgY29sb3IgPSBhcy5mYWN0b3IoZXhlbXB0aW9uKSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjcpLCB3aWR0aCA9IDAuNiwgYWxwaGEgPSAwLjg1KSArIA0KICB5bGltKDAsIG1heChzdW1tYXJ5X2ZpbHRlcmVkJHZhbHVlKSAqIDEuMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMyLCBsYWJlbHMgPSBjKCJObyBFeGVtcHRpb24iLCAiV2l0aCBFeGVtcHRpb24iKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzMiwgZ3VpZGUgPSAibm9uZSIpICsgIA0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgYW5kIFN0YW5kYXJkIERldmlhdGlvbiBvZiBNYXJrZXQgVmFsdWUgKDIwMTUtMjAyNSkiLA0KICAgICAgIHggPSAiTWV0cmljIiwgDQogICAgICAgeSA9ICJWYWx1ZSAoJCkiLCANCiAgICAgICBmaWxsID0gIkV4ZW1wdGlvbiBTdGF0dXMiKSArDQogIGJhc2VfdGhlbWUgDQpgYGANCg0KDQojIyMjIFllYXJseSBUcmVuZHMgaW4gUmVzaWRlbnRpYWwgRGF0YSB7LnVubnVtYmVyZWR9DQoNCkJ5IHBsb3R0aW5nIHRoZSB5ZWFybHkgdGF4YWJsZSBidWlsZGluZyB2YWx1ZXMgZm9yIGV4ZW1wdCBhbmQgbm9uLWV4ZW1wdCBwcm9wZXJ0aWVzIGZyb20gMjAxNSB0byAyMDI1LCB3ZSBvYnNlcnZlZCB0aGF0IG5vbi1leGVtcHQgcHJvcGVydGllcyBleHBlcmllbmNlZCBhIHNpZ25pZmljYW50bHkgZmFzdGVyIGluY3JlYXNlIGluIHRheGFibGUgdmFsdWVzIGNvbXBhcmVkIHRvIGV4ZW1wdCBwcm9wZXJ0aWVzLiBUaGlzIGxvbmctdGVybSB0cmVuZCBpbmRpY2F0ZXMgdGhhdCBub24tZXhlbXB0IGhvbWVvd25lcnMgaGF2ZSBiZWVuIG1vcmUgZXhwb3NlZCB0byBzdGVhZGlseSByaXNpbmcgdGF4IGJ1cmRlbnMgb3ZlciB0aW1lLiBNb3Jlb3ZlciwgdGhlIHNoYXJwZXIgY2hhbmdlcyBvYnNlcnZlZCBiZXR3ZWVuIDIwMjIgYW5kIDIwMjUgZnVydGhlciBoaWdobGlnaHQgaG93IG5vbi1leGVtcHQgcHJvcGVydGllcyByZXNwb25kZWQgbW9yZSBzZW5zaXRpdmVseSB0byBicm9hZGVyIGVjb25vbWljIHNoaWZ0cywgd2hlcmVhcyBleGVtcHQgcHJvcGVydGllcyByZW1haW5lZCByZWxhdGl2ZWx5IGluc3VsYXRlZCwgbWFpbnRhaW5pbmcgYSBtb3JlIHN0YWJsZSB0YXhhdGlvbiB0cmFqZWN0b3J5Lg0KDQpgYGB7ciBZZWFybHkgVHJlbmRzLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQp5ZWFybHlfcmVzaWRlbnRpYWxfZGF0YSA8LSBhc3Nlc3NtZW50czIgJT4lDQogIGlubmVyX2pvaW4oY2xlYW5lZF9wcm9wZXJ0aWVzLCBieSA9ICJwYXJjZWxfbnVtYmVyIikgJT4lDQogIGZpbHRlcihpc19yZXNpZGVudGlhbCA9PSAxKSAgIyBLZWVwIG9ubHkgcmVzaWRlbnRpYWwgcHJvcGVydGllcw0KDQojIFN1bW1hcml6ZSB5ZWFybHkgcmVzaWRlbnRpYWwgZGF0YSBieSBleGVtcHRpb24gc3RhdHVzDQp5ZWFybHlfcmVzaWRlbnRpYWxfc3VtbWFyeSA8LSB5ZWFybHlfcmVzaWRlbnRpYWxfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgZXhlbXB0aW9uKSAlPiUNCiAgc3VtbWFyaXNlKHRheGFibGVfYnVpbGRpbmcgPSBtZWFuKHRheGFibGVfYnVpbGRpbmcsIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCnllYXJseV9yZXNpZGVudGlhbF9zdW1tYXJ5ICU+JQ0KICBmaWx0ZXIoeWVhciA+PSAyMDE1KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHRheGFibGVfYnVpbGRpbmcsIGNvbG9yID0gYXMuZmFjdG9yKGV4ZW1wdGlvbikpKSArDQogICAgZ2VvbV9saW5lKHNpemUgPSAxLjIpICsNCiAgICBnZW9tX3BvaW50KHNpemUgPSAyKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgyMDE1LCBtYXgoeWVhcmx5X3Jlc2lkZW50aWFsX3N1bW1hcnkkeWVhciksIGJ5ID0gMSkpICsNCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzMiwgbGFiZWxzID0gYygiTm8gRXhlbXB0aW9uIiwgIldpdGggRXhlbXB0aW9uIikpICsNCiAgICBsYWJzKHRpdGxlID0gIlllYXJseSBDaGFuZ2UgaW4gVGF4YWJsZSBCdWlsZGluZyBWYWx1ZSIsDQogICAgICAgICB4ID0gIlllYXIiLCB5ID0gIlRheGFibGUgQnVpbGRpbmcgVmFsdWUiLCBjb2xvciA9ICJFeGVtcHRpb24gU3RhdHVzIikgKw0KICAgIGJhc2VfdGhlbWUgKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KIyMjIyBQcm9wZXJ0eSBUcmFuc2ZlciBUeXBlcyB7LnVubnVtYmVyZWR9DQoNClByb3BlcnR5IHRyYW5zZmVyIGRlZWQgdHlwZXMgd2VyZSBhbHNvIGV4YW1pbmVkIGluIHJlbGF0aW9uIHRvIGVhY2ggcHJvcGVydHkuIFByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoICJEZWVkIC0gRGVjZWFzZWQiIGFuZCAiU2F0aXNmYWN0aW9uIG9mIE1vcnRnYWdlIiBleGhpYml0ZWQgbm90YWJseSBoaWdoZXIgZXhlbXB0aW9uIHJhdGVzLiBUaGVzZSBkZWVkIHR5cGVzIHR5cGljYWxseSByZWZsZWN0IGludHJhLWZhbWlseSB0cmFuc2ZlcnMsIGluaGVyaXRhbmNlLCBvciBtb3J0Z2FnZSBzZXR0bGVtZW50cywgYWxpZ25pbmcgd2l0aCBjb21tb24gcGF0aHdheXMgdG8gZXhlbXB0aW9uIGVsaWdpYmlsaXR5LiBMb2dpc3RpYyByZWdyZXNzaW9uIGFuYWx5c2lzIGNvbmZpcm1lZCBkZWVkIHR5cGUgYXMgYSBzaWduaWZpY2FudCBwcmVkaWN0b3Igb2YgZXhlbXB0aW9uIHN0YXR1cy4gU2VsZWN0ZWQgZGVlZCB0eXBlcyBjYW4gYmUgZW5jb2RlZCBhcyBiaW5hcnkgZmVhdHVyZXMgZm9yIHVzZSBpbiBwcmVkaWN0aXZlIG1vZGVsaW5nLg0KDQpgYGB7ciB0cmFuc2Zlcl90eXBlc19ub25lLCBldmFsPUZBTFNFfQ0KdHJhbnNmZXJzMiA8LSBmcmVhZCgiRGF0YS9SVFRfU1VNTUFSWS5jc3YiKQ0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSBjbGVhbmVkX3Byb3BlcnRpZXMgJT4lDQogIGZpbHRlcihpc19yZXNpZGVudGlhbCA9PSAxKQ0KcmVzaWRlbnRpYWxfdHJhbnNmZXJzIDwtIHJlc2lkZW50aWFsX3Byb3BlcnRpZXMgJT4lDQogIGxlZnRfam9pbih0cmFuc2ZlcnMyLCBieSA9IGMoInBhcmNlbF9udW1iZXIiID0gIm9wYV9hY2NvdW50X251bSIpKQ0KDQpyZXNpZGVudGlhbF90cmFuc2ZlcnMgPC0gcmVzaWRlbnRpYWxfdHJhbnNmZXJzICU+JQ0KICBtdXRhdGUoZG9jdW1lbnRfdHlwZSA9IGlmZWxzZShpcy5uYShkb2N1bWVudF90eXBlKSwgIlVua25vd24iLCBkb2N1bWVudF90eXBlKSkNCg0KZXhlbXB0aW9uX2J5X2RvY3VtZW50X3R5cGUgPC0gcmVzaWRlbnRpYWxfdHJhbnNmZXJzICU+JQ0KICBncm91cF9ieShkb2N1bWVudF90eXBlKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX2NvdW50ID0gbigpLA0KICAgIGV4ZW1wdGlvbl9jb3VudCA9IHN1bShleGVtcHRpb24gPT0gMSksDQogICAgZXhlbXB0aW9uX3Byb3BvcnRpb24gPSBleGVtcHRpb25fY291bnQgLyB0b3RhbF9jb3VudCAqIDEwMA0KICApICU+JQ0KICBhcnJhbmdlKGRlc2MoZXhlbXB0aW9uX3Byb3BvcnRpb24pKQ0KDQojIyBiaW5vbWlhbCBtb2RlbDpERUVEIC0gREVDRUFTRUQsIFNBVElTRkFDVElPTiBPRiBNT1JUR0FHRSwgTU9SVEdBR0UsIEFTU0lHTk1FTlQgT0YgTU9SVEdBR0UNCmRvY3VtZW50X2V4ZW1wdGlvbl9tb2RlbCA8LSBnbG0oZXhlbXB0aW9uIH4gZG9jdW1lbnRfdHlwZSwgZGF0YSA9IHJlc2lkZW50aWFsX3RyYW5zZmVycywgZmFtaWx5ID0gYmlub21pYWwpDQpgYGANCg0KYGBge3IgdHJhbnNmZXJfdHlwZXMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCnRyYW5zZmVyc19uZXcgPC0gZnJlYWQoIkRhdGEvcmVzaWRlbnRpYWxfdHJhbnNmZXJzX2NsZWFuZWQuY3N2IikgJT4lIA0KICByZW5hbWUoaGFzX3JlY2VudF90cmFuc2ZlciA9IGhhc19yZWNlbnRfdHJhbnNmZXIueCkNCg0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSByZXNpZGVudGlhbF9wcm9wZXJ0aWVzICU+JQ0KICBsZWZ0X2pvaW4oDQogICAgdHJhbnNmZXJzX25ldyAlPiUNCiAgICAgIGRwbHlyOjpzZWxlY3QocGFyY2VsX251bWJlciwgaGFzX3JlY2VudF90cmFuc2ZlciwgbGF0ZXN0X2RvY3VtZW50X3R5cGUpLA0KICAgIGJ5ID0gYygicGFyY2VsX251bWJlciIgPSAicGFyY2VsX251bWJlciIpDQogICklPiUNCiAgbXV0YXRlKGhhc19yZWNlbnRfdHJhbnNmZXIgPSBpZmVsc2UoaXMubmEoaGFzX3JlY2VudF90cmFuc2ZlciksIDAsIGhhc19yZWNlbnRfdHJhbnNmZXIpKSU+JQ0KICBtdXRhdGUobGF0ZXN0X2RvY3VtZW50X3R5cGUgPSBpZmVsc2UoaXMubmEobGF0ZXN0X2RvY3VtZW50X3R5cGUpLCAibm9uZSIsIGxhdGVzdF9kb2N1bWVudF90eXBlKSklPiUNCiAgbXV0YXRlKGxhdGVzdF9kb2N1bWVudF90eXBlX0RFRUQgPSBjYXNlX3doZW4oDQogICAgbGF0ZXN0X2RvY3VtZW50X3R5cGUgPT0gIkRFRUQiIH4gIkRFRUQiLA0KICAgIGxhdGVzdF9kb2N1bWVudF90eXBlID09ICJub25lIiB+ICJub25lIiwNCiAgICBsYXRlc3RfZG9jdW1lbnRfdHlwZSA9PSAiU0FUSVNGQUNUSU9OIE9GIE1PUlRHQUdFIiB+ICJTQVRJU0ZBQ1RJT04gT0YgTU9SVEdBR0UiLA0KICAgIFRSVUUgfiAib3RoZXJzIg0KICApKQ0KDQpnZ3Bsb3QocmVzaWRlbnRpYWxfcHJvcGVydGllcywgYWVzKHggPSBsYXRlc3RfZG9jdW1lbnRfdHlwZV9ERUVELCBmaWxsID0gYXMuZmFjdG9yKGV4ZW1wdGlvbikpKSArICAgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKyANCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JzMikgKw0KICBsYWJzKHggPSAiUHJvcGVydHkgVHJhbnNmZXIgVHlwZXMiLCB5ID0gIkNvdW50IiwNCiAgICAgICB0aXRsZSA9ICJMYXRlc3QgUHJvcGVydHkgVHJhbnNmZXIgVHlwZXMgYnkgSG9tZXN0ZWFkIEV4ZW1wdGlvbiIpICsNCiAgYmFzZV90aGVtZQ0KYGBgDQoNCiMjIyMgUmVjZW50bHkgVHJhbnNmZXIgey51bm51bWJlcmVkfQ0KDQpPbiBhdmVyYWdlLCAyMC4wNyUgb2YgcHJvcGVydGllcyB3aXRob3V0IGEgaG9tZXN0ZWFkIGV4ZW1wdGlvbiBoYWQgYSB0cmFuc2ZlciBpbiB0aGUgcGFzdCB0d28geWVhcnMsIGNvbXBhcmVkIHRvIDE2LjE3JSBvZiB0aG9zZSB3aXRoIGFuIGV4ZW1wdGlvbi4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwcm9wZXJ0aWVzIHdpdGhvdXQgZXhlbXB0aW9ucyB0ZW5kIHRvIGhhdmUgYSBzbGlnaHRseSBoaWdoZXIgbGlrZWxpaG9vZCBvZiByZWNlbnQgdHJhbnNhY3Rpb25zLg0KDQpgYGB7ciBSZWNlbnRfVHJhbnNmZXJfbm9uZSwgZXZhbD1GQUxTRX0NCiMgQ29udmVydCByZWNvcmRpbmdfZGF0ZSB0byBEYXRlIGZvcm1hdA0KcmVzaWRlbnRpYWxfdHJhbnNmZXJzIDwtIHJlc2lkZW50aWFsX3RyYW5zZmVycyAlPiUNCiAgbXV0YXRlKHJlY29yZGluZ19kYXRlID0gYXMuRGF0ZShyZWNvcmRpbmdfZGF0ZSwgZm9ybWF0PSIlWS0lbS0lZCIpKQ0KDQpjdXJyZW50X3llYXIgPC0geWVhcihTeXMuRGF0ZSgpKQ0KDQojIFN0ZXAgMTogRmluZCB0aGUgbW9zdCByZWNlbnQgdHJhbnNmZXIgeWVhciBmb3IgZWFjaCBwcm9wZXJ0eQ0KcmVjZW50X3RyYW5zZmVycyA8LSByZXNpZGVudGlhbF90cmFuc2ZlcnMgJT4lDQogIGZpbHRlcighaXMubmEocmVjb3JkaW5nX2RhdGUpKSAlPiUNCiAgZ3JvdXBfYnkocGFyY2VsX251bWJlcikgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBsYXRlc3RfdHJhbnNmZXJfeWVhciA9IG1heCh5ZWFyKHJlY29yZGluZ19kYXRlKSwgbmEucm0gPSBUUlVFKSwgICMgTW9zdCByZWNlbnQgdHJhbnNmZXIgeWVhcg0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIGxhdGVzdF90cmFuc2Zlcl95ZWFyID0gaWZlbHNlKGlzLmluZmluaXRlKGxhdGVzdF90cmFuc2Zlcl95ZWFyKSwgTkEsIGxhdGVzdF90cmFuc2Zlcl95ZWFyKSAgIyBIYW5kbGUgaW5maW5pdGUgdmFsdWVzDQogICkNCg0KIyBTdGVwIDI6IENyZWF0ZSBhIGJpbmFyeSB2YXJpYWJsZSBmb3IgcmVjZW50IHRyYW5zZmVycyAod2l0aGluIGxhc3QgMiB5ZWFycykNCnJlY2VudF90cmFuc2ZlcnMgPC0gcmVjZW50X3RyYW5zZmVycyAlPiUNCiAgbXV0YXRlKGhhc19yZWNlbnRfdHJhbnNmZXIgPSBpZmVsc2UoIWlzLm5hKGxhdGVzdF90cmFuc2Zlcl95ZWFyKSAmIGxhdGVzdF90cmFuc2Zlcl95ZWFyID49IChjdXJyZW50X3llYXIgLSAyKSwgMSwgMCkpDQoNCiMgU3RlcCAzOiBNZXJnZSB0aGlzIGluZm9ybWF0aW9uIGludG8gYHJlc2lkZW50aWFsX3RyYW5zZmVyc19jbGVhbmVkYA0KcmVzaWRlbnRpYWxfdHJhbnNmZXJzX2NsZWFuZWQgPC0gcmVzaWRlbnRpYWxfdHJhbnNmZXJzX2NsZWFuZWQgJT4lDQogIGxlZnRfam9pbihyZWNlbnRfdHJhbnNmZXJzLCBieSA9ICJwYXJjZWxfbnVtYmVyIikNCmBgYA0KDQpgYGB7ciByZWNlbnRfdHJhbnNmZXIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCiNSZWNlbnQoMnkpIFRyYW5zZmVyIEFuYWx5c2lzDQpnZ3Bsb3QocmVzaWRlbnRpYWxfcHJvcGVydGllcywgYWVzKHggPSBmYWN0b3IoaGFzX3JlY2VudF90cmFuc2ZlciksIGZpbGwgPSBmYWN0b3IoZXhlbXB0aW9uKSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArICANCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiMCIgPSAiI2U0MjUyNCIsICIxIiA9ICIjMDBBREE5IiksICANCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMCIgPSAiTm8gRXhlbXB0aW9uIiwgIjEiID0gIldpdGggRXhlbXB0aW9uIikpICsgIA0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiMCIgPSAiI2U0MjUyNCIsICIxIiA9ICIjMDBBREE5IikpICsgIA0KICBsYWJzKHRpdGxlID0gIlJlY2VudCBUcmFuc2ZlciBNZXRyaWNzIGJ5IEhvbWVzdGVhZCBFeGVtcHRpb24gU3RhdHVzIiwNCiAgICAgICB4ID0gIlJlY2VudCgyeSkgVHJhbnNmZXIiLA0KICAgICAgIHkgPSAiQ291bnQiLA0KICAgICAgIGZpbGwgPSAiRXhlbXB0aW9uIFN0YXR1cyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSANCmBgYA0KDQojIyMgTmVpZ2hib3Job29kIERlbW9ncmFwaGljIENoYXJhY3RlcmlzdGljcyB7LnRhYnNldH0NCg0KVG8gY29udGV4dHVhbGl6ZSBpbmRpdmlkdWFsIHByb3BlcnR5IHBhdHRlcm5zIHdpdGhpbiBicm9hZGVyIG5laWdoYm9yaG9vZCB0cmVuZHMsIHdlIGFsc28gaW5jb3Jwb3JhdGUgZGVtb2dyYXBoaWMgYW5kIGZpbmFuY2lhbCBpbmRpY2F0b3JzIGF0IHRoZSBjZW5zdXMgdHJhY3QgbGV2ZWwuIEFsdGhvdWdoIG5vdCBmb3JtYWxseSBwYXJ0IG9mIHRoZSBIb21lc3RlYWQgRXhlbXB0aW9uIGVsaWdpYmlsaXR5IGNyaXRlcmlhLCB0aGVzZSBjaGFyYWN0ZXJpc3RpY3MgbWF5IGluZmx1ZW5jZSBhd2FyZW5lc3MsIGFwcGxpY2F0aW9uIGJlaGF2aW9yLCBhbmQgb3V0cmVhY2ggZWZmZWN0aXZlbmVzcy4NCg0KV2UgZHJhdyBvbiBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5IChBQ1MpIDUteWVhciBlc3RpbWF0ZXMgdG8gaW5jbHVkZSBtZWRpYW4gaG9tZSB2YWx1ZSBhbmQgb3duZXItb2NjdXBhbmN5IHJhdGUuIE1lZGlhbiBob21lIHZhbHVlIGNhcHR1cmVzIHRoZSByZWxhdGl2ZSB3ZWFsdGggb2YgYSBuZWlnaGJvcmhvb2QgYW5kIG1heSBjb3JyZWxhdGUgd2l0aCBhIGhvbWVvd25lcuKAmXMgcGVyY2VpdmVkIG5lZWQgZm9yIG9yIGludGVyZXN0IGluIHRoZSBleGVtcHRpb24uIE93bmVyIG9jY3VwYW5jeSBwcm92aWRlcyBhIHByb3h5IGZvciByZXNpZGVudGlhbCBzdGFiaWxpdHkgYW5kIGludmVzdG1lbnQgaW4gcGxhY2XigJRhcmVhcyB3aXRoIGhpZ2hlciByYXRlcyBtYXkgYmUgbW9yZSBsaWtlbHkgdG8gaGF2ZSBlbGlnaWJsZSBhbmQgZW5nYWdlZCBob21lb3duZXJzLg0KDQpab25pbmcgY29tcG9zaXRpb24gaXMgdXNlZCB0byBhcHByb3hpbWF0ZSB0aGUgbGFuZCB1c2UgY29udGV4dCBvZiBlYWNoIHRyYWN0LiBBIGhpZ2hlciBwcm9wb3J0aW9uIG9mIHJlc2lkZW50aWFsIHpvbmluZyBzdWdnZXN0cyBtb3JlIGVsaWdpYmxlIHByb3BlcnRpZXMsIHdoaWxlIG1peGVkLXVzZSBvciBjb21tZXJjaWFsbHkgZG9taW5hdGVkIGFyZWFzIG1heSBjb250YWluIGZld2VyIG93bmVyLW9jY3VwaWVkIGhvbWVzLg0KDQpXZSBhbHNvIGluY2x1ZGUgdGF4IGJhbGFuY2UgZGF0YSB0byBjYXB0dXJlIGZpbmFuY2lhbCBzdHJlc3MgYXQgdGhlIG5laWdoYm9yaG9vZCBsZXZlbC4gVGhpcyB3YXMgdXNpbmcgdGhlIFJlYWwgRXN0YXRlIFRheCBCYWxhbmNlcyBkYXRhc2V0IGZyb20gT3BlbkRhdGFQaGlsbHksIGNvbWJpbmluZyBpdCB3aXRoIHRoZSBwcm9wZXJ0eSBkYXRhc2V0IHVzaW5nIHppcCBjb2RlLiBTcGVjaWZpY2FsbHksIHdlIGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBvZiBwcm9wZXJ0aWVzIHdpdGhpbiBlYWNoIHRyYWN0IHRoYXQgaGF2ZSBvdXRzdGFuZGluZyB0YXggYmFsYW5jZXMsIGluY2x1ZGluZyBwcmluY2lwYWwsIHBlbmFsdGllcywgYW5kIGludGVyZXN0LiBXaGlsZSB0aGlzIGlzIG5vdCBhIHN0YXRlZCBjcml0ZXJpb24gZm9yIHRoZSBIb21lc3RlYWQgRXhlbXB0aW9uLCBoaWdoIGxldmVscyBvZiB0YXggZGVsaW5xdWVuY3kgbWF5IHJlZmxlY3QgYnJvYWRlciBzb2Npb2Vjb25vbWljIGNoYWxsZW5nZXPigJRzdWNoIGFzIGxvd2VyIGluY29tZSwgbGltaXRlZCBFbmdsaXNoIHByb2ZpY2llbmN5LCBvciBsb3cgaW5zdGl0dXRpb25hbCB0cnVzdOKAlHRoYXQgaW5mbHVlbmNlIGV4ZW1wdGlvbiBwYXJ0aWNpcGF0aW9uLg0KDQojIyMjIE1lZGlhbiBIb21lIFZhbHVlIHsudW5udW1iZXJlZH0NCg0KUHJvcGVydGllcyB3aXRoIHRoZSBIb21lc3RlYWQgRXhlbXB0aW9uIGFyZSB0eXBpY2FsbHkgbG9jYXRlZCBpbiBjZW5zdXMgdHJhY3RzIHdoZXJlIHRoZSBtZWRpYW4gaG9tZSB2YWx1ZSByYW5nZXMgYmV0d2VlbiAkMjAwLDAwMCBhbmQgJDQwMCwwMDAsIHdoaWNoIGlzIGdlbmVyYWxseSBoaWdoZXIgdGhhbiBpbiB0cmFjdHMgd2l0aG91dCBleGVtcHRpb25zLiBIb3dldmVyLCBjZW5zdXMgdHJhY3RzIHdpdGggbWVkaWFuIGhvbWUgdmFsdWVzIGV4Y2VlZGluZyAkNDAwLDAwMCB0ZW5kIHRvIGhhdmUgZmV3ZXIgcHJvcGVydGllcyB3aXRoIGV4ZW1wdGlvbnMsIHN1Z2dlc3RpbmcgdGhhdCB3ZWFsdGhpZXIgbmVpZ2hib3Job29kcyBtYXkgaGF2ZSBsb3dlciBwYXJ0aWNpcGF0aW9uIGluIHRoZSBwcm9ncmFtLg0KDQpgYGB7ciBtZWRpYW5faG9tZV92YWx1ZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KI2pvaW4gdG8gZGF0YXNldA0KIyBFeHRyYWN0IGNvbHVtbiBuYW1lcyBmb3IgaW5kZXggODEgdG8gMTEyDQpzZWxlY3RlZF9jb2x1bW5zIDwtIG5hbWVzKHByb3BlcnRpZXNfdHJhY3QpW2MoMSwgODE6MTEzKV0NCiMgUGVyZm9ybSB0aGUgbGVmdCBqb2luDQpyZXNpZGVudGlhbF9wcm9wZXJ0aWVzIDwtIHJlc2lkZW50aWFsX3Byb3BlcnRpZXMgJT4lDQogIGxlZnRfam9pbigNCiAgICBwcm9wZXJ0aWVzX3RyYWN0ICU+JSBkcGx5cjo6c2VsZWN0KGFsbF9vZihzZWxlY3RlZF9jb2x1bW5zKSksDQogICAgYnkgPSBjKCJvYmplY3RpZCIgPSAib2JqZWN0aWQiKQ0KICApDQoNCmdncGxvdChyZXNpZGVudGlhbF9wcm9wZXJ0aWVzLCANCiAgICAgICBhZXMoeCA9IG1lZGlhbl9ob21lX3ZhbHVlLCBjb2xvciA9IGFzLmZhY3RvcihleGVtcHRpb24pKSkgKw0KICBnZW9tX2RlbnNpdHkoc2l6ZSA9IDAuNykgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzMikgKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbiBIb21lIFZhbHVlIHBlciBDZW5zdXMgVHJhY3QiLA0KICAgICAgIHggPSAiTWVkaWFuIEhvbWUgVmFsdWUiLA0KICAgICAgIHkgPSAiRGVuc2l0eSIsDQogICAgICAgY29sb3IgPSAiRXhlbXB0aW9uIikgKw0KICBiYXNlX3RoZW1lDQpgYGANCg0KIyMjIyBPd25lciBPY2N1cGFuY3kgey51bm51bWJlcmVkfQ0KDQpOb3RhYmx5LCBoaWdoZXIgcmF0ZXMgb2Ygb3duZXIgb2NjdXBhbmN5IGRvbid0IGF1dG9tYXRpY2FsbHkgdHJhbnNsYXRlIHRvIGhpZ2hlciBwcm9ncmFtIHBhcnRpY2lwYXRpb24uIFRoaXMgc3VnZ2VzdHMgdGhhdCBvdGhlciBmYWN0b3JzIGJleW9uZCBob21lIG93bmVyc2hpcCAtIHN1Y2ggYXMgYXdhcmVuZXNzIG9mIHRoZSBwcm9ncmFtLCBlYXNlIG9mIGVucm9sbG1lbnQsIG9yIGRlbW9ncmFwaGljIGNoYXJhY3RlcmlzdGljcyAtIG1heSBwbGF5IG1vcmUgc2lnbmlmaWNhbnQgcm9sZXMgaW4gZGV0ZXJtaW5pbmcgcGFydGljaXBhdGlvbiByYXRlcy4gVGhlc2UgaW5zaWdodHMgY2FuIGhlbHAgZ3VpZGUgdGFyZ2V0ZWQgb3V0cmVhY2ggZWZmb3J0cyB0byBpbmNyZWFzZSBwcm9ncmFtIGVucm9sbG1lbnQgYW1vbmcgZWxpZ2libGUgaG9tZW93bmVycyB3aG8gYXJlIGN1cnJlbnRseSBtaXNzaW5nIG91dCBvbiB0aGlzIHRheCBiZW5lZml0Lg0KDQpgYGB7ciBvd25lcl9vY2N1cGFuY3ksIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmdncGxvdChyZXNpZGVudGlhbF9wcm9wZXJ0aWVzLCANCiAgICAgICBhZXMoeCA9IG93bmVyX29jY19yYXRlLCBjb2xvciA9IGFzLmZhY3RvcihleGVtcHRpb24pKSkgKw0KICBnZW9tX2RlbnNpdHkoc2l6ZSA9IDAuNykgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzMikgKw0KICBsYWJzKHRpdGxlID0gIk93bmVyIE9jY3VwYW5jeSBSYXRlIHBlciBDZW5zdXMgVHJhY3QiLA0KICAgICAgIHggPSAiT3duZXIgT2NjdXBhbmN5IFJhdGUiLA0KICAgICAgIHkgPSAiRGVuc2l0eSIsDQogICAgICAgY29sb3IgPSAiRXhlbXB0aW9uIikgKw0KICBiYXNlX3RoZW1lDQpgYGANCg0KIyMjIyBab25pbmcgQW5hbHlzaXMgIHsudW5udW1iZXJlZH0NCg0KQ2Vuc3VzIHRyYWN0cyB3aXRoIHNpbmdsZS1mYW1pbHkgem9uaW5nLCBib3RoIGRldGFjaGVkIGFuZCBhdHRhY2hlZCwgaGF2ZSB0aGUgaGlnaGVzdCBwZXJjZW50YWdlIG9mIHByb3BlcnRpZXMgd2l0aCB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbi4gSW4gY29udHJhc3QsIG11bHRpLWZhbWlseSBvciBtaXhlZC11c2UgcmVzaWRlbnRpYWwgem9uZXMgdGVuZCB0byBoYXZlIGZld2VyIHByb3BlcnRpZXMgZW5yb2xsZWQgaW4gdGhlIGV4ZW1wdGlvbiBwcm9ncmFtLg0KDQpgYGB7ciB6b25pbmcsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCiMgRGF0YSBmcmFtZSBvZiB6b25pbmcgdHlwZXMNCnpvbmluZ190eXBlcyA8LSBkYXRhLmZyYW1lKA0KICBUeXBlID0gYygNCiAgICAiU2luZ2xlIEZhbWlseSBEZXRhY2hlZCIsDQogICAgIlNpbmdsZSBGYW1pbHkgQXR0YWNoZWQiLA0KICAgICJUd28tRmFtaWx5IEF0dGFjaGVkIiwNCiAgICAiTXVsdGktRmFtaWx5IiwNCiAgICAiUmVzaWRlbnRpYWwgTWl4ZWQtVXNlIiwNCiAgICAiQ29tbWVyY2lhbCBNaXhlZC1Vc2UiLA0KICAgICJJbmR1c3RyaWFsIFJlc2lkZW50aWFsIE1peGVkLVVzZSINCiAgKSwNCiAgQ29kZXMgPSBjKA0KICAgICJSU0QxLCBSU0QyLCBSU0QzIiwNCiAgICAiUlNBMSwgUlNBMiwgUlNBMywgUlNBNCwgUlNBNSwgUlNBNiIsDQogICAgIlJUQTEiLA0KICAgICJSTTEsIFJNMiwgUk0zLCBSTTQiLA0KICAgICJSTVgxLCBSTVgyLCBSTVgzIiwNCiAgICAiQ01YMSwgQ01YMiwgQ01YMi41LCBDTVgzLCBDTVg0LCBDTVg1IiwNCiAgICAiSVJNWCINCiAgKSwNCiAgRGVzY3JpcHRpb24gPSBjKA0KICAgICJEZXRhY2hlZCBob3VzZXMgb24gaW5kaXZpZHVhbCBsb3RzIiwNCiAgICAiQXR0YWNoZWQgYW5kIHNlbWktZGV0YWNoZWQgaG91c2VzIG9uIGluZGl2aWR1YWwgbG90cyIsDQogICAgIlR3by1mYW1pbHksIHNlbWktZGV0YWNoZWQgaG91c2VzIG9uIGluZGl2aWR1YWwgbG90cyIsDQogICAgIk1vZGVyYXRlIHRvIGhpZ2gtZGVuc2l0eSBtdWx0aS11bml0IHJlc2lkZW50aWFsIGJ1aWxkaW5ncyIsDQogICAgIlJlc2lkZW50aWFsIGFuZCBtaXhlZC11c2UgZGV2ZWxvcG1lbnQsIGluY2x1ZGluZyBtYXN0ZXIgcGxhbiBkZXZlbG9wbWVudCIsDQogICAgIk5laWdoYm9yaG9vZCB0byByZWdpb25hbC1zZXJ2aW5nIG1peGVkLXVzZSBkZXZlbG9wbWVudCIsDQogICAgIk1peCBvZiBsb3ctaW1wYWN0IGluZHVzdHJpYWwsIGFydGlzYW4gaW5kdXN0cmlhbCwgcmVzaWRlbnRpYWwsIGFuZCBuZWlnaGJvcmhvb2QgY29tbWVyY2lhbCB1c2VzIg0KICApDQopDQoNCnByb3BlcnRpZXNfZmlsdGVyZWQgPC0gZmlsdGVyZWRfcHJvcGVydGllcyAlPiUNCiAgZHBseXI6OnNlbGVjdCgNCiAgICB6b25pbmcsDQogICAgaG9tZXN0ZWFkX2V4ZW1wdGlvbiwNCiAgICBpc19yZXNpZGVudGlhbCwNCiAgICBjZW5zdXNfdHJhY3QsDQogICAgc2hhcGUNCiAgKQ0KDQojIEZpcnN0IGNyZWF0ZSBhIHpvbmluZyB0eXBlIGNsYXNzaWZpY2F0aW9uDQpmaWx0ZXJlZF9wcm9wZXJ0aWVzIDwtIGZpbHRlcmVkX3Byb3BlcnRpZXMgJT4lIA0KICBtdXRhdGUoDQogICAgem9uaW5nX3R5cGUgPSBjYXNlX3doZW4oDQogICAgICB6b25pbmcgJWluJSBjKCJSU0QxIiwgIlJTRDIiLCAiUlNEMyIpIH4gIlNpbmdsZSBGYW1pbHkgRGV0YWNoZWQiLA0KICAgICAgem9uaW5nICVpbiUgYygiUlNBMSIsICJSU0EyIiwgIlJTQTMiLCAiUlNBNCIsICJSU0E1IiwgIlJTQTYiKSB+ICJTaW5nbGUgRmFtaWx5IEF0dGFjaGVkIiwNCiAgICAgIHpvbmluZyAlaW4lIGMoIlJUQTEiKSB+ICJUd28tRmFtaWx5IEF0dGFjaGVkIiwNCiAgICAgIHpvbmluZyAlaW4lIGMoIlJNMSIsICJSTTIiLCAiUk0zIiwgIlJNNCIpIH4gIk11bHRpLUZhbWlseSIsDQogICAgICB6b25pbmcgJWluJSBjKCJSTVgxIiwgIlJNWDIiLCAiUk1YMyIpIH4gIlJlc2lkZW50aWFsIE1peGVkLVVzZSIsDQogICAgICB6b25pbmcgJWluJSBjKCJDTVgxIiwgIkNNWDIiLCAiQ01YMi41IiwgIkNNWDMiLCAiQ01YNCIsICJDTVg1IikgfiAiQ29tbWVyY2lhbCBNaXhlZC1Vc2UiLA0KICAgICAgem9uaW5nICVpbiUgYygiSVJNWCIpIH4gIkluZHVzdHJpYWwgUmVzaWRlbnRpYWwgTWl4ZWQtVXNlIiwNCiAgICAgIFRSVUUgfiAiT3RoZXIiDQogICAgKSwNCiAgICBpc19yZXNpZGVudGlhbCA9IGlmZWxzZSh6b25pbmdfdHlwZSAhPSAiT3RoZXIiLCAxLCAwKQ0KICApDQoNCg0Kem9uaW5nX3N1bW1hcnkgPC0gZmlsdGVyZWRfcHJvcGVydGllcyAlPiUNCiAgZmlsdGVyKGlzX3Jlc2lkZW50aWFsID09IDEpICU+JQ0KICBncm91cF9ieSh6b25pbmdfdHlwZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICB0b3RhbF9wcm9wZXJ0aWVzID0gbigpLA0KICAgIGhvbWVzdGVhZF9jb3VudCA9IHN1bShob21lc3RlYWRfZXhlbXB0aW9uID4gMCwgbmEucm0gPSBUUlVFKSwNCiAgICBwY3RfaG9tZXN0ZWFkID0gKGhvbWVzdGVhZF9jb3VudCAvIHRvdGFsX3Byb3BlcnRpZXMpICogMTAwDQogICkgJT4lDQogIGFycmFuZ2UoZGVzYyhwY3RfaG9tZXN0ZWFkKSkNCg0KIyBIb21lc3RlYWQgcmF0ZXMgYnkgem9uaW5nIHR5cGUNCmdncGxvdCh6b25pbmdfc3VtbWFyeSwgDQogICAgICAgYWVzKHggPSByZW9yZGVyKHpvbmluZ190eXBlLCAtcGN0X2hvbWVzdGVhZCksIA0KICAgICAgICAgICB5ID0gcGN0X2hvbWVzdGVhZCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIA0KICAgICAgICAgICBmaWxsID0gIiMwMEFEQTkiLA0KICAgICAgICAgICBhbHBoYSA9IDAuOCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkhvbWVzdGVhZCBFeGVtcHRpb24gUmF0ZXMgYnkgWm9uaW5nIENhdGVnb3J5IGluIFBoaWxhZGVscGhpYSIsDQogICAgc3VidGl0bGUgPSAiUmVzaWRlbnRpYWwgYW5kIE1peGVkLVVzZSBEaXN0cmljdHMgT25seSIsDQogICAgeCA9ICJab25pbmcgQ2F0ZWdvcnkiLA0KICAgIHkgPSAiUGVyY2VudGFnZSB3aXRoIEhvbWVzdGVhZCBFeGVtcHRpb24iLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBQaGlsYWRlbHBoaWEgUHJvcGVydHkgRGF0YSwgMjAyNSINCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBsaW1pdHMgPSBjKDAsIG1heCh6b25pbmdfc3VtbWFyeSRwY3RfaG9tZXN0ZWFkKSAqIDEuMSksDQogICAgbGFiZWxzID0gZnVuY3Rpb24oeCkgcGFzdGUwKHgsICIlIikNCiAgKSArDQogIGJhc2VfdGhlbWUgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCiMjIyMgVGF4IEJhbGFuY2UgUmF0ZSB7LnVubnVtYmVyZWR9DQoNClByb3BlcnRpZXMgd2l0aCB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbiBhcmUgbW9yZSBsaWtlbHkgdG8gYmUgbG9jYXRlZCBpbiBjZW5zdXMgdHJhY3RzIHdoZXJlIGZld2VyIHByb3BlcnRpZXMgaGF2ZSBvdXRzdGFuZGluZyB0YXggYmFsYW5jZXMsIHBhcnRpY3VsYXJseSBpbiB0cmFjdHMgd2hlcmUgdGhlIHRheCBiYWxhbmNlIHJhdGUgaXMgbGVzcyB0aGFuIDEwJS4NCg0KYGBge3IgdGF4X2JhbGFuY2UsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmJhbGFuY2VzIDwtIHJlYWQuY3N2KCJEYXRhL3JlYWxfZXN0YXRlX3RheF9iYWxhbmNlc19jZW5zdXNfdHJhY3QuY3N2IikNCg0KYmFsYW5jZV9zZiA8LSBjZW5zdXNfdHJhY3RzX2VucmljaGVkICU+JSANCiAgbGVmdF9qb2luKGJhbGFuY2VzICU+JSBkcGx5cjo6c2VsZWN0KGNlbnN1c190cmFjdCxiYWxhbmNlLG51bV9wcm9wcyksIA0KICAgICAgICAgICAgYnkgPSBjKCJHRU9JRCIgPSAiY2Vuc3VzX3RyYWN0IikpICU+JQ0KICBtdXRhdGUoDQogICAgbnVtX3Byb3BzID0gaWZlbHNlKGlzLm5hKHRvdGFsX3Byb3BlcnRpZXMpLCBOQSwgbnVtX3Byb3BzKSwNCiAgICBiYWxhbmNlID0gaWZlbHNlKGlzLm5hKHRvdGFsX3Byb3BlcnRpZXMpLCBOQSwgYmFsYW5jZSkNCiAgKQ0KDQojZGlzdGluY3QNCmJhbGFuY2VfZGlzdGluY3QgPC0gYmFsYW5jZXMgJT4lDQogIG11dGF0ZShjZW5zdXMgPSBhcy5udW1lcmljKHN1YnN0cihjZW5zdXNfdHJhY3QsIDYsIDkpKSklPiUNCiAgc3RfZHJvcF9nZW9tZXRyeSgpJT4lDQogIGdyb3VwX2J5KGNlbnN1cykgJT4lIA0KICBzdW1tYXJpc2UodGF4X3Byb3BzPXN1bShudW1fcHJvcHMsbmEucm09VFJVRSkpICU+JQ0KICB1bmdyb3VwKCkNCg0KcHJvcGVydGllc19udW1iZXI8LXByb3BlcnRpZXNfc2YlPiUNCiAgZHBseXI6OnNlbGVjdChjZW5zdXNfdHJhY3QsZXhlbXB0aW9uLHBhcmNlbF9udW1iZXIpJT4lDQogIG11dGF0ZShwcm9wPTEpJT4lDQogIHN0X2Ryb3BfZ2VvbWV0cnkoKSU+JQ0KICBncm91cF9ieShjZW5zdXNfdHJhY3QpJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9wcm9wcz1zdW0ocHJvcCkpJT4lDQogIHVuZ3JvdXAoKQ0KDQpwcm9wZXJ0aWVzX3NmX251bWJlcjwtcHJvcGVydGllc19zZiU+JQ0KICBsZWZ0X2pvaW4ocHJvcGVydGllc19udW1iZXIsYnk9ImNlbnN1c190cmFjdCIpDQoNCnByb3BlcnRpZXNfYmFsYW5jZSA8LSBwcm9wZXJ0aWVzX3NmX251bWJlciAlPiUNCiAgZHBseXI6OnNlbGVjdChvYmplY3RpZCwgY2Vuc3VzX3RyYWN0LGV4ZW1wdGlvbixwYXJjZWxfbnVtYmVyLHRvdGFsX3Byb3BzKSU+JQ0KICBsZWZ0X2pvaW4oYmFsYW5jZV9kaXN0aW5jdCwgYnkgPSBjKCJjZW5zdXNfdHJhY3QiID0gImNlbnN1cyIpKSU+JQ0KICBtdXRhdGUodGF4X3Byb3BzPXJlcGxhY2UodGF4X3Byb3BzLGlzLm5hKHRheF9wcm9wcyksMCkpJT4lDQogIG11dGF0ZShiYWxhbmNlX3JhdGU9dGF4X3Byb3BzL3RvdGFsX3Byb3BzKSU+JQ0KICBmaWx0ZXIoIWlzLm5hKGNlbnN1c190cmFjdCkpIA0KDQojam9pbiB0byBkYXRhc2V0DQpyZXNpZGVudGlhbF9wcm9wZXJ0aWVzIDwtIHJlc2lkZW50aWFsX3Byb3BlcnRpZXMgJT4lDQogIGxlZnRfam9pbihwcm9wZXJ0aWVzX2JhbGFuY2UlPiUNCiAgICAgICAgICAgICAgc3RfZHJvcF9nZW9tZXRyeSgpJT4lDQogICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3Qob2JqZWN0aWQsYmFsYW5jZV9yYXRlKSwgDQogICAgICAgICAgICBieSA9IGMoIm9iamVjdGlkIiA9ICJvYmplY3RpZCIpKQ0KDQpnZ3Bsb3QocmVzaWRlbnRpYWxfcHJvcGVydGllcywgDQogICAgICAgYWVzKHggPSBiYWxhbmNlX3JhdGUsIGNvbG9yID0gYXMuZmFjdG9yKGV4ZW1wdGlvbikpKSArDQogIGdlb21fZGVuc2l0eShzaXplID0gMC43KSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnMyKSArDQogIGxhYnModGl0bGUgPSAiUGVydGVudGFnZSBvZiBQcm9wZXJ0aWVzIEluIFRheCBCYWxhbmNlIHBlciBDZW5zdXMgVHJhY3QiLA0KICAgICAgIHggPSAiQmFsYW5jZSBSYXRlIiwNCiAgICAgICB5ID0gIkRlbnNpdHkiLA0KICAgICAgIGNvbG9yID0gIkV4ZW1wdGlvbiIpICsNCiAgYmFzZV90aGVtZQ0KYGBgDQoNCmBgYHtyIHNlbGVjdF92YXJpYWJsZSxldmFsPUZBTFNFfQ0KcHJvcGVydGllc19tb2RlbCA8LSByZXNpZGVudGlhbF9wcm9wZXJ0aWVzICU+JSANCiAgZHBseXI6OnNlbGVjdChvYmplY3RpZCwgY2Vuc3VzX3RyYWN0LCBnZW9ncmFwaGljX3dhcmQsIG5laWdoYm9yaG9vZCwgemlwX2NvZGUsIA0KICAgICAgICAgICAgICAgIHhfMjI3MiwgeV8yMjcyLCBsb25fNDMyNiwgbGF0XzQzMjYsIGV4ZW1wdGlvbiwgc2FtZV9hZGRyZXNzLA0KICAgICAgICAgICAgICAgIGlzX2RlZXAsIGxhcmdlX2FyZWEsb3duZXJfY291bnQsIHJlbnRhbF9saWNlbnNlLCBjb21tZXJjaWFsX2xpY2Vuc2UsIA0KICAgICAgICAgICAgICAgIGJhbGFuY2VfcmF0ZSwgYXZnX21hcmtldF92YWx1ZSwgc2RfbWFya2V0X3ZhbHVlLA0KICAgICAgICAgICAgICAgIGhhc19yZWNlbnRfdHJhbnNmZXIsIGxhdGVzdF9kb2N1bWVudF90eXBlLGxhdGVzdF9kb2N1bWVudF90eXBlX0RFRUQsDQogICAgICAgICAgICAgICAgcGN0X2ZvcmVpZ25fYm9ybiwgb3ZlcmFsbF92YWNhbmN5X3JhdGUsIHBvdmVydHlfcmF0ZSwgYmFjaF9kZWdyZWVfcmF0ZSwNCiAgICAgICAgICAgICAgICB5b3VuZ19vd25lcl9yYXRlLHNlbmlvcl9vd25lcl9yYXRlLGZhbWlseV9oaF9yYXRlLCBsaW1pdGVkX2VuZ2xpc2hfcmF0ZSwNCiAgICAgICAgICAgICAgICBkaXZlcnNpdHlfaW5kZXgsIG1lZGlhbl9pbmNvbWUsIG93bmVyX29jY19yYXRlLA0KICAgICAgICAgICAgICAgIGNvc3RfYnVyZGVuX3JhdGUsbW9ydGdhZ2VfYnVyZGVuX3JhdGUsbWVkaWFuX2hvbWVfdmFsdWUpDQpgYGANCg0KIyBNb2RlbGluZw0KDQpXZSB1c2UgdGhlIGlkZW50aWZpZWQgcHJvcGVydHkgYW5kIG5laWdoYm9yaG9vZCBjaGFyYWN0ZXJpc3RpY3MgYXMgcHJlZGljdG9yIHZhcmlhYmxlcyB0byBtb2RlbCB0aGUgbGlrZWxpaG9vZCB0aGF0IGEgcHJvcGVydHkgcmVjZWl2ZXMgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24uIFRoZSBnb2FsIGlzIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBrZXkgZmFjdG9ycyBhc3NvY2lhdGVkIHdpdGggZXhlbXB0aW9uIHN0YXR1cyBhbmQgdG8gaWRlbnRpZnkgcG90ZW50aWFsbHkgZWxpZ2libGUgcHJvcGVydGllcyB0aGF0IGFyZSBub3QgY3VycmVudGx5IGVucm9sbGVkLg0KDQpXZSB0ZXN0IHNldmVyYWwgY2xhc3NpZmljYXRpb24gbW9kZWxzLCBpbmNsdWRpbmcgSy1OZWFyZXN0IE5laWdoYm9ycyAoS05OKSBhbmQgUmFuZG9tIEZvcmVzdCwgYW5kIGl0ZXJhdGl2ZWx5IHJlZmluZSBvdXIgZmVhdHVyZSBzZXQuIFNwYXRpYWwgaW5kaWNhdG9ycyBzdWNoIGFzIGxvbmdpdHVkZSwgbGF0aXR1ZGUsIGFuZCBzcGF0aWFsIGxhZyB0ZXJtcyBhcmUgaW5jb3Jwb3JhdGVkIHRvIGNhcHR1cmUgZ2VvZ3JhcGhpYyBwYXR0ZXJucyBpbiBleGVtcHRpb24gcGFydGljaXBhdGlvbi4gT3VyIGJlc3QtcGVyZm9ybWluZyBtb2RlbCBpcyBiYXNlZCBvbiBYR0Jvb3N0LCB3aGljaCBwcm92aWRlcyB0aGUgaGlnaGVzdCBwcmVkaWN0aXZlIGFjY3VyYWN5Lg0KDQohW10ocm1kX3BuZy9tZXRob2QucG5nKQ0KDQojIyBDb3JyZWxhdGlvbiBNYXRyaXgNCg0KV2UgYmVnaW4gYnkgc2VsZWN0aW5nIGFuZCBsb2FkaW5nIHRoZSByZWxldmFudCBkYXRhLCB0aGVuIGdlbmVyYXRlIGEgY29ycmVsYXRpb24gbWF0cml4IHRvIGdhaW4gYW4gaW5pdGlhbCB1bmRlcnN0YW5kaW5nIG9mIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzLg0KDQpgYGB7ciByZWFkX2RhdGEgLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQpwcm9wZXJ0aWVzX21vZGVsIDwtIGZyZWFkKCJEYXRhL3hnYl9mdWxsX3ByZWRfMDUwNS5jc3YiKQ0KdmFyaWFibGVzNSA8LSBjKCJzYW1lX2FkZHJlc3MiLCJyZW50YWxfbGljZW5zZSIsDQogICAgICAgICAgICAgICAgImF2Z19tYXJrZXRfdmFsdWUiLCJzZF9tYXJrZXRfdmFsdWUiLCJsYWdfZXhlbXB0aW9uIiwiYmFsYW5jZV9yYXRlIiwic2VuaW9yX293bmVyX3JhdGUiLCJsYXRlc3RfZG9jdW1lbnRfdHlwZV9ERUVEIiwibWVkaWFuX2hvbWVfdmFsdWUiLCAibG9uXzQzMjYiLCJvd25lcl9vY2NfcmF0ZSIsImhhc19yZWNlbnRfdHJhbnNmZXIiLCJnZW9ncmFwaGljX3dhcmQiLCAicG92ZXJ0eV9yYXRlIiwibGF0XzQzMjYiKQ0KYGBgDQoNCmBgYHtyIENvcnJlbGF0aW9uIE1hdHJpeCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KbnVtZXJpY1ZhcnMgPC0gYXMuZGF0YS5mcmFtZShwcm9wZXJ0aWVzX21vZGVsKSAlPiUNCiAgZHBseXI6OnNlbGVjdCh2YXJpYWJsZXM1KSAlPiUgIA0KICBzZWxlY3RfaWYoaXMubnVtZXJpYykgJT4lIA0KICBuYS5vbWl0KCkgDQoNCmNvcnJlbGF0aW9uX21hdHJpeCA8LSBjb3IobnVtZXJpY1ZhcnMpDQoNCm51bWVyaWNWYXJzICU+JSANCiAgY29ycmVsYXRlKCkgJT4lIA0KICBhdXRvcGxvdCgpICsNCiAgZ2VvbV90aWxlKGFlcyhmaWxsID0gciksIGNvbG9yID0gIiNlOWU5ZTkiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChyLGRpZ2l0cz0yKSksIHNpemUgPSAzKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICAiIzAwQURBOSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAgIiNlNDI1MjQiLA0KICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IDAsIGxpbWl0cyA9IGMoLTEsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoLTEsIDEsIGJ5ID0gMC4yKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvcnJlbGF0aW9uIGFjcm9zcyBudW1lcmljIHZhcmlhYmxlcyIpICAjIFNldCBwbG90IHRpdGxlDQpgYGANCg0KIyMgU3BsaXQgRGF0YXNldA0KDQpOZXh0LCB3ZSBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHR3byBwYXJ0czogNzUlIGZvciB0cmFpbmluZyBhbmQgMjUlIGZvciB0ZXN0aW5nLiBUaGUgdHJhaW5pbmcgc2V0IGlzIHVzZWQgdG8gYnVpbGQgbW9kZWxzIHVzaW5nIHZhcmlvdXMgbWV0aG9kcywgd2hpbGUgdGhlIHRlc3Rpbmcgc2V0IGlzIHVzZWQgdG8gZXZhbHVhdGUgbW9kZWwgcGVyZm9ybWFuY2UgYW5kIGlkZW50aWZ5IHRoZSBtb3N0IGFjY3VyYXRlIG9uZS4NCg0KIVtdKHJtZF9wbmcvbW9kZWwucG5nKQ0KDQpgYGB7ciBzcGxpdGUsIGV2YWw9RkFMU0V9DQpwcm9wZXJ0aWVzX21vZGVsPC0gcHJvcGVydGllc19tb2RlbCU+JQ0KICBtdXRhdGUocHJvcGVydHlfSUQgPSBzZXEoMTpuKCkpKSU+JQ0KICBkcGx5cjo6c2VsZWN0KGFsbF9vZih2YXJpYWJsZXM0KSwgZXhlbXB0aW9uLCB6aXBfY29kZSklPiUNCiAgc3RfZHJvcF9nZW9tZXRyeSgpDQoNCmRhdGFfc3BsaXQgPC0gaW5pdGlhbF9zcGxpdChwcm9wZXJ0aWVzX21vZGVsLCBzdHJhdGEgPSAiemlwX2NvZGUiLCBwcm9wID0gMC43NSkNCnByb3BlcnRpZXNfdHJhaW4gPC0gdHJhaW5pbmcoZGF0YV9zcGxpdCkNCnByb3BlcnRpZXNfdGVzdCAgPC0gdGVzdGluZyhkYXRhX3NwbGl0KQ0KYGBgDQoNCiMjIEFkZCBTcGF0aWFsIExhZyBGb3IgVHJhaW5pbmcNCg0KVG8gcHJldmVudCBkYXRhIGxlYWthZ2UsIHNwYXRpYWwgbGFnIHZhcmlhYmxlcyBuZWVkIHRvIGJlIGNhbGN1bGF0ZWQgc2VwYXJhdGVseSBmb3IgdGhlIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzLiBJZiBzcGF0aWFsIGluZm9ybWF0aW9uIGZyb20gdGhlIHRlc3Qgc2V0IGlzIHVzZWQgZHVyaW5nIHRoZSB0cmFpbmluZyBwaGFzZSwgdGhlIG1vZGVsIHdvdWxkICJzZWUiIHBhcnQgb2YgdGhlIHRlc3QgZGF0YSdzIHN0cnVjdHVyZSBpbiBhZHZhbmNlLCBsZWFkaW5nIHRvIG92ZXJmaXR0aW5nIGFuZCBmYWlsaW5nIHRvIHJlZmxlY3QgdGhlIHRydWUgZ2VuZXJhbGl6YXRpb24gYWJpbGl0eSBvZiB0aGUgbW9kZWwuDQoNClRoZXJlZm9yZSwgaW4gdGhpcyBhbmFseXNpcywgd2UgZmlyc3Qgc3BsaXQgdGhlIGRhdGEgYW5kIHRoZW4gaW5kZXBlbmRlbnRseSBjYWxjdWxhdGUgdGhlIHNwYXRpYWwgYWRqYWNlbmN5IHJlbGF0aW9uc2hpcHMgYW5kIHNwYXRpYWwgbGFnIHZhbHVlcyBmb3IgZWFjaCBzdWJzZXQuIFRoaXMgYXBwcm9hY2ggbm90IG9ubHkgYmV0dGVyIHJlZmxlY3RzIHJlYWwtd29ybGQgc2NlbmFyaW9zICh3aGVyZSB0aGUgbW9kZWwgb25seSBoYXMgYWNjZXNzIHRvIHRoZSB0cmFpbmluZyBkYXRhIGZvciBwcmVkaWN0aW9uKSBidXQgYWxzbyBpbXByb3ZlcyB0aGUgYWNjdXJhY3kgYW5kIHJlbGlhYmlsaXR5IG9mIG1vZGVsIGV2YWx1YXRpb24uDQoNCmBgYHtyIHNsLCBldmFsPUZBTFNFfQ0KY29vcmRzX3RyYWluIDwtIHByb3BlcnRpZXNfdHJhaW4gJT4lIA0KICBkcGx5cjo6c2VsZWN0KGxvbl80MzI2LCBsYXRfNDMyNikgJT4lIA0KICBkYXRhLm1hdHJpeCgpDQoNCmtubl9uYl90cmFpbiA8LSBrbm4ybmIoa25lYXJuZWlnaChjb29yZHNfdHJhaW4sIGsgPSA0KSkNCmx3X3RyYWluIDwtIG5iMmxpc3R3KGtubl9uYl90cmFpbiwgc3R5bGUgPSAiVyIpDQoNCnByb3BlcnRpZXNfdHJhaW4kbGFnX2V4ZW1wdGlvbiA8LSBsYWcubGlzdHcobHdfdHJhaW4sIHByb3BlcnRpZXNfdHJhaW4kZXhlbXB0aW9uKQ0KbWVhbl9sYWdfdHJhaW4gPC0gbWVhbihwcm9wZXJ0aWVzX3RyYWluJGxhZ19leGVtcHRpb24sIG5hLnJtID0gVFJVRSkNCnByb3BlcnRpZXNfdHJhaW4kbGFnX2V4ZW1wdGlvbltpcy5uYShwcm9wZXJ0aWVzX3RyYWluJGxhZ19leGVtcHRpb24pXSA8LSBtZWFuX2xhZ190cmFpbg0KDQpjb29yZHNfdGVzdCA8LSBwcm9wZXJ0aWVzX3Rlc3QgJT4lIA0KICBkcGx5cjo6c2VsZWN0KGxvbl80MzI2LCBsYXRfNDMyNikgJT4lIA0KICBkYXRhLm1hdHJpeCgpDQoNCmtubl9uYl90ZXN0IDwtIGtubjJuYihrbmVhcm5laWdoKGNvb3Jkc190ZXN0LCBrID0gNCkpDQpsd190ZXN0IDwtIG5iMmxpc3R3KGtubl9uYl90ZXN0LCBzdHlsZSA9ICJXIikNCg0KcHJvcGVydGllc190ZXN0JGxhZ19leGVtcHRpb24gPC0gbGFnLmxpc3R3KGx3X3Rlc3QsIHByb3BlcnRpZXNfdGVzdCRleGVtcHRpb24pDQptZWFuX2xhZ190ZXN0IDwtIG1lYW4ocHJvcGVydGllc190ZXN0JGxhZ19leGVtcHRpb24sIG5hLnJtID0gVFJVRSkNCnByb3BlcnRpZXNfdGVzdCRsYWdfZXhlbXB0aW9uW2lzLm5hKHByb3BlcnRpZXNfdGVzdCRsYWdfZXhlbXB0aW9uKV0gPC0gbWVhbl9sYWdfdGVzdA0KYGBgDQoNCiMjIENyb3NzIFZhbGlkYXRpb24NCg0KVG8gZW5zdXJlIHRoZSByb2J1c3RuZXNzIG9mIG91ciBtb2RlbCBhbmQgYWNjb3VudCBmb3IgZ2VvZ3JhcGhpYyB2YXJpYXRpb24sIHdlIGltcGxlbWVudCBncm91cGVkIGNyb3NzLXZhbGlkYXRpb24gdXNpbmcgYGdyb3VwX3Zmb2xkX2N2KClgLiBJbiB0aGlzIGNhc2UsIHdlIHVzZSBMT0dPQ1YgKExlYXZlLU9uZS1Hcm91cC1PdXQgQ3Jvc3MgVmFsaWRhdGlvbikgYmFzZWQgb24gdGhlIGdlb2dyYXBoaWNfd2FyZCB2YXJpYWJsZSwgd2hpY2ggYWxsb3dzIHVzIHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIGFjcm9zcyBkaWZmZXJlbnQgbmVpZ2hib3Job29kIGdyb3Vwcy4NCg0KQmVmb3JlIG1vZGVsaW5nLCB3ZSBhbHNvIGNyZWF0ZSBhIHByZXByb2Nlc3NpbmcgcmVjaXBlIHRoYXQgaW5jbHVkZXMgb25lLWhvdCBlbmNvZGluZyBmb3IgY2F0ZWdvcmljYWwgdmFyaWFibGVzLCByZW1vdmFsIG9mIHplcm8tdmFyaWFuY2UgcHJlZGljdG9ycywgYW5kIG5vcm1hbGl6YXRpb24gKGNlbnRlcmluZyBhbmQgc2NhbGluZykgZm9yIG51bWVyaWMgcHJlZGljdG9ycy4NCg0KYGBge3IgY3YsIGV2YWw9RkFMU0V9DQojIyBMT0dPQ1Ygb24gTmVpZ2hib3Job29kIHdpdGggZ3JvdXBfdmZvbGRfY3YoKQ0KY3Zfc3BsaXRzX2dlbyA8LSBncm91cF92Zm9sZF9jdihwcm9wZXJ0aWVzX3RyYWluLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gImdlb2dyYXBoaWNfd2FyZCIpDQoNCiMgRmVhdHVyZSBDcmVhdGlvbg0KbW9kZWxfcmVjIDwtIHJlY2lwZShleGVtcHRpb24gfiAuLCBkYXRhID0gcHJvcGVydGllc190cmFpbikgICU+JQ0KICBzdGVwX2R1bW15KGFsbF9ub21pbmFsX3ByZWRpY3RvcnMoKSkgJT4lICANCiAgc3RlcF96dihhbGxfcHJlZGljdG9ycygpKSAlPiUNCiAgc3RlcF9jZW50ZXIoYWxsX251bWVyaWNfcHJlZGljdG9ycygpKSAlPiUNCiAgc3RlcF9zY2FsZShhbGxfbnVtZXJpY19wcmVkaWN0b3JzKCkpDQpgYGANCg0KIyMgWEdCb29zdCBNb2RlbA0KDQpXZSB0cmFpbiBhbiAqKlhHQm9vc3QgY2xhc3NpZmljYXRpb24gbW9kZWwqKiB0byBwcmVkaWN0IGV4ZW1wdGlvbiBlbGlnaWJpbGl0eSwgdXNpbmcgYSBncmlkIHNlYXJjaCB0byB0dW5lIGtleSBoeXBlcnBhcmFtZXRlcnMgKG10cnkgYW5kIG1pbl9uKS4gVGhlIG1vZGVsIGlzIGJ1aWx0IHdpdGhpbiBhIHdvcmtmbG93IHRoYXQgaW5jbHVkZXMgcHJlcHJvY2Vzc2luZyBzdGVwcyBzdWNoIGFzIGR1bW15IGVuY29kaW5nIGFuZCBmZWF0dXJlIHNjYWxpbmcuIFdlIGFwcGx5IGdyb3VwLWJhc2VkIGNyb3NzLXZhbGlkYXRpb24gYnkgZ2VvZ3JhcGhpYyB3YXJkIHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIGFuZCBzZWxlY3QgdGhlIGJlc3QgY29tYmluYXRpb24gb2YgcGFyYW1ldGVycyBiYXNlZCBvbiBhY2N1cmFjeS4gVGhlIGZpbmFsaXplZCBtb2RlbCBpcyB0aGVuIGZpdHRlZCBvbiB0aGUgZW50aXJlIHRyYWluaW5nIHNldCBhbmQgZXZhbHVhdGVkIG9uIHRoZSBob2xkb3V0IHRlc3Qgc2V0LiBQcmVkaWN0aW9ucyBmcm9tIGJvdGggY3Jvc3MtdmFsaWRhdGlvbiBhbmQgdGhlIGZpbmFsIHRlc3Qgc2V0IGFyZSBjb2xsZWN0ZWQgZm9yIGZ1cnRoZXIgYW5hbHlzaXMuDQoNCmBgYHtyIFhHQm9vc3QsIGV2YWw9RkFMU0V9DQojIyBNb2RlbCBzcGVjaWZpY2F0aW9ucw0KWEdCX3BsYW4gPC0gYm9vc3RfdHJlZSgpICU+JQ0KICBzZXRfYXJncyhtdHJ5ICA9IHR1bmUoKSkgJT4lDQogIHNldF9hcmdzKG1pbl9uID0gdHVuZSgpKSAlPiUNCiAgc2V0X2FyZ3ModHJlZXMgPSAyMDApICU+JSANCiAgc2V0X2VuZ2luZSgieGdib29zdCIpICU+JSANCiAgc2V0X21vZGUoImNsYXNzaWZpY2F0aW9uIikgDQoNCiMgSHlwZXJwYXJhbWV0ZXIgZ3JpZCBmb3IgZ2xtbmV0IChwZW5hbGl6YXRpb24pDQp4Z2JfZ3JpZCA8LSBleHBhbmQuZ3JpZCgNCiAgbXRyeSA9IGMoMywgNywxMCksICANCiAgbWluX24gPSBjKDEsNSwxMCkNCikNCg0KIyBjcmVhdGUgd29ya2Zsb3cNCnhnYl93ZiA8LQ0KICB3b3JrZmxvdygpICU+JSANCiAgYWRkX3JlY2lwZShtb2RlbF9yZWMpICU+JSANCiAgYWRkX21vZGVsKFhHQl9wbGFuKQ0KDQojIGZpdCBtb2RlbCB0byB3b3JrZmxvdyBhbmQgY2FsY3VsYXRlIG1ldHJpY3MNCmNvbnRyb2wgPC0gY29udHJvbF9yZXNhbXBsZXMoc2F2ZV9wcmVkID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUpDQptZXRyaWNzIDwtIG1ldHJpY19zZXQocm9jX2F1YywgYWNjdXJhY3ksIGthcCkNCnhnYl90dW5lZCA8LSB4Z2Jfd2YgJT4lDQogIHR1bmU6OnR1bmVfZ3JpZCguLA0KICAgICAgICAgICAgICAgICAgcmVzYW1wbGVzID0gY3Zfc3BsaXRzX2dlbywNCiAgICAgICAgICAgICAgICAgIGdyaWQgICAgICA9IHhnYl9ncmlkLA0KICAgICAgICAgICAgICAgICAgY29udHJvbCAgID0gY29udHJvbCwNCiAgICAgICAgICAgICAgICAgIG1ldHJpY3MgICA9IG1ldHJpY3MpDQoNCiMjIG1ldHJpY3MgYWNyb3NzIGdyaWQNCmNvbGxlY3RfbWV0cmljcyh4Z2JfdHVuZWQpDQoNCiMjICdCZXN0JyBieSBzb21lIG1ldHJpYyBhbmQgbWFyZ2luDQpzaG93X2Jlc3QoeGdiX3R1bmVkLCBtZXRyaWMgPSAiYWNjdXJhY3kiLCBuID0gMTUpDQp4Z2JfYmVzdF9wYXJhbXMgICAgPC0gc2VsZWN0X2Jlc3QoeGdiX3R1bmVkLCBtZXRyaWMgPSAiYWNjdXJhY3kiICAgKQ0KeGdiX2Jlc3Rfd2YgICAgPC0gZmluYWxpemVfd29ya2Zsb3coeGdiX3dmLCB4Z2JfYmVzdF9wYXJhbXMpDQoNCiMgbGFzdF9maXQoKSBlbXVsYXRlcyB0aGUgcHJvY2VzcyB3aGVyZSwgYWZ0ZXIgZGV0ZXJtaW5pbmcgdGhlIGJlc3QgbW9kZWwsIHRoZSBmaW5hbCBmaXQgb24gdGhlIGVudGlyZSB0cmFpbmluZyBzZXQgaXMgbmVlZGVkIGFuZCBpcyB0aGVuIGV2YWx1YXRlZCBvbiB0aGUgdGVzdCBzZXQuDQp4Z2JfdmFsX2ZpdF9nZW8gPC0geGdiX2Jlc3Rfd2YgJT4lIA0KICBsYXN0X2ZpdChzcGxpdCAgICAgPSBkYXRhX3NwbGl0LA0KICAgICAgICAgICBjb250cm9sICAgPSBjb250cm9sLA0KICAgICAgICAgICBtZXRyaWNzICAgPSBtZXRyaWNzKQ0KDQojIFB1bGwgYmVzdCBoeXBlcnBhcmFtIHByZWRzIGZyb20gb3V0LW9mLWZvbGQgcHJlZGljdGlvbnMNCnhnYl9iZXN0X09PRl9wcmVkcyA8LSBjb2xsZWN0X3ByZWRpY3Rpb25zKHhnYl90dW5lZCkgJT4lIA0KICBmaWx0ZXIobXRyeSAgPT0geGdiX2Jlc3RfcGFyYW1zJG10cnlbMV0gJiBtaW5fbiA9PSB4Z2JfYmVzdF9wYXJhbXMkbWluX25bMV0pDQoNCiMgY29sbGVjdCB2YWxpZGF0aW9uIHNldCBwcmVkaWN0aW9ucyBmcm9tIGxhc3RfZml0IG1vZGVsDQp4Z2JfdmFsX3ByZWRfZ2VvICAgIDwtIGNvbGxlY3RfcHJlZGljdGlvbnMoeGdiX3ZhbF9maXRfZ2VvKQ0KYGBgDQoNCkJhc2VkIG9uIHRoZSBmZWF0dXJlIGltcG9ydGFuY2UgcGxvdCBmcm9tIHRoZSBYR0Jvb3N0IG1vZGVsLCB0aGUgdmFyaWFibGUgYHNhbWVfYWRkcmVzc2AsIGluZGljYXRpbmcgd2hldGhlciB0aGUgb3duZXIncyBtYWlsaW5nIGFkZHJlc3MgbWF0Y2hlcyB0aGUgcHJvcGVydHkgYWRkcmVzcywgaXMgYnkgZmFyIHRoZSBtb3N0IGluZmx1ZW50aWFsIHByZWRpY3RvciBvZiBleGVtcHRpb24gc3RhdHVzLiBUaGlzIGxpa2VseSByZWZsZWN0cyB0aGF0IG93bmVyLW9jY3VwaWVkIHByb3BlcnRpZXMgYXJlIG1vcmUgbGlrZWx5IHRvIGFwcGx5IGZvciBhbmQgcmVjZWl2ZSBleGVtcHRpb25zLiBPdGhlciB0b3AgcHJlZGljdG9ycyBpbmNsdWRlIGByZW50YWxfbGljZW5zZWAsIHN1Z2dlc3RpbmcgdGhhdCBwcm9wZXJ0aWVzIHdpdGggcmVudGFsIGxpY2Vuc2VzIGFyZSBsZXNzIGxpa2VseSB0byByZWNlaXZlIGV4ZW1wdGlvbnMsIGFuZCBtZWFzdXJlcyBvZiBwcm9wZXJ0eSB2YWx1ZSBzdWNoIGFzIGBzZF9tYXJrZXRfdmFsdWVgIChzdGFuZGFyZCBkZXZpYXRpb24gb2YgYXNzZXNzZWQgdmFsdWUpLCBgYXZnX21hcmtldF92YWx1ZWAsIGFuZCBgbWVkaWFuX2hvbWVfdmFsdWVgIGF0IHRoZSB0cmFjdCBsZXZlbCwgd2hpY2ggcmVmbGVjdCBib3RoIHByb3BlcnR5IGNoYXJhY3RlcmlzdGljcyBhbmQgbmVpZ2hib3Job29kIGFmZm9yZGFiaWxpdHkuIFNwYXRpYWwgaW5kaWNhdG9ycyBsaWtlYCBsYWdfZXhlbXB0aW9uYCwgYGxhdF80MzI2YCwgYW5kIGBsb25fNDMyNmAgYWxzbyBjb250cmlidXRlIHNpZ25pZmljYW50bHksIHNob3dpbmcgdGhhdCBzcGF0aWFsIGNsdXN0ZXJpbmcgYW5kIGdlb2dyYXBoaWMgbG9jYXRpb24gaW5mbHVlbmNlIGV4ZW1wdGlvbiBwYXR0ZXJucy4gT3ZlcmFsbCwgYSBtaXggb2Ygb3duZXJzaGlwIHN0YXR1cywgcmVudGFsIGFjdGl2aXR5LCBhc3Nlc3NlZCB2YWx1ZSwgYW5kIHNwYXRpYWwgYW5kIGRlbW9ncmFwaGljIGNvbnRleHQgbW9zdCBzdHJvbmdseSBzaGFwZSBleGVtcHRpb24gZWxpZ2liaWxpdHkuDQoNCiFbXShybWRfcG5nL2luZmx1ZW5jZS5wbmcpDQoNCmBgYHtyIEluZmx1ZW5jZSBvZiB2YWlyYWJsZXMsIGV2YWw9RkFMU0V9DQojIEluZmx1ZW5jZSBvZiB2YWlyYWJsZXMNCnhnYl9maW5hbF93ZiA8LSBmaW5hbGl6ZV93b3JrZmxvdyh4Z2Jfd2YsIHhnYl9iZXN0X3BhcmFtcykNCnhnYl9maW5hbF9maXQgPC0gZml0KHhnYl9maW5hbF93ZiwgZGF0YSA9IHByb3BlcnRpZXNfdHJhaW4pDQp4Z2JfbW9kZWwgPC0gZXh0cmFjdF9maXRfcGFyc25pcCh4Z2JfZmluYWxfZml0KSRmaXQNCnhnYl9pbXAgPC0geGdib29zdDo6eGdiLmltcG9ydGFuY2UobW9kZWwgPSB4Z2JfbW9kZWwpDQp4Z2JfaW1wX3NvcnRlZCA8LSB4Z2JfaW1wICU+JSANCiAgYXJyYW5nZShkZXNjKEdhaW4pKQ0KcHJpbnQoeGdiX2ltcF9zb3J0ZWQpDQp4Z2Jvb3N0Ojp4Z2IucGxvdC5pbXBvcnRhbmNlKHhnYl9pbXAsIHRvcF9uID0gMzAsIG1haW4gPSAiVG9wIDIwIE1vc3QgSW5mbHVlbnRpYWwgVmFyaWFibGVzIikNCmBgYA0KDQojIyBQcmVkaWN0IA0KDQpXZSB1c2UgdGhlIGZpbmFsIG1vZGVsIHRvIHByZWRpY3QgZWxpZ2liaWxpdHkgZm9yIGV4ZW1wdGlvbnMgYWNyb3NzIGFsbCBwcm9wZXJ0aWVzLiBXZSBzZXQgYSA1MCUgcHJvYmFiaWxpdHkgdGhyZXNob2xkOiBwcm9wZXJ0aWVzIHdpdGggcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgYmVsb3cgNTAlIGFyZSBjbGFzc2lmaWVkIGFzIGluZWxpZ2libGUsIHdoaWxlIHRob3NlIGFib3ZlIDUwJSBhcmUgY2xhc3NpZmllZCBhcyBlbGlnaWJsZS4gVGhpcyBhbGxvd3MgdXMgdG8gY29tcGFyZSBvdXIgcHJlZGljdGlvbnMgd2l0aCB0aGUgY3VycmVudCBleGVtcHRpb24gc3RhdHVzLg0KDQpBcyBzaG93biwgcHJvcGVydGllcyB3aXRob3V0IGV4ZW1wdGlvbnMgKG1hcmtlZCBpbiByZWQpIGZvbGxvdyBhIGNsZWFyIGJpbW9kYWwgZGlzdHJpYnV0aW9uLiBUaGUgcmlnaHQgcGVhayByZXByZXNlbnRzIHRoZSAxNTMsOTgyIHByb3BlcnRpZXMgY29ycmVjdGx5IHByZWRpY3RlZCBhcyBpbmVsaWdpYmxlLiBUaGUgbGVmdCBwZWFrIGhpZ2hsaWdodHMgb3ZlciA3NSw3MDggcHJvcGVydGllcyB0aGF0IGFyZSBsaWtlbHkgZWxpZ2libGUgZm9yIGV4ZW1wdGlvbiBidXQgYXJlIGN1cnJlbnRseSBtaXNzaW5nIG91dC4gVGhlc2UgYXJlIHRoZSBwcm9wZXJ0aWVzIHdlIHdpbGwgdGFyZ2V0IGZvciBvdXRyZWFjaC4NCg0KRm9yIHByb3BlcnRpZXMgdGhhdCBhbHJlYWR5IGhhdmUgZXhlbXB0aW9ucyAobWFya2VkIGluIGdyZWVuKSwgdGhlcmUgaXMgYSBzaW5nbGUgcGVhaywgd2hpY2ggaXMgZXhwZWN0ZWQuIFRoaXMgcGVhayBjb3JyZXNwb25kcyB0byB0aGUgMjA1LDc4MCBwcm9wZXJ0aWVzIHByZWRpY3RlZCBhcyBlbGlnaWJsZS4gVGhlIHJpZ2h0IHRhaWwgcmVwcmVzZW50cyAzNCwwMDYgcHJvcGVydGllcyB0aGF0IGFyZSBpbmNvcnJlY3RseSBwcmVkaWN0ZWQgYXMgaW5lbGlnaWJsZSBkZXNwaXRlIGhhdmluZyBleGVtcHRpb25zLiBXZSBhaW0gdG8gbWluaW1pemUgdGhpcyBtaXNjbGFzc2lmaWNhdGlvbi4gVGhlIG1vZGVsIHBlcmZvcm1zIHdlbGwgaW4gbWluaW1pemluZyBlcnJvcnMsIGFjaGlldmluZyBhbiA4NS44JSBhY2N1cmFjeSBpbiBwcmVkaWN0aW5nIGVsaWdpYmxlIHByb3BlcnRpZXMgd2l0aCBleGVtcHRpb25zLg0KDQpgYGB7ciBwcmVkaWN0LGV2YWw9RkFMU0V9DQp4Z2JfZnVsbF9wcmVkIDwtIHhnYl9iZXN0X3dmICU+JSANCiAgZml0KGRhdGEgPSBwcm9wZXJ0aWVzX3ByZWRpY3QwKSAlPiUNCiAgcHJlZGljdChuZXdfZGF0YSA9IHByb3BlcnRpZXNfcHJlZGljdDAsdHlwZT0icHJvYiIpICU+JQ0KICBiaW5kX2NvbHMocHJvcGVydGllc19wcmVkaWN0MCkNCg0KeGdiX2Z1bGxfcHJlZCA8LSB4Z2JfZnVsbF9wcmVkICU+JQ0KICBtdXRhdGUoZXhlbXB0aW9uLnByZWQgPSBpZmVsc2UoLnByZWQgPj0gMC41LCAiMSIsICIwIikpJT4lDQogIHJlbmFtZSgucHJlZD0ucHJlZCkNCmBgYA0KDQpgYGB7ciBQTE9UIHJlc3VsdCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KZ2dwbG90KHByb3BlcnRpZXNfbW9kZWwsIGFlcyh4ID0gLnByZWQsIGZpbGwgPSBhcy5mYWN0b3IoZXhlbXB0aW9uKSkpICsgDQogIGdlb21fZGVuc2l0eSgpICsNCiAgZmFjZXRfZ3JpZChleGVtcHRpb24gfiAuKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yczIpICsNCiAgbGFicyh4ID0gIlByb2JhYmlsaXRpZXMiLCB5ID0gIkRlbnNpdHkgb2YgcHJvYmFiaWxpdGllcyIsDQogICAgICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzIGJ5IG9ic2VydmVkIG91dGNvbWUiLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIldpdGhvdXQgRXhlbXB0aW9uID0gMCwgRXhlbXB0aW9uID0gMSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSANCmBgYA0KDQpgYGB7ciBjb25mdXNpb25tYXRyaXgsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCnByb3BlcnRpZXNfbW9kZWwkZXhlbXB0aW9uLnByZWQgPC0gZmFjdG9yKGFzLmNoYXJhY3Rlcihwcm9wZXJ0aWVzX21vZGVsJGV4ZW1wdGlvbi5wcmVkKSwgbGV2ZWxzID0gYygiMCIsICIxIikpDQpwcm9wZXJ0aWVzX21vZGVsJGV4ZW1wdGlvbjwtIGZhY3Rvcihhcy5jaGFyYWN0ZXIocHJvcGVydGllc19tb2RlbCRleGVtcHRpb24pLCAgICAgICBsZXZlbHMgPSBjKCIwIiwgIjEiKSkNCg0KY2FyZXQ6OmNvbmZ1c2lvbk1hdHJpeChwcm9wZXJ0aWVzX21vZGVsJGV4ZW1wdGlvbi5wcmVkLCBwcm9wZXJ0aWVzX21vZGVsJGV4ZW1wdGlvbiwgDQogICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlID0gIjEiKQ0KYGBgDQoNClRoZSBtb2RlbOKAmXMgc2Vuc2l0aXZpdHnigJRpdHMgYWJpbGl0eSB0byBjb3JyZWN0bHkgaWRlbnRpZnkgY3VycmVudCBleGVtcHRpb24gaG9sZGVyc+KAlGlzIGhpZ2ggYW5kIGNvbnNpc3RlbnQgYWNyb3NzIG1vc3QgZGVtb2dyYXBoaWMgZ3JvdXBzLCB3aXRoIHJhdGVzIGFyb3VuZCA4NiUgYW5kIGZhbHNlIG5lZ2F0aXZlIHJhdGVzIChtaXNzZXMpIGFyb3VuZCAxNCUuIFBlcmZvcm1hbmNlIGlzIHNpbWlsYXIgZm9yIGJvdGggTWFqb3JpdHkgV2hpdGUgYW5kIE1ham9yaXR5IE5vbi1XaGl0ZSB0cmFjdHMsIGFzIHdlbGwgYXMgYWNyb3NzIGluY29tZSwgZm9yZWlnbi1ib3JuLCBhbmQgbGltaXRlZCBFbmdsaXNoIGdyb3Vwcy4NCg0KSG93ZXZlciwgdGhlIG1vZGVsIGlzIGxlc3MgZWZmZWN0aXZlIGluIGNlcnRhaW4gYXJlYXM6DQpMb3cgRWR1Y2F0aW9uIHRyYWN0czogU2Vuc2l0aXZpdHkgZHJvcHMgdG8gNzguNiUsIHdpdGggYSBoaWdoZXIgZmFsc2UgbmVnYXRpdmUgcmF0ZSBvZiAyMS40JS4NCkxvdyBTZW5pb3IgUG9wdWxhdGlvbiB0cmFjdHM6IFNlbnNpdGl2aXR5IGlzIG11Y2ggbG93ZXIgYXQgNTIuNSUsIHdpdGggbmVhcmx5IGhhbGYgb2YgZXhlbXB0aW9uIGhvbGRlcnMgbWlzc2VkIChGTiByYXRlIDQ3LjUlKS4NClRoZXNlIHJlc3VsdHMgc3VnZ2VzdCB0aGF0IHdoaWxlIHRoZSBtb2RlbCBwZXJmb3JtcyBlcXVpdGFibHkgZm9yIG1vc3QgZ3JvdXBzLCBhZGRpdGlvbmFsIGF0dGVudGlvbiBtYXkgYmUgbmVlZGVkIHRvIGVuc3VyZSByZXNpZGVudHMgaW4gdHJhY3RzIHdpdGggbG93ZXIgZWR1Y2F0aW9uIGxldmVscyBvciBmZXdlciBzZW5pb3JzIGFyZSBub3Qgb3Zlcmxvb2tlZCBpbiBvdXRyZWFjaCBlZmZvcnRzLg0KDQohW10ocm1kX3BuZy9mbi5wbmcpDQoNCmBgYHtyIHNlbnNpdGl2aXR5LCBldmFsPUZBTFNFfQ0KZGF0YTEgPC0gcmVhZC5jc3YoIkRhdGEveGdiX2Z1bGxfcHJlZF8wNTA1LmNzdiIpDQpjZW5zdXNfdHJhY3RzIDwtIHN0X3JlYWQoIkRhdGEvcGhpbGFfY2Vuc3VzMS5ncGtnIikNCg0KZGF0YTFfc2YgPC0gc3RfYXNfc2YoZGF0YTEsIGNvb3JkcyA9IGMoImxvbl80MzI2IiwgImxhdF80MzI2IiksIGNycyA9IDQzMjYsIHJlbW92ZSA9IEZBTFNFKQ0KY2Vuc3VzX3RyYWN0cyA8LSBzdF90cmFuc2Zvcm0oY2Vuc3VzX3RyYWN0cywgY3JzID0gNDMyNikNCg0KZGF0YTFfam9pbmVkIDwtIHN0X2pvaW4oZGF0YTFfc2YsIGNlbnN1c190cmFjdHMsIGpvaW4gPSBzdF93aXRoaW4sIGxlZnQgPSBUUlVFKQ0KDQpkYXRhMV9qb2luZWQgPC0gZGF0YTFfam9pbmVkICU+JQ0KICByZW5hbWUoDQogICAgcGN0X3dodCA9IHBjdF93aGl0ZSwNCiAgICBtZG5fbmNtXzEgPSBtZWRpYW5faW5jb21lLnksDQogICAgcGN0X2ZyMSA9IHBjdF9mb3JlaWduX2Jvcm4ueSwNCiAgICBsbXRkX24xID0gbGltaXRlZF9lbmdsaXNoX3JhdGUueSwNCiAgICBiY2hfZGcxID0gYmFjaF9kZWdyZWVfcmF0ZS55LA0KICAgIHNucl93bjEgPSBzZW5pb3Jfb3duZXJfcmF0ZS55LA0KICAgIHluZ193bjEgPSB5b3VuZ19vd25lcl9yYXRlLnkNCiAgKQ0KDQpkYXRhMV9qb2luZWQgPC0gZGF0YTFfam9pbmVkICU+JQ0KICBtdXRhdGUoDQogICAgbWFqb3JpdHlfd2hpdGUgPSBpZmVsc2UocGN0X3dodCA+IDAuNSwgIk1ham9yaXR5IFdoaXRlIiwgIk1ham9yaXR5IE5vbi1XaGl0ZSIpLA0KICAgIGFib3ZlX2F2Z19pbmNvbWUgPSBpZmVsc2UobWRuX25jbV8xID4gbWVkaWFuKG1kbl9uY21fMSwgbmEucm0gPSBUUlVFKSwgIkFib3ZlIEF2ZXJhZ2UgSW5jb21lIiwgIkJlbG93IEF2ZXJhZ2UgSW5jb21lIiksDQogICAgaGlnaF9mb3JlaWduX2Jvcm4gPSBpZmVsc2UocGN0X2ZyMSA+IDAuNSwgIkhpZ2ggRm9yZWlnbiBCb3JuIiwgIkxvdyBGb3JlaWduIEJvcm4iKSwNCiAgICBoaWdoX2xpbWl0ZWRfZW5nbGlzaCA9IGlmZWxzZShsbXRkX24xID4gMC41LCAiSGlnaCBMaW1pdGVkIEVuZ2xpc2giLCAiTG93IExpbWl0ZWQgRW5nbGlzaCIpLA0KICAgIGhpZ2hfZWR1Y2F0aW9uID0gaWZlbHNlKGJjaF9kZzEgPiAwLjUsICJIaWdoIEVkdWNhdGlvbiIsICJMb3cgRWR1Y2F0aW9uIiksDQogICAgaGlnaF9zZW5pb3IgPSBpZmVsc2Uoc25yX3duMSA+IDAuNSwgIkhpZ2ggU2VuaW9yIFBvcHVsYXRpb24iLCAiTG93IFNlbmlvciBQb3B1bGF0aW9uIiksDQogICAgaGlnaF95b3VuZyA9IGlmZWxzZSh5bmdfd24xID4gMC41LCAiSGlnaCBZb3VuZyBQb3B1bGF0aW9uIiwgIkxvdyBZb3VuZyBQb3B1bGF0aW9uIikNCiAgKQ0KDQojIEZpbHRlciB0byBvbmx5IGN1cnJlbnQgZXhlbXB0aW9uIGhvbGRlcnMgYW5kIGRyb3AgZ2VvbWV0cnkNCmV4ZW1wdF9kYXRhIDwtIGRhdGExX2pvaW5lZCAlPiUgZmlsdGVyKGV4ZW1wdGlvbiA9PSAxKSAlPiUgc3RfZHJvcF9nZW9tZXRyeSgpDQp0cF9kYXRhIDwtIGV4ZW1wdF9kYXRhICU+JSBmaWx0ZXIoLnByZWRfMSA+PSAwLjUpDQpmbl9kYXRhIDwtIGV4ZW1wdF9kYXRhICU+JSBmaWx0ZXIoLnByZWRfMSA8IDAuNSkNCg0KIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgRk4gUmF0ZSBhbmQgU2Vuc2l0aXZpdHkgcGVyIGdyb3VwDQpjYWxjX2ZuX3JhdGUgPC0gZnVuY3Rpb24odmFyLCBsYWJlbCkgew0KICB0b3RhbCA8LSBleGVtcHRfZGF0YSAlPiUgZ3JvdXBfYnkoISFzeW0odmFyKSkgJT4lIHN1bW1hcmlzZShuID0gbigpKQ0KICB0cCA8LSB0cF9kYXRhICU+JSBncm91cF9ieSghIXN5bSh2YXIpKSAlPiUgc3VtbWFyaXNlKHRwX24gPSBuKCkpDQogIGZuIDwtIGZuX2RhdGEgJT4lIGdyb3VwX2J5KCEhc3ltKHZhcikpICU+JSBzdW1tYXJpc2UoZm5fbiA9IG4oKSkNCiAgc3VtbWFyeSA8LSBsZWZ0X2pvaW4odG90YWwsIHRwLCBieSA9IHZhcikgJT4lDQogICAgbGVmdF9qb2luKGZuLCBieSA9IHZhcikgJT4lDQogICAgbXV0YXRlKA0KICAgICAgdHBfbiA9IGlmZWxzZShpcy5uYSh0cF9uKSwgMCwgdHBfbiksDQogICAgICBmbl9uID0gaWZlbHNlKGlzLm5hKGZuX24pLCAwLCBmbl9uKSwNCiAgICAgIHNlbnNpdGl2aXR5ID0gdHBfbiAvIG4sDQogICAgICBmbl9yYXRlID0gZm5fbiAvIG4NCiAgICApICU+JQ0KICAgIHNlbGVjdCghIXN5bSh2YXIpLCBuLCB0cF9uLCBmbl9uLCBzZW5zaXRpdml0eSwgZm5fcmF0ZSkNCiAgY29sbmFtZXMoc3VtbWFyeSkgPC0gYygiQ2F0ZWdvcnkiLCAiVG90YWwgRXhlbXB0aW9uIEhvbGRlcnMiLCAiVHJ1ZSBQb3NpdGl2ZXMiLCAiRmFsc2UgTmVnYXRpdmVzIiwgIlNlbnNpdGl2aXR5IiwgIkZOIFJhdGUgKCUpIikNCiAgc3VtbWFyeSRHcm91cCA8LSBsYWJlbA0KICBzdW1tYXJ5DQp9DQoNCiMgQ2FsY3VsYXRlIEZOIHJhdGVzIGFuZCBzZW5zaXRpdml0eSBmb3IgZWFjaCBncm91cA0KZm5fbWFqb3JpdHlfd2hpdGUgPC0gY2FsY19mbl9yYXRlKCJtYWpvcml0eV93aGl0ZSIsICJNYWpvcml0eSBSYWNlIikNCmZuX2luY29tZSA8LSBjYWxjX2ZuX3JhdGUoImFib3ZlX2F2Z19pbmNvbWUiLCAiSW5jb21lIikNCmZuX2ZvcmVpZ25fYm9ybiA8LSBjYWxjX2ZuX3JhdGUoImhpZ2hfZm9yZWlnbl9ib3JuIiwgIkZvcmVpZ24gQm9ybiIpDQpmbl9saW1pdGVkX2VuZ2xpc2ggPC0gY2FsY19mbl9yYXRlKCJoaWdoX2xpbWl0ZWRfZW5nbGlzaCIsICJMaW1pdGVkIEVuZ2xpc2giKQ0KZm5fZWR1Y2F0aW9uIDwtIGNhbGNfZm5fcmF0ZSgiaGlnaF9lZHVjYXRpb24iLCAiRWR1Y2F0aW9uIikNCmZuX3NlbmlvciA8LSBjYWxjX2ZuX3JhdGUoImhpZ2hfc2VuaW9yIiwgIlNlbmlvciBQb3B1bGF0aW9uIikNCmZuX3lvdW5nIDwtIGNhbGNfZm5fcmF0ZSgiaGlnaF95b3VuZyIsICJZb3VuZyBQb3B1bGF0aW9uIikNCg0KIyBDb21iaW5lIGFsbCBzdW1tYXJpZXMNCmZuX3N1bW1hcnkgPC0gYmluZF9yb3dzKA0KICBmbl9tYWpvcml0eV93aGl0ZSwNCiAgZm5faW5jb21lLA0KICBmbl9mb3JlaWduX2Jvcm4sDQogIGZuX2xpbWl0ZWRfZW5nbGlzaCwNCiAgZm5fZWR1Y2F0aW9uLA0KICBmbl9zZW5pb3IsDQogIGZuX3lvdW5nDQopDQoNCiMgQ3JlYXRlIHRoZSB0YWJsZSB3aXRoIFNlbnNpdGl2aXR5DQpmbl9zdW1tYXJ5ICU+JQ0KICBndChncm91cG5hbWVfY29sID0gIkdyb3VwIikgJT4lDQogIHRhYl9oZWFkZXIoDQogICAgdGl0bGUgPSAiU3VtbWFyeSBvZiBGYWxzZSBOZWdhdGl2ZSBSYXRlcyBieSBEZW1vZ3JhcGhpYyBHcm91cCINCiAgKSAlPiUNCiAgZm10X251bWJlcigNCiAgICBjb2x1bW5zID0gdmFycyhgVG90YWwgRXhlbXB0aW9uIEhvbGRlcnNgLCBgVHJ1ZSBQb3NpdGl2ZXNgLCBgRmFsc2UgTmVnYXRpdmVzYCksDQogICAgZGVjaW1hbHMgPSAwLA0KICAgIHVzZV9zZXBzID0gVFJVRQ0KICApICU+JQ0KICBmbXRfcGVyY2VudCgNCiAgICBjb2x1bW5zID0gdmFycyhgRk4gUmF0ZSAoJSlgLCBTZW5zaXRpdml0eSksDQogICAgZGVjaW1hbHMgPSAxDQogICkgJT4lDQogIGNvbHNfbGFiZWwoDQogICAgQ2F0ZWdvcnkgPSAiQ2F0ZWdvcnkiLA0KICAgIGBUb3RhbCBFeGVtcHRpb24gSG9sZGVyc2AgPSAiVG90YWwgRXhlbXB0aW9uIEhvbGRlcnMiLA0KICAgIGBUcnVlIFBvc2l0aXZlc2AgPSAiVHJ1ZSBQb3NpdGl2ZXMiLA0KICAgIGBGYWxzZSBOZWdhdGl2ZXNgID0gIkZhbHNlIE5lZ2F0aXZlcyIsDQogICAgYEZOIFJhdGUgKCUpYCA9ICJGTiBSYXRlICglKSIsDQogICAgU2Vuc2l0aXZpdHkgPSAiU2Vuc2l0aXZpdHkiDQogICkNCmBgYA0KDQojIE1pc3NlZCBFeGVtcHRpb24gT3Bwb3J0dW5pdGllcw0KDQpXZSBmb2N1cyBvbiBmYWxzZSBwb3NpdGl2ZSBwcm9wZXJ0aWVz4oCUdGhvc2UgcHJlZGljdGVkIGFzIGVsaWdpYmxlIGJ1dCBjdXJyZW50bHkgbm90IHJlY2VpdmluZyBhbiBleGVtcHRpb24uIFRoZXNlIHByb3BlcnRpZXMgYXJlIGtleSB0YXJnZXRzIGZvciBvdXRyZWFjaCwgYXMgdGhleSBtYXkgYmUgbWlzc2luZyBvdXQgb24gZXhlbXB0aW9uIG9wcG9ydHVuaXRpZXMuIEF0IGEgMC41IHRocmVzaG9sZCwgdGhpcyBhbW91bnRzIHRvIDc1LDcwOCBob3VzZXMuDQoNCmBgYHtyIHJlYWRfZnAsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmZwX2RhdGEgPC0gcmVhZF9jc3YoIkRhdGEvZnBfZGF0YV8wNTA1LmNzdiIpDQpmcF9zZiA8LSBzdF9hc19zZihmcF9kYXRhLCBjb29yZHMgPSBjKCJsb25fNDMyNiIsICJsYXRfNDMyNiIpLCBjcnMgPSA0MzI2KQ0KcGhpbGx5X3NoYXBlZmlsZSA8LSBzdF9yZWFkKGhlcmUoIkRhdGEiLCAidGxfMjAyMF80MjEwMV90cmFjdDIwIiwgInRsXzIwMjBfNDIxMDFfdHJhY3QyMC5zaHAiKSkNCmBgYA0KDQojIyBTcGF0aWFsIERlbnNpdHkgb2YgTWlzc2VkIEV4ZW1wdGlvbnMNCg0KQSBkZW5zaXR5IG1hcCByZXZlYWxzIGNsdXN0ZXJpbmcgcGF0dGVybnMgb2YgbWlzc2VkIGV4ZW1wdGlvbnMgYWNyb3NzIHRoZSBjaXR5LiBTb3V0aHdlc3QgYW5kIE5vcnRoIFBoaWxhZGVscGhpYSBlbWVyZ2UgYXMgbm90YWJsZSBob3RzcG90cywgc3VnZ2VzdGluZyBzcGF0aWFsIGJhcnJpZXJzIG9yIGluZXF1aXRpZXMgaW4gZXhlbXB0aW9uIHVwdGFrZS4gVGhlc2UgYXJlYXMgbWF5IGJlbmVmaXQgZnJvbSBhZGRpdGlvbmFsIHN1cHBvcnQgb3IgY29tbXVuaWNhdGlvbiBlZmZvcnRzLg0KDQpgYGB7ciBkZW5zaXR5bWFwLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQpnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YSA9IHBoaWxseV9zaGFwZWZpbGUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJncmF5ODAiKSArDQogIHN0YXRfZGVuc2l0eTJkKA0KICAgIGRhdGEgPSBmcF9kYXRhLCANCiAgICBhZXMoeCA9IGxvbl80MzI2LCB5ID0gbGF0XzQzMjYsIGZpbGwgPSAuLmxldmVsLi4pLCANCiAgICBnZW9tID0gInBvbHlnb24iLCBhbHBoYSA9IDAuNiwgY29sb3IgPSBOQQ0KICApICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArDQogIGNvb3JkX3NmKCkgKw0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgb2YgRmFsc2UgUG9zaXRpdmUgUHJvcGVydGllcyBpbiBQaGlsYWRlbHBoaWEiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjIERCU0NBTg0KDQpEQlNDQU4sIERlbnNpdHktQmFzZWQgU3BhdGlhbCBDbHVzdGVyaW5nIG9mIEFwcGxpY2F0aW9ucyB3aXRoIE5vaXNlLCB3YXMgYWxzbyB1c2VkIHRvIGV4cGxvcmUgdGhlIHNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIG1pc3NlZCBleGVtcHRpb24gb3Bwb3J0dW5pdGllcy4gSXQgaXMgYSBjbHVzdGVyaW5nIGFsZ29yaXRobSB0aGF0IGdyb3VwcyBkYXRhIHBvaW50cyB3aGljaCBhcmUgY2xvc2UgdG8gZWFjaCBvdGhlciBiYXNlZCBvbiBhIGRlbnNpdHkgY3JpdGVyaW9uLiBEQlNDQU4gaG90c3BvdHMgYXJlIHJlZ2lvbnMgd2hlcmUgdGhlcmUgaXMgYXQgbGVhc3QgYSBzcGVjaWZpZWQgbWluaW11bSBudW1iZXIgb2YgcG9pbnRzIGFyZSBsb2NhdGVkIHdpdGhpbiBhIGRlZmluZWQgcmFkaXVzIChlc3BzaWxvbikgZnJvbSBlYWNoIG90aGVyLiBJbiB0aGlzIGNhc2UsIHRoZSBtaW5pbXVtIG51bWJlciBvZiBwb2ludHMgd2FzIHNldCBhdCAyMCBhbmQgdGhlIGVwc2lsb24gYXQgMzAwIG1ldGVycy4gVGhpcyBhbGdvcml0aG0gaXMgc3RyaWN0ZXIgYW5kIHRlbmRzIHRvIGlnbm9yZSBhcmVhcyB0aGF0IGFyZSBoaWdoLWRlbnNpdHkgYnV0IG1vcmUgZGlzcGVyc2VkLiBPbmx5IGRlbnNlIGNsdXN0ZXJzIG9mIGNsb3NlbHkgcGFja2VkIHBvaW50cyBhcmUgaWRlbnRpZmllZC4NCg0KYGBge3IgYmRzY2FuLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9DQpmcF9wcm9qIDwtIHN0X3RyYW5zZm9ybShmcF9zZiwgMjY5MTgpDQpjb29yZHMgPC0gc3RfY29vcmRpbmF0ZXMoZnBfcHJvaikNCg0KbGlicmFyeShkYnNjYW4pDQoNCmVwc192YWwgPC0gMzAwICAgDQptaW5fcHRzIDwtIDIwICAgIA0KDQpkYl9yZXN1bHQgPC0gZGJzY2FuKGNvb3JkcywgZXBzID0gZXBzX3ZhbCwgbWluUHRzID0gbWluX3B0cykNCmZwX3Byb2okY2x1c3RlciA8LSBhcy5mYWN0b3IoZGJfcmVzdWx0JGNsdXN0ZXIpDQoNCmdncGxvdChmcF9wcm9qKSArDQogIGdlb21fc2YoYWVzKGNvbG9yID0gY2x1c3RlciksIHNpemUgPSAwLjIsIGFscGhhID0gMC43KSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAicGxhc21hIiwgbmFtZSA9ICJDbHVzdGVyIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkRCU0NBTiBDbHVzdGVyaW5nIG9mIEZhbHNlIFBvc2l0aXZlIFByb3BlcnRpZXMiLA0KICAgIHN1YnRpdGxlID0gcGFzdGUoIs61ID0iLCBlcHNfdmFsLCAiLCBtaW5QdHMgPSIsIG1pbl9wdHMpLA0KICAgIGNhcHRpb24gPSAiQ2x1c3RlciAwID0gbm9pc2UgKG5vdCBhc3NpZ25lZCB0byBhbnkgY2x1c3RlcikiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpgYGB7ciBzcGF0aWFsam9pbiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KIyMgc3BhdGlhbCBqb2luIHRvIFRyYWN0cw0KcGhpbGx5X3NoYXBlZmlsZSA8LSBzdF90cmFuc2Zvcm0ocGhpbGx5X3NoYXBlZmlsZSwgc3RfY3JzKGZwX3Byb2opKQ0KZnBfd2l0aF90cmFjdCA8LSBzdF9qb2luKGZwX3Byb2osIHBoaWxseV9zaGFwZWZpbGUpDQoNCmNsdXN0ZXJfc3VtbWFyeSA8LSBmcF93aXRoX3RyYWN0ICU+JQ0KICBzdF9kcm9wX2dlb21ldHJ5KCkgJT4lDQogIGdyb3VwX2J5KFRSQUNUQ0UyMCwgY2x1c3RlcikgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0KdHJhY3RfZnBfc3RhdHMgPC0gY2x1c3Rlcl9zdW1tYXJ5ICU+JQ0KICBncm91cF9ieShUUkFDVENFMjApICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfZnAgPSBzdW0oY291bnQpLA0KICAgIG5fY2x1c3RlcnMgPSBuX2Rpc3RpbmN0KGNsdXN0ZXIpDQogICkgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9mcCkpDQoNCnBoaWxseV90cmFjdHNfam9pbmVkIDwtIGxlZnRfam9pbihwaGlsbHlfc2hhcGVmaWxlLCB0cmFjdF9mcF9zdGF0cywgYnkgPSAiVFJBQ1RDRTIwIikNCg0KdG9wMTBfdHJhY3RzIDwtIHBoaWxseV90cmFjdHNfam9pbmVkICU+JQ0KICBhcnJhbmdlKGRlc2ModG90YWxfZnApKSAlPiUNCiAgc2xpY2VfaGVhZChuID0gMTApICU+JQ0KICBwdWxsKFRSQUNUQ0UyMCkNCg0KcGhpbGx5X3RyYWN0c19qb2luZWQkaGlnaGxpZ2h0X3RvcDEwIDwtIHBoaWxseV90cmFjdHNfam9pbmVkJFRSQUNUQ0UyMCAlaW4lIHRvcDEwX3RyYWN0cw0KDQpnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YSA9IHBoaWxseV90cmFjdHNfam9pbmVkLCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiZ3JheTcwIiwgc2l6ZSA9IDAuMykgKw0KICBnZW9tX3NmKGRhdGEgPSBmaWx0ZXIocGhpbGx5X3RyYWN0c19qb2luZWQsICFpcy5uYSh0b3RhbF9mcCkpLA0KICAgICAgICAgIGFlcyhmaWxsID0gdG90YWxfZnApLCBjb2xvciA9IE5BKSArDQogIA0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMDBBREE5IiwgaGlnaCA9ICIjRTQyNTI0IiwgbmFtZSA9ICJGYWxzZSBQb3NpdGl2ZSBDb3VudCIpICsNCiAgZ2VvbV9zZihkYXRhID0gZmlsdGVyKHBoaWxseV90cmFjdHNfam9pbmVkLCBoaWdobGlnaHRfdG9wMTApLA0KICAgICAgICAgIGZpbGwgPSBOQSwgY29sb3IgPSAiI0U0MjUyNCIsIGxpbmV3aWR0aCA9IDAuNikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIk1pc3NlZCBFeGVtcHRpb24gT3Bwb3J0dW5pdGllcyBieSBDZW5zdXMgVHJhY3QiLA0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgTW9yYW4ncyBJDQoNClRoZSBsb2NhbCBNb3JhbuKAmXMgSSBzaG93cyB0d28gaGlnaC1oaWdoIGNsdXN0ZXJzIGluIFNvdXRoIGFuZCBOb3J0aCBQaGlsYWRlbHBoaWEsIGluZGljYXRpbmcgYXJlYXMgd2hlcmUgcHJvcGVydGllcyB3aXRoIG1pc3NlZCBleGVtcHRpb24gb3Bwb3J0dW5pdGllcyBhcmUgY29uY2VudHJhdGVkLiBJbiBjb250cmFzdCwgdGhlcmUgYXJlIGxvdy1sb3cgY2x1c3RlcnMgaW4gdGhlIGNpdHkgY2VudGVyIGFuZCBOb3J0aHdlc3QgUGhpbGFkZWxwaGlhLCB3aGVyZSBmZXdlciBzdWNoIHByb3BlcnRpZXMgYXJlIGxvY2F0ZWQuIEluIG90aGVyIGFyZWFzLCBwLXZhbHVlcyBhcmUgYWJvdmUgMC4xLCBzbyB0aGUgcmVzdWx0cyBhcmVu4oCZdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KDQpgYGB7ciBsaXNhICwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLnNob3c9J2hvbGQnfQ0KcGhpbGx5X21vcmFuIDwtIHBoaWxseV90cmFjdHNfam9pbmVkICU+JSANCiAgZmlsdGVyKCFpcy5uYSh0b3RhbF9mcCkpDQoNCnRyYWN0X25iIDwtIHBvbHkybmIocGhpbGx5X21vcmFuKQ0KdHJhY3Rfd2VpZ2h0cyA8LSBuYjJsaXN0dyh0cmFjdF9uYiwgc3R5bGUgPSAiVyIsIHplcm8ucG9saWN5ID0gVFJVRSkNCg0KbG9jYWxfbW9yYW4gPC0gbG9jYWxtb3JhbigNCiAgeCA9IHBoaWxseV9tb3JhbiR0b3RhbF9mcCwNCiAgbGlzdHcgPSB0cmFjdF93ZWlnaHRzLA0KICB6ZXJvLnBvbGljeSA9IFRSVUUNCikNCg0KcGhpbGx5X21vcmFuJElpIDwtIGxvY2FsX21vcmFuWywgMV0gICAgICAjIExvY2FsIE1vcmFuJ3MgSQ0KcGhpbGx5X21vcmFuJFpfSWkgPC0gbG9jYWxfbW9yYW5bLCA0XSAgICAjIOagh+WHhuWMliBJDQpwaGlsbHlfbW9yYW4kcF92YWx1ZSA8LSBsb2NhbF9tb3JhblssIDVdICMgcC12YWx1ZQ0KDQpmcF9tZWFuIDwtIG1lYW4ocGhpbGx5X21vcmFuJHRvdGFsX2ZwKQ0KDQpwaGlsbHlfbW9yYW4gPC0gcGhpbGx5X21vcmFuICU+JQ0KICBtdXRhdGUoDQogICAgbGFnX2ZwID0gbGFnLmxpc3R3KHRyYWN0X3dlaWdodHMsIHRvdGFsX2ZwKSwNCiAgICBjbHVzdGVyX3R5cGUgPSBjYXNlX3doZW4oDQogICAgICB0b3RhbF9mcCA+IGZwX21lYW4gJiBsYWdfZnAgPiBmcF9tZWFuICYgcF92YWx1ZSA8IDAuMDUgfiAiSGlnaC1IaWdoIiwNCiAgICAgIHRvdGFsX2ZwIDwgZnBfbWVhbiAmIGxhZ19mcCA8IGZwX21lYW4gJiBwX3ZhbHVlIDwgMC4wNSB+ICJMb3ctTG93IiwNCiAgICAgIHRvdGFsX2ZwID4gZnBfbWVhbiAmIGxhZ19mcCA8IGZwX21lYW4gJiBwX3ZhbHVlIDwgMC4wNSB+ICJIaWdoLUxvdyIsDQogICAgICB0b3RhbF9mcCA8IGZwX21lYW4gJiBsYWdfZnAgPiBmcF9tZWFuICYgcF92YWx1ZSA8IDAuMDUgfiAiTG93LUhpZ2giLA0KICAgICAgVFJVRSB+ICJOb3QgU2lnbmlmaWNhbnQiDQogICAgKQ0KICApDQoNCmdncGxvdChwaGlsbHlfbW9yYW4pICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IGNsdXN0ZXJfdHlwZSksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDAuMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKA0KICAgICAgIkhpZ2gtSGlnaCIgPSAiI0U0MjUyNCIsDQogICAgICAiTG93LUxvdyIgPSAiIzAwQURBOSIsDQogICAgICAiSGlnaC1Mb3ciID0gIiNGMzlDMTIiLA0KICAgICAgIkxvdy1IaWdoIiA9ICIjOUI1OUI2IiwNCiAgICAgICJOb3QgU2lnbmlmaWNhbnQiID0gImdyYXk4MCINCiAgICApLA0KICAgIG5hbWUgPSAiTElTQSBDbHVzdGVyIg0KICApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJMSVNBIENsdXN0ZXIgTWFwIChMb2NhbCBNb3JhbidzIEkpIiwNCiAgICBzdWJ0aXRsZSA9ICJDbHVzdGVycyBvZiBNaXNzZWQgRXhlbXB0aW9uIE9wcG9ydHVuaXRpZXMiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpgYGB7ciBwX3ZhbHVlX0xJU0EsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmdncGxvdChwaGlsbHlfbW9yYW4pICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IHBfdmFsdWUpLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkMiLCBkaXJlY3Rpb24gPSAtMSkgKw0KICBsYWJzKHRpdGxlID0gIlAtVmFsdWVzIGZyb20gTG9jYWwgTW9yYW4ncyBJIiwgZmlsbCA9ICJQLVZhbHVlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyBEZW1vZ3JhcGhpYw0KDQpJbiB0ZXJtcyBvZiBkZW1vZ3JhcGhpYyBhY2NvcnNzIGNlbnN1cyB0cmFjdCwgdGhlIG1vZGVsJ3MgZmFsc2UgcG9zaXRpdmUgcmF0ZXPigJR1c2VkIHRvIGd1aWRlIG91dHJlYWNo4oCUc2hvdyBtaXhlZCBwYXR0ZXJucyBvZiBlcXVpdHkgYWNyb3NzIGRlbW9ncmFwaGljIGdyb3Vwcy4gV2hpbGUgdGhlIHJhdGVzIGFyZSByZWxhdGl2ZWx5IGNvbnNpc3RlbnQgYWNyb3NzIHJhY2lhbCBncm91cHMgKDMzLjAlIGZvciBNYWpvcml0eSBXaGl0ZSB2cyAzMS45JSBmb3IgTWFqb3JpdHkgTm9uLVdoaXRlKSBhbmQgbGFuZ3VhZ2UgcHJvZmljaWVuY3kgbGV2ZWxzICgzMy4wJSBmb3IgSGlnaCBMaW1pdGVkIEVuZ2xpc2ggdnMgMzMuMyUgZm9yIExvdyBMaW1pdGVkIEVuZ2xpc2gpLCB0aGVyZSBhcmUgbm90YWJsZSBkaXNwYXJpdGllcyBpbiBvdGhlciBhcmVhcy4NCg0KVHJhY3RzIHdpdGggbG93ZXIgZWR1Y2F0aW9uIGxldmVscyBzaG93IHNpZ25pZmljYW50bHkgbG93ZXIgRlAgcmF0ZXMgKDIwLjAlIHZzIDMzLjElIGluIGhpZ2ggZWR1Y2F0aW9uIGFyZWFzKSwgYW5kIGFyZWFzIHdpdGggZmV3ZXIgc2VuaW9ycyBoYXZlIGRyYW1hdGljYWxseSBsb3dlciByYXRlcyAoNy4zJSB2cyAzMy4xJSBpbiBoaWdoIHNlbmlvciBhcmVhcykuDQoNCkFkZGl0aW9uYWxseSwgdGhlcmUncyBhIHNsaWdodCBiaWFzIHRvd2FyZCB3ZWFsdGhpZXIgYXJlYXMgKDM0LjglIGluIEFib3ZlIEF2ZXJhZ2UgSW5jb21lIHZzIDMxLjElIGluIEJlbG93IEF2ZXJhZ2UgSW5jb21lKS4gVGhlc2UgcGF0dGVybnMgc3VnZ2VzdCB0aGF0IHdoaWxlIHRoZSBtb2RlbCBtYWludGFpbnMgZXF1aXR5IGFjcm9zcyBzb21lIGRlbW9ncmFwaGljIGRpbWVuc2lvbnMsIGl0IG1heSBiZSB1bmRlci1wcmVkaWN0aW5nIHBvdGVudGlhbCBleGVtcHRpb25zIGluIGFyZWFzIHdpdGggbG93ZXIgZWR1Y2F0aW9uIGxldmVscyBhbmQgZmV3ZXIgc2VuaW9ycy4NCg0KVGhpcyBjb3VsZCByZWZsZWN0IHRydWUgZGlmZmVyZW5jZXMgaW4gZWxpZ2liaWxpdHksIGJ1dCBpdCdzIGltcG9ydGFudCB0byBtb25pdG9yIHRoZXNlIGdyb3VwcyB0byBlbnN1cmUgdGhleSBhcmUgbm90IGluYWR2ZXJ0ZW50bHkgdW5kZXJzZXJ2ZWQuIFRoZSBtb2RlbCdzIHBlcmZvcm1hbmNlIGluIGFyZWFzIHdpdGggaGlnaCBmb3JlaWduLWJvcm4gcG9wdWxhdGlvbnMgKDMyLjklIEZQIHJhdGUpIGlzIHJlbGF0aXZlbHkgZXF1aXRhYmxlIGNvbXBhcmVkIHRvIGxvdyBmb3JlaWduLWJvcm4gYXJlYXMgKDM1LjclKSwgdGhvdWdoIHRoZSBzbWFsbCBudW1iZXIgb2YgcHJvcGVydGllcyBpbiBsb3cgZm9yZWlnbi1ib3JuIHRyYWN0cyAoMiw2MzUpIG1ha2VzIHRoaXMgY29tcGFyaXNvbiBsZXNzIHJlbGlhYmxlLg0KDQohW10ocm1kX3BuZy9mcC5wbmcpDQoNCmBgYHtyIERlbW9ncmFwaGljLCBldmFsPUZBTFNFfQ0KIyBMb2FkIHRoZSBHZW9KU09OIGRhdGENCmRhdGEgPC0gc3RfcmVhZCgiRGF0YS9wcm9wZXJ0aWVzX3dvX2V4ZW1wdGlvbl8wNTA1cHJlZC5nZW9qc29uIikNCm9sZF9kYXRhIDwtIHN0X3JlYWQoIkRhdGEvcHJvcGVydHlfd2l0aG91dF9leGVtcHRpb25fdHJhY3RkYXRhLmdlb2pzb24iKQ0KDQojIEpvaW4gYWxsIG5lY2Vzc2FyeSBkZW1vZ3JhcGhpYyBjb2x1bW5zIGZyb20gb2xkX2RhdGEgdG8gZGF0YSB1c2luZyBHRU9JRA0KZGF0YSA8LSBkYXRhICU+JQ0KICBsZWZ0X2pvaW4oDQogICAgb2xkX2RhdGEgJT4lIA0KICAgICAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JSANCiAgICAgIGdyb3VwX2J5KEdFT0lEKSAlPiUNCiAgICAgIHN1bW1hcml6ZSgNCiAgICAgICAgcGN0X3dodCA9IG1lYW4ocGN0X3dodCwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgcGN0X2ZyMSA9IG1lYW4ocGN0X2ZyMSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgbG10ZF9uMSA9IG1lYW4obG10ZF9uMSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgYmNoX2RnMSA9IG1lYW4oYmNoX2RnMSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgc25yX3duMSA9IG1lYW4oc25yX3duMSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgeW5nX3duMSA9IG1lYW4oeW5nX3duMSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgbWRuX25jbV8xID0gbWVhbihtZG5fbmNtXzEsIG5hLnJtID0gVFJVRSkNCiAgICAgICksDQogICAgYnkgPSAiR0VPSUQiDQogICkNCg0KIyBBZGQgZGVtb2dyYXBoaWMgZ3JvdXBpbmdzIEZJUlNUDQpkYXRhIDwtIGRhdGEgJT4lDQogIG11dGF0ZSgNCiAgICBtYWpvcml0eV93aGl0ZSA9IGlmZWxzZShwY3Rfd2h0ID4gMC41LCAiTWFqb3JpdHkgV2hpdGUiLCAiTWFqb3JpdHkgTm9uLVdoaXRlIiksDQogICAgYWJvdmVfYXZnX2luY29tZSA9IGlmZWxzZShtZG5fbmNtXzEgPiBtZWRpYW4obWRuX25jbV8xLCBuYS5ybSA9IFRSVUUpLCAiQWJvdmUgQXZlcmFnZSBJbmNvbWUiLCAiQmVsb3cgQXZlcmFnZSBJbmNvbWUiKSwNCiAgICBoaWdoX2ZvcmVpZ25fYm9ybiA9IGlmZWxzZShwY3RfZnIxID4gMC41LCAiSGlnaCBGb3JlaWduIEJvcm4iLCAiTG93IEZvcmVpZ24gQm9ybiIpLA0KICAgIGhpZ2hfbGltaXRlZF9lbmdsaXNoID0gaWZlbHNlKGxtdGRfbjEgPiAwLjUsICJIaWdoIExpbWl0ZWQgRW5nbGlzaCIsICJMb3cgTGltaXRlZCBFbmdsaXNoIiksDQogICAgaGlnaF9lZHVjYXRpb24gPSBpZmVsc2UoYmNoX2RnMSA+IDAuNSwgIkhpZ2ggRWR1Y2F0aW9uIiwgIkxvdyBFZHVjYXRpb24iKSwNCiAgICBoaWdoX3NlbmlvciA9IGlmZWxzZShzbnJfd24xID4gMC41LCAiSGlnaCBTZW5pb3IgUG9wdWxhdGlvbiIsICJMb3cgU2VuaW9yIFBvcHVsYXRpb24iKSwNCiAgICBoaWdoX3lvdW5nID0gaWZlbHNlKHluZ193bjEgPiAwLjUsICJIaWdoIFlvdW5nIFBvcHVsYXRpb24iLCAiTG93IFlvdW5nIFBvcHVsYXRpb24iKQ0KICApDQoNCiMgTm93IGZpbHRlciBmb3IgZmFsc2UgcG9zaXRpdmVzIChYX3ByZWQxID49IDAuNSkNCmZwX2RhdGEgPC0gZGF0YSAlPiUgZmlsdGVyKFhfcHJlZF8xID49IDAuNSkNCg0KIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgRlAgUmF0ZSBwZXIgZ3JvdXANCmNhbGNfZnBfcmF0ZSA8LSBmdW5jdGlvbih2YXIsIGxhYmVsKSB7DQogIHRvdGFsIDwtIGFzLmRhdGEuZnJhbWUoZGF0YSkgJT4lIGdyb3VwX2J5KCEhc3ltKHZhcikpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkNCiAgZnAgPC0gYXMuZGF0YS5mcmFtZShmcF9kYXRhKSAlPiUgZ3JvdXBfYnkoISFzeW0odmFyKSkgJT4lIHN1bW1hcmlzZShmcF9uID0gbigpKQ0KICBzdW1tYXJ5IDwtIGxlZnRfam9pbih0b3RhbCwgZnAsIGJ5ID0gdmFyKSAlPiUNCiAgICBtdXRhdGUoZnBfbiA9IGlmZWxzZShpcy5uYShmcF9uKSwgMCwgZnBfbiksDQogICAgICAgICAgIGZwX3JhdGUgPSBmcF9uIC8gbikgJT4lICAjIDwtLS0gcHJvcG9ydGlvbiwgbm90IHBlcmNlbnQNCiAgICBzZWxlY3QoISFzeW0odmFyKSwgbiwgZnBfbiwgZnBfcmF0ZSkNCiAgY29sbmFtZXMoc3VtbWFyeSkgPC0gYygiQ2F0ZWdvcnkiLCAiVG90YWwgUHJvcGVydGllcyIsICJGYWxzZSBQb3NpdGl2ZXMiLCAiRlAgUmF0ZSAoJSkiKQ0KICBzdW1tYXJ5JEdyb3VwIDwtIGxhYmVsDQogIHN1bW1hcnkNCn0NCg0KIyBDYWxjdWxhdGUgRlAgcmF0ZXMgZm9yIGVhY2ggZ3JvdXANCmZwX21ham9yaXR5X3doaXRlIDwtIGNhbGNfZnBfcmF0ZSgibWFqb3JpdHlfd2hpdGUiLCAiTWFqb3JpdHkgUmFjZSIpDQpmcF9pbmNvbWUgPC0gY2FsY19mcF9yYXRlKCJhYm92ZV9hdmdfaW5jb21lIiwgIkluY29tZSIpDQpmcF9mb3JlaWduX2Jvcm4gPC0gY2FsY19mcF9yYXRlKCJoaWdoX2ZvcmVpZ25fYm9ybiIsICJGb3JlaWduIEJvcm4iKQ0KZnBfbGltaXRlZF9lbmdsaXNoIDwtIGNhbGNfZnBfcmF0ZSgiaGlnaF9saW1pdGVkX2VuZ2xpc2giLCAiTGltaXRlZCBFbmdsaXNoIikNCmZwX2VkdWNhdGlvbiA8LSBjYWxjX2ZwX3JhdGUoImhpZ2hfZWR1Y2F0aW9uIiwgIkVkdWNhdGlvbiIpDQpmcF9zZW5pb3IgPC0gY2FsY19mcF9yYXRlKCJoaWdoX3NlbmlvciIsICJTZW5pb3IgUG9wdWxhdGlvbiIpDQpmcF95b3VuZyA8LSBjYWxjX2ZwX3JhdGUoImhpZ2hfeW91bmciLCAiWW91bmcgUG9wdWxhdGlvbiIpDQoNCiMgQ29tYmluZSBhbGwgc3VtbWFyaWVzDQpmcF9zdW1tYXJ5IDwtIGJpbmRfcm93cygNCiAgZnBfbWFqb3JpdHlfd2hpdGUsDQogIGZwX2luY29tZSwNCiAgZnBfZm9yZWlnbl9ib3JuLA0KICBmcF9saW1pdGVkX2VuZ2xpc2gsDQogIGZwX2VkdWNhdGlvbiwNCiAgZnBfc2VuaW9yLA0KICBmcF95b3VuZw0KKQ0KDQpmcF9zdW1tYXJ5ICU+JQ0KICBndChncm91cG5hbWVfY29sID0gIkdyb3VwIikgJT4lDQogIHRhYl9oZWFkZXIoDQogICAgdGl0bGUgPSAiU3VtbWFyeSBvZiBGYWxzZSBQb3NpdGl2ZSBSYXRlcyBieSBEZW1vZ3JhcGhpYyBHcm91cCINCiAgKSAlPiUNCiAgZm10X251bWJlcigNCiAgICBjb2x1bW5zID0gdmFycyhgVG90YWwgUHJvcGVydGllc2AsIGBGYWxzZSBQb3NpdGl2ZXNgKSwNCiAgICBkZWNpbWFscyA9IDAsDQogICAgdXNlX3NlcHMgPSBUUlVFDQogICkgJT4lDQogIGZtdF9wZXJjZW50KA0KICAgIGNvbHVtbnMgPSB2YXJzKGBGUCBSYXRlICglKWApLA0KICAgIGRlY2ltYWxzID0gMQ0KICApICU+JQ0KICBjb2xzX2xhYmVsKA0KICAgIENhdGVnb3J5ID0gIkNhdGVnb3J5IiwNCiAgICBgVG90YWwgUHJvcGVydGllc2AgPSAiVG90YWwgUHJvcGVydGllcyIsDQogICAgYEZhbHNlIFBvc2l0aXZlc2AgPSAiRmFsc2UgUG9zaXRpdmVzIiwNCiAgICBgRlAgUmF0ZSAoJSlgID0gIkZQIFJhdGUgKCUpIg0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI2YwZjBmMCIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX3Jvd19ncm91cHMoKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX3RleHQoY29sb3IgPSAiYmxhY2siLCB3ZWlnaHQgPSAiYm9sZCIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX3Jvd19ncm91cHMoKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX3RleHQoY29sb3IgPSAiYmxhY2siKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KCkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF90ZXh0KGNvbG9yID0gImJsYWNrIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfY29sdW1uX2xhYmVscygpDQogICkNCmBgYA0KDQojIE91dHJlYWNoIFN0cmF0ZWdpZXMNCg0KVGhyZWUgbWFpbiBwb3RlbnRpYWwgb3V0cmVhY2ggc3RyYXRlZ2llcyBhcmUgcHJvcG9zZWQuIFRoZSBjb3N0cyBmb3IgZWFjaCBvZiB0aGVzZSBzdHJhdGVnaWVzIHdlcmUgdGhlbiBlc3RpbWF0ZWQgYmFzZWQgb24gZXhpc3RpbmcgY29zdCBzdHJ1Y3R1cmUgcmVmZXJlbmNlcy4NCg0KIVtdKHJtZF9wbmcvb3V0cmVhY2gucG5nKQ0KDQpUaGUgZmlyc3QgcG90ZW50aWFsIHN0cmF0ZWd5IGlzICoqYSBkaXJlY3QgbWFpbGluZyBjYW1wYWlnbioqLCB3aGljaCBpbnZvbHZlcyBzZW5kaW5nIGZseWVycyBvdXQgdG8gYWxsIHByb3BlcnRpZXMgaWRlbnRpZmllZCBhcyBmYWxzZSBwb3NpdGl2ZXMgYnkgdGhlIG1vZGVsLiBUaGUgZmx5ZXIgd291bGQgY29udGFpbiBpbmZvcm1hdGlvbiBvbiB3aGF0IHRoZSBob21lc3RlYWQgZXhlbXB0aW9uIHByb2dyYW0gaXMsIGl0cyBlbGlnaWJpbGl0eSBjcml0ZXJpYSwgaW5zdHJ1Y3Rpb25zIG9uIGhvdyB0byBhcHBseSwgYW5kIHJlbGV2YW50IGNvbnRhY3QgaW5mb3JtYXRpb24sIHRyYW5zbGF0ZWQgYWNyb3NzIGRpZmZlcmVudCBsYW5ndWFnZXMuICANCg0KVGhlIG5leHQgcG90ZW50aWFsIHN0cmF0ZWd5IGlzICoqYSBkb29yLWtub2NraW5nIGNhbXBhaWduKiouIFRoaXMgaW52b2x2ZXMgZ29pbmcgZG9vci10by1kb29yIHRvIGlkZW50aWZpZWQgcHJvcGVydGllcyBhbmQgaGF2aW5nIGNhbnZhc3NlcnMga25vY2sgb24gdGhlIGRvb3JzLCBzaGFyaW5nIHdpdGggaG9tZW93bmVycyB3aG8gcmVzcG9uZCBhYm91dCB0aGUgaG9tZXN0ZWFkIGV4ZW1wdGlvbiBwcm9ncmFtLiBUaGlzIGZhY2UtdG8tZmFjZSBpbnRlcmFjdGlvbiBjYW4gaGlnaGx5IGVmZmVjdGl2ZSBpbiByYWlzaW5nIGF3YXJlbmVzcyBhYm91dCB0aGUgcHJvZ3JhbSwgaG93IHRvIGFwcGx5IHRvIGl0LCBhbmQgZGlyZWN0bHkgYWRkcmVzcyBhbnkgcXVlcmllcyBvciBkb3VidHMgdGhhdCB0aGUgaG9tZW93bmVyIG1heSBoYXZlIGFib3V0IGl0LiBGcm9tIEp1bHkgMjAyMyB0byBKdW5lIDIwMjQsIHRoZSBDaXR5IG9mIFBoaWxhZGVscGhpYSBjb25kdWN0ZWQgYSBkb29yLWtub2NraW5nIGNhbXBhaWduIHVuZGVyIHRoZSBPdmVyZG9zZSBBd2FyZW5lc3MgQ2FudmFzc2luZyBhbmQgVHJ1c3RlZCBDb21tdW5pdHkgTWVzc2VuZ2VyIFByb2dyYW0uIERvb3Ita25vY2tpbmcgaXMgcHJvcG9zZWQgdG8gYmUgY29uZHVjdGVkIGZvciBoaWdoIHBvdGVudGlhbCBhcmVhcyB3aXRoIGNsdXN0ZXJzIG9mIG1pc3NlZCBob21lc3RlYWQgZXhlbXB0aW9uIG9wcG9ydHVuaXRpZXMuIFRoaXMgb3B0aW1pemVzIGxpbWl0ZWQgcmVzb3VyY2VzIGluIHRyYXZlbCB0aW1lIGFuZCBjb3N0cyBiZXR3ZWVuIHByb3BlcnRpZXMgZm9yIGRvb3Iga25vY2tpbmcuIFRoaXMgY2FtcGFpZ24gd291bGQgdGhlcmVmb3JlIG9ubHkgdGFyZ2V0IHRoZSAxMiwzMDIgaG9tZXMgaWRlbnRpZmllZCBpbiB0aGUgdHdvIGNsdXN0ZXJzLCBOb3J0aGVhc3QgYW5kIFNvdXRoIFBoaWxhZGVscGhpYSwgd2hpY2ggaGF2ZSA2LDY2OSBhbmQgNiwzNjIgdGFyZ2V0IG91dHJlYWNoIGhvbWVzIHJlc3BlY3RpdmVseS4NCg0KYGBge3IgaGlnaF9oaWdoLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmdncGxvdChwaGlsbHlfbW9yYW4pICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IGNsdXN0ZXJfdHlwZSksIGNvbG9yID0gImdyYXk5MCIsIHNpemUgPSAwLjIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwoDQogICAgdmFsdWVzID0gYygNCiAgICAgICJIaWdoLUhpZ2giID0gIiNFNDI1MjQiDQogICAgKSwNCiAgICBuYW1lID0gIkxJU0EgQ2x1c3RlciINCiAgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiTElTQSBDbHVzdGVyIE1hcCAoTG9jYWwgTW9yYW4ncyBJKSIsDQogICAgc3VidGl0bGUgPSAiQ2x1c3RlcnMgb2YgTWlzc2VkIEV4ZW1wdGlvbiBPcHBvcnR1bml0aWVzIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KQW5vdGhlciBwb3RlbnRpYWwgc3RyYXRlZ3kgaXMgdG8gKipyZWFjaCBvdXQgdG8gY29tbXVuaXR5IG9yZ2FuaXphdGlvbnMqKiB0byBlZHVjYXRlIG9yZ2FuaXphdGlvbiBsZWFkZXJzIGFuZCBzdGFmZiBhYm91dCB0aGUgZXhlbXB0aW9uIHByb2dyYW0sIHdobyBjYW4gdGhlbiBzcHJlYWQgdGhlIHdvcmQgdG8gdGhlaXIgbWVtYmVycyBhbmQgdGhlIGltbWVkaWF0ZSBsb2NhbCBjb21tdW5pdHkgYWJvdXQgaXQuIFRoaXMgbWF5IGluY2x1ZGUgY29tbXVuaXR5IGNlbnRyZXMgb3IgcmVsaWdpb3VzIG9yZ2FuaXphdGlvbnMsIHN1Y2ggYXMgdGhlIENpdHkgb2YgTGlmZSBjaHVyY2ggaW4gU291dGggUGhpbGFkZWxwaGlhLg0KDQpUaGUgZXN0aW1hdGVkIGNvc3RzIG9mIHRoZSBvdXRyZWFjaCBzdHJhdGVnaWVzIHdlcmUgY2FsY3VsYXRlZCBiYXNlZCBvbiB0aGUgY29zdCBzdHJ1Y3R1cmVzIGZyb20gdGhlIE9waW9pZCBSZXNwb25zZSBVbml0IERvb3ItS25vY2tpbmcgQ2FtcGFpZ24gYW5kIFVTUFMgRGlyZWN0IE1haWwgQWR2ZXJ0aXNpbmcgY29zdCBjYWxjdWxhdG9yLg0KDQpEb29yIEtub2NraW5nOg0KDQotIEZpeGVkIENvc3RzOiBQZXJzb25uZWwgKyBTdXBwbGllcw0KLSBWYXJpYWJsZSBDb3N0czogbGFib3IgJDM0LjgwIC9ob3VyIMOXIChQcm9wZXJ0aWVzIMO3IDEwIGhvbWVzL2hyKQ0KLSBJbmRpcmVjdCBDb3N0czogMTAlIG9mIHRvdGFsIGRpcmVjdCBjb3N0cw0KLSBXZWVrbHkgQ2FwYWNpdHk6IDEsNjAwIGhvbWVzICg4IHN0YWZmIMOXIDIwIGhycyDDlyAxMCBob21lcy9ocikNCg0KRGlyZWN0IE1haWxpbmc6DQoNCi0gRml4ZWQgQ29zdHM6IFBlcnNvbm5lbCArIERlc2lnbiArIFN1cHBsaWVzDQotIFZhcmlhYmxlIENvc3RzOiBQcmludGluZyAkMC4wOSBwZXIgcGllY2UgfCBNYWlsaW5nICQwLjI5IHBlciBwaWVjZQ0KLSBJbmRpcmVjdCBDb3N0czogMTAlIG9mIHRvdGFsIGRpcmVjdCBjb3N0cw0KDQohW10ocm1kX3BuZy9vdXRyZWFjaGNvc3QucG5nKQ0KDQpgYGB7ciBvdXRyZWFjaF9jb3N0LCBldmFsPUZBTFNFfQ0KY29zdHMgPC0gZGF0YS5mcmFtZSgNCiAgQ2F0ZWdvcnkgPSBjKA0KICAgICJQZXJzb25uZWwiLCAiUHVyY2hhc2UgU2VydmljZXMiLCAiUHJvZ3JhbSBTdXBwbGllcyIsICJJbmRpcmVjdCBDb3N0cyIsICJUb3RhbCINCiAgKSwNCiAgYERpcmVjdCBNYWlsaW5nXG4oQWxsOiA3NywzMTcgaG9tZXMpYCA9IGMoDQogICAgMjgwNiwgNzI2LCAyOTY3OCwgMzMyMSwgMzY1MzINCiAgKSwNCiAgYERvb3ItS25vY2tpbmdcbihIaWdoLVBvdGVudGlhbCBDbHVzdGVyczogMTMsMDMxIGhvbWVzKWAgPSBjKA0KICAgIDI5ODQwLCA2NjgxNiwgMzc5OCwgMTAwNDUsIDExMDQ5OQ0KICApDQopDQoNCmNvc3RzWyAsMjozXSA8LSBsYXBwbHkoY29zdHNbICwyOjNdLCBkb2xsYXIpDQoNCmthYmxlKGNvc3RzLCBhbGlnbiA9ICJscnIiLCBlc2NhcGUgPSBGQUxTRSwgY2FwdGlvbiA9ICJQcm9ncmFtIE91dHJlYWNoIENvc3RzIGJ5IFN0cmF0ZWd5IikgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkNCmBgYA0KDQpUaGUgcG90ZW50aWFsIGJlbmVmaXRzIG9mIHN1Y2ggb3V0cmVhY2ggY2FtcGFpZ25zIGFyZSB2YXN0LiBCYXNlZCBvbiB0aGUgRGF0YSBhbmQgTWFya2V0aW5nIEFzc29jaWF0aW9uLCB0aGUgYXZlcmFnZSByZXNwb25zZSByYXRlIHRvIGEgZGlyZWN0IG1haWxpbmcgY2FtcGFpZ24gcmFuZ2VzIGJldHdlZW4gNCBhbmQgOSUuIFdpdGggYW4gYXNzdW1wdGlvbiB0aGF0IDUlIG9mIGFsbCBob21lb3duZXJzIHdlIG91dHJlYWNoIHRvIHRoZW4gc3VjY2Vzc2Z1bGx5IGVucm9sbCBpbnRvIGEgaG9tZXN0ZWFkIGV4ZW1wdGlvbiwgdGhlIHRvdGFsIGRpcmVjdCBiZW5lZml0IGluIGhvbWVvd25lciBzYXZpbmdzIHdvdWxkIGJlIE51bWJlciBvZiBQcm9wZXJ0aWVzIMOXIDAuMDUgw5cgKHVwIHRvKSBcJDEsMzk5LiBVc2luZyB0aGlzIGZvcm11bGEsICoqdGhlcmUgY2FuIGJlIHVwIHRvIFwkNSwyOTUsNzc0LjYwIG9mIHNhdmluZ3MgYWNyb3NzIHRoZSBob21lb3duZXJzLioqIE1ham9yaXR5IG9mIHRoZSBob21lc3RlYWQgZXhlbXB0aW9ucyBoYXZlIGJlZW4gb2JzZXJ2ZWQgdG8gcmVjZWl2ZSB0aGUgbWF4aW11bSBlbGlnaWJsZSBleGVtcHRpb24uIENvbXBhcmluZyB0aGlzIHRvIHRoZSB0b3RhbCBvdXRyZWFjaCBjb3N0IGZvciBhIGRpcmVjdCBtYWlsaW5nIGNhbXBhaWduIG9mIFwkMzUsODYxLCB0aGUgb3V0cmVhY2ggY2FuIGJyaW5nIG1hc3NpdmUgcHVibGljIGJlbmVmaXQgZm9yIGEgcmVsYXRpdmVseSBzbWFsbCBhbW91bnQuIEZ1cnRoZXJtb3JlLCB0aGlzIGVzdGltYXRlIGRvZXMgbm90IGV2ZW4gaW5jbHVkZSB0aGUgaHVnZSB1bnF1YW50aWZpZWQgYmVuZWZpdHMgb2YgaW5jcmVhc2VkIGhvdXNpbmcgc3RhYmlsaXR5IGZvciBob21lb3duZXJzIGFuZCB0aGVpciBmYW1pbGllcy4gVGhpcyByZWR1Y2VzIHRyYW5zaWVuY2UgYW5kIGVuY291cmFnZXMgb3duZXIgb2NjdXBhbmN5IGFuZCBsb25nIHRlcm0gcmVzaWRlbmN5LCB3aGljaCBzdXBwb3J0cyBjb25zaXN0ZW50IG5laWdoYm9yaG9vZCBuZXR3b3JrcywgZm9zdGVyaW5nIG1vcmUgZW5nYWdlZCBhbmQgaW52ZXN0ZWQgbG9jYWwgY29tbXVuaXRpZXMuIE93bmVyLW9jY3VwaWVkIGhvbWVzIGFyZSBhbHNvIG1vcmUgbGlrZWx5IHRvIGJlIHdlbGwtbWFpbnRhaW5lZCBhcyB0aGVyZSBpcyBncmVhdGVyIGluY2VudGl2ZSB0byB1cGtlZXAgdGhlIHByb3BlcnR5LCB3aGljaCBiZW5lZml0cyBuZWlnaGJvcmhvb2QgYWVzdGhldGljcyBhbmQgcHJvcGVydHkgdmFsdWVzLg0KDQpJdCBpcyB0aGVuIGV4cGxvcmVkIGhvdyB0aGUgdXNlIG9mIHRoZSBtb2RlbCBjb21wYXJlcyB0byBhbiBhbHRlcm5hdGl2ZSBhcHByb2FjaCBvZiBhIGZpbHRlcmVkIGxpc3Qgb2YgcHJvcGVydGllcy4gVGhlIHByb3BlcnRpZXMgYXJlIGZpbHRlcmVkIHRvIHJlc2lkZW50aWFsLW9ubHksIG5vbi1jb3Jwb3JhdGlvbiBvd25lZCBwcm9wZXJ0aWVzIHdpdGggdGhlIHNhbWUgYWRkcmVzcyBhcyBpdHMgbWFpbGluZyBhZGRyZXNzLiAqKlRoaXMgcmVzdWx0cyBpbiAzMzMsNjIzIHByb3BlcnRpZXMsIHdoaWNoIHdvdWxkIGNvc3QgJDE0Myw2NjkgdG8gZXhlY3V0ZSBzb2xlbHkgdGhlIGRpcmVjdCBtYWlsaW5nIGNhbXBhaWduLioqIFVzaW5nIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCB0byBpZGVudGlmeSBwcm9wZXJ0aWVzIHRvIHJlYWNoIG91dCB0byBzdWJzdGFudGlhbGx5IG5hcnJvd3MgZG93biB0aGUgdGFyZ2V0IG51bWJlciwgYWxsb3dpbmcgZm9yIGh1Z2UgY29zdC1zYXZpbmdzIGFuZCBhbiBlZmZlY3RpdmUgdXNlIG9mIGxpbWl0ZWQgcmVzb3VyY2VzLiBUaGUgc3BhdGlhbCBhbmFseXNpcyBvZiBmYWxzZSBwb3NpdGl2ZXMgYWxzbyBhbGxvdyBmb3IgbW9yZSB0YXJnZXRlZCBkb29yLWtub2NraW5nIHRvIHRha2UgcGxhY2UuDQoNCiFbXShybWRfcG5nL3NpbXBsZV9maWx0ZXIucG5nKQ0KDQpgYGB7ciBzaW1wbGVfZmlsdGVyLCBldmFsPUZBTFNFfQ0KIyBDb21wYXJpc29uIHRvIGEgYnVzaW5lc3MtYXMtdXN1YWwgZmlsdGVyaW5nIGFwcHJvYWNoDQpmaWx0ZXJlZF9wcm9wZXJ0aWVzX3Jlc29ubHkgPC0gZmlsdGVyZWRfcHJvcGVydGllc19leCAlPiUgbXV0YXRlKGlzX3Jlc2lkZW50aWFsID0gaWZlbHNlKHpvbmluZyAlaW4lIGMoDQogICJSTTEiLCAiUk0yIiwgIlJNMyIsICJSTTQiLA0KICAiUlNBMSIsICJSU0EyIiwgIlJTQTMiLCAiUlNBNCIsICJSU0E1IiwgIlJTQTYiLCANCiAgIlJTRDEiLCAiUlNEMiIsICJSU0QzIiwgDQogICJSTTF8UlNBNSIsICJSU0QxfFJTRDMiLCAiUlNBNXxSU0E1IiwNCiAgIlJUQTEiLCANCiAgIkNNWDEiLCAiQ01YMiIsICJDTVgyLjUiLCAiQ01YMyIsICJDTVg0IiwgIkNNWDUiLCAiSVJNWCIpLCAxLCAwKSkNCg0Kb3duZXJzdG9yZW1vdmUgPC0gcHJvcGVydGllcyAlPiUNCiAgZ3JvdXBfYnkob3duZXJfMSkgJT4lDQogIHN1bW1hcmlzZShwcm9wZXJ0eV9jb3VudCA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGZpbHRlcihzdHJfZGV0ZWN0KG93bmVyXzEsICIgTExDIHwgTExDfFJFQUwgRVNUQVRFfEFTU09DfEhBTEFCVUdJIElOQ3xJTlZFU1RNRU5UfENIVVJDSHwxMjI5LTEyNDcgTk9SVEggMjdUSCBTVHxLSU5HUyBISUdIV0FZfFZJTExBR0V8DQogIEFDUVVJU0lUSU9OfFBBUlRORVJTfDIxMDEgV0FTSElOR1RPTiBBVkVOVUUgTEx8Q0hBSSBOVVRTIExQfFJFQUxUWXxQUk9QRVJUSUVTfFNQRUNJQUwgUEVPUExFIElOIE5PUlRIRUF8Q09NUEFOWXxTUEVDSUFMfA0KICBMQU5EIFRSVVNUfFRSVVNUfFNJRU5BIFBMQUNFIFBMQU5ORUQgQ09NTVV8Tk9SUklTIFNRVUFSRSBORUlHSEJPUkhPT3wyMDEtNTkgTk9SVEggRUlHSFRIfFBSRVBBUkFUT1J8SU5WRVNUT1JTfA0KICBQT0lOVCBCUkVFWkV8V1BSRSBJSUkgTCBQfE5BVElPTkFMfEFSQ0ggVi1URU1QTEUgMTZUSCBTVFJFRVR8Tk9SVEggRk9VUlRIIFNUUkVFVHxCQU5LRVJTIFRSVVNUfENPTU1PTlMgQVQgUE9JTlQgQlJFRVpFfA0KICBWRVRFUkFOfFBSRVNFUlZBVElPTnxDT05ET01JTklVTXwxOTkgSFVOVElORyBQQVJLfEFQQVJUTUVOVHxIT0xESU5HU3wgTCBQfENPVVJUfFNDSE9PTHxTRVJWSUNFU3xIQUJJVEFUIEZPUiBIVU1BTklUWXxDT01NSVRURUV8QkFQVElTVHwNCiAgQ09MTEVHRXxBQ1FVSVNJVElPTnxERUxFT3xBTVRSQUt8UkVOVEFMU3xQQVJUSUNJUEFUSU9OfFNQUklORyBBUlRTfFNFUFRBfFdBU0hJTkdUT04gU1FVQVJFfEZBSVJNT1VOVCBQQVJLfFBBUktJTkd8DQogIEFSQ0ggVkkgLSBURU1QTEV8VEhFIExPRlRTfEZVTkQgfFdIQVJUT04gQ09VUlR8R1JPVVB8UEVOVEVDT1NUfFJBRCBESVZFUlNJRklFRCBSRUlUIElOQ3xDT01NT05TfExJTUlURUR8UEVOTkEgfEZJUlNUfENPTlRSQUNUT1J8UE9JTlQgQlJFRVpFfEJPT1RTVFJBUHxSSVRURU5IT1VTRXwNCiAgSEFCSVRBVCBGT1IgSFVNQU5JVFl8REVMQVdBUkUgUklWRVJ8RU5URVJQUklTRVN8Q09NTVVOSVRZfEZPVU5EQVRJT058QkVMTCBURUxFUEhPTkUgQ098Q0VOVEVSfFBBUlRORVJTfERFVkVMT1BNRU5UfA0KICBWRVQgQUZGQUlSU3xGRURFUkFMfFdPUktGT1JDRXxQRU5ORE9UfElOVkVTVE9SU3xHRU9SR0UgV09PRFdBUkQgSU5DfEhBUlJJU09OIElOQ3xKREogRlVORHxBRkZPUkRBQkxFfElOVEVSU1RBVEV8IElOQyB8QklPIExVQ0tZIFNUQVIgSU5DfExFQU5OQSBJTkN8RUxFQkFIIElOQ3xCRU5HRU1JTkkgQ09OU1VMVEFOVFMgSU5DfEJVSUxERVJTfEtPUkVBTiBDT01NVU5JVFkgREVWRUxPUE18REVWRUxPUEVSU3wNCiAgUE9SVEZPTElPfFJFU0lERU5USUFMfFBISUxMWXxQUk9KRUNUfE1BTkFHRU1FTlR8VU1PSkEgSU5DfEFTU04gSU5DfERFTEFXQVJFIFZBTExFWXxBUkNIIFZJIC0gVEVNUExFIE4gR1JBVFp8U1VQUExZfExPRlRTfFNUUkVFVHxPRkZJQ0V8IExQfENJVFl8VkVOVFVSRVN8DQogIFVOSVRFRCBTVEFURVMgT0YgQU1FUklDQXxQSElMQXxOT04gUFJPRklUfEFTU098SE9VU0V8TkVJR0hCT1JIT09EfFBBVEggSU5DfFVOSVZ8SE9VU0lOR3xQUk9QRVJUWXxDT01NT05XRUFMVEh8Q09OUkFJTHxDT01NRVJDRXwNCiAgVkVOVFVSRVN8VU5JVEVEfENPUlJJRE9SfFNRVUFSRXxDSVZJQ3xBUk1ZfFNBTFZBVElPTnxQRU5OU1lMVkFOSUF8QURNSU5JU1RSQVRPUnxUT1dOSE9NRVN8Q0JNfFJFTlRBTHxBTUVSSUNBIElOQ3xTVCBGUkFOQ0lTIElOTnxIT01FT1dORVJTSElQfA0KICBJTlNUSVRVVEV8UkVTT1VSQ0VTfENPTlNUUlVDVElPTnxMIFB8VFJBTlNQT1JUQVRJT058Q1NYfERSRVhFTHxQQVNTWVVOS3xDT0xMRUdFfFdJU1RFUkNPUiBJTkN8U0lFTkEgUExBQ0UgUFVEfEVRVUlUWXwgQ0FQSVRBTHxFWFBPUlR8U1RSQVdCRVJSWSBNQU5TSU9OfDctRUxFVkVOfEtFRVAgUExVR0dJTkcgVEhSRUUgSU5DfE9VVFNPVVJDRSAyMDAwIElOQ3xDSEFJIDE4IElOQ3xZIEUgUiBBIElOQyB8V09STER8QURNSU58VSBTIE9GIEFNRVJJQ0F8QVVUSE9SSVRZfA0KICBTRVBUQXxBUFRTfCBMVER8Q09SUCIpKSAlPiUNCiAgcHVsbChvd25lcl8xKSAgIyBFeHRyYWN0IHRoZSBsaXN0IG9mIG93bmVycyB0byByZW1vdmUNCg0KIyBTdGVwIDI6IEZpbHRlciBvdXQgcHJvcGVydGllcyBvd25lZCBieSB0aGVzZSBvd25lcnMNCmZpbHRlcmVkX3Byb3BlcnRpZXMgPC0gZmlsdGVyZWRfcHJvcGVydGllc19yZXNvbmx5ICU+JQ0KICBmaWx0ZXIoIW93bmVyXzEgJWluJSBvd25lcnN0b3JlbW92ZSkNCg0KcmVzaWRlbnRpYWxfcHJvcGVydGllcyA8LSBmaWx0ZXJlZF9wcm9wZXJ0aWVzICU+JSBmaWx0ZXIoaXNfcmVzaWRlbnRpYWwgPT0gMSkNCmBgYA0KDQojIERhc2hib2FyZA0KDQpPdXIgZGFzaGJvYXJkIFtIb21lc3RlYWQgRXhlbXB0aW9uIE91dHJlYWNoIEV4cGxvcmVyXShodHRwczovL2hhb3l1MjUuZ2l0aHViLmlvL1BoaWxseS1Ib21lb3duZXJzLykgaXMgZm9yIFBoaWxseSBTdGF0IDM2MCBhbmQgcG90ZW50aWFsIG91dHJlYWNoIGNhbXBhaWduIG1hbmFnZXJzIHRvIGV4cGxvcmUgd2hlcmUgcHJvcGVydGllcyBwcmVkaWN0ZWQgdG8gYmUgbGlrZWx5IGVsaWdpYmxlIGZvciB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbiBwcm9ncmFtIGFyZSBsb2NhdGVkLCBhcyB3ZWxsIGFzIG5laWdoYm9yaG9vZCBwcm9maWxlcyBvZiBhcmVhcy4gVGhlIHRocmVzaG9sZCBzbGlkZXIgYWxsb3dzIG9uZSB0byBjaGFuZ2UgdGhlIGVsaWdpYmlsaXR5IHRocmVzaG9sZCBvZiB0aGUgbW9kZWwsIHdoZXJlIGEgbG93ZXIgdmFsdWUgaW5kaWNhdGVzIGEgbW9yZSBsZW5pZW50IHRocmVzaG9sZCB3aGljaCB3b3VsZCBpbmNsdWRlIG1vcmUgcHJvcGVydGllcyBpbiB0aGUgY2Vuc3VzIHRyYWN0LCB3aGlsZSBhIGhpZ2hlciB2YWx1ZSBpbmRpY2F0ZXMgYSBzdHJpY3RlciB0aHJlc2hvbGQuIFRoZSBleHBvcnRlZCBzcHJlYWRzaGVldCBjb250YWlucyBhbGwgYWRkcmVzc2VzIGFuZCBvd25lciBuYW1lcyBvZiB0aGUgcHJvcGVydGllcyBpbiB0aGUgc2VsZWN0ZWQgY2Vuc3VzIHRyYWN0LCBiYXNlZCBvbiB0aGUgY2hvc2VuIHRocmVzaG9sZCBsZXZlbC4NCg0KQWRkaXRpb25hbCBmZWF0dXJlcyBpbmNsdWRlIHRoZSBhZGRyZXNzIHNlYXJjaCBiYXIgZnVuY3Rpb24gYW5kIHRoZSBjb21tdW5pdHkgc2l0ZXMgdG9nZ2xlIGJ1dHRvbi4gQ29tbXVuaXR5IHNpdGVzIGluY2x1ZGUgcGxhY2VzIG9mIHdvcnNoaXAsIGxpYnJhcmllcywgbWFya2V0cGxhY2VzIGFuZCBjb21tdW5pdHkgY2VudGVycywgZXh0cmFjdGVkIGZyb20gT3BlblN0cmVldE1hcC4gVGhlc2UgYXJlIHBvdGVudGlhbCBsb2NhdGlvbnMgdGhhdCBjYW52YXNzZXJzIGNhbiByZWFjaCBvdXQgdG8gYW5kIHBhcnRuZXIsIGluY2x1ZGluZyByZXF1ZXN0aW5nIHN1cHBvcnQgZm9yIGRpc3NlbWluYXRpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gcHJvZ3JhbSwgYXMgd2VsbCBhcyBwdXR0aW5nIHVwIGluZm9ybWF0aW9uYWwgbWF0ZXJpYWwgc3VjaCBhcyBwb3N0ZXJzIGluIHRoZXNlIGxvY2F0aW9ucy4NCg0KT25lIG9mIHRoZSBjZW5zdXMgdHJhaXQgY2hhcmFjdGVyaXN0aWNzIHNob3duIGluIHRoZSBkYXNoYm9hcmQgaXMgbW9zdCBkb21pbmFudCBub24tRW5nbGlzaCBsYW5ndWFnZSBzcG9rZW4gaW4gdGhlIGNlbnN1cyB0cmFjdCwgYWxvbmcgd2l0aCB0aGUgcGVyY2VudGFnZSBvZiByZXNpZGVudHMgd2hvIHNwZWFrIGl0LiBUaGlzIGNhbiBiZSBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBjYW1wYWlnbiBtYW5hZ2VycyB3aGVuIG9yZ2FuaXppbmcgb3V0cmVhY2ggc3RyYXRlZ2llcywgc3VjaCBhcyBlbnN1cmluZyBjYW52YXNzZXJzIHdobyBjYW4gc3BlYWsgdGhhdCBwYXJ0aWN1bGFyIGxhbmd1YWdlIGNvbmR1Y3Qgb3V0cmVhY2ggaW4gdGhlIGFyZWEgdG8gbW9yZSBlZmZlY3RpdmVseSByYWlzZSBhd2FyZW5lc3MgYWJvdXQgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gcHJvZ3JhbSB0byB0aGUgcG90ZW50aWFsIGhvbWVvd25lcnMuDQoNCmBgYHtyIGxhbmd1YWdlX3RyYWN0LGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5zaG93PSdob2xkJ30NCmxhbmd1YWdlX2RhdGEgPC0gc3RfcmVhZCgiLi9EYXRhL3BoaWxseV9sYW5ndWFnZV9kb21pbmFuY2UuZ2VvanNvbiIpDQoNCmxhbmd1YWdlX2NvbG9ycyA8LSBjKA0KICAiU3BhbmlzaCIgPSAiI0U0MUExQyIsDQogICJDaGluZXNlIiA9ICIjMzc3RUI4IiwNCiAgIlZpZXRuYW1lc2UiID0gIiM0REFGNEEiLA0KICAiUnVzc2lhbiBQb2xpc2ggU2xhdmljIiA9ICIjOTg0RUEzIiwNCiAgIkFyYWJpYyIgPSAiI0ZGN0YwMCIsDQogICJLb3JlYW4iID0gIiNGRkQ3MDAiLA0KICAiRnJlbmNoIEhhaXRpYW4gQ2FqdW4iID0gIiNBNjU2MjgiLA0KICAiT3RoZXIgSW5kbyBFdXJvcGVhbiIgPSAiI0Y3ODFCRiIsDQogICJPdGhlciBBc2lhbiBQYWNpZmljIiA9ICIjOTk5OTk5IiwNCiAgIkdlcm1hbiBXZXN0IEdlcm1hbmljIiA9ICIjNjZDMkE1IiwNCiAgIlRhZ2Fsb2ciID0gIiNGQzhENjIiLA0KICAiT3RoZXIgVW5zcGVjaWZpZWQiID0gIiM4REEwQ0IiLA0KICAiTkEiID0gImdyYXk5MCINCikNCg0KZ2dwbG90KGxhbmd1YWdlX2RhdGEpICsNCiAgZ2VvbV9zZihhZXMoZmlsbCA9IGRvbWluYW50X2xhbmd1YWdlKSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMC4xKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBsYW5ndWFnZV9jb2xvcnMpICsgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRG9taW5hbnQgTm9uLUVuZ2xpc2ggTGFuZ3VhZ2UgYnkgUmVnaW9uIiwNCiAgICBmaWxsID0gIkRvbWluYW50IExhbmd1YWdlIiAgDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKyANCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSANCiAgKQ0KYGBgDQoNCmBgYHtyIHByb3BlcnR5X2xhbmd1YWdlLCBldmFsPUZBTFNFfQ0KIyBGaXJzdCByZWFkIGluIGJvdGggZGF0YXNldHMNCmxhbmd1YWdlX2RhdGEgPC0gc3RfcmVhZCgiLi9EYXRhL3BoaWxseV9sYW5ndWFnZV9kb21pbmFuY2UuZ2VvanNvbiIpDQpwcm9wZXJ0aWVzX25vX2V4ZW1wdGlvbiA8LSBzdF9yZWFkKCIuL2RhdGEvcHJvcGVydGllc193aXRob3V0X2V4ZW1wdGlvbl9sYW5ndWFnZV8wNTA1Lmdlb2pzb24iKQ0KDQojIEpvaW4gdGhlIGRhdGFzZXRzLCBrZWVwaW5nIG9ubHkgdGhlIG5ldyBjb2x1bW5zIHdlIHdhbnQgZnJvbSBsYW5ndWFnZV9kYXRhDQpwcm9wZXJ0aWVzX3dpdGhfbGFuZ3VhZ2UgPC0gcHJvcGVydGllc19ub19leGVtcHRpb24gJT4lDQogIGxlZnRfam9pbigNCiAgICBsYW5ndWFnZV9kYXRhICU+JQ0KICAgICAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JSAgIyBEcm9wIGdlb21ldHJ5IHNpbmNlIHdlJ2xsIGtlZXAgdGhlIGdlb21ldHJ5IGZyb20gcHJvcGVydGllcw0KICAgICAgc2VsZWN0KEdFT0lELCBOQU1FLCBkb21pbmFudF9sYW5ndWFnZSwgZG9taW5hbnRfcGN0KSAlPiUNCiAgICAgIHJlbmFtZSh0cmFjdF9uYW1lID0gTkFNRSksICAjIFJlbmFtZSB0byBhdm9pZCBhbnkgY29uZnVzaW9uIHdpdGggb3RoZXIgTkFNRSBjb2x1bW5zDQogICAgYnkgPSAiR0VPSUQiDQogICkNCg0KIyBTdW1tYXJ5IG9mIGRvbWluYW50IGxhbmd1YWdlcyBhY3Jvc3MgYWxsIHRyYWN0cw0KbGFuZ3VhZ2VfZGF0YSAlPiUNCiAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JQ0KICBncm91cF9ieShkb21pbmFudF9sYW5ndWFnZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBudW1iZXJfb2ZfdHJhY3RzID0gbigpLA0KICAgIGF2Z19wZXJjZW50YWdlID0gbWVhbihkb21pbmFudF9wY3QsIG5hLnJtID0gVFJVRSksDQogICAgbWluX3BlcmNlbnRhZ2UgPSBtaW4oZG9taW5hbnRfcGN0LCBuYS5ybSA9IFRSVUUpLA0KICAgIG1heF9wZXJjZW50YWdlID0gbWF4KGRvbWluYW50X3BjdCwgbmEucm0gPSBUUlVFKQ0KICApICU+JQ0KICBhcnJhbmdlKGRlc2MobnVtYmVyX29mX3RyYWN0cykpICU+JQ0KICBtdXRhdGUoDQogICAgcGN0X29mX3RyYWN0cyA9IChudW1iZXJfb2ZfdHJhY3RzIC8gc3VtKG51bWJlcl9vZl90cmFjdHMpICogMTAwKQ0KICApICU+JQ0KICBrbml0cjo6a2FibGUoDQogICAgY29sLm5hbWVzID0gYygNCiAgICAgICJEb21pbmFudCBMYW5ndWFnZSIsDQogICAgICAiTnVtYmVyIG9mIFRyYWN0cyIsDQogICAgICAiQXZlcmFnZSAlIiwNCiAgICAgICJNaW5pbXVtICUiLA0KICAgICAgIk1heGltdW0gJSIsDQogICAgICAiJSBvZiBBbGwgVHJhY3RzIg0KICAgICksDQogICAgZGlnaXRzID0gMSwNCiAgICBjYXB0aW9uID0gIkRpc3RyaWJ1dGlvbiBvZiBEb21pbmFudCBOb24tRW5nbGlzaCBMYW5ndWFnZXMgQWNyb3NzIFBoaWxhZGVscGhpYSBDZW5zdXMgVHJhY3RzIg0KICApICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKA0KICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLA0KICAgIGZvbnRfc2l6ZSA9IDE4LA0KICAgIGZ1bGxfd2lkdGggPSBUUlVFDQogICkgJT4lDQogIGthYmxlRXh0cmE6OnJvd19zcGVjKDAsIGJvbGQgPSBUUlVFLCBmb250X3NpemUgPSAxOSkgICMgTWFrZXMgaGVhZGVyIGxhcmdlcg0KDQojIFRvcCAxMCB0cmFjdHMgd2l0aCBoaWdoZXN0IGxhbmd1YWdlIHBlcmNlbnRhZ2VzDQpsYW5ndWFnZV9kYXRhICU+JQ0KICBzdF9kcm9wX2dlb21ldHJ5KCkgJT4lDQogIGFycmFuZ2UoZGVzYyhkb21pbmFudF9wY3QpKSAlPiUNCiAgaGVhZCgxMCkgJT4lDQogIHNlbGVjdChOQU1FLCBkb21pbmFudF9sYW5ndWFnZSwgZG9taW5hbnRfcGN0KSAlPiUNCiAga25pdHI6OmthYmxlKA0KICAgIGNvbC5uYW1lcyA9IGMoDQogICAgICAiQ2Vuc3VzIFRyYWN0IiwNCiAgICAgICJEb21pbmFudCBMYW5ndWFnZSIsDQogICAgICAiUGVyY2VudGFnZSINCiAgICApLA0KICAgIGRpZ2l0cyA9IDEsDQogICAgY2FwdGlvbiA9ICJUb3AgMTAgQ2Vuc3VzIFRyYWN0cyB3aXRoIEhpZ2hlc3QgTm9uLUVuZ2xpc2ggTGFuZ3VhZ2UgQ29uY2VudHJhdGlvbnMiDQogICkgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoDQogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiksDQogICAgZm9udF9zaXplID0gMTgsDQogICAgZnVsbF93aWR0aCA9IFRSVUUNCiAgKSAlPiUNCiAga2FibGVFeHRyYTo6cm93X3NwZWMoMCwgYm9sZCA9IFRSVUUsIGZvbnRfc2l6ZSA9IDE5KSAgIyBNYWtlcyBoZWFkZXIgbGFyZ2VyDQpgYGANCg0KIyBDb25jbHVzaW9uDQpUaGlzIHByb2plY3QgYWltZWQgdG8gaWRlbnRpZnkgaG9tZW93bmVycyBpbiBQaGlsYWRlbHBoaWEgbGlrZWx5IHRvIGJlIGVsaWdpYmxlIGJ1dCBub3QgeWV0IGVucm9sbGVkIGZvciB0aGUgSG9tZXN0ZWFkIEV4ZW1wdGlvbiBwcm9ncmFtLiBUaHJvdWdoIHRoZSBjcmVhdGlvbiBvZiBhIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwgYW5kIGEgd2ViIGFwcGxpY2F0aW9uIGRhc2hib2FyZCwgdGhlIGhvcGUgaXMgZm9yIHRoaXMgcHJvamVjdCB0byBzdXBwb3J0IGEgZGF0YS1kcml2ZW4gdGFyZ2V0ZWQgb3V0cmVhY2ggYXBwcm9hY2ggdGhhdCBpcyBjb3N0LWVmZmljaWVudCBhbmQgYWJsZSB0byBhbGxvdyBob21lb3duZXJzIHRvIHJlY2VpdmUgdGF4IHNhdmluZ3MuIEl0IHNob3VsZCBiZSBub3RlZCB0aGF0IHRoaXMgY3VycmVudCBtb2RlbCB3YXMgdW5hYmxlIHRvIGZhY3RvciBpbiBleGlzdGluZyBlbnJvbGxtZW50IG9mIGEgcHJvcGVydHkgaW4gdGhlIDEwLXllYXIgcmVzaWRlbnRpYWwgdGF4IGFiYXRlbWVudCBvciBMT09QIHByb2dyYW0sIHdoaWNoIHdvdWxkIG1ha2UgdGhlIHByb2dyYW0gaW5lbGlnaWJsZSBmb3IgdGhlIEhvbWVzdGVhZCBFeGVtcHRpb24gcHJvZ3JhbS4gSWYgZnV0dXJlIGFjY2VzcyB0byB0aGlzIGRhdGEgZnJvbSB0aGUgT2ZmaWNlIG9mIFByb3BlcnR5IEFzc2Vzc21lbnQgY2FuIGJlIG9idGFpbmVkLCB0aGlzIG1heSBpbXByb3ZlIHRoZSBtb2RlbCBmdXJ0aGVyLiBOZXZlcnRoZWxlc3MsIHRoZSBwcm9qZWN0IGhhcyBwcm92aWRlZCBhIG1vZGVsIHdpdGggc3Ryb25nIHBvdGVudGlhbCBhbmQgcHJvdmVuIHRoZSBpbW1lbnNlIGJlbmVmaXRzIHN0b29kIHRvIGJlIGdhaW5lZCBieSBjdXJyZW50bHkgdW5lbnJvbGxlZCBob21lb3duZXJzIGF0IGEgcmVsYXRpdmVseSBsb3cgY29zdCBvZiBvdXRyZWFjaC4gU3VjY2Vzc2Z1bGx5IGlkZW50aWZ5aW5nIHRoZXNlIGhvbWVvd25lcnMgY2FuIGFsc28gYWxsb3cgdGhlIENpdHkgb2YgUGhpbGFkZWxwaGlhIHRvIHByb3ZpZGUgZnVydGhlciBiZW5lZml0cyBzdWNoIGFzIGhvbWUgdXBncmFkaW5nIHN1YnNpZGllcyBmb3IgdGhlc2UgaG9tZW93bmVycy4gVWx0aW1hdGVseSwgaXQgaXMgaG9wZWQgdGhhdCBlbnN1cmluZyBtb3JlIGVsaWdpYmxlIGhvbWVvd25lcnMgYXJlIG1hZGUgYXdhcmUgb2YgYW5kIGNhbiB0YWtlIHVwIHRoZSBIb21lb3duZXIgRXhlbXB0aW9uIHByb2dyYW0gY2FuIG9mZmVyIGdyZWF0ZXIgc3RhYmlsaXR5LCBwcmVzZXJ2ZSBjb21tdW5pdHkgdGllcyBhbmQgcmVkdWNlIGZpbmFuY2lhbCBidXJkZW4gZm9yIHRoZXNlIGhvbWVvd25lcnMuIA==