Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
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