Example: The IRIS classification task
Here is the association between Sepal’s length and width and the two dimensional distribution of iris species in our datset:
library(ggplot2)
ggplot(iris,aes(x=Sepal.Length,y=Sepal.Width))+stat_density2d(geom="polygon",aes(fill=iris$Species,alpha = ..level..))+geom_point(aes(shape=Species),color="black",size=2)+theme_bw()+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))
The same analysis could be done for Petal’s length and width:
ggplot(iris,aes(x=Petal.Length,y=Petal.Width))+stat_density2d(geom="polygon",aes(fill=iris$Species,alpha = ..level..))+geom_point(aes(shape=Species),color="black",size=2)+theme_bw()+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))

As usual, we will set a classification task in mlr then introduce some learners
#Make a multiclass classification task in mlr
library(mlr)
## Loading required package: ParamHelpers
## Warning: replacing previous import 'BBmisc::isFALSE' by
## 'backports::isFALSE' when loading 'mlr'
taskiris=makeClassifTask(id="iris",data=iris,target="Species")
# Making 7 different Learners (algorithm)
learnerCART=makeLearner(id="CART","classif.rpart", predict.type = "prob")
learnerRF=makeLearner(id="RF","classif.randomForestSRC", predict.type = "prob")
learnerSVM=makeLearner(id="SVM","classif.svm", predict.type = "prob")
learnerGBM=makeLearner(id="GBM","classif.gbm", predict.type = "prob")
learnerGLMN=makeLearner(id="Elasticnet","classif.glmnet", predict.type = "prob")
learnerKNN=makeLearner(id="KNN","classif.knn")
learnerLDA=makeLearner(id="LDA","classif.lda", predict.type = "prob")
The syntax of plotLearnerPrediction( ) function
** plotLearnerPrediction(learner, task, features = NULL, measures, cv = 10L, …, gridsize, pointsize = 2, prob.alpha = TRUE, se.band = TRUE, err.col =”white“, greyscale = FALSE) **
Where:
learner is object’s name for learner task is the object name for task
features argument : up to 2 features could be introduced here. By default the first 2 features are used
measures indicate Performance measure(s) to evaluate. Default is the default measure for the task
cv for setting the cross-validation and reporting its result as plot title. Number of folds. cv=0 means no CV. Default is 10.
gridsize is the grid resolution per axis for background predictions. Default is 100 for 2D.
Pointsize for ggplot2 geom_point for data points. Default is 2.
prob.alpha is a logical argument, for setting alpha value of background to probability for predicted class? Allows visualization of “confidence” for prediction. If not, only a constant color is displayed in the background for the predicted label. Default is TRUE.
se.band: For regression in 1D: Show band for standard error estimation? Default is TRUE.
err.col: For classification, Color of misclassified data points. Default is “white”
greyscale is a logical argument: Should the plot be greyscale completely? Default is FALSE
CART algorithm
plotLearnerPrediction(learnerCART,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerCART,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
** Support vector machine algorithm **
plotLearnerPrediction(learnerSVM,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerSVM,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
** Gradient boosting machine algorithm **
plotLearnerPrediction(learnerGBM,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...

plotLearnerPrediction(learnerGBM,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
## Distribution not specified, assuming multinomial ...
Elastic net (logistic) algorithm
plotLearnerPrediction(learnerGLMN,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerGLMN,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
** KNN algorithm**
plotLearnerPrediction(learnerKNN,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerKNN,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

LDA algorithm
plotLearnerPrediction(learnerLDA,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerLDA,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()
Random Forest algorithm
plotLearnerPrediction(learnerRF,taskiris,features=c("Sepal.Length","Sepal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

plotLearnerPrediction(learnerRF,taskiris,features=c("Petal.Length","Petal.Width"),cv=100L,gridsize=100)+scale_fill_manual(values=c("#ff0061","#11a6fc","#ffae00"))+theme_bw()

LS0tCnRpdGxlOiA8Y2VudGVyPiBBIGhpZGRlbiBmdW5jdGlvbiBpbiBNTFIgPC9jZW50ZXI+CnN1YnRpdGxlOiA8Y2VudGVyPiBwbG90TGVhcm5lclByZWRpY3Rpb24oKSBmdW5jdGlvbiA8L2NlbnRlcj4KYXV0aG9yOiA8Y2VudGVyPiBPbGVnIEJheWRha292IDwvY2VudGVyPgpkYXRlOiA8Y2VudGVyPiBEZWNlbWJlciAwMiwgMjAxNyA8L2NlbnRlcj4Kb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OiAKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDoga2FibGUKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogZmxhdGx5CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgo8Y2VudGVyPiFbXShoaWRkZW5fZnVuY3Rpb25fbWxyLnBuZyl7IHdpZHRoPTUwJX08L2NlbnRlcj4KPGJyPgoKIyBJbnRyb2R1Y3Rpb24KClRoZSAqKnBsb3RMZWFybmVyUHJlZGljdGlvbigpKiogZnVuY3Rpb24gY29uc2lzdHMgb2YgYW4gaW50ZWdyYXRlZCBwcm9jZWR1cmU6CgorIFRyYWluaW5nIGFuZCBjcm9zcy12YWxpZGF0aW9uOiBUaGUgbGVhcm5lciB3aWxsIGJlIHRyYWluZWQgbWFueSB0aW1lcyB1cG9uIDc1JSBvZiB0aGUgb3JpZ2luYWwgZGF0YXNldCBpbiBjbGFzc2lmaWNhdGlvbiBUYXNrLiBGb3IgZWFjaCBpdGVyYXRpb24sIHRyYWluZWQgbW9kZWwgd2lsbCBiZSB0ZXN0ZWQgb24gZWl0aGVyIHRyYWluIHN1YnNldCAoNzUlKSBhbmQgdGVzdCBzdWJzZXQgKHJlbWFuaW5nIDI1JSBvZiBvcmlnaW5hbCBkYXRhc2V0KS4gVGhlIG1vZGVs4oCZcyBwZXJmb3JtYW5jZSAoYnkgZGVmYXVsdDogbWVhbiBtaXNzY2xhc3NpZmljYXRpb24gZXJyb3ItIG1tY2U7IGl0IGNvdWxkIGJlIGN1c3RvbWlzZWQgYnkgdXNlciB0byBpbmNsdWRlIG1vcmUgcGVyZm9ybWFuY2UgbWV0cmljcykgd2lsbCBiZSBhdmVyYWdlZC4gVGhlIGxlYXJuZXLigJlzIG5hbWUgYW5kIGl0cyBjcm9zcy12YWxpZGF0aW9uIHJlc3VsdCB3aWxsIGJlIHJlcG9ydGVkIGFzIHN1YnRpdGxlIG9uIHRoZSBmaW5hbCBncmFwaC4KCisgQSB0d28gZGltZW5zaW9uYWwgZGF0YSBzcGFjZSB3aWxsIGJlIHNldCBmcm9tIFggYW5kIFkgdmFyaWFibGVzIGFzIGludHJvZHVjZWQgYnkgdGhlIOKAmGZlYXR1cmVz4oCZIGFyZ3VtZW50cy4gVGhlbiBhIHNjYXR0ZXIgZG90IHBsb3Qgd2lsbCBiZSBnZW5lcmF0ZWQgYnkgZ2VvbV9wb2ludCgpIGZ1bmN0aW9uIGluIGdncGxvdDIuCgorIFByZWRpY3Rpb24gYm91bmRhcmllcyB3aWxsIGJlIGdlbmVyYXRlZCB1c2luZyBnZW9tX3RpbGUoKSBmdW5jdGlvbiBpbiBnZ3Bsb3QyIHdpdGggZWl0aGVyIHByZWRpY3RlZCBwcm9iYWJpbGl0eSAod2hlbiBhdmFpbGFibGUpIG9yIHByZWRpY3RlZCBjbGFzc2VzLiBXaGVuIHByb2JhYmlsaXRpZXMgYXJlIHVzZWQsIHRoZSBwcmVkaWN0aW9uIHdpbGwgYmUgbGFiZWxsZWQgYnkgY29sb3IgZmlsbCBhbmQgYWxwaGEgaXMgY29kZWQgYnkgcHJvYmFiaWxpdHkgdmFsdWVzLgoKVGhlIGZpbmFsIG91dHB1dCBjb25zaXN0cyBvZiBhIGdncGxvdDIgb2JqZWN0IGFuZCB0aGVyZWZvcmUgY291bGQgYmUgY3VzdG9taXNlZCBieSBzY2FsZV9maWxsX2NvbG9yKCkgb3IgZ2dwbG90MuKAmXMgdGhlbWVzIHNldHRpbmcuCgojIEV4YW1wbGU6IFRoZSBJUklTIGNsYXNzaWZpY2F0aW9uIHRhc2sKSGVyZSBpcyB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBTZXBhbOKAmXMgbGVuZ3RoIGFuZCB3aWR0aCBhbmQgdGhlIHR3byBkaW1lbnNpb25hbCBkaXN0cmlidXRpb24gb2YgaXJpcyBzcGVjaWVzIGluIG91ciBkYXRzZXQ6CmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCgpnZ3Bsb3QoaXJpcyxhZXMoeD1TZXBhbC5MZW5ndGgseT1TZXBhbC5XaWR0aCkpK3N0YXRfZGVuc2l0eTJkKGdlb209InBvbHlnb24iLGFlcyhmaWxsPWlyaXMkU3BlY2llcyxhbHBoYSA9IC4ubGV2ZWwuLikpK2dlb21fcG9pbnQoYWVzKHNoYXBlPVNwZWNpZXMpLGNvbG9yPSJibGFjayIsc2l6ZT0yKSt0aGVtZV9idygpK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjZmYwMDYxIiwiIzExYTZmYyIsIiNmZmFlMDAiKSkKYGBgClRoZSBzYW1lIGFuYWx5c2lzIGNvdWxkIGJlIGRvbmUgZm9yIFBldGFs4oCZcyBsZW5ndGggYW5kIHdpZHRoOgpgYGB7cn0KZ2dwbG90KGlyaXMsYWVzKHg9UGV0YWwuTGVuZ3RoLHk9UGV0YWwuV2lkdGgpKStzdGF0X2RlbnNpdHkyZChnZW9tPSJwb2x5Z29uIixhZXMoZmlsbD1pcmlzJFNwZWNpZXMsYWxwaGEgPSAuLmxldmVsLi4pKStnZW9tX3BvaW50KGFlcyhzaGFwZT1TcGVjaWVzKSxjb2xvcj0iYmxhY2siLHNpemU9MikrdGhlbWVfYncoKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2ZmMDA2MSIsIiMxMWE2ZmMiLCIjZmZhZTAwIikpCmBgYAoKQXMgdXN1YWwsIHdlIHdpbGwgc2V0IGEgY2xhc3NpZmljYXRpb24gdGFzayBpbiBtbHIgdGhlbiBpbnRyb2R1Y2Ugc29tZSBsZWFybmVycwpgYGB7cn0KI01ha2UgYSBtdWx0aWNsYXNzIGNsYXNzaWZpY2F0aW9uIHRhc2sgaW4gbWxyCgpsaWJyYXJ5KG1scikKCnRhc2tpcmlzPW1ha2VDbGFzc2lmVGFzayhpZD0iaXJpcyIsZGF0YT1pcmlzLHRhcmdldD0iU3BlY2llcyIpCgojIE1ha2luZyA3IGRpZmZlcmVudCBMZWFybmVycyAoYWxnb3JpdGhtKQoKbGVhcm5lckNBUlQ9bWFrZUxlYXJuZXIoaWQ9IkNBUlQiLCJjbGFzc2lmLnJwYXJ0IiwgcHJlZGljdC50eXBlID0gInByb2IiKQoKbGVhcm5lclJGPW1ha2VMZWFybmVyKGlkPSJSRiIsImNsYXNzaWYucmFuZG9tRm9yZXN0U1JDIiwgcHJlZGljdC50eXBlID0gInByb2IiKQoKbGVhcm5lclNWTT1tYWtlTGVhcm5lcihpZD0iU1ZNIiwiY2xhc3NpZi5zdm0iLCBwcmVkaWN0LnR5cGUgPSAicHJvYiIpCgpsZWFybmVyR0JNPW1ha2VMZWFybmVyKGlkPSJHQk0iLCJjbGFzc2lmLmdibSIsIHByZWRpY3QudHlwZSA9ICJwcm9iIikKCmxlYXJuZXJHTE1OPW1ha2VMZWFybmVyKGlkPSJFbGFzdGljbmV0IiwiY2xhc3NpZi5nbG1uZXQiLCBwcmVkaWN0LnR5cGUgPSAicHJvYiIpCgpsZWFybmVyS05OPW1ha2VMZWFybmVyKGlkPSJLTk4iLCJjbGFzc2lmLmtubiIpCgpsZWFybmVyTERBPW1ha2VMZWFybmVyKGlkPSJMREEiLCJjbGFzc2lmLmxkYSIsIHByZWRpY3QudHlwZSA9ICJwcm9iIikKYGBgCgojIFRoZSBzeW50YXggb2YgcGxvdExlYXJuZXJQcmVkaWN0aW9uKCApIGZ1bmN0aW9uCgoqKiBwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lciwgdGFzaywgZmVhdHVyZXMgPSBOVUxMLCBtZWFzdXJlcywgY3YgPSAxMEwsIOKApiwgZ3JpZHNpemUsIHBvaW50c2l6ZSA9IDIsIHByb2IuYWxwaGEgPSBUUlVFLCBzZS5iYW5kID0gVFJVRSwgZXJyLmNvbCA94oCdd2hpdGXigJwsIGdyZXlzY2FsZSA9IEZBTFNFKSAqKgoKV2hlcmU6CgorIGxlYXJuZXIgaXMgb2JqZWN04oCZcyBuYW1lIGZvciBsZWFybmVyIHRhc2sgaXMgdGhlIG9iamVjdCBuYW1lIGZvciB0YXNrCgorIGZlYXR1cmVzIGFyZ3VtZW50IDogdXAgdG8gMiBmZWF0dXJlcyBjb3VsZCBiZSBpbnRyb2R1Y2VkIGhlcmUuIEJ5IGRlZmF1bHQgdGhlIGZpcnN0IDIgZmVhdHVyZXMgYXJlIHVzZWQKCisgbWVhc3VyZXMgaW5kaWNhdGUgUGVyZm9ybWFuY2UgbWVhc3VyZShzKSB0byBldmFsdWF0ZS4gRGVmYXVsdCBpcyB0aGUgZGVmYXVsdCBtZWFzdXJlIGZvciB0aGUgdGFzawoKKyBjdiBmb3Igc2V0dGluZyB0aGUgY3Jvc3MtdmFsaWRhdGlvbiBhbmQgcmVwb3J0aW5nIGl0cyByZXN1bHQgYXMgcGxvdCB0aXRsZS4gTnVtYmVyIG9mIGZvbGRzLiBjdj0wIG1lYW5zIG5vIENWLiBEZWZhdWx0IGlzIDEwLgoKKyBncmlkc2l6ZSBpcyB0aGUgZ3JpZCByZXNvbHV0aW9uIHBlciBheGlzIGZvciBiYWNrZ3JvdW5kIHByZWRpY3Rpb25zLiBEZWZhdWx0IGlzIDEwMCBmb3IgMkQuCgorIFBvaW50c2l6ZSBmb3IgZ2dwbG90MiBnZW9tX3BvaW50IGZvciBkYXRhIHBvaW50cy4gRGVmYXVsdCBpcyAyLgoKKyBwcm9iLmFscGhhIGlzIGEgbG9naWNhbCBhcmd1bWVudCwgZm9yIHNldHRpbmcgYWxwaGEgdmFsdWUgb2YgYmFja2dyb3VuZCB0byBwcm9iYWJpbGl0eSBmb3IgcHJlZGljdGVkIGNsYXNzPyBBbGxvd3MgdmlzdWFsaXphdGlvbiBvZiDigJxjb25maWRlbmNl4oCdIGZvciBwcmVkaWN0aW9uLiBJZiBub3QsIG9ubHkgYSBjb25zdGFudCBjb2xvciBpcyBkaXNwbGF5ZWQgaW4gdGhlIGJhY2tncm91bmQgZm9yIHRoZSBwcmVkaWN0ZWQgbGFiZWwuIERlZmF1bHQgaXMgVFJVRS4KCisgc2UuYmFuZDogRm9yIHJlZ3Jlc3Npb24gaW4gMUQ6IFNob3cgYmFuZCBmb3Igc3RhbmRhcmQgZXJyb3IgZXN0aW1hdGlvbj8gRGVmYXVsdCBpcyBUUlVFLgoKKyBlcnIuY29sOiBGb3IgY2xhc3NpZmljYXRpb24sIENvbG9yIG9mIG1pc2NsYXNzaWZpZWQgZGF0YSBwb2ludHMuIERlZmF1bHQgaXMg4oCcd2hpdGXigJ0KCisgZ3JleXNjYWxlIGlzIGEgbG9naWNhbCBhcmd1bWVudDogU2hvdWxkIHRoZSBwbG90IGJlIGdyZXlzY2FsZSBjb21wbGV0ZWx5PyBEZWZhdWx0IGlzIEZBTFNFCgoqKkNBUlQgYWxnb3JpdGhtKioKYGBge3J9CnBsb3RMZWFybmVyUHJlZGljdGlvbihsZWFybmVyQ0FSVCx0YXNraXJpcyxmZWF0dXJlcz1jKCJTZXBhbC5MZW5ndGgiLCJTZXBhbC5XaWR0aCIpLGN2PTEwMEwsZ3JpZHNpemU9MTAwKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2ZmMDA2MSIsIiMxMWE2ZmMiLCIjZmZhZTAwIikpK3RoZW1lX2J3KCkKYGBgCmBgYHtyfQpwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lckNBUlQsdGFza2lyaXMsZmVhdHVyZXM9YygiUGV0YWwuTGVuZ3RoIiwiUGV0YWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYAoqKiBTdXBwb3J0IHZlY3RvciBtYWNoaW5lIGFsZ29yaXRobSAqKgpgYGB7cn0KcGxvdExlYXJuZXJQcmVkaWN0aW9uKGxlYXJuZXJTVk0sdGFza2lyaXMsZmVhdHVyZXM9YygiU2VwYWwuTGVuZ3RoIiwiU2VwYWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYApgYGB7cn0KcGxvdExlYXJuZXJQcmVkaWN0aW9uKGxlYXJuZXJTVk0sdGFza2lyaXMsZmVhdHVyZXM9YygiUGV0YWwuTGVuZ3RoIiwiUGV0YWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYAoqKiBHcmFkaWVudCBib29zdGluZyBtYWNoaW5lIGFsZ29yaXRobSAqKgpgYGB7cn0KcGxvdExlYXJuZXJQcmVkaWN0aW9uKGxlYXJuZXJHQk0sdGFza2lyaXMsZmVhdHVyZXM9YygiU2VwYWwuTGVuZ3RoIiwiU2VwYWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYAoKYGBge3J9CnBsb3RMZWFybmVyUHJlZGljdGlvbihsZWFybmVyR0JNLHRhc2tpcmlzLGZlYXR1cmVzPWMoIlBldGFsLkxlbmd0aCIsIlBldGFsLldpZHRoIiksY3Y9MTAwTCxncmlkc2l6ZT0xMDApK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjZmYwMDYxIiwiIzExYTZmYyIsIiNmZmFlMDAiKSkrdGhlbWVfYncoKQpgYGAKKipFbGFzdGljIG5ldCAobG9naXN0aWMpIGFsZ29yaXRobSoqCmBgYHtyfQpwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lckdMTU4sdGFza2lyaXMsZmVhdHVyZXM9YygiU2VwYWwuTGVuZ3RoIiwiU2VwYWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYApgYGB7cn0KcGxvdExlYXJuZXJQcmVkaWN0aW9uKGxlYXJuZXJHTE1OLHRhc2tpcmlzLGZlYXR1cmVzPWMoIlBldGFsLkxlbmd0aCIsIlBldGFsLldpZHRoIiksY3Y9MTAwTCxncmlkc2l6ZT0xMDApK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjZmYwMDYxIiwiIzExYTZmYyIsIiNmZmFlMDAiKSkrdGhlbWVfYncoKQpgYGAKKiogS05OIGFsZ29yaXRobSoqCmBgYHtyfQpwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lcktOTix0YXNraXJpcyxmZWF0dXJlcz1jKCJTZXBhbC5MZW5ndGgiLCJTZXBhbC5XaWR0aCIpLGN2PTEwMEwsZ3JpZHNpemU9MTAwKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2ZmMDA2MSIsIiMxMWE2ZmMiLCIjZmZhZTAwIikpK3RoZW1lX2J3KCkKYGBgCmBgYHtyfQpwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lcktOTix0YXNraXJpcyxmZWF0dXJlcz1jKCJQZXRhbC5MZW5ndGgiLCJQZXRhbC5XaWR0aCIpLGN2PTEwMEwsZ3JpZHNpemU9MTAwKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI2ZmMDA2MSIsIiMxMWE2ZmMiLCIjZmZhZTAwIikpK3RoZW1lX2J3KCkKYGBgCgoqKkxEQSBhbGdvcml0aG0qKgpgYGB7cn0KcGxvdExlYXJuZXJQcmVkaWN0aW9uKGxlYXJuZXJMREEsdGFza2lyaXMsZmVhdHVyZXM9YygiU2VwYWwuTGVuZ3RoIiwiU2VwYWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYAoKYGBge3J9CnBsb3RMZWFybmVyUHJlZGljdGlvbihsZWFybmVyTERBLHRhc2tpcmlzLGZlYXR1cmVzPWMoIlBldGFsLkxlbmd0aCIsIlBldGFsLldpZHRoIiksY3Y9MTAwTCxncmlkc2l6ZT0xMDApK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjZmYwMDYxIiwiIzExYTZmYyIsIiNmZmFlMDAiKSkrdGhlbWVfYncoKQpgYGAKKipSYW5kb20gRm9yZXN0IGFsZ29yaXRobSoqCmBgYHtyfQpwbG90TGVhcm5lclByZWRpY3Rpb24obGVhcm5lclJGLHRhc2tpcmlzLGZlYXR1cmVzPWMoIlNlcGFsLkxlbmd0aCIsIlNlcGFsLldpZHRoIiksY3Y9MTAwTCxncmlkc2l6ZT0xMDApK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjZmYwMDYxIiwiIzExYTZmYyIsIiNmZmFlMDAiKSkrdGhlbWVfYncoKQpgYGAKYGBge3J9CnBsb3RMZWFybmVyUHJlZGljdGlvbihsZWFybmVyUkYsdGFza2lyaXMsZmVhdHVyZXM9YygiUGV0YWwuTGVuZ3RoIiwiUGV0YWwuV2lkdGgiKSxjdj0xMDBMLGdyaWRzaXplPTEwMCkrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNmZjAwNjEiLCIjMTFhNmZjIiwiI2ZmYWUwMCIpKSt0aGVtZV9idygpCmBgYAoKIyBDb25jbHVzaW9uCioqcGxvdExlYXJuZXJQcmVkaWN0aW9uKCkqKiBpcyBhIGhpZGRlbiB0b29sIGluIG1sciBwYWNrYWdlLiBUaGlzIHVzZWZ1bCBmdW5jdGlvbiBhbGxvd3MgdG8gZ2VuZXJhdGUgYmVhdXRpZnVsIHBsb3RzIGZvciB0aGUgaWxsdXN0cmF0aW9uIHB1cnBvc2UuIFRoZXNlIHBsb3RzIHByb3ZpZGUgbWFueSBpbmZvcm1hdGlvbiwgc3VjaCBhczoKCisgQSB2aXN1YWwgcGVyY2VwdGlvbiBvZiBtb2RlbOKAmXMgcGVyZm9ybWFuY2U6IGl0cyBhYmlsaXR5IHRvIGNsYXNzaWZ5IHRoZSBpbnN0YW5jZXMgaW50byB0d28gb3IgbW9yZSBjbGFzc2VzLCB0aGUgY29ycmVjdCBjbGFzc2lmaWNhdGlvbiBhbmQgZXJyb3IgcmF0ZXMuCgorIEEgdmlzdWFsIHByZXNlbnRhdGlvbiBvZiB0aGUgdW5kZXJseWluZyBtZWNoYW5pc20gb2YgdGhlIG1vZGVsLCB2aWEgdGhlIHByZWRpY3Rpb24gYm91bmRhcmllcwoKKyBBc3NvY2F0aW9uIGJldHdlZW4gdHdvIGZlYXR1cmVzIGFuZCB0aGVpciBjb250cmlidXRpb24gdG8gbW9kZWzigJlzIHByZWRpY3Rpb24uCgorIE51bWVyaWNhbCByZXN1bHQgb2YgY3Jvc3MtdmFsaWRhdGlvbjogYXZlcmFnZWQgbW9kZWzigJlzIHBlcmZvcm1hbmNlIG1ldHJpY3MKCg==