Report timestamp: 2019-09-27 02:23:24

Contact: goran.milovanovic_ext at wikimedia.de


Introduction

The Wikidata Quality Report presents an assessment of the quality of Wikidata items based on the Objective Revision Evaluation Services - ORES machine learning system predictions. ORES learns about the feature distributions of Wikidata items of various quality from human annotated data sets and then predicts the quality class (see Grading Scheme bellow) of the previously unassessed items.

The Grading Scheme for Wikidata items used in this report encompasses five categories (A, B, C, D, and E) of decreasing quality. The following (somewhat shortend) description of the quality classes used by ORES and reported herein is taken directly from https://www.wikidata.org/wiki/Wikidata:Item_quality (for more details visit the Grading Scheme Wikidata page):

schemeURL <- "https://www.wikidata.org/wiki/Wikidata:Item_quality"
gradingScheme <- htmltab(schemeURL, 2, rm_nodata_cols = F)
gradingScheme$Criteria <- paste0(
  gsub("\\..+", "", gradingScheme$Criteria), ".")
gradingScheme$Examples <- gsub('\\((Q[[:digit:]]+)\\)', 
                               '<a href="https://www.wikidata.org/wiki/\\1">\\1</a>', 
                               gradingScheme$Examples)
DT::datatable(gradingScheme, 
              options = list(
                width = '100%',
                columnDefs = list(list(className = 'dt-center', targets = "_all"))
              ),
              rownames = FALSE,
              escape = FALSE
)

This Report uses the Wikidata Concepts Monitor - WDCM re-use statistics data in combination with ORES prediction scores to provide a more comprehensive picture of data quality in Wikidata. The WDCM system tracks the Wikidata re-use across the Wikimedia projects and assings each item a unique re-use statistic. The WDCM re-use statistic is defined as the number of mentions of an item across the Wikimedia projects: multiple uses of the same item, in any of the several usage aspects (see: wbc_entity_usage), on the same page, and in the same project are counted as one item mention. For example, the usage statistic for Q42 is thus the sum of the count of all pages across all Wikimedia projects that make at least one use of it - and irrespective of the usage aspect.

All data sets upon which this Report is based are publicly available from the following URL:

https://analytics.wikimedia.org/datasets/wmde-analytics-engineering/Wikidata/WD_DataQuality/


Overview

stats <- read.csv('https://analytics.wikimedia.org/datasets/wmde-analytics-engineering/Wikidata/WD_DataQuality/dataQuality_Stats.csv', 
                  header = T, 
                  check.names = F, 
                  stringsAsFactors = F)

This Report finds a total number of 57190185 items currently in Wikidata, of which 57014687 (99.69%) have received a quality assessment from the ORES system. Out of the total number of 57190185 items, WDCM finds that 27694683 (48.43%) are re-used across the Wikimedia projects. The latest ORES prediction run upon which this Report is based was on 2019-09-16 13:17:00, while the latest update of the WDCM re-use statistics happend on 2019-09-26 23:14:36 UTC. The report is based on the 2019-08 snapshot of the wmf.mediawiki_history table in the WMD Data Lake, and the 20190603 version of the hdfs copy of the Wikidata JSON dump.

Quality distribution for all items

Looking at all of the 57014687 Wikidata items that have received a quality score from ORES, we find the following:

dataA <- read.csv('https://analytics.wikimedia.org/datasets/wmde-analytics-engineering/Wikidata/WD_DataQuality/dataQuality_oresScoresDistribution.csv',
                 header = T,
                 check.names = F,
                 stringsAsFactors = F,
                 row.names = 1)
colnames(dataA) <- c('Quality', 'Number of items')
dataA$Percent <- round(dataA$`Number of items`/sum(dataA$`Number of items`)*100, 2)
DT::datatable(dataA, 
              options = list(
                width = '100%',
                columnDefs = list(list(className = 'dt-center', targets = "_all"))
              ),
              rownames = FALSE
    )

Quality distribution for the top 10,000 re-used items

Looking only at the top 10,000 most re-used items across the Wikimedia projects according to the WDCM, we find the following distribution of quality:

dataB <- read.csv('https://analytics.wikimedia.org/datasets/wmde-analytics-engineering/Wikidata/WD_DataQuality/dataQuality_oresScoresDistribution_10000.csv',
                 header = T,
                 check.names = F,
                 stringsAsFactors = F,
                 row.names = 1)
colnames(dataB) <- c('Quality', 'Number of items')
dataB$Percent <- round(dataB$`Number of items`/sum(dataB$`Number of items`)*100, 2)
DT::datatable(dataB, 
              options = list(
                width = '100%',
                columnDefs = list(list(className = 'dt-center', targets = "_all"))
              ),
              rownames = FALSE
    )

Quality distribution: top 10K most used items vs all items

If we would compare the quality distribution of all items to the top 10,000 re-used items across the Wikimedia projects, this is the picture that would emerge:

qualFrame <- data.frame(
  Quality = c("A", "B", "C", "D", "E"),
  All = dataA$Percent,
  Top10K = dataB$Percent, 
  stringsAsFactors = F)
qualFrame <- gather(qualFrame, 
                    key = 'Items',
                    value = 'Percent', 
                    2:3)
ggplot(qualFrame, 
       aes(x = Quality, 
           y = Percent, 
           group = Items, 
           color = Items, 
           fill = Items, 
           label = paste0(Percent, " %"))) + 
  geom_line() + 
  geom_point(size = 2.5) +
  geom_point(size = 2, color = "white") + 
  geom_text_repel(show.legend = FALSE) + 
  scale_colour_manual(values= c("darkblue", "darkred")) +
  theme_bw() +
  theme(panel.background = element_rect(color = "white", fill = "white")) +
      theme(panel.border = element_blank()) +
      theme(panel.grid = element_blank()) + 
      theme(legend.text = element_text(size = 14)) +
      theme(legend.title = element_text(size = 15))


Item quality and re-use

Item re-use w. outliers

In the following chart we present the WDCM re-use statistics (vertical axis, logarithmic scale) for all Wikidata items respective of their predicted quality score (A, B, C, D, or E). The horizontal lines in the boxplots represent the median values of the re-use statistics, while their lower and upper limits represent the 1st (.25) and the 3rd (.75) quartile, respectively. The free floating points above (and sometimes bellow) the boxes are outliers: they represent the Wikidata items used suspiciously more (or less) than other items in the same quality class. Once again: the outliers in this boxplot are detected for each quality class (A, B, C, D, or E) separately.

Item re-use w/o outliers

Now we present the same data except for the outliers that have been removed. We can see that item quality is correlated with item re-use: the lower the item quality, the less the item seems to be re-used across the Wikimedia projects. The vertical lines above and bellow the boxes extend to Q3+1.5*IQR and Q1-1.5*IQR respectively, where IQR is the Interquartile range; the outliers, if any remained here, would be shown bellow and above these limits.

Diversity of item re-use vs item quality

The following chart provides an in-depth insight into the relationship between item quality (as predicted by ORES) and item re-use across the Wikimedia projects (as assessed by WDCM). Each bubble represents (potentially) many Wikidata items. Let’s focus on a single quality class, A for example. Any A class item could be re-used 1, 2, 3, .., n, etc. times across the projects. Each bubble in this chart represents all Wikidata items in the respective quality class that share the same value of the re-use statistic (y-axis, log scale). The size of the bubble corresponds to the number of items that it represents (i.e. the number of items that share the same value of the re-use statistic). From the chart we can observe the following: the lower the item quality class (A > B > C > D > E), the lesser the number of unique re-use statistic values that the items from the respective class take.

The diversity of the unique values of the re-use statistic is much higher in the A quality class, for example, than in the D or E classes (where the re-use statistic takes only three unique values). This might be a consequence of (a) more human or human|machine engagement in the re-use of the top quality A items across the projects and (b) more pure machine engagement in the re-use of the D and E lower quality items.

Distribution of item re-use within the quality classes

The panels in the following chart present the distributiong of the WDCM re-use statistic (log scale, horizontal axes) across the item quality classes (A, B, C, D, or E: different panels). The vertical axes represent the number of Wikidata items found in each bin of the respective distribution.


The latest revids by quality class

The following chart has time (in a YYYY-MM format, and thus a monthly aggregate) on the horizontal axis, and the number of items (on a logarithmic scale) on the vertical axis. Each point represents the number of Wikidata items that have received their latest revision in the respective year and month. The quality classes (A, B, C, D, or E) are represented by separate lines connecting the data points. What we can see is that the top quality class A items are at the same time the most revisted ones. The pattern is similar for the B class items, while it seems that there are many C, D, and E class items that were revised only a long time ago.


Critical Wikidata items

We provide a list of all Wikidata items scored as imperfect (i.e. found in the B, C, D, or E quality class) that are also found as outliers in terms of their re-use (i.e. being used suspiciously more than all other Wikidata items across the Wikimedia projects). The list encompasses the top 1,000 most re-used items of imperfect quality from each quality class that are recognized as outliers in terms of their re-use. The items from the D and E classes in this list are probably the most critical Wikidata items and need to be improved immediately.

critical <- read.csv('https://analytics.wikimedia.org/datasets/wmde-analytics-engineering/Wikidata/WD_DataQuality/positiveOutliers.csv',
                 header = T,
                 check.names = F,
                 stringsAsFactors = F,
                 row.names = 1)
colnames(critical) <- c('Item', 'Quality', 'Re-use')
critical$url <- paste0('https://www.wikidata.org/wiki/', critical$Item)
critical$Item <- paste0('<a href="', critical$url, '" target="_blank">', critical$Item, "</a>")
critical$url <- NULL
critical <- critical %>% 
  dplyr::arrange(desc(Quality), desc(`Re-use`))
DT::datatable(critical, 
              options = list(
                pageLength = 100, 
                width = '100%',
                columnDefs = list(list(className = 'dt-center', targets = "_all"))
              ),
              escape = FALSE,
              rownames = FALSE
    )

We wish to thank all the member of the ORES team for their help in the production of this report.


LS0tCnRpdGxlOiBXaWtpZGF0YSBRdWFsaXR5IFJlcG9ydAphdXRob3I6Ci0gbmFtZTogR29yYW4gUy4gTWlsb3Zhbm92acSHCiAgYWZmaWxpYXRpb246IFdpa2ltZWRpYSBEZXV0c2NobGFuZCwgRGF0YSBTY2llbnRpc3QKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRoZW1lOiBzcGFjZWxhYgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICB0b2NfZGVwdGg6IDIKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgotLS0KIVtdKFdpa2lkYXRhLWxvZ28tZW4ucG5nKQoKKioqKioqCgpSZXBvcnQgdGltZXN0YW1wOiAqKmByIGFzLmNoYXJhY3RlcihTeXMudGltZSgpKWAqKgoKCkNvbnRhY3Q6IF9nb3Jhbi5taWxvdmFub3ZpY19leHQgYXQgd2lraW1lZGlhLmRlXwoKKioqKioqCgpgYGB7ciBlY2hvID0gRn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShodG1sdGFiKQpgYGAKCiMgSW50cm9kdWN0aW9uCgpUaGUgKipXaWtpZGF0YSBRdWFsaXR5IFJlcG9ydCoqIHByZXNlbnRzIGFuIGFzc2Vzc21lbnQgb2YgdGhlIFtxdWFsaXR5IG9mIFdpa2lkYXRhIGl0ZW1zXShodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS9XaWtpZGF0YTpJdGVtX3F1YWxpdHkpIGJhc2VkIG9uIHRoZSBbT2JqZWN0aXZlIFJldmlzaW9uIEV2YWx1YXRpb24gU2VydmljZXMgIC0gT1JFU10oaHR0cHM6Ly93d3cubWVkaWF3aWtpLm9yZy93aWtpL09SRVMpIG1hY2hpbmUgbGVhcm5pbmcgc3lzdGVtIHByZWRpY3Rpb25zLiBPUkVTIGxlYXJucyBhYm91dCB0aGUgZmVhdHVyZSBkaXN0cmlidXRpb25zIG9mIFdpa2lkYXRhIGl0ZW1zIG9mIHZhcmlvdXMgcXVhbGl0eSBmcm9tIGh1bWFuIGFubm90YXRlZCBkYXRhIHNldHMgYW5kIHRoZW4gcHJlZGljdHMgdGhlIHF1YWxpdHkgY2xhc3MgKHNlZSBfR3JhZGluZyBTY2hlbWVfIGJlbGxvdykgb2YgdGhlIHByZXZpb3VzbHkgdW5hc3Nlc3NlZCBpdGVtcy4gCgpUaGUgW0dyYWRpbmcgU2NoZW1lXShodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS9XaWtpZGF0YTpJdGVtX3F1YWxpdHkjR3JhZGluZ19zY2hlbWUpIGZvciBXaWtpZGF0YSBpdGVtcyB1c2VkIGluIHRoaXMgcmVwb3J0IGVuY29tcGFzc2VzIGZpdmUgY2F0ZWdvcmllcyAoKipBKiosICoqQioqLCAqKkMqKiwgKipEKiosIGFuZCAqKkUqKikgb2YgZGVjcmVhc2luZyBxdWFsaXR5LgpUaGUgZm9sbG93aW5nIChzb21ld2hhdCBzaG9ydGVuZCkgZGVzY3JpcHRpb24gb2YgdGhlIHF1YWxpdHkgY2xhc3NlcyB1c2VkIGJ5IE9SRVMgYW5kIHJlcG9ydGVkIGhlcmVpbiBpcyB0YWtlbiBkaXJlY3RseSBmcm9tIFtodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS9XaWtpZGF0YTpJdGVtX3F1YWxpdHldKGh0dHBzOi8vd3d3Lndpa2lkYXRhLm9yZy93aWtpL1dpa2lkYXRhOkl0ZW1fcXVhbGl0eSkgKGZvciBtb3JlIGRldGFpbHMgdmlzaXQgdGhlIFtHcmFkaW5nIFNjaGVtZV0oaHR0cHM6Ly93d3cud2lraWRhdGEub3JnL3dpa2kvV2lraWRhdGE6SXRlbV9xdWFsaXR5I0dyYWRpbmdfc2NoZW1lKSBXaWtpZGF0YSBwYWdlKToKCgpgYGB7ciBlY2hvID0gVH0Kc2NoZW1lVVJMIDwtICJodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS9XaWtpZGF0YTpJdGVtX3F1YWxpdHkiCmdyYWRpbmdTY2hlbWUgPC0gaHRtbHRhYihzY2hlbWVVUkwsIDIsIHJtX25vZGF0YV9jb2xzID0gRikKZ3JhZGluZ1NjaGVtZSRDcml0ZXJpYSA8LSBwYXN0ZTAoCiAgZ3N1YigiXFwuLisiLCAiIiwgZ3JhZGluZ1NjaGVtZSRDcml0ZXJpYSksICIuIikKZ3JhZGluZ1NjaGVtZSRFeGFtcGxlcyA8LSBnc3ViKCdcXCgoUVtbOmRpZ2l0Ol1dKylcXCknLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YSBocmVmPSJodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS9cXDEiPlxcMTwvYT4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYWRpbmdTY2hlbWUkRXhhbXBsZXMpCkRUOjpkYXRhdGFibGUoZ3JhZGluZ1NjaGVtZSwgCiAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgICAgICAgICAgICB3aWR0aCA9ICcxMDAlJywKICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSAiX2FsbCIpKQogICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgICAgICBlc2NhcGUgPSBGQUxTRQopCmBgYAoKVGhpcyBSZXBvcnQgdXNlcyB0aGUgW1dpa2lkYXRhIENvbmNlcHRzIE1vbml0b3IgLSBXRENNXShodHRwczovL3dpa2l0ZWNoLndpa2ltZWRpYS5vcmcvd2lraS9XaWtpZGF0YV9Db25jZXB0c19Nb25pdG9yKSByZS11c2Ugc3RhdGlzdGljcyBkYXRhIGluIGNvbWJpbmF0aW9uIHdpdGggT1JFUyBwcmVkaWN0aW9uIHNjb3JlcyB0byBwcm92aWRlIGEgbW9yZSBjb21wcmVoZW5zaXZlIHBpY3R1cmUgb2YgZGF0YSBxdWFsaXR5IGluIFdpa2lkYXRhLiBUaGUgV0RDTSBzeXN0ZW0gdHJhY2tzIHRoZSBXaWtpZGF0YSByZS11c2UgYWNyb3NzIHRoZSBXaWtpbWVkaWEgcHJvamVjdHMgYW5kIGFzc2luZ3MgZWFjaCBpdGVtIGEgdW5pcXVlIHJlLXVzZSBzdGF0aXN0aWMuIFRoZSBXRENNIHJlLXVzZSBzdGF0aXN0aWMgaXMgZGVmaW5lZCBhcyB0aGUgbnVtYmVyIG9mIF9tZW50aW9uc18gb2YgYW4gaXRlbSBhY3Jvc3MgdGhlIFdpa2ltZWRpYSBwcm9qZWN0czogbXVsdGlwbGUgdXNlcyBvZiB0aGUgc2FtZSBpdGVtLCBpbiBhbnkgb2YgdGhlIHNldmVyYWwgdXNhZ2UgYXNwZWN0cyAoc2VlOiBbd2JjX2VudGl0eV91c2FnZV0oaHR0cHM6Ly93d3cubWVkaWF3aWtpLm9yZy93aWtpL1dpa2liYXNlL1NjaGVtYS93YmNfZW50aXR5X3VzYWdlKSksIG9uIHRoZSBzYW1lIHBhZ2UsIGFuZCBpbiB0aGUgc2FtZSBwcm9qZWN0IGFyZSBjb3VudGVkIGFzIF9vbmVfIGl0ZW0gbWVudGlvbi4gRm9yIGV4YW1wbGUsIHRoZSB1c2FnZSBzdGF0aXN0aWMgZm9yIFtRNDJdKGh0dHBzOi8vd3d3Lndpa2lkYXRhLm9yZy93aWtpL1E0MikgaXMgdGh1cyB0aGUgc3VtIG9mIHRoZSBjb3VudCBvZiBhbGwgcGFnZXMgYWNyb3NzIGFsbCBXaWtpbWVkaWEgcHJvamVjdHMgdGhhdCBtYWtlIGF0IGxlYXN0IG9uZSB1c2Ugb2YgaXQgLSBhbmQgaXJyZXNwZWN0aXZlIG9mIHRoZSB1c2FnZSBhc3BlY3QuCgpBbGwgZGF0YSBzZXRzIHVwb24gd2hpY2ggdGhpcyBSZXBvcnQgaXMgYmFzZWQgYXJlIHB1YmxpY2x5IGF2YWlsYWJsZSBmcm9tIHRoZSBmb2xsb3dpbmcgVVJMOgoKW2h0dHBzOi8vYW5hbHl0aWNzLndpa2ltZWRpYS5vcmcvZGF0YXNldHMvd21kZS1hbmFseXRpY3MtZW5naW5lZXJpbmcvV2lraWRhdGEvV0RfRGF0YVF1YWxpdHkvXShodHRwczovL2FuYWx5dGljcy53aWtpbWVkaWEub3JnL2RhdGFzZXRzL3dtZGUtYW5hbHl0aWNzLWVuZ2luZWVyaW5nL1dpa2lkYXRhL1dEX0RhdGFRdWFsaXR5LykKCioqKioqKgoKIyBPdmVydmlldwoKYGBge3IgZWNobyA9IFR9CnN0YXRzIDwtIHJlYWQuY3N2KCdodHRwczovL2FuYWx5dGljcy53aWtpbWVkaWEub3JnL2RhdGFzZXRzL3dtZGUtYW5hbHl0aWNzLWVuZ2luZWVyaW5nL1dpa2lkYXRhL1dEX0RhdGFRdWFsaXR5L2RhdGFRdWFsaXR5X1N0YXRzLmNzdicsIAogICAgICAgICAgICAgICAgICBoZWFkZXIgPSBULCAKICAgICAgICAgICAgICAgICAgY2hlY2submFtZXMgPSBGLCAKICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYpCmBgYAoKVGhpcyBSZXBvcnQgZmluZHMgYSB0b3RhbCBudW1iZXIgb2YgKipgciBzdGF0cyR0b3RhbF9uX2l0ZW1zYCoqIGl0ZW1zIGN1cnJlbnRseSBpbiBXaWtpZGF0YSwgb2Ygd2hpY2ggKipgciBzdGF0cyR0b3RhbF9uX2l0ZW1zX3dpdGhfT1JFU19wcmVkaWN0aW9uX2ZpbmFsYCoqIChgciBwYXN0ZTAocm91bmQoc3RhdHMkdG90YWxfbl9pdGVtc193aXRoX09SRVNfcHJlZGljdGlvbl9maW5hbC9zdGF0cyR0b3RhbF9uX2l0ZW1zKjEwMCwgMiksICIlKSIpYCBoYXZlIHJlY2VpdmVkIGEgcXVhbGl0eSBhc3Nlc3NtZW50IGZyb20gdGhlIE9SRVMgc3lzdGVtLiBPdXQgb2YgdGhlIHRvdGFsIG51bWJlciBvZiAqKmByIHN0YXRzJHRvdGFsX25faXRlbXNgKiogaXRlbXMsIFdEQ00gZmluZHMgdGhhdCAqKmByIHN0YXRzJHRvdGFsX25faXRlbXNfdXNlZGAqKiAoYHIgcGFzdGUwKHJvdW5kKHN0YXRzJHRvdGFsX25faXRlbXNfdXNlZC9zdGF0cyR0b3RhbF9uX2l0ZW1zKjEwMCwgMiksICIlKSIpYCBhcmUgcmUtdXNlZCBhY3Jvc3MgdGhlIFdpa2ltZWRpYSBwcm9qZWN0cy4gClRoZSBsYXRlc3QgT1JFUyBwcmVkaWN0aW9uIHJ1biB1cG9uIHdoaWNoIHRoaXMgUmVwb3J0IGlzIGJhc2VkIHdhcyBvbiAqKmByIHN0YXRzJE9SRVNfdGltZXN0YW1wYCoqLCB3aGlsZSB0aGUgbGF0ZXN0IHVwZGF0ZSBvZiB0aGUgV0RDTSByZS11c2Ugc3RhdGlzdGljcyBoYXBwZW5kIG9uICoqYHIgc3RhdHMkV0RDTV90aW1lc3RhbXBgKiouIFRoZSByZXBvcnQgaXMgYmFzZWQgb24gdGhlIGAyMDE5LTA4YCBzbmFwc2hvdCBvZiB0aGUgW3dtZi5tZWRpYXdpa2lfaGlzdG9yeV0oaHR0cHM6Ly93aWtpdGVjaC53aWtpbWVkaWEub3JnL3dpa2kvQW5hbHl0aWNzL0RhdGFfTGFrZS9FZGl0cy9NZWRpYXdpa2lfaGlzdG9yeSkgdGFibGUgaW4gdGhlIFtXTUQgRGF0YSBMYWtlXShodHRwczovL3dpa2l0ZWNoLndpa2ltZWRpYS5vcmcvd2lraS9BbmFseXRpY3MvRGF0YV9MYWtlKSwgYW5kIHRoZSBgMjAxOTA2MDNgIHZlcnNpb24gb2YgdGhlIGBoZGZzYCBbY29weSBvZiB0aGUgV2lraWRhdGEgSlNPTiBkdW1wXShodHRwczovL3BoYWJyaWNhdG9yLndpa2ltZWRpYS5vcmcvVDIwOTY1NSkuCgojIyBRdWFsaXR5IGRpc3RyaWJ1dGlvbiBmb3IgYWxsIGl0ZW1zCgpMb29raW5nIGF0IGFsbCBvZiB0aGUgKipgciBzdGF0cyR0b3RhbF9uX2l0ZW1zX3dpdGhfT1JFU19wcmVkaWN0aW9uX2ZpbmFsYCoqIFdpa2lkYXRhIGl0ZW1zIHRoYXQgaGF2ZSByZWNlaXZlZCBhIHF1YWxpdHkgc2NvcmUgZnJvbSBPUkVTLCB3ZSBmaW5kIHRoZSBmb2xsb3dpbmc6CgpgYGB7ciBlY2hvID0gVH0KZGF0YUEgPC0gcmVhZC5jc3YoJ2h0dHBzOi8vYW5hbHl0aWNzLndpa2ltZWRpYS5vcmcvZGF0YXNldHMvd21kZS1hbmFseXRpY3MtZW5naW5lZXJpbmcvV2lraWRhdGEvV0RfRGF0YVF1YWxpdHkvZGF0YVF1YWxpdHlfb3Jlc1Njb3Jlc0Rpc3RyaWJ1dGlvbi5jc3YnLAogICAgICAgICAgICAgICAgIGhlYWRlciA9IFQsCiAgICAgICAgICAgICAgICAgY2hlY2submFtZXMgPSBGLAogICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGLAogICAgICAgICAgICAgICAgIHJvdy5uYW1lcyA9IDEpCmNvbG5hbWVzKGRhdGFBKSA8LSBjKCdRdWFsaXR5JywgJ051bWJlciBvZiBpdGVtcycpCmRhdGFBJFBlcmNlbnQgPC0gcm91bmQoZGF0YUEkYE51bWJlciBvZiBpdGVtc2Avc3VtKGRhdGFBJGBOdW1iZXIgb2YgaXRlbXNgKSoxMDAsIDIpCkRUOjpkYXRhdGFibGUoZGF0YUEsIAogICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgd2lkdGggPSAnMTAwJScsCiAgICAgICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gIl9hbGwiKSkKICAgICAgICAgICAgICApLAogICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UKICAgICkKYGBgCgojIyBRdWFsaXR5IGRpc3RyaWJ1dGlvbiBmb3IgdGhlIHRvcCAxMCwwMDAgcmUtdXNlZCBpdGVtcwoKTG9va2luZyBvbmx5IGF0IHRoZSB0b3AgMTAsMDAwIG1vc3QgcmUtdXNlZCBpdGVtcyBhY3Jvc3MgdGhlIFdpa2ltZWRpYSBwcm9qZWN0cyBhY2NvcmRpbmcgdG8gdGhlIFdEQ00sIHdlIGZpbmQgdGhlIGZvbGxvd2luZyBkaXN0cmlidXRpb24gb2YgcXVhbGl0eToKCmBgYHtyIGVjaG8gPSBUfQpkYXRhQiA8LSByZWFkLmNzdignaHR0cHM6Ly9hbmFseXRpY3Mud2lraW1lZGlhLm9yZy9kYXRhc2V0cy93bWRlLWFuYWx5dGljcy1lbmdpbmVlcmluZy9XaWtpZGF0YS9XRF9EYXRhUXVhbGl0eS9kYXRhUXVhbGl0eV9vcmVzU2NvcmVzRGlzdHJpYnV0aW9uXzEwMDAwLmNzdicsCiAgICAgICAgICAgICAgICAgaGVhZGVyID0gVCwKICAgICAgICAgICAgICAgICBjaGVjay5uYW1lcyA9IEYsCiAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYsCiAgICAgICAgICAgICAgICAgcm93Lm5hbWVzID0gMSkKY29sbmFtZXMoZGF0YUIpIDwtIGMoJ1F1YWxpdHknLCAnTnVtYmVyIG9mIGl0ZW1zJykKZGF0YUIkUGVyY2VudCA8LSByb3VuZChkYXRhQiRgTnVtYmVyIG9mIGl0ZW1zYC9zdW0oZGF0YUIkYE51bWJlciBvZiBpdGVtc2ApKjEwMCwgMikKRFQ6OmRhdGF0YWJsZShkYXRhQiwgCiAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgICAgICAgICAgICB3aWR0aCA9ICcxMDAlJywKICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSAiX2FsbCIpKQogICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRQogICAgKQpgYGAKCiMjIFF1YWxpdHkgZGlzdHJpYnV0aW9uOiB0b3AgMTBLIG1vc3QgdXNlZCBpdGVtcyB2cyBhbGwgaXRlbXMKCklmIHdlIHdvdWxkIGNvbXBhcmUgdGhlIHF1YWxpdHkgZGlzdHJpYnV0aW9uIG9mIGFsbCBpdGVtcyB0byB0aGUgdG9wIDEwLDAwMCByZS11c2VkIGl0ZW1zIGFjcm9zcyB0aGUgV2lraW1lZGlhIHByb2plY3RzLCB0aGlzIGlzIHRoZSBwaWN0dXJlIHRoYXQgd291bGQgZW1lcmdlOgoKYGBge3IgZWNobyA9IFR9CnF1YWxGcmFtZSA8LSBkYXRhLmZyYW1lKAogIFF1YWxpdHkgPSBjKCJBIiwgIkIiLCAiQyIsICJEIiwgIkUiKSwKICBBbGwgPSBkYXRhQSRQZXJjZW50LAogIFRvcDEwSyA9IGRhdGFCJFBlcmNlbnQsIAogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGKQpxdWFsRnJhbWUgPC0gZ2F0aGVyKHF1YWxGcmFtZSwgCiAgICAgICAgICAgICAgICAgICAga2V5ID0gJ0l0ZW1zJywKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICdQZXJjZW50JywgCiAgICAgICAgICAgICAgICAgICAgMjozKQpnZ3Bsb3QocXVhbEZyYW1lLCAKICAgICAgIGFlcyh4ID0gUXVhbGl0eSwgCiAgICAgICAgICAgeSA9IFBlcmNlbnQsIAogICAgICAgICAgIGdyb3VwID0gSXRlbXMsIAogICAgICAgICAgIGNvbG9yID0gSXRlbXMsIAogICAgICAgICAgIGZpbGwgPSBJdGVtcywgCiAgICAgICAgICAgbGFiZWwgPSBwYXN0ZTAoUGVyY2VudCwgIiAlIikpKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMi41KSArCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAid2hpdGUiKSArIAogIGdlb21fdGV4dF9yZXBlbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPSBjKCJkYXJrYmx1ZSIsICJkYXJrcmVkIikpICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gIndoaXRlIiwgZmlsbCA9ICJ3aGl0ZSIpKSArCiAgICAgIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKwogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKSArIAogICAgICB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKSArCiAgICAgIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKCioqKioqKgoKIyBJdGVtIHF1YWxpdHkgYW5kIHJlLXVzZQoKIyMgSXRlbSByZS11c2Ugdy4gb3V0bGllcnMKCkluIHRoZSBmb2xsb3dpbmcgY2hhcnQgd2UgcHJlc2VudCB0aGUgV0RDTSByZS11c2Ugc3RhdGlzdGljcyAodmVydGljYWwgYXhpcywgbG9nYXJpdGhtaWMgc2NhbGUpIGZvciBhbGwgV2lraWRhdGEgaXRlbXMgcmVzcGVjdGl2ZSBvZiB0aGVpciBwcmVkaWN0ZWQgcXVhbGl0eSBzY29yZSAoQSwgQiwgQywgRCwgb3IgRSkuIFRoZSBob3Jpem9udGFsIGxpbmVzIGluIHRoZSBib3hwbG90cyByZXByZXNlbnQgdGhlIFttZWRpYW5dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01lZGlhbikgdmFsdWVzIG9mIHRoZSByZS11c2Ugc3RhdGlzdGljcywgd2hpbGUgdGhlaXIgbG93ZXIgYW5kIHVwcGVyIGxpbWl0cyByZXByZXNlbnQgdGhlIDFzdCAoLjI1KSBhbmQgdGhlIDNyZCAoLjc1KSBbcXVhcnRpbGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1F1YXJ0aWxlKSwgcmVzcGVjdGl2ZWx5LiBUaGUgZnJlZSBmbG9hdGluZyBwb2ludHMgYWJvdmUgKGFuZCBzb21ldGltZXMgYmVsbG93KSB0aGUgYm94ZXMgYXJlICoqb3V0bGllcnMqKjogdGhleSByZXByZXNlbnQgdGhlIFdpa2lkYXRhIGl0ZW1zIHVzZWQgc3VzcGljaW91c2x5IG1vcmUgKG9yIGxlc3MpIHRoYW4gb3RoZXIgaXRlbXMgX2luIHRoZSBzYW1lIHF1YWxpdHkgY2xhc3NfLiBPbmNlIGFnYWluOiB0aGUgb3V0bGllcnMgaW4gdGhpcyBib3hwbG90IGFyZSBkZXRlY3RlZCBmb3IgZWFjaCBxdWFsaXR5IGNsYXNzIChBLCBCLCBDLCBELCBvciBFKSBzZXBhcmF0ZWx5LiAKCiFbXShodHRwczovL2FuYWx5dGljcy53aWtpbWVkaWEub3JnL2RhdGFzZXRzL3dtZGUtYW5hbHl0aWNzLWVuZ2luZWVyaW5nL1dpa2lkYXRhL1dEX0RhdGFRdWFsaXR5L3Njb3JlVXNhZ2VfQm94UGxvdF9nZ3Bsb3QyLnBuZykKCiMjIEl0ZW0gcmUtdXNlIHcvbyBvdXRsaWVycwoKTm93IHdlIHByZXNlbnQgdGhlIHNhbWUgZGF0YSBleGNlcHQgZm9yIHRoZSBvdXRsaWVycyB0aGF0IGhhdmUgYmVlbiByZW1vdmVkLiBXZSBjYW4gc2VlIHRoYXQgaXRlbSBxdWFsaXR5IGlzIGNvcnJlbGF0ZWQgd2l0aCBpdGVtIHJlLXVzZTogdGhlIGxvd2VyIHRoZSBpdGVtIHF1YWxpdHksIHRoZSBsZXNzIHRoZSBpdGVtIHNlZW1zIHRvIGJlIHJlLXVzZWQgYWNyb3NzIHRoZSBXaWtpbWVkaWEgcHJvamVjdHMuIFRoZSB2ZXJ0aWNhbCBsaW5lcyBhYm92ZSBhbmQgYmVsbG93IHRoZSBib3hlcyBleHRlbmQgdG8gYFEzKzEuNSpJUVJgIGFuZCBgUTEtMS41KklRUmAgcmVzcGVjdGl2ZWx5LCB3aGVyZSBgSVFSYCBpcyB0aGUgW0ludGVycXVhcnRpbGUgcmFuZ2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ludGVycXVhcnRpbGVfcmFuZ2UpOyB0aGUgb3V0bGllcnMsIGlmIGFueSByZW1haW5lZCBoZXJlLCB3b3VsZCBiZSBzaG93biBiZWxsb3cgYW5kIGFib3ZlIHRoZXNlIGxpbWl0cy4KCiFbXShodHRwczovL2FuYWx5dGljcy53aWtpbWVkaWEub3JnL2RhdGFzZXRzL3dtZGUtYW5hbHl0aWNzLWVuZ2luZWVyaW5nL1dpa2lkYXRhL1dEX0RhdGFRdWFsaXR5L3Njb3JlVXNhZ2VfQm94UGxvdF9nZ3Bsb3QyX291dGxpZXJzX3JlbW92ZWQucG5nKQoKIyMgRGl2ZXJzaXR5IG9mIGl0ZW0gcmUtdXNlIHZzIGl0ZW0gcXVhbGl0eQoKVGhlIGZvbGxvd2luZyBjaGFydCBwcm92aWRlcyBhbiBpbi1kZXB0aCBpbnNpZ2h0IGludG8gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGl0ZW0gcXVhbGl0eSAoYXMgcHJlZGljdGVkIGJ5IE9SRVMpIGFuZCBpdGVtIHJlLXVzZSBhY3Jvc3MgdGhlIFdpa2ltZWRpYSBwcm9qZWN0cyAoYXMgYXNzZXNzZWQgYnkgV0RDTSkuCkVhY2ggYnViYmxlIHJlcHJlc2VudHMgKHBvdGVudGlhbGx5KSBtYW55IFdpa2lkYXRhIGl0ZW1zLiBMZXQncyBmb2N1cyBvbiBhIHNpbmdsZSBxdWFsaXR5IGNsYXNzLCBgQWAgZm9yIGV4YW1wbGUuIEFueSBgQWAgY2xhc3MgaXRlbSBjb3VsZCBiZSByZS11c2VkIF8xXywgXzJfLCBfM18sIC4uLCBfbl8sIGV0Yy4gdGltZXMgYWNyb3NzIHRoZSBwcm9qZWN0cy4gRWFjaCBidWJibGUgaW4gdGhpcyBjaGFydCByZXByZXNlbnRzIF9hbGxfIFdpa2lkYXRhIGl0ZW1zIGluIHRoZSByZXNwZWN0aXZlIHF1YWxpdHkgY2xhc3MgdGhhdCBfc2hhcmUgdGhlIHNhbWUgdmFsdWUgb2YgdGhlIHJlLXVzZSBzdGF0aXN0aWNfICh5LWF4aXMsIGxvZyBzY2FsZSkuIFRoZSBzaXplIG9mIHRoZSBidWJibGUgY29ycmVzcG9uZHMgdG8gdGhlIG51bWJlciBvZiBpdGVtcyB0aGF0IGl0IHJlcHJlc2VudHMgKGkuZS4gdGhlIG51bWJlciBvZiBpdGVtcyB0aGF0IHNoYXJlIHRoZSBzYW1lIHZhbHVlIG9mIHRoZSByZS11c2Ugc3RhdGlzdGljKS4KRnJvbSB0aGUgY2hhcnQgd2UgY2FuIG9ic2VydmUgdGhlIGZvbGxvd2luZzogdGhlIGxvd2VyIHRoZSBpdGVtIHF1YWxpdHkgY2xhc3MgKEEgPiBCID4gQyA+IEQgPiBFKSwgdGhlIGxlc3NlciB0aGUgbnVtYmVyIG9mIHVuaXF1ZSByZS11c2Ugc3RhdGlzdGljIHZhbHVlcyB0aGF0IHRoZSBpdGVtcyBmcm9tIHRoZSByZXNwZWN0aXZlIGNsYXNzIHRha2UuCgohW10oaHR0cHM6Ly9hbmFseXRpY3Mud2lraW1lZGlhLm9yZy9kYXRhc2V0cy93bWRlLWFuYWx5dGljcy1lbmdpbmVlcmluZy9XaWtpZGF0YS9XRF9EYXRhUXVhbGl0eS9zY29yZVVzYWdlX0JveFBsb3RfZ2dwbG90Ml9vdXRsaWVyc19yZW1vdmVkX3VuaXF1ZV92YWx1ZXMucG5nKQoKClRoZSBkaXZlcnNpdHkgb2YgdGhlIHVuaXF1ZSB2YWx1ZXMgb2YgdGhlIHJlLXVzZSBzdGF0aXN0aWMgaXMgbXVjaCBoaWdoZXIgaW4gdGhlIGBBYCBxdWFsaXR5IGNsYXNzLCBmb3IgZXhhbXBsZSwgdGhhbiBpbiB0aGUgYERgIG9yIGBFYCBjbGFzc2VzICh3aGVyZSB0aGUgcmUtdXNlIHN0YXRpc3RpYyB0YWtlcyBvbmx5IHRocmVlIHVuaXF1ZSB2YWx1ZXMpLiBUaGlzIF9taWdodF8gYmUgYSBjb25zZXF1ZW5jZSBvZiAoYSkgbW9yZSBodW1hbiBvciBodW1hbnxtYWNoaW5lIGVuZ2FnZW1lbnQgaW4gdGhlIHJlLXVzZSBvZiB0aGUgdG9wIHF1YWxpdHkgYEFgIGl0ZW1zIGFjcm9zcyB0aGUgcHJvamVjdHMgYW5kIChiKSBtb3JlIHB1cmUgbWFjaGluZSBlbmdhZ2VtZW50IGluIHRoZSByZS11c2Ugb2YgdGhlIGBEYCBhbmQgYEVgIGxvd2VyIHF1YWxpdHkgaXRlbXMuCgojIyBEaXN0cmlidXRpb24gb2YgaXRlbSByZS11c2Ugd2l0aGluIHRoZSBxdWFsaXR5IGNsYXNzZXMKClRoZSBwYW5lbHMgaW4gdGhlIGZvbGxvd2luZyBjaGFydCBwcmVzZW50IHRoZSBkaXN0cmlidXRpb25nIG9mIHRoZSBXRENNIHJlLXVzZSBzdGF0aXN0aWMgKGxvZyBzY2FsZSwgaG9yaXpvbnRhbCBheGVzKSBhY3Jvc3MgdGhlIGl0ZW0gcXVhbGl0eSBjbGFzc2VzIChBLCBCLCBDLCBELCBvciBFOiBkaWZmZXJlbnQgcGFuZWxzKS4gVGhlIHZlcnRpY2FsIGF4ZXMgcmVwcmVzZW50IHRoZSBudW1iZXIgb2YgV2lraWRhdGEgaXRlbXMgZm91bmQgaW4gZWFjaCBiaW4gb2YgdGhlIHJlc3BlY3RpdmUgZGlzdHJpYnV0aW9uLgoKIVtdKGh0dHBzOi8vYW5hbHl0aWNzLndpa2ltZWRpYS5vcmcvZGF0YXNldHMvd21kZS1hbmFseXRpY3MtZW5naW5lZXJpbmcvV2lraWRhdGEvV0RfRGF0YVF1YWxpdHkvZGlzdHJpYnV0aW9uX1F1YWxpdHlfVVNhZ2UucG5nKQoKCioqKioqKgoKCiMgVGhlIGxhdGVzdCByZXZpZHMgYnkgcXVhbGl0eSBjbGFzcwoKVGhlIGZvbGxvd2luZyBjaGFydCBoYXMgdGltZSAoaW4gYSBgWVlZWS1NTWAgZm9ybWF0LCBhbmQgdGh1cyBhIG1vbnRobHkgYWdncmVnYXRlKSBvbiB0aGUgaG9yaXpvbnRhbCBheGlzLCBhbmQgdGhlIG51bWJlciBvZiBpdGVtcyAob24gYSBsb2dhcml0aG1pYyBzY2FsZSkgb24gdGhlIHZlcnRpY2FsIGF4aXMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIFdpa2lkYXRhIGl0ZW1zIHRoYXQgaGF2ZSByZWNlaXZlZCB0aGVpciBsYXRlc3QgcmV2aXNpb24gaW4gdGhlIHJlc3BlY3RpdmUgeWVhciBhbmQgbW9udGguIFRoZSBxdWFsaXR5IGNsYXNzZXMgKEEsIEIsIEMsIEQsIG9yIEUpIGFyZSByZXByZXNlbnRlZCBieSBzZXBhcmF0ZSBsaW5lcyBjb25uZWN0aW5nIHRoZSBkYXRhIHBvaW50cy4KV2hhdCB3ZSBjYW4gc2VlIGlzIHRoYXQgdGhlIHRvcCBxdWFsaXR5IGNsYXNzIGBBYCBpdGVtcyBhcmUgYXQgdGhlIHNhbWUgdGltZSB0aGUgbW9zdCByZXZpc3RlZCBvbmVzLiBUaGUgcGF0dGVybiBpcyBzaW1pbGFyIGZvciB0aGUgYEJgIGNsYXNzIGl0ZW1zLCB3aGlsZSBpdCBzZWVtcyB0aGF0IHRoZXJlIGFyZSBtYW55IGBDYCwgYERgLCBhbmQgYEVgIGNsYXNzIGl0ZW1zIHRoYXQgd2VyZSByZXZpc2VkIG9ubHkgYSBsb25nIHRpbWUgYWdvLgoKIVtdKGh0dHBzOi8vYW5hbHl0aWNzLndpa2ltZWRpYS5vcmcvZGF0YXNldHMvd21kZS1hbmFseXRpY3MtZW5naW5lZXJpbmcvV2lraWRhdGEvV0RfRGF0YVF1YWxpdHkvcmV2aWRzX3RpbWVsaW5lX3F1YWxpdHlfY2xhc3Nlcy5wbmcpCgoKKioqKioqCgojIENyaXRpY2FsIFdpa2lkYXRhIGl0ZW1zCgpXZSBwcm92aWRlIGEgW2xpc3RdKGh0dHBzOi8vYW5hbHl0aWNzLndpa2ltZWRpYS5vcmcvZGF0YXNldHMvd21kZS1hbmFseXRpY3MtZW5naW5lZXJpbmcvV2lraWRhdGEvV0RfRGF0YVF1YWxpdHkvcG9zaXRpdmVPdXRsaWVycy5jc3YpIG9mIGFsbCBXaWtpZGF0YSBpdGVtcyBzY29yZWQgYXMgaW1wZXJmZWN0IChpLmUuIGZvdW5kIGluIHRoZSBCLCBDLCBELCBvciBFIHF1YWxpdHkgY2xhc3MpIHRoYXQgYXJlIGFsc28gZm91bmQgYXMgb3V0bGllcnMgaW4gdGVybXMgb2YgdGhlaXIgcmUtdXNlIChpLmUuIGJlaW5nIHVzZWQgc3VzcGljaW91c2x5IG1vcmUgdGhhbiBhbGwgb3RoZXIgV2lraWRhdGEgaXRlbXMgYWNyb3NzIHRoZSBXaWtpbWVkaWEgcHJvamVjdHMpLiBUaGUgbGlzdCBlbmNvbXBhc3NlcyB0aGUgdG9wIDEsMDAwIG1vc3QgcmUtdXNlZCBpdGVtcyBvZiBpbXBlcmZlY3QgcXVhbGl0eSBmcm9tIGVhY2ggcXVhbGl0eSBjbGFzcyB0aGF0IGFyZSByZWNvZ25pemVkIGFzIG91dGxpZXJzIGluIHRlcm1zIG9mIHRoZWlyIHJlLXVzZS4gVGhlIGl0ZW1zIGZyb20gdGhlIGBEYCBhbmQgYEVgIGNsYXNzZXMgaW4gdGhpcyBsaXN0IGFyZSBwcm9iYWJseSB0aGUgbW9zdCBjcml0aWNhbCBXaWtpZGF0YSBpdGVtcyBhbmQgbmVlZCB0byBiZSBpbXByb3ZlZCBpbW1lZGlhdGVseS4KCmBgYHtyIGVjaG8gPSBUfQpjcml0aWNhbCA8LSByZWFkLmNzdignaHR0cHM6Ly9hbmFseXRpY3Mud2lraW1lZGlhLm9yZy9kYXRhc2V0cy93bWRlLWFuYWx5dGljcy1lbmdpbmVlcmluZy9XaWtpZGF0YS9XRF9EYXRhUXVhbGl0eS9wb3NpdGl2ZU91dGxpZXJzLmNzdicsCiAgICAgICAgICAgICAgICAgaGVhZGVyID0gVCwKICAgICAgICAgICAgICAgICBjaGVjay5uYW1lcyA9IEYsCiAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYsCiAgICAgICAgICAgICAgICAgcm93Lm5hbWVzID0gMSkKY29sbmFtZXMoY3JpdGljYWwpIDwtIGMoJ0l0ZW0nLCAnUXVhbGl0eScsICdSZS11c2UnKQpjcml0aWNhbCR1cmwgPC0gcGFzdGUwKCdodHRwczovL3d3dy53aWtpZGF0YS5vcmcvd2lraS8nLCBjcml0aWNhbCRJdGVtKQpjcml0aWNhbCRJdGVtIDwtIHBhc3RlMCgnPGEgaHJlZj0iJywgY3JpdGljYWwkdXJsLCAnIiB0YXJnZXQ9Il9ibGFuayI+JywgY3JpdGljYWwkSXRlbSwgIjwvYT4iKQpjcml0aWNhbCR1cmwgPC0gTlVMTApjcml0aWNhbCA8LSBjcml0aWNhbCAlPiUgCiAgZHBseXI6OmFycmFuZ2UoZGVzYyhRdWFsaXR5KSwgZGVzYyhgUmUtdXNlYCkpCkRUOjpkYXRhdGFibGUoY3JpdGljYWwsIAogICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwMCwgCiAgICAgICAgICAgICAgICB3aWR0aCA9ICcxMDAlJywKICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSAiX2FsbCIpKQogICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgZXNjYXBlID0gRkFMU0UsCiAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRQogICAgKQpgYGAKCioqKioqKgoKV2Ugd2lzaCB0byB0aGFuayBhbGwgdGhlIG1lbWJlciBvZiB0aGUgW09SRVNdKGh0dHBzOi8vd3d3Lm1lZGlhd2lraS5vcmcvd2lraS9PUkVTKSB0ZWFtIGZvciB0aGVpciBoZWxwIGluIHRoZSBwcm9kdWN0aW9uIG9mIHRoaXMgcmVwb3J0LgoKKioqKioqCgoKIVtdKFdpa2ltZWRpYV9EZXV0c2NobGFuZF9Mb2dvX3NtYWxsLnBuZykgCgoKCgoKCgoK