).';\n\n\t\tif( initialized ) throw 'Reveal.js has already been initialized.';\n\n\t\tinitialized = true;\n\n\t\t// Cache references to key DOM elements\n\t\tdom.wrapper = revealElement;\n\t\tdom.slides = revealElement.querySelector( '.slides' );\n\n\t\tif( !dom.slides ) throw 'Unable to find slides container (
).';\n\n\t\t// Compose our config object in order of increasing precedence:\n\t\t// 1. Default reveal.js options\n\t\t// 2. Options provided via Reveal.configure() prior to\n\t\t// initialization\n\t\t// 3. Options passed to the Reveal constructor\n\t\t// 4. Options passed to Reveal.initialize\n\t\t// 5. Query params\n\t\tconfig = { ...defaultConfig, ...config, ...options, ...initOptions, ...Util.getQueryHash() };\n\n\t\t// Legacy support for the ?print-pdf query\n\t\tif( /print-pdf/gi.test( window.location.search ) ) {\n\t\t\tconfig.view = 'print';\n\t\t}\n\n\t\tsetViewport();\n\n\t\t// Force a layout when the whole page, incl fonts, has loaded\n\t\twindow.addEventListener( 'load', layout, false );\n\n\t\t// Register plugins and load dependencies, then move on to #start()\n\t\tplugins.load( config.plugins, config.dependencies ).then( start );\n\n\t\treturn new Promise( resolve => Reveal.on( 'ready', resolve ) );\n\n\t}\n\n\t/**\n\t * Encase the presentation in a reveal.js viewport. The\n\t * extent of the viewport differs based on configuration.\n\t */\n\tfunction setViewport() {\n\n\t\t// Embedded decks use the reveal element as their viewport\n\t\tif( config.embedded === true ) {\n\t\t\tdom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;\n\t\t}\n\t\t// Full-page decks use the body as their viewport\n\t\telse {\n\t\t\tdom.viewport = document.body;\n\t\t\tdocument.documentElement.classList.add( 'reveal-full-page' );\n\t\t}\n\n\t\tdom.viewport.classList.add( 'reveal-viewport' );\n\n\t}\n\n\t/**\n\t * Starts up reveal.js by binding input events and navigating\n\t * to the current URL deeplink if there is one.\n\t */\n\tfunction start() {\n\n\t\t// Don't proceed if this instance has been destroyed\n\t\tif( initialized === false ) return;\n\n\t\tready = true;\n\n\t\t// Remove slides hidden with data-visibility\n\t\tremoveHiddenSlides();\n\n\t\t// Make sure we've got all the DOM elements we need\n\t\tsetupDOM();\n\n\t\t// Listen to messages posted to this window\n\t\tsetupPostMessage();\n\n\t\t// Prevent the slides from being scrolled out of view\n\t\tsetupScrollPrevention();\n\n\t\t// Adds bindings for fullscreen mode\n\t\tsetupFullscreen();\n\n\t\t// Resets all vertical slides so that only the first is visible\n\t\tresetVerticalSlides();\n\n\t\t// Updates the presentation to match the current configuration values\n\t\tconfigure();\n\n\t\t// Create slide backgrounds\n\t\tbackgrounds.update( true );\n\n\t\t// Activate the print/scroll view if configured\n\t\tactivateInitialView();\n\n\t\t// Read the initial hash\n\t\tlocation.readURL();\n\n\t\t// Notify listeners that the presentation is ready but use a 1ms\n\t\t// timeout to ensure it's not fired synchronously after #initialize()\n\t\tsetTimeout( () => {\n\t\t\t// Enable transitions now that we're loaded\n\t\t\tdom.slides.classList.remove( 'no-transition' );\n\n\t\t\tdom.wrapper.classList.add( 'ready' );\n\n\t\t\tdispatchEvent({\n\t\t\t\ttype: 'ready',\n\t\t\t\tdata: {\n\t\t\t\t\tindexh,\n\t\t\t\t\tindexv,\n\t\t\t\t\tcurrentSlide\n\t\t\t\t}\n\t\t\t});\n\t\t}, 1 );\n\n\t}\n\n\t/**\n\t * Activates the correct reveal.js view based on our config.\n\t * This is only invoked once during initialization.\n\t */\n\tfunction activateInitialView() {\n\n\t\tconst activatePrintView = config.view === 'print';\n\t\tconst activateScrollView = config.view === 'scroll' || config.view === 'reader';\n\n\t\tif( activatePrintView || activateScrollView ) {\n\n\t\t\tif( activatePrintView ) {\n\t\t\t\tremoveEventListeners();\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttouch.unbind();\n\t\t\t}\n\n\t\t\t// Avoid content flickering during layout\n\t\t\tdom.viewport.classList.add( 'loading-scroll-mode' );\n\n\t\t\tif( activatePrintView ) {\n\t\t\t\t// The document needs to have loaded for the PDF layout\n\t\t\t\t// measurements to be accurate\n\t\t\t\tif( document.readyState === 'complete' ) {\n\t\t\t\t\tprintView.activate();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\twindow.addEventListener( 'load', () => printView.activate() );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tscrollView.activate();\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes all slides with data-visibility=\"hidden\". This\n\t * is done right before the rest of the presentation is\n\t * initialized.\n\t *\n\t * If you want to show all hidden slides, initialize\n\t * reveal.js with showHiddenSlides set to true.\n\t */\n\tfunction removeHiddenSlides() {\n\n\t\tif( !config.showHiddenSlides ) {\n\t\t\tUtil.queryAll( dom.wrapper, 'section[data-visibility=\"hidden\"]' ).forEach( slide => {\n\t\t\t\tconst parent = slide.parentNode;\n\n\t\t\t\t// If this slide is part of a stack and that stack will be\n\t\t\t\t// empty after removing the hidden slide, remove the entire\n\t\t\t\t// stack\n\t\t\t\tif( parent.childElementCount === 1 && /section/i.test( parent.nodeName ) ) {\n\t\t\t\t\tparent.remove();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tslide.remove();\n\t\t\t\t}\n\n\t\t\t} );\n\t\t}\n\n\t}\n\n\t/**\n\t * Finds and stores references to DOM elements which are\n\t * required by the presentation. If a required element is\n\t * not found, it is created.\n\t */\n\tfunction setupDOM() {\n\n\t\t// Prevent transitions while we're loading\n\t\tdom.slides.classList.add( 'no-transition' );\n\n\t\tif( Device.isMobile ) {\n\t\t\tdom.wrapper.classList.add( 'no-hover' );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.classList.remove( 'no-hover' );\n\t\t}\n\n\t\tbackgrounds.render();\n\t\tslideNumber.render();\n\t\tjumpToSlide.render();\n\t\tcontrols.render();\n\t\tprogress.render();\n\t\tnotes.render();\n\n\t\t// Overlay graphic which is displayed during the paused mode\n\t\tdom.pauseOverlay = Util.createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '
Resume presentation ' : null );\n\n\t\tdom.statusElement = createStatusElement();\n\n\t\tdom.wrapper.setAttribute( 'role', 'application' );\n\t}\n\n\t/**\n\t * Creates a hidden div with role aria-live to announce the\n\t * current slide content. Hide the div off-screen to make it\n\t * available only to Assistive Technologies.\n\t *\n\t * @return {HTMLElement}\n\t */\n\tfunction createStatusElement() {\n\n\t\tlet statusElement = dom.wrapper.querySelector( '.aria-status' );\n\t\tif( !statusElement ) {\n\t\t\tstatusElement = document.createElement( 'div' );\n\t\t\tstatusElement.style.position = 'absolute';\n\t\t\tstatusElement.style.height = '1px';\n\t\t\tstatusElement.style.width = '1px';\n\t\t\tstatusElement.style.overflow = 'hidden';\n\t\t\tstatusElement.style.clip = 'rect( 1px, 1px, 1px, 1px )';\n\t\t\tstatusElement.classList.add( 'aria-status' );\n\t\t\tstatusElement.setAttribute( 'aria-live', 'polite' );\n\t\t\tstatusElement.setAttribute( 'aria-atomic','true' );\n\t\t\tdom.wrapper.appendChild( statusElement );\n\t\t}\n\t\treturn statusElement;\n\n\t}\n\n\t/**\n\t * Announces the given text to screen readers.\n\t */\n\tfunction announceStatus( value ) {\n\n\t\tdom.statusElement.textContent = value;\n\n\t}\n\n\t/**\n\t * Converts the given HTML element into a string of text\n\t * that can be announced to a screen reader. Hidden\n\t * elements are excluded.\n\t */\n\tfunction getStatusText( node ) {\n\n\t\tlet text = '';\n\n\t\t// Text node\n\t\tif( node.nodeType === 3 ) {\n\t\t\ttext += node.textContent;\n\t\t}\n\t\t// Element node\n\t\telse if( node.nodeType === 1 ) {\n\n\t\t\tlet isAriaHidden = node.getAttribute( 'aria-hidden' );\n\t\t\tlet isDisplayHidden = window.getComputedStyle( node )['display'] === 'none';\n\t\t\tif( isAriaHidden !== 'true' && !isDisplayHidden ) {\n\n\t\t\t\tArray.from( node.childNodes ).forEach( child => {\n\t\t\t\t\ttext += getStatusText( child );\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t\ttext = text.trim();\n\n\t\treturn text === '' ? '' : text + ' ';\n\n\t}\n\n\t/**\n\t * This is an unfortunate necessity. Some actions – such as\n\t * an input field being focused in an iframe or using the\n\t * keyboard to expand text selection beyond the bounds of\n\t * a slide – can trigger our content to be pushed out of view.\n\t * This scrolling can not be prevented by hiding overflow in\n\t * CSS (we already do) so we have to resort to repeatedly\n\t * checking if the slides have been offset :(\n\t */\n\tfunction setupScrollPrevention() {\n\n\t\tsetInterval( () => {\n\t\t\tif( !scrollView.isActive() && dom.wrapper.scrollTop !== 0 || dom.wrapper.scrollLeft !== 0 ) {\n\t\t\t\tdom.wrapper.scrollTop = 0;\n\t\t\t\tdom.wrapper.scrollLeft = 0;\n\t\t\t}\n\t\t}, 1000 );\n\n\t}\n\n\t/**\n\t * After entering fullscreen we need to force a layout to\n\t * get our presentations to scale correctly. This behavior\n\t * is inconsistent across browsers but a force layout seems\n\t * to normalize it.\n\t */\n\tfunction setupFullscreen() {\n\n\t\tdocument.addEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.addEventListener( 'webkitfullscreenchange', onFullscreenChange );\n\n\t}\n\n\t/**\n\t * Registers a listener to postMessage events, this makes it\n\t * possible to call all reveal.js API methods from another\n\t * window. For example:\n\t *\n\t * revealWindow.postMessage( JSON.stringify({\n\t * method: 'slide',\n\t * args: [ 2 ]\n\t * }), '*' );\n\t */\n\tfunction setupPostMessage() {\n\n\t\tif( config.postMessage ) {\n\t\t\twindow.addEventListener( 'message', onPostMessage, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Applies the configuration settings from the config\n\t * object. May be called multiple times.\n\t *\n\t * @param {object} options\n\t */\n\tfunction configure( options ) {\n\n\t\tconst oldConfig = { ...config }\n\n\t\t// New config options may be passed when this method\n\t\t// is invoked through the API after initialization\n\t\tif( typeof options === 'object' ) Util.extend( config, options );\n\n\t\t// Abort if reveal.js hasn't finished loading, config\n\t\t// changes will be applied automatically once ready\n\t\tif( Reveal.isReady() === false ) return;\n\n\t\tconst numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length;\n\n\t\t// The transition is added as a class on the .reveal element\n\t\tdom.wrapper.classList.remove( oldConfig.transition );\n\t\tdom.wrapper.classList.add( config.transition );\n\n\t\tdom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );\n\t\tdom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );\n\n\t\t// Expose our configured slide dimensions as custom props\n\t\tdom.viewport.style.setProperty( '--slide-width', typeof config.width === 'string' ? config.width : config.width + 'px' );\n\t\tdom.viewport.style.setProperty( '--slide-height', typeof config.height === 'string' ? config.height : config.height + 'px' );\n\n\t\tif( config.shuffle ) {\n\t\t\tshuffle();\n\t\t}\n\n\t\tUtil.toggleClass( dom.wrapper, 'embedded', config.embedded );\n\t\tUtil.toggleClass( dom.wrapper, 'rtl', config.rtl );\n\t\tUtil.toggleClass( dom.wrapper, 'center', config.center );\n\n\t\t// Exit the paused mode if it was configured off\n\t\tif( config.pause === false ) {\n\t\t\tresume();\n\t\t}\n\n\t\t// Reset all changes made by auto-animations\n\t\tautoAnimate.reset();\n\n\t\t// Remove existing auto-slide controls\n\t\tif( autoSlidePlayer ) {\n\t\t\tautoSlidePlayer.destroy();\n\t\t\tautoSlidePlayer = null;\n\t\t}\n\n\t\t// Generate auto-slide controls if needed\n\t\tif( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable ) {\n\t\t\tautoSlidePlayer = new Playback( dom.wrapper, () => {\n\t\t\t\treturn Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );\n\t\t\t} );\n\n\t\t\tautoSlidePlayer.on( 'click', onAutoSlidePlayerClick );\n\t\t\tautoSlidePaused = false;\n\t\t}\n\n\t\t// Add the navigation mode to the DOM so we can adjust styling\n\t\tif( config.navigationMode !== 'default' ) {\n\t\t\tdom.wrapper.setAttribute( 'data-navigation-mode', config.navigationMode );\n\t\t}\n\t\telse {\n\t\t\tdom.wrapper.removeAttribute( 'data-navigation-mode' );\n\t\t}\n\n\t\tnotes.configure( config, oldConfig );\n\t\tfocus.configure( config, oldConfig );\n\t\tpointer.configure( config, oldConfig );\n\t\tcontrols.configure( config, oldConfig );\n\t\tprogress.configure( config, oldConfig );\n\t\tkeyboard.configure( config, oldConfig );\n\t\tfragments.configure( config, oldConfig );\n\t\tslideNumber.configure( config, oldConfig );\n\n\t\tsync();\n\n\t}\n\n\t/**\n\t * Binds all event listeners.\n\t */\n\tfunction addEventListeners() {\n\n\t\teventsAreBound = true;\n\n\t\twindow.addEventListener( 'resize', onWindowResize, false );\n\n\t\tif( config.touch ) touch.bind();\n\t\tif( config.keyboard ) keyboard.bind();\n\t\tif( config.progress ) progress.bind();\n\t\tif( config.respondToHashChanges ) location.bind();\n\t\tcontrols.bind();\n\t\tfocus.bind();\n\n\t\tdom.slides.addEventListener( 'click', onSlidesClicked, false );\n\t\tdom.slides.addEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.addEventListener( 'click', resume, false );\n\n\t\tif( config.focusBodyOnPageVisibilityChange ) {\n\t\t\tdocument.addEventListener( 'visibilitychange', onPageVisibilityChange, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Unbinds all event listeners.\n\t */\n\tfunction removeEventListeners() {\n\n\t\teventsAreBound = false;\n\n\t\ttouch.unbind();\n\t\tfocus.unbind();\n\t\tkeyboard.unbind();\n\t\tcontrols.unbind();\n\t\tprogress.unbind();\n\t\tlocation.unbind();\n\n\t\twindow.removeEventListener( 'resize', onWindowResize, false );\n\n\t\tdom.slides.removeEventListener( 'click', onSlidesClicked, false );\n\t\tdom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );\n\t\tdom.pauseOverlay.removeEventListener( 'click', resume, false );\n\n\t}\n\n\t/**\n\t * Uninitializes reveal.js by undoing changes made to the\n\t * DOM and removing all event listeners.\n\t */\n\tfunction destroy() {\n\n\t\tinitialized = false;\n\n\t\t// There's nothing to destroy if this instance hasn't finished\n\t\t// initializing\n\t\tif( ready === false ) return;\n\n\t\tremoveEventListeners();\n\t\tcancelAutoSlide();\n\n\t\t// Destroy controllers\n\t\tnotes.destroy();\n\t\tfocus.destroy();\n\t\toverlay.destroy();\n\t\tplugins.destroy();\n\t\tpointer.destroy();\n\t\tcontrols.destroy();\n\t\tprogress.destroy();\n\t\tbackgrounds.destroy();\n\t\tslideNumber.destroy();\n\t\tjumpToSlide.destroy();\n\n\t\t// Remove event listeners\n\t\tdocument.removeEventListener( 'fullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'webkitfullscreenchange', onFullscreenChange );\n\t\tdocument.removeEventListener( 'visibilitychange', onPageVisibilityChange, false );\n\t\twindow.removeEventListener( 'message', onPostMessage, false );\n\t\twindow.removeEventListener( 'load', layout, false );\n\n\t\t// Undo DOM changes\n\t\tif( dom.pauseOverlay ) dom.pauseOverlay.remove();\n\t\tif( dom.statusElement ) dom.statusElement.remove();\n\n\t\tdocument.documentElement.classList.remove( 'reveal-full-page' );\n\n\t\tdom.wrapper.classList.remove( 'ready', 'center', 'has-horizontal-slides', 'has-vertical-slides' );\n\t\tdom.wrapper.removeAttribute( 'data-transition-speed' );\n\t\tdom.wrapper.removeAttribute( 'data-background-transition' );\n\n\t\tdom.viewport.classList.remove( 'reveal-viewport' );\n\t\tdom.viewport.style.removeProperty( '--slide-width' );\n\t\tdom.viewport.style.removeProperty( '--slide-height' );\n\n\t\tdom.slides.style.removeProperty( 'width' );\n\t\tdom.slides.style.removeProperty( 'height' );\n\t\tdom.slides.style.removeProperty( 'zoom' );\n\t\tdom.slides.style.removeProperty( 'left' );\n\t\tdom.slides.style.removeProperty( 'top' );\n\t\tdom.slides.style.removeProperty( 'bottom' );\n\t\tdom.slides.style.removeProperty( 'right' );\n\t\tdom.slides.style.removeProperty( 'transform' );\n\n\t\tArray.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {\n\t\t\tslide.style.removeProperty( 'display' );\n\t\t\tslide.style.removeProperty( 'top' );\n\t\t\tslide.removeAttribute( 'hidden' );\n\t\t\tslide.removeAttribute( 'aria-hidden' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Adds a listener to one of our custom reveal.js events,\n\t * like slidechanged.\n\t */\n\tfunction on( type, listener, useCapture ) {\n\n\t\trevealElement.addEventListener( type, listener, useCapture );\n\n\t}\n\n\t/**\n\t * Unsubscribes from a reveal.js event.\n\t */\n\tfunction off( type, listener, useCapture ) {\n\n\t\trevealElement.removeEventListener( type, listener, useCapture );\n\n\t}\n\n\t/**\n\t * Applies CSS transforms to the slides container. The container\n\t * is transformed from two separate sources: layout and the overview\n\t * mode.\n\t *\n\t * @param {object} transforms\n\t */\n\tfunction transformSlides( transforms ) {\n\n\t\t// Pick up new transforms from arguments\n\t\tif( typeof transforms.layout === 'string' ) slidesTransform.layout = transforms.layout;\n\t\tif( typeof transforms.overview === 'string' ) slidesTransform.overview = transforms.overview;\n\n\t\t// Apply the transforms to the slides container\n\t\tif( slidesTransform.layout ) {\n\t\t\tUtil.transformElement( dom.slides, slidesTransform.layout + ' ' + slidesTransform.overview );\n\t\t}\n\t\telse {\n\t\t\tUtil.transformElement( dom.slides, slidesTransform.overview );\n\t\t}\n\n\t}\n\n\t/**\n\t * Dispatches an event of the specified type from the\n\t * reveal DOM element.\n\t */\n\tfunction dispatchEvent({ target=dom.wrapper, type, data, bubbles=true }) {\n\n\t\tlet event = document.createEvent( 'HTMLEvents', 1, 2 );\n\t\tevent.initEvent( type, bubbles, true );\n\t\tUtil.extend( event, data );\n\t\ttarget.dispatchEvent( event );\n\n\t\tif( target === dom.wrapper ) {\n\t\t\t// If we're in an iframe, post each reveal.js event to the\n\t\t\t// parent window. Used by the notes plugin\n\t\t\tdispatchPostMessage( type );\n\t\t}\n\n\t\treturn event;\n\n\t}\n\n\t/**\n\t * Dispatches a slidechanged event.\n\t *\n\t * @param {string} origin Used to identify multiplex clients\n\t */\n\tfunction dispatchSlideChanged( origin ) {\n\n\t\tdispatchEvent({\n\t\t\ttype: 'slidechanged',\n\t\t\tdata: {\n\t\t\t\tindexh,\n\t\t\t\tindexv,\n\t\t\t\tpreviousSlide,\n\t\t\t\tcurrentSlide,\n\t\t\t\torigin\n\t\t\t}\n\t\t});\n\n\t}\n\n\t/**\n\t * Dispatched a postMessage of the given type from our window.\n\t */\n\tfunction dispatchPostMessage( type, data ) {\n\n\t\tif( config.postMessageEvents && window.parent !== window.self ) {\n\t\t\tlet message = {\n\t\t\t\tnamespace: 'reveal',\n\t\t\t\teventName: type,\n\t\t\t\tstate: getState()\n\t\t\t};\n\n\t\t\tUtil.extend( message, data );\n\n\t\t\twindow.parent.postMessage( JSON.stringify( message ), '*' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Applies JavaScript-controlled layout rules to the\n\t * presentation.\n\t */\n\tfunction layout() {\n\n\t\tif( dom.wrapper && !printView.isActive() ) {\n\n\t\t\tconst viewportWidth = dom.viewport.offsetWidth;\n\t\t\tconst viewportHeight = dom.viewport.offsetHeight;\n\n\t\t\tif( !config.disableLayout ) {\n\n\t\t\t\t// On some mobile devices '100vh' is taller than the visible\n\t\t\t\t// viewport which leads to part of the presentation being\n\t\t\t\t// cut off. To work around this we define our own '--vh' custom\n\t\t\t\t// property where 100x adds up to the correct height.\n\t\t\t\t//\n\t\t\t\t// https://css-tricks.com/the-trick-to-viewport-units-on-mobile/\n\t\t\t\tif( Device.isMobile && !config.embedded ) {\n\t\t\t\t\tdocument.documentElement.style.setProperty( '--vh', ( window.innerHeight * 0.01 ) + 'px' );\n\t\t\t\t}\n\n\t\t\t\tconst size = scrollView.isActive() ?\n\t\t\t\t\t\t\t getComputedSlideSize( viewportWidth, viewportHeight ) :\n\t\t\t\t\t\t\t getComputedSlideSize();\n\n\t\t\t\tconst oldScale = scale;\n\n\t\t\t\t// Layout the contents of the slides\n\t\t\t\tlayoutSlideContents( config.width, config.height );\n\n\t\t\t\tdom.slides.style.width = size.width + 'px';\n\t\t\t\tdom.slides.style.height = size.height + 'px';\n\n\t\t\t\t// Determine scale of content to fit within available space\n\t\t\t\tscale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height );\n\n\t\t\t\t// Respect max/min scale settings\n\t\t\t\tscale = Math.max( scale, config.minScale );\n\t\t\t\tscale = Math.min( scale, config.maxScale );\n\n\t\t\t\t// Don't apply any scaling styles if scale is 1 or we're\n\t\t\t\t// in the scroll view\n\t\t\t\tif( scale === 1 || scrollView.isActive() ) {\n\t\t\t\t\tdom.slides.style.zoom = '';\n\t\t\t\t\tdom.slides.style.left = '';\n\t\t\t\t\tdom.slides.style.top = '';\n\t\t\t\t\tdom.slides.style.bottom = '';\n\t\t\t\t\tdom.slides.style.right = '';\n\t\t\t\t\ttransformSlides( { layout: '' } );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdom.slides.style.zoom = '';\n\t\t\t\t\tdom.slides.style.left = '50%';\n\t\t\t\t\tdom.slides.style.top = '50%';\n\t\t\t\t\tdom.slides.style.bottom = 'auto';\n\t\t\t\t\tdom.slides.style.right = 'auto';\n\t\t\t\t\ttransformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );\n\t\t\t\t}\n\n\t\t\t\t// Select all slides, vertical and horizontal\n\t\t\t\tconst slides = Array.from( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) );\n\n\t\t\t\tfor( let i = 0, len = slides.length; i < len; i++ ) {\n\t\t\t\t\tconst slide = slides[ i ];\n\n\t\t\t\t\t// Don't bother updating invisible slides\n\t\t\t\t\tif( slide.style.display === 'none' ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif( ( config.center || slide.classList.contains( 'center' ) ) ) {\n\t\t\t\t\t\t// Vertical stacks are not centred since their section\n\t\t\t\t\t\t// children will be\n\t\t\t\t\t\tif( slide.classList.contains( 'stack' ) ) {\n\t\t\t\t\t\t\tslide.style.top = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tslide.style.top = Math.max( ( size.height - slide.scrollHeight ) / 2, 0 ) + 'px';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tslide.style.top = '';\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif( oldScale !== scale ) {\n\t\t\t\t\tdispatchEvent({\n\t\t\t\t\t\ttype: 'resize',\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\toldScale,\n\t\t\t\t\t\t\tscale,\n\t\t\t\t\t\t\tsize\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcheckResponsiveScrollView();\n\n\t\t\tdom.viewport.style.setProperty( '--slide-scale', scale );\n\t\t\tdom.viewport.style.setProperty( '--viewport-width', viewportWidth + 'px' );\n\t\t\tdom.viewport.style.setProperty( '--viewport-height', viewportHeight + 'px' );\n\n\t\t\tscrollView.layout();\n\n\t\t\tprogress.update();\n\t\t\tbackgrounds.updateParallax();\n\n\t\t\tif( overview.isActive() ) {\n\t\t\t\toverview.update();\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Applies layout logic to the contents of all slides in\n\t * the presentation.\n\t *\n\t * @param {string|number} width\n\t * @param {string|number} height\n\t */\n\tfunction layoutSlideContents( width, height ) {\n\t\t// Handle sizing of elements with the 'r-stretch' class\n\t\tUtil.queryAll( dom.slides, 'section > .stretch, section > .r-stretch' ).forEach( element => {\n\n\t\t\t// Determine how much vertical space we can use\n\t\t\tlet remainingHeight = Util.getRemainingHeight( element, height );\n\n\t\t\t// Consider the aspect ratio of media elements\n\t\t\tif( /(img|video)/gi.test( element.nodeName ) ) {\n\t\t\t\tconst nw = element.naturalWidth || element.videoWidth,\n\t\t\t\t\t nh = element.naturalHeight || element.videoHeight;\n\n\t\t\t\tconst es = Math.min( width / nw, remainingHeight / nh );\n\n\t\t\t\telement.style.width = ( nw * es ) + 'px';\n\t\t\t\telement.style.height = ( nh * es ) + 'px';\n\n\t\t\t}\n\t\t\telse {\n\t\t\t\telement.style.width = width + 'px';\n\t\t\t\telement.style.height = remainingHeight + 'px';\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Responsively activates the scroll mode when we reach the configured\n\t * activation width.\n\t */\n\tfunction checkResponsiveScrollView() {\n\n\t\t// Only proceed if...\n\t\t// 1. The DOM is ready\n\t\t// 2. Layouts aren't disabled via config\n\t\t// 3. We're not currently printing\n\t\t// 4. There is a scrollActivationWidth set\n\t\t// 5. The deck isn't configured to always use the scroll view\n\t\tif(\n\t\t\tdom.wrapper &&\n\t\t\t!config.disableLayout &&\n\t\t\t!printView.isActive() &&\n\t\t\ttypeof config.scrollActivationWidth === 'number' &&\n\t\t\tconfig.view !== 'scroll'\n\t\t) {\n\t\t\tconst size = getComputedSlideSize();\n\n\t\t\tif( size.presentationWidth > 0 && size.presentationWidth <= config.scrollActivationWidth ) {\n\t\t\t\tif( !scrollView.isActive() ) {\n\t\t\t\t\tbackgrounds.create();\n\t\t\t\t\tscrollView.activate()\n\t\t\t\t};\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( scrollView.isActive() ) scrollView.deactivate();\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Calculates the computed pixel size of our slides. These\n\t * values are based on the width and height configuration\n\t * options.\n\t *\n\t * @param {number} [presentationWidth=dom.wrapper.offsetWidth]\n\t * @param {number} [presentationHeight=dom.wrapper.offsetHeight]\n\t */\n\tfunction getComputedSlideSize( presentationWidth, presentationHeight ) {\n\n\t\tlet width = config.width;\n\t\tlet height = config.height;\n\n\t\tif( config.disableLayout ) {\n\t\t\twidth = dom.slides.offsetWidth;\n\t\t\theight = dom.slides.offsetHeight;\n\t\t}\n\n\t\tconst size = {\n\t\t\t// Slide size\n\t\t\twidth: width,\n\t\t\theight: height,\n\n\t\t\t// Presentation size\n\t\t\tpresentationWidth: presentationWidth || dom.wrapper.offsetWidth,\n\t\t\tpresentationHeight: presentationHeight || dom.wrapper.offsetHeight\n\t\t};\n\n\t\t// Reduce available space by margin\n\t\tsize.presentationWidth -= ( size.presentationWidth * config.margin );\n\t\tsize.presentationHeight -= ( size.presentationHeight * config.margin );\n\n\t\t// Slide width may be a percentage of available width\n\t\tif( typeof size.width === 'string' && /%$/.test( size.width ) ) {\n\t\t\tsize.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth;\n\t\t}\n\n\t\t// Slide height may be a percentage of available height\n\t\tif( typeof size.height === 'string' && /%$/.test( size.height ) ) {\n\t\t\tsize.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight;\n\t\t}\n\n\t\treturn size;\n\n\t}\n\n\t/**\n\t * Stores the vertical index of a stack so that the same\n\t * vertical slide can be selected when navigating to and\n\t * from the stack.\n\t *\n\t * @param {HTMLElement} stack The vertical stack element\n\t * @param {string|number} [v=0] Index to memorize\n\t */\n\tfunction setPreviousVerticalIndex( stack, v ) {\n\n\t\tif( typeof stack === 'object' && typeof stack.setAttribute === 'function' ) {\n\t\t\tstack.setAttribute( 'data-previous-indexv', v || 0 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Retrieves the vertical index which was stored using\n\t * #setPreviousVerticalIndex() or 0 if no previous index\n\t * exists.\n\t *\n\t * @param {HTMLElement} stack The vertical stack element\n\t */\n\tfunction getPreviousVerticalIndex( stack ) {\n\n\t\tif( typeof stack === 'object' && typeof stack.setAttribute === 'function' && stack.classList.contains( 'stack' ) ) {\n\t\t\t// Prefer manually defined start-indexv\n\t\t\tconst attributeName = stack.hasAttribute( 'data-start-indexv' ) ? 'data-start-indexv' : 'data-previous-indexv';\n\n\t\t\treturn parseInt( stack.getAttribute( attributeName ) || 0, 10 );\n\t\t}\n\n\t\treturn 0;\n\n\t}\n\n\t/**\n\t * Checks if the current or specified slide is vertical\n\t * (nested within another slide).\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide to check\n\t * orientation of\n\t * @return {Boolean}\n\t */\n\tfunction isVerticalSlide( slide = currentSlide ) {\n\n\t\treturn slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );\n\n\t}\n\n\t/**\n\t * Checks if the current or specified slide is a stack containing\n\t * vertical slides.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide]\n\t * @return {Boolean}\n\t */\n\tfunction isVerticalStack( slide = currentSlide ) {\n\n\t\treturn slide.classList.contains( '.stack' ) || slide.querySelector( 'section' ) !== null;\n\n\t}\n\n\t/**\n\t * Returns true if we're on the last slide in the current\n\t * vertical stack.\n\t */\n\tfunction isLastVerticalSlide() {\n\n\t\tif( currentSlide && isVerticalSlide( currentSlide ) ) {\n\t\t\t// Does this slide have a next sibling?\n\t\t\tif( currentSlide.nextElementSibling ) return false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Returns true if we're currently on the first slide in\n\t * the presentation.\n\t */\n\tfunction isFirstSlide() {\n\n\t\treturn indexh === 0 && indexv === 0;\n\n\t}\n\n\t/**\n\t * Returns true if we're currently on the last slide in\n\t * the presentation. If the last slide is a stack, we only\n\t * consider this the last slide if it's at the end of the\n\t * stack.\n\t */\n\tfunction isLastSlide() {\n\n\t\tif( currentSlide ) {\n\t\t\t// Does this slide have a next sibling?\n\t\t\tif( currentSlide.nextElementSibling ) return false;\n\n\t\t\t// If it's vertical, does its parent have a next sibling?\n\t\t\tif( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Enters the paused mode which fades everything on screen to\n\t * black.\n\t */\n\tfunction pause() {\n\n\t\tif( config.pause ) {\n\t\t\tconst wasPaused = dom.wrapper.classList.contains( 'paused' );\n\n\t\t\tcancelAutoSlide();\n\t\t\tdom.wrapper.classList.add( 'paused' );\n\n\t\t\tif( wasPaused === false ) {\n\t\t\t\tdispatchEvent({ type: 'paused' });\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Exits from the paused mode.\n\t */\n\tfunction resume() {\n\n\t\tconst wasPaused = dom.wrapper.classList.contains( 'paused' );\n\t\tdom.wrapper.classList.remove( 'paused' );\n\n\t\tcueAutoSlide();\n\n\t\tif( wasPaused ) {\n\t\t\tdispatchEvent({ type: 'resumed' });\n\t\t}\n\n\t}\n\n\t/**\n\t * Toggles the paused mode on and off.\n\t */\n\tfunction togglePause( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? pause() : resume();\n\t\t}\n\t\telse {\n\t\t\tisPaused() ? resume() : pause();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if we are currently in the paused mode.\n\t *\n\t * @return {Boolean}\n\t */\n\tfunction isPaused() {\n\n\t\treturn dom.wrapper.classList.contains( 'paused' );\n\n\t}\n\n\t/**\n\t * Toggles visibility of the jump-to-slide UI.\n\t */\n\tfunction toggleJumpToSlide( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? jumpToSlide.show() : jumpToSlide.hide();\n\t\t}\n\t\telse {\n\t\t\tjumpToSlide.isVisible() ? jumpToSlide.hide() : jumpToSlide.show();\n\t\t}\n\n\t}\n\n\t/**\n\t * Toggles the auto slide mode on and off.\n\t *\n\t * @param {Boolean} [override] Flag which sets the desired state.\n\t * True means autoplay starts, false means it stops.\n\t */\n\n\tfunction toggleAutoSlide( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? resumeAutoSlide() : pauseAutoSlide();\n\t\t}\n\n\t\telse {\n\t\t\tautoSlidePaused ? resumeAutoSlide() : pauseAutoSlide();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the auto slide mode is currently on.\n\t *\n\t * @return {Boolean}\n\t */\n\tfunction isAutoSliding() {\n\n\t\treturn !!( autoSlide && !autoSlidePaused );\n\n\t}\n\n\t/**\n\t * Steps from the current point in the presentation to the\n\t * slide which matches the specified horizontal and vertical\n\t * indices.\n\t *\n\t * @param {number} [h=indexh] Horizontal index of the target slide\n\t * @param {number} [v=indexv] Vertical index of the target slide\n\t * @param {number} [f] Index of a fragment within the\n\t * target slide to activate\n\t * @param {number} [origin] Origin for use in multimaster environments\n\t */\n\tfunction slide( h, v, f, origin ) {\n\n\t\t// Dispatch an event before the slide\n\t\tconst slidechange = dispatchEvent({\n\t\t\ttype: 'beforeslidechange',\n\t\t\tdata: {\n\t\t\t\tindexh: h === undefined ? indexh : h,\n\t\t\t\tindexv: v === undefined ? indexv : v,\n\t\t\t\torigin\n\t\t\t}\n\t\t});\n\n\t\t// Abort if this slide change was prevented by an event listener\n\t\tif( slidechange.defaultPrevented ) return;\n\n\t\t// Remember where we were at before\n\t\tpreviousSlide = currentSlide;\n\n\t\t// Query all horizontal slides in the deck\n\t\tconst horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );\n\n\t\t// If we're in scroll mode, we scroll the target slide into view\n\t\t// instead of running our standard slide transition\n\t\tif( scrollView.isActive() ) {\n\t\t\tconst scrollToSlide = scrollView.getSlideByIndices( h, v );\n\t\t\tif( scrollToSlide ) scrollView.scrollToSlide( scrollToSlide );\n\t\t\treturn;\n\t\t}\n\n\t\t// Abort if there are no slides\n\t\tif( horizontalSlides.length === 0 ) return;\n\n\t\t// If no vertical index is specified and the upcoming slide is a\n\t\t// stack, resume at its previous vertical index\n\t\tif( v === undefined && !overview.isActive() ) {\n\t\t\tv = getPreviousVerticalIndex( horizontalSlides[ h ] );\n\t\t}\n\n\t\t// If we were on a vertical stack, remember what vertical index\n\t\t// it was on so we can resume at the same position when returning\n\t\tif( previousSlide && previousSlide.parentNode && previousSlide.parentNode.classList.contains( 'stack' ) ) {\n\t\t\tsetPreviousVerticalIndex( previousSlide.parentNode, indexv );\n\t\t}\n\n\t\t// Remember the state before this slide\n\t\tconst stateBefore = state.concat();\n\n\t\t// Reset the state array\n\t\tstate.length = 0;\n\n\t\tlet indexhBefore = indexh || 0,\n\t\t\tindexvBefore = indexv || 0;\n\n\t\t// Activate and transition to the new slide\n\t\tindexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );\n\t\tindexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );\n\n\t\t// Dispatch an event if the slide changed\n\t\tlet slideChanged = ( indexh !== indexhBefore || indexv !== indexvBefore );\n\n\t\t// Ensure that the previous slide is never the same as the current\n\t\tif( !slideChanged ) previousSlide = null;\n\n\t\t// Find the current horizontal slide and any possible vertical slides\n\t\t// within it\n\t\tlet currentHorizontalSlide = horizontalSlides[ indexh ],\n\t\t\tcurrentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );\n\n\t\t// Indicate when we're on a vertical slide\n\t\trevealElement.classList.toggle( 'is-vertical-slide', currentVerticalSlides.length > 1 );\n\n\t\t// Store references to the previous and current slides\n\t\tcurrentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;\n\n\t\tlet autoAnimateTransition = false;\n\n\t\t// Detect if we're moving between two auto-animated slides\n\t\tif( slideChanged && previousSlide && currentSlide && !overview.isActive() ) {\n\t\t\ttransition = 'running';\n\n\t\t\tautoAnimateTransition = shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexvBefore );\n\n\t\t\t// If this is an auto-animated transition, we disable the\n\t\t\t// regular slide transition\n\t\t\t//\n\t\t\t// Note 20-03-2020:\n\t\t\t// This needs to happen before we update slide visibility,\n\t\t\t// otherwise transitions will still run in Safari.\n\t\t\tif( autoAnimateTransition ) {\n\t\t\t\tdom.slides.classList.add( 'disable-slide-transitions' )\n\t\t\t}\n\t\t}\n\n\t\t// Update the visibility of slides now that the indices have changed\n\t\tupdateSlidesVisibility();\n\n\t\tlayout();\n\n\t\t// Update the overview if it's currently active\n\t\tif( overview.isActive() ) {\n\t\t\toverview.update();\n\t\t}\n\n\t\t// Show fragment, if specified\n\t\tif( typeof f !== 'undefined' ) {\n\t\t\tfragments.goto( f );\n\t\t}\n\n\t\t// Solves an edge case where the previous slide maintains the\n\t\t// 'present' class when navigating between adjacent vertical\n\t\t// stacks\n\t\tif( previousSlide && previousSlide !== currentSlide ) {\n\t\t\tpreviousSlide.classList.remove( 'present' );\n\t\t\tpreviousSlide.setAttribute( 'aria-hidden', 'true' );\n\n\t\t\t// Reset all slides upon navigate to home\n\t\t\tif( isFirstSlide() ) {\n\t\t\t\t// Launch async task\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tgetVerticalStacks().forEach( slide => {\n\t\t\t\t\t\tsetPreviousVerticalIndex( slide, 0 );\n\t\t\t\t\t} );\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t}\n\n\t\t// Apply the new state\n\t\tstateLoop: for( let i = 0, len = state.length; i < len; i++ ) {\n\t\t\t// Check if this state existed on the previous slide. If it\n\t\t\t// did, we will avoid adding it repeatedly\n\t\t\tfor( let j = 0; j < stateBefore.length; j++ ) {\n\t\t\t\tif( stateBefore[j] === state[i] ) {\n\t\t\t\t\tstateBefore.splice( j, 1 );\n\t\t\t\t\tcontinue stateLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdom.viewport.classList.add( state[i] );\n\n\t\t\t// Dispatch custom event matching the state's name\n\t\t\tdispatchEvent({ type: state[i] });\n\t\t}\n\n\t\t// Clean up the remains of the previous state\n\t\twhile( stateBefore.length ) {\n\t\t\tdom.viewport.classList.remove( stateBefore.pop() );\n\t\t}\n\n\t\tif( slideChanged ) {\n\t\t\tdispatchSlideChanged( origin );\n\t\t}\n\n\t\t// Handle embedded content\n\t\tif( slideChanged || !previousSlide ) {\n\t\t\tslideContent.stopEmbeddedContent( previousSlide );\n\t\t\tslideContent.startEmbeddedContent( currentSlide );\n\t\t}\n\n\t\t// Announce the current slide contents to screen readers\n\t\t// Use animation frame to prevent getComputedStyle in getStatusText\n\t\t// from triggering layout mid-frame\n\t\trequestAnimationFrame( () => {\n\t\t\tannounceStatus( getStatusText( currentSlide ) );\n\t\t});\n\n\t\tprogress.update();\n\t\tcontrols.update();\n\t\tnotes.update();\n\t\tbackgrounds.update();\n\t\tbackgrounds.updateParallax();\n\t\tslideNumber.update();\n\t\tfragments.update();\n\n\t\t// Update the URL hash\n\t\tlocation.writeURL();\n\n\t\tcueAutoSlide();\n\n\t\t// Auto-animation\n\t\tif( autoAnimateTransition ) {\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tdom.slides.classList.remove( 'disable-slide-transitions' );\n\t\t\t}, 0 );\n\n\t\t\tif( config.autoAnimate ) {\n\t\t\t\t// Run the auto-animation between our slides\n\t\t\t\tautoAnimate.run( previousSlide, currentSlide );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks whether or not an auto-animation should take place between\n\t * the two given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t * @param {number} indexhBefore\n\t * @param {number} indexvBefore\n\t *\n\t * @returns {boolean}\n\t */\n\tfunction shouldAutoAnimateBetween( fromSlide, toSlide, indexhBefore, indexvBefore ) {\n\n\t\treturn \tfromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' ) &&\n\t\t\t\tfromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) &&\n\t\t\t\t!( ( indexh > indexhBefore || indexv > indexvBefore ) ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' );\n\n\t}\n\n\t/**\n\t * Called anytime a new slide should be activated while in the scroll\n\t * view. The active slide is the page that occupies the most space in\n\t * the scrollable viewport.\n\t *\n\t * @param {number} pageIndex\n\t * @param {HTMLElement} slideElement\n\t */\n\tfunction setCurrentScrollPage( slideElement, h, v ) {\n\n\t\tlet indexhBefore = indexh || 0;\n\n\t\tindexh = h;\n\t\tindexv = v;\n\n\t\tconst slideChanged = currentSlide !== slideElement;\n\n\t\tpreviousSlide = currentSlide;\n\t\tcurrentSlide = slideElement;\n\n\t\tif( currentSlide && previousSlide ) {\n\t\t\tif( config.autoAnimate && shouldAutoAnimateBetween( previousSlide, currentSlide, indexhBefore, indexv ) ) {\n\t\t\t\t// Run the auto-animation between our slides\n\t\t\t\tautoAnimate.run( previousSlide, currentSlide );\n\t\t\t}\n\t\t}\n\n\t\t// Start or stop embedded content like videos and iframes\n\t\tif( slideChanged ) {\n\t\t\tif( previousSlide ) {\n\t\t\t\tslideContent.stopEmbeddedContent( previousSlide );\n\t\t\t\tslideContent.stopEmbeddedContent( previousSlide.slideBackgroundElement );\n\t\t\t}\n\n\t\t\tslideContent.startEmbeddedContent( currentSlide );\n\t\t\tslideContent.startEmbeddedContent( currentSlide.slideBackgroundElement );\n\t\t}\n\n\t\trequestAnimationFrame( () => {\n\t\t\tannounceStatus( getStatusText( currentSlide ) );\n\t\t});\n\n\t\tdispatchSlideChanged();\n\n\t}\n\n\t/**\n\t * Syncs the presentation with the current DOM. Useful\n\t * when new slides or control elements are added or when\n\t * the configuration has changed.\n\t */\n\tfunction sync() {\n\n\t\t// Subscribe to input\n\t\tremoveEventListeners();\n\t\taddEventListeners();\n\n\t\t// Force a layout to make sure the current config is accounted for\n\t\tlayout();\n\n\t\t// Reflect the current autoSlide value\n\t\tautoSlide = config.autoSlide;\n\n\t\t// Start auto-sliding if it's enabled\n\t\tcueAutoSlide();\n\n\t\t// Re-create all slide backgrounds\n\t\tbackgrounds.create();\n\n\t\t// Write the current hash to the URL\n\t\tlocation.writeURL();\n\n\t\tif( config.sortFragmentsOnSync === true ) {\n\t\t\tfragments.sortAll();\n\t\t}\n\n\t\tcontrols.update();\n\t\tprogress.update();\n\n\t\tupdateSlidesVisibility();\n\n\t\tnotes.update();\n\t\tnotes.updateVisibility();\n\t\toverlay.update();\n\t\tbackgrounds.update( true );\n\t\tslideNumber.update();\n\t\tslideContent.formatEmbeddedContent();\n\n\t\t// Start or stop embedded content depending on global config\n\t\tif( config.autoPlayMedia === false ) {\n\t\t\tslideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } );\n\t\t}\n\t\telse {\n\t\t\tslideContent.startEmbeddedContent( currentSlide );\n\t\t}\n\n\t\tif( overview.isActive() ) {\n\t\t\toverview.layout();\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates reveal.js to keep in sync with new slide attributes. For\n\t * example, if you add a new `data-background-image` you can call\n\t * this to have reveal.js render the new background image.\n\t *\n\t * Similar to #sync() but more efficient when you only need to\n\t * refresh a specific slide.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tfunction syncSlide( slide = currentSlide ) {\n\n\t\tbackgrounds.sync( slide );\n\t\tfragments.sync( slide );\n\n\t\tslideContent.load( slide );\n\n\t\tbackgrounds.update();\n\t\tnotes.update();\n\n\t}\n\n\t/**\n\t * Resets all vertical slides so that only the first\n\t * is visible.\n\t */\n\tfunction resetVerticalSlides() {\n\n\t\tgetHorizontalSlides().forEach( horizontalSlide => {\n\n\t\t\tUtil.queryAll( horizontalSlide, 'section' ).forEach( ( verticalSlide, y ) => {\n\n\t\t\t\tif( y > 0 ) {\n\t\t\t\t\tverticalSlide.classList.remove( 'present' );\n\t\t\t\t\tverticalSlide.classList.remove( 'past' );\n\t\t\t\t\tverticalSlide.classList.add( 'future' );\n\t\t\t\t\tverticalSlide.setAttribute( 'aria-hidden', 'true' );\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Randomly shuffles all slides in the deck.\n\t */\n\tfunction shuffle( slides = getHorizontalSlides() ) {\n\n\t\tslides.forEach( ( slide, i ) => {\n\n\t\t\t// Insert the slide next to a randomly picked sibling slide\n\t\t\t// slide. This may cause the slide to insert before itself,\n\t\t\t// but that's not an issue.\n\t\t\tlet beforeSlide = slides[ Math.floor( Math.random() * slides.length ) ];\n\t\t\tif( beforeSlide.parentNode === slide.parentNode ) {\n\t\t\t\tslide.parentNode.insertBefore( slide, beforeSlide );\n\t\t\t}\n\n\t\t\t// Randomize the order of vertical slides (if there are any)\n\t\t\tlet verticalSlides = slide.querySelectorAll( 'section' );\n\t\t\tif( verticalSlides.length ) {\n\t\t\t\tshuffle( verticalSlides );\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Updates one dimension of slides by showing the slide\n\t * with the specified index.\n\t *\n\t * @param {string} selector A CSS selector that will fetch\n\t * the group of slides we are working with\n\t * @param {number} index The index of the slide that should be\n\t * shown\n\t *\n\t * @return {number} The index of the slide that is now shown,\n\t * might differ from the passed in index if it was out of\n\t * bounds.\n\t */\n\tfunction updateSlides( selector, index ) {\n\n\t\t// Select all slides and convert the NodeList result to\n\t\t// an array\n\t\tlet slides = Util.queryAll( dom.wrapper, selector ),\n\t\t\tslidesLength = slides.length;\n\n\t\tlet printMode = scrollView.isActive() || printView.isActive();\n\t\tlet loopedForwards = false;\n\t\tlet loopedBackwards = false;\n\n\t\tif( slidesLength ) {\n\n\t\t\t// Should the index loop?\n\t\t\tif( config.loop ) {\n\t\t\t\tif( index >= slidesLength ) loopedForwards = true;\n\n\t\t\t\tindex %= slidesLength;\n\n\t\t\t\tif( index < 0 ) {\n\t\t\t\t\tindex = slidesLength + index;\n\t\t\t\t\tloopedBackwards = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Enforce max and minimum index bounds\n\t\t\tindex = Math.max( Math.min( index, slidesLength - 1 ), 0 );\n\n\t\t\tfor( let i = 0; i < slidesLength; i++ ) {\n\t\t\t\tlet element = slides[i];\n\n\t\t\t\tlet reverse = config.rtl && !isVerticalSlide( element );\n\n\t\t\t\t// Avoid .remove() with multiple args for IE11 support\n\t\t\t\telement.classList.remove( 'past' );\n\t\t\t\telement.classList.remove( 'present' );\n\t\t\t\telement.classList.remove( 'future' );\n\n\t\t\t\t// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute\n\t\t\t\telement.setAttribute( 'hidden', '' );\n\t\t\t\telement.setAttribute( 'aria-hidden', 'true' );\n\n\t\t\t\t// If this element contains vertical slides\n\t\t\t\tif( element.querySelector( 'section' ) ) {\n\t\t\t\t\telement.classList.add( 'stack' );\n\t\t\t\t}\n\n\t\t\t\t// If we're printing static slides, all slides are \"present\"\n\t\t\t\tif( printMode ) {\n\t\t\t\t\telement.classList.add( 'present' );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif( i < index ) {\n\t\t\t\t\t// Any element previous to index is given the 'past' class\n\t\t\t\t\telement.classList.add( reverse ? 'future' : 'past' );\n\n\t\t\t\t\tif( config.fragments ) {\n\t\t\t\t\t\t// Show all fragments in prior slides\n\t\t\t\t\t\tshowFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( i > index ) {\n\t\t\t\t\t// Any element subsequent to index is given the 'future' class\n\t\t\t\t\telement.classList.add( reverse ? 'past' : 'future' );\n\n\t\t\t\t\tif( config.fragments ) {\n\t\t\t\t\t\t// Hide all fragments in future slides\n\t\t\t\t\t\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Update the visibility of fragments when a presentation loops\n\t\t\t\t// in either direction\n\t\t\t\telse if( i === index && config.fragments ) {\n\t\t\t\t\tif( loopedForwards ) {\n\t\t\t\t\t\thideFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t\telse if( loopedBackwards ) {\n\t\t\t\t\t\tshowFragmentsIn( element );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet slide = slides[index];\n\t\t\tlet wasPresent = slide.classList.contains( 'present' );\n\n\t\t\t// Mark the current slide as present\n\t\t\tslide.classList.add( 'present' );\n\t\t\tslide.removeAttribute( 'hidden' );\n\t\t\tslide.removeAttribute( 'aria-hidden' );\n\n\t\t\tif( !wasPresent ) {\n\t\t\t\t// Dispatch an event indicating the slide is now visible\n\t\t\t\tdispatchEvent({\n\t\t\t\t\ttarget: slide,\n\t\t\t\t\ttype: 'visible',\n\t\t\t\t\tbubbles: false\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// If this slide has a state associated with it, add it\n\t\t\t// onto the current state of the deck\n\t\t\tlet slideState = slide.getAttribute( 'data-state' );\n\t\t\tif( slideState ) {\n\t\t\t\tstate = state.concat( slideState.split( ' ' ) );\n\t\t\t}\n\n\t\t}\n\t\telse {\n\t\t\t// Since there are no slides we can't be anywhere beyond the\n\t\t\t// zeroth index\n\t\t\tindex = 0;\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\t/**\n\t * Shows all fragment elements within the given container.\n\t */\n\tfunction showFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment' ).forEach( fragment => {\n\t\t\tfragment.classList.add( 'visible' );\n\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Hides all fragment elements within the given container.\n\t */\n\tfunction hideFragmentsIn( container ) {\n\n\t\tUtil.queryAll( container, '.fragment.visible' ).forEach( fragment => {\n\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Optimization method; hide all slides that are far away\n\t * from the present slide.\n\t */\n\tfunction updateSlidesVisibility() {\n\n\t\t// Select all slides and convert the NodeList result to\n\t\t// an array\n\t\tlet horizontalSlides = getHorizontalSlides(),\n\t\t\thorizontalSlidesLength = horizontalSlides.length,\n\t\t\tdistanceX,\n\t\t\tdistanceY;\n\n\t\tif( horizontalSlidesLength && typeof indexh !== 'undefined' ) {\n\n\t\t\t// The number of steps away from the present slide that will\n\t\t\t// be visible\n\t\t\tlet viewDistance = overview.isActive() ? 10 : config.viewDistance;\n\n\t\t\t// Shorten the view distance on devices that typically have\n\t\t\t// less resources\n\t\t\tif( Device.isMobile ) {\n\t\t\t\tviewDistance = overview.isActive() ? 6 : config.mobileViewDistance;\n\t\t\t}\n\n\t\t\t// All slides need to be visible when exporting to PDF\n\t\t\tif( printView.isActive() ) {\n\t\t\t\tviewDistance = Number.MAX_VALUE;\n\t\t\t}\n\n\t\t\tfor( let x = 0; x < horizontalSlidesLength; x++ ) {\n\t\t\t\tlet horizontalSlide = horizontalSlides[x];\n\n\t\t\t\tlet verticalSlides = Util.queryAll( horizontalSlide, 'section' ),\n\t\t\t\t\tverticalSlidesLength = verticalSlides.length;\n\n\t\t\t\t// Determine how far away this slide is from the present\n\t\t\t\tdistanceX = Math.abs( ( indexh || 0 ) - x ) || 0;\n\n\t\t\t\t// If the presentation is looped, distance should measure\n\t\t\t\t// 1 between the first and last slides\n\t\t\t\tif( config.loop ) {\n\t\t\t\t\tdistanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;\n\t\t\t\t}\n\n\t\t\t\t// Show the horizontal slide if it's within the view distance\n\t\t\t\tif( distanceX < viewDistance ) {\n\t\t\t\t\tslideContent.load( horizontalSlide );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tslideContent.unload( horizontalSlide );\n\t\t\t\t}\n\n\t\t\t\tif( verticalSlidesLength ) {\n\n\t\t\t\t\tlet oy = getPreviousVerticalIndex( horizontalSlide );\n\n\t\t\t\t\tfor( let y = 0; y < verticalSlidesLength; y++ ) {\n\t\t\t\t\t\tlet verticalSlide = verticalSlides[y];\n\n\t\t\t\t\t\tdistanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy );\n\n\t\t\t\t\t\tif( distanceX + distanceY < viewDistance ) {\n\t\t\t\t\t\t\tslideContent.load( verticalSlide );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tslideContent.unload( verticalSlide );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Flag if there are ANY vertical slides, anywhere in the deck\n\t\t\tif( hasVerticalSlides() ) {\n\t\t\t\tdom.wrapper.classList.add( 'has-vertical-slides' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdom.wrapper.classList.remove( 'has-vertical-slides' );\n\t\t\t}\n\n\t\t\t// Flag if there are ANY horizontal slides, anywhere in the deck\n\t\t\tif( hasHorizontalSlides() ) {\n\t\t\t\tdom.wrapper.classList.add( 'has-horizontal-slides' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdom.wrapper.classList.remove( 'has-horizontal-slides' );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Determine what available routes there are for navigation.\n\t *\n\t * @return {{left: boolean, right: boolean, up: boolean, down: boolean}}\n\t */\n\tfunction availableRoutes({ includeFragments = false } = {}) {\n\n\t\tlet horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),\n\t\t\tverticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR );\n\n\t\tlet routes = {\n\t\t\tleft: indexh > 0,\n\t\t\tright: indexh < horizontalSlides.length - 1,\n\t\t\tup: indexv > 0,\n\t\t\tdown: indexv < verticalSlides.length - 1\n\t\t};\n\n\t\t// Looped presentations can always be navigated as long as\n\t\t// there are slides available\n\t\tif( config.loop ) {\n\t\t\tif( horizontalSlides.length > 1 ) {\n\t\t\t\troutes.left = true;\n\t\t\t\troutes.right = true;\n\t\t\t}\n\n\t\t\tif( verticalSlides.length > 1 ) {\n\t\t\t\troutes.up = true;\n\t\t\t\troutes.down = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( horizontalSlides.length > 1 && config.navigationMode === 'linear' ) {\n\t\t\troutes.right = routes.right || routes.down;\n\t\t\troutes.left = routes.left || routes.up;\n\t\t}\n\n\t\t// If includeFragments is set, a route will be considered\n\t\t// available if either a slid OR fragment is available in\n\t\t// the given direction\n\t\tif( includeFragments === true ) {\n\t\t\tlet fragmentRoutes = fragments.availableRoutes();\n\t\t\troutes.left = routes.left || fragmentRoutes.prev;\n\t\t\troutes.up = routes.up || fragmentRoutes.prev;\n\t\t\troutes.down = routes.down || fragmentRoutes.next;\n\t\t\troutes.right = routes.right || fragmentRoutes.next;\n\t\t}\n\n\t\t// Reverse horizontal controls for rtl\n\t\tif( config.rtl ) {\n\t\t\tlet left = routes.left;\n\t\t\troutes.left = routes.right;\n\t\t\troutes.right = left;\n\t\t}\n\n\t\treturn routes;\n\n\t}\n\n\t/**\n\t * Returns the number of past slides. This can be used as a global\n\t * flattened index for slides.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide we're counting before\n\t *\n\t * @return {number} Past slide count\n\t */\n\tfunction getSlidePastCount( slide = currentSlide ) {\n\n\t\tlet horizontalSlides = getHorizontalSlides();\n\n\t\t// The number of past slides\n\t\tlet pastCount = 0;\n\n\t\t// Step through all slides and count the past ones\n\t\tmainLoop: for( let i = 0; i < horizontalSlides.length; i++ ) {\n\n\t\t\tlet horizontalSlide = horizontalSlides[i];\n\t\t\tlet verticalSlides = horizontalSlide.querySelectorAll( 'section' );\n\n\t\t\tfor( let j = 0; j < verticalSlides.length; j++ ) {\n\n\t\t\t\t// Stop as soon as we arrive at the present\n\t\t\t\tif( verticalSlides[j] === slide ) {\n\t\t\t\t\tbreak mainLoop;\n\t\t\t\t}\n\n\t\t\t\t// Don't count slides with the \"uncounted\" class\n\t\t\t\tif( verticalSlides[j].dataset.visibility !== 'uncounted' ) {\n\t\t\t\t\tpastCount++;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Stop as soon as we arrive at the present\n\t\t\tif( horizontalSlide === slide ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Don't count the wrapping section for vertical slides and\n\t\t\t// slides marked as uncounted\n\t\t\tif( horizontalSlide.classList.contains( 'stack' ) === false && horizontalSlide.dataset.visibility !== 'uncounted' ) {\n\t\t\t\tpastCount++;\n\t\t\t}\n\n\t\t}\n\n\t\treturn pastCount;\n\n\t}\n\n\t/**\n\t * Returns a value ranging from 0-1 that represents\n\t * how far into the presentation we have navigated.\n\t *\n\t * @return {number}\n\t */\n\tfunction getProgress() {\n\n\t\t// The number of past and total slides\n\t\tlet totalCount = getTotalSlides();\n\t\tlet pastCount = getSlidePastCount();\n\n\t\tif( currentSlide ) {\n\n\t\t\tlet allFragments = currentSlide.querySelectorAll( '.fragment' );\n\n\t\t\t// If there are fragments in the current slide those should be\n\t\t\t// accounted for in the progress.\n\t\t\tif( allFragments.length > 0 ) {\n\t\t\t\tlet visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );\n\n\t\t\t\t// This value represents how big a portion of the slide progress\n\t\t\t\t// that is made up by its fragments (0-1)\n\t\t\t\tlet fragmentWeight = 0.9;\n\n\t\t\t\t// Add fragment progress to the past slide count\n\t\t\t\tpastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight;\n\t\t\t}\n\n\t\t}\n\n\t\treturn Math.min( pastCount / ( totalCount - 1 ), 1 );\n\n\t}\n\n\t/**\n\t * Retrieves the h/v location and fragment of the current,\n\t * or specified, slide.\n\t *\n\t * @param {HTMLElement} [slide] If specified, the returned\n\t * index will be for this slide rather than the currently\n\t * active one\n\t *\n\t * @return {{h: number, v: number, f: number}}\n\t */\n\tfunction getIndices( slide ) {\n\n\t\t// By default, return the current indices\n\t\tlet h = indexh,\n\t\t\tv = indexv,\n\t\t\tf;\n\n\t\t// If a slide is specified, return the indices of that slide\n\t\tif( slide ) {\n\t\t\t// In scroll mode the original h/x index is stored on the slide\n\t\t\tif( scrollView.isActive() ) {\n\t\t\t\th = parseInt( slide.getAttribute( 'data-index-h' ), 10 );\n\n\t\t\t\tif( slide.getAttribute( 'data-index-v' ) ) {\n\t\t\t\t\tv = parseInt( slide.getAttribute( 'data-index-v' ), 10 );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlet isVertical = isVerticalSlide( slide );\n\t\t\t\tlet slideh = isVertical ? slide.parentNode : slide;\n\n\t\t\t\t// Select all horizontal slides\n\t\t\t\tlet horizontalSlides = getHorizontalSlides();\n\n\t\t\t\t// Now that we know which the horizontal slide is, get its index\n\t\t\t\th = Math.max( horizontalSlides.indexOf( slideh ), 0 );\n\n\t\t\t\t// Assume we're not vertical\n\t\t\t\tv = undefined;\n\n\t\t\t\t// If this is a vertical slide, grab the vertical index\n\t\t\t\tif( isVertical ) {\n\t\t\t\t\tv = Math.max( Util.queryAll( slide.parentNode, 'section' ).indexOf( slide ), 0 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( !slide && currentSlide ) {\n\t\t\tlet hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;\n\t\t\tif( hasFragments ) {\n\t\t\t\tlet currentFragment = currentSlide.querySelector( '.current-fragment' );\n\t\t\t\tif( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\t\tf = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tf = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { h, v, f };\n\n\t}\n\n\t/**\n\t * Retrieves all slides in this presentation.\n\t */\n\tfunction getSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, SLIDES_SELECTOR + ':not(.stack):not([data-visibility=\"uncounted\"])' );\n\n\t}\n\n\t/**\n\t * Returns a list of all horizontal slides in the deck. Each\n\t * vertical stack is included as one horizontal slide in the\n\t * resulting array.\n\t */\n\tfunction getHorizontalSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR );\n\n\t}\n\n\t/**\n\t * Returns all vertical slides that exist within this deck.\n\t */\n\tfunction getVerticalSlides() {\n\n\t\treturn Util.queryAll( dom.wrapper, '.slides>section>section' );\n\n\t}\n\n\t/**\n\t * Returns all vertical stacks (each stack can contain multiple slides).\n\t */\n\tfunction getVerticalStacks() {\n\n\t\treturn Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.stack');\n\n\t}\n\n\t/**\n\t * Returns true if there are at least two horizontal slides.\n\t */\n\tfunction hasHorizontalSlides() {\n\n\t\treturn getHorizontalSlides().length > 1;\n\t}\n\n\t/**\n\t * Returns true if there are at least two vertical slides.\n\t */\n\tfunction hasVerticalSlides() {\n\n\t\treturn getVerticalSlides().length > 1;\n\n\t}\n\n\t/**\n\t * Returns an array of objects where each object represents the\n\t * attributes on its respective slide.\n\t */\n\tfunction getSlidesAttributes() {\n\n\t\treturn getSlides().map( slide => {\n\n\t\t\tlet attributes = {};\n\t\t\tfor( let i = 0; i < slide.attributes.length; i++ ) {\n\t\t\t\tlet attribute = slide.attributes[ i ];\n\t\t\t\tattributes[ attribute.name ] = attribute.value;\n\t\t\t}\n\t\t\treturn attributes;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Retrieves the total number of slides in this presentation.\n\t *\n\t * @return {number}\n\t */\n\tfunction getTotalSlides() {\n\n\t\treturn getSlides().length;\n\n\t}\n\n\t/**\n\t * Returns the slide element matching the specified index.\n\t *\n\t * @return {HTMLElement}\n\t */\n\tfunction getSlide( x, y ) {\n\n\t\tlet horizontalSlide = getHorizontalSlides()[ x ];\n\t\tlet verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );\n\n\t\tif( verticalSlides && verticalSlides.length && typeof y === 'number' ) {\n\t\t\treturn verticalSlides ? verticalSlides[ y ] : undefined;\n\t\t}\n\n\t\treturn horizontalSlide;\n\n\t}\n\n\t/**\n\t * Returns the background element for the given slide.\n\t * All slides, even the ones with no background properties\n\t * defined, have a background element so as long as the\n\t * index is valid an element will be returned.\n\t *\n\t * @param {mixed} x Horizontal background index OR a slide\n\t * HTML element\n\t * @param {number} y Vertical background index\n\t * @return {(HTMLElement[]|*)}\n\t */\n\tfunction getSlideBackground( x, y ) {\n\n\t\tlet slide = typeof x === 'number' ? getSlide( x, y ) : x;\n\t\tif( slide ) {\n\t\t\treturn slide.slideBackgroundElement;\n\t\t}\n\n\t\treturn undefined;\n\n\t}\n\n\t/**\n\t * Retrieves the current state of the presentation as\n\t * an object. This state can then be restored at any\n\t * time.\n\t *\n\t * @return {{indexh: number, indexv: number, indexf: number, paused: boolean, overview: boolean}}\n\t */\n\tfunction getState() {\n\n\t\tlet indices = getIndices();\n\n\t\treturn {\n\t\t\tindexh: indices.h,\n\t\t\tindexv: indices.v,\n\t\t\tindexf: indices.f,\n\t\t\tpaused: isPaused(),\n\t\t\toverview: overview.isActive(),\n\t\t\t...overlay.getState()\n\t\t};\n\n\t}\n\n\t/**\n\t * Restores the presentation to the given state.\n\t *\n\t * @param {object} state As generated by getState()\n\t * @see {@link getState} generates the parameter `state`\n\t */\n\tfunction setState( state ) {\n\n\t\tif( typeof state === 'object' ) {\n\t\t\tslide( Util.deserialize( state.indexh ), Util.deserialize( state.indexv ), Util.deserialize( state.indexf ) );\n\n\t\t\tlet pausedFlag = Util.deserialize( state.paused ),\n\t\t\t\toverviewFlag = Util.deserialize( state.overview );\n\n\t\t\tif( typeof pausedFlag === 'boolean' && pausedFlag !== isPaused() ) {\n\t\t\t\ttogglePause( pausedFlag );\n\t\t\t}\n\n\t\t\tif( typeof overviewFlag === 'boolean' && overviewFlag !== overview.isActive() ) {\n\t\t\t\toverview.toggle( overviewFlag );\n\t\t\t}\n\n\t\t\toverlay.setState( state );\n\t\t}\n\n\t}\n\n\t/**\n\t * Cues a new automated slide if enabled in the config.\n\t */\n\tfunction cueAutoSlide() {\n\n\t\tcancelAutoSlide();\n\n\t\tif( currentSlide && config.autoSlide !== false ) {\n\n\t\t\tlet fragment = currentSlide.querySelector( '.current-fragment[data-autoslide]' );\n\n\t\t\tlet fragmentAutoSlide = fragment ? fragment.getAttribute( 'data-autoslide' ) : null;\n\t\t\tlet parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;\n\t\t\tlet slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );\n\n\t\t\t// Pick value in the following priority order:\n\t\t\t// 1. Current fragment's data-autoslide\n\t\t\t// 2. Current slide's data-autoslide\n\t\t\t// 3. Parent slide's data-autoslide\n\t\t\t// 4. Global autoSlide setting\n\t\t\tif( fragmentAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( fragmentAutoSlide, 10 );\n\t\t\t}\n\t\t\telse if( slideAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( slideAutoSlide, 10 );\n\t\t\t}\n\t\t\telse if( parentAutoSlide ) {\n\t\t\t\tautoSlide = parseInt( parentAutoSlide, 10 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tautoSlide = config.autoSlide;\n\n\t\t\t\t// If there are media elements with data-autoplay,\n\t\t\t\t// automatically set the autoSlide duration to the\n\t\t\t\t// length of that media. Not applicable if the slide\n\t\t\t\t// is divided up into fragments.\n\t\t\t\t// playbackRate is accounted for in the duration.\n\t\t\t\tif( currentSlide.querySelectorAll( '.fragment' ).length === 0 ) {\n\t\t\t\t\tUtil.queryAll( currentSlide, 'video, audio' ).forEach( el => {\n\t\t\t\t\t\tif( el.hasAttribute( 'data-autoplay' ) ) {\n\t\t\t\t\t\t\tif( autoSlide && (el.duration * 1000 / el.playbackRate ) > autoSlide ) {\n\t\t\t\t\t\t\t\tautoSlide = ( el.duration * 1000 / el.playbackRate ) + 1000;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Cue the next auto-slide if:\n\t\t\t// - There is an autoSlide value\n\t\t\t// - Auto-sliding isn't paused by the user\n\t\t\t// - The presentation isn't paused\n\t\t\t// - The overview isn't active\n\t\t\t// - The presentation isn't over\n\t\t\tif( autoSlide && !autoSlidePaused && !isPaused() && !overview.isActive() && ( !isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) {\n\t\t\t\tautoSlideTimeout = setTimeout( () => {\n\t\t\t\t\tif( typeof config.autoSlideMethod === 'function' ) {\n\t\t\t\t\t\tconfig.autoSlideMethod()\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnavigateNext();\n\t\t\t\t\t}\n\t\t\t\t\tcueAutoSlide();\n\t\t\t\t}, autoSlide );\n\t\t\t\tautoSlideStartTime = Date.now();\n\t\t\t}\n\n\t\t\tif( autoSlidePlayer ) {\n\t\t\t\tautoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Cancels any ongoing request to auto-slide.\n\t */\n\tfunction cancelAutoSlide() {\n\n\t\tclearTimeout( autoSlideTimeout );\n\t\tautoSlideTimeout = -1;\n\n\t}\n\n\tfunction pauseAutoSlide() {\n\n\t\tif( autoSlide && !autoSlidePaused ) {\n\t\t\tautoSlidePaused = true;\n\t\t\tdispatchEvent({ type: 'autoslidepaused' });\n\t\t\tclearTimeout( autoSlideTimeout );\n\n\t\t\tif( autoSlidePlayer ) {\n\t\t\t\tautoSlidePlayer.setPlaying( false );\n\t\t\t}\n\t\t}\n\n\t}\n\n\tfunction resumeAutoSlide() {\n\n\t\tif( autoSlide && autoSlidePaused ) {\n\t\t\tautoSlidePaused = false;\n\t\t\tdispatchEvent({ type: 'autoslideresumed' });\n\t\t\tcueAutoSlide();\n\t\t}\n\n\t}\n\n\tfunction navigateLeft({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.prev();\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().left ) {\n\t\t\t\tslide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t\t}\n\t\t}\n\t\t// Normal navigation\n\t\telse if( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().left ) {\n\t\t\tslide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t}\n\n\t}\n\n\tfunction navigateRight({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.next();\n\n\t\t// Reverse for RTL\n\t\tif( config.rtl ) {\n\t\t\tif( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().right ) {\n\t\t\t\tslide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t\t}\n\t\t}\n\t\t// Normal navigation\n\t\telse if( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().right ) {\n\t\t\tslide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );\n\t\t}\n\n\t}\n\n\tfunction navigateUp({skipFragments=false}={}) {\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.prev();\n\n\t\t// Prioritize hiding fragments\n\t\tif( ( overview.isActive() || skipFragments || fragments.prev() === false ) && availableRoutes().up ) {\n\t\t\tslide( indexh, indexv - 1 );\n\t\t}\n\n\t}\n\n\tfunction navigateDown({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.next();\n\n\t\t// Prioritize revealing fragments\n\t\tif( ( overview.isActive() || skipFragments || fragments.next() === false ) && availableRoutes().down ) {\n\t\t\tslide( indexh, indexv + 1 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Navigates backwards, prioritized in the following order:\n\t * 1) Previous fragment\n\t * 2) Previous vertical slide\n\t * 3) Previous horizontal slide\n\t */\n\tfunction navigatePrev({skipFragments=false}={}) {\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.prev();\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || fragments.prev() === false ) {\n\t\t\tif( availableRoutes().up ) {\n\t\t\t\tnavigateUp({skipFragments});\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Fetch the previous horizontal slide, if there is one\n\t\t\t\tlet previousSlide;\n\n\t\t\t\tif( config.rtl ) {\n\t\t\t\t\tpreviousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.future' ).pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpreviousSlide = Util.queryAll( dom.wrapper, HORIZONTAL_SLIDES_SELECTOR + '.past' ).pop();\n\t\t\t\t}\n\n\t\t\t\t// When going backwards and arriving on a stack we start\n\t\t\t\t// at the bottom of the stack\n\t\t\t\tif( previousSlide && previousSlide.classList.contains( 'stack' ) ) {\n\t\t\t\t\tlet v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;\n\t\t\t\t\tlet h = indexh - 1;\n\t\t\t\t\tslide( h, v );\n\t\t\t\t}\n\t\t\t\telse if( config.rtl ) {\n\t\t\t\t\tnavigateRight({skipFragments});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnavigateLeft({skipFragments});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * The reverse of #navigatePrev().\n\t */\n\tfunction navigateNext({skipFragments=false}={}) {\n\n\t\tnavigationHistory.hasNavigatedHorizontally = true;\n\t\tnavigationHistory.hasNavigatedVertically = true;\n\n\t\t// Scroll view navigation is handled independently\n\t\tif( scrollView.isActive() ) return scrollView.next();\n\n\t\t// Prioritize revealing fragments\n\t\tif( skipFragments || fragments.next() === false ) {\n\n\t\t\tlet routes = availableRoutes();\n\n\t\t\t// When looping is enabled `routes.down` is always available\n\t\t\t// so we need a separate check for when we've reached the\n\t\t\t// end of a stack and should move horizontally\n\t\t\tif( routes.down && routes.right && config.loop && isLastVerticalSlide() ) {\n\t\t\t\troutes.down = false;\n\t\t\t}\n\n\t\t\tif( routes.down ) {\n\t\t\t\tnavigateDown({skipFragments});\n\t\t\t}\n\t\t\telse if( config.rtl ) {\n\t\t\t\tnavigateLeft({skipFragments});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnavigateRight({skipFragments});\n\t\t\t}\n\t\t}\n\n\t}\n\n\n\t// --------------------------------------------------------------------//\n\t// ----------------------------- EVENTS -------------------------------//\n\t// --------------------------------------------------------------------//\n\n\t/**\n\t * Called by all event handlers that are based on user\n\t * input.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onUserInput( event ) {\n\n\t\tif( config.autoSlideStoppable ) {\n\t\t\tpauseAutoSlide();\n\t\t}\n\n\t}\n\n\t/**\n\t* Listener for post message events posted to this window.\n\t*/\n\tfunction onPostMessage( event ) {\n\n\t\tlet data = event.data;\n\n\t\t// Make sure we're dealing with JSON\n\t\tif( typeof data === 'string' && data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {\n\t\t\tdata = JSON.parse( data );\n\n\t\t\t// Check if the requested method can be found\n\t\t\tif( data.method && typeof Reveal[data.method] === 'function' ) {\n\n\t\t\t\tif( POST_MESSAGE_METHOD_BLACKLIST.test( data.method ) === false ) {\n\n\t\t\t\t\tconst result = Reveal[data.method].apply( Reveal, data.args );\n\n\t\t\t\t\t// Dispatch a postMessage event with the returned value from\n\t\t\t\t\t// our method invocation for getter functions\n\t\t\t\t\tdispatchPostMessage( 'callback', { method: data.method, result: result } );\n\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconsole.warn( 'reveal.js: \"'+ data.method +'\" is is blacklisted from the postMessage API' );\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Event listener for transition end on the current slide.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onTransitionEnd( event ) {\n\n\t\tif( transition === 'running' && /section/gi.test( event.target.nodeName ) ) {\n\t\t\ttransition = 'idle';\n\t\t\tdispatchEvent({\n\t\t\t\ttype: 'slidetransitionend',\n\t\t\t\tdata: { indexh, indexv, previousSlide, currentSlide }\n\t\t\t});\n\t\t}\n\n\t}\n\n\t/**\n\t * A global listener for all click events inside of the\n\t * .slides container.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onSlidesClicked( event ) {\n\n\t\tconst anchor = Util.closest( event.target, 'a[href^=\"#\"]' );\n\n\t\t// If a hash link is clicked, we find the target slide\n\t\t// and navigate to it. We previously relied on 'hashchange'\n\t\t// for links like these but that prevented media with\n\t\t// audio tracks from playing in mobile browsers since it\n\t\t// wasn't considered a direct interaction with the document.\n\t\tif( anchor ) {\n\t\t\tconst hash = anchor.getAttribute( 'href' );\n\t\t\tconst indices = location.getIndicesFromHash( hash );\n\n\t\t\tif( indices ) {\n\t\t\t\tReveal.slide( indices.h, indices.v, indices.f );\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the window level 'resize' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onWindowResize( event ) {\n\n\t\tlayout();\n\t}\n\n\t/**\n\t * Handle for the window level 'visibilitychange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onPageVisibilityChange( event ) {\n\n\t\t// If, after clicking a link or similar and we're coming back,\n\t\t// focus the document.body to ensure we can use keyboard shortcuts\n\t\tif( document.hidden === false && document.activeElement !== document.body ) {\n\t\t\t// Not all elements support .blur() - SVGs among them.\n\t\t\tif( typeof document.activeElement.blur === 'function' ) {\n\t\t\t\tdocument.activeElement.blur();\n\t\t\t}\n\t\t\tdocument.body.focus();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the document level 'fullscreenchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onFullscreenChange( event ) {\n\n\t\tlet element = document.fullscreenElement || document.webkitFullscreenElement;\n\t\tif( element === dom.wrapper ) {\n\t\t\tevent.stopImmediatePropagation();\n\n\t\t\t// Timeout to avoid layout shift in Safari\n\t\t\tsetTimeout( () => {\n\t\t\t\tReveal.layout();\n\t\t\t\tReveal.focus.focus(); // focus.focus :'(\n\t\t\t}, 1 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Handles click on the auto-sliding controls element.\n\t *\n\t * @param {object} [event]\n\t */\n\tfunction onAutoSlidePlayerClick( event ) {\n\n\t\t// Replay\n\t\tif( isLastSlide() && config.loop === false ) {\n\t\t\tslide( 0, 0 );\n\t\t\tresumeAutoSlide();\n\t\t}\n\t\t// Resume\n\t\telse if( autoSlidePaused ) {\n\t\t\tresumeAutoSlide();\n\t\t}\n\t\t// Pause\n\t\telse {\n\t\t\tpauseAutoSlide();\n\t\t}\n\n\t}\n\n\n\t// --------------------------------------------------------------------//\n\t// ------------------------------- API --------------------------------//\n\t// --------------------------------------------------------------------//\n\n\t// The public reveal.js API\n\tconst API = {\n\t\tVERSION,\n\n\t\tinitialize,\n\t\tconfigure,\n\t\tdestroy,\n\n\t\tsync,\n\t\tsyncSlide,\n\t\tsyncFragments: fragments.sync.bind( fragments ),\n\n\t\t// Navigation methods\n\t\tslide,\n\t\tleft: navigateLeft,\n\t\tright: navigateRight,\n\t\tup: navigateUp,\n\t\tdown: navigateDown,\n\t\tprev: navigatePrev,\n\t\tnext: navigateNext,\n\n\t\t// Navigation aliases\n\t\tnavigateLeft, navigateRight, navigateUp, navigateDown, navigatePrev, navigateNext,\n\n\t\t// Fragment methods\n\t\tnavigateFragment: fragments.goto.bind( fragments ),\n\t\tprevFragment: fragments.prev.bind( fragments ),\n\t\tnextFragment: fragments.next.bind( fragments ),\n\n\t\t// Event binding\n\t\ton,\n\t\toff,\n\n\t\t// Legacy event binding methods left in for backwards compatibility\n\t\taddEventListener: on,\n\t\tremoveEventListener: off,\n\n\t\t// Forces an update in slide layout\n\t\tlayout,\n\n\t\t// Randomizes the order of slides\n\t\tshuffle,\n\n\t\t// Returns an object with the available routes as booleans (left/right/top/bottom)\n\t\tavailableRoutes,\n\n\t\t// Returns an object with the available fragments as booleans (prev/next)\n\t\tavailableFragments: fragments.availableRoutes.bind( fragments ),\n\n\t\t// Toggles a help overlay with keyboard shortcuts\n\t\ttoggleHelp: overlay.toggleHelp.bind( overlay ),\n\n\t\t// Toggles the overview mode on/off\n\t\ttoggleOverview: overview.toggle.bind( overview ),\n\n\t\t// Toggles the scroll view on/off\n\t\ttoggleScrollView: scrollView.toggle.bind( scrollView ),\n\n\t\t// Toggles the \"black screen\" mode on/off\n\t\ttogglePause,\n\n\t\t// Toggles the auto slide mode on/off\n\t\ttoggleAutoSlide,\n\n\t\t// Toggles visibility of the jump-to-slide UI\n\t\ttoggleJumpToSlide,\n\n\t\t// Slide navigation checks\n\t\tisFirstSlide,\n\t\tisLastSlide,\n\t\tisLastVerticalSlide,\n\t\tisVerticalSlide,\n\t\tisVerticalStack,\n\n\t\t// State checks\n\t\tisPaused,\n\t\tisAutoSliding,\n\t\tisSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),\n\t\tisOverview: overview.isActive.bind( overview ),\n\t\tisFocused: focus.isFocused.bind( focus ),\n\t\tisOverlayOpen: overlay.isOpen.bind( overlay ),\n\t\tisScrollView: scrollView.isActive.bind( scrollView ),\n\t\tisPrintView: printView.isActive.bind( printView ),\n\n\t\t// Checks if reveal.js has been loaded and is ready for use\n\t\tisReady: () => ready,\n\n\t\t// Slide preloading\n\t\tloadSlide: slideContent.load.bind( slideContent ),\n\t\tunloadSlide: slideContent.unload.bind( slideContent ),\n\n\t\t// Start/stop all media inside of the current slide\n\t\tstartEmbeddedContent: () => slideContent.startEmbeddedContent( currentSlide ),\n\t\tstopEmbeddedContent: () => slideContent.stopEmbeddedContent( currentSlide, { unloadIframes: false } ),\n\n\t\t// Preview management\n\t\tshowIframePreview: overlay.showIframePreview.bind( overlay ),\n\t\tshowMediaPreview: overlay.showMediaPreview.bind( overlay ),\n\t\tshowPreview: overlay.showIframePreview.bind( overlay ), // deprecated in favor of showIframePreview\n\t\thidePreview: overlay.close.bind( overlay ),\n\n\t\t// Adds or removes all internal event listeners\n\t\taddEventListeners,\n\t\tremoveEventListeners,\n\t\tdispatchEvent,\n\n\t\t// Facility for persisting and restoring the presentation state\n\t\tgetState,\n\t\tsetState,\n\n\t\t// Presentation progress on range of 0-1\n\t\tgetProgress,\n\n\t\t// Returns the indices of the current, or specified, slide\n\t\tgetIndices,\n\n\t\t// Returns an Array of key:value maps of the attributes of each\n\t\t// slide in the deck\n\t\tgetSlidesAttributes,\n\n\t\t// Returns the number of slides that we have passed\n\t\tgetSlidePastCount,\n\n\t\t// Returns the total number of slides\n\t\tgetTotalSlides,\n\n\t\t// Returns the slide element at the specified index\n\t\tgetSlide,\n\n\t\t// Returns the previous slide element, may be null\n\t\tgetPreviousSlide: () => previousSlide,\n\n\t\t// Returns the current slide element\n\t\tgetCurrentSlide: () => currentSlide,\n\n\t\t// Returns the slide background element at the specified index\n\t\tgetSlideBackground,\n\n\t\t// Returns the speaker notes string for a slide, or null\n\t\tgetSlideNotes: notes.getSlideNotes.bind( notes ),\n\n\t\t// Returns an Array of all slides\n\t\tgetSlides,\n\n\t\t// Returns an array with all horizontal/vertical slides in the deck\n\t\tgetHorizontalSlides,\n\t\tgetVerticalSlides,\n\n\t\t// Checks if the presentation contains two or more horizontal\n\t\t// and vertical slides\n\t\thasHorizontalSlides,\n\t\thasVerticalSlides,\n\n\t\t// Checks if the deck has navigated on either axis at least once\n\t\thasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,\n\t\thasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,\n\n\t\tshouldAutoAnimateBetween,\n\n\t\t// Adds/removes a custom key binding\n\t\taddKeyBinding: keyboard.addKeyBinding.bind( keyboard ),\n\t\tremoveKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),\n\n\t\t// Programmatically triggers a keyboard event\n\t\ttriggerKey: keyboard.triggerKey.bind( keyboard ),\n\n\t\t// Registers a new shortcut to include in the help overlay\n\t\tregisterKeyboardShortcut: keyboard.registerKeyboardShortcut.bind( keyboard ),\n\n\t\tgetComputedSlideSize,\n\t\tsetCurrentScrollPage,\n\n\t\t// Returns the current scale of the presentation content\n\t\tgetScale: () => scale,\n\n\t\t// Returns the current configuration object\n\t\tgetConfig: () => config,\n\n\t\t// Helper method, retrieves query string as a key:value map\n\t\tgetQueryHash: Util.getQueryHash,\n\n\t\t// Returns the path to the current slide as represented in the URL\n\t\tgetSlidePath: location.getHash.bind( location ),\n\n\t\t// Returns reveal.js DOM elements\n\t\tgetRevealElement: () => revealElement,\n\t\tgetSlidesElement: () => dom.slides,\n\t\tgetViewportElement: () => dom.viewport,\n\t\tgetBackgroundsElement: () => backgrounds.element,\n\n\t\t// API for registering and retrieving plugins\n\t\tregisterPlugin: plugins.registerPlugin.bind( plugins ),\n\t\thasPlugin: plugins.hasPlugin.bind( plugins ),\n\t\tgetPlugin: plugins.getPlugin.bind( plugins ),\n\t\tgetPlugins: plugins.getRegisteredPlugins.bind( plugins )\n\n\t};\n\n\t// Our internal API which controllers have access to\n\tUtil.extend( Reveal, {\n\t\t...API,\n\n\t\t// Methods for announcing content to screen readers\n\t\tannounceStatus,\n\t\tgetStatusText,\n\n\t\t// Controllers\n\t\tfocus,\n\t\tscroll: scrollView,\n\t\tprogress,\n\t\tcontrols,\n\t\tlocation,\n\t\toverview,\n\t\tkeyboard,\n\t\tfragments,\n\t\tbackgrounds,\n\t\tslideContent,\n\t\tslideNumber,\n\n\t\tonUserInput,\n\t\tcloseOverlay: overlay.close.bind( overlay ),\n\t\tupdateSlidesVisibility,\n\t\tlayoutSlideContents,\n\t\ttransformSlides,\n\t\tcueAutoSlide,\n\t\tcancelAutoSlide\n\t} );\n\n\treturn API;\n\n};\n","import Deck, { VERSION } from './reveal.js'\n\n/**\n * Expose the Reveal class to the window. To create a\n * new instance:\n * let deck = new Reveal( document.querySelector( '.reveal' ), {\n * controls: false\n * } );\n * deck.initialize().then(() => {\n * // reveal.js is ready\n * });\n */\nlet Reveal = Deck;\n\n\n/**\n * The below is a thin shell that mimics the pre 4.0\n * reveal.js API and ensures backwards compatibility.\n * This API only allows for one Reveal instance per\n * page, whereas the new API above lets you run many\n * presentations on the same page.\n *\n * Reveal.initialize( { controls: false } ).then(() => {\n * // reveal.js is ready\n * });\n */\n\nlet enqueuedAPICalls = [];\n\nReveal.initialize = options => {\n\n\t// Create our singleton reveal.js instance\n\tObject.assign( Reveal, new Deck( document.querySelector( '.reveal' ), options ) );\n\n\t// Invoke any enqueued API calls\n\tenqueuedAPICalls.map( method => method( Reveal ) );\n\n\treturn Reveal.initialize();\n\n}\n\n/**\n * The pre 4.0 API let you add event listener before\n * initializing. We maintain the same behavior by\n * queuing up premature API calls and invoking all\n * of them when Reveal.initialize is called.\n */\n[ 'configure', 'on', 'off', 'addEventListener', 'removeEventListener', 'registerPlugin' ].forEach( method => {\n\tReveal[method] = ( ...args ) => {\n\t\tenqueuedAPICalls.push( deck => deck[method].call( null, ...args ) );\n\t}\n} );\n\nReveal.isReady = () => false;\n\nReveal.VERSION = VERSION;\n\nexport default Reveal;"],"names":["extend","a","b","i","queryAll","el","selector","Array","from","querySelectorAll","toggleClass","className","value","classList","add","remove","deserialize","match","parseFloat","transformElement","element","transform","style","matches","target","matchesMethod","matchesSelector","msMatchesSelector","call","closest","parentNode","enterFullscreen","requestMethod","document","documentElement","requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","apply","createStyleSheet","tag","createElement","type","length","styleSheet","cssText","appendChild","createTextNode","head","getQueryHash","query","location","search","replace","split","shift","pop","unescape","fileExtensionToMimeMap","mp4","m4a","ogv","mpeg","webm","UA","navigator","userAgent","isMobile","test","platform","maxTouchPoints","isAndroid","e","t","slice","o","l","u","cancelAnimationFrame","requestAnimationFrame","s","filter","dirty","active","c","forEach","styleComputed","m","y","v","p","d","f","S","availableWidth","clientWidth","currentWidth","scrollWidth","previousFontSize","currentFontSize","Math","min","max","minSize","maxSize","whiteSpace","multiLine","n","getComputedStyle","getPropertyValue","display","preStyleTestCompleted","fontSize","dispatchEvent","CustomEvent","detail","oldValue","newValue","scaleFactor","h","w","observeMutations","observer","disconnect","originalStyle","z","F","MutationObserver","observe","g","subtree","childList","characterData","W","E","clearTimeout","setTimeout","x","observeWindowDelay","M","Object","defineProperty","set","concat","observeWindow","fitAll","C","assign","map","newbie","push","fit","unfreeze","freeze","unsubscribe","arguments","window","SlideContent","constructor","Reveal","this","startEmbeddedIframe","bind","shouldPreload","isScrollView","preload","getConfig","preloadIframes","hasAttribute","load","slide","options","tagName","setAttribute","getAttribute","removeAttribute","media","sources","source","background","slideBackgroundElement","backgroundContent","slideBackgroundContentElement","backgroundIframe","backgroundImage","backgroundVideo","backgroundVideoLoop","backgroundVideoMuted","trim","encodeRFC3986URI","url","encodeURI","charCodeAt","toString","toUpperCase","decodeURI","join","video","isSpeakerNotes","muted","sourceElement","getMimeTypeFromFile","filename","excludeIframes","iframe","width","height","maxHeight","maxWidth","backgroundIframeElement","querySelector","layout","scopeElement","fitty","unload","getSlideBackground","formatEmbeddedContent","_appendParamToIframeSource","sourceAttribute","sourceURL","param","getSlidesElement","src","indexOf","startEmbeddedContent","isSpeakerNotesWindow","autoplay","autoPlayMedia","play","readyState","startEmbeddedMedia","promise","catch","controls","addEventListener","removeEventListener","event","isAttachedToDOM","isVisible","paused","ended","currentTime","contentWindow","postMessage","stopEmbeddedContent","unloadIframes","pause","SLIDES_SELECTOR","HORIZONTAL_SLIDES_SELECTOR","VERTICAL_SLIDES_SELECTOR","POST_MESSAGE_METHOD_BLACKLIST","SlideNumber","render","getRevealElement","configure","config","oldConfig","slideNumberDisplay","slideNumber","isPrintView","showSlideNumber","update","innerHTML","getSlideNumber","getCurrentSlide","format","getHorizontalSlides","horizontalOffset","dataset","visibility","getSlidePastCount","getTotalSlides","indices","getIndices","sep","isVerticalSlide","getHash","formatNumber","delimiter","isNaN","destroy","JumpToSlide","onInput","onBlur","onKeyDown","jumpInput","placeholder","show","indicesOnShow","focus","hide","jumpTimeout","jump","slideNumberFormat","getSlides","parseInt","getIndicesFromHash","oneBasedIndex","jumpAfter","delay","regex","RegExp","find","innerText","cancel","confirm","keyCode","stopImmediatePropagation","colorToRgb","color","hex3","r","charAt","hex6","rgb","rgba","Backgrounds","create","slideh","backgroundStack","createBackground","slidev","parallaxBackgroundImage","backgroundSize","parallaxBackgroundSize","backgroundRepeat","parallaxBackgroundRepeat","backgroundPosition","parallaxBackgroundPosition","container","contentElement","sync","data","backgroundColor","backgroundGradient","backgroundTransition","backgroundOpacity","dataPreload","opacity","contrastClass","getContrastClass","contrastColor","computedBackgroundStyle","bubbleSlideContrastClassToElement","classToBubble","contains","includeAll","currentSlide","currentBackground","horizontalPast","rtl","horizontalFuture","childNodes","backgroundh","backgroundv","indexv","previousBackground","previousBackgroundHash","currentBackgroundHash","currentVideo","previousVideo","currentVideoParent","backgroundChanged","slideContent","currentBackgroundContent","backgroundImageURL","updateParallax","backgroundWidth","backgroundHeight","horizontalSlides","verticalSlides","getVerticalSlides","horizontalOffsetMultiplier","slideWidth","offsetWidth","horizontalSlideCount","parallaxBackgroundHorizontal","verticalOffsetMultiplier","verticalOffset","slideHeight","offsetHeight","verticalSlideCount","parallaxBackgroundVertical","autoAnimateCounter","AutoAnimate","run","fromSlide","toSlide","reset","allSlides","toSlideIndex","fromSlideIndex","autoAnimateStyleSheet","animationOptions","getAutoAnimateOptions","autoAnimate","slideDirection","fromSlideIsHidden","css","getAutoAnimatableElements","elements","autoAnimateElements","to","autoAnimateUnmatched","defaultUnmatchedDuration","duration","defaultUnmatchedDelay","getUnmatchedAutoAnimateElements","unmatchedElement","unmatchedOptions","id","autoAnimateTarget","fontWeight","sheet","removeChild","elementOptions","easing","fromProps","getAutoAnimatableProperties","toProps","styles","translate","scale","presentationScale","getScale","delta","scaleX","scaleY","round","propertyName","toValue","fromValue","explicitValue","toStyleProperties","keys","inheritedOptions","autoAnimateEasing","autoAnimateDuration","autoAnimatedParent","autoAnimateDelay","direction","properties","bounds","measure","center","getBoundingClientRect","offsetLeft","offsetTop","computedStyles","autoAnimateStyles","property","pairs","autoAnimateMatcher","getAutoAnimatePairs","reserved","pair","index","textNodes","findAutoAnimateMatches","node","nodeName","textContent","getLocalBoundingBox","fromScope","toScope","serializer","fromMatches","toMatches","key","fromElement","primaryIndex","secondaryIndex","rootElement","children","reduce","result","containsAnimatedElements","ScrollView","activatedCallbacks","onScroll","activate","stateBeforeActivation","getState","slideHTMLBeforeActivation","horizontalBackgrounds","presentationBackground","viewportElement","viewportStyles","pageElements","pageContainer","previousSlide","createPageElement","isVertical","contentContainer","shouldAutoAnimateBetween","page","slideBackground","pageBackground","stickyContainer","insertBefore","horizontalSlide","isVerticalStack","verticalSlide","createProgressBar","stack","setState","callback","restoreScrollPosition","passive","deactivate","stateBeforeDeactivation","removeProgressBar","toggle","override","isActive","progressBar","progressBarInner","progressBarPlayhead","firstChild","handleDocumentMouseMove","progress","clientY","top","progressBarHeight","scrollTop","scrollHeight","handleDocumentMouseUp","draggingProgressBar","showProgressBar","preventDefault","syncPages","syncScrollPosition","slideSize","getComputedSlideSize","innerWidth","innerHeight","useCompactLayout","scrollLayout","viewportHeight","compactHeight","pageHeight","scrollTriggerHeight","setProperty","scrollSnapType","scrollSnap","slideTriggers","pages","pageElement","createPage","slideElement","stickyElement","backgroundElement","autoAnimatePages","activatePage","deactivatePage","createFragmentTriggersForPage","createAutoAnimateTriggersForPage","totalScrollTriggerCount","scrollTriggers","total","triggerStick","scrollSnapAlign","marginTop","removeProperty","scrollPadding","totalHeight","position","setTriggerRanges","scrollProgress","syncProgressBar","trigger","rangeStart","range","scrollTriggerSegmentSize","scrollTrigger","fragmentGroups","fragments","sort","autoAnimateElement","autoAnimatePage","indexh","viewportHeightFactor","playheadHeight","progressBarScrollableHeight","progressSegmentHeight","spacing","slideTrigger","progressBarSlide","scrollTriggerElements","triggerElement","scrollProgressMid","activePage","loaded","activateTrigger","deactivateTrigger","setProgressBarValue","getAllPages","hideProgressBarTimeout","prev","next","scrollToSlide","getScrollTriggerBySlide","storeScrollPosition","storeScrollPositionTimeout","sessionStorage","setItem","origin","pathname","scrollPosition","getItem","scrollOrigin","setCurrentScrollPage","backgrounds","sibling","getSlideByIndices","flatMap","getViewportElement","PrintView","slides","injectPageNumbers","pageWidth","floor","margin","Promise","body","layoutSlideContents","slideScrollHeights","left","contentHeight","numberOfPages","ceil","pdfMaxPagesPerSlide","pdfPageHeightOffset","showNotes","notes","getSlideNotes","notesSpacing","notesLayout","notesElement","bottom","numberElement","pdfSeparateFragments","previousFragmentStep","fragment","clonedPage","cloneNode","fragmentNumber","view","Fragments","disable","enable","availableRoutes","hiddenFragments","grouped","ordered","unordered","sorted","group","sortAll","changedFragments","shown","hidden","maxIndex","currentFragment","wasVisible","announceStatus","getStatusText","bubbles","goto","offset","lastVisibleFragment","fragmentInURL","writeURL","Overview","onSlideClicked","overview","cancelAutoSlide","getBackgroundsElement","overviewSlideWidth","overviewSlideHeight","updateSlidesVisibility","hslide","vslide","hbackground","vbackground","vmin","transformSlides","cueAutoSlide","Keyboard","shortcuts","bindings","onDocumentKeyDown","navigationMode","unbind","addKeyBinding","binding","description","removeKeyBinding","triggerKey","registerKeyboardShortcut","getShortcuts","getBindings","keyboardCondition","isFocused","autoSlideWasPaused","isAutoSliding","onUserInput","activeElementIsCE","activeElement","isContentEditable","activeElementIsInput","activeElementIsNotes","unusedModifier","shiftKey","altKey","ctrlKey","metaKey","resumeKeyCodes","keyboard","isOverlayOpen","includes","isPaused","useLinearMode","hasHorizontalSlides","hasVerticalSlides","triggered","action","skipFragments","right","undefined","up","Number","MAX_VALUE","down","togglePause","embedded","autoSlideStoppable","toggleAutoSlide","jumpToSlide","toggleJumpToSlide","closeOverlay","toggleHelp","Location","MAX_REPLACE_STATE_FREQUENCY","writeURLTimeout","replaceStateTimestamp","onWindowHashChange","hash","name","bits","hashIndexBase","hashOneBasedIndex","getElementById","decodeURIComponent","error","readURL","currentIndices","newIndices","history","debouncedReplaceState","replaceState","Date","now","replaceStateTimeout","encodeURIComponent","Controls","onNavigateLeftClicked","onNavigateRightClicked","onNavigateUpClicked","onNavigateDownClicked","onNavigatePrevClicked","onNavigateNextClicked","onEnterFullscreen","revealElement","controlsLeft","controlsRight","controlsUp","controlsDown","controlsPrev","controlsNext","controlsFullscreen","controlsRightArrow","controlsLeftArrow","controlsDownArrow","controlsLayout","controlsBackArrows","pointerEvents","eventName","routes","fragmentsRoutes","hasVerticalSiblings","parentElement","controlsTutorial","hasNavigatedVertically","hasNavigatedHorizontally","viewport","Progress","onProgressClicked","bar","getProgress","getMaxWidth","slidesTotal","slideIndex","clientX","targetIndices","Pointer","lastMouseWheelStep","cursorHidden","cursorInactiveTimeout","onDocumentCursorActive","onDocumentMouseScroll","mouseWheel","hideInactiveCursor","showCursor","cursor","hideCursor","hideCursorTime","wheelDelta","loadScript","script","async","defer","onload","onreadystatechange","onerror","err","Error","lastChild","Plugins","reveal","state","registeredPlugins","asyncDependencies","plugins","dependencies","registerPlugin","resolve","scripts","scriptsToLoad","condition","scriptLoadedCallback","initPlugins","then","console","warn","pluginValues","values","pluginsToInitialize","loadAsync","initNextPlugin","afterPlugInitialized","plugin","init","hasPlugin","getPlugin","getRegisteredPlugins","Overlay","onSlidesClicked","linkPreviewSelector","mediaPreviewSelector","previewLinks","hasLinkPreviews","hasMediaPreviews","createOverlay","dom","showIframePreview","close","previewIframe","showMediaPreview","mediaType","fitMode","previewFit","previewImage","img","previewVideo","previewAutoplay","previewControls","loop","previewLoop","previewMuted","playsInline","showHelp","help","html","isOpen","linkTarget","mediaTarget","Touch","touchStartX","touchStartY","touchStartCount","touchCaptured","onPointerDown","onPointerMove","onPointerUp","onTouchStart","onTouchMove","onTouchEnd","msPointerEnabled","isSwipePrevented","touches","currentX","currentY","includeFragments","deltaX","deltaY","abs","pointerType","MSPOINTER_TYPE_TOUCH","STATE_FOCUS","STATE_BLUR","Focus","onRevealPointerDown","onDocumentPointerDown","blur","Notes","updateVisibility","hasNotes","notesElements","Playback","progressCheck","diameter","diameter2","thickness","playing","progressOffset","canvas","context","getContext","setPlaying","wasPlaying","animate","progressBefore","radius","iconSize","endAngle","PI","startAngle","save","clearRect","beginPath","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","fillRect","moveTo","lineTo","restore","on","listener","off","defaultConfig","minScale","maxScale","respondToHashChanges","disableLayout","touch","shuffle","showHiddenSlides","autoSlide","autoSlideMethod","defaultTiming","postMessageEvents","focusBodyOnPageVisibilityChange","transition","transitionSpeed","scrollActivationWidth","POSITIVE_INFINITY","viewDistance","mobileViewDistance","sortFragmentsOnSync","VERSION","Deck","autoSlidePlayer","initialized","ready","navigationHistory","slidesTransform","autoSlideTimeout","autoSlideStartTime","autoSlidePaused","scrollView","printView","pointer","overlay","start","Util","wrapper","parent","childElementCount","Device","pauseOverlay","createSingletonNode","tagname","classname","nodes","testNode","statusElement","overflow","clip","createStatusElement","setupDOM","onPostMessage","setInterval","scrollLeft","onFullscreenChange","activatePrintView","activateScrollView","removeEventListeners","activateInitialView","text","nodeType","isAriaHidden","isDisplayHidden","child","isReady","numberOfSlides","resume","onAutoSlidePlayerClick","addEventListeners","onWindowResize","onTransitionEnd","onPageVisibilityChange","useCapture","transforms","createEvent","initEvent","dispatchPostMessage","dispatchSlideChanged","self","message","namespace","JSON","stringify","viewportWidth","size","oldScale","presentationWidth","presentationHeight","zoom","len","checkResponsiveScrollView","remainingHeight","getRemainingHeight","newHeight","oldHeight","nw","naturalWidth","videoWidth","nh","naturalHeight","videoHeight","es","setPreviousVerticalIndex","getPreviousVerticalIndex","attributeName","isLastVerticalSlide","nextElementSibling","isFirstSlide","isLastSlide","wasPaused","defaultPrevented","stateBefore","indexhBefore","indexvBefore","updateSlides","slideChanged","currentHorizontalSlide","currentVerticalSlides","autoAnimateTransition","stateLoop","j","splice","beforeSlide","random","slidesLength","printMode","loopedForwards","loopedBackwards","reverse","showFragmentsIn","hideFragmentsIn","wasPresent","slideState","distanceX","distanceY","horizontalSlidesLength","verticalSlidesLength","oy","fragmentRoutes","pastCount","mainLoop","getSlide","indexf","fragmentAutoSlide","parentAutoSlide","slideAutoSlide","playbackRate","navigateNext","pauseAutoSlide","resumeAutoSlide","navigateLeft","navigateRight","navigateUp","navigateDown","navigatePrev","parse","method","args","anchor","fullscreenElement","webkitFullscreenElement","API","initialize","initOptions","setViewport","syncSlide","syncFragments","navigateFragment","prevFragment","nextFragment","availableFragments","toggleOverview","toggleScrollView","isOverview","loadSlide","unloadSlide","showPreview","hidePreview","pausedFlag","overviewFlag","totalCount","allFragments","fragmentWeight","getSlidesAttributes","attributes","attribute","getPreviousSlide","getSlidePath","getPlugins","scroll","enqueuedAPICalls","deck"],"mappings":"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","x_google_ignoreList":[2]}
\ No newline at end of file
+{"version":3,"file":"reveal.js","sources":["../js/utils/util.js","../js/utils/device.js","../node_modules/fitty/dist/fitty.module.js","../js/controllers/slidecontent.js","../js/utils/constants.js","../js/controllers/slidenumber.js","../js/controllers/jumptoslide.js","../js/utils/color.js","../js/controllers/backgrounds.js","../js/controllers/autoanimate.js","../js/controllers/scrollview.js","../js/controllers/printview.js","../js/controllers/fragments.js","../js/controllers/overview.js","../js/controllers/keyboard.js","../js/controllers/location.js","../js/controllers/controls.js","../js/controllers/progress.js","../js/controllers/pointer.js","../js/utils/loader.js","../js/controllers/plugins.js","../js/controllers/overlay.js","../js/controllers/touch.js","../js/controllers/focus.js","../js/controllers/notes.js","../js/components/playback.js","../js/config.js","../js/reveal.js","../js/index.js"],"sourcesContent":["/**\n * Extend object a with the properties of object b.\n * If there's a conflict, object b takes precedence.\n *\n * @param {object} a\n * @param {object} b\n */\nexport const extend = ( a, b ) => {\n\n\tfor( let i in b ) {\n\t\ta[ i ] = b[ i ];\n\t}\n\n\treturn a;\n\n}\n\n/**\n * querySelectorAll but returns an Array.\n */\nexport const queryAll = ( el, selector ) => {\n\n\treturn Array.from( el.querySelectorAll( selector ) );\n\n}\n\n/**\n * classList.toggle() with cross browser support\n */\nexport const toggleClass = ( el, className, value ) => {\n\tif( value ) {\n\t\tel.classList.add( className );\n\t}\n\telse {\n\t\tel.classList.remove( className );\n\t}\n}\n\n/**\n * Utility for deserializing a value.\n *\n * @param {*} value\n * @return {*}\n */\nexport const deserialize = ( value ) => {\n\n\tif( typeof value === 'string' ) {\n\t\tif( value === 'null' ) return null;\n\t\telse if( value === 'true' ) return true;\n\t\telse if( value === 'false' ) return false;\n\t\telse if( value.match( /^-?[\\d\\.]+$/ ) ) return parseFloat( value );\n\t}\n\n\treturn value;\n\n}\n\n/**\n * Measures the distance in pixels between point a\n * and point b.\n *\n * @param {object} a point with x/y properties\n * @param {object} b point with x/y properties\n *\n * @return {number}\n */\nexport const distanceBetween = ( a, b ) => {\n\n\tlet dx = a.x - b.x,\n\t\tdy = a.y - b.y;\n\n\treturn Math.sqrt( dx*dx + dy*dy );\n\n}\n\n/**\n * Applies a CSS transform to the target element.\n *\n * @param {HTMLElement} element\n * @param {string} transform\n */\nexport const transformElement = ( element, transform ) => {\n\n\telement.style.transform = transform;\n\n}\n\n/**\n * Element.matches with IE support.\n *\n * @param {HTMLElement} target The element to match\n * @param {String} selector The CSS selector to match\n * the element against\n *\n * @return {Boolean}\n */\nexport const matches = ( target, selector ) => {\n\n\tlet matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;\n\n\treturn !!( matchesMethod && matchesMethod.call( target, selector ) );\n\n}\n\n/**\n * Find the closest parent that matches the given\n * selector.\n *\n * @param {HTMLElement} target The child element\n * @param {String} selector The CSS selector to match\n * the parents against\n *\n * @return {HTMLElement} The matched parent or null\n * if no matching parent was found\n */\nexport const closest = ( target, selector ) => {\n\n\t// Native Element.closest\n\tif( typeof target.closest === 'function' ) {\n\t\treturn target.closest( selector );\n\t}\n\n\t// Polyfill\n\twhile( target ) {\n\t\tif( matches( target, selector ) ) {\n\t\t\treturn target;\n\t\t}\n\n\t\t// Keep searching\n\t\ttarget = target.parentNode;\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Handling the fullscreen functionality via the fullscreen API\n *\n * @see http://fullscreen.spec.whatwg.org/\n * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode\n */\nexport const enterFullscreen = element => {\n\n\telement = element || document.documentElement;\n\n\t// Check which implementation is available\n\tlet requestMethod = element.requestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullscreen ||\n\t\t\t\t\t\telement.webkitRequestFullScreen ||\n\t\t\t\t\t\telement.mozRequestFullScreen ||\n\t\t\t\t\t\telement.msRequestFullscreen;\n\n\tif( requestMethod ) {\n\t\trequestMethod.apply( element );\n\t}\n\n}\n\n/**\n * Creates an HTML element and returns a reference to it.\n * If the element already exists the existing instance will\n * be returned.\n *\n * @param {HTMLElement} container\n * @param {string} tagname\n * @param {string} classname\n * @param {string} innerHTML\n *\n * @return {HTMLElement}\n */\nexport const createSingletonNode = ( container, tagname, classname, innerHTML='' ) => {\n\n\t// Find all nodes matching the description\n\tlet nodes = container.querySelectorAll( '.' + classname );\n\n\t// Check all matches to find one which is a direct child of\n\t// the specified container\n\tfor( let i = 0; i < nodes.length; i++ ) {\n\t\tlet testNode = nodes[i];\n\t\tif( testNode.parentNode === container ) {\n\t\t\treturn testNode;\n\t\t}\n\t}\n\n\t// If no node was found, create it now\n\tlet node = document.createElement( tagname );\n\tnode.className = classname;\n\tnode.innerHTML = innerHTML;\n\tcontainer.appendChild( node );\n\n\treturn node;\n\n}\n\n/**\n * Injects the given CSS styles into the DOM.\n *\n * @param {string} value\n */\nexport const createStyleSheet = ( value ) => {\n\n\tlet tag = document.createElement( 'style' );\n\ttag.type = 'text/css';\n\n\tif( value && value.length > 0 ) {\n\t\tif( tag.styleSheet ) {\n\t\t\ttag.styleSheet.cssText = value;\n\t\t}\n\t\telse {\n\t\t\ttag.appendChild( document.createTextNode( value ) );\n\t\t}\n\t}\n\n\tdocument.head.appendChild( tag );\n\n\treturn tag;\n\n}\n\n/**\n * Returns a key:value hash of all query params.\n */\nexport const getQueryHash = () => {\n\n\tlet query = {};\n\n\tlocation.search.replace( /[A-Z0-9]+?=([\\w\\.%-]*)/gi, a => {\n\t\tquery[ a.split( '=' ).shift() ] = a.split( '=' ).pop();\n\t} );\n\n\t// Basic deserialization\n\tfor( let i in query ) {\n\t\tlet value = query[ i ];\n\n\t\tquery[ i ] = deserialize( unescape( value ) );\n\t}\n\n\t// Do not accept new dependencies via query config to avoid\n\t// the potential of malicious script injection\n\tif( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];\n\n\treturn query;\n\n}\n\n/**\n * Returns the remaining height within the parent of the\n * target element.\n *\n * remaining height = [ configured parent height ] - [ current parent height ]\n *\n * @param {HTMLElement} element\n * @param {number} [height]\n */\nexport const getRemainingHeight = ( element, height = 0 ) => {\n\n\tif( element ) {\n\t\tlet newHeight, oldHeight = element.style.height;\n\n\t\t// Change the .stretch element height to 0 in order find the height of all\n\t\t// the other elements\n\t\telement.style.height = '0px';\n\n\t\t// In Overview mode, the parent (.slide) height is set of 700px.\n\t\t// Restore it temporarily to its natural height.\n\t\telement.parentNode.style.height = 'auto';\n\n\t\tnewHeight = height - element.parentNode.offsetHeight;\n\n\t\t// Restore the old height, just in case\n\t\telement.style.height = oldHeight + 'px';\n\n\t\t// Clear the parent (.slide) height. .removeProperty works in IE9+\n\t\telement.parentNode.style.removeProperty('height');\n\n\t\treturn newHeight;\n\t}\n\n\treturn height;\n\n}\n\nconst fileExtensionToMimeMap = {\n\t'mp4': 'video/mp4',\n\t'm4a': 'video/mp4',\n\t'ogv': 'video/ogg',\n\t'mpeg': 'video/mpeg',\n\t'webm': 'video/webm'\n}\n\n/**\n * Guess the MIME type for common file formats.\n */\nexport const getMimeTypeFromFile = ( filename='' ) => {\n\treturn fileExtensionToMimeMap[filename.split('.').pop()]\n}\n\n/**\n * Encodes a string for RFC3986-compliant URL format.\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#encoding_for_rfc3986\n *\n * @param {string} url\n */\nexport const encodeRFC3986URI = ( url='' ) => {\n\treturn encodeURI(url)\n\t .replace(/%5B/g, \"[\")\n\t .replace(/%5D/g, \"]\")\n\t .replace(\n\t\t/[!'()*]/g,\n\t\t(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`\n\t );\n}","const UA = navigator.userAgent;\n\nexport const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||\n\t\t\t\t\t\t( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS\n\nexport const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );\n\nexport const isAndroid = /android/gi.test( UA );","/**\n * fitty v2.3.7 - Snugly resizes text to fit its parent container\n * Copyright (c) 2023 Rik Schennink
(https://pqina.nl/)\n */\n\nvar e=function(e){if(e){var t=function(e){return[].slice.call(e)},n=0,i=1,r=2,o=3,a=[],l=null,u=\"requestAnimationFrame\"in e?function(){e.cancelAnimationFrame(l),l=e.requestAnimationFrame((function(){return s(a.filter((function(e){return e.dirty&&e.active})))}))}:function(){},c=function(e){return function(){a.forEach((function(t){return t.dirty=e})),u()}},s=function(e){e.filter((function(e){return!e.styleComputed})).forEach((function(e){e.styleComputed=m(e)})),e.filter(y).forEach(v);var t=e.filter(p);t.forEach(d),t.forEach((function(e){v(e),f(e)})),t.forEach(S)},f=function(e){return e.dirty=n},d=function(e){e.availableWidth=e.element.parentNode.clientWidth,e.currentWidth=e.element.scrollWidth,e.previousFontSize=e.currentFontSize,e.currentFontSize=Math.min(Math.max(e.minSize,e.availableWidth/e.currentWidth*e.previousFontSize),e.maxSize),e.whiteSpace=e.multiLine&&e.currentFontSize===e.minSize?\"normal\":\"nowrap\"},p=function(e){return e.dirty!==r||e.dirty===r&&e.element.parentNode.clientWidth!==e.availableWidth},m=function(t){var n=e.getComputedStyle(t.element,null);return t.currentFontSize=parseFloat(n.getPropertyValue(\"font-size\")),t.display=n.getPropertyValue(\"display\"),t.whiteSpace=n.getPropertyValue(\"white-space\"),!0},y=function(e){var t=!1;return!e.preStyleTestCompleted&&(/inline-/.test(e.display)||(t=!0,e.display=\"inline-block\"),\"nowrap\"!==e.whiteSpace&&(t=!0,e.whiteSpace=\"nowrap\"),e.preStyleTestCompleted=!0,t)},v=function(e){e.element.style.whiteSpace=e.whiteSpace,e.element.style.display=e.display,e.element.style.fontSize=e.currentFontSize+\"px\"},S=function(e){e.element.dispatchEvent(new CustomEvent(\"fit\",{detail:{oldValue:e.previousFontSize,newValue:e.currentFontSize,scaleFactor:e.currentFontSize/e.previousFontSize}}))},h=function(e,t){return function(){e.dirty=t,e.active&&u()}},w=function(e){return function(){a=a.filter((function(t){return t.element!==e.element})),e.observeMutations&&e.observer.disconnect(),e.element.style.whiteSpace=e.originalStyle.whiteSpace,e.element.style.display=e.originalStyle.display,e.element.style.fontSize=e.originalStyle.fontSize}},b=function(e){return function(){e.active||(e.active=!0,u())}},z=function(e){return function(){return e.active=!1}},F=function(e){e.observeMutations&&(e.observer=new MutationObserver(h(e,i)),e.observer.observe(e.element,e.observeMutations))},g={minSize:16,maxSize:512,multiLine:!0,observeMutations:\"MutationObserver\"in e&&{subtree:!0,childList:!0,characterData:!0}},W=null,E=function(){e.clearTimeout(W),W=e.setTimeout(c(r),x.observeWindowDelay)},M=[\"resize\",\"orientationchange\"];return Object.defineProperty(x,\"observeWindow\",{set:function(t){var n=\"\".concat(t?\"add\":\"remove\",\"EventListener\");M.forEach((function(t){e[n](t,E)}))}}),x.observeWindow=!0,x.observeWindowDelay=100,x.fitAll=c(o),x}function C(e,t){var n=Object.assign({},g,t),i=e.map((function(e){var t=Object.assign({},n,{element:e,active:!0});return function(e){e.originalStyle={whiteSpace:e.element.style.whiteSpace,display:e.element.style.display,fontSize:e.element.style.fontSize},F(e),e.newbie=!0,e.dirty=!0,a.push(e)}(t),{element:e,fit:h(t,o),unfreeze:b(t),freeze:z(t),unsubscribe:w(t)}}));return u(),i}function x(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return\"string\"==typeof e?C(t(document.querySelectorAll(e)),n):C([e],n)[0]}}(\"undefined\"==typeof window?null:window);export default e;\n","import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'\nimport { isMobile } from '../utils/device.js'\n\nimport fitty from 'fitty';\n\n/**\n * Handles loading, unloading and playback of slide\n * content such as images, videos and iframes.\n */\nexport default class SlideContent {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );\n\n\t}\n\n\t/**\n\t * Should the given element be preloaded?\n\t * Decides based on local element attributes and global config.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tshouldPreload( element ) {\n\n\t\tif( this.Reveal.isScrollView() ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prefer an explicit global preload setting\n\t\tlet preload = this.Reveal.getConfig().preloadIframes;\n\n\t\t// If no global setting is available, fall back on the element's\n\t\t// own preload setting\n\t\tif( typeof preload !== 'boolean' ) {\n\t\t\tpreload = element.hasAttribute( 'data-preload' );\n\t\t}\n\n\t\treturn preload;\n\t}\n\n\t/**\n\t * Called when the given slide is within the configured view\n\t * distance. Shows the slide element and loads any content\n\t * that is set to load lazily (data-src).\n\t *\n\t * @param {HTMLElement} slide Slide to show\n\t */\n\tload( slide, options = {} ) {\n\n\t\t// Show the slide element\n\t\tslide.style.display = this.Reveal.getConfig().display;\n\n\t\t// Media elements with data-src attributes\n\t\tqueryAll( slide, 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ).forEach( element => {\n\t\t\tif( element.tagName !== 'IFRAME' || this.shouldPreload( element ) ) {\n\t\t\t\telement.setAttribute( 'src', element.getAttribute( 'data-src' ) );\n\t\t\t\telement.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\telement.removeAttribute( 'data-src' );\n\t\t\t}\n\t\t} );\n\n\t\t// Media elements with children\n\t\tqueryAll( slide, 'video, audio' ).forEach( media => {\n\t\t\tlet sources = 0;\n\n\t\t\tqueryAll( media, 'source[data-src]' ).forEach( source => {\n\t\t\t\tsource.setAttribute( 'src', source.getAttribute( 'data-src' ) );\n\t\t\t\tsource.removeAttribute( 'data-src' );\n\t\t\t\tsource.setAttribute( 'data-lazy-loaded', '' );\n\t\t\t\tsources += 1;\n\t\t\t} );\n\n\t\t\t// Enable inline video playback in mobile Safari\n\t\t\tif( isMobile && media.tagName === 'VIDEO' ) {\n\t\t\t\tmedia.setAttribute( 'playsinline', '' );\n\t\t\t}\n\n\t\t\t// If we rewrote sources for this video/audio element, we need\n\t\t\t// to manually tell it to load from its new origin\n\t\t\tif( sources > 0 ) {\n\t\t\t\tmedia.load();\n\t\t\t}\n\t\t} );\n\n\n\t\t// Show the corresponding background element\n\t\tlet background = slide.slideBackgroundElement;\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'block';\n\n\t\t\tlet backgroundContent = slide.slideBackgroundContentElement;\n\t\t\tlet backgroundIframe = slide.getAttribute( 'data-background-iframe' );\n\n\t\t\t// If the background contains media, load it\n\t\t\tif( background.hasAttribute( 'data-loaded' ) === false ) {\n\t\t\t\tbackground.setAttribute( 'data-loaded', 'true' );\n\n\t\t\t\tlet backgroundImage = slide.getAttribute( 'data-background-image' ),\n\t\t\t\t\tbackgroundVideo = slide.getAttribute( 'data-background-video' ),\n\t\t\t\t\tbackgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ),\n\t\t\t\t\tbackgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' );\n\n\t\t\t\t// Images\n\t\t\t\tif( backgroundImage ) {\n\t\t\t\t\t// base64\n\t\t\t\t\tif( /^data:/.test( backgroundImage.trim() ) ) {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;\n\t\t\t\t\t}\n\t\t\t\t\t// URL(s)\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {\n\t\t\t\t\t\t\t// Decode URL(s) that are already encoded first\n\t\t\t\t\t\t\tlet decoded = decodeURI(background.trim());\n\t\t\t\t\t\t\treturn `url(${encodeRFC3986URI(decoded)})`;\n\t\t\t\t\t\t}).join( ',' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Videos\n\t\t\t\telse if ( backgroundVideo ) {\n\t\t\t\t\tlet video = document.createElement( 'video' );\n\n\t\t\t\t\tif( backgroundVideoLoop ) {\n\t\t\t\t\t\tvideo.setAttribute( 'loop', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\tif( backgroundVideoMuted || this.Reveal.isSpeakerNotes() ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Enable inline playback in mobile Safari\n\t\t\t\t\t//\n\t\t\t\t\t// Mute is required for video to play when using\n\t\t\t\t\t// swipe gestures to navigate since they don't\n\t\t\t\t\t// count as direct user actions :'(\n\t\t\t\t\tif( isMobile ) {\n\t\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\t\tvideo.setAttribute( 'playsinline', '' );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support comma separated lists of video sources\n\t\t\t\t\tbackgroundVideo.split( ',' ).forEach( source => {\n\t\t\t\t\t\tconst sourceElement = document.createElement( 'source' );\n\t\t\t\t\t\tsourceElement.setAttribute( 'src', source );\n\n\t\t\t\t\t\tlet type = getMimeTypeFromFile( source );\n\t\t\t\t\t\tif( type ) {\n\t\t\t\t\t\t\tsourceElement.setAttribute( 'type', type );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvideo.appendChild( sourceElement );\n\t\t\t\t\t} );\n\n\t\t\t\t\tbackgroundContent.appendChild( video );\n\t\t\t\t}\n\t\t\t\t// Iframes\n\t\t\t\telse if( backgroundIframe && options.excludeIframes !== true ) {\n\t\t\t\t\tlet iframe = document.createElement( 'iframe' );\n\t\t\t\t\tiframe.setAttribute( 'allowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'mozallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'webkitallowfullscreen', '' );\n\t\t\t\t\tiframe.setAttribute( 'allow', 'autoplay' );\n\n\t\t\t\t\tiframe.setAttribute( 'data-src', backgroundIframe );\n\n\t\t\t\t\tiframe.style.width = '100%';\n\t\t\t\t\tiframe.style.height = '100%';\n\t\t\t\t\tiframe.style.maxHeight = '100%';\n\t\t\t\t\tiframe.style.maxWidth = '100%';\n\n\t\t\t\t\tbackgroundContent.appendChild( iframe );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start loading preloadable iframes\n\t\t\tlet backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' );\n\t\t\tif( backgroundIframeElement ) {\n\n\t\t\t\t// Check if this iframe is eligible to be preloaded\n\t\t\t\tif( this.shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) {\n\t\t\t\t\tif( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) {\n\t\t\t\t\t\tbackgroundIframeElement.setAttribute( 'src', backgroundIframe );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.layout( slide );\n\n\t}\n\n\t/**\n\t * Applies JS-dependent layout helpers for the scope.\n\t */\n\tlayout( scopeElement ) {\n\n\t\t// Autosize text with the r-fit-text class based on the\n\t\t// size of its container. This needs to happen after the\n\t\t// slide is visible in order to measure the text.\n\t\tArray.from( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => {\n\t\t\tfitty( element, {\n\t\t\t\tminSize: 24,\n\t\t\t\tmaxSize: this.Reveal.getConfig().height * 0.8,\n\t\t\t\tobserveMutations: false,\n\t\t\t\tobserveWindow: false\n\t\t\t} );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Unloads and hides the given slide. This is called when the\n\t * slide is moved outside of the configured view distance.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tunload( slide ) {\n\n\t\t// Hide the slide element\n\t\tslide.style.display = 'none';\n\n\t\t// Hide the corresponding background element\n\t\tlet background = this.Reveal.getSlideBackground( slide );\n\t\tif( background ) {\n\t\t\tbackground.style.display = 'none';\n\n\t\t\t// Unload any background iframes\n\t\t\tqueryAll( background, 'iframe[src]' ).forEach( element => {\n\t\t\t\telement.removeAttribute( 'src' );\n\t\t\t} );\n\t\t}\n\n\t\t// Reset lazy-loaded media elements with src attributes\n\t\tqueryAll( slide, 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ).forEach( element => {\n\t\t\telement.setAttribute( 'data-src', element.getAttribute( 'src' ) );\n\t\t\telement.removeAttribute( 'src' );\n\t\t} );\n\n\t\t// Reset lazy-loaded media elements with children\n\t\tqueryAll( slide, 'video[data-lazy-loaded] source[src], audio source[src]' ).forEach( source => {\n\t\t\tsource.setAttribute( 'data-src', source.getAttribute( 'src' ) );\n\t\t\tsource.removeAttribute( 'src' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Enforces origin-specific format rules for embedded media.\n\t */\n\tformatEmbeddedContent() {\n\n\t\tlet _appendParamToIframeSource = ( sourceAttribute, sourceURL, param ) => {\n\t\t\tqueryAll( this.Reveal.getSlidesElement(), 'iframe['+ sourceAttribute +'*=\"'+ sourceURL +'\"]' ).forEach( el => {\n\t\t\t\tlet src = el.getAttribute( sourceAttribute );\n\t\t\t\tif( src && src.indexOf( param ) === -1 ) {\n\t\t\t\t\tel.setAttribute( sourceAttribute, src + ( !/\\?/.test( src ) ? '?' : '&' ) + param );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// YouTube frames must include \"?enablejsapi=1\"\n\t\t_appendParamToIframeSource( 'src', 'youtube.com/embed/', 'enablejsapi=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'youtube.com/embed/', 'enablejsapi=1' );\n\n\t\t// Vimeo frames must include \"?api=1\"\n\t\t_appendParamToIframeSource( 'src', 'player.vimeo.com/', 'api=1' );\n\t\t_appendParamToIframeSource( 'data-src', 'player.vimeo.com/', 'api=1' );\n\n\t}\n\n\t/**\n\t * Start playback of any embedded content inside of\n\t * the given element.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstartEmbeddedContent( element ) {\n\n\t\tif( element ) {\n\n\t\t\tconst isSpeakerNotesWindow = this.Reveal.isSpeakerNotes();\n\n\t\t\t// Restart GIFs\n\t\t\tqueryAll( element, 'img[src$=\".gif\"]' ).forEach( el => {\n\t\t\t\t// Setting the same unchanged source like this was confirmed\n\t\t\t\t// to work in Chrome, FF & Safari\n\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'src' ) );\n\t\t\t} );\n\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\tif( autoplay && typeof el.play === 'function' ) {\n\n\t\t\t\t\t// In the speaker view we only auto-play muted media\n\t\t\t\t\tif( isSpeakerNotesWindow && !el.muted ) return;\n\n\t\t\t\t\t// If the media is ready, start playback\n\t\t\t\t\tif( el.readyState > 1 ) {\n\t\t\t\t\t\tthis.startEmbeddedMedia( { target: el } );\n\t\t\t\t\t}\n\t\t\t\t\t// Mobile devices never fire a loaded event so instead\n\t\t\t\t\t// of waiting, we initiate playback\n\t\t\t\t\telse if( isMobile ) {\n\t\t\t\t\t\tlet promise = el.play();\n\n\t\t\t\t\t\t// If autoplay does not work, ensure that the controls are visible so\n\t\t\t\t\t\t// that the viewer can start the media on their own\n\t\t\t\t\t\tif( promise && typeof promise.catch === 'function' && el.controls === false ) {\n\t\t\t\t\t\t\tpromise.catch( () => {\n\t\t\t\t\t\t\t\tel.controls = true;\n\n\t\t\t\t\t\t\t\t// Once the video does start playing, hide the controls again\n\t\t\t\t\t\t\t\tel.addEventListener( 'play', () => {\n\t\t\t\t\t\t\t\t\tel.controls = false;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the media isn't loaded, wait before playing\n\t\t\t\t\telse {\n\t\t\t\t\t\tel.removeEventListener( 'loadeddata', this.startEmbeddedMedia ); // remove first to avoid dupes\n\t\t\t\t\t\tel.addEventListener( 'loadeddata', this.startEmbeddedMedia );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Don't play iframe content in the speaker view since we can't\n\t\t\t// guarantee that it's muted\n\t\t\tif( !isSpeakerNotesWindow ) {\n\n\t\t\t\t// Normal iframes\n\t\t\t\tqueryAll( element, 'iframe[src]' ).forEach( el => {\n\t\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.startEmbeddedIframe( { target: el } );\n\t\t\t\t} );\n\n\t\t\t\t// Lazy loading iframes\n\t\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\t\tif( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {\n\t\t\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe ); // remove first to avoid dupes\n\t\t\t\t\t\tel.addEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t\t\t\tel.setAttribute( 'src', el.getAttribute( 'data-src' ) );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Starts playing an embedded video/audio element after\n\t * it has finished loading.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedMedia( event ) {\n\n\t\tlet isAttachedToDOM = !!closest( event.target, 'html' ),\n\t\t\tisVisible \t\t= !!closest( event.target, '.present' );\n\n\t\tif( isAttachedToDOM && isVisible ) {\n\t\t\t// Don't restart if media is already playing\n\t\t\tif( event.target.paused || event.target.ended ) {\n\t\t\t\tevent.target.currentTime = 0;\n\t\t\t\tevent.target.play();\n\t\t\t}\n\t\t}\n\n\t\tevent.target.removeEventListener( 'loadeddata', this.startEmbeddedMedia );\n\n\t}\n\n\t/**\n\t * \"Starts\" the content of an embedded iframe using the\n\t * postMessage API.\n\t *\n\t * @param {object} event\n\t */\n\tstartEmbeddedIframe( event ) {\n\n\t\tlet iframe = event.target;\n\n\t\tif( iframe && iframe.contentWindow ) {\n\n\t\t\tlet isAttachedToDOM = !!closest( event.target, 'html' ),\n\t\t\t\tisVisible \t\t= !!closest( event.target, '.present' );\n\n\t\t\tif( isAttachedToDOM && isVisible ) {\n\n\t\t\t\t// Prefer an explicit global autoplay setting\n\t\t\t\tlet autoplay = this.Reveal.getConfig().autoPlayMedia;\n\n\t\t\t\t// If no global setting is available, fall back on the element's\n\t\t\t\t// own autoplay setting\n\t\t\t\tif( typeof autoplay !== 'boolean' ) {\n\t\t\t\t\tautoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );\n\t\t\t\t}\n\n\t\t\t\t// YouTube postMessage API\n\t\t\t\tif( /youtube\\.com\\/embed\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"playVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Vimeo postMessage API\n\t\t\t\telse if( /player\\.vimeo\\.com\\//.test( iframe.getAttribute( 'src' ) ) && autoplay ) {\n\t\t\t\t\tiframe.contentWindow.postMessage( '{\"method\":\"play\"}', '*' );\n\t\t\t\t}\n\t\t\t\t// Generic postMessage API\n\t\t\t\telse {\n\t\t\t\t\tiframe.contentWindow.postMessage( 'slide:start', '*' );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Stop playback of any embedded content inside of\n\t * the targeted slide.\n\t *\n\t * @param {HTMLElement} element\n\t */\n\tstopEmbeddedContent( element, options = {} ) {\n\n\t\toptions = extend( {\n\t\t\t// Defaults\n\t\t\tunloadIframes: true\n\t\t}, options );\n\n\t\tif( element && element.parentNode ) {\n\t\t\t// HTML5 media elements\n\t\t\tqueryAll( element, 'video, audio' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {\n\t\t\t\t\tel.setAttribute('data-paused-by-reveal', '');\n\t\t\t\t\tel.pause();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Generic postMessage API for non-lazy loaded iframes\n\t\t\tqueryAll( element, 'iframe' ).forEach( el => {\n\t\t\t\tif( el.contentWindow ) el.contentWindow.postMessage( 'slide:stop', '*' );\n\t\t\t\tel.removeEventListener( 'load', this.startEmbeddedIframe );\n\t\t\t});\n\n\t\t\t// YouTube postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"youtube.com/embed/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"event\":\"command\",\"func\":\"pauseVideo\",\"args\":\"\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Vimeo postMessage API\n\t\t\tqueryAll( element, 'iframe[src*=\"player.vimeo.com/\"]' ).forEach( el => {\n\t\t\t\tif( !el.hasAttribute( 'data-ignore' ) && el.contentWindow && typeof el.contentWindow.postMessage === 'function' ) {\n\t\t\t\t\tel.contentWindow.postMessage( '{\"method\":\"pause\"}', '*' );\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( options.unloadIframes === true ) {\n\t\t\t\t// Unload lazy-loaded iframes\n\t\t\t\tqueryAll( element, 'iframe[data-src]' ).forEach( el => {\n\t\t\t\t\t// Only removing the src doesn't actually unload the frame\n\t\t\t\t\t// in all browsers (Firefox) so we set it to blank first\n\t\t\t\t\tel.setAttribute( 'src', 'about:blank' );\n\t\t\t\t\tel.removeAttribute( 'src' );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t}\n\n}\n","\nexport const SLIDES_SELECTOR = '.slides section';\nexport const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';\nexport const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';\nexport const HORIZONTAL_BACKGROUNDS_SELECTOR = '.backgrounds>.slide-background';\n\n// Methods that may not be invoked via the postMessage API\nexport const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/;\n\n// Regex for retrieving the fragment style from a class attribute\nexport const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;\n\n// Slide number formats\nexport const SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL = 'h.v';\nexport const SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL = 'h/v';\nexport const SLIDE_NUMBER_FORMAT_CURRENT = 'c';\nexport const SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL = 'c/t';","import {\n\tSLIDE_NUMBER_FORMAT_CURRENT,\n\tSLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL,\n\tSLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL,\n\tSLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL\n} from \"../utils/constants\";\n\n/**\n * Handles the display of reveal.js' optional slide number.\n */\nexport default class SlideNumber {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'slide-number';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tlet slideNumberDisplay = 'none';\n\t\tif( config.slideNumber && !this.Reveal.isPrintView() ) {\n\t\t\tif( config.showSlideNumber === 'all' ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t\telse if( config.showSlideNumber === 'speaker' && this.Reveal.isSpeakerNotes() ) {\n\t\t\t\tslideNumberDisplay = 'block';\n\t\t\t}\n\t\t}\n\n\t\tthis.element.style.display = slideNumberDisplay;\n\n\t}\n\n\t/**\n\t * Updates the slide number to match the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update slide number if enabled\n\t\tif( this.Reveal.getConfig().slideNumber && this.element ) {\n\t\t\tthis.element.innerHTML = this.getSlideNumber();\n\t\t}\n\n\t}\n\n\t/**\n\t * Returns the HTML string corresponding to the current slide\n\t * number, including formatting.\n\t */\n\tgetSlideNumber( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet value;\n\t\tlet format = SLIDE_NUMBER_FORMAT_HORIZONTAL_DOT_VERTICAL;\n\n\t\tif ( typeof config.slideNumber === 'function' ) {\n\t\t\tvalue = config.slideNumber( slide );\n\t\t} else {\n\t\t\t// Check if a custom number format is available\n\t\t\tif( typeof config.slideNumber === 'string' ) {\n\t\t\t\tformat = config.slideNumber;\n\t\t\t}\n\n\t\t\t// If there are ONLY vertical slides in this deck, always use\n\t\t\t// a flattened slide number\n\t\t\tif( !/c/.test( format ) && this.Reveal.getHorizontalSlides().length === 1 ) {\n\t\t\t\tformat = SLIDE_NUMBER_FORMAT_CURRENT;\n\t\t\t}\n\n\t\t\t// Offset the current slide number by 1 to make it 1-indexed\n\t\t\tlet horizontalOffset = slide && slide.dataset.visibility === 'uncounted' ? 0 : 1;\n\n\t\t\tvalue = [];\n\t\t\tswitch( format ) {\n\t\t\t\tcase SLIDE_NUMBER_FORMAT_CURRENT:\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset );\n\t\t\t\t\tbreak;\n\t\t\t\tcase SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL:\n\t\t\t\t\tvalue.push( this.Reveal.getSlidePastCount( slide ) + horizontalOffset, '/', this.Reveal.getTotalSlides() );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tlet indices = this.Reveal.getIndices( slide );\n\t\t\t\t\tvalue.push( indices.h + horizontalOffset );\n\t\t\t\t\tlet sep = format === SLIDE_NUMBER_FORMAT_HORIZONTAL_SLASH_VERTICAL ? '/' : '.';\n\t\t\t\t\tif( this.Reveal.isVerticalSlide( slide ) ) value.push( sep, indices.v + 1 );\n\t\t\t}\n\t\t}\n\n\t\tlet url = '#' + this.Reveal.location.getHash( slide );\n\t\treturn this.formatNumber( value[0], value[1], value[2], url );\n\n\t}\n\n\t/**\n\t * Applies HTML formatting to a slide number before it's\n\t * written to the DOM.\n\t *\n\t * @param {number} a Current slide\n\t * @param {string} delimiter Character to separate slide numbers\n\t * @param {(number|*)} b Total slides\n\t * @param {HTMLElement} [url='#'+locationHash()] The url to link to\n\t * @return {string} HTML string fragment\n\t */\n\tformatNumber( a, delimiter, b, url = '#' + this.Reveal.location.getHash() ) {\n\n\t\tif( typeof b === 'number' && !isNaN( b ) ) {\n\t\t\treturn `\n\t\t\t\t\t${a} \n\t\t\t\t\t${delimiter} \n\t\t\t\t\t${b} \n\t\t\t\t\t `;\n\t\t}\n\t\telse {\n\t\t\treturn `\n\t\t\t\t\t${a} \n\t\t\t\t\t `;\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}","import {\n\tSLIDE_NUMBER_FORMAT_CURRENT,\n\tSLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL\n} from \"../utils/constants\";\n\n/**\n * Makes it possible to jump to a slide by entering its\n * slide number or id.\n */\nexport default class JumpToSlide {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onInput = this.onInput.bind( this );\n\t\tthis.onBlur = this.onBlur.bind( this );\n\t\tthis.onKeyDown = this.onKeyDown.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'jump-to-slide';\n\n this.jumpInput = document.createElement( 'input' );\n this.jumpInput.type = 'text';\n this.jumpInput.className = 'jump-to-slide-input';\n this.jumpInput.placeholder = 'Jump to slide';\n\t\tthis.jumpInput.addEventListener( 'input', this.onInput );\n\t\tthis.jumpInput.addEventListener( 'keydown', this.onKeyDown );\n\t\tthis.jumpInput.addEventListener( 'blur', this.onBlur );\n\n this.element.appendChild( this.jumpInput );\n\n\t}\n\n\tshow() {\n\n\t\tthis.indicesOnShow = this.Reveal.getIndices();\n\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\t\tthis.jumpInput.focus();\n\n\t}\n\n\thide() {\n\n\t\tif( this.isVisible() ) {\n\t\t\tthis.element.remove();\n\t\t\tthis.jumpInput.value = '';\n\n\t\t\tclearTimeout( this.jumpTimeout );\n\t\t\tdelete this.jumpTimeout;\n\t\t}\n\n\t}\n\n\tisVisible() {\n\n\t\treturn !!this.element.parentNode;\n\n\t}\n\n\t/**\n\t * Parses the current input and jumps to the given slide.\n\t */\n\tjump() {\n\n\t\tclearTimeout( this.jumpTimeout );\n\t\tdelete this.jumpTimeout;\n\n\t\tlet query = this.jumpInput.value.trim( '' );\n\t\tlet indices;\n\n\t\t// When slide numbers are formatted to be a single linear number\n\t\t// (instead of showing a separate horizontal/vertical index) we\n\t\t// use the same format for slide jumps\n\t\tif( /^\\d+$/.test( query ) ) {\n\t\t\tconst slideNumberFormat = this.Reveal.getConfig().slideNumber;\n\t\t\tif( slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT || slideNumberFormat === SLIDE_NUMBER_FORMAT_CURRENT_SLASH_TOTAL ) {\n\t\t\t\tconst slide = this.Reveal.getSlides()[ parseInt( query, 10 ) - 1 ];\n\t\t\t\tif( slide ) {\n\t\t\t\t\tindices = this.Reveal.getIndices( slide );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( !indices ) {\n\t\t\t// If the query uses \"horizontal.vertical\" format, convert to\n\t\t\t// \"horizontal/vertical\" so that our URL parser can understand\n\t\t\tif( /^\\d+\\.\\d+$/.test( query ) ) {\n\t\t\t\tquery = query.replace( '.', '/' );\n\t\t\t}\n\n\t\t\tindices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );\n\t\t}\n\n\t\t// Still no valid index? Fall back on a text search\n\t\tif( !indices && /\\S+/i.test( query ) && query.length > 1 ) {\n\t\t\tindices = this.search( query );\n\t\t}\n\n\t\tif( indices && query !== '' ) {\n\t\t\tthis.Reveal.slide( indices.h, indices.v, indices.f );\n\t\t\treturn true;\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );\n\t\t\treturn false;\n\t\t}\n\n\t}\n\n\tjumpAfter( delay ) {\n\n\t\tclearTimeout( this.jumpTimeout );\n\t\tthis.jumpTimeout = setTimeout( () => this.jump(), delay );\n\n\t}\n\n\t/**\n\t * A lofi search that looks for the given query in all\n\t * of our slides and returns the first match.\n\t */\n\tsearch( query ) {\n\n\t\tconst regex = new RegExp( '\\\\b' + query.trim() + '\\\\b', 'i' );\n\n\t\tconst slide = this.Reveal.getSlides().find( ( slide ) => {\n\t\t\treturn regex.test( slide.innerText );\n\t\t} );\n\n\t\tif( slide ) {\n\t\t\treturn this.Reveal.getIndices( slide );\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t}\n\n\t/**\n\t * Reverts back to the slide we were on when jump to slide was\n\t * invoked.\n\t */\n\tcancel() {\n\n\t\tthis.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );\n\t\tthis.hide();\n\n\t}\n\n\tconfirm() {\n\n\t\tthis.jump();\n\t\tthis.hide();\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.jumpInput.removeEventListener( 'input', this.onInput );\n\t\tthis.jumpInput.removeEventListener( 'keydown', this.onKeyDown );\n\t\tthis.jumpInput.removeEventListener( 'blur', this.onBlur );\n\n\t\tthis.element.remove();\n\n\t}\n\n\tonKeyDown( event ) {\n\n\t\tif( event.keyCode === 13 ) {\n\t\t\tthis.confirm();\n\t\t}\n\t\telse if( event.keyCode === 27 ) {\n\t\t\tthis.cancel();\n\n\t\t\tevent.stopImmediatePropagation();\n\t\t}\n\n\t}\n\n\tonInput( event ) {\n\n\t\tthis.jumpAfter( 200 );\n\n\t}\n\n\tonBlur() {\n\n\t\tsetTimeout( () => this.hide(), 1 );\n\n\t}\n\n}","/**\n * Converts various color input formats to an {r:0,g:0,b:0} object.\n *\n * @param {string} color The string representation of a color\n * @example\n * colorToRgb('#000');\n * @example\n * colorToRgb('#000000');\n * @example\n * colorToRgb('rgb(0,0,0)');\n * @example\n * colorToRgb('rgba(0,0,0)');\n *\n * @return {{r: number, g: number, b: number, [a]: number}|null}\n */\nexport const colorToRgb = ( color ) => {\n\n\tlet hex3 = color.match( /^#([0-9a-f]{3})$/i );\n\tif( hex3 && hex3[1] ) {\n\t\thex3 = hex3[1];\n\t\treturn {\n\t\t\tr: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,\n\t\t\tg: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,\n\t\t\tb: parseInt( hex3.charAt( 2 ), 16 ) * 0x11\n\t\t};\n\t}\n\n\tlet hex6 = color.match( /^#([0-9a-f]{6})$/i );\n\tif( hex6 && hex6[1] ) {\n\t\thex6 = hex6[1];\n\t\treturn {\n\t\t\tr: parseInt( hex6.slice( 0, 2 ), 16 ),\n\t\t\tg: parseInt( hex6.slice( 2, 4 ), 16 ),\n\t\t\tb: parseInt( hex6.slice( 4, 6 ), 16 )\n\t\t};\n\t}\n\n\tlet rgb = color.match( /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i );\n\tif( rgb ) {\n\t\treturn {\n\t\t\tr: parseInt( rgb[1], 10 ),\n\t\t\tg: parseInt( rgb[2], 10 ),\n\t\t\tb: parseInt( rgb[3], 10 )\n\t\t};\n\t}\n\n\tlet rgba = color.match( /^rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([\\d]+|[\\d]*.[\\d]+)\\s*\\)$/i );\n\tif( rgba ) {\n\t\treturn {\n\t\t\tr: parseInt( rgba[1], 10 ),\n\t\t\tg: parseInt( rgba[2], 10 ),\n\t\t\tb: parseInt( rgba[3], 10 ),\n\t\t\ta: parseFloat( rgba[4] )\n\t\t};\n\t}\n\n\treturn null;\n\n}\n\n/**\n * Calculates brightness on a scale of 0-255.\n *\n * @param {string} color See colorToRgb for supported formats.\n * @see {@link colorToRgb}\n */\nexport const colorBrightness = ( color ) => {\n\n\tif( typeof color === 'string' ) color = colorToRgb( color );\n\n\tif( color ) {\n\t\treturn ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;\n\t}\n\n\treturn null;\n\n}","import { queryAll } from '../utils/util.js'\nimport { colorToRgb, colorBrightness } from '../utils/color.js'\n\n/**\n * Creates and updates slide backgrounds.\n */\nexport default class Backgrounds {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'backgrounds';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Creates the slide background elements and appends them\n\t * to the background container. One element is created per\n\t * slide no matter if the given slide has visible background.\n\t */\n\tcreate() {\n\n\t\t// Clear prior backgrounds\n\t\tthis.element.innerHTML = '';\n\t\tthis.element.classList.add( 'no-transition' );\n\n\t\t// Iterate over all horizontal slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( slideh => {\n\n\t\t\tlet backgroundStack = this.createBackground( slideh, this.element );\n\n\t\t\t// Iterate over all vertical slides\n\t\t\tqueryAll( slideh, 'section' ).forEach( slidev => {\n\n\t\t\t\tthis.createBackground( slidev, backgroundStack );\n\n\t\t\t\tbackgroundStack.classList.add( 'stack' );\n\n\t\t\t} );\n\n\t\t} );\n\n\t\t// Add parallax background if specified\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tthis.element.style.backgroundImage = 'url(\"' + this.Reveal.getConfig().parallaxBackgroundImage + '\")';\n\t\t\tthis.element.style.backgroundSize = this.Reveal.getConfig().parallaxBackgroundSize;\n\t\t\tthis.element.style.backgroundRepeat = this.Reveal.getConfig().parallaxBackgroundRepeat;\n\t\t\tthis.element.style.backgroundPosition = this.Reveal.getConfig().parallaxBackgroundPosition;\n\n\t\t\t// Make sure the below properties are set on the element - these properties are\n\t\t\t// needed for proper transitions to be set on the element via CSS. To remove\n\t\t\t// annoying background slide-in effect when the presentation starts, apply\n\t\t\t// these properties after short time delay\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.add( 'has-parallax-background' );\n\t\t\t}, 1 );\n\n\t\t}\n\t\telse {\n\n\t\t\tthis.element.style.backgroundImage = '';\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'has-parallax-background' );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a background for the given slide.\n\t *\n\t * @param {HTMLElement} slide\n\t * @param {HTMLElement} container The element that the background\n\t * should be appended to\n\t * @return {HTMLElement} New background div\n\t */\n\tcreateBackground( slide, container ) {\n\n\t\t// Main slide background element\n\t\tlet element = document.createElement( 'div' );\n\t\telement.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );\n\n\t\t// Inner background element that wraps images/videos/iframes\n\t\tlet contentElement = document.createElement( 'div' );\n\t\tcontentElement.className = 'slide-background-content';\n\n\t\telement.appendChild( contentElement );\n\t\tcontainer.appendChild( element );\n\n\t\tslide.slideBackgroundElement = element;\n\t\tslide.slideBackgroundContentElement = contentElement;\n\n\t\t// Syncs the background to reflect all current background settings\n\t\tthis.sync( slide );\n\n\t\treturn element;\n\n\t}\n\n\t/**\n\t * Renders all of the visual properties of a slide background\n\t * based on the various background attributes.\n\t *\n\t * @param {HTMLElement} slide\n\t */\n\tsync( slide ) {\n\n\t\tconst element = slide.slideBackgroundElement,\n\t\t\tcontentElement = slide.slideBackgroundContentElement;\n\n\t\tconst data = {\n\t\t\tbackground: slide.getAttribute( 'data-background' ),\n\t\t\tbackgroundSize: slide.getAttribute( 'data-background-size' ),\n\t\t\tbackgroundImage: slide.getAttribute( 'data-background-image' ),\n\t\t\tbackgroundVideo: slide.getAttribute( 'data-background-video' ),\n\t\t\tbackgroundIframe: slide.getAttribute( 'data-background-iframe' ),\n\t\t\tbackgroundColor: slide.getAttribute( 'data-background-color' ),\n\t\t\tbackgroundGradient: slide.getAttribute( 'data-background-gradient' ),\n\t\t\tbackgroundRepeat: slide.getAttribute( 'data-background-repeat' ),\n\t\t\tbackgroundPosition: slide.getAttribute( 'data-background-position' ),\n\t\t\tbackgroundTransition: slide.getAttribute( 'data-background-transition' ),\n\t\t\tbackgroundOpacity: slide.getAttribute( 'data-background-opacity' ),\n\t\t};\n\n\t\tconst dataPreload = slide.hasAttribute( 'data-preload' );\n\n\t\t// Reset the prior background state in case this is not the\n\t\t// initial sync\n\t\tslide.classList.remove( 'has-dark-background' );\n\t\tslide.classList.remove( 'has-light-background' );\n\n\t\telement.removeAttribute( 'data-loaded' );\n\t\telement.removeAttribute( 'data-background-hash' );\n\t\telement.removeAttribute( 'data-background-size' );\n\t\telement.removeAttribute( 'data-background-transition' );\n\t\telement.style.backgroundColor = '';\n\n\t\tcontentElement.style.backgroundSize = '';\n\t\tcontentElement.style.backgroundRepeat = '';\n\t\tcontentElement.style.backgroundPosition = '';\n\t\tcontentElement.style.backgroundImage = '';\n\t\tcontentElement.style.opacity = '';\n\t\tcontentElement.innerHTML = '';\n\n\t\tif( data.background ) {\n\t\t\t// Auto-wrap image urls in url(...)\n\t\t\tif( /^(http|file|\\/\\/)/gi.test( data.background ) || /\\.(svg|png|jpg|jpeg|gif|bmp|webp)([?#\\s]|$)/gi.test( data.background ) ) {\n\t\t\t\tslide.setAttribute( 'data-background-image', data.background );\n\t\t\t}\n\t\t\telse {\n\t\t\t\telement.style.background = data.background;\n\t\t\t}\n\t\t}\n\n\t\t// Create a hash for this combination of background settings.\n\t\t// This is used to determine when two slide backgrounds are\n\t\t// the same.\n\t\tif( data.background || data.backgroundColor || data.backgroundGradient || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {\n\t\t\telement.setAttribute( 'data-background-hash', data.background +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundSize +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundImage +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundVideo +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundIframe +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundColor +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundGradient +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundRepeat +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundPosition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundTransition +\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.backgroundOpacity );\n\t\t}\n\n\t\t// Additional and optional background properties\n\t\tif( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );\n\t\tif( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;\n\t\tif( data.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;\n\t\tif( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );\n\n\t\tif( dataPreload ) element.setAttribute( 'data-preload', '' );\n\n\t\t// Background image options are set on the content wrapper\n\t\tif( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;\n\t\tif( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;\n\t\tif( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;\n\t\tif( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;\n\n\t\tconst contrastClass = this.getContrastClass( slide );\n\n\t\tif( typeof contrastClass === 'string' ) {\n\t\t\tslide.classList.add( contrastClass );\n\t\t}\n\n\t}\n\n\t/**\n\t * Returns a class name that can be applied to a slide to indicate\n\t * if it has a light or dark background.\n\t *\n\t * @param {*} slide\n\t *\n\t * @returns {string|null}\n\t */\n\tgetContrastClass( slide ) {\n\n\t\tconst element = slide.slideBackgroundElement;\n\n\t\t// If this slide has a background color, we add a class that\n\t\t// signals if it is light or dark. If the slide has no background\n\t\t// color, no class will be added\n\t\tlet contrastColor = slide.getAttribute( 'data-background-color' );\n\n\t\t// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background\n\t\tif( !contrastColor || !colorToRgb( contrastColor ) ) {\n\t\t\tlet computedBackgroundStyle = window.getComputedStyle( element );\n\t\t\tif( computedBackgroundStyle && computedBackgroundStyle.backgroundColor ) {\n\t\t\t\tcontrastColor = computedBackgroundStyle.backgroundColor;\n\t\t\t}\n\t\t}\n\n\t\tif( contrastColor ) {\n\t\t\tconst rgb = colorToRgb( contrastColor );\n\n\t\t\t// Ignore fully transparent backgrounds. Some browsers return\n\t\t\t// rgba(0,0,0,0) when reading the computed background color of\n\t\t\t// an element with no background\n\t\t\tif( rgb && rgb.a !== 0 ) {\n\t\t\t\tif( colorBrightness( contrastColor ) < 128 ) {\n\t\t\t\t\treturn 'has-dark-background';\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn 'has-light-background';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t/**\n\t * Bubble the 'has-light-background'/'has-dark-background' classes.\n\t */\n\tbubbleSlideContrastClassToElement( slide, target ) {\n\n\t\t[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {\n\t\t\tif( slide.classList.contains( classToBubble ) ) {\n\t\t\t\ttarget.classList.add( classToBubble );\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttarget.classList.remove( classToBubble );\n\t\t\t}\n\t\t}, this );\n\n\t}\n\n\t/**\n\t * Updates the background elements to reflect the current\n\t * slide.\n\t *\n\t * @param {boolean} includeAll If true, the backgrounds of\n\t * all vertical slides (not just the present) will be updated.\n\t */\n\tupdate( includeAll = false ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tlet currentBackground = null;\n\n\t\t// Reverse past/future classes when in RTL mode\n\t\tlet horizontalPast = config.rtl ? 'future' : 'past',\n\t\t\thorizontalFuture = config.rtl ? 'past' : 'future';\n\n\t\t// Update the classes of all backgrounds to match the\n\t\t// states of their slides (past/present/future)\n\t\tArray.from( this.element.childNodes ).forEach( ( backgroundh, h ) => {\n\n\t\t\tbackgroundh.classList.remove( 'past', 'present', 'future' );\n\n\t\t\tif( h < indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalPast );\n\t\t\t}\n\t\t\telse if ( h > indices.h ) {\n\t\t\t\tbackgroundh.classList.add( horizontalFuture );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundh.classList.add( 'present' );\n\n\t\t\t\t// Store a reference to the current background element\n\t\t\t\tcurrentBackground = backgroundh;\n\t\t\t}\n\n\t\t\tif( includeAll || h === indices.h ) {\n\t\t\t\tqueryAll( backgroundh, '.slide-background' ).forEach( ( backgroundv, v ) => {\n\n\t\t\t\t\tbackgroundv.classList.remove( 'past', 'present', 'future' );\n\n\t\t\t\t\tconst indexv = typeof indices.v === 'number' ? indices.v : 0;\n\n\t\t\t\t\tif( v < indexv ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'past' );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( v > indexv ) {\n\t\t\t\t\t\tbackgroundv.classList.add( 'future' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbackgroundv.classList.add( 'present' );\n\n\t\t\t\t\t\t// Only if this is the present horizontal and vertical slide\n\t\t\t\t\t\tif( h === indices.h ) currentBackground = backgroundv;\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\t\t\t}\n\n\t\t} );\n\n\t\t// The previous background may refer to a DOM element that has\n\t\t// been removed after a presentation is synced & bgs are recreated\n\t\tif( this.previousBackground && !this.previousBackground.closest( 'body' ) ) {\n\t\t\tthis.previousBackground = null;\n\t\t}\n\n\t\tif( currentBackground && this.previousBackground ) {\n\n\t\t\t// Don't transition between identical backgrounds. This\n\t\t\t// prevents unwanted flicker.\n\t\t\tlet previousBackgroundHash = this.previousBackground.getAttribute( 'data-background-hash' );\n\t\t\tlet currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );\n\n\t\t\tif( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== this.previousBackground ) {\n\t\t\t\tthis.element.classList.add( 'no-transition' );\n\n\t\t\t\t// If multiple slides have the same background video, carry\n\t\t\t\t// the element forward so that it plays continuously\n\t\t\t\t// across multiple slides\n\t\t\t\tconst currentVideo = currentBackground.querySelector( 'video' );\n\t\t\t\tconst previousVideo = this.previousBackground.querySelector( 'video' );\n\n\t\t\t\tif( currentVideo && previousVideo ) {\n\n\t\t\t\t\tconst currentVideoParent = currentVideo.parentNode;\n\t\t\t\t\tconst previousVideoParent = previousVideo.parentNode;\n\n\t\t\t\t\t// Swap the two videos\n\t\t\t\t\tpreviousVideoParent.appendChild( currentVideo );\n\t\t\t\t\tcurrentVideoParent.appendChild( previousVideo );\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tconst backgroundChanged = currentBackground !== this.previousBackground;\n\n\t\t// Stop content inside of previous backgrounds\n\t\tif( backgroundChanged && this.previousBackground ) {\n\n\t\t\tthis.Reveal.slideContent.stopEmbeddedContent( this.previousBackground, { unloadIframes: !this.Reveal.slideContent.shouldPreload( this.previousBackground ) } );\n\n\t\t}\n\n\t\t// Start content in the current background\n\t\tif( backgroundChanged && currentBackground ) {\n\n\t\t\tthis.Reveal.slideContent.startEmbeddedContent( currentBackground );\n\n\t\t\tlet currentBackgroundContent = currentBackground.querySelector( '.slide-background-content' );\n\t\t\tif( currentBackgroundContent ) {\n\n\t\t\t\tlet backgroundImageURL = currentBackgroundContent.style.backgroundImage || '';\n\n\t\t\t\t// Restart GIFs (doesn't work in Firefox)\n\t\t\t\tif( /\\.gif/i.test( backgroundImageURL ) ) {\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = '';\n\t\t\t\t\twindow.getComputedStyle( currentBackgroundContent ).opacity;\n\t\t\t\t\tcurrentBackgroundContent.style.backgroundImage = backgroundImageURL;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.previousBackground = currentBackground;\n\n\t\t}\n\n\t\t// If there's a background brightness flag for this slide,\n\t\t// bubble it to the .reveal container\n\t\tif( currentSlide ) {\n\t\t\tthis.bubbleSlideContrastClassToElement( currentSlide, this.Reveal.getRevealElement() );\n\t\t}\n\n\t\t// Allow the first background to apply without transition\n\t\tsetTimeout( () => {\n\t\t\tthis.element.classList.remove( 'no-transition' );\n\t\t}, 10 );\n\n\t}\n\n\t/**\n\t * Updates the position of the parallax background based\n\t * on the current slide index.\n\t */\n\tupdateParallax() {\n\n\t\tlet indices = this.Reveal.getIndices();\n\n\t\tif( this.Reveal.getConfig().parallaxBackgroundImage ) {\n\n\t\t\tlet horizontalSlides = this.Reveal.getHorizontalSlides(),\n\t\t\t\tverticalSlides = this.Reveal.getVerticalSlides();\n\n\t\t\tlet backgroundSize = this.element.style.backgroundSize.split( ' ' ),\n\t\t\t\tbackgroundWidth, backgroundHeight;\n\n\t\t\tif( backgroundSize.length === 1 ) {\n\t\t\t\tbackgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbackgroundWidth = parseInt( backgroundSize[0], 10 );\n\t\t\t\tbackgroundHeight = parseInt( backgroundSize[1], 10 );\n\t\t\t}\n\n\t\t\tlet slideWidth = this.element.offsetWidth,\n\t\t\t\thorizontalSlideCount = horizontalSlides.length,\n\t\t\t\thorizontalOffsetMultiplier,\n\t\t\t\thorizontalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundHorizontal === 'number' ) {\n\t\t\t\thorizontalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundHorizontal;\n\t\t\t}\n\t\t\telse {\n\t\t\t\thorizontalOffsetMultiplier = horizontalSlideCount > 1 ? ( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) : 0;\n\t\t\t}\n\n\t\t\thorizontalOffset = horizontalOffsetMultiplier * indices.h * -1;\n\n\t\t\tlet slideHeight = this.element.offsetHeight,\n\t\t\t\tverticalSlideCount = verticalSlides.length,\n\t\t\t\tverticalOffsetMultiplier,\n\t\t\t\tverticalOffset;\n\n\t\t\tif( typeof this.Reveal.getConfig().parallaxBackgroundVertical === 'number' ) {\n\t\t\t\tverticalOffsetMultiplier = this.Reveal.getConfig().parallaxBackgroundVertical;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tverticalOffsetMultiplier = ( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 );\n\t\t\t}\n\n\t\t\tverticalOffset = verticalSlideCount > 0 ? verticalOffsetMultiplier * indices.v : 0;\n\n\t\t\tthis.element.style.backgroundPosition = horizontalOffset + 'px ' + -verticalOffset + 'px';\n\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}\n","import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'\nimport { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'\n\n// Counter used to generate unique IDs for auto-animated elements\nlet autoAnimateCounter = 0;\n\n/**\n * Automatically animates matching elements across\n * slides with the [data-auto-animate] attribute.\n */\nexport default class AutoAnimate {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Runs an auto-animation between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t */\n\trun( fromSlide, toSlide ) {\n\n\t\t// Clean up after prior animations\n\t\tthis.reset();\n\n\t\tlet allSlides = this.Reveal.getSlides();\n\t\tlet toSlideIndex = allSlides.indexOf( toSlide );\n\t\tlet fromSlideIndex = allSlides.indexOf( fromSlide );\n\n\t\t// Ensure that;\n\t\t// 1. Both slides exist.\n\t\t// 2. Both slides are auto-animate targets with the same\n\t\t// data-auto-animate-id value (including null if absent on both).\n\t\t// 3. data-auto-animate-restart isn't set on the physically latter\n\t\t// slide (independent of slide direction).\n\t\tif( fromSlide && toSlide && fromSlide.hasAttribute( 'data-auto-animate' ) && toSlide.hasAttribute( 'data-auto-animate' )\n\t\t\t\t&& fromSlide.getAttribute( 'data-auto-animate-id' ) === toSlide.getAttribute( 'data-auto-animate-id' ) \n\t\t\t\t&& !( toSlideIndex > fromSlideIndex ? toSlide : fromSlide ).hasAttribute( 'data-auto-animate-restart' ) ) {\n\n\t\t\t// Create a new auto-animate sheet\n\t\t\tthis.autoAnimateStyleSheet = this.autoAnimateStyleSheet || createStyleSheet();\n\n\t\t\tlet animationOptions = this.getAutoAnimateOptions( toSlide );\n\n\t\t\t// Set our starting state\n\t\t\tfromSlide.dataset.autoAnimate = 'pending';\n\t\t\ttoSlide.dataset.autoAnimate = 'pending';\n\n\t\t\t// Flag the navigation direction, needed for fragment buildup\n\t\t\tanimationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';\n\n\t\t\t// If the from-slide is hidden because it has moved outside\n\t\t\t// the view distance, we need to temporarily show it while\n\t\t\t// measuring\n\t\t\tlet fromSlideIsHidden = fromSlide.style.display === 'none';\n\t\t\tif( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;\n\n\t\t\t// Inject our auto-animate styles for this transition\n\t\t\tlet css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {\n\t\t\t\treturn this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );\n\t\t\t} );\n\n\t\t\tif( fromSlideIsHidden ) fromSlide.style.display = 'none';\n\n\t\t\t// Animate unmatched elements, if enabled\n\t\t\tif( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {\n\n\t\t\t\t// Our default timings for unmatched elements\n\t\t\t\tlet defaultUnmatchedDuration = animationOptions.duration * 0.8,\n\t\t\t\t\tdefaultUnmatchedDelay = animationOptions.duration * 0.2;\n\n\t\t\t\tthis.getUnmatchedAutoAnimateElements( toSlide ).forEach( unmatchedElement => {\n\n\t\t\t\t\tlet unmatchedOptions = this.getAutoAnimateOptions( unmatchedElement, animationOptions );\n\t\t\t\t\tlet id = 'unmatched';\n\n\t\t\t\t\t// If there is a duration or delay set specifically for this\n\t\t\t\t\t// element our unmatched elements should adhere to those\n\t\t\t\t\tif( unmatchedOptions.duration !== animationOptions.duration || unmatchedOptions.delay !== animationOptions.delay ) {\n\t\t\t\t\t\tid = 'unmatched-' + autoAnimateCounter++;\n\t\t\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"${id}\"] { transition: opacity ${unmatchedOptions.duration}s ease ${unmatchedOptions.delay}s; }` );\n\t\t\t\t\t}\n\n\t\t\t\t\tunmatchedElement.dataset.autoAnimateTarget = id;\n\n\t\t\t\t}, this );\n\n\t\t\t\t// Our default transition for unmatched elements\n\t\t\t\tcss.push( `[data-auto-animate=\"running\"] [data-auto-animate-target=\"unmatched\"] { transition: opacity ${defaultUnmatchedDuration}s ease ${defaultUnmatchedDelay}s; }` );\n\n\t\t\t}\n\n\t\t\t// Setting the whole chunk of CSS at once is the most\n\t\t\t// efficient way to do this. Using sheet.insertRule\n\t\t\t// is multiple factors slower.\n\t\t\tthis.autoAnimateStyleSheet.innerHTML = css.join( '' );\n\n\t\t\t// Start the animation next cycle\n\t\t\trequestAnimationFrame( () => {\n\t\t\t\tif( this.autoAnimateStyleSheet ) {\n\t\t\t\t\t// This forces our newly injected styles to be applied in Firefox\n\t\t\t\t\tgetComputedStyle( this.autoAnimateStyleSheet ).fontWeight;\n\n\t\t\t\t\ttoSlide.dataset.autoAnimate = 'running';\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'autoanimate',\n\t\t\t\tdata: {\n\t\t\t\t\tfromSlide,\n\t\t\t\t\ttoSlide,\n\t\t\t\t\tsheet: this.autoAnimateStyleSheet\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Rolls back all changes that we've made to the DOM so\n\t * that as part of animating.\n\t */\n\treset() {\n\n\t\t// Reset slides\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate]:not([data-auto-animate=\"\"])' ).forEach( element => {\n\t\t\telement.dataset.autoAnimate = '';\n\t\t} );\n\n\t\t// Reset elements\n\t\tqueryAll( this.Reveal.getRevealElement(), '[data-auto-animate-target]' ).forEach( element => {\n\t\t\tdelete element.dataset.autoAnimateTarget;\n\t\t} );\n\n\t\t// Remove the animation sheet\n\t\tif( this.autoAnimateStyleSheet && this.autoAnimateStyleSheet.parentNode ) {\n\t\t\tthis.autoAnimateStyleSheet.parentNode.removeChild( this.autoAnimateStyleSheet );\n\t\t\tthis.autoAnimateStyleSheet = null;\n\t\t}\n\n\t}\n\n\t/**\n\t * Creates a FLIP animation where the `to` element starts out\n\t * in the `from` element position and animates to its original\n\t * state.\n\t *\n\t * @param {HTMLElement} from\n\t * @param {HTMLElement} to\n\t * @param {Object} elementOptions Options for this element pair\n\t * @param {Object} animationOptions Options set at the slide level\n\t * @param {String} id Unique ID that we can use to identify this\n\t * auto-animate element in the DOM\n\t */\n\tautoAnimateElements( from, to, elementOptions, animationOptions, id ) {\n\n\t\t// 'from' elements are given a data-auto-animate-target with no value,\n\t\t// 'to' elements are are given a data-auto-animate-target with an ID\n\t\tfrom.dataset.autoAnimateTarget = '';\n\t\tto.dataset.autoAnimateTarget = id;\n\n\t\t// Each element may override any of the auto-animate options\n\t\t// like transition easing, duration and delay via data-attributes\n\t\tlet options = this.getAutoAnimateOptions( to, animationOptions );\n\n\t\t// If we're using a custom element matcher the element options\n\t\t// may contain additional transition overrides\n\t\tif( typeof elementOptions.delay !== 'undefined' ) options.delay = elementOptions.delay;\n\t\tif( typeof elementOptions.duration !== 'undefined' ) options.duration = elementOptions.duration;\n\t\tif( typeof elementOptions.easing !== 'undefined' ) options.easing = elementOptions.easing;\n\n\t\tlet fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),\n\t\t\ttoProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );\n\n\t\tif( to.classList.contains( 'fragment' ) ) {\n\n\t\t\t// Don't auto-animate the opacity of fragments to avoid\n\t\t\t// conflicts with fragment animations\n\t\t\tdelete toProps.styles['opacity'];\n\n\t\t}\n\n\t\t// If translation and/or scaling are enabled, css transform\n\t\t// the 'to' element so that it matches the position and size\n\t\t// of the 'from' element\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\n\t\t\tlet presentationScale = this.Reveal.getScale();\n\n\t\t\tlet delta = {\n\t\t\t\tx: ( fromProps.x - toProps.x ) / presentationScale,\n\t\t\t\ty: ( fromProps.y - toProps.y ) / presentationScale,\n\t\t\t\tscaleX: fromProps.width / toProps.width,\n\t\t\t\tscaleY: fromProps.height / toProps.height\n\t\t\t};\n\n\t\t\t// Limit decimal points to avoid 0.0001px blur and stutter\n\t\t\tdelta.x = Math.round( delta.x * 1000 ) / 1000;\n\t\t\tdelta.y = Math.round( delta.y * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\t\t\tdelta.scaleX = Math.round( delta.scaleX * 1000 ) / 1000;\n\n\t\t\tlet translate = elementOptions.translate !== false && ( delta.x !== 0 || delta.y !== 0 ),\n\t\t\t\tscale = elementOptions.scale !== false && ( delta.scaleX !== 0 || delta.scaleY !== 0 );\n\n\t\t\t// No need to transform if nothing's changed\n\t\t\tif( translate || scale ) {\n\n\t\t\t\tlet transform = [];\n\n\t\t\t\tif( translate ) transform.push( `translate(${delta.x}px, ${delta.y}px)` );\n\t\t\t\tif( scale ) transform.push( `scale(${delta.scaleX}, ${delta.scaleY})` );\n\n\t\t\t\tfromProps.styles['transform'] = transform.join( ' ' );\n\t\t\t\tfromProps.styles['transform-origin'] = 'top left';\n\n\t\t\t\ttoProps.styles['transform'] = 'none';\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Delete all unchanged 'to' styles\n\t\tfor( let propertyName in toProps.styles ) {\n\t\t\tconst toValue = toProps.styles[propertyName];\n\t\t\tconst fromValue = fromProps.styles[propertyName];\n\n\t\t\tif( toValue === fromValue ) {\n\t\t\t\tdelete toProps.styles[propertyName];\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// If these property values were set via a custom matcher providing\n\t\t\t\t// an explicit 'from' and/or 'to' value, we always inject those values.\n\t\t\t\tif( toValue.explicitValue === true ) {\n\t\t\t\t\ttoProps.styles[propertyName] = toValue.value;\n\t\t\t\t}\n\n\t\t\t\tif( fromValue.explicitValue === true ) {\n\t\t\t\t\tfromProps.styles[propertyName] = fromValue.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet css = '';\n\n\t\tlet toStyleProperties = Object.keys( toProps.styles );\n\n\t\t// Only create animate this element IF at least one style\n\t\t// property has changed\n\t\tif( toStyleProperties.length > 0 ) {\n\n\t\t\t// Instantly move to the 'from' state\n\t\t\tfromProps.styles['transition'] = 'none';\n\n\t\t\t// Animate towards the 'to' state\n\t\t\ttoProps.styles['transition'] = `all ${options.duration}s ${options.easing} ${options.delay}s`;\n\t\t\ttoProps.styles['transition-property'] = toStyleProperties.join( ', ' );\n\t\t\ttoProps.styles['will-change'] = toStyleProperties.join( ', ' );\n\n\t\t\t// Build up our custom CSS. We need to override inline styles\n\t\t\t// so we need to make our styles vErY IMPORTANT!1!!\n\t\t\tlet fromCSS = Object.keys( fromProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + fromProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tlet toCSS = Object.keys( toProps.styles ).map( propertyName => {\n\t\t\t\treturn propertyName + ': ' + toProps.styles[propertyName] + ' !important;';\n\t\t\t} ).join( '' );\n\n\t\t\tcss = \t'[data-auto-animate-target=\"'+ id +'\"] {'+ fromCSS +'}' +\n\t\t\t\t\t'[data-auto-animate=\"running\"] [data-auto-animate-target=\"'+ id +'\"] {'+ toCSS +'}';\n\n\t\t}\n\n\t\treturn css;\n\n\t}\n\n\t/**\n\t * Returns the auto-animate options for the given element.\n\t *\n\t * @param {HTMLElement} element Element to pick up options\n\t * from, either a slide or an animation target\n\t * @param {Object} [inheritedOptions] Optional set of existing\n\t * options\n\t */\n\tgetAutoAnimateOptions( element, inheritedOptions ) {\n\n\t\tlet options = {\n\t\t\teasing: this.Reveal.getConfig().autoAnimateEasing,\n\t\t\tduration: this.Reveal.getConfig().autoAnimateDuration,\n\t\t\tdelay: 0\n\t\t};\n\n\t\toptions = extend( options, inheritedOptions );\n\n\t\t// Inherit options from parent elements\n\t\tif( element.parentNode ) {\n\t\t\tlet autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );\n\t\t\tif( autoAnimatedParent ) {\n\t\t\t\toptions = this.getAutoAnimateOptions( autoAnimatedParent, options );\n\t\t\t}\n\t\t}\n\n\t\tif( element.dataset.autoAnimateEasing ) {\n\t\t\toptions.easing = element.dataset.autoAnimateEasing;\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDuration ) {\n\t\t\toptions.duration = parseFloat( element.dataset.autoAnimateDuration );\n\t\t}\n\n\t\tif( element.dataset.autoAnimateDelay ) {\n\t\t\toptions.delay = parseFloat( element.dataset.autoAnimateDelay );\n\t\t}\n\n\t\treturn options;\n\n\t}\n\n\t/**\n\t * Returns an object containing all of the properties\n\t * that can be auto-animated for the given element and\n\t * their current computed values.\n\t *\n\t * @param {String} direction 'from' or 'to'\n\t */\n\tgetAutoAnimatableProperties( direction, element, elementOptions ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\tlet properties = { styles: [] };\n\n\t\t// Position and size\n\t\tif( elementOptions.translate !== false || elementOptions.scale !== false ) {\n\t\t\tlet bounds;\n\n\t\t\t// Custom auto-animate may optionally return a custom tailored\n\t\t\t// measurement function\n\t\t\tif( typeof elementOptions.measure === 'function' ) {\n\t\t\t\tbounds = elementOptions.measure( element );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( config.center ) {\n\t\t\t\t\t// More precise, but breaks when used in combination\n\t\t\t\t\t// with zoom for scaling the deck ¯\\_(ツ)_/¯\n\t\t\t\t\tbounds = element.getBoundingClientRect();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet scale = this.Reveal.getScale();\n\t\t\t\t\tbounds = {\n\t\t\t\t\t\tx: element.offsetLeft * scale,\n\t\t\t\t\t\ty: element.offsetTop * scale,\n\t\t\t\t\t\twidth: element.offsetWidth * scale,\n\t\t\t\t\t\theight: element.offsetHeight * scale\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tproperties.x = bounds.x;\n\t\t\tproperties.y = bounds.y;\n\t\t\tproperties.width = bounds.width;\n\t\t\tproperties.height = bounds.height;\n\t\t}\n\n\t\tconst computedStyles = getComputedStyle( element );\n\n\t\t// CSS styles\n\t\t( elementOptions.styles || config.autoAnimateStyles ).forEach( style => {\n\t\t\tlet value;\n\n\t\t\t// `style` is either the property name directly, or an object\n\t\t\t// definition of a style property\n\t\t\tif( typeof style === 'string' ) style = { property: style };\n\n\t\t\tif( typeof style.from !== 'undefined' && direction === 'from' ) {\n\t\t\t\tvalue = { value: style.from, explicitValue: true };\n\t\t\t}\n\t\t\telse if( typeof style.to !== 'undefined' && direction === 'to' ) {\n\t\t\t\tvalue = { value: style.to, explicitValue: true };\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Use a unitless value for line-height so that it inherits properly\n\t\t\t\tif( style.property === 'line-height' ) {\n\t\t\t\t\tvalue = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );\n\t\t\t\t}\n\n\t\t\t\tif( isNaN(value) ) {\n\t\t\t\t\tvalue = computedStyles[style.property];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( value !== '' ) {\n\t\t\t\tproperties.styles[style.property] = value;\n\t\t\t}\n\t\t} );\n\n\t\treturn properties;\n\n\t}\n\n\t/**\n\t * Get a list of all element pairs that we can animate\n\t * between the given slides.\n\t *\n\t * @param {HTMLElement} fromSlide\n\t * @param {HTMLElement} toSlide\n\t *\n\t * @return {Array} Each value is an array where [0] is\n\t * the element we're animating from and [1] is the\n\t * element we're animating to\n\t */\n\tgetAutoAnimatableElements( fromSlide, toSlide ) {\n\n\t\tlet matcher = typeof this.Reveal.getConfig().autoAnimateMatcher === 'function' ? this.Reveal.getConfig().autoAnimateMatcher : this.getAutoAnimatePairs;\n\n\t\tlet pairs = matcher.call( this, fromSlide, toSlide );\n\n\t\tlet reserved = [];\n\n\t\t// Remove duplicate pairs\n\t\treturn pairs.filter( ( pair, index ) => {\n\t\t\tif( reserved.indexOf( pair.to ) === -1 ) {\n\t\t\t\treserved.push( pair.to );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Identifies matching elements between slides.\n\t *\n\t * You can specify a custom matcher function by using\n\t * the `autoAnimateMatcher` config option.\n\t */\n\tgetAutoAnimatePairs( fromSlide, toSlide ) {\n\n\t\tlet pairs = [];\n\n\t\tconst codeNodes = 'pre';\n\t\tconst textNodes = 'h1, h2, h3, h4, h5, h6, p, li';\n\t\tconst mediaNodes = 'img, video, iframe';\n\n\t\t// Explicit matches via data-id\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {\n\t\t\treturn node.nodeName + ':::' + node.getAttribute( 'data-id' );\n\t\t} );\n\n\t\t// Text\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, textNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.textContent.trim();\n\t\t} );\n\n\t\t// Media\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, mediaNodes, node => {\n\t\t\treturn node.nodeName + ':::' + ( node.getAttribute( 'src' ) || node.getAttribute( 'data-src' ) );\n\t\t} );\n\n\t\t// Code\n\t\tthis.findAutoAnimateMatches( pairs, fromSlide, toSlide, codeNodes, node => {\n\t\t\treturn node.nodeName + ':::' + node.textContent.trim();\n\t\t} );\n\n\t\tpairs.forEach( pair => {\n\t\t\t// Disable scale transformations on text nodes, we transition\n\t\t\t// each individual text property instead\n\t\t\tif( matches( pair.from, textNodes ) ) {\n\t\t\t\tpair.options = { scale: false };\n\t\t\t}\n\t\t\t// Animate individual lines of code\n\t\t\telse if( matches( pair.from, codeNodes ) ) {\n\n\t\t\t\t// Transition the code block's width and height instead of scaling\n\t\t\t\t// to prevent its content from being squished\n\t\t\t\tpair.options = { scale: false, styles: [ 'width', 'height' ] };\n\n\t\t\t\t// Lines of code\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-code', node => {\n\t\t\t\t\treturn node.textContent;\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t\t// Line numbers\n\t\t\t\tthis.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-numbers[data-line-number]', node => {\n\t\t\t\t\treturn node.getAttribute( 'data-line-number' );\n\t\t\t\t}, {\n\t\t\t\t\tscale: false,\n\t\t\t\t\tstyles: [ 'width' ],\n\t\t\t\t\tmeasure: this.getLocalBoundingBox.bind( this )\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\treturn pairs;\n\n\t}\n\n\t/**\n\t * Helper method which returns a bounding box based on\n\t * the given elements offset coordinates.\n\t *\n\t * @param {HTMLElement} element\n\t * @return {Object} x, y, width, height\n\t */\n\tgetLocalBoundingBox( element ) {\n\n\t\tconst presentationScale = this.Reveal.getScale();\n\n\t\treturn {\n\t\t\tx: Math.round( ( element.offsetLeft * presentationScale ) * 100 ) / 100,\n\t\t\ty: Math.round( ( element.offsetTop * presentationScale ) * 100 ) / 100,\n\t\t\twidth: Math.round( ( element.offsetWidth * presentationScale ) * 100 ) / 100,\n\t\t\theight: Math.round( ( element.offsetHeight * presentationScale ) * 100 ) / 100\n\t\t};\n\n\t}\n\n\t/**\n\t * Finds matching elements between two slides.\n\t *\n\t * @param {Array} pairs \tList of pairs to push matches to\n\t * @param {HTMLElement} fromScope Scope within the from element exists\n\t * @param {HTMLElement} toScope Scope within the to element exists\n\t * @param {String} selector CSS selector of the element to match\n\t * @param {Function} serializer A function that accepts an element and returns\n\t * a stringified ID based on its contents\n\t * @param {Object} animationOptions Optional config options for this pair\n\t */\n\tfindAutoAnimateMatches( pairs, fromScope, toScope, selector, serializer, animationOptions ) {\n\n\t\tlet fromMatches = {};\n\t\tlet toMatches = {};\n\n\t\t[].slice.call( fromScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\tif( typeof key === 'string' && key.length ) {\n\t\t\t\tfromMatches[key] = fromMatches[key] || [];\n\t\t\t\tfromMatches[key].push( element );\n\t\t\t}\n\t\t} );\n\n\t\t[].slice.call( toScope.querySelectorAll( selector ) ).forEach( ( element, i ) => {\n\t\t\tconst key = serializer( element );\n\t\t\ttoMatches[key] = toMatches[key] || [];\n\t\t\ttoMatches[key].push( element );\n\n\t\t\tlet fromElement;\n\n\t\t\t// Retrieve the 'from' element\n\t\t\tif( fromMatches[key] ) {\n\t\t\t\tconst primaryIndex = toMatches[key].length - 1;\n\t\t\t\tconst secondaryIndex = fromMatches[key].length - 1;\n\n\t\t\t\t// If there are multiple identical from elements, retrieve\n\t\t\t\t// the one at the same index as our to-element.\n\t\t\t\tif( fromMatches[key][ primaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ primaryIndex ];\n\t\t\t\t\tfromMatches[key][ primaryIndex ] = null;\n\t\t\t\t}\n\t\t\t\t// If there are no matching from-elements at the same index,\n\t\t\t\t// use the last one.\n\t\t\t\telse if( fromMatches[key][ secondaryIndex ] ) {\n\t\t\t\t\tfromElement = fromMatches[key][ secondaryIndex ];\n\t\t\t\t\tfromMatches[key][ secondaryIndex ] = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we've got a matching pair, push it to the list of pairs\n\t\t\tif( fromElement ) {\n\t\t\t\tpairs.push({\n\t\t\t\t\tfrom: fromElement,\n\t\t\t\t\tto: element,\n\t\t\t\t\toptions: animationOptions\n\t\t\t\t});\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns a all elements within the given scope that should\n\t * be considered unmatched in an auto-animate transition. If\n\t * fading of unmatched elements is turned on, these elements\n\t * will fade when going between auto-animate slides.\n\t *\n\t * Note that parents of auto-animate targets are NOT considered\n\t * unmatched since fading them would break the auto-animation.\n\t *\n\t * @param {HTMLElement} rootElement\n\t * @return {Array}\n\t */\n\tgetUnmatchedAutoAnimateElements( rootElement ) {\n\n\t\treturn [].slice.call( rootElement.children ).reduce( ( result, element ) => {\n\n\t\t\tconst containsAnimatedElements = element.querySelector( '[data-auto-animate-target]' );\n\n\t\t\t// The element is unmatched if\n\t\t\t// - It is not an auto-animate target\n\t\t\t// - It does not contain any auto-animate targets\n\t\t\tif( !element.hasAttribute( 'data-auto-animate-target' ) && !containsAnimatedElements ) {\n\t\t\t\tresult.push( element );\n\t\t\t}\n\n\t\t\tif( element.querySelector( '[data-auto-animate-target]' ) ) {\n\t\t\t\tresult = result.concat( this.getUnmatchedAutoAnimateElements( element ) );\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}, [] );\n\n\t}\n\n}\n","import { HORIZONTAL_SLIDES_SELECTOR, HORIZONTAL_BACKGROUNDS_SELECTOR } from '../utils/constants.js'\nimport { queryAll } from '../utils/util.js'\n\nconst HIDE_SCROLLBAR_TIMEOUT = 500;\nconst MAX_PROGRESS_SPACING = 4;\nconst MIN_PROGRESS_SEGMENT_HEIGHT = 6;\nconst MIN_PLAYHEAD_HEIGHT = 8;\n\n/**\n * The scroll view lets you read a reveal.js presentation\n * as a linear scrollable page.\n */\nexport default class ScrollView {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.active = false;\n\t\tthis.activatedCallbacks = [];\n\n\t\tthis.onScroll = this.onScroll.bind( this );\n\n\t}\n\n\t/**\n\t * Activates the scroll view. This rearranges the presentation DOM\n\t * by—among other things—wrapping each slide in a page element.\n\t */\n\tactivate() {\n\n\t\tif( this.active ) return;\n\n\t\tconst stateBeforeActivation = this.Reveal.getState();\n\n\t\tthis.active = true;\n\n\t\t// Store the full presentation HTML so that we can restore it\n\t\t// when/if the scroll view is deactivated\n\t\tthis.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;\n\n\t\tconst horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );\n\t\tconst horizontalBackgrounds = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_BACKGROUNDS_SELECTOR );\n\n\t\tthis.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-scroll' );\n\n\t\tlet presentationBackground;\n\n\t\tconst viewportStyles = window.getComputedStyle( this.viewportElement );\n\t\tif( viewportStyles && viewportStyles.background ) {\n\t\t\tpresentationBackground = viewportStyles.background;\n\t\t}\n\n\t\tconst pageElements = [];\n\t\tconst pageContainer = horizontalSlides[0].parentNode;\n\n\t\tlet previousSlide;\n\n\t\t// Creates a new page element and appends the given slide/bg\n\t\t// to it.\n\t\tconst createPageElement = ( slide, h, v, isVertical ) => {\n\n\t\t\tlet contentContainer;\n\n\t\t\t// If this slide is part of an auto-animation sequence, we\n\t\t\t// group it under the same page element as the previous slide\n\t\t\tif( previousSlide && this.Reveal.shouldAutoAnimateBetween( previousSlide, slide ) ) {\n\t\t\t\tcontentContainer = document.createElement( 'div' );\n\t\t\t\tcontentContainer.className = 'scroll-page-content scroll-auto-animate-page';\n\t\t\t\tcontentContainer.style.display = 'none';\n\t\t\t\tpreviousSlide.closest( '.scroll-page-content' ).parentNode.appendChild( contentContainer );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Wrap the slide in a page element and hide its overflow\n\t\t\t\t// so that no page ever flows onto another\n\t\t\t\tconst page = document.createElement( 'div' );\n\t\t\t\tpage.className = 'scroll-page';\n\t\t\t\tpageElements.push( page );\n\n\t\t\t\t// This transfers over the background of the vertical stack containing\n\t\t\t\t// the slide if it exists. Otherwise, it uses the presentation-wide\n\t\t\t\t// background.\n\t\t\t\tif( isVertical && horizontalBackgrounds.length > h ) {\n\t\t\t\t\tconst slideBackground = horizontalBackgrounds[h];\n\t\t\t\t\tconst pageBackground = window.getComputedStyle( slideBackground );\n\n\t\t\t\t\tif( pageBackground && pageBackground.background ) {\n\t\t\t\t\t\tpage.style.background = pageBackground.background;\n\t\t\t\t\t}\n\t\t\t\t\telse if( presentationBackground ) {\n\t\t\t\t\t\tpage.style.background = presentationBackground;\n\t\t\t\t\t}\n\t\t\t\t} else if( presentationBackground ) {\n\t\t\t\t\tpage.style.background = presentationBackground;\n\t\t\t\t}\n\n\t\t\t\tconst stickyContainer = document.createElement( 'div' );\n\t\t\t\tstickyContainer.className = 'scroll-page-sticky';\n\t\t\t\tpage.appendChild( stickyContainer );\n\n\t\t\t\tcontentContainer = document.createElement( 'div' );\n\t\t\t\tcontentContainer.className = 'scroll-page-content';\n\t\t\t\tstickyContainer.appendChild( contentContainer );\n\t\t\t}\n\n\t\t\tcontentContainer.appendChild( slide );\n\n\t\t\tslide.classList.remove( 'past', 'future' );\n\t\t\tslide.setAttribute( 'data-index-h', h );\n\t\t\tslide.setAttribute( 'data-index-v', v );\n\n\t\t\tif( slide.slideBackgroundElement ) {\n\t\t\t\tslide.slideBackgroundElement.remove( 'past', 'future' );\n\t\t\t\tcontentContainer.insertBefore( slide.slideBackgroundElement, slide );\n\t\t\t}\n\n\t\t\tpreviousSlide = slide;\n\n\t\t}\n\n\t\t// Slide and slide background layout\n\t\thorizontalSlides.forEach( ( horizontalSlide, h ) => {\n\n\t\t\tif( this.Reveal.isVerticalStack( horizontalSlide ) ) {\n\t\t\t\thorizontalSlide.querySelectorAll( 'section' ).forEach( ( verticalSlide, v ) => {\n\t\t\t\t\tcreatePageElement( verticalSlide, h, v, true );\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcreatePageElement( horizontalSlide, h, 0 );\n\t\t\t}\n\n\t\t}, this );\n\n\t\tthis.createProgressBar();\n\n\t\t// Remove leftover stacks\n\t\tqueryAll( this.Reveal.getRevealElement(), '.stack' ).forEach( stack => stack.remove() );\n\n\t\t// Add our newly created pages to the DOM\n\t\tpageElements.forEach( page => pageContainer.appendChild( page ) );\n\n\t\t// Re-run JS-based content layout after the slide is added to page DOM\n\t\tthis.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );\n\n\t\tthis.Reveal.layout();\n\t\tthis.Reveal.setState( stateBeforeActivation );\n\n\t\tthis.activatedCallbacks.forEach( callback => callback() );\n\t\tthis.activatedCallbacks = [];\n\n\t\tthis.restoreScrollPosition();\n\n\t\tthis.viewportElement.classList.remove( 'loading-scroll-mode' );\n\t\tthis.viewportElement.addEventListener( 'scroll', this.onScroll, { passive: true } );\n\n\t}\n\n\t/**\n\t * Deactivates the scroll view and restores the standard slide-based\n\t * presentation.\n\t */\n\tdeactivate() {\n\n\t\tif( !this.active ) return;\n\n\t\tconst stateBeforeDeactivation = this.Reveal.getState();\n\n\t\tthis.active = false;\n\n\t\tthis.viewportElement.removeEventListener( 'scroll', this.onScroll );\n\t\tthis.viewportElement.classList.remove( 'reveal-scroll' );\n\n\t\tthis.removeProgressBar();\n\n\t\tthis.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;\n\t\tthis.Reveal.sync();\n\t\tthis.Reveal.setState( stateBeforeDeactivation );\n\n\t\tthis.slideHTMLBeforeActivation = null;\n\n\t}\n\n\ttoggle( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? this.activate() : this.deactivate();\n\t\t}\n\t\telse {\n\t\t\tthis.isActive() ? this.deactivate() : this.activate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the scroll view is currently active.\n\t */\n\tisActive() {\n\n\t\treturn this.active;\n\n\t}\n\n\t/**\n\t * Renders the progress bar component.\n\t */\n\tcreateProgressBar() {\n\n\t\tthis.progressBar = document.createElement( 'div' );\n\t\tthis.progressBar.className = 'scrollbar';\n\n\t\tthis.progressBarInner = document.createElement( 'div' );\n\t\tthis.progressBarInner.className = 'scrollbar-inner';\n\t\tthis.progressBar.appendChild( this.progressBarInner );\n\n\t\tthis.progressBarPlayhead = document.createElement( 'div' );\n\t\tthis.progressBarPlayhead.className = 'scrollbar-playhead';\n\t\tthis.progressBarInner.appendChild( this.progressBarPlayhead );\n\n\t\tthis.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );\n\n\t\tconst handleDocumentMouseMove\t= ( event ) => {\n\n\t\t\tlet progress = ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight;\n\t\t\tprogress = Math.max( Math.min( progress, 1 ), 0 );\n\n\t\t\tthis.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );\n\n\t\t};\n\n\t\tconst handleDocumentMouseUp = ( event ) => {\n\n\t\t\tthis.draggingProgressBar = false;\n\t\t\tthis.showProgressBar();\n\n\t\t\tdocument.removeEventListener( 'mousemove', handleDocumentMouseMove );\n\t\t\tdocument.removeEventListener( 'mouseup', handleDocumentMouseUp );\n\n\t\t};\n\n\t\tconst handleMouseDown = ( event ) => {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tthis.draggingProgressBar = true;\n\n\t\t\tdocument.addEventListener( 'mousemove', handleDocumentMouseMove );\n\t\t\tdocument.addEventListener( 'mouseup', handleDocumentMouseUp );\n\n\t\t\thandleDocumentMouseMove( event );\n\n\t\t};\n\n\t\tthis.progressBarInner.addEventListener( 'mousedown', handleMouseDown );\n\n\t}\n\n\tremoveProgressBar() {\n\n\t\tif( this.progressBar ) {\n\t\t\tthis.progressBar.remove();\n\t\t\tthis.progressBar = null;\n\t\t}\n\n\t}\n\n\tlayout() {\n\n\t\tif( this.isActive() ) {\n\t\t\tthis.syncPages();\n\t\t\tthis.syncScrollPosition();\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates our pages to match the latest configuration and\n\t * presentation size.\n\t */\n\tsyncPages() {\n\n\t\tconst config = this.Reveal.getConfig();\n\n\t\tconst slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );\n\t\tconst scale = this.Reveal.getScale();\n\t\tconst useCompactLayout = config.scrollLayout === 'compact';\n\n\t\tconst viewportHeight = this.viewportElement.offsetHeight;\n\t\tconst compactHeight = slideSize.height * scale;\n\t\tconst pageHeight = useCompactLayout ? compactHeight : viewportHeight;\n\n\t\t// The height that needs to be scrolled between scroll triggers\n\t\tthis.scrollTriggerHeight = useCompactLayout ? compactHeight : viewportHeight;\n\n\t\tthis.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );\n\t\tthis.viewportElement.style.scrollSnapType = typeof config.scrollSnap === 'string' ? `y ${config.scrollSnap}` : '';\n\n\t\t// This will hold all scroll triggers used to show/hide slides\n\t\tthis.slideTriggers = [];\n\n\t\tconst pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.scroll-page' ) );\n\n\t\tthis.pages = pageElements.map( pageElement => {\n\t\t\tconst page = this.createPage({\n\t\t\t\tpageElement,\n\t\t\t\tslideElement: pageElement.querySelector( 'section' ),\n\t\t\t\tstickyElement: pageElement.querySelector( '.scroll-page-sticky' ),\n\t\t\t\tcontentElement: pageElement.querySelector( '.scroll-page-content' ),\n\t\t\t\tbackgroundElement: pageElement.querySelector( '.slide-background' ),\n\t\t\t\tautoAnimateElements: pageElement.querySelectorAll( '.scroll-auto-animate-page' ),\n\t\t\t\tautoAnimatePages: []\n\t\t\t});\n\n\t\t\tpage.pageElement.style.setProperty( '--slide-height', config.center === true ? 'auto' : slideSize.height + 'px' );\n\n\t\t\tthis.slideTriggers.push({\n\t\t\t\tpage: page,\n\t\t\t\tactivate: () => this.activatePage( page ),\n\t\t\t\tdeactivate: () => this.deactivatePage( page )\n\t\t\t});\n\n\t\t\t// Create scroll triggers that show/hide fragments\n\t\t\tthis.createFragmentTriggersForPage( page );\n\n\t\t\t// Create scroll triggers for triggering auto-animate steps\n\t\t\tif( page.autoAnimateElements.length > 0 ) {\n\t\t\t\tthis.createAutoAnimateTriggersForPage( page );\n\t\t\t}\n\n\t\t\tlet totalScrollTriggerCount = Math.max( page.scrollTriggers.length - 1, 0 );\n\n\t\t\t// Each auto-animate step may include its own scroll triggers\n\t\t\t// for fragments, ensure we count those as well\n\t\t\ttotalScrollTriggerCount += page.autoAnimatePages.reduce( ( total, page ) => {\n\t\t\t\treturn total + Math.max( page.scrollTriggers.length - 1, 0 );\n\t\t\t}, page.autoAnimatePages.length );\n\n\t\t\t// Clean up from previous renders\n\t\t\tpage.pageElement.querySelectorAll( '.scroll-snap-point' ).forEach( el => el.remove() );\n\n\t\t\t// Create snap points for all scroll triggers\n\t\t\t// - Can't be absolute in FF\n\t\t\t// - Can't be 0-height in Safari\n\t\t\t// - Can't use snap-align on parent in Safari because then\n\t\t\t// inner triggers won't work\n\t\t\tfor( let i = 0; i < totalScrollTriggerCount + 1; i++ ) {\n\t\t\t\tconst triggerStick = document.createElement( 'div' );\n\t\t\t\ttriggerStick.className = 'scroll-snap-point';\n\t\t\t\ttriggerStick.style.height = this.scrollTriggerHeight + 'px';\n\t\t\t\ttriggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';\n\t\t\t\tpage.pageElement.appendChild( triggerStick );\n\n\t\t\t\tif( i === 0 ) {\n\t\t\t\t\ttriggerStick.style.marginTop = -this.scrollTriggerHeight + 'px';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// In the compact layout, only slides with scroll triggers cover the\n\t\t\t// full viewport height. This helps avoid empty gaps before or after\n\t\t\t// a sticky slide.\n\t\t\tif( useCompactLayout && page.scrollTriggers.length > 0 ) {\n\t\t\t\tpage.pageHeight = viewportHeight;\n\t\t\t\tpage.pageElement.style.setProperty( '--page-height', viewportHeight + 'px' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpage.pageHeight = pageHeight;\n\t\t\t\tpage.pageElement.style.removeProperty( '--page-height' );\n\t\t\t}\n\n\t\t\t// Add scroll padding based on how many scroll triggers we have\n\t\t\tpage.scrollPadding = this.scrollTriggerHeight * totalScrollTriggerCount;\n\n\t\t\t// The total height including scrollable space\n\t\t\tpage.totalHeight = page.pageHeight + page.scrollPadding;\n\n\t\t\t// This is used to pad the height of our page in CSS\n\t\t\tpage.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );\n\n\t\t\t// If this is a sticky page, stick it to the vertical center\n\t\t\tif( totalScrollTriggerCount > 0 ) {\n\t\t\t\tpage.stickyElement.style.position = 'sticky';\n\t\t\t\tpage.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpage.stickyElement.style.position = 'relative';\n\t\t\t\tpage.pageElement.style.scrollSnapAlign = page.pageHeight < viewportHeight ? 'center' : 'start';\n\t\t\t}\n\n\t\t\treturn page;\n\t\t} );\n\n\t\tthis.setTriggerRanges();\n\n\t\t/*\n\t\tconsole.log(this.slideTriggers.map( t => {\n\t\t\treturn {\n\t\t\t\trange: `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`,\n\t\t\t\ttriggers: t.page.scrollTriggers.map( t => {\n\t\t\t\t\treturn `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`\n\t\t\t\t}).join( ', ' ),\n\t\t\t}\n\t\t}))\n\t\t*/\n\n\t\tthis.viewportElement.setAttribute( 'data-scrollbar', config.scrollProgress );\n\n\t\tif( config.scrollProgress && this.totalScrollTriggerCount > 1 ) {\n\t\t\t// Create the progress bar if it doesn't already exist\n\t\t\tif( !this.progressBar ) this.createProgressBar();\n\n\t\t\tthis.syncProgressBar();\n\t\t}\n\t\telse {\n\t\t\tthis.removeProgressBar();\n\t\t}\n\n\t}\n\n\t/**\n\t * Calculates and sets the scroll range for all of our scroll\n\t * triggers.\n\t */\n\tsetTriggerRanges() {\n\n\t\t// Calculate the total number of scroll triggers\n\t\tthis.totalScrollTriggerCount = this.slideTriggers.reduce( ( total, trigger ) => {\n\t\t\treturn total + Math.max( trigger.page.scrollTriggers.length, 1 );\n\t\t}, 0 );\n\n\t\tlet rangeStart = 0;\n\n\t\t// Calculate the scroll range of each scroll trigger on a scale\n\t\t// of 0-1\n\t\tthis.slideTriggers.forEach( ( trigger, i ) => {\n\t\t\ttrigger.range = [\n\t\t\t\trangeStart,\n\t\t\t\trangeStart + Math.max( trigger.page.scrollTriggers.length, 1 ) / this.totalScrollTriggerCount\n\t\t\t];\n\n\t\t\tconst scrollTriggerSegmentSize = ( trigger.range[1] - trigger.range[0] ) / trigger.page.scrollTriggers.length;\n\t\t\t// Set the range for each inner scroll trigger\n\t\t\ttrigger.page.scrollTriggers.forEach( ( scrollTrigger, i ) => {\n\t\t\t\tscrollTrigger.range = [\n\t\t\t\t\trangeStart + i * scrollTriggerSegmentSize,\n\t\t\t\t\trangeStart + ( i + 1 ) * scrollTriggerSegmentSize\n\t\t\t\t];\n\t\t\t} );\n\n\t\t\trangeStart = trigger.range[1];\n\t\t} );\n\n\t\t// Ensure the last trigger extends to the end of the page, otherwise\n\t\t// rounding errors can cause the last trigger to end at 0.999999...\n\t\tthis.slideTriggers[this.slideTriggers.length - 1].range[1] = 1;\n\n\t}\n\n\t/**\n\t * Creates one scroll trigger for each fragments in the given page.\n\t *\n\t * @param {*} page\n\t */\n\tcreateFragmentTriggersForPage( page, slideElement ) {\n\n\t\tslideElement = slideElement || page.slideElement;\n\n\t\t// Each fragment 'group' is an array containing one or more\n\t\t// fragments. Multiple fragments that appear at the same time\n\t\t// are part of the same group.\n\t\tconst fragmentGroups = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment' ), true );\n\n\t\t// Create scroll triggers that show/hide fragments\n\t\tif( fragmentGroups.length ) {\n\t\t\tpage.fragments = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment:not(.disabled)' ) );\n\t\t\tpage.scrollTriggers.push(\n\t\t\t\t// Trigger for the initial state with no fragments visible\n\t\t\t\t{\n\t\t\t\t\tactivate: () => {\n\t\t\t\t\t\tthis.Reveal.fragments.update( -1, page.fragments, slideElement );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t// Triggers for each fragment group\n\t\t\tfragmentGroups.forEach( ( fragments, i ) => {\n\t\t\t\tpage.scrollTriggers.push({\n\t\t\t\t\tactivate: () => {\n\t\t\t\t\t\tthis.Reveal.fragments.update( i, page.fragments, slideElement );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} );\n\t\t}\n\n\n\t\treturn page.scrollTriggers.length;\n\n\t}\n\n\t/**\n\t * Creates scroll triggers for the auto-animate steps in the\n\t * given page.\n\t *\n\t * @param {*} page\n\t */\n\tcreateAutoAnimateTriggersForPage( page ) {\n\n\t\tif( page.autoAnimateElements.length > 0 ) {\n\n\t\t\t// Triggers for each subsequent auto-animate slide\n\t\t\tthis.slideTriggers.push( ...Array.from( page.autoAnimateElements ).map( ( autoAnimateElement, i ) => {\n\t\t\t\tlet autoAnimatePage = this.createPage({\n\t\t\t\t\tslideElement: autoAnimateElement.querySelector( 'section' ),\n\t\t\t\t\tcontentElement: autoAnimateElement,\n\t\t\t\t\tbackgroundElement: autoAnimateElement.querySelector( '.slide-background' )\n\t\t\t\t});\n\n\t\t\t\t// Create fragment scroll triggers for the auto-animate slide\n\t\t\t\tthis.createFragmentTriggersForPage( autoAnimatePage, autoAnimatePage.slideElement );\n\n\t\t\t\tpage.autoAnimatePages.push( autoAnimatePage );\n\n\t\t\t\t// Return our slide trigger\n\t\t\t\treturn {\n\t\t\t\t\tpage: autoAnimatePage,\n\t\t\t\t\tactivate: () => this.activatePage( autoAnimatePage ),\n\t\t\t\t\tdeactivate: () => this.deactivatePage( autoAnimatePage )\n\t\t\t\t};\n\t\t\t}));\n\t\t}\n\n\t}\n\n\t/**\n\t * Helper method for creating a page definition and adding\n\t * required fields. A \"page\" is a slide or auto-animate step.\n\t */\n\tcreatePage( page ) {\n\n\t\tpage.scrollTriggers = [];\n\t\tpage.indexh = parseInt( page.slideElement.getAttribute( 'data-index-h' ), 10 );\n\t\tpage.indexv = parseInt( page.slideElement.getAttribute( 'data-index-v' ), 10 );\n\n\t\treturn page;\n\n\t}\n\n\t/**\n\t * Rerenders progress bar segments so that they match the current\n\t * reveal.js config and size.\n\t */\n\tsyncProgressBar() {\n\n\t\tthis.progressBarInner.querySelectorAll( '.scrollbar-slide' ).forEach( slide => slide.remove() );\n\n\t\tconst scrollHeight = this.viewportElement.scrollHeight;\n\t\tconst viewportHeight = this.viewportElement.offsetHeight;\n\t\tconst viewportHeightFactor = viewportHeight / scrollHeight;\n\n\t\tthis.progressBarHeight = this.progressBarInner.offsetHeight;\n\t\tthis.playheadHeight = Math.max( viewportHeightFactor * this.progressBarHeight, MIN_PLAYHEAD_HEIGHT );\n\t\tthis.progressBarScrollableHeight = this.progressBarHeight - this.playheadHeight;\n\n\t\tconst progressSegmentHeight = viewportHeight / scrollHeight * this.progressBarHeight;\n\t\tconst spacing = Math.min( progressSegmentHeight / 8, MAX_PROGRESS_SPACING );\n\n\t\tthis.progressBarPlayhead.style.height = this.playheadHeight - spacing + 'px';\n\n\t\t// Don't show individual segments if they're too small\n\t\tif( progressSegmentHeight > MIN_PROGRESS_SEGMENT_HEIGHT ) {\n\n\t\t\tthis.slideTriggers.forEach( slideTrigger => {\n\n\t\t\t\tconst { page } = slideTrigger;\n\n\t\t\t\t// Visual representation of a slide\n\t\t\t\tpage.progressBarSlide = document.createElement( 'div' );\n\t\t\t\tpage.progressBarSlide.className = 'scrollbar-slide';\n\t\t\t\tpage.progressBarSlide.style.top = slideTrigger.range[0] * this.progressBarHeight + 'px';\n\t\t\t\tpage.progressBarSlide.style.height = ( slideTrigger.range[1] - slideTrigger.range[0] ) * this.progressBarHeight - spacing + 'px';\n\t\t\t\tpage.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );\n\t\t\t\tthis.progressBarInner.appendChild( page.progressBarSlide );\n\n\t\t\t\t// Visual representations of each scroll trigger\n\t\t\t\tpage.scrollTriggerElements = page.scrollTriggers.map( ( trigger, i ) => {\n\n\t\t\t\t\tconst triggerElement = document.createElement( 'div' );\n\t\t\t\t\ttriggerElement.className = 'scrollbar-trigger';\n\t\t\t\t\ttriggerElement.style.top = ( trigger.range[0] - slideTrigger.range[0] ) * this.progressBarHeight + 'px';\n\t\t\t\t\ttriggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * this.progressBarHeight - spacing + 'px';\n\t\t\t\t\tpage.progressBarSlide.appendChild( triggerElement );\n\n\t\t\t\t\tif( i === 0 ) triggerElement.style.display = 'none';\n\n\t\t\t\t\treturn triggerElement;\n\n\t\t\t\t} );\n\n\t\t\t} );\n\n\t\t}\n\t\telse {\n\n\t\t\tthis.pages.forEach( page => page.progressBarSlide = null );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Reads the current scroll position and updates our active\n\t * trigger states accordingly.\n\t */\n\tsyncScrollPosition() {\n\n\t\tconst viewportHeight = this.viewportElement.offsetHeight;\n\t\tconst viewportHeightFactor = viewportHeight / this.viewportElement.scrollHeight;\n\n\t\tconst scrollTop = this.viewportElement.scrollTop;\n\t\tconst scrollHeight = this.viewportElement.scrollHeight - viewportHeight\n\t\tconst scrollProgress = Math.max( Math.min( scrollTop / scrollHeight, 1 ), 0 );\n\t\tconst scrollProgressMid = Math.max( Math.min( ( scrollTop + viewportHeight / 2 ) / this.viewportElement.scrollHeight, 1 ), 0 );\n\n\t\tlet activePage;\n\n\t\tthis.slideTriggers.forEach( ( trigger ) => {\n\t\t\tconst { page } = trigger;\n\n\t\t\tconst shouldPreload = scrollProgress >= trigger.range[0] - viewportHeightFactor*2 &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tscrollProgress <= trigger.range[1] + viewportHeightFactor*2;\n\n\t\t\t// Load slides that are within the preload range\n\t\t\tif( shouldPreload && !page.loaded ) {\n\t\t\t\tpage.loaded = true;\n\t\t\t\tthis.Reveal.slideContent.load( page.slideElement );\n\t\t\t}\n\t\t\telse if( page.loaded ) {\n\t\t\t\tpage.loaded = false;\n\t\t\t\tthis.Reveal.slideContent.unload( page.slideElement );\n\t\t\t}\n\n\t\t\t// If we're within this trigger range, activate it\n\t\t\tif( scrollProgress >= trigger.range[0] && scrollProgress <= trigger.range[1] ) {\n\t\t\t\tthis.activateTrigger( trigger );\n\t\t\t\tactivePage = trigger.page;\n\t\t\t}\n\t\t\t// .. otherwise deactivate\n\t\t\telse if( trigger.active ) {\n\t\t\t\tthis.deactivateTrigger( trigger );\n\t\t\t}\n\t\t} );\n\n\t\t// Each page can have its own scroll triggers, check if any of those\n\t\t// need to be activated/deactivated\n\t\tif( activePage ) {\n\t\t\tactivePage.scrollTriggers.forEach( ( trigger ) => {\n\t\t\t\tif( scrollProgressMid >= trigger.range[0] && scrollProgressMid <= trigger.range[1] ) {\n\t\t\t\t\tthis.activateTrigger( trigger );\n\t\t\t\t}\n\t\t\t\telse if( trigger.active ) {\n\t\t\t\t\tthis.deactivateTrigger( trigger );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Update our visual progress indication\n\t\tthis.setProgressBarValue( scrollTop / ( this.viewportElement.scrollHeight - viewportHeight ) );\n\n\t}\n\n\t/**\n\t * Moves the progress bar playhead to the specified position.\n\t *\n\t * @param {number} progress 0-1\n\t */\n\tsetProgressBarValue( progress ) {\n\n\t\tif( this.progressBar ) {\n\n\t\t\tthis.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;\n\n\t\t\tthis.getAllPages()\n\t\t\t\t.filter( page => page.progressBarSlide )\n\t\t\t\t.forEach( ( page ) => {\n\t\t\t\t\tpage.progressBarSlide.classList.toggle( 'active', page.active === true );\n\n\t\t\t\t\tpage.scrollTriggers.forEach( ( trigger, i ) => {\n\t\t\t\t\t\tpage.scrollTriggerElements[i].classList.toggle( 'active', page.active === true && trigger.active === true );\n\t\t\t\t\t} );\n\t\t\t\t} );\n\n\t\t\tthis.showProgressBar();\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Show the progress bar and, if configured, automatically hide\n\t * it after a delay.\n\t */\n\tshowProgressBar() {\n\n\t\tthis.progressBar.classList.add( 'visible' );\n\n\t\tclearTimeout( this.hideProgressBarTimeout );\n\n\t\tif( this.Reveal.getConfig().scrollProgress === 'auto' && !this.draggingProgressBar ) {\n\n\t\t\tthis.hideProgressBarTimeout = setTimeout( () => {\n\t\t\t\tif( this.progressBar ) {\n\t\t\t\t\tthis.progressBar.classList.remove( 'visible' );\n\t\t\t\t}\n\t\t\t}, HIDE_SCROLLBAR_TIMEOUT );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Scroll to the previous page.\n\t */\n\tprev() {\n\n\t\tthis.viewportElement.scrollTop -= this.scrollTriggerHeight;\n\n\t}\n\n\t/**\n\t * Scroll to the next page.\n\t */\n\tnext() {\n\n\t\tthis.viewportElement.scrollTop += this.scrollTriggerHeight;\n\n\t}\n\n\t/**\n\t * Scrolls the given slide element into view.\n\t *\n\t * @param {HTMLElement} slideElement\n\t */\n\tscrollToSlide( slideElement ) {\n\n\t\t// If the scroll view isn't active yet, queue this action\n\t\tif( !this.active ) {\n\t\t\tthis.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );\n\t\t}\n\t\telse {\n\t\t\t// Find the trigger for this slide\n\t\t\tconst trigger = this.getScrollTriggerBySlide( slideElement );\n\n\t\t\tif( trigger ) {\n\t\t\t\t// Use the trigger's range to calculate the scroll position\n\t\t\t\tthis.viewportElement.scrollTop = trigger.range[0] * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Persists the current scroll position to session storage\n\t * so that it can be restored.\n\t */\n\tstoreScrollPosition() {\n\n\t\tclearTimeout( this.storeScrollPositionTimeout );\n\n\t\tthis.storeScrollPositionTimeout = setTimeout( () => {\n\t\t\tsessionStorage.setItem( 'reveal-scroll-top', this.viewportElement.scrollTop );\n\t\t\tsessionStorage.setItem( 'reveal-scroll-origin', location.origin + location.pathname );\n\n\t\t\tthis.storeScrollPositionTimeout = null;\n\t\t}, 50 );\n\n\t}\n\n\t/**\n\t * Restores the scroll position when a deck is reloader.\n\t */\n\trestoreScrollPosition() {\n\n\t\tconst scrollPosition = sessionStorage.getItem( 'reveal-scroll-top' );\n\t\tconst scrollOrigin = sessionStorage.getItem( 'reveal-scroll-origin' );\n\n\t\tif( scrollPosition && scrollOrigin === location.origin + location.pathname ) {\n\t\t\tthis.viewportElement.scrollTop = parseInt( scrollPosition, 10 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Activates the given page and starts its embedded content\n\t * if there is any.\n\t *\n\t * @param {object} page\n\t */\n\tactivatePage( page ) {\n\n\t\tif( !page.active ) {\n\n\t\t\tpage.active = true;\n\n\t\t\tconst { slideElement, backgroundElement, contentElement, indexh, indexv } = page;\n\n\t\t\tcontentElement.style.display = 'block';\n\n\t\t\tslideElement.classList.add( 'present' );\n\n\t\t\tif( backgroundElement ) {\n\t\t\t\tbackgroundElement.classList.add( 'present' );\n\t\t\t}\n\n\t\t\tthis.Reveal.setCurrentScrollPage( slideElement, indexh, indexv );\n\t\t\tthis.Reveal.backgrounds.bubbleSlideContrastClassToElement( slideElement, this.viewportElement );\n\n\t\t\t// If this page is part of an auto-animation there will be one\n\t\t\t// content element per auto-animated page. We need to show the\n\t\t\t// current page and hide all others.\n\t\t\tArray.from( contentElement.parentNode.querySelectorAll( '.scroll-page-content' ) ).forEach( sibling => {\n\t\t\t\tif( sibling !== contentElement ) {\n\t\t\t\t\tsibling.style.display = 'none';\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Deactivates the page after it has been visible.\n\t *\n\t * @param {object} page\n\t */\n\tdeactivatePage( page ) {\n\n\t\tif( page.active ) {\n\n\t\t\tpage.active = false;\n\t\t\tif( page.slideElement ) page.slideElement.classList.remove( 'present' );\n\t\t\tif( page.backgroundElement ) page.backgroundElement.classList.remove( 'present' );\n\n\t\t}\n\n\t}\n\n\tactivateTrigger( trigger ) {\n\n\t\tif( !trigger.active ) {\n\t\t\ttrigger.active = true;\n\t\t\ttrigger.activate();\n\t\t}\n\n\t}\n\n\tdeactivateTrigger( trigger ) {\n\n\t\tif( trigger.active ) {\n\t\t\ttrigger.active = false;\n\n\t\t\tif( trigger.deactivate ) {\n\t\t\t\ttrigger.deactivate();\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Retrieve a slide by its original h/v index (i.e. the indices the\n\t * slide had before being linearized).\n\t *\n\t * @param {number} h\n\t * @param {number} v\n\t * @returns {HTMLElement}\n\t */\n\tgetSlideByIndices( h, v ) {\n\n\t\tconst page = this.getAllPages().find( page => {\n\t\t\treturn page.indexh === h && page.indexv === v;\n\t\t} );\n\n\t\treturn page ? page.slideElement : null;\n\n\t}\n\n\t/**\n\t * Retrieve a list of all scroll triggers for the given slide\n\t * DOM element.\n\t *\n\t * @param {HTMLElement} slide\n\t * @returns {Array}\n\t */\n\tgetScrollTriggerBySlide( slide ) {\n\n\t\treturn this.slideTriggers.find( trigger => trigger.page.slideElement === slide );\n\n\t}\n\n\t/**\n\t * Get a list of all pages in the scroll view. This includes\n\t * both top-level slides and auto-animate steps.\n\t *\n\t * @returns {Array}\n\t */\n\tgetAllPages() {\n\n\t\treturn this.pages.flatMap( page => [page, ...(page.autoAnimatePages || [])] );\n\n\t}\n\n\tonScroll() {\n\n\t\tthis.syncScrollPosition();\n\t\tthis.storeScrollPosition();\n\n\t}\n\n\tget viewportElement() {\n\n\t\treturn this.Reveal.getViewportElement();\n\n\t}\n\n}\n","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { queryAll, createStyleSheet } from '../utils/util.js'\n\n/**\n * Setups up our presentation for printing/exporting to PDF.\n */\nexport default class PrintView {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Configures the presentation for printing to a static\n\t * PDF.\n\t */\n\tasync activate() {\n\n\t\tconst config = this.Reveal.getConfig();\n\t\tconst slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )\n\n\t\t// Compute slide numbers now, before we start duplicating slides\n\t\tconst injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );\n\n\t\tconst slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );\n\n\t\t// Dimensions of the PDF pages\n\t\tconst pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),\n\t\t\tpageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );\n\n\t\t// Dimensions of slides within the pages\n\t\tconst slideWidth = slideSize.width,\n\t\t\tslideHeight = slideSize.height;\n\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\t// Let the browser know what page size we want to print\n\t\tcreateStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0px;}' );\n\n\t\t// Limit the size of certain elements to the dimensions of the slide\n\t\tcreateStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );\n\n\t\tdocument.documentElement.classList.add( 'reveal-print', 'print-pdf' );\n\t\tdocument.body.style.width = pageWidth + 'px';\n\t\tdocument.body.style.height = pageHeight + 'px';\n\n\t\tconst viewportElement = this.Reveal.getViewportElement();\n\t\tlet presentationBackground;\n\t\tif( viewportElement ) {\n\t\t\tconst viewportStyles = window.getComputedStyle( viewportElement );\n\t\t\tif( viewportStyles && viewportStyles.background ) {\n\t\t\t\tpresentationBackground = viewportStyles.background;\n\t\t\t}\n\t\t}\n\n\t\t// Make sure stretch elements fit on slide\n\t\tawait new Promise( requestAnimationFrame );\n\t\tthis.Reveal.layoutSlideContents( slideWidth, slideHeight );\n\n\t\t// Batch scrollHeight access to prevent layout thrashing\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\tconst slideScrollHeights = slides.map( slide => slide.scrollHeight );\n\n\t\tconst pages = [];\n\t\tconst pageContainer = slides[0].parentNode;\n\t\tlet slideNumber = 1;\n\n\t\t// Slide and slide background layout\n\t\tslides.forEach( function( slide, index ) {\n\n\t\t\t// Vertical stacks are not centred since their section\n\t\t\t// children will be\n\t\t\tif( slide.classList.contains( 'stack' ) === false ) {\n\t\t\t\t// Center the slide inside of the page, giving the slide some margin\n\t\t\t\tlet left = ( pageWidth - slideWidth ) / 2;\n\t\t\t\tlet top = ( pageHeight - slideHeight ) / 2;\n\n\t\t\t\tconst contentHeight = slideScrollHeights[ index ];\n\t\t\t\tlet numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );\n\n\t\t\t\t// Adhere to configured pages per slide limit\n\t\t\t\tnumberOfPages = Math.min( numberOfPages, config.pdfMaxPagesPerSlide );\n\n\t\t\t\t// Center slides vertically\n\t\t\t\tif( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {\n\t\t\t\t\ttop = Math.max( ( pageHeight - contentHeight ) / 2, 0 );\n\t\t\t\t}\n\n\t\t\t\t// Wrap the slide in a page element and hide its overflow\n\t\t\t\t// so that no page ever flows onto another\n\t\t\t\tconst page = document.createElement( 'div' );\n\t\t\t\tpages.push( page );\n\n\t\t\t\tpage.className = 'pdf-page';\n\t\t\t\tpage.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';\n\n\t\t\t\t// Copy the presentation-wide background to each individual\n\t\t\t\t// page when printing\n\t\t\t\tif( presentationBackground ) {\n\t\t\t\t\tpage.style.background = presentationBackground;\n\t\t\t\t}\n\n\t\t\t\tpage.appendChild( slide );\n\n\t\t\t\t// Position the slide inside of the page\n\t\t\t\tslide.style.left = left + 'px';\n\t\t\t\tslide.style.top = top + 'px';\n\t\t\t\tslide.style.width = slideWidth + 'px';\n\n\t\t\t\tthis.Reveal.slideContent.layout( slide );\n\n\t\t\t\tif( slide.slideBackgroundElement ) {\n\t\t\t\t\tpage.insertBefore( slide.slideBackgroundElement, slide );\n\t\t\t\t}\n\n\t\t\t\t// Inject notes if `showNotes` is enabled\n\t\t\t\tif( config.showNotes ) {\n\n\t\t\t\t\t// Are there notes for this slide?\n\t\t\t\t\tconst notes = this.Reveal.getSlideNotes( slide );\n\t\t\t\t\tif( notes ) {\n\n\t\t\t\t\t\tconst notesSpacing = 8;\n\t\t\t\t\t\tconst notesLayout = typeof config.showNotes === 'string' ? config.showNotes : 'inline';\n\t\t\t\t\t\tconst notesElement = document.createElement( 'div' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes' );\n\t\t\t\t\t\tnotesElement.classList.add( 'speaker-notes-pdf' );\n\t\t\t\t\t\tnotesElement.setAttribute( 'data-layout', notesLayout );\n\t\t\t\t\t\tnotesElement.innerHTML = notes;\n\n\t\t\t\t\t\tif( notesLayout === 'separate-page' ) {\n\t\t\t\t\t\t\tpages.push( notesElement );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tnotesElement.style.left = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.bottom = notesSpacing + 'px';\n\t\t\t\t\t\t\tnotesElement.style.width = ( pageWidth - notesSpacing*2 ) + 'px';\n\t\t\t\t\t\t\tpage.appendChild( notesElement );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Inject page numbers if `slideNumbers` are enabled\n\t\t\t\tif( injectPageNumbers ) {\n\t\t\t\t\tconst numberElement = document.createElement( 'div' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number' );\n\t\t\t\t\tnumberElement.classList.add( 'slide-number-pdf' );\n\t\t\t\t\tnumberElement.innerHTML = slideNumber++;\n\t\t\t\t\tpage.appendChild( numberElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy page and show fragments one after another\n\t\t\t\tif( config.pdfSeparateFragments ) {\n\n\t\t\t\t\t// Each fragment 'group' is an array containing one or more\n\t\t\t\t\t// fragments. Multiple fragments that appear at the same time\n\t\t\t\t\t// are part of the same group.\n\t\t\t\t\tconst fragmentGroups = this.Reveal.fragments.sort( page.querySelectorAll( '.fragment' ), true );\n\n\t\t\t\t\tlet previousFragmentStep;\n\n\t\t\t\t\tfragmentGroups.forEach( function( fragments, index ) {\n\n\t\t\t\t\t\t// Remove 'current-fragment' from the previous group\n\t\t\t\t\t\tif( previousFragmentStep ) {\n\t\t\t\t\t\t\tpreviousFragmentStep.forEach( function( fragment ) {\n\t\t\t\t\t\t\t\tfragment.classList.remove( 'current-fragment' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Show the fragments for the current index\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.add( 'visible', 'current-fragment' );\n\t\t\t\t\t\t}, this );\n\n\t\t\t\t\t\t// Create a separate page for the current fragment state\n\t\t\t\t\t\tconst clonedPage = page.cloneNode( true );\n\n\t\t\t\t\t\t// Inject unique page numbers for fragments\n\t\t\t\t\t\tif( injectPageNumbers ) {\n\t\t\t\t\t\t\tconst numberElement = clonedPage.querySelector( '.slide-number-pdf' );\n\t\t\t\t\t\t\tconst fragmentNumber = index + 1;\n\t\t\t\t\t\t\tnumberElement.innerHTML += '.' + fragmentNumber;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpages.push( clonedPage );\n\n\t\t\t\t\t\tpreviousFragmentStep = fragments;\n\n\t\t\t\t\t}, this );\n\n\t\t\t\t\t// Reset the first/original page so that all fragments are hidden\n\t\t\t\t\tfragmentGroups.forEach( function( fragments ) {\n\t\t\t\t\t\tfragments.forEach( function( fragment ) {\n\t\t\t\t\t\t\tfragment.classList.remove( 'visible', 'current-fragment' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t\t// Show all fragments\n\t\t\t\telse {\n\t\t\t\t\tqueryAll( page, '.fragment:not(.fade-out)' ).forEach( function( fragment ) {\n\t\t\t\t\t\tfragment.classList.add( 'visible' );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}, this );\n\n\t\tawait new Promise( requestAnimationFrame );\n\n\t\tpages.forEach( page => pageContainer.appendChild( page ) );\n\n\t\t// Re-run JS-based content layout after the slide is added to page DOM\n\t\tthis.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );\n\n\t\t// Notify subscribers that the PDF layout is good to go\n\t\tthis.Reveal.dispatchEvent({ type: 'pdf-ready' });\n\n\t\tviewportElement.classList.remove( 'loading-scroll-mode' );\n\n\t}\n\n\t/**\n\t * Checks if the print mode is/should be activated.\n\t */\n\tisActive() {\n\n\t\treturn this.Reveal.getConfig().view === 'print';\n\n\t}\n\n}","import { extend, queryAll } from '../utils/util.js'\n\n/**\n * Handles sorting and navigation of slide fragments.\n * Fragments are elements within a slide that are\n * revealed/animated incrementally.\n */\nexport default class Fragments {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.fragments === false ) {\n\t\t\tthis.disable();\n\t\t}\n\t\telse if( oldConfig.fragments === false ) {\n\t\t\tthis.enable();\n\t\t}\n\n\t}\n\n\t/**\n\t * If fragments are disabled in the deck, they should all be\n\t * visible rather than stepped through.\n\t */\n\tdisable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.add( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Reverse of #disable(). Only called if fragments have\n\t * previously been disabled.\n\t */\n\tenable() {\n\n\t\tqueryAll( this.Reveal.getSlidesElement(), '.fragment' ).forEach( element => {\n\t\t\telement.classList.remove( 'visible' );\n\t\t\telement.classList.remove( 'current-fragment' );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Returns an object describing the available fragment\n\t * directions.\n\t *\n\t * @return {{prev: boolean, next: boolean}}\n\t */\n\tavailableRoutes() {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\t\t\tlet fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );\n\t\t\tlet hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );\n\n\t\t\treturn {\n\t\t\t\tprev: fragments.length - hiddenFragments.length > 0,\n\t\t\t\tnext: !!hiddenFragments.length\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\treturn { prev: false, next: false };\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a sorted fragments list, ordered by an increasing\n\t * \"data-fragment-index\" attribute.\n\t *\n\t * Fragments will be revealed in the order that they are returned by\n\t * this function, so you can use the index attributes to control the\n\t * order of fragment appearance.\n\t *\n\t * To maintain a sensible default fragment order, fragments are presumed\n\t * to be passed in document order. This function adds a \"fragment-index\"\n\t * attribute to each node if such an attribute is not already present,\n\t * and sets that attribute to an integer value which is the position of\n\t * the fragment within the fragments list.\n\t *\n\t * @param {object[]|*} fragments\n\t * @param {boolean} grouped If true the returned array will contain\n\t * nested arrays for all fragments with the same index\n\t * @return {object[]} sorted Sorted array of fragments\n\t */\n\tsort( fragments, grouped = false ) {\n\n\t\tfragments = Array.from( fragments );\n\n\t\tlet ordered = [],\n\t\t\tunordered = [],\n\t\t\tsorted = [];\n\n\t\t// Group ordered and unordered elements\n\t\tfragments.forEach( fragment => {\n\t\t\tif( fragment.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\tlet index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );\n\n\t\t\t\tif( !ordered[index] ) {\n\t\t\t\t\tordered[index] = [];\n\t\t\t\t}\n\n\t\t\t\tordered[index].push( fragment );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tunordered.push( [ fragment ] );\n\t\t\t}\n\t\t} );\n\n\t\t// Append fragments without explicit indices in their\n\t\t// DOM order\n\t\tordered = ordered.concat( unordered );\n\n\t\t// Manually count the index up per group to ensure there\n\t\t// are no gaps\n\t\tlet index = 0;\n\n\t\t// Push all fragments in their sorted order to an array,\n\t\t// this flattens the groups\n\t\tordered.forEach( group => {\n\t\t\tgroup.forEach( fragment => {\n\t\t\t\tsorted.push( fragment );\n\t\t\t\tfragment.setAttribute( 'data-fragment-index', index );\n\t\t\t} );\n\n\t\t\tindex ++;\n\t\t} );\n\n\t\treturn grouped === true ? ordered : sorted;\n\n\t}\n\n\t/**\n\t * Sorts and formats all of fragments in the\n\t * presentation.\n\t */\n\tsortAll() {\n\n\t\tthis.Reveal.getHorizontalSlides().forEach( horizontalSlide => {\n\n\t\t\tlet verticalSlides = queryAll( horizontalSlide, 'section' );\n\t\t\tverticalSlides.forEach( ( verticalSlide, y ) => {\n\n\t\t\t\tthis.sort( verticalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t\t}, this );\n\n\t\t\tif( verticalSlides.length === 0 ) this.sort( horizontalSlide.querySelectorAll( '.fragment' ) );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Refreshes the fragments on the current slide so that they\n\t * have the appropriate classes (.visible + .current-fragment).\n\t *\n\t * @param {number} [index] The index of the current fragment\n\t * @param {array} [fragments] Array containing all fragments\n\t * in the current slide\n\t *\n\t * @return {{shown: array, hidden: array}}\n\t */\n\tupdate( index, fragments, slide = this.Reveal.getCurrentSlide() ) {\n\n\t\tlet changedFragments = {\n\t\t\tshown: [],\n\t\t\thidden: []\n\t\t};\n\n\t\tif( slide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tfragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );\n\n\t\t\tif( fragments.length ) {\n\n\t\t\t\tlet maxIndex = 0;\n\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();\n\t\t\t\t\tif( currentFragment ) {\n\t\t\t\t\t\tindex = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tArray.from( fragments ).forEach( ( el, i ) => {\n\n\t\t\t\t\tif( el.hasAttribute( 'data-fragment-index' ) ) {\n\t\t\t\t\t\ti = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );\n\t\t\t\t\t}\n\n\t\t\t\t\tmaxIndex = Math.max( maxIndex, i );\n\n\t\t\t\t\t// Visible fragments\n\t\t\t\t\tif( i <= index ) {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.add( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( i === index ) {\n\t\t\t\t\t\t\t// Announce the fragments one by one to the Screen Reader\n\t\t\t\t\t\t\tthis.Reveal.announceStatus( this.Reveal.getStatusText( el ) );\n\n\t\t\t\t\t\t\tel.classList.add( 'current-fragment' );\n\t\t\t\t\t\t\tthis.Reveal.slideContent.startEmbeddedContent( el );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( !wasVisible ) {\n\t\t\t\t\t\t\tchangedFragments.shown.push( el )\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'visible',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Hidden fragments\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet wasVisible = el.classList.contains( 'visible' )\n\t\t\t\t\t\tel.classList.remove( 'visible' );\n\t\t\t\t\t\tel.classList.remove( 'current-fragment' );\n\n\t\t\t\t\t\tif( wasVisible ) {\n\t\t\t\t\t\t\tthis.Reveal.slideContent.stopEmbeddedContent( el );\n\t\t\t\t\t\t\tchangedFragments.hidden.push( el );\n\t\t\t\t\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\t\t\t\t\ttarget: el,\n\t\t\t\t\t\t\t\ttype: 'hidden',\n\t\t\t\t\t\t\t\tbubbles: false\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\t// Write the current fragment index to the slide .\n\t\t\t\t// This can be used by end users to apply styles based on\n\t\t\t\t// the current fragment index.\n\t\t\t\tindex = typeof index === 'number' ? index : -1;\n\t\t\t\tindex = Math.max( Math.min( index, maxIndex ), -1 );\n\t\t\t\tslide.setAttribute( 'data-fragment', index );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif( changedFragments.hidden.length ) {\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'fragmenthidden',\n\t\t\t\tdata: {\n\t\t\t\t\tfragment: changedFragments.hidden[0],\n\t\t\t\t\tfragments: changedFragments.hidden\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif( changedFragments.shown.length ) {\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'fragmentshown',\n\t\t\t\tdata: {\n\t\t\t\t\tfragment: changedFragments.shown[0],\n\t\t\t\t\tfragments: changedFragments.shown\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn changedFragments;\n\n\t}\n\n\t/**\n\t * Formats the fragments on the given slide so that they have\n\t * valid indices. Call this if fragments are changed in the DOM\n\t * after reveal.js has already initialized.\n\t *\n\t * @param {HTMLElement} slide\n\t * @return {Array} a list of the HTML fragments that were synced\n\t */\n\tsync( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\treturn this.sort( slide.querySelectorAll( '.fragment' ) );\n\n\t}\n\n\t/**\n\t * Navigate to the specified slide fragment.\n\t *\n\t * @param {?number} index The index of the fragment that\n\t * should be shown, -1 means all are invisible\n\t * @param {number} offset Integer offset to apply to the\n\t * fragment index\n\t *\n\t * @return {boolean} true if a change was made in any\n\t * fragments visibility as part of this call\n\t */\n\tgoto( index, offset = 0 ) {\n\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide && this.Reveal.getConfig().fragments ) {\n\n\t\t\tlet fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );\n\t\t\tif( fragments.length ) {\n\n\t\t\t\t// If no index is specified, find the current\n\t\t\t\tif( typeof index !== 'number' ) {\n\t\t\t\t\tlet lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();\n\n\t\t\t\t\tif( lastVisibleFragment ) {\n\t\t\t\t\t\tindex = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tindex = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply the offset if there is one\n\t\t\t\tindex += offset;\n\n\t\t\t\tlet changedFragments = this.update( index, fragments );\n\n\t\t\t\tthis.Reveal.controls.update();\n\t\t\t\tthis.Reveal.progress.update();\n\n\t\t\t\tif( this.Reveal.getConfig().fragmentInURL ) {\n\t\t\t\t\tthis.Reveal.location.writeURL();\n\t\t\t\t}\n\n\t\t\t\treturn !!( changedFragments.shown.length || changedFragments.hidden.length );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Navigate to the next slide fragment.\n\t *\n\t * @return {boolean} true if there was a next fragment,\n\t * false otherwise\n\t */\n\tnext() {\n\n\t\treturn this.goto( null, 1 );\n\n\t}\n\n\t/**\n\t * Navigate to the previous slide fragment.\n\t *\n\t * @return {boolean} true if there was a previous fragment,\n\t * false otherwise\n\t */\n\tprev() {\n\n\t\treturn this.goto( null, -1 );\n\n\t}\n\n}","import { SLIDES_SELECTOR } from '../utils/constants.js'\nimport { extend, queryAll, transformElement } from '../utils/util.js'\n\n/**\n * Handles all logic related to the overview mode\n * (birds-eye view of all slides).\n */\nexport default class Overview {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.active = false;\n\n\t\tthis.onSlideClicked = this.onSlideClicked.bind( this );\n\n\t}\n\n\t/**\n\t * Displays the overview of slides (quick nav) by scaling\n\t * down and arranging all slide elements.\n\t */\n\tactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {\n\n\t\t\tthis.active = true;\n\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview' );\n\n\t\t\t// Don't auto-slide while in overview mode\n\t\t\tthis.Reveal.cancelAutoSlide();\n\n\t\t\t// Move the backgrounds element into the slide container to\n\t\t\t// that the same scaling is applied\n\t\t\tthis.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clicking on an overview slide navigates to it\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\tif( !slide.classList.contains( 'stack' ) ) {\n\t\t\t\t\tslide.addEventListener( 'click', this.onSlideClicked, true );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Calculate slide sizes\n\t\t\tconst margin = 70;\n\t\t\tconst slideSize = this.Reveal.getComputedSlideSize();\n\t\t\tthis.overviewSlideWidth = slideSize.width + margin;\n\t\t\tthis.overviewSlideHeight = slideSize.height + margin;\n\n\t\t\t// Reverse in RTL mode\n\t\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\t\tthis.overviewSlideWidth = -this.overviewSlideWidth;\n\t\t\t}\n\n\t\t\tthis.Reveal.updateSlidesVisibility();\n\n\t\t\tthis.layout();\n\t\t\tthis.update();\n\n\t\t\tthis.Reveal.layout();\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\t// Notify observers of the overview showing\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewshown',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Uses CSS transforms to position all slides in a grid for\n\t * display inside of the overview mode.\n\t */\n\tlayout() {\n\n\t\t// Layout slides\n\t\tthis.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {\n\t\t\thslide.setAttribute( 'data-index-h', h );\n\t\t\ttransformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tif( hslide.classList.contains( 'stack' ) ) {\n\n\t\t\t\tqueryAll( hslide, 'section' ).forEach( ( vslide, v ) => {\n\t\t\t\t\tvslide.setAttribute( 'data-index-h', h );\n\t\t\t\t\tvslide.setAttribute( 'data-index-v', v );\n\n\t\t\t\t\ttransformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t\t} );\n\n\t\t\t}\n\t\t} );\n\n\t\t// Layout slide backgrounds\n\t\tArray.from( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {\n\t\t\ttransformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );\n\n\t\t\tqueryAll( hbackground, '.slide-background' ).forEach( ( vbackground, v ) => {\n\t\t\t\ttransformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );\n\t\t\t} );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Moves the overview viewport to the current slides.\n\t * Called each time the current slide changes.\n\t */\n\tupdate() {\n\n\t\tconst vmin = Math.min( window.innerWidth, window.innerHeight );\n\t\tconst scale = Math.max( vmin / 5, 150 ) / vmin;\n\t\tconst indices = this.Reveal.getIndices();\n\n\t\tthis.Reveal.transformSlides( {\n\t\t\toverview: [\n\t\t\t\t'scale('+ scale +')',\n\t\t\t\t'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',\n\t\t\t\t'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'\n\t\t\t].join( ' ' )\n\t\t} );\n\n\t}\n\n\t/**\n\t * Exits the slide overview and enters the currently\n\t * active slide.\n\t */\n\tdeactivate() {\n\n\t\t// Only proceed if enabled in config\n\t\tif( this.Reveal.getConfig().overview ) {\n\n\t\t\tthis.active = false;\n\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview' );\n\n\t\t\t// Temporarily add a class so that transitions can do different things\n\t\t\t// depending on whether they are exiting/entering overview, or just\n\t\t\t// moving from slide to slide\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'overview-deactivating' );\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );\n\t\t\t}, 1 );\n\n\t\t\t// Move the background element back out\n\t\t\tthis.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );\n\n\t\t\t// Clean up changes made to slides\n\t\t\tqueryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR ).forEach( slide => {\n\t\t\t\ttransformElement( slide, '' );\n\n\t\t\t\tslide.removeEventListener( 'click', this.onSlideClicked, true );\n\t\t\t} );\n\n\t\t\t// Clean up changes made to backgrounds\n\t\t\tqueryAll( this.Reveal.getBackgroundsElement(), '.slide-background' ).forEach( background => {\n\t\t\t\ttransformElement( background, '' );\n\t\t\t} );\n\n\t\t\tthis.Reveal.transformSlides( { overview: '' } );\n\n\t\t\tconst indices = this.Reveal.getIndices();\n\n\t\t\tthis.Reveal.slide( indices.h, indices.v );\n\t\t\tthis.Reveal.layout();\n\t\t\tthis.Reveal.cueAutoSlide();\n\n\t\t\t// Notify observers of the overview hiding\n\t\t\tthis.Reveal.dispatchEvent({\n\t\t\t\ttype: 'overviewhidden',\n\t\t\t\tdata: {\n\t\t\t\t\t'indexh': indices.h,\n\t\t\t\t\t'indexv': indices.v,\n\t\t\t\t\t'currentSlide': this.Reveal.getCurrentSlide()\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t}\n\n\t/**\n\t * Toggles the slide overview mode on and off.\n\t *\n\t * @param {Boolean} [override] Flag which overrides the\n\t * toggle logic and forcibly sets the desired state. True means\n\t * overview is open, false means it's closed.\n\t */\n\ttoggle( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? this.activate() : this.deactivate();\n\t\t}\n\t\telse {\n\t\t\tthis.isActive() ? this.deactivate() : this.activate();\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if the overview is currently active.\n\t *\n\t * @return {Boolean} true if the overview is active,\n\t * false otherwise\n\t */\n\tisActive() {\n\n\t\treturn this.active;\n\n\t}\n\n\t/**\n\t * Invoked when a slide is and we're in the overview.\n\t *\n\t * @param {object} event\n\t */\n\tonSlideClicked( event ) {\n\n\t\tif( this.isActive() ) {\n\t\t\tevent.preventDefault();\n\n\t\t\tlet element = event.target;\n\n\t\t\twhile( element && !element.nodeName.match( /section/gi ) ) {\n\t\t\t\telement = element.parentNode;\n\t\t\t}\n\n\t\t\tif( element && !element.classList.contains( 'disabled' ) ) {\n\n\t\t\t\tthis.deactivate();\n\n\t\t\t\tif( element.nodeName.match( /section/gi ) ) {\n\t\t\t\t\tlet h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),\n\t\t\t\t\t\tv = parseInt( element.getAttribute( 'data-index-v' ), 10 );\n\n\t\t\t\t\tthis.Reveal.slide( h, v );\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t}\n\n}","import { enterFullscreen } from '../utils/util.js'\n\n/**\n * Handles all reveal.js keyboard interactions.\n */\nexport default class Keyboard {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// A key:value map of keyboard keys and descriptions of\n\t\t// the actions they trigger\n\t\tthis.shortcuts = {};\n\n\t\t// Holds custom key code mappings\n\t\tthis.bindings = {};\n\n\t\tthis.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.navigationMode === 'linear' ) {\n\t\t\tthis.shortcuts['→ , ↓ , SPACE , N , L , J'] = 'Next slide';\n\t\t\tthis.shortcuts['← , ↑ , P , H , K'] = 'Previous slide';\n\t\t}\n\t\telse {\n\t\t\tthis.shortcuts['N , SPACE'] = 'Next slide';\n\t\t\tthis.shortcuts['P , Shift SPACE'] = 'Previous slide';\n\t\t\tthis.shortcuts['← , H'] = 'Navigate left';\n\t\t\tthis.shortcuts['→ , L'] = 'Navigate right';\n\t\t\tthis.shortcuts['↑ , K'] = 'Navigate up';\n\t\t\tthis.shortcuts['↓ , J'] = 'Navigate down';\n\t\t}\n\n\t\tthis.shortcuts['Alt + ←/↑/→/↓'] = 'Navigate without fragments';\n\t\tthis.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';\n\t\tthis.shortcuts['B , .'] = 'Pause';\n\t\tthis.shortcuts['F'] = 'Fullscreen';\n\t\tthis.shortcuts['G'] = 'Jump to slide';\n\t\tthis.shortcuts['ESC, O'] = 'Slide overview';\n\n\t}\n\n\t/**\n\t * Starts listening for keyboard events.\n\t */\n\tbind() {\n\n\t\tdocument.addEventListener( 'keydown', this.onDocumentKeyDown, false );\n\n\t}\n\n\t/**\n\t * Stops listening for keyboard events.\n\t */\n\tunbind() {\n\n\t\tdocument.removeEventListener( 'keydown', this.onDocumentKeyDown, false );\n\n\t}\n\n\t/**\n\t * Add a custom key binding with optional description to\n\t * be added to the help screen.\n\t */\n\taddKeyBinding( binding, callback ) {\n\n\t\tif( typeof binding === 'object' && binding.keyCode ) {\n\t\t\tthis.bindings[binding.keyCode] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: binding.key,\n\t\t\t\tdescription: binding.description\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tthis.bindings[binding] = {\n\t\t\t\tcallback: callback,\n\t\t\t\tkey: null,\n\t\t\t\tdescription: null\n\t\t\t};\n\t\t}\n\n\t}\n\n\t/**\n\t * Removes the specified custom key binding.\n\t */\n\tremoveKeyBinding( keyCode ) {\n\n\t\tdelete this.bindings[keyCode];\n\n\t}\n\n\t/**\n\t * Programmatically triggers a keyboard event\n\t *\n\t * @param {int} keyCode\n\t */\n\ttriggerKey( keyCode ) {\n\n\t\tthis.onDocumentKeyDown( { keyCode } );\n\n\t}\n\n\t/**\n\t * Registers a new shortcut to include in the help overlay\n\t *\n\t * @param {String} key\n\t * @param {String} value\n\t */\n\tregisterKeyboardShortcut( key, value ) {\n\n\t\tthis.shortcuts[key] = value;\n\n\t}\n\n\tgetShortcuts() {\n\n\t\treturn this.shortcuts;\n\n\t}\n\n\tgetBindings() {\n\n\t\treturn this.bindings;\n\n\t}\n\n\t/**\n\t * Handler for the document level 'keydown' event.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentKeyDown( event ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// If there's a condition specified and it returns false,\n\t\t// ignore this event\n\t\tif( typeof config.keyboardCondition === 'function' && config.keyboardCondition(event) === false ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If keyboardCondition is set, only capture keyboard events\n\t\t// for embedded decks when they are focused\n\t\tif( config.keyboardCondition === 'focused' && !this.Reveal.isFocused() ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Shorthand\n\t\tlet keyCode = event.keyCode;\n\n\t\t// Remember if auto-sliding was paused so we can toggle it\n\t\tlet autoSlideWasPaused = !this.Reveal.isAutoSliding();\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\t// Is there a focused element that could be using the keyboard?\n\t\tlet activeElementIsCE = document.activeElement && document.activeElement.isContentEditable === true;\n\t\tlet activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );\n\t\tlet activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);\n\n\t\t// Whitelist certain modifiers for slide navigation shortcuts\n\t\tlet keyCodeUsesModifier = [32, 37, 38, 39, 40, 63, 78, 80, 191].indexOf( event.keyCode ) !== -1;\n\n\t\t// Prevent all other events when a modifier is pressed\n\t\tlet unusedModifier = \t!( keyCodeUsesModifier && event.shiftKey || event.altKey ) &&\n\t\t\t\t\t\t\t\t( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );\n\n\t\t// Disregard the event if there's a focused element or a\n\t\t// keyboard modifier key is present\n\t\tif( activeElementIsCE || activeElementIsInput || activeElementIsNotes || unusedModifier ) return;\n\n\t\t// While paused only allow resume keyboard events; 'b', 'v', '.'\n\t\tlet resumeKeyCodes = [66,86,190,191,112];\n\t\tlet key;\n\n\t\t// Custom key bindings for togglePause should be able to resume\n\t\tif( typeof config.keyboard === 'object' ) {\n\t\t\tfor( key in config.keyboard ) {\n\t\t\t\tif( config.keyboard[key] === 'togglePause' ) {\n\t\t\t\t\tresumeKeyCodes.push( parseInt( key, 10 ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif( this.Reveal.isOverlayOpen() && ![\"Escape\", \"f\", \"c\", \"b\", \".\"].includes(event.key) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif( this.Reveal.isPaused() && resumeKeyCodes.indexOf( keyCode ) === -1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Use linear navigation if we're configured to OR if\n\t\t// the presentation is one-dimensional\n\t\tlet useLinearMode = config.navigationMode === 'linear' || !this.Reveal.hasHorizontalSlides() || !this.Reveal.hasVerticalSlides();\n\n\t\tlet triggered = false;\n\n\t\t// 1. User defined key bindings\n\t\tif( typeof config.keyboard === 'object' ) {\n\n\t\t\tfor( key in config.keyboard ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet value = config.keyboard[ key ];\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof value === 'function' ) {\n\t\t\t\t\t\tvalue.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof value === 'string' && typeof this.Reveal[ value ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ value ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// 2. Registered custom key bindings\n\t\tif( triggered === false ) {\n\n\t\t\tfor( key in this.bindings ) {\n\n\t\t\t\t// Check if this binding matches the pressed key\n\t\t\t\tif( parseInt( key, 10 ) === keyCode ) {\n\n\t\t\t\t\tlet action = this.bindings[ key ].callback;\n\n\t\t\t\t\t// Callback function\n\t\t\t\t\tif( typeof action === 'function' ) {\n\t\t\t\t\t\taction.apply( null, [ event ] );\n\t\t\t\t\t}\n\t\t\t\t\t// String shortcuts to reveal.js API\n\t\t\t\t\telse if( typeof action === 'string' && typeof this.Reveal[ action ] === 'function' ) {\n\t\t\t\t\t\tthis.Reveal[ action ].call();\n\t\t\t\t\t}\n\n\t\t\t\t\ttriggered = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 3. System defined key bindings\n\t\tif( triggered === false ) {\n\n\t\t\t// Assume true and try to prove false\n\t\t\ttriggered = true;\n\n\t\t\t// P, PAGE UP\n\t\t\tif( keyCode === 80 || keyCode === 33 ) {\n\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t}\n\t\t\t// N, PAGE DOWN\n\t\t\telse if( keyCode === 78 || keyCode === 34 ) {\n\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t}\n\t\t\t// H, LEFT\n\t\t\telse if( keyCode === 72 || keyCode === 37 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.left({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// L, RIGHT\n\t\t\telse if( keyCode === 76 || keyCode === 39 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.right({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// K, UP\n\t\t\telse if( keyCode === 75 || keyCode === 38 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, 0 );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.up({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// J, DOWN\n\t\t\telse if( keyCode === 74 || keyCode === 40 ) {\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.slide( undefined, Number.MAX_VALUE );\n\t\t\t\t}\n\t\t\t\telse if( !this.Reveal.overview.isActive() && useLinearMode ) {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.down({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// HOME\n\t\t\telse if( keyCode === 36 ) {\n\t\t\t\tthis.Reveal.slide( 0 );\n\t\t\t}\n\t\t\t// END\n\t\t\telse if( keyCode === 35 ) {\n\t\t\t\tthis.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );\n\t\t\t}\n\t\t\t// SPACE\n\t\t\telse if( keyCode === 32 ) {\n\t\t\t\tif( this.Reveal.overview.isActive() ) {\n\t\t\t\t\tthis.Reveal.overview.deactivate();\n\t\t\t\t}\n\t\t\t\tif( event.shiftKey ) {\n\t\t\t\t\tthis.Reveal.prev({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.Reveal.next({skipFragments: event.altKey});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS \"BLACK SCREEN\" BUTTON\n\t\t\telse if( [58, 59, 66, 86, 190].includes( keyCode ) || ( keyCode === 191 && !event.shiftKey ) ) {\n\t\t\t\tthis.Reveal.togglePause();\n\t\t\t}\n\t\t\t// F\n\t\t\telse if( keyCode === 70 ) {\n\t\t\t\tenterFullscreen( config.embedded ? this.Reveal.getViewportElement() : document.documentElement );\n\t\t\t}\n\t\t\t// A\n\t\t\telse if( keyCode === 65 ) {\n\t\t\t\tif( config.autoSlideStoppable ) {\n\t\t\t\t\tthis.Reveal.toggleAutoSlide( autoSlideWasPaused );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G\n\t\t\telse if( keyCode === 71 ) {\n\t\t\t\tif( config.jumpToSlide ) {\n\t\t\t\t\tthis.Reveal.toggleJumpToSlide();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// C\n\t\t\telse if( keyCode === 67 && this.Reveal.isOverlayOpen() ) {\n\t\t\t\tthis.Reveal.closeOverlay();\n\t\t\t}\n\t\t\t// ?\n\t\t\telse if( ( keyCode === 63 || keyCode === 191 ) && event.shiftKey ) {\n\t\t\t\tthis.Reveal.toggleHelp();\n\t\t\t}\n\t\t\t// F1\n\t\t\telse if( keyCode === 112 ) {\n\t\t\t\tthis.Reveal.toggleHelp();\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttriggered = false;\n\t\t\t}\n\n\t\t}\n\n\t\t// If the input resulted in a triggered action we should prevent\n\t\t// the browsers default behavior\n\t\tif( triggered ) {\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\t\t// ESC or O key\n\t\telse if( keyCode === 27 || keyCode === 79 ) {\n\t\t\tif( this.Reveal.closeOverlay() === false ) {\n\t\t\t\tthis.Reveal.overview.toggle();\n\t\t\t}\n\n\t\t\tevent.preventDefault && event.preventDefault();\n\t\t}\n\n\t\t// If auto-sliding is enabled we need to cue up\n\t\t// another timeout\n\t\tthis.Reveal.cueAutoSlide();\n\n\t}\n\n}\n","/**\n * Reads and writes the URL based on reveal.js' current state.\n */\nexport default class Location {\n\n\t// The minimum number of milliseconds that must pass between\n\t// calls to history.replaceState\n\tMAX_REPLACE_STATE_FREQUENCY = 1000\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Delays updates to the URL due to a Chrome thumbnailer bug\n\t\tthis.writeURLTimeout = 0;\n\n\t\tthis.replaceStateTimestamp = 0;\n\n\t\tthis.onWindowHashChange = this.onWindowHashChange.bind( this );\n\n\t}\n\n\tbind() {\n\n\t\twindow.addEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\tunbind() {\n\n\t\twindow.removeEventListener( 'hashchange', this.onWindowHashChange, false );\n\n\t}\n\n\t/**\n\t * Returns the slide indices for the given hash link.\n\t *\n\t * @param {string} [hash] the hash string that we want to\n\t * find the indices for\n\t *\n\t * @returns slide indices or null\n\t */\n\tgetIndicesFromHash( hash=window.location.hash, options={} ) {\n\n\t\t// Attempt to parse the hash as either an index or name\n\t\tlet name = hash.replace( /^#\\/?/, '' );\n\t\tlet bits = name.split( '/' );\n\n\t\t// If the first bit is not fully numeric and there is a name we\n\t\t// can assume that this is a named link\n\t\tif( !/^[0-9]*$/.test( bits[0] ) && name.length ) {\n\t\t\tlet slide;\n\n\t\t\tlet f;\n\n\t\t\t// Parse named links with fragments (#/named-link/2)\n\t\t\tif( /\\/[-\\d]+$/g.test( name ) ) {\n\t\t\t\tf = parseInt( name.split( '/' ).pop(), 10 );\n\t\t\t\tf = isNaN(f) ? undefined : f;\n\t\t\t\tname = name.split( '/' ).shift();\n\t\t\t}\n\n\t\t\t// Ensure the named link is a valid HTML ID attribute\n\t\t\ttry {\n\t\t\t\tslide = document\n\t\t\t\t\t.getElementById( decodeURIComponent( name ) )\n\t\t\t\t\t.closest('.slides section');\n\t\t\t}\n\t\t\tcatch ( error ) { }\n\n\t\t\tif( slide ) {\n\t\t\t\treturn { ...this.Reveal.getIndices( slide ), f };\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst config = this.Reveal.getConfig();\n\t\t\tlet hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0;\n\n\t\t\t// Read the index components of the hash\n\t\t\tlet h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tv = ( parseInt( bits[1], 10 ) - hashIndexBase ) || 0,\n\t\t\t\tf;\n\n\t\t\tif( config.fragmentInURL ) {\n\t\t\t\tf = parseInt( bits[2], 10 );\n\t\t\t\tif( isNaN( f ) ) {\n\t\t\t\t\tf = undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { h, v, f };\n\t\t}\n\n\t\t// The hash couldn't be parsed or no matching named link was found\n\t\treturn null\n\n\t}\n\n\t/**\n\t * Reads the current URL (hash) and navigates accordingly.\n\t */\n\treadURL() {\n\n\t\tconst currentIndices = this.Reveal.getIndices();\n\t\tconst newIndices = this.getIndicesFromHash();\n\n\t\tif( newIndices ) {\n\t\t\tif( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {\n\t\t\t\t\tthis.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );\n\t\t\t}\n\t\t}\n\t\t// If no new indices are available, we're trying to navigate to\n\t\t// a slide hash that does not exist\n\t\telse {\n\t\t\tthis.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the page URL (hash) to reflect the current\n\t * state.\n\t *\n\t * @param {number} delay The time in ms to wait before\n\t * writing the hash\n\t */\n\twriteURL( delay ) {\n\n\t\tlet config = this.Reveal.getConfig();\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\n\t\t// Make sure there's never more than one timeout running\n\t\tclearTimeout( this.writeURLTimeout );\n\n\t\t// If a delay is specified, timeout this call\n\t\tif( typeof delay === 'number' ) {\n\t\t\tthis.writeURLTimeout = setTimeout( this.writeURL, delay );\n\t\t}\n\t\telse if( currentSlide ) {\n\n\t\t\tlet hash = this.getHash();\n\n\t\t\t// If we're configured to push to history OR the history\n\t\t\t// API is not available.\n\t\t\tif( config.history ) {\n\t\t\t\twindow.location.hash = hash;\n\t\t\t}\n\t\t\t// If we're configured to reflect the current slide in the\n\t\t\t// URL without pushing to history.\n\t\t\telse if( config.hash ) {\n\t\t\t\t// If the hash is empty, don't add it to the URL\n\t\t\t\tif( hash === '/' ) {\n\t\t\t\t\tthis.debouncedReplaceState( window.location.pathname + window.location.search );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.debouncedReplaceState( '#' + hash );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// UPDATE: The below nuking of all hash changes breaks\n\t\t\t// anchors on pages where reveal.js is running. Removed\n\t\t\t// in 4.0. Why was it here in the first place? ¯\\_(ツ)_/¯\n\t\t\t//\n\t\t\t// If history and hash are both disabled, a hash may still\n\t\t\t// be added to the URL by clicking on a href with a hash\n\t\t\t// target. Counter this by always removing the hash.\n\t\t\t// else {\n\t\t\t// \twindow.history.replaceState( null, null, window.location.pathname + window.location.search );\n\t\t\t// }\n\n\t\t}\n\n\t}\n\n\treplaceState( url ) {\n\n\t\twindow.history.replaceState( null, null, url );\n\t\tthis.replaceStateTimestamp = Date.now();\n\n\t}\n\n\tdebouncedReplaceState( url ) {\n\n\t\tclearTimeout( this.replaceStateTimeout );\n\n\t\tif( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {\n\t\t\tthis.replaceState( url );\n\t\t}\n\t\telse {\n\t\t\tthis.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );\n\t\t}\n\n\t}\n\n\t/**\n\t * Return a hash URL that will resolve to the given slide location.\n\t *\n\t * @param {HTMLElement} [slide=currentSlide] The slide to link to\n\t */\n\tgetHash( slide ) {\n\n\t\tlet url = '/';\n\n\t\t// Attempt to create a named link based on the slide's ID\n\t\tlet s = slide || this.Reveal.getCurrentSlide();\n\t\tlet id = s ? s.getAttribute( 'id' ) : null;\n\t\tif( id ) {\n\t\t\tid = encodeURIComponent( id );\n\t\t}\n\n\t\tlet index = this.Reveal.getIndices( slide );\n\t\tif( !this.Reveal.getConfig().fragmentInURL ) {\n\t\t\tindex.f = undefined;\n\t\t}\n\n\t\t// If the current slide has an ID, use that as a named link,\n\t\t// but we don't support named links with a fragment index\n\t\tif( typeof id === 'string' && id.length ) {\n\t\t\turl = '/' + id;\n\n\t\t\t// If there is also a fragment, append that at the end\n\t\t\t// of the named link, like: #/named-link/2\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\n\t\t}\n\t\t// Otherwise use the /h/v index\n\t\telse {\n\t\t\tlet hashIndexBase = this.Reveal.getConfig().hashOneBasedIndex ? 1 : 0;\n\t\t\tif( index.h > 0 || index.v > 0 || index.f >= 0 ) url += index.h + hashIndexBase;\n\t\t\tif( index.v > 0 || index.f >= 0 ) url += '/' + (index.v + hashIndexBase );\n\t\t\tif( index.f >= 0 ) url += '/' + index.f;\n\t\t}\n\n\t\treturn url;\n\n\t}\n\n\t/**\n\t * Handler for the window level 'hashchange' event.\n\t *\n\t * @param {object} [event]\n\t */\n\tonWindowHashChange( event ) {\n\n\t\tthis.readURL();\n\n\t}\n\n}","import { queryAll, enterFullscreen } from '../utils/util.js'\nimport { isAndroid } from '../utils/device.js'\n\n/**\n * Manages our presentation controls. This includes both\n * the built-in control arrows as well as event monitoring\n * of any elements within the presentation with either of the\n * following helper classes:\n * - .navigate-up\n * - .navigate-right\n * - .navigate-down\n * - .navigate-left\n * - .navigate-next\n * - .navigate-prev\n * - .enter-fullscreen\n */\nexport default class Controls {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onNavigateLeftClicked = this.onNavigateLeftClicked.bind( this );\n\t\tthis.onNavigateRightClicked = this.onNavigateRightClicked.bind( this );\n\t\tthis.onNavigateUpClicked = this.onNavigateUpClicked.bind( this );\n\t\tthis.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );\n\t\tthis.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );\n\t\tthis.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );\n\t\tthis.onEnterFullscreen = this.onEnterFullscreen.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tconst rtl = this.Reveal.getConfig().rtl;\n\t\tconst revealElement = this.Reveal.getRevealElement();\n\n\t\tthis.element = document.createElement( 'aside' );\n\t\tthis.element.className = 'controls';\n\t\tthis.element.innerHTML =\n\t\t\t`
\n\t\t\t
\n\t\t\t
\n\t\t\t
`;\n\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\t// There can be multiple instances of controls throughout the page\n\t\tthis.controlsLeft = queryAll( revealElement, '.navigate-left' );\n\t\tthis.controlsRight = queryAll( revealElement, '.navigate-right' );\n\t\tthis.controlsUp = queryAll( revealElement, '.navigate-up' );\n\t\tthis.controlsDown = queryAll( revealElement, '.navigate-down' );\n\t\tthis.controlsPrev = queryAll( revealElement, '.navigate-prev' );\n\t\tthis.controlsNext = queryAll( revealElement, '.navigate-next' );\n\t\tthis.controlsFullscreen = queryAll( revealElement, '.enter-fullscreen' );\n\n\t\t// The left, right and down arrows in the standard reveal.js controls\n\t\tthis.controlsRightArrow = this.element.querySelector( '.navigate-right' );\n\t\tthis.controlsLeftArrow = this.element.querySelector( '.navigate-left' );\n\t\tthis.controlsDownArrow = this.element.querySelector( '.navigate-down' );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = (\n\t\t\tconfig.controls &&\n\t\t\t(config.controls !== 'speaker-only' || this.Reveal.isSpeakerNotes())\n\t\t) ? 'block' : 'none';\n\n\t\tthis.element.setAttribute( 'data-controls-layout', config.controlsLayout );\n\t\tthis.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );\n\n\t}\n\n\tbind() {\n\n\t\t// Listen to both touch and click events, in case the device\n\t\t// supports both\n\t\tlet pointerEvents = [ 'touchstart', 'click' ];\n\n\t\t// Only support touch for Android, fixes double navigations in\n\t\t// stock browser\n\t\tif( isAndroid ) {\n\t\t\tpointerEvents = [ 'touchstart' ];\n\t\t}\n\n\t\tpointerEvents.forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t\tthis.controlsFullscreen.forEach( el => el.addEventListener( eventName, this.onEnterFullscreen, false ) );\n\t\t} );\n\n\t}\n\n\tunbind() {\n\n\t\t[ 'touchstart', 'click' ].forEach( eventName => {\n\t\t\tthis.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );\n\t\t\tthis.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );\n\t\t\tthis.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );\n\t\t\tthis.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );\n\t\t\tthis.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );\n\t\t\tthis.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );\n\t\t\tthis.controlsFullscreen.forEach( el => el.removeEventListener( eventName, this.onEnterFullscreen, false ) );\n\t\t} );\n\n\t}\n\n\t/**\n\t * Updates the state of all control/navigation arrows.\n\t */\n\tupdate() {\n\n\t\tlet routes = this.Reveal.availableRoutes();\n\n\t\t// Remove the 'enabled' class from all directions\n\t\t[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {\n\t\t\tnode.classList.remove( 'enabled', 'fragmented' );\n\n\t\t\t// Set 'disabled' attribute on all directions\n\t\t\tnode.setAttribute( 'disabled', 'disabled' );\n\t\t} );\n\n\t\t// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons\n\t\tif( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Prev/next buttons\n\t\tif( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\tif( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t// Highlight fragment directions\n\t\tlet currentSlide = this.Reveal.getCurrentSlide();\n\t\tif( currentSlide ) {\n\n\t\t\tlet fragmentsRoutes = this.Reveal.fragments.availableRoutes();\n\n\t\t\t// Always apply fragment decorator to prev/next buttons\n\t\t\tif( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\tif( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\n\t\t\tconst isVerticalStack = this.Reveal.isVerticalSlide( currentSlide );\n\t\t\tconst hasVerticalSiblings = isVerticalStack &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcurrentSlide.parentElement &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcurrentSlide.parentElement.querySelectorAll( ':scope > section' ).length > 1;\n\n\t\t\t// Apply fragment decorators to directional buttons based on\n\t\t\t// what slide axis they are in\n\t\t\tif( isVerticalStack && hasVerticalSiblings ) {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t\tif( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );\n\t\t\t}\n\n\t\t}\n\n\t\tif( this.Reveal.getConfig().controlsTutorial ) {\n\n\t\t\tlet indices = this.Reveal.getIndices();\n\n\t\t\t// Highlight control arrows with an animation to ensure\n\t\t\t// that the viewer knows how to navigate\n\t\t\tif( !this.Reveal.hasNavigatedVertically() && routes.down ) {\n\t\t\t\tthis.controlsDownArrow.classList.add( 'highlight' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.controlsDownArrow.classList.remove( 'highlight' );\n\n\t\t\t\tif( this.Reveal.getConfig().rtl ) {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsLeftArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.add( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.controlsRightArrow.classList.remove( 'highlight' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy() {\n\n\t\tthis.unbind();\n\t\tthis.element.remove();\n\n\t}\n\n\t/**\n\t * Event handlers for navigation control buttons.\n\t */\n\tonNavigateLeftClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.prev();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.left();\n\t\t}\n\n\t}\n\n\tonNavigateRightClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tif( this.Reveal.getConfig().navigationMode === 'linear' ) {\n\t\t\tthis.Reveal.next();\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.right();\n\t\t}\n\n\t}\n\n\tonNavigateUpClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.up();\n\n\t}\n\n\tonNavigateDownClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.down();\n\n\t}\n\n\tonNavigatePrevClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.prev();\n\n\t}\n\n\tonNavigateNextClicked( event ) {\n\n\t\tevent.preventDefault();\n\t\tthis.Reveal.onUserInput();\n\n\t\tthis.Reveal.next();\n\n\t}\n\n\tonEnterFullscreen( event ) {\n\n\t\tconst config = this.Reveal.getConfig();\n\t\tconst viewport = this.Reveal.getViewportElement();\n\n\t\tenterFullscreen( config.embedded ? viewport : viewport.parentElement );\n\n\t}\n\n}","/**\n * Creates a visual progress bar for the presentation.\n */\nexport default class Progress {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onProgressClicked = this.onProgressClicked.bind( this );\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'progress';\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t\tthis.bar = document.createElement( 'span' );\n\t\tthis.element.appendChild( this.bar );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tthis.element.style.display = config.progress ? 'block' : 'none';\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.addEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tif ( this.Reveal.getConfig().progress && this.element ) {\n\t\t\tthis.element.removeEventListener( 'click', this.onProgressClicked, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the progress bar to reflect the current slide.\n\t */\n\tupdate() {\n\n\t\t// Update progress if enabled\n\t\tif( this.Reveal.getConfig().progress && this.bar ) {\n\n\t\t\tlet scale = this.Reveal.getProgress();\n\n\t\t\t// Don't fill the progress bar if there's only one slide\n\t\t\tif( this.Reveal.getTotalSlides() < 2 ) {\n\t\t\t\tscale = 0;\n\t\t\t}\n\n\t\t\tthis.bar.style.transform = 'scaleX('+ scale +')';\n\n\t\t}\n\n\t}\n\n\tgetMaxWidth() {\n\n\t\treturn this.Reveal.getRevealElement().offsetWidth;\n\n\t}\n\n\t/**\n\t * Clicking on the progress bar results in a navigation to the\n\t * closest approximate horizontal slide using this equation:\n\t *\n\t * ( clickX / presentationWidth ) * numberOfSlides\n\t *\n\t * @param {object} event\n\t */\n\tonProgressClicked( event ) {\n\n\t\tthis.Reveal.onUserInput( event );\n\n\t\tevent.preventDefault();\n\n\t\tlet slides = this.Reveal.getSlides();\n\t\tlet slidesTotal = slides.length;\n\t\tlet slideIndex = Math.floor( ( event.clientX / this.getMaxWidth() ) * slidesTotal );\n\n\t\tif( this.Reveal.getConfig().rtl ) {\n\t\t\tslideIndex = slidesTotal - slideIndex;\n\t\t}\n\n\t\tlet targetIndices = this.Reveal.getIndices(slides[slideIndex]);\n\t\tthis.Reveal.slide( targetIndices.h, targetIndices.v );\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.element.remove();\n\n\t}\n\n}","/**\n * Handles hiding of the pointer/cursor when inactive.\n */\nexport default class Pointer {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Throttles mouse wheel navigation\n\t\tthis.lastMouseWheelStep = 0;\n\n\t\t// Is the mouse pointer currently hidden from view\n\t\tthis.cursorHidden = false;\n\n\t\t// Timeout used to determine when the cursor is inactive\n\t\tthis.cursorInactiveTimeout = 0;\n\n\t\tthis.onDocumentCursorActive = this.onDocumentCursorActive.bind( this );\n\t\tthis.onDocumentMouseScroll = this.onDocumentMouseScroll.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.mouseWheel ) {\n\t\t\tdocument.addEventListener( 'wheel', this.onDocumentMouseScroll, false );\n\t\t}\n\t\telse {\n\t\t\tdocument.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );\n\t\t}\n\n\t\t// Auto-hide the mouse pointer when its inactive\n\t\tif( config.hideInactiveCursor ) {\n\t\t\tdocument.addEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.addEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\t\telse {\n\t\t\tthis.showCursor();\n\n\t\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\t\t}\n\n\t}\n\n\t/**\n\t * Shows the mouse pointer after it has been hidden with\n\t * #hideCursor.\n\t */\n\tshowCursor() {\n\n\t\tif( this.cursorHidden ) {\n\t\t\tthis.cursorHidden = false;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = '';\n\t\t}\n\n\t}\n\n\t/**\n\t * Hides the mouse pointer when it's on top of the .reveal\n\t * container.\n\t */\n\thideCursor() {\n\n\t\tif( this.cursorHidden === false ) {\n\t\t\tthis.cursorHidden = true;\n\t\t\tthis.Reveal.getRevealElement().style.cursor = 'none';\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.showCursor();\n\n\t\tdocument.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );\n\t\tdocument.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );\n\t\tdocument.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );\n\n\t}\n\n\t/**\n\t * Called whenever there is mouse input at the document level\n\t * to determine if the cursor is active or not.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentCursorActive( event ) {\n\n\t\tthis.showCursor();\n\n\t\tclearTimeout( this.cursorInactiveTimeout );\n\n\t\tthis.cursorInactiveTimeout = setTimeout( this.hideCursor.bind( this ), this.Reveal.getConfig().hideCursorTime );\n\n\t}\n\n\t/**\n\t * Handles mouse wheel scrolling, throttled to avoid skipping\n\t * multiple slides.\n\t *\n\t * @param {object} event\n\t */\n\tonDocumentMouseScroll( event ) {\n\n\t\tif( Date.now() - this.lastMouseWheelStep > 1000 ) {\n\n\t\t\tthis.lastMouseWheelStep = Date.now();\n\n\t\t\tlet delta = event.detail || -event.wheelDelta;\n\t\t\tif( delta > 0 ) {\n\t\t\t\tthis.Reveal.next();\n\t\t\t}\n\t\t\telse if( delta < 0 ) {\n\t\t\t\tthis.Reveal.prev();\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}\n","/**\n * Loads a JavaScript file from the given URL and executes it.\n *\n * @param {string} url Address of the .js file to load\n * @param {function} callback Method to invoke when the script\n * has loaded and executed\n */\nexport const loadScript = ( url, callback ) => {\n\n\tconst script = document.createElement( 'script' );\n\tscript.type = 'text/javascript';\n\tscript.async = false;\n\tscript.defer = false;\n\tscript.src = url;\n\n\tif( typeof callback === 'function' ) {\n\n\t\t// Success callback\n\t\tscript.onload = script.onreadystatechange = event => {\n\t\t\tif( event.type === 'load' || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t// Kill event listeners\n\t\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\t\tcallback();\n\n\t\t\t}\n\t\t};\n\n\t\t// Error callback\n\t\tscript.onerror = err => {\n\n\t\t\t// Kill event listeners\n\t\t\tscript.onload = script.onreadystatechange = script.onerror = null;\n\n\t\t\tcallback( new Error( 'Failed loading script: ' + script.src + '\\n' + err ) );\n\n\t\t};\n\n\t}\n\n\t// Append the script at the end of \n\tconst head = document.querySelector( 'head' );\n\thead.insertBefore( script, head.lastChild );\n\n}","import { loadScript } from '../utils/loader.js'\n\n/**\n * Manages loading and registering of reveal.js plugins.\n */\nexport default class Plugins {\n\n\tconstructor( reveal ) {\n\n\t\tthis.Reveal = reveal;\n\n\t\t// Flags our current state (idle -> loading -> loaded)\n\t\tthis.state = 'idle';\n\n\t\t// An id:instance map of currently registered plugins\n\t\tthis.registeredPlugins = {};\n\n\t\tthis.asyncDependencies = [];\n\n\t}\n\n\t/**\n\t * Loads reveal.js dependencies, registers and\n\t * initializes plugins.\n\t *\n\t * Plugins are direct references to a reveal.js plugin\n\t * object that we register and initialize after any\n\t * synchronous dependencies have loaded.\n\t *\n\t * Dependencies are defined via the 'dependencies' config\n\t * option and will be loaded prior to starting reveal.js.\n\t * Some dependencies may have an 'async' flag, if so they\n\t * will load after reveal.js has been started up.\n\t */\n\tload( plugins, dependencies ) {\n\n\t\tthis.state = 'loading';\n\n\t\tplugins.forEach( this.registerPlugin.bind( this ) );\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet scripts = [],\n\t\t\t\tscriptsToLoad = 0;\n\n\t\t\tdependencies.forEach( s => {\n\t\t\t\t// Load if there's no condition or the condition is truthy\n\t\t\t\tif( !s.condition || s.condition() ) {\n\t\t\t\t\tif( s.async ) {\n\t\t\t\t\t\tthis.asyncDependencies.push( s );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tscripts.push( s );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tif( scripts.length ) {\n\t\t\t\tscriptsToLoad = scripts.length;\n\n\t\t\t\tconst scriptLoadedCallback = (s) => {\n\t\t\t\t\tif( s && typeof s.callback === 'function' ) s.callback();\n\n\t\t\t\t\tif( --scriptsToLoad === 0 ) {\n\t\t\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Load synchronous scripts\n\t\t\t\tscripts.forEach( s => {\n\t\t\t\t\tif( typeof s.id === 'string' ) {\n\t\t\t\t\t\tthis.registerPlugin( s );\n\t\t\t\t\t\tscriptLoadedCallback( s );\n\t\t\t\t\t}\n\t\t\t\t\telse if( typeof s.src === 'string' ) {\n\t\t\t\t\t\tloadScript( s.src, () => scriptLoadedCallback(s) );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tconsole.warn( 'Unrecognized plugin format', s );\n\t\t\t\t\t\tscriptLoadedCallback();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.initPlugins().then( resolve );\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Initializes our plugins and waits for them to be ready\n\t * before proceeding.\n\t */\n\tinitPlugins() {\n\n\t\treturn new Promise( resolve => {\n\n\t\t\tlet pluginValues = Object.values( this.registeredPlugins );\n\t\t\tlet pluginsToInitialize = pluginValues.length;\n\n\t\t\t// If there are no plugins, skip this step\n\t\t\tif( pluginsToInitialize === 0 ) {\n\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t}\n\t\t\t// ... otherwise initialize plugins\n\t\t\telse {\n\n\t\t\t\tlet initNextPlugin;\n\n\t\t\t\tlet afterPlugInitialized = () => {\n\t\t\t\t\tif( --pluginsToInitialize === 0 ) {\n\t\t\t\t\t\tthis.loadAsync().then( resolve );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tinitNextPlugin();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet i = 0;\n\n\t\t\t\t// Initialize plugins serially\n\t\t\t\tinitNextPlugin = () => {\n\n\t\t\t\t\tlet plugin = pluginValues[i++];\n\n\t\t\t\t\t// If the plugin has an 'init' method, invoke it\n\t\t\t\t\tif( typeof plugin.init === 'function' ) {\n\t\t\t\t\t\tlet promise = plugin.init( this.Reveal );\n\n\t\t\t\t\t\t// If the plugin returned a Promise, wait for it\n\t\t\t\t\t\tif( promise && typeof promise.then === 'function' ) {\n\t\t\t\t\t\t\tpromise.then( afterPlugInitialized );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tafterPlugInitialized();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tinitNextPlugin();\n\n\t\t\t}\n\n\t\t} )\n\n\t}\n\n\t/**\n\t * Loads all async reveal.js dependencies.\n\t */\n\tloadAsync() {\n\n\t\tthis.state = 'loaded';\n\n\t\tif( this.asyncDependencies.length ) {\n\t\t\tthis.asyncDependencies.forEach( s => {\n\t\t\t\tloadScript( s.src, s.callback );\n\t\t\t} );\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n\t/**\n\t * Registers a new plugin with this reveal.js instance.\n\t *\n\t * reveal.js waits for all registered plugins to initialize\n\t * before considering itself ready, as long as the plugin\n\t * is registered before calling `Reveal.initialize()`.\n\t */\n\tregisterPlugin( plugin ) {\n\n\t\t// Backwards compatibility to make reveal.js ~3.9.0\n\t\t// plugins work with reveal.js 4.0.0\n\t\tif( arguments.length === 2 && typeof arguments[0] === 'string' ) {\n\t\t\tplugin = arguments[1];\n\t\t\tplugin.id = arguments[0];\n\t\t}\n\t\t// Plugin can optionally be a function which we call\n\t\t// to create an instance of the plugin\n\t\telse if( typeof plugin === 'function' ) {\n\t\t\tplugin = plugin();\n\t\t}\n\n\t\tlet id = plugin.id;\n\n\t\tif( typeof id !== 'string' ) {\n\t\t\tconsole.warn( 'Unrecognized plugin format; can\\'t find plugin.id', plugin );\n\t\t}\n\t\telse if( this.registeredPlugins[id] === undefined ) {\n\t\t\tthis.registeredPlugins[id] = plugin;\n\n\t\t\t// If a plugin is registered after reveal.js is loaded,\n\t\t\t// initialize it right away\n\t\t\tif( this.state === 'loaded' && typeof plugin.init === 'function' ) {\n\t\t\t\tplugin.init( this.Reveal );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconsole.warn( 'reveal.js: \"'+ id +'\" plugin has already been registered' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if a specific plugin has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\thasPlugin( id ) {\n\n\t\treturn !!this.registeredPlugins[id];\n\n\t}\n\n\t/**\n\t * Returns the specific plugin instance, if a plugin\n\t * with the given ID has been registered.\n\t *\n\t * @param {String} id Unique plugin identifier\n\t */\n\tgetPlugin( id ) {\n\n\t\treturn this.registeredPlugins[id];\n\n\t}\n\n\tgetRegisteredPlugins() {\n\n\t\treturn this.registeredPlugins;\n\n\t}\n\n\tdestroy() {\n\n\t\tObject.values( this.registeredPlugins ).forEach( plugin => {\n\t\t\tif( typeof plugin.destroy === 'function' ) {\n\t\t\t\tplugin.destroy();\n\t\t\t}\n\t\t} );\n\n\t\tthis.registeredPlugins = {};\n\t\tthis.asyncDependencies = [];\n\n\t}\n\n}\n","/**\n * Handles the display of reveal.js' overlay elements used\n * to preview iframes, images & videos.\n */\nexport default class Overlay {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onSlidesClicked = this.onSlidesClicked.bind( this );\n\n\t\tthis.iframeTriggerSelector = null;\n\t\tthis.mediaTriggerSelector = '[data-preview-image], [data-preview-video]';\n\n\t\tthis.state = {};\n\n\t}\n\n\tupdate() {\n\n\t\t// Enable link previews globally\n\t\tif( this.Reveal.getConfig().previewLinks ) {\n\t\t\tthis.iframeTriggerSelector = 'a[href]:not([data-preview-link=false]), [data-preview-link]:not(a):not([data-preview-link=false])';\n\t\t}\n\t\t// Enable link previews for individual elements\n\t\telse {\n\t\t\tthis.iframeTriggerSelector = '[data-preview-link]:not([data-preview-link=false])';\n\t\t}\n\n\t\tconst hasLinkPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.iframeTriggerSelector ).length > 0;\n\t\tconst hasMediaPreviews = this.Reveal.getSlidesElement().querySelectorAll( this.mediaTriggerSelector ).length > 0;\n\n\t\t// Only add the listener when there are previewable elements in the slides\n\t\tif( hasLinkPreviews || hasMediaPreviews ) {\n\t\t\tthis.Reveal.getSlidesElement().addEventListener( 'click', this.onSlidesClicked, false );\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.getSlidesElement().removeEventListener( 'click', this.onSlidesClicked, false );\n\t\t}\n\n\t}\n\n\tcreateOverlay( className ) {\n\n\t\tthis.dom = document.createElement( 'div' );\n\t\tthis.dom.classList.add( 'r-overlay' );\n\t\tthis.dom.classList.add( className );\n\n\t\tthis.viewport = document.createElement( 'div' );\n\t\tthis.viewport.classList.add( 'r-overlay-viewport' );\n\n\t\tthis.dom.appendChild( this.viewport );\n\t\tthis.Reveal.getRevealElement().appendChild( this.dom );\n\n\t}\n\n\t/**\n\t * Opens a lightbox that previews the target URL.\n\t *\n\t * @param {string} url - url for lightbox iframe src\n\t */\n\tpreviewIframe( url ) {\n\n\t\tthis.close();\n\n\t\tthis.state.previewIframe = url;\n\n\t\tthis.createOverlay( 'r-overlay-preview' );\n\t\tthis.dom.dataset.state = 'loading';\n\n\t\tthis.viewport.innerHTML =\n\t\t\t`\n\t\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\tUnable to load iframe. This is likely due to the site's policy (x-frame-options). \n\t\t\t\t \n\t\t\t
`;\n\n\t\tthis.dom.querySelector( 'iframe' ).addEventListener( 'load', event => {\n\t\t\tthis.dom.dataset.state = 'loaded';\n\t\t}, false );\n\n\t\tthis.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {\n\t\t\tthis.close();\n\t\t\tevent.preventDefault();\n\t\t}, false );\n\n\t\tthis.dom.querySelector( '.r-overlay-external' ).addEventListener( 'click', event => {\n\t\t\tthis.close();\n\t\t}, false );\n\n\t\tthis.Reveal.dispatchEvent({ type: 'previewiframe', data: { url } });\n\n\t}\n\n\t/**\n\t * Opens a lightbox window that provides a larger view of the\n\t * given image/video.\n\t *\n\t * @param {string} url - url to the image/video to preview\n\t * @param {image|video} mediaType\n\t * @param {string} [fitMode] - the fit mode to use for the preview\n\t */\n\tpreviewMedia( url, mediaType, fitMode ) {\n\n\t\tif( mediaType !== 'image' && mediaType !== 'video' ) {\n\t\t\tconsole.warn( 'Please specify a valid media type to preview (image|video)' );\n\t\t\treturn;\n\t\t}\n\n\t\tthis.close();\n\n\t\tfitMode = fitMode || 'scale-down';\n\n\t\tthis.createOverlay( 'r-overlay-preview' );\n\t\tthis.dom.dataset.state = 'loading';\n\t\tthis.dom.dataset.previewFit = fitMode;\n\n\t\tthis.viewport.innerHTML =\n\t\t\t`\n\t\t\t
\n\t\t\t
`;\n\n\t\tconst contentElement = this.dom.querySelector( '.r-overlay-content' );\n\n\t\tif( mediaType === 'image' ) {\n\n\t\t\tthis.state = { previewImage: url, previewFit: fitMode }\n\n\t\t\tconst img = document.createElement( 'img', {} );\n\t\t\timg.src = url;\n\t\t\tcontentElement.appendChild( img );\n\n\t\t\timg.addEventListener( 'load', () => {\n\t\t\t\tthis.dom.dataset.state = 'loaded';\n\t\t\t}, false );\n\n\t\t\timg.addEventListener( 'error', () => {\n\t\t\t\tthis.dom.dataset.state = 'error';\n\t\t\t\tcontentElement.innerHTML =\n\t\t\t\t\t\t`Unable to load image. `\n\t\t\t}, false );\n\n\t\t\t// Hide image overlays when clicking outside the overlay\n\t\t\tthis.dom.style.cursor = 'zoom-out';\n\t\t\tthis.dom.addEventListener( 'click', ( event ) => {\n\t\t\t\tthis.close();\n\t\t\t}, false );\n\n\t\t\tthis.Reveal.dispatchEvent({ type: 'previewimage', data: { url } });\n\n\t\t}\n\t\telse if( mediaType === 'video' ) {\n\n\t\t\tthis.state = { previewVideo: url, previewFit: fitMode }\n\n\t\t\tconst video = document.createElement( 'video' );\n\t\t\tvideo.autoplay = this.dom.dataset.previewAutoplay === 'false' ? false : true;\n\t\t\tvideo.controls = this.dom.dataset.previewControls === 'false' ? false : true;\n\t\t\tvideo.loop = this.dom.dataset.previewLoop === 'true' ? true : false;\n\t\t\tvideo.muted = this.dom.dataset.previewMuted === 'true' ? true : false;\n\t\t\tvideo.playsInline = true;\n\t\t\tvideo.src = url;\n\t\t\tcontentElement.appendChild( video );\n\n\t\t\tvideo.addEventListener( 'loadeddata', () => {\n\t\t\t\tthis.dom.dataset.state = 'loaded';\n\t\t\t}, false );\n\n\t\t\tvideo.addEventListener( 'error', () => {\n\t\t\t\tthis.dom.dataset.state = 'error';\n\t\t\t\tcontentElement.innerHTML =\n\t\t\t\t\t`Unable to load video. `;\n\t\t\t}, false );\n\n\t\t\tthis.Reveal.dispatchEvent({ type: 'previewvideo', data: { url } });\n\n\t\t}\n\t\telse {\n\t\t\tthrow new Error( 'Please specify a valid media type to preview' );\n\t\t}\n\n\t\tthis.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', ( event ) => {\n\t\t\tthis.close();\n\t\t\tevent.preventDefault();\n\t\t}, false );\n\n\t}\n\n\tpreviewImage( url, fitMode ) {\n\n\t\tthis.previewMedia( url, 'image', fitMode );\n\n\t}\n\n\tpreviewVideo( url, fitMode ) {\n\n\t\tthis.previewMedia( url, 'video', fitMode );\n\n\t}\n\n\t/**\n\t * Open or close help overlay window.\n\t *\n\t * @param {Boolean} [override] Flag which overrides the\n\t * toggle logic and forcibly sets the desired state. True means\n\t * help is open, false means it's closed.\n\t */\n\ttoggleHelp( override ) {\n\n\t\tif( typeof override === 'boolean' ) {\n\t\t\toverride ? this.showHelp() : this.close();\n\t\t}\n\t\telse {\n\t\t\tif( this.dom ) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.showHelp();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Opens an overlay window with help material.\n\t */\n\tshowHelp() {\n\n\t\tif( this.Reveal.getConfig().help ) {\n\n\t\t\tthis.close();\n\n\t\t\tthis.createOverlay( 'r-overlay-help' );\n\n\t\t\tlet html = 'Keyboard Shortcuts
';\n\n\t\t\tlet shortcuts = this.Reveal.keyboard.getShortcuts(),\n\t\t\t\tbindings = this.Reveal.keyboard.getBindings();\n\n\t\t\thtml += 'KEY ACTION ';\n\t\t\tfor( let key in shortcuts ) {\n\t\t\t\thtml += `${key} ${shortcuts[ key ]} `;\n\t\t\t}\n\n\t\t\t// Add custom key bindings that have associated descriptions\n\t\t\tfor( let binding in bindings ) {\n\t\t\t\tif( bindings[binding].key && bindings[binding].description ) {\n\t\t\t\t\thtml += `${bindings[binding].key} ${bindings[binding].description} `;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thtml += '
';\n\n\t\t\tthis.viewport.innerHTML = `\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
${html}
\n\t\t\t\t
\n\t\t\t`;\n\n\t\t\tthis.dom.querySelector( '.r-overlay-close' ).addEventListener( 'click', event => {\n\t\t\t\tthis.close();\n\t\t\t\tevent.preventDefault();\n\t\t\t}, false );\n\n\t\t\tthis.Reveal.dispatchEvent({ type: 'showhelp' });\n\n\t\t}\n\n\t}\n\n\tisOpen() {\n\n\t\treturn !!this.dom;\n\n\t}\n\n\t/**\n\t * Closes any currently open overlay.\n\t */\n\tclose() {\n\n\t\tif( this.dom ) {\n\t\t\tthis.dom.remove();\n\t\t\tthis.dom = null;\n\n\t\t\tthis.state = {};\n\n\t\t\tthis.Reveal.dispatchEvent({ type: 'closeoverlay' });\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tgetState() {\n\n\t\treturn this.state;\n\n\t}\n\n\tsetState( state ) {\n\n\t\tif( state.previewIframe ) {\n\t\t\tthis.previewIframe( state.previewIframe );\n\t\t}\n\t\telse if( state.previewImage ) {\n\t\t\tthis.previewImage( state.previewImage, state.previewFit );\n\t\t}\n\t\telse if( state.previewVideo ) {\n\t\t\tthis.previewVideo( state.previewVideo, state.previewFit );\n\t\t}\n\t\telse {\n\t\t\tthis.close();\n\t\t}\n\n\t}\n\n\tonSlidesClicked( event ) {\n\n\t\tconst target = event.target;\n\n\t\tconst linkTarget = target.closest( this.iframeTriggerSelector );\n\t\tconst mediaTarget = target.closest( this.mediaTriggerSelector );\n\n\t\t// Was an iframe lightbox trigger clicked?\n\t\tif( linkTarget ) {\n\t\t\tif( event.metaKey || event.shiftKey || event.altKey ) {\n\t\t\t\t// Let the browser handle meta keys naturally so users can cmd+click, cmd+shift+click, shift+click, alt+click, etc.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet url = linkTarget.getAttribute( 'href' ) || linkTarget.getAttribute( 'data-preview-link' );\n\t\t\tif( url ) {\n\t\t\t\tthis.previewIframe( url );\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t\t// Was a media lightbox trigger clicked?\n\t\telse if( mediaTarget ) {\n\t\t\tif( mediaTarget.hasAttribute( 'data-preview-image' ) ) {\n\t\t\t\tlet url = mediaTarget.dataset.previewImage || mediaTarget.getAttribute( 'src' );\n\t\t\t\tif( url ) {\n\t\t\t\t\tthis.previewImage( url, mediaTarget.dataset.previewFit );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if( mediaTarget.hasAttribute( 'data-preview-video' ) ) {\n\t\t\t\tlet url = mediaTarget.dataset.previewVideo || mediaTarget.getAttribute( 'src' );\n\t\t\t\tif( !url ) {\n\t\t\t\t\tlet source = mediaTarget.querySelector( 'source' );\n\t\t\t\t\tif( source ) {\n\t\t\t\t\t\turl = source.getAttribute( 'src' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( url ) {\n\t\t\t\t\tthis.previewVideo( url, mediaTarget.dataset.previewFit );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.close();\n\n\t}\n\n}","import { isAndroid } from '../utils/device.js'\nimport { matches } from '../utils/util.js'\n\nconst SWIPE_THRESHOLD = 40;\n\n/**\n * Controls all touch interactions and navigations for\n * a presentation.\n */\nexport default class Touch {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\t// Holds information about the currently ongoing touch interaction\n\t\tthis.touchStartX = 0;\n\t\tthis.touchStartY = 0;\n\t\tthis.touchStartCount = 0;\n\t\tthis.touchCaptured = false;\n\n\t\tthis.onPointerDown = this.onPointerDown.bind( this );\n\t\tthis.onPointerMove = this.onPointerMove.bind( this );\n\t\tthis.onPointerUp = this.onPointerUp.bind( this );\n\t\tthis.onTouchStart = this.onTouchStart.bind( this );\n\t\tthis.onTouchMove = this.onTouchMove.bind( this );\n\t\tthis.onTouchEnd = this.onTouchEnd.bind( this );\n\n\t}\n\n\t/**\n\t *\n\t */\n\tbind() {\n\n\t\tlet revealElement = this.Reveal.getRevealElement();\n\n\t\tif( 'onpointerdown' in window ) {\n\t\t\t// Use W3C pointer events\n\t\t\trevealElement.addEventListener( 'pointerdown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'pointermove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'pointerup', this.onPointerUp, false );\n\t\t}\n\t\telse if( window.navigator.msPointerEnabled ) {\n\t\t\t// IE 10 uses prefixed version of pointer events\n\t\t\trevealElement.addEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\t\trevealElement.addEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\t\trevealElement.addEventListener( 'MSPointerUp', this.onPointerUp, false );\n\t\t}\n\t\telse {\n\t\t\t// Fall back to touch events\n\t\t\trevealElement.addEventListener( 'touchstart', this.onTouchStart, false );\n\t\t\trevealElement.addEventListener( 'touchmove', this.onTouchMove, false );\n\t\t\trevealElement.addEventListener( 'touchend', this.onTouchEnd, false );\n\t\t}\n\n\t}\n\n\t/**\n\t *\n\t */\n\tunbind() {\n\n\t\tlet revealElement = this.Reveal.getRevealElement();\n\n\t\trevealElement.removeEventListener( 'pointerdown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'pointermove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'pointerup', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'MSPointerDown', this.onPointerDown, false );\n\t\trevealElement.removeEventListener( 'MSPointerMove', this.onPointerMove, false );\n\t\trevealElement.removeEventListener( 'MSPointerUp', this.onPointerUp, false );\n\n\t\trevealElement.removeEventListener( 'touchstart', this.onTouchStart, false );\n\t\trevealElement.removeEventListener( 'touchmove', this.onTouchMove, false );\n\t\trevealElement.removeEventListener( 'touchend', this.onTouchEnd, false );\n\n\t}\n\n\t/**\n\t * Checks if the target element prevents the triggering of\n\t * swipe navigation.\n\t */\n\tisSwipePrevented( target ) {\n\n\t\t// Prevent accidental swipes when scrubbing timelines\n\t\tif( matches( target, 'video[controls], audio[controls]' ) ) return true;\n\n\t\twhile( target && typeof target.hasAttribute === 'function' ) {\n\t\t\tif( target.hasAttribute( 'data-prevent-swipe' ) ) return true;\n\t\t\ttarget = target.parentNode;\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchstart' event, enables support for\n\t * swipe and pinch gestures.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchStart( event ) {\n\n\t\tthis.touchCaptured = false;\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tthis.touchStartX = event.touches[0].clientX;\n\t\tthis.touchStartY = event.touches[0].clientY;\n\t\tthis.touchStartCount = event.touches.length;\n\n\t}\n\n\t/**\n\t * Handler for the 'touchmove' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchMove( event ) {\n\n\t\tif( this.isSwipePrevented( event.target ) ) return true;\n\n\t\tlet config = this.Reveal.getConfig();\n\n\t\t// Each touch should only trigger one action\n\t\tif( !this.touchCaptured ) {\n\t\t\tthis.Reveal.onUserInput( event );\n\n\t\t\tlet currentX = event.touches[0].clientX;\n\t\t\tlet currentY = event.touches[0].clientY;\n\n\t\t\t// There was only one touch point, look for a swipe\n\t\t\tif( event.touches.length === 1 && this.touchStartCount !== 2 ) {\n\n\t\t\t\tlet availableRoutes = this.Reveal.availableRoutes({ includeFragments: true });\n\n\t\t\t\tlet deltaX = currentX - this.touchStartX,\n\t\t\t\t\tdeltaY = currentY - this.touchStartY;\n\n\t\t\t\tif( deltaX > SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.left();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaX < -SWIPE_THRESHOLD && Math.abs( deltaX ) > Math.abs( deltaY ) ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tif( config.rtl ) {\n\t\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.right();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY > SWIPE_THRESHOLD && availableRoutes.up ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.prev();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.up();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( deltaY < -SWIPE_THRESHOLD && availableRoutes.down ) {\n\t\t\t\t\tthis.touchCaptured = true;\n\t\t\t\t\tif( config.navigationMode === 'linear' ) {\n\t\t\t\t\t\tthis.Reveal.next();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.Reveal.down();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we're embedded, only block touch events if they have\n\t\t\t\t// triggered an action\n\t\t\t\tif( config.embedded ) {\n\t\t\t\t\tif( this.touchCaptured || this.Reveal.isVerticalSlide() ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Not embedded? Block them all to avoid needless tossing\n\t\t\t\t// around of the viewport in iOS\n\t\t\t\telse {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t\t// There's a bug with swiping on some Android devices unless\n\t\t// the default action is always prevented\n\t\telse if( isAndroid ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t}\n\n\t/**\n\t * Handler for the 'touchend' event.\n\t *\n\t * @param {object} event\n\t */\n\tonTouchEnd( event ) {\n\n\t\tthis.touchCaptured = false;\n\n\t}\n\n\t/**\n\t * Convert pointer down to touch start.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerDown( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchStart( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer move to touch move.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerMove( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchMove( event );\n\t\t}\n\n\t}\n\n\t/**\n\t * Convert pointer up to touch end.\n\t *\n\t * @param {object} event\n\t */\n\tonPointerUp( event ) {\n\n\t\tif( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === \"touch\" ) {\n\t\t\tevent.touches = [{ clientX: event.clientX, clientY: event.clientY }];\n\t\t\tthis.onTouchEnd( event );\n\t\t}\n\n\t}\n\n}","import { closest } from '../utils/util.js'\n\n/**\n * Manages focus when a presentation is embedded. This\n * helps us only capture keyboard from the presentation\n * a user is currently interacting with in a page where\n * multiple presentations are embedded.\n */\n\nconst STATE_FOCUS = 'focus';\nconst STATE_BLUR = 'blur';\n\nexport default class Focus {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t\tthis.onRevealPointerDown = this.onRevealPointerDown.bind( this );\n\t\tthis.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.embedded ) {\n\t\t\tthis.blur();\n\t\t}\n\t\telse {\n\t\t\tthis.focus();\n\t\t\tthis.unbind();\n\t\t}\n\n\t}\n\n\tbind() {\n\n\t\tif( this.Reveal.getConfig().embedded ) {\n\t\t\tthis.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tthis.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );\n\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\n\t}\n\n\tfocus() {\n\n\t\tif( this.state !== STATE_FOCUS ) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'focused' );\n\t\t\tdocument.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_FOCUS;\n\n\t}\n\n\tblur() {\n\n\t\tif( this.state !== STATE_BLUR ) {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\t\t\tdocument.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );\n\t\t}\n\n\t\tthis.state = STATE_BLUR;\n\n\t}\n\n\tisFocused() {\n\n\t\treturn this.state === STATE_FOCUS;\n\n\t}\n\n\tdestroy() {\n\n\t\tthis.Reveal.getRevealElement().classList.remove( 'focused' );\n\n\t}\n\n\tonRevealPointerDown( event ) {\n\n\t\tthis.focus();\n\n\t}\n\n\tonDocumentPointerDown( event ) {\n\n\t\tlet revealElement = closest( event.target, '.reveal' );\n\t\tif( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {\n\t\t\tthis.blur();\n\t\t}\n\n\t}\n\n}","/**\n * Handles the showing of speaker notes\n */\nexport default class Notes {\n\n\tconstructor( Reveal ) {\n\n\t\tthis.Reveal = Reveal;\n\n\t}\n\n\trender() {\n\n\t\tthis.element = document.createElement( 'div' );\n\t\tthis.element.className = 'speaker-notes';\n\t\tthis.element.setAttribute( 'data-prevent-swipe', '' );\n\t\tthis.element.setAttribute( 'tabindex', '0' );\n\t\tthis.Reveal.getRevealElement().appendChild( this.element );\n\n\t}\n\n\t/**\n\t * Called when the reveal.js config is updated.\n\t */\n\tconfigure( config, oldConfig ) {\n\n\t\tif( config.showNotes ) {\n\t\t\tthis.element.setAttribute( 'data-layout', typeof config.showNotes === 'string' ? config.showNotes : 'inline' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Pick up notes from the current slide and display them\n\t * to the viewer.\n\t *\n\t * @see {@link config.showNotes}\n\t */\n\tupdate() {\n\n\t\tif( this.Reveal.getConfig().showNotes &&\n\t\t\tthis.element && this.Reveal.getCurrentSlide() &&\n\t\t\t!this.Reveal.isScrollView() &&\n\t\t\t!this.Reveal.isPrintView()\n\t\t) {\n\t\t\tthis.element.innerHTML = this.getSlideNotes() || 'No notes on this slide. ';\n\t\t}\n\n\t}\n\n\t/**\n\t * Updates the visibility of the speaker notes sidebar that\n\t * is used to share annotated slides. The notes sidebar is\n\t * only visible if showNotes is true and there are notes on\n\t * one or more slides in the deck.\n\t */\n\tupdateVisibility() {\n\n\t\tif( this.Reveal.getConfig().showNotes &&\n\t\t\tthis.hasNotes() &&\n\t\t\t!this.Reveal.isScrollView() &&\n\t\t\t!this.Reveal.isPrintView()\n\t\t) {\n\t\t\tthis.Reveal.getRevealElement().classList.add( 'show-notes' );\n\t\t}\n\t\telse {\n\t\t\tthis.Reveal.getRevealElement().classList.remove( 'show-notes' );\n\t\t}\n\n\t}\n\n\t/**\n\t * Checks if there are speaker notes for ANY slide in the\n\t * presentation.\n\t */\n\thasNotes() {\n\n\t\treturn this.Reveal.getSlidesElement().querySelectorAll( '[data-notes], aside.notes' ).length > 0;\n\n\t}\n\n\t/**\n\t * Checks if this presentation is running inside of the\n\t * speaker notes window.\n\t *\n\t * @return {boolean}\n\t */\n\tisSpeakerNotesWindow() {\n\n\t\treturn !!window.location.search.match( /receiver/gi );\n\n\t}\n\n\t/**\n\t * Retrieves the speaker notes from a slide. Notes can be\n\t * defined in two ways:\n\t * 1. As a data-notes attribute on the slide \n\t * 2. With elements inside the slide\n\t *\n\t * @param {HTMLElement} [slide=currentSlide]\n\t * @return {(string|null)}\n\t */\n\tgetSlideNotes( slide = this.Reveal.getCurrentSlide() ) {\n\n\t\t// Notes can be specified via the data-notes attribute...\n\t\tif( slide.hasAttribute( 'data-notes' ) ) {\n\t\t\treturn slide.getAttribute( 'data-notes' );\n\t\t}\n\n\t\t// ... or using