ngx-atomic-i18n 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,347 @@
1
+ import * as ngx_atomic_i18n from 'ngx-atomic-i18n';
2
+ import * as rxjs from 'rxjs';
3
+ import { Observable } from 'rxjs';
4
+ import * as i0 from '@angular/core';
5
+ import { Signal, PipeTransform, Provider, InjectionToken } from '@angular/core';
6
+ import { HttpClient } from '@angular/common/http';
7
+
8
+ /** Global configuration contract used by the translation system. */
9
+ interface TranslationConfig {
10
+ supportedLangs: string[];
11
+ fallbackLang: string;
12
+ i18nRoots: string[];
13
+ pathTemplates: string[] | string;
14
+ fallbackNamespace: string;
15
+ langDetectionOrder: ('localStorage' | 'url' | 'browser' | 'customLang' | 'fallback' | 'clientRequest')[];
16
+ /** Enable verbose logging. Defaults to true in dev mode. */
17
+ debug?: boolean;
18
+ /** Enable use */
19
+ enablePageFallback: boolean;
20
+ preloadNamespaces?: string[];
21
+ customLang?: (() => string) | string;
22
+ /** Language passed from SSR request and reused on the client. */
23
+ clientRequestLang?: string | null;
24
+ missingTranslationBehavior?: MissingTranslationBehavior;
25
+ }
26
+ /** Metadata passed into consumers to indicate namespace readiness. */
27
+ interface TranslationContext {
28
+ namespace: string;
29
+ ready?: Signal<boolean>;
30
+ }
31
+ type LazyLoader = Record<Lang, () => Promise<Translations>>;
32
+ type Params = Record<string, any>;
33
+ type Translations = Record<string, string>;
34
+ type Lang = string;
35
+ /** lang:namespace:version */
36
+ type nsKey = string;
37
+ /**
38
+ * How the translation system should behave when a translation key is missing.
39
+ *
40
+ * - 'show-key': Display the key itself (e.g., `'menu.about'`) as a fallback.
41
+ * - 'empty': Show an empty string. Use this if you prefer untranslated text to disappear silently.
42
+ * - 'throw': Throw a runtime error. Recommended only during development or testing; will break the UI if not handled.
43
+ * - string: Any custom string, e.g., '--', 'loading...', etc.
44
+ */
45
+ type MissingTranslationBehavior = 'show-key' | 'empty' | 'throw-error';
46
+ interface TranslationLoader {
47
+ /**
48
+ * @param i18nRoot List of base folders to look for JSON (ordered by priority)
49
+ * @param ns Namespace, e.g. "home" or "auth-login"
50
+ * @param lang Language code, e.g. "en" or "zh-Hant"
51
+ */
52
+ load(i18nRoots: string[], namespace: string, lang: string): Promise<Translations>;
53
+ }
54
+ type FormatResult = {
55
+ format(params: Record<string, any>): string;
56
+ };
57
+ type DeepPartial<T> = {
58
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
59
+ };
60
+ interface FsModuleLike {
61
+ /** Minimal subset of Node's fs API needed by the SSR loader. */
62
+ readFileSync(path: string, encoding: 'utf8'): string;
63
+ statSync(path: string): any;
64
+ }
65
+ /** Options used to customise the SSR file-system loader. */
66
+ interface FsLoaderOptions {
67
+ /** only for SSR , e.g. process.cwd() */
68
+ baseDir?: string;
69
+ /** e.g. 'projects/app/src/assets' (dev) or 'dist/app/browser/assets' */
70
+ assetPath?: string;
71
+ /** Custom resolver that returns an ordered list of candidate absolute paths. */
72
+ resolvePaths?: (ctx: {
73
+ baseDir: string;
74
+ assetPath: string;
75
+ root: string;
76
+ lang: string;
77
+ namespace: string;
78
+ }) => string[];
79
+ /** Custom fs module instance (takes precedence over dynamic imports). */
80
+ fsModule?: FsModuleLike;
81
+ cacheMax?: number;
82
+ }
83
+ /** Options used to customise the HTTP loader in CSR environments. */
84
+ interface HttpLoaderOptions {
85
+ /** default '/assets' */
86
+ baseUrl?: string;
87
+ }
88
+ /** Aggregate options exposed via `provideTranslationInit`. */
89
+ interface TranslationLoaderOptions {
90
+ forceMode?: 'ssr' | 'csr';
91
+ ssrLoader?: () => TranslationLoader;
92
+ csrLoader?: (http: HttpClient) => TranslationLoader;
93
+ fsOptions?: FsLoaderOptions;
94
+ httpOptions?: HttpLoaderOptions;
95
+ }
96
+ type CacheEntry = {
97
+ mtimeMs: number;
98
+ data: Translations;
99
+ };
100
+ type PathTemplate = string | string[] | undefined;
101
+ declare enum TempToken {
102
+ /** Placeholder for the language code inside loader path templates. */
103
+ Lang = "{{lang}}",
104
+ /** Placeholder for the namespace inside loader path templates. */
105
+ Namespace = "{{namespace}}",
106
+ /** Placeholder for the root folder inside loader path templates. */
107
+ Root = "{{root}}"
108
+ }
109
+
110
+ declare class TranslationCoreService {
111
+ /** Immutable runtime configuration injected from the library bootstrap. */
112
+ private readonly _config;
113
+ /** Active loader used to fetch namespace JSON payloads. */
114
+ private readonly _loader;
115
+ /** Optional custom ICU formatter constructor supplied by the host application. */
116
+ private readonly _ICU;
117
+ private readonly debugEnabled;
118
+ /** Reactive language state tracking the current locale. */
119
+ private readonly _lang;
120
+ readonly lang: Signal<string>;
121
+ /** Translation documents keyed by language then namespace. */
122
+ private readonly _jsonCache;
123
+ /** Version fingerprints captured alongside each namespace entry. */
124
+ private readonly _versionMap;
125
+ /** Least-recently-used cache of compiled ICU formatters. */
126
+ private readonly _formatterCache;
127
+ private _missingKeyCache;
128
+ private _inflight;
129
+ /** Caches compiled ICU expressions (with or without custom formatters). */
130
+ private readonly _icuCompiledCache;
131
+ readonly onLangChange: rxjs.Observable<string>;
132
+ readonly fallbackLang: string;
133
+ get currentLang(): string;
134
+ readySignal(namespace: string, version?: string): Signal<boolean>;
135
+ setLang(lang?: string): void;
136
+ load(nsKey: string, fetchFn: () => Promise<Translations>): Promise<void>;
137
+ getAndCreateFormatter(nsKey: string, key: string): FormatResult | undefined;
138
+ findFallbackFormatter(key: string, exclude: string[], version?: string): FormatResult | undefined;
139
+ preloadNamespaces(namespaces: string[], lang: string): Promise<void>;
140
+ private handleNewTranslations;
141
+ private hasJsonCacheValue;
142
+ addResourceBundle(lang: string, namespace: string, bundle: Translations, deep?: boolean, overwrite?: boolean): void;
143
+ addResources(lang: string, namespace: string, obj: Translations, overwrite?: boolean): void;
144
+ addResource(lang: string, namespace: string, key: string, val: string, overwrite?: boolean): void;
145
+ getAllBundle(): Map<string, Map<string, Record<string, any>>>;
146
+ hasResourceBundle(lang: string, namespace: string): boolean;
147
+ getResourceBundle(lang: string, namespace: string): Translations | undefined;
148
+ removeResourceBundle(lang: string, namespace: string): void;
149
+ /** Clear everything: data, versions, formatters, missing keys, inflight */
150
+ clearAll(): void;
151
+ /** Clear all resources for a language */
152
+ clearLang(lang: string): void;
153
+ /** Clear a specific namespace for a language */
154
+ clearNamespace(lang: string, namespace: string): void;
155
+ getResource(lang: string, namespace: string, key: string): string | undefined;
156
+ private log;
157
+ private error;
158
+ private warn;
159
+ static ɵfac: i0.ɵɵFactoryDeclaration<TranslationCoreService, never>;
160
+ static ɵprov: i0.ɵɵInjectableDeclaration<TranslationCoreService>;
161
+ }
162
+
163
+ declare class TranslationService {
164
+ readonly namespaceInput: string;
165
+ /** Shared translation configuration resolved from the host application. */
166
+ private readonly config;
167
+ private readonly parent;
168
+ private readonly isPageRoot;
169
+ /** Core translation engine that handles lookups and formatter lifecycle. */
170
+ private readonly core;
171
+ /** Loader implementation responsible for fetching translation payloads. */
172
+ private readonly loader;
173
+ /** Optional build fingerprint for cache busting injected at runtime. */
174
+ private readonly injectedVersion;
175
+ /** Flag used to guard debug logging output. */
176
+ private readonly debugEnabled;
177
+ /** Observable mirror of the language signal for consumers outside of signals. */
178
+ readonly onLangChange: rxjs.Observable<string>;
179
+ /** Namespace currently owned by this service instance. */
180
+ private namespace;
181
+ get lang(): Signal<string>;
182
+ get currentLang(): string;
183
+ get supportedLangs(): string[];
184
+ /** Build version identifier used to scope namespace caches. */
185
+ private readonly buildVersion;
186
+ /** Composes the unique key used to store namespace resources per lang and build. */
187
+ get getNskey(): string;
188
+ /** Signal that flips to true when the namespace resources are available. */
189
+ get readySignal(): Signal<boolean>;
190
+ /** Convenience boolean wrapper around the readiness signal. */
191
+ get ready(): boolean;
192
+ constructor(namespaceInput: string);
193
+ /** Switches the active language and triggers downstream refresh logic. */
194
+ setLang(lang: string): void;
195
+ /**
196
+ * Resolves the translation for `key`, formatting with the provided params
197
+ * and falling back to configured behaviors when a translation is missing.
198
+ */
199
+ t(key: string, params?: Params): string;
200
+ /** Determines the fallback string or error when a translation entry is missing. */
201
+ private getMissingTranslation;
202
+ /** Pass-through helpers that delegate resource management to the core service. */
203
+ addResourceBundle(...p: Parameters<TranslationCoreService['addResourceBundle']>): void;
204
+ addResources(...p: Parameters<TranslationCoreService['addResources']>): void;
205
+ addResource(...p: Parameters<TranslationCoreService['addResource']>): void;
206
+ hasResourceBundle(...p: Parameters<TranslationCoreService['hasResourceBundle']>): boolean;
207
+ getResource(...p: Parameters<TranslationCoreService['getResource']>): string;
208
+ getResourceBundle(...p: Parameters<TranslationCoreService['getResourceBundle']>): ngx_atomic_i18n.Translations;
209
+ getAllBundle(): Map<string, Map<string, Record<string, any>>>;
210
+ removeResourceBundle(...p: Parameters<TranslationCoreService['removeResourceBundle']>): void;
211
+ preloadNamespaces(...p: Parameters<TranslationCoreService['preloadNamespaces']>): Promise<void>;
212
+ /** Emits debug info when verbose logging is enabled. */
213
+ private info;
214
+ /** Emits debug warnings when verbose logging is enabled. */
215
+ private warn;
216
+ static ɵfac: i0.ɵɵFactoryDeclaration<TranslationService, never>;
217
+ static ɵprov: i0.ɵɵInjectableDeclaration<TranslationService>;
218
+ }
219
+
220
+ declare class TranslationPipe implements PipeTransform {
221
+ private readonly service;
222
+ /** Formats the translation identified by `key` using the optional params. */
223
+ transform(key: string, params?: Params): string;
224
+ static ɵfac: i0.ɵɵFactoryDeclaration<TranslationPipe, never>;
225
+ static ɵpipe: i0.ɵɵPipeDeclaration<TranslationPipe, "t", true>;
226
+ }
227
+
228
+ declare class TranslationDirective {
229
+ private selfElm;
230
+ private service;
231
+ /** Translation key resolved for the host element. */
232
+ readonly t: i0.InputSignal<string>;
233
+ /** Optional interpolation parameters passed to the translation formatter. */
234
+ readonly tParams: i0.InputSignal<Params>;
235
+ /** Attribute name to receive the translated value instead of textContent. */
236
+ readonly tAttr: i0.InputSignal<string>;
237
+ constructor();
238
+ static ɵfac: i0.ɵɵFactoryDeclaration<TranslationDirective, never>;
239
+ static ɵdir: i0.ɵɵDirectiveDeclaration<TranslationDirective, "[t]", never, { "t": { "alias": "t"; "required": false; "isSignal": true; }; "tParams": { "alias": "tParams"; "required": false; "isSignal": true; }; "tAttr": { "alias": "tAttr"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
240
+ }
241
+
242
+ type ProvideTranslationInitOptions = Partial<TranslationConfig> & {
243
+ loader?: TranslationLoaderOptions;
244
+ /** Optional global build version for SSR/CSR to align caches */
245
+ buildVersion?: string | null;
246
+ };
247
+ declare const defaultConfig: TranslationConfig;
248
+ /** Bootstraps the entire translation infrastructure for an application. */
249
+ declare function provideTranslationInit(userConfig?: ProvideTranslationInitOptions): Provider[];
250
+ /** Provides the component-scoped namespace injection for component-registered service.
251
+ * @param namespace The namespace owned by the component.
252
+ * @param isPage Whether the component is a top-level page (defaults to false).
253
+ */
254
+ declare function provideTranslation(namespace: string, isPage?: boolean): Provider[];
255
+ /** Configures the runtime translation loader for CSR or SSR environments. */
256
+ declare function provideTranslationLoader(config: ProvideTranslationInitOptions): Provider[];
257
+
258
+ declare class HttpTranslationLoader implements TranslationLoader {
259
+ private readonly http;
260
+ private readonly option;
261
+ private readonly pathTemplates;
262
+ private pathTemplateCache?;
263
+ constructor(http: HttpClient, option: HttpLoaderOptions, pathTemplates: string[] | string);
264
+ load(i18nRoots: string[], namespace: string, lang: string): Promise<Translations>;
265
+ }
266
+
267
+ /** File-system backed loader used during SSR to read translation JSON from disk. */
268
+ declare class FsTranslationLoader implements TranslationLoader {
269
+ private fsOptions;
270
+ private pathTemplates;
271
+ private customFs?;
272
+ private cache;
273
+ /**
274
+ * @param customFs Optional fs-like abstraction injected explicitly (tests or adapters).
275
+ */
276
+ constructor(fsOptions: FsLoaderOptions, pathTemplates: string[] | string, customFs?: FsModuleLike);
277
+ load(i18nRoots: string[] | string, namespace: string, lang: string): Promise<Translations>;
278
+ /** Attempts to import a Node built-in without throwing when unavailable (e.g. CSR). */
279
+ private importSafely;
280
+ private pickFs;
281
+ private safeJoin;
282
+ }
283
+
284
+ /** Scoped namespace for translating a component tree (string or array). */
285
+ declare const TRANSLATION_NAMESPACE: InjectionToken<string>;
286
+ /** Root configuration describing language support and loader behavior. */
287
+ declare const TRANSLATION_CONFIG: InjectionToken<TranslationConfig>;
288
+ /** Factory used to retrieve translation JSON for a namespace/language tuple. */
289
+ declare const TRANSLATION_LOADER: InjectionToken<TranslationLoader>;
290
+ /** Optional build fingerprint appended to namespace cache keys. */
291
+ declare const BUILD_VERSION: InjectionToken<string>;
292
+ /** Custom ICU formatter constructor injected by the host app when available. */
293
+ declare const ICU_FORMATTER_TOKEN: InjectionToken<any>;
294
+ declare const PAGE_TRANSLATION_ROOT: InjectionToken<boolean>;
295
+ /** Per-request language captured during SSR and replayed on CSR. */
296
+ declare const CLIENT_REQUEST_LANG: InjectionToken<string>;
297
+
298
+ /** Normalizes a language code against the configured supported languages. */
299
+ declare function normalizeLangCode(lang: string | null | undefined, supportedLangs: string[]): string | null;
300
+ /** Determines the most appropriate language using the configured detection order. */
301
+ declare function detectPreferredLang(config: TranslationConfig): string;
302
+ /** Lightweight ICU parser that supports nested select/plural structures. */
303
+ declare function parseICU(templateText: string, params?: Record<string, string | number>): string;
304
+ /** Flattens a nested translation object using dot notation keys. */
305
+ declare function flattenTranslations(obj: any, prefix?: string): Record<string, string>;
306
+ /** Converts a signal to an observable while preserving injection context. */
307
+ declare function toObservable<T>(signal: Signal<T>): Observable<T>;
308
+ /** Deeply merges plain objects, replacing non-object values by assignment. */
309
+ declare function deepMerge<T extends object, U extends object>(target: T, source: U): T & U;
310
+ /** Recursively retains only keys that are not already present in the existing object. */
311
+ declare function filterNewKeysDeep<T extends object, U extends object>(bundle: T, existing: U): DeepPartial<T>;
312
+ /** Safely reads a dotted path from a nested object. */
313
+ declare function getNested(obj: any, path: string): string | undefined;
314
+ /** Removes any leading slashes from path-like strings. */
315
+ declare const stripLeadingSep: (s: string) => string;
316
+ /** Normalises the path template configuration to an array form. */
317
+ declare const tempToArray: (template: PathTemplate) => string[];
318
+ /**
319
+ * Detect current build version from injected script names (CSR only).
320
+ * Matches filenames like: main.<hash>.js, runtime.<hash>.js, polyfills.<hash>.js
321
+ */
322
+ declare function detectBuildVersion(): string | null;
323
+
324
+ /** Combined FIFO/LRU cache used to store compiled formatters. */
325
+ declare class FIFOCache<K, V> {
326
+ private max;
327
+ private map;
328
+ get size(): number;
329
+ constructor(max: number);
330
+ set(key: K, value: V): void;
331
+ get(key: K): V | undefined;
332
+ has(key: K): boolean;
333
+ delete(k: K): void;
334
+ clear(): void;
335
+ /** Utility helper for controlled external iteration/manipulation. */
336
+ keys(): IterableIterator<K>;
337
+ /** Iterates cached values without exposing the backing Map. */
338
+ forEach(cb: (value: V, key: K) => void): void;
339
+ /**
340
+ * Delete all entries that match the predicate.
341
+ * Returns the number of deleted entries.
342
+ */
343
+ deleteWhere(predicate: (key: K, value: V) => boolean): number;
344
+ }
345
+
346
+ export { BUILD_VERSION, CLIENT_REQUEST_LANG, FIFOCache, FsTranslationLoader, HttpTranslationLoader, ICU_FORMATTER_TOKEN, PAGE_TRANSLATION_ROOT, TRANSLATION_CONFIG, TRANSLATION_LOADER, TRANSLATION_NAMESPACE, TempToken, TranslationCoreService, TranslationDirective, TranslationPipe, TranslationService, deepMerge, defaultConfig, detectBuildVersion, detectPreferredLang, filterNewKeysDeep, flattenTranslations, getNested, normalizeLangCode, parseICU, provideTranslation, provideTranslationInit, provideTranslationLoader, stripLeadingSep, tempToArray, toObservable };
347
+ export type { CacheEntry, DeepPartial, FormatResult, FsLoaderOptions, FsModuleLike, HttpLoaderOptions, Lang, LazyLoader, MissingTranslationBehavior, Params, PathTemplate, ProvideTranslationInitOptions, TranslationConfig, TranslationContext, TranslationLoader, TranslationLoaderOptions, Translations, nsKey };
@@ -1,64 +0,0 @@
1
- /** Combined FIFO/LRU cache used to store compiled formatters. */
2
- export class FIFOCache {
3
- max;
4
- map = new Map();
5
- get size() {
6
- return this.map.size;
7
- }
8
- constructor(max) {
9
- this.max = max;
10
- }
11
- set(key, value) {
12
- if (this.map.has(key)) {
13
- this.map.delete(key);
14
- }
15
- this.map.set(key, value);
16
- if (this.map.size > this.max) {
17
- const first = this.map.keys().next().value;
18
- if (first) {
19
- this.map.delete(first);
20
- }
21
- }
22
- }
23
- get(key) {
24
- const val = this.map.get(key);
25
- // Refresh recency on hit so frequently used entries stay resident.
26
- if (val !== undefined) {
27
- this.map.delete(key);
28
- this.map.set(key, val);
29
- }
30
- return val;
31
- }
32
- has(key) {
33
- return this.map.has(key);
34
- }
35
- delete(k) {
36
- this.map.delete(k);
37
- }
38
- clear() {
39
- this.map.clear();
40
- }
41
- /** Utility helper for controlled external iteration/manipulation. */
42
- keys() {
43
- return this.map.keys();
44
- }
45
- /** Iterates cached values without exposing the backing Map. */
46
- forEach(cb) {
47
- this.map.forEach((v, k) => cb(v, k));
48
- }
49
- /**
50
- * Delete all entries that match the predicate.
51
- * Returns the number of deleted entries.
52
- */
53
- deleteWhere(predicate) {
54
- let count = 0;
55
- for (const [k, v] of this.map) {
56
- if (predicate(k, v)) {
57
- this.map.delete(k);
58
- count++;
59
- }
60
- }
61
- return count;
62
- }
63
- }
64
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRklGTy5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1hdG9taWMtaTE4bi9zcmMvbGliL0ZJRk8ubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUVBQWlFO0FBQ2pFLE1BQU0sT0FBTyxTQUFTO0lBS0U7SUFKWixHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVEsQ0FBQztJQUM5QixJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxZQUFvQixHQUFXO1FBQVgsUUFBRyxHQUFILEdBQUcsQ0FBUTtJQUFJLENBQUM7SUFDcEMsR0FBRyxDQUFDLEdBQU0sRUFBRSxLQUFRO1FBQ2hCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixDQUFDO1FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQzNDLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBQ0QsR0FBRyxDQUFDLEdBQU07UUFDTixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QixtRUFBbUU7UUFDbkUsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFDRCxHQUFHLENBQUMsR0FBTTtRQUNOLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE1BQU0sQ0FBQyxDQUFJO1FBQ1AsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUNELEtBQUs7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxxRUFBcUU7SUFDckUsSUFBSTtRQUNBLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELE9BQU8sQ0FBQyxFQUE4QjtRQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLFNBQXdDO1FBQ2hELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLEtBQUssTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDNUIsSUFBSSxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixLQUFLLEVBQUUsQ0FBQztZQUNaLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIENvbWJpbmVkIEZJRk8vTFJVIGNhY2hlIHVzZWQgdG8gc3RvcmUgY29tcGlsZWQgZm9ybWF0dGVycy4gKi9cbmV4cG9ydCBjbGFzcyBGSUZPQ2FjaGU8SywgVj4ge1xuICAgIHByaXZhdGUgbWFwID0gbmV3IE1hcDxLLCBWPigpO1xuICAgIGdldCBzaXplKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5zaXplO1xuICAgIH1cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1heDogbnVtYmVyKSB7IH1cbiAgICBzZXQoa2V5OiBLLCB2YWx1ZTogVik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tYXAuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRoaXMubWFwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgaWYgKHRoaXMubWFwLnNpemUgPiB0aGlzLm1heCkge1xuICAgICAgICAgICAgY29uc3QgZmlyc3QgPSB0aGlzLm1hcC5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgICAgICAgICAgaWYgKGZpcnN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXAuZGVsZXRlKGZpcnN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQoa2V5OiBLKTogViB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChrZXkpO1xuICAgICAgICAvLyBSZWZyZXNoIHJlY2VuY3kgb24gaGl0IHNvIGZyZXF1ZW50bHkgdXNlZCBlbnRyaWVzIHN0YXkgcmVzaWRlbnQuXG4gICAgICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5tYXAuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB0aGlzLm1hcC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfVxuICAgIGhhcyhrZXk6IEspOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmhhcyhrZXkpO1xuICAgIH1cbiAgICBkZWxldGUoazogSyk6IHZvaWQge1xuICAgICAgICB0aGlzLm1hcC5kZWxldGUoayk7XG4gICAgfVxuICAgIGNsZWFyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLm1hcC5jbGVhcigpO1xuICAgIH1cblxuICAgIC8qKiBVdGlsaXR5IGhlbHBlciBmb3IgY29udHJvbGxlZCBleHRlcm5hbCBpdGVyYXRpb24vbWFuaXB1bGF0aW9uLiAqL1xuICAgIGtleXMoKTogSXRlcmFibGVJdGVyYXRvcjxLPiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5rZXlzKCk7XG4gICAgfVxuXG4gICAgLyoqIEl0ZXJhdGVzIGNhY2hlZCB2YWx1ZXMgd2l0aG91dCBleHBvc2luZyB0aGUgYmFja2luZyBNYXAuICovXG4gICAgZm9yRWFjaChjYjogKHZhbHVlOiBWLCBrZXk6IEspID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tYXAuZm9yRWFjaCgodiwgaykgPT4gY2IodiwgaykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBhbGwgZW50cmllcyB0aGF0IG1hdGNoIHRoZSBwcmVkaWNhdGUuXG4gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRlbGV0ZWQgZW50cmllcy5cbiAgICAgKi9cbiAgICBkZWxldGVXaGVyZShwcmVkaWNhdGU6IChrZXk6IEssIHZhbHVlOiBWKSA9PiBib29sZWFuKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBbaywgdl0gb2YgdGhpcy5tYXApIHtcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoaywgdikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1hcC5kZWxldGUoayk7XG4gICAgICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgfVxufVxuIl19
@@ -1,18 +0,0 @@
1
- import { inject, Pipe } from "@angular/core";
2
- import { TranslationService } from "./translation.service";
3
- import * as i0 from "@angular/core";
4
- /** Template helper that proxies lookups to `TranslationService.t`. */
5
- export class TranslationPipe {
6
- service = inject(TranslationService);
7
- /** Formats the translation identified by `key` using the optional params. */
8
- transform(key, params) {
9
- return this.service.t(key, params);
10
- }
11
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
12
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, isStandalone: true, name: "t", pure: false });
13
- }
14
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, decorators: [{
15
- type: Pipe,
16
- args: [{ name: 't', standalone: true, pure: false }]
17
- }] });
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnBpcGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXRvbWljLWkxOG4vc3JjL2xpYi90cmFuc2xhdGUucGlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFFNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7O0FBRzNELHNFQUFzRTtBQUN0RSxNQUFNLE9BQU8sZUFBZTtJQUNULE9BQU8sR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN0RCw2RUFBNkU7SUFDN0UsU0FBUyxDQUFDLEdBQVcsRUFBRSxNQUFlO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7d0dBTFUsZUFBZTtzR0FBZixlQUFlOzs0RkFBZixlQUFlO2tCQUYzQixJQUFJO21CQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgUGFyYW1zIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnR5cGVcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9uU2VydmljZSB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLnNlcnZpY2VcIjtcblxuQFBpcGUoeyBuYW1lOiAndCcsIHN0YW5kYWxvbmU6IHRydWUsIHB1cmU6IGZhbHNlIH0pXG4vKiogVGVtcGxhdGUgaGVscGVyIHRoYXQgcHJveGllcyBsb29rdXBzIHRvIGBUcmFuc2xhdGlvblNlcnZpY2UudGAuICovXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRpb25QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZSA9IGluamVjdChUcmFuc2xhdGlvblNlcnZpY2UpO1xuICAvKiogRm9ybWF0cyB0aGUgdHJhbnNsYXRpb24gaWRlbnRpZmllZCBieSBga2V5YCB1c2luZyB0aGUgb3B0aW9uYWwgcGFyYW1zLiAqL1xuICB0cmFuc2Zvcm0oa2V5OiBzdHJpbmcsIHBhcmFtcz86IFBhcmFtcyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VydmljZS50KGtleSwgcGFyYW1zKTtcbiAgfVxufVxuIl19
@@ -1,121 +0,0 @@
1
- import { HttpClient } from "@angular/common/http";
2
- import { APP_INITIALIZER, inject, isDevMode, PLATFORM_ID, TransferState, makeStateKey, Optional } from "@angular/core";
3
- import { HttpTranslationLoader } from "./translation.loader.csr";
4
- import { detectPreferredLang } from "./translate.util";
5
- import { isPlatformServer } from "@angular/common";
6
- import { TranslationService } from "./translation.service";
7
- import { TempToken } from "./translate.type";
8
- import { BUILD_VERSION, CLIENT_REQUEST_LANG, PAGE_TRANSLATION_ROOT, TRANSLATION_CONFIG, TRANSLATION_LOADER, TRANSLATION_NAMESPACE } from "./translate.token";
9
- import { FsTranslationLoader } from "./translation.loader.ssr";
10
- export const defaultConfig = {
11
- supportedLangs: ['en'],
12
- fallbackNamespace: 'common',
13
- fallbackLang: '',
14
- i18nRoots: ['i18n'],
15
- pathTemplates: [`${TempToken.Root}/${TempToken.Namespace}/${TempToken.Lang}.json`],
16
- enablePageFallback: false,
17
- missingTranslationBehavior: 'show-key',
18
- langDetectionOrder: ['url', 'clientRequest', 'localStorage', 'browser', 'customLang', 'fallback'],
19
- clientRequestLang: null,
20
- };
21
- const CLIENT_REQUEST_LANG_STATE_KEY = makeStateKey('NGX_I18N_CLIENT_REQUEST_LANG');
22
- function resolveClientRequestLang(platformId, transferState, providedLang) {
23
- const stored = transferState?.get(CLIENT_REQUEST_LANG_STATE_KEY, null);
24
- if (stored)
25
- return stored;
26
- const resolved = providedLang ?? null;
27
- if (resolved && transferState && isPlatformServer(platformId)) {
28
- transferState.set(CLIENT_REQUEST_LANG_STATE_KEY, resolved);
29
- }
30
- return resolved;
31
- }
32
- /** Bootstraps the entire translation infrastructure for an application. */
33
- export function provideTranslationInit(userConfig) {
34
- const debugEnabled = userConfig?.debug ?? isDevMode();
35
- const baseConfig = { ...defaultConfig, ...(userConfig ?? {}), fallbackLang: defaultConfig.supportedLangs[0], debug: debugEnabled };
36
- if (debugEnabled) {
37
- console.info('[ngx-atomic-i18n] Debug logging is enabled.');
38
- }
39
- return [
40
- {
41
- provide: TRANSLATION_CONFIG,
42
- useFactory: (platformId, transferState, clientRequestLang) => {
43
- const requestLang = resolveClientRequestLang(platformId, transferState, clientRequestLang ?? baseConfig.clientRequestLang ?? null);
44
- const finalConfig = { ...baseConfig, clientRequestLang: requestLang };
45
- const preferredLang = detectPreferredLang(finalConfig);
46
- return { ...finalConfig, customLang: preferredLang };
47
- },
48
- deps: [PLATFORM_ID, [new Optional(), TransferState], [new Optional(), CLIENT_REQUEST_LANG]],
49
- },
50
- {
51
- provide: BUILD_VERSION,
52
- useValue: userConfig?.buildVersion ?? null,
53
- },
54
- ...provideTranslationLoader(baseConfig),
55
- ...provideTranslation(baseConfig.fallbackNamespace),
56
- {
57
- provide: APP_INITIALIZER,
58
- useFactory: (ts) => {
59
- return async () => {
60
- const preload = baseConfig.preloadNamespaces;
61
- if (preload?.length) {
62
- await ts.preloadNamespaces(preload, ts.currentLang);
63
- }
64
- ts.setLang(ts.currentLang);
65
- };
66
- },
67
- deps: [TranslationService],
68
- multi: true,
69
- },
70
- ];
71
- }
72
- /** Provides the component-scoped namespace injection for component-registered service.
73
- * @param namespace The namespace owned by the component.
74
- * @param isPage Whether the component is a top-level page (defaults to false).
75
- */
76
- export function provideTranslation(namespace, isPage = false) {
77
- return [
78
- {
79
- provide: TRANSLATION_NAMESPACE,
80
- useValue: namespace,
81
- },
82
- TranslationService,
83
- ...(isPage ? [{
84
- provide: PAGE_TRANSLATION_ROOT,
85
- useValue: true,
86
- }] : []),
87
- ];
88
- }
89
- /** Configures the runtime translation loader for CSR or SSR environments. */
90
- export function provideTranslationLoader(config) {
91
- return [
92
- {
93
- provide: TRANSLATION_LOADER,
94
- useFactory: (platformId) => {
95
- const options = config.loader ?? {};
96
- const finalPathTemplates = config.pathTemplates ?? defaultConfig.pathTemplates;
97
- const isSSR = options.forceMode === 'ssr' || (options.forceMode !== 'csr' && isPlatformServer(platformId));
98
- if (isSSR) {
99
- const nodeProcess = globalThis.process;
100
- const baseDir = options.fsOptions?.baseDir ??
101
- (typeof nodeProcess?.cwd === 'function' ? nodeProcess.cwd() : '');
102
- const assetPath = options.fsOptions?.assetPath ?? (isDevMode() ? 'src/assets' : 'dist/browser/assets');
103
- return options.ssrLoader?.()
104
- ?? new FsTranslationLoader({
105
- baseDir,
106
- assetPath,
107
- resolvePaths: options.fsOptions?.resolvePaths,
108
- fsModule: options.fsOptions?.fsModule
109
- }, finalPathTemplates);
110
- }
111
- const http = inject(HttpClient);
112
- return options.csrLoader?.(http)
113
- ?? new HttpTranslationLoader(http, {
114
- baseUrl: options.httpOptions?.baseUrl ?? '/assets',
115
- }, finalPathTemplates);
116
- },
117
- deps: [PLATFORM_ID],
118
- }
119
- ];
120
- }
121
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWF0b21pYy1pMThuL3NyYy9saWIvdHJhbnNsYXRlLnByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFZLGFBQWEsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pJLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzNELE9BQU8sRUFBRSxTQUFTLEVBQWtFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0csT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdKLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBUy9ELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBc0I7SUFDOUMsY0FBYyxFQUFFLENBQUMsSUFBSSxDQUFDO0lBQ3RCLGlCQUFpQixFQUFFLFFBQVE7SUFDM0IsWUFBWSxFQUFFLEVBQUU7SUFDaEIsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ25CLGFBQWEsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxJQUFJLE9B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TyxDQUFDLFNBQVMsRUFBRSxPQUFPO3dCQUMxQixDQUFDLE9BQU8sV0FBVyxFQUFFLEdBQUcsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3BFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQztvQkFDdkcsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUU7MkJBQ3ZCLElBQUksbUJBQW1CLENBQUM7NEJBQ3pCLE9BQU87NEJBQ1AsU0FBUzs0QkFDVCxZQUFZLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxZQUFZOzRCQUM3QyxRQUFRLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxRQUFRO3lCQUN0QyxFQUFFLGtCQUFrQixDQUFDLENBQUM7Z0JBQzNCLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUNoQyxPQUFPLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUM7dUJBQzNCLElBQUkscUJBQXFCLENBQUMsSUFBSSxFQUFFO3dCQUNqQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksU0FBUztxQkFDbkQsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1lBQzNCLENBQUM7WUFDRCxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUM7U0FDcEI7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7IEFQUF9JTklUSUFMSVpFUiwgaW5qZWN0LCBpc0Rldk1vZGUsIFBMQVRGT1JNX0lELCBQcm92aWRlciwgVHJhbnNmZXJTdGF0ZSwgbWFrZVN0YXRlS2V5LCBPcHRpb25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBIdHRwVHJhbnNsYXRpb25Mb2FkZXIgfSBmcm9tIFwiLi90cmFuc2xhdGlvbi5sb2FkZXIuY3NyXCI7XG5pbXBvcnQgeyBkZXRlY3RQcmVmZXJyZWRMYW5nIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnV0aWxcIjtcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi90cmFuc2xhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBUZW1wVG9rZW4sIFRyYW5zbGF0aW9uQ29uZmlnLCBUcmFuc2xhdGlvbkxvYWRlciwgVHJhbnNsYXRpb25Mb2FkZXJPcHRpb25zIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnR5cGVcIjtcbmltcG9ydCB7IEJVSUxEX1ZFUlNJT04sIENMSUVOVF9SRVFVRVNUX0xBTkcsIFBBR0VfVFJBTlNMQVRJT05fUk9PVCwgVFJBTlNMQVRJT05fQ09ORklHLCBUUkFOU0xBVElPTl9MT0FERVIsIFRSQU5TTEFUSU9OX05BTUVTUEFDRSB9IGZyb20gXCIuL3RyYW5zbGF0ZS50b2tlblwiO1xuaW1wb3J0IHsgRnNUcmFuc2xhdGlvbkxvYWRlciB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLmxvYWRlci5zc3JcIjtcblxuZXhwb3J0IHR5cGUgUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMgPVxuICBQYXJ0aWFsPFRyYW5zbGF0aW9uQ29uZmlnPiAmIHtcbiAgICBsb2FkZXI/OiBUcmFuc2xhdGlvbkxvYWRlck9wdGlvbnM7XG4gICAgLyoqIE9wdGlvbmFsIGdsb2JhbCBidWlsZCB2ZXJzaW9uIGZvciBTU1IvQ1NSIHRvIGFsaWduIGNhY2hlcyAqL1xuICAgIGJ1aWxkVmVyc2lvbj86IHN0cmluZyB8IG51bGw7XG4gIH07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29uZmlnOiBUcmFuc2xhdGlvbkNvbmZpZyA9IHtcbiAgc3VwcG9ydGVkTGFuZ3M6IFsnZW4nXSxcbiAgZmFsbGJhY2tOYW1lc3BhY2U6ICdjb21tb24nLFxuICBmYWxsYmFja0xhbmc6ICcnLFxuICBpMThuUm9vdHM6IFsnaTE4biddLFxuICBwYXRoVGVtcGxhdGVzOiBbYCR7VGVtcFRva2VuLlJvb3R9LyR7VGVtcFRva2VuLk5hbWVzcGFjZX0vJHtUZW1wVG9rZW4uTGFuZ30uanNvbmBdLFxuICBlbmFibGVQYWdlRmFsbGJhY2s6IGZhbHNlLFxuICBtaXNzaW5nVHJhbnNsYXRpb25CZWhhdmlvcjogJ3Nob3cta2V5JyxcbiAgbGFuZ0RldGVjdGlvbk9yZGVyOiBbJ3VybCcsICdjbGllbnRSZXF1ZXN0JywgJ2xvY2FsU3RvcmFnZScsICdicm93c2VyJywgJ2N1c3RvbUxhbmcnLCAnZmFsbGJhY2snXSxcbiAgY2xpZW50UmVxdWVzdExhbmc6IG51bGwsXG59O1xuXG5jb25zdCBDTElFTlRfUkVRVUVTVF9MQU5HX1NUQVRFX0tFWSA9IG1ha2VTdGF0ZUtleTxzdHJpbmcgfCBudWxsPignTkdYX0kxOE5fQ0xJRU5UX1JFUVVFU1RfTEFORycpO1xuXG5mdW5jdGlvbiByZXNvbHZlQ2xpZW50UmVxdWVzdExhbmcoXG4gIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgdHJhbnNmZXJTdGF0ZTogVHJhbnNmZXJTdGF0ZSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIHByb3ZpZGVkTGFuZzogc3RyaW5nIHwgbnVsbFxuKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHN0b3JlZCA9IHRyYW5zZmVyU3RhdGU/LmdldChDTElFTlRfUkVRVUVTVF9MQU5HX1NUQVRFX0tFWSwgbnVsbCk7XG4gIGlmIChzdG9yZWQpIHJldHVybiBzdG9yZWQ7XG5cbiAgY29uc3QgcmVzb2x2ZWQgPSBwcm92aWRlZExhbmcgPz8gbnVsbDtcbiAgaWYgKHJlc29sdmVkICYmIHRyYW5zZmVyU3RhdGUgJiYgaXNQbGF0Zm9ybVNlcnZlcihwbGF0Zm9ybUlkKSkge1xuICAgIHRyYW5zZmVyU3RhdGUuc2V0KENMSUVOVF9SRVFVRVNUX0xBTkdfU1RBVEVfS0VZLCByZXNvbHZlZCk7XG4gIH1cbiAgcmV0dXJuIHJlc29sdmVkO1xufVxuLyoqIEJvb3RzdHJhcHMgdGhlIGVudGlyZSB0cmFuc2xhdGlvbiBpbmZyYXN0cnVjdHVyZSBmb3IgYW4gYXBwbGljYXRpb24uICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVRyYW5zbGF0aW9uSW5pdCh1c2VyQ29uZmlnPzogUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMpOiBQcm92aWRlcltdIHtcbiAgY29uc3QgZGVidWdFbmFibGVkID0gdXNlckNvbmZpZz8uZGVidWcgPz8gaXNEZXZNb2RlKCk7XG4gIGNvbnN0IGJhc2VDb25maWcgPSB7IC4uLmRlZmF1bHRDb25maWcsIC4uLih1c2VyQ29uZmlnID8/IHt9KSwgZmFsbGJhY2tMYW5nOiBkZWZhdWx0Q29uZmlnLnN1cHBvcnRlZExhbmdzWzBdLCBkZWJ1ZzogZGVidWdFbmFibGVkIH0gYXMgVHJhbnNsYXRpb25Db25maWc7XG4gIGlmIChkZWJ1Z0VuYWJsZWQpIHtcbiAgICBjb25zb2xlLmluZm8oJ1tuZ3gtYXRvbWljLWkxOG5dIERlYnVnIGxvZ2dpbmcgaXMgZW5hYmxlZC4nKTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IFRSQU5TTEFUSU9OX0NPTkZJRyxcbiAgICAgIHVzZUZhY3Rvcnk6IChwbGF0Zm9ybUlkOiBPYmplY3QsIHRyYW5zZmVyU3RhdGU6IFRyYW5zZmVyU3RhdGUgfCBudWxsIHwgdW5kZWZpbmVkLCBjbGllbnRSZXF1ZXN0TGFuZzogc3RyaW5nIHwgbnVsbCkgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0TGFuZyA9IHJlc29sdmVDbGllbnRSZXF1ZXN0TGFuZyhwbGF0Zm9ybUlkLCB0cmFuc2ZlclN0YXRlLCBjbGllbnRSZXF1ZXN0TGFuZyA/PyBiYXNlQ29uZmlnLmNsaWVudFJlcXVlc3RMYW5nID8/IG51bGwpO1xuICAgICAgICBjb25zdCBmaW5hbENvbmZpZyA9IHsgLi4uYmFzZUNvbmZpZywgY2xpZW50UmVxdWVzdExhbmc6IHJlcXVlc3RMYW5nIH0gYXMgVHJhbnNsYXRpb25Db25maWc7XG4gICAgICAgIGNvbnN0IHByZWZlcnJlZExhbmcgPSBkZXRlY3RQcmVmZXJyZWRMYW5nKGZpbmFsQ29uZmlnKTtcbiAgICAgICAgcmV0dXJuIHsgLi4uZmluYWxDb25maWcsIGN1c3RvbUxhbmc6IHByZWZlcnJlZExhbmcgfTtcbiAgICAgIH0sXG4gICAgICBkZXBzOiBbUExBVEZPUk1fSUQsIFtuZXcgT3B0aW9uYWwoKSwgVHJhbnNmZXJTdGF0ZV0sIFtuZXcgT3B0aW9uYWwoKSwgQ0xJRU5UX1JFUVVFU1RfTEFOR11dLFxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogQlVJTERfVkVSU0lPTixcbiAgICAgIHVzZVZhbHVlOiB1c2VyQ29uZmlnPy5idWlsZFZlcnNpb24gPz8gbnVsbCxcbiAgICB9LFxuICAgIC4uLnByb3ZpZGVUcmFuc2xhdGlvbkxvYWRlcihiYXNlQ29uZmlnKSxcbiAgICAuLi5wcm92aWRlVHJhbnNsYXRpb24oYmFzZUNvbmZpZy5mYWxsYmFja05hbWVzcGFjZSksXG4gICAge1xuICAgICAgcHJvdmlkZTogQVBQX0lOSVRJQUxJWkVSLFxuICAgICAgdXNlRmFjdG9yeTogKHRzOiBUcmFuc2xhdGlvblNlcnZpY2UpID0+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBwcmVsb2FkID0gYmFzZUNvbmZpZy5wcmVsb2FkTmFtZXNwYWNlcztcbiAgICAgICAgICBpZiAocHJlbG9hZD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICBhd2FpdCB0cy5wcmVsb2FkTmFtZXNwYWNlcyhwcmVsb2FkLCB0cy5jdXJyZW50TGFuZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRzLnNldExhbmcodHMuY3VycmVudExhbmcpO1xuICAgICAgICB9O1xuICAgICAgfSxcbiAgICAgIGRlcHM6IFtUcmFuc2xhdGlvblNlcnZpY2VdLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXTtcbn1cblxuXG4vKiogUHJvdmlkZXMgdGhlIGNvbXBvbmVudC1zY29wZWQgbmFtZXNwYWNlIGluamVjdGlvbiBmb3IgY29tcG9uZW50LXJlZ2lzdGVyZWQgc2VydmljZS5cbiAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvd25lZCBieSB0aGUgY29tcG9uZW50LlxuICogQHBhcmFtIGlzUGFnZSBXaGV0aGVyIHRoZSBjb21wb25lbnQgaXMgYSB0b3AtbGV2ZWwgcGFnZSAoZGVmYXVsdHMgdG8gZmFsc2UpLlxuKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlVHJhbnNsYXRpb24obmFtZXNwYWNlOiBzdHJpbmcsIGlzUGFnZTogYm9vbGVhbiA9IGZhbHNlKTogUHJvdmlkZXJbXSB7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogVFJBTlNMQVRJT05fTkFNRVNQQUNFLFxuICAgICAgdXNlVmFsdWU6IG5hbWVzcGFjZSxcbiAgICB9LFxuICAgIFRyYW5zbGF0aW9uU2VydmljZSxcbiAgICAuLi4oaXNQYWdlID8gW3tcbiAgICAgIHByb3ZpZGU6IFBBR0VfVFJBTlNMQVRJT05fUk9PVCxcbiAgICAgIHVzZVZhbHVlOiB0cnVlLFxuICAgIH1dIDogW10pLFxuICBdXG59XG5cbi8qKiBDb25maWd1cmVzIHRoZSBydW50aW1lIHRyYW5zbGF0aW9uIGxvYWRlciBmb3IgQ1NSIG9yIFNTUiBlbnZpcm9ubWVudHMuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVRyYW5zbGF0aW9uTG9hZGVyKGNvbmZpZzogUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMpOiBQcm92aWRlcltdIHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBUUkFOU0xBVElPTl9MT0FERVIsXG4gICAgICB1c2VGYWN0b3J5OiAocGxhdGZvcm1JZDogT2JqZWN0KTogVHJhbnNsYXRpb25Mb2FkZXIgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gY29uZmlnLmxvYWRlciA/PyB7fTtcbiAgICAgICAgY29uc3QgZmluYWxQYXRoVGVtcGxhdGVzID0gY29uZmlnLnBhdGhUZW1wbGF0ZXMgPz8gZGVmYXVsdENvbmZpZy5wYXRoVGVtcGxhdGVzO1xuICAgICAgICBjb25zdCBpc1NTUiA9IG9wdGlvbnMuZm9yY2VNb2RlID09PSAnc3NyJyB8fCAob3B0aW9ucy5mb3JjZU1vZGUgIT09ICdjc3InICYmIGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkpO1xuICAgICAgICBpZiAoaXNTU1IpIHtcbiAgICAgICAgICBjb25zdCBub2RlUHJvY2VzcyA9IChnbG9iYWxUaGlzIGFzIGFueSkucHJvY2VzcyBhcyB7IGN3ZD86ICgpID0+IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnN0IGJhc2VEaXIgPVxuICAgICAgICAgICAgb3B0aW9ucy5mc09wdGlvbnM/LmJhc2VEaXIgPz9cbiAgICAgICAgICAgICh0eXBlb2Ygbm9kZVByb2Nlc3M/LmN3ZCA9PT0gJ2Z1bmN0aW9uJyA/IG5vZGVQcm9jZXNzLmN3ZCgpIDogJycpO1xuICAgICAgICAgIGNvbnN0IGFzc2V0UGF0aCA9IG9wdGlvbnMuZnNPcHRpb25zPy5hc3NldFBhdGggPz8gKGlzRGV2TW9kZSgpID8gJ3NyYy9hc3NldHMnIDogJ2Rpc3QvYnJvd3Nlci9hc3NldHMnKTtcbiAgICAgICAgICByZXR1cm4gb3B0aW9ucy5zc3JMb2FkZXI/LigpXG4gICAgICAgICAgICA/PyBuZXcgRnNUcmFuc2xhdGlvbkxvYWRlcih7XG4gICAgICAgICAgICAgIGJhc2VEaXIsXG4gICAgICAgICAgICAgIGFzc2V0UGF0aCxcbiAgICAgICAgICAgICAgcmVzb2x2ZVBhdGhzOiBvcHRpb25zLmZzT3B0aW9ucz8ucmVzb2x2ZVBhdGhzLFxuICAgICAgICAgICAgICBmc01vZHVsZTogb3B0aW9ucy5mc09wdGlvbnM/LmZzTW9kdWxlXG4gICAgICAgICAgICB9LCBmaW5hbFBhdGhUZW1wbGF0ZXMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmNzckxvYWRlcj8uKGh0dHApXG4gICAgICAgICAgPz8gbmV3IEh0dHBUcmFuc2xhdGlvbkxvYWRlcihodHRwLCB7XG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmh0dHBPcHRpb25zPy5iYXNlVXJsID8/ICcvYXNzZXRzJyxcbiAgICAgICAgICB9LCBmaW5hbFBhdGhUZW1wbGF0ZXMpO1xuICAgICAgfSxcbiAgICAgIGRlcHM6IFtQTEFURk9STV9JRF0sXG4gICAgfVxuICBdO1xufVxuIl19
@@ -1,15 +0,0 @@
1
- import { InjectionToken } from "@angular/core";
2
- /** Scoped namespace for translating a component tree (string or array). */
3
- export const TRANSLATION_NAMESPACE = new InjectionToken('TRANSLATION_NAMESPACE');
4
- /** Root configuration describing language support and loader behavior. */
5
- export const TRANSLATION_CONFIG = new InjectionToken('TRANSLATION_CONFIG');
6
- /** Factory used to retrieve translation JSON for a namespace/language tuple. */
7
- export const TRANSLATION_LOADER = new InjectionToken('TRANSLATION_LOADER');
8
- /** Optional build fingerprint appended to namespace cache keys. */
9
- export const BUILD_VERSION = new InjectionToken('BUILD_VERSION');
10
- /** Custom ICU formatter constructor injected by the host app when available. */
11
- export const ICU_FORMATTER_TOKEN = new InjectionToken('ICU_FORMATTER_TOKEN');
12
- export const PAGE_TRANSLATION_ROOT = new InjectionToken('PAGE_TRANSLATION_ROOT');
13
- /** Per-request language captured during SSR and replayed on CSR. */
14
- export const CLIENT_REQUEST_LANG = new InjectionToken('CLIENT_REQUEST_LANG');
15
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWF0b21pYy1pMThuL3NyYy9saWIvdHJhbnNsYXRlLnRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHL0MsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLElBQUksY0FBYyxDQUFTLHVCQUF1QixDQUFDLENBQUM7QUFDekYsMEVBQTBFO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUFvQixvQkFBb0IsQ0FBQyxDQUFDO0FBQzlGLGdGQUFnRjtBQUNoRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLGNBQWMsQ0FBb0Isb0JBQW9CLENBQUMsQ0FBQztBQUM5RixtRUFBbUU7QUFDbkUsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksY0FBYyxDQUFnQixlQUFlLENBQUMsQ0FBQztBQUNoRixnRkFBZ0Y7QUFDaEYsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxjQUFjLENBQU0scUJBQXFCLENBQUMsQ0FBQztBQUVsRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLGNBQWMsQ0FBVSx1QkFBdUIsQ0FBQyxDQUFDO0FBQzFGLG9FQUFvRTtBQUNwRSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLGNBQWMsQ0FBZ0IscUJBQXFCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9uQ29uZmlnLCBUcmFuc2xhdGlvbkxvYWRlciB9IGZyb20gXCIuL3RyYW5zbGF0ZS50eXBlXCI7XG5cbi8qKiBTY29wZWQgbmFtZXNwYWNlIGZvciB0cmFuc2xhdGluZyBhIGNvbXBvbmVudCB0cmVlIChzdHJpbmcgb3IgYXJyYXkpLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TTEFUSU9OX05BTUVTUEFDRSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KCdUUkFOU0xBVElPTl9OQU1FU1BBQ0UnKTtcbi8qKiBSb290IGNvbmZpZ3VyYXRpb24gZGVzY3JpYmluZyBsYW5ndWFnZSBzdXBwb3J0IGFuZCBsb2FkZXIgYmVoYXZpb3IuICovXG5leHBvcnQgY29uc3QgVFJBTlNMQVRJT05fQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPFRyYW5zbGF0aW9uQ29uZmlnPignVFJBTlNMQVRJT05fQ09ORklHJyk7XG4vKiogRmFjdG9yeSB1c2VkIHRvIHJldHJpZXZlIHRyYW5zbGF0aW9uIEpTT04gZm9yIGEgbmFtZXNwYWNlL2xhbmd1YWdlIHR1cGxlLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TTEFUSU9OX0xPQURFUiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxUcmFuc2xhdGlvbkxvYWRlcj4oJ1RSQU5TTEFUSU9OX0xPQURFUicpO1xuLyoqIE9wdGlvbmFsIGJ1aWxkIGZpbmdlcnByaW50IGFwcGVuZGVkIHRvIG5hbWVzcGFjZSBjYWNoZSBrZXlzLiAqL1xuZXhwb3J0IGNvbnN0IEJVSUxEX1ZFUlNJT04gPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nIHwgbnVsbD4oJ0JVSUxEX1ZFUlNJT04nKTtcbi8qKiBDdXN0b20gSUNVIGZvcm1hdHRlciBjb25zdHJ1Y3RvciBpbmplY3RlZCBieSB0aGUgaG9zdCBhcHAgd2hlbiBhdmFpbGFibGUuICovXG5leHBvcnQgY29uc3QgSUNVX0ZPUk1BVFRFUl9UT0tFTiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxhbnk+KCdJQ1VfRk9STUFUVEVSX1RPS0VOJyk7XG5cbmV4cG9ydCBjb25zdCBQQUdFX1RSQU5TTEFUSU9OX1JPT1QgPSBuZXcgSW5qZWN0aW9uVG9rZW48Ym9vbGVhbj4oJ1BBR0VfVFJBTlNMQVRJT05fUk9PVCcpO1xuLyoqIFBlci1yZXF1ZXN0IGxhbmd1YWdlIGNhcHR1cmVkIGR1cmluZyBTU1IgYW5kIHJlcGxheWVkIG9uIENTUi4gKi9cbmV4cG9ydCBjb25zdCBDTElFTlRfUkVRVUVTVF9MQU5HID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZyB8IG51bGw+KCdDTElFTlRfUkVRVUVTVF9MQU5HJyk7XG4iXX0=
@@ -1,10 +0,0 @@
1
- export var TempToken;
2
- (function (TempToken) {
3
- /** Placeholder for the language code inside loader path templates. */
4
- TempToken["Lang"] = "{{lang}}";
5
- /** Placeholder for the namespace inside loader path templates. */
6
- TempToken["Namespace"] = "{{namespace}}";
7
- /** Placeholder for the root folder inside loader path templates. */
8
- TempToken["Root"] = "{{root}}";
9
- })(TempToken || (TempToken = {}));
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnR5cGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXRvbWljLWkxOG4vc3JjL2xpYi90cmFuc2xhdGUudHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1R0EsTUFBTSxDQUFOLElBQVksU0FPWDtBQVBELFdBQVksU0FBUztJQUNuQixzRUFBc0U7SUFDdEUsOEJBQWlCLENBQUE7SUFDakIsa0VBQWtFO0lBQ2xFLHdDQUEyQixDQUFBO0lBQzNCLG9FQUFvRTtJQUNwRSw4QkFBaUIsQ0FBQTtBQUNuQixDQUFDLEVBUFcsU0FBUyxLQUFULFNBQVMsUUFPcEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuXG4vKiogR2xvYmFsIGNvbmZpZ3VyYXRpb24gY29udHJhY3QgdXNlZCBieSB0aGUgdHJhbnNsYXRpb24gc3lzdGVtLiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkNvbmZpZyB7XG4gIHN1cHBvcnRlZExhbmdzOiBzdHJpbmdbXTtcbiAgZmFsbGJhY2tMYW5nOiBzdHJpbmc7XG4gIGkxOG5Sb290czogc3RyaW5nW107XG4gIHBhdGhUZW1wbGF0ZXM6IHN0cmluZ1tdIHwgc3RyaW5nO1xuICBmYWxsYmFja05hbWVzcGFjZTogc3RyaW5nO1xuICBsYW5nRGV0ZWN0aW9uT3JkZXI6ICgnbG9jYWxTdG9yYWdlJyB8ICd1cmwnIHwgJ2Jyb3dzZXInIHwgJ2N1c3RvbUxhbmcnIHwgJ2ZhbGxiYWNrJyB8ICdjbGllbnRSZXF1ZXN0JylbXTtcbiAgLyoqIEVuYWJsZSB2ZXJib3NlIGxvZ2dpbmcuIERlZmF1bHRzIHRvIHRydWUgaW4gZGV2IG1vZGUuICovXG4gIGRlYnVnPzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSB1c2UgICovXG4gIGVuYWJsZVBhZ2VGYWxsYmFjazogYm9vbGVhbjtcbiAgcHJlbG9hZE5hbWVzcGFjZXM/OiBzdHJpbmdbXTtcbiAgY3VzdG9tTGFuZz86ICgoKSA9PiBzdHJpbmcpIHwgc3RyaW5nO1xuICAvKiogTGFuZ3VhZ2UgcGFzc2VkIGZyb20gU1NSIHJlcXVlc3QgYW5kIHJldXNlZCBvbiB0aGUgY2xpZW50LiAqL1xuICBjbGllbnRSZXF1ZXN0TGFuZz86IHN0cmluZyB8IG51bGw7XG4gIG1pc3NpbmdUcmFuc2xhdGlvbkJlaGF2aW9yPzogTWlzc2luZ1RyYW5zbGF0aW9uQmVoYXZpb3I7XG59XG5cbi8qKiBNZXRhZGF0YSBwYXNzZWQgaW50byBjb25zdW1lcnMgdG8gaW5kaWNhdGUgbmFtZXNwYWNlIHJlYWRpbmVzcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNsYXRpb25Db250ZXh0IHtcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XG4gIHJlYWR5PzogU2lnbmFsPGJvb2xlYW4+O1xufVxuXG5leHBvcnQgdHlwZSBMYXp5TG9hZGVyID0gUmVjb3JkPExhbmcsICgpID0+IFByb21pc2U8VHJhbnNsYXRpb25zPj47XG5leHBvcnQgdHlwZSBQYXJhbXMgPSBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuZXhwb3J0IHR5cGUgVHJhbnNsYXRpb25zID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbmV4cG9ydCB0eXBlIExhbmcgPSBzdHJpbmc7XG4vKiogbGFuZzpuYW1lc3BhY2U6dmVyc2lvbiAqL1xuZXhwb3J0IHR5cGUgbnNLZXkgPSBzdHJpbmc7XG4vKipcbiAqIEhvdyB0aGUgdHJhbnNsYXRpb24gc3lzdGVtIHNob3VsZCBiZWhhdmUgd2hlbiBhIHRyYW5zbGF0aW9uIGtleSBpcyBtaXNzaW5nLlxuICpcbiAqIC0gJ3Nob3cta2V5JzogRGlzcGxheSB0aGUga2V5IGl0c2VsZiAoZS5nLiwgYCdtZW51LmFib3V0J2ApIGFzIGEgZmFsbGJhY2suXG4gKiAtICdlbXB0eSc6IFNob3cgYW4gZW1wdHkgc3RyaW5nLiBVc2UgdGhpcyBpZiB5b3UgcHJlZmVyIHVudHJhbnNsYXRlZCB0ZXh0IHRvIGRpc2FwcGVhciBzaWxlbnRseS5cbiAqIC0gJ3Rocm93JzogVGhyb3cgYSBydW50aW1lIGVycm9yLiBSZWNvbW1lbmRlZCBvbmx5IGR1cmluZyBkZXZlbG9wbWVudCBvciB0ZXN0aW5nOyB3aWxsIGJyZWFrIHRoZSBVSSBpZiBub3QgaGFuZGxlZC5cbiAqIC0gc3RyaW5nOiBBbnkgY3VzdG9tIHN0cmluZywgZS5nLiwgJy0tJywgJ2xvYWRpbmcuLi4nLCBldGMuXG4gKi9cbmV4cG9ydCB0eXBlIE1pc3NpbmdUcmFuc2xhdGlvbkJlaGF2aW9yID0gJ3Nob3cta2V5JyB8ICdlbXB0eScgfCAndGhyb3ctZXJyb3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uTG9hZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSBpMThuUm9vdCAgTGlzdCBvZiBiYXNlIGZvbGRlcnMgdG8gbG9vayBmb3IgSlNPTiAob3JkZXJlZCBieSBwcmlvcml0eSlcbiAgICogQHBhcmFtIG5zICAgICAgICBOYW1lc3BhY2UsIGUuZy4gXCJob21lXCIgb3IgXCJhdXRoLWxvZ2luXCJcbiAgICogQHBhcmFtIGxhbmcgICAgICBMYW5ndWFnZSBjb2RlLCBlLmcuIFwiZW5cIiBvciBcInpoLUhhbnRcIlxuICAgKi9cbiAgbG9hZChpMThuUm9vdHM6IHN0cmluZ1tdLCBuYW1lc3BhY2U6IHN0cmluZywgbGFuZzogc3RyaW5nKTogUHJvbWlzZTxUcmFuc2xhdGlvbnM+O1xufVxuXG5leHBvcnQgdHlwZSBGb3JtYXRSZXN1bHQgPSB7IGZvcm1hdChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcgfVxuXG5leHBvcnQgdHlwZSBEZWVwUGFydGlhbDxUPiA9IHtcbiAgW0sgaW4ga2V5b2YgVF0/OiBUW0tdIGV4dGVuZHMgb2JqZWN0ID8gRGVlcFBhcnRpYWw8VFtLXT4gOiBUW0tdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBGc01vZHVsZUxpa2Uge1xuICAvKiogTWluaW1hbCBzdWJzZXQgb2YgTm9kZSdzIGZzIEFQSSBuZWVkZWQgYnkgdGhlIFNTUiBsb2FkZXIuICovXG4gIHJlYWRGaWxlU3luYyhwYXRoOiBzdHJpbmcsIGVuY29kaW5nOiAndXRmOCcpOiBzdHJpbmc7XG4gIHN0YXRTeW5jKHBhdGg6IHN0cmluZyk6IGFueVxufVxuXG4vKiogT3B0aW9ucyB1c2VkIHRvIGN1c3RvbWlzZSB0aGUgU1NSIGZpbGUtc3lzdGVtIGxvYWRlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRnNMb2FkZXJPcHRpb25zIHtcbiAgLyoqICBvbmx5IGZvciBTU1IgLCBlLmcuIHByb2Nlc3MuY3dkKCkgKi9cbiAgYmFzZURpcj86IHN0cmluZztcbiAgLyoqIGUuZy4gJ3Byb2plY3RzL2FwcC9zcmMvYXNzZXRzJyAoZGV2KSBvciAnZGlzdC9hcHAvYnJvd3Nlci9hc3NldHMnICovXG4gIGFzc2V0UGF0aD86IHN0cmluZztcbiAgLyoqIEN1c3RvbSByZXNvbHZlciB0aGF0IHJldHVybnMgYW4gb3JkZXJlZCBsaXN0IG9mIGNhbmRpZGF0ZSBhYnNvbHV0ZSBwYXRocy4gKi9cbiAgcmVzb2x2ZVBhdGhzPzogKGN0eDoge1xuICAgIGJhc2VEaXI6IHN0cmluZztcbiAgICBhc3NldFBhdGg6IHN0cmluZztcbiAgICByb290OiBzdHJpbmc7XG4gICAgbGFuZzogc3RyaW5nO1xuICAgIG5hbWVzcGFjZTogc3RyaW5nO1xuICB9KSA9PiBzdHJpbmdbXTtcbiAgLyoqIEN1c3RvbSBmcyBtb2R1bGUgaW5zdGFuY2UgKHRha2VzIHByZWNlZGVuY2Ugb3ZlciBkeW5hbWljIGltcG9ydHMpLiAqL1xuICBmc01vZHVsZT86IEZzTW9kdWxlTGlrZTtcbiAgY2FjaGVNYXg/OiBudW1iZXI7XG59XG5cbi8qKiBPcHRpb25zIHVzZWQgdG8gY3VzdG9taXNlIHRoZSBIVFRQIGxvYWRlciBpbiBDU1IgZW52aXJvbm1lbnRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwTG9hZGVyT3B0aW9ucyB7XG4gIC8qKiBkZWZhdWx0ICcvYXNzZXRzJyAqL1xuICBiYXNlVXJsPzogc3RyaW5nO1xufVxuXG4vKiogQWdncmVnYXRlIG9wdGlvbnMgZXhwb3NlZCB2aWEgYHByb3ZpZGVUcmFuc2xhdGlvbkluaXRgLiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvYWRlck9wdGlvbnMge1xuICBmb3JjZU1vZGU/OiAnc3NyJyB8ICdjc3InO1xuICBzc3JMb2FkZXI/OiAoKSA9PiBUcmFuc2xhdGlvbkxvYWRlcjsgICAgICAgICAgICAgICAgICAgIC8vIGN1c3RvbSBTU1IgbG9hZGVyXG4gIGNzckxvYWRlcj86IChodHRwOiBIdHRwQ2xpZW50KSA9PiBUcmFuc2xhdGlvbkxvYWRlcjsgICAgLy8gY3VzdG9tIENTUiBsb2FkZXJcbiAgZnNPcHRpb25zPzogRnNMb2FkZXJPcHRpb25zOyAgICAgICAgICAvL29wdGlvbnMgZm9yIEZzVHJhbnNsYXRpb25Mb2FkZXJcbiAgaHR0cE9wdGlvbnM/OiBIdHRwTG9hZGVyT3B0aW9uczsgICAgICAgICAvLyBvcHRpb25zIGZvciBIdHRwVHJhbnNsYXRpb25Mb2FkZXJcbn1cblxuZXhwb3J0IHR5cGUgQ2FjaGVFbnRyeSA9IHsgbXRpbWVNczogbnVtYmVyLCBkYXRhOiBUcmFuc2xhdGlvbnMgfTtcblxuZXhwb3J0IHR5cGUgUGF0aFRlbXBsYXRlID0gc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCBlbnVtIFRlbXBUb2tlbiB7XG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIGxhbmd1YWdlIGNvZGUgaW5zaWRlIGxvYWRlciBwYXRoIHRlbXBsYXRlcy4gKi9cbiAgTGFuZyA9ICd7e2xhbmd9fScsXG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIG5hbWVzcGFjZSBpbnNpZGUgbG9hZGVyIHBhdGggdGVtcGxhdGVzLiAqL1xuICBOYW1lc3BhY2UgPSAne3tuYW1lc3BhY2V9fScsXG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIHJvb3QgZm9sZGVyIGluc2lkZSBsb2FkZXIgcGF0aCB0ZW1wbGF0ZXMuICovXG4gIFJvb3QgPSAne3tyb290fX0nXG59XG4iXX0=