diff --git a/inst/reveal.js-4.1.2/js/utils/color.js b/inst/reveal.js-4.1.2/js/utils/color.js
new file mode 100644
index 0000000..1043f83
--- /dev/null
+++ b/inst/reveal.js-4.1.2/js/utils/color.js
@@ -0,0 +1,77 @@
+/**
+ * Converts various color input formats to an {r:0,g:0,b:0} object.
+ *
+ * @param {string} color The string representation of a color
+ * @example
+ * colorToRgb('#000');
+ * @example
+ * colorToRgb('#000000');
+ * @example
+ * colorToRgb('rgb(0,0,0)');
+ * @example
+ * colorToRgb('rgba(0,0,0)');
+ *
+ * @return {{r: number, g: number, b: number, [a]: number}|null}
+ */
+export const colorToRgb = ( color ) => {
+
+	let hex3 = color.match( /^#([0-9a-f]{3})$/i );
+	if( hex3 && hex3[1] ) {
+		hex3 = hex3[1];
+		return {
+			r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,
+			g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,
+			b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11
+		};
+	}
+
+	let hex6 = color.match( /^#([0-9a-f]{6})$/i );
+	if( hex6 && hex6[1] ) {
+		hex6 = hex6[1];
+		return {
+			r: parseInt( hex6.substr( 0, 2 ), 16 ),
+			g: parseInt( hex6.substr( 2, 2 ), 16 ),
+			b: parseInt( hex6.substr( 4, 2 ), 16 )
+		};
+	}
+
+	let rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i );
+	if( rgb ) {
+		return {
+			r: parseInt( rgb[1], 10 ),
+			g: parseInt( rgb[2], 10 ),
+			b: parseInt( rgb[3], 10 )
+		};
+	}
+
+	let rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
+	if( rgba ) {
+		return {
+			r: parseInt( rgba[1], 10 ),
+			g: parseInt( rgba[2], 10 ),
+			b: parseInt( rgba[3], 10 ),
+			a: parseFloat( rgba[4] )
+		};
+	}
+
+	return null;
+
+}
+
+/**
+ * Calculates brightness on a scale of 0-255.
+ *
+ * @param {string} color See colorToRgb for supported formats.
+ * @see {@link colorToRgb}
+ */
+export const colorBrightness = ( color ) => {
+
+	if( typeof color === 'string' ) color = colorToRgb( color );
+
+	if( color ) {
+		return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;
+	}
+
+	return null;
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.1.2/js/utils/constants.js b/inst/reveal.js-4.1.2/js/utils/constants.js
new file mode 100644
index 0000000..6c2382e
--- /dev/null
+++ b/inst/reveal.js-4.1.2/js/utils/constants.js
@@ -0,0 +1,10 @@
+
+export const SLIDES_SELECTOR = '.slides section';
+export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
+export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
+
+// Methods that may not be invoked via the postMessage API
+export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
+
+// Regex for retrieving the fragment style from a class attribute
+export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
\ No newline at end of file
diff --git a/inst/reveal.js-4.1.2/js/utils/device.js b/inst/reveal.js-4.1.2/js/utils/device.js
new file mode 100644
index 0000000..ec1034f
--- /dev/null
+++ b/inst/reveal.js-4.1.2/js/utils/device.js
@@ -0,0 +1,15 @@
+const UA = navigator.userAgent;
+const testElement = document.createElement( 'div' );
+
+export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
+						( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
+
+export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
+
+export const isAndroid = /android/gi.test( UA );
+
+// Flags if we should use zoom instead of transform to scale
+// up slides. Zoom produces crisper results but has a lot of
+// xbrowser quirks so we only use it in whitelisted browsers.
+export const supportsZoom = 'zoom' in testElement.style && !isMobile &&
+				( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) );
\ No newline at end of file
diff --git a/inst/reveal.js-4.1.2/js/utils/loader.js b/inst/reveal.js-4.1.2/js/utils/loader.js
new file mode 100644
index 0000000..58d39ac
--- /dev/null
+++ b/inst/reveal.js-4.1.2/js/utils/loader.js
@@ -0,0 +1,46 @@
+/**
+ * Loads a JavaScript file from the given URL and executes it.
+ *
+ * @param {string} url Address of the .js file to load
+ * @param {function} callback Method to invoke when the script
+ * has loaded and executed
+ */
+export const loadScript = ( url, callback ) => {
+
+	const script = document.createElement( 'script' );
+	script.type = 'text/javascript';
+	script.async = false;
+	script.defer = false;
+	script.src = url;
+
+	if( typeof callback === 'function' ) {
+
+		// Success callback
+		script.onload = script.onreadystatechange = event => {
+			if( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {
+
+				// Kill event listeners
+				script.onload = script.onreadystatechange = script.onerror = null;
+
+				callback();
+
+			}
+		};
+
+		// Error callback
+		script.onerror = err => {
+
+			// Kill event listeners
+			script.onload = script.onreadystatechange = script.onerror = null;
+
+			callback( new Error( 'Failed loading script: ' + script.src + '\n' + err ) );
+
+		};
+
+	}
+
+	// Append the script at the end of <head>
+	const head = document.querySelector( 'head' );
+	head.insertBefore( script, head.lastChild );
+
+}
\ No newline at end of file
diff --git a/inst/reveal.js-4.1.2/js/utils/util.js b/inst/reveal.js-4.1.2/js/utils/util.js
new file mode 100644
index 0000000..68ff085
--- /dev/null
+++ b/inst/reveal.js-4.1.2/js/utils/util.js
@@ -0,0 +1,282 @@
+/**
+ * Extend object a with the properties of object b.
+ * If there's a conflict, object b takes precedence.
+ *
+ * @param {object} a
+ * @param {object} b
+ */
+export const extend = ( a, b ) => {
+
+	for( let i in b ) {
+		a[ i ] = b[ i ];
+	}
+
+	return a;
+
+}
+
+/**
+ * querySelectorAll but returns an Array.
+ */
+export const queryAll = ( el, selector ) => {
+
+	return Array.from( el.querySelectorAll( selector ) );
+
+}
+
+/**
+ * classList.toggle() with cross browser support
+ */
+export const toggleClass = ( el, className, value ) => {
+	if( value ) {
+		el.classList.add( className );
+	}
+	else {
+		el.classList.remove( className );
+	}
+}
+
+/**
+ * Utility for deserializing a value.
+ *
+ * @param {*} value
+ * @return {*}
+ */
+export const deserialize = ( value ) => {
+
+	if( typeof value === 'string' ) {
+		if( value === 'null' ) return null;
+		else if( value === 'true' ) return true;
+		else if( value === 'false' ) return false;
+		else if( value.match( /^-?[\d\.]+$/ ) ) return parseFloat( value );
+	}
+
+	return value;
+
+}
+
+/**
+ * Measures the distance in pixels between point a
+ * and point b.
+ *
+ * @param {object} a point with x/y properties
+ * @param {object} b point with x/y properties
+ *
+ * @return {number}
+ */
+export const distanceBetween = ( a, b ) => {
+
+	let dx = a.x - b.x,
+		dy = a.y - b.y;
+
+	return Math.sqrt( dx*dx + dy*dy );
+
+}
+
+/**
+ * Applies a CSS transform to the target element.
+ *
+ * @param {HTMLElement} element
+ * @param {string} transform
+ */
+export const transformElement = ( element, transform ) => {
+
+	element.style.transform = transform;
+
+}
+
+/**
+ * Element.matches with IE support.
+ *
+ * @param {HTMLElement} target The element to match
+ * @param {String} selector The CSS selector to match
+ * the element against
+ *
+ * @return {Boolean}
+ */
+export const matches = ( target, selector ) => {
+
+	let matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;
+
+	return !!( matchesMethod && matchesMethod.call( target, selector ) );
+
+}
+
+/**
+ * Find the closest parent that matches the given
+ * selector.
+ *
+ * @param {HTMLElement} target The child element
+ * @param {String} selector The CSS selector to match
+ * the parents against
+ *
+ * @return {HTMLElement} The matched parent or null
+ * if no matching parent was found
+ */
+export const closest = ( target, selector ) => {
+
+	// Native Element.closest
+	if( typeof target.closest === 'function' ) {
+		return target.closest( selector );
+	}
+
+	// Polyfill
+	while( target ) {
+		if( matches( target, selector ) ) {
+			return target;
+		}
+
+		// Keep searching
+		target = target.parentNode;
+	}
+
+	return null;
+
+}
+
+/**
+ * Handling the fullscreen functionality via the fullscreen API
+ *
+ * @see http://fullscreen.spec.whatwg.org/
+ * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
+ */
+export const enterFullscreen = element => {
+
+	element = element || document.documentElement;
+
+	// Check which implementation is available
+	let requestMethod = element.requestFullscreen ||
+						element.webkitRequestFullscreen ||
+						element.webkitRequestFullScreen ||
+						element.mozRequestFullScreen ||
+						element.msRequestFullscreen;
+
+	if( requestMethod ) {
+		requestMethod.apply( element );
+	}
+
+}
+
+/**
+ * Creates an HTML element and returns a reference to it.
+ * If the element already exists the existing instance will
+ * be returned.
+ *
+ * @param {HTMLElement} container
+ * @param {string} tagname
+ * @param {string} classname
+ * @param {string} innerHTML
+ *
+ * @return {HTMLElement}
+ */
+export const createSingletonNode = ( container, tagname, classname, innerHTML='' ) => {
+
+	// Find all nodes matching the description
+	let nodes = container.querySelectorAll( '.' + classname );
+
+	// Check all matches to find one which is a direct child of
+	// the specified container
+	for( let i = 0; i < nodes.length; i++ ) {
+		let testNode = nodes[i];
+		if( testNode.parentNode === container ) {
+			return testNode;
+		}
+	}
+
+	// If no node was found, create it now
+	let node = document.createElement( tagname );
+	node.className = classname;
+	node.innerHTML = innerHTML;
+	container.appendChild( node );
+
+	return node;
+
+}
+
+/**
+ * Injects the given CSS styles into the DOM.
+ *
+ * @param {string} value
+ */
+export const createStyleSheet = ( value ) => {
+
+	let tag = document.createElement( 'style' );
+	tag.type = 'text/css';
+
+	if( value && value.length > 0 ) {
+		if( tag.styleSheet ) {
+			tag.styleSheet.cssText = value;
+		}
+		else {
+			tag.appendChild( document.createTextNode( value ) );
+		}
+	}
+
+	document.head.appendChild( tag );
+
+	return tag;
+
+}
+
+/**
+ * Returns a key:value hash of all query params.
+ */
+export const getQueryHash = () => {
+
+	let query = {};
+
+	location.search.replace( /[A-Z0-9]+?=([\w\.%-]*)/gi, a => {
+		query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
+	} );
+
+	// Basic deserialization
+	for( let i in query ) {
+		let value = query[ i ];
+
+		query[ i ] = deserialize( unescape( value ) );
+	}
+
+	// Do not accept new dependencies via query config to avoid
+	// the potential of malicious script injection
+	if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
+	return query;
+
+}
+
+/**
+ * Returns the remaining height within the parent of the
+ * target element.
+ *
+ * remaining height = [ configured parent height ] - [ current parent height ]
+ *
+ * @param {HTMLElement} element
+ * @param {number} [height]
+ */
+export const getRemainingHeight = ( element, height = 0 ) => {
+
+	if( element ) {
+		let newHeight, oldHeight = element.style.height;
+
+		// Change the .stretch element height to 0 in order find the height of all
+		// the other elements
+		element.style.height = '0px';
+
+		// In Overview mode, the parent (.slide) height is set of 700px.
+		// Restore it temporarily to its natural height.
+		element.parentNode.style.height = 'auto';
+
+		newHeight = height - element.parentNode.offsetHeight;
+
+		// Restore the old height, just in case
+		element.style.height = oldHeight + 'px';
+
+		// Clear the parent (.slide) height. .removeProperty works in IE9+
+		element.parentNode.style.removeProperty('height');
+
+		return newHeight;
+	}
+
+	return height;
+
+}
\ No newline at end of file
