@alauda-fe/common
Version:
Alauda frontend team common codes.
841 lines • 101 kB
JavaScript
import { __decorate, __metadata } from "tslib";
/**
* @packageDocumentation
* @module translate
*/
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable, Optional, isDevMode, } from '@angular/core';
import { IntlMessageFormat } from 'intl-messageformat';
import { get, head, has, isPlainObject, template } from 'lodash-es';
import { Observable, Subject, forkJoin, throwError, EMPTY, catchError, filter, finalize, map, takeUntil, } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { API_GATEWAY } from '../core/constants/constants';
import { ObservableInput, TOKEN_BASE_HREF } from '../core/public-api';
import { isAbsoluteUrl } from '../core/utils/common';
import { parse } from '../core/utils/yaml';
import { FALLBACK_LANGUAGE, LOCALE_PLACEHOLDER_REGEX, LOCALE_STORAGE, } from './constants';
import { getUserLanguage } from './i18n-config';
import { TRANSLATE_OPTIONS, TRANSLATIONS } from './tokens';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
function getLooseLocale(locale) {
return head(locale.split(/[_-]/)) || locale;
}
function hasLodashTemplateFormat(message) {
return /\{\{[^}]+\}\}/.test(message);
}
function hasIcuMessageFormat(message) {
return /\{[^{}]+\}/.test(message);
}
function isTemplatePlainObject(data) {
return isPlainObject(data);
}
/**
* 国际化翻译服务
*
* 特性:
* - 支持多层级翻译优先级(远程翻译 > 手动添加翻译 > 配置翻译)
* - 支持动态语言切换
* - 支持 ICU Message Format 模板插值
* - 支持宽松模式语言匹配
* - 支持异步远程翻译加载
*/
export class TranslateService {
/** 获取支持的语言列表 */
get locales() {
return this.options.locales;
}
/** 获取回退语言 */
get fallbackLocale() {
return this.options.fallbackLocale;
}
constructor(http, baseHref, options, translationList) {
this.http = http;
this.baseHref = baseHref;
/** 翻译添加通知流 */
this.translationsAdded$$ = new Subject();
this.translationsAdded$ = this.translationsAdded$$.asObservable();
/** 组件销毁通知流 */
this.destroy$$ = new Subject();
/** 本地翻译列表(优先级:后加入的优先级更高) */
this.translationsList = [];
/** 远程翻译列表(优先级最高) */
this.remoteTranslationsList = [];
// 初始化语言环境
this.locale = this.getInitialLocale(options);
// 初始化配置选项
this.options = {
locales: [this.locale],
fallbackLocale: FALLBACK_LANGUAGE,
loose: false,
...options,
};
// 初始化翻译列表
this.translationsList = this.getInitializeTranslations(options, translationList);
// 加载远程翻译
this.loadRemoteTranslations(options);
}
/**
* 组件销毁清理
*/
ngOnDestroy() {
this.destroy$$.next();
this.destroy$$.complete();
}
/**
* 获取翻译文本并进行模板插值
* 支持两种模板语法:
* 1. 传统的 {{ key }} 语法,使用 lodash template 处理
* 2. ICU Message Format 语法,使用 IntlMessageFormat 处理
* @param key - 翻译键或翻译对象
* @param data - 模板数据(支持基本类型、Date、对象和数组)
* @returns 翻译后的文本
*
* @example
* ```typescript
* // lodash template 语法
* translate.get('hello', { name: 'World' }) // 模板: "Hello {{ name }}"
*
* // ICU Message Format 语法
* translate.get('itemCount', { count: 5 }) // 模板: "Items: {count, number}"
* translate.get('createdAt', { date: new Date() }) // 模板: "Created: {date, date, short}"
* ```
*/
get(key, data) {
const translation = this.getRaw(key);
if (data == null) {
return translation;
}
try {
// 检测模板类型并使用相应的处理方式
if (hasLodashTemplateFormat(translation)) {
return this.formatLodashTemplate(translation, data);
}
if (hasIcuMessageFormat(translation)) {
return this.formatIcuMessage(translation, data);
}
// 如果没有模板语法,直接返回翻译文本
return translation;
}
catch (error) {
this.handleTemplateError(key, error);
return translation;
}
}
/**
* 获取原始翻译文本模板(不进行插值处理)
* @param key - 翻译键或翻译对象
* @returns 原始翻译模板文本
*/
getRaw(key) {
// 当翻译key是null或undefined时返回空字符串
if (key == null) {
return '';
}
if (typeof key === 'string') {
return this.getTranslationByKey(key);
}
// 当key是Translation对象时,获取当前语言的翻译值
const value = this.getTranslationByObject(key, this.locale);
return value == null ? '' : String(value);
}
/**
* 切换到下一个支持的语言环境
*/
toggleLocale() {
const currentIndex = this.options.locales.indexOf(this.locale);
if (currentIndex === -1) {
this.handleInvalidLocale();
return;
}
const nextIndex = (currentIndex + 1) % this.options.locales.length;
const nextLocale = this.options.locales[nextIndex];
if (nextLocale && nextLocale !== this.locale) {
this.setLocale(nextLocale);
}
}
/**
* 设置当前语言环境
* @param locale - 要设置的语言环境
*/
setLocale(locale) {
if (!this.isValidLocale(locale)) {
if (isDevMode()) {
console.warn(`Invalid locale: ${locale}. Supported locales: ${this.options.locales.join(', ')}`);
}
return;
}
localStorage.setItem(LOCALE_STORAGE, locale);
this.locale = locale;
}
/**
* 手动添加翻译包
* @param translations - 要添加的翻译包
*/
addTranslations(translations) {
if (!translations || typeof translations !== 'object') {
if (isDevMode()) {
console.warn('Invalid translations object provided');
}
return;
}
// 开发模式下检查重复翻译
if (isDevMode() && this.translationsList.length > 0) {
this.checkForDuplicateTranslations(translations);
}
this.translationsList.push(translations);
this.translationsAdded$$.next();
}
/**
* 添加远程翻译包
* @param remoteUrl - 远程翻译文件URL
*/
addRemoteTranslations(remoteUrl) {
if (!remoteUrl) {
return;
}
const normalizedUrl = this.normalizeRemoteUrl(remoteUrl);
const request$ = this.createRemoteTranslationRequest(normalizedUrl);
request$
.pipe(takeUntil(this.destroy$$), finalize(() => {
this.translationsAdded$$.next();
}))
.subscribe({
next: remoteTranslations => {
if (remoteTranslations) {
this.remoteTranslationsList.push(remoteTranslations);
}
},
error: error => {
if (isDevMode()) {
console.error(`Failed to load remote translations from ${remoteUrl}:`, error);
}
},
});
}
fetchTranslation(remoteUrl, locale) {
this.validateFetchTranslationParams(remoteUrl, locale);
const targetUrl = locale
? remoteUrl.replace(LOCALE_PLACEHOLDER_REGEX, locale)
: remoteUrl;
return this.performTranslationRequest(targetUrl);
}
/**
* 获取初始语言环境
*/
getInitialLocale(options) {
return options?.locale || getUserLanguage();
}
/**
* 获取初始翻译列表
*/
getInitializeTranslations(options, translationList) {
return [options?.translations, ...(translationList || [])].filter(Boolean);
}
/**
* 加载远程翻译
*/
loadRemoteTranslations(options) {
if (!options?.remoteUrl)
return;
const urls = Array.isArray(options.remoteUrl)
? options.remoteUrl
: [options.remoteUrl];
urls.forEach(url => this.addRemoteTranslations(url));
}
/**
* 转换模板数据为 ICU 兼容格式
* @param data - 模板数据
* @returns ICU 兼容的数据对象
*/
normalizeIcuData(data) {
if (data == null) {
return {};
}
// 如果是纯对象,直接转换其属性
if (isTemplatePlainObject(data)) {
return this.convertObjectToIcuData(data);
}
// 基本类型、数组、Date等包装为 { value: data }
return { value: this.convertValueToIcuValue(data) };
}
/**
* 转换对象的所有属性为 ICU 兼容值
*/
convertObjectToIcuData(obj) {
const result = {};
for (const [key, value] of Object.entries(obj)) {
if (value != null) {
result[key] = this.convertValueToIcuValue(value);
}
}
return result;
}
/**
* 将单个值转换为 ICU 兼容类型
* 按照 ICU MessageFormat 规范,只支持 string | number | Date
*/
convertValueToIcuValue(value) {
// ICU 原生支持的类型直接返回
if (typeof value === 'string' || typeof value === 'number') {
return value;
}
if (value instanceof Date) {
return value;
}
// 其他类型转为字符串
if (typeof value === 'boolean') {
return String(value);
}
if (Array.isArray(value)) {
// 简单数组转为逗号分隔的字符串
return value.map(item => String(item ?? '')).join(', ');
}
if (value === null) {
return 'null';
}
if (value === undefined) {
return '';
}
// 对象转为 JSON 字符串
if (typeof value === 'object') {
try {
return JSON.stringify(value);
}
catch {
return String(value);
}
}
return String(value);
}
/**
* 处理模板错误
*/
handleTemplateError(key, error) {
const keyStr = typeof key === 'string' ? key : '[object]';
const message = `The translation key '${keyStr}' is missing the necessary parameters.`;
if (isDevMode()) {
console.error(message, error);
}
else {
console.warn(message, error);
}
}
/**
* 使用 lodash template 格式化文本
* @param message - 包含 {{ }} 语法的模板字符串
* @param data - 模板数据
* @returns 格式化后的字符串
*/
formatLodashTemplate(message, data) {
try {
// 将数据标准化为对象格式
const templateData = this.normalizeTemplateData(data);
// 使用 lodash template 处理 {{ }} 语法
const compiled = template(message, {
interpolate: /\{\{(.+?)\}\}/g, // 自定义插值语法为 {{ }}
});
return compiled(templateData);
}
catch (error) {
if (isDevMode()) {
console.warn(`Lodash template formatting failed for "${message}":`, error);
}
// 降级处理:返回原始消息
return message;
}
}
/**
* 标准化模板数据为对象格式
* @param data - 原始模板数据
* @returns 标准化后的对象或数组(为了向后兼容)
*/
normalizeTemplateData(data) {
if (data == null) {
return {};
}
// 如果是纯对象,直接返回
if (isTemplatePlainObject(data)) {
return data;
}
// 这样模板中可以使用 {{ 0 }} 访问第一个元素
return [data];
}
/**
* 使用 ICU message format 格式化文本
*/
formatIcuMessage(message, data) {
try {
// 将数据转换为 ICU 兼容格式
const icuData = this.normalizeIcuData(data);
const messageFormat = new IntlMessageFormat(message, this.locale, undefined, { ignoreTag: true });
return messageFormat.format(icuData);
}
catch (error) {
if (isDevMode()) {
console.warn(`ICU message formatting failed for "${message}":`, error);
}
// 降级处理:返回原始消息
return message;
}
}
/**
* 格式化数字
* @param value - 要格式化的数字
* @param options - 格式化选项
* @returns 格式化后的数字字符串
*
* @example
* formatNumber(1234.56) // "1,234.56"
* formatNumber(0.85, { style: 'percent' }) // "85%"
* formatNumber(1234.56, { style: 'currency', currency: 'CNY' }) // "¥1,234.56"
*/
formatNumber(value, options = {}) {
try {
return new Intl.NumberFormat(this.locale, options).format(value);
}
catch (error) {
if (isDevMode()) {
console.warn(`Number formatting failed for value ${value}:`, error);
}
return value.toString();
}
}
/**
* 格式化货币
* @param value - 要格式化的金额
* @param currency - 货币代码,默认为 CNY
* @param options - 其他格式化选项
* @returns 格式化后的货币字符串
*
* @example
* formatCurrency(1234.56) // en-US: "CN¥1,234.56", zh-CN: "¥1,234.56"
* formatCurrency(1234.56, 'USD') // en-US: "$1,234.56", zh-CN: "US$1,234.56"
*/
formatCurrency(value, currency = 'CNY', options = {}) {
return this.formatNumber(value, {
style: 'currency',
currency,
...options,
});
}
/**
* 格式化百分比
* @param value - 要格式化的值(0.85 表示 85%)
* @param options - 格式化选项
* @returns 格式化后的百分比字符串
*
* @example
* formatPercent(0.85) // "85%"
* formatPercent(0.8567, { minimumFractionDigits: 2 }) // "85.67%"
*/
formatPercent(value, options = {}) {
return this.formatNumber(value, {
style: 'percent',
...options,
});
}
/**
* 格式化日期
* @param date - 要格式化的日期
* @param options - Intl.DateTimeFormatOptions 格式配置
* @returns 格式化后的日期字符串
*
* @example
* formatDate(new Date()) // en-US: "01/01/2025", zh-CN: "2025/01/01"
* formatDate(new Date(), { dateStyle: 'full' }) // "2024年8月20日星期二"
* formatDate(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit' }) // 根据locale格式化
* formatDate(new Date(), { year: 'numeric', month: 'long' }) // "2024年8月"
*/
formatDate(date, options = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}) {
try {
const dateObj = new Date(date);
if (isNaN(dateObj.getTime())) {
throw new Error('Invalid date');
}
return this.formatDateByOptions(dateObj, options);
}
catch (error) {
if (isDevMode()) {
console.warn(`Date formatting failed for date ${date}:`, error);
}
return String(date);
}
}
/**
* 格式化日期和时间
* @param date - 要格式化的日期时间
* @param options - Intl.DateTimeFormatOptions 格式配置
* @returns 格式化后的日期时间字符串
*
* @example
* formatDateTime(new Date()) // en-US: "01/01/2025, 14:30:00", zh-CN: "2025/01/01 14:30:00"
* formatDateTime(new Date(), { dateStyle: 'medium', timeStyle: 'short' }) // "2024年8月20日 14:30"
* formatDateTime(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }) // 根据locale格式化
*/
formatDateTime(date, options = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
}) {
return this.formatDate(date, options);
}
formatRelativeTime(value, unitOrOptions, options = { numeric: 'auto' }) {
try {
let finalValue;
let finalUnit;
let finalOptions;
if (value instanceof Date) {
// 自动计算时间差和单位
const { value: calculatedValue, unit: calculatedUnit } = this.calculateRelativeTime(value);
finalValue = calculatedValue;
finalUnit = calculatedUnit;
finalOptions =
unitOrOptions || options;
}
else {
// 使用提供的数值和单位
finalValue = value;
finalUnit = unitOrOptions;
finalOptions = options;
}
return new Intl.RelativeTimeFormat(this.locale, finalOptions).format(finalValue, finalUnit);
}
catch (error) {
if (isDevMode()) {
console.warn(`Relative time formatting failed for ${value}:`, error);
}
return value instanceof Date
? value.toLocaleString(this.locale)
: `${value}`;
}
}
/**
* 根据日期计算相对时间差值和最合适的单位
* @param date - 目标日期
* @returns 包含时间差值和单位的对象
*/
calculateRelativeTime(date) {
const now = new Date();
const diffMs = date.getTime() - now.getTime();
const absDiffMs = Math.abs(diffMs);
// 时间单位阈值(毫秒)
const MINUTE_MS = 60 * 1000;
const HOUR_MS = 60 * MINUTE_MS;
const DAY_MS = 24 * HOUR_MS;
// 根据时间差选择合适的单位,最大单位为day
if (absDiffMs >= DAY_MS) {
return {
value: Math.round(diffMs / DAY_MS),
unit: 'day',
};
}
if (absDiffMs >= HOUR_MS) {
return {
value: Math.round(diffMs / HOUR_MS),
unit: 'hour',
};
}
if (absDiffMs >= MINUTE_MS) {
return {
value: Math.round(diffMs / MINUTE_MS),
unit: 'minute',
};
}
return {
value: Math.round(diffMs / 1000),
unit: 'second',
};
}
/**
* 根据日期格式配置格式化日期
* 使用标准 Intl.DateTimeFormatOptions 确保格式可预测性
*/
formatDateByOptions(date, options) {
try {
return new Intl.DateTimeFormat(this.locale, options).format(date);
}
catch (error) {
if (isDevMode()) {
console.warn(`Date formatting failed:`, error);
}
return date.toISOString();
}
}
/**
* 处理无效语言环境
*/
handleInvalidLocale() {
if (isDevMode()) {
throw new TypeError('`locales` has not been initialized correctly');
}
}
/**
* 验证语言环境是否有效
*/
isValidLocale(locale) {
return this.options.locales.includes(locale);
}
/**
* 检查重复翻译(开发模式)
*/
checkForDuplicateTranslations(newTranslations) {
for (const existingTranslations of this.translationsList) {
Object.keys(newTranslations).forEach(locale => {
if (existingTranslations[locale]) {
this.compareTranslationKeys(locale, newTranslations[locale], existingTranslations[locale]);
}
});
}
}
/**
* 标准化远程URL
*/
normalizeRemoteUrl(remoteUrl) {
// 清理URL(移除hash片段)
remoteUrl = head(remoteUrl.split(/#/)) || remoteUrl;
const isAbsolute = isAbsoluteUrl(remoteUrl);
const isApiGateWayRequest = remoteUrl.startsWith(API_GATEWAY);
// 开发模式下进行URL验证
if (isDevMode()) {
this.validateRemoteUrl(remoteUrl, isAbsolute);
}
// 相对URL转换为绝对URL
if (!isAbsolute && !isApiGateWayRequest) {
const baseUrl = this.baseHref.endsWith('/')
? this.baseHref
: `${this.baseHref}/`;
return `${baseUrl}${remoteUrl}`;
}
return remoteUrl;
}
/**
* 验证远程URL(开发模式)
*/
validateRemoteUrl(remoteUrl, isAbsolute) {
if (!isAbsolute && (!this.baseHref || !isAbsoluteUrl(this.baseHref))) {
throw new TypeError('absolute base href is required for relative remote url');
}
if (remoteUrl.split('?')[0].includes('./')) {
throw new TypeError('do not use any dot with slash for relative url which should always base from base href');
}
}
/**
* 创建远程翻译请求
*/
createRemoteTranslationRequest(normalizedUrl) {
if (LOCALE_PLACEHOLDER_REGEX.test(normalizedUrl)) {
return this.createMultiLocaleRequest(normalizedUrl);
}
return this.createSingleLocaleRequest(normalizedUrl);
}
/**
* 创建多语言请求
*/
createMultiLocaleRequest(urlTemplate) {
const requests = this.options.locales.map(locale => this.fetchTranslation(urlTemplate, locale).pipe(catchError(error => {
if (this.options.loose) {
const looseLocale = getLooseLocale(locale);
if (looseLocale !== locale &&
!this.options.locales.includes(looseLocale)) {
return this.fetchTranslation(urlTemplate, looseLocale);
}
}
return isDevMode() ? throwError(() => error) : EMPTY;
}), filter(isPlainObject), map((translation) => ({ [locale]: translation }))));
return forkJoin(requests).pipe(map(results => results.reduce((acc, curr) => Object.assign(acc, curr), {})));
}
/**
* 创建单语言请求
*/
createSingleLocaleRequest(url) {
return this.performTranslationRequest(url).pipe(catchError(error => (isDevMode() ? throwError(() => error) : EMPTY)));
}
/**
* 执行翻译请求
*/
performTranslationRequest(url) {
const isJSON = url.endsWith('.json');
const isApiGateWayRequest = url.startsWith(API_GATEWAY);
const responseType = isJSON ? 'json' : 'text';
if (isApiGateWayRequest) {
return this.http
.request('GET', url, { responseType })
.pipe(map(body => (isJSON ? body : parse(body))));
}
return ajax({ url, responseType }).pipe(map(({ response }) => (isJSON ? response : parse(response))));
}
/**
* 验证fetchTranslation参数
*/
validateFetchTranslationParams(remoteUrl, locale) {
if (isDevMode() && LOCALE_PLACEHOLDER_REGEX.test(remoteUrl) && !locale) {
throw new TypeError('`locale` is required since the provided remote url contains locale placeholder');
}
}
/**
* 通过键查找翻译文本
*/
getTranslationByKey(key, locale = this.locale) {
// 1) 精确匹配当前 locale
let value = this.findInAllTranslations(key, locale);
// 2) 宽松匹配当前 locale(如 zh-CN -> zh)
if (value === undefined && this.options.loose) {
const loose = getLooseLocale(locale);
if (loose !== locale) {
value = this.findInAllTranslations(key, loose);
}
}
// 3) 回退到 fallbackLocale
if (value === undefined && locale !== this.options.fallbackLocale) {
const fb = this.options.fallbackLocale;
value = this.findInAllTranslations(key, fb);
// 4) 宽松匹配回退 locale
if (value === undefined && this.options.loose) {
const fbLoose = getLooseLocale(fb);
if (fbLoose !== fb) {
value = this.findInAllTranslations(key, fbLoose);
}
}
}
return value ?? key;
}
/**
* 在所有翻译源中查找键值
*/
findInAllTranslations(key, locale) {
// 远程翻译优先级更高
return (this.findInTranslationsList(key, locale, this.remoteTranslationsList) ??
this.findInTranslationsList(key, locale, this.translationsList));
}
/**
* 在翻译列表中查找键值
*/
findInTranslationsList(key, locale, translationsList) {
if (!translationsList?.length)
return undefined;
// 后加入的优先级更高
for (let i = translationsList.length - 1; i >= 0; i--) {
const value = this.findInTranslation(key, locale, translationsList[i]);
if (value !== undefined)
return value;
}
return undefined;
}
/**
* 在单个翻译对象中查找键值
*/
findInTranslation(key, locale, translations) {
const localeData = translations[locale];
if (!localeData)
return undefined;
const value = get(localeData, key);
if (value !== undefined) {
this.validateTranslationValue(value, locale, key);
return value == null ? '' : String(value);
}
return undefined;
}
/**
* 从Translation对象中获取翻译值(支持宽松匹配和回退逻辑)
*/
getTranslationByObject(source, locale = this.locale) {
if (!source)
return undefined;
// 1) 精确匹配当前 locale
if (has(source, locale)) {
return source[locale];
}
// 2) 宽松匹配当前 locale(如 zh-CN -> zh)
if (this.options.loose) {
const loose = getLooseLocale(locale);
if (loose !== locale && has(source, loose)) {
return source[loose];
}
}
// 3) 回退到 fallbackLocale
const fb = this.options.fallbackLocale;
if (fb !== locale && has(source, fb)) {
return source[fb];
}
// 4) 宽松匹配回退 locale
if (this.options.loose) {
const fbLoose = getLooseLocale(fb);
if (fbLoose !== fb && has(source, fbLoose)) {
return source[fbLoose];
}
}
return undefined;
}
/**
* 验证翻译值(开发模式)
*/
validateTranslationValue(value, locale, key) {
if (isDevMode() &&
typeof value === 'object' &&
typeof get(value, Symbol.toPrimitive) !== 'function') {
console.warn(`The translation for locale: \`${locale}\` and key:\`${key}\` is an object, which could be unexpected`);
}
}
/**
* 比较翻译键(开发模式下检查重复)
*/
compareTranslationKeys(locale, translation, prevTranslation, path = []) {
if (translation == null || prevTranslation == null) {
return;
}
Object.entries(translation).forEach(([key, value]) => {
if (!has(prevTranslation, key)) {
return;
}
const prevValue = prevTranslation[key];
const valueIsPlainObject = isPlainObject(value);
const prevValueIsPlainObject = isPlainObject(prevValue);
if (valueIsPlainObject && prevValueIsPlainObject) {
this.compareTranslationKeys(locale, value, prevValue, [...path, key]);
return;
}
if (!valueIsPlainObject && !prevValueIsPlainObject) {
const outputPath = [...path, key].join(' -> ');
if (value === prevValue) {
console.warn(`The customized translation for locale: \`${locale}\` and path: \`${outputPath}\` is duplicated with the other translation, please remove it in your translation file.`);
}
else {
console.warn(`Two keys that the locale is \`${locale}\` and the path is \`${outputPath}\` are same, but their values are not equal, please remove one of them or change one of the keys.`);
}
}
});
}
static { this.ɵfac = function TranslateService_Factory(t) { return new (t || TranslateService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(TOKEN_BASE_HREF), i0.ɵɵinject(TRANSLATE_OPTIONS, 8), i0.ɵɵinject(TRANSLATIONS, 8)); }; }
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TranslateService, factory: TranslateService.ɵfac, providedIn: 'root' }); }
}
__decorate([
ObservableInput(),
__metadata("design:type", Observable)
], TranslateService.prototype, "locale$", void 0);
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TranslateService, [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
type: Inject,
args: [TOKEN_BASE_HREF]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [TRANSLATE_OPTIONS]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [TRANSLATIONS]
}] }], { locale$: [] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvdHJhbnNsYXRlL3RyYW5zbGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUNMLE1BQU0sRUFDTixVQUFVLEVBRVYsUUFBUSxFQUNSLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRSxPQUFPLEVBQ0wsVUFBVSxFQUNWLE9BQU8sRUFDUCxRQUFRLEVBQ1IsVUFBVSxFQUNWLEtBQUssRUFDTCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFFBQVEsRUFDUixHQUFHLEVBQ0gsU0FBUyxHQUNWLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTNDLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsd0JBQXdCLEVBQ3hCLGNBQWMsR0FDZixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZ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