diff --git a/node_modules/mdl-ext/src/carousel/carousel.js b/node_modules/mdl-ext/src/carousel/carousel.js
new file mode 100644
index 0000000..8fe59e1
--- /dev/null
+++ b/node_modules/mdl-ext/src/carousel/carousel.js
@@ -0,0 +1,726 @@
+/**
+ * @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
+ */
+
+import intervalFunction from '../utils/interval-function';
+import { inOutQuintic } from '../utils/easing';
+import { jsonStringToObject} from '../utils/json-utils';
+import {
+  VK_TAB,
+  VK_ENTER,
+  VK_ESC,
+  VK_SPACE,
+  VK_PAGE_UP,
+  VK_PAGE_DOWN,
+  VK_END,
+  VK_HOME,
+  VK_ARROW_LEFT,
+  VK_ARROW_UP,
+  VK_ARROW_RIGHT,
+  VK_ARROW_DOWN,
+  IS_UPGRADED,
+  IS_FOCUSED,
+  MDL_RIPPLE,
+  MDL_RIPPLE_COMPONENT,
+  MDL_RIPPLE_EFFECT,
+  MDL_RIPPLE_EFFECT_IGNORE_EVENTS
+} from '../utils/constants';
+
+const MDL_RIPPLE_CONTAINER = 'mdlext-carousel__slide__ripple-container';
+
+
+(function() {
+  'use strict';
+
+  //const CAROUSEL = 'mdlext-carousel';
+  const SLIDE      = 'mdlext-carousel__slide';
+  const ROLE       = 'list';
+  const SLIDE_ROLE = 'listitem';
+
+
+  /**
+   * @constructor
+   * @param {Element} element The element that will be upgraded.
+   */
+  const MaterialExtCarousel = function MaterialExtCarousel(element) {
+    // Stores the element.
+    this.element_ = element;
+
+    // Default config
+    this.config_ = {
+      interactive  : true,
+      autostart    : false,
+      type         : 'slide',
+      interval     : 1000,
+      animationLoop: intervalFunction(1000)
+    };
+
+    this.scrollAnimation_ = intervalFunction(33);
+
+    // Initialize instance.
+    this.init();
+  };
+
+  window['MaterialExtCarousel'] = MaterialExtCarousel;
+
+
+  /**
+   * Start slideshow animation
+   * @private
+   */
+  MaterialExtCarousel.prototype.startSlideShow_ = function() {
+
+    const nextSlide = () => {
+      let 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;
+    };
+
+    const nextScroll = direction => {
+      let nextDirection = direction;
+
+      if('next' === direction &&  this.element_.scrollLeft === this.element_.scrollWidth - this.element_.clientWidth) {
+        nextDirection = 'prev';
+      }
+      else if(this.element_.scrollLeft === 0) {
+        nextDirection = 'next';
+      }
+      const 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) {
+      this.config_.animationLoop.interval = this.config_.interval;
+      let direction = 'next';
+
+      if('scroll' === this.config_.type) {
+        this.config_.animationLoop.start( () => {
+          direction = nextScroll(direction);
+          return true; // It runs until cancelSlideShow_ is triggered
+        });
+      }
+      else {
+        nextSlide();
+        this.config_.animationLoop.start( () => {
+          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', VK_ESC, this.element_.querySelector(`.${SLIDE}[aria-selected]`));
+    }
+  };
+
+  /**
+   * Animate scroll
+   * @param newPosition
+   * @param newDuration
+   * @param completedCallback
+   * @private
+   */
+  MaterialExtCarousel.prototype.animateScroll_ = function( newPosition, newDuration, completedCallback ) {
+
+    const start = this.element_.scrollLeft;
+    const distance = newPosition - start;
+
+    if(distance !== 0) {
+      const duration = Math.max(Math.min(Math.abs(distance), newDuration||400), 100); // duration is between 100 and newDuration||400ms||distance
+      let t = 0;
+      this.scrollAnimation_.stop();
+      this.scrollAnimation_.start( timeElapsed => {
+        t += timeElapsed;
+        if(t < duration) {
+          this.element_.scrollLeft = inOutQuintic(t, start, distance, duration);
+          return true;
+        }
+        else {
+          this.element_.scrollLeft = newPosition;
+          if(completedCallback) {
+            completedCallback();
+          }
+          return false;
+        }
+      });
+    }
+    else {
+      if(completedCallback) {
+        completedCallback();
+      }
+    }
+  };
+
+  /**
+   * Execute commend
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.command_ = function( event ) {
+    let x = 0;
+    let slide = null;
+    const 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':
+        Object.assign(this.config_, event.detail);
+        this.startSlideShow_();
+        return;
+
+      case 'pause':
+        return;
+
+      default:
+        return;
+    }
+
+    this.animateScroll_(x, undefined, () => {
+      if ('scroll-next' === a || 'scroll-prev' === a) {
+        const slides = this.getSlidesInViewport_();
+        if (slides.length > 0) {
+          slide = 'scroll-next' === a ? slides[0] : slides[slides.length - 1];
+        }
+      }
+      this.setAriaSelected_(slide);
+      this.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_) {
+
+      let action = 'first';
+
+      if ( event.keyCode === VK_HOME    || event.keyCode === VK_END
+        || event.keyCode === VK_PAGE_UP || event.keyCode === VK_PAGE_DOWN) {
+
+        event.preventDefault();
+        if (event.keyCode === VK_END) {
+          action = 'last';
+        }
+        else if (event.keyCode === VK_PAGE_UP) {
+          action = 'scroll-prev';
+        }
+        else if (event.keyCode === VK_PAGE_DOWN) {
+          action = 'scroll-next';
+        }
+
+        const cmd = new CustomEvent('select', {
+          detail: {
+            action: action,
+          }
+        });
+        this.command_(cmd);
+      }
+      else if ( event.keyCode === VK_TAB
+        || event.keyCode === VK_ENTER      || event.keyCode === VK_SPACE
+        || event.keyCode === VK_ARROW_UP   || event.keyCode === VK_ARROW_LEFT
+        || event.keyCode === VK_ARROW_DOWN || event.keyCode === VK_ARROW_RIGHT) {
+
+        let slide = getSlide_(event.target);
+
+        if(!slide) {
+          return;
+        }
+
+        // Cancel slideshow if running
+        this.cancelSlideShow_();
+
+        switch (event.keyCode) {
+          case VK_ARROW_UP:
+          case VK_ARROW_LEFT:
+            action = 'prev';
+            slide = slide.previousElementSibling;
+            break;
+
+          case VK_ARROW_DOWN:
+          case VK_ARROW_RIGHT:
+            action = 'next';
+            slide = slide.nextElementSibling;
+            break;
+
+          case VK_TAB:
+            if (event.shiftKey) {
+              action = 'prev';
+              slide = slide.previousElementSibling;
+            }
+            else {
+              action = 'next';
+              slide = slide.nextElementSibling;
+            }
+            break;
+
+          case VK_SPACE:
+          case 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) {
+    event.preventDefault();
+
+    // Cancel slideshow if running
+    this.cancelSlideShow_();
+
+    let updating = false;
+    let rAFDragId = 0;
+
+    const startX = event.clientX || (event.touches !== undefined ? event.touches[0].clientX : 0);
+    let prevX = startX;
+    const targetElement = event.target;
+
+    const update = e => {
+      const currentX = (e.clientX || (e.touches !== undefined ? e.touches[0].clientX : 0));
+      const dx = prevX - currentX;
+
+      if(dx < 0) {
+        this.element_.scrollLeft = Math.max(this.element_.scrollLeft + dx, 0);
+      }
+      else if(dx > 0) {
+        this.element_.scrollLeft = Math.min(this.element_.scrollLeft + dx, this.element_.scrollWidth - this.element_.clientWidth);
+      }
+
+      prevX = currentX;
+      updating = false;
+    };
+
+    // drag handler
+    const drag = e => {
+      e.preventDefault();
+
+      if(!updating) {
+        rAFDragId = window.requestAnimationFrame( () => update(e));
+        updating = true;
+      }
+    };
+
+    // end drag handler
+    const endDrag = e => {
+      e.preventDefault();
+
+      this.element_.removeEventListener('mousemove', drag);
+      this.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);
+
+      const slide = getSlide_(targetElement);
+      setFocus_(slide);
+      this.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) {
+    const 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(IS_FOCUSED);
+    }
+  };
+
+  /**
+   * Handle blur
+   * @param event
+   * @private
+   */
+  MaterialExtCarousel.prototype.blurHandler_ = function(event) {
+    const slide = getSlide_(event.target);
+    if(slide) {
+      slide.classList.remove(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);
+
+      const 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() {
+    const carouselRect = this.element_.getBoundingClientRect();
+
+    const slidesInViewport = [...this.element_.querySelectorAll(`.${SLIDE}`)].filter( slide => {
+      const 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) {
+    const carouselRect = this.element_.getBoundingClientRect();
+    const slideRect = slide.getBoundingClientRect();
+
+    if(slideRect.left < carouselRect.left) {
+      const x = this.element_.scrollLeft - (carouselRect.left - slideRect.left);
+      this.animateScroll_(x);
+    }
+    else if(slideRect.right > carouselRect.right) {
+      const 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) {
+      [...this.element_.querySelectorAll(`.${SLIDE}[aria-selected]`)].forEach(
+        slide => 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
+  const getSlide_ = element => {
+    return element.closest(`.${SLIDE}`);
+  };
+
+  const setFocus_ = slide => {
+    if(slide) {
+      slide.focus();
+    }
+  };
+
+  const addRipple_ = slide => {
+    if(!slide.querySelector(`.${MDL_RIPPLE_CONTAINER}`)) {
+      const rippleContainer = document.createElement('span');
+      rippleContainer.classList.add(MDL_RIPPLE_CONTAINER);
+      rippleContainer.classList.add(MDL_RIPPLE_EFFECT);
+      const ripple = document.createElement('span');
+      ripple.classList.add(MDL_RIPPLE);
+      rippleContainer.appendChild(ripple);
+
+      const img = slide.querySelector('img');
+      if (img) {
+        // rippleContainer blocks image title
+        rippleContainer.title = img.title;
+      }
+      slide.appendChild(rippleContainer);
+      componentHandler.upgradeElement(rippleContainer, 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() {
+
+    const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+
+    [...this.element_.querySelectorAll(`.${SLIDE}`)].forEach( slide => {
+
+      slide.setAttribute('role', SLIDE_ROLE);
+
+      if(this.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_ = jsonStringToObject(this.element_.getAttribute('data-config'), this.config_);
+      }
+
+      // Wai-Aria
+      this.element_.setAttribute('role', ROLE);
+
+      // Prefer tabindex -1
+      if(!Number.isInteger(this.element_.getAttribute('tabindex'))) {
+        this.element_.setAttribute('tabindex', -1);
+      }
+
+      // Remove listeners, just in case ...
+      this.removeListeners_();
+
+      if(this.config_.interactive) {
+
+        // Ripple
+        const hasRippleEffect = this.element_.classList.contains(MDL_RIPPLE_EFFECT);
+        if (hasRippleEffect) {
+          this.element_.classList.add(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(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
+  });
+})();
