remodel translations

This commit is contained in:
marlon-erler
2024-07-09 02:36:43 +02:00
parent b00c7927b5
commit bcfb82477c
7 changed files with 79 additions and 79 deletions
+32 -27
View File
@@ -242,6 +242,8 @@
}; };
mailboxConnectionHandler = (mailboxId) => { mailboxConnectionHandler = (mailboxId) => {
}; };
mailboxDeleteHandler = (mailboxId) => {
};
// INIT // INIT
set onconnect(handler) { set onconnect(handler) {
this.connectionHandler = handler; this.connectionHandler = handler;
@@ -252,12 +254,15 @@
set onmessage(handler) { set onmessage(handler) {
this.messageHandler = handler; this.messageHandler = handler;
} }
set onmailbox(handler) { set onmailboxcreate(handler) {
this.mailboxHandler = handler; this.mailboxHandler = handler;
} }
set onmailboxconnect(handler) { set onmailboxconnect(handler) {
this.mailboxConnectionHandler = handler; this.mailboxConnectionHandler = handler;
} }
set onmailboxdelete(handler) {
this.mailboxDeleteHandler = handler;
}
// UTILITY METHODS // UTILITY METHODS
send(messageObject) { send(messageObject) {
if (this.ws == void 0) return false; if (this.ws == void 0) return false;
@@ -268,6 +273,7 @@
// PUBLIC METHODS // PUBLIC METHODS
// connection // connection
connect(address) { connect(address) {
try {
this.disconnect(); this.disconnect();
this.ws = new WebSocket(address); this.ws = new WebSocket(address);
this.ws.addEventListener("open", this.connectionHandler); this.ws.addEventListener("open", this.connectionHandler);
@@ -278,11 +284,16 @@
if (data.assignedMailboxId) { if (data.assignedMailboxId) {
return this.mailboxHandler(data.assignedMailboxId); return this.mailboxHandler(data.assignedMailboxId);
} else if (data.connectedMailboxId) { } else if (data.connectedMailboxId) {
return this.mailboxConnectionHandler(data.assignedMailboxId); return this.mailboxConnectionHandler(data.connectedMailboxId);
} else if (data.deletedMailbox) {
return this.mailboxDeleteHandler(data.deletedMailbox);
} else { } else {
this.messageHandler(data); this.messageHandler(data);
} }
}); });
} catch (error) {
console.error(error);
}
} }
disconnect() { disconnect() {
this.ws?.close(); this.ws?.close();
@@ -354,7 +365,7 @@
subscribe: "Subscribe", subscribe: "Subscribe",
unsubscribe: "Unubscribe" unsubscribe: "Unubscribe"
}; };
var translations = { var allTranslations = {
en: staticTextEnglish, en: staticTextEnglish,
es: { es: {
mailbox: "Buz\xF3n", mailbox: "Buz\xF3n",
@@ -405,13 +416,8 @@
unsubscribe: "Verlassen" unsubscribe: "Verlassen"
} }
}; };
function getText(key) { var language = navigator.language.substring(0, 2);
const language = navigator.language.substring(0, 2); var translations = allTranslations[language];
if (translations[language]) {
return translations[language][key];
}
return translations.en[key];
}
// src/model.tsx // src/model.tsx
var Message = class { var Message = class {
@@ -426,7 +432,7 @@
var isMailboxDisonnected = new State(true); var isMailboxDisonnected = new State(true);
var messages = new ListState(); var messages = new ListState();
var lastReceivedMessage = new State( var lastReceivedMessage = new State(
getText("noMessagesReceived") translations.noMessagesReceived
); );
var statHTMLString = new State(""); var statHTMLString = new State("");
async function updateStats() { async function updateStats() {
@@ -496,7 +502,6 @@
newMessageBody.value = ""; newMessageBody.value = "";
} }
function requestMailbox() { function requestMailbox() {
deleteMailbox();
UDN.requestMailbox(); UDN.requestMailbox();
} }
function deleteMailbox() { function deleteMailbox() {
@@ -506,19 +511,19 @@
// src/infoScreen.tsx // src/infoScreen.tsx
function InfoScreen() { function InfoScreen() {
return /* @__PURE__ */ createElement("article", { id: "info-screen" }, /* @__PURE__ */ createElement("header", null, getText("serverInfo"), /* @__PURE__ */ createElement("span", null, /* @__PURE__ */ createElement("button", { "on:click": updateStats }, /* @__PURE__ */ createElement("span", { class: "icon" }, "refresh")))), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "flex-column gap", "subscribe:innerHTML": statHTMLString }))); return /* @__PURE__ */ createElement("article", { id: "info-screen" }, /* @__PURE__ */ createElement("header", null, translations.serverInfo, /* @__PURE__ */ createElement("span", null, /* @__PURE__ */ createElement("button", { "on:click": updateStats }, /* @__PURE__ */ createElement("span", { class: "icon" }, "refresh")))), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "flex-column gap", "subscribe:innerHTML": statHTMLString })));
} }
// src/mainScreen.tsx // src/mainScreen.tsx
function MainScreen() { function MainScreen() {
return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, getText("settings")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("messageLastReceived")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("mailbox")), /* @__PURE__ */ createElement("p", { class: "secondary", "toggle:hidden": isMailboxDisonnected }, getText("mailboxConnected")))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement( return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, translations.settings), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.messageLastReceived), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.mailbox), /* @__PURE__ */ createElement("p", { class: "secondary", "toggle:hidden": isMailboxDisonnected }, translations.mailboxConnected))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement(
"button", "button",
{ {
class: "danger width-50", class: "danger width-50",
"on:click": deleteMailbox, "on:click": deleteMailbox,
"toggle:disabled": isMailboxDisonnected "toggle:disabled": isMailboxDisonnected
}, },
getText("deleteMailbox") translations.deleteMailbox
), /* @__PURE__ */ createElement( ), /* @__PURE__ */ createElement(
"button", "button",
{ {
@@ -526,26 +531,26 @@
"on:click": requestMailbox, "on:click": requestMailbox,
"toggle:disabled": isDisconnected "toggle:disabled": isDisconnected
}, },
getText("requestMailbox"), translations.requestMailbox,
/* @__PURE__ */ createElement("span", { class: "icon" }, "inbox") /* @__PURE__ */ createElement("span", { class: "icon" }, "inbox")
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("subscribeToChannel")), /* @__PURE__ */ createElement( )), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.subscribeToChannel), /* @__PURE__ */ createElement(
"input", "input",
{ {
placeholder: getText("channel_placeholder"), placeholder: translations.channel_placeholder,
"bind:value": subscriptionChannel, "bind:value": subscriptionChannel,
"on:enter": subscribe "on:enter": subscribe
} }
))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement("button", { class: "danger width-50", "on:click": unsubscribe }, getText("unsubscribe")), /* @__PURE__ */ createElement("button", { class: "primary width-50", "on:click": subscribe }, getText("subscribe"), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("channel")), /* @__PURE__ */ createElement( ))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement("button", { class: "danger width-50", "on:click": unsubscribe }, translations.unsubscribe), /* @__PURE__ */ createElement("button", { class: "primary width-50", "on:click": subscribe }, translations.subscribe, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.channel), /* @__PURE__ */ createElement(
"input", "input",
{ {
placeholder: getText("channel_placeholder"), placeholder: translations.channel_placeholder,
"bind:value": newMessageChannel, "bind:value": newMessageChannel,
"on:enter": sendMessage "on:enter": sendMessage
} }
))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("message")), /* @__PURE__ */ createElement( ))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.message), /* @__PURE__ */ createElement(
"input", "input",
{ {
placeholder: getText("message_placeholder"), placeholder: translations.message_placeholder,
"bind:value": newMessageBody, "bind:value": newMessageBody,
"on:enter": sendMessage "on:enter": sendMessage
} }
@@ -556,7 +561,7 @@
"on:click": sendMessage, "on:click": sendMessage,
"toggle:disabled": isMessageEmpty "toggle:disabled": isMessageEmpty
}, },
getText("send"), translations.send,
/* @__PURE__ */ createElement("span", { class: "icon" }, "send") /* @__PURE__ */ createElement("span", { class: "icon" }, "send")
)))); ))));
} }
@@ -566,7 +571,7 @@
return /* @__PURE__ */ createElement("div", { class: "tile", style: "flex: 0" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", { class: "secondary" }, message.channel), /* @__PURE__ */ createElement("b", null, message.body))); return /* @__PURE__ */ createElement("div", { class: "tile", style: "flex: 0" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", { class: "secondary" }, message.channel), /* @__PURE__ */ createElement("b", null, message.body)));
}; };
function MessageScreen() { function MessageScreen() {
return /* @__PURE__ */ createElement("article", { id: "message-screen" }, /* @__PURE__ */ createElement("header", null, getText("messagesReceived")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement( return /* @__PURE__ */ createElement("article", { id: "message-screen" }, /* @__PURE__ */ createElement("header", null, translations.messagesReceived), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement(
"div", "div",
{ {
class: "flex-column gap", class: "flex-column gap",
@@ -576,7 +581,7 @@
"input", "input",
{ {
style: "max-width: unset", style: "max-width: unset",
placeholder: getText("message_placeholder_generic"), placeholder: translations.message_placeholder_generic,
"bind:value": newMessageBody, "bind:value": newMessageBody,
"on:enter": sendMessage "on:enter": sendMessage
} }
@@ -593,10 +598,10 @@
// src/index.tsx // src/index.tsx
document.body.prepend( document.body.prepend(
/* @__PURE__ */ createElement("menu", null, /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#info-screen", active: true }, /* @__PURE__ */ createElement("span", { class: "icon" }, "info"), getText("info")), /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#main-screen" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "settings"), getText("settings")), /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#message-screen" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "chat"), getText("messages"))) /* @__PURE__ */ createElement("menu", null, /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#info-screen", active: true }, /* @__PURE__ */ createElement("span", { class: "icon" }, "info"), translations.info), /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#main-screen" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "settings"), translations.settings), /* @__PURE__ */ createElement("a", { class: "tab-link", href: "#message-screen" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "chat"), translations.messages))
); );
document.querySelector("main").append(InfoScreen(), MainScreen(), MessageScreen()); document.querySelector("main").append(InfoScreen(), MainScreen(), MessageScreen());
document.body.append( document.body.append(
/* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isDisconnected }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("div", { class: "flex-column align-center justify-center width-100 height-100", style: "gap: 1rem" }, /* @__PURE__ */ createElement("span", { class: "icon error", style: "font-size: 3rem" }, "signal_disconnected"), /* @__PURE__ */ createElement("h1", { class: "error" }, getText("disconnected")), /* @__PURE__ */ createElement("p", { class: "secondary" }, getText("reconnecting")))))) /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isDisconnected }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("div", { class: "flex-column align-center justify-center width-100 height-100", style: "gap: 1rem" }, /* @__PURE__ */ createElement("span", { class: "icon error", style: "font-size: 3rem" }, "signal_disconnected"), /* @__PURE__ */ createElement("h1", { class: "error" }, translations.disconnected), /* @__PURE__ */ createElement("p", { class: "secondary" }, translations.reconnecting)))))
); );
})(); })();
+6 -6
View File
@@ -3,23 +3,23 @@ import * as React from "bloatless-react";
import { InfoScreen } from "./infoScreen"; import { InfoScreen } from "./infoScreen";
import { MainScreen } from "./mainScreen"; import { MainScreen } from "./mainScreen";
import { MessageScreen } from "./messageScreen"; import { MessageScreen } from "./messageScreen";
import { getText } from "./translations";
import { isDisconnected } from "./model"; import { isDisconnected } from "./model";
import { translations } from "./translations";
// WS // WS
document.body.prepend( document.body.prepend(
<menu> <menu>
<a class="tab-link" href="#info-screen" active> <a class="tab-link" href="#info-screen" active>
<span class="icon">info</span> <span class="icon">info</span>
{getText("info")} {translations.info}
</a> </a>
<a class="tab-link" href="#main-screen"> <a class="tab-link" href="#main-screen">
<span class="icon">settings</span> <span class="icon">settings</span>
{getText("settings")} {translations.settings}
</a> </a>
<a class="tab-link" href="#message-screen"> <a class="tab-link" href="#message-screen">
<span class="icon">chat</span> <span class="icon">chat</span>
{getText("messages")} {translations.messages}
</a> </a>
</menu> </menu>
); );
@@ -34,8 +34,8 @@ document.body.append(
<span class="icon error" style="font-size: 3rem"> <span class="icon error" style="font-size: 3rem">
signal_disconnected signal_disconnected
</span> </span>
<h1 class="error">{getText("disconnected")}</h1> <h1 class="error">{translations.disconnected}</h1>
<p class="secondary">{getText("reconnecting")}</p> <p class="secondary">{translations.reconnecting}</p>
</div> </div>
</main> </main>
</div> </div>
+2 -2
View File
@@ -2,13 +2,13 @@ import * as React from "bloatless-react";
import { statHTMLString, updateStats } from "./model"; import { statHTMLString, updateStats } from "./model";
import { getText } from "./translations"; import { translations } from "./translations";
export function InfoScreen() { export function InfoScreen() {
return ( return (
<article id="info-screen"> <article id="info-screen">
<header> <header>
{getText("serverInfo")} {translations.serverInfo}
<span> <span>
<button on:click={updateStats}> <button on:click={updateStats}>
<span class="icon">refresh</span> <span class="icon">refresh</span>
+16 -16
View File
@@ -15,17 +15,17 @@ import {
unsubscribe, unsubscribe,
} from "./model"; } from "./model";
import { getText } from "./translations"; import { translations } from "./translations";
export function MainScreen() { export function MainScreen() {
// UI // UI
return ( return (
<article id="main-screen"> <article id="main-screen">
<header>{getText("settings")}</header> <header>{translations.settings}</header>
<div> <div>
<div class="tile width-input"> <div class="tile width-input">
<div> <div>
<b>{getText("messageLastReceived")}</b> <b>{translations.messageLastReceived}</b>
<p class="secondary" subscribe:innerText={lastReceivedMessage}></p> <p class="secondary" subscribe:innerText={lastReceivedMessage}></p>
</div> </div>
</div> </div>
@@ -34,9 +34,9 @@ export function MainScreen() {
<div class="tile width-input"> <div class="tile width-input">
<div> <div>
<b>{getText("mailbox")}</b> <b>{translations.mailbox}</b>
<p class="secondary" toggle:hidden={isMailboxDisonnected}> <p class="secondary" toggle:hidden={isMailboxDisonnected}>
{getText("mailboxConnected")} {translations.mailboxConnected}
</p> </p>
</div> </div>
</div> </div>
@@ -47,14 +47,14 @@ export function MainScreen() {
on:click={deleteMailbox} on:click={deleteMailbox}
toggle:disabled={isMailboxDisonnected} toggle:disabled={isMailboxDisonnected}
> >
{getText("deleteMailbox")} {translations.deleteMailbox}
</button> </button>
<button <button
class="primary width-50" class="primary width-50"
on:click={requestMailbox} on:click={requestMailbox}
toggle:disabled={isDisconnected} toggle:disabled={isDisconnected}
> >
{getText("requestMailbox")} {translations.requestMailbox}
<span class="icon">inbox</span> <span class="icon">inbox</span>
</button> </button>
</div> </div>
@@ -63,9 +63,9 @@ export function MainScreen() {
<label class="tile"> <label class="tile">
<div> <div>
<span>{getText("subscribeToChannel")}</span> <span>{translations.subscribeToChannel}</span>
<input <input
placeholder={getText("channel_placeholder")} placeholder={translations.channel_placeholder}
bind:value={subscriptionChannel} bind:value={subscriptionChannel}
on:enter={subscribe} on:enter={subscribe}
></input> ></input>
@@ -74,10 +74,10 @@ export function MainScreen() {
<div class="flex-row width-input justify-end"> <div class="flex-row width-input justify-end">
<button class="danger width-50" on:click={unsubscribe}> <button class="danger width-50" on:click={unsubscribe}>
{getText("unsubscribe")} {translations.unsubscribe}
</button> </button>
<button class="primary width-50" on:click={subscribe}> <button class="primary width-50" on:click={subscribe}>
{getText("subscribe")} {translations.subscribe}
<span class="icon">arrow_forward</span> <span class="icon">arrow_forward</span>
</button> </button>
</div> </div>
@@ -86,9 +86,9 @@ export function MainScreen() {
<label class="tile"> <label class="tile">
<div> <div>
<span>{getText("channel")}</span> <span>{translations.channel}</span>
<input <input
placeholder={getText("channel_placeholder")} placeholder={translations.channel_placeholder}
bind:value={newMessageChannel} bind:value={newMessageChannel}
on:enter={sendMessage} on:enter={sendMessage}
></input> ></input>
@@ -97,9 +97,9 @@ export function MainScreen() {
<label class="tile"> <label class="tile">
<div> <div>
<span>{getText("message")}</span> <span>{translations.message}</span>
<input <input
placeholder={getText("message_placeholder")} placeholder={translations.message_placeholder}
bind:value={newMessageBody} bind:value={newMessageBody}
on:enter={sendMessage} on:enter={sendMessage}
></input> ></input>
@@ -112,7 +112,7 @@ export function MainScreen() {
on:click={sendMessage} on:click={sendMessage}
toggle:disabled={isMessageEmpty} toggle:disabled={isMessageEmpty}
> >
{getText("send")} {translations.send}
<span class="icon">send</span> <span class="icon">send</span>
</button> </button>
</div> </div>
+3 -3
View File
@@ -8,7 +8,7 @@ import {
sendMessage, sendMessage,
} from "./model"; } from "./model";
import { getText } from "./translations"; import { translations } from "./translations";
const convertMessageToElement: React.ListItemConverter<Message> = (message) => { const convertMessageToElement: React.ListItemConverter<Message> = (message) => {
return ( return (
@@ -24,7 +24,7 @@ const convertMessageToElement: React.ListItemConverter<Message> = (message) => {
export function MessageScreen() { export function MessageScreen() {
return ( return (
<article id="message-screen"> <article id="message-screen">
<header>{getText("messagesReceived")}</header> <header>{translations.messagesReceived}</header>
<div> <div>
<div <div
class="flex-column gap" class="flex-column gap"
@@ -34,7 +34,7 @@ export function MessageScreen() {
<footer> <footer>
<input <input
style="max-width: unset" style="max-width: unset"
placeholder={getText("message_placeholder_generic")} placeholder={translations.message_placeholder_generic}
bind:value={newMessageBody} bind:value={newMessageBody}
on:enter={sendMessage} on:enter={sendMessage}
></input> ></input>
+2 -2
View File
@@ -1,7 +1,7 @@
import * as React from "bloatless-react"; import * as React from "bloatless-react";
import UDNFrontend from "udn-frontend"; import UDNFrontend from "udn-frontend";
import { getText } from "./translations"; import { translations } from "./translations";
export class Message implements React.Identifiable { export class Message implements React.Identifiable {
id = React.UUID(); id = React.UUID();
@@ -18,7 +18,7 @@ export const isMailboxDisonnected = new React.State(true);
// messages // messages
export const messages = new React.ListState<Message>(); export const messages = new React.ListState<Message>();
export const lastReceivedMessage = new React.State( export const lastReceivedMessage = new React.State(
getText("noMessagesReceived") translations.noMessagesReceived
); );
// stats // stats
+3 -8
View File
@@ -1,5 +1,5 @@
// STATIC // STATIC
export const staticTextEnglish = { const staticTextEnglish = {
mailbox: "Mailbox", mailbox: "Mailbox",
requestMailbox: "Request", requestMailbox: "Request",
deleteMailbox: "Delete", deleteMailbox: "Delete",
@@ -24,7 +24,7 @@ export const staticTextEnglish = {
unsubscribe: "Unubscribe", unsubscribe: "Unubscribe",
}; };
export const translations: { [key: string]: typeof staticTextEnglish } = { const allTranslations: { [key: string]: typeof staticTextEnglish } = {
en: staticTextEnglish, en: staticTextEnglish,
es: { es: {
mailbox: "Buzón", mailbox: "Buzón",
@@ -76,10 +76,5 @@ export const translations: { [key: string]: typeof staticTextEnglish } = {
}, },
}; };
export function getText(key: keyof typeof staticTextEnglish): string {
const language = navigator.language.substring(0, 2); const language = navigator.language.substring(0, 2);
if (translations[language]) { export const translations = allTranslations[language];
return translations[language][key];
}
return translations.en[key];
}