var notes =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "documentation-bundle/assets/";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ({

/***/ "./Resources/css/notes.css":
/*!*********************************!*\
  !*** ./Resources/css/notes.css ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),

/***/ "./Resources/js/slides/notes.js":
/*!**************************************!*\
  !*** ./Resources/js/slides/notes.js ***!
  \**************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _css_notes_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../css/notes.css */ "./Resources/css/notes.css");
/* harmony import */ var _css_notes_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_notes_css__WEBPACK_IMPORTED_MODULE_0__);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

//const marked = require("reveal.js/plugin/markdown/marked.js");

var params = ['receiver', 'progress=false', 'history=false', 'transition=none', 'autoSlide=0', 'backgroundTransition=none'].join('&');
var SPEAKER_LAYOUTS = {
  'default': 'Default',
  'wide': 'Wide',
  'tall': 'Tall',
  'notes-only': 'Notes only'
};
/**
 * Called when the main window sends an updated state.
 */

function handleStateMessage(data) {
  // Store the most recently set state to avoid circular loops
  // applying the same state
  this.currentState = JSON.stringify(data.state); // No need for updating the notes in case of fragment changes

  if (data.notes) {
    this.notes.classList.remove('hidden');
    this.notesValue.style.whiteSpace = data.whitespace;

    if (data.markdown) {
      this.notesValue.innerHTML = marked(data.notes);
    } else {
      this.notesValue.innerHTML = data.notes;
    }
  } else {
    this.notes.classList.add('hidden');
  } // Update the note slides


  this.currentSlide.contentWindow.postMessage(JSON.stringify({
    method: 'setState',
    args: [data.state]
  }), '*');
  this.upcomingSlide.contentWindow.postMessage(JSON.stringify({
    method: 'setState',
    args: [data.state]
  }), '*');
  this.upcomingSlide.contentWindow.postMessage(JSON.stringify({
    method: 'next'
  }), '*');
}
/**
 * Limits the frequency at which a function can be called.
 */


function debounce(fn, ms) {
  var lastTime = 0,
      timeout;
  return function () {
    var args = arguments;
    var context = this;
    clearTimeout(timeout);
    var timeSinceLastCall = Date.now() - lastTime;

    if (timeSinceLastCall > ms) {
      fn.apply(context, args);
      lastTime = Date.now();
    } else {
      timeout = setTimeout(function () {
        fn.apply(context, args);
        lastTime = Date.now();
      }, ms - timeSinceLastCall);
    }
  };
}

var Notes = /*#__PURE__*/function () {
  function Notes() {
    _classCallCheck(this, Notes);

    this.notesValue = null;
    this.currentState = null;
    this.currentSlide = null;
    this.upcomingSlide = null;
    this.layoutLabel = null;
    this.layoutDropdown = null;
    this.pendingCalls = {};
    this.lastRevealApiCallId = 0;
    this.connected = false;
    this.setupLayout();
    this.initialize();
  }

  _createClass(Notes, [{
    key: "initialize",
    value: function initialize() {
      this.connectionStatus = document.querySelector('#connection-status');
      this.connectionTimeout = setTimeout(function () {
        this.connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
      }, 5000); // Limit to max one state update per X ms

      this.handleStateMessage = debounce(handleStateMessage.bind(this), 200);
      window.addEventListener('message', function (event) {
        clearTimeout(this.connectionTimeout);
        this.connectionStatus.style.display = 'none';
        var data = JSON.parse(event.data); // The overview mode is only useful to the reveal.js instance
        // where navigation occurs so we don't sync it

        if (data.state) delete data.state.overview; // Messages sent by the notes plugin inside of the main window

        if (data && data.namespace === 'reveal-notes') {
          if (data.type === 'connect') {
            this.handleConnectMessage(data);
          } else if (data.type === 'state') {
            thix.handleStateMessage(data);
          } else if (data.type === 'return') {
            this.pendingCalls[data.callId](data.result);
            delete this.pendingCalls[data.callId];
          }
        } // Messages sent by the reveal.js inside of the current slide preview
        else if (data && data.namespace === 'reveal') {
            if (/ready/.test(data.eventName)) {
              // Send a message back to notify that the handshake is complete
              window.opener.postMessage(JSON.stringify({
                namespace: 'reveal-notes',
                type: 'connected'
              }), '*');
            } else if (/slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test(data.eventName) && currentState !== JSON.stringify(data.state)) {
              window.opener.postMessage(JSON.stringify({
                method: 'setState',
                args: [data.state]
              }), '*');
            }
          }
      });
    }
    /**
     * Sets up the speaker view layout and layout selector.
     */

  }, {
    key: "setupLayout",
    value: function setupLayout() {
      this.layoutDropdown = document.querySelector('.speaker-layout-dropdown');
      this.layoutLabel = document.querySelector('.speaker-layout-label'); // Render the list of available layouts

      for (var id in SPEAKER_LAYOUTS) {
        var option = document.createElement('option');
        option.setAttribute('value', id);
        option.textContent = SPEAKER_LAYOUTS[id];
        this.layoutDropdown.appendChild(option);
      } // Monitor the dropdown for changes


      this.layoutDropdown.addEventListener('change', function (event) {
        this.setLayout(this.layoutDropdown.value);
      }, false); // Restore any currently persisted layout

      this.setLayout(this.getLayout());
    }
    /**
     * Sets a new speaker view layout. The layout is persisted
     * in local storage.
     */

  }, {
    key: "setLayout",
    value: function setLayout(value) {
      var title = SPEAKER_LAYOUTS[value];
      this.layoutLabel.innerHTML = 'Layout' + (title ? ': ' + title : '');
      this.layoutDropdown.value = value;
      document.body.setAttribute('data-speaker-layout', value); // Persist locally

      if (this.supportsLocalStorage()) {
        window.localStorage.setItem('reveal-speaker-layout', value);
      }
    }
    /**
     * Returns the ID of the most recently set speaker layout
     * or our default layout if none has been set.
     */

  }, {
    key: "getLayout",
    value: function getLayout() {
      if (this.supportsLocalStorage()) {
        var layout = window.localStorage.getItem('reveal-speaker-layout');

        if (layout) {
          return layout;
        }
      } // Default to the first record in the layouts hash


      for (var id in SPEAKER_LAYOUTS) {
        return id;
      }
    }
  }, {
    key: "supportsLocalStorage",
    value: function supportsLocalStorage() {
      try {
        localStorage.setItem('test', 'test');
        localStorage.removeItem('test');
        return true;
      } catch (e) {
        return false;
      }
    }
    /**
     * Called when the main window is trying to establish a
     * connection.
     */

  }, {
    key: "handleConnectMessage",
    value: function handleConnectMessage(data) {
      if (this.connected === false) {
        this.connected = true;
        this.setupIframes(data);
        this.setupKeyboard();
        this.setupNotes();
        this.setupTimer();
      }
    }
    /**
     * Creates the preview iframes.
     */

  }, {
    key: "setupIframes",
    value: function setupIframes(data) {
      var urlSeparator = /\?/.test(data.url) ? '&' : '?';
      var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
      var currentURL = data.url + urlSeparator + params + '&postMessageEvents=true' + hash;
      var upcomingURL = data.url + urlSeparator + params + '&controls=false' + hash;
      this.currentSlide = document.createElement('iframe');
      this.currentSlide.setAttribute('width', 1280);
      this.currentSlide.setAttribute('height', 1024);
      this.currentSlide.setAttribute('src', currentURL);
      document.querySelector('#current-slide').appendChild(this.currentSlide);
      this.upcomingSlide = document.createElement('iframe');
      this.upcomingSlide.setAttribute('width', 640);
      this.upcomingSlide.setAttribute('height', 512);
      this.upcomingSlide.setAttribute('src', upcomingURL);
      document.querySelector('#upcoming-slide').appendChild(this.upcomingSlide);
    }
    /**
     * Forward keyboard events to the current slide window.
     * This enables keyboard events to work even if focus
     * isn't set on the current slide iframe.
     *
     * Block F5 default handling, it reloads and disconnects
     * the speaker notes window.
     */

  }, {
    key: "setupKeyboard",
    value: function setupKeyboard() {
      document.addEventListener('keydown', function (event) {
        if (event.keyCode === 116 || event.metaKey && event.keyCode === 82) {
          event.preventDefault();
          return false;
        }

        this.currentSlide.contentWindow.postMessage(JSON.stringify({
          method: 'triggerKey',
          args: [event.keyCode]
        }), '*');
      });
    }
    /**
     * Setup the notes UI.
     */

  }, {
    key: "setupNotes",
    value: function setupNotes() {
      this.notes = document.querySelector('.speaker-controls-notes');
      this.notesValue = document.querySelector('.speaker-controls-notes .value');
    }
    /**
     * Create the timer and clock and start updating them
     * at an interval.
     */

  }, {
    key: "setupTimer",
    value: function setupTimer() {
      var _this = this;

      this.start = new Date(), this.timeEl = document.querySelector('.speaker-controls-time'), this.clockEl = this.timeEl.querySelector('.clock-value'), this.hoursEl = this.timeEl.querySelector('.hours-value'), this.minutesEl = this.timeEl.querySelector('.minutes-value'), this.secondsEl = this.timeEl.querySelector('.seconds-value'), this.pacingTitleEl = this.timeEl.querySelector('.pacing-title'), this.pacingEl = this.timeEl.querySelector('.pacing'), this.pacingHoursEl = this.pacingEl.querySelector('.hours-value'), this.pacingMinutesEl = this.pacingEl.querySelector('.minutes-value'), this.pacingSecondsEl = this.pacingEl.querySelector('.seconds-value');
      this.timings = null;
      this.getTimings(function (_timings) {
        _this.timings = _timings;

        if (_timings !== null) {
          _this.pacingTitleEl.style.removeProperty('display');

          _this.pacingEl.style.removeProperty('display');
        } // Update once directly


        _this._updateTimer(); // Then update every second


        setInterval(_this._updateTimer.bind(_this), 1000);
      });
      this.timeEl.addEventListener('click', function () {
        _this._resetTimer();

        return false;
      });
    }
  }, {
    key: "_resetTimer",
    value: function _resetTimer() {
      var _this2 = this;

      if (this.timings == null) {
        this.start = new Date();

        this._updateTimer();
      } else {
        // Reset timer to beginning of current slide
        this.getTimeAllocated(this.timings, function (slideEndTimingSeconds) {
          var slideEndTiming = slideEndTimingSeconds * 1000;

          _this2.callRevealApi('getSlidePastCount', [], function (currentSlide) {
            var currentSlideTiming = this.timings[currentSlide] * 1000;
            var previousSlidesTiming = slideEndTiming - currentSlideTiming;
            var now = new Date();
            this.start = new Date(now.getTime() - previousSlidesTiming);

            this._updateTimer();
          });
        });
      }
    }
  }, {
    key: "_updatePacing",
    value: function _updatePacing(diff) {
      this.getTimeAllocated(this.timings, function (slideEndTimingSeconds) {
        var slideEndTiming = slideEndTimingSeconds * 1000;
        this.callRevealApi('getSlidePastCount', [], function (currentSlide) {
          var currentSlideTiming = this.timings[currentSlide] * 1000;
          var timeLeftCurrentSlide = slideEndTiming - diff;

          if (timeLeftCurrentSlide < 0) {
            this.pacingEl.className = 'pacing behind';
          } else if (timeLeftCurrentSlide < currentSlideTiming) {
            this.pacingEl.className = 'pacing on-track';
          } else {
            this.pacingEl.className = 'pacing ahead';
          }

          this._displayTime(this.pacingHoursEl, this.pacingMinutesEl, this.pacingSecondsEl, timeLeftCurrentSlide);
        });
      });
    }
  }, {
    key: "_updateTimer",
    value: function _updateTimer() {
      var diff,
          hours,
          minutes,
          seconds,
          now = new Date();
      diff = now.getTime() - start.getTime();
      this.clockEl.innerHTML = now.toLocaleTimeString('en-US', {
        hour12: true,
        hour: '2-digit',
        minute: '2-digit'
      });

      this._displayTime(hoursEl, minutesEl, secondsEl, diff);

      if (this.timings !== null) {
        this._updatePacing(diff);
      }
    }
  }, {
    key: "_displayTime",
    value: function _displayTime(hrEl, minEl, secEl, time) {
      var sign = Math.sign(time) == -1 ? "-" : "";
      time = Math.abs(Math.round(time / 1000));
      var seconds = time % 60;
      var minutes = Math.floor(time / 60) % 60;
      var hours = Math.floor(time / (60 * 60));
      this.hrEl.innerHTML = sign + this.zeroPadInteger(hours);

      if (hours == 0) {
        hrEl.classList.add('mute');
      } else {
        hrEl.classList.remove('mute');
      }

      this.minEl.innerHTML = ':' + this.zeroPadInteger(minutes);

      if (hours == 0 && minutes == 0) {
        minEl.classList.add('mute');
      } else {
        this.minEl.classList.remove('mute');
      }

      this.secEl.innerHTML = ':' + this.zeroPadInteger(seconds);
    }
    /**
     * Asynchronously calls the Reveal.js API of the main frame.
     */

  }, {
    key: "callRevealApi",
    value: function callRevealApi(methodName, methodArguments, callback) {
      var callId = ++this.lastRevealApiCallId;
      this.pendingCalls[callId] = callback;
      window.opener.postMessage(JSON.stringify({
        namespace: 'reveal-notes',
        type: 'call',
        callId: callId,
        methodName: methodName,
        arguments: methodArguments
      }), '*');
    }
    /**
     * Return the number of seconds allocated for presenting
     * all slides up to and including this one.
     */

  }, {
    key: "getTimeAllocated",
    value: function getTimeAllocated(timings, callback) {
      this.callRevealApi('getSlidePastCount', [], function (currentSlide) {
        var allocated = 0;

        for (var i in timings.slice(0, currentSlide + 1)) {
          allocated += timings[i];
        }

        callback(allocated);
      });
    }
  }, {
    key: "zeroPadInteger",
    value: function zeroPadInteger(num) {
      var str = '00' + parseInt(num);
      return str.substring(str.length - 2);
    }
  }, {
    key: "getTimings",
    value: function getTimings(callback) {
      var _this3 = this;

      this.callRevealApi('getSlidesAttributes', [], function (slideAttributes) {
        _this3.callRevealApi('getConfig', [], function (config) {
          var totalTime = config.totalTime;
          var minTimePerSlide = config.minimumTimePerSlide || 0;
          var defaultTiming = config.defaultTiming;

          if (defaultTiming == null && totalTime == null) {
            callback(null);
            return;
          } // Setting totalTime overrides defaultTiming


          if (totalTime) {
            defaultTiming = 0;
          }

          var timings = [];

          for (var i in slideAttributes) {
            var slide = slideAttributes[i];
            var timing = defaultTiming;

            if (slide.hasOwnProperty('data-timing')) {
              var t = slide['data-timing'];
              timing = parseInt(t);

              if (isNaN(timing)) {
                console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
                timing = defaultTiming;
              }
            }

            timings.push(timing);
          }

          if (totalTime) {
            // After we've allocated time to individual slides, we summarize it and
            // subtract it from the total time
            var remainingTime = totalTime - timings.reduce(function (a, b) {
              return a + b;
            }, 0); // The remaining time is divided by the number of slides that have 0 seconds
            // allocated at the moment, giving the average time-per-slide on the remaining slides

            var remainingSlides = timings.filter(function (x) {
              return x == 0;
            }).length;
            var timePerSlide = Math.round(remainingTime / remainingSlides, 0); // And now we replace every zero-value timing with that average

            timings = timings.map(function (x) {
              return x == 0 ? timePerSlide : x;
            });
          }

          var slidesUnderMinimum = timings.filter(function (x) {
            return x < minTimePerSlide;
          }).length;
          var message;

          if (slidesUnderMinimum) {
            message = "The pacing time for " + slidesUnderMinimum + " slide(s) is under the configured minimum of " + minTimePerSlide + " seconds. Check the data-timing attribute on individual slides, or consider increasing the totalTime or minimumTimePerSlide configuration options (or removing some slides).";
            alert(message);
          }

          callback(timings);
        });
      });
    }
  }]);

  return Notes;
}();

/* harmony default export */ __webpack_exports__["default"] = (new Notes());

/***/ }),

/***/ 2:
/*!********************************************!*\
  !*** multi ./Resources/js/slides/notes.js ***!
  \********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./Resources/js/slides/notes.js */"./Resources/js/slides/notes.js");


/***/ })

/******/ })["default"];
//# sourceMappingURL=notes.js.map