The 6th Mill is the last mill in any of both tandems, meaning that the entire bagasse mass flow must go through it (similar to the 1st mill). When too much imbibition water is applied, chute level control is lost as the top speed is not enough for displacing the volume (baggase+water) that must go through the mill. This high chute level condition increases the probability of blockages and mechanical damage to the bagasse feeders, that can cause significant downtime.

The purpose of this analysis is to find an operational constraint over the imbibition water applied to the 6th Mills based upon process variables to prevent damages and downtime.

For that a Correlation Analysis for Mill 6 on TA & TB for the 2023-2024 Harvest Season is conducted.

Libraries

library(dplyr)
library(pastecs)
library(ggplot2)
library(lares)

Scatter - Correlation Plot Function

mapa_dispersion <- function(label_x,label_y,dataset) {
  correlacion <- round(cor(dataset[[label_x]],dataset[[label_y]]),2)
  ggplot(dataset, aes(.data[[label_x]], .data[[label_y]])) + 
    geom_point(
        color="orange",
        fill="#69b3a2",
        shape=21,
        alpha=0.5,
        size=6,
        stroke = 2
        ) +
    geom_smooth(method=lm , color="#990000", fill="#FFCF00", se=TRUE) +
    ggtitle(paste(label_y,"vrs.",label_x), subtitle = paste("Correlation: ",correlacion)) +
  xlab(label_x) + ylab(label_y)
}

TA & TB Dataframes

The datasets used for this analysis include operational variables like mill speed, power, torque, chute level, etc., as well as variables related to mass flows like imbibition water, bagasse, fiber, etc. The variables are daily averages.

dataset <- read.csv(file = 'Dataset.csv')

# Dataset for each tandem
df_TA <- dataset[-c(4,5,8,9,12,13,16,17,20,21,24,25,31,32,33,34,35,38,39,41,43,45,47,49,51)]
df_TB <- dataset[c(1,4,5,8,9,12,13,16,17,20,21,24,25,31,32,33,34,35,38,39,41,43,45,47,49,51,52,53)]
df_TA
df_TB

Tandem “A”

Density Function: 6th Mill TA Speed (rpm)

We first take a look at the Mill Speed Distribution, to identify the speed range where the level control of the mill is nearly lost.


# PDF
distr(df_TA,'ST55M601')
Warning: Font 'Arial Narrow' is not installed, has other name, or can't be found

# Boxplot
ggplot(df_TA, aes(y=ST55M601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "ST55M601 (rpm)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$ST55M601))
NA

Maximum Operational Speed: 1200 rpms. Maximum Average Operational Speed: 1160 rpms.

# Quartiles:
res<-quantile(df_TA$ST55M601, probs = c(0,0.25,0.5,0.75,1)) 
res
       0%       25%       50%       75%      100% 
 560.6891  868.7622  941.8143 1014.9713 1156.3707 

Density Function: 6th Mill TA Power (kW)

We examine the power distribution of the mill, as a proxy variable for identifiying an acceptable load range.


# PDF
distr(df_TA,'JT55M601')


# Boxplot
ggplot(df_TA, aes(y=JT55M601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "JT55M601 (kW)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$JT55M601))
NA

Maximum Average Operational Power: 769 kW

# Quartiles:
res<-quantile(df_TA$JT55M601, probs = c(0,0.25,0.5,0.75,1)) 
res
      0%      25%      50%      75%     100% 
347.0196 489.0803 565.8324 660.6705 769.0661 

Density Function: 6th Mill TA Chute Level (%)

We examine the chute level distribution of the mill.


# PDF
distr(df_TA,'LT55M601')


# Boxplot
ggplot(df_TA, aes(y=LT55M601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "LT55M601 (%)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$LT55M601))
NA
# Quartiles:
res<-quantile(df_TA$LT55M601, probs = c(0,0.25,0.5,0.75,1)) 
res
      0%      25%      50%      75%     100% 
13.59563 21.51660 26.01151 31.23077 46.33880 

Dataframe Filtering

We filter observations for the following operational ranges:

  • Power Range for Normal Sugar Cane Milling.
  • Speed Range for High Chute Level Condition in the Mill.

# Filter Dataset by Column Values:
df_TA_filtered <- df_TA[df_TA$JT55M601>=489,] # Filter by Minimum Threshold of 1st Quartile Power
df_TA_filtered <- df_TA_filtered[df_TA_filtered$ST55M601>=1015,] # Filter by Top 25% of Maximum Operational Speed (1050)
df_TA_filtered
NA

Largest Correlation Variables with TA Imbibition Water

We inspect the largest correlated variables with Imbibition Water

corr_var(df_TA_filtered, # dataframe name
  ImbTA, # target
  max_pvalue = 0.05, # significance level
  top = 15, # top n most correlated variables with target
  plot = T
)

Scatter Plots for TA Imbibition Water

Day of Season Day of Season might be a confounder variable, because usually it is highly correlated with bagasse / fiber content of the sugar cane. We inspect this correlation.

label_x <- "Dia.Zafra"
label_y <- "fibra.caña.ta"

mapa_dispersion(label_x,label_y,df_TA_filtered)

6th Mill TA Speed

label_x <- "ST55M601"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Sugar Cane Bagasse Content TA

label_x <- "bagazo...caña.ta"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Fiber Content Tandem A

label_x <- "X..Fibra.Core.TA"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Bagasse Mass Flow TA

label_x <- "WT555801"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Sugar Cane Trash Content Tandem A

label_x <- "X..Trash.Ponderado"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Torque on Mill 1 TA Day of Season might be a confounder variable, because usually it is highly correlated with bagasse / fiber content of the sugar cane. We inspect this correlation.

label_x <- "TQ55M101"
label_y <- "ImbTA"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Imbibition Water TA Linear Model

lm_ImbTA = lm(ImbTA ~ TQ55M101 + WT555801 + X..Fibra.Core.TA + ST55M601 + bagazo...caña.ta + Trash.Total...., data = df_TA_filtered) #Create the linear regression
summary(lm_ImbTA)

Call:
lm(formula = ImbTA ~ TQ55M101 + WT555801 + X..Fibra.Core.TA + 
    ST55M601 + bagazo...caña.ta + Trash.Total...., data = df_TA_filtered)

Residuals:
    Min      1Q  Median      3Q     Max -60.110 -24.433   2.742  23.406  47.965 

Coefficients:
                  Estimate Std. Error Pr(>|t|)    
(Intercept)      -577.0672   221.8002  -2.602 0.014873 *      0.1227     0.0618   1.986 0.057233 .  
WT555801            1.9592     0.7820   2.505 0.018569 *  
X..Fibra.Core.TA  -42.0349    17.0986  -2.458 0.020658
ST55M601            0.8991     0.2364   3.803 0.000744 ***
bagazo...caña.ta   18.4594     3.7877   4.874 4.28e-05 ***  -10.1793     4.3757  -2.326 0.027753 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 31.98 on 27 degrees of freedom
Multiple R-squared:  0.8399,    Adjusted R-squared:  0.8043 
F-statistic: 23.61 on 6 and 27 DF,  p-value: 1.476e-09

Imbibition Water TA Linear Model Test

# applying fitted values to TA data frame
df_TA_filtered$fitted<- lm_ImbTA$fitted.values

# creating ggplot object for visualization
lm_ImbTA_plot <- ggplot(df_TA_filtered, aes(x= Dia.Zafra, y= ImbTA,colour="real values")) +
  geom_point() +
  geom_line(aes(y= fitted, colour="fitted values")) +
  scale_color_manual(name = "Imbibition Water TA", values = c("fitted values" = "darkblue", "real values" = "red"))

print(lm_ImbTA_plot)

Tandem “B”

Density Function: 6th Mill TB Speed (rpm)

We first take a look at the Mill Speed Distribution, to identify the speed range where the level control of the mill is nearly lost.


# PDF
distr(df_TB,'ST55N601')


# Boxplot
ggplot(df_TB, aes(y=ST55N601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "ST55N601 (rpm)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TB$ST55N601))
NA

Maximum Operational Speed: 1200 rpms. Maximum Average Operational Speed: 1160 rpms.

# Quartiles:
res<-quantile(df_TB$ST55N601, probs = c(0,0.25,0.5,0.75,1)) 
res
       0%       25%       75%      100% 
 593.0956  897.9540  965.2726 1012.9059 1165.1792 

Density Function: 6th Mill TB Power (kW)

We examine the power distribution of the mill, as a proxy variable for identifiying an acceptable load range.


# PDF
distr(df_TB,'JT55N601')


# Boxplot
ggplot(df_TB, aes(y=JT55N601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "JT55N601 (kW)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TB$JT55N601))
NA

Maximum Operational Power: 900 kW

# Quartiles:
res<-quantile(df_TB$JT55N601, probs = c(0,0.25,0.5,0.75,1)) 
res
      0%      50%      75%     100% 
301.3789 542.7360 642.1705 722.1480 892.5287 

Density Function: 6th Mill TB Chute Level (%)

We examine the chute level distribution of the mill.


# PDF
distr(df_TB,'LT55N601')


# Boxplot
ggplot(df_TB, aes(y=LT55N601)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "LT55N601 (%)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TB$LT55N601))
NA
# Quartiles:
res<-quantile(df_TB$LT55N601, probs = c(0,0.25,0.5,0.75,1)) 
res
       0%       25%       50%       75%      100% 
 2.596137 24.073490 39.651763 48.249095 66.099806 

# Filter Dataset by Column Values:
df_TB_filtered <- df_TB[df_TB$JT55N601>=542,] # Filter by Minimum Threshold of 1st Quartile Power
df_TB_filtered <- df_TB_filtered[df_TB_filtered$ST55N601>=1012,] # Filter by Top 25% of Maximum Operational Speed
df_TB_filtered
NA

Largest Correlation Variables with TB Imbibition Water

corr_var(df_TB_filtered, # dataframe name
  ImbTB, # target
  max_pvalue = 0.05, # significance level
  top = 15, # top n most correlated variables with target
  plot = T
)

Day of Season

label_x <- "Dia.Zafra"
label_y <- "ImbTB"

mapa_dispersion(label_x,label_y,df_TB_filtered)

6th TB Mill Speed

label_x <- "ST55N601"
label_y <- "ImbTB"

mapa_dispersion(label_x,label_y,df_TB_filtered)

1st TB Mill Power

label_x <- "JT55N101"
label_y <- "ImbTB"

mapa_dispersion(label_x,label_y,df_TB_filtered)

Sugar Cane Fiber Content Tandem B

label_x <- "X..Fibra.Core.TB"
label_y <- "ImbTB"

mapa_dispersion(label_x,label_y,df_TB_filtered)

Imbibition Water TB Linear Model

lm_ImbTB = lm(ImbTB ~ Dia.Zafra + ST55N601 + TQ55N101_stdev + JT55N101_stdev + caña.molida.tb, data = df_TB_filtered) #Create the linear regression
summary(lm_ImbTB)

Call:
lm(formula = ImbTB ~ Dia.Zafra + ST55N601 + TQ55N101_stdev + 
    JT55N101_stdev + caña.molida.tb, data = df_TB_filtered)Residuals:
   Min     1Q Median     3Q    Max 
-22.83   5.04  19.66  38.66 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)     17.440963 145.137904 0.905079    
Dia.Zafra        1.228458   0.215136   5.710 2.27e-06 ***
ST55N601         0.532491   3.752 0.000676 ***
TQ55N101_stdev  -0.829769   0.293859  -2.824 ** 
JT55N101_stdev   1.599298   0.657877   2.431 0.020654 *  
caña.molida.tb   0.008479   0.003985   2.128 0.040893 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 29.32 on 33 degrees of freedom
Multiple R-squared:  0.7808 0.7476 
F-statistic: 23.51  5 and 33 DF,  p-value: 5.28e-10

Imbibition Water TB Linear Model Test

# applying fitted values to TB data frame
df_TB_filtered$fitted<- lm_ImbTB$fitted.values

# creating ggplot object for visualization
lm_ImbTB_plot <- ggplot(df_TB_filtered, aes(x= Dia.Zafra, y= ImbTB,colour="real values")) +
  geom_point() +
  geom_line(aes(y= fitted, colour="fitted values")) +
  scale_color_manual(name = "Imbibition Water TB", values = c("fitted values" = "darkblue", "real values" = "red"))

print(lm_ImbTB_plot)

LS0tDQp0aXRsZTogIk1pbGwgNiBJbWJpYml0aW9uIFdhdGVyIE9wZXJhdGlvbmFsIENvbnN0cmFpbnQiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGUgNnRoIE1pbGwgaXMgdGhlIGxhc3QgbWlsbCBpbiBhbnkgb2YgYm90aCB0YW5kZW1zLCBtZWFuaW5nIHRoYXQgdGhlIGVudGlyZSBiYWdhc3NlIG1hc3MgZmxvdyBtdXN0IGdvIHRocm91Z2ggaXQgKHNpbWlsYXIgdG8gdGhlIDFzdCBtaWxsKS4gV2hlbiB0b28gbXVjaCBpbWJpYml0aW9uIHdhdGVyIGlzIGFwcGxpZWQsIGNodXRlIGxldmVsIGNvbnRyb2wgaXMgbG9zdCBhcyB0aGUgdG9wIHNwZWVkIGlzIG5vdCBlbm91Z2ggZm9yIGRpc3BsYWNpbmcgdGhlIHZvbHVtZSAoYmFnZ2FzZSt3YXRlcikgdGhhdCBtdXN0IGdvIHRocm91Z2ggdGhlIG1pbGwuIFRoaXMgaGlnaCBjaHV0ZSBsZXZlbCBjb25kaXRpb24gaW5jcmVhc2VzIHRoZSBwcm9iYWJpbGl0eSBvZiBibG9ja2FnZXMgYW5kIG1lY2hhbmljYWwgZGFtYWdlIHRvIHRoZSBiYWdhc3NlIGZlZWRlcnMsIHRoYXQgY2FuIGNhdXNlIHNpZ25pZmljYW50IGRvd250aW1lLg0KDQpUaGUgcHVycG9zZSBvZiB0aGlzIGFuYWx5c2lzIGlzIHRvIGZpbmQgYW4gb3BlcmF0aW9uYWwgY29uc3RyYWludCBvdmVyIHRoZSBpbWJpYml0aW9uIHdhdGVyIGFwcGxpZWQgdG8gdGhlIDZ0aCBNaWxscyBiYXNlZCB1cG9uIHByb2Nlc3MgdmFyaWFibGVzIHRvIHByZXZlbnQgZGFtYWdlcyBhbmQgZG93bnRpbWUuIA0KDQpGb3IgdGhhdCBhIENvcnJlbGF0aW9uIEFuYWx5c2lzIGZvciBNaWxsIDYgb24gVEEgJiBUQiBmb3IgdGhlICoqMjAyMy0yMDI0IEhhcnZlc3QgU2Vhc29uKiogaXMgY29uZHVjdGVkLg0KDQoNCiMjIyBMaWJyYXJpZXMNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocGFzdGVjcykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobGFyZXMpDQpgYGANCg0KIyMjIFNjYXR0ZXIgLSBDb3JyZWxhdGlvbiBQbG90IEZ1bmN0aW9uDQpgYGB7cn0NCm1hcGFfZGlzcGVyc2lvbiA8LSBmdW5jdGlvbihsYWJlbF94LGxhYmVsX3ksZGF0YXNldCkgew0KICBjb3JyZWxhY2lvbiA8LSByb3VuZChjb3IoZGF0YXNldFtbbGFiZWxfeF1dLGRhdGFzZXRbW2xhYmVsX3ldXSksMikNCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyguZGF0YVtbbGFiZWxfeF1dLCAuZGF0YVtbbGFiZWxfeV1dKSkgKyANCiAgICBnZW9tX3BvaW50KA0KICAgICAgICBjb2xvcj0ib3JhbmdlIiwNCiAgICAgICAgZmlsbD0iIzY5YjNhMiIsDQogICAgICAgIHNoYXBlPTIxLA0KICAgICAgICBhbHBoYT0wLjUsDQogICAgICAgIHNpemU9NiwNCiAgICAgICAgc3Ryb2tlID0gMg0KICAgICAgICApICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0gLCBjb2xvcj0iIzk5MDAwMCIsIGZpbGw9IiNGRkNGMDAiLCBzZT1UUlVFKSArDQogICAgZ2d0aXRsZShwYXN0ZShsYWJlbF95LCJ2cnMuIixsYWJlbF94KSwgc3VidGl0bGUgPSBwYXN0ZSgiQ29ycmVsYXRpb246ICIsY29ycmVsYWNpb24pKSArDQogIHhsYWIobGFiZWxfeCkgKyB5bGFiKGxhYmVsX3kpDQp9DQpgYGANCg0KIyMjIFRBICYgVEIgRGF0YWZyYW1lcw0KDQpUaGUgZGF0YXNldHMgdXNlZCBmb3IgdGhpcyBhbmFseXNpcyBpbmNsdWRlIG9wZXJhdGlvbmFsIHZhcmlhYmxlcyBsaWtlIG1pbGwgc3BlZWQsIHBvd2VyLCB0b3JxdWUsIGNodXRlIGxldmVsLCBldGMuLCBhcyB3ZWxsIGFzIHZhcmlhYmxlcyByZWxhdGVkIHRvIG1hc3MgZmxvd3MgbGlrZSBpbWJpYml0aW9uIHdhdGVyLCBiYWdhc3NlLCBmaWJlciwgZXRjLiBUaGUgdmFyaWFibGVzIGFyZSAqKmRhaWx5IGF2ZXJhZ2VzKiouDQpgYGB7cn0NCmRhdGFzZXQgPC0gcmVhZC5jc3YoZmlsZSA9ICdEYXRhc2V0LmNzdicpDQoNCiMgRGF0YXNldCBmb3IgZWFjaCB0YW5kZW0NCmRmX1RBIDwtIGRhdGFzZXRbLWMoNCw1LDgsOSwxMiwxMywxNiwxNywyMCwyMSwyNCwyNSwzMSwzMiwzMywzNCwzNSwzOCwzOSw0MSw0Myw0NSw0Nyw0OSw1MSldDQpkZl9UQiA8LSBkYXRhc2V0W2MoMSw0LDUsOCw5LDEyLDEzLDE2LDE3LDIwLDIxLDI0LDI1LDMxLDMyLDMzLDM0LDM1LDM4LDM5LDQxLDQzLDQ1LDQ3LDQ5LDUxLDUyLDUzKV0NCmRmX1RBDQpkZl9UQg0KYGBgDQojIyBUYW5kZW0gIkEiDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiA2dGggTWlsbCBUQSBTcGVlZCAocnBtKQ0KDQpXZSBmaXJzdCB0YWtlIGEgbG9vayBhdCB0aGUgTWlsbCBTcGVlZCBEaXN0cmlidXRpb24sIHRvIGlkZW50aWZ5IHRoZSBzcGVlZCByYW5nZSB3aGVyZSB0aGUgbGV2ZWwgY29udHJvbCBvZiB0aGUgbWlsbCBpcyBuZWFybHkgbG9zdC4NCmBgYHtyfQ0KDQojIFBERg0KZGlzdHIoZGZfVEEsJ1NUNTVNNjAxJykNCg0KIyBCb3hwbG90DQpnZ3Bsb3QoZGZfVEEsIGFlcyh5PVNUNTVNNjAxKSkgKyANCiAgICBnZW9tX2JveHBsb3QoIA0KICAgICAgICAjIGN1c3RvbSBib3hlcw0KICAgICAgICBjb2xvcj0iYmx1ZSIsDQogICAgICAgIGZpbGw9ImJsdWUiLA0KICAgICAgICBhbHBoYT0wLjIsDQogICAgICAgIA0KICAgICAgICAjIE5vdGNoDQogICAgICAgIG5vdGNoPVRSVUUsDQogICAgICAgIG5vdGNod2lkdGggPSAwLjgsDQogICAgICAgIA0KICAgICAgICAjIGN1c3RvbSBvdXRsaWVycw0KICAgICAgICBvdXRsaWVyLmNvbG91cj0icmVkIiwNCiAgICAgICAgb3V0bGllci5maWxsPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLnNpemU9MykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCkgKw0KICBsYWJzKHRpdGxlPSJCb3hwbG90Iix4PSIiLCB5ID0gIlNUNTVNNjAxIChycG0pIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRTVDU1TTYwMSkpDQoNCmBgYA0KTWF4aW11bSBPcGVyYXRpb25hbCBTcGVlZDogMTIwMCBycG1zLiBNYXhpbXVtIEF2ZXJhZ2UgT3BlcmF0aW9uYWwgU3BlZWQ6IDExNjAgcnBtcy4NCg0KYGBge3J9DQojIFF1YXJ0aWxlczoNCnJlczwtcXVhbnRpbGUoZGZfVEEkU1Q1NU02MDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQoNCmBgYA0KDQojIyMgRGVuc2l0eSBGdW5jdGlvbjogNnRoIE1pbGwgVEEgUG93ZXIgKGtXKQ0KDQpXZSBleGFtaW5lIHRoZSBwb3dlciBkaXN0cmlidXRpb24gb2YgdGhlIG1pbGwsIGFzIGEgcHJveHkgdmFyaWFibGUgZm9yIGlkZW50aWZpeWluZyBhbiBhY2NlcHRhYmxlIGxvYWQgcmFuZ2UuDQpgYGB7cn0NCg0KIyBQREYNCmRpc3RyKGRmX1RBLCdKVDU1TTYwMScpDQoNCiMgQm94cGxvdA0KZ2dwbG90KGRmX1RBLCBhZXMoeT1KVDU1TTYwMSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCANCiAgICAgICAgIyBjdXN0b20gYm94ZXMNCiAgICAgICAgY29sb3I9ImJsdWUiLA0KICAgICAgICBmaWxsPSJibHVlIiwNCiAgICAgICAgYWxwaGE9MC4yLA0KICAgICAgICANCiAgICAgICAgIyBOb3RjaA0KICAgICAgICBub3RjaD1UUlVFLA0KICAgICAgICBub3RjaHdpZHRoID0gMC44LA0KICAgICAgICANCiAgICAgICAgIyBjdXN0b20gb3V0bGllcnMNCiAgICAgICAgb3V0bGllci5jb2xvdXI9InJlZCIsDQogICAgICAgIG91dGxpZXIuZmlsbD0icmVkIiwNCiAgICAgICAgb3V0bGllci5zaXplPTMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgpICsNCiAgbGFicyh0aXRsZT0iQm94cGxvdCIseD0iIiwgeSA9ICJKVDU1TTYwMSAoa1cpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRKVDU1TTYwMSkpDQoNCmBgYA0KTWF4aW11bSBBdmVyYWdlIE9wZXJhdGlvbmFsIFBvd2VyOiA3Njkga1cNCg0KYGBge3J9DQojIFF1YXJ0aWxlczoNCnJlczwtcXVhbnRpbGUoZGZfVEEkSlQ1NU02MDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQoNCmBgYA0KDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiA2dGggTWlsbCBUQSBDaHV0ZSBMZXZlbCAoJSkNCg0KV2UgZXhhbWluZSB0aGUgY2h1dGUgbGV2ZWwgZGlzdHJpYnV0aW9uIG9mIHRoZSBtaWxsLg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnTFQ1NU02MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9TFQ1NU02MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiTFQ1NU02MDEgKCUpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRMVDU1TTYwMSkpDQoNCmBgYA0KYGBge3J9DQojIFF1YXJ0aWxlczoNCnJlczwtcXVhbnRpbGUoZGZfVEEkTFQ1NU02MDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQoNCmBgYA0KDQojIyMgRGF0YWZyYW1lIEZpbHRlcmluZw0KDQpXZSBmaWx0ZXIgb2JzZXJ2YXRpb25zIGZvciB0aGUgZm9sbG93aW5nIG9wZXJhdGlvbmFsIHJhbmdlczoNCg0KLSBQb3dlciBSYW5nZSBmb3IgTm9ybWFsIFN1Z2FyIENhbmUgTWlsbGluZy4NCi0gU3BlZWQgUmFuZ2UgZm9yIEhpZ2ggQ2h1dGUgTGV2ZWwgQ29uZGl0aW9uIGluIHRoZSBNaWxsLg0KDQpgYGB7cn0NCg0KIyBGaWx0ZXIgRGF0YXNldCBieSBDb2x1bW4gVmFsdWVzOg0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFbZGZfVEEkSlQ1NU02MDE+PTQ4OSxdICMgRmlsdGVyIGJ5IE1pbmltdW0gVGhyZXNob2xkIG9mIDFzdCBRdWFydGlsZSBQb3dlcg0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFfZmlsdGVyZWRbZGZfVEFfZmlsdGVyZWQkU1Q1NU02MDE+PTEwMTUsXSAjIEZpbHRlciBieSBUb3AgMjUlIG9mIE1heGltdW0gT3BlcmF0aW9uYWwgU3BlZWQgKDEwNTApDQpkZl9UQV9maWx0ZXJlZA0KDQpgYGANCiMjIyBMYXJnZXN0IENvcnJlbGF0aW9uIFZhcmlhYmxlcyB3aXRoIFRBIEltYmliaXRpb24gV2F0ZXINCg0KV2UgaW5zcGVjdCB0aGUgbGFyZ2VzdCBjb3JyZWxhdGVkIHZhcmlhYmxlcyB3aXRoIEltYmliaXRpb24gV2F0ZXINCmBgYHtyfQ0KY29ycl92YXIoZGZfVEFfZmlsdGVyZWQsICMgZGF0YWZyYW1lIG5hbWUNCiAgSW1iVEEsICMgdGFyZ2V0DQogIG1heF9wdmFsdWUgPSAwLjA1LCAjIHNpZ25pZmljYW5jZSBsZXZlbA0KICB0b3AgPSAxNSwgIyB0b3AgbiBtb3N0IGNvcnJlbGF0ZWQgdmFyaWFibGVzIHdpdGggdGFyZ2V0DQogIHBsb3QgPSBUDQopDQoNCmBgYA0KDQojIyMgU2NhdHRlciBQbG90cyBmb3IgVEEgSW1iaWJpdGlvbiBXYXRlcg0KDQoqKkRheSBvZiBTZWFzb24qKg0KRGF5IG9mIFNlYXNvbiBtaWdodCBiZSBhIGNvbmZvdW5kZXIgdmFyaWFibGUsIGJlY2F1c2UgdXN1YWxseSBpdCBpcyBoaWdobHkgY29ycmVsYXRlZCB3aXRoIGJhZ2Fzc2UgLyBmaWJlciBjb250ZW50IG9mIHRoZSBzdWdhciBjYW5lLiBXZSBpbnNwZWN0IHRoaXMgY29ycmVsYXRpb24uDQoNCmBgYHtyfQ0KbGFiZWxfeCA8LSAiRGlhLlphZnJhIg0KbGFiZWxfeSA8LSAiZmlicmEuY2HDsWEudGEiDQoNCm1hcGFfZGlzcGVyc2lvbihsYWJlbF94LGxhYmVsX3ksZGZfVEFfZmlsdGVyZWQpDQpgYGANCg0KKio2dGggTWlsbCBUQSBTcGVlZCoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIlNUNTVNNjAxIg0KbGFiZWxfeSA8LSAiSW1iVEEiDQoNCm1hcGFfZGlzcGVyc2lvbihsYWJlbF94LGxhYmVsX3ksZGZfVEFfZmlsdGVyZWQpDQpgYGANCg0KKipTdWdhciBDYW5lIEJhZ2Fzc2UgQ29udGVudCBUQSAqKg0KYGBge3J9DQpsYWJlbF94IDwtICJiYWdhem8uLi5jYcOxYS50YSINCmxhYmVsX3kgPC0gIkltYlRBIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RBX2ZpbHRlcmVkKQ0KYGBgDQoNCioqRmliZXIgQ29udGVudCBUYW5kZW0gQSoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIlguLkZpYnJhLkNvcmUuVEEiDQpsYWJlbF95IDwtICJJbWJUQSINCg0KbWFwYV9kaXNwZXJzaW9uKGxhYmVsX3gsbGFiZWxfeSxkZl9UQV9maWx0ZXJlZCkNCmBgYA0KDQoqKkJhZ2Fzc2UgTWFzcyBGbG93IFRBICoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIldUNTU1ODAxIg0KbGFiZWxfeSA8LSAiSW1iVEEiDQoNCm1hcGFfZGlzcGVyc2lvbihsYWJlbF94LGxhYmVsX3ksZGZfVEFfZmlsdGVyZWQpDQpgYGANCg0KDQoqKlN1Z2FyIENhbmUgVHJhc2ggQ29udGVudCBUYW5kZW0gQSoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIlguLlRyYXNoLlBvbmRlcmFkbyINCmxhYmVsX3kgPC0gIkltYlRBIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RBX2ZpbHRlcmVkKQ0KYGBgDQoNCioqVG9ycXVlIG9uIE1pbGwgMSBUQSoqDQpEYXkgb2YgU2Vhc29uIG1pZ2h0IGJlIGEgY29uZm91bmRlciB2YXJpYWJsZSwgYmVjYXVzZSB1c3VhbGx5IGl0IGlzIGhpZ2hseSBjb3JyZWxhdGVkIHdpdGggYmFnYXNzZSAvIGZpYmVyIGNvbnRlbnQgb2YgdGhlIHN1Z2FyIGNhbmUuIFdlIGluc3BlY3QgdGhpcyBjb3JyZWxhdGlvbi4NCg0KYGBge3J9DQpsYWJlbF94IDwtICJUUTU1TTEwMSINCmxhYmVsX3kgPC0gIkltYlRBIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RBX2ZpbHRlcmVkKQ0KYGBgDQoNCg0KIyMjIEltYmliaXRpb24gV2F0ZXIgVEEgTGluZWFyIE1vZGVsDQpgYGB7cn0NCmxtX0ltYlRBID0gbG0oSW1iVEEgfiBUUTU1TTEwMSArIFdUNTU1ODAxICsgWC4uRmlicmEuQ29yZS5UQSArIFNUNTVNNjAxICsgYmFnYXpvLi4uY2HDsWEudGEgKyBUcmFzaC5Ub3RhbC4uLi4sIGRhdGEgPSBkZl9UQV9maWx0ZXJlZCkgI0NyZWF0ZSB0aGUgbGluZWFyIHJlZ3Jlc3Npb24NCnN1bW1hcnkobG1fSW1iVEEpDQpgYGANCg0KIyMjIEltYmliaXRpb24gV2F0ZXIgVEEgTGluZWFyIE1vZGVsIFRlc3QNCg0KYGBge3J9DQojIGFwcGx5aW5nIGZpdHRlZCB2YWx1ZXMgdG8gVEEgZGF0YSBmcmFtZQ0KZGZfVEFfZmlsdGVyZWQkZml0dGVkPC0gbG1fSW1iVEEkZml0dGVkLnZhbHVlcw0KDQojIGNyZWF0aW5nIGdncGxvdCBvYmplY3QgZm9yIHZpc3VhbGl6YXRpb24NCmxtX0ltYlRBX3Bsb3QgPC0gZ2dwbG90KGRmX1RBX2ZpbHRlcmVkLCBhZXMoeD0gRGlhLlphZnJhLCB5PSBJbWJUQSxjb2xvdXI9InJlYWwgdmFsdWVzIikpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGFlcyh5PSBmaXR0ZWQsIGNvbG91cj0iZml0dGVkIHZhbHVlcyIpKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIkltYmliaXRpb24gV2F0ZXIgVEEiLCB2YWx1ZXMgPSBjKCJmaXR0ZWQgdmFsdWVzIiA9ICJkYXJrYmx1ZSIsICJyZWFsIHZhbHVlcyIgPSAicmVkIikpDQoNCnByaW50KGxtX0ltYlRBX3Bsb3QpDQoNCmBgYA0KIyMgVGFuZGVtICJCIg0KDQojIyMgRGVuc2l0eSBGdW5jdGlvbjogNnRoIE1pbGwgVEIgU3BlZWQgKHJwbSkNCldlIGZpcnN0IHRha2UgYSBsb29rIGF0IHRoZSBNaWxsIFNwZWVkIERpc3RyaWJ1dGlvbiwgdG8gaWRlbnRpZnkgdGhlIHNwZWVkIHJhbmdlIHdoZXJlIHRoZSBsZXZlbCBjb250cm9sIG9mIHRoZSBtaWxsIGlzIG5lYXJseSBsb3N0Lg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQiwnU1Q1NU42MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQiwgYWVzKHk9U1Q1NU42MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiU1Q1NU42MDEgKHJwbSkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RCJFNUNTVONjAxKSkNCg0KYGBgDQoNCk1heGltdW0gT3BlcmF0aW9uYWwgU3BlZWQ6IDEyMDAgcnBtcy4gTWF4aW11bSBBdmVyYWdlIE9wZXJhdGlvbmFsIFNwZWVkOiAxMTYwIHJwbXMuDQoNCmBgYHtyfQ0KIyBRdWFydGlsZXM6DQpyZXM8LXF1YW50aWxlKGRmX1RCJFNUNTVONjAxLCBwcm9icyA9IGMoMCwwLjI1LDAuNSwwLjc1LDEpKSANCnJlcw0KDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IDZ0aCBNaWxsIFRCIFBvd2VyIChrVykNCldlIGV4YW1pbmUgdGhlIHBvd2VyIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbWlsbCwgYXMgYSBwcm94eSB2YXJpYWJsZSBmb3IgaWRlbnRpZml5aW5nIGFuIGFjY2VwdGFibGUgbG9hZCByYW5nZS4NCmBgYHtyfQ0KDQojIFBERg0KZGlzdHIoZGZfVEIsJ0pUNTVONjAxJykNCg0KIyBCb3hwbG90DQpnZ3Bsb3QoZGZfVEIsIGFlcyh5PUpUNTVONjAxKSkgKyANCiAgICBnZW9tX2JveHBsb3QoIA0KICAgICAgICAjIGN1c3RvbSBib3hlcw0KICAgICAgICBjb2xvcj0iYmx1ZSIsDQogICAgICAgIGZpbGw9ImJsdWUiLA0KICAgICAgICBhbHBoYT0wLjIsDQogICAgICAgIA0KICAgICAgICAjIE5vdGNoDQogICAgICAgIG5vdGNoPVRSVUUsDQogICAgICAgIG5vdGNod2lkdGggPSAwLjgsDQogICAgICAgIA0KICAgICAgICAjIGN1c3RvbSBvdXRsaWVycw0KICAgICAgICBvdXRsaWVyLmNvbG91cj0icmVkIiwNCiAgICAgICAgb3V0bGllci5maWxsPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLnNpemU9MykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCkgKw0KICBsYWJzKHRpdGxlPSJCb3hwbG90Iix4PSIiLCB5ID0gIkpUNTVONjAxIChrVykiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RCJEpUNTVONjAxKSkNCg0KYGBgDQpNYXhpbXVtIE9wZXJhdGlvbmFsIFBvd2VyOiA5MDAga1cNCg0KYGBge3J9DQojIFF1YXJ0aWxlczoNCnJlczwtcXVhbnRpbGUoZGZfVEIkSlQ1NU42MDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQoNCmBgYA0KDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiA2dGggTWlsbCBUQiBDaHV0ZSBMZXZlbCAoJSkNCg0KV2UgZXhhbWluZSB0aGUgY2h1dGUgbGV2ZWwgZGlzdHJpYnV0aW9uIG9mIHRoZSBtaWxsLg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQiwnTFQ1NU42MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQiwgYWVzKHk9TFQ1NU42MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiTFQ1NU42MDEgKCUpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQiRMVDU1TjYwMSkpDQoNCmBgYA0KYGBge3J9DQojIFF1YXJ0aWxlczoNCnJlczwtcXVhbnRpbGUoZGZfVEIkTFQ1NU42MDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQojIEZpbHRlciBEYXRhc2V0IGJ5IENvbHVtbiBWYWx1ZXM6DQpkZl9UQl9maWx0ZXJlZCA8LSBkZl9UQltkZl9UQiRKVDU1TjYwMT49NTQyLF0gIyBGaWx0ZXIgYnkgTWluaW11bSBUaHJlc2hvbGQgb2YgMXN0IFF1YXJ0aWxlIFBvd2VyDQpkZl9UQl9maWx0ZXJlZCA8LSBkZl9UQl9maWx0ZXJlZFtkZl9UQl9maWx0ZXJlZCRTVDU1TjYwMT49MTAxMixdICMgRmlsdGVyIGJ5IFRvcCAyNSUgb2YgTWF4aW11bSBPcGVyYXRpb25hbCBTcGVlZA0KZGZfVEJfZmlsdGVyZWQNCg0KYGBgDQoNCiMjIyBMYXJnZXN0IENvcnJlbGF0aW9uIFZhcmlhYmxlcyB3aXRoIFRCIEltYmliaXRpb24gV2F0ZXINCmBgYHtyfQ0KY29ycl92YXIoZGZfVEJfZmlsdGVyZWQsICMgZGF0YWZyYW1lIG5hbWUNCiAgSW1iVEIsICMgdGFyZ2V0DQogIG1heF9wdmFsdWUgPSAwLjA1LCAjIHNpZ25pZmljYW5jZSBsZXZlbA0KICB0b3AgPSAxNSwgIyB0b3AgbiBtb3N0IGNvcnJlbGF0ZWQgdmFyaWFibGVzIHdpdGggdGFyZ2V0DQogIHBsb3QgPSBUDQopDQoNCmBgYA0KDQoNCioqRGF5IG9mIFNlYXNvbioqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIkRpYS5aYWZyYSINCmxhYmVsX3kgPC0gIkltYlRCIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RCX2ZpbHRlcmVkKQ0KYGBgDQoNCioqNnRoIFRCIE1pbGwgU3BlZWQqKg0KYGBge3J9DQpsYWJlbF94IDwtICJTVDU1TjYwMSINCmxhYmVsX3kgPC0gIkltYlRCIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RCX2ZpbHRlcmVkKQ0KYGBgDQoNCioqMXN0IFRCIE1pbGwgUG93ZXIqKg0KYGBge3J9DQpsYWJlbF94IDwtICJKVDU1TjEwMSINCmxhYmVsX3kgPC0gIkltYlRCIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RCX2ZpbHRlcmVkKQ0KYGBgDQoNCioqU3VnYXIgQ2FuZSBGaWJlciBDb250ZW50IFRhbmRlbSBCKioNCmBgYHtyfQ0KbGFiZWxfeCA8LSAiWC4uRmlicmEuQ29yZS5UQiINCmxhYmVsX3kgPC0gIkltYlRCIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RCX2ZpbHRlcmVkKQ0KYGBgDQoNCiMjIyBJbWJpYml0aW9uIFdhdGVyIFRCIExpbmVhciBNb2RlbA0KYGBge3J9DQpsbV9JbWJUQiA9IGxtKEltYlRCIH4gRGlhLlphZnJhICsgU1Q1NU42MDEgKyBUUTU1TjEwMV9zdGRldiArIEpUNTVOMTAxX3N0ZGV2ICsgY2HDsWEubW9saWRhLnRiLCBkYXRhID0gZGZfVEJfZmlsdGVyZWQpICNDcmVhdGUgdGhlIGxpbmVhciByZWdyZXNzaW9uDQpzdW1tYXJ5KGxtX0ltYlRCKQ0KYGBgDQoNCiMjIyBJbWJpYml0aW9uIFdhdGVyIFRCIExpbmVhciBNb2RlbCBUZXN0DQoNCmBgYHtyfQ0KIyBhcHBseWluZyBmaXR0ZWQgdmFsdWVzIHRvIFRCIGRhdGEgZnJhbWUNCmRmX1RCX2ZpbHRlcmVkJGZpdHRlZDwtIGxtX0ltYlRCJGZpdHRlZC52YWx1ZXMNCg0KIyBjcmVhdGluZyBnZ3Bsb3Qgb2JqZWN0IGZvciB2aXN1YWxpemF0aW9uDQpsbV9JbWJUQl9wbG90IDwtIGdncGxvdChkZl9UQl9maWx0ZXJlZCwgYWVzKHg9IERpYS5aYWZyYSwgeT0gSW1iVEIsY29sb3VyPSJyZWFsIHZhbHVlcyIpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZShhZXMoeT0gZml0dGVkLCBjb2xvdXI9ImZpdHRlZCB2YWx1ZXMiKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJJbWJpYml0aW9uIFdhdGVyIFRCIiwgdmFsdWVzID0gYygiZml0dGVkIHZhbHVlcyIgPSAiZGFya2JsdWUiLCAicmVhbCB2YWx1ZXMiID0gInJlZCIpKQ0KDQpwcmludChsbV9JbWJUQl9wbG90KQ0KDQpgYGANCg0K