Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/node_modules/material-design-lite/src/layout/layout.js b/node_modules/material-design-lite/src/layout/layout.js
new file mode 100644
index 0000000..a1cc1dc
--- /dev/null
+++ b/node_modules/material-design-lite/src/layout/layout.js
@@ -0,0 +1,574 @@
+/**
+ * @license
+ * Copyright 2015 Google Inc. 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.
+ */
+
+(function() {
+  'use strict';
+
+  /**
+   * Class constructor for Layout MDL 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 MaterialLayout = function MaterialLayout(element) {
+    this.element_ = element;
+
+    // Initialize instance.
+    this.init();
+  };
+  window['MaterialLayout'] = MaterialLayout;
+
+  /**
+   * Store constants in one place so they can be updated easily.
+   *
+   * @enum {string | number}
+   * @private
+   */
+  MaterialLayout.prototype.Constant_ = {
+    MAX_WIDTH: '(max-width: 1024px)',
+    TAB_SCROLL_PIXELS: 100,
+    RESIZE_TIMEOUT: 100,
+
+    MENU_ICON: '',
+    CHEVRON_LEFT: 'chevron_left',
+    CHEVRON_RIGHT: 'chevron_right'
+  };
+
+  /**
+   * Keycodes, for code readability.
+   *
+   * @enum {number}
+   * @private
+   */
+  MaterialLayout.prototype.Keycodes_ = {
+    ENTER: 13,
+    ESCAPE: 27,
+    SPACE: 32
+  };
+
+  /**
+   * Modes.
+   *
+   * @enum {number}
+   * @private
+   */
+  MaterialLayout.prototype.Mode_ = {
+    STANDARD: 0,
+    SEAMED: 1,
+    WATERFALL: 2,
+    SCROLL: 3
+  };
+
+  /**
+   * Store strings for class names defined by this component that are used in
+   * JavaScript. This allows us to simply change it in one place should we
+   * decide to modify at a later date.
+   *
+   * @enum {string}
+   * @private
+   */
+  MaterialLayout.prototype.CssClasses_ = {
+    CONTAINER: 'mdl-layout__container',
+    HEADER: 'mdl-layout__header',
+    DRAWER: 'mdl-layout__drawer',
+    CONTENT: 'mdl-layout__content',
+    DRAWER_BTN: 'mdl-layout__drawer-button',
+
+    ICON: 'material-icons',
+
+    JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+    RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',
+    RIPPLE: 'mdl-ripple',
+    RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+
+    HEADER_SEAMED: 'mdl-layout__header--seamed',
+    HEADER_WATERFALL: 'mdl-layout__header--waterfall',
+    HEADER_SCROLL: 'mdl-layout__header--scroll',
+
+    FIXED_HEADER: 'mdl-layout--fixed-header',
+    OBFUSCATOR: 'mdl-layout__obfuscator',
+
+    TAB_BAR: 'mdl-layout__tab-bar',
+    TAB_CONTAINER: 'mdl-layout__tab-bar-container',
+    TAB: 'mdl-layout__tab',
+    TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',
+    TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',
+    TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',
+    TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch',
+    PANEL: 'mdl-layout__tab-panel',
+
+    HAS_DRAWER: 'has-drawer',
+    HAS_TABS: 'has-tabs',
+    HAS_SCROLLING_HEADER: 'has-scrolling-header',
+    CASTING_SHADOW: 'is-casting-shadow',
+    IS_COMPACT: 'is-compact',
+    IS_SMALL_SCREEN: 'is-small-screen',
+    IS_DRAWER_OPEN: 'is-visible',
+    IS_ACTIVE: 'is-active',
+    IS_UPGRADED: 'is-upgraded',
+    IS_ANIMATING: 'is-animating',
+
+    ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',
+    ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'
+
+  };
+
+  /**
+   * Handles scrolling on the content.
+   *
+   * @private
+   */
+  MaterialLayout.prototype.contentScrollHandler_ = function() {
+    if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {
+      return;
+    }
+
+    var headerVisible =
+        !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) ||
+        this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);
+
+    if (this.content_.scrollTop > 0 &&
+        !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+      this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
+      this.header_.classList.add(this.CssClasses_.IS_COMPACT);
+      if (headerVisible) {
+        this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+      }
+    } else if (this.content_.scrollTop <= 0 &&
+        this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+      this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+      this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
+      if (headerVisible) {
+        this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+      }
+    }
+  };
+
+  /**
+   * Handles a keyboard event on the drawer.
+   *
+   * @param {Event} evt The event that fired.
+   * @private
+   */
+  MaterialLayout.prototype.keyboardEventHandler_ = function(evt) {
+    // Only react when the drawer is open.
+    if (evt.keyCode === this.Keycodes_.ESCAPE &&
+        this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
+      this.toggleDrawer();
+    }
+  };
+
+  /**
+   * Handles changes in screen size.
+   *
+   * @private
+   */
+  MaterialLayout.prototype.screenSizeHandler_ = function() {
+    if (this.screenSizeMediaQuery_.matches) {
+      this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
+    } else {
+      this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
+      // Collapse drawer (if any) when moving to a large screen size.
+      if (this.drawer_) {
+        this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
+        this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
+      }
+    }
+  };
+
+  /**
+   * Handles events of drawer button.
+   *
+   * @param {Event} evt The event that fired.
+   * @private
+   */
+  MaterialLayout.prototype.drawerToggleHandler_ = function(evt) {
+    if (evt && (evt.type === 'keydown')) {
+      if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
+        // prevent scrolling in drawer nav
+        evt.preventDefault();
+      } else {
+        // prevent other keys
+        return;
+      }
+    }
+
+    this.toggleDrawer();
+  };
+
+  /**
+   * Handles (un)setting the `is-animating` class
+   *
+   * @private
+   */
+  MaterialLayout.prototype.headerTransitionEndHandler_ = function() {
+    this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);
+  };
+
+  /**
+   * Handles expanding the header on click
+   *
+   * @private
+   */
+  MaterialLayout.prototype.headerClickHandler_ = function() {
+    if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+      this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
+      this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+    }
+  };
+
+  /**
+   * Reset tab state, dropping active classes
+   *
+   * @private
+   */
+  MaterialLayout.prototype.resetTabState_ = function(tabBar) {
+    for (var k = 0; k < tabBar.length; k++) {
+      tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);
+    }
+  };
+
+  /**
+   * Reset panel state, droping active classes
+   *
+   * @private
+   */
+  MaterialLayout.prototype.resetPanelState_ = function(panels) {
+    for (var j = 0; j < panels.length; j++) {
+      panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);
+    }
+  };
+
+  /**
+  * Toggle drawer state
+  *
+  * @public
+  */
+  MaterialLayout.prototype.toggleDrawer = function() {
+    var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
+    this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
+    this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
+
+    // Set accessibility properties.
+    if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
+      this.drawer_.setAttribute('aria-hidden', 'false');
+      drawerButton.setAttribute('aria-expanded', 'true');
+    } else {
+      this.drawer_.setAttribute('aria-hidden', 'true');
+      drawerButton.setAttribute('aria-expanded', 'false');
+    }
+  };
+  MaterialLayout.prototype['toggleDrawer'] =
+      MaterialLayout.prototype.toggleDrawer;
+
+  /**
+   * Initialize element.
+   */
+  MaterialLayout.prototype.init = function() {
+    if (this.element_) {
+      var container = document.createElement('div');
+      container.classList.add(this.CssClasses_.CONTAINER);
+
+      var focusedElement = this.element_.querySelector(':focus');
+
+      this.element_.parentElement.insertBefore(container, this.element_);
+      this.element_.parentElement.removeChild(this.element_);
+      container.appendChild(this.element_);
+
+      if (focusedElement) {
+        focusedElement.focus();
+      }
+
+      var directChildren = this.element_.childNodes;
+      var numChildren = directChildren.length;
+      for (var c = 0; c < numChildren; c++) {
+        var child = directChildren[c];
+        if (child.classList &&
+            child.classList.contains(this.CssClasses_.HEADER)) {
+          this.header_ = child;
+        }
+
+        if (child.classList &&
+            child.classList.contains(this.CssClasses_.DRAWER)) {
+          this.drawer_ = child;
+        }
+
+        if (child.classList &&
+            child.classList.contains(this.CssClasses_.CONTENT)) {
+          this.content_ = child;
+        }
+      }
+
+      window.addEventListener('pageshow', function(e) {
+        if (e.persisted) { // when page is loaded from back/forward cache
+          // trigger repaint to let layout scroll in safari
+          this.element_.style.overflowY = 'hidden';
+          requestAnimationFrame(function() {
+            this.element_.style.overflowY = '';
+          }.bind(this));
+        }
+      }.bind(this), false);
+
+      if (this.header_) {
+        this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);
+      }
+
+      var mode = this.Mode_.STANDARD;
+
+      if (this.header_) {
+        if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {
+          mode = this.Mode_.SEAMED;
+        } else if (this.header_.classList.contains(
+            this.CssClasses_.HEADER_WATERFALL)) {
+          mode = this.Mode_.WATERFALL;
+          this.header_.addEventListener('transitionend',
+            this.headerTransitionEndHandler_.bind(this));
+          this.header_.addEventListener('click',
+            this.headerClickHandler_.bind(this));
+        } else if (this.header_.classList.contains(
+            this.CssClasses_.HEADER_SCROLL)) {
+          mode = this.Mode_.SCROLL;
+          container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);
+        }
+
+        if (mode === this.Mode_.STANDARD) {
+          this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
+          if (this.tabBar_) {
+            this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);
+          }
+        } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {
+          this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+          if (this.tabBar_) {
+            this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+          }
+        } else if (mode === this.Mode_.WATERFALL) {
+          // Add and remove shadows depending on scroll position.
+          // Also add/remove auxiliary class for styling of the compact version of
+          // the header.
+          this.content_.addEventListener('scroll',
+              this.contentScrollHandler_.bind(this));
+          this.contentScrollHandler_();
+        }
+      }
+
+      // Add drawer toggling button to our layout, if we have an openable drawer.
+      if (this.drawer_) {
+        var drawerButton = this.element_.querySelector('.' +
+          this.CssClasses_.DRAWER_BTN);
+        if (!drawerButton) {
+          drawerButton = document.createElement('div');
+          drawerButton.setAttribute('aria-expanded', 'false');
+          drawerButton.setAttribute('role', 'button');
+          drawerButton.setAttribute('tabindex', '0');
+          drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);
+
+          var drawerButtonIcon = document.createElement('i');
+          drawerButtonIcon.classList.add(this.CssClasses_.ICON);
+          drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;
+          drawerButton.appendChild(drawerButtonIcon);
+        }
+
+        if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {
+          //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.
+          drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);
+        } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {
+          //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.
+          drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);
+        }
+
+        drawerButton.addEventListener('click',
+            this.drawerToggleHandler_.bind(this));
+
+        drawerButton.addEventListener('keydown',
+            this.drawerToggleHandler_.bind(this));
+
+        // Add a class if the layout has a drawer, for altering the left padding.
+        // Adds the HAS_DRAWER to the elements since this.header_ may or may
+        // not be present.
+        this.element_.classList.add(this.CssClasses_.HAS_DRAWER);
+
+        // If we have a fixed header, add the button to the header rather than
+        // the layout.
+        if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {
+          this.header_.insertBefore(drawerButton, this.header_.firstChild);
+        } else {
+          this.element_.insertBefore(drawerButton, this.content_);
+        }
+
+        var obfuscator = document.createElement('div');
+        obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);
+        this.element_.appendChild(obfuscator);
+        obfuscator.addEventListener('click',
+            this.drawerToggleHandler_.bind(this));
+        this.obfuscator_ = obfuscator;
+
+        this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));
+        this.drawer_.setAttribute('aria-hidden', 'true');
+      }
+
+      // Keep an eye on screen size, and add/remove auxiliary class for styling
+      // of small screens.
+      this.screenSizeMediaQuery_ = window.matchMedia(
+          /** @type {string} */ (this.Constant_.MAX_WIDTH));
+      this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
+      this.screenSizeHandler_();
+
+      // Initialize tabs, if any.
+      if (this.header_ && this.tabBar_) {
+        this.element_.classList.add(this.CssClasses_.HAS_TABS);
+
+        var tabContainer = document.createElement('div');
+        tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);
+        this.header_.insertBefore(tabContainer, this.tabBar_);
+        this.header_.removeChild(this.tabBar_);
+
+        var leftButton = document.createElement('div');
+        leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
+        leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);
+        var leftButtonIcon = document.createElement('i');
+        leftButtonIcon.classList.add(this.CssClasses_.ICON);
+        leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;
+        leftButton.appendChild(leftButtonIcon);
+        leftButton.addEventListener('click', function() {
+          this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;
+        }.bind(this));
+
+        var rightButton = document.createElement('div');
+        rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
+        rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);
+        var rightButtonIcon = document.createElement('i');
+        rightButtonIcon.classList.add(this.CssClasses_.ICON);
+        rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;
+        rightButton.appendChild(rightButtonIcon);
+        rightButton.addEventListener('click', function() {
+          this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;
+        }.bind(this));
+
+        tabContainer.appendChild(leftButton);
+        tabContainer.appendChild(this.tabBar_);
+        tabContainer.appendChild(rightButton);
+
+        // Add and remove tab buttons depending on scroll position and total
+        // window size.
+        var tabUpdateHandler = function() {
+          if (this.tabBar_.scrollLeft > 0) {
+            leftButton.classList.add(this.CssClasses_.IS_ACTIVE);
+          } else {
+            leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);
+          }
+
+          if (this.tabBar_.scrollLeft <
+              this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {
+            rightButton.classList.add(this.CssClasses_.IS_ACTIVE);
+          } else {
+            rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);
+          }
+        }.bind(this);
+
+        this.tabBar_.addEventListener('scroll', tabUpdateHandler);
+        tabUpdateHandler();
+
+        // Update tabs when the window resizes.
+        var windowResizeHandler = function() {
+          // Use timeouts to make sure it doesn't happen too often.
+          if (this.resizeTimeoutId_) {
+            clearTimeout(this.resizeTimeoutId_);
+          }
+          this.resizeTimeoutId_ = setTimeout(function() {
+            tabUpdateHandler();
+            this.resizeTimeoutId_ = null;
+          }.bind(this), /** @type {number} */ (this.Constant_.RESIZE_TIMEOUT));
+        }.bind(this);
+
+        window.addEventListener('resize', windowResizeHandler);
+
+        if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
+          this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+        }
+
+        // Select element tabs, document panels
+        var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);
+        var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);
+
+        // Create new tabs for each tab element
+        for (var i = 0; i < tabs.length; i++) {
+          new MaterialLayoutTab(tabs[i], tabs, panels, this);
+        }
+      }
+
+      this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+    }
+  };
+
+  /**
+   * Constructor for an individual tab.
+   *
+   * @constructor
+   * @param {HTMLElement} tab The HTML element for the tab.
+   * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.
+   * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.
+   * @param {MaterialLayout} layout The MaterialLayout object that owns the tab.
+   */
+  function MaterialLayoutTab(tab, tabs, panels, layout) {
+
+    /**
+     * Auxiliary method to programmatically select a tab in the UI.
+     */
+    function selectTab() {
+      var href = tab.href.split('#')[1];
+      var panel = layout.content_.querySelector('#' + href);
+      layout.resetTabState_(tabs);
+      layout.resetPanelState_(panels);
+      tab.classList.add(layout.CssClasses_.IS_ACTIVE);
+      panel.classList.add(layout.CssClasses_.IS_ACTIVE);
+    }
+
+    if (layout.tabBar_.classList.contains(
+        layout.CssClasses_.JS_RIPPLE_EFFECT)) {
+      var rippleContainer = document.createElement('span');
+      rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);
+      rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);
+      var ripple = document.createElement('span');
+      ripple.classList.add(layout.CssClasses_.RIPPLE);
+      rippleContainer.appendChild(ripple);
+      tab.appendChild(rippleContainer);
+    }
+
+    if (!layout.tabBar_.classList.contains(
+      layout.CssClasses_.TAB_MANUAL_SWITCH)) {
+      tab.addEventListener('click', function(e) {
+        if (tab.getAttribute('href').charAt(0) === '#') {
+          e.preventDefault();
+          selectTab();
+        }
+      });
+    }
+
+    tab.show = selectTab;
+  }
+  window['MaterialLayoutTab'] = MaterialLayoutTab;
+
+  // The component registers itself. It can assume componentHandler is available
+  // in the global scope.
+  componentHandler.register({
+    constructor: MaterialLayout,
+    classAsString: 'MaterialLayout',
+    cssClass: 'mdl-js-layout'
+  });
+})();