import { APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationModule, ApplicationRef, Attribute, BehaviorSubject, CSP_NONCE, ChangeDetectorRef, Compiler, Component, ConnectableObservable, Console, ContentChildren, DEFAULT_CURRENCY_CODE, DestroyRef, Directive, EMPTY, ENVIRONMENT_INITIALIZER, ElementRef, EmptyError, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, INJECTOR_SCOPE, INTERNAL_APPLICATION_ERROR_HANDLER, Inject, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, LocaleDataIndex, NgModule, NgModuleFactory$1, NgModuleRef$1, NgZone, Observable, Optional, Output, PLATFORM_ID, PLATFORM_INITIALIZER, PendingTasksInternal, Pipe, Renderer2, RendererFactory2, RendererStyleFlags2, ResourceImpl, ResourceStatus, RuntimeError, SecurityContext, SkipSelf, Subject, Subscription, TESTABILITY, TESTABILITY_GETTER, TemplateRef, Testability, TestabilityRegistry, TracingService, TransferState, Version, ViewContainerRef, ViewEncapsulation, XSS_SECURITY_URL, ZONELESS_ENABLED, __objRest, __spreadProps, __spreadValues, _global, _sanitizeHtml, _sanitizeUrl, afterNextRender, allowSanitizationBypassAndThrow, assertInInjectionContext, booleanAttribute, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, catchError, combineLatest, computed, concat, concatMap, createEnvironmentInjector, createNgModule, createPlatformFactory, defaultIfEmpty, defer, filter, finalize, findLocaleData, first, formatRuntimeError, forwardRef, from, getLocalePluralCase, inject, input, internalCreateApplication, isInjectable, isNgModule, isObservable, isPromise, isStandalone, isSubscribable, last, linkedSignal, makeEnvironmentProviders, makeStateKey, map, mergeAll, mergeMap, numberAttribute, of, performanceMarkFeature, pipe, platformCore, refCount, reflectComponentType, runInInjectionContext, scan, setClassMetadata, setDocument, signal, startWith, stringify, switchMap, take, takeLast, takeUntil, tap, throwError, truncateMiddle, untracked, unwrapSafeValue, withDomHydration, ɵɵNgOnChangesFeature, ɵɵattribute, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵelement, ɵɵgetInheritedFactory, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵqueryRefresh, ɵɵsanitizeUrlOrResourceUrl, ɵɵstyleProp } from "./chunk-G3VQHART.js"; // node_modules/@angular/common/fesm2022/common.mjs var _DOM = null; function getDOM() { return _DOM; } function setRootDomAdapter(adapter) { _DOM ??= adapter; } var DomAdapter = class { }; var PlatformNavigation = class _PlatformNavigation { static \u0275fac = function PlatformNavigation_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PlatformNavigation)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _PlatformNavigation, factory: () => (() => window.navigation)(), providedIn: "platform" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PlatformNavigation, [{ type: Injectable, args: [{ providedIn: "platform", useFactory: () => window.navigation }] }], null, null); })(); var DOCUMENT = new InjectionToken(ngDevMode ? "DocumentToken" : ""); var PlatformLocation = class _PlatformLocation { historyGo(relativePosition) { throw new Error(ngDevMode ? "Not implemented" : ""); } static \u0275fac = function PlatformLocation_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PlatformLocation)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _PlatformLocation, factory: () => (() => inject(BrowserPlatformLocation))(), providedIn: "platform" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PlatformLocation, [{ type: Injectable, args: [{ providedIn: "platform", useFactory: () => inject(BrowserPlatformLocation) }] }], null, null); })(); var LOCATION_INITIALIZED = new InjectionToken(ngDevMode ? "Location Initialized" : ""); var BrowserPlatformLocation = class _BrowserPlatformLocation extends PlatformLocation { _location; _history; _doc = inject(DOCUMENT); constructor() { super(); this._location = window.location; this._history = window.history; } getBaseHrefFromDOM() { return getDOM().getBaseHref(this._doc); } onPopState(fn) { const window2 = getDOM().getGlobalEventTarget(this._doc, "window"); window2.addEventListener("popstate", fn, false); return () => window2.removeEventListener("popstate", fn); } onHashChange(fn) { const window2 = getDOM().getGlobalEventTarget(this._doc, "window"); window2.addEventListener("hashchange", fn, false); return () => window2.removeEventListener("hashchange", fn); } get href() { return this._location.href; } get protocol() { return this._location.protocol; } get hostname() { return this._location.hostname; } get port() { return this._location.port; } get pathname() { return this._location.pathname; } get search() { return this._location.search; } get hash() { return this._location.hash; } set pathname(newPath) { this._location.pathname = newPath; } pushState(state, title, url) { this._history.pushState(state, title, url); } replaceState(state, title, url) { this._history.replaceState(state, title, url); } forward() { this._history.forward(); } back() { this._history.back(); } historyGo(relativePosition = 0) { this._history.go(relativePosition); } getState() { return this._history.state; } static \u0275fac = function BrowserPlatformLocation_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _BrowserPlatformLocation)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _BrowserPlatformLocation, factory: () => (() => new _BrowserPlatformLocation())(), providedIn: "platform" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(BrowserPlatformLocation, [{ type: Injectable, args: [{ providedIn: "platform", useFactory: () => new BrowserPlatformLocation() }] }], () => [], null); })(); function joinWithSlash(start, end) { if (!start) return end; if (!end) return start; if (start.endsWith("/")) { return end.startsWith("/") ? start + end.slice(1) : start + end; } return end.startsWith("/") ? start + end : `${start}/${end}`; } function stripTrailingSlash(url) { const pathEndIdx = url.search(/#|\?|$/); return url[pathEndIdx - 1] === "/" ? url.slice(0, pathEndIdx - 1) + url.slice(pathEndIdx) : url; } function normalizeQueryParams(params) { return params && params[0] !== "?" ? `?${params}` : params; } var LocationStrategy = class _LocationStrategy { historyGo(relativePosition) { throw new Error(ngDevMode ? "Not implemented" : ""); } static \u0275fac = function LocationStrategy_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _LocationStrategy)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _LocationStrategy, factory: () => (() => inject(PathLocationStrategy))(), providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(LocationStrategy, [{ type: Injectable, args: [{ providedIn: "root", useFactory: () => inject(PathLocationStrategy) }] }], null, null); })(); var APP_BASE_HREF = new InjectionToken(ngDevMode ? "appBaseHref" : ""); var PathLocationStrategy = class _PathLocationStrategy extends LocationStrategy { _platformLocation; _baseHref; _removeListenerFns = []; constructor(_platformLocation, href) { super(); this._platformLocation = _platformLocation; this._baseHref = href ?? this._platformLocation.getBaseHrefFromDOM() ?? inject(DOCUMENT).location?.origin ?? ""; } /** @nodoc */ ngOnDestroy() { while (this._removeListenerFns.length) { this._removeListenerFns.pop()(); } } onPopState(fn) { this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn)); } getBaseHref() { return this._baseHref; } prepareExternalUrl(internal) { return joinWithSlash(this._baseHref, internal); } path(includeHash = false) { const pathname = this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search); const hash = this._platformLocation.hash; return hash && includeHash ? `${pathname}${hash}` : pathname; } pushState(state, title, url, queryParams) { const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams)); this._platformLocation.pushState(state, title, externalUrl); } replaceState(state, title, url, queryParams) { const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams)); this._platformLocation.replaceState(state, title, externalUrl); } forward() { this._platformLocation.forward(); } back() { this._platformLocation.back(); } getState() { return this._platformLocation.getState(); } historyGo(relativePosition = 0) { this._platformLocation.historyGo?.(relativePosition); } static \u0275fac = function PathLocationStrategy_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PathLocationStrategy)(\u0275\u0275inject(PlatformLocation), \u0275\u0275inject(APP_BASE_HREF, 8)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _PathLocationStrategy, factory: _PathLocationStrategy.\u0275fac, providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PathLocationStrategy, [{ type: Injectable, args: [{ providedIn: "root" }] }], () => [{ type: PlatformLocation }, { type: void 0, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF] }] }], null); })(); var HashLocationStrategy = class _HashLocationStrategy extends LocationStrategy { _platformLocation; _baseHref = ""; _removeListenerFns = []; constructor(_platformLocation, _baseHref) { super(); this._platformLocation = _platformLocation; if (_baseHref != null) { this._baseHref = _baseHref; } } /** @nodoc */ ngOnDestroy() { while (this._removeListenerFns.length) { this._removeListenerFns.pop()(); } } onPopState(fn) { this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn)); } getBaseHref() { return this._baseHref; } path(includeHash = false) { const path = this._platformLocation.hash ?? "#"; return path.length > 0 ? path.substring(1) : path; } prepareExternalUrl(internal) { const url = joinWithSlash(this._baseHref, internal); return url.length > 0 ? "#" + url : url; } pushState(state, title, path, queryParams) { const url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams)) || this._platformLocation.pathname; this._platformLocation.pushState(state, title, url); } replaceState(state, title, path, queryParams) { const url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams)) || this._platformLocation.pathname; this._platformLocation.replaceState(state, title, url); } forward() { this._platformLocation.forward(); } back() { this._platformLocation.back(); } getState() { return this._platformLocation.getState(); } historyGo(relativePosition = 0) { this._platformLocation.historyGo?.(relativePosition); } static \u0275fac = function HashLocationStrategy_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HashLocationStrategy)(\u0275\u0275inject(PlatformLocation), \u0275\u0275inject(APP_BASE_HREF, 8)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HashLocationStrategy, factory: _HashLocationStrategy.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HashLocationStrategy, [{ type: Injectable }], () => [{ type: PlatformLocation }, { type: void 0, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF] }] }], null); })(); var Location = class _Location { /** @internal */ _subject = new Subject(); /** @internal */ _basePath; /** @internal */ _locationStrategy; /** @internal */ _urlChangeListeners = []; /** @internal */ _urlChangeSubscription = null; constructor(locationStrategy) { this._locationStrategy = locationStrategy; const baseHref = this._locationStrategy.getBaseHref(); this._basePath = _stripOrigin(stripTrailingSlash(_stripIndexHtml(baseHref))); this._locationStrategy.onPopState((ev) => { this._subject.next({ "url": this.path(true), "pop": true, "state": ev.state, "type": ev.type }); }); } /** @nodoc */ ngOnDestroy() { this._urlChangeSubscription?.unsubscribe(); this._urlChangeListeners = []; } /** * Normalizes the URL path for this location. * * @param includeHash True to include an anchor fragment in the path. * * @returns The normalized URL path. */ // TODO: vsavkin. Remove the boolean flag and always include hash once the deprecated router is // removed. path(includeHash = false) { return this.normalize(this._locationStrategy.path(includeHash)); } /** * Reports the current state of the location history. * @returns The current value of the `history.state` object. */ getState() { return this._locationStrategy.getState(); } /** * Normalizes the given path and compares to the current normalized path. * * @param path The given URL path. * @param query Query parameters. * * @returns True if the given URL path is equal to the current normalized path, false * otherwise. */ isCurrentPathEqualTo(path, query = "") { return this.path() == this.normalize(path + normalizeQueryParams(query)); } /** * Normalizes a URL path by stripping any trailing slashes. * * @param url String representing a URL. * * @returns The normalized URL string. */ normalize(url) { return _Location.stripTrailingSlash(_stripBasePath(this._basePath, _stripIndexHtml(url))); } /** * Normalizes an external URL path. * If the given URL doesn't begin with a leading slash (`'/'`), adds one * before normalizing. Adds a hash if `HashLocationStrategy` is * in use, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use. * * @param url String representing a URL. * * @returns A normalized platform-specific URL. */ prepareExternalUrl(url) { if (url && url[0] !== "/") { url = "/" + url; } return this._locationStrategy.prepareExternalUrl(url); } // TODO: rename this method to pushState /** * Changes the browser's URL to a normalized version of a given URL, and pushes a * new item onto the platform's history. * * @param path URL path to normalize. * @param query Query parameters. * @param state Location history state. * */ go(path, query = "", state = null) { this._locationStrategy.pushState(state, "", path, query); this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state); } /** * Changes the browser's URL to a normalized version of the given URL, and replaces * the top item on the platform's history stack. * * @param path URL path to normalize. * @param query Query parameters. * @param state Location history state. */ replaceState(path, query = "", state = null) { this._locationStrategy.replaceState(state, "", path, query); this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state); } /** * Navigates forward in the platform's history. */ forward() { this._locationStrategy.forward(); } /** * Navigates back in the platform's history. */ back() { this._locationStrategy.back(); } /** * Navigate to a specific page from session history, identified by its relative position to the * current page. * * @param relativePosition Position of the target page in the history relative to the current * page. * A negative value moves backwards, a positive value moves forwards, e.g. `location.historyGo(2)` * moves forward two pages and `location.historyGo(-2)` moves back two pages. When we try to go * beyond what's stored in the history session, we stay in the current page. Same behaviour occurs * when `relativePosition` equals 0. * @see https://developer.mozilla.org/en-US/docs/Web/API/History_API#Moving_to_a_specific_point_in_history */ historyGo(relativePosition = 0) { this._locationStrategy.historyGo?.(relativePosition); } /** * Registers a URL change listener. Use to catch updates performed by the Angular * framework that are not detectible through "popstate" or "hashchange" events. * * @param fn The change handler function, which take a URL and a location history state. * @returns A function that, when executed, unregisters a URL change listener. */ onUrlChange(fn) { this._urlChangeListeners.push(fn); this._urlChangeSubscription ??= this.subscribe((v) => { this._notifyUrlChangeListeners(v.url, v.state); }); return () => { const fnIndex = this._urlChangeListeners.indexOf(fn); this._urlChangeListeners.splice(fnIndex, 1); if (this._urlChangeListeners.length === 0) { this._urlChangeSubscription?.unsubscribe(); this._urlChangeSubscription = null; } }; } /** @internal */ _notifyUrlChangeListeners(url = "", state) { this._urlChangeListeners.forEach((fn) => fn(url, state)); } /** * Subscribes to the platform's `popState` events. * * Note: `Location.go()` does not trigger the `popState` event in the browser. Use * `Location.onUrlChange()` to subscribe to URL changes instead. * * @param value Event that is triggered when the state history changes. * @param exception The exception to throw. * * @see [onpopstate](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate) * * @returns Subscribed events. */ subscribe(onNext, onThrow, onReturn) { return this._subject.subscribe({ next: onNext, error: onThrow ?? void 0, complete: onReturn ?? void 0 }); } /** * Normalizes URL parameters by prepending with `?` if needed. * * @param params String of URL parameters. * * @returns The normalized URL parameters string. */ static normalizeQueryParams = normalizeQueryParams; /** * Joins two parts of a URL with a slash if needed. * * @param start URL string * @param end URL string * * * @returns The joined URL string. */ static joinWithSlash = joinWithSlash; /** * Removes a trailing slash from a URL string if needed. * Looks for the first occurrence of either `#`, `?`, or the end of the * line as `/` characters and removes the trailing slash if one exists. * * @param url URL string. * * @returns The URL string, modified if needed. */ static stripTrailingSlash = stripTrailingSlash; static \u0275fac = function Location_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _Location)(\u0275\u0275inject(LocationStrategy)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _Location, factory: () => createLocation(), providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Location, [{ type: Injectable, args: [{ providedIn: "root", // See #23917 useFactory: createLocation }] }], () => [{ type: LocationStrategy }], null); })(); function createLocation() { return new Location(\u0275\u0275inject(LocationStrategy)); } function _stripBasePath(basePath, url) { if (!basePath || !url.startsWith(basePath)) { return url; } const strippedUrl = url.substring(basePath.length); if (strippedUrl === "" || ["/", ";", "?", "#"].includes(strippedUrl[0])) { return strippedUrl; } return url; } function _stripIndexHtml(url) { return url.replace(/\/index.html$/, ""); } function _stripOrigin(baseHref) { const isAbsoluteUrl2 = new RegExp("^(https?:)?//").test(baseHref); if (isAbsoluteUrl2) { const [, pathname] = baseHref.split(/\/\/[^\/]+/); return pathname; } return baseHref; } var CURRENCIES_EN = { "ADP": [void 0, void 0, 0], "AFN": [void 0, "\u060B", 0], "ALL": [void 0, void 0, 0], "AMD": [void 0, "\u058F", 2], "AOA": [void 0, "Kz"], "ARS": [void 0, "$"], "AUD": ["A$", "$"], "AZN": [void 0, "\u20BC"], "BAM": [void 0, "KM"], "BBD": [void 0, "$"], "BDT": [void 0, "\u09F3"], "BHD": [void 0, void 0, 3], "BIF": [void 0, void 0, 0], "BMD": [void 0, "$"], "BND": [void 0, "$"], "BOB": [void 0, "Bs"], "BRL": ["R$"], "BSD": [void 0, "$"], "BWP": [void 0, "P"], "BYN": [void 0, void 0, 2], "BYR": [void 0, void 0, 0], "BZD": [void 0, "$"], "CAD": ["CA$", "$", 2], "CHF": [void 0, void 0, 2], "CLF": [void 0, void 0, 4], "CLP": [void 0, "$", 0], "CNY": ["CN\xA5", "\xA5"], "COP": [void 0, "$", 2], "CRC": [void 0, "\u20A1", 2], "CUC": [void 0, "$"], "CUP": [void 0, "$"], "CZK": [void 0, "K\u010D", 2], "DJF": [void 0, void 0, 0], "DKK": [void 0, "kr", 2], "DOP": [void 0, "$"], "EGP": [void 0, "E\xA3"], "ESP": [void 0, "\u20A7", 0], "EUR": ["\u20AC"], "FJD": [void 0, "$"], "FKP": [void 0, "\xA3"], "GBP": ["\xA3"], "GEL": [void 0, "\u20BE"], "GHS": [void 0, "GH\u20B5"], "GIP": [void 0, "\xA3"], "GNF": [void 0, "FG", 0], "GTQ": [void 0, "Q"], "GYD": [void 0, "$", 2], "HKD": ["HK$", "$"], "HNL": [void 0, "L"], "HRK": [void 0, "kn"], "HUF": [void 0, "Ft", 2], "IDR": [void 0, "Rp", 2], "ILS": ["\u20AA"], "INR": ["\u20B9"], "IQD": [void 0, void 0, 0], "IRR": [void 0, void 0, 0], "ISK": [void 0, "kr", 0], "ITL": [void 0, void 0, 0], "JMD": [void 0, "$"], "JOD": [void 0, void 0, 3], "JPY": ["\xA5", void 0, 0], "KHR": [void 0, "\u17DB"], "KMF": [void 0, "CF", 0], "KPW": [void 0, "\u20A9", 0], "KRW": ["\u20A9", void 0, 0], "KWD": [void 0, void 0, 3], "KYD": [void 0, "$"], "KZT": [void 0, "\u20B8"], "LAK": [void 0, "\u20AD", 0], "LBP": [void 0, "L\xA3", 0], "LKR": [void 0, "Rs"], "LRD": [void 0, "$"], "LTL": [void 0, "Lt"], "LUF": [void 0, void 0, 0], "LVL": [void 0, "Ls"], "LYD": [void 0, void 0, 3], "MGA": [void 0, "Ar", 0], "MGF": [void 0, void 0, 0], "MMK": [void 0, "K", 0], "MNT": [void 0, "\u20AE", 2], "MRO": [void 0, void 0, 0], "MUR": [void 0, "Rs", 2], "MXN": ["MX$", "$"], "MYR": [void 0, "RM"], "NAD": [void 0, "$"], "NGN": [void 0, "\u20A6"], "NIO": [void 0, "C$"], "NOK": [void 0, "kr", 2], "NPR": [void 0, "Rs"], "NZD": ["NZ$", "$"], "OMR": [void 0, void 0, 3], "PHP": ["\u20B1"], "PKR": [void 0, "Rs", 2], "PLN": [void 0, "z\u0142"], "PYG": [void 0, "\u20B2", 0], "RON": [void 0, "lei"], "RSD": [void 0, void 0, 0], "RUB": [void 0, "\u20BD"], "RWF": [void 0, "RF", 0], "SBD": [void 0, "$"], "SEK": [void 0, "kr", 2], "SGD": [void 0, "$"], "SHP": [void 0, "\xA3"], "SLE": [void 0, void 0, 2], "SLL": [void 0, void 0, 0], "SOS": [void 0, void 0, 0], "SRD": [void 0, "$"], "SSP": [void 0, "\xA3"], "STD": [void 0, void 0, 0], "STN": [void 0, "Db"], "SYP": [void 0, "\xA3", 0], "THB": [void 0, "\u0E3F"], "TMM": [void 0, void 0, 0], "TND": [void 0, void 0, 3], "TOP": [void 0, "T$"], "TRL": [void 0, void 0, 0], "TRY": [void 0, "\u20BA"], "TTD": [void 0, "$"], "TWD": ["NT$", "$", 2], "TZS": [void 0, void 0, 2], "UAH": [void 0, "\u20B4"], "UGX": [void 0, void 0, 0], "USD": ["$"], "UYI": [void 0, void 0, 0], "UYU": [void 0, "$"], "UYW": [void 0, void 0, 4], "UZS": [void 0, void 0, 2], "VEF": [void 0, "Bs", 2], "VND": ["\u20AB", void 0, 0], "VUV": [void 0, void 0, 0], "XAF": ["FCFA", void 0, 0], "XCD": ["EC$", "$"], "XOF": ["F\u202FCFA", void 0, 0], "XPF": ["CFPF", void 0, 0], "XXX": ["\xA4"], "YER": [void 0, void 0, 0], "ZAR": [void 0, "R"], "ZMK": [void 0, void 0, 0], "ZMW": [void 0, "ZK"], "ZWD": [void 0, void 0, 0] }; var NumberFormatStyle; (function(NumberFormatStyle2) { NumberFormatStyle2[NumberFormatStyle2["Decimal"] = 0] = "Decimal"; NumberFormatStyle2[NumberFormatStyle2["Percent"] = 1] = "Percent"; NumberFormatStyle2[NumberFormatStyle2["Currency"] = 2] = "Currency"; NumberFormatStyle2[NumberFormatStyle2["Scientific"] = 3] = "Scientific"; })(NumberFormatStyle || (NumberFormatStyle = {})); var Plural; (function(Plural2) { Plural2[Plural2["Zero"] = 0] = "Zero"; Plural2[Plural2["One"] = 1] = "One"; Plural2[Plural2["Two"] = 2] = "Two"; Plural2[Plural2["Few"] = 3] = "Few"; Plural2[Plural2["Many"] = 4] = "Many"; Plural2[Plural2["Other"] = 5] = "Other"; })(Plural || (Plural = {})); var FormStyle; (function(FormStyle2) { FormStyle2[FormStyle2["Format"] = 0] = "Format"; FormStyle2[FormStyle2["Standalone"] = 1] = "Standalone"; })(FormStyle || (FormStyle = {})); var TranslationWidth; (function(TranslationWidth2) { TranslationWidth2[TranslationWidth2["Narrow"] = 0] = "Narrow"; TranslationWidth2[TranslationWidth2["Abbreviated"] = 1] = "Abbreviated"; TranslationWidth2[TranslationWidth2["Wide"] = 2] = "Wide"; TranslationWidth2[TranslationWidth2["Short"] = 3] = "Short"; })(TranslationWidth || (TranslationWidth = {})); var FormatWidth; (function(FormatWidth2) { FormatWidth2[FormatWidth2["Short"] = 0] = "Short"; FormatWidth2[FormatWidth2["Medium"] = 1] = "Medium"; FormatWidth2[FormatWidth2["Long"] = 2] = "Long"; FormatWidth2[FormatWidth2["Full"] = 3] = "Full"; })(FormatWidth || (FormatWidth = {})); var NumberSymbol = { /** * Decimal separator. * For `en-US`, the dot character. * Example: 2,345`.`67 */ Decimal: 0, /** * Grouping separator, typically for thousands. * For `en-US`, the comma character. * Example: 2`,`345.67 */ Group: 1, /** * List-item separator. * Example: "one, two, and three" */ List: 2, /** * Sign for percentage (out of 100). * Example: 23.4% */ PercentSign: 3, /** * Sign for positive numbers. * Example: +23 */ PlusSign: 4, /** * Sign for negative numbers. * Example: -23 */ MinusSign: 5, /** * Computer notation for exponential value (n times a power of 10). * Example: 1.2E3 */ Exponential: 6, /** * Human-readable format of exponential. * Example: 1.2x103 */ SuperscriptingExponent: 7, /** * Sign for permille (out of 1000). * Example: 23.4‰ */ PerMille: 8, /** * Infinity, can be used with plus and minus. * Example: ∞, +∞, -∞ */ Infinity: 9, /** * Not a number. * Example: NaN */ NaN: 10, /** * Symbol used between time units. * Example: 10:52 */ TimeSeparator: 11, /** * Decimal separator for currency values (fallback to `Decimal`). * Example: $2,345.67 */ CurrencyDecimal: 12, /** * Group separator for currency values (fallback to `Group`). * Example: $2,345.67 */ CurrencyGroup: 13 }; var WeekDay; (function(WeekDay2) { WeekDay2[WeekDay2["Sunday"] = 0] = "Sunday"; WeekDay2[WeekDay2["Monday"] = 1] = "Monday"; WeekDay2[WeekDay2["Tuesday"] = 2] = "Tuesday"; WeekDay2[WeekDay2["Wednesday"] = 3] = "Wednesday"; WeekDay2[WeekDay2["Thursday"] = 4] = "Thursday"; WeekDay2[WeekDay2["Friday"] = 5] = "Friday"; WeekDay2[WeekDay2["Saturday"] = 6] = "Saturday"; })(WeekDay || (WeekDay = {})); function getLocaleId(locale) { return findLocaleData(locale)[LocaleDataIndex.LocaleId]; } function getLocaleDayPeriods(locale, formStyle, width) { const data = findLocaleData(locale); const amPmData = [data[LocaleDataIndex.DayPeriodsFormat], data[LocaleDataIndex.DayPeriodsStandalone]]; const amPm = getLastDefinedValue(amPmData, formStyle); return getLastDefinedValue(amPm, width); } function getLocaleDayNames(locale, formStyle, width) { const data = findLocaleData(locale); const daysData = [data[LocaleDataIndex.DaysFormat], data[LocaleDataIndex.DaysStandalone]]; const days = getLastDefinedValue(daysData, formStyle); return getLastDefinedValue(days, width); } function getLocaleMonthNames(locale, formStyle, width) { const data = findLocaleData(locale); const monthsData = [data[LocaleDataIndex.MonthsFormat], data[LocaleDataIndex.MonthsStandalone]]; const months = getLastDefinedValue(monthsData, formStyle); return getLastDefinedValue(months, width); } function getLocaleEraNames(locale, width) { const data = findLocaleData(locale); const erasData = data[LocaleDataIndex.Eras]; return getLastDefinedValue(erasData, width); } function getLocaleDateFormat(locale, width) { const data = findLocaleData(locale); return getLastDefinedValue(data[LocaleDataIndex.DateFormat], width); } function getLocaleTimeFormat(locale, width) { const data = findLocaleData(locale); return getLastDefinedValue(data[LocaleDataIndex.TimeFormat], width); } function getLocaleDateTimeFormat(locale, width) { const data = findLocaleData(locale); const dateTimeFormatData = data[LocaleDataIndex.DateTimeFormat]; return getLastDefinedValue(dateTimeFormatData, width); } function getLocaleNumberSymbol(locale, symbol) { const data = findLocaleData(locale); const res = data[LocaleDataIndex.NumberSymbols][symbol]; if (typeof res === "undefined") { if (symbol === NumberSymbol.CurrencyDecimal) { return data[LocaleDataIndex.NumberSymbols][NumberSymbol.Decimal]; } else if (symbol === NumberSymbol.CurrencyGroup) { return data[LocaleDataIndex.NumberSymbols][NumberSymbol.Group]; } } return res; } function getLocaleNumberFormat(locale, type) { const data = findLocaleData(locale); return data[LocaleDataIndex.NumberFormats][type]; } function getLocaleCurrencies(locale) { const data = findLocaleData(locale); return data[LocaleDataIndex.Currencies]; } var getLocalePluralCase2 = getLocalePluralCase; function checkFullData(data) { if (!data[LocaleDataIndex.ExtraData]) { throw new Error(`Missing extra locale data for the locale "${data[LocaleDataIndex.LocaleId]}". Use "registerLocaleData" to load new data. See the "I18n guide" on angular.io to know more.`); } } function getLocaleExtraDayPeriodRules(locale) { const data = findLocaleData(locale); checkFullData(data); const rules = data[LocaleDataIndex.ExtraData][ 2 /* ɵExtraLocaleDataIndex.ExtraDayPeriodsRules */ ] || []; return rules.map((rule) => { if (typeof rule === "string") { return extractTime(rule); } return [extractTime(rule[0]), extractTime(rule[1])]; }); } function getLocaleExtraDayPeriods(locale, formStyle, width) { const data = findLocaleData(locale); checkFullData(data); const dayPeriodsData = [data[LocaleDataIndex.ExtraData][ 0 /* ɵExtraLocaleDataIndex.ExtraDayPeriodFormats */ ], data[LocaleDataIndex.ExtraData][ 1 /* ɵExtraLocaleDataIndex.ExtraDayPeriodStandalone */ ]]; const dayPeriods = getLastDefinedValue(dayPeriodsData, formStyle) || []; return getLastDefinedValue(dayPeriods, width) || []; } function getLastDefinedValue(data, index) { for (let i = index; i > -1; i--) { if (typeof data[i] !== "undefined") { return data[i]; } } throw new Error("Locale data API: locale data undefined"); } function extractTime(time) { const [h, m] = time.split(":"); return { hours: +h, minutes: +m }; } function getCurrencySymbol(code, format, locale = "en") { const currency = getLocaleCurrencies(locale)[code] || CURRENCIES_EN[code] || []; const symbolNarrow = currency[ 1 /* ɵCurrencyIndex.SymbolNarrow */ ]; if (format === "narrow" && typeof symbolNarrow === "string") { return symbolNarrow; } return currency[ 0 /* ɵCurrencyIndex.Symbol */ ] || code; } var DEFAULT_NB_OF_CURRENCY_DIGITS = 2; function getNumberOfCurrencyDigits(code) { let digits; const currency = CURRENCIES_EN[code]; if (currency) { digits = currency[ 2 /* ɵCurrencyIndex.NbOfDigits */ ]; } return typeof digits === "number" ? digits : DEFAULT_NB_OF_CURRENCY_DIGITS; } var ISO8601_DATE_REGEX = /^(\d{4,})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; var NAMED_FORMATS = {}; var DATE_FORMATS_SPLIT = /((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/; function formatDate(value, format, locale, timezone) { let date = toDate(value); const namedFormat = getNamedFormat(locale, format); format = namedFormat || format; let parts = []; let match2; while (format) { match2 = DATE_FORMATS_SPLIT.exec(format); if (match2) { parts = parts.concat(match2.slice(1)); const part = parts.pop(); if (!part) { break; } format = part; } else { parts.push(format); break; } } if (typeof ngDevMode === "undefined" || ngDevMode) { assertValidDateFormat(parts); } let dateTimezoneOffset = date.getTimezoneOffset(); if (timezone) { dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset); date = convertTimezoneToLocal(date, timezone); } let text = ""; parts.forEach((value2) => { const dateFormatter = getDateFormatter(value2); text += dateFormatter ? dateFormatter(date, locale, dateTimezoneOffset) : value2 === "''" ? "'" : value2.replace(/(^'|'$)/g, "").replace(/''/g, "'"); }); return text; } function assertValidDateFormat(parts) { if (parts.some((part) => /^Y+$/.test(part)) && !parts.some((part) => /^w+$/.test(part))) { const message = `Suspicious use of week-based year "Y" in date pattern "${parts.join("")}". Did you mean to use calendar year "y" instead?`; if (parts.length === 1) { console.error(formatRuntimeError(2300, message)); } else { throw new RuntimeError(2300, message); } } } function createDate(year, month, date) { const newDate = /* @__PURE__ */ new Date(0); newDate.setFullYear(year, month, date); newDate.setHours(0, 0, 0); return newDate; } function getNamedFormat(locale, format) { const localeId = getLocaleId(locale); NAMED_FORMATS[localeId] ??= {}; if (NAMED_FORMATS[localeId][format]) { return NAMED_FORMATS[localeId][format]; } let formatValue = ""; switch (format) { case "shortDate": formatValue = getLocaleDateFormat(locale, FormatWidth.Short); break; case "mediumDate": formatValue = getLocaleDateFormat(locale, FormatWidth.Medium); break; case "longDate": formatValue = getLocaleDateFormat(locale, FormatWidth.Long); break; case "fullDate": formatValue = getLocaleDateFormat(locale, FormatWidth.Full); break; case "shortTime": formatValue = getLocaleTimeFormat(locale, FormatWidth.Short); break; case "mediumTime": formatValue = getLocaleTimeFormat(locale, FormatWidth.Medium); break; case "longTime": formatValue = getLocaleTimeFormat(locale, FormatWidth.Long); break; case "fullTime": formatValue = getLocaleTimeFormat(locale, FormatWidth.Full); break; case "short": const shortTime = getNamedFormat(locale, "shortTime"); const shortDate = getNamedFormat(locale, "shortDate"); formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Short), [shortTime, shortDate]); break; case "medium": const mediumTime = getNamedFormat(locale, "mediumTime"); const mediumDate = getNamedFormat(locale, "mediumDate"); formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Medium), [mediumTime, mediumDate]); break; case "long": const longTime = getNamedFormat(locale, "longTime"); const longDate = getNamedFormat(locale, "longDate"); formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Long), [longTime, longDate]); break; case "full": const fullTime = getNamedFormat(locale, "fullTime"); const fullDate = getNamedFormat(locale, "fullDate"); formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Full), [fullTime, fullDate]); break; } if (formatValue) { NAMED_FORMATS[localeId][format] = formatValue; } return formatValue; } function formatDateTime(str, opt_values) { if (opt_values) { str = str.replace(/\{([^}]+)}/g, function(match2, key) { return opt_values != null && key in opt_values ? opt_values[key] : match2; }); } return str; } function padNumber(num, digits, minusSign = "-", trim, negWrap) { let neg = ""; if (num < 0 || negWrap && num <= 0) { if (negWrap) { num = -num + 1; } else { num = -num; neg = minusSign; } } let strNum = String(num); while (strNum.length < digits) { strNum = "0" + strNum; } if (trim) { strNum = strNum.slice(strNum.length - digits); } return neg + strNum; } function formatFractionalSeconds(milliseconds, digits) { const strMs = padNumber(milliseconds, 3); return strMs.substring(0, digits); } function dateGetter(name, size, offset = 0, trim = false, negWrap = false) { return function(date, locale) { let part = getDatePart(name, date); if (offset > 0 || part > -offset) { part += offset; } if (name === 3) { if (part === 0 && offset === -12) { part = 12; } } else if (name === 6) { return formatFractionalSeconds(part, size); } const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign); return padNumber(part, size, localeMinus, trim, negWrap); }; } function getDatePart(part, date) { switch (part) { case 0: return date.getFullYear(); case 1: return date.getMonth(); case 2: return date.getDate(); case 3: return date.getHours(); case 4: return date.getMinutes(); case 5: return date.getSeconds(); case 6: return date.getMilliseconds(); case 7: return date.getDay(); default: throw new RuntimeError(2301, ngDevMode && `Unknown DateType value "${part}".`); } } function dateStrGetter(name, width, form = FormStyle.Format, extended = false) { return function(date, locale) { return getDateTranslation(date, locale, name, width, form, extended); }; } function getDateTranslation(date, locale, name, width, form, extended) { switch (name) { case 2: return getLocaleMonthNames(locale, form, width)[date.getMonth()]; case 1: return getLocaleDayNames(locale, form, width)[date.getDay()]; case 0: const currentHours = date.getHours(); const currentMinutes = date.getMinutes(); if (extended) { const rules = getLocaleExtraDayPeriodRules(locale); const dayPeriods = getLocaleExtraDayPeriods(locale, form, width); const index = rules.findIndex((rule) => { if (Array.isArray(rule)) { const [from2, to] = rule; const afterFrom = currentHours >= from2.hours && currentMinutes >= from2.minutes; const beforeTo = currentHours < to.hours || currentHours === to.hours && currentMinutes < to.minutes; if (from2.hours < to.hours) { if (afterFrom && beforeTo) { return true; } } else if (afterFrom || beforeTo) { return true; } } else { if (rule.hours === currentHours && rule.minutes === currentMinutes) { return true; } } return false; }); if (index !== -1) { return dayPeriods[index]; } } return getLocaleDayPeriods(locale, form, width)[currentHours < 12 ? 0 : 1]; case 3: return getLocaleEraNames(locale, width)[date.getFullYear() <= 0 ? 0 : 1]; default: const unexpected = name; throw new RuntimeError(2302, ngDevMode && `unexpected translation type ${unexpected}`); } } function timeZoneGetter(width) { return function(date, locale, offset) { const zone = -1 * offset; const minusSign = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign); const hours = zone > 0 ? Math.floor(zone / 60) : Math.ceil(zone / 60); switch (width) { case 0: return (zone >= 0 ? "+" : "") + padNumber(hours, 2, minusSign) + padNumber(Math.abs(zone % 60), 2, minusSign); case 1: return "GMT" + (zone >= 0 ? "+" : "") + padNumber(hours, 1, minusSign); case 2: return "GMT" + (zone >= 0 ? "+" : "") + padNumber(hours, 2, minusSign) + ":" + padNumber(Math.abs(zone % 60), 2, minusSign); case 3: if (offset === 0) { return "Z"; } else { return (zone >= 0 ? "+" : "") + padNumber(hours, 2, minusSign) + ":" + padNumber(Math.abs(zone % 60), 2, minusSign); } default: throw new RuntimeError(2302, ngDevMode && `Unknown zone width "${width}"`); } }; } var JANUARY = 0; var THURSDAY = 4; function getFirstThursdayOfYear(year) { const firstDayOfYear = createDate(year, JANUARY, 1).getDay(); return createDate(year, 0, 1 + (firstDayOfYear <= THURSDAY ? THURSDAY : THURSDAY + 7) - firstDayOfYear); } function getThursdayThisIsoWeek(datetime) { const currentDay = datetime.getDay(); const deltaToThursday = currentDay === 0 ? -3 : THURSDAY - currentDay; return createDate(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + deltaToThursday); } function weekGetter(size, monthBased = false) { return function(date, locale) { let result; if (monthBased) { const nbDaysBefore1stDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1).getDay() - 1; const today = date.getDate(); result = 1 + Math.floor((today + nbDaysBefore1stDayOfMonth) / 7); } else { const thisThurs = getThursdayThisIsoWeek(date); const firstThurs = getFirstThursdayOfYear(thisThurs.getFullYear()); const diff = thisThurs.getTime() - firstThurs.getTime(); result = 1 + Math.round(diff / 6048e5); } return padNumber(result, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign)); }; } function weekNumberingYearGetter(size, trim = false) { return function(date, locale) { const thisThurs = getThursdayThisIsoWeek(date); const weekNumberingYear = thisThurs.getFullYear(); return padNumber(weekNumberingYear, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign), trim); }; } var DATE_FORMATS = {}; function getDateFormatter(format) { if (DATE_FORMATS[format]) { return DATE_FORMATS[format]; } let formatter; switch (format) { // Era name (AD/BC) case "G": case "GG": case "GGG": formatter = dateStrGetter(3, TranslationWidth.Abbreviated); break; case "GGGG": formatter = dateStrGetter(3, TranslationWidth.Wide); break; case "GGGGG": formatter = dateStrGetter(3, TranslationWidth.Narrow); break; // 1 digit representation of the year, e.g. (AD 1 => 1, AD 199 => 199) case "y": formatter = dateGetter(0, 1, 0, false, true); break; // 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) case "yy": formatter = dateGetter(0, 2, 0, true, true); break; // 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10) case "yyy": formatter = dateGetter(0, 3, 0, false, true); break; // 4 digit representation of the year (e.g. AD 1 => 0001, AD 2010 => 2010) case "yyyy": formatter = dateGetter(0, 4, 0, false, true); break; // 1 digit representation of the week-numbering year, e.g. (AD 1 => 1, AD 199 => 199) case "Y": formatter = weekNumberingYearGetter(1); break; // 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD // 2010 => 10) case "YY": formatter = weekNumberingYearGetter(2, true); break; // 3 digit representation of the week-numbering year, padded (000-999). (e.g. AD 1 => 001, AD // 2010 => 2010) case "YYY": formatter = weekNumberingYearGetter(3); break; // 4 digit representation of the week-numbering year (e.g. AD 1 => 0001, AD 2010 => 2010) case "YYYY": formatter = weekNumberingYearGetter(4); break; // Month of the year (1-12), numeric case "M": case "L": formatter = dateGetter(1, 1, 1); break; case "MM": case "LL": formatter = dateGetter(1, 2, 1); break; // Month of the year (January, ...), string, format case "MMM": formatter = dateStrGetter(2, TranslationWidth.Abbreviated); break; case "MMMM": formatter = dateStrGetter(2, TranslationWidth.Wide); break; case "MMMMM": formatter = dateStrGetter(2, TranslationWidth.Narrow); break; // Month of the year (January, ...), string, standalone case "LLL": formatter = dateStrGetter(2, TranslationWidth.Abbreviated, FormStyle.Standalone); break; case "LLLL": formatter = dateStrGetter(2, TranslationWidth.Wide, FormStyle.Standalone); break; case "LLLLL": formatter = dateStrGetter(2, TranslationWidth.Narrow, FormStyle.Standalone); break; // Week of the year (1, ... 52) case "w": formatter = weekGetter(1); break; case "ww": formatter = weekGetter(2); break; // Week of the month (1, ...) case "W": formatter = weekGetter(1, true); break; // Day of the month (1-31) case "d": formatter = dateGetter(2, 1); break; case "dd": formatter = dateGetter(2, 2); break; // Day of the Week StandAlone (1, 1, Mon, Monday, M, Mo) case "c": case "cc": formatter = dateGetter(7, 1); break; case "ccc": formatter = dateStrGetter(1, TranslationWidth.Abbreviated, FormStyle.Standalone); break; case "cccc": formatter = dateStrGetter(1, TranslationWidth.Wide, FormStyle.Standalone); break; case "ccccc": formatter = dateStrGetter(1, TranslationWidth.Narrow, FormStyle.Standalone); break; case "cccccc": formatter = dateStrGetter(1, TranslationWidth.Short, FormStyle.Standalone); break; // Day of the Week case "E": case "EE": case "EEE": formatter = dateStrGetter(1, TranslationWidth.Abbreviated); break; case "EEEE": formatter = dateStrGetter(1, TranslationWidth.Wide); break; case "EEEEE": formatter = dateStrGetter(1, TranslationWidth.Narrow); break; case "EEEEEE": formatter = dateStrGetter(1, TranslationWidth.Short); break; // Generic period of the day (am-pm) case "a": case "aa": case "aaa": formatter = dateStrGetter(0, TranslationWidth.Abbreviated); break; case "aaaa": formatter = dateStrGetter(0, TranslationWidth.Wide); break; case "aaaaa": formatter = dateStrGetter(0, TranslationWidth.Narrow); break; // Extended period of the day (midnight, at night, ...), standalone case "b": case "bb": case "bbb": formatter = dateStrGetter(0, TranslationWidth.Abbreviated, FormStyle.Standalone, true); break; case "bbbb": formatter = dateStrGetter(0, TranslationWidth.Wide, FormStyle.Standalone, true); break; case "bbbbb": formatter = dateStrGetter(0, TranslationWidth.Narrow, FormStyle.Standalone, true); break; // Extended period of the day (midnight, night, ...), standalone case "B": case "BB": case "BBB": formatter = dateStrGetter(0, TranslationWidth.Abbreviated, FormStyle.Format, true); break; case "BBBB": formatter = dateStrGetter(0, TranslationWidth.Wide, FormStyle.Format, true); break; case "BBBBB": formatter = dateStrGetter(0, TranslationWidth.Narrow, FormStyle.Format, true); break; // Hour in AM/PM, (1-12) case "h": formatter = dateGetter(3, 1, -12); break; case "hh": formatter = dateGetter(3, 2, -12); break; // Hour of the day (0-23) case "H": formatter = dateGetter(3, 1); break; // Hour in day, padded (00-23) case "HH": formatter = dateGetter(3, 2); break; // Minute of the hour (0-59) case "m": formatter = dateGetter(4, 1); break; case "mm": formatter = dateGetter(4, 2); break; // Second of the minute (0-59) case "s": formatter = dateGetter(5, 1); break; case "ss": formatter = dateGetter(5, 2); break; // Fractional second case "S": formatter = dateGetter(6, 1); break; case "SS": formatter = dateGetter(6, 2); break; case "SSS": formatter = dateGetter(6, 3); break; // Timezone ISO8601 short format (-0430) case "Z": case "ZZ": case "ZZZ": formatter = timeZoneGetter( 0 /* ZoneWidth.Short */ ); break; // Timezone ISO8601 extended format (-04:30) case "ZZZZZ": formatter = timeZoneGetter( 3 /* ZoneWidth.Extended */ ); break; // Timezone GMT short format (GMT+4) case "O": case "OO": case "OOO": // Should be location, but fallback to format O instead because we don't have the data yet case "z": case "zz": case "zzz": formatter = timeZoneGetter( 1 /* ZoneWidth.ShortGMT */ ); break; // Timezone GMT long format (GMT+0430) case "OOOO": case "ZZZZ": // Should be location, but fallback to format O instead because we don't have the data yet case "zzzz": formatter = timeZoneGetter( 2 /* ZoneWidth.Long */ ); break; default: return null; } DATE_FORMATS[format] = formatter; return formatter; } function timezoneToOffset(timezone, fallback) { timezone = timezone.replace(/:/g, ""); const requestedTimezoneOffset = Date.parse("Jan 01, 1970 00:00:00 " + timezone) / 6e4; return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset; } function addDateMinutes(date, minutes) { date = new Date(date.getTime()); date.setMinutes(date.getMinutes() + minutes); return date; } function convertTimezoneToLocal(date, timezone, reverse) { const reverseValue = -1; const dateTimezoneOffset = date.getTimezoneOffset(); const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset); return addDateMinutes(date, reverseValue * (timezoneOffset - dateTimezoneOffset)); } function toDate(value) { if (isDate(value)) { return value; } if (typeof value === "number" && !isNaN(value)) { return new Date(value); } if (typeof value === "string") { value = value.trim(); if (/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(value)) { const [y, m = 1, d = 1] = value.split("-").map((val) => +val); return createDate(y, m - 1, d); } const parsedNb = parseFloat(value); if (!isNaN(value - parsedNb)) { return new Date(parsedNb); } let match2; if (match2 = value.match(ISO8601_DATE_REGEX)) { return isoStringToDate(match2); } } const date = new Date(value); if (!isDate(date)) { throw new RuntimeError(2302, ngDevMode && `Unable to convert "${value}" into a date`); } return date; } function isoStringToDate(match2) { const date = /* @__PURE__ */ new Date(0); let tzHour = 0; let tzMin = 0; const dateSetter = match2[8] ? date.setUTCFullYear : date.setFullYear; const timeSetter = match2[8] ? date.setUTCHours : date.setHours; if (match2[9]) { tzHour = Number(match2[9] + match2[10]); tzMin = Number(match2[9] + match2[11]); } dateSetter.call(date, Number(match2[1]), Number(match2[2]) - 1, Number(match2[3])); const h = Number(match2[4] || 0) - tzHour; const m = Number(match2[5] || 0) - tzMin; const s = Number(match2[6] || 0); const ms = Math.floor(parseFloat("0." + (match2[7] || 0)) * 1e3); timeSetter.call(date, h, m, s, ms); return date; } function isDate(value) { return value instanceof Date && !isNaN(value.valueOf()); } var NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/; var MAX_DIGITS = 22; var DECIMAL_SEP = "."; var ZERO_CHAR = "0"; var PATTERN_SEP = ";"; var GROUP_SEP = ","; var DIGIT_CHAR = "#"; var CURRENCY_CHAR = "\xA4"; var PERCENT_CHAR = "%"; function formatNumberToLocaleString(value, pattern, locale, groupSymbol, decimalSymbol, digitsInfo, isPercent = false) { let formattedText = ""; let isZero = false; if (!isFinite(value)) { formattedText = getLocaleNumberSymbol(locale, NumberSymbol.Infinity); } else { let parsedNumber = parseNumber(value); if (isPercent) { parsedNumber = toPercent(parsedNumber); } let minInt = pattern.minInt; let minFraction = pattern.minFrac; let maxFraction = pattern.maxFrac; if (digitsInfo) { const parts = digitsInfo.match(NUMBER_FORMAT_REGEXP); if (parts === null) { throw new Error(`${digitsInfo} is not a valid digit info`); } const minIntPart = parts[1]; const minFractionPart = parts[3]; const maxFractionPart = parts[5]; if (minIntPart != null) { minInt = parseIntAutoRadix(minIntPart); } if (minFractionPart != null) { minFraction = parseIntAutoRadix(minFractionPart); } if (maxFractionPart != null) { maxFraction = parseIntAutoRadix(maxFractionPart); } else if (minFractionPart != null && minFraction > maxFraction) { maxFraction = minFraction; } } roundNumber(parsedNumber, minFraction, maxFraction); let digits = parsedNumber.digits; let integerLen = parsedNumber.integerLen; const exponent = parsedNumber.exponent; let decimals = []; isZero = digits.every((d) => !d); for (; integerLen < minInt; integerLen++) { digits.unshift(0); } for (; integerLen < 0; integerLen++) { digits.unshift(0); } if (integerLen > 0) { decimals = digits.splice(integerLen, digits.length); } else { decimals = digits; digits = [0]; } const groups = []; if (digits.length >= pattern.lgSize) { groups.unshift(digits.splice(-pattern.lgSize, digits.length).join("")); } while (digits.length > pattern.gSize) { groups.unshift(digits.splice(-pattern.gSize, digits.length).join("")); } if (digits.length) { groups.unshift(digits.join("")); } formattedText = groups.join(getLocaleNumberSymbol(locale, groupSymbol)); if (decimals.length) { formattedText += getLocaleNumberSymbol(locale, decimalSymbol) + decimals.join(""); } if (exponent) { formattedText += getLocaleNumberSymbol(locale, NumberSymbol.Exponential) + "+" + exponent; } } if (value < 0 && !isZero) { formattedText = pattern.negPre + formattedText + pattern.negSuf; } else { formattedText = pattern.posPre + formattedText + pattern.posSuf; } return formattedText; } function formatCurrency(value, locale, currency, currencyCode, digitsInfo) { const format = getLocaleNumberFormat(locale, NumberFormatStyle.Currency); const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign)); pattern.minFrac = getNumberOfCurrencyDigits(currencyCode); pattern.maxFrac = pattern.minFrac; const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.CurrencyGroup, NumberSymbol.CurrencyDecimal, digitsInfo); return res.replace(CURRENCY_CHAR, currency).replace(CURRENCY_CHAR, "").trim(); } function formatPercent(value, locale, digitsInfo) { const format = getLocaleNumberFormat(locale, NumberFormatStyle.Percent); const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign)); const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo, true); return res.replace(new RegExp(PERCENT_CHAR, "g"), getLocaleNumberSymbol(locale, NumberSymbol.PercentSign)); } function formatNumber(value, locale, digitsInfo) { const format = getLocaleNumberFormat(locale, NumberFormatStyle.Decimal); const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign)); return formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo); } function parseNumberFormat(format, minusSign = "-") { const p = { minInt: 1, minFrac: 0, maxFrac: 0, posPre: "", posSuf: "", negPre: "", negSuf: "", gSize: 0, lgSize: 0 }; const patternParts = format.split(PATTERN_SEP); const positive = patternParts[0]; const negative = patternParts[1]; const positiveParts = positive.indexOf(DECIMAL_SEP) !== -1 ? positive.split(DECIMAL_SEP) : [positive.substring(0, positive.lastIndexOf(ZERO_CHAR) + 1), positive.substring(positive.lastIndexOf(ZERO_CHAR) + 1)], integer = positiveParts[0], fraction = positiveParts[1] || ""; p.posPre = integer.substring(0, integer.indexOf(DIGIT_CHAR)); for (let i = 0; i < fraction.length; i++) { const ch = fraction.charAt(i); if (ch === ZERO_CHAR) { p.minFrac = p.maxFrac = i + 1; } else if (ch === DIGIT_CHAR) { p.maxFrac = i + 1; } else { p.posSuf += ch; } } const groups = integer.split(GROUP_SEP); p.gSize = groups[1] ? groups[1].length : 0; p.lgSize = groups[2] || groups[1] ? (groups[2] || groups[1]).length : 0; if (negative) { const trunkLen = positive.length - p.posPre.length - p.posSuf.length, pos = negative.indexOf(DIGIT_CHAR); p.negPre = negative.substring(0, pos).replace(/'/g, ""); p.negSuf = negative.slice(pos + trunkLen).replace(/'/g, ""); } else { p.negPre = minusSign + p.posPre; p.negSuf = p.posSuf; } return p; } function toPercent(parsedNumber) { if (parsedNumber.digits[0] === 0) { return parsedNumber; } const fractionLen = parsedNumber.digits.length - parsedNumber.integerLen; if (parsedNumber.exponent) { parsedNumber.exponent += 2; } else { if (fractionLen === 0) { parsedNumber.digits.push(0, 0); } else if (fractionLen === 1) { parsedNumber.digits.push(0); } parsedNumber.integerLen += 2; } return parsedNumber; } function parseNumber(num) { let numStr = Math.abs(num) + ""; let exponent = 0, digits, integerLen; let i, j, zeros; if ((integerLen = numStr.indexOf(DECIMAL_SEP)) > -1) { numStr = numStr.replace(DECIMAL_SEP, ""); } if ((i = numStr.search(/e/i)) > 0) { if (integerLen < 0) integerLen = i; integerLen += +numStr.slice(i + 1); numStr = numStr.substring(0, i); } else if (integerLen < 0) { integerLen = numStr.length; } for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { } if (i === (zeros = numStr.length)) { digits = [0]; integerLen = 1; } else { zeros--; while (numStr.charAt(zeros) === ZERO_CHAR) zeros--; integerLen -= i; digits = []; for (j = 0; i <= zeros; i++, j++) { digits[j] = Number(numStr.charAt(i)); } } if (integerLen > MAX_DIGITS) { digits = digits.splice(0, MAX_DIGITS - 1); exponent = integerLen - 1; integerLen = 1; } return { digits, exponent, integerLen }; } function roundNumber(parsedNumber, minFrac, maxFrac) { if (minFrac > maxFrac) { throw new Error(`The minimum number of digits after fraction (${minFrac}) is higher than the maximum (${maxFrac}).`); } let digits = parsedNumber.digits; let fractionLen = digits.length - parsedNumber.integerLen; const fractionSize = Math.min(Math.max(minFrac, fractionLen), maxFrac); let roundAt = fractionSize + parsedNumber.integerLen; let digit = digits[roundAt]; if (roundAt > 0) { digits.splice(Math.max(parsedNumber.integerLen, roundAt)); for (let j = roundAt; j < digits.length; j++) { digits[j] = 0; } } else { fractionLen = Math.max(0, fractionLen); parsedNumber.integerLen = 1; digits.length = Math.max(1, roundAt = fractionSize + 1); digits[0] = 0; for (let i = 1; i < roundAt; i++) digits[i] = 0; } if (digit >= 5) { if (roundAt - 1 < 0) { for (let k = 0; k > roundAt; k--) { digits.unshift(0); parsedNumber.integerLen++; } digits.unshift(1); parsedNumber.integerLen++; } else { digits[roundAt - 1]++; } } for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0); let dropTrailingZeros = fractionSize !== 0; const minLen = minFrac + parsedNumber.integerLen; const carry = digits.reduceRight(function(carry2, d, i, digits2) { d = d + carry2; digits2[i] = d < 10 ? d : d - 10; if (dropTrailingZeros) { if (digits2[i] === 0 && i >= minLen) { digits2.pop(); } else { dropTrailingZeros = false; } } return d >= 10 ? 1 : 0; }, 0); if (carry) { digits.unshift(carry); parsedNumber.integerLen++; } } function parseIntAutoRadix(text) { const result = parseInt(text); if (isNaN(result)) { throw new Error("Invalid integer literal when parsing " + text); } return result; } var NgLocalization = class _NgLocalization { static \u0275fac = function NgLocalization_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgLocalization)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _NgLocalization, factory: function NgLocalization_Factory(__ngFactoryType__) { let __ngConditionalFactory__ = null; if (__ngFactoryType__) { __ngConditionalFactory__ = new __ngFactoryType__(); } else { __ngConditionalFactory__ = ((locale) => new NgLocaleLocalization(locale))(\u0275\u0275inject(LOCALE_ID)); } return __ngConditionalFactory__; }, providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgLocalization, [{ type: Injectable, args: [{ providedIn: "root", useFactory: (locale) => new NgLocaleLocalization(locale), deps: [LOCALE_ID] }] }], null, null); })(); function getPluralCategory(value, cases, ngLocalization, locale) { let key = `=${value}`; if (cases.indexOf(key) > -1) { return key; } key = ngLocalization.getPluralCategory(value, locale); if (cases.indexOf(key) > -1) { return key; } if (cases.indexOf("other") > -1) { return "other"; } throw new Error(`No plural message found for value "${value}"`); } var NgLocaleLocalization = class _NgLocaleLocalization extends NgLocalization { locale; constructor(locale) { super(); this.locale = locale; } getPluralCategory(value, locale) { const plural = getLocalePluralCase2(locale || this.locale)(value); switch (plural) { case Plural.Zero: return "zero"; case Plural.One: return "one"; case Plural.Two: return "two"; case Plural.Few: return "few"; case Plural.Many: return "many"; default: return "other"; } } static \u0275fac = function NgLocaleLocalization_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgLocaleLocalization)(\u0275\u0275inject(LOCALE_ID)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _NgLocaleLocalization, factory: _NgLocaleLocalization.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgLocaleLocalization, [{ type: Injectable }], () => [{ type: void 0, decorators: [{ type: Inject, args: [LOCALE_ID] }] }], null); })(); function parseCookieValue(cookieStr, name) { name = encodeURIComponent(name); for (const cookie of cookieStr.split(";")) { const eqIndex = cookie.indexOf("="); const [cookieName, cookieValue] = eqIndex == -1 ? [cookie, ""] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)]; if (cookieName.trim() === name) { return decodeURIComponent(cookieValue); } } return null; } var WS_REGEXP = /\s+/; var EMPTY_ARRAY = []; var NgClass = class _NgClass { _ngEl; _renderer; initialClasses = EMPTY_ARRAY; rawClass; stateMap = /* @__PURE__ */ new Map(); constructor(_ngEl, _renderer) { this._ngEl = _ngEl; this._renderer = _renderer; } set klass(value) { this.initialClasses = value != null ? value.trim().split(WS_REGEXP) : EMPTY_ARRAY; } set ngClass(value) { this.rawClass = typeof value === "string" ? value.trim().split(WS_REGEXP) : value; } /* The NgClass directive uses the custom change detection algorithm for its inputs. The custom algorithm is necessary since inputs are represented as complex object or arrays that need to be deeply-compared. This algorithm is perf-sensitive since NgClass is used very frequently and its poor performance might negatively impact runtime performance of the entire change detection cycle. The design of this algorithm is making sure that: - there is no unnecessary DOM manipulation (CSS classes are added / removed from the DOM only when needed), even if references to bound objects change; - there is no memory allocation if nothing changes (even relatively modest memory allocation during the change detection cycle can result in GC pauses for some of the CD cycles). The algorithm works by iterating over the set of bound classes, staring with [class] binding and then going over [ngClass] binding. For each CSS class name: - check if it was seen before (this information is tracked in the state map) and if its value changed; - mark it as "touched" - names that are not marked are not present in the latest set of binding and we can remove such class name from the internal data structures; After iteration over all the CSS class names we've got data structure with all the information necessary to synchronize changes to the DOM - it is enough to iterate over the state map, flush changes to the DOM and reset internal data structures so those are ready for the next change detection cycle. */ ngDoCheck() { for (const klass of this.initialClasses) { this._updateState(klass, true); } const rawClass = this.rawClass; if (Array.isArray(rawClass) || rawClass instanceof Set) { for (const klass of rawClass) { this._updateState(klass, true); } } else if (rawClass != null) { for (const klass of Object.keys(rawClass)) { this._updateState(klass, Boolean(rawClass[klass])); } } this._applyStateDiff(); } _updateState(klass, nextEnabled) { const state = this.stateMap.get(klass); if (state !== void 0) { if (state.enabled !== nextEnabled) { state.changed = true; state.enabled = nextEnabled; } state.touched = true; } else { this.stateMap.set(klass, { enabled: nextEnabled, changed: true, touched: true }); } } _applyStateDiff() { for (const stateEntry of this.stateMap) { const klass = stateEntry[0]; const state = stateEntry[1]; if (state.changed) { this._toggleClass(klass, state.enabled); state.changed = false; } else if (!state.touched) { if (state.enabled) { this._toggleClass(klass, false); } this.stateMap.delete(klass); } state.touched = false; } } _toggleClass(klass, enabled) { if (ngDevMode) { if (typeof klass !== "string") { throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${stringify(klass)}`); } } klass = klass.trim(); if (klass.length > 0) { klass.split(WS_REGEXP).forEach((klass2) => { if (enabled) { this._renderer.addClass(this._ngEl.nativeElement, klass2); } else { this._renderer.removeClass(this._ngEl.nativeElement, klass2); } }); } } static \u0275fac = function NgClass_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgClass)(\u0275\u0275directiveInject(ElementRef), \u0275\u0275directiveInject(Renderer2)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgClass, selectors: [["", "ngClass", ""]], inputs: { klass: [0, "class", "klass"], ngClass: "ngClass" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgClass, [{ type: Directive, args: [{ selector: "[ngClass]" }] }], () => [{ type: ElementRef }, { type: Renderer2 }], { klass: [{ type: Input, args: ["class"] }], ngClass: [{ type: Input, args: ["ngClass"] }] }); })(); var NgComponentOutlet = class _NgComponentOutlet { _viewContainerRef; // TODO(crisbeto): this should be `Type`, but doing so broke a few // targets in a TGP so we need to do it in a major version. /** Component that should be rendered in the outlet. */ ngComponentOutlet = null; ngComponentOutletInputs; ngComponentOutletInjector; ngComponentOutletContent; ngComponentOutletNgModule; /** * @deprecated This input is deprecated, use `ngComponentOutletNgModule` instead. */ ngComponentOutletNgModuleFactory; _componentRef; _moduleRef; /** * A helper data structure that allows us to track inputs that were part of the * ngComponentOutletInputs expression. Tracking inputs is necessary for proper removal of ones * that are no longer referenced. */ _inputsUsed = /* @__PURE__ */ new Map(); /** * Gets the instance of the currently-rendered component. * Will be null if no component has been rendered. */ get componentInstance() { return this._componentRef?.instance ?? null; } constructor(_viewContainerRef) { this._viewContainerRef = _viewContainerRef; } _needToReCreateNgModuleInstance(changes) { return changes["ngComponentOutletNgModule"] !== void 0 || changes["ngComponentOutletNgModuleFactory"] !== void 0; } _needToReCreateComponentInstance(changes) { return changes["ngComponentOutlet"] !== void 0 || changes["ngComponentOutletContent"] !== void 0 || changes["ngComponentOutletInjector"] !== void 0 || this._needToReCreateNgModuleInstance(changes); } /** @nodoc */ ngOnChanges(changes) { if (this._needToReCreateComponentInstance(changes)) { this._viewContainerRef.clear(); this._inputsUsed.clear(); this._componentRef = void 0; if (this.ngComponentOutlet) { const injector = this.ngComponentOutletInjector || this._viewContainerRef.parentInjector; if (this._needToReCreateNgModuleInstance(changes)) { this._moduleRef?.destroy(); if (this.ngComponentOutletNgModule) { this._moduleRef = createNgModule(this.ngComponentOutletNgModule, getParentInjector(injector)); } else if (this.ngComponentOutletNgModuleFactory) { this._moduleRef = this.ngComponentOutletNgModuleFactory.create(getParentInjector(injector)); } else { this._moduleRef = void 0; } } this._componentRef = this._viewContainerRef.createComponent(this.ngComponentOutlet, { injector, ngModuleRef: this._moduleRef, projectableNodes: this.ngComponentOutletContent }); } } } /** @nodoc */ ngDoCheck() { if (this._componentRef) { if (this.ngComponentOutletInputs) { for (const inputName of Object.keys(this.ngComponentOutletInputs)) { this._inputsUsed.set(inputName, true); } } this._applyInputStateDiff(this._componentRef); } } /** @nodoc */ ngOnDestroy() { this._moduleRef?.destroy(); } _applyInputStateDiff(componentRef) { for (const [inputName, touched] of this._inputsUsed) { if (!touched) { componentRef.setInput(inputName, void 0); this._inputsUsed.delete(inputName); } else { componentRef.setInput(inputName, this.ngComponentOutletInputs[inputName]); this._inputsUsed.set(inputName, false); } } } static \u0275fac = function NgComponentOutlet_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgComponentOutlet)(\u0275\u0275directiveInject(ViewContainerRef)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgComponentOutlet, selectors: [["", "ngComponentOutlet", ""]], inputs: { ngComponentOutlet: "ngComponentOutlet", ngComponentOutletInputs: "ngComponentOutletInputs", ngComponentOutletInjector: "ngComponentOutletInjector", ngComponentOutletContent: "ngComponentOutletContent", ngComponentOutletNgModule: "ngComponentOutletNgModule", ngComponentOutletNgModuleFactory: "ngComponentOutletNgModuleFactory" }, exportAs: ["ngComponentOutlet"], features: [\u0275\u0275NgOnChangesFeature] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgComponentOutlet, [{ type: Directive, args: [{ selector: "[ngComponentOutlet]", exportAs: "ngComponentOutlet" }] }], () => [{ type: ViewContainerRef }], { ngComponentOutlet: [{ type: Input }], ngComponentOutletInputs: [{ type: Input }], ngComponentOutletInjector: [{ type: Input }], ngComponentOutletContent: [{ type: Input }], ngComponentOutletNgModule: [{ type: Input }], ngComponentOutletNgModuleFactory: [{ type: Input }] }); })(); function getParentInjector(injector) { const parentNgModule = injector.get(NgModuleRef$1); return parentNgModule.injector; } var NgForOfContext = class { $implicit; ngForOf; index; count; constructor($implicit, ngForOf, index, count) { this.$implicit = $implicit; this.ngForOf = ngForOf; this.index = index; this.count = count; } // Indicates whether this is the first item in the collection. get first() { return this.index === 0; } // Indicates whether this is the last item in the collection. get last() { return this.index === this.count - 1; } // Indicates whether an index of this item in the collection is even. get even() { return this.index % 2 === 0; } // Indicates whether an index of this item in the collection is odd. get odd() { return !this.even; } }; var NgForOf = class _NgForOf { _viewContainer; _template; _differs; /** * The value of the iterable expression, which can be used as a * [template input variable](guide/directives/structural-directives#shorthand). */ set ngForOf(ngForOf) { this._ngForOf = ngForOf; this._ngForOfDirty = true; } /** * Specifies a custom `TrackByFunction` to compute the identity of items in an iterable. * * If a custom `TrackByFunction` is not provided, `NgForOf` will use the item's [object * identity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) * as the key. * * `NgForOf` uses the computed key to associate items in an iterable with DOM elements * it produces for these items. * * A custom `TrackByFunction` is useful to provide good user experience in cases when items in an * iterable rendered using `NgForOf` have a natural identifier (for example, custom ID or a * primary key), and this iterable could be updated with new object instances that still * represent the same underlying entity (for example, when data is re-fetched from the server, * and the iterable is recreated and re-rendered, but most of the data is still the same). * * @see {@link TrackByFunction} */ set ngForTrackBy(fn) { if ((typeof ngDevMode === "undefined" || ngDevMode) && fn != null && typeof fn !== "function") { console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}. See https://angular.io/api/common/NgForOf#change-propagation for more information.`); } this._trackByFn = fn; } get ngForTrackBy() { return this._trackByFn; } _ngForOf = null; _ngForOfDirty = true; _differ = null; // TODO(issue/24571): remove '!' // waiting for microsoft/typescript#43662 to allow the return type `TrackByFunction|undefined` for // the getter _trackByFn; constructor(_viewContainer, _template, _differs) { this._viewContainer = _viewContainer; this._template = _template; this._differs = _differs; } /** * A reference to the template that is stamped out for each item in the iterable. * @see [template reference variable](guide/templates/variables#template-reference-variables) */ set ngForTemplate(value) { if (value) { this._template = value; } } /** * Applies the changes when needed. * @nodoc */ ngDoCheck() { if (this._ngForOfDirty) { this._ngForOfDirty = false; const value = this._ngForOf; if (!this._differ && value) { if (typeof ngDevMode === "undefined" || ngDevMode) { try { this._differ = this._differs.find(value).create(this.ngForTrackBy); } catch { let errorMessage = `Cannot find a differ supporting object '${value}' of type '${getTypeName(value)}'. NgFor only supports binding to Iterables, such as Arrays.`; if (typeof value === "object") { errorMessage += " Did you mean to use the keyvalue pipe?"; } throw new RuntimeError(-2200, errorMessage); } } else { this._differ = this._differs.find(value).create(this.ngForTrackBy); } } } if (this._differ) { const changes = this._differ.diff(this._ngForOf); if (changes) this._applyChanges(changes); } } _applyChanges(changes) { const viewContainer = this._viewContainer; changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => { if (item.previousIndex == null) { viewContainer.createEmbeddedView(this._template, new NgForOfContext(item.item, this._ngForOf, -1, -1), currentIndex === null ? void 0 : currentIndex); } else if (currentIndex == null) { viewContainer.remove(adjustedPreviousIndex === null ? void 0 : adjustedPreviousIndex); } else if (adjustedPreviousIndex !== null) { const view = viewContainer.get(adjustedPreviousIndex); viewContainer.move(view, currentIndex); applyViewChange(view, item); } }); for (let i = 0, ilen = viewContainer.length; i < ilen; i++) { const viewRef = viewContainer.get(i); const context = viewRef.context; context.index = i; context.count = ilen; context.ngForOf = this._ngForOf; } changes.forEachIdentityChange((record) => { const viewRef = viewContainer.get(record.currentIndex); applyViewChange(viewRef, record); }); } /** * Asserts the correct type of the context for the template that `NgForOf` will render. * * The presence of this method is a signal to the Ivy template type-check compiler that the * `NgForOf` structural directive renders its template with a specific context type. */ static ngTemplateContextGuard(dir, ctx) { return true; } static \u0275fac = function NgForOf_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgForOf)(\u0275\u0275directiveInject(ViewContainerRef), \u0275\u0275directiveInject(TemplateRef), \u0275\u0275directiveInject(IterableDiffers)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgForOf, selectors: [["", "ngFor", "", "ngForOf", ""]], inputs: { ngForOf: "ngForOf", ngForTrackBy: "ngForTrackBy", ngForTemplate: "ngForTemplate" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgForOf, [{ type: Directive, args: [{ selector: "[ngFor][ngForOf]" }] }], () => [{ type: ViewContainerRef }, { type: TemplateRef }, { type: IterableDiffers }], { ngForOf: [{ type: Input }], ngForTrackBy: [{ type: Input }], ngForTemplate: [{ type: Input }] }); })(); function applyViewChange(view, record) { view.context.$implicit = record.item; } function getTypeName(type) { return type["name"] || typeof type; } var NgIf = class _NgIf { _viewContainer; _context = new NgIfContext(); _thenTemplateRef = null; _elseTemplateRef = null; _thenViewRef = null; _elseViewRef = null; constructor(_viewContainer, templateRef) { this._viewContainer = _viewContainer; this._thenTemplateRef = templateRef; } /** * The Boolean expression to evaluate as the condition for showing a template. */ set ngIf(condition) { this._context.$implicit = this._context.ngIf = condition; this._updateView(); } /** * A template to show if the condition expression evaluates to true. */ set ngIfThen(templateRef) { assertTemplate(templateRef, (typeof ngDevMode === "undefined" || ngDevMode) && "ngIfThen"); this._thenTemplateRef = templateRef; this._thenViewRef = null; this._updateView(); } /** * A template to show if the condition expression evaluates to false. */ set ngIfElse(templateRef) { assertTemplate(templateRef, (typeof ngDevMode === "undefined" || ngDevMode) && "ngIfElse"); this._elseTemplateRef = templateRef; this._elseViewRef = null; this._updateView(); } _updateView() { if (this._context.$implicit) { if (!this._thenViewRef) { this._viewContainer.clear(); this._elseViewRef = null; if (this._thenTemplateRef) { this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context); } } } else { if (!this._elseViewRef) { this._viewContainer.clear(); this._thenViewRef = null; if (this._elseTemplateRef) { this._elseViewRef = this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context); } } } } /** @internal */ static ngIfUseIfTypeGuard; /** * Assert the correct type of the expression bound to the `ngIf` input within the template. * * The presence of this static field is a signal to the Ivy template type check compiler that * when the `NgIf` structural directive renders its template, the type of the expression bound * to `ngIf` should be narrowed in some way. For `NgIf`, the binding expression itself is used to * narrow its type, which allows the strictNullChecks feature of TypeScript to work with `NgIf`. */ static ngTemplateGuard_ngIf; /** * Asserts the correct type of the context for the template that `NgIf` will render. * * The presence of this method is a signal to the Ivy template type-check compiler that the * `NgIf` structural directive renders its template with a specific context type. */ static ngTemplateContextGuard(dir, ctx) { return true; } static \u0275fac = function NgIf_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgIf)(\u0275\u0275directiveInject(ViewContainerRef), \u0275\u0275directiveInject(TemplateRef)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgIf, selectors: [["", "ngIf", ""]], inputs: { ngIf: "ngIf", ngIfThen: "ngIfThen", ngIfElse: "ngIfElse" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgIf, [{ type: Directive, args: [{ selector: "[ngIf]" }] }], () => [{ type: ViewContainerRef }, { type: TemplateRef }], { ngIf: [{ type: Input }], ngIfThen: [{ type: Input }], ngIfElse: [{ type: Input }] }); })(); var NgIfContext = class { $implicit = null; ngIf = null; }; function assertTemplate(templateRef, property) { if (templateRef && !templateRef.createEmbeddedView) { throw new RuntimeError(2020, (typeof ngDevMode === "undefined" || ngDevMode) && `${property} must be a TemplateRef, but received '${stringify(templateRef)}'.`); } } var SwitchView = class { _viewContainerRef; _templateRef; _created = false; constructor(_viewContainerRef, _templateRef) { this._viewContainerRef = _viewContainerRef; this._templateRef = _templateRef; } create() { this._created = true; this._viewContainerRef.createEmbeddedView(this._templateRef); } destroy() { this._created = false; this._viewContainerRef.clear(); } enforceState(created) { if (created && !this._created) { this.create(); } else if (!created && this._created) { this.destroy(); } } }; var NgSwitch = class _NgSwitch { _defaultViews = []; _defaultUsed = false; _caseCount = 0; _lastCaseCheckIndex = 0; _lastCasesMatched = false; _ngSwitch; set ngSwitch(newValue) { this._ngSwitch = newValue; if (this._caseCount === 0) { this._updateDefaultCases(true); } } /** @internal */ _addCase() { return this._caseCount++; } /** @internal */ _addDefault(view) { this._defaultViews.push(view); } /** @internal */ _matchCase(value) { const matched = value === this._ngSwitch; this._lastCasesMatched ||= matched; this._lastCaseCheckIndex++; if (this._lastCaseCheckIndex === this._caseCount) { this._updateDefaultCases(!this._lastCasesMatched); this._lastCaseCheckIndex = 0; this._lastCasesMatched = false; } return matched; } _updateDefaultCases(useDefault) { if (this._defaultViews.length > 0 && useDefault !== this._defaultUsed) { this._defaultUsed = useDefault; for (const defaultView of this._defaultViews) { defaultView.enforceState(useDefault); } } } static \u0275fac = function NgSwitch_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgSwitch)(); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgSwitch, selectors: [["", "ngSwitch", ""]], inputs: { ngSwitch: "ngSwitch" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgSwitch, [{ type: Directive, args: [{ selector: "[ngSwitch]" }] }], null, { ngSwitch: [{ type: Input }] }); })(); var NgSwitchCase = class _NgSwitchCase { ngSwitch; _view; /** * Stores the HTML template to be selected on match. */ ngSwitchCase; constructor(viewContainer, templateRef, ngSwitch) { this.ngSwitch = ngSwitch; if ((typeof ngDevMode === "undefined" || ngDevMode) && !ngSwitch) { throwNgSwitchProviderNotFoundError("ngSwitchCase", "NgSwitchCase"); } ngSwitch._addCase(); this._view = new SwitchView(viewContainer, templateRef); } /** * Performs case matching. For internal use only. * @nodoc */ ngDoCheck() { this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase)); } static \u0275fac = function NgSwitchCase_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgSwitchCase)(\u0275\u0275directiveInject(ViewContainerRef), \u0275\u0275directiveInject(TemplateRef), \u0275\u0275directiveInject(NgSwitch, 9)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgSwitchCase, selectors: [["", "ngSwitchCase", ""]], inputs: { ngSwitchCase: "ngSwitchCase" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgSwitchCase, [{ type: Directive, args: [{ selector: "[ngSwitchCase]" }] }], () => [{ type: ViewContainerRef }, { type: TemplateRef }, { type: NgSwitch, decorators: [{ type: Optional }, { type: Host }] }], { ngSwitchCase: [{ type: Input }] }); })(); var NgSwitchDefault = class _NgSwitchDefault { constructor(viewContainer, templateRef, ngSwitch) { if ((typeof ngDevMode === "undefined" || ngDevMode) && !ngSwitch) { throwNgSwitchProviderNotFoundError("ngSwitchDefault", "NgSwitchDefault"); } ngSwitch._addDefault(new SwitchView(viewContainer, templateRef)); } static \u0275fac = function NgSwitchDefault_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgSwitchDefault)(\u0275\u0275directiveInject(ViewContainerRef), \u0275\u0275directiveInject(TemplateRef), \u0275\u0275directiveInject(NgSwitch, 9)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgSwitchDefault, selectors: [["", "ngSwitchDefault", ""]] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgSwitchDefault, [{ type: Directive, args: [{ selector: "[ngSwitchDefault]" }] }], () => [{ type: ViewContainerRef }, { type: TemplateRef }, { type: NgSwitch, decorators: [{ type: Optional }, { type: Host }] }], null); })(); function throwNgSwitchProviderNotFoundError(attrName, directiveName) { throw new RuntimeError(2e3, `An element with the "${attrName}" attribute (matching the "${directiveName}" directive) must be located inside an element with the "ngSwitch" attribute (matching "NgSwitch" directive)`); } var NgPlural = class _NgPlural { _localization; _activeView; _caseViews = {}; constructor(_localization) { this._localization = _localization; } set ngPlural(value) { this._updateView(value); } addCase(value, switchView) { this._caseViews[value] = switchView; } _updateView(switchValue) { this._clearViews(); const cases = Object.keys(this._caseViews); const key = getPluralCategory(switchValue, cases, this._localization); this._activateView(this._caseViews[key]); } _clearViews() { if (this._activeView) this._activeView.destroy(); } _activateView(view) { if (view) { this._activeView = view; this._activeView.create(); } } static \u0275fac = function NgPlural_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgPlural)(\u0275\u0275directiveInject(NgLocalization)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgPlural, selectors: [["", "ngPlural", ""]], inputs: { ngPlural: "ngPlural" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgPlural, [{ type: Directive, args: [{ selector: "[ngPlural]" }] }], () => [{ type: NgLocalization }], { ngPlural: [{ type: Input }] }); })(); var NgPluralCase = class _NgPluralCase { value; constructor(value, template, viewContainer, ngPlural) { this.value = value; const isANumber = !isNaN(Number(value)); ngPlural.addCase(isANumber ? `=${value}` : value, new SwitchView(viewContainer, template)); } static \u0275fac = function NgPluralCase_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgPluralCase)(\u0275\u0275injectAttribute("ngPluralCase"), \u0275\u0275directiveInject(TemplateRef), \u0275\u0275directiveInject(ViewContainerRef), \u0275\u0275directiveInject(NgPlural, 1)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgPluralCase, selectors: [["", "ngPluralCase", ""]] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgPluralCase, [{ type: Directive, args: [{ selector: "[ngPluralCase]" }] }], () => [{ type: void 0, decorators: [{ type: Attribute, args: ["ngPluralCase"] }] }, { type: TemplateRef }, { type: ViewContainerRef }, { type: NgPlural, decorators: [{ type: Host }] }], null); })(); var NgStyle = class _NgStyle { _ngEl; _differs; _renderer; _ngStyle = null; _differ = null; constructor(_ngEl, _differs, _renderer) { this._ngEl = _ngEl; this._differs = _differs; this._renderer = _renderer; } set ngStyle(values) { this._ngStyle = values; if (!this._differ && values) { this._differ = this._differs.find(values).create(); } } ngDoCheck() { if (this._differ) { const changes = this._differ.diff(this._ngStyle); if (changes) { this._applyChanges(changes); } } } _setStyle(nameAndUnit, value) { const [name, unit] = nameAndUnit.split("."); const flags = name.indexOf("-") === -1 ? void 0 : RendererStyleFlags2.DashCase; if (value != null) { this._renderer.setStyle(this._ngEl.nativeElement, name, unit ? `${value}${unit}` : value, flags); } else { this._renderer.removeStyle(this._ngEl.nativeElement, name, flags); } } _applyChanges(changes) { changes.forEachRemovedItem((record) => this._setStyle(record.key, null)); changes.forEachAddedItem((record) => this._setStyle(record.key, record.currentValue)); changes.forEachChangedItem((record) => this._setStyle(record.key, record.currentValue)); } static \u0275fac = function NgStyle_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgStyle)(\u0275\u0275directiveInject(ElementRef), \u0275\u0275directiveInject(KeyValueDiffers), \u0275\u0275directiveInject(Renderer2)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgStyle, selectors: [["", "ngStyle", ""]], inputs: { ngStyle: "ngStyle" } }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgStyle, [{ type: Directive, args: [{ selector: "[ngStyle]" }] }], () => [{ type: ElementRef }, { type: KeyValueDiffers }, { type: Renderer2 }], { ngStyle: [{ type: Input, args: ["ngStyle"] }] }); })(); var NgTemplateOutlet = class _NgTemplateOutlet { _viewContainerRef; _viewRef = null; /** * A context object to attach to the {@link EmbeddedViewRef}. This should be an * object, the object's keys will be available for binding by the local template `let` * declarations. * Using the key `$implicit` in the context object will set its value as default. */ ngTemplateOutletContext = null; /** * A string defining the template reference and optionally the context object for the template. */ ngTemplateOutlet = null; /** Injector to be used within the embedded view. */ ngTemplateOutletInjector = null; constructor(_viewContainerRef) { this._viewContainerRef = _viewContainerRef; } ngOnChanges(changes) { if (this._shouldRecreateView(changes)) { const viewContainerRef = this._viewContainerRef; if (this._viewRef) { viewContainerRef.remove(viewContainerRef.indexOf(this._viewRef)); } if (!this.ngTemplateOutlet) { this._viewRef = null; return; } const viewContext = this._createContextForwardProxy(); this._viewRef = viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, viewContext, { injector: this.ngTemplateOutletInjector ?? void 0 }); } } /** * We need to re-create existing embedded view if either is true: * - the outlet changed. * - the injector changed. */ _shouldRecreateView(changes) { return !!changes["ngTemplateOutlet"] || !!changes["ngTemplateOutletInjector"]; } /** * For a given outlet instance, we create a proxy object that delegates * to the user-specified context. This allows changing, or swapping out * the context object completely without having to destroy/re-create the view. */ _createContextForwardProxy() { return new Proxy({}, { set: (_target, prop, newValue) => { if (!this.ngTemplateOutletContext) { return false; } return Reflect.set(this.ngTemplateOutletContext, prop, newValue); }, get: (_target, prop, receiver) => { if (!this.ngTemplateOutletContext) { return void 0; } return Reflect.get(this.ngTemplateOutletContext, prop, receiver); } }); } static \u0275fac = function NgTemplateOutlet_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgTemplateOutlet)(\u0275\u0275directiveInject(ViewContainerRef)); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgTemplateOutlet, selectors: [["", "ngTemplateOutlet", ""]], inputs: { ngTemplateOutletContext: "ngTemplateOutletContext", ngTemplateOutlet: "ngTemplateOutlet", ngTemplateOutletInjector: "ngTemplateOutletInjector" }, features: [\u0275\u0275NgOnChangesFeature] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgTemplateOutlet, [{ type: Directive, args: [{ selector: "[ngTemplateOutlet]" }] }], () => [{ type: ViewContainerRef }], { ngTemplateOutletContext: [{ type: Input }], ngTemplateOutlet: [{ type: Input }], ngTemplateOutletInjector: [{ type: Input }] }); })(); var COMMON_DIRECTIVES = [NgClass, NgComponentOutlet, NgForOf, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase]; function invalidPipeArgumentError(type, value) { return new RuntimeError(2100, ngDevMode && `InvalidPipeArgument: '${value}' for pipe '${stringify(type)}'`); } var SubscribableStrategy = class { createSubscription(async, updateLatestValue, onError) { return untracked(() => async.subscribe({ next: updateLatestValue, error: onError })); } dispose(subscription) { untracked(() => subscription.unsubscribe()); } }; var PromiseStrategy = class { createSubscription(async, updateLatestValue, onError) { return async.then(updateLatestValue, onError); } dispose(subscription) { } }; var _promiseStrategy = new PromiseStrategy(); var _subscribableStrategy = new SubscribableStrategy(); var AsyncPipe = class _AsyncPipe { _ref; _latestValue = null; markForCheckOnValueUpdate = true; _subscription = null; _obj = null; _strategy = null; applicationErrorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER); constructor(ref) { this._ref = ref; } ngOnDestroy() { if (this._subscription) { this._dispose(); } this._ref = null; } transform(obj) { if (!this._obj) { if (obj) { try { this.markForCheckOnValueUpdate = false; this._subscribe(obj); } finally { this.markForCheckOnValueUpdate = true; } } return this._latestValue; } if (obj !== this._obj) { this._dispose(); return this.transform(obj); } return this._latestValue; } _subscribe(obj) { this._obj = obj; this._strategy = this._selectStrategy(obj); this._subscription = this._strategy.createSubscription(obj, (value) => this._updateLatestValue(obj, value), (e) => this.applicationErrorHandler(e)); } _selectStrategy(obj) { if (isPromise(obj)) { return _promiseStrategy; } if (isSubscribable(obj)) { return _subscribableStrategy; } throw invalidPipeArgumentError(_AsyncPipe, obj); } _dispose() { this._strategy.dispose(this._subscription); this._latestValue = null; this._subscription = null; this._obj = null; } _updateLatestValue(async, value) { if (async === this._obj) { this._latestValue = value; if (this.markForCheckOnValueUpdate) { this._ref?.markForCheck(); } } } static \u0275fac = function AsyncPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _AsyncPipe)(\u0275\u0275directiveInject(ChangeDetectorRef, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "async", type: _AsyncPipe, pure: false }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(AsyncPipe, [{ type: Pipe, args: [{ name: "async", pure: false }] }], () => [{ type: ChangeDetectorRef }], null); })(); var LowerCasePipe = class _LowerCasePipe { transform(value) { if (value == null) return null; if (typeof value !== "string") { throw invalidPipeArgumentError(_LowerCasePipe, value); } return value.toLowerCase(); } static \u0275fac = function LowerCasePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _LowerCasePipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "lowercase", type: _LowerCasePipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(LowerCasePipe, [{ type: Pipe, args: [{ name: "lowercase" }] }], null, null); })(); var unicodeWordMatch = /(?:[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])\S*/g; var TitleCasePipe = class _TitleCasePipe { transform(value) { if (value == null) return null; if (typeof value !== "string") { throw invalidPipeArgumentError(_TitleCasePipe, value); } return value.replace(unicodeWordMatch, (txt) => txt[0].toUpperCase() + txt.slice(1).toLowerCase()); } static \u0275fac = function TitleCasePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _TitleCasePipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "titlecase", type: _TitleCasePipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(TitleCasePipe, [{ type: Pipe, args: [{ name: "titlecase" }] }], null, null); })(); var UpperCasePipe = class _UpperCasePipe { transform(value) { if (value == null) return null; if (typeof value !== "string") { throw invalidPipeArgumentError(_UpperCasePipe, value); } return value.toUpperCase(); } static \u0275fac = function UpperCasePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _UpperCasePipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "uppercase", type: _UpperCasePipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(UpperCasePipe, [{ type: Pipe, args: [{ name: "uppercase" }] }], null, null); })(); var DEFAULT_DATE_FORMAT = "mediumDate"; var DATE_PIPE_DEFAULT_TIMEZONE = new InjectionToken(ngDevMode ? "DATE_PIPE_DEFAULT_TIMEZONE" : ""); var DATE_PIPE_DEFAULT_OPTIONS = new InjectionToken(ngDevMode ? "DATE_PIPE_DEFAULT_OPTIONS" : ""); var DatePipe = class _DatePipe { locale; defaultTimezone; defaultOptions; constructor(locale, defaultTimezone, defaultOptions) { this.locale = locale; this.defaultTimezone = defaultTimezone; this.defaultOptions = defaultOptions; } transform(value, format, timezone, locale) { if (value == null || value === "" || value !== value) return null; try { const _format = format ?? this.defaultOptions?.dateFormat ?? DEFAULT_DATE_FORMAT; const _timezone = timezone ?? this.defaultOptions?.timezone ?? this.defaultTimezone ?? void 0; return formatDate(value, _format, locale || this.locale, _timezone); } catch (error) { throw invalidPipeArgumentError(_DatePipe, error.message); } } static \u0275fac = function DatePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _DatePipe)(\u0275\u0275directiveInject(LOCALE_ID, 16), \u0275\u0275directiveInject(DATE_PIPE_DEFAULT_TIMEZONE, 24), \u0275\u0275directiveInject(DATE_PIPE_DEFAULT_OPTIONS, 24)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "date", type: _DatePipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DatePipe, [{ type: Pipe, args: [{ name: "date" }] }], () => [{ type: void 0, decorators: [{ type: Inject, args: [LOCALE_ID] }] }, { type: void 0, decorators: [{ type: Inject, args: [DATE_PIPE_DEFAULT_TIMEZONE] }, { type: Optional }] }, { type: void 0, decorators: [{ type: Inject, args: [DATE_PIPE_DEFAULT_OPTIONS] }, { type: Optional }] }], null); })(); var _INTERPOLATION_REGEXP = /#/g; var I18nPluralPipe = class _I18nPluralPipe { _localization; constructor(_localization) { this._localization = _localization; } /** * @param value the number to be formatted * @param pluralMap an object that mimics the ICU format, see * https://unicode-org.github.io/icu/userguide/format_parse/messages/. * @param locale a `string` defining the locale to use (uses the current {@link LOCALE_ID} by * default). */ transform(value, pluralMap, locale) { if (value == null) return ""; if (typeof pluralMap !== "object" || pluralMap === null) { throw invalidPipeArgumentError(_I18nPluralPipe, pluralMap); } const key = getPluralCategory(value, Object.keys(pluralMap), this._localization, locale); return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString()); } static \u0275fac = function I18nPluralPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _I18nPluralPipe)(\u0275\u0275directiveInject(NgLocalization, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "i18nPlural", type: _I18nPluralPipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(I18nPluralPipe, [{ type: Pipe, args: [{ name: "i18nPlural" }] }], () => [{ type: NgLocalization }], null); })(); var I18nSelectPipe = class _I18nSelectPipe { /** * @param value a string to be internationalized. * @param mapping an object that indicates the text that should be displayed * for different values of the provided `value`. */ transform(value, mapping) { if (value == null) return ""; if (typeof mapping !== "object" || typeof value !== "string") { throw invalidPipeArgumentError(_I18nSelectPipe, mapping); } if (mapping.hasOwnProperty(value)) { return mapping[value]; } if (mapping.hasOwnProperty("other")) { return mapping["other"]; } return ""; } static \u0275fac = function I18nSelectPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _I18nSelectPipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "i18nSelect", type: _I18nSelectPipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(I18nSelectPipe, [{ type: Pipe, args: [{ name: "i18nSelect" }] }], null, null); })(); var JsonPipe = class _JsonPipe { /** * @param value A value of any type to convert into a JSON-format string. */ transform(value) { return JSON.stringify(value, null, 2); } static \u0275fac = function JsonPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _JsonPipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "json", type: _JsonPipe, pure: false }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(JsonPipe, [{ type: Pipe, args: [{ name: "json", pure: false }] }], null, null); })(); function makeKeyValuePair(key, value) { return { key, value }; } var KeyValuePipe = class _KeyValuePipe { differs; constructor(differs) { this.differs = differs; } differ; keyValues = []; compareFn = defaultComparator; transform(input2, compareFn = defaultComparator) { if (!input2 || !(input2 instanceof Map) && typeof input2 !== "object") { return null; } this.differ ??= this.differs.find(input2).create(); const differChanges = this.differ.diff(input2); const compareFnChanged = compareFn !== this.compareFn; if (differChanges) { this.keyValues = []; differChanges.forEachItem((r) => { this.keyValues.push(makeKeyValuePair(r.key, r.currentValue)); }); } if (differChanges || compareFnChanged) { if (compareFn) { this.keyValues.sort(compareFn); } this.compareFn = compareFn; } return this.keyValues; } static \u0275fac = function KeyValuePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _KeyValuePipe)(\u0275\u0275directiveInject(KeyValueDiffers, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "keyvalue", type: _KeyValuePipe, pure: false }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(KeyValuePipe, [{ type: Pipe, args: [{ name: "keyvalue", pure: false }] }], () => [{ type: KeyValueDiffers }], null); })(); function defaultComparator(keyValueA, keyValueB) { const a = keyValueA.key; const b = keyValueB.key; if (a === b) return 0; if (a == null) return 1; if (b == null) return -1; if (typeof a == "string" && typeof b == "string") { return a < b ? -1 : 1; } if (typeof a == "number" && typeof b == "number") { return a - b; } if (typeof a == "boolean" && typeof b == "boolean") { return a < b ? -1 : 1; } const aString = String(a); const bString = String(b); return aString == bString ? 0 : aString < bString ? -1 : 1; } var DecimalPipe = class _DecimalPipe { _locale; constructor(_locale) { this._locale = _locale; } transform(value, digitsInfo, locale) { if (!isValue(value)) return null; locale ||= this._locale; try { const num = strToNumber(value); return formatNumber(num, locale, digitsInfo); } catch (error) { throw invalidPipeArgumentError(_DecimalPipe, error.message); } } static \u0275fac = function DecimalPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _DecimalPipe)(\u0275\u0275directiveInject(LOCALE_ID, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "number", type: _DecimalPipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DecimalPipe, [{ type: Pipe, args: [{ name: "number" }] }], () => [{ type: void 0, decorators: [{ type: Inject, args: [LOCALE_ID] }] }], null); })(); var PercentPipe = class _PercentPipe { _locale; constructor(_locale) { this._locale = _locale; } /** * * @param value The number to be formatted as a percentage. * @param digitsInfo Decimal representation options, specified by a string * in the following format:
* {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}. * - `minIntegerDigits`: The minimum number of integer digits before the decimal point. * Default is `1`. * - `minFractionDigits`: The minimum number of digits after the decimal point. * Default is `0`. * - `maxFractionDigits`: The maximum number of digits after the decimal point. * Default is `0`. * @param locale A locale code for the locale format rules to use. * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default. * See [Setting your app locale](guide/i18n/locale-id). */ transform(value, digitsInfo, locale) { if (!isValue(value)) return null; locale ||= this._locale; try { const num = strToNumber(value); return formatPercent(num, locale, digitsInfo); } catch (error) { throw invalidPipeArgumentError(_PercentPipe, error.message); } } static \u0275fac = function PercentPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PercentPipe)(\u0275\u0275directiveInject(LOCALE_ID, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "percent", type: _PercentPipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PercentPipe, [{ type: Pipe, args: [{ name: "percent" }] }], () => [{ type: void 0, decorators: [{ type: Inject, args: [LOCALE_ID] }] }], null); })(); var CurrencyPipe = class _CurrencyPipe { _locale; _defaultCurrencyCode; constructor(_locale, _defaultCurrencyCode = "USD") { this._locale = _locale; this._defaultCurrencyCode = _defaultCurrencyCode; } transform(value, currencyCode = this._defaultCurrencyCode, display = "symbol", digitsInfo, locale) { if (!isValue(value)) return null; locale ||= this._locale; if (typeof display === "boolean") { if ((typeof ngDevMode === "undefined" || ngDevMode) && console && console.warn) { console.warn(`Warning: the currency pipe has been changed in Angular v5. The symbolDisplay option (third parameter) is now a string instead of a boolean. The accepted values are "code", "symbol" or "symbol-narrow".`); } display = display ? "symbol" : "code"; } let currency = currencyCode || this._defaultCurrencyCode; if (display !== "code") { if (display === "symbol" || display === "symbol-narrow") { currency = getCurrencySymbol(currency, display === "symbol" ? "wide" : "narrow", locale); } else { currency = display; } } try { const num = strToNumber(value); return formatCurrency(num, locale, currency, currencyCode, digitsInfo); } catch (error) { throw invalidPipeArgumentError(_CurrencyPipe, error.message); } } static \u0275fac = function CurrencyPipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _CurrencyPipe)(\u0275\u0275directiveInject(LOCALE_ID, 16), \u0275\u0275directiveInject(DEFAULT_CURRENCY_CODE, 16)); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "currency", type: _CurrencyPipe, pure: true }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CurrencyPipe, [{ type: Pipe, args: [{ name: "currency" }] }], () => [{ type: void 0, decorators: [{ type: Inject, args: [LOCALE_ID] }] }, { type: void 0, decorators: [{ type: Inject, args: [DEFAULT_CURRENCY_CODE] }] }], null); })(); function isValue(value) { return !(value == null || value === "" || value !== value); } function strToNumber(value) { if (typeof value === "string" && !isNaN(Number(value) - parseFloat(value))) { return Number(value); } if (typeof value !== "number") { throw new Error(`${value} is not a number`); } return value; } var SlicePipe = class _SlicePipe { transform(value, start, end) { if (value == null) return null; const supports = typeof value === "string" || Array.isArray(value); if (!supports) { throw invalidPipeArgumentError(_SlicePipe, value); } return value.slice(start, end); } static \u0275fac = function SlicePipe_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _SlicePipe)(); }; static \u0275pipe = /* @__PURE__ */ \u0275\u0275definePipe({ name: "slice", type: _SlicePipe, pure: false }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(SlicePipe, [{ type: Pipe, args: [{ name: "slice", pure: false }] }], null, null); })(); var COMMON_PIPES = [AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe, TitleCasePipe, CurrencyPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, KeyValuePipe]; var CommonModule = class _CommonModule { static \u0275fac = function CommonModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _CommonModule)(); }; static \u0275mod = /* @__PURE__ */ \u0275\u0275defineNgModule({ type: _CommonModule }); static \u0275inj = /* @__PURE__ */ \u0275\u0275defineInjector({}); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CommonModule, [{ type: NgModule, args: [{ imports: [COMMON_DIRECTIVES, COMMON_PIPES], exports: [COMMON_DIRECTIVES, COMMON_PIPES] }] }], null, null); })(); var PLATFORM_BROWSER_ID = "browser"; var PLATFORM_SERVER_ID = "server"; function isPlatformBrowser(platformId) { return platformId === PLATFORM_BROWSER_ID; } function isPlatformServer(platformId) { return platformId === PLATFORM_SERVER_ID; } var VERSION = new Version("0.0.0"); var ViewportScroller = class _ViewportScroller { // De-sugared tree-shakable injection // See #23917 /** @nocollapse */ static \u0275prov = ( /** @pureOrBreakMyCode */ /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _ViewportScroller, providedIn: "root", factory: () => false ? new NullViewportScroller() : new BrowserViewportScroller(inject(DOCUMENT), window) }) ); }; var BrowserViewportScroller = class { document; window; offset = () => [0, 0]; constructor(document2, window2) { this.document = document2; this.window = window2; } /** * Configures the top offset used when scrolling to an anchor. * @param offset A position in screen coordinates (a tuple with x and y values) * or a function that returns the top offset position. * */ setOffset(offset) { if (Array.isArray(offset)) { this.offset = () => offset; } else { this.offset = offset; } } /** * Retrieves the current scroll position. * @returns The position in screen coordinates. */ getScrollPosition() { return [this.window.scrollX, this.window.scrollY]; } /** * Sets the scroll position. * @param position The new position in screen coordinates. */ scrollToPosition(position) { this.window.scrollTo(position[0], position[1]); } /** * Scrolls to an element and attempts to focus the element. * * Note that the function name here is misleading in that the target string may be an ID for a * non-anchor element. * * @param target The ID of an element or name of the anchor. * * @see https://html.spec.whatwg.org/#the-indicated-part-of-the-document * @see https://html.spec.whatwg.org/#scroll-to-fragid */ scrollToAnchor(target) { const elSelected = findAnchorFromDocument(this.document, target); if (elSelected) { this.scrollToElement(elSelected); elSelected.focus(); } } /** * Disables automatic scroll restoration provided by the browser. */ setHistoryScrollRestoration(scrollRestoration) { this.window.history.scrollRestoration = scrollRestoration; } /** * Scrolls to an element using the native offset and the specified offset set on this scroller. * * The offset can be used when we know that there is a floating header and scrolling naively to an * element (ex: `scrollIntoView`) leaves the element hidden behind the floating header. */ scrollToElement(el) { const rect = el.getBoundingClientRect(); const left = rect.left + this.window.pageXOffset; const top = rect.top + this.window.pageYOffset; const offset = this.offset(); this.window.scrollTo(left - offset[0], top - offset[1]); } }; function findAnchorFromDocument(document2, target) { const documentResult = document2.getElementById(target) || document2.getElementsByName(target)[0]; if (documentResult) { return documentResult; } if (typeof document2.createTreeWalker === "function" && document2.body && typeof document2.body.attachShadow === "function") { const treeWalker = document2.createTreeWalker(document2.body, NodeFilter.SHOW_ELEMENT); let currentNode = treeWalker.currentNode; while (currentNode) { const shadowRoot = currentNode.shadowRoot; if (shadowRoot) { const result = shadowRoot.getElementById(target) || shadowRoot.querySelector(`[name="${target}"]`); if (result) { return result; } } currentNode = treeWalker.nextNode(); } } return null; } var XhrFactory = class { }; var PLACEHOLDER_QUALITY = "20"; function getUrl(src, win) { return isAbsoluteUrl(src) ? new URL(src) : new URL(src, win.location.href); } function isAbsoluteUrl(src) { return /^https?:\/\//.test(src); } function extractHostname(url) { return isAbsoluteUrl(url) ? new URL(url).hostname : url; } function isValidPath(path) { const isString = typeof path === "string"; if (!isString || path.trim() === "") { return false; } try { const url = new URL(path); return true; } catch { return false; } } function normalizePath(path) { return path.endsWith("/") ? path.slice(0, -1) : path; } function normalizeSrc(src) { return src.startsWith("/") ? src.slice(1) : src; } var noopImageLoader = (config) => config.src; var IMAGE_LOADER = new InjectionToken(ngDevMode ? "ImageLoader" : "", { providedIn: "root", factory: () => noopImageLoader }); function createImageLoader(buildUrlFn, exampleUrls) { return function provideImageLoader(path) { if (!isValidPath(path)) { throwInvalidPathError(path, exampleUrls || []); } path = normalizePath(path); const loaderFn = (config) => { if (isAbsoluteUrl(config.src)) { throwUnexpectedAbsoluteUrlError(path, config.src); } return buildUrlFn(path, __spreadProps(__spreadValues({}, config), { src: normalizeSrc(config.src) })); }; const providers = [{ provide: IMAGE_LOADER, useValue: loaderFn }]; return providers; }; } function throwInvalidPathError(path, exampleUrls) { throw new RuntimeError(2959, ngDevMode && `Image loader has detected an invalid path (\`${path}\`). To fix this, supply a path using one of the following formats: ${exampleUrls.join(" or ")}`); } function throwUnexpectedAbsoluteUrlError(path, url) { throw new RuntimeError(2959, ngDevMode && `Image loader has detected a \`\` tag with an invalid \`ngSrc\` attribute: ${url}. This image loader expects \`ngSrc\` to be a relative URL - however the provided value is an absolute URL. To fix this, provide \`ngSrc\` as a path relative to the base URL configured for this loader (\`${path}\`).`); } var provideCloudflareLoader = createImageLoader(createCloudflareUrl, ngDevMode ? ["https:///cdn-cgi/image//"] : void 0); function createCloudflareUrl(path, config) { let params = `format=auto`; if (config.width) { params += `,width=${config.width}`; } if (config.isPlaceholder) { params += `,quality=${PLACEHOLDER_QUALITY}`; } return `${path}/cdn-cgi/image/${params}/${config.src}`; } var cloudinaryLoaderInfo = { name: "Cloudinary", testUrl: isCloudinaryUrl }; var CLOUDINARY_LOADER_REGEX = /https?\:\/\/[^\/]+\.cloudinary\.com\/.+/; function isCloudinaryUrl(url) { return CLOUDINARY_LOADER_REGEX.test(url); } var provideCloudinaryLoader = createImageLoader(createCloudinaryUrl, ngDevMode ? ["https://res.cloudinary.com/mysite", "https://mysite.cloudinary.com", "https://subdomain.mysite.com"] : void 0); function createCloudinaryUrl(path, config) { const quality = config.isPlaceholder ? "q_auto:low" : "q_auto"; let params = `f_auto,${quality}`; if (config.width) { params += `,w_${config.width}`; } if (config.loaderParams?.["rounded"]) { params += `,r_max`; } return `${path}/image/upload/${params}/${config.src}`; } var imageKitLoaderInfo = { name: "ImageKit", testUrl: isImageKitUrl }; var IMAGE_KIT_LOADER_REGEX = /https?\:\/\/[^\/]+\.imagekit\.io\/.+/; function isImageKitUrl(url) { return IMAGE_KIT_LOADER_REGEX.test(url); } var provideImageKitLoader = createImageLoader(createImagekitUrl, ngDevMode ? ["https://ik.imagekit.io/mysite", "https://subdomain.mysite.com"] : void 0); function createImagekitUrl(path, config) { const { src, width } = config; const params = []; if (width) { params.push(`w-${width}`); } if (config.isPlaceholder) { params.push(`q-${PLACEHOLDER_QUALITY}`); } const urlSegments = params.length ? [path, `tr:${params.join(",")}`, src] : [path, src]; const url = new URL(urlSegments.join("/")); return url.href; } var imgixLoaderInfo = { name: "Imgix", testUrl: isImgixUrl }; var IMGIX_LOADER_REGEX = /https?\:\/\/[^\/]+\.imgix\.net\/.+/; function isImgixUrl(url) { return IMGIX_LOADER_REGEX.test(url); } var provideImgixLoader = createImageLoader(createImgixUrl, ngDevMode ? ["https://somepath.imgix.net/"] : void 0); function createImgixUrl(path, config) { const url = new URL(`${path}/${config.src}`); url.searchParams.set("auto", "format"); if (config.width) { url.searchParams.set("w", config.width.toString()); } if (config.isPlaceholder) { url.searchParams.set("q", PLACEHOLDER_QUALITY); } return url.href; } var netlifyLoaderInfo = { name: "Netlify", testUrl: isNetlifyUrl }; var NETLIFY_LOADER_REGEX = /https?\:\/\/[^\/]+\.netlify\.app\/.+/; function isNetlifyUrl(url) { return NETLIFY_LOADER_REGEX.test(url); } function imgDirectiveDetails(ngSrc, includeNgSrc = true) { const ngSrcInfo = includeNgSrc ? `(activated on an element with the \`ngSrc="proxy.php?url=https%3A%2F%2Fangular-kr-docs.web.app%2F%24%7BngSrc%7D"\`) ` : ""; return `The NgOptimizedImage directive ${ngSrcInfo}has detected that`; } function assertDevMode(checkName) { if (!ngDevMode) { throw new RuntimeError(2958, `Unexpected invocation of the ${checkName} in the prod mode. Please make sure that the prod mode is enabled for production builds.`); } } var LCPImageObserver = class _LCPImageObserver { // Map of full image URLs -> original `ngSrc` values. images = /* @__PURE__ */ new Map(); window = null; observer = null; constructor() { const isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); assertDevMode("LCP checker"); const win = inject(DOCUMENT).defaultView; if (isBrowser && typeof PerformanceObserver !== "undefined") { this.window = win; this.observer = this.initPerformanceObserver(); } } /** * Inits PerformanceObserver and subscribes to LCP events. * Based on https://web.dev/lcp/#measure-lcp-in-javascript */ initPerformanceObserver() { const observer = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); if (entries.length === 0) return; const lcpElement = entries[entries.length - 1]; const imgSrc = lcpElement.element?.src ?? ""; if (imgSrc.startsWith("data:") || imgSrc.startsWith("blob:")) return; const img = this.images.get(imgSrc); if (!img) return; if (!img.priority && !img.alreadyWarnedPriority) { img.alreadyWarnedPriority = true; logMissingPriorityError(imgSrc); } if (img.modified && !img.alreadyWarnedModified) { img.alreadyWarnedModified = true; logModifiedWarning(imgSrc); } }); observer.observe({ type: "largest-contentful-paint", buffered: true }); return observer; } registerImage(rewrittenSrc, originalNgSrc, isPriority) { if (!this.observer) return; const newObservedImageState = { priority: isPriority, modified: false, alreadyWarnedModified: false, alreadyWarnedPriority: false }; this.images.set(getUrl(rewrittenSrc, this.window).href, newObservedImageState); } unregisterImage(rewrittenSrc) { if (!this.observer) return; this.images.delete(getUrl(rewrittenSrc, this.window).href); } updateImage(originalSrc, newSrc) { if (!this.observer) return; const originalUrl = getUrl(originalSrc, this.window).href; const img = this.images.get(originalUrl); if (img) { img.modified = true; this.images.set(getUrl(newSrc, this.window).href, img); this.images.delete(originalUrl); } } ngOnDestroy() { if (!this.observer) return; this.observer.disconnect(); this.images.clear(); } static \u0275fac = function LCPImageObserver_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _LCPImageObserver)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _LCPImageObserver, factory: _LCPImageObserver.\u0275fac, providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(LCPImageObserver, [{ type: Injectable, args: [{ providedIn: "root" }] }], () => [], null); })(); function logMissingPriorityError(ngSrc) { const directiveDetails = imgDirectiveDetails(ngSrc); console.error(formatRuntimeError(2955, `${directiveDetails} this image is the Largest Contentful Paint (LCP) element but was not marked "priority". This image should be marked "priority" in order to prioritize its loading. To fix this, add the "priority" attribute.`)); } function logModifiedWarning(ngSrc) { const directiveDetails = imgDirectiveDetails(ngSrc); console.warn(formatRuntimeError(2964, `${directiveDetails} this image is the Largest Contentful Paint (LCP) element and has had its "ngSrc" attribute modified. This can cause slower loading performance. It is recommended not to modify the "ngSrc" property on any image which could be the LCP element.`)); } var INTERNAL_PRECONNECT_CHECK_BLOCKLIST = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0"]); var PRECONNECT_CHECK_BLOCKLIST = new InjectionToken(ngDevMode ? "PRECONNECT_CHECK_BLOCKLIST" : ""); var PreconnectLinkChecker = class _PreconnectLinkChecker { document = inject(DOCUMENT); /** * Set of tags found on this page. * The `null` value indicates that there was no DOM query operation performed. */ preconnectLinks = null; /* * Keep track of all already seen origin URLs to avoid repeating the same check. */ alreadySeen = /* @__PURE__ */ new Set(); window = this.document.defaultView; blocklist = new Set(INTERNAL_PRECONNECT_CHECK_BLOCKLIST); constructor() { assertDevMode("preconnect link checker"); const blocklist = inject(PRECONNECT_CHECK_BLOCKLIST, { optional: true }); if (blocklist) { this.populateBlocklist(blocklist); } } populateBlocklist(origins) { if (Array.isArray(origins)) { deepForEach(origins, (origin) => { this.blocklist.add(extractHostname(origin)); }); } else { this.blocklist.add(extractHostname(origins)); } } /** * Checks that a preconnect resource hint exists in the head for the * given src. * * @param rewrittenSrc src formatted with loader * @param originalNgSrc ngSrc value */ assertPreconnect(rewrittenSrc, originalNgSrc) { if (false) return; const imgUrl = getUrl(rewrittenSrc, this.window); if (this.blocklist.has(imgUrl.hostname) || this.alreadySeen.has(imgUrl.origin)) return; this.alreadySeen.add(imgUrl.origin); this.preconnectLinks ??= this.queryPreconnectLinks(); if (!this.preconnectLinks.has(imgUrl.origin)) { console.warn(formatRuntimeError(2956, `${imgDirectiveDetails(originalNgSrc)} there is no preconnect tag present for this image. Preconnecting to the origin(s) that serve priority images ensures that these images are delivered as soon as possible. To fix this, please add the following element into the of the document: `)); } } queryPreconnectLinks() { const preconnectUrls = /* @__PURE__ */ new Set(); const selector = "link[rel=preconnect]"; const links = Array.from(this.document.querySelectorAll(selector)); for (let link of links) { const url = getUrl(link.href, this.window); preconnectUrls.add(url.origin); } return preconnectUrls; } ngOnDestroy() { this.preconnectLinks?.clear(); this.alreadySeen.clear(); } static \u0275fac = function PreconnectLinkChecker_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PreconnectLinkChecker)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _PreconnectLinkChecker, factory: _PreconnectLinkChecker.\u0275fac, providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PreconnectLinkChecker, [{ type: Injectable, args: [{ providedIn: "root" }] }], () => [], null); })(); function deepForEach(input2, fn) { for (let value of input2) { Array.isArray(value) ? deepForEach(value, fn) : fn(value); } } var DEFAULT_PRELOADED_IMAGES_LIMIT = 5; var PRELOADED_IMAGES = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "NG_OPTIMIZED_PRELOADED_IMAGES" : "", { providedIn: "root", factory: () => /* @__PURE__ */ new Set() }); var PreloadLinkCreator = class _PreloadLinkCreator { preloadedImages = inject(PRELOADED_IMAGES); document = inject(DOCUMENT); /** * @description Add a preload `` to the `` of the `index.html` that is served from the * server while using Angular Universal and SSR to kick off image loads for high priority images. * * The `sizes` (passed in from the user) and `srcset` (parsed and formatted from `ngSrcset`) * properties used to set the corresponding attributes, `imagesizes` and `imagesrcset` * respectively, on the preload `` tag so that the correctly sized image is preloaded from * the CDN. * * {@link https://web.dev/preload-responsive-images/#imagesrcset-and-imagesizes} * * @param renderer The `Renderer2` passed in from the directive * @param src The original src of the image that is set on the `ngSrc` input. * @param srcset The parsed and formatted srcset created from the `ngSrcset` input * @param sizes The value of the `sizes` attribute passed in to the `` tag */ createPreloadLinkTag(renderer, src, srcset, sizes) { if (ngDevMode) { if (this.preloadedImages.size >= DEFAULT_PRELOADED_IMAGES_LIMIT) { throw new RuntimeError(2961, ngDevMode && `The \`NgOptimizedImage\` directive has detected that more than ${DEFAULT_PRELOADED_IMAGES_LIMIT} images were marked as priority. This might negatively affect an overall performance of the page. To fix this, remove the "priority" attribute from images with less priority.`); } } if (this.preloadedImages.has(src)) { return; } this.preloadedImages.add(src); const preload = renderer.createElement("link"); renderer.setAttribute(preload, "as", "image"); renderer.setAttribute(preload, "href", src); renderer.setAttribute(preload, "rel", "preload"); renderer.setAttribute(preload, "fetchpriority", "high"); if (sizes) { renderer.setAttribute(preload, "imageSizes", sizes); } if (srcset) { renderer.setAttribute(preload, "imageSrcset", srcset); } renderer.appendChild(this.document.head, preload); } static \u0275fac = function PreloadLinkCreator_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _PreloadLinkCreator)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _PreloadLinkCreator, factory: _PreloadLinkCreator.\u0275fac, providedIn: "root" }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PreloadLinkCreator, [{ type: Injectable, args: [{ providedIn: "root" }] }], null, null); })(); var BASE64_IMG_MAX_LENGTH_IN_ERROR = 50; var VALID_WIDTH_DESCRIPTOR_SRCSET = /^((\s*\d+w\s*(,|$)){1,})$/; var VALID_DENSITY_DESCRIPTOR_SRCSET = /^((\s*\d+(\.\d+)?x\s*(,|$)){1,})$/; var ABSOLUTE_SRCSET_DENSITY_CAP = 3; var RECOMMENDED_SRCSET_DENSITY_CAP = 2; var DENSITY_SRCSET_MULTIPLIERS = [1, 2]; var VIEWPORT_BREAKPOINT_CUTOFF = 640; var ASPECT_RATIO_TOLERANCE = 0.1; var OVERSIZED_IMAGE_TOLERANCE = 1e3; var FIXED_SRCSET_WIDTH_LIMIT = 1920; var FIXED_SRCSET_HEIGHT_LIMIT = 1080; var PLACEHOLDER_DIMENSION_LIMIT = 1e3; var DATA_URL_WARN_LIMIT = 4e3; var DATA_URL_ERROR_LIMIT = 1e4; var BUILT_IN_LOADERS = [imgixLoaderInfo, imageKitLoaderInfo, cloudinaryLoaderInfo, netlifyLoaderInfo]; var PRIORITY_COUNT_THRESHOLD = 10; var IMGS_WITH_PRIORITY_ATTR_COUNT = 0; var NgOptimizedImage = class _NgOptimizedImage { imageLoader = inject(IMAGE_LOADER); config = processConfig(inject(IMAGE_CONFIG)); renderer = inject(Renderer2); imgElement = inject(ElementRef).nativeElement; injector = inject(Injector); // An LCP image observer should be injected only in development mode. // Do not assign it to `null` to avoid having a redundant property in the production bundle. lcpObserver; /** * Calculate the rewritten `src` once and store it. * This is needed to avoid repetitive calculations and make sure the directive cleanup in the * `ngOnDestroy` does not rely on the `IMAGE_LOADER` logic (which in turn can rely on some other * instance that might be already destroyed). */ _renderedSrc = null; /** * Name of the source image. * Image name will be processed by the image loader and the final URL will be applied as the `src` * property of the image. */ ngSrc; /** * A comma separated list of width or density descriptors. * The image name will be taken from `ngSrc` and combined with the list of width or density * descriptors to generate the final `srcset` property of the image. * * Example: * ```html * => * * ``` */ ngSrcset; /** * The base `sizes` attribute passed through to the `` element. * Providing sizes causes the image to create an automatic responsive srcset. */ sizes; /** * For responsive images: the intrinsic width of the image in pixels. * For fixed size images: the desired rendered width of the image in pixels. */ width; /** * For responsive images: the intrinsic height of the image in pixels. * For fixed size images: the desired rendered height of the image in pixels. */ height; /** * The desired loading behavior (lazy, eager, or auto). Defaults to `lazy`, * which is recommended for most images. * * Warning: Setting images as loading="eager" or loading="auto" marks them * as non-priority images and can hurt loading performance. For images which * may be the LCP element, use the `priority` attribute instead of `loading`. */ loading; /** * Indicates whether this image should have a high priority. */ priority = false; /** * Data to pass through to custom loaders. */ loaderParams; /** * Disables automatic srcset generation for this image. */ disableOptimizedSrcset = false; /** * Sets the image to "fill mode", which eliminates the height/width requirement and adds * styles such that the image fills its containing element. */ fill = false; /** * A URL or data URL for an image to be used as a placeholder while this image loads. */ placeholder; /** * Configuration object for placeholder settings. Options: * * blur: Setting this to false disables the automatic CSS blur. */ placeholderConfig; /** * Value of the `src` attribute if set on the host `` element. * This input is exclusively read to assert that `src` is not set in conflict * with `ngSrc` and that images don't start to load until a lazy loading strategy is set. * @internal */ src; /** * Value of the `srcset` attribute if set on the host `` element. * This input is exclusively read to assert that `srcset` is not set in conflict * with `ngSrcset` and that images don't start to load until a lazy loading strategy is set. * @internal */ srcset; constructor() { if (ngDevMode) { this.lcpObserver = this.injector.get(LCPImageObserver); const destroyRef = inject(DestroyRef); destroyRef.onDestroy(() => { if (!this.priority && this._renderedSrc !== null) { this.lcpObserver.unregisterImage(this._renderedSrc); } }); } } /** @nodoc */ ngOnInit() { performanceMarkFeature("NgOptimizedImage"); if (ngDevMode) { const ngZone = this.injector.get(NgZone); assertNonEmptyInput(this, "ngSrc", this.ngSrc); assertValidNgSrcset(this, this.ngSrcset); assertNoConflictingSrc(this); if (this.ngSrcset) { assertNoConflictingSrcset(this); } assertNotBase64Image(this); assertNotBlobUrl(this); if (this.fill) { assertEmptyWidthAndHeight(this); ngZone.runOutsideAngular(() => assertNonZeroRenderedHeight(this, this.imgElement, this.renderer)); } else { assertNonEmptyWidthAndHeight(this); if (this.height !== void 0) { assertGreaterThanZero(this, this.height, "height"); } if (this.width !== void 0) { assertGreaterThanZero(this, this.width, "width"); } ngZone.runOutsideAngular(() => assertNoImageDistortion(this, this.imgElement, this.renderer)); } assertValidLoadingInput(this); if (!this.ngSrcset) { assertNoComplexSizes(this); } assertValidPlaceholder(this, this.imageLoader); assertNotMissingBuiltInLoader(this.ngSrc, this.imageLoader); assertNoNgSrcsetWithoutLoader(this, this.imageLoader); assertNoLoaderParamsWithoutLoader(this, this.imageLoader); ngZone.runOutsideAngular(() => { this.lcpObserver.registerImage(this.getRewrittenSrc(), this.ngSrc, this.priority); }); if (this.priority) { const checker = this.injector.get(PreconnectLinkChecker); checker.assertPreconnect(this.getRewrittenSrc(), this.ngSrc); if (true) { const applicationRef = this.injector.get(ApplicationRef); assetPriorityCountBelowThreshold(applicationRef); } } } if (this.placeholder) { this.removePlaceholderOnLoad(this.imgElement); } this.setHostAttributes(); } setHostAttributes() { if (this.fill) { this.sizes ||= "100vw"; } else { this.setHostAttribute("width", this.width.toString()); this.setHostAttribute("height", this.height.toString()); } this.setHostAttribute("loading", this.getLoadingBehavior()); this.setHostAttribute("fetchpriority", this.getFetchPriority()); this.setHostAttribute("ng-img", "true"); const rewrittenSrcset = this.updateSrcAndSrcset(); if (this.sizes) { if (this.getLoadingBehavior() === "lazy") { this.setHostAttribute("sizes", "auto, " + this.sizes); } else { this.setHostAttribute("sizes", this.sizes); } } else { if (this.ngSrcset && VALID_WIDTH_DESCRIPTOR_SRCSET.test(this.ngSrcset) && this.getLoadingBehavior() === "lazy") { this.setHostAttribute("sizes", "auto, 100vw"); } } if (false) { const preloadLinkCreator = this.injector.get(PreloadLinkCreator); preloadLinkCreator.createPreloadLinkTag(this.renderer, this.getRewrittenSrc(), rewrittenSrcset, this.sizes); } } /** @nodoc */ ngOnChanges(changes) { if (ngDevMode) { assertNoPostInitInputChange(this, changes, ["ngSrcset", "width", "height", "priority", "fill", "loading", "sizes", "loaderParams", "disableOptimizedSrcset"]); } if (changes["ngSrc"] && !changes["ngSrc"].isFirstChange()) { const oldSrc = this._renderedSrc; this.updateSrcAndSrcset(true); if (ngDevMode) { const newSrc = this._renderedSrc; if (oldSrc && newSrc && oldSrc !== newSrc) { const ngZone = this.injector.get(NgZone); ngZone.runOutsideAngular(() => { this.lcpObserver.updateImage(oldSrc, newSrc); }); } } } if (ngDevMode && changes["placeholder"]?.currentValue && true && true) { assertPlaceholderDimensions(this, this.imgElement); } } callImageLoader(configWithoutCustomParams) { let augmentedConfig = configWithoutCustomParams; if (this.loaderParams) { augmentedConfig.loaderParams = this.loaderParams; } return this.imageLoader(augmentedConfig); } getLoadingBehavior() { if (!this.priority && this.loading !== void 0) { return this.loading; } return this.priority ? "eager" : "lazy"; } getFetchPriority() { return this.priority ? "high" : "auto"; } getRewrittenSrc() { if (!this._renderedSrc) { const imgConfig = { src: this.ngSrc }; this._renderedSrc = this.callImageLoader(imgConfig); } return this._renderedSrc; } getRewrittenSrcset() { const widthSrcSet = VALID_WIDTH_DESCRIPTOR_SRCSET.test(this.ngSrcset); const finalSrcs = this.ngSrcset.split(",").filter((src) => src !== "").map((srcStr) => { srcStr = srcStr.trim(); const width = widthSrcSet ? parseFloat(srcStr) : parseFloat(srcStr) * this.width; return `${this.callImageLoader({ src: this.ngSrc, width })} ${srcStr}`; }); return finalSrcs.join(", "); } getAutomaticSrcset() { if (this.sizes) { return this.getResponsiveSrcset(); } else { return this.getFixedSrcset(); } } getResponsiveSrcset() { const { breakpoints } = this.config; let filteredBreakpoints = breakpoints; if (this.sizes?.trim() === "100vw") { filteredBreakpoints = breakpoints.filter((bp) => bp >= VIEWPORT_BREAKPOINT_CUTOFF); } const finalSrcs = filteredBreakpoints.map((bp) => `${this.callImageLoader({ src: this.ngSrc, width: bp })} ${bp}w`); return finalSrcs.join(", "); } updateSrcAndSrcset(forceSrcRecalc = false) { if (forceSrcRecalc) { this._renderedSrc = null; } const rewrittenSrc = this.getRewrittenSrc(); this.setHostAttribute("src", rewrittenSrc); let rewrittenSrcset = void 0; if (this.ngSrcset) { rewrittenSrcset = this.getRewrittenSrcset(); } else if (this.shouldGenerateAutomaticSrcset()) { rewrittenSrcset = this.getAutomaticSrcset(); } if (rewrittenSrcset) { this.setHostAttribute("srcset", rewrittenSrcset); } return rewrittenSrcset; } getFixedSrcset() { const finalSrcs = DENSITY_SRCSET_MULTIPLIERS.map((multiplier) => `${this.callImageLoader({ src: this.ngSrc, width: this.width * multiplier })} ${multiplier}x`); return finalSrcs.join(", "); } shouldGenerateAutomaticSrcset() { let oversizedImage = false; if (!this.sizes) { oversizedImage = this.width > FIXED_SRCSET_WIDTH_LIMIT || this.height > FIXED_SRCSET_HEIGHT_LIMIT; } return !this.disableOptimizedSrcset && !this.srcset && this.imageLoader !== noopImageLoader && !oversizedImage; } /** * Returns an image url formatted for use with the CSS background-image property. Expects one of: * * A base64 encoded image, which is wrapped and passed through. * * A boolean. If true, calls the image loader to generate a small placeholder url. */ generatePlaceholder(placeholderInput) { const { placeholderResolution } = this.config; if (placeholderInput === true) { return `url(${this.callImageLoader({ src: this.ngSrc, width: placeholderResolution, isPlaceholder: true })})`; } else if (typeof placeholderInput === "string") { return `url(${placeholderInput})`; } return null; } /** * Determines if blur should be applied, based on an optional boolean * property `blur` within the optional configuration object `placeholderConfig`. */ shouldBlurPlaceholder(placeholderConfig) { if (!placeholderConfig || !placeholderConfig.hasOwnProperty("blur")) { return true; } return Boolean(placeholderConfig.blur); } removePlaceholderOnLoad(img) { const callback = () => { const changeDetectorRef = this.injector.get(ChangeDetectorRef); removeLoadListenerFn(); removeErrorListenerFn(); this.placeholder = false; changeDetectorRef.markForCheck(); }; const removeLoadListenerFn = this.renderer.listen(img, "load", callback); const removeErrorListenerFn = this.renderer.listen(img, "error", callback); callOnLoadIfImageIsLoaded(img, callback); } setHostAttribute(name, value) { this.renderer.setAttribute(this.imgElement, name, value); } static \u0275fac = function NgOptimizedImage_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _NgOptimizedImage)(); }; static \u0275dir = /* @__PURE__ */ \u0275\u0275defineDirective({ type: _NgOptimizedImage, selectors: [["img", "ngSrc", ""]], hostVars: 18, hostBindings: function NgOptimizedImage_HostBindings(rf, ctx) { if (rf & 2) { \u0275\u0275styleProp("position", ctx.fill ? "absolute" : null)("width", ctx.fill ? "100%" : null)("height", ctx.fill ? "100%" : null)("inset", ctx.fill ? "0" : null)("background-size", ctx.placeholder ? "cover" : null)("background-position", ctx.placeholder ? "50% 50%" : null)("background-repeat", ctx.placeholder ? "no-repeat" : null)("background-image", ctx.placeholder ? ctx.generatePlaceholder(ctx.placeholder) : null)("filter", ctx.placeholder && ctx.shouldBlurPlaceholder(ctx.placeholderConfig) ? "blur(15px)" : null); } }, inputs: { ngSrc: [2, "ngSrc", "ngSrc", unwrapSafeUrl], ngSrcset: "ngSrcset", sizes: "sizes", width: [2, "width", "width", numberAttribute], height: [2, "height", "height", numberAttribute], loading: "loading", priority: [2, "priority", "priority", booleanAttribute], loaderParams: "loaderParams", disableOptimizedSrcset: [2, "disableOptimizedSrcset", "disableOptimizedSrcset", booleanAttribute], fill: [2, "fill", "fill", booleanAttribute], placeholder: [2, "placeholder", "placeholder", booleanOrUrlAttribute], placeholderConfig: "placeholderConfig", src: "src", srcset: "srcset" }, features: [\u0275\u0275NgOnChangesFeature] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgOptimizedImage, [{ type: Directive, args: [{ selector: "img[ngSrc]", host: { "[style.position]": 'fill ? "absolute" : null', "[style.width]": 'fill ? "100%" : null', "[style.height]": 'fill ? "100%" : null', "[style.inset]": 'fill ? "0" : null', "[style.background-size]": 'placeholder ? "cover" : null', "[style.background-position]": 'placeholder ? "50% 50%" : null', "[style.background-repeat]": 'placeholder ? "no-repeat" : null', "[style.background-image]": "placeholder ? generatePlaceholder(placeholder) : null", "[style.filter]": 'placeholder && shouldBlurPlaceholder(placeholderConfig) ? "blur(15px)" : null' } }] }], () => [], { ngSrc: [{ type: Input, args: [{ required: true, transform: unwrapSafeUrl }] }], ngSrcset: [{ type: Input }], sizes: [{ type: Input }], width: [{ type: Input, args: [{ transform: numberAttribute }] }], height: [{ type: Input, args: [{ transform: numberAttribute }] }], loading: [{ type: Input }], priority: [{ type: Input, args: [{ transform: booleanAttribute }] }], loaderParams: [{ type: Input }], disableOptimizedSrcset: [{ type: Input, args: [{ transform: booleanAttribute }] }], fill: [{ type: Input, args: [{ transform: booleanAttribute }] }], placeholder: [{ type: Input, args: [{ transform: booleanOrUrlAttribute }] }], placeholderConfig: [{ type: Input }], src: [{ type: Input }], srcset: [{ type: Input }] }); })(); function processConfig(config) { let sortedBreakpoints = {}; if (config.breakpoints) { sortedBreakpoints.breakpoints = config.breakpoints.sort((a, b) => a - b); } return Object.assign({}, IMAGE_CONFIG_DEFAULTS, config, sortedBreakpoints); } function assertNoConflictingSrc(dir) { if (dir.src) { throw new RuntimeError(2950, `${imgDirectiveDetails(dir.ngSrc)} both \`src\` and \`ngSrc\` have been set. Supplying both of these attributes breaks lazy loading. The NgOptimizedImage directive sets \`src\` itself based on the value of \`ngSrc\`. To fix this, please remove the \`src\` attribute.`); } } function assertNoConflictingSrcset(dir) { if (dir.srcset) { throw new RuntimeError(2951, `${imgDirectiveDetails(dir.ngSrc)} both \`srcset\` and \`ngSrcset\` have been set. Supplying both of these attributes breaks lazy loading. The NgOptimizedImage directive sets \`srcset\` itself based on the value of \`ngSrcset\`. To fix this, please remove the \`srcset\` attribute.`); } } function assertNotBase64Image(dir) { let ngSrc = dir.ngSrc.trim(); if (ngSrc.startsWith("data:")) { if (ngSrc.length > BASE64_IMG_MAX_LENGTH_IN_ERROR) { ngSrc = ngSrc.substring(0, BASE64_IMG_MAX_LENGTH_IN_ERROR) + "..."; } throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc, false)} \`ngSrc\` is a Base64-encoded string (${ngSrc}). NgOptimizedImage does not support Base64-encoded strings. To fix this, disable the NgOptimizedImage directive for this element by removing \`ngSrc\` and using a standard \`src\` attribute instead.`); } } function assertNoComplexSizes(dir) { let sizes = dir.sizes; if (sizes?.match(/((\)|,)\s|^)\d+px/)) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc, false)} \`sizes\` was set to a string including pixel values. For automatic \`srcset\` generation, \`sizes\` must only include responsive values, such as \`sizes="50vw"\` or \`sizes="(min-width: 768px) 50vw, 100vw"\`. To fix this, modify the \`sizes\` attribute, or provide your own \`ngSrcset\` value directly.`); } } function assertValidPlaceholder(dir, imageLoader) { assertNoPlaceholderConfigWithoutPlaceholder(dir); assertNoRelativePlaceholderWithoutLoader(dir, imageLoader); assertNoOversizedDataUrl(dir); } function assertNoPlaceholderConfigWithoutPlaceholder(dir) { if (dir.placeholderConfig && !dir.placeholder) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc, false)} \`placeholderConfig\` options were provided for an image that does not use the \`placeholder\` attribute, and will have no effect.`); } } function assertNoRelativePlaceholderWithoutLoader(dir, imageLoader) { if (dir.placeholder === true && imageLoader === noopImageLoader) { throw new RuntimeError(2963, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to true but no image loader is configured (i.e. the default one is being used), which would result in the same image being used for the primary image and its placeholder. To fix this, provide a loader or remove the \`placeholder\` attribute from the image.`); } } function assertNoOversizedDataUrl(dir) { if (dir.placeholder && typeof dir.placeholder === "string" && dir.placeholder.startsWith("data:")) { if (dir.placeholder.length > DATA_URL_ERROR_LIMIT) { throw new RuntimeError(2965, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to a data URL which is longer than ${DATA_URL_ERROR_LIMIT} characters. This is strongly discouraged, as large inline placeholders directly increase the bundle size of Angular and hurt page load performance. To fix this, generate a smaller data URL placeholder.`); } if (dir.placeholder.length > DATA_URL_WARN_LIMIT) { console.warn(formatRuntimeError(2965, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to a data URL which is longer than ${DATA_URL_WARN_LIMIT} characters. This is discouraged, as large inline placeholders directly increase the bundle size of Angular and hurt page load performance. For better loading performance, generate a smaller data URL placeholder.`)); } } } function assertNotBlobUrl(dir) { const ngSrc = dir.ngSrc.trim(); if (ngSrc.startsWith("blob:")) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} \`ngSrc\` was set to a blob URL (${ngSrc}). Blob URLs are not supported by the NgOptimizedImage directive. To fix this, disable the NgOptimizedImage directive for this element by removing \`ngSrc\` and using a regular \`src\` attribute instead.`); } } function assertNonEmptyInput(dir, name, value) { const isString = typeof value === "string"; const isEmptyString = isString && value.trim() === ""; if (!isString || isEmptyString) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} \`${name}\` has an invalid value (\`${value}\`). To fix this, change the value to a non-empty string.`); } } function assertValidNgSrcset(dir, value) { if (value == null) return; assertNonEmptyInput(dir, "ngSrcset", value); const stringVal = value; const isValidWidthDescriptor = VALID_WIDTH_DESCRIPTOR_SRCSET.test(stringVal); const isValidDensityDescriptor = VALID_DENSITY_DESCRIPTOR_SRCSET.test(stringVal); if (isValidDensityDescriptor) { assertUnderDensityCap(dir, stringVal); } const isValidSrcset = isValidWidthDescriptor || isValidDensityDescriptor; if (!isValidSrcset) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} \`ngSrcset\` has an invalid value (\`${value}\`). To fix this, supply \`ngSrcset\` using a comma-separated list of one or more width descriptors (e.g. "100w, 200w") or density descriptors (e.g. "1x, 2x").`); } } function assertUnderDensityCap(dir, value) { const underDensityCap = value.split(",").every((num) => num === "" || parseFloat(num) <= ABSOLUTE_SRCSET_DENSITY_CAP); if (!underDensityCap) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` contains an unsupported image density:\`${value}\`. NgOptimizedImage generally recommends a max image density of ${RECOMMENDED_SRCSET_DENSITY_CAP}x but supports image densities up to ${ABSOLUTE_SRCSET_DENSITY_CAP}x. The human eye cannot distinguish between image densities greater than ${RECOMMENDED_SRCSET_DENSITY_CAP}x - which makes them unnecessary for most use cases. Images that will be pinch-zoomed are typically the primary use case for ${ABSOLUTE_SRCSET_DENSITY_CAP}x images. Please remove the high density descriptor and try again.`); } } function postInitInputChangeError(dir, inputName) { let reason; if (inputName === "width" || inputName === "height") { reason = `Changing \`${inputName}\` may result in different attribute value applied to the underlying image element and cause layout shifts on a page.`; } else { reason = `Changing the \`${inputName}\` would have no effect on the underlying image element, because the resource loading has already occurred.`; } return new RuntimeError(2953, `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` was updated after initialization. The NgOptimizedImage directive will not react to this input change. ${reason} To fix this, either switch \`${inputName}\` to a static value or wrap the image element in an @if that is gated on the necessary value.`); } function assertNoPostInitInputChange(dir, changes, inputs) { inputs.forEach((input2) => { const isUpdated = changes.hasOwnProperty(input2); if (isUpdated && !changes[input2].isFirstChange()) { if (input2 === "ngSrc") { dir = { ngSrc: changes[input2].previousValue }; } throw postInitInputChangeError(dir, input2); } }); } function assertGreaterThanZero(dir, inputValue, inputName) { const validNumber = typeof inputValue === "number" && inputValue > 0; const validString = typeof inputValue === "string" && /^\d+$/.test(inputValue.trim()) && parseInt(inputValue) > 0; if (!validNumber && !validString) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` has an invalid value. To fix this, provide \`${inputName}\` as a number greater than 0.`); } } function assertNoImageDistortion(dir, img, renderer) { const callback = () => { removeLoadListenerFn(); removeErrorListenerFn(); const computedStyle = window.getComputedStyle(img); let renderedWidth = parseFloat(computedStyle.getPropertyValue("width")); let renderedHeight = parseFloat(computedStyle.getPropertyValue("height")); const boxSizing = computedStyle.getPropertyValue("box-sizing"); if (boxSizing === "border-box") { const paddingTop = computedStyle.getPropertyValue("padding-top"); const paddingRight = computedStyle.getPropertyValue("padding-right"); const paddingBottom = computedStyle.getPropertyValue("padding-bottom"); const paddingLeft = computedStyle.getPropertyValue("padding-left"); renderedWidth -= parseFloat(paddingRight) + parseFloat(paddingLeft); renderedHeight -= parseFloat(paddingTop) + parseFloat(paddingBottom); } const renderedAspectRatio = renderedWidth / renderedHeight; const nonZeroRenderedDimensions = renderedWidth !== 0 && renderedHeight !== 0; const intrinsicWidth = img.naturalWidth; const intrinsicHeight = img.naturalHeight; const intrinsicAspectRatio = intrinsicWidth / intrinsicHeight; const suppliedWidth = dir.width; const suppliedHeight = dir.height; const suppliedAspectRatio = suppliedWidth / suppliedHeight; const inaccurateDimensions = Math.abs(suppliedAspectRatio - intrinsicAspectRatio) > ASPECT_RATIO_TOLERANCE; const stylingDistortion = nonZeroRenderedDimensions && Math.abs(intrinsicAspectRatio - renderedAspectRatio) > ASPECT_RATIO_TOLERANCE; if (inaccurateDimensions) { console.warn(formatRuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the image does not match the aspect ratio indicated by the width and height attributes. Intrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h (aspect-ratio: ${round(intrinsicAspectRatio)}). Supplied width and height attributes: ${suppliedWidth}w x ${suppliedHeight}h (aspect-ratio: ${round(suppliedAspectRatio)}). To fix this, update the width and height attributes.`)); } else if (stylingDistortion) { console.warn(formatRuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the rendered image does not match the image's intrinsic aspect ratio. Intrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h (aspect-ratio: ${round(intrinsicAspectRatio)}). Rendered image size: ${renderedWidth}w x ${renderedHeight}h (aspect-ratio: ${round(renderedAspectRatio)}). This issue can occur if "width" and "height" attributes are added to an image without updating the corresponding image styling. To fix this, adjust image styling. In most cases, adding "height: auto" or "width: auto" to the image styling will fix this issue.`)); } else if (!dir.ngSrcset && nonZeroRenderedDimensions) { const recommendedWidth = RECOMMENDED_SRCSET_DENSITY_CAP * renderedWidth; const recommendedHeight = RECOMMENDED_SRCSET_DENSITY_CAP * renderedHeight; const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE; const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE; if (oversizedWidth || oversizedHeight) { console.warn(formatRuntimeError(2960, `${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly larger than necessary. Rendered image size: ${renderedWidth}w x ${renderedHeight}h. Intrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. Recommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. Note: Recommended intrinsic image size is calculated assuming a maximum DPR of ${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image or consider using the "ngSrcset" and "sizes" attributes.`)); } } }; const removeLoadListenerFn = renderer.listen(img, "load", callback); const removeErrorListenerFn = renderer.listen(img, "error", () => { removeLoadListenerFn(); removeErrorListenerFn(); }); callOnLoadIfImageIsLoaded(img, callback); } function assertNonEmptyWidthAndHeight(dir) { let missingAttributes = []; if (dir.width === void 0) missingAttributes.push("width"); if (dir.height === void 0) missingAttributes.push("height"); if (missingAttributes.length > 0) { throw new RuntimeError(2954, `${imgDirectiveDetails(dir.ngSrc)} these required attributes are missing: ${missingAttributes.map((attr) => `"${attr}"`).join(", ")}. Including "width" and "height" attributes will prevent image-related layout shifts. To fix this, include "width" and "height" attributes on the image tag or turn on "fill" mode with the \`fill\` attribute.`); } } function assertEmptyWidthAndHeight(dir) { if (dir.width || dir.height) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the attributes \`height\` and/or \`width\` are present along with the \`fill\` attribute. Because \`fill\` mode causes an image to fill its containing element, the size attributes have no effect and should be removed.`); } } function assertNonZeroRenderedHeight(dir, img, renderer) { const callback = () => { removeLoadListenerFn(); removeErrorListenerFn(); const renderedHeight = img.clientHeight; if (dir.fill && renderedHeight === 0) { console.warn(formatRuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the height of the fill-mode image is zero. This is likely because the containing element does not have the CSS 'position' property set to one of the following: "relative", "fixed", or "absolute". To fix this problem, make sure the container element has the CSS 'position' property defined and the height of the element is not zero.`)); } }; const removeLoadListenerFn = renderer.listen(img, "load", callback); const removeErrorListenerFn = renderer.listen(img, "error", () => { removeLoadListenerFn(); removeErrorListenerFn(); }); callOnLoadIfImageIsLoaded(img, callback); } function assertValidLoadingInput(dir) { if (dir.loading && dir.priority) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute was used on an image that was marked "priority". Setting \`loading\` on priority images is not allowed because these images will always be eagerly loaded. To fix this, remove the \u201Cloading\u201D attribute from the priority image.`); } const validInputs = ["auto", "eager", "lazy"]; if (typeof dir.loading === "string" && !validInputs.includes(dir.loading)) { throw new RuntimeError(2952, `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute has an invalid value (\`${dir.loading}\`). To fix this, provide a valid value ("lazy", "eager", or "auto").`); } } function assertNotMissingBuiltInLoader(ngSrc, imageLoader) { if (imageLoader === noopImageLoader) { let builtInLoaderName = ""; for (const loader of BUILT_IN_LOADERS) { if (loader.testUrl(ngSrc)) { builtInLoaderName = loader.name; break; } } if (builtInLoaderName) { console.warn(formatRuntimeError(2962, `NgOptimizedImage: It looks like your images may be hosted on the ${builtInLoaderName} CDN, but your app is not using Angular's built-in loader for that CDN. We recommend switching to use the built-in by calling \`provide${builtInLoaderName}Loader()\` in your \`providers\` and passing it your instance's base URL. If you don't want to use the built-in loader, define a custom loader function using IMAGE_LOADER to silence this warning.`)); } } } function assertNoNgSrcsetWithoutLoader(dir, imageLoader) { if (dir.ngSrcset && imageLoader === noopImageLoader) { console.warn(formatRuntimeError(2963, `${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` attribute is present but no image loader is configured (i.e. the default one is being used), which would result in the same image being used for all configured sizes. To fix this, provide a loader or remove the \`ngSrcset\` attribute from the image.`)); } } function assertNoLoaderParamsWithoutLoader(dir, imageLoader) { if (dir.loaderParams && imageLoader === noopImageLoader) { console.warn(formatRuntimeError(2963, `${imgDirectiveDetails(dir.ngSrc)} the \`loaderParams\` attribute is present but no image loader is configured (i.e. the default one is being used), which means that the loaderParams data will not be consumed and will not affect the URL. To fix this, provide a custom loader or remove the \`loaderParams\` attribute from the image.`)); } } async function assetPriorityCountBelowThreshold(appRef) { if (IMGS_WITH_PRIORITY_ATTR_COUNT === 0) { IMGS_WITH_PRIORITY_ATTR_COUNT++; await appRef.whenStable(); if (IMGS_WITH_PRIORITY_ATTR_COUNT > PRIORITY_COUNT_THRESHOLD) { console.warn(formatRuntimeError(2966, `NgOptimizedImage: The "priority" attribute is set to true more than ${PRIORITY_COUNT_THRESHOLD} times (${IMGS_WITH_PRIORITY_ATTR_COUNT} times). Marking too many images as "high" priority can hurt your application's LCP (https://web.dev/lcp). "Priority" should only be set on the image expected to be the page's LCP element.`)); } } else { IMGS_WITH_PRIORITY_ATTR_COUNT++; } } function assertPlaceholderDimensions(dir, imgElement) { const computedStyle = window.getComputedStyle(imgElement); let renderedWidth = parseFloat(computedStyle.getPropertyValue("width")); let renderedHeight = parseFloat(computedStyle.getPropertyValue("height")); if (renderedWidth > PLACEHOLDER_DIMENSION_LIMIT || renderedHeight > PLACEHOLDER_DIMENSION_LIMIT) { console.warn(formatRuntimeError(2967, `${imgDirectiveDetails(dir.ngSrc)} it uses a placeholder image, but at least one of the dimensions attribute (height or width) exceeds the limit of ${PLACEHOLDER_DIMENSION_LIMIT}px. To fix this, use a smaller image as a placeholder.`)); } } function callOnLoadIfImageIsLoaded(img, callback) { if (img.complete && img.naturalWidth) { callback(); } } function round(input2) { return Number.isInteger(input2) ? input2 : input2.toFixed(2); } function unwrapSafeUrl(value) { if (typeof value === "string") { return value; } return unwrapSafeValue(value); } function booleanOrUrlAttribute(value) { if (typeof value === "string" && value !== "true" && value !== "false" && value !== "") { return value; } return booleanAttribute(value); } // node_modules/@angular/common/fesm2022/http.mjs var HttpHandler = class { }; var HttpBackend = class { }; var HttpHeaders = class _HttpHeaders { /** * Internal map of lowercase header names to values. */ // TODO(issue/24571): remove '!'. headers; /** * Internal map of lowercased header names to the normalized * form of the name (the form seen first). */ normalizedNames = /* @__PURE__ */ new Map(); /** * Complete the lazy initialization of this object (needed before reading). */ lazyInit; /** * Queued updates to be materialized the next initialization. */ lazyUpdate = null; /** Constructs a new HTTP header object with the given values.*/ constructor(headers) { if (!headers) { this.headers = /* @__PURE__ */ new Map(); } else if (typeof headers === "string") { this.lazyInit = () => { this.headers = /* @__PURE__ */ new Map(); headers.split("\n").forEach((line) => { const index = line.indexOf(":"); if (index > 0) { const name = line.slice(0, index); const value = line.slice(index + 1).trim(); this.addHeaderEntry(name, value); } }); }; } else if (typeof Headers !== "undefined" && headers instanceof Headers) { this.headers = /* @__PURE__ */ new Map(); headers.forEach((value, name) => { this.addHeaderEntry(name, value); }); } else { this.lazyInit = () => { if (typeof ngDevMode === "undefined" || ngDevMode) { assertValidHeaders(headers); } this.headers = /* @__PURE__ */ new Map(); Object.entries(headers).forEach(([name, values]) => { this.setHeaderEntries(name, values); }); }; } } /** * Checks for existence of a given header. * * @param name The header name to check for existence. * * @returns True if the header exists, false otherwise. */ has(name) { this.init(); return this.headers.has(name.toLowerCase()); } /** * Retrieves the first value of a given header. * * @param name The header name. * * @returns The value string if the header exists, null otherwise */ get(name) { this.init(); const values = this.headers.get(name.toLowerCase()); return values && values.length > 0 ? values[0] : null; } /** * Retrieves the names of the headers. * * @returns A list of header names. */ keys() { this.init(); return Array.from(this.normalizedNames.values()); } /** * Retrieves a list of values for a given header. * * @param name The header name from which to retrieve values. * * @returns A string of values if the header exists, null otherwise. */ getAll(name) { this.init(); return this.headers.get(name.toLowerCase()) || null; } /** * Appends a new value to the existing set of values for a header * and returns them in a clone of the original instance. * * @param name The header name for which to append the values. * @param value The value to append. * * @returns A clone of the HTTP headers object with the value appended to the given header. */ append(name, value) { return this.clone({ name, value, op: "a" }); } /** * Sets or modifies a value for a given header in a clone of the original instance. * If the header already exists, its value is replaced with the given value * in the returned object. * * @param name The header name. * @param value The value or values to set or override for the given header. * * @returns A clone of the HTTP headers object with the newly set header value. */ set(name, value) { return this.clone({ name, value, op: "s" }); } /** * Deletes values for a given header in a clone of the original instance. * * @param name The header name. * @param value The value or values to delete for the given header. * * @returns A clone of the HTTP headers object with the given value deleted. */ delete(name, value) { return this.clone({ name, value, op: "d" }); } maybeSetNormalizedName(name, lcName) { if (!this.normalizedNames.has(lcName)) { this.normalizedNames.set(lcName, name); } } 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; } } } copyFrom(other) { other.init(); Array.from(other.headers.keys()).forEach((key) => { this.headers.set(key, other.headers.get(key)); this.normalizedNames.set(key, other.normalizedNames.get(key)); }); } clone(update) { const clone = new _HttpHeaders(); clone.lazyInit = !!this.lazyInit && this.lazyInit instanceof _HttpHeaders ? this.lazyInit : this; clone.lazyUpdate = (this.lazyUpdate || []).concat([update]); return clone; } applyUpdate(update) { const key = update.name.toLowerCase(); switch (update.op) { case "a": case "s": let value = update.value; if (typeof value === "string") { value = [value]; } if (value.length === 0) { return; } this.maybeSetNormalizedName(update.name, key); const base = (update.op === "a" ? this.headers.get(key) : void 0) || []; base.push(...value); this.headers.set(key, base); break; case "d": const toDelete = update.value; if (!toDelete) { this.headers.delete(key); this.normalizedNames.delete(key); } else { let existing = this.headers.get(key); if (!existing) { return; } existing = existing.filter((value2) => toDelete.indexOf(value2) === -1); if (existing.length === 0) { this.headers.delete(key); this.normalizedNames.delete(key); } else { this.headers.set(key, existing); } } break; } } addHeaderEntry(name, value) { const key = name.toLowerCase(); this.maybeSetNormalizedName(name, key); if (this.headers.has(key)) { this.headers.get(key).push(value); } else { this.headers.set(key, [value]); } } setHeaderEntries(name, values) { const headerValues = (Array.isArray(values) ? values : [values]).map((value) => value.toString()); const key = name.toLowerCase(); this.headers.set(key, headerValues); this.maybeSetNormalizedName(name, key); } /** * @internal */ forEach(fn) { this.init(); Array.from(this.normalizedNames.keys()).forEach((key) => fn(this.normalizedNames.get(key), this.headers.get(key))); } }; function assertValidHeaders(headers) { for (const [key, value] of Object.entries(headers)) { if (!(typeof value === "string" || typeof value === "number") && !Array.isArray(value)) { throw new Error(`Unexpected value of the \`${key}\` header provided. Expecting either a string, a number or an array, but got: \`${value}\`.`); } } } var HttpUrlEncodingCodec = class { /** * Encodes a key name for a URL parameter or query-string. * @param key The key name. * @returns The encoded key name. */ encodeKey(key) { return standardEncoding(key); } /** * Encodes the value of a URL parameter or query-string. * @param value The value. * @returns The encoded value. */ encodeValue(value) { return standardEncoding(value); } /** * Decodes an encoded URL parameter or query-string key. * @param key The encoded key name. * @returns The decoded key name. */ decodeKey(key) { return decodeURIComponent(key); } /** * Decodes an encoded URL parameter or query-string value. * @param value The encoded value. * @returns The decoded value. */ decodeValue(value) { return decodeURIComponent(value); } }; function paramParser(rawParams, codec) { const map2 = /* @__PURE__ */ new Map(); if (rawParams.length > 0) { const params = rawParams.replace(/^\?/, "").split("&"); params.forEach((param) => { const eqIdx = param.indexOf("="); const [key, val] = eqIdx == -1 ? [codec.decodeKey(param), ""] : [codec.decodeKey(param.slice(0, eqIdx)), codec.decodeValue(param.slice(eqIdx + 1))]; const list = map2.get(key) || []; list.push(val); map2.set(key, list); }); } return map2; } var STANDARD_ENCODING_REGEX = /%(\d[a-f0-9])/gi; var STANDARD_ENCODING_REPLACEMENTS = { "40": "@", "3A": ":", "24": "$", "2C": ",", "3B": ";", "3D": "=", "3F": "?", "2F": "/" }; function standardEncoding(v) { return encodeURIComponent(v).replace(STANDARD_ENCODING_REGEX, (s, t) => STANDARD_ENCODING_REPLACEMENTS[t] ?? s); } function valueToString(value) { return `${value}`; } var HttpParams = class _HttpParams { map; encoder; updates = null; cloneFrom = null; constructor(options = {}) { this.encoder = options.encoder || new HttpUrlEncodingCodec(); if (options.fromString) { if (options.fromObject) { throw new RuntimeError(2805, ngDevMode && "Cannot specify both fromString and fromObject."); } this.map = paramParser(options.fromString, this.encoder); } else if (!!options.fromObject) { this.map = /* @__PURE__ */ new Map(); Object.keys(options.fromObject).forEach((key) => { const value = options.fromObject[key]; const values = Array.isArray(value) ? value.map(valueToString) : [valueToString(value)]; this.map.set(key, values); }); } else { this.map = null; } } /** * Reports whether the body includes one or more values for a given parameter. * @param param The parameter name. * @returns True if the parameter has one or more values, * false if it has no value or is not present. */ has(param) { this.init(); return this.map.has(param); } /** * Retrieves the first value for a parameter. * @param param The parameter name. * @returns The first value of the given parameter, * or `null` if the parameter is not present. */ get(param) { this.init(); const res = this.map.get(param); return !!res ? res[0] : null; } /** * Retrieves all values for a parameter. * @param param The parameter name. * @returns All values in a string array, * or `null` if the parameter not present. */ getAll(param) { this.init(); return this.map.get(param) || null; } /** * Retrieves all the parameters for this body. * @returns The parameter names in a string array. */ keys() { this.init(); return Array.from(this.map.keys()); } /** * Appends a new value to existing values for a parameter. * @param param The parameter name. * @param value The new value to add. * @return A new body with the appended value. */ append(param, value) { return this.clone({ param, value, op: "a" }); } /** * Constructs a new body with appended values for the given parameter name. * @param params parameters and values * @return A new body with the new value. */ appendAll(params) { const updates = []; Object.keys(params).forEach((param) => { const value = params[param]; if (Array.isArray(value)) { value.forEach((_value) => { updates.push({ param, value: _value, op: "a" }); }); } else { updates.push({ param, value, op: "a" }); } }); return this.clone(updates); } /** * Replaces the value for a parameter. * @param param The parameter name. * @param value The new value. * @return A new body with the new value. */ set(param, value) { return this.clone({ param, value, op: "s" }); } /** * Removes a given value or all values from a parameter. * @param param The parameter name. * @param value The value to remove, if provided. * @return A new body with the given value removed, or with all values * removed if no value is specified. */ delete(param, value) { return this.clone({ param, value, op: "d" }); } /** * Serializes the body to an encoded string, where key-value pairs (separated by `=`) are * separated by `&`s. */ toString() { this.init(); return this.keys().map((key) => { const eKey = this.encoder.encodeKey(key); return this.map.get(key).map((value) => eKey + "=" + this.encoder.encodeValue(value)).join("&"); }).filter((param) => param !== "").join("&"); } clone(update) { const clone = new _HttpParams({ encoder: this.encoder }); clone.cloneFrom = this.cloneFrom || this; clone.updates = (this.updates || []).concat(update); return clone; } init() { if (this.map === null) { this.map = /* @__PURE__ */ new Map(); } if (this.cloneFrom !== null) { this.cloneFrom.init(); this.cloneFrom.keys().forEach((key) => this.map.set(key, this.cloneFrom.map.get(key))); this.updates.forEach((update) => { switch (update.op) { case "a": case "s": const base = (update.op === "a" ? this.map.get(update.param) : void 0) || []; base.push(valueToString(update.value)); this.map.set(update.param, base); break; case "d": if (update.value !== void 0) { let base2 = this.map.get(update.param) || []; const idx = base2.indexOf(valueToString(update.value)); if (idx !== -1) { base2.splice(idx, 1); } if (base2.length > 0) { this.map.set(update.param, base2); } else { this.map.delete(update.param); } } else { this.map.delete(update.param); break; } } }); this.cloneFrom = this.updates = null; } } }; var HttpContext = class { map = /* @__PURE__ */ new Map(); /** * Store a value in the context. If a value is already present it will be overwritten. * * @param token The reference to an instance of `HttpContextToken`. * @param value The value to store. * * @returns A reference to itself for easy chaining. */ set(token, value) { this.map.set(token, value); return this; } /** * Retrieve the value associated with the given token. * * @param token The reference to an instance of `HttpContextToken`. * * @returns The stored value or default if one is defined. */ get(token) { if (!this.map.has(token)) { this.map.set(token, token.defaultValue()); } return this.map.get(token); } /** * Delete the value associated with the given token. * * @param token The reference to an instance of `HttpContextToken`. * * @returns A reference to itself for easy chaining. */ delete(token) { this.map.delete(token); return this; } /** * Checks for existence of a given token. * * @param token The reference to an instance of `HttpContextToken`. * * @returns True if the token exists, false otherwise. */ has(token) { return this.map.has(token); } /** * @returns a list of tokens currently stored in the context. */ keys() { return this.map.keys(); } }; function mightHaveBody(method) { switch (method) { case "DELETE": case "GET": case "HEAD": case "OPTIONS": case "JSONP": return false; default: return true; } } function isArrayBuffer(value) { return typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer; } function isBlob(value) { return typeof Blob !== "undefined" && value instanceof Blob; } function isFormData(value) { return typeof FormData !== "undefined" && value instanceof FormData; } function isUrlSearchParams(value) { return typeof URLSearchParams !== "undefined" && value instanceof URLSearchParams; } var CONTENT_TYPE_HEADER = "Content-Type"; var ACCEPT_HEADER = "Accept"; var X_REQUEST_URL_HEADER = "X-Request-URL"; var TEXT_CONTENT_TYPE = "text/plain"; var JSON_CONTENT_TYPE = "application/json"; var ACCEPT_HEADER_VALUE = `${JSON_CONTENT_TYPE}, ${TEXT_CONTENT_TYPE}, */*`; var HttpRequest = class _HttpRequest { 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. */ body = null; /** * Outgoing headers for this request. */ // TODO(issue/24571): remove '!'. headers; /** * Shared and mutable context that can be used by interceptors */ context; /** * 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. * * Note: The `FetchBackend` doesn't support progress report on uploads. */ reportProgress = false; /** * Whether this request should be sent with outgoing credentials (cookies). */ withCredentials = false; /** * The expected response type of the server. * * This is used to parse the response appropriately before returning it to * the requestee. */ responseType = "json"; /** * The outgoing HTTP request method. */ method; /** * Outgoing URL parameters. * * To pass a string representation of HTTP parameters in the URL-query-string format, * the `HttpParamsOptions`' `fromString` may be used. For example: * * ```ts * new HttpParams({fromString: 'angular=awesome'}) * ``` */ // TODO(issue/24571): remove '!'. params; /** * The outgoing URL with all URL parameters set. */ urlWithParams; /** * The HttpTransferCache option for the request */ transferCache; constructor(method, url, third, fourth) { this.url = url; this.method = method.toUpperCase(); let options; if (mightHaveBody(this.method) || !!fourth) { this.body = third !== void 0 ? third : null; options = fourth; } else { options = third; } if (options) { this.reportProgress = !!options.reportProgress; this.withCredentials = !!options.withCredentials; if (!!options.responseType) { this.responseType = options.responseType; } if (!!options.headers) { this.headers = options.headers; } if (!!options.context) { this.context = options.context; } if (!!options.params) { this.params = options.params; } this.transferCache = options.transferCache; } this.headers ??= new HttpHeaders(); this.context ??= new HttpContext(); if (!this.params) { this.params = new HttpParams(); this.urlWithParams = url; } else { const params = this.params.toString(); if (params.length === 0) { this.urlWithParams = url; } else { const qIdx = url.indexOf("?"); const 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. */ serializeBody() { if (this.body === null) { return null; } if (typeof this.body === "string" || isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) || isUrlSearchParams(this.body)) { return this.body; } if (this.body instanceof HttpParams) { return this.body.toString(); } if (typeof this.body === "object" || typeof this.body === "boolean" || Array.isArray(this.body)) { return JSON.stringify(this.body); } return 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`. */ detectContentTypeHeader() { if (this.body === null) { return null; } if (isFormData(this.body)) { return null; } if (isBlob(this.body)) { return this.body.type || null; } if (isArrayBuffer(this.body)) { return null; } if (typeof this.body === "string") { return TEXT_CONTENT_TYPE; } if (this.body instanceof HttpParams) { return "application/x-www-form-urlencoded;charset=UTF-8"; } if (typeof this.body === "object" || typeof this.body === "number" || typeof this.body === "boolean") { return JSON_CONTENT_TYPE; } return null; } clone(update = {}) { const method = update.method || this.method; const url = update.url || this.url; const responseType = update.responseType || this.responseType; const transferCache = update.transferCache ?? this.transferCache; const body = update.body !== void 0 ? update.body : this.body; const withCredentials = update.withCredentials ?? this.withCredentials; const reportProgress = update.reportProgress ?? this.reportProgress; let headers = update.headers || this.headers; let params = update.params || this.params; const context = update.context ?? this.context; if (update.setHeaders !== void 0) { headers = Object.keys(update.setHeaders).reduce((headers2, name) => headers2.set(name, update.setHeaders[name]), headers); } if (update.setParams) { params = Object.keys(update.setParams).reduce((params2, param) => params2.set(param, update.setParams[param]), params); } return new _HttpRequest(method, url, body, { params, headers, context, reportProgress, responseType, withCredentials, transferCache }); } }; var HttpEventType; (function(HttpEventType2) { HttpEventType2[HttpEventType2["Sent"] = 0] = "Sent"; HttpEventType2[HttpEventType2["UploadProgress"] = 1] = "UploadProgress"; HttpEventType2[HttpEventType2["ResponseHeader"] = 2] = "ResponseHeader"; HttpEventType2[HttpEventType2["DownloadProgress"] = 3] = "DownloadProgress"; HttpEventType2[HttpEventType2["Response"] = 4] = "Response"; HttpEventType2[HttpEventType2["User"] = 5] = "User"; })(HttpEventType || (HttpEventType = {})); var HttpResponseBase = class { /** * All response headers. */ headers; /** * Response status code. */ status; /** * Textual description of response status code, defaults to OK. * * Do not depend on this. */ statusText; /** * URL of the resource retrieved, or null if not available. */ url; /** * Whether the status code falls in the 2xx range. */ ok; /** * Type of the response, narrowed to either the full response or the header. */ // TODO(issue/24571): remove '!'. type; /** * 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. */ constructor(init, defaultStatus = 200, defaultStatusText = "OK") { this.headers = init.headers || new HttpHeaders(); this.status = init.status !== void 0 ? init.status : defaultStatus; this.statusText = init.statusText || defaultStatusText; this.url = init.url || null; this.ok = this.status >= 200 && this.status < 300; } }; var HttpHeaderResponse = class _HttpHeaderResponse extends HttpResponseBase { /** * Create a new `HttpHeaderResponse` with the given parameters. */ constructor(init = {}) { super(init); } type = HttpEventType.ResponseHeader; /** * Copy this `HttpHeaderResponse`, overriding its contents with the * given parameter hash. */ clone(update = {}) { return new _HttpHeaderResponse({ headers: update.headers || this.headers, status: update.status !== void 0 ? update.status : this.status, statusText: update.statusText || this.statusText, url: update.url || this.url || void 0 }); } }; var HttpResponse = class _HttpResponse extends HttpResponseBase { /** * The response body, or `null` if one was not returned. */ body; /** * Construct a new `HttpResponse`. */ constructor(init = {}) { super(init); this.body = init.body !== void 0 ? init.body : null; } type = HttpEventType.Response; clone(update = {}) { return new _HttpResponse({ body: update.body !== void 0 ? update.body : this.body, headers: update.headers || this.headers, status: update.status !== void 0 ? update.status : this.status, statusText: update.statusText || this.statusText, url: update.url || this.url || void 0 }); } }; var HttpErrorResponse = class extends HttpResponseBase { name = "HttpErrorResponse"; message; error; /** * Errors are never okay, even when the status code is in the 2xx success range. */ ok = false; constructor(init) { super(init, 0, "Unknown Error"); 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; } }; var HTTP_STATUS_CODE_OK = 200; var HTTP_STATUS_CODE_NO_CONTENT = 204; var HttpStatusCode; (function(HttpStatusCode2) { HttpStatusCode2[HttpStatusCode2["Continue"] = 100] = "Continue"; HttpStatusCode2[HttpStatusCode2["SwitchingProtocols"] = 101] = "SwitchingProtocols"; HttpStatusCode2[HttpStatusCode2["Processing"] = 102] = "Processing"; HttpStatusCode2[HttpStatusCode2["EarlyHints"] = 103] = "EarlyHints"; HttpStatusCode2[HttpStatusCode2["Ok"] = 200] = "Ok"; HttpStatusCode2[HttpStatusCode2["Created"] = 201] = "Created"; HttpStatusCode2[HttpStatusCode2["Accepted"] = 202] = "Accepted"; HttpStatusCode2[HttpStatusCode2["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation"; HttpStatusCode2[HttpStatusCode2["NoContent"] = 204] = "NoContent"; HttpStatusCode2[HttpStatusCode2["ResetContent"] = 205] = "ResetContent"; HttpStatusCode2[HttpStatusCode2["PartialContent"] = 206] = "PartialContent"; HttpStatusCode2[HttpStatusCode2["MultiStatus"] = 207] = "MultiStatus"; HttpStatusCode2[HttpStatusCode2["AlreadyReported"] = 208] = "AlreadyReported"; HttpStatusCode2[HttpStatusCode2["ImUsed"] = 226] = "ImUsed"; HttpStatusCode2[HttpStatusCode2["MultipleChoices"] = 300] = "MultipleChoices"; HttpStatusCode2[HttpStatusCode2["MovedPermanently"] = 301] = "MovedPermanently"; HttpStatusCode2[HttpStatusCode2["Found"] = 302] = "Found"; HttpStatusCode2[HttpStatusCode2["SeeOther"] = 303] = "SeeOther"; HttpStatusCode2[HttpStatusCode2["NotModified"] = 304] = "NotModified"; HttpStatusCode2[HttpStatusCode2["UseProxy"] = 305] = "UseProxy"; HttpStatusCode2[HttpStatusCode2["Unused"] = 306] = "Unused"; HttpStatusCode2[HttpStatusCode2["TemporaryRedirect"] = 307] = "TemporaryRedirect"; HttpStatusCode2[HttpStatusCode2["PermanentRedirect"] = 308] = "PermanentRedirect"; HttpStatusCode2[HttpStatusCode2["BadRequest"] = 400] = "BadRequest"; HttpStatusCode2[HttpStatusCode2["Unauthorized"] = 401] = "Unauthorized"; HttpStatusCode2[HttpStatusCode2["PaymentRequired"] = 402] = "PaymentRequired"; HttpStatusCode2[HttpStatusCode2["Forbidden"] = 403] = "Forbidden"; HttpStatusCode2[HttpStatusCode2["NotFound"] = 404] = "NotFound"; HttpStatusCode2[HttpStatusCode2["MethodNotAllowed"] = 405] = "MethodNotAllowed"; HttpStatusCode2[HttpStatusCode2["NotAcceptable"] = 406] = "NotAcceptable"; HttpStatusCode2[HttpStatusCode2["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; HttpStatusCode2[HttpStatusCode2["RequestTimeout"] = 408] = "RequestTimeout"; HttpStatusCode2[HttpStatusCode2["Conflict"] = 409] = "Conflict"; HttpStatusCode2[HttpStatusCode2["Gone"] = 410] = "Gone"; HttpStatusCode2[HttpStatusCode2["LengthRequired"] = 411] = "LengthRequired"; HttpStatusCode2[HttpStatusCode2["PreconditionFailed"] = 412] = "PreconditionFailed"; HttpStatusCode2[HttpStatusCode2["PayloadTooLarge"] = 413] = "PayloadTooLarge"; HttpStatusCode2[HttpStatusCode2["UriTooLong"] = 414] = "UriTooLong"; HttpStatusCode2[HttpStatusCode2["UnsupportedMediaType"] = 415] = "UnsupportedMediaType"; HttpStatusCode2[HttpStatusCode2["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable"; HttpStatusCode2[HttpStatusCode2["ExpectationFailed"] = 417] = "ExpectationFailed"; HttpStatusCode2[HttpStatusCode2["ImATeapot"] = 418] = "ImATeapot"; HttpStatusCode2[HttpStatusCode2["MisdirectedRequest"] = 421] = "MisdirectedRequest"; HttpStatusCode2[HttpStatusCode2["UnprocessableEntity"] = 422] = "UnprocessableEntity"; HttpStatusCode2[HttpStatusCode2["Locked"] = 423] = "Locked"; HttpStatusCode2[HttpStatusCode2["FailedDependency"] = 424] = "FailedDependency"; HttpStatusCode2[HttpStatusCode2["TooEarly"] = 425] = "TooEarly"; HttpStatusCode2[HttpStatusCode2["UpgradeRequired"] = 426] = "UpgradeRequired"; HttpStatusCode2[HttpStatusCode2["PreconditionRequired"] = 428] = "PreconditionRequired"; HttpStatusCode2[HttpStatusCode2["TooManyRequests"] = 429] = "TooManyRequests"; HttpStatusCode2[HttpStatusCode2["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge"; HttpStatusCode2[HttpStatusCode2["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons"; HttpStatusCode2[HttpStatusCode2["InternalServerError"] = 500] = "InternalServerError"; HttpStatusCode2[HttpStatusCode2["NotImplemented"] = 501] = "NotImplemented"; HttpStatusCode2[HttpStatusCode2["BadGateway"] = 502] = "BadGateway"; HttpStatusCode2[HttpStatusCode2["ServiceUnavailable"] = 503] = "ServiceUnavailable"; HttpStatusCode2[HttpStatusCode2["GatewayTimeout"] = 504] = "GatewayTimeout"; HttpStatusCode2[HttpStatusCode2["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported"; HttpStatusCode2[HttpStatusCode2["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates"; HttpStatusCode2[HttpStatusCode2["InsufficientStorage"] = 507] = "InsufficientStorage"; HttpStatusCode2[HttpStatusCode2["LoopDetected"] = 508] = "LoopDetected"; HttpStatusCode2[HttpStatusCode2["NotExtended"] = 510] = "NotExtended"; HttpStatusCode2[HttpStatusCode2["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired"; })(HttpStatusCode || (HttpStatusCode = {})); function addBody(options, body) { return { body, headers: options.headers, context: options.context, observe: options.observe, params: options.params, reportProgress: options.reportProgress, responseType: options.responseType, withCredentials: options.withCredentials, transferCache: options.transferCache }; } var HttpClient = class _HttpClient { handler; constructor(handler) { this.handler = handler; } /** * Constructs an observable for a generic HTTP request that, when subscribed, * fires the request through the chain of registered interceptors and on to the * server. * * You can pass an `HttpRequest` directly as the only parameter. In this case, * the call returns an observable of the raw `HttpEvent` stream. * * Alternatively you can pass an HTTP method as the first parameter, * a URL string as the second, and an options hash containing the request body as the third. * See `addBody()`. In this case, the specified `responseType` and `observe` options determine the * type of returned observable. * * The `responseType` value determines how a successful response body is parsed. * * If `responseType` is the default `json`, you can pass a type interface for the resulting * object as a type parameter to the call. * * The `observe` value determines the return type, according to what you are interested in * observing. * * An `observe` value of events returns an observable of the raw `HttpEvent` stream, including * progress events by default. * * An `observe` value of response returns an observable of `HttpResponse`, * where the `T` parameter depends on the `responseType` and any optionally provided type * parameter. * * An `observe` value of body returns an observable of `` with the same `T` body type. * */ request(first2, url, options = {}) { let req; if (first2 instanceof HttpRequest) { req = first2; } else { let headers = void 0; if (options.headers instanceof HttpHeaders) { headers = options.headers; } else { headers = new HttpHeaders(options.headers); } let params = void 0; if (!!options.params) { if (options.params instanceof HttpParams) { params = options.params; } else { params = new HttpParams({ fromObject: options.params }); } } req = new HttpRequest(first2, url, options.body !== void 0 ? options.body : null, { headers, context: options.context, params, reportProgress: options.reportProgress, // By default, JSON is assumed to be returned for all calls. responseType: options.responseType || "json", withCredentials: options.withCredentials, transferCache: options.transferCache }); } const events$ = of(req).pipe(concatMap((req2) => this.handler.handle(req2))); if (first2 instanceof HttpRequest || options.observe === "events") { return events$; } const res$ = events$.pipe(filter((event) => event instanceof HttpResponse)); switch (options.observe || "body") { case "body": switch (req.responseType) { case "arraybuffer": return res$.pipe(map((res) => { if (res.body !== null && !(res.body instanceof ArrayBuffer)) { throw new RuntimeError(2806, ngDevMode && "Response is not an ArrayBuffer."); } return res.body; })); case "blob": return res$.pipe(map((res) => { if (res.body !== null && !(res.body instanceof Blob)) { throw new RuntimeError(2807, ngDevMode && "Response is not a Blob."); } return res.body; })); case "text": return res$.pipe(map((res) => { if (res.body !== null && typeof res.body !== "string") { throw new RuntimeError(2808, ngDevMode && "Response is not a string."); } return res.body; })); case "json": default: return res$.pipe(map((res) => res.body)); } case "response": return res$; default: throw new RuntimeError(2809, ngDevMode && `Unreachable: unhandled observe type ${options.observe}}`); } } /** * Constructs an observable that, when subscribed, causes the configured * `DELETE` request to execute on the server. See the individual overloads for * details on the return type. * * @param url The endpoint URL. * @param options The HTTP options to send with the request. * */ delete(url, options = {}) { return this.request("DELETE", url, options); } /** * Constructs an observable that, when subscribed, causes the configured * `GET` request to execute on the server. See the individual overloads for * details on the return type. */ get(url, options = {}) { return this.request("GET", url, options); } /** * Constructs an observable that, when subscribed, causes the configured * `HEAD` request to execute on the server. The `HEAD` method returns * meta information about the resource without transferring the * resource itself. See the individual overloads for * details on the return type. */ head(url, options = {}) { return this.request("HEAD", url, options); } /** * Constructs an `Observable` that, when subscribed, causes a request with the special method * `JSONP` to be dispatched via the interceptor pipeline. * The [JSONP pattern](https://en.wikipedia.org/wiki/JSONP) works around limitations of certain * API endpoints that don't support newer, * and preferable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) protocol. * JSONP treats the endpoint API as a JavaScript file and tricks the browser to process the * requests even if the API endpoint is not located on the same domain (origin) as the client-side * application making the request. * The endpoint API must support JSONP callback for JSONP requests to work. * The resource API returns the JSON response wrapped in a callback function. * You can pass the callback function name as one of the query parameters. * Note that JSONP requests can only be used with `GET` requests. * * @param url The resource URL. * @param callbackParam The callback function name. * */ jsonp(url, callbackParam) { return this.request("JSONP", url, { params: new HttpParams().append(callbackParam, "JSONP_CALLBACK"), observe: "body", responseType: "json" }); } /** * Constructs an `Observable` that, when subscribed, causes the configured * `OPTIONS` request to execute on the server. This method allows the client * to determine the supported HTTP methods and other capabilities of an endpoint, * without implying a resource action. See the individual overloads for * details on the return type. */ options(url, options = {}) { return this.request("OPTIONS", url, options); } /** * Constructs an observable that, when subscribed, causes the configured * `PATCH` request to execute on the server. See the individual overloads for * details on the return type. */ patch(url, body, options = {}) { return this.request("PATCH", url, addBody(options, body)); } /** * Constructs an observable that, when subscribed, causes the configured * `POST` request to execute on the server. The server responds with the location of * the replaced resource. See the individual overloads for * details on the return type. */ post(url, body, options = {}) { return this.request("POST", url, addBody(options, body)); } /** * Constructs an observable that, when subscribed, causes the configured * `PUT` request to execute on the server. The `PUT` method replaces an existing resource * with a new set of values. * See the individual overloads for details on the return type. */ put(url, body, options = {}) { return this.request("PUT", url, addBody(options, body)); } static \u0275fac = function HttpClient_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpClient)(\u0275\u0275inject(HttpHandler)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HttpClient, factory: _HttpClient.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpClient, [{ type: Injectable }], () => [{ type: HttpHandler }], null); })(); var XSSI_PREFIX$1 = /^\)\]\}',?\n/; function getResponseUrl$1(response) { if (response.url) { return response.url; } const xRequestUrl = X_REQUEST_URL_HEADER.toLocaleLowerCase(); return response.headers.get(xRequestUrl); } var FETCH_BACKEND = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "FETCH_BACKEND" : ""); var FetchBackend = class _FetchBackend { // We use an arrow function to always reference the current global implementation of `fetch`. // This is helpful for cases when the global `fetch` implementation is modified by external code, // see https://github.com/angular/angular/issues/57527. fetchImpl = inject(FetchFactory, { optional: true })?.fetch ?? ((...args) => globalThis.fetch(...args)); ngZone = inject(NgZone); handle(request) { return new Observable((observer) => { const aborter = new AbortController(); this.doRequest(request, aborter.signal, observer).then(noop, (error) => observer.error(new HttpErrorResponse({ error }))); return () => aborter.abort(); }); } async doRequest(request, signal2, observer) { const init = this.createRequestInit(request); let response; try { const fetchPromise = this.ngZone.runOutsideAngular(() => this.fetchImpl(request.urlWithParams, __spreadValues({ signal: signal2 }, init))); silenceSuperfluousUnhandledPromiseRejection(fetchPromise); observer.next({ type: HttpEventType.Sent }); response = await fetchPromise; } catch (error) { observer.error(new HttpErrorResponse({ error, status: error.status ?? 0, statusText: error.statusText, url: request.urlWithParams, headers: error.headers })); return; } const headers = new HttpHeaders(response.headers); const statusText = response.statusText; const url = getResponseUrl$1(response) ?? request.urlWithParams; let status = response.status; let body = null; if (request.reportProgress) { observer.next(new HttpHeaderResponse({ headers, status, statusText, url })); } if (response.body) { const contentLength = response.headers.get("content-length"); const chunks = []; const reader = response.body.getReader(); let receivedLength = 0; let decoder; let partialText; const reqZone = typeof Zone !== "undefined" && Zone.current; await this.ngZone.runOutsideAngular(async () => { while (true) { const { done, value } = await reader.read(); if (done) { break; } chunks.push(value); receivedLength += value.length; if (request.reportProgress) { partialText = request.responseType === "text" ? (partialText ?? "") + (decoder ??= new TextDecoder()).decode(value, { stream: true }) : void 0; const reportProgress = () => observer.next({ type: HttpEventType.DownloadProgress, total: contentLength ? +contentLength : void 0, loaded: receivedLength, partialText }); reqZone ? reqZone.run(reportProgress) : reportProgress(); } } }); const chunksAll = this.concatChunks(chunks, receivedLength); try { const contentType = response.headers.get(CONTENT_TYPE_HEADER) ?? ""; body = this.parseBody(request, chunksAll, contentType); } catch (error) { observer.error(new HttpErrorResponse({ error, headers: new HttpHeaders(response.headers), status: response.status, statusText: response.statusText, url: getResponseUrl$1(response) ?? request.urlWithParams })); return; } } if (status === 0) { status = body ? HTTP_STATUS_CODE_OK : 0; } const ok = status >= 200 && status < 300; if (ok) { observer.next(new HttpResponse({ body, headers, status, statusText, url })); observer.complete(); } else { observer.error(new HttpErrorResponse({ error: body, headers, status, statusText, url })); } } parseBody(request, binContent, contentType) { switch (request.responseType) { case "json": const text = new TextDecoder().decode(binContent).replace(XSSI_PREFIX$1, ""); return text === "" ? null : JSON.parse(text); case "text": return new TextDecoder().decode(binContent); case "blob": return new Blob([binContent], { type: contentType }); case "arraybuffer": return binContent.buffer; } } createRequestInit(req) { const headers = {}; const credentials = req.withCredentials ? "include" : void 0; req.headers.forEach((name, values) => headers[name] = values.join(",")); if (!req.headers.has(ACCEPT_HEADER)) { headers[ACCEPT_HEADER] = ACCEPT_HEADER_VALUE; } if (!req.headers.has(CONTENT_TYPE_HEADER)) { const detectedType = req.detectContentTypeHeader(); if (detectedType !== null) { headers[CONTENT_TYPE_HEADER] = detectedType; } } return { body: req.serializeBody(), method: req.method, headers, credentials }; } concatChunks(chunks, totalLength) { const chunksAll = new Uint8Array(totalLength); let position = 0; for (const chunk of chunks) { chunksAll.set(chunk, position); position += chunk.length; } return chunksAll; } static \u0275fac = function FetchBackend_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _FetchBackend)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _FetchBackend, factory: _FetchBackend.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(FetchBackend, [{ type: Injectable }], null, null); })(); var FetchFactory = class { }; function noop() { } function silenceSuperfluousUnhandledPromiseRejection(promise) { promise.then(noop, noop); } function interceptorChainEndFn(req, finalHandlerFn) { return finalHandlerFn(req); } function adaptLegacyInterceptorToChain(chainTailFn, interceptor) { return (initialRequest, finalHandlerFn) => interceptor.intercept(initialRequest, { handle: (downstreamRequest) => chainTailFn(downstreamRequest, finalHandlerFn) }); } function chainedInterceptorFn(chainTailFn, interceptorFn, injector) { return (initialRequest, finalHandlerFn) => runInInjectionContext(injector, () => interceptorFn(initialRequest, (downstreamRequest) => chainTailFn(downstreamRequest, finalHandlerFn))); } var HTTP_INTERCEPTORS = new InjectionToken(ngDevMode ? "HTTP_INTERCEPTORS" : ""); var HTTP_INTERCEPTOR_FNS = new InjectionToken(ngDevMode ? "HTTP_INTERCEPTOR_FNS" : ""); var HTTP_ROOT_INTERCEPTOR_FNS = new InjectionToken(ngDevMode ? "HTTP_ROOT_INTERCEPTOR_FNS" : ""); var REQUESTS_CONTRIBUTE_TO_STABILITY = new InjectionToken(ngDevMode ? "REQUESTS_CONTRIBUTE_TO_STABILITY" : "", { providedIn: "root", factory: () => true }); function legacyInterceptorFnFactory() { let chain = null; return (req, handler) => { if (chain === null) { const interceptors = inject(HTTP_INTERCEPTORS, { optional: true }) ?? []; chain = interceptors.reduceRight(adaptLegacyInterceptorToChain, interceptorChainEndFn); } const pendingTasks = inject(PendingTasksInternal); const contributeToStability = inject(REQUESTS_CONTRIBUTE_TO_STABILITY); if (contributeToStability) { const taskId = pendingTasks.add(); return chain(req, handler).pipe(finalize(() => pendingTasks.remove(taskId))); } else { return chain(req, handler); } }; } var fetchBackendWarningDisplayed = false; var HttpInterceptorHandler = class _HttpInterceptorHandler extends HttpHandler { backend; injector; chain = null; pendingTasks = inject(PendingTasksInternal); contributeToStability = inject(REQUESTS_CONTRIBUTE_TO_STABILITY); constructor(backend, injector) { super(); this.backend = backend; this.injector = injector; if ((typeof ngDevMode === "undefined" || ngDevMode) && !fetchBackendWarningDisplayed) { const isServer = isPlatformServer(injector.get(PLATFORM_ID)); const isTestingBackend = this.backend.isTestingBackend; if (isServer && !(this.backend instanceof FetchBackend) && !isTestingBackend) { fetchBackendWarningDisplayed = true; injector.get(Console).warn(formatRuntimeError(2801, "Angular detected that `HttpClient` is not configured to use `fetch` APIs. It's strongly recommended to enable `fetch` for applications that use Server-Side Rendering for better performance and compatibility. To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` call at the root of the application.")); } } } handle(initialRequest) { if (this.chain === null) { const dedupedInterceptorFns = Array.from(/* @__PURE__ */ new Set([...this.injector.get(HTTP_INTERCEPTOR_FNS), ...this.injector.get(HTTP_ROOT_INTERCEPTOR_FNS, [])])); this.chain = dedupedInterceptorFns.reduceRight((nextSequencedFn, interceptorFn) => chainedInterceptorFn(nextSequencedFn, interceptorFn, this.injector), interceptorChainEndFn); } if (this.contributeToStability) { const taskId = this.pendingTasks.add(); return this.chain(initialRequest, (downstreamRequest) => this.backend.handle(downstreamRequest)).pipe(finalize(() => this.pendingTasks.remove(taskId))); } else { return this.chain(initialRequest, (downstreamRequest) => this.backend.handle(downstreamRequest)); } } static \u0275fac = function HttpInterceptorHandler_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpInterceptorHandler)(\u0275\u0275inject(HttpBackend), \u0275\u0275inject(EnvironmentInjector)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HttpInterceptorHandler, factory: _HttpInterceptorHandler.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpInterceptorHandler, [{ type: Injectable }], () => [{ type: HttpBackend }, { type: EnvironmentInjector }], null); })(); var nextRequestId = 0; var foreignDocument; var JSONP_ERR_NO_CALLBACK = "JSONP injected script did not invoke callback."; var JSONP_ERR_WRONG_METHOD = "JSONP requests must use JSONP request method."; var JSONP_ERR_WRONG_RESPONSE_TYPE = "JSONP requests must use Json response type."; var JSONP_ERR_HEADERS_NOT_SUPPORTED = "JSONP requests do not support headers."; var JsonpCallbackContext = class { }; function jsonpCallbackContext() { if (typeof window === "object") { return window; } return {}; } var JsonpClientBackend = class _JsonpClientBackend { callbackMap; document; /** * A resolved promise that can be used to schedule microtasks in the event handlers. */ resolvedPromise = Promise.resolve(); constructor(callbackMap, document2) { this.callbackMap = callbackMap; this.document = document2; } /** * Get the name of the next callback method, by incrementing the global `nextRequestId`. */ nextCallback() { return `ng_jsonp_callback_${nextRequestId++}`; } /** * Processes a JSONP request and returns an event stream of the results. * @param req The request object. * @returns An observable of the response events. * */ handle(req) { if (req.method !== "JSONP") { throw new RuntimeError(2810, ngDevMode && JSONP_ERR_WRONG_METHOD); } else if (req.responseType !== "json") { throw new RuntimeError(2811, ngDevMode && JSONP_ERR_WRONG_RESPONSE_TYPE); } if (req.headers.keys().length > 0) { throw new RuntimeError(2812, ngDevMode && JSONP_ERR_HEADERS_NOT_SUPPORTED); } return new Observable((observer) => { const callback = this.nextCallback(); const url = req.urlWithParams.replace(/=JSONP_CALLBACK(&|$)/, `=${callback}$1`); const node = this.document.createElement("script"); node.src = url; let body = null; let finished = false; this.callbackMap[callback] = (data) => { delete this.callbackMap[callback]; body = data; finished = true; }; const cleanup = () => { node.removeEventListener("load", onLoad); node.removeEventListener("error", onError); node.remove(); delete this.callbackMap[callback]; }; const onLoad = () => { this.resolvedPromise.then(() => { cleanup(); if (!finished) { observer.error(new HttpErrorResponse({ url, status: 0, statusText: "JSONP Error", error: new Error(JSONP_ERR_NO_CALLBACK) })); return; } observer.next(new HttpResponse({ body, status: HTTP_STATUS_CODE_OK, statusText: "OK", url })); observer.complete(); }); }; const onError = (error) => { cleanup(); observer.error(new HttpErrorResponse({ error, status: 0, statusText: "JSONP Error", url })); }; node.addEventListener("load", onLoad); node.addEventListener("error", onError); this.document.body.appendChild(node); observer.next({ type: HttpEventType.Sent }); return () => { if (!finished) { this.removeListeners(node); } cleanup(); }; }); } removeListeners(script) { foreignDocument ??= this.document.implementation.createHTMLDocument(); foreignDocument.adoptNode(script); } static \u0275fac = function JsonpClientBackend_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _JsonpClientBackend)(\u0275\u0275inject(JsonpCallbackContext), \u0275\u0275inject(DOCUMENT)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _JsonpClientBackend, factory: _JsonpClientBackend.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(JsonpClientBackend, [{ type: Injectable }], () => [{ type: JsonpCallbackContext }, { type: void 0, decorators: [{ type: Inject, args: [DOCUMENT] }] }], null); })(); function jsonpInterceptorFn(req, next) { if (req.method === "JSONP") { return inject(JsonpClientBackend).handle(req); } return next(req); } var JsonpInterceptor = class _JsonpInterceptor { injector; constructor(injector) { this.injector = injector; } /** * Identifies and handles a given JSONP request. * @param initialRequest The outgoing request object to handle. * @param next The next interceptor in the chain, or the backend * if no interceptors remain in the chain. * @returns An observable of the event stream. */ intercept(initialRequest, next) { return runInInjectionContext(this.injector, () => jsonpInterceptorFn(initialRequest, (downstreamRequest) => next.handle(downstreamRequest))); } static \u0275fac = function JsonpInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _JsonpInterceptor)(\u0275\u0275inject(EnvironmentInjector)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _JsonpInterceptor, factory: _JsonpInterceptor.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(JsonpInterceptor, [{ type: Injectable }], () => [{ type: EnvironmentInjector }], null); })(); var XSSI_PREFIX = /^\)\]\}',?\n/; var X_REQUEST_URL_REGEXP = RegExp(`^${X_REQUEST_URL_HEADER}:`, "m"); function getResponseUrl(xhr) { if ("responseURL" in xhr && xhr.responseURL) { return xhr.responseURL; } if (X_REQUEST_URL_REGEXP.test(xhr.getAllResponseHeaders())) { return xhr.getResponseHeader(X_REQUEST_URL_HEADER); } return null; } var HttpXhrBackend = class _HttpXhrBackend { xhrFactory; constructor(xhrFactory) { this.xhrFactory = xhrFactory; } /** * Processes a request and returns a stream of response events. * @param req The request object. * @returns An observable of the response events. */ handle(req) { if (req.method === "JSONP") { throw new RuntimeError(-2800, (typeof ngDevMode === "undefined" || ngDevMode) && `Cannot make a JSONP request without JSONP support. To fix the problem, either add the \`withJsonpSupport()\` call (if \`provideHttpClient()\` is used) or import the \`HttpClientJsonpModule\` in the root NgModule.`); } const xhrFactory = this.xhrFactory; const source = xhrFactory.\u0275loadImpl ? from(xhrFactory.\u0275loadImpl()) : of(null); return source.pipe(switchMap(() => { return new Observable((observer) => { const xhr = xhrFactory.build(); xhr.open(req.method, req.urlWithParams); if (req.withCredentials) { xhr.withCredentials = true; } req.headers.forEach((name, values) => xhr.setRequestHeader(name, values.join(","))); if (!req.headers.has(ACCEPT_HEADER)) { xhr.setRequestHeader(ACCEPT_HEADER, ACCEPT_HEADER_VALUE); } if (!req.headers.has(CONTENT_TYPE_HEADER)) { const detectedType = req.detectContentTypeHeader(); if (detectedType !== null) { xhr.setRequestHeader(CONTENT_TYPE_HEADER, detectedType); } } if (req.responseType) { const responseType = req.responseType.toLowerCase(); xhr.responseType = responseType !== "json" ? responseType : "text"; } const reqBody = req.serializeBody(); let headerResponse = null; const partialFromXhr = () => { if (headerResponse !== null) { return headerResponse; } const statusText = xhr.statusText || "OK"; const headers = new HttpHeaders(xhr.getAllResponseHeaders()); const url = getResponseUrl(xhr) || req.url; headerResponse = new HttpHeaderResponse({ headers, status: xhr.status, statusText, url }); return headerResponse; }; const onLoad = () => { let { headers, status, statusText, url } = partialFromXhr(); let body = null; if (status !== HTTP_STATUS_CODE_NO_CONTENT) { body = typeof xhr.response === "undefined" ? xhr.responseText : xhr.response; } if (status === 0) { status = !!body ? HTTP_STATUS_CODE_OK : 0; } let ok = status >= 200 && status < 300; if (req.responseType === "json" && typeof body === "string") { const originalBody = body; body = body.replace(XSSI_PREFIX, ""); try { body = body !== "" ? JSON.parse(body) : null; } catch (error) { body = originalBody; if (ok) { ok = false; body = { error, text: body }; } } } if (ok) { observer.next(new HttpResponse({ body, headers, status, statusText, url: url || void 0 })); observer.complete(); } else { observer.error(new HttpErrorResponse({ // The error in this case is the response body (error from the server). error: body, headers, status, statusText, url: url || void 0 })); } }; const onError = (error) => { const { url } = partialFromXhr(); const res = new HttpErrorResponse({ error, status: xhr.status || 0, statusText: xhr.statusText || "Unknown Error", url: url || void 0 }); observer.error(res); }; let sentHeaders = false; const onDownProgress = (event) => { if (!sentHeaders) { observer.next(partialFromXhr()); sentHeaders = true; } let progressEvent = { type: HttpEventType.DownloadProgress, loaded: event.loaded }; if (event.lengthComputable) { progressEvent.total = event.total; } if (req.responseType === "text" && !!xhr.responseText) { progressEvent.partialText = xhr.responseText; } observer.next(progressEvent); }; const onUpProgress = (event) => { let progress = { type: HttpEventType.UploadProgress, loaded: event.loaded }; if (event.lengthComputable) { progress.total = event.total; } observer.next(progress); }; xhr.addEventListener("load", onLoad); xhr.addEventListener("error", onError); xhr.addEventListener("timeout", onError); xhr.addEventListener("abort", onError); if (req.reportProgress) { xhr.addEventListener("progress", onDownProgress); if (reqBody !== null && xhr.upload) { xhr.upload.addEventListener("progress", onUpProgress); } } xhr.send(reqBody); observer.next({ type: HttpEventType.Sent }); return () => { xhr.removeEventListener("error", onError); xhr.removeEventListener("abort", onError); xhr.removeEventListener("load", onLoad); xhr.removeEventListener("timeout", onError); if (req.reportProgress) { xhr.removeEventListener("progress", onDownProgress); if (reqBody !== null && xhr.upload) { xhr.upload.removeEventListener("progress", onUpProgress); } } if (xhr.readyState !== xhr.DONE) { xhr.abort(); } }; }); })); } static \u0275fac = function HttpXhrBackend_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpXhrBackend)(\u0275\u0275inject(XhrFactory)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HttpXhrBackend, factory: _HttpXhrBackend.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpXhrBackend, [{ type: Injectable }], () => [{ type: XhrFactory }], null); })(); var XSRF_ENABLED = new InjectionToken(ngDevMode ? "XSRF_ENABLED" : ""); var XSRF_DEFAULT_COOKIE_NAME = "XSRF-TOKEN"; var XSRF_COOKIE_NAME = new InjectionToken(ngDevMode ? "XSRF_COOKIE_NAME" : "", { providedIn: "root", factory: () => XSRF_DEFAULT_COOKIE_NAME }); var XSRF_DEFAULT_HEADER_NAME = "X-XSRF-TOKEN"; var XSRF_HEADER_NAME = new InjectionToken(ngDevMode ? "XSRF_HEADER_NAME" : "", { providedIn: "root", factory: () => XSRF_DEFAULT_HEADER_NAME }); var HttpXsrfTokenExtractor = class { }; var HttpXsrfCookieExtractor = class _HttpXsrfCookieExtractor { doc; platform; cookieName; lastCookieString = ""; lastToken = null; /** * @internal for testing */ parseCount = 0; constructor(doc, platform, cookieName) { this.doc = doc; this.platform = platform; this.cookieName = cookieName; } getToken() { if (this.platform === "server") { return null; } const cookieString = this.doc.cookie || ""; if (cookieString !== this.lastCookieString) { this.parseCount++; this.lastToken = parseCookieValue(cookieString, this.cookieName); this.lastCookieString = cookieString; } return this.lastToken; } static \u0275fac = function HttpXsrfCookieExtractor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpXsrfCookieExtractor)(\u0275\u0275inject(DOCUMENT), \u0275\u0275inject(PLATFORM_ID), \u0275\u0275inject(XSRF_COOKIE_NAME)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HttpXsrfCookieExtractor, factory: _HttpXsrfCookieExtractor.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpXsrfCookieExtractor, [{ type: Injectable }], () => [{ type: void 0, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: void 0, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: void 0, decorators: [{ type: Inject, args: [XSRF_COOKIE_NAME] }] }], null); })(); function xsrfInterceptorFn(req, next) { const lcUrl = req.url.toLowerCase(); if (!inject(XSRF_ENABLED) || req.method === "GET" || req.method === "HEAD" || lcUrl.startsWith("http://") || lcUrl.startsWith("https://")) { return next(req); } const token = inject(HttpXsrfTokenExtractor).getToken(); const headerName = inject(XSRF_HEADER_NAME); if (token != null && !req.headers.has(headerName)) { req = req.clone({ headers: req.headers.set(headerName, token) }); } return next(req); } var HttpXsrfInterceptor = class _HttpXsrfInterceptor { injector; constructor(injector) { this.injector = injector; } intercept(initialRequest, next) { return runInInjectionContext(this.injector, () => xsrfInterceptorFn(initialRequest, (downstreamRequest) => next.handle(downstreamRequest))); } static \u0275fac = function HttpXsrfInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpXsrfInterceptor)(\u0275\u0275inject(EnvironmentInjector)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _HttpXsrfInterceptor, factory: _HttpXsrfInterceptor.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpXsrfInterceptor, [{ type: Injectable }], () => [{ type: EnvironmentInjector }], null); })(); var HttpFeatureKind; (function(HttpFeatureKind2) { HttpFeatureKind2[HttpFeatureKind2["Interceptors"] = 0] = "Interceptors"; HttpFeatureKind2[HttpFeatureKind2["LegacyInterceptors"] = 1] = "LegacyInterceptors"; HttpFeatureKind2[HttpFeatureKind2["CustomXsrfConfiguration"] = 2] = "CustomXsrfConfiguration"; HttpFeatureKind2[HttpFeatureKind2["NoXsrfProtection"] = 3] = "NoXsrfProtection"; HttpFeatureKind2[HttpFeatureKind2["JsonpSupport"] = 4] = "JsonpSupport"; HttpFeatureKind2[HttpFeatureKind2["RequestsMadeViaParent"] = 5] = "RequestsMadeViaParent"; HttpFeatureKind2[HttpFeatureKind2["Fetch"] = 6] = "Fetch"; })(HttpFeatureKind || (HttpFeatureKind = {})); function makeHttpFeature(kind, providers) { return { \u0275kind: kind, \u0275providers: providers }; } function provideHttpClient(...features) { if (ngDevMode) { const featureKinds = new Set(features.map((f) => f.\u0275kind)); if (featureKinds.has(HttpFeatureKind.NoXsrfProtection) && featureKinds.has(HttpFeatureKind.CustomXsrfConfiguration)) { throw new Error(ngDevMode ? `Configuration error: found both withXsrfConfiguration() and withNoXsrfProtection() in the same call to provideHttpClient(), which is a contradiction.` : ""); } } const providers = [HttpClient, HttpXhrBackend, HttpInterceptorHandler, { provide: HttpHandler, useExisting: HttpInterceptorHandler }, { provide: HttpBackend, useFactory: () => { return inject(FETCH_BACKEND, { optional: true }) ?? inject(HttpXhrBackend); } }, { provide: HTTP_INTERCEPTOR_FNS, useValue: xsrfInterceptorFn, multi: true }, { provide: XSRF_ENABLED, useValue: true }, { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor }]; for (const feature of features) { providers.push(...feature.\u0275providers); } return makeEnvironmentProviders(providers); } var LEGACY_INTERCEPTOR_FN = new InjectionToken(ngDevMode ? "LEGACY_INTERCEPTOR_FN" : ""); function withInterceptorsFromDi() { return makeHttpFeature(HttpFeatureKind.LegacyInterceptors, [{ provide: LEGACY_INTERCEPTOR_FN, useFactory: legacyInterceptorFnFactory }, { provide: HTTP_INTERCEPTOR_FNS, useExisting: LEGACY_INTERCEPTOR_FN, multi: true }]); } function withXsrfConfiguration({ cookieName, headerName }) { const providers = []; if (cookieName !== void 0) { providers.push({ provide: XSRF_COOKIE_NAME, useValue: cookieName }); } if (headerName !== void 0) { providers.push({ provide: XSRF_HEADER_NAME, useValue: headerName }); } return makeHttpFeature(HttpFeatureKind.CustomXsrfConfiguration, providers); } function withNoXsrfProtection() { return makeHttpFeature(HttpFeatureKind.NoXsrfProtection, [{ provide: XSRF_ENABLED, useValue: false }]); } function withJsonpSupport() { return makeHttpFeature(HttpFeatureKind.JsonpSupport, [JsonpClientBackend, { provide: JsonpCallbackContext, useFactory: jsonpCallbackContext }, { provide: HTTP_INTERCEPTOR_FNS, useValue: jsonpInterceptorFn, multi: true }]); } function withFetch() { return makeHttpFeature(HttpFeatureKind.Fetch, [FetchBackend, { provide: FETCH_BACKEND, useExisting: FetchBackend }, { provide: HttpBackend, useExisting: FetchBackend }]); } var HttpClientXsrfModule = class _HttpClientXsrfModule { /** * Disable the default XSRF protection. */ static disable() { return { ngModule: _HttpClientXsrfModule, providers: [withNoXsrfProtection().\u0275providers] }; } /** * Configure XSRF protection. * @param options An object that can specify either or both * cookie name or header name. * - Cookie name default is `XSRF-TOKEN`. * - Header name default is `X-XSRF-TOKEN`. * */ static withOptions(options = {}) { return { ngModule: _HttpClientXsrfModule, providers: withXsrfConfiguration(options).\u0275providers }; } static \u0275fac = function HttpClientXsrfModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpClientXsrfModule)(); }; static \u0275mod = /* @__PURE__ */ \u0275\u0275defineNgModule({ type: _HttpClientXsrfModule }); static \u0275inj = /* @__PURE__ */ \u0275\u0275defineInjector({ providers: [HttpXsrfInterceptor, { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true }, { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor }, withXsrfConfiguration({ cookieName: XSRF_DEFAULT_COOKIE_NAME, headerName: XSRF_DEFAULT_HEADER_NAME }).\u0275providers, { provide: XSRF_ENABLED, useValue: true }] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpClientXsrfModule, [{ type: NgModule, args: [{ providers: [HttpXsrfInterceptor, { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true }, { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor }, withXsrfConfiguration({ cookieName: XSRF_DEFAULT_COOKIE_NAME, headerName: XSRF_DEFAULT_HEADER_NAME }).\u0275providers, { provide: XSRF_ENABLED, useValue: true }] }] }], null, null); })(); var HttpClientModule = class _HttpClientModule { static \u0275fac = function HttpClientModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpClientModule)(); }; static \u0275mod = /* @__PURE__ */ \u0275\u0275defineNgModule({ type: _HttpClientModule }); static \u0275inj = /* @__PURE__ */ \u0275\u0275defineInjector({ providers: [provideHttpClient(withInterceptorsFromDi())] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpClientModule, [{ type: NgModule, args: [{ /** * Configures the dependency injector where it is imported * with supporting services for HTTP communications. */ providers: [provideHttpClient(withInterceptorsFromDi())] }] }], null, null); })(); var HttpClientJsonpModule = class _HttpClientJsonpModule { static \u0275fac = function HttpClientJsonpModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _HttpClientJsonpModule)(); }; static \u0275mod = /* @__PURE__ */ \u0275\u0275defineNgModule({ type: _HttpClientJsonpModule }); static \u0275inj = /* @__PURE__ */ \u0275\u0275defineInjector({ providers: [withJsonpSupport().\u0275providers] }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HttpClientJsonpModule, [{ type: NgModule, args: [{ providers: [withJsonpSupport().\u0275providers] }] }], null, null); })(); var httpResource = (() => { const jsonFn = makeHttpResourceFn("json"); jsonFn.arrayBuffer = makeHttpResourceFn("arraybuffer"); jsonFn.blob = makeHttpResourceFn("blob"); jsonFn.text = makeHttpResourceFn("text"); return jsonFn; })(); function makeHttpResourceFn(responseType) { return function httpResourceRef(request, options) { options?.injector || assertInInjectionContext(httpResource); const injector = options?.injector ?? inject(Injector); return new HttpResourceImpl(injector, () => normalizeRequest(request, responseType), options?.defaultValue, options?.parse, options?.equal); }; } function normalizeRequest(request, responseType) { let unwrappedRequest = typeof request === "function" ? request() : request; if (unwrappedRequest === void 0) { return void 0; } else if (typeof unwrappedRequest === "string") { unwrappedRequest = { url: unwrappedRequest }; } const headers = unwrappedRequest.headers instanceof HttpHeaders ? unwrappedRequest.headers : new HttpHeaders(unwrappedRequest.headers); const params = unwrappedRequest.params instanceof HttpParams ? unwrappedRequest.params : new HttpParams({ fromObject: unwrappedRequest.params }); return new HttpRequest(unwrappedRequest.method ?? "GET", unwrappedRequest.url, unwrappedRequest.body ?? null, { headers, params, reportProgress: unwrappedRequest.reportProgress, withCredentials: unwrappedRequest.withCredentials, responseType, context: unwrappedRequest.context, transferCache: unwrappedRequest.transferCache }); } var HttpResourceImpl = class extends ResourceImpl { client; _headers = linkedSignal({ source: this.extRequest, computation: () => void 0 }); _progress = linkedSignal({ source: this.extRequest, computation: () => void 0 }); _statusCode = linkedSignal({ source: this.extRequest, computation: () => void 0 }); headers = computed(() => this.status() === ResourceStatus.Resolved || this.status() === ResourceStatus.Error ? this._headers() : void 0); progress = this._progress.asReadonly(); statusCode = this._statusCode.asReadonly(); constructor(injector, request, defaultValue, parse, equal) { super(request, ({ request: request2, abortSignal }) => { let sub; const onAbort = () => sub.unsubscribe(); abortSignal.addEventListener("abort", onAbort); const stream = signal({ value: void 0 }); let resolve; const promise = new Promise((r) => resolve = r); const send = (value) => { stream.set(value); resolve?.(stream); resolve = void 0; }; sub = this.client.request(request2).subscribe({ next: (event) => { switch (event.type) { case HttpEventType.Response: this._headers.set(event.headers); this._statusCode.set(event.status); try { send({ value: parse ? parse(event.body) : event.body }); } catch (error) { send({ error }); } break; case HttpEventType.DownloadProgress: this._progress.set(event); break; } }, error: (error) => send({ error }), complete: () => { if (resolve) { send({ error: new Error("Resource completed before producing a value") }); } abortSignal.removeEventListener("abort", onAbort); } }); return promise; }, defaultValue, equal, injector); this.client = injector.get(HttpClient); } }; var HTTP_TRANSFER_CACHE_ORIGIN_MAP = new InjectionToken(ngDevMode ? "HTTP_TRANSFER_CACHE_ORIGIN_MAP" : ""); var BODY = "b"; var HEADERS = "h"; var STATUS = "s"; var STATUS_TEXT = "st"; var REQ_URL = "u"; var RESPONSE_TYPE = "rt"; var CACHE_OPTIONS = new InjectionToken(ngDevMode ? "HTTP_TRANSFER_STATE_CACHE_OPTIONS" : ""); var ALLOWED_METHODS = ["GET", "HEAD"]; function transferCacheInterceptorFn(req, next) { const _a = inject(CACHE_OPTIONS), { isCacheActive } = _a, globalOptions = __objRest(_a, [ "isCacheActive" ]); const { transferCache: requestOptions, method: requestMethod } = req; if (!isCacheActive || requestOptions === false || // POST requests are allowed either globally or at request level requestMethod === "POST" && !globalOptions.includePostRequests && !requestOptions || requestMethod !== "POST" && !ALLOWED_METHODS.includes(requestMethod) || // Do not cache request that require authorization when includeRequestsWithAuthHeaders is falsey !globalOptions.includeRequestsWithAuthHeaders && hasAuthHeaders(req) || globalOptions.filter?.(req) === false) { return next(req); } const transferState = inject(TransferState); const originMap = inject(HTTP_TRANSFER_CACHE_ORIGIN_MAP, { optional: true }); if (originMap) { throw new RuntimeError(2803, ngDevMode && "Angular detected that the `HTTP_TRANSFER_CACHE_ORIGIN_MAP` token is configured and present in the client side code. Please ensure that this token is only provided in the server code of the application."); } const requestUrl = false ? mapRequestOriginUrl(req.url, originMap) : req.url; const storeKey = makeCacheKey(req, requestUrl); const response = transferState.get(storeKey, null); let headersToInclude = globalOptions.includeHeaders; if (typeof requestOptions === "object" && requestOptions.includeHeaders) { headersToInclude = requestOptions.includeHeaders; } if (response) { const { [BODY]: undecodedBody, [RESPONSE_TYPE]: responseType, [HEADERS]: httpHeaders, [STATUS]: status, [STATUS_TEXT]: statusText, [REQ_URL]: url } = response; let body = undecodedBody; switch (responseType) { case "arraybuffer": body = new TextEncoder().encode(undecodedBody).buffer; break; case "blob": body = new Blob([undecodedBody]); break; } let headers = new HttpHeaders(httpHeaders); if (typeof ngDevMode === "undefined" || ngDevMode) { headers = appendMissingHeadersDetection(req.url, headers, headersToInclude ?? []); } return of(new HttpResponse({ body, headers, status, statusText, url })); } return next(req).pipe(tap((event) => { if (event instanceof HttpResponse && true && false) { transferState.set(storeKey, { [BODY]: event.body, [HEADERS]: getFilteredHeaders(event.headers, headersToInclude), [STATUS]: event.status, [STATUS_TEXT]: event.statusText, [REQ_URL]: requestUrl, [RESPONSE_TYPE]: req.responseType }); } })); } function hasAuthHeaders(req) { return req.headers.has("authorization") || req.headers.has("proxy-authorization"); } function sortAndConcatParams(params) { return [...params.keys()].sort().map((k) => `${k}=${params.getAll(k)}`).join("&"); } function makeCacheKey(request, mappedRequestUrl) { const { params, method, responseType } = request; const encodedParams = sortAndConcatParams(params); let serializedBody = request.serializeBody(); if (serializedBody instanceof URLSearchParams) { serializedBody = sortAndConcatParams(serializedBody); } else if (typeof serializedBody !== "string") { serializedBody = ""; } const key = [method, responseType, mappedRequestUrl, serializedBody, encodedParams].join("|"); const hash = generateHash(key); return makeStateKey(hash); } function generateHash(value) { let hash = 0; for (const char of value) { hash = Math.imul(31, hash) + char.charCodeAt(0) << 0; } hash += 2147483647 + 1; return hash.toString(); } function withHttpTransferCache(cacheOptions) { return [{ provide: CACHE_OPTIONS, useFactory: () => { performanceMarkFeature("NgHttpTransferCache"); return __spreadValues({ isCacheActive: true }, cacheOptions); } }, { provide: HTTP_ROOT_INTERCEPTOR_FNS, useValue: transferCacheInterceptorFn, multi: true }, { provide: APP_BOOTSTRAP_LISTENER, multi: true, useFactory: () => { const appRef = inject(ApplicationRef); const cacheState = inject(CACHE_OPTIONS); return () => { appRef.whenStable().then(() => { cacheState.isCacheActive = false; }); }; } }]; } function appendMissingHeadersDetection(url, headers, headersToInclude) { const warningProduced = /* @__PURE__ */ new Set(); return new Proxy(headers, { get(target, prop) { const value = Reflect.get(target, prop); const methods = /* @__PURE__ */ new Set(["get", "has", "getAll"]); if (typeof value !== "function" || !methods.has(prop)) { return value; } return (headerName) => { const key = (prop + ":" + headerName).toLowerCase(); if (!headersToInclude.includes(headerName) && !warningProduced.has(key)) { warningProduced.add(key); const truncatedUrl = truncateMiddle(url); console.warn(formatRuntimeError(2802, `Angular detected that the \`${headerName}\` header is accessed, but the value of the header was not transferred from the server to the client by the HttpTransferCache. To include the value of the \`${headerName}\` header for the \`${truncatedUrl}\` request, use the \`includeHeaders\` list. The \`includeHeaders\` can be defined either on a request level by adding the \`transferCache\` parameter, or on an application level by adding the \`httpCacheTransfer.includeHeaders\` argument to the \`provideClientHydration()\` call. `)); } return value.apply(target, [headerName]); }; } }); } // node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs var GenericBrowserDomAdapter = class extends DomAdapter { supportsDOMEvents = true; }; var BrowserDomAdapter = class _BrowserDomAdapter extends GenericBrowserDomAdapter { static makeCurrent() { setRootDomAdapter(new _BrowserDomAdapter()); } onAndCancel(el, evt, listener, options) { el.addEventListener(evt, listener, options); return () => { el.removeEventListener(evt, listener, options); }; } dispatchEvent(el, evt) { el.dispatchEvent(evt); } remove(node) { node.remove(); } createElement(tagName, doc) { doc = doc || this.getDefaultDocument(); return doc.createElement(tagName); } createHtmlDocument() { return document.implementation.createHTMLDocument("fakeTitle"); } getDefaultDocument() { return document; } isElementNode(node) { return node.nodeType === Node.ELEMENT_NODE; } isShadowRoot(node) { return node instanceof DocumentFragment; } /** @deprecated No longer being used in Ivy code. To be removed in version 14. */ getGlobalEventTarget(doc, target) { if (target === "window") { return window; } if (target === "document") { return doc; } if (target === "body") { return doc.body; } return null; } getBaseHref(doc) { const href = getBaseElementHref(); return href == null ? null : relativePath(href); } resetBaseElement() { baseElement = null; } getUserAgent() { return window.navigator.userAgent; } getCookie(name) { return parseCookieValue(document.cookie, name); } }; var baseElement = null; function getBaseElementHref() { baseElement = baseElement || document.querySelector("base"); return baseElement ? baseElement.getAttribute("href") : null; } function relativePath(url) { return new URL(url, document.baseURI).pathname; } var BrowserGetTestability = class { addToWindow(registry) { _global["getAngularTestability"] = (elem, findInAncestors = true) => { const testability = registry.findTestabilityInTree(elem, findInAncestors); if (testability == null) { throw new RuntimeError(5103, (typeof ngDevMode === "undefined" || ngDevMode) && "Could not find testability for element."); } return testability; }; _global["getAllAngularTestabilities"] = () => registry.getAllTestabilities(); _global["getAllAngularRootElements"] = () => registry.getAllRootElements(); const whenAllStable = (callback) => { const testabilities = _global["getAllAngularTestabilities"](); let count = testabilities.length; const decrement = function() { count--; if (count == 0) { callback(); } }; testabilities.forEach((testability) => { testability.whenStable(decrement); }); }; if (!_global["frameworkStabilizers"]) { _global["frameworkStabilizers"] = []; } _global["frameworkStabilizers"].push(whenAllStable); } findTestabilityInTree(registry, elem, findInAncestors) { if (elem == null) { return null; } const t = registry.getTestability(elem); if (t != null) { return t; } else if (!findInAncestors) { return null; } if (getDOM().isShadowRoot(elem)) { return this.findTestabilityInTree(registry, elem.host, true); } return this.findTestabilityInTree(registry, elem.parentElement, true); } }; var BrowserXhr = class _BrowserXhr { build() { return new XMLHttpRequest(); } static \u0275fac = function BrowserXhr_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _BrowserXhr)(); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _BrowserXhr, factory: _BrowserXhr.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(BrowserXhr, [{ type: Injectable }], null, null); })(); var EVENT_MANAGER_PLUGINS = new InjectionToken(ngDevMode ? "EventManagerPlugins" : ""); var EventManager = class _EventManager { _zone; _plugins; _eventNameToPlugin = /* @__PURE__ */ new Map(); /** * Initializes an instance of the event-manager service. */ constructor(plugins, _zone) { this._zone = _zone; plugins.forEach((plugin) => { plugin.manager = this; }); this._plugins = plugins.slice().reverse(); } /** * Registers a handler for a specific element and event. * * @param element The HTML element to receive event notifications. * @param eventName The name of the event to listen for. * @param handler A function to call when the notification occurs. Receives the * event object as an argument. * @param options Options that configure how the event listener is bound. * @returns A callback function that can be used to remove the handler. */ addEventListener(element, eventName, handler, options) { const plugin = this._findPluginFor(eventName); return plugin.addEventListener(element, eventName, handler, options); } /** * Retrieves the compilation zone in which event listeners are registered. */ getZone() { return this._zone; } /** @internal */ _findPluginFor(eventName) { let plugin = this._eventNameToPlugin.get(eventName); if (plugin) { return plugin; } const plugins = this._plugins; plugin = plugins.find((plugin2) => plugin2.supports(eventName)); if (!plugin) { throw new RuntimeError(5101, (typeof ngDevMode === "undefined" || ngDevMode) && `No event manager plugin found for event ${eventName}`); } this._eventNameToPlugin.set(eventName, plugin); return plugin; } static \u0275fac = function EventManager_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _EventManager)(\u0275\u0275inject(EVENT_MANAGER_PLUGINS), \u0275\u0275inject(NgZone)); }; static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _EventManager, factory: _EventManager.\u0275fac }); }; (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(EventManager, [{ type: Injectable }], () => [{ type: void 0, decorators: [{ type: Inject, args: [EVENT_MANAGER_PLUGINS] }] }, { type: NgZone }], null); })(); var EventManagerPlugin = class { _doc; // TODO: remove (has some usage in G3) constructor(_doc) { this._doc = _doc; } // Using non-null assertion because it's set by EventManager's constructor manager; }; var APP_ID_ATTRIBUTE_NAME = "ng-app-id"; function removeElements(elements) { for (const element of elements) { element.remove(); } } function createStyleElement(style, doc) { const styleElement = doc.createElement("style"); styleElement.textContent = style; return styleElement; } function addServerStyles(doc, appId, inline, external) { const elements = doc.head?.querySelectorAll(`style[${APP_ID_ATTRIBUTE_NAME}="${appId}"],link[${APP_ID_ATTRIBUTE_NAME}="${appId}"]`); if (elements) { for (const styleElement of elements) { styleElement.removeAttribute(APP_ID_ATTRIBUTE_NAME); if (styleElement instanceof HTMLLinkElement) { external.set(styleElement.href.slice(styleElement.href.lastIndexOf("/") + 1), { usage: 0, elements: [styleElement] }); } else if (styleElement.textContent) { inline.set(styleElement.textContent, { usage: 0, elements: [styleElement] }); } } } } function createLinkElement(url, doc) { const linkElement = doc.createElement("link"); linkElement.setAttribute("rel", "stylesheet"); linkElement.setAttribute("href", url); return linkElement; } var SharedStylesHost = class _SharedStylesHost { doc; appId; nonce; /** * Provides usage information for active inline style content and associated HTML