mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22f42117df | ||
|
|
788edf5bdf | ||
|
|
d0170d53e4 | ||
|
|
ae5e38139b | ||
|
|
e38713f365 | ||
|
|
5903b8130b | ||
|
|
179ce62a55 | ||
|
|
a2f1593a0e | ||
|
|
6305db7ad6 | ||
|
|
5082e1b82b | ||
|
|
e7ca8f1b10 | ||
|
|
0d8a677ac5 | ||
|
|
a8dc271e0a | ||
|
|
f3d6ba68a7 | ||
|
|
e68b27bac4 | ||
|
|
d49eef7308 | ||
|
|
6e630a91aa | ||
|
|
2c66e79daf | ||
|
|
9a94a4e371 | ||
|
|
b1372c998d | ||
|
|
4ed93cb38f | ||
|
|
4d1b175c07 | ||
|
|
ecfedc32ad | ||
|
|
9da514c329 | ||
|
|
ee5386c925 | ||
|
|
76f7ae45ce | ||
|
|
ad2aaa7bf8 | ||
|
|
2a4375c718 | ||
|
|
134566f1d8 | ||
|
|
d592a95cae | ||
|
|
4f74556eb6 | ||
|
|
1342f434a3 | ||
|
|
6110471990 | ||
|
|
359eec5209 |
No files matched your search
@@ -29,7 +29,7 @@ concurrency:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.ASSET_BOT }}
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
|
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
|
||||||
@@ -51,6 +51,8 @@ env:
|
|||||||
PUBLIC_NITROPAY_ID: ${{ secrets.PUBLIC_NITROPAY_ID }}
|
PUBLIC_NITROPAY_ID: ${{ secrets.PUBLIC_NITROPAY_ID }}
|
||||||
PUBLIC_DEBUG_MISSING_I18N: false
|
PUBLIC_DEBUG_MISSING_I18N: false
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
download_client:
|
download_client:
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ concurrency:
|
|||||||
env:
|
env:
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ env:
|
|||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
host:
|
host:
|
||||||
@@ -27,8 +29,8 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: oven-sh/setup-bun@v1
|
- uses: oven-sh/setup-bun@v1
|
||||||
# with:
|
# with:
|
||||||
# bun-version: 1.1.33
|
# bun-version: 1.1.33
|
||||||
|
|
||||||
- name: Download release assets
|
- name: Download release assets
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -25,4 +25,6 @@ jobs:
|
|||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
run: bun build:ratingleaderboard --region=asia
|
run: bun build:ratingleaderboard --region=asia
|
||||||
@@ -25,4 +25,6 @@ jobs:
|
|||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
run: bun build:ratingleaderboard --region=eu
|
run: bun build:ratingleaderboard --region=eu
|
||||||
@@ -25,4 +25,6 @@ jobs:
|
|||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
run: bun build:ratingleaderboard --region=com
|
run: bun build:ratingleaderboard --region=com
|
||||||
@@ -21,7 +21,7 @@ env:
|
|||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
||||||
ALLOW_ROBOTS: "true"
|
ALLOW_ROBOTS: 'true'
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
||||||
@@ -29,6 +29,8 @@ env:
|
|||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
||||||
|
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
||||||
|
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
+1
-2
@@ -22,8 +22,7 @@ depots
|
|||||||
public/sitemap*
|
public/sitemap*
|
||||||
/firebase.json
|
/firebase.json
|
||||||
target
|
target
|
||||||
# packages/core/src/protos/*
|
# *.ts
|
||||||
# !packages/core/src/protos/*.proto
|
|
||||||
/.vercel
|
/.vercel
|
||||||
/.astro
|
/.astro
|
||||||
.vercel
|
.vercel
|
||||||
|
|||||||
@@ -4,6 +4,3 @@
|
|||||||
[submodule "submodules/CUE4Parse"]
|
[submodule "submodules/CUE4Parse"]
|
||||||
path = submodules/CUE4Parse
|
path = submodules/CUE4Parse
|
||||||
url = https://github.com/FabianFG/CUE4Parse
|
url = https://github.com/FabianFG/CUE4Parse
|
||||||
[submodule "submodules/UAssetAPI"]
|
|
||||||
path = submodules/UAssetAPI
|
|
||||||
url = https://github.com/atenfyr/UAssetAPI
|
|
||||||
Vendored
+6
@@ -33,6 +33,7 @@
|
|||||||
"blitzkit",
|
"blitzkit",
|
||||||
"blitzrinth",
|
"blitzrinth",
|
||||||
"blitzstars",
|
"blitzstars",
|
||||||
|
"bufbuild",
|
||||||
"cacheable",
|
"cacheable",
|
||||||
"Callouts",
|
"Callouts",
|
||||||
"Camo",
|
"Camo",
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
"dxgi",
|
"dxgi",
|
||||||
"echarts",
|
"echarts",
|
||||||
"Everytime",
|
"Everytime",
|
||||||
|
"FABLEGEAR",
|
||||||
"FASTNAME",
|
"FASTNAME",
|
||||||
"flexdirection",
|
"flexdirection",
|
||||||
"FOURCC",
|
"FOURCC",
|
||||||
@@ -108,6 +110,7 @@
|
|||||||
"Maddoxkkm",
|
"Maddoxkkm",
|
||||||
"malum",
|
"malum",
|
||||||
"mantlets",
|
"mantlets",
|
||||||
|
"MECHA",
|
||||||
"metallicness",
|
"metallicness",
|
||||||
"metalness",
|
"metalness",
|
||||||
"minitelrose",
|
"minitelrose",
|
||||||
@@ -145,9 +148,11 @@
|
|||||||
"POSITIVEY",
|
"POSITIVEY",
|
||||||
"POSITIVEZ",
|
"POSITIVEZ",
|
||||||
"precompute",
|
"precompute",
|
||||||
|
"PROGRESSTON",
|
||||||
"Promisable",
|
"Promisable",
|
||||||
"proto",
|
"proto",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
|
"protoc",
|
||||||
"protos",
|
"protos",
|
||||||
"Pyogenics",
|
"Pyogenics",
|
||||||
"ratingleaderboard",
|
"ratingleaderboard",
|
||||||
@@ -203,6 +208,7 @@
|
|||||||
"vitepress",
|
"vitepress",
|
||||||
"Vovko",
|
"Vovko",
|
||||||
"wargaming",
|
"wargaming",
|
||||||
|
"WARHAMMER",
|
||||||
"webp",
|
"webp",
|
||||||
"whitespaces",
|
"whitespaces",
|
||||||
"WHSS",
|
"WHSS",
|
||||||
|
|||||||
+12
-2
@@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkit",
|
"name": "@blitzkit",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.27.11",
|
"version": "1.27.11",
|
||||||
"description": "🎉 Tools for everything World of Tanks Blitz",
|
"description": "🎉 Tools for everything World of Tanks Blitz",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"types": "./types.d.ts",
|
"types": "./types.d.ts",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*",
|
||||||
|
"submodules/*"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:assets": "cd packages/scripts && bun run build:assets",
|
"build:assets": "cd packages/scripts && bun run build:assets",
|
||||||
@@ -41,14 +42,23 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"googleapis": "^144.0.0",
|
"googleapis": "^144.0.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"protobufjs": "^7.5.2",
|
||||||
|
"react": "^19.1.0",
|
||||||
|
"react-dom": "^19.1.0",
|
||||||
"quicklime": "^1.2.0",
|
"quicklime": "^1.2.0",
|
||||||
"sharp": "^0.33.5"
|
"sharp": "^0.33.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@astrojs/react": "^4.3.0",
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
"@types/react": "^19.1.5",
|
||||||
|
"@types/react-dom": "^19.1.5",
|
||||||
"@types/node": "^22.14.1",
|
"@types/node": "^22.14.1",
|
||||||
|
"astro": "^5.8.0",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prisma": "^6.6.0",
|
"prisma": "^6.6.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
"satori": "^0.10.14",
|
"satori": "^0.10.14",
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
"@resvg/resvg-js": "^2.6.2",
|
||||||
"discord.js": "^14.16.3",
|
"discord.js": "^14.16.3",
|
||||||
"react": "^18.3.1",
|
|
||||||
"@radix-ui/colors": "^3.0.0",
|
"@radix-ui/colors": "^3.0.0",
|
||||||
"fuzzysort": "^2.0.4",
|
"fuzzysort": "^2.0.4",
|
||||||
"bepaint": "^0.1.0-beta.3",
|
"bepaint": "^0.1.0-beta.3",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"include": ["src/**/*", "../core/src/blitzkit/supportedLocales.ts", "../i18n/src/unwrapper.ts"]
|
"include": [
|
||||||
|
"src/**/*",
|
||||||
|
"../core/src/blitzkit/supportedLocales.ts",
|
||||||
|
"../i18n/src/unwrapper.ts"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "../../"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@blitzkit/closed": "workspace:*",
|
||||||
"@octokit/plugin-throttling": "^8.2.0",
|
"@octokit/plugin-throttling": "^8.2.0",
|
||||||
"@octokit/rest": "^20.1.1",
|
"@octokit/rest": "^20.1.1",
|
||||||
"@prisma/client": "^6.6.0",
|
"@prisma/client": "^6.6.0",
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { CatalogItem } from '@protos/blitz_items';
|
||||||
|
import { Any } from '@protos/google/protobuf/any';
|
||||||
|
import { MessageFns } from '../protos';
|
||||||
|
|
||||||
|
export class CatalogItemAccessor {
|
||||||
|
private components: Record<string, Any> = {};
|
||||||
|
|
||||||
|
constructor(item: CatalogItem) {
|
||||||
|
for (const component of item.components) {
|
||||||
|
if (
|
||||||
|
component.value === undefined ||
|
||||||
|
component.value.component === undefined
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.components[component.key] = component.value.component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get<Type>(Message: MessageFns<Type>, component: string) {
|
||||||
|
if (component in this.components) {
|
||||||
|
return Message.decode(this.components[component].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unknown component: ${component}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export function entityName(entity: string) {
|
||||||
|
const [_, ...name] = entity.split('.');
|
||||||
|
return name.join('.');
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
export * from './canSplash';
|
export * from './canSplash';
|
||||||
|
export * from './catalogItemAccessor';
|
||||||
export * from './clans';
|
export * from './clans';
|
||||||
export * from './classes';
|
export * from './classes';
|
||||||
export * from './constants';
|
export * from './constants';
|
||||||
|
export * from './entityName';
|
||||||
export * from './equipmentPrice';
|
export * from './equipmentPrice';
|
||||||
export * from './fetchBlitz';
|
export * from './fetchBlitz';
|
||||||
export * from './fetchGlossary';
|
export * from './fetchGlossary';
|
||||||
@@ -18,6 +20,7 @@ export * from './getTankStats';
|
|||||||
export * from './idToRegion';
|
export * from './idToRegion';
|
||||||
export * from './isOnGoingRatingSeason';
|
export * from './isOnGoingRatingSeason';
|
||||||
export * from './isValidBlitzId';
|
export * from './isValidBlitzId';
|
||||||
|
export * from './metadataAccessor';
|
||||||
export * from './nations';
|
export * from './nations';
|
||||||
export * from './normalizeExtra';
|
export * from './normalizeExtra';
|
||||||
export * from './normalizeIds';
|
export * from './normalizeIds';
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { CatalogItem } from '@protos/blitz_items';
|
||||||
|
import { Metadata } from '@protos/blitz_metadata';
|
||||||
|
import { CatalogItemAccessor } from './catalogItemAccessor';
|
||||||
|
|
||||||
|
export class UnpackedMetadataAccessor {
|
||||||
|
private items: Record<string, CatalogItemAccessor> = {};
|
||||||
|
|
||||||
|
constructor(metadata: Metadata) {
|
||||||
|
for (const item of metadata.catalog_items) {
|
||||||
|
if (item.catalog_id in this.items) {
|
||||||
|
throw new Error(`Duplicate catalog ID: ${item.catalog_id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.items[item.catalog_id] = new CatalogItemAccessor(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(item: string) {
|
||||||
|
if (item in this.items) return this.items[item];
|
||||||
|
|
||||||
|
throw new Error(`Unknown catalog ID: ${item}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DiscreteMetadataAccessor {
|
||||||
|
constructor(private base: string) {}
|
||||||
|
|
||||||
|
async get(item: string) {
|
||||||
|
const response = await fetch(`${this.base}/${item}.pb`);
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(`Unknown catalog ID: ${item}`);
|
||||||
|
|
||||||
|
const buffer = await response.arrayBuffer();
|
||||||
|
const catalogItem = CatalogItem.decode(new Uint8Array(buffer));
|
||||||
|
|
||||||
|
return new CatalogItemAccessor(catalogItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,4 +46,5 @@ export * from './gallery';
|
|||||||
export * from './metaSortTank';
|
export * from './metaSortTank';
|
||||||
export * from './popularTanks';
|
export * from './popularTanks';
|
||||||
export * from './romanize';
|
export * from './romanize';
|
||||||
|
export * from './slugify';
|
||||||
export * from './youtubers';
|
export * from './youtubers';
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { deburr } from 'lodash-es';
|
||||||
|
|
||||||
|
const nonAlphanumericRegex = /[^a-z0-9]/g;
|
||||||
|
const multipleDashesRegex = /--+/g;
|
||||||
|
const trailingDashRegex = /-$/g;
|
||||||
|
const leadingDashRegex = /^-/g;
|
||||||
|
|
||||||
|
export function slugify(name: string) {
|
||||||
|
let slug = deburr(name).toLowerCase();
|
||||||
|
slug = slug.replaceAll(nonAlphanumericRegex, '-');
|
||||||
|
slug = slug.replaceAll(multipleDashesRegex, '-');
|
||||||
|
slug = slug.replaceAll(trailingDashRegex, '');
|
||||||
|
slug = slug.replaceAll(leadingDashRegex, '');
|
||||||
|
|
||||||
|
return slug;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { deburr } from 'lodash-es';
|
import { deburr } from 'lodash-es';
|
||||||
import { SUPPORTED_LOCALES } from '../../../i18n/src/strings';
|
|
||||||
import { I18nString } from '../protos';
|
import { I18nString } from '../protos';
|
||||||
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
|
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
|
||||||
import { fetchTankDefinitions } from './tankDefinitions';
|
import { fetchTankDefinitions } from './tankDefinitions';
|
||||||
@@ -26,8 +26,8 @@ export async function fetchTankNames() {
|
|||||||
searchableNameDeburr,
|
searchableNameDeburr,
|
||||||
camouflages: tank.camouflages
|
camouflages: tank.camouflages
|
||||||
?.map((id) =>
|
?.map((id) =>
|
||||||
SUPPORTED_LOCALES.map(
|
locales.supported.map(
|
||||||
(locale) =>
|
({ locale }) =>
|
||||||
camouflageDefinitions.camouflages[id]?.name.locales[locale],
|
camouflageDefinitions.camouflages[id]?.name.locales[locale],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -42,9 +42,11 @@ export async function fetchTankNames() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const SEARCH_KEYS = [
|
export const SEARCH_KEYS = [
|
||||||
...SUPPORTED_LOCALES.map((locale) => [
|
...locales.supported
|
||||||
`searchableName.locales.${locale}`,
|
.map(({ locale }) => [
|
||||||
`searchableNameDeburr.locales.${locale}`,
|
`searchableName.locales.${locale}`,
|
||||||
]).flat(),
|
`searchableNameDeburr.locales.${locale}`,
|
||||||
|
])
|
||||||
|
.flat(),
|
||||||
'camouflages',
|
'camouflages',
|
||||||
];
|
];
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/average_definitions.proto
|
// source: average_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -58,7 +58,7 @@ export interface Samples {
|
|||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseAverageDefinitions(): AverageDefinitions {
|
export function createBaseAverageDefinitions(): AverageDefinitions {
|
||||||
return { averages: {}, samples: createBaseSamples(), time: 0 };
|
return { averages: {}, samples: createBaseSamples(), time: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
export function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||||
return { key: 0, value: createBaseAverageDefinitionsEntry() };
|
return { key: 0, value: createBaseAverageDefinitionsEntry() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,12 +251,12 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? AverageDefinitionsEntry.fromPartial(object.value)
|
? AverageDefinitionsEntry.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseAverageDefinitionsEntry();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
export function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||||
return {
|
return {
|
||||||
mu: createBaseAverageDefinitionsAllStats(),
|
mu: createBaseAverageDefinitionsAllStats(),
|
||||||
sigma: createBaseAverageDefinitionsAllStats(),
|
sigma: createBaseAverageDefinitionsAllStats(),
|
||||||
@@ -377,7 +377,7 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
export function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||||
return {
|
return {
|
||||||
battles: 0,
|
battles: 0,
|
||||||
capture_points: 0,
|
capture_points: 0,
|
||||||
@@ -738,7 +738,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseSamples(): Samples {
|
export function createBaseSamples(): Samples {
|
||||||
return { d_1: 0, d_7: 0, d_30: 0, d_60: 0, d_90: 0, d_120: 0, total: 0 };
|
return { d_1: 0, d_7: 0, d_30: 0, d_60: 0, d_90: 0, d_120: 0, total: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message CamouflageDefinitions {
|
message CamouflageDefinitions {
|
||||||
map<uint32, Camouflage> camouflages = 1;
|
map<uint32, Camouflage> camouflages = 1;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/camouflage_definitions.proto
|
// source: camouflage_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ export interface Camouflage {
|
|||||||
tank_name_full?: I18nString | undefined;
|
tank_name_full?: I18nString | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
export function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||||
return { camouflages: {} };
|
return { camouflages: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
export function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||||
return { key: 0, value: createBaseCamouflage() };
|
return { key: 0, value: createBaseCamouflage() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,12 +185,12 @@ export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefini
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Camouflage.fromPartial(object.value)
|
? Camouflage.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseCamouflage();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseCamouflage(): Camouflage {
|
export function createBaseCamouflage(): Camouflage {
|
||||||
return { id: 0, name: createBaseI18nString(), tank_name: undefined, tank_name_full: undefined };
|
return { id: 0, name: createBaseI18nString(), tank_name: undefined, tank_name_full: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message ConsumableDefinitions {
|
message ConsumableDefinitions {
|
||||||
map<uint32, Consumable> consumables = 1;
|
map<uint32, Consumable> consumables = 1;
|
||||||
|
|||||||
@@ -2,23 +2,23 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/consumable_definitions.proto
|
// source: consumable_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
export enum ConsumableTankCategoryFilterCategory {
|
export enum ConsumableTankCategoryFilterCategory {
|
||||||
CLIP = 0,
|
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
||||||
switch (object) {
|
switch (object) {
|
||||||
case 0:
|
case 0:
|
||||||
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
||||||
return ConsumableTankCategoryFilterCategory.CLIP;
|
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
|
||||||
default:
|
default:
|
||||||
throw new globalThis.Error(
|
throw new globalThis.Error(
|
||||||
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
||||||
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
|
|||||||
|
|
||||||
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
||||||
switch (object) {
|
switch (object) {
|
||||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||||
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
||||||
default:
|
default:
|
||||||
throw new globalThis.Error(
|
throw new globalThis.Error(
|
||||||
@@ -82,7 +82,7 @@ export interface ConsumableTankNationFilter {
|
|||||||
nations: string[];
|
nations: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
export function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||||
return { consumables: {} };
|
return { consumables: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
export function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||||
return { key: 0, value: createBaseConsumable() };
|
return { key: 0, value: createBaseConsumable() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,12 +241,12 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Consumable.fromPartial(object.value)
|
? Consumable.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseConsumable();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumable(): Consumable {
|
export function createBaseConsumable(): Consumable {
|
||||||
return {
|
return {
|
||||||
id: 0,
|
id: 0,
|
||||||
name: createBaseI18nString(),
|
name: createBaseI18nString(),
|
||||||
@@ -416,7 +416,7 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
export function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
||||||
return { filter_type: undefined };
|
return { filter_type: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
export function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||||
return { min: 0, max: 0 };
|
return { min: 0, max: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,7 +640,7 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
export function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
||||||
return { ids: [] };
|
return { ids: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,7 +710,7 @@ export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
export function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||||
return { categories: [] };
|
return { categories: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,7 +784,7 @@ export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilt
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
export function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||||
return { nations: [] };
|
return { nations: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message EquipmentDefinitions {
|
message EquipmentDefinitions {
|
||||||
map<string, EquipmentPreset> presets = 1;
|
map<string, EquipmentPreset> presets = 1;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/equipment_definitions.proto
|
// source: equipment_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export interface EquipmentSlot {
|
|||||||
right: number;
|
right: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
export function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||||
return { presets: {}, equipments: {} };
|
return { presets: {}, equipments: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
export function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||||
return { key: "", value: createBaseEquipmentPreset() };
|
return { key: "", value: createBaseEquipmentPreset() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,12 +236,12 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
|||||||
message.key = object.key ?? "";
|
message.key = object.key ?? "";
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? EquipmentPreset.fromPartial(object.value)
|
? EquipmentPreset.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseEquipmentPreset();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
export function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||||
return { key: 0, value: createBaseEquipment() };
|
return { key: 0, value: createBaseEquipment() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,12 +318,12 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Equipment.fromPartial(object.value)
|
? Equipment.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseEquipment();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseEquipment(): Equipment {
|
export function createBaseEquipment(): Equipment {
|
||||||
return { name: createBaseI18nString(), description: createBaseI18nString() };
|
return { name: createBaseI18nString(), description: createBaseI18nString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ export const Equipment: MessageFns<Equipment> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseEquipmentPreset(): EquipmentPreset {
|
export function createBaseEquipmentPreset(): EquipmentPreset {
|
||||||
return { slots: [] };
|
return { slots: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseEquipmentSlot(): EquipmentSlot {
|
export function createBaseEquipmentSlot(): EquipmentSlot {
|
||||||
return { left: 0, right: 0 };
|
return { left: 0, right: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message Gallery {
|
message Gallery {
|
||||||
repeated Avatar avatars = 1;
|
repeated Avatar avatars = 1;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/gallery.proto
|
// source: gallery.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from './i18n';
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = 'blitzkit';
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
export interface Gallery {
|
export interface Gallery {
|
||||||
avatars: Avatar[];
|
avatars: Avatar[];
|
||||||
@@ -20,15 +20,12 @@ export interface Avatar {
|
|||||||
extension: string;
|
extension: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseGallery(): Gallery {
|
export function createBaseGallery(): Gallery {
|
||||||
return { avatars: [] };
|
return { avatars: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Gallery: MessageFns<Gallery> = {
|
export const Gallery: MessageFns<Gallery> = {
|
||||||
encode(
|
encode(message: Gallery, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
message: Gallery,
|
|
||||||
writer: BinaryWriter = new BinaryWriter(),
|
|
||||||
): BinaryWriter {
|
|
||||||
for (const v of message.avatars) {
|
for (const v of message.avatars) {
|
||||||
Avatar.encode(v!, writer.uint32(10).fork()).join();
|
Avatar.encode(v!, writer.uint32(10).fork()).join();
|
||||||
}
|
}
|
||||||
@@ -36,8 +33,7 @@ export const Gallery: MessageFns<Gallery> = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
||||||
const reader =
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
||||||
let end = length === undefined ? reader.len : reader.pos + length;
|
let end = length === undefined ? reader.len : reader.pos + length;
|
||||||
const message = createBaseGallery();
|
const message = createBaseGallery();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
@@ -62,9 +58,7 @@ export const Gallery: MessageFns<Gallery> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Gallery {
|
fromJSON(object: any): Gallery {
|
||||||
return {
|
return {
|
||||||
avatars: globalThis.Array.isArray(object?.avatars)
|
avatars: globalThis.Array.isArray(object?.avatars) ? object.avatars.map((e: any) => Avatar.fromJSON(e)) : [],
|
||||||
? object.avatars.map((e: any) => Avatar.fromJSON(e))
|
|
||||||
: [],
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -86,30 +80,26 @@ export const Gallery: MessageFns<Gallery> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseAvatar(): Avatar {
|
export function createBaseAvatar(): Avatar {
|
||||||
return { id: '', name: createBaseI18nString(), extension: '' };
|
return { id: "", name: createBaseI18nString(), extension: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Avatar: MessageFns<Avatar> = {
|
export const Avatar: MessageFns<Avatar> = {
|
||||||
encode(
|
encode(message: Avatar, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
message: Avatar,
|
if (message.id !== "") {
|
||||||
writer: BinaryWriter = new BinaryWriter(),
|
|
||||||
): BinaryWriter {
|
|
||||||
if (message.id !== '') {
|
|
||||||
writer.uint32(10).string(message.id);
|
writer.uint32(10).string(message.id);
|
||||||
}
|
}
|
||||||
if (message.name !== undefined) {
|
if (message.name !== undefined) {
|
||||||
I18nString.encode(message.name, writer.uint32(18).fork()).join();
|
I18nString.encode(message.name, writer.uint32(18).fork()).join();
|
||||||
}
|
}
|
||||||
if (message.extension !== '') {
|
if (message.extension !== "") {
|
||||||
writer.uint32(26).string(message.extension);
|
writer.uint32(26).string(message.extension);
|
||||||
}
|
}
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
||||||
const reader =
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
||||||
let end = length === undefined ? reader.len : reader.pos + length;
|
let end = length === undefined ? reader.len : reader.pos + length;
|
||||||
const message = createBaseAvatar();
|
const message = createBaseAvatar();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
@@ -150,23 +140,21 @@ export const Avatar: MessageFns<Avatar> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Avatar {
|
fromJSON(object: any): Avatar {
|
||||||
return {
|
return {
|
||||||
id: globalThis.String(assertSet('Avatar.id', object.id)),
|
id: globalThis.String(assertSet("Avatar.id", object.id)),
|
||||||
name: I18nString.fromJSON(assertSet('Avatar.name', object.name)),
|
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
|
||||||
extension: globalThis.String(
|
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
|
||||||
assertSet('Avatar.extension', object.extension),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: Avatar): unknown {
|
toJSON(message: Avatar): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.id !== '') {
|
if (message.id !== "") {
|
||||||
obj.id = message.id;
|
obj.id = message.id;
|
||||||
}
|
}
|
||||||
if (message.name !== undefined) {
|
if (message.name !== undefined) {
|
||||||
obj.name = I18nString.toJSON(message.name);
|
obj.name = I18nString.toJSON(message.name);
|
||||||
}
|
}
|
||||||
if (message.extension !== '') {
|
if (message.extension !== "") {
|
||||||
obj.extension = message.extension;
|
obj.extension = message.extension;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -177,43 +165,27 @@ export const Avatar: MessageFns<Avatar> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<Avatar>, I>>(object: I): Avatar {
|
fromPartial<I extends Exact<DeepPartial<Avatar>, I>>(object: I): Avatar {
|
||||||
const message = createBaseAvatar();
|
const message = createBaseAvatar();
|
||||||
message.id = object.id ?? '';
|
message.id = object.id ?? "";
|
||||||
message.name =
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
object.name !== undefined && object.name !== null
|
? I18nString.fromPartial(object.name)
|
||||||
? I18nString.fromPartial(object.name)
|
: createBaseI18nString();
|
||||||
: createBaseI18nString();
|
message.extension = object.extension ?? "";
|
||||||
message.extension = object.extension ?? '';
|
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Builtin =
|
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||||
| Date
|
|
||||||
| Function
|
|
||||||
| Uint8Array
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
export type DeepPartial<T> = T extends Builtin
|
export type DeepPartial<T> = T extends Builtin ? T
|
||||||
? T
|
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||||
: T extends globalThis.Array<infer U>
|
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||||
? globalThis.Array<DeepPartial<U>>
|
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
|
||||||
: T extends ReadonlyArray<infer U>
|
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||||
? ReadonlyArray<DeepPartial<U>>
|
: Partial<T>;
|
||||||
: T extends { $case: string; value: unknown }
|
|
||||||
? { $case: T['$case']; value?: DeepPartial<T['value']> }
|
|
||||||
: T extends {}
|
|
||||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
|
||||||
: Partial<T>;
|
|
||||||
|
|
||||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||||
export type Exact<P, I extends P> = P extends Builtin
|
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||||
? P
|
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
|
|
||||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
function isSet(value: any): boolean {
|
function isSet(value: any): boolean {
|
||||||
return value !== null && value !== undefined;
|
return value !== null && value !== undefined;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message GameDefinitions {
|
message GameDefinitions {
|
||||||
required string version = 1;
|
required string version = 1;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/game_definitions.proto
|
// source: game_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export interface GameModeRole {
|
|||||||
consumables: number[];
|
consumables: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseGameDefinitions(): GameDefinitions {
|
export function createBaseGameDefinitions(): GameDefinitions {
|
||||||
return { version: "", nations: [], gameModes: {}, roles: {} };
|
return { version: "", nations: [], gameModes: {}, roles: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
export function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||||
return { key: 0, value: createBaseGameMode() };
|
return { key: 0, value: createBaseGameMode() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,12 +260,12 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? GameMode.fromPartial(object.value)
|
? GameMode.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseGameMode();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
export function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||||
return { key: 0, value: createBaseGameModeRole() };
|
return { key: 0, value: createBaseGameModeRole() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,12 +338,12 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? GameModeRole.fromPartial(object.value)
|
? GameModeRole.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseGameModeRole();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseGameMode(): GameMode {
|
export function createBaseGameMode(): GameMode {
|
||||||
return { name: createBaseI18nString() };
|
return { name: createBaseI18nString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ export const GameMode: MessageFns<GameMode> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseGameModeRole(): GameModeRole {
|
export function createBaseGameModeRole(): GameModeRole {
|
||||||
return { provisions: [], consumables: [] };
|
return { provisions: [], consumables: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/i18n.proto
|
// source: i18n.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -97,7 +97,7 @@ export const I18nString: MessageFns<I18nString> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
export function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||||
return { key: "", value: "" };
|
return { key: "", value: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message MapDefinitions {
|
message MapDefinitions {
|
||||||
map<int32, MapDefinition> maps = 1;
|
map<int32, MapDefinition> maps = 1;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/map_definitions.proto
|
// source: map_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ export interface MapDefinition {
|
|||||||
name: I18nString;
|
name: I18nString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseMapDefinitions(): MapDefinitions {
|
export function createBaseMapDefinitions(): MapDefinitions {
|
||||||
return { maps: {} };
|
return { maps: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
export function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||||
return { key: 0, value: createBaseMapDefinition() };
|
return { key: 0, value: createBaseMapDefinition() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +176,12 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? MapDefinition.fromPartial(object.value)
|
? MapDefinition.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseMapDefinition();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseMapDefinition(): MapDefinition {
|
export function createBaseMapDefinition(): MapDefinition {
|
||||||
return { id: 0, name: createBaseI18nString() };
|
return { id: 0, name: createBaseI18nString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/model_definitions.proto
|
// source: model_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -110,7 +110,7 @@ export interface PitchLimitsExtrema {
|
|||||||
range: number;
|
range: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseModelDefinitions(): ModelDefinitions {
|
export function createBaseModelDefinitions(): ModelDefinitions {
|
||||||
return { models: {} };
|
return { models: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ export const ModelDefinitions: MessageFns<ModelDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseModelDefinitions_ModelsEntry(): ModelDefinitions_ModelsEntry {
|
export function createBaseModelDefinitions_ModelsEntry(): ModelDefinitions_ModelsEntry {
|
||||||
return { key: 0, value: createBaseModelDefinition() };
|
return { key: 0, value: createBaseModelDefinition() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,12 +265,12 @@ export const ModelDefinitions_ModelsEntry: MessageFns<ModelDefinitions_ModelsEnt
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? ModelDefinition.fromPartial(object.value)
|
? ModelDefinition.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseModelDefinition();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseModelDefinition(): ModelDefinition {
|
export function createBaseModelDefinition(): ModelDefinition {
|
||||||
return {
|
return {
|
||||||
armor: createBaseArmor(),
|
armor: createBaseArmor(),
|
||||||
turret_origin: createBaseVector3(),
|
turret_origin: createBaseVector3(),
|
||||||
@@ -472,7 +472,7 @@ export const ModelDefinition: MessageFns<ModelDefinition> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseModelDefinition_TurretsEntry(): ModelDefinition_TurretsEntry {
|
export function createBaseModelDefinition_TurretsEntry(): ModelDefinition_TurretsEntry {
|
||||||
return { key: 0, value: createBaseTurretModelDefinition() };
|
return { key: 0, value: createBaseTurretModelDefinition() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,12 +545,12 @@ export const ModelDefinition_TurretsEntry: MessageFns<ModelDefinition_TurretsEnt
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? TurretModelDefinition.fromPartial(object.value)
|
? TurretModelDefinition.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseTurretModelDefinition();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseModelDefinition_TracksEntry(): ModelDefinition_TracksEntry {
|
export function createBaseModelDefinition_TracksEntry(): ModelDefinition_TracksEntry {
|
||||||
return { key: 0, value: createBaseTrackModelDefinition() };
|
return { key: 0, value: createBaseTrackModelDefinition() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,12 +623,12 @@ export const ModelDefinition_TracksEntry: MessageFns<ModelDefinition_TracksEntry
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? TrackModelDefinition.fromPartial(object.value)
|
? TrackModelDefinition.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseTrackModelDefinition();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseArmor(): Armor {
|
export function createBaseArmor(): Armor {
|
||||||
return { thickness: {}, spaced: [] };
|
return { thickness: {}, spaced: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +738,7 @@ export const Armor: MessageFns<Armor> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseArmor_ThicknessEntry(): Armor_ThicknessEntry {
|
export function createBaseArmor_ThicknessEntry(): Armor_ThicknessEntry {
|
||||||
return { key: 0, value: 0 };
|
return { key: 0, value: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,7 +814,7 @@ export const Armor_ThicknessEntry: MessageFns<Armor_ThicknessEntry> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseVector3(): Vector3 {
|
export function createBaseVector3(): Vector3 {
|
||||||
return { x: 0, y: 0, z: 0 };
|
return { x: 0, y: 0, z: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,7 +906,7 @@ export const Vector3: MessageFns<Vector3> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseInitialTurretRotation(): InitialTurretRotation {
|
export function createBaseInitialTurretRotation(): InitialTurretRotation {
|
||||||
return { yaw: 0, pitch: 0, roll: 0 };
|
return { yaw: 0, pitch: 0, roll: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,7 +998,7 @@ export const InitialTurretRotation: MessageFns<InitialTurretRotation> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseTurretModelDefinition(): TurretModelDefinition {
|
export function createBaseTurretModelDefinition(): TurretModelDefinition {
|
||||||
return {
|
return {
|
||||||
bounding_box: createBaseBoundingBox(),
|
bounding_box: createBaseBoundingBox(),
|
||||||
armor: createBaseArmor(),
|
armor: createBaseArmor(),
|
||||||
@@ -1173,7 +1173,7 @@ export const TurretModelDefinition: MessageFns<TurretModelDefinition> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseTurretModelDefinition_GunsEntry(): TurretModelDefinition_GunsEntry {
|
export function createBaseTurretModelDefinition_GunsEntry(): TurretModelDefinition_GunsEntry {
|
||||||
return { key: 0, value: createBaseGunModelDefinition() };
|
return { key: 0, value: createBaseGunModelDefinition() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1248,12 +1248,12 @@ export const TurretModelDefinition_GunsEntry: MessageFns<TurretModelDefinition_G
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? GunModelDefinition.fromPartial(object.value)
|
? GunModelDefinition.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseGunModelDefinition();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseYawLimits(): YawLimits {
|
export function createBaseYawLimits(): YawLimits {
|
||||||
return { min: 0, max: 0 };
|
return { min: 0, max: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1329,7 +1329,7 @@ export const YawLimits: MessageFns<YawLimits> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseBoundingBox(): BoundingBox {
|
export function createBaseBoundingBox(): BoundingBox {
|
||||||
return { min: createBaseVector3(), max: createBaseVector3() };
|
return { min: createBaseVector3(), max: createBaseVector3() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1409,7 +1409,7 @@ export const BoundingBox: MessageFns<BoundingBox> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseTrackModelDefinition(): TrackModelDefinition {
|
export function createBaseTrackModelDefinition(): TrackModelDefinition {
|
||||||
return { thickness: 0, origin: createBaseVector3() };
|
return { thickness: 0, origin: createBaseVector3() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1487,7 +1487,7 @@ export const TrackModelDefinition: MessageFns<TrackModelDefinition> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseGunModelDefinition(): GunModelDefinition {
|
export function createBaseGunModelDefinition(): GunModelDefinition {
|
||||||
return { armor: createBaseArmor(), thickness: 0, model_id: 0, pitch: createBasePitchLimits(), mask: undefined };
|
return { armor: createBaseArmor(), thickness: 0, model_id: 0, pitch: createBasePitchLimits(), mask: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1615,7 +1615,7 @@ export const GunModelDefinition: MessageFns<GunModelDefinition> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBasePitchLimits(): PitchLimits {
|
export function createBasePitchLimits(): PitchLimits {
|
||||||
return { min: 0, max: 0, front: undefined, back: undefined, transition: undefined };
|
return { min: 0, max: 0, front: undefined, back: undefined, transition: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1743,7 +1743,7 @@ export const PitchLimits: MessageFns<PitchLimits> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBasePitchLimitsExtrema(): PitchLimitsExtrema {
|
export function createBasePitchLimitsExtrema(): PitchLimitsExtrema {
|
||||||
return { min: 0, max: 0, range: 0 };
|
return { min: 0, max: 0, range: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/popular_tanks.proto
|
// source: popular_tanks.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -19,7 +19,7 @@ export interface PopularTank {
|
|||||||
views: number;
|
views: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBasePopularTanks(): PopularTanks {
|
export function createBasePopularTanks(): PopularTanks {
|
||||||
return { tanks: [] };
|
return { tanks: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBasePopularTank(): PopularTank {
|
export function createBasePopularTank(): PopularTank {
|
||||||
return { id: 0, views: 0 };
|
return { id: 0, views: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/consumable_definitions.proto";
|
import "consumable_definitions.proto";
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message ProvisionDefinitions {
|
message ProvisionDefinitions {
|
||||||
map<uint32, Provision> provisions = 1;
|
map<uint32, Provision> provisions = 1;
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/provision_definitions.proto
|
// source: provision_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { ConsumableTankFilter } from "./consumable_definitions";
|
import { ConsumableTankFilter } from "./consumable_definitions";
|
||||||
import { I18nString, createBaseI18nString } from "./i18n";
|
import { createBaseI18nString, I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export interface Provision {
|
|||||||
exclude: ConsumableTankFilter[];
|
exclude: ConsumableTankFilter[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
export function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||||
return { provisions: {} };
|
return { provisions: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
export function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||||
return { key: 0, value: createBaseProvision() };
|
return { key: 0, value: createBaseProvision() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,12 +188,12 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Provision.fromPartial(object.value)
|
? Provision.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseProvision();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseProvision(): Provision {
|
export function createBaseProvision(): Provision {
|
||||||
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
|
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/rating_leaderboard.proto
|
// source: rating_leaderboard.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -36,7 +36,7 @@ export interface RatingLeaderboardEntryV2 {
|
|||||||
kills: number;
|
kills: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseRatingLeaderboard(): RatingLeaderboard {
|
export function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||||
return { version: undefined };
|
return { version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
export function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||||
return { entries: [] };
|
return { entries: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
export function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
||||||
return { id: 0, score: 0 };
|
return { id: 0, score: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
export function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
||||||
return { entries: [] };
|
return { entries: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
export function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
||||||
return { id: 0, score: 0, battles: 0, wins: 0, survived: 0, damage: 0, kills: 0 };
|
return { id: 0, score: 0, battles: 0, wins: 0, survived: 0, damage: 0, kills: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/reviews.proto
|
// source: reviews.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -28,7 +28,7 @@ export interface Video {
|
|||||||
author: string;
|
author: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseReviews(): Reviews {
|
export function createBaseReviews(): Reviews {
|
||||||
return { reviews: {} };
|
return { reviews: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ export const Reviews: MessageFns<Reviews> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
export function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||||
return { key: 0, value: createBaseReview() };
|
return { key: 0, value: createBaseReview() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,12 +180,12 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Review.fromPartial(object.value)
|
? Review.fromPartial(object.value)
|
||||||
: undefined;
|
: createBaseReview();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseReview(): Review {
|
export function createBaseReview(): Review {
|
||||||
return { last_updated: 0, videos: [] };
|
return { last_updated: 0, videos: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ export const Review: MessageFns<Review> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseVideo(): Video {
|
export function createBaseVideo(): Video {
|
||||||
return { id: "", author: "" };
|
return { id: "", author: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.2.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/skill_definitions.proto
|
// source: skill_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -23,7 +23,7 @@ export interface Skill {
|
|||||||
skills: string[];
|
skills: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBaseSkillDefinitions(): SkillDefinitions {
|
export function createBaseSkillDefinitions(): SkillDefinitions {
|
||||||
return { classes: {} };
|
return { classes: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
export function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||||
return { key: 0, value: createBaseSkill() };
|
return { key: 0, value: createBaseSkill() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,12 +175,14 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
|||||||
): SkillDefinitions_ClassesEntry {
|
): SkillDefinitions_ClassesEntry {
|
||||||
const message = createBaseSkillDefinitions_ClassesEntry();
|
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null) ? Skill.fromPartial(object.value) : undefined;
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
|
? Skill.fromPartial(object.value)
|
||||||
|
: createBaseSkill();
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createBaseSkill(): Skill {
|
export function createBaseSkill(): Skill {
|
||||||
return { skills: [] };
|
return { skills: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message TankDefinitions {
|
message TankDefinitions {
|
||||||
map<uint32, TankDefinition> tanks = 1;
|
map<uint32, TankDefinition> tanks = 1;
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"include": ["src/**/*", "../i18n/src/strings.ts"]
|
"include": ["src/**/*", "../i18n/src/strings.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "../../"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,89 +1,8 @@
|
|||||||
import { merge } from 'ts-deepmerge';
|
import type en from '../strings/en.json';
|
||||||
import en from '../strings/en.json';
|
|
||||||
import es from '../strings/es.json';
|
|
||||||
import fr from '../strings/fr.json';
|
|
||||||
import ja from '../strings/ja.json';
|
|
||||||
import pl from '../strings/pl.json';
|
|
||||||
import pt from '../strings/pt.json';
|
|
||||||
import ru from '../strings/ru.json';
|
|
||||||
import uk from '../strings/uk.json';
|
|
||||||
import zh from '../strings/zh.json';
|
|
||||||
|
|
||||||
export type BlitzKitStrings = typeof en;
|
export type BlitzKitStrings = typeof en;
|
||||||
|
|
||||||
const stringsRaw = { en, es, fr, ja, pl, pt, ru, uk, zh };
|
export const SUPPORTED_LOCALE_FLAGS: Record<string, string> = {
|
||||||
|
|
||||||
export const SUPPORTED_LOCALES = Object.keys(stringsRaw) as SupportedLocale[];
|
|
||||||
|
|
||||||
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
|
|
||||||
|
|
||||||
function redact(string: string) {
|
|
||||||
const matches = [...string.matchAll(/%s\d+/g)];
|
|
||||||
const characters = string
|
|
||||||
.split('')
|
|
||||||
.map((char) => (char === ' ' ? ' ' : '█')) as string[];
|
|
||||||
|
|
||||||
matches.forEach((match) => {
|
|
||||||
const start = match.index;
|
|
||||||
const matchText = match[0];
|
|
||||||
for (let i = 0; i < matchText.length; i++) {
|
|
||||||
characters[start + i] = matchText[i];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return characters.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
function nuke(object: TranslationTree) {
|
|
||||||
for (const key in object) {
|
|
||||||
const typedKey = key as keyof typeof object;
|
|
||||||
|
|
||||||
if (typeof object[typedKey] === 'string') {
|
|
||||||
const value = object[typedKey];
|
|
||||||
object[typedKey] = redact(value as string);
|
|
||||||
} else nuke(object[typedKey] as TranslationTree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const stringsPartial: Partial<Record<SupportedLocale, TranslationTree>> = {};
|
|
||||||
|
|
||||||
for (const locale in stringsRaw) {
|
|
||||||
if (locale === DEFAULT_LOCALE) {
|
|
||||||
stringsPartial[DEFAULT_LOCALE] = stringsRaw[DEFAULT_LOCALE];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const localeStrings = stringsRaw[locale as SupportedLocale];
|
|
||||||
stringsPartial[locale as SupportedLocale] = merge(
|
|
||||||
stringsRaw[DEFAULT_LOCALE],
|
|
||||||
localeStrings,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') {
|
|
||||||
nuke(stringsPartial[locale as SupportedLocale]!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const STRINGS = stringsPartial as Record<
|
|
||||||
SupportedLocale,
|
|
||||||
BlitzKitStrings
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type SupportedLocale = keyof typeof stringsRaw;
|
|
||||||
|
|
||||||
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
|
|
||||||
en: 'en',
|
|
||||||
es: 'es',
|
|
||||||
fr: 'fr',
|
|
||||||
ja: 'ja',
|
|
||||||
pt: 'pt',
|
|
||||||
ru: 'ru',
|
|
||||||
uk: 'uk',
|
|
||||||
zh: 'zh-Hans',
|
|
||||||
pl: 'pl',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
|
||||||
en: '🇺🇸',
|
en: '🇺🇸',
|
||||||
es: '🇪🇸',
|
es: '🇪🇸',
|
||||||
fr: '🇫🇷',
|
fr: '🇫🇷',
|
||||||
@@ -94,7 +13,3 @@ export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
|||||||
zh: '🇨🇳',
|
zh: '🇨🇳',
|
||||||
pl: '🇵🇱',
|
pl: '🇵🇱',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TranslationTree = { [key: string]: TranslationNode };
|
|
||||||
|
|
||||||
export type TranslationNode = string | TranslationTree;
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { I18nString } from '@blitzkit/core';
|
import { I18nString } from '@blitzkit/core';
|
||||||
import { DEFAULT_LOCALE } from './strings';
|
import locales from '../locales.json' with { type: 'json' };
|
||||||
|
|
||||||
export function unwrapper(locale: string) {
|
export function unwrapper(locale: string) {
|
||||||
return function (i18nString: I18nString) {
|
return function (i18nString: I18nString) {
|
||||||
@@ -7,6 +7,6 @@ export function unwrapper(locale: string) {
|
|||||||
return i18nString.locales[locale];
|
return i18nString.locales[locale];
|
||||||
}
|
}
|
||||||
|
|
||||||
return i18nString.locales[DEFAULT_LOCALE];
|
return i18nString.locales[locales.default];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,18 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"common": {
|
"common": {
|
||||||
|
"tiers": {
|
||||||
|
"0": "Unknown tier",
|
||||||
|
"1": "I",
|
||||||
|
"2": "II",
|
||||||
|
"3": "III",
|
||||||
|
"4": "IV",
|
||||||
|
"5": "V",
|
||||||
|
"6": "VI",
|
||||||
|
"7": "VII",
|
||||||
|
"8": "Vintage"
|
||||||
|
},
|
||||||
|
|
||||||
"units": {
|
"units": {
|
||||||
"m": "%s1m",
|
"m": "%s1m",
|
||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
@@ -86,15 +98,44 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"nations": {
|
"nations": {
|
||||||
"ussr": "U.S.S.R.",
|
"0": "Unknown nation",
|
||||||
"germany": "Germany",
|
"1": "U.S.S.R.",
|
||||||
"usa": "U.S.A.",
|
"2": "Germany",
|
||||||
"china": "China",
|
"3": "U.S.A.",
|
||||||
"uk": "U.K.",
|
"4": "China",
|
||||||
"france": "France",
|
"5": "France",
|
||||||
"japan": "Japan",
|
"6": "U.K.",
|
||||||
"european": "European Nation",
|
"7": "Japan",
|
||||||
"other": "Hybrid Nation"
|
"8": "Europe",
|
||||||
|
"9": "Poland",
|
||||||
|
"10": "Australia",
|
||||||
|
"11": "Canada",
|
||||||
|
"12": "Italy",
|
||||||
|
"13": "Finland",
|
||||||
|
"14": "Czech",
|
||||||
|
"15": "Hybrid Nation",
|
||||||
|
"16": "GDR",
|
||||||
|
"17": "Ireland",
|
||||||
|
"18": "Scotland",
|
||||||
|
"19": "Sweden",
|
||||||
|
"20": "Argo Coalition",
|
||||||
|
"21": "Titan Lab",
|
||||||
|
"22": "Defender",
|
||||||
|
"23": "Progresston",
|
||||||
|
"24": "Wasteland",
|
||||||
|
"25": "Hunters Moon",
|
||||||
|
"26": "Cold Front",
|
||||||
|
"27": "The Explorer",
|
||||||
|
"28": "Fablegear",
|
||||||
|
"29": "Outlaws",
|
||||||
|
"30": "GUP",
|
||||||
|
"31": "Dune",
|
||||||
|
"32": "Terminator",
|
||||||
|
"33": "Warhammer",
|
||||||
|
"34": "Valkirya Chronicles",
|
||||||
|
"35": "Mecha",
|
||||||
|
"36": "TMNT",
|
||||||
|
"37": "Star Trek"
|
||||||
},
|
},
|
||||||
|
|
||||||
"nations_adjectives": {
|
"nations_adjectives": {
|
||||||
@@ -109,6 +150,14 @@
|
|||||||
"other": "Hybrid"
|
"other": "Hybrid"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"tank_class": {
|
||||||
|
"0": "Unknown Class",
|
||||||
|
"1": "Heavy",
|
||||||
|
"2": "Light",
|
||||||
|
"3": "Medium",
|
||||||
|
"4": "Tank destroyer"
|
||||||
|
},
|
||||||
|
|
||||||
"tank_class_short": {
|
"tank_class_short": {
|
||||||
"-1": "unrecognized",
|
"-1": "unrecognized",
|
||||||
"0": "Light",
|
"0": "Light",
|
||||||
@@ -133,10 +182,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"tree_type": {
|
"tree_type": {
|
||||||
"-1": "unrecognized",
|
"0": "Unknown tree type",
|
||||||
"0": "Tech tree",
|
"1": "Common",
|
||||||
"1": "Premium",
|
"2": "Premium",
|
||||||
"2": "Collector"
|
"3": "Collector"
|
||||||
},
|
},
|
||||||
|
|
||||||
"regions": {
|
"regions": {
|
||||||
@@ -988,6 +1037,8 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"meta": {
|
"meta": {
|
||||||
|
"compensation": "Compensation",
|
||||||
|
"free": "Free",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"compare": "Compare",
|
"compare": "Compare",
|
||||||
"swap": {
|
"swap": {
|
||||||
@@ -1001,11 +1052,12 @@
|
|||||||
"class": "Class",
|
"class": "Class",
|
||||||
"tier": "Tier",
|
"tier": "Tier",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"dev_id": "DEV: ID",
|
"id": "ID",
|
||||||
"purchase": "Purchase price",
|
"purchase": "Purchase price",
|
||||||
"restoration": "Restoration price",
|
"restoration": "Restoration price",
|
||||||
"sale": "Sale price",
|
"sale": "Sale price",
|
||||||
"research": "Research XP"
|
"set": "Set",
|
||||||
|
"price": "Price"
|
||||||
},
|
},
|
||||||
|
|
||||||
"tech_tree": {
|
"tech_tree": {
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1pv",
|
"hp": "%s1pv",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Auto cargador",
|
"auto_loader": "Auto cargador",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Modo de desarrollador",
|
"dev_mode": "Modo de desarrollador",
|
||||||
"language": "Idioma"
|
"language": "Idioma"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "Sin resultados"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Tankopedia",
|
"name": "Tankopedia",
|
||||||
"button": "Encuentra tanques",
|
"button": "Encuentra tanques",
|
||||||
"description": "Enciclopedia de tanques de WOTB",
|
"description": "Enciclopedia de tanques de WOTB",
|
||||||
"seo_description": "Estadísticas, armaduras y más para todos los tanques en World of Tanks Blitz",
|
"seo_description": "Estadísticas, armaduras y más para todos los tanques en World of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - Nivel %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - Nivel %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 blindaje, estadisticas, equipamiento, proviciones y mas.\n%s2 DPM, %3hp alfa, %s4mm penetracion, %s5kph velocidad maxima, %s6 hp salud",
|
"tank_seo_description": "%s1 blindaje, estadisticas, equipamiento, proviciones y mas.\n%s2 DPM, %3hp alfa, %s4mm penetracion, %s5kph velocidad maxima, %s6 hp salud",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "Medio",
|
||||||
|
"soft": "Suave",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "Normalización",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "Blindaje",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "Hull down",
|
"hull_down": "Hull down",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Características",
|
"title": "Características",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Comparar",
|
"label": "Comparar con",
|
||||||
"class": "Nivel %s1 - %s2",
|
"class": "Nivel %s1 - %s2",
|
||||||
"tier": "Todos de nivel %s1",
|
"tier": "Todos de nivel %s1",
|
||||||
"all": "Todos los tanques"
|
"all": "Todos los tanques"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1ps",
|
"hp": "%s1ps",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Chargement auto",
|
"auto_loader": "Chargement auto",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Development mode",
|
"dev_mode": "Development mode",
|
||||||
"language": "Language"
|
"language": "Language"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "No results"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Tankopedia",
|
"name": "Tankopedia",
|
||||||
"button": "Find tanks",
|
"button": "Find tanks",
|
||||||
"description": "Blitz tank encyclopedia",
|
"description": "Blitz tank encyclopedia",
|
||||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "Moyen",
|
||||||
|
"soft": "Soft",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "Normalization",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "Armor",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "Hull down",
|
"hull_down": "Hull down",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Characteristics",
|
"title": "Characteristics",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Compare",
|
"label": "Compare against",
|
||||||
"class": "Tier %s1 %s2",
|
"class": "Tier %s1 %s2",
|
||||||
"tier": "All of tier %s1",
|
"tier": "All of tier %s1",
|
||||||
"all": "All tanks"
|
"all": "All tanks"
|
||||||
|
|||||||
+189
-145
@@ -2,7 +2,7 @@
|
|||||||
"test": {
|
"test": {
|
||||||
"default": "test",
|
"default": "test",
|
||||||
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is %s1 because it has the color of %s2. I like it so much that I will say its name 3 times! %s1! %s1! %s1! Once again, it's %s2, not %s3.",
|
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is %s1 because it has the color of %s2. I like it so much that I will say its name 3 times! %s1! %s1! %s1! Once again, it's %s2, not %s3.",
|
||||||
"fox": "The quick brown fox jumps over the lazy dog."
|
"fox": "すばしっこい茶色のキツネが怠け者の犬を飛び越した。"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"units": {
|
"units": {
|
||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1hp",
|
"hp": "%s1hp",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "自動装填砲",
|
"auto_loader": "自動装填砲",
|
||||||
@@ -33,10 +35,10 @@
|
|||||||
"d_1": "昨日"
|
"d_1": "昨日"
|
||||||
},
|
},
|
||||||
"branches": {
|
"branches": {
|
||||||
"local": "dev",
|
"local": "開発",
|
||||||
"dev": "beta",
|
"dev": "ベータ版",
|
||||||
"opentest": "opentest",
|
"opentest": "オープンテスト",
|
||||||
"preview": "preview"
|
"preview": "プレビュー"
|
||||||
},
|
},
|
||||||
"locales": {
|
"locales": {
|
||||||
"en": "英語",
|
"en": "英語",
|
||||||
@@ -104,10 +106,10 @@
|
|||||||
"3": "駆逐戦車"
|
"3": "駆逐戦車"
|
||||||
},
|
},
|
||||||
"tank_class_short_plural_lowercase": {
|
"tank_class_short_plural_lowercase": {
|
||||||
"0": "LT",
|
"0": "軽戦車",
|
||||||
"1": "MT",
|
"1": "中戦車",
|
||||||
"2": "HT",
|
"2": "重戦車",
|
||||||
"3": "TD"
|
"3": "駆逐戦車"
|
||||||
},
|
},
|
||||||
"tank_class_medium": {
|
"tank_class_medium": {
|
||||||
"-1": "不明",
|
"-1": "不明",
|
||||||
@@ -124,9 +126,9 @@
|
|||||||
},
|
},
|
||||||
"regions": {
|
"regions": {
|
||||||
"normal": {
|
"normal": {
|
||||||
"com": "North America",
|
"com": "北米",
|
||||||
"eu": "Europe",
|
"eu": "ヨーロッパ",
|
||||||
"asia": "Asia-Pacific"
|
"asia": "アジア太平洋"
|
||||||
},
|
},
|
||||||
"short": {
|
"short": {
|
||||||
"com": "NA",
|
"com": "NA",
|
||||||
@@ -142,58 +144,58 @@
|
|||||||
"bronze": "ブロンズ"
|
"bronze": "ブロンズ"
|
||||||
},
|
},
|
||||||
"composite_stats": {
|
"composite_stats": {
|
||||||
"normalized_damage_dealt": "Damage",
|
"normalized_damage_dealt": "ダメージ",
|
||||||
"normalized_damage_received": "Damage received",
|
"normalized_damage_received": "被ダメージ",
|
||||||
"normalized_deaths": "Deathrate",
|
"normalized_deaths": "被撃破率",
|
||||||
"normalized_frags": "Kills",
|
"normalized_frags": "撃破",
|
||||||
"normalized_hits": "Hits",
|
"normalized_hits": "命中",
|
||||||
"normalized_losses": "Lossrate",
|
"normalized_losses": "減衰率",
|
||||||
"normalized_misses": "Misses",
|
"normalized_misses": "非命中数",
|
||||||
"normalized_shots": "Shots",
|
"normalized_shots": "射撃数",
|
||||||
"normalized_spotted": "Spots",
|
"normalized_spotted": "発見数",
|
||||||
"normalized_survived_battles": "Survival rate",
|
"normalized_survived_battles": "生存率",
|
||||||
"normalized_win_and_survived": "Winning and surviving rate",
|
"normalized_win_and_survived": "勝率・生還率",
|
||||||
"normalized_wins": "Winrate",
|
"normalized_wins": "勝率",
|
||||||
"normalized_xp": "XP",
|
"normalized_xp": "経験値",
|
||||||
"normalized_battle_life_time": "Battle time",
|
"normalized_battle_life_time": "戦闘時間",
|
||||||
"cumulative_accuracy": "Accuracy",
|
"cumulative_accuracy": "精度",
|
||||||
"cumulative_battles": "Battles",
|
"cumulative_battles": "戦闘数",
|
||||||
"cumulative_capture_points": "Total capture points",
|
"cumulative_capture_points": "総占領ポイント",
|
||||||
"cumulative_damage_dealt": "Total damage",
|
"cumulative_damage_dealt": "総ダメージ",
|
||||||
"cumulative_damage_ratio": "Damage ratio",
|
"cumulative_damage_ratio": "ダメージ率",
|
||||||
"cumulative_damage_received": "Total damage received",
|
"cumulative_damage_received": "総被ダメージ",
|
||||||
"cumulative_deaths": "Total deaths",
|
"cumulative_deaths": "総被撃破数",
|
||||||
"cumulative_dropped_capture_points": "Total dropped capture points",
|
"cumulative_dropped_capture_points": "総喪失占領ポイント",
|
||||||
"cumulative_frags": "Total kills",
|
"cumulative_frags": "総撃破数",
|
||||||
"cumulative_hits": "Total hits",
|
"cumulative_hits": "総命中数",
|
||||||
"cumulative_inaccuracy": "Inaccuracy",
|
"cumulative_inaccuracy": "非命中率",
|
||||||
"cumulative_kills_to_death_ratio": "Kills to death ratio",
|
"cumulative_kills_to_death_ratio": "撃破/被撃破比",
|
||||||
"cumulative_losses": "Losses",
|
"cumulative_losses": "敗北",
|
||||||
"cumulative_misses": "Total misses",
|
"cumulative_misses": "総非命中数",
|
||||||
"cumulative_shots": "Total shots",
|
"cumulative_shots": "総射撃数",
|
||||||
"cumulative_spotted": "Total spots",
|
"cumulative_spotted": "総発見数",
|
||||||
"cumulative_survived_battles": "Survived battles",
|
"cumulative_survived_battles": "生還した戦闘数",
|
||||||
"cumulative_win_and_survived": "Won and survived battles",
|
"cumulative_win_and_survived": "勝利し生還した戦闘数",
|
||||||
"cumulative_wins": "Wins",
|
"cumulative_wins": "勝利",
|
||||||
"cumulative_xp": "Total XP",
|
"cumulative_xp": "総経験値",
|
||||||
"cumulative_wn8": "WN8",
|
"cumulative_wn8": "WN8",
|
||||||
"cumulative_battle_life_time": "Total battle time"
|
"cumulative_battle_life_time": "総戦闘時間"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bot": {
|
"bot": {
|
||||||
"common": {
|
"common": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"clan_not_found": "# Could not find clan\nCouldn't find \"%s1\". Try selecting a clan from the search result.",
|
"clan_not_found": "# クランが見つかりませんでした\n\"%s1\"は見つかりませんでした。検索結果からクランを選択してください。",
|
||||||
"player_not_found": "# Could not find user\nI couldn't find user \"%s1\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
|
"player_not_found": "# ユーザーが見つかりませんでした\nユーザー「\"%s1\"」は見つかりませんでした。検索結果からユーザーを選択するか、有効な名前を入力してください。`/link`コマンドを使用することも可能です。",
|
||||||
"player_not_linked": "# Use `/link` to get started\nI don't know who you are but you can tell me today!",
|
"player_not_linked": "# `/link`を使用して始めましょう\nはじめまして!あなたが誰か、私に教えてください。",
|
||||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"%s1\".",
|
"tank_name_not_found": "# 車輌が見つかりませんでした\n\"%s1\"という名前の車輌は見つかりませんでした。",
|
||||||
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"%s1\". Try typing the name of the tank instead of a number.",
|
"tank_id_not_found": "# 車輌が見つかりませんでした\n\"%s1\"というIDの車輌は見つかりませんでした。番号ではなく名前で検索してください。",
|
||||||
"no_tank_stats": "# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for.",
|
"no_tank_stats": "# 利用可能な車輌統計がありません\nこのプレイヤーには利用可能な統計がありません。あなたが探しているプレイヤーではない可能性があります。",
|
||||||
"get_help": "Discordサーバーに参加する",
|
"get_help": "Discordサーバーに参加する",
|
||||||
"uncaught_error": "# BlitzKit がエラーに遭遇しました!\n申し訳ありません。お気軽に[Discordの公式サーバー](https://discord.gg/nDt7AjGJQH) をご利用ください。",
|
"uncaught_error": "# BlitzKitがエラーに遭遇しました!\n申し訳ありません。お気軽に[公式Discordサーバー](https://discord.gg/nDt7AjGJQH)にお問い合わせください。",
|
||||||
"preview": "# This command is in preview\n\nYou can only access this command in [the official Discord server](https://discord.gg/nDt7AjGJQH). The command will be generally available soon.",
|
"preview": "このコマンドは現在[公式Discardサーバー](https://discord.gg/nDt7AjGJQH)でのみ利用可能です。間もなく全体で利用可能になります。",
|
||||||
"query_too_small": "# Your search is too short\nYour search must be at least 3 characters long.",
|
"query_too_small": "# 単語が短すぎます\n検索には少なくとも3文字が含まれている必要があります。",
|
||||||
"query_too_long": "# Your search is too long\nYour search must be at most 100 characters long."
|
"query_too_long": "# 単語が長すぎます\n検索は最大で100文字までです。"
|
||||||
},
|
},
|
||||||
"wn8": {
|
"wn8": {
|
||||||
"name": "WN8",
|
"name": "WN8",
|
||||||
@@ -217,26 +219,26 @@
|
|||||||
},
|
},
|
||||||
"30": {
|
"30": {
|
||||||
"name": "30",
|
"name": "30",
|
||||||
"description": "30 days"
|
"description": "30日"
|
||||||
},
|
},
|
||||||
"60": {
|
"60": {
|
||||||
"name": "60",
|
"name": "60",
|
||||||
"description": "60 days"
|
"description": "60日"
|
||||||
},
|
},
|
||||||
"90": {
|
"90": {
|
||||||
"name": "90",
|
"name": "90",
|
||||||
"description": "90日"
|
"description": "90日"
|
||||||
},
|
},
|
||||||
"career": {
|
"career": {
|
||||||
"name": "総合戦績",
|
"name": "総合戦績",
|
||||||
"description": "Career"
|
"description": "Career"
|
||||||
},
|
},
|
||||||
"custom": {
|
"custom": {
|
||||||
"name": "custom",
|
"name": "カスタム",
|
||||||
"description": "Custom range",
|
"description": "Custom range",
|
||||||
"options": {
|
"options": {
|
||||||
"start": {
|
"start": {
|
||||||
"name": "start",
|
"name": "開始",
|
||||||
"description": "Start in number of days ago from today"
|
"description": "Start in number of days ago from today"
|
||||||
},
|
},
|
||||||
"end": {
|
"end": {
|
||||||
@@ -248,21 +250,21 @@
|
|||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"clan": {
|
"clan": {
|
||||||
"name": "clan",
|
"name": "クラン",
|
||||||
"description": "The clan name or tag"
|
"description": "クラン名もしくはタグ"
|
||||||
},
|
},
|
||||||
"tank": {
|
"tank": {
|
||||||
"name": "tank",
|
"name": "車輌",
|
||||||
"description": "The tank to get stats for"
|
"description": "統計を得る車輌"
|
||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"name": "username",
|
"name": "ユーザー名",
|
||||||
"description": "The Blitz username of the player"
|
"description": "プレイヤーのBlitzユーザー名"
|
||||||
},
|
},
|
||||||
"filters": {
|
"filters": {
|
||||||
"nation": {
|
"nation": {
|
||||||
"name": "nation",
|
"name": "国家",
|
||||||
"description": "Nation"
|
"description": "国家"
|
||||||
},
|
},
|
||||||
"class": {
|
"class": {
|
||||||
"name": "",
|
"name": "",
|
||||||
@@ -274,8 +276,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"region": {
|
"region": {
|
||||||
"name": "region",
|
"name": "地域",
|
||||||
"description": "Region"
|
"description": "地域"
|
||||||
},
|
},
|
||||||
"tier": {
|
"tier": {
|
||||||
"name": "tier",
|
"name": "tier",
|
||||||
@@ -292,7 +294,7 @@
|
|||||||
"custom": "%s1 - %s2 days"
|
"custom": "%s1 - %s2 days"
|
||||||
},
|
},
|
||||||
"filters": {
|
"filters": {
|
||||||
"none": "No filters",
|
"none": "フィルターなし",
|
||||||
"tier": "Tier %s1"
|
"tier": "Tier %s1"
|
||||||
},
|
},
|
||||||
"no_data": {
|
"no_data": {
|
||||||
@@ -305,31 +307,31 @@
|
|||||||
"refresh": "Refresh"
|
"refresh": "Refresh"
|
||||||
},
|
},
|
||||||
"hero_stats": {
|
"hero_stats": {
|
||||||
"battles": "Battles",
|
"battles": "戦闘数",
|
||||||
"winrate": "Winrate",
|
"winrate": "勝率",
|
||||||
"damage": "Damage",
|
"damage": "ダメージ",
|
||||||
"damage_ratio": "Damage ratio",
|
"damage_ratio": "ダメージ率",
|
||||||
"tier": "Tier",
|
"tier": "Tier",
|
||||||
"survival": "Survival",
|
"survival": "生存",
|
||||||
"accuracy": "Accuracy",
|
"accuracy": "命中率",
|
||||||
"kills": "Kills"
|
"kills": "撃破"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"auction": {
|
"auction": {
|
||||||
"name": "auction",
|
"name": "オークション",
|
||||||
"description": "Tanks available right now in the auction",
|
"description": "現在オークションで購入可能な車輌",
|
||||||
"body": {
|
"body": {
|
||||||
"title": "Blitz Auction",
|
"title": "Blitzオークション",
|
||||||
"subtitle": "%s1 available • next prices %s2\nBid now: %s3",
|
"subtitle": "%s1 残り• 次の価格 %s2\n今すぐ入札: %s3",
|
||||||
"next": "Next price: %s1",
|
"next": "次の価格: %s1",
|
||||||
"available": "Available: %s1 / %s2"
|
"available": "残り: %s1 / %s2"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"no_auction": "# No ongoing auction\n\nCurrently, there are no tanks available for purchase in the auction. If you think this is an error, please report this discrepancy in [the official Discord Server](https://discord.gg/nDt7AjGJQH)."
|
"no_auction": "# 進行中のオークションはありません\n現在、オークションで購入可能な車輌はありません。もしこれが間違いの場合、[公式Discardサーバー](https://discord.gg/nDt7AjGJQH)に報告してください。"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"bid": "Bid now"
|
"bid": "今すぐ入札"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"replay": {
|
"replay": {
|
||||||
@@ -337,7 +339,7 @@
|
|||||||
"description": "Display replay results"
|
"description": "Display replay results"
|
||||||
},
|
},
|
||||||
"research": {
|
"research": {
|
||||||
"name": "research",
|
"name": "研究",
|
||||||
"description": "Lists the expenses in researching a line",
|
"description": "Lists the expenses in researching a line",
|
||||||
"options": {
|
"options": {
|
||||||
"target_tank": {
|
"target_tank": {
|
||||||
@@ -369,32 +371,32 @@
|
|||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"name": "about",
|
"name": "about",
|
||||||
"description": "All the info you need about the bot",
|
"description": "botについての情報の全て",
|
||||||
"subcommands": {
|
"subcommands": {
|
||||||
"commands": {
|
"commands": {
|
||||||
"name": "commands",
|
"name": "コマンド",
|
||||||
"description": "List of all commands and their descriptions",
|
"description": "全コマンドのリストと説明",
|
||||||
"body": "# Commands\n\nBlitzKit offers the following commands:\n\n"
|
"body": "# コマンド\nBlitzKitは以下のコマンドを提供します:"
|
||||||
},
|
},
|
||||||
"embeds": {
|
"embeds": {
|
||||||
"name": "embeds",
|
"name": "埋め込み",
|
||||||
"description": "How embeds work"
|
"description": "埋め込みがどう機能するか"
|
||||||
},
|
},
|
||||||
"introduction": {
|
"introduction": {
|
||||||
"name": "introduction",
|
"name": "introduction",
|
||||||
"description": "About the bot"
|
"description": "botについて"
|
||||||
},
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"name": "invite",
|
"name": "招待",
|
||||||
"description": "How to invite the bot"
|
"description": "botを招待する方法"
|
||||||
},
|
},
|
||||||
"timezones": {
|
"timezones": {
|
||||||
"name": "timezones",
|
"name": "タイムゾーン",
|
||||||
"description": "How BlitzKit infers and uses your timezone"
|
"description": "How BlitzKit infers and uses your timezone"
|
||||||
},
|
},
|
||||||
"credits": {
|
"credits": {
|
||||||
"name": "credits",
|
"name": "クレジット",
|
||||||
"description": "People who have helped BlitzKit"
|
"description": "BlitzKitを支援した人々"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -403,10 +405,10 @@
|
|||||||
"description": "A period's breakdown by tanks played",
|
"description": "A period's breakdown by tanks played",
|
||||||
"body": {
|
"body": {
|
||||||
"total": "トータル",
|
"total": "トータル",
|
||||||
"battles": "Battles",
|
"battles": "戦闘数",
|
||||||
"wn8": "WN8",
|
"wn8": "WN8",
|
||||||
"winrate": "Winrate",
|
"winrate": "勝率",
|
||||||
"damage": "Damage",
|
"damage": "ダメージ",
|
||||||
"unknown_tank": "Unknown tank %s1"
|
"unknown_tank": "Unknown tank %s1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -432,7 +434,7 @@
|
|||||||
"description": "Player statistics"
|
"description": "Player statistics"
|
||||||
},
|
},
|
||||||
"tank": {
|
"tank": {
|
||||||
"name": "tank",
|
"name": "車輌",
|
||||||
"description": "Tank statistics"
|
"description": "Tank statistics"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,21 +460,21 @@
|
|||||||
"cards": {
|
"cards": {
|
||||||
"games": {
|
"games": {
|
||||||
"title": "Games",
|
"title": "Games",
|
||||||
"winrate": "Winrate",
|
"winrate": "勝率",
|
||||||
"battles": "Battles",
|
"battles": "戦闘数",
|
||||||
"wins_losses": "Wins / losses"
|
"wins_losses": "Wins / losses"
|
||||||
},
|
},
|
||||||
"efficiency": {
|
"efficiency": {
|
||||||
"title": "Efficiency",
|
"title": "Efficiency",
|
||||||
"wn8": "WN8",
|
"wn8": "WN8",
|
||||||
"survival": "Survival",
|
"survival": "生存",
|
||||||
"accuracy": "Accuracy"
|
"accuracy": "精度"
|
||||||
},
|
},
|
||||||
"lethality": {
|
"lethality": {
|
||||||
"title": "Lethality",
|
"title": "Lethality",
|
||||||
"average_damage": "Average damage",
|
"average_damage": "Average damage",
|
||||||
"damage_per_tier": "Damage per tier",
|
"damage_per_tier": "Damage per tier",
|
||||||
"damage_ratio": "Damage ratio",
|
"damage_ratio": "ダメージ比",
|
||||||
"average_kills": "Average kills"
|
"average_kills": "Average kills"
|
||||||
},
|
},
|
||||||
"miscellaneous": {
|
"miscellaneous": {
|
||||||
@@ -480,7 +482,7 @@
|
|||||||
"average_tier": "Average tier",
|
"average_tier": "Average tier",
|
||||||
"average_spots": "Average spots",
|
"average_spots": "Average spots",
|
||||||
"average_xp": "Average XP",
|
"average_xp": "Average XP",
|
||||||
"kills_to_death_ratio": "Kills to death ratio"
|
"kills_to_death_ratio": "撃破/被撃破比"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,7 +570,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"today": {
|
"today": {
|
||||||
"name": "today",
|
"name": "今日",
|
||||||
"description": "Today's played tanks and statistics"
|
"description": "Today's played tanks and statistics"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
@@ -617,8 +619,8 @@
|
|||||||
"body": {
|
"body": {
|
||||||
"title": "%s1's information",
|
"title": "%s1's information",
|
||||||
"nickname": "Nickname",
|
"nickname": "Nickname",
|
||||||
"battles": "Battles",
|
"battles": "戦闘数",
|
||||||
"winrate": "Winrate",
|
"winrate": "勝率",
|
||||||
"account_id": "Account ID",
|
"account_id": "Account ID",
|
||||||
"created": "Created",
|
"created": "Created",
|
||||||
"last_battle": "Last battle"
|
"last_battle": "Last battle"
|
||||||
@@ -629,7 +631,7 @@
|
|||||||
"description": "Rating player's statistics",
|
"description": "Rating player's statistics",
|
||||||
"subcommands": {
|
"subcommands": {
|
||||||
"today": {
|
"today": {
|
||||||
"name": "today",
|
"name": "今日",
|
||||||
"description": "Today's rating statistics"
|
"description": "Today's rating statistics"
|
||||||
},
|
},
|
||||||
"season": {
|
"season": {
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "開発者モード",
|
"dev_mode": "開発者モード",
|
||||||
"language": "言語 / Language"
|
"language": "言語 / Language"
|
||||||
@@ -670,11 +676,11 @@
|
|||||||
"recent": "最近の閲覧",
|
"recent": "最近の閲覧",
|
||||||
"select_all": "全て選択",
|
"select_all": "全て選択",
|
||||||
"count_singular": "1 輌",
|
"count_singular": "1 輌",
|
||||||
"count_plural": "%s1 輌",
|
"count_plural": "%s1輌",
|
||||||
"sorting_by": "並べ替え:%s1",
|
"sorting_by": ":%s1で並び替え",
|
||||||
"no_tanks_found": {
|
"no_tanks_found": {
|
||||||
"body": "該当する車輌が存在しません。",
|
"body": "該当する車輌が存在しません。",
|
||||||
"search_again": "もう一度探してください。",
|
"search_again": "もう一度検索してください。",
|
||||||
"clear_filters": "フィルターをクリアしてください"
|
"clear_filters": "フィルターをクリアしてください"
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
@@ -687,7 +693,7 @@
|
|||||||
"survivability.volume": "体積",
|
"survivability.volume": "体積",
|
||||||
"survivability.length": "全長",
|
"survivability.length": "全長",
|
||||||
"fire.dpm": "通常弾DPM",
|
"fire.dpm": "通常弾DPM",
|
||||||
"fire.dpmPremium": "課金弾DPM",
|
"fire.dpmPremium": "プレミアム弾DPM",
|
||||||
"fire.reload": "装填時間",
|
"fire.reload": "装填時間",
|
||||||
"fire.caliber": "砲口径",
|
"fire.caliber": "砲口径",
|
||||||
"fire.standardPenetration": "通常弾貫通力",
|
"fire.standardPenetration": "通常弾貫通力",
|
||||||
@@ -698,10 +704,10 @@
|
|||||||
"fire.shellRange": "射程範囲",
|
"fire.shellRange": "射程範囲",
|
||||||
"fire.shellCapacity": "総弾数",
|
"fire.shellCapacity": "総弾数",
|
||||||
"fire.aimTime": "照準時間",
|
"fire.aimTime": "照準時間",
|
||||||
"fire.dispersionStill": "静止時散布界",
|
"fire.dispersionStill": "静止時拡散",
|
||||||
"fire.dispersionMoving": "移動時散布界",
|
"fire.dispersionMoving": "移動時拡散",
|
||||||
"fire.gunDepression": "主砲俯角",
|
"fire.gunDepression": "俯角",
|
||||||
"fire.gunElevation": "主砲仰角",
|
"fire.gunElevation": "仰角",
|
||||||
"maneuverability.forwardsSpeed": "前進速度",
|
"maneuverability.forwardsSpeed": "前進速度",
|
||||||
"maneuverability.backwardsSpeed": "後退速度",
|
"maneuverability.backwardsSpeed": "後退速度",
|
||||||
"maneuverability.power": "馬力",
|
"maneuverability.power": "馬力",
|
||||||
@@ -710,17 +716,17 @@
|
|||||||
"maneuverability.traverseSpeed": "車体旋回速度"
|
"maneuverability.traverseSpeed": "車体旋回速度"
|
||||||
},
|
},
|
||||||
"sort_dropdown": {
|
"sort_dropdown": {
|
||||||
"label": "ソート",
|
"label": "並び替え",
|
||||||
"groups": {
|
"groups": {
|
||||||
"sort": {
|
"sort": {
|
||||||
"no_sort": "ソートなし",
|
"no_sort": "並び替えなし",
|
||||||
"label": "並べ替え項目",
|
"label": "並べ替え項目",
|
||||||
"fire": "火力",
|
"fire": "火力",
|
||||||
"maneuverability": "機動性",
|
"maneuverability": "機動性",
|
||||||
"survivability": "生存性"
|
"survivability": "生存性"
|
||||||
},
|
},
|
||||||
"direction": {
|
"direction": {
|
||||||
"label": "方法",
|
"label": "方向",
|
||||||
"ascending": "昇順",
|
"ascending": "昇順",
|
||||||
"descending": "降順"
|
"descending": "降順"
|
||||||
}
|
}
|
||||||
@@ -742,13 +748,13 @@
|
|||||||
},
|
},
|
||||||
"hot_tanks": {
|
"hot_tanks": {
|
||||||
"title": "人気の車輌",
|
"title": "人気の車輌",
|
||||||
"subtitle": "過去 %s1 日間"
|
"subtitle": "過去 %s1日間"
|
||||||
},
|
},
|
||||||
"other_projects": {
|
"other_projects": {
|
||||||
"title": "Other cool projects"
|
"title": "他のプロジェクト"
|
||||||
},
|
},
|
||||||
"help_translate": "%s1の %s2への翻訳にご協力ください!",
|
"help_translate": "%s1の %s2への翻訳にご協力ください!",
|
||||||
"seo_description": "Tools for everything World of Tanks Blitz"
|
"seo_description": "World of Tanks Blitz全般のツール"
|
||||||
},
|
},
|
||||||
"docs": {
|
"docs": {
|
||||||
"patches": {
|
"patches": {
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "該当なし"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Tankopedia",
|
"name": "Tankopedia",
|
||||||
"button": "戦車を探す",
|
"button": "戦車を探す",
|
||||||
"description": "Blitz戦車百科",
|
"description": "Blitz戦車百科",
|
||||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "不整地",
|
||||||
|
"soft": "軟弱地",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "標準化",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "装甲",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "ハルダウン",
|
"hull_down": "ハルダウン",
|
||||||
@@ -795,7 +839,7 @@
|
|||||||
"normalization": "標準化",
|
"normalization": "標準化",
|
||||||
"ricochet": "跳弾角度",
|
"ricochet": "跳弾角度",
|
||||||
"explosion_radius": "爆風半径",
|
"explosion_radius": "爆風半径",
|
||||||
"exit": "決定",
|
"exit": "終了",
|
||||||
"reset": "リセット"
|
"reset": "リセット"
|
||||||
},
|
},
|
||||||
"advanced": "高度なハイライト",
|
"advanced": "高度なハイライト",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "性能値",
|
"title": "性能値",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "性能比較",
|
"label": "比較対象",
|
||||||
"class": "Tier %s1 %s2",
|
"class": "Tier %s1 %s2",
|
||||||
"tier": "Tier %s1 全車輌",
|
"tier": "Tier %s1 全車輌",
|
||||||
"all": "全車輌"
|
"all": "全車輌"
|
||||||
@@ -952,22 +996,22 @@
|
|||||||
"azimuthRight": "右射界",
|
"azimuthRight": "右射界",
|
||||||
"speedForwards": "前進",
|
"speedForwards": "前進",
|
||||||
"speedBackwards": "後退",
|
"speedBackwards": "後退",
|
||||||
"hardTerrainCoefficient": "道",
|
"hardTerrainCoefficient": "舗装路での地形走破能力",
|
||||||
"hardTerrainCoefficientRaw": "道",
|
"hardTerrainCoefficientRaw": "舗装路での地形係数",
|
||||||
"mediumTerrainCoefficient": "地面",
|
"mediumTerrainCoefficient": "不整地",
|
||||||
"mediumTerrainCoefficientRaw": "地面",
|
"mediumTerrainCoefficientRaw": "不整地",
|
||||||
"softTerrainCoefficient": "水辺",
|
"softTerrainCoefficient": "軟弱地",
|
||||||
"softTerrainCoefficientRaw": "水辺",
|
"softTerrainCoefficientRaw": "軟弱地",
|
||||||
"enginePower": "エンジン出力",
|
"enginePower": "エンジン出力",
|
||||||
"powerToWeightRatioHardTerrain": "道",
|
"powerToWeightRatioHardTerrain": "舗装路での重量毎出力値",
|
||||||
"powerToWeightRatioMediumTerrain": "地面",
|
"powerToWeightRatioMediumTerrain": "不整地",
|
||||||
"powerToWeightRatioSoftTerrain": "水辺",
|
"powerToWeightRatioSoftTerrain": "軟弱地",
|
||||||
"weight": "重量",
|
"weight": "重量",
|
||||||
"turretTraverseSpeed": "砲塔旋回速度",
|
"turretTraverseSpeed": "砲塔旋回速度",
|
||||||
"gunTraverseSpeed": "主砲旋回速度",
|
"gunTraverseSpeed": "主砲旋回速度",
|
||||||
"hullTraverseHardTerrain": "道",
|
"hullTraverseHardTerrain": "舗装路での旋回速度",
|
||||||
"hullTraverseMediumTerrain": "地面",
|
"hullTraverseMediumTerrain": "不整地",
|
||||||
"hullTraverseSoftTerrain": "水辺",
|
"hullTraverseSoftTerrain": "軟弱地",
|
||||||
"health": "耐久値",
|
"health": "耐久値",
|
||||||
"fireChance": "火災発生率",
|
"fireChance": "火災発生率",
|
||||||
"viewRange": "視認範囲",
|
"viewRange": "視認範囲",
|
||||||
@@ -980,7 +1024,7 @@
|
|||||||
"height": "全高",
|
"height": "全高",
|
||||||
"length": "車体長",
|
"length": "車体長",
|
||||||
"volume": "体積",
|
"volume": "体積",
|
||||||
"shellRange": "射程範囲",
|
"shellRange": "射程",
|
||||||
"shellCapacity": "総弾数",
|
"shellCapacity": "総弾数",
|
||||||
"gunType": "主砲タイプ",
|
"gunType": "主砲タイプ",
|
||||||
"penetrationAt250m": "250m での貫通力"
|
"penetrationAt250m": "250m での貫通力"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1hp",
|
"hp": "%s1hp",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Auto loader",
|
"auto_loader": "Auto loader",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Development mode",
|
"dev_mode": "Development mode",
|
||||||
"language": "Language"
|
"language": "Language"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "Brak wyników"
|
||||||
|
},
|
||||||
|
"stats": ""
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Tankopedia",
|
"name": "Tankopedia",
|
||||||
"button": "Find tanks",
|
"button": "Find tanks",
|
||||||
"description": "Blitz tank encyclopedia",
|
"description": "Blitz tank encyclopedia",
|
||||||
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
"seo_description": "Statistics, armor, and more for all tanks in World of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - Tier %s2 %s3 %s4 | %s5 Tankopedia | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "Medium",
|
||||||
|
"soft": "Soft",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "Normalization",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "Armor",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "Hull down",
|
"hull_down": "Hull down",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Characteristics",
|
"title": "Characteristics",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Compare",
|
"label": "Compare against",
|
||||||
"class": "Tier %s1 %s2",
|
"class": "Tier %s1 %s2",
|
||||||
"tier": "All of tier %s1",
|
"tier": "All of tier %s1",
|
||||||
"all": "All tanks"
|
"all": "All tanks"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1mm",
|
"mm": "%s1mm",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1hp",
|
"hp": "%s1hp",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Autocarregador",
|
"auto_loader": "Autocarregador",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Modo de desenvolvimento",
|
"dev_mode": "Modo de desenvolvimento",
|
||||||
"language": "Idioma"
|
"language": "Idioma"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "Sem resultados"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Tanquepedia",
|
"name": "Tanquepedia",
|
||||||
"button": "Encontrar tanques",
|
"button": "Encontrar tanques",
|
||||||
"description": "Blitz enciclopédia de tanques",
|
"description": "Blitz enciclopédia de tanques",
|
||||||
"seo_description": "Estatísticas, blindagem, e mais para todos os tanques de Wolrd of Tanks Blitz",
|
"seo_description": "Estatísticas, blindagem, e mais para todos os tanques de Wolrd of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - Nível %s2 %s3 %s4 | %s5 Tanquepedia | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - Nível %s2 %s3 %s4 | %s5 Tanquepedia | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 blindagem, estatísticas, equipamentos, provisões e mais. %s2 DPM, %s3hp alfa, %s4mm de penetração, %s5km/h velocidade máxima, %s6hp vida.",
|
"tank_seo_description": "%s1 blindagem, estatísticas, equipamentos, provisões e mais. %s2 DPM, %s3hp alfa, %s4mm de penetração, %s5km/h velocidade máxima, %s6hp vida.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "Médio",
|
||||||
|
"soft": "Macio",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "Normalização",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "Blindagem",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "Casco para baixo",
|
"hull_down": "Casco para baixo",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Características",
|
"title": "Características",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Comparar",
|
"label": "Comparar com",
|
||||||
"class": "Nível %s1 %s2",
|
"class": "Nível %s1 %s2",
|
||||||
"tier": "Tudo de nível %s1",
|
"tier": "Tudo de nível %s1",
|
||||||
"all": "Todos os tanques"
|
"all": "Todos os tanques"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1мм",
|
"mm": "%s1мм",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1hp",
|
"hp": "%s1hp",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/с"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Барабан",
|
"auto_loader": "Барабан",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: перемещено навсегда",
|
||||||
|
"body": "Эта страница перемещена. Перенаправление..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Режим разработчика",
|
"dev_mode": "Режим разработчика",
|
||||||
"language": "Язык"
|
"language": "Язык"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Угадайте танк",
|
||||||
|
"button": "Угадать",
|
||||||
|
"description": "Мини-игра «Силуэт»",
|
||||||
|
"seo_description": "Играйте угадывая силуэт танка из World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Введите догадку...",
|
||||||
|
"skip": "Пропустить",
|
||||||
|
"guess": "Угадать",
|
||||||
|
"next": "Следующий",
|
||||||
|
"no_results": "Ничего не найденo"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 угадано верно"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Поиск характеристик...",
|
||||||
"name": "Танкопедия",
|
"name": "Танкопедия",
|
||||||
"button": "Поиск танков",
|
"button": "Поиск танков",
|
||||||
"description": "Танковая энциклопедия Blitz",
|
"description": "Танковая энциклопедия Blitz",
|
||||||
"seo_description": "Статистика, броня и многое другое по всем танкам World of Tanks Blitz",
|
"seo_description": "Статистика, броня и многое другое по всем танкам World of Tanks Blitz",
|
||||||
"tank_seo_title": "%s1 - %s4 %s3 %s2 уровня | Танкопедия %s5 | World of Tanks Blitz (WoTB)",
|
"tank_seo_title": "%s1 - %s4 %s3 %s2 уровня | Танкопедия %s5 | World of Tanks Blitz (WoTB)",
|
||||||
"tank_seo_description": "%s1 броня, статистика, оборудование, снабжение и многое другое. %s2 УВМ, %s3hp альфа, %s4mm пробитие, %s5км/ч лучшая скорость, %s6hp здоровье.",
|
"tank_seo_description": "%s1 броня, статистика, оборудование, снабжение и многое другое. %s2 УВМ, %s3hp альфа, %s4mm пробитие, %s5км/ч лучшая скорость, %s6hp здоровье.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Корпус",
|
||||||
|
"turret": "Башня",
|
||||||
|
"hard": "Твёрдые",
|
||||||
|
"medium": "Средний танк",
|
||||||
|
"soft": "На мягком грунте",
|
||||||
|
"effective": "Эффективно"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Угол",
|
||||||
|
"normalization": "Нормализация",
|
||||||
|
"effective_angle": "Эффективный угол",
|
||||||
|
"armor": "Броня",
|
||||||
|
"no_ricochet": "Разрывные снаряды не рикошетят"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Камо",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Промзона",
|
||||||
|
"dead_rail": "Эшелон"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "За холмом",
|
"hull_down": "За холмом",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Характеристики",
|
"title": "Характеристики",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Сравнение",
|
"label": "Сравнивать с",
|
||||||
"class": "%s2 %s1 уровня",
|
"class": "%s2 %s1 уровня",
|
||||||
"tier": "Все %s1 уровня",
|
"tier": "Все %s1 уровня",
|
||||||
"all": "Все танки"
|
"all": "Все танки"
|
||||||
@@ -1143,7 +1187,7 @@
|
|||||||
"description": "Встраиваемые элементы для стримов",
|
"description": "Встраиваемые элементы для стримов",
|
||||||
"seo_description": "Создать вставки для стримов по World of Tanks Blitz с невероятной кастомизации",
|
"seo_description": "Создать вставки для стримов по World of Tanks Blitz с невероятной кастомизации",
|
||||||
"coming_soon": "Скоро появятся новые встраиваемые элементы.",
|
"coming_soon": "Скоро появятся новые встраиваемые элементы.",
|
||||||
"suggest": "Предложить идеи",
|
"suggest": "Предложить идеи.",
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "Предпросмотр",
|
"title": "Предпросмотр",
|
||||||
"upload": "Загрузить фон для теста"
|
"upload": "Загрузить фон для теста"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s1мм",
|
"mm": "%s1мм",
|
||||||
"deg": "%s1°",
|
"deg": "%s1°",
|
||||||
"hp": "%s1хп",
|
"hp": "%s1хп",
|
||||||
"x": "х%s1"
|
"x": "х%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Магазинна система заряджання",
|
"auto_loader": "Магазинна система заряджання",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Development mode",
|
"dev_mode": "Development mode",
|
||||||
"language": "Мова"
|
"language": "Мова"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "Немає результатів"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "Танкопедія",
|
"name": "Танкопедія",
|
||||||
"button": "Знайти танки",
|
"button": "Знайти танки",
|
||||||
"description": "Танкова енциклопедія",
|
"description": "Танкова енциклопедія",
|
||||||
"seo_description": "Характеристики, броня та інше для всіх танків WoT Blitz",
|
"seo_description": "Характеристики, броня та інше для всіх танків WoT Blitz",
|
||||||
"tank_seo_title": "%s1 - Рівень %s2 %s3 %s4 | %s5 Танкопедія | WoT Blitz",
|
"tank_seo_title": "%s1 - Рівень %s2 %s3 %s4 | %s5 Танкопедія | WoT Blitz",
|
||||||
"tank_seo_description": "%s1 броня, характеристики, обладнання, амуніція та більше. %s2 шкода на хвилину, %s3 разова шкода, %s4 мм пробиття, %s5 км/год максимальна швидкість, %s6 міцність.",
|
"tank_seo_description": "%s1 броня, характеристики, обладнання, амуніція та більше. %s2 шкода на хвилину, %s3 разова шкода, %s4 мм пробиття, %s5 км/год максимальна швидкість, %s6 міцність.",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "Середній",
|
||||||
|
"soft": "Soft",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "Нормалізація",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "Броня",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "Від башти",
|
"hull_down": "Від башти",
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "Characteristics",
|
"title": "Characteristics",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "Порівняти",
|
"label": "Compare against",
|
||||||
"class": "Tier %s1 %s2",
|
"class": "Tier %s1 %s2",
|
||||||
"tier": "All of tier %s1",
|
"tier": "All of tier %s1",
|
||||||
"all": "Усі танки"
|
"all": "Усі танки"
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
"mm": "%s毫米",
|
"mm": "%s毫米",
|
||||||
"deg": "%s1度",
|
"deg": "%s1度",
|
||||||
"hp": "%s生命值",
|
"hp": "%s生命值",
|
||||||
"x": "x%s1"
|
"x": "x%s1",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"deg_s": "%s1°/s"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "彈夾型戰車",
|
"auto_loader": "彈夾型戰車",
|
||||||
@@ -651,6 +653,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"website": {
|
"website": {
|
||||||
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "開發人員模式",
|
"dev_mode": "開發人員模式",
|
||||||
"language": "語言"
|
"language": "語言"
|
||||||
@@ -757,13 +763,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
"guess": {
|
||||||
|
"name": "Guess the tank",
|
||||||
|
"button": "Guess away",
|
||||||
|
"description": "Silhouette mini-game",
|
||||||
|
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Type to guess...",
|
||||||
|
"skip": "Skip",
|
||||||
|
"guess": "Guess",
|
||||||
|
"next": "Next",
|
||||||
|
"no_results": "沒有結果"
|
||||||
|
},
|
||||||
|
"stats": "%s1 / %s2 guessed correctly"
|
||||||
|
},
|
||||||
"tankopedia": {
|
"tankopedia": {
|
||||||
|
"search": "Search a stat...",
|
||||||
"name": "戰車百科",
|
"name": "戰車百科",
|
||||||
"button": "尋找戰車",
|
"button": "尋找戰車",
|
||||||
"description": "閃擊戰戰車百科全書",
|
"description": "閃擊戰戰車百科全書",
|
||||||
"seo_description": "世界坦克布莱茨坦克坦克世界闪击战的所有坦克的统计数字、装甲和更多",
|
"seo_description": "世界坦克布莱茨坦克坦克世界闪击战的所有坦克的统计数字、装甲和更多",
|
||||||
"tank_seo_title": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
"tank_seo_title": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
||||||
"tank_seo_description": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
"tank_seo_description": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
|
||||||
|
"visualizers": {
|
||||||
|
"rotator": {
|
||||||
|
"hull": "Hull",
|
||||||
|
"turret": "Turret",
|
||||||
|
"hard": "Hard",
|
||||||
|
"medium": "中型戰車",
|
||||||
|
"soft": "柔软的",
|
||||||
|
"effective": "Effective"
|
||||||
|
},
|
||||||
|
"ricochet": {
|
||||||
|
"angle": "Angle",
|
||||||
|
"normalization": "轉正",
|
||||||
|
"effective_angle": "Effective angle",
|
||||||
|
"armor": "裝甲",
|
||||||
|
"no_ricochet": "Explosive shells don't ricochet"
|
||||||
|
},
|
||||||
|
"view_range": {
|
||||||
|
"camo": "Camo",
|
||||||
|
"percentage": "%s1%",
|
||||||
|
"ghost_factory": "Ghost Factory",
|
||||||
|
"dead_rail": "Dead Rail"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sandbox": {
|
"sandbox": {
|
||||||
"poses": {
|
"poses": {
|
||||||
"hull_down": "戰車下部",
|
"hull_down": "戰車下部",
|
||||||
@@ -810,14 +854,14 @@
|
|||||||
"track": "履帶"
|
"track": "履帶"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"penetration": "%s生命值 擊穿",
|
"penetration": "%s1生命值 擊穿",
|
||||||
"blocked": "阻擋傷害",
|
"blocked": "阻擋傷害",
|
||||||
"ricochet": "跳彈",
|
"ricochet": "跳彈",
|
||||||
"splash": "%s生命值 爆炸範圍"
|
"splash": "%s生命值 爆炸範圍"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"thickness_and_angle": "等效%s毫米 %s2度",
|
"thickness_and_angle": "等效%s1毫米 %s2度",
|
||||||
"nominal": "%s毫米 裝甲厚度",
|
"nominal": "%s1毫米 裝甲厚度",
|
||||||
"ricochet_loss": "%s1%機率擊穿"
|
"ricochet_loss": "%s1%機率擊穿"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -900,7 +944,7 @@
|
|||||||
"characteristics": {
|
"characteristics": {
|
||||||
"title": "属性",
|
"title": "属性",
|
||||||
"compare": {
|
"compare": {
|
||||||
"label": "比較",
|
"label": "比较",
|
||||||
"class": "%s1 %s2 级",
|
"class": "%s1 %s2 级",
|
||||||
"tier": "所有级别 %s1",
|
"tier": "所有级别 %s1",
|
||||||
"all": "所有坦克"
|
"all": "所有坦克"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { mkdir, writeFile } from 'fs/promises';
|
|||||||
import { parse as parsePath } from 'path';
|
import { parse as parsePath } from 'path';
|
||||||
import ProgressBar from 'progress';
|
import ProgressBar from 'progress';
|
||||||
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
||||||
import { dvp } from '../../../submodules/blitzkit-closed/src/dvp';
|
import { dvp } from '../../../submodules/blitzkit-closed/src/dava/dvp';
|
||||||
import { readStringDVPL } from '../src/core/blitz/readStringDVPL';
|
import { readStringDVPL } from '../src/core/blitz/readStringDVPL';
|
||||||
import { DATA } from './buildAssets/constants';
|
import { DATA } from './buildAssets/constants';
|
||||||
import { readYAMLDVPL } from './core/blitz/readYAMLDVPL';
|
import { readYAMLDVPL } from './core/blitz/readYAMLDVPL';
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ const WINDOWS_APPS = 'C:/Program Files/WindowsApps';
|
|||||||
const wotbPackageRegex = /7458BE2C\..+_\d+(\.\d+)+_x64__.+/;
|
const wotbPackageRegex = /7458BE2C\..+_\d+(\.\d+)+_x64__.+/;
|
||||||
|
|
||||||
const isDepot = argv.includes('--depot');
|
const isDepot = argv.includes('--depot');
|
||||||
|
const isManual = argv.includes('--manual');
|
||||||
|
|
||||||
let data: string;
|
let data: string;
|
||||||
let compressed: boolean;
|
let compressed: boolean;
|
||||||
|
|
||||||
if (isDepot) {
|
if (isManual) {
|
||||||
|
data = '../../temp/game/Data';
|
||||||
|
compressed = true;
|
||||||
|
} else if (isDepot) {
|
||||||
const [installationVersion] = await readdir(`../../depots/444202`);
|
const [installationVersion] = await readdir(`../../depots/444202`);
|
||||||
data = `../../depots/444202/${installationVersion}/Data`;
|
data = `../../depots/444202/${installationVersion}/Data`;
|
||||||
compressed = true;
|
compressed = true;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
ResearchCost,
|
ResearchCost,
|
||||||
ShellType,
|
ShellType,
|
||||||
SkillDefinitions,
|
SkillDefinitions,
|
||||||
|
slugify,
|
||||||
TankClass,
|
TankClass,
|
||||||
TankDefinitions,
|
TankDefinitions,
|
||||||
TankPrice,
|
TankPrice,
|
||||||
@@ -37,7 +38,6 @@ import {
|
|||||||
SUPPORTED_LOCALES,
|
SUPPORTED_LOCALES,
|
||||||
} from '@blitzkit/i18n';
|
} from '@blitzkit/i18n';
|
||||||
import { readdir } from 'fs/promises';
|
import { readdir } from 'fs/promises';
|
||||||
import { deburr } from 'lodash-es';
|
|
||||||
import { parse as parsePath } from 'path';
|
import { parse as parsePath } from 'path';
|
||||||
import { Vector3Tuple } from 'three';
|
import { Vector3Tuple } from 'three';
|
||||||
import { parse as parseYaml } from 'yaml';
|
import { parse as parseYaml } from 'yaml';
|
||||||
@@ -49,11 +49,6 @@ import { DATA } from './constants';
|
|||||||
import { Avatar } from './skillIcons';
|
import { Avatar } from './skillIcons';
|
||||||
import { TankParameters } from './tankIcons';
|
import { TankParameters } from './tankIcons';
|
||||||
|
|
||||||
const nonAlphanumericRegex = /[^a-z0-9]/g;
|
|
||||||
const multipleDashesRegex = /--+/g;
|
|
||||||
const trailingDashRegex = /-$/g;
|
|
||||||
const leadingDashRegex = /^-/g;
|
|
||||||
|
|
||||||
const nationSlugDiscriminators = {
|
const nationSlugDiscriminators = {
|
||||||
china: 'cn',
|
china: 'cn',
|
||||||
european: 'eu',
|
european: 'eu',
|
||||||
@@ -740,12 +735,7 @@ export async function definitions() {
|
|||||||
? getString(tank.shortUserString)
|
? getString(tank.shortUserString)
|
||||||
: undefined) ?? getString(tank.userString)
|
: undefined) ?? getString(tank.userString)
|
||||||
).locales.en;
|
).locales.en;
|
||||||
|
const slug = slugify(name);
|
||||||
let slug = deburr(name).toLowerCase();
|
|
||||||
slug = slug.replaceAll(nonAlphanumericRegex, '-');
|
|
||||||
slug = slug.replaceAll(multipleDashesRegex, '-');
|
|
||||||
slug = slug.replaceAll(trailingDashRegex, '');
|
|
||||||
slug = slug.replaceAll(leadingDashRegex, '');
|
|
||||||
|
|
||||||
idToNation[tankId] = nation;
|
idToNation[tankId] = nation;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
|
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
|
||||||
import locales from '@blitzkit/i18n/locales.json';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { extname } from 'path';
|
import { extname } from 'path';
|
||||||
import ProgressBar from 'progress';
|
import ProgressBar from 'progress';
|
||||||
import { commitAssets } from '../core/github/commitAssets';
|
import { commitAssets } from '../core/github/commitAssets';
|
||||||
|
|||||||
@@ -28,26 +28,24 @@ export async function tankModels() {
|
|||||||
|
|
||||||
console.log(`Building models for ${nation}`);
|
console.log(`Building models for ${nation}`);
|
||||||
|
|
||||||
await Promise.all(
|
for (const [tankKey, tank] of Object.entries(tanks.root)) {
|
||||||
Object.entries(tanks.root).map(async ([tankKey, tank]) => {
|
if (tankKey.includes('tutorial_bot')) continue;
|
||||||
if (tankKey.includes('tutorial_bot')) return;
|
|
||||||
|
|
||||||
const id = toUniqueId(nation, tank.id);
|
const id = toUniqueId(nation, tank.id);
|
||||||
|
|
||||||
const parameters = await readYAMLDVPL<TankParameters>(
|
const parameters = await readYAMLDVPL<TankParameters>(
|
||||||
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||||
);
|
);
|
||||||
const model = await extractModel(
|
const model = await extractModel(
|
||||||
DATA,
|
DATA,
|
||||||
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ''),
|
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ''),
|
||||||
);
|
);
|
||||||
|
|
||||||
changes.push({
|
changes.push({
|
||||||
path: `3d/tanks/models/${id}.glb`,
|
path: `3d/tanks/models/${id}.glb`,
|
||||||
content: Buffer.from(await nodeIO.writeBinary(model)),
|
content: Buffer.from(await nodeIO.writeBinary(model)),
|
||||||
});
|
});
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
|
|
||||||
await commitAssets(`tank models ${nation}`, changes);
|
await commitAssets(`tank models ${nation}`, changes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { readFile } from 'fs/promises';
|
import { readFile } from 'fs/promises';
|
||||||
import { DATA_COMPRESSED } from '../../buildAssets/constants';
|
|
||||||
import { readDVPL } from './readDVPL';
|
import { readDVPL } from './readDVPL';
|
||||||
|
|
||||||
export async function readDVPLFile(file: string) {
|
export async function readDVPLFile(file: string) {
|
||||||
if (DATA_COMPRESSED && !file.endsWith('.dvpl')) {
|
const path = `${file}${file.endsWith('.dvpl') ? '' : '.dvpl'}`;
|
||||||
return readDVPL(await readFile(`${file}.dvpl`));
|
const content = await readFile(path);
|
||||||
}
|
const dvpl = readDVPL(content);
|
||||||
|
|
||||||
return readFile(file);
|
return dvpl;
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
|
|||||||
const resolvedTexturePath = isDds
|
const resolvedTexturePath = isDds
|
||||||
? ddsTexturePath
|
? ddsTexturePath
|
||||||
: ddsTexturePath.replace('.dds', '.pvr');
|
: ddsTexturePath.replace('.dds', '.pvr');
|
||||||
const decompressedDvpl = await readDVPLFile(resolvedTexturePath);
|
const decompressedDvpl = await readDVPLFile(`${resolvedTexturePath}.dvpl`);
|
||||||
|
|
||||||
const raw = isDds
|
const raw = isDds
|
||||||
? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds()
|
? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds()
|
||||||
@@ -75,4 +75,5 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
|
|||||||
default:
|
default:
|
||||||
return await sharp(raw.data, { raw }).jpeg().toBuffer();
|
return await sharp(raw.data, { raw }).jpeg().toBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import { exec as execSync } from 'child_process';
|
import { exec as execSync } from 'child_process';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { readdir, rm, writeFile } from 'fs/promises';
|
import { readdir, rm, writeFile } from 'fs/promises';
|
||||||
|
import { chunk } from 'lodash-es';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
const ROOT = 'packages/core/src/protos';
|
|
||||||
|
|
||||||
const exec = promisify(execSync);
|
const exec = promisify(execSync);
|
||||||
|
|
||||||
let executableFileExtension: string;
|
let executableFileExtension: string;
|
||||||
@@ -15,33 +14,42 @@ if (existsSync('node_modules/.bin/protoc-gen-ts_proto.exe')) {
|
|||||||
executableFileExtension = '';
|
executableFileExtension = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesRaw = await readdir(`${ROOT}`);
|
await compile('packages/core/src/protos');
|
||||||
await Promise.all(
|
await compile('submodules/blitzkit-closed/src/protos');
|
||||||
filesRaw.map(async (file) => {
|
|
||||||
if (!file.endsWith('.proto')) {
|
|
||||||
await rm(`${ROOT}/${file}`);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const files = filesRaw.filter((file) => file.endsWith('.proto'));
|
async function compile(root: string) {
|
||||||
const args = [
|
const filesRaw = await readdir(root);
|
||||||
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
|
|
||||||
'--ts_proto_opt=esModuleInterop=true',
|
|
||||||
'--ts_proto_opt=oneof=unions-value',
|
|
||||||
'--ts_proto_opt=removeEnumPrefix=true',
|
|
||||||
'--ts_proto_opt=unrecognizedEnum=false',
|
|
||||||
'--ts_proto_opt=snakeToCamel=false',
|
|
||||||
'--ts_proto_out=.',
|
|
||||||
...files.map((file) => `${ROOT}/${file}`),
|
|
||||||
];
|
|
||||||
|
|
||||||
await exec(`protoc ${args.join(' ')}`);
|
for (const file of filesRaw) {
|
||||||
await writeFile(
|
if (!file.endsWith('.ts')) continue;
|
||||||
`${ROOT}/index.ts`,
|
await rm(`${root}/${file}`);
|
||||||
'// @ts-nocheck\n' +
|
}
|
||||||
files
|
|
||||||
.map((file) => file.replace('.proto', ''))
|
const allFiles = filesRaw.filter((file) => file.endsWith('.proto'));
|
||||||
.map((file) => `export * from './${file}.ts';`)
|
|
||||||
.join('\n'),
|
for (const files of chunk(allFiles, 32)) {
|
||||||
);
|
const args = [
|
||||||
|
`-I=${root}`,
|
||||||
|
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
|
||||||
|
'--ts_proto_opt=esModuleInterop=true',
|
||||||
|
'--ts_proto_opt=oneof=unions-value',
|
||||||
|
// '--ts_proto_opt=removeEnumPrefix=true',
|
||||||
|
'--ts_proto_opt=unrecognizedEnum=false',
|
||||||
|
'--ts_proto_opt=snakeToCamel=false',
|
||||||
|
`--ts_proto_out=${root}`,
|
||||||
|
...files.map((file) => `${root}/${file}`),
|
||||||
|
];
|
||||||
|
|
||||||
|
await exec(`protoc ${args.join(' ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(
|
||||||
|
`${root}/index.ts`,
|
||||||
|
'// @ts-nocheck\n' +
|
||||||
|
allFiles
|
||||||
|
.sort()
|
||||||
|
.map((file) => file.replace('.proto', ''))
|
||||||
|
.map((file) => `export * from './${file}.ts';`)
|
||||||
|
.join('\n'),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"include": ["src/**/*"]
|
"include": ["src/**/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "../../"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,13 @@
|
|||||||
import partytown from '@astrojs/partytown';
|
import partytown from '@astrojs/partytown';
|
||||||
import react from '@astrojs/react';
|
import react from '@astrojs/react';
|
||||||
import sitemap from '@astrojs/sitemap';
|
import sitemap from '@astrojs/sitemap';
|
||||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: 'en',
|
defaultLocale: locales.default,
|
||||||
locales: [...SUPPORTED_LOCALES],
|
locales: locales.supported.map(({ locale }) => locale),
|
||||||
routing: {
|
routing: {
|
||||||
prefixDefaultLocale: false,
|
prefixDefaultLocale: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/partytown": "^2.1.4",
|
"@astrojs/partytown": "^2.1.4",
|
||||||
"@astrolib/seo": "^1.0.0-beta.8",
|
"@astrolib/seo": "^1.0.0-beta.8",
|
||||||
|
"@blitzkit/closed": "workspace:*",
|
||||||
"@blitzkit/core": "workspace:*",
|
"@blitzkit/core": "workspace:*",
|
||||||
"@blitzkit/i18n": "workspace:*",
|
"@blitzkit/i18n": "workspace:*",
|
||||||
"@fontsource/inter": "^5.2.5",
|
"@fontsource/inter": "^5.2.5",
|
||||||
@@ -20,10 +21,10 @@
|
|||||||
"@nivo/bar": "^0.87.0",
|
"@nivo/bar": "^0.87.0",
|
||||||
"@nivo/line": "^0.88.0",
|
"@nivo/line": "^0.88.0",
|
||||||
"@radix-ui/colors": "^3.0.0",
|
"@radix-ui/colors": "^3.0.0",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@radix-ui/themes": "^3.1.4",
|
"@radix-ui/themes": "^3.2.1",
|
||||||
"@react-three/drei": "^9.115.0",
|
"@react-three/drei": "^10.0.8",
|
||||||
"@react-three/fiber": "^8.17.10",
|
"@react-three/fiber": "^9.1.2",
|
||||||
"compare-versions": "^6.1.1",
|
"compare-versions": "^6.1.1",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"immer": "^10.1.1",
|
"immer": "^10.1.1",
|
||||||
@@ -31,9 +32,7 @@
|
|||||||
"markdown-to-jsx": "^7.5.0",
|
"markdown-to-jsx": "^7.5.0",
|
||||||
"nanostores": "^0.11.3",
|
"nanostores": "^0.11.3",
|
||||||
"quicklime": "^1.2.0",
|
"quicklime": "^1.2.0",
|
||||||
"react": "^18.3.1",
|
|
||||||
"react-device-detect": "^2.2.3",
|
"react-device-detect": "^2.2.3",
|
||||||
"react-dom": "^18.3.1",
|
|
||||||
"react-promise-suspense": "^0.3.4",
|
"react-promise-suspense": "^0.3.4",
|
||||||
"three": "^0.169.0",
|
"three": "^0.169.0",
|
||||||
"urlon": "^3.1.0",
|
"urlon": "^3.1.0",
|
||||||
@@ -46,10 +45,7 @@
|
|||||||
"@playform/compress": "^0.1.9",
|
"@playform/compress": "^0.1.9",
|
||||||
"@playform/inline": "^0.1.2",
|
"@playform/inline": "^0.1.2",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/react": "^18.3.12",
|
|
||||||
"@types/react-dom": "^18.3.1",
|
|
||||||
"@types/three": "^0.160.0",
|
"@types/three": "^0.160.0",
|
||||||
"astro": "^4.16.7",
|
"astro": "^4.16.7"
|
||||||
"astro-compressor": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -23,7 +23,9 @@ export function AesonPlug() {
|
|||||||
|
|
||||||
<Flex py="3" px="5" direction="column" justify="center">
|
<Flex py="3" px="5" direction="column" justify="center">
|
||||||
<Heading size="5">Preview brought to you by WoT Blitz News</Heading>
|
<Heading size="5">Preview brought to you by WoT Blitz News</Heading>
|
||||||
<Text color="gray">What the hell do I put here haha</Text>
|
<Text color="gray">
|
||||||
|
Join the Discord for the absolute latest news
|
||||||
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,16 +1,29 @@
|
|||||||
import { TankClass } from '@blitzkit/core';
|
import { TankClass as TankClass_dava } from '@blitzkit/core';
|
||||||
|
import { TankClass } from '@protos/blitz_static_tank_component';
|
||||||
|
import { QuestionMarkIcon } from '@radix-ui/react-icons';
|
||||||
import type { ComponentProps, ReactNode } from 'react';
|
import type { ComponentProps, ReactNode } from 'react';
|
||||||
import { ClassHeavy } from './components/ClassHeavy';
|
import { ClassHeavy } from './components/ClassHeavy';
|
||||||
import { ClassLight } from './components/ClassLight';
|
import { ClassLight } from './components/ClassLight';
|
||||||
import { ClassMedium } from './components/ClassMedium';
|
import { ClassMedium } from './components/ClassMedium';
|
||||||
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
|
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
|
||||||
|
|
||||||
export const classIcons: Record<
|
export const classIcons_ue: Record<
|
||||||
TankClass,
|
TankClass,
|
||||||
|
((props: ComponentProps<'svg'>) => ReactNode) | typeof QuestionMarkIcon
|
||||||
|
> = {
|
||||||
|
[TankClass.TANK_CLASS_UNSPECIFIED]: QuestionMarkIcon,
|
||||||
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
|
||||||
|
[TankClass.TANK_CLASS_HEAVY]: ClassHeavy,
|
||||||
|
[TankClass.TANK_CLASS_LIGHT]: ClassLight,
|
||||||
|
[TankClass.TANK_CLASS_MEDIUM]: ClassMedium,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const classIcons: Record<
|
||||||
|
TankClass_dava,
|
||||||
(props: ComponentProps<'svg'>) => ReactNode
|
(props: ComponentProps<'svg'>) => ReactNode
|
||||||
> = {
|
> = {
|
||||||
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
|
[TankClass_dava.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
|
||||||
[TankClass.HEAVY]: ClassHeavy,
|
[TankClass_dava.TANK_CLASS_HEAVY]: ClassHeavy,
|
||||||
[TankClass.LIGHT]: ClassLight,
|
[TankClass_dava.TANK_CLASS_LIGHT]: ClassLight,
|
||||||
[TankClass.MEDIUM]: ClassMedium,
|
[TankClass_dava.TANK_CLASS_MEDIUM]: ClassMedium,
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import type { RewardCurrency } from '@protos/blitz_static_reward_currency';
|
||||||
|
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
||||||
|
import { entityName } from 'packages/core/src';
|
||||||
|
import { useLocale } from '../hooks/useLocale';
|
||||||
|
|
||||||
|
type CurrencyProps = TextProps & {
|
||||||
|
reward: RewardCurrency;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Currency({ reward, ...props }: CurrencyProps) {
|
||||||
|
const { locale } = useLocale();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text {...props}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
{reward.amount.toLocaleString(locale)}
|
||||||
|
<img
|
||||||
|
src={`/api/currencies/${entityName(reward.currency_catalog_id)}.webp`}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -130,15 +130,13 @@ const strings = getStrings(locale);
|
|||||||
<Flex gap="5" display={{ initial: 'flex', sm: 'none' }}>
|
<Flex gap="5" display={{ initial: 'flex', sm: 'none' }}>
|
||||||
<Flex direction="column" justify="between" align="end">
|
<Flex direction="column" justify="between" align="end">
|
||||||
<Text size="2" color="gray">BlitzKit</Text>
|
<Text size="2" color="gray">BlitzKit</Text>
|
||||||
|
|
||||||
{
|
{
|
||||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||||
<Text size="2" color="gray">
|
<Text size="2" color="gray">
|
||||||
WoTB
|
WoTB
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<Text size="2" color="gray">CDN</Text>
|
<Text size="2" color="gray">CDN</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
@@ -146,15 +144,13 @@ const strings = getStrings(locale);
|
|||||||
<Code size="2" color="gray">
|
<Code size="2" color="gray">
|
||||||
{packageJson.version}
|
{packageJson.version}
|
||||||
</Code>
|
</Code>
|
||||||
|
|
||||||
{
|
{
|
||||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||||
<Code size="2" color="gray">
|
<Code size="2" color="gray">
|
||||||
{gameDefinitions.version}
|
{gameDefinitions.version}
|
||||||
</Code>
|
</Code>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<Code size="2" color="gray">
|
<Code size="2" color="gray">
|
||||||
{PUBLIC_ASSET_BRANCH}
|
{PUBLIC_ASSET_BRANCH}
|
||||||
</Code>
|
</Code>
|
||||||
@@ -168,7 +164,7 @@ const strings = getStrings(locale);
|
|||||||
</Code>
|
</Code>
|
||||||
|
|
||||||
{
|
{
|
||||||
PUBLIC_ASSET_BRANCH !== 'opentest' && (
|
PUBLIC_ASSET_BRANCH !== 'preview' && (
|
||||||
<>
|
<>
|
||||||
<Text size="2" color="gray">
|
<Text size="2" color="gray">
|
||||||
WoTB
|
WoTB
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import locales from '@blitzkit/i18n/locales.json';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { literals } from '@blitzkit/i18n/src/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Flex, Text } from '@radix-ui/themes';
|
import { Flex, Text } from '@radix-ui/themes';
|
||||||
import fuzzysort from 'fuzzysort';
|
import fuzzysort from 'fuzzysort';
|
||||||
|
|||||||
@@ -3,11 +3,16 @@ import { Code, Flex, Heading, Text } from '@radix-ui/themes';
|
|||||||
import { resolveBranchName } from '../core/blitzkit/branches';
|
import { resolveBranchName } from '../core/blitzkit/branches';
|
||||||
import { getStrings } from '../core/i18n/getStrings';
|
import { getStrings } from '../core/i18n/getStrings';
|
||||||
import { literals } from '@blitzkit/i18n/src/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
|
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||||
|
|
||||||
const { locale } = Astro.params;
|
interface Props {
|
||||||
|
locale: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { locale } = Astro.props;
|
||||||
|
const strings = await getStrings(locale);
|
||||||
const branchName = resolveBranchName(locale);
|
const branchName = resolveBranchName(locale);
|
||||||
const isBranchNamed = branchName !== undefined;
|
const isBranchNamed = branchName !== undefined;
|
||||||
const strings = getStrings(locale);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
||||||
import { Link, type LinkProps } from '@radix-ui/themes';
|
import { Link, type LinkProps } from '@radix-ui/themes';
|
||||||
import type { LocaleAcceptorProps } from '../hooks/useLocale';
|
|
||||||
|
|
||||||
type LinkI18nProps = LinkProps & LocaleAcceptorProps;
|
type LinkI18nProps = LinkProps & {
|
||||||
|
locale: string;
|
||||||
|
};
|
||||||
|
|
||||||
export function LinkI18n({ locale, href, ...props }: LinkI18nProps) {
|
export function LinkI18n({ locale, href, ...props }: LinkI18nProps) {
|
||||||
const prefix =
|
const prefix = locale === DEFAULT_LOCALE ? '' : `/${locale}`;
|
||||||
locale === undefined || locale === DEFAULT_LOCALE ? '' : `/${locale}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={href?.startsWith('/') ? `${prefix}${href}` : href} {...props} />
|
<Link href={href?.startsWith('/') ? `${prefix}${href}` : href} {...props} />
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ import { LinkI18n } from './LinkI18n';
|
|||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
integrated?: boolean;
|
integrated?: boolean;
|
||||||
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { integrated } = Astro.props;
|
const { integrated, locale } = Astro.props;
|
||||||
const toolsFiltered = TOOLS.filter((tool) => !('href' in tool));
|
const toolsFiltered = TOOLS.filter((tool) => !('href' in tool));
|
||||||
const { locale } = Astro.params;
|
|
||||||
const branchName = resolveBranchName(locale);
|
const branchName = resolveBranchName(locale);
|
||||||
const isBranchNamed = branchName !== undefined;
|
const isBranchNamed = branchName !== undefined;
|
||||||
const strings = getStrings(locale);
|
const strings = getStrings(locale);
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ export function Listing({ label, ...props }: ListingProps) {
|
|||||||
gap="4"
|
gap="4"
|
||||||
style={{ borderBottom: `1px solid ${Var('gray-a9')}` }}
|
style={{ borderBottom: `1px solid ${Var('gray-a9')}` }}
|
||||||
>
|
>
|
||||||
<Text size="4">{label}</Text>
|
<Text size="4" wrap="nowrap">
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
<Text align="right" size="4" weight="medium" {...props} />
|
<Text align="right" size="4" weight="medium" {...props} />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import { Nation, TankType } from '@protos/blitz_static_tank_component';
|
||||||
|
import { Box, Code, Flex } from '@radix-ui/themes';
|
||||||
|
import { asset, TIER_ROMAN_NUMERALS } from 'packages/core/src';
|
||||||
|
import { Var } from '../../core/radix/var';
|
||||||
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
|
import { TankopediaEphemeral_ue } from '../../stores/tankopediaEphemeral_ue';
|
||||||
|
import { classIcons_ue } from '../ClassIcon';
|
||||||
|
import { Currency } from '../Currency';
|
||||||
|
import { Listing } from '../Tankopedia/MetaSection/components/Listing';
|
||||||
|
|
||||||
|
const NATIONAL_BANNER_POSITION_OVERRIDES: Partial<Record<Nation, string>> = {
|
||||||
|
[Nation.NATION_GERMANY]: '50% 35%',
|
||||||
|
[Nation.NATION_FRANCE]: '50% 35%',
|
||||||
|
[Nation.NATION_OTHER]: '50% 35%',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function MetaSection() {
|
||||||
|
const tank = TankopediaEphemeral_ue.use((state) => state.tank);
|
||||||
|
const entity = TankopediaEphemeral_ue.use((state) => state.entity);
|
||||||
|
const set = TankopediaEphemeral_ue.use((state) => state.set);
|
||||||
|
const compensation = TankopediaEphemeral_ue.use(
|
||||||
|
(state) => state.compensation,
|
||||||
|
);
|
||||||
|
const catalogueId = TankopediaEphemeral_ue.use((state) => state.entity);
|
||||||
|
const ClassIcon = classIcons_ue[tank.tank_class];
|
||||||
|
const { locale, strings, gameStrings } = useLocale();
|
||||||
|
const reward = set.tank_set_rewards.find(
|
||||||
|
(reward) =>
|
||||||
|
reward.tank_set_reward_on_level &&
|
||||||
|
reward.tank_set_reward_on_level.reward_list.some(
|
||||||
|
(rewardOnLevel) =>
|
||||||
|
rewardOnLevel.tank_reward &&
|
||||||
|
rewardOnLevel.tank_reward.tank_catalog_id === catalogueId,
|
||||||
|
),
|
||||||
|
)!;
|
||||||
|
const price =
|
||||||
|
reward.tank_set_reward_price?.price_list[0].currency_price!.amount;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex justify="center" mt="-9">
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
background: `url(/assets/images/national-wallpapers/${tank.nation}.jpg)`,
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition:
|
||||||
|
NATIONAL_BANNER_POSITION_OVERRIDES[tank.nation] ?? 'center',
|
||||||
|
}}
|
||||||
|
flexGrow="1"
|
||||||
|
maxWidth="120rem"
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
background: `url(${asset(`flags/scratched/${tank.nation}.webp`)})`,
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundSize: 'min(53rem, 80vw)',
|
||||||
|
backgroundPosition: '-8rem 50%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
justify="center"
|
||||||
|
align="center"
|
||||||
|
py="6rem"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(${Var('black-a8')}, ${Var('black-a8')}, ${Var('gray-1')})`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex direction="column" align="center" gap="6">
|
||||||
|
<Flex
|
||||||
|
gap={{ initial: '2', sm: '8' }}
|
||||||
|
direction={{ initial: 'column', sm: 'row' }}
|
||||||
|
>
|
||||||
|
<Flex direction="column" width="100%" gap="2">
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.nation}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
<img
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
alt={Nation[tank.nation]}
|
||||||
|
src={asset(`flags/circle/${tank.nation}.webp`)}
|
||||||
|
/>
|
||||||
|
{strings.common.nations[tank.nation]}
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.class}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
<ClassIcon width="1em" height="1em" />
|
||||||
|
{strings.common.tank_class[tank.tank_class]}
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.tier}>
|
||||||
|
{TIER_ROMAN_NUMERALS[tank.tier]}
|
||||||
|
</Listing>
|
||||||
|
|
||||||
|
<Listing
|
||||||
|
label={strings.website.tools.tankopedia.meta.type}
|
||||||
|
color={
|
||||||
|
tank.tank_type === TankType.TANK_TYPE_COLLECTIBLE
|
||||||
|
? 'blue'
|
||||||
|
: tank.tank_type === TankType.TANK_TYPE_PREMIUM
|
||||||
|
? 'amber'
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{strings.common.tree_type[tank.tank_type]}
|
||||||
|
</Listing>
|
||||||
|
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.id}>
|
||||||
|
<Code variant="ghost">
|
||||||
|
{entity.replace('TankEntity.', '')}
|
||||||
|
</Code>
|
||||||
|
</Listing>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex direction="column" width="100%" gap="2">
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.set}>
|
||||||
|
{gameStrings[set.tank_set_ui!.tank_set_displayed_name]}
|
||||||
|
</Listing>
|
||||||
|
|
||||||
|
<Listing label={strings.website.tools.tankopedia.meta.price}>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
{reward.tank_set_reward_price === undefined ? (
|
||||||
|
strings.website.tools.tankopedia.meta.free
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{price?.toLocaleString(locale)}
|
||||||
|
|
||||||
|
<img
|
||||||
|
style={{ width: '1em', height: '1em' }}
|
||||||
|
alt="xp"
|
||||||
|
src={
|
||||||
|
'https://wotblitz-gc.gcdn.co/dlc/ultra_test2_25abc2385a5/assets/Medusa/Currency/T_UI_Currency_Silver_S.webp'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Listing>
|
||||||
|
|
||||||
|
{compensation.compensation?.currency_reward && (
|
||||||
|
<Listing
|
||||||
|
label={strings.website.tools.tankopedia.meta.compensation}
|
||||||
|
>
|
||||||
|
<Currency
|
||||||
|
reward={compensation.compensation.currency_reward}
|
||||||
|
/>
|
||||||
|
</Listing>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
type CompositeStats,
|
type CompositeStats,
|
||||||
type CompositeStatsKey,
|
type CompositeStatsKey,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
import strings from '@blitzkit/i18n/strings/en.json';
|
|
||||||
import { amberDark, blueDark } from '@radix-ui/colors';
|
import { amberDark, blueDark } from '@radix-ui/colors';
|
||||||
import { Flex, Text, type FlexProps } from '@radix-ui/themes';
|
import { Flex, Text, type FlexProps } from '@radix-ui/themes';
|
||||||
import { times } from 'lodash-es';
|
import { times } from 'lodash-es';
|
||||||
@@ -53,7 +52,7 @@ export function BreakdownEmbedCard({
|
|||||||
}: BreakdownEmbedCardProps) {
|
}: BreakdownEmbedCardProps) {
|
||||||
const { useEmbedState, useRichText } =
|
const { useEmbedState, useRichText } =
|
||||||
useEmbedStateCurry<typeof breakdownConfig>();
|
useEmbedStateCurry<typeof breakdownConfig>();
|
||||||
const { unwrap } = useLocale();
|
const { unwrap, strings } = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
export function TestComponent({ data }: { data: any }) {
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(data);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return 'TestComponent';
|
||||||
|
}
|
||||||
@@ -2,20 +2,20 @@
|
|||||||
import { assertSecret } from '@blitzkit/core';
|
import { assertSecret } from '@blitzkit/core';
|
||||||
import { CaretRightIcon } from '@radix-ui/react-icons';
|
import { CaretRightIcon } from '@radix-ui/react-icons';
|
||||||
import { Box, Button, Code, Flex, Heading, Text } from '@radix-ui/themes';
|
import { Box, Button, Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||||
|
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||||
import type { Tool } from '../constants/tools';
|
import type { Tool } from '../constants/tools';
|
||||||
import { getStrings } from '../core/i18n/getStrings';
|
|
||||||
import { LinkI18n } from './LinkI18n';
|
import { LinkI18n } from './LinkI18n';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tool: Tool;
|
tool: Tool;
|
||||||
|
strings: BlitzKitStrings;
|
||||||
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tool } = Astro.props;
|
const { tool, strings, locale } = Astro.props;
|
||||||
const disabled = tool.branches?.every(
|
const disabled = tool.branches?.every(
|
||||||
(branch) => branch !== assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH),
|
(branch) => branch !== assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH),
|
||||||
);
|
);
|
||||||
const { locale } = Astro.params;
|
|
||||||
const strings = getStrings(locale);
|
|
||||||
const toolStrings =
|
const toolStrings =
|
||||||
strings.website.tools[
|
strings.website.tools[
|
||||||
(tool.stringsId ?? tool.id) as keyof typeof strings.website.tools
|
(tool.stringsId ?? tool.id) as keyof typeof strings.website.tools
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { DiscreteMetadataAccessor } from 'packages/core/src';
|
||||||
|
|
||||||
|
export const discreteMetadata = new DiscreteMetadataAccessor('/api/catalog');
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import type { TankSetCatalogComponent } from '@protos/blitz_static_tank_set_component';
|
||||||
|
import type { MetadataAccessor } from 'submodules/blitzkit-closed/src';
|
||||||
|
|
||||||
|
export async function tankToSet(metadata: MetadataAccessor, tank: string) {
|
||||||
|
for (const [id] of metadata.items) {
|
||||||
|
if (!id.startsWith('TankSetEntity')) continue;
|
||||||
|
|
||||||
|
const components = await metadata.get(id);
|
||||||
|
const set = await components.get<TankSetCatalogComponent>(
|
||||||
|
'tankSetCatalogComponent',
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const reward of set.tank_set_rewards) {
|
||||||
|
if (!reward.tank_set_reward_on_level) continue;
|
||||||
|
|
||||||
|
for (const rewardOnLevel of reward.tank_set_reward_on_level.reward_list) {
|
||||||
|
if (!rewardOnLevel.tank_reward) continue;
|
||||||
|
|
||||||
|
if (rewardOnLevel.tank_reward.tank_catalog_id === tank) {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Tank ${tank} not found in any set`);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { requestAutoProxyClient, unpackMetadata } from '@blitzkit/closed';
|
||||||
|
import type { GetPackedMetadataAsyncResponse } from '@blitzkit/closed/src/unreal/protos/auto_legacy_proxy_client';
|
||||||
|
import { UnpackedMetadataAccessor } from 'packages/core/src';
|
||||||
|
|
||||||
|
export const unpackedMetadata = new UnpackedMetadataAccessor(
|
||||||
|
await requestAutoProxyClient<GetPackedMetadataAsyncResponse>(
|
||||||
|
'GetPackedMetadataAsyncRequest',
|
||||||
|
).then(unpackMetadata),
|
||||||
|
);
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { DEFAULT_LOCALE, STRINGS, type SupportedLocale } from '@blitzkit/i18n';
|
import en from '@strings/en.json' with { type: 'json' };
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
|
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||||
|
|
||||||
export function getStrings(locale: string = DEFAULT_LOCALE) {
|
export async function getStrings(locale: string) {
|
||||||
if (locale in STRINGS) return STRINGS[locale as SupportedLocale];
|
const strings = await import(`../../../../i18n/strings/${locale}.json`);
|
||||||
throw new Error(`Unsupported locale: ${locale}`);
|
return merge({}, en, strings) as BlitzKitStrings;
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,30 @@
|
|||||||
import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { createContext, useContext, type ReactNode } from 'react';
|
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||||
import { getStrings } from '../core/i18n/getStrings';
|
import { createContext, use, useContext } from 'react';
|
||||||
|
const LocaleContext = createContext<string | null>(null);
|
||||||
|
|
||||||
const LocaleContext = createContext<{
|
interface LocaleProviderProps {
|
||||||
locale: string;
|
locale: string;
|
||||||
localeRaw: string | undefined;
|
children: React.ReactNode;
|
||||||
} | null>(null);
|
|
||||||
|
|
||||||
interface LocaleProviderProps extends LocaleAcceptorProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LocaleProvider({ locale, children }: LocaleProviderProps) {
|
export function LocaleProvider({ locale, children }: LocaleProviderProps) {
|
||||||
|
const isSupported = locales.supported.some(
|
||||||
|
(supported) => supported.locale === locale,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isSupported) throw new Error(`Unsupported locale: ${locale}`);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LocaleContext.Provider
|
<LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
|
||||||
value={{ locale: locale ?? DEFAULT_LOCALE, localeRaw: locale }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</LocaleContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLocale() {
|
export function useLocale() {
|
||||||
const context = useContext(LocaleContext);
|
const locale = useContext(LocaleContext);
|
||||||
|
const strings = use<BlitzKitStrings>(
|
||||||
|
fetch(`/api/strings/${locale}.json`).then((response) => response.json()),
|
||||||
|
);
|
||||||
|
|
||||||
if (!context) {
|
return { locale, strings };
|
||||||
throw new Error('useLocale must be used within a LocaleProvider');
|
|
||||||
}
|
|
||||||
|
|
||||||
const strings = getStrings(context.locale);
|
|
||||||
const unwrap = unwrapper(context.locale);
|
|
||||||
|
|
||||||
return { locale: context.locale, strings, unwrap };
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LocaleAcceptorProps {
|
|
||||||
locale: string | undefined;
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
import '@fontsource/inter';
|
|
||||||
import { Flex } from '@radix-ui/themes';
|
import { Flex } from '@radix-ui/themes';
|
||||||
import { BlitzKitTheme } from '../components/BlitzKitTheme';
|
import { BlitzKitTheme } from '../components/BlitzKitTheme';
|
||||||
import { Checks } from '../components/Checks';
|
import { Checks } from '../components/Checks';
|
||||||
@@ -7,16 +6,18 @@ import Footer from '../components/Footer.astro';
|
|||||||
import Navbar from '../components/Navbar.astro';
|
import Navbar from '../components/Navbar.astro';
|
||||||
import Party3 from '../components/Party3.astro';
|
import Party3 from '../components/Party3.astro';
|
||||||
import './base.css';
|
import './base.css';
|
||||||
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
import type { BlitzKitStrings } from 'packages/i18n/src';
|
||||||
|
import { getStrings } from '../core/i18n/getStrings';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
noFooter?: boolean;
|
noFooter?: boolean;
|
||||||
noNavbar?: boolean;
|
noNavbar?: boolean;
|
||||||
integrated?: boolean;
|
integrated?: boolean;
|
||||||
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { noFooter, noNavbar, integrated } = Astro.props;
|
const { noFooter, noNavbar, integrated, locale } = Astro.props;
|
||||||
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
const strings = await getStrings(locale);
|
||||||
---
|
---
|
||||||
|
|
||||||
<html lang={locale}>
|
<html lang={locale}>
|
||||||
@@ -30,25 +31,26 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|||||||
<Party3 />
|
<Party3 />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { getBestLocale } from '../core/i18n/getBestLocale';
|
import { getBestLocale } from '../core/i18n/getBestLocale';
|
||||||
const isAPI = window.location.pathname.startsWith('/api');
|
const isAPI = window.location.pathname.startsWith('/api');
|
||||||
const isI18nPath = SUPPORTED_LOCALES.some((locale) =>
|
const isI18nPath = locales.supported.some(({ locale }) =>
|
||||||
window.location.pathname.startsWith(`/${locale}`),
|
window.location.pathname.startsWith(`/${locale}`),
|
||||||
);
|
);
|
||||||
const bestLocale = getBestLocale();
|
const bestLocale = getBestLocale();
|
||||||
const currentPathLocale = SUPPORTED_LOCALES.find((locale) =>
|
const currentPathLocale = locales.supported.find(({ locale }) =>
|
||||||
window.location.pathname.startsWith(`/${locale}`),
|
window.location.pathname.startsWith(`/${locale}`),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isAPI && // not an api, duh!
|
!isAPI && // not an api, duh!
|
||||||
localStorage.getItem('preferred-locale') !== null && // no preference, so probably google's crawler
|
localStorage.getItem('preferred-locale') !== null && // no preference, so probably google's crawler
|
||||||
bestLocale !== currentPathLocale // we need to redirect
|
currentPathLocale &&
|
||||||
|
bestLocale !== currentPathLocale.locale // we need to redirect
|
||||||
) {
|
) {
|
||||||
window.location.pathname = isI18nPath
|
window.location.pathname = isI18nPath
|
||||||
? window.location.pathname.replace(
|
? window.location.pathname.replace(
|
||||||
`/${currentPathLocale}`,
|
`/${currentPathLocale.locale}`,
|
||||||
bestLocale === undefined ? '' : `/${bestLocale}`,
|
bestLocale === undefined ? '' : `/${bestLocale}`,
|
||||||
)
|
)
|
||||||
: `/${bestLocale}${window.location.pathname}`;
|
: `/${bestLocale}${window.location.pathname}`;
|
||||||
@@ -61,9 +63,9 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|||||||
<body class={noNavbar ? 'no-navbar' : ''}>
|
<body class={noNavbar ? 'no-navbar' : ''}>
|
||||||
<BlitzKitTheme>
|
<BlitzKitTheme>
|
||||||
<Flex direction="column" minHeight="100vh">
|
<Flex direction="column" minHeight="100vh">
|
||||||
<Navbar {integrated} />
|
<Navbar {locale} {integrated} />
|
||||||
|
|
||||||
<Checks {locale} client:only="react" />
|
<Checks localeContext={{ locale, strings }} client:only="react" />
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
@import '@radix-ui/themes/styles.css';
|
@import '@radix-ui/themes/styles.css';
|
||||||
|
|
||||||
.radix-themes {
|
|
||||||
--default-font-family: 'Inter';
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
---
|
---
|
||||||
import { AstroSeo } from '@astrolib/seo';
|
import { AstroSeo } from '@astrolib/seo';
|
||||||
import { assertSecret } from '@blitzkit/core';
|
import { assertSecret } from '@blitzkit/core';
|
||||||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
import { literals } from '@blitzkit/i18n/src/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Box, Flex, Heading, Link } from '@radix-ui/themes';
|
import { Box, Flex, Heading, Link } from '@radix-ui/themes';
|
||||||
import type { GetStaticPaths } from 'astro';
|
import type { GetStaticPaths } from 'astro';
|
||||||
import { AesonPlug } from '../../components/AesonPlug';
|
import { AesonPlug } from '../../components/AesonPlug';
|
||||||
import HomeHero from '../../components/HomeHero.astro';
|
import HomeHero from '../../components/HomeHero.astro';
|
||||||
import { HomePageHotTanks } from '../../components/HomePageHotTanks';
|
|
||||||
import { Plugs } from '../../components/Plugs';
|
import { Plugs } from '../../components/Plugs';
|
||||||
import ToolCard from '../../components/ToolCard.astro';
|
import ToolCard from '../../components/ToolCard.astro';
|
||||||
import {
|
import {
|
||||||
@@ -25,17 +24,16 @@ import { getStrings } from '../../core/i18n/getStrings';
|
|||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
|
|
||||||
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
||||||
const MODE = assertSecret(import.meta.env.MODE);
|
const { locale } = Astro.props;
|
||||||
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
const strings = await getStrings(locale);
|
||||||
const strings = getStrings(Astro.params.locale);
|
|
||||||
|
|
||||||
export const getStaticPaths = (() => {
|
export const getStaticPaths = (() => {
|
||||||
return [
|
return locales.supported.map(({ locale, blitz }) => {
|
||||||
...SUPPORTED_LOCALES.filter((locale) => locale !== DEFAULT_LOCALE).map(
|
return {
|
||||||
(locale) => ({ params: { locale } }),
|
params: { locale: locale === locales.default ? undefined : locale },
|
||||||
),
|
props: { locale, blitzLocale: blitz ?? locale },
|
||||||
{ params: { locale: undefined } },
|
};
|
||||||
];
|
});
|
||||||
}) satisfies GetStaticPaths;
|
}) satisfies GetStaticPaths;
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -52,8 +50,8 @@ export const getStaticPaths = (() => {
|
|||||||
twitter={{ cardType: 'summary_large_image' }}
|
twitter={{ cardType: 'summary_large_image' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseLayout>
|
<BaseLayout {locale}>
|
||||||
<HomeHero />
|
<HomeHero {locale} />
|
||||||
|
|
||||||
<!-- <Flex justify="center" py="6" px="4" justify="center">
|
<!-- <Flex justify="center" py="6" px="4" justify="center">
|
||||||
<Flex
|
<Flex
|
||||||
@@ -72,7 +70,7 @@ export const getStaticPaths = (() => {
|
|||||||
</Flex> -->
|
</Flex> -->
|
||||||
|
|
||||||
{
|
{
|
||||||
locale !== DEFAULT_LOCALE && (
|
locale !== locales.default && (
|
||||||
<Flex justify="center" mb="4">
|
<Flex justify="center" mb="4">
|
||||||
<Link
|
<Link
|
||||||
href="https://crowdin.com/project/blitzkrieg"
|
href="https://crowdin.com/project/blitzkrieg"
|
||||||
@@ -81,7 +79,9 @@ export const getStaticPaths = (() => {
|
|||||||
>
|
>
|
||||||
{literals(strings.website.home.help_translate, [
|
{literals(strings.website.home.help_translate, [
|
||||||
'BlitzKit',
|
'BlitzKit',
|
||||||
strings.common.locales[locale],
|
strings.common.locales[
|
||||||
|
locale as keyof typeof strings.common.locales
|
||||||
|
],
|
||||||
])}
|
])}
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -100,35 +100,29 @@ export const getStaticPaths = (() => {
|
|||||||
|
|
||||||
<Flex p="4" justify="center" gap="4" mt="3">
|
<Flex p="4" justify="center" gap="4" mt="3">
|
||||||
<Flex maxWidth="80rem" flexGrow="1" gap="4" direction="column">
|
<Flex maxWidth="80rem" flexGrow="1" gap="4" direction="column">
|
||||||
<ToolCard tool={tankopediaTool} />
|
<ToolCard {locale} {strings} tool={tankopediaTool} />
|
||||||
|
|
||||||
{
|
|
||||||
(PUBLIC_ASSET_BRANCH === 'main' || MODE === 'development') && (
|
|
||||||
<HomePageHotTanks {locale} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
{/* <ToolCard tool={playerStatsTool} /> */}
|
{/* <ToolCard {locale} {strings} tool={playerStatsTool} /> */}
|
||||||
<ToolCard tool={compareTool} />
|
<ToolCard {locale} {strings} tool={compareTool} />
|
||||||
<ToolCard tool={performanceTool} />
|
<ToolCard {locale} {strings} tool={performanceTool} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
<!-- <ToolCard tool={chartsTool} /> -->
|
<!-- <ToolCard {locale} {strings} tool={chartsTool} /> -->
|
||||||
<!-- <ToolCard tool={guessTool} /> -->
|
<!-- <ToolCard {locale} {strings} tool={guessTool} /> -->
|
||||||
<ToolCard tool={galleryTool} />
|
<ToolCard {locale} {strings} tool={galleryTool} />
|
||||||
<ToolCard tool={sessionTool} />
|
<ToolCard {locale} {strings} tool={sessionTool} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
<ToolCard tool={discordTool} />
|
<ToolCard {locale} {strings} tool={discordTool} />
|
||||||
<ToolCard tool={tierListTool} />
|
<ToolCard {locale} {strings} tool={tierListTool} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
<ToolCard tool={embedTool} />
|
<ToolCard {locale} {strings} tool={embedTool} />
|
||||||
<ToolCard tool={moreTool} />
|
<ToolCard {locale} {strings} tool={moreTool} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
@@ -141,6 +135,8 @@ export const getStaticPaths = (() => {
|
|||||||
|
|
||||||
<Flex gap="4" mb="6" direction={{ initial: 'column', sm: 'row' }}>
|
<Flex gap="4" mb="6" direction={{ initial: 'column', sm: 'row' }}>
|
||||||
<ToolCard
|
<ToolCard
|
||||||
|
{locale}
|
||||||
|
{strings}
|
||||||
tool={{
|
tool={{
|
||||||
button: { color: 'blue' },
|
button: { color: 'blue' },
|
||||||
id: 'blitz-analysis',
|
id: 'blitz-analysis',
|
||||||
@@ -149,6 +145,8 @@ export const getStaticPaths = (() => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ToolCard
|
<ToolCard
|
||||||
|
{locale}
|
||||||
|
{strings}
|
||||||
tool={{
|
tool={{
|
||||||
button: { color: 'purple', highContrast: true },
|
button: { color: 'purple', highContrast: true },
|
||||||
id: 'blitz-insider',
|
id: 'blitz-insider',
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { PageWrapper } from 'packages/website/src/components/PageWrapper';
|
||||||
|
import { MetaSection } from 'packages/website/src/components/Tankopedia_ue/MetaSection';
|
||||||
|
import {
|
||||||
|
LocaleProvider,
|
||||||
|
type LocaleAcceptorProps,
|
||||||
|
} from 'packages/website/src/hooks/useLocale';
|
||||||
|
import { App } from 'packages/website/src/stores/app';
|
||||||
|
import { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue';
|
||||||
|
|
||||||
|
interface PageProps extends LocaleAcceptorProps {
|
||||||
|
tankContext: TankopediaEphemeral_ue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Page({ localeContext, tankContext }: PageProps) {
|
||||||
|
return (
|
||||||
|
<LocaleProvider data={localeContext}>
|
||||||
|
<App.Provider>
|
||||||
|
<TankopediaEphemeral_ue.Provider data={tankContext}>
|
||||||
|
<PageWrapper p="0" maxWidth="unset" color="purple" gap="9" pb="9">
|
||||||
|
<MetaSection />
|
||||||
|
</PageWrapper>
|
||||||
|
</TankopediaEphemeral_ue.Provider>
|
||||||
|
</App.Provider>
|
||||||
|
</LocaleProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
import type {
|
||||||
|
CatalogItemsComponent,
|
||||||
|
CompensationComponent,
|
||||||
|
TankCatalogComponent,
|
||||||
|
} from '@blitzkit/closed/src/unreal/protos';
|
||||||
|
import { slugify } from '@blitzkit/core';
|
||||||
|
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
|
||||||
|
import type { GetStaticPaths } from 'astro';
|
||||||
|
import { tankToSet } from 'packages/website/src/core/blitz/tankToSet';
|
||||||
|
import type { TankopediaEphemeral_ue } from 'packages/website/src/stores/tankopediaEphemeral_ue';
|
||||||
|
import { unpackedMetadata } from '../../../../core/blitz/unpackedMetadata';
|
||||||
|
import BaseLayout from '../../../../layouts/BaseLayout.astro';
|
||||||
|
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
||||||
|
import { Page } from './_index';
|
||||||
|
|
||||||
|
export const getStaticPaths = (async () => {
|
||||||
|
const tanks = await unpackedMetadata.getComponent<CatalogItemsComponent>(
|
||||||
|
'CatalogItemsGroupEntity.all_tanks',
|
||||||
|
'catalogItemsGroupComponent',
|
||||||
|
);
|
||||||
|
const gameStringsDefault = await unpackedMetadata.stringsSubset(
|
||||||
|
locales.default,
|
||||||
|
['TankEntity'],
|
||||||
|
);
|
||||||
|
const parentPaths = parentGetStaticPaths();
|
||||||
|
|
||||||
|
return (
|
||||||
|
await Promise.all(
|
||||||
|
tanks.catalog_items.map(async (item) => {
|
||||||
|
const tank = await unpackedMetadata.get(item).then((components) => {
|
||||||
|
return components.get<TankCatalogComponent>('tankCatalogComponent');
|
||||||
|
});
|
||||||
|
const nameEn = gameStringsDefault[tank.name!.value];
|
||||||
|
const slug = slugify(nameEn) || item.replace('TankEntity.', '');
|
||||||
|
|
||||||
|
return parentPaths.map((parent) => {
|
||||||
|
return {
|
||||||
|
params: { ...parent.params, slug },
|
||||||
|
props: { ...parent.props, entity: item },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
|
const { entity, locale, strings, blitzLocale } = Astro.props;
|
||||||
|
const set = await tankToSet(unpackedMetadata, entity);
|
||||||
|
const gameStrings = await unpackedMetadata.stringsSubset(blitzLocale, [
|
||||||
|
set.tank_set_ui!.tank_set_displayed_name,
|
||||||
|
]);
|
||||||
|
const tankEntity = await unpackedMetadata.get(entity);
|
||||||
|
const tank = await tankEntity.get<TankCatalogComponent>('tankCatalogComponent');
|
||||||
|
const compensation = await tankEntity.get<CompensationComponent>(
|
||||||
|
'compensationComponent',
|
||||||
|
);
|
||||||
|
const tankContext: TankopediaEphemeral_ue = { tank, set, compensation, entity };
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout {locale} {strings}>
|
||||||
|
<Page
|
||||||
|
client:load
|
||||||
|
{tankContext}
|
||||||
|
localeContext={{ locale, strings, gameStrings }}
|
||||||
|
/>
|
||||||
|
</BaseLayout>
|
||||||
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user