Adjust some things in mvmz
This commit is contained in:
parent
aea6760f3e
commit
48adaa445b
18 changed files with 12151 additions and 12082 deletions
1199
modules/alice.py
1199
modules/alice.py
File diff suppressed because it is too large
Load diff
1141
modules/anim.py
1141
modules/anim.py
File diff suppressed because it is too large
Load diff
1402
modules/csv.py
1402
modules/csv.py
File diff suppressed because it is too large
Load diff
1473
modules/eushully.py
1473
modules/eushully.py
File diff suppressed because it is too large
Load diff
1503
modules/irissoft.py
1503
modules/irissoft.py
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1137
modules/json.py
1137
modules/json.py
File diff suppressed because it is too large
Load diff
1405
modules/kansen.py
1405
modules/kansen.py
File diff suppressed because it is too large
Load diff
1223
modules/kirikiri.py
1223
modules/kirikiri.py
File diff suppressed because it is too large
Load diff
330
modules/main.py
330
modules/main.py
|
|
@ -1,165 +1,165 @@
|
|||
import sys
|
||||
import os
|
||||
import traceback
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from colorama import Fore
|
||||
from tqdm import tqdm
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# This needs to be before the module imports as some of them currently try to read and use some of these values
|
||||
# upon import, in which case if they are unset the script will crash before we can output these messages.
|
||||
envMissing = False
|
||||
load_dotenv()
|
||||
for env in [
|
||||
"api",
|
||||
"key",
|
||||
"organization",
|
||||
"model",
|
||||
"language",
|
||||
"timeout",
|
||||
"fileThreads",
|
||||
"threads",
|
||||
"width",
|
||||
"listWidth",
|
||||
]:
|
||||
if os.getenv(env) is None or str(os.getenv(env))[:1] == "<":
|
||||
tqdm.write(Fore.RED + f"Environment variable {env} is not set!")
|
||||
envMissing = True
|
||||
if envMissing:
|
||||
tqdm.write(
|
||||
Fore.RED
|
||||
+ "Some of the required environment values may not be set correctly. You can set \
|
||||
these values using an .env file, for an example see .env.example"
|
||||
)
|
||||
|
||||
from modules.rpgmakermvmz import handleMVMZ
|
||||
from modules.rpgmakerace import handleACE
|
||||
from modules.csv import handleCSV
|
||||
from modules.eushully import handleEushully
|
||||
from modules.alice import handleAlice
|
||||
from modules.tyrano import handleTyrano
|
||||
from modules.kirikiri import handleKirikiri
|
||||
from modules.json import handleJSON
|
||||
from modules.kansen import handleKansen
|
||||
from modules.lune import handleLune
|
||||
from modules.atelier import handleAtelier
|
||||
from modules.anim import handleAnim
|
||||
from modules.nscript import handleOnscripter
|
||||
from modules.wolf import handleWOLF
|
||||
from modules.wolf2 import handleWOLF2
|
||||
from modules.javascript import handleJavascript
|
||||
from modules.irissoft import handleIris
|
||||
from modules.regex import handleRegex
|
||||
from modules.text import handleText
|
||||
from modules.renpy import handleRenpy
|
||||
from modules.unity import handleUnity
|
||||
from modules.images import handleImages
|
||||
from modules.rpgmakerplugin import handlePlugin
|
||||
|
||||
# For GPT4 rate limit will be hit if you have more than 1 thread.
|
||||
# 1 Thread for each file. Controls how many files are worked on at once.
|
||||
THREADS = int(os.getenv("fileThreads"))
|
||||
|
||||
# [Display name, file extension, handle function]
|
||||
MODULES = [
|
||||
["RPGMaker MV/MZ", ["json"], handleMVMZ],
|
||||
["RPGMaker Plugins", ["js"], handlePlugin],
|
||||
["RPGMaker ACE", ["yaml"], handleACE],
|
||||
["CSV (From Translator++)", ["csv"], handleCSV],
|
||||
["Eushully", ["txt"], handleEushully],
|
||||
["Alice", ["txt"], handleAlice],
|
||||
["Tyrano", ["ks"], handleTyrano],
|
||||
["Kirikiri", ["ks", "tjs", "ssd", "asd"], handleKirikiri],
|
||||
["JSON", ["json"], handleJSON],
|
||||
["Kansen", ["ks"], handleKansen],
|
||||
["Lune", ["json"], handleLune],
|
||||
["Atelier", ["txt"], handleAtelier],
|
||||
["Anim", ["json"], handleAnim],
|
||||
["NScript", ["txt"], handleOnscripter],
|
||||
["Wolf", ["json"], handleWOLF],
|
||||
["Wolf", ["txt"], handleWOLF2],
|
||||
["Javascript", ["js"], handleJavascript],
|
||||
["Iris", ["txt"], handleIris],
|
||||
["Regex", ["txt", "json", "script"], handleRegex],
|
||||
["Text", ["txt", "srt"], handleText],
|
||||
["Renpy", ["rpy"], handleRenpy],
|
||||
["Unity", ["txt"], handleUnity],
|
||||
["Images", [""], handleImages],
|
||||
]
|
||||
|
||||
# Info Message
|
||||
tqdm.write(
|
||||
Fore.LIGHTYELLOW_EX
|
||||
+ "WARNING: Once the translation starts do not close it unless you want to lose your \
|
||||
translated data. If a file fails or gets stuck, translated lines will remain translated so you don't have \
|
||||
to worry about being charged twice. You can simply copy the file generated in /translations back over to \
|
||||
/files and start the script again. It will skip over any translated text."
|
||||
+ Fore.RESET,
|
||||
end="\n\n",
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
estimate = ""
|
||||
while estimate == "":
|
||||
estimate = input("Select Translation or Cost Estimation:\n\n 1. Translate\n 2. Estimate\n")
|
||||
match estimate:
|
||||
case "1":
|
||||
estimate = False
|
||||
case "2":
|
||||
estimate = True
|
||||
case _:
|
||||
estimate = ""
|
||||
|
||||
version = ""
|
||||
while True:
|
||||
tqdm.write("Select game engine:\n")
|
||||
for position, module in enumerate(MODULES):
|
||||
tqdm.write(f"{str(position + 1).rjust(2)}. {module[0]} (.{module[1]})")
|
||||
version = input()
|
||||
try:
|
||||
version = int(version) - 1
|
||||
except:
|
||||
continue
|
||||
if version in range(len(MODULES)):
|
||||
break
|
||||
|
||||
totalCost = (
|
||||
Fore.RED
|
||||
+ "Translation module didn't return the total cost. Make sure the \
|
||||
files to translate are in the /files folder and that you picked the right game engine."
|
||||
)
|
||||
|
||||
# Open File (Threads)
|
||||
with ThreadPoolExecutor(max_workers=THREADS) as executor:
|
||||
futures = [
|
||||
executor.submit(MODULES[version][2], filename, estimate)
|
||||
for filename in os.listdir("files")
|
||||
for m in MODULES[version][1]
|
||||
if filename.endswith(m) and filename != ".gitkeep"
|
||||
]
|
||||
for future in as_completed(futures):
|
||||
try:
|
||||
totalCost = future.result()
|
||||
except Exception as e:
|
||||
tracebackLineNo = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
|
||||
tqdm.write(Fore.RED + str(e) + "|" + tracebackLineNo + Fore.RESET)
|
||||
|
||||
# Delete Tmp Files
|
||||
if os.path.isfile("csv.tmp"):
|
||||
os.remove("csv.tmp")
|
||||
|
||||
# Finish
|
||||
if totalCost != "Fail":
|
||||
# if estimate is False:
|
||||
# This is to encourage people to grab what's in /translated instead
|
||||
# deleteFolderFiles("files")
|
||||
|
||||
tqdm.write(str(totalCost))
|
||||
|
||||
|
||||
def deleteFolderFiles(folderPath):
|
||||
for filename in os.listdir(folderPath):
|
||||
file_path = os.path.join(folderPath, filename)
|
||||
if file_path.endswith((".json", ".yaml", ".ks")):
|
||||
os.remove(file_path)
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from colorama import Fore
|
||||
from tqdm import tqdm
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# This needs to be before the module imports as some of them currently try to read and use some of these values
|
||||
# upon import, in which case if they are unset the script will crash before we can output these messages.
|
||||
envMissing = False
|
||||
load_dotenv()
|
||||
for env in [
|
||||
"api",
|
||||
"key",
|
||||
"organization",
|
||||
"model",
|
||||
"language",
|
||||
"timeout",
|
||||
"fileThreads",
|
||||
"threads",
|
||||
"width",
|
||||
"listWidth",
|
||||
]:
|
||||
if os.getenv(env) is None or str(os.getenv(env))[:1] == "<":
|
||||
tqdm.write(Fore.RED + f"Environment variable {env} is not set!")
|
||||
envMissing = True
|
||||
if envMissing:
|
||||
tqdm.write(
|
||||
Fore.RED
|
||||
+ "Some of the required environment values may not be set correctly. You can set \
|
||||
these values using an .env file, for an example see .env.example"
|
||||
)
|
||||
|
||||
from modules.rpgmakermvmz import handleMVMZ
|
||||
from modules.rpgmakerace import handleACE
|
||||
from modules.csv import handleCSV
|
||||
from modules.eushully import handleEushully
|
||||
from modules.alice import handleAlice
|
||||
from modules.tyrano import handleTyrano
|
||||
from modules.kirikiri import handleKirikiri
|
||||
from modules.json import handleJSON
|
||||
from modules.kansen import handleKansen
|
||||
from modules.lune import handleLune
|
||||
from modules.atelier import handleAtelier
|
||||
from modules.anim import handleAnim
|
||||
from modules.nscript import handleOnscripter
|
||||
from modules.wolf import handleWOLF
|
||||
from modules.wolf2 import handleWOLF2
|
||||
from modules.javascript import handleJavascript
|
||||
from modules.irissoft import handleIris
|
||||
from modules.regex import handleRegex
|
||||
from modules.text import handleText
|
||||
from modules.renpy import handleRenpy
|
||||
from modules.unity import handleUnity
|
||||
from modules.images import handleImages
|
||||
from modules.rpgmakerplugin import handlePlugin
|
||||
|
||||
# For GPT4 rate limit will be hit if you have more than 1 thread.
|
||||
# 1 Thread for each file. Controls how many files are worked on at once.
|
||||
THREADS = int(os.getenv("fileThreads"))
|
||||
|
||||
# [Display name, file extension, handle function]
|
||||
MODULES = [
|
||||
["RPGMaker MV/MZ", ["json"], handleMVMZ],
|
||||
["RPGMaker Plugins", ["js"], handlePlugin],
|
||||
["RPGMaker ACE", ["yaml"], handleACE],
|
||||
["CSV (From Translator++)", ["csv"], handleCSV],
|
||||
["Eushully", ["txt"], handleEushully],
|
||||
["Alice", ["txt"], handleAlice],
|
||||
["Tyrano", ["ks"], handleTyrano],
|
||||
["Kirikiri", ["ks", "tjs", "ssd", "asd"], handleKirikiri],
|
||||
["JSON", ["json"], handleJSON],
|
||||
["Kansen", ["ks"], handleKansen],
|
||||
["Lune", ["json"], handleLune],
|
||||
["Atelier", ["txt"], handleAtelier],
|
||||
["Anim", ["json"], handleAnim],
|
||||
["NScript", ["txt"], handleOnscripter],
|
||||
["Wolf", ["json"], handleWOLF],
|
||||
["Wolf", ["txt"], handleWOLF2],
|
||||
["Javascript", ["js"], handleJavascript],
|
||||
["Iris", ["txt"], handleIris],
|
||||
["Regex", ["txt", "json", "script", "csv"], handleRegex],
|
||||
["Text", ["txt", "srt"], handleText],
|
||||
["Renpy", ["rpy"], handleRenpy],
|
||||
["Unity", ["txt"], handleUnity],
|
||||
["Images", [""], handleImages],
|
||||
]
|
||||
|
||||
# Info Message
|
||||
tqdm.write(
|
||||
Fore.LIGHTYELLOW_EX
|
||||
+ "WARNING: Once the translation starts do not close it unless you want to lose your \
|
||||
translated data. If a file fails or gets stuck, translated lines will remain translated so you don't have \
|
||||
to worry about being charged twice. You can simply copy the file generated in /translations back over to \
|
||||
/files and start the script again. It will skip over any translated text."
|
||||
+ Fore.RESET,
|
||||
end="\n\n",
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
estimate = ""
|
||||
while estimate == "":
|
||||
estimate = input("Select Translation or Cost Estimation:\n\n 1. Translate\n 2. Estimate\n")
|
||||
match estimate:
|
||||
case "1":
|
||||
estimate = False
|
||||
case "2":
|
||||
estimate = True
|
||||
case _:
|
||||
estimate = ""
|
||||
|
||||
version = ""
|
||||
while True:
|
||||
tqdm.write("Select game engine:\n")
|
||||
for position, module in enumerate(MODULES):
|
||||
tqdm.write(f"{str(position + 1).rjust(2)}. {module[0]} (.{module[1]})")
|
||||
version = input()
|
||||
try:
|
||||
version = int(version) - 1
|
||||
except:
|
||||
continue
|
||||
if version in range(len(MODULES)):
|
||||
break
|
||||
|
||||
totalCost = (
|
||||
Fore.RED
|
||||
+ "Translation module didn't return the total cost. Make sure the \
|
||||
files to translate are in the /files folder and that you picked the right game engine."
|
||||
)
|
||||
|
||||
# Open File (Threads)
|
||||
with ThreadPoolExecutor(max_workers=THREADS) as executor:
|
||||
futures = [
|
||||
executor.submit(MODULES[version][2], filename, estimate)
|
||||
for filename in os.listdir("files")
|
||||
for m in MODULES[version][1]
|
||||
if filename.endswith(m) and filename != ".gitkeep"
|
||||
]
|
||||
for future in as_completed(futures):
|
||||
try:
|
||||
totalCost = future.result()
|
||||
except Exception as e:
|
||||
tracebackLineNo = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
|
||||
tqdm.write(Fore.RED + str(e) + "|" + tracebackLineNo + Fore.RESET)
|
||||
|
||||
# Delete Tmp Files
|
||||
if os.path.isfile("csv.tmp"):
|
||||
os.remove("csv.tmp")
|
||||
|
||||
# Finish
|
||||
if totalCost != "Fail":
|
||||
# if estimate is False:
|
||||
# This is to encourage people to grab what's in /translated instead
|
||||
# deleteFolderFiles("files")
|
||||
|
||||
tqdm.write(str(totalCost))
|
||||
|
||||
|
||||
def deleteFolderFiles(folderPath):
|
||||
for filename in os.listdir(folderPath):
|
||||
file_path = os.path.join(folderPath, filename)
|
||||
if file_path.endswith((".json", ".yaml", ".ks")):
|
||||
os.remove(file_path)
|
||||
|
|
|
|||
1242
modules/regex.py
1242
modules/regex.py
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1081
modules/text.py
1081
modules/text.py
File diff suppressed because it is too large
Load diff
1229
modules/tyrano.py
1229
modules/tyrano.py
File diff suppressed because it is too large
Load diff
1099
modules/unity.py
1099
modules/unity.py
File diff suppressed because it is too large
Load diff
1159
modules/wolf2.py
1159
modules/wolf2.py
File diff suppressed because it is too large
Load diff
218
vocab.txt
218
vocab.txt
|
|
@ -1,93 +1,127 @@
|
|||
Here are some vocabulary and terms so that you know the proper spelling and translation.
|
||||
```
|
||||
# Game Characters
|
||||
Adachi Tenka (足立 甜花) - Female
|
||||
Komako Semenovich (コマコ セメノビッチ) - Female
|
||||
Sayama Chie (狭山 千恵) - Female
|
||||
Sayama Yuuko (狭山 優子) - Female
|
||||
Hanano Fuuka (華野 楓花) - Female
|
||||
Tachikawa Kiyoshi (立川 清) - Male
|
||||
|
||||
# Lewd Terms
|
||||
マンコ (pussy)
|
||||
おまんこ (vagina)
|
||||
尻 (ass)
|
||||
お尻 (butt)
|
||||
お股 (crotch)
|
||||
秘部 (genitals)
|
||||
チンポ (dick)
|
||||
チンコ (cock)
|
||||
ショーツ (panties)
|
||||
|
||||
# Honorifics
|
||||
さん (san)
|
||||
様, さま (sama)
|
||||
君, くん (kun)
|
||||
ちゃん (chan)
|
||||
たん (tan)
|
||||
先輩 (senpai)
|
||||
せんぱい (senpai)
|
||||
先生 (sensei)
|
||||
師匠 (shishou)
|
||||
せんせい (sensei)
|
||||
にいさん (nii-san)
|
||||
兄さん (nii-san)
|
||||
お兄ちゃん (onii-san)
|
||||
姉さん (nee-san)
|
||||
お姉ちゃん (onee-chan)
|
||||
ねえさん (nee-san)
|
||||
|
||||
# System
|
||||
初めから (Start)
|
||||
逃げる (Escape)
|
||||
大事なもの (Key Items)
|
||||
最強装備 (Optimize)
|
||||
攻撃力 (Attack)
|
||||
回避率 (Evasion)
|
||||
敏捷性 (Agility)
|
||||
最大HP (Max HP)
|
||||
経験値 (EXP)
|
||||
購入する (Buy)
|
||||
魔力攻撃 (M. Attack)
|
||||
魔力防御 (M. Defense)
|
||||
魔法力 (M. Power)
|
||||
命中率 (Accuracy)
|
||||
%1 の%2を獲得! (Gained %1 %2)
|
||||
持っている数 (Owned)
|
||||
ME 音量 (ME Volume)
|
||||
回想する (Recollection)
|
||||
|
||||
# RPG
|
||||
魂 (Soul)
|
||||
エクスポーション (EX Potion)
|
||||
アスカロン (Ascalon)
|
||||
刀 (Sword)
|
||||
ゴブリン (Goblin)
|
||||
|
||||
# Demons/Angels
|
||||
悪魔 (Devil)
|
||||
上級悪魔 (Arch Devil)
|
||||
歪魔 (Distorted Devil)
|
||||
魔神 (Demon)
|
||||
魔人 (Majin)
|
||||
睡魔 (Mare)
|
||||
淫魔 (Succubus)
|
||||
天使 (Angel)
|
||||
大天使 (Archangel)
|
||||
権天使 (Ruler)
|
||||
能天使 (Power)
|
||||
力天使 (Virtue)
|
||||
主天使 (Dominion)
|
||||
智天使 (Cherub)
|
||||
飛天魔 (Nephilim)
|
||||
堕天使 (Fallen Angel)
|
||||
鬼 (Oni)
|
||||
妖怪 (Yokai)
|
||||
式神 (Shikigami)
|
||||
|
||||
# Terms
|
||||
ローバー (Roper)
|
||||
w ((lol))
|
||||
巫女 (Shrine Maiden)
|
||||
コイツ (this bastard)
|
||||
Here are some vocabulary and terms so that you know the proper spelling and translation.
|
||||
```
|
||||
# Game Characters
|
||||
種島のぞみ (Nozomi Tanejima) - Female
|
||||
佐和田美結 (Miyu Sawada) - Female
|
||||
笠島陽菜 (Hina Kasajima) - Female
|
||||
遠藤香里 (Kaori Endo) - Female
|
||||
|
||||
# Lewd Terms
|
||||
マンコ (pussy)
|
||||
おまんこ (vagina)
|
||||
尻 (ass)
|
||||
お尻 (butt)
|
||||
お股 (crotch)
|
||||
秘部 (genitals)
|
||||
チンポ (dick)
|
||||
チンコ (cock)
|
||||
ショーツ (panties)
|
||||
|
||||
# Honorifics
|
||||
さん (san)
|
||||
様, さま (sama)
|
||||
君, くん (kun)
|
||||
ちゃん (chan)
|
||||
たん (tan)
|
||||
先輩 (senpai)
|
||||
せんぱい (senpai)
|
||||
先生 (sensei)
|
||||
師匠 (shishou)
|
||||
せんせい (sensei)
|
||||
にいさん (nii-san)
|
||||
兄さん (nii-san)
|
||||
お兄ちゃん (onii-san)
|
||||
姉さん (nee-san)
|
||||
お姉ちゃん (onee-chan)
|
||||
ねえさん (nee-san)
|
||||
|
||||
# System
|
||||
初めから (Start)
|
||||
逃げる (Escape)
|
||||
大事なもの (Key Items)
|
||||
最強装備 (Optimize)
|
||||
攻撃力 (Attack)
|
||||
回避率 (Evasion)
|
||||
敏捷性 (Agility)
|
||||
最大HP (Max HP)
|
||||
経験値 (EXP)
|
||||
購入する (Buy)
|
||||
魔力攻撃 (M. Attack)
|
||||
魔力防御 (M. Defense)
|
||||
魔法力 (M. Power)
|
||||
命中率 (Accuracy)
|
||||
%1 の%2を獲得! (Gained %1 %2)
|
||||
持っている数 (Owned)
|
||||
ME 音量 (ME Volume)
|
||||
回想する (Recollection)
|
||||
|
||||
# RPG
|
||||
魂 (Soul)
|
||||
エクスポーション (EX Potion)
|
||||
アスカロン (Ascalon)
|
||||
刀 (Sword)
|
||||
ゴブリン (Goblin)
|
||||
|
||||
# Demons/Angels
|
||||
悪魔 (Devil)
|
||||
上級悪魔 (Arch Devil)
|
||||
歪魔 (Distorted Devil)
|
||||
魔神 (Demon)
|
||||
魔人 (Majin)
|
||||
睡魔 (Mare)
|
||||
淫魔 (Succubus)
|
||||
天使 (Angel)
|
||||
大天使 (Archangel)
|
||||
権天使 (Ruler)
|
||||
能天使 (Power)
|
||||
力天使 (Virtue)
|
||||
主天使 (Dominion)
|
||||
智天使 (Cherub)
|
||||
飛天魔 (Nephilim)
|
||||
堕天使 (Fallen Angel)
|
||||
鬼 (Oni)
|
||||
妖怪 (Yokai)
|
||||
式神 (Shikigami)
|
||||
|
||||
# Terms
|
||||
ローバー (Roper)
|
||||
w ((lol))
|
||||
巫女 (Shrine Maiden)
|
||||
コイツ (this bastard)
|
||||
|
||||
#Items
|
||||
デバッグ用 (Debug Item)
|
||||
スマホ (Smartphone)
|
||||
チョコレート (Chocolate)
|
||||
疲労回復サプリ (Fatigue Recovery Supplement)
|
||||
エナジードリンク (Energy Drink)
|
||||
栄養ドリンク (Nutritional Drink)
|
||||
高級栄養ドリンク (Premium Nutritional Drink)
|
||||
コンドーム (Condom)
|
||||
お守り (Amulet)
|
||||
参考書 (Reference Book)
|
||||
ファッション雑誌 (Fashion Magazine)
|
||||
淑女のありかた (The Way of a Lady)
|
||||
1日1善 (One Good Deed a Day)
|
||||
配信機材セット (Streaming Equipment Set)
|
||||
いい釣竿 (Good Fishing Rod)
|
||||
真剣ゼミ (Serious Study Program)
|
||||
コスメセット (Cosmetic Set)
|
||||
ピル (Pill)
|
||||
アフターピル (Morning-After Pill)
|
||||
ローション (Lotion)
|
||||
ディルド (Dildo)
|
||||
アナルバイブ (Anal Vibrator)
|
||||
ペニバン (Strap-On)
|
||||
オトナの女の四十八手 (48 Techniques of an Adult Woman)
|
||||
正しいお尻の開発方法 (Proper Butt Development Method)
|
||||
虜にさせる口技集 (Oral Techniques to Enchant)
|
||||
ドキドキ露出プレイ (Exciting Exposure Play)
|
||||
夜のご奉仕大全 (Night Service Compendium)
|
||||
感じる乳房の作り方 (How to Create Sensitive Breasts)
|
||||
時計 (Watch)
|
||||
|
||||
# Locations:
|
||||
鴨ノ橋学園 (Kaminohashi Academy)
|
||||
喫茶店『宿り木』 (Cafe 'Yadorigi')
|
||||
```
|
||||
Loading…
Reference in a new issue