text: /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/a11y'), require('@angular/cdk/bidi'), require('@angular/common'), require('@angular/core'), require('@angular/platform-browser'), require('@angular/cdk/coercion'), require('rxjs/Subject'), require('@angular/cdk/scrolling'), require('@angular/cdk/platform'), require('@angular/cdk/keycodes'), require('@angular/forms'), require('rxjs/Subscription')) :
  	typeof define === 'function' && define.amd ? define(['exports', '@angular/cdk/a11y', '@angular/cdk/bidi', '@angular/common', '@angular/core', '@angular/platform-browser', '@angular/cdk/coercion', 'rxjs/Subject', '@angular/cdk/scrolling', '@angular/cdk/platform', '@angular/cdk/keycodes', '@angular/forms', 'rxjs/Subscription'], factory) :
  	(factory((global.ng = global.ng || {}, global.ng.material = global.ng.material || {}, global.ng.material.slider = global.ng.material.slider || {}),global.ng.cdk.a11y,global.ng.cdk.bidi,global.ng.common,global.ng.core,global.ng.platformBrowser,global.ng.cdk.coercion,global.Rx,global.ng.cdk.scrolling,global.ng.cdk.platform,global.ng.cdk.keycodes,global.ng.forms,global.Rx));
  }(this, (function (exports,_angular_cdk_a11y,_angular_cdk_bidi,_angular_common,_angular_core,_angular_platformBrowser,_angular_cdk_coercion,rxjs_Subject,_angular_cdk_scrolling,_angular_cdk_platform,_angular_cdk_keycodes,_angular_forms,rxjs_Subscription) { 'use strict';
  
  /*! *****************************************************************************
  Copyright (c) Microsoft Corporation. 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
  
  THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  MERCHANTABLITY OR NON-INFRINGEMENT.
  
  See the Apache Version 2.0 License for specific language governing permissions
  and limitations under the License.
  ***************************************************************************** */
  /* global Reflect, Promise */
  
  var extendStatics = Object.setPrototypeOf ||
      ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
      function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  
  function __extends(d, b) {
      extendStatics(d, b);
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  }
  
  /**
   * \@docs-private
   */
  var AnimationCurves = (function () {
      function AnimationCurves() {
      }
      return AnimationCurves;
  }());
  AnimationCurves.STANDARD_CURVE = 'cubic-bezier(0.4,0.0,0.2,1)';
  AnimationCurves.DECELERATION_CURVE = 'cubic-bezier(0.0,0.0,0.2,1)';
  AnimationCurves.ACCELERATION_CURVE = 'cubic-bezier(0.4,0.0,1,1)';
  AnimationCurves.SHARP_CURVE = 'cubic-bezier(0.4,0.0,0.6,1)';
  /**
   * \@docs-private
   */
  var AnimationDurations = (function () {
      function AnimationDurations() {
      }
      return AnimationDurations;
  }());
  AnimationDurations.COMPLEX = '375ms';
  AnimationDurations.ENTERING = '225ms';
  AnimationDurations.EXITING = '195ms';
  var MATERIAL_COMPATIBILITY_MODE = new _angular_core.InjectionToken('md-compatibility-mode');
  /**
   * Returns an exception to be thrown if the consumer has used
  an invalid Material prefix on a component.
  \@docs-private
   * @param {?} prefix
   * @param {?} nodeName
   * @return {?}
   */
  function getMdCompatibilityInvalidPrefixError(prefix, nodeName) {
      return Error("The \"" + prefix + "-\" prefix cannot be used in ng-material v1 compatibility mode. " +
          ("It was used on an \"" + nodeName.toLowerCase() + "\" element."));
  }
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  var MAT_ELEMENTS_SELECTOR = "\n  [mat-button],\n  [mat-fab],\n  [mat-icon-button],\n  [mat-mini-fab],\n  [mat-raised-button],\n  [matCardSubtitle],\n  [matCardTitle],\n  [matCellDef],\n  [matColumnDef],\n  [matDialogActions],\n  [matDialogClose],\n  [matDialogContent],\n  [matDialogTitle],\n  [matHeaderCellDef],\n  [matHeaderRowDef],\n  [matLine],\n  [matRowDef],\n  [matStepLabel],\n  [matStepperNext],\n  [matStepperPrevious],\n  [matTabLabel],\n  [matTabLink],\n  [matTabNav],\n  [matTooltip],\n  [matInput],\n  [matPrefix],\n  [matSuffix],\n  mat-autocomplete,\n  mat-button-toggle,\n  mat-button-toggle,\n  mat-button-toggle-group,\n  mat-card,\n  mat-card-actions,\n  mat-card-content,\n  mat-card-footer,\n  mat-card-header,\n  mat-card-subtitle,\n  mat-card-title,\n  mat-card-title-group,\n  mat-cell,\n  mat-checkbox,\n  mat-chip,\n  mat-dialog-actions,\n  mat-dialog-container,\n  mat-dialog-content,\n  mat-divider,\n  mat-error,\n  mat-grid-list,\n  mat-grid-tile,\n  mat-grid-tile-footer,\n  mat-grid-tile-header,\n  mat-header-cell,\n  mat-header-row,\n  mat-hint,\n  mat-horizontal-stepper,\n  mat-icon,\n  mat-input-container,\n  mat-form-field,\n  mat-list,\n  mat-list-item,\n  mat-menu,\n  mat-nav-list,\n  mat-option,\n  mat-placeholder,\n  mat-progress-bar,\n  mat-pseudo-checkbox,\n  mat-radio-button,\n  mat-radio-group,\n  mat-row,\n  mat-select,\n  mat-sidenav,\n  mat-sidenav-container,\n  mat-slider,\n  mat-spinner,\n  mat-step,\n  mat-tab,\n  mat-table,\n  mat-tab-group,\n  mat-toolbar,\n  mat-vertical-stepper";
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  var MD_ELEMENTS_SELECTOR = "\n  [md-button],\n  [md-fab],\n  [md-icon-button],\n  [md-mini-fab],\n  [md-raised-button],\n  [mdCardSubtitle],\n  [mdCardTitle],\n  [mdCellDef],\n  [mdColumnDef],\n  [mdDialogActions],\n  [mdDialogClose],\n  [mdDialogContent],\n  [mdDialogTitle],\n  [mdHeaderCellDef],\n  [mdHeaderRowDef],\n  [mdLine],\n  [mdRowDef],\n  [mdStepLabel],\n  [mdStepperNext],\n  [mdStepperPrevious],\n  [mdTabLabel],\n  [mdTabLink],\n  [mdTabNav],\n  [mdTooltip],\n  [mdInput],\n  [mdPrefix],\n  [mdSuffix],\n  md-autocomplete,\n  md-button-toggle,\n  md-button-toggle,\n  md-button-toggle-group,\n  md-card,\n  md-card-actions,\n  md-card-content,\n  md-card-footer,\n  md-card-header,\n  md-card-subtitle,\n  md-card-title,\n  md-card-title-group,\n  md-cell,\n  md-checkbox,\n  md-chip,\n  md-dialog-actions,\n  md-dialog-container,\n  md-dialog-content,\n  md-divider,\n  md-error,\n  md-grid-list,\n  md-grid-tile,\n  md-grid-tile-footer,\n  md-grid-tile-header,\n  md-header-cell,\n  md-header-row,\n  md-hint,\n  md-horizontal-stepper,\n  md-icon,\n  md-input-container,\n  md-form-field,\n  md-list,\n  md-list-item,\n  md-menu,\n  md-nav-list,\n  md-option,\n  md-placeholder,\n  md-progress-bar,\n  md-pseudo-checkbox,\n  md-radio-button,\n  md-radio-group,\n  md-row,\n  md-select,\n  md-sidenav,\n  md-sidenav-container,\n  md-slider,\n  md-spinner,\n  md-step,\n  md-tab,\n  md-table,\n  md-tab-group,\n  md-toolbar,\n  md-vertical-stepper";
  /**
   * Directive that enforces that the `mat-` prefix cannot be used.
   */
  var MatPrefixRejector = (function () {
      /**
       * @param {?} isCompatibilityMode
       * @param {?} elementRef
       */
      function MatPrefixRejector(isCompatibilityMode, elementRef) {
          if (!isCompatibilityMode) {
              throw getMdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName);
          }
      }
      return MatPrefixRejector;
  }());
  MatPrefixRejector.decorators = [
      { type: _angular_core.Directive, args: [{ selector: MAT_ELEMENTS_SELECTOR },] },
  ];
  /**
   * @nocollapse
   */
  MatPrefixRejector.ctorParameters = function () { return [
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MATERIAL_COMPATIBILITY_MODE,] },] },
      { type: _angular_core.ElementRef, },
  ]; };
  /**
   * Directive that enforces that the `md-` prefix cannot be used.
   */
  var MdPrefixRejector = (function () {
      /**
       * @param {?} isCompatibilityMode
       * @param {?} elementRef
       */
      function MdPrefixRejector(isCompatibilityMode, elementRef) {
          if (isCompatibilityMode) {
              throw getMdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName);
          }
      }
      return MdPrefixRejector;
  }());
  MdPrefixRejector.decorators = [
      { type: _angular_core.Directive, args: [{ selector: MD_ELEMENTS_SELECTOR },] },
  ];
  /**
   * @nocollapse
   */
  MdPrefixRejector.ctorParameters = function () { return [
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MATERIAL_COMPATIBILITY_MODE,] },] },
      { type: _angular_core.ElementRef, },
  ]; };
  /**
   * Module that enforces the default compatibility mode settings. When this module is loaded
  without NoConflictStyleCompatibilityMode also being imported, it will throw an error if
  there are any uses of the `mat-` prefix.
   */
  var CompatibilityModule = (function () {
      function CompatibilityModule() {
      }
      return CompatibilityModule;
  }());
  CompatibilityModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  declarations: [MatPrefixRejector, MdPrefixRejector],
                  exports: [MatPrefixRejector, MdPrefixRejector],
              },] },
  ];
  /**
   * @nocollapse
   */
  CompatibilityModule.ctorParameters = function () { return []; };
  /**
   * Module that enforces "no-conflict" compatibility mode settings. When this module is loaded,
  it will throw an error if there are any uses of the `md-` prefix.
   */
  var NoConflictStyleCompatibilityMode = (function () {
      function NoConflictStyleCompatibilityMode() {
      }
      return NoConflictStyleCompatibilityMode;
  }());
  NoConflictStyleCompatibilityMode.decorators = [
      { type: _angular_core.NgModule, args: [{
                  providers: [{
                          provide: MATERIAL_COMPATIBILITY_MODE, useValue: true,
                      }],
              },] },
  ];
  /**
   * @nocollapse
   */
  NoConflictStyleCompatibilityMode.ctorParameters = function () { return []; };
  /**
   * Injection token that configures whether the Material sanity checks are enabled.
   */
  var MATERIAL_SANITY_CHECKS = new _angular_core.InjectionToken('md-sanity-checks');
  /**
   * Module that captures anything that should be loaded and/or run for *all* Angular Material
  components. This includes Bidi, compatibility mode, etc.
  
  This module should be imported to each top-level component module (e.g., MdTabsModule).
   */
  var MdCommonModule = (function () {
      /**
       * @param {?} _document
       * @param {?} _sanityChecksEnabled
       */
      function MdCommonModule(_document, _sanityChecksEnabled) {
          this._document = _document;
          /**
           * Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype).
           */
          this._hasDoneGlobalChecks = false;
          if (_sanityChecksEnabled && !this._hasDoneGlobalChecks && _document && _angular_core.isDevMode()) {
              this._checkDoctype();
              this._checkTheme();
              this._hasDoneGlobalChecks = true;
          }
      }
      /**
       * @return {?}
       */
      MdCommonModule.prototype._checkDoctype = function () {
          if (!this._document.doctype) {
              console.warn('Current document does not have a doctype. This may cause ' +
                  'some Angular Material components not to behave as expected.');
          }
      };
      /**
       * @return {?}
       */
      MdCommonModule.prototype._checkTheme = function () {
          if (typeof getComputedStyle === 'function') {
              var /** @type {?} */ testElement = this._document.createElement('div');
              testElement.classList.add('mat-theme-loaded-marker');
              this._document.body.appendChild(testElement);
              if (getComputedStyle(testElement).display !== 'none') {
                  console.warn('Could not find Angular Material core theme. Most Material ' +
                      'components may not work as expected. For more info refer ' +
                      'to the theming guide: https://material.angular.io/guide/theming');
              }
              this._document.body.removeChild(testElement);
          }
      };
      return MdCommonModule;
  }());
  MdCommonModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [CompatibilityModule, _angular_cdk_bidi.BidiModule],
                  exports: [CompatibilityModule, _angular_cdk_bidi.BidiModule],
                  providers: [{
                          provide: MATERIAL_SANITY_CHECKS, useValue: true,
                      }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdCommonModule.ctorParameters = function () { return [
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_platformBrowser.DOCUMENT,] },] },
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MATERIAL_SANITY_CHECKS,] },] },
  ]; };
  /**
   * Mixin to augment a directive with a `disabled` property.
   * @template T
   * @param {?} base
   * @return {?}
   */
  function mixinDisabled(base) {
      return (function (_super) {
          __extends(class_1, _super);
          /**
           * @param {...?} args
           */
          function class_1() {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var _this = _super.apply(this, args) || this;
              _this._disabled = false;
              return _this;
          }
          Object.defineProperty(class_1.prototype, "disabled", {
              /**
               * @return {?}
               */
              get: function () { return this._disabled; },
              /**
               * @param {?} value
               * @return {?}
               */
              set: function (value) { this._disabled = _angular_cdk_coercion.coerceBooleanProperty(value); },
              enumerable: true,
              configurable: true
          });
          return class_1;
      }(base));
  }
  /**
   * Mixin to augment a directive with a `color` property.
   * @template T
   * @param {?} base
   * @param {?=} defaultColor
   * @return {?}
   */
  function mixinColor(base, defaultColor) {
      return (function (_super) {
          __extends(class_2, _super);
          /**
           * @param {...?} args
           */
          function class_2() {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var _this = _super.apply(this, args) || this;
              // Set the default color that can be specified from the mixin.
              _this.color = defaultColor;
              return _this;
          }
          Object.defineProperty(class_2.prototype, "color", {
              /**
               * @return {?}
               */
              get: function () { return this._color; },
              /**
               * @param {?} value
               * @return {?}
               */
              set: function (value) {
                  var /** @type {?} */ colorPalette = value || defaultColor;
                  if (colorPalette !== this._color) {
                      if (this._color) {
                          this._renderer.removeClass(this._elementRef.nativeElement, "mat-" + this._color);
                      }
                      if (colorPalette) {
                          this._renderer.addClass(this._elementRef.nativeElement, "mat-" + colorPalette);
                      }
                      this._color = colorPalette;
                  }
              },
              enumerable: true,
              configurable: true
          });
          return class_2;
      }(base));
  }
  /**
   * Class to coordinate unique selection based on name.
  Intended to be consumed as an Angular service.
  This service is needed because native radio change events are only fired on the item currently
  being selected, and we still need to uncheck the previous selection.
  
  This service does not *store* any IDs and names because they may change at any time, so it is
  less error-prone if they are simply passed through when the events occur.
   */
  var UniqueSelectionDispatcher = (function () {
      function UniqueSelectionDispatcher() {
          this._listeners = [];
      }
      /**
       * Notify other items that selection for the given name has been set.
      \@param id ID of the item.
      \@param name Name of the item.
       * @param {?} id
       * @param {?} name
       * @return {?}
       */
      UniqueSelectionDispatcher.prototype.notify = function (id, name) {
          for (var _i = 0, _a = this._listeners; _i < _a.length; _i++) {
              var listener = _a[_i];
              listener(id, name);
          }
      };
      /**
       * Listen for future changes to item selection.
      \@return Function used to deregister listener
       * @param {?} listener
       * @return {?}
       */
      UniqueSelectionDispatcher.prototype.listen = function (listener) {
          var _this = this;
          this._listeners.push(listener);
          return function () {
              _this._listeners = _this._listeners.filter(function (registered) {
                  return listener !== registered;
              });
          };
      };
      return UniqueSelectionDispatcher;
  }());
  UniqueSelectionDispatcher.decorators = [
      { type: _angular_core.Injectable },
  ];
  /**
   * @nocollapse
   */
  UniqueSelectionDispatcher.ctorParameters = function () { return []; };
  /**
   * \@docs-private
   * @param {?} parentDispatcher
   * @return {?}
   */
  function UNIQUE_SELECTION_DISPATCHER_PROVIDER_FACTORY(parentDispatcher) {
      return parentDispatcher || new UniqueSelectionDispatcher();
  }
  /**
   * \@docs-private
   */
  var UNIQUE_SELECTION_DISPATCHER_PROVIDER = {
      // If there is already a dispatcher available, use that. Otherwise, provide a new one.
      provide: UniqueSelectionDispatcher,
      deps: [[new _angular_core.Optional(), new _angular_core.SkipSelf(), UniqueSelectionDispatcher]],
      useFactory: UNIQUE_SELECTION_DISPATCHER_PROVIDER_FACTORY
  };
  /**
   * InjectionToken for datepicker that can be used to override default locale code.
   */
  var MAT_DATE_LOCALE = new _angular_core.InjectionToken('MAT_DATE_LOCALE');
  /**
   * Provider for MAT_DATE_LOCALE injection token.
   */
  var MAT_DATE_LOCALE_PROVIDER = { provide: MAT_DATE_LOCALE, useExisting: _angular_core.LOCALE_ID };
  /**
   * Adapts type `D` to be usable as a date by cdk-based components that work with dates.
   * @abstract
   */
  var DateAdapter = (function () {
      function DateAdapter() {
          this._localeChanges = new rxjs_Subject.Subject();
      }
      Object.defineProperty(DateAdapter.prototype, "localeChanges", {
          /**
           * A stream that emits when the locale changes.
           * @return {?}
           */
          get: function () { return this._localeChanges; },
          enumerable: true,
          configurable: true
      });
      /**
       * Gets the year component of the given date.
      \@param date The date to extract the year from.
      \@returns The year component.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getYear = function (date) { };
      /**
       * Gets the month component of the given date.
      \@param date The date to extract the month from.
      \@returns The month component (0-indexed, 0 = January).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getMonth = function (date) { };
      /**
       * Gets the date of the month component of the given date.
      \@param date The date to extract the date of the month from.
      \@returns The month component (1-indexed, 1 = first of month).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getDate = function (date) { };
      /**
       * Gets the day of the week component of the given date.
      \@param date The date to extract the day of the week from.
      \@returns The month component (0-indexed, 0 = Sunday).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getDayOfWeek = function (date) { };
      /**
       * Gets a list of names for the months.
      \@param style The naming style (e.g. long = 'January', short = 'Jan', narrow = 'J').
      \@returns An ordered list of all month names, starting with January.
       * @abstract
       * @param {?} style
       * @return {?}
       */
      DateAdapter.prototype.getMonthNames = function (style) { };
      /**
       * Gets a list of names for the dates of the month.
      \@returns An ordered list of all date of the month names, starting with '1'.
       * @abstract
       * @return {?}
       */
      DateAdapter.prototype.getDateNames = function () { };
      /**
       * Gets a list of names for the days of the week.
      \@param style The naming style (e.g. long = 'Sunday', short = 'Sun', narrow = 'S').
      \@returns An ordered list of all weekday names, starting with Sunday.
       * @abstract
       * @param {?} style
       * @return {?}
       */
      DateAdapter.prototype.getDayOfWeekNames = function (style) { };
      /**
       * Gets the name for the year of the given date.
      \@param date The date to get the year name for.
      \@returns The name of the given year (e.g. '2017').
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getYearName = function (date) { };
      /**
       * Gets the first day of the week.
      \@returns The first day of the week (0-indexed, 0 = Sunday).
       * @abstract
       * @return {?}
       */
      DateAdapter.prototype.getFirstDayOfWeek = function () { };
      /**
       * Gets the number of days in the month of the given date.
      \@param date The date whose month should be checked.
      \@returns The number of days in the month of the given date.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.getNumDaysInMonth = function (date) { };
      /**
       * Clones the given date.
      \@param date The date to clone
      \@returns A new date equal to the given date.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.clone = function (date) { };
      /**
       * Creates a date with the given year, month, and date. Does not allow over/under-flow of the
      month and date.
      \@param year The full year of the date. (e.g. 89 means the year 89, not the year 1989).
      \@param month The month of the date (0-indexed, 0 = January). Must be an integer 0 - 11.
      \@param date The date of month of the date. Must be an integer 1 - length of the given month.
      \@returns The new date, or null if invalid.
       * @abstract
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.createDate = function (year, month, date) { };
      /**
       * Gets today's date.
      \@returns Today's date.
       * @abstract
       * @return {?}
       */
      DateAdapter.prototype.today = function () { };
      /**
       * Parses a date from a value.
      \@param value The value to parse.
      \@param parseFormat The expected format of the value being parsed
          (type is implementation-dependent).
      \@returns The parsed date.
       * @abstract
       * @param {?} value
       * @param {?} parseFormat
       * @return {?}
       */
      DateAdapter.prototype.parse = function (value, parseFormat) { };
      /**
       * Formats a date as a string.
      \@param date The value to format.
      \@param displayFormat The format to use to display the date as a string.
      \@returns The formatted date string.
       * @abstract
       * @param {?} date
       * @param {?} displayFormat
       * @return {?}
       */
      DateAdapter.prototype.format = function (date, displayFormat) { };
      /**
       * Adds the given number of years to the date. Years are counted as if flipping 12 pages on the
      calendar for each year and then finding the closest date in the new month. For example when
      adding 1 year to Feb 29, 2016, the resulting date will be Feb 28, 2017.
      \@param date The date to add years to.
      \@param years The number of years to add (may be negative).
      \@returns A new date equal to the given one with the specified number of years added.
       * @abstract
       * @param {?} date
       * @param {?} years
       * @return {?}
       */
      DateAdapter.prototype.addCalendarYears = function (date, years) { };
      /**
       * Adds the given number of months to the date. Months are counted as if flipping a page on the
      calendar for each month and then finding the closest date in the new month. For example when
      adding 1 month to Jan 31, 2017, the resulting date will be Feb 28, 2017.
      \@param date The date to add months to.
      \@param months The number of months to add (may be negative).
      \@returns A new date equal to the given one with the specified number of months added.
       * @abstract
       * @param {?} date
       * @param {?} months
       * @return {?}
       */
      DateAdapter.prototype.addCalendarMonths = function (date, months) { };
      /**
       * Adds the given number of days to the date. Days are counted as if moving one cell on the
      calendar for each day.
      \@param date The date to add days to.
      \@param days The number of days to add (may be negative).
      \@returns A new date equal to the given one with the specified number of days added.
       * @abstract
       * @param {?} date
       * @param {?} days
       * @return {?}
       */
      DateAdapter.prototype.addCalendarDays = function (date, days) { };
      /**
       * Gets the RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339) for the given date.
      \@param date The date to get the ISO date string for.
      \@returns The ISO date string date string.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.toIso8601 = function (date) { };
      /**
       * Creates a date from an RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339).
      \@param iso8601String The ISO date string to create a date from
      \@returns The date created from the ISO date string.
       * @abstract
       * @param {?} iso8601String
       * @return {?}
       */
      DateAdapter.prototype.fromIso8601 = function (iso8601String) { };
      /**
       * Checks whether the given object is considered a date instance by this DateAdapter.
      \@param obj The object to check
      \@returns Whether the object is a date instance.
       * @abstract
       * @param {?} obj
       * @return {?}
       */
      DateAdapter.prototype.isDateInstance = function (obj) { };
      /**
       * Checks whether the given date is valid.
      \@param date The date to check.
      \@returns Whether the date is valid.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      DateAdapter.prototype.isValid = function (date) { };
      /**
       * Sets the locale used for all dates.
      \@param locale The new locale.
       * @param {?} locale
       * @return {?}
       */
      DateAdapter.prototype.setLocale = function (locale) {
          this.locale = locale;
          this._localeChanges.next();
      };
      /**
       * Compares two dates.
      \@param first The first date to compare.
      \@param second The second date to compare.
      \@returns 0 if the dates are equal, a number less than 0 if the first date is earlier,
          a number greater than 0 if the first date is later.
       * @param {?} first
       * @param {?} second
       * @return {?}
       */
      DateAdapter.prototype.compareDate = function (first, second) {
          return this.getYear(first) - this.getYear(second) ||
              this.getMonth(first) - this.getMonth(second) ||
              this.getDate(first) - this.getDate(second);
      };
      /**
       * Checks if two dates are equal.
      \@param first The first date to check.
      \@param second The second date to check.
      \@returns {boolean} Whether the two dates are equal.
          Null dates are considered equal to other null dates.
       * @param {?} first
       * @param {?} second
       * @return {?}
       */
      DateAdapter.prototype.sameDate = function (first, second) {
          return first && second ? !this.compareDate(first, second) : first == second;
      };
      /**
       * Clamp the given date between min and max dates.
      \@param date The date to clamp.
      \@param min The minimum value to allow. If null or omitted no min is enforced.
      \@param max The maximum value to allow. If null or omitted no max is enforced.
      \@returns `min` if `date` is less than `min`, `max` if date is greater than `max`,
          otherwise `date`.
       * @param {?} date
       * @param {?=} min
       * @param {?=} max
       * @return {?}
       */
      DateAdapter.prototype.clampDate = function (date, min, max) {
          if (min && this.compareDate(date, min) < 0) {
              return min;
          }
          if (max && this.compareDate(date, max) > 0) {
              return max;
          }
          return date;
      };
      return DateAdapter;
  }());
  /**
   * Extends an object with the *enumerable* and *own* properties of one or more source objects,
  similar to Object.assign.
  
  \@param dest The object which will have properties copied to it.
  \@param sources The source objects from which properties will be copied.
   * @param {?} dest
   * @param {...?} sources
   * @return {?}
   */
  function extendObject(dest) {
      var sources = [];
      for (var _i = 1; _i < arguments.length; _i++) {
          sources[_i - 1] = arguments[_i];
      }
      if (dest == null) {
          throw TypeError('Cannot convert undefined or null to object');
      }
      for (var _a = 0, sources_1 = sources; _a < sources_1.length; _a++) {
          var source = sources_1[_a];
          if (source != null) {
              for (var /** @type {?} */ key in source) {
                  if (source.hasOwnProperty(key)) {
                      dest[key] = source[key];
                  }
              }
          }
      }
      return dest;
  }
  /**
   * Whether the browser supports the Intl API.
   */
  var SUPPORTS_INTL_API = typeof Intl != 'undefined';
  /**
   * The default month names to use if Intl API is not available.
   */
  var DEFAULT_MONTH_NAMES = {
      'long': [
          'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September',
          'October', 'November', 'December'
      ],
      'short': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      'narrow': ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D']
  };
  /**
   * The default date names to use if Intl API is not available.
   */
  var DEFAULT_DATE_NAMES = range(31, function (i) { return String(i + 1); });
  /**
   * The default day of the week names to use if Intl API is not available.
   */
  var DEFAULT_DAY_OF_WEEK_NAMES = {
      'long': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
      'short': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
      'narrow': ['S', 'M', 'T', 'W', 'T', 'F', 'S']
  };
  /**
   * Matches strings that have the form of a valid RFC 3339 string
  (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date
  because the regex will match strings an with out of bounds month, date, etc.
   */
  var ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
  /**
   * Creates an array and fills it with values.
   * @template T
   * @param {?} length
   * @param {?} valueFunction
   * @return {?}
   */
  function range(length, valueFunction) {
      var /** @type {?} */ valuesArray = Array(length);
      for (var /** @type {?} */ i = 0; i < length; i++) {
          valuesArray[i] = valueFunction(i);
      }
      return valuesArray;
  }
  /**
   * Adapts the native JS Date for use with cdk-based components that work with dates.
   */
  var NativeDateAdapter = (function (_super) {
      __extends(NativeDateAdapter, _super);
      /**
       * @param {?} matDateLocale
       */
      function NativeDateAdapter(matDateLocale) {
          var _this = _super.call(this) || this;
          /**
           * Whether to use `timeZone: 'utc'` with `Intl.DateTimeFormat` when formatting dates.
          Without this `Intl.DateTimeFormat` sometimes chooses the wrong timeZone, which can throw off
          the result. (e.g. in the en-US locale `new Date(1800, 7, 14).toLocaleDateString()`
          will produce `'8/13/1800'`.
           */
          _this.useUtcForDisplay = true;
          _super.prototype.setLocale.call(_this, matDateLocale);
          return _this;
      }
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getYear = function (date) {
          return date.getFullYear();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getMonth = function (date) {
          return date.getMonth();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getDate = function (date) {
          return date.getDate();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getDayOfWeek = function (date) {
          return date.getDay();
      };
      /**
       * @param {?} style
       * @return {?}
       */
      NativeDateAdapter.prototype.getMonthNames = function (style) {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_1 = new Intl.DateTimeFormat(this.locale, { month: style });
              return range(12, function (i) { return _this._stripDirectionalityCharacters(dtf_1.format(new Date(2017, i, 1))); });
          }
          return DEFAULT_MONTH_NAMES[style];
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.getDateNames = function () {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_2 = new Intl.DateTimeFormat(this.locale, { day: 'numeric' });
              return range(31, function (i) { return _this._stripDirectionalityCharacters(dtf_2.format(new Date(2017, 0, i + 1))); });
          }
          return DEFAULT_DATE_NAMES;
      };
      /**
       * @param {?} style
       * @return {?}
       */
      NativeDateAdapter.prototype.getDayOfWeekNames = function (style) {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_3 = new Intl.DateTimeFormat(this.locale, { weekday: style });
              return range(7, function (i) { return _this._stripDirectionalityCharacters(dtf_3.format(new Date(2017, 0, i + 1))); });
          }
          return DEFAULT_DAY_OF_WEEK_NAMES[style];
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getYearName = function (date) {
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { year: 'numeric' });
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return String(this.getYear(date));
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.getFirstDayOfWeek = function () {
          // We can't tell using native JS Date what the first day of the week is, we default to Sunday.
          return 0;
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getNumDaysInMonth = function (date) {
          return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.clone = function (date) {
          return this.createDate(this.getYear(date), this.getMonth(date), this.getDate(date));
      };
      /**
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.createDate = function (year, month, date) {
          // Check for invalid month and date (except upper bound on date which we have to check after
          // creating the Date).
          if (month < 0 || month > 11) {
              throw Error("Invalid month index \"" + month + "\". Month index has to be between 0 and 11.");
          }
          if (date < 1) {
              throw Error("Invalid date \"" + date + "\". Date has to be greater than 0.");
          }
          var /** @type {?} */ result = this._createDateWithOverflow(year, month, date);
          // Check that the date wasn't above the upper bound for the month, causing the month to overflow
          if (result.getMonth() != month) {
              throw Error("Invalid date \"" + date + "\" for month with index \"" + month + "\".");
          }
          return result;
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.today = function () {
          return new Date();
      };
      /**
       * @param {?} value
       * @return {?}
       */
      NativeDateAdapter.prototype.parse = function (value) {
          // We have no way using the native JS Date to set the parse format or locale, so we ignore these
          // parameters.
          if (typeof value == 'number') {
              return new Date(value);
          }
          return value ? new Date(Date.parse(value)) : null;
      };
      /**
       * @param {?} date
       * @param {?} displayFormat
       * @return {?}
       */
      NativeDateAdapter.prototype.format = function (date, displayFormat) {
          if (!this.isValid(date)) {
              throw Error('NativeDateAdapter: Cannot format invalid date.');
          }
          if (SUPPORTS_INTL_API) {
              if (this.useUtcForDisplay) {
                  date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
                  displayFormat = extendObject({}, displayFormat, { timeZone: 'utc' });
              }
              var /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, displayFormat);
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return this._stripDirectionalityCharacters(date.toDateString());
      };
      /**
       * @param {?} date
       * @param {?} years
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarYears = function (date, years) {
          return this.addCalendarMonths(date, years * 12);
      };
      /**
       * @param {?} date
       * @param {?} months
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarMonths = function (date, months) {
          var /** @type {?} */ newDate = this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + months, this.getDate(date));
          // It's possible to wind up in the wrong month if the original month has more days than the new
          // month. In this case we want to go to the last day of the desired month.
          // Note: the additional + 12 % 12 ensures we end up with a positive number, since JS % doesn't
          // guarantee this.
          if (this.getMonth(newDate) != ((this.getMonth(date) + months) % 12 + 12) % 12) {
              newDate = this._createDateWithOverflow(this.getYear(newDate), this.getMonth(newDate), 0);
          }
          return newDate;
      };
      /**
       * @param {?} date
       * @param {?} days
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarDays = function (date, days) {
          return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.toIso8601 = function (date) {
          return [
              date.getUTCFullYear(),
              this._2digit(date.getUTCMonth() + 1),
              this._2digit(date.getUTCDate())
          ].join('-');
      };
      /**
       * @param {?} iso8601String
       * @return {?}
       */
      NativeDateAdapter.prototype.fromIso8601 = function (iso8601String) {
          // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the
          // string is the right format first.
          if (ISO_8601_REGEX.test(iso8601String)) {
              var /** @type {?} */ d = new Date(iso8601String);
              if (this.isValid(d)) {
                  return d;
              }
          }
          return null;
      };
      /**
       * @param {?} obj
       * @return {?}
       */
      NativeDateAdapter.prototype.isDateInstance = function (obj) {
          return obj instanceof Date;
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.isValid = function (date) {
          return !isNaN(date.getTime());
      };
      /**
       * Creates a date but allows the month and date to overflow.
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype._createDateWithOverflow = function (year, month, date) {
          var /** @type {?} */ result = new Date(year, month, date);
          // We need to correct for the fact that JS native Date treats years in range [0, 99] as
          // abbreviations for 19xx.
          if (year >= 0 && year < 100) {
              result.setFullYear(this.getYear(result) - 1900);
          }
          return result;
      };
      /**
       * Pads a number to make it two digits.
      \@param n The number to pad.
      \@returns The padded number.
       * @param {?} n
       * @return {?}
       */
      NativeDateAdapter.prototype._2digit = function (n) {
          return ('00' + n).slice(-2);
      };
      /**
       * Strip out unicode LTR and RTL characters. Edge and IE insert these into formatted dates while
      other browsers do not. We remove them to make output consistent and because they interfere with
      date parsing.
      \@param str The string to strip direction characters from.
      \@returns The stripped string.
       * @param {?} str
       * @return {?}
       */
      NativeDateAdapter.prototype._stripDirectionalityCharacters = function (str) {
          return str.replace(/[\u200e\u200f]/g, '');
      };
      return NativeDateAdapter;
  }(DateAdapter));
  NativeDateAdapter.decorators = [
      { type: _angular_core.Injectable },
  ];
  /**
   * @nocollapse
   */
  NativeDateAdapter.ctorParameters = function () { return [
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_LOCALE,] },] },
  ]; };
  var MD_DATE_FORMATS = new _angular_core.InjectionToken('md-date-formats');
  var MD_NATIVE_DATE_FORMATS = {
      parse: {
          dateInput: null,
      },
      display: {
          dateInput: { year: 'numeric', month: 'numeric', day: 'numeric' },
          monthYearLabel: { year: 'numeric', month: 'short' },
          dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
          monthYearA11yLabel: { year: 'numeric', month: 'long' },
      }
  };
  var NativeDateModule = (function () {
      function NativeDateModule() {
      }
      return NativeDateModule;
  }());
  NativeDateModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  providers: [
                      { provide: DateAdapter, useClass: NativeDateAdapter },
                      MAT_DATE_LOCALE_PROVIDER
                  ],
              },] },
  ];
  /**
   * @nocollapse
   */
  NativeDateModule.ctorParameters = function () { return []; };
  var MdNativeDateModule = (function () {
      function MdNativeDateModule() {
      }
      return MdNativeDateModule;
  }());
  MdNativeDateModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [NativeDateModule],
                  providers: [{ provide: MD_DATE_FORMATS, useValue: MD_NATIVE_DATE_FORMATS }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdNativeDateModule.ctorParameters = function () { return []; };
  /**
   * Injection token that can be used to specify the global error options.
   */
  var MD_ERROR_GLOBAL_OPTIONS = new _angular_core.InjectionToken('md-error-global-options');
  var GestureConfig = (function (_super) {
      __extends(GestureConfig, _super);
      function GestureConfig() {
          var _this = _super.call(this) || this;
          _this._hammer = typeof window !== 'undefined' ? ((window)).Hammer : null;
          /* List of new event names to add to the gesture support list */
          _this.events = _this._hammer ? [
              'longpress',
              'slide',
              'slidestart',
              'slideend',
              'slideright',
              'slideleft'
          ] : [];
          if (!_this._hammer && _angular_core.isDevMode()) {
              console.warn('Could not find HammerJS. Certain Angular Material ' +
                  'components may not work correctly.');
          }
          return _this;
      }
      /**
       * Builds Hammer instance manually to add custom recognizers that match the Material Design spec.
      
      Our gesture names come from the Material Design gestures spec:
      https://www.google.com/design/spec/patterns/gestures.html#gestures-touch-mechanics
      
      More information on default recognizers can be found in Hammer docs:
      http://hammerjs.github.io/recognizer-pan/
      http://hammerjs.github.io/recognizer-press/
      
      \@param element Element to which to assign the new HammerJS gestures.
      \@returns Newly-created HammerJS instance.
       * @param {?} element
       * @return {?}
       */
      GestureConfig.prototype.buildHammer = function (element) {
          var /** @type {?} */ mc = new this._hammer(element);
          // Default Hammer Recognizers.
          var /** @type {?} */ pan = new this._hammer.Pan();
          var /** @type {?} */ swipe = new this._hammer.Swipe();
          var /** @type {?} */ press = new this._hammer.Press();
          // Notice that a HammerJS recognizer can only depend on one other recognizer once.
          // Otherwise the previous `recognizeWith` will be dropped.
          // TODO: Confirm threshold numbers with Material Design UX Team
          var /** @type {?} */ slide = this._createRecognizer(pan, { event: 'slide', threshold: 0 }, swipe);
          var /** @type {?} */ longpress = this._createRecognizer(press, { event: 'longpress', time: 500 });
          // Overwrite the default `pan` event to use the swipe event.
          pan.recognizeWith(swipe);
          // Add customized gestures to Hammer manager
          mc.add([swipe, press, pan, slide, longpress]);
          return (mc);
      };
      /**
       * Creates a new recognizer, without affecting the default recognizers of HammerJS
       * @param {?} base
       * @param {?} options
       * @param {...?} inheritances
       * @return {?}
       */
      GestureConfig.prototype._createRecognizer = function (base, options) {
          var inheritances = [];
          for (var _i = 2; _i < arguments.length; _i++) {
              inheritances[_i - 2] = arguments[_i];
          }
          var /** @type {?} */ recognizer = new ((base.constructor))(options);
          inheritances.push(base);
          inheritances.forEach(function (item) { return recognizer.recognizeWith(item); });
          return recognizer;
      };
      return GestureConfig;
  }(_angular_platformBrowser.HammerGestureConfig));
  GestureConfig.decorators = [
      { type: _angular_core.Injectable },
  ];
  /**
   * @nocollapse
   */
  GestureConfig.ctorParameters = function () { return []; };
  /**
   * Shared directive to count lines inside a text area, such as a list item.
  Line elements can be extracted with a \@ContentChildren(MdLine) query, then
  counted by checking the query list's length.
   */
  var MdLine = (function () {
      function MdLine() {
      }
      return MdLine;
  }());
  MdLine.decorators = [
      { type: _angular_core.Directive, args: [{
                  selector: '[md-line], [mat-line], [mdLine], [matLine]',
                  host: { 'class': 'mat-line' }
              },] },
  ];
  /**
   * @nocollapse
   */
  MdLine.ctorParameters = function () { return []; };
  var MdLineModule = (function () {
      function MdLineModule() {
      }
      return MdLineModule;
  }());
  MdLineModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [MdCommonModule],
                  exports: [MdLine, MdCommonModule],
                  declarations: [MdLine],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdLineModule.ctorParameters = function () { return []; };
  var RippleState = {};
  RippleState.FADING_IN = 0;
  RippleState.VISIBLE = 1;
  RippleState.FADING_OUT = 2;
  RippleState.HIDDEN = 3;
  RippleState[RippleState.FADING_IN] = "FADING_IN";
  RippleState[RippleState.VISIBLE] = "VISIBLE";
  RippleState[RippleState.FADING_OUT] = "FADING_OUT";
  RippleState[RippleState.HIDDEN] = "HIDDEN";
  /**
   * Reference to a previously launched ripple element.
   */
  var RippleRef = (function () {
      /**
       * @param {?} _renderer
       * @param {?} element
       * @param {?} config
       */
      function RippleRef(_renderer, element, config) {
          this._renderer = _renderer;
          this.element = element;
          this.config = config;
          /**
           * Current state of the ripple reference.
           */
          this.state = RippleState.HIDDEN;
      }
      /**
       * Fades out the ripple element.
       * @return {?}
       */
      RippleRef.prototype.fadeOut = function () {
          this._renderer.fadeOutRipple(this);
      };
      return RippleRef;
  }());
  /**
   * Fade-in duration for the ripples. Can be modified with the speedFactor option.
   */
  var RIPPLE_FADE_IN_DURATION = 450;
  /**
   * Fade-out duration for the ripples in milliseconds. This can't be modified by the speedFactor.
   */
  var RIPPLE_FADE_OUT_DURATION = 400;
  /**
   * Helper service that performs DOM manipulations. Not intended to be used outside this module.
  The constructor takes a reference to the ripple directive's host element and a map of DOM
  event handlers to be installed on the element that triggers ripple animations.
  This will eventually become a custom renderer once Angular support exists.
  \@docs-private
   */
  var RippleRenderer = (function () {
      /**
       * @param {?} elementRef
       * @param {?} _ngZone
       * @param {?} _ruler
       * @param {?} platform
       */
      function RippleRenderer(elementRef, _ngZone, _ruler, platform) {
          this._ngZone = _ngZone;
          this._ruler = _ruler;
          /**
           * Whether the mouse is currently down or not.
           */
          this._isMousedown = false;
          /**
           * Events to be registered on the trigger element.
           */
          this._triggerEvents = new Map();
          /**
           * Set of currently active ripple references.
           */
          this._activeRipples = new Set();
          /**
           * Ripple config for all ripples created by events.
           */
          this.rippleConfig = {};
          /**
           * Whether mouse ripples should be created or not.
           */
          this.rippleDisabled = false;
          // Only do anything if we're on the browser.
          if (platform.isBrowser) {
              this._containerElement = elementRef.nativeElement;
              // Specify events which need to be registered on the trigger.
              this._triggerEvents.set('mousedown', this.onMousedown.bind(this));
              this._triggerEvents.set('mouseup', this.onMouseup.bind(this));
              this._triggerEvents.set('mouseleave', this.onMouseLeave.bind(this));
              // By default use the host element as trigger element.
              this.setTriggerElement(this._containerElement);
          }
      }
      /**
       * Fades in a ripple at the given coordinates.
       * @param {?} pageX
       * @param {?} pageY
       * @param {?=} config
       * @return {?}
       */
      RippleRenderer.prototype.fadeInRipple = function (pageX, pageY, config) {
          var _this = this;
          if (config === void 0) { config = {}; }
          var /** @type {?} */ containerRect = this._containerElement.getBoundingClientRect();
          if (config.centered) {
              pageX = containerRect.left + containerRect.width / 2;
              pageY = containerRect.top + containerRect.height / 2;
          }
          else {
              // Subtract scroll values from the coordinates because calculations below
              // are always relative to the viewport rectangle.
              var /** @type {?} */ scrollPosition = this._ruler.getViewportScrollPosition();
              pageX -= scrollPosition.left;
              pageY -= scrollPosition.top;
          }
          var /** @type {?} */ radius = config.radius || distanceToFurthestCorner(pageX, pageY, containerRect);
          var /** @type {?} */ duration = RIPPLE_FADE_IN_DURATION * (1 / (config.speedFactor || 1));
          var /** @type {?} */ offsetX = pageX - containerRect.left;
          var /** @type {?} */ offsetY = pageY - containerRect.top;
          var /** @type {?} */ ripple = document.createElement('div');
          ripple.classList.add('mat-ripple-element');
          ripple.style.left = offsetX - radius + "px";
          ripple.style.top = offsetY - radius + "px";
          ripple.style.height = radius * 2 + "px";
          ripple.style.width = radius * 2 + "px";
          // If the color is not set, the default CSS color will be used.
          ripple.style.backgroundColor = config.color || null;
          ripple.style.transitionDuration = duration + "ms";
          this._containerElement.appendChild(ripple);
          // By default the browser does not recalculate the styles of dynamically created
          // ripple elements. This is critical because then the `scale` would not animate properly.
          enforceStyleRecalculation(ripple);
          ripple.style.transform = 'scale(1)';
          // Exposed reference to the ripple that will be returned.
          var /** @type {?} */ rippleRef = new RippleRef(this, ripple, config);
          rippleRef.state = RippleState.FADING_IN;
          // Add the ripple reference to the list of all active ripples.
          this._activeRipples.add(rippleRef);
          // Wait for the ripple element to be completely faded in.
          // Once it's faded in, the ripple can be hidden immediately if the mouse is released.
          this.runTimeoutOutsideZone(function () {
              rippleRef.state = RippleState.VISIBLE;
              if (!config.persistent && !_this._isMousedown) {
                  rippleRef.fadeOut();
              }
          }, duration);
          return rippleRef;
      };
      /**
       * Fades out a ripple reference.
       * @param {?} rippleRef
       * @return {?}
       */
      RippleRenderer.prototype.fadeOutRipple = function (rippleRef) {
          // For ripples that are not active anymore, don't re-un the fade-out animation.
          if (!this._activeRipples.delete(rippleRef)) {
              return;
          }
          var /** @type {?} */ rippleEl = rippleRef.element;
          rippleEl.style.transitionDuration = RIPPLE_FADE_OUT_DURATION + "ms";
          rippleEl.style.opacity = '0';
          rippleRef.state = RippleState.FADING_OUT;
          // Once the ripple faded out, the ripple can be safely removed from the DOM.
          this.runTimeoutOutsideZone(function () {
              rippleRef.state = RippleState.HIDDEN; /** @type {?} */
              ((rippleEl.parentNode)).removeChild(rippleEl);
          }, RIPPLE_FADE_OUT_DURATION);
      };
      /**
       * Fades out all currently active ripples.
       * @return {?}
       */
      RippleRenderer.prototype.fadeOutAll = function () {
          this._activeRipples.forEach(function (ripple) { return ripple.fadeOut(); });
      };
      /**
       * Sets the trigger element and registers the mouse events.
       * @param {?} element
       * @return {?}
       */
      RippleRenderer.prototype.setTriggerElement = function (element) {
          var _this = this;
          // Remove all previously register event listeners from the trigger element.
          if (this._triggerElement) {
              this._triggerEvents.forEach(function (fn, type) {
                  ((_this._triggerElement)).removeEventListener(type, fn);
              });
          }
          if (element) {
              // If the element is not null, register all event listeners on the trigger element.
              this._ngZone.runOutsideAngular(function () {
                  _this._triggerEvents.forEach(function (fn, type) { return element.addEventListener(type, fn); });
              });
          }
          this._triggerElement = element;
      };
      /**
       * Listener being called on mousedown event.
       * @param {?} event
       * @return {?}
       */
      RippleRenderer.prototype.onMousedown = function (event) {
          if (!this.rippleDisabled) {
              this._isMousedown = true;
              this.fadeInRipple(event.pageX, event.pageY, this.rippleConfig);
          }
      };
      /**
       * Listener being called on mouseup event.
       * @return {?}
       */
      RippleRenderer.prototype.onMouseup = function () {
          this._isMousedown = false;
          // Fade-out all ripples that are completely visible and not persistent.
          this._activeRipples.forEach(function (ripple) {
              if (!ripple.config.persistent && ripple.state === RippleState.VISIBLE) {
                  ripple.fadeOut();
              }
          });
      };
      /**
       * Listener being called on mouseleave event.
       * @return {?}
       */
      RippleRenderer.prototype.onMouseLeave = function () {
          if (this._isMousedown) {
              this.onMouseup();
          }
      };
      /**
       * Runs a timeout outside of the Angular zone to avoid triggering the change detection.
       * @param {?} fn
       * @param {?=} delay
       * @return {?}
       */
      RippleRenderer.prototype.runTimeoutOutsideZone = function (fn, delay) {
          if (delay === void 0) { delay = 0; }
          this._ngZone.runOutsideAngular(function () { return setTimeout(fn, delay); });
      };
      return RippleRenderer;
  }());
  /**
   * @param {?} element
   * @return {?}
   */
  function enforceStyleRecalculation(element) {
      // Enforce a style recalculation by calling `getComputedStyle` and accessing any property.
      // Calling `getPropertyValue` is important to let optimizers know that this is not a noop.
      // See: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
      window.getComputedStyle(element).getPropertyValue('opacity');
  }
  /**
   * Returns the distance from the point (x, y) to the furthest corner of a rectangle.
   * @param {?} x
   * @param {?} y
   * @param {?} rect
   * @return {?}
   */
  function distanceToFurthestCorner(x, y, rect) {
      var /** @type {?} */ distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
      var /** @type {?} */ distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));
      return Math.sqrt(distX * distX + distY * distY);
  }
  /**
   * Injection token that can be used to specify the global ripple options.
   */
  var MD_RIPPLE_GLOBAL_OPTIONS = new _angular_core.InjectionToken('md-ripple-global-options');
  var MdRipple = (function () {
      /**
       * @param {?} elementRef
       * @param {?} ngZone
       * @param {?} ruler
       * @param {?} platform
       * @param {?} globalOptions
       */
      function MdRipple(elementRef, ngZone, ruler, platform, globalOptions) {
          /**
           * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius
          will be the distance from the center of the ripple to the furthest corner of the host element's
          bounding rectangle.
           */
          this.radius = 0;
          /**
           * If set, the normal duration of ripple animations is divided by this value. For example,
          setting it to 0.5 will cause the animations to take twice as long.
          A changed speedFactor will not modify the fade-out duration of the ripples.
           */
          this.speedFactor = 1;
          this._rippleRenderer = new RippleRenderer(elementRef, ngZone, ruler, platform);
          this._globalOptions = globalOptions ? globalOptions : {};
          this._updateRippleRenderer();
      }
      Object.defineProperty(MdRipple.prototype, "_matRippleTrigger", {
          /**
           * @return {?}
           */
          get: function () { return this.trigger; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.trigger = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleCentered", {
          /**
           * @return {?}
           */
          get: function () { return this.centered; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.centered = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleDisabled", {
          /**
           * @return {?}
           */
          get: function () { return this.disabled; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.disabled = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleRadius", {
          /**
           * @return {?}
           */
          get: function () { return this.radius; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.radius = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleSpeedFactor", {
          /**
           * @return {?}
           */
          get: function () { return this.speedFactor; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.speedFactor = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleColor", {
          /**
           * @return {?}
           */
          get: function () { return this.color; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.color = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdRipple.prototype, "_matRippleUnbounded", {
          /**
           * @return {?}
           */
          get: function () { return this.unbounded; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.unbounded = v; },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} changes
       * @return {?}
       */
      MdRipple.prototype.ngOnChanges = function (changes) {
          if ((changes['trigger'] || changes['_matRippleTrigger']) && this.trigger) {
              this._rippleRenderer.setTriggerElement(this.trigger);
          }
          this._updateRippleRenderer();
      };
      /**
       * @return {?}
       */
      MdRipple.prototype.ngOnDestroy = function () {
          // Set the trigger element to null to cleanup all listeners.
          this._rippleRenderer.setTriggerElement(null);
      };
      /**
       * Launches a manual ripple at the specified position.
       * @param {?} pageX
       * @param {?} pageY
       * @param {?=} config
       * @return {?}
       */
      MdRipple.prototype.launch = function (pageX, pageY, config) {
          if (config === void 0) { config = this.rippleConfig; }
          return this._rippleRenderer.fadeInRipple(pageX, pageY, config);
      };
      /**
       * Fades out all currently showing ripple elements.
       * @return {?}
       */
      MdRipple.prototype.fadeOutAll = function () {
          this._rippleRenderer.fadeOutAll();
      };
      Object.defineProperty(MdRipple.prototype, "rippleConfig", {
          /**
           * Ripple configuration from the directive's input values.
           * @return {?}
           */
          get: function () {
              return {
                  centered: this.centered,
                  speedFactor: this.speedFactor * (this._globalOptions.baseSpeedFactor || 1),
                  radius: this.radius,
                  color: this.color
              };
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Updates the ripple renderer with the latest ripple configuration.
       * @return {?}
       */
      MdRipple.prototype._updateRippleRenderer = function () {
          this._rippleRenderer.rippleDisabled = this._globalOptions.disabled || this.disabled;
          this._rippleRenderer.rippleConfig = this.rippleConfig;
      };
      return MdRipple;
  }());
  MdRipple.decorators = [
      { type: _angular_core.Directive, args: [{
                  selector: '[md-ripple], [mat-ripple], [mdRipple], [matRipple]',
                  exportAs: 'mdRipple, matRipple',
                  host: {
                      'class': 'mat-ripple',
                      '[class.mat-ripple-unbounded]': 'unbounded'
                  }
              },] },
  ];
  /**
   * @nocollapse
   */
  MdRipple.ctorParameters = function () { return [
      { type: _angular_core.ElementRef, },
      { type: _angular_core.NgZone, },
      { type: _angular_cdk_scrolling.ViewportRuler, },
      { type: _angular_cdk_platform.Platform, },
      { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MD_RIPPLE_GLOBAL_OPTIONS,] },] },
  ]; };
  MdRipple.propDecorators = {
      'trigger': [{ type: _angular_core.Input, args: ['mdRippleTrigger',] },],
      'centered': [{ type: _angular_core.Input, args: ['mdRippleCentered',] },],
      'disabled': [{ type: _angular_core.Input, args: ['mdRippleDisabled',] },],
      'radius': [{ type: _angular_core.Input, args: ['mdRippleRadius',] },],
      'speedFactor': [{ type: _angular_core.Input, args: ['mdRippleSpeedFactor',] },],
      'color': [{ type: _angular_core.Input, args: ['mdRippleColor',] },],
      'unbounded': [{ type: _angular_core.Input, args: ['mdRippleUnbounded',] },],
      '_matRippleTrigger': [{ type: _angular_core.Input, args: ['matRippleTrigger',] },],
      '_matRippleCentered': [{ type: _angular_core.Input, args: ['matRippleCentered',] },],
      '_matRippleDisabled': [{ type: _angular_core.Input, args: ['matRippleDisabled',] },],
      '_matRippleRadius': [{ type: _angular_core.Input, args: ['matRippleRadius',] },],
      '_matRippleSpeedFactor': [{ type: _angular_core.Input, args: ['matRippleSpeedFactor',] },],
      '_matRippleColor': [{ type: _angular_core.Input, args: ['matRippleColor',] },],
      '_matRippleUnbounded': [{ type: _angular_core.Input, args: ['matRippleUnbounded',] },],
  };
  var MdRippleModule = (function () {
      function MdRippleModule() {
      }
      return MdRippleModule;
  }());
  MdRippleModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [MdCommonModule, _angular_cdk_platform.PlatformModule, _angular_cdk_scrolling.ScrollDispatchModule],
                  exports: [MdRipple, MdCommonModule],
                  declarations: [MdRipple],
                  providers: [_angular_cdk_scrolling.VIEWPORT_RULER_PROVIDER],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdRippleModule.ctorParameters = function () { return []; };
  /**
   * Component that shows a simplified checkbox without including any kind of "real" checkbox.
  Meant to be used when the checkbox is purely decorative and a large number of them will be
  included, such as for the options in a multi-select. Uses no SVGs or complex animations.
  Note that theming is meant to be handled by the parent element, e.g.
  `mat-primary .mat-pseudo-checkbox`.
  
  Note that this component will be completely invisible to screen-reader users. This is *not*
  interchangeable with <md-checkbox> and should *not* be used if the user would directly interact
  with the checkbox. The pseudo-checkbox should only be used as an implementation detail of
  more complex components that appropriately handle selected / checked state.
  \@docs-private
   */
  var MdPseudoCheckbox = (function () {
      function MdPseudoCheckbox() {
          /**
           * Display state of the checkbox.
           */
          this.state = 'unchecked';
          /**
           * Whether the checkbox is disabled.
           */
          this.disabled = false;
      }
      return MdPseudoCheckbox;
  }());
  MdPseudoCheckbox.decorators = [
      { type: _angular_core.Component, args: [{ encapsulation: _angular_core.ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  selector: 'md-pseudo-checkbox, mat-pseudo-checkbox',
                  styles: [".mat-pseudo-checkbox{width:20px;height:20px;border:2px solid;border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0,0,.2,.1),background-color 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:'';border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox.mat-pseudo-checkbox-indeterminate{border:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{top:9px;left:2px;width:16px;opacity:1}.mat-pseudo-checkbox-checked::after{top:5px;left:3px;width:12px;height:5px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1}"],
                  template: '',
                  host: {
                      'class': 'mat-pseudo-checkbox',
                      '[class.mat-pseudo-checkbox-indeterminate]': 'state === "indeterminate"',
                      '[class.mat-pseudo-checkbox-checked]': 'state === "checked"',
                      '[class.mat-pseudo-checkbox-disabled]': 'disabled',
                  },
              },] },
  ];
  /**
   * @nocollapse
   */
  MdPseudoCheckbox.ctorParameters = function () { return []; };
  MdPseudoCheckbox.propDecorators = {
      'state': [{ type: _angular_core.Input },],
      'disabled': [{ type: _angular_core.Input },],
  };
  var MdPseudoCheckboxModule = (function () {
      function MdPseudoCheckboxModule() {
      }
      return MdPseudoCheckboxModule;
  }());
  MdPseudoCheckboxModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  exports: [MdPseudoCheckbox],
                  declarations: [MdPseudoCheckbox]
              },] },
  ];
  /**
   * @nocollapse
   */
  MdPseudoCheckboxModule.ctorParameters = function () { return []; };
  /**
   * \@docs-private
   */
  var MdOptgroupBase = (function () {
      function MdOptgroupBase() {
      }
      return MdOptgroupBase;
  }());
  var _MdOptgroupMixinBase = mixinDisabled(MdOptgroupBase);
  // Counter for unique group ids.
  var _uniqueOptgroupIdCounter = 0;
  /**
   * Component that is used to group instances of `md-option`.
   */
  var MdOptgroup = (function (_super) {
      __extends(MdOptgroup, _super);
      function MdOptgroup() {
          var _this = _super.apply(this, arguments) || this;
          /**
           * Unique id for the underlying label.
           */
          _this._labelId = "mat-optgroup-label-" + _uniqueOptgroupIdCounter++;
          return _this;
      }
      return MdOptgroup;
  }(_MdOptgroupMixinBase));
  MdOptgroup.decorators = [
      { type: _angular_core.Component, args: [{ selector: 'md-optgroup, mat-optgroup',
                  template: "<label class=\"mat-optgroup-label\" [id]=\"_labelId\">{{ label }}</label><ng-content select=\"md-option, mat-option\"></ng-content>",
                  encapsulation: _angular_core.ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  inputs: ['disabled'],
                  host: {
                      'class': 'mat-optgroup',
                      'role': 'group',
                      '[class.mat-optgroup-disabled]': 'disabled',
                      '[attr.aria-disabled]': 'disabled.toString()',
                      '[attr.aria-labelledby]': '_labelId',
                  }
              },] },
  ];
  /**
   * @nocollapse
   */
  MdOptgroup.ctorParameters = function () { return []; };
  MdOptgroup.propDecorators = {
      'label': [{ type: _angular_core.Input },],
  };
  /**
   * Option IDs need to be unique across components, so this counter exists outside of
  the component definition.
   */
  var _uniqueIdCounter = 0;
  /**
   * Event object emitted by MdOption when selected or deselected.
   */
  var MdOptionSelectionChange = (function () {
      /**
       * @param {?} source
       * @param {?=} isUserInput
       */
      function MdOptionSelectionChange(source, isUserInput) {
          if (isUserInput === void 0) { isUserInput = false; }
          this.source = source;
          this.isUserInput = isUserInput;
      }
      return MdOptionSelectionChange;
  }());
  /**
   * Single option inside of a `<md-select>` element.
   */
  var MdOption = (function () {
      /**
       * @param {?} _element
       * @param {?} _changeDetectorRef
       * @param {?} group
       */
      function MdOption(_element, _changeDetectorRef, group) {
          this._element = _element;
          this._changeDetectorRef = _changeDetectorRef;
          this.group = group;
          this._selected = false;
          this._active = false;
          this._multiple = false;
          this._disableRipple = false;
          /**
           * Whether the option is disabled.
           */
          this._disabled = false;
          this._id = "md-option-" + _uniqueIdCounter++;
          /**
           * Event emitted when the option is selected or deselected.
           */
          this.onSelectionChange = new _angular_core.EventEmitter();
      }
      Object.defineProperty(MdOption.prototype, "multiple", {
          /**
           * Whether the wrapping component is in multiple selection mode.
           * @return {?}
           */
          get: function () { return this._multiple; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              if (value !== this._multiple) {
                  this._multiple = value;
                  this._changeDetectorRef.markForCheck();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "id", {
          /**
           * The unique ID of the option.
           * @return {?}
           */
          get: function () { return this._id; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "selected", {
          /**
           * Whether or not the option is currently selected.
           * @return {?}
           */
          get: function () { return this._selected; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "disabled", {
          /**
           * Whether the option is disabled.
           * @return {?}
           */
          get: function () { return (this.group && this.group.disabled) || this._disabled; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._disabled = _angular_cdk_coercion.coerceBooleanProperty(value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "disableRipple", {
          /**
           * Whether ripples for the option are disabled.
           * @return {?}
           */
          get: function () { return this._disableRipple; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._disableRipple = value;
              this._changeDetectorRef.markForCheck();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "active", {
          /**
           * Whether or not the option is currently active and ready to be selected.
          An active option displays styles as if it is focused, but the
          focus is actually retained somewhere else. This comes in handy
          for components like autocomplete where focus must remain on the input.
           * @return {?}
           */
          get: function () {
              return this._active;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdOption.prototype, "viewValue", {
          /**
           * The displayed value of the option. It is necessary to show the selected option in the
          select's trigger.
           * @return {?}
           */
          get: function () {
              // TODO(kara): Add input property alternative for node envs.
              return (this._getHostElement().textContent || '').trim();
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Selects the option.
       * @return {?}
       */
      MdOption.prototype.select = function () {
          this._selected = true;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      };
      /**
       * Deselects the option.
       * @return {?}
       */
      MdOption.prototype.deselect = function () {
          this._selected = false;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      };
      /**
       * Sets focus onto this option.
       * @return {?}
       */
      MdOption.prototype.focus = function () {
          var /** @type {?} */ element = this._getHostElement();
          if (typeof element.focus === 'function') {
              element.focus();
          }
      };
      /**
       * This method sets display styles on the option to make it appear
      active. This is used by the ActiveDescendantKeyManager so key
      events will display the proper options as active on arrow key events.
       * @return {?}
       */
      MdOption.prototype.setActiveStyles = function () {
          if (!this._active) {
              this._active = true;
              this._changeDetectorRef.markForCheck();
          }
      };
      /**
       * This method removes display styles on the option that made it appear
      active. This is used by the ActiveDescendantKeyManager so key
      events will display the proper options as active on arrow key events.
       * @return {?}
       */
      MdOption.prototype.setInactiveStyles = function () {
          if (this._active) {
              this._active = false;
              this._changeDetectorRef.markForCheck();
          }
      };
      /**
       * Gets the label to be used when determining whether the option should be focused.
       * @return {?}
       */
      MdOption.prototype.getLabel = function () {
          return this.viewValue;
      };
      /**
       * Ensures the option is selected when activated from the keyboard.
       * @param {?} event
       * @return {?}
       */
      MdOption.prototype._handleKeydown = function (event) {
          if (event.keyCode === _angular_cdk_keycodes.ENTER || event.keyCode === _angular_cdk_keycodes.SPACE) {
              this._selectViaInteraction();
              // Prevent the page from scrolling down and form submits.
              event.preventDefault();
          }
      };
      /**
       * Selects the option while indicating the selection came from the user. Used to
      determine if the select's view -> model callback should be invoked.
       * @return {?}
       */
      MdOption.prototype._selectViaInteraction = function () {
          if (!this.disabled) {
              this._selected = this.multiple ? !this._selected : true;
              this._changeDetectorRef.markForCheck();
              this._emitSelectionChangeEvent(true);
          }
      };
      /**
       * Returns the correct tabindex for the option depending on disabled state.
       * @return {?}
       */
      MdOption.prototype._getTabIndex = function () {
          return this.disabled ? '-1' : '0';
      };
      /**
       * Gets the host DOM element.
       * @return {?}
       */
      MdOption.prototype._getHostElement = function () {
          return this._element.nativeElement;
      };
      /**
       * Emits the selection change event.
       * @param {?=} isUserInput
       * @return {?}
       */
      MdOption.prototype._emitSelectionChangeEvent = function (isUserInput) {
          if (isUserInput === void 0) { isUserInput = false; }
          this.onSelectionChange.emit(new MdOptionSelectionChange(this, isUserInput));
      };
      /**
       * Counts the amount of option group labels that precede the specified option.
      \@param optionIndex Index of the option at which to start counting.
      \@param options Flat list of all of the options.
      \@param optionGroups Flat list of all of the option groups.
       * @param {?} optionIndex
       * @param {?} options
       * @param {?} optionGroups
       * @return {?}
       */
      MdOption.countGroupLabelsBeforeOption = function (optionIndex, options, optionGroups) {
          if (optionGroups.length) {
              var /** @type {?} */ optionsArray = options.toArray();
              var /** @type {?} */ groups = optionGroups.toArray();
              var /** @type {?} */ groupCounter = 0;
              for (var /** @type {?} */ i = 0; i < optionIndex + 1; i++) {
                  if (optionsArray[i].group && optionsArray[i].group === groups[groupCounter]) {
                      groupCounter++;
                  }
              }
              return groupCounter;
          }
          return 0;
      };
      return MdOption;
  }());
  MdOption.decorators = [
      { type: _angular_core.Component, args: [{ selector: 'md-option, mat-option',
                  host: {
                      'role': 'option',
                      '[attr.tabindex]': '_getTabIndex()',
                      '[class.mat-selected]': 'selected',
                      '[class.mat-option-multiple]': 'multiple',
                      '[class.mat-active]': 'active',
                      '[id]': 'id',
                      '[attr.aria-selected]': 'selected.toString()',
                      '[attr.aria-disabled]': 'disabled.toString()',
                      '[class.mat-option-disabled]': 'disabled',
                      '(click)': '_selectViaInteraction()',
                      '(keydown)': '_handleKeydown($event)',
                      'class': 'mat-option',
                  },
                  template: "<span *ngIf=\"multiple\"><mat-pseudo-checkbox class=\"mat-option-pseudo-checkbox\" [state]=\"selected ? 'checked' : ''\" [disabled]=\"disabled\"></mat-pseudo-checkbox></span><span class=\"mat-option-text\"><ng-content></ng-content></span><div class=\"mat-option-ripple\" mat-ripple [matRippleTrigger]=\"_getHostElement()\" [matRippleDisabled]=\"disabled || disableRipple\"></div>",
                  encapsulation: _angular_core.ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  viewProviders: [{ provide: MATERIAL_COMPATIBILITY_MODE, useValue: true }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdOption.ctorParameters = function () { return [
      { type: _angular_core.ElementRef, },
      { type: _angular_core.ChangeDetectorRef, },
      { type: MdOptgroup, decorators: [{ type: _angular_core.Optional },] },
  ]; };
  MdOption.propDecorators = {
      'value': [{ type: _angular_core.Input },],
      'disabled': [{ type: _angular_core.Input },],
      'onSelectionChange': [{ type: _angular_core.Output },],
  };
  var MdOptionModule = (function () {
      function MdOptionModule() {
      }
      return MdOptionModule;
  }());
  MdOptionModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [MdRippleModule, _angular_common.CommonModule, MdPseudoCheckboxModule],
                  exports: [MdOption, MdOptgroup],
                  declarations: [MdOption, MdOptgroup]
              },] },
  ];
  /**
   * @nocollapse
   */
  MdOptionModule.ctorParameters = function () { return []; };
  /**
   * InjectionToken that can be used to specify the global placeholder options.
   */
  var MD_PLACEHOLDER_GLOBAL_OPTIONS = new _angular_core.InjectionToken('md-placeholder-global-options');
  
  /**
   * Visually, a 30px separation between tick marks looks best. This is very subjective but it is
  the default separation we chose.
   */
  var MIN_AUTO_TICK_SEPARATION = 30;
  /**
   * The thumb gap size for a disabled slider.
   */
  var DISABLED_THUMB_GAP = 7;
  /**
   * The thumb gap size for a non-active slider at its minimum value.
   */
  var MIN_VALUE_NONACTIVE_THUMB_GAP = 7;
  /**
   * The thumb gap size for an active slider at its minimum value.
   */
  var MIN_VALUE_ACTIVE_THUMB_GAP = 10;
  /**
   * Provider Expression that allows md-slider to register as a ControlValueAccessor.
  This allows it to support [(ngModel)] and [formControl].
   */
  var MD_SLIDER_VALUE_ACCESSOR = {
      provide: _angular_forms.NG_VALUE_ACCESSOR,
      useExisting: _angular_core.forwardRef(function () { return MdSlider; }),
      multi: true
  };
  /**
   * A simple change event emitted by the MdSlider component.
   */
  var MdSliderChange = (function () {
      function MdSliderChange() {
      }
      return MdSliderChange;
  }());
  /**
   * \@docs-private
   */
  var MdSliderBase = (function () {
      /**
       * @param {?} _renderer
       * @param {?} _elementRef
       */
      function MdSliderBase(_renderer, _elementRef) {
          this._renderer = _renderer;
          this._elementRef = _elementRef;
      }
      return MdSliderBase;
  }());
  var _MdSliderMixinBase = mixinColor(mixinDisabled(MdSliderBase), 'accent');
  /**
   * Allows users to select from a range of values by moving the slider thumb. It is similar in
  behavior to the native `<input type="range">` element.
   */
  var MdSlider = (function (_super) {
      __extends(MdSlider, _super);
      /**
       * @param {?} renderer
       * @param {?} elementRef
       * @param {?} _focusMonitor
       * @param {?} _changeDetectorRef
       * @param {?} _dir
       */
      function MdSlider(renderer, elementRef, _focusMonitor, _changeDetectorRef, _dir) {
          var _this = _super.call(this, renderer, elementRef) || this;
          _this._focusMonitor = _focusMonitor;
          _this._changeDetectorRef = _changeDetectorRef;
          _this._dir = _dir;
          _this._invert = false;
          _this._max = 100;
          _this._min = 0;
          _this._step = 1;
          _this._thumbLabel = false;
          _this._tickInterval = 0;
          _this._value = null;
          _this._vertical = false;
          /**
           * Event emitted when the slider value has changed.
           */
          _this.change = new _angular_core.EventEmitter();
          /**
           * Event emitted when the slider thumb moves.
           */
          _this.input = new _angular_core.EventEmitter();
          /**
           * onTouch function registered via registerOnTouch (ControlValueAccessor).
           */
          _this.onTouched = function () { };
          _this._percent = 0;
          /**
           * Whether or not the thumb is sliding.
          Used to determine if there should be a transition for the thumb and fill track.
           */
          _this._isSliding = false;
          /**
           * Whether or not the slider is active (clicked or sliding).
          Used to shrink and grow the thumb as according to the Material Design spec.
           */
          _this._isActive = false;
          /**
           * The size of a tick interval as a percentage of the size of the track.
           */
          _this._tickIntervalPercent = 0;
          /**
           * The dimensions of the slider.
           */
          _this._sliderDimensions = null;
          _this._controlValueAccessorChangeFn = function () { };
          /**
           * Subscription to the Directionality change EventEmitter.
           */
          _this._dirChangeSubscription = rxjs_Subscription.Subscription.EMPTY;
          return _this;
      }
      Object.defineProperty(MdSlider.prototype, "invert", {
          /**
           * Whether the slider is inverted.
           * @return {?}
           */
          get: function () { return this._invert; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._invert = _angular_cdk_coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "max", {
          /**
           * The maximum value that the slider can have.
           * @return {?}
           */
          get: function () { return this._max; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) {
              this._max = _angular_cdk_coercion.coerceNumberProperty(v, this._max);
              this._percent = this._calculatePercentage(this._value);
              // Since this also modifies the percentage, we need to let the change detection know.
              this._changeDetectorRef.markForCheck();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "min", {
          /**
           * The minimum value that the slider can have.
           * @return {?}
           */
          get: function () { return this._min; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) {
              this._min = _angular_cdk_coercion.coerceNumberProperty(v, this._min);
              // If the value wasn't explicitly set by the user, set it to the min.
              if (this._value === null) {
                  this.value = this._min;
              }
              this._percent = this._calculatePercentage(this._value);
              // Since this also modifies the percentage, we need to let the change detection know.
              this._changeDetectorRef.markForCheck();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "step", {
          /**
           * The values at which the thumb will snap.
           * @return {?}
           */
          get: function () { return this._step; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) {
              this._step = _angular_cdk_coercion.coerceNumberProperty(v, this._step);
              if (this._step % 1 !== 0) {
                  this._roundLabelTo = ((this._step.toString().split('.').pop())).length;
              }
              // Since this could modify the label, we need to notify the change detection.
              this._changeDetectorRef.markForCheck();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "thumbLabel", {
          /**
           * Whether or not to show the thumb label.
           * @return {?}
           */
          get: function () { return this._thumbLabel; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._thumbLabel = _angular_cdk_coercion.coerceBooleanProperty(value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_thumbLabelDeprecated", {
          /**
           * @deprecated
           * @return {?}
           */
          get: function () { return this._thumbLabel; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._thumbLabel = value; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "tickInterval", {
          /**
           * How often to show ticks. Relative to the step so that a tick always appears on a step.
          Ex: Tick interval of 4 with a step of 3 will draw a tick every 4 steps (every 12 values).
           * @return {?}
           */
          get: function () { return this._tickInterval; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              if (value === 'auto') {
                  this._tickInterval = 'auto';
              }
              else if (typeof value === 'number' || typeof value === 'string') {
                  this._tickInterval = _angular_cdk_coercion.coerceNumberProperty(value, /** @type {?} */ (this._tickInterval));
              }
              else {
                  this._tickInterval = 0;
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_tickIntervalDeprecated", {
          /**
           * @deprecated
           * @return {?}
           */
          get: function () { return this.tickInterval; },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) { this.tickInterval = v; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "value", {
          /**
           * Value of the slider.
           * @return {?}
           */
          get: function () {
              // If the value needs to be read and it is still uninitialized, initialize it to the min.
              if (this._value === null) {
                  this.value = this._min;
              }
              return this._value;
          },
          /**
           * @param {?} v
           * @return {?}
           */
          set: function (v) {
              if (v !== this._value) {
                  this._value = _angular_cdk_coercion.coerceNumberProperty(v, this._value || 0);
                  this._percent = this._calculatePercentage(this._value);
                  // Since this also modifies the percentage, we need to let the change detection know.
                  this._changeDetectorRef.markForCheck();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "vertical", {
          /**
           * Whether the slider is vertical.
           * @return {?}
           */
          get: function () { return this._vertical; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._vertical = _angular_cdk_coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "displayValue", {
          /**
           * The value to be used for display purposes.
           * @return {?}
           */
          get: function () {
              // Note that this could be improved further by rounding something like 0.999 to 1 or
              // 0.899 to 0.9, however it is very performance sensitive, because it gets called on
              // every change detection cycle.
              if (this._roundLabelTo && this.value && this.value % 1 !== 0) {
                  return this.value.toFixed(this._roundLabelTo);
              }
              return this.value || 0;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "percent", {
          /**
           * The percentage of the slider that coincides with the value.
           * @return {?}
           */
          get: function () { return this._clamp(this._percent); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_invertAxis", {
          /**
           * Whether the axis of the slider is inverted.
          (i.e. whether moving the thumb in the positive x or y direction decreases the slider's value).
           * @return {?}
           */
          get: function () {
              // Standard non-inverted mode for a vertical slider should be dragging the thumb from bottom to
              // top. However from a y-axis standpoint this is inverted.
              return this.vertical ? !this.invert : this.invert;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_isMinValue", {
          /**
           * Whether the slider is at its minimum value.
           * @return {?}
           */
          get: function () {
              return this.percent === 0;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_thumbGap", {
          /**
           * The amount of space to leave between the slider thumb and the track fill & track background
          elements.
           * @return {?}
           */
          get: function () {
              if (this.disabled) {
                  return DISABLED_THUMB_GAP;
              }
              if (this._isMinValue && !this.thumbLabel) {
                  return this._isActive ? MIN_VALUE_ACTIVE_THUMB_GAP : MIN_VALUE_NONACTIVE_THUMB_GAP;
              }
              return 0;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_trackBackgroundStyles", {
          /**
           * CSS styles for the track background element.
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ axis = this.vertical ? 'Y' : 'X';
              var /** @type {?} */ sign = this._invertMouseCoords ? '-' : '';
              return {
                  'transform': "translate" + axis + "(" + sign + this._thumbGap + "px) scale" + axis + "(" + (1 - this.percent) + ")"
              };
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_trackFillStyles", {
          /**
           * CSS styles for the track fill element.
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ axis = this.vertical ? 'Y' : 'X';
              var /** @type {?} */ sign = this._invertMouseCoords ? '' : '-';
              return {
                  'transform': "translate" + axis + "(" + sign + this._thumbGap + "px) scale" + axis + "(" + this.percent + ")"
              };
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_ticksContainerStyles", {
          /**
           * CSS styles for the ticks container element.
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ axis = this.vertical ? 'Y' : 'X';
              // For a horizontal slider in RTL languages we push the ticks container off the left edge
              // instead of the right edge to avoid causing a horizontal scrollbar to appear.
              var /** @type {?} */ sign = !this.vertical && this._direction == 'rtl' ? '' : '-';
              var /** @type {?} */ offset = this._tickIntervalPercent / 2 * 100;
              return {
                  'transform': "translate" + axis + "(" + sign + offset + "%)"
              };
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_ticksStyles", {
          /**
           * CSS styles for the ticks element.
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ tickSize = this._tickIntervalPercent * 100;
              var /** @type {?} */ backgroundSize = this.vertical ? "2px " + tickSize + "%" : tickSize + "% 2px";
              var /** @type {?} */ axis = this.vertical ? 'Y' : 'X';
              // Depending on the direction we pushed the ticks container, push the ticks the opposite
              // direction to re-center them but clip off the end edge. In RTL languages we need to flip the
              // ticks 180 degrees so we're really cutting off the end edge abd not the start.
              var /** @type {?} */ sign = !this.vertical && this._direction == 'rtl' ? '-' : '';
              var /** @type {?} */ rotate = !this.vertical && this._direction == 'rtl' ? ' rotate(180deg)' : '';
              var /** @type {?} */ styles = {
                  'backgroundSize': backgroundSize,
                  // Without translateZ ticks sometimes jitter as the slider moves on Chrome & Firefox.
                  'transform': "translateZ(0) translate" + axis + "(" + sign + tickSize / 2 + "%)" + rotate
              };
              if (this._isMinValue && this._thumbGap) {
                  var /** @type {?} */ side = this.vertical ?
                      (this._invertAxis ? 'Bottom' : 'Top') :
                      (this._invertAxis ? 'Right' : 'Left');
                  styles["padding" + side] = this._thumbGap + "px";
              }
              return styles;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_thumbContainerStyles", {
          /**
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ axis = this.vertical ? 'Y' : 'X';
              // For a horizontal slider in RTL languages we push the thumb container off the left edge
              // instead of the right edge to avoid causing a horizontal scrollbar to appear.
              var /** @type {?} */ invertOffset = (this._direction == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
              var /** @type {?} */ offset = (invertOffset ? this.percent : 1 - this.percent) * 100;
              return {
                  'transform': "translate" + axis + "(-" + offset + "%)"
              };
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_invertMouseCoords", {
          /**
           * Whether mouse events should be converted to a slider position by calculating their distance
          from the right or bottom edge of the slider as opposed to the top or left.
           * @return {?}
           */
          get: function () {
              return (this._direction == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MdSlider.prototype, "_direction", {
          /**
           * The language direction for this slider element.
           * @return {?}
           */
          get: function () {
              return (this._dir && this._dir.value == 'rtl') ? 'rtl' : 'ltr';
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MdSlider.prototype.ngOnInit = function () {
          var _this = this;
          this._focusMonitor
              .monitor(this._elementRef.nativeElement, this._renderer, true)
              .subscribe(function (origin) {
              _this._isActive = !!origin && origin !== 'keyboard';
              _this._changeDetectorRef.detectChanges();
          });
          if (this._dir) {
              this._dirChangeSubscription = this._dir.change.subscribe(function () {
                  _this._changeDetectorRef.markForCheck();
              });
          }
      };
      /**
       * @return {?}
       */
      MdSlider.prototype.ngOnDestroy = function () {
          this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
          this._dirChangeSubscription.unsubscribe();
      };
      /**
       * @return {?}
       */
      MdSlider.prototype._onMouseenter = function () {
          if (this.disabled) {
              return;
          }
          // We save the dimensions of the slider here so we can use them to update the spacing of the
          // ticks and determine where on the slider click and slide events happen.
          this._sliderDimensions = this._getSliderDimensions();
          this._updateTickIntervalPercent();
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MdSlider.prototype._onClick = function (event) {
          if (this.disabled) {
              return;
          }
          var /** @type {?} */ oldValue = this.value;
          this._isSliding = false;
          this._focusHostElement();
          this._updateValueFromPosition({ x: event.clientX, y: event.clientY });
          /* Emit a change and input event if the value changed. */
          if (oldValue != this.value) {
              this._emitInputEvent();
              this._emitChangeEvent();
          }
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MdSlider.prototype._onSlide = function (event) {
          if (this.disabled) {
              return;
          }
          // The slide start event sometimes fails to fire on iOS, so if we're not already in the sliding
          // state, call the slide start handler manually.
          if (!this._isSliding) {
              this._onSlideStart(null);
          }
          // Prevent the slide from selecting anything else.
          event.preventDefault();
          var /** @type {?} */ oldValue = this.value;
          this._updateValueFromPosition({ x: event.center.x, y: event.center.y });
          // Native range elements always emit `input` events when the value changed while sliding.
          if (oldValue != this.value) {
              this._emitInputEvent();
          }
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MdSlider.prototype._onSlideStart = function (event) {
          if (this.disabled) {
              return;
          }
          // Simulate mouseenter in case this is a mobile device.
          this._onMouseenter();
          this._isSliding = true;
          this._focusHostElement();
          this._valueOnSlideStart = this.value;
          if (event) {
              this._updateValueFromPosition({ x: event.center.x, y: event.center.y });
              event.preventDefault();
          }
      };
      /**
       * @return {?}
       */
      MdSlider.prototype._onSlideEnd = function () {
          this._isSliding = false;
          if (this._valueOnSlideStart != this.value) {
              this._emitChangeEvent();
          }
          this._valueOnSlideStart = null;
      };
      /**
       * @return {?}
       */
      MdSlider.prototype._onFocus = function () {
          // We save the dimensions of the slider here so we can use them to update the spacing of the
          // ticks and determine where on the slider click and slide events happen.
          this._sliderDimensions = this._getSliderDimensions();
          this._updateTickIntervalPercent();
      };
      /**
       * @return {?}
       */
      MdSlider.prototype._onBlur = function () {
          this.onTouched();
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MdSlider.prototype._onKeydown = function (event) {
          if (this.disabled) {
              return;
          }
          var /** @type {?} */ oldValue = this.value;
          switch (event.keyCode) {
              case _angular_cdk_keycodes.PAGE_UP:
                  this._increment(10);
                  break;
              case _angular_cdk_keycodes.PAGE_DOWN:
                  this._increment(-10);
                  break;
              case _angular_cdk_keycodes.END:
                  this.value = this.max;
                  break;
              case _angular_cdk_keycodes.HOME:
                  this.value = this.min;
                  break;
              case _angular_cdk_keycodes.LEFT_ARROW:
                  // NOTE: For a sighted user it would make more sense that when they press an arrow key on an
                  // inverted slider the thumb moves in that direction. However for a blind user, nothing
                  // about the slider indicates that it is inverted. They will expect left to be decrement,
                  // regardless of how it appears on the screen. For speakers ofRTL languages, they probably
                  // expect left to mean increment. Therefore we flip the meaning of the side arrow keys for
                  // RTL. For inverted sliders we prefer a good a11y experience to having it "look right" for
                  // sighted users, therefore we do not swap the meaning.
                  this._increment(this._direction == 'rtl' ? 1 : -1);
                  break;
              case _angular_cdk_keycodes.UP_ARROW:
                  this._increment(1);
                  break;
              case _angular_cdk_keycodes.RIGHT_ARROW:
                  // See comment on LEFT_ARROW about the conditions under which we flip the meaning.
                  this._increment(this._direction == 'rtl' ? -1 : 1);
                  break;
              case _angular_cdk_keycodes.DOWN_ARROW:
                  this._increment(-1);
                  break;
              default:
                  // Return if the key is not one that we explicitly handle to avoid calling preventDefault on
                  // it.
                  return;
          }
          if (oldValue != this.value) {
              this._emitInputEvent();
              this._emitChangeEvent();
          }
          this._isSliding = true;
          event.preventDefault();
      };
      /**
       * @return {?}
       */
      MdSlider.prototype._onKeyup = function () {
          this._isSliding = false;
      };
      /**
       * Increments the slider by the given number of steps (negative number decrements).
       * @param {?} numSteps
       * @return {?}
       */
      MdSlider.prototype._increment = function (numSteps) {
          this.value = this._clamp((this.value || 0) + this.step * numSteps, this.min, this.max);
      };
      /**
       * Calculate the new value from the new physical location. The value will always be snapped.
       * @param {?} pos
       * @return {?}
       */
      MdSlider.prototype._updateValueFromPosition = function (pos) {
          if (!this._sliderDimensions) {
              return;
          }
          var /** @type {?} */ offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
          var /** @type {?} */ size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
          var /** @type {?} */ posComponent = this.vertical ? pos.y : pos.x;
          // The exact value is calculated from the event and used to find the closest snap value.
          var /** @type {?} */ percent = this._clamp((posComponent - offset) / size);
          if (this._invertMouseCoords) {
              percent = 1 - percent;
          }
          var /** @type {?} */ exactValue = this._calculateValue(percent);
          // This calculation finds the closest step by finding the closest whole number divisible by the
          // step relative to the min.
          var /** @type {?} */ closestValue = Math.round((exactValue - this.min) / this.step) * this.step + this.min;
          // The value needs to snap to the min and max.
          this.value = this._clamp(closestValue, this.min, this.max);
      };
      /**
       * Emits a change event if the current value is different from the last emitted value.
       * @return {?}
       */
      MdSlider.prototype._emitChangeEvent = function () {
          this._controlValueAccessorChangeFn(this.value);
          this.change.emit(this._createChangeEvent());
      };
      /**
       * Emits an input event when the current value is different from the last emitted value.
       * @return {?}
       */
      MdSlider.prototype._emitInputEvent = function () {
          this.input.emit(this._createChangeEvent());
      };
      /**
       * Updates the amount of space between ticks as a percentage of the width of the slider.
       * @return {?}
       */
      MdSlider.prototype._updateTickIntervalPercent = function () {
          if (!this.tickInterval || !this._sliderDimensions) {
              return;
          }
          if (this.tickInterval == 'auto') {
              var /** @type {?} */ trackSize = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
              var /** @type {?} */ pixelsPerStep = trackSize * this.step / (this.max - this.min);
              var /** @type {?} */ stepsPerTick = Math.ceil(MIN_AUTO_TICK_SEPARATION / pixelsPerStep);
              var /** @type {?} */ pixelsPerTick = stepsPerTick * this.step;
              this._tickIntervalPercent = pixelsPerTick / trackSize;
          }
          else {
              this._tickIntervalPercent = this.tickInterval * this.step / (this.max - this.min);
          }
      };
      /**
       * Creates a slider change object from the specified value.
       * @param {?=} value
       * @return {?}
       */
      MdSlider.prototype._createChangeEvent = function (value) {
          if (value === void 0) { value = this.value; }
          var /** @type {?} */ event = new MdSliderChange();
          event.source = this;
          event.value = value;
          return event;
      };
      /**
       * Calculates the percentage of the slider that a value is.
       * @param {?} value
       * @return {?}
       */
      MdSlider.prototype._calculatePercentage = function (value) {
          return ((value || 0) - this.min) / (this.max - this.min);
      };
      /**
       * Calculates the value a percentage of the slider corresponds to.
       * @param {?} percentage
       * @return {?}
       */
      MdSlider.prototype._calculateValue = function (percentage) {
          return this.min + percentage * (this.max - this.min);
      };
      /**
       * Return a number between two numbers.
       * @param {?} value
       * @param {?=} min
       * @param {?=} max
       * @return {?}
       */
      MdSlider.prototype._clamp = function (value, min, max) {
          if (min === void 0) { min = 0; }
          if (max === void 0) { max = 1; }
          return Math.max(min, Math.min(value, max));
      };
      /**
       * Get the bounding client rect of the slider track element.
      The track is used rather than the native element to ignore the extra space that the thumb can
      take up.
       * @return {?}
       */
      MdSlider.prototype._getSliderDimensions = function () {
          return this._sliderWrapper ? this._sliderWrapper.nativeElement.getBoundingClientRect() : null;
      };
      /**
       * Focuses the native element.
      Currently only used to allow a blur event to fire but will be used with keyboard input later.
       * @return {?}
       */
      MdSlider.prototype._focusHostElement = function () {
          this._elementRef.nativeElement.focus();
      };
      /**
       * Sets the model value. Implemented as part of ControlValueAccessor.
      \@param value
       * @param {?} value
       * @return {?}
       */
      MdSlider.prototype.writeValue = function (value) {
          this.value = value;
      };
      /**
       * Registers a callback to eb triggered when the value has changed.
      Implemented as part of ControlValueAccessor.
      \@param fn Callback to be registered.
       * @param {?} fn
       * @return {?}
       */
      MdSlider.prototype.registerOnChange = function (fn) {
          this._controlValueAccessorChangeFn = fn;
      };
      /**
       * Registers a callback to be triggered when the component is touched.
      Implemented as part of ControlValueAccessor.
      \@param fn Callback to be registered.
       * @param {?} fn
       * @return {?}
       */
      MdSlider.prototype.registerOnTouched = function (fn) {
          this.onTouched = fn;
      };
      /**
       * Sets whether the component should be disabled.
      Implemented as part of ControlValueAccessor.
      \@param isDisabled
       * @param {?} isDisabled
       * @return {?}
       */
      MdSlider.prototype.setDisabledState = function (isDisabled) {
          this.disabled = isDisabled;
      };
      return MdSlider;
  }(_MdSliderMixinBase));
  MdSlider.decorators = [
      { type: _angular_core.Component, args: [{ selector: 'md-slider, mat-slider',
                  providers: [MD_SLIDER_VALUE_ACCESSOR],
                  host: {
                      '(focus)': '_onFocus()',
                      '(blur)': '_onBlur()',
                      '(click)': '_onClick($event)',
                      '(keydown)': '_onKeydown($event)',
                      '(keyup)': '_onKeyup()',
                      '(mouseenter)': '_onMouseenter()',
                      '(slide)': '_onSlide($event)',
                      '(slideend)': '_onSlideEnd()',
                      '(slidestart)': '_onSlideStart($event)',
                      'class': 'mat-slider',
                      'role': 'slider',
                      'tabindex': '0',
                      '[attr.aria-disabled]': 'disabled',
                      '[attr.aria-valuemax]': 'max',
                      '[attr.aria-valuemin]': 'min',
                      '[attr.aria-valuenow]': 'value',
                      '[attr.aria-orientation]': 'vertical ? "vertical" : "horizontal"',
                      '[class.mat-slider-disabled]': 'disabled',
                      '[class.mat-slider-has-ticks]': 'tickInterval',
                      '[class.mat-slider-horizontal]': '!vertical',
                      '[class.mat-slider-axis-inverted]': '_invertAxis',
                      '[class.mat-slider-sliding]': '_isSliding',
                      '[class.mat-slider-thumb-label-showing]': 'thumbLabel',
                      '[class.mat-slider-vertical]': 'vertical',
                      '[class.mat-slider-min-value]': '_isMinValue',
                      '[class.mat-slider-hide-last-tick]': 'disabled || _isMinValue && _thumbGap && _invertAxis',
                  },
                  template: "<div class=\"mat-slider-wrapper\" #sliderWrapper><div class=\"mat-slider-track-wrapper\"><div class=\"mat-slider-track-background\" [ngStyle]=\"_trackBackgroundStyles\"></div><div class=\"mat-slider-track-fill\" [ngStyle]=\"_trackFillStyles\"></div></div><div class=\"mat-slider-ticks-container\" [ngStyle]=\"_ticksContainerStyles\"><div class=\"mat-slider-ticks\" [ngStyle]=\"_ticksStyles\"></div></div><div class=\"mat-slider-thumb-container\" [ngStyle]=\"_thumbContainerStyles\"><div class=\"mat-slider-focus-ring\"></div><div class=\"mat-slider-thumb\"></div><div class=\"mat-slider-thumb-label\"><span class=\"mat-slider-thumb-label-text\">{{displayValue}}</span></div></div></div>",
                  styles: [".mat-slider{display:inline-block;position:relative;box-sizing:border-box;padding:8px;outline:0;vertical-align:middle}.mat-slider-wrapper{position:absolute}.mat-slider-track-wrapper{position:absolute;top:0;left:0;overflow:hidden}.mat-slider-track-fill{position:absolute;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-track-background{position:absolute;transform-origin:100% 100%;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-ticks-container{position:absolute;left:0;top:0;overflow:hidden}.mat-slider-ticks{background-repeat:repeat;background-clip:content-box;box-sizing:border-box;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-container{position:absolute;z-index:1;transition:transform .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-focus-ring{position:absolute;width:30px;height:30px;border-radius:50%;transform:scale(0);opacity:0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),opacity .4s cubic-bezier(.25,.8,.25,1)}.cdk-keyboard-focused .mat-slider-focus-ring{transform:scale(1);opacity:1}.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb-label{cursor:-webkit-grab;cursor:grab}.mat-slider-sliding:not(.mat-slider-disabled) .mat-slider-thumb,.mat-slider-sliding:not(.mat-slider-disabled) .mat-slider-thumb-label,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb-label:active,.mat-slider:not(.mat-slider-disabled) .mat-slider-thumb:active{cursor:-webkit-grabbing;cursor:grabbing}.mat-slider-thumb{position:absolute;right:-10px;bottom:-10px;box-sizing:border-box;width:20px;height:20px;border:3px solid transparent;border-radius:50%;transform:scale(.7);transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),border-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-label{display:none;align-items:center;justify-content:center;position:absolute;width:28px;height:28px;border-radius:50%;transition:transform .4s cubic-bezier(.25,.8,.25,1),border-radius .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-thumb-label-text{z-index:1;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-sliding .mat-slider-thumb-container,.mat-slider-sliding .mat-slider-track-background,.mat-slider-sliding .mat-slider-track-fill{transition-duration:0s}.mat-slider-has-ticks .mat-slider-wrapper::after{content:'';position:absolute;border-width:0;border-style:solid;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mat-slider-has-ticks.cdk-focused:not(.mat-slider-hide-last-tick) .mat-slider-wrapper::after,.mat-slider-has-ticks:hover:not(.mat-slider-hide-last-tick) .mat-slider-wrapper::after{opacity:1}.mat-slider-has-ticks.cdk-focused:not(.mat-slider-disabled) .mat-slider-ticks,.mat-slider-has-ticks:hover:not(.mat-slider-disabled) .mat-slider-ticks{opacity:1}.mat-slider-thumb-label-showing .mat-slider-focus-ring{transform:scale(0);opacity:0}.mat-slider-thumb-label-showing .mat-slider-thumb-label{display:flex}.mat-slider-axis-inverted .mat-slider-track-fill{transform-origin:100% 100%}.mat-slider-axis-inverted .mat-slider-track-background{transform-origin:0 0}.mat-slider:not(.mat-slider-disabled).cdk-focused.mat-slider-thumb-label-showing .mat-slider-thumb{transform:scale(0)}.mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label{border-radius:50% 50% 0}.mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label-text{opacity:1}.mat-slider:not(.mat-slider-disabled).cdk-mouse-focused .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled).cdk-program-focused .mat-slider-thumb,.mat-slider:not(.mat-slider-disabled).cdk-touch-focused .mat-slider-thumb{border-width:2px;transform:scale(1)}.mat-slider-disabled .mat-slider-focus-ring{transform:scale(0);opacity:0}.mat-slider-disabled .mat-slider-thumb{border-width:4px;transform:scale(.5)}.mat-slider-disabled .mat-slider-thumb-label{display:none}.mat-slider-horizontal{height:48px;min-width:128px}.mat-slider-horizontal .mat-slider-wrapper{height:2px;top:23px;left:8px;right:8px}.mat-slider-horizontal .mat-slider-wrapper::after{height:2px;border-left-width:2px;right:0;top:0}.mat-slider-horizontal .mat-slider-track-wrapper{height:2px;width:100%}.mat-slider-horizontal .mat-slider-track-fill{height:2px;width:100%;transform:scaleX(0)}.mat-slider-horizontal .mat-slider-track-background{height:2px;width:100%;transform:scaleX(1)}.mat-slider-horizontal .mat-slider-ticks-container{height:2px;width:100%}.mat-slider-horizontal .mat-slider-ticks{height:2px;width:100%}.mat-slider-horizontal .mat-slider-thumb-container{width:100%;height:0;top:50%}.mat-slider-horizontal .mat-slider-focus-ring{top:-15px;right:-15px}.mat-slider-horizontal .mat-slider-thumb-label{right:-14px;top:-40px;transform:translateY(26px) scale(.01) rotate(45deg)}.mat-slider-horizontal .mat-slider-thumb-label-text{transform:rotate(-45deg)}.mat-slider-horizontal.cdk-focused .mat-slider-thumb-label{transform:rotate(45deg)}.mat-slider-vertical{width:48px;min-height:128px}.mat-slider-vertical .mat-slider-wrapper{width:2px;top:8px;bottom:8px;left:23px}.mat-slider-vertical .mat-slider-wrapper::after{width:2px;border-top-width:2px;bottom:0;left:0}.mat-slider-vertical .mat-slider-track-wrapper{height:100%;width:2px}.mat-slider-vertical .mat-slider-track-fill{height:100%;width:2px;transform:scaleY(0)}.mat-slider-vertical .mat-slider-track-background{height:100%;width:2px;transform:scaleY(1)}.mat-slider-vertical .mat-slider-ticks-container{width:2px;height:100%}.mat-slider-vertical .mat-slider-focus-ring{bottom:-15px;left:-15px}.mat-slider-vertical .mat-slider-ticks{width:2px;height:100%}.mat-slider-vertical .mat-slider-thumb-container{height:100%;width:0;left:50%}.mat-slider-vertical .mat-slider-thumb-label{bottom:-14px;left:-40px;transform:translateX(26px) scale(.01) rotate(-45deg)}.mat-slider-vertical .mat-slider-thumb-label-text{transform:rotate(45deg)}.mat-slider-vertical.cdk-focused .mat-slider-thumb-label{transform:rotate(-45deg)}[dir=rtl] .mat-slider-wrapper::after{left:0;right:auto}[dir=rtl] .mat-slider-horizontal .mat-slider-track-fill{transform-origin:100% 100%}[dir=rtl] .mat-slider-horizontal .mat-slider-track-background{transform-origin:0 0}[dir=rtl] .mat-slider-horizontal.mat-slider-axis-inverted .mat-slider-track-fill{transform-origin:0 0}[dir=rtl] .mat-slider-horizontal.mat-slider-axis-inverted .mat-slider-track-background{transform-origin:100% 100%}"],
                  inputs: ['disabled', 'color'],
                  encapsulation: _angular_core.ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
              },] },
  ];
  /**
   * @nocollapse
   */
  MdSlider.ctorParameters = function () { return [
      { type: _angular_core.Renderer2, },
      { type: _angular_core.ElementRef, },
      { type: _angular_cdk_a11y.FocusMonitor, },
      { type: _angular_core.ChangeDetectorRef, },
      { type: _angular_cdk_bidi.Directionality, decorators: [{ type: _angular_core.Optional },] },
  ]; };
  MdSlider.propDecorators = {
      'invert': [{ type: _angular_core.Input },],
      'max': [{ type: _angular_core.Input },],
      'min': [{ type: _angular_core.Input },],
      'step': [{ type: _angular_core.Input },],
      'thumbLabel': [{ type: _angular_core.Input },],
      '_thumbLabelDeprecated': [{ type: _angular_core.Input, args: ['thumb-label',] },],
      'tickInterval': [{ type: _angular_core.Input },],
      '_tickIntervalDeprecated': [{ type: _angular_core.Input, args: ['tick-interval',] },],
      'value': [{ type: _angular_core.Input },],
      'vertical': [{ type: _angular_core.Input },],
      'change': [{ type: _angular_core.Output },],
      'input': [{ type: _angular_core.Output },],
      '_sliderWrapper': [{ type: _angular_core.ViewChild, args: ['sliderWrapper',] },],
  };
  var MdSliderModule = (function () {
      function MdSliderModule() {
      }
      return MdSliderModule;
  }());
  MdSliderModule.decorators = [
      { type: _angular_core.NgModule, args: [{
                  imports: [_angular_common.CommonModule, MdCommonModule, _angular_cdk_bidi.BidiModule, _angular_cdk_a11y.A11yModule],
                  exports: [MdSlider, MdCommonModule],
                  declarations: [MdSlider],
                  providers: [{ provide: _angular_platformBrowser.HAMMER_GESTURE_CONFIG, useClass: GestureConfig }]
              },] },
  ];
  /**
   * @nocollapse
   */
  MdSliderModule.ctorParameters = function () { return []; };
  
  exports.MdSliderModule = MdSliderModule;
  exports.MD_SLIDER_VALUE_ACCESSOR = MD_SLIDER_VALUE_ACCESSOR;
  exports.MdSliderChange = MdSliderChange;
  exports.MdSliderBase = MdSliderBase;
  exports._MdSliderMixinBase = _MdSliderMixinBase;
  exports.MdSlider = MdSlider;
  exports.MAT_SLIDER_VALUE_ACCESSOR = MD_SLIDER_VALUE_ACCESSOR;
  exports.MatSlider = MdSlider;
  exports.MatSliderBase = MdSliderBase;
  exports.MatSliderChange = MdSliderChange;
  exports.MatSliderModule = MdSliderModule;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=material-slider.umd.js.map
  