update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {

		let changedFragments = {
			shown: [],
			hidden: []
		};

		if( slide && this.Reveal.getConfig().fragments ) {

			fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );

			if( fragments.length ) {

				let maxIndex = 0;

				if( typeof index !== 'number' ) {
					let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
					if( currentFragment ) {
						index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
					}
				}

				Array.from( fragments ).forEach( ( el, i ) => {

					if( el.hasAttribute( 'data-fragment-index' ) ) {
						i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );
					}

					maxIndex = Math.max( maxIndex, i );

					// Visible fragments
					if( i <= index ) {
						let wasVisible = el.classList.contains( 'visible' )
						el.classList.add( 'visible' );
						el.classList.remove( 'current-fragment' );

						if( i === index ) {
							// Announce the fragments one by one to the Screen Reader
							this.Reveal.announceStatus( this.Reveal.getStatusText( el ) );

							el.classList.add( 'current-fragment' );
							this.Reveal.slideContent.startEmbeddedContent( el );
						}

						if( !wasVisible ) {
							changedFragments.shown.push( el )
							this.Reveal.dispatchEvent({
								target: el,
								type: 'visible',
								bubbles: false
							});
						}
					}
					// Hidden fragments
					else {
						let wasVisible = el.classList.contains( 'visible' )
						el.classList.remove( 'visible' );
						el.classList.remove( 'current-fragment' );

						if( wasVisible ) {
							this.Reveal.slideContent.stopEmbeddedContent( el );
							changedFragments.hidden.push( el );
							this.Reveal.dispatchEvent({
								target: el,
								type: 'hidden',
								bubbles: false
							});
						}
					}

				} );

				// Write the current fragment index to the slide <section>.
				// This can be used by end users to apply styles based on
				// the current fragment index.
				index = typeof index === 'number' ? index : -1;
				index = Math.max( Math.min( index, maxIndex ), -1 );
				slide.setAttribute( 'data-fragment', index );

			}

		}

		if( changedFragments.hidden.length ) {
			this.Reveal.dispatchEvent({
				type: 'fragmenthidden',
				data: {
					fragment: changedFragments.hidden[0],
					fragments: changedFragments.hidden
				}
			});
		}

		if( changedFragments.shown.length ) {
			this.Reveal.dispatchEvent({
				type: 'fragmentshown',
				data: {
					fragment: changedFragments.shown[0],
					fragments: changedFragments.shown
				}
			});
		}

		return changedFragments;

	}
Refreshes the fragments on the current slide so that they
have the appropriate classes (.visible + .current-fragment).

@param {number} [index] The index of the current fragment
@param {array} [fragments] Array containing all fragments
in the current slide

@return {{shown: array, hidden: array}}