text: /**
   * @license Angular v6.0.0
   * (c) 2010-2018 Google, Inc. https://angular.io/
   * License: MIT
   */
  
  import { Inject, Injectable, InjectionToken, Injector, NgModule, PLATFORM_ID } from '@angular/core';
  import { Observable, of } from 'rxjs';
  import { concatMap, filter, map } from 'rxjs/operators';
  import { DOCUMENT, ɵparseCookieValue } from '@angular/common';
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Transforms an `HttpRequest` into a stream of `HttpEvent`s, one of which will likely be a
   * `HttpResponse`.
   *
   * `HttpHandler` is injectable. When injected, the handler instance dispatches requests to the
   * first interceptor in the chain, which dispatches to the second, etc, eventually reaching the
   * `HttpBackend`.
   *
   * In an `HttpInterceptor`, the `HttpHandler` parameter is the next interceptor in the chain.
   *
   *
   * @abstract
   */
  class HttpHandler {
  }
  /**
   * A final `HttpHandler` which will dispatch the request via browser HTTP APIs to a backend.
   *
   * Interceptors sit between the `HttpClient` interface and the `HttpBackend`.
   *
   * When injected, `HttpBackend` dispatches requests directly to the backend, without going
   * through the interceptor chain.
   *
   *
   * @abstract
   */
  class HttpBackend {
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @record
   */
  /**
   * Immutable set of Http headers, with lazy parsing.
   *
   */
  class HttpHeaders {
      /**
       * @param {?=} headers
       */
      constructor(headers) {
          /**
           * Internal map of lowercased header names to the normalized
           * form of the name (the form seen first).
           */
          this.normalizedNames = new Map();
          /**
           * Queued updates to be materialized the next initialization.
           */
          this.lazyUpdate = null;
          if (!headers) {
              this.headers = new Map();
          }
          else if (typeof headers === 'string') {
              this.lazyInit = () => {
                  this.headers = new Map();
                  headers.split('\n').forEach(line => {
                      const /** @type {?} */ index = line.indexOf(':');
                      if (index > 0) {
                          const /** @type {?} */ name = line.slice(0, index);
                          const /** @type {?} */ key = name.toLowerCase();
                          const /** @type {?} */ value = line.slice(index + 1).trim();
                          this.maybeSetNormalizedName(name, key);
                          if (this.headers.has(key)) {
                              /** @type {?} */ ((this.headers.get(key))).push(value);
                          }
                          else {
                              this.headers.set(key, [value]);
                          }
                      }
                  });
              };
          }
          else {
              this.lazyInit = () => {
                  this.headers = new Map();
                  Object.keys(headers).forEach(name => {
                      let /** @type {?} */ values = headers[name];
                      const /** @type {?} */ key = name.toLowerCase();
                      if (typeof values === 'string') {
                          values = [values];
                      }
                      if (values.length > 0) {
                          this.headers.set(key, values);
                          this.maybeSetNormalizedName(name, key);
                      }
                  });
              };
          }
      }
      /**
       * Checks for existence of header by given name.
       * @param {?} name
       * @return {?}
       */
      has(name) {
          this.init();
          return this.headers.has(name.toLowerCase());
      }
      /**
       * Returns first header that matches given name.
       * @param {?} name
       * @return {?}
       */
      get(name) {
          this.init();
          const /** @type {?} */ values = this.headers.get(name.toLowerCase());
          return values && values.length > 0 ? values[0] : null;
      }
      /**
       * Returns the names of the headers
       * @return {?}
       */
      keys() {
          this.init();
          return Array.from(this.normalizedNames.values());
      }
      /**
       * Returns list of header values for a given name.
       * @param {?} name
       * @return {?}
       */
      getAll(name) {
          this.init();
          return this.headers.get(name.toLowerCase()) || null;
      }
      /**
       * @param {?} name
       * @param {?} value
       * @return {?}
       */
      append(name, value) {
          return this.clone({ name, value, op: 'a' });
      }
      /**
       * @param {?} name
       * @param {?} value
       * @return {?}
       */
      set(name, value) {
          return this.clone({ name, value, op: 's' });
      }
      /**
       * @param {?} name
       * @param {?=} value
       * @return {?}
       */
      delete(name, value) {
          return this.clone({ name, value, op: 'd' });
      }
      /**
       * @param {?} name
       * @param {?} lcName
       * @return {?}
       */
      maybeSetNormalizedName(name, lcName) {
          if (!this.normalizedNames.has(lcName)) {
              this.normalizedNames.set(lcName, name);
          }
      }
      /**
       * @return {?}
       */
      init() {
          if (!!this.lazyInit) {
              if (this.lazyInit instanceof HttpHeaders) {
                  this.copyFrom(this.lazyInit);
              }
              else {
                  this.lazyInit();
              }
              this.lazyInit = null;
              if (!!this.lazyUpdate) {
                  this.lazyUpdate.forEach(update => this.applyUpdate(update));
                  this.lazyUpdate = null;
              }
          }
      }
      /**
       * @param {?} other
       * @return {?}
       */
      copyFrom(other) {
          other.init();
          Array.from(other.headers.keys()).forEach(key => {
              this.headers.set(key, /** @type {?} */ ((other.headers.get(key))));
              this.normalizedNames.set(key, /** @type {?} */ ((other.normalizedNames.get(key))));
          });
      }
      /**
       * @param {?} update
       * @return {?}
       */
      clone(update) {
          const /** @type {?} */ clone = new HttpHeaders();
          clone.lazyInit =
              (!!this.lazyInit && this.lazyInit instanceof HttpHeaders) ? this.lazyInit : this;
          clone.lazyUpdate = (this.lazyUpdate || []).concat([update]);
          return clone;
      }
      /**
       * @param {?} update
       * @return {?}
       */
      applyUpdate(update) {
          const /** @type {?} */ key = update.name.toLowerCase();
          switch (update.op) {
              case 'a':
              case 's':
                  let /** @type {?} */ value = /** @type {?} */ ((update.value));
                  if (typeof value === 'string') {
                      value = [value];
                  }
                  if (value.length === 0) {
                      return;
                  }
                  this.maybeSetNormalizedName(update.name, key);
                  const /** @type {?} */ base = (update.op === 'a' ? this.headers.get(key) : undefined) || [];
                  base.push(...value);
                  this.headers.set(key, base);
                  break;
              case 'd':
                  const /** @type {?} */ toDelete = /** @type {?} */ (update.value);
                  if (!toDelete) {
                      this.headers.delete(key);
                      this.normalizedNames.delete(key);
                  }
                  else {
                      let /** @type {?} */ existing = this.headers.get(key);
                      if (!existing) {
                          return;
                      }
                      existing = existing.filter(value => toDelete.indexOf(value) === -1);
                      if (existing.length === 0) {
                          this.headers.delete(key);
                          this.normalizedNames.delete(key);
                      }
                      else {
                          this.headers.set(key, existing);
                      }
                  }
                  break;
          }
      }
      /**
       * \@internal
       * @param {?} fn
       * @return {?}
       */
      forEach(fn) {
          this.init();
          Array.from(this.normalizedNames.keys())
              .forEach(key => fn(/** @type {?} */ ((this.normalizedNames.get(key))), /** @type {?} */ ((this.headers.get(key)))));
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A codec for encoding and decoding parameters in URLs.
   *
   * Used by `HttpParams`.
   *
   *
   *
   * @record
   */
  
  /**
   * A `HttpParameterCodec` that uses `encodeURIComponent` and `decodeURIComponent` to
   * serialize and parse URL parameter keys and values.
   *
   *
   */
  class HttpUrlEncodingCodec {
      /**
       * @param {?} k
       * @return {?}
       */
      encodeKey(k) { return standardEncoding(k); }
      /**
       * @param {?} v
       * @return {?}
       */
      encodeValue(v) { return standardEncoding(v); }
      /**
       * @param {?} k
       * @return {?}
       */
      decodeKey(k) { return decodeURIComponent(k); }
      /**
       * @param {?} v
       * @return {?}
       */
      decodeValue(v) { return decodeURIComponent(v); }
  }
  /**
   * @param {?} rawParams
   * @param {?} codec
   * @return {?}
   */
  function paramParser(rawParams, codec) {
      const /** @type {?} */ map$$1 = new Map();
      if (rawParams.length > 0) {
          const /** @type {?} */ params = rawParams.split('&');
          params.forEach((param) => {
              const /** @type {?} */ eqIdx = param.indexOf('=');
              const [key, val] = eqIdx == -1 ?
                  [codec.decodeKey(param), ''] :
                  [codec.decodeKey(param.slice(0, eqIdx)), codec.decodeValue(param.slice(eqIdx + 1))];
              const /** @type {?} */ list = map$$1.get(key) || [];
              list.push(val);
              map$$1.set(key, list);
          });
      }
      return map$$1;
  }
  /**
   * @param {?} v
   * @return {?}
   */
  function standardEncoding(v) {
      return encodeURIComponent(v)
          .replace(/%40/gi, '@')
          .replace(/%3A/gi, ':')
          .replace(/%24/gi, '$')
          .replace(/%2C/gi, ',')
          .replace(/%3B/gi, ';')
          .replace(/%2B/gi, '+')
          .replace(/%3D/gi, '=')
          .replace(/%3F/gi, '?')
          .replace(/%2F/gi, '/');
  }
  /**
   * Options used to construct an `HttpParams` instance.
   * @record
   */
  
  /**
   * An HTTP request/response body that represents serialized parameters,
   * per the MIME type `application/x-www-form-urlencoded`.
   *
   * This class is immutable - all mutation operations return a new instance.
   *
   *
   */
  class HttpParams {
      /**
       * @param {?=} options
       */
      constructor(options = /** @type {?} */ ({})) {
          this.updates = null;
          this.cloneFrom = null;
          this.encoder = options.encoder || new HttpUrlEncodingCodec();
          if (!!options.fromString) {
              if (!!options.fromObject) {
                  throw new Error(`Cannot specify both fromString and fromObject.`);
              }
              this.map = paramParser(options.fromString, this.encoder);
          }
          else if (!!options.fromObject) {
              this.map = new Map();
              Object.keys(options.fromObject).forEach(key => {
                  const /** @type {?} */ value = (/** @type {?} */ (options.fromObject))[key]; /** @type {?} */
                  ((this.map)).set(key, Array.isArray(value) ? value : [value]);
              });
          }
          else {
              this.map = null;
          }
      }
      /**
       * Check whether the body has one or more values for the given parameter name.
       * @param {?} param
       * @return {?}
       */
      has(param) {
          this.init();
          return /** @type {?} */ ((this.map)).has(param);
      }
      /**
       * Get the first value for the given parameter name, or `null` if it's not present.
       * @param {?} param
       * @return {?}
       */
      get(param) {
          this.init();
          const /** @type {?} */ res = /** @type {?} */ ((this.map)).get(param);
          return !!res ? res[0] : null;
      }
      /**
       * Get all values for the given parameter name, or `null` if it's not present.
       * @param {?} param
       * @return {?}
       */
      getAll(param) {
          this.init();
          return /** @type {?} */ ((this.map)).get(param) || null;
      }
      /**
       * Get all the parameter names for this body.
       * @return {?}
       */
      keys() {
          this.init();
          return Array.from(/** @type {?} */ ((this.map)).keys());
      }
      /**
       * Construct a new body with an appended value for the given parameter name.
       * @param {?} param
       * @param {?} value
       * @return {?}
       */
      append(param, value) { return this.clone({ param, value, op: 'a' }); }
      /**
       * Construct a new body with a new value for the given parameter name.
       * @param {?} param
       * @param {?} value
       * @return {?}
       */
      set(param, value) { return this.clone({ param, value, op: 's' }); }
      /**
       * Construct a new body with either the given value for the given parameter
       * removed, if a value is given, or all values for the given parameter removed
       * if not.
       * @param {?} param
       * @param {?=} value
       * @return {?}
       */
      delete(param, value) { return this.clone({ param, value, op: 'd' }); }
      /**
       * Serialize the body to an encoded string, where key-value pairs (separated by `=`) are
       * separated by `&`s.
       * @return {?}
       */
      toString() {
          this.init();
          return this.keys()
              .map(key => {
              const /** @type {?} */ eKey = this.encoder.encodeKey(key);
              return /** @type {?} */ ((/** @type {?} */ ((this.map)).get(key))).map(value => eKey + '=' + this.encoder.encodeValue(value)).join('&');
          })
              .join('&');
      }
      /**
       * @param {?} update
       * @return {?}
       */
      clone(update) {
          const /** @type {?} */ clone = new HttpParams(/** @type {?} */ ({ encoder: this.encoder }));
          clone.cloneFrom = this.cloneFrom || this;
          clone.updates = (this.updates || []).concat([update]);
          return clone;
      }
      /**
       * @return {?}
       */
      init() {
          if (this.map === null) {
              this.map = new Map();
          }
          if (this.cloneFrom !== null) {
              this.cloneFrom.init();
              this.cloneFrom.keys().forEach(key => /** @type {?} */ ((this.map)).set(key, /** @type {?} */ ((/** @type {?} */ ((/** @type {?} */ ((this.cloneFrom)).map)).get(key))))); /** @type {?} */
              ((this.updates)).forEach(update => {
                  switch (update.op) {
                      case 'a':
                      case 's':
                          const /** @type {?} */ base = (update.op === 'a' ? /** @type {?} */ ((this.map)).get(update.param) : undefined) || [];
                          base.push(/** @type {?} */ ((update.value))); /** @type {?} */
                          ((this.map)).set(update.param, base);
                          break;
                      case 'd':
                          if (update.value !== undefined) {
                              let /** @type {?} */ base = /** @type {?} */ ((this.map)).get(update.param) || [];
                              const /** @type {?} */ idx = base.indexOf(update.value);
                              if (idx !== -1) {
                                  base.splice(idx, 1);
                              }
                              if (base.length > 0) {
                                  /** @type {?} */ ((this.map)).set(update.param, base);
                              }
                              else {
                                  /** @type {?} */ ((this.map)).delete(update.param);
                              }
                          }
                          else {
                              /** @type {?} */ ((this.map)).delete(update.param);
                              break;
                          }
                  }
              });
              this.cloneFrom = null;
          }
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Determine whether the given HTTP method may include a body.
   * @param {?} method
   * @return {?}
   */
  function mightHaveBody(method) {
      switch (method) {
          case 'DELETE':
          case 'GET':
          case 'HEAD':
          case 'OPTIONS':
          case 'JSONP':
              return false;
          default:
              return true;
      }
  }
  /**
   * Safely assert whether the given value is an ArrayBuffer.
   *
   * In some execution environments ArrayBuffer is not defined.
   * @param {?} value
   * @return {?}
   */
  function isArrayBuffer(value) {
      return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
  }
  /**
   * Safely assert whether the given value is a Blob.
   *
   * In some execution environments Blob is not defined.
   * @param {?} value
   * @return {?}
   */
  function isBlob(value) {
      return typeof Blob !== 'undefined' && value instanceof Blob;
  }
  /**
   * Safely assert whether the given value is a FormData instance.
   *
   * In some execution environments FormData is not defined.
   * @param {?} value
   * @return {?}
   */
  function isFormData(value) {
      return typeof FormData !== 'undefined' && value instanceof FormData;
  }
  /**
   * An outgoing HTTP request with an optional typed body.
   *
   * `HttpRequest` represents an outgoing request, including URL, method,
   * headers, body, and other request configuration options. Instances should be
   * assumed to be immutable. To modify a `HttpRequest`, the `clone`
   * method should be used.
   *
   *
   * @template T
   */
  class HttpRequest {
      /**
       * @param {?} method
       * @param {?} url
       * @param {?=} third
       * @param {?=} fourth
       */
      constructor(method, url, third, fourth) {
          this.url = url;
          /**
           * The request body, or `null` if one isn't set.
           *
           * Bodies are not enforced to be immutable, as they can include a reference to any
           * user-defined data type. However, interceptors should take care to preserve
           * idempotence by treating them as such.
           */
          this.body = null;
          /**
           * Whether this request should be made in a way that exposes progress events.
           *
           * Progress events are expensive (change detection runs on each event) and so
           * they should only be requested if the consumer intends to monitor them.
           */
          this.reportProgress = false;
          /**
           * Whether this request should be sent with outgoing credentials (cookies).
           */
          this.withCredentials = false;
          /**
           * The expected response type of the server.
           *
           * This is used to parse the response appropriately before returning it to
           * the requestee.
           */
          this.responseType = 'json';
          this.method = method.toUpperCase();
          // Next, need to figure out which argument holds the HttpRequestInit
          // options, if any.
          let /** @type {?} */ options;
          // Check whether a body argument is expected. The only valid way to omit
          // the body argument is to use a known no-body method like GET.
          if (mightHaveBody(this.method) || !!fourth) {
              // Body is the third argument, options are the fourth.
              this.body = (third !== undefined) ? /** @type {?} */ (third) : null;
              options = fourth;
          }
          else {
              // No body required, options are the third argument. The body stays null.
              options = /** @type {?} */ (third);
          }
          // If options have been passed, interpret them.
          if (options) {
              // Normalize reportProgress and withCredentials.
              this.reportProgress = !!options.reportProgress;
              this.withCredentials = !!options.withCredentials;
              // Override default response type of 'json' if one is provided.
              if (!!options.responseType) {
                  this.responseType = options.responseType;
              }
              // Override headers if they're provided.
              if (!!options.headers) {
                  this.headers = options.headers;
              }
              if (!!options.params) {
                  this.params = options.params;
              }
          }
          // If no headers have been passed in, construct a new HttpHeaders instance.
          if (!this.headers) {
              this.headers = new HttpHeaders();
          }
          // If no parameters have been passed in, construct a new HttpUrlEncodedParams instance.
          if (!this.params) {
              this.params = new HttpParams();
              this.urlWithParams = url;
          }
          else {
              // Encode the parameters to a string in preparation for inclusion in the URL.
              const /** @type {?} */ params = this.params.toString();
              if (params.length === 0) {
                  // No parameters, the visible URL is just the URL given at creation time.
                  this.urlWithParams = url;
              }
              else {
                  // Does the URL already have query parameters? Look for '?'.
                  const /** @type {?} */ qIdx = url.indexOf('?');
                  // There are 3 cases to handle:
                  // 1) No existing parameters -> append '?' followed by params.
                  // 2) '?' exists and is followed by existing query string ->
                  //    append '&' followed by params.
                  // 3) '?' exists at the end of the url -> append params directly.
                  // This basically amounts to determining the character, if any, with
                  // which to join the URL and parameters.
                  const /** @type {?} */ sep = qIdx === -1 ? '?' : (qIdx < url.length - 1 ? '&' : '');
                  this.urlWithParams = url + sep + params;
              }
          }
      }
      /**
       * Transform the free-form body into a serialized format suitable for
       * transmission to the server.
       * @return {?}
       */
      serializeBody() {
          // If no body is present, no need to serialize it.
          if (this.body === null) {
              return null;
          }
          // Check whether the body is already in a serialized form. If so,
          // it can just be returned directly.
          if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) ||
              typeof this.body === 'string') {
              return this.body;
          }
          // Check whether the body is an instance of HttpUrlEncodedParams.
          if (this.body instanceof HttpParams) {
              return this.body.toString();
          }
          // Check whether the body is an object or array, and serialize with JSON if so.
          if (typeof this.body === 'object' || typeof this.body === 'boolean' ||
              Array.isArray(this.body)) {
              return JSON.stringify(this.body);
          }
          // Fall back on toString() for everything else.
          return (/** @type {?} */ (this.body)).toString();
      }
      /**
       * Examine the body and attempt to infer an appropriate MIME type
       * for it.
       *
       * If no such type can be inferred, this method will return `null`.
       * @return {?}
       */
      detectContentTypeHeader() {
          // An empty body has no content type.
          if (this.body === null) {
              return null;
          }
          // FormData bodies rely on the browser's content type assignment.
          if (isFormData(this.body)) {
              return null;
          }
          // Blobs usually have their own content type. If it doesn't, then
          // no type can be inferred.
          if (isBlob(this.body)) {
              return this.body.type || null;
          }
          // Array buffers have unknown contents and thus no type can be inferred.
          if (isArrayBuffer(this.body)) {
              return null;
          }
          // Technically, strings could be a form of JSON data, but it's safe enough
          // to assume they're plain strings.
          if (typeof this.body === 'string') {
              return 'text/plain';
          }
          // `HttpUrlEncodedParams` has its own content-type.
          if (this.body instanceof HttpParams) {
              return 'application/x-www-form-urlencoded;charset=UTF-8';
          }
          // Arrays, objects, and numbers will be encoded as JSON.
          if (typeof this.body === 'object' || typeof this.body === 'number' ||
              Array.isArray(this.body)) {
              return 'application/json';
          }
          // No type could be inferred.
          return null;
      }
      /**
       * @param {?=} update
       * @return {?}
       */
      clone(update = {}) {
          // For method, url, and responseType, take the current value unless
          // it is overridden in the update hash.
          const /** @type {?} */ method = update.method || this.method;
          const /** @type {?} */ url = update.url || this.url;
          const /** @type {?} */ responseType = update.responseType || this.responseType;
          // The body is somewhat special - a `null` value in update.body means
          // whatever current body is present is being overridden with an empty
          // body, whereas an `undefined` value in update.body implies no
          // override.
          const /** @type {?} */ body = (update.body !== undefined) ? update.body : this.body;
          // Carefully handle the boolean options to differentiate between
          // `false` and `undefined` in the update args.
          const /** @type {?} */ withCredentials = (update.withCredentials !== undefined) ? update.withCredentials : this.withCredentials;
          const /** @type {?} */ reportProgress = (update.reportProgress !== undefined) ? update.reportProgress : this.reportProgress;
          // Headers and params may be appended to if `setHeaders` or
          // `setParams` are used.
          let /** @type {?} */ headers = update.headers || this.headers;
          let /** @type {?} */ params = update.params || this.params;
          // Check whether the caller has asked to add headers.
          if (update.setHeaders !== undefined) {
              // Set every requested header.
              headers =
                  Object.keys(update.setHeaders)
                      .reduce((headers, name) => headers.set(name, /** @type {?} */ ((update.setHeaders))[name]), headers);
          }
          // Check whether the caller has asked to set params.
          if (update.setParams) {
              // Set every requested param.
              params = Object.keys(update.setParams)
                  .reduce((params, param) => params.set(param, /** @type {?} */ ((update.setParams))[param]), params);
          }
          // Finally, construct the new HttpRequest using the pieces from above.
          return new HttpRequest(method, url, body, {
              params, headers, reportProgress, responseType, withCredentials,
          });
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /** @enum {number} */
  const HttpEventType = {
      /**
         * The request was sent out over the wire.
         */
      Sent: 0,
      /**
         * An upload progress event was received.
         */
      UploadProgress: 1,
      /**
         * The response status code and headers were received.
         */
      ResponseHeader: 2,
      /**
         * A download progress event was received.
         */
      DownloadProgress: 3,
      /**
         * The full response including the body was received.
         */
      Response: 4,
      /**
         * A custom event from an interceptor or a backend.
         */
      User: 5,
  };
  HttpEventType[HttpEventType.Sent] = "Sent";
  HttpEventType[HttpEventType.UploadProgress] = "UploadProgress";
  HttpEventType[HttpEventType.ResponseHeader] = "ResponseHeader";
  HttpEventType[HttpEventType.DownloadProgress] = "DownloadProgress";
  HttpEventType[HttpEventType.Response] = "Response";
  HttpEventType[HttpEventType.User] = "User";
  /**
   * Base interface for progress events.
   *
   *
   * @record
   */
  
  /**
   * A download progress event.
   *
   *
   * @record
   */
  
  /**
   * An upload progress event.
   *
   *
   * @record
   */
  
  /**
   * An event indicating that the request was sent to the server. Useful
   * when a request may be retried multiple times, to distinguish between
   * retries on the final event stream.
   *
   *
   * @record
   */
  
  /**
   * A user-defined event.
   *
   * Grouping all custom events under this type ensures they will be handled
   * and forwarded by all implementations of interceptors.
   *
   *
   * @record
   * @template T
   */
  
  /**
   * An error that represents a failed attempt to JSON.parse text coming back
   * from the server.
   *
   * It bundles the Error object with the actual response body that failed to parse.
   *
   *
   * @record
   */
  
  /**
   * Base class for both `HttpResponse` and `HttpHeaderResponse`.
   *
   *
   * @abstract
   */
  class HttpResponseBase {
      /**
       * Super-constructor for all responses.
       *
       * The single parameter accepted is an initialization hash. Any properties
       * of the response passed there will override the default values.
       * @param {?} init
       * @param {?=} defaultStatus
       * @param {?=} defaultStatusText
       */
      constructor(init, defaultStatus = 200, defaultStatusText = 'OK') {
          // If the hash has values passed, use them to initialize the response.
          // Otherwise use the default values.
          this.headers = init.headers || new HttpHeaders();
          this.status = init.status !== undefined ? init.status : defaultStatus;
          this.statusText = init.statusText || defaultStatusText;
          this.url = init.url || null;
          // Cache the ok value to avoid defining a getter.
          this.ok = this.status >= 200 && this.status < 300;
      }
  }
  /**
   * A partial HTTP response which only includes the status and header data,
   * but no response body.
   *
   * `HttpHeaderResponse` is a `HttpEvent` available on the response
   * event stream, only when progress events are requested.
   *
   *
   */
  class HttpHeaderResponse extends HttpResponseBase {
      /**
       * Create a new `HttpHeaderResponse` with the given parameters.
       * @param {?=} init
       */
      constructor(init = {}) {
          super(init);
          this.type = HttpEventType.ResponseHeader;
      }
      /**
       * Copy this `HttpHeaderResponse`, overriding its contents with the
       * given parameter hash.
       * @param {?=} update
       * @return {?}
       */
      clone(update = {}) {
          // Perform a straightforward initialization of the new HttpHeaderResponse,
          // overriding the current parameters with new ones if given.
          return new HttpHeaderResponse({
              headers: update.headers || this.headers,
              status: update.status !== undefined ? update.status : this.status,
              statusText: update.statusText || this.statusText,
              url: update.url || this.url || undefined,
          });
      }
  }
  /**
   * A full HTTP response, including a typed response body (which may be `null`
   * if one was not returned).
   *
   * `HttpResponse` is a `HttpEvent` available on the response event
   * stream.
   *
   *
   * @template T
   */
  class HttpResponse extends HttpResponseBase {
      /**
       * Construct a new `HttpResponse`.
       * @param {?=} init
       */
      constructor(init = {}) {
          super(init);
          this.type = HttpEventType.Response;
          this.body = init.body !== undefined ? init.body : null;
      }
      /**
       * @param {?=} update
       * @return {?}
       */
      clone(update = {}) {
          return new HttpResponse({
              body: (update.body !== undefined) ? update.body : this.body,
              headers: update.headers || this.headers,
              status: (update.status !== undefined) ? update.status : this.status,
              statusText: update.statusText || this.statusText,
              url: update.url || this.url || undefined,
          });
      }
  }
  /**
   * A response that represents an error or failure, either from a
   * non-successful HTTP status, an error while executing the request,
   * or some other failure which occurred during the parsing of the response.
   *
   * Any error returned on the `Observable` response stream will be
   * wrapped in an `HttpErrorResponse` to provide additional context about
   * the state of the HTTP layer when the error occurred. The error property
   * will contain either a wrapped Error object or the error response returned
   * from the server.
   *
   *
   */
  class HttpErrorResponse extends HttpResponseBase {
      /**
       * @param {?} init
       */
      constructor(init) {
          // Initialize with a default status of 0 / Unknown Error.
          super(init, 0, 'Unknown Error');
          this.name = 'HttpErrorResponse';
          /**
           * Errors are never okay, even when the status code is in the 2xx success range.
           */
          this.ok = false;
          // If the response was successful, then this was a parse error. Otherwise, it was
          // a protocol-level failure of some sort. Either the request failed in transit
          // or the server returned an unsuccessful status code.
          if (this.status >= 200 && this.status < 300) {
              this.message = `Http failure during parsing for ${init.url || '(unknown url)'}`;
          }
          else {
              this.message =
                  `Http failure response for ${init.url || '(unknown url)'}: ${init.status} ${init.statusText}`;
          }
          this.error = init.error || null;
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Construct an instance of `HttpRequestOptions<T>` from a source `HttpMethodOptions` and
   * the given `body`. Basically, this clones the object and adds the body.
   * @template T
   * @param {?} options
   * @param {?} body
   * @return {?}
   */
  function addBody(options, body) {
      return {
          body,
          headers: options.headers,
          observe: options.observe,
          params: options.params,
          reportProgress: options.reportProgress,
          responseType: options.responseType,
          withCredentials: options.withCredentials,
      };
  }
  /**
   * Perform HTTP requests.
   *
   * `HttpClient` is available as an injectable class, with methods to perform HTTP requests.
   * Each request method has multiple signatures, and the return type varies according to which
   * signature is called (mainly the values of `observe` and `responseType`).
   *
   *
   */
  class HttpClient {
      /**
       * @param {?} handler
       */
      constructor(handler) {
          this.handler = handler;
      }
      /**
       * Constructs an `Observable` for a particular HTTP request that, when subscribed,
       * fires the request through the chain of registered interceptors and on to the
       * server.
       *
       * This method can be called in one of two ways. Either an `HttpRequest`
       * instance can be passed directly as the only parameter, or a method can be
       * passed as the first parameter, a string URL as the second, and an
       * options hash as the third.
       *
       * If a `HttpRequest` object is passed directly, an `Observable` of the
       * raw `HttpEvent` stream will be returned.
       *
       * If a request is instead built by providing a URL, the options object
       * determines the return type of `request()`. In addition to configuring
       * request parameters such as the outgoing headers and/or the body, the options
       * hash specifies two key pieces of information about the request: the
       * `responseType` and what to `observe`.
       *
       * The `responseType` value determines how a successful response body will be
       * parsed. If `responseType` is the default `json`, a type interface for the
       * resulting object may be passed as a type parameter to `request()`.
       *
       * The `observe` value determines the return type of `request()`, based on what
       * the consumer is interested in observing. A value of `events` will return an
       * `Observable<HttpEvent>` representing the raw `HttpEvent` stream,
       * including progress events by default. A value of `response` will return an
       * `Observable<HttpResponse<T>>` where the `T` parameter of `HttpResponse`
       * depends on the `responseType` and any optionally provided type parameter.
       * A value of `body` will return an `Observable<T>` with the same `T` body type.
       * @param {?} first
       * @param {?=} url
       * @param {?=} options
       * @return {?}
       */
      request(first, url, options = {}) {
          let /** @type {?} */ req;
          // Firstly, check whether the primary argument is an instance of `HttpRequest`.
          if (first instanceof HttpRequest) {
              // It is. The other arguments must be undefined (per the signatures) and can be
              // ignored.
              req = /** @type {?} */ (first);
          }
          else {
              // It's a string, so it represents a URL. Construct a request based on it,
              // and incorporate the remaining arguments (assuming GET unless a method is
              // provided.
              // Figure out the headers.
              let /** @type {?} */ headers = undefined;
              if (options.headers instanceof HttpHeaders) {
                  headers = options.headers;
              }
              else {
                  headers = new HttpHeaders(options.headers);
              }
              // Sort out parameters.
              let /** @type {?} */ params = undefined;
              if (!!options.params) {
                  if (options.params instanceof HttpParams) {
                      params = options.params;
                  }
                  else {
                      params = new HttpParams(/** @type {?} */ ({ fromObject: options.params }));
                  }
              }
              // Construct the request.
              req = new HttpRequest(first, /** @type {?} */ ((url)), (options.body !== undefined ? options.body : null), {
                  headers,
                  params,
                  reportProgress: options.reportProgress,
                  // By default, JSON is assumed to be returned for all calls.
                  responseType: options.responseType || 'json',
                  withCredentials: options.withCredentials,
              });
          }
          // Start with an Observable.of() the initial request, and run the handler (which
          // includes all interceptors) inside a concatMap(). This way, the handler runs
          // inside an Observable chain, which causes interceptors to be re-run on every
          // subscription (this also makes retries re-run the handler, including interceptors).
          const /** @type {?} */ events$ = of(req).pipe(concatMap((req) => this.handler.handle(req)));
          // If coming via the API signature which accepts a previously constructed HttpRequest,
          // the only option is to get the event stream. Otherwise, return the event stream if
          // that is what was requested.
          if (first instanceof HttpRequest || options.observe === 'events') {
              return events$;
          }
          // The requested stream contains either the full response or the body. In either
          // case, the first step is to filter the event stream to extract a stream of
          // responses(s).
          const /** @type {?} */ res$ = /** @type {?} */ (events$.pipe(filter((event) => event instanceof HttpResponse)));
          // Decide which stream to return.
          switch (options.observe || 'body') {
              case 'body':
                  // The requested stream is the body. Map the response stream to the response
                  // body. This could be done more simply, but a misbehaving interceptor might
                  // transform the response body into a different format and ignore the requested
                  // responseType. Guard against this by validating that the response is of the
                  // requested type.
                  switch (req.responseType) {
                      case 'arraybuffer':
                          return res$.pipe(map((res) => {
                              // Validate that the body is an ArrayBuffer.
                              if (res.body !== null && !(res.body instanceof ArrayBuffer)) {
                                  throw new Error('Response is not an ArrayBuffer.');
                              }
                              return res.body;
                          }));
                      case 'blob':
                          return res$.pipe(map((res) => {
                              // Validate that the body is a Blob.
                              if (res.body !== null && !(res.body instanceof Blob)) {
                                  throw new Error('Response is not a Blob.');
                              }
                              return res.body;
                          }));
                      case 'text':
                          return res$.pipe(map((res) => {
                              // Validate that the body is a string.
                              if (res.body !== null && typeof res.body !== 'string') {
                                  throw new Error('Response is not a string.');
                              }
                              return res.body;
                          }));
                      case 'json':
                      default:
                          // No validation needed for JSON responses, as they can be of any type.
                          return res$.pipe(map((res) => res.body));
                  }
              case 'response':
                  // The response stream was requested directly, so return it.
                  return res$;
              default:
                  // Guard against new future observe types being added.
                  throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
          }
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * DELETE request to be executed on the server. See the individual overloads for
       * details of `delete()`'s return type based on the provided options.
       * @param {?} url
       * @param {?=} options
       * @return {?}
       */
      delete(url, options = {}) {
          return this.request('DELETE', url, /** @type {?} */ (options));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * GET request to be executed on the server. See the individual overloads for
       * details of `get()`'s return type based on the provided options.
       * @param {?} url
       * @param {?=} options
       * @return {?}
       */
      get(url, options = {}) {
          return this.request('GET', url, /** @type {?} */ (options));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * HEAD request to be executed on the server. See the individual overloads for
       * details of `head()`'s return type based on the provided options.
       * @param {?} url
       * @param {?=} options
       * @return {?}
       */
      head(url, options = {}) {
          return this.request('HEAD', url, /** @type {?} */ (options));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause a request
       * with the special method `JSONP` to be dispatched via the interceptor pipeline.
       *
       * A suitable interceptor must be installed (e.g. via the `HttpClientJsonpModule`).
       * If no such interceptor is reached, then the `JSONP` request will likely be
       * rejected by the configured backend.
       * @template T
       * @param {?} url
       * @param {?} callbackParam
       * @return {?}
       */
      jsonp(url, callbackParam) {
          return this.request('JSONP', url, {
              params: new HttpParams().append(callbackParam, 'JSONP_CALLBACK'),
              observe: 'body',
              responseType: 'json',
          });
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * OPTIONS request to be executed on the server. See the individual overloads for
       * details of `options()`'s return type based on the provided options.
       * @param {?} url
       * @param {?=} options
       * @return {?}
       */
      options(url, options = {}) {
          return this.request('OPTIONS', url, /** @type {?} */ (options));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * PATCH request to be executed on the server. See the individual overloads for
       * details of `patch()`'s return type based on the provided options.
       * @param {?} url
       * @param {?} body
       * @param {?=} options
       * @return {?}
       */
      patch(url, body, options = {}) {
          return this.request('PATCH', url, addBody(options, body));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * POST request to be executed on the server. See the individual overloads for
       * details of `post()`'s return type based on the provided options.
       * @param {?} url
       * @param {?} body
       * @param {?=} options
       * @return {?}
       */
      post(url, body, options = {}) {
          return this.request('POST', url, addBody(options, body));
      }
      /**
       * Constructs an `Observable` which, when subscribed, will cause the configured
       * POST request to be executed on the server. See the individual overloads for
       * details of `post()`'s return type based on the provided options.
       * @param {?} url
       * @param {?} body
       * @param {?=} options
       * @return {?}
       */
      put(url, body, options = {}) {
          return this.request('PUT', url, addBody(options, body));
      }
  }
  HttpClient.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  HttpClient.ctorParameters = () => [
      { type: HttpHandler, },
  ];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Intercepts `HttpRequest` and handles them.
   *
   * Most interceptors will transform the outgoing request before passing it to the
   * next interceptor in the chain, by calling `next.handle(transformedReq)`.
   *
   * In rare cases, interceptors may wish to completely handle a request themselves,
   * and not delegate to the remainder of the chain. This behavior is allowed.
   *
   *
   * @record
   */
  
  /**
   * `HttpHandler` which applies an `HttpInterceptor` to an `HttpRequest`.
   *
   *
   */
  class HttpInterceptorHandler {
      /**
       * @param {?} next
       * @param {?} interceptor
       */
      constructor(next, interceptor) {
          this.next = next;
          this.interceptor = interceptor;
      }
      /**
       * @param {?} req
       * @return {?}
       */
      handle(req) {
          return this.interceptor.intercept(req, this.next);
      }
  }
  /**
   * A multi-provider token which represents the array of `HttpInterceptor`s that
   * are registered.
   *
   *
   */
  const HTTP_INTERCEPTORS = new InjectionToken('HTTP_INTERCEPTORS');
  class NoopInterceptor {
      /**
       * @param {?} req
       * @param {?} next
       * @return {?}
       */
      intercept(req, next) {
          return next.handle(req);
      }
  }
  NoopInterceptor.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  NoopInterceptor.ctorParameters = () => [];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  // Every request made through JSONP needs a callback name that's unique across the
  // whole page. Each request is assigned an id and the callback name is constructed
  // from that. The next id to be assigned is tracked in a global variable here that
  // is shared among all applications on the page.
  let nextRequestId = 0;
  // Error text given when a JSONP script is injected, but doesn't invoke the callback
  // passed in its URL.
  const JSONP_ERR_NO_CALLBACK = 'JSONP injected script did not invoke callback.';
  // Error text given when a request is passed to the JsonpClientBackend that doesn't
  // have a request method JSONP.
  const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use JSONP request method.';
  const JSONP_ERR_WRONG_RESPONSE_TYPE = 'JSONP requests must use Json response type.';
  /**
   * DI token/abstract type representing a map of JSONP callbacks.
   *
   * In the browser, this should always be the `window` object.
   *
   *
   * @abstract
   */
  class JsonpCallbackContext {
  }
  /**
   * `HttpBackend` that only processes `HttpRequest` with the JSONP method,
   * by performing JSONP style requests.
   *
   *
   */
  class JsonpClientBackend {
      /**
       * @param {?} callbackMap
       * @param {?} document
       */
      constructor(callbackMap, document) {
          this.callbackMap = callbackMap;
          this.document = document;
      }
      /**
       * Get the name of the next callback method, by incrementing the global `nextRequestId`.
       * @return {?}
       */
      nextCallback() { return `ng_jsonp_callback_${nextRequestId++}`; }
      /**
       * Process a JSONP request and return an event stream of the results.
       * @param {?} req
       * @return {?}
       */
      handle(req) {
          // Firstly, check both the method and response type. If either doesn't match
          // then the request was improperly routed here and cannot be handled.
          if (req.method !== 'JSONP') {
              throw new Error(JSONP_ERR_WRONG_METHOD);
          }
          else if (req.responseType !== 'json') {
              throw new Error(JSONP_ERR_WRONG_RESPONSE_TYPE);
          }
          // Everything else happens inside the Observable boundary.
          return new Observable((observer) => {
              // The first step to make a request is to generate the callback name, and replace the
              // callback placeholder in the URL with the name. Care has to be taken here to ensure
              // a trailing &, if matched, gets inserted back into the URL in the correct place.
              const /** @type {?} */ callback = this.nextCallback();
              const /** @type {?} */ url = req.urlWithParams.replace(/=JSONP_CALLBACK(&|$)/, `=${callback}$1`);
              // Construct the <script> tag and point it at the URL.
              const /** @type {?} */ node = this.document.createElement('script');
              node.src = url;
              // A JSONP request requires waiting for multiple callbacks. These variables
              // are closed over and track state across those callbacks.
              // The response object, if one has been received, or null otherwise.
              let /** @type {?} */ body = null;
              // Whether the response callback has been called.
              let /** @type {?} */ finished = false;
              // Whether the request has been cancelled (and thus any other callbacks)
              // should be ignored.
              let /** @type {?} */ cancelled = false;
              // Set the response callback in this.callbackMap (which will be the window
              // object in the browser. The script being loaded via the <script> tag will
              // eventually call this callback.
              this.callbackMap[callback] = (data) => {
                  // Data has been received from the JSONP script. Firstly, delete this callback.
                  delete this.callbackMap[callback];
                  // Next, make sure the request wasn't cancelled in the meantime.
                  if (cancelled) {
                      return;
                  }
                  // Set state to indicate data was received.
                  body = data;
                  finished = true;
              };
              // cleanup() is a utility closure that removes the <script> from the page and
              // the response callback from the window. This logic is used in both the
              // success, error, and cancellation paths, so it's extracted out for convenience.
              const /** @type {?} */ cleanup = () => {
                  // Remove the <script> tag if it's still on the page.
                  if (node.parentNode) {
                      node.parentNode.removeChild(node);
                  }
                  // Remove the response callback from the callbackMap (window object in the
                  // browser).
                  delete this.callbackMap[callback];
              };
              // onLoad() is the success callback which runs after the response callback
              // if the JSONP script loads successfully. The event itself is unimportant.
              // If something went wrong, onLoad() may run without the response callback
              // having been invoked.
              const /** @type {?} */ onLoad = (event) => {
                  // Do nothing if the request has been cancelled.
                  if (cancelled) {
                      return;
                  }
                  // Cleanup the page.
                  cleanup();
                  // Check whether the response callback has run.
                  if (!finished) {
                      // It hasn't, something went wrong with the request. Return an error via
                      // the Observable error path. All JSONP errors have status 0.
                      observer.error(new HttpErrorResponse({
                          url,
                          status: 0,
                          statusText: 'JSONP Error',
                          error: new Error(JSONP_ERR_NO_CALLBACK),
                      }));
                      return;
                  }
                  // Success. body either contains the response body or null if none was
                  // returned.
                  observer.next(new HttpResponse({
                      body,
                      status: 200,
                      statusText: 'OK', url,
                  }));
                  // Complete the stream, the response is over.
                  observer.complete();
              };
              // onError() is the error callback, which runs if the script returned generates
              // a Javascript error. It emits the error via the Observable error channel as
              // a HttpErrorResponse.
              const /** @type {?} */ onError = (error) => {
                  // If the request was already cancelled, no need to emit anything.
                  if (cancelled) {
                      return;
                  }
                  cleanup();
                  // Wrap the error in a HttpErrorResponse.
                  observer.error(new HttpErrorResponse({
                      error,
                      status: 0,
                      statusText: 'JSONP Error', url,
                  }));
              };
              // Subscribe to both the success (load) and error events on the <script> tag,
              // and add it to the page.
              node.addEventListener('load', onLoad);
              node.addEventListener('error', onError);
              this.document.body.appendChild(node);
              // The request has now been successfully sent.
              observer.next({ type: HttpEventType.Sent });
              // Cancellation handler.
              return () => {
                  // Track the cancellation so event listeners won't do anything even if already scheduled.
                  cancelled = true;
                  // Remove the event listeners so they won't run if the events later fire.
                  node.removeEventListener('load', onLoad);
                  node.removeEventListener('error', onError);
                  // And finally, clean up the page.
                  cleanup();
              };
          });
      }
  }
  JsonpClientBackend.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  JsonpClientBackend.ctorParameters = () => [
      { type: JsonpCallbackContext, },
      { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] },
  ];
  /**
   * An `HttpInterceptor` which identifies requests with the method JSONP and
   * shifts them to the `JsonpClientBackend`.
   *
   *
   */
  class JsonpInterceptor {
      /**
       * @param {?} jsonp
       */
      constructor(jsonp) {
          this.jsonp = jsonp;
      }
      /**
       * @param {?} req
       * @param {?} next
       * @return {?}
       */
      intercept(req, next) {
          if (req.method === 'JSONP') {
              return this.jsonp.handle(/** @type {?} */ (req));
          }
          // Fall through for normal HTTP requests.
          return next.handle(req);
      }
  }
  JsonpInterceptor.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  JsonpInterceptor.ctorParameters = () => [
      { type: JsonpClientBackend, },
  ];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  const XSSI_PREFIX = /^\)\]\}',?\n/;
  /**
   * Determine an appropriate URL for the response, by checking either
   * XMLHttpRequest.responseURL or the X-Request-URL header.
   * @param {?} xhr
   * @return {?}
   */
  function getResponseUrl(xhr) {
      if ('responseURL' in xhr && xhr.responseURL) {
          return xhr.responseURL;
      }
      if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
          return xhr.getResponseHeader('X-Request-URL');
      }
      return null;
  }
  /**
   * A wrapper around the `XMLHttpRequest` constructor.
   *
   *
   * @abstract
   */
  class XhrFactory {
  }
  /**
   * A factory for \@{link HttpXhrBackend} that uses the `XMLHttpRequest` browser API.
   *
   *
   */
  class BrowserXhr {
      constructor() { }
      /**
       * @return {?}
       */
      build() { return /** @type {?} */ ((new XMLHttpRequest())); }
  }
  BrowserXhr.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  BrowserXhr.ctorParameters = () => [];
  /**
   * An `HttpBackend` which uses the XMLHttpRequest API to send
   * requests to a backend server.
   *
   *
   */
  class HttpXhrBackend {
      /**
       * @param {?} xhrFactory
       */
      constructor(xhrFactory) {
          this.xhrFactory = xhrFactory;
      }
      /**
       * Process a request and return a stream of response events.
       * @param {?} req
       * @return {?}
       */
      handle(req) {
          // Quick check to give a better error message when a user attempts to use
          // HttpClient.jsonp() without installing the JsonpClientModule
          if (req.method === 'JSONP') {
              throw new Error(`Attempted to construct Jsonp request without JsonpClientModule installed.`);
          }
          // Everything happens on Observable subscription.
          return new Observable((observer) => {
              // Start by setting up the XHR object with request method, URL, and withCredentials flag.
              const /** @type {?} */ xhr = this.xhrFactory.build();
              xhr.open(req.method, req.urlWithParams);
              if (!!req.withCredentials) {
                  xhr.withCredentials = true;
              }
              // Add all the requested headers.
              req.headers.forEach((name, values) => xhr.setRequestHeader(name, values.join(',')));
              // Add an Accept header if one isn't present already.
              if (!req.headers.has('Accept')) {
                  xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
              }
              // Auto-detect the Content-Type header if one isn't present already.
              if (!req.headers.has('Content-Type')) {
                  const /** @type {?} */ detectedType = req.detectContentTypeHeader();
                  // Sometimes Content-Type detection fails.
                  if (detectedType !== null) {
                      xhr.setRequestHeader('Content-Type', detectedType);
                  }
              }
              // Set the responseType if one was requested.
              if (req.responseType) {
                  const /** @type {?} */ responseType = req.responseType.toLowerCase();
                  // JSON responses need to be processed as text. This is because if the server
                  // returns an XSSI-prefixed JSON response, the browser will fail to parse it,
                  // xhr.response will be null, and xhr.responseText cannot be accessed to
                  // retrieve the prefixed JSON data in order to strip the prefix. Thus, all JSON
                  // is parsed by first requesting text and then applying JSON.parse.
                  xhr.responseType = /** @type {?} */ (((responseType !== 'json') ? responseType : 'text'));
              }
              // Serialize the request body if one is present. If not, this will be set to null.
              const /** @type {?} */ reqBody = req.serializeBody();
              // If progress events are enabled, response headers will be delivered
              // in two events - the HttpHeaderResponse event and the full HttpResponse
              // event. However, since response headers don't change in between these
              // two events, it doesn't make sense to parse them twice. So headerResponse
              // caches the data extracted from the response whenever it's first parsed,
              // to ensure parsing isn't duplicated.
              let /** @type {?} */ headerResponse = null;
              // partialFromXhr extracts the HttpHeaderResponse from the current XMLHttpRequest
              // state, and memoizes it into headerResponse.
              const /** @type {?} */ partialFromXhr = () => {
                  if (headerResponse !== null) {
                      return headerResponse;
                  }
                  // Read status and normalize an IE9 bug (http://bugs.jquery.com/ticket/1450).
                  const /** @type {?} */ status = xhr.status === 1223 ? 204 : xhr.status;
                  const /** @type {?} */ statusText = xhr.statusText || 'OK';
                  // Parse headers from XMLHttpRequest - this step is lazy.
                  const /** @type {?} */ headers = new HttpHeaders(xhr.getAllResponseHeaders());
                  // Read the response URL from the XMLHttpResponse instance and fall back on the
                  // request URL.
                  const /** @type {?} */ url = getResponseUrl(xhr) || req.url;
                  // Construct the HttpHeaderResponse and memoize it.
                  headerResponse = new HttpHeaderResponse({ headers, status, statusText, url });
                  return headerResponse;
              };
              // Next, a few closures are defined for the various events which XMLHttpRequest can
              // emit. This allows them to be unregistered as event listeners later.
              // First up is the load event, which represents a response being fully available.
              const /** @type {?} */ onLoad = () => {
                  // Read response state from the memoized partial data.
                  let { headers, status, statusText, url } = partialFromXhr();
                  // The body will be read out if present.
                  let /** @type {?} */ body = null;
                  if (status !== 204) {
                      // Use XMLHttpRequest.response if set, responseText otherwise.
                      body = (typeof xhr.response === 'undefined') ? xhr.responseText : xhr.response;
                  }
                  // Normalize another potential bug (this one comes from CORS).
                  if (status === 0) {
                      status = !!body ? 200 : 0;
                  }
                  // ok determines whether the response will be transmitted on the event or
                  // error channel. Unsuccessful status codes (not 2xx) will always be errors,
                  // but a successful status code can still result in an error if the user
                  // asked for JSON data and the body cannot be parsed as such.
                  let /** @type {?} */ ok = status >= 200 && status < 300;
                  // Check whether the body needs to be parsed as JSON (in many cases the browser
                  // will have done that already).
                  if (req.responseType === 'json' && typeof body === 'string') {
                      // Save the original body, before attempting XSSI prefix stripping.
                      const /** @type {?} */ originalBody = body;
                      body = body.replace(XSSI_PREFIX, '');
                      try {
                          // Attempt the parse. If it fails, a parse error should be delivered to the user.
                          body = body !== '' ? JSON.parse(body) : null;
                      }
                      catch (/** @type {?} */ error) {
                          // Since the JSON.parse failed, it's reasonable to assume this might not have been a
                          // JSON response. Restore the original body (including any XSSI prefix) to deliver
                          // a better error response.
                          body = originalBody;
                          // If this was an error request to begin with, leave it as a string, it probably
                          // just isn't JSON. Otherwise, deliver the parsing error to the user.
                          if (ok) {
                              // Even though the response status was 2xx, this is still an error.
                              ok = false;
                              // The parse error contains the text of the body that failed to parse.
                              body = /** @type {?} */ ({ error, text: body });
                          }
                      }
                  }
                  if (ok) {
                      // A successful response is delivered on the event stream.
                      observer.next(new HttpResponse({
                          body,
                          headers,
                          status,
                          statusText,
                          url: url || undefined,
                      }));
                      // The full body has been received and delivered, no further events
                      // are possible. This request is complete.
                      observer.complete();
                  }
                  else {
                      // An unsuccessful request is delivered on the error channel.
                      observer.error(new HttpErrorResponse({
                          // The error in this case is the response body (error from the server).
                          error: body,
                          headers,
                          status,
                          statusText,
                          url: url || undefined,
                      }));
                  }
              };
              // The onError callback is called when something goes wrong at the network level.
              // Connection timeout, DNS error, offline, etc. These are actual errors, and are
              // transmitted on the error channel.
              const /** @type {?} */ onError = (error) => {
                  const /** @type {?} */ res = new HttpErrorResponse({
                      error,
                      status: xhr.status || 0,
                      statusText: xhr.statusText || 'Unknown Error',
                  });
                  observer.error(res);
              };
              // The sentHeaders flag tracks whether the HttpResponseHeaders event
              // has been sent on the stream. This is necessary to track if progress
              // is enabled since the event will be sent on only the first download
              // progerss event.
              let /** @type {?} */ sentHeaders = false;
              // The download progress event handler, which is only registered if
              // progress events are enabled.
              const /** @type {?} */ onDownProgress = (event) => {
                  // Send the HttpResponseHeaders event if it hasn't been sent already.
                  if (!sentHeaders) {
                      observer.next(partialFromXhr());
                      sentHeaders = true;
                  }
                  // Start building the download progress event to deliver on the response
                  // event stream.
                  let /** @type {?} */ progressEvent = {
                      type: HttpEventType.DownloadProgress,
                      loaded: event.loaded,
                  };
                  // Set the total number of bytes in the event if it's available.
                  if (event.lengthComputable) {
                      progressEvent.total = event.total;
                  }
                  // If the request was for text content and a partial response is
                  // available on XMLHttpRequest, include it in the progress event
                  // to allow for streaming reads.
                  if (req.responseType === 'text' && !!xhr.responseText) {
                      progressEvent.partialText = xhr.responseText;
                  }
                  // Finally, fire the event.
                  observer.next(progressEvent);
              };
              // The upload progress event handler, which is only registered if
              // progress events are enabled.
              const /** @type {?} */ onUpProgress = (event) => {
                  // Upload progress events are simpler. Begin building the progress
                  // event.
                  let /** @type {?} */ progress = {
                      type: HttpEventType.UploadProgress,
                      loaded: event.loaded,
                  };
                  // If the total number of bytes being uploaded is available, include
                  // it.
                  if (event.lengthComputable) {
                      progress.total = event.total;
                  }
                  // Send the event.
                  observer.next(progress);
              };
              // By default, register for load and error events.
              xhr.addEventListener('load', onLoad);
              xhr.addEventListener('error', onError);
              // Progress events are only enabled if requested.
              if (req.reportProgress) {
                  // Download progress is always enabled if requested.
                  xhr.addEventListener('progress', onDownProgress);
                  // Upload progress depends on whether there is a body to upload.
                  if (reqBody !== null && xhr.upload) {
                      xhr.upload.addEventListener('progress', onUpProgress);
                  }
              }
              // Fire the request, and notify the event stream that it was fired.
              xhr.send(reqBody);
              observer.next({ type: HttpEventType.Sent });
              // This is the return from the Observable function, which is the
              // request cancellation handler.
              return () => {
                  // On a cancellation, remove all registered event listeners.
                  xhr.removeEventListener('error', onError);
                  xhr.removeEventListener('load', onLoad);
                  if (req.reportProgress) {
                      xhr.removeEventListener('progress', onDownProgress);
                      if (reqBody !== null && xhr.upload) {
                          xhr.upload.removeEventListener('progress', onUpProgress);
                      }
                  }
                  // Finally, abort the in-flight request.
                  xhr.abort();
              };
          });
      }
  }
  HttpXhrBackend.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  HttpXhrBackend.ctorParameters = () => [
      { type: XhrFactory, },
  ];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  const XSRF_COOKIE_NAME = new InjectionToken('XSRF_COOKIE_NAME');
  const XSRF_HEADER_NAME = new InjectionToken('XSRF_HEADER_NAME');
  /**
   * Retrieves the current XSRF token to use with the next outgoing request.
   *
   *
   * @abstract
   */
  class HttpXsrfTokenExtractor {
  }
  /**
   * `HttpXsrfTokenExtractor` which retrieves the token from a cookie.
   */
  class HttpXsrfCookieExtractor {
      /**
       * @param {?} doc
       * @param {?} platform
       * @param {?} cookieName
       */
      constructor(doc, platform, cookieName) {
          this.doc = doc;
          this.platform = platform;
          this.cookieName = cookieName;
          this.lastCookieString = '';
          this.lastToken = null;
          /**
           * \@internal for testing
           */
          this.parseCount = 0;
      }
      /**
       * @return {?}
       */
      getToken() {
          if (this.platform === 'server') {
              return null;
          }
          const /** @type {?} */ cookieString = this.doc.cookie || '';
          if (cookieString !== this.lastCookieString) {
              this.parseCount++;
              this.lastToken = ɵparseCookieValue(cookieString, this.cookieName);
              this.lastCookieString = cookieString;
          }
          return this.lastToken;
      }
  }
  HttpXsrfCookieExtractor.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  HttpXsrfCookieExtractor.ctorParameters = () => [
      { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] },
      { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] },] },
      { type: undefined, decorators: [{ type: Inject, args: [XSRF_COOKIE_NAME,] },] },
  ];
  /**
   * `HttpInterceptor` which adds an XSRF token to eligible outgoing requests.
   */
  class HttpXsrfInterceptor {
      /**
       * @param {?} tokenService
       * @param {?} headerName
       */
      constructor(tokenService, headerName) {
          this.tokenService = tokenService;
          this.headerName = headerName;
      }
      /**
       * @param {?} req
       * @param {?} next
       * @return {?}
       */
      intercept(req, next) {
          const /** @type {?} */ lcUrl = req.url.toLowerCase();
          // Skip both non-mutating requests and absolute URLs.
          // Non-mutating requests don't require a token, and absolute URLs require special handling
          // anyway as the cookie set
          // on our origin is not the same as the token expected by another origin.
          if (req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') ||
              lcUrl.startsWith('https://')) {
              return next.handle(req);
          }
          const /** @type {?} */ token = this.tokenService.getToken();
          // Be careful not to overwrite an existing header of the same name.
          if (token !== null && !req.headers.has(this.headerName)) {
              req = req.clone({ headers: req.headers.set(this.headerName, token) });
          }
          return next.handle(req);
      }
  }
  HttpXsrfInterceptor.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  HttpXsrfInterceptor.ctorParameters = () => [
      { type: HttpXsrfTokenExtractor, },
      { type: undefined, decorators: [{ type: Inject, args: [XSRF_HEADER_NAME,] },] },
  ];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * An `HttpHandler` that applies a bunch of `HttpInterceptor`s
   * to a request before passing it to the given `HttpBackend`.
   *
   * The interceptors are loaded lazily from the injector, to allow
   * interceptors to themselves inject classes depending indirectly
   * on `HttpInterceptingHandler` itself.
   */
  class HttpInterceptingHandler {
      /**
       * @param {?} backend
       * @param {?} injector
       */
      constructor(backend, injector) {
          this.backend = backend;
          this.injector = injector;
          this.chain = null;
      }
      /**
       * @param {?} req
       * @return {?}
       */
      handle(req) {
          if (this.chain === null) {
              const /** @type {?} */ interceptors = this.injector.get(HTTP_INTERCEPTORS, []);
              this.chain = interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), this.backend);
          }
          return this.chain.handle(req);
      }
  }
  HttpInterceptingHandler.decorators = [
      { type: Injectable }
  ];
  /** @nocollapse */
  HttpInterceptingHandler.ctorParameters = () => [
      { type: HttpBackend, },
      { type: Injector, },
  ];
  /**
   * Constructs an `HttpHandler` that applies a bunch of `HttpInterceptor`s
   * to a request before passing it to the given `HttpBackend`.
   *
   * Meant to be used as a factory function within `HttpClientModule`.
   *
   *
   * @param {?} backend
   * @param {?=} interceptors
   * @return {?}
   */
  function interceptingHandler(backend, interceptors = []) {
      if (!interceptors) {
          return backend;
      }
      return interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), backend);
  }
  /**
   * Factory function that determines where to store JSONP callbacks.
   *
   * Ordinarily JSONP callbacks are stored on the `window` object, but this may not exist
   * in test environments. In that case, callbacks are stored on an anonymous object instead.
   *
   *
   * @return {?}
   */
  function jsonpCallbackContext() {
      if (typeof window === 'object') {
          return window;
      }
      return {};
  }
  /**
   * `NgModule` which adds XSRF protection support to outgoing requests.
   *
   * Provided the server supports a cookie-based XSRF protection system, this
   * module can be used directly to configure XSRF protection with the correct
   * cookie and header names.
   *
   * If no such names are provided, the default is to use `X-XSRF-TOKEN` for
   * the header name and `XSRF-TOKEN` for the cookie name.
   *
   *
   */
  class HttpClientXsrfModule {
      /**
       * Disable the default XSRF protection.
       * @return {?}
       */
      static disable() {
          return {
              ngModule: HttpClientXsrfModule,
              providers: [
                  { provide: HttpXsrfInterceptor, useClass: NoopInterceptor },
              ],
          };
      }
      /**
       * Configure XSRF protection to use the given cookie name or header name,
       * or the default names (as described above) if not provided.
       * @param {?=} options
       * @return {?}
       */
      static withOptions(options = {}) {
          return {
              ngModule: HttpClientXsrfModule,
              providers: [
                  options.cookieName ? { provide: XSRF_COOKIE_NAME, useValue: options.cookieName } : [],
                  options.headerName ? { provide: XSRF_HEADER_NAME, useValue: options.headerName } : [],
              ],
          };
      }
  }
  HttpClientXsrfModule.decorators = [
      { type: NgModule, args: [{
                  providers: [
                      HttpXsrfInterceptor,
                      { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
                      { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
                      { provide: XSRF_COOKIE_NAME, useValue: 'XSRF-TOKEN' },
                      { provide: XSRF_HEADER_NAME, useValue: 'X-XSRF-TOKEN' },
                  ],
              },] }
  ];
  /** @nocollapse */
  HttpClientXsrfModule.ctorParameters = () => [];
  /**
   * `NgModule` which provides the `HttpClient` and associated services.
   *
   * Interceptors can be added to the chain behind `HttpClient` by binding them
   * to the multiprovider for `HTTP_INTERCEPTORS`.
   *
   *
   */
  class HttpClientModule {
  }
  HttpClientModule.decorators = [
      { type: NgModule, args: [{
                  imports: [
                      HttpClientXsrfModule.withOptions({
                          cookieName: 'XSRF-TOKEN',
                          headerName: 'X-XSRF-TOKEN',
                      }),
                  ],
                  providers: [
                      HttpClient,
                      { provide: HttpHandler, useClass: HttpInterceptingHandler },
                      HttpXhrBackend,
                      { provide: HttpBackend, useExisting: HttpXhrBackend },
                      BrowserXhr,
                      { provide: XhrFactory, useExisting: BrowserXhr },
                  ],
              },] }
  ];
  /** @nocollapse */
  HttpClientModule.ctorParameters = () => [];
  /**
   * `NgModule` which enables JSONP support in `HttpClient`.
   *
   * Without this module, Jsonp requests will reach the backend
   * with method JSONP, where they'll be rejected.
   *
   *
   */
  class HttpClientJsonpModule {
  }
  HttpClientJsonpModule.decorators = [
      { type: NgModule, args: [{
                  providers: [
                      JsonpClientBackend,
                      { provide: JsonpCallbackContext, useFactory: jsonpCallbackContext },
                      { provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true },
                  ],
              },] }
  ];
  /** @nocollapse */
  HttpClientJsonpModule.ctorParameters = () => [];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  // This file is not used to build this module. It is only used during editing
  // by the TypeScript language service and during build for verification. `ngc`
  // replaces this file with production index.ts when it rewrites private symbol
  // names.
  
  /**
   * Generated bundle index. Do not edit.
   */
  
  export { NoopInterceptor as ɵangular_packages_common_http_http_a, JsonpCallbackContext as ɵangular_packages_common_http_http_b, HttpInterceptingHandler as ɵangular_packages_common_http_http_c, jsonpCallbackContext as ɵangular_packages_common_http_http_d, BrowserXhr as ɵangular_packages_common_http_http_e, HttpXsrfCookieExtractor as ɵangular_packages_common_http_http_h, HttpXsrfInterceptor as ɵangular_packages_common_http_http_i, XSRF_COOKIE_NAME as ɵangular_packages_common_http_http_f, XSRF_HEADER_NAME as ɵangular_packages_common_http_http_g, HttpBackend, HttpHandler, HttpClient, HttpHeaders, HTTP_INTERCEPTORS, JsonpClientBackend, JsonpInterceptor, HttpClientJsonpModule, HttpClientModule, HttpClientXsrfModule, interceptingHandler as ɵinterceptingHandler, HttpParams, HttpUrlEncodingCodec, HttpRequest, HttpErrorResponse, HttpEventType, HttpHeaderResponse, HttpResponse, HttpResponseBase, HttpXhrBackend, XhrFactory, HttpXsrfTokenExtractor };
  //# sourceMappingURL=http.js.map
  