Project Overview

This report describes the Tableau dashboard and story points created for Project #4. The dashboard was built using the Sample Superstore dataset and focuses on sales, profit, product categories, customer segments, and geographic performance.

The purpose of the dashboard is to tell a clear business story about which parts of the Superstore business are performing well and which areas may need improvement. The final report embeds the Tableau Public dashboard and five Tableau Public story points so that readers can interact with the visualizations directly from the HTML report.

a. Narrative of the Story

The main story of this dashboard is that high sales do not always lead to high profit. A business can generate strong revenue while still losing money in certain product categories, sub-categories, customer segments, or geographic areas. Because of this, managers should evaluate both sales and profitability before making decisions.

The dashboard begins by showing sales performance across product categories and sub-categories. This helps identify which product groups generate the most revenue. However, by also comparing those product groups by profit, the dashboard shows whether revenue is actually creating business value.

The scatter plot expands the story by showing the relationship between sales and profit. This chart helps identify outliers, especially product groups or customer segments with high sales but low or negative profit. These cases may point to problems such as excessive discounting, high shipping costs, or inefficient pricing strategies.

The histogram shows the distribution of order-level sales. This helps explain whether total revenue is driven by many small transactions or by a smaller number of large orders. Understanding the distribution of sales is useful because extreme values can influence overall business results.

The map adds a geographic perspective by showing sales or profit by state and region. This makes it easier to identify areas where the company performs well and areas where profit may be weaker. Regional differences may reflect customer demand, shipping costs, product preferences, or discounting patterns.

Finally, the customer segment chart shows which customer groups contribute the largest share of sales. This helps managers understand whether Consumer, Corporate, or Home Office customers are driving business performance.

Overall, the dashboard tells a practical business story: Superstore should not focus only on increasing sales. It should focus on profitable growth by identifying strong product groups, improving weak regions, and managing customer segments more strategically.

b. Data Sources and Description

The data source used for this dashboard is the Sample Superstore dataset. This dataset contains retail order information, including product details, customer segments, geographic information, sales, profit, discounts, and shipping information.

The dataset is appropriate for this project because it contains both numerical and categorical variables. This allows the dashboard to include the required chart types, including histograms, scatter plots, bar charts, maps, and pie or bubble charts.

Numerical Variables

The main numerical variables used in the dashboard include:

  • Sales: Revenue generated from each order.
  • Profit: Profit or loss associated with each order.
  • Quantity: Number of items purchased.
  • Discount: Discount applied to the order.

Categorical Variables

The main categorical variables used in the dashboard include:

  • Category: Broad product group, such as Furniture, Office Supplies, or Technology.
  • Sub-Category: More specific product grouping within each category.
  • Region: Geographic region where the order occurred.
  • State: State where the customer is located.
  • Segment: Customer segment, such as Consumer, Corporate, or Home Office.
  • Ship Mode: Shipping method used for the order.

Dashboard Charts

Chart 1: Sales by Category and Sub-Category

Chart type: Bar chart
Variables used: Category, Sub-Category, Sales, Profit

This chart identifies which product groups generate the highest sales and whether those product groups are also profitable. It helps show that high sales do not always guarantee high profit.

Chart 2: Profit vs. Sales Scatter Plot

Chart type: Scatter plot
Variables used: Sales, Profit, Category, Segment

This chart shows the relationship between revenue and profitability. It is useful for identifying outliers, especially areas with high sales but low or negative profit.

Chart 3: Sales Distribution Histogram

Chart type: Histogram
Variables used: Sales

This chart shows the distribution of order-level sales. It helps explain whether most purchases are small, medium, or large.

Chart 4: Sales or Profit by Region

Chart type: Map or filled map
Variables used: State, Region, Sales, Profit

This chart shows geographic performance patterns and helps identify which states or regions generate strong profit and which areas may need improvement.

Chart 5: Segment Share of Sales

Chart type: Pie chart or packed bubble chart
Variables used: Segment, Sales

This chart shows which customer segments contribute the largest share of sales.

Interactivity and Filters

The dashboard includes interactive filters that allow users to explore the data more deeply. The filters include:

  • Region
  • Category
  • Segment
  • Order Date
  • Ship Mode

The most important global filter is Region, because it allows users to compare performance across geographic markets. The dashboard applies filters across the connected worksheets so that changing one filter updates the charts together. This creates a reactive dashboard where users can explore product, customer, and geographic patterns together.

c. Embedding Tableau Dashboard and Story Points to the Report

Embedded Tableau Public Dashboard

Open the Tableau Public Dashboard

Embedded Tableau Public Story Points

Story Point 1: Overall Business Performance

This story point introduces the overall purpose of the dashboard. It provides a high-level view of Superstore performance and frames the central business question: which parts of the company are generating strong sales and which areas are producing weaker profitability?

Open Story Point 1

Story Point 2: Product Performance

This story point focuses on product category and sub-category performance. It explains which product groups generate the most sales and whether those products are also profitable.

Open Story Point 2

Story Point 3: Sales vs. Profit Relationship

This story point examines the relationship between sales and profit. The scatter plot helps identify whether higher sales generally lead to higher profit and highlights possible outliers.

Open Story Point 3

Story Point 4: Geographic Performance

This story point adds a regional perspective to the dashboard. By comparing sales and profit across states or regions, the viewer can see where Superstore performs strongest and where profitability may be weaker.

Open Story Point 4

Story Point 5: Customer Segment Insights and Recommendations

This final story point summarizes the dashboard findings and connects them to business recommendations. It focuses on customer segments and explains how Superstore can use the dashboard to make better decisions.

Open Story Point 5

Recommendations

Based on the dashboard and story points, Superstore managers should consider the following actions:

  1. Focus on product sub-categories that generate both strong sales and strong profit.
  2. Investigate sub-categories with high sales but weak or negative profit.
  3. Review discounting practices in low-profit product groups.
  4. Compare regional performance to identify markets that need improvement.
  5. Use customer segment insights to target the most valuable customer groups.
  6. Monitor profit ratio alongside total sales to avoid pursuing revenue growth that does not improve profitability.

Conclusion

The Tableau dashboard provides a clear and interactive view of Superstore performance. It shows that sales, profit, product category, region, and customer segment must be analyzed together to make strong business decisions. The dashboard supports the project goal by combining multiple chart types into one interconnected visual story.

The most important conclusion is that profitable growth matters more than sales growth alone. By using filters, dashboards, and story points, viewers can identify where Superstore is performing well, where it is losing profit, and where management should focus future improvement efforts.

LS0tDQp0aXRsZTogIlByb2plY3QgIzQ6IFRhYmxlYXUgRGFzaGJvYXJkIFJlcG9ydCINCmF1dGhvcjogIktpZXJhbiBIZWZmZXJhbiINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0aGVtZTogY29zbW8NCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQ0KYGBgDQoNCiMgUHJvamVjdCBPdmVydmlldw0KDQpUaGlzIHJlcG9ydCBkZXNjcmliZXMgdGhlIFRhYmxlYXUgZGFzaGJvYXJkIGFuZCBzdG9yeSBwb2ludHMgY3JlYXRlZCBmb3IgUHJvamVjdCAjNC4gVGhlIGRhc2hib2FyZCB3YXMgYnVpbHQgdXNpbmcgdGhlICoqU2FtcGxlIFN1cGVyc3RvcmUqKiBkYXRhc2V0IGFuZCBmb2N1c2VzIG9uIHNhbGVzLCBwcm9maXQsIHByb2R1Y3QgY2F0ZWdvcmllcywgY3VzdG9tZXIgc2VnbWVudHMsIGFuZCBnZW9ncmFwaGljIHBlcmZvcm1hbmNlLg0KDQpUaGUgcHVycG9zZSBvZiB0aGUgZGFzaGJvYXJkIGlzIHRvIHRlbGwgYSBjbGVhciBidXNpbmVzcyBzdG9yeSBhYm91dCB3aGljaCBwYXJ0cyBvZiB0aGUgU3VwZXJzdG9yZSBidXNpbmVzcyBhcmUgcGVyZm9ybWluZyB3ZWxsIGFuZCB3aGljaCBhcmVhcyBtYXkgbmVlZCBpbXByb3ZlbWVudC4gVGhlIGZpbmFsIHJlcG9ydCBlbWJlZHMgdGhlIFRhYmxlYXUgUHVibGljIGRhc2hib2FyZCBhbmQgZml2ZSBUYWJsZWF1IFB1YmxpYyBzdG9yeSBwb2ludHMgc28gdGhhdCByZWFkZXJzIGNhbiBpbnRlcmFjdCB3aXRoIHRoZSB2aXN1YWxpemF0aW9ucyBkaXJlY3RseSBmcm9tIHRoZSBIVE1MIHJlcG9ydC4NCg0KIyBhLiBOYXJyYXRpdmUgb2YgdGhlIFN0b3J5DQoNClRoZSBtYWluIHN0b3J5IG9mIHRoaXMgZGFzaGJvYXJkIGlzIHRoYXQgKipoaWdoIHNhbGVzIGRvIG5vdCBhbHdheXMgbGVhZCB0byBoaWdoIHByb2ZpdCoqLiBBIGJ1c2luZXNzIGNhbiBnZW5lcmF0ZSBzdHJvbmcgcmV2ZW51ZSB3aGlsZSBzdGlsbCBsb3NpbmcgbW9uZXkgaW4gY2VydGFpbiBwcm9kdWN0IGNhdGVnb3JpZXMsIHN1Yi1jYXRlZ29yaWVzLCBjdXN0b21lciBzZWdtZW50cywgb3IgZ2VvZ3JhcGhpYyBhcmVhcy4gQmVjYXVzZSBvZiB0aGlzLCBtYW5hZ2VycyBzaG91bGQgZXZhbHVhdGUgYm90aCBzYWxlcyBhbmQgcHJvZml0YWJpbGl0eSBiZWZvcmUgbWFraW5nIGRlY2lzaW9ucy4NCg0KVGhlIGRhc2hib2FyZCBiZWdpbnMgYnkgc2hvd2luZyBzYWxlcyBwZXJmb3JtYW5jZSBhY3Jvc3MgcHJvZHVjdCBjYXRlZ29yaWVzIGFuZCBzdWItY2F0ZWdvcmllcy4gVGhpcyBoZWxwcyBpZGVudGlmeSB3aGljaCBwcm9kdWN0IGdyb3VwcyBnZW5lcmF0ZSB0aGUgbW9zdCByZXZlbnVlLiBIb3dldmVyLCBieSBhbHNvIGNvbXBhcmluZyB0aG9zZSBwcm9kdWN0IGdyb3VwcyBieSBwcm9maXQsIHRoZSBkYXNoYm9hcmQgc2hvd3Mgd2hldGhlciByZXZlbnVlIGlzIGFjdHVhbGx5IGNyZWF0aW5nIGJ1c2luZXNzIHZhbHVlLg0KDQpUaGUgc2NhdHRlciBwbG90IGV4cGFuZHMgdGhlIHN0b3J5IGJ5IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNhbGVzIGFuZCBwcm9maXQuIFRoaXMgY2hhcnQgaGVscHMgaWRlbnRpZnkgb3V0bGllcnMsIGVzcGVjaWFsbHkgcHJvZHVjdCBncm91cHMgb3IgY3VzdG9tZXIgc2VnbWVudHMgd2l0aCBoaWdoIHNhbGVzIGJ1dCBsb3cgb3IgbmVnYXRpdmUgcHJvZml0LiBUaGVzZSBjYXNlcyBtYXkgcG9pbnQgdG8gcHJvYmxlbXMgc3VjaCBhcyBleGNlc3NpdmUgZGlzY291bnRpbmcsIGhpZ2ggc2hpcHBpbmcgY29zdHMsIG9yIGluZWZmaWNpZW50IHByaWNpbmcgc3RyYXRlZ2llcy4NCg0KVGhlIGhpc3RvZ3JhbSBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIG9yZGVyLWxldmVsIHNhbGVzLiBUaGlzIGhlbHBzIGV4cGxhaW4gd2hldGhlciB0b3RhbCByZXZlbnVlIGlzIGRyaXZlbiBieSBtYW55IHNtYWxsIHRyYW5zYWN0aW9ucyBvciBieSBhIHNtYWxsZXIgbnVtYmVyIG9mIGxhcmdlIG9yZGVycy4gVW5kZXJzdGFuZGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbGVzIGlzIHVzZWZ1bCBiZWNhdXNlIGV4dHJlbWUgdmFsdWVzIGNhbiBpbmZsdWVuY2Ugb3ZlcmFsbCBidXNpbmVzcyByZXN1bHRzLg0KDQpUaGUgbWFwIGFkZHMgYSBnZW9ncmFwaGljIHBlcnNwZWN0aXZlIGJ5IHNob3dpbmcgc2FsZXMgb3IgcHJvZml0IGJ5IHN0YXRlIGFuZCByZWdpb24uIFRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIGlkZW50aWZ5IGFyZWFzIHdoZXJlIHRoZSBjb21wYW55IHBlcmZvcm1zIHdlbGwgYW5kIGFyZWFzIHdoZXJlIHByb2ZpdCBtYXkgYmUgd2Vha2VyLiBSZWdpb25hbCBkaWZmZXJlbmNlcyBtYXkgcmVmbGVjdCBjdXN0b21lciBkZW1hbmQsIHNoaXBwaW5nIGNvc3RzLCBwcm9kdWN0IHByZWZlcmVuY2VzLCBvciBkaXNjb3VudGluZyBwYXR0ZXJucy4NCg0KRmluYWxseSwgdGhlIGN1c3RvbWVyIHNlZ21lbnQgY2hhcnQgc2hvd3Mgd2hpY2ggY3VzdG9tZXIgZ3JvdXBzIGNvbnRyaWJ1dGUgdGhlIGxhcmdlc3Qgc2hhcmUgb2Ygc2FsZXMuIFRoaXMgaGVscHMgbWFuYWdlcnMgdW5kZXJzdGFuZCB3aGV0aGVyIENvbnN1bWVyLCBDb3Jwb3JhdGUsIG9yIEhvbWUgT2ZmaWNlIGN1c3RvbWVycyBhcmUgZHJpdmluZyBidXNpbmVzcyBwZXJmb3JtYW5jZS4NCg0KT3ZlcmFsbCwgdGhlIGRhc2hib2FyZCB0ZWxscyBhIHByYWN0aWNhbCBidXNpbmVzcyBzdG9yeTogKipTdXBlcnN0b3JlIHNob3VsZCBub3QgZm9jdXMgb25seSBvbiBpbmNyZWFzaW5nIHNhbGVzLiBJdCBzaG91bGQgZm9jdXMgb24gcHJvZml0YWJsZSBncm93dGggYnkgaWRlbnRpZnlpbmcgc3Ryb25nIHByb2R1Y3QgZ3JvdXBzLCBpbXByb3Zpbmcgd2VhayByZWdpb25zLCBhbmQgbWFuYWdpbmcgY3VzdG9tZXIgc2VnbWVudHMgbW9yZSBzdHJhdGVnaWNhbGx5LioqDQoNCiMgYi4gRGF0YSBTb3VyY2VzIGFuZCBEZXNjcmlwdGlvbg0KDQpUaGUgZGF0YSBzb3VyY2UgdXNlZCBmb3IgdGhpcyBkYXNoYm9hcmQgaXMgdGhlICoqU2FtcGxlIFN1cGVyc3RvcmUqKiBkYXRhc2V0LiBUaGlzIGRhdGFzZXQgY29udGFpbnMgcmV0YWlsIG9yZGVyIGluZm9ybWF0aW9uLCBpbmNsdWRpbmcgcHJvZHVjdCBkZXRhaWxzLCBjdXN0b21lciBzZWdtZW50cywgZ2VvZ3JhcGhpYyBpbmZvcm1hdGlvbiwgc2FsZXMsIHByb2ZpdCwgZGlzY291bnRzLCBhbmQgc2hpcHBpbmcgaW5mb3JtYXRpb24uDQoNClRoZSBkYXRhc2V0IGlzIGFwcHJvcHJpYXRlIGZvciB0aGlzIHByb2plY3QgYmVjYXVzZSBpdCBjb250YWlucyBib3RoIG51bWVyaWNhbCBhbmQgY2F0ZWdvcmljYWwgdmFyaWFibGVzLiBUaGlzIGFsbG93cyB0aGUgZGFzaGJvYXJkIHRvIGluY2x1ZGUgdGhlIHJlcXVpcmVkIGNoYXJ0IHR5cGVzLCBpbmNsdWRpbmcgaGlzdG9ncmFtcywgc2NhdHRlciBwbG90cywgYmFyIGNoYXJ0cywgbWFwcywgYW5kIHBpZSBvciBidWJibGUgY2hhcnRzLg0KDQojIyBOdW1lcmljYWwgVmFyaWFibGVzDQoNClRoZSBtYWluIG51bWVyaWNhbCB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgZGFzaGJvYXJkIGluY2x1ZGU6DQoNCi0gKipTYWxlcyoqOiBSZXZlbnVlIGdlbmVyYXRlZCBmcm9tIGVhY2ggb3JkZXIuDQotICoqUHJvZml0Kio6IFByb2ZpdCBvciBsb3NzIGFzc29jaWF0ZWQgd2l0aCBlYWNoIG9yZGVyLg0KLSAqKlF1YW50aXR5Kio6IE51bWJlciBvZiBpdGVtcyBwdXJjaGFzZWQuDQotICoqRGlzY291bnQqKjogRGlzY291bnQgYXBwbGllZCB0byB0aGUgb3JkZXIuDQoNCiMjIENhdGVnb3JpY2FsIFZhcmlhYmxlcw0KDQpUaGUgbWFpbiBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgZGFzaGJvYXJkIGluY2x1ZGU6DQoNCi0gKipDYXRlZ29yeSoqOiBCcm9hZCBwcm9kdWN0IGdyb3VwLCBzdWNoIGFzIEZ1cm5pdHVyZSwgT2ZmaWNlIFN1cHBsaWVzLCBvciBUZWNobm9sb2d5Lg0KLSAqKlN1Yi1DYXRlZ29yeSoqOiBNb3JlIHNwZWNpZmljIHByb2R1Y3QgZ3JvdXBpbmcgd2l0aGluIGVhY2ggY2F0ZWdvcnkuDQotICoqUmVnaW9uKio6IEdlb2dyYXBoaWMgcmVnaW9uIHdoZXJlIHRoZSBvcmRlciBvY2N1cnJlZC4NCi0gKipTdGF0ZSoqOiBTdGF0ZSB3aGVyZSB0aGUgY3VzdG9tZXIgaXMgbG9jYXRlZC4NCi0gKipTZWdtZW50Kio6IEN1c3RvbWVyIHNlZ21lbnQsIHN1Y2ggYXMgQ29uc3VtZXIsIENvcnBvcmF0ZSwgb3IgSG9tZSBPZmZpY2UuDQotICoqU2hpcCBNb2RlKio6IFNoaXBwaW5nIG1ldGhvZCB1c2VkIGZvciB0aGUgb3JkZXIuDQoNCiMgRGFzaGJvYXJkIENoYXJ0cw0KDQojIyBDaGFydCAxOiBTYWxlcyBieSBDYXRlZ29yeSBhbmQgU3ViLUNhdGVnb3J5DQoNCioqQ2hhcnQgdHlwZToqKiBCYXIgY2hhcnQgIA0KKipWYXJpYWJsZXMgdXNlZDoqKiBDYXRlZ29yeSwgU3ViLUNhdGVnb3J5LCBTYWxlcywgUHJvZml0ICANCg0KVGhpcyBjaGFydCBpZGVudGlmaWVzIHdoaWNoIHByb2R1Y3QgZ3JvdXBzIGdlbmVyYXRlIHRoZSBoaWdoZXN0IHNhbGVzIGFuZCB3aGV0aGVyIHRob3NlIHByb2R1Y3QgZ3JvdXBzIGFyZSBhbHNvIHByb2ZpdGFibGUuIEl0IGhlbHBzIHNob3cgdGhhdCBoaWdoIHNhbGVzIGRvIG5vdCBhbHdheXMgZ3VhcmFudGVlIGhpZ2ggcHJvZml0Lg0KDQojIyBDaGFydCAyOiBQcm9maXQgdnMuIFNhbGVzIFNjYXR0ZXIgUGxvdA0KDQoqKkNoYXJ0IHR5cGU6KiogU2NhdHRlciBwbG90ICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2FsZXMsIFByb2ZpdCwgQ2F0ZWdvcnksIFNlZ21lbnQgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiByZXZlbnVlIGFuZCBwcm9maXRhYmlsaXR5LiBJdCBpcyB1c2VmdWwgZm9yIGlkZW50aWZ5aW5nIG91dGxpZXJzLCBlc3BlY2lhbGx5IGFyZWFzIHdpdGggaGlnaCBzYWxlcyBidXQgbG93IG9yIG5lZ2F0aXZlIHByb2ZpdC4NCg0KIyMgQ2hhcnQgMzogU2FsZXMgRGlzdHJpYnV0aW9uIEhpc3RvZ3JhbQ0KDQoqKkNoYXJ0IHR5cGU6KiogSGlzdG9ncmFtICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2FsZXMgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2Ygb3JkZXItbGV2ZWwgc2FsZXMuIEl0IGhlbHBzIGV4cGxhaW4gd2hldGhlciBtb3N0IHB1cmNoYXNlcyBhcmUgc21hbGwsIG1lZGl1bSwgb3IgbGFyZ2UuDQoNCiMjIENoYXJ0IDQ6IFNhbGVzIG9yIFByb2ZpdCBieSBSZWdpb24NCg0KKipDaGFydCB0eXBlOioqIE1hcCBvciBmaWxsZWQgbWFwICANCioqVmFyaWFibGVzIHVzZWQ6KiogU3RhdGUsIFJlZ2lvbiwgU2FsZXMsIFByb2ZpdCAgDQoNClRoaXMgY2hhcnQgc2hvd3MgZ2VvZ3JhcGhpYyBwZXJmb3JtYW5jZSBwYXR0ZXJucyBhbmQgaGVscHMgaWRlbnRpZnkgd2hpY2ggc3RhdGVzIG9yIHJlZ2lvbnMgZ2VuZXJhdGUgc3Ryb25nIHByb2ZpdCBhbmQgd2hpY2ggYXJlYXMgbWF5IG5lZWQgaW1wcm92ZW1lbnQuDQoNCiMjIENoYXJ0IDU6IFNlZ21lbnQgU2hhcmUgb2YgU2FsZXMNCg0KKipDaGFydCB0eXBlOioqIFBpZSBjaGFydCBvciBwYWNrZWQgYnViYmxlIGNoYXJ0ICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2VnbWVudCwgU2FsZXMgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHdoaWNoIGN1c3RvbWVyIHNlZ21lbnRzIGNvbnRyaWJ1dGUgdGhlIGxhcmdlc3Qgc2hhcmUgb2Ygc2FsZXMuDQoNCiMgSW50ZXJhY3Rpdml0eSBhbmQgRmlsdGVycw0KDQpUaGUgZGFzaGJvYXJkIGluY2x1ZGVzIGludGVyYWN0aXZlIGZpbHRlcnMgdGhhdCBhbGxvdyB1c2VycyB0byBleHBsb3JlIHRoZSBkYXRhIG1vcmUgZGVlcGx5LiBUaGUgZmlsdGVycyBpbmNsdWRlOg0KDQotIFJlZ2lvbg0KLSBDYXRlZ29yeQ0KLSBTZWdtZW50DQotIE9yZGVyIERhdGUNCi0gU2hpcCBNb2RlDQoNClRoZSBtb3N0IGltcG9ydGFudCBnbG9iYWwgZmlsdGVyIGlzICoqUmVnaW9uKiosIGJlY2F1c2UgaXQgYWxsb3dzIHVzZXJzIHRvIGNvbXBhcmUgcGVyZm9ybWFuY2UgYWNyb3NzIGdlb2dyYXBoaWMgbWFya2V0cy4gVGhlIGRhc2hib2FyZCBhcHBsaWVzIGZpbHRlcnMgYWNyb3NzIHRoZSBjb25uZWN0ZWQgd29ya3NoZWV0cyBzbyB0aGF0IGNoYW5naW5nIG9uZSBmaWx0ZXIgdXBkYXRlcyB0aGUgY2hhcnRzIHRvZ2V0aGVyLiBUaGlzIGNyZWF0ZXMgYSByZWFjdGl2ZSBkYXNoYm9hcmQgd2hlcmUgdXNlcnMgY2FuIGV4cGxvcmUgcHJvZHVjdCwgY3VzdG9tZXIsIGFuZCBnZW9ncmFwaGljIHBhdHRlcm5zIHRvZ2V0aGVyLg0KDQojIGMuIEVtYmVkZGluZyBUYWJsZWF1IERhc2hib2FyZCBhbmQgU3RvcnkgUG9pbnRzIHRvIHRoZSBSZXBvcnQNCg0KIyMgRW1iZWRkZWQgVGFibGVhdSBQdWJsaWMgRGFzaGJvYXJkDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzNzk2NTc5NScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdQcm9qZWN0IDQgVGFibGVhdSBEYXNoYm9hcmQnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxLzFfcnNzLnBuZycgc3R5bGU9J2JvcmRlcjogbm9uZScgLz4NCiAgICA8L2E+DQogIDwvbm9zY3JpcHQ+DQogIDxvYmplY3QgY2xhc3M9J3RhYmxlYXVWaXonIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCiAgICA8cGFyYW0gbmFtZT0naG9zdF91cmwnIHZhbHVlPSdodHRwcyUzQSUyRiUyRnB1YmxpYy50YWJsZWF1LmNvbSUyRicgLz4NCiAgICA8cGFyYW0gbmFtZT0nZW1iZWRfY29kZV92ZXJzaW9uJyB2YWx1ZT0nMycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc2l0ZV9yb290JyB2YWx1ZT0nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSduYW1lJyB2YWx1ZT0nUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvRGFzaGJvYXJkMScgLz4NCiAgICA8cGFyYW0gbmFtZT0ndGFicycgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0ndG9vbGJhcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc3RhdGljX2ltYWdlJyB2YWx1ZT0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxLzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM3OTY1Nzk1Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIGlmIChkaXZFbGVtZW50Lm9mZnNldFdpZHRoID4gODAwKSB7DQogICAgdml6RWxlbWVudC5zdHlsZS5taW5XaWR0aD0nMTIwMHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heFdpZHRoPScxMDAlJzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbkhlaWdodD0nMTAxNHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heEhlaWdodD0oZGl2RWxlbWVudC5vZmZzZXRXaWR0aCowLjc1KSsncHgnOw0KICB9IGVsc2UgaWYgKGRpdkVsZW1lbnQub2Zmc2V0V2lkdGggPiA1MDApIHsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbldpZHRoPScxMjAwcHgnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWF4V2lkdGg9JzEwMCUnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWluSGVpZ2h0PScxMDE0cHgnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWF4SGVpZ2h0PShkaXZFbGVtZW50Lm9mZnNldFdpZHRoKjAuNzUpKydweCc7DQogIH0gZWxzZSB7DQogICAgdml6RWxlbWVudC5zdHlsZS5taW5XaWR0aD0nMTAxNnB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heFdpZHRoPScxMDAlJzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbkhlaWdodD0nMTc1MHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heEhlaWdodD0oZGl2RWxlbWVudC5vZmZzZXRXaWR0aCoxLjc3KSsncHgnOw0KICB9DQogIHZhciBzY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7DQogIHNjcmlwdEVsZW1lbnQuc3JjID0gJ2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL2phdmFzY3JpcHRzL2FwaS92aXpfdjEuanMnOw0KICB2aXpFbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdEVsZW1lbnQsIHZpekVsZW1lbnQpOw0KPC9zY3JpcHQ+DQoNCmBgYA0KDQpbT3BlbiB0aGUgVGFibGVhdSBQdWJsaWMgRGFzaGJvYXJkXShodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxPzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMgRW1iZWRkZWQgVGFibGVhdSBQdWJsaWMgU3RvcnkgUG9pbnRzDQoNCiMjIFN0b3J5IFBvaW50IDE6IE92ZXJhbGwgQnVzaW5lc3MgUGVyZm9ybWFuY2UNCg0KVGhpcyBzdG9yeSBwb2ludCBpbnRyb2R1Y2VzIHRoZSBvdmVyYWxsIHB1cnBvc2Ugb2YgdGhlIGRhc2hib2FyZC4gSXQgcHJvdmlkZXMgYSBoaWdoLWxldmVsIHZpZXcgb2YgU3VwZXJzdG9yZSBwZXJmb3JtYW5jZSBhbmQgZnJhbWVzIHRoZSBjZW50cmFsIGJ1c2luZXNzIHF1ZXN0aW9uOiB3aGljaCBwYXJ0cyBvZiB0aGUgY29tcGFueSBhcmUgZ2VuZXJhdGluZyBzdHJvbmcgc2FsZXMgYW5kIHdoaWNoIGFyZWFzIGFyZSBwcm9kdWNpbmcgd2Vha2VyIHByb2ZpdGFiaWxpdHk/DQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODMzOTg5NScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTEnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTEvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTEnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkxLzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4MzM5ODk1Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgMV0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkxPzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMjIFN0b3J5IFBvaW50IDI6IFByb2R1Y3QgUGVyZm9ybWFuY2UNCg0KVGhpcyBzdG9yeSBwb2ludCBmb2N1c2VzIG9uIHByb2R1Y3QgY2F0ZWdvcnkgYW5kIHN1Yi1jYXRlZ29yeSBwZXJmb3JtYW5jZS4gSXQgZXhwbGFpbnMgd2hpY2ggcHJvZHVjdCBncm91cHMgZ2VuZXJhdGUgdGhlIG1vc3Qgc2FsZXMgYW5kIHdoZXRoZXIgdGhvc2UgcHJvZHVjdHMgYXJlIGFsc28gcHJvZml0YWJsZS4NCg0KYGBgez1odG1sfQ0KDQo8ZGl2IGNsYXNzPSd0YWJsZWF1UGxhY2Vob2xkZXInIGlkPSd2aXoxNzgyMTM4NjA2Njg2JyBzdHlsZT0ncG9zaXRpb246IHJlbGF0aXZlJz4NCiAgPG5vc2NyaXB0Pg0KICAgIDxhIGhyZWY9JyMnPg0KICAgICAgPGltZyBhbHQ9J1N0b3J5Micgc3JjPSdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9zdGF0aWMvaW1hZ2VzL1ByL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5Mi8xX3Jzcy5wbmcnIHN0eWxlPSdib3JkZXI6IG5vbmUnIC8+DQogICAgPC9hPg0KICA8L25vc2NyaXB0Pg0KICA8b2JqZWN0IGNsYXNzPSd0YWJsZWF1Vml6JyBzdHlsZT0nZGlzcGxheTpub25lOyc+DQogICAgPHBhcmFtIG5hbWU9J2hvc3RfdXJsJyB2YWx1ZT0naHR0cHMlM0ElMkYlMkZwdWJsaWMudGFibGVhdS5jb20lMkYnIC8+DQogICAgPHBhcmFtIG5hbWU9J2VtYmVkX2NvZGVfdmVyc2lvbicgdmFsdWU9JzMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3NpdGVfcm9vdCcgdmFsdWU9JycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbmFtZScgdmFsdWU9J1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5MicgLz4NCiAgICA8cGFyYW0gbmFtZT0ndGFicycgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0ndG9vbGJhcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc3RhdGljX2ltYWdlJyB2YWx1ZT0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTIvMS5wbmcnIC8+DQogICAgPHBhcmFtIG5hbWU9J2FuaW1hdGVfdHJhbnNpdGlvbicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9zdGF0aWNfaW1hZ2UnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3Bpbm5lcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9vdmVybGF5JyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X2NvdW50JyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdsYW5ndWFnZScgdmFsdWU9J2VuLVVTJyAvPg0KICA8L29iamVjdD4NCjwvZGl2Pg0KDQo8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc+DQogIHZhciBkaXZFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpejE3ODIxMzg2MDY2ODYnKTsNCiAgdmFyIHZpekVsZW1lbnQgPSBkaXZFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdvYmplY3QnKVswXTsNCiAgdml6RWxlbWVudC5zdHlsZS53aWR0aD0nMTAxNnB4JzsNCiAgdml6RWxlbWVudC5zdHlsZS5oZWlnaHQ9JzEwMTRweCc7DQogIHZhciBzY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7DQogIHNjcmlwdEVsZW1lbnQuc3JjID0gJ2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL2phdmFzY3JpcHRzL2FwaS92aXpfdjEuanMnOw0KICB2aXpFbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdEVsZW1lbnQsIHZpekVsZW1lbnQpOw0KPC9zY3JpcHQ+DQoNCmBgYA0KDQpbT3BlbiBTdG9yeSBQb2ludCAyXShodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTI/Omxhbmd1YWdlPWVuLVVTJjpzaWQ9JjpyZWRpcmVjdD1hdXRoJjpkaXNwbGF5X2NvdW50PW4mOm9yaWdpbj12aXpfc2hhcmVfbGluaykNCg0KIyMgU3RvcnkgUG9pbnQgMzogU2FsZXMgdnMuIFByb2ZpdCBSZWxhdGlvbnNoaXANCg0KVGhpcyBzdG9yeSBwb2ludCBleGFtaW5lcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gc2FsZXMgYW5kIHByb2ZpdC4gVGhlIHNjYXR0ZXIgcGxvdCBoZWxwcyBpZGVudGlmeSB3aGV0aGVyIGhpZ2hlciBzYWxlcyBnZW5lcmFsbHkgbGVhZCB0byBoaWdoZXIgcHJvZml0IGFuZCBoaWdobGlnaHRzIHBvc3NpYmxlIG91dGxpZXJzLg0KDQpgYGB7PWh0bWx9DQoNCjxkaXYgY2xhc3M9J3RhYmxlYXVQbGFjZWhvbGRlcicgaWQ9J3ZpejE3ODIxMzg2NDcyMzUnIHN0eWxlPSdwb3NpdGlvbjogcmVsYXRpdmUnPg0KICA8bm9zY3JpcHQ+DQogICAgPGEgaHJlZj0nIyc+DQogICAgICA8aW1nIGFsdD0nU3RvcnkzJyBzcmM9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkzLzFfcnNzLnBuZycgc3R5bGU9J2JvcmRlcjogbm9uZScgLz4NCiAgICA8L2E+DQogIDwvbm9zY3JpcHQ+DQogIDxvYmplY3QgY2xhc3M9J3RhYmxlYXVWaXonIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCiAgICA8cGFyYW0gbmFtZT0naG9zdF91cmwnIHZhbHVlPSdodHRwcyUzQSUyRiUyRnB1YmxpYy50YWJsZWF1LmNvbSUyRicgLz4NCiAgICA8cGFyYW0gbmFtZT0nZW1iZWRfY29kZV92ZXJzaW9uJyB2YWx1ZT0nMycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc2l0ZV9yb290JyB2YWx1ZT0nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSduYW1lJyB2YWx1ZT0nUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSd0YWJzJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSd0b29sYmFyJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzdGF0aWNfaW1hZ2UnIHZhbHVlPSdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9zdGF0aWMvaW1hZ2VzL1ByL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5My8xLnBuZycgLz4NCiAgICA8cGFyYW0gbmFtZT0nYW5pbWF0ZV90cmFuc2l0aW9uJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3N0YXRpY19pbWFnZScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9zcGlubmVyJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X292ZXJsYXknIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfY291bnQnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2xhbmd1YWdlJyB2YWx1ZT0nZW4tVVMnIC8+DQogIDwvb2JqZWN0Pg0KPC9kaXY+DQoNCjxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0Jz4NCiAgdmFyIGRpdkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndml6MTc4MjEzODY0NzIzNScpOw0KICB2YXIgdml6RWxlbWVudCA9IGRpdkVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ29iamVjdCcpWzBdOw0KICB2aXpFbGVtZW50LnN0eWxlLndpZHRoPScxMDE2cHgnOw0KICB2aXpFbGVtZW50LnN0eWxlLmhlaWdodD0nMTAxNHB4JzsNCiAgdmFyIHNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsNCiAgc2NyaXB0RWxlbWVudC5zcmMgPSAnaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vamF2YXNjcmlwdHMvYXBpL3Zpel92MS5qcyc7DQogIHZpekVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2NyaXB0RWxlbWVudCwgdml6RWxlbWVudCk7DQo8L3NjcmlwdD4NCg0KYGBgDQoNCltPcGVuIFN0b3J5IFBvaW50IDNdKGh0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3ZpZXdzL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5Mz86bGFuZ3VhZ2U9ZW4tVVMmOnNpZD0mOnJlZGlyZWN0PWF1dGgmOmRpc3BsYXlfY291bnQ9biY6b3JpZ2luPXZpel9zaGFyZV9saW5rKQ0KDQojIyBTdG9yeSBQb2ludCA0OiBHZW9ncmFwaGljIFBlcmZvcm1hbmNlDQoNClRoaXMgc3RvcnkgcG9pbnQgYWRkcyBhIHJlZ2lvbmFsIHBlcnNwZWN0aXZlIHRvIHRoZSBkYXNoYm9hcmQuIEJ5IGNvbXBhcmluZyBzYWxlcyBhbmQgcHJvZml0IGFjcm9zcyBzdGF0ZXMgb3IgcmVnaW9ucywgdGhlIHZpZXdlciBjYW4gc2VlIHdoZXJlIFN1cGVyc3RvcmUgcGVyZm9ybXMgc3Ryb25nZXN0IGFuZCB3aGVyZSBwcm9maXRhYmlsaXR5IG1heSBiZSB3ZWFrZXIuDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODY2OTM1OCcgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTQnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTQvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTQnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk0LzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4NjY5MzU4Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgNF0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk0PzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMjIFN0b3J5IFBvaW50IDU6IEN1c3RvbWVyIFNlZ21lbnQgSW5zaWdodHMgYW5kIFJlY29tbWVuZGF0aW9ucw0KDQpUaGlzIGZpbmFsIHN0b3J5IHBvaW50IHN1bW1hcml6ZXMgdGhlIGRhc2hib2FyZCBmaW5kaW5ncyBhbmQgY29ubmVjdHMgdGhlbSB0byBidXNpbmVzcyByZWNvbW1lbmRhdGlvbnMuIEl0IGZvY3VzZXMgb24gY3VzdG9tZXIgc2VnbWVudHMgYW5kIGV4cGxhaW5zIGhvdyBTdXBlcnN0b3JlIGNhbiB1c2UgdGhlIGRhc2hib2FyZCB0byBtYWtlIGJldHRlciBkZWNpc2lvbnMuDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODcwNDU5MScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTUnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTUvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTUnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk1LzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4NzA0NTkxJyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgNV0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk1PzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMgUmVjb21tZW5kYXRpb25zDQoNCkJhc2VkIG9uIHRoZSBkYXNoYm9hcmQgYW5kIHN0b3J5IHBvaW50cywgU3VwZXJzdG9yZSBtYW5hZ2VycyBzaG91bGQgY29uc2lkZXIgdGhlIGZvbGxvd2luZyBhY3Rpb25zOg0KDQoxLiBGb2N1cyBvbiBwcm9kdWN0IHN1Yi1jYXRlZ29yaWVzIHRoYXQgZ2VuZXJhdGUgYm90aCBzdHJvbmcgc2FsZXMgYW5kIHN0cm9uZyBwcm9maXQuDQoyLiBJbnZlc3RpZ2F0ZSBzdWItY2F0ZWdvcmllcyB3aXRoIGhpZ2ggc2FsZXMgYnV0IHdlYWsgb3IgbmVnYXRpdmUgcHJvZml0Lg0KMy4gUmV2aWV3IGRpc2NvdW50aW5nIHByYWN0aWNlcyBpbiBsb3ctcHJvZml0IHByb2R1Y3QgZ3JvdXBzLg0KNC4gQ29tcGFyZSByZWdpb25hbCBwZXJmb3JtYW5jZSB0byBpZGVudGlmeSBtYXJrZXRzIHRoYXQgbmVlZCBpbXByb3ZlbWVudC4NCjUuIFVzZSBjdXN0b21lciBzZWdtZW50IGluc2lnaHRzIHRvIHRhcmdldCB0aGUgbW9zdCB2YWx1YWJsZSBjdXN0b21lciBncm91cHMuDQo2LiBNb25pdG9yIHByb2ZpdCByYXRpbyBhbG9uZ3NpZGUgdG90YWwgc2FsZXMgdG8gYXZvaWQgcHVyc3VpbmcgcmV2ZW51ZSBncm93dGggdGhhdCBkb2VzIG5vdCBpbXByb3ZlIHByb2ZpdGFiaWxpdHkuDQoNCiMgQ29uY2x1c2lvbg0KDQpUaGUgVGFibGVhdSBkYXNoYm9hcmQgcHJvdmlkZXMgYSBjbGVhciBhbmQgaW50ZXJhY3RpdmUgdmlldyBvZiBTdXBlcnN0b3JlIHBlcmZvcm1hbmNlLiBJdCBzaG93cyB0aGF0IHNhbGVzLCBwcm9maXQsIHByb2R1Y3QgY2F0ZWdvcnksIHJlZ2lvbiwgYW5kIGN1c3RvbWVyIHNlZ21lbnQgbXVzdCBiZSBhbmFseXplZCB0b2dldGhlciB0byBtYWtlIHN0cm9uZyBidXNpbmVzcyBkZWNpc2lvbnMuIFRoZSBkYXNoYm9hcmQgc3VwcG9ydHMgdGhlIHByb2plY3QgZ29hbCBieSBjb21iaW5pbmcgbXVsdGlwbGUgY2hhcnQgdHlwZXMgaW50byBvbmUgaW50ZXJjb25uZWN0ZWQgdmlzdWFsIHN0b3J5Lg0KDQpUaGUgbW9zdCBpbXBvcnRhbnQgY29uY2x1c2lvbiBpcyB0aGF0ICoqcHJvZml0YWJsZSBncm93dGggbWF0dGVycyBtb3JlIHRoYW4gc2FsZXMgZ3Jvd3RoIGFsb25lKiouIEJ5IHVzaW5nIGZpbHRlcnMsIGRhc2hib2FyZHMsIGFuZCBzdG9yeSBwb2ludHMsIHZpZXdlcnMgY2FuIGlkZW50aWZ5IHdoZXJlIFN1cGVyc3RvcmUgaXMgcGVyZm9ybWluZyB3ZWxsLCB3aGVyZSBpdCBpcyBsb3NpbmcgcHJvZml0LCBhbmQgd2hlcmUgbWFuYWdlbWVudCBzaG91bGQgZm9jdXMgZnV0dXJlIGltcHJvdmVtZW50IGVmZm9ydHMuDQo=