diff --git a/.idea/misc.xml b/.idea/misc.xml
index b2c751a..7e4f6ee 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -6,4 +6,11 @@
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index fc922ac..68454df 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -51,6 +51,16 @@ dependencies {
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
implementation("androidx.recyclerview:recyclerview:1.3.2")
+ implementation("com.squareup.retrofit2:retrofit:2.9.0")
+ implementation("com.squareup.retrofit2:converter-simplexml:2.9.0")
+ dependencies {
+ implementation("com.squareup.retrofit2:retrofit:2.9.0")
+ implementation("com.squareup.retrofit2:converter-simplexml:2.9.0")
+ implementation("com.squareup.okhttp3:okhttp:4.11.0")
+ implementation("com.squareup.moshi:moshi-kotlin:1.15.0")
+
+ }
+
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96e4581..d4dde1b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/curation_train_app/AkaneReponder.kt b/app/src/main/java/com/example/curation_train_app/AkaneReponder.kt
new file mode 100644
index 0000000..446c71b
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/AkaneReponder.kt
@@ -0,0 +1,23 @@
+package com.example.curation_train_app
+
+class AkaneResponder : CharacterResponder {
+
+ override val profile = CharacterProfiles.akane
+
+ override fun respond(info: String, type: InfoType): String {
+ return when (type) {
+
+ InfoType.DELAY ->
+ "えっ!?遅延!? 急ぐなら別ルートも考えたほうがいいかもだよっ!!"
+
+ InfoType.REVISION ->
+ "うわーっ!ダイヤ改正だって!? 新しい運用とかワクワクするじゃんっ!"
+
+ InfoType.EVENT ->
+ "イベント列車!? こういうのめっちゃ楽しみだよねっ!!"
+
+ else ->
+ "なんか気になる情報があるよねっ!気をつけていこーっ!"
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/CharacterProfile.kt b/app/src/main/java/com/example/curation_train_app/CharacterProfile.kt
new file mode 100644
index 0000000..ee0f6f3
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/CharacterProfile.kt
@@ -0,0 +1,136 @@
+package com.example.curation_train_app
+
+object CharacterProfiles {
+
+ data class CharacterProfile(
+ val id: String,
+ val name: String,
+ val speakingStyle: String, // 話し方・口調の説明
+ val personality: String, // 性格・立ち位置
+ val knowledgeLevel: String // 鉄道知識レベル
+ )
+
+ // ───────────────────────────────
+ // 🔴1. 霊夢(メイン進行・解説)
+ // ───────────────────────────────
+ val reimu = CharacterProfile(
+ id = "reimu",
+ name = "霊夢",
+ speakingStyle =
+ "落ち着いた女言葉。断定を避け、やわらかい表現。敬語は使わない。" +
+ "語尾は自然な範囲で「〜よ」「〜わよ」「〜よね」を用いる。",
+ personality =
+ "穏やか、冷静、全体進行役。説明整理が得意で、視聴者に安心感を与える。優しい。",
+ knowledgeLevel = "中程度の鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // 🟡2. 魔理沙(補足・深掘り担当)
+ // ───────────────────────────────
+ val marisa = CharacterProfile(
+ id = "marisa",
+ name = "魔理沙",
+ speakingStyle =
+ "元気な口調。「〜だぜ」は乱発せず、強調・納得・気付きの場面でだけ自然に使う。",
+ personality =
+ "深掘り・解説の補足、技術寄りの説明が得意。少しテンション高めで勢いがある。",
+ knowledgeLevel = "高い鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // 🟠3. フラン(明るく元気)
+ // ───────────────────────────────
+ val flan = CharacterProfile(
+ id = "flan",
+ name = "フラン",
+ speakingStyle =
+ "明るく元気。テンションが高いときだけ「なのだー」「のだー」が出る。" +
+ "普段は普通の話し方で語尾を毎回つけない。",
+ personality =
+ "ムードメーカー。感情表現が大きく、明るい。盛り上げ役。",
+ knowledgeLevel = "中〜低の鉄道知識(感覚派)"
+ )
+
+ // ───────────────────────────────
+ // 🟢4. 早苗(丁寧で落ち着いた補足役)
+ // ───────────────────────────────
+ val sanae = CharacterProfile(
+ id = "sanae",
+ name = "早苗",
+ speakingStyle =
+ "丁寧で落ち着いた語り。霊夢寄りの柔らかい話し方。敬語あり。",
+ personality =
+ "冷静な補足役。情景や背景知識を丁寧に伝える。視点が穏やか。",
+ knowledgeLevel = "中程度の鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // 🟨5. あかね(テンション高い・視聴者代表)
+ // ───────────────────────────────
+ val akane = CharacterProfile(
+ id = "akane",
+ name = "あかね",
+ speakingStyle =
+ "元気で明るい。テンション高め。語尾に小さい「っ」が入ることがある。" +
+ "自分のことを「HN君」と呼ぶ。",
+ personality =
+ "視聴者代表。リアクション担当。疑問を素直に口に出す。場を明るくする。",
+ knowledgeLevel = "低〜中の鉄道知識。難しい話は苦手。"
+ )
+
+ // ───────────────────────────────
+ // 🟦6. さやか(冷静・整理役)
+ // ───────────────────────────────
+ val sayaka = CharacterProfile(
+ id = "sayaka",
+ name = "さやか",
+ speakingStyle =
+ "落ち着いた女言葉。霊夢寄りの丁寧な話し方。語尾は崩れない。敬語は使わない",
+ personality =
+ "冷静な説明・整理役。感情を抑えめに、的確に指摘する。",
+ knowledgeLevel = "中程度の鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // 🟧7. ひより(穏やか・控えめ)
+ // ───────────────────────────────
+ val hiyori = CharacterProfile(
+ id = "hiyori",
+ name = "ひより",
+ speakingStyle =
+ "やわらかく、控えめな話し方。語彙は優しめ。崩れすぎない。",
+ personality =
+ "優しく控えめで、聞き役になることもある。しっかり者だが遠慮がち。",
+ knowledgeLevel = "中〜低の鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // 🍑8. ももか(甘めの口調・テンション高め)
+ // ───────────────────────────────
+ val momoka = CharacterProfile(
+ id = "momoka",
+ name = "ももか",
+ speakingStyle =
+ "かわいめの語尾・柔らかい話し方。テンション高めの時だけ「っ」が入る。",
+ personality =
+ "甘めの雰囲気で明るい。感情が前に出るタイプ。",
+ knowledgeLevel = "低〜中の鉄道知識"
+ )
+
+ // ───────────────────────────────
+ // ID → キャラ検索
+ // ───────────────────────────────
+ fun getProfile(id: String): CharacterProfile? {
+ return when (id.lowercase()) {
+ "reimu" -> reimu
+ "marisa" -> marisa
+ "flan" -> flan
+ "sanae" -> sanae
+ "akane" -> akane
+ "sayaka" -> sayaka
+ "hiyori" -> hiyori
+ "momoka" -> momoka
+ else -> null
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/CharacterReplyManager.kt b/app/src/main/java/com/example/curation_train_app/CharacterReplyManager.kt
new file mode 100644
index 0000000..88378f6
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/CharacterReplyManager.kt
@@ -0,0 +1,39 @@
+package com.example.curation_train_app
+
+import com.example.curation_train_app.ai.PromptBuilder
+import com.example.curation_train_app.ai.AiClient
+private const val API_KEY = "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"
+
+
+
+class CharacterReplyManager {
+
+ private val responders = mapOf(
+ "reimu" to ReimuResponder(),
+ "akane" to AkaneResponder(),
+ "marisa" to MarisaResponder(),
+ "sayaka" to SayakResponder(),
+ "sanae" to SanaeResponder(),
+ "momoka" to MomokaResponder(),
+ "flandre" to flandreResponder(),
+ "hiyori" to HiyoriResponder()
+ // ← 6人追加予定
+ )
+
+ fun reply(characterId: String, info: String, type: InfoType): String {
+ val responder = responders[characterId]
+ ?: return "キャラが見つかりません。"
+ return responder.respond(info, type)
+ }
+ fun replyWithAI(characterId: String, info: String, type: InfoType): String {
+ val character = CharacterProfiles.getProfile(characterId)
+ ?: return "(エラー:キャラが不明です)"
+
+
+ val prompt = PromptBuilder.buildPrompt(character, info, type)
+
+ val ai = AiClient(API_KEY)
+ return ai.requestCharacterReply(prompt)
+ }
+
+}
diff --git a/app/src/main/java/com/example/curation_train_app/CharacterResponder.kt b/app/src/main/java/com/example/curation_train_app/CharacterResponder.kt
new file mode 100644
index 0000000..0f544bf
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/CharacterResponder.kt
@@ -0,0 +1,6 @@
+package com.example.curation_train_app
+
+interface CharacterResponder {
+ val profile: CharacterProfiles.CharacterProfile
+ fun respond(info: String, type: InfoType): String
+}
diff --git a/app/src/main/java/com/example/curation_train_app/DummyLines.kt b/app/src/main/java/com/example/curation_train_app/DummyLines.kt
new file mode 100644
index 0000000..f304527
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/DummyLines.kt
@@ -0,0 +1,18 @@
+package com.example.curation_train_app
+
+object DummyLines {
+
+ fun linesOf(region: String): List {
+ return when (region) {
+ "北海道" -> listOf("JR北海道全線", "札幌市営地下鉄", "道南いさりび鉄道")
+ "東北" -> listOf("JR東日本(東北)", "仙台市地下鉄", "青い森鉄道")
+ "関東" -> listOf("JR東日本(関東)", "東京メトロ", "京急", "東急", "小田急", "京王")
+ "中部" -> listOf("JR東海", "名鉄", "近鉄(名古屋)")
+ "関西" -> listOf("JR西日本(関西)", "大阪メトロ", "阪急", "阪神", "京阪", "南海", "近鉄(関西)")
+ "中国" -> listOf("JR西日本(中国)", "広島電鉄", "一畑電車")
+ "四国" -> listOf("JR四国")
+ "九州" -> listOf("JR九州", "西鉄")
+ else -> listOf("該当する路線がありません")
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/FillterSettingActivity.kt b/app/src/main/java/com/example/curation_train_app/FillterSettingActivity.kt
new file mode 100644
index 0000000..c2f82da
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/FillterSettingActivity.kt
@@ -0,0 +1,12 @@
+package com.example.curation_train_app
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+
+class FilterSettingActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_filter_setting)
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/HiyoriResponder.kt b/app/src/main/java/com/example/curation_train_app/HiyoriResponder.kt
new file mode 100644
index 0000000..cc05ad7
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/HiyoriResponder.kt
@@ -0,0 +1,23 @@
+package com.example.curation_train_app
+
+class HiyoriResponder : CharacterResponder {
+
+ override val profile = CharacterProfiles.hiyori
+
+ override fun respond(info: String, type: InfoType): String {
+ return when (type) {
+
+ InfoType.DELAY ->
+ "遅延しているみたい…焦らずに、少し余裕を持って動けるといいね。"
+
+ InfoType.REVISION ->
+ "ダイヤが変わるんだね…。知らないと戸惑うから、確認しておくと安心だよ。"
+
+ InfoType.EVENT ->
+ "イベント列車…!楽しそうだね。時間が合えば、ちょっと見に行ってみたいな。"
+
+ else ->
+ "気になったことがあるの?よかったら教えてね。いっしょに見てみるよ。"
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/InfoClassifier.kt b/app/src/main/java/com/example/curation_train_app/InfoClassifier.kt
new file mode 100644
index 0000000..d7afbe5
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/InfoClassifier.kt
@@ -0,0 +1,28 @@
+package com.example.curation_train_app
+
+object InfoClassifier {
+
+ fun classify(text: String): InfoType {
+
+ val t = text.lowercase()
+
+ return when {
+ // 遅延系
+ t.contains("遅延") || t.contains("遅れ") || t.contains("delay") ->
+ InfoType.DELAY
+
+ // ダイヤ改正 / 運転変更
+ t.contains("ダイヤ") || t.contains("時刻表") || t.contains("運転変更") ->
+ InfoType.REVISION
+
+ // 注意報・警報・天候・安全
+ t.contains("強風") || t.contains("大雨") ||
+ t.contains("警報") || t.contains("注意喚起") ||
+ t.contains("事故") || t.contains("運休") ->
+ InfoType.WEATHER
+
+ // その他
+ else -> InfoType.OTHER
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/curation_train_app/InfoType.kt b/app/src/main/java/com/example/curation_train_app/InfoType.kt
new file mode 100644
index 0000000..143bf68
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/InfoType.kt
@@ -0,0 +1,12 @@
+package com.example.curation_train_app
+
+enum class InfoType {
+ DELAY, // 遅延
+ SUSPENSION, // 運休
+ REVISION, // ダイヤ改正
+ CONSTRUCTION, // 工事
+ EVENT, // イベント・臨時列車
+ WEATHER, // 天候影響
+ NEW_TRAIN, // 新型車両関連
+ OTHER // 分類できない場合
+}
diff --git a/app/src/main/java/com/example/curation_train_app/LinePriorityActivity.kt b/app/src/main/java/com/example/curation_train_app/LinePriorityActivity.kt
new file mode 100644
index 0000000..0666d23
--- /dev/null
+++ b/app/src/main/java/com/example/curation_train_app/LinePriorityActivity.kt
@@ -0,0 +1,52 @@
+package com.example.curation_train_app
+
+import android.os.Bundle
+import android.widget.TextView
+import androidx.activity.ComponentActivity
+import android.content.Intent
+import android.widget.Button
+
+class LinePriorityActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_line_priority)
+
+ val btnOpenFilter = findViewById