From 8b2d87d2f06ce681cbc5ad7e1a0ff0632d213c55 Mon Sep 17 00:00:00 2001 From: snehil Date: Fri, 24 Feb 2017 00:22:47 +0530 Subject: [PATCH] webscrapingworkshop --- slides/web-scraping/CONTRIBUTING.md | 23 + slides/web-scraping/Gruntfile.js | 176 + slides/web-scraping/LICENSE | 19 + slides/web-scraping/README.md | 2 + slides/web-scraping/bower.json | 27 + slides/web-scraping/css/print/paper.css | 202 + slides/web-scraping/css/print/pdf.css | 160 + slides/web-scraping/css/reveal.css | 1338 +++++ slides/web-scraping/css/reveal.scss | 1379 +++++ slides/web-scraping/css/theme/README.md | 21 + slides/web-scraping/css/theme/beige.css | 290 + slides/web-scraping/css/theme/black.css | 286 + slides/web-scraping/css/theme/blood.css | 309 ++ slides/web-scraping/css/theme/league.css | 292 + slides/web-scraping/css/theme/moon.css | 290 + slides/web-scraping/css/theme/night.css | 284 + slides/web-scraping/css/theme/serif.css | 286 + slides/web-scraping/css/theme/simple.css | 286 + slides/web-scraping/css/theme/sky.css | 293 ++ slides/web-scraping/css/theme/solarized.css | 290 + .../web-scraping/css/theme/source/beige.scss | 39 + .../web-scraping/css/theme/source/black.scss | 49 + .../web-scraping/css/theme/source/blood.scss | 79 + .../web-scraping/css/theme/source/league.scss | 34 + .../web-scraping/css/theme/source/moon.scss | 57 + .../web-scraping/css/theme/source/night.scss | 35 + .../web-scraping/css/theme/source/serif.scss | 35 + .../web-scraping/css/theme/source/simple.scss | 38 + slides/web-scraping/css/theme/source/sky.scss | 46 + .../css/theme/source/solarized.scss | 63 + .../web-scraping/css/theme/source/white.scss | 49 + .../css/theme/template/mixins.scss | 29 + .../css/theme/template/settings.scss | 43 + .../css/theme/template/theme.scss | 345 ++ slides/web-scraping/css/theme/white.css | 286 + slides/web-scraping/img/list.png | Bin 0 -> 116624 bytes slides/web-scraping/img/workflow.jpg | Bin 0 -> 26489 bytes slides/web-scraping/index.html | 184 + slides/web-scraping/js/reveal.js | 4677 +++++++++++++++++ slides/web-scraping/lib/css/zenburn.css | 115 + .../lib/font/league-gothic/LICENSE | 2 + .../lib/font/league-gothic/league-gothic.css | 10 + .../lib/font/league-gothic/league-gothic.eot | Bin 0 -> 25696 bytes .../lib/font/league-gothic/league-gothic.ttf | Bin 0 -> 64256 bytes .../lib/font/league-gothic/league-gothic.woff | Bin 0 -> 30764 bytes .../lib/font/source-sans-pro/LICENSE | 45 + .../source-sans-pro-italic.eot | Bin 0 -> 75720 bytes .../source-sans-pro-italic.ttf | Bin 0 -> 238084 bytes .../source-sans-pro-italic.woff | Bin 0 -> 98556 bytes .../source-sans-pro-regular.eot | Bin 0 -> 88070 bytes .../source-sans-pro-regular.ttf | Bin 0 -> 288008 bytes .../source-sans-pro-regular.woff | Bin 0 -> 114324 bytes .../source-sans-pro-semibold.eot | Bin 0 -> 89897 bytes .../source-sans-pro-semibold.ttf | Bin 0 -> 284640 bytes .../source-sans-pro-semibold.woff | Bin 0 -> 115648 bytes .../source-sans-pro-semibolditalic.eot | Bin 0 -> 75706 bytes .../source-sans-pro-semibolditalic.ttf | Bin 0 -> 240944 bytes .../source-sans-pro-semibolditalic.woff | Bin 0 -> 98816 bytes .../font/source-sans-pro/source-sans-pro.css | 39 + slides/web-scraping/lib/js/classList.js | 2 + slides/web-scraping/lib/js/head.min.js | 8 + slides/web-scraping/lib/js/html5shiv.js | 7 + slides/web-scraping/package.json | 45 + .../plugin/highlight/highlight.js | 32 + .../web-scraping/plugin/markdown/example.html | 129 + .../web-scraping/plugin/markdown/example.md | 31 + .../web-scraping/plugin/markdown/markdown.js | 402 ++ slides/web-scraping/plugin/markdown/marked.js | 6 + slides/web-scraping/plugin/math/math.js | 67 + .../web-scraping/plugin/multiplex/client.js | 13 + slides/web-scraping/plugin/multiplex/index.js | 56 + .../web-scraping/plugin/multiplex/master.js | 31 + .../plugin/notes-server/client.js | 65 + .../web-scraping/plugin/notes-server/index.js | 68 + .../plugin/notes-server/notes.html | 407 ++ slides/web-scraping/plugin/notes/notes.html | 407 ++ slides/web-scraping/plugin/notes/notes.js | 127 + .../plugin/print-pdf/print-pdf.js | 48 + slides/web-scraping/plugin/search/search.js | 196 + slides/web-scraping/plugin/zoom-js/zoom.js | 278 + .../test/examples/assets/image1.png | Bin 0 -> 21991 bytes .../test/examples/assets/image2.png | Bin 0 -> 10237 bytes .../web-scraping/test/examples/barebones.html | 41 + .../test/examples/embedded-media.html | 49 + slides/web-scraping/test/examples/math.html | 185 + .../test/examples/slide-backgrounds.html | 144 + .../test/examples/slide-transitions.html | 101 + slides/web-scraping/test/qunit-1.12.0.css | 244 + slides/web-scraping/test/qunit-1.12.0.js | 2212 ++++++++ .../test-markdown-element-attributes.html | 134 + .../test/test-markdown-element-attributes.js | 46 + .../test/test-markdown-slide-attributes.html | 128 + .../test/test-markdown-slide-attributes.js | 47 + slides/web-scraping/test/test-markdown.html | 52 + slides/web-scraping/test/test-markdown.js | 15 + slides/web-scraping/test/test-pdf.html | 83 + slides/web-scraping/test/test-pdf.js | 15 + slides/web-scraping/test/test.html | 86 + slides/web-scraping/test/test.js | 597 +++ 99 files changed, 19156 insertions(+) create mode 100644 slides/web-scraping/CONTRIBUTING.md create mode 100644 slides/web-scraping/Gruntfile.js create mode 100644 slides/web-scraping/LICENSE create mode 100644 slides/web-scraping/README.md create mode 100644 slides/web-scraping/bower.json create mode 100644 slides/web-scraping/css/print/paper.css create mode 100644 slides/web-scraping/css/print/pdf.css create mode 100644 slides/web-scraping/css/reveal.css create mode 100644 slides/web-scraping/css/reveal.scss create mode 100644 slides/web-scraping/css/theme/README.md create mode 100644 slides/web-scraping/css/theme/beige.css create mode 100644 slides/web-scraping/css/theme/black.css create mode 100644 slides/web-scraping/css/theme/blood.css create mode 100644 slides/web-scraping/css/theme/league.css create mode 100644 slides/web-scraping/css/theme/moon.css create mode 100644 slides/web-scraping/css/theme/night.css create mode 100644 slides/web-scraping/css/theme/serif.css create mode 100644 slides/web-scraping/css/theme/simple.css create mode 100644 slides/web-scraping/css/theme/sky.css create mode 100644 slides/web-scraping/css/theme/solarized.css create mode 100644 slides/web-scraping/css/theme/source/beige.scss create mode 100644 slides/web-scraping/css/theme/source/black.scss create mode 100644 slides/web-scraping/css/theme/source/blood.scss create mode 100644 slides/web-scraping/css/theme/source/league.scss create mode 100644 slides/web-scraping/css/theme/source/moon.scss create mode 100644 slides/web-scraping/css/theme/source/night.scss create mode 100644 slides/web-scraping/css/theme/source/serif.scss create mode 100644 slides/web-scraping/css/theme/source/simple.scss create mode 100644 slides/web-scraping/css/theme/source/sky.scss create mode 100644 slides/web-scraping/css/theme/source/solarized.scss create mode 100644 slides/web-scraping/css/theme/source/white.scss create mode 100644 slides/web-scraping/css/theme/template/mixins.scss create mode 100644 slides/web-scraping/css/theme/template/settings.scss create mode 100644 slides/web-scraping/css/theme/template/theme.scss create mode 100644 slides/web-scraping/css/theme/white.css create mode 100644 slides/web-scraping/img/list.png create mode 100644 slides/web-scraping/img/workflow.jpg create mode 100644 slides/web-scraping/index.html create mode 100644 slides/web-scraping/js/reveal.js create mode 100644 slides/web-scraping/lib/css/zenburn.css create mode 100644 slides/web-scraping/lib/font/league-gothic/LICENSE create mode 100644 slides/web-scraping/lib/font/league-gothic/league-gothic.css create mode 100755 slides/web-scraping/lib/font/league-gothic/league-gothic.eot create mode 100755 slides/web-scraping/lib/font/league-gothic/league-gothic.ttf create mode 100755 slides/web-scraping/lib/font/league-gothic/league-gothic.woff create mode 100644 slides/web-scraping/lib/font/source-sans-pro/LICENSE create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-italic.eot create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-italic.ttf create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-italic.woff create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-regular.eot create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-regular.ttf create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-regular.woff create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibold.eot create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibold.ttf create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibold.woff create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf create mode 100755 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff create mode 100644 slides/web-scraping/lib/font/source-sans-pro/source-sans-pro.css create mode 100644 slides/web-scraping/lib/js/classList.js create mode 100644 slides/web-scraping/lib/js/head.min.js create mode 100644 slides/web-scraping/lib/js/html5shiv.js create mode 100644 slides/web-scraping/package.json create mode 100644 slides/web-scraping/plugin/highlight/highlight.js create mode 100644 slides/web-scraping/plugin/markdown/example.html create mode 100644 slides/web-scraping/plugin/markdown/example.md create mode 100755 slides/web-scraping/plugin/markdown/markdown.js create mode 100644 slides/web-scraping/plugin/markdown/marked.js create mode 100755 slides/web-scraping/plugin/math/math.js create mode 100644 slides/web-scraping/plugin/multiplex/client.js create mode 100644 slides/web-scraping/plugin/multiplex/index.js create mode 100644 slides/web-scraping/plugin/multiplex/master.js create mode 100644 slides/web-scraping/plugin/notes-server/client.js create mode 100644 slides/web-scraping/plugin/notes-server/index.js create mode 100644 slides/web-scraping/plugin/notes-server/notes.html create mode 100644 slides/web-scraping/plugin/notes/notes.html create mode 100644 slides/web-scraping/plugin/notes/notes.js create mode 100644 slides/web-scraping/plugin/print-pdf/print-pdf.js create mode 100644 slides/web-scraping/plugin/search/search.js create mode 100644 slides/web-scraping/plugin/zoom-js/zoom.js create mode 100644 slides/web-scraping/test/examples/assets/image1.png create mode 100644 slides/web-scraping/test/examples/assets/image2.png create mode 100644 slides/web-scraping/test/examples/barebones.html create mode 100644 slides/web-scraping/test/examples/embedded-media.html create mode 100644 slides/web-scraping/test/examples/math.html create mode 100644 slides/web-scraping/test/examples/slide-backgrounds.html create mode 100644 slides/web-scraping/test/examples/slide-transitions.html create mode 100644 slides/web-scraping/test/qunit-1.12.0.css create mode 100644 slides/web-scraping/test/qunit-1.12.0.js create mode 100644 slides/web-scraping/test/test-markdown-element-attributes.html create mode 100644 slides/web-scraping/test/test-markdown-element-attributes.js create mode 100644 slides/web-scraping/test/test-markdown-slide-attributes.html create mode 100644 slides/web-scraping/test/test-markdown-slide-attributes.js create mode 100644 slides/web-scraping/test/test-markdown.html create mode 100644 slides/web-scraping/test/test-markdown.js create mode 100644 slides/web-scraping/test/test-pdf.html create mode 100644 slides/web-scraping/test/test-pdf.js create mode 100644 slides/web-scraping/test/test.html create mode 100644 slides/web-scraping/test/test.js diff --git a/slides/web-scraping/CONTRIBUTING.md b/slides/web-scraping/CONTRIBUTING.md new file mode 100644 index 0000000..c2091e8 --- /dev/null +++ b/slides/web-scraping/CONTRIBUTING.md @@ -0,0 +1,23 @@ +## Contributing + +Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. + + +### Personal Support +If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js). + + +### Bug Reports +When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested. + + +### Pull Requests +- Should follow the coding style of the file you work in, most importantly: + - Tabs to indent + - Single-quoted strings +- Should be made towards the **dev branch** +- Should be submitted from a feature/topic branch (not your master) + + +### Plugins +Please do not submit plugins as pull requests. They should be maintained in their own separate repository. More information here: https://github.com/hakimel/reveal.js/wiki/Plugin-Guidelines diff --git a/slides/web-scraping/Gruntfile.js b/slides/web-scraping/Gruntfile.js new file mode 100644 index 0000000..675adff --- /dev/null +++ b/slides/web-scraping/Gruntfile.js @@ -0,0 +1,176 @@ +/* global module:false */ +module.exports = function(grunt) { + var port = grunt.option('port') || 8000; + var base = grunt.option('base') || '.'; + + // Project configuration + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + meta: { + banner: + '/*!\n' + + ' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' + + ' * http://lab.hakim.se/reveal-js\n' + + ' * MIT licensed\n' + + ' *\n' + + ' * Copyright (C) 2016 Hakim El Hattab, http://hakim.se\n' + + ' */' + }, + + qunit: { + files: [ 'test/*.html' ] + }, + + uglify: { + options: { + banner: '<%= meta.banner %>\n' + }, + build: { + src: 'js/reveal.js', + dest: 'js/reveal.min.js' + } + }, + + sass: { + core: { + files: { + 'css/reveal.css': 'css/reveal.scss', + } + }, + themes: { + files: [ + { + expand: true, + cwd: 'css/theme/source', + src: ['*.scss'], + dest: 'css/theme', + ext: '.css' + } + ] + } + }, + + autoprefixer: { + dist: { + src: 'css/reveal.css' + } + }, + + cssmin: { + compress: { + files: { + 'css/reveal.min.css': [ 'css/reveal.css' ] + } + } + }, + + jshint: { + options: { + curly: false, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + eqnull: true, + browser: true, + expr: true, + globals: { + head: false, + module: false, + console: false, + unescape: false, + define: false, + exports: false + } + }, + files: [ 'Gruntfile.js', 'js/reveal.js' ] + }, + + connect: { + server: { + options: { + port: port, + base: base, + livereload: true, + open: true + } + } + }, + + zip: { + 'reveal-js-presentation.zip': [ + 'index.html', + 'css/**', + 'js/**', + 'lib/**', + 'images/**', + 'plugin/**', + '**.md' + ] + }, + + watch: { + options: { + livereload: true + }, + js: { + files: [ 'Gruntfile.js', 'js/reveal.js' ], + tasks: 'js' + }, + theme: { + files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ], + tasks: 'css-themes' + }, + css: { + files: [ 'css/reveal.scss' ], + tasks: 'css-core' + }, + html: { + files: [ 'index.html'] + }, + markdown: { + files: [ './*.md' ] + } + } + + }); + + // Dependencies + grunt.loadNpmTasks( 'grunt-contrib-qunit' ); + grunt.loadNpmTasks( 'grunt-contrib-jshint' ); + grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); + grunt.loadNpmTasks( 'grunt-contrib-uglify' ); + grunt.loadNpmTasks( 'grunt-contrib-watch' ); + grunt.loadNpmTasks( 'grunt-sass' ); + grunt.loadNpmTasks( 'grunt-contrib-connect' ); + grunt.loadNpmTasks( 'grunt-autoprefixer' ); + grunt.loadNpmTasks( 'grunt-zip' ); + + // Default task + grunt.registerTask( 'default', [ 'css', 'js' ] ); + + // JS task + grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] ); + + // Theme CSS + grunt.registerTask( 'css-themes', [ 'sass:themes' ] ); + + // Core framework CSS + grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] ); + + // All CSS + grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] ); + + // Package presentation to archive + grunt.registerTask( 'package', [ 'default', 'zip' ] ); + + // Serve presentation locally + grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); + + // Run tests + grunt.registerTask( 'test', [ 'jshint', 'qunit' ] ); + +}; diff --git a/slides/web-scraping/LICENSE b/slides/web-scraping/LICENSE new file mode 100644 index 0000000..faadd00 --- /dev/null +++ b/slides/web-scraping/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2016 Hakim El Hattab, http://hakim.se + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/slides/web-scraping/README.md b/slides/web-scraping/README.md new file mode 100644 index 0000000..91c309c --- /dev/null +++ b/slides/web-scraping/README.md @@ -0,0 +1,2 @@ +# git-basics for learning and using github in easiest and efficient way +Feel free to contribute diff --git a/slides/web-scraping/bower.json b/slides/web-scraping/bower.json new file mode 100644 index 0000000..5561820 --- /dev/null +++ b/slides/web-scraping/bower.json @@ -0,0 +1,27 @@ +{ + "name": "reveal.js", + "version": "3.2.0", + "main": [ + "js/reveal.js", + "css/reveal.css" + ], + "homepage": "http://lab.hakim.se/reveal-js/", + "license": "MIT", + "description": "The HTML Presentation Framework", + "authors": [ + "Hakim El Hattab " + ], + "dependencies": { + "headjs": "~1.0.3" + }, + "repository": { + "type": "git", + "url": "git://github.com/hakimel/reveal.js.git" + }, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test" + ] +} \ No newline at end of file diff --git a/slides/web-scraping/css/print/paper.css b/slides/web-scraping/css/print/paper.css new file mode 100644 index 0000000..6588f48 --- /dev/null +++ b/slides/web-scraping/css/print/paper.css @@ -0,0 +1,202 @@ +/* Default Print Stylesheet Template + by Rob Glazebrook of CSSnewbie.com + Last Updated: June 4, 2008 + + Feel free (nay, compelled) to edit, append, and + manipulate this file as you see fit. */ + + +@media print { + + /* SECTION 1: Set default width, margin, float, and + background. This prevents elements from extending + beyond the edge of the printed page, and prevents + unnecessary background images from printing */ + html { + background: #fff; + width: auto; + height: auto; + overflow: visible; + } + body { + background: #fff; + font-size: 20pt; + width: auto; + height: auto; + border: 0; + margin: 0 5%; + padding: 0; + overflow: visible; + float: none !important; + } + + /* SECTION 2: Remove any elements not needed in print. + This would include navigation, ads, sidebars, etc. */ + .nestedarrow, + .controls, + .fork-reveal, + .share-reveal, + .state-background, + .reveal .progress, + .reveal .backgrounds { + display: none !important; + } + + /* SECTION 3: Set body font face, size, and color. + Consider using a serif font for readability. */ + body, p, td, li, div { + font-size: 20pt!important; + font-family: Georgia, "Times New Roman", Times, serif !important; + color: #000; + } + + /* SECTION 4: Set heading font face, sizes, and color. + Differentiate your headings from your body text. + Perhaps use a large sans-serif for distinction. */ + h1,h2,h3,h4,h5,h6 { + color: #000!important; + height: auto; + line-height: normal; + font-family: Georgia, "Times New Roman", Times, serif !important; + text-shadow: 0 0 0 #000 !important; + text-align: left; + letter-spacing: normal; + } + /* Need to reduce the size of the fonts for printing */ + h1 { font-size: 28pt !important; } + h2 { font-size: 24pt !important; } + h3 { font-size: 22pt !important; } + h4 { font-size: 22pt !important; font-variant: small-caps; } + h5 { font-size: 21pt !important; } + h6 { font-size: 20pt !important; font-style: italic; } + + /* SECTION 5: Make hyperlinks more usable. + Ensure links are underlined, and consider appending + the URL to the end of the link for usability. */ + a:link, + a:visited { + color: #000 !important; + font-weight: bold; + text-decoration: underline; + } + /* + .reveal a:link:after, + .reveal a:visited:after { + content: " (" attr(href) ") "; + color: #222 !important; + font-size: 90%; + } + */ + + + /* SECTION 6: more reveal.js specific additions by @skypanther */ + ul, ol, div, p { + visibility: visible; + position: static; + width: auto; + height: auto; + display: block; + overflow: visible; + margin: 0; + text-align: left !important; + } + .reveal pre, + .reveal table { + margin-left: 0; + margin-right: 0; + } + .reveal pre code { + padding: 20px; + border: 1px solid #ddd; + } + .reveal blockquote { + margin: 20px 0; + } + .reveal .slides { + position: static !important; + width: auto !important; + height: auto !important; + + left: 0 !important; + top: 0 !important; + margin-left: 0 !important; + margin-top: 0 !important; + padding: 0 !important; + zoom: 1 !important; + + overflow: visible !important; + display: block !important; + + text-align: left !important; + -webkit-perspective: none; + -moz-perspective: none; + -ms-perspective: none; + perspective: none; + + -webkit-perspective-origin: 50% 50%; + -moz-perspective-origin: 50% 50%; + -ms-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; + } + .reveal .slides section { + visibility: visible !important; + position: static !important; + width: auto !important; + height: auto !important; + display: block !important; + overflow: visible !important; + + left: 0 !important; + top: 0 !important; + margin-left: 0 !important; + margin-top: 0 !important; + padding: 60px 20px !important; + z-index: auto !important; + + opacity: 1 !important; + + page-break-after: always !important; + + -webkit-transform-style: flat !important; + -moz-transform-style: flat !important; + -ms-transform-style: flat !important; + transform-style: flat !important; + + -webkit-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + transform: none !important; + + -webkit-transition: none !important; + -moz-transition: none !important; + -ms-transition: none !important; + transition: none !important; + } + .reveal .slides section.stack { + padding: 0 !important; + } + .reveal section:last-of-type { + page-break-after: avoid !important; + } + .reveal section .fragment { + opacity: 1 !important; + visibility: visible !important; + + -webkit-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + transform: none !important; + } + .reveal section img { + display: block; + margin: 15px 0px; + background: rgba(255,255,255,1); + border: 1px solid #666; + box-shadow: none; + } + + .reveal section small { + font-size: 0.8em; + } + +} \ No newline at end of file diff --git a/slides/web-scraping/css/print/pdf.css b/slides/web-scraping/css/print/pdf.css new file mode 100644 index 0000000..9ed90d6 --- /dev/null +++ b/slides/web-scraping/css/print/pdf.css @@ -0,0 +1,160 @@ +/** + * This stylesheet is used to print reveal.js + * presentations to PDF. + * + * https://github.com/hakimel/reveal.js#pdf-export + */ + +* { + -webkit-print-color-adjust: exact; +} + +body { + margin: 0 auto !important; + border: 0; + padding: 0; + float: none !important; + overflow: visible; +} + +html { + width: 100%; + height: 100%; + overflow: visible; +} + +/* Remove any elements not needed in print. */ +.nestedarrow, +.reveal .controls, +.reveal .progress, +.reveal .playback, +.reveal.overview, +.fork-reveal, +.share-reveal, +.state-background { + display: none !important; +} + +h1, h2, h3, h4, h5, h6 { + text-shadow: 0 0 0 #000 !important; +} + +.reveal pre code { + overflow: hidden !important; + font-family: Courier, 'Courier New', monospace !important; +} + +ul, ol, div, p { + visibility: visible; + position: static; + width: auto; + height: auto; + display: block; + overflow: visible; + margin: auto; +} +.reveal { + width: auto !important; + height: auto !important; + overflow: hidden !important; +} +.reveal .slides { + position: static; + width: 100%; + height: auto; + + left: auto; + top: auto; + margin: 0 !important; + padding: 0 !important; + + overflow: visible; + display: block; + + -webkit-perspective: none; + -moz-perspective: none; + -ms-perspective: none; + perspective: none; + + -webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */ + -moz-perspective-origin: 50% 50%; + -ms-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; +} + +.reveal .slides section { + page-break-after: always !important; + + visibility: visible !important; + position: relative !important; + display: block !important; + position: relative !important; + + margin: 0 !important; + padding: 0 !important; + box-sizing: border-box !important; + min-height: 1px; + + opacity: 1 !important; + + -webkit-transform-style: flat !important; + -moz-transform-style: flat !important; + -ms-transform-style: flat !important; + transform-style: flat !important; + + -webkit-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + transform: none !important; +} + +.reveal section.stack { + margin: 0 !important; + padding: 0 !important; + page-break-after: avoid !important; + height: auto !important; + min-height: auto !important; +} + +.reveal img { + box-shadow: none; +} + +.reveal .roll { + overflow: visible; + line-height: 1em; +} + +/* Slide backgrounds are placed inside of their slide when exporting to PDF */ +.reveal section .slide-background { + display: block !important; + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: -1; +} + +/* All elements should be above the slide-background */ +.reveal section>* { + position: relative; + z-index: 1; +} + +/* Display slide speaker notes when 'showNotes' is enabled */ +.reveal .speaker-notes-pdf { + display: block; + width: 100%; + max-height: none; + left: auto; + top: auto; + z-index: 100; +} + +/* Display slide numbers when 'slideNumber' is enabled */ +.reveal .slide-number-pdf { + display: block; + position: absolute; + font-size: 14px; +} + diff --git a/slides/web-scraping/css/reveal.css b/slides/web-scraping/css/reveal.css new file mode 100644 index 0000000..9739291 --- /dev/null +++ b/slides/web-scraping/css/reveal.css @@ -0,0 +1,1338 @@ +/*! + * reveal.js + * http://lab.hakim.se/reveal-js + * MIT licensed + * + * Copyright (C) 2016 Hakim El Hattab, http://hakim.se + */ +/********************************************* + * RESET STYLES + *********************************************/ +html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal iframe, +.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal p, .reveal blockquote, .reveal pre, +.reveal a, .reveal abbr, .reveal acronym, .reveal address, .reveal big, .reveal cite, .reveal code, +.reveal del, .reveal dfn, .reveal em, .reveal img, .reveal ins, .reveal kbd, .reveal q, .reveal s, .reveal samp, +.reveal small, .reveal strike, .reveal strong, .reveal sub, .reveal sup, .reveal tt, .reveal var, +.reveal b, .reveal u, .reveal center, +.reveal dl, .reveal dt, .reveal dd, .reveal ol, .reveal ul, .reveal li, +.reveal fieldset, .reveal form, .reveal label, .reveal legend, +.reveal table, .reveal caption, .reveal tbody, .reveal tfoot, .reveal thead, .reveal tr, .reveal th, .reveal td, +.reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed, +.reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup, +.reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary, +.reveal time, .reveal mark, .reveal audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; } + +.reveal article, .reveal aside, .reveal details, .reveal figcaption, .reveal figure, +.reveal footer, .reveal header, .reveal hgroup, .reveal menu, .reveal nav, .reveal section { + display: block; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +html, +body { + width: 100%; + height: 100%; + overflow: hidden; } + +body { + position: relative; + line-height: 1; + background-color: #fff; + color: #000; } + +html:-webkit-full-screen-ancestor { + background-color: inherit; } + +html:-moz-full-screen-ancestor { + background-color: inherit; } + +/********************************************* + * VIEW FRAGMENTS + *********************************************/ +.reveal .slides section .fragment { + opacity: 0; + visibility: hidden; + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; } + .reveal .slides section .fragment.visible { + opacity: 1; + visibility: visible; } + +.reveal .slides section .fragment.grow { + opacity: 1; + visibility: visible; } + .reveal .slides section .fragment.grow.visible { + -webkit-transform: scale(1.3); + -ms-transform: scale(1.3); + transform: scale(1.3); } + +.reveal .slides section .fragment.shrink { + opacity: 1; + visibility: visible; } + .reveal .slides section .fragment.shrink.visible { + -webkit-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); } + +.reveal .slides section .fragment.zoom-in { + -webkit-transform: scale(0.1); + -ms-transform: scale(0.1); + transform: scale(0.1); } + .reveal .slides section .fragment.zoom-in.visible { + -webkit-transform: none; + -ms-transform: none; + transform: none; } + +.reveal .slides section .fragment.fade-out { + opacity: 1; + visibility: visible; } + .reveal .slides section .fragment.fade-out.visible { + opacity: 0; + visibility: hidden; } + +.reveal .slides section .fragment.semi-fade-out { + opacity: 1; + visibility: visible; } + .reveal .slides section .fragment.semi-fade-out.visible { + opacity: 0.5; + visibility: visible; } + +.reveal .slides section .fragment.strike { + opacity: 1; + visibility: visible; } + .reveal .slides section .fragment.strike.visible { + text-decoration: line-through; } + +.reveal .slides section .fragment.current-visible { + opacity: 0; + visibility: hidden; } + .reveal .slides section .fragment.current-visible.current-fragment { + opacity: 1; + visibility: visible; } + +.reveal .slides section .fragment.highlight-red, +.reveal .slides section .fragment.highlight-current-red, +.reveal .slides section .fragment.highlight-green, +.reveal .slides section .fragment.highlight-current-green, +.reveal .slides section .fragment.highlight-blue, +.reveal .slides section .fragment.highlight-current-blue { + opacity: 1; + visibility: visible; } + +.reveal .slides section .fragment.highlight-red.visible { + color: #ff2c2d; } + +.reveal .slides section .fragment.highlight-green.visible { + color: #17ff2e; } + +.reveal .slides section .fragment.highlight-blue.visible { + color: #1b91ff; } + +.reveal .slides section .fragment.highlight-current-red.current-fragment { + color: #ff2c2d; } + +.reveal .slides section .fragment.highlight-current-green.current-fragment { + color: #17ff2e; } + +.reveal .slides section .fragment.highlight-current-blue.current-fragment { + color: #1b91ff; } + +/********************************************* + * DEFAULT ELEMENT STYLES + *********************************************/ +/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */ +.reveal:after { + content: ''; + font-style: italic; } + +.reveal iframe { + z-index: 1; } + +/** Prevents layering issues in certain browser/transition combinations */ +.reveal a { + position: relative; } + +.reveal .stretch { + max-width: none; + max-height: none; } + +.reveal pre.stretch code { + height: 100%; + max-height: 100%; + box-sizing: border-box; } + +/********************************************* + * CONTROLS + *********************************************/ +.reveal .controls { + display: none; + position: fixed; + width: 110px; + height: 110px; + z-index: 30; + right: 10px; + bottom: 10px; + -webkit-user-select: none; } + +.reveal .controls button { + padding: 0; + position: absolute; + opacity: 0.05; + width: 0; + height: 0; + background-color: transparent; + border: 12px solid transparent; + -webkit-transform: scale(0.9999); + -ms-transform: scale(0.9999); + transform: scale(0.9999); + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; + -webkit-appearance: none; + -webkit-tap-highlight-color: transparent; } + +.reveal .controls .enabled { + opacity: 0.7; + cursor: pointer; } + +.reveal .controls .enabled:active { + margin-top: 1px; } + +.reveal .controls .navigate-left { + top: 42px; + border-right-width: 22px; + border-right-color: #000; } + +.reveal .controls .navigate-left.fragmented { + opacity: 0.3; } + +.reveal .controls .navigate-right { + left: 74px; + top: 42px; + border-left-width: 22px; + border-left-color: #000; } + +.reveal .controls .navigate-right.fragmented { + opacity: 0.3; } + +.reveal .controls .navigate-up { + left: 42px; + border-bottom-width: 22px; + border-bottom-color: #000; } + +.reveal .controls .navigate-up.fragmented { + opacity: 0.3; } + +.reveal .controls .navigate-down { + left: 42px; + top: 74px; + border-top-width: 22px; + border-top-color: #000; } + +.reveal .controls .navigate-down.fragmented { + opacity: 0.3; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + position: fixed; + display: none; + height: 3px; + width: 100%; + bottom: 0; + left: 0; + z-index: 10; + background-color: rgba(0, 0, 0, 0.2); } + +.reveal .progress:after { + content: ''; + display: block; + position: absolute; + height: 20px; + width: 100%; + top: -20px; } + +.reveal .progress span { + display: block; + height: 100%; + width: 0px; + background-color: #000; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/********************************************* + * SLIDE NUMBER + *********************************************/ +.reveal .slide-number { + position: fixed; + display: block; + right: 8px; + bottom: 8px; + z-index: 31; + font-family: Helvetica, sans-serif; + font-size: 12px; + line-height: 1; + color: #fff; + background-color: rgba(0, 0, 0, 0.4); + padding: 5px; } + +.reveal .slide-number-delimiter { + margin: 0 3px; } + +/********************************************* + * SLIDES + *********************************************/ +.reveal { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + -ms-touch-action: none; + touch-action: none; } + +.reveal .slides { + position: absolute; + width: 100%; + height: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; + overflow: visible; + z-index: 1; + text-align: center; + -webkit-perspective: 600px; + perspective: 600px; + -webkit-perspective-origin: 50% 40%; + perspective-origin: 50% 40%; } + +.reveal .slides > section { + -ms-perspective: 600px; } + +.reveal .slides > section, +.reveal .slides > section > section { + display: none; + position: absolute; + width: 100%; + padding: 20px 0px; + z-index: 10; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transition: -webkit-transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), -webkit-transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: -ms-transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: transform-origin 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), transform 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), visibility 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985), opacity 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] .slides section { + -webkit-transition-duration: 400ms; + transition-duration: 400ms; } + +.reveal[data-transition-speed="slow"] .slides section { + -webkit-transition-duration: 1200ms; + transition-duration: 1200ms; } + +/* Slide-specific transition speed overrides */ +.reveal .slides section[data-transition-speed="fast"] { + -webkit-transition-duration: 400ms; + transition-duration: 400ms; } + +.reveal .slides section[data-transition-speed="slow"] { + -webkit-transition-duration: 1200ms; + transition-duration: 1200ms; } + +.reveal .slides > section.stack { + padding-top: 0; + padding-bottom: 0; } + +.reveal .slides > section.present, +.reveal .slides > section > section.present { + display: block; + z-index: 11; + opacity: 1; } + +.reveal.center, +.reveal.center .slides, +.reveal.center .slides section { + min-height: 0 !important; } + +/* Don't allow interaction with invisible slides */ +.reveal .slides > section.future, +.reveal .slides > section > section.future, +.reveal .slides > section.past, +.reveal .slides > section > section.past { + pointer-events: none; } + +.reveal.overview .slides > section, +.reveal.overview .slides > section > section { + pointer-events: auto; } + +.reveal .slides > section.past, +.reveal .slides > section.future, +.reveal .slides > section > section.past, +.reveal .slides > section > section.future { + opacity: 0; } + +/********************************************* + * Mixins for readability of transitions + *********************************************/ +/********************************************* + * SLIDE TRANSITION + * Aliased 'linear' for backwards compatibility + *********************************************/ +.reveal.slide section { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .slides > section[data-transition=slide].past, +.reveal .slides > section[data-transition~=slide-out].past, +.reveal.slide .slides > section:not([data-transition]).past { + -webkit-transform: translate(-150%, 0); + -ms-transform: translate(-150%, 0); + transform: translate(-150%, 0); } + +.reveal .slides > section[data-transition=slide].future, +.reveal .slides > section[data-transition~=slide-in].future, +.reveal.slide .slides > section:not([data-transition]).future { + -webkit-transform: translate(150%, 0); + -ms-transform: translate(150%, 0); + transform: translate(150%, 0); } + +.reveal .slides > section > section[data-transition=slide].past, +.reveal .slides > section > section[data-transition~=slide-out].past, +.reveal.slide .slides > section > section:not([data-transition]).past { + -webkit-transform: translate(0, -150%); + -ms-transform: translate(0, -150%); + transform: translate(0, -150%); } + +.reveal .slides > section > section[data-transition=slide].future, +.reveal .slides > section > section[data-transition~=slide-in].future, +.reveal.slide .slides > section > section:not([data-transition]).future { + -webkit-transform: translate(0, 150%); + -ms-transform: translate(0, 150%); + transform: translate(0, 150%); } + +.reveal.linear section { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .slides > section[data-transition=linear].past, +.reveal .slides > section[data-transition~=linear-out].past, +.reveal.linear .slides > section:not([data-transition]).past { + -webkit-transform: translate(-150%, 0); + -ms-transform: translate(-150%, 0); + transform: translate(-150%, 0); } + +.reveal .slides > section[data-transition=linear].future, +.reveal .slides > section[data-transition~=linear-in].future, +.reveal.linear .slides > section:not([data-transition]).future { + -webkit-transform: translate(150%, 0); + -ms-transform: translate(150%, 0); + transform: translate(150%, 0); } + +.reveal .slides > section > section[data-transition=linear].past, +.reveal .slides > section > section[data-transition~=linear-out].past, +.reveal.linear .slides > section > section:not([data-transition]).past { + -webkit-transform: translate(0, -150%); + -ms-transform: translate(0, -150%); + transform: translate(0, -150%); } + +.reveal .slides > section > section[data-transition=linear].future, +.reveal .slides > section > section[data-transition~=linear-in].future, +.reveal.linear .slides > section > section:not([data-transition]).future { + -webkit-transform: translate(0, 150%); + -ms-transform: translate(0, 150%); + transform: translate(0, 150%); } + +/********************************************* + * CONVEX TRANSITION + * Aliased 'default' for backwards compatibility + *********************************************/ +.reveal .slides > section[data-transition=default].past, +.reveal .slides > section[data-transition~=default-out].past, +.reveal.default .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=default].future, +.reveal .slides > section[data-transition~=default-in].future, +.reveal.default .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=default].past, +.reveal .slides > section > section[data-transition~=default-out].past, +.reveal.default .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); } + +.reveal .slides > section > section[data-transition=default].future, +.reveal .slides > section > section[data-transition~=default-in].future, +.reveal.default .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); } + +.reveal .slides > section[data-transition=convex].past, +.reveal .slides > section[data-transition~=convex-out].past, +.reveal.convex .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=convex].future, +.reveal .slides > section[data-transition~=convex-in].future, +.reveal.convex .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=convex].past, +.reveal .slides > section > section[data-transition~=convex-out].past, +.reveal.convex .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); } + +.reveal .slides > section > section[data-transition=convex].future, +.reveal .slides > section > section[data-transition~=convex-in].future, +.reveal.convex .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); } + +/********************************************* + * CONCAVE TRANSITION + *********************************************/ +.reveal .slides > section[data-transition=concave].past, +.reveal .slides > section[data-transition~=concave-out].past, +.reveal.concave .slides > section:not([data-transition]).past { + -webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); } + +.reveal .slides > section[data-transition=concave].future, +.reveal .slides > section[data-transition~=concave-in].future, +.reveal.concave .slides > section:not([data-transition]).future { + -webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); } + +.reveal .slides > section > section[data-transition=concave].past, +.reveal .slides > section > section[data-transition~=concave-out].past, +.reveal.concave .slides > section > section:not([data-transition]).past { + -webkit-transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); + transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); } + +.reveal .slides > section > section[data-transition=concave].future, +.reveal .slides > section > section[data-transition~=concave-in].future, +.reveal.concave .slides > section > section:not([data-transition]).future { + -webkit-transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); + transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); } + +/********************************************* + * ZOOM TRANSITION + *********************************************/ +.reveal .slides section[data-transition=zoom], +.reveal.zoom .slides section:not([data-transition]) { + -webkit-transition-timing-function: ease; + transition-timing-function: ease; } + +.reveal .slides > section[data-transition=zoom].past, +.reveal .slides > section[data-transition~=zoom-out].past, +.reveal.zoom .slides > section:not([data-transition]).past { + visibility: hidden; + -webkit-transform: scale(16); + -ms-transform: scale(16); + transform: scale(16); } + +.reveal .slides > section[data-transition=zoom].future, +.reveal .slides > section[data-transition~=zoom-in].future, +.reveal.zoom .slides > section:not([data-transition]).future { + visibility: hidden; + -webkit-transform: scale(0.2); + -ms-transform: scale(0.2); + transform: scale(0.2); } + +.reveal .slides > section > section[data-transition=zoom].past, +.reveal .slides > section > section[data-transition~=zoom-out].past, +.reveal.zoom .slides > section > section:not([data-transition]).past { + -webkit-transform: translate(0, -150%); + -ms-transform: translate(0, -150%); + transform: translate(0, -150%); } + +.reveal .slides > section > section[data-transition=zoom].future, +.reveal .slides > section > section[data-transition~=zoom-in].future, +.reveal.zoom .slides > section > section:not([data-transition]).future { + -webkit-transform: translate(0, 150%); + -ms-transform: translate(0, 150%); + transform: translate(0, 150%); } + +/********************************************* + * CUBE TRANSITION + *********************************************/ +.reveal.cube .slides { + -webkit-perspective: 1300px; + perspective: 1300px; } + +.reveal.cube .slides section { + padding: 30px; + min-height: 700px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + box-sizing: border-box; } + +.reveal.center.cube .slides section { + min-height: 0; } + +.reveal.cube .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + -webkit-transform: translateZ(-20px); + transform: translateZ(-20px); } + +.reveal.cube .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0, 0, 0, 0.2); + -webkit-transform: translateZ(-90px) rotateX(65deg); + transform: translateZ(-90px) rotateX(65deg); } + +.reveal.cube .slides > section.stack { + padding: 0; + background: none; } + +.reveal.cube .slides > section.past { + -webkit-transform-origin: 100% 0%; + -ms-transform-origin: 100% 0%; + transform-origin: 100% 0%; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg); + transform: translate3d(-100%, 0, 0) rotateY(-90deg); } + +.reveal.cube .slides > section.future { + -webkit-transform-origin: 0% 0%; + -ms-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg); + transform: translate3d(100%, 0, 0) rotateY(90deg); } + +.reveal.cube .slides > section > section.past { + -webkit-transform-origin: 0% 100%; + -ms-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transform: translate3d(0, -100%, 0) rotateX(90deg); + transform: translate3d(0, -100%, 0) rotateX(90deg); } + +.reveal.cube .slides > section > section.future { + -webkit-transform-origin: 0% 0%; + -ms-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg); + transform: translate3d(0, 100%, 0) rotateX(-90deg); } + +/********************************************* + * PAGE TRANSITION + *********************************************/ +.reveal.page .slides { + -webkit-perspective-origin: 0% 50%; + perspective-origin: 0% 50%; + -webkit-perspective: 3000px; + perspective: 3000px; } + +.reveal.page .slides section { + padding: 30px; + min-height: 700px; + box-sizing: border-box; } + +.reveal.page .slides section.past { + z-index: 12; } + +.reveal.page .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0, 0, 0, 0.1); + -webkit-transform: translateZ(-20px); + transform: translateZ(-20px); } + +.reveal.page .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0, 0, 0, 0.2); + -webkit-transform: translateZ(-90px) rotateX(65deg); } + +.reveal.page .slides > section.stack { + padding: 0; + background: none; } + +.reveal.page .slides > section.past { + -webkit-transform-origin: 0% 0%; + -ms-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(-40%, 0, 0) rotateY(-80deg); + transform: translate3d(-40%, 0, 0) rotateY(-80deg); } + +.reveal.page .slides > section.future { + -webkit-transform-origin: 100% 0%; + -ms-transform-origin: 100% 0%; + transform-origin: 100% 0%; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +.reveal.page .slides > section > section.past { + -webkit-transform-origin: 0% 0%; + -ms-transform-origin: 0% 0%; + transform-origin: 0% 0%; + -webkit-transform: translate3d(0, -40%, 0) rotateX(80deg); + transform: translate3d(0, -40%, 0) rotateX(80deg); } + +.reveal.page .slides > section > section.future { + -webkit-transform-origin: 0% 100%; + -ms-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +/********************************************* + * FADE TRANSITION + *********************************************/ +.reveal .slides section[data-transition=fade], +.reveal.fade .slides section:not([data-transition]), +.reveal.fade .slides > section > section:not([data-transition]) { + -webkit-transform: none; + -ms-transform: none; + transform: none; + -webkit-transition: opacity 0.5s; + transition: opacity 0.5s; } + +.reveal.fade.overview .slides section, +.reveal.fade.overview .slides > section > section { + -webkit-transition: none; + transition: none; } + +/********************************************* + * NO TRANSITION + *********************************************/ +.reveal .slides section[data-transition=none], +.reveal.none .slides section:not([data-transition]) { + -webkit-transform: none; + -ms-transform: none; + transform: none; + -webkit-transition: none; + transition: none; } + +/********************************************* + * PAUSED MODE + *********************************************/ +.reveal .pause-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: black; + visibility: hidden; + opacity: 0; + z-index: 100; + -webkit-transition: all 1s ease; + transition: all 1s ease; } + +.reveal.paused .pause-overlay { + visibility: visible; + opacity: 1; } + +/********************************************* + * FALLBACK + *********************************************/ +.no-transforms { + overflow-y: auto; } + +.no-transforms .reveal .slides { + position: relative; + width: 80%; + height: auto !important; + top: 0; + left: 50%; + margin: 0; + text-align: center; } + +.no-transforms .reveal .controls, +.no-transforms .reveal .progress { + display: none !important; } + +.no-transforms .reveal .slides section { + display: block !important; + opacity: 1 !important; + position: relative !important; + height: auto; + min-height: 0; + top: 0; + left: -50%; + margin: 70px 0; + -webkit-transform: none; + -ms-transform: none; + transform: none; } + +.no-transforms .reveal .slides section section { + left: 0; } + +.reveal .no-transition, +.reveal .no-transition * { + -webkit-transition: none !important; + transition: none !important; } + +/********************************************* + * PER-SLIDE BACKGROUNDS + *********************************************/ +.reveal .backgrounds { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + -webkit-perspective: 600px; + perspective: 600px; } + +.reveal .slide-background { + display: none; + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + visibility: hidden; + background-color: transparent; + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; + -webkit-transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal .slide-background.stack { + display: block; } + +.reveal .slide-background.present { + opacity: 1; + visibility: visible; } + +.print-pdf .reveal .slide-background { + opacity: 1 !important; + visibility: visible !important; } + +/* Video backgrounds */ +.reveal .slide-background video { + position: absolute; + width: 100%; + height: 100%; + max-width: none; + max-height: none; + top: 0; + left: 0; } + +/* Immediate transition style */ +.reveal[data-background-transition=none] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=none] { + -webkit-transition: none; + transition: none; } + +/* Slide */ +.reveal[data-background-transition=slide] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=slide] { + opacity: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=slide] { + -webkit-transform: translate(-100%, 0); + -ms-transform: translate(-100%, 0); + transform: translate(-100%, 0); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=slide] { + -webkit-transform: translate(100%, 0); + -ms-transform: translate(100%, 0); + transform: translate(100%, 0); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=slide] { + -webkit-transform: translate(0, -100%); + -ms-transform: translate(0, -100%); + transform: translate(0, -100%); } + +.reveal[data-background-transition=slide] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=slide] { + -webkit-transform: translate(0, 100%); + -ms-transform: translate(0, 100%); + transform: translate(0, 100%); } + +/* Convex */ +.reveal[data-background-transition=convex] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); } + +.reveal[data-background-transition=convex] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=convex] { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); } + +/* Concave */ +.reveal[data-background-transition=concave] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); } + +.reveal[data-background-transition=concave] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=concave] { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); } + +/* Zoom */ +.reveal[data-background-transition=zoom] > .backgrounds .slide-background, +.reveal > .backgrounds .slide-background[data-background-transition=zoom] { + -webkit-transition-timing-function: ease; + transition-timing-function: ease; } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background.past, +.reveal > .backgrounds .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(16); + -ms-transform: scale(16); + transform: scale(16); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background.future, +.reveal > .backgrounds .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + -ms-transform: scale(0.2); + transform: scale(0.2); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.past, +.reveal > .backgrounds .slide-background > .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(16); + -ms-transform: scale(16); + transform: scale(16); } + +.reveal[data-background-transition=zoom] > .backgrounds .slide-background > .slide-background.future, +.reveal > .backgrounds .slide-background > .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + -ms-transform: scale(0.2); + transform: scale(0.2); } + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] > .backgrounds .slide-background { + -webkit-transition-duration: 400ms; + transition-duration: 400ms; } + +.reveal[data-transition-speed="slow"] > .backgrounds .slide-background { + -webkit-transition-duration: 1200ms; + transition-duration: 1200ms; } + +/********************************************* + * OVERVIEW + *********************************************/ +.reveal.overview { + -webkit-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; + -webkit-perspective: 700px; + perspective: 700px; } + .reveal.overview .slides section { + height: 700px; + opacity: 1 !important; + overflow: hidden; + visibility: visible !important; + cursor: pointer; + box-sizing: border-box; } + .reveal.overview .slides section:hover, + .reveal.overview .slides section.present { + outline: 10px solid rgba(150, 150, 150, 0.4); + outline-offset: 10px; } + .reveal.overview .slides section .fragment { + opacity: 1; + -webkit-transition: none; + transition: none; } + .reveal.overview .slides section:after, + .reveal.overview .slides section:before { + display: none !important; } + .reveal.overview .slides > section.stack { + padding: 0; + top: 0 !important; + background: none; + outline: none; + overflow: visible; } + .reveal.overview .backgrounds { + -webkit-perspective: inherit; + perspective: inherit; } + .reveal.overview .backgrounds .slide-background { + opacity: 1; + visibility: visible; + outline: 10px solid rgba(150, 150, 150, 0.1); + outline-offset: 10px; } + +.reveal.overview .slides section, +.reveal.overview-deactivating .slides section { + -webkit-transition: none; + transition: none; } + +.reveal.overview .backgrounds .slide-background, +.reveal.overview-deactivating .backgrounds .slide-background { + -webkit-transition: none; + transition: none; } + +.reveal.overview-animated .slides { + -webkit-transition: -webkit-transform 0.4s ease; + transition: transform 0.4s ease; } + +/********************************************* + * RTL SUPPORT + *********************************************/ +.reveal.rtl .slides, +.reveal.rtl .slides h1, +.reveal.rtl .slides h2, +.reveal.rtl .slides h3, +.reveal.rtl .slides h4, +.reveal.rtl .slides h5, +.reveal.rtl .slides h6 { + direction: rtl; + font-family: sans-serif; } + +.reveal.rtl pre, +.reveal.rtl code { + direction: ltr; } + +.reveal.rtl ol, +.reveal.rtl ul { + text-align: right; } + +.reveal.rtl .progress span { + float: right; } + +/********************************************* + * PARALLAX BACKGROUND + *********************************************/ +.reveal.has-parallax-background .backgrounds { + -webkit-transition: all 0.8s ease; + transition: all 0.8s ease; } + +/* Global transition speed settings */ +.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds { + -webkit-transition-duration: 400ms; + transition-duration: 400ms; } + +.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds { + -webkit-transition-duration: 1200ms; + transition-duration: 1200ms; } + +/********************************************* + * LINK PREVIEW OVERLAY + *********************************************/ +.reveal .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + background: rgba(0, 0, 0, 0.9); + opacity: 0; + visibility: hidden; + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; } + +.reveal .overlay.visible { + opacity: 1; + visibility: visible; } + +.reveal .overlay .spinner { + position: absolute; + display: block; + top: 50%; + left: 50%; + width: 32px; + height: 32px; + margin: -16px 0 0 -16px; + z-index: 10; + background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D); + visibility: visible; + opacity: 0.6; + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; } + +.reveal .overlay header { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 40px; + z-index: 2; + border-bottom: 1px solid #222; } + +.reveal .overlay header a { + display: inline-block; + width: 40px; + height: 40px; + padding: 0 10px; + float: right; + opacity: 0.6; + box-sizing: border-box; } + +.reveal .overlay header a:hover { + opacity: 1; } + +.reveal .overlay header a .icon { + display: inline-block; + width: 20px; + height: 20px; + background-position: 50% 50%; + background-size: 100%; + background-repeat: no-repeat; } + +.reveal .overlay header a.close .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC); } + +.reveal .overlay header a.external .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==); } + +.reveal .overlay .viewport { + position: absolute; + top: 40px; + right: 0; + bottom: 0; + left: 0; } + +.reveal .overlay.overlay-preview .viewport iframe { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + border: 0; + opacity: 0; + visibility: hidden; + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; } + +.reveal .overlay.overlay-preview.loaded .viewport iframe { + opacity: 1; + visibility: visible; } + +.reveal .overlay.overlay-preview.loaded .spinner { + opacity: 0; + visibility: hidden; + -webkit-transform: scale(0.2); + -ms-transform: scale(0.2); + transform: scale(0.2); } + +.reveal .overlay.overlay-help .viewport { + overflow: auto; + color: #fff; } + +.reveal .overlay.overlay-help .viewport .viewport-inner { + width: 600px; + margin: 0 auto; + padding: 60px; + text-align: center; + letter-spacing: normal; } + +.reveal .overlay.overlay-help .viewport .viewport-inner .title { + font-size: 20px; } + +.reveal .overlay.overlay-help .viewport .viewport-inner table { + border: 1px solid #fff; + border-collapse: collapse; + font-size: 14px; } + +.reveal .overlay.overlay-help .viewport .viewport-inner table th, +.reveal .overlay.overlay-help .viewport .viewport-inner table td { + width: 200px; + padding: 10px; + border: 1px solid #fff; + vertical-align: middle; } + +.reveal .overlay.overlay-help .viewport .viewport-inner table th { + padding-top: 20px; + padding-bottom: 20px; } + +/********************************************* + * PLAYBACK COMPONENT + *********************************************/ +.reveal .playback { + position: fixed; + left: 15px; + bottom: 20px; + z-index: 30; + cursor: pointer; + -webkit-transition: all 400ms ease; + transition: all 400ms ease; } + +.reveal.overview .playback { + opacity: 0; + visibility: hidden; } + +/********************************************* + * ROLLING LINKS + *********************************************/ +.reveal .roll { + display: inline-block; + line-height: 1.2; + overflow: hidden; + vertical-align: top; + -webkit-perspective: 400px; + perspective: 400px; + -webkit-perspective-origin: 50% 50%; + perspective-origin: 50% 50%; } + +.reveal .roll:hover { + background: none; + text-shadow: none; } + +.reveal .roll span { + display: block; + position: relative; + padding: 0 2px; + pointer-events: none; + -webkit-transition: all 400ms ease; + transition: all 400ms ease; + -webkit-transform-origin: 50% 0%; + -ms-transform-origin: 50% 0%; + transform-origin: 50% 0%; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + +.reveal .roll:hover span { + background: rgba(0, 0, 0, 0.5); + -webkit-transform: translate3d(0px, 0px, -45px) rotateX(90deg); + transform: translate3d(0px, 0px, -45px) rotateX(90deg); } + +.reveal .roll span:after { + content: attr(data-title); + display: block; + position: absolute; + left: 0; + top: 0; + padding: 0 2px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform-origin: 50% 0%; + -ms-transform-origin: 50% 0%; + transform-origin: 50% 0%; + -webkit-transform: translate3d(0px, 110%, 0px) rotateX(-90deg); + transform: translate3d(0px, 110%, 0px) rotateX(-90deg); } + +/********************************************* + * SPEAKER NOTES + *********************************************/ +.reveal aside.notes { + display: none; } + +.reveal .speaker-notes { + display: none; + position: absolute; + width: 70%; + max-height: 15%; + left: 15%; + bottom: 26px; + padding: 10px; + z-index: 1; + font-size: 18px; + line-height: 1.4; + color: #fff; + background-color: rgba(0, 0, 0, 0.5); + overflow: auto; + box-sizing: border-box; + text-align: left; + font-family: Helvetica, sans-serif; + -webkit-overflow-scrolling: touch; } + +.reveal .speaker-notes.visible:not(:empty) { + display: block; } + +@media screen and (max-width: 1024px) { + .reveal .speaker-notes { + font-size: 14px; } } + +@media screen and (max-width: 600px) { + .reveal .speaker-notes { + width: 90%; + left: 5%; } } + +/********************************************* + * ZOOM PLUGIN + *********************************************/ +.zoomed .reveal *, +.zoomed .reveal *:before, +.zoomed .reveal *:after { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; } + +.zoomed .reveal .progress, +.zoomed .reveal .controls { + opacity: 0; } + +.zoomed .reveal .roll span { + background: none; } + +.zoomed .reveal .roll span:after { + visibility: hidden; } diff --git a/slides/web-scraping/css/reveal.scss b/slides/web-scraping/css/reveal.scss new file mode 100644 index 0000000..eb600ac --- /dev/null +++ b/slides/web-scraping/css/reveal.scss @@ -0,0 +1,1379 @@ +/*! + * reveal.js + * http://lab.hakim.se/reveal-js + * MIT licensed + * + * Copyright (C) 2016 Hakim El Hattab, http://hakim.se + */ + + +/********************************************* + * RESET STYLES + *********************************************/ + +html, body, .reveal div, .reveal span, .reveal applet, .reveal object, .reveal iframe, +.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal p, .reveal blockquote, .reveal pre, +.reveal a, .reveal abbr, .reveal acronym, .reveal address, .reveal big, .reveal cite, .reveal code, +.reveal del, .reveal dfn, .reveal em, .reveal img, .reveal ins, .reveal kbd, .reveal q, .reveal s, .reveal samp, +.reveal small, .reveal strike, .reveal strong, .reveal sub, .reveal sup, .reveal tt, .reveal var, +.reveal b, .reveal u, .reveal center, +.reveal dl, .reveal dt, .reveal dd, .reveal ol, .reveal ul, .reveal li, +.reveal fieldset, .reveal form, .reveal label, .reveal legend, +.reveal table, .reveal caption, .reveal tbody, .reveal tfoot, .reveal thead, .reveal tr, .reveal th, .reveal td, +.reveal article, .reveal aside, .reveal canvas, .reveal details, .reveal embed, +.reveal figure, .reveal figcaption, .reveal footer, .reveal header, .reveal hgroup, +.reveal menu, .reveal nav, .reveal output, .reveal ruby, .reveal section, .reveal summary, +.reveal time, .reveal mark, .reveal audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +.reveal article, .reveal aside, .reveal details, .reveal figcaption, .reveal figure, +.reveal footer, .reveal header, .reveal hgroup, .reveal menu, .reveal nav, .reveal section { + display: block; +} + + +/********************************************* + * GLOBAL STYLES + *********************************************/ + +html, +body { + width: 100%; + height: 100%; + overflow: hidden; +} + +body { + position: relative; + line-height: 1; + + background-color: #fff; + color: #000; +} + +// Ensures that the main background color matches the +// theme in fullscreen mode +html:-webkit-full-screen-ancestor { + background-color: inherit; +} +html:-moz-full-screen-ancestor { + background-color: inherit; +} + + +/********************************************* + * VIEW FRAGMENTS + *********************************************/ + +.reveal .slides section .fragment { + opacity: 0; + visibility: hidden; + transition: all .2s ease; + + &.visible { + opacity: 1; + visibility: visible; + } +} + +.reveal .slides section .fragment.grow { + opacity: 1; + visibility: visible; + + &.visible { + transform: scale( 1.3 ); + } +} + +.reveal .slides section .fragment.shrink { + opacity: 1; + visibility: visible; + + &.visible { + transform: scale( 0.7 ); + } +} + +.reveal .slides section .fragment.zoom-in { + transform: scale( 0.1 ); + + &.visible { + transform: none; + } +} + +.reveal .slides section .fragment.fade-out { + opacity: 1; + visibility: visible; + + &.visible { + opacity: 0; + visibility: hidden; + } +} + +.reveal .slides section .fragment.semi-fade-out { + opacity: 1; + visibility: visible; + + &.visible { + opacity: 0.5; + visibility: visible; + } +} + +.reveal .slides section .fragment.strike { + opacity: 1; + visibility: visible; + + &.visible { + text-decoration: line-through; + } +} + +.reveal .slides section .fragment.current-visible { + opacity: 0; + visibility: hidden; + + &.current-fragment { + opacity: 1; + visibility: visible; + } +} + +.reveal .slides section .fragment.highlight-red, +.reveal .slides section .fragment.highlight-current-red, +.reveal .slides section .fragment.highlight-green, +.reveal .slides section .fragment.highlight-current-green, +.reveal .slides section .fragment.highlight-blue, +.reveal .slides section .fragment.highlight-current-blue { + opacity: 1; + visibility: visible; +} + .reveal .slides section .fragment.highlight-red.visible { + color: #ff2c2d + } + .reveal .slides section .fragment.highlight-green.visible { + color: #17ff2e; + } + .reveal .slides section .fragment.highlight-blue.visible { + color: #1b91ff; + } + +.reveal .slides section .fragment.highlight-current-red.current-fragment { + color: #ff2c2d +} +.reveal .slides section .fragment.highlight-current-green.current-fragment { + color: #17ff2e; +} +.reveal .slides section .fragment.highlight-current-blue.current-fragment { + color: #1b91ff; +} + + +/********************************************* + * DEFAULT ELEMENT STYLES + *********************************************/ + +/* Fixes issue in Chrome where italic fonts did not appear when printing to PDF */ +.reveal:after { + content: ''; + font-style: italic; +} + +.reveal iframe { + z-index: 1; +} + +/** Prevents layering issues in certain browser/transition combinations */ +.reveal a { + position: relative; +} + +.reveal .stretch { + max-width: none; + max-height: none; +} + +.reveal pre.stretch code { + height: 100%; + max-height: 100%; + box-sizing: border-box; +} + + +/********************************************* + * CONTROLS + *********************************************/ + +.reveal .controls { + display: none; + position: fixed; + width: 110px; + height: 110px; + z-index: 30; + right: 10px; + bottom: 10px; + + -webkit-user-select: none; +} + +.reveal .controls button { + padding: 0; + position: absolute; + opacity: 0.05; + width: 0; + height: 0; + background-color: transparent; + border: 12px solid transparent; + transform: scale(.9999); + transition: all 0.2s ease; + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba( 0, 0, 0, 0 ); +} + +.reveal .controls .enabled { + opacity: 0.7; + cursor: pointer; +} + +.reveal .controls .enabled:active { + margin-top: 1px; +} + + .reveal .controls .navigate-left { + top: 42px; + + border-right-width: 22px; + border-right-color: #000; + } + .reveal .controls .navigate-left.fragmented { + opacity: 0.3; + } + + .reveal .controls .navigate-right { + left: 74px; + top: 42px; + + border-left-width: 22px; + border-left-color: #000; + } + .reveal .controls .navigate-right.fragmented { + opacity: 0.3; + } + + .reveal .controls .navigate-up { + left: 42px; + + border-bottom-width: 22px; + border-bottom-color: #000; + } + .reveal .controls .navigate-up.fragmented { + opacity: 0.3; + } + + .reveal .controls .navigate-down { + left: 42px; + top: 74px; + + border-top-width: 22px; + border-top-color: #000; + } + .reveal .controls .navigate-down.fragmented { + opacity: 0.3; + } + + +/********************************************* + * PROGRESS BAR + *********************************************/ + +.reveal .progress { + position: fixed; + display: none; + height: 3px; + width: 100%; + bottom: 0; + left: 0; + z-index: 10; + + background-color: rgba( 0, 0, 0, 0.2 ); +} + .reveal .progress:after { + content: ''; + display: block; + position: absolute; + height: 20px; + width: 100%; + top: -20px; + } + .reveal .progress span { + display: block; + height: 100%; + width: 0px; + + background-color: #000; + transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + +/********************************************* + * SLIDE NUMBER + *********************************************/ + +.reveal .slide-number { + position: fixed; + display: block; + right: 8px; + bottom: 8px; + z-index: 31; + font-family: Helvetica, sans-serif; + font-size: 12px; + line-height: 1; + color: #fff; + background-color: rgba( 0, 0, 0, 0.4 ); + padding: 5px; +} + +.reveal .slide-number-delimiter { + margin: 0 3px; +} + +/********************************************* + * SLIDES + *********************************************/ + +.reveal { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + touch-action: none; +} + +.reveal .slides { + position: absolute; + width: 100%; + height: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; + + overflow: visible; + z-index: 1; + text-align: center; + perspective: 600px; + perspective-origin: 50% 40%; +} + +.reveal .slides>section { + -ms-perspective: 600px; +} + +.reveal .slides>section, +.reveal .slides>section>section { + display: none; + position: absolute; + width: 100%; + padding: 20px 0px; + + z-index: 10; + transform-style: preserve-3d; + transition: transform-origin 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + transform 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + visibility 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985), + opacity 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); +} + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"] .slides section { + transition-duration: 400ms; +} +.reveal[data-transition-speed="slow"] .slides section { + transition-duration: 1200ms; +} + +/* Slide-specific transition speed overrides */ +.reveal .slides section[data-transition-speed="fast"] { + transition-duration: 400ms; +} +.reveal .slides section[data-transition-speed="slow"] { + transition-duration: 1200ms; +} + +.reveal .slides>section.stack { + padding-top: 0; + padding-bottom: 0; +} + +.reveal .slides>section.present, +.reveal .slides>section>section.present { + display: block; + z-index: 11; + opacity: 1; +} + +.reveal.center, +.reveal.center .slides, +.reveal.center .slides section { + min-height: 0 !important; +} + +/* Don't allow interaction with invisible slides */ +.reveal .slides>section.future, +.reveal .slides>section>section.future, +.reveal .slides>section.past, +.reveal .slides>section>section.past { + pointer-events: none; +} + +.reveal.overview .slides>section, +.reveal.overview .slides>section>section { + pointer-events: auto; +} + +.reveal .slides>section.past, +.reveal .slides>section.future, +.reveal .slides>section>section.past, +.reveal .slides>section>section.future { + opacity: 0; +} + + +/********************************************* + * Mixins for readability of transitions + *********************************************/ + +@mixin transition-global($style) { + .reveal .slides section[data-transition=#{$style}], + .reveal.#{$style} .slides section:not([data-transition]) { + @content; + } +} +@mixin transition-horizontal-past($style) { + .reveal .slides>section[data-transition=#{$style}].past, + .reveal .slides>section[data-transition~=#{$style}-out].past, + .reveal.#{$style} .slides>section:not([data-transition]).past { + @content; + } +} +@mixin transition-horizontal-future($style) { + .reveal .slides>section[data-transition=#{$style}].future, + .reveal .slides>section[data-transition~=#{$style}-in].future, + .reveal.#{$style} .slides>section:not([data-transition]).future { + @content; + } +} + +@mixin transition-vertical-past($style) { + .reveal .slides>section>section[data-transition=#{$style}].past, + .reveal .slides>section>section[data-transition~=#{$style}-out].past, + .reveal.#{$style} .slides>section>section:not([data-transition]).past { + @content; + } +} +@mixin transition-vertical-future($style) { + .reveal .slides>section>section[data-transition=#{$style}].future, + .reveal .slides>section>section[data-transition~=#{$style}-in].future, + .reveal.#{$style} .slides>section>section:not([data-transition]).future { + @content; + } +} + +/********************************************* + * SLIDE TRANSITION + * Aliased 'linear' for backwards compatibility + *********************************************/ + +@each $stylename in slide, linear { + .reveal.#{$stylename} section { + backface-visibility: hidden; + } + @include transition-horizontal-past(#{$stylename}) { + transform: translate(-150%, 0); + } + @include transition-horizontal-future(#{$stylename}) { + transform: translate(150%, 0); + } + @include transition-vertical-past(#{$stylename}) { + transform: translate(0, -150%); + } + @include transition-vertical-future(#{$stylename}) { + transform: translate(0, 150%); + } +} + +/********************************************* + * CONVEX TRANSITION + * Aliased 'default' for backwards compatibility + *********************************************/ + +@each $stylename in default, convex { + @include transition-horizontal-past(#{$stylename}) { + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); + } + @include transition-horizontal-future(#{$stylename}) { + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); + } + @include transition-vertical-past(#{$stylename}) { + transform: translate3d(0, -300px, 0) rotateX(70deg) translate3d(0, -300px, 0); + } + @include transition-vertical-future(#{$stylename}) { + transform: translate3d(0, 300px, 0) rotateX(-70deg) translate3d(0, 300px, 0); + } +} + +/********************************************* + * CONCAVE TRANSITION + *********************************************/ + +@include transition-horizontal-past(concave) { + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); +} +@include transition-horizontal-future(concave) { + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); +} +@include transition-vertical-past(concave) { + transform: translate3d(0, -80%, 0) rotateX(-70deg) translate3d(0, -80%, 0); +} +@include transition-vertical-future(concave) { + transform: translate3d(0, 80%, 0) rotateX(70deg) translate3d(0, 80%, 0); +} + + +/********************************************* + * ZOOM TRANSITION + *********************************************/ + +@include transition-global(zoom) { + transition-timing-function: ease; +} +@include transition-horizontal-past(zoom) { + visibility: hidden; + transform: scale(16); +} +@include transition-horizontal-future(zoom) { + visibility: hidden; + transform: scale(0.2); +} +@include transition-vertical-past(zoom) { + transform: translate(0, -150%); +} +@include transition-vertical-future(zoom) { + transform: translate(0, 150%); +} + + +/********************************************* + * CUBE TRANSITION + *********************************************/ + +.reveal.cube .slides { + perspective: 1300px; +} + +.reveal.cube .slides section { + padding: 30px; + min-height: 700px; + backface-visibility: hidden; + box-sizing: border-box; +} + .reveal.center.cube .slides section { + min-height: 0; + } + .reveal.cube .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0,0,0,0.1); + border-radius: 4px; + transform: translateZ( -20px ); + } + .reveal.cube .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0,0,0,0.2); + transform: translateZ(-90px) rotateX( 65deg ); + } + +.reveal.cube .slides>section.stack { + padding: 0; + background: none; +} + +.reveal.cube .slides>section.past { + transform-origin: 100% 0%; + transform: translate3d(-100%, 0, 0) rotateY(-90deg); +} + +.reveal.cube .slides>section.future { + transform-origin: 0% 0%; + transform: translate3d(100%, 0, 0) rotateY(90deg); +} + +.reveal.cube .slides>section>section.past { + transform-origin: 0% 100%; + transform: translate3d(0, -100%, 0) rotateX(90deg); +} + +.reveal.cube .slides>section>section.future { + transform-origin: 0% 0%; + transform: translate3d(0, 100%, 0) rotateX(-90deg); +} + + +/********************************************* + * PAGE TRANSITION + *********************************************/ + +.reveal.page .slides { + perspective-origin: 0% 50%; + perspective: 3000px; +} + +.reveal.page .slides section { + padding: 30px; + min-height: 700px; + box-sizing: border-box; +} + .reveal.page .slides section.past { + z-index: 12; + } + .reveal.page .slides section:not(.stack):before { + content: ''; + position: absolute; + display: block; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgba(0,0,0,0.1); + transform: translateZ( -20px ); + } + .reveal.page .slides section:not(.stack):after { + content: ''; + position: absolute; + display: block; + width: 90%; + height: 30px; + left: 5%; + bottom: 0; + background: none; + z-index: 1; + + border-radius: 4px; + box-shadow: 0px 95px 25px rgba(0,0,0,0.2); + + -webkit-transform: translateZ(-90px) rotateX( 65deg ); + } + +.reveal.page .slides>section.stack { + padding: 0; + background: none; +} + +.reveal.page .slides>section.past { + transform-origin: 0% 0%; + transform: translate3d(-40%, 0, 0) rotateY(-80deg); +} + +.reveal.page .slides>section.future { + transform-origin: 100% 0%; + transform: translate3d(0, 0, 0); +} + +.reveal.page .slides>section>section.past { + transform-origin: 0% 0%; + transform: translate3d(0, -40%, 0) rotateX(80deg); +} + +.reveal.page .slides>section>section.future { + transform-origin: 0% 100%; + transform: translate3d(0, 0, 0); +} + + +/********************************************* + * FADE TRANSITION + *********************************************/ + +.reveal .slides section[data-transition=fade], +.reveal.fade .slides section:not([data-transition]), +.reveal.fade .slides>section>section:not([data-transition]) { + transform: none; + transition: opacity 0.5s; +} + + +.reveal.fade.overview .slides section, +.reveal.fade.overview .slides>section>section { + transition: none; +} + + +/********************************************* + * NO TRANSITION + *********************************************/ + +@include transition-global(none) { + transform: none; + transition: none; +} + + +/********************************************* + * PAUSED MODE + *********************************************/ + +.reveal .pause-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: black; + visibility: hidden; + opacity: 0; + z-index: 100; + transition: all 1s ease; +} +.reveal.paused .pause-overlay { + visibility: visible; + opacity: 1; +} + + +/********************************************* + * FALLBACK + *********************************************/ + +.no-transforms { + overflow-y: auto; +} + +.no-transforms .reveal .slides { + position: relative; + width: 80%; + height: auto !important; + top: 0; + left: 50%; + margin: 0; + text-align: center; +} + +.no-transforms .reveal .controls, +.no-transforms .reveal .progress { + display: none !important; +} + +.no-transforms .reveal .slides section { + display: block !important; + opacity: 1 !important; + position: relative !important; + height: auto; + min-height: 0; + top: 0; + left: -50%; + margin: 70px 0; + transform: none; +} + +.no-transforms .reveal .slides section section { + left: 0; +} + +.reveal .no-transition, +.reveal .no-transition * { + transition: none !important; +} + + +/********************************************* + * PER-SLIDE BACKGROUNDS + *********************************************/ + +.reveal .backgrounds { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + perspective: 600px; +} + .reveal .slide-background { + display: none; + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + visibility: hidden; + + background-color: rgba( 0, 0, 0, 0 ); + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; + + transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + + .reveal .slide-background.stack { + display: block; + } + + .reveal .slide-background.present { + opacity: 1; + visibility: visible; + } + + .print-pdf .reveal .slide-background { + opacity: 1 !important; + visibility: visible !important; + } + +/* Video backgrounds */ +.reveal .slide-background video { + position: absolute; + width: 100%; + height: 100%; + max-width: none; + max-height: none; + top: 0; + left: 0; +} + +/* Immediate transition style */ +.reveal[data-background-transition=none]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=none] { + transition: none; +} + +/* Slide */ +.reveal[data-background-transition=slide]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=slide] { + opacity: 1; + backface-visibility: hidden; +} + .reveal[data-background-transition=slide]>.backgrounds .slide-background.past, + .reveal>.backgrounds .slide-background.past[data-background-transition=slide] { + transform: translate(-100%, 0); + } + .reveal[data-background-transition=slide]>.backgrounds .slide-background.future, + .reveal>.backgrounds .slide-background.future[data-background-transition=slide] { + transform: translate(100%, 0); + } + + .reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past, + .reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide] { + transform: translate(0, -100%); + } + .reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future, + .reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide] { + transform: translate(0, 100%); + } + + +/* Convex */ +.reveal[data-background-transition=convex]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=convex] { + opacity: 0; + transform: translate3d(-100%, 0, 0) rotateY(-90deg) translate3d(-100%, 0, 0); +} +.reveal[data-background-transition=convex]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=convex] { + opacity: 0; + transform: translate3d(100%, 0, 0) rotateY(90deg) translate3d(100%, 0, 0); +} + +.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex] { + opacity: 0; + transform: translate3d(0, -100%, 0) rotateX(90deg) translate3d(0, -100%, 0); +} +.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex] { + opacity: 0; + transform: translate3d(0, 100%, 0) rotateX(-90deg) translate3d(0, 100%, 0); +} + + +/* Concave */ +.reveal[data-background-transition=concave]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=concave] { + opacity: 0; + transform: translate3d(-100%, 0, 0) rotateY(90deg) translate3d(-100%, 0, 0); +} +.reveal[data-background-transition=concave]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=concave] { + opacity: 0; + transform: translate3d(100%, 0, 0) rotateY(-90deg) translate3d(100%, 0, 0); +} + +.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave] { + opacity: 0; + transform: translate3d(0, -100%, 0) rotateX(-90deg) translate3d(0, -100%, 0); +} +.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave] { + opacity: 0; + transform: translate3d(0, 100%, 0) rotateX(90deg) translate3d(0, 100%, 0); +} + +/* Zoom */ +.reveal[data-background-transition=zoom]>.backgrounds .slide-background, +.reveal>.backgrounds .slide-background[data-background-transition=zoom] { + transition-timing-function: ease; +} + +.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past, +.reveal>.backgrounds .slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(16); +} +.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future, +.reveal>.backgrounds .slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(0.2); +} + +.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past, +.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(16); +} +.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future, +.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom] { + opacity: 0; + visibility: hidden; + transform: scale(0.2); +} + + +/* Global transition speed settings */ +.reveal[data-transition-speed="fast"]>.backgrounds .slide-background { + transition-duration: 400ms; +} +.reveal[data-transition-speed="slow"]>.backgrounds .slide-background { + transition-duration: 1200ms; +} + + +/********************************************* + * OVERVIEW + *********************************************/ + +.reveal.overview { + perspective-origin: 50% 50%; + perspective: 700px; + + .slides section { + height: 700px; + opacity: 1 !important; + overflow: hidden; + visibility: visible !important; + cursor: pointer; + box-sizing: border-box; + } + .slides section:hover, + .slides section.present { + outline: 10px solid rgba(150,150,150,0.4); + outline-offset: 10px; + } + .slides section .fragment { + opacity: 1; + transition: none; + } + .slides section:after, + .slides section:before { + display: none !important; + } + .slides>section.stack { + padding: 0; + top: 0 !important; + background: none; + outline: none; + overflow: visible; + } + + .backgrounds { + perspective: inherit; + } + + .backgrounds .slide-background { + opacity: 1; + visibility: visible; + + // This can't be applied to the slide itself in Safari + outline: 10px solid rgba(150,150,150,0.1); + outline-offset: 10px; + } +} + +// Disable transitions transitions while we're activating +// or deactivating the overview mode. +.reveal.overview .slides section, +.reveal.overview-deactivating .slides section { + transition: none; +} + +.reveal.overview .backgrounds .slide-background, +.reveal.overview-deactivating .backgrounds .slide-background { + transition: none; +} + +.reveal.overview-animated .slides { + transition: transform 0.4s ease; +} + + +/********************************************* + * RTL SUPPORT + *********************************************/ + +.reveal.rtl .slides, +.reveal.rtl .slides h1, +.reveal.rtl .slides h2, +.reveal.rtl .slides h3, +.reveal.rtl .slides h4, +.reveal.rtl .slides h5, +.reveal.rtl .slides h6 { + direction: rtl; + font-family: sans-serif; +} + +.reveal.rtl pre, +.reveal.rtl code { + direction: ltr; +} + +.reveal.rtl ol, +.reveal.rtl ul { + text-align: right; +} + +.reveal.rtl .progress span { + float: right +} + +/********************************************* + * PARALLAX BACKGROUND + *********************************************/ + +.reveal.has-parallax-background .backgrounds { + transition: all 0.8s ease; +} + +/* Global transition speed settings */ +.reveal.has-parallax-background[data-transition-speed="fast"] .backgrounds { + transition-duration: 400ms; +} +.reveal.has-parallax-background[data-transition-speed="slow"] .backgrounds { + transition-duration: 1200ms; +} + + +/********************************************* + * LINK PREVIEW OVERLAY + *********************************************/ + +.reveal .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + background: rgba( 0, 0, 0, 0.9 ); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; +} + .reveal .overlay.visible { + opacity: 1; + visibility: visible; + } + + .reveal .overlay .spinner { + position: absolute; + display: block; + top: 50%; + left: 50%; + width: 32px; + height: 32px; + margin: -16px 0 0 -16px; + z-index: 10; + background-image: url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D); + + visibility: visible; + opacity: 0.6; + transition: all 0.3s ease; + } + + .reveal .overlay header { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 40px; + z-index: 2; + border-bottom: 1px solid #222; + } + .reveal .overlay header a { + display: inline-block; + width: 40px; + height: 40px; + padding: 0 10px; + float: right; + opacity: 0.6; + + box-sizing: border-box; + } + .reveal .overlay header a:hover { + opacity: 1; + } + .reveal .overlay header a .icon { + display: inline-block; + width: 20px; + height: 20px; + + background-position: 50% 50%; + background-size: 100%; + background-repeat: no-repeat; + } + .reveal .overlay header a.close .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC); + } + .reveal .overlay header a.external .icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==); + } + + .reveal .overlay .viewport { + position: absolute; + top: 40px; + right: 0; + bottom: 0; + left: 0; + } + + .reveal .overlay.overlay-preview .viewport iframe { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + border: 0; + + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + } + + .reveal .overlay.overlay-preview.loaded .viewport iframe { + opacity: 1; + visibility: visible; + } + + .reveal .overlay.overlay-preview.loaded .spinner { + opacity: 0; + visibility: hidden; + transform: scale(0.2); + } + + .reveal .overlay.overlay-help .viewport { + overflow: auto; + color: #fff; + } + + .reveal .overlay.overlay-help .viewport .viewport-inner { + width: 600px; + margin: 0 auto; + padding: 60px; + text-align: center; + letter-spacing: normal; + } + + .reveal .overlay.overlay-help .viewport .viewport-inner .title { + font-size: 20px; + } + + .reveal .overlay.overlay-help .viewport .viewport-inner table { + border: 1px solid #fff; + border-collapse: collapse; + font-size: 14px; + } + + .reveal .overlay.overlay-help .viewport .viewport-inner table th, + .reveal .overlay.overlay-help .viewport .viewport-inner table td { + width: 200px; + padding: 10px; + border: 1px solid #fff; + vertical-align: middle; + } + + .reveal .overlay.overlay-help .viewport .viewport-inner table th { + padding-top: 20px; + padding-bottom: 20px; + } + + + +/********************************************* + * PLAYBACK COMPONENT + *********************************************/ + +.reveal .playback { + position: fixed; + left: 15px; + bottom: 20px; + z-index: 30; + cursor: pointer; + transition: all 400ms ease; +} + +.reveal.overview .playback { + opacity: 0; + visibility: hidden; +} + + +/********************************************* + * ROLLING LINKS + *********************************************/ + +.reveal .roll { + display: inline-block; + line-height: 1.2; + overflow: hidden; + + vertical-align: top; + perspective: 400px; + perspective-origin: 50% 50%; +} + .reveal .roll:hover { + background: none; + text-shadow: none; + } +.reveal .roll span { + display: block; + position: relative; + padding: 0 2px; + + pointer-events: none; + transition: all 400ms ease; + transform-origin: 50% 0%; + transform-style: preserve-3d; + backface-visibility: hidden; +} + .reveal .roll:hover span { + background: rgba(0,0,0,0.5); + transform: translate3d( 0px, 0px, -45px ) rotateX( 90deg ); + } +.reveal .roll span:after { + content: attr(data-title); + + display: block; + position: absolute; + left: 0; + top: 0; + padding: 0 2px; + backface-visibility: hidden; + transform-origin: 50% 0%; + transform: translate3d( 0px, 110%, 0px ) rotateX( -90deg ); +} + + +/********************************************* + * SPEAKER NOTES + *********************************************/ + +// Hide on-page notes +.reveal aside.notes { + display: none; +} + +// An interface element that can optionally be used to show the +// speaker notes to all viewers, on top of the presentation +.reveal .speaker-notes { + display: none; + position: absolute; + width: 70%; + max-height: 15%; + left: 15%; + bottom: 26px; + padding: 10px; + z-index: 1; + font-size: 18px; + line-height: 1.4; + color: #fff; + background-color: rgba(0,0,0,0.5); + overflow: auto; + box-sizing: border-box; + text-align: left; + font-family: Helvetica, sans-serif; + -webkit-overflow-scrolling: touch; +} + +.reveal .speaker-notes.visible:not(:empty) { + display: block; +} + +@media screen and (max-width: 1024px) { + .reveal .speaker-notes { + font-size: 14px; + } +} + +@media screen and (max-width: 600px) { + .reveal .speaker-notes { + width: 90%; + left: 5%; + } +} + + +/********************************************* + * ZOOM PLUGIN + *********************************************/ + +.zoomed .reveal *, +.zoomed .reveal *:before, +.zoomed .reveal *:after { + backface-visibility: visible !important; +} + +.zoomed .reveal .progress, +.zoomed .reveal .controls { + opacity: 0; +} + +.zoomed .reveal .roll span { + background: none; +} + +.zoomed .reveal .roll span:after { + visibility: hidden; +} + + diff --git a/slides/web-scraping/css/theme/README.md b/slides/web-scraping/css/theme/README.md new file mode 100644 index 0000000..5a6c8fa --- /dev/null +++ b/slides/web-scraping/css/theme/README.md @@ -0,0 +1,21 @@ +## Dependencies + +Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup + +## Creating a Theme + +To create your own theme, start by duplicating a ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). It will be automatically compiled by Grunt from Sass to CSS (see the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js)) when you run `grunt css-themes`. + +Each theme file does four things in the following order: + +1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)** +Shared utility functions. + +2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)** +Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3. + +3. **Override** +This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding any selectors and styles you please. + +4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)** +The template theme file which will generate final CSS output based on the currently defined variables. diff --git a/slides/web-scraping/css/theme/beige.css b/slides/web-scraping/css/theme/beige.css new file mode 100644 index 0000000..be18733 --- /dev/null +++ b/slides/web-scraping/css/theme/beige.css @@ -0,0 +1,290 @@ +/** + * Beige theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #f7f2d3; + background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3)); + background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%); + background-color: #f7f3de; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 36px; + font-weight: normal; + color: #333; } + +::selection { + color: #fff; + background: rgba(79, 64, 28, 0.99); + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #333; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #8b743d; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #c0a86e; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #564826; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #333; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #8b743d; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #8b743d; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #8b743d; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #8b743d; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #8b743d; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #c0a86e; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #c0a86e; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #c0a86e; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #c0a86e; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #8b743d; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/black.css b/slides/web-scraping/css/theme/black.css new file mode 100644 index 0000000..deccc46 --- /dev/null +++ b/slides/web-scraping/css/theme/black.css @@ -0,0 +1,286 @@ +/** + * Black theme for reveal.js. This is the opposite of the 'white' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 { + color: #222; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #222; + background-color: #222; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #fff; } + +::selection { + color: #fff; + background: #bee4fd; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #fff; + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #42affa; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #8dcffc; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #068de9; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #fff; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #42affa; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #42affa; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #42affa; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #42affa; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #42affa; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #8dcffc; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #8dcffc; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #8dcffc; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #8dcffc; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #42affa; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/blood.css b/slides/web-scraping/css/theme/blood.css new file mode 100644 index 0000000..e035ab6 --- /dev/null +++ b/slides/web-scraping/css/theme/blood.css @@ -0,0 +1,309 @@ +/** + * Blood theme for reveal.js + * Author: Walther http://github.com/Walther + * + * Designed to be used with highlight.js theme + * "monokai_sublime.css" available from + * https://github.com/isagalaev/highlight.js/ + * + * For other themes, change $codeBackground accordingly. + * + */ +@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #222; + background-color: #222; } + +.reveal { + font-family: Ubuntu, "sans-serif"; + font-size: 36px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #a23; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: Ubuntu, "sans-serif"; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: 2px 2px 2px #222; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #a23; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #dd5566; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #6a1520; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #a23; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #a23; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #a23; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #a23; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #a23; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #dd5566; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #dd5566; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #dd5566; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #dd5566; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #a23; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } + +.reveal p { + font-weight: 300; + text-shadow: 1px 1px #222; } + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + font-weight: 700; } + +.reveal p code { + background-color: #23241f; + display: inline-block; + border-radius: 7px; } + +.reveal small code { + vertical-align: baseline; } diff --git a/slides/web-scraping/css/theme/league.css b/slides/web-scraping/css/theme/league.css new file mode 100644 index 0000000..fa9f53c --- /dev/null +++ b/slides/web-scraping/css/theme/league.css @@ -0,0 +1,292 @@ +/** + * League theme for reveal.js. + * + * This was the default theme pre-3.0.0. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #1c1e20; + background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20)); + background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%); + background-color: #2b2b2b; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 36px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #FF5E99; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #13DAEC; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #71e9f4; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #0d99a5; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #13DAEC; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #13DAEC; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #13DAEC; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #13DAEC; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #13DAEC; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #71e9f4; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #71e9f4; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #71e9f4; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #71e9f4; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #13DAEC; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/moon.css b/slides/web-scraping/css/theme/moon.css new file mode 100644 index 0000000..b119576 --- /dev/null +++ b/slides/web-scraping/css/theme/moon.css @@ -0,0 +1,290 @@ +/** + * Solarized Dark theme for reveal.js. + * Author: Achim Staebler + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #002b36; + background-color: #002b36; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 36px; + font-weight: normal; + color: #93a1a1; } + +::selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee8d5; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #268bd2; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #78b9e6; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a6091; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #93a1a1; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #268bd2; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #268bd2; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #268bd2; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #268bd2; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #268bd2; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #78b9e6; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #78b9e6; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #78b9e6; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #78b9e6; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #268bd2; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/night.css b/slides/web-scraping/css/theme/night.css new file mode 100644 index 0000000..3d0e3c5 --- /dev/null +++ b/slides/web-scraping/css/theme/night.css @@ -0,0 +1,284 @@ +/** + * Black theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=Montserrat:700); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #111; + background-color: #111; } + +.reveal { + font-family: "Open Sans", sans-serif; + font-size: 30px; + font-weight: normal; + color: #eee; } + +::selection { + color: #fff; + background: #e7ad52; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #eee; + font-family: "Montserrat", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: -0.03em; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #e7ad52; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #f3d7ac; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #d08a1d; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #eee; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #e7ad52; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #e7ad52; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #e7ad52; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #e7ad52; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #e7ad52; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #f3d7ac; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #f3d7ac; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #f3d7ac; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #f3d7ac; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #e7ad52; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/serif.css b/slides/web-scraping/css/theme/serif.css new file mode 100644 index 0000000..736c0b5 --- /dev/null +++ b/slides/web-scraping/css/theme/serif.css @@ -0,0 +1,286 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is brown. + * + * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. + */ +.reveal a { + line-height: 1.3em; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #F0F1EB; + background-color: #F0F1EB; } + +.reveal { + font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif; + font-size: 36px; + font-weight: normal; + color: #000; } + +::selection { + color: #fff; + background: #26351C; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #383D3D; + font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #51483D; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #8b7c69; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #25211c; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #000; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #51483D; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #51483D; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #51483D; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #51483D; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #51483D; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #8b7c69; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #8b7c69; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #8b7c69; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #8b7c69; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #51483D; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/simple.css b/slides/web-scraping/css/theme/simple.css new file mode 100644 index 0000000..20d919d --- /dev/null +++ b/slides/web-scraping/css/theme/simple.css @@ -0,0 +1,286 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is darkblue. + * + * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. + * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fff; + background-color: #fff; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 36px; + font-weight: normal; + color: #000; } + +::selection { + color: #fff; + background: rgba(0, 0, 0, 0.99); + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #000; + font-family: "News Cycle", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: none; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #00008B; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #0000f1; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #00003f; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #000; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #00008B; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #00008B; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #00008B; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #00008B; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #00008B; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #0000f1; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #0000f1; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #0000f1; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #0000f1; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #00008B; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/sky.css b/slides/web-scraping/css/theme/sky.css new file mode 100644 index 0000000..e762a50 --- /dev/null +++ b/slides/web-scraping/css/theme/sky.css @@ -0,0 +1,293 @@ +/** + * Sky theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ +@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); +.reveal a { + line-height: 1.3em; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #add9e4; + background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4)); + background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%); + background-color: #f7fbfc; } + +.reveal { + font-family: "Open Sans", sans-serif; + font-size: 36px; + font-weight: normal; + color: #333; } + +::selection { + color: #fff; + background: #134674; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #333; + font-family: "Quicksand", sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: -0.08em; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #3b759e; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #74a7cb; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #264c66; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #333; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #3b759e; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #3b759e; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #3b759e; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #3b759e; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #3b759e; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #74a7cb; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #74a7cb; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #74a7cb; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #74a7cb; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #3b759e; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/solarized.css b/slides/web-scraping/css/theme/solarized.css new file mode 100644 index 0000000..bf2f651 --- /dev/null +++ b/slides/web-scraping/css/theme/solarized.css @@ -0,0 +1,290 @@ +/** + * Solarized Light theme for reveal.js. + * Author: Achim Staebler + */ +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fdf6e3; + background-color: #fdf6e3; } + +.reveal { + font-family: "Lato", sans-serif; + font-size: 36px; + font-weight: normal; + color: #657b83; } + +::selection { + color: #fff; + background: #d33682; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #586e75; + font-family: "League Gothic", Impact, sans-serif; + font-weight: normal; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 3.77em; } + +.reveal h2 { + font-size: 2.11em; } + +.reveal h3 { + font-size: 1.55em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #268bd2; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #78b9e6; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a6091; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #657b83; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #268bd2; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #268bd2; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #268bd2; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #268bd2; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #268bd2; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #78b9e6; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #78b9e6; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #78b9e6; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #78b9e6; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #268bd2; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/css/theme/source/beige.scss b/slides/web-scraping/css/theme/source/beige.scss new file mode 100644 index 0000000..5564f53 --- /dev/null +++ b/slides/web-scraping/css/theme/source/beige.scss @@ -0,0 +1,39 @@ +/** + * Beige theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$mainColor: #333; +$headingColor: #333; +$headingTextShadow: none; +$backgroundColor: #f7f3de; +$linkColor: #8b743d; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: rgba(79, 64, 28, 0.99); +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/black.scss b/slides/web-scraping/css/theme/source/black.scss new file mode 100644 index 0000000..5f7f601 --- /dev/null +++ b/slides/web-scraping/css/theme/source/black.scss @@ -0,0 +1,49 @@ +/** + * Black theme for reveal.js. This is the opposite of the 'white' theme. + * + * By Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #222; + +$mainColor: #fff; +$headingColor: #fff; + +$mainFontSize: 38px; +$mainFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingFontWeight: 600; +$linkColor: #42affa; +$linkColorHover: lighten( $linkColor, 15% ); +$selectionBackgroundColor: lighten( $linkColor, 25% ); + +$heading1Size: 2.5em; +$heading2Size: 1.6em; +$heading3Size: 1.3em; +$heading4Size: 1.0em; + +section.has-light-background { + &, h1, h2, h3, h4, h5, h6 { + color: #222; + } +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/blood.scss b/slides/web-scraping/css/theme/source/blood.scss new file mode 100644 index 0000000..d22b53d --- /dev/null +++ b/slides/web-scraping/css/theme/source/blood.scss @@ -0,0 +1,79 @@ +/** + * Blood theme for reveal.js + * Author: Walther http://github.com/Walther + * + * Designed to be used with highlight.js theme + * "monokai_sublime.css" available from + * https://github.com/isagalaev/highlight.js/ + * + * For other themes, change $codeBackground accordingly. + * + */ + + // Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + +// Include theme-specific fonts + +@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); + +// Colors used in the theme +$blood: #a23; +$coal: #222; +$codeBackground: #23241f; + +$backgroundColor: $coal; + +// Main text +$mainFont: Ubuntu, 'sans-serif'; +$mainFontSize: 36px; +$mainColor: #eee; + +// Headings +$headingFont: Ubuntu, 'sans-serif'; +$headingTextShadow: 2px 2px 2px $coal; + +// h1 shadow, borrowed humbly from +// (c) Default theme by Hakim El Hattab +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Links +$linkColor: $blood; +$linkColorHover: lighten( $linkColor, 20% ); + +// Text selection +$selectionBackgroundColor: $blood; +$selectionColor: #fff; + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- + +// some overrides after theme template import + +.reveal p { + font-weight: 300; + text-shadow: 1px 1px $coal; +} + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + font-weight: 700; +} + +.reveal p code { + background-color: $codeBackground; + display: inline-block; + border-radius: 7px; +} + +.reveal small code { + vertical-align: baseline; +} \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/league.scss b/slides/web-scraping/css/theme/source/league.scss new file mode 100644 index 0000000..46ea04a --- /dev/null +++ b/slides/web-scraping/css/theme/source/league.scss @@ -0,0 +1,34 @@ +/** + * League theme for reveal.js. + * + * This was the default theme pre-3.0.0. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + +// Override theme settings (see ../template/settings.scss) +$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2); +$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/moon.scss b/slides/web-scraping/css/theme/source/moon.scss new file mode 100644 index 0000000..e47e5b5 --- /dev/null +++ b/slides/web-scraping/css/theme/source/moon.scss @@ -0,0 +1,57 @@ +/** + * Solarized Dark theme for reveal.js. + * Author: Achim Staebler + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; +} + +// Solarized colors +$base03: #002b36; +$base02: #073642; +$base01: #586e75; +$base00: #657b83; +$base0: #839496; +$base1: #93a1a1; +$base2: #eee8d5; +$base3: #fdf6e3; +$yellow: #b58900; +$orange: #cb4b16; +$red: #dc322f; +$magenta: #d33682; +$violet: #6c71c4; +$blue: #268bd2; +$cyan: #2aa198; +$green: #859900; + +// Override theme settings (see ../template/settings.scss) +$mainColor: $base1; +$headingColor: $base2; +$headingTextShadow: none; +$backgroundColor: $base03; +$linkColor: $blue; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: $magenta; + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/slides/web-scraping/css/theme/source/night.scss b/slides/web-scraping/css/theme/source/night.scss new file mode 100644 index 0000000..b0cb57f --- /dev/null +++ b/slides/web-scraping/css/theme/source/night.scss @@ -0,0 +1,35 @@ +/** + * Black theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=Montserrat:700); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #111; + +$mainFont: 'Open Sans', sans-serif; +$linkColor: #e7ad52; +$linkColorHover: lighten( $linkColor, 20% ); +$headingFont: 'Montserrat', Impact, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: -0.03em; +$headingTextTransform: none; +$selectionBackgroundColor: #e7ad52; +$mainFontSize: 30px; + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/serif.scss b/slides/web-scraping/css/theme/source/serif.scss new file mode 100644 index 0000000..ec3fcb3 --- /dev/null +++ b/slides/web-scraping/css/theme/source/serif.scss @@ -0,0 +1,35 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is brown. + * + * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; +$mainColor: #000; +$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; +$headingColor: #383D3D; +$headingTextShadow: none; +$headingTextTransform: none; +$backgroundColor: #F0F1EB; +$linkColor: #51483D; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: #26351C; + +.reveal a { + line-height: 1.3em; +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/slides/web-scraping/css/theme/source/simple.scss b/slides/web-scraping/css/theme/source/simple.scss new file mode 100644 index 0000000..84c7d9b --- /dev/null +++ b/slides/web-scraping/css/theme/source/simple.scss @@ -0,0 +1,38 @@ +/** + * A simple theme for reveal.js presentations, similar + * to the default theme. The accent color is darkblue. + * + * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. + * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Lato', sans-serif; +$mainColor: #000; +$headingFont: 'News Cycle', Impact, sans-serif; +$headingColor: #000; +$headingTextShadow: none; +$headingTextTransform: none; +$backgroundColor: #fff; +$linkColor: #00008B; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: rgba(0, 0, 0, 0.99); + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/source/sky.scss b/slides/web-scraping/css/theme/source/sky.scss new file mode 100644 index 0000000..3fee67c --- /dev/null +++ b/slides/web-scraping/css/theme/source/sky.scss @@ -0,0 +1,46 @@ +/** + * Sky theme for reveal.js. + * + * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); + + +// Override theme settings (see ../template/settings.scss) +$mainFont: 'Open Sans', sans-serif; +$mainColor: #333; +$headingFont: 'Quicksand', sans-serif; +$headingColor: #333; +$headingLetterSpacing: -0.08em; +$headingTextShadow: none; +$backgroundColor: #f7fbfc; +$linkColor: #3b759e; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: #134674; + +// Fix links so they are not cut off +.reveal a { + line-height: 1.3em; +} + +// Background generator +@mixin bodyBackground() { + @include radial-gradient( #add9e4, #f7fbfc ); +} + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/slides/web-scraping/css/theme/source/solarized.scss b/slides/web-scraping/css/theme/source/solarized.scss new file mode 100644 index 0000000..912be56 --- /dev/null +++ b/slides/web-scraping/css/theme/source/solarized.scss @@ -0,0 +1,63 @@ +/** + * Solarized Light theme for reveal.js. + * Author: Achim Staebler + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + + +// Include theme-specific fonts +@import url(../../lib/font/league-gothic/league-gothic.css); +@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); + + +/** + * Solarized colors by Ethan Schoonover + */ +html * { + color-profile: sRGB; + rendering-intent: auto; +} + +// Solarized colors +$base03: #002b36; +$base02: #073642; +$base01: #586e75; +$base00: #657b83; +$base0: #839496; +$base1: #93a1a1; +$base2: #eee8d5; +$base3: #fdf6e3; +$yellow: #b58900; +$orange: #cb4b16; +$red: #dc322f; +$magenta: #d33682; +$violet: #6c71c4; +$blue: #268bd2; +$cyan: #2aa198; +$green: #859900; + +// Override theme settings (see ../template/settings.scss) +$mainColor: $base00; +$headingColor: $base01; +$headingTextShadow: none; +$backgroundColor: $base3; +$linkColor: $blue; +$linkColorHover: lighten( $linkColor, 20% ); +$selectionBackgroundColor: $magenta; + +// Background generator +// @mixin bodyBackground() { +// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) ); +// } + + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- diff --git a/slides/web-scraping/css/theme/source/white.scss b/slides/web-scraping/css/theme/source/white.scss new file mode 100644 index 0000000..6758ce0 --- /dev/null +++ b/slides/web-scraping/css/theme/source/white.scss @@ -0,0 +1,49 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ + + +// Default mixins and settings ----------------- +@import "../template/mixins"; +@import "../template/settings"; +// --------------------------------------------- + + +// Include theme-specific fonts +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); + + +// Override theme settings (see ../template/settings.scss) +$backgroundColor: #fff; + +$mainColor: #222; +$headingColor: #222; + +$mainFontSize: 38px; +$mainFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingFont: 'Source Sans Pro', Helvetica, sans-serif; +$headingTextShadow: none; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingFontWeight: 600; +$linkColor: #2a76dd; +$linkColorHover: lighten( $linkColor, 15% ); +$selectionBackgroundColor: lighten( $linkColor, 25% ); + +$heading1Size: 2.5em; +$heading2Size: 1.6em; +$heading3Size: 1.3em; +$heading4Size: 1.0em; + +section.has-dark-background { + &, h1, h2, h3, h4, h5, h6 { + color: #fff; + } +} + + +// Theme template ------------------------------ +@import "../template/theme"; +// --------------------------------------------- \ No newline at end of file diff --git a/slides/web-scraping/css/theme/template/mixins.scss b/slides/web-scraping/css/theme/template/mixins.scss new file mode 100644 index 0000000..e0c5606 --- /dev/null +++ b/slides/web-scraping/css/theme/template/mixins.scss @@ -0,0 +1,29 @@ +@mixin vertical-gradient( $top, $bottom ) { + background: $top; + background: -moz-linear-gradient( top, $top 0%, $bottom 100% ); + background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) ); + background: -webkit-linear-gradient( top, $top 0%, $bottom 100% ); + background: -o-linear-gradient( top, $top 0%, $bottom 100% ); + background: -ms-linear-gradient( top, $top 0%, $bottom 100% ); + background: linear-gradient( top, $top 0%, $bottom 100% ); +} + +@mixin horizontal-gradient( $top, $bottom ) { + background: $top; + background: -moz-linear-gradient( left, $top 0%, $bottom 100% ); + background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) ); + background: -webkit-linear-gradient( left, $top 0%, $bottom 100% ); + background: -o-linear-gradient( left, $top 0%, $bottom 100% ); + background: -ms-linear-gradient( left, $top 0%, $bottom 100% ); + background: linear-gradient( left, $top 0%, $bottom 100% ); +} + +@mixin radial-gradient( $outer, $inner, $type: circle ) { + background: $outer; + background: -moz-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) ); + background: -webkit-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -o-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: -ms-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); + background: radial-gradient( center, $type cover, $inner 0%, $outer 100% ); +} \ No newline at end of file diff --git a/slides/web-scraping/css/theme/template/settings.scss b/slides/web-scraping/css/theme/template/settings.scss new file mode 100644 index 0000000..ffaac23 --- /dev/null +++ b/slides/web-scraping/css/theme/template/settings.scss @@ -0,0 +1,43 @@ +// Base settings for all themes that can optionally be +// overridden by the super-theme + +// Background of the presentation +$backgroundColor: #2b2b2b; + +// Primary/body text +$mainFont: 'Lato', sans-serif; +$mainFontSize: 36px; +$mainColor: #eee; + +// Vertical spacing between blocks of text +$blockMargin: 20px; + +// Headings +$headingMargin: 0 0 $blockMargin 0; +$headingFont: 'League Gothic', Impact, sans-serif; +$headingColor: #eee; +$headingLineHeight: 1.2; +$headingLetterSpacing: normal; +$headingTextTransform: uppercase; +$headingTextShadow: none; +$headingFontWeight: normal; +$heading1TextShadow: $headingTextShadow; + +$heading1Size: 3.77em; +$heading2Size: 2.11em; +$heading3Size: 1.55em; +$heading4Size: 1.00em; + +// Links and actions +$linkColor: #13DAEC; +$linkColorHover: lighten( $linkColor, 20% ); + +// Text selection +$selectionBackgroundColor: #FF5E99; +$selectionColor: #fff; + +// Generates the presentation background, can be overridden +// to return a background image or gradient +@mixin bodyBackground() { + background: $backgroundColor; +} \ No newline at end of file diff --git a/slides/web-scraping/css/theme/template/theme.scss b/slides/web-scraping/css/theme/template/theme.scss new file mode 100644 index 0000000..9bb416a --- /dev/null +++ b/slides/web-scraping/css/theme/template/theme.scss @@ -0,0 +1,345 @@ +// Base theme template for reveal.js + +/********************************************* + * GLOBAL STYLES + *********************************************/ + +body { + @include bodyBackground(); + background-color: $backgroundColor; +} + +.reveal { + font-family: $mainFont; + font-size: $mainFontSize; + font-weight: normal; + color: $mainColor; +} + +::selection { + color: $selectionColor; + background: $selectionBackgroundColor; + text-shadow: none; +} + +.reveal .slides>section, +.reveal .slides>section>section { + line-height: 1.3; + font-weight: inherit; +} + +/********************************************* + * HEADERS + *********************************************/ + +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: $headingMargin; + color: $headingColor; + + font-family: $headingFont; + font-weight: $headingFontWeight; + line-height: $headingLineHeight; + letter-spacing: $headingLetterSpacing; + + text-transform: $headingTextTransform; + text-shadow: $headingTextShadow; + + word-wrap: break-word; +} + +.reveal h1 {font-size: $heading1Size; } +.reveal h2 {font-size: $heading2Size; } +.reveal h3 {font-size: $heading3Size; } +.reveal h4 {font-size: $heading4Size; } + +.reveal h1 { + text-shadow: $heading1TextShadow; +} + + +/********************************************* + * OTHER + *********************************************/ + +.reveal p { + margin: $blockMargin 0; + line-height: 1.3; +} + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; +} +.reveal strong, +.reveal b { + font-weight: bold; +} + +.reveal em { + font-style: italic; +} + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + + text-align: left; + margin: 0 0 0 1em; +} + +.reveal ol { + list-style-type: decimal; +} + +.reveal ul { + list-style-type: disc; +} + +.reveal ul ul { + list-style-type: square; +} + +.reveal ul ul ul { + list-style-type: circle; +} + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; +} + +.reveal dt { + font-weight: bold; +} + +.reveal dd { + margin-left: 40px; +} + +.reveal q, +.reveal blockquote { + quotes: none; +} + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: $blockMargin auto; + padding: 5px; + + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0,0,0,0.2); +} + .reveal blockquote p:first-child, + .reveal blockquote p:last-child { + display: inline-block; + } + +.reveal q { + font-style: italic; +} + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: $blockMargin auto; + + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + + word-wrap: break-word; + + box-shadow: 0px 0px 6px rgba(0,0,0,0.3); +} +.reveal code { + font-family: monospace; +} + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; +} + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; +} + +.reveal table th { + font-weight: bold; +} + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; +} + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; +} + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; +} + +.reveal table tr:last-child td { + border-bottom: none; +} + +.reveal sup { + vertical-align: super; +} +.reveal sub { + vertical-align: sub; +} + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; +} + +.reveal small * { + vertical-align: top; +} + + +/********************************************* + * LINKS + *********************************************/ + +.reveal a { + color: $linkColor; + text-decoration: none; + + -webkit-transition: color .15s ease; + -moz-transition: color .15s ease; + transition: color .15s ease; +} + .reveal a:hover { + color: $linkColorHover; + + text-shadow: none; + border: none; + } + +.reveal .roll span:after { + color: #fff; + background: darken( $linkColor, 15% ); +} + + +/********************************************* + * IMAGES + *********************************************/ + +.reveal section img { + margin: 15px 0px; + background: rgba(255,255,255,0.12); + border: 4px solid $mainColor; + + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); +} + + .reveal section img.plain { + border: 0; + box-shadow: none; + } + + .reveal a img { + -webkit-transition: all .15s linear; + -moz-transition: all .15s linear; + transition: all .15s linear; + } + + .reveal a:hover img { + background: rgba(255,255,255,0.2); + border-color: $linkColor; + + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); + } + + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ + +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: $linkColor; +} + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: $linkColor; +} + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: $linkColor; +} + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: $linkColor; +} + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: $linkColorHover; +} + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: $linkColorHover; +} + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: $linkColorHover; +} + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: $linkColorHover; +} + + +/********************************************* + * PROGRESS BAR + *********************************************/ + +.reveal .progress { + background: rgba(0,0,0,0.2); +} + .reveal .progress span { + background: $linkColor; + + -webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); + } + + diff --git a/slides/web-scraping/css/theme/white.css b/slides/web-scraping/css/theme/white.css new file mode 100644 index 0000000..14e1703 --- /dev/null +++ b/slides/web-scraping/css/theme/white.css @@ -0,0 +1,286 @@ +/** + * White theme for reveal.js. This is the opposite of the 'black' theme. + * + * By Hakim El Hattab, http://hakim.se + */ +@import url(../../lib/font/source-sans-pro/source-sans-pro.css); +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #fff; } + +/********************************************* + * GLOBAL STYLES + *********************************************/ +body { + background: #fff; + background-color: #fff; } + +.reveal { + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-size: 38px; + font-weight: normal; + color: #222; } + +::selection { + color: #fff; + background: #98bdef; + text-shadow: none; } + +.reveal .slides > section, +.reveal .slides > section > section { + line-height: 1.3; + font-weight: inherit; } + +/********************************************* + * HEADERS + *********************************************/ +.reveal h1, +.reveal h2, +.reveal h3, +.reveal h4, +.reveal h5, +.reveal h6 { + margin: 0 0 20px 0; + color: #222; + font-family: "Source Sans Pro", Helvetica, sans-serif; + font-weight: 600; + line-height: 1.2; + letter-spacing: normal; + text-transform: uppercase; + text-shadow: none; + word-wrap: break-word; } + +.reveal h1 { + font-size: 2.5em; } + +.reveal h2 { + font-size: 1.6em; } + +.reveal h3 { + font-size: 1.3em; } + +.reveal h4 { + font-size: 1em; } + +.reveal h1 { + text-shadow: none; } + +/********************************************* + * OTHER + *********************************************/ +.reveal p { + margin: 20px 0; + line-height: 1.3; } + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; } + +.reveal strong, +.reveal b { + font-weight: bold; } + +.reveal em { + font-style: italic; } + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } + +.reveal ol { + list-style-type: decimal; } + +.reveal ul { + list-style-type: disc; } + +.reveal ul ul { + list-style-type: square; } + +.reveal ul ul ul { + list-style-type: circle; } + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; } + +.reveal dt { + font-weight: bold; } + +.reveal dd { + margin-left: 40px; } + +.reveal q, +.reveal blockquote { + quotes: none; } + +.reveal blockquote { + display: block; + position: relative; + width: 70%; + margin: 20px auto; + padding: 5px; + font-style: italic; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; } + +.reveal q { + font-style: italic; } + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: 20px auto; + text-align: left; + font-size: 0.55em; + font-family: monospace; + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } + +.reveal code { + font-family: monospace; } + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; } + +.reveal table { + margin: auto; + border-collapse: collapse; + border-spacing: 0; } + +.reveal table th { + font-weight: bold; } + +.reveal table th, +.reveal table td { + text-align: left; + padding: 0.2em 0.5em 0.2em 0.5em; + border-bottom: 1px solid; } + +.reveal table th[align="center"], +.reveal table td[align="center"] { + text-align: center; } + +.reveal table th[align="right"], +.reveal table td[align="right"] { + text-align: right; } + +.reveal table tr:last-child td { + border-bottom: none; } + +.reveal sup { + vertical-align: super; } + +.reveal sub { + vertical-align: sub; } + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; } + +.reveal small * { + vertical-align: top; } + +/********************************************* + * LINKS + *********************************************/ +.reveal a { + color: #2a76dd; + text-decoration: none; + -webkit-transition: color 0.15s ease; + -moz-transition: color 0.15s ease; + transition: color 0.15s ease; } + +.reveal a:hover { + color: #6ca0e8; + text-shadow: none; + border: none; } + +.reveal .roll span:after { + color: #fff; + background: #1a53a1; } + +/********************************************* + * IMAGES + *********************************************/ +.reveal section img { + margin: 15px 0px; + background: rgba(255, 255, 255, 0.12); + border: 4px solid #222; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal section img.plain { + border: 0; + box-shadow: none; } + +.reveal a img { + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + transition: all 0.15s linear; } + +.reveal a:hover img { + background: rgba(255, 255, 255, 0.2); + border-color: #2a76dd; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls .navigate-left, +.reveal .controls .navigate-left.enabled { + border-right-color: #2a76dd; } + +.reveal .controls .navigate-right, +.reveal .controls .navigate-right.enabled { + border-left-color: #2a76dd; } + +.reveal .controls .navigate-up, +.reveal .controls .navigate-up.enabled { + border-bottom-color: #2a76dd; } + +.reveal .controls .navigate-down, +.reveal .controls .navigate-down.enabled { + border-top-color: #2a76dd; } + +.reveal .controls .navigate-left.enabled:hover { + border-right-color: #6ca0e8; } + +.reveal .controls .navigate-right.enabled:hover { + border-left-color: #6ca0e8; } + +.reveal .controls .navigate-up.enabled:hover { + border-bottom-color: #6ca0e8; } + +.reveal .controls .navigate-down.enabled:hover { + border-top-color: #6ca0e8; } + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); } + +.reveal .progress span { + background: #2a76dd; + -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); + transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } diff --git a/slides/web-scraping/img/list.png b/slides/web-scraping/img/list.png new file mode 100644 index 0000000000000000000000000000000000000000..f5531f5a5dbad20cbebf0ac94123ffc6d7758dee GIT binary patch literal 116624 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 =YQioL2qu_%(UrY5*-RJyMwF)TG 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 KWzWp-mH!9v@3 + + + + + + web-scraping + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

Web Scraping Basics

+

+ Contributors
+ Snehil Verma @vsnehil92 + +

+
+ +
+

What is scraping?

+ +
+ +
+ +

Why Scraping?

+ +
+ + +
+

Use of Scraping

+

+

    +
  • Real Estate Listings gathering.
  • +
  • Product review scrapes.
  • +
  • Scraping to create other websites.
  • +
  • Getting massive amounts of data for research purposes.
  • +
+ +

+
+ +
+

Scraping and Python

+

+

    +
  • Requests.
  • +
  • Beautiful Soup 4.
  • +
  • lxml.
  • +
  • Selenium.
  • +
  • Scrapy.
  • +
+ +

+
+
+

Workflow of web scraping

+ +
+
+

BEAUTIFUL SOUP

+ +
+ +
+

Installing Beautiful Soup

+
    +
  • pip install beautifulsoup4
  • +
+
+ +
+

Writing basic script in Beautiful Soup

+ +
+ +
+

Scrapy

+ +

+ + $ pip install Scrapy + +

+ +
+ +
+

Terminal commands of Scrapy

+

+

    +
  • startproject.
  • +
  • genspider.
  • +
  • settings.
  • +
  • runspider.
  • +
  • shell.
  • +
  • fetch.
  • +
  • view.
  • +
  • version.
  • +
+ +

+
+
+

Writing basic scrapy spider

+
+
+

List of comanies that usses scraping

+ +
+ +
+

Thank You

+

Any Queries?

+
+
+ +
+ + + + + + + + diff --git a/slides/web-scraping/js/reveal.js b/slides/web-scraping/js/reveal.js new file mode 100644 index 0000000..2c92954 --- /dev/null +++ b/slides/web-scraping/js/reveal.js @@ -0,0 +1,4677 @@ +/*! + * reveal.js + * http://lab.hakim.se/reveal-js + * MIT licensed + * + * Copyright (C) 2016 Hakim El Hattab, http://hakim.se + */ +(function( root, factory ) { + if( typeof define === 'function' && define.amd ) { + // AMD. Register as an anonymous module. + define( function() { + root.Reveal = factory(); + return root.Reveal; + } ); + } else if( typeof exports === 'object' ) { + // Node. Does not work with strict CommonJS. + module.exports = factory(); + } else { + // Browser globals. + root.Reveal = factory(); + } +}( this, function() { + + 'use strict'; + + var Reveal; + + var SLIDES_SELECTOR = '.slides section', + HORIZONTAL_SLIDES_SELECTOR = '.slides>section', + VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section', + HOME_SLIDE_SELECTOR = '.slides>section:first-of-type', + + // Configuration defaults, can be overridden at initialization time + config = { + + // The "normal" size of the presentation, aspect ratio will be preserved + // when the presentation is scaled to fit different resolutions + width: 960, + height: 700, + + // Factor of the display size that should remain empty around the content + margin: 0.1, + + // Bounds for smallest/largest possible scale to apply to content + minScale: 0.2, + maxScale: 1.5, + + // Display controls in the bottom right corner + controls: true, + + // Display a presentation progress bar + progress: true, + + // Display the page number of the current slide + slideNumber: false, + + // Push each slide change to the browser history + history: false, + + // Enable keyboard shortcuts for navigation + keyboard: true, + + // Optional function that blocks keyboard events when retuning false + keyboardCondition: null, + + // Enable the slide overview mode + overview: true, + + // Vertical centering of slides + center: true, + + // Enables touch navigation on devices with touch input + touch: true, + + // Loop the presentation + loop: false, + + // Change the presentation direction to be RTL + rtl: false, + + // Turns fragments on and off globally + fragments: true, + + // Flags if the presentation is running in an embedded mode, + // i.e. contained within a limited portion of the screen + embedded: false, + + // Flags if we should show a help overlay when the questionmark + // key is pressed + help: true, + + // Flags if it should be possible to pause the presentation (blackout) + pause: true, + + // Flags if speaker notes should be visible to all viewers + showNotes: false, + + // Number of milliseconds between automatically proceeding to the + // next slide, disabled when set to 0, this value can be overwritten + // by using a data-autoslide attribute on your slides + autoSlide: 0, + + // Stop auto-sliding after user input + autoSlideStoppable: true, + + // Enable slide navigation via mouse wheel + mouseWheel: false, + + // Apply a 3D roll to links on hover + rollingLinks: false, + + // Hides the address bar on mobile devices + hideAddressBar: true, + + // Opens links in an iframe preview overlay + previewLinks: false, + + // Exposes the reveal.js API through window.postMessage + postMessage: true, + + // Dispatches all reveal.js events to the parent window through postMessage + postMessageEvents: false, + + // Focuses body when page changes visiblity to ensure keyboard shortcuts work + focusBodyOnPageVisibilityChange: true, + + // Transition style + transition: 'slide', // none/fade/slide/convex/concave/zoom + + // Transition speed + transitionSpeed: 'default', // default/fast/slow + + // Transition style for full page slide backgrounds + backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom + + // Parallax background image + parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg" + + // Parallax background size + parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px" + + // Amount of pixels to move the parallax background per slide step + parallaxBackgroundHorizontal: null, + parallaxBackgroundVertical: null, + + // Number of slides away from the current that are visible + viewDistance: 3, + + // Script dependencies to load + dependencies: [] + + }, + + // Flags if reveal.js is loaded (has dispatched the 'ready' event) + loaded = false, + + // Flags if the overview mode is currently active + overview = false, + + // The horizontal and vertical index of the currently active slide + indexh, + indexv, + + // The previous and current slide HTML elements + previousSlide, + currentSlide, + + previousBackground, + + // Slides may hold a data-state attribute which we pick up and apply + // as a class to the body. This list contains the combined state of + // all current slides. + state = [], + + // The current scale of the presentation (see width/height config) + scale = 1, + + // CSS transform that is currently applied to the slides container, + // split into two groups + slidesTransform = { layout: '', overview: '' }, + + // Cached references to DOM elements + dom = {}, + + // Features supported by the browser, see #checkCapabilities() + features = {}, + + // Client is a mobile device, see #checkCapabilities() + isMobileDevice, + + // Throttles mouse wheel navigation + lastMouseWheelStep = 0, + + // Delays updates to the URL due to a Chrome thumbnailer bug + writeURLTimeout = 0, + + // Flags if the interaction event listeners are bound + eventsAreBound = false, + + // The current auto-slide duration + autoSlide = 0, + + // Auto slide properties + autoSlidePlayer, + autoSlideTimeout = 0, + autoSlideStartTime = -1, + autoSlidePaused = false, + + // Holds information about the currently ongoing touch input + touch = { + startX: 0, + startY: 0, + startSpan: 0, + startCount: 0, + captured: false, + threshold: 40 + }, + + // Holds information about the keyboard shortcuts + keyboardShortcuts = { + 'N , SPACE': 'Next slide', + 'P': 'Previous slide', + '← , H': 'Navigate left', + '→ , L': 'Navigate right', + '↑ , K': 'Navigate up', + '↓ , J': 'Navigate down', + 'Home': 'First slide', + 'End': 'Last slide', + 'B , .': 'Pause', + 'F': 'Fullscreen', + 'ESC, O': 'Slide overview' + }; + + /** + * Starts up the presentation if the client is capable. + */ + function initialize( options ) { + + checkCapabilities(); + + if( !features.transforms2d && !features.transforms3d ) { + document.body.setAttribute( 'class', 'no-transforms' ); + + // Since JS won't be running any further, we load all lazy + // loading elements upfront + var images = toArray( document.getElementsByTagName( 'img' ) ), + iframes = toArray( document.getElementsByTagName( 'iframe' ) ); + + var lazyLoadable = images.concat( iframes ); + + for( var i = 0, len = lazyLoadable.length; i < len; i++ ) { + var element = lazyLoadable[i]; + if( element.getAttribute( 'data-src' ) ) { + element.setAttribute( 'src', element.getAttribute( 'data-src' ) ); + element.removeAttribute( 'data-src' ); + } + } + + // If the browser doesn't support core features we won't be + // using JavaScript to control the presentation + return; + } + + // Cache references to key DOM elements + dom.wrapper = document.querySelector( '.reveal' ); + dom.slides = document.querySelector( '.reveal .slides' ); + + // Force a layout when the whole page, incl fonts, has loaded + window.addEventListener( 'load', layout, false ); + + var query = Reveal.getQueryHash(); + + // Do not accept new dependencies via query config to avoid + // the potential of malicious script injection + if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies']; + + // Copy options over to our config object + extend( config, options ); + extend( config, query ); + + // Hide the address bar in mobile browsers + hideAddressBar(); + + // Loads the dependencies and continues to #start() once done + load(); + + } + + /** + * Inspect the client to see what it's capable of, this + * should only happens once per runtime. + */ + function checkCapabilities() { + + features.transforms3d = 'WebkitPerspective' in document.body.style || + 'MozPerspective' in document.body.style || + 'msPerspective' in document.body.style || + 'OPerspective' in document.body.style || + 'perspective' in document.body.style; + + features.transforms2d = 'WebkitTransform' in document.body.style || + 'MozTransform' in document.body.style || + 'msTransform' in document.body.style || + 'OTransform' in document.body.style || + 'transform' in document.body.style; + + features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; + features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function'; + + features.canvas = !!document.createElement( 'canvas' ).getContext; + + features.touch = !!( 'ontouchstart' in window ); + + // Transitions in the overview are disabled in desktop and + // mobile Safari due to lag + features.overviewTransitions = !/Version\/[\d\.]+.*Safari/.test( navigator.userAgent ); + + isMobileDevice = /(iphone|ipod|ipad|android)/gi.test( navigator.userAgent ); + + } + + /** + * Loads the dependencies of reveal.js. Dependencies are + * defined via the configuration option 'dependencies' + * and will be loaded prior to starting/binding reveal.js. + * Some dependencies may have an 'async' flag, if so they + * will load after reveal.js has been started up. + */ + function load() { + + var scripts = [], + scriptsAsync = [], + scriptsToPreload = 0; + + // Called once synchronous scripts finish loading + function proceed() { + if( scriptsAsync.length ) { + // Load asynchronous scripts + head.js.apply( null, scriptsAsync ); + } + + start(); + } + + function loadScript( s ) { + head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() { + // Extension may contain callback functions + if( typeof s.callback === 'function' ) { + s.callback.apply( this ); + } + + if( --scriptsToPreload === 0 ) { + proceed(); + } + }); + } + + for( var i = 0, len = config.dependencies.length; i < len; i++ ) { + var s = config.dependencies[i]; + + // Load if there's no condition or the condition is truthy + if( !s.condition || s.condition() ) { + if( s.async ) { + scriptsAsync.push( s.src ); + } + else { + scripts.push( s.src ); + } + + loadScript( s ); + } + } + + if( scripts.length ) { + scriptsToPreload = scripts.length; + + // Load synchronous scripts + head.js.apply( null, scripts ); + } + else { + proceed(); + } + + } + + /** + * Starts up reveal.js by binding input events and navigating + * to the current URL deeplink if there is one. + */ + function start() { + + // Make sure we've got all the DOM elements we need + setupDOM(); + + // Listen to messages posted to this window + setupPostMessage(); + + // Prevent iframes from scrolling the slides out of view + setupIframeScrollPrevention(); + + // Resets all vertical slides so that only the first is visible + resetVerticalSlides(); + + // Updates the presentation to match the current configuration values + configure(); + + // Read the initial hash + readURL(); + + // Update all backgrounds + updateBackground( true ); + + // Notify listeners that the presentation is ready but use a 1ms + // timeout to ensure it's not fired synchronously after #initialize() + setTimeout( function() { + // Enable transitions now that we're loaded + dom.slides.classList.remove( 'no-transition' ); + + loaded = true; + + dispatchEvent( 'ready', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + }, 1 ); + + // Special setup and config is required when printing to PDF + if( isPrintingPDF() ) { + removeEventListeners(); + + // The document needs to have loaded for the PDF layout + // measurements to be accurate + if( document.readyState === 'complete' ) { + setupPDF(); + } + else { + window.addEventListener( 'load', setupPDF ); + } + } + + } + + /** + * Finds and stores references to DOM elements which are + * required by the presentation. If a required element is + * not found, it is created. + */ + function setupDOM() { + + // Prevent transitions while we're loading + dom.slides.classList.add( 'no-transition' ); + + // Background element + dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null ); + + // Progress bar + dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '' ); + dom.progressbar = dom.progress.querySelector( 'span' ); + + // Arrow controls + createSingletonNode( dom.wrapper, 'aside', 'controls', + '' + + '' + + '' + + '' ); + + // Slide number + dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' ); + + // Element containing notes that are visible to the audience + dom.speakerNotes = createSingletonNode( dom.wrapper, 'div', 'speaker-notes', null ); + dom.speakerNotes.setAttribute( 'data-prevent-swipe', '' ); + + // Overlay graphic which is displayed during the paused mode + createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null ); + + // Cache references to elements + dom.controls = document.querySelector( '.reveal .controls' ); + dom.theme = document.querySelector( '#theme' ); + + dom.wrapper.setAttribute( 'role', 'application' ); + + // There can be multiple instances of controls throughout the page + dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) ); + dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) ); + dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) ); + dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) ); + dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) ); + dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) ); + + dom.statusDiv = createStatusDiv(); + } + + /** + * Creates a hidden div with role aria-live to announce the + * current slide content. Hide the div off-screen to make it + * available only to Assistive Technologies. + */ + function createStatusDiv() { + + var statusDiv = document.getElementById( 'aria-status-div' ); + if( !statusDiv ) { + statusDiv = document.createElement( 'div' ); + statusDiv.style.position = 'absolute'; + statusDiv.style.height = '1px'; + statusDiv.style.width = '1px'; + statusDiv.style.overflow ='hidden'; + statusDiv.style.clip = 'rect( 1px, 1px, 1px, 1px )'; + statusDiv.setAttribute( 'id', 'aria-status-div' ); + statusDiv.setAttribute( 'aria-live', 'polite' ); + statusDiv.setAttribute( 'aria-atomic','true' ); + dom.wrapper.appendChild( statusDiv ); + } + return statusDiv; + + } + + /** + * Configures the presentation for printing to a static + * PDF. + */ + function setupPDF() { + + var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight ); + + // Dimensions of the PDF pages + var pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ), + pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) ); + + // Dimensions of slides within the pages + var slideWidth = slideSize.width, + slideHeight = slideSize.height; + + // Let the browser know what page size we want to print + injectStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0;}' ); + + // Limit the size of certain elements to the dimensions of the slide + injectStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' ); + + document.body.classList.add( 'print-pdf' ); + document.body.style.width = pageWidth + 'px'; + document.body.style.height = pageHeight + 'px'; + + // Add each slide's index as attributes on itself, we need these + // indices to generate slide numbers below + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( hslide, h ) { + hslide.setAttribute( 'data-index-h', h ); + + if( hslide.classList.contains( 'stack' ) ) { + toArray( hslide.querySelectorAll( 'section' ) ).forEach( function( vslide, v ) { + vslide.setAttribute( 'data-index-h', h ); + vslide.setAttribute( 'data-index-v', v ); + } ); + } + } ); + + // Slide and slide background layout + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) === false ) { + // Center the slide inside of the page, giving the slide some margin + var left = ( pageWidth - slideWidth ) / 2, + top = ( pageHeight - slideHeight ) / 2; + + var contentHeight = getAbsoluteHeight( slide ); + var numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 ); + + // Center slides vertically + if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) { + top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); + } + + // Position the slide inside of the page + slide.style.left = left + 'px'; + slide.style.top = top + 'px'; + slide.style.width = slideWidth + 'px'; + + // TODO Backgrounds need to be multiplied when the slide + // stretches over multiple pages + var background = slide.querySelector( '.slide-background' ); + if( background ) { + background.style.width = pageWidth + 'px'; + background.style.height = ( pageHeight * numberOfPages ) + 'px'; + background.style.top = -top + 'px'; + background.style.left = -left + 'px'; + } + + // Inject notes if `showNotes` is enabled + if( config.showNotes ) { + var notes = getSlideNotes( slide ); + if( notes ) { + var notesSpacing = 8; + var notesElement = document.createElement( 'div' ); + notesElement.classList.add( 'speaker-notes' ); + notesElement.classList.add( 'speaker-notes-pdf' ); + notesElement.innerHTML = notes; + notesElement.style.left = ( notesSpacing - left ) + 'px'; + notesElement.style.bottom = ( notesSpacing - top ) + 'px'; + notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px'; + slide.appendChild( notesElement ); + } + } + + // Inject slide numbers if `slideNumbers` are enabled + if( config.slideNumber ) { + var slideNumberH = parseInt( slide.getAttribute( 'data-index-h' ), 10 ) + 1, + slideNumberV = parseInt( slide.getAttribute( 'data-index-v' ), 10 ) + 1; + + var numberElement = document.createElement( 'div' ); + numberElement.classList.add( 'slide-number' ); + numberElement.classList.add( 'slide-number-pdf' ); + numberElement.innerHTML = formatSlideNumber( slideNumberH, '.', slideNumberV ); + background.appendChild( numberElement ); + } + } + + } ); + + // Show all fragments + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' .fragment' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + } ); + + } + + /** + * This is an unfortunate necessity. Iframes can trigger the + * parent window to scroll, for example by focusing an input. + * This scrolling can not be prevented by hiding overflow in + * CSS so we have to resort to repeatedly checking if the + * browser has decided to offset our slides :( + */ + function setupIframeScrollPrevention() { + + if( dom.slides.querySelector( 'iframe' ) ) { + setInterval( function() { + if( dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) { + dom.wrapper.scrollTop = 0; + dom.wrapper.scrollLeft = 0; + } + }, 500 ); + } + + } + + /** + * Creates an HTML element and returns a reference to it. + * If the element already exists the existing instance will + * be returned. + */ + function createSingletonNode( container, tagname, classname, innerHTML ) { + + // Find all nodes matching the description + var nodes = container.querySelectorAll( '.' + classname ); + + // Check all matches to find one which is a direct child of + // the specified container + for( var i = 0; i < nodes.length; i++ ) { + var testNode = nodes[i]; + if( testNode.parentNode === container ) { + return testNode; + } + } + + // If no node was found, create it now + var node = document.createElement( tagname ); + node.classList.add( classname ); + if( typeof innerHTML === 'string' ) { + node.innerHTML = innerHTML; + } + container.appendChild( node ); + + return node; + + } + + /** + * Creates the slide background elements and appends them + * to the background container. One element is created per + * slide no matter if the given slide has visible background. + */ + function createBackgrounds() { + + var printMode = isPrintingPDF(); + + // Clear prior backgrounds + dom.background.innerHTML = ''; + dom.background.classList.add( 'no-transition' ); + + // Iterate over all horizontal slides + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) { + + var backgroundStack; + + if( printMode ) { + backgroundStack = createBackground( slideh, slideh ); + } + else { + backgroundStack = createBackground( slideh, dom.background ); + } + + // Iterate over all vertical slides + toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) { + + if( printMode ) { + createBackground( slidev, slidev ); + } + else { + createBackground( slidev, backgroundStack ); + } + + backgroundStack.classList.add( 'stack' ); + + } ); + + } ); + + // Add parallax background if specified + if( config.parallaxBackgroundImage ) { + + dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")'; + dom.background.style.backgroundSize = config.parallaxBackgroundSize; + + // Make sure the below properties are set on the element - these properties are + // needed for proper transitions to be set on the element via CSS. To remove + // annoying background slide-in effect when the presentation starts, apply + // these properties after short time delay + setTimeout( function() { + dom.wrapper.classList.add( 'has-parallax-background' ); + }, 1 ); + + } + else { + + dom.background.style.backgroundImage = ''; + dom.wrapper.classList.remove( 'has-parallax-background' ); + + } + + } + + /** + * Creates a background for the given slide. + * + * @param {HTMLElement} slide + * @param {HTMLElement} container The element that the background + * should be appended to + */ + function createBackground( slide, container ) { + + var data = { + background: slide.getAttribute( 'data-background' ), + backgroundSize: slide.getAttribute( 'data-background-size' ), + backgroundImage: slide.getAttribute( 'data-background-image' ), + backgroundVideo: slide.getAttribute( 'data-background-video' ), + backgroundIframe: slide.getAttribute( 'data-background-iframe' ), + backgroundColor: slide.getAttribute( 'data-background-color' ), + backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), + backgroundPosition: slide.getAttribute( 'data-background-position' ), + backgroundTransition: slide.getAttribute( 'data-background-transition' ) + }; + + var element = document.createElement( 'div' ); + + // Carry over custom classes from the slide to the background + element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); + + if( data.background ) { + // Auto-wrap image urls in url(...) + if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) { + slide.setAttribute( 'data-background-image', data.background ); + } + else { + element.style.background = data.background; + } + } + + // Create a hash for this combination of background settings. + // This is used to determine when two slide backgrounds are + // the same. + if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) { + element.setAttribute( 'data-background-hash', data.background + + data.backgroundSize + + data.backgroundImage + + data.backgroundVideo + + data.backgroundIframe + + data.backgroundColor + + data.backgroundRepeat + + data.backgroundPosition + + data.backgroundTransition ); + } + + // Additional and optional background properties + if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize; + if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; + if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat; + if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition; + if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); + + container.appendChild( element ); + + // If backgrounds are being recreated, clear old classes + slide.classList.remove( 'has-dark-background' ); + slide.classList.remove( 'has-light-background' ); + + // If this slide has a background color, add a class that + // signals if it is light or dark. If the slide has no background + // color, no class will be set + var computedBackgroundColor = window.getComputedStyle( element ).backgroundColor; + if( computedBackgroundColor ) { + var rgb = colorToRgb( computedBackgroundColor ); + + // Ignore fully transparent backgrounds. Some browsers return + // rgba(0,0,0,0) when reading the computed background color of + // an element with no background + if( rgb && rgb.a !== 0 ) { + if( colorBrightness( computedBackgroundColor ) < 128 ) { + slide.classList.add( 'has-dark-background' ); + } + else { + slide.classList.add( 'has-light-background' ); + } + } + } + + return element; + + } + + /** + * Registers a listener to postMessage events, this makes it + * possible to call all reveal.js API methods from another + * window. For example: + * + * revealWindow.postMessage( JSON.stringify({ + * method: 'slide', + * args: [ 2 ] + * }), '*' ); + */ + function setupPostMessage() { + + if( config.postMessage ) { + window.addEventListener( 'message', function ( event ) { + var data = event.data; + + // Make sure we're dealing with JSON + if( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) { + data = JSON.parse( data ); + + // Check if the requested method can be found + if( data.method && typeof Reveal[data.method] === 'function' ) { + Reveal[data.method].apply( Reveal, data.args ); + } + } + }, false ); + } + + } + + /** + * Applies the configuration settings from the config + * object. May be called multiple times. + */ + function configure( options ) { + + var numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length; + + dom.wrapper.classList.remove( config.transition ); + + // New config options may be passed when this method + // is invoked through the API after initialization + if( typeof options === 'object' ) extend( config, options ); + + // Force linear transition based on browser capabilities + if( features.transforms3d === false ) config.transition = 'linear'; + + dom.wrapper.classList.add( config.transition ); + + dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed ); + dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition ); + + dom.controls.style.display = config.controls ? 'block' : 'none'; + dom.progress.style.display = config.progress ? 'block' : 'none'; + dom.slideNumber.style.display = config.slideNumber && !isPrintingPDF() ? 'block' : 'none'; + + if( config.rtl ) { + dom.wrapper.classList.add( 'rtl' ); + } + else { + dom.wrapper.classList.remove( 'rtl' ); + } + + if( config.center ) { + dom.wrapper.classList.add( 'center' ); + } + else { + dom.wrapper.classList.remove( 'center' ); + } + + // Exit the paused mode if it was configured off + if( config.pause === false ) { + resume(); + } + + if( config.showNotes ) { + dom.speakerNotes.classList.add( 'visible' ); + } + else { + dom.speakerNotes.classList.remove( 'visible' ); + } + + if( config.mouseWheel ) { + document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF + document.addEventListener( 'mousewheel', onDocumentMouseScroll, false ); + } + else { + document.removeEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF + document.removeEventListener( 'mousewheel', onDocumentMouseScroll, false ); + } + + // Rolling 3D links + if( config.rollingLinks ) { + enableRollingLinks(); + } + else { + disableRollingLinks(); + } + + // Iframe link previews + if( config.previewLinks ) { + enablePreviewLinks(); + } + else { + disablePreviewLinks(); + enablePreviewLinks( '[data-preview-link]' ); + } + + // Remove existing auto-slide controls + if( autoSlidePlayer ) { + autoSlidePlayer.destroy(); + autoSlidePlayer = null; + } + + // Generate auto-slide controls if needed + if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) { + autoSlidePlayer = new Playback( dom.wrapper, function() { + return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 ); + } ); + + autoSlidePlayer.on( 'click', onAutoSlidePlayerClick ); + autoSlidePaused = false; + } + + // When fragments are turned off they should be visible + if( config.fragments === false ) { + toArray( dom.slides.querySelectorAll( '.fragment' ) ).forEach( function( element ) { + element.classList.add( 'visible' ); + element.classList.remove( 'current-fragment' ); + } ); + } + + sync(); + + } + + /** + * Binds all event listeners. + */ + function addEventListeners() { + + eventsAreBound = true; + + window.addEventListener( 'hashchange', onWindowHashChange, false ); + window.addEventListener( 'resize', onWindowResize, false ); + + if( config.touch ) { + dom.wrapper.addEventListener( 'touchstart', onTouchStart, false ); + dom.wrapper.addEventListener( 'touchmove', onTouchMove, false ); + dom.wrapper.addEventListener( 'touchend', onTouchEnd, false ); + + // Support pointer-style touch interaction as well + if( window.navigator.pointerEnabled ) { + // IE 11 uses un-prefixed version of pointer events + dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false ); + dom.wrapper.addEventListener( 'pointermove', onPointerMove, false ); + dom.wrapper.addEventListener( 'pointerup', onPointerUp, false ); + } + else if( window.navigator.msPointerEnabled ) { + // IE 10 uses prefixed version of pointer events + dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false ); + dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false ); + dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false ); + } + } + + if( config.keyboard ) { + document.addEventListener( 'keydown', onDocumentKeyDown, false ); + document.addEventListener( 'keypress', onDocumentKeyPress, false ); + } + + if( config.progress && dom.progress ) { + dom.progress.addEventListener( 'click', onProgressClicked, false ); + } + + if( config.focusBodyOnPageVisibilityChange ) { + var visibilityChange; + + if( 'hidden' in document ) { + visibilityChange = 'visibilitychange'; + } + else if( 'msHidden' in document ) { + visibilityChange = 'msvisibilitychange'; + } + else if( 'webkitHidden' in document ) { + visibilityChange = 'webkitvisibilitychange'; + } + + if( visibilityChange ) { + document.addEventListener( visibilityChange, onPageVisibilityChange, false ); + } + } + + // Listen to both touch and click events, in case the device + // supports both + var pointerEvents = [ 'touchstart', 'click' ]; + + // Only support touch for Android, fixes double navigations in + // stock browser + if( navigator.userAgent.match( /android/gi ) ) { + pointerEvents = [ 'touchstart' ]; + } + + pointerEvents.forEach( function( eventName ) { + dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } ); + dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } ); + dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } ); + dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } ); + dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } ); + dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } ); + } ); + + } + + /** + * Unbinds all event listeners. + */ + function removeEventListeners() { + + eventsAreBound = false; + + document.removeEventListener( 'keydown', onDocumentKeyDown, false ); + document.removeEventListener( 'keypress', onDocumentKeyPress, false ); + window.removeEventListener( 'hashchange', onWindowHashChange, false ); + window.removeEventListener( 'resize', onWindowResize, false ); + + dom.wrapper.removeEventListener( 'touchstart', onTouchStart, false ); + dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false ); + dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false ); + + // IE11 + if( window.navigator.pointerEnabled ) { + dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false ); + } + // IE10 + else if( window.navigator.msPointerEnabled ) { + dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false ); + dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false ); + dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false ); + } + + if ( config.progress && dom.progress ) { + dom.progress.removeEventListener( 'click', onProgressClicked, false ); + } + + [ 'touchstart', 'click' ].forEach( function( eventName ) { + dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } ); + dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } ); + dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } ); + dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } ); + dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } ); + dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } ); + } ); + + } + + /** + * Extend object a with the properties of object b. + * If there's a conflict, object b takes precedence. + */ + function extend( a, b ) { + + for( var i in b ) { + a[ i ] = b[ i ]; + } + + } + + /** + * Converts the target object to an array. + */ + function toArray( o ) { + + return Array.prototype.slice.call( o ); + + } + + /** + * Utility for deserializing a value. + */ + function deserialize( value ) { + + if( typeof value === 'string' ) { + if( value === 'null' ) return null; + else if( value === 'true' ) return true; + else if( value === 'false' ) return false; + else if( value.match( /^\d+$/ ) ) return parseFloat( value ); + } + + return value; + + } + + /** + * Measures the distance in pixels between point a + * and point b. + * + * @param {Object} a point with x/y properties + * @param {Object} b point with x/y properties + */ + function distanceBetween( a, b ) { + + var dx = a.x - b.x, + dy = a.y - b.y; + + return Math.sqrt( dx*dx + dy*dy ); + + } + + /** + * Applies a CSS transform to the target element. + */ + function transformElement( element, transform ) { + + element.style.WebkitTransform = transform; + element.style.MozTransform = transform; + element.style.msTransform = transform; + element.style.transform = transform; + + } + + /** + * Applies CSS transforms to the slides container. The container + * is transformed from two separate sources: layout and the overview + * mode. + */ + function transformSlides( transforms ) { + + // Pick up new transforms from arguments + if( typeof transforms.layout === 'string' ) slidesTransform.layout = transforms.layout; + if( typeof transforms.overview === 'string' ) slidesTransform.overview = transforms.overview; + + // Apply the transforms to the slides container + if( slidesTransform.layout ) { + transformElement( dom.slides, slidesTransform.layout + ' ' + slidesTransform.overview ); + } + else { + transformElement( dom.slides, slidesTransform.overview ); + } + + } + + /** + * Injects the given CSS styles into the DOM. + */ + function injectStyleSheet( value ) { + + var tag = document.createElement( 'style' ); + tag.type = 'text/css'; + if( tag.styleSheet ) { + tag.styleSheet.cssText = value; + } + else { + tag.appendChild( document.createTextNode( value ) ); + } + document.getElementsByTagName( 'head' )[0].appendChild( tag ); + + } + + /** + * Converts various color input formats to an {r:0,g:0,b:0} object. + * + * @param {String} color The string representation of a color, + * the following formats are supported: + * - #000 + * - #000000 + * - rgb(0,0,0) + */ + function colorToRgb( color ) { + + var hex3 = color.match( /^#([0-9a-f]{3})$/i ); + if( hex3 && hex3[1] ) { + hex3 = hex3[1]; + return { + r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11, + g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11, + b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11 + }; + } + + var hex6 = color.match( /^#([0-9a-f]{6})$/i ); + if( hex6 && hex6[1] ) { + hex6 = hex6[1]; + return { + r: parseInt( hex6.substr( 0, 2 ), 16 ), + g: parseInt( hex6.substr( 2, 2 ), 16 ), + b: parseInt( hex6.substr( 4, 2 ), 16 ) + }; + } + + var rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i ); + if( rgb ) { + return { + r: parseInt( rgb[1], 10 ), + g: parseInt( rgb[2], 10 ), + b: parseInt( rgb[3], 10 ) + }; + } + + var rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i ); + if( rgba ) { + return { + r: parseInt( rgba[1], 10 ), + g: parseInt( rgba[2], 10 ), + b: parseInt( rgba[3], 10 ), + a: parseFloat( rgba[4] ) + }; + } + + return null; + + } + + /** + * Calculates brightness on a scale of 0-255. + * + * @param color See colorStringToRgb for supported formats. + */ + function colorBrightness( color ) { + + if( typeof color === 'string' ) color = colorToRgb( color ); + + if( color ) { + return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000; + } + + return null; + + } + + /** + * Retrieves the height of the given element by looking + * at the position and height of its immediate children. + */ + function getAbsoluteHeight( element ) { + + var height = 0; + + if( element ) { + var absoluteChildren = 0; + + toArray( element.childNodes ).forEach( function( child ) { + + if( typeof child.offsetTop === 'number' && child.style ) { + // Count # of abs children + if( window.getComputedStyle( child ).position === 'absolute' ) { + absoluteChildren += 1; + } + + height = Math.max( height, child.offsetTop + child.offsetHeight ); + } + + } ); + + // If there are no absolute children, use offsetHeight + if( absoluteChildren === 0 ) { + height = element.offsetHeight; + } + + } + + return height; + + } + + /** + * Returns the remaining height within the parent of the + * target element. + * + * remaining height = [ configured parent height ] - [ current parent height ] + */ + function getRemainingHeight( element, height ) { + + height = height || 0; + + if( element ) { + var newHeight, oldHeight = element.style.height; + + // Change the .stretch element height to 0 in order find the height of all + // the other elements + element.style.height = '0px'; + newHeight = height - element.parentNode.offsetHeight; + + // Restore the old height, just in case + element.style.height = oldHeight + 'px'; + + return newHeight; + } + + return height; + + } + + /** + * Checks if this instance is being used to print a PDF. + */ + function isPrintingPDF() { + + return ( /print-pdf/gi ).test( window.location.search ); + + } + + /** + * Hides the address bar if we're on a mobile device. + */ + function hideAddressBar() { + + if( config.hideAddressBar && isMobileDevice ) { + // Events that should trigger the address bar to hide + window.addEventListener( 'load', removeAddressBar, false ); + window.addEventListener( 'orientationchange', removeAddressBar, false ); + } + + } + + /** + * Causes the address bar to hide on mobile devices, + * more vertical space ftw. + */ + function removeAddressBar() { + + setTimeout( function() { + window.scrollTo( 0, 1 ); + }, 10 ); + + } + + /** + * Dispatches an event of the specified type from the + * reveal DOM element. + */ + function dispatchEvent( type, args ) { + + var event = document.createEvent( 'HTMLEvents', 1, 2 ); + event.initEvent( type, true, true ); + extend( event, args ); + dom.wrapper.dispatchEvent( event ); + + // If we're in an iframe, post each reveal.js event to the + // parent window. Used by the notes plugin + if( config.postMessageEvents && window.parent !== window.self ) { + window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: getState() }), '*' ); + } + + } + + /** + * Wrap all links in 3D goodness. + */ + function enableRollingLinks() { + + if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) { + var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a' ); + + for( var i = 0, len = anchors.length; i < len; i++ ) { + var anchor = anchors[i]; + + if( anchor.textContent && !anchor.querySelector( '*' ) && ( !anchor.className || !anchor.classList.contains( anchor, 'roll' ) ) ) { + var span = document.createElement('span'); + span.setAttribute('data-title', anchor.text); + span.innerHTML = anchor.innerHTML; + + anchor.classList.add( 'roll' ); + anchor.innerHTML = ''; + anchor.appendChild(span); + } + } + } + + } + + /** + * Unwrap all 3D links. + */ + function disableRollingLinks() { + + var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a.roll' ); + + for( var i = 0, len = anchors.length; i < len; i++ ) { + var anchor = anchors[i]; + var span = anchor.querySelector( 'span' ); + + if( span ) { + anchor.classList.remove( 'roll' ); + anchor.innerHTML = span.innerHTML; + } + } + + } + + /** + * Bind preview frame links. + */ + function enablePreviewLinks( selector ) { + + var anchors = toArray( document.querySelectorAll( selector ? selector : 'a' ) ); + + anchors.forEach( function( element ) { + if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) { + element.addEventListener( 'click', onPreviewLinkClicked, false ); + } + } ); + + } + + /** + * Unbind preview frame links. + */ + function disablePreviewLinks() { + + var anchors = toArray( document.querySelectorAll( 'a' ) ); + + anchors.forEach( function( element ) { + if( /^(http|www)/gi.test( element.getAttribute( 'href' ) ) ) { + element.removeEventListener( 'click', onPreviewLinkClicked, false ); + } + } ); + + } + + /** + * Opens a preview window for the target URL. + */ + function showPreview( url ) { + + closeOverlay(); + + dom.overlay = document.createElement( 'div' ); + dom.overlay.classList.add( 'overlay' ); + dom.overlay.classList.add( 'overlay-preview' ); + dom.wrapper.appendChild( dom.overlay ); + + dom.overlay.innerHTML = [ + '
', + '', + '', + '
', + '
', + '
', + '', + '
' + ].join(''); + + dom.overlay.querySelector( 'iframe' ).addEventListener( 'load', function( event ) { + dom.overlay.classList.add( 'loaded' ); + }, false ); + + dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) { + closeOverlay(); + event.preventDefault(); + }, false ); + + dom.overlay.querySelector( '.external' ).addEventListener( 'click', function( event ) { + closeOverlay(); + }, false ); + + setTimeout( function() { + dom.overlay.classList.add( 'visible' ); + }, 1 ); + + } + + /** + * Opens a overlay window with help material. + */ + function showHelp() { + + if( config.help ) { + + closeOverlay(); + + dom.overlay = document.createElement( 'div' ); + dom.overlay.classList.add( 'overlay' ); + dom.overlay.classList.add( 'overlay-help' ); + dom.wrapper.appendChild( dom.overlay ); + + var html = '

Keyboard Shortcuts


'; + + html += ''; + for( var key in keyboardShortcuts ) { + html += ''; + } + + html += '
KEYACTION
' + key + '' + keyboardShortcuts[ key ] + '
'; + + dom.overlay.innerHTML = [ + '
', + '', + '
', + '
', + '
'+ html +'
', + '
' + ].join(''); + + dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) { + closeOverlay(); + event.preventDefault(); + }, false ); + + setTimeout( function() { + dom.overlay.classList.add( 'visible' ); + }, 1 ); + + } + + } + + /** + * Closes any currently open overlay. + */ + function closeOverlay() { + + if( dom.overlay ) { + dom.overlay.parentNode.removeChild( dom.overlay ); + dom.overlay = null; + } + + } + + /** + * Applies JavaScript-controlled layout rules to the + * presentation. + */ + function layout() { + + if( dom.wrapper && !isPrintingPDF() ) { + + var size = getComputedSlideSize(); + + var slidePadding = 20; // TODO Dig this out of DOM + + // Layout the contents of the slides + layoutSlideContents( config.width, config.height, slidePadding ); + + dom.slides.style.width = size.width + 'px'; + dom.slides.style.height = size.height + 'px'; + + // Determine scale of content to fit within available space + scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); + + // Respect max/min scale settings + scale = Math.max( scale, config.minScale ); + scale = Math.min( scale, config.maxScale ); + + // Don't apply any scaling styles if scale is 1 + if( scale === 1 ) { + dom.slides.style.zoom = ''; + dom.slides.style.left = ''; + dom.slides.style.top = ''; + dom.slides.style.bottom = ''; + dom.slides.style.right = ''; + transformSlides( { layout: '' } ); + } + else { + // Use zoom to scale up in desktop Chrome so that content + // remains crisp. We don't use zoom to scale down since that + // can lead to shifts in text layout/line breaks. + if( scale > 1 && !isMobileDevice && /chrome/i.test( navigator.userAgent ) && typeof dom.slides.style.zoom !== 'undefined' ) { + dom.slides.style.zoom = scale; + dom.slides.style.left = ''; + dom.slides.style.top = ''; + dom.slides.style.bottom = ''; + dom.slides.style.right = ''; + transformSlides( { layout: '' } ); + } + // Apply scale transform as a fallback + else { + dom.slides.style.zoom = ''; + dom.slides.style.left = '50%'; + dom.slides.style.top = '50%'; + dom.slides.style.bottom = 'auto'; + dom.slides.style.right = 'auto'; + transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } ); + } + } + + // Select all slides, vertical and horizontal + var slides = toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ); + + for( var i = 0, len = slides.length; i < len; i++ ) { + var slide = slides[ i ]; + + // Don't bother updating invisible slides + if( slide.style.display === 'none' ) { + continue; + } + + if( config.center || slide.classList.contains( 'center' ) ) { + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) ) { + slide.style.top = 0; + } + else { + slide.style.top = Math.max( ( ( size.height - getAbsoluteHeight( slide ) ) / 2 ) - slidePadding, 0 ) + 'px'; + } + } + else { + slide.style.top = ''; + } + + } + + updateProgress(); + updateParallax(); + + } + + } + + /** + * Applies layout logic to the contents of all slides in + * the presentation. + */ + function layoutSlideContents( width, height, padding ) { + + // Handle sizing of elements with the 'stretch' class + toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) { + + // Determine how much vertical space we can use + var remainingHeight = getRemainingHeight( element, height ); + + // Consider the aspect ratio of media elements + if( /(img|video)/gi.test( element.nodeName ) ) { + var nw = element.naturalWidth || element.videoWidth, + nh = element.naturalHeight || element.videoHeight; + + var es = Math.min( width / nw, remainingHeight / nh ); + + element.style.width = ( nw * es ) + 'px'; + element.style.height = ( nh * es ) + 'px'; + + } + else { + element.style.width = width + 'px'; + element.style.height = remainingHeight + 'px'; + } + + } ); + + } + + /** + * Calculates the computed pixel size of our slides. These + * values are based on the width and height configuration + * options. + */ + function getComputedSlideSize( presentationWidth, presentationHeight ) { + + var size = { + // Slide size + width: config.width, + height: config.height, + + // Presentation size + presentationWidth: presentationWidth || dom.wrapper.offsetWidth, + presentationHeight: presentationHeight || dom.wrapper.offsetHeight + }; + + // Reduce available space by margin + size.presentationWidth -= ( size.presentationWidth * config.margin ); + size.presentationHeight -= ( size.presentationHeight * config.margin ); + + // Slide width may be a percentage of available width + if( typeof size.width === 'string' && /%$/.test( size.width ) ) { + size.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth; + } + + // Slide height may be a percentage of available height + if( typeof size.height === 'string' && /%$/.test( size.height ) ) { + size.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight; + } + + return size; + + } + + /** + * Stores the vertical index of a stack so that the same + * vertical slide can be selected when navigating to and + * from the stack. + * + * @param {HTMLElement} stack The vertical stack element + * @param {int} v Index to memorize + */ + function setPreviousVerticalIndex( stack, v ) { + + if( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) { + stack.setAttribute( 'data-previous-indexv', v || 0 ); + } + + } + + /** + * Retrieves the vertical index which was stored using + * #setPreviousVerticalIndex() or 0 if no previous index + * exists. + * + * @param {HTMLElement} stack The vertical stack element + */ + function getPreviousVerticalIndex( stack ) { + + if( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) { + // Prefer manually defined start-indexv + var attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv'; + + return parseInt( stack.getAttribute( attributeName ) || 0, 10 ); + } + + return 0; + + } + + /** + * Displays the overview of slides (quick nav) by scaling + * down and arranging all slide elements. + */ + function activateOverview() { + + // Only proceed if enabled in config + if( config.overview && !isOverview() ) { + + overview = true; + + dom.wrapper.classList.add( 'overview' ); + dom.wrapper.classList.remove( 'overview-deactivating' ); + + if( features.overviewTransitions ) { + setTimeout( function() { + dom.wrapper.classList.add( 'overview-animated' ); + }, 1 ); + } + + // Don't auto-slide while in overview mode + cancelAutoSlide(); + + // Move the backgrounds element into the slide container to + // that the same scaling is applied + dom.slides.appendChild( dom.background ); + + // Clicking on an overview slide navigates to it + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + if( !slide.classList.contains( 'stack' ) ) { + slide.addEventListener( 'click', onOverviewSlideClicked, true ); + } + } ); + + updateSlidesVisibility(); + layoutOverview(); + updateOverview(); + + layout(); + + // Notify observers of the overview showing + dispatchEvent( 'overviewshown', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + + } + + } + + /** + * Uses CSS transforms to position all slides in a grid for + * display inside of the overview mode. + */ + function layoutOverview() { + + var margin = 70; + var slideWidth = config.width + margin, + slideHeight = config.height + margin; + + // Reverse in RTL mode + if( config.rtl ) { + slideWidth = -slideWidth; + } + + // Layout slides + toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( hslide, h ) { + hslide.setAttribute( 'data-index-h', h ); + transformElement( hslide, 'translate3d(' + ( h * slideWidth ) + 'px, 0, 0)' ); + + if( hslide.classList.contains( 'stack' ) ) { + + toArray( hslide.querySelectorAll( 'section' ) ).forEach( function( vslide, v ) { + vslide.setAttribute( 'data-index-h', h ); + vslide.setAttribute( 'data-index-v', v ); + + transformElement( vslide, 'translate3d(0, ' + ( v * slideHeight ) + 'px, 0)' ); + } ); + + } + } ); + + // Layout slide backgrounds + toArray( dom.background.childNodes ).forEach( function( hbackground, h ) { + transformElement( hbackground, 'translate3d(' + ( h * slideWidth ) + 'px, 0, 0)' ); + + toArray( hbackground.querySelectorAll( '.slide-background' ) ).forEach( function( vbackground, v ) { + transformElement( vbackground, 'translate3d(0, ' + ( v * slideHeight ) + 'px, 0)' ); + } ); + } ); + + } + + /** + * Moves the overview viewport to the current slides. + * Called each time the current slide changes. + */ + function updateOverview() { + + var margin = 70; + var slideWidth = config.width + margin, + slideHeight = config.height + margin; + + // Reverse in RTL mode + if( config.rtl ) { + slideWidth = -slideWidth; + } + + transformSlides( { + overview: [ + 'translateX('+ ( -indexh * slideWidth ) +'px)', + 'translateY('+ ( -indexv * slideHeight ) +'px)', + 'translateZ('+ ( window.innerWidth < 400 ? -1000 : -2500 ) +'px)' + ].join( ' ' ) + } ); + + } + + /** + * Exits the slide overview and enters the currently + * active slide. + */ + function deactivateOverview() { + + // Only proceed if enabled in config + if( config.overview ) { + + overview = false; + + dom.wrapper.classList.remove( 'overview' ); + dom.wrapper.classList.remove( 'overview-animated' ); + + // Temporarily add a class so that transitions can do different things + // depending on whether they are exiting/entering overview, or just + // moving from slide to slide + dom.wrapper.classList.add( 'overview-deactivating' ); + + setTimeout( function () { + dom.wrapper.classList.remove( 'overview-deactivating' ); + }, 1 ); + + // Move the background element back out + dom.wrapper.appendChild( dom.background ); + + // Clean up changes made to slides + toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + transformElement( slide, '' ); + + slide.removeEventListener( 'click', onOverviewSlideClicked, true ); + } ); + + // Clean up changes made to backgrounds + toArray( dom.background.querySelectorAll( '.slide-background' ) ).forEach( function( background ) { + transformElement( background, '' ); + } ); + + transformSlides( { overview: '' } ); + + slide( indexh, indexv ); + + layout(); + + cueAutoSlide(); + + // Notify observers of the overview hiding + dispatchEvent( 'overviewhidden', { + 'indexh': indexh, + 'indexv': indexv, + 'currentSlide': currentSlide + } ); + + } + } + + /** + * Toggles the slide overview mode on and off. + * + * @param {Boolean} override Optional flag which overrides the + * toggle logic and forcibly sets the desired state. True means + * overview is open, false means it's closed. + */ + function toggleOverview( override ) { + + if( typeof override === 'boolean' ) { + override ? activateOverview() : deactivateOverview(); + } + else { + isOverview() ? deactivateOverview() : activateOverview(); + } + + } + + /** + * Checks if the overview is currently active. + * + * @return {Boolean} true if the overview is active, + * false otherwise + */ + function isOverview() { + + return overview; + + } + + /** + * Checks if the current or specified slide is vertical + * (nested within another slide). + * + * @param {HTMLElement} slide [optional] The slide to check + * orientation of + */ + function isVerticalSlide( slide ) { + + // Prefer slide argument, otherwise use current slide + slide = slide ? slide : currentSlide; + + return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i ); + + } + + /** + * Handling the fullscreen functionality via the fullscreen API + * + * @see http://fullscreen.spec.whatwg.org/ + * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode + */ + function enterFullscreen() { + + var element = document.body; + + // Check which implementation is available + var requestMethod = element.requestFullScreen || + element.webkitRequestFullscreen || + element.webkitRequestFullScreen || + element.mozRequestFullScreen || + element.msRequestFullscreen; + + if( requestMethod ) { + requestMethod.apply( element ); + } + + } + + /** + * Enters the paused mode which fades everything on screen to + * black. + */ + function pause() { + + if( config.pause ) { + var wasPaused = dom.wrapper.classList.contains( 'paused' ); + + cancelAutoSlide(); + dom.wrapper.classList.add( 'paused' ); + + if( wasPaused === false ) { + dispatchEvent( 'paused' ); + } + } + + } + + /** + * Exits from the paused mode. + */ + function resume() { + + var wasPaused = dom.wrapper.classList.contains( 'paused' ); + dom.wrapper.classList.remove( 'paused' ); + + cueAutoSlide(); + + if( wasPaused ) { + dispatchEvent( 'resumed' ); + } + + } + + /** + * Toggles the paused mode on and off. + */ + function togglePause( override ) { + + if( typeof override === 'boolean' ) { + override ? pause() : resume(); + } + else { + isPaused() ? resume() : pause(); + } + + } + + /** + * Checks if we are currently in the paused mode. + */ + function isPaused() { + + return dom.wrapper.classList.contains( 'paused' ); + + } + + /** + * Toggles the auto slide mode on and off. + * + * @param {Boolean} override Optional flag which sets the desired state. + * True means autoplay starts, false means it stops. + */ + + function toggleAutoSlide( override ) { + + if( typeof override === 'boolean' ) { + override ? resumeAutoSlide() : pauseAutoSlide(); + } + + else { + autoSlidePaused ? resumeAutoSlide() : pauseAutoSlide(); + } + + } + + /** + * Checks if the auto slide mode is currently on. + */ + function isAutoSliding() { + + return !!( autoSlide && !autoSlidePaused ); + + } + + /** + * Steps from the current point in the presentation to the + * slide which matches the specified horizontal and vertical + * indices. + * + * @param {int} h Horizontal index of the target slide + * @param {int} v Vertical index of the target slide + * @param {int} f Optional index of a fragment within the + * target slide to activate + * @param {int} o Optional origin for use in multimaster environments + */ + function slide( h, v, f, o ) { + + // Remember where we were at before + previousSlide = currentSlide; + + // Query all horizontal slides in the deck + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ); + + // If no vertical index is specified and the upcoming slide is a + // stack, resume at its previous vertical index + if( v === undefined && !isOverview() ) { + v = getPreviousVerticalIndex( horizontalSlides[ h ] ); + } + + // If we were on a vertical stack, remember what vertical index + // it was on so we can resume at the same position when returning + if( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) { + setPreviousVerticalIndex( previousSlide.parentNode, indexv ); + } + + // Remember the state before this slide + var stateBefore = state.concat(); + + // Reset the state array + state.length = 0; + + var indexhBefore = indexh || 0, + indexvBefore = indexv || 0; + + // Activate and transition to the new slide + indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h ); + indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v ); + + // Update the visibility of slides now that the indices have changed + updateSlidesVisibility(); + + layout(); + + // Apply the new state + stateLoop: for( var i = 0, len = state.length; i < len; i++ ) { + // Check if this state existed on the previous slide. If it + // did, we will avoid adding it repeatedly + for( var j = 0; j < stateBefore.length; j++ ) { + if( stateBefore[j] === state[i] ) { + stateBefore.splice( j, 1 ); + continue stateLoop; + } + } + + document.documentElement.classList.add( state[i] ); + + // Dispatch custom event matching the state's name + dispatchEvent( state[i] ); + } + + // Clean up the remains of the previous state + while( stateBefore.length ) { + document.documentElement.classList.remove( stateBefore.pop() ); + } + + // Update the overview if it's currently active + if( isOverview() ) { + updateOverview(); + } + + // Find the current horizontal slide and any possible vertical slides + // within it + var currentHorizontalSlide = horizontalSlides[ indexh ], + currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' ); + + // Store references to the previous and current slides + currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide; + + // Show fragment, if specified + if( typeof f !== 'undefined' ) { + navigateFragment( f ); + } + + // Dispatch an event if the slide changed + var slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore ); + if( slideChanged ) { + dispatchEvent( 'slidechanged', { + 'indexh': indexh, + 'indexv': indexv, + 'previousSlide': previousSlide, + 'currentSlide': currentSlide, + 'origin': o + } ); + } + else { + // Ensure that the previous slide is never the same as the current + previousSlide = null; + } + + // Solves an edge case where the previous slide maintains the + // 'present' class when navigating between adjacent vertical + // stacks + if( previousSlide ) { + previousSlide.classList.remove( 'present' ); + previousSlide.setAttribute( 'aria-hidden', 'true' ); + + // Reset all slides upon navigate to home + // Issue: #285 + if ( dom.wrapper.querySelector( HOME_SLIDE_SELECTOR ).classList.contains( 'present' ) ) { + // Launch async task + setTimeout( function () { + var slides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.stack') ), i; + for( i in slides ) { + if( slides[i] ) { + // Reset stack + setPreviousVerticalIndex( slides[i], 0 ); + } + } + }, 0 ); + } + } + + // Handle embedded content + if( slideChanged || !previousSlide ) { + stopEmbeddedContent( previousSlide ); + startEmbeddedContent( currentSlide ); + } + + // Announce the current slide contents, for screen readers + dom.statusDiv.textContent = currentSlide.textContent; + + updateControls(); + updateProgress(); + updateBackground(); + updateParallax(); + updateSlideNumber(); + updateNotes(); + + // Update the URL hash + writeURL(); + + cueAutoSlide(); + + } + + /** + * Syncs the presentation with the current DOM. Useful + * when new slides or control elements are added or when + * the configuration has changed. + */ + function sync() { + + // Subscribe to input + removeEventListeners(); + addEventListeners(); + + // Force a layout to make sure the current config is accounted for + layout(); + + // Reflect the current autoSlide value + autoSlide = config.autoSlide; + + // Start auto-sliding if it's enabled + cueAutoSlide(); + + // Re-create the slide backgrounds + createBackgrounds(); + + // Write the current hash to the URL + writeURL(); + + sortAllFragments(); + + updateControls(); + updateProgress(); + updateBackground( true ); + updateSlideNumber(); + updateSlidesVisibility(); + updateNotes(); + + formatEmbeddedContent(); + startEmbeddedContent( currentSlide ); + + if( isOverview() ) { + layoutOverview(); + } + + } + + /** + * Resets all vertical slides so that only the first + * is visible. + */ + function resetVerticalSlides() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + horizontalSlides.forEach( function( horizontalSlide ) { + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + verticalSlides.forEach( function( verticalSlide, y ) { + + if( y > 0 ) { + verticalSlide.classList.remove( 'present' ); + verticalSlide.classList.remove( 'past' ); + verticalSlide.classList.add( 'future' ); + verticalSlide.setAttribute( 'aria-hidden', 'true' ); + } + + } ); + + } ); + + } + + /** + * Sorts and formats all of fragments in the + * presentation. + */ + function sortAllFragments() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + horizontalSlides.forEach( function( horizontalSlide ) { + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + verticalSlides.forEach( function( verticalSlide, y ) { + + sortFragments( verticalSlide.querySelectorAll( '.fragment' ) ); + + } ); + + if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) ); + + } ); + + } + + /** + * Updates one dimension of slides by showing the slide + * with the specified index. + * + * @param {String} selector A CSS selector that will fetch + * the group of slides we are working with + * @param {Number} index The index of the slide that should be + * shown + * + * @return {Number} The index of the slide that is now shown, + * might differ from the passed in index if it was out of + * bounds. + */ + function updateSlides( selector, index ) { + + // Select all slides and convert the NodeList result to + // an array + var slides = toArray( dom.wrapper.querySelectorAll( selector ) ), + slidesLength = slides.length; + + var printMode = isPrintingPDF(); + + if( slidesLength ) { + + // Should the index loop? + if( config.loop ) { + index %= slidesLength; + + if( index < 0 ) { + index = slidesLength + index; + } + } + + // Enforce max and minimum index bounds + index = Math.max( Math.min( index, slidesLength - 1 ), 0 ); + + for( var i = 0; i < slidesLength; i++ ) { + var element = slides[i]; + + var reverse = config.rtl && !isVerticalSlide( element ); + + element.classList.remove( 'past' ); + element.classList.remove( 'present' ); + element.classList.remove( 'future' ); + + // http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute + element.setAttribute( 'hidden', '' ); + element.setAttribute( 'aria-hidden', 'true' ); + + // If this element contains vertical slides + if( element.querySelector( 'section' ) ) { + element.classList.add( 'stack' ); + } + + // If we're printing static slides, all slides are "present" + if( printMode ) { + element.classList.add( 'present' ); + continue; + } + + if( i < index ) { + // Any element previous to index is given the 'past' class + element.classList.add( reverse ? 'future' : 'past' ); + + if( config.fragments ) { + var pastFragments = toArray( element.querySelectorAll( '.fragment' ) ); + + // Show all fragments on prior slides + while( pastFragments.length ) { + var pastFragment = pastFragments.pop(); + pastFragment.classList.add( 'visible' ); + pastFragment.classList.remove( 'current-fragment' ); + } + } + } + else if( i > index ) { + // Any element subsequent to index is given the 'future' class + element.classList.add( reverse ? 'past' : 'future' ); + + if( config.fragments ) { + var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) ); + + // No fragments in future slides should be visible ahead of time + while( futureFragments.length ) { + var futureFragment = futureFragments.pop(); + futureFragment.classList.remove( 'visible' ); + futureFragment.classList.remove( 'current-fragment' ); + } + } + } + } + + // Mark the current slide as present + slides[index].classList.add( 'present' ); + slides[index].removeAttribute( 'hidden' ); + slides[index].removeAttribute( 'aria-hidden' ); + + // If this slide has a state associated with it, add it + // onto the current state of the deck + var slideState = slides[index].getAttribute( 'data-state' ); + if( slideState ) { + state = state.concat( slideState.split( ' ' ) ); + } + + } + else { + // Since there are no slides we can't be anywhere beyond the + // zeroth index + index = 0; + } + + return index; + + } + + /** + * Optimization method; hide all slides that are far away + * from the present slide. + */ + function updateSlidesVisibility() { + + // Select all slides and convert the NodeList result to + // an array + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ), + horizontalSlidesLength = horizontalSlides.length, + distanceX, + distanceY; + + if( horizontalSlidesLength && typeof indexh !== 'undefined' ) { + + // The number of steps away from the present slide that will + // be visible + var viewDistance = isOverview() ? 10 : config.viewDistance; + + // Limit view distance on weaker devices + if( isMobileDevice ) { + viewDistance = isOverview() ? 6 : 2; + } + + // All slides need to be visible when exporting to PDF + if( isPrintingPDF() ) { + viewDistance = Number.MAX_VALUE; + } + + for( var x = 0; x < horizontalSlidesLength; x++ ) { + var horizontalSlide = horizontalSlides[x]; + + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ), + verticalSlidesLength = verticalSlides.length; + + // Determine how far away this slide is from the present + distanceX = Math.abs( ( indexh || 0 ) - x ) || 0; + + // If the presentation is looped, distance should measure + // 1 between the first and last slides + if( config.loop ) { + distanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0; + } + + // Show the horizontal slide if it's within the view distance + if( distanceX < viewDistance ) { + showSlide( horizontalSlide ); + } + else { + hideSlide( horizontalSlide ); + } + + if( verticalSlidesLength ) { + + var oy = getPreviousVerticalIndex( horizontalSlide ); + + for( var y = 0; y < verticalSlidesLength; y++ ) { + var verticalSlide = verticalSlides[y]; + + distanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy ); + + if( distanceX + distanceY < viewDistance ) { + showSlide( verticalSlide ); + } + else { + hideSlide( verticalSlide ); + } + } + + } + } + + } + + } + + /** + * Pick up notes from the current slide and display tham + * to the viewer. + * + * @see `showNotes` config value + */ + function updateNotes() { + + if( config.showNotes && dom.speakerNotes && currentSlide && !isPrintingPDF() ) { + + dom.speakerNotes.innerHTML = getSlideNotes() || ''; + + } + + } + + /** + * Updates the progress bar to reflect the current slide. + */ + function updateProgress() { + + // Update progress if enabled + if( config.progress && dom.progressbar ) { + + dom.progressbar.style.width = getProgress() * dom.wrapper.offsetWidth + 'px'; + + } + + } + + /** + * Updates the slide number div to reflect the current slide. + * + * The following slide number formats are available: + * "h.v": horizontal . vertical slide number (default) + * "h/v": horizontal / vertical slide number + * "c": flattened slide number + * "c/t": flattened slide number / total slides + */ + function updateSlideNumber() { + + // Update slide number if enabled + if( config.slideNumber && dom.slideNumber ) { + + var value = []; + var format = 'h.v'; + + // Check if a custom number format is available + if( typeof config.slideNumber === 'string' ) { + format = config.slideNumber; + } + + switch( format ) { + case 'c': + value.push( getSlidePastCount() + 1 ); + break; + case 'c/t': + value.push( getSlidePastCount() + 1, '/', getTotalSlides() ); + break; + case 'h/v': + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '/', indexv + 1 ); + break; + default: + value.push( indexh + 1 ); + if( isVerticalSlide() ) value.push( '.', indexv + 1 ); + } + + dom.slideNumber.innerHTML = formatSlideNumber( value[0], value[1], value[2] ); + } + + } + + /** + * Applies HTML formatting to a slide number before it's + * written to the DOM. + */ + function formatSlideNumber( a, delimiter, b ) { + + if( typeof b === 'number' && !isNaN( b ) ) { + return ''+ a +'' + + ''+ delimiter +'' + + ''+ b +''; + } + else { + return ''+ a +''; + } + + } + + /** + * Updates the state of all control/navigation arrows. + */ + function updateControls() { + + var routes = availableRoutes(); + var fragments = availableFragments(); + + // Remove the 'enabled' class from all directions + dom.controlsLeft.concat( dom.controlsRight ) + .concat( dom.controlsUp ) + .concat( dom.controlsDown ) + .concat( dom.controlsPrev ) + .concat( dom.controlsNext ).forEach( function( node ) { + node.classList.remove( 'enabled' ); + node.classList.remove( 'fragmented' ); + } ); + + // Add the 'enabled' class to the available routes + if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + + // Prev/next buttons + if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } ); + + // Highlight fragment directions + if( currentSlide ) { + + // Always apply fragment decorator to prev/next buttons + if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + + // Apply fragment decorators to directional buttons based on + // what slide axis they are in + if( isVerticalSlide( currentSlide ) ) { + if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + } + else { + if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } ); + } + + } + + } + + /** + * Updates the background elements to reflect the current + * slide. + * + * @param {Boolean} includeAll If true, the backgrounds of + * all vertical slides (not just the present) will be updated. + */ + function updateBackground( includeAll ) { + + var currentBackground = null; + + // Reverse past/future classes when in RTL mode + var horizontalPast = config.rtl ? 'future' : 'past', + horizontalFuture = config.rtl ? 'past' : 'future'; + + // Update the classes of all backgrounds to match the + // states of their slides (past/present/future) + toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) { + + backgroundh.classList.remove( 'past' ); + backgroundh.classList.remove( 'present' ); + backgroundh.classList.remove( 'future' ); + + if( h < indexh ) { + backgroundh.classList.add( horizontalPast ); + } + else if ( h > indexh ) { + backgroundh.classList.add( horizontalFuture ); + } + else { + backgroundh.classList.add( 'present' ); + + // Store a reference to the current background element + currentBackground = backgroundh; + } + + if( includeAll || h === indexh ) { + toArray( backgroundh.querySelectorAll( '.slide-background' ) ).forEach( function( backgroundv, v ) { + + backgroundv.classList.remove( 'past' ); + backgroundv.classList.remove( 'present' ); + backgroundv.classList.remove( 'future' ); + + if( v < indexv ) { + backgroundv.classList.add( 'past' ); + } + else if ( v > indexv ) { + backgroundv.classList.add( 'future' ); + } + else { + backgroundv.classList.add( 'present' ); + + // Only if this is the present horizontal and vertical slide + if( h === indexh ) currentBackground = backgroundv; + } + + } ); + } + + } ); + + // Stop any currently playing video background + if( previousBackground ) { + + var previousVideo = previousBackground.querySelector( 'video' ); + if( previousVideo ) previousVideo.pause(); + + } + + if( currentBackground ) { + + // Start video playback + var currentVideo = currentBackground.querySelector( 'video' ); + if( currentVideo ) { + if( currentVideo.currentTime > 0 ) currentVideo.currentTime = 0; + currentVideo.play(); + } + + var backgroundImageURL = currentBackground.style.backgroundImage || ''; + + // Restart GIFs (doesn't work in Firefox) + if( /\.gif/i.test( backgroundImageURL ) ) { + currentBackground.style.backgroundImage = ''; + window.getComputedStyle( currentBackground ).opacity; + currentBackground.style.backgroundImage = backgroundImageURL; + } + + // Don't transition between identical backgrounds. This + // prevents unwanted flicker. + var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null; + var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' ); + if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) { + dom.background.classList.add( 'no-transition' ); + } + + previousBackground = currentBackground; + + } + + // If there's a background brightness flag for this slide, + // bubble it to the .reveal container + if( currentSlide ) { + [ 'has-light-background', 'has-dark-background' ].forEach( function( classToBubble ) { + if( currentSlide.classList.contains( classToBubble ) ) { + dom.wrapper.classList.add( classToBubble ); + } + else { + dom.wrapper.classList.remove( classToBubble ); + } + } ); + } + + // Allow the first background to apply without transition + setTimeout( function() { + dom.background.classList.remove( 'no-transition' ); + }, 1 ); + + } + + /** + * Updates the position of the parallax background based + * on the current slide index. + */ + function updateParallax() { + + if( config.parallaxBackgroundImage ) { + + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), + verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); + + var backgroundSize = dom.background.style.backgroundSize.split( ' ' ), + backgroundWidth, backgroundHeight; + + if( backgroundSize.length === 1 ) { + backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 ); + } + else { + backgroundWidth = parseInt( backgroundSize[0], 10 ); + backgroundHeight = parseInt( backgroundSize[1], 10 ); + } + + var slideWidth = dom.background.offsetWidth, + horizontalSlideCount = horizontalSlides.length, + horizontalOffsetMultiplier, + horizontalOffset; + + if( typeof config.parallaxBackgroundHorizontal === 'number' ) { + horizontalOffsetMultiplier = config.parallaxBackgroundHorizontal; + } + else { + horizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0; + } + + horizontalOffset = horizontalOffsetMultiplier * indexh * -1; + + var slideHeight = dom.background.offsetHeight, + verticalSlideCount = verticalSlides.length, + verticalOffsetMultiplier, + verticalOffset; + + if( typeof config.parallaxBackgroundVertical === 'number' ) { + verticalOffsetMultiplier = config.parallaxBackgroundVertical; + } + else { + verticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ); + } + + verticalOffset = verticalSlideCount > 0 ? verticalOffsetMultiplier * indexv * 1 : 0; + + dom.background.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px'; + + } + + } + + /** + * Called when the given slide is within the configured view + * distance. Shows the slide element and loads any content + * that is set to load lazily (data-src). + */ + function showSlide( slide ) { + + // Show the slide element + slide.style.display = 'block'; + + // Media elements with data-src attributes + toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src]' ) ).forEach( function( element ) { + element.setAttribute( 'src', element.getAttribute( 'data-src' ) ); + element.removeAttribute( 'data-src' ); + } ); + + // Media elements with children + toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( media ) { + var sources = 0; + + toArray( media.querySelectorAll( 'source[data-src]' ) ).forEach( function( source ) { + source.setAttribute( 'src', source.getAttribute( 'data-src' ) ); + source.removeAttribute( 'data-src' ); + sources += 1; + } ); + + // If we rewrote sources for this video/audio element, we need + // to manually tell it to load from its new origin + if( sources > 0 ) { + media.load(); + } + } ); + + + // Show the corresponding background element + var indices = getIndices( slide ); + var background = getSlideBackground( indices.h, indices.v ); + if( background ) { + background.style.display = 'block'; + + // If the background contains media, load it + if( background.hasAttribute( 'data-loaded' ) === false ) { + background.setAttribute( 'data-loaded', 'true' ); + + var backgroundImage = slide.getAttribute( 'data-background-image' ), + backgroundVideo = slide.getAttribute( 'data-background-video' ), + backgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ), + backgroundIframe = slide.getAttribute( 'data-background-iframe' ); + + // Images + if( backgroundImage ) { + background.style.backgroundImage = 'url('+ backgroundImage +')'; + } + // Videos + else if ( backgroundVideo && !isSpeakerNotes() ) { + var video = document.createElement( 'video' ); + + if( backgroundVideoLoop ) { + video.setAttribute( 'loop', '' ); + } + + // Support comma separated lists of video sources + backgroundVideo.split( ',' ).forEach( function( source ) { + video.innerHTML += ''; + } ); + + background.appendChild( video ); + } + // Iframes + else if( backgroundIframe ) { + var iframe = document.createElement( 'iframe' ); + iframe.setAttribute( 'src', backgroundIframe ); + iframe.style.width = '100%'; + iframe.style.height = '100%'; + iframe.style.maxHeight = '100%'; + iframe.style.maxWidth = '100%'; + + background.appendChild( iframe ); + } + } + } + + } + + /** + * Called when the given slide is moved outside of the + * configured view distance. + */ + function hideSlide( slide ) { + + // Hide the slide element + slide.style.display = 'none'; + + // Hide the corresponding background element + var indices = getIndices( slide ); + var background = getSlideBackground( indices.h, indices.v ); + if( background ) { + background.style.display = 'none'; + } + + } + + /** + * Determine what available routes there are for navigation. + * + * @return {Object} containing four booleans: left/right/up/down + */ + function availableRoutes() { + + var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ), + verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR ); + + var routes = { + left: indexh > 0 || config.loop, + right: indexh < horizontalSlides.length - 1 || config.loop, + up: indexv > 0, + down: indexv < verticalSlides.length - 1 + }; + + // reverse horizontal controls for rtl + if( config.rtl ) { + var left = routes.left; + routes.left = routes.right; + routes.right = left; + } + + return routes; + + } + + /** + * Returns an object describing the available fragment + * directions. + * + * @return {Object} two boolean properties: prev/next + */ + function availableFragments() { + + if( currentSlide && config.fragments ) { + var fragments = currentSlide.querySelectorAll( '.fragment' ); + var hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' ); + + return { + prev: fragments.length - hiddenFragments.length > 0, + next: !!hiddenFragments.length + }; + } + else { + return { prev: false, next: false }; + } + + } + + /** + * Enforces origin-specific format rules for embedded media. + */ + function formatEmbeddedContent() { + + var _appendParamToIframeSource = function( sourceAttribute, sourceURL, param ) { + toArray( dom.slides.querySelectorAll( 'iframe['+ sourceAttribute +'*="'+ sourceURL +'"]' ) ).forEach( function( el ) { + var src = el.getAttribute( sourceAttribute ); + if( src && src.indexOf( param ) === -1 ) { + el.setAttribute( sourceAttribute, src + ( !/\?/.test( src ) ? '?' : '&' ) + param ); + } + }); + }; + + // YouTube frames must include "?enablejsapi=1" + _appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' ); + _appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' ); + + // Vimeo frames must include "?api=1" + _appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' ); + _appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' ); + + } + + /** + * Start playback of any embedded content inside of + * the targeted slide. + */ + function startEmbeddedContent( slide ) { + + if( slide && !isSpeakerNotes() ) { + // Restart GIFs + toArray( slide.querySelectorAll( 'img[src$=".gif"]' ) ).forEach( function( el ) { + // Setting the same unchanged source like this was confirmed + // to work in Chrome, FF & Safari + el.setAttribute( 'src', el.getAttribute( 'src' ) ); + } ); + + // HTML5 media elements + toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) { + if( el.hasAttribute( 'data-autoplay' ) && typeof el.play === 'function' ) { + el.play(); + } + } ); + + // Normal iframes + toArray( slide.querySelectorAll( 'iframe[src]' ) ).forEach( function( el ) { + startEmbeddedIframe( { target: el } ); + } ); + + // Lazy loading iframes + toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) { + if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) { + el.removeEventListener( 'load', startEmbeddedIframe ); // remove first to avoid dupes + el.addEventListener( 'load', startEmbeddedIframe ); + el.setAttribute( 'src', el.getAttribute( 'data-src' ) ); + } + } ); + } + + } + + /** + * "Starts" the content of an embedded iframe using the + * postmessage API. + */ + function startEmbeddedIframe( event ) { + + var iframe = event.target; + + // YouTube postMessage API + if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && iframe.hasAttribute( 'data-autoplay' ) ) { + iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' ); + } + // Vimeo postMessage API + else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && iframe.hasAttribute( 'data-autoplay' ) ) { + iframe.contentWindow.postMessage( '{"method":"play"}', '*' ); + } + // Generic postMessage API + else { + iframe.contentWindow.postMessage( 'slide:start', '*' ); + } + + } + + /** + * Stop playback of any embedded content inside of + * the targeted slide. + */ + function stopEmbeddedContent( slide ) { + + if( slide && slide.parentNode ) { + // HTML5 media elements + toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) { + el.pause(); + } + } ); + + // Generic postMessage API for non-lazy loaded iframes + toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) { + el.contentWindow.postMessage( 'slide:stop', '*' ); + el.removeEventListener( 'load', startEmbeddedIframe ); + }); + + // YouTube postMessage API + toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) { + el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' ); + } + }); + + // Vimeo postMessage API + toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) { + if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) { + el.contentWindow.postMessage( '{"method":"pause"}', '*' ); + } + }); + + // Lazy loading iframes + toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) { + // Only removing the src doesn't actually unload the frame + // in all browsers (Firefox) so we set it to blank first + el.setAttribute( 'src', 'about:blank' ); + el.removeAttribute( 'src' ); + } ); + } + + } + + /** + * Returns the number of past slides. This can be used as a global + * flattened index for slides. + */ + function getSlidePastCount() { + + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + // The number of past slides + var pastCount = 0; + + // Step through all slides and count the past ones + mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) { + + var horizontalSlide = horizontalSlides[i]; + var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); + + for( var j = 0; j < verticalSlides.length; j++ ) { + + // Stop as soon as we arrive at the present + if( verticalSlides[j].classList.contains( 'present' ) ) { + break mainLoop; + } + + pastCount++; + + } + + // Stop as soon as we arrive at the present + if( horizontalSlide.classList.contains( 'present' ) ) { + break; + } + + // Don't count the wrapping section for vertical slides + if( horizontalSlide.classList.contains( 'stack' ) === false ) { + pastCount++; + } + + } + + return pastCount; + + } + + /** + * Returns a value ranging from 0-1 that represents + * how far into the presentation we have navigated. + */ + function getProgress() { + + // The number of past and total slides + var totalCount = getTotalSlides(); + var pastCount = getSlidePastCount(); + + if( currentSlide ) { + + var allFragments = currentSlide.querySelectorAll( '.fragment' ); + + // If there are fragments in the current slide those should be + // accounted for in the progress. + if( allFragments.length > 0 ) { + var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' ); + + // This value represents how big a portion of the slide progress + // that is made up by its fragments (0-1) + var fragmentWeight = 0.9; + + // Add fragment progress to the past slide count + pastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight; + } + + } + + return pastCount / ( totalCount - 1 ); + + } + + /** + * Checks if this presentation is running inside of the + * speaker notes window. + */ + function isSpeakerNotes() { + + return !!window.location.search.match( /receiver/gi ); + + } + + /** + * Reads the current URL (hash) and navigates accordingly. + */ + function readURL() { + + var hash = window.location.hash; + + // Attempt to parse the hash as either an index or name + var bits = hash.slice( 2 ).split( '/' ), + name = hash.replace( /#|\//gi, '' ); + + // If the first bit is invalid and there is a name we can + // assume that this is a named link + if( isNaN( parseInt( bits[0], 10 ) ) && name.length ) { + var element; + + // Ensure the named link is a valid HTML ID attribute + if( /^[a-zA-Z][\w:.-]*$/.test( name ) ) { + // Find the slide with the specified ID + element = document.getElementById( name ); + } + + if( element ) { + // Find the position of the named slide and navigate to it + var indices = Reveal.getIndices( element ); + slide( indices.h, indices.v ); + } + // If the slide doesn't exist, navigate to the current slide + else { + slide( indexh || 0, indexv || 0 ); + } + } + else { + // Read the index components of the hash + var h = parseInt( bits[0], 10 ) || 0, + v = parseInt( bits[1], 10 ) || 0; + + if( h !== indexh || v !== indexv ) { + slide( h, v ); + } + } + + } + + /** + * Updates the page URL (hash) to reflect the current + * state. + * + * @param {Number} delay The time in ms to wait before + * writing the hash + */ + function writeURL( delay ) { + + if( config.history ) { + + // Make sure there's never more than one timeout running + clearTimeout( writeURLTimeout ); + + // If a delay is specified, timeout this call + if( typeof delay === 'number' ) { + writeURLTimeout = setTimeout( writeURL, delay ); + } + else if( currentSlide ) { + var url = '/'; + + // Attempt to create a named link based on the slide's ID + var id = currentSlide.getAttribute( 'id' ); + if( id ) { + id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' ); + } + + // If the current slide has an ID, use that as a named link + if( typeof id === 'string' && id.length ) { + url = '/' + id; + } + // Otherwise use the /h/v index + else { + if( indexh > 0 || indexv > 0 ) url += indexh; + if( indexv > 0 ) url += '/' + indexv; + } + + window.location.hash = url; + } + } + + } + + /** + * Retrieves the h/v location of the current, or specified, + * slide. + * + * @param {HTMLElement} slide If specified, the returned + * index will be for this slide rather than the currently + * active one + * + * @return {Object} { h: , v: , f: } + */ + function getIndices( slide ) { + + // By default, return the current indices + var h = indexh, + v = indexv, + f; + + // If a slide is specified, return the indices of that slide + if( slide ) { + var isVertical = isVerticalSlide( slide ); + var slideh = isVertical ? slide.parentNode : slide; + + // Select all horizontal slides + var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); + + // Now that we know which the horizontal slide is, get its index + h = Math.max( horizontalSlides.indexOf( slideh ), 0 ); + + // Assume we're not vertical + v = undefined; + + // If this is a vertical slide, grab the vertical index + if( isVertical ) { + v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 ); + } + } + + if( !slide && currentSlide ) { + var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0; + if( hasFragments ) { + var currentFragment = currentSlide.querySelector( '.current-fragment' ); + if( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) { + f = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 ); + } + else { + f = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1; + } + } + } + + return { h: h, v: v, f: f }; + + } + + /** + * Retrieves the total number of slides in this presentation. + */ + function getTotalSlides() { + + return dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length; + + } + + /** + * Returns the slide element matching the specified index. + */ + function getSlide( x, y ) { + + var horizontalSlide = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ]; + var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' ); + + if( verticalSlides && verticalSlides.length && typeof y === 'number' ) { + return verticalSlides ? verticalSlides[ y ] : undefined; + } + + return horizontalSlide; + + } + + /** + * Returns the background element for the given slide. + * All slides, even the ones with no background properties + * defined, have a background element so as long as the + * index is valid an element will be returned. + */ + function getSlideBackground( x, y ) { + + // When printing to PDF the slide backgrounds are nested + // inside of the slides + if( isPrintingPDF() ) { + var slide = getSlide( x, y ); + if( slide ) { + var background = slide.querySelector( '.slide-background' ); + if( background && background.parentNode === slide ) { + return background; + } + } + + return undefined; + } + + var horizontalBackground = dom.wrapper.querySelectorAll( '.backgrounds>.slide-background' )[ x ]; + var verticalBackgrounds = horizontalBackground && horizontalBackground.querySelectorAll( '.slide-background' ); + + if( verticalBackgrounds && verticalBackgrounds.length && typeof y === 'number' ) { + return verticalBackgrounds ? verticalBackgrounds[ y ] : undefined; + } + + return horizontalBackground; + + } + + /** + * Retrieves the speaker notes from a slide. Notes can be + * defined in two ways: + * 1. As a data-notes attribute on the slide
+ * 2. As an