Introduction

This analysis explores waste collection and recycling performance in New York City (NYC) using data from the Department of Sanitation (DSNY). The key objective is to analyze temporal and spatial trends in refuse and recycling tonnage, focusing on boroughs and community districts. The study also evaluates recycling rates and waste composition to identify areas for improvement in waste diversion practices.

Research Questions:

  1. How does waste collection and recycling performance vary across NYC boroughs and community districts over time?

  2. Which boroughs and community districts recycle the most/least?

  3. What actionable insights can be drawn to improve recycling practices and waste diversion rates?

The findings will inform potential policies and strategies to enhance waste management across NYC.

Methods

Data Source: The primary dataset was obtained from NYC Open Data’s DSNY Monthly Tonnage dataset, which records monthly tonnage of refuse and recyclable materials collected by the Department of Sanitation across NYC’s boroughs and community districts.

Steps:

  1. Data Cleaning: The dataset was cleaned and transformed to ensure consistency and usability.

  2. Temporal Analysis: Aggregated yearly trends in recycling and refuse collection were examined.

  3. Spatial Analysis: Borough-level and community district-level analyses were conducted using geographic data.

  4. Waste Composition: Waste types (e.g., refuse, paper, metal/glass/plastic) were analyzed to understand their contributions to total waste.

  5. Visualization: Various graphs and maps were created to visualize trends and spatial patterns.

Summary Tables

This section summarizes key statistics for selected community districts and boroughs.

Selected Community Districts (District 2 and 13 across all boroughs)

Borough-Level Summary
Borough Total Refuse (Tons) Total Recycling (Tons) Recycling Rate (%)
Manhattan 15815196 3151949 16.62
Queens 24908660 4949664 16.58
Staten Island 6459843 1224458 15.93
Brooklyn 28217303 4917786 14.84
Bronx 14484778 2039472 12.34

Results:

  • Recycling rates vary significantly across boroughs, with Manhattan leading and Bronx lagging.

  • Boroughs with higher recycling rates may have more effective waste diversion programs or greater community participation.

Temporal Analysis

This section analyzes temporal trends in waste collection and recycling tonnage across NYC boroughs over time.

The chart titled Total Recycling Trends by Borough presents the total recycling tonnage (in tons) over time for each borough in New York City from approximately 1990 to 2023. Here’s a detailed analysis:

  1. Overall Trends

Peak Around 2000: All boroughs experienced a significant increase in recycling tonnage during the late 1990s and peaked around 2000. This likely corresponds to the implementation of stronger recycling programs and initiatives in NYC.

Post-2000 Decline: Following the peak, there is a notable decline in recycling tonnage across all boroughs, potentially due to policy changes, reduced public participation, or fluctuations in waste generation patterns.

Stabilization and Gradual Recovery: From around 2010 onwards, recycling tonnage stabilizes, with some boroughs showing gradual recovery and growth.

  1. Borough-Level Insights

Queens: Queens consistently leads in total recycling tonnage over the years, reflecting strong community participation and efficient recycling programs. The decline post-2000 is visible but less severe compared to other boroughs.

Brooklyn: Brooklyn follows Queens in total recycling tonnage, with similar trends but slightly lower figures. The recovery post-2000 is more modest compared to Queens.

Manhattan: Manhattan demonstrates relatively high recycling tonnage, but its recovery post-2000 is less pronounced compared to Queens and Brooklyn. Manhattan’s dense population and high waste generation might contribute to its consistent recycling efforts.

Bronx: The Bronx has lower recycling tonnage compared to Queens, Brooklyn, and Manhattan. Recycling tonnage shows a steady increase until 2000, followed by a gradual decline and limited recovery afterward.

Spatial Analysis

Total Refuse by Community District

This section examines the total refuse collected in each community district using geospatial data and visualization. A map is created to show the distribution of refuse across NYC.

Recycling Rates by Community District

This section focuses on the spatial patterns of recycling rates across NYC community districts. A map for a selected year (2020) visualizes district-level recycling performance.

Key Takeaways from Spatial Analysis

Total Refuse:

  • High refuse tonnage in Manhattan and Brooklyn reflects their population density and commercial activity.

  • Staten Island districts produce significantly less refuse, consistent with its lower population.

Recycling Rates:

  • Significant disparities exist, with Manhattan and Queens leading and Bronx lagging.

  • Targeted interventions, such as infrastructure improvement and community awareness programs, are needed for low-performing districts.

Waste Composition

This section analyzes the proportion of waste types (refuse, paper, metal/glass/plastic) across NYC boroughs. The stacked bar chart displays the proportions of different types of waste—refuse (excluding paper and MGP), paper, and metal/glass/plastic (MGP)—as a percentage of the total waste generated by each borough. The total height of each bar is normalized to 100%, representing the total waste generated in that borough. The different colors indicate the relative contribution of each waste type to the total waste.

The blue section (total_refuse_without_paper_mgp) is the largest across all boroughs, indicating that the majority of waste is non-recyclable refuse. This highlights the need for improving recycling practices.

The green section (total_paper) and red section (total_mgp) represent recyclable materials.

Manhattan and Queens have slightly higher proportions of recyclables compared to Staten Island and the Bronx, suggesting better recycling performance in those boroughs.

Even though Staten Island generates less waste overall, the proportions of recyclable waste types (paper and MGP) are smaller compared to other boroughs. The Pie Charts allow a more detailed look at each borough individually, making it easier to identify borough-specific trends.

Conclusion

This analysis highlights the multifaceted nature of waste management in New York City, revealing not only borough-level disparities in recycling performance but also the overarching dominance of non-recyclable refuse in the city’s waste stream. While certain boroughs, like Manhattan and Queens, show encouraging trends in recycling efforts, the city as a whole still faces significant challenges in transitioning towards a more sustainable and efficient waste diversion system.

Addressing these challenges requires a coordinated strategy that combines infrastructure improvement, targeted public awareness campaigns, and innovative recycling policies. Boroughs lagging in recycling rates, such as Staten Island and the Bronx, would benefit from localized initiatives tailored to address their unique barriers to participation.

Beyond these findings, the analysis underscores the importance of integrating geospatial data and temporal trends into policy decisions. These tools can help policymakers identify high-impact intervention areas, measure the effectiveness of ongoing programs, and adapt strategies dynamically.

Ultimately, the path forward for NYC lies in leveraging data-driven insights to build an equitable, efficient, and sustainable waste management system—one that minimizes environmental impact and maximizes community engagement in recycling and waste diversion practices.

LS0tDQp0aXRsZTogIkFuYWx5c2lzIG9mIFdhc3RlIENvbGxlY3Rpb24gYW5kIFJlY3ljbGluZyBQZXJmb3JtYW5jZSBpbiBOZXcgWW9yayBDaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBULA0KICAgICAgICAgICAgICAgICAgICAgIHF1aWV0bHkgPSBULA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGKQ0KYGBgDQojIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBhbmFseXNpcyBleHBsb3JlcyB3YXN0ZSBjb2xsZWN0aW9uIGFuZCByZWN5Y2xpbmcgcGVyZm9ybWFuY2UgaW4gTmV3IFlvcmsgQ2l0eSAoTllDKSB1c2luZyBkYXRhIGZyb20gdGhlIERlcGFydG1lbnQgb2YgU2FuaXRhdGlvbiAoRFNOWSkuIFRoZSBrZXkgb2JqZWN0aXZlIGlzIHRvIGFuYWx5emUgdGVtcG9yYWwgYW5kIHNwYXRpYWwgdHJlbmRzIGluIHJlZnVzZSBhbmQgcmVjeWNsaW5nIHRvbm5hZ2UsIGZvY3VzaW5nIG9uIGJvcm91Z2hzIGFuZCBjb21tdW5pdHkgZGlzdHJpY3RzLiBUaGUgc3R1ZHkgYWxzbyBldmFsdWF0ZXMgcmVjeWNsaW5nIHJhdGVzIGFuZCB3YXN0ZSBjb21wb3NpdGlvbiB0byBpZGVudGlmeSBhcmVhcyBmb3IgaW1wcm92ZW1lbnQgaW4gd2FzdGUgZGl2ZXJzaW9uIHByYWN0aWNlcy4NCg0KKipSZXNlYXJjaCBRdWVzdGlvbnM6KioNCg0KMS4gSG93IGRvZXMgd2FzdGUgY29sbGVjdGlvbiBhbmQgcmVjeWNsaW5nIHBlcmZvcm1hbmNlIHZhcnkgYWNyb3NzIE5ZQyBib3JvdWdocyBhbmQgY29tbXVuaXR5IGRpc3RyaWN0cyBvdmVyIHRpbWU/DQoNCjIuIFdoaWNoIGJvcm91Z2hzIGFuZCBjb21tdW5pdHkgZGlzdHJpY3RzIHJlY3ljbGUgdGhlIG1vc3QvbGVhc3Q/DQoNCjMuIFdoYXQgYWN0aW9uYWJsZSBpbnNpZ2h0cyBjYW4gYmUgZHJhd24gdG8gaW1wcm92ZSByZWN5Y2xpbmcgcHJhY3RpY2VzIGFuZCB3YXN0ZSBkaXZlcnNpb24gcmF0ZXM/DQoNClRoZSBmaW5kaW5ncyB3aWxsIGluZm9ybSBwb3RlbnRpYWwgcG9saWNpZXMgYW5kIHN0cmF0ZWdpZXMgdG8gZW5oYW5jZSB3YXN0ZSBtYW5hZ2VtZW50IGFjcm9zcyBOWUMuDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShSU29jcmF0YSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeSh0aWR5Y2Vuc3VzKQ0KbGlicmFyeShzZikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KIyMgTWV0aG9kcw0KDQoqKkRhdGEgU291cmNlOioqDQpUaGUgcHJpbWFyeSBkYXRhc2V0IHdhcyBvYnRhaW5lZCBmcm9tIE5ZQyBPcGVuIERhdGEncyBEU05ZIE1vbnRobHkgVG9ubmFnZSBkYXRhc2V0LCB3aGljaCByZWNvcmRzIG1vbnRobHkgdG9ubmFnZSBvZiByZWZ1c2UgYW5kIHJlY3ljbGFibGUgbWF0ZXJpYWxzIGNvbGxlY3RlZCBieSB0aGUgRGVwYXJ0bWVudCBvZiBTYW5pdGF0aW9uIGFjcm9zcyBOWUMncyBib3JvdWdocyBhbmQgY29tbXVuaXR5IGRpc3RyaWN0cy4NCg0KKipTdGVwczoqKg0KDQoxLiBEYXRhIENsZWFuaW5nOiBUaGUgZGF0YXNldCB3YXMgY2xlYW5lZCBhbmQgdHJhbnNmb3JtZWQgdG8gZW5zdXJlIGNvbnNpc3RlbmN5IGFuZCB1c2FiaWxpdHkuDQoNCjIuIFRlbXBvcmFsIEFuYWx5c2lzOiBBZ2dyZWdhdGVkIHllYXJseSB0cmVuZHMgaW4gcmVjeWNsaW5nIGFuZCByZWZ1c2UgY29sbGVjdGlvbiB3ZXJlIGV4YW1pbmVkLg0KDQozLiBTcGF0aWFsIEFuYWx5c2lzOiBCb3JvdWdoLWxldmVsIGFuZCBjb21tdW5pdHkgZGlzdHJpY3QtbGV2ZWwgYW5hbHlzZXMgd2VyZSBjb25kdWN0ZWQgdXNpbmcgZ2VvZ3JhcGhpYyBkYXRhLg0KDQo0LiBXYXN0ZSBDb21wb3NpdGlvbjogV2FzdGUgdHlwZXMgKGUuZy4sIHJlZnVzZSwgcGFwZXIsIG1ldGFsL2dsYXNzL3BsYXN0aWMpIHdlcmUgYW5hbHl6ZWQgdG8gdW5kZXJzdGFuZCB0aGVpciBjb250cmlidXRpb25zIHRvIHRvdGFsIHdhc3RlLg0KDQo1LiBWaXN1YWxpemF0aW9uOiBWYXJpb3VzIGdyYXBocyBhbmQgbWFwcyB3ZXJlIGNyZWF0ZWQgdG8gdmlzdWFsaXplIHRyZW5kcyBhbmQgc3BhdGlhbCBwYXR0ZXJucy4NCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KYm9yb3MgPC0gc3RfcmVhZCgiQzovVXNlcnMvYXJvb2ovT25lRHJpdmUvRGVza3RvcC9jbGFzcyAxL3BhcnQyLTIwMjQxMDE0VDE0MTIxOFotMDAxL3BhcnQyL2RhdGEvcmF3L2dlby9Cb3JvdWdoIEJvdW5kYXJpZXMuZ2VvanNvbiIpDQoNCmNvbW11bml0eV9kaXN0cmljdHMgPC0gc3RfcmVhZCgiQzovVXNlcnMvYXJvb2ovT25lRHJpdmUvRGVza3RvcC9jbGFzcyAxL3BhcnQyLTIwMjQxMDE0VDE0MTIxOFotMDAxL3BhcnQyL2RhdGEvcmF3L2dlby9Db21tdW5pdHkgRGlzdHJpY3RzL2dlb19leHBvcnRfNTBmNjZkODAtNzgwMy00NjY0LWJkNTItMmIxNmY2NjlkOTUyLnNocCIpDQoNCmRhdGEgPC0gcmVhZC5zb2NyYXRhKCJodHRwczovL2RhdGEuY2l0eW9mbmV3eW9yay51cy9yZXNvdXJjZS9lYmI3LW12cDUuY3N2IikNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiMgRGF0YSBjbGVhbmluZyBhbmQgcHJlcGFyYXRpb24NCiMgVXNlIHNlcGFyYXRlKCkgdG8gc3BsaXQgdGhlICJtb250aCIgY29sdW1uDQpkc255X2RhdGEgPC0gZGF0YSB8Pg0KICBzZXBhcmF0ZShjb2wgPSBtb250aCwgaW50byA9IGMoInllYXIiLCAibW9udGgiKSwgc2VwID0gIiAvICIsIHJlbW92ZSA9IEZBTFNFICkgfD4NCiAgbXV0YXRlKA0KICAgIHllYXIgPSBhcy5udW1lcmljKHllYXIpLCAgICANCiAgICBtb250aCA9IGFzLm51bWVyaWMobW9udGgpLCAgDQogICAgcmVmdXNlID0gYXMubnVtZXJpYyhyZWZ1c2V0b25zY29sbGVjdGVkKSwNCiAgICBwYXBlciA9IGFzLm51bWVyaWMocGFwZXJ0b25zY29sbGVjdGVkKSwNCiAgICBtZXRhbF9nbGFzc19wbGFzdGljID0gYXMubnVtZXJpYyhtZ3B0b25zY29sbGVjdGVkKSwNCiAgICByZXNpZGVudGlhbF9vcmdhbmljID0gYXMubnVtZXJpYyhyZXNvcmdhbmljc3RvbnMpLA0KICAgIGNvbW11bml0eWRpc3RyaWN0ID0gYXMubnVtZXJpYyhjb21tdW5pdHlkaXN0cmljdCkpIA0KYGBgDQojIyBTdW1tYXJ5IFRhYmxlcw0KDQpUaGlzIHNlY3Rpb24gc3VtbWFyaXplcyBrZXkgc3RhdGlzdGljcyBmb3Igc2VsZWN0ZWQgY29tbXVuaXR5IGRpc3RyaWN0cyBhbmQgYm9yb3VnaHMuDQoNCioqU2VsZWN0ZWQgQ29tbXVuaXR5IERpc3RyaWN0cyAoRGlzdHJpY3QgMiBhbmQgMTMgYWNyb3NzIGFsbCBib3JvdWdocykqKg0KYGBge3IsIGVjaG89RkFMU0V9DQpzZWxlY3RlZF9kaXN0cmljdHMgPC0gZHNueV9kYXRhIHw+DQogIGZpbHRlcihjb21tdW5pdHlkaXN0cmljdCA9PSAyIHwgY29tbXVuaXR5ZGlzdHJpY3QgPT0gMTMpIHw+DQogIHNlbGVjdChjb21tdW5pdHlkaXN0cmljdCwgYm9yb3VnaCwgcGFwZXIsIG1ldGFsX2dsYXNzX3BsYXN0aWMsIHJlZnVzZSkgfD4NCiAgYXJyYW5nZShkZXNjKHBhcGVyKSkNCmRhdGF0YWJsZShzZWxlY3RlZF9kaXN0cmljdHMpDQpgYGANCg0KDQoqKkJvcm91Z2gtTGV2ZWwgU3VtbWFyeSoqDQpgYGB7ciwgZWNobz1GQUxTRX0NCmJvcm91Z2hfc3RhdHMgPC0gZHNueV9kYXRhIHw+DQogIGdyb3VwX2J5KGJvcm91Z2gpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICByZWN5Y2xpbmdfcmF0ZSA9IHJvdW5kKHRvdGFsX3JlY3ljbGluZyAvICh0b3RhbF9yZWZ1c2UgKyB0b3RhbF9yZWN5Y2xpbmcpICogMTAwLCAyKSl8Pg0KYXJyYW5nZShkZXNjKHJlY3ljbGluZ19yYXRlKSkNCg0KYm9yb3VnaF9zdGF0cyB8Pg0KICBrYWJsZSgNCiAgICBmb3JtYXQgPSAiaHRtbCIsIA0KICAgIGNvbC5uYW1lcyA9IGMoIkJvcm91Z2giLCAiVG90YWwgUmVmdXNlIChUb25zKSIsICJUb3RhbCBSZWN5Y2xpbmcgKFRvbnMpIiwgIlJlY3ljbGluZyBSYXRlICglKSIpLA0KICAgIGFsaWduID0gImMiKQ0KYGBgDQoqKlJlc3VsdHM6KioNCg0KKiBSZWN5Y2xpbmcgcmF0ZXMgdmFyeSBzaWduaWZpY2FudGx5IGFjcm9zcyBib3JvdWdocywgd2l0aCBNYW5oYXR0YW4gbGVhZGluZyBhbmQgQnJvbnggbGFnZ2luZy4NCg0KKiBCb3JvdWdocyB3aXRoIGhpZ2hlciByZWN5Y2xpbmcgcmF0ZXMgbWF5IGhhdmUgbW9yZSBlZmZlY3RpdmUgd2FzdGUgZGl2ZXJzaW9uIHByb2dyYW1zIG9yIGdyZWF0ZXIgY29tbXVuaXR5IHBhcnRpY2lwYXRpb24uDQpgYGB7ciwgZWNobz1GQUxTRX0NCmdncGxvdChib3JvdWdoX3N0YXRzLCBhZXMoeD1yZW9yZGVyKGJvcm91Z2gsIHJlY3ljbGluZ19yYXRlKSwgeT1yZWN5Y2xpbmdfcmF0ZSwgZmlsbD1ib3JvdWdoKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiUmVjeWNsaW5nIFJhdGVzIGJ5IEJvcm91Z2giLCB4ID0gIkJvcm91Z2giLCB5ID0gIlJlY3ljbGluZyBSYXRlICglKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgVGVtcG9yYWwgQW5hbHlzaXMNCg0KVGhpcyBzZWN0aW9uIGFuYWx5emVzIHRlbXBvcmFsIHRyZW5kcyBpbiB3YXN0ZSBjb2xsZWN0aW9uIGFuZCByZWN5Y2xpbmcgdG9ubmFnZSBhY3Jvc3MgTllDIGJvcm91Z2hzIG92ZXIgdGltZS4NCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kd2FzdGVfdHJlbmRzIDwtIGRzbnlfZGF0YSB8Pg0KICBncm91cF9ieSh5ZWFyLCBib3JvdWdoKXw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKQ0KICApDQpnZ3Bsb3Qod2FzdGVfdHJlbmRzLCBhZXMoeCA9IHllYXIsIHkgPSB0b3RhbF9yZWN5Y2xpbmcsIGNvbG9yID0gYm9yb3VnaCwgZ3JvdXAgPSBib3JvdWdoKSkgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBSZWN5Y2xpbmcgVHJlbmRzIGJ5IEJvcm91Z2giLCB4ID0gIlllYXIiLCB5ID0gIlRvdGFsIFJlY3ljbGluZyAoVG9ucykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClRoZSBjaGFydCB0aXRsZWQgKipUb3RhbCBSZWN5Y2xpbmcgVHJlbmRzIGJ5IEJvcm91Z2gqKiBwcmVzZW50cyB0aGUgdG90YWwgcmVjeWNsaW5nIHRvbm5hZ2UgKGluIHRvbnMpIG92ZXIgdGltZSBmb3IgZWFjaCBib3JvdWdoIGluIE5ldyBZb3JrIENpdHkgZnJvbSBhcHByb3hpbWF0ZWx5IDE5OTAgdG8gMjAyMy4gSGVyZSdzIGEgZGV0YWlsZWQgYW5hbHlzaXM6DQoNCjEuIE92ZXJhbGwgVHJlbmRzDQoNClBlYWsgQXJvdW5kIDIwMDA6IEFsbCBib3JvdWdocyBleHBlcmllbmNlZCBhIHNpZ25pZmljYW50IGluY3JlYXNlIGluIHJlY3ljbGluZyB0b25uYWdlIGR1cmluZyB0aGUgbGF0ZSAxOTkwcyBhbmQgcGVha2VkIGFyb3VuZCAyMDAwLiBUaGlzIGxpa2VseSBjb3JyZXNwb25kcyB0byB0aGUgaW1wbGVtZW50YXRpb24gb2Ygc3Ryb25nZXIgcmVjeWNsaW5nIHByb2dyYW1zIGFuZCBpbml0aWF0aXZlcyBpbiBOWUMuDQoNClBvc3QtMjAwMCBEZWNsaW5lOiBGb2xsb3dpbmcgdGhlIHBlYWssIHRoZXJlIGlzIGEgbm90YWJsZSBkZWNsaW5lIGluIHJlY3ljbGluZyB0b25uYWdlIGFjcm9zcyBhbGwgYm9yb3VnaHMsIHBvdGVudGlhbGx5IGR1ZSB0byBwb2xpY3kgY2hhbmdlcywgcmVkdWNlZCBwdWJsaWMgcGFydGljaXBhdGlvbiwgb3IgZmx1Y3R1YXRpb25zIGluIHdhc3RlIGdlbmVyYXRpb24gcGF0dGVybnMuDQoNClN0YWJpbGl6YXRpb24gYW5kIEdyYWR1YWwgUmVjb3Zlcnk6IEZyb20gYXJvdW5kIDIwMTAgb253YXJkcywgcmVjeWNsaW5nIHRvbm5hZ2Ugc3RhYmlsaXplcywgd2l0aCBzb21lIGJvcm91Z2hzIHNob3dpbmcgZ3JhZHVhbCByZWNvdmVyeSBhbmQgZ3Jvd3RoLg0KDQoyLiBCb3JvdWdoLUxldmVsIEluc2lnaHRzDQoNCioqUXVlZW5zOioqDQpRdWVlbnMgY29uc2lzdGVudGx5IGxlYWRzIGluIHRvdGFsIHJlY3ljbGluZyB0b25uYWdlIG92ZXIgdGhlIHllYXJzLCByZWZsZWN0aW5nIHN0cm9uZyBjb21tdW5pdHkgcGFydGljaXBhdGlvbiBhbmQgZWZmaWNpZW50IHJlY3ljbGluZyBwcm9ncmFtcy4NClRoZSBkZWNsaW5lIHBvc3QtMjAwMCBpcyB2aXNpYmxlIGJ1dCBsZXNzIHNldmVyZSBjb21wYXJlZCB0byBvdGhlciBib3JvdWdocy4NCg0KKipCcm9va2x5bjoqKg0KQnJvb2tseW4gZm9sbG93cyBRdWVlbnMgaW4gdG90YWwgcmVjeWNsaW5nIHRvbm5hZ2UsIHdpdGggc2ltaWxhciB0cmVuZHMgYnV0IHNsaWdodGx5IGxvd2VyIGZpZ3VyZXMuDQpUaGUgcmVjb3ZlcnkgcG9zdC0yMDAwIGlzIG1vcmUgbW9kZXN0IGNvbXBhcmVkIHRvIFF1ZWVucy4NCg0KKipNYW5oYXR0YW46KioNCk1hbmhhdHRhbiBkZW1vbnN0cmF0ZXMgcmVsYXRpdmVseSBoaWdoIHJlY3ljbGluZyB0b25uYWdlLCBidXQgaXRzIHJlY292ZXJ5IHBvc3QtMjAwMCBpcyBsZXNzIHByb25vdW5jZWQgY29tcGFyZWQgdG8gUXVlZW5zIGFuZCBCcm9va2x5bi4NCk1hbmhhdHRhbidzIGRlbnNlIHBvcHVsYXRpb24gYW5kIGhpZ2ggd2FzdGUgZ2VuZXJhdGlvbiBtaWdodCBjb250cmlidXRlIHRvIGl0cyBjb25zaXN0ZW50IHJlY3ljbGluZyBlZmZvcnRzLg0KDQoqKkJyb254OioqDQpUaGUgQnJvbnggaGFzIGxvd2VyIHJlY3ljbGluZyB0b25uYWdlIGNvbXBhcmVkIHRvIFF1ZWVucywgQnJvb2tseW4sIGFuZCBNYW5oYXR0YW4uDQpSZWN5Y2xpbmcgdG9ubmFnZSBzaG93cyBhIHN0ZWFkeSBpbmNyZWFzZSB1bnRpbCAyMDAwLCBmb2xsb3dlZCBieSBhIGdyYWR1YWwgZGVjbGluZSBhbmQgbGltaXRlZCByZWNvdmVyeSBhZnRlcndhcmQuDQoNCiMjIFNwYXRpYWwgQW5hbHlzaXMNCg0KKipUb3RhbCBSZWZ1c2UgYnkgQ29tbXVuaXR5IERpc3RyaWN0KioNCg0KVGhpcyBzZWN0aW9uIGV4YW1pbmVzIHRoZSB0b3RhbCByZWZ1c2UgY29sbGVjdGVkIGluIGVhY2ggY29tbXVuaXR5IGRpc3RyaWN0IHVzaW5nIGdlb3NwYXRpYWwgZGF0YSBhbmQgdmlzdWFsaXphdGlvbi4gQSBtYXAgaXMgY3JlYXRlZCB0byBzaG93IHRoZSBkaXN0cmlidXRpb24gb2YgcmVmdXNlIGFjcm9zcyBOWUMuDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZHNueV9kYXRhYSA8LSBkc255X2RhdGEgfD4NCiAgbXV0YXRlKA0KICAgIGNvbW11bml0eWRpc3RyaWN0ID0gY2FzZV93aGVuKA0KICAgICAgYm9yb3VnaCA9PSAiTWFuaGF0dGFuIiB+IHBhc3RlMCgiMSIsIHNwcmludGYoIiUwMmQiLCBjb21tdW5pdHlkaXN0cmljdCkpLA0KICAgICAgYm9yb3VnaCA9PSAiQnJvbngiIH4gcGFzdGUwKCIyIiwgc3ByaW50ZigiJTAyZCIsIGNvbW11bml0eWRpc3RyaWN0KSksDQogICAgICBib3JvdWdoID09ICJCcm9va2x5biIgfiBwYXN0ZTAoIjMiLCBzcHJpbnRmKCIlMDJkIiwgY29tbXVuaXR5ZGlzdHJpY3QpKSwNCiAgICAgIGJvcm91Z2ggPT0gIlF1ZWVucyIgfiBwYXN0ZTAoIjQiLCBzcHJpbnRmKCIlMDJkIiwgY29tbXVuaXR5ZGlzdHJpY3QpKSwNCiAgICAgIGJvcm91Z2ggPT0gIlN0YXRlbiBJc2xhbmQiIH4gcGFzdGUwKCI1Iiwgc3ByaW50ZigiJTAyZCIsIGNvbW11bml0eWRpc3RyaWN0KSksDQogICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXyAgKSApDQoNCmRpc3RyaWN0X3JlZnVzZSA8LSBkc255X2RhdGFhIHw+DQogIGdyb3VwX2J5KGNvbW11bml0eWRpc3RyaWN0KSB8Pg0KICBzdW1tYXJpemUoDQogICAgdG90YWxfcmVmdXNlID0gc3VtKHJlZnVzZSwgbmEucm0gPSBUUlVFKQ0KICApDQoNCmRpc3RyaWN0X3JlZnVzZSA8LSBkaXN0cmljdF9yZWZ1c2UgfD4NCiAgbXV0YXRlKGNvbW11bml0eWRpc3RyaWN0ID0gYXMuY2hhcmFjdGVyKGNvbW11bml0eWRpc3RyaWN0KSkNCg0KY29tbXVuaXR5X2Rpc3RyaWN0cyA8LSBjb21tdW5pdHlfZGlzdHJpY3RzIHw+DQogIG11dGF0ZShib3JvX2NkID0gYXMuY2hhcmFjdGVyKGJvcm9fY2QpKQ0KDQpjb21tdW5pdHlfbWFwIDwtIGNvbW11bml0eV9kaXN0cmljdHMgfD4NCiAgbGVmdF9qb2luKGRpc3RyaWN0X3JlZnVzZSwgYnkgPSBjKCJib3JvX2NkIiA9ICJjb21tdW5pdHlkaXN0cmljdCIpKQ0KDQoNCm1hcF9wbG90IDwtIGdncGxvdCgpICsNCiAgIyBQbG90IGNvbW11bml0eSBkaXN0cmljdHMgd2l0aCB0b3RhbCByZWZ1c2UNCiAgZ2VvbV9zZihkYXRhID0gY29tbXVuaXR5X21hcCwgDQogICAgICAgICAgYWVzKGZpbGwgPSB0b3RhbF9yZWZ1c2UsIA0KICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJDb21tdW5pdHkgRGlzdHJpY3Q6ICIsIGJvcm9fY2QsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+VG90YWwgUmVmdXNlOiAiLCBzY2FsZXM6OmNvbW1hKHRvdGFsX3JlZnVzZSwgYWNjdXJhY3kgPSAxKSkpLCANCiAgICAgICAgICBjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IDAuMDUpICsNCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MsIA0KICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAwLjIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmFtZSA9ICJUb3RhbCBSZWZ1c2UgKFRvbnMpIiwgDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIA0KICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJUb3RhbCBSZWZ1c2UgYnkgQ29tbXVuaXR5IERpc3RyaWN0IiwNCiAgICBzdWJ0aXRsZSA9ICJOZXcgWW9yayBDaXR5IiwNCiAgICBjYXB0aW9uID0gIlNvdXJjZTogRFNOWSBEYXRhIikNCg0KZ2dwbG90bHkobWFwX3Bsb3QsIHRvb2x0aXAgPSBjKCJib3JvX2NkIiwgInRvdGFsX3JlZnVzZSIpKQ0KDQpgYGANCg0KKipSZWN5Y2xpbmcgUmF0ZXMgYnkgQ29tbXVuaXR5IERpc3RyaWN0KioNCg0KVGhpcyBzZWN0aW9uIGZvY3VzZXMgb24gdGhlIHNwYXRpYWwgcGF0dGVybnMgb2YgcmVjeWNsaW5nIHJhdGVzIGFjcm9zcyBOWUMgY29tbXVuaXR5IGRpc3RyaWN0cy4gQSBtYXAgZm9yIGEgc2VsZWN0ZWQgeWVhciAoMjAyMCkgdmlzdWFsaXplcyBkaXN0cmljdC1sZXZlbCByZWN5Y2xpbmcgcGVyZm9ybWFuY2UuDQpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbW11bml0eV90cmVuZHNfbWFwIDwtIGRzbnlfZGF0YWEgfD4NCiAgZ3JvdXBfYnkoY29tbXVuaXR5ZGlzdHJpY3QsIHllYXIpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICByZWN5Y2xpbmdfcmF0ZSA9IHJvdW5kKCh0b3RhbF9yZWN5Y2xpbmcgLyAodG90YWxfcmVmdXNlICsgdG90YWxfcmVjeWNsaW5nKSkgKiAxMDAsIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpDQoNCmNvbW11bml0eV90cmVuZHNfbWFwIDwtIGNvbW11bml0eV90cmVuZHNfbWFwIHw+DQogIG11dGF0ZShjb21tdW5pdHlkaXN0cmljdCA9IGFzLmNoYXJhY3Rlcihjb21tdW5pdHlkaXN0cmljdCkpDQoNCmNvbW11bml0eV9kaXN0cmljdHMgPC0gY29tbXVuaXR5X2Rpc3RyaWN0cyB8Pg0KICBtdXRhdGUoYm9yb19jZCA9IGFzLmNoYXJhY3Rlcihib3JvX2NkKSkNCg0KY29tbXVuaXR5X21hcF90cmVuZHMgPC0gY29tbXVuaXR5X2Rpc3RyaWN0cyB8Pg0KICBsZWZ0X2pvaW4oY29tbXVuaXR5X3RyZW5kc19tYXAsIGJ5ID0gYygiYm9yb19jZCIgPSAiY29tbXVuaXR5ZGlzdHJpY3QiKSkNCg0Kc2VsZWN0ZWRfeWVhciA8LSAyMDIwDQpjb21tdW5pdHlfbWFwX3NlbGVjdGVkX3llYXIgPC0gY29tbXVuaXR5X21hcF90cmVuZHMgfD4NCiAgZmlsdGVyKHllYXIgPT0gc2VsZWN0ZWRfeWVhcikNCg0KcmVjeWNsaW5nX21hcCA8LSBnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YSA9IGNvbW11bml0eV9tYXBfc2VsZWN0ZWRfeWVhciwgDQogICAgICAgICAgYWVzKGZpbGwgPSByZWN5Y2xpbmdfcmF0ZSwgDQogICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIkNvbW11bml0eSBEaXN0cmljdDogIiwgYm9yb19jZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlJlY3ljbGluZyBSYXRlOiAiLCByZWN5Y2xpbmdfcmF0ZSwgIiUiKSksIA0KICAgICAgICAgIGNvbG9yID0gImdyZXkiLCBzaXplID0gMC4wNSkgKw0KICBnZW9tX3NmKGRhdGEgPSBib3JvcywgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IDAuMikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhuYW1lID0gIlJlY3ljbGluZyBSYXRlICglKSIsIA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KHNjYWxlID0gMSksIA0KICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9IHBhc3RlKCJSZWN5Y2xpbmcgUmF0ZSBieSBDb21tdW5pdHkgRGlzdHJpY3QgKCIsIHNlbGVjdGVkX3llYXIsICIpIiwgc2VwID0gIiIpLA0KICAgIHN1YnRpdGxlID0gIk5ldyBZb3JrIENpdHkiLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBEU05ZIERhdGEiKQ0KDQpnZ3Bsb3RseShyZWN5Y2xpbmdfbWFwLCB0b29sdGlwID0gYygidGV4dCIpKQ0KDQoNCmBgYA0KKipLZXkgVGFrZWF3YXlzIGZyb20gU3BhdGlhbCBBbmFseXNpcyoqDQoNClRvdGFsIFJlZnVzZToNCg0KKiBIaWdoIHJlZnVzZSB0b25uYWdlIGluIE1hbmhhdHRhbiBhbmQgQnJvb2tseW4gcmVmbGVjdHMgdGhlaXIgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBjb21tZXJjaWFsIGFjdGl2aXR5Lg0KDQoqIFN0YXRlbiBJc2xhbmQgZGlzdHJpY3RzIHByb2R1Y2Ugc2lnbmlmaWNhbnRseSBsZXNzIHJlZnVzZSwgY29uc2lzdGVudCB3aXRoIGl0cyBsb3dlciBwb3B1bGF0aW9uLg0KDQpSZWN5Y2xpbmcgUmF0ZXM6DQoNCiogU2lnbmlmaWNhbnQgZGlzcGFyaXRpZXMgZXhpc3QsIHdpdGggTWFuaGF0dGFuIGFuZCBRdWVlbnMgbGVhZGluZyBhbmQgQnJvbnggbGFnZ2luZy4NCg0KKiBUYXJnZXRlZCBpbnRlcnZlbnRpb25zLCBzdWNoIGFzIGluZnJhc3RydWN0dXJlIGltcHJvdmVtZW50IGFuZCBjb21tdW5pdHkgYXdhcmVuZXNzIHByb2dyYW1zLCBhcmUgbmVlZGVkIGZvciBsb3ctcGVyZm9ybWluZyBkaXN0cmljdHMuDQoNCiMjIFdhc3RlIENvbXBvc2l0aW9uDQoNClRoaXMgc2VjdGlvbiBhbmFseXplcyB0aGUgcHJvcG9ydGlvbiBvZiB3YXN0ZSB0eXBlcyAocmVmdXNlLCBwYXBlciwgbWV0YWwvZ2xhc3MvcGxhc3RpYykgYWNyb3NzIE5ZQyBib3JvdWdocy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kd2FzdGVfY29tcG9zaXRpb24gPC0gZHNueV9kYXRhIHw+DQogIGdyb3VwX2J5KGJvcm91Z2gpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9wYXBlciA9IHN1bShwYXBlciwgbmEucm0gPSBUUlVFKSwNCiAgICB0b3RhbF9tZ3AgPSBzdW0obWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICB0b3RhbF9yZWZ1c2Vfd2l0aG91dF9wYXBlcl9tZ3AgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpKSB8Pg0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCJ0b3RhbCIpLCANCiAgICBuYW1lc190byA9ICJ3YXN0ZV90eXBlIiwgDQogICAgdmFsdWVzX3RvID0gInRvbnMiKQ0KDQpnZ3Bsb3Qod2FzdGVfY29tcG9zaXRpb24sIGFlcyh4ID0gYm9yb3VnaCwgeSA9IHRvbnMsIGZpbGwgPSB3YXN0ZV90eXBlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZmlsbCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIldhc3RlIENvbXBvc2l0aW9uIGJ5IEJvcm91Z2giLA0KICAgIHggPSAiQm9yb3VnaCIsDQogICAgeSA9ICJQcm9wb3J0aW9uIiwNCiAgICBmaWxsID0gIldhc3RlIFR5cGUiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KVGhlIHN0YWNrZWQgYmFyIGNoYXJ0IGRpc3BsYXlzIHRoZSBwcm9wb3J0aW9ucyBvZiBkaWZmZXJlbnQgdHlwZXMgb2Ygd2FzdGXigJRyZWZ1c2UgKGV4Y2x1ZGluZyBwYXBlciBhbmQgTUdQKSwgcGFwZXIsIGFuZCBtZXRhbC9nbGFzcy9wbGFzdGljIChNR1Ap4oCUYXMgYSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCB3YXN0ZSBnZW5lcmF0ZWQgYnkgZWFjaCBib3JvdWdoLg0KVGhlIHRvdGFsIGhlaWdodCBvZiBlYWNoIGJhciBpcyBub3JtYWxpemVkIHRvIDEwMCUsIHJlcHJlc2VudGluZyB0aGUgdG90YWwgd2FzdGUgZ2VuZXJhdGVkIGluIHRoYXQgYm9yb3VnaC4gVGhlIGRpZmZlcmVudCBjb2xvcnMgaW5kaWNhdGUgdGhlIHJlbGF0aXZlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIHdhc3RlIHR5cGUgdG8gdGhlIHRvdGFsIHdhc3RlLg0KDQpUaGUgYmx1ZSBzZWN0aW9uICh0b3RhbF9yZWZ1c2Vfd2l0aG91dF9wYXBlcl9tZ3ApIGlzIHRoZSBsYXJnZXN0IGFjcm9zcyBhbGwgYm9yb3VnaHMsIGluZGljYXRpbmcgdGhhdCB0aGUgbWFqb3JpdHkgb2Ygd2FzdGUgaXMgbm9uLXJlY3ljbGFibGUgcmVmdXNlLiBUaGlzIGhpZ2hsaWdodHMgdGhlIG5lZWQgZm9yIGltcHJvdmluZyByZWN5Y2xpbmcgcHJhY3RpY2VzLg0KDQpUaGUgZ3JlZW4gc2VjdGlvbiAodG90YWxfcGFwZXIpIGFuZCByZWQgc2VjdGlvbiAodG90YWxfbWdwKSByZXByZXNlbnQgcmVjeWNsYWJsZSBtYXRlcmlhbHMuDQoNCk1hbmhhdHRhbiBhbmQgUXVlZW5zIGhhdmUgc2xpZ2h0bHkgaGlnaGVyIHByb3BvcnRpb25zIG9mIHJlY3ljbGFibGVzIGNvbXBhcmVkIHRvIFN0YXRlbiBJc2xhbmQgYW5kIHRoZSBCcm9ueCwgc3VnZ2VzdGluZyBiZXR0ZXIgcmVjeWNsaW5nIHBlcmZvcm1hbmNlIGluIHRob3NlIGJvcm91Z2hzLg0KDQpFdmVuIHRob3VnaCBTdGF0ZW4gSXNsYW5kIGdlbmVyYXRlcyBsZXNzIHdhc3RlIG92ZXJhbGwsIHRoZSBwcm9wb3J0aW9ucyBvZiByZWN5Y2xhYmxlIHdhc3RlIHR5cGVzIChwYXBlciBhbmQgTUdQKSBhcmUgc21hbGxlciBjb21wYXJlZCB0byBvdGhlciBib3JvdWdocy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0KZ2dwbG90KHdhc3RlX2NvbXBvc2l0aW9uLCBhZXMoeCA9ICIiLCB5ID0gdG9ucywgZmlsbCA9IHdhc3RlX3R5cGUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgZmFjZXRfd3JhcCh+Ym9yb3VnaCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIldhc3RlIENvbXBvc2l0aW9uIGJ5IEJvcm91Z2ggKFBpZSBDaGFydHMpIiwNCiAgICB4ID0gTlVMTCwNCiAgICB5ID0gTlVMTCwNCiAgICBmaWxsID0gIldhc3RlIFR5cGUiDQogICkgKw0KICB0aGVtZV92b2lkKCkNCmBgYA0KVGhlIFBpZSBDaGFydHMgYWxsb3cgYSBtb3JlIGRldGFpbGVkIGxvb2sgYXQgZWFjaCBib3JvdWdoIGluZGl2aWR1YWxseSwgbWFraW5nIGl0IGVhc2llciB0byBpZGVudGlmeSBib3JvdWdoLXNwZWNpZmljIHRyZW5kcy4NCg0KIyMgQ29uY2x1c2lvbg0KVGhpcyBhbmFseXNpcyBoaWdobGlnaHRzIHRoZSBtdWx0aWZhY2V0ZWQgbmF0dXJlIG9mIHdhc3RlIG1hbmFnZW1lbnQgaW4gTmV3IFlvcmsgQ2l0eSwgcmV2ZWFsaW5nIG5vdCBvbmx5IGJvcm91Z2gtbGV2ZWwgZGlzcGFyaXRpZXMgaW4gcmVjeWNsaW5nIHBlcmZvcm1hbmNlIGJ1dCBhbHNvIHRoZSBvdmVyYXJjaGluZyBkb21pbmFuY2Ugb2Ygbm9uLXJlY3ljbGFibGUgcmVmdXNlIGluIHRoZSBjaXR5J3Mgd2FzdGUgc3RyZWFtLiBXaGlsZSBjZXJ0YWluIGJvcm91Z2hzLCBsaWtlIE1hbmhhdHRhbiBhbmQgUXVlZW5zLCBzaG93IGVuY291cmFnaW5nIHRyZW5kcyBpbiByZWN5Y2xpbmcgZWZmb3J0cywgdGhlIGNpdHkgYXMgYSB3aG9sZSBzdGlsbCBmYWNlcyBzaWduaWZpY2FudCBjaGFsbGVuZ2VzIGluIHRyYW5zaXRpb25pbmcgdG93YXJkcyBhIG1vcmUgc3VzdGFpbmFibGUgYW5kIGVmZmljaWVudCB3YXN0ZSBkaXZlcnNpb24gc3lzdGVtLg0KDQpBZGRyZXNzaW5nIHRoZXNlIGNoYWxsZW5nZXMgcmVxdWlyZXMgYSBjb29yZGluYXRlZCBzdHJhdGVneSB0aGF0IGNvbWJpbmVzIGluZnJhc3RydWN0dXJlIGltcHJvdmVtZW50LCB0YXJnZXRlZCBwdWJsaWMgYXdhcmVuZXNzIGNhbXBhaWducywgYW5kIGlubm92YXRpdmUgcmVjeWNsaW5nIHBvbGljaWVzLiBCb3JvdWdocyBsYWdnaW5nIGluIHJlY3ljbGluZyByYXRlcywgc3VjaCBhcyBTdGF0ZW4gSXNsYW5kIGFuZCB0aGUgQnJvbngsIHdvdWxkIGJlbmVmaXQgZnJvbSBsb2NhbGl6ZWQgaW5pdGlhdGl2ZXMgdGFpbG9yZWQgdG8gYWRkcmVzcyB0aGVpciB1bmlxdWUgYmFycmllcnMgdG8gcGFydGljaXBhdGlvbi4NCg0KQmV5b25kIHRoZXNlIGZpbmRpbmdzLCB0aGUgYW5hbHlzaXMgdW5kZXJzY29yZXMgdGhlIGltcG9ydGFuY2Ugb2YgaW50ZWdyYXRpbmcgZ2Vvc3BhdGlhbCBkYXRhIGFuZCB0ZW1wb3JhbCB0cmVuZHMgaW50byBwb2xpY3kgZGVjaXNpb25zLiBUaGVzZSB0b29scyBjYW4gaGVscCBwb2xpY3ltYWtlcnMgaWRlbnRpZnkgaGlnaC1pbXBhY3QgaW50ZXJ2ZW50aW9uIGFyZWFzLCBtZWFzdXJlIHRoZSBlZmZlY3RpdmVuZXNzIG9mIG9uZ29pbmcgcHJvZ3JhbXMsIGFuZCBhZGFwdCBzdHJhdGVnaWVzIGR5bmFtaWNhbGx5Lg0KDQpVbHRpbWF0ZWx5LCB0aGUgcGF0aCBmb3J3YXJkIGZvciBOWUMgbGllcyBpbiBsZXZlcmFnaW5nIGRhdGEtZHJpdmVuIGluc2lnaHRzIHRvIGJ1aWxkIGFuIGVxdWl0YWJsZSwgZWZmaWNpZW50LCBhbmQgc3VzdGFpbmFibGUgd2FzdGUgbWFuYWdlbWVudCBzeXN0ZW3igJRvbmUgdGhhdCBtaW5pbWl6ZXMgZW52aXJvbm1lbnRhbCBpbXBhY3QgYW5kIG1heGltaXplcyBjb21tdW5pdHkgZW5nYWdlbWVudCBpbiByZWN5Y2xpbmcgYW5kIHdhc3RlIGRpdmVyc2lvbiBwcmFjdGljZXMuDQoNCg==