Fuente publicada
Descargar fuente ZIP
CH-J Tools
Busque directorios y archivos para obtener una versión de aplicación específica.
CH-J / Server Manager
1704 archivos
0.1.2-beta
Añadido: · Construido:
1
"use strict";3
// Core UI translations. The texts live in data files (i18n/core/<language>.json) and the4
// list of languages in i18n/languages.json, so a language is added without code changes.5
// The Rust Core injects both into the window before this script runs; Node tests read the files.6
(function exposeI18n(root, factory) {7
const api = factory();8
if (typeof module === "object" && module.exports) module.exports = api;9
else {10
root.CHJ_I18N = api;11
root.chjI18n = api.createI18n(api.defaultLanguage);12
}13
})(typeof globalThis !== "undefined" ? globalThis : this, () => {14
function loadData() {15
const injected = globalThis.__CHJ_I18N__;16
if (injected && injected.catalogs && injected.catalogs.core) return { manifest: injected.manifest, catalogs: injected.catalogs.core };17
if (typeof require === "function" && typeof __dirname === "string") {18
const fs = require("fs"), path = require("path"), dir = path.join(__dirname, "i18n");19
const manifest = JSON.parse(fs.readFileSync(path.join(dir, "languages.json"), "utf8"));20
const catalogs = {};21
for (const language of manifest.languages) {22
const file = path.join(dir, "core", `${language.code}.json`);23
if (fs.existsSync(file)) catalogs[language.code] = JSON.parse(fs.readFileSync(file, "utf8"));24
}25
return { manifest, catalogs };26
}27
return { manifest: { defaultLanguage: "cs", fallbackLanguage: "en", languages: [] }, catalogs: {} };28
}30
const { manifest, catalogs } = loadData();31
// The main window receives catalogs only for its language chain; `manifest.available` lists every language with a32
// catalog in the Core, and `addCatalogs` adds one when the user switches to it.33
const available = Array.isArray(manifest.available) ? manifest.available : null;34
const languages = Object.freeze((manifest.languages || []).filter((entry) => (available ? available.includes(entry.code) : catalogs[entry.code])).map((entry) => Object.freeze({ ...entry })));35
const known = (code) => Boolean(catalogs[code]) || Boolean(available && available.includes(code));36
const defaultLanguage = known(manifest.defaultLanguage) ? manifest.defaultLanguage : (languages[0]?.code || "cs");37
const sourceLanguage = known("cs") ? "cs" : defaultLanguage;38
const localeByLanguage = Object.freeze(Object.fromEntries(languages.map((entry) => [entry.code, entry.locale || entry.code])));39
const supportedLanguages = Object.freeze(languages.map((entry) => entry.code));41
const entryByLanguage = Object.freeze(Object.fromEntries(languages.map((entry) => [entry.code, entry])));43
// Exact code first (zh-tw, de-at), then the base language (fr-CA → fr).44
function normalizeLanguage(value) {45
const language = String(value || "").toLowerCase().replace(/_/g, "-");46
if (supportedLanguages.includes(language)) return language;47
const base = language.split("-")[0];48
return supportedLanguages.includes(base) ? base : defaultLanguage;49
}51
// Lookup order: the language, its parent (regional variants), the fallback language, Czech.52
function lookupChain(language) {53
const parent = entryByLanguage[language]?.parent || (language.includes("-") ? language.split("-")[0] : null);54
return [...new Set([language, parent, manifest.fallbackLanguage, sourceLanguage].filter(Boolean))];55
}57
function direction(language) {58
return entryByLanguage[language]?.dir === "rtl" ? "rtl" : "ltr";59
}61
function interpolate(template, values = {}) {62
return String(template).replace(/\{([A-Za-z0-9_]+)\}/g, (match, key) => (63
Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match64
));65
}67
function createI18n(initialLanguage = defaultLanguage) {68
let language = normalizeLanguage(initialLanguage);69
const staticText = new WeakMap();70
return Object.freeze({71
apply(rootNode = document) {72
// Text the application has set itself is not the static translation; its renderers refresh it.73
rootNode.querySelectorAll("[data-i18n]").forEach((element) => {74
if (staticText.has(element) && element.textContent !== staticText.get(element)) return;75
const text = this.t(element.dataset.i18n);76
element.textContent = text;77
staticText.set(element, text);78
});79
rootNode.querySelectorAll("[data-i18n-placeholder]").forEach((element) => { element.placeholder = this.t(element.dataset.i18nPlaceholder); });80
rootNode.querySelectorAll("[data-i18n-aria-label]").forEach((element) => { element.setAttribute("aria-label", this.t(element.dataset.i18nAriaLabel)); });81
},82
formatNumber(value, options) { return Number(value).toLocaleString(localeByLanguage[language], options); },83
getLanguage() { return language; },84
getDirection() { return direction(language); },85
getLocale() { return localeByLanguage[language]; },86
setLanguage(value) { language = normalizeLanguage(value); return language; },87
t(key, values) {88
const template = lookupChain(language).map((code) => catalogs[code]?.[key]).find((value) => value !== undefined) ?? key;89
return interpolate(template, values);90
}91
});92
}94
// Whether `language` and its lookup chain are loaded (otherwise fetch them before switching).95
function hasLanguage(language) {96
return lookupChain(normalizeLanguage(language)).every((code) => !known(code) || catalogs[code]);97
}99
function addCatalogs(core) {100
for (const [code, catalog] of Object.entries(core || {})) if (!catalogs[code]) catalogs[code] = catalog;101
}103
return Object.freeze({ catalogs, createI18n, interpolate, normalizeLanguage, direction, supportedLanguages, languages, defaultLanguage, hasLanguage, addCatalogs });104
});SHA-256
6a9abba60d30c04d7c1d1c50eb188cebe50739ce0d208d31dc85b72413728150CH-J Proprietary Software License 1.14 · La fuente se proporciona en el CH-J Proprietary Software License 1.14. Su disponibilidad no cambia los términos de la licencia ni otorga derechos adicionales.
Archivo SHA-256
ac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f