Thesis: In West Virginia, the strongest predictors of county-level
educational outcomes are average family income and the percentage of
residents with at least a bachelor’s degree.
This analysis examines various data points and factors to predict
educational outcomes at the county level in West Virginia. The
predictors tested for their influence on proficiency rates include
federal, state, and local revenues allocated to each county;
county-level expenditures; unemployment rates; the percentage of
residents with less than a 9th-grade education; the enrollment amount
per each county; the percentage with less than a high school education;
the percentage with at least a bachelor’s degree; and income metrics
such as average vast majority income, average household income, and
average family income. These factors are analyzed to determine their
impact on past proficiency rates and identify the strongest influences
on educational outcomes.
Data Description
The data was gathered from us census websites for West Virginia
counties.
Key variables included:
- enroll: The amount of students enrolled in each
county.
- tfedrev: The amount of federal revenue allocated to
each county.
- tstrev: The amount of state revenue allocated to
each county.
- tlocrev: The amount of local revenue allocated to
each county.
- totalexp: The amount of expenditures utilized by
each county.
- unemployed: The percent of unemployment per each
county.
- less_than_9th_grade_education: The percent of
people in each county with less than a 9th grade education.
- less_than_high_school_grade_education: The percent
of people in each county with less than a high school education.
- at_least_bachelor_education: The percent of people
in each county with at least bachelor’s degree.
- vast_majority_income: The average amount of vast
majority income per each county.
- household_income: The average amount of household
income per each county.
- family_income: The average amount of family income
per each county.
- proficiency: The percent of students that are
educationally proficient per each county.
- proficiency_range: A range of percents of students
that are educationally proficient per each county.
Methods
Load Assessment Data
In this section, the assessment data provided by the professor was
loaded.
Load Spending Data
In this section, the spending data provided by the professor was
loaded.
Load Demographic Data
In this section, the demographic data provided by the professor was
loaded.
Add in New Data
In this section, new data was loaded and cleaned. Additional
educational outcome data, including math proficiency, reading
proficiency, and an average proficiency score, was incorporated.
County-level educational attainment data and income level information
were also added.
Join Data
In this section, the loaded data was merged to create a unified
dataset, facilitating more efficient analysis and ensuring all relevant
variables are accessible for the study.
View Proficiency Data
In this section, a state-level graph was created to visualize
proficiency rates at the county level.

Correlations
In this section, correlation analysis was performed to identify the
factors with the greatest influence on educational proficiency.

Create Test/Training Data
In this section, the data was divided into training and testing sets
to facilitate model training and evaluation.
Linear Regression Model
In this section, a linear regression model was created to predict
educational proficiency levels.
Call:
lm(formula = proficiency ~ at_least_bachelor_education + family_income,
data = t_train)
Residuals:
Min 1Q Median 3Q Max
-6.4377 -2.0840 -0.2013 1.9891 8.5273
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 12.01459814 3.64431128 3.297 0.00200 **
at_least_bachelor_education 0.32319107 0.11888552 2.719 0.00949 **
family_income 0.00017861 0.00007458 2.395 0.02117 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.776 on 42 degrees of freedom
Multiple R-squared: 0.5767, Adjusted R-squared: 0.5566
F-statistic: 28.61 on 2 and 42 DF, p-value: 0.00000001442
View Residuals of Linear Regression Model
In this section, a histogram was created to visualize the
distribution of residuals based on the linear regression model.

PCA
In this section, principal component analysis (PCA) was performed to
identify key patterns in the population.

K-Means
In this section, k-means clustering was performed to group the
population into distinct clusters based on similar patterns.

Decision Tree
In this section, a decision tree was created to classify the
population based on distinct patterns and key factors.

Decision Tree Results
In this section, a confusion matrix was generated to evaluate the
performance of the decision tree by comparing the predicted values with
the actual outcomes.
[1] 0.6363636
18 to 25 25 to 30 30 to 35 35 to 40 40 to 47
18 TO 25 4 0 3 0 0
25 TO 30 5 22 3 2 1
30 TO 35 0 2 5 1 0
35 TO 40 0 0 1 4 2
18 to 25 25 to 30 30 to 35 35 to 40 40 to 47
18 TO 25 0.44444444 0.00000000 0.25000000 0.00000000 0.00000000
25 TO 30 0.55555556 0.91666667 0.25000000 0.28571429 0.33333333
30 TO 35 0.00000000 0.08333333 0.41666667 0.14285714 0.00000000
35 TO 40 0.00000000 0.00000000 0.08333333 0.57142857 0.66666667
Limitations
The timing of the data was inconsistent. My demographic, education,
and income data are based on the most recent information, while the
educational proficiency rate data is a few years older. As a result, the
county-level data may have been different a few years ago, which could
have affected the outcomes. Additionally, there are several factors I
didn’t consider, such as data on incarceration, smoking rates,
non-English speaking populations, and other variables that could
influence proficiency rates.
References
Sources included:
LS0tDQp0aXRsZTogIlIgUHJvamVjdCAzIg0KYXV0aG9yOiAiSm9zaCBGcmVlbWFuIg0KZGF0ZTogIjEyLzgvMjAyNCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjIFRoZXNpczogSW4gV2VzdCBWaXJnaW5pYSwgdGhlIHN0cm9uZ2VzdCBwcmVkaWN0b3JzIG9mIGNvdW50eS1sZXZlbCBlZHVjYXRpb25hbCBvdXRjb21lcyBhcmUgYXZlcmFnZSBmYW1pbHkgaW5jb21lIGFuZCB0aGUgcGVyY2VudGFnZSBvZiByZXNpZGVudHMgd2l0aCBhdCBsZWFzdCBhIGJhY2hlbG9yJ3MgZGVncmVlLiANCg0KVGhpcyBhbmFseXNpcyBleGFtaW5lcyB2YXJpb3VzIGRhdGEgcG9pbnRzIGFuZCBmYWN0b3JzIHRvIHByZWRpY3QgZWR1Y2F0aW9uYWwgb3V0Y29tZXMgYXQgdGhlIGNvdW50eSBsZXZlbCBpbiBXZXN0IFZpcmdpbmlhLiBUaGUgcHJlZGljdG9ycyB0ZXN0ZWQgZm9yIHRoZWlyIGluZmx1ZW5jZSBvbiBwcm9maWNpZW5jeSByYXRlcyBpbmNsdWRlIGZlZGVyYWwsIHN0YXRlLCBhbmQgbG9jYWwgcmV2ZW51ZXMgYWxsb2NhdGVkIHRvIGVhY2ggY291bnR5OyBjb3VudHktbGV2ZWwgZXhwZW5kaXR1cmVzOyB1bmVtcGxveW1lbnQgcmF0ZXM7IHRoZSBwZXJjZW50YWdlIG9mIHJlc2lkZW50cyB3aXRoIGxlc3MgdGhhbiBhIDl0aC1ncmFkZSBlZHVjYXRpb247IHRoZSBlbnJvbGxtZW50IGFtb3VudCBwZXIgZWFjaCBjb3VudHk7IHRoZSBwZXJjZW50YWdlIHdpdGggbGVzcyB0aGFuIGEgaGlnaCBzY2hvb2wgZWR1Y2F0aW9uOyB0aGUgcGVyY2VudGFnZSB3aXRoIGF0IGxlYXN0IGEgYmFjaGVsb3IncyBkZWdyZWU7IGFuZCBpbmNvbWUgbWV0cmljcyBzdWNoIGFzIGF2ZXJhZ2UgdmFzdCBtYWpvcml0eSBpbmNvbWUsIGF2ZXJhZ2UgaG91c2Vob2xkIGluY29tZSwgYW5kIGF2ZXJhZ2UgZmFtaWx5IGluY29tZS4gVGhlc2UgZmFjdG9ycyBhcmUgYW5hbHl6ZWQgdG8gZGV0ZXJtaW5lIHRoZWlyIGltcGFjdCBvbiBwYXN0IHByb2ZpY2llbmN5IHJhdGVzIGFuZCBpZGVudGlmeSB0aGUgc3Ryb25nZXN0IGluZmx1ZW5jZXMgb24gZWR1Y2F0aW9uYWwgb3V0Y29tZXMuDQoNCiMjIERhdGEgRGVzY3JpcHRpb24NCg0KVGhlIGRhdGEgd2FzIGdhdGhlcmVkIGZyb20gdXMgY2Vuc3VzIHdlYnNpdGVzIGZvciBXZXN0IFZpcmdpbmlhIGNvdW50aWVzLiANCg0KS2V5IHZhcmlhYmxlcyBpbmNsdWRlZDoNCg0KLSAqKmVucm9sbCoqOiBUaGUgYW1vdW50IG9mIHN0dWRlbnRzIGVucm9sbGVkIGluIGVhY2ggY291bnR5LiANCi0gKip0ZmVkcmV2Kio6IFRoZSBhbW91bnQgb2YgZmVkZXJhbCByZXZlbnVlIGFsbG9jYXRlZCB0byBlYWNoIGNvdW50eS4NCi0gKip0c3RyZXYqKjogVGhlIGFtb3VudCBvZiBzdGF0ZSByZXZlbnVlIGFsbG9jYXRlZCB0byBlYWNoIGNvdW50eS4NCi0gKip0bG9jcmV2Kio6IFRoZSBhbW91bnQgb2YgbG9jYWwgcmV2ZW51ZSBhbGxvY2F0ZWQgdG8gZWFjaCBjb3VudHkuDQotICoqdG90YWxleHAqKjogVGhlIGFtb3VudCBvZiBleHBlbmRpdHVyZXMgdXRpbGl6ZWQgYnkgZWFjaCBjb3VudHkuDQotICoqdW5lbXBsb3llZCoqOiBUaGUgcGVyY2VudCBvZiB1bmVtcGxveW1lbnQgcGVyIGVhY2ggY291bnR5LiANCi0gKipsZXNzX3RoYW5fOXRoX2dyYWRlX2VkdWNhdGlvbioqOiBUaGUgcGVyY2VudCBvZiBwZW9wbGUgaW4gZWFjaCBjb3VudHkgd2l0aCBsZXNzIHRoYW4gYSA5dGggZ3JhZGUgZWR1Y2F0aW9uLiANCi0gKipsZXNzX3RoYW5faGlnaF9zY2hvb2xfZ3JhZGVfZWR1Y2F0aW9uKio6IFRoZSBwZXJjZW50IG9mIHBlb3BsZSBpbiBlYWNoIGNvdW50eSB3aXRoIGxlc3MgdGhhbiBhIGhpZ2ggc2Nob29sIGVkdWNhdGlvbi4NCi0gKiphdF9sZWFzdF9iYWNoZWxvcl9lZHVjYXRpb24qKjogVGhlIHBlcmNlbnQgb2YgcGVvcGxlIGluIGVhY2ggY291bnR5IHdpdGggYXQgbGVhc3QgYmFjaGVsb3IncyBkZWdyZWUuDQotICoqdmFzdF9tYWpvcml0eV9pbmNvbWUqKjogVGhlIGF2ZXJhZ2UgYW1vdW50IG9mIHZhc3QgbWFqb3JpdHkgaW5jb21lIHBlciBlYWNoIGNvdW50eS4gDQotICoqaG91c2Vob2xkX2luY29tZSoqOiBUaGUgYXZlcmFnZSBhbW91bnQgb2YgaG91c2Vob2xkIGluY29tZSBwZXIgZWFjaCBjb3VudHkuDQotICoqZmFtaWx5X2luY29tZSoqOiBUaGUgYXZlcmFnZSBhbW91bnQgb2YgZmFtaWx5IGluY29tZSBwZXIgZWFjaCBjb3VudHkuDQotICoqcHJvZmljaWVuY3kqKjogVGhlIHBlcmNlbnQgb2Ygc3R1ZGVudHMgdGhhdCBhcmUgZWR1Y2F0aW9uYWxseSBwcm9maWNpZW50IHBlciBlYWNoIGNvdW50eS4gDQotICoqcHJvZmljaWVuY3lfcmFuZ2UqKjogQSByYW5nZSBvZiBwZXJjZW50cyBvZiBzdHVkZW50cyB0aGF0IGFyZSBlZHVjYXRpb25hbGx5IHByb2ZpY2llbnQgcGVyIGVhY2ggY291bnR5LiANCg0KIyMgTWV0aG9kcw0KDQojIyMgTG9hZCBBc3Nlc3NtZW50IERhdGENCg0KSW4gdGhpcyBzZWN0aW9uLCB0aGUgYXNzZXNzbWVudCBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBwcm9mZXNzb3Igd2FzIGxvYWRlZC4gDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KHJwYXJ0KQ0KbGlicmFyeShyZWFkeGwpDQphc3Nlc3NtZW50X3BhdGggPC0gJy4vd3YgZWQgc3R1ZGVudCBhY2hpZXZlbWVudC9IaXN0b3JpY2FsX0Fzc2Vzc21lbnRSZXN1bHRzX1NZMTUtdG8tU1kyMS54bHN4Jw0KDQoNCnRfYXNzZXNzX3Jhd19zY2hvb2wgPC0gcmVhZF9leGNlbChwYXRoID0gYXNzZXNzbWVudF9wYXRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQgPSAnU1kyMSBTY2hvb2wgJiBEaXN0cmljdCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9ICdiMjpmNzMxMicpDQoNCg0KdF9hc3Nlc3NfcmF3X3NjaWVuY2UgPC0gcmVhZF9leGNlbChwYXRoID0gYXNzZXNzbWVudF9wYXRoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQgPSAnU1kyMSBTY2hvb2wgJiBEaXN0cmljdCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9ICdkYjM6ZGI3MzEyJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBjKCdzY2llbmNlX3Byb2ZpY2llbmN5JyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBuYSA9ICcqKicpDQoNCnRfYXNzZXNzIDwtIHRfYXNzZXNzX3Jhd19zY2hvb2wgJT4lDQogIGJpbmRfY29scyh0X2Fzc2Vzc19yYXdfc2NpZW5jZSkgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKHNjaG9vbCA9PSA5OTkpICU+JSANCiAgZmlsdGVyKHBvcHVsYXRpb25fZ3JvdXAgPT0gJ1RvdGFsIFBvcHVsYXRpb24nKSAlPiUgDQogIGZpbHRlcihjb3VudHkgIT0gJ1N0YXRld2lkZScpICU+JSANCiAgbXV0YXRlKHByb2ZpY2llbmN5ID0gc2NpZW5jZV9wcm9maWNpZW5jeSkgIA0KDQpgYGANCg0KIyMjIExvYWQgU3BlbmRpbmcgRGF0YQ0KDQpJbiB0aGlzIHNlY3Rpb24sIHRoZSBzcGVuZGluZyBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBwcm9mZXNzb3Igd2FzIGxvYWRlZC4gDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpzcGVuZGluZ19wYXRoIDwtICcuL3VzIGNlbnN1cyBlZCBzcGVuZGluZy9lbHNlYzIydC54bHMnDQoNCnRfc3BlbmRpbmdfcmF3IDwtIHJlYWRfZXhjZWwocGF0aCA9IHNwZW5kaW5nX3BhdGgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVldCA9ICdlbHNlYzIydCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9ICdhMTpnYjE0MTA2JykgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQoNCg0KY29vcGVyYXRlcyA8LSBjKCdNT1VOVEFJTiBTVEFURSBFRFVDQVRJT05BTCBTRVJWSUNFUyBDT09QRVJBVElWRScsDQogICAgICAgICAgICAgICAgJ0VBU1RFUk4gUEFOSEFORExFIElOU1RSVUNUSU9OQUwgQ09PUEVSQVRJVkUnLA0KICAgICAgICAgICAgICAgICdTT1VUSEVSTiBFRFVDQVRJT05BTCBTRVJWSUNFUyBDT09QRVJBVElWRScpDQoNCnRfc3BlbmRpbmcgPC0gdF9zcGVuZGluZ19yYXcgJT4lIA0KICBmaWx0ZXIoc3RhdGUgPT0gNDkpICU+JSANCiAgZmlsdGVyKCFuYW1lICVpbiUgY29vcGVyYXRlcykgJT4lIA0KICBzZWxlY3QobmFtZSwgZW5yb2xsLCB0ZmVkcmV2LCB0c3RyZXYsIHRsb2NyZXYsIHRvdGFsZXhwLCBwcGNzdG90KSAlPiUgDQogIG11dGF0ZShjb3VudHkgPSBzdHJfdG9fdGl0bGUoc3RyX3NwbGl0X2kobmFtZSwgJyAnLDEpKSwNCiAgICAgICAgIGNvdW50eSA9IGlmZWxzZShjb3VudHkgPT0gJ01jJywgJ01jRG93ZWxsJywgY291bnR5KSkgJT4lIA0KICBtdXRhdGUoY291bnR5ID0gcGFzdGUwKGNvdW50eSwgIiBDb3VudHkiKSkNCg0KYGBgDQoNCiMjIyBMb2FkIERlbW9ncmFwaGljIERhdGENCg0KSW4gdGhpcyBzZWN0aW9uLCB0aGUgZGVtb2dyYXBoaWMgZGF0YSBwcm92aWRlZCBieSB0aGUgcHJvZmVzc29yIHdhcyBsb2FkZWQuIA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KDQp0X2RlbW9ncmFwaGljcyA8LSByZWFkX2NzdignLi9kZW1vZ3JhcGhpY3MvdW5lbXBsb3llZC5jc3YnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYSA9ICdOL0EnKSAlPiUNCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihjb3VudHkgIT0gJ1dlc3QgVmlyZ2luaWEnLA0KICAgICAgICAgY291bnR5ICE9ICdVbml0ZWQgU3RhdGVzJywNCiAgICAgICAgICFpcy5uYSh2YWx1ZV9wZXJjZW50KSApICU+JSANCiAgc2VsZWN0KGNvdW50eSwgdmFsdWVfcGVyY2VudCkgJT4lDQogIHJlbmFtZSh1bmVtcGxveWVkID0gdmFsdWVfcGVyY2VudCkNCg0KYGBgDQoNCiMjIyBBZGQgaW4gTmV3IERhdGENCg0KSW4gdGhpcyBzZWN0aW9uLCBuZXcgZGF0YSB3YXMgbG9hZGVkIGFuZCBjbGVhbmVkLiBBZGRpdGlvbmFsIGVkdWNhdGlvbmFsIG91dGNvbWUgZGF0YSwgaW5jbHVkaW5nIG1hdGggcHJvZmljaWVuY3ksIHJlYWRpbmcgcHJvZmljaWVuY3ksIGFuZCBhbiBhdmVyYWdlIHByb2ZpY2llbmN5IHNjb3JlLCB3YXMgaW5jb3Jwb3JhdGVkLiBDb3VudHktbGV2ZWwgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCBkYXRhIGFuZCBpbmNvbWUgbGV2ZWwgaW5mb3JtYXRpb24gd2VyZSBhbHNvIGFkZGVkLg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkocnBhcnQpDQpsaWJyYXJ5KHJlYWR4bCkNCg0KYXNzZXNzbWVudF9wYXRoIDwtICcuL3d2IGVkIHN0dWRlbnQgYWNoaWV2ZW1lbnQvSGlzdG9yaWNhbF9Bc3Nlc3NtZW50UmVzdWx0c19TWTE1LXRvLVNZMjEueGxzeCcNCg0KDQp0X2Fzc2Vzc19yYXdfc2Nob29sIDwtIHJlYWRfZXhjZWwocGF0aCA9IGFzc2Vzc21lbnRfcGF0aCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0ID0gJ1NZMjEgU2Nob29sICYgRGlzdHJpY3QnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSAnYjI6ZjczMTInKQ0KDQoNCnRfYXNzZXNzX3Jhd19tYXRoIDwtIHJlYWRfZXhjZWwocGF0aCA9IGFzc2Vzc21lbnRfcGF0aCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0ID0gJ1NZMjEgU2Nob29sICYgRGlzdHJpY3QnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSAnYXQzOmF0NzMxMicsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygnbWF0aF9wcm9maWNpZW5jeScpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEgPSAnKionKQ0KDQp0X2Fzc2Vzc19yYXdfcmVhZGluZyA8LSByZWFkX2V4Y2VsKHBhdGggPSBhc3Nlc3NtZW50X3BhdGgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVldCA9ICdTWTIxIFNjaG9vbCAmIERpc3RyaWN0JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlID0gJ2NoMzpjaDczMTInLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9uYW1lcyA9IGMoJ3JlYWRpbmdfcHJvZmljaWVuY3knKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hID0gJyoqJykNCg0KdF9hc3Nlc3MgPC0gdF9hc3Nlc3NfcmF3X3NjaG9vbCAlPiUNCiAgYmluZF9jb2xzKHRfYXNzZXNzX3Jhd19zY2llbmNlKSAlPiUgDQogIGJpbmRfY29scyh0X2Fzc2Vzc19yYXdfbWF0aCkgJT4lIA0KICBiaW5kX2NvbHModF9hc3Nlc3NfcmF3X3JlYWRpbmcpICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihzY2hvb2wgPT0gOTk5KSAlPiUgDQogIGZpbHRlcihwb3B1bGF0aW9uX2dyb3VwID09ICdUb3RhbCBQb3B1bGF0aW9uJykgJT4lIA0KICBmaWx0ZXIoY291bnR5ICE9ICdTdGF0ZXdpZGUnKSAlPiUgDQogIG11dGF0ZShwcm9maWNpZW5jeSA9IChzY2llbmNlX3Byb2ZpY2llbmN5ICsgbWF0aF9wcm9maWNpZW5jeSArIHJlYWRpbmdfcHJvZmljaWVuY3kpIC8gMykgJT4lIA0KICBtdXRhdGUoY291bnR5ID0gcGFzdGUwKGNvdW50eSwgIiBDb3VudHkiKSkNCg0KDQplZHVjYXRpb25fOXRoX3BhdGggPC0gJy4vd3YgZWR1Y2F0aW9uIGRhdGEvV1ZFZHVjYXRpb25MZXNzVGhhbjl0aEdyYWRlLmNzdicNCg0KdF9lZHVjYXRpb25fOXRoIDwtIHJlYWRfY3N2KGVkdWNhdGlvbl85dGhfcGF0aCwNCnNraXAgPSA1LA0KbmEgPSAiTi9BIikgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKGNvdW50eSAhPSAnV2VzdCBWaXJnaW5pYScsDQogICAgICAgICBjb3VudHkgIT0gJ1VuaXRlZCBTdGF0ZXMnLA0KICAgICAgICAgIWlzLm5hKHZhbHVlX3BlcmNlbnQpICkgJT4lIA0KICBzZWxlY3QoY291bnR5LCB2YWx1ZV9wZXJjZW50KSAlPiUNCiAgcmVuYW1lKGxlc3NfdGhhbl85dGhfZ3JhZGVfZWR1Y2F0aW9uID0gdmFsdWVfcGVyY2VudCkNCg0KDQplZHVjYXRpb25faGlnaF9zY2hvb2xfcGF0aCA8LSAnLi93diBlZHVjYXRpb24gZGF0YS9XVkVkdWNhdGlvbkxlc3NUaGFuSGlnaFNjaG9vbC5jc3YnDQoNCnRfZWR1Y2F0aW9uX2hpZ2hfc2Nob29sIDwtIHJlYWRfY3N2KGVkdWNhdGlvbl9oaWdoX3NjaG9vbF9wYXRoLA0Kc2tpcCA9IDUsDQpuYSA9ICJOL0EiKSAlPiUgDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoY291bnR5ICE9ICdXZXN0IFZpcmdpbmlhJywNCiAgICAgICAgIGNvdW50eSAhPSAnVW5pdGVkIFN0YXRlcycsDQogICAgICAgICAhaXMubmEodmFsdWVfcGVyY2VudCkgKSAlPiUgDQogIHNlbGVjdChjb3VudHksIHZhbHVlX3BlcmNlbnQpICU+JQ0KICByZW5hbWUobGVzc190aGFuX2hpZ2hfc2Nob29sX2dyYWRlX2VkdWNhdGlvbiA9IHZhbHVlX3BlcmNlbnQpDQoNCg0KZWR1Y2F0aW9uX2JhY2hlbG9yX3BhdGggPC0gJy4vd3YgZWR1Y2F0aW9uIGRhdGEvV1ZFZHVjYXRpb25BdExlYXN0QmFjaGVsb3JzRGVncmVlLmNzdicNCg0KdF9lZHVjYXRpb25fYmFjaGVsb3IgPC0gcmVhZF9jc3YoZWR1Y2F0aW9uX2JhY2hlbG9yX3BhdGgsDQpza2lwID0gNSwNCm5hID0gIk4vQSIpICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihjb3VudHkgIT0gJ1dlc3QgVmlyZ2luaWEnLA0KICAgICAgICAgY291bnR5ICE9ICdVbml0ZWQgU3RhdGVzJywNCiAgICAgICAgICFpcy5uYSh2YWx1ZV9wZXJjZW50KSApICU+JSANCiAgc2VsZWN0KGNvdW50eSwgdmFsdWVfcGVyY2VudCkgJT4lDQogIHJlbmFtZShhdF9sZWFzdF9iYWNoZWxvcl9lZHVjYXRpb24gPSB2YWx1ZV9wZXJjZW50KQ0KDQoNCmZhbWlseV9pbmNvbWVfcGF0aCA8LSAnLi93diBpbmNvbWUgZGF0YS9XVkZhbWlseUluY29tZS5jc3YnDQoNCnRfZmFtaWx5X2luY29tZSA8LSByZWFkX2NzdihmYW1pbHlfaW5jb21lX3BhdGgsDQpza2lwID0gNCwNCm5hID0gIk4vQSIpICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihjb3VudHkgIT0gJ1dlc3QgVmlyZ2luaWEnLA0KICAgICAgICAgY291bnR5ICE9ICdVbml0ZWQgU3RhdGVzJywNCiAgICAgICAgICFpcy5uYSh2YWx1ZV9kb2xsYXJzKSApICU+JSANCiAgc2VsZWN0KGNvdW50eSwgdmFsdWVfZG9sbGFycykgJT4lDQogIHJlbmFtZShmYW1pbHlfaW5jb21lID0gdmFsdWVfZG9sbGFycykNCg0KDQpob3VzZWhvbGRfaW5jb21lX3BhdGggPC0gJy4vd3YgaW5jb21lIGRhdGEvV1ZIb3VzZWhvbGRJbmNvbWUuY3N2Jw0KDQp0X2hvdXNlaG9sZF9pbmNvbWUgPC0gcmVhZF9jc3YoaG91c2Vob2xkX2luY29tZV9wYXRoLA0Kc2tpcCA9IDQsDQpuYSA9ICJOL0EiKSAlPiUgDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoY291bnR5ICE9ICdXZXN0IFZpcmdpbmlhJywNCiAgICAgICAgIGNvdW50eSAhPSAnVW5pdGVkIFN0YXRlcycsDQogICAgICAgICAhaXMubmEodmFsdWVfZG9sbGFycykgKSAlPiUgDQogIHNlbGVjdChjb3VudHksIHZhbHVlX2RvbGxhcnMpICU+JQ0KICByZW5hbWUoaG91c2Vob2xkX2luY29tZSA9IHZhbHVlX2RvbGxhcnMpDQoNCg0KdmFzdF9tYWpvcml0eV9pbmNvbWVfcGF0aCA8LSAnLi93diBpbmNvbWUgZGF0YS9XVlZhc3RNYWpvcml0eUluY29tZS5jc3YnDQoNCnRfdmFzdF9tYWpvcml0eV9pbmNvbWUgPC0gcmVhZF9jc3YodmFzdF9tYWpvcml0eV9pbmNvbWVfcGF0aCwNCnNraXAgPSA1LA0KbmEgPSAiTi9BIikgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKGNvdW50eSAhPSAnV2VzdCBWaXJnaW5pYScsDQogICAgICAgICBjb3VudHkgIT0gJ1VuaXRlZCBTdGF0ZXMnLA0KICAgICAgICAgIWlzLm5hKHZhbHVlX2RvbGxhcnMpICkgJT4lIA0KICBzZWxlY3QoY291bnR5LCB2YWx1ZV9kb2xsYXJzKSAlPiUNCiAgcmVuYW1lKHZhc3RfbWFqb3JpdHlfaW5jb21lID0gdmFsdWVfZG9sbGFycykNCg0KYGBgDQoNCiMjIyBKb2luIERhdGENCg0KSW4gdGhpcyBzZWN0aW9uLCB0aGUgbG9hZGVkIGRhdGEgd2FzIG1lcmdlZCB0byBjcmVhdGUgYSB1bmlmaWVkIGRhdGFzZXQsIGZhY2lsaXRhdGluZyBtb3JlIGVmZmljaWVudCBhbmFseXNpcyBhbmQgZW5zdXJpbmcgYWxsIHJlbGV2YW50IHZhcmlhYmxlcyBhcmUgYWNjZXNzaWJsZSBmb3IgdGhlIHN0dWR5Lg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocHVycnIpDQoNCnRhYmxlcyA8LSBsaXN0KA0KICB0X2Fzc2VzcywNCiAgdF9kZW1vZ3JhcGhpY3MsDQogIHRfZWR1Y2F0aW9uXzl0aCwNCiAgdF9lZHVjYXRpb25fYmFjaGVsb3IsDQogIHRfZWR1Y2F0aW9uX2hpZ2hfc2Nob29sLA0KICB0X2ZhbWlseV9pbmNvbWUsDQogIHRfaG91c2Vob2xkX2luY29tZSwNCiAgdF9zcGVuZGluZywNCiAgdF92YXN0X21ham9yaXR5X2luY29tZQ0KKQ0KDQp0IDwtIHJlZHVjZSh0YWJsZXMsIGZ1bGxfam9pbiwgYnkgPSAiY291bnR5IikNCg0KdCA8LSB0ICU+JSANCiAgc2VsZWN0KC1zY2hvb2wsIC1zY2hvb2xfbmFtZSwgLXBvcHVsYXRpb25fZ3JvdXAsIC1zdWJncm91cCwgLW5hbWUpDQp0IDwtIHQgJT4lIA0KICBzZWxlY3QoY291bnR5LCBlbnJvbGwsIHRmZWRyZXYsIHRzdHJldiwgdGxvY3JldiwgdG90YWxleHAsIHBwY3N0b3QsIHVuZW1wbG95ZWQsIGxlc3NfdGhhbl85dGhfZ3JhZGVfZWR1Y2F0aW9uLCBsZXNzX3RoYW5faGlnaF9zY2hvb2xfZ3JhZGVfZWR1Y2F0aW9uLCBhdF9sZWFzdF9iYWNoZWxvcl9lZHVjYXRpb24sIHZhc3RfbWFqb3JpdHlfaW5jb21lLCBob3VzZWhvbGRfaW5jb21lLCBmYW1pbHlfaW5jb21lLCBwcm9maWNpZW5jeSkNCg0Kdmlldyh0KQ0KYGBgDQoNCiMjIyBWaWV3IFByb2ZpY2llbmN5IERhdGENCg0KSW4gdGhpcyBzZWN0aW9uLCBhIHN0YXRlLWxldmVsIGdyYXBoIHdhcyBjcmVhdGVkIHRvIHZpc3VhbGl6ZSBwcm9maWNpZW5jeSByYXRlcyBhdCB0aGUgY291bnR5IGxldmVsLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQp0JHN0YXRlIDwtICJXZXN0IFZpcmdpbmlhIg0KDQojIEdldCByZWZlcmVuY2UgRklQUyBkYXRhIGZvciBXZXN0IFZpcmdpbmlhDQpmaXBzX3d2IDwtIHVzbWFwOjpjb3VudHlwb3AgJT4lDQogIGZpbHRlcihhYmJyID09ICJXViIpICU+JQ0KICBzZWxlY3QoZmlwcywgY291bnR5KQ0KDQp0IDwtIGxlZnRfam9pbih0LCBmaXBzX3d2LCBieSA9ICJjb3VudHkiKQ0KDQpsaWJyYXJ5KHVzbWFwKQ0KDQpwbG90X3VzbWFwKGRhdGEgPSB0LCANCiAgICAgICAgICAgdmFsdWVzID0gInByb2ZpY2llbmN5IiwgDQogICAgICAgICAgIGluY2x1ZGUgPSAiV2VzdCBWaXJnaW5pYSIsIA0KICAgICAgICAgICByZWdpb25zID0gImNvdW50aWVzIikgKyAgIyBVc2UgImNvdW50aWVzIiBmb3IgY291bnR5LWxldmVsIG1hcHMNCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKG5hbWUgPSAiUHJvZmljaWVuY3kiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGxvdyA9ICdyZWQnLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2ggPSAnYmx1ZScpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9maWNpZW5jeSBieSBDb3VudHkiKQ0KDQpgYGANCg0KDQojIyMgQ29ycmVsYXRpb25zDQoNCkluIHRoaXMgc2VjdGlvbiwgY29ycmVsYXRpb24gYW5hbHlzaXMgd2FzIHBlcmZvcm1lZCB0byBpZGVudGlmeSB0aGUgZmFjdG9ycyB3aXRoIHRoZSBncmVhdGVzdCBpbmZsdWVuY2Ugb24gZWR1Y2F0aW9uYWwgcHJvZmljaWVuY3kuIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShnZ2NvcnJwbG90KQ0KYyA8LSBjb3IodCAlPiUgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKSkNCg0KZ2djb3JycGxvdChjLCANCiAgICAgICAgICAgaGMub3JkZXIgPSBUUlVFLCANCiAgICAgICAgICAgdHlwZSA9ICJsb3dlciIsIA0KICAgICAgICAgICBsYWIgPSBGQUxTRSwgDQogICAgICAgICAgIGxhYl9zaXplID0gMTAwLCANCiAgICAgICAgICAgbWV0aG9kID0gImNpcmNsZSIpDQoNCmBgYA0KDQojIyMgQ3JlYXRlIFRlc3QvVHJhaW5pbmcgRGF0YQ0KDQpJbiB0aGlzIHNlY3Rpb24sIHRoZSBkYXRhIHdhcyBkaXZpZGVkIGludG8gdHJhaW5pbmcgYW5kIHRlc3Rpbmcgc2V0cyB0byBmYWNpbGl0YXRlIG1vZGVsIHRyYWluaW5nIGFuZCBldmFsdWF0aW9uLiANCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0Kc2FtcGxlIDwtIHNhbXBsZShjKDEsIDApLCBzaXplID0gbnJvdyh0KSwgcmVwbGFjZSA9IFRSVUUsIHByb2IgPSBjKDAuNywgMC4zKSkNCnRfdHJhaW4gPC0gdFtzYW1wbGUgPT0gMSwgXQ0KdF90ZXN0IDwtIHRbc2FtcGxlID09IDAsIF0NCg0KYGBgDQoNCiMjIyBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbA0KDQpJbiB0aGlzIHNlY3Rpb24sIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgd2FzIGNyZWF0ZWQgdG8gcHJlZGljdCBlZHVjYXRpb25hbCBwcm9maWNpZW5jeSBsZXZlbHMuDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkNCg0KdF90cmFpbiRjb3VudHkgPC0gYXMuZmFjdG9yKHRfdHJhaW4kY291bnR5KQ0KdF90ZXN0JGNvdW50eSA8LSBmYWN0b3IodF90ZXN0JGNvdW50eSwgbGV2ZWxzID0gbGV2ZWxzKHRfdHJhaW4kY291bnR5KSkNCg0KDQptb2RlbCA8LSBsbShwcm9maWNpZW5jeSB+ICBhdF9sZWFzdF9iYWNoZWxvcl9lZHVjYXRpb24gKyBmYW1pbHlfaW5jb21lLCBkYXRhID0gdF90cmFpbikNCnN1bW1hcnkobW9kZWwpDQoNCg0KcHJlZGljdGVkX3Byb2ZpY2llbmN5IDwtIHByZWRpY3QobW9kZWwsIG5ld2RhdGEgPSB0X3Rlc3QpDQoNCg0KdF90ZXN0IDwtIHRfdGVzdCAlPiUNCiAgbXV0YXRlKHByZWRpY3Rpb24gPSBwcmVkaWN0ZWRfcHJvZmljaWVuY3ksIA0KICAgICAgICAgcmVzaWR1YWxzID0gcHJvZmljaWVuY3kgLSBwcmVkaWN0aW9uKQ0KDQoNCmBgYA0KDQojIyMgVmlldyBSZXNpZHVhbHMgb2YgTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWwNCg0KSW4gdGhpcyBzZWN0aW9uLCBhIGhpc3RvZ3JhbSB3YXMgY3JlYXRlZCB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMgYmFzZWQgb24gdGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQoNCm1pbl9yZXNpZHVhbCA8LSBmbG9vcihtaW4odF90ZXN0JHJlc2lkdWFscywgbmEucm0gPSBUUlVFKSkNCm1heF9yZXNpZHVhbCA8LSBjZWlsaW5nKG1heCh0X3Rlc3QkcmVzaWR1YWxzLCBuYS5ybSA9IFRSVUUpKQ0KDQoNCmhpc3QodF90ZXN0JHJlc2lkdWFscywgDQogICAgIGJyZWFrcyA9IHNlcShtaW5fcmVzaWR1YWwsIG1heF9yZXNpZHVhbCwgYnkgPSAxKSwgDQogICAgIG1haW4gPSAiSGlzdG9ncmFtIG9mIFJlc2lkdWFscyIsIA0KICAgICB4bGFiID0gIlJlc2lkdWFscyIsIA0KICAgICBjb2wgPSAibGlnaHRibHVlIiwgDQogICAgIGJvcmRlciA9ICJibGFjayIpDQoNCmBgYA0KDQoNCiMjIyBQQ0ENCg0KSW4gdGhpcyBzZWN0aW9uLCBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpIHdhcyBwZXJmb3JtZWQgdG8gaWRlbnRpZnkga2V5IHBhdHRlcm5zIGluIHRoZSBwb3B1bGF0aW9uLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQp0X251bWVyaWMgPC0gdCAlPiUgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKQ0KDQpwY2FfcmVzdWx0cyA8LSBwcmNvbXAodF9udW1lcmljLCBzY2FsZSA9IFRSVUUsIGNlbnRlciA9IFRSVUUsIHJhbmsgPSAyKQ0KDQpwcmludChwY2FfcmVzdWx0cykNCg0KZ2dwbG90KGRhdGEgPSBhcy5kYXRhLmZyYW1lKHBjYV9yZXN1bHRzJHJvdGF0aW9uKSwgDQogICAgICAgYWVzKHggPSBQQzEsIHkgPSBQQzIsIGxhYmVsID0gcm93bmFtZXMocGNhX3Jlc3VsdHMkcm90YXRpb24pKSkgKyANCiAgZ2VvbV90ZXh0KCkgKyANCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIyMgSy1NZWFucw0KDQpJbiB0aGlzIHNlY3Rpb24sIGstbWVhbnMgY2x1c3RlcmluZyB3YXMgcGVyZm9ybWVkIHRvIGdyb3VwIHRoZSBwb3B1bGF0aW9uIGludG8gZGlzdGluY3QgY2x1c3RlcnMgYmFzZWQgb24gc2ltaWxhciBwYXR0ZXJucy4NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeSh1c21hcCkNCg0KdF9rbWVhbnMgPC0gdCAlPiUgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKQ0KDQprcmVzdWx0IDwtIGttZWFucygNCiAgeCA9IHRfa21lYW5zLA0KICBjZW50ZXJzID0gNSwNCiAgbnN0YXJ0ID0gMjANCikNCg0KdCA8LSB0ICU+JQ0KICBtdXRhdGUoa21lYW5zID0gZmFjdG9yKGtyZXN1bHQkY2x1c3RlcikpDQoNCnBsb3RfdXNtYXAoZGF0YSA9IHQsIA0KICAgICAgICAgICB2YWx1ZXMgPSAia21lYW5zIiwgDQogICAgICAgICAgIGluY2x1ZGUgPSAiV2VzdCBWaXJnaW5pYSIsIA0KICAgICAgICAgICByZWdpb25zID0gImNvdW50aWVzIikgKyANCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJLLW1lYW5zIENsdXN0ZXIiLCAgDQogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoInJlZCIsICJibHVlIiwgImdyZWVuIiwgInllbGxvdyIsICJwdXJwbGUiKSkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikgKyANCiAgbGFicyh0aXRsZSA9ICJLLW1lYW5zIENsdXN0ZXJpbmcgb2YgV2VzdCBWaXJnaW5pYSBDb3VudGllcyIpDQoNCg0KYGBgDQoNCg0KIyMjIERlY2lzaW9uIFRyZWUNCg0KSW4gdGhpcyBzZWN0aW9uLCBhIGRlY2lzaW9uIHRyZWUgd2FzIGNyZWF0ZWQgdG8gY2xhc3NpZnkgdGhlIHBvcHVsYXRpb24gYmFzZWQgb24gZGlzdGluY3QgcGF0dGVybnMgYW5kIGtleSBmYWN0b3JzLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJwYXJ0KQ0KbGlicmFyeShycGFydC5wbG90KQ0KDQp0X2R0IDwtIHQgJT4lIA0KICBzZWxlY3QoLWZpcHMsIC1zdGF0ZSwgLWNvdW50eSkgJT4lIA0KICBtdXRhdGUocHJvZmljaWVuY3lfcmFuZ2UgPSBjYXNlX3doZW4oDQogICAgcHJvZmljaWVuY3kgPj0gMTggJiBwcm9maWNpZW5jeSA8IDI1IH4gIjE4IHRvIDI1IiwNCiAgICBwcm9maWNpZW5jeSA+PSAyNSAmIHByb2ZpY2llbmN5IDwgMzAgfiAiMjUgdG8gMzAiLA0KICAgIHByb2ZpY2llbmN5ID49IDMwICYgcHJvZmljaWVuY3kgPCAzNSB+ICIzMCB0byAzNSIsDQogICAgcHJvZmljaWVuY3kgPj0gMzUgJiBwcm9maWNpZW5jeSA8IDQwIH4gIjM1IHRvIDQwIiwNCiAgICBwcm9maWNpZW5jeSA+PSA0MCAmIHByb2ZpY2llbmN5IDw9IDQ3IH4gIjQwIHRvIDQ3IiwNCiAgICBUUlVFIH4gIk91dCBvZiByYW5nZSIgICMgSW4gY2FzZSB0aGVyZSBhcmUgdmFsdWVzIG91dHNpZGUgdGhlIHNwZWNpZmllZCByYW5nZXMNCiAgKSkNCg0KbSA8LSBycGFydChmb3JtdWxhID0gcHJvZmljaWVuY3lfcmFuZ2UgfiBhdF9sZWFzdF9iYWNoZWxvcl9lZHVjYXRpb24gKyBmYW1pbHlfaW5jb21lICsgdGxvY3JldiArIHVuZW1wbG95ZWQsDQogICAgICAgICAgIGRhdGEgPSB0X2R0LA0KICAgICAgICAgICBtaW5zcGxpdCA9IDcsDQogICAgICAgICAgIG1pbmJ1Y2tldCA9IDcsDQogICAgICAgICAgIG1ldGhvZCA9ICJjbGFzcyIpDQoNCiMgU2hvdyByZXN1bHRzIG9mIG1vZGVsDQpycGFydC5wbG90KG0pDQoNCmBgYA0KDQojIyMgRGVjaXNpb24gVHJlZSBSZXN1bHRzDQoNCkluIHRoaXMgc2VjdGlvbiwgYSBjb25mdXNpb24gbWF0cml4IHdhcyBnZW5lcmF0ZWQgdG8gZXZhbHVhdGUgdGhlIHBlcmZvcm1hbmNlIG9mIHRoZSBkZWNpc2lvbiB0cmVlIGJ5IGNvbXBhcmluZyB0aGUgcHJlZGljdGVkIHZhbHVlcyB3aXRoIHRoZSBhY3R1YWwgb3V0Y29tZXMuDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCiMgQ3JlYXRlIHRoZSBwcmVkaWN0ZWQgdmFsdWUgYW5kIGFkZCBpdCB0byBvdXIgdGliYmxlDQpwcmVkaWN0ZWQgPC0gcHJlZGljdChtLCB0X2R0LCB0eXBlID0gJ2NsYXNzJykNCnRfZHQgPC0gbXV0YXRlKCB0X2R0LCANCiAgICAgICAgICAgICBwcmVkaWN0ZWQgPSBwcmVkaWN0ZWQsDQogICAgICAgICAgICAgaXNfY29ycmVjdCA9IHByZWRpY3RlZCA9PSBwcm9maWNpZW5jeV9yYW5nZSkNCg0KIyBQZXJjZW50YWdlIGNvcnJlY3QNCnByaW50KG1lYW4odF9kdCRpc19jb3JyZWN0KSkNCg0KIyBTaG93IGEgY29uZnVzaW9uIG1hdHJpeA0KIyBQcmVkaWN0ZWQgdmFsdWVzIGFyZSBpbiB1cHBlciBjYXNlLg0KdGFibGUoc3RyX3RvX3VwcGVyKHRfZHQkcHJlZGljdGVkKSwgdF9kdCRwcm9maWNpZW5jeV9yYW5nZSkNCnByb3AudGFibGUodGFibGUoc3RyX3RvX3VwcGVyKHRfZHQkcHJlZGljdGVkKSwgdF9kdCRwcm9maWNpZW5jeV9yYW5nZSksIDIpDQpgYGANCiMjIExpbWl0YXRpb25zDQoNClRoZSB0aW1pbmcgb2YgdGhlIGRhdGEgd2FzIGluY29uc2lzdGVudC4gTXkgZGVtb2dyYXBoaWMsIGVkdWNhdGlvbiwgYW5kIGluY29tZSBkYXRhIGFyZSBiYXNlZCBvbiB0aGUgbW9zdCByZWNlbnQgaW5mb3JtYXRpb24sIHdoaWxlIHRoZSBlZHVjYXRpb25hbCBwcm9maWNpZW5jeSByYXRlIGRhdGEgaXMgYSBmZXcgeWVhcnMgb2xkZXIuIEFzIGEgcmVzdWx0LCB0aGUgY291bnR5LWxldmVsIGRhdGEgbWF5IGhhdmUgYmVlbiBkaWZmZXJlbnQgYSBmZXcgeWVhcnMgYWdvLCB3aGljaCBjb3VsZCBoYXZlIGFmZmVjdGVkIHRoZSBvdXRjb21lcy4gQWRkaXRpb25hbGx5LCB0aGVyZSBhcmUgc2V2ZXJhbCBmYWN0b3JzIEkgZGlkbid0IGNvbnNpZGVyLCBzdWNoIGFzIGRhdGEgb24gaW5jYXJjZXJhdGlvbiwgc21va2luZyByYXRlcywgbm9uLUVuZ2xpc2ggc3BlYWtpbmcgcG9wdWxhdGlvbnMsIGFuZCBvdGhlciB2YXJpYWJsZXMgdGhhdCBjb3VsZCBpbmZsdWVuY2UgcHJvZmljaWVuY3kgcmF0ZXMuDQoNCiMjIFJlZmVyZW5jZXMNCg0KU291cmNlcyBpbmNsdWRlZDoNCg0KLSBXZXN0IFZpcmdpbmlhIENvdW50eS1MZXZlbCBJbmNvbWUgRGF0YToNCmh0dHBzOi8vaGRwdWxzZS5uaW1oZC5uaWguZ292L2RhdGEtcG9ydGFsL3NvY2lhbC9tYXA/c29jaWFsdG9waWM9MDMwJnNvY2lhbHRvcGljX29wdGlvbnM9c29jaWFsXzYmZGVtbz0wMDAxMCZkZW1vX29wdGlvbnM9aW5jb21lXzMmcmFjZT0wMCZyYWNlX29wdGlvbnM9cmFjZV83JnNleD0wJnNleF9vcHRpb25zPXNleGJvdGhfMSZhZ2U9MDAxJmFnZV9vcHRpb25zPWFnZWFsbF8xJnN0YXRlZmlwcz01NCZzdGF0ZWZpcHNfb3B0aW9ucz1hcmVhX3N0YXRlcyANCi0gV2VzdCBWaXJnaW5pYSBDb3VudHktTGV2ZWwgRWR1Y2F0aW9uYWwgRGF0YTogaHR0cHM6Ly9oZHB1bHNlLm5pbWhkLm5paC5nb3YvZGF0YS1wb3J0YWwvc29jaWFsL21hcD9zb2NpYWx0b3BpYz0wMjAmc29jaWFsdG9waWNfb3B0aW9ucz1zb2NpYWxfNiZkZW1vPTAwMDA2JmRlbW9fb3B0aW9ucz1lZHVjYXRpb25fMyZyYWNlPTAwJnJhY2Vfb3B0aW9ucz1yYWNlXzcmc2V4PTAmc2V4X29wdGlvbnM9c2V4XzMmYWdlPTA4MSZhZ2Vfb3B0aW9ucz1hZ2UyNV8xJnN0YXRlZmlwcz01NCZzdGF0ZWZpcHNfb3B0aW9ucz1hcmVhX3N0YXRlcw0KLSBDaGF0R1BUOiBodHRwczovL29wZW5haS5jb20vY2hhdGdwdC9vdmVydmlldy8NCkNoYXRHUFQgaGVscGVkIG1lIHRocm91Z2hvdXQgdGhlIHByb2plY3QuIEkgd291bGQgd3JpdGUgdGhlIGNvZGUgYW5kIGFzayBDaGF0R1BUIGZvciBoZWxwIGlmIEkgcmFuIGludG8gcHJvYmxlbXMgb3Igd2Fzbid0IHN1cmUgaG93IHRvIGRvIHNvbWV0aGluZy4gSSBhbHNvIGFza2VkIENoYXRHUFQgZm9yIGFkdmljZSBvbiBob3cgdG8gd29yayBhbmQgYWNoaWV2ZSBteSBvdXRwdXQgZWZmaWNpZW50bHkuIA0K