From be67781f18cff61ee79eba18881c5c0e20dde57d Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 01:03:02 +0900
Subject: [PATCH 1/7] move to pages directory

---
 components/Summary.vue  | 590 ---------------------------------------
 pages/summary/index.vue | 593 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 589 insertions(+), 594 deletions(-)
 delete mode 100644 components/Summary.vue

diff --git a/components/Summary.vue b/components/Summary.vue
deleted file mode 100644
index 689bd94..0000000
--- a/components/Summary.vue
+++ /dev/null
@@ -1,590 +0,0 @@
-<script setup lang="ts">
-import type { SummaryOne } from "@/interfaces";
-const config = useRuntimeConfig(); // nuxt.config.ts に書いてあるコンフィグを読み出す
-const incomeList = ref<SummaryOne[]>()
-const incomeSumList = ref<SummaryOne>()
-const outgoingList = ref<SummaryOne[]>()
-const outgoingSumList = ref<SummaryOne>()
-const investList = ref<SummaryOne[]>()
-const investSumList = ref<SummaryOne>()
-const AllSumList = ref<SummaryOne>() // 合計フィールド
-const AllSumWithoutInvestList = ref<SummaryOne>() // 合計(投資除く)フィールド
-
-let fetched: boolean // api fetch 出来ていたら true にする(表示制御用)
-const asyncData = await useFetch(
-  "/api/summary",
-  {
-    key: `/api/summary`,
-    transform: (data: SummaryOne[]): SummaryOne[][] => {
-      let incomeArray: SummaryOne[] = [];
-      let outgoingArray: SummaryOne[] = [];
-      let investArray: SummaryOne[] = [];
-      for (let d of data) {
-        if ([100, 101, 110].includes(d.category_id)) {
-          incomeArray.push(d)
-        }
-        if ([200, 210, 220, 221, 222, 230, 231, 240, 250, 251, 260, 270, 280, 300, 400, 500].includes(d.category_id)) {
-          outgoingArray.push(d)
-        }
-        if ([700, 701].includes(d.category_id)) {
-          investArray.push(d)
-        }
-      }
-      const retArray: SummaryOne[][] = [incomeArray, outgoingArray, investArray]
-      return retArray
-    }
-  }
-);
-
-
-
-if (asyncData.data.value != undefined) {
-  const incomeData = asyncData.data.value[0] as SummaryOne[];
-  const outgoingData = asyncData.data.value[1] as SummaryOne[];
-  const investData = asyncData.data.value[2] as SummaryOne[];
-  incomeList.value = incomeData
-  outgoingList.value = outgoingData
-  investList.value = investData
-
-  // sum の計算(income)
-  let incomeSumData: SummaryOne = {
-    category_id: 999,
-    category_name: "収入合計",
-    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
-  };
-
-  for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
-    for (let d of incomeData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
-    }
-    incomeSumData.price[i] = sum;
-    incomeSumData.total += totalsum;
-  }
-  incomeSumList.value = incomeSumData
-
-  // sum の計算(outgoing)
-  let outgoingSumData: SummaryOne = {
-    category_id: 999,
-    category_name: "支出合計",
-    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
-  };
-  for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
-    for (let d of outgoingData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
-    }
-    outgoingSumData.price[i] = sum;
-    outgoingSumData.total += totalsum;
-  }
-  outgoingSumList.value = outgoingSumData
-
-  // sum の計算(invest)
-  let investSumData: SummaryOne = {
-    category_id: 999,
-    category_name: "投資合計",
-    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
-  };
-
-  for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
-    for (let d of investData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
-    }
-    investSumData.price[i] = sum;
-    investSumData.total += totalsum;
-  }
-  investSumList.value = investSumData
-
-  // 合計テーブル用の計算
-  let AllSumData: SummaryOne = {
-    category_id: 999,
-    category_name: "合計",
-    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
-  };
-
-  for (let i: number = 0; i < 12; i++) {
-    AllSumData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i] - investSumData.price[i];
-  }
-  AllSumData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
-  AllSumList.value = AllSumData
-
-  let AllSumWithoutInvestData: SummaryOne = {
-    category_id: 999,
-    category_name: "合計(投資除く)",
-    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
-  };
-
-  for (let i: number = 0; i < 12; i++) {
-    AllSumWithoutInvestData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i];
-  }
-  AllSumWithoutInvestData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
-  AllSumWithoutInvestList.value = AllSumWithoutInvestData
-
-  fetched = true // データ取得後のフラグを立てる
-}
-
-</script>
-
-<template>
-  <div class="container">
-    <a href="../">トップに戻る</a>
-
-    <h2>合計</h2>
-    <table class="table small bordered striped table-bordered">
-      <thead>
-        <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
-        </tr>
-      </thead>
-      <tbody>
-        <th scope="row"></th>
-        <tr v-if="fetched">
-          <td>{{ AllSumList.category_id }}</td>
-          <td>{{ AllSumList.category_name }}</td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumList.total }}</div>
-          </td>
-        </tr>
-        <tr v-if="fetched" class="table-info">
-          <td>{{ AllSumWithoutInvestList.category_id }}</td>
-          <td>{{ AllSumWithoutInvestList.category_name }}</td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.total }}</div>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-
-    <h2>収入</h2>
-    <table class="table small bordered striped table-bordered">
-      <thead>
-        <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr v-for="income in incomeList">
-          <td>{{ income.category_id }}</td>
-          <td>{{ income.category_name }}</td>
-          <td>
-            <div class="text-end">{{ income.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ income.total }}</div>
-          </td>
-        </tr>
-        <tr v-if="fetched" class="table-success">
-          <td>{{ incomeSumList.category_id }}</td>
-          <td>{{ incomeSumList.category_name }}</td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ incomeSumList.total }}</div>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-
-    <h2>支出</h2>
-    <table class="table small bordered striped table-bordered">
-      <thead>
-        <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr v-for="outgoing in outgoingList">
-          <td>{{ outgoing.category_id }}</td>
-          <td>{{ outgoing.category_name }}</td>
-          <td>
-            <div class="text-end">{{ outgoing.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoing.total }}</div>
-          </td>
-        </tr>
-        <tr v-if="fetched" class="table-danger">
-          <td>{{ outgoingSumList.category_id }}</td>
-          <td>{{ outgoingSumList.category_name }}</td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ outgoingSumList.total }}</div>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-
-    <h2>投資</h2>
-    <table class="table small bordered striped table-bordered">
-      <thead>
-        <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%"">合計</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr v-for=" invest in investList">
-          <td>{{ invest.category_id }}</td>
-          <td>{{ invest.category_name }}</td>
-          <td>
-            <div class="text-end">{{ invest.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ invest.total }}</div>
-          </td>
-        </tr>
-        <tr v-if="fetched" class="table-warning">
-          <td>{{ investSumList.category_id }}</td>
-          <td>{{ investSumList.category_name }}</td>
-          <td>
-            <div class="text-end">{{ investSumList.price[0] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[1] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[2] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[3] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[4] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[5] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[6] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[7] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[8] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[9] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[10] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.price[11] }}</div>
-          </td>
-          <td>
-            <div class="text-end">{{ investSumList.total }}</div>
-          </td>
-        </tr>
-        </tbody>
-    </table>
-
-  </div>
-</template>
diff --git a/pages/summary/index.vue b/pages/summary/index.vue
index e6fe983..b9d56c7 100644
--- a/pages/summary/index.vue
+++ b/pages/summary/index.vue
@@ -1,6 +1,591 @@
+<script setup lang="ts">
+import type { SummaryOne } from "@/interfaces";
+const config = useRuntimeConfig(); // nuxt.config.ts に書いてあるコンフィグを読み出す
+const incomeList = ref<SummaryOne[]>()
+const incomeSumList = ref<SummaryOne>()
+const outgoingList = ref<SummaryOne[]>()
+const outgoingSumList = ref<SummaryOne>()
+const investList = ref<SummaryOne[]>()
+const investSumList = ref<SummaryOne>()
+const AllSumList = ref<SummaryOne>() // 合計フィールド
+const AllSumWithoutInvestList = ref<SummaryOne>() // 合計(投資除く)フィールド
+
+let fetched: boolean // api fetch 出来ていたら true にする(表示制御用)
+const asyncData = await useFetch(
+  "/api/summary",
+  {
+    key: `/api/summary`,
+    transform: (data: SummaryOne[]): SummaryOne[][] => {
+      let incomeArray: SummaryOne[] = [];
+      let outgoingArray: SummaryOne[] = [];
+      let investArray: SummaryOne[] = [];
+      for (let d of data) {
+        if ([100, 101, 110].includes(d.category_id)) {
+          incomeArray.push(d)
+        }
+        if ([200, 210, 220, 221, 222, 230, 231, 240, 250, 251, 260, 270, 280, 300, 400, 500].includes(d.category_id)) {
+          outgoingArray.push(d)
+        }
+        if ([700, 701].includes(d.category_id)) {
+          investArray.push(d)
+        }
+      }
+      const retArray: SummaryOne[][] = [incomeArray, outgoingArray, investArray]
+      return retArray
+    }
+  }
+);
+
+
+
+if (asyncData.data.value != undefined) {
+  const incomeData = asyncData.data.value[0] as SummaryOne[];
+  const outgoingData = asyncData.data.value[1] as SummaryOne[];
+  const investData = asyncData.data.value[2] as SummaryOne[];
+  incomeList.value = incomeData
+  outgoingList.value = outgoingData
+  investList.value = investData
+
+  // sum の計算(income)
+  let incomeSumData: SummaryOne = {
+    category_id: 999,
+    category_name: "収入合計",
+    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    total: 0
+  };
+
+  for (let i: number = 0; i < 12; i++) {
+    let sum: number = 0;
+    let totalsum: number = 0;
+    for (let d of incomeData) {
+      sum += d.price[i];
+      totalsum += d.price[i];
+    }
+    incomeSumData.price[i] = sum;
+    incomeSumData.total += totalsum;
+  }
+  incomeSumList.value = incomeSumData
+
+  // sum の計算(outgoing)
+  let outgoingSumData: SummaryOne = {
+    category_id: 999,
+    category_name: "支出合計",
+    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    total: 0
+  };
+  for (let i: number = 0; i < 12; i++) {
+    let sum: number = 0;
+    let totalsum: number = 0;
+    for (let d of outgoingData) {
+      sum += d.price[i];
+      totalsum += d.price[i];
+    }
+    outgoingSumData.price[i] = sum;
+    outgoingSumData.total += totalsum;
+  }
+  outgoingSumList.value = outgoingSumData
+
+  // sum の計算(invest)
+  let investSumData: SummaryOne = {
+    category_id: 999,
+    category_name: "投資合計",
+    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    total: 0
+  };
+
+  for (let i: number = 0; i < 12; i++) {
+    let sum: number = 0;
+    let totalsum: number = 0;
+    for (let d of investData) {
+      sum += d.price[i];
+      totalsum += d.price[i];
+    }
+    investSumData.price[i] = sum;
+    investSumData.total += totalsum;
+  }
+  investSumList.value = investSumData
+
+  // 合計テーブル用の計算
+  let AllSumData: SummaryOne = {
+    category_id: 999,
+    category_name: "合計",
+    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    total: 0
+  };
+
+  for (let i: number = 0; i < 12; i++) {
+    AllSumData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i] - investSumData.price[i];
+  }
+  AllSumData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
+  AllSumList.value = AllSumData
+
+  let AllSumWithoutInvestData: SummaryOne = {
+    category_id: 999,
+    category_name: "合計(投資除く)",
+    price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    total: 0
+  };
+
+  for (let i: number = 0; i < 12; i++) {
+    AllSumWithoutInvestData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i];
+  }
+  AllSumWithoutInvestData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
+  AllSumWithoutInvestList.value = AllSumWithoutInvestData
+
+  fetched = true // データ取得後のフラグを立てる
+}
+
+</script>
+
 <template>
-  <section>
-    <h1>summary page</h1>
-    <Summary />
-  </section>
+  <h1>サマリー表示</h1>
+  <div class="container">
+    <a href="../">トップに戻る</a>
+
+    <h2>合計</h2>
+    <table class="table small bordered striped table-bordered">
+      <thead>
+        <tr>
+          <th scope="col" style="width: 3%">ID</th>
+          <th scope="col" style="width: 10%">カテゴリ名</th>
+          <th scope="col" style="width: 5%">4月</th>
+          <th scope="col" style="width: 5%">5月</th>
+          <th scope="col" style="width: 5%">6月</th>
+          <th scope="col" style="width: 5%">7月</th>
+          <th scope="col" style="width: 5%">8月</th>
+          <th scope="col" style="width: 5%">9月</th>
+          <th scope="col" style="width: 5%">10月</th>
+          <th scope="col" style="width: 5%">11月</th>
+          <th scope="col" style="width: 5%">12月</th>
+          <th scope="col" style="width: 5%">1月</th>
+          <th scope="col" style="width: 5%">2月</th>
+          <th scope="col" style="width: 5%">3月</th>
+          <th scope="col" style="width: 7%">合計</th>
+        </tr>
+      </thead>
+      <tbody>
+        <th scope="row"></th>
+        <tr v-if="fetched">
+          <td>{{ AllSumList.category_id }}</td>
+          <td>{{ AllSumList.category_name }}</td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumList.total }}</div>
+          </td>
+        </tr>
+        <tr v-if="fetched" class="table-info">
+          <td>{{ AllSumWithoutInvestList.category_id }}</td>
+          <td>{{ AllSumWithoutInvestList.category_name }}</td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ AllSumWithoutInvestList.total }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+
+    <h2>収入</h2>
+    <table class="table small bordered striped table-bordered">
+      <thead>
+        <tr>
+          <th scope="col" style="width: 3%">ID</th>
+          <th scope="col" style="width: 10%">カテゴリ名</th>
+          <th scope="col" style="width: 5%">4月</th>
+          <th scope="col" style="width: 5%">5月</th>
+          <th scope="col" style="width: 5%">6月</th>
+          <th scope="col" style="width: 5%">7月</th>
+          <th scope="col" style="width: 5%">8月</th>
+          <th scope="col" style="width: 5%">9月</th>
+          <th scope="col" style="width: 5%">10月</th>
+          <th scope="col" style="width: 5%">11月</th>
+          <th scope="col" style="width: 5%">12月</th>
+          <th scope="col" style="width: 5%">1月</th>
+          <th scope="col" style="width: 5%">2月</th>
+          <th scope="col" style="width: 5%">3月</th>
+          <th scope="col" style="width: 7%">合計</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr v-for="income in incomeList">
+          <td>{{ income.category_id }}</td>
+          <td>{{ income.category_name }}</td>
+          <td>
+            <div class="text-end">{{ income.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ income.total }}</div>
+          </td>
+        </tr>
+        <tr v-if="fetched" class="table-success">
+          <td>{{ incomeSumList.category_id }}</td>
+          <td>{{ incomeSumList.category_name }}</td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ incomeSumList.total }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+
+    <h2>支出</h2>
+    <table class="table small bordered striped table-bordered">
+      <thead>
+        <tr>
+          <th scope="col" style="width: 3%">ID</th>
+          <th scope="col" style="width: 10%">カテゴリ名</th>
+          <th scope="col" style="width: 5%">4月</th>
+          <th scope="col" style="width: 5%">5月</th>
+          <th scope="col" style="width: 5%">6月</th>
+          <th scope="col" style="width: 5%">7月</th>
+          <th scope="col" style="width: 5%">8月</th>
+          <th scope="col" style="width: 5%">9月</th>
+          <th scope="col" style="width: 5%">10月</th>
+          <th scope="col" style="width: 5%">11月</th>
+          <th scope="col" style="width: 5%">12月</th>
+          <th scope="col" style="width: 5%">1月</th>
+          <th scope="col" style="width: 5%">2月</th>
+          <th scope="col" style="width: 5%">3月</th>
+          <th scope="col" style="width: 7%">合計</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr v-for="outgoing in outgoingList">
+          <td>{{ outgoing.category_id }}</td>
+          <td>{{ outgoing.category_name }}</td>
+          <td>
+            <div class="text-end">{{ outgoing.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoing.total }}</div>
+          </td>
+        </tr>
+        <tr v-if="fetched" class="table-danger">
+          <td>{{ outgoingSumList.category_id }}</td>
+          <td>{{ outgoingSumList.category_name }}</td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ outgoingSumList.total }}</div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+
+    <h2>投資</h2>
+    <table class="table small bordered striped table-bordered">
+      <thead>
+        <tr>
+          <th scope="col" style="width: 3%">ID</th>
+          <th scope="col" style="width: 10%">カテゴリ名</th>
+          <th scope="col" style="width: 5%">4月</th>
+          <th scope="col" style="width: 5%">5月</th>
+          <th scope="col" style="width: 5%">6月</th>
+          <th scope="col" style="width: 5%">7月</th>
+          <th scope="col" style="width: 5%">8月</th>
+          <th scope="col" style="width: 5%">9月</th>
+          <th scope="col" style="width: 5%">10月</th>
+          <th scope="col" style="width: 5%">11月</th>
+          <th scope="col" style="width: 5%">12月</th>
+          <th scope="col" style="width: 5%">1月</th>
+          <th scope="col" style="width: 5%">2月</th>
+          <th scope="col" style="width: 5%">3月</th>
+          <th scope="col" style="width: 7%"">合計</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr v-for=" invest in investList">
+          <td>{{ invest.category_id }}</td>
+          <td>{{ invest.category_name }}</td>
+          <td>
+            <div class="text-end">{{ invest.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ invest.total }}</div>
+          </td>
+        </tr>
+        <tr v-if="fetched" class="table-warning">
+          <td>{{ investSumList.category_id }}</td>
+          <td>{{ investSumList.category_name }}</td>
+          <td>
+            <div class="text-end">{{ investSumList.price[0] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[1] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[2] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[3] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[4] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[5] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[6] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[7] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[8] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[9] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[10] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.price[11] }}</div>
+          </td>
+          <td>
+            <div class="text-end">{{ investSumList.total }}</div>
+          </td>
+        </tr>
+        </tbody>
+    </table>
+
+  </div>
 </template>

From 00e46562664018d8d8a083acc6e21feed9559a02 Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 01:42:18 +0900
Subject: [PATCH 2/7] Use NuxtLink and path parameter routing

---
 pages/index.vue                         |  12 +-
 pages/summary/{index.vue => [year].vue} | 150 ++++++++++++------------
 2 files changed, 86 insertions(+), 76 deletions(-)
 rename pages/summary/{index.vue => [year].vue} (74%)

diff --git a/pages/index.vue b/pages/index.vue
index d14fb61..7fb760b 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -1,3 +1,11 @@
+<script setup lang="ts">
+import type Year from './summary/[year].vue';
+
+const today = new Date();
+let thisYear = today.getFullYear();
+</script>
+
+
 <template>
   <h1>mawinter-front</h1>
   <section>
@@ -7,7 +15,9 @@
     </p>
 
     <div class="summary_link">
-      <a href="/summary">サマリー表示</a>
+      <NuxtLink v-bind:to="{name: 'summary-year', params: {year: thisYear}}">
+        サマリー表示
+      </NuxtLink>
     </div>
 
     <p text-alignment="center">
diff --git a/pages/summary/index.vue b/pages/summary/[year].vue
similarity index 74%
rename from pages/summary/index.vue
rename to pages/summary/[year].vue
index b9d56c7..5d08a50 100644
--- a/pages/summary/index.vue
+++ b/pages/summary/[year].vue
@@ -166,89 +166,89 @@ if (asyncData.data.value != undefined) {
       <tbody>
         <th scope="row"></th>
         <tr v-if="fetched">
-          <td>{{ AllSumList.category_id }}</td>
-          <td>{{ AllSumList.category_name }}</td>
+          <td>{{ AllSumList?.category_id }}</td>
+          <td>{{ AllSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ AllSumList.price[0] }}</div>
+            <div class="text-end">{{ AllSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[1] }}</div>
+            <div class="text-end">{{ AllSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[2] }}</div>
+            <div class="text-end">{{ AllSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[3] }}</div>
+            <div class="text-end">{{ AllSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[4] }}</div>
+            <div class="text-end">{{ AllSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[5] }}</div>
+            <div class="text-end">{{ AllSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[6] }}</div>
+            <div class="text-end">{{ AllSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[7] }}</div>
+            <div class="text-end">{{ AllSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[8] }}</div>
+            <div class="text-end">{{ AllSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[9] }}</div>
+            <div class="text-end">{{ AllSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[10] }}</div>
+            <div class="text-end">{{ AllSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.price[11] }}</div>
+            <div class="text-end">{{ AllSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList.total }}</div>
+            <div class="text-end">{{ AllSumList?.total }}</div>
           </td>
         </tr>
         <tr v-if="fetched" class="table-info">
-          <td>{{ AllSumWithoutInvestList.category_id }}</td>
-          <td>{{ AllSumWithoutInvestList.category_name }}</td>
+          <td>{{ AllSumWithoutInvestList?.category_id }}</td>
+          <td>{{ AllSumWithoutInvestList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[0] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[1] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[2] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[3] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[4] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[5] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[6] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[7] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[8] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[9] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[10] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.price[11] }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList.total }}</div>
+            <div class="text-end">{{ AllSumWithoutInvestList?.total }}</div>
           </td>
         </tr>
       </tbody>
@@ -320,46 +320,46 @@ if (asyncData.data.value != undefined) {
           </td>
         </tr>
         <tr v-if="fetched" class="table-success">
-          <td>{{ incomeSumList.category_id }}</td>
-          <td>{{ incomeSumList.category_name }}</td>
+          <td>{{ incomeSumList?.category_id }}</td>
+          <td>{{ incomeSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[0] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[1] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[2] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[3] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[4] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[5] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[6] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[7] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[8] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[9] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[10] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.price[11] }}</div>
+            <div class="text-end">{{ incomeSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList.total }}</div>
+            <div class="text-end">{{ incomeSumList?.total }}</div>
           </td>
         </tr>
       </tbody>
@@ -431,46 +431,46 @@ if (asyncData.data.value != undefined) {
           </td>
         </tr>
         <tr v-if="fetched" class="table-danger">
-          <td>{{ outgoingSumList.category_id }}</td>
-          <td>{{ outgoingSumList.category_name }}</td>
+          <td>{{ outgoingSumList?.category_id }}</td>
+          <td>{{ outgoingSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[0] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[1] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[2] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[3] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[4] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[5] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[6] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[7] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[8] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[9] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[10] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.price[11] }}</div>
+            <div class="text-end">{{ outgoingSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList.total }}</div>
+            <div class="text-end">{{ outgoingSumList?.total }}</div>
           </td>
         </tr>
       </tbody>
@@ -542,46 +542,46 @@ if (asyncData.data.value != undefined) {
           </td>
         </tr>
         <tr v-if="fetched" class="table-warning">
-          <td>{{ investSumList.category_id }}</td>
-          <td>{{ investSumList.category_name }}</td>
+          <td>{{ investSumList?.category_id }}</td>
+          <td>{{ investSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ investSumList.price[0] }}</div>
+            <div class="text-end">{{ investSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[1] }}</div>
+            <div class="text-end">{{ investSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[2] }}</div>
+            <div class="text-end">{{ investSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[3] }}</div>
+            <div class="text-end">{{ investSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[4] }}</div>
+            <div class="text-end">{{ investSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[5] }}</div>
+            <div class="text-end">{{ investSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[6] }}</div>
+            <div class="text-end">{{ investSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[7] }}</div>
+            <div class="text-end">{{ investSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[8] }}</div>
+            <div class="text-end">{{ investSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[9] }}</div>
+            <div class="text-end">{{ investSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[10] }}</div>
+            <div class="text-end">{{ investSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.price[11] }}</div>
+            <div class="text-end">{{ investSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList.total }}</div>
+            <div class="text-end">{{ investSumList?.total }}</div>
           </td>
         </tr>
         </tbody>

From 58a2238a9f3d5af0a9888262e9fbb6e59f381c08 Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Mon, 9 Sep 2024 17:15:04 +0000
Subject: [PATCH 3/7] Use ESlint

---
 components/History.vue    |   40 +-
 components/PostRecord.vue |   48 +-
 eslint.config.mjs         |   23 +
 interfaces.ts             |   28 +-
 nuxt.config.ts            |    6 +-
 package-lock.json         | 2627 ++++++++++++++++++++++++++++++++-----
 package.json              |   11 +-
 pages/index.vue           |   16 +-
 pages/summary/[year].vue  |  444 +++----
 9 files changed, 2623 insertions(+), 620 deletions(-)
 create mode 100644 eslint.config.mjs

diff --git a/components/History.vue b/components/History.vue
index 8636e1a..0a983f5 100644
--- a/components/History.vue
+++ b/components/History.vue
@@ -1,21 +1,21 @@
-<script setup lang="ts">
-import type { Record } from "@/interfaces";
-const config = useRuntimeConfig(); // nuxt.config.ts に書いてあるコンフィグを読み出す
+<script setup lang='ts'>
+import type { Record } from '@/interfaces'
+const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
 const recordList = ref<Record[]>()
 const asyncData = await useFetch(
-  "/api/history",
+  '/api/history',
   {
     key: `/api/history`,
   }
-);
+)
 
 
-const data = asyncData.data.value as Record[];
+const data = asyncData.data.value as Record[]
 
 // fetchデータを整形
 if (data != undefined) { // 取得済の場合のみ
   for (let d of data) {
-    d.datetime = d.datetime.slice(0, 19); // 2023-09-23T00:00:00+09:00 -> 2023-09-23T00:00:00
+    d.datetime = d.datetime.slice(0, 19) // 2023-09-23T00:00:00+09:00 -> 2023-09-23T00:00:00
   }
 }
 
@@ -23,29 +23,29 @@ if (data != undefined) { // 取得済の場合のみ
 recordList.value = data
 
 async function showDeleteDialog(id: number): Promise<void> {
-  const userResponse: boolean = confirm("このデータを削除しますか");
+  const userResponse: boolean = confirm('このデータを削除しますか')
   if (userResponse == true) {
-    console.log('delete: id=' + id);
+    console.log('delete: id=' + id)
     const asyncDataBtn = await useAsyncData(
       `record`,
       (): Promise<any> => {
-        const param = { 'id': id };
-        const paramStr = "?id=" + param['id'];
-        const localurl = "/api/deleteRecord" + paramStr
-        const response = $fetch(localurl);
-        return response;
+        const param = { 'id': id }
+        const paramStr = '?id=' + param['id']
+        const localurl = '/api/deleteRecord' + paramStr
+        const response = $fetch(localurl)
+        return response
       }
-    );
+    )
     location.reload()
   }
 
-};
+}
 
 </script>
 
 <template>
-  <div class="container-sm">
-    <table class="table table-striped table-sm">
+  <div class='container-sm'>
+    <table class='table table-striped table-sm'>
       <thead>
         <tr>
           <th>ID</th>
@@ -57,13 +57,13 @@ async function showDeleteDialog(id: number): Promise<void> {
         </tr>
       </thead>
       <tbody>
-        <tr v-for="record in recordList">
+        <tr v-for='record in recordList'>
           <td>{{ record.id }}</td>
           <td>{{ record.category_name }}</td>
           <td>{{ record.price }}</td>
           <td>{{ record.datetime }}</td>
           <td>{{ record.memo }}</td>
-          <td><button class="btn btn-secondary" @click="showDeleteDialog(record.id)">削除</button></td>
+          <td><button class='btn btn-secondary' @click='showDeleteDialog(record.id)'>削除</button></td>
         </tr>
       </tbody>
     </table>
diff --git a/components/PostRecord.vue b/components/PostRecord.vue
index fd33a4a..64785d1 100644
--- a/components/PostRecord.vue
+++ b/components/PostRecord.vue
@@ -1,24 +1,24 @@
-<script setup lang="ts">
-import type { Category } from "@/interfaces";
-const config = useRuntimeConfig(); // nuxt.config.ts に書いてあるコンフィグを読み出す
+<script setup lang='ts'>
+import type { Category } from '@/interfaces'
+const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
 const selector = ref<any>()
 const categoryList = ref<Category[]>()
 const asyncData = await useFetch(
-  "/api/getCategories",
+  '/api/getCategories',
   {
     key: `/api/getCategories`,
   }
-);
+)
 
-const data = asyncData.data.value as Category[];
+const data = asyncData.data.value as Category[]
 
 // category 加工
 if (data != undefined) { // 取得済の場合のみ
   for (let d of data) {
     // 100, category_name -> 100:category_name という表示に
     // ただし加工済の場合は skip
-    if (d.category_name[3] != ":") {
-      d.category_name = d.category_id + ":" + d.category_name
+    if (d.category_name[3] != ':') {
+      d.category_name = d.category_id + ':' + d.category_name
     }
   }
 }
@@ -33,36 +33,36 @@ const postButton = async (): Promise<void> => {
     `record`,
     (): Promise<any> => {
       const send_category_id = selector.value.slice(0, 3) // 210-食費→210
-      const param = { 'price': priceBox.value, 'category_id': send_category_id }
-      const paramStr = "?price=" + param['price'] + "&category_id=" + param['category_id']
-      const localurl = "/api/postRecord" + paramStr
-      const response = $fetch(localurl);
-      return response;
+      const param = { price: priceBox.value, category_id: send_category_id }
+      const paramStr = '?price=' + param['price'] + '&category_id=' + param['category_id']
+      const localurl = '/api/postRecord' + paramStr
+      const response = $fetch(localurl)
+      return response
     }
-  );
+  )
   location.reload()
-};
+}
 
 </script>
 
 <template>
-  <div class="container text-center">
-    <div class="row justify-content-center">
-      <div class="col-2">
-        <select v-model="selector" class="form-select">
-          <option v-for="category in categoryList" :key="category.category_id">
+  <div class='container text-center'>
+    <div class='row justify-content-center'>
+      <div class='col-2'>
+        <select v-model='selector' class='form-select'>
+          <option v-for='category in categoryList' :key='category.category_id'>
             {{ category.category_name }}
           </option>
         </select>
       </div>
 
-      <div class="col-2 mb-3">
-        <input v-model="priceBox" type="number" placeholder="Value" />
+      <div class='col-2 mb-3'>
+        <input v-model='priceBox' type='number' placeholder='Value' />
       </div>
     </div>
 
-    <div class="d-grid col-2 mx-auto">
-      <button class="btn btn-primary" @click="postButton" name="postButton" type="submit">Post</button>
+    <div class='d-grid col-2 mx-auto'>
+      <button class='btn btn-primary' @click='postButton' name='postButton' type='submit'>Post</button>
     </div>
 
   </div>
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..9d009b7
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,23 @@
+import withNuxt from './.nuxt/eslint.config.mjs'
+import stylistic from '@stylistic/eslint-plugin'
+
+export default withNuxt(
+  {
+    files: ['**/*.vue'],
+    rules: {
+      'vue/require-v-for-key': 'error',
+      'vue/no-use-v-if-with-v-for': 'error',
+    },
+  },
+  {
+    files: ['**/*.vue', '**/*.ts'],
+    rules: {
+      'no-console': 'error',
+      '@typescript-eslint/no-explicit-any': 'error',
+    },
+  },
+  stylistic.configs.customize({
+    indent: 2, // インデントはスペース2
+    semi: false, // セミコロンは不要
+  }),
+)
diff --git a/interfaces.ts b/interfaces.ts
index 515e1fb..1ac1200 100644
--- a/interfaces.ts
+++ b/interfaces.ts
@@ -1,22 +1,22 @@
 export interface Record {
-    id: number;
-    category_id: number;
-    category_name: string;
-    datetime: string;
-    from: string;
-    type: string;
-    price: number;
-    memo: string;
+  id: number
+  category_id: number
+  category_name: string
+  datetime: string
+  from: string
+  type: string
+  price: number
+  memo: string
 }
 
 export interface Category {
-    category_id: number;
-    category_name: string;
+  category_id: number
+  category_name: string
 }
 
 export interface SummaryOne {
-    category_id: number;
-    category_name: string;
-    price: number[]; // 4,5,6,7,8,9,10,11,12,1,2,3月の額
-    total: number;
+  category_id: number
+  category_name: string
+  price: number[] // 4,5,6,7,8,9,10,11,12,1,2,3月の額
+  total: number
 }
diff --git a/nuxt.config.ts b/nuxt.config.ts
index e1ea45d..affec5e 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -10,5 +10,9 @@ export default defineNuxtConfig({
     public: { // 外部から取得するにはpublic が必要
       mawinterApi: "http://mawinter-api", // .env の NUXT_PUBLIC_API_BASE_ENDPOINT から取得
     }
-  }
+  },
+  modules: [
+    '@nuxt/eslint'
+  ],
+  
 })
diff --git a/package-lock.json b/package-lock.json
index 152f892..6dfd0fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,10 +10,13 @@
         "@typescript-eslint/eslint-plugin": "^8.0.1",
         "@typescript-eslint/parser": "^8.0.1",
         "bootstrap": "^5.3.0",
-        "eslint": "^9.9.0",
         "eslint-plugin-react": "^7.35.0",
         "nuxt": "^3.12.4",
         "vue": "latest"
+      },
+      "devDependencies": {
+        "@nuxt/eslint": "^0.5.6",
+        "eslint": "^9.10.0"
       }
     },
     "node_modules/@ampproject/remapping": {
@@ -38,6 +41,24 @@
         "url": "https://github.com/sponsors/antfu"
       }
     },
+    "node_modules/@apidevtools/json-schema-ref-parser": {
+      "version": "11.7.0",
+      "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz",
+      "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jsdevtools/ono": "^7.1.3",
+        "@types/json-schema": "^7.0.15",
+        "js-yaml": "^4.1.0"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/philsturgeon"
+      }
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.24.7",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
@@ -546,6 +567,21 @@
         "node": ">=10.0.0"
       }
     },
+    "node_modules/@es-joy/jsdoccomment": {
+      "version": "0.48.0",
+      "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.48.0.tgz",
+      "integrity": "sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "comment-parser": "1.4.1",
+        "esquery": "^1.6.0",
+        "jsdoc-type-pratt-parser": "~4.1.0"
+      },
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "node_modules/@esbuild/aix-ppc64": {
       "version": "0.23.0",
       "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz",
@@ -954,10 +990,21 @@
         "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
       }
     },
+    "node_modules/@eslint/compat": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.1.tgz",
+      "integrity": "sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
     "node_modules/@eslint/config-array": {
       "version": "0.17.1",
       "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
       "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
+      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@eslint/object-schema": "^2.1.4",
@@ -972,6 +1019,7 @@
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "balanced-match": "^1.0.0",
@@ -982,6 +1030,7 @@
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
       "license": "ISC",
       "dependencies": {
         "brace-expansion": "^1.1.7"
@@ -990,160 +1039,774 @@
         "node": "*"
       }
     },
-    "node_modules/@eslint/eslintrc": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
-      "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
-      "license": "MIT",
+    "node_modules/@eslint/config-inspector": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/@eslint/config-inspector/-/config-inspector-0.5.4.tgz",
+      "integrity": "sha512-WB/U/B6HdRiIt/CfbcqqFp7Svz+3INLtnGcuMT2hnU39S3cb9JGGkvB1T6lbIlDoQ9VRnhc4riIFFoicGRZ2mw==",
+      "dev": true,
+      "license": "Apache-2.0",
       "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^10.0.1",
-        "globals": "^14.0.0",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^4.1.0",
-        "minimatch": "^3.1.2",
-        "strip-json-comments": "^3.1.1"
+        "@eslint/config-array": "^0.17.1",
+        "@voxpelli/config-array-find-files": "^0.1.2",
+        "bundle-require": "^5.0.0",
+        "cac": "^6.7.14",
+        "chokidar": "^3.6.0",
+        "esbuild": "^0.21.5",
+        "fast-glob": "^3.3.2",
+        "find-up": "^7.0.0",
+        "get-port-please": "^3.1.2",
+        "h3": "^1.12.0",
+        "minimatch": "^9.0.5",
+        "mlly": "^1.7.1",
+        "mrmime": "^2.0.0",
+        "open": "^10.1.0",
+        "picocolors": "^1.0.1",
+        "ws": "^8.18.0"
       },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      "bin": {
+        "config-inspector": "bin.mjs",
+        "eslint-config-inspector": "bin.mjs"
       },
       "funding": {
         "url": "https://opencollective.com/eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.50.0 || ^9.0.0"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
-      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/aix-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
       "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
       "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=12"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/android-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
       "engines": {
-        "node": "*"
+        "node": ">=12"
       }
     },
-    "node_modules/@eslint/js": {
-      "version": "9.9.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz",
-      "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/android-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
       "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
       "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+        "node": ">=12"
       }
     },
-    "node_modules/@eslint/object-schema": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
-      "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
-      "license": "Apache-2.0",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/android-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
       "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+        "node": ">=12"
       }
     },
-    "node_modules/@fastify/busboy": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
-      "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/darwin-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
       "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
       "engines": {
-        "node": ">=14"
+        "node": ">=12"
       }
     },
-    "node_modules/@humanwhocodes/module-importer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "license": "Apache-2.0",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/darwin-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
       "engines": {
-        "node": ">=12.22"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
+        "node": ">=12"
       }
     },
-    "node_modules/@humanwhocodes/retry": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
-      "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
-      "license": "Apache-2.0",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
       "engines": {
-        "node": ">=18.18"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
+        "node": ">=12"
       }
     },
-    "node_modules/@ioredis/commands": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
-      "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==",
-      "license": "MIT"
-    },
-    "node_modules/@isaacs/cliui": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
-      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^5.1.2",
-        "string-width-cjs": "npm:string-width@^4.2.0",
-        "strip-ansi": "^7.0.1",
-        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
-        "wrap-ansi": "^8.1.0",
-        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
-      },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/freebsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
       "engines": {
         "node": ">=12"
       }
     },
-    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-arm": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
       "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
         "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
       }
     },
-    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
-      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
       "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
         "node": ">=12"
-      },
-      "funding": {
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-loong64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-mips64el": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-ppc64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-riscv64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-s390x": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/linux-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/netbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/openbsd-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/sunos-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/win32-arm64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/win32-ia32": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/@esbuild/win32-x64": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/define-lazy-prop": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+      "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/esbuild": {
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.21.5",
+        "@esbuild/android-arm": "0.21.5",
+        "@esbuild/android-arm64": "0.21.5",
+        "@esbuild/android-x64": "0.21.5",
+        "@esbuild/darwin-arm64": "0.21.5",
+        "@esbuild/darwin-x64": "0.21.5",
+        "@esbuild/freebsd-arm64": "0.21.5",
+        "@esbuild/freebsd-x64": "0.21.5",
+        "@esbuild/linux-arm": "0.21.5",
+        "@esbuild/linux-arm64": "0.21.5",
+        "@esbuild/linux-ia32": "0.21.5",
+        "@esbuild/linux-loong64": "0.21.5",
+        "@esbuild/linux-mips64el": "0.21.5",
+        "@esbuild/linux-ppc64": "0.21.5",
+        "@esbuild/linux-riscv64": "0.21.5",
+        "@esbuild/linux-s390x": "0.21.5",
+        "@esbuild/linux-x64": "0.21.5",
+        "@esbuild/netbsd-x64": "0.21.5",
+        "@esbuild/openbsd-x64": "0.21.5",
+        "@esbuild/sunos-x64": "0.21.5",
+        "@esbuild/win32-arm64": "0.21.5",
+        "@esbuild/win32-ia32": "0.21.5",
+        "@esbuild/win32-x64": "0.21.5"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/find-up": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
+      "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^7.2.0",
+        "path-exists": "^5.0.0",
+        "unicorn-magic": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/locate-path": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+      "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^6.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/open": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
+      "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "default-browser": "^5.2.1",
+        "define-lazy-prop": "^3.0.0",
+        "is-inside-container": "^1.0.0",
+        "is-wsl": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/p-limit": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+      "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "yocto-queue": "^1.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/p-locate": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+      "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-limit": "^4.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/path-exists": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+      "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      }
+    },
+    "node_modules/@eslint/config-inspector/node_modules/yocto-queue": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
+      "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/eslintrc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
+      "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "^6.12.4",
+        "debug": "^4.3.2",
+        "espree": "^10.0.1",
+        "globals": "^14.0.0",
+        "ignore": "^5.2.0",
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
+        "strip-json-comments": "^3.1.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/globals": {
+      "version": "14.0.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/@eslint/js": {
+      "version": "9.10.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
+      "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
+      "license": "MIT",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
+    "node_modules/@eslint/object-schema": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
+      "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
+    "node_modules/@eslint/plugin-kit": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
+      "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "levn": "^0.4.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
+    "node_modules/@fastify/busboy": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
+      "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@humanwhocodes/retry": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
+      "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=18.18"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@ioredis/commands": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
+      "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==",
+      "license": "MIT"
+    },
+    "node_modules/@isaacs/cliui": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
@@ -1260,6 +1923,13 @@
         "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
+    "node_modules/@jsdevtools/ono": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+      "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@kwsites/file-exists": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
@@ -1348,112 +2018,362 @@
       "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
       "license": "MIT",
       "engines": {
-        "node": ">= 8"
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nuxt/devalue": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz",
+      "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==",
+      "license": "MIT"
+    },
+    "node_modules/@nuxt/devtools": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/@nuxt/devtools/-/devtools-1.3.9.tgz",
+      "integrity": "sha512-tFKlbUPgSXw4tyD8xpztQtJeVn3egdKbFCV0xc92FbfGbclAyaa3XhKA2tMWXEGZQpykAWMRNrGWN24FtXFA6Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@antfu/utils": "^0.7.10",
+        "@nuxt/devtools-kit": "1.3.9",
+        "@nuxt/devtools-wizard": "1.3.9",
+        "@nuxt/kit": "^3.12.2",
+        "@vue/devtools-core": "7.3.3",
+        "@vue/devtools-kit": "7.3.3",
+        "birpc": "^0.2.17",
+        "consola": "^3.2.3",
+        "cronstrue": "^2.50.0",
+        "destr": "^2.0.3",
+        "error-stack-parser-es": "^0.1.4",
+        "execa": "^7.2.0",
+        "fast-glob": "^3.3.2",
+        "fast-npm-meta": "^0.1.1",
+        "flatted": "^3.3.1",
+        "get-port-please": "^3.1.2",
+        "hookable": "^5.5.3",
+        "image-meta": "^0.2.0",
+        "is-installed-globally": "^1.0.0",
+        "launch-editor": "^2.8.0",
+        "local-pkg": "^0.5.0",
+        "magicast": "^0.3.4",
+        "nypm": "^0.3.9",
+        "ohash": "^1.1.3",
+        "pathe": "^1.1.2",
+        "perfect-debounce": "^1.0.0",
+        "pkg-types": "^1.1.2",
+        "rc9": "^2.1.2",
+        "scule": "^1.3.0",
+        "semver": "^7.6.2",
+        "simple-git": "^3.25.0",
+        "sirv": "^2.0.4",
+        "unimport": "^3.7.2",
+        "vite-plugin-inspect": "^0.8.4",
+        "vite-plugin-vue-inspector": "^5.1.2",
+        "which": "^3.0.1",
+        "ws": "^8.17.1"
+      },
+      "bin": {
+        "devtools": "cli.mjs"
+      },
+      "peerDependencies": {
+        "vite": "*"
+      }
+    },
+    "node_modules/@nuxt/devtools-kit": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-1.3.9.tgz",
+      "integrity": "sha512-tgr/F+4BbI53/JxgaXl3cuV9dMuCXMsd4GEXN+JqtCdAkDbH3wL79GGWx0/6I9acGzRsB6UZ1H6U96nfgcIrAw==",
+      "license": "MIT",
+      "dependencies": {
+        "@nuxt/kit": "^3.12.2",
+        "@nuxt/schema": "^3.12.3",
+        "execa": "^7.2.0"
+      },
+      "peerDependencies": {
+        "vite": "*"
+      }
+    },
+    "node_modules/@nuxt/devtools-wizard": {
+      "version": "1.3.9",
+      "resolved": "https://registry.npmjs.org/@nuxt/devtools-wizard/-/devtools-wizard-1.3.9.tgz",
+      "integrity": "sha512-WMgwWWuyng+Y6k7sfBI95wYnec8TPFkuYbHHOlYQgqE9dAewPisSbEm3WkB7p/W9UqxpN8mvKN5qUg4sTmEpgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "consola": "^3.2.3",
+        "diff": "^5.2.0",
+        "execa": "^7.2.0",
+        "global-directory": "^4.0.1",
+        "magicast": "^0.3.4",
+        "pathe": "^1.1.2",
+        "pkg-types": "^1.1.2",
+        "prompts": "^2.4.2",
+        "rc9": "^2.1.2",
+        "semver": "^7.6.2"
+      },
+      "bin": {
+        "devtools-wizard": "cli.mjs"
+      }
+    },
+    "node_modules/@nuxt/eslint": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/@nuxt/eslint/-/eslint-0.5.6.tgz",
+      "integrity": "sha512-kW9+vyFBSSCYY1oaHhtMZPoZUlD2fLh1j6t/giCw6M/IiPWsMs2Hfzm/hqrfP/XNw9pvvtATAxRB9eF76IStwA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint/config-inspector": "^0.5.4",
+        "@nuxt/devtools-kit": "^1.4.1",
+        "@nuxt/eslint-config": "0.5.6",
+        "@nuxt/eslint-plugin": "0.5.6",
+        "@nuxt/kit": "^3.13.1",
+        "chokidar": "^3.6.0",
+        "eslint-flat-config-utils": "^0.3.1",
+        "eslint-typegen": "^0.3.1",
+        "find-up": "^7.0.0",
+        "get-port-please": "^3.1.2",
+        "mlly": "^1.7.1",
+        "pathe": "^1.1.2",
+        "unimport": "^3.11.1"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "eslint-webpack-plugin": "^4.1.0",
+        "vite-plugin-eslint2": "^4.4.0"
+      },
+      "peerDependenciesMeta": {
+        "eslint-webpack-plugin": {
+          "optional": true
+        },
+        "vite-plugin-eslint2": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@nuxt/eslint-config": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/@nuxt/eslint-config/-/eslint-config-0.5.6.tgz",
+      "integrity": "sha512-2kse94xvLW9SeENOAkGaksfff7vwRWsekbDsRjVoW2h3/95wRHWSenObUbGaW6Jr3D0o7DzyEIsaOvnWHZXvDg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint/js": "^9.9.1",
+        "@nuxt/eslint-plugin": "0.5.6",
+        "@stylistic/eslint-plugin": "^2.7.2",
+        "@typescript-eslint/eslint-plugin": "^8.4.0",
+        "@typescript-eslint/parser": "^8.4.0",
+        "eslint-config-flat-gitignore": "^0.3.0",
+        "eslint-flat-config-utils": "^0.3.1",
+        "eslint-plugin-import-x": "^4.2.1",
+        "eslint-plugin-jsdoc": "^50.2.2",
+        "eslint-plugin-regexp": "^2.6.0",
+        "eslint-plugin-unicorn": "^55.0.0",
+        "eslint-plugin-vue": "^9.28.0",
+        "globals": "^15.9.0",
+        "local-pkg": "^0.5.0",
+        "pathe": "^1.1.2",
+        "vue-eslint-parser": "^9.4.3"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0"
+      }
+    },
+    "node_modules/@nuxt/eslint-config/node_modules/globals": {
+      "version": "15.9.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+      "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@nuxt/eslint-plugin": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/@nuxt/eslint-plugin/-/eslint-plugin-0.5.6.tgz",
+      "integrity": "sha512-WgTcC4pGjbd8NCZpTYOOWnUWEncYV/rWJFeL5gyCXT+t36qkmWESrPLQ2NqBNaFLhoz6b/BFuOvMPVKg/q1T9g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/types": "^8.4.0",
+        "@typescript-eslint/utils": "^8.4.0"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0"
+      }
+    },
+    "node_modules/@nuxt/eslint/node_modules/@nuxt/devtools-kit": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-1.4.1.tgz",
+      "integrity": "sha512-6h7T9B0tSZVap13/hf7prEAgIzraj/kyux6/Iif455Trew96jHIFCCboBApUMastYEuCo3l17tgZKe0HW+jrtA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nuxt/kit": "^3.13.0",
+        "@nuxt/schema": "^3.13.0",
+        "execa": "^7.2.0"
+      },
+      "peerDependencies": {
+        "vite": "*"
+      }
+    },
+    "node_modules/@nuxt/eslint/node_modules/@nuxt/kit": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.13.1.tgz",
+      "integrity": "sha512-FkUL349lp/3nVfTIyws4UDJ3d2jyv5Pk1DC1HQUCOkSloYYMdbRcQAUcb4fe2TCLNWvHM+FhU8jnzGTzjALZYA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nuxt/schema": "3.13.1",
+        "c12": "^1.11.2",
+        "consola": "^3.2.3",
+        "defu": "^6.1.4",
+        "destr": "^2.0.3",
+        "globby": "^14.0.2",
+        "hash-sum": "^2.0.0",
+        "ignore": "^5.3.2",
+        "jiti": "^1.21.6",
+        "klona": "^2.0.6",
+        "knitwork": "^1.1.0",
+        "mlly": "^1.7.1",
+        "pathe": "^1.1.2",
+        "pkg-types": "^1.2.0",
+        "scule": "^1.3.0",
+        "semver": "^7.6.3",
+        "ufo": "^1.5.4",
+        "unctx": "^2.3.1",
+        "unimport": "^3.11.1",
+        "untyped": "^1.4.2"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.10.0"
+      }
+    },
+    "node_modules/@nuxt/eslint/node_modules/@nuxt/schema": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-3.13.1.tgz",
+      "integrity": "sha512-ishbhzVGspjshG9AG0hYnKYY6LWXzCtua7OXV7C/DQ2yA7rRcy1xHpzKZUDbIRyxCHHCAcBd8jfHEUmEuhEPrA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "compatx": "^0.1.8",
+        "consola": "^3.2.3",
+        "defu": "^6.1.4",
+        "hookable": "^5.5.3",
+        "pathe": "^1.1.2",
+        "pkg-types": "^1.2.0",
+        "scule": "^1.3.0",
+        "std-env": "^3.7.0",
+        "ufo": "^1.5.4",
+        "uncrypto": "^0.1.3",
+        "unimport": "^3.11.1",
+        "untyped": "^1.4.2"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.10.0"
+      }
+    },
+    "node_modules/@nuxt/eslint/node_modules/find-up": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
+      "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^7.2.0",
+        "path-exists": "^5.0.0",
+        "unicorn-magic": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@nuxt/eslint/node_modules/locate-path": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+      "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^6.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+    "node_modules/@nuxt/eslint/node_modules/p-limit": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+      "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
+        "yocto-queue": "^1.0.0"
       },
       "engines": {
-        "node": ">= 8"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@nuxt/devalue": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@nuxt/devalue/-/devalue-2.0.2.tgz",
-      "integrity": "sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==",
-      "license": "MIT"
-    },
-    "node_modules/@nuxt/devtools": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/@nuxt/devtools/-/devtools-1.3.9.tgz",
-      "integrity": "sha512-tFKlbUPgSXw4tyD8xpztQtJeVn3egdKbFCV0xc92FbfGbclAyaa3XhKA2tMWXEGZQpykAWMRNrGWN24FtXFA6Q==",
+    "node_modules/@nuxt/eslint/node_modules/p-locate": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+      "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@antfu/utils": "^0.7.10",
-        "@nuxt/devtools-kit": "1.3.9",
-        "@nuxt/devtools-wizard": "1.3.9",
-        "@nuxt/kit": "^3.12.2",
-        "@vue/devtools-core": "7.3.3",
-        "@vue/devtools-kit": "7.3.3",
-        "birpc": "^0.2.17",
-        "consola": "^3.2.3",
-        "cronstrue": "^2.50.0",
-        "destr": "^2.0.3",
-        "error-stack-parser-es": "^0.1.4",
-        "execa": "^7.2.0",
-        "fast-glob": "^3.3.2",
-        "fast-npm-meta": "^0.1.1",
-        "flatted": "^3.3.1",
-        "get-port-please": "^3.1.2",
-        "hookable": "^5.5.3",
-        "image-meta": "^0.2.0",
-        "is-installed-globally": "^1.0.0",
-        "launch-editor": "^2.8.0",
-        "local-pkg": "^0.5.0",
-        "magicast": "^0.3.4",
-        "nypm": "^0.3.9",
-        "ohash": "^1.1.3",
-        "pathe": "^1.1.2",
-        "perfect-debounce": "^1.0.0",
-        "pkg-types": "^1.1.2",
-        "rc9": "^2.1.2",
-        "scule": "^1.3.0",
-        "semver": "^7.6.2",
-        "simple-git": "^3.25.0",
-        "sirv": "^2.0.4",
-        "unimport": "^3.7.2",
-        "vite-plugin-inspect": "^0.8.4",
-        "vite-plugin-vue-inspector": "^5.1.2",
-        "which": "^3.0.1",
-        "ws": "^8.17.1"
+        "p-limit": "^4.0.0"
       },
-      "bin": {
-        "devtools": "cli.mjs"
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
-      "peerDependencies": {
-        "vite": "*"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@nuxt/devtools-kit": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/@nuxt/devtools-kit/-/devtools-kit-1.3.9.tgz",
-      "integrity": "sha512-tgr/F+4BbI53/JxgaXl3cuV9dMuCXMsd4GEXN+JqtCdAkDbH3wL79GGWx0/6I9acGzRsB6UZ1H6U96nfgcIrAw==",
+    "node_modules/@nuxt/eslint/node_modules/path-exists": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+      "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+      "dev": true,
       "license": "MIT",
-      "dependencies": {
-        "@nuxt/kit": "^3.12.2",
-        "@nuxt/schema": "^3.12.3",
-        "execa": "^7.2.0"
-      },
-      "peerDependencies": {
-        "vite": "*"
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
     },
-    "node_modules/@nuxt/devtools-wizard": {
-      "version": "1.3.9",
-      "resolved": "https://registry.npmjs.org/@nuxt/devtools-wizard/-/devtools-wizard-1.3.9.tgz",
-      "integrity": "sha512-WMgwWWuyng+Y6k7sfBI95wYnec8TPFkuYbHHOlYQgqE9dAewPisSbEm3WkB7p/W9UqxpN8mvKN5qUg4sTmEpgQ==",
+    "node_modules/@nuxt/eslint/node_modules/yocto-queue": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
+      "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
+      "dev": true,
       "license": "MIT",
-      "dependencies": {
-        "consola": "^3.2.3",
-        "diff": "^5.2.0",
-        "execa": "^7.2.0",
-        "global-directory": "^4.0.1",
-        "magicast": "^0.3.4",
-        "pathe": "^1.1.2",
-        "pkg-types": "^1.1.2",
-        "prompts": "^2.4.2",
-        "rc9": "^2.1.2",
-        "semver": "^7.6.2"
+      "engines": {
+        "node": ">=12.20"
       },
-      "bin": {
-        "devtools-wizard": "cli.mjs"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/@nuxt/kit": {
@@ -1906,6 +2826,19 @@
         "node": ">=14"
       }
     },
+    "node_modules/@pkgr/core": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
+      "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/unts"
+      }
+    },
     "node_modules/@polka/url": {
       "version": "1.0.0-next.25",
       "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz",
@@ -2350,6 +3283,52 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/@stylistic/eslint-plugin": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.8.0.tgz",
+      "integrity": "sha512-Ufvk7hP+bf+pD35R/QfunF793XlSRIC7USr3/EdgduK9j13i2JjmsM0LUz3/foS+jDYp2fzyWZA9N44CPur0Ow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/utils": "^8.4.0",
+        "eslint-visitor-keys": "^4.0.0",
+        "espree": "^10.1.0",
+        "estraverse": "^5.3.0",
+        "picomatch": "^4.0.2"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "peerDependencies": {
+        "eslint": ">=8.40.0"
+      }
+    },
+    "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+      "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
     "node_modules/@trysound/sax": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@@ -2359,6 +3338,17 @@
         "node": ">=10.13.0"
       }
     },
+    "node_modules/@types/eslint": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+      "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
     "node_modules/@types/estree": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@@ -2374,6 +3364,13 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@types/node": {
       "version": "22.2.0",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz",
@@ -2383,6 +3380,13 @@
         "undici-types": "~6.13.0"
       }
     },
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@types/resolve": {
       "version": "1.20.2",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@@ -2390,16 +3394,16 @@
       "license": "MIT"
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz",
-      "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.4.0.tgz",
+      "integrity": "sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==",
       "license": "MIT",
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "8.0.1",
-        "@typescript-eslint/type-utils": "8.0.1",
-        "@typescript-eslint/utils": "8.0.1",
-        "@typescript-eslint/visitor-keys": "8.0.1",
+        "@typescript-eslint/scope-manager": "8.4.0",
+        "@typescript-eslint/type-utils": "8.4.0",
+        "@typescript-eslint/utils": "8.4.0",
+        "@typescript-eslint/visitor-keys": "8.4.0",
         "graphemer": "^1.4.0",
         "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
@@ -2423,15 +3427,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz",
-      "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.4.0.tgz",
+      "integrity": "sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==",
       "license": "BSD-2-Clause",
       "dependencies": {
-        "@typescript-eslint/scope-manager": "8.0.1",
-        "@typescript-eslint/types": "8.0.1",
-        "@typescript-eslint/typescript-estree": "8.0.1",
-        "@typescript-eslint/visitor-keys": "8.0.1",
+        "@typescript-eslint/scope-manager": "8.4.0",
+        "@typescript-eslint/types": "8.4.0",
+        "@typescript-eslint/typescript-estree": "8.4.0",
+        "@typescript-eslint/visitor-keys": "8.4.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -2451,13 +3455,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz",
-      "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz",
+      "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==",
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.0.1",
-        "@typescript-eslint/visitor-keys": "8.0.1"
+        "@typescript-eslint/types": "8.4.0",
+        "@typescript-eslint/visitor-keys": "8.4.0"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2468,13 +3472,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz",
-      "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.4.0.tgz",
+      "integrity": "sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==",
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "8.0.1",
-        "@typescript-eslint/utils": "8.0.1",
+        "@typescript-eslint/typescript-estree": "8.4.0",
+        "@typescript-eslint/utils": "8.4.0",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.3.0"
       },
@@ -2492,9 +3496,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz",
-      "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz",
+      "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==",
       "license": "MIT",
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2505,15 +3509,15 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz",
-      "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz",
+      "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==",
       "license": "BSD-2-Clause",
       "dependencies": {
-        "@typescript-eslint/types": "8.0.1",
-        "@typescript-eslint/visitor-keys": "8.0.1",
+        "@typescript-eslint/types": "8.4.0",
+        "@typescript-eslint/visitor-keys": "8.4.0",
         "debug": "^4.3.4",
-        "globby": "^11.1.0",
+        "fast-glob": "^3.3.2",
         "is-glob": "^4.0.3",
         "minimatch": "^9.0.4",
         "semver": "^7.6.0",
@@ -2532,26 +3536,6 @@
         }
       }
     },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
-      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
-      "license": "MIT",
-      "dependencies": {
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.2.9",
-        "ignore": "^5.2.0",
-        "merge2": "^1.4.1",
-        "slash": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
       "version": "9.0.5",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -2567,25 +3551,16 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/@typescript-eslint/utils": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz",
-      "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz",
+      "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==",
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@typescript-eslint/scope-manager": "8.0.1",
-        "@typescript-eslint/types": "8.0.1",
-        "@typescript-eslint/typescript-estree": "8.0.1"
+        "@typescript-eslint/scope-manager": "8.4.0",
+        "@typescript-eslint/types": "8.4.0",
+        "@typescript-eslint/typescript-estree": "8.4.0"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2599,12 +3574,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz",
-      "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz",
+      "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==",
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.0.1",
+        "@typescript-eslint/types": "8.4.0",
         "eslint-visitor-keys": "^3.4.3"
       },
       "engines": {
@@ -2803,6 +3778,60 @@
         "vue": "^3.0.0"
       }
     },
+    "node_modules/@voxpelli/config-array-find-files": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/@voxpelli/config-array-find-files/-/config-array-find-files-0.1.2.tgz",
+      "integrity": "sha512-jOva73R+0Nc5/pyS/piBSjQzO4EehME7rPSkBpPC9PYSta+yj3OpF14v0m0HLLYLVNuyHbBjQh5QvGIZwTH2eA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.walk": "^2.0.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "peerDependencies": {
+        "@eslint/config-array": ">=0.16.0"
+      }
+    },
+    "node_modules/@voxpelli/config-array-find-files/node_modules/@nodelib/fs.scandir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-3.0.0.tgz",
+      "integrity": "sha512-ktI9+PxfHYtKjF3cLTUAh2N+b8MijCRPNwKJNqTVdL0gB0QxLU2rIRaZ1t71oEa3YBDE6bukH1sR0+CDnpp/Mg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "3.0.0",
+        "run-parallel": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=16.14.0"
+      }
+    },
+    "node_modules/@voxpelli/config-array-find-files/node_modules/@nodelib/fs.stat": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-3.0.0.tgz",
+      "integrity": "sha512-2tQOI38s19P9i7X/Drt0v8iMA+KMsgdhB/dyPER+e+2Y8L1Z7QvnuRdW/uLuf5YRFUYmnj4bMA6qCuZHFI1GDQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=16.14.0"
+      }
+    },
+    "node_modules/@voxpelli/config-array-find-files/node_modules/@nodelib/fs.walk": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-2.0.0.tgz",
+      "integrity": "sha512-54voNDBobGdMl3BUXSu7UaDh1P85PGHWlJ5e0XhPugo1JulOyCtp2I+5ri4wplGDJ8QGwPEQW7/x3yTLU7yF1A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "3.0.0",
+        "fastq": "^1.15.0"
+      },
+      "engines": {
+        "node": ">=16.14.0"
+      }
+    },
     "node_modules/@vue-macros/common": {
       "version": "1.12.2",
       "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-1.12.2.tgz",
@@ -3319,6 +4348,16 @@
         "node": ">=16 || 14 >=14.17"
       }
     },
+    "node_modules/are-docs-informative": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+      "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/are-we-there-yet": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
@@ -3389,15 +4428,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/array.prototype.findlast": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
@@ -3808,10 +4838,26 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/bundle-require": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.0.0.tgz",
+      "integrity": "sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "load-tsconfig": "^0.2.3"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "esbuild": ">=0.18"
+      }
+    },
     "node_modules/c12": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/c12/-/c12-1.11.1.tgz",
-      "integrity": "sha512-KDU0TvSvVdaYcQKQ6iPHATGz/7p/KiVjPg4vQrB6Jg/wX9R0yl5RZxWm9IoZqaIHD2+6PZd81+KMGwRr/lRIUg==",
+      "version": "1.11.2",
+      "resolved": "https://registry.npmjs.org/c12/-/c12-1.11.2.tgz",
+      "integrity": "sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==",
       "license": "MIT",
       "dependencies": {
         "chokidar": "^3.6.0",
@@ -3824,7 +4870,7 @@
         "ohash": "^1.1.3",
         "pathe": "^1.1.2",
         "perfect-debounce": "^1.0.0",
-        "pkg-types": "^1.1.1",
+        "pkg-types": "^1.2.0",
         "rc9": "^2.1.2"
       },
       "peerDependencies": {
@@ -3997,6 +5043,29 @@
         "consola": "^3.2.3"
       }
     },
+    "node_modules/clean-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
+      "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "escape-string-regexp": "^1.0.5"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/clean-regexp/node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
     "node_modules/clear": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/clear/-/clear-0.1.0.tgz",
@@ -4140,6 +5209,16 @@
         "node": ">= 10"
       }
     },
+    "node_modules/comment-parser": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+      "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
     "node_modules/commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -4234,6 +5313,20 @@
         "url": "https://github.com/sponsors/mesqueeb"
       }
     },
+    "node_modules/core-js-compat": {
+      "version": "3.38.1",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
+      "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "browserslist": "^4.23.3"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
     "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -4758,27 +5851,6 @@
         "node": ">=0.3.1"
       }
     },
-    "node_modules/dir-glob": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "license": "MIT",
-      "dependencies": {
-        "path-type": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dir-glob/node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/doctrine": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@@ -4949,6 +6021,16 @@
         "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
+    "node_modules/error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
     "node_modules/error-stack-parser-es": {
       "version": "0.1.5",
       "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz",
@@ -5070,6 +6152,13 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/es-module-lexer": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
+      "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/es-object-atoms": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
@@ -5189,16 +6278,17 @@
       }
     },
     "node_modules/eslint": {
-      "version": "9.9.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz",
-      "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==",
+      "version": "9.10.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
+      "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.11.0",
-        "@eslint/config-array": "^0.17.1",
+        "@eslint/config-array": "^0.18.0",
         "@eslint/eslintrc": "^3.1.0",
-        "@eslint/js": "9.9.0",
+        "@eslint/js": "9.10.0",
+        "@eslint/plugin-kit": "^0.1.0",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@humanwhocodes/retry": "^0.3.0",
         "@nodelib/fs.walk": "^1.2.8",
@@ -5221,7 +6311,6 @@
         "is-glob": "^4.0.0",
         "is-path-inside": "^3.0.3",
         "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
         "lodash.merge": "^4.6.2",
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
@@ -5247,6 +6336,152 @@
         }
       }
     },
+    "node_modules/eslint-config-flat-gitignore": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.3.0.tgz",
+      "integrity": "sha512-0Ndxo4qGhcewjTzw52TK06Mc00aDtHNTdeeW2JfONgDcLkRO/n/BteMRzNVpLQYxdCC/dFEilfM9fjjpGIJ9Og==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint/compat": "^1.1.1",
+        "find-up-simple": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "eslint": "^9.5.0"
+      }
+    },
+    "node_modules/eslint-flat-config-utils": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.3.1.tgz",
+      "integrity": "sha512-eFT3EaoJN1hlN97xw4FIEX//h0TiFUobgl2l5uLkIwhVN9ahGq95Pbs+i1/B5UACA78LO3rco3JzuvxLdTUOPA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/eslint": "^9.6.0",
+        "pathe": "^1.1.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/eslint-import-resolver-node": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+      "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^3.2.7",
+        "is-core-module": "^2.13.0",
+        "resolve": "^1.22.4"
+      }
+    },
+    "node_modules/eslint-import-resolver-node/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/eslint-plugin-import-x": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.2.1.tgz",
+      "integrity": "sha512-WWi2GedccIJa0zXxx3WDnTgouGQTtdYK1nhXMwywbqqAgB0Ov+p1pYBsWh3VaB0bvBOwLse6OfVII7jZD9xo5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/utils": "^8.1.0",
+        "debug": "^4.3.4",
+        "doctrine": "^3.0.0",
+        "eslint-import-resolver-node": "^0.3.9",
+        "get-tsconfig": "^4.7.3",
+        "is-glob": "^4.0.3",
+        "minimatch": "^9.0.3",
+        "semver": "^7.6.3",
+        "stable-hash": "^0.0.4",
+        "tslib": "^2.6.3"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-import-x/node_modules/doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-import-x/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/eslint-plugin-jsdoc": {
+      "version": "50.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.2.2.tgz",
+      "integrity": "sha512-i0ZMWA199DG7sjxlzXn5AeYZxpRfMJjDPUl7lL9eJJX8TPRoIaxJU4ys/joP5faM5AXE1eqW/dslCj3uj4Nqpg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@es-joy/jsdoccomment": "~0.48.0",
+        "are-docs-informative": "^0.0.2",
+        "comment-parser": "1.4.1",
+        "debug": "^4.3.6",
+        "escape-string-regexp": "^4.0.0",
+        "espree": "^10.1.0",
+        "esquery": "^1.6.0",
+        "parse-imports": "^2.1.1",
+        "semver": "^7.6.3",
+        "spdx-expression-parse": "^4.0.0",
+        "synckit": "^0.9.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/eslint-plugin-react": {
       "version": "7.35.0",
       "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz",
@@ -5327,6 +6562,140 @@
         "semver": "bin/semver.js"
       }
     },
+    "node_modules/eslint-plugin-regexp": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz",
+      "integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.9.1",
+        "comment-parser": "^1.4.0",
+        "jsdoc-type-pratt-parser": "^4.0.0",
+        "refa": "^0.12.1",
+        "regexp-ast-analysis": "^0.7.1",
+        "scslre": "^0.3.0"
+      },
+      "engines": {
+        "node": "^18 || >=20"
+      },
+      "peerDependencies": {
+        "eslint": ">=8.44.0"
+      }
+    },
+    "node_modules/eslint-plugin-unicorn": {
+      "version": "55.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-55.0.0.tgz",
+      "integrity": "sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.24.5",
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "ci-info": "^4.0.0",
+        "clean-regexp": "^1.0.0",
+        "core-js-compat": "^3.37.0",
+        "esquery": "^1.5.0",
+        "globals": "^15.7.0",
+        "indent-string": "^4.0.0",
+        "is-builtin-module": "^3.2.1",
+        "jsesc": "^3.0.2",
+        "pluralize": "^8.0.0",
+        "read-pkg-up": "^7.0.1",
+        "regexp-tree": "^0.1.27",
+        "regjsparser": "^0.10.0",
+        "semver": "^7.6.1",
+        "strip-indent": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=18.18"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
+      },
+      "peerDependencies": {
+        "eslint": ">=8.56.0"
+      }
+    },
+    "node_modules/eslint-plugin-unicorn/node_modules/globals": {
+      "version": "15.9.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+      "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint-plugin-unicorn/node_modules/jsesc": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+      "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/eslint-plugin-vue": {
+      "version": "9.28.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz",
+      "integrity": "sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "globals": "^13.24.0",
+        "natural-compare": "^1.4.0",
+        "nth-check": "^2.1.1",
+        "postcss-selector-parser": "^6.0.15",
+        "semver": "^7.6.3",
+        "vue-eslint-parser": "^9.4.3",
+        "xml-name-validator": "^4.0.0"
+      },
+      "engines": {
+        "node": "^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-vue/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint-plugin-vue/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/eslint-scope": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
@@ -5343,6 +6712,23 @@
         "url": "https://opencollective.com/eslint"
       }
     },
+    "node_modules/eslint-typegen": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/eslint-typegen/-/eslint-typegen-0.3.2.tgz",
+      "integrity": "sha512-YD/flDDDYoBszomo6wVAJ01HcEWTLfOb04+Mwir8/oR66t2bnajw+qUI6JfBoBQO3HbebcCmEtgjKgWVB67ggQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "json-schema-to-typescript-lite": "^14.1.0",
+        "ohash": "^1.1.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "eslint": "^8.45.0 || ^9.0.0"
+      }
+    },
     "node_modules/eslint-visitor-keys": {
       "version": "3.4.3",
       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
@@ -5355,6 +6741,20 @@
         "url": "https://opencollective.com/eslint"
       }
     },
+    "node_modules/eslint/node_modules/@eslint/config-array": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
+      "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@eslint/object-schema": "^2.1.4",
+        "debug": "^4.3.1",
+        "minimatch": "^3.1.2"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
     "node_modules/eslint/node_modules/ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -5738,6 +7138,19 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/find-up-simple": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz",
+      "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/flat-cache": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
@@ -6009,6 +7422,19 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/get-tsconfig": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz",
+      "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "resolve-pkg-maps": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+      }
+    },
     "node_modules/giget": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz",
@@ -6304,6 +7730,13 @@
       "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
       "license": "MIT"
     },
+    "node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true,
+      "license": "ISC"
+    },
     "node_modules/html-tags": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
@@ -6391,9 +7824,9 @@
       "license": "BSD-3-Clause"
     },
     "node_modules/ignore": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
-      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
       "license": "MIT",
       "engines": {
         "node": ">= 4"
@@ -6439,6 +7872,16 @@
         "node": ">=0.8.19"
       }
     },
+    "node_modules/indent-string": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -6528,6 +7971,13 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/is-async-function": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
@@ -7094,6 +8544,16 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/jsdoc-type-pratt-parser": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+      "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -7112,6 +8572,24 @@
       "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
       "license": "MIT"
     },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/json-schema-to-typescript-lite": {
+      "version": "14.1.0",
+      "resolved": "https://registry.npmjs.org/json-schema-to-typescript-lite/-/json-schema-to-typescript-lite-14.1.0.tgz",
+      "integrity": "sha512-b8K6P3aiLgiYKYcHacgZKrwPXPyjekqRPV5vkNfBt0EoohcOSXEbcuGzgi6KQmsAhuy5Mh2KMxofXodRhMxURA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@apidevtools/json-schema-ref-parser": "^11.7.0",
+        "@types/json-schema": "^7.0.15"
+      }
+    },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -7279,6 +8757,13 @@
         "url": "https://github.com/sponsors/antonk52"
       }
     },
+    "node_modules/lines-and-columns": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/listhen": {
       "version": "1.7.2",
       "resolved": "https://registry.npmjs.org/listhen/-/listhen-1.7.2.tgz",
@@ -7309,6 +8794,16 @@
         "listhen": "bin/listhen.mjs"
       }
     },
+    "node_modules/load-tsconfig": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+      "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      }
+    },
     "node_modules/local-pkg": {
       "version": "0.5.0",
       "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
@@ -7514,6 +9009,16 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/min-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/minimatch": {
       "version": "5.1.6",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
@@ -8224,6 +9729,29 @@
         "node": ">=6"
       }
     },
+    "node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/normalize-package-data/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -8744,6 +10272,16 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/package-json-from-dist": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
@@ -8781,6 +10319,39 @@
       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "license": "ISC"
     },
+    "node_modules/parse-imports": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.1.tgz",
+      "integrity": "sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "es-module-lexer": "^1.5.3",
+        "slashes": "^3.0.12"
+      },
+      "engines": {
+        "node": ">= 18"
+      }
+    },
+    "node_modules/parse-json": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/parse-path": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz",
@@ -8906,9 +10477,9 @@
       }
     },
     "node_modules/pkg-types": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz",
-      "integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz",
+      "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==",
       "license": "MIT",
       "dependencies": {
         "confbox": "^0.1.7",
@@ -8916,6 +10487,16 @@
         "pathe": "^1.1.2"
       }
     },
+    "node_modules/pluralize": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
+      "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/possible-typed-array-names": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -9542,6 +11123,116 @@
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
       "license": "MIT"
     },
+    "node_modules/read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/readable-stream": {
       "version": "4.5.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
@@ -9600,6 +11291,19 @@
         "node": ">=4"
       }
     },
+    "node_modules/refa": {
+      "version": "0.12.1",
+      "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz",
+      "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.8.0"
+      },
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
     "node_modules/reflect.getprototypeof": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
@@ -9621,6 +11325,30 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/regexp-ast-analysis": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz",
+      "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.8.0",
+        "refa": "^0.12.1"
+      },
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
+    "node_modules/regexp-tree": {
+      "version": "0.1.27",
+      "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+      "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "regexp-tree": "bin/regexp-tree"
+      }
+    },
     "node_modules/regexp.prototype.flags": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
@@ -9639,6 +11367,28 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/regjsparser": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz",
+      "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "jsesc": "~0.5.0"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/regjsparser/node_modules/jsesc": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+      "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      }
+    },
     "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -9674,6 +11424,16 @@
         "node": ">=8"
       }
     },
+    "node_modules/resolve-pkg-maps": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+      "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+      }
+    },
     "node_modules/reusify": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -9906,6 +11666,21 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/scslre": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz",
+      "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.8.0",
+        "refa": "^0.12.0",
+        "regexp-ast-analysis": "^0.7.0"
+      },
+      "engines": {
+        "node": "^14.0.0 || >=16.0.0"
+      }
+    },
     "node_modules/scule": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
@@ -10159,6 +11934,13 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/slashes": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz",
+      "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==",
+      "dev": true,
+      "license": "ISC"
+    },
     "node_modules/smob": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
@@ -10202,6 +11984,53 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+      "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+      "dev": true,
+      "license": "CC-BY-3.0"
+    },
+    "node_modules/spdx-expression-parse": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+      "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.20",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
+      "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
+      "dev": true,
+      "license": "CC0-1.0"
+    },
     "node_modules/speakingurl": {
       "version": "14.0.1",
       "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
@@ -10211,6 +12040,13 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/stable-hash": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz",
+      "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/standard-as-callback": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
@@ -10406,6 +12242,19 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/strip-indent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "min-indent": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -10518,6 +12367,23 @@
         "url": "https://opencollective.com/svgo"
       }
     },
+    "node_modules/synckit": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
+      "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@pkgr/core": "^0.1.0",
+        "tslib": "^2.6.2"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/unts"
+      }
+    },
     "node_modules/system-architecture": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz",
@@ -10684,6 +12550,13 @@
         "typescript": ">=4.2.0"
       }
     },
+    "node_modules/tslib": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+      "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+      "dev": true,
+      "license": "0BSD"
+    },
     "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -10911,9 +12784,9 @@
       }
     },
     "node_modules/unimport": {
-      "version": "3.10.0",
-      "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.10.0.tgz",
-      "integrity": "sha512-/UvKRfWx3mNDWwWQhR62HsoM3wxHwYdTq8ellZzMOHnnw4Dp8tovgthyW7DjTrbjDL+i4idOp06voz2VKlvrLw==",
+      "version": "3.11.1",
+      "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.11.1.tgz",
+      "integrity": "sha512-DuB1Uoq01LrrXTScxnwOoMSlTXxyKcULguFxbLrMDFcE/CO0ZWHpEiyhovN0mycPt7K6luAHe8laqvwvuoeUPg==",
       "license": "MIT",
       "dependencies": {
         "@rollup/pluginutils": "^5.1.0",
@@ -10925,10 +12798,10 @@
         "magic-string": "^0.30.11",
         "mlly": "^1.7.1",
         "pathe": "^1.1.2",
-        "pkg-types": "^1.1.3",
+        "pkg-types": "^1.2.0",
         "scule": "^1.3.0",
         "strip-literal": "^2.1.0",
-        "unplugin": "^1.12.0"
+        "unplugin": "^1.12.2"
       }
     },
     "node_modules/universalify": {
@@ -10941,18 +12814,24 @@
       }
     },
     "node_modules/unplugin": {
-      "version": "1.12.1",
-      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.12.1.tgz",
-      "integrity": "sha512-aXEH9c5qi3uYZHo0niUtxDlT9ylG/luMW/dZslSCkbtC31wCyFkmM0kyoBBh+Grhn7CL+/kvKLfN61/EdxPxMQ==",
+      "version": "1.14.0",
+      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.14.0.tgz",
+      "integrity": "sha512-cfkZeALGyW7tKYjZbi0G+pn0XnUFa0QvLIeLJEUUlnU0R8YYsBQnt5+h9Eu1B7AB7KETld+UBFI5lOeBL+msoQ==",
       "license": "MIT",
       "dependencies": {
         "acorn": "^8.12.1",
-        "chokidar": "^3.6.0",
-        "webpack-sources": "^3.2.3",
         "webpack-virtual-modules": "^0.6.2"
       },
       "engines": {
         "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "webpack-sources": "^3"
+      },
+      "peerDependenciesMeta": {
+        "webpack-sources": {
+          "optional": true
+        }
       }
     },
     "node_modules/unplugin-vue-router": {
@@ -11167,6 +13046,28 @@
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "license": "MIT"
     },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
     "node_modules/vite": {
       "version": "5.4.0",
       "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz",
@@ -12025,6 +13926,66 @@
       "integrity": "sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==",
       "license": "MIT"
     },
+    "node_modules/vue-eslint-parser": {
+      "version": "9.4.3",
+      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+      "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.3.4",
+        "eslint-scope": "^7.1.1",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.3.1",
+        "esquery": "^1.4.0",
+        "lodash": "^4.17.21",
+        "semver": "^7.3.6"
+      },
+      "engines": {
+        "node": "^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mysticatea"
+      },
+      "peerDependencies": {
+        "eslint": ">=6.0.0"
+      }
+    },
+    "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/vue-eslint-parser/node_modules/espree": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "acorn": "^8.9.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
     "node_modules/vue-router": {
       "version": "4.4.3",
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.3.tgz",
@@ -12051,6 +14012,8 @@
       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
       "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=10.13.0"
       }
@@ -12317,6 +14280,16 @@
         }
       }
     },
+    "node_modules/xml-name-validator": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+      "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/y18n": {
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index 3877889..5601c39 100644
--- a/package.json
+++ b/package.json
@@ -7,15 +7,18 @@
     "dev": "nuxt dev",
     "generate": "nuxt generate",
     "preview": "nuxt preview",
-    "postinstall": "nuxt prepare"
+    "postinstall": "nuxt prepare",
+    "lint": "eslint .",
+    "format": "eslint --fix . "
   },
   "dependencies": {
-    "@typescript-eslint/eslint-plugin": "^8.0.1",
-    "@typescript-eslint/parser": "^8.0.1",
     "bootstrap": "^5.3.0",
-    "eslint": "^9.9.0",
     "eslint-plugin-react": "^7.35.0",
     "nuxt": "^3.12.4",
     "vue": "latest"
+  },
+  "devDependencies": {
+    "@nuxt/eslint": "^0.5.6",
+    "eslint": "^9.10.0"
   }
 }
diff --git a/pages/index.vue b/pages/index.vue
index 7fb760b..06c0f71 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -1,33 +1,33 @@
-<script setup lang="ts">
-import type Year from './summary/[year].vue';
+<script setup lang='ts'>
+import type Year from './summary/[year].vue'
 
-const today = new Date();
-let thisYear = today.getFullYear();
+const today = new Date()
+let thisYear = today.getFullYear()
 </script>
 
 
 <template>
   <h1>mawinter-front</h1>
   <section>
-    <p text-alignment="center">
+    <p text-alignment='center'>
     <h2>登録</h2>
     <PostRecord />
     </p>
 
-    <div class="summary_link">
+    <div class='summary_link'>
       <NuxtLink v-bind:to="{name: 'summary-year', params: {year: thisYear}}">
         サマリー表示
       </NuxtLink>
     </div>
 
-    <p text-alignment="center">
+    <p text-alignment='center'>
     <h2>直近履歴</h2>
     <History />
     </p>
   </section>
 </template>
 
-<style lang="css">
+<style lang='css'>
 h2 {
   text-align: center;
   margin-left: auto;
diff --git a/pages/summary/[year].vue b/pages/summary/[year].vue
index 5d08a50..6043211 100644
--- a/pages/summary/[year].vue
+++ b/pages/summary/[year].vue
@@ -1,6 +1,6 @@
-<script setup lang="ts">
-import type { SummaryOne } from "@/interfaces";
-const config = useRuntimeConfig(); // nuxt.config.ts に書いてあるコンフィグを読み出す
+<script setup lang='ts'>
+import type { SummaryOne } from '@/interfaces'
+const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
 const incomeList = ref<SummaryOne[]>()
 const incomeSumList = ref<SummaryOne>()
 const outgoingList = ref<SummaryOne[]>()
@@ -12,13 +12,13 @@ const AllSumWithoutInvestList = ref<SummaryOne>() // 合計(投資除く)フ
 
 let fetched: boolean // api fetch 出来ていたら true にする(表示制御用)
 const asyncData = await useFetch(
-  "/api/summary",
+  '/api/summary',
   {
     key: `/api/summary`,
     transform: (data: SummaryOne[]): SummaryOne[][] => {
-      let incomeArray: SummaryOne[] = [];
-      let outgoingArray: SummaryOne[] = [];
-      let investArray: SummaryOne[] = [];
+      let incomeArray: SummaryOne[] = []
+      let outgoingArray: SummaryOne[] = []
+      let investArray: SummaryOne[] = []
       for (let d of data) {
         if ([100, 101, 110].includes(d.category_id)) {
           incomeArray.push(d)
@@ -34,14 +34,14 @@ const asyncData = await useFetch(
       return retArray
     }
   }
-);
+)
 
 
 
 if (asyncData.data.value != undefined) {
-  const incomeData = asyncData.data.value[0] as SummaryOne[];
-  const outgoingData = asyncData.data.value[1] as SummaryOne[];
-  const investData = asyncData.data.value[2] as SummaryOne[];
+  const incomeData = asyncData.data.value[0] as SummaryOne[]
+  const outgoingData = asyncData.data.value[1] as SummaryOne[]
+  const investData = asyncData.data.value[2] as SummaryOne[]
   incomeList.value = incomeData
   outgoingList.value = outgoingData
   investList.value = investData
@@ -49,87 +49,87 @@ if (asyncData.data.value != undefined) {
   // sum の計算(income)
   let incomeSumData: SummaryOne = {
     category_id: 999,
-    category_name: "収入合計",
+    category_name: '収入合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     total: 0
-  };
+  }
 
   for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
+    let sum: number = 0
+    let totalsum: number = 0
     for (let d of incomeData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
+      sum += d.price[i]
+      totalsum += d.price[i]
     }
-    incomeSumData.price[i] = sum;
-    incomeSumData.total += totalsum;
+    incomeSumData.price[i] = sum
+    incomeSumData.total += totalsum
   }
   incomeSumList.value = incomeSumData
 
   // sum の計算(outgoing)
   let outgoingSumData: SummaryOne = {
     category_id: 999,
-    category_name: "支出合計",
+    category_name: '支出合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     total: 0
-  };
+  }
   for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
+    let sum: number = 0
+    let totalsum: number = 0
     for (let d of outgoingData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
+      sum += d.price[i]
+      totalsum += d.price[i]
     }
-    outgoingSumData.price[i] = sum;
-    outgoingSumData.total += totalsum;
+    outgoingSumData.price[i] = sum
+    outgoingSumData.total += totalsum
   }
   outgoingSumList.value = outgoingSumData
 
   // sum の計算(invest)
   let investSumData: SummaryOne = {
     category_id: 999,
-    category_name: "投資合計",
+    category_name: '投資合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     total: 0
-  };
+  }
 
   for (let i: number = 0; i < 12; i++) {
-    let sum: number = 0;
-    let totalsum: number = 0;
+    let sum: number = 0
+    let totalsum: number = 0
     for (let d of investData) {
-      sum += d.price[i];
-      totalsum += d.price[i];
+      sum += d.price[i]
+      totalsum += d.price[i]
     }
-    investSumData.price[i] = sum;
-    investSumData.total += totalsum;
+    investSumData.price[i] = sum
+    investSumData.total += totalsum
   }
   investSumList.value = investSumData
 
   // 合計テーブル用の計算
   let AllSumData: SummaryOne = {
     category_id: 999,
-    category_name: "合計",
+    category_name: '合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     total: 0
-  };
+  }
 
   for (let i: number = 0; i < 12; i++) {
-    AllSumData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i] - investSumData.price[i];
+    AllSumData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i] - investSumData.price[i]
   }
-  AllSumData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
+  AllSumData.total = incomeSumData.total - outgoingSumData.total - investSumData.total
   AllSumList.value = AllSumData
 
   let AllSumWithoutInvestData: SummaryOne = {
     category_id: 999,
-    category_name: "合計(投資除く)",
+    category_name: '合計(投資除く)',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     total: 0
-  };
+  }
 
   for (let i: number = 0; i < 12; i++) {
-    AllSumWithoutInvestData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i];
+    AllSumWithoutInvestData.price[i] = incomeSumData.price[i] - outgoingSumData.price[i]
   }
-  AllSumWithoutInvestData.total = incomeSumData.total - outgoingSumData.total - investSumData.total;
+  AllSumWithoutInvestData.total = incomeSumData.total - outgoingSumData.total - investSumData.total
   AllSumWithoutInvestList.value = AllSumWithoutInvestData
 
   fetched = true // データ取得後のフラグを立てる
@@ -139,449 +139,449 @@ if (asyncData.data.value != undefined) {
 
 <template>
   <h1>サマリー表示</h1>
-  <div class="container">
-    <a href="../">トップに戻る</a>
+  <div class='container'>
+    <a href='../'>トップに戻る</a>
 
     <h2>合計</h2>
-    <table class="table small bordered striped table-bordered">
+    <table class='table small bordered striped table-bordered'>
       <thead>
         <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
+          <th scope='col' style='width: 3%'>ID</th>
+          <th scope='col' style='width: 10%'>カテゴリ名</th>
+          <th scope='col' style='width: 5%'>4月</th>
+          <th scope='col' style='width: 5%'>5月</th>
+          <th scope='col' style='width: 5%'>6月</th>
+          <th scope='col' style='width: 5%'>7月</th>
+          <th scope='col' style='width: 5%'>8月</th>
+          <th scope='col' style='width: 5%'>9月</th>
+          <th scope='col' style='width: 5%'>10月</th>
+          <th scope='col' style='width: 5%'>11月</th>
+          <th scope='col' style='width: 5%'>12月</th>
+          <th scope='col' style='width: 5%'>1月</th>
+          <th scope='col' style='width: 5%'>2月</th>
+          <th scope='col' style='width: 5%'>3月</th>
+          <th scope='col' style='width: 7%'>合計</th>
         </tr>
       </thead>
       <tbody>
-        <th scope="row"></th>
-        <tr v-if="fetched">
+        <th scope='row'></th>
+        <tr v-if='fetched'>
           <td>{{ AllSumList?.category_id }}</td>
           <td>{{ AllSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[0] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[1] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[2] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[3] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[4] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[5] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[6] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[7] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[8] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[9] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[10] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.price[11] }}</div>
+            <div class='text-end'>{{ AllSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumList?.total }}</div>
+            <div class='text-end'>{{ AllSumList?.total }}</div>
           </td>
         </tr>
-        <tr v-if="fetched" class="table-info">
+        <tr v-if='fetched' class='table-info'>
           <td>{{ AllSumWithoutInvestList?.category_id }}</td>
           <td>{{ AllSumWithoutInvestList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[0] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[1] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[2] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[3] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[4] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[5] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[6] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[7] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[8] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[9] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[10] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.price[11] }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ AllSumWithoutInvestList?.total }}</div>
+            <div class='text-end'>{{ AllSumWithoutInvestList?.total }}</div>
           </td>
         </tr>
       </tbody>
     </table>
 
     <h2>収入</h2>
-    <table class="table small bordered striped table-bordered">
+    <table class='table small bordered striped table-bordered'>
       <thead>
         <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
+          <th scope='col' style='width: 3%'>ID</th>
+          <th scope='col' style='width: 10%'>カテゴリ名</th>
+          <th scope='col' style='width: 5%'>4月</th>
+          <th scope='col' style='width: 5%'>5月</th>
+          <th scope='col' style='width: 5%'>6月</th>
+          <th scope='col' style='width: 5%'>7月</th>
+          <th scope='col' style='width: 5%'>8月</th>
+          <th scope='col' style='width: 5%'>9月</th>
+          <th scope='col' style='width: 5%'>10月</th>
+          <th scope='col' style='width: 5%'>11月</th>
+          <th scope='col' style='width: 5%'>12月</th>
+          <th scope='col' style='width: 5%'>1月</th>
+          <th scope='col' style='width: 5%'>2月</th>
+          <th scope='col' style='width: 5%'>3月</th>
+          <th scope='col' style='width: 7%'>合計</th>
         </tr>
       </thead>
       <tbody>
-        <tr v-for="income in incomeList">
+        <tr v-for='income in incomeList'>
           <td>{{ income.category_id }}</td>
           <td>{{ income.category_name }}</td>
           <td>
-            <div class="text-end">{{ income.price[0] }}</div>
+            <div class='text-end'>{{ income.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[1] }}</div>
+            <div class='text-end'>{{ income.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[2] }}</div>
+            <div class='text-end'>{{ income.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[3] }}</div>
+            <div class='text-end'>{{ income.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[4] }}</div>
+            <div class='text-end'>{{ income.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[5] }}</div>
+            <div class='text-end'>{{ income.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[6] }}</div>
+            <div class='text-end'>{{ income.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[7] }}</div>
+            <div class='text-end'>{{ income.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[8] }}</div>
+            <div class='text-end'>{{ income.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[9] }}</div>
+            <div class='text-end'>{{ income.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[10] }}</div>
+            <div class='text-end'>{{ income.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.price[11] }}</div>
+            <div class='text-end'>{{ income.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ income.total }}</div>
+            <div class='text-end'>{{ income.total }}</div>
           </td>
         </tr>
-        <tr v-if="fetched" class="table-success">
+        <tr v-if='fetched' class='table-success'>
           <td>{{ incomeSumList?.category_id }}</td>
           <td>{{ incomeSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[0] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[1] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[2] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[3] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[4] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[5] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[6] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[7] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[8] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[9] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[10] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.price[11] }}</div>
+            <div class='text-end'>{{ incomeSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ incomeSumList?.total }}</div>
+            <div class='text-end'>{{ incomeSumList?.total }}</div>
           </td>
         </tr>
       </tbody>
     </table>
 
     <h2>支出</h2>
-    <table class="table small bordered striped table-bordered">
+    <table class='table small bordered striped table-bordered'>
       <thead>
         <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%">合計</th>
+          <th scope='col' style='width: 3%'>ID</th>
+          <th scope='col' style='width: 10%'>カテゴリ名</th>
+          <th scope='col' style='width: 5%'>4月</th>
+          <th scope='col' style='width: 5%'>5月</th>
+          <th scope='col' style='width: 5%'>6月</th>
+          <th scope='col' style='width: 5%'>7月</th>
+          <th scope='col' style='width: 5%'>8月</th>
+          <th scope='col' style='width: 5%'>9月</th>
+          <th scope='col' style='width: 5%'>10月</th>
+          <th scope='col' style='width: 5%'>11月</th>
+          <th scope='col' style='width: 5%'>12月</th>
+          <th scope='col' style='width: 5%'>1月</th>
+          <th scope='col' style='width: 5%'>2月</th>
+          <th scope='col' style='width: 5%'>3月</th>
+          <th scope='col' style='width: 7%'>合計</th>
         </tr>
       </thead>
       <tbody>
-        <tr v-for="outgoing in outgoingList">
+        <tr v-for='outgoing in outgoingList'>
           <td>{{ outgoing.category_id }}</td>
           <td>{{ outgoing.category_name }}</td>
           <td>
-            <div class="text-end">{{ outgoing.price[0] }}</div>
+            <div class='text-end'>{{ outgoing.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[1] }}</div>
+            <div class='text-end'>{{ outgoing.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[2] }}</div>
+            <div class='text-end'>{{ outgoing.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[3] }}</div>
+            <div class='text-end'>{{ outgoing.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[4] }}</div>
+            <div class='text-end'>{{ outgoing.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[5] }}</div>
+            <div class='text-end'>{{ outgoing.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[6] }}</div>
+            <div class='text-end'>{{ outgoing.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[7] }}</div>
+            <div class='text-end'>{{ outgoing.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[8] }}</div>
+            <div class='text-end'>{{ outgoing.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[9] }}</div>
+            <div class='text-end'>{{ outgoing.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[10] }}</div>
+            <div class='text-end'>{{ outgoing.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.price[11] }}</div>
+            <div class='text-end'>{{ outgoing.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoing.total }}</div>
+            <div class='text-end'>{{ outgoing.total }}</div>
           </td>
         </tr>
-        <tr v-if="fetched" class="table-danger">
+        <tr v-if='fetched' class='table-danger'>
           <td>{{ outgoingSumList?.category_id }}</td>
           <td>{{ outgoingSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[0] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[1] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[2] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[3] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[4] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[5] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[6] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[7] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[8] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[9] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[10] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.price[11] }}</div>
+            <div class='text-end'>{{ outgoingSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ outgoingSumList?.total }}</div>
+            <div class='text-end'>{{ outgoingSumList?.total }}</div>
           </td>
         </tr>
       </tbody>
     </table>
 
     <h2>投資</h2>
-    <table class="table small bordered striped table-bordered">
+    <table class='table small bordered striped table-bordered'>
       <thead>
         <tr>
-          <th scope="col" style="width: 3%">ID</th>
-          <th scope="col" style="width: 10%">カテゴリ名</th>
-          <th scope="col" style="width: 5%">4月</th>
-          <th scope="col" style="width: 5%">5月</th>
-          <th scope="col" style="width: 5%">6月</th>
-          <th scope="col" style="width: 5%">7月</th>
-          <th scope="col" style="width: 5%">8月</th>
-          <th scope="col" style="width: 5%">9月</th>
-          <th scope="col" style="width: 5%">10月</th>
-          <th scope="col" style="width: 5%">11月</th>
-          <th scope="col" style="width: 5%">12月</th>
-          <th scope="col" style="width: 5%">1月</th>
-          <th scope="col" style="width: 5%">2月</th>
-          <th scope="col" style="width: 5%">3月</th>
-          <th scope="col" style="width: 7%"">合計</th>
+          <th scope='col' style='width: 3%'>ID</th>
+          <th scope='col' style='width: 10%'>カテゴリ名</th>
+          <th scope='col' style='width: 5%'>4月</th>
+          <th scope='col' style='width: 5%'>5月</th>
+          <th scope='col' style='width: 5%'>6月</th>
+          <th scope='col' style='width: 5%'>7月</th>
+          <th scope='col' style='width: 5%'>8月</th>
+          <th scope='col' style='width: 5%'>9月</th>
+          <th scope='col' style='width: 5%'>10月</th>
+          <th scope='col' style='width: 5%'>11月</th>
+          <th scope='col' style='width: 5%'>12月</th>
+          <th scope='col' style='width: 5%'>1月</th>
+          <th scope='col' style='width: 5%'>2月</th>
+          <th scope='col' style='width: 5%'>3月</th>
+          <th scope='col' style='width: 7%''>合計</th>
         </tr>
       </thead>
       <tbody>
-        <tr v-for=" invest in investList">
+        <tr v-for=' invest in investList'>
           <td>{{ invest.category_id }}</td>
           <td>{{ invest.category_name }}</td>
           <td>
-            <div class="text-end">{{ invest.price[0] }}</div>
+            <div class='text-end'>{{ invest.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[1] }}</div>
+            <div class='text-end'>{{ invest.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[2] }}</div>
+            <div class='text-end'>{{ invest.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[3] }}</div>
+            <div class='text-end'>{{ invest.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[4] }}</div>
+            <div class='text-end'>{{ invest.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[5] }}</div>
+            <div class='text-end'>{{ invest.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[6] }}</div>
+            <div class='text-end'>{{ invest.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[7] }}</div>
+            <div class='text-end'>{{ invest.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[8] }}</div>
+            <div class='text-end'>{{ invest.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[9] }}</div>
+            <div class='text-end'>{{ invest.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[10] }}</div>
+            <div class='text-end'>{{ invest.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.price[11] }}</div>
+            <div class='text-end'>{{ invest.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ invest.total }}</div>
+            <div class='text-end'>{{ invest.total }}</div>
           </td>
         </tr>
-        <tr v-if="fetched" class="table-warning">
+        <tr v-if='fetched' class='table-warning'>
           <td>{{ investSumList?.category_id }}</td>
           <td>{{ investSumList?.category_name }}</td>
           <td>
-            <div class="text-end">{{ investSumList?.price[0] }}</div>
+            <div class='text-end'>{{ investSumList?.price[0] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[1] }}</div>
+            <div class='text-end'>{{ investSumList?.price[1] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[2] }}</div>
+            <div class='text-end'>{{ investSumList?.price[2] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[3] }}</div>
+            <div class='text-end'>{{ investSumList?.price[3] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[4] }}</div>
+            <div class='text-end'>{{ investSumList?.price[4] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[5] }}</div>
+            <div class='text-end'>{{ investSumList?.price[5] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[6] }}</div>
+            <div class='text-end'>{{ investSumList?.price[6] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[7] }}</div>
+            <div class='text-end'>{{ investSumList?.price[7] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[8] }}</div>
+            <div class='text-end'>{{ investSumList?.price[8] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[9] }}</div>
+            <div class='text-end'>{{ investSumList?.price[9] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[10] }}</div>
+            <div class='text-end'>{{ investSumList?.price[10] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.price[11] }}</div>
+            <div class='text-end'>{{ investSumList?.price[11] }}</div>
           </td>
           <td>
-            <div class="text-end">{{ investSumList?.total }}</div>
+            <div class='text-end'>{{ investSumList?.total }}</div>
           </td>
         </tr>
         </tbody>

From 1768702f4f547a5fbf65a1915c54546ac5965a86 Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 02:40:34 +0900
Subject: [PATCH 4/7] disable ssr

---
 nuxt.config.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nuxt.config.ts b/nuxt.config.ts
index affec5e..529cc95 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -4,7 +4,7 @@ export default defineNuxtConfig({
   css: ["bootstrap/dist/css/bootstrap.min.css"],
   devtools: { enabled: true },
   routeRules: {
-    "/": { ssr: true },
+    "/": { ssr: false },
   },
   runtimeConfig: {
     public: { // 外部から取得するにはpublic が必要

From 3c3ec5fc32c0986433098bbc8f18ed56cd047f30 Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 19:45:08 +0900
Subject: [PATCH 5/7] Reduce ESLint error

---
 components/PostRecord.vue                   | 15 +++---
 components/{History.vue => ShowHistory.vue} | 19 +++-----
 nuxt.config.ts                              | 11 ++---
 pages/index.vue                             | 14 ++----
 pages/summary/[year].vue                    | 52 ++++++++++-----------
 server/api/deleteRecord.ts                  |  8 ++--
 server/api/getCategories.ts                 |  8 ++--
 server/api/history.ts                       | 18 +++----
 server/api/postRecord.ts                    | 11 ++---
 server/api/summary.ts                       |  8 ++--
 10 files changed, 73 insertions(+), 91 deletions(-)
 rename components/{History.vue => ShowHistory.vue} (82%)

diff --git a/components/PostRecord.vue b/components/PostRecord.vue
index 64785d1..c57a3f6 100644
--- a/components/PostRecord.vue
+++ b/components/PostRecord.vue
@@ -1,20 +1,19 @@
 <script setup lang='ts'>
 import type { Category } from '@/interfaces'
-const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
-const selector = ref<any>()
+let selector: string
 const categoryList = ref<Category[]>()
 const asyncData = await useFetch(
   '/api/getCategories',
   {
     key: `/api/getCategories`,
-  }
+  },
 )
 
 const data = asyncData.data.value as Category[]
 
 // category 加工
 if (data != undefined) { // 取得済の場合のみ
-  for (let d of data) {
+  for (const d of data) {
     // 100, category_name -> 100:category_name という表示に
     // ただし加工済の場合は skip
     if (d.category_name[3] != ':') {
@@ -29,16 +28,16 @@ categoryList.value = data
 const priceBox = ref<number>()
 
 const postButton = async (): Promise<void> => {
-  const asyncDataBtn = await useAsyncData(
+  await useAsyncData(
     `record`,
-    (): Promise<any> => {
-      const send_category_id = selector.value.slice(0, 3) // 210-食費→210
+    (): Promise<unknown> => {
+      const send_category_id = selector.slice(0, 3) // 210-食費→210
       const param = { price: priceBox.value, category_id: send_category_id }
       const paramStr = '?price=' + param['price'] + '&category_id=' + param['category_id']
       const localurl = '/api/postRecord' + paramStr
       const response = $fetch(localurl)
       return response
-    }
+    },
   )
   location.reload()
 }
diff --git a/components/History.vue b/components/ShowHistory.vue
similarity index 82%
rename from components/History.vue
rename to components/ShowHistory.vue
index 0a983f5..87db274 100644
--- a/components/History.vue
+++ b/components/ShowHistory.vue
@@ -1,44 +1,39 @@
 <script setup lang='ts'>
 import type { Record } from '@/interfaces'
-const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
 const recordList = ref<Record[]>()
 const asyncData = await useFetch(
   '/api/history',
   {
     key: `/api/history`,
-  }
+  },
 )
 
-
 const data = asyncData.data.value as Record[]
 
 // fetchデータを整形
 if (data != undefined) { // 取得済の場合のみ
-  for (let d of data) {
+  for (const d of data) {
     d.datetime = d.datetime.slice(0, 19) // 2023-09-23T00:00:00+09:00 -> 2023-09-23T00:00:00
   }
 }
 
-
 recordList.value = data
 
 async function showDeleteDialog(id: number): Promise<void> {
   const userResponse: boolean = confirm('このデータを削除しますか')
   if (userResponse == true) {
-    console.log('delete: id=' + id)
-    const asyncDataBtn = await useAsyncData(
+    await useAsyncData(
       `record`,
-      (): Promise<any> => {
-        const param = { 'id': id }
+      (): Promise<unknown> => {
+        const param = { id: id }
         const paramStr = '?id=' + param['id']
         const localurl = '/api/deleteRecord' + paramStr
         const response = $fetch(localurl)
         return response
-      }
+      },
     )
     location.reload()
   }
-
 }
 
 </script>
@@ -57,7 +52,7 @@ async function showDeleteDialog(id: number): Promise<void> {
         </tr>
       </thead>
       <tbody>
-        <tr v-for='record in recordList'>
+        <tr v-for='record in recordList' :key=record.id>
           <td>{{ record.id }}</td>
           <td>{{ record.category_name }}</td>
           <td>{{ record.price }}</td>
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 529cc95..a85c977 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -1,18 +1,17 @@
 // https://nuxt.com/docs/api/configuration/nuxt-config
 export default defineNuxtConfig({
   compatibilityDate: '2024-04-03',
-  css: ["bootstrap/dist/css/bootstrap.min.css"],
+  css: ['bootstrap/dist/css/bootstrap.min.css'],
   devtools: { enabled: true },
   routeRules: {
-    "/": { ssr: false },
+    '/': { ssr: false },
   },
   runtimeConfig: {
     public: { // 外部から取得するにはpublic が必要
-      mawinterApi: "http://mawinter-api", // .env の NUXT_PUBLIC_API_BASE_ENDPOINT から取得
-    }
+      mawinterApi: 'http://mawinter-api', // .env の NUXT_PUBLIC_API_BASE_ENDPOINT から取得
+    },
   },
   modules: [
-    '@nuxt/eslint'
+    '@nuxt/eslint',
   ],
-  
 })
diff --git a/pages/index.vue b/pages/index.vue
index 06c0f71..d8cfc73 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -1,18 +1,13 @@
 <script setup lang='ts'>
-import type Year from './summary/[year].vue'
-
 const today = new Date()
-let thisYear = today.getFullYear()
+const thisYear = today.getFullYear()
 </script>
 
-
 <template>
-  <h1>mawinter-front</h1>
   <section>
-    <p text-alignment='center'>
+  <h1>mawinter-front</h1>
     <h2>登録</h2>
     <PostRecord />
-    </p>
 
     <div class='summary_link'>
       <NuxtLink v-bind:to="{name: 'summary-year', params: {year: thisYear}}">
@@ -20,10 +15,9 @@ let thisYear = today.getFullYear()
       </NuxtLink>
     </div>
 
-    <p text-alignment='center'>
     <h2>直近履歴</h2>
-    <History />
-    </p>
+    <ShowHistory />
+
   </section>
 </template>
 
diff --git a/pages/summary/[year].vue b/pages/summary/[year].vue
index 6043211..c4342b2 100644
--- a/pages/summary/[year].vue
+++ b/pages/summary/[year].vue
@@ -1,6 +1,5 @@
 <script setup lang='ts'>
 import type { SummaryOne } from '@/interfaces'
-const config = useRuntimeConfig() // nuxt.config.ts に書いてあるコンフィグを読み出す
 const incomeList = ref<SummaryOne[]>()
 const incomeSumList = ref<SummaryOne>()
 const outgoingList = ref<SummaryOne[]>()
@@ -16,10 +15,10 @@ const asyncData = await useFetch(
   {
     key: `/api/summary`,
     transform: (data: SummaryOne[]): SummaryOne[][] => {
-      let incomeArray: SummaryOne[] = []
-      let outgoingArray: SummaryOne[] = []
-      let investArray: SummaryOne[] = []
-      for (let d of data) {
+      const incomeArray: SummaryOne[] = []
+      const outgoingArray: SummaryOne[] = []
+      const investArray: SummaryOne[] = []
+      for (const d of data) {
         if ([100, 101, 110].includes(d.category_id)) {
           incomeArray.push(d)
         }
@@ -32,12 +31,10 @@ const asyncData = await useFetch(
       }
       const retArray: SummaryOne[][] = [incomeArray, outgoingArray, investArray]
       return retArray
-    }
-  }
+    },
+  },
 )
 
-
-
 if (asyncData.data.value != undefined) {
   const incomeData = asyncData.data.value[0] as SummaryOne[]
   const outgoingData = asyncData.data.value[1] as SummaryOne[]
@@ -47,17 +44,17 @@ if (asyncData.data.value != undefined) {
   investList.value = investData
 
   // sum の計算(income)
-  let incomeSumData: SummaryOne = {
+  const incomeSumData: SummaryOne = {
     category_id: 999,
     category_name: '収入合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
+    total: 0,
   }
 
   for (let i: number = 0; i < 12; i++) {
     let sum: number = 0
     let totalsum: number = 0
-    for (let d of incomeData) {
+    for (const d of incomeData) {
       sum += d.price[i]
       totalsum += d.price[i]
     }
@@ -67,16 +64,16 @@ if (asyncData.data.value != undefined) {
   incomeSumList.value = incomeSumData
 
   // sum の計算(outgoing)
-  let outgoingSumData: SummaryOne = {
+  const outgoingSumData: SummaryOne = {
     category_id: 999,
     category_name: '支出合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
+    total: 0,
   }
   for (let i: number = 0; i < 12; i++) {
     let sum: number = 0
     let totalsum: number = 0
-    for (let d of outgoingData) {
+    for (const d of outgoingData) {
       sum += d.price[i]
       totalsum += d.price[i]
     }
@@ -86,17 +83,17 @@ if (asyncData.data.value != undefined) {
   outgoingSumList.value = outgoingSumData
 
   // sum の計算(invest)
-  let investSumData: SummaryOne = {
+  const investSumData: SummaryOne = {
     category_id: 999,
     category_name: '投資合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
+    total: 0,
   }
 
   for (let i: number = 0; i < 12; i++) {
     let sum: number = 0
     let totalsum: number = 0
-    for (let d of investData) {
+    for (const d of investData) {
       sum += d.price[i]
       totalsum += d.price[i]
     }
@@ -106,11 +103,11 @@ if (asyncData.data.value != undefined) {
   investSumList.value = investSumData
 
   // 合計テーブル用の計算
-  let AllSumData: SummaryOne = {
+  const AllSumData: SummaryOne = {
     category_id: 999,
     category_name: '合計',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
+    total: 0,
   }
 
   for (let i: number = 0; i < 12; i++) {
@@ -119,11 +116,11 @@ if (asyncData.data.value != undefined) {
   AllSumData.total = incomeSumData.total - outgoingSumData.total - investSumData.total
   AllSumList.value = AllSumData
 
-  let AllSumWithoutInvestData: SummaryOne = {
+  const AllSumWithoutInvestData: SummaryOne = {
     category_id: 999,
     category_name: '合計(投資除く)',
     price: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-    total: 0
+    total: 0,
   }
 
   for (let i: number = 0; i < 12; i++) {
@@ -138,8 +135,8 @@ if (asyncData.data.value != undefined) {
 </script>
 
 <template>
-  <h1>サマリー表示</h1>
   <div class='container'>
+  <h1>サマリー表示</h1>
     <a href='../'>トップに戻る</a>
 
     <h2>合計</h2>
@@ -164,7 +161,6 @@ if (asyncData.data.value != undefined) {
         </tr>
       </thead>
       <tbody>
-        <th scope='row'></th>
         <tr v-if='fetched'>
           <td>{{ AllSumList?.category_id }}</td>
           <td>{{ AllSumList?.category_name }}</td>
@@ -276,7 +272,7 @@ if (asyncData.data.value != undefined) {
         </tr>
       </thead>
       <tbody>
-        <tr v-for='income in incomeList'>
+        <tr v-for='income in incomeList' :key=income.id>
           <td>{{ income.category_id }}</td>
           <td>{{ income.category_name }}</td>
           <td>
@@ -387,7 +383,7 @@ if (asyncData.data.value != undefined) {
         </tr>
       </thead>
       <tbody>
-        <tr v-for='outgoing in outgoingList'>
+        <tr v-for='outgoing in outgoingList' :key=outgoing.id>
           <td>{{ outgoing.category_id }}</td>
           <td>{{ outgoing.category_name }}</td>
           <td>
@@ -494,11 +490,11 @@ if (asyncData.data.value != undefined) {
           <th scope='col' style='width: 5%'>1月</th>
           <th scope='col' style='width: 5%'>2月</th>
           <th scope='col' style='width: 5%'>3月</th>
-          <th scope='col' style='width: 7%''>合計</th>
+          <th scope='col' style='width: 7%'>合計</th>
         </tr>
       </thead>
       <tbody>
-        <tr v-for=' invest in investList'>
+        <tr v-for='invest in investList' :key=invest.id>
           <td>{{ invest.category_id }}</td>
           <td>{{ invest.category_name }}</td>
           <td>
diff --git a/server/api/deleteRecord.ts b/server/api/deleteRecord.ts
index c35249a..5da0233 100644
--- a/server/api/deleteRecord.ts
+++ b/server/api/deleteRecord.ts
@@ -1,11 +1,11 @@
-export default defineEventHandler ( async (event) => {
+export default defineEventHandler (async (event) => {
   const config = useRuntimeConfig()
   const query = getQuery(event)
-  const url = config.public.mawinterApi + "/v2/record/" + query.id
+  const url = config.public.mawinterApi + '/v2/record/' + query.id
   const result = await $fetch(url,
     {
-        method: "DELETE",
-    }
+      method: 'DELETE',
+    },
   )
   return result
 })
diff --git a/server/api/getCategories.ts b/server/api/getCategories.ts
index 6ae6797..7b4d4db 100644
--- a/server/api/getCategories.ts
+++ b/server/api/getCategories.ts
@@ -1,10 +1,10 @@
-export default defineEventHandler ( async (event) => {
+export default defineEventHandler (async () => {
   const config = useRuntimeConfig()
-  const url = config.public.mawinterApi + "/categories"
+  const url = config.public.mawinterApi + '/categories'
   const result = await $fetch(url,
     {
-        method: "GET",
-    }
+      method: 'GET',
+    },
   )
   return result
 })
diff --git a/server/api/history.ts b/server/api/history.ts
index 520e421..65cdd4a 100644
--- a/server/api/history.ts
+++ b/server/api/history.ts
@@ -1,10 +1,10 @@
-export default defineEventHandler ( async (event) => {
-    const config = useRuntimeConfig()
-    const url = config.public.mawinterApi + "/v2/record"
-    const result = await $fetch(url,
-      {
-          method: "GET",
-      }
-    )
-    return result
+export default defineEventHandler (async () => {
+  const config = useRuntimeConfig()
+  const url = config.public.mawinterApi + '/v2/record'
+  const result = await $fetch(url,
+    {
+      method: 'GET',
+    },
+  )
+  return result
 })
diff --git a/server/api/postRecord.ts b/server/api/postRecord.ts
index 535bf84..112dc02 100644
--- a/server/api/postRecord.ts
+++ b/server/api/postRecord.ts
@@ -1,4 +1,4 @@
-export default defineEventHandler ( async (event) => {
+export default defineEventHandler (async (event) => {
   const config = useRuntimeConfig()
   const query = getQuery(event)
   // create body
@@ -10,13 +10,12 @@ export default defineEventHandler ( async (event) => {
   "memo":"手動"
   }
   `
-  console.log(reqbody)
-  const url = config.public.mawinterApi + "/v2/record"
+  const url = config.public.mawinterApi + '/v2/record'
   const result = await $fetch(url,
     {
-        method: "POST",
-        body: reqbody
-    }
+      method: 'POST',
+      body: reqbody,
+    },
   )
   return result
 })
diff --git a/server/api/summary.ts b/server/api/summary.ts
index d2539a7..d18b21f 100644
--- a/server/api/summary.ts
+++ b/server/api/summary.ts
@@ -1,10 +1,10 @@
-export default defineEventHandler ( async (event) => {
+export default defineEventHandler (async () => {
   const config = useRuntimeConfig()
-  const url = config.public.mawinterApi + "/v2/record/summary/2024"
+  const url = config.public.mawinterApi + '/v2/record/summary/2024'
   const result = await $fetch(url,
     {
-      method: "GET",
-    }
+      method: 'GET',
+    },
   )
   return result
 })

From eafdef985464241dad373fb8e5a1386ffcb37d9e Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 20:10:18 +0900
Subject: [PATCH 6/7] Add eslint for actions

---
 .github/workflows/frontend.yml | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 4f5627c..ec46df0 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -11,7 +11,7 @@ on:
 jobs:
   frontend:
     runs-on: ubuntu-latest
-    steps: 
+    steps:
       - name: Checkout
         uses: actions/checkout@v4
 
@@ -19,7 +19,7 @@ jobs:
         uses: actions/setup-node@v4
         with:
           node-version: "22.5"
-          cache-dependency-path: 'package-lock.json'
+          cache-dependency-path: "package-lock.json"
 
       - run: node --version
 
@@ -34,6 +34,5 @@ jobs:
         env:
           NODE_OPTIONS: "--max_old_space_size=8192"
 
-      - name: npm run generate
-        run: npm run build
-
+      - name: npm run lint
+        run: npm run lint

From a876c269a24db7ab30582fd55f1a530ba4fb2838 Mon Sep 17 00:00:00 2001
From: azuki774s <azuki774s@gmail.com>
Date: Tue, 10 Sep 2024 22:17:16 +0900
Subject: [PATCH 7/7] Use Parameter for summary page FY

---
 pages/summary/[year].vue | 5 ++++-
 server/api/summary.ts    | 5 +++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/pages/summary/[year].vue b/pages/summary/[year].vue
index c4342b2..ce784c9 100644
--- a/pages/summary/[year].vue
+++ b/pages/summary/[year].vue
@@ -10,8 +10,11 @@ const AllSumList = ref<SummaryOne>() // 合計フィールド
 const AllSumWithoutInvestList = ref<SummaryOne>() // 合計(投資除く)フィールド
 
 let fetched: boolean // api fetch 出来ていたら true にする(表示制御用)
+
+const route = useRoute()
+const year = route.params.year
 const asyncData = await useFetch(
-  '/api/summary',
+  '/api/summary' + '?year=' + year, // webサーバ内ではクエリパラメータで渡す
   {
     key: `/api/summary`,
     transform: (data: SummaryOne[]): SummaryOne[][] => {
diff --git a/server/api/summary.ts b/server/api/summary.ts
index d18b21f..21254ae 100644
--- a/server/api/summary.ts
+++ b/server/api/summary.ts
@@ -1,6 +1,7 @@
-export default defineEventHandler (async () => {
+export default defineEventHandler (async (event) => {
   const config = useRuntimeConfig()
-  const url = config.public.mawinterApi + '/v2/record/summary/2024'
+  const query = getQuery(event)
+  const url = config.public.mawinterApi + '/v2/record/summary/' + query.year
   const result = await $fetch(url,
     {
       method: 'GET',