├── .gitignore ├── Materials ├── Data │ ├── car_data.RData │ └── okc.RData ├── Extra_Slides.R ├── Extra_Slides.html ├── Extra_Slides.pdf ├── Extra_Slides_files │ └── figure-html │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ └── coef-plots-2-show-1.svg ├── Part_1_Getting_Started.R ├── Part_1_Getting_Started.html ├── Part_1_Getting_Started.pdf ├── Part_1_Getting_Started_files │ └── figure-html │ │ ├── ggplot - example - disp-1.svg │ │ └── ggplot-example-disp-1.svg ├── Part_2_Basic_Principals.R ├── Part_2_Basic_Principals.html ├── Part_2_Basic_Principals.pdf ├── Part_2_Basic_Principals_files │ └── figure-html │ │ ├── ames-knn-1.svg │ │ ├── ames-knn-indiv-1.svg │ │ ├── ames-split-dists-dist-1.svg │ │ ├── boot-plot-1.svg │ │ ├── cv-corr-1.svg │ │ ├── cv-plot-1.svg │ │ ├── two-class-2panel-1.svg │ │ └── two-class-overfit-1.svg ├── Part_3_Feature_Engineering.R ├── Part_3_Feature_Engineering.html ├── Part_3_Feature_Engineering.pdf ├── Part_3_Feature_Engineering_files │ └── figure-html │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid8414f540ecdd4c4cbc8f6544838eea13.js │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js │ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js │ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ │ ├── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js │ │ ├── year-built-ac-plot-1.svg │ │ └── year-built-plot-1.svg ├── Part_4_Regression_Modeling.R ├── Part_4_Regression_Modeling.html ├── Part_4_Regression_Modeling.pdf ├── Part_4_Regression_Modeling_files │ └── figure-html │ │ ├── ames-glmn-enhance-1.svg │ │ ├── ames-glmn-imp-1.svg │ │ ├── ames-glmn-op-1.svg │ │ ├── ames-glmn-rmse-plot-1.svg │ │ ├── ames-mars-imp-1.svg │ │ ├── ames-mars-op-1.svg │ │ ├── ames-mars-rmse-plot-1.svg │ │ ├── bagged-op-1.svg │ │ ├── bayes-1.png │ │ ├── bayes-2.png │ │ ├── bayes-contrast-1.png │ │ ├── bayes-contrast-plot-1.svg │ │ ├── car-bag-mars-op-1.svg │ │ ├── car-glmn-imp-1.svg │ │ ├── car-glmn-op-1.svg │ │ ├── car-glmn-rmse-plot-1.svg │ │ ├── car-mars-imp-1.svg │ │ ├── car-mars-op-1.svg │ │ ├── car-mars-rmse-plot-1.svg │ │ ├── mars-2d-1.svg │ │ ├── mars-bag-final-1.svg │ │ ├── mars-cuts-1.svg │ │ ├── mars-sim-1.png │ │ ├── mars-sim-1.svg │ │ ├── mars-sim-final-1.svg │ │ ├── mars-sim-fit-1.svg │ │ ├── par-plot-1.svg │ │ ├── reg-path-1.svg │ │ ├── test-op-1.svg │ │ └── tp-post-plot-1.svg ├── Part_5_Classification.R ├── Part_5_Classification.html ├── Part_5_Classification.pdf ├── Part_5_Classification_files │ └── figure-html │ │ ├── bag-imp-1.svg │ │ ├── bag-roc-plot-1.svg │ │ ├── boost-plot-1.svg │ │ ├── boot-cart-1-1.png │ │ ├── boot-cart-1-1.svg │ │ ├── boot-cart-2-1.png │ │ ├── boot-cart-2-1.svg │ │ ├── boot-cart-3-1.png │ │ ├── boot-cart-3-1.svg │ │ ├── calib-hist-1.svg │ │ ├── calib-roc-1.svg │ │ ├── cart-age-split-1.svg │ │ ├── cart-imp-1.svg │ │ ├── cart-orientation-split-1.svg │ │ ├── cart-plot-1.png │ │ ├── cart-plot-1.svg │ │ ├── cart-roc-plot-1.svg │ │ ├── cart-split-1-1.svg │ │ ├── cart-split-2-1.svg │ │ ├── nb-cat-1.svg │ │ ├── nb-dens-1.svg │ │ ├── nb-indep-1.svg │ │ ├── nb-numeric-1.svg │ │ ├── nb-plot-1.svg │ │ ├── nb-roc-plot-1.svg │ │ ├── nb-shrink-1.svg │ │ ├── roc-plot-1.svg │ │ ├── rs-contrast-plot-1.svg │ │ ├── test-probs-1.svg │ │ ├── test-roc-1.svg │ │ ├── u-shape-1.svg │ │ └── xgb-roc-plot-1.svg ├── RData │ ├── cart_bag.RData │ ├── cart_mod.RData │ ├── glmn_mod.RData │ ├── mars_gcv_bag.RData │ ├── mars_gcv_mod.RData │ ├── mars_mod.RData │ └── nb_mod.RData ├── Template.Rmd ├── Template.html ├── Template_files │ └── figure-html │ │ ├── example-plot-1.svg │ │ └── example-plot-again-1.svg ├── fonts_mtheme_max.css ├── images │ ├── broom.png │ ├── dplyr.png │ ├── ggplot2.png │ ├── intro-process-1.svg │ ├── nope.png │ ├── nopestradomis.jpg │ ├── purrr.png │ ├── readr.png │ ├── recipes.png │ ├── review-resamp-cache.png │ ├── rsample.png │ ├── tidyposterior.png │ └── yardstick.png ├── libs │ ├── DiagrammeR-styles-0.2 │ │ └── styles.css │ ├── Proj4Leaflet-0.7.2 │ │ ├── proj4-compressed.js │ │ ├── proj4.js │ │ └── proj4leaflet.js │ ├── d3-4.3.0 │ │ └── d3.min.js │ ├── d3-lasso-0.0.5 │ │ ├── d3-lasso.min.js │ │ └── lasso.js │ ├── ggiraph-0.2.0 │ │ └── styles.css │ ├── ggiraph-binding-0.4.1 │ │ └── ggiraph.js │ ├── grViz-binding-0.9.0 │ │ └── grViz.js │ ├── grViz-binding-0.9.2 │ │ └── grViz.js │ ├── htmlwidgets-0.8 │ │ └── htmlwidgets.js │ ├── htmlwidgets-0.9 │ │ └── htmlwidgets.js │ ├── htmlwidgets-1.0 │ │ └── htmlwidgets.js │ ├── jquery-1.12.4 │ │ ├── jquery.js │ │ └── jquery.min.js │ ├── leaflet-0.7.7 │ │ ├── images │ │ │ ├── 1px.png │ │ │ ├── layers-2x.png │ │ │ ├── layers.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── marker-icon.png │ │ │ └── marker-shadow.png │ │ ├── leaflet-src.js │ │ ├── leaflet.css │ │ └── leaflet.js │ ├── leaflet-binding-1.1.0 │ │ └── leaflet.js │ ├── leaflet-label-0.2.2 │ │ ├── images │ │ │ └── death.png │ │ ├── leaflet.label-src.js │ │ ├── leaflet.label.css │ │ └── leaflet.label.js │ ├── leaflet-providers-1.0.27 │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── bower.json │ │ ├── css │ │ │ ├── gh-fork-ribbon.css │ │ │ └── gh-fork-ribbon.ie.css │ │ ├── leaflet-providers.js │ │ ├── license.md │ │ ├── package.json │ │ └── providers.json │ ├── leaflet-providers-plugin-1.1.0 │ │ └── leaflet-providers-plugin.js │ ├── leafletfix-1.0.0 │ │ └── leafletfix.css │ ├── remark-css-0.0.1 │ │ └── example.css │ ├── uid8414f540ecdd4c4cbc8f6544838eea13-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid8414f540ecdd4c4cbc8f6544838eea13.js │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js │ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js │ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ │ └── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js │ ├── uid88417f800ebd4b67adc5397e0356b276-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ ├── uid88e8e777f3714197936848c6636be3b1-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js │ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ ├── uida86b4bcdd21d43799fdb0f0e380e3861-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js │ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js │ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ ├── uidd3aa604fdfff44999bd703dd04674170-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ └── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ ├── uidd99cbc273a584e809be0ff8ad53817fa-0.0.1 │ │ ├── ames-hood-1.svg │ │ ├── bivariate-plot-inverse-1.svg │ │ ├── bivariate-plot-natural-1.svg │ │ ├── bivariate-plot-pca-1.svg │ │ ├── bivariate-rec-orig-1.svg │ │ ├── coef-plots-1-show-1.svg │ │ ├── coef-plots-2-show-1.svg │ │ ├── latitude-1.svg │ │ ├── lm-obs-pred-show-1.svg │ │ ├── longitude-1.svg │ │ ├── scripts_uid88417f800ebd4b67adc5397e0356b276.js │ │ ├── scripts_uid88e8e777f3714197936848c6636be3b1.js │ │ ├── scripts_uida86b4bcdd21d43799fdb0f0e380e3861.js │ │ ├── scripts_uidd3aa604fdfff44999bd703dd04674170.js │ │ └── scripts_uidd99cbc273a584e809be0ff8ad53817fa.js │ └── viz-0.3 │ │ └── viz.js ├── macros.js └── mtheme_max.css ├── Preparations └── installs.R └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Materials/Data/car_data.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Data/car_data.RData -------------------------------------------------------------------------------- /Materials/Data/okc.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Data/okc.RData -------------------------------------------------------------------------------- /Materials/Extra_Slides.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | library(ggplot2) 6 | 7 | thm <- theme_bw() + 8 | theme( 9 | panel.background = element_rect(fill = "transparent", colour = NA), 10 | plot.background = element_rect(fill = "transparent", colour = NA), 11 | legend.position = "top", 12 | legend.background = element_rect(fill = "transparent", colour = NA), 13 | legend.key = element_rect(fill = "transparent", colour = NA) 14 | ) 15 | theme_set(thm) 16 | 17 | 18 | # Create Data for PCA slides 19 | library(caret) 20 | data(segmentationData) 21 | 22 | segmentationData <- segmentationData[, c("EqSphereAreaCh1", "PerimCh1", "Class", "Case")] 23 | names(segmentationData)[1:2] <- paste0("Predictor", LETTERS[1:2]) 24 | 25 | segmentationData$Class <- factor(ifelse(segmentationData$Class == "PS", "One", "Two")) 26 | 27 | bivariate_data_train <- subset(segmentationData, Case == "Train") 28 | bivariate_data_test <- subset(segmentationData, Case == "Test") 29 | 30 | bivariate_data_train$Case <- NULL 31 | bivariate_data_test$Case <- NULL 32 | 33 | # Slide 4 34 | 35 | library(recipes) 36 | 37 | bivariate_rec <- recipe(Class ~ PredictorA + PredictorB, 38 | data = bivariate_data_train) %>% 39 | step_BoxCox(all_predictors()) 40 | 41 | bivariate_rec <- prep(bivariate_rec, training = bivariate_data_train, verbose = FALSE) 42 | 43 | inverse_test <- bake(bivariate_rec, newdata = bivariate_data_test, everything()) 44 | 45 | # Slide 8 46 | 47 | ggplot(inverse_test, 48 | aes(x = 1/PredictorA, 49 | y = 1/PredictorB, 50 | color = Class)) + 51 | geom_point(alpha = .3, cex = 1.5) + 52 | theme(legend.position = "top") + 53 | xlab("1/A") + ylab("1/B") 54 | 55 | # Slide 9 56 | 57 | bivariate_pca <- 58 | recipe(Class ~ PredictorA + PredictorB, data = bivariate_data_train) %>% 59 | step_BoxCox(all_predictors()) %>% 60 | step_center(all_predictors()) %>% 61 | step_scale(all_predictors()) %>% 62 | step_pca(all_predictors()) %>% 63 | prep(training = bivariate_data_test, verbose = FALSE) 64 | 65 | pca_test <- bake(bivariate_pca, newdata = bivariate_data_test) 66 | 67 | # Put components axes on the same range 68 | pca_rng <- extendrange(c(pca_test$PC1, pca_test$PC2)) 69 | 70 | ggplot(pca_test, aes(x = PC1, y = PC2, color = Class)) + 71 | geom_point(alpha = .2, cex = 1.5) + 72 | theme(legend.position = "top") + 73 | xlim(pca_rng) + ylim(pca_rng) + 74 | xlab("Principal Component 1") + ylab("Principal Component 2") 75 | 76 | 77 | # Data for Remaining Slides 78 | 79 | library(AmesHousing) 80 | ames <- make_ames() 81 | nrow(ames) 82 | 83 | library(rsample) 84 | 85 | # Make sure that you get the same random numbers 86 | set.seed(4595) 87 | data_split <- initial_split(ames, strata = "Sale_Price") 88 | 89 | ames_train <- training(data_split) 90 | ames_test <- testing(data_split) 91 | 92 | set.seed(2453) 93 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price") 94 | 95 | lin_coords <- recipe(Sale_Price ~ Bldg_Type + Neighborhood + Year_Built + 96 | Gr_Liv_Area + Full_Bath + Year_Sold + Lot_Area + 97 | Central_Air + Longitude + Latitude, 98 | data = ames_train) %>% 99 | step_log(Sale_Price, base = 10) %>% 100 | step_YeoJohnson(Lot_Area, Gr_Liv_Area) %>% 101 | step_other(Neighborhood, threshold = 0.05) %>% 102 | step_dummy(all_nominal()) %>% 103 | step_interact(~ starts_with("Central_Air"):Year_Built) 104 | 105 | coords <- lin_coords %>% 106 | step_bs(Longitude, Latitude, options = list(df = 5)) 107 | 108 | library(purrr) 109 | cv_splits <- cv_splits %>% 110 | mutate(coords = map(splits, prepper, recipe = coords, retain = TRUE)) 111 | 112 | lm_fit_rec <- function(rec_obj, ...) 113 | lm(..., data = juice(rec_obj)) 114 | 115 | cv_splits <- cv_splits %>% 116 | mutate(fits = map(coords, lm_fit_rec, Sale_Price ~ .)) 117 | 118 | # Slide 12 119 | 120 | coef_summary <- map(cv_splits$fits, tidy) %>% bind_rows 121 | head(coef_summary) 122 | 123 | # Slide 13 124 | 125 | num_pred <- c("Year_Built", "Gr_Liv_Area", 126 | "Full_Bath", "Year_Sold", 127 | "Lot_Area") 128 | z_lim <- qnorm(c(0.025, 0.975)) 129 | coef_summary %>% 130 | filter(term %in% num_pred) %>% 131 | ggplot(aes(x = term, y = statistic)) + 132 | geom_hline(yintercept = z_lim, 133 | lty = 2, col = "red") + 134 | geom_jitter(width = .1, alpha = .4, cex = 2) + 135 | coord_flip() + 136 | xlab("") 137 | 138 | # Slide 14 139 | 140 | coef_summary %>% 141 | filter(grepl("^Neighborhood", term)) %>% 142 | ggplot(aes(x = term, y = statistic)) + 143 | geom_hline( 144 | yintercept = z_lim, 145 | lty = 2, 146 | col = "red" 147 | ) + 148 | geom_jitter( 149 | width = .1, 150 | alpha = .4, 151 | cex = 2 152 | ) + 153 | coord_flip() + 154 | xlab("") + 155 | ylab( 156 | paste("Difference from", 157 | levels(ames_test$Neighborhood)[1]) 158 | ) 159 | 160 | # Slide 17 161 | 162 | library(yardstick) 163 | data(solubility_test) 164 | str(solubility_test, nchar.max = 70) 165 | 166 | # Slide 18 167 | 168 | rmse(solubility_test, truth = solubility, estimate = prediction) 169 | 170 | # Slide 19 171 | 172 | rsq(solubility_test, truth = solubility, estimate = prediction) 173 | 174 | # Slide 20 175 | 176 | library(dplyr) 177 | set.seed(3545) 178 | solubility_test <- solubility_test %>% mutate(noise = sample(prediction)) 179 | 180 | rsq(solubility_test, truth = solubility, estimate = noise) 181 | rsq_trad(solubility_test, truth = solubility, estimate = noise) 182 | 183 | -------------------------------------------------------------------------------- /Materials/Extra_Slides.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Applied Machine Learning - Extra Slides 5 | 6 | 7 | 8 | 9 | 10 | 11 | 431 | 432 | 439 | 440 | 447 | 448 | 458 | 459 | 460 | -------------------------------------------------------------------------------- /Materials/Extra_Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Extra_Slides.pdf -------------------------------------------------------------------------------- /Materials/Part_1_Getting_Started.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | 6 | library(ggplot2) 7 | 8 | thm <- theme_bw() + 9 | theme( 10 | panel.background = element_rect(fill = "transparent", colour = NA), 11 | plot.background = element_rect(fill = "transparent", colour = NA), 12 | legend.position = "top", 13 | legend.background = element_rect(fill = "transparent", colour = NA), 14 | legend.key = element_rect(fill = "transparent", colour = NA) 15 | ) 16 | theme_set(thm) 17 | 18 | # Slide 12 19 | 20 | library(tidyverse) 21 | 22 | ames <- 23 | read_delim("http://bit.ly/2whgsQM", delim = "\t") %>% 24 | rename_at(vars(contains(' ')), funs(gsub(' ', '_', .))) %>% 25 | rename(Sale_Price = SalePrice) %>% 26 | filter(!is.na(Electrical)) %>% 27 | select(-Order, -PID, -Garage_Yr_Blt) 28 | 29 | ames %>% 30 | group_by(Alley) %>% 31 | summarize(mean_price = mean(Sale_Price/1000), 32 | n = sum(!is.na(Sale_Price))) 33 | 34 | # Slide 13 35 | 36 | ggplot(ames, 37 | aes(x = Garage_Type, 38 | y = Sale_Price)) + 39 | geom_violin() + 40 | coord_trans(y = "log10") + 41 | xlab("Garage Type") + 42 | ylab("Sale Price") 43 | 44 | 45 | 46 | # Slide 14 47 | 48 | library(purrr) 49 | 50 | # summarize via purrr::map 51 | by_alley <- split(ames, ames$Alley) 52 | is_list(by_alley) 53 | 54 | map(by_alley, nrow) 55 | 56 | # or better yet: 57 | map_int(by_alley, nrow) 58 | 59 | 60 | # works on non-list vectors too 61 | ames %>% 62 | mutate(Sale_Price = Sale_Price %>% 63 | map_dbl(function(x) x / 1000)) %>% 64 | select(Sale_Price, Yr_Sold) %>% 65 | head(4) 66 | 67 | # Slide 15 68 | 69 | library(AmesHousing) 70 | ames <- make_ames() 71 | 72 | -------------------------------------------------------------------------------- /Materials/Part_1_Getting_Started.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_1_Getting_Started.pdf -------------------------------------------------------------------------------- /Materials/Part_2_Basic_Principals.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | library(ggplot2) 6 | 7 | thm <- theme_bw() + 8 | theme( 9 | panel.background = element_rect(fill = "transparent", colour = NA), 10 | plot.background = element_rect(fill = "transparent", colour = NA), 11 | legend.position = "top", 12 | legend.background = element_rect(fill = "transparent", colour = NA), 13 | legend.key = element_rect(fill = "transparent", colour = NA) 14 | ) 15 | theme_set(thm) 16 | 17 | # Slide 10 18 | 19 | library(AmesHousing) 20 | ames <- make_ames() 21 | nrow(ames) 22 | 23 | library(rsample) 24 | 25 | # Make sure that you get the same random numbers 26 | set.seed(4595) 27 | data_split <- initial_split(ames, strata = "Sale_Price") 28 | 29 | ames_train <- training(data_split) 30 | ames_test <- testing(data_split) 31 | 32 | nrow(ames_train)/nrow(ames) 33 | 34 | # Slide 11 35 | 36 | ggplot(ames_train, aes(x = Sale_Price)) + 37 | geom_line(stat = "density", trim = TRUE) + 38 | geom_line(data = ames_test, 39 | stat = "density", 40 | trim = TRUE, col = "red") 41 | 42 | # Slide 15 43 | 44 | simple_lm <- lm(log10(Sale_Price) ~ Longitude + Latitude, data = ames_train) 45 | 46 | library(broom) 47 | simple_lm_values <- augment(simple_lm) 48 | names(simple_lm_values) 49 | 50 | # Slide 19 51 | 52 | summary(simple_lm) 53 | 54 | # Slide 28 55 | 56 | library(rsample) 57 | set.seed(2453) 58 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price") 59 | cv_splits 60 | 61 | # Slide 29 62 | 63 | # The `split` objects contain the information about the sample sizes 64 | cv_splits$splits[[1]] 65 | 66 | # Use the `analysis` and `assessment` functions to get the data 67 | analysis(cv_splits$splits[[1]]) %>% dim() 68 | assessment(cv_splits$splits[[1]]) %>% dim() 69 | 70 | # Slide 30 71 | 72 | library(yardstick) 73 | library(dplyr) 74 | 75 | lm_fit <- function(data_split, ...) 76 | lm(..., data = analysis(data_split)) 77 | 78 | # A formula is also needed for each model: 79 | form <- as.formula( 80 | log10(Sale_Price) ~ Longitude + Latitude 81 | ) 82 | 83 | model_perf <- function(data_split, mod_obj) { 84 | vars <- rsample::form_pred(mod_obj$terms) 85 | assess_dat <- assessment(data_split) %>% 86 | select(!!!vars, Sale_Price) %>% 87 | mutate( 88 | pred = predict( 89 | mod_obj, 90 | newdata = assessment(data_split) 91 | ), 92 | Sale_Price = log10(Sale_Price) 93 | ) 94 | 95 | rmse <- assess_dat %>% 96 | rmse(truth = Sale_Price, estimate = pred) 97 | rsq <- assess_dat %>% 98 | rsq(truth = Sale_Price, estimate = pred) 99 | data.frame(rmse = rmse, rsq = rsq) 100 | } 101 | 102 | # Slide 31 103 | 104 | library(purrr) 105 | cv_splits <- cv_splits %>% 106 | mutate(lm_mod = map(splits, lm_fit, formula = form)) 107 | cv_splits 108 | 109 | # Slide 32 110 | 111 | # map2 can be used to move over two objects of equal length 112 | lm_res <- map2_df(cv_splits$splits, cv_splits$lm_mod, model_perf) %>% 113 | dplyr::rename(rmse_simple = rmse, rsq_simple = rsq) 114 | head(lm_res, 3) 115 | 116 | ## Merge in results: 117 | cv_splits <- cv_splits %>% bind_cols(lm_res) 118 | 119 | ## Rename the columns and compute the resampling estimates: 120 | cv_splits %>% select(rmse_simple, rsq_simple) %>% colMeans 121 | 122 | # Slide 34 123 | 124 | get_assessment <- function(splits, model) 125 | augment(model, newdata = assessment(splits)) %>% 126 | mutate(.resid = log10(Sale_Price) - .fitted) 127 | 128 | holdout_results <- map2_df(cv_splits$splits, cv_splits$lm_mod, get_assessment) 129 | holdout_results %>% dim() 130 | ames_train %>% dim() 131 | 132 | # Slide 39 133 | 134 | library(caret) 135 | 136 | knn_train_mod <- knnreg(log10(Sale_Price) ~ Longitude + Latitude, 137 | data = ames_train, 138 | k = 2) 139 | repredict <- data.frame(price = log10(ames_train$Sale_Price)) %>% 140 | mutate(pred = 141 | predict(knn_train_mod, 142 | newdata = ames_train %>% select(Longitude, Latitude) 143 | ) 144 | ) 145 | 146 | repredict %>% rsq(truth = "price", estimate = "pred") # <- the ruckus is here 147 | 148 | # Slide 40 149 | 150 | knn_fit <- function(data_split, ...) 151 | knnreg(..., data = analysis(data_split)) 152 | 153 | cv_splits <- cv_splits %>% 154 | mutate(knn_mod = map(splits, knn_fit, formula = form, k = 2)) 155 | 156 | knn_res <- map2_df(cv_splits$splits, cv_splits$knn_mod, model_perf) %>% 157 | rename(rmse_knn = rmse, rsq_knn = rsq) 158 | 159 | ## Merge in results: 160 | cv_splits <- cv_splits %>% bind_cols(knn_res) 161 | 162 | colMeans(knn_res) 163 | 164 | # Slide 42 165 | 166 | rs_comp <- data.frame( 167 | rmse = c(cv_splits$rmse_simple, cv_splits$rmse_knn), 168 | Model = rep(c("Linear\nRegression", "2-NN"), each = nrow(cv_splits)), 169 | Resample = cv_splits$id 170 | ) 171 | 172 | ggplot(rs_comp, aes(x = Model, y = rmse, group = Resample, col = Resample)) + 173 | geom_point() + 174 | geom_line() + 175 | theme(legend.position = "none") 176 | 177 | # Slide 43 178 | 179 | t.test(cv_splits$rmse_simple, cv_splits$rmse_knn, paired = TRUE) 180 | 181 | # Slide 49 182 | 183 | knn_rmse <- function(k, split) { 184 | mod <- knnreg(log10(Sale_Price) ~ Longitude + Latitude, 185 | data = analysis(split), 186 | k = k) 187 | # Extract the names of the predictors 188 | preds <- form_pred(mod$terms) 189 | data.frame(Sale_Price = log10(assessment(split)$Sale_Price)) %>% 190 | mutate(pred = predict(mod, assessment(split) %>% select(!!!preds))) %>% 191 | rmse(Sale_Price, pred) 192 | } 193 | 194 | # Slide 50 195 | library(dplyr) 196 | 197 | knn_grid <- function(split) { 198 | # Create grid 199 | tibble(k = 1:20) %>% 200 | # Execute grid for this resample 201 | mutate( 202 | rmse = map_dbl(k, knn_rmse, split = split), 203 | # Attach the resample indicators using `lables` 204 | id = labels(split)[[1]] 205 | ) 206 | } 207 | 208 | # Slide 51 209 | 210 | iter_over_resamples <- 211 | function(resamp) 212 | map_df(resamp$splits, knn_grid) 213 | 214 | # Slide 52 215 | 216 | knn_tune_res <- iter_over_resamples(cv_splits) 217 | knn_tune_res %>% head(15) 218 | 219 | # Slide 53 220 | 221 | rmse_by_k <- knn_tune_res %>% 222 | group_by(k) %>% 223 | summarize(rmse = mean(rmse)) 224 | 225 | ggplot(rmse_by_k, aes(x = k, y = rmse)) + 226 | geom_point() + geom_line() 227 | 228 | # Slide 54 229 | 230 | best_k <- knn_tune_res %>% 231 | group_by(id) %>% 232 | summarize(k = k[which.min(rmse)], 233 | rmse = rmse[which.min(rmse)]) 234 | 235 | ggplot(rmse_by_k, aes(x = k, y = rmse)) + 236 | geom_point() + geom_line() + 237 | geom_line(data = knn_tune_res, 238 | aes(group = id, 239 | col = id), 240 | alpha = .2, lwd = 1) + 241 | geom_point(data = best_k, aes(col = id), 242 | alpha = .5, cex = 2)+ 243 | theme(legend.position = "none") 244 | 245 | # Slide 55 246 | 247 | final_knn <- knnreg(log10(Sale_Price) ~ Longitude + Latitude, 248 | data = ames_train, 249 | k = 4) 250 | 251 | -------------------------------------------------------------------------------- /Materials/Part_2_Basic_Principals.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_2_Basic_Principals.pdf -------------------------------------------------------------------------------- /Materials/Part_3_Feature_Engineering.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | library(ggplot2) 6 | 7 | thm <- theme_bw() + 8 | theme( 9 | panel.background = element_rect(fill = "transparent", colour = NA), 10 | plot.background = element_rect(fill = "transparent", colour = NA), 11 | legend.position = "top", 12 | legend.background = element_rect(fill = "transparent", colour = NA), 13 | legend.key = element_rect(fill = "transparent", colour = NA) 14 | ) 15 | theme_set(thm) 16 | 17 | 18 | # Bivariate Data used in examples 19 | 20 | library(caret) 21 | data(segmentationData) 22 | 23 | segmentationData <- segmentationData[, c("EqSphereAreaCh1", "PerimCh1", "Class", "Case")] 24 | names(segmentationData)[1:2] <- paste0("Predictor", LETTERS[1:2]) 25 | 26 | segmentationData$Class <- factor(ifelse(segmentationData$Class == "PS", "One", "Two")) 27 | 28 | bivariate_data_train <- subset(segmentationData, Case == "Train") 29 | bivariate_data_test <- subset(segmentationData, Case == "Test") 30 | 31 | bivariate_data_train$Case <- NULL 32 | bivariate_data_test$Case <- NULL 33 | 34 | # Slide 4 35 | 36 | ggplot(bivariate_data_test, 37 | aes(x = PredictorA, 38 | y = PredictorB, 39 | color = Class)) + 40 | geom_point(alpha = .3, cex = 1.5) + 41 | theme(legend.position = "top") 42 | 43 | # Slide 5 44 | 45 | library(dplyr) 46 | library(recipes) 47 | 48 | bivariate_rec <- recipe(Class ~ PredictorA + PredictorB, 49 | data = bivariate_data_train) %>% 50 | step_BoxCox(all_predictors()) 51 | 52 | bivariate_rec <- prep(bivariate_rec, training = bivariate_data_train, verbose = FALSE) 53 | 54 | inverse_test <- bake(bivariate_rec, newdata = bivariate_data_test, everything()) 55 | 56 | ggplot(inverse_test, 57 | aes(x = 1/PredictorA, 58 | y = 1/PredictorB, 59 | color = Class)) + 60 | geom_point(alpha = .3, cex = 1.5) + 61 | theme(legend.position = "top") + 62 | xlab("1/A") + ylab("1/B") 63 | 64 | # Recreate the Ames Data 65 | 66 | library(AmesHousing) 67 | ames <- make_ames() 68 | nrow(ames) 69 | 70 | library(rsample) 71 | 72 | # Make sure that you get the same random numbers 73 | set.seed(4595) 74 | data_split <- initial_split(ames, strata = "Sale_Price") 75 | 76 | ames_train <- training(data_split) 77 | ames_test <- testing(data_split) 78 | 79 | alleys <- data.frame(Alley = levels(ames_train$Alley)) 80 | alley_dummies <- model.matrix(~ Alley, data = alleys)[, -1] 81 | alley_dummies <- as.data.frame(alley_dummies) 82 | rownames(alley_dummies) <- levels(ames_train$Alley) 83 | colnames(alley_dummies) <- gsub("^Alley", "", colnames(alley_dummies)) 84 | 85 | 86 | # Slide 10 87 | 88 | ggplot(ames_train, aes(x = Neighborhood)) + geom_bar() + coord_flip() + xlab("") 89 | 90 | # Slide 12 91 | 92 | library(recipes) 93 | mod_rec <- recipe(Sale_Price ~ Longitude + Latitude, data = ames_train) %>% 94 | step_log(Sale_Price, base = 10) 95 | 96 | # Slide 13 97 | 98 | mod_rec <- recipe(Sale_Price ~ Longitude + Latitude + Neighborhood, data = ames_train) %>% 99 | step_log(Sale_Price, base = 10) %>% 100 | 101 | # Lump factor levels that occur in <= 5% of data as "other" 102 | step_other(Neighborhood, threshold = 0.05) %>% 103 | 104 | # Create dummy variables for _any_ factor variables 105 | step_dummy(all_nominal()) 106 | 107 | # Slide 14 108 | 109 | mod_rec_trained <- prep(mod_rec, training = ames_train, retain = TRUE, verbose = TRUE) 110 | 111 | # Slide 15 112 | 113 | mod_rec_trained 114 | 115 | # Slide 16 116 | 117 | ames_test_dummies <- bake(mod_rec_trained,newdata = ames_test) 118 | names(ames_test_dummies) 119 | 120 | # Slide 19 121 | 122 | price_breaks <- (1:6)*(10^5) 123 | 124 | ggplot(ames_train, aes(x = Year_Built, y = Sale_Price)) + 125 | geom_point(alpha = 0.4) + 126 | scale_x_log10() + 127 | scale_y_continuous(breaks = price_breaks, trans = "log10" ) + 128 | geom_smooth(method = "loess") 129 | 130 | # Slide 20 131 | 132 | library(MASS) # to get robust linear regression model 133 | 134 | ggplot(ames_train, 135 | aes(x = Year_Built, 136 | y = Sale_Price)) + 137 | geom_point(alpha = 0.4) + 138 | scale_y_continuous(breaks = price_breaks, 139 | trans = "log10") + 140 | facet_wrap(~ Central_Air, nrow = 2) + 141 | geom_smooth(method = "rlm") 142 | 143 | # Slide 21 144 | 145 | mod1 <- lm(log10(Sale_Price) ~ Year_Built + Central_Air, data = ames_train) 146 | mod2 <- lm(log10(Sale_Price) ~ Year_Built + Central_Air + Year_Built: Central_Air, data = ames_train) 147 | anova(mod1, mod2) 148 | 149 | # Slide 33 150 | 151 | recipe(Sale_Price ~ Year_Built + Central_Air, data = ames_train) %>% 152 | step_log(Sale_Price) %>% 153 | step_dummy(Central_Air) %>% 154 | step_interact(~ starts_with("Central_Air"):Year_Built) %>% 155 | prep(training = ames_train, retain = TRUE) %>% 156 | juice %>% 157 | # select a few rows with different values 158 | slice(153:157) 159 | 160 | # Slide 24 161 | 162 | library(AmesHousing) 163 | ames <- make_ames() 164 | 165 | library(rsample) 166 | set.seed(4595) 167 | data_split <- initial_split(ames, strata = "Sale_Price") 168 | ames_train <- training(data_split) 169 | 170 | set.seed(2453) 171 | cv_splits <- vfold_cv(ames_train, v = 10, strata = "Sale_Price") 172 | 173 | # Slide 25 174 | 175 | lin_coords <- recipe(Sale_Price ~ Bldg_Type + Neighborhood + Year_Built + 176 | Gr_Liv_Area + Full_Bath + Year_Sold + Lot_Area + 177 | Central_Air + Longitude + Latitude, 178 | data = ames_train) %>% 179 | step_log(Sale_Price, base = 10) %>% 180 | step_YeoJohnson(Lot_Area, Gr_Liv_Area) %>% 181 | step_other(Neighborhood, threshold = 0.05) %>% 182 | step_dummy(all_nominal()) %>% 183 | step_interact(~ starts_with("Central_Air"):Year_Built) 184 | 185 | coords <- lin_coords %>% 186 | step_bs(Longitude, Latitude, options = list(df = 5)) 187 | 188 | # Slide 26 189 | 190 | ggplot(ames_train, 191 | aes(x = Longitude, y = Sale_Price)) + 192 | geom_point(alpha = .5) + 193 | geom_smooth( 194 | method = "lm", 195 | formula = y ~ splines::bs(x, 5) 196 | ) + 197 | scale_y_log10() 198 | 199 | # Slide 27 200 | 201 | ggplot(ames_train, 202 | aes(x = Latitude, y = Sale_Price)) + 203 | geom_point(alpha = .5) + 204 | geom_smooth( 205 | method = "lm", 206 | formula = y ~ splines::bs(x, 5) 207 | ) + 208 | scale_y_log10() 209 | 210 | # Slide 28 211 | 212 | prepper 213 | library(purrr) 214 | cv_splits <- cv_splits %>% 215 | mutate(coords = map(splits, prepper, recipe = coords, retain = TRUE)) 216 | 217 | # Slide 29 218 | 219 | lm_fit_rec <- function(rec_obj, ...) 220 | lm(..., data = juice(rec_obj)) 221 | 222 | cv_splits <- cv_splits %>% 223 | mutate(fits = map(coords, lm_fit_rec, Sale_Price ~ .)) 224 | glance(cv_splits$fits[[1]]) 225 | 226 | # Slide 30 227 | 228 | assess_predictions <- function(split_obj, rec_obj, mod_obj) { 229 | raw_data <- assessment(split_obj) 230 | proc_x <- bake(rec_obj, newdata = raw_data, all_predictors()) 231 | # Now save _all_ of the columns and add predictions. 232 | bake(rec_obj, newdata = raw_data, everything()) %>% 233 | mutate( 234 | .fitted = predict(mod_obj, newdata = proc_x), 235 | .resid = Sale_Price - .fitted, # Sale_Price is already logged by the recipe 236 | # Save the original row number of the data 237 | .row = as.integer(split_obj, data = "assessment") 238 | ) 239 | } 240 | 241 | # Slide 31 242 | 243 | cv_splits <- cv_splits %>% 244 | mutate( 245 | pred = 246 | pmap( 247 | lst(split_obj = cv_splits$splits, rec_obj = cv_splits$coords, mod_obj = cv_splits$fits), 248 | assess_predictions 249 | ) 250 | ) 251 | 252 | # Slide 32 253 | 254 | library(yardstick) 255 | 256 | # Compute the summary statistics 257 | map_df(cv_splits$pred, metrics, truth = Sale_Price, estimate = .fitted) %>% 258 | colMeans 259 | 260 | # Slide 33 261 | 262 | assess_pred <- bind_rows(cv_splits$pred) %>% 263 | mutate(Sale_Price = 10^Sale_Price, 264 | .fitted = 10^.fitted) 265 | 266 | ggplot(assess_pred, 267 | aes(x = Sale_Price, y = .fitted)) + 268 | geom_abline(lty = 2) + 269 | geom_point(alpha = .4) + 270 | geom_smooth(se = FALSE, col = "red") 271 | -------------------------------------------------------------------------------- /Materials/Part_3_Feature_Engineering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_3_Feature_Engineering.pdf -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | library(ggplot2) 6 | 7 | thm <- theme_bw() + 8 | theme( 9 | panel.background = element_rect(fill = "transparent", colour = NA), 10 | plot.background = element_rect(fill = "transparent", colour = NA), 11 | legend.position = "top", 12 | legend.background = element_rect(fill = "transparent", colour = NA), 13 | legend.key = element_rect(fill = "transparent", colour = NA) 14 | ) 15 | theme_set(thm) 16 | 17 | # Slide 4 18 | 19 | load("Data/car_data.RData") 20 | library(dplyr) 21 | car_train <- car_data %>% 22 | filter(model_year < 2018) 23 | 24 | car_test <- car_data %>% 25 | filter(model_year == 2018) 26 | 27 | # Slide 8 28 | 29 | ## lm(mpg ~ . -carline + poly(eng_displ, 2), data = car_train) 30 | 31 | # Slide 9 32 | 33 | car_train %>% 34 | group_by(division) %>% 35 | count() %>% 36 | arrange(n) %>% 37 | head(8) 38 | 39 | # Slide 10 40 | 41 | library(recipes) 42 | basic_rec <- recipe(mpg ~ ., data = car_train) %>% 43 | # keep the car name but don't use as a predictor 44 | add_role(carline, new_role = "car name") %>% 45 | # collapse some divisions into "other" 46 | step_other(division, threshold = 0.005) %>% 47 | step_dummy(all_nominal(), -carline) %>% 48 | step_zv(all_predictors()) 49 | 50 | # Slide 14 51 | 52 | glmn_grid <- expand.grid(alpha = seq(0, 1, by = .25), lambda = 10^seq(-3, -1, length = 20)) 53 | nrow(glmn_grid) 54 | 55 | # Slide 17 56 | 57 | library(caret) 58 | ctrl <- trainControl( 59 | method = "cv", 60 | # Save the assessment predictions from the best model 61 | savePredictions = "final", 62 | # Log the progress of the tuning process 63 | verboseIter = TRUE 64 | ) 65 | 66 | # Slide 18 67 | 68 | glmn_rec <- basic_rec %>% 69 | step_poly(eng_displ) %>% 70 | step_center(all_predictors()) %>% 71 | step_scale(all_predictors()) 72 | 73 | set.seed(3544) 74 | glmn_mod <- train( 75 | glmn_rec, 76 | data = car_train, 77 | method = "glmnet", 78 | trControl = ctrl, 79 | tuneGrid = glmn_grid 80 | ) 81 | 82 | # Slide 20 83 | 84 | ggplot(glmn_mod) + scale_x_log10() + theme(legend.position = "top") 85 | 86 | # Slide 21 87 | 88 | glmn_mod$pred %>% head(4) 89 | 90 | ggplot(glmn_mod$pred, aes(x = obs, y = pred)) + 91 | geom_abline(col = "green", alpha = .5) + 92 | geom_smooth(se = FALSE, col = "red", lty = 2, lwd = 1, alpha = .5) + 93 | geom_point(alpha = .3) 94 | 95 | # Slide 22 96 | 97 | reg_imp <- varImp(glmn_mod, scale = FALSE) 98 | ggplot(reg_imp, top = 30) + xlab("") 99 | 100 | # Slide 24 101 | 102 | library(glmnet) 103 | plot(glmn_mod$finalModel, xvar = "lambda") 104 | 105 | # If you would like to run in parallel 106 | 107 | library(doParallel) 108 | cl <- makeCluster(parallel::detectCores(logical = FALSE)) 109 | registerDoParallel(cl) 110 | 111 | # Slide 37 112 | 113 | ctrl$verboseIter <- FALSE 114 | 115 | mars_grid <- expand.grid(degree = 1:2, nprune = seq(2, 60, by = 2)) 116 | 117 | # Using the same seed to obtain the same 118 | # resamples as the glmnet model. 119 | set.seed(3544) 120 | mars_mod <- train( 121 | basic_rec, 122 | data = car_train, 123 | method = "earth", 124 | tuneGrid = mars_grid, 125 | trControl = ctrl 126 | ) 127 | 128 | # Slide 40 129 | 130 | ggplot(mars_mod) + theme(legend.position = "top") 131 | 132 | # Slide 41 133 | 134 | ggplot(mars_mod$pred, aes(x = obs, y = pred)) + 135 | geom_abline(col = "green", alpha = .5) + 136 | geom_smooth(se = FALSE, col = "red", 137 | lty = 2, lwd = 1, alpha = .5) + 138 | geom_point(alpha = .3) 139 | 140 | # Slide 42 141 | 142 | library(earth) 143 | mars_mod$finalModel 144 | 145 | # Slide 43 146 | 147 | mars_imp <- varImp(mars_mod) 148 | ggplot(mars_imp, top = 30) + xlab("") 149 | 150 | # Slide 44 151 | 152 | set.seed(3544) 153 | mars_gcv_mod <- train( 154 | basic_rec, 155 | data = car_train, 156 | method = "gcvEarth", 157 | tuneGrid = data.frame(degree = 1:2), 158 | trControl = ctrl 159 | ) 160 | mars_gcv_mod$finalModel 161 | 162 | # Slide 49 163 | 164 | set.seed(3544) 165 | mars_gcv_bag <- train( 166 | basic_rec, 167 | data = car_train, 168 | method = "bagEarthGCV", 169 | tuneGrid = data.frame(degree = 1:2), 170 | trControl = ctrl, 171 | # Number of bootstraps for `bagEarth` function 172 | B = 50 173 | ) 174 | 175 | # Slide 50 176 | 177 | mars_gcv_bag 178 | 179 | # Slide 51 180 | 181 | ggplot(mars_gcv_bag$pred, aes(x = obs, y = pred)) + 182 | geom_abline(col = "green", alpha = .5) + 183 | geom_smooth(se = FALSE, col = "red", 184 | lty = 2, lwd = 1, alpha = .5) + 185 | geom_point(alpha = .3) 186 | 187 | # Slide 52 188 | 189 | car_train %>% 190 | arrange(mpg) %>% 191 | select(mpg, carline, model_year) %>% 192 | tail(10) 193 | 194 | # Slide 54 195 | 196 | rs <- resamples( 197 | list(glmn = glmn_mod, MARS = mars_mod, bagged = mars_gcv_bag) 198 | ) 199 | 200 | # Slide 57 201 | 202 | library(tidyposterior) 203 | rmse_mod <- perf_mod(rs, seed = 4344, iter = 5000, metric = "RMSE") 204 | 205 | # Slide 58 206 | 207 | posteriors <- tidy(rmse_mod, seed = 366784) 208 | summary(posteriors) 209 | 210 | ggplot(posteriors) 211 | 212 | # Slide 59 213 | 214 | differences <- 215 | contrast_models( 216 | rmse_mod, 217 | list_1 = rep("bagged", 2), 218 | list_2 = c("glmn", "MARS"), 219 | seed = 2581 220 | ) 221 | 222 | ggplot(differences, size = 0.25) 223 | 224 | # Slide 60 225 | 226 | summary(differences, size = 0.25) 227 | 228 | # Slide 62 229 | 230 | car_test <- car_test %>% 231 | mutate(pred = predict(mars_gcv_bag, car_test)) 232 | 233 | library(yardstick) 234 | rmse(car_test, truth = mpg, estimate = pred) 235 | 236 | ggplot(car_test, aes(x = mpg, y = pred)) + 237 | geom_abline(col = "green", alpha = .5) + 238 | geom_smooth(se = FALSE, col = "red", 239 | lty = 2, lwd = 1, alpha = .5) + 240 | geom_point(alpha = .3) 241 | 242 | # Stop the cluster if you used it 243 | 244 | stopCluster(cl) 245 | 246 | -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling.pdf -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling_files/figure-html/bayes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-1.png -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling_files/figure-html/bayes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-2.png -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling_files/figure-html/bayes-contrast-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/bayes-contrast-1.png -------------------------------------------------------------------------------- /Materials/Part_4_Regression_Modeling_files/figure-html/mars-sim-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_4_Regression_Modeling_files/figure-html/mars-sim-1.png -------------------------------------------------------------------------------- /Materials/Part_5_Classification.R: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | ## Code for Applied Machine Learning by Max Kuhn @ RStudio::conf 3 | ## https://github.com/topepo/rstudio-conf-2018 4 | 5 | library(ggplot2) 6 | 7 | thm <- theme_bw() + 8 | theme( 9 | panel.background = element_rect(fill = "transparent", colour = NA), 10 | plot.background = element_rect(fill = "transparent", colour = NA), 11 | legend.position = "top", 12 | legend.background = element_rect(fill = "transparent", colour = NA), 13 | legend.key = element_rect(fill = "transparent", colour = NA) 14 | ) 15 | theme_set(thm) 16 | 17 | 18 | # Slide 4 19 | 20 | library(yardstick) 21 | library(dplyr) 22 | two_class_example %>% head(4) 23 | 24 | # Slide 5 25 | 26 | two_class_example %>% 27 | conf_mat(truth = truth, estimate = predicted) 28 | 29 | two_class_example %>% 30 | accuracy(truth = truth, estimate = predicted) 31 | 32 | # Slide 6 33 | 34 | two_class_example %>% 35 | sens(truth = truth, estimate = predicted) 36 | 37 | two_class_example %>% 38 | spec(truth = truth, estimate = predicted) 39 | 40 | # Slide 9 41 | 42 | library(pROC) 43 | roc_obj <- roc( 44 | response = two_class_example$truth, 45 | predictor = two_class_example$Class1, 46 | # If the first level is the event of interest: 47 | levels = rev(levels(two_class_example$truth)) 48 | ) 49 | 50 | auc(roc_obj) 51 | 52 | plot( 53 | roc_obj, 54 | legacy.axes = TRUE, 55 | print.thres = c(.2, .5, .8), 56 | print.thres.pattern = "cut = %.2f (Spec = %.2f, Sens = %.2f)", 57 | print.thres.cex = .8 58 | ) 59 | 60 | # Slide 11 61 | 62 | library(dplyr) 63 | load("Data/okc.RData") 64 | okc_train %>% dim() 65 | okc_test %>% nrow() 66 | table(okc_train$Class) 67 | 68 | # Slide 16 69 | 70 | library(caret) 71 | ctrl <- trainControl( 72 | method = "cv", 73 | # Also predict the probabilities 74 | classProbs = TRUE, 75 | # Compute the ROC AUC as well as the sens and 76 | # spec from the default 50% cutoff. The 77 | # function `twoClassSummary` will produce those. 78 | summaryFunction = twoClassSummary, 79 | savePredictions = "final", 80 | sampling = "down" 81 | ) 82 | 83 | # Slide 22 84 | 85 | set.seed(5515) 86 | cart_mod <- train( 87 | x = okc_train[, names(okc_train) != "Class"], 88 | y = okc_train$Class, 89 | method = "rpart2", 90 | metric = "ROC", 91 | tuneGrid = data.frame(maxdepth = 1:20), 92 | trControl = ctrl 93 | ) 94 | 95 | # Slide 23 96 | 97 | cart_mod$finalModel 98 | 99 | # Slide 24 100 | 101 | ggplot(cart_mod) 102 | 103 | # Slide 25 104 | 105 | plot_roc <- function(x, ...) { 106 | averaged <- x %>% 107 | group_by(rowIndex, obs) %>% 108 | summarise(stem = mean(stem, na.rm = TRUE)) 109 | roc_obj <- roc( 110 | averaged[["obs"]], 111 | averaged[["stem"]], 112 | levels = rev(levels(averaged$obs)) 113 | ) 114 | plot(roc_obj, ...) 115 | } 116 | plot_roc(cart_mod$pred) 117 | 118 | # Slide 26 119 | 120 | confusionMatrix(cart_mod) 121 | 122 | # Slide 27 123 | 124 | cart_imp <- varImp(cart_mod, scale = FALSE, 125 | surrogates = FALSE, competes = FALSE) 126 | ggplot(cart_imp, top = 7) + xlab("") 127 | 128 | # Slide 35 129 | 130 | set.seed(5515) 131 | cart_bag <- train( 132 | x = okc_train[, names(okc_train) != "Class"], 133 | y = okc_train$Class, 134 | method = "treebag", 135 | metric = "ROC", 136 | trControl = ctrl 137 | ) 138 | 139 | # Slide 36 140 | 141 | cart_bag 142 | 143 | # Slide 37 144 | 145 | confusionMatrix(cart_bag) 146 | 147 | # Slide 38 148 | 149 | plot_roc(cart_mod$pred) 150 | plot_roc(cart_bag$pred, col = "darkred", add = TRUE) 151 | 152 | # Slide 39 153 | 154 | bag_imp <- varImp(cart_bag, scale = FALSE) 155 | ggplot(bag_imp, top = 30) + xlab("") 156 | 157 | 158 | # Slide 46 159 | 160 | ggplot(okc_train, aes(x = essay_length, col = Class)) + 161 | geom_line(stat = "density") 162 | 163 | # Slide 48 164 | 165 | library(tidyr) 166 | 167 | pred_xtab <- table(okc_train$religion, okc_train$Class) 168 | pred_xtab <- t(apply(pred_xtab, 2, function(x) x/sum(x))) 169 | pred_xtab <- as.data.frame(pred_xtab) %>% 170 | tibble::rownames_to_column("Class") %>% 171 | gather(value, prob, -Class) 172 | 173 | ggplot(pred_xtab, aes(x = reorder(value, prob), y = prob, fill = Class)) + 174 | geom_bar(stat = "identity", position = position_dodge()) + 175 | xlab("") + 176 | ylab("Within-Class Probability") 177 | 178 | # Slide 53 179 | 180 | library(recipes) 181 | is_dummy <- vapply(okc_train, function(x) length(unique(x)) == 2 & is.numeric(x), logical(1)) 182 | dummies <- names(is_dummy)[is_dummy] 183 | no_dummies <- recipe(Class ~ ., data = okc_train) %>% 184 | step_bin2factor(!!! dummies) %>% 185 | step_zv(all_predictors()) 186 | 187 | smoothing_grid <- expand.grid(usekernel = TRUE, fL = 0, adjust = seq(0.5, 3.5, by = 0.5)) 188 | 189 | # Slide 54 190 | 191 | set.seed(5515) 192 | nb_mod <- train( 193 | no_dummies, 194 | data = okc_train, 195 | method = "nb", 196 | metric = "ROC", 197 | tuneGrid = smoothing_grid, 198 | trControl = ctrl 199 | ) 200 | 201 | # Slide 55 202 | 203 | ggplot(nb_mod) 204 | 205 | # Slide 56 206 | 207 | plot_roc(cart_mod$pred) 208 | plot_roc(cart_bag$pred, col = "red", add = TRUE) 209 | plot_roc(nb_mod$pred, col = "blue", add = TRUE) 210 | 211 | # Slide 58 212 | 213 | rs <- resamples( 214 | list(CART = cart_mod, Bagged = cart_bag, Bayes = nb_mod) 215 | ) 216 | library(tidyposterior) 217 | roc_mod <- perf_mod(rs, seed = 2560, iter = 5000) 218 | 219 | # Slide 59 220 | 221 | roc_dist <- tidy(roc_mod) 222 | summary(roc_dist) 223 | differences <- 224 | contrast_models( 225 | roc_mod, 226 | list_1 = c("Bagged", "Bayes"), 227 | list_2 = c("CART", "Bagged"), 228 | seed = 650 229 | ) 230 | 231 | # Slide 60 232 | 233 | summary(differences, size = 0.025) 234 | 235 | differences %>% 236 | mutate(contrast = paste(model_2, "vs", model_1)) %>% 237 | ggplot(aes(x = difference, col = contrast)) + 238 | geom_line(stat = "density") + 239 | geom_vline(xintercept = c(-0.025, 0.025), lty = 2) 240 | 241 | # Slide 62 242 | 243 | test_res <- okc_test %>% 244 | dplyr::select(Class) %>% 245 | mutate( 246 | prob = predict(nb_mod, okc_test, type = "prob")[, "stem"], 247 | pred = predict(nb_mod, okc_test) 248 | ) 249 | roc_curve <- roc(test_res$Class, test_res$prob, levels = c("other", "stem")) 250 | 251 | 252 | # Slide 63 253 | 254 | plot( 255 | roc_curve, 256 | print.thres = .5, 257 | print.thres.pattern = "cut = %.2f (Sp = %.3f, Sn = %.3f)", 258 | legacy.axes = TRUE 259 | ) 260 | 261 | roc_curve 262 | getTrainPerf(nb_mod) 263 | 264 | # Slide 64 265 | 266 | ggplot(test_res, aes(x = prob)) + geom_histogram(binwidth = .04) + facet_wrap(~Class) 267 | 268 | -------------------------------------------------------------------------------- /Materials/Part_5_Classification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification.pdf -------------------------------------------------------------------------------- /Materials/Part_5_Classification_files/figure-html/boot-cart-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-1-1.png -------------------------------------------------------------------------------- /Materials/Part_5_Classification_files/figure-html/boot-cart-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-2-1.png -------------------------------------------------------------------------------- /Materials/Part_5_Classification_files/figure-html/boot-cart-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/boot-cart-3-1.png -------------------------------------------------------------------------------- /Materials/Part_5_Classification_files/figure-html/cart-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/Part_5_Classification_files/figure-html/cart-plot-1.png -------------------------------------------------------------------------------- /Materials/RData/cart_bag.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/cart_bag.RData -------------------------------------------------------------------------------- /Materials/RData/cart_mod.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/cart_mod.RData -------------------------------------------------------------------------------- /Materials/RData/glmn_mod.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/glmn_mod.RData -------------------------------------------------------------------------------- /Materials/RData/mars_gcv_bag.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_gcv_bag.RData -------------------------------------------------------------------------------- /Materials/RData/mars_gcv_mod.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_gcv_mod.RData -------------------------------------------------------------------------------- /Materials/RData/mars_mod.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/mars_mod.RData -------------------------------------------------------------------------------- /Materials/RData/nb_mod.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/RData/nb_mod.RData -------------------------------------------------------------------------------- /Materials/Template.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Presentation" 3 | author: Your Name Here 4 | output: 5 | xaringan::moon_reader: 6 | css: ["mtheme_max.css", "fonts_mtheme_max.css"] 7 | self_contained: false 8 | lib_dir: libs 9 | nature: 10 | ratio: '16:9' 11 | highlightLanguage: R 12 | countIncrementalSlides: false 13 | --- 14 | 15 | ```{r startup, include = FALSE, message = FALSE, warning = FALSE} 16 | # This is good for getting the ggplot background consistent with 17 | # the html background color 18 | library(ggplot2) 19 | thm <- theme_bw() + 20 | theme( 21 | panel.background = element_rect(fill = "transparent", colour = NA), 22 | plot.background = element_rect(fill = "transparent", colour = NA), 23 | legend.position = "top", 24 | legend.background = element_rect(fill = "transparent", colour = NA), 25 | legend.key = element_rect(fill = "transparent", colour = NA) 26 | ) 27 | theme_set(thm) 28 | ``` 29 | 30 | # Outline 31 | 32 | * Something 33 | * Something else 34 | * That other thing 35 | 36 | 37 | --- 38 | layout: false 39 | class: inverse, middle, center 40 | 41 | # Heading Text 42 | 43 | --- 44 | 45 | # Some Acronyms and Codes 46 | 47 | .pull-left[ 48 | Test or code chunks for the lhs 49 | ] 50 | .pull-right[ 51 | rhs bits 52 | ] 53 | 54 | --- 55 | 56 | # Plot on the entire slide with a hex sticker 57 | 58 | ```{r example-plot, fig.width=6, fig.height=5.5, out.width = '40%', fig.align='center', dev = 'svg', dev.args = list(bg = "transparent")} 59 | ggplot(mtcars, aes(x = disp, y = mpg))+ 60 | geom_point() 61 | ``` 62 | 63 | --- 64 | 65 | # Plots on one side 66 | 67 | .pull-left[ 68 | show some code here but don't make image: 69 | 70 | ```{r just-dont, eval = FALSE} 71 | ggplot(mtcars, aes(x = disp, y = mpg))+ 72 | geom_point() 73 | ``` 74 | 75 | ] 76 | .pull-right[ 77 | 78 | ```{r example-plot-again, echo = FALSE, fig.width=6, fig.height=5.5, out.width = '90%', fig.align='center', dev = 'svg', dev.args = list(bg = "transparent")} 79 | ggplot(mtcars, aes(x = disp, y = mpg))+ 80 | geom_point() 81 | ``` 82 | ] 83 | 84 | -------------------------------------------------------------------------------- /Materials/Template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Presentation 5 | 6 | 7 | 8 | 9 | 10 | 11 | 77 | 78 | 85 | 86 | 93 | 94 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Materials/fonts_mtheme_max.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); 3 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700); 4 | @import url(https://fonts.googleapis.com/css?family=Fira+Sans:300,300i,400,400i,500,500i,700,700i); 5 | @import url(https://cdn.rawgit.com/tonsky/FiraCode/1.204/distr/fira_code.css); 6 | 7 | @import url(https://fonts.googleapis.com/css?family=Noto+Serif); 8 | 9 | body { 10 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; 11 | font-size: 120%; 12 | } 13 | 14 | p { 15 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; 16 | font-size: 120%; 17 | } 18 | 19 | ul, ol { 20 | font-family: 'Fira Sans','Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; 21 | font-size: 100%; 22 | } 23 | 24 | .remark-code, .remark-inline-code { 25 | font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; 26 | font-size: 80%; 27 | } 28 | 29 | .remark-inline-code { 30 | /* background: #F5F5F5; /* lighter */ 31 | /* background: #e7e8e2; /* darker */ 32 | border-radius: 3px; 33 | padding: 4px; 34 | } 35 | 36 | .code10 .remark-code { 37 | font-size: 10%; 38 | } 39 | 40 | .code20 .remark-code { 41 | font-size: 20%; 42 | } 43 | 44 | .code30 .remark-code { 45 | font-size: 30%; 46 | } 47 | 48 | .code40 .remark-code { 49 | font-size: 40%; 50 | } 51 | 52 | .code50 .remark-code { 53 | font-size: 50%; 54 | } 55 | 56 | .code60 .remark-code { 57 | font-size: 60%; 58 | } 59 | 60 | .code70 .remark-code { 61 | font-size: 70%; 62 | } 63 | 64 | .code80 .remark-code { 65 | font-size: 80%; 66 | } 67 | 68 | .code90 .remark-code { 69 | font-size: 90%; 70 | } 71 | 72 | .code100 .remark-code { 73 | font-size: 100%; 74 | } 75 | 76 | .font10 { 77 | font-size: 10%; 78 | } 79 | 80 | .font20 { 81 | font-size: 20%; 82 | } 83 | 84 | .font30 { 85 | font-size: 30%; 86 | } 87 | 88 | .font40 { 89 | font-size: 40%; 90 | } 91 | 92 | .font50 { 93 | font-size: 50%; 94 | } 95 | 96 | .font60 { 97 | font-size: 60%; 98 | } 99 | 100 | .font70 { 101 | font-size: 70%; 102 | } 103 | 104 | .font80 { 105 | font-size: 80%; 106 | } 107 | 108 | .font90 { 109 | font-size: 90%; 110 | } 111 | 112 | .font100 { 113 | font-size: 100%; 114 | } 115 | 116 | .font110 { 117 | font-size: 110%; 118 | } 119 | 120 | .font120 { 121 | font-size: 120%; 122 | } 123 | 124 | .font130 { 125 | font-size: 130%; 126 | } 127 | 128 | .font140 { 129 | font-size: 140%; 130 | } 131 | 132 | .font150 { 133 | font-size: 150%; 134 | } 135 | 136 | .font160 { 137 | font-size: 160%; 138 | } 139 | .font170 { 140 | font-size: 170%; 141 | } 142 | .font180 { 143 | font-size: 180%; 144 | } 145 | .font190 { 146 | font-size: 190%; 147 | } 148 | .font200 { 149 | font-size: 200%; 150 | } 151 | -------------------------------------------------------------------------------- /Materials/images/broom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/broom.png -------------------------------------------------------------------------------- /Materials/images/dplyr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/dplyr.png -------------------------------------------------------------------------------- /Materials/images/ggplot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/ggplot2.png -------------------------------------------------------------------------------- /Materials/images/nope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/nope.png -------------------------------------------------------------------------------- /Materials/images/nopestradomis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/nopestradomis.jpg -------------------------------------------------------------------------------- /Materials/images/purrr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/purrr.png -------------------------------------------------------------------------------- /Materials/images/readr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/readr.png -------------------------------------------------------------------------------- /Materials/images/recipes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/recipes.png -------------------------------------------------------------------------------- /Materials/images/review-resamp-cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/review-resamp-cache.png -------------------------------------------------------------------------------- /Materials/images/rsample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/rsample.png -------------------------------------------------------------------------------- /Materials/images/tidyposterior.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/tidyposterior.png -------------------------------------------------------------------------------- /Materials/images/yardstick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/images/yardstick.png -------------------------------------------------------------------------------- /Materials/libs/DiagrammeR-styles-0.2/styles.css: -------------------------------------------------------------------------------- 1 | .DiagrammeR,.grViz pre { 2 | white-space: pre-wrap; /* CSS 3 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | 9 | .DiagrammeR g .label { 10 | font-family: Helvetica; 11 | font-size: 14px; 12 | color: #333333; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Materials/libs/Proj4Leaflet-0.7.2/proj4leaflet.js: -------------------------------------------------------------------------------- 1 | (function (factory) { 2 | var L, proj4; 3 | if (typeof define === 'function' && define.amd) { 4 | // AMD 5 | define(['leaflet', 'proj4'], factory); 6 | } else if (typeof module === 'object' && typeof module.exports === "object") { 7 | // Node/CommonJS 8 | L = require('leaflet'); 9 | proj4 = require('proj4'); 10 | module.exports = factory(L, proj4); 11 | } else { 12 | // Browser globals 13 | if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined') 14 | throw 'Leaflet and proj4 must be loaded first'; 15 | factory(window.L, window.proj4); 16 | } 17 | }(function (L, proj4) { 18 | 19 | L.Proj = {}; 20 | 21 | L.Proj._isProj4Obj = function(a) { 22 | return (typeof a.inverse !== 'undefined' && 23 | typeof a.forward !== 'undefined'); 24 | }; 25 | 26 | L.Proj.ScaleDependantTransformation = function(scaleTransforms) { 27 | this.scaleTransforms = scaleTransforms; 28 | }; 29 | 30 | L.Proj.ScaleDependantTransformation.prototype.transform = function(point, scale) { 31 | return this.scaleTransforms[scale].transform(point, scale); 32 | }; 33 | 34 | L.Proj.ScaleDependantTransformation.prototype.untransform = function(point, scale) { 35 | return this.scaleTransforms[scale].untransform(point, scale); 36 | }; 37 | 38 | L.Proj.Projection = L.Class.extend({ 39 | initialize: function(a, def) { 40 | if (L.Proj._isProj4Obj(a)) { 41 | this._proj = a; 42 | } else { 43 | var code = a; 44 | if (def) { 45 | proj4.defs(code, def); 46 | } else if (proj4.defs[code] === undefined) { 47 | var urn = code.split(':'); 48 | if (urn.length > 3) { 49 | code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; 50 | } 51 | if (proj4.defs[code] === undefined) { 52 | throw 'No projection definition for code ' + code; 53 | } 54 | } 55 | this._proj = proj4(code); 56 | } 57 | }, 58 | 59 | project: function (latlng) { 60 | var point = this._proj.forward([latlng.lng, latlng.lat]); 61 | return new L.Point(point[0], point[1]); 62 | }, 63 | 64 | unproject: function (point, unbounded) { 65 | var point2 = this._proj.inverse([point.x, point.y]); 66 | return new L.LatLng(point2[1], point2[0], unbounded); 67 | } 68 | }); 69 | 70 | L.Proj.CRS = L.Class.extend({ 71 | includes: L.CRS, 72 | 73 | options: { 74 | transformation: new L.Transformation(1, 0, -1, 0) 75 | }, 76 | 77 | initialize: function(a, b, c) { 78 | var code, proj, def, options; 79 | 80 | if (L.Proj._isProj4Obj(a)) { 81 | proj = a; 82 | code = proj.srsCode; 83 | options = b || {}; 84 | 85 | this.projection = new L.Proj.Projection(proj); 86 | } else { 87 | code = a; 88 | def = b; 89 | options = c || {}; 90 | this.projection = new L.Proj.Projection(code, def); 91 | } 92 | 93 | L.Util.setOptions(this, options); 94 | this.code = code; 95 | this.transformation = this.options.transformation; 96 | 97 | if (this.options.origin) { 98 | this.transformation = 99 | new L.Transformation(1, -this.options.origin[0], 100 | -1, this.options.origin[1]); 101 | } 102 | 103 | if (this.options.scales) { 104 | this._scales = this.options.scales; 105 | } else if (this.options.resolutions) { 106 | this._scales = []; 107 | for (var i = this.options.resolutions.length - 1; i >= 0; i--) { 108 | if (this.options.resolutions[i]) { 109 | this._scales[i] = 1 / this.options.resolutions[i]; 110 | } 111 | } 112 | } 113 | }, 114 | 115 | scale: function(zoom) { 116 | var iZoom = Math.floor(zoom), 117 | baseScale, 118 | nextScale, 119 | scaleDiff, 120 | zDiff; 121 | if (zoom === iZoom) { 122 | return this._scales[zoom]; 123 | } else { 124 | // Non-integer zoom, interpolate 125 | baseScale = this._scales[iZoom]; 126 | nextScale = this._scales[iZoom + 1]; 127 | scaleDiff = nextScale - baseScale; 128 | zDiff = (zoom - iZoom); 129 | return baseScale + scaleDiff * zDiff; 130 | } 131 | }, 132 | 133 | getSize: function(zoom) { 134 | var b = this.options.bounds, 135 | s, 136 | min, 137 | max; 138 | 139 | if (b) { 140 | s = this.scale(zoom); 141 | min = this.transformation.transform(b.min, s); 142 | max = this.transformation.transform(b.max, s); 143 | return L.point(Math.abs(max.x - min.x), Math.abs(max.y - min.y)); 144 | } else { 145 | // Backwards compatibility with Leaflet < 0.7 146 | s = 256 * Math.pow(2, zoom); 147 | return L.point(s, s); 148 | } 149 | } 150 | }); 151 | 152 | L.Proj.CRS.TMS = L.Proj.CRS.extend({ 153 | options: { 154 | tileSize: 256 155 | }, 156 | 157 | initialize: function(a, b, c, d) { 158 | var code, 159 | def, 160 | proj, 161 | projectedBounds, 162 | options; 163 | 164 | if (L.Proj._isProj4Obj(a)) { 165 | proj = a; 166 | projectedBounds = b; 167 | options = c || {}; 168 | options.origin = [projectedBounds[0], projectedBounds[3]]; 169 | L.Proj.CRS.prototype.initialize.call(this, proj, options); 170 | } else { 171 | code = a; 172 | def = b; 173 | projectedBounds = c; 174 | options = d || {}; 175 | options.origin = [projectedBounds[0], projectedBounds[3]]; 176 | L.Proj.CRS.prototype.initialize.call(this, code, def, options); 177 | } 178 | 179 | this.projectedBounds = projectedBounds; 180 | 181 | this._sizes = this._calculateSizes(); 182 | }, 183 | 184 | _calculateSizes: function() { 185 | var sizes = [], 186 | crsBounds = this.projectedBounds, 187 | projectedTileSize, 188 | i, 189 | x, 190 | y; 191 | for (i = this._scales.length - 1; i >= 0; i--) { 192 | if (this._scales[i]) { 193 | projectedTileSize = this.options.tileSize / this._scales[i]; 194 | // to prevent very small rounding errors from causing us to round up, 195 | // cut any decimals after 3rd before rounding up. 196 | x = Math.ceil(parseFloat((crsBounds[2] - crsBounds[0]) / projectedTileSize).toPrecision(3)) * 197 | projectedTileSize * this._scales[i]; 198 | y = Math.ceil(parseFloat((crsBounds[3] - crsBounds[1]) / projectedTileSize).toPrecision(3)) * 199 | projectedTileSize * this._scales[i]; 200 | sizes[i] = L.point(x, y); 201 | } 202 | } 203 | 204 | return sizes; 205 | }, 206 | 207 | getSize: function(zoom) { 208 | return this._sizes[zoom]; 209 | } 210 | }); 211 | 212 | L.Proj.TileLayer = {}; 213 | 214 | // Note: deprecated and not necessary since 0.7, will be removed 215 | L.Proj.TileLayer.TMS = L.TileLayer.extend({ 216 | options: { 217 | continuousWorld: true 218 | }, 219 | 220 | initialize: function(urlTemplate, crs, options) { 221 | var boundsMatchesGrid = true, 222 | scaleTransforms, 223 | upperY, 224 | crsBounds, 225 | i; 226 | 227 | if (!(crs instanceof L.Proj.CRS.TMS)) { 228 | throw 'CRS is not L.Proj.CRS.TMS.'; 229 | } 230 | 231 | L.TileLayer.prototype.initialize.call(this, urlTemplate, options); 232 | // Enabling tms will cause Leaflet to also try to do TMS, which will 233 | // break (at least prior to 0.7.0). Actively disable it, to prevent 234 | // well-meaning users from shooting themselves in the foot. 235 | this.options.tms = false; 236 | this.crs = crs; 237 | crsBounds = this.crs.projectedBounds; 238 | 239 | // Verify grid alignment 240 | for (i = this.options.minZoom; i < this.options.maxZoom && boundsMatchesGrid; i++) { 241 | var gridHeight = (crsBounds[3] - crsBounds[1]) / 242 | this._projectedTileSize(i); 243 | boundsMatchesGrid = Math.abs(gridHeight - Math.round(gridHeight)) > 1e-3; 244 | } 245 | 246 | if (!boundsMatchesGrid) { 247 | scaleTransforms = {}; 248 | for (i = this.options.minZoom; i < this.options.maxZoom; i++) { 249 | upperY = crsBounds[1] + Math.ceil((crsBounds[3] - crsBounds[1]) / 250 | this._projectedTileSize(i)) * this._projectedTileSize(i); 251 | scaleTransforms[this.crs.scale(i)] = new L.Transformation(1, -crsBounds[0], -1, upperY); 252 | } 253 | 254 | this.crs = new L.Proj.CRS.TMS(this.crs.projection._proj, crsBounds, this.crs.options); 255 | this.crs.transformation = new L.Proj.ScaleDependantTransformation(scaleTransforms); 256 | } 257 | }, 258 | 259 | getTileUrl: function(tilePoint) { 260 | var zoom = this._map.getZoom(), 261 | gridHeight = Math.ceil( 262 | (this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) / 263 | this._projectedTileSize(zoom)); 264 | 265 | return L.Util.template(this._url, L.Util.extend({ 266 | s: this._getSubdomain(tilePoint), 267 | z: this._getZoomForUrl(), 268 | x: tilePoint.x, 269 | y: gridHeight - tilePoint.y - 1 270 | }, this.options)); 271 | }, 272 | 273 | _projectedTileSize: function(zoom) { 274 | return (this.options.tileSize / this.crs.scale(zoom)); 275 | } 276 | }); 277 | 278 | L.Proj.GeoJSON = L.GeoJSON.extend({ 279 | initialize: function(geojson, options) { 280 | this._callLevel = 0; 281 | L.GeoJSON.prototype.initialize.call(this, null, options); 282 | if (geojson) { 283 | this.addData(geojson); 284 | } 285 | }, 286 | 287 | addData: function(geojson) { 288 | var crs; 289 | 290 | if (geojson) { 291 | if (geojson.crs && geojson.crs.type === 'name') { 292 | crs = new L.Proj.CRS(geojson.crs.properties.name); 293 | } else if (geojson.crs && geojson.crs.type) { 294 | crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); 295 | } 296 | 297 | if (crs !== undefined) { 298 | this.options.coordsToLatLng = function(coords) { 299 | var point = L.point(coords[0], coords[1]); 300 | return crs.projection.unproject(point); 301 | }; 302 | } 303 | } 304 | 305 | // Base class' addData might call us recursively, but 306 | // CRS shouldn't be cleared in that case, since CRS applies 307 | // to the whole GeoJSON, inluding sub-features. 308 | this._callLevel++; 309 | try { 310 | L.GeoJSON.prototype.addData.call(this, geojson); 311 | } finally { 312 | this._callLevel--; 313 | if (this._callLevel === 0) { 314 | delete this.options.coordsToLatLng; 315 | } 316 | } 317 | } 318 | }); 319 | 320 | L.Proj.geoJson = function(geojson, options) { 321 | return new L.Proj.GeoJSON(geojson, options); 322 | }; 323 | 324 | L.Proj.ImageOverlay = L.ImageOverlay.extend({ 325 | initialize: function(url, bounds, options) { 326 | L.ImageOverlay.prototype.initialize.call(this, url, null, options); 327 | this._projBounds = bounds; 328 | }, 329 | 330 | /* Danger ahead: overriding internal methods in Leaflet. 331 | I've decided to do this rather than making a copy of L.ImageOverlay 332 | and making very tiny modifications to it. Future will tell if this 333 | was wise or not. */ 334 | _animateZoom: function (e) { 335 | var northwest = L.point(this._projBounds.min.x, this._projBounds.max.y), 336 | southeast = L.point(this._projBounds.max.x, this._projBounds.min.y), 337 | topLeft = this._projectedToNewLayerPoint(northwest, e.zoom, e.center), 338 | size = this._projectedToNewLayerPoint(southeast, e.zoom, e.center).subtract(topLeft), 339 | origin = topLeft.add(size._multiplyBy((1 - 1 / e.scale) / 2)); 340 | 341 | this._image.style[L.DomUtil.TRANSFORM] = 342 | L.DomUtil.getTranslateString(origin) + ' scale(' + this._map.getZoomScale(e.zoom) + ') '; 343 | }, 344 | 345 | _reset: function() { 346 | var zoom = this._map.getZoom(), 347 | pixelOrigin = this._map.getPixelOrigin(), 348 | bounds = L.bounds(this._transform(this._projBounds.min, zoom)._subtract(pixelOrigin), 349 | this._transform(this._projBounds.max, zoom)._subtract(pixelOrigin)), 350 | size = bounds.getSize(), 351 | image = this._image; 352 | 353 | L.DomUtil.setPosition(image, bounds.min); 354 | image.style.width = size.x + 'px'; 355 | image.style.height = size.y + 'px'; 356 | }, 357 | 358 | _projectedToNewLayerPoint: function (point, newZoom, newCenter) { 359 | var topLeft = this._map._getNewTopLeftPoint(newCenter, newZoom).add(this._map._getMapPanePos()); 360 | return this._transform(point, newZoom)._subtract(topLeft); 361 | }, 362 | 363 | _transform: function(p, zoom) { 364 | var crs = this._map.options.crs, 365 | transformation = crs.transformation, 366 | scale = crs.scale(zoom); 367 | return transformation.transform(p, scale); 368 | } 369 | }); 370 | 371 | L.Proj.imageOverlay = function(url, bounds, options) { 372 | return new L.Proj.ImageOverlay(url, bounds, options); 373 | }; 374 | 375 | if (typeof L.CRS !== 'undefined') { 376 | // This is left here for backwards compatibility 377 | L.CRS.proj4js = (function () { 378 | return function (code, def, transformation, options) { 379 | options = options || {}; 380 | if (transformation) { 381 | options.transformation = transformation; 382 | } 383 | 384 | return new L.Proj.CRS(code, def, options); 385 | }; 386 | }()); 387 | } 388 | 389 | return L.Proj; 390 | })); 391 | -------------------------------------------------------------------------------- /Materials/libs/d3-lasso-0.0.5/d3-lasso.min.js: -------------------------------------------------------------------------------- 1 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-selection"),require("d3-drag")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-drag"],n):n(t.d3=t.d3||{},t.d3,t.d3)}(this,function(t,n,r){"use strict";function e(t,n){return n={exports:{}},t(n,n.exports),n.exports}function o(){function t(t){function u(){p=[],h="",_.attr("d",null),m.attr("d",null),r.nodes().forEach(function(t){t.__lasso.possible=!1,t.__lasso.selected=!1,t.__lasso.hoverSelect=!1,t.__lasso.loopSelect=!1;var n=t.getBoundingClientRect();t.__lasso.lassoPoint=[Math.round(n.left+n.width/2),Math.round(n.top+n.height/2)]}),s&&r.on("mouseover.lasso",function(){this.__lasso.hoverSelect=!0}),i.start()}function l(){var t,n;"touchmove"===d3.event.sourceEvent.type?(t=d3.event.sourceEvent.touches[0].clientX,n=d3.event.sourceEvent.touches[0].clientY):(t=d3.event.sourceEvent.clientX,n=d3.event.sourceEvent.clientY);var s=d3.mouse(this)[0],u=d3.mouse(this)[1];""===h?(h=h+"M "+s+" "+u,v=[t,n],d=[s,u],b.attr("cx",s).attr("cy",u).attr("r",7).attr("display",null)):h=h+" L "+s+" "+u,p.push([t,n]);var l=Math.sqrt(Math.pow(t-v[0],2)+Math.pow(n-v[1],2)),f="M "+s+" "+u+" L "+d[0]+" "+d[1];_.attr("d",h),m.attr("d",f),a=l<=e,a&&o?m.attr("display",null):m.attr("display","none"),r.nodes().forEach(function(t){t.__lasso.loopSelect=!(!a||!o)&&c(p,t.__lasso.lassoPoint)<1,t.__lasso.possible=t.__lasso.hoverSelect||t.__lasso.loopSelect}),i.draw()}function f(){r.on("mouseover.lasso",null),r.nodes().forEach(function(t){t.__lasso.selected=t.__lasso.possible,t.__lasso.possible=!1}),_.attr("d",null),m.attr("d",null),b.attr("display","none"),i.end()}var h,v,d,p,g=t.append("g").attr("class","lasso"),_=g.append("path").attr("class","drawn"),m=g.append("path").attr("class","loop_close"),b=g.append("circle").attr("class","origin"),M=d3.drag().on("start",u).on("drag",l).on("end",f);n.call(M)}var n,r=[],e=75,o=!0,a=!1,s=!0,i={start:function(){},draw:function(){},end:function(){}};return t.items=function(n){if(!arguments.length)return r;r=n;var e=r.nodes();return e.forEach(function(t){t.__lasso={possible:!1,selected:!1}}),t},t.possibleItems=function(){return r.filter(function(){return this.__lasso.possible})},t.selectedItems=function(){return r.filter(function(){return this.__lasso.selected})},t.notPossibleItems=function(){return r.filter(function(){return!this.__lasso.possible})},t.notSelectedItems=function(){return r.filter(function(){return!this.__lasso.selected})},t.closePathDistance=function(n){return arguments.length?(e=n,t):e},t.closePathSelect=function(n){return arguments.length?(o=n===!0,t):o},t.isPathClosed=function(n){return arguments.length?(a=n===!0,t):a},t.hoverSelect=function(n){return arguments.length?(s=n===!0,t):s},t.on=function(n,r){if(!arguments.length)return i;if(1===arguments.length)return i[n];var e=["start","draw","end"];return e.indexOf(n)>-1&&(i[n]=r),t},t.targetArea=function(r){return arguments.length?(n=r,t):n},t}var a=e(function(t){function n(t,n,e){var o=t*n,a=r*t,s=a-t,i=a-s,u=t-i,l=r*n,f=l-n,c=l-f,h=n-c,v=o-i*c,d=v-u*c,p=d-i*h,g=u*h-p;return e?(e[0]=g,e[1]=o,e):[g,o]}t.exports=n;var r=+(Math.pow(2,27)+1)}),s=e(function(t){function n(t,n){var r=t+n,e=r-t,o=r-e,a=n-e,s=t-o,i=s+a;return i?[i,r]:[r]}function r(t,r){var e=0|t.length,o=0|r.length;if(1===e&&1===o)return n(t[0],r[0]);var a,s,i=e+o,u=new Array(i),l=0,f=0,c=0,h=Math.abs,v=t[f],d=h(v),p=r[c],g=h(p);d=o?(a=v,f+=1,f=o?(a=v,f+=1,f>1;return["sum(",o(t.slice(0,n)),",",o(t.slice(n)),")"].join("")}function i(t){if(2===t.length)return[["sum(prod(",t[0][0],",",t[1][1],"),prod(-",t[0][1],",",t[1][0],"))"].join("")];for(var r=[],a=0;a0){if(a<=0)return s;e=o+a}else{if(!(o<0))return s;if(a>=0)return s;e=-(o+a)}var i=b*e;return s>=i||s<=-i?s:y(t,n,r)},function(t,n,r,e){var o=t[0]-e[0],a=n[0]-e[0],s=r[0]-e[0],i=t[1]-e[1],u=n[1]-e[1],l=r[1]-e[1],f=t[2]-e[2],c=n[2]-e[2],h=r[2]-e[2],v=a*l,d=s*u,p=s*i,g=o*l,_=o*u,m=a*i,b=f*(v-d)+c*(p-g)+h*(_-m),y=(Math.abs(v)+Math.abs(d))*Math.abs(f)+(Math.abs(p)+Math.abs(g))*Math.abs(c)+(Math.abs(_)+Math.abs(m))*Math.abs(h),x=M*y;return b>x||-b>x?b:w(t,n,r,e)}];h()}),c=e(function(t){function n(t,n){for(var e=n[0],o=n[1],a=t.length,s=1,i=a,u=0,l=a-1;u0;){var b=(l+a-1)%a,M=t[b];if(M[1]!==o)break;var y=M[0];_=Math.min(_,y),m=Math.max(m,y),l=b}if(0===l)return _<=e&&e<=m?0:1;i=l+1}for(var w=t[(l+a-1)%a][1];u+1-1) { 247 | on[type] = _; 248 | } 249 | return lasso; 250 | }; 251 | 252 | // Area where lasso can be triggered from 253 | lasso.targetArea = function(_) { 254 | if(!arguments.length) return targetArea; 255 | targetArea = _; 256 | return lasso; 257 | } 258 | 259 | 260 | 261 | return lasso; 262 | }; 263 | -------------------------------------------------------------------------------- /Materials/libs/ggiraph-0.2.0/styles.css: -------------------------------------------------------------------------------- 1 | .ggiraph-toolbar { 2 | position: absolute; 3 | top: 3px; 4 | right: 3px; 5 | z-index: 1001; 6 | background: rgba(255, 255, 255,.3); 7 | border-radius: 5px; 8 | padding-top:2px; 9 | opacity: 0; 10 | transition: opacity 0.3s ease 0s; 11 | } 12 | 13 | .ggiraph-toolbar-block { 14 | display: inline-block; 15 | padding-right: 10px; 16 | } 17 | 18 | .ggiraph-toolbar-icon { 19 | position: relative; 20 | cursor: pointer; 21 | box-sizing: border-box; 22 | padding-right: 3px; 23 | } 24 | 25 | .drop { 26 | stroke: #E30C37; 27 | fill: #E30C37; 28 | } 29 | .drop:hover{ 30 | stroke: #333333; 31 | fill: #333333; 32 | } 33 | .neutral { 34 | stroke: #006699; 35 | fill: #006699; 36 | } 37 | .neutral:hover{ 38 | stroke: #333333; 39 | fill: #333333; 40 | } 41 | 42 | .ggiraph-container { 43 | position: relative; 44 | margin:auto; 45 | } 46 | 47 | .flex-container { 48 | height: 0; 49 | padding:0; 50 | width:100%; 51 | } 52 | 53 | .svg-inline-container { 54 | position: absolute; 55 | margin:auto; 56 | width:100%; 57 | top: 0; 58 | left: 0; 59 | right: 0; 60 | } 61 | 62 | .svg-responsive-container { 63 | width:100%; 64 | } 65 | 66 | .lasso path { 67 | stroke: rgb(80,80,80); 68 | stroke-width:2px; 69 | } 70 | 71 | .lasso .drawn { 72 | fill-opacity:.05 ; 73 | } 74 | 75 | .lasso .loop_close { 76 | fill:none; 77 | stroke-dasharray: 4,4; 78 | } 79 | 80 | .lasso .origin { 81 | fill:#333333; 82 | fill-opacity:.5; 83 | } 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Materials/libs/ggiraph-binding-0.4.1/ggiraph.js: -------------------------------------------------------------------------------- 1 | /* 2 | set_over_effect 3 | */ 4 | function set_over_effect(id){ 5 | d3.select("#" + id ).on("mouseover", function(d) { 6 | d3.select('#' + id +' div.ggiraph-toolbar').transition() 7 | .duration(200) 8 | .style("opacity", 0.8); 9 | }) 10 | .on("mouseout", function(d) { 11 | d3.select('#' + id +' div.ggiraph-toolbar').transition() 12 | .duration(500) 13 | .style("opacity", 0); 14 | }); 15 | } 16 | 17 | function set_tooltip(id, tooltip_opacity, tooltip_offx, tooltip_offy) { 18 | 19 | var div = d3.select('body').append("div") 20 | .attr("class", 'tooltip_' + id) 21 | .style("opacity", 0); 22 | var sel_tooltiped = d3.selectAll('#' + id + ' svg *[title]'); 23 | sel_tooltiped.on("mouseover", function(d) { 24 | div.transition() 25 | .duration(200) 26 | .style("opacity", tooltip_opacity); 27 | div.html(d3.select(this).attr("title")) 28 | .style("left", (d3.event.pageX + tooltip_offx ) + "px") 29 | .style("top", (d3.event.pageY + tooltip_offy ) + "px"); 30 | }) 31 | .on("mouseout", function(d) { 32 | div.transition() 33 | .duration(500) 34 | .style("opacity", 0); 35 | }); 36 | 37 | } 38 | 39 | 40 | 41 | function set_selector(container_id, sel_array_name, selected_class, sel_type, widget_id) { 42 | 43 | var sel_data_id = d3.selectAll('#' + container_id + ' svg *[data-id]'); 44 | 45 | if( sel_type == "single" ){ 46 | sel_data_id.call(select_data_id_single, sel_array_name, selected_class, widget_id, container_id); 47 | } else if( sel_type == "multiple" ){ 48 | sel_data_id.call(select_data_id_multiple, sel_array_name, selected_class, widget_id, container_id); 49 | } else { 50 | sel_data_id.call(function(selection) {selection.on("click", null);}); 51 | } 52 | } 53 | 54 | function set_highlight(id) { 55 | var sel_data_id = d3.selectAll('#' + id + ' svg *[data-id]'); 56 | sel_data_id.classed("cl_data_id_" + id, true); 57 | } 58 | 59 | 60 | function resize(id, width, height) { 61 | var containerdiv = d3.select('#' + id + " div"); 62 | var is_fd = window["fd_" + containerdiv.attr("id")]; 63 | if(is_fd > 0){ 64 | var ratio = window["ratio_" + containerdiv.attr("id")]; 65 | var dady = containerdiv.node().parentNode; 66 | var dadybb = dady.getBoundingClientRect(); 67 | containerdiv.style("width", (dadybb.bottom - dadybb.top) * ratio + "px"); 68 | } 69 | } 70 | 71 | 72 | 73 | function lasso_on(id_str, add, sel_array_name, selected_class ){ 74 | 75 | if( typeof Shiny === 'undefined' ) return false; 76 | 77 | var widget_id = window["widget_" + id_str]; 78 | var svg = d3.select('#' + id_str + ' svg'); 79 | 80 | var lasso_start = function() {}; 81 | var lasso_draw = function() {}; 82 | var lasso_end = function() { 83 | lasso.selectedItems().each( function(d, i){ 84 | d3.select(this).classed(selected_class, true); 85 | var dataid = d3.select(this).attr("data-id"); 86 | var index = window[sel_array_name].indexOf(dataid); 87 | if( index < 0 && add ){ 88 | window[sel_array_name].push( dataid ); 89 | } else if( index >= 0 && !add ){ 90 | window[sel_array_name].splice(index,1); 91 | } 92 | 93 | }); 94 | refresh_selected(sel_array_name, selected_class, id_str); 95 | 96 | svg.on(".dragstart", null) 97 | .on(".drag", null) 98 | .on(".dragend", null); 99 | 100 | Shiny.onInputChange(widget_id + "_selected", window[sel_array_name]); 101 | }; 102 | 103 | var lasso = window["lasso_"+id_str] 104 | .closePathSelect(true) 105 | .closePathDistance(100) 106 | .items(svg.selectAll('*[data-id]')) 107 | .targetArea(svg) 108 | .on("start",lasso_start) 109 | .on("draw",lasso_draw) 110 | .on("end",lasso_end); 111 | 112 | svg.call(lasso); 113 | } 114 | 115 | 116 | 117 | function zoom_on(id, zoom_min, zoom_max){ 118 | var zoom_ = window["zoom_" + id]; 119 | d3.select('#' + id ).call(zoom_ 120 | .on("zoom", (function() { 121 | d3.select('#' + id + ' svg g').attr("transform", d3.event.transform); 122 | }))); 123 | } 124 | 125 | function zoom_off(id){ 126 | var elt = d3.select('#' + id ); 127 | var zoom_ = window["zoom_" + id]; 128 | elt.call(zoom_.on("zoom", null)); 129 | } 130 | 131 | function zoom_identity(id){ 132 | var zoom_ = window["zoom_" + id]; 133 | var elt = d3.select('#' + id ); 134 | elt.call(zoom_.transform, d3.zoomIdentity); 135 | } 136 | 137 | 138 | 139 | 140 | function refresh_selected(sel_array_name, selected_class, id){ 141 | 142 | var widget_id = window["widget_" + id]; 143 | var svg = d3.select('#' + widget_id +' svg'); 144 | svg.selectAll('*[data-id]').classed(selected_class, false); 145 | 146 | var selid = window[sel_array_name]; 147 | d3.selectAll(selid).each(function(d, i) { 148 | svg.selectAll('*[data-id=\"'+ selid[i] + '\"]').classed(selected_class, true); 149 | }); 150 | 151 | } 152 | 153 | function select_data_id_single(selection, sel_array_name, selected_class, id, container_id ) { 154 | 155 | selection.on("click", function(d,i) { 156 | 157 | var dataid = d3.select(this).attr("data-id"); 158 | 159 | if( window[sel_array_name][0] == dataid ){ 160 | window[sel_array_name] = []; 161 | } 162 | else { 163 | window[sel_array_name] = [dataid]; 164 | } 165 | refresh_selected(sel_array_name, selected_class, container_id); 166 | Shiny.onInputChange(id + "_selected", window[sel_array_name]); 167 | }); 168 | } 169 | 170 | function select_data_id_multiple(selection, sel_array_name, selected_class, id, container_id) { 171 | 172 | selection.on("click", function(d,i) { 173 | 174 | var dataid = d3.select(this).attr("data-id"); 175 | var index = window[sel_array_name].indexOf(dataid); 176 | if( index < 0 ){ 177 | window[sel_array_name].push( dataid ); 178 | } else { 179 | window[sel_array_name].splice(index,1); 180 | } 181 | refresh_selected(sel_array_name, selected_class, container_id); 182 | Shiny.onInputChange(id + "_selected", window[sel_array_name]); 183 | }); 184 | } 185 | 186 | 187 | function tooltip_remove(id){ 188 | var subid = d3.select('#' + id + " div" ).attr("id"); 189 | d3.selectAll(".tooltip_" + subid ).remove(); 190 | } 191 | 192 | 193 | 194 | HTMLWidgets.widget({ 195 | 196 | name: "ggiraph", 197 | 198 | type: "output", 199 | 200 | factory: function(el, width, height) { 201 | 202 | 203 | return { 204 | renderValue: function(x) { 205 | window["widget_" + x.uid] = el.id; 206 | var div_htmlwidget = d3.select("#" + el.id ); 207 | 208 | if( HTMLWidgets.shinyMode || x.flexdashboard ){ 209 | div_htmlwidget.html(x.html); 210 | } 211 | else if( x.use_wh ){ 212 | div_htmlwidget.html("
" + 213 | x.html + "
"); 214 | } else { 215 | div_htmlwidget.html("
" + 216 | x.html + "
"); 217 | } 218 | 219 | 220 | div_htmlwidget.style("width", null).style("height", null); 221 | 222 | var fun_ = window[x.funname]; 223 | fun_(); 224 | set_over_effect(el.id); 225 | set_highlight(x.uid); 226 | set_tooltip(x.uid, x.tooltip_opacity, x.tooltip_offx, x.tooltip_offy); 227 | if( HTMLWidgets.shinyMode ){ 228 | 229 | set_selector(x.uid, x.sel_array_name, x.selected_class, x.selection_type, el.id); 230 | Shiny.addCustomMessageHandler(el.id+'_set',function(message) { 231 | 232 | var varname = el.id + '_selected'; 233 | d3.selectAll('#' + el.id + ' svg *[data-id]').classed('clicked_'+x.uid, false); 234 | d3.selectAll(message).each(function(d, i) { 235 | d3.selectAll('#' + el.id + ' svg *[data-id="'+ message[i] + '"]').classed('clicked_'+x.uid, true); 236 | }); 237 | window[x.sel_array_name] = message; 238 | Shiny.onInputChange(varname, window[x.sel_array_name]); 239 | }); 240 | 241 | Shiny.addCustomMessageHandler(el.id+'_tooltip_remove',function(message) { 242 | tooltip_remove(message); 243 | }); 244 | 245 | 246 | } else{ 247 | d3.selectAll(".ggiraph-toolbar-block").filter(".shinyonly").remove(); 248 | } 249 | resize(el.id, width, height); 250 | }, 251 | 252 | resize: function(width, height) { 253 | resize(el.id, width, height); 254 | } 255 | 256 | }; 257 | } 258 | }); -------------------------------------------------------------------------------- /Materials/libs/grViz-binding-0.9.0/grViz.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'grViz', 4 | 5 | type: 'output', 6 | 7 | initialize: function(el, width, height) { 8 | 9 | return { 10 | // TODO: add instance fields as required 11 | } 12 | 13 | }, 14 | 15 | renderValue: function(el, x, instance) { 16 | // use this to sort of make our diagram responsive 17 | // or at a minimum fit within the bounds set by htmlwidgets 18 | // for the parent container 19 | function makeResponsive(el){ 20 | var svg = el.getElementsByTagName("svg")[0]; 21 | if(svg){ 22 | if(svg.width) {svg.removeAttribute("width")}; 23 | if(svg.height) {svg.removeAttribute("height")}; 24 | svg.style.width = "100%"; 25 | svg.style.height = "100%"; 26 | } 27 | }; 28 | 29 | if ( x.diagram != "" ) { 30 | 31 | if ( typeof x.config === "undefined" ){ 32 | x.config = {}; 33 | x.config.engine = "dot"; 34 | x.config.options = {}; 35 | } 36 | 37 | try { 38 | el.innerHTML = Viz( x.diagram, format="svg", engine=x.config.engine, options=x.config.options ); 39 | 40 | makeResponsive(el); 41 | 42 | // set up a container for tasks to perform after completion 43 | // one example would be add callbacks for event handling 44 | // styling 45 | if (!(typeof x.tasks === "undefined") ){ 46 | if ( (typeof x.tasks.length === "undefined") || 47 | (typeof x.tasks === "function" ) ) { 48 | // handle a function not enclosed in array 49 | // should be able to remove once using jsonlite 50 | x.tasks = [x.tasks]; 51 | } 52 | x.tasks.map(function(t){ 53 | // for each tasks add it to the mermaid.tasks with el 54 | t.call(el); 55 | }) 56 | } 57 | } catch(e){ 58 | var p = document.createElement("pre") 59 | p.innerText = e; 60 | el.appendChild(p); 61 | } 62 | } 63 | 64 | }, 65 | 66 | resize: function(el, width, height, instance) { 67 | 68 | } 69 | 70 | 71 | }); 72 | -------------------------------------------------------------------------------- /Materials/libs/grViz-binding-0.9.2/grViz.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'grViz', 4 | 5 | type: 'output', 6 | 7 | initialize: function(el, width, height) { 8 | 9 | return { 10 | // TODO: add instance fields as required 11 | } 12 | 13 | }, 14 | 15 | renderValue: function(el, x, instance) { 16 | // use this to sort of make our diagram responsive 17 | // or at a minimum fit within the bounds set by htmlwidgets 18 | // for the parent container 19 | function makeResponsive(el){ 20 | var svg = el.getElementsByTagName("svg")[0]; 21 | if(svg){ 22 | if(svg.width) {svg.removeAttribute("width")}; 23 | if(svg.height) {svg.removeAttribute("height")}; 24 | svg.style.width = "100%"; 25 | svg.style.height = "100%"; 26 | } 27 | }; 28 | 29 | if ( x.diagram != "" ) { 30 | 31 | if ( typeof x.config === "undefined" ){ 32 | x.config = {}; 33 | x.config.engine = "dot"; 34 | x.config.options = {}; 35 | } 36 | 37 | try { 38 | el.innerHTML = Viz( x.diagram, format="svg", engine=x.config.engine, options=x.config.options ); 39 | 40 | makeResponsive(el); 41 | 42 | // set up a container for tasks to perform after completion 43 | // one example would be add callbacks for event handling 44 | // styling 45 | if (!(typeof x.tasks === "undefined") ){ 46 | if ( (typeof x.tasks.length === "undefined") || 47 | (typeof x.tasks === "function" ) ) { 48 | // handle a function not enclosed in array 49 | // should be able to remove once using jsonlite 50 | x.tasks = [x.tasks]; 51 | } 52 | x.tasks.map(function(t){ 53 | // for each tasks add it to the mermaid.tasks with el 54 | t.call(el); 55 | }) 56 | } 57 | } catch(e){ 58 | var p = document.createElement("pre") 59 | p.innerText = e; 60 | el.appendChild(p); 61 | } 62 | } 63 | 64 | }, 65 | 66 | resize: function(el, width, height, instance) { 67 | 68 | } 69 | 70 | 71 | }); 72 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/1px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/1px.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/layers-2x.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/layers.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-icon-2x.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-icon.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-0.7.7/images/marker-shadow.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-0.7.7/leaflet.css: -------------------------------------------------------------------------------- 1 | /* required styles */ 2 | 3 | .leaflet-map-pane, 4 | .leaflet-tile, 5 | .leaflet-marker-icon, 6 | .leaflet-marker-shadow, 7 | .leaflet-tile-pane, 8 | .leaflet-tile-container, 9 | .leaflet-overlay-pane, 10 | .leaflet-shadow-pane, 11 | .leaflet-marker-pane, 12 | .leaflet-popup-pane, 13 | .leaflet-overlay-pane svg, 14 | .leaflet-zoom-box, 15 | .leaflet-image-layer, 16 | .leaflet-layer { 17 | position: absolute; 18 | left: 0; 19 | top: 0; 20 | } 21 | .leaflet-container { 22 | overflow: hidden; 23 | -ms-touch-action: none; 24 | touch-action: none; 25 | } 26 | .leaflet-tile, 27 | .leaflet-marker-icon, 28 | .leaflet-marker-shadow { 29 | -webkit-user-select: none; 30 | -moz-user-select: none; 31 | user-select: none; 32 | -webkit-user-drag: none; 33 | } 34 | .leaflet-marker-icon, 35 | .leaflet-marker-shadow { 36 | display: block; 37 | } 38 | /* map is broken in FF if you have max-width: 100% on tiles */ 39 | .leaflet-container img { 40 | max-width: none !important; 41 | } 42 | /* stupid Android 2 doesn't understand "max-width: none" properly */ 43 | .leaflet-container img.leaflet-image-layer { 44 | max-width: 15000px !important; 45 | } 46 | .leaflet-tile { 47 | filter: inherit; 48 | visibility: hidden; 49 | } 50 | .leaflet-tile-loaded { 51 | visibility: inherit; 52 | } 53 | .leaflet-zoom-box { 54 | width: 0; 55 | height: 0; 56 | } 57 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ 58 | .leaflet-overlay-pane svg { 59 | -moz-user-select: none; 60 | } 61 | 62 | .leaflet-tile-pane { z-index: 2; } 63 | .leaflet-objects-pane { z-index: 3; } 64 | .leaflet-overlay-pane { z-index: 4; } 65 | .leaflet-shadow-pane { z-index: 5; } 66 | .leaflet-marker-pane { z-index: 6; } 67 | .leaflet-popup-pane { z-index: 7; } 68 | 69 | .leaflet-vml-shape { 70 | width: 1px; 71 | height: 1px; 72 | } 73 | .lvml { 74 | behavior: url(#default#VML); 75 | display: inline-block; 76 | position: absolute; 77 | } 78 | 79 | 80 | /* control positioning */ 81 | 82 | .leaflet-control { 83 | position: relative; 84 | z-index: 7; 85 | pointer-events: auto; 86 | } 87 | .leaflet-top, 88 | .leaflet-bottom { 89 | position: absolute; 90 | z-index: 1000; 91 | pointer-events: none; 92 | } 93 | .leaflet-top { 94 | top: 0; 95 | } 96 | .leaflet-right { 97 | right: 0; 98 | } 99 | .leaflet-bottom { 100 | bottom: 0; 101 | } 102 | .leaflet-left { 103 | left: 0; 104 | } 105 | .leaflet-control { 106 | float: left; 107 | clear: both; 108 | } 109 | .leaflet-right .leaflet-control { 110 | float: right; 111 | } 112 | .leaflet-top .leaflet-control { 113 | margin-top: 10px; 114 | } 115 | .leaflet-bottom .leaflet-control { 116 | margin-bottom: 10px; 117 | } 118 | .leaflet-left .leaflet-control { 119 | margin-left: 10px; 120 | } 121 | .leaflet-right .leaflet-control { 122 | margin-right: 10px; 123 | } 124 | 125 | 126 | /* zoom and fade animations */ 127 | 128 | .leaflet-fade-anim .leaflet-tile, 129 | .leaflet-fade-anim .leaflet-popup { 130 | opacity: 0; 131 | -webkit-transition: opacity 0.2s linear; 132 | -moz-transition: opacity 0.2s linear; 133 | -o-transition: opacity 0.2s linear; 134 | transition: opacity 0.2s linear; 135 | } 136 | .leaflet-fade-anim .leaflet-tile-loaded, 137 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup { 138 | opacity: 1; 139 | } 140 | 141 | .leaflet-zoom-anim .leaflet-zoom-animated { 142 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); 143 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); 144 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1); 145 | transition: transform 0.25s cubic-bezier(0,0,0.25,1); 146 | } 147 | .leaflet-zoom-anim .leaflet-tile, 148 | .leaflet-pan-anim .leaflet-tile, 149 | .leaflet-touching .leaflet-zoom-animated { 150 | -webkit-transition: none; 151 | -moz-transition: none; 152 | -o-transition: none; 153 | transition: none; 154 | } 155 | 156 | .leaflet-zoom-anim .leaflet-zoom-hide { 157 | visibility: hidden; 158 | } 159 | 160 | 161 | /* cursors */ 162 | 163 | .leaflet-clickable { 164 | cursor: pointer; 165 | } 166 | .leaflet-container { 167 | cursor: -webkit-grab; 168 | cursor: -moz-grab; 169 | } 170 | .leaflet-popup-pane, 171 | .leaflet-control { 172 | cursor: auto; 173 | } 174 | .leaflet-dragging .leaflet-container, 175 | .leaflet-dragging .leaflet-clickable { 176 | cursor: move; 177 | cursor: -webkit-grabbing; 178 | cursor: -moz-grabbing; 179 | } 180 | 181 | 182 | /* visual tweaks */ 183 | 184 | .leaflet-container { 185 | background: #ddd; 186 | outline: 0; 187 | } 188 | .leaflet-container a { 189 | color: #0078A8; 190 | } 191 | .leaflet-container a.leaflet-active { 192 | outline: 2px solid orange; 193 | } 194 | .leaflet-zoom-box { 195 | border: 2px dotted #38f; 196 | background: rgba(255,255,255,0.5); 197 | } 198 | 199 | 200 | /* general typography */ 201 | .leaflet-container { 202 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; 203 | } 204 | 205 | 206 | /* general toolbar styles */ 207 | 208 | .leaflet-bar { 209 | box-shadow: 0 1px 5px rgba(0,0,0,0.65); 210 | border-radius: 4px; 211 | } 212 | .leaflet-bar a, 213 | .leaflet-bar a:hover { 214 | background-color: #fff; 215 | border-bottom: 1px solid #ccc; 216 | width: 26px; 217 | height: 26px; 218 | line-height: 26px; 219 | display: block; 220 | text-align: center; 221 | text-decoration: none; 222 | color: black; 223 | } 224 | .leaflet-bar a, 225 | .leaflet-control-layers-toggle { 226 | background-position: 50% 50%; 227 | background-repeat: no-repeat; 228 | display: block; 229 | } 230 | .leaflet-bar a:hover { 231 | background-color: #f4f4f4; 232 | } 233 | .leaflet-bar a:first-child { 234 | border-top-left-radius: 4px; 235 | border-top-right-radius: 4px; 236 | } 237 | .leaflet-bar a:last-child { 238 | border-bottom-left-radius: 4px; 239 | border-bottom-right-radius: 4px; 240 | border-bottom: none; 241 | } 242 | .leaflet-bar a.leaflet-disabled { 243 | cursor: default; 244 | background-color: #f4f4f4; 245 | color: #bbb; 246 | } 247 | 248 | .leaflet-touch .leaflet-bar a { 249 | width: 30px; 250 | height: 30px; 251 | line-height: 30px; 252 | } 253 | 254 | 255 | /* zoom control */ 256 | 257 | .leaflet-control-zoom-in, 258 | .leaflet-control-zoom-out { 259 | font: bold 18px 'Lucida Console', Monaco, monospace; 260 | text-indent: 1px; 261 | } 262 | .leaflet-control-zoom-out { 263 | font-size: 20px; 264 | } 265 | 266 | .leaflet-touch .leaflet-control-zoom-in { 267 | font-size: 22px; 268 | } 269 | .leaflet-touch .leaflet-control-zoom-out { 270 | font-size: 24px; 271 | } 272 | 273 | 274 | /* layers control */ 275 | 276 | .leaflet-control-layers { 277 | box-shadow: 0 1px 5px rgba(0,0,0,0.4); 278 | background: #fff; 279 | border-radius: 5px; 280 | } 281 | .leaflet-control-layers-toggle { 282 | background-image: url(images/layers.png); 283 | width: 36px; 284 | height: 36px; 285 | } 286 | .leaflet-retina .leaflet-control-layers-toggle { 287 | background-image: url(images/layers-2x.png); 288 | background-size: 26px 26px; 289 | } 290 | .leaflet-touch .leaflet-control-layers-toggle { 291 | width: 44px; 292 | height: 44px; 293 | } 294 | .leaflet-control-layers .leaflet-control-layers-list, 295 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle { 296 | display: none; 297 | } 298 | .leaflet-control-layers-expanded .leaflet-control-layers-list { 299 | display: block; 300 | position: relative; 301 | } 302 | .leaflet-control-layers-expanded { 303 | padding: 6px 10px 6px 6px; 304 | color: #333; 305 | background: #fff; 306 | } 307 | .leaflet-control-layers-selector { 308 | margin-top: 2px; 309 | position: relative; 310 | top: 1px; 311 | } 312 | .leaflet-control-layers label { 313 | display: block; 314 | } 315 | .leaflet-control-layers-separator { 316 | height: 0; 317 | border-top: 1px solid #ddd; 318 | margin: 5px -10px 5px -6px; 319 | } 320 | 321 | 322 | /* attribution and scale controls */ 323 | 324 | .leaflet-container .leaflet-control-attribution { 325 | background: #fff; 326 | background: rgba(255, 255, 255, 0.7); 327 | margin: 0; 328 | } 329 | .leaflet-control-attribution, 330 | .leaflet-control-scale-line { 331 | padding: 0 5px; 332 | color: #333; 333 | } 334 | .leaflet-control-attribution a { 335 | text-decoration: none; 336 | } 337 | .leaflet-control-attribution a:hover { 338 | text-decoration: underline; 339 | } 340 | .leaflet-container .leaflet-control-attribution, 341 | .leaflet-container .leaflet-control-scale { 342 | font-size: 11px; 343 | } 344 | .leaflet-left .leaflet-control-scale { 345 | margin-left: 5px; 346 | } 347 | .leaflet-bottom .leaflet-control-scale { 348 | margin-bottom: 5px; 349 | } 350 | .leaflet-control-scale-line { 351 | border: 2px solid #777; 352 | border-top: none; 353 | line-height: 1.1; 354 | padding: 2px 5px 1px; 355 | font-size: 11px; 356 | white-space: nowrap; 357 | overflow: hidden; 358 | -moz-box-sizing: content-box; 359 | box-sizing: content-box; 360 | 361 | background: #fff; 362 | background: rgba(255, 255, 255, 0.5); 363 | } 364 | .leaflet-control-scale-line:not(:first-child) { 365 | border-top: 2px solid #777; 366 | border-bottom: none; 367 | margin-top: -2px; 368 | } 369 | .leaflet-control-scale-line:not(:first-child):not(:last-child) { 370 | border-bottom: 2px solid #777; 371 | } 372 | 373 | .leaflet-touch .leaflet-control-attribution, 374 | .leaflet-touch .leaflet-control-layers, 375 | .leaflet-touch .leaflet-bar { 376 | box-shadow: none; 377 | } 378 | .leaflet-touch .leaflet-control-layers, 379 | .leaflet-touch .leaflet-bar { 380 | border: 2px solid rgba(0,0,0,0.2); 381 | background-clip: padding-box; 382 | } 383 | 384 | 385 | /* popup */ 386 | 387 | .leaflet-popup { 388 | position: absolute; 389 | text-align: center; 390 | } 391 | .leaflet-popup-content-wrapper { 392 | padding: 1px; 393 | text-align: left; 394 | border-radius: 12px; 395 | } 396 | .leaflet-popup-content { 397 | margin: 13px 19px; 398 | line-height: 1.4; 399 | } 400 | .leaflet-popup-content p { 401 | margin: 18px 0; 402 | } 403 | .leaflet-popup-tip-container { 404 | margin: 0 auto; 405 | width: 40px; 406 | height: 20px; 407 | position: relative; 408 | overflow: hidden; 409 | } 410 | .leaflet-popup-tip { 411 | width: 17px; 412 | height: 17px; 413 | padding: 1px; 414 | 415 | margin: -10px auto 0; 416 | 417 | -webkit-transform: rotate(45deg); 418 | -moz-transform: rotate(45deg); 419 | -ms-transform: rotate(45deg); 420 | -o-transform: rotate(45deg); 421 | transform: rotate(45deg); 422 | } 423 | .leaflet-popup-content-wrapper, 424 | .leaflet-popup-tip { 425 | background: white; 426 | 427 | box-shadow: 0 3px 14px rgba(0,0,0,0.4); 428 | } 429 | .leaflet-container a.leaflet-popup-close-button { 430 | position: absolute; 431 | top: 0; 432 | right: 0; 433 | padding: 4px 4px 0 0; 434 | text-align: center; 435 | width: 18px; 436 | height: 14px; 437 | font: 16px/14px Tahoma, Verdana, sans-serif; 438 | color: #c3c3c3; 439 | text-decoration: none; 440 | font-weight: bold; 441 | background: transparent; 442 | } 443 | .leaflet-container a.leaflet-popup-close-button:hover { 444 | color: #999; 445 | } 446 | .leaflet-popup-scrolled { 447 | overflow: auto; 448 | border-bottom: 1px solid #ddd; 449 | border-top: 1px solid #ddd; 450 | } 451 | 452 | .leaflet-oldie .leaflet-popup-content-wrapper { 453 | zoom: 1; 454 | } 455 | .leaflet-oldie .leaflet-popup-tip { 456 | width: 24px; 457 | margin: 0 auto; 458 | 459 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 460 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 461 | } 462 | .leaflet-oldie .leaflet-popup-tip-container { 463 | margin-top: -1px; 464 | } 465 | 466 | .leaflet-oldie .leaflet-control-zoom, 467 | .leaflet-oldie .leaflet-control-layers, 468 | .leaflet-oldie .leaflet-popup-content-wrapper, 469 | .leaflet-oldie .leaflet-popup-tip { 470 | border: 1px solid #999; 471 | } 472 | 473 | 474 | /* div icon */ 475 | 476 | .leaflet-div-icon { 477 | background: #fff; 478 | border: 1px solid #666; 479 | } 480 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-label-0.2.2/images/death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topepo/rstudio-conf-2018/c815e5cd6d6017cce9b7d83a5979b549cb1bdae2/Materials/libs/leaflet-label-0.2.2/images/death.png -------------------------------------------------------------------------------- /Materials/libs/leaflet-label-0.2.2/leaflet.label-src.js: -------------------------------------------------------------------------------- 1 | /* 2 | Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps. 3 | (c) 2012-2013, Jacob Toye, Smartrak 4 | 5 | https://github.com/Leaflet/Leaflet.label 6 | http://leafletjs.com 7 | https://github.com/jacobtoye 8 | */ 9 | (function (factory, window) { 10 | 11 | // define an AMD module that relies on 'leaflet' 12 | if (typeof define === 'function' && define.amd) { 13 | define(['leaflet'], factory); 14 | 15 | // define a Common JS module that relies on 'leaflet' 16 | } else if (typeof exports === 'object') { 17 | module.exports = factory(require('leaflet')); 18 | } 19 | 20 | // attach your plugin to the global 'L' variable 21 | if (typeof window !== 'undefined' && window.L) { 22 | window.LeafletLabel = factory(L); 23 | } 24 | }(function (L) { 25 | L.labelVersion = '0.2.4'; 26 | 27 | 28 | var LeafletLabel = L.Class.extend({ 29 | 30 | includes: L.Mixin.Events, 31 | 32 | _directions: [ 'top', 'right', 'bottom', 'left' ], 33 | 34 | options: { 35 | className: '', 36 | clickable: false, 37 | direction: 'right', 38 | noHide: false, 39 | offset: [12, -15], // 6 (width of the label triangle) + 6 (padding) 40 | opacity: 1, 41 | textsize: "10px", 42 | textOnly: false, 43 | style: null, 44 | zoomAnimation: true 45 | }, 46 | 47 | initialize: function (options, source) { 48 | L.setOptions(this, options); 49 | 50 | this._source = source; 51 | this._animated = L.Browser.any3d && this.options.zoomAnimation; 52 | this._isOpen = false; 53 | }, 54 | 55 | _isOnMarker: function () { 56 | return this._source instanceof L.Marker; 57 | }, 58 | 59 | onAdd: function (map) { 60 | this._map = map; 61 | 62 | this._pane = this.options.pane ? map._panes[this.options.pane] : 63 | this._isOnMarker() ? map._panes.markerPane : map._panes.popupPane; 64 | 65 | if (!this._container) { 66 | this._initLayout(); 67 | } 68 | 69 | this._pane.appendChild(this._container); 70 | 71 | this._initInteraction(); 72 | 73 | this._update(); 74 | 75 | this.setOpacity(this.options.opacity); 76 | 77 | map 78 | .on('moveend', this._onMoveEnd, this) 79 | .on('viewreset', this._onViewReset, this); 80 | 81 | if (this._animated) { 82 | map.on('zoomanim', this._zoomAnimation, this); 83 | } 84 | 85 | if (L.Browser.touch && !this.options.noHide) { 86 | L.DomEvent.on(this._container, 'click', this.close, this); 87 | map.on('click', this.close, this); 88 | } 89 | }, 90 | 91 | onRemove: function (map) { 92 | this._pane.removeChild(this._container); 93 | 94 | map.off({ 95 | zoomanim: this._zoomAnimation, 96 | moveend: this._onMoveEnd, 97 | viewreset: this._onViewReset 98 | }, this); 99 | 100 | this._removeInteraction(); 101 | 102 | this._map = null; 103 | }, 104 | 105 | setLatLng: function (latlng) { 106 | this._latlng = L.latLng(latlng); 107 | if (this._map) { 108 | this._updatePosition(); 109 | } 110 | return this; 111 | }, 112 | 113 | setContent: function (content) { 114 | // Backup previous content and store new content 115 | this._previousContent = this._content; 116 | this._content = content; 117 | 118 | this._updateContent(); 119 | 120 | return this; 121 | }, 122 | 123 | close: function () { 124 | var map = this._map; 125 | 126 | if (map) { 127 | if (L.Browser.touch && !this.options.noHide) { 128 | L.DomEvent.off(this._container, 'click', this.close); 129 | map.off('click', this.close, this); 130 | } 131 | 132 | map.removeLayer(this); 133 | } 134 | }, 135 | 136 | updateZIndex: function (zIndex) { 137 | this._zIndex = zIndex; 138 | 139 | if (this._container && this._zIndex) { 140 | this._container.style.zIndex = zIndex; 141 | } 142 | }, 143 | 144 | setOpacity: function (opacity) { 145 | this.options.opacity = opacity; 146 | 147 | if (this._container) { 148 | L.DomUtil.setOpacity(this._container, opacity); 149 | } 150 | }, 151 | 152 | _initLayout: function () { 153 | this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated'); 154 | this._container.style.fontSize = this.options.textsize; 155 | if (this.options.textOnly) { L.DomUtil.addClass(this._container, 'leaflet-label-text-only'); } 156 | if (this.options.style) { 157 | for (var property in this.options.style) { 158 | if (this.options.style.hasOwnProperty(property)) { 159 | this._container.style[property] = this.options.style[property]; 160 | } 161 | } 162 | } 163 | this.updateZIndex(this._zIndex); 164 | }, 165 | 166 | _update: function () { 167 | if (!this._map) { return; } 168 | 169 | this._container.style.visibility = 'hidden'; 170 | 171 | this._updateContent(); 172 | this._updatePosition(); 173 | 174 | this._container.style.visibility = ''; 175 | }, 176 | 177 | _updateContent: function () { 178 | if (!this._content || !this._map || this._prevContent === this._content) { 179 | return; 180 | } 181 | 182 | if (typeof this._content === 'string') { 183 | this._container.innerHTML = this._content; 184 | 185 | this._prevContent = this._content; 186 | 187 | this._labelWidth = this._container.offsetWidth; 188 | } 189 | }, 190 | 191 | _updatePosition: function () { 192 | var pos = this._map.latLngToLayerPoint(this._latlng); 193 | 194 | this._setPosition(pos); 195 | }, 196 | 197 | _getIconHeight: function () { 198 | return this._source.options.icon ? this._source.options.icon.options.iconSize[1] : 0; 199 | }, 200 | 201 | _setPosition: function (pos) { 202 | var map = this._map, 203 | container = this._container, 204 | centerPoint = map.latLngToContainerPoint(map.getCenter()), 205 | labelPoint = map.layerPointToContainerPoint(pos), 206 | direction = this._getDirection(), 207 | labelWidth = this._labelWidth, 208 | offset = L.point(this.options.offset), 209 | verticalOffset = offset.y; 210 | 211 | if (direction === 'top') { 212 | verticalOffset -= this._isOnMarker() ? this._getIconHeight() : 0; 213 | 214 | pos = pos.add(L.point(-labelWidth / 2, verticalOffset)); 215 | } else if (direction === 'bottom') { 216 | verticalOffset += this._isOnMarker ? this._getIconHeight() : 0; 217 | 218 | pos = pos.add(L.point(-labelWidth / 2, verticalOffset)); 219 | } else if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) { 220 | direction = 'right'; 221 | pos = pos.add(offset); 222 | } else { 223 | direction = 'left'; 224 | pos = pos.add(L.point(-offset.x - labelWidth, offset.y)); 225 | } 226 | 227 | this._setProperClass(pos, direction); 228 | L.DomUtil.setPosition(container, pos); 229 | }, 230 | 231 | _generateLabelClass: function (direction) { 232 | return 'leaflet-label-' + direction; 233 | }, 234 | 235 | _setProperClass: function (pos, _direction) { 236 | var map = this._map, 237 | container = this._container, 238 | direction = _direction || this._getDirection(), 239 | labelPoint = map.layerPointToContainerPoint(pos), 240 | centerPoint = map.latLngToContainerPoint(map.getCenter()), 241 | classToAdd = this._generateLabelClass(direction); 242 | 243 | for (var i = 0; i < this._directions.length; i++) { 244 | var d = this._directions[i]; 245 | if (d !== direction) { 246 | var classToRemove = this._generateLabelClass(d); 247 | L.DomUtil.removeClass(container, classToRemove); 248 | } 249 | } 250 | 251 | L.DomUtil.addClass(container, classToAdd); 252 | }, 253 | 254 | _getDirection: function () { 255 | return this.options.direction; 256 | }, 257 | 258 | _zoomAnimation: function (opt) { 259 | var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); 260 | 261 | this._setPosition(pos); 262 | }, 263 | 264 | _onMoveEnd: function () { 265 | if (!this._animated || this._getDirection() === 'auto') { 266 | this._updatePosition(); 267 | } 268 | }, 269 | 270 | _onViewReset: function (e) { 271 | /* if map resets hard, we must update the label */ 272 | if (e && e.hard) { 273 | this._update(); 274 | } 275 | }, 276 | 277 | _initInteraction: function () { 278 | if (!this.options.clickable) { return; } 279 | 280 | var container = this._container, 281 | events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu']; 282 | 283 | L.DomUtil.addClass(container, 'leaflet-clickable'); 284 | L.DomEvent.on(container, 'click', this._onMouseClick, this); 285 | 286 | for (var i = 0; i < events.length; i++) { 287 | L.DomEvent.on(container, events[i], this._fireMouseEvent, this); 288 | } 289 | }, 290 | 291 | _removeInteraction: function () { 292 | if (!this.options.clickable) { return; } 293 | 294 | var container = this._container, 295 | events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu']; 296 | 297 | L.DomUtil.removeClass(container, 'leaflet-clickable'); 298 | L.DomEvent.off(container, 'click', this._onMouseClick, this); 299 | 300 | for (var i = 0; i < events.length; i++) { 301 | L.DomEvent.off(container, events[i], this._fireMouseEvent, this); 302 | } 303 | }, 304 | 305 | _onMouseClick: function (e) { 306 | if (this.hasEventListeners(e.type)) { 307 | L.DomEvent.stopPropagation(e); 308 | } 309 | 310 | this.fire(e.type, { 311 | originalEvent: e 312 | }); 313 | }, 314 | 315 | _fireMouseEvent: function (e) { 316 | this.fire(e.type, { 317 | originalEvent: e 318 | }); 319 | 320 | // TODO proper custom event propagation 321 | // this line will always be called if marker is in a FeatureGroup 322 | if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) { 323 | L.DomEvent.preventDefault(e); 324 | } 325 | if (e.type !== 'mousedown') { 326 | L.DomEvent.stopPropagation(e); 327 | } else { 328 | L.DomEvent.preventDefault(e); 329 | } 330 | } 331 | }); 332 | 333 | 334 | /*global LeafletLabel */ 335 | 336 | // This object is a mixin for L.Marker and L.CircleMarker. We declare it here as both need to include the contents. 337 | L.BaseMarkerMethods = { 338 | showLabel: function () { 339 | if (this.label && this._map) { 340 | this.label.setLatLng(this._latlng); 341 | this._map.showLabel(this.label); 342 | } 343 | 344 | return this; 345 | }, 346 | 347 | hideLabel: function () { 348 | if (this.label) { 349 | this.label.close(); 350 | } 351 | return this; 352 | }, 353 | 354 | setLabelNoHide: function (noHide) { 355 | if (this._labelNoHide === noHide) { 356 | return; 357 | } 358 | 359 | this._labelNoHide = noHide; 360 | 361 | if (noHide) { 362 | this._removeLabelRevealHandlers(); 363 | this.showLabel(); 364 | } else { 365 | this._addLabelRevealHandlers(); 366 | this.hideLabel(); 367 | } 368 | }, 369 | 370 | bindLabel: function (content, options) { 371 | var labelAnchor = this.options.icon ? this.options.icon.options.labelAnchor : this.options.labelAnchor, 372 | anchor = L.point(labelAnchor) || L.point(0, 0); 373 | 374 | anchor = anchor.add(LeafletLabel.prototype.options.offset); 375 | 376 | if (options && options.offset) { 377 | anchor = anchor.add(options.offset); 378 | } 379 | 380 | options = L.Util.extend({offset: anchor}, options); 381 | 382 | this._labelNoHide = options.noHide; 383 | 384 | if (!this.label) { 385 | if (!this._labelNoHide) { 386 | this._addLabelRevealHandlers(); 387 | } 388 | 389 | this 390 | .on('remove', this.hideLabel, this) 391 | .on('move', this._moveLabel, this) 392 | .on('add', this._onMarkerAdd, this); 393 | 394 | this._hasLabelHandlers = true; 395 | } 396 | 397 | this.label = new LeafletLabel(options, this) 398 | .setContent(content); 399 | 400 | return this; 401 | }, 402 | 403 | unbindLabel: function () { 404 | if (this.label) { 405 | this.hideLabel(); 406 | 407 | this.label = null; 408 | 409 | if (this._hasLabelHandlers) { 410 | if (!this._labelNoHide) { 411 | this._removeLabelRevealHandlers(); 412 | } 413 | 414 | this 415 | .off('remove', this.hideLabel, this) 416 | .off('move', this._moveLabel, this) 417 | .off('add', this._onMarkerAdd, this); 418 | } 419 | 420 | this._hasLabelHandlers = false; 421 | } 422 | return this; 423 | }, 424 | 425 | updateLabelContent: function (content) { 426 | if (this.label) { 427 | this.label.setContent(content); 428 | } 429 | }, 430 | 431 | getLabel: function () { 432 | return this.label; 433 | }, 434 | 435 | _onMarkerAdd: function () { 436 | if (this._labelNoHide) { 437 | this.showLabel(); 438 | } 439 | }, 440 | 441 | _addLabelRevealHandlers: function () { 442 | this 443 | .on('mouseover', this.showLabel, this) 444 | .on('mouseout', this.hideLabel, this); 445 | 446 | if (L.Browser.touch) { 447 | this.on('click', this.showLabel, this); 448 | } 449 | }, 450 | 451 | _removeLabelRevealHandlers: function () { 452 | this 453 | .off('mouseover', this.showLabel, this) 454 | .off('mouseout', this.hideLabel, this); 455 | 456 | if (L.Browser.touch) { 457 | this.off('click', this.showLabel, this); 458 | } 459 | }, 460 | 461 | _moveLabel: function (e) { 462 | this.label.setLatLng(e.latlng); 463 | } 464 | }; 465 | 466 | 467 | // Add in an option to icon that is used to set where the label anchor is 468 | L.Icon.Default.mergeOptions({ 469 | labelAnchor: new L.Point(9, -20) 470 | }); 471 | 472 | // Have to do this since Leaflet is loaded before this plugin and initializes 473 | // L.Marker.options.icon therefore missing our mixin above. 474 | L.Marker.mergeOptions({ 475 | icon: new L.Icon.Default() 476 | }); 477 | 478 | L.Marker.include(L.BaseMarkerMethods); 479 | L.Marker.include({ 480 | _originalUpdateZIndex: L.Marker.prototype._updateZIndex, 481 | 482 | _updateZIndex: function (offset) { 483 | var zIndex = this._zIndex + offset; 484 | 485 | this._originalUpdateZIndex(offset); 486 | 487 | if (this.label) { 488 | this.label.updateZIndex(zIndex); 489 | } 490 | }, 491 | 492 | _originalSetOpacity: L.Marker.prototype.setOpacity, 493 | 494 | setOpacity: function (opacity, labelHasSemiTransparency) { 495 | this.options.labelHasSemiTransparency = labelHasSemiTransparency; 496 | 497 | this._originalSetOpacity(opacity); 498 | }, 499 | 500 | _originalUpdateOpacity: L.Marker.prototype._updateOpacity, 501 | 502 | _updateOpacity: function () { 503 | var absoluteOpacity = this.options.opacity === 0 ? 0 : 1; 504 | 505 | this._originalUpdateOpacity(); 506 | 507 | if (this.label) { 508 | this.label.setOpacity(this.options.labelHasSemiTransparency ? this.options.opacity : absoluteOpacity); 509 | } 510 | }, 511 | 512 | _originalSetLatLng: L.Marker.prototype.setLatLng, 513 | 514 | setLatLng: function (latlng) { 515 | if (this.label && !this._labelNoHide) { 516 | this.hideLabel(); 517 | } 518 | 519 | return this._originalSetLatLng(latlng); 520 | } 521 | }); 522 | 523 | // Add in an option to icon that is used to set where the label anchor is 524 | L.CircleMarker.mergeOptions({ 525 | labelAnchor: new L.Point(0, 0) 526 | }); 527 | 528 | 529 | L.CircleMarker.include(L.BaseMarkerMethods); 530 | 531 | /*global LeafletLabel */ 532 | 533 | L.Path.include({ 534 | bindLabel: function (content, options) { 535 | if (!this.label || this.label.options !== options) { 536 | this.label = new LeafletLabel(options, this); 537 | } 538 | 539 | this.label.setContent(content); 540 | 541 | if (!this._showLabelAdded) { 542 | this 543 | .on('mouseover', this._showLabel, this) 544 | .on('mousemove', this._moveLabel, this) 545 | .on('mouseout remove', this._hideLabel, this); 546 | 547 | if (L.Browser.touch) { 548 | this.on('click', this._showLabel, this); 549 | } 550 | this._showLabelAdded = true; 551 | } 552 | 553 | return this; 554 | }, 555 | 556 | unbindLabel: function () { 557 | if (this.label) { 558 | this._hideLabel(); 559 | this.label = null; 560 | this._showLabelAdded = false; 561 | this 562 | .off('mouseover', this._showLabel, this) 563 | .off('mousemove', this._moveLabel, this) 564 | .off('mouseout remove', this._hideLabel, this); 565 | } 566 | return this; 567 | }, 568 | 569 | updateLabelContent: function (content) { 570 | if (this.label) { 571 | this.label.setContent(content); 572 | } 573 | }, 574 | 575 | _showLabel: function (e) { 576 | this.label.setLatLng(e.latlng); 577 | this._map.showLabel(this.label); 578 | }, 579 | 580 | _moveLabel: function (e) { 581 | this.label.setLatLng(e.latlng); 582 | }, 583 | 584 | _hideLabel: function () { 585 | this.label.close(); 586 | } 587 | }); 588 | 589 | 590 | L.Map.include({ 591 | showLabel: function (label) { 592 | return this.addLayer(label); 593 | } 594 | }); 595 | 596 | L.FeatureGroup.include({ 597 | // TODO: remove this when AOP is supported in Leaflet, need this as we cannot put code in removeLayer() 598 | clearLayers: function () { 599 | this.unbindLabel(); 600 | this.eachLayer(this.removeLayer, this); 601 | return this; 602 | }, 603 | 604 | bindLabel: function (content, options) { 605 | return this.invoke('bindLabel', content, options); 606 | }, 607 | 608 | unbindLabel: function () { 609 | //return this.invoke('unbindLabel'); 610 | return this.invoke('hideLabel'); 611 | }, 612 | 613 | updateLabelContent: function (content) { 614 | this.invoke('updateLabelContent', content); 615 | } 616 | }); 617 | 618 | 619 | return LeafletLabel; 620 | }, window)); 621 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-label-0.2.2/leaflet.label.css: -------------------------------------------------------------------------------- 1 | .leaflet-label { 2 | background: rgb(235, 235, 235); 3 | background: rgba(235, 235, 235, 0.81); 4 | background-clip: padding-box; 5 | border-color: #777; 6 | border-color: rgba(0,0,0,0.45); 7 | border-radius: 4px; 8 | border-style: solid; 9 | border-width: 4px; 10 | color: #111; 11 | display: block; 12 | font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; 13 | font-weight: bold; 14 | padding: 1px 6px; 15 | position: absolute; 16 | -webkit-user-select: none; 17 | -moz-user-select: none; 18 | -ms-user-select: none; 19 | user-select: none; 20 | pointer-events: none; 21 | white-space: nowrap; 22 | z-index: 500; 23 | } 24 | 25 | .leaflet-label.leaflet-clickable { 26 | cursor: pointer; 27 | pointer-events: auto; 28 | } 29 | 30 | .leaflet-label:before, 31 | .leaflet-label:after { 32 | border-top: 6px solid transparent; 33 | border-bottom: 6px solid transparent; 34 | border-right: 6px solid transparent; 35 | content: none; 36 | position: absolute; 37 | top: 5px; 38 | } 39 | 40 | .leaflet-label:before { 41 | border-right: 6px solid black; 42 | border-right-color: inherit; 43 | left: -10px; 44 | } 45 | 46 | .leaflet-label:after { 47 | border-left: 6px solid black; 48 | border-left-color: inherit; 49 | right: -16px; 50 | } 51 | 52 | .leaflet-label-top:after, 53 | .leaflet-label-top:before { 54 | left: -50%; 55 | border-top-color: black; 56 | border-top-color: rgba(0,0,0,0.45); 57 | position: relative; 58 | top: 29px; 59 | } 60 | 61 | .leaflet-label-top:before { 62 | display: none; 63 | border-right-color: transparent; 64 | border-bottom-color: transparent; 65 | border-left-color: transparent; 66 | border-top-color: transparent; 67 | } 68 | 69 | .leaflet-label-top:after { 70 | content: ' '; 71 | border-right-color: transparent; 72 | border-bottom-color: transparent; 73 | border-left-color: transparent; 74 | } 75 | 76 | .leaflet-label-bottom:before { 77 | display: none; 78 | border-right-color: transparent; 79 | border-bottom-color: transparent; 80 | border-left-color: transparent; 81 | border-top-color: transparent; 82 | } 83 | 84 | .leaflet-label-bottom:after, 85 | .leaflet-label-bottom:before { 86 | left: -50%; 87 | border-bottom-color: black; 88 | border-bottom-color: rgba(0,0,0,0.45); 89 | position: relative; 90 | top: -28px; 91 | } 92 | 93 | .leaflet-label-bottom:after { 94 | border-right-color: transparent; 95 | border-top-color: transparent; 96 | border-left-color: transparent; 97 | } 98 | 99 | .leaflet-label-bottom:after, 100 | .leaflet-label-top:after, 101 | .leaflet-label-right:before, 102 | .leaflet-label-left:after { 103 | content: ""; 104 | } 105 | 106 | .leaflet-label.leaflet-label-text-only, 107 | .leaflet-label.leaflet-label-text-only:before, 108 | .leaflet-label.leaflet-label-text-only:after { 109 | background: none; 110 | border: none; 111 | } 112 | 113 | .leaflet-label.leaflet-label-text-only.leaflet-label-left { 114 | margin-right: -10px; 115 | } 116 | 117 | .leaflet-label.leaflet-label-text-only.leaflet-label-right { 118 | margin-left: -10px; 119 | } 120 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-label-0.2.2/leaflet.label.js: -------------------------------------------------------------------------------- 1 | /* 2 | Leaflet.label, a plugin that adds labels to markers and vectors for Leaflet powered maps. 3 | (c) 2012-2013, Jacob Toye, Smartrak 4 | 5 | https://github.com/Leaflet/Leaflet.label 6 | http://leafletjs.com 7 | https://github.com/jacobtoye 8 | */ 9 | !function(t,e){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof exports&&(module.exports=t(require("leaflet"))),"undefined"!=typeof e&&e.L&&(e.LeafletLabel=t(L))}(function(t){t.labelVersion="0.2.4";var e=t.Class.extend({includes:t.Mixin.Events,_directions:["top","right","bottom","left"],options:{className:"",clickable:!1,direction:"right",noHide:!1,offset:[12,-15],opacity:1,textsize:"10px",textOnly:!1,style:null,zoomAnimation:!0},initialize:function(e,i){t.setOptions(this,e),this._source=i,this._animated=t.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},_isOnMarker:function(){return this._source instanceof t.Marker},onAdd:function(e){this._map=e,this._pane=this.options.pane?e._panes[this.options.pane]:this._isOnMarker()?e._panes.markerPane:e._panes.popupPane,this._container||this._initLayout(),this._pane.appendChild(this._container),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity),e.on("moveend",this._onMoveEnd,this).on("viewreset",this._onViewReset,this),this._animated&&e.on("zoomanim",this._zoomAnimation,this),t.Browser.touch&&!this.options.noHide&&(t.DomEvent.on(this._container,"click",this.close,this),e.on("click",this.close,this))},onRemove:function(t){this._pane.removeChild(this._container),t.off({zoomanim:this._zoomAnimation,moveend:this._onMoveEnd,viewreset:this._onViewReset},this),this._removeInteraction(),this._map=null},setLatLng:function(e){return this._latlng=t.latLng(e),this._map&&this._updatePosition(),this},setContent:function(t){return this._previousContent=this._content,this._content=t,this._updateContent(),this},close:function(){var e=this._map;e&&(t.Browser.touch&&!this.options.noHide&&(t.DomEvent.off(this._container,"click",this.close),e.off("click",this.close,this)),e.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(e){this.options.opacity=e,this._container&&t.DomUtil.setOpacity(this._container,e)},_initLayout:function(){if(this._container=t.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this._container.style.fontSize=this.options.textsize,this.options.textOnly&&t.DomUtil.addClass(this._container,"leaflet-label-text-only"),this.options.style)for(var e in this.options.style)this.options.style.hasOwnProperty(e)&&(this._container.style[e]=this.options.style[e]);this.updateZIndex(this._zIndex)},_update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updatePosition(),this._container.style.visibility="")},_updateContent:function(){this._content&&this._map&&this._prevContent!==this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content,this._prevContent=this._content,this._labelWidth=this._container.offsetWidth)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_getIconHeight:function(){return this._source.options.icon?this._source.options.icon.options.iconSize[1]:0},_setPosition:function(e){var i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),s=i.layerPointToContainerPoint(e),a=this._getDirection(),h=this._labelWidth,l=t.point(this.options.offset),r=l.y;"top"===a?(r-=this._isOnMarker()?this._getIconHeight():0,e=e.add(t.point(-h/2,r))):"bottom"===a?(r+=this._isOnMarker?this._getIconHeight():0,e=e.add(t.point(-h/2,r))):"right"===a||"auto"===a&&s.x[1](#what-is-free) tile providers. 4 | 5 | # Usage 6 | Leaflet-providers [providers](#providers) are refered to with a `provider[.]`-string. Let's say you want to add the nice [Watercolor](http://maps.stamen.com/#watercolor/) style from Stamen to your map, you pass `Stamen.Watercolor` to the `L.tileLayer.provider`-constructor, which will return a [L.TileLayer](http://leafletjs.com/reference.html#tilelayer) instance for Stamens Watercolor tile layer. 7 | 8 | ```Javascript 9 | // add Stamen Watercolor to map. 10 | L.tileLayer.provider('Stamen.Watercolor').addTo(map); 11 | ``` 12 | 13 | ## Protocol relativity (`https://`-urls) 14 | 15 | Leaflet-providers tries to use `https://` if the page uses `https://` and the provider supports it. 16 | You can force the use of `http://` by passing `force_http: true` in the options argument. 17 | 18 | ## Retina tiles 19 | 20 | Some providers have retina tiles for which the URL only needs to be slightly adjusted, e.g. `-----@2x.png`. For this, add the retina option in the URL, e.g. `-----{retina}.png`, and set a retina value in the options, e.g. `retina: '@2x'`. If Leaflet detects a retina screen (`L.Browser.retina`), the retina option passed to the tileLayer is set to the value supplied, otherwise it's replaced by an empty string. 21 | 22 | # Providers 23 | 24 | Leaflet-providers provides tile layers from different providers, including *OpenStreetMap*, *Stamen*, *Esri* and *OpenWeatherMap*. The full listing of free to use layers can be [previewed](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). The page will show you the name to use with `leaflet-providers.js` and the code to use it without dependencies. 25 | 26 | ## Providers requiring registration 27 | 28 | In addition to the providers you are free1 to use, we support some layers which require registration. 29 | 30 | ### HERE (formerly Nokia). 31 | 32 | In order to use HERE layers, you must [register](http://developer.here.com/). Once registered, you can create an `app_id` and `app_code` which you have to pass to `L.tileLayer.provider` in the options: 33 | 34 | ```Javascript 35 | L.tileLayer.provider('HERE.terrainDay', { 36 | app_id: '', 37 | app_code: '' 38 | }).addTo(map); 39 | ``` 40 | 41 | [Available HERE layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=HERE) 42 | 43 | ### Mapbox 44 | 45 | In order to use Mapbox maps, you must [register](https://tiles.mapbox.com/signup). You can get map ID and ACCESS_TOKEN from [Mapbox projects](https://www.mapbox.com/projects): 46 | ```JavaScript 47 | L.tileLayer.provider('MapBox', {id: 'ID', accessToken: 'ACCESS_TOKEN'}).addTo(map); 48 | ``` 49 | 50 | ### Esri/ArcGIS 51 | 52 | In order to use ArcGIS maps, you must [register](https://developers.arcgis.com/en/sign-up/) and abide by the [terms of service](https://developers.arcgis.com/en/terms/). No special syntax is required. 53 | 54 | [Available Esri layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=Esri) 55 | 56 | # Attribution 57 | 58 | This work was inspired from , and originally created by [Stefan Seelmann](https://github.com/seelmann). 59 | 60 | ### What do we mean by *free*? 61 | 1 62 | We try to maintain leaflet-providers in such a way that you'll be able to use the layers we include without paying money. 63 | This doesn't mean no limits apply, you should always check before using these layers for anything serious. 64 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-providers", 3 | "version": "1.1.15", 4 | "homepage": "https://github.com/leaflet-extras/leaflet-providers", 5 | "description": "An extension to Leaflet that contains configurations for various free tile providers.", 6 | "dependencies": { 7 | "leaflet": "~0.7.3" 8 | }, 9 | "main": "leaflet-providers.js", 10 | "keywords": [ 11 | "leaflet", 12 | "stamen", 13 | "osm" 14 | ], 15 | "license": "BSD-2-Clause", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests", 22 | "preview", 23 | "*.html" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/css/gh-fork-ribbon.css: -------------------------------------------------------------------------------- 1 | /* Left will inherit from right (so we don't need to duplicate code */ 2 | .github-fork-ribbon { 3 | /* The right and left lasses determine the side we attach our banner to */ 4 | position: absolute; 5 | 6 | /* Add a bit of padding to give some substance outside the "stitching" */ 7 | padding: 2px 0; 8 | 9 | /* Set the base colour */ 10 | background-color: #a00; 11 | 12 | /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ 13 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15))); 14 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); 15 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); 16 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); 17 | background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); 18 | background-image: linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); 19 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000'); 20 | 21 | /* Add a drop shadow */ 22 | -webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); 23 | box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); 24 | 25 | z-index: 9999; 26 | } 27 | 28 | .github-fork-ribbon a { 29 | /* Set the font */ 30 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 31 | font-size: 13px; 32 | font-weight: 700; 33 | color: white; 34 | 35 | /* Set the text properties */ 36 | text-decoration: none; 37 | text-shadow: 0 -1px rgba(0,0,0,0.5); 38 | text-align: center; 39 | 40 | /* Set the geometry. If you fiddle with these you'll also need to tweak the top and right values in #github-fork-ribbon. */ 41 | width: 200px; 42 | line-height: 20px; 43 | 44 | /* Set the layout properties */ 45 | display: inline-block; 46 | padding: 2px 0; 47 | 48 | /* Add "stitching" effect */ 49 | border-width: 1px 0; 50 | border-style: dotted; 51 | border-color: rgba(255,255,255,0.7); 52 | } 53 | 54 | .github-fork-ribbon-wrapper { 55 | width: 150px; 56 | height: 150px; 57 | position: absolute; 58 | overflow: hidden; 59 | top: 0; 60 | } 61 | 62 | .github-fork-ribbon-wrapper.left { 63 | left: 0; 64 | } 65 | 66 | .github-fork-ribbon-wrapper.right { 67 | right: 0; 68 | } 69 | 70 | .github-fork-ribbon-wrapper.left-bottom { 71 | position: fixed; 72 | top: inherit; 73 | bottom: 0; 74 | left: 0; 75 | } 76 | 77 | .github-fork-ribbon-wrapper.right-bottom { 78 | position: fixed; 79 | top: inherit; 80 | bottom: 0; 81 | right: 0; 82 | } 83 | 84 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 85 | top: 42px; 86 | right: -43px; 87 | 88 | /* Rotate the banner 45 degrees */ 89 | -webkit-transform: rotate(45deg); 90 | -moz-transform: rotate(45deg); 91 | -o-transform: rotate(45deg); 92 | transform: rotate(45deg); 93 | } 94 | 95 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 96 | top: 42px; 97 | left: -43px; 98 | 99 | /* Rotate the banner -45 degrees */ 100 | -webkit-transform: rotate(-45deg); 101 | -moz-transform: rotate(-45deg); 102 | -o-transform: rotate(-45deg); 103 | transform: rotate(-45deg); 104 | } 105 | 106 | 107 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 108 | top: 80px; 109 | left: -43px; 110 | 111 | /* Rotate the banner -45 degrees */ 112 | -webkit-transform: rotate(45deg); 113 | -moz-transform: rotate(45deg); 114 | -o-transform: rotate(45deg); 115 | transform: rotate(45deg); 116 | } 117 | 118 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 119 | top: 80px; 120 | right: -43px; 121 | 122 | /* Rotate the banner -45 degrees */ 123 | -webkit-transform: rotate(-45deg); 124 | -moz-transform: rotate(-45deg); 125 | -o-transform: rotate(-45deg); 126 | transform: rotate(-45deg); 127 | } -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/css/gh-fork-ribbon.ie.css: -------------------------------------------------------------------------------- 1 | /* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and 2 | * http://www.useragentman.com/IETransformsTranslator */ 3 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 4 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 5 | top: -22px; 6 | right: -62px; 7 | 8 | /* IE8+ */ 9 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 10 | /* IE6 and 7 */ 11 | filter: progid:DXImageTransform.Microsoft.Matrix( 12 | M11=0.7071067811865474, 13 | M12=-0.7071067811865477, 14 | M21=0.7071067811865477, 15 | M22=0.7071067811865474, 16 | SizingMethod='auto expand' 17 | ); 18 | } 19 | 20 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 21 | top: -22px; 22 | left: -22px; 23 | 24 | /* IE8+ */ 25 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 26 | /* IE6 and 7 */ 27 | filter: progid:DXImageTransform.Microsoft.Matrix( 28 | M11=0.7071067811865483, 29 | M12=0.7071067811865467, 30 | M21=-0.7071067811865467, 31 | M22=0.7071067811865483, 32 | SizingMethod='auto expand' 33 | ); 34 | } 35 | 36 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 37 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 38 | top: 12px; 39 | left: -22px; 40 | 41 | 42 | /* IE8+ */ 43 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 44 | /* IE6 and 7 */ 45 | /* filter: progid:DXImageTransform.Microsoft.Matrix( 46 | M11=0.7071067811865474, 47 | M12=-0.7071067811865477, 48 | M21=0.7071067811865477, 49 | M22=0.7071067811865474, 50 | SizingMethod='auto expand' 51 | ); 52 | */} 53 | 54 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 55 | top: 12px; 56 | right: -62px; 57 | 58 | /* IE8+ */ 59 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 60 | /* IE6 and 7 */ 61 | filter: progid:DXImageTransform.Microsoft.Matrix( 62 | M11=0.7071067811865483, 63 | M12=0.7071067811865467, 64 | M21=-0.7071067811865467, 65 | M22=0.7071067811865483, 66 | SizingMethod='auto expand' 67 | ); 68 | } -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/leaflet-providers.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | // AMD. Register as an anonymous module. 4 | define(['leaflet'], factory); 5 | } else if (typeof modules === 'object' && module.exports) { 6 | // define a Common JS module that relies on 'leaflet' 7 | module.exports = factory(require('leaflet')); 8 | } else { 9 | // Assume Leaflet is loaded into global object L already 10 | factory(L); 11 | } 12 | }(this, function (L) { 13 | 'use strict'; 14 | 15 | L.TileLayer.Provider = L.TileLayer.extend({ 16 | initialize: function (arg, options) { 17 | var providers = L.TileLayer.Provider.providers; 18 | 19 | var parts = arg.split('.'); 20 | 21 | var providerName = parts[0]; 22 | var variantName = parts[1]; 23 | 24 | if (!providers[providerName]) { 25 | throw 'No such provider (' + providerName + ')'; 26 | } 27 | 28 | var provider = { 29 | url: providers[providerName].url, 30 | options: providers[providerName].options 31 | }; 32 | 33 | // overwrite values in provider from variant. 34 | if (variantName && 'variants' in providers[providerName]) { 35 | if (!(variantName in providers[providerName].variants)) { 36 | throw 'No such variant of ' + providerName + ' (' + variantName + ')'; 37 | } 38 | var variant = providers[providerName].variants[variantName]; 39 | var variantOptions; 40 | if (typeof variant === 'string') { 41 | variantOptions = { 42 | variant: variant 43 | }; 44 | } else { 45 | variantOptions = variant.options; 46 | } 47 | provider = { 48 | url: variant.url || provider.url, 49 | options: L.Util.extend({}, provider.options, variantOptions) 50 | }; 51 | } 52 | 53 | var forceHTTP = window.location.protocol === 'file:' || provider.options.forceHTTP; 54 | if (provider.url.indexOf('//') === 0 && forceHTTP) { 55 | provider.url = 'http:' + provider.url; 56 | } 57 | 58 | // If retina option is set 59 | if (provider.options.retina) { 60 | // Check retina screen 61 | if (options.detectRetina && L.Browser.retina) { 62 | // The retina option will be active now 63 | // But we need to prevent Leaflet retina mode 64 | options.detectRetina = false; 65 | } else { 66 | // No retina, remove option 67 | provider.options.retina = ''; 68 | } 69 | } 70 | 71 | // replace attribution placeholders with their values from toplevel provider attribution, 72 | // recursively 73 | var attributionReplacer = function (attr) { 74 | if (attr.indexOf('{attribution.') === -1) { 75 | return attr; 76 | } 77 | return attr.replace(/\{attribution.(\w*)\}/, 78 | function (match, attributionName) { 79 | return attributionReplacer(providers[attributionName].options.attribution); 80 | } 81 | ); 82 | }; 83 | provider.options.attribution = attributionReplacer(provider.options.attribution); 84 | 85 | // Compute final options combining provider options with any user overrides 86 | var layerOpts = L.Util.extend({}, provider.options, options); 87 | L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts); 88 | } 89 | }); 90 | 91 | /** 92 | * Definition of providers. 93 | * see http://leafletjs.com/reference.html#tilelayer for options in the options map. 94 | */ 95 | 96 | L.TileLayer.Provider.providers = { 97 | OpenStreetMap: { 98 | url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 99 | options: { 100 | maxZoom: 19, 101 | attribution: 102 | '© OpenStreetMap' 103 | }, 104 | variants: { 105 | Mapnik: {}, 106 | BlackAndWhite: { 107 | url: 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', 108 | options: { 109 | maxZoom: 18 110 | } 111 | }, 112 | DE: { 113 | url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', 114 | options: { 115 | maxZoom: 18 116 | } 117 | }, 118 | France: { 119 | url: '//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', 120 | options: { 121 | maxZoom: 20, 122 | attribution: '© Openstreetmap France | {attribution.OpenStreetMap}' 123 | } 124 | }, 125 | HOT: { 126 | url: '//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', 127 | options: { 128 | attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Humanitarian OpenStreetMap Team' 129 | } 130 | } 131 | } 132 | }, 133 | OpenSeaMap: { 134 | url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 135 | options: { 136 | attribution: 'Map data: © OpenSeaMap contributors' 137 | } 138 | }, 139 | OpenTopoMap: { 140 | url: '//{s}.tile.opentopomap.org/{z}/{x}/{y}.png', 141 | options: { 142 | maxZoom: 17, 143 | attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)' 144 | } 145 | }, 146 | Thunderforest: { 147 | url: '//{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png', 148 | options: { 149 | attribution: 150 | '© Thunderforest, {attribution.OpenStreetMap}', 151 | variant: 'cycle' 152 | }, 153 | variants: { 154 | OpenCycleMap: 'cycle', 155 | Transport: { 156 | options: { 157 | variant: 'transport', 158 | maxZoom: 19 159 | } 160 | }, 161 | TransportDark: { 162 | options: { 163 | variant: 'transport-dark', 164 | maxZoom: 19 165 | } 166 | }, 167 | SpinalMap: { 168 | options: { 169 | variant: 'spinal-map', 170 | maxZoom: 11 171 | } 172 | }, 173 | Landscape: 'landscape', 174 | Outdoors: 'outdoors', 175 | Pioneer: 'pioneer' 176 | } 177 | }, 178 | OpenMapSurfer: { 179 | url: 'http://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}', 180 | options: { 181 | maxZoom: 20, 182 | variant: 'roads', 183 | attribution: 'Imagery from GIScience Research Group @ University of Heidelberg — Map data {attribution.OpenStreetMap}' 184 | }, 185 | variants: { 186 | Roads: 'roads', 187 | AdminBounds: { 188 | options: { 189 | variant: 'adminb', 190 | maxZoom: 19 191 | } 192 | }, 193 | Grayscale: { 194 | options: { 195 | variant: 'roadsg', 196 | maxZoom: 19 197 | } 198 | } 199 | } 200 | }, 201 | Hydda: { 202 | url: '//{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png', 203 | options: { 204 | variant: 'full', 205 | attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}' 206 | }, 207 | variants: { 208 | Full: 'full', 209 | Base: 'base', 210 | RoadsAndLabels: 'roads_and_labels' 211 | } 212 | }, 213 | MapBox: { 214 | url: '//api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', 215 | options: { 216 | attribution: 217 | 'Imagery from MapBox — ' + 218 | 'Map data {attribution.OpenStreetMap}', 219 | subdomains: 'abcd' 220 | } 221 | }, 222 | Stamen: { 223 | url: '//stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', 224 | options: { 225 | attribution: 226 | 'Map tiles by Stamen Design, ' + 227 | 'CC BY 3.0 — ' + 228 | 'Map data {attribution.OpenStreetMap}', 229 | subdomains: 'abcd', 230 | minZoom: 0, 231 | maxZoom: 20, 232 | variant: 'toner', 233 | ext: 'png' 234 | }, 235 | variants: { 236 | Toner: 'toner', 237 | TonerBackground: 'toner-background', 238 | TonerHybrid: 'toner-hybrid', 239 | TonerLines: 'toner-lines', 240 | TonerLabels: 'toner-labels', 241 | TonerLite: 'toner-lite', 242 | Watercolor: { 243 | options: { 244 | variant: 'watercolor', 245 | minZoom: 1, 246 | maxZoom: 16 247 | } 248 | }, 249 | Terrain: { 250 | options: { 251 | variant: 'terrain', 252 | minZoom: 0, 253 | maxZoom: 18 254 | } 255 | }, 256 | TerrainBackground: { 257 | options: { 258 | variant: 'terrain-background', 259 | minZoom: 0, 260 | maxZoom: 18 261 | } 262 | }, 263 | TopOSMRelief: { 264 | options: { 265 | variant: 'toposm-color-relief', 266 | ext: 'jpg', 267 | bounds: [[22, -132], [51, -56]] 268 | } 269 | }, 270 | TopOSMFeatures: { 271 | options: { 272 | variant: 'toposm-features', 273 | bounds: [[22, -132], [51, -56]], 274 | opacity: 0.9 275 | } 276 | } 277 | } 278 | }, 279 | Esri: { 280 | url: '//server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}', 281 | options: { 282 | variant: 'World_Street_Map', 283 | attribution: 'Tiles © Esri' 284 | }, 285 | variants: { 286 | WorldStreetMap: { 287 | options: { 288 | attribution: 289 | '{attribution.Esri} — ' + 290 | 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' 291 | } 292 | }, 293 | DeLorme: { 294 | options: { 295 | variant: 'Specialty/DeLorme_World_Base_Map', 296 | minZoom: 1, 297 | maxZoom: 11, 298 | attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme' 299 | } 300 | }, 301 | WorldTopoMap: { 302 | options: { 303 | variant: 'World_Topo_Map', 304 | attribution: 305 | '{attribution.Esri} — ' + 306 | 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community' 307 | } 308 | }, 309 | WorldImagery: { 310 | options: { 311 | variant: 'World_Imagery', 312 | attribution: 313 | '{attribution.Esri} — ' + 314 | 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' 315 | } 316 | }, 317 | WorldTerrain: { 318 | options: { 319 | variant: 'World_Terrain_Base', 320 | maxZoom: 13, 321 | attribution: 322 | '{attribution.Esri} — ' + 323 | 'Source: USGS, Esri, TANA, DeLorme, and NPS' 324 | } 325 | }, 326 | WorldShadedRelief: { 327 | options: { 328 | variant: 'World_Shaded_Relief', 329 | maxZoom: 13, 330 | attribution: '{attribution.Esri} — Source: Esri' 331 | } 332 | }, 333 | WorldPhysical: { 334 | options: { 335 | variant: 'World_Physical_Map', 336 | maxZoom: 8, 337 | attribution: '{attribution.Esri} — Source: US National Park Service' 338 | } 339 | }, 340 | OceanBasemap: { 341 | options: { 342 | variant: 'Ocean_Basemap', 343 | maxZoom: 13, 344 | attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri' 345 | } 346 | }, 347 | NatGeoWorldMap: { 348 | options: { 349 | variant: 'NatGeo_World_Map', 350 | maxZoom: 16, 351 | attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC' 352 | } 353 | }, 354 | WorldGrayCanvas: { 355 | options: { 356 | variant: 'Canvas/World_Light_Gray_Base', 357 | maxZoom: 16, 358 | attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ' 359 | } 360 | } 361 | } 362 | }, 363 | OpenWeatherMap: { 364 | url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png', 365 | options: { 366 | maxZoom: 19, 367 | attribution: 'Map data © OpenWeatherMap', 368 | opacity: 0.5 369 | }, 370 | variants: { 371 | Clouds: 'clouds', 372 | CloudsClassic: 'clouds_cls', 373 | Precipitation: 'precipitation', 374 | PrecipitationClassic: 'precipitation_cls', 375 | Rain: 'rain', 376 | RainClassic: 'rain_cls', 377 | Pressure: 'pressure', 378 | PressureContour: 'pressure_cntr', 379 | Wind: 'wind', 380 | Temperature: 'temp', 381 | Snow: 'snow' 382 | } 383 | }, 384 | HERE: { 385 | /* 386 | * HERE maps, formerly Nokia maps. 387 | * These basemaps are free, but you need an API key. Please sign up at 388 | * http://developer.here.com/getting-started 389 | * 390 | * Note that the base urls contain '.cit' whichs is HERE's 391 | * 'Customer Integration Testing' environment. Please remove for production 392 | * envirionments. 393 | */ 394 | url: 395 | '//{s}.{base}.maps.cit.api.here.com/maptile/2.1/' + 396 | '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + 397 | 'app_id={app_id}&app_code={app_code}&lg={language}', 398 | options: { 399 | attribution: 400 | 'Map © 1987-2014 HERE', 401 | subdomains: '1234', 402 | mapID: 'newest', 403 | 'app_id': '', 404 | 'app_code': '', 405 | base: 'base', 406 | variant: 'normal.day', 407 | maxZoom: 20, 408 | type: 'maptile', 409 | language: 'eng', 410 | format: 'png8', 411 | size: '256' 412 | }, 413 | variants: { 414 | normalDay: 'normal.day', 415 | normalDayCustom: 'normal.day.custom', 416 | normalDayGrey: 'normal.day.grey', 417 | normalDayMobile: 'normal.day.mobile', 418 | normalDayGreyMobile: 'normal.day.grey.mobile', 419 | normalDayTransit: 'normal.day.transit', 420 | normalDayTransitMobile: 'normal.day.transit.mobile', 421 | normalNight: 'normal.night', 422 | normalNightMobile: 'normal.night.mobile', 423 | normalNightGrey: 'normal.night.grey', 424 | normalNightGreyMobile: 'normal.night.grey.mobile', 425 | 426 | basicMap: { 427 | options: { 428 | type: 'basetile' 429 | } 430 | }, 431 | mapLabels: { 432 | options: { 433 | type: 'labeltile', 434 | format: 'png' 435 | } 436 | }, 437 | trafficFlow: { 438 | options: { 439 | base: 'traffic', 440 | type: 'flowtile' 441 | } 442 | }, 443 | carnavDayGrey: 'carnav.day.grey', 444 | hybridDay: { 445 | options: { 446 | base: 'aerial', 447 | variant: 'hybrid.day' 448 | } 449 | }, 450 | hybridDayMobile: { 451 | options: { 452 | base: 'aerial', 453 | variant: 'hybrid.day.mobile' 454 | } 455 | }, 456 | pedestrianDay: 'pedestrian.day', 457 | pedestrianNight: 'pedestrian.night', 458 | satelliteDay: { 459 | options: { 460 | base: 'aerial', 461 | variant: 'satellite.day' 462 | } 463 | }, 464 | terrainDay: { 465 | options: { 466 | base: 'aerial', 467 | variant: 'terrain.day' 468 | } 469 | }, 470 | terrainDayMobile: { 471 | options: { 472 | base: 'aerial', 473 | variant: 'terrain.day.mobile' 474 | } 475 | } 476 | } 477 | }, 478 | FreeMapSK: { 479 | url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg', 480 | options: { 481 | minZoom: 8, 482 | maxZoom: 16, 483 | subdomains: '1234', 484 | bounds: [[47.204642, 15.996093], [49.830896, 22.576904]], 485 | attribution: 486 | '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk' 487 | } 488 | }, 489 | MtbMap: { 490 | url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', 491 | options: { 492 | attribution: 493 | '{attribution.OpenStreetMap} & USGS' 494 | } 495 | }, 496 | CartoDB: { 497 | url: 'http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png', 498 | options: { 499 | attribution: '{attribution.OpenStreetMap} © CartoDB', 500 | subdomains: 'abcd', 501 | maxZoom: 19, 502 | variant: 'light_all' 503 | }, 504 | variants: { 505 | Positron: 'light_all', 506 | PositronNoLabels: 'light_nolabels', 507 | PositronOnlyLabels: 'light_only_labels', 508 | DarkMatter: 'dark_all', 509 | DarkMatterNoLabels: 'dark_nolabels', 510 | DarkMatterOnlyLabels: 'dark_only_labels' 511 | } 512 | }, 513 | HikeBike: { 514 | url: 'http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png', 515 | options: { 516 | maxZoom: 19, 517 | attribution: '{attribution.OpenStreetMap}', 518 | variant: 'hikebike' 519 | }, 520 | variants: { 521 | HikeBike: {}, 522 | HillShading: { 523 | options: { 524 | maxZoom: 15, 525 | variant: 'hillshading' 526 | } 527 | } 528 | } 529 | }, 530 | BasemapAT: { 531 | url: '//maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}', 532 | options: { 533 | maxZoom: 19, 534 | attribution: 'Datenquelle: basemap.at', 535 | subdomains: ['', '1', '2', '3', '4'], 536 | format: 'png', 537 | bounds: [[46.358770, 8.782379], [49.037872, 17.189532]], 538 | variant: 'geolandbasemap' 539 | }, 540 | variants: { 541 | basemap: 'geolandbasemap', 542 | grau: 'bmapgrau', 543 | overlay: 'bmapoverlay', 544 | highdpi: { 545 | options: { 546 | variant: 'bmaphidpi', 547 | format: 'jpeg' 548 | } 549 | }, 550 | orthofoto: { 551 | options: { 552 | variant: 'bmaporthofoto30cm', 553 | format: 'jpeg' 554 | } 555 | } 556 | } 557 | }, 558 | NASAGIBS: { 559 | url: '//map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}', 560 | options: { 561 | attribution: 562 | 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' + 563 | '(ESDIS) with funding provided by NASA/HQ.', 564 | bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], 565 | minZoom: 1, 566 | maxZoom: 9, 567 | format: 'jpg', 568 | time: '', 569 | tilematrixset: 'GoogleMapsCompatible_Level' 570 | }, 571 | variants: { 572 | ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor', 573 | ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367', 574 | ViirsEarthAtNight2012: { 575 | options: { 576 | variant: 'VIIRS_CityLights_2012', 577 | maxZoom: 8 578 | } 579 | }, 580 | ModisTerraLSTDay: { 581 | options: { 582 | variant: 'MODIS_Terra_Land_Surface_Temp_Day', 583 | format: 'png', 584 | maxZoom: 7, 585 | opacity: 0.75 586 | } 587 | }, 588 | ModisTerraSnowCover: { 589 | options: { 590 | variant: 'MODIS_Terra_Snow_Cover', 591 | format: 'png', 592 | maxZoom: 8, 593 | opacity: 0.75 594 | } 595 | }, 596 | ModisTerraAOD: { 597 | options: { 598 | variant: 'MODIS_Terra_Aerosol', 599 | format: 'png', 600 | maxZoom: 6, 601 | opacity: 0.75 602 | } 603 | }, 604 | ModisTerraChlorophyll: { 605 | options: { 606 | variant: 'MODIS_Terra_Chlorophyll_A', 607 | format: 'png', 608 | maxZoom: 7, 609 | opacity: 0.75 610 | } 611 | } 612 | } 613 | }, 614 | NLS: { 615 | // NLS maps are copyright National library of Scotland. 616 | // http://maps.nls.uk/projects/api/index.html 617 | // Please contact NLS for anything other than non-commercial low volume usage 618 | // 619 | // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s 620 | // z0-9 - 1:1m 621 | // z10-11 - quarter inch (1:253440) 622 | // z12-18 - one inch (1:63360) 623 | url: '//nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', 624 | options: { 625 | attribution: 'National Library of Scotland Historic Maps', 626 | bounds: [[49.6, -12], [61.7, 3]], 627 | minZoom: 1, 628 | maxZoom: 18, 629 | subdomains: '0123', 630 | } 631 | } 632 | }; 633 | 634 | L.tileLayer.provider = function (provider, options) { 635 | return new L.TileLayer.Provider(provider, options); 636 | }; 637 | 638 | return L; 639 | })); 640 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/license.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Leaflet Providers contributors 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | _THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._ -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-providers", 3 | "version": "1.1.15", 4 | "description": "An extension to Leaflet that contains configurations for various free tile providers.", 5 | "main": "leaflet-providers.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/leaflet-extras/leaflet-providers.git" 9 | }, 10 | "scripts": { 11 | "test": "npm run lint && npm run testsuite", 12 | "testsuite": "mocha-phantomjs tests/index.html", 13 | "lint": "eslint --config .eslintrc leaflet-providers.js index.html preview/*.js preview/*.html tests/*", 14 | "min": "uglifyjs leaflet-providers.js -mc -o leaflet-providers.min.js", 15 | "release": "mversion patch -m" 16 | }, 17 | "license": "BSD-2-Clause", 18 | "bugs": { 19 | "url": "https://github.com/leaflet-extras/leaflet-providers/issues" 20 | }, 21 | "files": [ 22 | "leaflet-providers.js", 23 | "README.md", 24 | "CHANGELOG.md", 25 | "licence.md" 26 | ], 27 | "devDependencies": { 28 | "chai": "^2.3.0", 29 | "eslint": "^2.7.0", 30 | "eslint-plugin-html": "^1.4.0", 31 | "mocha": "^2.2.4", 32 | "mocha-phantomjs": "^3.5.3", 33 | "mversion": "^1.3.0", 34 | "phantomjs": "1.9.7-15", 35 | "uglify-js": "^2.4.15" 36 | }, 37 | "autoupdate": { 38 | "source": "git", 39 | "target": "git://github.com/leaflet-extras/leaflet-providers.git", 40 | "basePath": "/", 41 | "files": [ 42 | "leaflet-providers.js" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-1.0.27/providers.json: -------------------------------------------------------------------------------- 1 | { 2 | "OpenStreetMap": { 3 | "url": "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", 4 | "options": { 5 | "maxZoom": 19, 6 | "attribution": 7 | "© OpenStreetMap" 8 | }, 9 | "variants": { 10 | "Mapnik": {}, 11 | "BlackAndWhite": { 12 | "url": "http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png", 13 | "options": { 14 | "maxZoom": 18 15 | } 16 | }, 17 | "DE": { 18 | "url": "http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png", 19 | "options": { 20 | "maxZoom": 18 21 | } 22 | }, 23 | "France": { 24 | "url": "//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png", 25 | "options": { 26 | "maxZoom": 20, 27 | "attribution": "© Openstreetmap France | {attribution.OpenStreetMap}" 28 | } 29 | }, 30 | "HOT": { 31 | "url": "//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", 32 | "options": { 33 | "attribution": "{attribution.OpenStreetMap}, Tiles courtesy of Humanitarian OpenStreetMap Team" 34 | } 35 | } 36 | } 37 | }, 38 | "OpenSeaMap": { 39 | "url": "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png", 40 | "options": { 41 | "attribution": "Map data: © OpenSeaMap contributors" 42 | } 43 | }, 44 | "OpenTopoMap": { 45 | "url": "//{s}.tile.opentopomap.org/{z}/{x}/{y}.png", 46 | "options": { 47 | "maxZoom": 17, 48 | "attribution": "Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)" 49 | } 50 | }, 51 | "Thunderforest": { 52 | "url": "//{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png", 53 | "options": { 54 | "attribution": 55 | "© Thunderforest, {attribution.OpenStreetMap}", 56 | "variant": "cycle" 57 | }, 58 | "variants": { 59 | "OpenCycleMap": "cycle", 60 | "Transport": { 61 | "options": { 62 | "variant": "transport", 63 | "maxZoom": 19 64 | } 65 | }, 66 | "TransportDark": { 67 | "options": { 68 | "variant": "transport-dark", 69 | "maxZoom": 19 70 | } 71 | }, 72 | "SpinalMap": { 73 | "options": { 74 | "variant": "spinal-map", 75 | "maxZoom": 11 76 | } 77 | }, 78 | "Landscape": "landscape", 79 | "Outdoors": "outdoors", 80 | "Pioneer": "pioneer" 81 | } 82 | }, 83 | "OpenMapSurfer": { 84 | "url": "http://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}", 85 | "options": { 86 | "maxZoom": 20, 87 | "variant": "roads", 88 | "attribution": "Imagery from GIScience Research Group @ University of Heidelberg — Map data {attribution.OpenStreetMap}" 89 | }, 90 | "variants": { 91 | "Roads": "roads", 92 | "AdminBounds": { 93 | "options": { 94 | "variant": "adminb", 95 | "maxZoom": 19 96 | } 97 | }, 98 | "Grayscale": { 99 | "options": { 100 | "variant": "roadsg", 101 | "maxZoom": 19 102 | } 103 | } 104 | } 105 | }, 106 | "Hydda": { 107 | "url": "//{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png", 108 | "options": { 109 | "variant": "full", 110 | "attribution": "Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}" 111 | }, 112 | "variants": { 113 | "Full": "full", 114 | "Base": "base", 115 | "RoadsAndLabels": "roads_and_labels" 116 | } 117 | }, 118 | "MapBox": { 119 | "url": "//api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}", 120 | "options": { 121 | "attribution": "Imagery from MapBox — Map data {attribution.OpenStreetMap}", 122 | "subdomains": "abcd" 123 | } 124 | }, 125 | "Stamen": { 126 | "url": "//stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}", 127 | "options": { 128 | "attribution": "Map tiles by Stamen Design, CC BY 3.0 — Map data {attribution.OpenStreetMap}", 129 | "subdomains": "abcd", 130 | "minZoom": 0, 131 | "maxZoom": 20, 132 | "variant": "toner", 133 | "ext": "png" 134 | }, 135 | "variants": { 136 | "Toner": "toner", 137 | "TonerBackground": "toner-background", 138 | "TonerHybrid": "toner-hybrid", 139 | "TonerLines": "toner-lines", 140 | "TonerLabels": "toner-labels", 141 | "TonerLite": "toner-lite", 142 | "Watercolor": { 143 | "options": { 144 | "variant": "watercolor", 145 | "minZoom": 1, 146 | "maxZoom": 16 147 | } 148 | }, 149 | "Terrain": { 150 | "options": { 151 | "variant": "terrain", 152 | "minZoom": 0, 153 | "maxZoom": 18 154 | } 155 | }, 156 | "TerrainBackground": { 157 | "options": { 158 | "variant": "terrain-background", 159 | "minZoom": 0, 160 | "maxZoom": 18 161 | } 162 | }, 163 | "TopOSMRelief": { 164 | "options": { 165 | "variant": "toposm-color-relief", 166 | "ext": "jpg", 167 | "bounds": [[22, -132], [51, -56]] 168 | } 169 | }, 170 | "TopOSMFeatures": { 171 | "options": { 172 | "variant": "toposm-features", 173 | "bounds": [[22, -132], [51, -56]], 174 | "opacity": 0.9 175 | } 176 | } 177 | } 178 | }, 179 | "Esri": { 180 | "url": "//server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}", 181 | "options": { 182 | "variant": "World_Street_Map", 183 | "attribution": "Tiles © Esri" 184 | }, 185 | "variants": { 186 | "WorldStreetMap": { 187 | "options": { 188 | "attribution": 189 | "Tiles © Esri Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012" 190 | } 191 | }, 192 | "DeLorme": { 193 | "options": { 194 | "variant": "Specialty/DeLorme_World_Base_Map", 195 | "minZoom": 1, 196 | "maxZoom": 11, 197 | "attribution": "Tiles © Esri — Copyright: ©2012 DeLorme" 198 | } 199 | }, 200 | "WorldTopoMap": { 201 | "options": { 202 | "variant": "World_Topo_Map", 203 | "attribution": "Tiles © Esri Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community" 204 | } 205 | }, 206 | "WorldImagery": { 207 | "options": { 208 | "variant": "World_Imagery", 209 | "attribution": "Tiles © Esri Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community" 210 | } 211 | }, 212 | "WorldTerrain": { 213 | "options": { 214 | "variant": "World_Terrain_Base", 215 | "maxZoom": 13, 216 | "attribution": "Tiles © Esri Source: USGS, Esri, TANA, DeLorme, and NPS" 217 | } 218 | }, 219 | "WorldShadedRelief": { 220 | "options": { 221 | "variant": "World_Shaded_Relief", 222 | "maxZoom": 13, 223 | "attribution": "{attribution.Esri} — Source: Esri" 224 | } 225 | }, 226 | "WorldPhysical": { 227 | "options": { 228 | "variant": "World_Physical_Map", 229 | "maxZoom": 8, 230 | "attribution": "{attribution.Esri} — Source: US National Park Service" 231 | } 232 | }, 233 | "OceanBasemap": { 234 | "options": { 235 | "variant": "Ocean_Basemap", 236 | "maxZoom": 13, 237 | "attribution": "{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri" 238 | } 239 | }, 240 | "NatGeoWorldMap": { 241 | "options": { 242 | "variant": "NatGeo_World_Map", 243 | "maxZoom": 16, 244 | "attribution": "{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC" 245 | } 246 | }, 247 | "WorldGrayCanvas": { 248 | "options": { 249 | "variant": "Canvas/World_Light_Gray_Base", 250 | "maxZoom": 16, 251 | "attribution": "{attribution.Esri} — Esri, DeLorme, NAVTEQ" 252 | } 253 | } 254 | } 255 | }, 256 | "OpenWeatherMap": { 257 | "url": "http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png", 258 | "options": { 259 | "maxZoom": 19, 260 | "attribution": "Map data © OpenWeatherMap", 261 | "opacity": 0.5 262 | }, 263 | "variants": { 264 | "Clouds": "clouds", 265 | "CloudsClassic": "clouds_cls", 266 | "Precipitation": "precipitation", 267 | "PrecipitationClassic": "precipitation_cls", 268 | "Rain": "rain", 269 | "RainClassic": "rain_cls", 270 | "Pressure": "pressure", 271 | "PressureContour": "pressure_cntr", 272 | "Wind": "wind", 273 | "Temperature": "temp", 274 | "Snow": "snow" 275 | } 276 | }, 277 | "HERE": { 278 | "url": "//{s}.{base}.maps.cit.api.here.com/maptile/2.1/{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?app_id={app_id}&app_code={app_code}&lg={language}", 279 | "options": { 280 | "attribution": 281 | "Map © 1987-2014 HERE", 282 | "subdomains": "1234", 283 | "mapID": "newest", 284 | "app_id": "", 285 | "app_code": "", 286 | "base": "base", 287 | "variant": "normal.day", 288 | "maxZoom": 20, 289 | "type": "maptile", 290 | "language": "eng", 291 | "format": "png8", 292 | "size": "256" 293 | }, 294 | "variants": { 295 | "normalDay": "normal.day", 296 | "normalDayCustom": "normal.day.custom", 297 | "normalDayGrey": "normal.day.grey", 298 | "normalDayMobile": "normal.day.mobile", 299 | "normalDayGreyMobile": "normal.day.grey.mobile", 300 | "normalDayTransit": "normal.day.transit", 301 | "normalDayTransitMobile": "normal.day.transit.mobile", 302 | "normalNight": "normal.night", 303 | "normalNightMobile": "normal.night.mobile", 304 | "normalNightGrey": "normal.night.grey", 305 | "normalNightGreyMobile": "normal.night.grey.mobile", 306 | 307 | "basicMap": { 308 | "options": { 309 | "type": "basetile" 310 | } 311 | }, 312 | "mapLabels": { 313 | "options": { 314 | "type": "labeltile", 315 | "format": "png" 316 | } 317 | }, 318 | "trafficFlow": { 319 | "options": { 320 | "base": "traffic", 321 | "type": "flowtile" 322 | } 323 | }, 324 | "carnavDayGrey": "carnav.day.grey", 325 | "hybridDay": { 326 | "options": { 327 | "base": "aerial", 328 | "variant": "hybrid.day" 329 | } 330 | }, 331 | "hybridDayMobile": { 332 | "options": { 333 | "base": "aerial", 334 | "variant": "hybrid.day.mobile" 335 | } 336 | }, 337 | "pedestrianDay": "pedestrian.day", 338 | "pedestrianNight": "pedestrian.night", 339 | "satelliteDay": { 340 | "options": { 341 | "base": "aerial", 342 | "variant": "satellite.day" 343 | } 344 | }, 345 | "terrainDay": { 346 | "options": { 347 | "base": "aerial", 348 | "variant": "terrain.day" 349 | } 350 | }, 351 | "terrainDayMobile": { 352 | "options": { 353 | "base": "aerial", 354 | "variant": "terrain.day.mobile" 355 | } 356 | } 357 | } 358 | }, 359 | "FreeMapSK": { 360 | "url": "http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg", 361 | "options": { 362 | "minZoom": 8, 363 | "maxZoom": 16, 364 | "subdomains": "1234", 365 | "bounds": [[47.204642, 15.996093], [49.830896, 22.576904]], 366 | "attribution": 367 | "{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk" 368 | } 369 | }, 370 | "MtbMap": { 371 | "url": "http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png", 372 | "options": { 373 | "attribution": 374 | "{attribution.OpenStreetMap} & USGS" 375 | } 376 | }, 377 | "CartoDB": { 378 | "url": "http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png", 379 | "options": { 380 | "attribution": "{attribution.OpenStreetMap} © CartoDB", 381 | "subdomains": "abcd", 382 | "maxZoom": 19, 383 | "variant": "light_all" 384 | }, 385 | "variants": { 386 | "Positron": "light_all", 387 | "PositronNoLabels": "light_nolabels", 388 | "PositronOnlyLabels": "light_only_labels", 389 | "DarkMatter": "dark_all", 390 | "DarkMatterNoLabels": "dark_nolabels", 391 | "DarkMatterOnlyLabels": "dark_only_labels" 392 | } 393 | }, 394 | "HikeBike": { 395 | "url": "http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png", 396 | "options": { 397 | "maxZoom": 19, 398 | "attribution": "{attribution.OpenStreetMap}", 399 | "variant": "hikebike" 400 | }, 401 | "variants": { 402 | "HikeBike": {}, 403 | "HillShading": { 404 | "options": { 405 | "maxZoom": 15, 406 | "variant": "hillshading" 407 | } 408 | } 409 | } 410 | }, 411 | "BasemapAT": { 412 | "url": "//maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}", 413 | "options": { 414 | "maxZoom": 19, 415 | "attribution": "Datenquelle: basemap.at", 416 | "subdomains": ["", "1", "2", "3", "4"], 417 | "format": "png", 418 | "bounds": [[46.358770, 8.782379], [49.037872, 17.189532]], 419 | "variant": "geolandbasemap" 420 | }, 421 | "variants": { 422 | "basemap": "geolandbasemap", 423 | "grau": "bmapgrau", 424 | "overlay": "bmapoverlay", 425 | "highdpi": { 426 | "options": { 427 | "variant": "bmaphidpi", 428 | "format": "jpeg" 429 | } 430 | }, 431 | "orthofoto": { 432 | "options": { 433 | "variant": "bmaporthofoto30cm", 434 | "format": "jpeg" 435 | } 436 | } 437 | } 438 | }, 439 | "NASAGIBS": { 440 | "url": "//map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}", 441 | "options": { 442 | "attribution": 443 | "Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System (ESDIS) with funding provided by NASA/HQ.", 444 | "bounds": [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], 445 | "minZoom": 1, 446 | "maxZoom": 9, 447 | "format": "jpg", 448 | "time": "", 449 | "tilematrixset": "GoogleMapsCompatible_Level" 450 | }, 451 | "variants": { 452 | "ModisTerraTrueColorCR": "MODIS_Terra_CorrectedReflectance_TrueColor", 453 | "ModisTerraBands367CR": "MODIS_Terra_CorrectedReflectance_Bands367", 454 | "ViirsEarthAtNight2012": { 455 | "options": { 456 | "variant": "VIIRS_CityLights_2012", 457 | "maxZoom": 8 458 | } 459 | }, 460 | "ModisTerraLSTDay": { 461 | "options": { 462 | "variant": "MODIS_Terra_Land_Surface_Temp_Day", 463 | "format": "png", 464 | "maxZoom": 7, 465 | "opacity": 0.75 466 | } 467 | }, 468 | "ModisTerraSnowCover": { 469 | "options": { 470 | "variant": "MODIS_Terra_Snow_Cover", 471 | "format": "png", 472 | "maxZoom": 8, 473 | "opacity": 0.75 474 | } 475 | }, 476 | "ModisTerraAOD": { 477 | "options": { 478 | "variant": "MODIS_Terra_Aerosol", 479 | "format": "png", 480 | "maxZoom": 6, 481 | "opacity": 0.75 482 | } 483 | }, 484 | "ModisTerraChlorophyll": { 485 | "options": { 486 | "variant": "MODIS_Terra_Chlorophyll_A", 487 | "format": "png", 488 | "maxZoom": 7, 489 | "opacity": 0.75 490 | } 491 | } 492 | } 493 | }, 494 | "NLS": { 495 | "url": "//nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg", 496 | "options": { 497 | "attribution": "National Library of Scotland Historic Maps", 498 | "bounds": [[49.6, -12], [61.7, 3]], 499 | "minZoom": 1, 500 | "maxZoom": 18, 501 | "subdomains": "0123" 502 | } 503 | } 504 | } 505 | -------------------------------------------------------------------------------- /Materials/libs/leaflet-providers-plugin-1.1.0/leaflet-providers-plugin.js: -------------------------------------------------------------------------------- 1 | LeafletWidget.methods.addProviderTiles = function(provider, layerId, group, options) { 2 | this.layerManager.addLayer(L.tileLayer.provider(provider, options), "tile", layerId, group); 3 | }; 4 | -------------------------------------------------------------------------------- /Materials/libs/leafletfix-1.0.0/leafletfix.css: -------------------------------------------------------------------------------- 1 | /* Work around CSS properties introduced on img by bootstrap */ 2 | img.leaflet-tile { 3 | padding: 0; 4 | margin: 0; 5 | border-radius: 0; 6 | border: none; 7 | } 8 | .info { 9 | padding: 6px 8px; 10 | font: 14px/16px Arial, Helvetica, sans-serif; 11 | background: white; 12 | background: rgba(255,255,255,0.8); 13 | box-shadow: 0 0 15px rgba(0,0,0,0.2); 14 | border-radius: 5px; 15 | } 16 | .legend { 17 | line-height: 18px; 18 | color: #555; 19 | } 20 | .legend svg text { 21 | fill: #555; 22 | } 23 | .legend svg line { 24 | stroke: #555; 25 | } 26 | .legend i { 27 | width: 18px; 28 | height: 18px; 29 | float: left; 30 | margin-right: 8px; 31 | opacity: 0.7; 32 | } 33 | -------------------------------------------------------------------------------- /Materials/libs/remark-css-0.0.1/example.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); 3 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700); 4 | 5 | body { font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; } 6 | h1, h2, h3 { 7 | font-family: 'Yanone Kaffeesatz'; 8 | font-weight: normal; 9 | } 10 | a, a > code { 11 | color: rgb(249, 38, 114); 12 | text-decoration: none; 13 | } 14 | .footnote { 15 | position: absolute; 16 | bottom: 3em; 17 | padding-right: 4em; 18 | font-size: 90%; 19 | } 20 | .remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; } 21 | .remark-code-line-highlighted { background-color: #ffff88; } 22 | 23 | .inverse { 24 | background-color: #272822; 25 | color: #d6d6d6; 26 | text-shadow: 0 0 20px #333; 27 | } 28 | .inverse h1, .inverse h2, .inverse h3 { 29 | color: #f3f3f3; 30 | line-height: 1.0em; 31 | } 32 | /* Two-column layout */ 33 | .left-column { 34 | color: #777; 35 | width: 20%; 36 | height: 92%; 37 | float: left; 38 | } 39 | .left-column h2:last-of-type, .left-column h3:last-child { 40 | color: #000; 41 | } 42 | .right-column { 43 | width: 75%; 44 | float: right; 45 | padding-top: 1em; 46 | } 47 | .pull-left { 48 | float: left; 49 | width: 47%; 50 | } 51 | .pull-right { 52 | float: right; 53 | width: 47%; 54 | } 55 | .pull-right ~ * { 56 | clear: both; 57 | } 58 | img, video, iframe { 59 | max-width: 100%; 60 | } 61 | blockquote { 62 | border-left: solid 5px lightgray; 63 | padding-left: 1em; 64 | } 65 | table { 66 | margin: auto; 67 | border-top: 1px solid #666; 68 | border-bottom: 1px solid #666; 69 | } 70 | table thead th { border-bottom: 1px solid #ddd; } 71 | th, td { padding: 5px; } 72 | thead, tfoot, tr:nth-child(even) { background: #eee } 73 | 74 | @page { margin: 0; } 75 | @media print { 76 | .remark-slide-scaler { 77 | width: 100% !important; 78 | height: 100% !important; 79 | transform: scale(1) !important; 80 | top: 0 !important; 81 | left: 0 !important; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Materials/macros.js: -------------------------------------------------------------------------------- 1 | remark.macros.scale = function (percentage) { 2 | var url = this; 3 | return ''; 4 | }; 5 | -------------------------------------------------------------------------------- /Materials/mtheme_max.css: -------------------------------------------------------------------------------- 1 | a, a > code { 2 | color: #ff0000; 3 | text-decoration: none; 4 | } 5 | 6 | .footnote { 7 | position: absolute; 8 | bottom: 3em; 9 | padding-right: 4em; 10 | font-size: 90%; 11 | } 12 | .remark-code-line-highlighted { background-color: #ffff88; } 13 | 14 | .remark-slide-content { 15 | background-color: #FAFAFA; 16 | border-top: 80px solid #23373B; 17 | font-size: 20px; 18 | font-weight: 300; 19 | line-height: 1.5; 20 | padding: 1em 2em 1em 2em 21 | } 22 | 23 | .title-slide .inverse .remark-slide-content { 24 | background-color: #FAFAFA; 25 | } 26 | 27 | .inverse { 28 | background-color: #23373B; 29 | text-shadow: none; 30 | } 31 | .inverse h1, .inverse h2, .inverse h3 { 32 | color: #f3f3f3; 33 | } 34 | /* Two-column layout */ 35 | .left-column { 36 | color: #777; 37 | width: 20%; 38 | height: 92%; 39 | float: left; 40 | } 41 | .left-column h2:last-of-type, .left-column h3:last-child { 42 | color: #000; 43 | } 44 | .right-column { 45 | width: 75%; 46 | float: right; 47 | padding-top: 1em; 48 | } 49 | .pull-left { 50 | float: left; 51 | width: 47%; 52 | } 53 | .pull-right { 54 | float: right; 55 | width: 47%; 56 | } 57 | .pull-right ~ * { 58 | clear: both; 59 | } 60 | img, video, iframe { 61 | max-width: 100%; 62 | } 63 | blockquote { 64 | border-left: solid 5px lightgray; 65 | padding-left: 1em; 66 | } 67 | table { 68 | margin: auto; 69 | border-top: 1px solid #666; 70 | border-bottom: 1px solid #666; 71 | } 72 | table thead th { border-bottom: 1px solid #ddd; } 73 | th, td { padding: 5px; } 74 | thead, tfoot, tr:nth-child(even) { background: #eee } 75 | 76 | @page { margin: 0; } 77 | @media print { 78 | .remark-slide-scaler { 79 | width: 100% !important; 80 | height: 100% !important; 81 | transform: scale(1) !important; 82 | top: 0 !important; 83 | left: 0 !important; 84 | } 85 | } 86 | 87 | .remark-slide-content > h1 { 88 | font-family: 'Fira Sans'; 89 | font-weight: normal; 90 | font-size: 45px; 91 | margin-top: -95px; 92 | margin-left: -00px; 93 | color: #FAFAFA; 94 | } 95 | 96 | .remark-slide-content > inverse { 97 | width: 112px; 98 | height: 47px; 99 | border-bottom: 1px solid black; 100 | position: absolute; 101 | } 102 | 103 | .remark-slide-content > h2 { 104 | padding-top: -15px; 105 | padding-bottom: 00px; 106 | color: #1A292C; 107 | text-shadow: none; 108 | font-weight: 400; 109 | font-size: 35px; 110 | text-align: left; 111 | margin-left: 00px; 112 | } 113 | 114 | .remark-slide-content > h3 { 115 | padding-top: -15px; 116 | padding-bottom: 10px; 117 | color: #1A292C; 118 | text-shadow: none; 119 | font-weight: 400; 120 | font-size: 30px; 121 | text-align: left; 122 | margin-left: 00px; 123 | } 124 | 125 | .title-slide { 126 | background-color: #FAFAFA; 127 | border-top: 80px solid #FAFAFA; 128 | } 129 | 130 | .title-slide > h1 { 131 | color: #1A292C; 132 | font-size: 40px; 133 | text-shadow: none; 134 | font-weight: 400; 135 | text-align: left; 136 | margin-left: 15px; 137 | padding-top: 80px; 138 | } 139 | .title-slide > h2 { 140 | margin-top: -25px; 141 | padding-bottom: -20px; 142 | color: #1A292C; 143 | text-shadow: none; 144 | font-weight: 300; 145 | font-size: 35px; 146 | text-align: left; 147 | margin-left: 15px; 148 | } 149 | .title-slide > h3 { 150 | color: #1A292C; 151 | text-shadow: none; 152 | font-weight: 300; 153 | font-size: 25px; 154 | text-align: left; 155 | margin-left: 15px; 156 | margin-bottom: -30px; 157 | } 158 | 159 | .remark-slide-number { 160 | font-size: 13pt; 161 | font-family: 'Fira Sans'; 162 | color: #272822; 163 | opacity: 1; 164 | } 165 | .inverse .remark-slide-number { 166 | font-size: 13pt; 167 | font-family: 'Fira Sans'; 168 | color: #FAFAFA; 169 | opacity: 1; 170 | } 171 | 172 | /* turns off slide numbers for title page: https://github.com/gnab/remark/issues/298 */ 173 | .title-slide .remark-slide-number { 174 | display: none; 175 | } 176 | 177 | 178 | 179 | .title-hex{ 180 | height: 60px; 181 | align: middle; 182 | float: right; 183 | } 184 | 185 | -------------------------------------------------------------------------------- /Preparations/installs.R: -------------------------------------------------------------------------------- 1 | from_cran <- 2 | c("AmesHousing", "broom", "caret", "devtools", "doParallel", "e1071", "earth", 3 | "glmnet", "ipred", "klaR", "pROC", "rpart", "rsample", "sessioninfo", 4 | "tidyposterior", "tidyverse", "yardstick") 5 | 6 | install.packages(from_cran, repos = "http://cran.rstudio.com") 7 | 8 | library(devtools) 9 | 10 | install_github("topepo/recipes") 11 | 12 | # If you can install from source: 13 | install_github("topepo/caret", subdir = "pkg/caret") 14 | 15 | if(!interactive()) 16 | q("no") 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rstudio-conf-2017 2 | Slide, code and data for "Applied Machine Learning" at Rstudio-conf 2017 3 | --------------------------------------------------------------------------------