Warning in read.socrata(https://data.cityofnewyork.us/resource/enfh-gkve.csv): Dates and currency fields will be converted to character

Name typecategory subcategory acres borough geometry
Grand Central Parkway Extension Parkway EXWY 249.389 Q MULTIPOLYGON (((-73.85875 4…
Sunset Cove Park Undeveloped NA 9.375 Q MULTIPOLYGON (((-73.82218 4…
Challenge Playground Jointly Operated Playground JOP 2.035 Q MULTIPOLYGON (((-73.72738 4…
McLaughlin Playground Playground Neighborhood Plgd 0.356 Q MULTIPOLYGON (((-73.76599 4…
Glen Oaks Oval Community Park Neighborhood Plgd 2.948 Q MULTIPOLYGON (((-73.71535 4…

Dataframe used to create map

Name borough typecategory acres geometry
Heritage Park R Neighborhood Park 9.934 MULTIPOLYGON (((-74.12088 4…
Washington Square Park M Neighborhood Park 9.749 MULTIPOLYGON (((-73.99661 4…
Bryant Park M Neighborhood Park 9.603 MULTIPOLYGON (((-73.98341 4…
Bicentennial Veterans Memorial Park X Neighborhood Park 9.395 MULTIPOLYGON (((-73.81338 4…
Haffen Park X Neighborhood Park 9.238 MULTIPOLYGON (((-73.83763 4…

Create map ggplot

Reading layer `Borough Boundaries' from data source 
  `D:\Parson Schoool Of Design\Design Method\Lesson\Week1\Part2\data\processed\geo\Borough Boundaries.geojson' 
  using driver `GeoJSON'
Simple feature collection with 5 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -74.25559 ymin: 40.49613 xmax: -73.70001 ymax: 40.91553
Geodetic CRS:  WGS 84
Reading layer `nynta2020' from data source 
  `D:\Parson Schoool Of Design\Design Method\Lesson\Week1\Part2\data\raw\geo\nynta2020_23c\nynta2020.shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 262 features and 11 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 913175.1 ymin: 120128.4 xmax: 1067383 ymax: 272844.3
Projected CRS: NAD83 / New York Long Island (ftUS)

Dataframe use to analyse data

Name borough typecategory acres geometry
Washington Square Park M Neighborhood Park 9.749 MULTIPOLYGON (((-73.99661 4…
Bryant Park M Neighborhood Park 9.603 MULTIPOLYGON (((-73.98341 4…
Bicentennial Veterans Memorial Park X Neighborhood Park 9.395 MULTIPOLYGON (((-73.81338 4…
Haffen Park X Neighborhood Park 9.238 MULTIPOLYGON (((-73.83763 4…
Central Park M Flagship Park 840.01 MULTIPOLYGON (((-73.95773 4…
Henry Hudson Park X Neighborhood Park 8.972 MULTIPOLYGON (((-73.91974 4…
Castle Hill Park X Neighborhood Park 8.834 MULTIPOLYGON (((-73.84765 4…
City Hall Park M Neighborhood Park 8.8 MULTIPOLYGON (((-74.00749 4…
Aqueduct Walk X Community Park 8.607 MULTIPOLYGON (((-73.91288 4…
Bronx Park X Flagship Park 718.373 MULTIPOLYGON (((-73.87742 4…
Riverside Park South M Community Park 71.933 MULTIPOLYGON (((-73.98716 4…
Sara D. Roosevelt Park M Neighborhood Park 7.85 MULTIPOLYGON (((-73.99219 4…
Ewen Park X Neighborhood Park 7.84 MULTIPOLYGON (((-73.90966 4…
Bridge Park X Neighborhood Park 7.156 MULTIPOLYGON (((-73.92687 4…
Fort Tryon Park M Community Park 67.213 MULTIPOLYGON (((-73.93136 4…
Joyce Kilmer Park X Community Park 6.882 MULTIPOLYGON (((-73.92296 4…
The High Line M Community Park 6.73 MULTIPOLYGON (((-74.00194 4…
J. Hood Wright Park M Neighborhood Park 6.699 MULTIPOLYGON (((-73.9406 40…
Union Square Park M Community Park 6.51 MULTIPOLYGON (((-73.99023 4…
Brigadier General Charles Young Playground M Neighborhood Park 6.423 MULTIPOLYGON (((-73.93439 4…
Concrete Plant Park X Neighborhood Park 6.282 MULTIPOLYGON (((-73.88506 4…
Madison Square Park M Neighborhood Park 6.234 MULTIPOLYGON (((-73.98678 4…
Devoe Park X Neighborhood Park 5.44 MULTIPOLYGON (((-73.90427 4…
John V. Lindsay East River Park M Community Park 45.88 MULTIPOLYGON (((-73.98038 4…
Macombs Dam Park X Community Park 44.174 MULTIPOLYGON (((-73.92698 4…
Ferry Point Park X Flagship Park 413.8 MULTIPOLYGON (((-73.82677 4…
Aqueduct Walk X Community Park 4.926 MULTIPOLYGON (((-73.90295 4…
Grant Park X Neighborhood Park 4.72 MULTIPOLYGON (((-73.91226 4…
Washington’s Walk X Neighborhood Park 4.637 MULTIPOLYGON (((-73.90044 4…
Richman (Echo) Park X Neighborhood Park 4.385 MULTIPOLYGON (((-73.90092 4…
Jerome Park X Neighborhood Park 4.359 MULTIPOLYGON (((-73.88894 4…
Corlears Hook Park M Neighborhood Park 4.355 MULTIPOLYGON (((-73.9803 40…
Asphalt Green M Community Park 4.35 MULTIPOLYGON (((-73.94363 4…
Hamilton Fish Park M Community Park 4.3 MULTIPOLYGON (((-73.97977 4…
Colucci Playground X Neighborhood Park 4.0 MULTIPOLYGON (((-73.83397 4…
Claremont Park X Community Park 38.536 MULTIPOLYGON (((-73.90827 4…
St. Mary’s Park X Community Park 35.311 MULTIPOLYGON (((-73.9107 40…
Stuyvesant Square M Neighborhood Park 3.928 MULTIPOLYGON (((-73.98285 4…
Seward Park M Neighborhood Park 3.361 MULTIPOLYGON (((-73.98883 4…
John Jay Park M Community Park 3.312 MULTIPOLYGON (((-73.94904 4…
University Woods X Neighborhood Park 3.306 MULTIPOLYGON (((-73.91595 4…
Watson Gleason Playground X Neighborhood Park 3.301 MULTIPOLYGON (((-73.86906 4…
Holcombe Rucker Park M Neighborhood Park 3.05 MULTIPOLYGON (((-73.93659 4…
Morningside Park M Community Park 29.888 MULTIPOLYGON (((-73.95846 4…
Pelham Bay Park X Flagship Park 2771.747 MULTIPOLYGON (((-73.80309 4…
Battery Park City M Community Park 26.042 MULTIPOLYGON (((-74.01468 4…
Randall’s Island Park M Flagship Park 254.3 MULTIPOLYGON (((-73.92597 4…
Riverside Park M Community Park 253.168 MULTIPOLYGON (((-73.96103 4…
Recreational Area M Community Park 23.093 MULTIPOLYGON (((-73.94992 4…
St. Nicholas Park M Neighborhood Park 22.74 MULTIPOLYGON (((-73.95044 4…
The Battery M Neighborhood Park 21.88 MULTIPOLYGON (((-74.01637 4…
Soundview Park X Flagship Park 205.31 MULTIPOLYGON (((-73.86982 4…
Marcus Garvey Park M Community Park 20.165 MULTIPOLYGON (((-73.94591 4…
Isham Park M Community Park 20.132 MULTIPOLYGON (((-73.91988 4…
St. Vartan Park M Neighborhood Park 2.759 MULTIPOLYGON (((-73.97313 4…
Louis Cuvillier Park M Neighborhood Park 2.752 MULTIPOLYGON (((-73.93049 4…
Bella Abzug Park M Neighborhood Park 2.633 MULTIPOLYGON (((-74.00066 4…
P.O. Serrano Playground X Neighborhood Park 2.618 MULTIPOLYGON (((-73.84994 4…
Bathgate Playground X Neighborhood Park 2.5 MULTIPOLYGON (((-73.89369 4…
Damrosch Park M Community Park 2.443 MULTIPOLYGON (((-73.98398 4…
Loreto Playground X Community Park 2.181 MULTIPOLYGON (((-73.85137 4…
Harding Park X Neighborhood Park 2.16 MULTIPOLYGON (((-73.8564 40…
Washington Market Park M Neighborhood Park 2.15 MULTIPOLYGON (((-74.01088 4…
Vidalia Park X Neighborhood Park 2.136 MULTIPOLYGON (((-73.88061 4…
Sakura Park M Neighborhood Park 2.067 MULTIPOLYGON (((-73.96216 4…
Inwood Hill Park M Community Park 196.398 MULTIPOLYGON (((-73.92093 4…
Williamsbridge Oval X Neighborhood Park 19.749 MULTIPOLYGON (((-73.8777 40…
Fort Washington Park M Community Park 184.143 MULTIPOLYGON (((-73.94444 4…
Starlight Park X Neighborhood Park 17.064 MULTIPOLYGON (((-73.88159 4…
Franz Sigel Park X Community Park 15.99 MULTIPOLYGON (((-73.92642 4…
Thomas Jefferson Park M Community Park 15.524 MULTIPOLYGON (((-73.93489 4…
Sherman Creek M Neighborhood Park 15.383 MULTIPOLYGON (((-73.9221 40…
Harris Park X Neighborhood Park 15.32 MULTIPOLYGON (((-73.88995 4…
Rev. T. Wendell Foster Park and Recreation Center X Community Park 15.049 MULTIPOLYGON (((-73.9224 40…
Walter Gladwin Park X Neighborhood Park 15.0 MULTIPOLYGON (((-73.89478 4…
Carl Schurz Park M Neighborhood Park 14.938 MULTIPOLYGON (((-73.94198 4…
Highbridge Park M Community Park 130.1 MULTIPOLYGON (((-73.93212 4…
Riverside Park M Neighborhood Park 13.35 MULTIPOLYGON (((-73.95194 4…
Crotona Park X Flagship Park 127.5 MULTIPOLYGON (((-73.88948 4…
Jackie Robinson Park M Neighborhood Park 12.772 MULTIPOLYGON (((-73.93941 4…
Barretto Point Park X Neighborhood Park 12.224 MULTIPOLYGON (((-73.88723 4…
Van Cortlandt Park X Flagship Park 1146.43 MULTIPOLYGON (((-73.8856 40…
Seton Park X Community Park 11.689 MULTIPOLYGON (((-73.9148 40…
Mill Pond Park X Neighborhood Park 11.57 MULTIPOLYGON (((-73.93129 4…
St. James Park X Neighborhood Park 11.39 MULTIPOLYGON (((-73.89611 4…
Tompkins Square Park M Neighborhood Park 10.502 MULTIPOLYGON (((-73.98126 4…
Andrew Haswell Green Park M Neighborhood Park 1.984 MULTIPOLYGON (((-73.95637 4…
Playground One Thirty Four CXXXIV X Neighborhood Park 1.95 MULTIPOLYGON (((-73.91676 4…
Frederick Douglass Playground M Neighborhood Park 1.945 MULTIPOLYGON (((-73.96759 4…
Amelia Gorman Park M Neighborhood Park 1.89 MULTIPOLYGON (((-73.93172 4…
Colgate Close X Neighborhood Park 1.871 MULTIPOLYGON (((-73.88163 4…
Mapes Park X Neighborhood Park 1.868 MULTIPOLYGON (((-73.88506 4…
Bennett Park M Neighborhood Park 1.8 MULTIPOLYGON (((-73.93793 4…
Cedar Playground X Neighborhood Park 1.8 MULTIPOLYGON (((-73.91697 4…
Brust Park X Neighborhood Park 1.79 MULTIPOLYGON (((-73.90324 4…
Alfred E. Smith Playground M Community Park 1.75 MULTIPOLYGON (((-73.99741 4…
East River Esplanade M Neighborhood Park 1.735 MULTIPOLYGON (((-73.9688 40…
James J Walker Park M Neighborhood Park 1.67 MULTIPOLYGON (((-74.00672 4…
Wagner Houses Pool M Community Park 1.64 MULTIPOLYGON (((-73.93163 4…
Percy E. Sutton Playground M Neighborhood Park 1.635 MULTIPOLYGON (((-73.93466 4…
Bellevue South Park M Neighborhood Park 1.593 MULTIPOLYGON (((-73.97742 4…
Battery Park City M Neighborhood Park 1.556 MULTIPOLYGON (((-74.01772 4…
Dry Dock Playground M Community Park 1.5 MULTIPOLYGON (((-73.97524 4…
Luther Gulick Park M Neighborhood Park 1.451 MULTIPOLYGON (((-73.98122 4…
Sheltering Arms Playground M Community Park 1.43 MULTIPOLYGON (((-73.95626 4…
Owen F. Dolen Park X Neighborhood Park 1.4 MULTIPOLYGON (((-73.84301 4…
St. Catherine’s Park M Neighborhood Park 1.383 MULTIPOLYGON (((-73.95842 4…
Melrose Commons Park X Neighborhood Park 1.381 MULTIPOLYGON (((-73.91233 4…
Tanahey Playground M Neighborhood Park 1.254 MULTIPOLYGON (((-73.99601 4…
Stanley Isaacs Playground M Neighborhood Park 1.227 MULTIPOLYGON (((-73.94447 4…
Corporal John A. Seravalli Playground M Neighborhood Park 1.143 MULTIPOLYGON (((-74.00431 4…
Yolanda García Park X Neighborhood Park 1.075 MULTIPOLYGON (((-73.91324 4…
Playground 103 CIII M Neighborhood Park 1.052 MULTIPOLYGON (((-73.93879 4…
West Farms Rapids X Neighborhood Park 1.016 MULTIPOLYGON (((-73.87746 4…
Monsignor Kett Playground M Neighborhood Park 1.0 MULTIPOLYGON (((-73.92047 4…
Captain William Harry Thompson Playground X Neighborhood Park 1.0 MULTIPOLYGON (((-73.87723 4…
Blake Hobbs Playground M Neighborhood Park 1.0 MULTIPOLYGON (((-73.94364 4…
Martin Luther King, Jr. Playground M Neighborhood Park 1.0 MULTIPOLYGON (((-73.9509 40…
Ruppert Park M Neighborhood Park 0.997 MULTIPOLYGON (((-73.94998 4…
Garrison Park X Neighborhood Park 0.995 MULTIPOLYGON (((-73.88443 4…
Abraham Lincoln Playground M Community Park 0.991 MULTIPOLYGON (((-73.93683 4…
Rock Garden Park X Neighborhood Park 0.977 MULTIPOLYGON (((-73.88471 4…
Ranaqua Playground X Neighborhood Park 0.972 MULTIPOLYGON (((-73.92192 4…
Mae Grant Playground M Neighborhood Park 0.97 MULTIPOLYGON (((-73.94896 4…
Cherry Tree Park M Neighborhood Park 0.95 MULTIPOLYGON (((-73.94706 4…
Fox Park X Neighborhood Park 0.94 MULTIPOLYGON (((-73.89784 4…
Estella Diggs Park X Neighborhood Park 0.919 MULTIPOLYGON (((-73.90566 4…
Virginia Park X Neighborhood Park 0.918 MULTIPOLYGON (((-73.86202 4…
Estella Diggs Park X Neighborhood Park 0.903 MULTIPOLYGON (((-73.90566 4…
Highbridge Park X Neighborhood Park 0.82 MULTIPOLYGON (((-73.9263 40…
Risse Street Park X Neighborhood Park 0.806 MULTIPOLYGON (((-73.88534 4…
Vladeck Park M Neighborhood Park 0.789 MULTIPOLYGON (((-73.98182 4…
First Park M Neighborhood Park 0.763 MULTIPOLYGON (((-73.99042 4…
Samuel N. Bennerson 2nd Playground M Neighborhood Park 0.749 MULTIPOLYGON (((-73.98653 4…
Railroad Park X Neighborhood Park 0.732 MULTIPOLYGON (((-73.91487 4…
Mapes Pool X Neighborhood Park 0.68 MULTIPOLYGON (((-73.88576 4…
Canal Park M Neighborhood Park 0.669 MULTIPOLYGON (((-74.01078 4…
O’Neill Triangle X Neighborhood Park 0.636 MULTIPOLYGON (((-73.91094 4…
Vesuvio Playground M Neighborhood Park 0.635 MULTIPOLYGON (((-74.00264 4…
Dr. Ronald E. McNair Playground M Neighborhood Park 0.603 MULTIPOLYGON (((-73.93788 4…
Penn South Playground M Neighborhood Park 0.6 MULTIPOLYGON (((-73.99827 4…
Peter Detmold Park M Neighborhood Park 0.588 MULTIPOLYGON (((-73.96439 4…
Hell’s Kitchen Park M Neighborhood Park 0.576 MULTIPOLYGON (((-73.99238 4…
Fiorello La Guardia Park M Neighborhood Park 0.545 MULTIPOLYGON (((-73.99773 4…
Dr. Gertrude B. Kelly Playground M Neighborhood Park 0.525 MULTIPOLYGON (((-74.00198 4…
Clement Clarke Moore Park M Neighborhood Park 0.489 MULTIPOLYGON (((-74.00388 4…
Charlton Garden X Neighborhood Park 0.488 MULTIPOLYGON (((-73.90682 4…
Bleecker Playground M Neighborhood Park 0.477 MULTIPOLYGON (((-74.00543 4…
Robert L. Clinkscales Playground and Community Garden M Neighborhood Park 0.436 MULTIPOLYGON (((-73.93969 4…
Hunts Point Riverside Park X Neighborhood Park 0.426 MULTIPOLYGON (((-73.88141 4…
Joseph C. Sauer Park M Neighborhood Park 0.403 MULTIPOLYGON (((-73.97938 4…
Harlem Art Park M Neighborhood Park 0.347 MULTIPOLYGON (((-73.93847 4…
Rev Lena Irons Unity Park X Neighborhood Park 0.342 MULTIPOLYGON (((-73.90636 4…
Rapkin-Gayle Plaza M Neighborhood Park 0.287 MULTIPOLYGON (((-73.99943 4…
Sutton Place Park M Neighborhood Park 0.268 MULTIPOLYGON (((-73.95996 4…
Detective Omar Edwards Park M Neighborhood Park 0.252 MULTIPOLYGON (((-73.93495 4…
Eae J Mitchell Park X Neighborhood Park 0.183 MULTIPOLYGON (((-73.88417 4…

Race analysis in Manhattan & The Bronx Import the raw data of Asian Ancestry from the American Community Survey

Create map by using ggplot

Import Neighborhood Tabulation Areas for NYC

Asian ancestry statistic in each borough

Import the raw data of Hispanic Ancestry from the American Community Survey

Create map by using ggplot

st_crs(hispanic)to print in console the projections of data frame

Import the raw data of Black Ancestry from the American Community Survey

Create map by using ggplot

st_crs(black)to print in console the projections of data frame

Import Neighborhood Tabulation Areas for NYC

Black ancestry statistic in each borough

Import the raw data of White Ancestry from the American Community Survey

Create map by using ggplot

Import Neighborhood Tabulation Areas for NYC

White ancestry statistic in each borough

Median Household Income

LS0tDQp0aXRsZTogIkZpbmFsIFByb2plY3QtUHVibGljIFBhcmsgTWFuaGF0dGFuLSBCcm9ueCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RiwgZWNobz1GQUxTRSwgcXVpZXRseT1UKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KFJTb2NyYXRhKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeSh0aWR5Y2Vuc3VzKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHZpcmlkaXMpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkocGxvdGx5KQ0Kb3B0aW9ucyhzY2llcGVuID0gOTk5KQ0KDQojICMgaW1wb3J0IHRoZSBkYXRhIGRpcmVjdGx5IGludG8gUlN0dWRpbyB1c2luZyB1cmwgcGF0aA0KIyBkYXRhIDwtIHJlYWQuc29jcmF0YSgiaHR0cHM6Ly9kYXRhLmNpdHlvZm5ld3lvcmsudXMvcmVzb3VyY2UvZW5maC1na3ZlLmNzdiIpDQojIA0KIyAjQ29udmVydGluZyB0byBzcGF0aWFsIGRhdGFmcmFtZQ0KIyBkYXRhX3NmIDwtIHN0X2FzX3NmKGRhdGEsIHdrdCA9ICJtdWx0aXBvbHlnb24iKQ0KDQpkYXRhX3NmIDwtIHN0X3JlYWQoIkM6L1VzZXJzL0NoZXkgU29jaGVhdGEvRG93bmxvYWRzL1BhcmtzIFByb3BlcnRpZXNfMjAyMzEyMDEuZ2VvanNvbiIpDQoNCmBgYA0KDQpXYXJuaW5nIGluIHJlYWQuc29jcmF0YSg8aHR0cHM6Ly9kYXRhLmNpdHlvZm5ld3lvcmsudXMvcmVzb3VyY2UvZW5maC1na3ZlLmNzdj4pOiBEYXRlcyBhbmQgY3VycmVuY3kgZmllbGRzIHdpbGwgYmUgY29udmVydGVkIHRvIGNoYXJhY3Rlcg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCiMgc2VsZWN0ZWQgdmFyaWFibGVzIChjb2x1bW5zKQ0KY29sdW1ucyA8LWMoIm5hbWUzMTEiLCAidHlwZWNhdGVnb3J5IiwgInN1YmNhdGVnb3J5IiwgImFjcmVzIiwiYm9yb3VnaCIsICJhZGRyZXNzIiwgImNsYXNzIiwgImxvY2F0aW9uIiwiZWFwcGx5IiwgImNvdW5jaWxkaXN0cmljdCIsICJjb21tdW5pdHlib2FyZCIsICJ1cmwiLCAiemlwY29kZSIsICJhY3F1aXNpdGlvbmRhdGUiKSAgIyMjIEkgcmVtb3ZlZCB0aGUgbXVsdGlwb2x5Z29uIGZvcm0gdGhlIGxpc3Qgb2YgY29sdW1ucyB0byBrZWVwIHNpbmNlIGl0IGlzIG5vdCBpbiB0aGUgZGF0YV9zZg0KbXlkYXRhIDwtIGRhdGFfc2YgfD4gDQogIHNlbGVjdChhbGxfb2YoY29sdW1ucykpfD4NCnJlbmFtZShOYW1lID0gbmFtZTMxMSkNCg0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KIG15ZGF0YSB8Pg0Kc2VsZWN0KDE6NSkgfD4NCnNsaWNlKDE6NSkgfD4ga2FibGUoKQ0KYGBgDQoNCkRhdGFmcmFtZSB1c2VkIHRvIGNyZWF0ZSBtYXANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpQYXJrcyA8LSBteWRhdGEgfD4gDQogIGZpbHRlcih0eXBlY2F0ZWdvcnkgPT0gIkZsYWdzaGlwIFBhcmsifHR5cGVjYXRlZ29yeSA9PSAiQ29tbXVuaXR5IFBhcmsiIHwgdHlwZWNhdGVnb3J5ID09Ik5laWdoYm9yaG9vZCBQYXJrIiApIHw+DQogIHNlbGVjdChjKE5hbWUsYm9yb3VnaCx0eXBlY2F0ZWdvcnksYWNyZXMpKSB8PiANCiAgYXJyYW5nZShkZXNjKGFjcmVzKSkNCiBQYXJrcyB8Pg0Kc2VsZWN0KDE6NSkgfD4NCnNsaWNlKDE6NSkgfD4ga2FibGUoKQ0KDQpgYGANCg0KQ3JlYXRlIG1hcCBnZ3Bsb3QNCg0KYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0NCiMjIGltcG9ydCBib3JvdWdoIHNoYXBlZmlsZXMgZnJvbSBOWUMgT3BlbiBEYXRhDQpib3JvcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9wcm9jZXNzZWQvZ2VvL0Jvcm91Z2ggQm91bmRhcmllcy5nZW9qc29uIikgDQpgYGANCg0KYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0NCiMjIGltcG9ydCBOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhcyBmb3IgTllDDQpuYWJlcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9yYXcvZ2VvL255bnRhMjAyMF8yM2MvbnludGEyMDIwLnNocCIpIA0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KZ2dwbG90KGRhdGEgPSBQYXJrcykgICsgDQogIGdlb21fc2YoZmlsbCA9ICIjMWQ4NTM5IiwgDQogICAgICAgICAgbHdkID0gMCkgKw0KICB0aGVtZV92b2lkKCkgKw0KICAjc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwgLjIsIC40LCAuNiwgLjgsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgICAjZGlyZWN0aW9uID0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgI25hLnZhbHVlID0gInRyYW5zcGFyZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgI25hbWU9Ik5ZQyBQdWJsaWMgUGFya3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAjbGFiZWxzID0gYWNyZXMgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiTllDIFB1YmxpYyBQYXJrcyIsDQogICAgY2FwdGlvbiA9ICJTb3VyY2U6IE5ZQyBPcGVuIERhdGEiDQogICkgKyANCiAgZ2VvbV9zZihkYXRhID0gbmFiZXMsIGNvbG9yID0gImdyYXkiLCBmaWxsID0gTkEsIGx3ZCA9IDAuMjUpICsNCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MsICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjUpDQpgYGANCg0KRGF0YWZyYW1lIHVzZSB0byBhbmFseXNlIGRhdGENCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpQYXJrc2RmIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoUGFya3MpIA0KDQpwYXJrc3N1bW1hcnkgPC0gUGFya3NkZiB8Pg0KICBncm91cF9ieShib3JvdWdoKXw+DQogIHN1bW1hcmlzZShDb3VudD1uKCksIA0KICAgICAgICAgICAgc3VtYWNyZXM9c3VtKGFjcmVzKSwNCiAgICAgICAgICAgIG1lYW5hY3Jlcz1tZWFuKGFjcmVzKSkNCg0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KUGFya3NNWCA8LSBteWRhdGEgfD4NCiAgZmlsdGVyKGJvcm91Z2ggPT0gIk0ifGJvcm91Z2ggPT0gIlgiICkgfD4NCiAgZmlsdGVyKHR5cGVjYXRlZ29yeSA9PSAiRmxhZ3NoaXAgUGFyayJ8dHlwZWNhdGVnb3J5ID09ICJDb21tdW5pdHkgUGFyayIgfCB0eXBlY2F0ZWdvcnkgPT0iTmVpZ2hib3Job29kIFBhcmsiICkgfD4NCiAgc2VsZWN0KGMoTmFtZSxib3JvdWdoLHR5cGVjYXRlZ29yeSxhY3JlcykpIHw+IA0KICBhcnJhbmdlKGRlc2MoYWNyZXMpKSAgDQpCb3JvdWdoTVggPC1ib3JvcyB8Pg0KICBmaWx0ZXIoYm9yb19uYW1lID09ICJNYW5oYXR0YW4ifGJvcm9fbmFtZSA9PSAiQnJvbngiICkNCm5hYmVzTVggPC1uYWJlcyB8Pg0KICBmaWx0ZXIoQm9yb05hbWUgPT0gIk1hbmhhdHRhbiJ8Qm9yb05hbWUgPT0gIkJyb254IiApDQogICANCmthYmxlKFBhcmtzTVgpDQoNCmdncGxvdChkYXRhID0gUGFya3NNWCkgICsgDQogIGdlb21fc2YoZmlsbCA9ICIjMWQ4NTM5IiwgDQogICAgICAgICAgbHdkID0gMCkgKw0KICB0aGVtZV92b2lkKCkgKw0KICAjc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwgLjIsIC40LCAuNiwgLjgsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgICAjZGlyZWN0aW9uID0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgI25hLnZhbHVlID0gInRyYW5zcGFyZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgI25hbWU9Ik5ZQyBQdWJsaWMgUGFya3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAjbGFiZWxzID0gYWNyZXMgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiTllDIFB1YmxpYyBQYXJrcyIsDQogICAgY2FwdGlvbiA9ICJTb3VyY2U6IE5ZQyBPcGVuIERhdGEiDQogICkgKyANCiAgZ2VvbV9zZihkYXRhID0gbmFiZXNNWCwgY29sb3IgPSAiZ3JheSIsIGZpbGwgPSBOQSwgbHdkID0gMC4yNSkgKw0KICBnZW9tX3NmKGRhdGEgPSBCb3JvdWdoTVgsICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjUpDQoNCmBgYA0KDQpSYWNlIGFuYWx5c2lzIGluIE1hbmhhdHRhbiAmIFRoZSBCcm9ueCBJbXBvcnQgdGhlIHJhdyBkYXRhIG9mIEFzaWFuIEFuY2VzdHJ5IGZyb20gdGhlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQojIyMjIGltcG9ydCBib3JvdWdoIHNoYXBlZmlsZXMgZnJvbSBOWUMgT3BlbiBEYXRhDQpib3JvcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9wcm9jZXNzZWQvZ2VvL0Jvcm91Z2ggQm91bmRhcmllcy5nZW9qc29uIikNCg0KcmF3X2FuY2VzdHJ5IDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSBjKGFuY2VzdHJ5X3BvcCA9ICJCMDQwMDZfMDAxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNpYW4gPSAiQjAyMDAxXzAwNSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPSdOWScsDQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudHkgPSBjKCdCcm9ueCcsJ05ldyBZb3JrJyksDQogICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjAsDQogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpIA0KDQphc2lhbiA8LSByYXdfYW5jZXN0cnkgfD4gDQogIG11dGF0ZShwY3RfYXNpYW4gPSBhc2lhbkUvYW5jZXN0cnlfcG9wRSkgfD4gDQogIGZpbHRlcihhbmNlc3RyeV9wb3BFID4gMCkNCg0KYGBgDQoNCkNyZWF0ZSBtYXAgYnkgdXNpbmcgZ2dwbG90DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KYXNpYW5fbWFwIDwtIHN1cHByZXNzV2FybmluZ3MoIGdncGxvdCgpICArIA0KICBnZW9tX3NmKGRhdGEgPSBhc2lhbiwgDQogICAgICAgICAgbWFwcGluZyA9IGFlcyhmaWxsID0gcGN0X2FzaWFuLA0KICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMChOQU1FLCAiOiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGVyY2VudCBBc2lhbiBhbmNlc3RyeTogIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyY2VudChwY3RfYXNpYW4sIGFjY3VyYWN5PTEpKSksDQogICAgICAgICAgY29sb3IgPSAidHJhbnNwYXJlbnQiKSArDQogIHRoZW1lX3ZvaWQoKSArDQogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKGJyZWFrcz1jKDAsIC4yLCAuNCwgLjYsIC44LCAxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAiI2ZhZmFmYSIsDQogICAgICAgICAgICAgICAgICAgICAgICMgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLA0KICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJQZXJjZW50IEFzaWFuIEFuY2VzdHJ5ICglKSIsDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1wZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkFzaWFuIEFuY2VzdHJ5IGJ5IENlbnN1cyBUcmFjdCIsDQogICAgY2FwdGlvbiA9ICJTb3VyY2U6IEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXksIDIwMTYtMjAiDQogICkpDQpnZ3Bsb3RseShhc2lhbl9tYXAsIHRvb2x0aXAgPSAidGV4dCIpDQpgYGANCg0KSW1wb3J0IE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWFzIGZvciBOWUMNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpuYWJlcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9yYXcvZ2VvL255bnRhMjAyMF8yM2MvbnludGEyMDIwLnNocCIpDQpzdF9jcnMobmFiZXMpDQoNCmFzaWFuXzIyNjMgPC0gc3RfdHJhbnNmb3JtKGFzaWFuLCAyMjYzKQ0Kc3RfY3JzKGFzaWFuXzIyNjMpDQoNCiNyZW1vdmUgdW5uZWNlc3NhcnkgZmllbGRzIGluIHRoZSBuZWlnaGJvcmhvb2Qgc2hhcGVmaWxlDQpuYWJlc19zZWxlY3RlZCA8LSBuYWJlcyB8Pg0KICBzZWxlY3QoQm9yb0NvZGUsIEJvcm9OYW1lLCBOVEEyMDIwLCBOVEFOYW1lKQ0KDQphc2lhbl9uYWJlcyA8LSBhc2lhbl8yMjYzIHw+DQogIHN0X2pvaW4obmFiZXNfc2VsZWN0ZWQsIA0KICAgICAgICAgIGxlZnQgPSBUUlVFLA0KICAgICAgICAgIGpvaW4gPSBzdF9pbnRlcnNlY3RzLA0KICAgICAgICAgIGxhcmdlc3QgPSBUKQ0KYGBgDQoNCkFzaWFuIGFuY2VzdHJ5IHN0YXRpc3RpYyBpbiBlYWNoIGJvcm91Z2gNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQphc2lhbl9uYWJlX3N0YXRzIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoYXNpYW5fbmFiZXMpIHw+IA0KICBncm91cF9ieShOVEFOYW1lKSB8PiANCiAgc3VtbWFyaXNlKEJvcm91Z2ggPSBmaXJzdChCb3JvTmFtZSksDQogICAgICAgICAgICBgRXN0LiBUb3RhbCBQb3B1bGF0aW9uYCA9IHN1bShhbmNlc3RyeV9wb3BFKSwNCiAgICAgICAgICAgIGBFc3QuIFRvdGFsIEFzaWFuIFBvcHVsYXRpb25gID0gc3VtKGFzaWFuTSkpIHw+IA0KICBtdXRhdGUoYEVzdC4gUGVyY2VudCBBc2lhbiBBbmNlc3RyeWAgPSBwZXJjZW50KGBFc3QuIFRvdGFsIEFzaWFuIFBvcHVsYXRpb25gL2BFc3QuIFRvdGFsIFBvcHVsYXRpb25gLCBhY2N1cmFjeSA9IDEpKSANCmBgYA0KDQpJbXBvcnQgdGhlIHJhdyBkYXRhIG9mIEhpc3BhbmljIEFuY2VzdHJ5IGZyb20gdGhlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQojIyMjIGltcG9ydCBib3JvdWdoIHNoYXBlZmlsZXMgZnJvbSBOWUMgT3BlbiBEYXRhDQpib3JvcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9wcm9jZXNzZWQvZ2VvL0Jvcm91Z2ggQm91bmRhcmllcy5nZW9qc29uIikNCg0KcmF3X2FuY2VzdHJ5IDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSBjKGFuY2VzdHJ5X3BvcCA9ICJCMDQwMDZfMDAxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlzcGFuaWMgPSAiQjAzMDAxXzAwMyIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPSdOWScsDQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudHkgPSBjKCdCcm9ueCcsJ05ldyBZb3JrJyksDQogICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjAsDQogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpIA0KDQpoaXNwYW5pYyA8LSByYXdfYW5jZXN0cnkgfD4gDQogIG11dGF0ZShwY3RfaGlzcGFuaWMgPSBoaXNwYW5pY0UvYW5jZXN0cnlfcG9wRSkgfD4gDQogIGZpbHRlcihhbmNlc3RyeV9wb3BFID4gMCkNCmBgYA0KDQpDcmVhdGUgbWFwIGJ5IHVzaW5nIGdncGxvdA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCmhpc3BhbmljX21hcCA8LSBnZ3Bsb3QoKSAgKyANCiAgZ2VvbV9zZihkYXRhID0gaGlzcGFuaWMsIA0KICAgICAgICAgIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF9oaXNwYW5pYywNCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoTkFNRSwgIjoiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlBlcmNlbnQgSGlzcGFuaWMgYW5jZXN0cnk6ICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQocGN0X2hpc3BhbmljLCBhY2N1cmFjeT0xKSkpLA0KICAgICAgICAgIGNvbG9yID0gInRyYW5zcGFyZW50IikgKw0KICB0aGVtZV92b2lkKCkgKw0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksDQogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiT3JhbmdlcyIsDQogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gIiNHcmVlbnMiLA0KICAgICAgICAgICAgICAgICAgICAgICAjIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iUGVyY2VudCBIaXNwYW5pYyBBbmNlc3RyeSAoJSkiLA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJIaXNwYW5pYyBBbmNlc3RyeSBieSBDZW5zdXMgVHJhY3QiLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5LCAyMDE2LTIwIg0KICApDQpnZ3Bsb3RseShoaXNwYW5pY19tYXAsIHRvb2x0aXAgPSAidGV4dCIpDQoNCmBgYA0KDQpzdF9jcnMoaGlzcGFuaWMpdG8gcHJpbnQgaW4gY29uc29sZSB0aGUgcHJvamVjdGlvbnMgb2YgZGF0YSBmcmFtZQ0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCm5hYmVzIDwtIHN0X3JlYWQoIkQ6L1BhcnNvbiBTY2hvb29sIE9mIERlc2lnbi9EZXNpZ24gTWV0aG9kL0xlc3Nvbi9XZWVrMS9QYXJ0Mi9kYXRhL3Jhdy9nZW8vbnludGEyMDIwXzIzYy9ueW50YTIwMjAuc2hwIikNCnN0X2NycyhuYWJlcykNCg0KaGlzcGFuaWNfMjI2MyA8LSBzdF90cmFuc2Zvcm0oaGlzcGFuaWMsIDIyNjMpDQpzdF9jcnMoaGlzcGFuaWNfMjI2MykNCg0KI3JlbW92ZSB1bm5lY2Vzc2FyeSBmaWVsZHMgaW4gdGhlIG5laWdoYm9yaG9vZCBzaGFwZWZpbGUNCm5hYmVzX3NlbGVjdGVkIDwtIG5hYmVzIHw+DQogIHNlbGVjdChCb3JvQ29kZSwgQm9yb05hbWUsIE5UQTIwMjAsIE5UQU5hbWUpDQoNCmhpc3BhbmljX25hYmVzIDwtIGhpc3BhbmljXzIyNjMgfD4NCiAgc3Rfam9pbihuYWJlc19zZWxlY3RlZCwgDQogICAgICAgICAgbGVmdCA9IFRSVUUsDQogICAgICAgICAgam9pbiA9IHN0X2ludGVyc2VjdHMsDQogICAgICAgICAgbGFyZ2VzdCA9IFQpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpoaXNwYW5pY19uYWJlX3N0YXRzIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoaGlzcGFuaWNfbmFiZXMpIHw+IA0KICBncm91cF9ieShOVEFOYW1lKSB8PiANCiAgc3VtbWFyaXNlKEJvcm91Z2ggPSBmaXJzdChCb3JvTmFtZSksDQogICAgICAgICAgICBgRXN0LiBUb3RhbCBQb3B1bGF0aW9uYCA9IHN1bShhbmNlc3RyeV9wb3BFKSwNCiAgICAgICAgICAgIGBFc3QuIFRvdGFsIEhpc3BhbmljIFBvcHVsYXRpb25gID0gc3VtKGhpc3BhbmljTSkpIHw+IA0KICBtdXRhdGUoYEVzdC4gUGVyY2VudCBIaXNwYW5pYyBBbmNlc3RyeWAgPSBwZXJjZW50KGBFc3QuIFRvdGFsIEhpc3BhbmljIFBvcHVsYXRpb25gL2BFc3QuIFRvdGFsIFBvcHVsYXRpb25gLCBhY2N1cmFjeSA9IDEpKSANCmBgYA0KDQpJbXBvcnQgdGhlIHJhdyBkYXRhIG9mIEJsYWNrIEFuY2VzdHJ5IGZyb20gdGhlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpib3JvcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9wcm9jZXNzZWQvZ2VvL0Jvcm91Z2ggQm91bmRhcmllcy5nZW9qc29uIikNCg0KcmF3X2FuY2VzdHJ5IDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSBjKGFuY2VzdHJ5X3BvcCA9ICJCMDQwMDZfMDAxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxhY2sgPSAiQjAyMDAxXzAwMyIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPSdOWScsDQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudHkgPSBjKCdCcm9ueCcsJ05ldyBZb3JrJyksDQogICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjAsDQogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpIA0KDQpibGFjayA8LSByYXdfYW5jZXN0cnkgfD4gDQogIG11dGF0ZShwY3RfYmxhY2sgPSBibGFja0UvYW5jZXN0cnlfcG9wRSkgfD4gDQogIGZpbHRlcihhbmNlc3RyeV9wb3BFID4gMCkNCmBgYA0KDQpDcmVhdGUgbWFwIGJ5IHVzaW5nIGdncGxvdA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCmJsYWNrX21hcCA8LSBnZ3Bsb3QoKSAgKyANCiAgZ2VvbV9zZihkYXRhID0gYmxhY2ssIA0KICAgICAgICAgIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF9ibGFjaywNCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoTkFNRSwgIjoiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlBlcmNlbnQgQmxhY2sgYW5jZXN0cnk6ICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQocGN0X2JsYWNrLCBhY2N1cmFjeT0xKSkpLA0KICAgICAgICAgIGNvbG9yID0gInRyYW5zcGFyZW50IikgKw0KICB0aGVtZV92b2lkKCkgKw0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksDQogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiUHVSZCIsDQogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gIiNZbE9yUmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAjIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iUGVyY2VudCBCbGFjayBBbmNlc3RyeSAoJSkiLA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCbGFjayBBbmNlc3RyeSBieSBDZW5zdXMgVHJhY3QiLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBBbWVyaWNhbiBDb21tdW5pdHkgU3VydmV5LCAyMDE2LTIwIg0KICApDQpnZ3Bsb3RseShibGFja19tYXAsIHRvb2x0aXAgPSAidGV4dCIpDQpgYGANCg0Kc3RfY3JzKGJsYWNrKXRvIHByaW50IGluIGNvbnNvbGUgdGhlIHByb2plY3Rpb25zIG9mIGRhdGEgZnJhbWUNCg0KSW1wb3J0IE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWFzIGZvciBOWUMNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpuYWJlcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9yYXcvZ2VvL255bnRhMjAyMF8yM2MvbnludGEyMDIwLnNocCIpDQpzdF9jcnMobmFiZXMpDQoNCmJsYWNrXzIyNjMgPC0gc3RfdHJhbnNmb3JtKGJsYWNrLCAyMjYzKQ0Kc3RfY3JzKGJsYWNrXzIyNjMpDQoNCiNyZW1vdmUgdW5uZWNlc3NhcnkgZmllbGRzIGluIHRoZSBuZWlnaGJvcmhvb2Qgc2hhcGVmaWxlDQpuYWJlc19zZWxlY3RlZCA8LSBuYWJlcyB8Pg0KICBzZWxlY3QoQm9yb0NvZGUsIEJvcm9OYW1lLCBOVEEyMDIwLCBOVEFOYW1lKQ0KDQpibGFja19uYWJlcyA8LSBibGFja18yMjYzIHw+DQogIHN0X2pvaW4obmFiZXNfc2VsZWN0ZWQsIA0KICAgICAgICAgIGxlZnQgPSBUUlVFLA0KICAgICAgICAgIGpvaW4gPSBzdF9pbnRlcnNlY3RzLA0KICAgICAgICAgIGxhcmdlc3QgPSBUKQ0KYGBgDQoNCkJsYWNrIGFuY2VzdHJ5IHN0YXRpc3RpYyBpbiBlYWNoIGJvcm91Z2gNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpibGFja19uYWJlX3N0YXRzIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoYmxhY2tfbmFiZXMpIHw+IA0KICBncm91cF9ieShOVEFOYW1lKSB8PiANCiAgc3VtbWFyaXNlKEJvcm91Z2ggPSBmaXJzdChCb3JvTmFtZSksDQogICAgICAgICAgICBgRXN0LiBUb3RhbCBQb3B1bGF0aW9uYCA9IHN1bShhbmNlc3RyeV9wb3BFKSwNCiAgICAgICAgICAgIGBFc3QuIFRvdGFsIGJsYWNrIFBvcHVsYXRpb25gID0gc3VtKGJsYWNrTSkpIHw+IA0KICBtdXRhdGUoYEVzdC4gUGVyY2VudCBibGFjayBBbmNlc3RyeWAgPSBwZXJjZW50KGBFc3QuIFRvdGFsIGJsYWNrIFBvcHVsYXRpb25gL2BFc3QuIFRvdGFsIFBvcHVsYXRpb25gLCBhY2N1cmFjeSA9IDEpKSANCmBgYA0KDQpJbXBvcnQgdGhlIHJhdyBkYXRhIG9mIFdoaXRlIEFuY2VzdHJ5IGZyb20gdGhlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQojIyMjIGltcG9ydCBib3JvdWdoIHNoYXBlZmlsZXMgZnJvbSBOWUMgT3BlbiBEYXRhDQpib3JvcyA8LSBzdF9yZWFkKCJEOi9QYXJzb24gU2Nob29vbCBPZiBEZXNpZ24vRGVzaWduIE1ldGhvZC9MZXNzb24vV2VlazEvUGFydDIvZGF0YS9wcm9jZXNzZWQvZ2VvL0Jvcm91Z2ggQm91bmRhcmllcy5nZW9qc29uIikNCg0KcmF3X2FuY2VzdHJ5IDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gInRyYWN0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSBjKGFuY2VzdHJ5X3BvcCA9ICJCMDQwMDZfMDAxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpdGUgPSAiQjAyMDAxXzAwMiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPSdOWScsDQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudHkgPSBjKCdCcm9ueCcsJ05ldyBZb3JrJyksDQogICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjAsDQogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpDQp3aGl0ZSA8LSByYXdfYW5jZXN0cnkgfD4gDQogIG11dGF0ZShwY3Rfd2hpdGUgPSB3aGl0ZUUvYW5jZXN0cnlfcG9wRSkgfD4gDQogIGZpbHRlcihhbmNlc3RyeV9wb3BFID4gMCkNCmBgYA0KDQpDcmVhdGUgbWFwIGJ5IHVzaW5nIGdncGxvdA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCndoaXRlX21hcCA8LSBnZ3Bsb3QoKSAgKyANCiAgZ2VvbV9zZihkYXRhID0gd2hpdGUsIA0KICAgICAgICAgIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF93aGl0ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoTkFNRSwgIjoiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlBlcmNlbnQgV2hpdGUgYW5jZXN0cnk6ICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQocGN0X3doaXRlLCBhY2N1cmFjeT0xKSkpLA0KICAgICAgICAgIGNvbG9yID0gInRyYW5zcGFyZW50IikgKw0KICB0aGVtZV92b2lkKCkgKw0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksDQogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiQnVQdSIsDQogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gIiNTZXQzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIyBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsDQogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnQgV2hpdGUgQW5jZXN0cnkgKCUpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPXBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiV2hpdGUgQW5jZXN0cnkgYnkgQ2Vuc3VzIFRyYWN0IiwNCiAgICBjYXB0aW9uID0gIlNvdXJjZTogQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSwgMjAxNi0yMCINCiAgKSANCmdncGxvdGx5KHdoaXRlX21hcCwgdG9vbHRpcCA9ICJ0ZXh0IikNCmBgYA0KDQpJbXBvcnQgTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYXMgZm9yIE5ZQw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCm5hYmVzIDwtIHN0X3JlYWQoIkQ6L1BhcnNvbiBTY2hvb29sIE9mIERlc2lnbi9EZXNpZ24gTWV0aG9kL0xlc3Nvbi9XZWVrMS9QYXJ0Mi9kYXRhL3Jhdy9nZW8vbnludGEyMDIwXzIzYy9ueW50YTIwMjAuc2hwIikNCnN0X2NycyhuYWJlcykNCg0Kd2hpdGVfMjI2MyA8LSBzdF90cmFuc2Zvcm0od2hpdGUsIDIyNjMpDQpzdF9jcnMod2hpdGVfMjI2MykNCg0KI3JlbW92ZSB1bm5lY2Vzc2FyeSBmaWVsZHMgaW4gdGhlIG5laWdoYm9yaG9vZCBzaGFwZWZpbGUNCm5hYmVzX3NlbGVjdGVkIDwtIG5hYmVzIHw+DQogIHNlbGVjdChCb3JvQ29kZSwgQm9yb05hbWUsIE5UQTIwMjAsIE5UQU5hbWUpDQoNCndoaXRlX25hYmVzIDwtIHdoaXRlXzIyNjMgfD4NCiAgc3Rfam9pbihuYWJlc19zZWxlY3RlZCwgDQogICAgICAgICAgbGVmdCA9IFRSVUUsDQogICAgICAgICAgam9pbiA9IHN0X2ludGVyc2VjdHMsDQogICAgICAgICAgbGFyZ2VzdCA9IFQpDQpgYGANCg0KV2hpdGUgYW5jZXN0cnkgc3RhdGlzdGljIGluIGVhY2ggYm9yb3VnaA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCndoaXRlX25hYmVfc3RhdHMgPC0gc3RfZHJvcF9nZW9tZXRyeSh3aGl0ZV9uYWJlcykgfD4gDQogIGdyb3VwX2J5KE5UQU5hbWUpIHw+IA0KICBzdW1tYXJpc2UoQm9yb3VnaCA9IGZpcnN0KEJvcm9OYW1lKSwNCiAgICAgICAgICAgIGBFc3QuIFRvdGFsIFBvcHVsYXRpb25gID0gc3VtKGFuY2VzdHJ5X3BvcEUpLA0KICAgICAgICAgICAgYEVzdC4gVG90YWwgd2hpdGUgUG9wdWxhdGlvbmAgPSBzdW0od2hpdGVNKSkgfD4gDQogIG11dGF0ZShgRXN0LiBQZXJjZW50IHdoaXRlIEFuY2VzdHJ5YCA9IHBlcmNlbnQoYEVzdC4gVG90YWwgd2hpdGUgUG9wdWxhdGlvbmAvYEVzdC4gVG90YWwgUG9wdWxhdGlvbmAsIGFjY3VyYWN5ID0gMSkpIA0KYGBgDQoNCk1lZGlhbiBIb3VzZWhvbGQgSW5jb21lDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KIyMjIyBpbXBvcnQgYm9yb3VnaCBzaGFwZWZpbGVzIGZyb20gTllDIE9wZW4gRGF0YQ0KYm9yb3MgPC0gc3RfcmVhZCgiRDovUGFyc29uIFNjaG9vb2wgT2YgRGVzaWduL0Rlc2lnbiBNZXRob2QvTGVzc29uL1dlZWsxL1BhcnQyL2RhdGEvcHJvY2Vzc2VkL2dlby9Cb3JvdWdoIEJvdW5kYXJpZXMuZ2VvanNvbiIpDQoNCk1ISSA8LSBnZXRfYWNzKGdlb2dyYXBoeSA9ICJ0cmFjdCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gYyhNSEkgPSAiQjE5MDE5XzAwMSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPSdOWScsDQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudHkgPSBjKCdCcm9ueCcsJ05ldyBZb3JrJyksDQogICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjAsDQogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSAid2lkZSIpIA0KDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQogbWhpX21hcCA8LSBnZ3Bsb3QoKSAgKyANCiAgICBzdXBwcmVzc1dhcm5pbmdzKGdlb21fc2YobHdkID0gMCwNCiAgICAgICAgICBkYXRhID0gTUhJLA0KICAgICAgICAgIG1hcHBpbmcgPSBhZXMoZmlsbCA9IE1ISUUsDQogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKE1ISUUsIjoiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIE1ISTogIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbGxhcihNSElFKSkpKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICBzY2FsZV9maWxsX2Zlcm1lbnRlcihicmVha3M9YygwLCAyNTAwMCwgNTAwMDAsIDc1MDAwLCAxMDAwMDAsIDEyNTAwMCwgMTUwMDAwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLA0KICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsDQogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9Ik1lZGlhbiBIb3VzZWhvbGQgSW5jb21lIiwNCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWRvbGxhcl9mb3JtYXQoYWNjdXJhY3kgPSBOVUxMKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIk1hbmhhdHRhbiAmIEJyb254LCBNZWRpYW4gSG91c2Vob2xkIEluY29tZSBieSBDZW5zdXMgVHJhY3QiLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBBbWVyaWNhbiBEZWNlbm5pYWwgQ2Vuc3VzLCAyMDIwIg0KICApICsNCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MgfD4gZmlsdGVyKGJvcm9fbmFtZSA9PSAiTWFuaGF0dGFuIiksICANCiAgICAgICAgICBjb2xvciA9ICJncmF5IiwgZmlsbCA9IE5BLCBsd2QgPSAuMSkgKw0KICBnZW9tX3NmKGRhdGEgPSBib3JvcyB8PiBmaWx0ZXIoYm9yb19uYW1lID09ICJCcm9ueCIpLCAgDQogICAgICAgICAgY29sb3IgPSAiZ3JheSIsIGZpbGwgPSBOQSwgbHdkID0gLjEpDQogIA0KDQpnZ3Bsb3RseShtaGlfbWFwLHRvb2x0aXAgPSAidGV4dCIpDQpgYGANCg==