visual-game.js
43.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
export default {
appName: 'voko.world',
productBrandSub: 'あなたのkosmoが呼んでいる。',
mobileCredit: { title: 'マイクレジット', buyCredits: 'クレジット購入', history: 'クレジット履歴', purchaseHistory: '購入履歴', usageHistory: '利用履歴', emptyHistory: '履歴はありません。', loadMore: 'さらに読み込む', balanceAfter: '残高:{points}', pending: '処理中', paid: '支払い済み', canceled: 'キャンセル済み', failed: '失敗', refunded: '返金済み', disputed: '異議申立中', autoReload: '自動リロード', bonusCredits: 'ボーナスクレジット', buyNow: '今すぐ購入', lowBalance: '残高不足', enabled: '有効', whenBelow: '残高が次を下回ったら', choosePack: 'リロードパックを選択', consent: '残高がしきい値に達した際、選択したパックを自動購入することを許可します。', terms: '利用規約', continueSecurely: '安全に続行', save: '設定を保存', disable: '自動リロードをオフ', setupComplete: '支払い方法を保存し、自動リロードを有効にしました。', setupCanceled: '設定をキャンセルしました。', actionRequired: '前回のリロードに失敗しました。支払い方法を再設定してください。', howTitle: '自動リロードの仕組み', howBalance: '残高がしきい値以下になると、選択したパックを購入します。', howSecure: '支払い情報は Stripe が安全に保存し、Voko はカード番号を保存しません。', howCancel: 'いつでも停止できます。過去の購入は返金されません。' },
nav: { play: 'プレイ', notes: '手掛かり', state: '状態', editor: '編集' },
scenario: { title: 'シナリオ', available: 'シナリオ', assetManifest: '素材一覧' },
character: { title: 'キャラクター', start: '開始', current: '現在のキャラクター' },
stage: { empty: 'シナリオとキャラクターを選択', turn: 'ターン {turn}', ending: 'エンディング', transcript: '記録' },
composer: { act: '行動', say: '発言', placeholder: '行動または発言を入力' },
actions: { refresh: '更新', start: '開始', home: 'ホーム', backHome: '戻る', newRun: '再開', send: '送信', save: '保存', compile: 'コンパイル', publish: '公開', rollback: 'ロールバック', upload: 'アップロード', select: '選択', endingText: 'エンディング文', load: '読み込む', backToGame: '戻る', cancel: 'キャンセル', confirm: '確認' },
account: {
signIn: 'ログイン',
signedIn: 'ログイン中',
signedOut: 'ログアウトしました',
sessionExpired: 'セッションの有効期限が切れました。もう一度ログインしてください。',
logoutFailed: 'ログアウトに失敗しました。もう一度お試しください。',
registered: '登録完了',
email: 'メール',
emailPlaceholder: 'メールアドレス',
password: 'パスワード',
passwordPlaceholder: 'パスワードを入力',
confirmPassword: 'パスワード確認',
confirmPasswordPlaceholder: 'もう一度入力',
verificationCode: '確認コード',
verificationCodePlaceholder: '6 桁のメール確認コード',
inviteToken: '招待コード',
inviteTokenPlaceholder: '8 文字の招待コードを入力',
sendCode: 'コード送信',
resendCode: '再送信',
codeSent: '確認コードを送信しました。メールを確認してください。',
codeRequired: 'メール確認コードを入力してください。',
inviteInvalid: '有効な 8 文字の招待コードを入力してください。',
emailRequired: '先にメールを入力してください。',
emailInvalid: '有効なメールアドレスを入力してください。',
passwordRequired: '先にパスワードを入力してください。',
confirmPasswordRequired: '先に確認用パスワードを入力してください。',
loginFieldsRequired: 'メールアドレスとパスワードを入力してください。',
inviteEmailMismatch: 'このメールアドレスは招待コードに紐づく申請メールと一致しません。',
passwordMismatch: 'パスワードが一致しません。',
createAccount: 'アカウント作成',
hasAccount: 'アカウントをお持ちですか?',
noAccount: 'アカウントはまだありませんか?',
termsHint: '続行すると、このメールが本人所有であることを確認し、進行、注文、ポイント保存に同意します。',
login: 'ログイン',
register: '登録',
reset: 'リセット',
forgotPassword: 'パスワードをお忘れですか?',
resetPassword: 'パスワードをリセット',
resetTitle: 'パスワードをリセット',
resetBody: 'メール確認コードを入力して新しいパスワードを設定します。既存セッションはすべて無効になります。',
resetCodeSent: 'リセット用コードを送信しました。メールを確認してください。',
resetFieldsRequired: 'メールアドレス、確認コード、新しいパスワード、確認用パスワードを入力してください。',
passwordResetDone: 'パスワードをリセットしました。新しいパスワードでログインしてください。',
logout: 'ログアウト',
logoutAll: 'すべての端末からログアウト',
credits: 'ポイント',
buy: 'ポイント購入',
billing: '請求',
promptTitle: 'ログインまたは登録して開始',
promptBody: '進行、セーブ、エンディング、ポイント、注文をアカウントに保存し、別の端末でも続行できます。',
signedInBody: '進行、セーブ、ポイントはデータベースに保存されます。',
registerAndStart: '登録して役を選ぶ',
guestStart: 'ゲストで試す',
savedHint: 'ログインすると進行とセーブを自動保存',
currentAccount: '現在のアカウント',
saveKicker: 'アカウント保存',
saveTitle: '進行と注文を保存',
loginTitle: 'ログイン',
loginBody: 'ログイン後、この端末のゲスト進行を可能な範囲で統合します。',
registerTitle: 'アカウント作成',
registerBody: '招待コードとメールの所有を確認してからアカウントを作成します。登録後は自動ログインし、100 ポイントを付与して端末進行を統合します。',
openBilling: 'ポイントと注文を見る',
mergePending: 'この端末のゲスト進行を統合中…',
mergeSuccess: '端末データを統合しました:{details}。',
mergeSeparator: '、',
mergeRuns: '{count} 件の対局',
mergeTurns: '{count} 件のターン',
mergeProgress: '{count} 件の進行',
mergeSaveSlots: '{count} 件のセーブ',
mergeEndingRecords: '{count} 件のエンディング',
mergeEvents: '{count} 件のイベント',
mergeAgentCalls: '{count} 件の AI 呼び出し',
mergeBillingLedger: '{count} 件のポイント履歴',
mergeBillingUnlocks: '{count} 件の有料解放',
mergeBillingFreeQuota: '{count} 件の無料枠',
mergePaymentOrders: '{count} 件の注文',
mergeEmpty: '統合できる端末進行はありません。',
mergeFailed: 'ログイン済みですが、端末進行はまだ統合されていません。後で更新してください。',
},
billing: {
title: 'ポイントと注文',
subtitle: '残高、購入、履歴、注文はデータベースから読み込みます。',
guestSubtitle: 'ゲストはポイントパックを確認できます。購入、残高、注文、履歴にはログインが必要です。',
balance: '現在の残高',
products: 'ポイントパック',
ledger: 'ポイント履歴',
orders: '注文',
refresh: '請求情報を更新',
testModeTitle: 'Stripe テスト環境',
testModeBody: 'テスト決済を使用するため、実際の請求は発生しません。',
testPurchase: 'テスト購入',
buy: '{points} ポイントを購入',
checkoutReady: '決済リンクを作成しました。',
openCheckout: '決済ページを開く',
selectedPack: '選択中',
selectedProduct: '{title} を選択しました。残高に {points} ポイントが追加されます。',
signInToBuy: 'ログインして購入',
readyToBuy: 'ポイントを購入できます',
readyToBuyBody: 'ポイントパックを選び、決済へ進みます。確認前の注文は処理中になります。',
checkoutPending: '決済ページへ移動中…',
checkoutReturnedSuccess: 'アプリに戻りました。残高と注文を更新しています。反映は注文状態に従います。',
checkoutReturnedCancel: '決済はキャンセルまたは未完了です。反映は確認されていません。',
signInHint: 'ログインすると残高、注文、履歴を確認できます。',
emptyProducts: 'ポイントパックはありません。',
emptyLedger: '履歴はありません。',
emptyOrders: '注文はありません。',
productFallback: 'ポイントパック',
points: '{points} ポイント',
price: '{amount} {currency}',
ledgerAmount: '{amount} ポイント',
orderStatus: '状態 {status}',
orderStatusPending: '処理中',
orderStatusPaid: '支払い済み',
orderStatusRefunded: '返金済み',
orderStatusDisputed: '異議申し立て中',
orderStatusUnknown: '状態不明',
ledgerReasonSignupGift: '登録特典',
ledgerReasonCheckout: 'ポイント購入',
ledgerReasonRefund: '注文返金',
ledgerReasonChargeback: 'チャージバック取り消し',
ledgerReasonUnlock: 'コンテンツ解放',
paywallTitle: '有料解放',
paywallTarget: '対象',
paywallReason: '課金理由',
paywallGenericReason: 'この内容を続けるにはポイントが必要です。',
paywallFreeContinue: '無料枠が残っています。続行できます。',
paywallInsufficient: 'ポイントが不足しています。先に購入してください。',
paywallPrice: '必要ポイント',
paywallFreeQuota: '残り無料枠',
paywallBalance: '利用可能残高',
},
endings: {
title: 'エンディング図鑑',
unlocked: '解放済み',
locked: '未解放',
collected: '{count}/{total} 収集済み',
lockedHint: '対応するエンディングに到達すると解放されます。',
},
saves: {
title: 'セーブ',
progress: '現在の進行',
activeRun: '現在のゲーム',
slot: 'スロット {slotNo}',
savedRun: '保存済み進行',
emptySlot: '空きスロット',
emptyHint: '現在の run を保存すると再読み込み後も復帰できます。',
saveHere: '保存',
overwrite: '上書き保存',
restore: '読み込み',
delete: '削除',
saved: 'セーブしました。',
restored: 'セーブを読み込みました。',
deleted: 'セーブを削除しました。',
conflict: '既存のセーブがあります。この復元地点を上書きする前に確認してください。',
restoreConfirm: '読み込むと現在のゲームはこのセーブ地点に切り替わります。',
deleteConfirm: '削除したセーブ地点は復元できません。',
noRunHint: '保存できる現在の run がありません。先に開始または再開してください。',
},
map: {
title: 'マップ',
current: '現在地',
route: '移動可能',
routes: '移動可能な場所',
locked: '未解放',
moveTo: '{location}へ移動',
objects: '調査できる対象',
inspect: '調査',
inspected: '調査済み',
inspectObject: '{object}を調べる',
},
videoCenter: {
eyebrow: 'プレイヤー記録',
title: '映像センター',
backHome: '戻る',
chooseScenario: 'シナリオ選択',
allScenarios: 'すべてのシナリオ',
searchScenario: 'シナリオを検索',
scenarioPaintedSkin: '画皮',
scenarioGuian: '帰安県失心事件',
nowPlaying: '再生中',
player: 'プレイヤー',
views: '視聴回数',
ending: '結末',
duration: '時間',
libraryEyebrow: '同じシナリオの映像',
allVideos: 'すべての映像',
sort: '映像の並び順',
recommended: 'おすすめ',
latest: '最新',
videoMeta: '{player} · {date}',
emptyTitle: 'プレイヤー映像はまだありません',
emptyText: 'このシナリオには公開されたプレイ映像がありません。',
viewAll: 'すべてのプレイヤー映像を見る',
discoverStories: '他の人の選択を見る',
backPrevious: '前のページへ', aiSummary: 'AI概要:', endingCount: '種類の結末', publicSeriesCount: '公開シリーズ', totalPlays: '総再生', seriesList: 'プレイヤーシリーズ', completed: '完結', updating: '第{count}話まで · 連載中', seriesMetrics: '全{episodes}話 · ▶ {plays} · ♥ {likes}', watchSeries: 'このシリーズを見る', playOwnSeries: '自分のシリーズを作る', minutes: '{count}分', share: '共有', shareCopied: 'リンクをコピーしました', shareFailed: '共有できませんでした', like: 'いいね', liked: 'いいね済み', save: '保存', saved: '保存済み', storyHighlight: '物語の見どころ', startPlay: 'プレイして結末を書き換える', episodeList: 'エピソード', episodeTotal: '全{count}話', episodeTitle: '第{count}話 · {title}',
},
runHistory: {
eyebrow: '個人プレイ記録',
title: '自分の対局',
allRuns: 'すべての対局',
count: '{count} 件',
empty: 'プレイ記録はまだありません。対局を始めるとここに表示されます。',
loadFailed: '読み込み失敗:{error}',
noTime: '時刻不明',
statusActive: '進行中',
statusCompleted: '終了',
videoNone: '動画なし',
videoQueued: '動画待機中',
videoRunning: '動画生成中',
videoReady: '動画準備完了',
videoFailed: '動画失敗',
videoRetry: '再生成',
untitledEnding: 'エンディング未到達',
meta: '{scenario} · ターン {turn} · {date}',
openRun: '対局を開く',
openNotes: 'ノート',
watchVideo: '動画を見る',
},
mobileProfile: { title: 'マイ', settings: '設定', content: 'コンテンツ', benefits: '特典', creator: 'クリエイター', support: 'お問い合わせ・サポート', contact: 'カスタマーサポート', terms: '利用規約', privacy: 'プライバシーポリシー', social: 'ソーシャルメディア' },
profileEditor: { editProfile: 'プロフィールを編集', nameSection: 'プロフィール名', nameHint: 'ゲームや動画に表示される名前です。', name: '名前', saveName: '名前を保存', nameRequired: '名前を入力してください。', nameSaved: '名前を更新しました。', passwordSection: 'パスワードを変更', passwordHint: 'メールに届く認証コードで本人確認を行います。', email: 'メール', verificationCode: 'メール認証コード', sendCode: 'コードを送信', codeSent: '認証コードをメールに送信しました。', newPassword: '新しいパスワード', confirmPassword: '新しいパスワードを確認', savePassword: 'パスワードを更新', passwordRequirements: '認証コードと8文字以上の新しいパスワードを入力してください。', passwordMismatch: 'パスワードが一致しません。', passwordSaved: 'パスワードを更新しました。' },
myGames: { recent: '最近プレイした作品', popular: '人気のストーリー', emptyRecent: '最近プレイしたストーリーがここに表示されます。', loadError: 'ゲームを読み込めませんでした。もう一度お試しください。' },
storyDetail: { title: 'ストーリー情報', description: 'ストーリー紹介', episodes: '{count} エピソード', endings: '{count} エンディング', by: '作者:{name}', lastUpdate: '最終更新', newPlay: '新しくプレイ', notFound: 'ストーリーが見つかりません。', loadError: 'ストーリーを読み込めませんでした。' },
accountCenter: { loadFailed: '個人センターを読み込めませんでした', loadTimeout: 'リクエストがタイムアウトしました。接続を確認して再試行してください。', title: 'マイページ', eyebrow: 'プレイヤープロフィール', runs: 'マイゲーム', videos: '動画コレクション', favorites: 'お気に入り', watchSeason: 'このシーズンを見る', emptyGames: 'まだゲームを開始していません。', emptyVideos: '生成された動画はまだありません。', emptyFavorites: 'お気に入りの動画はありません。', lastPlayed: '最終プレイ · {date}', currentTurn: '進行中 · ターン {turn}', noActiveRun: '進行中のプレイはありません', endingsUnlocked: 'エンディング {unlocked}/{total}', runsPlayed: '累計 {count} 回', continueGame: 'ゲームを続ける', startGame: 'ゲームを始める', viewHistory: '履歴を見る', levelProgress: '{played}/{total} ステージをプレイ', viewSeasonDetails: 'シーズン詳細を見る', hideSeasonDetails: 'シーズン詳細を閉じる', levelInProgress: '進行中', levelCompleted: '完了', endingLabel: '到達したエンディング', cluesLabel: '獲得した手がかり', clueCount: '手がかり {count} 件', viewRunRecords: 'ゲーム記録を見る', runRecordSummary: '手がかり {clues} 件 · エンディング {ending} 件', noEnding: 'まだエンディングに到達していません', noClues: '手がかりはまだありません', seasonDetailsLoadFailed: 'シーズン詳細を読み込めませんでした。再試行してください。', public: '公開', private: '自分のみ', deleteVideo: '動画を削除', confirmDelete: '削除を確認', signInTitle: 'ログインしてください', signInBody: 'ログインするとゲーム進行と動画を管理できます。' },
visual: {
eyebrow: 'TRPG Visual',
chooseScript: 'シナリオ選択',
actTitle: '第{count}幕 · {title}',
actLocked: '{title}は未解放です',
actSealed: '前幕未完',
toBeContinued: '続く',
finishPreviousAct: '前幕の結末に到達すると解放',
revealAfterAct: '第{count}幕を完了すると明らかになります',
moreScripts: 'その他のステージ',
comingSoon: '近日公開',
watchScriptVideo: 'シナリオ映像を見る',
scenarioKicker: 'シナリオ',
hiddenTitle: '田又',
revealedTitle: '画皮',
objectives: '現在の目標',
playHistory: 'プレイ記録',
objectiveLabel: 'ミッション目標',
close: '閉じる',
noObjectives: '進行中のタスクはありません。',
taskProgress: '手順 {done}/{total}',
entryKicker: 'ゲーム開始',
entryTitle: '今夜、部屋に入る',
emptyScenarioEyebrow: 'シナリオ未公開',
emptyScenarioTitle: 'プレイ可能なシナリオがありません',
emptyScenarioText: 'サーバーから公開済みシナリオが返りません。更新するか公開状態を確認してください。',
emptyScenarioActionTitle: '公開待ち',
emptyScenarioActionText: '実データなしでローカルの仮シナリオは開始しません。',
continueTitle: '前回の続き',
entryBody: '先に役を選んで旧屋へ入ります。',
chooseCharacter: 'キャラクター選択',
enterStory: '物語へ進む',
back: '戻る',
skip: 'スキップ',
editor: 'エディター',
debugPage: 'デバッグ',
state: '状態',
settings: '設定',
language: '言語',
languageUnavailable: 'このレベルには、選択した言語の翻訳がまだありません。',
turnVideoMatching: 'スマートCGマッチング',
turnVideoMatchingHint: 'オンにすると類似する場面からこのターンのCGを探します。オフでは完全一致のCGのみ再生します。',
turnVideoMatchingOn: 'オン',
turnVideoMatchingOff: 'オフ',
exitGame: 'ゲームを終了',
exitGameHint: '現在のプレイを離れ、シナリオ選択へ戻ります。',
saveAndExit: '保存して終了',
exitWithoutSaving: '保存せず終了',
notes: 'ノート',
saves: 'セーブ',
continueRun: '続きから',
balanceEntry: '残高 {credits}',
endingCollection: 'エンディング図鑑',
narrator: '語り手',
npcName: '屋内の女',
npcLine: '「{line}」',
notStarted: '未開始',
startHint: '開始を押して古屋に入る。',
debug: '数値デバッグ',
debugOnly: 'デバッグ用',
waiting: '待機中。',
modeAct: '行動',
modeSay: '発言',
inputMethod: '入力方法',
textInputMode: 'テキスト',
voiceInputMode: '音声',
choiceGroupLabel: '選択肢',
inputPlaceholder: '例:銅鏡を持ち、彼女と壁の絵に向ける。',
mobileInputPlaceholder: 'セリフや行動を入力…',
voiceStart: '音声入力を開始',
voiceStop: '音声入力を停止',
voiceListening: '聞き取り中…',
voiceRecognizing: '認識中…',
voiceUnsupported: 'このブラウザは音声入力に対応していません',
voicePermissionDenied: 'マイクを使用できません。ブラウザの権限を確認してください',
voiceMicrophoneUnavailable: '使用可能なマイクが見つかりません',
voiceNoSpeech: '音声を認識できませんでした。もう一度お試しください',
voiceNoAudioCaptured: 'マイクの音声を取得できませんでした。ブラウザの権限を確認してください',
voiceRecognitionFailed: '音声認識に失敗しました。もう一度お試しください',
voiceHoldToTalk: '押して話す',
voicePreparing: 'マイクを準備中…',
voiceShortcutLabel: 'ショートカット',
voiceReleaseSend: '離して送信',
voiceSlideCancel: '上にスライドしてキャンセル',
voiceReleaseCancel: '離してキャンセル',
voiceUnderstanding: '指示を理解しています…',
ending: 'エンディング',
endingLabel: 'エンディング',
endingLine: 'エンディング:{title}\n{description}',
endingSummary: '結末まとめ',
endingPoem: '定場詩',
endingFallbackPoem: '……',
endingBackgroundLoadFailed: 'エンディング画面を読み込めませんでした。再読み込みしてください。',
recordSeal: '案',
recordTitle: '捕吏記録',
recordKicker: '県衙文書',
recordMeta: '雨夜の後',
continue: '続ける',
enterNextEpisode: '次の章へ',
viewCurrentSeasonStory: '今季のストーリーを見る',
played: '再生済み',
nextPage: '次ページ',
statusCreating: '物語を準備しています...',
statusStarted: '開始しました。発言か行動を入力してください。',
statusHistoryRun: '過去の run を表示中です。続きはサーバー進行に従います。',
statusKp: 'KP が判定中...',
statusDone: 'ターン完了。',
contentFiltered: 'この行動は描写できません。別の方法を試してください。',
turnFailed: 'このステップを完了できませんでした。もう一度お試しください。',
audioFailed: '音声の再生に失敗しました。もう一度お試しください。',
actionRejected: 'その行動はまだ成立しません。別の方法を試してください。',
statusEnded: 'ゲーム終了。',
statusEndingText: '結末文を生成中...',
statusEndingLocked: 'エンディングが確定しました。移行中...',
statusNpcAction: 'NPC が行動を試みています。KP 判定待ち...',
statusNpcDone: 'NPC が応答しました。',
clueGained: '手掛かり入手',
landscapeTitle: '端末を横向きにしてください',
landscapeBody: 'シーンとCGをすべて表示するため、横向きでプレイしてください。',
stats: {
suspicion: '疑念',
charm: '魅惑',
fear: '恐怖',
},
guide: {
label: 'ガイド',
skip: 'スキップ',
next: '次へ',
done: '了解',
optionsTitle: '直接選択',
optionsText: 'NPC の反応後、下に二つの候補が出ます。「発言」か「行動」を選べます。',
keyboardTitle: 'キーボード入力に切り替える',
keyboardText: '初期設定は音声入力です。キーボードボタンを押すと、発言や行動を直接入力できます。',
inputTitle: '「発言 / 行動」を選ぶ',
inputText: '入力前に「発言」か「行動」を選びます。どちらも KP が判定します。',
notesTitle: 'ノート確認',
notesText: '右側のノートには発見した手掛かりと解放済みエンディングが記録されます。',
goalTitle: '生き残る',
goalText: 'これは会話だけではありません。彼女の言葉を聞き、部屋と異常も観察してください。',
videoTitle: 'ストーリーを完成させると、この冒険があなただけの映像になります',
videoExampleLabel: 'サンプル動画',
videoExampleNotice: 'この動画はサンプルであり、あなたのプレイから生成される内容ではありません。',
videoLoading: 'サンプル動画を読み込み中…',
videoUnavailable: 'このストーリーにはまだサンプル動画がありません。',
videoDone: '私のストーリーを始める',
},
openingOptions: {
say: 'すみません、勝手に入るつもりはありませんでした。外に何かがいて追われていました。',
act: '声を低くして、扉、窓、灯、彼女の位置を確認する。',
},
},
panels: { clues: '手掛かり', conclusions: '結論', info: '情報', inventory: '所持品', events: 'イベント', stats: '能力値', flags: 'フラグ', objects: 'オブジェクト', npcs: 'NPC', endingRecords: '解放済みエンディング' },
standalone: {
summary: '概要',
availableClues: '入手可能な手掛かり',
recentTurns: '最近のターン',
audit: {
title: 'AI 監査',
subtitle: 'KP、NPC、エンディング、TTS 呼び出しのコストと失敗記録。',
totalCalls: '呼び出し',
failedCalls: '失敗',
tokens: '入力/出力 token',
cost: 'コスト',
roles: 'ロール別集計',
models: 'モデル別集計',
recentCalls: '最近の呼び出し',
empty: 'AI 呼び出し記録はありません。',
calls: '{count} 回',
tokenPair: 'token {tokens}',
},
state: {
title: '状態可視化',
waiting: 'RunState の読み込み待ち。',
noRun: 'runId がありません。ゲーム画面から開くか、runId を入力してください。',
loading: '{runId} を読み込み中...',
loaded: '{runId} を読み込みました',
},
notes: {
title: 'ノート',
waiting: 'ノートを読み込み中。',
noRun: '現在のセーブがありません。先にゲームを開始または再開してください。',
loading: '{runId} を読み込み中...',
loaded: '{runId} を読み込みました',
unavailable: 'このゲームのノートは現在読み込めません。',
emptyClues: '手掛かりはまだありません',
emptyConclusions: '結論はまだありません',
emptyEndings: 'エンディングはまだありません',
tabs: 'ノート分類',
list: '項目リスト',
detail: '項目詳細',
locked: '未解放',
lockedHint: 'このエンディングはまだ記録されていません。',
recorded: '記録済み',
importance: { minor: '副次', major: '重要', critical: '核心' },
relatedClues: '関連する手掛かり',
noRelatedClues: 'この結論を支える手掛かりはまだ見つかっていません。',
},
},
editor: {
title: 'シナリオ編集',
pack: 'パック',
section: 'セクション',
raw: 'JSON',
structured: '構造化編集',
debugJson: 'デバッグ JSON',
item: '項目',
noStructuredFields: 'このセクションには直接編集できる構造化フィールドがまだありません。',
updated: '保存済み',
assetUploaded: 'アセットをドラフトに追加済み',
compiled: 'ドラフトをコンパイル済み',
published: 'バージョンを公開済み',
rolledBack: 'バージョンをロールバック済み',
versions: 'バージョン',
assets: 'アセット索引',
current: '現在',
currentVersion: '現在のバージョン',
noPublishedVersion: '未公開',
noVersions: 'まだバージョンがありません。先にドラフトをコンパイルしてください。',
noAssets: 'まだアセット索引がありません。先にマニフェストをコンパイルしてください。',
noFilteredAssets: '条件に一致するアセットはありません。',
assetSearch: '検索',
assetSearchPlaceholder: 'タグ、ファイル、objectKey',
assetTypeFilter: '種類',
assetSourceFilter: 'ソース',
assetFilterAll: 'すべて',
assetFilterResult: '{shown}/{total}',
assetSource: {
uploaded: 'アップロード済み',
static: '静的ファイル',
missing: '参照なし',
},
uploadFile: 'ファイル',
uploadTag: 'タグ',
uploadTagPlaceholder: 'opening_cg',
uploadType: '種類',
noUploadFile: 'ファイル未選択',
},
waitingList: {
eyebrow: '先行アクセス',
apply: '体験を申し込む',
useInvite: '招待コードを使う',
invitedRegister: '招待済みですか?アカウント作成',
title: 'ゲームサーバーの waiting list に参加',
body: 'メールと用途を残すと、運営が管理画面から招待リンクを発行します。',
displayName: '名前',
displayNamePlaceholder: '任意',
useCase: '用途',
useCaseOptional: '用途(任意)',
useCasePlaceholder: 'チームテスト、作者トライアル、イベント',
useCaseRequired: '用途を入力してください。',
consent: 'この waiting list の招待と製品メールを受け取ることに同意します。',
join: '参加する',
joined: '申請を受け付けました。メール通知をお待ちください。',
joinedTitle: '申請済み',
changeEmail: '別のメールを使う',
accountAlreadyRegistered: 'このメールアドレスは登録済みです。ログインしてください。',
emailRequired: 'メールアドレスが必要です。',
consentRequired: '参加前にメール送信への同意が必要です。',
inviteEyebrow: '招待',
inviteTitle: 'voko.world アカウントを作成',
inviteBody: 'この招待はメールアドレスに紐づいています。パスワードを設定して登録を完了してください。',
inviteMissing: '招待 token がありません。',
inviteEnterCode: '受け取った 8 文字の招待コードを入力してアカウントを作成します。',
inviteValidate: '招待コードを確認',
inviteReenter: '招待コードを再入力',
inviteInvalid: '招待が無効または期限切れです。',
codeSent: '確認コードを送信しました。',
passwordMismatch: 'パスワードが一致しません。',
acceptInvite: 'アカウント登録',
},
landing: { officialVideo: '公式動画を見る', officialVideoEyebrow: 'VOKO について', officialVideoTitle: 'あなたの世界が呼んでいます。', officialVideoBody: '自分の世界を作り、再びあなたを呼ぶ物語をプレイし、すべての瞬間を見たくなる映像として共有しましょう。', homeLabel: 'voko.world ホーム', navHome: 'Home', navScripts: '物語', navVideos: '動画', featuredStories: '注目の物語', featuredStoriesEyebrow: 'プレイ開始', endingCount: 'エンディング {count} 個', allStories: 'すべての物語', dramaTitle: 'ドラマ', brandSub: 'インタラクティブストーリー', navLabel: 'メインナビ', navStories: 'ゲーム', navGallery: 'ギャラリー', eyebrow: 'AI ビジュアルロールプレイ', loadError: '読み込みに失敗しました。', retry: '再読み込み', emptyGames: '公開中のゲームはありません。', scenarioFallback: '選択でこの物語を変えましょう。', publicVideos: 'プレイヤー動画', publicGames: '公開ゲーム', watchDrama: 'ドラマを見る', enterPlay: 'プレイする', comingSoon: '近日公開', carouselLabel: 'ゲームカルーセル', previousGame: '前のゲーム', nextGame: '次のゲーム', showcaseTitle: 'プレイヤーが作った物語', showcaseBody: '他のプレイヤーの結末を見て、自分の物語を作りましょう。', searchLabel: '物語を検索', searchPlaceholder: 'ゲーム名で検索', sortLabel: '並び順', latest: '最新', popular: '人気', videoCount: '{count} 本の動画', levelCount: '全{count}関', levelNumber: '第{count}関', singleLevel: '単独シナリオ', publicGame: '公開ゲーム', noSearchResults: '一致する物語がありません', clearSearch: '検索をクリア', finalEyebrow: 'あなたの物語が待っています', finalTitle: '誰になりますか?', finalBody: '世界へ足を踏み入れ、最初の一言を。', begin: '旅を始める', footer: '© 2026 voko.world', earlyAccess: '先行アクセス', footerSocial: 'コミュニティ', footerLegal: '規約と連絡先', privacy: 'プライバシーポリシー', terms: '利用規約', contact: '連絡先メール' },
landingCarousel: { introEyebrow: '生成ドラマゲーム', introSummary: '短いドラマを見て役に入り、選択で物語を変えましょう。', dramaEyebrow: '注目ドラマ {count}', controls: 'ホームカルーセル', goToSlide: 'スライド {count} へ' },
landingCinema: { navHome: 'ホーム', navDramas: 'ゲーム', navPlayerStories: 'ドラマ', navMy: 'マイ', featuredDramas: 'ゲーム', playerStories: 'ドラマ' },
searchPage: { placeholder: 'ストーリー、ドラマ、アカウントを検索', popular: '人気の検索', history: '最近の検索', clearHistory: 'クリア', resultTypes: '検索結果の種類', all: 'すべて', accounts: 'アカウント', accountStats: '作品 {titles} 件 · 再生 {plays} 回' },
landingIntro: { title: 'voko.world', apply: '体験を申し込む', watchVideo: '動画を見る', start: 'ゲームを始める', continue: 'ゲームを続ける', viewJourney: 'プレイ履歴', continueProgress: 'シーズン {season} {scenario}', storyLine: 'ストーリーライン', viewMore: 'さらに見る' },
storyTree: {
eyebrow: 'シーズンライン',
subtitle: '1本のラインが1シーズン、各ノードが1ステージを表します。',
root: 'ドラマ',
branch: '分岐',
active: '進行中',
completed: '完了',
locked: '未到達',
empty: '表示できるシーズンラインはまだありません。',
loadError: 'シーズンラインを読み込めませんでした。',
navigation: 'シーズン範囲',
range: 'シーズン {first}–{last} · 全 {total}',
newer: '前のグループ',
older: '次のグループ',
startPlaying: 'プレイ開始',
turnProgress: '第 {turn} ターン',
continuePlaying: 'プレイを続ける',
playLog: 'プレイ記録',
seasonEnding: 'シーズンの結末',
currentSeason: '現在のシーズン',
logLoadError: 'プレイ記録を読み込めません。',
logEmpty: 'このシーズンにはまだプレイ履歴がありません。',
turnNumber: '第 {turn} ターン',
playerSaid: 'あなたの発言',
playerDid: 'あなたの行動',
storyOpening: '物語の始まり',
turnVideos: '一致した動画',
playActionVideo: 'アクション動画',
playPlayerVideo: 'プレイヤー動画',
playNpcVideo: 'NPC 動画',
replayTurn: 'リプレイ',
replayTurnTitle: '第 {turn} ターンの再生',
replayProgress: '{current}/{total} クリップ',
actionSegment: 'アクション',
playerSpeechSegment: 'プレイヤー発言',
npcSpeechSegment: 'NPC 発言',
pauseReplay: '一時停止',
continueReplay: '続ける',
restartReplay: '最初から再生',
exportReplay: '全編を書き出す',
replayQueued: '待機中',
replayExporting: '書き出し中',
playFullReplay: '全編を再生',
retryReplayExport: '再書き出し',
downloadReplay: 'MP4 をダウンロード',
downloadSegment: 'このクリップをダウンロード',
downloadTurn: 'このターン全体をダウンロード',
turnExporting: 'ターン動画を書き出し中',
turnExportError: 'ターン動画の書き出しに失敗しました。',
segmentExporting: 'クリップを書き出し中',
segmentExportError: 'クリップの書き出しに失敗しました。',
fullReplayTitle: '{title} · 全編再生',
replayExportError: '全編の書き出しに失敗しました。',
videoLoadError: '動画を読み込めませんでした。',
tools: 'ストーリーラインの検索・絞り込み・並べ替え',
search: '検索',
searchPlaceholder: 'ステージ、結末、最近の行動を検索',
filter: '状態',
filterAll: 'すべて',
filterInProgress: '進行中',
filterCompleted: '完了',
sort: '並べ替え',
sortRecent: '最近プレイした順',
sortSeasonDesc: 'シーズン降順',
sortSeasonAsc: 'シーズン昇順',
resultCount: '全 {count} シーズン',
noResults: '条件に一致するストーリーラインはありません。',
canvasHint: 'キャンバスをドラッグまたはスクロールして右側のステージを表示',
canvasLabel: '横方向に移動できるストーリーツリーキャンバス',
storySwitch: '作品',
},
storyTreeCurrentSeasonHint: '最新の進行',
storyTreeViewDetails: 'シーズン {number} の詳細を見る',
storyTreeDelete: { action: '分岐を削除', confirm: 'シーズン {number} とそこから派生した分岐を削除しますか?この操作は取り消せません。', deleting: '削除中…', error: '分岐を削除できませんでした。' },
storyTreeVideoUnavailable: '映像はありません',
storyTreeFork: { action: 'ここからやり直す', confirm: '第 {turn} ターンから新しいストーリー分岐を作成します。現在のプレイ記録は変更されません。', failed: '新しいストーリー分岐を作成できませんでした。', creating: '作成中…' },
runVideoGeneration: { title: 'フル動画を生成', description: 'このプレイからフル動画を生成します。確定後にポイントを消費し、生成失敗時は自動返還されます。', generate: '動画を生成', regenerate: '再生成', retry: 'もう一度生成', queued: '生成待ち', running: '生成中', price: '必要ポイント', balance: '現在の残高', balanceAfter: '消費後の残高' },
landingShowcase: { title: 'それぞれの物語', body: 'ほかのプレイヤーが辿った運命を見届け、物語に入り、あなただけの結末を描きましょう。' },
landingMetrics: { playCount: '再生数', likeCount: 'いいね数' },
landingCard: { level: 'エピソード', searchPlaceholder: '物語・動画・プレイヤーを探す', scriptFilter: 'ドラマ', scriptAll: 'すべてのドラマ', playerVideoCount: '公開動画 {count} 本', publishedAt: '公開日', publishedAll: 'すべて', publishedToday: '今日', publishedWeek: '過去 7 日', publishedMonth: '過去 30 日', expandSynopsis: '展開', collapseSynopsis: '閉じる' },
playerPage: { loadError: 'プレイヤーの動画を読み込めませんでした。', notFound: 'プレイヤーが見つからないか、公開動画がありません。', searchPlaceholder: '作品・ステージ・シーズン名を検索' },
season: { choose: 'シーズンを選択', chooseBody: 'このエピソードは選択したシーズンの物語に続きます。', number: 'シーズン {number}', empty: '続けるには、いずれかのシーズンで前のエピソードを完了してください。' },
status: { loading: '読み込み中', empty: 'データなし', error: '読み込み失敗', streaming: '進行中' },
storiesPage: { tags: 'ストーリータグ', allTags: 'すべて', swipeForNextStory: '上にスワイプして次の物語へ' },
creator: { nav: '制作', queued: '処理待ち', attachmentTypeError: 'TXT、PDF、Word、PNG、JPG、WEBP のいずれか1ファイルを選択してください。', attachmentSizeError: '添付ファイルは10 MB以下にしてください。', attachmentReadError: '添付ファイルを読み取れませんでした。', generationFailed: '生成失敗', reviewRejected: '審査否認', published: '公開済み', archived: 'アーカイブ', composerTitle: '今日はどんな世界をつくりますか?', submitIdea: 'アイデアを送信', examplesNote: '公開済みゲームをレイアウト例として表示しています。', exampleStatus: '公開例', projectsEyebrow: 'Visual Game Creator', projectsTitle: 'マイゲーム', projectsBody: '制作したゲームと生成・審査状況を管理します。', newGame: '新しいゲームを作成', draftStatus: '下書き', continueEditing: '編集を続ける', generatedScopes: '件の生成内容', emptyTitle: '最初のゲームを作成', emptyBody: 'アイデアや脚本、世界観から遊べるゲームを作りましょう。', eyebrow: 'Visual Game Creator', title: '物語を、遊べる世界へ', subtitle: 'アイデアや脚本、世界観を共有してください。ゲーム設計、素材制作、検証、審査申請まで自動で進みます。', stepIdea: 'アイデア', stepGenerate: '生成', stepReview: '審査', ideaTitle: 'ゲームを説明する', ideaBody: '自然な言葉で入力できます。JSONの知識は不要です。', ideaLabel: 'アイデアまたは脚本', ideaHint: '世界、人物、対立、望む体験を含めてください。', ideaPlaceholder: '旅人が嵐の夜に宿で目覚めると、全員が昨夜を違って記憶していた……', ideaError: '20文字以上入力してください。', languageLabel: 'ゲーム言語', languages: { zh: '中国語', en: '英語', ja: '日本語', ko: '韓国語' }, scopeTitle: '生成する内容', scopeStory: '物語とレベル', scopeStoryBody: '人物、任務、状態、結末', scopeVisuals: 'ビジュアル', scopeVisualsBody: '人物、背景、小道具、動画', scopeVoice: '音声', scopeVoiceBody: 'プレイヤー、NPC、結末', scopeError: '1つ以上選択してください。', assetsTitle: '参考素材', assetsBody: '任意。人物や世界の一貫性を高めます。', uploadAction: '参考ファイルを追加', uploadHint: '1ファイル · TXT、PDF、Word、PNG、JPG、WEBP · 最大10 MB', supportedTitle: '対応素材', supportedBody: '人物・背景・小道具・画風画像、脚本、文書、動画、音声。', removeFile: '{name} を削除', saved: '下書きを保存しました。', draftNote: '初版はローカル下書き保存に対応します。', save: '下書きを保存' },
labels: { scenario: 'シナリオ', asset: '素材', mode: 'モード', phase: 'フェーズ', location: '場所', noRun: '未開始', none: 'なし' },
}