aboutsummaryrefslogtreecommitdiffhomepage
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/reveal.js974
-rw-r--r--js/reveal.min.js5
2 files changed, 780 insertions, 199 deletions
diff --git a/js/reveal.js b/js/reveal.js
index 794911c..d1d8ea6 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -12,7 +12,7 @@ var Reveal = (function(){
var SLIDES_SELECTOR = '.reveal .slides section',
HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
- HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-child',
+ HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-of-type',
// Configurations defaults, can be overridden at initialization time
config = {
@@ -35,6 +35,9 @@ var Reveal = (function(){
// Display a presentation progress bar
progress: true,
+ // Display the page number of the current slide
+ slideNumber: false,
+
// Push each slide change to the browser history
history: false,
@@ -44,7 +47,7 @@ var Reveal = (function(){
// Enable the slide overview mode
overview: true,
- // Vertical centring of slides
+ // Vertical centering of slides
center: true,
// Enables touch navigation on devices with touch input
@@ -68,6 +71,9 @@ var Reveal = (function(){
// by using a data-autoslide attribute on your slides
autoSlide: 0,
+ // Stop auto-sliding after user input
+ autoSlideStoppable: true,
+
// Enable slide navigation via mouse wheel
mouseWheel: false,
@@ -80,6 +86,9 @@ var Reveal = (function(){
// Opens links in an iframe preview overlay
previewLinks: false,
+ // Focuses body when page changes visiblity to ensure keyboard shortcuts work
+ focusBodyOnPageVisiblityChange: true,
+
// Theme (see /css/theme)
theme: null,
@@ -92,19 +101,23 @@ var Reveal = (function(){
// Transition style for full page slide backgrounds
backgroundTransition: 'default', // default/linear/none
+ // Parallax background image
+ parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
+
+ // Parallax background size
+ parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
+
// Number of slides away from the current that are visible
viewDistance: 3,
// Script dependencies to load
dependencies: []
+
},
// Flags if reveal.js is loaded (has dispatched the 'ready' event)
loaded = false,
- // The current auto-slide duration
- autoSlide = 0,
-
// The horizontal and vertical index of the currently active slide
indexh,
indexv,
@@ -113,6 +126,8 @@ var Reveal = (function(){
previousSlide,
currentSlide,
+ previousBackground,
+
// Slides may hold a data-state attribute which we pick up and apply
// as a class to the body. This list contains the combined state of
// all current slides.
@@ -124,11 +139,8 @@ var Reveal = (function(){
// Cached references to DOM elements
dom = {},
- // Client support for CSS 3D transforms, see #checkCapabilities()
- supports3DTransforms,
-
- // Client support for CSS 2D transforms, see #checkCapabilities()
- supports2DTransforms,
+ // Features supported by the browser, see #checkCapabilities()
+ features = {},
// Client is a mobile device, see #checkCapabilities()
isMobileDevice,
@@ -136,9 +148,6 @@ var Reveal = (function(){
// Throttles mouse wheel navigation
lastMouseWheelStep = 0,
- // An interval used to automatically move on to the next slide
- autoSlideTimeout = 0,
-
// Delays updates to the URL due to a Chrome thumbnailer bug
writeURLTimeout = 0,
@@ -151,6 +160,15 @@ var Reveal = (function(){
// Flags if the interaction event listeners are bound
eventsAreBound = false,
+ // The current auto-slide duration
+ autoSlide = 0,
+
+ // Auto slide properties
+ autoSlidePlayer,
+ autoSlideTimeout = 0,
+ autoSlideStartTime = -1,
+ autoSlidePaused = false,
+
// Holds information about the currently ongoing touch input
touch = {
startX: 0,
@@ -168,7 +186,7 @@ var Reveal = (function(){
checkCapabilities();
- if( !supports2DTransforms && !supports3DTransforms ) {
+ if( !features.transforms2d && !features.transforms3d ) {
document.body.setAttribute( 'class', 'no-transforms' );
// If the browser doesn't support core features we won't be
@@ -179,8 +197,15 @@ var Reveal = (function(){
// Force a layout when the whole page, incl fonts, has loaded
window.addEventListener( 'load', layout, false );
+ var query = Reveal.getQueryHash();
+
+ // Do not accept new dependencies via query config to avoid
+ // the potential of malicious script injection
+ if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
+
// Copy options over to our config object
extend( config, options );
+ extend( config, query );
// Hide the address bar in mobile browsers
hideAddressBar();
@@ -196,33 +221,63 @@ var Reveal = (function(){
*/
function checkCapabilities() {
- supports3DTransforms = 'WebkitPerspective' in document.body.style ||
+ features.transforms3d = 'WebkitPerspective' in document.body.style ||
'MozPerspective' in document.body.style ||
'msPerspective' in document.body.style ||
'OPerspective' in document.body.style ||
'perspective' in document.body.style;
- supports2DTransforms = 'WebkitTransform' in document.body.style ||
+ features.transforms2d = 'WebkitTransform' in document.body.style ||
'MozTransform' in document.body.style ||
'msTransform' in document.body.style ||
'OTransform' in document.body.style ||
'transform' in document.body.style;
+ features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
+ features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function';
+
+ features.canvas = !!document.createElement( 'canvas' ).getContext;
+
isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
}
- /**
- * Loads the dependencies of reveal.js. Dependencies are
- * defined via the configuration option 'dependencies'
- * and will be loaded prior to starting/binding reveal.js.
- * Some dependencies may have an 'async' flag, if so they
- * will load after reveal.js has been started up.
- */
+
+ /**
+ * Loads the dependencies of reveal.js. Dependencies are
+ * defined via the configuration option 'dependencies'
+ * and will be loaded prior to starting/binding reveal.js.
+ * Some dependencies may have an 'async' flag, if so they
+ * will load after reveal.js has been started up.
+ */
function load() {
var scripts = [],
- scriptsAsync = [];
+ scriptsAsync = [],
+ scriptsToPreload = 0;
+
+ // Called once synchronous scripts finish loading
+ function proceed() {
+ if( scriptsAsync.length ) {
+ // Load asynchronous scripts
+ head.js.apply( null, scriptsAsync );
+ }
+
+ start();
+ }
+
+ function loadScript( s ) {
+ head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() {
+ // Extension may contain callback functions
+ if( typeof s.callback === 'function' ) {
+ s.callback.apply( this );
+ }
+
+ if( --scriptsToPreload === 0 ) {
+ proceed();
+ }
+ });
+ }
for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
var s = config.dependencies[i];
@@ -236,25 +291,12 @@ var Reveal = (function(){
scripts.push( s.src );
}
- // Extension may contain callback functions
- if( typeof s.callback === 'function' ) {
- head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], s.callback );
- }
- }
- }
-
- // Called once synchronous scripts finish loading
- function proceed() {
- if( scriptsAsync.length ) {
- // Load asynchronous scripts
- head.js.apply( null, scriptsAsync );
+ loadScript( s );
}
-
- start();
}
if( scripts.length ) {
- head.ready( proceed );
+ scriptsToPreload = scripts.length;
// Load synchronous scripts
head.js.apply( null, scripts );
@@ -275,7 +317,7 @@ var Reveal = (function(){
setupDOM();
// Decorate the slide DOM elements with state classes (past/future)
- setupSlides();
+ formatSlides();
// Updates the presentation to match the current configuration values
configure();
@@ -283,6 +325,9 @@ var Reveal = (function(){
// Read the initial hash
readURL();
+ // Update all backgrounds
+ updateBackground( true );
+
// Notify listeners that the presentation is ready but use a 1ms
// timeout to ensure it's not fired synchronously after #initialize()
setTimeout( function() {
@@ -301,26 +346,6 @@ var Reveal = (function(){
}
/**
- * Iterates through and decorates slides DOM elements with
- * appropriate classes.
- */
- function setupSlides() {
-
- var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
- horizontalSlides.forEach( function( horizontalSlide ) {
-
- var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
- verticalSlides.forEach( function( verticalSlide, y ) {
-
- if( y > 0 ) verticalSlide.classList.add( 'future' );
-
- } );
-
- } );
-
- }
-
- /**
* Finds and stores references to DOM elements which are
* required by the presentation. If a required element is
* not found, it is created.
@@ -349,6 +374,9 @@ var Reveal = (function(){
'<div class="navigate-up"></div>' +
'<div class="navigate-down"></div>' );
+ // Slide number
+ dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
+
// State background element [DEPRECATED]
createSingletonNode( dom.wrapper, 'div', 'state-background', null );
@@ -422,7 +450,7 @@ var Reveal = (function(){
if( data.background ) {
// Auto-wrap image urls in url(...)
- if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
+ if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
element.style.backgroundImage = 'url('+ data.background +')';
}
else {
@@ -430,6 +458,10 @@ var Reveal = (function(){
}
}
+ if( data.background || data.backgroundColor || data.backgroundImage ) {
+ element.setAttribute( 'data-background-hash', data.background + data.backgroundSize + data.backgroundImage + data.backgroundColor + data.backgroundRepeat + data.backgroundPosition + data.backgroundTransition );
+ }
+
// Additional and optional background properties
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
if( data.backgroundImage ) element.style.backgroundImage = 'url("' + data.backgroundImage + '")';
@@ -470,6 +502,28 @@ var Reveal = (function(){
} );
+ // Add parallax background if specified
+ if( config.parallaxBackgroundImage ) {
+
+ dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")';
+ dom.background.style.backgroundSize = config.parallaxBackgroundSize;
+
+ // Make sure the below properties are set on the element - these properties are
+ // needed for proper transitions to be set on the element via CSS. To remove
+ // annoying background slide-in effect when the presentation starts, apply
+ // these properties after short time delay
+ setTimeout( function() {
+ dom.wrapper.classList.add( 'has-parallax-background' );
+ }, 1 );
+
+ }
+ else {
+
+ dom.background.style.backgroundImage = '';
+ dom.wrapper.classList.remove( 'has-parallax-background' );
+
+ }
+
}
/**
@@ -478,6 +532,8 @@ var Reveal = (function(){
*/
function configure( options ) {
+ var numberOfSlides = document.querySelectorAll( SLIDES_SELECTOR ).length;
+
dom.wrapper.classList.remove( config.transition );
// New config options may be passed when this method
@@ -485,7 +541,7 @@ var Reveal = (function(){
if( typeof options === 'object' ) extend( config, options );
// Force linear transition based on browser capabilities
- if( supports3DTransforms === false ) config.transition = 'linear';
+ if( features.transforms3d === false ) config.transition = 'linear';
dom.wrapper.classList.add( config.transition );
@@ -535,6 +591,20 @@ var Reveal = (function(){
enablePreviewLinks( '[data-preview-link]' );
}
+ // Auto-slide playback controls
+ if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
+ autoSlidePlayer = new Playback( dom.wrapper, function() {
+ return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
+ } );
+
+ autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
+ autoSlidePaused = false;
+ }
+ else if( autoSlidePlayer ) {
+ autoSlidePlayer.destroy();
+ autoSlidePlayer = null;
+ }
+
// Load the theme in the config, if it's not already loaded
if( config.theme && dom.theme ) {
var themeURL = dom.theme.getAttribute( 'href' );
@@ -578,10 +648,28 @@ var Reveal = (function(){
document.addEventListener( 'keydown', onDocumentKeyDown, false );
}
- if ( config.progress && dom.progress ) {
+ if( config.progress && dom.progress ) {
dom.progress.addEventListener( 'click', onProgressClicked, false );
}
+ if( config.focusBodyOnPageVisiblityChange ) {
+ var visibilityChange;
+
+ if( 'hidden' in document ) {
+ visibilityChange = 'visibilitychange';
+ }
+ else if( 'msHidden' in document ) {
+ visibilityChange = 'msvisibilitychange';
+ }
+ else if( 'webkitHidden' in document ) {
+ visibilityChange = 'webkitvisibilitychange';
+ }
+
+ if( visibilityChange ) {
+ document.addEventListener( visibilityChange, onPageVisibilityChange, false );
+ }
+ }
+
[ 'touchstart', 'click' ].forEach( function( eventName ) {
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
@@ -784,16 +872,6 @@ var Reveal = (function(){
*/
function removeAddressBar() {
- // Portrait and not Chrome for iOS
- if( window.orientation === 0 && !/crios/gi.test( navigator.userAgent ) ) {
- document.documentElement.style.overflow = 'scroll';
- document.body.style.height = '120%';
- }
- else {
- document.documentElement.style.overflow = '';
- document.body.style.height = '100%';
- }
-
setTimeout( function() {
window.scrollTo( 0, 1 );
}, 10 );
@@ -818,7 +896,7 @@ var Reveal = (function(){
*/
function enableRollingLinks() {
- if( supports3DTransforms && !( 'msPerspective' in document.body.style ) ) {
+ if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a:not(.image)' );
for( var i = 0, len = anchors.length; i < len; i++ ) {
@@ -942,38 +1020,6 @@ var Reveal = (function(){
}
/**
- * 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.
- */
- function sortFragments( fragments ) {
-
- var a = toArray( fragments );
-
- a.forEach( function( el, idx ) {
- if( !el.hasAttribute( 'data-fragment-index' ) ) {
- el.setAttribute( 'data-fragment-index', idx );
- }
- } );
-
- a.sort( function( l, r ) {
- return l.getAttribute( 'data-fragment-index' ) - r.getAttribute( 'data-fragment-index');
- } );
-
- return a;
-
- }
-
- /**
* Applies JavaScript-controlled layout rules to the
* presentation.
*/
@@ -1038,7 +1084,7 @@ var Reveal = (function(){
continue;
}
- if( config.center ) {
+ if( config.center || slide.classList.contains( 'center' ) ) {
// Vertical stacks are not centred since their section
// children will be
if( slide.classList.contains( 'stack' ) ) {
@@ -1055,6 +1101,7 @@ var Reveal = (function(){
}
updateProgress();
+ updateParallax();
}
@@ -1471,19 +1518,9 @@ var Reveal = (function(){
// Store references to the previous and current slides
currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
-
// Show fragment, if specified
if( typeof f !== 'undefined' ) {
- var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
-
- toArray( fragments ).forEach( function( fragment, indexf ) {
- if( indexf < f ) {
- fragment.classList.add( 'visible' );
- }
- else {
- fragment.classList.remove( 'visible' );
- }
- } );
+ navigateFragment( f );
}
// Dispatch an event if the slide changed
@@ -1533,10 +1570,14 @@ var Reveal = (function(){
updateControls();
updateProgress();
updateBackground();
+ updateParallax();
+ updateSlideNumber();
// Update the URL hash
writeURL();
+ cueAutoSlide();
+
}
/**
@@ -1562,9 +1603,36 @@ var Reveal = (function(){
// Re-create the slide backgrounds
createBackgrounds();
+ formatSlides();
+
updateControls();
updateProgress();
- updateBackground();
+ updateBackground( true );
+ updateSlideNumber();
+
+ }
+
+ /**
+ * Iterates through and decorates slides DOM elements with
+ * appropriate classes.
+ */
+ function formatSlides() {
+
+ var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
+ horizontalSlides.forEach( function( horizontalSlide ) {
+
+ var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
+ verticalSlides.forEach( function( verticalSlide, y ) {
+
+ if( y > 0 ) verticalSlide.classList.add( 'future' );
+
+ sortFragments( verticalSlide.querySelectorAll( '.fragment' ) );
+
+ } );
+
+ if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) );
+
+ } );
}
@@ -1617,16 +1685,27 @@ var Reveal = (function(){
if( i < index ) {
// Any element previous to index is given the 'past' class
element.classList.add( reverse ? 'future' : 'past' );
+
+ var pastFragments = toArray( element.querySelectorAll( '.fragment' ) );
+
+ // Show all fragments on prior slides
+ while( pastFragments.length ) {
+ var pastFragment = pastFragments.pop();
+ pastFragment.classList.add( 'visible' );
+ pastFragment.classList.remove( 'current-fragment' );
+ }
}
else if( i > index ) {
// Any element subsequent to index is given the 'future' class
element.classList.add( reverse ? 'past' : 'future' );
- var fragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
+ var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
// No fragments in future slides should be visible ahead of time
- while( fragments.length ) {
- fragments.pop().classList.remove( 'visible' );
+ while( futureFragments.length ) {
+ var futureFragment = futureFragments.pop();
+ futureFragment.classList.remove( 'visible' );
+ futureFragment.classList.remove( 'current-fragment' );
}
}
@@ -1647,18 +1726,6 @@ var Reveal = (function(){
state = state.concat( slideState.split( ' ' ) );
}
- // If this slide has a data-autoslide attribute associated use this as
- // autoSlide value otherwise use the global configured time
- var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' );
- if( slideAutoSlide ) {
- autoSlide = parseInt( slideAutoSlide, 10 );
- }
- else {
- autoSlide = config.autoSlide;
- }
-
- cueAutoSlide();
-
}
else {
// Since there are no slides we can't be anywhere beyond the
@@ -1775,6 +1842,25 @@ var Reveal = (function(){
}
/**
+ * Updates the slide number div to reflect the current slide.
+ */
+ function updateSlideNumber() {
+
+ // Update slide number if enabled
+ if( config.slideNumber && dom.slideNumber) {
+
+ // Display the number of the page using 'indexh - indexv' format
+ var indexString = indexh;
+ if( indexv > 0 ) {
+ indexString += ' - ' + indexv;
+ }
+
+ dom.slideNumber.innerHTML = indexString;
+ }
+
+ }
+
+ /**
* Updates the state of all control/navigation arrows.
*/
function updateControls() {
@@ -1825,29 +1911,70 @@ var Reveal = (function(){
}
/**
- * Updates the background elements to reflect the current
+ * Updates the background elements to reflect the current
* slide.
+ *
+ * @param {Boolean} includeAll If true, the backgrounds of
+ * all vertical slides (not just the present) will be updated.
*/
- function updateBackground() {
+ function updateBackground( includeAll ) {
+
+ var currentBackground = null;
+
+ // Reverse past/future classes when in RTL mode
+ var horizontalPast = config.rtl ? 'future' : 'past',
+ horizontalFuture = config.rtl ? 'past' : 'future';
- // Update the classes of all backgrounds to match the
+ // Update the classes of all backgrounds to match the
// states of their slides (past/present/future)
toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) {
- // Reverse past/future classes when in RTL mode
- var horizontalPast = config.rtl ? 'future' : 'past',
- horizontalFuture = config.rtl ? 'past' : 'future';
+ if( h < indexh ) {
+ backgroundh.className = 'slide-background ' + horizontalPast;
+ }
+ else if ( h > indexh ) {
+ backgroundh.className = 'slide-background ' + horizontalFuture;
+ }
+ else {
+ backgroundh.className = 'slide-background present';
- backgroundh.className = 'slide-background ' + ( h < indexh ? horizontalPast : h > indexh ? horizontalFuture : 'present' );
+ // Store a reference to the current background element
+ currentBackground = backgroundh;
+ }
- toArray( backgroundh.childNodes ).forEach( function( backgroundv, v ) {
+ if( includeAll || h === indexh ) {
+ toArray( backgroundh.childNodes ).forEach( function( backgroundv, v ) {
- backgroundv.className = 'slide-background ' + ( v < indexv ? 'past' : v > indexv ? 'future' : 'present' );
+ if( v < indexv ) {
+ backgroundv.className = 'slide-background past';
+ }
+ else if ( v > indexv ) {
+ backgroundv.className = 'slide-background future';
+ }
+ else {
+ backgroundv.className = 'slide-background present';
- } );
+ // Only if this is the present horizontal and vertical slide
+ if( h === indexh ) currentBackground = backgroundv;
+ }
+
+ } );
+ }
} );
+ // Don't transition between identical backgrounds. This
+ // prevents unwanted flicker.
+ if( currentBackground ) {
+ var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null;
+ var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
+ if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) {
+ dom.background.classList.add( 'no-transition' );
+ }
+
+ previousBackground = currentBackground;
+ }
+
// Allow the first background to apply without transition
setTimeout( function() {
dom.background.classList.remove( 'no-transition' );
@@ -1856,6 +1983,42 @@ var Reveal = (function(){
}
/**
+ * Updates the position of the parallax background based
+ * on the current slide index.
+ */
+ function updateParallax() {
+
+ if( config.parallaxBackgroundImage ) {
+
+ var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
+ verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
+
+ var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
+ backgroundWidth, backgroundHeight;
+
+ if( backgroundSize.length === 1 ) {
+ backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
+ }
+ else {
+ backgroundWidth = parseInt( backgroundSize[0], 10 );
+ backgroundHeight = parseInt( backgroundSize[1], 10 );
+ }
+
+ var slideWidth = dom.background.offsetWidth;
+ var horizontalSlideCount = horizontalSlides.length;
+ var horizontalOffset = -( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) * indexh;
+
+ var slideHeight = dom.background.offsetHeight;
+ var verticalSlideCount = verticalSlides.length;
+ var verticalOffset = verticalSlideCount > 0 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
+
+ dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
+
+ }
+
+ }
+
+ /**
* Determine what available routes there are for navigation.
*
* @return {Object} containing four booleans: left/right/up/down
@@ -1912,7 +2075,7 @@ var Reveal = (function(){
*/
function startEmbeddedContent( slide ) {
- if( slide ) {
+ if( slide && !isSpeakerNotes() ) {
// HTML5 media elements
toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
if( el.hasAttribute( 'data-autoplay' ) ) {
@@ -1920,10 +2083,15 @@ var Reveal = (function(){
}
} );
+ // iframe embeds
+ toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+ el.contentWindow.postMessage( 'slide:start', '*' );
+ });
+
// YouTube embeds
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
if( el.hasAttribute( 'data-autoplay' ) ) {
- el.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
+ el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
}
});
}
@@ -1944,10 +2112,15 @@ var Reveal = (function(){
}
} );
+ // iframe embeds
+ toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
+ el.contentWindow.postMessage( 'slide:stop', '*' );
+ });
+
// YouTube embeds
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
- el.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
+ el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
}
});
}
@@ -1955,6 +2128,16 @@ var Reveal = (function(){
}
/**
+ * Checks if this presentation is running inside of the
+ * speaker notes window.
+ */
+ function isSpeakerNotes() {
+
+ return !!window.location.search.match( /receiver/gi );
+
+ }
+
+ /**
* Reads the current URL (hash) and navigates accordingly.
*/
function readURL() {
@@ -2068,7 +2251,7 @@ var Reveal = (function(){
var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
if( hasFragments ) {
var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
- f = visibleFragments.length;
+ f = visibleFragments.length - 1;
}
}
@@ -2077,67 +2260,144 @@ var Reveal = (function(){
}
/**
- * Navigate to the next slide fragment.
+ * Return a sorted fragments list, ordered by an increasing
+ * "data-fragment-index" attribute.
*
- * @return {Boolean} true if there was a next fragment,
- * false otherwise
+ * 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.
*/
- function nextFragment() {
-
- if( currentSlide && config.fragments ) {
- var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment:not(.visible)' ) );
+ function sortFragments( fragments ) {
- if( fragments.length ) {
- // Find the index of the next fragment
- var index = fragments[0].getAttribute( 'data-fragment-index' );
+ fragments = toArray( fragments );
- // Find all fragments with the same index
- fragments = currentSlide.querySelectorAll( '.fragment[data-fragment-index="'+ index +'"]' );
+ var ordered = [],
+ unordered = [],
+ sorted = [];
- toArray( fragments ).forEach( function( element ) {
- element.classList.add( 'visible' );
- } );
+ // Group ordered and unordered elements
+ fragments.forEach( function( fragment, i ) {
+ if( fragment.hasAttribute( 'data-fragment-index' ) ) {
+ var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
- // Notify subscribers of the change
- dispatchEvent( 'fragmentshown', { fragment: fragments[0], fragments: fragments } );
+ if( !ordered[index] ) {
+ ordered[index] = [];
+ }
- updateControls();
- return true;
+ ordered[index].push( fragment );
}
- }
+ else {
+ unordered.push( [ fragment ] );
+ }
+ } );
- return false;
+ // 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
+ var index = 0;
+
+ // Push all fragments in their sorted order to an array,
+ // this flattens the groups
+ ordered.forEach( function( group ) {
+ group.forEach( function( fragment ) {
+ sorted.push( fragment );
+ fragment.setAttribute( 'data-fragment-index', index );
+ } );
+
+ index ++;
+ } );
+
+ return sorted;
}
/**
- * Navigate to the previous slide fragment.
+ * Navigate to the specified slide fragment.
*
- * @return {Boolean} true if there was a previous fragment,
- * false otherwise
+ * @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
*/
- function previousFragment() {
+ function navigateFragment( index, offset ) {
if( currentSlide && config.fragments ) {
- var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) );
+ var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
if( fragments.length ) {
- // Find the index of the previous fragment
- var index = fragments[ fragments.length - 1 ].getAttribute( 'data-fragment-index' );
- // Find all fragments with the same index
- fragments = currentSlide.querySelectorAll( '.fragment[data-fragment-index="'+ index +'"]' );
+ // If no index is specified, find the current
+ if( typeof index !== 'number' ) {
+ var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+
+ if( lastVisibleFragment ) {
+ index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+ }
+ else {
+ index = -1;
+ }
+ }
+
+ // If an offset is specified, apply it to the index
+ if( typeof offset === 'number' ) {
+ index += offset;
+ }
+
+ var fragmentsShown = [],
+ fragmentsHidden = [];
+
+ toArray( fragments ).forEach( function( element, i ) {
+
+ if( element.hasAttribute( 'data-fragment-index' ) ) {
+ i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
+ }
+
+ // Visible fragments
+ if( i <= index ) {
+ if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
+ element.classList.add( 'visible' );
+ element.classList.remove( 'current-fragment' );
+
+ if( i === index ) {
+ element.classList.add( 'current-fragment' );
+ }
+ }
+ // Hidden fragments
+ else {
+ if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
+ element.classList.remove( 'visible' );
+ element.classList.remove( 'current-fragment' );
+ }
+
- toArray( fragments ).forEach( function( f ) {
- f.classList.remove( 'visible' );
} );
- // Notify subscribers of the change
- dispatchEvent( 'fragmenthidden', { fragment: fragments[0], fragments: fragments } );
+ if( fragmentsHidden.length ) {
+ dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
+ }
+
+ if( fragmentsShown.length ) {
+ dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
+ }
updateControls();
- return true;
+
+ return !!( fragmentsShown.length || fragmentsHidden.length );
+
}
+
}
return false;
@@ -2145,15 +2405,81 @@ var Reveal = (function(){
}
/**
+ * Navigate to the next slide fragment.
+ *
+ * @return {Boolean} true if there was a next fragment,
+ * false otherwise
+ */
+ function nextFragment() {
+
+ return navigateFragment( null, 1 );
+
+ }
+
+ /**
+ * Navigate to the previous slide fragment.
+ *
+ * @return {Boolean} true if there was a previous fragment,
+ * false otherwise
+ */
+ function previousFragment() {
+
+ return navigateFragment( null, -1 );
+
+ }
+
+ /**
* Cues a new automated slide if enabled in the config.
*/
function cueAutoSlide() {
- clearTimeout( autoSlideTimeout );
+ cancelAutoSlide();
+
+ if( currentSlide ) {
+
+ var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
+ var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
+
+ // Pick value in the following priority order:
+ // 1. Current slide's data-autoslide
+ // 2. Parent slide's data-autoslide
+ // 3. Global autoSlide setting
+ if( slideAutoSlide ) {
+ autoSlide = parseInt( slideAutoSlide, 10 );
+ }
+ else if( parentAutoSlide ) {
+ autoSlide = parseInt( parentAutoSlide, 10 );
+ }
+ else {
+ autoSlide = config.autoSlide;
+ }
+
+ // If there are media elements with data-autoplay,
+ // automatically set the autoSlide duration to the
+ // length of that media
+ toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
+ if( el.hasAttribute( 'data-autoplay' ) ) {
+ if( autoSlide && el.duration * 1000 > autoSlide ) {
+ autoSlide = ( el.duration * 1000 ) + 1000;
+ }
+ }
+ } );
+
+ // Cue the next auto-slide if:
+ // - There is an autoSlide value
+ // - Auto-sliding isn't paused by the user
+ // - The presentation isn't paused
+ // - The overview isn't active
+ // - The presentation isn't over
+ if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
+ autoSlideTimeout = setTimeout( navigateNext, autoSlide );
+ autoSlideStartTime = Date.now();
+ }
+
+ if( autoSlidePlayer ) {
+ autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
+ }
- // Cue the next auto-slide if enabled
- if( autoSlide && !isPaused() && !isOverview() ) {
- autoSlideTimeout = setTimeout( navigateNext, autoSlide );
}
}
@@ -2164,6 +2490,25 @@ var Reveal = (function(){
function cancelAutoSlide() {
clearTimeout( autoSlideTimeout );
+ autoSlideTimeout = -1;
+
+ }
+
+ function pauseAutoSlide() {
+
+ autoSlidePaused = true;
+ clearTimeout( autoSlideTimeout );
+
+ if( autoSlidePlayer ) {
+ autoSlidePlayer.setPlaying( false );
+ }
+
+ }
+
+ function resumeAutoSlide() {
+
+ autoSlidePaused = false;
+ cueAutoSlide();
}
@@ -2263,14 +2608,25 @@ var Reveal = (function(){
// ----------------------------- EVENTS -------------------------------//
// --------------------------------------------------------------------//
+ /**
+ * Called by all event handlers that are based on user
+ * input.
+ */
+ function onUserInput( event ) {
+
+ if( config.autoSlideStoppable ) {
+ pauseAutoSlide();
+ }
+
+ }
/**
* Handler for the document level 'keydown' event.
- *
- * @param {Object} event
*/
function onDocumentKeyDown( event ) {
+ onUserInput( event );
+
// Check if there's a focused element that could be using
// the keyboard
var activeElement = document.activeElement;
@@ -2357,8 +2713,13 @@ var Reveal = (function(){
event.preventDefault();
}
// ESC or O key
- else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && supports3DTransforms ) {
- toggleOverview();
+ else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
+ if( dom.preview ) {
+ closePreview();
+ }
+ else {
+ toggleOverview();
+ }
event.preventDefault();
}
@@ -2400,6 +2761,8 @@ var Reveal = (function(){
// Each touch should only trigger one action
if( !touch.captured ) {
+ onUserInput( event );
+
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
@@ -2553,6 +2916,8 @@ var Reveal = (function(){
*/
function onProgressClicked( event ) {
+ onUserInput( event );
+
event.preventDefault();
var slidesTotal = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
@@ -2565,12 +2930,12 @@ var Reveal = (function(){
/**
* Event handler for navigation control buttons.
*/
- function onNavigateLeftClicked( event ) { event.preventDefault(); navigateLeft(); }
- function onNavigateRightClicked( event ) { event.preventDefault(); navigateRight(); }
- function onNavigateUpClicked( event ) { event.preventDefault(); navigateUp(); }
- function onNavigateDownClicked( event ) { event.preventDefault(); navigateDown(); }
- function onNavigatePrevClicked( event ) { event.preventDefault(); navigatePrev(); }
- function onNavigateNextClicked( event ) { event.preventDefault(); navigateNext(); }
+ function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
+ function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
+ function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
+ function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
+ function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
+ function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }
/**
* Handler for the window level 'hashchange' event.
@@ -2591,6 +2956,24 @@ var Reveal = (function(){
}
/**
+ * Handle for the window level 'visibilitychange' event.
+ */
+ function onPageVisibilityChange( event ) {
+
+ var isHidden = document.webkitHidden ||
+ document.msHidden ||
+ document.hidden;
+
+ // If, after clicking a link or similar and we're coming back,
+ // focus the document.body to ensure we can use keyboard shortcuts
+ if( isHidden === false && document.activeElement !== document.body ) {
+ document.activeElement.blur();
+ document.body.focus();
+ }
+
+ }
+
+ /**
* Invoked when a slide is and we're in the overview.
*/
function onOverviewSlideClicked( event ) {
@@ -2636,6 +3019,191 @@ var Reveal = (function(){
}
+ /**
+ * Handles click on the auto-sliding controls element.
+ */
+ function onAutoSlidePlayerClick( event ) {
+
+ // Replay
+ if( Reveal.isLastSlide() && config.loop === false ) {
+ slide( 0, 0 );
+ resumeAutoSlide();
+ }
+ // Resume
+ else if( autoSlidePaused ) {
+ resumeAutoSlide();
+ }
+ // Pause
+ else {
+ pauseAutoSlide();
+ }
+
+ }
+
+
+ // --------------------------------------------------------------------//
+ // ------------------------ PLAYBACK COMPONENT ------------------------//
+ // --------------------------------------------------------------------//
+
+
+ /**
+ * Constructor for the playback component, which displays
+ * play/pause/progress controls.
+ *
+ * @param {HTMLElement} container The component will append
+ * itself to this
+ * @param {Function} progressCheck A method which will be
+ * called frequently to get the current progress on a range
+ * of 0-1
+ */
+ function Playback( container, progressCheck ) {
+
+ // Cosmetics
+ this.diameter = 50;
+ this.thickness = 3;
+
+ // Flags if we are currently playing
+ this.playing = false;
+
+ // Current progress on a 0-1 range
+ this.progress = 0;
+
+ // Used to loop the animation smoothly
+ this.progressOffset = 1;
+
+ this.container = container;
+ this.progressCheck = progressCheck;
+
+ this.canvas = document.createElement( 'canvas' );
+ this.canvas.className = 'playback';
+ this.canvas.width = this.diameter;
+ this.canvas.height = this.diameter;
+ this.context = this.canvas.getContext( '2d' );
+
+ this.container.appendChild( this.canvas );
+
+ this.render();
+
+ }
+
+ Playback.prototype.setPlaying = function( value ) {
+
+ var wasPlaying = this.playing;
+
+ this.playing = value;
+
+ // Start repainting if we weren't already
+ if( !wasPlaying && this.playing ) {
+ this.animate();
+ }
+ else {
+ this.render();
+ }
+
+ };
+
+ Playback.prototype.animate = function() {
+
+ var progressBefore = this.progress;
+
+ this.progress = this.progressCheck();
+
+ // When we loop, offset the progress so that it eases
+ // smoothly rather than immediately resetting
+ if( progressBefore > 0.8 && this.progress < 0.2 ) {
+ this.progressOffset = this.progress;
+ }
+
+ this.render();
+
+ if( this.playing ) {
+ features.requestAnimationFrameMethod.call( window, this.animate.bind( this ) );
+ }
+
+ };
+
+ /**
+ * Renders the current progress and playback state.
+ */
+ Playback.prototype.render = function() {
+
+ var progress = this.playing ? this.progress : 0,
+ radius = ( this.diameter / 2 ) - this.thickness,
+ x = this.diameter / 2,
+ y = this.diameter / 2,
+ iconSize = 14;
+
+ // Ease towards 1
+ this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
+
+ var endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
+ var startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
+
+ this.context.save();
+ this.context.clearRect( 0, 0, this.diameter, this.diameter );
+
+ // Solid background color
+ this.context.beginPath();
+ this.context.arc( x, y, radius + 2, 0, Math.PI * 2, false );
+ this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
+ this.context.fill();
+
+ // Draw progress track
+ this.context.beginPath();
+ this.context.arc( x, y, radius, 0, Math.PI * 2, false );
+ this.context.lineWidth = this.thickness;
+ this.context.strokeStyle = '#666';
+ this.context.stroke();
+
+ if( this.playing ) {
+ // Draw progress on top of track
+ this.context.beginPath();
+ this.context.arc( x, y, radius, startAngle, endAngle, false );
+ this.context.lineWidth = this.thickness;
+ this.context.strokeStyle = '#fff';
+ this.context.stroke();
+ }
+
+ this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
+
+ // Draw play/pause icons
+ if( this.playing ) {
+ this.context.fillStyle = '#fff';
+ this.context.fillRect( 0, 0, iconSize / 2 - 2, iconSize );
+ this.context.fillRect( iconSize / 2 + 2, 0, iconSize / 2 - 2, iconSize );
+ }
+ else {
+ this.context.beginPath();
+ this.context.translate( 2, 0 );
+ this.context.moveTo( 0, 0 );
+ this.context.lineTo( iconSize - 2, iconSize / 2 );
+ this.context.lineTo( 0, iconSize );
+ this.context.fillStyle = '#fff';
+ this.context.fill();
+ }
+
+ this.context.restore();
+
+ };
+
+ Playback.prototype.on = function( type, listener ) {
+ this.canvas.addEventListener( type, listener, false );
+ };
+
+ Playback.prototype.off = function( type, listener ) {
+ this.canvas.removeEventListener( type, listener, false );
+ };
+
+ Playback.prototype.destroy = function() {
+
+ this.playing = false;
+
+ if( this.canvas.parentNode ) {
+ this.container.removeChild( this.canvas );
+ }
+
+ };
+
// --------------------------------------------------------------------//
// ------------------------------- API --------------------------------//
@@ -2655,6 +3223,9 @@ var Reveal = (function(){
down: navigateDown,
prev: navigatePrev,
next: navigateNext,
+
+ // Fragment methods
+ navigateFragment: navigateFragment,
prevFragment: previousFragment,
nextFragment: nextFragment,
@@ -2733,6 +3304,15 @@ var Reveal = (function(){
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
} );
+ // Basic deserialization
+ for( var i in query ) {
+ var value = query[ i ];
+ if( value === 'null' ) query[ i ] = null;
+ else if( value === 'true' ) query[ i ] = true;
+ else if( value === 'false' ) query[ i ] = false;
+ else if( !isNaN( parseFloat( value ) ) ) query[ i ] = parseFloat( value );
+ }
+
return query;
},
diff --git a/js/reveal.min.js b/js/reveal.min.js
index b3985aa..9a7a76f 100644
--- a/js/reveal.min.js
+++ b/js/reveal.min.js
@@ -1,8 +1,9 @@
/*!
- * reveal.js 2.6.0-dev (2013-09-11, 21:54)
+ * reveal.js 2.6.0-dev (2013-11-26, 18:20)
* http://lab.hakim.se/reveal-js
* MIT licensed
*
* Copyright (C) 2013 Hakim El Hattab, http://hakim.se
*/
-var Reveal=function(){"use strict";function a(a){return b(),Kb||Jb?(window.addEventListener("load",C,!1),l(Qb,a),s(),c(),void 0):(document.body.setAttribute("class","no-transforms"),void 0)}function b(){Jb="WebkitPerspective"in document.body.style||"MozPerspective"in document.body.style||"msPerspective"in document.body.style||"OPerspective"in document.body.style||"perspective"in document.body.style,Kb="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style,Lb=navigator.userAgent.match(/(iphone|ipod|android)/gi)}function c(){function a(){c.length&&head.js.apply(null,c),d()}for(var b=[],c=[],e=0,f=Qb.dependencies.length;f>e;e++){var g=Qb.dependencies[e];(!g.condition||g.condition())&&(g.async?c.push(g.src):b.push(g.src),"function"==typeof g.callback&&head.ready(g.src.match(/([\w\d_\-]*)\.?js$|[^\\\/]*$/i)[0],g.callback))}b.length?(head.ready(a),head.js.apply(null,b)):a()}function d(){f(),e(),i(),_(),setTimeout(function(){Vb.slides.classList.remove("no-transition"),Rb=!0,u("ready",{indexh:Fb,indexv:Gb,currentSlide:Ib})},1)}function e(){var a=m(document.querySelectorAll(Nb));a.forEach(function(a){var b=m(a.querySelectorAll("section"));b.forEach(function(a,b){b>0&&a.classList.add("future")})})}function f(){Vb.theme=document.querySelector("#theme"),Vb.wrapper=document.querySelector(".reveal"),Vb.slides=document.querySelector(".reveal .slides"),Vb.slides.classList.add("no-transition"),Vb.background=g(Vb.wrapper,"div","backgrounds",null),Vb.progress=g(Vb.wrapper,"div","progress","<span></span>"),Vb.progressbar=Vb.progress.querySelector("span"),g(Vb.wrapper,"aside","controls",'<div class="navigate-left"></div><div class="navigate-right"></div><div class="navigate-up"></div><div class="navigate-down"></div>'),g(Vb.wrapper,"div","state-background",null),g(Vb.wrapper,"div","pause-overlay",null),Vb.controls=document.querySelector(".reveal .controls"),Vb.controlsLeft=m(document.querySelectorAll(".navigate-left")),Vb.controlsRight=m(document.querySelectorAll(".navigate-right")),Vb.controlsUp=m(document.querySelectorAll(".navigate-up")),Vb.controlsDown=m(document.querySelectorAll(".navigate-down")),Vb.controlsPrev=m(document.querySelectorAll(".navigate-prev")),Vb.controlsNext=m(document.querySelectorAll(".navigate-next"))}function g(a,b,c,d){var e=a.querySelector("."+c);return e||(e=document.createElement(b),e.classList.add(c),null!==d&&(e.innerHTML=d),a.appendChild(e)),e}function h(){function a(a,b){var c={background:a.getAttribute("data-background"),backgroundSize:a.getAttribute("data-background-size"),backgroundImage:a.getAttribute("data-background-image"),backgroundColor:a.getAttribute("data-background-color"),backgroundRepeat:a.getAttribute("data-background-repeat"),backgroundPosition:a.getAttribute("data-background-position"),backgroundTransition:a.getAttribute("data-background-transition")},d=document.createElement("div");return d.className="slide-background",c.background&&(/^(http|file|\/\/)/gi.test(c.background)||/\.(png|jpg|jpeg|gif|bmp)$/gi.test(c.background)?d.style.backgroundImage="url("+c.background+")":d.style.background=c.background),c.backgroundSize&&(d.style.backgroundSize=c.backgroundSize),c.backgroundImage&&(d.style.backgroundImage='url("'+c.backgroundImage+'")'),c.backgroundColor&&(d.style.backgroundColor=c.backgroundColor),c.backgroundRepeat&&(d.style.backgroundRepeat=c.backgroundRepeat),c.backgroundPosition&&(d.style.backgroundPosition=c.backgroundPosition),c.backgroundTransition&&d.setAttribute("data-background-transition",c.backgroundTransition),b.appendChild(d),d}r()&&document.body.classList.add("print-pdf"),Vb.background.innerHTML="",Vb.background.classList.add("no-transition"),m(document.querySelectorAll(Nb)).forEach(function(b){var c;c=r()?a(b,b):a(b,Vb.background),m(b.querySelectorAll("section")).forEach(function(b){r()?a(b,b):a(b,c)})})}function i(a){if(Vb.wrapper.classList.remove(Qb.transition),"object"==typeof a&&l(Qb,a),Jb===!1&&(Qb.transition="linear"),Vb.wrapper.classList.add(Qb.transition),Vb.wrapper.setAttribute("data-transition-speed",Qb.transitionSpeed),Vb.wrapper.setAttribute("data-background-transition",Qb.backgroundTransition),Vb.controls.style.display=Qb.controls?"block":"none",Vb.progress.style.display=Qb.progress?"block":"none",Qb.rtl?Vb.wrapper.classList.add("rtl"):Vb.wrapper.classList.remove("rtl"),Qb.center?Vb.wrapper.classList.add("center"):Vb.wrapper.classList.remove("center"),Qb.mouseWheel?(document.addEventListener("DOMMouseScroll",tb,!1),document.addEventListener("mousewheel",tb,!1)):(document.removeEventListener("DOMMouseScroll",tb,!1),document.removeEventListener("mousewheel",tb,!1)),Qb.rollingLinks?v():w(),Qb.previewLinks?x():(y(),x("[data-preview-link]")),Qb.theme&&Vb.theme){var b=Vb.theme.getAttribute("href"),c=/[^\/]*?(?=\.css)/,d=b.match(c)[0];Qb.theme!==d&&(b=b.replace(c,Qb.theme),Vb.theme.setAttribute("href",b))}R()}function j(){_b=!0,window.addEventListener("hashchange",Bb,!1),window.addEventListener("resize",Cb,!1),Qb.touch&&(Vb.wrapper.addEventListener("touchstart",nb,!1),Vb.wrapper.addEventListener("touchmove",ob,!1),Vb.wrapper.addEventListener("touchend",pb,!1),window.navigator.msPointerEnabled&&(Vb.wrapper.addEventListener("MSPointerDown",qb,!1),Vb.wrapper.addEventListener("MSPointerMove",rb,!1),Vb.wrapper.addEventListener("MSPointerUp",sb,!1))),Qb.keyboard&&document.addEventListener("keydown",mb,!1),Qb.progress&&Vb.progress&&Vb.progress.addEventListener("click",ub,!1),["touchstart","click"].forEach(function(a){Vb.controlsLeft.forEach(function(b){b.addEventListener(a,vb,!1)}),Vb.controlsRight.forEach(function(b){b.addEventListener(a,wb,!1)}),Vb.controlsUp.forEach(function(b){b.addEventListener(a,xb,!1)}),Vb.controlsDown.forEach(function(b){b.addEventListener(a,yb,!1)}),Vb.controlsPrev.forEach(function(b){b.addEventListener(a,zb,!1)}),Vb.controlsNext.forEach(function(b){b.addEventListener(a,Ab,!1)})})}function k(){_b=!1,document.removeEventListener("keydown",mb,!1),window.removeEventListener("hashchange",Bb,!1),window.removeEventListener("resize",Cb,!1),Vb.wrapper.removeEventListener("touchstart",nb,!1),Vb.wrapper.removeEventListener("touchmove",ob,!1),Vb.wrapper.removeEventListener("touchend",pb,!1),window.navigator.msPointerEnabled&&(Vb.wrapper.removeEventListener("MSPointerDown",qb,!1),Vb.wrapper.removeEventListener("MSPointerMove",rb,!1),Vb.wrapper.removeEventListener("MSPointerUp",sb,!1)),Qb.progress&&Vb.progress&&Vb.progress.removeEventListener("click",ub,!1),["touchstart","click"].forEach(function(a){Vb.controlsLeft.forEach(function(b){b.removeEventListener(a,vb,!1)}),Vb.controlsRight.forEach(function(b){b.removeEventListener(a,wb,!1)}),Vb.controlsUp.forEach(function(b){b.removeEventListener(a,xb,!1)}),Vb.controlsDown.forEach(function(b){b.removeEventListener(a,yb,!1)}),Vb.controlsPrev.forEach(function(b){b.removeEventListener(a,zb,!1)}),Vb.controlsNext.forEach(function(b){b.removeEventListener(a,Ab,!1)})})}function l(a,b){for(var c in b)a[c]=b[c]}function m(a){return Array.prototype.slice.call(a)}function n(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}function o(a,b){a.style.WebkitTransform=b,a.style.MozTransform=b,a.style.msTransform=b,a.style.OTransform=b,a.style.transform=b}function p(a){var b=0;if(a){var c=0;m(a.childNodes).forEach(function(a){"number"==typeof a.offsetTop&&a.style&&("absolute"===a.style.position&&(c+=1),b=Math.max(b,a.offsetTop+a.offsetHeight))}),0===c&&(b=a.offsetHeight)}return b}function q(a,b){if(b=b||0,a){var c=a.parentNode,d=c.childNodes;m(d).forEach(function(c){if("number"==typeof c.offsetHeight&&c!==a){var d=window.getComputedStyle(c),e=parseInt(d.marginTop,10),f=parseInt(d.marginBottom,10);b-=c.offsetHeight+e+f}});var e=window.getComputedStyle(a);b-=parseInt(e.marginTop,10)+parseInt(e.marginBottom,10)}return b}function r(){return/print-pdf/gi.test(window.location.search)}function s(){Qb.hideAddressBar&&Lb&&(window.addEventListener("load",t,!1),window.addEventListener("orientationchange",t,!1))}function t(){0!==window.orientation||/crios/gi.test(navigator.userAgent)?(document.documentElement.style.overflow="",document.body.style.height="100%"):(document.documentElement.style.overflow="scroll",document.body.style.height="120%"),setTimeout(function(){window.scrollTo(0,1)},10)}function u(a,b){var c=document.createEvent("HTMLEvents",1,2);c.initEvent(a,!0,!0),l(c,b),Vb.wrapper.dispatchEvent(c)}function v(){if(Jb&&!("msPerspective"in document.body.style))for(var a=document.querySelectorAll(Mb+" a:not(.image)"),b=0,c=a.length;c>b;b++){var d=a[b];if(!(!d.textContent||d.querySelector("*")||d.className&&d.classList.contains(d,"roll"))){var e=document.createElement("span");e.setAttribute("data-title",d.text),e.innerHTML=d.innerHTML,d.classList.add("roll"),d.innerHTML="",d.appendChild(e)}}}function w(){for(var a=document.querySelectorAll(Mb+" a.roll"),b=0,c=a.length;c>b;b++){var d=a[b],e=d.querySelector("span");e&&(d.classList.remove("roll"),d.innerHTML=e.innerHTML)}}function x(a){var b=m(document.querySelectorAll(a?a:"a"));b.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.addEventListener("click",Eb,!1)})}function y(){var a=m(document.querySelectorAll("a"));a.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.removeEventListener("click",Eb,!1)})}function z(a){A(),Vb.preview=document.createElement("div"),Vb.preview.classList.add("preview-link-overlay"),Vb.wrapper.appendChild(Vb.preview),Vb.preview.innerHTML=["<header>",'<a class="close" href="#"><span class="icon"></span></a>','<a class="external" href="'+a+'" target="_blank"><span class="icon"></span></a>',"</header>",'<div class="spinner"></div>','<div class="viewport">','<iframe src="'+a+'"></iframe>',"</div>"].join(""),Vb.preview.querySelector("iframe").addEventListener("load",function(){Vb.preview.classList.add("loaded")},!1),Vb.preview.querySelector(".close").addEventListener("click",function(a){A(),a.preventDefault()},!1),Vb.preview.querySelector(".external").addEventListener("click",function(){A()},!1),setTimeout(function(){Vb.preview.classList.add("visible")},1)}function A(){Vb.preview&&(Vb.preview.setAttribute("src",""),Vb.preview.parentNode.removeChild(Vb.preview),Vb.preview=null)}function B(a){var b=m(a);return b.forEach(function(a,b){a.hasAttribute("data-fragment-index")||a.setAttribute("data-fragment-index",b)}),b.sort(function(a,b){return a.getAttribute("data-fragment-index")-b.getAttribute("data-fragment-index")}),b}function C(){if(Vb.wrapper&&!r()){var a=Vb.wrapper.offsetWidth,b=Vb.wrapper.offsetHeight;a-=b*Qb.margin,b-=b*Qb.margin;var c=Qb.width,d=Qb.height,e=20;D(Qb.width,Qb.height,e),"string"==typeof c&&/%$/.test(c)&&(c=parseInt(c,10)/100*a),"string"==typeof d&&/%$/.test(d)&&(d=parseInt(d,10)/100*b),Vb.slides.style.width=c+"px",Vb.slides.style.height=d+"px",Ub=Math.min(a/c,b/d),Ub=Math.max(Ub,Qb.minScale),Ub=Math.min(Ub,Qb.maxScale),"undefined"==typeof Vb.slides.style.zoom||navigator.userAgent.match(/(iphone|ipod|ipad|android)/gi)?o(Vb.slides,"translate(-50%, -50%) scale("+Ub+") translate(50%, 50%)"):Vb.slides.style.zoom=Ub;for(var f=m(document.querySelectorAll(Mb)),g=0,h=f.length;h>g;g++){var i=f[g];"none"!==i.style.display&&(i.style.top=Qb.center?i.classList.contains("stack")?0:Math.max(-(p(i)/2)-e,-d/2)+"px":"")}U()}}function D(a,b,c){m(Vb.slides.querySelectorAll("section > .stretch")).forEach(function(d){var e=q(d,b-2*c);if(/(img|video)/gi.test(d.nodeName)){var f=d.naturalWidth||d.videoWidth,g=d.naturalHeight||d.videoHeight,h=Math.min(a/f,e/g);d.style.width=f*h+"px",d.style.height=g*h+"px"}else d.style.width=a+"px",d.style.height=e+"px"})}function E(a,b){"object"==typeof a&&"function"==typeof a.setAttribute&&a.setAttribute("data-previous-indexv",b||0)}function F(a){if("object"==typeof a&&"function"==typeof a.setAttribute&&a.classList.contains("stack")){var b=a.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(a.getAttribute(b)||0,10)}return 0}function G(){if(Qb.overview){fb();var a=Vb.wrapper.classList.contains("overview"),b=window.innerWidth<400?1e3:2500;Vb.wrapper.classList.add("overview"),Vb.wrapper.classList.remove("overview-deactivating"),clearTimeout(Zb),clearTimeout($b),Zb=setTimeout(function(){for(var c=document.querySelectorAll(Nb),d=0,e=c.length;e>d;d++){var f=c[d],g=Qb.rtl?-105:105;if(f.setAttribute("data-index-h",d),o(f,"translateZ(-"+b+"px) translate("+(d-Fb)*g+"%, 0%)"),f.classList.contains("stack"))for(var h=f.querySelectorAll("section"),i=0,j=h.length;j>i;i++){var k=d===Fb?Gb:F(f),l=h[i];l.setAttribute("data-index-h",d),l.setAttribute("data-index-v",i),o(l,"translate(0%, "+105*(i-k)+"%)"),l.addEventListener("click",Db,!0)}else f.addEventListener("click",Db,!0)}T(),C(),a||u("overviewshown",{indexh:Fb,indexv:Gb,currentSlide:Ib})},10)}}function H(){Qb.overview&&(clearTimeout(Zb),clearTimeout($b),Vb.wrapper.classList.remove("overview"),Vb.wrapper.classList.add("overview-deactivating"),$b=setTimeout(function(){Vb.wrapper.classList.remove("overview-deactivating")},1),m(document.querySelectorAll(Mb)).forEach(function(a){o(a,""),a.removeEventListener("click",Db,!0)}),Q(Fb,Gb),eb(),u("overviewhidden",{indexh:Fb,indexv:Gb,currentSlide:Ib}))}function I(a){"boolean"==typeof a?a?G():H():J()?H():G()}function J(){return Vb.wrapper.classList.contains("overview")}function K(a){return a=a?a:Ib,a&&a.parentNode&&!!a.parentNode.nodeName.match(/section/i)}function L(){var a=document.body,b=a.requestFullScreen||a.webkitRequestFullscreen||a.webkitRequestFullScreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&b.apply(a)}function M(){var a=Vb.wrapper.classList.contains("paused");fb(),Vb.wrapper.classList.add("paused"),a===!1&&u("paused")}function N(){var a=Vb.wrapper.classList.contains("paused");Vb.wrapper.classList.remove("paused"),eb(),a&&u("resumed")}function O(){P()?N():M()}function P(){return Vb.wrapper.classList.contains("paused")}function Q(a,b,c,d){Hb=Ib;var e=document.querySelectorAll(Nb);void 0===b&&(b=F(e[a])),Hb&&Hb.parentNode&&Hb.parentNode.classList.contains("stack")&&E(Hb.parentNode,Gb);var f=Tb.concat();Tb.length=0;var g=Fb||0,h=Gb||0;Fb=S(Nb,void 0===a?Fb:a),Gb=S(Ob,void 0===b?Gb:b),T(),C();a:for(var i=0,j=Tb.length;j>i;i++){for(var k=0;k<f.length;k++)if(f[k]===Tb[i]){f.splice(k,1);continue a}document.documentElement.classList.add(Tb[i]),u(Tb[i])}for(;f.length;)document.documentElement.classList.remove(f.pop());J()&&G();var l=e[Fb],n=l.querySelectorAll("section");if(Ib=n[Gb]||l,"undefined"!=typeof c){var o=B(Ib.querySelectorAll(".fragment"));m(o).forEach(function(a,b){c>b?a.classList.add("visible"):a.classList.remove("visible")})}var p=Fb!==g||Gb!==h;p?u("slidechanged",{indexh:Fb,indexv:Gb,previousSlide:Hb,currentSlide:Ib,origin:d}):Hb=null,Hb&&(Hb.classList.remove("present"),document.querySelector(Pb).classList.contains("present")&&setTimeout(function(){var a,b=m(document.querySelectorAll(Nb+".stack"));for(a in b)b[a]&&E(b[a],0)},0)),p&&($(Hb),Z(Ib)),V(),U(),W(),ab()}function R(){k(),j(),C(),Sb=Qb.autoSlide,eb(),h(),V(),U(),W()}function S(a,b){var c=m(document.querySelectorAll(a)),d=c.length;if(d){Qb.loop&&(b%=d,0>b&&(b=d+b)),b=Math.max(Math.min(b,d-1),0);for(var e=0;d>e;e++){var f=c[e],g=Qb.rtl&&!K(f);if(f.classList.remove("past"),f.classList.remove("present"),f.classList.remove("future"),f.setAttribute("hidden",""),b>e)f.classList.add(g?"future":"past");else if(e>b){f.classList.add(g?"past":"future");for(var h=m(f.querySelectorAll(".fragment.visible"));h.length;)h.pop().classList.remove("visible")}f.querySelector("section")&&f.classList.add("stack")}c[b].classList.add("present"),c[b].removeAttribute("hidden");var i=c[b].getAttribute("data-state");i&&(Tb=Tb.concat(i.split(" ")));var j=c[b].getAttribute("data-autoslide");Sb=j?parseInt(j,10):Qb.autoSlide,eb()}else b=0;return b}function T(){var a,b,c=m(document.querySelectorAll(Nb)),d=c.length;if(d){var e=J()?10:Qb.viewDistance;Lb&&(e=J()?6:1);for(var f=0;d>f;f++){var g=c[f],h=m(g.querySelectorAll("section")),i=h.length;if(a=Math.abs((Fb-f)%(d-e))||0,g.style.display=a>e?"none":"block",i)for(var j=F(g),k=0;i>k;k++){var l=h[k];b=f===Fb?Math.abs(Gb-k):Math.abs(k-j),l.style.display=a+b>e?"none":"block"}}}}function U(){if(Qb.progress&&Vb.progress){var a=m(document.querySelectorAll(Nb)),b=document.querySelectorAll(Mb+":not(.stack)").length,c=0;a:for(var d=0;d<a.length;d++){for(var e=a[d],f=m(e.querySelectorAll("section")),g=0;g<f.length;g++){if(f[g].classList.contains("present"))break a;c++}if(e.classList.contains("present"))break;e.classList.contains("stack")===!1&&c++}Vb.progressbar.style.width=c/(b-1)*window.innerWidth+"px"}}function V(){var a=X(),b=Y();Vb.controlsLeft.concat(Vb.controlsRight).concat(Vb.controlsUp).concat(Vb.controlsDown).concat(Vb.controlsPrev).concat(Vb.controlsNext).forEach(function(a){a.classList.remove("enabled"),a.classList.remove("fragmented")}),a.left&&Vb.controlsLeft.forEach(function(a){a.classList.add("enabled")}),a.right&&Vb.controlsRight.forEach(function(a){a.classList.add("enabled")}),a.up&&Vb.controlsUp.forEach(function(a){a.classList.add("enabled")}),a.down&&Vb.controlsDown.forEach(function(a){a.classList.add("enabled")}),(a.left||a.up)&&Vb.controlsPrev.forEach(function(a){a.classList.add("enabled")}),(a.right||a.down)&&Vb.controlsNext.forEach(function(a){a.classList.add("enabled")}),Ib&&(b.prev&&Vb.controlsPrev.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&Vb.controlsNext.forEach(function(a){a.classList.add("fragmented","enabled")}),K(Ib)?(b.prev&&Vb.controlsUp.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&Vb.controlsDown.forEach(function(a){a.classList.add("fragmented","enabled")})):(b.prev&&Vb.controlsLeft.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&Vb.controlsRight.forEach(function(a){a.classList.add("fragmented","enabled")})))}function W(){m(Vb.background.childNodes).forEach(function(a,b){var c=Qb.rtl?"future":"past",d=Qb.rtl?"past":"future";a.className="slide-background "+(Fb>b?c:b>Fb?d:"present"),m(a.childNodes).forEach(function(a,b){a.className="slide-background "+(Gb>b?"past":b>Gb?"future":"present")})}),setTimeout(function(){Vb.background.classList.remove("no-transition")},1)}function X(){var a=document.querySelectorAll(Nb),b=document.querySelectorAll(Ob),c={left:Fb>0||Qb.loop,right:Fb<a.length-1||Qb.loop,up:Gb>0,down:Gb<b.length-1};if(Qb.rtl){var d=c.left;c.left=c.right,c.right=d}return c}function Y(){if(Ib&&Qb.fragments){var a=Ib.querySelectorAll(".fragment"),b=Ib.querySelectorAll(".fragment:not(.visible)");return{prev:a.length-b.length>0,next:!!b.length}}return{prev:!1,next:!1}}function Z(a){a&&(m(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&a.play()}),m(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-autoplay")&&a.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")}))}function $(a){a&&(m(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-ignore")||a.pause()}),m(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-ignore")||"function"!=typeof a.contentWindow.postMessage||a.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}))}function _(){var a=window.location.hash,b=a.slice(2).split("/"),c=a.replace(/#|\//gi,"");if(isNaN(parseInt(b[0],10))&&c.length){var d=document.querySelector("#"+c);if(d){var e=Reveal.getIndices(d);Q(e.h,e.v)}else Q(Fb||0,Gb||0)}else{var f=parseInt(b[0],10)||0,g=parseInt(b[1],10)||0;(f!==Fb||g!==Gb)&&Q(f,g)}}function ab(a){if(Qb.history)if(clearTimeout(Yb),"number"==typeof a)Yb=setTimeout(ab,a);else{var b="/";Ib&&"string"==typeof Ib.getAttribute("id")?b="/"+Ib.getAttribute("id"):((Fb>0||Gb>0)&&(b+=Fb),Gb>0&&(b+="/"+Gb)),window.location.hash=b}}function bb(a){var b,c=Fb,d=Gb;if(a){var e=K(a),f=e?a.parentNode:a,g=m(document.querySelectorAll(Nb));c=Math.max(g.indexOf(f),0),e&&(d=Math.max(m(a.parentNode.querySelectorAll("section")).indexOf(a),0))}if(!a&&Ib){var h=Ib.querySelectorAll(".fragment").length>0;if(h){var i=Ib.querySelectorAll(".fragment.visible");b=i.length}}return{h:c,v:d,f:b}}function cb(){if(Ib&&Qb.fragments){var a=B(Ib.querySelectorAll(".fragment:not(.visible)"));if(a.length){var b=a[0].getAttribute("data-fragment-index");return a=Ib.querySelectorAll('.fragment[data-fragment-index="'+b+'"]'),m(a).forEach(function(a){a.classList.add("visible")}),u("fragmentshown",{fragment:a[0],fragments:a}),V(),!0}}return!1}function db(){if(Ib&&Qb.fragments){var a=B(Ib.querySelectorAll(".fragment.visible"));if(a.length){var b=a[a.length-1].getAttribute("data-fragment-index");return a=Ib.querySelectorAll('.fragment[data-fragment-index="'+b+'"]'),m(a).forEach(function(a){a.classList.remove("visible")}),u("fragmenthidden",{fragment:a[0],fragments:a}),V(),!0}}return!1}function eb(){clearTimeout(Xb),!Sb||P()||J()||(Xb=setTimeout(lb,Sb))}function fb(){clearTimeout(Xb)}function gb(){Qb.rtl?(J()||cb()===!1)&&X().left&&Q(Fb+1):(J()||db()===!1)&&X().left&&Q(Fb-1)}function hb(){Qb.rtl?(J()||db()===!1)&&X().right&&Q(Fb-1):(J()||cb()===!1)&&X().right&&Q(Fb+1)}function ib(){(J()||db()===!1)&&X().up&&Q(Fb,Gb-1)}function jb(){(J()||cb()===!1)&&X().down&&Q(Fb,Gb+1)}function kb(){if(db()===!1)if(X().up)ib();else{var a=document.querySelector(Nb+".past:nth-child("+Fb+")");if(a){var b=a.querySelectorAll("section").length-1||void 0,c=Fb-1;Q(c,b)}}}function lb(){cb()===!1&&(X().down?jb():hb()),eb()}function mb(a){document.activeElement;var b=!(!document.activeElement||!document.activeElement.type&&!document.activeElement.href&&"inherit"===document.activeElement.contentEditable);if(!(b||a.shiftKey&&32!==a.keyCode||a.altKey||a.ctrlKey||a.metaKey)){if(P()&&-1===[66,190,191].indexOf(a.keyCode))return!1;var c=!1;if("object"==typeof Qb.keyboard)for(var d in Qb.keyboard)if(parseInt(d,10)===a.keyCode){var e=Qb.keyboard[d];"function"==typeof e?e.apply(null,[a]):"string"==typeof e&&"function"==typeof Reveal[e]&&Reveal[e].call(),c=!0}if(c===!1)switch(c=!0,a.keyCode){case 80:case 33:kb();break;case 78:case 34:lb();break;case 72:case 37:gb();break;case 76:case 39:hb();break;case 75:case 38:ib();break;case 74:case 40:jb();break;case 36:Q(0);break;case 35:Q(Number.MAX_VALUE);break;case 32:J()?H():a.shiftKey?kb():lb();break;case 13:J()?H():c=!1;break;case 66:case 190:case 191:O();break;case 70:L();break;default:c=!1}c?a.preventDefault():27!==a.keyCode&&79!==a.keyCode||!Jb||(I(),a.preventDefault()),eb()}}function nb(a){ac.startX=a.touches[0].clientX,ac.startY=a.touches[0].clientY,ac.startCount=a.touches.length,2===a.touches.length&&Qb.overview&&(ac.startSpan=n({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:ac.startX,y:ac.startY}))}function ob(a){if(ac.captured)navigator.userAgent.match(/android/gi)&&a.preventDefault();else{var b=a.touches[0].clientX,c=a.touches[0].clientY;if(2===a.touches.length&&2===ac.startCount&&Qb.overview){var d=n({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:ac.startX,y:ac.startY});Math.abs(ac.startSpan-d)>ac.threshold&&(ac.captured=!0,d<ac.startSpan?G():H()),a.preventDefault()}else if(1===a.touches.length&&2!==ac.startCount){var e=b-ac.startX,f=c-ac.startY;e>ac.threshold&&Math.abs(e)>Math.abs(f)?(ac.captured=!0,gb()):e<-ac.threshold&&Math.abs(e)>Math.abs(f)?(ac.captured=!0,hb()):f>ac.threshold?(ac.captured=!0,ib()):f<-ac.threshold&&(ac.captured=!0,jb()),Qb.embedded?(ac.captured||K(Ib))&&a.preventDefault():a.preventDefault()}}}function pb(){ac.captured=!1}function qb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],nb(a))}function rb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],ob(a))}function sb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],pb(a))}function tb(a){if(Date.now()-Wb>600){Wb=Date.now();var b=a.detail||-a.wheelDelta;b>0?lb():kb()}}function ub(a){a.preventDefault();var b=m(document.querySelectorAll(Nb)).length,c=Math.floor(a.clientX/Vb.wrapper.offsetWidth*b);Q(c)}function vb(a){a.preventDefault(),gb()}function wb(a){a.preventDefault(),hb()}function xb(a){a.preventDefault(),ib()}function yb(a){a.preventDefault(),jb()}function zb(a){a.preventDefault(),kb()}function Ab(a){a.preventDefault(),lb()}function Bb(){_()}function Cb(){C()}function Db(a){if(_b&&J()){a.preventDefault();for(var b=a.target;b&&!b.nodeName.match(/section/gi);)b=b.parentNode;if(b&&!b.classList.contains("disabled")&&(H(),b.nodeName.match(/section/gi))){var c=parseInt(b.getAttribute("data-index-h"),10),d=parseInt(b.getAttribute("data-index-v"),10);Q(c,d)}}}function Eb(a){var b=a.target.getAttribute("href");b&&(z(b),a.preventDefault())}var Fb,Gb,Hb,Ib,Jb,Kb,Lb,Mb=".reveal .slides section",Nb=".reveal .slides>section",Ob=".reveal .slides>section.present>section",Pb=".reveal .slides>section:first-child",Qb={width:960,height:700,margin:.1,minScale:.2,maxScale:1,controls:!0,progress:!0,history:!1,keyboard:!0,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,fragments:!0,embedded:!1,autoSlide:0,mouseWheel:!1,rollingLinks:!1,hideAddressBar:!0,previewLinks:!1,theme:null,transition:"default",transitionSpeed:"default",backgroundTransition:"default",viewDistance:3,dependencies:[]},Rb=!1,Sb=0,Tb=[],Ub=1,Vb={},Wb=0,Xb=0,Yb=0,Zb=0,$b=0,_b=!1,ac={startX:0,startY:0,startSpan:0,startCount:0,captured:!1,threshold:40};return{initialize:a,configure:i,sync:R,slide:Q,left:gb,right:hb,up:ib,down:jb,prev:kb,next:lb,prevFragment:db,nextFragment:cb,navigateTo:Q,navigateLeft:gb,navigateRight:hb,navigateUp:ib,navigateDown:jb,navigatePrev:kb,navigateNext:lb,layout:C,availableRoutes:X,availableFragments:Y,toggleOverview:I,togglePause:O,isOverview:J,isPaused:P,addEventListeners:j,removeEventListeners:k,getIndices:bb,getSlide:function(a,b){var c=document.querySelectorAll(Nb)[a],d=c&&c.querySelectorAll("section");return"undefined"!=typeof b?d?d[b]:void 0:c},getPreviousSlide:function(){return Hb},getCurrentSlide:function(){return Ib},getScale:function(){return Ub},getConfig:function(){return Qb},getQueryHash:function(){var a={};return location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(b){a[b.split("=").shift()]=b.split("=").pop()}),a},isFirstSlide:function(){return null==document.querySelector(Mb+".past")?!0:!1},isLastSlide:function(){return Ib?Ib.nextElementSibling?!1:K(Ib)&&Ib.parentNode.nextElementSibling?!1:!0:!1},isReady:function(){return Rb},addEventListener:function(a,b,c){"addEventListener"in window&&(Vb.wrapper||document.querySelector(".reveal")).addEventListener(a,b,c)},removeEventListener:function(a,b,c){"addEventListener"in window&&(Vb.wrapper||document.querySelector(".reveal")).removeEventListener(a,b,c)}}}(); \ No newline at end of file
+var Reveal=function(){"use strict";function a(a){if(b(),!dc.transforms2d&&!dc.transforms3d)return document.body.setAttribute("class","no-transforms"),void 0;window.addEventListener("load",A,!1);var d=Reveal.getQueryHash();"undefined"!=typeof d.dependencies&&delete d.dependencies,k($b,a),k($b,d),r(),c()}function b(){dc.transforms3d="WebkitPerspective"in document.body.style||"MozPerspective"in document.body.style||"msPerspective"in document.body.style||"OPerspective"in document.body.style||"perspective"in document.body.style,dc.transforms2d="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style,dc.requestAnimationFrameMethod=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,dc.requestAnimationFrame="function"==typeof dc.requestAnimationFrameMethod,dc.canvas=!!document.createElement("canvas").getContext,Ub=navigator.userAgent.match(/(iphone|ipod|android)/gi)}function c(){function a(){e.length&&head.js.apply(null,e),d()}function b(b){head.ready(b.src.match(/([\w\d_\-]*)\.?js$|[^\\\/]*$/i)[0],function(){"function"==typeof b.callback&&b.callback.apply(this),0===--f&&a()})}for(var c=[],e=[],f=0,g=0,h=$b.dependencies.length;h>g;g++){var i=$b.dependencies[g];(!i.condition||i.condition())&&(i.async?e.push(i.src):c.push(i.src),b(i))}c.length?(f=c.length,head.js.apply(null,c)):a()}function d(){e(),Q(),h(),bb(),W(!0),setTimeout(function(){cc.slides.classList.remove("no-transition"),_b=!0,t("ready",{indexh:Pb,indexv:Qb,currentSlide:Sb})},1)}function e(){cc.theme=document.querySelector("#theme"),cc.wrapper=document.querySelector(".reveal"),cc.slides=document.querySelector(".reveal .slides"),cc.slides.classList.add("no-transition"),cc.background=f(cc.wrapper,"div","backgrounds",null),cc.progress=f(cc.wrapper,"div","progress","<span></span>"),cc.progressbar=cc.progress.querySelector("span"),f(cc.wrapper,"aside","controls",'<div class="navigate-left"></div><div class="navigate-right"></div><div class="navigate-up"></div><div class="navigate-down"></div>'),cc.slideNumber=f(cc.wrapper,"div","slide-number",""),f(cc.wrapper,"div","state-background",null),f(cc.wrapper,"div","pause-overlay",null),cc.controls=document.querySelector(".reveal .controls"),cc.controlsLeft=l(document.querySelectorAll(".navigate-left")),cc.controlsRight=l(document.querySelectorAll(".navigate-right")),cc.controlsUp=l(document.querySelectorAll(".navigate-up")),cc.controlsDown=l(document.querySelectorAll(".navigate-down")),cc.controlsPrev=l(document.querySelectorAll(".navigate-prev")),cc.controlsNext=l(document.querySelectorAll(".navigate-next"))}function f(a,b,c,d){var e=a.querySelector("."+c);return e||(e=document.createElement(b),e.classList.add(c),null!==d&&(e.innerHTML=d),a.appendChild(e)),e}function g(){function a(a,b){var c={background:a.getAttribute("data-background"),backgroundSize:a.getAttribute("data-background-size"),backgroundImage:a.getAttribute("data-background-image"),backgroundColor:a.getAttribute("data-background-color"),backgroundRepeat:a.getAttribute("data-background-repeat"),backgroundPosition:a.getAttribute("data-background-position"),backgroundTransition:a.getAttribute("data-background-transition")},d=document.createElement("div");return d.className="slide-background",c.background&&(/^(http|file|\/\/)/gi.test(c.background)||/\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test(c.background)?d.style.backgroundImage="url("+c.background+")":d.style.background=c.background),(c.background||c.backgroundColor||c.backgroundImage)&&d.setAttribute("data-background-hash",c.background+c.backgroundSize+c.backgroundImage+c.backgroundColor+c.backgroundRepeat+c.backgroundPosition+c.backgroundTransition),c.backgroundSize&&(d.style.backgroundSize=c.backgroundSize),c.backgroundImage&&(d.style.backgroundImage='url("'+c.backgroundImage+'")'),c.backgroundColor&&(d.style.backgroundColor=c.backgroundColor),c.backgroundRepeat&&(d.style.backgroundRepeat=c.backgroundRepeat),c.backgroundPosition&&(d.style.backgroundPosition=c.backgroundPosition),c.backgroundTransition&&d.setAttribute("data-background-transition",c.backgroundTransition),b.appendChild(d),d}q()&&document.body.classList.add("print-pdf"),cc.background.innerHTML="",cc.background.classList.add("no-transition"),l(document.querySelectorAll(Xb)).forEach(function(b){var c;c=q()?a(b,b):a(b,cc.background),l(b.querySelectorAll("section")).forEach(function(b){q()?a(b,b):a(b,c)})}),$b.parallaxBackgroundImage?(cc.background.style.backgroundImage='url("'+$b.parallaxBackgroundImage+'")',cc.background.style.backgroundSize=$b.parallaxBackgroundSize,setTimeout(function(){cc.wrapper.classList.add("has-parallax-background")},1)):(cc.background.style.backgroundImage="",cc.wrapper.classList.remove("has-parallax-background"))}function h(a){var b=document.querySelectorAll(Wb).length;if(cc.wrapper.classList.remove($b.transition),"object"==typeof a&&k($b,a),dc.transforms3d===!1&&($b.transition="linear"),cc.wrapper.classList.add($b.transition),cc.wrapper.setAttribute("data-transition-speed",$b.transitionSpeed),cc.wrapper.setAttribute("data-background-transition",$b.backgroundTransition),cc.controls.style.display=$b.controls?"block":"none",cc.progress.style.display=$b.progress?"block":"none",$b.rtl?cc.wrapper.classList.add("rtl"):cc.wrapper.classList.remove("rtl"),$b.center?cc.wrapper.classList.add("center"):cc.wrapper.classList.remove("center"),$b.mouseWheel?(document.addEventListener("DOMMouseScroll",Ab,!1),document.addEventListener("mousewheel",Ab,!1)):(document.removeEventListener("DOMMouseScroll",Ab,!1),document.removeEventListener("mousewheel",Ab,!1)),$b.rollingLinks?u():v(),$b.previewLinks?w():(x(),w("[data-preview-link]")),b>1&&$b.autoSlide&&$b.autoSlideStoppable&&dc.canvas&&dc.requestAnimationFrame?(Vb=new Ob(cc.wrapper,function(){return Math.min(Math.max((Date.now()-lc)/jc,0),1)}),Vb.on("click",Nb),mc=!1):Vb&&(Vb.destroy(),Vb=null),$b.theme&&cc.theme){var c=cc.theme.getAttribute("href"),d=/[^\/]*?(?=\.css)/,e=c.match(d)[0];$b.theme!==e&&(c=c.replace(d,$b.theme),cc.theme.setAttribute("href",c))}P()}function i(){if(ic=!0,window.addEventListener("hashchange",Ib,!1),window.addEventListener("resize",Jb,!1),$b.touch&&(cc.wrapper.addEventListener("touchstart",ub,!1),cc.wrapper.addEventListener("touchmove",vb,!1),cc.wrapper.addEventListener("touchend",wb,!1),window.navigator.msPointerEnabled&&(cc.wrapper.addEventListener("MSPointerDown",xb,!1),cc.wrapper.addEventListener("MSPointerMove",yb,!1),cc.wrapper.addEventListener("MSPointerUp",zb,!1))),$b.keyboard&&document.addEventListener("keydown",tb,!1),$b.progress&&cc.progress&&cc.progress.addEventListener("click",Bb,!1),$b.focusBodyOnPageVisiblityChange){var a;"hidden"in document?a="visibilitychange":"msHidden"in document?a="msvisibilitychange":"webkitHidden"in document&&(a="webkitvisibilitychange"),a&&document.addEventListener(a,Kb,!1)}["touchstart","click"].forEach(function(a){cc.controlsLeft.forEach(function(b){b.addEventListener(a,Cb,!1)}),cc.controlsRight.forEach(function(b){b.addEventListener(a,Db,!1)}),cc.controlsUp.forEach(function(b){b.addEventListener(a,Eb,!1)}),cc.controlsDown.forEach(function(b){b.addEventListener(a,Fb,!1)}),cc.controlsPrev.forEach(function(b){b.addEventListener(a,Gb,!1)}),cc.controlsNext.forEach(function(b){b.addEventListener(a,Hb,!1)})})}function j(){ic=!1,document.removeEventListener("keydown",tb,!1),window.removeEventListener("hashchange",Ib,!1),window.removeEventListener("resize",Jb,!1),cc.wrapper.removeEventListener("touchstart",ub,!1),cc.wrapper.removeEventListener("touchmove",vb,!1),cc.wrapper.removeEventListener("touchend",wb,!1),window.navigator.msPointerEnabled&&(cc.wrapper.removeEventListener("MSPointerDown",xb,!1),cc.wrapper.removeEventListener("MSPointerMove",yb,!1),cc.wrapper.removeEventListener("MSPointerUp",zb,!1)),$b.progress&&cc.progress&&cc.progress.removeEventListener("click",Bb,!1),["touchstart","click"].forEach(function(a){cc.controlsLeft.forEach(function(b){b.removeEventListener(a,Cb,!1)}),cc.controlsRight.forEach(function(b){b.removeEventListener(a,Db,!1)}),cc.controlsUp.forEach(function(b){b.removeEventListener(a,Eb,!1)}),cc.controlsDown.forEach(function(b){b.removeEventListener(a,Fb,!1)}),cc.controlsPrev.forEach(function(b){b.removeEventListener(a,Gb,!1)}),cc.controlsNext.forEach(function(b){b.removeEventListener(a,Hb,!1)})})}function k(a,b){for(var c in b)a[c]=b[c]}function l(a){return Array.prototype.slice.call(a)}function m(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}function n(a,b){a.style.WebkitTransform=b,a.style.MozTransform=b,a.style.msTransform=b,a.style.OTransform=b,a.style.transform=b}function o(a){var b=0;if(a){var c=0;l(a.childNodes).forEach(function(a){"number"==typeof a.offsetTop&&a.style&&("absolute"===a.style.position&&(c+=1),b=Math.max(b,a.offsetTop+a.offsetHeight))}),0===c&&(b=a.offsetHeight)}return b}function p(a,b){if(b=b||0,a){var c=a.parentNode,d=c.childNodes;l(d).forEach(function(c){if("number"==typeof c.offsetHeight&&c!==a){var d=window.getComputedStyle(c),e=parseInt(d.marginTop,10),f=parseInt(d.marginBottom,10);b-=c.offsetHeight+e+f}});var e=window.getComputedStyle(a);b-=parseInt(e.marginTop,10)+parseInt(e.marginBottom,10)}return b}function q(){return/print-pdf/gi.test(window.location.search)}function r(){$b.hideAddressBar&&Ub&&(window.addEventListener("load",s,!1),window.addEventListener("orientationchange",s,!1))}function s(){setTimeout(function(){window.scrollTo(0,1)},10)}function t(a,b){var c=document.createEvent("HTMLEvents",1,2);c.initEvent(a,!0,!0),k(c,b),cc.wrapper.dispatchEvent(c)}function u(){if(dc.transforms3d&&!("msPerspective"in document.body.style))for(var a=document.querySelectorAll(Wb+" a:not(.image)"),b=0,c=a.length;c>b;b++){var d=a[b];if(!(!d.textContent||d.querySelector("*")||d.className&&d.classList.contains(d,"roll"))){var e=document.createElement("span");e.setAttribute("data-title",d.text),e.innerHTML=d.innerHTML,d.classList.add("roll"),d.innerHTML="",d.appendChild(e)}}}function v(){for(var a=document.querySelectorAll(Wb+" a.roll"),b=0,c=a.length;c>b;b++){var d=a[b],e=d.querySelector("span");e&&(d.classList.remove("roll"),d.innerHTML=e.innerHTML)}}function w(a){var b=l(document.querySelectorAll(a?a:"a"));b.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.addEventListener("click",Mb,!1)})}function x(){var a=l(document.querySelectorAll("a"));a.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.removeEventListener("click",Mb,!1)})}function y(a){z(),cc.preview=document.createElement("div"),cc.preview.classList.add("preview-link-overlay"),cc.wrapper.appendChild(cc.preview),cc.preview.innerHTML=["<header>",'<a class="close" href="#"><span class="icon"></span></a>','<a class="external" href="'+a+'" target="_blank"><span class="icon"></span></a>',"</header>",'<div class="spinner"></div>','<div class="viewport">','<iframe src="'+a+'"></iframe>',"</div>"].join(""),cc.preview.querySelector("iframe").addEventListener("load",function(){cc.preview.classList.add("loaded")},!1),cc.preview.querySelector(".close").addEventListener("click",function(a){z(),a.preventDefault()},!1),cc.preview.querySelector(".external").addEventListener("click",function(){z()},!1),setTimeout(function(){cc.preview.classList.add("visible")},1)}function z(){cc.preview&&(cc.preview.setAttribute("src",""),cc.preview.parentNode.removeChild(cc.preview),cc.preview=null)}function A(){if(cc.wrapper&&!q()){var a=cc.wrapper.offsetWidth,b=cc.wrapper.offsetHeight;a-=b*$b.margin,b-=b*$b.margin;var c=$b.width,d=$b.height,e=20;B($b.width,$b.height,e),"string"==typeof c&&/%$/.test(c)&&(c=parseInt(c,10)/100*a),"string"==typeof d&&/%$/.test(d)&&(d=parseInt(d,10)/100*b),cc.slides.style.width=c+"px",cc.slides.style.height=d+"px",bc=Math.min(a/c,b/d),bc=Math.max(bc,$b.minScale),bc=Math.min(bc,$b.maxScale),"undefined"==typeof cc.slides.style.zoom||navigator.userAgent.match(/(iphone|ipod|ipad|android)/gi)?n(cc.slides,"translate(-50%, -50%) scale("+bc+") translate(50%, 50%)"):cc.slides.style.zoom=bc;for(var f=l(document.querySelectorAll(Wb)),g=0,h=f.length;h>g;g++){var i=f[g];"none"!==i.style.display&&(i.style.top=$b.center||i.classList.contains("center")?i.classList.contains("stack")?0:Math.max(-(o(i)/2)-e,-d/2)+"px":"")}T(),X()}}function B(a,b,c){l(cc.slides.querySelectorAll("section > .stretch")).forEach(function(d){var e=p(d,b-2*c);if(/(img|video)/gi.test(d.nodeName)){var f=d.naturalWidth||d.videoWidth,g=d.naturalHeight||d.videoHeight,h=Math.min(a/f,e/g);d.style.width=f*h+"px",d.style.height=g*h+"px"}else d.style.width=a+"px",d.style.height=e+"px"})}function C(a,b){"object"==typeof a&&"function"==typeof a.setAttribute&&a.setAttribute("data-previous-indexv",b||0)}function D(a){if("object"==typeof a&&"function"==typeof a.setAttribute&&a.classList.contains("stack")){var b=a.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(a.getAttribute(b)||0,10)}return 0}function E(){if($b.overview){jb();var a=cc.wrapper.classList.contains("overview"),b=window.innerWidth<400?1e3:2500;cc.wrapper.classList.add("overview"),cc.wrapper.classList.remove("overview-deactivating"),clearTimeout(gc),clearTimeout(hc),gc=setTimeout(function(){for(var c=document.querySelectorAll(Xb),d=0,e=c.length;e>d;d++){var f=c[d],g=$b.rtl?-105:105;if(f.setAttribute("data-index-h",d),n(f,"translateZ(-"+b+"px) translate("+(d-Pb)*g+"%, 0%)"),f.classList.contains("stack"))for(var h=f.querySelectorAll("section"),i=0,j=h.length;j>i;i++){var k=d===Pb?Qb:D(f),l=h[i];l.setAttribute("data-index-h",d),l.setAttribute("data-index-v",i),n(l,"translate(0%, "+105*(i-k)+"%)"),l.addEventListener("click",Lb,!0)}else f.addEventListener("click",Lb,!0)}S(),A(),a||t("overviewshown",{indexh:Pb,indexv:Qb,currentSlide:Sb})},10)}}function F(){$b.overview&&(clearTimeout(gc),clearTimeout(hc),cc.wrapper.classList.remove("overview"),cc.wrapper.classList.add("overview-deactivating"),hc=setTimeout(function(){cc.wrapper.classList.remove("overview-deactivating")},1),l(document.querySelectorAll(Wb)).forEach(function(a){n(a,""),a.removeEventListener("click",Lb,!0)}),O(Pb,Qb),ib(),t("overviewhidden",{indexh:Pb,indexv:Qb,currentSlide:Sb}))}function G(a){"boolean"==typeof a?a?E():F():H()?F():E()}function H(){return cc.wrapper.classList.contains("overview")}function I(a){return a=a?a:Sb,a&&a.parentNode&&!!a.parentNode.nodeName.match(/section/i)}function J(){var a=document.body,b=a.requestFullScreen||a.webkitRequestFullscreen||a.webkitRequestFullScreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&b.apply(a)}function K(){var a=cc.wrapper.classList.contains("paused");jb(),cc.wrapper.classList.add("paused"),a===!1&&t("paused")}function L(){var a=cc.wrapper.classList.contains("paused");cc.wrapper.classList.remove("paused"),ib(),a&&t("resumed")}function M(){N()?L():K()}function N(){return cc.wrapper.classList.contains("paused")}function O(a,b,c,d){Rb=Sb;var e=document.querySelectorAll(Xb);void 0===b&&(b=D(e[a])),Rb&&Rb.parentNode&&Rb.parentNode.classList.contains("stack")&&C(Rb.parentNode,Qb);var f=ac.concat();ac.length=0;var g=Pb||0,h=Qb||0;Pb=R(Xb,void 0===a?Pb:a),Qb=R(Yb,void 0===b?Qb:b),S(),A();a:for(var i=0,j=ac.length;j>i;i++){for(var k=0;k<f.length;k++)if(f[k]===ac[i]){f.splice(k,1);continue a}document.documentElement.classList.add(ac[i]),t(ac[i])}for(;f.length;)document.documentElement.classList.remove(f.pop());H()&&E();var m=e[Pb],n=m.querySelectorAll("section");Sb=n[Qb]||m,"undefined"!=typeof c&&fb(c);var o=Pb!==g||Qb!==h;o?t("slidechanged",{indexh:Pb,indexv:Qb,previousSlide:Rb,currentSlide:Sb,origin:d}):Rb=null,Rb&&(Rb.classList.remove("present"),document.querySelector(Zb).classList.contains("present")&&setTimeout(function(){var a,b=l(document.querySelectorAll(Xb+".stack"));for(a in b)b[a]&&C(b[a],0)},0)),o&&(_(Rb),$(Sb)),V(),T(),W(),X(),U(),cb(),ib()}function P(){j(),i(),A(),jc=$b.autoSlide,ib(),g(),Q(),V(),T(),W(!0),U()}function Q(){var a=l(document.querySelectorAll(Xb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a,b){b>0&&a.classList.add("future"),eb(a.querySelectorAll(".fragment"))}),0===b.length&&eb(a.querySelectorAll(".fragment"))})}function R(a,b){var c=l(document.querySelectorAll(a)),d=c.length;if(d){$b.loop&&(b%=d,0>b&&(b=d+b)),b=Math.max(Math.min(b,d-1),0);for(var e=0;d>e;e++){var f=c[e],g=$b.rtl&&!I(f);if(f.classList.remove("past"),f.classList.remove("present"),f.classList.remove("future"),f.setAttribute("hidden",""),b>e){f.classList.add(g?"future":"past");for(var h=l(f.querySelectorAll(".fragment"));h.length;){var i=h.pop();i.classList.add("visible"),i.classList.remove("current-fragment")}}else if(e>b){f.classList.add(g?"past":"future");for(var j=l(f.querySelectorAll(".fragment.visible"));j.length;){var k=j.pop();k.classList.remove("visible"),k.classList.remove("current-fragment")}}f.querySelector("section")&&f.classList.add("stack")}c[b].classList.add("present"),c[b].removeAttribute("hidden");var m=c[b].getAttribute("data-state");m&&(ac=ac.concat(m.split(" ")))}else b=0;return b}function S(){var a,b,c=l(document.querySelectorAll(Xb)),d=c.length;if(d){var e=H()?10:$b.viewDistance;Ub&&(e=H()?6:1);for(var f=0;d>f;f++){var g=c[f],h=l(g.querySelectorAll("section")),i=h.length;if(a=Math.abs((Pb-f)%(d-e))||0,g.style.display=a>e?"none":"block",i)for(var j=D(g),k=0;i>k;k++){var m=h[k];b=f===Pb?Math.abs(Qb-k):Math.abs(k-j),m.style.display=a+b>e?"none":"block"}}}}function T(){if($b.progress&&cc.progress){var a=l(document.querySelectorAll(Xb)),b=document.querySelectorAll(Wb+":not(.stack)").length,c=0;a:for(var d=0;d<a.length;d++){for(var e=a[d],f=l(e.querySelectorAll("section")),g=0;g<f.length;g++){if(f[g].classList.contains("present"))break a;c++}if(e.classList.contains("present"))break;e.classList.contains("stack")===!1&&c++}cc.progressbar.style.width=c/(b-1)*window.innerWidth+"px"}}function U(){if($b.slideNumber&&cc.slideNumber){var a=Pb;Qb>0&&(a+=" - "+Qb),cc.slideNumber.innerHTML=a}}function V(){var a=Y(),b=Z();cc.controlsLeft.concat(cc.controlsRight).concat(cc.controlsUp).concat(cc.controlsDown).concat(cc.controlsPrev).concat(cc.controlsNext).forEach(function(a){a.classList.remove("enabled"),a.classList.remove("fragmented")}),a.left&&cc.controlsLeft.forEach(function(a){a.classList.add("enabled")}),a.right&&cc.controlsRight.forEach(function(a){a.classList.add("enabled")}),a.up&&cc.controlsUp.forEach(function(a){a.classList.add("enabled")}),a.down&&cc.controlsDown.forEach(function(a){a.classList.add("enabled")}),(a.left||a.up)&&cc.controlsPrev.forEach(function(a){a.classList.add("enabled")}),(a.right||a.down)&&cc.controlsNext.forEach(function(a){a.classList.add("enabled")}),Sb&&(b.prev&&cc.controlsPrev.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&cc.controlsNext.forEach(function(a){a.classList.add("fragmented","enabled")}),I(Sb)?(b.prev&&cc.controlsUp.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&cc.controlsDown.forEach(function(a){a.classList.add("fragmented","enabled")})):(b.prev&&cc.controlsLeft.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&cc.controlsRight.forEach(function(a){a.classList.add("fragmented","enabled")})))}function W(a){var b=null,c=$b.rtl?"future":"past",d=$b.rtl?"past":"future";if(l(cc.background.childNodes).forEach(function(e,f){Pb>f?e.className="slide-background "+c:f>Pb?e.className="slide-background "+d:(e.className="slide-background present",b=e),(a||f===Pb)&&l(e.childNodes).forEach(function(a,c){Qb>c?a.className="slide-background past":c>Qb?a.className="slide-background future":(a.className="slide-background present",f===Pb&&(b=a))})}),b){var e=Tb?Tb.getAttribute("data-background-hash"):null,f=b.getAttribute("data-background-hash");f&&f===e&&b!==Tb&&cc.background.classList.add("no-transition"),Tb=b}setTimeout(function(){cc.background.classList.remove("no-transition")},1)}function X(){if($b.parallaxBackgroundImage){var a,b,c=document.querySelectorAll(Xb),d=document.querySelectorAll(Yb),e=cc.background.style.backgroundSize.split(" ");1===e.length?a=b=parseInt(e[0],10):(a=parseInt(e[0],10),b=parseInt(e[1],10));var f=cc.background.offsetWidth,g=c.length,h=-(a-f)/(g-1)*Pb,i=cc.background.offsetHeight,j=d.length,k=j>0?-(b-i)/(j-1)*Qb:0;cc.background.style.backgroundPosition=h+"px "+k+"px"}}function Y(){var a=document.querySelectorAll(Xb),b=document.querySelectorAll(Yb),c={left:Pb>0||$b.loop,right:Pb<a.length-1||$b.loop,up:Qb>0,down:Qb<b.length-1};if($b.rtl){var d=c.left;c.left=c.right,c.right=d}return c}function Z(){if(Sb&&$b.fragments){var a=Sb.querySelectorAll(".fragment"),b=Sb.querySelectorAll(".fragment:not(.visible)");return{prev:a.length-b.length>0,next:!!b.length}}return{prev:!1,next:!1}}function $(a){a&&!ab()&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&a.play()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:start","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-autoplay")&&a.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")}))}function _(a){a&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-ignore")||a.pause()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:stop","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-ignore")||"function"!=typeof a.contentWindow.postMessage||a.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}))}function ab(){return!!window.location.search.match(/receiver/gi)}function bb(){var a=window.location.hash,b=a.slice(2).split("/"),c=a.replace(/#|\//gi,"");if(isNaN(parseInt(b[0],10))&&c.length){var d=document.querySelector("#"+c);if(d){var e=Reveal.getIndices(d);O(e.h,e.v)}else O(Pb||0,Qb||0)}else{var f=parseInt(b[0],10)||0,g=parseInt(b[1],10)||0;(f!==Pb||g!==Qb)&&O(f,g)}}function cb(a){if($b.history)if(clearTimeout(fc),"number"==typeof a)fc=setTimeout(cb,a);else{var b="/";Sb&&"string"==typeof Sb.getAttribute("id")?b="/"+Sb.getAttribute("id"):((Pb>0||Qb>0)&&(b+=Pb),Qb>0&&(b+="/"+Qb)),window.location.hash=b}}function db(a){var b,c=Pb,d=Qb;if(a){var e=I(a),f=e?a.parentNode:a,g=l(document.querySelectorAll(Xb));c=Math.max(g.indexOf(f),0),e&&(d=Math.max(l(a.parentNode.querySelectorAll("section")).indexOf(a),0))}if(!a&&Sb){var h=Sb.querySelectorAll(".fragment").length>0;if(h){var i=Sb.querySelectorAll(".fragment.visible");b=i.length-1}}return{h:c,v:d,f:b}}function eb(a){a=l(a);var b=[],c=[],d=[];a.forEach(function(a){if(a.hasAttribute("data-fragment-index")){var d=parseInt(a.getAttribute("data-fragment-index"),10);b[d]||(b[d]=[]),b[d].push(a)}else c.push([a])}),b=b.concat(c);var e=0;return b.forEach(function(a){a.forEach(function(a){d.push(a),a.setAttribute("data-fragment-index",e)}),e++}),d}function fb(a,b){if(Sb&&$b.fragments){var c=eb(Sb.querySelectorAll(".fragment"));if(c.length){if("number"!=typeof a){var d=eb(Sb.querySelectorAll(".fragment.visible")).pop();a=d?parseInt(d.getAttribute("data-fragment-index")||0,10):-1}"number"==typeof b&&(a+=b);var e=[],f=[];return l(c).forEach(function(b,c){b.hasAttribute("data-fragment-index")&&(c=parseInt(b.getAttribute("data-fragment-index"),10)),a>=c?(b.classList.contains("visible")||e.push(b),b.classList.add("visible"),b.classList.remove("current-fragment"),c===a&&b.classList.add("current-fragment")):(b.classList.contains("visible")&&f.push(b),b.classList.remove("visible"),b.classList.remove("current-fragment"))}),f.length&&t("fragmenthidden",{fragment:f[0],fragments:f}),e.length&&t("fragmentshown",{fragment:e[0],fragments:e}),V(),!(!e.length&&!f.length)}}return!1}function gb(){return fb(null,1)}function hb(){return fb(null,-1)}function ib(){if(jb(),Sb){var a=Sb.parentNode?Sb.parentNode.getAttribute("data-autoslide"):null,b=Sb.getAttribute("data-autoslide");jc=b?parseInt(b,10):a?parseInt(a,10):$b.autoSlide,l(Sb.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&jc&&1e3*a.duration>jc&&(jc=1e3*a.duration+1e3)}),!jc||mc||N()||H()||Reveal.isLastSlide()&&$b.loop!==!0||(kc=setTimeout(rb,jc),lc=Date.now()),Vb&&Vb.setPlaying(-1!==kc)}}function jb(){clearTimeout(kc),kc=-1}function kb(){mc=!0,clearTimeout(kc),Vb&&Vb.setPlaying(!1)}function lb(){mc=!1,ib()}function mb(){$b.rtl?(H()||gb()===!1)&&Y().left&&O(Pb+1):(H()||hb()===!1)&&Y().left&&O(Pb-1)}function nb(){$b.rtl?(H()||hb()===!1)&&Y().right&&O(Pb-1):(H()||gb()===!1)&&Y().right&&O(Pb+1)}function ob(){(H()||hb()===!1)&&Y().up&&O(Pb,Qb-1)}function pb(){(H()||gb()===!1)&&Y().down&&O(Pb,Qb+1)}function qb(){if(hb()===!1)if(Y().up)ob();else{var a=document.querySelector(Xb+".past:nth-child("+Pb+")");if(a){var b=a.querySelectorAll("section").length-1||void 0,c=Pb-1;O(c,b)}}}function rb(){gb()===!1&&(Y().down?pb():nb()),ib()}function sb(){$b.autoSlideStoppable&&kb()}function tb(a){sb(a),document.activeElement;var b=!(!document.activeElement||!document.activeElement.type&&!document.activeElement.href&&"inherit"===document.activeElement.contentEditable);if(!(b||a.shiftKey&&32!==a.keyCode||a.altKey||a.ctrlKey||a.metaKey)){if(N()&&-1===[66,190,191].indexOf(a.keyCode))return!1;var c=!1;if("object"==typeof $b.keyboard)for(var d in $b.keyboard)if(parseInt(d,10)===a.keyCode){var e=$b.keyboard[d];"function"==typeof e?e.apply(null,[a]):"string"==typeof e&&"function"==typeof Reveal[e]&&Reveal[e].call(),c=!0}if(c===!1)switch(c=!0,a.keyCode){case 80:case 33:qb();break;case 78:case 34:rb();break;case 72:case 37:mb();break;case 76:case 39:nb();break;case 75:case 38:ob();break;case 74:case 40:pb();break;case 36:O(0);break;case 35:O(Number.MAX_VALUE);break;case 32:H()?F():a.shiftKey?qb():rb();break;case 13:H()?F():c=!1;break;case 66:case 190:case 191:M();break;case 70:J();break;default:c=!1}c?a.preventDefault():27!==a.keyCode&&79!==a.keyCode||!dc.transforms3d||(cc.preview?z():G(),a.preventDefault()),ib()}}function ub(a){nc.startX=a.touches[0].clientX,nc.startY=a.touches[0].clientY,nc.startCount=a.touches.length,2===a.touches.length&&$b.overview&&(nc.startSpan=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:nc.startX,y:nc.startY}))}function vb(a){if(nc.captured)navigator.userAgent.match(/android/gi)&&a.preventDefault();else{sb(a);var b=a.touches[0].clientX,c=a.touches[0].clientY;if(2===a.touches.length&&2===nc.startCount&&$b.overview){var d=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:nc.startX,y:nc.startY});Math.abs(nc.startSpan-d)>nc.threshold&&(nc.captured=!0,d<nc.startSpan?E():F()),a.preventDefault()}else if(1===a.touches.length&&2!==nc.startCount){var e=b-nc.startX,f=c-nc.startY;e>nc.threshold&&Math.abs(e)>Math.abs(f)?(nc.captured=!0,mb()):e<-nc.threshold&&Math.abs(e)>Math.abs(f)?(nc.captured=!0,nb()):f>nc.threshold?(nc.captured=!0,ob()):f<-nc.threshold&&(nc.captured=!0,pb()),$b.embedded?(nc.captured||I(Sb))&&a.preventDefault():a.preventDefault()}}}function wb(){nc.captured=!1}function xb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],ub(a))}function yb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],vb(a))}function zb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],wb(a))}function Ab(a){if(Date.now()-ec>600){ec=Date.now();var b=a.detail||-a.wheelDelta;b>0?rb():qb()}}function Bb(a){sb(a),a.preventDefault();var b=l(document.querySelectorAll(Xb)).length,c=Math.floor(a.clientX/cc.wrapper.offsetWidth*b);O(c)}function Cb(a){a.preventDefault(),sb(),mb()}function Db(a){a.preventDefault(),sb(),nb()}function Eb(a){a.preventDefault(),sb(),ob()}function Fb(a){a.preventDefault(),sb(),pb()}function Gb(a){a.preventDefault(),sb(),qb()}function Hb(a){a.preventDefault(),sb(),rb()}function Ib(){bb()}function Jb(){A()}function Kb(){var a=document.webkitHidden||document.msHidden||document.hidden;a===!1&&document.activeElement!==document.body&&(document.activeElement.blur(),document.body.focus())}function Lb(a){if(ic&&H()){a.preventDefault();for(var b=a.target;b&&!b.nodeName.match(/section/gi);)b=b.parentNode;if(b&&!b.classList.contains("disabled")&&(F(),b.nodeName.match(/section/gi))){var c=parseInt(b.getAttribute("data-index-h"),10),d=parseInt(b.getAttribute("data-index-v"),10);O(c,d)}}}function Mb(a){var b=a.target.getAttribute("href");b&&(y(b),a.preventDefault())}function Nb(){Reveal.isLastSlide()&&$b.loop===!1?(O(0,0),lb()):mc?lb():kb()}function Ob(a,b){this.diameter=50,this.thickness=3,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=a,this.progressCheck=b,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}var Pb,Qb,Rb,Sb,Tb,Ub,Vb,Wb=".reveal .slides section",Xb=".reveal .slides>section",Yb=".reveal .slides>section.present>section",Zb=".reveal .slides>section:first-of-type",$b={width:960,height:700,margin:.1,minScale:.2,maxScale:1,controls:!0,progress:!0,slideNumber:!1,history:!1,keyboard:!0,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,fragments:!0,embedded:!1,autoSlide:0,autoSlideStoppable:!0,mouseWheel:!1,rollingLinks:!1,hideAddressBar:!0,previewLinks:!1,focusBodyOnPageVisiblityChange:!0,theme:null,transition:"default",transitionSpeed:"default",backgroundTransition:"default",parallaxBackgroundImage:"",parallaxBackgroundSize:"",viewDistance:3,dependencies:[]},_b=!1,ac=[],bc=1,cc={},dc={},ec=0,fc=0,gc=0,hc=0,ic=!1,jc=0,kc=0,lc=-1,mc=!1,nc={startX:0,startY:0,startSpan:0,startCount:0,captured:!1,threshold:40};return Ob.prototype.setPlaying=function(a){var b=this.playing;this.playing=a,!b&&this.playing?this.animate():this.render()},Ob.prototype.animate=function(){var a=this.progress;this.progress=this.progressCheck(),a>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&dc.requestAnimationFrameMethod.call(window,this.animate.bind(this))},Ob.prototype.render=function(){var a=this.playing?this.progress:0,b=this.diameter/2-this.thickness,c=this.diameter/2,d=this.diameter/2,e=14;this.progressOffset+=.1*(1-this.progressOffset);var f=-Math.PI/2+a*2*Math.PI,g=-Math.PI/2+this.progressOffset*2*Math.PI;this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(c,d,b+2,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(c,d,b,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#666",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(c,d,b,g,f,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(c-e/2,d-e/2),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,e/2-2,e),this.context.fillRect(e/2+2,0,e/2-2,e)):(this.context.beginPath(),this.context.translate(2,0),this.context.moveTo(0,0),this.context.lineTo(e-2,e/2),this.context.lineTo(0,e),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()},Ob.prototype.on=function(a,b){this.canvas.addEventListener(a,b,!1)},Ob.prototype.off=function(a,b){this.canvas.removeEventListener(a,b,!1)},Ob.prototype.destroy=function(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)},{initialize:a,configure:h,sync:P,slide:O,left:mb,right:nb,up:ob,down:pb,prev:qb,next:rb,navigateFragment:fb,prevFragment:hb,nextFragment:gb,navigateTo:O,navigateLeft:mb,navigateRight:nb,navigateUp:ob,navigateDown:pb,navigatePrev:qb,navigateNext:rb,layout:A,availableRoutes:Y,availableFragments:Z,toggleOverview:G,togglePause:M,isOverview:H,isPaused:N,addEventListeners:i,removeEventListeners:j,getIndices:db,getSlide:function(a,b){var c=document.querySelectorAll(Xb)[a],d=c&&c.querySelectorAll("section");
+return"undefined"!=typeof b?d?d[b]:void 0:c},getPreviousSlide:function(){return Rb},getCurrentSlide:function(){return Sb},getScale:function(){return bc},getConfig:function(){return $b},getQueryHash:function(){var a={};location.search.replace(/[A-Z0-9]+?=(\w*)/gi,function(b){a[b.split("=").shift()]=b.split("=").pop()});for(var b in a){var c=a[b];"null"===c?a[b]=null:"true"===c?a[b]=!0:"false"===c?a[b]=!1:isNaN(parseFloat(c))||(a[b]=parseFloat(c))}return a},isFirstSlide:function(){return null==document.querySelector(Wb+".past")?!0:!1},isLastSlide:function(){return Sb?Sb.nextElementSibling?!1:I(Sb)&&Sb.parentNode.nextElementSibling?!1:!0:!1},isReady:function(){return _b},addEventListener:function(a,b,c){"addEventListener"in window&&(cc.wrapper||document.querySelector(".reveal")).addEventListener(a,b,c)},removeEventListener:function(a,b,c){"addEventListener"in window&&(cc.wrapper||document.querySelector(".reveal")).removeEventListener(a,b,c)}}}(); \ No newline at end of file