1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Use yaml-loader instead of relying on gulp to build the translations

This commit is contained in:
Bjorn Stromberg 2020-08-10 14:54:55 +09:00
parent fd7ae79971
commit e801bab0be
34 changed files with 724 additions and 273 deletions

View File

@ -94,6 +94,7 @@
"sass-unused": "^0.3.0",
"strip-json-comments": "^3.0.1",
"trim": "^0.0.1",
"yaml-loader": "^0.6.0",
"yarn": "^1.22.4"
}
}

View File

@ -1,113 +0,0 @@
/**
* @type {Object<string, {name: string, data: any, code: string, region: string}>}
*/
export const LANGUAGES = {
"en": {
name: "English",
data: null,
code: "en",
region: "",
},
"de": {
name: "Deutsch",
data: require("./built-temp/base-de.json"),
code: "de",
region: "",
},
"fr": {
name: "Français",
data: require("./built-temp/base-fr.json"),
code: "fr",
region: "",
},
"ja": {
name: "日本語",
data: require("./built-temp/base-ja.json"),
code: "ja",
region: "",
},
"pt-PT": {
name: "Português (Portugal)",
data: require("./built-temp/base-pt-PT.json"),
code: "pt",
region: "PT",
},
"pt-BR": {
name: "Português (Brasil)",
data: require("./built-temp/base-pt-BR.json"),
code: "pt",
region: "BR",
},
"ru": {
name: "Русский",
data: require("./built-temp/base-ru.json"),
code: "ru",
region: "",
},
"cs": {
name: "Čeština",
data: require("./built-temp/base-cz.json"),
code: "cs",
region: "",
},
"es-419": {
name: "Español",
data: require("./built-temp/base-es.json"),
code: "es",
region: "",
},
"pl": {
name: "Polski",
data: require("./built-temp/base-pl.json"),
code: "pl",
region: "",
},
"kor": {
name: "한국어",
data: require("./built-temp/base-kor.json"),
code: "kor",
region: "",
},
"nl": {
name: "Nederlands",
data: require("./built-temp/base-nl.json"),
code: "nl",
region: "",
},
"no": {
name: "Norsk",
data: require("./built-temp/base-no.json"),
code: "no",
region: "",
},
"tr": {
name: "Türkçe",
data: require("./built-temp/base-tr.json"),
code: "tr",
region: "",
},
"zh-CN": {
// simplified
name: "中文简体",
data: require("./built-temp/base-zh-CN.json"),
code: "zh",
region: "CN",
},
"zh-TW": {
// traditional
name: "中文繁體",
data: require("./built-temp/base-zh-TW.json"),
code: "zh",
region: "TW",
},
"sv": {
name: "Svenska",
data: require("./built-temp/base-sv.json"),
code: "sv",
region: "",
},
};

View File

@ -6,10 +6,14 @@ import { ReadWriteProxy } from "../core/read_write_proxy";
import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types";
import { createLogger } from "../core/logging";
import { ExplainedResult } from "../core/explained_result";
import { THEMES, THEME, applyGameTheme } from "../game/theme";
import { THEMES, applyGameTheme } from "../game/theme";
import { IS_DEMO } from "../core/config";
import { T } from "../translations";
import { LANGUAGES } from "../languages";
import languageMap, { isLanguageTag, languageTags } from "../translations/languages";
/**
* @typedef {import("../translations/languages").LanguageTag} LanguageTag
**/
const logger = createLogger("application_settings");
@ -125,9 +129,9 @@ export const autosaveIntervals = [
/** @type {Array<BaseSetting>} */
export const allApplicationSettings = [
new EnumSetting("language", {
options: Object.keys(LANGUAGES),
valueGetter: key => key,
textGetter: key => LANGUAGES[key].name,
options: languageTags,
valueGetter: languageTag => languageTag,
textGetter: languageTag => languageMap[languageTag].name,
category: enumCategories.general,
restartRequired: true,
changeCb: (app, id) => null,
@ -275,6 +279,7 @@ class SettingsStorage {
this.refreshRate = "60";
this.scrollWheelSensitivity = "regular";
this.movementSpeed = "regular";
/** @type {LanguageTag | "auto-detect"} **/
this.language = "auto-detect";
this.autosaveInterval = "two_minutes";
@ -405,10 +410,12 @@ export class ApplicationSettings extends ReadWriteProxy {
}
// Setters
updateLanguage(id) {
assert(LANGUAGES[id], "Language not known: " + id);
return this.updateSetting("language", id);
/**
* @param {LanguageTag} languageTag
**/
updateLanguage(languageTag) {
assert(isLanguageTag(languageTag), "Language not known: " + languageTag);
return this.updateSetting("language", languageTag);
}
/**

View File

@ -1,4 +1,4 @@
import { BaseSavegameInterface } from "../savegame_interface.js";
import { BaseSavegameInterface } from "../savegame_interface";
const schema = require("./1000.json");

View File

@ -1,7 +1,7 @@
import { SavegameInterface_V1000 } from "./1000.js";
import { createLogger } from "../../core/logging.js";
import { T } from "../../translations.js";
import { TypeVector, TypeNumber, TypeString, TypeNullable } from "../serialization_data_types.js";
import { SavegameInterface_V1000 } from "./1000";
import { createLogger } from "../../core/logging";
import { T } from "../../translations";
import { TypeVector, TypeNumber } from "../serialization_data_types";
const schema = require("./1001.json");

View File

@ -1,6 +1,5 @@
import { createLogger } from "../../core/logging.js";
import { T } from "../../translations.js";
import { SavegameInterface_V1001 } from "./1001.js";
import { createLogger } from "../../core/logging";
import { SavegameInterface_V1001 } from "./1001";
const schema = require("./1002.json");
const logger = createLogger("savegame_interface/1002");

View File

@ -1,5 +1,5 @@
import { createLogger } from "../../core/logging.js";
import { SavegameInterface_V1002 } from "./1002.js";
import { createLogger } from "../../core/logging";
import { SavegameInterface_V1002 } from "./1002";
const schema = require("./1003.json");
const logger = createLogger("savegame_interface/1003");

View File

@ -1,5 +1,5 @@
import { createLogger } from "../../core/logging.js";
import { SavegameInterface_V1003 } from "./1003.js";
import { createLogger } from "../../core/logging";
import { SavegameInterface_V1003 } from "./1003";
const schema = require("./1004.json");
const logger = createLogger("savegame_interface/1004");

View File

@ -1,5 +1,5 @@
import { createLogger } from "../../core/logging.js";
import { SavegameInterface_V1004 } from "./1004.js";
import { createLogger } from "../../core/logging";
import { SavegameInterface_V1004 } from "./1004";
const schema = require("./1005.json");
const logger = createLogger("savegame_interface/1005");

View File

@ -4,6 +4,7 @@ import { findNiceValue } from "../core/utils";
import { cachebust } from "../core/cachebust";
import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper";
import { T, autoDetectLanguageId, updateApplicationLanguage } from "../translations";
import { isLanguageTag } from "../translations/languages";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { CHANGELOG } from "../changelog";
import { globalConfig } from "../core/config";
@ -125,7 +126,9 @@ export class PreloadState extends GameState {
})
.then(() => {
const language = this.app.settings.getLanguage();
updateApplicationLanguage(language);
if (isLanguageTag(language)) {
updateApplicationLanguage(language);
}
})
.then(() => this.setStatus("Initializing sounds"))

View File

@ -1,135 +0,0 @@
import { globalConfig } from "./core/config";
import { createLogger } from "./core/logging";
import { LANGUAGES } from "./languages";
const logger = createLogger("translations");
// @ts-ignore
const baseTranslations = require("./built-temp/base-en.json");
export let T = baseTranslations;
if (G_IS_DEV && globalConfig.debug.testTranslations) {
// Replaces all translations by fake translations to see whats translated and what not
const mapTranslations = obj => {
for (const key in obj) {
const value = obj[key];
if (typeof value === "string") {
obj[key] = value.replace(/[a-z]/gi, "x");
} else {
mapTranslations(value);
}
}
};
mapTranslations(T);
}
export function applyLanguage(languageCode) {
logger.log("Applying language:", languageCode);
const data = LANGUAGES[languageCode];
if (!data) {
logger.error("Language not found:", languageCode);
return false;
}
}
// Language key is something like de-DE or en or en-US
function mapLanguageCodeToId(languageKey) {
const key = languageKey.toLowerCase();
const shortKey = key.split("-")[0];
// Try to match by key or short key
for (const id in LANGUAGES) {
const data = LANGUAGES[id];
const code = data.code.toLowerCase();
if (code === key) {
console.log("-> Match", languageKey, "->", id);
return id;
}
if (code === shortKey) {
console.log("-> Match by short key", languageKey, "->", id);
return id;
}
}
// If none found, try to find a better alternative by using the base language at least
for (const id in LANGUAGES) {
const data = LANGUAGES[id];
const code = data.code.toLowerCase();
const shortCode = code.split("-")[0];
if (shortCode === key) {
console.log("-> Desperate Match", languageKey, "->", id);
return id;
}
if (shortCode === shortKey) {
console.log("-> Desperate Match by short key", languageKey, "->", id);
return id;
}
}
return null;
}
/**
* Tries to auto-detect a language
* @returns {string}
*/
export function autoDetectLanguageId() {
let languages = [];
if (navigator.languages) {
languages = navigator.languages.slice();
} else if (navigator.language) {
languages = [navigator.language];
} else {
logger.warn("Navigator has no languages prop");
}
for (let i = 0; i < languages.length; ++i) {
logger.log("Trying to find language target for", languages[i]);
const trans = mapLanguageCodeToId(languages[i]);
if (trans) {
return trans;
}
}
// Fallback
return "en";
}
function matchDataRecursive(dest, src) {
if (typeof dest !== "object" || typeof src !== "object") {
return;
}
for (const key in dest) {
if (src[key]) {
// console.log("copy", key);
const data = dest[key];
if (typeof data === "object") {
matchDataRecursive(dest[key], src[key]);
} else if (typeof data === "string" || typeof data === "number") {
// console.log("match string", key);
dest[key] = src[key];
} else {
logger.log("Unknown type:", typeof data, "in key", key);
}
}
}
}
export function updateApplicationLanguage(id) {
logger.log("Setting application language:", id);
const data = LANGUAGES[id];
if (!data) {
logger.error("Unknown language:", id);
return;
}
if (data.data) {
logger.log("Applying translations ...");
matchDataRecursive(T, data.data);
}
}

View File

@ -0,0 +1,115 @@
import { globalConfig } from "../core/config";
import { createLogger } from "../core/logging";
import languageMap, { isLanguageTag, languageTags } from "./languages";
/**
* @typedef {import("./languages").LanguageTag} LanguageTag
**/
const logger = createLogger("translations");
export const T = languageMap.en.data;
if (G_IS_DEV && globalConfig.debug.testTranslations) {
// Replaces all translations by fake translations to see whats translated and what not
const mapTranslations = obj => {
for (const key in obj) {
const value = obj[key];
if (typeof value === "string") {
obj[key] = value.replace(/[a-z]/gi, "x");
} else {
mapTranslations(value);
}
}
};
mapTranslations(T);
}
/** tag should be a language code, like de-DE or en or en-US
* @param {string} tag
* @returns {LanguageTag | null}
**/
function mapLanguageCodeToId(tag) {
if (isLanguageTag(tag)) {
return tag;
}
const [code] = tag.split("-");
// Try to match by tag or code
for (const languageTag of languageTags) {
const { code: c } = languageMap[languageTag];
if (tag === c) {
console.log("-> Match", tag, "->", languageTag);
return languageTag;
}
if (code === c) {
console.log("-> Match by short key", tag, "->", languageTag);
return languageTag;
}
}
return null;
}
/**
* Tries to auto-detect a language
* @returns {LanguageTag}
*/
export function autoDetectLanguageId() {
let languages = [];
if (navigator.languages) {
languages = navigator.languages.slice();
} else if (navigator.language) {
languages = [navigator.language];
} else {
logger.warn("Navigator has no languages prop");
}
for (let i = 0; i < languages.length; ++i) {
logger.log("Trying to find language target for", languages[i]);
const trans = mapLanguageCodeToId(languages[i]);
if (trans) {
return trans;
}
}
// Fallback
return "en";
}
function matchDataRecursive(dest, src) {
if (typeof dest !== "object" || typeof src !== "object") {
return;
}
for (const key in dest) {
if (src[key]) {
const data = dest[key];
if (typeof data === "object") {
matchDataRecursive(dest[key], src[key]);
} else if (typeof data === "string" || typeof data === "number") {
dest[key] = src[key];
} else {
logger.log("Unknown type:", typeof data, "in key", key);
}
}
}
}
/**
* @param {LanguageTag} languageTag
**/
export function updateApplicationLanguage(languageTag) {
logger.log("Setting application language:", languageTag);
if (!languageMap.hasOwnProperty(languageTag)) {
logger.error("Unknown language:", languageTag);
return;
}
const { data } = languageMap[languageTag];
logger.log("Applying translations ...");
matchDataRecursive(T, data);
}

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-cs.yaml";
/** @type {"cs"} **/
const code = "cs";
const name = "Čeština";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-de.yaml";
/** @type {"de"} **/
const code = "de";
const name = "Deutsch";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-en.yaml";
/** @type {"en"} **/
const code = "en";
const name = "English";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-es-419.yaml";
/** @type {"es"} **/
const code = "es";
const name = "Español";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-fr.yaml";
/** @type {"fr"} **/
const code = "fr";
const name = "Français";
export default { code, data, name };

View File

@ -0,0 +1,99 @@
import cs from "./cs";
import de from "./de";
import en from "./en";
import es419 from "./es-419";
import fr from "./fr";
import ja from "./ja";
import kor from "./kor";
import nl from "./nl";
import no from "./no";
import pl from "./pl";
import ptPT from "./pt-PT";
import ptBR from "./pt-BR";
import ru from "./ru";
import sv from "./sv";
import tr from "./tr";
import zhCN from "./zh-CN";
import zhTW from "./zh-TW";
/**
* @typedef {"en" | "de" | "fr" | "ja" | "pt-PT" | "pt-BR" | "ru" | "cs" | "es-419" | "pl" | "kor" | "nl" | "no" | "tr" | "zh-CN" | "zh-TW" | "sv"} LanguageTag
*/
/** @type {LanguageTag[]} **/
export const languageTags = [
"en",
"de",
"fr",
"ja",
"pt-PT",
"pt-BR",
"ru",
"cs",
"es-419",
"pl",
"kor",
"nl",
"no",
"tr",
"zh-CN",
"zh-TW",
"sv",
];
/**
* @param {unknown} value
* @returns {value is LanguageTag}
**/
export function isLanguageTag(value) {
return languageTags.includes(/** @type {LanguageTag} **/ (value));
}
/** @typedef {"en" | "de" | "fr" | "ja" | "pt" | "ru" | "cs" | "es" | "pl" | "kor" | "nl" | "no" | "tr" | "zh" | "sv"} LanguageCode
*/
/** @type {LanguageCode[]} **/
const languageCodes = [
"en",
"de",
"fr",
"ja",
"pt",
"ru",
"cs",
"es",
"pl",
"kor",
"nl",
"no",
"tr",
"zh",
"sv",
];
/** @typedef {"PT" | "BR" | "CN" | "TW"} LanguageRegion **/
/** @type {LanguageRegion[]} **/
const languageRegions = ["PT", "BR", "CN", "TW"];
/**
* @type {Record<LanguageTag, {name: string, data: Translations, code: LanguageCode, region?: LanguageRegion}>}
*/
export default {
cs,
de,
en,
"es-419": es419,
fr,
ja,
kor,
nl,
no,
pl,
"pt-BR": ptBR,
"pt-PT": ptPT,
ru,
sv,
tr,
"zh-CN": zhCN,
"zh-TW": zhTW,
};

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-ja.yaml";
/** @type {"ja"} **/
const code = "ja";
const name = "日本語";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-kor.yaml";
/** @type {"kor"} **/
const code = "kor";
const name = "한국어";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-nl.yaml";
/** @type {"nl"} **/
const code = "nl";
const name = "Nederlands";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-no.yaml";
/** @type {"no"} **/
const code = "no";
const name = "Norsk";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-pl.yaml";
/** @type {"pl"} **/
const code = "pl";
const name = "Polski";
export default { code, data, name };

View File

@ -0,0 +1,8 @@
import data from "yaml-loader!../../../../translations/base-pt-BR.yaml";
/** @type {"pt"} **/
const code = "pt";
const name = "Português (Brasil)";
const region = "BR";
export default { code, data, name, region };

View File

@ -0,0 +1,8 @@
import data from "yaml-loader!../../../../translations/base-pt-PT.yaml";
/** @type {"pt"} **/
const code = "pt";
const name = "Português (Portugal)";
const region = "PT";
export default { code, data, name, region };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-ru.yaml";
/** @type {"ru"} **/
const code = "ru";
const name = "Русский";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-sv.yaml";
/** @type {"sv"} **/
const code = "sv";
const name = "Svenska";
export default { code, data, name };

View File

@ -0,0 +1,7 @@
import data from "yaml-loader!../../../../translations/base-tr.yaml";
/** @type {"tr"} **/
const code = "tr";
const name = "Türkçe";
export default { code, data, name };

View File

@ -0,0 +1,8 @@
import data from "yaml-loader!../../../../translations/base-zh-CN.yaml";
/** @type {"zh"} **/
const code = "zh";
const name = "中文简体";
const region = "CN";
export default { code, data, name, region };

View File

@ -0,0 +1,8 @@
import data from "yaml-loader!../../../../translations/base-zh-TW.yaml";
/** @type {"zh"} **/
const code = "zh";
const name = "中文繁體";
const region = "TW";
export default { code, data, name, region };

344
src/js/translations/types.d.ts vendored Normal file
View File

@ -0,0 +1,344 @@
declare type Translation<T extends string, U = string> = Record<T, U>;
declare type BeltVariant = "default";
declare type WireVariant = "default" | "chainable";
declare type UndergroundBeltVariant = "default" | "tier2";
declare type SplitterVariant = "default" | "compact" | "compact-inverse";
declare type CutterVariant = "default" | "quad";
declare type AdvancedProcessorVariant = "default";
declare type RotaterVariant = "default" | "ccw" | "fl";
declare type StackerVariant = "default";
declare type MixerVariant = "default";
declare type PainterVariant = "default" | "mirrored" | "double" | "quad";
declare type TrashVariant = "default" | "storage";
declare type EnergyGeneratorVariant = "default";
declare type WireCrossingsVariant = "default" | "merger";
declare type BuildingVariantMap = {
belt: BeltVariant;
wire: WireVariant;
underground_belt: UndergroundBeltVariant;
splitter: SplitterVariant;
cutter: CutterVariant;
advanced_processor: AdvancedProcessorVariant;
rotater: RotaterVariant;
stacker: StackerVariant;
mixer: MixerVariant;
painter: PainterVariant;
trash: TrashVariant;
energy_generator: EnergyGeneratorVariant;
wire_crossings: WireCrossingsVariant;
};
declare type BuildingVariant<V extends keyof BuildingVariantMap> = BuildingVariantMap[V];
declare type Building = keyof BuildingVariantMap;
declare type Color =
| "red"
| "green"
| "blue"
| "yellow"
| "purple"
| "cyan"
| "white"
| "uncolored"
| "black";
declare type Environment = "dev" | "prod" | "staging";
declare type Interval =
| "one_minute"
| "two_minutes"
| "five_minutes"
| "ten_minutes"
| "twenty_minutes"
| "disabled";
declare type Scale = "super_small" | "small" | "regular" | "large" | "huge";
declare type Sensitivity = "super_slow" | "slow" | "regular" | "fast" | "super_fast";
declare type Speed = "super_slow" | "slow" | "regular" | "fast" | "super_fast" | "extremely_fast";
declare type Theme = "dark" | "light";
declare type Rewards =
| "reward_cutter_and_trash"
| "reward_rotater"
| "reward_painter"
| "reward_mixer"
| "reward_stacker"
| "reward_splitter"
| "reward_tunnel"
| "reward_rotater_ccw"
| "reward_miner_chainable"
| "reward_underground_belt_tier_2"
| "reward_splitter_compact"
| "reward_cutter_quad"
| "reward_painter_double"
| "reward_painter_quad"
| "reward_storage"
| "reward_freeplay"
| "reward_blueprints"
| "no_reward"
| "no_reward_freeplay";
declare type TitleAndText = Translation<"title" | "text">;
declare type TitleAndDesc = Translation<"title" | "desc">;
declare type TitleAndDescription = Translation<"title" | "description">;
declare type NameAndDescription = Translation<"name" | "description">;
declare type SteamPage = Translation<"shortText" | "discordLink" | "longText">;
declare type Global = Translation<
"loading" | "error" | "thousandsDivider" | "decimalSeparator" | "infinite"
> & {
suffix: Translation<"thousands" | "millions" | "billions" | "trillions">;
time: Translation<
| "oneSecondAgo"
| "xSecondsAgo"
| "oneMinuteAgo"
| "xMinutesAgo"
| "oneHourAgo"
| "xHoursAgo"
| "oneDayAgo"
| "xDaysAgo"
| "secondsShort"
| "minutesAndSecondsShort"
| "hoursAndMinutesShort"
| "xMinutes"
>;
keys: Translation<"tab" | "control" | "alt" | "escape" | "shift" | "space">;
};
declare type DemoBanners = Translation<"title" | "intro">;
declare type MainMenu = Translation<
| "play"
| "continue"
| "newGame"
| "changelog"
| "subreddit"
| "importSavegame"
| "openSourceHint"
| "discordLink"
| "helpTranslate"
| "madeBy"
| "browserWarning"
| "savegameLevel"
| "savegameLevelUnknown"
>;
declare type Dialogs = Translation<
| "importSavegameError"
| "importSavegameSuccess"
| "gameLoadFailure"
| "confirmSavegameDelete"
| "savegameDeletionError"
| "restartRequired",
TitleAndText
> &
Translation<
| "editKeybinding"
| "resetKeybindingsConfirmation"
| "keybindingsResetOk"
| "featureRestriction"
| "oneSavegameLimit"
| "updateSummary"
| "upgradesIntroduction"
| "massDeleteConfirm"
| "massCutConfirm"
| "massCutInsufficientConfirm"
| "blueprintsNotUnlocked"
| "keybindingsIntroduction"
| "exportScreenshotWarning",
TitleAndDesc
> & {
createMarker: TitleAndDesc & Translation<"titleEdit">;
markerDemoLimit: Translation<"desc">;
} & {
buttons: Translation<
| "ok"
| "delete"
| "cancel"
| "later"
| "restart"
| "reset"
| "getStandalone"
| "deleteGame"
| "viewUpdate"
| "showUpgrades"
| "showKeybindings"
>;
};
declare type Ingame = {
keybindingsOverlay: Translation<
| "moveMap"
| "selectBuildings"
| "stopPlacement"
| "rotateBuilding"
| "placeMultiple"
| "reverseOrientation"
| "disableAutoOrientation"
| "toggleHud"
| "placeBuilding"
| "createMarker"
| "delete"
| "pasteLastBlueprint"
| "lockBeltDirection"
| "plannerSwitchSide"
| "cutSelection"
| "copySelection"
| "clearSelection"
| "pipette"
| "switchLayers"
>;
colors: Translation<Color>;
buildingPlacement: Translation<"cycleBuildingVariants" | "hotkeyLabel"> & {
infoTexts: Translation<
| "speed"
| "range"
| "storage"
| "oneItemPerSecond"
| "itemsPerSecond"
| "itemsPerSecondDouble"
| "tiles"
>;
};
levelCompleteNotification: Translation<"levelTitle" | "completed" | "unlockText" | "buttonNextLevel">;
notifications: Translation<"newUpgrade" | "gameSaved">;
shop: Translation<"title" | "buttonUnlock" | "tier" | "maximumLevel"> & {
tierLabels: [string, string, string, string, string, string, string, string, string, string];
};
statistics: Translation<"title" | "noShapesProduced" | "shapesPerMinute"> & {
dataSources: Translation<"stored" | "produced" | "delivered", TitleAndDescription>;
};
settingsMenu: Translation<"playtime" | "buildingsPlaced" | "beltsPlaced"> & {
buttons: Translation<"continue" | "settings" | "menu">;
};
tutorialHints: Translation<"title" | "showHint" | "hideHint">;
blueprintPlacer: Translation<"cost">;
waypoints: Translation<"waypoints" | "hub" | "description" | "creationSuccessNotification">;
shapeViewer: Translation<"title" | "empty" | "copyKey">;
interactiveTutorial: Translation<"title"> & {
hints: Translation<"1_1_extractor" | "1_2_conveyor" | "1_3_expand">;
};
};
declare type ShopUpgrades = Record<"belt" | "miner" | "processors" | "painting", NameAndDescription>;
declare type Buildings = { [Key in Building]: Translation<BuildingVariant<Key>, NameAndDescription> } & {
hub: Translation<"deliver" | "toUnlock" | "levelShortcut">;
energy_generator: Translation<"deliver" | "toGenerateEnergy">;
};
declare type StoryRewards = Translation<Rewards, TitleAndDesc>;
declare type Settings = Translation<"title" | "buildDate"> & {
categories: Translation<"general" | "userInterface" | "advanced">;
versionBadges: Translation<Environment>;
labels: Translation<
| "language"
| "enableColorBlindHelper"
| "fullscreen"
| "soundsMuted"
| "musicMuted"
| "refreshRate"
| "alwaysMultiplace"
| "offerHints"
| "enableTunnelSmartplace"
| "vignette"
| "rotationByBuilding"
| "compactBuildingInfo"
| "disableCutDeleteWarnings",
TitleAndDescription
> & {
autosaveInterval: TitleAndDescription & { intervals: Translation<Interval> };
movementSpeed: TitleAndDescription & { speeds: Translation<Speed> };
scrollWheelSensitivity: TitleAndDescription & { sensitivity: Translation<Sensitivity> };
theme: TitleAndDescription & { themes: Translation<Theme> };
uiScale: TitleAndDescription & { scales: Translation<Scale> };
};
};
declare type KeyBindings = Translation<"title" | "hint" | "resetKeybindings" | "categoryLabels"> & {
categoryLabels: Translation<
"general" | "ingame" | "navigation" | "placement" | "massSelect" | "buildings" | "placementModifiers"
>;
mappings: Translation<
| "confirm"
| "back"
| "mapMoveUp"
| "mapMoveRight"
| "mapMoveDown"
| "mapMoveLeft"
| "mapMoveFaster"
| "centerMap"
| "mapZoomIn"
| "mapZoomOut"
| "createMarker"
| "menuOpenShop"
| "menuOpenStats"
| "menuClose"
| "toggleHud"
| "toggleFPSInfo"
| "switchLayers"
| "exportScreenshot"
| "belt"
| "splitter"
| "underground_belt"
| "miner"
| "cutter"
| "advanced_processor"
| "rotater"
| "stacker"
| "mixer"
| "energy_generator"
| "painter"
| "trash"
| "wire"
| "pipette"
| "rotateWhilePlacing"
| "rotateInverseModifier"
| "cycleBuildingVariants"
| "confirmMassDelete"
| "pasteLastBlueprint"
| "cycleBuildings"
| "lockBeltDirection"
| "switchDirectionLockSide"
| "massSelectStart"
| "massSelectSelectMultiple"
| "massSelectCopy"
| "massSelectCut"
| "placementDisableAutoOrientation"
| "placeMultiple"
| "placeInverse"
>;
};
declare type About = Translation<"title" | "body">;
declare type Changelog = Translation<"title">;
declare type Demo = Translation<"settingNotAvailable"> & {
features: Translation<
"restoringGames" | "importingGames" | "oneGameLimit" | "customizeKeybindings" | "exportingBase"
>;
};
declare interface Translations {
steamPage: SteamPage;
global: Global;
demoBanners: DemoBanners;
mainMenu: MainMenu;
dialogs: Dialogs;
ingame: Ingame;
shopUpgrades: ShopUpgrades;
buildings: Buildings;
storyRewards: StoryRewards;
settings: Settings;
keybindings: KeyBindings;
about: About;
changelog: Changelog;
demo: Demo;
}
declare module "yaml-loader!*" {
const content: Translations;
export default content;
}

View File

@ -8555,7 +8555,15 @@ yaml-js@^0.1.3:
resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.1.5.tgz#a01369010b3558d8aaed2394615dfd0780fd8fac"
integrity sha1-oBNpAQs1WNiq7SOUYV39B4D9j6w=
yaml@^1.10.0:
yaml-loader@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.6.0.tgz#fe1c48b9f4803dace55a59a1474e790ba6ab1b48"
integrity sha512-1bNiLelumURyj+zvVHOv8Y3dpCri0F2S+DCcmps0pA1zWRLjS+FhZQg4o3aUUDYESh73+pKZNI18bj7stpReow==
dependencies:
loader-utils "^1.4.0"
yaml "^1.8.3"
yaml@^1.10.0, yaml@^1.8.3:
version "1.10.0"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==