diff --git a/inst/reveal.js-4.2.1/js/controllers/autoanimate.js b/inst/reveal.js-4.2.1/js/controllers/autoanimate.js
new file mode 100644
index 0000000..60c02e5
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/autoanimate.js
@@ -0,0 +1,626 @@
+import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'
+import { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'
+
+// Counter used to generate unique IDs for auto-animated elements
+let autoAnimateCounter = 0;
+
+/**
+ * Automatically animates matching elements across
+ * slides with the [data-auto-animate] attribute.
+ */
+export default class AutoAnimate {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Runs an auto-animation between the given slides.
+	 *
+	 * @param  {HTMLElement} fromSlide
+	 * @param  {HTMLElement} toSlide
+	 */
+	run( fromSlide, toSlide ) {
+
+		// Clean up after prior animations
+		this.reset();
+
+		let allSlides = this.Reveal.getSlides();
+		let toSlideIndex = allSlides.indexOf( toSlide );
+		let fromSlideIndex = allSlides.indexOf( fromSlide );
+
+		// Ensure that both slides are auto-animate targets with the same data-auto-animate-id value
+		// (including null if absent on both) and that data-auto-animate-restart isn't set on the
+		// physically latter slide (independent of slide direction)
+		if( fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )
+				&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) 
+				&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {
+
+			// Create a new auto-animate sheet
+			this.autoAnimateStyleSheet = this.autoAnimateStyleSheet || createStyleSheet();
+
+			let animationOptions = this.getAutoAnimateOptions( toSlide );
+
+			// Set our starting state
+			fromSlide.dataset.autoAnimate = 'pending';
+			toSlide.dataset.autoAnimate = 'pending';
+
+			// Flag the navigation direction, needed for fragment buildup
+			animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
+
+			// Inject our auto-animate styles for this transition
+			let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
+				return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
+			} );
+
+			// Animate unmatched elements, if enabled
+			if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
+
+				// Our default timings for unmatched elements
+				let defaultUnmatchedDuration = animationOptions.duration * 0.8,
+					defaultUnmatchedDelay = animationOptions.duration * 0.2;
+
+				this.getUnmatchedAutoAnimateElements( toSlide ).forEach( unmatchedElement => {
+
+					let unmatchedOptions = this.getAutoAnimateOptions( unmatchedElement, animationOptions );
+					let id = 'unmatched';
+
+					// If there is a duration or delay set specifically for this
+					// element our unmatched elements should adhere to those
+					if( unmatchedOptions.duration !== animationOptions.duration || unmatchedOptions.delay !== animationOptions.delay ) {
+						id = 'unmatched-' + autoAnimateCounter++;
+						css.push( `[data-auto-animate="running"] [data-auto-animate-target="${id}"] { transition: opacity ${unmatchedOptions.duration}s ease ${unmatchedOptions.delay}s; }` );
+					}
+
+					unmatchedElement.dataset.autoAnimateTarget = id;
+
+				}, this );
+
+				// Our default transition for unmatched elements
+				css.push( `[data-auto-animate="running"] [data-auto-animate-target="unmatched"] { transition: opacity ${defaultUnmatchedDuration}s ease ${defaultUnmatchedDelay}s; }` );
+
+			}
+
+			// Setting the whole chunk of CSS at once is the most
+			// efficient way to do this. Using sheet.insertRule
+			// is multiple factors slower.
+			this.autoAnimateStyleSheet.innerHTML = css.join( '' );
+
+			// Start the animation next cycle
+			requestAnimationFrame( () => {
+				if( this.autoAnimateStyleSheet ) {
+					// This forces our newly injected styles to be applied in Firefox
+					getComputedStyle( this.autoAnimateStyleSheet ).fontWeight;
+
+					toSlide.dataset.autoAnimate = 'running';
+				}
+			} );
+
+			this.Reveal.dispatchEvent({
+				type: 'autoanimate',
+				data: {
+					fromSlide,
+					toSlide,
+					sheet: this.autoAnimateStyleSheet
+				}
+			});
+
+		}
+
+	}
+
+	/**
+	 * Rolls back all changes that we've made to the DOM so
+	 * that as part of animating.
+	 */
+	reset() {
+
+		// Reset slides
+		queryAll( this.Reveal.getRevealElement(), '[data-auto-animate]:not([data-auto-animate=""])' ).forEach( element => {
+			element.dataset.autoAnimate = '';
+		} );
+
+		// Reset elements
+		queryAll( this.Reveal.getRevealElement(), '[data-auto-animate-target]' ).forEach( element => {
+			delete element.dataset.autoAnimateTarget;
+		} );
+
+		// Remove the animation sheet
+		if( this.autoAnimateStyleSheet && this.autoAnimateStyleSheet.parentNode ) {
+			this.autoAnimateStyleSheet.parentNode.removeChild( this.autoAnimateStyleSheet );
+			this.autoAnimateStyleSheet = null;
+		}
+
+	}
+
+	/**
+	 * Creates a FLIP animation where the `to` element starts out
+	 * in the `from` element position and animates to its original
+	 * state.
+	 *
+	 * @param {HTMLElement} from
+	 * @param {HTMLElement} to
+	 * @param {Object} elementOptions Options for this element pair
+	 * @param {Object} animationOptions Options set at the slide level
+	 * @param {String} id Unique ID that we can use to identify this
+	 * auto-animate element in the DOM
+	 */
+	autoAnimateElements( from, to, elementOptions, animationOptions, id ) {
+
+		// 'from' elements are given a data-auto-animate-target with no value,
+		// 'to' elements are are given a data-auto-animate-target with an ID
+		from.dataset.autoAnimateTarget = '';
+		to.dataset.autoAnimateTarget = id;
+
+		// Each element may override any of the auto-animate options
+		// like transition easing, duration and delay via data-attributes
+		let options = this.getAutoAnimateOptions( to, animationOptions );
+
+		// If we're using a custom element matcher the element options
+		// may contain additional transition overrides
+		if( typeof elementOptions.delay !== 'undefined' ) options.delay = elementOptions.delay;
+		if( typeof elementOptions.duration !== 'undefined' ) options.duration = elementOptions.duration;
+		if( typeof elementOptions.easing !== 'undefined' ) options.easing = elementOptions.easing;
+
+		let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
+			toProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );
+
+		// Maintain fragment visibility for matching elements when
+		// we're navigating forwards, this way the viewer won't need
+		// to step through the same fragments twice
+		if( to.classList.contains( 'fragment' ) ) {
+
+			// Don't auto-animate the opacity of fragments to avoid
+			// conflicts with fragment animations
+			delete toProps.styles['opacity'];
+
+			if( from.classList.contains( 'fragment' ) ) {
+
+				let fromFragmentStyle = ( from.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];
+				let toFragmentStyle = ( to.className.match( FRAGMENT_STYLE_REGEX ) || [''] )[0];
+
+				// Only skip the fragment if the fragment animation style
+				// remains unchanged
+				if( fromFragmentStyle === toFragmentStyle && animationOptions.slideDirection === 'forward' ) {
+					to.classList.add( 'visible', 'disabled' );
+				}
+
+			}
+
+		}
+
+		// If translation and/or scaling are enabled, css transform
+		// the 'to' element so that it matches the position and size
+		// of the 'from' element
+		if( elementOptions.translate !== false || elementOptions.scale !== false ) {
+
+			let presentationScale = this.Reveal.getScale();
+
+			let delta = {
+				x: ( fromProps.x - toProps.x ) / presentationScale,
+				y: ( fromProps.y - toProps.y ) / presentationScale,
+				scaleX: fromProps.width / toProps.width,
+				scaleY: fromProps.height / toProps.height
+			};
+
+			// Limit decimal points to avoid 0.0001px blur and stutter
+			delta.x = Math.round( delta.x * 1000 ) / 1000;
+			delta.y = Math.round( delta.y * 1000 ) / 1000;
+			delta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;
+			delta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;
+
+			let translate = elementOptions.translate !== false && ( delta.x !== 0 || delta.y !== 0 ),
+				scale = elementOptions.scale !== false && ( delta.scaleX !== 0 || delta.scaleY !== 0 );
+
+			// No need to transform if nothing's changed
+			if( translate || scale ) {
+
+				let transform = [];
+
+				if( translate ) transform.push( `translate(${delta.x}px, ${delta.y}px)` );
+				if( scale ) transform.push( `scale(${delta.scaleX}, ${delta.scaleY})` );
+
+				fromProps.styles['transform'] = transform.join( ' ' );
+				fromProps.styles['transform-origin'] = 'top left';
+
+				toProps.styles['transform'] = 'none';
+
+			}
+
+		}
+
+		// Delete all unchanged 'to' styles
+		for( let propertyName in toProps.styles ) {
+			const toValue = toProps.styles[propertyName];
+			const fromValue = fromProps.styles[propertyName];
+
+			if( toValue === fromValue ) {
+				delete toProps.styles[propertyName];
+			}
+			else {
+				// If these property values were set via a custom matcher providing
+				// an explicit 'from' and/or 'to' value, we always inject those values.
+				if( toValue.explicitValue === true ) {
+					toProps.styles[propertyName] = toValue.value;
+				}
+
+				if( fromValue.explicitValue === true ) {
+					fromProps.styles[propertyName] = fromValue.value;
+				}
+			}
+		}
+
+		let css = '';
+
+		let toStyleProperties = Object.keys( toProps.styles );
+
+		// Only create animate this element IF at least one style
+		// property has changed
+		if( toStyleProperties.length > 0 ) {
+
+			// Instantly move to the 'from' state
+			fromProps.styles['transition'] = 'none';
+
+			// Animate towards the 'to' state
+			toProps.styles['transition'] = `all ${options.duration}s ${options.easing} ${options.delay}s`;
+			toProps.styles['transition-property'] = toStyleProperties.join( ', ' );
+			toProps.styles['will-change'] = toStyleProperties.join( ', ' );
+
+			// Build up our custom CSS. We need to override inline styles
+			// so we need to make our styles vErY IMPORTANT!1!!
+			let fromCSS = Object.keys( fromProps.styles ).map( propertyName => {
+				return propertyName + ': ' + fromProps.styles[propertyName] + ' !important;';
+			} ).join( '' );
+
+			let toCSS = Object.keys( toProps.styles ).map( propertyName => {
+				return propertyName + ': ' + toProps.styles[propertyName] + ' !important;';
+			} ).join( '' );
+
+			css = 	'[data-auto-animate-target="'+ id +'"] {'+ fromCSS +'}' +
+					'[data-auto-animate="running"] [data-auto-animate-target="'+ id +'"] {'+ toCSS +'}';
+
+		}
+
+		return css;
+
+	}
+
+	/**
+	 * Returns the auto-animate options for the given element.
+	 *
+	 * @param {HTMLElement} element Element to pick up options
+	 * from, either a slide or an animation target
+	 * @param {Object} [inheritedOptions] Optional set of existing
+	 * options
+	 */
+	getAutoAnimateOptions( element, inheritedOptions ) {
+
+		let options = {
+			easing: this.Reveal.getConfig().autoAnimateEasing,
+			duration: this.Reveal.getConfig().autoAnimateDuration,
+			delay: 0
+		};
+
+		options = extend( options, inheritedOptions );
+
+		// Inherit options from parent elements
+		if( element.parentNode ) {
+			let autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );
+			if( autoAnimatedParent ) {
+				options = this.getAutoAnimateOptions( autoAnimatedParent, options );
+			}
+		}
+
+		if( element.dataset.autoAnimateEasing ) {
+			options.easing = element.dataset.autoAnimateEasing;
+		}
+
+		if( element.dataset.autoAnimateDuration ) {
+			options.duration = parseFloat( element.dataset.autoAnimateDuration );
+		}
+
+		if( element.dataset.autoAnimateDelay ) {
+			options.delay = parseFloat( element.dataset.autoAnimateDelay );
+		}
+
+		return options;
+
+	}
+
+	/**
+	 * Returns an object containing all of the properties
+	 * that can be auto-animated for the given element and
+	 * their current computed values.
+	 *
+	 * @param {String} direction 'from' or 'to'
+	 */
+	getAutoAnimatableProperties( direction, element, elementOptions ) {
+
+		let config = this.Reveal.getConfig();
+
+		let properties = { styles: [] };
+
+		// Position and size
+		if( elementOptions.translate !== false || elementOptions.scale !== false ) {
+			let bounds;
+
+			// Custom auto-animate may optionally return a custom tailored
+			// measurement function
+			if( typeof elementOptions.measure === 'function' ) {
+				bounds = elementOptions.measure( element );
+			}
+			else {
+				if( config.center ) {
+					// More precise, but breaks when used in combination
+					// with zoom for scaling the deck ¯\_(ツ)_/¯
+					bounds = element.getBoundingClientRect();
+				}
+				else {
+					let scale = this.Reveal.getScale();
+					bounds = {
+						x: element.offsetLeft * scale,
+						y: element.offsetTop * scale,
+						width: element.offsetWidth * scale,
+						height: element.offsetHeight * scale
+					};
+				}
+			}
+
+			properties.x = bounds.x;
+			properties.y = bounds.y;
+			properties.width = bounds.width;
+			properties.height = bounds.height;
+		}
+
+		const computedStyles = getComputedStyle( element );
+
+		// CSS styles
+		( elementOptions.styles || config.autoAnimateStyles ).forEach( style => {
+			let value;
+
+			// `style` is either the property name directly, or an object
+			// definition of a style property
+			if( typeof style === 'string' ) style = { property: style };
+
+			if( typeof style.from !== 'undefined' && direction === 'from' ) {
+				value = { value: style.from, explicitValue: true };
+			}
+			else if( typeof style.to !== 'undefined' && direction === 'to' ) {
+				value = { value: style.to, explicitValue: true };
+			}
+			else {
+				value = computedStyles[style.property];
+			}
+
+			if( value !== '' ) {
+				properties.styles[style.property] = value;
+			}
+		} );
+
+		return properties;
+
+	}
+
+	/**
+	 * Get a list of all element pairs that we can animate
+	 * between the given slides.
+	 *
+	 * @param {HTMLElement} fromSlide
+	 * @param {HTMLElement} toSlide
+	 *
+	 * @return {Array} Each value is an array where [0] is
+	 * the element we're animating from and [1] is the
+	 * element we're animating to
+	 */
+	getAutoAnimatableElements( fromSlide, toSlide ) {
+
+		let matcher = typeof this.Reveal.getConfig().autoAnimateMatcher === 'function' ? this.Reveal.getConfig().autoAnimateMatcher : this.getAutoAnimatePairs;
+
+		let pairs = matcher.call( this, fromSlide, toSlide );
+
+		let reserved = [];
+
+		// Remove duplicate pairs
+		return pairs.filter( ( pair, index ) => {
+			if( reserved.indexOf( pair.to ) === -1 ) {
+				reserved.push( pair.to );
+				return true;
+			}
+		} );
+
+	}
+
+	/**
+	 * Identifies matching elements between slides.
+	 *
+	 * You can specify a custom matcher function by using
+	 * the `autoAnimateMatcher` config option.
+	 */
+	getAutoAnimatePairs( fromSlide, toSlide ) {
+
+		let pairs = [];
+
+		const codeNodes = 'pre';
+		const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
+		const mediaNodes = 'img, video, iframe';
+
+		// Eplicit matches via data-id
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
+			return node.nodeName + ':::' + node.getAttribute( 'data-id' );
+		} );
+
+		// Text
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {
+			return node.nodeName + ':::' + node.innerText;
+		} );
+
+		// Media
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, mediaNodes, node => {
+			return node.nodeName + ':::' + ( node.getAttribute( 'src' ) || node.getAttribute( 'data-src' ) );
+		} );
+
+		// Code
+		this.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {
+			return node.nodeName + ':::' + node.innerText;
+		} );
+
+		pairs.forEach( pair => {
+
+			// Disable scale transformations on text nodes, we transition
+			// each individual text property instead
+			if( matches( pair.from, textNodes ) ) {
+				pair.options = { scale: false };
+			}
+			// Animate individual lines of code
+			else if( matches( pair.from, codeNodes ) ) {
+
+				// Transition the code block's width and height instead of scaling
+				// to prevent its content from being squished
+				pair.options = { scale: false, styles: [ 'width', 'height' ] };
+
+				// Lines of code
+				this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-code', node => {
+					return node.textContent;
+				}, {
+					scale: false,
+					styles: [],
+					measure: this.getLocalBoundingBox.bind( this )
+				} );
+
+				// Line numbers
+				this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {
+					return node.getAttribute( 'data-line-number' );
+				}, {
+					scale: false,
+					styles: [ 'width' ],
+					measure: this.getLocalBoundingBox.bind( this )
+				} );
+
+			}
+
+		}, this );
+
+		return pairs;
+
+	}
+
+	/**
+	 * Helper method which returns a bounding box based on
+	 * the given elements offset coordinates.
+	 *
+	 * @param {HTMLElement} element
+	 * @return {Object} x, y, width, height
+	 */
+	getLocalBoundingBox( element ) {
+
+		const presentationScale = this.Reveal.getScale();
+
+		return {
+			x: Math.round( ( element.offsetLeft * presentationScale ) * 100 ) / 100,
+			y: Math.round( ( element.offsetTop * presentationScale ) * 100 ) / 100,
+			width: Math.round( ( element.offsetWidth * presentationScale ) * 100 ) / 100,
+			height: Math.round( ( element.offsetHeight * presentationScale ) * 100 ) / 100
+		};
+
+	}
+
+	/**
+	 * Finds matching elements between two slides.
+	 *
+	 * @param {Array} pairs            	List of pairs to push matches to
+	 * @param {HTMLElement} fromScope   Scope within the from element exists
+	 * @param {HTMLElement} toScope     Scope within the to element exists
+	 * @param {String} selector         CSS selector of the element to match
+	 * @param {Function} serializer     A function that accepts an element and returns
+	 *                                  a stringified ID based on its contents
+	 * @param {Object} animationOptions Optional config options for this pair
+	 */
+	findAutoAnimateMatches( pairs, fromScope, toScope, selector, serializer, animationOptions ) {
+
+		let fromMatches = {};
+		let toMatches = {};
+
+		[].slice.call( fromScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {
+			const key = serializer( element );
+			if( typeof key === 'string' && key.length ) {
+				fromMatches[key] = fromMatches[key] || [];
+				fromMatches[key].push( element );
+			}
+		} );
+
+		[].slice.call( toScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {
+			const key = serializer( element );
+			toMatches[key] = toMatches[key] || [];
+			toMatches[key].push( element );
+
+			let fromElement;
+
+			// Retrieve the 'from' element
+			if( fromMatches[key] ) {
+				const pimaryIndex = toMatches[key].length - 1;
+				const secondaryIndex = fromMatches[key].length - 1;
+
+				// If there are multiple identical from elements, retrieve
+				// the one at the same index as our to-element.
+				if( fromMatches[key][ pimaryIndex ] ) {
+					fromElement = fromMatches[key][ pimaryIndex ];
+					fromMatches[key][ pimaryIndex ] = null;
+				}
+				// If there are no matching from-elements at the same index,
+				// use the last one.
+				else if( fromMatches[key][ secondaryIndex ] ) {
+					fromElement = fromMatches[key][ secondaryIndex ];
+					fromMatches[key][ secondaryIndex ] = null;
+				}
+			}
+
+			// If we've got a matching pair, push it to the list of pairs
+			if( fromElement ) {
+				pairs.push({
+					from: fromElement,
+					to: element,
+					options: animationOptions
+				});
+			}
+		} );
+
+	}
+
+	/**
+	 * Returns a all elements within the given scope that should
+	 * be considered unmatched in an auto-animate transition. If
+	 * fading of unmatched elements is turned on, these elements
+	 * will fade when going between auto-animate slides.
+	 *
+	 * Note that parents of auto-animate targets are NOT considerd
+	 * unmatched since fading them would break the auto-animation.
+	 *
+	 * @param {HTMLElement} rootElement
+	 * @return {Array}
+	 */
+	getUnmatchedAutoAnimateElements( rootElement ) {
+
+		return [].slice.call( rootElement.children ).reduce( ( result, element ) => {
+
+			const containsAnimatedElements = element.querySelector( '[data-auto-animate-target]' );
+
+			// The element is unmatched if
+			// - It is not an auto-animate target
+			// - It does not contain any auto-animate targets
+			if( !element.hasAttribute( 'data-auto-animate-target' ) && !containsAnimatedElements ) {
+				result.push( element );
+			}
+
+			if( element.querySelector( '[data-auto-animate-target]' ) ) {
+				result = result.concat( this.getUnmatchedAutoAnimateElements( element ) );
+			}
+
+			return result;
+
+		}, [] );
+
+	}
+
+}
diff --git a/inst/reveal.js-4.2.1/js/controllers/backgrounds.js b/inst/reveal.js-4.2.1/js/controllers/backgrounds.js
new file mode 100644
index 0000000..f412a18
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/backgrounds.js
@@ -0,0 +1,397 @@
+import { queryAll } from '../utils/util.js'
+import { colorToRgb, colorBrightness } from '../utils/color.js'
+
+/**
+ * Creates and updates slide backgrounds.
+ */
+export default class Backgrounds {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'backgrounds';
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+	}
+
+	/**
+	 * 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.
+	 */
+	create() {
+
+		// Clear prior backgrounds
+		this.element.innerHTML = '';
+		this.element.classList.add( 'no-transition' );
+
+		// Iterate over all horizontal slides
+		this.Reveal.getHorizontalSlides().forEach( slideh => {
+
+			let backgroundStack = this.createBackground( slideh, this.element );
+
+			// Iterate over all vertical slides
+			queryAll( slideh, 'section' ).forEach( slidev => {
+
+				this.createBackground( slidev, backgroundStack );
+
+				backgroundStack.classList.add( 'stack' );
+
+			} );
+
+		} );
+
+		// Add parallax background if specified
+		if( this.Reveal.getConfig().parallaxBackgroundImage ) {
+
+			this.element.style.backgroundImage = 'url("' + this.Reveal.getConfig().parallaxBackgroundImage + '")';
+			this.element.style.backgroundSize = this.Reveal.getConfig().parallaxBackgroundSize;
+			this.element.style.backgroundRepeat = this.Reveal.getConfig().parallaxBackgroundRepeat;
+			this.element.style.backgroundPosition = this.Reveal.getConfig().parallaxBackgroundPosition;
+
+			// 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( () => {
+				this.Reveal.getRevealElement().classList.add( 'has-parallax-background' );
+			}, 1 );
+
+		}
+		else {
+
+			this.element.style.backgroundImage = '';
+			this.Reveal.getRevealElement().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
+	 * @return {HTMLElement} New background div
+	 */
+	createBackground( slide, container ) {
+
+		// Main slide background element
+		let element = document.createElement( 'div' );
+		element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );
+
+		// Inner background element that wraps images/videos/iframes
+		let contentElement = document.createElement( 'div' );
+		contentElement.className = 'slide-background-content';
+
+		element.appendChild( contentElement );
+		container.appendChild( element );
+
+		slide.slideBackgroundElement = element;
+		slide.slideBackgroundContentElement = contentElement;
+
+		// Syncs the background to reflect all current background settings
+		this.sync( slide );
+
+		return element;
+
+	}
+
+	/**
+	 * Renders all of the visual properties of a slide background
+	 * based on the various background attributes.
+	 *
+	 * @param {HTMLElement} slide
+	 */
+	sync( slide ) {
+
+		const element = slide.slideBackgroundElement,
+			contentElement = slide.slideBackgroundContentElement;
+
+		const 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' ),
+			backgroundOpacity: slide.getAttribute( 'data-background-opacity' ),
+		};
+
+		const dataPreload = slide.hasAttribute( 'data-preload' );
+
+		// Reset the prior background state in case this is not the
+		// initial sync
+		slide.classList.remove( 'has-dark-background' );
+		slide.classList.remove( 'has-light-background' );
+
+		element.removeAttribute( 'data-loaded' );
+		element.removeAttribute( 'data-background-hash' );
+		element.removeAttribute( 'data-background-size' );
+		element.removeAttribute( 'data-background-transition' );
+		element.style.backgroundColor = '';
+
+		contentElement.style.backgroundSize = '';
+		contentElement.style.backgroundRepeat = '';
+		contentElement.style.backgroundPosition = '';
+		contentElement.style.backgroundImage = '';
+		contentElement.style.opacity = '';
+		contentElement.innerHTML = '';
+
+		if( data.background ) {
+			// Auto-wrap image urls in url(...)
+			if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/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 +
+															data.backgroundOpacity );
+		}
+
+		// Additional and optional background properties
+		if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
+		if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
+		if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
+
+		if( dataPreload ) element.setAttribute( 'data-preload', '' );
+
+		// Background image options are set on the content wrapper
+		if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;
+		if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;
+		if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
+		if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
+
+		// If this slide has a background color, we add a class that
+		// signals if it is light or dark. If the slide has no background
+		// color, no class will be added
+		let contrastColor = data.backgroundColor;
+
+		// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
+		if( !contrastColor || !colorToRgb( contrastColor ) ) {
+			let computedBackgroundStyle = window.getComputedStyle( element );
+			if( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {
+				contrastColor = computedBackgroundStyle.backgroundColor;
+			}
+		}
+
+		if( contrastColor ) {
+			const rgb = colorToRgb( contrastColor );
+
+			// 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( contrastColor ) < 128 ) {
+					slide.classList.add( 'has-dark-background' );
+				}
+				else {
+					slide.classList.add( 'has-light-background' );
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * 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.
+	 */
+	update( includeAll = false ) {
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		let indices = this.Reveal.getIndices();
+
+		let currentBackground = null;
+
+		// Reverse past/future classes when in RTL mode
+		let horizontalPast = this.Reveal.getConfig().rtl ? 'future' : 'past',
+			horizontalFuture = this.Reveal.getConfig().rtl ? 'past' : 'future';
+
+		// Update the classes of all backgrounds to match the
+		// states of their slides (past/present/future)
+		Array.from( this.element.childNodes ).forEach( ( backgroundh, h ) => {
+
+			backgroundh.classList.remove( 'past', 'present', 'future' );
+
+			if( h < indices.h ) {
+				backgroundh.classList.add( horizontalPast );
+			}
+			else if ( h > indices.h ) {
+				backgroundh.classList.add( horizontalFuture );
+			}
+			else {
+				backgroundh.classList.add( 'present' );
+
+				// Store a reference to the current background element
+				currentBackground = backgroundh;
+			}
+
+			if( includeAll || h === indices.h ) {
+				queryAll( backgroundh, '.slide-background' ).forEach( ( backgroundv, v ) => {
+
+					backgroundv.classList.remove( 'past', 'present', 'future' );
+
+					if( v < indices.v ) {
+						backgroundv.classList.add( 'past' );
+					}
+					else if ( v > indices.v ) {
+						backgroundv.classList.add( 'future' );
+					}
+					else {
+						backgroundv.classList.add( 'present' );
+
+						// Only if this is the present horizontal and vertical slide
+						if( h === indices.h ) currentBackground = backgroundv;
+					}
+
+				} );
+			}
+
+		} );
+
+		// Stop content inside of previous backgrounds
+		if( this.previousBackground ) {
+
+			this.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );
+
+		}
+
+		// Start content in the current background
+		if( currentBackground ) {
+
+			this.Reveal.slideContent.startEmbeddedContent( currentBackground );
+
+			let currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' );
+			if( currentBackgroundContent ) {
+
+				let backgroundImageURL = currentBackgroundContent.style.backgroundImage || '';
+
+				// Restart GIFs (doesn't work in Firefox)
+				if( /\.gif/i.test( backgroundImageURL ) ) {
+					currentBackgroundContent.style.backgroundImage = '';
+					window.getComputedStyle( currentBackgroundContent ).opacity;
+					currentBackgroundContent.style.backgroundImage = backgroundImageURL;
+				}
+
+			}
+
+			// Don't transition between identical backgrounds. This
+			// prevents unwanted flicker.
+			let previousBackgroundHash = this.previousBackground ? this.previousBackground.getAttribute( 'data-background-hash' ) : null;
+			let currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
+			if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {
+				this.element.classList.add( 'no-transition' );
+			}
+
+			this.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( classToBubble => {
+				if( currentSlide.classList.contains( classToBubble ) ) {
+					this.Reveal.getRevealElement().classList.add( classToBubble );
+				}
+				else {
+					this.Reveal.getRevealElement().classList.remove( classToBubble );
+				}
+			}, this );
+		}
+
+		// Allow the first background to apply without transition
+		setTimeout( () => {
+			this.element.classList.remove( 'no-transition' );
+		}, 1 );
+
+	}
+
+	/**
+	 * Updates the position of the parallax background based
+	 * on the current slide index.
+	 */
+	updateParallax() {
+
+		let indices = this.Reveal.getIndices();
+
+		if( this.Reveal.getConfig().parallaxBackgroundImage ) {
+
+			let horizontalSlides = this.Reveal.getHorizontalSlides(),
+				verticalSlides = this.Reveal.getVerticalSlides();
+
+			let backgroundSize = this.element.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 );
+			}
+
+			let slideWidth = this.element.offsetWidth,
+				horizontalSlideCount = horizontalSlides.length,
+				horizontalOffsetMultiplier,
+				horizontalOffset;
+
+			if( typeof this.Reveal.getConfig().parallaxBackgroundHorizontal === 'number' ) {
+				horizontalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundHorizontal;
+			}
+			else {
+				horizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0;
+			}
+
+			horizontalOffset = horizontalOffsetMultiplier * indices.h * -1;
+
+			let slideHeight = this.element.offsetHeight,
+				verticalSlideCount = verticalSlides.length,
+				verticalOffsetMultiplier,
+				verticalOffset;
+
+			if( typeof this.Reveal.getConfig().parallaxBackgroundVertical === 'number' ) {
+				verticalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundVertical;
+			}
+			else {
+				verticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 );
+			}
+
+			verticalOffset = verticalSlideCount > 0 ?  verticalOffsetMultiplier * indices.v : 0;
+
+			this.element.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px';
+
+		}
+
+	}
+
+}
diff --git a/inst/reveal.js-4.2.1/js/controllers/controls.js b/inst/reveal.js-4.2.1/js/controllers/controls.js
new file mode 100644
index 0000000..556bcf0
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/controls.js
@@ -0,0 +1,259 @@
+import { queryAll } from '../utils/util.js'
+import { isAndroid } from '../utils/device.js'
+
+/**
+ * Manages our presentation controls. This includes both
+ * the built-in control arrows as well as event monitoring
+ * of any elements within the presentation with either of the
+ * following helper classes:
+ * - .navigate-up
+ * - .navigate-right
+ * - .navigate-down
+ * - .navigate-left
+ * - .navigate-next
+ * - .navigate-prev
+ */
+export default class Controls {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.onNavigateLeftClicked = this.onNavigateLeftClicked.bind( this );
+		this.onNavigateRightClicked = this.onNavigateRightClicked.bind( this );
+		this.onNavigateUpClicked = this.onNavigateUpClicked.bind( this );
+		this.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );
+		this.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );
+		this.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );
+
+	}
+
+	render() {
+
+		const rtl = this.Reveal.getConfig().rtl;
+		const revealElement = this.Reveal.getRevealElement();
+
+		this.element = document.createElement( 'aside' );
+		this.element.className = 'controls';
+		this.element.innerHTML =
+			`<button class="navigate-left" aria-label="${ rtl ? 'next slide' : 'previous slide' }"><div class="controls-arrow"></div></button>
+			<button class="navigate-right" aria-label="${ rtl ? 'previous slide' : 'next slide' }"><div class="controls-arrow"></div></button>
+			<button class="navigate-up" aria-label="above slide"><div class="controls-arrow"></div></button>
+			<button class="navigate-down" aria-label="below slide"><div class="controls-arrow"></div></button>`;
+
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+		// There can be multiple instances of controls throughout the page
+		this.controlsLeft = queryAll( revealElement, '.navigate-left' );
+		this.controlsRight = queryAll( revealElement, '.navigate-right' );
+		this.controlsUp = queryAll( revealElement, '.navigate-up' );
+		this.controlsDown = queryAll( revealElement, '.navigate-down' );
+		this.controlsPrev = queryAll( revealElement, '.navigate-prev' );
+		this.controlsNext = queryAll( revealElement, '.navigate-next' );
+
+		// The left, right and down arrows in the standard reveal.js controls
+		this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
+		this.controlsLeftArrow = this.element.querySelector( '.navigate-left' );
+		this.controlsDownArrow = this.element.querySelector( '.navigate-down' );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		this.element.style.display = config.controls ? 'block' : 'none';
+
+		this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
+		this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
+
+	}
+
+	bind() {
+
+		// Listen to both touch and click events, in case the device
+		// supports both
+		let pointerEvents = [ 'touchstart', 'click' ];
+
+		// Only support touch for Android, fixes double navigations in
+		// stock browser
+		if( isAndroid ) {
+			pointerEvents = [ 'touchstart' ];
+		}
+
+		pointerEvents.forEach( eventName => {
+			this.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );
+			this.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );
+			this.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );
+			this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
+			this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
+			this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
+		} );
+
+	}
+
+	unbind() {
+
+		[ 'touchstart', 'click' ].forEach( eventName => {
+			this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
+			this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
+			this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
+			this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
+			this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
+			this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
+		} );
+
+	}
+
+	/**
+	 * Updates the state of all control/navigation arrows.
+	 */
+	update() {
+
+		let routes = this.Reveal.availableRoutes();
+
+		// Remove the 'enabled' class from all directions
+		[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {
+			node.classList.remove( 'enabled', 'fragmented' );
+
+			// Set 'disabled' attribute on all directions
+			node.setAttribute( 'disabled', 'disabled' );
+		} );
+
+		// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons
+		if( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+		// Prev/next buttons
+		if( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+		if( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+		// Highlight fragment directions
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide ) {
+
+			let fragmentsRoutes = this.Reveal.fragments.availableRoutes();
+
+			// Always apply fragment decorator to prev/next buttons
+			if( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			if( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+
+			// Apply fragment decorators to directional buttons based on
+			// what slide axis they are in
+			if( this.Reveal.isVerticalSlide( currentSlide ) ) {
+				if( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+				if( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			}
+			else {
+				if( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+				if( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
+			}
+
+		}
+
+		if( this.Reveal.getConfig().controlsTutorial ) {
+
+			let indices = this.Reveal.getIndices();
+
+			// Highlight control arrows with an animation to ensure
+			// that the viewer knows how to navigate
+			if( !this.Reveal.hasNavigatedVertically() && routes.down ) {
+				this.controlsDownArrow.classList.add( 'highlight' );
+			}
+			else {
+				this.controlsDownArrow.classList.remove( 'highlight' );
+
+				if( this.Reveal.getConfig().rtl ) {
+
+					if( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {
+						this.controlsLeftArrow.classList.add( 'highlight' );
+					}
+					else {
+						this.controlsLeftArrow.classList.remove( 'highlight' );
+					}
+
+				} else {
+
+					if( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {
+						this.controlsRightArrow.classList.add( 'highlight' );
+					}
+					else {
+						this.controlsRightArrow.classList.remove( 'highlight' );
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Event handlers for navigation control buttons.
+	 */
+	onNavigateLeftClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		if( this.Reveal.getConfig().navigationMode === 'linear' ) {
+			this.Reveal.prev();
+		}
+		else {
+			this.Reveal.left();
+		}
+
+	}
+
+	onNavigateRightClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		if( this.Reveal.getConfig().navigationMode === 'linear' ) {
+			this.Reveal.next();
+		}
+		else {
+			this.Reveal.right();
+		}
+
+	}
+
+	onNavigateUpClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.up();
+
+	}
+
+	onNavigateDownClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.down();
+
+	}
+
+	onNavigatePrevClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.prev();
+
+	}
+
+	onNavigateNextClicked( event ) {
+
+		event.preventDefault();
+		this.Reveal.onUserInput();
+
+		this.Reveal.next();
+
+	}
+
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/focus.js b/inst/reveal.js-4.2.1/js/controllers/focus.js
new file mode 100644
index 0000000..2191807
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/focus.js
@@ -0,0 +1,97 @@
+import { closest } from '../utils/util.js'
+
+/**
+ * Manages focus when a presentation is embedded. This
+ * helps us only capture keyboard from the presentation
+ * a user is currently interacting with in a page where
+ * multiple presentations are embedded.
+ */
+
+const STATE_FOCUS = 'focus';
+const STATE_BLUR = 'blur';
+
+export default class Focus {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.onRevealPointerDown = this.onRevealPointerDown.bind( this );
+		this.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.embedded ) {
+			this.blur();
+		}
+		else {
+			this.focus();
+			this.unbind();
+		}
+
+	}
+
+	bind() {
+
+		if( this.Reveal.getConfig().embedded ) {
+			this.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );
+		}
+
+	}
+
+	unbind() {
+
+		this.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );
+		document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+
+	}
+
+	focus() {
+
+		if( this.state !== STATE_FOCUS ) {
+			this.Reveal.getRevealElement().classList.add( 'focused' );
+			document.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+		}
+
+		this.state = STATE_FOCUS;
+
+	}
+
+	blur() {
+
+		if( this.state !== STATE_BLUR ) {
+			this.Reveal.getRevealElement().classList.remove( 'focused' );
+			document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
+		}
+
+		this.state = STATE_BLUR;
+
+	}
+
+	isFocused() {
+
+		return this.state === STATE_FOCUS;
+
+	}
+
+	onRevealPointerDown( event ) {
+
+		this.focus();
+
+	}
+
+	onDocumentPointerDown( event ) {
+
+		let revealElement = closest( event.target, '.reveal' );
+		if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
+			this.blur();
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/fragments.js b/inst/reveal.js-4.2.1/js/controllers/fragments.js
new file mode 100644
index 0000000..796c168
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/fragments.js
@@ -0,0 +1,376 @@
+import { extend, queryAll } from '../utils/util.js'
+
+/**
+ * Handles sorting and navigation of slide fragments.
+ * Fragments are elements within a slide that are
+ * revealed/animated incrementally.
+ */
+export default class Fragments {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.fragments === false ) {
+			this.disable();
+		}
+		else if( oldConfig.fragments === false ) {
+			this.enable();
+		}
+
+	}
+
+	/**
+	 * If fragments are disabled in the deck, they should all be
+	 * visible rather than stepped through.
+	 */
+	disable() {
+
+		queryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {
+			element.classList.add( 'visible' );
+			element.classList.remove( 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Reverse of #disable(). Only called if fragments have
+	 * previously been disabled.
+	 */
+	enable() {
+
+		queryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {
+			element.classList.remove( 'visible' );
+			element.classList.remove( 'current-fragment' );
+		} );
+
+	}
+
+	/**
+	 * Returns an object describing the available fragment
+	 * directions.
+	 *
+	 * @return {{prev: boolean, next: boolean}}
+	 */
+	availableRoutes() {
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide && this.Reveal.getConfig().fragments ) {
+			let fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );
+			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );
+
+			return {
+				prev: fragments.length - hiddenFragments.length > 0,
+				next: !!hiddenFragments.length
+			};
+		}
+		else {
+			return { prev: false, next: false };
+		}
+
+	}
+
+	/**
+	 * Return a sorted fragments list, ordered by an increasing
+	 * "data-fragment-index" attribute.
+	 *
+	 * Fragments will be revealed in the order that they are returned by
+	 * this function, so you can use the index attributes to control the
+	 * order of fragment appearance.
+	 *
+	 * To maintain a sensible default fragment order, fragments are presumed
+	 * to be passed in document order. This function adds a "fragment-index"
+	 * attribute to each node if such an attribute is not already present,
+	 * and sets that attribute to an integer value which is the position of
+	 * the fragment within the fragments list.
+	 *
+	 * @param {object[]|*} fragments
+	 * @param {boolean} grouped If true the returned array will contain
+	 * nested arrays for all fragments with the same index
+	 * @return {object[]} sorted Sorted array of fragments
+	 */
+	sort( fragments, grouped = false ) {
+
+		fragments = Array.from( fragments );
+
+		let ordered = [],
+			unordered = [],
+			sorted = [];
+
+		// Group ordered and unordered elements
+		fragments.forEach( fragment => {
+			if( fragment.hasAttribute( 'data-fragment-index' ) ) {
+				let index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
+
+				if( !ordered[index] ) {
+					ordered[index] = [];
+				}
+
+				ordered[index].push( fragment );
+			}
+			else {
+				unordered.push( [ fragment ] );
+			}
+		} );
+
+		// Append fragments without explicit indices in their
+		// DOM order
+		ordered = ordered.concat( unordered );
+
+		// Manually count the index up per group to ensure there
+		// are no gaps
+		let index = 0;
+
+		// Push all fragments in their sorted order to an array,
+		// this flattens the groups
+		ordered.forEach( group => {
+			group.forEach( fragment => {
+				sorted.push( fragment );
+				fragment.setAttribute( 'data-fragment-index', index );
+			} );
+
+			index ++;
+		} );
+
+		return grouped === true ? ordered : sorted;
+
+	}
+
+	/**
+	 * Sorts and formats all of fragments in the
+	 * presentation.
+	 */
+	sortAll() {
+
+		this.Reveal.getHorizontalSlides().forEach( horizontalSlide => {
+
+			let verticalSlides = queryAll( horizontalSlide, 'section' );
+			verticalSlides.forEach( ( verticalSlide, y ) => {
+
+				this.sort( verticalSlide.querySelectorAll( '.fragment' ) );
+
+			}, this );
+
+			if( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) );
+
+		} );
+
+	}
+
+	/**
+	 * Refreshes the fragments on the current slide so that they
+	 * have the appropriate classes (.visible + .current-fragment).
+	 *
+	 * @param {number} [index] The index of the current fragment
+	 * @param {array} [fragments] Array containing all fragments
+	 * in the current slide
+	 *
+	 * @return {{shown: array, hidden: array}}
+	 */
+	update( index, fragments ) {
+
+		let changedFragments = {
+			shown: [],
+			hidden: []
+		};
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide && this.Reveal.getConfig().fragments ) {
+
+			fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );
+
+			if( fragments.length ) {
+
+				let maxIndex = 0;
+
+				if( typeof index !== 'number' ) {
+					let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+					if( currentFragment ) {
+						index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+				}
+
+				Array.from( fragments ).forEach( ( el, i ) => {
+
+					if( el.hasAttribute( 'data-fragment-index' ) ) {
+						i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );
+					}
+
+					maxIndex = Math.max( maxIndex, i );
+
+					// Visible fragments
+					if( i <= index ) {
+						let wasVisible = el.classList.contains( 'visible' )
+						el.classList.add( 'visible' );
+						el.classList.remove( 'current-fragment' );
+
+						if( i === index ) {
+							// Announce the fragments one by one to the Screen Reader
+							this.Reveal.announceStatus( this.Reveal.getStatusText( el ) );
+
+							el.classList.add( 'current-fragment' );
+							this.Reveal.slideContent.startEmbeddedContent( el );
+						}
+
+						if( !wasVisible ) {
+							changedFragments.shown.push( el )
+							this.Reveal.dispatchEvent({
+								target: el,
+								type: 'visible',
+								bubbles: false
+							});
+						}
+					}
+					// Hidden fragments
+					else {
+						let wasVisible = el.classList.contains( 'visible' )
+						el.classList.remove( 'visible' );
+						el.classList.remove( 'current-fragment' );
+
+						if( wasVisible ) {
+							this.Reveal.slideContent.stopEmbeddedContent( el );
+							changedFragments.hidden.push( el );
+							this.Reveal.dispatchEvent({
+								target: el,
+								type: 'hidden',
+								bubbles: false
+							});
+						}
+					}
+
+				} );
+
+				// Write the current fragment index to the slide <section>.
+				// This can be used by end users to apply styles based on
+				// the current fragment index.
+				index = typeof index === 'number' ? index : -1;
+				index = Math.max( Math.min( index, maxIndex ), -1 );
+				currentSlide.setAttribute( 'data-fragment', index );
+
+			}
+
+		}
+
+		return changedFragments;
+
+	}
+
+	/**
+	 * Formats the fragments on the given slide so that they have
+	 * valid indices. Call this if fragments are changed in the DOM
+	 * after reveal.js has already initialized.
+	 *
+	 * @param {HTMLElement} slide
+	 * @return {Array} a list of the HTML fragments that were synced
+	 */
+	sync( slide = this.Reveal.getCurrentSlide() ) {
+
+		return this.sort( slide.querySelectorAll( '.fragment' ) );
+
+	}
+
+	/**
+	 * Navigate to the specified slide fragment.
+	 *
+	 * @param {?number} index The index of the fragment that
+	 * should be shown, -1 means all are invisible
+	 * @param {number} offset Integer offset to apply to the
+	 * fragment index
+	 *
+	 * @return {boolean} true if a change was made in any
+	 * fragments visibility as part of this call
+	 */
+	goto( index, offset = 0 ) {
+
+		let currentSlide = this.Reveal.getCurrentSlide();
+		if( currentSlide && this.Reveal.getConfig().fragments ) {
+
+			let fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );
+			if( fragments.length ) {
+
+				// If no index is specified, find the current
+				if( typeof index !== 'number' ) {
+					let lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();
+
+					if( lastVisibleFragment ) {
+						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+					else {
+						index = -1;
+					}
+				}
+
+				// Apply the offset if there is one
+				index += offset;
+
+				let changedFragments = this.update( index, fragments );
+
+				if( changedFragments.hidden.length ) {
+					this.Reveal.dispatchEvent({
+						type: 'fragmenthidden',
+						data: {
+							fragment: changedFragments.hidden[0],
+							fragments: changedFragments.hidden
+						}
+					});
+				}
+
+				if( changedFragments.shown.length ) {
+					this.Reveal.dispatchEvent({
+						type: 'fragmentshown',
+						data: {
+							fragment: changedFragments.shown[0],
+							fragments: changedFragments.shown
+						}
+					});
+				}
+
+				this.Reveal.controls.update();
+				this.Reveal.progress.update();
+
+				if( this.Reveal.getConfig().fragmentInURL ) {
+					this.Reveal.location.writeURL();
+				}
+
+				return !!( changedFragments.shown.length || changedFragments.hidden.length );
+
+			}
+
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Navigate to the next slide fragment.
+	 *
+	 * @return {boolean} true if there was a next fragment,
+	 * false otherwise
+	 */
+	next() {
+
+		return this.goto( null, 1 );
+
+	}
+
+	/**
+	 * Navigate to the previous slide fragment.
+	 *
+	 * @return {boolean} true if there was a previous fragment,
+	 * false otherwise
+	 */
+	prev() {
+
+		return this.goto( null, -1 );
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/keyboard.js b/inst/reveal.js-4.2.1/js/controllers/keyboard.js
new file mode 100644
index 0000000..4e013a3
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/keyboard.js
@@ -0,0 +1,392 @@
+import { enterFullscreen } from '../utils/util.js'
+
+/**
+ * Handles all reveal.js keyboard interactions.
+ */
+export default class Keyboard {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// A key:value map of keyboard keys and descriptions of
+		// the actions they trigger
+		this.shortcuts = {};
+
+		// Holds custom key code mappings
+		this.bindings = {};
+
+		this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
+		this.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.navigationMode === 'linear' ) {
+			this.shortcuts['&#8594;  ,  &#8595;  ,  SPACE  ,  N  ,  L  ,  J'] = 'Next slide';
+			this.shortcuts['&#8592;  ,  &#8593;  ,  P  ,  H  ,  K']           = 'Previous slide';
+		}
+		else {
+			this.shortcuts['N  ,  SPACE']   = 'Next slide';
+			this.shortcuts['P  ,  Shift SPACE']             = 'Previous slide';
+			this.shortcuts['&#8592;  ,  H'] = 'Navigate left';
+			this.shortcuts['&#8594;  ,  L'] = 'Navigate right';
+			this.shortcuts['&#8593;  ,  K'] = 'Navigate up';
+			this.shortcuts['&#8595;  ,  J'] = 'Navigate down';
+		}
+
+		this.shortcuts['Alt + &#8592;/&#8593/&#8594;/&#8595;']        = 'Navigate without fragments';
+		this.shortcuts['Shift + &#8592;/&#8593/&#8594;/&#8595;']      = 'Jump to first/last slide';
+		this.shortcuts['B  ,  .']                       = 'Pause';
+		this.shortcuts['F']                             = 'Fullscreen';
+		this.shortcuts['ESC, O']                        = 'Slide overview';
+
+	}
+
+	/**
+	 * Starts listening for keyboard events.
+	 */
+	bind() {
+
+		document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
+		document.addEventListener( 'keypress', this.onDocumentKeyPress, false );
+
+	}
+
+	/**
+	 * Stops listening for keyboard events.
+	 */
+	unbind() {
+
+		document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
+		document.removeEventListener( 'keypress', this.onDocumentKeyPress, false );
+
+	}
+
+	/**
+	 * Add a custom key binding with optional description to
+	 * be added to the help screen.
+	 */
+	addKeyBinding( binding, callback ) {
+
+		if( typeof binding === 'object' && binding.keyCode ) {
+			this.bindings[binding.keyCode] = {
+				callback: callback,
+				key: binding.key,
+				description: binding.description
+			};
+		}
+		else {
+			this.bindings[binding] = {
+				callback: callback,
+				key: null,
+				description: null
+			};
+		}
+
+	}
+
+	/**
+	 * Removes the specified custom key binding.
+	 */
+	removeKeyBinding( keyCode ) {
+
+		delete this.bindings[keyCode];
+
+	}
+
+	/**
+	 * Programmatically triggers a keyboard event
+	 *
+	 * @param {int} keyCode
+	 */
+	triggerKey( keyCode ) {
+
+		this.onDocumentKeyDown( { keyCode } );
+
+	}
+
+	/**
+	 * Registers a new shortcut to include in the help overlay
+	 *
+	 * @param {String} key
+	 * @param {String} value
+	 */
+	registerKeyboardShortcut( key, value ) {
+
+		this.shortcuts[key] = value;
+
+	}
+
+	getShortcuts() {
+
+		return this.shortcuts;
+
+	}
+
+	getBindings() {
+
+		return this.bindings;
+
+	}
+
+	/**
+	 * Handler for the document level 'keypress' event.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentKeyPress( event ) {
+
+		// Check if the pressed key is question mark
+		if( event.shiftKey && event.charCode === 63 ) {
+			this.Reveal.toggleHelp();
+		}
+
+	}
+
+	/**
+	 * Handler for the document level 'keydown' event.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentKeyDown( event ) {
+
+		let config = this.Reveal.getConfig();
+
+		// If there's a condition specified and it returns false,
+		// ignore this event
+		if( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {
+			return true;
+		}
+
+		// If keyboardCondition is set, only capture keyboard events
+		// for embedded decks when they are focused
+		if( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {
+			return true;
+		}
+
+		// Shorthand
+		let keyCode = event.keyCode;
+
+		// Remember if auto-sliding was paused so we can toggle it
+		let autoSlideWasPaused = !this.Reveal.isAutoSliding();
+
+		this.Reveal.onUserInput( event );
+
+		// Is there a focused element that could be using the keyboard?
+		let activeElementIsCE = document.activeElement && document.activeElement.isContentEditable === true;
+		let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
+		let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
+
+		// Whitelist certain modifiers for slide navigation shortcuts
+		let isNavigationKey = [32, 37, 38, 39, 40, 78, 80].indexOf( event.keyCode ) !== -1;
+
+		// Prevent all other events when a modifier is pressed
+		let unusedModifier = 	!( isNavigationKey && event.shiftKey || event.altKey ) &&
+								( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
+
+		// Disregard the event if there's a focused element or a
+		// keyboard modifier key is present
+		if( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;
+
+		// While paused only allow resume keyboard events; 'b', 'v', '.'
+		let resumeKeyCodes = [66,86,190,191];
+		let key;
+
+		// Custom key bindings for togglePause should be able to resume
+		if( typeof config.keyboard === 'object' ) {
+			for( key in config.keyboard ) {
+				if( config.keyboard[key] === 'togglePause' ) {
+					resumeKeyCodes.push( parseInt( key, 10 ) );
+				}
+			}
+		}
+
+		if( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {
+			return false;
+		}
+
+		// Use linear navigation if we're configured to OR if
+		// the presentation is one-dimensional
+		let useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();
+
+		let triggered = false;
+
+		// 1. User defined key bindings
+		if( typeof config.keyboard === 'object' ) {
+
+			for( key in config.keyboard ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === keyCode ) {
+
+					let value = config.keyboard[ key ];
+
+					// Callback function
+					if( typeof value === 'function' ) {
+						value.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {
+						this.Reveal[ value ].call();
+					}
+
+					triggered = true;
+
+				}
+
+			}
+
+		}
+
+		// 2. Registered custom key bindings
+		if( triggered === false ) {
+
+			for( key in this.bindings ) {
+
+				// Check if this binding matches the pressed key
+				if( parseInt( key, 10 ) === keyCode ) {
+
+					let action = this.bindings[ key ].callback;
+
+					// Callback function
+					if( typeof action === 'function' ) {
+						action.apply( null, [ event ] );
+					}
+					// String shortcuts to reveal.js API
+					else if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {
+						this.Reveal[ action ].call();
+					}
+
+					triggered = true;
+				}
+			}
+		}
+
+		// 3. System defined key bindings
+		if( triggered === false ) {
+
+			// Assume true and try to prove false
+			triggered = true;
+
+			// P, PAGE UP
+			if( keyCode === 80 || keyCode === 33 ) {
+				this.Reveal.prev({skipFragments: event.altKey});
+			}
+			// N, PAGE DOWN
+			else if( keyCode === 78 || keyCode === 34 ) {
+				this.Reveal.next({skipFragments: event.altKey});
+			}
+			// H, LEFT
+			else if( keyCode === 72 || keyCode === 37 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( 0 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.prev({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.left({skipFragments: event.altKey});
+				}
+			}
+			// L, RIGHT
+			else if( keyCode === 76 || keyCode === 39 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.next({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.right({skipFragments: event.altKey});
+				}
+			}
+			// K, UP
+			else if( keyCode === 75 || keyCode === 38 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( undefined, 0 );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.prev({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.up({skipFragments: event.altKey});
+				}
+			}
+			// J, DOWN
+			else if( keyCode === 74 || keyCode === 40 ) {
+				if( event.shiftKey ) {
+					this.Reveal.slide( undefined, Number.MAX_VALUE );
+				}
+				else if( !this.Reveal.overview.isActive() && useLinearMode ) {
+					this.Reveal.next({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.down({skipFragments: event.altKey});
+				}
+			}
+			// HOME
+			else if( keyCode === 36 ) {
+				this.Reveal.slide( 0 );
+			}
+			// END
+			else if( keyCode === 35 ) {
+				this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
+			}
+			// SPACE
+			else if( keyCode === 32 ) {
+				if( this.Reveal.overview.isActive() ) {
+					this.Reveal.overview.deactivate();
+				}
+				if( event.shiftKey ) {
+					this.Reveal.prev({skipFragments: event.altKey});
+				}
+				else {
+					this.Reveal.next({skipFragments: event.altKey});
+				}
+			}
+			// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
+			else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
+				this.Reveal.togglePause();
+			}
+			// F
+			else if( keyCode === 70 ) {
+				enterFullscreen( config.embedded ? this.Reveal.getViewportElement() : document.documentElement );
+			}
+			// A
+			else if( keyCode === 65 ) {
+				if ( config.autoSlideStoppable ) {
+					this.Reveal.toggleAutoSlide( autoSlideWasPaused );
+				}
+			}
+			else {
+				triggered = false;
+			}
+
+		}
+
+		// If the input resulted in a triggered action we should prevent
+		// the browsers default behavior
+		if( triggered ) {
+			event.preventDefault && event.preventDefault();
+		}
+		// ESC or O key
+		else if( keyCode === 27 || keyCode === 79 ) {
+			if( this.Reveal.closeOverlay() === false ) {
+				this.Reveal.overview.toggle();
+			}
+
+			event.preventDefault && event.preventDefault();
+		}
+
+		// If auto-sliding is enabled we need to cue up
+		// another timeout
+		this.Reveal.cueAutoSlide();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/location.js b/inst/reveal.js-4.2.1/js/controllers/location.js
new file mode 100644
index 0000000..ec86e65
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/location.js
@@ -0,0 +1,219 @@
+/**
+ * Reads and writes the URL based on reveal.js' current state.
+ */
+export default class Location {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Delays updates to the URL due to a Chrome thumbnailer bug
+		this.writeURLTimeout = 0;
+
+		this.onWindowHashChange = this.onWindowHashChange.bind( this );
+
+	}
+
+	bind() {
+
+		window.addEventListener( 'hashchange', this.onWindowHashChange, false );
+
+	}
+
+	unbind() {
+
+		window.removeEventListener( 'hashchange', this.onWindowHashChange, false );
+
+	}
+
+	/**
+	 * Returns the slide indices for the given hash link.
+	 *
+	 * @param {string} [hash] the hash string that we want to
+	 * find the indices for
+	 *
+	 * @returns slide indices or null
+	 */
+	getIndicesFromHash( hash=window.location.hash ) {
+
+		// Attempt to parse the hash as either an index or name
+		let name = hash.replace( /^#\/?/, '' );
+		let bits = name.split( '/' );
+
+		// If the first bit is not fully numeric and there is a name we
+		// can assume that this is a named link
+		if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
+			let element;
+
+			let f;
+
+			// Parse named links with fragments (#/named-link/2)
+			if( /\/[-\d]+$/g.test( name ) ) {
+				f = parseInt( name.split( '/' ).pop(), 10 );
+				f = isNaN(f) ? undefined : f;
+				name = name.split( '/' ).shift();
+			}
+
+			// Ensure the named link is a valid HTML ID attribute
+			try {
+				element = document.getElementById( decodeURIComponent( name ) );
+			}
+			catch ( error ) { }
+
+			if( element ) {
+				return { ...this.Reveal.getIndices( element ), f };
+			}
+		}
+		else {
+			const config = this.Reveal.getConfig();
+			let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
+
+			// Read the index components of the hash
+			let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
+				v = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0,
+				f;
+
+			if( config.fragmentInURL ) {
+				f = parseInt( bits[2], 10 );
+				if( isNaN( f ) ) {
+					f = undefined;
+				}
+			}
+
+			return { h, v, f };
+		}
+
+		// The hash couldn't be parsed or no matching named link was found
+		return null
+
+	}
+
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	readURL() {
+
+		const currentIndices = this.Reveal.getIndices();
+		const newIndices = this.getIndicesFromHash();
+
+		if( newIndices ) {
+			if( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
+					this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
+			}
+		}
+		// If no new indices are available, we're trying to navigate to
+		// a slide hash that does not exist
+		else {
+			this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
+		}
+
+	}
+
+	/**
+	 * Updates the page URL (hash) to reflect the current
+	 * state.
+	 *
+	 * @param {number} delay The time in ms to wait before
+	 * writing the hash
+	 */
+	writeURL( delay ) {
+
+		let config = this.Reveal.getConfig();
+		let currentSlide = this.Reveal.getCurrentSlide();
+
+		// Make sure there's never more than one timeout running
+		clearTimeout( this.writeURLTimeout );
+
+		// If a delay is specified, timeout this call
+		if( typeof delay === 'number' ) {
+			this.writeURLTimeout = setTimeout( this.writeURL, delay );
+		}
+		else if( currentSlide ) {
+
+			let hash = this.getHash();
+
+			// If we're configured to push to history OR the history
+			// API is not avaialble.
+			if( config.history ) {
+				window.location.hash = hash;
+			}
+			// If we're configured to reflect the current slide in the
+			// URL without pushing to history.
+			else if( config.hash ) {
+				// If the hash is empty, don't add it to the URL
+				if( hash === '/' ) {
+					window.history.replaceState( null, null, window.location.pathname + window.location.search );
+				}
+				else {
+					window.history.replaceState( null, null, '#' + hash );
+				}
+			}
+			// UPDATE: The below nuking of all hash changes breaks
+			// anchors on pages where reveal.js is running. Removed
+			// in 4.0. Why was it here in the first place? ¯\_(ツ)_/¯
+			//
+			// If history and hash are both disabled, a hash may still
+			// be added to the URL by clicking on a href with a hash
+			// target. Counter this by always removing the hash.
+			// else {
+			// 	window.history.replaceState( null, null, window.location.pathname + window.location.search );
+			// }
+
+		}
+
+	}
+
+	/**
+	 * Return a hash URL that will resolve to the given slide location.
+	 *
+	 * @param {HTMLElement} [slide=currentSlide] The slide to link to
+	 */
+	getHash( slide ) {
+
+		let url = '/';
+
+		// Attempt to create a named link based on the slide's ID
+		let s = slide || this.Reveal.getCurrentSlide();
+		let id = s ? s.getAttribute( 'id' ) : null;
+		if( id ) {
+			id = encodeURIComponent( id );
+		}
+
+		let index = this.Reveal.getIndices( slide );
+		if( !this.Reveal.getConfig().fragmentInURL ) {
+			index.f = undefined;
+		}
+
+		// If the current slide has an ID, use that as a named link,
+		// but we don't support named links with a fragment index
+		if( typeof id === 'string' && id.length ) {
+			url = '/' + id;
+
+			// If there is also a fragment, append that at the end
+			// of the named link, like: #/named-link/2
+			if( index.f >= 0 ) url += '/' + index.f;
+		}
+		// Otherwise use the /h/v index
+		else {
+			let hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;
+			if( index.h > 0 || index.v > 0 || index.f >= 0 ) url += index.h + hashIndexBase;
+			if( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );
+			if( index.f >= 0 ) url += '/' + index.f;
+		}
+
+		return url;
+
+	}
+
+	/**
+	 * Handler for the window level 'hashchange' event.
+	 *
+	 * @param {object} [event]
+	 */
+	onWindowHashChange( event ) {
+
+		this.readURL();
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/notes.js b/inst/reveal.js-4.2.1/js/controllers/notes.js
new file mode 100644
index 0000000..8ec1d42
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/notes.js
@@ -0,0 +1,114 @@
+/**
+ * Handles the showing and 
+ */
+export default class Notes {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'speaker-notes';
+		this.element.setAttribute( 'data-prevent-swipe', '' );
+		this.element.setAttribute( 'tabindex', '0' );
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.showNotes ) {
+			this.element.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' );
+		}
+
+	}
+
+	/**
+	 * Pick up notes from the current slide and display them
+	 * to the viewer.
+	 *
+	 * @see {@link config.showNotes}
+	 */
+	update() {
+
+		if( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {
+
+			this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
+
+		}
+
+	}
+
+	/**
+	 * Updates the visibility of the speaker notes sidebar that
+	 * is used to share annotated slides. The notes sidebar is
+	 * only visible if showNotes is true and there are notes on
+	 * one or more slides in the deck.
+	 */
+	updateVisibility() {
+
+		if( this.Reveal.getConfig().showNotes && this.hasNotes() && !this.Reveal.print.isPrintingPDF() ) {
+			this.Reveal.getRevealElement().classList.add( 'show-notes' );
+		}
+		else {
+			this.Reveal.getRevealElement().classList.remove( 'show-notes' );
+		}
+
+	}
+
+	/**
+	 * Checks if there are speaker notes for ANY slide in the
+	 * presentation.
+	 */
+	hasNotes() {
+
+		return this.Reveal.getSlidesElement().querySelectorAll( '[data-notes], aside.notes' ).length > 0;
+
+	}
+
+	/**
+	 * Checks if this presentation is running inside of the
+	 * speaker notes window.
+	 *
+	 * @return {boolean}
+	 */
+	isSpeakerNotesWindow() {
+
+		return !!window.location.search.match( /receiver/gi );
+
+	}
+
+	/**
+	 * Retrieves the speaker notes from a slide. Notes can be
+	 * defined in two ways:
+	 * 1. As a data-notes attribute on the slide <section>
+	 * 2. As an <aside class="notes"> inside of the slide
+	 *
+	 * @param {HTMLElement} [slide=currentSlide]
+	 * @return {(string|null)}
+	 */
+	getSlideNotes( slide = this.Reveal.getCurrentSlide() ) {
+
+		// Notes can be specified via the data-notes attribute...
+		if( slide.hasAttribute( 'data-notes' ) ) {
+			return slide.getAttribute( 'data-notes' );
+		}
+
+		// ... or using an <aside class="notes"> element
+		let notesElement = slide.querySelector( 'aside.notes' );
+		if( notesElement ) {
+			return notesElement.innerHTML;
+		}
+
+		return null;
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/overview.js b/inst/reveal.js-4.2.1/js/controllers/overview.js
new file mode 100644
index 0000000..30e4c63
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/overview.js
@@ -0,0 +1,255 @@
+import { SLIDES_SELECTOR } from '../utils/constants.js'
+import { extend, queryAll, transformElement } from '../utils/util.js'
+
+/**
+ * Handles all logic related to the overview mode
+ * (birds-eye view of all slides).
+ */
+export default class Overview {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.active = false;
+
+		this.onSlideClicked = this.onSlideClicked.bind( this );
+
+	}
+
+	/**
+	 * Displays the overview of slides (quick nav) by scaling
+	 * down and arranging all slide elements.
+	 */
+	activate() {
+
+		// Only proceed if enabled in config
+		if( this.Reveal.getConfig().overview && !this.isActive() ) {
+
+			this.active = true;
+
+			this.Reveal.getRevealElement().classList.add( 'overview' );
+
+			// Don't auto-slide while in overview mode
+			this.Reveal.cancelAutoSlide();
+
+			// Move the backgrounds element into the slide container to
+			// that the same scaling is applied
+			this.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );
+
+			// Clicking on an overview slide navigates to it
+			queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {
+				if( !slide.classList.contains( 'stack' ) ) {
+					slide.addEventListener( 'click', this.onSlideClicked, true );
+				}
+			} );
+
+			// Calculate slide sizes
+			const margin = 70;
+			const slideSize = this.Reveal.getComputedSlideSize();
+			this.overviewSlideWidth = slideSize.width + margin;
+			this.overviewSlideHeight = slideSize.height + margin;
+
+			// Reverse in RTL mode
+			if( this.Reveal.getConfig().rtl ) {
+				this.overviewSlideWidth = -this.overviewSlideWidth;
+			}
+
+			this.Reveal.updateSlidesVisibility();
+
+			this.layout();
+			this.update();
+
+			this.Reveal.layout();
+
+			const indices = this.Reveal.getIndices();
+
+			// Notify observers of the overview showing
+			this.Reveal.dispatchEvent({
+				type: 'overviewshown',
+				data: {
+					'indexh': indices.h,
+					'indexv': indices.v,
+					'currentSlide': this.Reveal.getCurrentSlide()
+				}
+			});
+
+		}
+
+	}
+
+	/**
+	 * Uses CSS transforms to position all slides in a grid for
+	 * display inside of the overview mode.
+	 */
+	layout() {
+
+		// Layout slides
+		this.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {
+			hslide.setAttribute( 'data-index-h', h );
+			transformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
+
+			if( hslide.classList.contains( 'stack' ) ) {
+
+				queryAll( hslide, 'section' ).forEach( ( vslide, v ) => {
+					vslide.setAttribute( 'data-index-h', h );
+					vslide.setAttribute( 'data-index-v', v );
+
+					transformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
+				} );
+
+			}
+		} );
+
+		// Layout slide backgrounds
+		Array.from( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {
+			transformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
+
+			queryAll( hbackground, '.slide-background' ).forEach( ( vbackground, v ) => {
+				transformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
+			} );
+		} );
+
+	}
+
+	/**
+	 * Moves the overview viewport to the current slides.
+	 * Called each time the current slide changes.
+	 */
+	update() {
+
+		const vmin = Math.min( window.innerWidth, window.innerHeight );
+		const scale = Math.max( vmin / 5, 150 ) / vmin;
+		const indices = this.Reveal.getIndices();
+
+		this.Reveal.transformSlides( {
+			overview: [
+				'scale('+ scale +')',
+				'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',
+				'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'
+			].join( ' ' )
+		} );
+
+	}
+
+	/**
+	 * Exits the slide overview and enters the currently
+	 * active slide.
+	 */
+	deactivate() {
+
+		// Only proceed if enabled in config
+		if( this.Reveal.getConfig().overview ) {
+
+			this.active = false;
+
+			this.Reveal.getRevealElement().classList.remove( 'overview' );
+
+			// 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
+			this.Reveal.getRevealElement().classList.add( 'overview-deactivating' );
+
+			setTimeout( () => {
+				this.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );
+			}, 1 );
+
+			// Move the background element back out
+			this.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );
+
+			// Clean up changes made to slides
+			queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {
+				transformElement( slide, '' );
+
+				slide.removeEventListener( 'click', this.onSlideClicked, true );
+			} );
+
+			// Clean up changes made to backgrounds
+			queryAll( this.Reveal.getBackgroundsElement(), '.slide-background' ).forEach( background => {
+				transformElement( background, '' );
+			} );
+
+			this.Reveal.transformSlides( { overview: '' } );
+
+			const indices = this.Reveal.getIndices();
+
+			this.Reveal.slide( indices.h, indices.v );
+			this.Reveal.layout();
+			this.Reveal.cueAutoSlide();
+
+			// Notify observers of the overview hiding
+			this.Reveal.dispatchEvent({
+				type: 'overviewhidden',
+				data: {
+					'indexh': indices.h,
+					'indexv': indices.v,
+					'currentSlide': this.Reveal.getCurrentSlide()
+				}
+			});
+
+		}
+	}
+
+	/**
+	 * Toggles the slide overview mode on and off.
+	 *
+	 * @param {Boolean} [override] Flag which overrides the
+	 * toggle logic and forcibly sets the desired state. True means
+	 * overview is open, false means it's closed.
+	 */
+	toggle( override ) {
+
+		if( typeof override === 'boolean' ) {
+			override ? this.activate() : this.deactivate();
+		}
+		else {
+			this.isActive() ? this.deactivate() : this.activate();
+		}
+
+	}
+
+	/**
+	 * Checks if the overview is currently active.
+	 *
+	 * @return {Boolean} true if the overview is active,
+	 * false otherwise
+	 */
+	isActive() {
+
+		return this.active;
+
+	}
+
+	/**
+	 * Invoked when a slide is and we're in the overview.
+	 *
+	 * @param {object} event
+	 */
+	onSlideClicked( event ) {
+
+		if( this.isActive() ) {
+			event.preventDefault();
+
+			let element = event.target;
+
+			while( element && !element.nodeName.match( /section/gi ) ) {
+				element = element.parentNode;
+			}
+
+			if( element && !element.classList.contains( 'disabled' ) ) {
+
+				this.deactivate();
+
+				if( element.nodeName.match( /section/gi ) ) {
+					let h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
+						v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
+
+					this.Reveal.slide( h, v );
+				}
+
+			}
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/plugins.js b/inst/reveal.js-4.2.1/js/controllers/plugins.js
new file mode 100644
index 0000000..7aa6ac4
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/plugins.js
@@ -0,0 +1,241 @@
+import { loadScript } from '../utils/loader.js'
+
+/**
+ * Manages loading and registering of reveal.js plugins.
+ */
+export default class Plugins {
+
+	constructor( reveal ) {
+
+		this.Reveal = reveal;
+
+		// Flags our current state (idle -> loading -> loaded)
+		this.state = 'idle';
+
+		// An id:instance map of currently registed plugins
+		this.registeredPlugins = {};
+
+		this.asyncDependencies = [];
+
+	}
+
+	/**
+	 * Loads reveal.js dependencies, registers and
+	 * initializes plugins.
+	 *
+	 * Plugins are direct references to a reveal.js plugin
+	 * object that we register and initialize after any
+	 * synchronous dependencies have loaded.
+	 *
+	 * Dependencies are defined via the 'dependencies' config
+	 * option and will be loaded prior to starting reveal.js.
+	 * Some dependencies may have an 'async' flag, if so they
+	 * will load after reveal.js has been started up.
+	 */
+	load( plugins, dependencies ) {
+
+		this.state = 'loading';
+
+		plugins.forEach( this.registerPlugin.bind( this ) );
+
+		return new Promise( resolve => {
+
+			let scripts = [],
+				scriptsToLoad = 0;
+
+			dependencies.forEach( s => {
+				// Load if there's no condition or the condition is truthy
+				if( !s.condition || s.condition() ) {
+					if( s.async ) {
+						this.asyncDependencies.push( s );
+					}
+					else {
+						scripts.push( s );
+					}
+				}
+			} );
+
+			if( scripts.length ) {
+				scriptsToLoad = scripts.length;
+
+				const scriptLoadedCallback = (s) => {
+					if( s && typeof s.callback === 'function' ) s.callback();
+
+					if( --scriptsToLoad === 0 ) {
+						this.initPlugins().then( resolve );
+					}
+				};
+
+				// Load synchronous scripts
+				scripts.forEach( s => {
+					if( typeof s.id === 'string' ) {
+						this.registerPlugin( s );
+						scriptLoadedCallback( s );
+					}
+					else if( typeof s.src === 'string' ) {
+						loadScript( s.src, () => scriptLoadedCallback(s) );
+					}
+					else {
+						console.warn( 'Unrecognized plugin format', s );
+						scriptLoadedCallback();
+					}
+				} );
+			}
+			else {
+				this.initPlugins().then( resolve );
+			}
+
+		} );
+
+	}
+
+	/**
+	 * Initializes our plugins and waits for them to be ready
+	 * before proceeding.
+	 */
+	initPlugins() {
+
+		return new Promise( resolve => {
+
+			let pluginValues = Object.values( this.registeredPlugins );
+			let pluginsToInitialize = pluginValues.length;
+
+			// If there are no plugins, skip this step
+			if( pluginsToInitialize === 0 ) {
+				this.loadAsync().then( resolve );
+			}
+			// ... otherwise initialize plugins
+			else {
+
+				let initNextPlugin;
+
+				let afterPlugInitialized = () => {
+					if( --pluginsToInitialize === 0 ) {
+						this.loadAsync().then( resolve );
+					}
+					else {
+						initNextPlugin();
+					}
+				};
+
+				let i = 0;
+
+				// Initialize plugins serially
+				initNextPlugin = () => {
+
+					let plugin = pluginValues[i++];
+
+					// If the plugin has an 'init' method, invoke it
+					if( typeof plugin.init === 'function' ) {
+						let promise = plugin.init( this.Reveal );
+
+						// If the plugin returned a Promise, wait for it
+						if( promise && typeof promise.then === 'function' ) {
+							promise.then( afterPlugInitialized );
+						}
+						else {
+							afterPlugInitialized();
+						}
+					}
+					else {
+						afterPlugInitialized();
+					}
+
+				}
+
+				initNextPlugin();
+
+			}
+
+		} )
+
+	}
+
+	/**
+	 * Loads all async reveal.js dependencies.
+	 */
+	loadAsync() {
+
+		this.state = 'loaded';
+
+		if( this.asyncDependencies.length ) {
+			this.asyncDependencies.forEach( s => {
+				loadScript( s.src, s.callback );
+			} );
+		}
+
+		return Promise.resolve();
+
+	}
+
+	/**
+	 * Registers a new plugin with this reveal.js instance.
+	 *
+	 * reveal.js waits for all regisered plugins to initialize
+	 * before considering itself ready, as long as the plugin
+	 * is registered before calling `Reveal.initialize()`.
+	 */
+	registerPlugin( plugin ) {
+
+		// Backwards compatibility to make reveal.js ~3.9.0
+		// plugins work with reveal.js 4.0.0
+		if( arguments.length === 2 && typeof arguments[0] === 'string' ) {
+			plugin = arguments[1];
+			plugin.id = arguments[0];
+		}
+		// Plugin can optionally be a function which we call
+		// to create an instance of the plugin
+		else if( typeof plugin === 'function' ) {
+			plugin = plugin();
+		}
+
+		let id = plugin.id;
+
+		if( typeof id !== 'string' ) {
+			console.warn( 'Unrecognized plugin format; can\'t find plugin.id', plugin );
+		}
+		else if( this.registeredPlugins[id] === undefined ) {
+			this.registeredPlugins[id] = plugin;
+
+			// If a plugin is registered after reveal.js is loaded,
+			// initialize it right away
+			if( this.state === 'loaded' && typeof plugin.init === 'function' ) {
+				plugin.init( this.Reveal );
+			}
+		}
+		else {
+			console.warn( 'reveal.js: "'+ id +'" plugin has already been registered' );
+		}
+
+	}
+
+	/**
+	 * Checks if a specific plugin has been registered.
+	 *
+	 * @param {String} id Unique plugin identifier
+	 */
+	hasPlugin( id ) {
+
+		return !!this.registeredPlugins[id];
+
+	}
+
+	/**
+	 * Returns the specific plugin instance, if a plugin
+	 * with the given ID has been registered.
+	 *
+	 * @param {String} id Unique plugin identifier
+	 */
+	getPlugin( id ) {
+
+		return this.registeredPlugins[id];
+
+	}
+
+	getRegisteredPlugins() {
+
+		return this.registeredPlugins;
+
+	}
+
+}
diff --git a/inst/reveal.js-4.2.1/js/controllers/pointer.js b/inst/reveal.js-4.2.1/js/controllers/pointer.js
new file mode 100644
index 0000000..aec19d5
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/pointer.js
@@ -0,0 +1,118 @@
+/**
+ * Handles hiding of the pointer/cursor when inactive.
+ */
+export default class Pointer {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Throttles mouse wheel navigation
+		this.lastMouseWheelStep = 0;
+
+		// Is the mouse pointer currently hidden from view
+		this.cursorHidden = false;
+
+		// Timeout used to determine when the cursor is inactive
+		this.cursorInactiveTimeout = 0;
+
+		this.onDocumentCursorActive = this.onDocumentCursorActive.bind( this );
+		this.onDocumentMouseScroll = this.onDocumentMouseScroll.bind( this );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		if( config.mouseWheel ) {
+			document.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
+			document.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
+		}
+		else {
+			document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
+			document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
+		}
+
+		// Auto-hide the mouse pointer when its inactive
+		if( config.hideInactiveCursor ) {
+			document.addEventListener( 'mousemove', this.onDocumentCursorActive, false );
+			document.addEventListener( 'mousedown', this.onDocumentCursorActive, false );
+		}
+		else {
+			this.showCursor();
+
+			document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
+			document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
+		}
+
+	}
+
+	/**
+	 * Shows the mouse pointer after it has been hidden with
+	 * #hideCursor.
+	 */
+	showCursor() {
+
+		if( this.cursorHidden ) {
+			this.cursorHidden = false;
+			this.Reveal.getRevealElement().style.cursor = '';
+		}
+
+	}
+
+	/**
+	 * Hides the mouse pointer when it's on top of the .reveal
+	 * container.
+	 */
+	hideCursor() {
+
+		if( this.cursorHidden === false ) {
+			this.cursorHidden = true;
+			this.Reveal.getRevealElement().style.cursor = 'none';
+		}
+
+	}
+
+	/**
+	 * Called whenever there is mouse input at the document level
+	 * to determine if the cursor is active or not.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentCursorActive( event ) {
+
+		this.showCursor();
+
+		clearTimeout( this.cursorInactiveTimeout );
+
+		this.cursorInactiveTimeout = setTimeout( this.hideCursor.bind( this ), this.Reveal.getConfig().hideCursorTime );
+
+	}
+
+	/**
+	 * Handles mouse wheel scrolling, throttled to avoid skipping
+	 * multiple slides.
+	 *
+	 * @param {object} event
+	 */
+	onDocumentMouseScroll( event ) {
+
+		if( Date.now() - this.lastMouseWheelStep > 1000 ) {
+
+			this.lastMouseWheelStep = Date.now();
+
+			let delta = event.detail || -event.wheelDelta;
+			if( delta > 0 ) {
+				this.Reveal.next();
+			}
+			else if( delta < 0 ) {
+				this.Reveal.prev();
+			}
+
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/print.js b/inst/reveal.js-4.2.1/js/controllers/print.js
new file mode 100644
index 0000000..aab4c62
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/print.js
@@ -0,0 +1,228 @@
+import { SLIDES_SELECTOR } from '../utils/constants.js'
+import { queryAll, createStyleSheet } from '../utils/util.js'
+
+/**
+ * Setups up our presentation for printing/exporting to PDF.
+ */
+export default class Print {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	/**
+	 * Configures the presentation for printing to a static
+	 * PDF.
+	 */
+	async setupPDF() {
+
+		const config = this.Reveal.getConfig();
+		const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
+
+		// Compute slide numbers now, before we start duplicating slides
+		const doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
+
+		const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
+
+		// Dimensions of the PDF pages
+		const pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),
+			pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );
+
+		// Dimensions of slides within the pages
+		const slideWidth = slideSize.width,
+			slideHeight = slideSize.height;
+
+		await new Promise( requestAnimationFrame );
+
+		// Let the browser know what page size we want to print
+		createStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );
+
+		// Limit the size of certain elements to the dimensions of the slide
+		createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
+
+		document.documentElement.classList.add( 'print-pdf' );
+		document.body.style.width = pageWidth + 'px';
+		document.body.style.height = pageHeight + 'px';
+
+		const viewportElement = document.querySelector( '.reveal-viewport' );
+		let presentationBackground;
+		if( viewportElement ) {
+			const viewportStyles = window.getComputedStyle( viewportElement );
+			if( viewportStyles && viewportStyles.background ) {
+				presentationBackground = viewportStyles.background;
+			}
+		}
+
+		// Make sure stretch elements fit on slide
+		await new Promise( requestAnimationFrame );
+		this.Reveal.layoutSlideContents( slideWidth, slideHeight );
+
+		// Batch scrollHeight access to prevent layout thrashing
+		await new Promise( requestAnimationFrame );
+
+		const slideScrollHeights = slides.map( slide => slide.scrollHeight );
+
+		const pages = [];
+		const pageContainer = slides[0].parentNode;
+
+		// Slide and slide background layout
+		slides.forEach( function( slide, index ) {
+
+			// 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
+				let left = ( pageWidth - slideWidth ) / 2;
+				let top = ( pageHeight - slideHeight ) / 2;
+
+				const contentHeight = slideScrollHeights[ index ];
+				let numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );
+
+				// Adhere to configured pages per slide limit
+				numberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide );
+
+				// Center slides vertically
+				if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {
+					top = Math.max( ( pageHeight - contentHeight ) / 2, 0 );
+				}
+
+				// Wrap the slide in a page element and hide its overflow
+				// so that no page ever flows onto another
+				const page = document.createElement( 'div' );
+				pages.push( page );
+
+				page.className = 'pdf-page';
+				page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
+
+				// Copy the presentation-wide background to each individual
+				// page when printing
+				if( presentationBackground ) {
+					page.style.background = presentationBackground;
+				}
+
+				page.appendChild( slide );
+
+				// Position the slide inside of the page
+				slide.style.left = left + 'px';
+				slide.style.top = top + 'px';
+				slide.style.width = slideWidth + 'px';
+
+				// Re-run the slide layout so that r-fit-text is applied based on
+				// the printed slide size
+				this.Reveal.slideContent.layout( slide )
+
+				if( slide.slideBackgroundElement ) {
+					page.insertBefore( slide.slideBackgroundElement, slide );
+				}
+
+				// Inject notes if `showNotes` is enabled
+				if( config.showNotes ) {
+
+					// Are there notes for this slide?
+					const notes = this.Reveal.getSlideNotes( slide );
+					if( notes ) {
+
+						const notesSpacing = 8;
+						const notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';
+						const notesElement = document.createElement( 'div' );
+						notesElement.classList.add( 'speaker-notes' );
+						notesElement.classList.add( 'speaker-notes-pdf' );
+						notesElement.setAttribute( 'data-layout', notesLayout );
+						notesElement.innerHTML = notes;
+
+						if( notesLayout === 'separate-page' ) {
+							pages.push( notesElement );
+						}
+						else {
+							notesElement.style.left = notesSpacing + 'px';
+							notesElement.style.bottom = notesSpacing + 'px';
+							notesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px';
+							page.appendChild( notesElement );
+						}
+
+					}
+
+				}
+
+				// Inject slide numbers if `slideNumbers` are enabled
+				if( doingSlideNumbers ) {
+					const slideNumber = index + 1;
+					const numberElement = document.createElement( 'div' );
+					numberElement.classList.add( 'slide-number' );
+					numberElement.classList.add( 'slide-number-pdf' );
+					numberElement.innerHTML = slideNumber;
+					page.appendChild( numberElement );
+				}
+
+				// Copy page and show fragments one after another
+				if( config.pdfSeparateFragments ) {
+
+					// Each fragment 'group' is an array containing one or more
+					// fragments. Multiple fragments that appear at the same time
+					// are part of the same group.
+					const fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );
+
+					let previousFragmentStep;
+
+					fragmentGroups.forEach( function( fragments ) {
+
+						// Remove 'current-fragment' from the previous group
+						if( previousFragmentStep ) {
+							previousFragmentStep.forEach( function( fragment ) {
+								fragment.classList.remove( 'current-fragment' );
+							} );
+						}
+
+						// Show the fragments for the current index
+						fragments.forEach( function( fragment ) {
+							fragment.classList.add( 'visible', 'current-fragment' );
+						}, this );
+
+						// Create a separate page for the current fragment state
+						const clonedPage = page.cloneNode( true );
+						pages.push( clonedPage );
+
+						previousFragmentStep = fragments;
+
+					}, this );
+
+					// Reset the first/original page so that all fragments are hidden
+					fragmentGroups.forEach( function( fragments ) {
+						fragments.forEach( function( fragment ) {
+							fragment.classList.remove( 'visible', 'current-fragment' );
+						} );
+					} );
+
+				}
+				// Show all fragments
+				else {
+					queryAll( page, '.fragment:not(.fade-out)' ).forEach( function( fragment ) {
+						fragment.classList.add( 'visible' );
+					} );
+				}
+
+			}
+
+		}, this );
+
+		await new Promise( requestAnimationFrame );
+
+		pages.forEach( page => pageContainer.appendChild( page ) );
+
+		// Notify subscribers that the PDF layout is good to go
+		this.Reveal.dispatchEvent({ type: 'pdf-ready' });
+
+	}
+
+	/**
+	 * Checks if this instance is being used to print a PDF.
+	 */
+	isPrintingPDF() {
+
+		return ( /print-pdf/gi ).test( window.location.search );
+
+	}
+
+}
diff --git a/inst/reveal.js-4.2.1/js/controllers/progress.js b/inst/reveal.js-4.2.1/js/controllers/progress.js
new file mode 100644
index 0000000..82a370a
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/progress.js
@@ -0,0 +1,105 @@
+/**
+ * Creates a visual progress bar for the presentation.
+ */
+export default class Progress {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.onProgressClicked = this.onProgressClicked.bind( this );
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'progress';
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+		this.bar = document.createElement( 'span' );
+		this.element.appendChild( this.bar );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		this.element.style.display = config.progress ? 'block' : 'none';
+
+	}
+
+	bind() {
+
+		if( this.Reveal.getConfig().progress && this.element ) {
+			this.element.addEventListener( 'click', this.onProgressClicked, false );
+		}
+
+	}
+
+	unbind() {
+
+		if ( this.Reveal.getConfig().progress && this.element ) {
+			this.element.removeEventListener( 'click', this.onProgressClicked, false );
+		}
+
+	}
+
+	/**
+	 * Updates the progress bar to reflect the current slide.
+	 */
+	update() {
+
+		// Update progress if enabled
+		if( this.Reveal.getConfig().progress && this.bar ) {
+
+			let scale = this.Reveal.getProgress();
+
+			// Don't fill the progress bar if there's only one slide
+			if( this.Reveal.getTotalSlides() < 2 ) {
+				scale = 0;
+			}
+
+			this.bar.style.transform = 'scaleX('+ scale +')';
+
+		}
+
+	}
+
+	getMaxWidth() {
+
+		return this.Reveal.getRevealElement().offsetWidth;
+
+	}
+
+	/**
+	 * Clicking on the progress bar results in a navigation to the
+	 * closest approximate horizontal slide using this equation:
+	 *
+	 * ( clickX / presentationWidth ) * numberOfSlides
+	 *
+	 * @param {object} event
+	 */
+	onProgressClicked( event ) {
+
+		this.Reveal.onUserInput( event );
+
+		event.preventDefault();
+
+		let slides = this.Reveal.getSlides();
+		let slidesTotal = slides.length;
+		let slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );
+
+		if( this.Reveal.getConfig().rtl ) {
+			slideIndex = slidesTotal - slideIndex;
+		}
+
+		let targetIndices = this.Reveal.getIndices(slides[slideIndex]);
+		this.Reveal.slide( targetIndices.h, targetIndices.v );
+
+	}
+
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/slidecontent.js b/inst/reveal.js-4.2.1/js/controllers/slidecontent.js
new file mode 100644
index 0000000..d37dc24
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/slidecontent.js
@@ -0,0 +1,479 @@
+import { extend, queryAll, closest, getMimeTypeFromFile } from '../utils/util.js'
+import { isMobile } from '../utils/device.js'
+
+import fitty from 'fitty';
+
+/**
+ * Handles loading, unloading and playback of slide
+ * content such as images, videos and iframes.
+ */
+export default class SlideContent {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
+
+	}
+
+	/**
+	 * Should the given element be preloaded?
+	 * Decides based on local element attributes and global config.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	shouldPreload( element ) {
+
+		// Prefer an explicit global preload setting
+		let preload = this.Reveal.getConfig().preloadIframes;
+
+		// If no global setting is available, fall back on the element's
+		// own preload setting
+		if( typeof preload !== 'boolean' ) {
+			preload = element.hasAttribute( 'data-preload' );
+		}
+
+		return preload;
+	}
+
+	/**
+	 * 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).
+	 *
+	 * @param {HTMLElement} slide Slide to show
+	 */
+	load( slide, options = {} ) {
+
+		// Show the slide element
+		slide.style.display = this.Reveal.getConfig().display;
+
+		// Media elements with data-src attributes
+		queryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {
+			if( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {
+				element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
+				element.setAttribute( 'data-lazy-loaded', '' );
+				element.removeAttribute( 'data-src' );
+			}
+		} );
+
+		// Media elements with <source> children
+		queryAll( slide, 'video, audio' ).forEach( media => {
+			let sources = 0;
+
+			queryAll( media, 'source[data-src]' ).forEach( source => {
+				source.setAttribute( 'src', source.getAttribute( 'data-src' ) );
+				source.removeAttribute( 'data-src' );
+				source.setAttribute( 'data-lazy-loaded', '' );
+				sources += 1;
+			} );
+
+			// Enable inline video playback in mobile Safari
+			if( isMobile && media.tagName === 'VIDEO' ) {
+				media.setAttribute( 'playsinline', '' );
+			}
+
+			// 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
+		let background = slide.slideBackgroundElement;
+		if( background ) {
+			background.style.display = 'block';
+
+			let backgroundContent = slide.slideBackgroundContentElement;
+			let backgroundIframe = slide.getAttribute( 'data-background-iframe' );
+
+			// If the background contains media, load it
+			if( background.hasAttribute( 'data-loaded' ) === false ) {
+				background.setAttribute( 'data-loaded', 'true' );
+
+				let backgroundImage = slide.getAttribute( 'data-background-image' ),
+					backgroundVideo = slide.getAttribute( 'data-background-video' ),
+					backgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ),
+					backgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' );
+
+				// Images
+				if( backgroundImage ) {
+					// base64
+					if(  /^data:/.test( backgroundImage.trim() ) ) {
+						backgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;
+					}
+					// URL(s)
+					else {
+						backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
+							return `url(${encodeURI(background.trim())})`;
+						}).join( ',' );
+					}
+				}
+				// Videos
+				else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
+					let video = document.createElement( 'video' );
+
+					if( backgroundVideoLoop ) {
+						video.setAttribute( 'loop', '' );
+					}
+
+					if( backgroundVideoMuted ) {
+						video.muted = true;
+					}
+
+					// Enable inline playback in mobile Safari
+					//
+					// Mute is required for video to play when using
+					// swipe gestures to navigate since they don't
+					// count as direct user actions :'(
+					if( isMobile ) {
+						video.muted = true;
+						video.setAttribute( 'playsinline', '' );
+					}
+
+					// Support comma separated lists of video sources
+					backgroundVideo.split( ',' ).forEach( source => {
+						let type = getMimeTypeFromFile( source );
+						if( type ) {
+							video.innerHTML += `<source src="${source}" type="${type}">`;
+						}
+						else {
+							video.innerHTML += `<source src="${source}">`;
+						}
+					} );
+
+					backgroundContent.appendChild( video );
+				}
+				// Iframes
+				else if( backgroundIframe && options.excludeIframes !== true ) {
+					let iframe = document.createElement( 'iframe' );
+					iframe.setAttribute( 'allowfullscreen', '' );
+					iframe.setAttribute( 'mozallowfullscreen', '' );
+					iframe.setAttribute( 'webkitallowfullscreen', '' );
+					iframe.setAttribute( 'allow', 'autoplay' );
+
+					iframe.setAttribute( 'data-src', backgroundIframe );
+
+					iframe.style.width  = '100%';
+					iframe.style.height = '100%';
+					iframe.style.maxHeight = '100%';
+					iframe.style.maxWidth = '100%';
+
+					backgroundContent.appendChild( iframe );
+				}
+			}
+
+			// Start loading preloadable iframes
+			let backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' );
+			if( backgroundIframeElement ) {
+
+				// Check if this iframe is eligible to be preloaded
+				if( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {
+					if( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) {
+						backgroundIframeElement.setAttribute( 'src', backgroundIframe );
+					}
+				}
+
+			}
+
+		}
+
+		this.layout( slide );
+
+	}
+
+	/**
+	 * Applies JS-dependent layout helpers for the given slide,
+	 * if there are any.
+	 */
+	layout( slide ) {
+
+		// Autosize text with the r-fit-text class based on the
+		// size of its container. This needs to happen after the
+		// slide is visible in order to measure the text.
+		Array.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
+			fitty( element, {
+				minSize: 24,
+				maxSize: this.Reveal.getConfig().height * 0.8,
+				observeMutations: false,
+				observeWindow: false
+			} );
+		} );
+
+	}
+
+	/**
+	 * Unloads and hides the given slide. This is called when the
+	 * slide is moved outside of the configured view distance.
+	 *
+	 * @param {HTMLElement} slide
+	 */
+	unload( slide ) {
+
+		// Hide the slide element
+		slide.style.display = 'none';
+
+		// Hide the corresponding background element
+		let background = this.Reveal.getSlideBackground( slide );
+		if( background ) {
+			background.style.display = 'none';
+
+			// Unload any background iframes
+			queryAll( background, 'iframe[src]' ).forEach( element => {
+				element.removeAttribute( 'src' );
+			} );
+		}
+
+		// Reset lazy-loaded media elements with src attributes
+		queryAll( slide, 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ).forEach( element => {
+			element.setAttribute( 'data-src', element.getAttribute( 'src' ) );
+			element.removeAttribute( 'src' );
+		} );
+
+		// Reset lazy-loaded media elements with <source> children
+		queryAll( slide, 'video[data-lazy-loaded] source[src], audio source[src]' ).forEach( source => {
+			source.setAttribute( 'data-src', source.getAttribute( 'src' ) );
+			source.removeAttribute( 'src' );
+		} );
+
+	}
+
+	/**
+	 * Enforces origin-specific format rules for embedded media.
+	 */
+	formatEmbeddedContent() {
+
+		let _appendParamToIframeSource = ( sourceAttribute, sourceURL, param ) => {
+			queryAll( this.Reveal.getSlidesElement(), 'iframe['+ sourceAttribute +'*="'+ sourceURL +'"]' ).forEach( el => {
+				let 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 given element.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	startEmbeddedContent( element ) {
+
+		if( element && !this.Reveal.isSpeakerNotes() ) {
+
+			// Restart GIFs
+			queryAll( element, 'img[src$=".gif"]' ).forEach( 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
+			queryAll( element, 'video, audio' ).forEach( el => {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+					return;
+				}
+
+				// Prefer an explicit global autoplay setting
+				let autoplay = this.Reveal.getConfig().autoPlayMedia;
+
+				// If no global setting is available, fall back on the element's
+				// own autoplay setting
+				if( typeof autoplay !== 'boolean' ) {
+					autoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );
+				}
+
+				if( autoplay && typeof el.play === 'function' ) {
+
+					// If the media is ready, start playback
+					if( el.readyState > 1 ) {
+						this.startEmbeddedMedia( { target: el } );
+					}
+					// Mobile devices never fire a loaded event so instead
+					// of waiting, we initiate playback
+					else if( isMobile ) {
+						let promise = el.play();
+
+						// If autoplay does not work, ensure that the controls are visible so
+						// that the viewer can start the media on their own
+						if( promise && typeof promise.catch === 'function' && el.controls === false ) {
+							promise.catch( () => {
+								el.controls = true;
+
+								// Once the video does start playing, hide the controls again
+								el.addEventListener( 'play', () => {
+									el.controls = false;
+								} );
+							} );
+						}
+					}
+					// If the media isn't loaded, wait before playing
+					else {
+						el.removeEventListener( 'loadeddata', this.startEmbeddedMedia ); // remove first to avoid dupes
+						el.addEventListener( 'loadeddata', this.startEmbeddedMedia );
+					}
+
+				}
+			} );
+
+			// Normal iframes
+			queryAll( element, 'iframe[src]' ).forEach( el => {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+					return;
+				}
+
+				this.startEmbeddedIframe( { target: el } );
+			} );
+
+			// Lazy loading iframes
+			queryAll( element, 'iframe[data-src]' ).forEach( el => {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
+					return;
+				}
+
+				if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
+					el.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes
+					el.addEventListener( 'load', this.startEmbeddedIframe );
+					el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
+				}
+			} );
+
+		}
+
+	}
+
+	/**
+	 * Starts playing an embedded video/audio element after
+	 * it has finished loading.
+	 *
+	 * @param {object} event
+	 */
+	startEmbeddedMedia( event ) {
+
+		let isAttachedToDOM = !!closest( event.target, 'html' ),
+			isVisible  		= !!closest( event.target, '.present' );
+
+		if( isAttachedToDOM && isVisible ) {
+			event.target.currentTime = 0;
+			event.target.play();
+		}
+
+		event.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );
+
+	}
+
+	/**
+	 * "Starts" the content of an embedded iframe using the
+	 * postMessage API.
+	 *
+	 * @param {object} event
+	 */
+	startEmbeddedIframe( event ) {
+
+		let iframe = event.target;
+
+		if( iframe && iframe.contentWindow ) {
+
+			let isAttachedToDOM = !!closest( event.target, 'html' ),
+				isVisible  		= !!closest( event.target, '.present' );
+
+			if( isAttachedToDOM && isVisible ) {
+
+				// Prefer an explicit global autoplay setting
+				let autoplay = this.Reveal.getConfig().autoPlayMedia;
+
+				// If no global setting is available, fall back on the element's
+				// own autoplay setting
+				if( typeof autoplay !== 'boolean' ) {
+					autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );
+				}
+
+				// YouTube postMessage API
+				if( /youtube\.com\/embed\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {
+					iframe.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
+				}
+				// Vimeo postMessage API
+				else if( /player\.vimeo\.com\//.test( iframe.getAttribute( 'src' ) ) && 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.
+	 *
+	 * @param {HTMLElement} element
+	 */
+	stopEmbeddedContent( element, options = {} ) {
+
+		options = extend( {
+			// Defaults
+			unloadIframes: true
+		}, options );
+
+		if( element && element.parentNode ) {
+			// HTML5 media elements
+			queryAll( element, 'video, audio' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
+					el.setAttribute('data-paused-by-reveal', '');
+					el.pause();
+				}
+			} );
+
+			// Generic postMessage API for non-lazy loaded iframes
+			queryAll( element, 'iframe' ).forEach( el => {
+				if( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );
+				el.removeEventListener( 'load', this.startEmbeddedIframe );
+			});
+
+			// YouTube postMessage API
+			queryAll( element, 'iframe[src*="youtube.com/embed/"]' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
+				}
+			});
+
+			// Vimeo postMessage API
+			queryAll( element, 'iframe[src*="player.vimeo.com/"]' ).forEach( el => {
+				if( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {
+					el.contentWindow.postMessage( '{"method":"pause"}', '*' );
+				}
+			});
+
+			if( options.unloadIframes === true ) {
+				// Unload lazy-loaded iframes
+				queryAll( element, 'iframe[data-src]' ).forEach( 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' );
+				} );
+			}
+		}
+
+	}
+
+}
diff --git a/inst/reveal.js-4.2.1/js/controllers/slidenumber.js b/inst/reveal.js-4.2.1/js/controllers/slidenumber.js
new file mode 100644
index 0000000..ba124c0
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/slidenumber.js
@@ -0,0 +1,126 @@
+/**
+ * Handles the display of reveal.js' optional slide number.
+ */
+export default class SlideNumber {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+	}
+
+	render() {
+
+		this.element = document.createElement( 'div' );
+		this.element.className = 'slide-number';
+		this.Reveal.getRevealElement().appendChild( this.element );
+
+	}
+
+	/**
+	 * Called when the reveal.js config is updated.
+	 */
+	configure( config, oldConfig ) {
+
+		let slideNumberDisplay = 'none';
+		if( config.slideNumber && !this.Reveal.isPrintingPDF() ) {
+			if( config.showSlideNumber === 'all' ) {
+				slideNumberDisplay = 'block';
+			}
+			else if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) {
+				slideNumberDisplay = 'block';
+			}
+		}
+
+		this.element.style.display = slideNumberDisplay;
+
+	}
+
+	/**
+	 * Updates the slide number to match the current slide.
+	 */
+	update() {
+
+		// Update slide number if enabled
+		if( this.Reveal.getConfig().slideNumber && this.element ) {
+			this.element.innerHTML = this.getSlideNumber();
+		}
+
+	}
+
+	/**
+	 * Returns the HTML string corresponding to the current slide
+	 * number, including formatting.
+	 */
+	getSlideNumber( slide = this.Reveal.getCurrentSlide() ) {
+
+		let config = this.Reveal.getConfig();
+		let value;
+		let format = 'h.v';
+
+		if ( typeof config.slideNumber === 'function' ) {
+			value = config.slideNumber( slide );
+		} else {
+			// Check if a custom number format is available
+			if( typeof config.slideNumber === 'string' ) {
+				format = config.slideNumber;
+			}
+
+			// If there are ONLY vertical slides in this deck, always use
+			// a flattened slide number
+			if( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {
+				format = 'c';
+			}
+
+			// Offset the current slide number by 1 to make it 1-indexed
+			let horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1;
+
+			value = [];
+			switch( format ) {
+				case 'c':
+					value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );
+					break;
+				case 'c/t':
+					value.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );
+					break;
+				default:
+					let indices = this.Reveal.getIndices( slide );
+					value.push( indices.h + horizontalOffset );
+					let sep = format === 'h/v' ? '/' : '.';
+					if( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );
+			}
+		}
+
+		let url = '#' + this.Reveal.location.getHash( slide );
+		return this.formatNumber( value[0], value[1], value[2], url );
+
+	}
+
+	/**
+	 * Applies HTML formatting to a slide number before it's
+	 * written to the DOM.
+	 *
+	 * @param {number} a Current slide
+	 * @param {string} delimiter Character to separate slide numbers
+	 * @param {(number|*)} b Total slides
+	 * @param {HTMLElement} [url='#'+locationHash()] The url to link to
+	 * @return {string} HTML string fragment
+	 */
+	formatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) {
+
+		if( typeof b === 'number' && !isNaN( b ) ) {
+			return  `<a href="${url}">
+					<span class="slide-number-a">${a}</span>
+					<span class="slide-number-delimiter">${delimiter}</span>
+					<span class="slide-number-b">${b}</span>
+					</a>`;
+		}
+		else {
+			return `<a href="${url}">
+					<span class="slide-number-a">${a}</span>
+					</a>`;
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.2.1/js/controllers/touch.js b/inst/reveal.js-4.2.1/js/controllers/touch.js
new file mode 100644
index 0000000..5ac6a10
--- /dev/null
+++ b/inst/reveal.js-4.2.1/js/controllers/touch.js
@@ -0,0 +1,263 @@
+import { isAndroid } from '../utils/device.js'
+import { matches } from '../utils/util.js'
+
+const SWIPE_THRESHOLD = 40;
+
+/**
+ * Controls all touch interactions and navigations for
+ * a presentation.
+ */
+export default class Touch {
+
+	constructor( Reveal ) {
+
+		this.Reveal = Reveal;
+
+		// Holds information about the currently ongoing touch interaction
+		this.touchStartX = 0;
+		this.touchStartY = 0;
+		this.touchStartCount = 0;
+		this.touchCaptured = false;
+
+		this.onPointerDown = this.onPointerDown.bind( this );
+		this.onPointerMove = this.onPointerMove.bind( this );
+		this.onPointerUp = this.onPointerUp.bind( this );
+		this.onTouchStart = this.onTouchStart.bind( this );
+		this.onTouchMove = this.onTouchMove.bind( this );
+		this.onTouchEnd = this.onTouchEnd.bind( this );
+
+	}
+
+	/**
+	 *
+	 */
+	bind() {
+
+		let revealElement = this.Reveal.getRevealElement();
+
+		if( 'onpointerdown' in window ) {
+			// Use W3C pointer events
+			revealElement.addEventListener( 'pointerdown', this.onPointerDown, false );
+			revealElement.addEventListener( 'pointermove', this.onPointerMove, false );
+			revealElement.addEventListener( 'pointerup', this.onPointerUp, false );
+		}
+		else if( window.navigator.msPointerEnabled ) {
+			// IE 10 uses prefixed version of pointer events
+			revealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );
+			revealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );
+			revealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );
+		}
+		else {
+			// Fall back to touch events
+			revealElement.addEventListener( 'touchstart', this.onTouchStart, false );
+			revealElement.addEventListener( 'touchmove', this.onTouchMove, false );
+			revealElement.addEventListener( 'touchend', this.onTouchEnd, false );
+		}
+
+	}
+
+	/**
+	 *
+	 */
+	unbind() {
+
+		let revealElement = this.Reveal.getRevealElement();
+
+		revealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'pointermove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'pointerup', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );
+		revealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );
+		revealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );
+
+		revealElement.removeEventListener( 'touchstart', this.onTouchStart, false );
+		revealElement.removeEventListener( 'touchmove', this.onTouchMove, false );
+		revealElement.removeEventListener( 'touchend', this.onTouchEnd, false );
+
+	}
+
+	/**
+	 * Checks if the target element prevents the triggering of
+	 * swipe navigation.
+	 */
+	isSwipePrevented( target ) {
+
+		// Prevent accidental swipes when scrubbing timelines
+		if( matches( target, 'video, audio' ) ) return true;
+
+		while( target && typeof target.hasAttribute === 'function' ) {
+			if( target.hasAttribute( 'data-prevent-swipe' ) ) return true;
+			target = target.parentNode;
+		}
+
+		return false;
+
+	}
+
+	/**
+	 * Handler for the 'touchstart' event, enables support for
+	 * swipe and pinch gestures.
+	 *
+	 * @param {object} event
+	 */
+	onTouchStart( event ) {
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		this.touchStartX = event.touches[0].clientX;
+		this.touchStartY = event.touches[0].clientY;
+		this.touchStartCount = event.touches.length;
+
+	}
+
+	/**
+	 * Handler for the 'touchmove' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchMove( event ) {
+
+		if( this.isSwipePrevented( event.target ) ) return true;
+
+		let config = this.Reveal.getConfig();
+
+		// Each touch should only trigger one action
+		if( !this.touchCaptured ) {
+			this.Reveal.onUserInput( event );
+
+			let currentX = event.touches[0].clientX;
+			let currentY = event.touches[0].clientY;
+
+			// There was only one touch point, look for a swipe
+			if( event.touches.length === 1 && this.touchStartCount !== 2 ) {
+
+				let availableRoutes = this.Reveal.availableRoutes({ includeFragments: true });
+
+				let deltaX = currentX - this.touchStartX,
+					deltaY = currentY - this.touchStartY;
+
+				if( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.next();
+						}
+						else {
+							this.Reveal.prev();
+						}
+					}
+					else {
+						this.Reveal.left();
+					}
+				}
+				else if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						if( config.rtl ) {
+							this.Reveal.prev();
+						}
+						else {
+							this.Reveal.next();
+						}
+					}
+					else {
+						this.Reveal.right();
+					}
+				}
+				else if( deltaY > SWIPE_THRESHOLD && availableRoutes.up ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.prev();
+					}
+					else {
+						this.Reveal.up();
+					}
+				}
+				else if( deltaY < -SWIPE_THRESHOLD && availableRoutes.down ) {
+					this.touchCaptured = true;
+					if( config.navigationMode === 'linear' ) {
+						this.Reveal.next();
+					}
+					else {
+						this.Reveal.down();
+					}
+				}
+
+				// If we're embedded, only block touch events if they have
+				// triggered an action
+				if( config.embedded ) {
+					if( this.touchCaptured || this.Reveal.isVerticalSlide() ) {
+						event.preventDefault();
+					}
+				}
+				// Not embedded? Block them all to avoid needless tossing
+				// around of the viewport in iOS
+				else {
+					event.preventDefault();
+				}
+
+			}
+		}
+		// There's a bug with swiping on some Android devices unless
+		// the default action is always prevented
+		else if( isAndroid ) {
+			event.preventDefault();
+		}
+
+	}
+
+	/**
+	 * Handler for the 'touchend' event.
+	 *
+	 * @param {object} event
+	 */
+	onTouchEnd( event ) {
+
+		this.touchCaptured = false;
+
+	}
+
+	/**
+	 * Convert pointer down to touch start.
+	 *
+	 * @param {object} event
+	 */
+	onPointerDown( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchStart( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer move to touch move.
+	 *
+	 * @param {object} event
+	 */
+	onPointerMove( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchMove( event );
+		}
+
+	}
+
+	/**
+	 * Convert pointer up to touch end.
+	 *
+	 * @param {object} event
+	 */
+	onPointerUp( event ) {
+
+		if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" )  {
+			event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
+			this.onTouchEnd( event );
+		}
+
+	}
+
+}
\ No newline at end of file
