├── .gitignore ├── README.html ├── README.md ├── XaringanTutorial.Rproj ├── _config.yml ├── imgs ├── dark.jpg ├── deploy.jpg ├── du.gif ├── ggplot2.gif ├── gh1.png ├── gh2.png ├── github.PNG ├── icon.png ├── light.jpg ├── ml.gif ├── netlify.jpg ├── ocrug.jpeg ├── ocrug_logo.png ├── showcase.gif ├── step2.jpg ├── step3.jpg ├── step4.jpg ├── step5.jpg ├── su.gif ├── themelibs.PNG └── xaringan-animation.gif ├── index.Rmd ├── index.html ├── index_files ├── figure-html │ ├── unnamed-chunk-1-1.png │ ├── unnamed-chunk-10-1.png │ ├── unnamed-chunk-3-1.png │ ├── unnamed-chunk-8-1.png │ └── unnamed-chunk-9-1.png └── remark-css │ ├── default-fonts.css │ ├── default.css │ └── rladies.css ├── libs ├── Proj4Leaflet │ ├── proj4-compressed.js │ └── proj4leaflet.js ├── crosstalk │ ├── css │ │ └── crosstalk.css │ └── js │ │ ├── crosstalk.js │ │ ├── crosstalk.js.map │ │ ├── crosstalk.min.js │ │ └── crosstalk.min.js.map ├── datatables-binding │ └── datatables.js ├── datatables-css │ └── datatables-crosstalk.css ├── dt-core │ ├── css │ │ ├── jquery.dataTables.extra.css │ │ └── jquery.dataTables.min.css │ └── js │ │ └── jquery.dataTables.min.js ├── font-awesome │ ├── css │ │ ├── fontawesome-all.css │ │ └── fontawesome-all.min.css │ ├── less │ │ ├── _animated.less │ │ ├── _bordered-pulled.less │ │ ├── _core.less │ │ ├── _fixed-width.less │ │ ├── _icons.less │ │ ├── _larger.less │ │ ├── _list.less │ │ ├── _mixins.less │ │ ├── _rotated-flipped.less │ │ ├── _screen-reader.less │ │ ├── _shims.less │ │ ├── _stacked.less │ │ ├── _variables.less │ │ ├── brands.less │ │ ├── fontawesome.less │ │ ├── regular.less │ │ ├── solid.less │ │ └── v4-shims.less │ ├── scss │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _rotated-flipped.scss │ │ ├── _screen-reader.scss │ │ ├── _shims.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ ├── brands.scss │ │ ├── fontawesome.scss │ │ ├── regular.scss │ │ ├── solid.scss │ │ └── v4-shims.scss │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 ├── htmlwidgets │ └── htmlwidgets.js ├── jquery │ ├── LICENSE.txt │ └── jquery.min.js ├── leaflet-binding │ └── leaflet.js ├── leaflet │ ├── images │ │ ├── layers-2x.png │ │ ├── layers.png │ │ ├── marker-icon-2x.png │ │ ├── marker-icon.png │ │ └── marker-shadow.png │ ├── leaflet.css │ └── leaflet.js ├── leafletfix │ └── leafletfix.css ├── remark-css │ ├── default.css │ ├── lucy-fonts.css │ └── rladies.css └── rstudio_leaflet │ ├── images │ └── 1px.png │ └── rstudio_leaflet.css ├── my-style.css └── templates ├── xaringan-themer.css ├── xaringanthemer.Rmd ├── xaringanthemer.html └── yihui.Rmd /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XaringanTutorial 2 | 3 | 4 | A quick tutorial on making slides using xaringan 5 | 6 | 7 | GitHub Page: https://zhiiiyang.github.io/XaringanTutorial/ 8 | 9 | Netlify Page: https://xaringantutorial.netlify.com 10 | 11 | More about xaringan: 12 | 13 | ### Tutorials: 14 | - [Presentation Ninja ⚔ with xaringan](https://slides.yihui.name/xaringan/) 15 | - [Contribute to Open Source with Pretty Slides](http://www.datalorax.com/talks/cascadia18/#1) [(repo)](https://github.com/datalorax/site/tree/master/content/talks/cascadia18) 16 | - [Meet xaringan](https://arm.rbind.io/slides/xaringan.html) [(repo)](https://arm.rbind.io/days/day1/xaringan/) 17 | - [Making Slides in the Tada!-verse](https://apreshill.github.io/data-vis-labs-2018/slides/06-slides_xaringan.html#1) [(repo)](https://github.com/apreshill/data-vis-labs-2018/tree/master/slides) [(blog)](https://apreshill.github.io/data-vis-labs-2018/index.html) 18 | 19 | ### Themes: 20 | - [xaringan / remark js ninja themes](https://emitanaka.github.io/ninja-theme/) [(repo)](https://github.com/emitanaka/ninja-theme) 21 | - [Xaringan example RU template](https://www.jvcasillas.com/ru_xaringan/slides/index.html) [(repo)](https://github.com/jvcasillas/ru_xaringan) 22 | - [A theme for the University of Sydney](https://garthtarr.github.io/sydney_xaringan/) [(repo)](https://github.com/garthtarr/sydney_xaringan) 23 | - [xaringan template for Duke University Combined CSS Styles](https://dukeslides.johnlittle.info/slides/) [(repo)](https://github.com/libjohn/dukeslides) [(blog)](https://www.johnlittle.info/post/slide-template-using-duke-university-color-palette-xaringan/) 24 | 25 | ### Showcases: 26 | - [the ggplot flipbook](https://evamaerey.github.io/ggplot_flipbook/ggplot_flipbook_xaringan.html) [(repo)](https://github.com/EvaMaeRey/ggplot_flipbook) 27 | - [Machine Learning 101](https://sarahromanes.github.io/r-ladies-ML-1/) [(repo)](https://github.com/sarahromanes/r-ladies-ML-1) 28 | - [What I Wish I Knew When I Started R](https://www.williamrchase.com/slides/intro_r_anthropology_2018) 29 | 30 | ### Blogs: 31 | - [Animate Xaringan Slide Transitions](https://www.garrickadenbuie.com/blog/2018/12/03/animate-xaringan-slide-transitions/) 32 | - [Create awesome HTML slides with xaringan](http://www.favstats.eu/post/xaringan_tut/) 33 | - [Make a trailer for your slidedeck with av](https://masalmon.eu/2018/10/07/trailer/) 34 | 35 | ### Recommended reading about presentations remark.js: 36 | - [Markdown Presentations With RemarkJS](https://www.xaprb.com/blog/markdown-presentations-with-remarkjs/) by [Baron Schwartz](https://www.xaprb.com/) 37 | - [On presentation tools](http://agateau.com/2013/on-presentation-tools/) by [Aurélien Gâteau](http://agateau.com/) 38 | - [Presentation Skills Considered Harmful](http://seriouspony.com/blog/2013/10/4/presentation-skills-considered-harmful) by [Kathy Sierra](http://seriouspony.com/) 39 | - [Remark.js for your Geeky Presentations](https://www.telematika.org/post/remark.js-for-your-geeky-presentations/) by [Eueung Mulyana](https://www.telematika.org/author/em/) 40 | -------------------------------------------------------------------------------- /XaringanTutorial.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /imgs/dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/dark.jpg -------------------------------------------------------------------------------- /imgs/deploy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/deploy.jpg -------------------------------------------------------------------------------- /imgs/du.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/du.gif -------------------------------------------------------------------------------- /imgs/ggplot2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/ggplot2.gif -------------------------------------------------------------------------------- /imgs/gh1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/gh1.png -------------------------------------------------------------------------------- /imgs/gh2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/gh2.png -------------------------------------------------------------------------------- /imgs/github.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/github.PNG -------------------------------------------------------------------------------- /imgs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/icon.png -------------------------------------------------------------------------------- /imgs/light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/light.jpg -------------------------------------------------------------------------------- /imgs/ml.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/ml.gif -------------------------------------------------------------------------------- /imgs/netlify.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/netlify.jpg -------------------------------------------------------------------------------- /imgs/ocrug.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/ocrug.jpeg -------------------------------------------------------------------------------- /imgs/ocrug_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/ocrug_logo.png -------------------------------------------------------------------------------- /imgs/showcase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/showcase.gif -------------------------------------------------------------------------------- /imgs/step2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/step2.jpg -------------------------------------------------------------------------------- /imgs/step3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/step3.jpg -------------------------------------------------------------------------------- /imgs/step4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/step4.jpg -------------------------------------------------------------------------------- /imgs/step5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/step5.jpg -------------------------------------------------------------------------------- /imgs/su.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/su.gif -------------------------------------------------------------------------------- /imgs/themelibs.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/themelibs.PNG -------------------------------------------------------------------------------- /imgs/xaringan-animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/imgs/xaringan-animation.gif -------------------------------------------------------------------------------- /index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to Make Slides in R" 3 | subtitle: "Using xaringan" 4 | author: "Zhi Yang" 5 | date: "2019/2/26" 6 | output: 7 | xaringan::moon_reader: 8 | css: ["default", "rladies","lucy-fonts", "my-style.css"] 9 | lib_dir: libs 10 | nature: 11 | highlightStyle: github 12 | highlightLines: true 13 | countIncrementalSlides: false 14 | #chakra: "remark.js" 15 | --- 16 | 17 | ```{r setup, include=FALSE} 18 | options(htmltools.dir.version = FALSE) 19 | knitr::opts_chunk$set(tidy = FALSE, tidy.opts=list(width.cutoff=40)) 20 | library(babynames) 21 | library(tidyverse) 22 | ``` 23 | 24 | # How I met xaringan Sharingan 25 | .center[An `R` user who would like to share awesome things in `R`] 26 | -- 27 | .pull-left[ 28 | by showing a bunch of `R code snippets` without losing taste. 29 | 30 | ] 31 | -- 32 | .pull-right[ 33 | given no time nor money on formatting codes and adjusting layouts. 34 | 35 | ] 36 | 37 | ??? 38 | https://medium.com/@jakeout/deprecate-keynote-78f0f09424dd 39 | 40 | --- 41 | # Meet xaringan Sharingan 42 | Beautiful and concise layout 43 | 44 | .center[ ] 45 | .center[] 46 | --- 47 | # Meet xaringan Sharingan 48 | Code highlighting and live demos 49 | 50 | .center[![](imgs/ggplot2.gif)] 51 | 52 | 53 | --- 54 | # Meet xaringan Sharingan 55 | Version control and easy distribution 56 | 57 | .center[ 58 | 59 | 60 | 61 | ] 62 | 63 | --- 64 | # Meet xaringan Sharingan 65 | It animates 66 | 67 | .center[![](https://www.garrickadenbuie.com/images/2018/animated-xaringan-slides/xaringan-animated.gif) 68 | ] 69 | 70 | 71 | --- 72 | # Infinite moon reader `r emo::ji("astronaut")` 73 | Do you use `ctrl + K` to render your slides? 74 | - So, Are you tired from scrolling down to the page you were working on? 75 | 76 | .center[] 77 | 78 | -- 79 | 80 | ####Turn on the `Moon Reader` from either the pacakge or the addins 81 | 82 | ####From now on, the slides will auto-reload every time you `save` it 83 | 84 | --- 85 | # Infinite moon reader `r emo::ji("astronaut")` 86 | 87 | .center[![](https://user-images.githubusercontent.com/163582/53144527-35f7a500-3562-11e9-862e-892d3fd7036d.gif)] 88 | 89 | 90 | --- 91 | class: center, middle 92 | 93 | # Keyboard shortcuts 94 | Press `h` or `?` 95 | 96 | -- 97 | 98 | `m` -> mirror 99 | 100 | `b` -> blackout 101 | 102 | `f` -> fullscreen mode 103 | 104 | -- 105 | 106 | `c` -> clone slideshow 107 | 108 | `p` -> presenter mode 109 | 110 | `t` -> restart timer 111 | 112 | --- 113 | # Themes 114 | 115 | - Built-in themes 116 | 117 | ```{r eval=TRUE} 118 | names(xaringan:::list_css()) 119 | ``` 120 | 121 | -- 122 | These go to your YAML 123 | 124 | ```{r eval = FALSE} 125 | output: 126 | xaringan::moon_reader: 127 | css: [default, rladies, rladies-fonts] #<< 128 | ``` 129 | 130 | --- 131 | class: center, middle 132 | # Build your own theme 133 | 134 | 135 | 136 | 137 | https://pkg.garrickadenbuie.com/xaringanthemer/ 138 | 139 | --- 140 | # Somewhere in the middle? 141 | 142 | Add `my-style.css` to the YAML with the current css file 143 | 144 | ```{r eval = FALSE} 145 | output: 146 | xaringan::moon_reader: 147 | css: [default, rladies, lucy-fonts, my-style.css] #<< 148 | ``` 149 | 150 | -- 151 | 152 | While sitting in my-style.css file, 153 | ```css 154 | .red { color: red; } 155 | .remark-code-line-highlighted { background-color: #e8c9e9; } 156 | .remark-code, .remark-inline-code { 157 | color: #7c347f; 158 | font-weight: 300; 159 | } 160 | ``` 161 | -- 162 | I've changed it to .red[red]. 163 | 164 | --- 165 | # Where to find the themes files? 166 | You can find CSS files here. However, don't save your own CSS file here. 167 | 168 | .center[![](/imgs/themelibs.PNG)] 169 | 170 | -- 171 | 172 | ### - start with an existing theme 173 | ### - try change something and see what happens 174 | 175 | --- 176 | # Meet slidex 177 | It converts PowerPoint slides to xaringan slides 178 | 179 | .center[![](https://github.com/datalorax/slidex/raw/master/docs/slidex-preview.gif)] 180 | 181 | 182 | 183 | --- 184 | #Start with the YAML 185 | 186 | .pull-left[ 187 | ### Simple version 188 | 189 | ``` 190 | --- 191 | title: "How to Make Slides in R" 192 | output: 193 | xaringan::moon_reader 194 | --- 195 | 196 | ``` 197 | ] 198 | 199 | -- 200 | 201 | .pull-right[ 202 | ### More options 203 | 204 | ``` 205 | --- 206 | title: "How to Make Slides in R" 207 | subtitle: "Using xaringan" 208 | author: "Zhi Yang" 209 | date: "2019/2/26" 210 | output: 211 | xaringan::moon_reader: 212 | css: ["default", "rladies", 213 | "lucy-fonts", 214 | "my-style.css"] 215 | lib_dir: libs 216 | nature: 217 | highlightStyle: github 218 | highlightLines: true 219 | countIncrementalSlides: false 220 | #chakra: "remark.js" 221 | --- 222 | 223 | ``` 224 | ] 225 | 226 | --- 227 | # Make new slides 228 | 229 | Three dashes `---` gives a new slide 230 | 231 | ``` 232 | --- 233 | title: "How to Make Slides in R" 234 | output: 235 | xaringan::moon_reader 236 | --- 237 | A slide 238 | --- 239 | Another slide 240 | 241 | 242 | ``` 243 | 244 | --- 245 | # Align an entire slide 246 | 247 | .left-column[ 248 | ###Horizontal 249 | ``` 250 | left, 251 | *center, 252 | right 253 | ``` 254 | ###Vertical 255 | ``` 256 | top, 257 | *middle, 258 | bottom 259 | ``` 260 | ] 261 | 262 | .right-column[ 263 | ```r 264 | --- 265 | *class: center, middle 266 | 267 | # Demo slide 268 | 269 | This is a center- and middle- aligned slide. 270 | ``` 271 | ] 272 | 273 | --- 274 | # Align the text 275 | 276 | .left-column[ 277 | ###Horizontal 278 | ``` 279 | .left[texts] 280 | *.center[texts] 281 | .right[texts] 282 | ``` 283 | ] 284 | 285 | .right-column[ 286 | ```r 287 | --- 288 | class: center, middle 289 | 290 | # Demo slide 291 | 292 | *.right[This is a center- and middle- aligned slide.] 293 | ``` 294 | ] 295 | 296 | --- 297 | 298 | class: center, middle 299 | 300 | # Demo slide 301 | 302 | .right[This is a center- and middle- aligned slide.] 303 | 304 | --- 305 | # Incremental reveals 306 | 307 | .left-column[ 308 | 309 | ```markdown 310 | # Hi 311 | 312 | Did you know 313 | 314 | -- 315 | you can 316 | 317 | -- 318 | do this? 319 | 320 | ``` 321 | ] 322 | 323 | 324 | #Hi 325 | 326 | -- 327 | 328 | Did you know 329 | 330 | -- 331 | 332 | you can 333 | 334 | -- 335 | 336 | do this? 337 | 338 | --- 339 | # Code and higtlight 340 | use the trailing comment `#<<` to highlight specific lines of the code 341 | 342 | .pull-left[ 343 | Source: 344 | 345 | ````markdown 346 | `r ''````{r} 347 | namedata <- babynames %>% 348 | filter(name == "Orange") %>% 349 | filter(sex == "M") %>% #<< 350 | arrange(year) 351 | 352 | head(namedata) 353 | ``` 354 | ```` 355 | ] 356 | 357 | .pull-right[ 358 | Output: 359 | 360 | ```{r eval=FALSE} 361 | namedata <- babynames %>% 362 | filter(name == "Orange") %>% 363 | filter(sex == "M") %>% #<< 364 | arrange(year) 365 | 366 | head(namedata) 367 | ``` 368 | ] 369 | 370 | --- 371 | # Output and higtlight 372 | use the chunk option `highlight.output` to highlight specific lines of the text output 373 | 374 | .pull-left[ 375 | Source: 376 | ````markdown 377 | `r ''````{r head, highlight.output=c(1, 3)} 378 | namedata <- babynames %>% 379 | filter(name == "Orange") %>% 380 | filter(sex == "M") %>% #<< 381 | arrange(year) 382 | 383 | head(namedata) 384 | ``` 385 | ```` 386 | ] 387 | 388 | .pull-right[ 389 | Output: 390 | ```{r, highlight.output=c(1, 3), echo=FALSE} 391 | namedata <- babynames %>% 392 | filter(name == "Orange") %>% 393 | filter(sex == "M") %>% #<< 394 | arrange(year) 395 | 396 | head(namedata) 397 | ``` 398 | ] 399 | 400 | --- 401 | # Two-columns 402 | .top-column[ 403 | ````md 404 | .pull-left[ 405 | `r ''````{r refname echo=TRUE, eval=FALSE} 406 | your R code 407 | ``` 408 | ] 409 | .pull-right[ 410 | `r ''````{r ref.label="refname" echo=FALSE, eval=TRUE} 411 | 412 | ``` 413 | ] 414 | ```` 415 | ] 416 | 417 | `.pull-left` and `.pull-right` provide 47% width 418 | 419 | -- 420 | 421 | 422 | .pull-left[ 423 | ```{r babynames, eacho=TRUE, eval=FALSE} 424 | namedata <- babynames %>% 425 | filter(name == "Orange") %>% 426 | filter(sex == "M") %>% #<< 427 | arrange(year) 428 | 429 | head(namedata) 430 | ``` 431 | ] 432 | 433 | -- 434 | 435 | .pull-right[ 436 | ```{r, ref.label="babynames", echo=FALSE, eval=TRUE} 437 | 438 | ``` 439 | ] 440 | 441 | --- 442 | # Two-columns 443 | ````md 444 | .left-column[ 445 | `r ''````{r evel = FALSE} 446 | Your R code 447 | ``` 448 | ] 449 | .right-column[ 450 | `r ''````{r evel = FALSE, echo = FALSE} 451 | Your R code 452 | ``` 453 | ] 454 | ```` 455 | 456 | `.left-column` and `.right-column` provide 20% and 75% width 457 | 458 | -- 459 | 460 | .left-column[ 461 | 462 | ```r 463 | head(gss_cat) 464 | ``` 465 | ] 466 | -- 467 | .right-column[ 468 | ```{r echo=FALSE, eval=TRUE} 469 | head(gss_cat) 470 | ``` 471 | ] 472 | 473 | --- 474 | #Add a table 475 | ```{r eval=TRUE} 476 | head(iris, n = 3) 477 | knitr::kable(head(iris, n = 3), format = "html") 478 | ``` 479 | 480 | Set the table to be the `HTML` format 481 | 482 | 483 | --- 484 | #Add a plot 485 | ````{r eval=TRUE, fig.height = 5, fig.width = 5} 486 | par(mar = c(4, 4, 1, 0.1)) 487 | plot(cars, pch = 19, col = "darkgray", las = 1) 488 | ``` 489 | 490 | use `fig.height` and `fig.width` to control the size 491 | 492 | --- 493 | #Add an image 494 | ```r 495 | ![](/imgs/ocrug.jpeg) 496 | ``` 497 | ![](/imgs/ocrug.jpeg) 498 | 499 | --- 500 | #Resize it 501 | Should it be something like `![](/imgs/ocrug.jpeg){width=10px}` ? `r emo::ji("cry")` 502 | 503 | -- 504 | 505 | Option 1: 506 | ```markdown 507 | 508 | ``` 509 | 510 | 511 | -- 512 | 513 | Option 2: 514 | ````markdown 515 | `r ''````{r out.width = "20%", eval=TRUE} 516 | knitr::include_graphics("imgs/ocrug.jpeg") 517 | ``` 518 | ```` 519 | 520 | ```{r out.width = "20%", echo=FALSE, eval=TRUE} 521 | knitr::include_graphics("imgs/ocrug.jpeg") 522 | ``` 523 | 524 | --- 525 | background-image: url(/imgs/ocrug.jpeg) 526 | background-size: cover 527 | 528 | # Full screen 529 | 530 | ```r 531 | background-image: url(/imgs/ocrug.jpeg) 532 | background-size: cover 533 | ``` 534 | 535 | --- 536 | background-image: url(/imgs/ocrug.jpeg) 537 | background-size: contain 538 | 539 | # Rescale only 540 | 541 | ```r 542 | background-image: url(/imgs/ocrug.jpeg) 543 | background-size: contain 544 | ``` 545 | 546 | --- 547 | background-image: url(/imgs/ocrug.jpeg) 548 | background-size: contain 549 | background-position: bottom 550 | 551 | # Change position 552 | 553 | ```r 554 | background-image: url(/imgs/ocrug.jpeg) 555 | background-size: contain 556 | background-position: bottom 557 | ``` 558 | 559 | --- 560 | background-image: url(https://secure.meetupstatic.com/photos/event/2/b/9/e/600_471491166.jpeg) 561 | background-size: contain 562 | background-position: bottom 563 | 564 | # Use online image 565 | 566 | ```markdown 567 | background-image: url(https://secure.meetupstatic.com/photos/event/2/b/9/e/600_471491166.jpeg) 568 | background-size: contain 569 | background-position: bottom 570 | ``` 571 | 572 | --- 573 | background-image: url(imgs/ocrug_logo.png), url(imgs/ocrug_logo.png) 574 | background-position: 0% 100%, 100% 0% 575 | background-size: 30%, 10% 576 | 577 | # Logos 578 | 579 | 580 | ```markdown 581 | background-image: url(imgs/ocrug_logo.png), url(imgs/ocrug_logo.png) 582 | background-position: 0% 100%, 100% 0% 583 | background-size: 30%, 10% 584 | ``` 585 | 586 | --- 587 | # Hosting slides `r fontawesome::fa("github")` 588 | .center[] 589 | 590 | --- 591 | # Netlify `r emo::ji("computer")` 592 | .pull-left[ 593 | `Step 1:` go to netlify.com 594 | 595 | 596 | ] 597 | 598 | .pull-right[ 599 | `Step 2:` connect with your Github account 600 | 601 | 602 | 603 | ] 604 | 605 | 606 | --- 607 | # Netlify `r emo::ji("computer")` 608 | .pull-left[ 609 | 610 | `Step 3:` select a repo 611 | 612 | 613 | ] 614 | -- 615 | .pull-right[ 616 | 617 | `Step 4:` select a branch 618 | 619 | 620 | ] 621 | 622 | --- 623 | # Netlify `r emo::ji("computer")` 624 | .pull-top[ 625 | `Step 5:` deploy a site 626 | 627 | 628 | 629 | ] 630 | 631 | .pull-bottom[ 632 | `Step 6:` change site name 633 | 634 | 635 | 636 | ] 637 | 638 | --- 639 | class: middle 640 | 641 | # More info... 642 | 643 | .pull-left[![](/imgs/gh1.png)] 644 | .pull-right[![](/imgs/gh2.png)] 645 | 646 | 647 | --- 648 | class: center, middle 649 | 650 | # Thanks! 651 | 652 |
653 | @zhiiiyang 654 | 655 | https://github.com/zhiiiyang/XaringanTutorial 656 |
657 | 658 | Slides created via the R package [**xaringan**](https://github.com/yihui/xaringan) 659 | 660 | Template created by [Alison Hill](https://alison.rbind.io/) 661 | 662 | 663 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | How to Make Slides in R 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 751 | 752 | 753 | 797 | 798 | 808 | 809 | 828 | 829 | 839 | 840 | 841 | -------------------------------------------------------------------------------- /index_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/index_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /index_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/index_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /index_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/index_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /index_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/index_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /index_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/index_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /index_files/remark-css/default-fonts.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 | .remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; } 11 | -------------------------------------------------------------------------------- /index_files/remark-css/default.css: -------------------------------------------------------------------------------- 1 | a, a > code { 2 | color: rgb(249, 38, 114); 3 | text-decoration: none; 4 | } 5 | .footnote { 6 | position: absolute; 7 | bottom: 3em; 8 | padding-right: 4em; 9 | font-size: 90%; 10 | } 11 | .remark-code-line-highlighted { background-color: #ffff88; } 12 | 13 | .inverse { 14 | background-color: #272822; 15 | color: #d6d6d6; 16 | text-shadow: 0 0 20px #333; 17 | } 18 | .inverse h1, .inverse h2, .inverse h3 { 19 | color: #f3f3f3; 20 | } 21 | /* Two-column layout */ 22 | .left-column { 23 | color: #777; 24 | width: 20%; 25 | height: 92%; 26 | float: left; 27 | } 28 | .left-column h2:last-of-type, .left-column h3:last-child { 29 | color: #000; 30 | } 31 | .right-column { 32 | width: 75%; 33 | float: right; 34 | padding-top: 1em; 35 | } 36 | .pull-left { 37 | float: left; 38 | width: 47%; 39 | } 40 | .pull-right { 41 | float: right; 42 | width: 47%; 43 | } 44 | .pull-right ~ * { 45 | clear: both; 46 | } 47 | img, video, iframe { 48 | max-width: 100%; 49 | } 50 | blockquote { 51 | border-left: solid 5px lightgray; 52 | padding-left: 1em; 53 | } 54 | .remark-slide table { 55 | margin: auto; 56 | border-top: 1px solid #666; 57 | border-bottom: 1px solid #666; 58 | } 59 | .remark-slide table thead th { border-bottom: 1px solid #ddd; } 60 | th, td { padding: 5px; } 61 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } 62 | 63 | @page { margin: 0; } 64 | @media print { 65 | .remark-slide-scaler { 66 | width: 100% !important; 67 | height: 100% !important; 68 | transform: scale(1) !important; 69 | top: 0 !important; 70 | left: 0 !important; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /index_files/remark-css/rladies.css: -------------------------------------------------------------------------------- 1 | h1, h2, h3 { 2 | font-weight: normal; 3 | color: #562457; 4 | } 5 | a, a > code { 6 | color: #88398a; 7 | } 8 | .remark-code-line-highlighted { background-color: rgba(136, 57, 138, 0.3); } 9 | 10 | .inverse { 11 | background-color: #562457; 12 | } 13 | .inverse, .inverse h1, .inverse h2, .inverse h3, .inverse a, inverse a > code { 14 | color: #fff; 15 | } 16 | -------------------------------------------------------------------------------- /libs/Proj4Leaflet/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 | if (proj4.__esModule && proj4.default) { 19 | // If proj4 was bundled as an ES6 module, unwrap it to get 20 | // to the actual main proj4 object. 21 | // See discussion in https://github.com/kartena/Proj4Leaflet/pull/147 22 | proj4 = proj4.default; 23 | } 24 | 25 | L.Proj = {}; 26 | 27 | L.Proj._isProj4Obj = function(a) { 28 | return (typeof a.inverse !== 'undefined' && 29 | typeof a.forward !== 'undefined'); 30 | }; 31 | 32 | L.Proj.Projection = L.Class.extend({ 33 | initialize: function(code, def, bounds) { 34 | var isP4 = L.Proj._isProj4Obj(code); 35 | this._proj = isP4 ? code : this._projFromCodeDef(code, def); 36 | this.bounds = isP4 ? def : bounds; 37 | }, 38 | 39 | project: function (latlng) { 40 | var point = this._proj.forward([latlng.lng, latlng.lat]); 41 | return new L.Point(point[0], point[1]); 42 | }, 43 | 44 | unproject: function (point, unbounded) { 45 | var point2 = this._proj.inverse([point.x, point.y]); 46 | return new L.LatLng(point2[1], point2[0], unbounded); 47 | }, 48 | 49 | _projFromCodeDef: function(code, def) { 50 | if (def) { 51 | proj4.defs(code, def); 52 | } else if (proj4.defs[code] === undefined) { 53 | var urn = code.split(':'); 54 | if (urn.length > 3) { 55 | code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; 56 | } 57 | if (proj4.defs[code] === undefined) { 58 | throw 'No projection definition for code ' + code; 59 | } 60 | } 61 | 62 | return proj4(code); 63 | } 64 | }); 65 | 66 | L.Proj.CRS = L.Class.extend({ 67 | includes: L.CRS, 68 | 69 | options: { 70 | transformation: new L.Transformation(1, 0, -1, 0) 71 | }, 72 | 73 | initialize: function(a, b, c) { 74 | var code, 75 | proj, 76 | def, 77 | options; 78 | 79 | if (L.Proj._isProj4Obj(a)) { 80 | proj = a; 81 | code = proj.srsCode; 82 | options = b || {}; 83 | 84 | this.projection = new L.Proj.Projection(proj, options.bounds); 85 | } else { 86 | code = a; 87 | def = b; 88 | options = c || {}; 89 | this.projection = new L.Proj.Projection(code, def, options.bounds); 90 | } 91 | 92 | L.Util.setOptions(this, options); 93 | this.code = code; 94 | this.transformation = this.options.transformation; 95 | 96 | if (this.options.origin) { 97 | this.transformation = 98 | new L.Transformation(1, -this.options.origin[0], 99 | -1, this.options.origin[1]); 100 | } 101 | 102 | if (this.options.scales) { 103 | this._scales = this.options.scales; 104 | } else if (this.options.resolutions) { 105 | this._scales = []; 106 | for (var i = this.options.resolutions.length - 1; i >= 0; i--) { 107 | if (this.options.resolutions[i]) { 108 | this._scales[i] = 1 / this.options.resolutions[i]; 109 | } 110 | } 111 | } 112 | 113 | this.infinite = !this.options.bounds; 114 | 115 | }, 116 | 117 | scale: function(zoom) { 118 | var iZoom = Math.floor(zoom), 119 | baseScale, 120 | nextScale, 121 | scaleDiff, 122 | zDiff; 123 | if (zoom === iZoom) { 124 | return this._scales[zoom]; 125 | } else { 126 | // Non-integer zoom, interpolate 127 | baseScale = this._scales[iZoom]; 128 | nextScale = this._scales[iZoom + 1]; 129 | scaleDiff = nextScale - baseScale; 130 | zDiff = (zoom - iZoom); 131 | return baseScale + scaleDiff * zDiff; 132 | } 133 | }, 134 | 135 | zoom: function(scale) { 136 | // Find closest number in this._scales, down 137 | var downScale = this._closestElement(this._scales, scale), 138 | downZoom = this._scales.indexOf(downScale), 139 | nextScale, 140 | nextZoom, 141 | scaleDiff; 142 | // Check if scale is downScale => return array index 143 | if (scale === downScale) { 144 | return downZoom; 145 | } 146 | if (downScale === undefined) { 147 | return -Infinity; 148 | } 149 | // Interpolate 150 | nextZoom = downZoom + 1; 151 | nextScale = this._scales[nextZoom]; 152 | if (nextScale === undefined) { 153 | return Infinity; 154 | } 155 | scaleDiff = nextScale - downScale; 156 | return (scale - downScale) / scaleDiff + downZoom; 157 | }, 158 | 159 | distance: L.CRS.Earth.distance, 160 | 161 | R: L.CRS.Earth.R, 162 | 163 | /* Get the closest lowest element in an array */ 164 | _closestElement: function(array, element) { 165 | var low; 166 | for (var i = array.length; i--;) { 167 | if (array[i] <= element && (low === undefined || low < array[i])) { 168 | low = array[i]; 169 | } 170 | } 171 | return low; 172 | } 173 | }); 174 | 175 | L.Proj.GeoJSON = L.GeoJSON.extend({ 176 | initialize: function(geojson, options) { 177 | this._callLevel = 0; 178 | L.GeoJSON.prototype.initialize.call(this, geojson, options); 179 | }, 180 | 181 | addData: function(geojson) { 182 | var crs; 183 | 184 | if (geojson) { 185 | if (geojson.crs && geojson.crs.type === 'name') { 186 | crs = new L.Proj.CRS(geojson.crs.properties.name); 187 | } else if (geojson.crs && geojson.crs.type) { 188 | crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); 189 | } 190 | 191 | if (crs !== undefined) { 192 | this.options.coordsToLatLng = function(coords) { 193 | var point = L.point(coords[0], coords[1]); 194 | return crs.projection.unproject(point); 195 | }; 196 | } 197 | } 198 | 199 | // Base class' addData might call us recursively, but 200 | // CRS shouldn't be cleared in that case, since CRS applies 201 | // to the whole GeoJSON, inluding sub-features. 202 | this._callLevel++; 203 | try { 204 | L.GeoJSON.prototype.addData.call(this, geojson); 205 | } finally { 206 | this._callLevel--; 207 | if (this._callLevel === 0) { 208 | delete this.options.coordsToLatLng; 209 | } 210 | } 211 | } 212 | }); 213 | 214 | L.Proj.geoJson = function(geojson, options) { 215 | return new L.Proj.GeoJSON(geojson, options); 216 | }; 217 | 218 | L.Proj.ImageOverlay = L.ImageOverlay.extend({ 219 | initialize: function (url, bounds, options) { 220 | L.ImageOverlay.prototype.initialize.call(this, url, null, options); 221 | this._projectedBounds = bounds; 222 | }, 223 | 224 | // Danger ahead: Overriding internal methods in Leaflet. 225 | // Decided to do this rather than making a copy of L.ImageOverlay 226 | // and doing very tiny modifications to it. 227 | // Future will tell if this was wise or not. 228 | _animateZoom: function (event) { 229 | var scale = this._map.getZoomScale(event.zoom); 230 | var northWest = L.point(this._projectedBounds.min.x, this._projectedBounds.max.y); 231 | var offset = this._projectedToNewLayerPoint(northWest, event.zoom, event.center); 232 | 233 | L.DomUtil.setTransform(this._image, offset, scale); 234 | }, 235 | 236 | _reset: function () { 237 | var zoom = this._map.getZoom(); 238 | var pixelOrigin = this._map.getPixelOrigin(); 239 | var bounds = L.bounds( 240 | this._transform(this._projectedBounds.min, zoom)._subtract(pixelOrigin), 241 | this._transform(this._projectedBounds.max, zoom)._subtract(pixelOrigin) 242 | ); 243 | var size = bounds.getSize(); 244 | 245 | L.DomUtil.setPosition(this._image, bounds.min); 246 | this._image.style.width = size.x + 'px'; 247 | this._image.style.height = size.y + 'px'; 248 | }, 249 | 250 | _projectedToNewLayerPoint: function (point, zoom, center) { 251 | var viewHalf = this._map.getSize()._divideBy(2); 252 | var newTopLeft = this._map.project(center, zoom)._subtract(viewHalf)._round(); 253 | var topLeft = newTopLeft.add(this._map._getMapPanePos()); 254 | 255 | return this._transform(point, zoom)._subtract(topLeft); 256 | }, 257 | 258 | _transform: function (point, zoom) { 259 | var crs = this._map.options.crs; 260 | var transformation = crs.transformation; 261 | var scale = crs.scale(zoom); 262 | 263 | return transformation.transform(point, scale); 264 | } 265 | }); 266 | 267 | L.Proj.imageOverlay = function (url, bounds, options) { 268 | return new L.Proj.ImageOverlay(url, bounds, options); 269 | }; 270 | 271 | return L.Proj; 272 | })); 273 | -------------------------------------------------------------------------------- /libs/crosstalk/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libs/crosstalk/js/crosstalk.min.js: -------------------------------------------------------------------------------- 1 | !function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gb?1:void 0}Object.defineProperty(c,"__esModule",{value:!0});var f=function(){function a(a,b){for(var c=0;c0&&void 0!==arguments[0]?arguments[0]:this._allKeys,b=Object.keys(this._handles).length;if(0===b)this._value=null;else{this._value=[];for(var c=0;c?@\[\\\]^`{|}~])/g,"\\$1")}function f(a){var b=h(a);Object.keys(i).forEach(function(c){if(b.hasClass(c)&&!b.hasClass("crosstalk-input-bound")){var d=i[c];g(d,a)}})}function g(a,b){var c=h(b).find("script[type='application/json'][data-for='"+e(b.id)+"']"),d=JSON.parse(c[0].innerText),f=a.factory(b,d);h(b).data("crosstalk-instance",f),h(b).addClass("crosstalk-input-bound")}Object.defineProperty(c,"__esModule",{value:!0}),c.register=b;var h=a.jQuery,i={};a.Shiny&&!function(){var b=new a.Shiny.InputBinding,c=a.jQuery;c.extend(b,{find:function(a){return c(a).find(".crosstalk-input")},initialize:function(a){c(a).hasClass("crosstalk-input-bound")||f(a)},getId:function(a){return a.id},getValue:function(a){},setValue:function(a,b){},receiveMessage:function(a,b){},subscribe:function(a,b){c(a).data("crosstalk-instance").resume()},unsubscribe:function(a){c(a).data("crosstalk-instance").suspend()}}),a.Shiny.inputBindings.register(b,"crosstalk.inputBinding")}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(a,b,c){(function(b){"use strict";function c(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b.default=a,b}var d=a("./input"),e=c(d),f=a("./filter"),g=b.jQuery;e.register({className:"crosstalk-input-checkboxgroup",factory:function(a,b){var c=new f.FilterHandle(b.group),d=void 0,e=g(a);return e.on("change","input[type='checkbox']",function(){var a=e.find("input[type='checkbox']:checked");0===a.length?(d=null,c.clear()):!function(){var e={};a.each(function(){b.map[this.value].forEach(function(a){e[a]=!0})});var f=Object.keys(e);f.sort(),d=f,c.set(f)}()}),{suspend:function(){c.clear()},resume:function(){d&&c.set(d)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],8:[function(a,b,c){(function(b){"use strict";function c(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b.default=a,b}var d=a("./input"),e=c(d),f=a("./util"),g=c(f),h=a("./filter"),i=b.jQuery;e.register({className:"crosstalk-input-select",factory:function(a,b){var c=[{value:"",label:"(All)"}],d=g.dataframeToD3(b.items),e={options:c.concat(d),valueField:"value",labelField:"label",searchField:"label"},f=i(a).find("select")[0],j=i(f).selectize(e)[0].selectize,k=new h.FilterHandle(b.group),l=void 0;return j.on("change",function(){0===j.items.length?(l=null,k.clear()):!function(){var a={};j.items.forEach(function(c){b.map[c].forEach(function(b){a[b]=!0})});var c=Object.keys(a);c.sort(),l=c,k.set(c)}()}),{suspend:function(){k.clear()},resume:function(){l&&k.set(l)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6,"./util":11}],9:[function(a,b,c){(function(b){"use strict";function c(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b.default=a,b}function d(a,b){for(var c=a.toString();c.length=i&&m<=j&&k.push(b.keys[l])}k.sort(),d.set(k),p=k}}),{suspend:function(){d.clear()},resume:function(){p&&d.set(p)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],10:[function(a,b,c){"use strict";function d(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b.default=a,b}function e(a){return a&&a.__esModule?a:{default:a}}function f(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(c,"__esModule",{value:!0}),c.SelectionHandle=void 0;var g=function(){function a(a,b){for(var c=0;c0&&void 0!==arguments[0]?arguments[0]:null,c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;f(this,a),this._eventRelay=new i.default,this._emitter=new m.SubscriptionTracker(this._eventRelay),this._group=null,this._var=null,this._varOnChangeSub=null,this._extraInfo=m.extend({sender:this},c),this.setGroup(b)}return g(a,[{key:"setGroup",value:function(a){var b=this;if(this._group!==a&&(this._group||a)&&(this._var&&(this._var.off("change",this._varOnChangeSub),this._var=null,this._varOnChangeSub=null),this._group=a,a)){this._var=(0,k.default)(a).var("selection");var c=this._var.on("change",function(a){b._eventRelay.trigger("change",a,b)});this._varOnChangeSub=c}}},{key:"_mergeExtraInfo",value:function(a){return m.extend({},this._extraInfo?this._extraInfo:null,a?a:null)}},{key:"set",value:function(a,b){this._var&&this._var.set(a,this._mergeExtraInfo(b))}},{key:"clear",value:function(a){this._var&&this.set(void 0,this._mergeExtraInfo(a))}},{key:"on",value:function(a,b){return this._emitter.on(a,b)}},{key:"off",value:function(a,b){return this._emitter.off(a,b)}},{key:"close",value:function(){this._emitter.removeAllListeners(),this.setGroup(null)}},{key:"value",get:function(){return this._var?this._var.get():null}}]),a}()},{"./events":1,"./group":4,"./util":11}],11:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function e(a){for(var b=arguments.length,c=Array(b>1?b-1:0),d=1;d.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} 2 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .@{fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 100% { 17 | transform: rotate(360deg); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | border-radius: .1em; 6 | border: solid .08em @fa-border-color; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix}, .fas, .far, .fal, .fab { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}, .fas, .far, .fal, .fab { 5 | -moz-osx-font-smoothing: grayscale; 6 | -webkit-font-smoothing: antialiased; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | text-rendering: auto; 11 | line-height: 1; 12 | } 13 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | text-align: center; 5 | width: (20em / 16); 6 | } 7 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | .larger(@factor) when (@factor > 0) { 5 | .larger((@factor - 1)); 6 | 7 | .@{fa-css-prefix}-@{factor}x { 8 | font-size: (@factor * 1em); 9 | } 10 | } 11 | 12 | /* makes the font 33% larger relative to the icon container */ 13 | .@{fa-css-prefix}-lg { 14 | font-size: (4em / 3); 15 | line-height: (3em / 4); 16 | vertical-align: -.0667em; 17 | } 18 | 19 | .@{fa-css-prefix}-xs { 20 | font-size: .75em; 21 | } 22 | 23 | .@{fa-css-prefix}-sm { 24 | font-size: .875em; 25 | } 26 | 27 | .larger(10); 28 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | list-style-type: none; 6 | margin-left: @fa-li-width * 5/4; 7 | padding-left: 0; 8 | 9 | > li { position: relative; } 10 | } 11 | 12 | .@{fa-css-prefix}-li { 13 | left: -@fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: @fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | -moz-osx-font-smoothing: grayscale; 6 | -webkit-font-smoothing: antialiased; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | font-weight: normal; 11 | line-height: 1; 12 | vertical-align: -.125em; 13 | } 14 | 15 | .fa-icon-rotate(@degrees, @rotation) { 16 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 17 | transform: rotate(@degrees); 18 | } 19 | 20 | .fa-icon-flip(@horiz, @vert, @rotation) { 21 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; 22 | transform: scale(@horiz, @vert); 23 | } 24 | 25 | 26 | // Only display content to screen readers. A la Bootstrap 4. 27 | // 28 | // See: http://a11yproject.com/posts/how-to-hide-content/ 29 | 30 | .sr-only() { 31 | border: 0; 32 | clip: rect(0,0,0,0); 33 | height: 1px; 34 | margin: -1px; 35 | overflow: hidden; 36 | padding: 0; 37 | position: absolute; 38 | width: 1px; 39 | } 40 | 41 | // Use in conjunction with .sr-only to only display content when it's focused. 42 | // 43 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 44 | // 45 | // Credit: HTML5 Boilerplate 46 | 47 | .sr-only-focusable() { 48 | &:active, 49 | &:focus { 50 | clip: auto; 51 | height: auto; 52 | margin: 0; 53 | overflow: visible; 54 | position: static; 55 | width: auto; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | .@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .@{fa-css-prefix}-rotate-90, 17 | .@{fa-css-prefix}-rotate-180, 18 | .@{fa-css-prefix}-rotate-270, 19 | .@{fa-css-prefix}-flip-horizontal, 20 | .@{fa-css-prefix}-flip-vertical { 21 | filter: none; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /libs/font-awesome/less/_stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: 2em; 11 | } 12 | 13 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 14 | left: 0; 15 | position: absolute; 16 | text-align: center; 17 | width: 100%; 18 | } 19 | 20 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 21 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 22 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 23 | -------------------------------------------------------------------------------- /libs/font-awesome/less/brands.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import "_variables.less"; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Brands'; 9 | font-style: normal; 10 | font-weight: normal; 11 | src: url('@{fa-font-path}/fa-brands-400.eot'); 12 | src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 13 | url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'), 14 | url('@{fa-font-path}/fa-brands-400.woff') format('woff'), 15 | url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'), 16 | url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fab { 20 | font-family: 'Font Awesome 5 Brands'; 21 | } 22 | -------------------------------------------------------------------------------- /libs/font-awesome/less/fontawesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import "_variables.less"; 6 | @import "_mixins.less"; 7 | @import "_core.less"; 8 | @import "_larger.less"; 9 | @import "_fixed-width.less"; 10 | @import "_list.less"; 11 | @import "_bordered-pulled.less"; 12 | @import "_animated.less"; 13 | @import "_rotated-flipped.less"; 14 | @import "_stacked.less"; 15 | @import "_icons.less"; 16 | @import "_screen-reader.less"; 17 | -------------------------------------------------------------------------------- /libs/font-awesome/less/regular.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import "_variables.less"; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: url('@{fa-font-path}/fa-regular-400.eot'); 12 | src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 13 | url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'), 14 | url('@{fa-font-path}/fa-regular-400.woff') format('woff'), 15 | url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'), 16 | url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .far { 20 | font-family: 'Font Awesome 5 Free'; 21 | font-weight: 400; 22 | } 23 | -------------------------------------------------------------------------------- /libs/font-awesome/less/solid.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import "_variables.less"; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | src: url('@{fa-font-path}/fa-solid-900.eot'); 12 | src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 13 | url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'), 14 | url('@{fa-font-path}/fa-solid-900.woff') format('woff'), 15 | url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'), 16 | url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fa, 20 | .fas { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 900; 23 | } 24 | -------------------------------------------------------------------------------- /libs/font-awesome/less/v4-shims.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import '_variables.less'; 6 | @import '_shims.less'; 7 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .#{$fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 17 | 100% { 18 | transform: rotate(360deg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | border: solid .08em $fa-border-color; 6 | border-radius: .1em; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix}, 14 | .fas, 15 | .far, 16 | .fal, 17 | .fab { 18 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 19 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 20 | } 21 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}, 5 | .fas, 6 | .far, 7 | .fal, 8 | .fab { 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | display: inline-block; 12 | font-style: normal; 13 | font-variant: normal; 14 | text-rendering: auto; 15 | line-height: 1; 16 | } 17 | 18 | %fa-icon { 19 | @include fa-icon; 20 | } 21 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | text-align: center; 5 | width: (20em / 16); 6 | } 7 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | // makes the font 33% larger relative to the icon container 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -.0667em; 9 | } 10 | 11 | .#{$fa-css-prefix}-xs { 12 | font-size: .75em; 13 | } 14 | 15 | .#{$fa-css-prefix}-sm { 16 | font-size: .875em; 17 | } 18 | 19 | @for $i from 1 through 10 { 20 | .#{$fa-css-prefix}-#{$i}x { 21 | font-size: $i * 1em; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | list-style-type: none; 6 | margin-left: $fa-li-width * 5/4; 7 | padding-left: 0; 8 | 9 | > li { position: relative; } 10 | } 11 | 12 | .#{$fa-css-prefix}-li { 13 | left: -$fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: $fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon { 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | font-weight: normal; 11 | line-height: 1; 12 | vertical-align: -.125em; 13 | } 14 | 15 | @mixin fa-icon-rotate($degrees, $rotation) { 16 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 17 | transform: rotate($degrees); 18 | } 19 | 20 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 21 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 22 | transform: scale($horiz, $vert); 23 | } 24 | 25 | 26 | // Only display content to screen readers. A la Bootstrap 4. 27 | // 28 | // See: http://a11yproject.com/posts/how-to-hide-content/ 29 | 30 | @mixin sr-only { 31 | border: 0; 32 | clip: rect(0, 0, 0, 0); 33 | height: 1px; 34 | margin: -1px; 35 | overflow: hidden; 36 | padding: 0; 37 | position: absolute; 38 | width: 1px; 39 | } 40 | 41 | // Use in conjunction with .sr-only to only display content when it's focused. 42 | // 43 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 44 | // 45 | // Credit: HTML5 Boilerplate 46 | 47 | @mixin sr-only-focusable { 48 | &:active, 49 | &:focus { 50 | clip: auto; 51 | height: auto; 52 | margin: 0; 53 | overflow: visible; 54 | position: static; 55 | width: auto; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .#{$fa-css-prefix}-rotate-90, 17 | .#{$fa-css-prefix}-rotate-180, 18 | .#{$fa-css-prefix}-rotate-270, 19 | .#{$fa-css-prefix}-flip-horizontal, 20 | .#{$fa-css-prefix}-flip-vertical { 21 | filter: none; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only; } 5 | .sr-only-focusable { @include sr-only-focusable; } 6 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: 2em; 11 | } 12 | 13 | .#{$fa-css-prefix}-stack-1x, 14 | .#{$fa-css-prefix}-stack-2x { 15 | left: 0; 16 | position: absolute; 17 | text-align: center; 18 | width: 100%; 19 | } 20 | 21 | .#{$fa-css-prefix}-stack-1x { 22 | line-height: inherit; 23 | } 24 | 25 | .#{$fa-css-prefix}-stack-2x { 26 | font-size: 2em; 27 | } 28 | 29 | .#{$fa-css-prefix}-inverse { 30 | color: $fa-inverse; 31 | } 32 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/brands.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Brands'; 9 | font-style: normal; 10 | font-weight: normal; 11 | src: url('#{$fa-font-path}/fa-brands-400.eot'); 12 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fab { 20 | font-family: 'Font Awesome 5 Brands'; 21 | } 22 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/fontawesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'mixins'; 7 | @import 'core'; 8 | @import 'larger'; 9 | @import 'fixed-width'; 10 | @import 'list'; 11 | @import 'bordered-pulled'; 12 | @import 'animated'; 13 | @import 'rotated-flipped'; 14 | @import 'stacked'; 15 | @import 'icons'; 16 | @import 'screen-reader'; 17 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/regular.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: url('#{$fa-font-path}/fa-regular-400.eot'); 12 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .far { 20 | font-family: 'Font Awesome 5 Free'; 21 | font-weight: 400; 22 | } 23 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/solid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | src: url('#{$fa-font-path}/fa-solid-900.eot'); 12 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fa, 20 | .fas { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 900; 23 | } 24 | -------------------------------------------------------------------------------- /libs/font-awesome/scss/v4-shims.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'shims'; 7 | -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /libs/font-awesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/font-awesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /libs/htmlwidgets/htmlwidgets.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | // If window.HTMLWidgets is already defined, then use it; otherwise create a 3 | // new object. This allows preceding code to set options that affect the 4 | // initialization process (though none currently exist). 5 | window.HTMLWidgets = window.HTMLWidgets || {}; 6 | 7 | // See if we're running in a viewer pane. If not, we're in a web browser. 8 | var viewerMode = window.HTMLWidgets.viewerMode = 9 | /\bviewer_pane=1\b/.test(window.location); 10 | 11 | // See if we're running in Shiny mode. If not, it's a static document. 12 | // Note that static widgets can appear in both Shiny and static modes, but 13 | // obviously, Shiny widgets can only appear in Shiny apps/documents. 14 | var shinyMode = window.HTMLWidgets.shinyMode = 15 | typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings; 16 | 17 | // We can't count on jQuery being available, so we implement our own 18 | // version if necessary. 19 | function querySelectorAll(scope, selector) { 20 | if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) { 21 | return scope.find(selector); 22 | } 23 | if (scope.querySelectorAll) { 24 | return scope.querySelectorAll(selector); 25 | } 26 | } 27 | 28 | function asArray(value) { 29 | if (value === null) 30 | return []; 31 | if ($.isArray(value)) 32 | return value; 33 | return [value]; 34 | } 35 | 36 | // Implement jQuery's extend 37 | function extend(target /*, ... */) { 38 | if (arguments.length == 1) { 39 | return target; 40 | } 41 | for (var i = 1; i < arguments.length; i++) { 42 | var source = arguments[i]; 43 | for (var prop in source) { 44 | if (source.hasOwnProperty(prop)) { 45 | target[prop] = source[prop]; 46 | } 47 | } 48 | } 49 | return target; 50 | } 51 | 52 | // IE8 doesn't support Array.forEach. 53 | function forEach(values, callback, thisArg) { 54 | if (values.forEach) { 55 | values.forEach(callback, thisArg); 56 | } else { 57 | for (var i = 0; i < values.length; i++) { 58 | callback.call(thisArg, values[i], i, values); 59 | } 60 | } 61 | } 62 | 63 | // Replaces the specified method with the return value of funcSource. 64 | // 65 | // Note that funcSource should not BE the new method, it should be a function 66 | // that RETURNS the new method. funcSource receives a single argument that is 67 | // the overridden method, it can be called from the new method. The overridden 68 | // method can be called like a regular function, it has the target permanently 69 | // bound to it so "this" will work correctly. 70 | function overrideMethod(target, methodName, funcSource) { 71 | var superFunc = target[methodName] || function() {}; 72 | var superFuncBound = function() { 73 | return superFunc.apply(target, arguments); 74 | }; 75 | target[methodName] = funcSource(superFuncBound); 76 | } 77 | 78 | // Add a method to delegator that, when invoked, calls 79 | // delegatee.methodName. If there is no such method on 80 | // the delegatee, but there was one on delegator before 81 | // delegateMethod was called, then the original version 82 | // is invoked instead. 83 | // For example: 84 | // 85 | // var a = { 86 | // method1: function() { console.log('a1'); } 87 | // method2: function() { console.log('a2'); } 88 | // }; 89 | // var b = { 90 | // method1: function() { console.log('b1'); } 91 | // }; 92 | // delegateMethod(a, b, "method1"); 93 | // delegateMethod(a, b, "method2"); 94 | // a.method1(); 95 | // a.method2(); 96 | // 97 | // The output would be "b1", "a2". 98 | function delegateMethod(delegator, delegatee, methodName) { 99 | var inherited = delegator[methodName]; 100 | delegator[methodName] = function() { 101 | var target = delegatee; 102 | var method = delegatee[methodName]; 103 | 104 | // The method doesn't exist on the delegatee. Instead, 105 | // call the method on the delegator, if it exists. 106 | if (!method) { 107 | target = delegator; 108 | method = inherited; 109 | } 110 | 111 | if (method) { 112 | return method.apply(target, arguments); 113 | } 114 | }; 115 | } 116 | 117 | // Implement a vague facsimilie of jQuery's data method 118 | function elementData(el, name, value) { 119 | if (arguments.length == 2) { 120 | return el["htmlwidget_data_" + name]; 121 | } else if (arguments.length == 3) { 122 | el["htmlwidget_data_" + name] = value; 123 | return el; 124 | } else { 125 | throw new Error("Wrong number of arguments for elementData: " + 126 | arguments.length); 127 | } 128 | } 129 | 130 | // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex 131 | function escapeRegExp(str) { 132 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 133 | } 134 | 135 | function hasClass(el, className) { 136 | var re = new RegExp("\\b" + escapeRegExp(className) + "\\b"); 137 | return re.test(el.className); 138 | } 139 | 140 | // elements - array (or array-like object) of HTML elements 141 | // className - class name to test for 142 | // include - if true, only return elements with given className; 143 | // if false, only return elements *without* given className 144 | function filterByClass(elements, className, include) { 145 | var results = []; 146 | for (var i = 0; i < elements.length; i++) { 147 | if (hasClass(elements[i], className) == include) 148 | results.push(elements[i]); 149 | } 150 | return results; 151 | } 152 | 153 | function on(obj, eventName, func) { 154 | if (obj.addEventListener) { 155 | obj.addEventListener(eventName, func, false); 156 | } else if (obj.attachEvent) { 157 | obj.attachEvent(eventName, func); 158 | } 159 | } 160 | 161 | function off(obj, eventName, func) { 162 | if (obj.removeEventListener) 163 | obj.removeEventListener(eventName, func, false); 164 | else if (obj.detachEvent) { 165 | obj.detachEvent(eventName, func); 166 | } 167 | } 168 | 169 | // Translate array of values to top/right/bottom/left, as usual with 170 | // the "padding" CSS property 171 | // https://developer.mozilla.org/en-US/docs/Web/CSS/padding 172 | function unpackPadding(value) { 173 | if (typeof(value) === "number") 174 | value = [value]; 175 | if (value.length === 1) { 176 | return {top: value[0], right: value[0], bottom: value[0], left: value[0]}; 177 | } 178 | if (value.length === 2) { 179 | return {top: value[0], right: value[1], bottom: value[0], left: value[1]}; 180 | } 181 | if (value.length === 3) { 182 | return {top: value[0], right: value[1], bottom: value[2], left: value[1]}; 183 | } 184 | if (value.length === 4) { 185 | return {top: value[0], right: value[1], bottom: value[2], left: value[3]}; 186 | } 187 | } 188 | 189 | // Convert an unpacked padding object to a CSS value 190 | function paddingToCss(paddingObj) { 191 | return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px"; 192 | } 193 | 194 | // Makes a number suitable for CSS 195 | function px(x) { 196 | if (typeof(x) === "number") 197 | return x + "px"; 198 | else 199 | return x; 200 | } 201 | 202 | // Retrieves runtime widget sizing information for an element. 203 | // The return value is either null, or an object with fill, padding, 204 | // defaultWidth, defaultHeight fields. 205 | function sizingPolicy(el) { 206 | var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']"); 207 | if (!sizingEl) 208 | return null; 209 | var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}"); 210 | if (viewerMode) { 211 | return sp.viewer; 212 | } else { 213 | return sp.browser; 214 | } 215 | } 216 | 217 | // @param tasks Array of strings (or falsy value, in which case no-op). 218 | // Each element must be a valid JavaScript expression that yields a 219 | // function. Or, can be an array of objects with "code" and "data" 220 | // properties; in this case, the "code" property should be a string 221 | // of JS that's an expr that yields a function, and "data" should be 222 | // an object that will be added as an additional argument when that 223 | // function is called. 224 | // @param target The object that will be "this" for each function 225 | // execution. 226 | // @param args Array of arguments to be passed to the functions. (The 227 | // same arguments will be passed to all functions.) 228 | function evalAndRun(tasks, target, args) { 229 | if (tasks) { 230 | forEach(tasks, function(task) { 231 | var theseArgs = args; 232 | if (typeof(task) === "object") { 233 | theseArgs = theseArgs.concat([task.data]); 234 | task = task.code; 235 | } 236 | var taskFunc = eval("(" + task + ")"); 237 | if (typeof(taskFunc) !== "function") { 238 | throw new Error("Task must be a function! Source:\n" + task); 239 | } 240 | taskFunc.apply(target, theseArgs); 241 | }); 242 | } 243 | } 244 | 245 | function initSizing(el) { 246 | var sizing = sizingPolicy(el); 247 | if (!sizing) 248 | return; 249 | 250 | var cel = document.getElementById("htmlwidget_container"); 251 | if (!cel) 252 | return; 253 | 254 | if (typeof(sizing.padding) !== "undefined") { 255 | document.body.style.margin = "0"; 256 | document.body.style.padding = paddingToCss(unpackPadding(sizing.padding)); 257 | } 258 | 259 | if (sizing.fill) { 260 | document.body.style.overflow = "hidden"; 261 | document.body.style.width = "100%"; 262 | document.body.style.height = "100%"; 263 | document.documentElement.style.width = "100%"; 264 | document.documentElement.style.height = "100%"; 265 | if (cel) { 266 | cel.style.position = "absolute"; 267 | var pad = unpackPadding(sizing.padding); 268 | cel.style.top = pad.top + "px"; 269 | cel.style.right = pad.right + "px"; 270 | cel.style.bottom = pad.bottom + "px"; 271 | cel.style.left = pad.left + "px"; 272 | el.style.width = "100%"; 273 | el.style.height = "100%"; 274 | } 275 | 276 | return { 277 | getWidth: function() { return cel.offsetWidth; }, 278 | getHeight: function() { return cel.offsetHeight; } 279 | }; 280 | 281 | } else { 282 | el.style.width = px(sizing.width); 283 | el.style.height = px(sizing.height); 284 | 285 | return { 286 | getWidth: function() { return el.offsetWidth; }, 287 | getHeight: function() { return el.offsetHeight; } 288 | }; 289 | } 290 | } 291 | 292 | // Default implementations for methods 293 | var defaults = { 294 | find: function(scope) { 295 | return querySelectorAll(scope, "." + this.name); 296 | }, 297 | renderError: function(el, err) { 298 | var $el = $(el); 299 | 300 | this.clearError(el); 301 | 302 | // Add all these error classes, as Shiny does 303 | var errClass = "shiny-output-error"; 304 | if (err.type !== null) { 305 | // use the classes of the error condition as CSS class names 306 | errClass = errClass + " " + $.map(asArray(err.type), function(type) { 307 | return errClass + "-" + type; 308 | }).join(" "); 309 | } 310 | errClass = errClass + " htmlwidgets-error"; 311 | 312 | // Is el inline or block? If inline or inline-block, just display:none it 313 | // and add an inline error. 314 | var display = $el.css("display"); 315 | $el.data("restore-display-mode", display); 316 | 317 | if (display === "inline" || display === "inline-block") { 318 | $el.hide(); 319 | if (err.message !== "") { 320 | var errorSpan = $("").addClass(errClass); 321 | errorSpan.text(err.message); 322 | $el.after(errorSpan); 323 | } 324 | } else if (display === "block") { 325 | // If block, add an error just after the el, set visibility:none on the 326 | // el, and position the error to be on top of the el. 327 | // Mark it with a unique ID and CSS class so we can remove it later. 328 | $el.css("visibility", "hidden"); 329 | if (err.message !== "") { 330 | var errorDiv = $("
").addClass(errClass).css("position", "absolute") 331 | .css("top", el.offsetTop) 332 | .css("left", el.offsetLeft) 333 | // setting width can push out the page size, forcing otherwise 334 | // unnecessary scrollbars to appear and making it impossible for 335 | // the element to shrink; so use max-width instead 336 | .css("maxWidth", el.offsetWidth) 337 | .css("height", el.offsetHeight); 338 | errorDiv.text(err.message); 339 | $el.after(errorDiv); 340 | 341 | // Really dumb way to keep the size/position of the error in sync with 342 | // the parent element as the window is resized or whatever. 343 | var intId = setInterval(function() { 344 | if (!errorDiv[0].parentElement) { 345 | clearInterval(intId); 346 | return; 347 | } 348 | errorDiv 349 | .css("top", el.offsetTop) 350 | .css("left", el.offsetLeft) 351 | .css("maxWidth", el.offsetWidth) 352 | .css("height", el.offsetHeight); 353 | }, 500); 354 | } 355 | } 356 | }, 357 | clearError: function(el) { 358 | var $el = $(el); 359 | var display = $el.data("restore-display-mode"); 360 | $el.data("restore-display-mode", null); 361 | 362 | if (display === "inline" || display === "inline-block") { 363 | if (display) 364 | $el.css("display", display); 365 | $(el.nextSibling).filter(".htmlwidgets-error").remove(); 366 | } else if (display === "block"){ 367 | $el.css("visibility", "inherit"); 368 | $(el.nextSibling).filter(".htmlwidgets-error").remove(); 369 | } 370 | }, 371 | sizing: {} 372 | }; 373 | 374 | // Called by widget bindings to register a new type of widget. The definition 375 | // object can contain the following properties: 376 | // - name (required) - A string indicating the binding name, which will be 377 | // used by default as the CSS classname to look for. 378 | // - initialize (optional) - A function(el) that will be called once per 379 | // widget element; if a value is returned, it will be passed as the third 380 | // value to renderValue. 381 | // - renderValue (required) - A function(el, data, initValue) that will be 382 | // called with data. Static contexts will cause this to be called once per 383 | // element; Shiny apps will cause this to be called multiple times per 384 | // element, as the data changes. 385 | window.HTMLWidgets.widget = function(definition) { 386 | if (!definition.name) { 387 | throw new Error("Widget must have a name"); 388 | } 389 | if (!definition.type) { 390 | throw new Error("Widget must have a type"); 391 | } 392 | // Currently we only support output widgets 393 | if (definition.type !== "output") { 394 | throw new Error("Unrecognized widget type '" + definition.type + "'"); 395 | } 396 | // TODO: Verify that .name is a valid CSS classname 397 | 398 | // Support new-style instance-bound definitions. Old-style class-bound 399 | // definitions have one widget "object" per widget per type/class of 400 | // widget; the renderValue and resize methods on such widget objects 401 | // take el and instance arguments, because the widget object can't 402 | // store them. New-style instance-bound definitions have one widget 403 | // object per widget instance; the definition that's passed in doesn't 404 | // provide renderValue or resize methods at all, just the single method 405 | // factory(el, width, height) 406 | // which returns an object that has renderValue(x) and resize(w, h). 407 | // This enables a far more natural programming style for the widget 408 | // author, who can store per-instance state using either OO-style 409 | // instance fields or functional-style closure variables (I guess this 410 | // is in contrast to what can only be called C-style pseudo-OO which is 411 | // what we required before). 412 | if (definition.factory) { 413 | definition = createLegacyDefinitionAdapter(definition); 414 | } 415 | 416 | if (!definition.renderValue) { 417 | throw new Error("Widget must have a renderValue function"); 418 | } 419 | 420 | // For static rendering (non-Shiny), use a simple widget registration 421 | // scheme. We also use this scheme for Shiny apps/documents that also 422 | // contain static widgets. 423 | window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || []; 424 | // Merge defaults into the definition; don't mutate the original definition. 425 | var staticBinding = extend({}, defaults, definition); 426 | overrideMethod(staticBinding, "find", function(superfunc) { 427 | return function(scope) { 428 | var results = superfunc(scope); 429 | // Filter out Shiny outputs, we only want the static kind 430 | return filterByClass(results, "html-widget-output", false); 431 | }; 432 | }); 433 | window.HTMLWidgets.widgets.push(staticBinding); 434 | 435 | if (shinyMode) { 436 | // Shiny is running. Register the definition with an output binding. 437 | // The definition itself will not be the output binding, instead 438 | // we will make an output binding object that delegates to the 439 | // definition. This is because we foolishly used the same method 440 | // name (renderValue) for htmlwidgets definition and Shiny bindings 441 | // but they actually have quite different semantics (the Shiny 442 | // bindings receive data that includes lots of metadata that it 443 | // strips off before calling htmlwidgets renderValue). We can't 444 | // just ignore the difference because in some widgets it's helpful 445 | // to call this.renderValue() from inside of resize(), and if 446 | // we're not delegating, then that call will go to the Shiny 447 | // version instead of the htmlwidgets version. 448 | 449 | // Merge defaults with definition, without mutating either. 450 | var bindingDef = extend({}, defaults, definition); 451 | 452 | // This object will be our actual Shiny binding. 453 | var shinyBinding = new Shiny.OutputBinding(); 454 | 455 | // With a few exceptions, we'll want to simply use the bindingDef's 456 | // version of methods if they are available, otherwise fall back to 457 | // Shiny's defaults. NOTE: If Shiny's output bindings gain additional 458 | // methods in the future, and we want them to be overrideable by 459 | // HTMLWidget binding definitions, then we'll need to add them to this 460 | // list. 461 | delegateMethod(shinyBinding, bindingDef, "getId"); 462 | delegateMethod(shinyBinding, bindingDef, "onValueChange"); 463 | delegateMethod(shinyBinding, bindingDef, "onValueError"); 464 | delegateMethod(shinyBinding, bindingDef, "renderError"); 465 | delegateMethod(shinyBinding, bindingDef, "clearError"); 466 | delegateMethod(shinyBinding, bindingDef, "showProgress"); 467 | 468 | // The find, renderValue, and resize are handled differently, because we 469 | // want to actually decorate the behavior of the bindingDef methods. 470 | 471 | shinyBinding.find = function(scope) { 472 | var results = bindingDef.find(scope); 473 | 474 | // Only return elements that are Shiny outputs, not static ones 475 | var dynamicResults = results.filter(".html-widget-output"); 476 | 477 | // It's possible that whatever caused Shiny to think there might be 478 | // new dynamic outputs, also caused there to be new static outputs. 479 | // Since there might be lots of different htmlwidgets bindings, we 480 | // schedule execution for later--no need to staticRender multiple 481 | // times. 482 | if (results.length !== dynamicResults.length) 483 | scheduleStaticRender(); 484 | 485 | return dynamicResults; 486 | }; 487 | 488 | // Wrap renderValue to handle initialization, which unfortunately isn't 489 | // supported natively by Shiny at the time of this writing. 490 | 491 | shinyBinding.renderValue = function(el, data) { 492 | Shiny.renderDependencies(data.deps); 493 | // Resolve strings marked as javascript literals to objects 494 | if (!(data.evals instanceof Array)) data.evals = [data.evals]; 495 | for (var i = 0; data.evals && i < data.evals.length; i++) { 496 | window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]); 497 | } 498 | if (!bindingDef.renderOnNullValue) { 499 | if (data.x === null) { 500 | el.style.visibility = "hidden"; 501 | return; 502 | } else { 503 | el.style.visibility = "inherit"; 504 | } 505 | } 506 | if (!elementData(el, "initialized")) { 507 | initSizing(el); 508 | 509 | elementData(el, "initialized", true); 510 | if (bindingDef.initialize) { 511 | var result = bindingDef.initialize(el, el.offsetWidth, 512 | el.offsetHeight); 513 | elementData(el, "init_result", result); 514 | } 515 | } 516 | bindingDef.renderValue(el, data.x, elementData(el, "init_result")); 517 | evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]); 518 | }; 519 | 520 | // Only override resize if bindingDef implements it 521 | if (bindingDef.resize) { 522 | shinyBinding.resize = function(el, width, height) { 523 | // Shiny can call resize before initialize/renderValue have been 524 | // called, which doesn't make sense for widgets. 525 | if (elementData(el, "initialized")) { 526 | bindingDef.resize(el, width, height, elementData(el, "init_result")); 527 | } 528 | }; 529 | } 530 | 531 | Shiny.outputBindings.register(shinyBinding, bindingDef.name); 532 | } 533 | }; 534 | 535 | var scheduleStaticRenderTimerId = null; 536 | function scheduleStaticRender() { 537 | if (!scheduleStaticRenderTimerId) { 538 | scheduleStaticRenderTimerId = setTimeout(function() { 539 | scheduleStaticRenderTimerId = null; 540 | window.HTMLWidgets.staticRender(); 541 | }, 1); 542 | } 543 | } 544 | 545 | // Render static widgets after the document finishes loading 546 | // Statically render all elements that are of this widget's class 547 | window.HTMLWidgets.staticRender = function() { 548 | var bindings = window.HTMLWidgets.widgets || []; 549 | forEach(bindings, function(binding) { 550 | var matches = binding.find(document.documentElement); 551 | forEach(matches, function(el) { 552 | var sizeObj = initSizing(el, binding); 553 | 554 | if (hasClass(el, "html-widget-static-bound")) 555 | return; 556 | el.className = el.className + " html-widget-static-bound"; 557 | 558 | var initResult; 559 | if (binding.initialize) { 560 | initResult = binding.initialize(el, 561 | sizeObj ? sizeObj.getWidth() : el.offsetWidth, 562 | sizeObj ? sizeObj.getHeight() : el.offsetHeight 563 | ); 564 | elementData(el, "init_result", initResult); 565 | } 566 | 567 | if (binding.resize) { 568 | var lastSize = { 569 | w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, 570 | h: sizeObj ? sizeObj.getHeight() : el.offsetHeight 571 | }; 572 | var resizeHandler = function(e) { 573 | var size = { 574 | w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, 575 | h: sizeObj ? sizeObj.getHeight() : el.offsetHeight 576 | }; 577 | if (size.w === 0 && size.h === 0) 578 | return; 579 | if (size.w === lastSize.w && size.h === lastSize.h) 580 | return; 581 | lastSize = size; 582 | binding.resize(el, size.w, size.h, initResult); 583 | }; 584 | 585 | on(window, "resize", resizeHandler); 586 | 587 | // This is needed for cases where we're running in a Shiny 588 | // app, but the widget itself is not a Shiny output, but 589 | // rather a simple static widget. One example of this is 590 | // an rmarkdown document that has runtime:shiny and widget 591 | // that isn't in a render function. Shiny only knows to 592 | // call resize handlers for Shiny outputs, not for static 593 | // widgets, so we do it ourselves. 594 | if (window.jQuery) { 595 | window.jQuery(document).on( 596 | "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets", 597 | resizeHandler 598 | ); 599 | window.jQuery(document).on( 600 | "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets", 601 | resizeHandler 602 | ); 603 | } 604 | 605 | // This is needed for the specific case of ioslides, which 606 | // flips slides between display:none and display:block. 607 | // Ideally we would not have to have ioslide-specific code 608 | // here, but rather have ioslides raise a generic event, 609 | // but the rmarkdown package just went to CRAN so the 610 | // window to getting that fixed may be long. 611 | if (window.addEventListener) { 612 | // It's OK to limit this to window.addEventListener 613 | // browsers because ioslides itself only supports 614 | // such browsers. 615 | on(document, "slideenter", resizeHandler); 616 | on(document, "slideleave", resizeHandler); 617 | } 618 | } 619 | 620 | var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']"); 621 | if (scriptData) { 622 | var data = JSON.parse(scriptData.textContent || scriptData.text); 623 | // Resolve strings marked as javascript literals to objects 624 | if (!(data.evals instanceof Array)) data.evals = [data.evals]; 625 | for (var k = 0; data.evals && k < data.evals.length; k++) { 626 | window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]); 627 | } 628 | binding.renderValue(el, data.x, initResult); 629 | evalAndRun(data.jsHooks.render, initResult, [el, data.x]); 630 | } 631 | }); 632 | }); 633 | 634 | invokePostRenderHandlers(); 635 | } 636 | 637 | // Wait until after the document has loaded to render the widgets. 638 | if (document.addEventListener) { 639 | document.addEventListener("DOMContentLoaded", function() { 640 | document.removeEventListener("DOMContentLoaded", arguments.callee, false); 641 | window.HTMLWidgets.staticRender(); 642 | }, false); 643 | } else if (document.attachEvent) { 644 | document.attachEvent("onreadystatechange", function() { 645 | if (document.readyState === "complete") { 646 | document.detachEvent("onreadystatechange", arguments.callee); 647 | window.HTMLWidgets.staticRender(); 648 | } 649 | }); 650 | } 651 | 652 | 653 | window.HTMLWidgets.getAttachmentUrl = function(depname, key) { 654 | // If no key, default to the first item 655 | if (typeof(key) === "undefined") 656 | key = 1; 657 | 658 | var link = document.getElementById(depname + "-" + key + "-attachment"); 659 | if (!link) { 660 | throw new Error("Attachment " + depname + "/" + key + " not found in document"); 661 | } 662 | return link.getAttribute("href"); 663 | }; 664 | 665 | window.HTMLWidgets.dataframeToD3 = function(df) { 666 | var names = []; 667 | var length; 668 | for (var name in df) { 669 | if (df.hasOwnProperty(name)) 670 | names.push(name); 671 | if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") { 672 | throw new Error("All fields must be arrays"); 673 | } else if (typeof(length) !== "undefined" && length !== df[name].length) { 674 | throw new Error("All fields must be arrays of the same length"); 675 | } 676 | length = df[name].length; 677 | } 678 | var results = []; 679 | var item; 680 | for (var row = 0; row < length; row++) { 681 | item = {}; 682 | for (var col = 0; col < names.length; col++) { 683 | item[names[col]] = df[names[col]][row]; 684 | } 685 | results.push(item); 686 | } 687 | return results; 688 | }; 689 | 690 | window.HTMLWidgets.transposeArray2D = function(array) { 691 | if (array.length === 0) return array; 692 | var newArray = array[0].map(function(col, i) { 693 | return array.map(function(row) { 694 | return row[i] 695 | }) 696 | }); 697 | return newArray; 698 | }; 699 | // Split value at splitChar, but allow splitChar to be escaped 700 | // using escapeChar. Any other characters escaped by escapeChar 701 | // will be included as usual (including escapeChar itself). 702 | function splitWithEscape(value, splitChar, escapeChar) { 703 | var results = []; 704 | var escapeMode = false; 705 | var currentResult = ""; 706 | for (var pos = 0; pos < value.length; pos++) { 707 | if (!escapeMode) { 708 | if (value[pos] === splitChar) { 709 | results.push(currentResult); 710 | currentResult = ""; 711 | } else if (value[pos] === escapeChar) { 712 | escapeMode = true; 713 | } else { 714 | currentResult += value[pos]; 715 | } 716 | } else { 717 | currentResult += value[pos]; 718 | escapeMode = false; 719 | } 720 | } 721 | if (currentResult !== "") { 722 | results.push(currentResult); 723 | } 724 | return results; 725 | } 726 | // Function authored by Yihui/JJ Allaire 727 | window.HTMLWidgets.evaluateStringMember = function(o, member) { 728 | var parts = splitWithEscape(member, '.', '\\'); 729 | for (var i = 0, l = parts.length; i < l; i++) { 730 | var part = parts[i]; 731 | // part may be a character or 'numeric' member name 732 | if (o !== null && typeof o === "object" && part in o) { 733 | if (i == (l - 1)) { // if we are at the end of the line then evalulate 734 | if (typeof o[part] === "string") 735 | o[part] = eval("(" + o[part] + ")"); 736 | } else { // otherwise continue to next embedded object 737 | o = o[part]; 738 | } 739 | } 740 | } 741 | }; 742 | 743 | // Retrieve the HTMLWidget instance (i.e. the return value of an 744 | // HTMLWidget binding's initialize() or factory() function) 745 | // associated with an element, or null if none. 746 | window.HTMLWidgets.getInstance = function(el) { 747 | return elementData(el, "init_result"); 748 | }; 749 | 750 | // Finds the first element in the scope that matches the selector, 751 | // and returns the HTMLWidget instance (i.e. the return value of 752 | // an HTMLWidget binding's initialize() or factory() function) 753 | // associated with that element, if any. If no element matches the 754 | // selector, or the first matching element has no HTMLWidget 755 | // instance associated with it, then null is returned. 756 | // 757 | // The scope argument is optional, and defaults to window.document. 758 | window.HTMLWidgets.find = function(scope, selector) { 759 | if (arguments.length == 1) { 760 | selector = scope; 761 | scope = document; 762 | } 763 | 764 | var el = scope.querySelector(selector); 765 | if (el === null) { 766 | return null; 767 | } else { 768 | return window.HTMLWidgets.getInstance(el); 769 | } 770 | }; 771 | 772 | // Finds all elements in the scope that match the selector, and 773 | // returns the HTMLWidget instances (i.e. the return values of 774 | // an HTMLWidget binding's initialize() or factory() function) 775 | // associated with the elements, in an array. If elements that 776 | // match the selector don't have an associated HTMLWidget 777 | // instance, the returned array will contain nulls. 778 | // 779 | // The scope argument is optional, and defaults to window.document. 780 | window.HTMLWidgets.findAll = function(scope, selector) { 781 | if (arguments.length == 1) { 782 | selector = scope; 783 | scope = document; 784 | } 785 | 786 | var nodes = scope.querySelectorAll(selector); 787 | var results = []; 788 | for (var i = 0; i < nodes.length; i++) { 789 | results.push(window.HTMLWidgets.getInstance(nodes[i])); 790 | } 791 | return results; 792 | }; 793 | 794 | var postRenderHandlers = []; 795 | function invokePostRenderHandlers() { 796 | while (postRenderHandlers.length) { 797 | var handler = postRenderHandlers.shift(); 798 | if (handler) { 799 | handler(); 800 | } 801 | } 802 | } 803 | 804 | // Register the given callback function to be invoked after the 805 | // next time static widgets are rendered. 806 | window.HTMLWidgets.addPostRenderHandler = function(callback) { 807 | postRenderHandlers.push(callback); 808 | }; 809 | 810 | // Takes a new-style instance-bound definition, and returns an 811 | // old-style class-bound definition. This saves us from having 812 | // to rewrite all the logic in this file to accomodate both 813 | // types of definitions. 814 | function createLegacyDefinitionAdapter(defn) { 815 | var result = { 816 | name: defn.name, 817 | type: defn.type, 818 | initialize: function(el, width, height) { 819 | return defn.factory(el, width, height); 820 | }, 821 | renderValue: function(el, x, instance) { 822 | return instance.renderValue(x); 823 | }, 824 | resize: function(el, width, height, instance) { 825 | return instance.resize(width, height); 826 | } 827 | }; 828 | 829 | if (defn.find) 830 | result.find = defn.find; 831 | if (defn.renderError) 832 | result.renderError = defn.renderError; 833 | if (defn.clearError) 834 | result.clearError = defn.clearError; 835 | 836 | return result; 837 | } 838 | })(); 839 | 840 | -------------------------------------------------------------------------------- /libs/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2005, 2014 jQuery Foundation and other contributors, 2 | https://jquery.org/ 3 | 4 | This software consists of voluntary contributions made by many 5 | individuals. For exact contribution history, see the revision history 6 | available at https://github.com/jquery/jquery 7 | 8 | The following license applies to all parts of this software except as 9 | documented below: 10 | 11 | ==== 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining 14 | a copy of this software and associated documentation files (the 15 | "Software"), to deal in the Software without restriction, including 16 | without limitation the rights to use, copy, modify, merge, publish, 17 | distribute, sublicense, and/or sell copies of the Software, and to 18 | permit persons to whom the Software is furnished to do so, subject to 19 | the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be 22 | included in all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | 32 | ==== 33 | 34 | All files located in the node_modules and external directories are 35 | externally maintained libraries used by this software which have their 36 | own licenses; we recommend you read them, as their terms may differ from 37 | the terms above. 38 | -------------------------------------------------------------------------------- /libs/leaflet/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/layers-2x.png -------------------------------------------------------------------------------- /libs/leaflet/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/layers.png -------------------------------------------------------------------------------- /libs/leaflet/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-icon-2x.png -------------------------------------------------------------------------------- /libs/leaflet/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-icon.png -------------------------------------------------------------------------------- /libs/leaflet/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/leaflet/images/marker-shadow.png -------------------------------------------------------------------------------- /libs/leaflet/leaflet.css: -------------------------------------------------------------------------------- 1 | /* required styles */ 2 | 3 | .leaflet-pane, 4 | .leaflet-tile, 5 | .leaflet-marker-icon, 6 | .leaflet-marker-shadow, 7 | .leaflet-tile-container, 8 | .leaflet-pane > svg, 9 | .leaflet-pane > canvas, 10 | .leaflet-zoom-box, 11 | .leaflet-image-layer, 12 | .leaflet-layer { 13 | position: absolute; 14 | left: 0; 15 | top: 0; 16 | } 17 | .leaflet-container { 18 | overflow: hidden; 19 | } 20 | .leaflet-tile, 21 | .leaflet-marker-icon, 22 | .leaflet-marker-shadow { 23 | -webkit-user-select: none; 24 | -moz-user-select: none; 25 | user-select: none; 26 | -webkit-user-drag: none; 27 | } 28 | /* Safari renders non-retina tile on retina better with this, but Chrome is worse */ 29 | .leaflet-safari .leaflet-tile { 30 | image-rendering: -webkit-optimize-contrast; 31 | } 32 | /* hack that prevents hw layers "stretching" when loading new tiles */ 33 | .leaflet-safari .leaflet-tile-container { 34 | width: 1600px; 35 | height: 1600px; 36 | -webkit-transform-origin: 0 0; 37 | } 38 | .leaflet-marker-icon, 39 | .leaflet-marker-shadow { 40 | display: block; 41 | } 42 | /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ 43 | /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ 44 | .leaflet-container .leaflet-overlay-pane svg, 45 | .leaflet-container .leaflet-marker-pane img, 46 | .leaflet-container .leaflet-shadow-pane img, 47 | .leaflet-container .leaflet-tile-pane img, 48 | .leaflet-container img.leaflet-image-layer { 49 | max-width: none !important; 50 | max-height: none !important; 51 | } 52 | 53 | .leaflet-container.leaflet-touch-zoom { 54 | -ms-touch-action: pan-x pan-y; 55 | touch-action: pan-x pan-y; 56 | } 57 | .leaflet-container.leaflet-touch-drag { 58 | -ms-touch-action: pinch-zoom; 59 | /* Fallback for FF which doesn't support pinch-zoom */ 60 | touch-action: none; 61 | touch-action: pinch-zoom; 62 | } 63 | .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { 64 | -ms-touch-action: none; 65 | touch-action: none; 66 | } 67 | .leaflet-container { 68 | -webkit-tap-highlight-color: transparent; 69 | } 70 | .leaflet-container a { 71 | -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); 72 | } 73 | .leaflet-tile { 74 | filter: inherit; 75 | visibility: hidden; 76 | } 77 | .leaflet-tile-loaded { 78 | visibility: inherit; 79 | } 80 | .leaflet-zoom-box { 81 | width: 0; 82 | height: 0; 83 | -moz-box-sizing: border-box; 84 | box-sizing: border-box; 85 | z-index: 800; 86 | } 87 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ 88 | .leaflet-overlay-pane svg { 89 | -moz-user-select: none; 90 | } 91 | 92 | .leaflet-pane { z-index: 400; } 93 | 94 | .leaflet-tile-pane { z-index: 200; } 95 | .leaflet-overlay-pane { z-index: 400; } 96 | .leaflet-shadow-pane { z-index: 500; } 97 | .leaflet-marker-pane { z-index: 600; } 98 | .leaflet-tooltip-pane { z-index: 650; } 99 | .leaflet-popup-pane { z-index: 700; } 100 | 101 | .leaflet-map-pane canvas { z-index: 100; } 102 | .leaflet-map-pane svg { z-index: 200; } 103 | 104 | .leaflet-vml-shape { 105 | width: 1px; 106 | height: 1px; 107 | } 108 | .lvml { 109 | behavior: url(#default#VML); 110 | display: inline-block; 111 | position: absolute; 112 | } 113 | 114 | 115 | /* control positioning */ 116 | 117 | .leaflet-control { 118 | position: relative; 119 | z-index: 800; 120 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 121 | pointer-events: auto; 122 | } 123 | .leaflet-top, 124 | .leaflet-bottom { 125 | position: absolute; 126 | z-index: 1000; 127 | pointer-events: none; 128 | } 129 | .leaflet-top { 130 | top: 0; 131 | } 132 | .leaflet-right { 133 | right: 0; 134 | } 135 | .leaflet-bottom { 136 | bottom: 0; 137 | } 138 | .leaflet-left { 139 | left: 0; 140 | } 141 | .leaflet-control { 142 | float: left; 143 | clear: both; 144 | } 145 | .leaflet-right .leaflet-control { 146 | float: right; 147 | } 148 | .leaflet-top .leaflet-control { 149 | margin-top: 10px; 150 | } 151 | .leaflet-bottom .leaflet-control { 152 | margin-bottom: 10px; 153 | } 154 | .leaflet-left .leaflet-control { 155 | margin-left: 10px; 156 | } 157 | .leaflet-right .leaflet-control { 158 | margin-right: 10px; 159 | } 160 | 161 | 162 | /* zoom and fade animations */ 163 | 164 | .leaflet-fade-anim .leaflet-tile { 165 | will-change: opacity; 166 | } 167 | .leaflet-fade-anim .leaflet-popup { 168 | opacity: 0; 169 | -webkit-transition: opacity 0.2s linear; 170 | -moz-transition: opacity 0.2s linear; 171 | -o-transition: opacity 0.2s linear; 172 | transition: opacity 0.2s linear; 173 | } 174 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup { 175 | opacity: 1; 176 | } 177 | .leaflet-zoom-animated { 178 | -webkit-transform-origin: 0 0; 179 | -ms-transform-origin: 0 0; 180 | transform-origin: 0 0; 181 | } 182 | .leaflet-zoom-anim .leaflet-zoom-animated { 183 | will-change: transform; 184 | } 185 | .leaflet-zoom-anim .leaflet-zoom-animated { 186 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); 187 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); 188 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1); 189 | transition: transform 0.25s cubic-bezier(0,0,0.25,1); 190 | } 191 | .leaflet-zoom-anim .leaflet-tile, 192 | .leaflet-pan-anim .leaflet-tile { 193 | -webkit-transition: none; 194 | -moz-transition: none; 195 | -o-transition: none; 196 | transition: none; 197 | } 198 | 199 | .leaflet-zoom-anim .leaflet-zoom-hide { 200 | visibility: hidden; 201 | } 202 | 203 | 204 | /* cursors */ 205 | 206 | .leaflet-interactive { 207 | cursor: pointer; 208 | } 209 | .leaflet-grab { 210 | cursor: -webkit-grab; 211 | cursor: -moz-grab; 212 | } 213 | .leaflet-crosshair, 214 | .leaflet-crosshair .leaflet-interactive { 215 | cursor: crosshair; 216 | } 217 | .leaflet-popup-pane, 218 | .leaflet-control { 219 | cursor: auto; 220 | } 221 | .leaflet-dragging .leaflet-grab, 222 | .leaflet-dragging .leaflet-grab .leaflet-interactive, 223 | .leaflet-dragging .leaflet-marker-draggable { 224 | cursor: move; 225 | cursor: -webkit-grabbing; 226 | cursor: -moz-grabbing; 227 | } 228 | 229 | /* marker & overlays interactivity */ 230 | .leaflet-marker-icon, 231 | .leaflet-marker-shadow, 232 | .leaflet-image-layer, 233 | .leaflet-pane > svg path, 234 | .leaflet-tile-container { 235 | pointer-events: none; 236 | } 237 | 238 | .leaflet-marker-icon.leaflet-interactive, 239 | .leaflet-image-layer.leaflet-interactive, 240 | .leaflet-pane > svg path.leaflet-interactive { 241 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 242 | pointer-events: auto; 243 | } 244 | 245 | /* visual tweaks */ 246 | 247 | .leaflet-container { 248 | background: #ddd; 249 | outline: 0; 250 | } 251 | .leaflet-container a { 252 | color: #0078A8; 253 | } 254 | .leaflet-container a.leaflet-active { 255 | outline: 2px solid orange; 256 | } 257 | .leaflet-zoom-box { 258 | border: 2px dotted #38f; 259 | background: rgba(255,255,255,0.5); 260 | } 261 | 262 | 263 | /* general typography */ 264 | .leaflet-container { 265 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; 266 | } 267 | 268 | 269 | /* general toolbar styles */ 270 | 271 | .leaflet-bar { 272 | box-shadow: 0 1px 5px rgba(0,0,0,0.65); 273 | border-radius: 4px; 274 | } 275 | .leaflet-bar a, 276 | .leaflet-bar a:hover { 277 | background-color: #fff; 278 | border-bottom: 1px solid #ccc; 279 | width: 26px; 280 | height: 26px; 281 | line-height: 26px; 282 | display: block; 283 | text-align: center; 284 | text-decoration: none; 285 | color: black; 286 | } 287 | .leaflet-bar a, 288 | .leaflet-control-layers-toggle { 289 | background-position: 50% 50%; 290 | background-repeat: no-repeat; 291 | display: block; 292 | } 293 | .leaflet-bar a:hover { 294 | background-color: #f4f4f4; 295 | } 296 | .leaflet-bar a:first-child { 297 | border-top-left-radius: 4px; 298 | border-top-right-radius: 4px; 299 | } 300 | .leaflet-bar a:last-child { 301 | border-bottom-left-radius: 4px; 302 | border-bottom-right-radius: 4px; 303 | border-bottom: none; 304 | } 305 | .leaflet-bar a.leaflet-disabled { 306 | cursor: default; 307 | background-color: #f4f4f4; 308 | color: #bbb; 309 | } 310 | 311 | .leaflet-touch .leaflet-bar a { 312 | width: 30px; 313 | height: 30px; 314 | line-height: 30px; 315 | } 316 | .leaflet-touch .leaflet-bar a:first-child { 317 | border-top-left-radius: 2px; 318 | border-top-right-radius: 2px; 319 | } 320 | .leaflet-touch .leaflet-bar a:last-child { 321 | border-bottom-left-radius: 2px; 322 | border-bottom-right-radius: 2px; 323 | } 324 | 325 | /* zoom control */ 326 | 327 | .leaflet-control-zoom-in, 328 | .leaflet-control-zoom-out { 329 | font: bold 18px 'Lucida Console', Monaco, monospace; 330 | text-indent: 1px; 331 | } 332 | 333 | .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { 334 | font-size: 22px; 335 | } 336 | 337 | 338 | /* layers control */ 339 | 340 | .leaflet-control-layers { 341 | box-shadow: 0 1px 5px rgba(0,0,0,0.4); 342 | background: #fff; 343 | border-radius: 5px; 344 | } 345 | .leaflet-control-layers-toggle { 346 | background-image: url(images/layers.png); 347 | width: 36px; 348 | height: 36px; 349 | } 350 | .leaflet-retina .leaflet-control-layers-toggle { 351 | background-image: url(images/layers-2x.png); 352 | background-size: 26px 26px; 353 | } 354 | .leaflet-touch .leaflet-control-layers-toggle { 355 | width: 44px; 356 | height: 44px; 357 | } 358 | .leaflet-control-layers .leaflet-control-layers-list, 359 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle { 360 | display: none; 361 | } 362 | .leaflet-control-layers-expanded .leaflet-control-layers-list { 363 | display: block; 364 | position: relative; 365 | } 366 | .leaflet-control-layers-expanded { 367 | padding: 6px 10px 6px 6px; 368 | color: #333; 369 | background: #fff; 370 | } 371 | .leaflet-control-layers-scrollbar { 372 | overflow-y: scroll; 373 | overflow-x: hidden; 374 | padding-right: 5px; 375 | } 376 | .leaflet-control-layers-selector { 377 | margin-top: 2px; 378 | position: relative; 379 | top: 1px; 380 | } 381 | .leaflet-control-layers label { 382 | display: block; 383 | } 384 | .leaflet-control-layers-separator { 385 | height: 0; 386 | border-top: 1px solid #ddd; 387 | margin: 5px -10px 5px -6px; 388 | } 389 | 390 | /* Default icon URLs */ 391 | .leaflet-default-icon-path { 392 | background-image: url(images/marker-icon.png); 393 | } 394 | 395 | 396 | /* attribution and scale controls */ 397 | 398 | .leaflet-container .leaflet-control-attribution { 399 | background: #fff; 400 | background: rgba(255, 255, 255, 0.7); 401 | margin: 0; 402 | } 403 | .leaflet-control-attribution, 404 | .leaflet-control-scale-line { 405 | padding: 0 5px; 406 | color: #333; 407 | } 408 | .leaflet-control-attribution a { 409 | text-decoration: none; 410 | } 411 | .leaflet-control-attribution a:hover { 412 | text-decoration: underline; 413 | } 414 | .leaflet-container .leaflet-control-attribution, 415 | .leaflet-container .leaflet-control-scale { 416 | font-size: 11px; 417 | } 418 | .leaflet-left .leaflet-control-scale { 419 | margin-left: 5px; 420 | } 421 | .leaflet-bottom .leaflet-control-scale { 422 | margin-bottom: 5px; 423 | } 424 | .leaflet-control-scale-line { 425 | border: 2px solid #777; 426 | border-top: none; 427 | line-height: 1.1; 428 | padding: 2px 5px 1px; 429 | font-size: 11px; 430 | white-space: nowrap; 431 | overflow: hidden; 432 | -moz-box-sizing: border-box; 433 | box-sizing: border-box; 434 | 435 | background: #fff; 436 | background: rgba(255, 255, 255, 0.5); 437 | } 438 | .leaflet-control-scale-line:not(:first-child) { 439 | border-top: 2px solid #777; 440 | border-bottom: none; 441 | margin-top: -2px; 442 | } 443 | .leaflet-control-scale-line:not(:first-child):not(:last-child) { 444 | border-bottom: 2px solid #777; 445 | } 446 | 447 | .leaflet-touch .leaflet-control-attribution, 448 | .leaflet-touch .leaflet-control-layers, 449 | .leaflet-touch .leaflet-bar { 450 | box-shadow: none; 451 | } 452 | .leaflet-touch .leaflet-control-layers, 453 | .leaflet-touch .leaflet-bar { 454 | border: 2px solid rgba(0,0,0,0.2); 455 | background-clip: padding-box; 456 | } 457 | 458 | 459 | /* popup */ 460 | 461 | .leaflet-popup { 462 | position: absolute; 463 | text-align: center; 464 | margin-bottom: 20px; 465 | } 466 | .leaflet-popup-content-wrapper { 467 | padding: 1px; 468 | text-align: left; 469 | border-radius: 12px; 470 | } 471 | .leaflet-popup-content { 472 | margin: 13px 19px; 473 | line-height: 1.4; 474 | } 475 | .leaflet-popup-content p { 476 | margin: 18px 0; 477 | } 478 | .leaflet-popup-tip-container { 479 | width: 40px; 480 | height: 20px; 481 | position: absolute; 482 | left: 50%; 483 | margin-left: -20px; 484 | overflow: hidden; 485 | pointer-events: none; 486 | } 487 | .leaflet-popup-tip { 488 | width: 17px; 489 | height: 17px; 490 | padding: 1px; 491 | 492 | margin: -10px auto 0; 493 | 494 | -webkit-transform: rotate(45deg); 495 | -moz-transform: rotate(45deg); 496 | -ms-transform: rotate(45deg); 497 | -o-transform: rotate(45deg); 498 | transform: rotate(45deg); 499 | } 500 | .leaflet-popup-content-wrapper, 501 | .leaflet-popup-tip { 502 | background: white; 503 | color: #333; 504 | box-shadow: 0 3px 14px rgba(0,0,0,0.4); 505 | } 506 | .leaflet-container a.leaflet-popup-close-button { 507 | position: absolute; 508 | top: 0; 509 | right: 0; 510 | padding: 4px 4px 0 0; 511 | border: none; 512 | text-align: center; 513 | width: 18px; 514 | height: 14px; 515 | font: 16px/14px Tahoma, Verdana, sans-serif; 516 | color: #c3c3c3; 517 | text-decoration: none; 518 | font-weight: bold; 519 | background: transparent; 520 | } 521 | .leaflet-container a.leaflet-popup-close-button:hover { 522 | color: #999; 523 | } 524 | .leaflet-popup-scrolled { 525 | overflow: auto; 526 | border-bottom: 1px solid #ddd; 527 | border-top: 1px solid #ddd; 528 | } 529 | 530 | .leaflet-oldie .leaflet-popup-content-wrapper { 531 | zoom: 1; 532 | } 533 | .leaflet-oldie .leaflet-popup-tip { 534 | width: 24px; 535 | margin: 0 auto; 536 | 537 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 538 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 539 | } 540 | .leaflet-oldie .leaflet-popup-tip-container { 541 | margin-top: -1px; 542 | } 543 | 544 | .leaflet-oldie .leaflet-control-zoom, 545 | .leaflet-oldie .leaflet-control-layers, 546 | .leaflet-oldie .leaflet-popup-content-wrapper, 547 | .leaflet-oldie .leaflet-popup-tip { 548 | border: 1px solid #999; 549 | } 550 | 551 | 552 | /* div icon */ 553 | 554 | .leaflet-div-icon { 555 | background: #fff; 556 | border: 1px solid #666; 557 | } 558 | 559 | 560 | /* Tooltip */ 561 | /* Base styles for the element that has a tooltip */ 562 | .leaflet-tooltip { 563 | position: absolute; 564 | padding: 6px; 565 | background-color: #fff; 566 | border: 1px solid #fff; 567 | border-radius: 3px; 568 | color: #222; 569 | white-space: nowrap; 570 | -webkit-user-select: none; 571 | -moz-user-select: none; 572 | -ms-user-select: none; 573 | user-select: none; 574 | pointer-events: none; 575 | box-shadow: 0 1px 3px rgba(0,0,0,0.4); 576 | } 577 | .leaflet-tooltip.leaflet-clickable { 578 | cursor: pointer; 579 | pointer-events: auto; 580 | } 581 | .leaflet-tooltip-top:before, 582 | .leaflet-tooltip-bottom:before, 583 | .leaflet-tooltip-left:before, 584 | .leaflet-tooltip-right:before { 585 | position: absolute; 586 | pointer-events: none; 587 | border: 6px solid transparent; 588 | background: transparent; 589 | content: ""; 590 | } 591 | 592 | /* Directions */ 593 | 594 | .leaflet-tooltip-bottom { 595 | margin-top: 6px; 596 | } 597 | .leaflet-tooltip-top { 598 | margin-top: -6px; 599 | } 600 | .leaflet-tooltip-bottom:before, 601 | .leaflet-tooltip-top:before { 602 | left: 50%; 603 | margin-left: -6px; 604 | } 605 | .leaflet-tooltip-top:before { 606 | bottom: 0; 607 | margin-bottom: -12px; 608 | border-top-color: #fff; 609 | } 610 | .leaflet-tooltip-bottom:before { 611 | top: 0; 612 | margin-top: -12px; 613 | margin-left: -6px; 614 | border-bottom-color: #fff; 615 | } 616 | .leaflet-tooltip-left { 617 | margin-left: -6px; 618 | } 619 | .leaflet-tooltip-right { 620 | margin-left: 6px; 621 | } 622 | .leaflet-tooltip-left:before, 623 | .leaflet-tooltip-right:before { 624 | top: 50%; 625 | margin-top: -6px; 626 | } 627 | .leaflet-tooltip-left:before { 628 | right: 0; 629 | margin-right: -12px; 630 | border-left-color: #fff; 631 | } 632 | .leaflet-tooltip-right:before { 633 | left: 0; 634 | margin-left: -12px; 635 | border-right-color: #fff; 636 | } 637 | -------------------------------------------------------------------------------- /libs/leafletfix/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 | margin-right: 4px; 30 | opacity: 0.7; 31 | display: inline-block; 32 | vertical-align: top; 33 | /*For IE 7*/ 34 | zoom: 1; 35 | *display: inline; 36 | } 37 | -------------------------------------------------------------------------------- /libs/remark-css/default.css: -------------------------------------------------------------------------------- 1 | a, a > code { 2 | color: rgb(249, 38, 114); 3 | text-decoration: none; 4 | } 5 | .footnote { 6 | position: absolute; 7 | bottom: 3em; 8 | padding-right: 4em; 9 | font-size: 90%; 10 | } 11 | .remark-code-line-highlighted { background-color: #ffff88; } 12 | 13 | .inverse { 14 | background-color: #272822; 15 | color: #d6d6d6; 16 | text-shadow: 0 0 20px #333; 17 | } 18 | .inverse h1, .inverse h2, .inverse h3 { 19 | color: #f3f3f3; 20 | } 21 | /* Two-column layout */ 22 | .left-column { 23 | color: #777; 24 | width: 20%; 25 | height: 92%; 26 | float: left; 27 | } 28 | .left-column h2:last-of-type, .left-column h3:last-child { 29 | color: #000; 30 | } 31 | .right-column { 32 | width: 75%; 33 | float: right; 34 | padding-top: 1em; 35 | } 36 | .pull-left { 37 | float: left; 38 | width: 47%; 39 | } 40 | .pull-right { 41 | float: right; 42 | width: 47%; 43 | } 44 | .pull-right ~ * { 45 | clear: both; 46 | } 47 | img, video, iframe { 48 | max-width: 100%; 49 | } 50 | blockquote { 51 | border-left: solid 5px lightgray; 52 | padding-left: 1em; 53 | } 54 | .remark-slide table { 55 | margin: auto; 56 | border-top: 1px solid #666; 57 | border-bottom: 1px solid #666; 58 | } 59 | .remark-slide table thead th { border-bottom: 1px solid #ddd; } 60 | th, td { padding: 5px; } 61 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } 62 | 63 | @page { margin: 0; } 64 | @media print { 65 | .remark-slide-scaler { 66 | width: 100% !important; 67 | height: 100% !important; 68 | transform: scale(1) !important; 69 | top: 0 !important; 70 | left: 0 !important; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /libs/remark-css/lucy-fonts.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Lato); 2 | @import url(https://fonts.googleapis.com/css?family=Anton); 3 | @import url('https://fonts.googleapis.com/css?family=Inconsolata:400,700'); 4 | 5 | body, h2, h3 { 6 | font-family: 'Lato', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; 7 | } 8 | 9 | h1 { 10 | font-family: 'Anton'; 11 | } 12 | 13 | .remark-code, .remark-inline-code { 14 | font-family: 'Inconsolata', 'Lucida Console', Monaco, monospace; 15 | } 16 | -------------------------------------------------------------------------------- /libs/remark-css/rladies.css: -------------------------------------------------------------------------------- 1 | h1, h2, h3 { 2 | font-weight: normal; 3 | color: #562457; 4 | } 5 | a, a > code { 6 | color: #88398a; 7 | } 8 | .remark-code-line-highlighted { background-color: rgba(136, 57, 138, 0.3); } 9 | 10 | .inverse { 11 | background-color: #562457; 12 | } 13 | .inverse, .inverse h1, .inverse h2, .inverse h3, .inverse a, inverse a > code { 14 | color: #fff; 15 | } 16 | -------------------------------------------------------------------------------- /libs/rstudio_leaflet/images/1px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhiiiyang/XaringanTutorial/63944704a4b41a9497bd86669ac23a02c13f5107/libs/rstudio_leaflet/images/1px.png -------------------------------------------------------------------------------- /libs/rstudio_leaflet/rstudio_leaflet.css: -------------------------------------------------------------------------------- 1 | .leaflet-tooltip.leaflet-tooltip-text-only, 2 | .leaflet-tooltip.leaflet-tooltip-text-only:before, 3 | .leaflet-tooltip.leaflet-tooltip-text-only:after { 4 | background: none; 5 | border: none; 6 | box-shadow: none; 7 | } 8 | 9 | .leaflet-tooltip.leaflet-tooltip-text-only.leaflet-tooltip-left { 10 | margin-left: 5px; 11 | } 12 | 13 | .leaflet-tooltip.leaflet-tooltip-text-only.leaflet-tooltip-right { 14 | margin-left: -5px; 15 | } 16 | 17 | .leaflet-tooltip:after { 18 | border-right: 6px solid transparent; 19 | /* right: -16px; */ 20 | } 21 | 22 | .leaflet-popup-pane .leaflet-popup-tip-container { 23 | /* when the tooltip container is clicked, it is closed */ 24 | pointer-events: all; 25 | /* tooltips should display the "hand" icon, just like .leaflet-interactive*/ 26 | cursor: pointer; 27 | } 28 | 29 | /* have the widget be displayed in the right 'layer' */ 30 | .leaflet-map-pane { 31 | z-index: auto; 32 | } 33 | -------------------------------------------------------------------------------- /my-style.css: -------------------------------------------------------------------------------- 1 | .red { color: red; } 2 | .remark-code-line-highlighted { background-color: #e8c9e9; } 3 | .remark-code, .remark-inline-code { 4 | color: #7c347f; 5 | font-weight: 300; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /templates/xaringan-themer.css: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------- 2 | * 3 | * !! This file was generated by xaringanthemer !! 4 | * 5 | * Changes made to this file directly will be overwritten 6 | * if you used xaringanthemer in your xaringan slides Rmd 7 | * 8 | * Issues or likes? 9 | * - https://github.com/gadenbuie/xaringanthemer 10 | * - https://www.garrickadenbuie.com 11 | * 12 | * Need help? Try: 13 | * - vignette(package = "xaringanthemer") 14 | * - ?xaringanthemer::write_xaringan_theme 15 | * - xaringan wiki: https://github.com/yihui/xaringan/wiki 16 | * - remarkjs wiki: https://github.com/gnab/remark/wiki 17 | * 18 | * ------------------------------------------------------- */ 19 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); 20 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); 21 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700); 22 | 23 | 24 | body { 25 | font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; 26 | font-weight: normal; 27 | color: #000; 28 | } 29 | h1, h2, h3 { 30 | font-family: 'Yanone Kaffeesatz'; 31 | font-weight: normal; 32 | color: #FFFFF; 33 | } 34 | .remark-slide-content { 35 | background-color: #FFF; 36 | font-size: 20px; 37 | 38 | 39 | 40 | padding: 1em 4em 1em 4em; 41 | } 42 | .remark-slide-content h1 { 43 | font-size: 55px; 44 | } 45 | .remark-slide-content h2 { 46 | font-size: 45px; 47 | } 48 | .remark-slide-content h3 { 49 | font-size: 35px; 50 | } 51 | .remark-code, .remark-inline-code { 52 | font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; 53 | } 54 | .remark-code { 55 | font-size: 0.9em; 56 | } 57 | .remark-inline-code { 58 | font-size: 1em; 59 | color: #000; 60 | 61 | 62 | } 63 | .remark-slide-number { 64 | color: #272822; 65 | opacity: 1; 66 | font-size: 0.9em; 67 | } 68 | 69 | a, a > code { 70 | color: rgb(249, 38, 114); 71 | text-decoration: none; 72 | } 73 | .footnote { 74 | 75 | position: absolute; 76 | bottom: 3em; 77 | padding-right: 4em; 78 | font-size: 0.9em; 79 | } 80 | .remark-code-line-highlighted { 81 | background-color: rgba(255,255,0,0.5); 82 | } 83 | .inverse { 84 | background-color: #272822; 85 | color: #d6d6d6; 86 | 87 | } 88 | .inverse h1, .inverse h2, .inverse h3 { 89 | color: #f3f3f3; 90 | } 91 | .title-slide, .title-slide h1, .title-slide h2, .title-slide h3 { 92 | color: #d6d6d6; 93 | } 94 | .title-slide { 95 | background-color: #272822; 96 | 97 | 98 | 99 | } 100 | .title-slide .remark-slide-number { 101 | display: none; 102 | } 103 | /* Two-column layout */ 104 | .left-column { 105 | width: 20%; 106 | height: 92%; 107 | float: left; 108 | } 109 | .left-column h2, .left-column h3 { 110 | color: #777; 111 | } 112 | .left-column h2:last-of-type, .left-column h3:last-child { 113 | color: #000; 114 | } 115 | .right-column { 116 | width: 75%; 117 | float: right; 118 | padding-top: 1em; 119 | } 120 | .pull-left { 121 | float: left; 122 | width: 47%; 123 | } 124 | .pull-right { 125 | float: right; 126 | width: 47%; 127 | } 128 | .pull-right ~ * { 129 | clear: both; 130 | } 131 | img, video, iframe { 132 | max-width: 100%; 133 | } 134 | blockquote { 135 | border-left: solid 5px lightgray; 136 | padding-left: 1em; 137 | } 138 | .remark-slide table { 139 | margin: auto; 140 | border-top: 1px solid #666; 141 | border-bottom: 1px solid #666; 142 | } 143 | .remark-slide table thead th { border-bottom: 1px solid #ddd; } 144 | th, td { padding: 5px; } 145 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } 146 | table.dataTable tbody { 147 | background-color: #FFF; 148 | color: #000; 149 | } 150 | table.dataTable.display tbody tr.odd { 151 | background-color: #FFF; 152 | } 153 | table.dataTable.display tbody tr.even { 154 | background-color: #eee; 155 | } 156 | table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { 157 | background-color: rgba(255, 255, 255, 0.5); 158 | } 159 | .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate { 160 | color: #000; 161 | } 162 | .dataTables_wrapper .dataTables_paginate .paginate_button { 163 | color: #000 !important; 164 | } 165 | 166 | @page { margin: 0; } 167 | @media print { 168 | .remark-slide-scaler { 169 | width: 100% !important; 170 | height: 100% !important; 171 | transform: scale(1) !important; 172 | top: 0 !important; 173 | left: 0 !important; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /templates/xaringanthemer.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "
OCRUG Themed Presentation \u6A59" 3 | subtitle: "with xaringan and xaringanthemer" 4 | author: "Zhi Yang" 5 | date: '`r Sys.Date()`' 6 | output: 7 | xaringan::moon_reader: 8 | lib_dir: libs 9 | css: xaringan-themer.css 10 | nature: 11 | highlightStyle: github 12 | highlightLines: true 13 | countIncrementalSlides: false 14 | --- 15 | 16 | ```{r setup, include=FALSE} 17 | options(htmltools.dir.version = FALSE) 18 | ``` 19 | 20 | ```{r xaringan-themer, include=FALSE, eval=TRUE} 21 | library(xaringanthemer) 22 | mono_accent( 23 | base_color = "#f38313", 24 | code_highlight_color = "#fce6cf" 25 | ) 26 | ``` 27 | 28 | 29 | # Hello World 30 | 31 | Install the **xaringan** package from [Github](https://github.com/yihui/xaringan): 32 | 33 | ```{r eval=FALSE, tidy=FALSE} 34 | devtools::install_github("yihui/xaringan") #<< 35 | plot(cars) 36 | ``` 37 | 38 | 39 | You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to. 40 | 41 | - Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;1 42 | 43 | 44 | - Click the `Knit` button to compile it; 45 | 46 | 47 | - or use the [RStudio Addin](https://rstudio.github.io/rstudioaddins/)2 "Infinite Moon Reader" to live preview the slides (every time you update and save the Rmd document, the slides will be automatically reloaded in RStudio Viewer. 48 | 49 | -------------------------------------------------------------------------------- /templates/xaringanthemer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | OCRUG Themed Presentation 橙 5 | 6 | 7 | 8 | 9 | 10 | 11 | 48 | 49 | 63 | 64 | 82 | 83 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /templates/yihui.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Presentation Ninja" 3 | subtitle: "⚔
with xaringan" 4 | author: "Yihui Xie" 5 | date: "2016/12/12 (updated: `r Sys.Date()`)" 6 | output: 7 | xaringan::moon_reader: 8 | lib_dir: libs 9 | nature: 10 | highlightStyle: github 11 | highlightLines: true 12 | countIncrementalSlides: false 13 | --- 14 | 15 | ```{r setup, include=FALSE} 16 | options(htmltools.dir.version = FALSE) 17 | ``` 18 | 19 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharingan_triple.svg) 20 | 21 | ??? 22 | 23 | Image credit: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Sharingan_triple.svg) 24 | 25 | --- 26 | class: center, middle 27 | 28 | # xaringan 29 | 30 | ### /ʃæ.'riŋ.ɡæn/ 31 | 32 | --- 33 | class: inverse, center, middle 34 | 35 | # Get Started 36 | 37 | --- 38 | 39 | # Hello World 40 | 41 | Install the **xaringan** package from [Github](https://github.com/yihui/xaringan): 42 | 43 | ```{r eval=FALSE, tidy=FALSE} 44 | devtools::install_github("yihui/xaringan") 45 | ``` 46 | 47 | -- 48 | 49 | You are recommended to use the [RStudio IDE](https://www.rstudio.com/products/rstudio/), but you do not have to. 50 | 51 | - Create a new R Markdown document from the menu `File -> New File -> R Markdown -> From Template -> Ninja Presentation`;1 52 | 53 | -- 54 | 55 | - Click the `Knit` button to compile it; 56 | 57 | -- 58 | 59 | - or use the [RStudio Addin](https://rstudio.github.io/rstudioaddins/)2 "Infinite Moon Reader" to live preview the slides (every time you update and save the Rmd document, the slides will be automatically reloaded in RStudio Viewer. 60 | 61 | .footnote[ 62 | [1] 中文用户请看[这份教程](http://slides.yihui.name/xaringan/zh-CN.html) 63 | 64 | [2] See [#2](https://github.com/yihui/xaringan/issues/2) if you do not see the template or addin in RStudio. 65 | ] 66 | 67 | --- 68 | background-image: url(`r xaringan:::karl`) 69 | background-position: 50% 50% 70 | class: center, bottom, inverse 71 | 72 | # You only live once! 73 | 74 | --- 75 | 76 | # Hello Ninja 77 | 78 | As a presentation ninja, you certainly should not be satisfied by the "Hello World" example. You need to understand more about two things: 79 | 80 | 1. The [remark.js](https://remarkjs.com) library; 81 | 82 | 1. The **xaringan** package; 83 | 84 | Basically **xaringan** injected the chakra of R Markdown (minus Pandoc) into **remark.js**. The slides are rendered by remark.js in the web browser, and the Markdown source needed by remark.js is generated from R Markdown (**knitr**). 85 | 86 | --- 87 | 88 | # remark.js 89 | 90 | You can see an introduction of remark.js from [its homepage](https://remarkjs.com). You should read the [remark.js Wiki](https://github.com/gnab/remark/wiki) at least once to know how to 91 | 92 | - create a new slide (Markdown syntax* and slide properties); 93 | 94 | - format a slide (e.g. text alignment); 95 | 96 | - configure the slideshow; 97 | 98 | - and use the presentation (keyboard shortcuts). 99 | 100 | It is important to be familiar with remark.js before you can understand the options in **xaringan**. 101 | 102 | .footnote[[*] It is different with Pandoc's Markdown! It is limited but should be enough for presentation purposes. Come on... You do not need a slide for the Table of Contents! Well, the Markdown support in remark.js [may be improved](https://github.com/gnab/remark/issues/142) in the future.] 103 | 104 | --- 105 | background-image: url(`r xaringan:::karl`) 106 | background-size: cover 107 | class: center, bottom, inverse 108 | 109 | # I was so happy to have discovered remark.js! 110 | 111 | --- 112 | class: inverse, middle, center 113 | 114 | # Using xaringan 115 | 116 | --- 117 | 118 | # xaringan 119 | 120 | Provides an R Markdown output format `xaringan::moon_reader` as a wrapper for remark.js, and you can use it in the YAML metadata, e.g. 121 | 122 | ```yaml 123 | --- 124 | title: "A Cool Presentation" 125 | output: 126 | xaringan::moon_reader: 127 | yolo: true 128 | nature: 129 | autoplay: 30000 130 | --- 131 | ``` 132 | 133 | See the help page `?xaringan::moon_reader` for all possible options that you can use. 134 | 135 | --- 136 | 137 | # remark.js vs xaringan 138 | 139 | Some differences between using remark.js (left) and using **xaringan** (right): 140 | 141 | .pull-left[ 142 | 1. Start with a boilerplate HTML file; 143 | 144 | 1. Plain Markdown; 145 | 146 | 1. Write JavaScript to autoplay slides; 147 | 148 | 1. Manually configure MathJax; 149 | 150 | 1. Highlight code with `*`; 151 | 152 | 1. Edit Markdown source and refresh browser to see updated slides; 153 | ] 154 | 155 | .pull-right[ 156 | 1. Start with an R Markdown document; 157 | 158 | 1. R Markdown (can embed R/other code chunks); 159 | 160 | 1. Provide an option `autoplay`; 161 | 162 | 1. MathJax just works;* 163 | 164 | 1. Highlight code with `{{}}`; 165 | 166 | 1. The RStudio addin "Infinite Moon Reader" automatically refreshes slides on changes; 167 | ] 168 | 169 | .footnote[[*] Not really. See next page.] 170 | 171 | --- 172 | 173 | # Math Expressions 174 | 175 | You can write LaTeX math expressions inside a pair of dollar signs, e.g. $\alpha+\beta$ renders $\alpha+\beta$. You can use the display style with double dollar signs: 176 | 177 | ``` 178 | $$\bar{X}=\frac{1}{n}\sum_{i=1}^nX_i$$ 179 | ``` 180 | 181 | $$\bar{X}=\frac{1}{n}\sum_{i=1}^nX_i$$ 182 | 183 | Limitations: 184 | 185 | 1. The source code of a LaTeX math expression must be in one line, unless it is inside a pair of double dollar signs, in which case the starting `$$` must appear in the very beginning of a line, followed immediately by a non-space character, and the ending `$$` must be at the end of a line, led by a non-space character; 186 | 187 | 1. There should not be spaces after the opening `$` or before the closing `$`. 188 | 189 | 1. Math does not work on the title slide (see [#61](https://github.com/yihui/xaringan/issues/61) for a workaround). 190 | 191 | --- 192 | 193 | # R Code 194 | 195 | ```{r comment='#'} 196 | # a boring regression 197 | fit = lm(dist ~ 1 + speed, data = cars) 198 | coef(summary(fit)) 199 | dojutsu = c('地爆天星', '天照', '加具土命', '神威', '須佐能乎', '無限月読') 200 | grep('天', dojutsu, value = TRUE) 201 | ``` 202 | 203 | --- 204 | 205 | # R Plots 206 | 207 | ```{r cars, fig.height=4, dev='svg'} 208 | par(mar = c(4, 4, 1, .1)) 209 | plot(cars, pch = 19, col = 'darkgray', las = 1) 210 | abline(fit, lwd = 2) 211 | ``` 212 | 213 | --- 214 | 215 | # Tables 216 | 217 | If you want to generate a table, make sure it is in the HTML format (instead of Markdown or other formats), e.g., 218 | 219 | ```{r} 220 | knitr::kable(head(iris), format = 'html') 221 | ``` 222 | 223 | --- 224 | 225 | # HTML Widgets 226 | 227 | I have not thoroughly tested HTML widgets against **xaringan**. Some may work well, and some may not. It is a little tricky. 228 | 229 | Similarly, the Shiny mode (`runtime: shiny`) does not work. I might get these issues fixed in the future, but these are not of high priority to me. I never turn my presentation into a Shiny app. When I need to demonstrate more complicated examples, I just launch them separately. It is convenient to share slides with other people when they are plain HTML/JS applications. 230 | 231 | See the next page for two HTML widgets. 232 | 233 | --- 234 | 235 | ```{r out.width='100%', fig.height=6, eval=require('leaflet')} 236 | library(leaflet) 237 | leaflet() %>% addTiles() %>% setView(-93.65, 42.0285, zoom = 17) 238 | ``` 239 | 240 | --- 241 | 242 | ```{r eval=require('DT'), tidy=FALSE} 243 | DT::datatable( 244 | head(iris, 10), 245 | fillContainer = FALSE, options = list(pageLength = 8) 246 | ) 247 | ``` 248 | 249 | --- 250 | 251 | # Some Tips 252 | 253 | - When you use the "Infinite Moon Reader" addin in RStudio, your R session will be blocked by default. You can click the red button on the right of the console to stop serving the slides, or use the _daemonized_ mode so that it does not block your R session. To do the latter, you can set the option 254 | 255 | ```r 256 | options(servr.daemon = TRUE) 257 | ``` 258 | 259 | in your current R session, or in `~/.Rprofile` so that it is applied to all future R sessions. I do the latter by myself. 260 | 261 | To know more about the web server, see the [**servr**](https://github.com/yihui/servr) package. 262 | 263 | -- 264 | 265 | - Do not forget to try the `yolo` option of `xaringan::moon_reader`. 266 | 267 | ```yaml 268 | output: 269 | xaringan::moon_reader: 270 | yolo: true 271 | ``` 272 | 273 | --- 274 | 275 | # Some Tips 276 | 277 | - Slides can be automatically played if you set the `autoplay` option under `nature`, e.g. go to the next slide every 30 seconds in a lightning talk: 278 | 279 | ```yaml 280 | output: 281 | xaringan::moon_reader: 282 | nature: 283 | autoplay: 30000 284 | ``` 285 | 286 | -- 287 | 288 | - A countdown timer can be added to every page of the slides using the `countdown` option under `nature`, e.g. if you want to spend one minute on every page when you give the talk, you can set: 289 | 290 | ```yaml 291 | output: 292 | xaringan::moon_reader: 293 | nature: 294 | countdown: 60000 295 | ``` 296 | 297 | Then you will see a timer counting down from `01:00`, to `00:59`, `00:58`, ... When the time is out, the timer will continue but the time turns red. 298 | 299 | --- 300 | 301 | # Some Tips 302 | 303 | - The title slide is created automatically by **xaringan**, but it is just another remark.js slide added before your other slides. 304 | 305 | The title slide is set to `class: center, middle, inverse, title-slide` by default. You can change the classes applied to the title slide with the `titleSlideClass` option of `nature` (`title-slide` is always applied). 306 | 307 | ```yaml 308 | output: 309 | xaringan::moon_reader: 310 | nature: 311 | titleSlideClass: [top, left, inverse] 312 | ``` 313 | 314 | -- 315 | 316 | - If you'd like to create your own title slide, disable **xaringan**'s title slide with the `seal = FALSE` option of `moon_reader`. 317 | 318 | ```yaml 319 | output: 320 | xaringan::moon_reader: 321 | seal: false 322 | ``` 323 | 324 | --- 325 | 326 | # Some Tips 327 | 328 | - There are several ways to build incremental slides. See [this presentation](https://slides.yihui.name/xaringan/incremental.html) for examples. 329 | 330 | - The option `highlightLines: true` of `nature` will highlight code lines that start with `*`, or are wrapped in `{{ }}`, or have trailing comments `#<<`; 331 | 332 | ```yaml 333 | output: 334 | xaringan::moon_reader: 335 | nature: 336 | highlightLines: true 337 | ``` 338 | 339 | See examples on the next page. 340 | 341 | --- 342 | 343 | # Some Tips 344 | 345 | 346 | .pull-left[ 347 | An example using a leading `*`: 348 | 349 | ```r 350 | if (TRUE) { 351 | ** message("Very important!") 352 | } 353 | ``` 354 | Output: 355 | ```r 356 | if (TRUE) { 357 | * message("Very important!") 358 | } 359 | ``` 360 | 361 | This is invalid R code, so it is a plain fenced code block that is not executed. 362 | ] 363 | 364 | .pull-right[ 365 | An example using `{{}}`: 366 | 367 | `r ''````{r tidy=FALSE} 368 | if (TRUE) { 369 | *{{ message("Very important!") }} 370 | } 371 | ``` 372 | Output: 373 | ```{r tidy=FALSE} 374 | if (TRUE) { 375 | {{ message("Very important!") }} 376 | } 377 | ``` 378 | 379 | It is valid R code so you can run it. Note that `{{}}` can wrap an R expression of multiple lines. 380 | ] 381 | 382 | --- 383 | 384 | # Some Tips 385 | 386 | An example of using the trailing comment `#<<` to highlight lines: 387 | 388 | ````markdown 389 | `r ''````{r tidy=FALSE} 390 | library(ggplot2) 391 | ggplot(mtcars) + 392 | aes(mpg, disp) + 393 | geom_point() + #<< 394 | geom_smooth() #<< 395 | ``` 396 | ```` 397 | 398 | Output: 399 | 400 | ```{r tidy=FALSE, eval=FALSE} 401 | library(ggplot2) 402 | ggplot(mtcars) + 403 | aes(mpg, disp) + 404 | geom_point() + #<< 405 | geom_smooth() #<< 406 | ``` 407 | 408 | --- 409 | 410 | # Some Tips 411 | 412 | When you enable line-highlighting, you can also use the chunk option `highlight.output` to highlight specific lines of the text output from a code chunk. For example, `highlight.output = TRUE` means highlighting all lines, and `highlight.output = c(1, 3)` means highlighting the first and third line. 413 | 414 | ````md 415 | `r ''````{r, highlight.output=c(1, 3)} 416 | head(iris) 417 | ``` 418 | ```` 419 | 420 | ```{r, highlight.output=c(1, 3), echo=FALSE} 421 | head(iris) 422 | ``` 423 | 424 | Question: what does `highlight.output = c(TRUE, FALSE)` mean? (Hint: think about R's recycling of vectors) 425 | 426 | --- 427 | 428 | # Some Tips 429 | 430 | - To make slides work offline, you need to download a copy of remark.js in advance, because **xaringan** uses the online version by default (see the help page `?xaringan::moon_reader`). 431 | 432 | - You can use `xaringan::summon_remark()` to download the latest or a specified version of remark.js. By default, it is downloaded to `libs/remark-latest.min.js`. 433 | 434 | - Then change the `chakra` option in YAML to point to this file, e.g. 435 | 436 | ```yaml 437 | output: 438 | xaringan::moon_reader: 439 | chakra: libs/remark-latest.min.js 440 | ``` 441 | 442 | - If you used Google fonts in slides (the default theme uses _Yanone Kaffeesatz_, _Droid Serif_, and _Source Code Pro_), they won't work offline unless you download or install them locally. The Heroku app [google-webfonts-helper](https://google-webfonts-helper.herokuapp.com/fonts) can help you download fonts and generate the necessary CSS. 443 | 444 | --- 445 | 446 | # Macros 447 | 448 | - remark.js [allows users to define custom macros](https://github.com/yihui/xaringan/issues/80) (JS functions) that can be applied to Markdown text using the syntax `![:macroName arg1, arg2, ...]` or `![:macroName arg1, arg2, ...](this)`. For example, before remark.js initializes the slides, you can define a macro named `scale`: 449 | 450 | ```js 451 | remark.macros.scale = function (percentage) { 452 | var url = this; 453 | return ''; 454 | }; 455 | ``` 456 | 457 | Then the Markdown text 458 | 459 | ```markdown 460 | ![:scale 50%](image.jpg) 461 | ``` 462 | 463 | will be translated to 464 | 465 | ```html 466 | 467 | ``` 468 | 469 | --- 470 | 471 | # Macros (continued) 472 | 473 | - To insert macros in **xaringan** slides, you can use the option `beforeInit` under the option `nature`, e.g., 474 | 475 | ```yaml 476 | output: 477 | xaringan::moon_reader: 478 | nature: 479 | beforeInit: "macros.js" 480 | ``` 481 | 482 | You save your remark.js macros in the file `macros.js`. 483 | 484 | - The `beforeInit` option can be used to insert arbitrary JS code before `remark.create()`. Inserting macros is just one of its possible applications. 485 | 486 | --- 487 | 488 | # CSS 489 | 490 | Among all options in `xaringan::moon_reader`, the most challenging but perhaps also the most rewarding one is `css`, because it allows you to customize the appearance of your slides using any CSS rules or hacks you know. 491 | 492 | You can see the default CSS file [here](https://github.com/yihui/xaringan/blob/master/inst/rmarkdown/templates/xaringan/resources/default.css). You can completely replace it with your own CSS files, or define new rules to override the default. See the help page `?xaringan::moon_reader` for more information. 493 | 494 | --- 495 | 496 | # CSS 497 | 498 | For example, suppose you want to change the font for code from the default "Source Code Pro" to "Ubuntu Mono". You can create a CSS file named, say, `ubuntu-mono.css`: 499 | 500 | ```css 501 | @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic); 502 | 503 | .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; } 504 | ``` 505 | 506 | Then set the `css` option in the YAML metadata: 507 | 508 | ```yaml 509 | output: 510 | xaringan::moon_reader: 511 | css: ["default", "ubuntu-mono.css"] 512 | ``` 513 | 514 | Here I assume `ubuntu-mono.css` is under the same directory as your Rmd. 515 | 516 | See [yihui/xaringan#83](https://github.com/yihui/xaringan/issues/83) for an example of using the [Fira Code](https://github.com/tonsky/FiraCode) font, which supports ligatures in program code. 517 | 518 | --- 519 | 520 | # Themes 521 | 522 | Don't want to learn CSS? Okay, you can use some user-contributed themes. A theme typically consists of two CSS files `foo.css` and `foo-fonts.css`, where `foo` is the theme name. Below are some existing themes: 523 | 524 | ```{r} 525 | names(xaringan:::list_css()) 526 | ``` 527 | 528 | --- 529 | 530 | # Themes 531 | 532 | To use a theme, you can specify the `css` option as an array of CSS filenames (without the `.css` extensions), e.g., 533 | 534 | ```yaml 535 | output: 536 | xaringan::moon_reader: 537 | css: [default, metropolis, metropolis-fonts] 538 | ``` 539 | 540 | If you want to contribute a theme to **xaringan**, please read [this blog post](https://yihui.name/en/2017/10/xaringan-themes). 541 | 542 | --- 543 | class: inverse, middle, center 544 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/39/Naruto_Shiki_Fujin.svg) 545 | background-size: contain 546 | 547 | # Naruto 548 | 549 | --- 550 | background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/be/Sharingan_triple.svg) 551 | background-size: 100px 552 | background-position: 90% 8% 553 | 554 | # Sharingan 555 | 556 | The R package name **xaringan** was derived1 from **Sharingan**, a dōjutsu in the Japanese anime _Naruto_ with two abilities: 557 | 558 | - the "Eye of Insight" 559 | 560 | - the "Eye of Hypnotism" 561 | 562 | I think a presentation is basically a way to communicate insights to the audience, and a great presentation may even "hypnotize" the audience.2,3 563 | 564 | .footnote[ 565 | [1] In Chinese, the pronounciation of _X_ is _Sh_ /ʃ/ (as in _shrimp_). Now you should have a better idea of how to pronounce my last name _Xie_. 566 | 567 | [2] By comparison, bad presentations only put the audience to sleep. 568 | 569 | [3] Personally I find that setting background images for slides is a killer feature of remark.js. It is an effective way to bring visual impact into your presentations. 570 | ] 571 | 572 | --- 573 | 574 | # Naruto terminology 575 | 576 | The **xaringan** package borrowed a few terms from Naruto, such as 577 | 578 | - [Sharingan](http://naruto.wikia.com/wiki/Sharingan) (写輪眼; the package name) 579 | 580 | - The [moon reader](http://naruto.wikia.com/wiki/Moon_Reader) (月読; an attractive R Markdown output format) 581 | 582 | - [Chakra](http://naruto.wikia.com/wiki/Chakra) (查克拉; the path to the remark.js library, which is the power to drive the presentation) 583 | 584 | - [Nature transformation](http://naruto.wikia.com/wiki/Nature_Transformation) (性質変化; transform the chakra by setting different options) 585 | 586 | - The [infinite moon reader](http://naruto.wikia.com/wiki/Infinite_Tsukuyomi) (無限月読; start a local web server to continuously serve your slides) 587 | 588 | - The [summoning technique](http://naruto.wikia.com/wiki/Summoning_Technique) (download remark.js from the web) 589 | 590 | You can click the links to know more about them if you want. The jutsu "Moon Reader" may seem a little evil, but that does not mean your slides are evil. 591 | 592 | --- 593 | 594 | class: center 595 | 596 | # Hand seals (印) 597 | 598 | Press `h` or `?` to see the possible ninjutsu you can use in remark.js. 599 | 600 | ![](https://upload.wikimedia.org/wikipedia/commons/7/7e/Mudra-Naruto-KageBunshin.svg) 601 | 602 | --- 603 | 604 | class: center, middle 605 | 606 | # Thanks! 607 | 608 | Slides created via the R package [**xaringan**](https://github.com/yihui/xaringan). 609 | 610 | The chakra comes from [remark.js](https://remarkjs.com), [**knitr**](http://yihui.name/knitr), and [R Markdown](https://rmarkdown.rstudio.com). 611 | --------------------------------------------------------------------------------