{"ast":null,"code":"/**\n * @license Angular v17.3.11\n * (c) 2010-2024 Google LLC. https://angular.io/\n * License: MIT\n */\n\nimport * as i0 from '@angular/core';\nimport { ɵglobal, ɵRuntimeError, Injectable, InjectionToken, Inject, APP_ID, CSP_NONCE, PLATFORM_ID, Optional, ViewEncapsulation, RendererStyleFlags2, ɵinternalCreateApplication, ErrorHandler, ɵsetDocument, PLATFORM_INITIALIZER, createPlatformFactory, platformCore, ɵTESTABILITY_GETTER, ɵTESTABILITY, Testability, NgZone, TestabilityRegistry, ɵINJECTOR_SCOPE, RendererFactory2, ApplicationModule, NgModule, SkipSelf, ApplicationRef, ɵConsole, forwardRef, ɵXSS_SECURITY_URL, SecurityContext, ɵallowSanitizationBypassAndThrow, ɵunwrapSafeValue, ɵ_sanitizeUrl, ɵ_sanitizeHtml, ɵbypassSanitizationTrustHtml, ɵbypassSanitizationTrustStyle, ɵbypassSanitizationTrustScript, ɵbypassSanitizationTrustUrl, ɵbypassSanitizationTrustResourceUrl, ENVIRONMENT_INITIALIZER, inject, ɵformatRuntimeError, makeEnvironmentProviders, ɵwithDomHydration, Version, makeStateKey as makeStateKey$1, TransferState as TransferState$1 } from '@angular/core';\nimport { ɵDomAdapter, ɵsetRootDomAdapter, ɵparseCookieValue, ɵgetDOM, isPlatformServer, DOCUMENT, ɵPLATFORM_BROWSER_ID, XhrFactory, CommonModule } from '@angular/common';\nexport { ɵgetDOM } from '@angular/common';\nimport { ɵwithHttpTransferCache } from '@angular/common/http';\n\n/**\n * Provides DOM operations in any browser environment.\n *\n * @security Tread carefully! Interacting with the DOM directly is dangerous and\n * can introduce XSS risks.\n */\nclass GenericBrowserDomAdapter extends ɵDomAdapter {\n  constructor() {\n    super(...arguments);\n    this.supportsDOMEvents = true;\n  }\n}\n\n/**\n * A `DomAdapter` powered by full browser DOM APIs.\n *\n * @security Tread carefully! Interacting with the DOM directly is dangerous and\n * can introduce XSS risks.\n */\n/* tslint:disable:requireParameterType no-console */\nclass BrowserDomAdapter extends GenericBrowserDomAdapter {\n  static makeCurrent() {\n    ɵsetRootDomAdapter(new BrowserDomAdapter());\n  }\n  onAndCancel(el, evt, listener) {\n    el.addEventListener(evt, listener);\n    return () => {\n      el.removeEventListener(evt, listener);\n    };\n  }\n  dispatchEvent(el, evt) {\n    el.dispatchEvent(evt);\n  }\n  remove(node) {\n    if (node.parentNode) {\n      node.parentNode.removeChild(node);\n    }\n  }\n  createElement(tagName, doc) {\n    doc = doc || this.getDefaultDocument();\n    return doc.createElement(tagName);\n  }\n  createHtmlDocument() {\n    return document.implementation.createHTMLDocument('fakeTitle');\n  }\n  getDefaultDocument() {\n    return document;\n  }\n  isElementNode(node) {\n    return node.nodeType === Node.ELEMENT_NODE;\n  }\n  isShadowRoot(node) {\n    return node instanceof DocumentFragment;\n  }\n  /** @deprecated No longer being used in Ivy code. To be removed in version 14. */\n  getGlobalEventTarget(doc, target) {\n    if (target === 'window') {\n      return window;\n    }\n    if (target === 'document') {\n      return doc;\n    }\n    if (target === 'body') {\n      return doc.body;\n    }\n    return null;\n  }\n  getBaseHref(doc) {\n    const href = getBaseElementHref();\n    return href == null ? null : relativePath(href);\n  }\n  resetBaseElement() {\n    baseElement = null;\n  }\n  getUserAgent() {\n    return window.navigator.userAgent;\n  }\n  getCookie(name) {\n    return ɵparseCookieValue(document.cookie, name);\n  }\n}\nlet baseElement = null;\nfunction getBaseElementHref() {\n  baseElement = baseElement || document.querySelector('base');\n  return baseElement ? baseElement.getAttribute('href') : null;\n}\nfunction relativePath(url) {\n  // The base URL doesn't really matter, we just need it so relative paths have something\n  // to resolve against. In the browser `HTMLBaseElement.href` is always absolute.\n  return new URL(url, document.baseURI).pathname;\n}\nclass BrowserGetTestability {\n  addToWindow(registry) {\n    ɵglobal['getAngularTestability'] = (elem, findInAncestors = true) => {\n      const testability = registry.findTestabilityInTree(elem, findInAncestors);\n      if (testability == null) {\n        throw new ɵRuntimeError(5103 /* RuntimeErrorCode.TESTABILITY_NOT_FOUND */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Could not find testability for element.');\n      }\n      return testability;\n    };\n    ɵglobal['getAllAngularTestabilities'] = () => registry.getAllTestabilities();\n    ɵglobal['getAllAngularRootElements'] = () => registry.getAllRootElements();\n    const whenAllStable = callback => {\n      const testabilities = ɵglobal['getAllAngularTestabilities']();\n      let count = testabilities.length;\n      const decrement = function () {\n        count--;\n        if (count == 0) {\n          callback();\n        }\n      };\n      testabilities.forEach(testability => {\n        testability.whenStable(decrement);\n      });\n    };\n    if (!ɵglobal['frameworkStabilizers']) {\n      ɵglobal['frameworkStabilizers'] = [];\n    }\n    ɵglobal['frameworkStabilizers'].push(whenAllStable);\n  }\n  findTestabilityInTree(registry, elem, findInAncestors) {\n    if (elem == null) {\n      return null;\n    }\n    const t = registry.getTestability(elem);\n    if (t != null) {\n      return t;\n    } else if (!findInAncestors) {\n      return null;\n    }\n    if (ɵgetDOM().isShadowRoot(elem)) {\n      return this.findTestabilityInTree(registry, elem.host, true);\n    }\n    return this.findTestabilityInTree(registry, elem.parentElement, true);\n  }\n}\n\n/**\n * A factory for `HttpXhrBackend` that uses the `XMLHttpRequest` browser API.\n */\nlet BrowserXhr = /*#__PURE__*/(() => {\n  class BrowserXhr {\n    build() {\n      return new XMLHttpRequest();\n    }\n    static #_ = this.ɵfac = function BrowserXhr_Factory(t) {\n      return new (t || BrowserXhr)();\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: BrowserXhr,\n      factory: BrowserXhr.ɵfac\n    });\n  }\n  return BrowserXhr;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * The injection token for plugins of the `EventManager` service.\n *\n * @publicApi\n */\nconst EVENT_MANAGER_PLUGINS = /*#__PURE__*/new InjectionToken(ngDevMode ? 'EventManagerPlugins' : '');\n/**\n * An injectable service that provides event management for Angular\n * through a browser plug-in.\n *\n * @publicApi\n */\nlet EventManager = /*#__PURE__*/(() => {\n  class EventManager {\n    /**\n     * Initializes an instance of the event-manager service.\n     */\n    constructor(plugins, _zone) {\n      this._zone = _zone;\n      this._eventNameToPlugin = new Map();\n      plugins.forEach(plugin => {\n        plugin.manager = this;\n      });\n      this._plugins = plugins.slice().reverse();\n    }\n    /**\n     * Registers a handler for a specific element and event.\n     *\n     * @param element The HTML element to receive event notifications.\n     * @param eventName The name of the event to listen for.\n     * @param handler A function to call when the notification occurs. Receives the\n     * event object as an argument.\n     * @returns  A callback function that can be used to remove the handler.\n     */\n    addEventListener(element, eventName, handler) {\n      const plugin = this._findPluginFor(eventName);\n      return plugin.addEventListener(element, eventName, handler);\n    }\n    /**\n     * Retrieves the compilation zone in which event listeners are registered.\n     */\n    getZone() {\n      return this._zone;\n    }\n    /** @internal */\n    _findPluginFor(eventName) {\n      let plugin = this._eventNameToPlugin.get(eventName);\n      if (plugin) {\n        return plugin;\n      }\n      const plugins = this._plugins;\n      plugin = plugins.find(plugin => plugin.supports(eventName));\n      if (!plugin) {\n        throw new ɵRuntimeError(5101 /* RuntimeErrorCode.NO_PLUGIN_FOR_EVENT */, (typeof ngDevMode === 'undefined' || ngDevMode) && `No event manager plugin found for event ${eventName}`);\n      }\n      this._eventNameToPlugin.set(eventName, plugin);\n      return plugin;\n    }\n    static #_ = this.ɵfac = function EventManager_Factory(t) {\n      return new (t || EventManager)(i0.ɵɵinject(EVENT_MANAGER_PLUGINS), i0.ɵɵinject(i0.NgZone));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: EventManager,\n      factory: EventManager.ɵfac\n    });\n  }\n  return EventManager;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * The plugin definition for the `EventManager` class\n *\n * It can be used as a base class to create custom manager plugins, i.e. you can create your own\n * class that extends the `EventManagerPlugin` one.\n *\n * @publicApi\n */\nclass EventManagerPlugin {\n  // TODO: remove (has some usage in G3)\n  constructor(_doc) {\n    this._doc = _doc;\n  }\n}\n\n/** The style elements attribute name used to set value of `APP_ID` token. */\nconst APP_ID_ATTRIBUTE_NAME = 'ng-app-id';\nlet SharedStylesHost = /*#__PURE__*/(() => {\n  class SharedStylesHost {\n    constructor(doc, appId, nonce, platformId = {}) {\n      this.doc = doc;\n      this.appId = appId;\n      this.nonce = nonce;\n      this.platformId = platformId;\n      // Maps all registered host nodes to a list of style nodes that have been added to the host node.\n      this.styleRef = new Map();\n      this.hostNodes = new Set();\n      this.styleNodesInDOM = this.collectServerRenderedStyles();\n      this.platformIsServer = isPlatformServer(platformId);\n      this.resetHostNodes();\n    }\n    addStyles(styles) {\n      for (const style of styles) {\n        const usageCount = this.changeUsageCount(style, 1);\n        if (usageCount === 1) {\n          this.onStyleAdded(style);\n        }\n      }\n    }\n    removeStyles(styles) {\n      for (const style of styles) {\n        const usageCount = this.changeUsageCount(style, -1);\n        if (usageCount <= 0) {\n          this.onStyleRemoved(style);\n        }\n      }\n    }\n    ngOnDestroy() {\n      const styleNodesInDOM = this.styleNodesInDOM;\n      if (styleNodesInDOM) {\n        styleNodesInDOM.forEach(node => node.remove());\n        styleNodesInDOM.clear();\n      }\n      for (const style of this.getAllStyles()) {\n        this.onStyleRemoved(style);\n      }\n      this.resetHostNodes();\n    }\n    addHost(hostNode) {\n      this.hostNodes.add(hostNode);\n      for (const style of this.getAllStyles()) {\n        this.addStyleToHost(hostNode, style);\n      }\n    }\n    removeHost(hostNode) {\n      this.hostNodes.delete(hostNode);\n    }\n    getAllStyles() {\n      return this.styleRef.keys();\n    }\n    onStyleAdded(style) {\n      for (const host of this.hostNodes) {\n        this.addStyleToHost(host, style);\n      }\n    }\n    onStyleRemoved(style) {\n      const styleRef = this.styleRef;\n      styleRef.get(style)?.elements?.forEach(node => node.remove());\n      styleRef.delete(style);\n    }\n    collectServerRenderedStyles() {\n      const styles = this.doc.head?.querySelectorAll(`style[${APP_ID_ATTRIBUTE_NAME}=\"${this.appId}\"]`);\n      if (styles?.length) {\n        const styleMap = new Map();\n        styles.forEach(style => {\n          if (style.textContent != null) {\n            styleMap.set(style.textContent, style);\n          }\n        });\n        return styleMap;\n      }\n      return null;\n    }\n    changeUsageCount(style, delta) {\n      const map = this.styleRef;\n      if (map.has(style)) {\n        const styleRefValue = map.get(style);\n        styleRefValue.usage += delta;\n        return styleRefValue.usage;\n      }\n      map.set(style, {\n        usage: delta,\n        elements: []\n      });\n      return delta;\n    }\n    getStyleElement(host, style) {\n      const styleNodesInDOM = this.styleNodesInDOM;\n      const styleEl = styleNodesInDOM?.get(style);\n      if (styleEl?.parentNode === host) {\n        // `styleNodesInDOM` cannot be undefined due to the above `styleNodesInDOM?.get`.\n        styleNodesInDOM.delete(style);\n        styleEl.removeAttribute(APP_ID_ATTRIBUTE_NAME);\n        if (typeof ngDevMode === 'undefined' || ngDevMode) {\n          // This attribute is solely used for debugging purposes.\n          styleEl.setAttribute('ng-style-reused', '');\n        }\n        return styleEl;\n      } else {\n        const styleEl = this.doc.createElement('style');\n        if (this.nonce) {\n          styleEl.setAttribute('nonce', this.nonce);\n        }\n        styleEl.textContent = style;\n        if (this.platformIsServer) {\n          styleEl.setAttribute(APP_ID_ATTRIBUTE_NAME, this.appId);\n        }\n        host.appendChild(styleEl);\n        return styleEl;\n      }\n    }\n    addStyleToHost(host, style) {\n      const styleEl = this.getStyleElement(host, style);\n      const styleRef = this.styleRef;\n      const styleElRef = styleRef.get(style)?.elements;\n      if (styleElRef) {\n        styleElRef.push(styleEl);\n      } else {\n        styleRef.set(style, {\n          elements: [styleEl],\n          usage: 1\n        });\n      }\n    }\n    resetHostNodes() {\n      const hostNodes = this.hostNodes;\n      hostNodes.clear();\n      // Re-add the head element back since this is the default host.\n      hostNodes.add(this.doc.head);\n    }\n    static #_ = this.ɵfac = function SharedStylesHost_Factory(t) {\n      return new (t || SharedStylesHost)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(APP_ID), i0.ɵɵinject(CSP_NONCE, 8), i0.ɵɵinject(PLATFORM_ID));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: SharedStylesHost,\n      factory: SharedStylesHost.ɵfac\n    });\n  }\n  return SharedStylesHost;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nconst NAMESPACE_URIS = {\n  'svg': 'http://www.w3.org/2000/svg',\n  'xhtml': 'http://www.w3.org/1999/xhtml',\n  'xlink': 'http://www.w3.org/1999/xlink',\n  'xml': 'http://www.w3.org/XML/1998/namespace',\n  'xmlns': 'http://www.w3.org/2000/xmlns/',\n  'math': 'http://www.w3.org/1998/MathML/'\n};\nconst COMPONENT_REGEX = /%COMP%/g;\nconst COMPONENT_VARIABLE = '%COMP%';\nconst HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;\nconst CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;\n/**\n * The default value for the `REMOVE_STYLES_ON_COMPONENT_DESTROY` DI token.\n */\nconst REMOVE_STYLES_ON_COMPONENT_DESTROY_DEFAULT = true;\n/**\n * A [DI token](guide/glossary#di-token \"DI token definition\") that indicates whether styles\n * of destroyed components should be removed from DOM.\n *\n * By default, the value is set to `true`.\n * @publicApi\n */\nconst REMOVE_STYLES_ON_COMPONENT_DESTROY = /*#__PURE__*/new InjectionToken(ngDevMode ? 'RemoveStylesOnCompDestroy' : '', {\n  providedIn: 'root',\n  factory: () => REMOVE_STYLES_ON_COMPONENT_DESTROY_DEFAULT\n});\nfunction shimContentAttribute(componentShortId) {\n  return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);\n}\nfunction shimHostAttribute(componentShortId) {\n  return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);\n}\nfunction shimStylesContent(compId, styles) {\n  return styles.map(s => s.replace(COMPONENT_REGEX, compId));\n}\nlet DomRendererFactory2 = /*#__PURE__*/(() => {\n  class DomRendererFactory2 {\n    constructor(eventManager, sharedStylesHost, appId, removeStylesOnCompDestroy, doc, platformId, ngZone, nonce = null) {\n      this.eventManager = eventManager;\n      this.sharedStylesHost = sharedStylesHost;\n      this.appId = appId;\n      this.removeStylesOnCompDestroy = removeStylesOnCompDestroy;\n      this.doc = doc;\n      this.platformId = platformId;\n      this.ngZone = ngZone;\n      this.nonce = nonce;\n      this.rendererByCompId = new Map();\n      this.platformIsServer = isPlatformServer(platformId);\n      this.defaultRenderer = new DefaultDomRenderer2(eventManager, doc, ngZone, this.platformIsServer);\n    }\n    createRenderer(element, type) {\n      if (!element || !type) {\n        return this.defaultRenderer;\n      }\n      if (this.platformIsServer && type.encapsulation === ViewEncapsulation.ShadowDom) {\n        // Domino does not support shadow DOM.\n        type = {\n          ...type,\n          encapsulation: ViewEncapsulation.Emulated\n        };\n      }\n      const renderer = this.getOrCreateRenderer(element, type);\n      // Renderers have different logic due to different encapsulation behaviours.\n      // Ex: for emulated, an attribute is added to the element.\n      if (renderer instanceof EmulatedEncapsulationDomRenderer2) {\n        renderer.applyToHost(element);\n      } else if (renderer instanceof NoneEncapsulationDomRenderer) {\n        renderer.applyStyles();\n      }\n      return renderer;\n    }\n    getOrCreateRenderer(element, type) {\n      const rendererByCompId = this.rendererByCompId;\n      let renderer = rendererByCompId.get(type.id);\n      if (!renderer) {\n        const doc = this.doc;\n        const ngZone = this.ngZone;\n        const eventManager = this.eventManager;\n        const sharedStylesHost = this.sharedStylesHost;\n        const removeStylesOnCompDestroy = this.removeStylesOnCompDestroy;\n        const platformIsServer = this.platformIsServer;\n        switch (type.encapsulation) {\n          case ViewEncapsulation.Emulated:\n            renderer = new EmulatedEncapsulationDomRenderer2(eventManager, sharedStylesHost, type, this.appId, removeStylesOnCompDestroy, doc, ngZone, platformIsServer);\n            break;\n          case ViewEncapsulation.ShadowDom:\n            return new ShadowDomRenderer(eventManager, sharedStylesHost, element, type, doc, ngZone, this.nonce, platformIsServer);\n          default:\n            renderer = new NoneEncapsulationDomRenderer(eventManager, sharedStylesHost, type, removeStylesOnCompDestroy, doc, ngZone, platformIsServer);\n            break;\n        }\n        rendererByCompId.set(type.id, renderer);\n      }\n      return renderer;\n    }\n    ngOnDestroy() {\n      this.rendererByCompId.clear();\n    }\n    static #_ = this.ɵfac = function DomRendererFactory2_Factory(t) {\n      return new (t || DomRendererFactory2)(i0.ɵɵinject(EventManager), i0.ɵɵinject(SharedStylesHost), i0.ɵɵinject(APP_ID), i0.ɵɵinject(REMOVE_STYLES_ON_COMPONENT_DESTROY), i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(PLATFORM_ID), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(CSP_NONCE));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: DomRendererFactory2,\n      factory: DomRendererFactory2.ɵfac\n    });\n  }\n  return DomRendererFactory2;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nclass DefaultDomRenderer2 {\n  constructor(eventManager, doc, ngZone, platformIsServer) {\n    this.eventManager = eventManager;\n    this.doc = doc;\n    this.ngZone = ngZone;\n    this.platformIsServer = platformIsServer;\n    this.data = Object.create(null);\n    /**\n     * By default this renderer throws when encountering synthetic properties\n     * This can be disabled for example by the AsyncAnimationRendererFactory\n     */\n    this.throwOnSyntheticProps = true;\n    this.destroyNode = null;\n  }\n  destroy() {}\n  createElement(name, namespace) {\n    if (namespace) {\n      // TODO: `|| namespace` was added in\n      // https://github.com/angular/angular/commit/2b9cc8503d48173492c29f5a271b61126104fbdb to\n      // support how Ivy passed around the namespace URI rather than short name at the time. It did\n      // not, however extend the support to other parts of the system (setAttribute, setAttribute,\n      // and the ServerRenderer). We should decide what exactly the semantics for dealing with\n      // namespaces should be and make it consistent.\n      // Related issues:\n      // https://github.com/angular/angular/issues/44028\n      // https://github.com/angular/angular/issues/44883\n      return this.doc.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);\n    }\n    return this.doc.createElement(name);\n  }\n  createComment(value) {\n    return this.doc.createComment(value);\n  }\n  createText(value) {\n    return this.doc.createTextNode(value);\n  }\n  appendChild(parent, newChild) {\n    const targetParent = isTemplateNode(parent) ? parent.content : parent;\n    targetParent.appendChild(newChild);\n  }\n  insertBefore(parent, newChild, refChild) {\n    if (parent) {\n      const targetParent = isTemplateNode(parent) ? parent.content : parent;\n      targetParent.insertBefore(newChild, refChild);\n    }\n  }\n  removeChild(parent, oldChild) {\n    if (parent) {\n      parent.removeChild(oldChild);\n    }\n  }\n  selectRootElement(selectorOrNode, preserveContent) {\n    let el = typeof selectorOrNode === 'string' ? this.doc.querySelector(selectorOrNode) : selectorOrNode;\n    if (!el) {\n      throw new ɵRuntimeError(-5104 /* RuntimeErrorCode.ROOT_NODE_NOT_FOUND */, (typeof ngDevMode === 'undefined' || ngDevMode) && `The selector \"${selectorOrNode}\" did not match any elements`);\n    }\n    if (!preserveContent) {\n      el.textContent = '';\n    }\n    return el;\n  }\n  parentNode(node) {\n    return node.parentNode;\n  }\n  nextSibling(node) {\n    return node.nextSibling;\n  }\n  setAttribute(el, name, value, namespace) {\n    if (namespace) {\n      name = namespace + ':' + name;\n      const namespaceUri = NAMESPACE_URIS[namespace];\n      if (namespaceUri) {\n        el.setAttributeNS(namespaceUri, name, value);\n      } else {\n        el.setAttribute(name, value);\n      }\n    } else {\n      el.setAttribute(name, value);\n    }\n  }\n  removeAttribute(el, name, namespace) {\n    if (namespace) {\n      const namespaceUri = NAMESPACE_URIS[namespace];\n      if (namespaceUri) {\n        el.removeAttributeNS(namespaceUri, name);\n      } else {\n        el.removeAttribute(`${namespace}:${name}`);\n      }\n    } else {\n      el.removeAttribute(name);\n    }\n  }\n  addClass(el, name) {\n    el.classList.add(name);\n  }\n  removeClass(el, name) {\n    el.classList.remove(name);\n  }\n  setStyle(el, style, value, flags) {\n    if (flags & (RendererStyleFlags2.DashCase | RendererStyleFlags2.Important)) {\n      el.style.setProperty(style, value, flags & RendererStyleFlags2.Important ? 'important' : '');\n    } else {\n      el.style[style] = value;\n    }\n  }\n  removeStyle(el, style, flags) {\n    if (flags & RendererStyleFlags2.DashCase) {\n      // removeProperty has no effect when used on camelCased properties.\n      el.style.removeProperty(style);\n    } else {\n      el.style[style] = '';\n    }\n  }\n  setProperty(el, name, value) {\n    if (el == null) {\n      return;\n    }\n    (typeof ngDevMode === 'undefined' || ngDevMode) && this.throwOnSyntheticProps && checkNoSyntheticProp(name, 'property');\n    el[name] = value;\n  }\n  setValue(node, value) {\n    node.nodeValue = value;\n  }\n  listen(target, event, callback) {\n    (typeof ngDevMode === 'undefined' || ngDevMode) && this.throwOnSyntheticProps && checkNoSyntheticProp(event, 'listener');\n    if (typeof target === 'string') {\n      target = ɵgetDOM().getGlobalEventTarget(this.doc, target);\n      if (!target) {\n        throw new Error(`Unsupported event target ${target} for event ${event}`);\n      }\n    }\n    return this.eventManager.addEventListener(target, event, this.decoratePreventDefault(callback));\n  }\n  decoratePreventDefault(eventHandler) {\n    // `DebugNode.triggerEventHandler` needs to know if the listener was created with\n    // decoratePreventDefault or is a listener added outside the Angular context so it can handle\n    // the two differently. In the first case, the special '__ngUnwrap__' token is passed to the\n    // unwrap the listener (see below).\n    return event => {\n      // Ivy uses '__ngUnwrap__' as a special token that allows us to unwrap the function\n      // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`. The\n      // debug_node can inspect the listener toString contents for the existence of this special\n      // token. Because the token is a string literal, it is ensured to not be modified by compiled\n      // code.\n      if (event === '__ngUnwrap__') {\n        return eventHandler;\n      }\n      // Run the event handler inside the ngZone because event handlers are not patched\n      // by Zone on the server. This is required only for tests.\n      const allowDefaultBehavior = this.platformIsServer ? this.ngZone.runGuarded(() => eventHandler(event)) : eventHandler(event);\n      if (allowDefaultBehavior === false) {\n        event.preventDefault();\n      }\n      return undefined;\n    };\n  }\n}\nconst AT_CHARCODE = /*#__PURE__*/(() => '@'.charCodeAt(0))();\nfunction checkNoSyntheticProp(name, nameKind) {\n  if (name.charCodeAt(0) === AT_CHARCODE) {\n    throw new ɵRuntimeError(5105 /* RuntimeErrorCode.UNEXPECTED_SYNTHETIC_PROPERTY */, `Unexpected synthetic ${nameKind} ${name} found. Please make sure that:\n  - Either \\`BrowserAnimationsModule\\` or \\`NoopAnimationsModule\\` are imported in your application.\n  - There is corresponding configuration for the animation named \\`${name}\\` defined in the \\`animations\\` field of the \\`@Component\\` decorator (see https://angular.io/api/core/Component#animations).`);\n  }\n}\nfunction isTemplateNode(node) {\n  return node.tagName === 'TEMPLATE' && node.content !== undefined;\n}\nclass ShadowDomRenderer extends DefaultDomRenderer2 {\n  constructor(eventManager, sharedStylesHost, hostEl, component, doc, ngZone, nonce, platformIsServer) {\n    super(eventManager, doc, ngZone, platformIsServer);\n    this.sharedStylesHost = sharedStylesHost;\n    this.hostEl = hostEl;\n    this.shadowRoot = hostEl.attachShadow({\n      mode: 'open'\n    });\n    this.sharedStylesHost.addHost(this.shadowRoot);\n    const styles = shimStylesContent(component.id, component.styles);\n    for (const style of styles) {\n      const styleEl = document.createElement('style');\n      if (nonce) {\n        styleEl.setAttribute('nonce', nonce);\n      }\n      styleEl.textContent = style;\n      this.shadowRoot.appendChild(styleEl);\n    }\n  }\n  nodeOrShadowRoot(node) {\n    return node === this.hostEl ? this.shadowRoot : node;\n  }\n  appendChild(parent, newChild) {\n    return super.appendChild(this.nodeOrShadowRoot(parent), newChild);\n  }\n  insertBefore(parent, newChild, refChild) {\n    return super.insertBefore(this.nodeOrShadowRoot(parent), newChild, refChild);\n  }\n  removeChild(parent, oldChild) {\n    return super.removeChild(this.nodeOrShadowRoot(parent), oldChild);\n  }\n  parentNode(node) {\n    return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(node)));\n  }\n  destroy() {\n    this.sharedStylesHost.removeHost(this.shadowRoot);\n  }\n}\nclass NoneEncapsulationDomRenderer extends DefaultDomRenderer2 {\n  constructor(eventManager, sharedStylesHost, component, removeStylesOnCompDestroy, doc, ngZone, platformIsServer, compId) {\n    super(eventManager, doc, ngZone, platformIsServer);\n    this.sharedStylesHost = sharedStylesHost;\n    this.removeStylesOnCompDestroy = removeStylesOnCompDestroy;\n    this.styles = compId ? shimStylesContent(compId, component.styles) : component.styles;\n  }\n  applyStyles() {\n    this.sharedStylesHost.addStyles(this.styles);\n  }\n  destroy() {\n    if (!this.removeStylesOnCompDestroy) {\n      return;\n    }\n    this.sharedStylesHost.removeStyles(this.styles);\n  }\n}\nclass EmulatedEncapsulationDomRenderer2 extends NoneEncapsulationDomRenderer {\n  constructor(eventManager, sharedStylesHost, component, appId, removeStylesOnCompDestroy, doc, ngZone, platformIsServer) {\n    const compId = appId + '-' + component.id;\n    super(eventManager, sharedStylesHost, component, removeStylesOnCompDestroy, doc, ngZone, platformIsServer, compId);\n    this.contentAttr = shimContentAttribute(compId);\n    this.hostAttr = shimHostAttribute(compId);\n  }\n  applyToHost(element) {\n    this.applyStyles();\n    this.setAttribute(element, this.hostAttr, '');\n  }\n  createElement(parent, name) {\n    const el = super.createElement(parent, name);\n    super.setAttribute(el, this.contentAttr, '');\n    return el;\n  }\n}\nlet DomEventsPlugin = /*#__PURE__*/(() => {\n  class DomEventsPlugin extends EventManagerPlugin {\n    constructor(doc) {\n      super(doc);\n    }\n    // This plugin should come last in the list of plugins, because it accepts all\n    // events.\n    supports(eventName) {\n      return true;\n    }\n    addEventListener(element, eventName, handler) {\n      element.addEventListener(eventName, handler, false);\n      return () => this.removeEventListener(element, eventName, handler);\n    }\n    removeEventListener(target, eventName, callback) {\n      return target.removeEventListener(eventName, callback);\n    }\n    static #_ = this.ɵfac = function DomEventsPlugin_Factory(t) {\n      return new (t || DomEventsPlugin)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: DomEventsPlugin,\n      factory: DomEventsPlugin.ɵfac\n    });\n  }\n  return DomEventsPlugin;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Defines supported modifiers for key events.\n */\nconst MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift'];\n// The following values are here for cross-browser compatibility and to match the W3C standard\n// cf https://www.w3.org/TR/DOM-Level-3-Events-key/\nconst _keyMap = {\n  '\\b': 'Backspace',\n  '\\t': 'Tab',\n  '\\x7F': 'Delete',\n  '\\x1B': 'Escape',\n  'Del': 'Delete',\n  'Esc': 'Escape',\n  'Left': 'ArrowLeft',\n  'Right': 'ArrowRight',\n  'Up': 'ArrowUp',\n  'Down': 'ArrowDown',\n  'Menu': 'ContextMenu',\n  'Scroll': 'ScrollLock',\n  'Win': 'OS'\n};\n/**\n * Retrieves modifiers from key-event objects.\n */\nconst MODIFIER_KEY_GETTERS = {\n  'alt': event => event.altKey,\n  'control': event => event.ctrlKey,\n  'meta': event => event.metaKey,\n  'shift': event => event.shiftKey\n};\n/**\n * A browser plug-in that provides support for handling of key events in Angular.\n */\nlet KeyEventsPlugin = /*#__PURE__*/(() => {\n  class KeyEventsPlugin extends EventManagerPlugin {\n    /**\n     * Initializes an instance of the browser plug-in.\n     * @param doc The document in which key events will be detected.\n     */\n    constructor(doc) {\n      super(doc);\n    }\n    /**\n     * Reports whether a named key event is supported.\n     * @param eventName The event name to query.\n     * @return True if the named key event is supported.\n     */\n    supports(eventName) {\n      return KeyEventsPlugin.parseEventName(eventName) != null;\n    }\n    /**\n     * Registers a handler for a specific element and key event.\n     * @param element The HTML element to receive event notifications.\n     * @param eventName The name of the key event to listen for.\n     * @param handler A function to call when the notification occurs. Receives the\n     * event object as an argument.\n     * @returns The key event that was registered.\n     */\n    addEventListener(element, eventName, handler) {\n      const parsedEvent = KeyEventsPlugin.parseEventName(eventName);\n      const outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());\n      return this.manager.getZone().runOutsideAngular(() => {\n        return ɵgetDOM().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);\n      });\n    }\n    /**\n     * Parses the user provided full keyboard event definition and normalizes it for\n     * later internal use. It ensures the string is all lowercase, converts special\n     * characters to a standard spelling, and orders all the values consistently.\n     *\n     * @param eventName The name of the key event to listen for.\n     * @returns an object with the full, normalized string, and the dom event name\n     * or null in the case when the event doesn't match a keyboard event.\n     */\n    static parseEventName(eventName) {\n      const parts = eventName.toLowerCase().split('.');\n      const domEventName = parts.shift();\n      if (parts.length === 0 || !(domEventName === 'keydown' || domEventName === 'keyup')) {\n        return null;\n      }\n      const key = KeyEventsPlugin._normalizeKey(parts.pop());\n      let fullKey = '';\n      let codeIX = parts.indexOf('code');\n      if (codeIX > -1) {\n        parts.splice(codeIX, 1);\n        fullKey = 'code.';\n      }\n      MODIFIER_KEYS.forEach(modifierName => {\n        const index = parts.indexOf(modifierName);\n        if (index > -1) {\n          parts.splice(index, 1);\n          fullKey += modifierName + '.';\n        }\n      });\n      fullKey += key;\n      if (parts.length != 0 || key.length === 0) {\n        // returning null instead of throwing to let another plugin process the event\n        return null;\n      }\n      // NOTE: Please don't rewrite this as so, as it will break JSCompiler property renaming.\n      //       The code must remain in the `result['domEventName']` form.\n      // return {domEventName, fullKey};\n      const result = {};\n      result['domEventName'] = domEventName;\n      result['fullKey'] = fullKey;\n      return result;\n    }\n    /**\n     * Determines whether the actual keys pressed match the configured key code string.\n     * The `fullKeyCode` event is normalized in the `parseEventName` method when the\n     * event is attached to the DOM during the `addEventListener` call. This is unseen\n     * by the end user and is normalized for internal consistency and parsing.\n     *\n     * @param event The keyboard event.\n     * @param fullKeyCode The normalized user defined expected key event string\n     * @returns boolean.\n     */\n    static matchEventFullKeyCode(event, fullKeyCode) {\n      let keycode = _keyMap[event.key] || event.key;\n      let key = '';\n      if (fullKeyCode.indexOf('code.') > -1) {\n        keycode = event.code;\n        key = 'code.';\n      }\n      // the keycode could be unidentified so we have to check here\n      if (keycode == null || !keycode) return false;\n      keycode = keycode.toLowerCase();\n      if (keycode === ' ') {\n        keycode = 'space'; // for readability\n      } else if (keycode === '.') {\n        keycode = 'dot'; // because '.' is used as a separator in event names\n      }\n      MODIFIER_KEYS.forEach(modifierName => {\n        if (modifierName !== keycode) {\n          const modifierGetter = MODIFIER_KEY_GETTERS[modifierName];\n          if (modifierGetter(event)) {\n            key += modifierName + '.';\n          }\n        }\n      });\n      key += keycode;\n      return key === fullKeyCode;\n    }\n    /**\n     * Configures a handler callback for a key event.\n     * @param fullKey The event name that combines all simultaneous keystrokes.\n     * @param handler The function that responds to the key event.\n     * @param zone The zone in which the event occurred.\n     * @returns A callback function.\n     */\n    static eventCallback(fullKey, handler, zone) {\n      return event => {\n        if (KeyEventsPlugin.matchEventFullKeyCode(event, fullKey)) {\n          zone.runGuarded(() => handler(event));\n        }\n      };\n    }\n    /** @internal */\n    static _normalizeKey(keyName) {\n      return keyName === 'esc' ? 'escape' : keyName;\n    }\n    static #_ = this.ɵfac = function KeyEventsPlugin_Factory(t) {\n      return new (t || KeyEventsPlugin)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: KeyEventsPlugin,\n      factory: KeyEventsPlugin.ɵfac\n    });\n  }\n  return KeyEventsPlugin;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Bootstraps an instance of an Angular application and renders a standalone component as the\n * application's root component. More information about standalone components can be found in [this\n * guide](guide/standalone-components).\n *\n * @usageNotes\n * The root component passed into this function *must* be a standalone one (should have the\n * `standalone: true` flag in the `@Component` decorator config).\n *\n * ```typescript\n * @Component({\n *   standalone: true,\n *   template: 'Hello world!'\n * })\n * class RootComponent {}\n *\n * const appRef: ApplicationRef = await bootstrapApplication(RootComponent);\n * ```\n *\n * You can add the list of providers that should be available in the application injector by\n * specifying the `providers` field in an object passed as the second argument:\n *\n * ```typescript\n * await bootstrapApplication(RootComponent, {\n *   providers: [\n *     {provide: BACKEND_URL, useValue: 'https://yourdomain.com/api'}\n *   ]\n * });\n * ```\n *\n * The `importProvidersFrom` helper method can be used to collect all providers from any\n * existing NgModule (and transitively from all NgModules that it imports):\n *\n * ```typescript\n * await bootstrapApplication(RootComponent, {\n *   providers: [\n *     importProvidersFrom(SomeNgModule)\n *   ]\n * });\n * ```\n *\n * Note: the `bootstrapApplication` method doesn't include [Testability](api/core/Testability) by\n * default. You can add [Testability](api/core/Testability) by getting the list of necessary\n * providers using `provideProtractorTestingSupport()` function and adding them into the `providers`\n * array, for example:\n *\n * ```typescript\n * import {provideProtractorTestingSupport} from '@angular/platform-browser';\n *\n * await bootstrapApplication(RootComponent, {providers: [provideProtractorTestingSupport()]});\n * ```\n *\n * @param rootComponent A reference to a standalone component that should be rendered.\n * @param options Extra configuration for the bootstrap operation, see `ApplicationConfig` for\n *     additional info.\n * @returns A promise that returns an `ApplicationRef` instance once resolved.\n *\n * @publicApi\n */\nfunction bootstrapApplication(rootComponent, options) {\n  return ɵinternalCreateApplication({\n    rootComponent,\n    ...createProvidersConfig(options)\n  });\n}\n/**\n * Create an instance of an Angular application without bootstrapping any components. This is useful\n * for the situation where one wants to decouple application environment creation (a platform and\n * associated injectors) from rendering components on a screen. Components can be subsequently\n * bootstrapped on the returned `ApplicationRef`.\n *\n * @param options Extra configuration for the application environment, see `ApplicationConfig` for\n *     additional info.\n * @returns A promise that returns an `ApplicationRef` instance once resolved.\n *\n * @publicApi\n */\nfunction createApplication(options) {\n  return ɵinternalCreateApplication(createProvidersConfig(options));\n}\nfunction createProvidersConfig(options) {\n  return {\n    appProviders: [...BROWSER_MODULE_PROVIDERS, ...(options?.providers ?? [])],\n    platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS\n  };\n}\n/**\n * Returns a set of providers required to setup [Testability](api/core/Testability) for an\n * application bootstrapped using the `bootstrapApplication` function. The set of providers is\n * needed to support testing an application with Protractor (which relies on the Testability APIs\n * to be present).\n *\n * @returns An array of providers required to setup Testability for an application and make it\n *     available for testing using Protractor.\n *\n * @publicApi\n */\nfunction provideProtractorTestingSupport() {\n  // Return a copy to prevent changes to the original array in case any in-place\n  // alterations are performed to the `provideProtractorTestingSupport` call results in app\n  // code.\n  return [...TESTABILITY_PROVIDERS];\n}\nfunction initDomAdapter() {\n  BrowserDomAdapter.makeCurrent();\n}\nfunction errorHandler() {\n  return new ErrorHandler();\n}\nfunction _document() {\n  // Tell ivy about the global document\n  ɵsetDocument(document);\n  return document;\n}\nconst INTERNAL_BROWSER_PLATFORM_PROVIDERS = [{\n  provide: PLATFORM_ID,\n  useValue: ɵPLATFORM_BROWSER_ID\n}, {\n  provide: PLATFORM_INITIALIZER,\n  useValue: initDomAdapter,\n  multi: true\n}, {\n  provide: DOCUMENT,\n  useFactory: _document,\n  deps: []\n}];\n/**\n * A factory function that returns a `PlatformRef` instance associated with browser service\n * providers.\n *\n * @publicApi\n */\nconst platformBrowser = /*#__PURE__*/createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);\n/**\n * Internal marker to signal whether providers from the `BrowserModule` are already present in DI.\n * This is needed to avoid loading `BrowserModule` providers twice. We can't rely on the\n * `BrowserModule` presence itself, since the standalone-based bootstrap just imports\n * `BrowserModule` providers without referencing the module itself.\n */\nconst BROWSER_MODULE_PROVIDERS_MARKER = /*#__PURE__*/new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'BrowserModule Providers Marker' : '');\nconst TESTABILITY_PROVIDERS = [{\n  provide: ɵTESTABILITY_GETTER,\n  useClass: BrowserGetTestability,\n  deps: []\n}, {\n  provide: ɵTESTABILITY,\n  useClass: Testability,\n  deps: [NgZone, TestabilityRegistry, ɵTESTABILITY_GETTER]\n}, {\n  provide: Testability,\n  // Also provide as `Testability` for backwards-compatibility.\n  useClass: Testability,\n  deps: [NgZone, TestabilityRegistry, ɵTESTABILITY_GETTER]\n}];\nconst BROWSER_MODULE_PROVIDERS = [{\n  provide: ɵINJECTOR_SCOPE,\n  useValue: 'root'\n}, {\n  provide: ErrorHandler,\n  useFactory: errorHandler,\n  deps: []\n}, {\n  provide: EVENT_MANAGER_PLUGINS,\n  useClass: DomEventsPlugin,\n  multi: true,\n  deps: [DOCUMENT, NgZone, PLATFORM_ID]\n}, {\n  provide: EVENT_MANAGER_PLUGINS,\n  useClass: KeyEventsPlugin,\n  multi: true,\n  deps: [DOCUMENT]\n}, DomRendererFactory2, SharedStylesHost, EventManager, {\n  provide: RendererFactory2,\n  useExisting: DomRendererFactory2\n}, {\n  provide: XhrFactory,\n  useClass: BrowserXhr,\n  deps: []\n}, typeof ngDevMode === 'undefined' || ngDevMode ? {\n  provide: BROWSER_MODULE_PROVIDERS_MARKER,\n  useValue: true\n} : []];\n/**\n * Exports required infrastructure for all Angular apps.\n * Included by default in all Angular apps created with the CLI\n * `new` command.\n * Re-exports `CommonModule` and `ApplicationModule`, making their\n * exports and providers available to all apps.\n *\n * @publicApi\n */\nlet BrowserModule = /*#__PURE__*/(() => {\n  class BrowserModule {\n    constructor(providersAlreadyPresent) {\n      if ((typeof ngDevMode === 'undefined' || ngDevMode) && providersAlreadyPresent) {\n        throw new ɵRuntimeError(5100 /* RuntimeErrorCode.BROWSER_MODULE_ALREADY_LOADED */, `Providers from the \\`BrowserModule\\` have already been loaded. If you need access ` + `to common directives such as NgIf and NgFor, import the \\`CommonModule\\` instead.`);\n      }\n    }\n    /**\n     * Configures a browser-based app to transition from a server-rendered app, if\n     * one is present on the page.\n     *\n     * @param params An object containing an identifier for the app to transition.\n     * The ID must match between the client and server versions of the app.\n     * @returns The reconfigured `BrowserModule` to import into the app's root `AppModule`.\n     *\n     * @deprecated Use {@link APP_ID} instead to set the application ID.\n     */\n    static withServerTransition(params) {\n      return {\n        ngModule: BrowserModule,\n        providers: [{\n          provide: APP_ID,\n          useValue: params.appId\n        }]\n      };\n    }\n    static #_ = this.ɵfac = function BrowserModule_Factory(t) {\n      return new (t || BrowserModule)(i0.ɵɵinject(BROWSER_MODULE_PROVIDERS_MARKER, 12));\n    };\n    static #_2 = this.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n      type: BrowserModule\n    });\n    static #_3 = this.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n      providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],\n      imports: [CommonModule, ApplicationModule]\n    });\n  }\n  return BrowserModule;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * A service for managing HTML `<meta>` tags.\n *\n * Properties of the `MetaDefinition` object match the attributes of the\n * HTML `<meta>` tag. These tags define document metadata that is important for\n * things like configuring a Content Security Policy, defining browser compatibility\n * and security settings, setting HTTP Headers, defining rich content for social sharing,\n * and Search Engine Optimization (SEO).\n *\n * To identify specific `<meta>` tags in a document, use an attribute selection\n * string in the format `\"tag_attribute='value string'\"`.\n * For example, an `attrSelector` value of `\"name='description'\"` matches a tag\n * whose `name` attribute has the value `\"description\"`.\n * Selectors are used with the `querySelector()` Document method,\n * in the format `meta[{attrSelector}]`.\n *\n * @see [HTML meta tag](https://developer.mozilla.org/docs/Web/HTML/Element/meta)\n * @see [Document.querySelector()](https://developer.mozilla.org/docs/Web/API/Document/querySelector)\n *\n *\n * @publicApi\n */\nlet Meta = /*#__PURE__*/(() => {\n  class Meta {\n    constructor(_doc) {\n      this._doc = _doc;\n      this._dom = ɵgetDOM();\n    }\n    /**\n     * Retrieves or creates a specific `<meta>` tag element in the current HTML document.\n     * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute\n     * values in the provided tag definition, and verifies that all other attribute values are equal.\n     * If an existing element is found, it is returned and is not modified in any way.\n     * @param tag The definition of a `<meta>` element to match or create.\n     * @param forceCreation True to create a new element without checking whether one already exists.\n     * @returns The existing element with the same attributes and values if found,\n     * the new element if no match is found, or `null` if the tag parameter is not defined.\n     */\n    addTag(tag, forceCreation = false) {\n      if (!tag) return null;\n      return this._getOrCreateElement(tag, forceCreation);\n    }\n    /**\n     * Retrieves or creates a set of `<meta>` tag elements in the current HTML document.\n     * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute\n     * values in the provided tag definition, and verifies that all other attribute values are equal.\n     * @param tags An array of tag definitions to match or create.\n     * @param forceCreation True to create new elements without checking whether they already exist.\n     * @returns The matching elements if found, or the new elements.\n     */\n    addTags(tags, forceCreation = false) {\n      if (!tags) return [];\n      return tags.reduce((result, tag) => {\n        if (tag) {\n          result.push(this._getOrCreateElement(tag, forceCreation));\n        }\n        return result;\n      }, []);\n    }\n    /**\n     * Retrieves a `<meta>` tag element in the current HTML document.\n     * @param attrSelector The tag attribute and value to match against, in the format\n     * `\"tag_attribute='value string'\"`.\n     * @returns The matching element, if any.\n     */\n    getTag(attrSelector) {\n      if (!attrSelector) return null;\n      return this._doc.querySelector(`meta[${attrSelector}]`) || null;\n    }\n    /**\n     * Retrieves a set of `<meta>` tag elements in the current HTML document.\n     * @param attrSelector The tag attribute and value to match against, in the format\n     * `\"tag_attribute='value string'\"`.\n     * @returns The matching elements, if any.\n     */\n    getTags(attrSelector) {\n      if (!attrSelector) return [];\n      const list /*NodeList*/ = this._doc.querySelectorAll(`meta[${attrSelector}]`);\n      return list ? [].slice.call(list) : [];\n    }\n    /**\n     * Modifies an existing `<meta>` tag element in the current HTML document.\n     * @param tag The tag description with which to replace the existing tag content.\n     * @param selector A tag attribute and value to match against, to identify\n     * an existing tag. A string in the format `\"tag_attribute=`value string`\"`.\n     * If not supplied, matches a tag with the same `name` or `property` attribute value as the\n     * replacement tag.\n     * @return The modified element.\n     */\n    updateTag(tag, selector) {\n      if (!tag) return null;\n      selector = selector || this._parseSelector(tag);\n      const meta = this.getTag(selector);\n      if (meta) {\n        return this._setMetaElementAttributes(tag, meta);\n      }\n      return this._getOrCreateElement(tag, true);\n    }\n    /**\n     * Removes an existing `<meta>` tag element from the current HTML document.\n     * @param attrSelector A tag attribute and value to match against, to identify\n     * an existing tag. A string in the format `\"tag_attribute=`value string`\"`.\n     */\n    removeTag(attrSelector) {\n      this.removeTagElement(this.getTag(attrSelector));\n    }\n    /**\n     * Removes an existing `<meta>` tag element from the current HTML document.\n     * @param meta The tag definition to match against to identify an existing tag.\n     */\n    removeTagElement(meta) {\n      if (meta) {\n        this._dom.remove(meta);\n      }\n    }\n    _getOrCreateElement(meta, forceCreation = false) {\n      if (!forceCreation) {\n        const selector = this._parseSelector(meta);\n        // It's allowed to have multiple elements with the same name so it's not enough to\n        // just check that element with the same name already present on the page. We also need to\n        // check if element has tag attributes\n        const elem = this.getTags(selector).filter(elem => this._containsAttributes(meta, elem))[0];\n        if (elem !== undefined) return elem;\n      }\n      const element = this._dom.createElement('meta');\n      this._setMetaElementAttributes(meta, element);\n      const head = this._doc.getElementsByTagName('head')[0];\n      head.appendChild(element);\n      return element;\n    }\n    _setMetaElementAttributes(tag, el) {\n      Object.keys(tag).forEach(prop => el.setAttribute(this._getMetaKeyMap(prop), tag[prop]));\n      return el;\n    }\n    _parseSelector(tag) {\n      const attr = tag.name ? 'name' : 'property';\n      return `${attr}=\"${tag[attr]}\"`;\n    }\n    _containsAttributes(tag, elem) {\n      return Object.keys(tag).every(key => elem.getAttribute(this._getMetaKeyMap(key)) === tag[key]);\n    }\n    _getMetaKeyMap(prop) {\n      return META_KEYS_MAP[prop] || prop;\n    }\n    static #_ = this.ɵfac = function Meta_Factory(t) {\n      return new (t || Meta)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: Meta,\n      factory: Meta.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return Meta;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Mapping for MetaDefinition properties with their correct meta attribute names\n */\nconst META_KEYS_MAP = {\n  httpEquiv: 'http-equiv'\n};\n\n/**\n * A service that can be used to get and set the title of a current HTML document.\n *\n * Since an Angular application can't be bootstrapped on the entire HTML document (`<html>` tag)\n * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements\n * (representing the `<title>` tag). Instead, this service can be used to set and get the current\n * title value.\n *\n * @publicApi\n */\nlet Title = /*#__PURE__*/(() => {\n  class Title {\n    constructor(_doc) {\n      this._doc = _doc;\n    }\n    /**\n     * Get the title of the current HTML document.\n     */\n    getTitle() {\n      return this._doc.title;\n    }\n    /**\n     * Set the title of the current HTML document.\n     * @param newTitle\n     */\n    setTitle(newTitle) {\n      this._doc.title = newTitle || '';\n    }\n    static #_ = this.ɵfac = function Title_Factory(t) {\n      return new (t || Title)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: Title,\n      factory: Title.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return Title;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if\n * `name` is `'probe'`.\n * @param name Name under which it will be exported. Keep in mind this will be a property of the\n * global `ng` object.\n * @param value The value to export.\n */\nfunction exportNgVar(name, value) {\n  if (typeof COMPILED === 'undefined' || !COMPILED) {\n    // Note: we can't export `ng` when using closure enhanced optimization as:\n    // - closure declares globals itself for minified names, which sometimes clobber our `ng` global\n    // - we can't declare a closure extern as the namespace `ng` is already used within Google\n    //   for typings for angularJS (via `goog.provide('ng....')`).\n    const ng = ɵglobal['ng'] = ɵglobal['ng'] || {};\n    ng[name] = value;\n  }\n}\nclass ChangeDetectionPerfRecord {\n  constructor(msPerTick, numTicks) {\n    this.msPerTick = msPerTick;\n    this.numTicks = numTicks;\n  }\n}\n/**\n * Entry point for all Angular profiling-related debug tools. This object\n * corresponds to the `ng.profiler` in the dev console.\n */\nclass AngularProfiler {\n  constructor(ref) {\n    this.appRef = ref.injector.get(ApplicationRef);\n  }\n  // tslint:disable:no-console\n  /**\n   * Exercises change detection in a loop and then prints the average amount of\n   * time in milliseconds how long a single round of change detection takes for\n   * the current state of the UI. It runs a minimum of 5 rounds for a minimum\n   * of 500 milliseconds.\n   *\n   * Optionally, a user may pass a `config` parameter containing a map of\n   * options. Supported options are:\n   *\n   * `record` (boolean) - causes the profiler to record a CPU profile while\n   * it exercises the change detector. Example:\n   *\n   * ```\n   * ng.profiler.timeChangeDetection({record: true})\n   * ```\n   */\n  timeChangeDetection(config) {\n    const record = config && config['record'];\n    const profileName = 'Change Detection';\n    // Profiler is not available in Android browsers without dev tools opened\n    if (record && 'profile' in console && typeof console.profile === 'function') {\n      console.profile(profileName);\n    }\n    const start = performance.now();\n    let numTicks = 0;\n    while (numTicks < 5 || performance.now() - start < 500) {\n      this.appRef.tick();\n      numTicks++;\n    }\n    const end = performance.now();\n    if (record && 'profileEnd' in console && typeof console.profileEnd === 'function') {\n      console.profileEnd(profileName);\n    }\n    const msPerTick = (end - start) / numTicks;\n    console.log(`ran ${numTicks} change detection cycles`);\n    console.log(`${msPerTick.toFixed(2)} ms per check`);\n    return new ChangeDetectionPerfRecord(msPerTick, numTicks);\n  }\n}\nconst PROFILER_GLOBAL_NAME = 'profiler';\n/**\n * Enabled Angular debug tools that are accessible via your browser's\n * developer console.\n *\n * Usage:\n *\n * 1. Open developer console (e.g. in Chrome Ctrl + Shift + j)\n * 1. Type `ng.` (usually the console will show auto-complete suggestion)\n * 1. Try the change detection profiler `ng.profiler.timeChangeDetection()`\n *    then hit Enter.\n *\n * @publicApi\n */\nfunction enableDebugTools(ref) {\n  exportNgVar(PROFILER_GLOBAL_NAME, new AngularProfiler(ref));\n  return ref;\n}\n/**\n * Disables Angular tools.\n *\n * @publicApi\n */\nfunction disableDebugTools() {\n  exportNgVar(PROFILER_GLOBAL_NAME, null);\n}\n\n/**\n * Predicates for use with {@link DebugElement}'s query functions.\n *\n * @publicApi\n */\nclass By {\n  /**\n   * Match all nodes.\n   *\n   * @usageNotes\n   * ### Example\n   *\n   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_all'}\n   */\n  static all() {\n    return () => true;\n  }\n  /**\n   * Match elements by the given CSS selector.\n   *\n   * @usageNotes\n   * ### Example\n   *\n   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_css'}\n   */\n  static css(selector) {\n    return debugElement => {\n      return debugElement.nativeElement != null ? elementMatches(debugElement.nativeElement, selector) : false;\n    };\n  }\n  /**\n   * Match nodes that have the given directive present.\n   *\n   * @usageNotes\n   * ### Example\n   *\n   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_directive'}\n   */\n  static directive(type) {\n    return debugNode => debugNode.providerTokens.indexOf(type) !== -1;\n  }\n}\nfunction elementMatches(n, selector) {\n  if (ɵgetDOM().isElementNode(n)) {\n    return n.matches && n.matches(selector) || n.msMatchesSelector && n.msMatchesSelector(selector) || n.webkitMatchesSelector && n.webkitMatchesSelector(selector);\n  }\n  return false;\n}\n\n/**\n * Supported HammerJS recognizer event names.\n */\nconst EVENT_NAMES = {\n  // pan\n  'pan': true,\n  'panstart': true,\n  'panmove': true,\n  'panend': true,\n  'pancancel': true,\n  'panleft': true,\n  'panright': true,\n  'panup': true,\n  'pandown': true,\n  // pinch\n  'pinch': true,\n  'pinchstart': true,\n  'pinchmove': true,\n  'pinchend': true,\n  'pinchcancel': true,\n  'pinchin': true,\n  'pinchout': true,\n  // press\n  'press': true,\n  'pressup': true,\n  // rotate\n  'rotate': true,\n  'rotatestart': true,\n  'rotatemove': true,\n  'rotateend': true,\n  'rotatecancel': true,\n  // swipe\n  'swipe': true,\n  'swipeleft': true,\n  'swiperight': true,\n  'swipeup': true,\n  'swipedown': true,\n  // tap\n  'tap': true,\n  'doubletap': true\n};\n/**\n * DI token for providing [HammerJS](https://hammerjs.github.io/) support to Angular.\n * @see {@link HammerGestureConfig}\n *\n * @ngModule HammerModule\n * @publicApi\n */\nconst HAMMER_GESTURE_CONFIG = /*#__PURE__*/new InjectionToken('HammerGestureConfig');\n/**\n * Injection token used to provide a {@link HammerLoader} to Angular.\n *\n * @publicApi\n */\nconst HAMMER_LOADER = /*#__PURE__*/new InjectionToken('HammerLoader');\n/**\n * An injectable [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)\n * for gesture recognition. Configures specific event recognition.\n * @publicApi\n */\nlet HammerGestureConfig = /*#__PURE__*/(() => {\n  class HammerGestureConfig {\n    constructor() {\n      /**\n       * A set of supported event names for gestures to be used in Angular.\n       * Angular supports all built-in recognizers, as listed in\n       * [HammerJS documentation](https://hammerjs.github.io/).\n       */\n      this.events = [];\n      /**\n       * Maps gesture event names to a set of configuration options\n       * that specify overrides to the default values for specific properties.\n       *\n       * The key is a supported event name to be configured,\n       * and the options object contains a set of properties, with override values\n       * to be applied to the named recognizer event.\n       * For example, to disable recognition of the rotate event, specify\n       *  `{\"rotate\": {\"enable\": false}}`.\n       *\n       * Properties that are not present take the HammerJS default values.\n       * For information about which properties are supported for which events,\n       * and their allowed and default values, see\n       * [HammerJS documentation](https://hammerjs.github.io/).\n       *\n       */\n      this.overrides = {};\n    }\n    /**\n     * Creates a [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)\n     * and attaches it to a given HTML element.\n     * @param element The element that will recognize gestures.\n     * @returns A HammerJS event-manager object.\n     */\n    buildHammer(element) {\n      const mc = new Hammer(element, this.options);\n      mc.get('pinch').set({\n        enable: true\n      });\n      mc.get('rotate').set({\n        enable: true\n      });\n      for (const eventName in this.overrides) {\n        mc.get(eventName).set(this.overrides[eventName]);\n      }\n      return mc;\n    }\n    static #_ = this.ɵfac = function HammerGestureConfig_Factory(t) {\n      return new (t || HammerGestureConfig)();\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: HammerGestureConfig,\n      factory: HammerGestureConfig.ɵfac\n    });\n  }\n  return HammerGestureConfig;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Event plugin that adds Hammer support to an application.\n *\n * @ngModule HammerModule\n */\nlet HammerGesturesPlugin = /*#__PURE__*/(() => {\n  class HammerGesturesPlugin extends EventManagerPlugin {\n    constructor(doc, _config, console, loader) {\n      super(doc);\n      this._config = _config;\n      this.console = console;\n      this.loader = loader;\n      this._loaderPromise = null;\n    }\n    supports(eventName) {\n      if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {\n        return false;\n      }\n      if (!window.Hammer && !this.loader) {\n        if (typeof ngDevMode === 'undefined' || ngDevMode) {\n          this.console.warn(`The \"${eventName}\" event cannot be bound because Hammer.JS is not ` + `loaded and no custom loader has been specified.`);\n        }\n        return false;\n      }\n      return true;\n    }\n    addEventListener(element, eventName, handler) {\n      const zone = this.manager.getZone();\n      eventName = eventName.toLowerCase();\n      // If Hammer is not present but a loader is specified, we defer adding the event listener\n      // until Hammer is loaded.\n      if (!window.Hammer && this.loader) {\n        this._loaderPromise = this._loaderPromise || zone.runOutsideAngular(() => this.loader());\n        // This `addEventListener` method returns a function to remove the added listener.\n        // Until Hammer is loaded, the returned function needs to *cancel* the registration rather\n        // than remove anything.\n        let cancelRegistration = false;\n        let deregister = () => {\n          cancelRegistration = true;\n        };\n        zone.runOutsideAngular(() => this._loaderPromise.then(() => {\n          // If Hammer isn't actually loaded when the custom loader resolves, give up.\n          if (!window.Hammer) {\n            if (typeof ngDevMode === 'undefined' || ngDevMode) {\n              this.console.warn(`The custom HAMMER_LOADER completed, but Hammer.JS is not present.`);\n            }\n            deregister = () => {};\n            return;\n          }\n          if (!cancelRegistration) {\n            // Now that Hammer is loaded and the listener is being loaded for real,\n            // the deregistration function changes from canceling registration to\n            // removal.\n            deregister = this.addEventListener(element, eventName, handler);\n          }\n        }).catch(() => {\n          if (typeof ngDevMode === 'undefined' || ngDevMode) {\n            this.console.warn(`The \"${eventName}\" event cannot be bound because the custom ` + `Hammer.JS loader failed.`);\n          }\n          deregister = () => {};\n        }));\n        // Return a function that *executes* `deregister` (and not `deregister` itself) so that we\n        // can change the behavior of `deregister` once the listener is added. Using a closure in\n        // this way allows us to avoid any additional data structures to track listener removal.\n        return () => {\n          deregister();\n        };\n      }\n      return zone.runOutsideAngular(() => {\n        // Creating the manager bind events, must be done outside of angular\n        const mc = this._config.buildHammer(element);\n        const callback = function (eventObj) {\n          zone.runGuarded(function () {\n            handler(eventObj);\n          });\n        };\n        mc.on(eventName, callback);\n        return () => {\n          mc.off(eventName, callback);\n          // destroy mc to prevent memory leak\n          if (typeof mc.destroy === 'function') {\n            mc.destroy();\n          }\n        };\n      });\n    }\n    isCustomEvent(eventName) {\n      return this._config.events.indexOf(eventName) > -1;\n    }\n    static #_ = this.ɵfac = function HammerGesturesPlugin_Factory(t) {\n      return new (t || HammerGesturesPlugin)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(HAMMER_GESTURE_CONFIG), i0.ɵɵinject(i0.ɵConsole), i0.ɵɵinject(HAMMER_LOADER, 8));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: HammerGesturesPlugin,\n      factory: HammerGesturesPlugin.ɵfac\n    });\n  }\n  return HammerGesturesPlugin;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Adds support for HammerJS.\n *\n * Import this module at the root of your application so that Angular can work with\n * HammerJS to detect gesture events.\n *\n * Note that applications still need to include the HammerJS script itself. This module\n * simply sets up the coordination layer between HammerJS and Angular's `EventManager`.\n *\n * @publicApi\n */\nlet HammerModule = /*#__PURE__*/(() => {\n  class HammerModule {\n    static #_ = this.ɵfac = function HammerModule_Factory(t) {\n      return new (t || HammerModule)();\n    };\n    static #_2 = this.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n      type: HammerModule\n    });\n    static #_3 = this.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n      providers: [{\n        provide: EVENT_MANAGER_PLUGINS,\n        useClass: HammerGesturesPlugin,\n        multi: true,\n        deps: [DOCUMENT, HAMMER_GESTURE_CONFIG, ɵConsole, [new Optional(), HAMMER_LOADER]]\n      }, {\n        provide: HAMMER_GESTURE_CONFIG,\n        useClass: HammerGestureConfig,\n        deps: []\n      }]\n    });\n  }\n  return HammerModule;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing\n * values to be safe to use in the different DOM contexts.\n *\n * For example, when binding a URL in an `<a [href]=\"someValue\">` hyperlink, `someValue` will be\n * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on\n * the website.\n *\n * In specific situations, it might be necessary to disable sanitization, for example if the\n * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.\n * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`\n * methods, and then binding to that value from the template.\n *\n * These situations should be very rare, and extraordinary care must be taken to avoid creating a\n * Cross Site Scripting (XSS) security bug!\n *\n * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as\n * close as possible to the source of the value, to make it easy to verify no security bug is\n * created by its use.\n *\n * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that\n * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous\n * code. The sanitizer leaves safe values intact.\n *\n * @security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in\n * sanitization for the value passed in. Carefully check and audit all values and code paths going\n * into this call. Make sure any user data is appropriately escaped for this security context.\n * For more detail, see the [Security Guide](https://g.co/ng/security).\n *\n * @publicApi\n */\nlet DomSanitizer = /*#__PURE__*/(() => {\n  class DomSanitizer {\n    static #_ = this.ɵfac = function DomSanitizer_Factory(t) {\n      return new (t || DomSanitizer)();\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: DomSanitizer,\n      factory: function DomSanitizer_Factory(t) {\n        let r = null;\n        if (t) {\n          r = new (t || DomSanitizer)();\n        } else {\n          r = i0.ɵɵinject(DomSanitizerImpl);\n        }\n        return r;\n      },\n      providedIn: 'root'\n    });\n  }\n  return DomSanitizer;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet DomSanitizerImpl = /*#__PURE__*/(() => {\n  class DomSanitizerImpl extends DomSanitizer {\n    constructor(_doc) {\n      super();\n      this._doc = _doc;\n    }\n    sanitize(ctx, value) {\n      if (value == null) return null;\n      switch (ctx) {\n        case SecurityContext.NONE:\n          return value;\n        case SecurityContext.HTML:\n          if (ɵallowSanitizationBypassAndThrow(value, \"HTML\" /* BypassType.Html */)) {\n            return ɵunwrapSafeValue(value);\n          }\n          return ɵ_sanitizeHtml(this._doc, String(value)).toString();\n        case SecurityContext.STYLE:\n          if (ɵallowSanitizationBypassAndThrow(value, \"Style\" /* BypassType.Style */)) {\n            return ɵunwrapSafeValue(value);\n          }\n          return value;\n        case SecurityContext.SCRIPT:\n          if (ɵallowSanitizationBypassAndThrow(value, \"Script\" /* BypassType.Script */)) {\n            return ɵunwrapSafeValue(value);\n          }\n          throw new ɵRuntimeError(5200 /* RuntimeErrorCode.SANITIZATION_UNSAFE_SCRIPT */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'unsafe value used in a script context');\n        case SecurityContext.URL:\n          if (ɵallowSanitizationBypassAndThrow(value, \"URL\" /* BypassType.Url */)) {\n            return ɵunwrapSafeValue(value);\n          }\n          return ɵ_sanitizeUrl(String(value));\n        case SecurityContext.RESOURCE_URL:\n          if (ɵallowSanitizationBypassAndThrow(value, \"ResourceURL\" /* BypassType.ResourceUrl */)) {\n            return ɵunwrapSafeValue(value);\n          }\n          throw new ɵRuntimeError(5201 /* RuntimeErrorCode.SANITIZATION_UNSAFE_RESOURCE_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `unsafe value used in a resource URL context (see ${ɵXSS_SECURITY_URL})`);\n        default:\n          throw new ɵRuntimeError(5202 /* RuntimeErrorCode.SANITIZATION_UNEXPECTED_CTX */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Unexpected SecurityContext ${ctx} (see ${ɵXSS_SECURITY_URL})`);\n      }\n    }\n    bypassSecurityTrustHtml(value) {\n      return ɵbypassSanitizationTrustHtml(value);\n    }\n    bypassSecurityTrustStyle(value) {\n      return ɵbypassSanitizationTrustStyle(value);\n    }\n    bypassSecurityTrustScript(value) {\n      return ɵbypassSanitizationTrustScript(value);\n    }\n    bypassSecurityTrustUrl(value) {\n      return ɵbypassSanitizationTrustUrl(value);\n    }\n    bypassSecurityTrustResourceUrl(value) {\n      return ɵbypassSanitizationTrustResourceUrl(value);\n    }\n    static #_ = this.ɵfac = function DomSanitizerImpl_Factory(t) {\n      return new (t || DomSanitizerImpl)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: DomSanitizerImpl,\n      factory: DomSanitizerImpl.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return DomSanitizerImpl;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * The list of features as an enum to uniquely type each `HydrationFeature`.\n * @see {@link HydrationFeature}\n *\n * @publicApi\n */\nvar HydrationFeatureKind = /*#__PURE__*/function (HydrationFeatureKind) {\n  HydrationFeatureKind[HydrationFeatureKind[\"NoHttpTransferCache\"] = 0] = \"NoHttpTransferCache\";\n  HydrationFeatureKind[HydrationFeatureKind[\"HttpTransferCacheOptions\"] = 1] = \"HttpTransferCacheOptions\";\n  return HydrationFeatureKind;\n}(HydrationFeatureKind || {});\n/**\n * Helper function to create an object that represents a Hydration feature.\n */\nfunction hydrationFeature(ɵkind, ɵproviders = [], ɵoptions = {}) {\n  return {\n    ɵkind,\n    ɵproviders\n  };\n}\n/**\n * Disables HTTP transfer cache. Effectively causes HTTP requests to be performed twice: once on the\n * server and other one on the browser.\n *\n * @publicApi\n */\nfunction withNoHttpTransferCache() {\n  // This feature has no providers and acts as a flag that turns off\n  // HTTP transfer cache (which otherwise is turned on by default).\n  return hydrationFeature(HydrationFeatureKind.NoHttpTransferCache);\n}\n/**\n * The function accepts a an object, which allows to configure cache parameters,\n * such as which headers should be included (no headers are included by default),\n * wether POST requests should be cached or a callback function to determine if a\n * particular request should be cached.\n *\n * @publicApi\n */\nfunction withHttpTransferCacheOptions(options) {\n  // This feature has no providers and acts as a flag to pass options to the HTTP transfer cache.\n  return hydrationFeature(HydrationFeatureKind.HttpTransferCacheOptions, ɵwithHttpTransferCache(options));\n}\n/**\n * Returns an `ENVIRONMENT_INITIALIZER` token setup with a function\n * that verifies whether compatible ZoneJS was used in an application\n * and logs a warning in a console if it's not the case.\n */\nfunction provideZoneJsCompatibilityDetector() {\n  return [{\n    provide: ENVIRONMENT_INITIALIZER,\n    useValue: () => {\n      const ngZone = inject(NgZone);\n      // Checking `ngZone instanceof NgZone` would be insufficient here,\n      // because custom implementations might use NgZone as a base class.\n      if (ngZone.constructor !== NgZone) {\n        const console = inject(ɵConsole);\n        const message = ɵformatRuntimeError(-5000 /* RuntimeErrorCode.UNSUPPORTED_ZONEJS_INSTANCE */, 'Angular detected that hydration was enabled for an application ' + 'that uses a custom or a noop Zone.js implementation. ' + 'This is not yet a fully supported configuration.');\n        // tslint:disable-next-line:no-console\n        console.warn(message);\n      }\n    },\n    multi: true\n  }];\n}\n/**\n * Sets up providers necessary to enable hydration functionality for the application.\n *\n * By default, the function enables the recommended set of features for the optimal\n * performance for most of the applications. It includes the following features:\n *\n * * Reconciling DOM hydration. Learn more about it [here](guide/hydration).\n * * [`HttpClient`](api/common/http/HttpClient) response caching while running on the server and\n * transferring this cache to the client to avoid extra HTTP requests. Learn more about data caching\n * [here](/guide/ssr#caching-data-when-using-httpclient).\n *\n * These functions allow you to disable some of the default features or configure features\n * * {@link withNoHttpTransferCache} to disable HTTP transfer cache\n * * {@link withHttpTransferCacheOptions} to configure some HTTP transfer cache options\n *\n * @usageNotes\n *\n * Basic example of how you can enable hydration in your application when\n * `bootstrapApplication` function is used:\n * ```\n * bootstrapApplication(AppComponent, {\n *   providers: [provideClientHydration()]\n * });\n * ```\n *\n * Alternatively if you are using NgModules, you would add `provideClientHydration`\n * to your root app module's provider list.\n * ```\n * @NgModule({\n *   declarations: [RootCmp],\n *   bootstrap: [RootCmp],\n *   providers: [provideClientHydration()],\n * })\n * export class AppModule {}\n * ```\n *\n * @see {@link withNoHttpTransferCache}\n * @see {@link withHttpTransferCacheOptions}\n *\n * @param features Optional features to configure additional router behaviors.\n * @returns A set of providers to enable hydration.\n *\n * @publicApi\n */\nfunction provideClientHydration(...features) {\n  const providers = [];\n  const featuresKind = new Set();\n  const hasHttpTransferCacheOptions = featuresKind.has(HydrationFeatureKind.HttpTransferCacheOptions);\n  for (const {\n    ɵproviders,\n    ɵkind\n  } of features) {\n    featuresKind.add(ɵkind);\n    if (ɵproviders.length) {\n      providers.push(ɵproviders);\n    }\n  }\n  if (typeof ngDevMode !== 'undefined' && ngDevMode && featuresKind.has(HydrationFeatureKind.NoHttpTransferCache) && hasHttpTransferCacheOptions) {\n    // TODO: Make this a runtime error\n    throw new Error('Configuration error: found both withHttpTransferCacheOptions() and withNoHttpTransferCache() in the same call to provideClientHydration(), which is a contradiction.');\n  }\n  return makeEnvironmentProviders([typeof ngDevMode !== 'undefined' && ngDevMode ? provideZoneJsCompatibilityDetector() : [], ɵwithDomHydration(), featuresKind.has(HydrationFeatureKind.NoHttpTransferCache) || hasHttpTransferCacheOptions ? [] : ɵwithHttpTransferCache({}), providers]);\n}\n\n/**\n * @module\n * @description\n * Entry point for all public APIs of the platform-browser package.\n */\n/**\n * @publicApi\n */\nconst VERSION = /*#__PURE__*/new Version('17.3.11');\n\n// Re-export TransferState to the public API of the `platform-browser` for backwards-compatibility.\n/**\n * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.\n *\n * Example:\n *\n * ```\n * const COUNTER_KEY = makeStateKey<number>('counter');\n * let value = 10;\n *\n * transferState.set(COUNTER_KEY, value);\n * ```\n *\n * @publicApi\n * @deprecated `makeStateKey` has moved, please import `makeStateKey` from `@angular/core` instead.\n */\n// The below is a workaround to add a deprecated message.\nconst makeStateKey = makeStateKey$1;\n// The below type is needed for G3 due to JSC_CONFORMANCE_VIOLATION.\nconst TransferState = TransferState$1;\n\n/**\n * @module\n * @description\n * Entry point for all public APIs of this package.\n */\n// This file only reexports content of the `src` folder. Keep it that way.\n\n// This file is not used to build this module. It is only used during editing\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { BrowserModule, By, DomSanitizer, EVENT_MANAGER_PLUGINS, EventManager, EventManagerPlugin, HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerModule, HydrationFeatureKind, Meta, REMOVE_STYLES_ON_COMPONENT_DESTROY, Title, TransferState, VERSION, bootstrapApplication, createApplication, disableDebugTools, enableDebugTools, makeStateKey, platformBrowser, provideClientHydration, provideProtractorTestingSupport, withHttpTransferCacheOptions, withNoHttpTransferCache, BrowserDomAdapter as ɵBrowserDomAdapter, BrowserGetTestability as ɵBrowserGetTestability, DomEventsPlugin as ɵDomEventsPlugin, DomRendererFactory2 as ɵDomRendererFactory2, DomSanitizerImpl as ɵDomSanitizerImpl, HammerGesturesPlugin as ɵHammerGesturesPlugin, INTERNAL_BROWSER_PLATFORM_PROVIDERS as ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS, KeyEventsPlugin as ɵKeyEventsPlugin, SharedStylesHost as ɵSharedStylesHost, initDomAdapter as ɵinitDomAdapter };\n//# sourceMappingURL=platform-browser.mjs.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}