diff --git a/node_modules/mdl-ext/es/accordion/accordion.js b/node_modules/mdl-ext/es/accordion/accordion.js
new file mode 100644
index 0000000..2d518ca
--- /dev/null
+++ b/node_modules/mdl-ext/es/accordion/accordion.js
@@ -0,0 +1,546 @@
+'use strict';
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+(function () {
+  'use strict';
+
+  var ACCORDION = 'mdlext-accordion';
+  var ACCORDION_VERTICAL = 'mdlext-accordion--vertical';
+  var ACCORDION_HORIZONTAL = 'mdlext-accordion--horizontal';
+  var PANEL = 'mdlext-accordion__panel';
+  var PANEL_ROLE = 'presentation';
+  var TAB = 'mdlext-accordion__tab';
+  var TAB_CAPTION = 'mdlext-accordion__tab__caption';
+  var TAB_ROLE = 'tab';
+  var TABPANEL = 'mdlext-accordion__tabpanel';
+  var TABPANEL_ROLE = 'tabpanel';
+  var RIPPLE_EFFECT = 'mdlext-js-ripple-effect';
+  var RIPPLE = 'mdlext-accordion__tab--ripple';
+  var ANIMATION_EFFECT = 'mdlext-js-animation-effect';
+  var ANIMATION = 'mdlext-accordion__tabpanel--animation';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtAccordion = function MaterialExtAccordion(element) {
+
+    // Stores the Accordion HTML element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtAccordion'] = MaterialExtAccordion;
+
+  // Helpers
+  var accordionPanelElements = function accordionPanelElements(element) {
+    if (!element) {
+      return {
+        panel: null,
+        tab: null,
+        tabpanel: null
+      };
+    } else if (element.classList.contains(PANEL)) {
+      return {
+        panel: element,
+        tab: element.querySelector('.' + TAB),
+        tabpanel: element.querySelector('.' + TABPANEL)
+      };
+    } else {
+      return {
+        panel: element.parentNode,
+        tab: element.parentNode.querySelector('.' + TAB),
+        tabpanel: element.parentNode.querySelector('.' + TABPANEL)
+      };
+    }
+  };
+
+  // Private methods.
+
+  /**
+   * Handles custom command event, 'open', 'close', 'toggle' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtAccordion.prototype.commandHandler_ = function (event) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if (event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+  /**
+   * Dispatch toggle event
+   * @param {string} state
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.dispatchToggleEvent_ = function (state, tab, tabpanel) {
+    var ce = new CustomEvent('toggle', {
+      bubbles: true,
+      cancelable: true,
+      detail: { state: state, tab: tab, tabpanel: tabpanel }
+    });
+    this.element_.dispatchEvent(ce);
+  };
+
+  /**
+   * Open tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTab_ = function (panel, tab, tabpanel) {
+    panel.classList.add(_constants.IS_EXPANDED);
+    tab.setAttribute(_constants.ARIA_EXPANDED, 'true');
+    tabpanel.removeAttribute('hidden');
+    tabpanel.setAttribute(_constants.ARIA_HIDDEN, 'false');
+    this.dispatchToggleEvent_('open', tab, tabpanel);
+  };
+
+  /**
+   * Close tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTab_ = function (panel, tab, tabpanel) {
+    panel.classList.remove(_constants.IS_EXPANDED);
+    tab.setAttribute(_constants.ARIA_EXPANDED, 'false');
+    tabpanel.setAttribute('hidden', '');
+    tabpanel.setAttribute(_constants.ARIA_HIDDEN, 'true');
+    this.dispatchToggleEvent_('close', tab, tabpanel);
+  };
+
+  /**
+   * Toggle tab
+   * @param {Element} panel
+   * @param {Element} tab
+   * @param {Element} tabpanel
+   * @private
+   */
+  MaterialExtAccordion.prototype.toggleTab_ = function (panel, tab, tabpanel) {
+    if (!(this.element_.hasAttribute('disabled') || tab.hasAttribute('disabled'))) {
+      if (tab.getAttribute(_constants.ARIA_EXPANDED).toLowerCase() === 'true') {
+        this.closeTab_(panel, tab, tabpanel);
+      } else {
+        if (this.element_.getAttribute(_constants.ARIA_MULTISELECTABLE).toLowerCase() !== 'true') {
+          this.closeTabs_();
+        }
+        this.openTab_(panel, tab, tabpanel);
+      }
+    }
+  };
+
+  /**
+   * Open tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.openTabs_ = function () {
+    var _this = this;
+
+    if (this.element_.getAttribute(_constants.ARIA_MULTISELECTABLE).toLowerCase() === 'true') {
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + ACCORDION + ' > .' + PANEL))).filter(function (panel) {
+        return !panel.classList.contains(_constants.IS_EXPANDED);
+      }).forEach(function (closedItem) {
+        var tab = closedItem.querySelector('.' + TAB);
+        if (!tab.hasAttribute('disabled')) {
+          _this.openTab_(closedItem, tab, closedItem.querySelector('.' + TABPANEL));
+        }
+      });
+    }
+  };
+
+  /**
+   * Close tabs
+   * @private
+   */
+  MaterialExtAccordion.prototype.closeTabs_ = function () {
+    var _this2 = this;
+
+    [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + ACCORDION + ' > .' + PANEL + '.' + _constants.IS_EXPANDED))).forEach(function (panel) {
+      var tab = panel.querySelector('.' + TAB);
+      if (!tab.hasAttribute('disabled')) {
+        _this2.closeTab_(panel, tab, panel.querySelector('.' + TABPANEL));
+      }
+    });
+  };
+
+  // Public methods.
+
+  /**
+   * Upgrade an individual accordion tab
+   * @public
+   * @param {Element} tabElement The HTML element for the accordion panel.
+   */
+  MaterialExtAccordion.prototype.upgradeTab = function (tabElement) {
+    var _this3 = this;
+
+    var _accordionPanelElemen = accordionPanelElements(tabElement),
+        panel = _accordionPanelElemen.panel,
+        tab = _accordionPanelElemen.tab,
+        tabpanel = _accordionPanelElemen.tabpanel;
+
+    var disableTab = function disableTab() {
+      panel.classList.remove(_constants.IS_EXPANDED);
+      tab.setAttribute('tabindex', '-1');
+      tab.setAttribute(_constants.ARIA_EXPANDED, 'false');
+      tabpanel.setAttribute('hidden', '');
+      tabpanel.setAttribute(_constants.ARIA_HIDDEN, 'true');
+    };
+
+    var enableTab = function enableTab() {
+      if (!tab.hasAttribute(_constants.ARIA_EXPANDED)) {
+        tab.setAttribute(_constants.ARIA_EXPANDED, 'false');
+      }
+
+      tab.setAttribute('tabindex', '0');
+
+      if (tab.getAttribute(_constants.ARIA_EXPANDED).toLowerCase() === 'true') {
+        panel.classList.add(_constants.IS_EXPANDED);
+        tabpanel.removeAttribute('hidden');
+        tabpanel.setAttribute(_constants.ARIA_HIDDEN, 'false');
+      } else {
+        panel.classList.remove(_constants.IS_EXPANDED);
+        tabpanel.setAttribute('hidden', '');
+        tabpanel.setAttribute(_constants.ARIA_HIDDEN, 'true');
+      }
+    };
+
+    // In horizontal layout, caption must have a max-width defined to prevent pushing elements to the right of the caption out of view.
+    // In JsDom, offsetWidth and offsetHeight properties do not work, so this function is not testable.
+    /* istanbul ignore next */
+    var calcMaxTabCaptionWidth = function calcMaxTabCaptionWidth() {
+
+      var tabCaption = tab.querySelector('.' + TAB_CAPTION);
+      if (tabCaption !== null) {
+        var w = [].concat((0, _toConsumableArray3.default)(tab.children)).filter(function (el) {
+          return el.classList && !el.classList.contains(TAB_CAPTION);
+        }).reduce(function (v, el) {
+          return v + el.offsetWidth;
+        }, 0);
+
+        var maxWidth = tab.clientHeight - w;
+        if (maxWidth > 0) {
+          tabCaption.style['max-width'] = maxWidth + 'px';
+        }
+      }
+    };
+
+    var selectTab = function selectTab() {
+      if (!tab.hasAttribute(_constants.ARIA_SELECTED)) {
+        [].concat((0, _toConsumableArray3.default)(_this3.element_.querySelectorAll('.' + TAB + '[aria-selected="true"]'))).forEach(function (selectedTab) {
+          return selectedTab.removeAttribute(_constants.ARIA_SELECTED);
+        });
+        tab.setAttribute(_constants.ARIA_SELECTED, 'true');
+      }
+    };
+
+    var tabClickHandler = function tabClickHandler() {
+      _this3.toggleTab_(panel, tab, tabpanel);
+      selectTab();
+    };
+
+    var tabFocusHandler = function tabFocusHandler() {
+      selectTab();
+    };
+
+    var tabpanelClickHandler = function tabpanelClickHandler() {
+      selectTab();
+    };
+
+    var tabpanelFocusHandler = function tabpanelFocusHandler() {
+      selectTab();
+    };
+
+    var tabKeydownHandler = function tabKeydownHandler(e) {
+
+      if (_this3.element_.hasAttribute('disabled')) {
+        return;
+      }
+
+      if (e.keyCode === _constants.VK_END || e.keyCode === _constants.VK_HOME || e.keyCode === _constants.VK_ARROW_UP || e.keyCode === _constants.VK_ARROW_LEFT || e.keyCode === _constants.VK_ARROW_DOWN || e.keyCode === _constants.VK_ARROW_RIGHT) {
+
+        var nextTab = null;
+        var keyCode = e.keyCode;
+
+        if (keyCode === _constants.VK_HOME) {
+          nextTab = _this3.element_.querySelector('.' + PANEL + ':first-child > .' + TAB);
+          if (nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = _constants.VK_ARROW_DOWN;
+          }
+        } else if (keyCode === _constants.VK_END) {
+          nextTab = _this3.element_.querySelector('.' + PANEL + ':last-child > .' + TAB);
+          if (nextTab && nextTab.hasAttribute('disabled')) {
+            nextTab = null;
+            keyCode = _constants.VK_ARROW_UP;
+          }
+        }
+
+        if (!nextTab) {
+          var nextPanel = panel;
+
+          do {
+            if (keyCode === _constants.VK_ARROW_UP || keyCode === _constants.VK_ARROW_LEFT) {
+              nextPanel = nextPanel.previousElementSibling;
+              if (!nextPanel) {
+                nextPanel = _this3.element_.querySelector('.' + PANEL + ':last-child');
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector('.' + PANEL + ' > .' + TAB);
+              }
+            } else if (keyCode === _constants.VK_ARROW_DOWN || keyCode === _constants.VK_ARROW_RIGHT) {
+              nextPanel = nextPanel.nextElementSibling;
+              if (!nextPanel) {
+                nextPanel = _this3.element_.querySelector('.' + PANEL + ':first-child');
+              }
+              if (nextPanel) {
+                nextTab = nextPanel.querySelector('.' + PANEL + ' > .' + TAB);
+              }
+            }
+
+            if (nextTab && nextTab.hasAttribute('disabled')) {
+              nextTab = null;
+            } else {
+              break;
+            }
+          } while (nextPanel !== panel);
+        }
+
+        if (nextTab) {
+          e.preventDefault();
+          e.stopPropagation();
+          nextTab.focus();
+
+          // Workaround for JSDom testing:
+          // In JsDom 'element.focus()' does not trigger any focus event
+          if (!nextTab.hasAttribute(_constants.ARIA_SELECTED)) {
+
+            [].concat((0, _toConsumableArray3.default)(_this3.element_.querySelectorAll('.' + TAB + '[aria-selected="true"]'))).forEach(function (selectedTab) {
+              return selectedTab.removeAttribute(_constants.ARIA_SELECTED);
+            });
+
+            nextTab.setAttribute(_constants.ARIA_SELECTED, 'true');
+          }
+        }
+      } else if (e.keyCode === _constants.VK_ENTER || e.keyCode === _constants.VK_SPACE) {
+        e.preventDefault();
+        e.stopPropagation();
+        _this3.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+    if (tab === null) {
+      throw new Error('There must be a tab element for each accordion panel.');
+    }
+
+    if (tabpanel === null) {
+      throw new Error('There must be a tabpanel element for each accordion panel.');
+    }
+
+    panel.setAttribute('role', PANEL_ROLE);
+    tab.setAttribute('role', TAB_ROLE);
+    tabpanel.setAttribute('role', TABPANEL_ROLE);
+
+    if (tab.hasAttribute('disabled')) {
+      disableTab();
+    } else {
+      enableTab();
+    }
+
+    if (this.element_.classList.contains(ACCORDION_HORIZONTAL)) {
+      calcMaxTabCaptionWidth();
+    }
+
+    if (this.element_.classList.contains(RIPPLE_EFFECT)) {
+      tab.classList.add(RIPPLE);
+    }
+
+    if (this.element_.classList.contains(ANIMATION_EFFECT)) {
+      tabpanel.classList.add(ANIMATION);
+    }
+
+    // Remove listeners, just in case ...
+    tab.removeEventListener('click', tabClickHandler);
+    tab.removeEventListener('focus', tabFocusHandler);
+    tab.removeEventListener('keydown', tabKeydownHandler);
+    tabpanel.removeEventListener('click', tabpanelClickHandler);
+    tabpanel.removeEventListener('focus', tabpanelFocusHandler);
+
+    tab.addEventListener('click', tabClickHandler);
+    tab.addEventListener('focus', tabFocusHandler);
+    tab.addEventListener('keydown', tabKeydownHandler);
+    tabpanel.addEventListener('click', tabpanelClickHandler, true);
+    tabpanel.addEventListener('focus', tabpanelFocusHandler, true);
+  };
+  MaterialExtAccordion.prototype['upgradeTab'] = MaterialExtAccordion.prototype.upgradeTab;
+
+  /**
+   * Execute command
+   * @param detail
+   */
+  MaterialExtAccordion.prototype.command = function (detail) {
+    var _this4 = this;
+
+    var openTab = function openTab(tabElement) {
+
+      if (tabElement === undefined) {
+        _this4.openTabs_();
+      } else if (tabElement !== null) {
+        var _accordionPanelElemen2 = accordionPanelElements(tabElement),
+            panel = _accordionPanelElemen2.panel,
+            tab = _accordionPanelElemen2.tab,
+            tabpanel = _accordionPanelElemen2.tabpanel;
+
+        if (tab.getAttribute(_constants.ARIA_EXPANDED).toLowerCase() !== 'true') {
+          _this4.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    var closeTab = function closeTab(tabElement) {
+      if (tabElement === undefined) {
+        _this4.closeTabs_();
+      } else if (tabElement !== null) {
+        var _accordionPanelElemen3 = accordionPanelElements(tabElement),
+            panel = _accordionPanelElemen3.panel,
+            tab = _accordionPanelElemen3.tab,
+            tabpanel = _accordionPanelElemen3.tabpanel;
+
+        if (tab.getAttribute(_constants.ARIA_EXPANDED).toLowerCase() === 'true') {
+          _this4.toggleTab_(panel, tab, tabpanel);
+        }
+      }
+    };
+
+    var toggleTab = function toggleTab(tabElement) {
+      if (tabElement) {
+        var _accordionPanelElemen4 = accordionPanelElements(tabElement),
+            panel = _accordionPanelElemen4.panel,
+            tab = _accordionPanelElemen4.tab,
+            tabpanel = _accordionPanelElemen4.tabpanel;
+
+        _this4.toggleTab_(panel, tab, tabpanel);
+      }
+    };
+
+    if (detail && detail.action) {
+      var action = detail.action,
+          target = detail.target;
+
+
+      switch (action.toLowerCase()) {
+        case 'open':
+          openTab(target);
+          break;
+        case 'close':
+          closeTab(target);
+          break;
+        case 'toggle':
+          toggleTab(target);
+          break;
+        case 'upgrade':
+          if (target) {
+            this.upgradeTab(target);
+          }
+          break;
+        default:
+          throw new Error('Unknown action "' + action + '". Action must be one of "open", "close", "toggle" or "upgrade"');
+      }
+    }
+  };
+  MaterialExtAccordion.prototype['command'] = MaterialExtAccordion.prototype.command;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtAccordion.prototype.init = function () {
+    var _this5 = this;
+
+    if (this.element_) {
+      // Do the init required for this component to work
+      if (!(this.element_.classList.contains(ACCORDION_HORIZONTAL) || this.element_.classList.contains(ACCORDION_VERTICAL))) {
+        throw new Error('Accordion must have one of the classes "' + ACCORDION_HORIZONTAL + '" or "' + ACCORDION_VERTICAL + '"');
+      }
+
+      this.element_.setAttribute('role', 'tablist');
+
+      if (!this.element_.hasAttribute(_constants.ARIA_MULTISELECTABLE)) {
+        this.element_.setAttribute(_constants.ARIA_MULTISELECTABLE, 'false');
+      }
+
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + ACCORDION + ' > .' + PANEL))).forEach(function (panel) {
+        return _this5.upgradeTab(panel);
+      });
+
+      // Set upgraded flag
+      this.element_.classList.add(_constants.IS_UPGRADED);
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+   MaterialExtAccordion.prototype.mdlDowngrade_ = function() {
+     'use strict';
+     console.log('***** MaterialExtAccordion.mdlDowngrade');
+   };
+   */
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtAccordion,
+    classAsString: 'MaterialExtAccordion',
+    cssClass: 'mdlext-js-accordion',
+    widget: true
+  });
+})(); /**
+       * @license
+       * Copyright 2016 Leif Olsen. All Rights Reserved.
+       *
+       * Licensed under the Apache License, Version 2.0 (the "License");
+       * you may not use this file except in compliance with the License.
+       * You may obtain a copy of the License at
+       *
+       *      http://www.apache.org/licenses/LICENSE-2.0
+       *
+       * Unless required by applicable law or agreed to in writing, software
+       * distributed under the License is distributed on an "AS IS" BASIS,
+       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       * See the License for the specific language governing permissions and
+       * limitations under the License.
+       *
+       * This code is built with Google Material Design Lite,
+       * which is Licensed under the Apache License, Version 2.0
+       */
+
+/**
+ * A WAI-ARIA friendly accordion component.
+ * An accordion is a collection of expandable panels associated with a common outer container. Panels consist
+ * of a header and an associated content region or tabpanel. The primary use of an Accordion is to present multiple sections
+ * of content on a single page without scrolling, where all of the sections are peers in the application or object hierarchy.
+ * The general look is similar to a tree where each root tree node is an expandable accordion header. The user navigates
+ * and makes the contents of each panel visible (or not) by interacting with the Accordion Header
+ */
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/carousel/carousel.js b/node_modules/mdl-ext/es/carousel/carousel.js
new file mode 100644
index 0000000..51b9451
--- /dev/null
+++ b/node_modules/mdl-ext/es/carousel/carousel.js
@@ -0,0 +1,718 @@
+'use strict';
+
+var _isInteger = require('babel-runtime/core-js/number/is-integer');
+
+var _isInteger2 = _interopRequireDefault(_isInteger);
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _assign = require('babel-runtime/core-js/object/assign');
+
+var _assign2 = _interopRequireDefault(_assign);
+
+var _intervalFunction = require('../utils/interval-function');
+
+var _intervalFunction2 = _interopRequireDefault(_intervalFunction);
+
+var _easing = require('../utils/easing');
+
+var _jsonUtils = require('../utils/json-utils');
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * Image carousel
+ */
+
+var MDL_RIPPLE_CONTAINER = 'mdlext-carousel__slide__ripple-container';
+
+(function () {
+  'use strict';
+
+  //const CAROUSEL = 'mdlext-carousel';
+
+  var SLIDE = 'mdlext-carousel__slide';
+  var ROLE = 'list';
+  var SLIDE_ROLE = 'listitem';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtCarousel = function MaterialExtCarousel(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Default config
+    this.config_ = {
+      interactive: true,
+      autostart: false,
+      type: 'slide',
+      interval: 1000,
+      animationLoop: (0, _intervalFunction2.default)(1000)
+    };
+
+    this.scrollAnimation_ = (0, _intervalFunction2.default)(33);
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtCarousel'] = MaterialExtCarousel;
+
+  /**
+   * Start slideshow animation
+   * @private
+   */
+  MaterialExtCarousel.prototype.startSlideShow_ = function () {
+    var _this = this;
+
+    var nextSlide = function nextSlide() {
+      var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected]');
+      if (slide) {
+        slide.removeAttribute('aria-selected');
+        slide = slide.nextElementSibling;
+      }
+      if (!slide) {
+        slide = _this.element_.querySelector('.' + SLIDE + ':first-child');
+        _this.animateScroll_(0);
+      }
+      if (slide) {
+        _this.moveSlideIntoViewport_(slide);
+        slide.setAttribute('aria-selected', '');
+        _this.emitSelectEvent_('next', null, slide);
+        return true;
+      }
+      return false;
+    };
+
+    var nextScroll = function nextScroll(direction) {
+      var nextDirection = direction;
+
+      if ('next' === direction && _this.element_.scrollLeft === _this.element_.scrollWidth - _this.element_.clientWidth) {
+        nextDirection = 'prev';
+      } else if (_this.element_.scrollLeft === 0) {
+        nextDirection = 'next';
+      }
+      var x = 'next' === nextDirection ? Math.min(_this.element_.scrollLeft + _this.element_.clientWidth, _this.element_.scrollWidth - _this.element_.clientWidth) : Math.max(_this.element_.scrollLeft - _this.element_.clientWidth, 0);
+
+      _this.animateScroll_(x, 1000);
+      return nextDirection;
+    };
+
+    if (!this.config_.animationLoop.started) {
+      (function () {
+        _this.config_.animationLoop.interval = _this.config_.interval;
+        var direction = 'next';
+
+        if ('scroll' === _this.config_.type) {
+          _this.config_.animationLoop.start(function () {
+            direction = nextScroll(direction);
+            return true; // It runs until cancelSlideShow_ is triggered
+          });
+        } else {
+          nextSlide();
+          _this.config_.animationLoop.start(function () {
+            return nextSlide(); // It runs until cancelSlideShow_ is triggered
+          });
+        }
+      })();
+    }
+
+    // TODO: Pause animation when carousel is not in browser viewport or user changes tab
+  };
+
+  /**
+   * Cancel slideshow if running. Emmits a 'pause' event
+   * @private
+   */
+  MaterialExtCarousel.prototype.cancelSlideShow_ = function () {
+    if (this.config_.animationLoop.started) {
+      this.config_.animationLoop.stop();
+      this.emitSelectEvent_('pause', _constants.VK_ESC, this.element_.querySelector('.' + SLIDE + '[aria-selected]'));
+    }
+  };
+
+  /**
+   * Animate scroll
+   * @param newPosition
+   * @param newDuration
+   * @param completedCallback
+   * @private
+   */
+  MaterialExtCarousel.prototype.animateScroll_ = function (newPosition, newDuration, completedCallback) {
+    var _this2 = this;
+
+    var start = this.element_.scrollLeft;
+    var distance = newPosition - start;
+
+    if (distance !== 0) {
+      (function () {
+        var duration = Math.max(Math.min(Math.abs(distance), newDuration || 400), 100); // duration is between 100 and newDuration||400ms||distance
+        var t = 0;
+        _this2.scrollAnimation_.stop();
+        _this2.scrollAnimation_.start(function (timeElapsed) {
+          t += timeElapsed;
+          if (t < duration) {
+            _this2.element_.scrollLeft = (0, _easing.inOutQuintic)(t, start, distance, duration);
+            return true;
+          } else {
+            _this2.element_.scrollLeft = newPosition;
+            if (completedCallback) {
+              completedCallback();
+            }
+            return false;
+          }
+        });
+      })();
+    } else {
+      if (completedCallback) {
+        completedCallback();
+      }
+    }
+  };
+
+  /**
+   * Execute commend
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.command_ = function (event) {
+    var _this3 = this;
+
+    var x = 0;
+    var slide = null;
+    var a = event.detail.action.toLowerCase();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    switch (a) {
+      case 'first':
+        slide = this.element_.querySelector('.' + SLIDE + ':first-child');
+        break;
+
+      case 'last':
+        x = this.element_.scrollWidth - this.element_.clientWidth;
+        slide = this.element_.querySelector('.' + SLIDE + ':last-child');
+        break;
+
+      case 'scroll-prev':
+        x = Math.max(this.element_.scrollLeft - this.element_.clientWidth, 0);
+        break;
+
+      case 'scroll-next':
+        x = Math.min(this.element_.scrollLeft + this.element_.clientWidth, this.element_.scrollWidth - this.element_.clientWidth);
+        break;
+
+      case 'next':
+      case 'prev':
+        slide = this.element_.querySelector('.' + SLIDE + '[aria-selected]');
+        if (slide) {
+          slide = a === 'next' ? slide.nextElementSibling : slide.previousElementSibling;
+          this.setAriaSelected_(slide);
+          this.emitSelectEvent_(a, null, slide);
+        }
+        return;
+
+      case 'play':
+        (0, _assign2.default)(this.config_, event.detail);
+        this.startSlideShow_();
+        return;
+
+      case 'pause':
+        return;
+
+      default:
+        return;
+    }
+
+    this.animateScroll_(x, undefined, function () {
+      if ('scroll-next' === a || 'scroll-prev' === a) {
+        var slides = _this3.getSlidesInViewport_();
+        if (slides.length > 0) {
+          slide = 'scroll-next' === a ? slides[0] : slides[slides.length - 1];
+        }
+      }
+      _this3.setAriaSelected_(slide);
+      _this3.emitSelectEvent_(a, null, slide);
+    });
+  };
+
+  /**
+   * Handles custom command event, 'scroll-prev', 'scroll-next', 'first', 'last', next, prev, play, pause
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtCarousel.prototype.commandHandler_ = function (event) {
+    event.preventDefault();
+    event.stopPropagation();
+    if (event.detail && event.detail.action) {
+      this.command_(event);
+    }
+  };
+
+  /**
+   * Handle keypress
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.keyDownHandler_ = function (event) {
+
+    if (event && event.target && event.target !== this.element_) {
+
+      var action = 'first';
+
+      if (event.keyCode === _constants.VK_HOME || event.keyCode === _constants.VK_END || event.keyCode === _constants.VK_PAGE_UP || event.keyCode === _constants.VK_PAGE_DOWN) {
+
+        event.preventDefault();
+        if (event.keyCode === _constants.VK_END) {
+          action = 'last';
+        } else if (event.keyCode === _constants.VK_PAGE_UP) {
+          action = 'scroll-prev';
+        } else if (event.keyCode === _constants.VK_PAGE_DOWN) {
+          action = 'scroll-next';
+        }
+
+        var cmd = new CustomEvent('select', {
+          detail: {
+            action: action
+          }
+        });
+        this.command_(cmd);
+      } else if (event.keyCode === _constants.VK_TAB || event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE || event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT || event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {
+
+        var slide = getSlide_(event.target);
+
+        if (!slide) {
+          return;
+        }
+
+        // Cancel slideshow if running
+        this.cancelSlideShow_();
+
+        switch (event.keyCode) {
+          case _constants.VK_ARROW_UP:
+          case _constants.VK_ARROW_LEFT:
+            action = 'prev';
+            slide = slide.previousElementSibling;
+            break;
+
+          case _constants.VK_ARROW_DOWN:
+          case _constants.VK_ARROW_RIGHT:
+            action = 'next';
+            slide = slide.nextElementSibling;
+            break;
+
+          case _constants.VK_TAB:
+            if (event.shiftKey) {
+              action = 'prev';
+              slide = slide.previousElementSibling;
+            } else {
+              action = 'next';
+              slide = slide.nextElementSibling;
+            }
+            break;
+
+          case _constants.VK_SPACE:
+          case _constants.VK_ENTER:
+            action = 'select';
+            break;
+        }
+
+        if (slide) {
+          event.preventDefault();
+          setFocus_(slide);
+          this.emitSelectEvent_(action, event.keyCode, slide);
+        }
+      }
+    }
+  };
+
+  /**
+   * Handle dragging
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.dragHandler_ = function (event) {
+    var _this4 = this;
+
+    event.preventDefault();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    var updating = false;
+    var rAFDragId = 0;
+
+    var startX = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+    var prevX = startX;
+    var targetElement = event.target;
+
+    var update = function update(e) {
+      var currentX = e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0);
+      var dx = prevX - currentX;
+
+      if (dx < 0) {
+        _this4.element_.scrollLeft = Math.max(_this4.element_.scrollLeft + dx, 0);
+      } else if (dx > 0) {
+        _this4.element_.scrollLeft = Math.min(_this4.element_.scrollLeft + dx, _this4.element_.scrollWidth - _this4.element_.clientWidth);
+      }
+
+      prevX = currentX;
+      updating = false;
+    };
+
+    // drag handler
+    var drag = function drag(e) {
+      e.preventDefault();
+
+      if (!updating) {
+        rAFDragId = window.requestAnimationFrame(function () {
+          return update(e);
+        });
+        updating = true;
+      }
+    };
+
+    // end drag handler
+    var endDrag = function endDrag(e) {
+      e.preventDefault();
+
+      _this4.element_.removeEventListener('mousemove', drag);
+      _this4.element_.removeEventListener('touchmove', drag);
+      window.removeEventListener('mouseup', endDrag);
+      window.removeEventListener('touchend', endDrag);
+
+      // cancel any existing drag rAF, see: http://www.html5rocks.com/en/tutorials/speed/animations/
+      window.cancelAnimationFrame(rAFDragId);
+
+      var slide = getSlide_(targetElement);
+      setFocus_(slide);
+      _this4.emitSelectEvent_('click', null, slide);
+    };
+
+    this.element_.addEventListener('mousemove', drag);
+    this.element_.addEventListener('touchmove', drag);
+    window.addEventListener('mouseup', endDrag);
+    window.addEventListener('touchend', endDrag);
+  };
+
+  /**
+   * Handle click
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.clickHandler_ = function (event) {
+    // Click is handled by drag
+    event.preventDefault();
+  };
+
+  /**
+   * Handle focus
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.focusHandler_ = function (event) {
+    var slide = getSlide_(event.target);
+    if (slide) {
+      // The last focused/selected slide has 'aria-selected', even if focus is lost
+      this.setAriaSelected_(slide);
+      slide.classList.add(_constants.IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Handle blur
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.blurHandler_ = function (event) {
+    var slide = getSlide_(event.target);
+    if (slide) {
+      slide.classList.remove(_constants.IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Emits a custeom 'select' event
+   * @param command
+   * @param keyCode
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.emitSelectEvent_ = function (command, keyCode, slide) {
+
+    if (slide) {
+      this.moveSlideIntoViewport_(slide);
+
+      var evt = new CustomEvent('select', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          command: command,
+          keyCode: keyCode,
+          source: slide
+        }
+      });
+      this.element_.dispatchEvent(evt);
+    }
+  };
+
+  /**
+   * Get the first visible slide in component viewport
+   * @private
+   */
+  MaterialExtCarousel.prototype.getSlidesInViewport_ = function () {
+    var carouselRect = this.element_.getBoundingClientRect();
+
+    var slidesInViewport = [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).filter(function (slide) {
+      var slideRect = slide.getBoundingClientRect();
+      return slideRect.left >= carouselRect.left && slideRect.right <= carouselRect.right;
+    });
+    return slidesInViewport;
+  };
+
+  /**
+   * Move slide into component viewport - if needed
+   * @param slide
+   * @private
+   */
+  MaterialExtCarousel.prototype.moveSlideIntoViewport_ = function (slide) {
+    var carouselRect = this.element_.getBoundingClientRect();
+    var slideRect = slide.getBoundingClientRect();
+
+    if (slideRect.left < carouselRect.left) {
+      var x = this.element_.scrollLeft - (carouselRect.left - slideRect.left);
+      this.animateScroll_(x);
+    } else if (slideRect.right > carouselRect.right) {
+      var _x = this.element_.scrollLeft - (carouselRect.right - slideRect.right);
+      this.animateScroll_(_x);
+    }
+  };
+
+  /**
+   * Removes 'aria-selected' from all slides in carousel
+   * @private
+   */
+  MaterialExtCarousel.prototype.setAriaSelected_ = function (slide) {
+    if (slide) {
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE + '[aria-selected]'))).forEach(function (slide) {
+        return slide.removeAttribute('aria-selected');
+      });
+      slide.setAttribute('aria-selected', '');
+    }
+  };
+
+  /**
+   * Removes event listeners
+   * @private
+   */
+  MaterialExtCarousel.prototype.removeListeners_ = function () {
+    this.element_.removeEventListener('focus', this.focusHandler_);
+    this.element_.removeEventListener('blur', this.blurHandler_);
+    this.element_.removeEventListener('keydown', this.keyDownHandler_);
+    this.element_.removeEventListener('mousedown', this.dragHandler_);
+    this.element_.removeEventListener('touchstart', this.dragHandler_);
+    this.element_.removeEventListener('click', this.clickHandler_, false);
+    this.element_.removeEventListener('command', this.commandHandler_);
+    this.element_.removeEventListener('mdl-componentdowngraded', this.mdlDowngrade_);
+  };
+
+  // Helpers
+  var getSlide_ = function getSlide_(element) {
+    return element.closest('.' + SLIDE);
+  };
+
+  var setFocus_ = function setFocus_(slide) {
+    if (slide) {
+      slide.focus();
+    }
+  };
+
+  var addRipple_ = function addRipple_(slide) {
+    if (!slide.querySelector('.' + MDL_RIPPLE_CONTAINER)) {
+      var rippleContainer = document.createElement('span');
+      rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+      rippleContainer.classList.add(_constants.MDL_RIPPLE_EFFECT);
+      var ripple = document.createElement('span');
+      ripple.classList.add(_constants.MDL_RIPPLE);
+      rippleContainer.appendChild(ripple);
+
+      var img = slide.querySelector('img');
+      if (img) {
+        // rippleContainer blocks image title
+        rippleContainer.title = img.title;
+      }
+      slide.appendChild(rippleContainer);
+      componentHandler.upgradeElement(rippleContainer, _constants.MDL_RIPPLE_COMPONENT);
+    }
+  };
+  // End helpers
+
+
+  // Public methods.
+
+  /**
+   * Cancel animation - if running.
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.stopAnimation = function () {
+    this.config_.animationLoop.stop();
+  };
+  MaterialExtCarousel.prototype['stopAnimation'] = MaterialExtCarousel.prototype.stopAnimation;
+
+  /**
+   * Upgrade slides
+   * Use if more list elements are added later (dynamically)
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.upgradeSlides = function () {
+    var _this5 = this;
+
+    var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+
+    [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).forEach(function (slide) {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if (_this5.config_.interactive) {
+        if (!slide.getAttribute('tabindex')) {
+          slide.setAttribute('tabindex', '0');
+        }
+        if (hasRippleEffect) {
+          addRipple_(slide);
+        }
+      } else {
+        slide.setAttribute('tabindex', '-1');
+      }
+    });
+  };
+  MaterialExtCarousel.prototype['upgradeSlides'] = MaterialExtCarousel.prototype.upgradeSlides;
+
+  /**
+   * Get config object
+   *
+   * @public
+   */
+  MaterialExtCarousel.prototype.getConfig = function () {
+    return this.config_;
+  };
+  MaterialExtCarousel.prototype['getConfig'] = MaterialExtCarousel.prototype.getConfig;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCarousel.prototype.init = function () {
+
+    if (this.element_) {
+      // Config
+      if (this.element_.hasAttribute('data-config')) {
+        this.config_ = (0, _jsonUtils.jsonStringToObject)(this.element_.getAttribute('data-config'), this.config_);
+      }
+
+      // Wai-Aria
+      this.element_.setAttribute('role', ROLE);
+
+      // Prefer tabindex -1
+      if (!(0, _isInteger2.default)(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', -1);
+      }
+
+      // Remove listeners, just in case ...
+      this.removeListeners_();
+
+      if (this.config_.interactive) {
+
+        // Ripple
+        var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+        if (hasRippleEffect) {
+          this.element_.classList.add(_constants.MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+        }
+
+        // Listen to focus/blur events
+        this.element_.addEventListener('focus', this.focusHandler_.bind(this), true);
+        this.element_.addEventListener('blur', this.blurHandler_.bind(this), true);
+
+        // Listen to keyboard events
+        this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this), false);
+
+        // Listen to drag events
+        this.element_.addEventListener('mousedown', this.dragHandler_.bind(this), false);
+        this.element_.addEventListener('touchstart', this.dragHandler_.bind(this), false);
+
+        // Listen to click events
+        this.element_.addEventListener('click', this.clickHandler_.bind(this), false);
+      }
+
+      // Listen to custom 'command' event
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+
+      // Slides collection
+      this.upgradeSlides();
+
+      // Set upgraded flag
+      this.element_.classList.add(_constants.IS_UPGRADED);
+
+      if (this.config_.autostart) {
+        // Start slideshow
+        this.startSlideShow_();
+      }
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCarousel.prototype.mdlDowngrade_ = function () {
+    'use strict';
+    //console.log('***** MaterialExtCarousel.mdlDowngrade_');
+
+    // Stop animation - if any
+
+    this.stopAnimation();
+
+    // Remove listeners
+    this.removeListeners_();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCarousel,
+    classAsString: 'MaterialExtCarousel',
+    cssClass: 'mdlext-js-carousel',
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/collapsible/collapsible.js b/node_modules/mdl-ext/es/collapsible/collapsible.js
new file mode 100644
index 0000000..80c2db0
--- /dev/null
+++ b/node_modules/mdl-ext/es/collapsible/collapsible.js
@@ -0,0 +1,481 @@
+'use strict';
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _constants = require('../utils/constants');
+
+var _stringUtils = require('../utils/string-utils');
+
+var _domUtils = require('../utils/dom-utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var JS_COLLAPSIBLE = 'mdlext-js-collapsible'; /**
+                                               * @license
+                                               * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+                                               *
+                                               * Licensed under the Apache License, Version 2.0 (the "License");
+                                               * you may not use this file except in compliance with the License.
+                                               * You may obtain a copy of the License at
+                                               *
+                                               *      http://www.apache.org/licenses/LICENSE-2.0
+                                               *
+                                               * Unless required by applicable law or agreed to in writing, software
+                                               * distributed under the License is distributed on an "AS IS" BASIS,
+                                               * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+                                               * See the License for the specific language governing permissions and
+                                               * limitations under the License.
+                                               *
+                                               * This code is built with Google Material Design Lite,
+                                               * which is Licensed under the Apache License, Version 2.0
+                                               */
+
+/**
+ * A collapsible is a component to mark expandable and collapsible regions.
+ * The component use the aria-expanded state to indicate whether regions of
+ * the content are collapsible, and to expose whether a region is currently
+ * expanded or collapsed.
+ * @see https://www.w3.org/WAI/GL/wiki/Using_the_WAI-ARIA_aria-expanded_state_to_mark_expandable_and_collapsible_regions
+ */
+
+var COLLAPSIBLE_CONTROL_CLASS = 'mdlext-collapsible';
+var COLLAPSIBLE_GROUP_CLASS = 'mdlext-collapsible-group';
+var COLLAPSIBLE_REGION_CLASS = 'mdlext-collapsible-region';
+
+/**
+ * The collapsible component
+ */
+
+var Collapsible = function () {
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that this component is connected to.
+   */
+  function Collapsible(element) {
+    var _this = this;
+
+    (0, _classCallCheck3.default)(this, Collapsible);
+    this.element_ = null;
+    this.controlElement_ = null;
+
+    this.keyDownHandler = function (event) {
+      if (event.keyCode === _constants.VK_ENTER || event.keyCode === _constants.VK_SPACE) {
+        event.preventDefault();
+
+        // Trigger click
+        (event.target || _this.controlElement).dispatchEvent(new MouseEvent('click', {
+          bubbles: true,
+          cancelable: true,
+          view: window
+        }));
+      }
+    };
+
+    this.clickHandler = function (event) {
+      if (!_this.isDisabled) {
+        if (event.target !== _this.controlElement) {
+          // Do not toggle if a focusable element inside the control element triggered the event
+          var p = (0, _domUtils.getParentElements)(event.target, _this.controlElement);
+          p.push(event.target);
+          if (p.find(function (el) {
+            return (0, _domUtils.isFocusable)(el);
+          })) {
+            return;
+          }
+        }
+        _this.toggle();
+      }
+    };
+
+    this.element_ = element;
+    this.init();
+  }
+
+  (0, _createClass3.default)(Collapsible, [{
+    key: 'collapse',
+    value: function collapse() {
+      if (!this.isDisabled && this.isExpanded) {
+        if (this.dispatchToggleEvent('collapse')) {
+          this.controlElement.setAttribute('aria-expanded', 'false');
+          var regions = this.regionElements.slice(0);
+          for (var i = regions.length - 1; i >= 0; --i) {
+            regions[i].setAttribute('hidden', '');
+          }
+        }
+      }
+    }
+  }, {
+    key: 'expand',
+    value: function expand() {
+      if (!this.isDisabled && !this.isExpanded) {
+        if (this.dispatchToggleEvent('expand')) {
+          this.controlElement.setAttribute('aria-expanded', 'true');
+          this.regionElements.forEach(function (region) {
+            return region.removeAttribute('hidden');
+          });
+        }
+      }
+    }
+  }, {
+    key: 'toggle',
+    value: function toggle() {
+      if (this.isExpanded) {
+        this.collapse();
+      } else {
+        this.expand();
+      }
+    }
+  }, {
+    key: 'dispatchToggleEvent',
+    value: function dispatchToggleEvent(action) {
+      return this.element.dispatchEvent(new CustomEvent('toggle', {
+        bubbles: true,
+        cancelable: true,
+        detail: {
+          action: action
+        }
+      }));
+    }
+  }, {
+    key: 'disableToggle',
+    value: function disableToggle() {
+      this.controlElement.setAttribute('aria-disabled', true);
+    }
+  }, {
+    key: 'enableToggle',
+    value: function enableToggle() {
+      this.controlElement.removeAttribute('aria-disabled');
+    }
+  }, {
+    key: 'addRegionId',
+    value: function addRegionId(regionId) {
+      var ids = this.regionIds;
+      if (!ids.find(function (id) {
+        return regionId === id;
+      })) {
+        ids.push(regionId);
+        this.controlElement.setAttribute('aria-controls', ids.join(' '));
+      }
+    }
+  }, {
+    key: 'addRegionElement',
+    value: function addRegionElement(region) {
+      if (!(region.classList.contains(COLLAPSIBLE_GROUP_CLASS) || region.classList.contains(COLLAPSIBLE_REGION_CLASS))) {
+        region.classList.add(COLLAPSIBLE_GROUP_CLASS);
+      }
+
+      if (!region.hasAttribute('role')) {
+        var role = region.classList.contains(COLLAPSIBLE_GROUP_CLASS) ? 'group' : 'region';
+        region.setAttribute('role', role);
+      }
+
+      if (!region.hasAttribute('id')) {
+        region.id = region.getAttribute('role') + '-' + (0, _stringUtils.randomString)();
+      }
+
+      if (this.isExpanded) {
+        region.removeAttribute('hidden');
+      } else {
+        region.setAttribute('hidden', '');
+      }
+      this.addRegionId(region.id);
+    }
+  }, {
+    key: 'removeRegionElement',
+    value: function removeRegionElement(region) {
+      if (region && region.id) {
+        var ids = this.regionIds.filter(function (id) {
+          return id === region.id;
+        });
+        this.controlElement.setAttribute('aria-controls', ids.join(' '));
+      }
+    }
+  }, {
+    key: 'removeListeners',
+    value: function removeListeners() {
+      this.controlElement.removeEventListener('keydown', this.keyDownHandler);
+      this.controlElement.removeEventListener('click', this.clickHandler);
+    }
+  }, {
+    key: 'init',
+    value: function init() {
+      var _this2 = this;
+
+      var initControl = function initControl() {
+        // Find the button element
+        _this2.controlElement_ = _this2.element.querySelector('.' + COLLAPSIBLE_CONTROL_CLASS) || _this2.element;
+
+        // Add "aria-expanded" attribute if not present
+        if (!_this2.controlElement.hasAttribute('aria-expanded')) {
+          _this2.controlElement.setAttribute('aria-expanded', 'false');
+        }
+
+        // Add role=button if control != <button>
+        if (_this2.controlElement.nodeName.toLowerCase() !== 'button') {
+          _this2.controlElement.setAttribute('role', 'button');
+        }
+
+        // Add tabindex
+        if (!(0, _domUtils.isFocusable)(_this2.controlElement) && !_this2.controlElement.hasAttribute('tabindex')) {
+          _this2.controlElement.setAttribute('tabindex', '0');
+        }
+      };
+
+      var initRegions = function initRegions() {
+        var regions = [];
+        if (!_this2.controlElement.hasAttribute('aria-controls')) {
+          // Add siblings as collapsible region(s)
+          var r = _this2.element.nextElementSibling;
+          while (r) {
+            if (r.classList.contains(COLLAPSIBLE_GROUP_CLASS) || r.classList.contains(COLLAPSIBLE_REGION_CLASS)) {
+              regions.push(r);
+            } else if (r.classList.contains(JS_COLLAPSIBLE)) {
+              // A new collapsible component
+              break;
+            }
+            r = r.nextElementSibling;
+          }
+        } else {
+          regions = _this2.regionElements;
+        }
+        regions.forEach(function (region) {
+          return _this2.addRegionElement(region);
+        });
+      };
+
+      var addListeners = function addListeners() {
+        _this2.controlElement.addEventListener('keydown', _this2.keyDownHandler);
+        _this2.controlElement.addEventListener('click', _this2.clickHandler);
+      };
+
+      initControl();
+      initRegions();
+      this.removeListeners();
+      addListeners();
+    }
+  }, {
+    key: 'downgrade',
+    value: function downgrade() {
+      this.removeListeners();
+    }
+  }, {
+    key: 'element',
+    get: function get() {
+      return this.element_;
+    }
+  }, {
+    key: 'controlElement',
+    get: function get() {
+      return this.controlElement_;
+    }
+  }, {
+    key: 'isDisabled',
+    get: function get() {
+      return this.controlElement.hasAttribute('disabled') && this.controlElement.getAttribute('disabled').toLowerCase() !== 'false' || this.controlElement.hasAttribute('aria-disabled') && this.controlElement.getAttribute('aria-disabled').toLowerCase() !== 'false';
+    }
+  }, {
+    key: 'isExpanded',
+    get: function get() {
+      return this.controlElement.hasAttribute('aria-expanded') && this.controlElement.getAttribute('aria-expanded').toLowerCase() === 'true';
+    }
+  }, {
+    key: 'regionIds',
+    get: function get() {
+      return this.controlElement.hasAttribute('aria-controls') ? this.controlElement.getAttribute('aria-controls').split(' ') : [];
+    }
+  }, {
+    key: 'regionElements',
+    get: function get() {
+      return this.regionIds.map(function (id) {
+        return document.querySelector('#' + id);
+      }).filter(function (el) {
+        return el != null;
+      });
+    }
+  }]);
+  return Collapsible;
+}();
+
+(function () {
+  'use strict';
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+
+  var MaterialExtCollapsible = function MaterialExtCollapsible(element) {
+    this.element_ = element;
+    this.collapsible = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtCollapsible'] = MaterialExtCollapsible;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtCollapsible.prototype.init = function () {
+    if (this.element_) {
+      this.collapsible = new Collapsible(this.element_);
+      this.element_.classList.add(_constants.IS_UPGRADED);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtCollapsible.prototype.mdlDowngrade_ = function () {
+    this.collapsible.downgrade();
+  };
+
+  // Public methods.
+
+  /**
+   * Get control element.
+   * @return {HTMLElement} element The element that controls the collapsible region.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getControlElement = function () {
+    return this.collapsible.controlElement;
+  };
+  MaterialExtCollapsible.prototype['getControlElement'] = MaterialExtCollapsible.prototype.getControlElement;
+
+  /**
+   * Get region elements controlled by this collapsible
+   * @returns {Array<HTMLElement>} the collapsible region elements
+   * @public
+   */
+  MaterialExtCollapsible.prototype.getRegionElements = function () {
+    return this.collapsible.regionElements;
+  };
+  MaterialExtCollapsible.prototype['getRegionElements'] = MaterialExtCollapsible.prototype.getRegionElements;
+
+  /**
+   * Add region elements.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.addRegionElements = function () {
+    var _this3 = this;
+
+    for (var _len = arguments.length, elements = Array(_len), _key = 0; _key < _len; _key++) {
+      elements[_key] = arguments[_key];
+    }
+
+    elements.forEach(function (element) {
+      return _this3.collapsible.addRegionElement(element);
+    });
+  };
+  MaterialExtCollapsible.prototype['addRegionElements'] = MaterialExtCollapsible.prototype.addRegionElements;
+
+  /**
+   * Remove collapsible region(s) from component.
+   * Note: This operation does not delete the element from the DOM tree.
+   * @param {Array<HTMLElement>} elements The element that will be upgraded.
+   * @public
+   */
+  MaterialExtCollapsible.prototype.removeRegionElements = function () {
+    var _this4 = this;
+
+    for (var _len2 = arguments.length, elements = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+      elements[_key2] = arguments[_key2];
+    }
+
+    elements.forEach(function (element) {
+      return _this4.collapsible.removeRegionElement(element);
+    });
+  };
+  MaterialExtCollapsible.prototype['removeRegionElements'] = MaterialExtCollapsible.prototype.removeRegionElements;
+
+  /**
+   * Expand collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.expand = function () {
+    this.collapsible.expand();
+  };
+  MaterialExtCollapsible.prototype['expand'] = MaterialExtCollapsible.prototype.expand;
+
+  /**
+   * Collapse collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.collapse = function () {
+    this.collapsible.collapse();
+  };
+  MaterialExtCollapsible.prototype['collapse'] = MaterialExtCollapsible.prototype.collapse;
+
+  /**
+   * Toggle collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.toggle = function () {
+    this.collapsible.toggle();
+  };
+  MaterialExtCollapsible.prototype['toggle'] = MaterialExtCollapsible.prototype.toggle;
+
+  /**
+   * Check whether component has aria-expanded state true
+   * @return {Boolean} true if aria-expanded="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isExpanded = function () {
+    return this.collapsible.isExpanded;
+  };
+  MaterialExtCollapsible.prototype['isExpanded'] = MaterialExtCollapsible.prototype.isExpanded;
+
+  /**
+   * Check whether component has aria-disabled state set to true
+   * @return {Boolean} true if aria-disabled="true", otherwise false
+   */
+  MaterialExtCollapsible.prototype.isDisabled = function () {
+    return this.collapsible.isDisabled;
+  };
+  MaterialExtCollapsible.prototype['isDisabled'] = MaterialExtCollapsible.prototype.isDisabled;
+
+  /**
+   * Disables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.disableToggle = function () {
+    this.collapsible.disableToggle();
+  };
+  MaterialExtCollapsible.prototype['disableToggle'] = MaterialExtCollapsible.prototype.disableToggle;
+
+  /**
+   * Enables toggling of collapsible region(s)
+   * @return {void}
+   * @public
+   */
+  MaterialExtCollapsible.prototype.enableToggle = function () {
+    this.collapsible.enableToggle();
+  };
+  MaterialExtCollapsible.prototype['enableToggle'] = MaterialExtCollapsible.prototype.enableToggle;
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtCollapsible,
+    classAsString: 'MaterialExtCollapsible',
+    cssClass: JS_COLLAPSIBLE,
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/formatfield/formatfield.js b/node_modules/mdl-ext/es/formatfield/formatfield.js
new file mode 100644
index 0000000..271da23
--- /dev/null
+++ b/node_modules/mdl-ext/es/formatfield/formatfield.js
@@ -0,0 +1,306 @@
+'use strict';
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _jsonUtils = require('../utils/json-utils');
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * @license
+ * Copyright 2016-2017 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+var JS_FORMAT_FIELD = 'mdlext-js-formatfield';
+var FORMAT_FIELD_COMPONENT = 'MaterialExtFormatfield';
+
+/**
+ * Detect browser locale
+ * @returns {string} the locale
+ * @see http://stackoverflow.com/questions/1043339/javascript-for-detecting-browser-language-preference
+ */
+var browserLanguage = function browserLanguage() {
+  return navigator.languages ? navigator.languages[0] : navigator.language || navigator.userLanguage;
+};
+
+/**
+ * The formatfield  formats an input field  using language sensitive number formatting.
+ */
+
+var FormatField = function () {
+  function FormatField(element) {
+    var _this = this;
+
+    (0, _classCallCheck3.default)(this, FormatField);
+    this.options_ = {};
+
+    this.clickHandler = function () {
+      clearTimeout(FormatField.timer);
+    };
+
+    this.focusInHandler = function () {
+      if (!(_this.input.readOnly || _this.input.disabled)) {
+        _this.input.value = _this.unformatInput();
+        //setTimeout(() => this.input.setSelectionRange(0, this.input.value.length), 20);
+        FormatField.timer = setTimeout(function () {
+          return _this.input.select();
+        }, 200);
+      }
+    };
+
+    this.focusOutHandler = function () {
+      clearTimeout(FormatField.timer);
+
+      if (!(_this.input.readOnly || _this.input.disabled)) {
+        _this.formatValue();
+      }
+    };
+
+    this.element_ = element;
+    this.init();
+  }
+
+  (0, _createClass3.default)(FormatField, [{
+    key: 'stripSeparatorsFromValue',
+    value: function stripSeparatorsFromValue() {
+      var _this2 = this;
+
+      var doReplace = function doReplace() {
+        return _this2.input.value.replace(/\s/g, '').replace(new RegExp(_this2.options.groupSeparator, 'g'), '').replace(_this2.options.decimalSeparator, '.');
+      };
+      //.replace(this.intlGroupSeparator_, ''),
+      //.replace(this.intlDecimalSeparator_, '.');
+
+      return this.input.value ? doReplace() : this.input.value;
+    }
+  }, {
+    key: 'fixSeparators',
+    value: function fixSeparators(value) {
+      var _this3 = this;
+
+      var doReplace = function doReplace() {
+        return value.replace(new RegExp(_this3.intlGroupSeparator_, 'g'), _this3.options.groupSeparator).replace(_this3.intlDecimalSeparator_, _this3.options.decimalSeparator);
+      };
+
+      return value ? doReplace() : value;
+    }
+  }, {
+    key: 'formatValue',
+    value: function formatValue() {
+      if (this.input.value) {
+        var v = new Intl.NumberFormat(this.options.locales, this.options).format(this.stripSeparatorsFromValue());
+
+        if ('NaN' !== v) {
+          this.input.value = this.fixSeparators(v);
+        }
+      }
+    }
+  }, {
+    key: 'unformat',
+    value: function unformat() {
+      var _this4 = this;
+
+      var doReplace = function doReplace() {
+        return _this4.input.value.replace(/\s/g, '').replace(new RegExp(_this4.options.groupSeparator, 'g'), '').replace(_this4.options.decimalSeparator, '.');
+      };
+
+      return this.input.value ? doReplace() : this.input.value;
+    }
+  }, {
+    key: 'unformatInput',
+    value: function unformatInput() {
+      var _this5 = this;
+
+      var doReplace = function doReplace() {
+        return _this5.input.value.replace(/\s/g, '').replace(new RegExp(_this5.options.groupSeparator, 'g'), '');
+      };
+
+      return this.input.value ? doReplace() : this.input.value;
+    }
+  }, {
+    key: 'removeListeners',
+    value: function removeListeners() {
+      this.input.removeEventListener('click', this.clickHandler);
+      this.input.removeEventListener('focusin', this.focusInHandler);
+      this.input.removeEventListener('focusout', this.focusOutHandler);
+    }
+  }, {
+    key: 'init',
+    value: function init() {
+      var _this6 = this;
+
+      var addListeners = function addListeners() {
+        _this6.input.addEventListener('click', _this6.clickHandler);
+        _this6.input.addEventListener('focusin', _this6.focusInHandler);
+        _this6.input.addEventListener('focusout', _this6.focusOutHandler);
+      };
+
+      var addOptions = function addOptions() {
+        var opts = _this6.element.getAttribute('data-formatfield-options') || _this6.input.getAttribute('data-formatfield-options');
+        if (opts) {
+          _this6.options_ = (0, _jsonUtils.jsonStringToObject)(opts, _this6.options);
+        }
+      };
+
+      var addLocale = function addLocale() {
+        if (!_this6.options.locales) {
+          _this6.options.locales = browserLanguage() || 'en-US'; //'nb-NO', //'en-US',
+        }
+      };
+
+      var addGrouping = function addGrouping() {
+        var s = 1234.5.toLocaleString(_this6.options.locales, {
+          style: 'decimal',
+          useGrouping: true,
+          minimumFractionDigits: 1,
+          maximumFractionDigits: 1
+        });
+
+        _this6.intlGroupSeparator_ = s.charAt(1);
+        _this6.intlDecimalSeparator_ = s.charAt(s.length - 2);
+        _this6.options.groupSeparator = _this6.options.groupSeparator || _this6.intlGroupSeparator_;
+        _this6.options.decimalSeparator = _this6.options.decimalSeparator || _this6.intlDecimalSeparator_;
+
+        if (_this6.options.groupSeparator === _this6.options.decimalSeparator) {
+          var e = 'Error! options.groupSeparator, "' + _this6.options.groupSeparator + '" ' + 'and options.decimalSeparator, ' + ('"' + _this6.options.decimalSeparator + '" should not be equal');
+          throw new Error(e);
+        }
+      };
+
+      this.input_ = this.element.querySelector('input') || this.element;
+
+      addOptions();
+      addLocale();
+      addGrouping();
+      this.formatValue();
+      addListeners();
+    }
+  }, {
+    key: 'downgrade',
+    value: function downgrade() {
+      this.removeListeners();
+    }
+  }, {
+    key: 'element',
+    get: function get() {
+      return this.element_;
+    }
+  }, {
+    key: 'input',
+    get: function get() {
+      return this.input_;
+    }
+  }, {
+    key: 'options',
+    get: function get() {
+      return this.options_;
+    }
+  }]);
+  return FormatField;
+}();
+
+FormatField.timer = null;
+
+
+(function () {
+  'use strict';
+
+  /**
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+
+  var MaterialExtFormatfield = function MaterialExtFormatfield(element) {
+    this.element_ = element;
+    this.formatField_ = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtFormatfield'] = MaterialExtFormatfield;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtFormatfield.prototype.init = function () {
+    if (this.element_) {
+      this.element_.classList.add(_constants.IS_UPGRADED);
+      this.formatField_ = new FormatField(this.element_);
+
+      // Listen to 'mdl-componentdowngraded' event
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+    }
+  };
+
+  /**
+   * Get options object
+   *
+   * @public
+   *
+   * @returns {Object} the options object
+   */
+  MaterialExtFormatfield.prototype.getOptions = function () {
+    return this.formatField_.options;
+  };
+  MaterialExtFormatfield.prototype['getOptions'] = MaterialExtFormatfield.prototype.getOptions;
+
+  /**
+   * A unformatted value is a string value where the locale specific decimal separator
+   * is replaced with a '.' separator and group separators are stripped.
+   * The returned value is suitable for parsing to a JavaScript numerical value.
+   *
+   * @example
+   * input.value = '1 234,5';
+   * inputElement.MaterialExtFormatfield.getUnformattedValue();
+   * // Returns '1234.5'
+   *
+   * @public
+   *
+   * @returns {String} the unformatted value
+   */
+  MaterialExtFormatfield.prototype.getUnformattedValue = function () {
+    return this.formatField_.unformat();
+  };
+  MaterialExtFormatfield.prototype['getUnformattedValue'] = MaterialExtFormatfield.prototype.getUnformattedValue;
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtFormatfield.prototype.mdlDowngrade_ = function () {
+    this.formatField_.downgrade();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtFormatfield,
+    classAsString: FORMAT_FIELD_COMPONENT,
+    cssClass: JS_FORMAT_FIELD,
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/index.js b/node_modules/mdl-ext/es/index.js
new file mode 100644
index 0000000..4407b52
--- /dev/null
+++ b/node_modules/mdl-ext/es/index.js
@@ -0,0 +1,21 @@
+'use strict';
+
+require('./utils');
+
+require('./accordion/accordion');
+
+require('./collapsible/collapsible');
+
+require('./carousel/carousel');
+
+require('./lightboard/lightboard');
+
+require('./lightbox/lightbox');
+
+require('./menu-button/menu-button');
+
+require('./selectfield/selectfield');
+
+require('./formatfield/formatfield');
+
+require('./sticky-header/sticky-header');
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/lightboard/lightboard.js b/node_modules/mdl-ext/es/lightboard/lightboard.js
new file mode 100644
index 0000000..03ceed8
--- /dev/null
+++ b/node_modules/mdl-ext/es/lightboard/lightboard.js
@@ -0,0 +1,316 @@
+'use strict';
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var MDL_RIPPLE_CONTAINER = 'mdlext-lightboard__slide__ripple-container'; /**
+                                                                          * @license
+                                                                          * Copyright 2016 Leif Olsen. All Rights Reserved.
+                                                                          *
+                                                                          * Licensed under the Apache License, Version 2.0 (the "License");
+                                                                          * you may not use this file except in compliance with the License.
+                                                                          * You may obtain a copy of the License at
+                                                                          *
+                                                                          *      http://www.apache.org/licenses/LICENSE-2.0
+                                                                          *
+                                                                          * Unless required by applicable law or agreed to in writing, software
+                                                                          * distributed under the License is distributed on an "AS IS" BASIS,
+                                                                          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+                                                                          * See the License for the specific language governing permissions and
+                                                                          * limitations under the License.
+                                                                          *
+                                                                          * This code is built with Google Material Design Lite,
+                                                                          * which is Licensed under the Apache License, Version 2.0
+                                                                          */
+
+/**
+ * A lightboard is a translucent surface illuminated from behind, used for situations
+ * where a shape laid upon the surface needs to be seen with high contrast. In the "old days" of photography
+ * photograpers used a lightboard to get a quick view of their slides. The goal is to create a responsive lightbox
+ * design, based on flex layout, similar to what is used in Adobe LightRoom to browse images.
+ */
+
+(function () {
+  'use strict';
+
+  //const LIGHTBOARD = 'mdlext-lightboard';
+
+  var LIGHTBOARD_ROLE = 'grid';
+  var SLIDE = 'mdlext-lightboard__slide';
+  var SLIDE_ROLE = 'gridcell';
+  var SLIDE_TABSTOP = 'mdlext-lightboard__slide__frame';
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtLightboard = function MaterialExtLightboard(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtLightboard'] = MaterialExtLightboard;
+
+  // Helpers
+  var getSlide = function getSlide(element) {
+    return element ? element.closest('.' + SLIDE) : null;
+  };
+
+  // Private methods.
+
+  /**
+   * Select a slide, i.e. set aria-selected="true"
+   * @param element
+   * @private
+   */
+  MaterialExtLightboard.prototype.selectSlide_ = function (element) {
+    var slide = getSlide(element);
+    if (slide && !slide.hasAttribute('aria-selected')) {
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE + '[aria-selected="true"]'))).forEach(function (selectedSlide) {
+        return selectedSlide.removeAttribute('aria-selected');
+      });
+
+      slide.setAttribute('aria-selected', 'true');
+    }
+  };
+
+  /**
+   * Dispatch select event
+   * @param {Element} slide The slide that caused the event
+   * @private
+   */
+  MaterialExtLightboard.prototype.dispatchSelectEvent_ = function (slide) {
+    this.element_.dispatchEvent(new CustomEvent('select', {
+      bubbles: true,
+      cancelable: true,
+      detail: { source: slide }
+    }));
+  };
+
+  /**
+   * Handles custom command event, 'first', 'next', 'prev', 'last', 'select' or upgrade
+   * @param event. A custom event
+   * @private
+   */
+  MaterialExtLightboard.prototype.commandHandler_ = function (event) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if (event && event.detail) {
+      this.command(event.detail);
+    }
+  };
+
+  // Public methods
+
+  /**
+   * Initialize lightboard slides
+   * @public
+   */
+  MaterialExtLightboard.prototype.upgradeSlides = function () {
+
+    var addRipple = function addRipple(slide) {
+      // Use slide frame as ripple container
+      if (!slide.querySelector('.' + MDL_RIPPLE_CONTAINER)) {
+        var a = slide.querySelector('.' + SLIDE_TABSTOP);
+        if (a) {
+          var rippleContainer = a;
+          rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+          rippleContainer.classList.add(_constants.MDL_RIPPLE_EFFECT);
+          var ripple = document.createElement('span');
+          ripple.classList.add(_constants.MDL_RIPPLE);
+          rippleContainer.appendChild(ripple);
+          componentHandler.upgradeElement(rippleContainer, _constants.MDL_RIPPLE_COMPONENT);
+        }
+      }
+    };
+
+    var hasRippleEffect = this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT);
+
+    [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + SLIDE))).forEach(function (slide) {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if (!slide.querySelector('a')) {
+        slide.setAttribute('tabindex', '0');
+      }
+      if (hasRippleEffect) {
+        addRipple(slide);
+      }
+    });
+  };
+  MaterialExtLightboard.prototype['upgradeSlides'] = MaterialExtLightboard.prototype.upgradeSlides;
+
+  /**
+   * Execute command
+   * @param detail
+   * @public
+   */
+  MaterialExtLightboard.prototype.command = function (detail) {
+    var _this = this;
+
+    var firstSlide = function firstSlide() {
+      return _this.element_.querySelector('.' + SLIDE + ':first-child');
+    };
+
+    var lastSlide = function lastSlide() {
+      return _this.element_.querySelector('.' + SLIDE + ':last-child');
+    };
+
+    var nextSlide = function nextSlide() {
+      var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected="true"]').nextElementSibling;
+      return slide ? slide : firstSlide();
+    };
+
+    var prevSlide = function prevSlide() {
+      var slide = _this.element_.querySelector('.' + SLIDE + '[aria-selected="true"]').previousElementSibling;
+      return slide ? slide : lastSlide();
+    };
+
+    if (detail && detail.action) {
+      var action = detail.action,
+          target = detail.target;
+
+
+      var slide = void 0;
+      switch (action.toLowerCase()) {
+        case 'select':
+          slide = getSlide(target);
+          this.dispatchSelectEvent_(slide);
+          break;
+        case 'first':
+          slide = firstSlide();
+          break;
+        case 'next':
+          slide = nextSlide();
+          break;
+        case 'prev':
+          slide = prevSlide();
+          break;
+        case 'last':
+          slide = lastSlide();
+          break;
+        case 'upgrade':
+          this.upgradeSlides();
+          break;
+        default:
+          throw new Error('Unknown action "' + action + '". Action must be one of "first", "next", "prev", "last", "select" or "upgrade"');
+      }
+
+      if (slide) {
+        var a = slide.querySelector('a');
+        if (a) {
+          a.focus();
+        } else {
+          slide.focus();
+        }
+
+        // Workaround for JSDom testing:
+        // In JsDom 'element.focus()' does not trigger any focus event
+        if (!slide.hasAttribute('aria-selected')) {
+          this.selectSlide_(slide);
+        }
+      }
+    }
+  };
+  MaterialExtLightboard.prototype['command'] = MaterialExtLightboard.prototype.command;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtLightboard.prototype.init = function () {
+    var _this2 = this;
+
+    var keydownHandler = function keydownHandler(event) {
+
+      if (event.target !== _this2.element_) {
+        var action = void 0;
+        var target = void 0;
+        switch (event.keyCode) {
+          case _constants.VK_HOME:
+            action = 'first';
+            break;
+          case _constants.VK_END:
+            action = 'last';
+            break;
+          case _constants.VK_ARROW_UP:
+          case _constants.VK_ARROW_LEFT:
+            action = 'prev';
+            break;
+          case _constants.VK_ARROW_DOWN:
+          case _constants.VK_ARROW_RIGHT:
+            action = 'next';
+            break;
+          case _constants.VK_ENTER:
+          case _constants.VK_SPACE:
+            action = 'select';
+            target = event.target;
+            break;
+        }
+        if (action) {
+          event.preventDefault();
+          event.stopPropagation();
+          _this2.command({ action: action, target: target });
+        }
+      }
+    };
+
+    var clickHandler = function clickHandler(event) {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if (event.target !== _this2.element_) {
+        _this2.command({ action: 'select', target: event.target });
+      }
+    };
+
+    var focusHandler = function focusHandler(event) {
+      event.preventDefault();
+      event.stopPropagation();
+
+      if (event.target !== _this2.element_) {
+        _this2.selectSlide_(event.target);
+      }
+    };
+
+    if (this.element_) {
+      this.element_.setAttribute('role', LIGHTBOARD_ROLE);
+
+      if (this.element_.classList.contains(_constants.MDL_RIPPLE_EFFECT)) {
+        this.element_.classList.add(_constants.MDL_RIPPLE_EFFECT_IGNORE_EVENTS);
+      }
+
+      // Remove listeners, just in case ...
+      this.element_.removeEventListener('command', this.commandHandler_);
+      this.element_.removeEventListener('keydown', keydownHandler);
+      this.element_.removeEventListener('click', clickHandler);
+      this.element_.removeEventListener('focus', focusHandler);
+
+      this.element_.addEventListener('command', this.commandHandler_.bind(this), false);
+      this.element_.addEventListener('keydown', keydownHandler, true);
+      this.element_.addEventListener('click', clickHandler, true);
+      this.element_.addEventListener('focus', focusHandler, true);
+
+      this.upgradeSlides();
+
+      this.element_.classList.add(_constants.IS_UPGRADED);
+    }
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialExtLightboard,
+    classAsString: 'MaterialExtLightboard',
+    cssClass: 'mdlext-js-lightboard',
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/lightbox/lightbox.js b/node_modules/mdl-ext/es/lightbox/lightbox.js
new file mode 100644
index 0000000..bc23129
--- /dev/null
+++ b/node_modules/mdl-ext/es/lightbox/lightbox.js
@@ -0,0 +1,396 @@
+'use strict';
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _isInteger = require('babel-runtime/core-js/number/is-integer');
+
+var _isInteger2 = _interopRequireDefault(_isInteger);
+
+var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
+
+var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
+
+var _entries = require('babel-runtime/core-js/object/entries');
+
+var _entries2 = _interopRequireDefault(_entries);
+
+var _getIterator2 = require('babel-runtime/core-js/get-iterator');
+
+var _getIterator3 = _interopRequireDefault(_getIterator2);
+
+var _fullThrottle = require('../utils/full-throttle');
+
+var _fullThrottle2 = _interopRequireDefault(_fullThrottle);
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * Responsive Lightbox
+ */
+
+(function () {
+  'use strict';
+
+  var LIGHTBOX = 'mdlext-lightbox';
+  var LIGHTBOX_SLIDER = 'mdlext-lightbox__slider';
+  var LIGHTBOX_SLIDER_SLIDE = 'mdlext-lightbox__slider__slide';
+  var STICKY_FOOTER = 'mdlext-lightbox--sticky-footer';
+  var BUTTON = 'mdl-button';
+
+  /**
+   * https://github.com/google/material-design-lite/issues/4205
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtLightbox = function MaterialExtLightbox(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtLightbox'] = MaterialExtLightbox;
+
+  /**
+   * Handle keypress
+   * @param event
+   * @private
+   */
+  MaterialExtLightbox.prototype.keyDownHandler_ = function (event) {
+
+    if (event) {
+      if (event.keyCode === _constants.VK_ESC || event.keyCode === _constants.VK_SPACE || event.keyCode === _constants.VK_END || event.keyCode === _constants.VK_HOME || event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT || event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {
+
+        if (event.keyCode !== _constants.VK_ESC) {
+          event.preventDefault();
+          event.stopPropagation();
+        }
+
+        var action = 'first';
+        if (event.keyCode === _constants.VK_END) {
+          action = 'last';
+        } else if (event.keyCode === _constants.VK_ARROW_UP || event.keyCode === _constants.VK_ARROW_LEFT) {
+          action = 'prev';
+        } else if (event.keyCode === _constants.VK_ARROW_DOWN || event.keyCode === _constants.VK_ARROW_RIGHT) {
+          action = 'next';
+        } else if (event.keyCode === _constants.VK_SPACE) {
+          action = 'select';
+        } else if (event.keyCode === _constants.VK_ESC) {
+          action = 'cancel';
+        }
+
+        dispatchAction_(action, this);
+      }
+    }
+  };
+
+  /**
+   * Handle button clicks
+   * @param event
+   * @private
+   */
+  MaterialExtLightbox.prototype.buttonClickHandler_ = function (event) {
+
+    if (event) {
+      event.preventDefault();
+      event.stopPropagation();
+
+      dispatchAction_(this.getAttribute('data-action') || '', this);
+
+      var n = this.closest('.' + LIGHTBOX);
+      if (n) {
+        n.focus();
+      }
+    }
+  };
+
+  /**
+   * Dispatches an action custom event
+   * @param action
+   * @param source
+   * @param target
+   * @private
+   */
+  var dispatchAction_ = function dispatchAction_(action, source) {
+    var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source;
+
+
+    target.dispatchEvent(new CustomEvent('action', {
+      bubbles: true,
+      cancelable: true,
+      detail: {
+        action: action || '',
+        source: source
+      }
+    }));
+  };
+
+  /**
+   * Reposition dialog if component parent element is "DIALOG"
+   * @param lightboxElement
+   * @private
+   */
+  var repositionDialog_ = function repositionDialog_(lightboxElement) {
+    var footerHeight = function footerHeight(footer, isSticky) {
+      return isSticky && footer ? footer.offsetHeight : 0;
+    };
+
+    var reposition = function reposition(dialog, fh) {
+      if (window.getComputedStyle(dialog).position === 'absolute') {
+        var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
+        var topValue = scrollTop + (window.innerHeight - dialog.offsetHeight - fh) / 2;
+        dialog.style.top = Math.max(scrollTop, topValue) + 'px';
+      }
+    };
+
+    var p = lightboxElement.parentNode;
+    var dialog = p && p.nodeName === 'DIALOG' ? p : null;
+
+    if (dialog && dialog.hasAttribute('open')) {
+      lightboxElement.style.width = 'auto';
+      lightboxElement.style.maxWidth = '100%';
+      var img = lightboxElement.querySelector('img');
+      if (img) {
+        lightboxElement.style.maxWidth = img.naturalWidth !== undefined ? img.naturalWidth + 'px' : img.width + 'px' || '100%';
+      }
+
+      var fh = footerHeight(lightboxElement.querySelector('footer'), lightboxElement.classList.contains(STICKY_FOOTER));
+      var vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - fh;
+      if (dialog.offsetHeight > vh) {
+        var n = 0;
+        while (dialog.offsetHeight > vh && ++n < 4) {
+          lightboxElement.style.width = lightboxElement.offsetWidth * vh / lightboxElement.offsetHeight + 'px';
+        }
+      }
+      reposition(dialog, fh);
+    }
+  };
+
+  /**
+   * Handle image load
+   * @param event
+   * @private
+   */
+
+  MaterialExtLightbox.prototype.imgLoadHandler_ = function () /*event*/{
+    repositionDialog_(this);
+  };
+
+  /**
+   * Handle image drag
+   * @param event
+   * @private
+     */
+  MaterialExtLightbox.prototype.imgDragHandler_ = function (event) {
+
+    var setStyles = function setStyles(element, properties) {
+      //noinspection JSAnnotator
+      var _iteratorNormalCompletion = true;
+      var _didIteratorError = false;
+      var _iteratorError = undefined;
+
+      try {
+        for (var _iterator = (0, _getIterator3.default)((0, _entries2.default)(properties)), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+          var _step$value = (0, _slicedToArray3.default)(_step.value, 2),
+              key = _step$value[0],
+              value = _step$value[1];
+
+          element.style[key] = value;
+        }
+        // ... or:
+        //for (const key in properties) {
+        //  element.style[key] = properties[key];
+        //}
+      } catch (err) {
+        _didIteratorError = true;
+        _iteratorError = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion && _iterator.return) {
+            _iterator.return();
+          }
+        } finally {
+          if (_didIteratorError) {
+            throw _iteratorError;
+          }
+        }
+      }
+    };
+
+    event.preventDefault();
+    //event.stopPropagation();
+
+    var x = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+
+    var img = this;
+    img.style.opacity = '0.2';
+
+    var slider = document.createElement('div');
+    slider.classList.add(LIGHTBOX_SLIDER);
+    setStyles(slider, { 'width': img.offsetWidth + 'px', 'height': img.offsetHeight + 'px' });
+
+    var slide = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    slide.textContent = '>';
+    setStyles(slide, {
+      'width': img.offsetWidth + 'px',
+      'height': img.offsetHeight + 'px',
+      'line-height': img.offsetHeight + 'px',
+      'font-size': img.offsetHeight / 4 + 'px',
+      'text-align': 'right',
+      'background-image': 'url("' + (img.getAttribute('data-img-url-prev') || '') + '")'
+    });
+    slider.appendChild(slide);
+
+    slide = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    setStyles(slide, {
+      'width': img.offsetWidth + 'px',
+      'height': img.offsetHeight + 'px',
+      'background-image': 'url("' + img.src + '")'
+    });
+    slider.appendChild(slide);
+
+    slide = document.createElement('div');
+    slide.classList.add(LIGHTBOX_SLIDER_SLIDE);
+    slide.textContent = '<';
+    setStyles(slide, {
+      'width': img.offsetWidth + 'px',
+      'height': img.offsetHeight + 'px',
+      'line-height': img.offsetHeight + 'px',
+      'font-size': img.offsetHeight / 4 + 'px',
+      'text-align': 'left',
+      'background-image': 'url("' + (img.getAttribute('data-img-url-next') || '') + '")'
+    });
+    slider.appendChild(slide);
+
+    img.parentNode.appendChild(slider);
+
+    // drag handler
+    var drag = function drag(e) {
+      e.preventDefault();
+      var dx = (e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0)) - x; // TODO: maybe rewrite to improve performance
+
+      if (slider.offsetWidth - Math.abs(dx) > 19) {
+        slider.style.left = dx + 'px';
+      }
+    };
+
+    // end drag handler
+    var endDrag = function endDrag(e) {
+      e.preventDefault();
+      //e.stopPropagation();
+
+      window.removeEventListener('mousemove', drag);
+      window.removeEventListener('touchmove', drag);
+      window.removeEventListener('mouseup', endDrag);
+      window.removeEventListener('touchend', endDrag);
+
+      var dx = slider.offsetLeft;
+      img.parentNode.removeChild(slider);
+      img.style.opacity = '1.0';
+
+      if (Math.abs(dx) > 19) {
+        dispatchAction_(dx > 0 ? 'prev' : 'next', img);
+      }
+    };
+
+    window.addEventListener('mousemove', drag);
+    window.addEventListener('touchmove', drag);
+    window.addEventListener('mouseup', endDrag);
+    window.addEventListener('touchend', endDrag);
+  };
+
+  /**
+   * Initialize component
+   */
+  MaterialExtLightbox.prototype.init = function () {
+    var _this = this;
+
+    if (this.element_) {
+      // Do the init required for this component to work
+      this.element_.addEventListener('keydown', this.keyDownHandler_.bind(this.element_), true);
+
+      if (!(0, _isInteger2.default)(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', 1);
+      }
+
+      [].concat((0, _toConsumableArray3.default)(this.element_.querySelectorAll('.' + BUTTON))).forEach(function (button) {
+        return button.addEventListener('click', _this.buttonClickHandler_.bind(button), false);
+      });
+
+      var figcaption = this.element_.querySelector('figcaption');
+      if (figcaption) {
+        figcaption.addEventListener('click', this.buttonClickHandler_.bind(figcaption), false);
+      }
+
+      var footer = this.element_.querySelector('footer');
+      if (footer) {
+        footer.addEventListener('click', this.buttonClickHandler_.bind(footer), false);
+      }
+
+      var img = this.element_.querySelector('img');
+      if (img) {
+        img.addEventListener('load', this.imgLoadHandler_.bind(this.element_), false);
+        img.addEventListener('click', function (e) {
+          return e.preventDefault();
+        }, true);
+        img.addEventListener('mousedown', this.imgDragHandler_.bind(img), true);
+        img.addEventListener('touchstart', this.imgDragHandler_.bind(img), true);
+      }
+      window.addEventListener('resize', (0, _fullThrottle2.default)(function () {
+        return repositionDialog_(_this.element_);
+      }));
+      window.addEventListener('orientationchange', function () {
+        return repositionDialog_(_this.element_);
+      });
+
+      // Set upgraded flag
+      this.element_.classList.add(_constants.IS_UPGRADED);
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+  MaterialExtLightbox.prototype.mdlDowngrade_ = function() {
+  };
+  */
+
+  /**
+   * The component registers itself. It can assume componentHandler is available in the global scope.
+   */
+  /* jshint undef:false */
+  componentHandler.register({
+    constructor: MaterialExtLightbox,
+    classAsString: 'MaterialExtLightbox',
+    cssClass: 'mdlext-js-lightbox'
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/menu-button/menu-button.js b/node_modules/mdl-ext/es/menu-button/menu-button.js
new file mode 100644
index 0000000..9f7ed17
--- /dev/null
+++ b/node_modules/mdl-ext/es/menu-button/menu-button.js
@@ -0,0 +1,790 @@
+'use strict';
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
+
+var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
+
+var _stringUtils = require('../utils/string-utils');
+
+var _fullThrottle = require('../utils/full-throttle');
+
+var _fullThrottle2 = _interopRequireDefault(_fullThrottle);
+
+var _constants = require('../utils/constants');
+
+var _domUtils = require('../utils/dom-utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/**
+ * A menu button is a button that opens a menu. It is often styled as a
+ * typical push button with a downward pointing arrow or triangle to hint
+ * that activating the button will display a menu.
+ */
+var JS_MENU_BUTTON = 'mdlext-js-menu-button';
+var MENU_BUTTON_MENU = 'mdlext-menu';
+var MENU_BUTTON_MENU_ITEM = 'mdlext-menu__item';
+var MENU_BUTTON_MENU_ITEM_SEPARATOR = 'mdlext-menu__item-separator';
+//const MDL_LAYOUT_CONTENT = 'mdl-layout__content';
+
+/**
+ * Creates the menu controlled by the menu button
+ * @param element
+ * @return {{element: Element, selected: Element, open: (function(*=)), removeListeners: (function()), downgrade: (function())}}
+ */
+
+var menuFactory = function menuFactory(element) {
+
+  var ariaControls = null;
+  var parentNode = null;
+
+  var removeAllSelected = function removeAllSelected() {
+    [].concat((0, _toConsumableArray3.default)(element.querySelectorAll('.' + MENU_BUTTON_MENU_ITEM + '[aria-selected="true"]'))).forEach(function (selectedItem) {
+      return selectedItem.removeAttribute('aria-selected');
+    });
+  };
+
+  var setSelected = function setSelected(item) {
+    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+
+    if (force || item && !item.hasAttribute('aria-selected')) {
+      removeAllSelected();
+      if (item) {
+        item.setAttribute('aria-selected', 'true');
+      }
+    }
+  };
+
+  var getSelected = function getSelected() {
+    return element.querySelector('.' + MENU_BUTTON_MENU_ITEM + '[aria-selected="true"]');
+  };
+
+  var isDisabled = function isDisabled(item) {
+    return item && item.hasAttribute('disabled');
+  };
+
+  var isSeparator = function isSeparator(item) {
+    return item && item.classList.contains(MENU_BUTTON_MENU_ITEM_SEPARATOR);
+  };
+
+  var focus = function focus(item) {
+    if (item) {
+      item = item.closest('.' + MENU_BUTTON_MENU_ITEM);
+    }
+    if (item) {
+      item.focus();
+    }
+  };
+
+  var nextItem = function nextItem(current) {
+    var n = current.nextElementSibling;
+    if (!n) {
+      n = element.firstElementChild;
+    }
+    if (!isDisabled(n) && !isSeparator(n)) {
+      focus(n);
+    } else {
+      var i = element.children.length;
+      while (n && i-- > 0) {
+        if (isDisabled(n) || isSeparator(n)) {
+          n = n.nextElementSibling;
+          if (!n) {
+            n = element.firstElementChild;
+          }
+        } else {
+          focus(n);
+          break;
+        }
+      }
+    }
+  };
+
+  var previousItem = function previousItem(current) {
+    var p = current.previousElementSibling;
+    if (!p) {
+      p = element.lastElementChild;
+    }
+    if (!isDisabled(p) && !isSeparator(p)) {
+      focus(p);
+    } else {
+      var i = element.children.length;
+      while (p && i-- > 0) {
+        if (isDisabled(p) || isSeparator(p)) {
+          p = p.previousElementSibling;
+          if (!p) {
+            p = element.lastElementChild;
+          }
+        } else {
+          focus(p);
+          break;
+        }
+      }
+    }
+  };
+
+  var firstItem = function firstItem() {
+    var item = element.firstElementChild;
+    if (isDisabled(item) || isSeparator(item)) {
+      nextItem(item);
+    } else {
+      focus(item);
+    }
+  };
+
+  var lastItem = function lastItem() {
+    var item = element.lastElementChild;
+    if (isDisabled(item) || isSeparator(item)) {
+      previousItem(item);
+    } else {
+      focus(item);
+    }
+  };
+
+  var selectItem = function selectItem(item) {
+    if (item && !isDisabled(item) && !isSeparator(item)) {
+      setSelected(item);
+      close(true, item);
+    }
+  };
+
+  var keyDownHandler = function keyDownHandler(event) {
+
+    var item = event.target.closest('.' + MENU_BUTTON_MENU_ITEM);
+
+    switch (event.keyCode) {
+      case _constants.VK_ARROW_UP:
+      case _constants.VK_ARROW_LEFT:
+        if (item) {
+          previousItem(item);
+        } else {
+          firstItem();
+        }
+        break;
+
+      case _constants.VK_ARROW_DOWN:
+      case _constants.VK_ARROW_RIGHT:
+        if (item) {
+          nextItem(item);
+        } else {
+          lastItem();
+        }
+        break;
+
+      case _constants.VK_HOME:
+        firstItem();
+        break;
+
+      case _constants.VK_END:
+        lastItem();
+        break;
+
+      case _constants.VK_SPACE:
+      case _constants.VK_ENTER:
+        selectItem(item);
+        break;
+
+      case _constants.VK_ESC:
+        close(true);
+        break;
+
+      case _constants.VK_TAB:
+        // We do not have a "natural" tab order from menu, so the best we can do is to set focus back to the button
+        close(true);
+        break;
+
+      default:
+        return;
+    }
+    event.preventDefault();
+  };
+
+  var blurHandler = function blurHandler(event) {
+
+    // See: https://github.com/facebook/react/issues/2011
+    var t = event.relatedTarget || event.explicitOriginalTarget || // FF
+    document.activeElement; // IE11
+
+    //console.log('***** blur, target, relatedTarget', event.target, t);
+
+    try {
+      if (t) {
+        if (t.closest('.' + MENU_BUTTON_MENU) !== element && shouldClose(t)) {
+          close();
+        }
+      } else {
+        close();
+      }
+    } catch (err) {
+      // FF throws error: "TypeError: n.closest is not a function" if related target is a text node
+      close();
+    }
+  };
+
+  var clickHandler = function clickHandler(event) {
+    //console.log('***** click, target', event.target);
+
+    event.preventDefault();
+    var t = event.target;
+    if (t && t.closest('.' + MENU_BUTTON_MENU) === element) {
+      var item = t.closest('.' + MENU_BUTTON_MENU_ITEM);
+      if (item) {
+        selectItem(item);
+      }
+    } else {
+      if (shouldClose(t)) {
+        close();
+      }
+    }
+  };
+
+  var touchStartHandler = function touchStartHandler(event) {
+    //console.log('***** touchStart, target', event.target);
+
+    var t = event.target;
+    if (!(t && t.closest('.' + MENU_BUTTON_MENU) === element)) {
+      if (event.type === 'touchstart') {
+        event.preventDefault();
+      }
+      close();
+    }
+  };
+
+  var addListeners = function addListeners() {
+    element.addEventListener('keydown', keyDownHandler, false);
+    element.addEventListener('blur', blurHandler, true);
+    element.addEventListener('click', clickHandler, true);
+    document.documentElement.addEventListener('touchstart', touchStartHandler, true);
+  };
+
+  var _removeListeners = function _removeListeners() {
+    element.removeEventListener('keydown', keyDownHandler, false);
+    element.removeEventListener('blur', blurHandler, true);
+    element.removeEventListener('click', clickHandler, true);
+    document.documentElement.removeEventListener('touchstart', touchStartHandler, true);
+  };
+
+  var _open = function _open(controlElement) {
+    var position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'first';
+
+
+    ariaControls = controlElement.closest('.' + JS_MENU_BUTTON);
+
+    element.style['min-width'] = Math.max(124, controlElement.getBoundingClientRect().width) + 'px';
+    element.removeAttribute('hidden');
+    (0, _domUtils.tether)(controlElement, element);
+
+    var item = void 0;
+    switch (position.toLowerCase()) {
+      case 'first':
+        firstItem();
+        break;
+
+      case 'last':
+        lastItem();
+        break;
+
+      case 'selected':
+        item = getSelected();
+        if (item && !item.hasAttribute('disabled')) {
+          focus(item);
+        } else {
+          firstItem();
+        }
+        break;
+    }
+
+    addListeners();
+  };
+
+  var shouldClose = function shouldClose(target) {
+    //console.log('***** shouldClose');
+
+    var result = false;
+    var btn = target && target.closest('.' + JS_MENU_BUTTON) || null;
+    if (!btn) {
+      result = true;
+    } else if (btn.getAttribute('aria-controls') === element.id) {
+      if (btn !== ariaControls) {
+        result = true;
+      }
+    } else {
+      result = true;
+    }
+    return result;
+  };
+
+  var close = function close() {
+    var forceFocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+    var item = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+
+    _removeListeners();
+
+    element.dispatchEvent(new CustomEvent('_closemenu', {
+      bubbles: true,
+      cancelable: true,
+      detail: { forceFocus: forceFocus, item: item }
+    }));
+  };
+
+  var addWaiAria = function addWaiAria() {
+    if (!element.hasAttribute('id')) {
+      // Generate a random id
+      element.id = 'menu-button-' + (0, _stringUtils.randomString)();
+    }
+    element.setAttribute('tabindex', '-1');
+    element.setAttribute('role', 'menu');
+    element.setAttribute('hidden', '');
+
+    [].concat((0, _toConsumableArray3.default)(element.querySelectorAll('.' + MENU_BUTTON_MENU_ITEM))).forEach(function (menuitem) {
+      menuitem.setAttribute('tabindex', '-1');
+      menuitem.setAttribute('role', 'menuitem');
+    });
+
+    [].concat((0, _toConsumableArray3.default)(element.querySelectorAll('.' + MENU_BUTTON_MENU_ITEM_SEPARATOR))).forEach(function (menuitem) {
+      menuitem.setAttribute('role', 'separator');
+    });
+  };
+
+  var init = function init() {
+    addWaiAria();
+    parentNode = element.parentNode;
+    element.classList.add('is-upgraded');
+  };
+
+  var _downgrade = function _downgrade() {
+    _removeListeners();
+    if (element.parentNode !== parentNode) {
+      parentNode.appendChild(element);
+    }
+    element.classList.remove('is-upgraded');
+  };
+
+  init();
+
+  return {
+    /**
+     * Get the menu element
+     * @returns {Element} the menu element
+     */
+    get element() {
+      return element;
+    },
+
+    /**
+     * Set selected menu item
+     * @param item
+     */
+    set selected(item) {
+      setSelected(item, true);
+    },
+
+    /**
+     * Open menu
+     * @param {Element} controlElement the element where the menu should be aligned to
+     * @param {String} position menuElement item to receive focus after menu element is opened
+     */
+    open: function open(controlElement) {
+      var position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'first';
+      return _open(controlElement, position);
+    },
+
+    /**
+     * Remove event listeners.
+     */
+    removeListeners: function removeListeners() {
+      return _removeListeners();
+    },
+
+    /**
+     * Downgrade menu
+     */
+    downgrade: function downgrade() {
+      return _downgrade();
+    }
+  };
+};
+
+/**
+ * The menubutton component
+ */
+
+var MenuButton = function () {
+  function MenuButton(element) {
+    var _this = this;
+
+    (0, _classCallCheck3.default)(this, MenuButton);
+
+    this.keyDownHandler = function (event) {
+      if (!_this.isDisabled()) {
+        switch (event.keyCode) {
+          case _constants.VK_ARROW_UP:
+            _this.openMenu('last');
+            break;
+
+          case _constants.VK_ARROW_DOWN:
+            _this.openMenu();
+            break;
+
+          case _constants.VK_SPACE:
+          case _constants.VK_ENTER:
+            _this.openMenu('selected');
+            break;
+
+          case _constants.VK_ESC:
+            _this.closeMenu();
+            break;
+
+          case _constants.VK_TAB:
+            _this.closeMenu();
+            return;
+
+          default:
+            return;
+        }
+      }
+      //event.stopPropagation();
+      event.preventDefault();
+    };
+
+    this.clickHandler = function () {
+      if (!_this.isDisabled()) {
+        if (_this.element.getAttribute('aria-expanded').toLowerCase() === 'true') {
+          _this.closeMenu(true);
+        } else {
+          _this.openMenu('selected');
+        }
+      }
+    };
+
+    this.recalcMenuPosition = (0, _fullThrottle2.default)(function () {
+      var c = _this.focusElement.getBoundingClientRect();
+      var dx = _this.focusElementLastScrollPosition.left - c.left;
+      var dy = _this.focusElementLastScrollPosition.top - c.top;
+      var left = (parseFloat(_this.menu.element.style.left) || 0) - dx;
+      var top = (parseFloat(_this.menu.element.style.top) || 0) - dy;
+
+      _this.menu.element.style.left = left + 'px';
+      _this.menu.element.style.top = top + 'px';
+      _this.focusElementLastScrollPosition = c;
+    });
+
+    this.positionChangeHandler = function () {
+      _this.recalcMenuPosition(_this);
+    };
+
+    this.closeMenuHandler = function (event) {
+      if (event && event.detail) {
+        if (event.detail.item && event.detail.item !== _this.selectedItem) {
+          _this.selectedItem = event.detail.item;
+          _this.dispatchMenuSelect();
+        }
+        _this.closeMenu(event.detail.forceFocus);
+      }
+    };
+
+    this.element = element;
+    this.focusElement = undefined;
+    this.focusElementLastScrollPosition = undefined;
+    this.scrollElements = [];
+    this.menu = undefined;
+    this.selectedItem = null;
+    this.init();
+  }
+
+  /**
+   * Re-position menu if content is scrolled, window is resized or orientation change
+   * @see https://javascriptweblog.wordpress.com/2015/11/02/of-classes-and-arrow-functions-a-cautionary-tale/
+   */
+
+
+  (0, _createClass3.default)(MenuButton, [{
+    key: 'dispatchMenuSelect',
+    value: function dispatchMenuSelect() {
+      this.element.dispatchEvent(new CustomEvent('menuselect', {
+        bubbles: true,
+        cancelable: true,
+        detail: { source: this.selectedItem }
+      }));
+    }
+  }, {
+    key: 'isDisabled',
+    value: function isDisabled() {
+      return this.element.hasAttribute('disabled');
+    }
+  }, {
+    key: 'removeListeners',
+    value: function removeListeners() {
+      this.element.removeEventListener('keydown', this.keyDownHandler);
+      this.element.removeEventListener('click', this.clickHandler);
+    }
+  }, {
+    key: 'openMenu',
+    value: function openMenu() {
+      var _this2 = this;
+
+      var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'first';
+
+
+      if (!this.isDisabled() && this.menu) {
+
+        // Close the menu if button position change
+        this.scrollElements = (0, _domUtils.getScrollParents)(this.element);
+        this.scrollElements.forEach(function (el) {
+          return el.addEventListener('scroll', _this2.positionChangeHandler);
+        });
+
+        window.addEventListener('resize', this.positionChangeHandler);
+        window.addEventListener('orientationchange', this.positionChangeHandler);
+        this.menu.element.addEventListener('_closemenu', this.closeMenuHandler);
+
+        this.menu.selected = this.selectedItem;
+        this.menu.open(this.focusElement, position);
+        this.element.setAttribute('aria-expanded', 'true');
+
+        this.focusElementLastScrollPosition = this.focusElement.getBoundingClientRect();
+      }
+    }
+  }, {
+    key: 'closeMenu',
+    value: function closeMenu() {
+      var _this3 = this;
+
+      var forceFocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+
+      if (this.menu) {
+        this.menu.removeListeners();
+        this.scrollElements.forEach(function (el) {
+          return el.removeEventListener('scroll', _this3.positionChangeHandler);
+        });
+        window.removeEventListener('resize', this.positionChangeHandler);
+        window.removeEventListener('orientationchange', this.positionChangeHandler);
+        this.menu.element.removeEventListener('_closemenu', this.closeMenuHandler);
+
+        if (forceFocus) {
+          this.focus();
+        }
+        this.element.setAttribute('aria-expanded', 'false');
+        this.menu.element.setAttribute('hidden', '');
+      }
+    }
+  }, {
+    key: 'focus',
+    value: function focus() {
+      if (!this.isDisabled()) {
+        this.focusElement.focus();
+      }
+    }
+  }, {
+    key: 'init',
+    value: function init() {
+      var _this4 = this;
+
+      var addListeners = function addListeners() {
+        _this4.element.addEventListener('keydown', _this4.keyDownHandler);
+        _this4.element.addEventListener('click', _this4.clickHandler);
+      };
+
+      var addWaiAria = function addWaiAria() {
+        _this4.element.setAttribute('role', 'button');
+        _this4.element.setAttribute('aria-expanded', 'false');
+        _this4.element.setAttribute('aria-haspopup', 'true');
+      };
+
+      var addFocusElement = function addFocusElement() {
+        _this4.focusElement = _this4.element.querySelector('input[type="text"]');
+        if (!_this4.focusElement) {
+          _this4.focusElement = _this4.element;
+
+          if (!(_this4.focusElement.tagName.toLowerCase() === 'button' || _this4.focusElement.tagName.toLowerCase() === 'input')) {
+            if (!_this4.focusElement.hasAttribute('tabindex')) {
+              _this4.focusElement.setAttribute('tabindex', '0');
+            }
+          }
+        }
+      };
+
+      var moveElementToDocumentBody = function moveElementToDocumentBody(element) {
+        // To position an element on top of all other z-indexed elements, the element should be moved to document.body
+        //       See: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
+
+        if (element.parentNode !== document.body) {
+          return document.body.appendChild(element);
+        }
+        return element;
+      };
+
+      var findMenuElement = function findMenuElement() {
+        var menuElement = void 0;
+        var menuElementId = _this4.element.getAttribute('aria-controls');
+        if (menuElementId !== null) {
+          menuElement = document.querySelector('#' + menuElementId);
+        } else {
+          menuElement = _this4.element.parentNode.querySelector('.' + MENU_BUTTON_MENU);
+        }
+        return menuElement;
+      };
+
+      var addMenu = function addMenu() {
+        var menuElement = findMenuElement();
+        if (menuElement) {
+          if (menuElement.componentInstance) {
+            _this4.menu = menuElement.componentInstance;
+          } else {
+            _this4.menu = menuFactory(menuElement);
+            menuElement.componentInstance = _this4.menu;
+            moveElementToDocumentBody(menuElement);
+          }
+          _this4.element.setAttribute('aria-controls', _this4.menu.element.id);
+        }
+      };
+
+      addFocusElement();
+      addWaiAria();
+      addMenu();
+      this.removeListeners();
+      addListeners();
+    }
+  }, {
+    key: 'downgrade',
+    value: function downgrade() {
+      var _this5 = this;
+
+      if (this.menu) {
+        // Do not downgrade menu if there are other buttons sharing this menu
+        var related = [].concat((0, _toConsumableArray3.default)(document.querySelectorAll('.' + JS_MENU_BUTTON + '[aria-controls="' + this.element.getAttribute('aria-controls') + '"]')));
+        if (related.filter(function (c) {
+          return c !== _this5.element && c.getAttribute('data-upgraded').indexOf('MaterialExtMenuButton') >= 0;
+        }).length === 0) {
+          this.menu.downgrade();
+        }
+      }
+      this.removeListeners();
+    }
+  }]);
+  return MenuButton;
+}();
+
+(function () {
+  'use strict';
+
+  /**
+   * https://github.com/google/material-design-lite/issues/4205
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+
+  var MaterialExtMenuButton = function MaterialExtMenuButton(element) {
+    this.element_ = element;
+    this.menuButton_ = null;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialExtMenuButton'] = MaterialExtMenuButton;
+
+  // Public methods.
+
+  /**
+   * Get the menu element controlled by this button, null if no menu is controlled by this button
+   * @public
+   */
+  MaterialExtMenuButton.prototype.getMenuElement = function () {
+    return this.menuButton_.menu ? this.menuButton_.menu.element : null;
+  };
+  MaterialExtMenuButton.prototype['getMenuElement'] = MaterialExtMenuButton.prototype.getMenuElement;
+
+  /**
+   * Open menu
+   * @public
+   * @param {String} position one of "first", "last" or "selected"
+   */
+  MaterialExtMenuButton.prototype.openMenu = function (position) {
+    this.menuButton_.openMenu(position);
+  };
+  MaterialExtMenuButton.prototype['openMenu'] = MaterialExtMenuButton.prototype.openMenu;
+
+  /**
+   * Close menu
+   * @public
+   */
+  MaterialExtMenuButton.prototype.closeMenu = function () {
+    this.menuButton_.closeMenu(true);
+  };
+  MaterialExtMenuButton.prototype['closeMenu'] = MaterialExtMenuButton.prototype.closeMenu;
+
+  /**
+   * Get selected menu item
+   * @public
+   * @returns {Element} The selected menu item or null if no item selected
+   */
+  MaterialExtMenuButton.prototype.getSelectedMenuItem = function () {
+    return this.menuButton_.selectedItem;
+  };
+  MaterialExtMenuButton.prototype['getSelectedMenuItem'] = MaterialExtMenuButton.prototype.getSelectedMenuItem;
+
+  /**
+   * Set (default) selected menu item
+   * @param {Element} item
+   */
+  MaterialExtMenuButton.prototype.setSelectedMenuItem = function (item) {
+    this.menuButton_.selectedItem = item;
+  };
+  MaterialExtMenuButton.prototype['setSelectedMenuItem'] = MaterialExtMenuButton.prototype.setSelectedMenuItem;
+
+  /**
+   * Initialize component
+   */
+  MaterialExtMenuButton.prototype.init = function () {
+    if (this.element_) {
+      this.menuButton_ = new MenuButton(this.element_);
+      this.element_.addEventListener('mdl-componentdowngraded', this.mdlDowngrade_.bind(this));
+      this.element_.classList.add(_constants.IS_UPGRADED);
+    }
+  };
+
+  /**
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   */
+  MaterialExtMenuButton.prototype.mdlDowngrade_ = function () {
+    this.menuButton_.downgrade();
+  };
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtMenuButton,
+    classAsString: 'MaterialExtMenuButton',
+    cssClass: JS_MENU_BUTTON,
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/selectfield/selectfield.js b/node_modules/mdl-ext/es/selectfield/selectfield.js
new file mode 100644
index 0000000..5274789
--- /dev/null
+++ b/node_modules/mdl-ext/es/selectfield/selectfield.js
@@ -0,0 +1,271 @@
+'use strict';
+
+var _stringUtils = require('../utils/string-utils');
+
+var _constants = require('../utils/constants');
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This code is built with Google Material Design Lite,
+ * which is Licensed under the Apache License, Version 2.0
+ */
+
+/*
+ * Copied/Modified from https://github.com/google/material-design-lite/tree/master/src/textfield
+ */
+
+(function () {
+  'use strict';
+
+  var LABEL = 'mdlext-selectfield__label';
+  var INPUT = 'mdlext-selectfield__select';
+
+  /**
+   * Class constructor for Selectfield MDLEXT component.
+   * Implements MDL component design pattern defined at:
+   * https://github.com/jasonmayes/mdl-component-design-pattern
+   *
+   * @constructor
+   * @param {HTMLElement} element The element that will be upgraded.
+   */
+  var MaterialExtSelectfield = function MaterialExtSelectfield(element) {
+    this.element_ = element;
+    this.init(); // Initialize instance.
+  };
+
+  window['MaterialExtSelectfield'] = MaterialExtSelectfield;
+
+  /**
+   * Handle focus.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  /*eslint no-unused-vars: 0*/
+  MaterialExtSelectfield.prototype.onFocus_ = function () /*event*/{
+    this.element_.classList.add(_constants.IS_FOCUSED);
+  };
+
+  /**
+   * Handle lost focus.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  /*eslint no-unused-vars: 0*/
+  MaterialExtSelectfield.prototype.onBlur_ = function () /*event*/{
+    this.element_.classList.remove(_constants.IS_FOCUSED);
+  };
+
+  /**
+   * Handle reset event from out side.
+   *
+   * @param {Event} event The event that fired.
+   * @private
+   */
+  MaterialExtSelectfield.prototype.onReset_ = function () /*event*/{
+    this.updateClasses_();
+  };
+
+  /**
+   * Handle class updates.
+   *
+   * @private
+   */
+  MaterialExtSelectfield.prototype.updateClasses_ = function () {
+    this.checkDisabled();
+    this.checkValidity();
+    this.checkDirty();
+    this.checkFocus();
+  };
+
+  // Public methods.
+
+  /**
+   * Check the disabled state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkDisabled = function () {
+    if (this.select_.disabled) {
+      this.element_.classList.add(_constants.IS_DISABLED);
+    } else {
+      this.element_.classList.remove(_constants.IS_DISABLED);
+    }
+  };
+  MaterialExtSelectfield.prototype['checkDisabled'] = MaterialExtSelectfield.prototype.checkDisabled;
+
+  /**
+   * Check the focus state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkFocus = function () {
+    // Note: element.querySelector(':focus') always return null in JsDom, even if select element has focus
+    /*eslint no-extra-boolean-cast: 0*/
+    if (Boolean(this.element_.querySelector(':focus'))) {
+      this.element_.classList.add(_constants.IS_FOCUSED);
+    } else {
+      this.element_.classList.remove(_constants.IS_FOCUSED);
+    }
+  };
+
+  MaterialExtSelectfield.prototype['checkFocus'] = MaterialExtSelectfield.prototype.checkFocus;
+
+  /**
+   * Check the validity state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkValidity = function () {
+
+    /* Don't think it makes any sense to check validity.
+       Tests I've done, so far, indicates that setting an illegal value via JS returns selectedIndex=0
+     if (this.select_.validity) {
+      if (this.select_.validity.valid) {
+        this.element_.classList.remove(this.CssClasses_.IS_INVALID);
+      } else {
+        this.element_.classList.add(this.CssClasses_.IS_INVALID);
+      }
+    }
+    */
+  };
+
+  MaterialExtSelectfield.prototype['checkValidity'] = MaterialExtSelectfield.prototype.checkValidity;
+
+  /**
+   * Check the dirty state and update field accordingly.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.checkDirty = function () {
+    if (this.select_.value && this.select_.value.length > 0) {
+      this.element_.classList.add(_constants.IS_DIRTY);
+    } else {
+      this.element_.classList.remove(_constants.IS_DIRTY);
+    }
+  };
+
+  MaterialExtSelectfield.prototype['checkDirty'] = MaterialExtSelectfield.prototype.checkDirty;
+
+  /**
+   * Disable select field.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.disable = function () {
+    this.select_.disabled = true;
+    this.updateClasses_();
+  };
+
+  MaterialExtSelectfield.prototype['disable'] = MaterialExtSelectfield.prototype.disable;
+
+  /**
+   * Enable select field.
+   *
+   * @public
+   */
+  MaterialExtSelectfield.prototype.enable = function () {
+    this.select_.disabled = false;
+    this.updateClasses_();
+  };
+
+  MaterialExtSelectfield.prototype['enable'] = MaterialExtSelectfield.prototype.enable;
+
+  /**
+   * Update select field value.
+   *
+   * @param {string} value The value to which to set the control (optional).
+   * @public
+   */
+  MaterialExtSelectfield.prototype.change = function (value) {
+    this.select_.value = value || '';
+    this.updateClasses_();
+  };
+  MaterialExtSelectfield.prototype['change'] = MaterialExtSelectfield.prototype.change;
+
+  /**
+   * Initialize element.
+   */
+  MaterialExtSelectfield.prototype.init = function () {
+    if (this.element_) {
+      this.label_ = this.element_.querySelector('.' + LABEL);
+      this.select_ = this.element_.querySelector('.' + INPUT);
+
+      if (this.select_) {
+        // Remove listeners, just in case ...
+        this.select_.removeEventListener('change', this.updateClasses_);
+        this.select_.removeEventListener('focus', this.onFocus_);
+        this.select_.removeEventListener('blur', this.onBlur_);
+        this.select_.removeEventListener('reset', this.onReset_);
+
+        this.select_.addEventListener('change', this.updateClasses_.bind(this));
+        this.select_.addEventListener('focus', this.onFocus_.bind(this));
+        this.select_.addEventListener('blur', this.onBlur_.bind(this));
+        this.select_.addEventListener('reset', this.onReset_.bind(this));
+
+        if (this.label_) {
+          var id = void 0;
+          if (!this.select_.hasAttribute('id')) {
+            id = 'select-' + (0, _stringUtils.randomString)();
+            this.select_.id = id;
+          } else {
+            id = this.select_.id;
+          }
+
+          if (!this.label_.hasAttribute('for')) {
+            this.label_.setAttribute('for', id);
+          }
+        }
+
+        var invalid = this.element_.classList.contains(_constants.IS_INVALID);
+        this.updateClasses_();
+        this.element_.classList.add(_constants.IS_UPGRADED);
+
+        if (invalid) {
+          this.element_.classList.add(_constants.IS_INVALID);
+        }
+        if (this.select_.hasAttribute('autofocus')) {
+          this.element_.focus();
+          this.checkFocus();
+        }
+      }
+    }
+  };
+
+  /**
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to downgrade
+   *
+  MaterialExtSelectfield.prototype.mdlDowngrade_ = function() {
+    'use strict';
+    console.log('***** MaterialExtSelectfield.mdlDowngrade ');
+  };
+  */
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /*eslint no-undef: 0*/
+  componentHandler.register({
+    constructor: MaterialExtSelectfield,
+    classAsString: 'MaterialExtSelectfield',
+    cssClass: 'mdlext-js-selectfield',
+    widget: true
+  });
+})();
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/sticky-header/sticky-header.js b/node_modules/mdl-ext/es/sticky-header/sticky-header.js
new file mode 100644
index 0000000..08593aa
--- /dev/null
+++ b/node_modules/mdl-ext/es/sticky-header/sticky-header.js
@@ -0,0 +1,252 @@
+'use strict';
+
+var _fullThrottle = require('../utils/full-throttle');
+
+var _fullThrottle2 = _interopRequireDefault(_fullThrottle);
+
+var _jsonUtils = require('../utils/json-utils');
+
+var _constants = require('../utils/constants');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+(function () {
+  'use strict';
+
+  var MDL_LAYOUT_CONTENT = 'mdl-layout__content';
+  var IS_SCROLL_CLASS = 'mdlext-is-scroll';
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  var MaterialExtStickyHeader = function MaterialExtStickyHeader(element) {
+    // Stores the element.
+    this.header_ = element;
+
+    // Heder listens to scroll events from content
+    this.content_ = null;
+    this.lastScrollTop_ = 0;
+
+    // Default config
+    this.config_ = {
+      visibleAtScrollEnd: false
+    };
+
+    this.mutationObserver_ = null;
+
+    this.drawing_ = false;
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtStickyHeader'] = MaterialExtStickyHeader;
+
+  /**
+   * Update header width
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.recalcWidth_ = function () {
+    this.header_.style.width = this.content_.clientWidth + 'px';
+  };
+
+  var throttleResize = (0, _fullThrottle2.default)(function (self) {
+    return self.recalcWidth_();
+  });
+
+  /**
+   * Adjust header width when window resizes or oreientation changes
+   * @param event
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.resizeHandler_ = function () /* event */{
+    throttleResize(this);
+  };
+
+  /**
+   * Update header position
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.reposition_ = function () {
+
+    var currentContentScrollTop = this.content_.scrollTop;
+    var scrollDiff = this.lastScrollTop_ - currentContentScrollTop;
+
+    if (currentContentScrollTop <= 0) {
+      // Scrolled to the top. Header sticks to the top
+      this.header_.style.top = '0';
+      this.header_.classList.remove(IS_SCROLL_CLASS);
+    } else if (scrollDiff > 0) {
+
+      if (scrollDiff >= this.header_.offsetHeight) {
+
+        // Scrolled up. Header slides in
+        var headerTop = parseInt(window.getComputedStyle(this.header_).getPropertyValue('top')) || 0;
+        if (headerTop != 0) {
+          this.header_.style.top = '0';
+          this.header_.classList.add(IS_SCROLL_CLASS);
+        }
+        this.lastScrollTop_ = currentContentScrollTop;
+      }
+      return;
+    } else if (scrollDiff < 0) {
+      // Scrolled down
+      this.header_.classList.add(IS_SCROLL_CLASS);
+      var _headerTop = parseInt(window.getComputedStyle(this.header_).getPropertyValue('top')) || 0;
+
+      if (this.content_.scrollHeight - this.content_.scrollTop <= this.content_.offsetHeight) {
+        // Bottom of content
+        if (_headerTop != 0) {
+          this.header_.style.top = this.config_.visibleAtScrollEnd ? '0' : '-' + this.header_.offsetHeight + 'px';
+        }
+      } else {
+        _headerTop += scrollDiff;
+        var offsetHeight = this.header_.offsetHeight;
+        this.header_.style.top = (Math.abs(_headerTop) > offsetHeight ? -offsetHeight : _headerTop) + 'px';
+      }
+    }
+
+    this.lastScrollTop_ = currentContentScrollTop;
+  };
+
+  var throttleScroll = (0, _fullThrottle2.default)(function (self) {
+    return self.reposition_();
+  });
+
+  /**
+   * Scroll header when content scrolls
+   * @param event
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.scrollHandler_ = function () /* event */{
+    throttleScroll(this);
+  };
+
+  /**
+   * Init header position
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.updatePosition_ = function () /* event */{
+    this.recalcWidth_();
+    this.reposition_();
+  };
+
+  /**
+   * Add mutation observer
+   * @private
+   */
+  MaterialExtStickyHeader.prototype.addMutationObserver_ = function () {
+    var _this = this;
+
+    // jsdom does not support MutationObserver - so this is not testable
+    /* istanbul ignore next */
+    this.mutationObserver_ = new MutationObserver(function () /*mutations*/{
+      // Adjust header width if content changes (e.g. in a SPA)
+      _this.updatePosition_();
+    });
+
+    this.mutationObserver_.observe(this.content_, {
+      attributes: false,
+      childList: true,
+      characterData: false,
+      subtree: true
+    });
+  };
+
+  /**
+  * Removes event listeners
+  * @private
+  */
+  MaterialExtStickyHeader.prototype.removeListeners_ = function () {
+
+    window.removeEventListener('resize', this.resizeHandler_);
+    window.removeEventListener('orientationchange', this.resizeHandler_);
+
+    if (this.content_) {
+      this.content_.removeEventListener('scroll', this.scrollHandler_);
+    }
+
+    if (this.mutationObserver_) {
+      this.mutationObserver_.disconnect();
+      this.mutationObserver_ = null;
+    }
+  };
+
+  /**
+   * Initialize component
+   */
+  MaterialExtStickyHeader.prototype.init = function () {
+
+    if (this.header_) {
+
+      this.removeListeners_();
+
+      if (this.header_.hasAttribute('data-config')) {
+        this.config_ = (0, _jsonUtils.jsonStringToObject)(this.header_.getAttribute('data-config'));
+      }
+
+      this.content_ = this.header_.parentNode.querySelector('.' + MDL_LAYOUT_CONTENT) || null;
+
+      if (this.content_) {
+        this.content_.style.paddingTop = this.header_.offsetHeight + 'px'; // Make room for sticky header
+        this.lastScrollTop_ = this.content_.scrollTop;
+
+        this.content_.addEventListener('scroll', this.scrollHandler_.bind(this));
+        window.addEventListener('resize', this.resizeHandler_.bind(this));
+        window.addEventListener('orientationchange', this.resizeHandler_.bind(this));
+
+        this.addMutationObserver_();
+        this.updatePosition_();
+
+        // Set upgraded flag
+        this.header_.classList.add(_constants.IS_UPGRADED);
+      }
+    }
+  };
+
+  /*
+   * Downgrade component
+   * E.g remove listeners and clean up resources
+   *
+   * Nothing to clean
+   *
+   MaterialExtStickyHeader.prototype.mdlDowngrade_ = function() {
+     'use strict';
+     console.log('***** MaterialExtStickyHeader.prototype.mdlDowngrade_');
+   };
+   */
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  /* eslint no-undef: 0 */
+  componentHandler.register({
+    constructor: MaterialExtStickyHeader,
+    classAsString: 'MaterialExtStickyHeader',
+    cssClass: 'mdlext-js-sticky-header'
+  });
+})(); /**
+       * @license
+       * Copyright 2016 Leif Olsen. All Rights Reserved.
+       *
+       * Licensed under the Apache License, Version 2.0 (the "License");
+       * you may not use this file except in compliance with the License.
+       * You may obtain a copy of the License at
+       *
+       *      http://www.apache.org/licenses/LICENSE-2.0
+       *
+       * Unless required by applicable law or agreed to in writing, software
+       * distributed under the License is distributed on an "AS IS" BASIS,
+       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       * See the License for the specific language governing permissions and
+       * limitations under the License.
+       *
+       * This code is built with Google Material Design Lite,
+       * which is Licensed under the Apache License, Version 2.0
+       */
+
+/**
+ * A sticky header makes site navigation easily accessible anywhere on the page and saves content space at the same.
+ * The header should auto-hide, i.e. hiding the header automatically when a user starts scrolling down the page and
+ * bringing the header back when a user might need it: they reach the bottom of the page or start scrolling up.
+ */
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/constants.js b/node_modules/mdl-ext/es/utils/constants.js
new file mode 100644
index 0000000..2d063e2
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/constants.js
@@ -0,0 +1,63 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var VK_TAB = 9;
+var VK_ENTER = 13;
+var VK_ESC = 27;
+var VK_SPACE = 32;
+var VK_PAGE_UP = 33;
+var VK_PAGE_DOWN = 34;
+var VK_END = 35;
+var VK_HOME = 36;
+var VK_ARROW_LEFT = 37;
+var VK_ARROW_UP = 38;
+var VK_ARROW_RIGHT = 39;
+var VK_ARROW_DOWN = 40;
+
+var ARIA_EXPANDED = 'aria-expanded';
+var ARIA_HIDDEN = 'aria-hidden';
+var ARIA_MULTISELECTABLE = 'aria-multiselectable';
+var ARIA_SELECTED = 'aria-selected';
+
+var IS_DIRTY = 'is-dirty';
+var IS_DISABLED = 'is-disabled';
+var IS_EXPANDED = 'is-expanded';
+var IS_FOCUSED = 'is-focused';
+var IS_INVALID = 'is-invalid';
+var IS_UPGRADED = 'is-upgraded';
+var DATA_UPGRADED = 'data-upgraded';
+
+var MDL_RIPPLE = 'mdl-ripple';
+var MDL_RIPPLE_COMPONENT = 'MaterialRipple';
+var MDL_RIPPLE_EFFECT = 'mdl-js-ripple-effect';
+var MDL_RIPPLE_EFFECT_IGNORE_EVENTS = 'mdl-js-ripple-effect--ignore-events';
+
+exports.VK_TAB = VK_TAB;
+exports.VK_ENTER = VK_ENTER;
+exports.VK_ESC = VK_ESC;
+exports.VK_SPACE = VK_SPACE;
+exports.VK_PAGE_UP = VK_PAGE_UP;
+exports.VK_PAGE_DOWN = VK_PAGE_DOWN;
+exports.VK_END = VK_END;
+exports.VK_HOME = VK_HOME;
+exports.VK_ARROW_LEFT = VK_ARROW_LEFT;
+exports.VK_ARROW_UP = VK_ARROW_UP;
+exports.VK_ARROW_RIGHT = VK_ARROW_RIGHT;
+exports.VK_ARROW_DOWN = VK_ARROW_DOWN;
+exports.ARIA_EXPANDED = ARIA_EXPANDED;
+exports.ARIA_HIDDEN = ARIA_HIDDEN;
+exports.ARIA_MULTISELECTABLE = ARIA_MULTISELECTABLE;
+exports.ARIA_SELECTED = ARIA_SELECTED;
+exports.IS_DIRTY = IS_DIRTY;
+exports.IS_DISABLED = IS_DISABLED;
+exports.IS_EXPANDED = IS_EXPANDED;
+exports.IS_FOCUSED = IS_FOCUSED;
+exports.IS_INVALID = IS_INVALID;
+exports.IS_UPGRADED = IS_UPGRADED;
+exports.DATA_UPGRADED = DATA_UPGRADED;
+exports.MDL_RIPPLE = MDL_RIPPLE;
+exports.MDL_RIPPLE_COMPONENT = MDL_RIPPLE_COMPONENT;
+exports.MDL_RIPPLE_EFFECT = MDL_RIPPLE_EFFECT;
+exports.MDL_RIPPLE_EFFECT_IGNORE_EVENTS = MDL_RIPPLE_EFFECT_IGNORE_EVENTS;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/debounce-function.js b/node_modules/mdl-ext/es/utils/debounce-function.js
new file mode 100644
index 0000000..27f977c
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/debounce-function.js
@@ -0,0 +1,89 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Debouncing enforces that a function not be called again until a certain
+ * amount of time has passed without it being called.
+ *
+ * @see https://css-tricks.com/the-difference-between-throttling-and-debouncing/
+ * @see https://github.com/webmodules/raf-debounce
+ * @see https://github.com/moszeed/es6-promise-debounce
+ * @see https://gist.github.com/philbirnie/893950093611d5c1dff4246a572cfbeb/
+ * @see https://github.com/SliceMeNice-ES6/event-utils/blob/master/debounce.js
+ * @see https://github.com/jeromedecoster/raf-funcs
+ * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
+ * @see http://davidwalsh.name/javascript-debounce-function
+ *
+ * @param callback the callback
+ * @param threshold optional delay, default to 250 ms, min to 1000/60ms ms
+ * @param context  optional context of this, default to global
+ * @return {Function} reference to immediate and cancel
+ */
+var MIN_THRESHOLD = 1000 / 60;
+
+var debounceFunction = function debounceFunction(callback) {
+  var threshold = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;
+  var context = arguments[2];
+
+
+  if (threshold < MIN_THRESHOLD) {
+    threshold = MIN_THRESHOLD;
+  }
+
+  if (!context) {
+    context = this || window;
+  }
+
+  var next = null;
+  var start = 0;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    var _cancel = function _cancel() {
+      if (next) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    var execute = function execute() {
+      _cancel();
+      return (0, _apply2.default)(callback, context, args);
+    };
+
+    var later = function later() {
+      if (threshold - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    _cancel();
+    start = Date.now();
+    next = window.requestAnimationFrame(later);
+
+    return {
+      cancel: function cancel() {
+        return _cancel();
+      },
+      immediate: function immediate() {
+        return execute();
+      }
+    };
+  };
+};
+
+exports.default = debounceFunction;
+module.exports = exports["default"];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/dom-utils.js b/node_modules/mdl-ext/es/utils/dom-utils.js
new file mode 100644
index 0000000..3f63f90
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/dom-utils.js
@@ -0,0 +1,424 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.tether = exports.removeChildElements = exports.moveElements = exports.isRectInsideWindowViewport = exports.isFocusable = exports.getScrollParents = exports.getParentElements = exports.getWindowViewport = undefined;
+
+var _isNan = require('babel-runtime/core-js/number/is-nan');
+
+var _isNan2 = _interopRequireDefault(_isNan);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Remove child element(s)
+ * element.innerHTNL = '' has a performance penality!
+ * @see http://jsperf.com/empty-an-element/16
+ * @see http://jsperf.com/force-reflow
+ * @param element
+ * @param forceReflow
+ */
+var removeChildElements = function removeChildElements(element) {
+  var forceReflow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
+
+
+  // See: http://jsperf.com/empty-an-element/16
+  while (element.lastChild) {
+    element.removeChild(element.lastChild);
+  }
+  if (forceReflow) {
+    // See: http://jsperf.com/force-reflow
+    var d = element.style.display;
+
+    element.style.display = 'none';
+    element.style.display = d;
+  }
+};
+
+/**
+ * Moves child elements from a DOM node to another dom node.
+ * @param source {HTMLElement}
+ * @param target {HTMLElement} If the target parameter is ommited, a document fragment is created
+ * @return {HTMLElement} The target node
+ *
+ * @example
+ * // Moves child elements from a DOM node to another dom node.
+ * moveElements(source, destination);
+ *
+ * @example
+ * // If the second parameter is ommited, a document fragment is created:
+ * let fragment = moveElements(source);
+ *
+ * @See: https://github.com/webmodules/dom-move
+ */
+var moveElements = function moveElements(source, target) {
+  if (!target) {
+    target = source.ownerDocument.createDocumentFragment();
+  }
+  while (source.firstChild) {
+    target.appendChild(source.firstChild);
+  }
+  return target;
+};
+
+/**
+ * Get the browser viewport dimensions
+ * @see http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
+ * @return {{windowWidth: number, windowHeight: number}}
+ */
+var getWindowViewport = function getWindowViewport() {
+  return {
+    viewportWidth: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0),
+    viewportHeight: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
+  };
+};
+
+/**
+ * Check whether an element is in the window viewport
+ * @see http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/
+ * @param top
+ * @param left
+ * @param bottom
+ * @param right
+ * @return {boolean} true if rectangle is inside window viewport, otherwise false
+ */
+var isRectInsideWindowViewport = function isRectInsideWindowViewport(_ref) {
+  var top = _ref.top,
+      left = _ref.left,
+      bottom = _ref.bottom,
+      right = _ref.right;
+
+  var _getWindowViewport = getWindowViewport(),
+      viewportWidth = _getWindowViewport.viewportWidth,
+      viewportHeight = _getWindowViewport.viewportHeight;
+
+  return top >= 0 && left >= 0 && bottom <= viewportHeight && right <= viewportWidth;
+};
+
+/**
+ * Get a list of parent elements that can possibly scroll
+ * @param el the element to get parents for
+ * @returns {Array}
+ */
+var getScrollParents = function getScrollParents(el) {
+  var elements = [];
+
+  /*
+  for (el = el.parentNode; el; el = el.parentNode) {
+    const cs = window.getComputedStyle(el);
+    if(!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(el);
+    }
+    if(el === document.body) {
+      break;
+    }
+  }
+  */
+
+  var element = el.parentNode;
+  while (element) {
+    var cs = window.getComputedStyle(element);
+    if (!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
+      elements.unshift(element);
+    }
+    if (element === document.body) {
+      break;
+    }
+    element = element.parentNode;
+  }
+
+  return elements;
+};
+
+/**
+ * Get a list of parent elements, from a given element to a given element
+ * @param {HTMLElement} from
+ * @param {HTMLElement} to
+ * @return {Array<HTMLElement>} the parent elements, not including from and to
+ */
+var getParentElements = function getParentElements(from, to) {
+  var result = [];
+  var element = from.parentNode;
+  while (element) {
+    if (element === to) {
+      break;
+    }
+    result.unshift(element);
+    element = element.parentNode;
+  }
+  return result;
+};
+
+/**
+ * Position element next to button
+ *
+ * Positioning strategy
+ *  1. element.height > viewport.height
+ *     let element.height = viewport.heigt
+ *     let element.overflow-y = auto
+ *  2. element.width > viewport.width
+ *     let element.width = viewport.width
+ *  3. position element below button, align left edge of element with button left
+ *       done if element inside viewport
+ *  4. position element below button, align right edge of element with button right
+ *       done if element inside viewport
+ *  5. positions element above button, aligns left edge of element with button left
+ *       done if element inside viewport
+ *  6. position element above the control element, aligned to its right.
+ *       done if element inside viewport
+ *  7. position element at button right hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  8. position element at button left hand side, aligns element top with button top
+ *       done if element inside viewport
+ *  9. position element inside viewport
+ *     1. position element at viewport bottom
+ *     2. position element at button right hand side
+ *        done if element inside viewport
+ *     3. position element at button left hand side
+ *       done if element inside viewport
+ *     4. position element at viewport right
+ * 10. done
+ *
+ */
+var tether = function tether(controlledBy, element) {
+  var controlRect = controlledBy.getBoundingClientRect();
+
+  // 1. will element height fit inside window viewport?
+
+  var _getWindowViewport2 = getWindowViewport(),
+      viewportWidth = _getWindowViewport2.viewportWidth,
+      viewportHeight = _getWindowViewport2.viewportHeight;
+
+  element.style.height = 'auto';
+  //element.style.overflowY = 'hidden';
+  if (element.offsetHeight > viewportHeight) {
+    element.style.height = viewportHeight + 'px';
+    element.style.overflowY = 'auto';
+  }
+
+  // 2. will element width fit inside window viewport?
+  element.style.width = 'auto';
+  if (element.offsetWidth > viewportWidth) {
+    element.style.width = viewportWidth + 'px';
+  }
+
+  var elementRect = element.getBoundingClientRect();
+
+  // element to control distance
+  var dy = controlRect.top - elementRect.top;
+  var dx = controlRect.left - elementRect.left;
+
+  // element rect, window coordinates relative to top,left of control
+  var top = elementRect.top + dy;
+  var left = elementRect.left + dx;
+  var bottom = top + elementRect.height;
+  var right = left + elementRect.width;
+
+  // Position relative to control
+  var ddy = dy;
+  var ddx = dx;
+
+  if (isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left,
+    bottom: bottom + controlRect.height,
+    right: right
+  })) {
+    // 3 position element below the control element, aligned to its left
+    ddy = controlRect.height + dy;
+    //console.log('***** 3');
+  } else if (isRectInsideWindowViewport({
+    top: top + controlRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom + controlRect.height,
+    right: left + controlRect.width
+  })) {
+    // 4 position element below the control element, aligned to its right
+    ddy = controlRect.height + dy;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 4');
+  } else if (isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left,
+    bottom: bottom - elementRect.height,
+    right: right
+  })) {
+    // 5. position element above the control element, aligned to its left.
+    ddy = dy - elementRect.height;
+    //console.log('***** 5');
+  } else if (isRectInsideWindowViewport({
+    top: top - elementRect.height,
+    left: left + controlRect.width - elementRect.width,
+    bottom: bottom - elementRect.height,
+    right: left + controlRect.width
+  })) {
+    // 6. position element above the control element, aligned to its right.
+    ddy = dy - elementRect.height;
+    ddx = dx + controlRect.width - elementRect.width;
+    //console.log('***** 6');
+  } else if (isRectInsideWindowViewport({
+    top: top,
+    left: left + controlRect.width,
+    bottom: bottom,
+    right: right + controlRect.width
+  })) {
+    // 7. position element at button right hand side
+    ddx = controlRect.width + dx;
+    //console.log('***** 7');
+  } else if (isRectInsideWindowViewport({
+    top: top,
+    left: left - controlRect.width,
+    bottom: bottom,
+    right: right - controlRect.width
+  })) {
+    // 8. position element at button left hand side
+    ddx = dx - elementRect.width;
+    //console.log('***** 8');
+  } else {
+    // 9. position element inside viewport, near controlrect if possible
+    //console.log('***** 9');
+
+    // 9.1 position element near controlrect bottom
+    ddy = dy - bottom + viewportHeight;
+    if (top + controlRect.height >= 0 && bottom + controlRect.height <= viewportHeight) {
+      ddy = controlRect.height + dy;
+    } else if (top - elementRect.height >= 0 && bottom - elementRect.height <= viewportHeight) {
+      ddy = dy - elementRect.height;
+    }
+
+    if (left + elementRect.width + controlRect.width <= viewportWidth) {
+      // 9.2 Position element at button right hand side
+      ddx = controlRect.width + dx;
+      //console.log('***** 9.2');
+    } else if (left - elementRect.width >= 0) {
+      // 9.3 Position element at button left hand side
+      ddx = dx - elementRect.width;
+      //console.log('***** 9.3');
+    } else {
+      // 9.4 position element at (near) viewport right
+      var r = left + elementRect.width - viewportWidth;
+      ddx = dx - r;
+      //console.log('***** 9.4');
+    }
+  }
+
+  // 10. done
+  element.style.top = element.offsetTop + ddy + 'px';
+  element.style.left = element.offsetLeft + ddx + 'px';
+  //console.log('***** 10. done');
+};
+
+/**
+ * Check if the given element can receive focus
+ * @param {HTMLElement} element the element to check
+ * @return {boolean} true if the element is focusable, otherwise false
+ */
+var isFocusable = function isFocusable(element) {
+  // https://github.com/stephenmathieson/is-focusable/blob/master/index.js
+  // http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
+
+  if (element.hasAttribute('tabindex')) {
+    var tabindex = element.getAttribute('tabindex');
+    if (!(0, _isNan2.default)(tabindex)) {
+      return parseInt(tabindex) > -1;
+    }
+  }
+
+  if (element.hasAttribute('contenteditable') && element.getAttribute('contenteditable') !== 'false') {
+    // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#attr-contenteditable
+    return true;
+  }
+
+  // natively focusable, but only when enabled
+  var selector = /input|select|textarea|button|details/i;
+  var name = element.nodeName;
+  if (selector.test(name)) {
+    return element.type.toLowerCase() !== 'hidden' && !element.disabled;
+  }
+
+  // anchors and area must have an href
+  if (name === 'A' || name === 'AREA') {
+    return !!element.href;
+  }
+
+  if (name === 'IFRAME') {
+    // Check visible iframe
+    var cs = window.getComputedStyle(element);
+    return cs.getPropertyValue('display').toLowerCase() !== 'none';
+  }
+
+  return false;
+};
+
+/**
+ * Get a list of offset parents for given element
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @param el the element
+ * @return {Array} a list of offset parents
+ */
+/*
+const offsetParents = (el) => {
+  const elements = [];
+  for (; el; el = el.offsetParent) {
+    elements.unshift(el);
+  }
+  if(!elements.find(e => e === document.body)) {
+    elements.unshift(document.body);
+  }
+  return elements;
+};
+*/
+
+/**
+ * Finds the common offset ancestor of two DOM nodes
+ * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
+ * @see https://gist.github.com/benpickles/4059636
+ * @param a
+ * @param b
+ * @return {Element} The common offset ancestor of a and b
+ */
+/*
+const commonOffsetAncestor = (a, b) => {
+  const parentsA = offsetParents(a);
+  const parentsB = offsetParents(b);
+
+  for (let i = 0; i < parentsA.length; i++) {
+    if (parentsA[i] !== parentsB[i]) return parentsA[i-1];
+  }
+};
+*/
+
+/**
+ * Calculate position relative to a target element
+ * @see http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+ * @param target
+ * @param el
+ * @return {{top: number, left: number}}
+ */
+/*
+const calcPositionRelativeToTarget = (target, el) => {
+  let top = 0;
+  let left = 0;
+
+  while(el) {
+    top += (el.offsetTop - el.scrollTop + el.clientTop) || 0;
+    left += (el.offsetLeft - el.scrollLeft + el.clientLeft) || 0;
+    el = el.offsetParent;
+
+    if(el === target) {
+      break;
+    }
+  }
+  return { top: top, left: left };
+};
+*/
+
+exports.getWindowViewport = getWindowViewport;
+exports.getParentElements = getParentElements;
+exports.getScrollParents = getScrollParents;
+exports.isFocusable = isFocusable;
+exports.isRectInsideWindowViewport = isRectInsideWindowViewport;
+exports.moveElements = moveElements;
+exports.removeChildElements = removeChildElements;
+exports.tether = tether;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/easing.js b/node_modules/mdl-ext/es/utils/easing.js
new file mode 100644
index 0000000..95da687
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/easing.js
@@ -0,0 +1,22 @@
+'use strict';
+
+// See: http://robertpenner.com/easing/
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var easeInOutQuad = function easeInOutQuad(t, b, c, d) {
+  t /= d / 2;
+  if (t < 1) return c / 2 * t * t + b;
+  t--;
+  return -c / 2 * (t * (t - 2) - 1) + b;
+};
+
+var inOutQuintic = function inOutQuintic(t, b, c, d) {
+  var ts = (t /= d) * t;
+  var tc = ts * t;
+  return b + c * (6 * tc * ts + -15 * ts * ts + 10 * tc);
+};
+
+exports.easeInOutQuad = easeInOutQuad;
+exports.inOutQuintic = inOutQuintic;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/full-throttle.js b/node_modules/mdl-ext/es/utils/full-throttle.js
new file mode 100644
index 0000000..da32123
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/full-throttle.js
@@ -0,0 +1,52 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Since some events can fire at a high rate, the event handler should be limited to execute computationally
+ * expensive operations, such as DOM modifications, inside a single rendered frame.
+ * When listening to e.g. scroll and resize events, the browser tends to fire off more events per
+ * second than are actually useful. For instance, if your event listener sets some element positions, then it
+ * is possible for those positions to be updated multiple times in a single rendered frame. In this case, all of
+ * the layout calculations triggered by setting the elements' positions will be wasted except for the one time that
+ * it runs immediately prior to the browser rendering the updated layout to the screen.
+ * To avoid wasting cycles, we can use requestAnimationFrame to only run the event listener once just before the page
+ * is rendered to the screen.
+ * *
+ * @param callback the function to throttle
+ * @param context  optional context of this, default to global
+ * @return {function(...[*])}
+ */
+var fullThrottle = function fullThrottle(callback, context) {
+
+  if (!context) {
+    context = undefined || window;
+  }
+
+  var throttling = false;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    if (!throttling) {
+      throttling = true;
+      window.requestAnimationFrame(function () {
+        throttling = false;
+        return (0, _apply2.default)(callback, context, args);
+      });
+    }
+  };
+};
+
+exports.default = fullThrottle;
+module.exports = exports["default"];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/index.js b/node_modules/mdl-ext/es/utils/index.js
new file mode 100644
index 0000000..4ef9db4
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/index.js
@@ -0,0 +1,15 @@
+'use strict';
+
+require('./constants');
+
+require('./dom-utils');
+
+require('./string-utils');
+
+require('./json-utils');
+
+require('./full-throttle');
+
+require('./easing');
+
+require('./interval-function');
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/interval-function.js b/node_modules/mdl-ext/es/utils/interval-function.js
new file mode 100644
index 0000000..abe7f9b
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/interval-function.js
@@ -0,0 +1,96 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var MIN_INERVAL = 1000 / 60;
+
+/**
+ * Trigger a callback at a given interval
+ * @param interval defaults to 1000/60 ms
+ * @return {function()} reference to start, stop, immediate and started
+ */
+
+var intervalFunction = function intervalFunction() {
+  var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MIN_INERVAL;
+
+
+  var lapse = interval < MIN_INERVAL ? MIN_INERVAL : interval;
+  var cb = undefined;
+  var next = null;
+  var timeElapsed = 0;
+
+  var execute = function execute() {
+    var f = cb(timeElapsed);
+    if (!f) {
+      cancel();
+    }
+  };
+
+  var cancel = function cancel() {
+    if (next) {
+      window.cancelAnimationFrame(next);
+    }
+    next = null;
+    timeElapsed = 0;
+  };
+
+  var _start = function _start() {
+    var timeStart = Date.now();
+
+    var loop = function loop(now) {
+      if (next) {
+        next = window.requestAnimationFrame(function () {
+          return loop(Date.now());
+        });
+
+        timeElapsed += now - timeStart;
+
+        if (timeElapsed >= lapse) {
+          execute();
+          if ((timeElapsed -= lapse) > lapse) {
+            // time elapsed - interval_ > interval_ , indicates inactivity
+            // Could be due to browser minimized, tab changed, screen saver started, computer sleep, and so on
+            timeElapsed = 0;
+          }
+        }
+        timeStart = now;
+      }
+    };
+
+    next = 1; // a truthy value for first loop
+    loop(timeStart);
+  };
+
+  return {
+    get started() {
+      return next != null;
+    },
+    get interval() {
+      return lapse;
+    },
+    set interval(value) {
+      lapse = value < MIN_INERVAL ? MIN_INERVAL : value;
+    },
+    start: function start(callback) {
+      if (typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+      cb = callback;
+      _start();
+    },
+    immediate: function immediate() {
+      if (!cb) {
+        throw new ReferenceError('callback parameter is not defined. Call start before immediate.');
+      }
+      execute();
+    },
+
+    stop: function stop() {
+      return cancel();
+    }
+  };
+};
+
+exports.default = intervalFunction;
+module.exports = exports['default'];
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/json-utils.js b/node_modules/mdl-ext/es/utils/json-utils.js
new file mode 100644
index 0000000..50be006
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/json-utils.js
@@ -0,0 +1,31 @@
+'use strict';
+
+/**
+ * Converts a JSON string to object
+ * @param jsonString
+ * @param source
+ */
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.jsonStringToObject = undefined;
+
+var _assign = require('babel-runtime/core-js/object/assign');
+
+var _assign2 = _interopRequireDefault(_assign);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var jsonStringToObject = function jsonStringToObject(jsonString) {
+  var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+  var s = jsonString.replace(/'/g, '"');
+  try {
+    return (0, _assign2.default)(source, JSON.parse(s));
+  } catch (e) {
+    throw new Error('Failed to parse json string: ' + s + '. Error: ' + e.message);
+  }
+};
+
+exports.jsonStringToObject = jsonStringToObject;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/resize-observer.js b/node_modules/mdl-ext/es/utils/resize-observer.js
new file mode 100644
index 0000000..37f0e0d
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/resize-observer.js
@@ -0,0 +1,377 @@
+'use strict';
+
+var _getIterator2 = require('babel-runtime/core-js/get-iterator');
+
+var _getIterator3 = _interopRequireDefault(_getIterator2);
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _intervalFunction = require('./interval-function');
+
+var _intervalFunction2 = _interopRequireDefault(_intervalFunction);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+(function (window, document) {
+  'use strict';
+
+  if (typeof window.ResizeObserver !== 'undefined') {
+    return;
+  }
+
+  document.resizeObservers = [];
+
+  /**
+   * The content rect is defined in section 2.3 ResizeObserverEntry of the spec
+   * @param target the element to calculate the content rect for
+   * @return {{top: (Number|number), left: (Number|number), width: number, height: number}}
+   *
+   * Note:
+   * Avoid using margins on the observed element. The calculation can return incorrect values when margins are involved.
+   *
+   * The following CSS will report incorrect width (Chrome OSX):
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin:30px; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * The calculated width is 280. The actual (correct) width is 340 since Chrome clips the margin.
+   *
+   * Use an outer container if you really need a "margin":
+   *
+   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto; padding:30px;">
+   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin: 0; border: 20px solid red; padding:10px;">
+   *   </div>
+   * </div>
+   *
+   * A more detailed explanation can be fund here:
+   * http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
+   */
+  var getContentRect = function getContentRect(target) {
+    var cs = window.getComputedStyle(target);
+    var r = target.getBoundingClientRect();
+    var top = parseFloat(cs.paddingTop) || 0;
+    var left = parseFloat(cs.paddingLeft) || 0;
+    var width = r.width - ((parseFloat(cs.marginLeft) || 0) + (parseFloat(cs.marginRight) || 0) + (parseFloat(cs.borderLeftWidth) || 0) + (parseFloat(cs.borderRightWidth) || 0) + left + (parseFloat(cs.paddingRight) || 0));
+    var height = r.height - ((parseFloat(cs.marginTop) || 0) + (parseFloat(cs.marginBottom) || 0) + (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0) + top + (parseFloat(cs.paddingBottom) || 0));
+    return { width: width, height: height, top: top, left: left };
+  };
+
+  var dimensionHasChanged = function dimensionHasChanged(target, lastWidth, lastHeight) {
+    var _getContentRect = getContentRect(target),
+        width = _getContentRect.width,
+        height = _getContentRect.height;
+
+    return width !== lastWidth || height !== lastHeight;
+  };
+
+  /**
+   * ResizeObservation holds observation information for a single Element.
+   * @param target
+   * @return {{target: *, broadcastWidth, broadcastHeight, isOrphan: (function()), isActive: (function())}}
+   * @constructor
+   */
+  var ResizeObservation = function ResizeObservation(target) {
+    var _getContentRect2 = getContentRect(target),
+        width = _getContentRect2.width,
+        height = _getContentRect2.height;
+
+    return {
+      target: target,
+      broadcastWidth: width,
+      broadcastHeight: height,
+
+      isOrphan: function isOrphan() {
+        return !this.target || !this.target.parentNode;
+      },
+      isActive: function isActive() {
+        return dimensionHasChanged(this.target, this.broadcastWidth, this.broadcastHeight);
+      }
+    };
+  };
+
+  /**
+   * A snapshot of the observed element
+   * @param target
+   * @param rect
+   * @return {{target: *, contentRect: *}}
+   * @constructor
+   */
+  var ResizeObserverEntry = function ResizeObserverEntry(target, rect) {
+    return {
+      target: target,
+      contentRect: rect
+    };
+  };
+
+  /**
+   * The ResizeObserver is used to observe changes to Element's content rect.
+   */
+
+  var ResizeObserver = function () {
+
+    /**
+     * Constructor for instantiating new Resize observers.
+     * @param callback void (sequence<ResizeObserverEntry> entries). The function which will be called on each resize.
+     * @throws {TypeError}
+     */
+    function ResizeObserver(callback) {
+      (0, _classCallCheck3.default)(this, ResizeObserver);
+
+
+      if (typeof callback !== 'function') {
+        throw new TypeError('callback parameter must be a function');
+      }
+
+      this.callback_ = callback;
+      this.observationTargets_ = [];
+      this.activeTargets_ = [];
+
+      document.resizeObservers.push(this);
+    }
+
+    /**
+     * A list of ResizeObservations. It represents all Elements being observed.
+     *
+     * @return {Array}
+     */
+
+
+    (0, _createClass3.default)(ResizeObserver, [{
+      key: 'observe',
+
+
+      /**
+       * Adds target to the list of observed elements.
+       * @param {HTMLElement} target The target to observe
+       */
+      value: function observe(target) {
+        if (target) {
+          if (!(target instanceof HTMLElement)) {
+            throw new TypeError('target parameter must be an HTMLElement');
+          }
+          if (!this.observationTargets_.find(function (t) {
+            return t.target === target;
+          })) {
+            this.observationTargets_.push(ResizeObservation(target));
+            resizeController.start();
+          }
+        }
+      }
+
+      /**
+       * Removes target from the list of observed elements.
+       * @param target The target to remove
+       */
+
+    }, {
+      key: 'unobserve',
+      value: function unobserve(target) {
+        var i = this.observationTargets_.findIndex(function (t) {
+          return t.target === target;
+        });
+        if (i > -1) {
+          this.observationTargets_.splice(i, 1);
+        }
+      }
+
+      /**
+       * Stops the ResizeObserver instance from receiving notifications of resize changes.
+       * Until the observe() method is used again, observer's callback will not be invoked.
+       */
+
+    }, {
+      key: 'disconnect',
+      value: function disconnect() {
+        this.observationTargets_ = [];
+        this.activeTargets_ = [];
+      }
+
+      /**
+       * Removes the ResizeObserver from the list of observers
+       */
+
+    }, {
+      key: 'destroy',
+      value: function destroy() {
+        var _this = this;
+
+        this.disconnect();
+        var i = document.resizeObservers.findIndex(function (o) {
+          return o === _this;
+        });
+        if (i > -1) {
+          document.resizeObservers.splice(i, 1);
+        }
+      }
+    }, {
+      key: 'deleteOrphansAndPopulateActiveTargets_',
+      value: function deleteOrphansAndPopulateActiveTargets_() {
+
+        // Works, but two iterations
+        //this.observationTargets_ = this.observationTargets_.filter( resizeObervation => !resizeObervation.isOrphan());
+        //this.activeTargets_ = this.observationTargets_.filter( resizeObervation => resizeObervation.isActive());
+
+        // Same result as above, one iteration
+        /*
+        this.activeTargets_ = [];
+        let n = this.observationTargets_.length-1;
+        while(n >= 0) {
+          if(this.observationTargets_[n].isOrphan()) {
+            this.observationTargets_.splice(n, 1);
+          }
+          else if(this.observationTargets_[n].isActive()) {
+            this.activeTargets_.push(this.observationTargets_[n]);
+          }
+          n -= 1;
+        }
+        */
+
+        // Same result as above - but reduce is cooler :-)
+        this.activeTargets_ = this.observationTargets_.reduceRight(function (prev, resizeObservation, index, arr) {
+          if (resizeObservation.isOrphan()) {
+            arr.splice(index, 1);
+          } else if (resizeObservation.isActive()) {
+            prev.push(resizeObservation);
+          }
+          return prev;
+        }, []);
+      }
+    }, {
+      key: 'broadcast_',
+      value: function broadcast_() {
+        this.deleteOrphansAndPopulateActiveTargets_();
+        if (this.activeTargets_.length > 0) {
+          var entries = [];
+          var _iteratorNormalCompletion = true;
+          var _didIteratorError = false;
+          var _iteratorError = undefined;
+
+          try {
+            for (var _iterator = (0, _getIterator3.default)(this.activeTargets_), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+              var resizeObservation = _step.value;
+
+              var rect = getContentRect(resizeObservation.target);
+              resizeObservation.broadcastWidth = rect.width;
+              resizeObservation.broadcastHeight = rect.height;
+              entries.push(ResizeObserverEntry(resizeObservation.target, rect));
+            }
+          } catch (err) {
+            _didIteratorError = true;
+            _iteratorError = err;
+          } finally {
+            try {
+              if (!_iteratorNormalCompletion && _iterator.return) {
+                _iterator.return();
+              }
+            } finally {
+              if (_didIteratorError) {
+                throw _iteratorError;
+              }
+            }
+          }
+
+          this.callback_(entries);
+          this.activeTargets_ = [];
+        }
+      }
+    }, {
+      key: 'observationTargets',
+      get: function get() {
+        return this.observationTargets_;
+      }
+
+      /**
+       *  A list of ResizeObservations. It represents all Elements whose size has
+       *  changed since last observation broadcast that are eligible for broadcast.
+       *
+       * @return {Array}
+       */
+
+    }, {
+      key: 'activeTargets',
+      get: function get() {
+        return this.activeTargets_;
+      }
+    }]);
+    return ResizeObserver;
+  }();
+
+  //let interval = require('./interval-function');
+
+  /**
+   * Broadcasts Element.resize events
+   * @return {{start: (function()), stop: (function())}}
+   * @constructor
+   */
+
+
+  var ResizeController = function ResizeController() {
+
+    var shouldStop = function shouldStop() {
+      return document.resizeObservers.findIndex(function (resizeObserver) {
+        return resizeObserver.observationTargets.length > 0;
+      }) > -1;
+    };
+
+    var execute = function execute() {
+      //console.log('***** Execute');
+      var _iteratorNormalCompletion2 = true;
+      var _didIteratorError2 = false;
+      var _iteratorError2 = undefined;
+
+      try {
+        for (var _iterator2 = (0, _getIterator3.default)(document.resizeObservers), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+          var resizeObserver = _step2.value;
+
+          resizeObserver.broadcast_();
+        }
+      } catch (err) {
+        _didIteratorError2 = true;
+        _iteratorError2 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion2 && _iterator2.return) {
+            _iterator2.return();
+          }
+        } finally {
+          if (_didIteratorError2) {
+            throw _iteratorError2;
+          }
+        }
+      }
+
+      return shouldStop();
+    };
+
+    var interval = (0, _intervalFunction2.default)(200);
+
+    return {
+      start: function start() {
+        if (!interval.started) {
+          //console.log('***** Start poll');
+          interval.start(execute);
+        }
+      }
+    };
+  };
+
+  window.ResizeObserver = ResizeObserver;
+
+  var resizeController = ResizeController();
+  //console.log('***** ResizeObserver ready');
+})(window, document);
+/**
+ * An API for observing changes to Element’s size.
+ *
+ * @See https://wicg.github.io/ResizeObserver/
+ * @ee https://github.com/pelotoncycle/resize-observer
+ *
+ */
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/string-utils.js b/node_modules/mdl-ext/es/utils/string-utils.js
new file mode 100644
index 0000000..ab0045a
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/string-utils.js
@@ -0,0 +1,114 @@
+'use strict';
+
+/**
+ * @license
+ * Copyright 2016 Leif Olsen. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * A javascript utility for conditionally creating a list of strings.
+ * The function takes any number of arguments which can be a string or object.
+ * Inspired by (but not copied from) JedWatson/classnames, https://github.com/JedWatson/classnames
+ *
+ * @param  {*} args the strings and/or objects to
+ * @return {Array} a list of strings
+ * @example
+ * // Returns ['foo', 'bar', 'baz', 'quux']
+ * stringList(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.stringList = exports.randomString = exports.joinStrings = undefined;
+
+var _keys = require('babel-runtime/core-js/object/keys');
+
+var _keys2 = _interopRequireDefault(_keys);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var stringList = function stringList() {
+  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+    args[_key] = arguments[_key];
+  }
+
+  var isString = function isString(str) {
+    return str != null && typeof str === 'string';
+  };
+
+  var flatten = function flatten(list) {
+    return list.reduce(function (a, b) {
+      return a.concat(Array.isArray(b) ? flatten(b) : b);
+    }, []);
+  };
+
+  var objectToStrings = function objectToStrings(arg) {
+    return (0, _keys2.default)(arg).filter(function (key) {
+      return arg[key];
+    }).map(function (key) {
+      return key;
+    });
+  };
+
+  return args.filter(function (arg) {
+    return !!arg;
+  }).map(function (arg) {
+    return isString(arg) ? arg : objectToStrings(arg);
+  }).reduce(function (result, arg) {
+    return result.concat(Array.isArray(arg) ? flatten(arg) : arg);
+  }, []);
+};
+
+/**
+ * A simple javascript utility for conditionally joining strings together.
+ * The function takes a delimiter string and any number of arguments which can be a string or object.
+ *
+ * @param delimiter delimiter to separate joined strings
+ * @param  {*} args the strings and/or objects to join
+ * @return {String} the joined strings
+ * @example
+ * // Returns 'foo, bar, baz, quux'
+ * joinStrings(', ', 'foo', { bar: true, duck: false }, 'baz', { quux: true });
+ * @example see the tests for more examples
+ */
+var joinStrings = function joinStrings() {
+  for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+    args[_key2 - 1] = arguments[_key2];
+  }
+
+  var delimiter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ' ';
+  return stringList.apply(undefined, args).join(delimiter);
+};
+
+/**
+ * Generates a random string with a given length
+ * @param n {Integer} length of generated string
+ * @see http://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
+ * @return {String} the random string
+ * @example
+ * // Returns e.g. 'pd781w0y'
+ * randomString(8);
+ * @example see the tests for more examples
+ */
+var randomString = function randomString() {
+  var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 12;
+  return Array(n + 1).join((Math.random().toString(36) + '00000000000000000').slice(2, 18)).slice(0, n);
+};
+
+exports.joinStrings = joinStrings;
+exports.randomString = randomString;
+exports.stringList = stringList;
\ No newline at end of file
diff --git a/node_modules/mdl-ext/es/utils/throttle-function.js b/node_modules/mdl-ext/es/utils/throttle-function.js
new file mode 100644
index 0000000..03a5cea
--- /dev/null
+++ b/node_modules/mdl-ext/es/utils/throttle-function.js
@@ -0,0 +1,84 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _apply = require("babel-runtime/core-js/reflect/apply");
+
+var _apply2 = _interopRequireDefault(_apply);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Throttling enforces a maximum number of times a function can be called over time.
+ *
+ * @param callback the function to throttle
+ * @param delay optional delay, default to 1000/60ms
+ * @param context optional context of this, default to global window
+ * @returns {Function} reference to immediate and cancel functions
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events/resize#Example
+ * @see https://gist.github.com/yoavniran/d1d33f278bb7744d55c3
+ * @see https://github.com/pelotoncycle/frame-throttle
+ * @see https://github.com/jeromedecoster/raf-funcs
+ */
+var MIN_DELAY = 1000 / 60;
+
+var throttleFunction = function throttleFunction(callback) {
+  var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : MIN_DELAY;
+  var context = arguments[2];
+
+
+  if (delay < MIN_DELAY) {
+    delay = MIN_DELAY;
+  }
+
+  if (!context) {
+    context = undefined || window;
+  }
+
+  var next = null;
+  var start = 0;
+
+  return function () {
+    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+      args[_key] = arguments[_key];
+    }
+
+    var _cancel = function _cancel() {
+      if (next !== null) {
+        window.cancelAnimationFrame(next);
+        next = null;
+      }
+    };
+
+    var execute = function execute() {
+      _cancel();
+      return (0, _apply2.default)(callback, context, args);
+    };
+
+    var later = function later() {
+      if (delay - (Date.now() - start) <= 0) {
+        return execute();
+      }
+      next = window.requestAnimationFrame(later);
+    };
+
+    if (next === null) {
+      start = Date.now();
+      next = window.requestAnimationFrame(later);
+    }
+
+    return {
+      cancel: function cancel() {
+        return _cancel();
+      },
+      immediate: function immediate() {
+        return execute();
+      }
+    };
+  };
+};
+
+exports.default = throttleFunction;
+module.exports = exports["default"];
\ No newline at end of file
