Data Filtering Criteria for Tandem A in 2023-2024 Harvest
Season.
Libraries
library(dplyr)
library(pastecs)
library(ggplot2)
library(lares)
Scatter 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)
}
Mill 1 TA Dataset
df_TA <- read.csv(file = 'Mill_1_TA.csv')
df_TA
Density Function: Mill 1 TA Speed (rpm)
# PDF
distr(df_TA,'ST55M101')

# Boxplot
ggplot(df_TA, aes(y=ST55M101)) +
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 = "ST55M101 (rpm)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$ST55M101))
NA
Density Function: Mill 1 TA Torque (N*m)
# PDF
distr(df_TA,'TQ55M101')

# Boxplot
ggplot(df_TA, aes(y=TQ55M101)) +
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 = "TQ55M101 (N*m)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$TQ55M101))
NA
Density Function: Mill 1 TA Power (kW)
# PDF
distr(df_TA,'JT55M101')

# Boxplot
ggplot(df_TA, aes(y=JT55M101)) +
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 = "JT55M101 (kW)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$JT55M101))
NA
Density Function: Mill 1 TA Level (%)
# PDF
distr(df_TA,'LT55M101')

# Boxplot
ggplot(df_TA, aes(y=LT55M101)) +
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 = "LT55M101 (%)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$LT55M101))
NA
Density Function: TA Bagasse Mass Flow (t/h)
# PDF
distr(df_TA,'WT555801')

# Boxplot
ggplot(df_TA, aes(y=WT555801)) +
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 = "WT555801 (t/h)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$WT555801))
NA
Filtering Criteria:
We first need to exclude any intentional or planned downtime of TA.
This can be done by filtering the left tail of the Torque (TQ55M101) and
Speed (ST55M101) distributions of the Mill 1 T, since the Mill stops
completely.
We also need to filter out any unintentional or unplanned downtime of
TA. This can be done by filtering the left tail of the bagasse mass flow
of TA. This works because for unplanned downtime usually the first mill
does not stop (because of the uncertainty of the duration of the stop).
Also we can estimate the sugar cane crush rate by the bagasse mass flow
coming out of the tandem (WT555801).
Scatter Plots and Correlations
Torque and Bagasse Relation Mill 1 TA
label_x <- "WT555801"
label_y <- "TQ55M101"
mapa_dispersion(label_x,label_y,df_TA)

Torque and Bagasse Mass Flow are correlated, but not perfectly. So we
need to filter out observations based on these variables
individually.
Torque and Power Relation Mill 1 TA
label_x <- "JT55M101"
label_y <- "TQ55M101"
mapa_dispersion(label_x,label_y,df_TA)

Torque and Mill Power are strongly correlated, almost perfectly. So
there is no need to filter out observations based on these variables
individually. We choose Torque since it contains information about Power
and Speed simultaneously.
WT5557801 Quantiles
# Filter Dataset by Column Values:
res<-quantile(df_TA$WT555801, probs = c(0,0.25,0.5,0.75,1))
res
0% 25% 50% 75% 100%
21.56174 132.91532 147.77292 158.52945 183.46936
TQ55M101 Quantiles
# Filter Dataset by Column Values:
res<-quantile(df_TA$TQ55M101, probs = c(0,0.25,0.5,0.75,1))
res
0% 25% 50% 75% 100%
226.5511 1869.4912 2092.0420 2283.7543 2579.5171
ST55M101 Quantiles
# Filter Dataset by Column Values:
res<-quantile(df_TA$ST55M101, probs = c(0,0.25,0.5,0.75,1))
res
0% 25% 50% 75% 100%
172.5349 702.7378 746.5287 774.9827 999.9883
# Filter Dataset by Column Values:
df_TA_filtered <- df_TA[df_TA$WT555801>=130,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) :
invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) :
attempt to use zero-length variable name
df_TA_filtered <- df_TA_filtered[df_TA_filtered$TQ55M101>=1800,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) :
invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) :
attempt to use zero-length variable name
df_TA_filtered <- df_TA_filtered[df_TA_filtered$ST55M101>=700,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) :
invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) :
attempt to use zero-length variable name
df_TA_filtered
Torque and Bagasse Relation Mill 1 TA (Filtered
Dataset)
label_x <- "WT555801"
label_y <- "TQ55M101"
mapa_dispersion(label_x,label_y,df_TA_filtered)

Density Function: TA Bagasse Mass Flow (t/h) Filtered
Distribution
# PDF
distr(df_TA_filtered,'WT555801')

# Boxplot
ggplot(df_TA_filtered, aes(y=WT555801)) +
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 = "WT555801 (t/h)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$WT555801))
NA
Density Function: Mill 1 TA Torque (t/h) Filtered Distribution
# PDF
distr(df_TA_filtered,'TQ55M101')

# Boxplot
ggplot(df_TA_filtered, aes(y=WT555801)) +
geom_boxplot(
# custom boxes
color="blue",
fill="blue",
alpha=0.2,
# Notch
notch=TRUE,
notchwidth = 0.8,
outlier.colour="red",
outlier.fill="red",
outlier.size=3) +
scale_x_discrete() +
labs(title="Boxplot",x="", y = "TQ55M101 (t/h)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$TQ55M101))
NA
Density Function: Mill 1 TA Speed (rpm) Filtered Distribution
# PDF
distr(df_TA_filtered,'ST55M101')

# Boxplot
ggplot(df_TA_filtered, aes(y=ST55M101)) +
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 = "ST55M101 (rpm)")

# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$ST55M101))
NA
Filter Criteria
Filter out any points for which:
- WT555801 < 130
- TQ55M101 < 1800
- ST55M101 < 700
LS0tDQp0aXRsZTogIlRhbmRlbSBBIERhdGEgRmlsdGVyaW5nIENyaXRlcmlhIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMjIERhdGEgRmlsdGVyaW5nIENyaXRlcmlhIGZvciBUYW5kZW0gQSBpbiAqKjIwMjMtMjAyNCBIYXJ2ZXN0IFNlYXNvbioqLg0KDQpMaWJyYXJpZXMNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocGFzdGVjcykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobGFyZXMpDQpgYGANCg0KDQojIyMgU2NhdHRlciBQbG90IEZ1bmN0aW9uDQpgYGB7cn0NCm1hcGFfZGlzcGVyc2lvbiA8LSBmdW5jdGlvbihsYWJlbF94LGxhYmVsX3ksZGF0YXNldCkgew0KICBjb3JyZWxhY2lvbiA8LSByb3VuZChjb3IoZGF0YXNldFtbbGFiZWxfeF1dLGRhdGFzZXRbW2xhYmVsX3ldXSksMikNCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyguZGF0YVtbbGFiZWxfeF1dLCAuZGF0YVtbbGFiZWxfeV1dKSkgKyANCiAgICBnZW9tX3BvaW50KA0KICAgICAgICBjb2xvcj0ib3JhbmdlIiwNCiAgICAgICAgZmlsbD0iIzY5YjNhMiIsDQogICAgICAgIHNoYXBlPTIxLA0KICAgICAgICBhbHBoYT0wLjUsDQogICAgICAgIHNpemU9NiwNCiAgICAgICAgc3Ryb2tlID0gMg0KICAgICAgICApICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0gLCBjb2xvcj0iIzk5MDAwMCIsIGZpbGw9IiNGRkNGMDAiLCBzZT1UUlVFKSArDQogICAgZ2d0aXRsZShwYXN0ZShsYWJlbF95LCJ2cnMuIixsYWJlbF94KSwgc3VidGl0bGUgPSBwYXN0ZSgiQ29ycmVsYXRpb246ICIsY29ycmVsYWNpb24pKSArDQogIHhsYWIobGFiZWxfeCkgKyB5bGFiKGxhYmVsX3kpDQp9DQpgYGANCg0KIyMjIE1pbGwgMSBUQSBEYXRhc2V0DQpgYGB7cn0NCmRmX1RBIDwtIHJlYWQuY3N2KGZpbGUgPSAnTWlsbF8xX1RBLmNzdicpDQoNCmRmX1RBDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBTcGVlZCAocnBtKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnU1Q1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9U1Q1NU0xMDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiU1Q1NU0xMDEgKHJwbSkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBJFNUNTVNMTAxKSkNCg0KYGBgDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBNaWxsIDEgVEEgVG9ycXVlIChOKm0pDQpgYGB7cn0NCg0KIyBQREYNCmRpc3RyKGRmX1RBLCdUUTU1TTEwMScpDQoNCiMgQm94cGxvdA0KZ2dwbG90KGRmX1RBLCBhZXMoeT1UUTU1TTEwMSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCANCiAgICAgICAgIyBjdXN0b20gYm94ZXMNCiAgICAgICAgY29sb3I9ImJsdWUiLA0KICAgICAgICBmaWxsPSJibHVlIiwNCiAgICAgICAgYWxwaGE9MC4yLA0KICAgICAgICANCiAgICAgICAgIyBOb3RjaA0KICAgICAgICBub3RjaD1UUlVFLA0KICAgICAgICBub3RjaHdpZHRoID0gMC44LA0KICAgICAgICANCiAgICAgICAgIyBjdXN0b20gb3V0bGllcnMNCiAgICAgICAgb3V0bGllci5jb2xvdXI9InJlZCIsDQogICAgICAgIG91dGxpZXIuZmlsbD0icmVkIiwNCiAgICAgICAgb3V0bGllci5zaXplPTMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgpICsNCiAgbGFicyh0aXRsZT0iQm94cGxvdCIseD0iIiwgeSA9ICJUUTU1TTEwMSAoTiptKSIpDQoNCiMgRGVzY3JpcHRpdmUgU3RhdGlzdGljcw0KZGF0YS5mcmFtZShFc3RhZGlzdGljYT1zdGF0LmRlc2MoZGZfVEEkVFE1NU0xMDEpKQ0KDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBQb3dlciAoa1cpDQpgYGB7cn0NCg0KIyBQREYNCmRpc3RyKGRmX1RBLCdKVDU1TTEwMScpDQoNCiMgQm94cGxvdA0KZ2dwbG90KGRmX1RBLCBhZXMoeT1KVDU1TTEwMSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCANCiAgICAgICAgIyBjdXN0b20gYm94ZXMNCiAgICAgICAgY29sb3I9ImJsdWUiLA0KICAgICAgICBmaWxsPSJibHVlIiwNCiAgICAgICAgYWxwaGE9MC4yLA0KICAgICAgICANCiAgICAgICAgIyBOb3RjaA0KICAgICAgICBub3RjaD1UUlVFLA0KICAgICAgICBub3RjaHdpZHRoID0gMC44LA0KICAgICAgICANCiAgICAgICAgIyBjdXN0b20gb3V0bGllcnMNCiAgICAgICAgb3V0bGllci5jb2xvdXI9InJlZCIsDQogICAgICAgIG91dGxpZXIuZmlsbD0icmVkIiwNCiAgICAgICAgb3V0bGllci5zaXplPTMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgpICsNCiAgbGFicyh0aXRsZT0iQm94cGxvdCIseD0iIiwgeSA9ICJKVDU1TTEwMSAoa1cpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRKVDU1TTEwMSkpDQoNCmBgYA0KDQojIyMgRGVuc2l0eSBGdW5jdGlvbjogTWlsbCAxIFRBIExldmVsICglKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnTFQ1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9TFQ1NU0xMDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiTFQ1NU0xMDEgKCUpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRMVDU1TTEwMSkpDQoNCmBgYA0KDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBUQSBCYWdhc3NlIE1hc3MgRmxvdyAodC9oKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnV1Q1NTU4MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiV1Q1NTU4MDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBJFdUNTU1ODAxKSkNCg0KYGBgDQoNCiMjIEZpbHRlcmluZyBDcml0ZXJpYToNCldlIGZpcnN0IG5lZWQgdG8gZXhjbHVkZSBhbnkgaW50ZW50aW9uYWwgb3IgcGxhbm5lZCBkb3dudGltZSBvZiBUQS4gVGhpcyBjYW4gYmUgZG9uZSBieSBmaWx0ZXJpbmcgdGhlIGxlZnQgdGFpbCBvZiB0aGUgVG9ycXVlIChUUTU1TTEwMSkgYW5kIFNwZWVkIChTVDU1TTEwMSkgZGlzdHJpYnV0aW9ucyBvZiB0aGUgTWlsbCAxIFQsIHNpbmNlIHRoZSBNaWxsIHN0b3BzIGNvbXBsZXRlbHkuDQoNCldlIGFsc28gbmVlZCB0byBmaWx0ZXIgb3V0IGFueSB1bmludGVudGlvbmFsIG9yIHVucGxhbm5lZCBkb3dudGltZSBvZiBUQS4gVGhpcyBjYW4gYmUgZG9uZSBieSBmaWx0ZXJpbmcgdGhlIGxlZnQgdGFpbCBvZiB0aGUgYmFnYXNzZSBtYXNzIGZsb3cgb2YgVEEuIFRoaXMgd29ya3MgYmVjYXVzZSBmb3IgdW5wbGFubmVkIGRvd250aW1lIHVzdWFsbHkgdGhlIGZpcnN0IG1pbGwgZG9lcyBub3Qgc3RvcCAoYmVjYXVzZSBvZiB0aGUgdW5jZXJ0YWludHkgb2YgdGhlIGR1cmF0aW9uIG9mIHRoZSBzdG9wKS4gQWxzbyB3ZSBjYW4gZXN0aW1hdGUgdGhlIHN1Z2FyIGNhbmUgY3J1c2ggcmF0ZSBieSB0aGUgYmFnYXNzZSBtYXNzIGZsb3cgY29taW5nIG91dCBvZiB0aGUgdGFuZGVtIChXVDU1NTgwMSkuDQoNCg0KIyMjIFNjYXR0ZXIgUGxvdHMgYW5kIENvcnJlbGF0aW9ucw0KDQoqKlRvcnF1ZSBhbmQgQmFnYXNzZSBSZWxhdGlvbiBNaWxsIDEgVEEqKg0KYGBge3J9DQpsYWJlbF94IDwtICJXVDU1NTgwMSINCmxhYmVsX3kgPC0gIlRRNTVNMTAxIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RBKQ0KYGBgDQpUb3JxdWUgYW5kIEJhZ2Fzc2UgTWFzcyBGbG93IGFyZSBjb3JyZWxhdGVkLCBidXQgbm90IHBlcmZlY3RseS4gU28gd2UgbmVlZCB0byBmaWx0ZXIgb3V0IG9ic2VydmF0aW9ucyBiYXNlZCBvbiB0aGVzZSB2YXJpYWJsZXMgaW5kaXZpZHVhbGx5Lg0KDQoqKlRvcnF1ZSBhbmQgUG93ZXIgUmVsYXRpb24gTWlsbCAxIFRBKioNCmBgYHtyfQ0KbGFiZWxfeCA8LSAiSlQ1NU0xMDEiDQpsYWJlbF95IDwtICJUUTU1TTEwMSINCg0KbWFwYV9kaXNwZXJzaW9uKGxhYmVsX3gsbGFiZWxfeSxkZl9UQSkNCmBgYA0KVG9ycXVlIGFuZCBNaWxsIFBvd2VyIGFyZSBzdHJvbmdseSBjb3JyZWxhdGVkLCBhbG1vc3QgcGVyZmVjdGx5LiBTbyB0aGVyZSBpcyBubyBuZWVkIHRvIGZpbHRlciBvdXQgb2JzZXJ2YXRpb25zIGJhc2VkIG9uIHRoZXNlIHZhcmlhYmxlcyBpbmRpdmlkdWFsbHkuIFdlIGNob29zZSBUb3JxdWUgc2luY2UgaXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgUG93ZXIgYW5kIFNwZWVkIHNpbXVsdGFuZW91c2x5Lg0KDQojIyMgV1Q1NTU3ODAxIFF1YW50aWxlcw0KYGBge3J9DQojIEZpbHRlciBEYXRhc2V0IGJ5IENvbHVtbiBWYWx1ZXM6DQpyZXM8LXF1YW50aWxlKGRmX1RBJFdUNTU1ODAxLCBwcm9icyA9IGMoMCwwLjI1LDAuNSwwLjc1LDEpKSANCnJlcw0KYGBgDQojIyMgVFE1NU0xMDEgUXVhbnRpbGVzDQpgYGB7cn0NCiMgRmlsdGVyIERhdGFzZXQgYnkgQ29sdW1uIFZhbHVlczoNCnJlczwtcXVhbnRpbGUoZGZfVEEkVFE1NU0xMDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQpgYGANCiMjIyBTVDU1TTEwMSBRdWFudGlsZXMNCmBgYHtyfQ0KIyBGaWx0ZXIgRGF0YXNldCBieSBDb2x1bW4gVmFsdWVzOg0KcmVzPC1xdWFudGlsZShkZl9UQSRTVDU1TTEwMSwgcHJvYnMgPSBjKDAsMC4yNSwwLjUsMC43NSwxKSkgDQpyZXMNCmBgYA0KDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgRGF0YXNldCBieSBDb2x1bW4gVmFsdWVzOg0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFbZGZfVEEkV1Q1NTU4MDE+PTEzMCxdICMgRmlsdGVyIGJ5IE1pbmltdW0gVGhyZXNob2xkIG9mIDFzdCBRdWFydGlsZQ0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFfZmlsdGVyZWRbZGZfVEFfZmlsdGVyZWQkVFE1NU0xMDE+PTE4MDAsXSAjIEZpbHRlciBieSBNaW5pbXVtIFRocmVzaG9sZCBvZiAxc3QgUXVhcnRpbGUNCmRmX1RBX2ZpbHRlcmVkIDwtIGRmX1RBX2ZpbHRlcmVkW2RmX1RBX2ZpbHRlcmVkJFNUNTVNMTAxPj03MDAsXSAjIEZpbHRlciBieSBNaW5pbXVtIFRocmVzaG9sZCBvZiAxc3QgUXVhcnRpbGUNCmRmX1RBX2ZpbHRlcmVkDQpgYGANCg0KKipUb3JxdWUgYW5kIEJhZ2Fzc2UgUmVsYXRpb24gTWlsbCAxIFRBIChGaWx0ZXJlZCBEYXRhc2V0KSoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIldUNTU1ODAxIg0KbGFiZWxfeSA8LSAiVFE1NU0xMDEiDQoNCm1hcGFfZGlzcGVyc2lvbihsYWJlbF94LGxhYmVsX3ksZGZfVEFfZmlsdGVyZWQpDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IFRBIEJhZ2Fzc2UgTWFzcyBGbG93ICh0L2gpIEZpbHRlcmVkIERpc3RyaWJ1dGlvbg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQV9maWx0ZXJlZCwnV1Q1NTU4MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQV9maWx0ZXJlZCwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiV1Q1NTU4MDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBX2ZpbHRlcmVkJFdUNTU1ODAxKSkNCg0KYGBgDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBNaWxsIDEgVEEgVG9ycXVlICh0L2gpIEZpbHRlcmVkIERpc3RyaWJ1dGlvbg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQV9maWx0ZXJlZCwnVFE1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQV9maWx0ZXJlZCwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiVFE1NU0xMDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBX2ZpbHRlcmVkJFRRNTVNMTAxKSkNCg0KYGBgDQoNCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBTcGVlZCAocnBtKSBGaWx0ZXJlZCBEaXN0cmlidXRpb24NCmBgYHtyfQ0KDQojIFBERg0KZGlzdHIoZGZfVEFfZmlsdGVyZWQsJ1NUNTVNMTAxJykNCg0KIyBCb3hwbG90DQpnZ3Bsb3QoZGZfVEFfZmlsdGVyZWQsIGFlcyh5PVNUNTVNMTAxKSkgKyANCiAgICBnZW9tX2JveHBsb3QoIA0KICAgICAgICAjIGN1c3RvbSBib3hlcw0KICAgICAgICBjb2xvcj0iYmx1ZSIsDQogICAgICAgIGZpbGw9ImJsdWUiLA0KICAgICAgICBhbHBoYT0wLjIsDQogICAgICAgIA0KICAgICAgICAjIE5vdGNoDQogICAgICAgIG5vdGNoPVRSVUUsDQogICAgICAgIG5vdGNod2lkdGggPSAwLjgsDQogICAgICAgIA0KICAgICAgICAjIGN1c3RvbSBvdXRsaWVycw0KICAgICAgICBvdXRsaWVyLmNvbG91cj0icmVkIiwNCiAgICAgICAgb3V0bGllci5maWxsPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLnNpemU9MykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCkgKw0KICBsYWJzKHRpdGxlPSJCb3hwbG90Iix4PSIiLCB5ID0gIlNUNTVNMTAxIChycG0pIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQV9maWx0ZXJlZCRTVDU1TTEwMSkpDQoNCmBgYA0KDQojIyBGaWx0ZXIgQ3JpdGVyaWENCioqRmlsdGVyIG91dCoqIGFueSBwb2ludHMgZm9yIHdoaWNoOg0KDQoqIFdUNTU1ODAxIDwgMTMwDQoqIFRRNTVNMTAxIDwgMTgwMA0KKiBTVDU1TTEwMSA8IDcwMA0KDQo=