87 lines
3.8 KiB
TypeScript
87 lines
3.8 KiB
TypeScript
// Memory bank of the default world. Values are taken from a real bank of the same run; the fields
|
||
// are the contract's.
|
||
//
|
||
// Three hard cases are deliberate, because each of them broke something before:
|
||
// · a POLYSEMOUS term arrives as two legal rows with the same `src` — the row key is
|
||
// (src, sense, since, until), and a key built from (src, dst, kind) collapsed them;
|
||
// · a row whose `kind` is `null` — a ruby candidate that is neither a name nor a place carries
|
||
// none, and a client may neither drop such a row nor invent a kind for it;
|
||
// · a long tail of undecided rows, so "signed N of M" is not a comfortable number.
|
||
|
||
import type { components } from '../api/schema';
|
||
|
||
type Schemas = components['schemas'];
|
||
|
||
const term = (
|
||
id: string,
|
||
src: string,
|
||
dst: string,
|
||
kind: Schemas['BankTerm']['kind'],
|
||
status: Schemas['TermStatus'],
|
||
origin: Schemas['TermOrigin'],
|
||
extra: Partial<Schemas['BankTerm']> = {},
|
||
): Schemas['BankTerm'] => ({
|
||
id,
|
||
src,
|
||
dst,
|
||
kind,
|
||
status,
|
||
origin,
|
||
sense: '',
|
||
since_chapter: 0,
|
||
until_chapter: 0,
|
||
...extra,
|
||
});
|
||
|
||
export const terms: Schemas['BankTerm'][] = [
|
||
term('t_1', '方源', 'Фан Юань', 'name', 'approved', 'seed', { sense: 'главный герой' }),
|
||
term('t_2', '白凝冰', 'Бай Нинбин', 'name', 'approved', 'seed', {
|
||
sense: 'спутница главного героя',
|
||
}),
|
||
term('t_3', '花酒行者', 'Монах Цветочного Вина', 'nickname', 'approved', 'mined', {
|
||
sense: 'странствующий мастер',
|
||
}),
|
||
term('t_4', '沈嬷嬷', 'матушка Шэнь', 'nickname', 'draft', 'mined', {
|
||
sense: 'служанка в поместье',
|
||
}),
|
||
term('t_5', '古月山寨', 'деревня Гуюэ', 'place', 'approved', 'seed', {
|
||
sense: 'родная деревня героя',
|
||
}),
|
||
term('t_6', '蛊', 'гу', 'term', 'approved', 'seed', { sense: 'существо-артефакт, основа силы' }),
|
||
term('t_7', '蛊师', 'гу-мастер', 'title', 'approved', 'seed', { sense: 'тот, кто владеет гу' }),
|
||
term('t_8', '开窍', 'открытие апертуры', 'term', 'approved', 'seed', {
|
||
sense: 'обряд посвящения',
|
||
}),
|
||
term('t_9', '春秋蝉', 'Весенне-осенняя цикада', 'term', 'approved', 'seed', {
|
||
sense: 'легендарный гу времени',
|
||
}),
|
||
term('t_10', '学堂', 'школа', 'place', 'approved', 'mined', { sense: 'деревенская школа' }),
|
||
// The same surface, two senses and two windows. Both rows are legal and both need signing.
|
||
term('t_11', '青茅', 'Цинмао', 'place', 'approved', 'mined', { sense: 'гора' }),
|
||
term('t_12', '青茅', 'зелёный тростник', 'term', 'draft', 'mined', {
|
||
sense: 'растение',
|
||
since_chapter: 40,
|
||
}),
|
||
// Spoiler window: the term must not be applied before chapter 300.
|
||
term('t_13', '不死凤凰', 'Бессмертный феникс', 'title', 'draft', 'mined', {
|
||
sense: 'гу воскрешения',
|
||
since_chapter: 300,
|
||
}),
|
||
// The engine could not decide the kind. Shown as undecided, never dropped, never guessed.
|
||
term('t_14', '一气金光虫', 'Золотосветный червь', null, 'auto', 'ruby'),
|
||
// A candidate with no proposed translation yet — legal only while the status is `auto`.
|
||
term('t_15', '罗刹', '', null, 'auto', 'ruby'),
|
||
];
|
||
|
||
// The tail is what makes the signing screen a screen: hundreds of rows nobody has looked at.
|
||
const tail: Schemas['BankTerm'][] = Array.from({ length: 45 }, (_, index) =>
|
||
term(`t_tail_${String(index)}`, `候选${String(index)}`, '', null, 'auto', 'mined'),
|
||
);
|
||
|
||
export const bankTerms = [...terms, ...tail];
|
||
|
||
export const bank = {
|
||
total: bankTerms.length,
|
||
signed: bankTerms.filter((row) => row.status === 'approved').length,
|
||
terms: bankTerms,
|
||
};
|