Summary

  1. Most of the outliers from the Service_Number variable have Sow_Date_BreedingHerd_Available values from 1951.

  2. Those farms with few services have either a very high or very low Service_Count_Matings mean and a low mean for the SowParity_Number variable. They also have a low mean for the SowParity_Number variable.

  3. It appears that the farms that are outliers (Sow Parity) either have low or high means for the Service_Count_Matings variable.

  4. The variable SowParity_Number have 1 observation with the value of 100 and 11 observations with 20 or more. I do not know if that is possible considering that pigs live between 15 and 20 years.

  5. There are 5 observations of the Sow_Date_Mating_First variable from the year 1961 and a few others from the early 2000s.

  6. For the variable Sow_Date_BreedingHerd_Available there are 20,869 observations from the year 1951 and a small number from the 60’s, 70’s and 90’s

  7. The FarrowingRate variable has many outliers. However, most of them are from the year 2020.

  8. Most of the farms with few services have a very low farrowing rate mean. All outliers for the farrowing rate are also outliers for the number of services.

Observations

Service Count Mating

1 and 2 are by far the most common values. Looking at a bar graph the differences can be better seen.

let’s look for outliers.

Let’s look at the percentage of outliers per farm.

The percentages of outliers per farm are too small to find any kind of pattern.

Service_Date_Mating_First

Unusual trends that could represent outliers are not appreciated. There are many years in which the numbers drop in the last week of December, or the first week of January. There is a clear increase in the trend the summer of 2018 to date. There is a small negative trend from June 2020 to January 2021, perhaps attributable to covid.

Service_IsRepeat

As you can see, most of the services are not repetitions. They have a ratio of 10.2.

Service_Number

Looking at these values it seems that perhaps there are some observations that are outliers. Let’s look at those observations that have more than 10 services. Specifically, let’s look at the farms where these come from.

What is striking is that for the variable Sow_Date_BreedingHerd_Available most of the observations are from the year 1951, with the exception of the 2 observations from farms BN1S and BP1S

Site_Code

There are 8 farms that can be considered outliers. Let’s look at their frequencies.

I want to see if there are substantial differences between farms. With that goal, I will start by analyzing the variable Service_Count_Matings by Site_Code

It is interesting to note that the outliers are usually at the extremes. In other words, those farms with few observations have either a very high or very low Service_Count_Matings mean.

Now, I will do the same for the mean Service_Number

There is no clear pattern. The only thing that can be appreciated is that those farms with a Service_Number mean of 1 are all outliers.

Now with SowParity_Number

There is a clear pattern. Most outliers have a low mean for the SowParity_Number variable.

SowParity_Number

There’s one observation with a value of SowParity_Number of 100. There’s other with 20 or more, I don’t know if that is possible considering how many years pig usually live.

Let’s take a look at the mean of the sow parity by farm.

Most of the farms that are outliers correspond to farms with very few services.

Now the same graph but using Service_Count_Matings

It appears that the farms that are outliers (Sow Parity) either have low or high means for the Service_Count_Matings variable.

Sow_Date_Mating_First

  1. There are very few observations before 2012.
  2. There is a peak in December 2016 - January 2017.
  3. Since 2019 there is a downward trend.
  4. This type of distribution perhaps makes sense if we consider how long pigs live

There are 5 observations from 1961 and a few from the early 2000s. Most likely, they will need to be eliminated.

Sow_Date_BreedingHerd_Available

The big difference, between this graph and the previous one, is that there is a peak in the 50’s

There are many old observations.

Response Data

Site_Code

Looking at the number of services per farm.

There are several farms with few services. Let’s look at the farrowing rate mean by location.

Let’s look at a scatterplot with the mean of the farrowing rate versus the number of services per farm.

Although there is no linear relationship between the variables, it can be seen that most of the farms with few services have a very low farrowing rate mean. All outliers for the farrowing rate are also outliers for the number of services.

FarrowingRate

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.7636  0.8246  0.7889  0.8655  0.9863 

Let’s look at the proportions of outliers per farm

The proportion of outliers is much lower in those farms with fewer observations, however there are many farms with many services that still have many outliers (MLSS, WHSS, CLXS, NVNS).

Let’s take a look at the number of services per year

x<-data1 %>% separate(ServiceYearWeek,into=c("year","week"),sep="-")%>% filter(FarrowingRate<0.60) %>% count(year,sort=TRUE)%>% rename(Outliers=n)


DT::datatable(x, rownames = FALSE,
          options = list(
            columnDefs = list(list(className = 'dt-center', targets = 0:1))))
NA

Most of the observations are from 2020, these outliers may be a product of the pandemic. Maybe it’s not good to delete them. Let’s do a chi square test to be sure.

Given the p-value, it is possible to say that the number of outliers and the years are related. Let’s look at the residuals to have a better idea about what’s going on.

   
           2016        2017        2018        2019        2020        2021
  0 -0.35116697 -0.13679451  0.78403993  0.95485363 -1.17885258 -0.07825466
  1  1.32259468  0.51520703 -2.95291739 -3.59625035  4.43989410  0.29472929

It is important to mention that the rule of thumb is that if the values of a cell are above 2, we have more observations than expected. On the other hand, if the cell value is less than -2 we have fewer values than expected. Looking at this table, we can say that for 2018 and 2019 we have fewer outliers than expected. As for the year 2020, we have more outliers than expected.

LS0tDQp0aXRsZTogIk91dGxpZXJzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0aGVtZTogdW5pdGVkDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHRydWUNCi0tLQ0KDQojIyBTdW1tYXJ5DQoNCjEpIE1vc3Qgb2YgdGhlIG91dGxpZXJzIGZyb20gdGhlICoqU2VydmljZV9OdW1iZXIqKiB2YXJpYWJsZSBoYXZlICoqU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSoqIHZhbHVlcyBmcm9tIDE5NTEuDQoNCjIpIFRob3NlIGZhcm1zIHdpdGggZmV3IHNlcnZpY2VzIGhhdmUgZWl0aGVyIGEgdmVyeSBoaWdoIG9yIHZlcnkgbG93ICoqU2VydmljZV9Db3VudF9NYXRpbmdzKiogbWVhbiBhbmQgYSBsb3cgbWVhbiBmb3IgdGhlICoqU293UGFyaXR5X051bWJlcioqIHZhcmlhYmxlLiBUaGV5IGFsc28gaGF2ZSBhIGxvdyBtZWFuIGZvciB0aGUgKipTb3dQYXJpdHlfTnVtYmVyKiogdmFyaWFibGUuDQoNCjMpIEl0IGFwcGVhcnMgdGhhdCB0aGUgZmFybXMgdGhhdCBhcmUgb3V0bGllcnMgKFNvdyBQYXJpdHkpIGVpdGhlciBoYXZlIGxvdyBvciBoaWdoIG1lYW5zIGZvciB0aGUgKipTZXJ2aWNlX0NvdW50X01hdGluZ3MqKiB2YXJpYWJsZS4NCg0KNCkgVGhlIHZhcmlhYmxlICoqU293UGFyaXR5X051bWJlcioqIGhhdmUgMSBvYnNlcnZhdGlvbiB3aXRoIHRoZSB2YWx1ZSBvZiAxMDAgYW5kIDExIG9ic2VydmF0aW9ucyB3aXRoIDIwIG9yIG1vcmUuIEkgZG8gbm90IGtub3cgaWYgdGhhdCBpcyBwb3NzaWJsZSBjb25zaWRlcmluZyB0aGF0IHBpZ3MgbGl2ZSBiZXR3ZWVuIDE1IGFuZCAyMCB5ZWFycy4NCg0KNSkgVGhlcmUgYXJlIDUgb2JzZXJ2YXRpb25zIG9mIHRoZSAqKlNvd19EYXRlX01hdGluZ19GaXJzdCoqIHZhcmlhYmxlIGZyb20gdGhlIHllYXIgMTk2MSBhbmQgYSBmZXcgb3RoZXJzIGZyb20gdGhlIGVhcmx5IDIwMDBzLg0KDQo2KSBGb3IgdGhlIHZhcmlhYmxlICoqU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSoqIHRoZXJlIGFyZSAyMCw4Njkgb2JzZXJ2YXRpb25zIGZyb20gdGhlIHllYXIgMTk1MSBhbmQgYSBzbWFsbCBudW1iZXIgZnJvbSB0aGUgNjAncywgNzAncyBhbmQgOTAncw0KDQo3KSBUaGUgKipGYXJyb3dpbmdSYXRlKiogdmFyaWFibGUgaGFzIG1hbnkgb3V0bGllcnMuIEhvd2V2ZXIsIG1vc3Qgb2YgdGhlbSBhcmUgZnJvbSB0aGUgeWVhciAyMDIwLg0KDQo4KSBNb3N0IG9mIHRoZSBmYXJtcyB3aXRoIGZldyBzZXJ2aWNlcyBoYXZlIGEgdmVyeSBsb3cgZmFycm93aW5nIHJhdGUgbWVhbi4gQWxsIG91dGxpZXJzIGZvciB0aGUgZmFycm93aW5nIHJhdGUgYXJlIGFsc28gb3V0bGllcnMgZm9yIHRoZSBudW1iZXIgb2Ygc2VydmljZXMuDQoNCg0KYGBge3IsZWNobz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KGdyaWRFeHRyYSkNCmxpYnJhcnkoYnJvb20pDQoNCmBgYA0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KZGF0YSA8LSByZWFkLmNzdihmaWxlLmNob29zZSgpKQ0KDQpgYGANCg0KIyBPYnNlcnZhdGlvbnMNCg0KIyMgU2VydmljZSBDb3VudCBNYXRpbmcNCg0KMSBhbmQgMiBhcmUgYnkgZmFyIHRoZSBtb3N0IGNvbW1vbiB2YWx1ZXMuIExvb2tpbmcgYXQgYSBiYXIgZ3JhcGggdGhlIGRpZmZlcmVuY2VzIGNhbiBiZSBiZXR0ZXIgc2Vlbi4NCg0KYGBge3IsZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KDQoNCmdncGxvdChkYXRhLCBtYXBwaW5nID0gYWVzKHggPSBTZXJ2aWNlX0NvdW50X01hdGluZ3MpKSArIA0KICBnZW9tX2JhcigpKyAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKSsNCnRoZW1lX2xpZ2h0KCkNCg0KDQoNCmBgYA0KDQpsZXQncyBsb29rIGZvciBvdXRsaWVycy4NCg0KYGBge3IsZWNobz1GQUxTRX0NCg0KZGF0YSU+JSBnZ3Bsb3QoYWVzKHg9U2VydmljZV9Db3VudF9NYXRpbmdzKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkrdGhlbWVfbGlnaHQoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpK2dndGl0bGUoIk51bWJlciBvZiBNYXRpbmdzIGJ5IFNlcnZpY2UiKQ0KYGBgDQoNCkxldCdzIGxvb2sgYXQgdGhlIHBlcmNlbnRhZ2Ugb2Ygb3V0bGllcnMgcGVyIGZhcm0uDQoNCmBgYHtyLGVjaG89RkFMU0Usd2FybmluZz1GQUxTRX0NCg0KDQpkYXRhPC1kYXRhICU+JSAgbXV0YXRlKG91dGxpZXI9aWZlbHNlKFNlcnZpY2VfQ291bnRfTWF0aW5ncz4zLDEsMCkpDQoNCng8LWRhdGEgJT4lIGdyb3VwX2J5KFNpdGVfQ29kZSkgJT4lIHN1bW1hcml6ZShPdXRsaWVycz1zdW0ob3V0bGllciksU2VydmljZXM9bigpLFBlcmNlbnRhZ2U9cm91bmQoKE91dGxpZXJzKjEwMCkvU2VydmljZXMsNCkpICU+JSBhcnJhbmdlKGRlc2MoUGVyY2VudGFnZSkpDQoNCg0KRFQ6OmRhdGF0YWJsZSh4LCByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KA0KICAgICAgICAgICAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDA6MykpKSkNCg0KDQoNCiAgDQpgYGANCg0KVGhlIHBlcmNlbnRhZ2VzIG9mIG91dGxpZXJzIHBlciBmYXJtIGFyZSB0b28gc21hbGwgdG8gZmluZCBhbnkga2luZCBvZiBwYXR0ZXJuLg0KDQojIyBTZXJ2aWNlX0RhdGVfTWF0aW5nX0ZpcnN0DQoNCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCmRhdGEgJT4lIGNvdW50KFNlcnZpY2VfRGF0ZV9NYXRpbmdfRmlyc3Qsc29ydD1UUlVFKSAlPiUNCiAgbXV0YXRlKFNlcnZpY2VfRGF0ZV9NYXRpbmdfRmlyc3QgPSB5bWQoU2VydmljZV9EYXRlX01hdGluZ19GaXJzdCkpICU+JSANCiBncm91cF9ieSh3ZWVrPWZsb29yX2RhdGUoU2VydmljZV9EYXRlX01hdGluZ19GaXJzdCwgIndlZWsiKSkgJT4lIA0KICBzdW1tYXJpemUobj1tZWFuKG4pKSAlPiUgDQogIHBsb3RfbHkoIHggPSB+d2VlaykgJT4lIGFkZF90cmFjZSh5ID0gfm4sIG5hbWUgPSAndHJhY2UgMCcsbW9kZSA9ICdsaW5lcycpJT4lIA0KICBsYXlvdXQodGl0bGUgPSAiRmlyc3QgU2VydmljZSBEYXRlIE92ZXIgdGhlIFllYXJzICIpICANCiAgDQoNCmBgYA0KDQpVbnVzdWFsIHRyZW5kcyB0aGF0IGNvdWxkIHJlcHJlc2VudCBvdXRsaWVycyBhcmUgbm90IGFwcHJlY2lhdGVkLiBUaGVyZSBhcmUgbWFueSB5ZWFycyBpbiB3aGljaCB0aGUgbnVtYmVycyBkcm9wIGluIHRoZSBsYXN0IHdlZWsgb2YgRGVjZW1iZXIsIG9yIHRoZSBmaXJzdCB3ZWVrIG9mIEphbnVhcnkuIFRoZXJlIGlzIGEgY2xlYXIgaW5jcmVhc2UgaW4gdGhlIHRyZW5kIHRoZSBzdW1tZXIgb2YgMjAxOCB0byBkYXRlLiBUaGVyZSBpcyBhIHNtYWxsIG5lZ2F0aXZlIHRyZW5kIGZyb20gSnVuZSAyMDIwIHRvIEphbnVhcnkgMjAyMSwgcGVyaGFwcyBhdHRyaWJ1dGFibGUgdG8gY292aWQuIA0KDQoNCiMjIFNlcnZpY2VfSXNSZXBlYXQNCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3QoZGF0YSwgbWFwcGluZyA9IGFlcyh4ID0gYXMuZmFjdG9yKFNlcnZpY2VfSXNSZXBlYXQpKSkgKyANCiAgZ2VvbV9iYXIoKSsgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkrDQp0aGVtZV9saWdodCgpK3hsYWIoIlNlcnZpY2VfSXNSZXBlYXQiKQ0KDQpgYGANCg0KQXMgeW91IGNhbiBzZWUsIG1vc3Qgb2YgdGhlIHNlcnZpY2VzIGFyZSBub3QgcmVwZXRpdGlvbnMuIFRoZXkgaGF2ZSBhIHJhdGlvIG9mIDEwLjIuDQoNCiMjIFNlcnZpY2VfTnVtYmVyDQoNCmBgYHtyLGVjaG89RkFMU0Usd2FybmluZz1GQUxTRX0NCmdncGxvdChkYXRhLCBtYXBwaW5nID0gYWVzKHggPSBhcy5mYWN0b3IoU2VydmljZV9OdW1iZXIpKSkgKyANCiAgZ2VvbV9iYXIoKSsgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkrDQp0aGVtZV9saWdodCgpK3hsYWIoIlNlcnZpY2UgTnVtYmVyIikNCg0KYGBgDQogDQogDQpMb29raW5nIGF0IHRoZXNlIHZhbHVlcyBpdCBzZWVtcyB0aGF0IHBlcmhhcHMgdGhlcmUgYXJlIHNvbWUgb2JzZXJ2YXRpb25zIHRoYXQgYXJlIG91dGxpZXJzLiBMZXQncyBsb29rIGF0IHRob3NlIG9ic2VydmF0aW9ucyB0aGF0IGhhdmUgbW9yZSB0aGFuIDEwIHNlcnZpY2VzLiBTcGVjaWZpY2FsbHksIGxldCdzIGxvb2sgYXQgdGhlIGZhcm1zIHdoZXJlIHRoZXNlIGNvbWUgZnJvbS4gDQoNCg0KYGBge3IsZWNobz1GQUxTRX0NCg0KWDwtZGF0YSAlPiUgZmlsdGVyKFNlcnZpY2VfTnVtYmVyPjEwKSAlPiUgY291bnQoU2l0ZV9Db2RlLHNvcnQ9VFJVRSkgJT4lIHJlbmFtZShPdXRsaWVycz1uKQ0KDQoNCkRUOjpkYXRhdGFibGUoWCwgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdCgNCiAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSAwOjEpKSkpDQoNCmBgYA0KDQoNCldoYXQgaXMgc3RyaWtpbmcgaXMgdGhhdCBmb3IgdGhlIHZhcmlhYmxlIFNvd19EYXRlX0JyZWVkaW5nSGVyZF9BdmFpbGFibGUgbW9zdCBvZiB0aGUgb2JzZXJ2YXRpb25zIGFyZSBmcm9tIHRoZSB5ZWFyIDE5NTEsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiB0aGUgMiBvYnNlcnZhdGlvbnMgZnJvbSBmYXJtcyBCTjFTIGFuZCBCUDFTDQoNCmBgYHtyLGVjaG89RkFMU0Usd2FybmluZz1GQUxTRX0NCg0KWDwtZGF0YSAlPiUgZmlsdGVyKFNlcnZpY2VfTnVtYmVyPjEwKSAlPiUgY291bnQoU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSxzb3J0PVRSVUUpJT4lIHJlbmFtZShPdXRsaWVycz1uKQ0KDQpEVDo6ZGF0YXRhYmxlKFgsIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gMDoxKSkpKQ0KDQpgYGANCg0KDQojIyBTaXRlX0NvZGUNCg0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KDQpkYXRhJT4lIGNvdW50KFNpdGVfQ29kZSxzb3J0PVRSVUUpICU+JSBnZ3Bsb3QoYWVzKHg9bG9nKG4pKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkrdGhlbWVfbGlnaHQoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpK2dndGl0bGUoIk51bWJlciBvZiBTZXJ2aWNlcyBieSBGYXJtIikNCg0KDQpgYGANCg0KVGhlcmUgYXJlIDggZmFybXMgdGhhdCBjYW4gYmUgY29uc2lkZXJlZCBvdXRsaWVycy4gTGV0J3MgbG9vayBhdCB0aGVpciBmcmVxdWVuY2llcy4NCg0KYGBge3IsZWNobz1GQUxTRX0NCg0KWDwtZGF0YSU+JSBjb3VudChTaXRlX0NvZGUsc29ydD1UUlVFKSAlPiUgbXV0YXRlKHJhbms9cmFuayhuKSkgJT4lIGZpbHRlcihyYW5rPDkpICU+JSBzZWxlY3QoMToyKSU+JSByZW5hbWUoT3V0bGllcnM9bikNCg0KRFQ6OmRhdGF0YWJsZShYLCByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KA0KICAgICAgICAgICAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDA6MSkpKSkNCg0KDQpgYGANCg0KSSB3YW50IHRvIHNlZSBpZiB0aGVyZSBhcmUgc3Vic3RhbnRpYWwgZGlmZmVyZW5jZXMgYmV0d2VlbiBmYXJtcy4gV2l0aCB0aGF0IGdvYWwsIEkgd2lsbCBzdGFydCBieSBhbmFseXppbmcgdGhlIHZhcmlhYmxlIFNlcnZpY2VfQ291bnRfTWF0aW5ncyBieSBTaXRlX0NvZGUNCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCnA8LWRhdGEgJT4lIGdyb3VwX2J5KFNpdGVfQ29kZSkgJT4lIHN1bW1hcml6ZShNZWFuX1NlcnZpY2VfQ291bnRfTWF0aW5ncz1tZWFuKFNlcnZpY2VfQ291bnRfTWF0aW5ncyksbj1uKCkpJT4lIG11dGF0ZShyYW5rPXJhbmsobiksb3V0bGllcj1pZmVsc2UocmFuazw5LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhNZWFuX1NlcnZpY2VfQ291bnRfTWF0aW5ncyxsb2cobiksY29sb3I9b3V0bGllciwgdGV4dCA9IHBhc3RlKCJGYXJtOiAiLCBTaXRlX0NvZGUpKSkrZ2VvbV9wb2ludCgpK3RoZW1lX2xpZ2h0KCkNCg0KDQpnZ3Bsb3RseShwLCB0b29sdGlwPSJ0ZXh0IiwgaGVpZ2h0ID0gNTAwKQ0KDQpgYGANCg0KSXQgaXMgaW50ZXJlc3RpbmcgdG8gbm90ZSB0aGF0IHRoZSBvdXRsaWVycyBhcmUgdXN1YWxseSBhdCB0aGUgZXh0cmVtZXMuIEluIG90aGVyIHdvcmRzLCB0aG9zZSBmYXJtcyB3aXRoIGZldyBvYnNlcnZhdGlvbnMgaGF2ZSBlaXRoZXIgYSB2ZXJ5IGhpZ2ggb3IgdmVyeSBsb3cgU2VydmljZV9Db3VudF9NYXRpbmdzIG1lYW4uDQoNCk5vdywgSSB3aWxsIGRvIHRoZSBzYW1lIGZvciB0aGUgbWVhbiBTZXJ2aWNlX051bWJlcg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCg0KcDwtZGF0YSAlPiUgZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKE1lYW5fU2VydmljZV9OdW1iZXI9bWVhbihTZXJ2aWNlX051bWJlciksbj1uKCkpJT4lIG11dGF0ZShyYW5rPXJhbmsobiksb3V0bGllcj1pZmVsc2UocmFuazw5LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhNZWFuX1NlcnZpY2VfTnVtYmVyLGxvZyhuKSxjb2xvcj1vdXRsaWVyLCB0ZXh0ID0gcGFzdGUoIkZhcm06ICIsIFNpdGVfQ29kZSkpKStnZW9tX3BvaW50KCkrdGhlbWVfbGlnaHQoKQ0KDQpnZ3Bsb3RseShwLCB0b29sdGlwPSJ0ZXh0IiwgaGVpZ2h0ID0gNTAwKQ0KDQoNCmBgYA0KDQpUaGVyZSBpcyBubyBjbGVhciBwYXR0ZXJuLiBUaGUgb25seSB0aGluZyB0aGF0IGNhbiBiZSBhcHByZWNpYXRlZCBpcyB0aGF0IHRob3NlIGZhcm1zIHdpdGggYSBTZXJ2aWNlX051bWJlciBtZWFuIG9mIDEgYXJlIGFsbCBvdXRsaWVycy4NCg0KTm93IHdpdGggU293UGFyaXR5X051bWJlciAgICAgICAgICAgICAgDQoNCmBgYHtyLGVjaG89RkFMU0Usd2FybmluZz1GQUxTRSxmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuMiwgd2FybmluZz1GQUxTRX0NCg0KcDwtZGF0YSAlPiUgZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKE1lYW5fU293UGFyaXR5X051bWJlcj1tZWFuKFNvd1Bhcml0eV9OdW1iZXIpLG49bigpKSU+JSBtdXRhdGUocmFuaz1yYW5rKG4pLG91dGxpZXI9aWZlbHNlKHJhbms8OSwiMSIsIjAiKSkgJT4lIGdncGxvdChhZXMoTWVhbl9Tb3dQYXJpdHlfTnVtYmVyLGxvZyhuKSxjb2xvcj1vdXRsaWVyLCB0ZXh0ID0gcGFzdGUoIkZhcm06ICIsIFNpdGVfQ29kZSkpKStnZW9tX3BvaW50KCkrdGhlbWVfbGlnaHQoKQ0KDQpnZ3Bsb3RseShwLCB0b29sdGlwPSJ0ZXh0IiwgaGVpZ2h0ID0gNTAwKQ0KDQoNCmBgYA0KDQpUaGVyZSBpcyBhIGNsZWFyIHBhdHRlcm4uIE1vc3Qgb3V0bGllcnMgaGF2ZSBhIGxvdyBtZWFuIGZvciB0aGUgU293UGFyaXR5X051bWJlciB2YXJpYWJsZS4NCg0KIyMgU293UGFyaXR5X051bWJlcg0KDQoNCmBgYHtyLGVjaG89RkFMU0V9DQoNCmRhdGElPiUgY291bnQoU293UGFyaXR5X051bWJlcixzb3J0PVRSVUUpICU+JSBnZ3Bsb3QoYWVzKHg9U293UGFyaXR5X051bWJlcikpICsgDQogIGdlb21fYm94cGxvdCgpK3RoZW1lX2xpZ2h0KCkrDQogIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKStnZ3RpdGxlKCJTb3dQYXJpdHlfTnVtYmVyIikNCg0KDQpgYGANCg0KVGhlcmUncyBvbmUgb2JzZXJ2YXRpb24gd2l0aCBhIHZhbHVlIG9mIFNvd1Bhcml0eV9OdW1iZXIgb2YgMTAwLiBUaGVyZSdzIG90aGVyIHdpdGggMjAgb3IgbW9yZSwgSSBkb24ndCBrbm93IGlmIHRoYXQgaXMgcG9zc2libGUgY29uc2lkZXJpbmcgaG93IG1hbnkgeWVhcnMgcGlnIHVzdWFsbHkgbGl2ZS4NCg0KIExldCdzIHRha2UgYSBsb29rIGF0IHRoZSBtZWFuIG9mIHRoZSBzb3cgcGFyaXR5IGJ5IGZhcm0uDQpgYGB7cixlY2hvPUZBTFNFfQ0KDQpkYXRhJT4lZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKFNvd1Bhcml0eV9OdW1iZXI9bWVhbihTb3dQYXJpdHlfTnVtYmVyKSkgJT4lIGdncGxvdChhZXMoeD1Tb3dQYXJpdHlfTnVtYmVyKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkrdGhlbWVfbGlnaHQoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpK2dndGl0bGUoIk1lYW4gU293IFBhcml0eSBieSBGYXJtIikNCg0KYGBgDQoNCk1vc3Qgb2YgdGhlIGZhcm1zIHRoYXQgYXJlIG91dGxpZXJzIGNvcnJlc3BvbmQgdG8gZmFybXMgd2l0aCB2ZXJ5IGZldyBzZXJ2aWNlcy4NCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy53aWR0aD03LjUsIGZpZy5oZWlnaHQ9NC4yLCB3YXJuaW5nPUZBTFNFfQ0KDQpwMTwtZGF0YSAlPiUgZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKE1lYW5fU293UGFyaXR5X051bWJlcj1tZWFuKFNvd1Bhcml0eV9OdW1iZXIpLG49bigpKSU+JSBtdXRhdGUocmFuaz1yYW5rKE1lYW5fU293UGFyaXR5X051bWJlciksb3V0bGllcj1pZmVsc2UocmFuazw5LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhNZWFuX1Nvd1Bhcml0eV9OdW1iZXIsbG9nKG4pLGNvbG9yPW91dGxpZXIsIHRleHQgPSBwYXN0ZSgiRmFybTogIiwgU2l0ZV9Db2RlKSkpK2dlb21fcG9pbnQoKSt0aGVtZV9saWdodCgpK2dndGl0bGUoIk91dGxpZXJzIFNvdyBQYXJpdHkiKQ0KDQoNCnAyPC1kYXRhICU+JSBncm91cF9ieShTaXRlX0NvZGUpICU+JSBzdW1tYXJpemUoTWVhbl9Tb3dQYXJpdHlfTnVtYmVyPW1lYW4oU293UGFyaXR5X051bWJlciksbj1uKCkpJT4lIG11dGF0ZShyYW5rPXJhbmsobiksb3V0bGllcj1pZmVsc2UocmFuazw5LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhNZWFuX1Nvd1Bhcml0eV9OdW1iZXIsbG9nKG4pLGNvbG9yPW91dGxpZXIpKStnZW9tX3BvaW50KCkrdGhlbWVfbGlnaHQoKStnZ3RpdGxlKCJPdXRsaWVycyBOIikNCg0KZ2dwbG90bHkocDEsIHRvb2x0aXA9InRleHQiLCBoZWlnaHQgPSA1MDApDQoNCg0KDQoNCmBgYA0KDQpOb3cgdGhlIHNhbWUgZ3JhcGggYnV0IHVzaW5nIFNlcnZpY2VfQ291bnRfTWF0aW5ncw0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCg0KcDE8LWRhdGEgJT4lIGdyb3VwX2J5KFNpdGVfQ29kZSkgJT4lIHN1bW1hcml6ZShTZXJ2aWNlX0NvdW50X01hdGluZ3M9bWVhbihTZXJ2aWNlX0NvdW50X01hdGluZ3MpLE1lYW5fU293UGFyaXR5X051bWJlcj1tZWFuKFNvd1Bhcml0eV9OdW1iZXIpKSU+JSBtdXRhdGUocmFuaz1yYW5rKE1lYW5fU293UGFyaXR5X051bWJlciksb3V0bGllcj1pZmVsc2UocmFuazw5LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhTZXJ2aWNlX0NvdW50X01hdGluZ3MsTWVhbl9Tb3dQYXJpdHlfTnVtYmVyLGNvbG9yPW91dGxpZXIsIHRleHQgPSBwYXN0ZSgiRmFybTogIiwgU2l0ZV9Db2RlKSkpK2dlb21fcG9pbnQoKSt0aGVtZV9saWdodCgpDQoNCmdncGxvdGx5KHAxLCB0b29sdGlwPSJ0ZXh0IiwgaGVpZ2h0ID0gNTAwKQ0KDQoNCg0KYGBgDQoNCkl0IGFwcGVhcnMgdGhhdCB0aGUgZmFybXMgdGhhdCBhcmUgb3V0bGllcnMgKFNvdyBQYXJpdHkpIGVpdGhlciBoYXZlIGxvdyBvciBoaWdoIG1lYW5zIGZvciB0aGUgU2VydmljZV9Db3VudF9NYXRpbmdzIHZhcmlhYmxlLg0KDQojIyBTb3dfRGF0ZV9NYXRpbmdfRmlyc3QgDQoNCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCmRhdGEgJT4lIGNvdW50KFNvd19EYXRlX01hdGluZ19GaXJzdCAsc29ydD1UUlVFKSAlPiUNCiAgbXV0YXRlKFNvd19EYXRlX01hdGluZ19GaXJzdCAgPSB5bWQoU293X0RhdGVfTWF0aW5nX0ZpcnN0ICkpICU+JSANCiBncm91cF9ieSh3ZWVrPWZsb29yX2RhdGUoU293X0RhdGVfTWF0aW5nX0ZpcnN0ICwgIndlZWsiKSkgJT4lIA0KICBzdW1tYXJpemUobj1zdW0obikpICU+JSANCiAgcGxvdF9seSggeCA9IH53ZWVrKSAlPiUgYWRkX3RyYWNlKHkgPSB+biwgbmFtZSA9ICd0cmFjZSAwJyxtb2RlID0gJ2xpbmVzJyklPiUgDQogIGxheW91dCh0aXRsZSA9ICJTb3dzIEZpcnN0IE1hdGluZyBPdmVyIHRoZSBZZWFycyAiKSAgDQpgYGANCg0KMSkgVGhlcmUgYXJlIHZlcnkgZmV3IG9ic2VydmF0aW9ucyBiZWZvcmUgMjAxMi4gDQoyKSBUaGVyZSBpcyBhIHBlYWsgaW4gRGVjZW1iZXIgMjAxNiAtIEphbnVhcnkgMjAxNy4NCjMpIFNpbmNlIDIwMTkgdGhlcmUgaXMgYSBkb3dud2FyZCB0cmVuZC4NCjQpIFRoaXMgdHlwZSBvZiBkaXN0cmlidXRpb24gcGVyaGFwcyBtYWtlcyBzZW5zZSBpZiB3ZSBjb25zaWRlciBob3cgbG9uZyBwaWdzIGxpdmUNCg0KYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQoNCng8LSBkYXRhICU+JSBjb3VudChTb3dfRGF0ZV9NYXRpbmdfRmlyc3QgLHNvcnQ9VFJVRSkgJT4lDQogIG11dGF0ZShTb3dfRGF0ZV9NYXRpbmdfRmlyc3QgID0geW1kKFNvd19EYXRlX01hdGluZ19GaXJzdCApKSAlPiUgDQogZ3JvdXBfYnkoeWVhcj1mbG9vcl9kYXRlKFNvd19EYXRlX01hdGluZ19GaXJzdCAsICJ5ZWFyIikpICU+JSANCiAgc3VtbWFyaXplKG49c3VtKG4pKSAlPiUgIHNlcGFyYXRlKHllYXIsaW50bz1jKCJ5ZWFyIiwid2VlayIpLHNlcD0iLSIpICU+JSBzZWxlY3QoeWVhcixuKSU+JSByZW5hbWUoT3V0bGllcnM9bikNCg0KDQoNCkRUOjpkYXRhdGFibGUoeCwgcm93bmFtZXMgPSBGQUxTRSwNCiAgICAgICAgICBvcHRpb25zID0gbGlzdCgNCiAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSAwOjEpKSkpDQoNCg0KDQpgYGANCg0KVGhlcmUgYXJlIDUgb2JzZXJ2YXRpb25zIGZyb20gMTk2MSBhbmQgYSBmZXcgZnJvbSB0aGUgZWFybHkgMjAwMHMuIE1vc3QgbGlrZWx5LCB0aGV5IHdpbGwgbmVlZCB0byBiZSBlbGltaW5hdGVkLg0KDQoNCg0KIyMgU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSANCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRSxmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuMiwgd2FybmluZz1GQUxTRX0NCg0KZGF0YSAlPiUgY291bnQoU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSANCiAsc29ydD1UUlVFKSAlPiUNCiAgbXV0YXRlKFNvd19EYXRlX0JyZWVkaW5nSGVyZF9BdmFpbGFibGUgID0geW1kKFNvd19EYXRlX0JyZWVkaW5nSGVyZF9BdmFpbGFibGUgKSkgJT4lIA0KIGdyb3VwX2J5KHdlZWs9Zmxvb3JfZGF0ZShTb3dfRGF0ZV9CcmVlZGluZ0hlcmRfQXZhaWxhYmxlICwgIndlZWsiKSkgJT4lIA0KICBzdW1tYXJpemUobj1zdW0obikpICU+JSANCiAgcGxvdF9seSggeCA9IH53ZWVrKSAlPiUgYWRkX3RyYWNlKHkgPSB+biwgbmFtZSA9ICd0cmFjZSAwJyxtb2RlID0gJ2xpbmVzJyklPiUgDQogIGxheW91dCh0aXRsZSA9ICJTb3dzIEJyZWVkaW5nIEhlcmQgT3ZlciB0aGUgWWVhcnMgIikgIA0KDQpgYGANCg0KDQpUaGUgYmlnIGRpZmZlcmVuY2UsIGJldHdlZW4gdGhpcyBncmFwaCBhbmQgdGhlIHByZXZpb3VzIG9uZSwgaXMgdGhhdCB0aGVyZSBpcyBhIHBlYWsgaW4gdGhlIDUwJ3MNCg0KDQpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCg0KeDwtZGF0YSAlPiUgY291bnQoU293X0RhdGVfQnJlZWRpbmdIZXJkX0F2YWlsYWJsZSAsc29ydD1UUlVFKSAlPiUNCiAgbXV0YXRlKFNvd19EYXRlX0JyZWVkaW5nSGVyZF9BdmFpbGFibGUgID0geW1kKFNvd19EYXRlX0JyZWVkaW5nSGVyZF9BdmFpbGFibGUgKSkgJT4lIA0KIGdyb3VwX2J5KHllYXI9Zmxvb3JfZGF0ZShTb3dfRGF0ZV9CcmVlZGluZ0hlcmRfQXZhaWxhYmxlICwgInllYXIiKSkgJT4lIA0KICBzdW1tYXJpemUobj1zdW0obikpICU+JSAgc2VwYXJhdGUoeWVhcixpbnRvPWMoInllYXIiLCJ3ZWVrIiksc2VwPSItIikgJT4lIHNlbGVjdCh5ZWFyLG4pICU+JSByZW5hbWUoT3V0bGllcnM9bikNCg0KRFQ6OmRhdGF0YWJsZSh4LCByb3duYW1lcyA9IEZBTFNFLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KA0KICAgICAgICAgICAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDA6MSkpKSkNCg0KDQpgYGANCg0KVGhlcmUgYXJlIG1hbnkgb2xkIG9ic2VydmF0aW9ucy4NCg0KDQoNCmBgYHtyLGVjaG89RkFMU0V9DQpkYXRhMSA8LSByZWFkLmNzdihmaWxlLmNob29zZSgpKQ0KDQpgYGANCg0KDQojIFJlc3BvbnNlIERhdGENCg0KIyMgU2l0ZV9Db2RlDQoNCkxvb2tpbmcgYXQgdGhlIG51bWJlciBvZiBzZXJ2aWNlcyBwZXIgZmFybS4NCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQoNCmRhdGExJT4lIGNvdW50KFNpdGVfQ29kZSxzb3J0PVRSVUUpICU+JSANCmdncGxvdChhZXMoeD1uKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkrdGhlbWVfbGlnaHQoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpK2dndGl0bGUoIlNlcnZpY2VzIGJ5IEZhcm0iKQ0KDQoNCmBgYA0KDQpUaGVyZSBhcmUgc2V2ZXJhbCBmYXJtcyB3aXRoIGZldyBzZXJ2aWNlcy4gTGV0J3MgbG9vayBhdCB0aGUgZmFycm93aW5nIHJhdGUgbWVhbiBieSBsb2NhdGlvbi4NCg0KYGBge3IsZWNobz1GQUxTRX0NCg0KZGF0YTEgJT4lIGdyb3VwX2J5KFNpdGVfQ29kZSkgJT4lIHN1bW1hcml6ZShGYXJyb3dpbmdSYXRlPW1lYW4oRmFycm93aW5nUmF0ZSkpICU+JSANCmdncGxvdChhZXMoeD1GYXJyb3dpbmdSYXRlKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkrdGhlbWVfbGlnaHQoKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpK2dndGl0bGUoIk1lYW4gRmFycm93aW5nIFJhdGUgYnkgRmFybSIpDQoNCmBgYA0KDQpMZXQncyBsb29rIGF0IGEgc2NhdHRlcnBsb3Qgd2l0aCB0aGUgbWVhbiBvZiB0aGUgZmFycm93aW5nIHJhdGUgdmVyc3VzIHRoZSBudW1iZXIgb2Ygc2VydmljZXMgcGVyIGZhcm0uDQoNCmBgYHtyLGVjaG89RkFMU0UsZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjIsIHdhcm5pbmc9RkFMU0V9DQoNCnAxPC1kYXRhMSAlPiUgZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKEZhcnJvd2luZ1JhdGU9bWVhbihGYXJyb3dpbmdSYXRlKSxuPW4oKSkgJT4lICBtdXRhdGUocmFuaz1yYW5rKEZhcnJvd2luZ1JhdGUpLG91dGxpZXI9aWZlbHNlKHJhbms8NywiMSIsIjAiKSkgJT4lIGdncGxvdChhZXMoRmFycm93aW5nUmF0ZSxuLGNvbG9yPW91dGxpZXIsdGV4dCA9IHBhc3RlKCJGYXJtOiAiLCBTaXRlX0NvZGUpKSkrZ2VvbV9wb2ludCgpK3RoZW1lX2xpZ2h0KCkrZ2d0aXRsZSgiRmFycm93aW5nIFJhdGUgdnMgTnVtYmVyIG9mIFNlcnZpY2VzIHBlciBGYXJtIikNCg0KDQpnZ3Bsb3RseShwMSwgdG9vbHRpcD0idGV4dCIsIGhlaWdodCA9IDUwMCkNCg0KDQpwMjwtZGF0YTEgJT4lIGdyb3VwX2J5KFNpdGVfQ29kZSkgJT4lIHN1bW1hcml6ZShGYXJyb3dpbmdSYXRlPW1lYW4oRmFycm93aW5nUmF0ZSksbj1uKCkpICU+JSAgbXV0YXRlKG91dGxpZXI9aWZlbHNlKG48MjU2LCIxIiwiMCIpKSAlPiUgZ2dwbG90KGFlcyhGYXJyb3dpbmdSYXRlLG4sY29sb3I9b3V0bGllcikpK2dlb21fcG9pbnQoKSt0aGVtZV9saWdodCgpK2dndGl0bGUoIk91dGxpZXJzIE51bWJlciBvZiBTZXJ2aWNlcyIpDQoNCg0KDQpgYGANCg0KQWx0aG91Z2ggdGhlcmUgaXMgbm8gbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMsIGl0IGNhbiBiZSBzZWVuIHRoYXQgbW9zdCBvZiB0aGUgZmFybXMgd2l0aCBmZXcgc2VydmljZXMgaGF2ZSBhIHZlcnkgbG93IGZhcnJvd2luZyByYXRlIG1lYW4uIEFsbCBvdXRsaWVycyBmb3IgdGhlIGZhcnJvd2luZyByYXRlIGFyZSBhbHNvIG91dGxpZXJzIGZvciB0aGUgbnVtYmVyIG9mIHNlcnZpY2VzLg0KDQoNCiMjIEZhcnJvd2luZ1JhdGUNCg0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQpzdW1tYXJ5KGRhdGExJEZhcnJvd2luZ1JhdGUpDQpgYGANCg0KYGBge3IsZWNobz1GQUxTRX0NCg0KZ2dwbG90KGRhdGExLCBhZXMoeD1GYXJyb3dpbmdSYXRlKSkgKyANCiAgZ2VvbV9ib3hwbG90KG5vdGNoPVRSVUUpDQoNCmBgYA0KDQpMZXQncyBsb29rIGF0IHRoZSBwcm9wb3J0aW9ucyBvZiBvdXRsaWVycyBwZXIgZmFybQ0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KDQpvdXRsaWVyczwtYm94cGxvdC5zdGF0cyhkYXRhMSRGYXJyb3dpbmdSYXRlKSRvdXQNCg0KZGF0YTE8LWRhdGExICU+JSAgbXV0YXRlKG91dGxpZXI9aWZlbHNlKEZhcnJvd2luZ1JhdGU8PTAuNjEwNywxLDApKQ0KDQp4PC1kYXRhMSAlPiUgZ3JvdXBfYnkoU2l0ZV9Db2RlKSAlPiUgc3VtbWFyaXplKG91dGxpZXJzPXN1bShvdXRsaWVyKSxTZXJ2aWNlcz1uKCkscGVyY2VudGFnZT1yb3VuZCgob3V0bGllcnMqMTAwKS9TZXJ2aWNlcywxKSkgJT4lIGFycmFuZ2UoZGVzYyhwZXJjZW50YWdlKSkNCg0KDQpEVDo6ZGF0YXRhYmxlKHgsIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gMDozKSkpKQ0KDQpgYGANCg0KVGhlIHByb3BvcnRpb24gb2Ygb3V0bGllcnMgaXMgbXVjaCBsb3dlciBpbiB0aG9zZSBmYXJtcyB3aXRoIGZld2VyIG9ic2VydmF0aW9ucywgaG93ZXZlciB0aGVyZSBhcmUgbWFueSBmYXJtcyB3aXRoIG1hbnkgc2VydmljZXMgdGhhdCBzdGlsbCBoYXZlIG1hbnkgb3V0bGllcnMgKE1MU1MsIFdIU1MsIENMWFMsIE5WTlMpLg0KDQpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgbnVtYmVyIG9mIHNlcnZpY2VzIHBlciB5ZWFyDQoNCmBgYHtyfQ0KeDwtZGF0YTEgJT4lIHNlcGFyYXRlKFNlcnZpY2VZZWFyV2VlayxpbnRvPWMoInllYXIiLCJ3ZWVrIiksc2VwPSItIiklPiUgZmlsdGVyKEZhcnJvd2luZ1JhdGU8MC42MCkgJT4lIGNvdW50KHllYXIsc29ydD1UUlVFKSU+JSByZW5hbWUoT3V0bGllcnM9bikNCg0KDQpEVDo6ZGF0YXRhYmxlKHgsIHJvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gMDoxKSkpKQ0KDQpgYGANCg0KDQpNb3N0IG9mIHRoZSBvYnNlcnZhdGlvbnMgYXJlIGZyb20gMjAyMCwgdGhlc2Ugb3V0bGllcnMgbWF5IGJlIGEgcHJvZHVjdCBvZiB0aGUgcGFuZGVtaWMuIE1heWJlIGl0J3Mgbm90IGdvb2QgdG8gZGVsZXRlIHRoZW0uIExldCdzIGRvIGEgY2hpIHNxdWFyZSB0ZXN0IHRvIGJlIHN1cmUuDQoNCg0KYGBge3IsZWNobz1GQUxTRX0NCg0Kb3V0bGllcnM8LWJveHBsb3Quc3RhdHMoZGF0YTEkRmFycm93aW5nUmF0ZSkkb3V0DQoNCmRhdGExPC1kYXRhMSAlPiUgIG11dGF0ZShvdXRsaWVyPWlmZWxzZShGYXJyb3dpbmdSYXRlPD0wLjYxMDcsIjEiLCIwIikpDQoNCmRhdGExPC1kYXRhMSAlPiUgc2VwYXJhdGUoU2VydmljZVllYXJXZWVrLGludG89YygieWVhciIsIndlZWsiKSxzZXA9Ii0iKQ0KDQoNCnRhYmxlPC10YWJsZShkYXRhMSRvdXRsaWVyLGRhdGExJHllYXIpDQoNCnJlc3VsdHM8LWNoaXNxLnRlc3QodGFibGUpIA0KDQp0aWR5KHJlc3VsdHMpDQoNCmBgYA0KDQpHaXZlbiB0aGUgcC12YWx1ZSwgaXQgaXMgcG9zc2libGUgdG8gc2F5IHRoYXQgdGhlIG51bWJlciBvZiBvdXRsaWVycyBhbmQgdGhlIHllYXJzIGFyZSByZWxhdGVkLiBMZXQncyBsb29rIGF0IHRoZSByZXNpZHVhbHMgdG8gaGF2ZSBhIGJldHRlciBpZGVhIGFib3V0IHdoYXQncyBnb2luZyBvbi4NCg0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KDQoocmVzaWR1YWxzKHJlc3VsdHMpKQ0KDQpgYGANCg0KSXQgaXMgaW1wb3J0YW50IHRvIG1lbnRpb24gdGhhdCB0aGUgcnVsZSBvZiB0aHVtYiBpcyB0aGF0IGlmIHRoZSB2YWx1ZXMgb2YgYSBjZWxsIGFyZSBhYm92ZSAyLCB3ZSBoYXZlIG1vcmUgb2JzZXJ2YXRpb25zIHRoYW4gZXhwZWN0ZWQuIE9uIHRoZSBvdGhlciBoYW5kLCBpZiB0aGUgY2VsbCB2YWx1ZSBpcyBsZXNzIHRoYW4gLTIgd2UgaGF2ZSBmZXdlciB2YWx1ZXMgdGhhbiBleHBlY3RlZC4gTG9va2luZyBhdCB0aGlzIHRhYmxlLCB3ZSBjYW4gc2F5IHRoYXQgZm9yIDIwMTggYW5kIDIwMTkgd2UgaGF2ZSBmZXdlciBvdXRsaWVycyB0aGFuIGV4cGVjdGVkLiBBcyBmb3IgdGhlIHllYXIgMjAyMCwgd2UgaGF2ZSBtb3JlIG91dGxpZXJzIHRoYW4gZXhwZWN0ZWQuDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==