0fa87e2d9a
Pricing: при полном отказе всех запросов пробует localStorage-кэш последнего успешного ответа вместо пустого состояния, пишет туда же при успехе. Faq: отличает "в кэше правда пусто" от "не смогли загрузить" — раньше оба случая показывали один и тот же текст "0 protocols found", что вводило в заблуждение при обычном сетевом сбое. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
224 lines
4.7 KiB
TypeScript
224 lines
4.7 KiB
TypeScript
// Форма JSON-словарей из dictionaries/en.json и dictionaries/ru.json — оба файла
|
|
// должны точно соответствовать этой структуре, иначе TypeScript подсветит расхождение
|
|
// в местах, где used dict.<section>.<key> (см. lib/dictionaries.ts).
|
|
export interface Dictionary {
|
|
nav: {
|
|
features: string;
|
|
pricing: string;
|
|
faq: string;
|
|
profile: string;
|
|
blog: string;
|
|
terminal: string;
|
|
docs: string;
|
|
cta: string;
|
|
menu: string;
|
|
speedtest: string; // Новое
|
|
doom: string; // Новое
|
|
};
|
|
hero: {
|
|
badge: string;
|
|
badgeSecure: string;
|
|
titleStart: string;
|
|
titleHighlight: string;
|
|
subtitle: string;
|
|
switchLabel: string;
|
|
ctaPrimary: string;
|
|
ctaSecondary: string;
|
|
};
|
|
features: {
|
|
title: string;
|
|
items: { title: string; description: string }[];
|
|
};
|
|
pricing: {
|
|
badge: string;
|
|
title: string;
|
|
perMonth: string;
|
|
recommend: string;
|
|
syncing: string;
|
|
empty: string;
|
|
discount: string;
|
|
mo: string;
|
|
billedOnce: string;
|
|
period1m: string;
|
|
period6m: string;
|
|
period1y: string;
|
|
offlineNotice: string;
|
|
};
|
|
faq: {
|
|
title: string;
|
|
empty: string;
|
|
loadError: string;
|
|
};
|
|
blog: {
|
|
badge: string;
|
|
title: string;
|
|
more: string;
|
|
readMore: string;
|
|
empty: string;
|
|
archive: string;
|
|
systemLogs: string;
|
|
emptySector: string;
|
|
decrypt: string;
|
|
backBtn: string;
|
|
readTime: string;
|
|
verified: string;
|
|
endTransmission: string;
|
|
};
|
|
footer: {
|
|
brand: string;
|
|
tagline: string;
|
|
sections: {
|
|
product: string;
|
|
resources: string;
|
|
legal: string;
|
|
};
|
|
links: {
|
|
features: string;
|
|
pricing: string;
|
|
faq: string;
|
|
protocol: string;
|
|
comms: string;
|
|
privacy: string;
|
|
terms: string;
|
|
profile: string;
|
|
};
|
|
rights: string;
|
|
protocolStatus: string;
|
|
uplinkStatus: string;
|
|
activeNode: string;
|
|
latency: string;
|
|
};
|
|
download: {
|
|
title: string;
|
|
subtitle: string;
|
|
badges: { active: string; dev: string };
|
|
buttons: {
|
|
direct: string;
|
|
store: string;
|
|
github: string;
|
|
notify: string;
|
|
soon: string;
|
|
pending: string;
|
|
};
|
|
platforms: {
|
|
windows: string;
|
|
android: string;
|
|
linux: string;
|
|
macos: string;
|
|
ios: string;
|
|
};
|
|
accessingBuild: string;
|
|
};
|
|
terminal: {
|
|
title: string;
|
|
description: string;
|
|
alias: string;
|
|
message: string;
|
|
send: string;
|
|
systemReady: string;
|
|
loadingHistory: string;
|
|
noMoreLogs: string;
|
|
encrypting: string;
|
|
cooldown: string;
|
|
manifestoTitle: string;
|
|
manifestoText: string;
|
|
rulesTitle: string;
|
|
rule1: string;
|
|
rule2: string;
|
|
rule3: string;
|
|
statusReady: string;
|
|
};
|
|
loading: {
|
|
establishing: string;
|
|
};
|
|
notFound: {
|
|
errorBadge: string;
|
|
message: string;
|
|
returnHome: string;
|
|
};
|
|
nodes: {
|
|
title: string;
|
|
subtitle: string;
|
|
status: {
|
|
online: string;
|
|
full: string;
|
|
maintenance: string;
|
|
};
|
|
labels: {
|
|
load: string;
|
|
latency: string;
|
|
};
|
|
};
|
|
guestbook: {
|
|
title: string;
|
|
subtitle: string;
|
|
description: string;
|
|
philosophyTitle: string;
|
|
philosophyText: string;
|
|
liveFeed: string;
|
|
noTransmissions: string;
|
|
labelAlias: string;
|
|
labelPayload: string;
|
|
placeholderAlias: string;
|
|
placeholderPayload: string;
|
|
statusSuccess: string;
|
|
statusErrorBreach: string;
|
|
statusErrorEmpty: string;
|
|
statusErrorSize: string;
|
|
statusErrorFirewall: string;
|
|
statusErrorOffline: string;
|
|
statusErrorFilter?: string;
|
|
btnEncrypting: string;
|
|
btnBroadcast: string;
|
|
cooldown: string;
|
|
};
|
|
auth: {
|
|
title: string;
|
|
processing: string;
|
|
verifying: string;
|
|
granted: string;
|
|
denied: string;
|
|
noToken: string;
|
|
redirecting: string;
|
|
toBot: string;
|
|
awaiting: string;
|
|
authPrompt: string;
|
|
logs: {
|
|
waitInit: string;
|
|
sigValid: string;
|
|
apiRejected: string;
|
|
coreOffline: string;
|
|
authPayload: string;
|
|
verifyHmac: string;
|
|
invalidSig: string;
|
|
networkError: string;
|
|
};
|
|
};
|
|
docs: {
|
|
establishing: string;
|
|
vaultTitle: string;
|
|
vaultSubtitle: string;
|
|
searchPlaceholder: string;
|
|
empty: string;
|
|
closeSession: string;
|
|
noContent: string;
|
|
eof: string;
|
|
};
|
|
speedtest: {
|
|
title: string;
|
|
mockMode: string;
|
|
prodMode: string;
|
|
btnError: string;
|
|
btnDone: string;
|
|
btnIdle: string;
|
|
statusPinging: string;
|
|
statusDownloading: string;
|
|
statusUploading: string;
|
|
latency: string;
|
|
download: string;
|
|
upload: string;
|
|
unitMs: string;
|
|
unitMbps: string;
|
|
};
|
|
}
|