diff --git a/docs/adr/0009-frontend-textlint-proofread.md b/docs/adr/0009-frontend-textlint-proofread.md
new file mode 100644
index 00000000..21d9b689
--- /dev/null
+++ b/docs/adr/0009-frontend-textlint-proofread.md
@@ -0,0 +1,49 @@
+# ADR-0009: 職務経歴書のフロントエンド完結型 文章校正(textlint + kuromoji)
+
+## ステータス
+
+Accepted
+
+## コンテキスト
+
+職務経歴書は転職で人の目に触れる重要文書だが、DevForge には誤字脱字・表記ゆれ・冗長表現を検出する仕組みが無かった。保存前にユーザーが自分で気づけるよう、保存確認ダイアログ(`CareerDiffModal`)内で文章を校正し、指摘を一覧表示する機能を追加する。
+
+制約・前提:
+
+- **個人情報を外部に送らない**: 職務経歴書は氏名・経歴を含む。外部 API / LLM に本文を送信しない方針(ADR-0008 のルールベース志向とも整合)。
+- **コスト**: 追加のサーバー処理・課金を避けたい。
+- **既存体験への影響最小化**: 保存フロー(`useDocumentForm.save`)の契約は変えない。
+
+## 決定内容
+
+**ルールベースの校正をフロントエンド完結(Web Worker)で実行する。**
+
+- エンジン: `@textlint/kernel` + `textlint-rule-preset-ja-technical-writing`(全23ルール)+ `textlint-rule-prh`(IT 用語の表記ゆれ辞書を同梱)。
+- 実行場所: 専用 Web Worker(`src/proofread/proofread.worker.ts`)。textlint / kuromoji 一式は動的 import で worker チャンクへ分割し、初期バンドル・初回描画から切り離す。
+- 形態素解析辞書(kuromoji): `frontend/public/kuromoji-dict/`(約18MB)に静的配信。worker から `globalThis.kuromojin.dicPath = "/kuromoji-dict"`(ルート相対)で参照。
+- UI 統合: メインスレッドは `ProofreadIssue[]` という安定インターフェースのみ知る。`useProofread` フックが保存確認ダイアログ表示中だけ校正を起動し、結果を `CareerDiffModal` 右サイドバー下部に「校正の指摘」として青系・控えめに表示する。**保存はブロックしない**(警告のみ)。
+- 辞書ロード失敗時は形態素解析依存ルール(二重助詞・冗長表現など11ルール)を除外し、prh + 非依存ルールで継続する(グレースフルデグラデーション)。
+
+## 代替案
+
+- **LLM / 外部校正 API**: 精度は高いが個人情報の外部送信・コスト・レイテンシで不採用(ADR-0008 の方針に反する)。
+- **バックエンド(Python)で textlint 相当を実行**: Node ランタイム追加 or Python 形態素解析の導入が必要でインフラ複雑化。本文をサーバーに送る必要も無いためフロント完結を優先。
+- **prh 単体 + 自前正規表現のみ(kuromoji 無し)**: リポジトリ肥大ゼロ・軽量だが、二重助詞・冗長表現などの文法系チェックが落ちる。フォールバック経路としては内包するが、第一選択は全プリセットとした。
+
+## トレードオフ・既知のリスク
+
+- **リポジトリ肥大**: kuromoji 辞書 約18MB を `public/` にコミットするため git 履歴が恒久的に増える(ユーザー承認済みのトレードオフ)。
+- **初回ロード遅延**: 初回校正時に辞書(数MB)を fetch するため、最初の指摘表示まで数秒かかる。以降は worker 内でキャッシュ。
+- **ブラウザ統合の脆さ**: textlint/kuromoji は Node 前提のため、worker で `window` / `process`(`cwd`/`nextTick` 等)の最小ポリフィル、node 組み込み(`path`/`os`/`assert`)のブラウザ実装エイリアス、辞書 `.gz` を `Content-Encoding: gzip` させない配信(dev: Vite プラグイン / prod: `public/_headers`)が必要。これらは `src/proofread/worker-env-polyfill.ts`・`vite.config.ts`・`public/_headers` に集約しコメントで明示した。
+- **辞書 `.gz` の二重展開**: サーバーが `.gz` を gzip 転送エンコーディング扱いすると、ブラウザが自動展開して kuromoji の再 gunzip が失敗する。生バイト配信を強制している。
+
+## 将来の移行条件
+
+- リポジトリ肥大が問題化した場合: 辞書を CDN(jsDelivr 等)配信へ切り替える、または kuromoji 依存ルールを外して辞書同梱をやめる(フォールバック構成へ)。
+- 校正精度を上げたい場合: prh 辞書の拡充、もしくは(個人情報の扱いを整理した上で)サーバーサイド校正の再検討。
+
+## 関連リンク
+
+- 実装: `frontend/src/proofread/`・`frontend/src/hooks/career/useProofread.ts`・`frontend/src/components/forms/CareerDiffModal.tsx`
+- 関連 ADR: ADR-0008(ルールベース設計への移行)
+- 参考: textlint / textlint-rule-preset-ja-technical-writing / kuromoji.js
diff --git a/frontend/e2e/career-proofread.spec.ts b/frontend/e2e/career-proofread.spec.ts
new file mode 100644
index 00000000..070cf586
--- /dev/null
+++ b/frontend/e2e/career-proofread.spec.ts
@@ -0,0 +1,73 @@
+import { test, expect, type Page } from "@playwright/test";
+import { setupAuth, waitForAuthenticatedLayout } from "./helpers/auth";
+
+/**
+ * 職務経歴書 保存時の文章校正(誤字脱字・表記ゆれ)E2E。
+ *
+ * 検証:
+ * - 保存確認ダイアログ(左右 diff モーダル)に「校正の指摘」セクションが出る。
+ * - 自己PR の表記ゆれ("javascript" → "JavaScript")が prh で実際に検出され、
+ * worker(textlint + kuromoji 辞書ロード)経由で指摘が画面に出る。
+ *
+ * 校正はフロント完結(API なし)なので backend モック不要。worker が public/kuromoji-dict/
+ * から辞書をロードするため、指摘表示には余裕を持った待機を取る。
+ */
+async function setupResumeApi(page: Page) {
+ const baseResume = {
+ id: "resume-1",
+ full_name: "山田 太郎",
+ career_summary: "サマリー",
+ // 表記ゆれ(javascript)を含む自己PR。
+ self_pr: "私はjavascriptが得意です。",
+ experiences: [],
+ qualifications: [],
+ };
+
+ await page.route("**/api/master-data/qualification", (route) =>
+ route.fulfill({ status: 200, contentType: "application/json", body: "[]" }),
+ );
+ await page.route("**/api/master-data/technology-stack", (route) =>
+ route.fulfill({ status: 200, contentType: "application/json", body: "[]" }),
+ );
+ await page.route("**/api/resumes/preview", (route) =>
+ route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify({ html: "
preview
", css: "" }),
+ }),
+ );
+ await page.route("**/api/resumes/latest", (route) =>
+ route.fulfill({
+ status: 200,
+ contentType: "application/json",
+ body: JSON.stringify(baseResume),
+ }),
+ );
+}
+
+test.describe("職務経歴書 保存時の文章校正", () => {
+ test.beforeEach(async ({ page }) => {
+ await setupAuth(page);
+ await setupResumeApi(page);
+ });
+
+ test("保存確認ダイアログに校正の指摘(表記ゆれ)が表示される", async ({ page }) => {
+ await page.goto("/career");
+ await waitForAuthenticatedLayout(page);
+
+ // 変更を作って確認ダイアログを開く(氏名を編集)。
+ await page.getByPlaceholder("例: 山田 太郎").fill("佐藤 花子");
+ await page.getByRole("button", { name: /更新する|保存する/ }).click();
+
+ // ダイアログと統合レビュー一覧(変更点+校正)が出る。
+ await expect(page.getByRole("dialog", { name: "変更内容の確認" })).toBeVisible();
+ await expect(page.getByText("変更点・校正", { exact: true })).toBeVisible();
+
+ // prh による表記ゆれ指摘(javascript => JavaScript)が worker 経由で表示される。
+ // 辞書ロードを含むため待機時間を長めに取る。
+ await expect(page.getByText(/JavaScript/)).toBeVisible({ timeout: 30000 });
+
+ // 校正があっても保存はブロックされない(「この内容で保存」が押せる)。
+ await expect(page.getByRole("button", { name: "この内容で保存" })).toBeEnabled();
+ });
+});
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 1995faa9..5c23e6c3 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,15 +9,20 @@
"version": "0.1.0",
"dependencies": {
"@reduxjs/toolkit": "^2.11.2",
+ "@textlint/kernel": "^15.7.1",
+ "@textlint/textlint-plugin-text": "^15.7.1",
"dompurify": "^3.4.7",
"marked": "^17.0.4",
+ "prh": "^6.0.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-pdf": "^9.2.1",
"react-redux": "^9.2.0",
"react-router-dom": "^7.13.1",
"recharts": "^3.8.0",
- "redux-persist": "^6.0.0"
+ "redux-persist": "^6.0.0",
+ "textlint-rule-preset-ja-technical-writing": "^12.0.2",
+ "textlint-rule-prh": "^6.1.0"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
@@ -25,11 +30,13 @@
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
+ "@textlint/types": "^15.7.1",
"@types/node": "^25.5.2",
"@types/react": "^18.3.15",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/coverage-v8": "^4.1.2",
+ "assert": "^2.1.0",
"concurrently": "^9.2.1",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
@@ -40,6 +47,8 @@
"jsdom": "^29.0.1",
"msw": "^2.13.2",
"openapi-typescript": "^7.13.0",
+ "os-browserify": "^0.3.0",
+ "path-browserify": "^1.0.1",
"playwright": "^1.56.0",
"prettier": "^3.8.1",
"typescript": "^5.7.2",
@@ -263,7 +272,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -273,7 +281,6 @@
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -307,7 +314,6 @@
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
"integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.0"
@@ -399,7 +405,6 @@
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -2002,6 +2007,55 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@kvs/env": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@kvs/env/-/env-2.2.2.tgz",
+ "integrity": "sha512-tvy6eb1IHiQWqgSBjOxJp+gQ8wI/1bT5pWKU0VJL9d8SwAflOpN9777wQ3RY3jUtEUpcQOUtxrxcrMs9VYiNBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@kvs/indexeddb": "^2.2.2",
+ "@kvs/node-localstorage": "^2.2.2",
+ "@kvs/storage": "^2.2.2",
+ "@kvs/types": "^2.2.2"
+ }
+ },
+ "node_modules/@kvs/indexeddb": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@kvs/indexeddb/-/indexeddb-2.2.2.tgz",
+ "integrity": "sha512-h9Fom6YvbRzMHhBLZKdNNJ/bgla0aBbmVBzUBLUoeEwT3C16Yx5eGA+spUQ69ZoRbsArZufX84qX/wRbyvjtrg==",
+ "license": "MIT",
+ "dependencies": {
+ "@kvs/storage": "^2.2.2",
+ "@kvs/types": "^2.2.2"
+ }
+ },
+ "node_modules/@kvs/node-localstorage": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@kvs/node-localstorage/-/node-localstorage-2.2.2.tgz",
+ "integrity": "sha512-e6r2CBWAQznaLEAmYSNNPGXUkSRP+yffSZNJYfgR4II8vjDFtGj1gByo2yk7pQsRiiId6IZ5dwDl1Tib3bNaqw==",
+ "license": "MIT",
+ "dependencies": {
+ "@kvs/storage": "^2.2.2",
+ "@kvs/types": "^2.2.2",
+ "app-root-path": "^3.1.0",
+ "node-localstorage": "^2.1.6"
+ }
+ },
+ "node_modules/@kvs/storage": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@kvs/storage/-/storage-2.2.2.tgz",
+ "integrity": "sha512-jThnhLTcT0w1SHzhr/PFTzzkKl+V3J6X07NyARceT02mIu5+tBWwtUhS68UNOaD7CTQ07rMFgb5UHoolies94g==",
+ "license": "MIT",
+ "dependencies": {
+ "@kvs/types": "^2.2.2"
+ }
+ },
+ "node_modules/@kvs/types": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@kvs/types/-/types-2.2.2.tgz",
+ "integrity": "sha512-5lmBuah+wOdypBf0O9t6BoHrnq5hX5MlhEPTDPBNKN38ayQwVc5gYgJOBR3Dg4EF7OwL+1c7JNtWXQEJXXVXlg==",
+ "license": "MIT"
+ },
"node_modules/@mswjs/interceptors": {
"version": "0.41.3",
"resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.3.tgz",
@@ -2694,6 +2748,176 @@
"@testing-library/dom": ">=7.21.4"
}
},
+ "node_modules/@textlint-rule/textlint-rule-no-invalid-control-character": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@textlint-rule/textlint-rule-no-invalid-control-character/-/textlint-rule-no-invalid-control-character-3.0.0.tgz",
+ "integrity": "sha512-2o9n4z49ntSPtJPlcJtxakyB4dAg2MKSvR9ZCZEHjye0ee27oWYzK6yHz2HjsXQqt9VeCwxNHDOIGIx2CQX0Dw==",
+ "license": "MIT"
+ },
+ "node_modules/@textlint-rule/textlint-rule-no-unmatched-pair": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@textlint-rule/textlint-rule-no-unmatched-pair/-/textlint-rule-no-unmatched-pair-2.0.4.tgz",
+ "integrity": "sha512-g9Ge1xUV9xJy8T7nuutF/2J6Cg2mmPx4gKsC3dCdxVxuL0wMqOOnAi8l6psFpAQ5UFtQuAzwkdclrehPtBT5tg==",
+ "license": "MIT",
+ "dependencies": {
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1"
+ }
+ },
+ "node_modules/@textlint/ast-node-types": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-15.7.1.tgz",
+ "integrity": "sha512-Wii5UgUKFEh9Uv6wbq1zr4/Kf+dtjiUuzPrrXzKp8H+ifkvKNzi23V4Nz+6wVyHQn5T28AFuc8VH8OtzvGYecA==",
+ "license": "MIT"
+ },
+ "node_modules/@textlint/ast-tester": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-tester/-/ast-tester-15.7.1.tgz",
+ "integrity": "sha512-0CZWFKB7D21y8LA4Dv5irOX1/iGDGwM4OTaW7PxJpfRhXCL40uMOhS+P+1bjFmpSkM/DF/5HPRph0E744iJobw==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "15.7.1",
+ "debug": "^4.4.3"
+ }
+ },
+ "node_modules/@textlint/ast-traverse": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-traverse/-/ast-traverse-15.7.1.tgz",
+ "integrity": "sha512-tFgFiSbh6fdQo7MF4FYQoQBHqM8BoTEfvubGXm7Xi65QRYefNz+iuXYaoyto6OlMj5M95u9Gk/Ni7577rZ8uow==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "15.7.1"
+ }
+ },
+ "node_modules/@textlint/feature-flag": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/feature-flag/-/feature-flag-15.7.1.tgz",
+ "integrity": "sha512-ZFIJ2edV7K04UJ7/7ptvL61vs54MHYzDaIfTW+vaXwq5KDeCD2QyjsKt+TbOHQ8n8sW6fO171n4p0gwRo01Ojg==",
+ "license": "MIT"
+ },
+ "node_modules/@textlint/kernel": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/kernel/-/kernel-15.7.1.tgz",
+ "integrity": "sha512-OGghiMbXLD3ULHedZYP1B+A8Bj4snlCatzsOdz0M8q0v4I79NdcamWt/5GYmbp6AOQg3HBQG8+9V+0H+do19mw==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "15.7.1",
+ "@textlint/ast-tester": "15.7.1",
+ "@textlint/ast-traverse": "15.7.1",
+ "@textlint/feature-flag": "15.7.1",
+ "@textlint/source-code-fixer": "15.7.1",
+ "@textlint/types": "15.7.1",
+ "@textlint/utils": "15.7.1",
+ "debug": "^4.4.3",
+ "fast-equals": "^4.0.3",
+ "structured-source": "^4.0.0"
+ }
+ },
+ "node_modules/@textlint/markdown-to-ast": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-13.4.1.tgz",
+ "integrity": "sha512-jUa5bTNmxjEgfCXW4xfn7eSJqzUXyNKiIDWLKtI4MUKRNhT3adEaa/NuQl0Mii3Hu3HraZR7hYhRHLh+eeM43w==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1",
+ "debug": "^4.3.4",
+ "mdast-util-gfm-autolink-literal": "^0.1.3",
+ "remark-footnotes": "^3.0.0",
+ "remark-frontmatter": "^3.0.0",
+ "remark-gfm": "^1.0.0",
+ "remark-parse": "^9.0.0",
+ "traverse": "^0.6.7",
+ "unified": "^9.2.2"
+ }
+ },
+ "node_modules/@textlint/markdown-to-ast/node_modules/@textlint/ast-node-types": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-13.4.1.tgz",
+ "integrity": "sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==",
+ "license": "MIT"
+ },
+ "node_modules/@textlint/module-interop": {
+ "version": "14.8.4",
+ "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-14.8.4.tgz",
+ "integrity": "sha512-1LdPYLAVpa27NOt6EqvuFO99s4XLB0c19Hw9xKSG6xQ1K82nUEyuWhzTQKb3KJ5Qx7qj14JlXZLfnEuL6A16Bw==",
+ "license": "MIT"
+ },
+ "node_modules/@textlint/regexp-string-matcher": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@textlint/regexp-string-matcher/-/regexp-string-matcher-1.1.1.tgz",
+ "integrity": "sha512-rrNUCKGKYBrZALotSF8D5A8xD05VHX6kxv0BP805Ig2M73Ha6LK+de31+ZocGm4CO+sikVFYyMCPPJhp7bCXcw==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0",
+ "execall": "^2.0.0",
+ "lodash.sortby": "^4.7.0",
+ "lodash.uniq": "^4.5.0",
+ "lodash.uniqwith": "^4.5.0",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "node_modules/@textlint/regexp-string-matcher/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@textlint/source-code-fixer": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/source-code-fixer/-/source-code-fixer-15.7.1.tgz",
+ "integrity": "sha512-Z8ZfQQbVH2GIUMzSGEQWKKnAFCH+mbQtw5ipigFHExUImx2RC2ppaR1m8ZAy7SYgbXGhvfkPKZ4ndEmVWTs5Mg==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/types": "15.7.1",
+ "debug": "^4.4.3"
+ }
+ },
+ "node_modules/@textlint/text-to-ast": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/text-to-ast/-/text-to-ast-15.7.1.tgz",
+ "integrity": "sha512-W6AYCOcEAtw9hs0u69+Tte8hmWaLKYGdo3yBxgOpl20Q6AOkxxEaG305Nr5rgbO6caWJWkR/t2WxBkZzm3KG0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "15.7.1"
+ }
+ },
+ "node_modules/@textlint/textlint-plugin-markdown": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-markdown/-/textlint-plugin-markdown-13.4.1.tgz",
+ "integrity": "sha512-OcLkFKYmbYeGJ0kj2487qcicCYTiE2vJLwfPcUDJrNoMYak5JtvHJfWffck8gON2mEM00DPkHH0UdxZpFjDfeg==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/markdown-to-ast": "^13.4.1"
+ }
+ },
+ "node_modules/@textlint/textlint-plugin-text": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-text/-/textlint-plugin-text-15.7.1.tgz",
+ "integrity": "sha512-krU0KiDmG2LrESF3LchgfbSwclB/8I2itA4uzSY9Tln3miaWGKzUpLu00bQtvua0f2Ux7tsLnSmwAgGFf9gERA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/text-to-ast": "15.7.1",
+ "@textlint/types": "15.7.1"
+ }
+ },
+ "node_modules/@textlint/types": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/types/-/types-15.7.1.tgz",
+ "integrity": "sha512-Vye/GmFNBTgVzZFtIFJTmLB+s2A7oIADxNG6r9UhfPuY+Czv0z5G3xeyFZZudPlfxURsKUyPIU5XsjOFqVp33A==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "15.7.1"
+ }
+ },
+ "node_modules/@textlint/utils": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@textlint/utils/-/utils-15.7.1.tgz",
+ "integrity": "sha512-+q5Z5fsNk/ixDY5D70ZCQungr7ppzBAAhmi207qDBzSBFeA5MM2ASGwMjPc5aMJ/3DvonI/01B3UIgbpVgIXVA==",
+ "license": "MIT"
+ },
"node_modules/@types/aria-query": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
@@ -2852,6 +3076,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/mdast": {
+ "version": "3.0.15",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
+ "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2"
+ }
+ },
"node_modules/@types/node": {
"version": "25.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz",
@@ -2904,6 +3137,12 @@
"license": "MIT",
"optional": true
},
+ "node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
"node_modules/@types/use-sync-external-store": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
@@ -3434,6 +3673,15 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/analyze-desumasu-dearu": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/analyze-desumasu-dearu/-/analyze-desumasu-dearu-5.0.2.tgz",
+ "integrity": "sha512-3PUxFk790GpQkME//hwiJellbtKMiAFX/CyA93etmAo5FujJ+5GKVXW+NU9v2MfF07iWcXsrNMbGW5/vVpqWwA==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0"
+ }
+ },
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@@ -3470,11 +3718,19 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/app-root-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
+ "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
"license": "Python-2.0"
},
"node_modules/aria-query": {
@@ -3487,6 +3743,57 @@
"dequal": "^2.0.3"
}
},
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assert": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz",
+ "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-nan": "^1.3.2",
+ "object-is": "^1.1.5",
+ "object.assign": "^4.1.4",
+ "util": "^0.12.5"
+ }
+ },
"node_modules/assertion-error": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
@@ -3497,6 +3804,15 @@
"node": ">=12"
}
},
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ast-v8-to-istanbul": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz",
@@ -3516,6 +3832,49 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/bail": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+ "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3611,6 +3970,12 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/boundary": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/boundary/-/boundary-2.0.0.tgz",
+ "integrity": "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/brace-expansion": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
@@ -3704,11 +4069,28 @@
"node": ">= 0.8"
}
},
+ "node_modules/call-bind": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
+ "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "get-intrinsic": "^1.3.0",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -3722,7 +4104,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -3781,6 +4162,16 @@
"node": "^18.12.0 || >= 20.9.0"
}
},
+ "node_modules/ccount": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz",
+ "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/chai": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
@@ -3815,6 +4206,51 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/check-ends-with-period": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/check-ends-with-period/-/check-ends-with-period-3.0.2.tgz",
+ "integrity": "sha512-/Bw+avucqqZ7PjKCVDod1QDGyZjo7Ht2701pdgcpTXzK5jI73/OUh3VR+m18jNUoJx5DSOUv0AxELZF7FYtcDA==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.1.0"
+ }
+ },
+ "node_modules/check-ends-with-period/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "license": "MIT"
+ },
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
@@ -3865,6 +4301,18 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/clone-regexp": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+ "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "is-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
@@ -3901,6 +4349,31 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/commandpost": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz",
+ "integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==",
+ "license": "MIT"
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -4181,22 +4654,72 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
"license": "MIT",
"dependencies": {
- "ms": "^2.1.3"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
},
"engines": {
- "node": ">=6.0"
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
}
},
"node_modules/decimal.js": {
@@ -4245,6 +4768,53 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -4274,6 +4844,15 @@
"node": ">=8"
}
},
+ "node_modules/diff": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz",
+ "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/dom-accessibility-api": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
@@ -4291,11 +4870,16 @@
"@types/trusted-types": "^2.0.7"
}
},
+ "node_modules/doublearray": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/doublearray/-/doublearray-0.0.2.tgz",
+ "integrity": "sha512-aw55FtZzT6AmiamEj2kvmR6BuFqvYgKZUkfQ7teqVRNqD5UE0rw8IeW/3gieHNKQ5sPuDKlljWEn4bzv5+1bHw==",
+ "license": "MIT"
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -4370,11 +4954,78 @@
"url": "https://github.com/sponsors/antfu"
}
},
+ "node_modules/es-abstract": {
+ "version": "1.24.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
+ "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4384,7 +5035,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4401,7 +5051,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -4410,6 +5059,38 @@
"node": ">= 0.4"
}
},
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/es-toolkit": {
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.45.1.tgz",
@@ -4483,7 +5164,6 @@
"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"
@@ -4646,6 +5326,19 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/esquery": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
@@ -4718,6 +5411,18 @@
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
"license": "MIT"
},
+ "node_modules/execall": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+ "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+ "license": "MIT",
+ "dependencies": {
+ "clone-regexp": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -4792,6 +5497,25 @@
"node": ">= 0.6"
}
},
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4799,6 +5523,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-equals": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz",
+ "integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==",
+ "license": "MIT"
+ },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -4813,6 +5543,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "license": "MIT",
+ "dependencies": {
+ "format": "^0.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
@@ -4938,6 +5681,29 @@
}
}
},
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -4984,12 +5750,49 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -5014,7 +5817,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -5039,7 +5841,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -5049,6 +5850,23 @@
"node": ">= 0.4"
}
},
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -5082,11 +5900,26 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -5095,6 +5928,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
"node_modules/graphql": {
"version": "16.13.2",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz",
@@ -5105,6 +5944,18 @@
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -5115,33 +5966,116 @@
"node": ">=8"
}
},
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "dev": true,
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/hasown": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
- "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
- "dev": true,
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"license": "MIT",
"dependencies": {
- "function-bind": "^1.1.2"
+ "dunder-proto": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/headers-polyfill": {
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
+ "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hast-util-from-parse5": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz",
+ "integrity": "sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA==",
+ "license": "MIT",
+ "dependencies": {
+ "ccount": "^1.0.3",
+ "hastscript": "^5.0.0",
+ "property-information": "^5.0.0",
+ "web-namespaces": "^1.1.2",
+ "xtend": "^4.0.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-parse-selector": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz",
+ "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/headers-polyfill": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz",
"integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==",
@@ -5339,7 +6273,6 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.19"
@@ -5382,6 +6315,20 @@
"license": "ISC",
"optional": true
},
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/internmap": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
@@ -5401,170 +6348,692 @@
"node": ">= 0.10"
}
},
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
+ "node_modules/is-accessor-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.2.tgz",
+ "integrity": "sha512-AIbwAcazqP3R65dGvqk1V+a+vE5Fg1yu/ZKMOiBWSUIXXiwQkYmXQcVa2O0nh0tSDKDFKxG2mY7dB1Sr4hEP1g==",
"license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
+ "node_modules/is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
"license": "MIT",
- "engines": {
- "node": ">=8"
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "node_modules/is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
"license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
},
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/is-node-process": {
+ "node_modules/is-arguments": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
- "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
"engines": {
- "node": ">=0.12.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "dev": true,
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-potential-custom-element-name": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
- "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "license": "BSD-3-Clause",
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "license": "BSD-3-Clause",
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "license": "MIT",
"dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
+ "has-bigints": "^1.0.2"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/istanbul-reports": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
- "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
- "dev": true,
- "license": "BSD-3-Clause",
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "license": "MIT",
"dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/js-levenshtein": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
- "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
- "dev": true,
+ "node_modules/is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4"
}
},
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
- "dev": true,
+ "node_modules/is-data-descriptor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz",
+ "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==",
"license": "MIT",
"dependencies": {
- "argparse": "^2.0.1"
+ "hasown": "^2.0.0"
},
- "bin": {
- "js-yaml": "bin/js-yaml.js"
+ "engines": {
+ "node": ">= 0.4"
}
},
- "node_modules/jsdom": {
- "version": "29.0.1",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.1.tgz",
- "integrity": "sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==",
- "dev": true,
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"license": "MIT",
"dependencies": {
- "@asamuzakjp/css-color": "^5.0.1",
- "@asamuzakjp/dom-selector": "^7.0.3",
- "@bramus/specificity": "^2.4.2",
- "@csstools/css-syntax-patches-for-csstree": "^1.1.1",
- "@exodus/bytes": "^1.15.0",
- "css-tree": "^3.2.1",
- "data-urls": "^7.0.0",
- "decimal.js": "^10.6.0",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-descriptor": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.4.tgz",
+ "integrity": "sha512-bv5z95W0dDtLfKwDfkTNxaRxmISBD3eQBKJeVxv2AQ7MjuUnDNG7cIQqvFtMOUYhsILWHhMayWdoGqNqYYYjww==",
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.2",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable/node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-nan": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
+ "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-node-process": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
+ "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regexp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/japanese-numerals-to-number": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/japanese-numerals-to-number/-/japanese-numerals-to-number-1.0.2.tgz",
+ "integrity": "sha512-rgs/V7G8Gfy8Z4XtnVBYXzWMAb9oUWp1pDdRmwHmh0hcjcy1kOu+DOpC5rwoHUAN4TqANwb7WD6z5W2v7v7PQQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-levenshtein": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
+ "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "29.0.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.1.tgz",
+ "integrity": "sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^5.0.1",
+ "@asamuzakjp/dom-selector": "^7.0.3",
+ "@bramus/specificity": "^2.4.2",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.1",
+ "@exodus/bytes": "^1.15.0",
+ "css-tree": "^3.2.1",
+ "data-urls": "^7.0.0",
+ "decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.2.7",
@@ -5668,6 +7137,28 @@
"node": ">=6"
}
},
+ "node_modules/kuromoji": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/kuromoji/-/kuromoji-0.1.2.tgz",
+ "integrity": "sha512-V0dUf+C2LpcPEXhoHLMAop/bOht16Dyr+mDiIE39yX3vqau7p80De/koFqpiTcL1zzdZlc3xuHZ8u5gjYRfFaQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^2.0.1",
+ "doublearray": "0.0.2",
+ "zlibjs": "^0.3.1"
+ }
+ },
+ "node_modules/kuromojin": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/kuromojin/-/kuromojin-3.0.1.tgz",
+ "integrity": "sha512-E4rLmbTid8ZGH8Fw421UXvfgCe0IXGFKhUw/IosBVW6ootxVGKGbtb0UPQAvPswgsXX/8UuPiE+amz1NN11Uzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@kvs/env": "^2.1.3",
+ "kuromoji": "0.1.2",
+ "lru_map": "^0.4.1"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -5698,6 +7189,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -5705,6 +7202,34 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniqwith": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz",
+ "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==",
+ "license": "MIT"
+ },
+ "node_modules/longest-streak": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz",
+ "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -5717,6 +7242,12 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lru_map": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.4.1.tgz",
+ "integrity": "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==",
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -5807,6 +7338,19 @@
"url": "https://github.com/wojtekmaj/make-event-props?sponsor=1"
}
},
+ "node_modules/markdown-table": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz",
+ "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==",
+ "license": "MIT",
+ "dependencies": {
+ "repeat-string": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/marked": {
"version": "17.0.4",
"resolved": "https://registry.npmjs.org/marked/-/marked-17.0.4.tgz",
@@ -5819,16 +7363,183 @@
"node": ">= 20"
}
},
+ "node_modules/match-index": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/match-index/-/match-index-1.0.3.tgz",
+ "integrity": "sha512-1XjyBWqCvEFFUDW/MPv0RwbITRD4xQXOvKoPYtLDq8IdZTfdF/cQSo5Yn4qvhfSSZgjgkTFsqJD2wOUG4ovV8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "regexp.prototype.flags": "^1.1.1"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
+ "node_modules/mdast-util-find-and-replace": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz",
+ "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-footnote": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz",
+ "integrity": "sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-to-markdown": "^0.6.0",
+ "micromark": "~2.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-from-markdown": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz",
+ "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "micromark": "~2.11.0",
+ "parse-entities": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-frontmatter": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz",
+ "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-extension-frontmatter": "^0.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz",
+ "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-gfm-autolink-literal": "^0.1.0",
+ "mdast-util-gfm-strikethrough": "^0.2.0",
+ "mdast-util-gfm-table": "^0.1.0",
+ "mdast-util-gfm-task-list-item": "^0.1.0",
+ "mdast-util-to-markdown": "^0.6.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-autolink-literal": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz",
+ "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==",
+ "license": "MIT",
+ "dependencies": {
+ "ccount": "^1.0.0",
+ "mdast-util-find-and-replace": "^1.1.0",
+ "micromark": "^2.11.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-strikethrough": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz",
+ "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-to-markdown": "^0.6.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-table": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz",
+ "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "markdown-table": "^2.0.0",
+ "mdast-util-to-markdown": "~0.6.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-task-list-item": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz",
+ "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-to-markdown": "~0.6.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz",
+ "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^2.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.0.0",
+ "zwitch": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdn-data": {
"version": "2.27.1",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
@@ -5876,6 +7587,132 @@
}
}
},
+ "node_modules/micromark": {
+ "version": "2.11.4",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
+ "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.0.0",
+ "parse-entities": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-footnote": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz",
+ "integrity": "sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-frontmatter": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz",
+ "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==",
+ "license": "MIT",
+ "dependencies": {
+ "fault": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz",
+ "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.0",
+ "micromark-extension-gfm-autolink-literal": "~0.5.0",
+ "micromark-extension-gfm-strikethrough": "~0.6.5",
+ "micromark-extension-gfm-table": "~0.4.0",
+ "micromark-extension-gfm-tagfilter": "~0.3.0",
+ "micromark-extension-gfm-task-list-item": "~0.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz",
+ "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-strikethrough": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz",
+ "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz",
+ "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-tagfilter": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz",
+ "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-task-list-item": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz",
+ "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark": "~2.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -6004,11 +7841,44 @@
"license": "MIT",
"optional": true
},
+ "node_modules/moji": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/moji/-/moji-0.5.1.tgz",
+ "integrity": "sha512-xYylXOjBS9mE/d690InK3Y74NpE0El0TmAKDmKJveWk9jds/0Tl7MQP4yhavS0U64diEq+5ey2905nhCpIHE+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^3.0.0"
+ }
+ },
+ "node_modules/morpheme-match": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/morpheme-match/-/morpheme-match-2.0.4.tgz",
+ "integrity": "sha512-C3U5g2h47dpztGVePLA8w2O1aQEvuJORwIcahWaCG91YPrq+0u7qcPsF9Nqqe8noFvHwgO7b2EEk3iPnYuGTew==",
+ "license": "MIT"
+ },
+ "node_modules/morpheme-match-all": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/morpheme-match-all/-/morpheme-match-all-2.0.5.tgz",
+ "integrity": "sha512-a6B6Nh4AhjMoEzVz8NOT5M9f3XwFVPM395gqnFNUXG/KTqQFTb9qM5JJFHJe+SvWfRVXTZSejyXNt+h+jmHUuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "morpheme-match": "^2.0.4"
+ }
+ },
+ "node_modules/morpheme-match-textlint": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/morpheme-match-textlint/-/morpheme-match-textlint-2.0.6.tgz",
+ "integrity": "sha512-CX+iQaUjjPMLvas+hZ8zg6Csxx5j1RLaytr+5w6lpBi/oTEV2pv6sgW5Vu3+pNJHbYcaqcuofQZsKocMNUNH8g==",
+ "license": "MIT",
+ "dependencies": {
+ "morpheme-match": "^2.0.4",
+ "morpheme-match-all": "^2.0.5"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/msw": {
@@ -6142,6 +8012,18 @@
"license": "MIT",
"optional": true
},
+ "node_modules/node-localstorage": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-2.2.1.tgz",
+ "integrity": "sha512-vv8fJuOUCCvSPjDjBLlMqYMHob4aGjkmrkaE42/mZr0VT+ZAU10jRF8oTnX9+pgU9/vYJ8P7YT3Vd6ajkmzSCw==",
+ "license": "MIT",
+ "dependencies": {
+ "write-file-atomic": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.27",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
@@ -6149,12 +8031,66 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/object-assign": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+ "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-is": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+ "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -6248,6 +8184,13 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/outvariant": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
@@ -6255,6 +8198,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -6300,6 +8260,24 @@
"node": ">=6"
}
},
+ "node_modules/parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/parse-json": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz",
@@ -6354,6 +8332,13 @@
"node": ">= 0.8"
}
},
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -6488,6 +8473,15 @@
"node": ">=4"
}
},
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -6609,6 +8603,36 @@
"license": "MIT",
"peer": true
},
+ "node_modules/prh": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/prh/-/prh-6.0.6.tgz",
+ "integrity": "sha512-WJ7aaIa37vwHYg5sa1VaqykJiO/6AEkbQOTEnp/52XDXnbMcBPY1++oeV5trjFrLbiTqJY5nO5BaR/MR5ioJHw==",
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^14.0.3",
+ "diff": "^9.0.0",
+ "js-yaml": "^4.1.0"
+ },
+ "bin": {
+ "prh": "bin/prh"
+ },
+ "engines": {
+ "node": ">=22"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -6927,6 +8951,152 @@
"redux": "^5.0.0"
}
},
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regx": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/regx/-/regx-1.0.4.tgz",
+ "integrity": "sha512-Z/5ochRUyD5TkJgFq+66ajKePlj6KzpSLfDO2lOLOLu7E82xAjNux0m8mx1DAXBj5ECHiRCBWoqL25b4lkwcgw==",
+ "license": "MIT"
+ },
+ "node_modules/rehype-parse": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-6.0.2.tgz",
+ "integrity": "sha512-0S3CpvpTAgGmnz8kiCyFLGuW5yA4OQhyNTm/nwPopZ7+PI11WnGl1TTWTGv/2hPEe/g2jRLlhVVSsoDH8waRug==",
+ "license": "MIT",
+ "dependencies": {
+ "hast-util-from-parse5": "^5.0.0",
+ "parse5": "^5.0.0",
+ "xtend": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-parse/node_modules/parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "license": "MIT"
+ },
+ "node_modules/remark-footnotes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz",
+ "integrity": "sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-footnote": "^0.1.0",
+ "micromark-extension-footnote": "^0.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-frontmatter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz",
+ "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-frontmatter": "^0.2.0",
+ "micromark-extension-frontmatter": "^0.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-gfm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz",
+ "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-gfm": "^0.1.0",
+ "micromark-extension-gfm": "^0.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz",
+ "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-from-markdown": "^0.8.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -6970,6 +9140,15 @@
"node": ">=4"
}
},
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
"node_modules/rettime": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/rettime/-/rettime-0.10.1.tgz",
@@ -7060,6 +9239,25 @@
"tslib": "^2.1.0"
}
},
+ "node_modules/safe-array-concat": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
+ "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -7081,6 +9279,48 @@
"license": "MIT",
"optional": true
},
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+ "license": "MIT",
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -7147,6 +9387,22 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/sentence-splitter": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/sentence-splitter/-/sentence-splitter-5.0.1.tgz",
+ "integrity": "sha512-Eu9l95hQfI0WdhXTznuBzqsFjTuL6UnPq341Ro1s2bjE3DMoBuhE0wk4z+rwbwVXfOAeuOQM0UF30HR2+66VuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1",
+ "structured-source": "^4.0.0"
+ }
+ },
+ "node_modules/sentence-splitter/node_modules/@textlint/ast-node-types": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-13.4.1.tgz",
+ "integrity": "sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==",
+ "license": "MIT"
+ },
"node_modules/serve-static": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
@@ -7173,6 +9429,52 @@
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -7278,7 +9580,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -7298,7 +9599,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -7315,7 +9615,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -7334,7 +9633,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -7417,6 +9715,15 @@
"simple-concat": "^1.0.0"
}
},
+ "node_modules/slide": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
+ "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
+ "license": "ISC",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -7427,6 +9734,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -7451,6 +9774,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/strict-event-emitter": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
@@ -7468,19 +9804,75 @@
"safe-buffer": "~5.2.0"
}
},
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"license": "MIT",
"dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/strip-ansi": {
@@ -7522,6 +9914,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/structured-source": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-4.0.0.tgz",
+ "integrity": "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boundary": "^2.0.0"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7560,29 +9961,574 @@
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"license": "MIT",
- "optional": true,
+ "optional": true,
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/textlint-rule-helper": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-helper/-/textlint-rule-helper-2.5.0.tgz",
+ "integrity": "sha512-QIbFPtyqLy0g5BJn8mryk9iHzGYicNaFIpLFPiEnb4RXxrEGeQ2W2aARQ9yEXLIAqo+OwK4ndWBAWkbgJEPzTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^15.2.1",
+ "structured-source": "^4.0.0",
+ "unist-util-visit": "^2.0.3"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-no-abusage/-/textlint-rule-ja-no-abusage-3.0.0.tgz",
+ "integrity": "sha512-DIqPZgYTwTsvjX6Bgj7GA8vlwGMObagJpNoUtkucOaoy7E7GwUOL+knqFjcTtlkWSmoKpIkw5OWW5CV3kivlfQ==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "morpheme-match-textlint": "^2.0.6",
+ "textlint-rule-prh": "^5.3.0"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage/node_modules/diff": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
+ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage/node_modules/prh": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/prh/-/prh-5.4.4.tgz",
+ "integrity": "sha512-UATF+R/2H8owxwPvF12Knihu9aYGTuZttGHrEEq5NBWz38mREh23+WvCVKX3fhnIZIMV7ye6E1fnqAl+V6WYEw==",
+ "license": "MIT",
+ "dependencies": {
+ "commandpost": "^1.2.1",
+ "diff": "^4.0.1",
+ "js-yaml": "^3.9.1"
+ },
+ "bin": {
+ "prh": "bin/prh"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-abusage/node_modules/textlint-rule-prh": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-prh/-/textlint-rule-prh-5.3.0.tgz",
+ "integrity": "sha512-gdod+lL1SWUDyXs1ICEwvQawaSshT3mvPGufBIjF2R5WFPdKQDMsiuzsjkLm+aF+9d97dA6pFsiyC8gSW7mSgg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.7.5",
+ "prh": "^5.4.4",
+ "textlint-rule-helper": "^2.1.1",
+ "untildify": "^3.0.3"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-mixed-period": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-no-mixed-period/-/textlint-rule-ja-no-mixed-period-3.0.2.tgz",
+ "integrity": "sha512-/WHRvbAXPJxjDAmVYjIp5qBHPS7Uqv3H+fH0oGMWzujEV4n2URtXmxqTUv7nd4giTRqeV2yuMZWYRRgA9Mh0Sg==",
+ "license": "MIT",
+ "dependencies": {
+ "check-ends-with-period": "^3.0.2",
+ "textlint-rule-helper": "^2.2.4"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-redundant-expression": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-no-redundant-expression/-/textlint-rule-ja-no-redundant-expression-4.0.1.tgz",
+ "integrity": "sha512-r8Qe6S7u9N97wD0gcrASqBUdZs5CMEVlgc8Ul+D2NQFiOi1BoseOMo5I9yUsEZMAL46yh/eaw9+EWz6IDlPWeA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/regexp-string-matcher": "^1.1.0",
+ "kuromojin": "^3.0.0",
+ "morpheme-match": "^2.0.4",
+ "morpheme-match-all": "^2.0.5",
+ "textlint-rule-helper": "^2.2.1",
+ "textlint-util-to-string": "^3.1.1"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-successive-word": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-no-successive-word/-/textlint-rule-ja-no-successive-word-2.0.1.tgz",
+ "integrity": "sha512-XKTXkHwMu86SnGaj73B67U4apDdTquDKF3SfG24tRbzMyJoGe/Iba5VMId8sp8QHeTonp1bYOSxjZsbkpGyCNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/regexp-string-matcher": "^1.1.0",
+ "kuromojin": "^3.0.0"
+ }
+ },
+ "node_modules/textlint-rule-ja-no-weak-phrase": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-no-weak-phrase/-/textlint-rule-ja-no-weak-phrase-2.0.0.tgz",
+ "integrity": "sha512-jZ1/3VnE8Bz/p0CCe/+BVOmWE1cZwpDkjKb6hnq39nGk3OD4XPW7biYavK/4/mZhk4bh2+Vtu1xV26lg8d+vBw==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "morpheme-match": "^2.0.4",
+ "morpheme-match-all": "^2.0.5"
+ }
+ },
+ "node_modules/textlint-rule-ja-unnatural-alphabet": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-ja-unnatural-alphabet/-/textlint-rule-ja-unnatural-alphabet-2.0.1.tgz",
+ "integrity": "sha512-n93V8qh6OKdh8OB6yLT+9Xl8DSoZ7gWi51tWdhlLEPIWgBm18nLMgm6Ck+nVc3eENOdRcQURWUpCGotI8wTemA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/regexp-string-matcher": "^1.0.2",
+ "match-index": "^1.0.1",
+ "regx": "^1.0.4"
+ }
+ },
+ "node_modules/textlint-rule-max-comma": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-max-comma/-/textlint-rule-max-comma-4.0.0.tgz",
+ "integrity": "sha512-2vKKXNg1YuTqr9/FrHvOGEHFe+6lNSDtzuEv+KRB+tuaj++UNa/YPvyY34UdDYuHUSKNcYdto8GlIUhAJDW9WQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sentence-splitter": "^5.0.0",
+ "textlint-util-to-string": "^3.3.4"
+ }
+ },
+ "node_modules/textlint-rule-max-kanji-continuous-len": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-max-kanji-continuous-len/-/textlint-rule-max-kanji-continuous-len-1.1.1.tgz",
+ "integrity": "sha512-os+p7dS9Op4PtZV7B9/wnzN5qpDO2WR2kj7nTnqEPbApS06AXX+qf5eH3fKdm4blzUCcPF5ozMN8zbs3AJUAug==",
+ "license": "MIT",
+ "dependencies": {
+ "match-index": "^1.0.1",
+ "textlint-rule-helper": "^2.0.0"
+ }
+ },
+ "node_modules/textlint-rule-max-ten": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-max-ten/-/textlint-rule-max-ten-5.0.0.tgz",
+ "integrity": "sha512-EWOvbEa3Ukxz0+GAUEJ91DYFSC3IkyJ10dBcsU6VlL33k1BvTRoFr3m26w6upnXJffXQUI70Etn39I++2duyhA==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1",
+ "textlint-util-to-string": "^3.3.4"
+ }
+ },
+ "node_modules/textlint-rule-no-double-negative-ja": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-double-negative-ja/-/textlint-rule-no-double-negative-ja-2.0.1.tgz",
+ "integrity": "sha512-LRofmNt+nd2mp+AHmG0ltk9AlbzKbWPE+EToYQ1zORCd8N8suE1YxNEplz9OeQ59ea9ITtudDIWoqeHaZnbDsg==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0"
+ }
+ },
+ "node_modules/textlint-rule-no-doubled-conjunction": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-doubled-conjunction/-/textlint-rule-no-doubled-conjunction-3.0.1.tgz",
+ "integrity": "sha512-fRJEiy0rkrmUDVdgzGiUKAgGngziUfsjL4eqY4a3YfFxXwtczOP+hyHfvLNrHOUI58Y6lNoLZpa5lNNXbzFyNg==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1"
+ }
+ },
+ "node_modules/textlint-rule-no-doubled-conjunctive-particle-ga": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-doubled-conjunctive-particle-ga/-/textlint-rule-no-doubled-conjunctive-particle-ga-3.0.0.tgz",
+ "integrity": "sha512-4IowX2YlTlD9VifThZwpENRh918BpPNTks0i4bOL7Gn82jUiXK0EZuV8Jtksm7i+RYG1xsO0U7P9AnxmuSxeDg==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1",
+ "textlint-util-to-string": "^3.3.4"
+ }
+ },
+ "node_modules/textlint-rule-no-doubled-joshi": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-doubled-joshi/-/textlint-rule-no-doubled-joshi-5.1.1.tgz",
+ "integrity": "sha512-bxiuqZiHE9ZZGHDX+O6J4vzhre7ghb7NBkPi/5TAWVvnQLULgY3COx/KXJgFItPmSrpYF8/AT/uTHC4QOg59qw==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1",
+ "textlint-util-to-string": "^3.3.4"
+ }
+ },
+ "node_modules/textlint-rule-no-dropping-the-ra": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-dropping-the-ra/-/textlint-rule-no-dropping-the-ra-3.0.0.tgz",
+ "integrity": "sha512-KbSIlcxj1kLs4sGSMSLGA8OmgRoaPAWtodJaGEyEUiy7uiZM/VPqYALpuD8vf16N1OR5SM/bXXeZFME65r8ZgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "kuromojin": "^3.0.0",
+ "textlint-rule-helper": "^2.1.1"
+ }
+ },
+ "node_modules/textlint-rule-no-exclamation-question-mark": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-exclamation-question-mark/-/textlint-rule-no-exclamation-question-mark-1.1.0.tgz",
+ "integrity": "sha512-FcBH3uH2qp5VG7I9LKwolUCcPigONcsdam1JhAFPcu10YZNYX0r1l2y9Hzg+E4+1fXLgtGyiObWwfsfelTx8Bw==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/regexp-string-matcher": "^1.1.0",
+ "match-index": "^1.0.3",
+ "textlint-rule-helper": "^2.1.1"
+ }
+ },
+ "node_modules/textlint-rule-no-hankaku-kana": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-hankaku-kana/-/textlint-rule-no-hankaku-kana-2.0.1.tgz",
+ "integrity": "sha512-39s94HK6V1xnII1haYiYQnWy1YQAKK7Zj0mcpUMFHHC4M5JdsRnhGs6DQPVEff0gQIFV0iuDNlofXt15kjMtEA==",
+ "license": "MIT",
+ "dependencies": {
+ "textlint-rule-helper": "^2.3.0",
+ "textlint-tester": "^13.3.1"
+ }
+ },
+ "node_modules/textlint-rule-no-mix-dearu-desumasu": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-mix-dearu-desumasu/-/textlint-rule-no-mix-dearu-desumasu-6.0.4.tgz",
+ "integrity": "sha512-SmALtOFbtmJ//k2iLMvtqhGrgJ/6uDVZFK7TBj2npVAbt10VxgLL87K+62pQ/BqiN9DpOVObshVFdug7lUOKHw==",
+ "license": "MIT",
+ "dependencies": {
+ "analyze-desumasu-dearu": "^5.0.2",
+ "textlint-rule-helper": "^2.3.1"
+ }
+ },
+ "node_modules/textlint-rule-no-nfd": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-nfd/-/textlint-rule-no-nfd-2.0.2.tgz",
+ "integrity": "sha512-lIUvcQ+wqtConpPQU2YwEJl2dRcRyyrxPYZ3V76UwnkVg++XPLIrE5mLDgyNE/UIQ34e/KitJfMLqKWvnkFbNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "match-index": "^1.0.3",
+ "textlint-rule-helper": "^2.3.0"
+ }
+ },
+ "node_modules/textlint-rule-no-zero-width-spaces": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-no-zero-width-spaces/-/textlint-rule-no-zero-width-spaces-1.0.1.tgz",
+ "integrity": "sha512-AkxpzBILGB4YsXddzHx2xqpXmqMv5Yd+PQm4anUV+ADSJuwLP1Jd6yHf/LOtu9j3ps8K3XM9vQrXRK73z0bU3A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/hata6502"
+ }
+ },
+ "node_modules/textlint-rule-preset-ja-technical-writing": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/textlint-rule-preset-ja-technical-writing/-/textlint-rule-preset-ja-technical-writing-12.0.2.tgz",
+ "integrity": "sha512-BBVY6oA5V799k5wRfP+gCpDHsp6vWjWX2UT+/KLlAFFsNdmRB8Z6qyOnqiOjfzmLGIRgoMcPI1dXj5upOqnD6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint-rule/textlint-rule-no-invalid-control-character": "^3.0.0",
+ "@textlint-rule/textlint-rule-no-unmatched-pair": "^2.0.4",
+ "@textlint/module-interop": "^14.4.0",
+ "textlint-rule-ja-no-abusage": "^3.0.0",
+ "textlint-rule-ja-no-mixed-period": "^3.0.1",
+ "textlint-rule-ja-no-redundant-expression": "^4.0.1",
+ "textlint-rule-ja-no-successive-word": "^2.0.1",
+ "textlint-rule-ja-no-weak-phrase": "^2.0.0",
+ "textlint-rule-ja-unnatural-alphabet": "2.0.1",
+ "textlint-rule-max-comma": "^4.0.0",
+ "textlint-rule-max-kanji-continuous-len": "^1.1.1",
+ "textlint-rule-max-ten": "^5.0.0",
+ "textlint-rule-no-double-negative-ja": "^2.0.1",
+ "textlint-rule-no-doubled-conjunction": "^3.0.0",
+ "textlint-rule-no-doubled-conjunctive-particle-ga": "^3.0.0",
+ "textlint-rule-no-doubled-joshi": "^5.1.0",
+ "textlint-rule-no-dropping-the-ra": "^3.0.0",
+ "textlint-rule-no-exclamation-question-mark": "^1.1.0",
+ "textlint-rule-no-hankaku-kana": "^2.0.1",
+ "textlint-rule-no-mix-dearu-desumasu": "^6.0.3",
+ "textlint-rule-no-nfd": "^2.0.2",
+ "textlint-rule-no-zero-width-spaces": "^1.0.1",
+ "textlint-rule-preset-jtf-style": "^3.0.1",
+ "textlint-rule-sentence-length": "^5.2.0"
+ }
+ },
+ "node_modules/textlint-rule-preset-jtf-style": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/textlint-rule-preset-jtf-style/-/textlint-rule-preset-jtf-style-3.0.3.tgz",
+ "integrity": "sha512-NTvqjg3oMTGjSDoH6MnYu+DDWW6cEghA66Lb8N0bheTphAj99aaG10HGhwTfDbaH2P6NfPQvRP5ISxiXCT9zdg==",
+ "license": "MIT",
+ "dependencies": {
+ "analyze-desumasu-dearu": "^2.1.2",
+ "japanese-numerals-to-number": "^1.0.2",
+ "match-index": "^1.0.3",
+ "moji": "^0.5.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "regx": "^1.0.4",
+ "textlint-rule-helper": "^2.3.1",
+ "textlint-rule-prh": "^6.0.0"
+ }
+ },
+ "node_modules/textlint-rule-preset-jtf-style/node_modules/analyze-desumasu-dearu": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/analyze-desumasu-dearu/-/analyze-desumasu-dearu-2.1.5.tgz",
+ "integrity": "sha512-4YPL7IRAuaZflE10+BVhKr6k5KQl/DiLeNCIF7ISqKr0ogM2hqm9ztRNCPqL/xYDI7hfuIHR8T+U7mIDRLQNXw==",
+ "license": "MIT"
+ },
+ "node_modules/textlint-rule-prh": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/textlint-rule-prh/-/textlint-rule-prh-6.1.0.tgz",
+ "integrity": "sha512-KrchADHw1/LZ/tAQ2XwL/XdUhunKCvlNmwgp+6hdyzuWX7uojOkDdJWWV0KAN4XWsK6Te5w/SZcYwQ7X6i3B0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.27.0",
+ "prh": "^5.4.4",
+ "textlint-rule-helper": "^2.3.1"
+ }
+ },
+ "node_modules/textlint-rule-prh/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/textlint-rule-prh/node_modules/diff": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
+ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/textlint-rule-prh/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/textlint-rule-prh/node_modules/prh": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/prh/-/prh-5.4.4.tgz",
+ "integrity": "sha512-UATF+R/2H8owxwPvF12Knihu9aYGTuZttGHrEEq5NBWz38mREh23+WvCVKX3fhnIZIMV7ye6E1fnqAl+V6WYEw==",
+ "license": "MIT",
+ "dependencies": {
+ "commandpost": "^1.2.1",
+ "diff": "^4.0.1",
+ "js-yaml": "^3.9.1"
+ },
+ "bin": {
+ "prh": "bin/prh"
+ }
+ },
+ "node_modules/textlint-rule-sentence-length": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/textlint-rule-sentence-length/-/textlint-rule-sentence-length-5.2.1.tgz",
+ "integrity": "sha512-z4HylabPy+e1I5DcuzDmcT65hvyytTlsD+uM49JkCBTSJBWqzQQ3kCGk4b1cF+kANS2HifWNnpTG/jfSOeavIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/regexp-string-matcher": "^2.0.2",
+ "sentence-splitter": "^5.0.0",
+ "textlint-rule-helper": "^2.3.1",
+ "textlint-util-to-string": "^3.3.4"
+ }
+ },
+ "node_modules/textlint-rule-sentence-length/node_modules/@textlint/regexp-string-matcher": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@textlint/regexp-string-matcher/-/regexp-string-matcher-2.0.2.tgz",
+ "integrity": "sha512-OXLD9XRxMhd3S0LWuPHpiARQOI7z9tCOs0FsynccW2lmyZzHHFJ9/eR6kuK9xF459Qf+740qI5h+/0cx+NljzA==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0",
+ "lodash.sortby": "^4.7.0",
+ "lodash.uniq": "^4.5.0",
+ "lodash.uniqwith": "^4.5.0"
+ }
+ },
+ "node_modules/textlint-tester": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/textlint-tester/-/textlint-tester-13.4.1.tgz",
+ "integrity": "sha512-Ubm9kUZ/NyY0Ggo1RkW2o5QSx6EJ/ogMT1kD5b5pk4cdFTWpUSs8StDMROgcz29wPhvS6sY/35qYALzqyZh8ew==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/feature-flag": "^13.4.1",
+ "@textlint/kernel": "^13.4.1",
+ "@textlint/textlint-plugin-markdown": "^13.4.1",
+ "@textlint/textlint-plugin-text": "^13.4.1"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/ast-node-types": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-13.4.1.tgz",
+ "integrity": "sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==",
+ "license": "MIT"
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/ast-tester": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-tester/-/ast-tester-13.4.1.tgz",
+ "integrity": "sha512-YSHUR1qDgMPGF5+nvrquEhif6zRJ667xUnfP/9rTNtThIhoTQINvczr5/7xa43F1PDWplL6Curw+2jrE1qHwGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1",
+ "debug": "^4.3.4"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/ast-traverse": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-traverse/-/ast-traverse-13.4.1.tgz",
+ "integrity": "sha512-uucuC7+NHWkXx2TX5vuyreuHeb+GFiA83V65I+FnYP5EC4dAMOQ86rTSPrZmCwLz+qIWgfDgihGzPccpj3EZGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/feature-flag": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/feature-flag/-/feature-flag-13.4.1.tgz",
+ "integrity": "sha512-qY8gKUf30XtzWMTkwYeKytCo6KPx6milpz8YZhuRsEPjT/5iNdakJp5USWDQWDrwbQf7RbRncQdU+LX5JbM9YA==",
+ "license": "MIT"
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/kernel": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/kernel/-/kernel-13.4.1.tgz",
+ "integrity": "sha512-r2sUhjPysFjl2Ax37x9AfWkJM8jgKN0bL4SX3xRzOukdcj69Dst5On5qBZtULaVMX1LDkwkdxA6ZEADmq27qQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1",
+ "@textlint/ast-tester": "^13.4.1",
+ "@textlint/ast-traverse": "^13.4.1",
+ "@textlint/feature-flag": "^13.4.1",
+ "@textlint/source-code-fixer": "^13.4.1",
+ "@textlint/types": "^13.4.1",
+ "@textlint/utils": "^13.4.1",
+ "debug": "^4.3.4",
+ "fast-equals": "^4.0.3",
+ "structured-source": "^4.0.0"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/source-code-fixer": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/source-code-fixer/-/source-code-fixer-13.4.1.tgz",
+ "integrity": "sha512-Sl29f3Tpimp0uVE3ysyJBjxaFTVYLOXiJX14eWCQ/kC5ZhIXGosEbStzkP1n8Urso1rs1W4p/2UemVAm3NH2ng==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/types": "^13.4.1",
+ "debug": "^4.3.4"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/text-to-ast": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/text-to-ast/-/text-to-ast-13.4.1.tgz",
+ "integrity": "sha512-vCA7uMmbjRv06sEHPbwxTV5iS8OQedC5s7qwmXnWAn2LLWxg4Yp98mONPS1o4D5cPomzYyKNCSfbLwu6yJBUQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/textlint-plugin-text": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/textlint-plugin-text/-/textlint-plugin-text-13.4.1.tgz",
+ "integrity": "sha512-z0p5B8WUfTCIRmhjVHFfJv719oIElDDKWOIZei4CyYkfMGo0kq8fkrYBkUR6VZ6gofHwc+mwmIABdUf1rDHzYA==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/text-to-ast": "^13.4.1"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/types": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/types/-/types-13.4.1.tgz",
+ "integrity": "sha512-1ApwQa31sFmiJeJ5yTNFqjbb2D1ICZvIDW0tFSM0OtmQCSDFNcKD3YrrwDBgSokZ6gWQq/FpNjlhi6iETUWt0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@textlint/ast-node-types": "^13.4.1"
+ }
+ },
+ "node_modules/textlint-tester/node_modules/@textlint/utils": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/utils/-/utils-13.4.1.tgz",
+ "integrity": "sha512-wX8RT1ejHAPTDmqlzngf0zI5kYoe3QvGDcj+skoTxSv+m/wOs/NyEr92d+ahCP32YqFYzXlqU7aDx2FkULKT+g==",
+ "license": "MIT"
+ },
+ "node_modules/textlint-util-to-string": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/textlint-util-to-string/-/textlint-util-to-string-3.3.4.tgz",
+ "integrity": "sha512-XF4Qfw0ES+czKy03BwuvBUoXC8NAg920VuRxW0pd72fW76zMeMbPI/bRN5PHq3SbCdOm7U69/Pk+DX34xqIYqA==",
+ "license": "MIT",
"dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
+ "@textlint/ast-node-types": "^13.4.1",
+ "rehype-parse": "^6.0.1",
+ "structured-source": "^4.0.0",
+ "unified": "^8.4.0"
}
},
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "node_modules/textlint-util-to-string/node_modules/@textlint/ast-node-types": {
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-13.4.1.tgz",
+ "integrity": "sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==",
+ "license": "MIT"
+ },
+ "node_modules/textlint-util-to-string/node_modules/unified": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz",
+ "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==",
"license": "MIT",
- "optional": true,
"dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
},
- "engines": {
- "node": ">=6"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
}
},
"node_modules/tiny-invariant": {
@@ -7655,6 +10601,21 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -7704,6 +10665,23 @@
"node": ">=20"
}
},
+ "node_modules/traverse": {
+ "version": "0.6.11",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz",
+ "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==",
+ "license": "MIT",
+ "dependencies": {
+ "gopd": "^1.2.0",
+ "typedarray.prototype.slice": "^1.0.5",
+ "which-typed-array": "^1.1.18"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
@@ -7714,6 +10692,16 @@
"tree-kill": "cli.js"
}
},
+ "node_modules/trough": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
+ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
@@ -7791,6 +10779,102 @@
"node": ">= 0.6"
}
},
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz",
+ "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "for-each": "^0.3.5",
+ "gopd": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "possible-typed-array-names": "^1.1.0",
+ "reflect.getprototypeof": "^1.0.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typedarray.prototype.slice": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz",
+ "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "math-intrinsics": "^1.1.0",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -7829,6 +10913,24 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/undici": {
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz",
@@ -7856,6 +10958,76 @@
"pathe": "^2.0.3"
}
},
+ "node_modules/unified": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz",
+ "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-buffer": "^2.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0",
+ "unist-util-visit-parents": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -7876,6 +11048,15 @@
"url": "https://github.com/sponsors/kettanaito"
}
},
+ "node_modules/untildify": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz",
+ "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
@@ -7933,6 +11114,20 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -7950,6 +11145,36 @@
"node": ">= 0.8"
}
},
+ "node_modules/vfile": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
+ "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/victory-vendor": {
"version": "37.3.6",
"resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz",
@@ -8151,6 +11376,16 @@
"loose-envify": "^1.0.0"
}
},
+ "node_modules/web-namespaces": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz",
+ "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/webidl-conversions": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
@@ -8202,6 +11437,91 @@
"node": ">= 8"
}
},
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.21",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.21.tgz",
+ "integrity": "sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==",
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/why-is-node-running": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
@@ -8791,6 +12111,17 @@
"devOptional": true,
"license": "ISC"
},
+ "node_modules/write-file-atomic": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz",
+ "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==",
+ "license": "ISC",
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "slide": "^1.1.5"
+ }
+ },
"node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
@@ -8830,6 +12161,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -8934,6 +12274,15 @@
"error-stack-parser-es": "^1.0.5"
}
},
+ "node_modules/zlibjs": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
+ "integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/zod": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
@@ -8956,6 +12305,16 @@
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
+ },
+ "node_modules/zwitch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz",
+ "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
}
}
}
diff --git a/frontend/package.json b/frontend/package.json
index 1eb1842e..2c82e4d0 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -21,15 +21,20 @@
},
"dependencies": {
"@reduxjs/toolkit": "^2.11.2",
+ "@textlint/kernel": "^15.7.1",
+ "@textlint/textlint-plugin-text": "^15.7.1",
"dompurify": "^3.4.7",
"marked": "^17.0.4",
+ "prh": "^6.0.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-pdf": "^9.2.1",
"react-redux": "^9.2.0",
"react-router-dom": "^7.13.1",
"recharts": "^3.8.0",
- "redux-persist": "^6.0.0"
+ "redux-persist": "^6.0.0",
+ "textlint-rule-preset-ja-technical-writing": "^12.0.2",
+ "textlint-rule-prh": "^6.1.0"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
@@ -37,11 +42,13 @@
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
+ "@textlint/types": "^15.7.1",
"@types/node": "^25.5.2",
"@types/react": "^18.3.15",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/coverage-v8": "^4.1.2",
+ "assert": "^2.1.0",
"concurrently": "^9.2.1",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
@@ -52,6 +59,8 @@
"jsdom": "^29.0.1",
"msw": "^2.13.2",
"openapi-typescript": "^7.13.0",
+ "os-browserify": "^0.3.0",
+ "path-browserify": "^1.0.1",
"playwright": "^1.56.0",
"prettier": "^3.8.1",
"typescript": "^5.7.2",
diff --git a/frontend/public/_headers b/frontend/public/_headers
new file mode 100644
index 00000000..dad4c164
--- /dev/null
+++ b/frontend/public/_headers
@@ -0,0 +1,7 @@
+# kuromoji(校正機能の形態素解析)辞書の配信ヘッダ(Cloudflare Pages 用)。
+# .gz を gzip 転送エンコーディング扱いさせず、生の gzip バイト列として返す
+# (kuromoji が自前で gunzip するため)。octet-stream 指定で edge の自動圧縮も避ける。
+# 辞書は不変なので長期キャッシュする。
+/kuromoji-dict/*
+ Content-Type: application/octet-stream
+ Cache-Control: public, max-age=31536000, immutable
diff --git a/frontend/public/kuromoji-dict/base.dat.gz b/frontend/public/kuromoji-dict/base.dat.gz
new file mode 100644
index 00000000..917954c3
Binary files /dev/null and b/frontend/public/kuromoji-dict/base.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/cc.dat.gz b/frontend/public/kuromoji-dict/cc.dat.gz
new file mode 100644
index 00000000..7d867067
Binary files /dev/null and b/frontend/public/kuromoji-dict/cc.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/check.dat.gz b/frontend/public/kuromoji-dict/check.dat.gz
new file mode 100644
index 00000000..7e977a10
Binary files /dev/null and b/frontend/public/kuromoji-dict/check.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/tid.dat.gz b/frontend/public/kuromoji-dict/tid.dat.gz
new file mode 100644
index 00000000..195a8707
Binary files /dev/null and b/frontend/public/kuromoji-dict/tid.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/tid_map.dat.gz b/frontend/public/kuromoji-dict/tid_map.dat.gz
new file mode 100644
index 00000000..d04bba3b
Binary files /dev/null and b/frontend/public/kuromoji-dict/tid_map.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/tid_pos.dat.gz b/frontend/public/kuromoji-dict/tid_pos.dat.gz
new file mode 100644
index 00000000..e4d5cffd
Binary files /dev/null and b/frontend/public/kuromoji-dict/tid_pos.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk.dat.gz b/frontend/public/kuromoji-dict/unk.dat.gz
new file mode 100644
index 00000000..83464686
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk_char.dat.gz b/frontend/public/kuromoji-dict/unk_char.dat.gz
new file mode 100644
index 00000000..8b7693a3
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk_char.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk_compat.dat.gz b/frontend/public/kuromoji-dict/unk_compat.dat.gz
new file mode 100644
index 00000000..87030e97
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk_compat.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk_invoke.dat.gz b/frontend/public/kuromoji-dict/unk_invoke.dat.gz
new file mode 100644
index 00000000..c6736eba
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk_invoke.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk_map.dat.gz b/frontend/public/kuromoji-dict/unk_map.dat.gz
new file mode 100644
index 00000000..12d427bf
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk_map.dat.gz differ
diff --git a/frontend/public/kuromoji-dict/unk_pos.dat.gz b/frontend/public/kuromoji-dict/unk_pos.dat.gz
new file mode 100644
index 00000000..50bb65de
Binary files /dev/null and b/frontend/public/kuromoji-dict/unk_pos.dat.gz differ
diff --git a/frontend/src/components/forms/CareerDiffModal.module.css b/frontend/src/components/forms/CareerDiffModal.module.css
index 3befaf3a..b5e32263 100644
--- a/frontend/src/components/forms/CareerDiffModal.module.css
+++ b/frontend/src/components/forms/CareerDiffModal.module.css
@@ -106,6 +106,10 @@
.sidebarHead {
flex-shrink: 0;
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ gap: 0.5rem;
padding: 0.4rem 0.7rem;
font-size: 0.8rem;
font-weight: 700;
@@ -120,37 +124,45 @@
overflow-y: auto;
display: flex;
flex-direction: column;
- gap: 0.4rem;
+ gap: 0.5rem;
+ flex: 1 1 auto;
+ min-height: 0;
}
-.row {
+/* 1 フィールド分のレビュー項目(差分+校正をまとめたカード)。 */
+.entry {
display: flex;
- align-items: stretch;
- gap: 0.4rem;
+ flex-direction: column;
border: 1px solid var(--border-color, #e0e0e0);
border-radius: 6px;
overflow: hidden;
}
-/* 行本体はクリックでスクロールするボタン。装飾はテキストブロック風に戻す。 */
-.rowMain {
- flex: 1;
- min-width: 0;
+/* 見出し(クリックで右ペインの該当箇所へスクロール)。 */
+.entryHead {
text-align: left;
- background: transparent;
+ background: var(--bg-page, #f7f7f8);
color: inherit;
border: none;
- border-radius: 0;
- padding: 0.45rem 0.55rem;
- font-weight: 400;
+ border-bottom: 1px solid var(--border-color, #ececec);
+ padding: 0.35rem 0.55rem;
cursor: pointer;
}
-.rowHead {
+/* 差分行: バッジ+旧→新 と 元に戻すボタン。 */
+.entryDiff {
display: flex;
align-items: center;
gap: 0.4rem;
- margin-bottom: 0.2rem;
+ padding: 0.35rem 0.5rem 0.35rem 0.55rem;
+}
+
+.diffMain {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
}
.badge {
@@ -177,7 +189,7 @@
.label {
font-size: 0.78rem;
font-weight: 600;
- word-break: break-word;
+ overflow-wrap: break-word;
}
.values {
@@ -191,7 +203,7 @@
.oldValue {
color: var(--text-muted, #888);
text-decoration: line-through;
- word-break: break-word;
+ overflow-wrap: break-word;
}
.arrow {
@@ -201,14 +213,13 @@
.newValue {
color: var(--text-primary, #111);
font-weight: 500;
- word-break: break-word;
+ overflow-wrap: break-word;
}
/* VSCode の diff の revert 矢印風。各変更行を編集前(保存済み)へ戻すアイコンボタン。 */
.rollback {
flex-shrink: 0;
align-self: center;
- margin-right: 0.4rem;
width: 26px;
height: 26px;
padding: 0;
@@ -243,3 +254,58 @@
padding: 0.75rem 1.25rem;
border-top: 1px solid var(--border-color, #e0e0e0);
}
+
+.proofreadLoading {
+ font-size: 0.7rem;
+ font-weight: 400;
+ color: #3b82f6;
+}
+
+/* 校正の指摘リスト(青系・控えめ)。エントリ内の差分の下に続く。 */
+.entryIssues {
+ list-style: none;
+ margin: 0;
+ padding: 0.3rem 0.5rem 0.4rem 0.55rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.3rem;
+ background: rgba(37, 99, 235, 0.05);
+ border-top: 1px solid rgba(37, 99, 235, 0.18);
+}
+
+.proofreadItem {
+ border-left: 2px solid rgba(37, 99, 235, 0.45);
+ padding-left: 0.45rem;
+}
+
+.proofreadMessage {
+ margin: 0;
+ font-size: 0.74rem;
+ color: var(--text-primary, #1f2937);
+ line-height: 1.4;
+ white-space: pre-wrap;
+ overflow-wrap: break-word;
+}
+
+.proofreadExcerpt {
+ margin: 0.15rem 0 0;
+ font-size: 0.68rem;
+ color: var(--text-muted, #6b7280);
+ overflow-wrap: break-word;
+}
+
+.proofreadEmpty {
+ margin: 0;
+ padding: 0 0.7rem 0.4rem;
+ font-size: 0.74rem;
+ color: var(--text-muted, #6b7280);
+}
+
+.proofreadHint {
+ flex-shrink: 0;
+ margin: 0;
+ padding: 0.35rem 0.7rem 0.5rem;
+ font-size: 0.66rem;
+ color: #2563eb;
+ line-height: 1.4;
+}
diff --git a/frontend/src/components/forms/CareerDiffModal.tsx b/frontend/src/components/forms/CareerDiffModal.tsx
index bf55d039..dae5b985 100644
--- a/frontend/src/components/forms/CareerDiffModal.tsx
+++ b/frontend/src/components/forms/CareerDiffModal.tsx
@@ -1,6 +1,8 @@
import { useMemo, useRef } from "react";
-import { DIFF_DIALOG_MESSAGES as D } from "../../constants/messages";
+import { DIFF_DIALOG_MESSAGES as D, PROOFREAD_MESSAGES as P } from "../../constants/messages";
+import type { ProofreadIssue } from "../../proofread/types";
+import { buildReviewEntries } from "../../utils/careerReview";
import type { CareerChange, ChangeKind } from "../../utils/careerDiff";
import {
annotateHtml,
@@ -20,6 +22,7 @@ const KIND_LABEL: Record = {
/**
* iframe 内に注入する diff 着色 CSS。backend の resume.css に追記する形で srcDoc に埋め込む。
* 緑=追加 / 赤=削除 / 黄=修正。VSCode 系 diff の配色に寄せる。
+ * 校正指摘は青の波線(diff の背景色と重ねても潰れないよう下線で表現)。
*/
const DIFF_CSS = `
body { margin: 0; padding: 12px 16px; background: #fff; }
@@ -27,6 +30,11 @@ const DIFF_CSS = `
.diff-added { background: rgba(22,163,74,0.18); box-shadow: 0 0 0 1px rgba(22,163,74,0.45); }
.diff-removed { background: rgba(220,38,38,0.16); box-shadow: 0 0 0 1px rgba(220,38,38,0.40); }
.diff-modified { background: rgba(234,179,8,0.25); box-shadow: 0 0 0 1px rgba(234,179,8,0.50); }
+ .diff-proofread {
+ text-decoration: underline wavy #2563eb;
+ text-decoration-skip-ink: none;
+ text-underline-offset: 2px;
+ }
details.fold { margin: 3px 0; }
summary.fold-summary {
cursor: pointer; list-style: none; font-size: 8pt; color: #6b7280;
@@ -63,6 +71,9 @@ export function CareerDiffModal({
loading,
error,
saving,
+ issues,
+ proofreading,
+ proofreadError,
onConfirm,
onCancel,
onRollback,
@@ -74,6 +85,12 @@ export function CareerDiffModal({
loading: boolean;
error: string | null;
saving: boolean;
+ /** 編集中フォームの校正指摘(フィールド横断)。 */
+ issues: ProofreadIssue[];
+ /** 校正処理中フラグ。 */
+ proofreading: boolean;
+ /** 校正失敗時のメッセージ(null なら正常)。 */
+ proofreadError: string | null;
onConfirm: () => void;
onCancel: () => void;
onRollback: (change: CareerChange) => void;
@@ -83,7 +100,20 @@ export function CareerDiffModal({
const pathKindMap = useMemo(() => buildPathKindMap(changes), [changes]);
+ /**
+ * 変更点と校正指摘を 1 本のレビュー一覧へ統合し、PDF レイアウト順に並べる。
+ * 左右ペイン(PDF)とサイドバーの縦順が一致し、上から順に突合できる。
+ */
+ const reviewEntries = useMemo(() => buildReviewEntries(changes, issues), [changes, issues]);
+
+ /** 校正指摘のあるフィールド id 集合(編集中ペインの青マーク/折りたたみ除外に使う)。 */
+ const proofreadFieldIds = useMemo(
+ () => new Set(issues.map((issue) => issue.fieldId)),
+ [issues],
+ );
+
// 着色(annotateHtml)→ 変更なし領域を畳む(foldUnchanged)の順で整形する。
+ // baseline(保存済み)側は校正マークを付けない(指摘は編集中フォームに対するもの)。
const baselineDoc = useMemo(() => {
if (baselineHtml === null) return null;
return buildSrcDoc(css, foldUnchanged(annotateHtml(baselineHtml, pathKindMap), pathKindMap));
@@ -91,17 +121,17 @@ export function CareerDiffModal({
const editedDoc = useMemo(() => {
if (editedHtml === null) return null;
- // 着色 → 削除跡のプレースホルダ挿入 → 変更なし領域の折りたたみ、の順で整形する。
- const annotated = annotateHtml(editedHtml, pathKindMap);
+ // 着色(差分+校正青マーク)→ 削除跡のプレースホルダ挿入 → 変更なし領域の折りたたみ。
+ // 校正指摘のある項目は畳まないよう foldUnchanged にも fieldId 集合を渡す。
+ const annotated = annotateHtml(editedHtml, pathKindMap, proofreadFieldIds);
const withStubs = injectRemovedPlaceholders(annotated, changes);
- return buildSrcDoc(css, foldUnchanged(withStubs, pathKindMap));
- }, [editedHtml, css, pathKindMap, changes]);
+ return buildSrcDoc(css, foldUnchanged(withStubs, pathKindMap, proofreadFieldIds));
+ }, [editedHtml, css, pathKindMap, changes, proofreadFieldIds]);
- /** 変更点行クリックで、右ペイン(編集中)の該当ノードへスクロールする。 */
- const scrollToChange = (change: CareerChange) => {
+ /** レビュー項目クリックで、右ペイン(編集中)の該当ノードへスクロールする。 */
+ const scrollToPath = (fp: string) => {
const doc = editedFrameRef.current?.contentDocument;
if (!doc) return;
- const fp = change.path.join(".");
const escaped = CSS.escape(fp);
const target =
doc.querySelector(`[data-fp="${escaped}"]`) ??
@@ -164,50 +194,82 @@ export function CareerDiffModal({
{loading && editedDoc && {D.PREVIEW_LOADING}
}
- {/* 変更点サイドバー */}
+ {/* レビュー一覧: 変更点と校正を 1 本に統合し PDF レイアウト順に並べる。 */}
diff --git a/frontend/src/components/forms/CareerResumeForm.tsx b/frontend/src/components/forms/CareerResumeForm.tsx
index c0176e12..1adc664a 100644
--- a/frontend/src/components/forms/CareerResumeForm.tsx
+++ b/frontend/src/components/forms/CareerResumeForm.tsx
@@ -14,6 +14,7 @@ import { SUCCESS_MESSAGES, UI_MESSAGES } from "../../constants/messages";
import { createInitialCareerForm, mapCareerResumeToForm } from "../../formMappers";
import { useCareerDirty } from "../../hooks/career/useCareerDirty";
import { useImportPanelLayout } from "../../hooks/career/useImportPanelLayout";
+import { useProofread } from "../../hooks/career/useProofread";
import { useResumeDiffPreview } from "../../hooks/career/useResumeDiffPreview";
import { useResumeImportAssist } from "../../hooks/career/useResumeImportAssist";
import { useDocumentForm } from "../../hooks/useDocumentForm";
@@ -86,16 +87,23 @@ export function CareerResumeForm() {
/**
* baseline(保存済み)と form(編集中)の変更点リスト。左右 diff モーダルのサイドバーと
- * ハイライト突合に使う。baseline が未ロード(null)のときは form 同士を比較して変更なし扱い。
+ * ハイライト突合に使う。
+ *
+ * baseline が未ロード(null = 新規作成の初回保存)のときは「空フォーム」を基準にする。
+ * これにより初回保存でも全項目が「追加」として変更点に立ち、確認ダイアログが開く
+ * (= 初回も校正を見せる)。既存データで差分が無い場合は changes が空のまま直接保存される。
*/
const changes = useMemo(
- () => buildCareerChanges(form, baseline ?? form),
+ () => buildCareerChanges(form, baseline ?? createInitialCareerForm()),
[form, baseline],
);
/** 左右 diff モーダル用の整形 HTML プレビュー(保存済み / 編集中)。開いている間だけ取得する。 */
const preview = useResumeDiffPreview(form, baseline, showSaveConfirm);
+ /** 保存確認ダイアログが開いている間、編集中フォームを校正する(誤字脱字・表記ゆれ)。 */
+ const proofread = useProofread(form, showSaveConfirm);
+
const {
downloading,
previewUrl,
@@ -207,6 +215,9 @@ export function CareerResumeForm() {
loading={preview.loading}
error={preview.error}
saving={saving}
+ issues={proofread.issues}
+ proofreading={proofread.proofreading}
+ proofreadError={proofread.error}
onConfirm={handleConfirmSave}
onCancel={() => setShowSaveConfirm(false)}
onRollback={(change) => setForm((prev) => change.rollback(prev))}
diff --git a/frontend/src/constants/messages.ts b/frontend/src/constants/messages.ts
index 159e2a0b..c24def8d 100644
--- a/frontend/src/constants/messages.ts
+++ b/frontend/src/constants/messages.ts
@@ -63,6 +63,7 @@ export const FALLBACK_MESSAGES = {
AUTH_CHECK: "ログイン状態の確認に失敗しました。",
GITHUB_OAUTH_START: "GitHub OAuth の開始に失敗しました",
GITHUB_LINK: "連携に失敗しました",
+ PROOFREAD: "文章の校正に失敗しました。",
} as const;
/**
@@ -230,6 +231,23 @@ export const DIFF_DIALOG_MESSAGES = {
BASELINE_EMPTY: "保存済みデータがありません。",
/** 変更点サイドバーの見出し */
CHANGES_HEADING: "変更点",
+ /** 変更点+校正を統合したレビュー一覧の見出し */
+ REVIEW_HEADING: "変更点・校正",
+} as const;
+
+/**
+ * 保存確認ダイアログ内の文章校正(誤字脱字・表記ゆれ)セクションの文言。
+ * 指摘メッセージ本文は textlint 由来の外部正本なのでここには持たず、そのまま表示する。
+ */
+export const PROOFREAD_MESSAGES = {
+ /** サイドバーの校正セクション見出し。 */
+ HEADING: "校正の指摘",
+ /** 校正処理中の表示。 */
+ LOADING: "文章を校正中...",
+ /** 指摘ゼロ件のときの表示。 */
+ NONE: "校正の指摘はありません。",
+ /** セクションの補足(保存はブロックしない旨)。 */
+ HINT: "保存はブロックされません。気になる箇所のみ修正してください。",
} as const;
/** 左右 diff で「変更なし領域」を畳んだときの展開ラベル(件数を埋め込む)。 */
diff --git a/frontend/src/hooks/career/useProofread.test.ts b/frontend/src/hooks/career/useProofread.test.ts
new file mode 100644
index 00000000..1688928b
--- /dev/null
+++ b/frontend/src/hooks/career/useProofread.test.ts
@@ -0,0 +1,95 @@
+import { act, renderHook } from "@testing-library/react";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
+
+import type { CareerFormState } from "../../payloadBuilders";
+import type { ProofreadIssue } from "../../proofread/types";
+import { useProofread } from "./useProofread";
+
+vi.mock("../../proofread/proofreadClient", () => ({
+ proofreadCareerForm: vi.fn(),
+}));
+
+import { proofreadCareerForm } from "../../proofread/proofreadClient";
+
+const mockProofread = proofreadCareerForm as unknown as ReturnType;
+
+const form: CareerFormState = {
+ full_name: "山田 太郎",
+ career_summary: "サマリー",
+ self_pr: "自己PR",
+ experiences: [],
+ qualifications: [],
+};
+
+const issue: ProofreadIssue = {
+ fieldId: "self_pr",
+ fieldLabel: "自己PR",
+ ruleId: "prh",
+ message: "javascript => JavaScript",
+ severity: "warning",
+ line: 1,
+ column: 1,
+ index: 0,
+ excerpt: "javascript",
+};
+
+beforeEach(() => {
+ mockProofread.mockReset();
+ mockProofread.mockResolvedValue([issue]);
+ vi.useFakeTimers();
+});
+
+afterEach(() => {
+ vi.useRealTimers();
+});
+
+describe("useProofread", () => {
+ it("成功: enabled の間フォームを校正し指摘を返す", async () => {
+ const { result } = renderHook(() => useProofread(form, true));
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(350);
+ });
+ expect(mockProofread).toHaveBeenCalledTimes(1);
+ expect(result.current.issues).toEqual([issue]);
+ expect(result.current.proofreading).toBe(false);
+ expect(result.current.error).toBeNull();
+ });
+
+ it("失敗: reject したらエラーを立て指摘を空にする", async () => {
+ mockProofread.mockRejectedValue(new Error("校正失敗"));
+ const { result } = renderHook(() => useProofread(form, true));
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(350);
+ });
+ expect(result.current.error).toBe("校正失敗");
+ expect(result.current.issues).toEqual([]);
+ expect(result.current.proofreading).toBe(false);
+ });
+
+ it("無効化中(enabled=false)は校正せず、結果は空のまま", async () => {
+ const { result } = renderHook(() => useProofread(form, false));
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(350);
+ });
+ expect(mockProofread).not.toHaveBeenCalled();
+ expect(result.current.issues).toEqual([]);
+ expect(result.current.error).toBeNull();
+ });
+
+ it("enabled が false に変わると前回の指摘をクリアする", async () => {
+ const { result, rerender } = renderHook(
+ ({ enabled }: { enabled: boolean }) => useProofread(form, enabled),
+ { initialProps: { enabled: true } },
+ );
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(350);
+ });
+ expect(result.current.issues).toEqual([issue]);
+
+ rerender({ enabled: false });
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(10);
+ });
+ expect(result.current.issues).toEqual([]);
+ });
+});
diff --git a/frontend/src/hooks/career/useProofread.ts b/frontend/src/hooks/career/useProofread.ts
new file mode 100644
index 00000000..02095ee7
--- /dev/null
+++ b/frontend/src/hooks/career/useProofread.ts
@@ -0,0 +1,72 @@
+import { useEffect, useState } from "react";
+
+import { FALLBACK_MESSAGES } from "../../constants/messages";
+import type { CareerFormState } from "../../payloadBuilders";
+import { proofreadCareerForm } from "../../proofread/proofreadClient";
+import type { ProofreadIssue } from "../../proofread/types";
+
+/** 校正の取得状態。 */
+export type ProofreadState = {
+ /** 校正指摘の一覧(フィールド横断・収集順)。 */
+ issues: ProofreadIssue[];
+ /** 校正処理中フラグ。 */
+ proofreading: boolean;
+ /** 校正失敗時のメッセージ。 */
+ error: string | null;
+};
+
+/**
+ * デバウンス。ダイアログ表示中に form が変わるのはロールバック操作のみだが、
+ * 校正は worker 往復があるため軽くまとめる。
+ */
+const DEBOUNCE_MS = 300;
+
+/**
+ * 保存確認ダイアログが開いている間(`enabled`)、編集中フォームを校正するフック。
+ *
+ * - ロールバックで form が変わるたびに再校正する(デバウンス付き)。
+ * - ダイアログを閉じたら結果をクリアし、次回開いた時に前回の指摘を残さない。
+ * - `react-hooks/set-state-in-effect` を避けるため、状態更新はすべて setTimeout 内で行う。
+ */
+export function useProofread(form: CareerFormState, enabled: boolean): ProofreadState {
+ const [issues, setIssues] = useState([]);
+ const [proofreading, setProofreading] = useState(false);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ let active = true;
+ const handle = setTimeout(
+ () => {
+ if (!active) return;
+ if (!enabled) {
+ setIssues([]);
+ setError(null);
+ setProofreading(false);
+ return;
+ }
+ setProofreading(true);
+ setError(null);
+ proofreadCareerForm(form)
+ .then((result) => {
+ if (active) setIssues(result);
+ })
+ .catch((err) => {
+ if (active) {
+ setIssues([]);
+ setError(err instanceof Error ? err.message : FALLBACK_MESSAGES.PROOFREAD);
+ }
+ })
+ .finally(() => {
+ if (active) setProofreading(false);
+ });
+ },
+ enabled ? DEBOUNCE_MS : 0,
+ );
+ return () => {
+ active = false;
+ clearTimeout(handle);
+ };
+ }, [enabled, form]);
+
+ return { issues, proofreading, error };
+}
diff --git a/frontend/src/proofread/collectCareerTexts.test.ts b/frontend/src/proofread/collectCareerTexts.test.ts
new file mode 100644
index 00000000..d1d6200d
--- /dev/null
+++ b/frontend/src/proofread/collectCareerTexts.test.ts
@@ -0,0 +1,123 @@
+import { describe, expect, it } from "vitest";
+
+import {
+ blankCareerClient,
+ blankCareerExperience,
+ blankCareerProject,
+} from "../constants";
+import type { CareerExperienceForm, CareerFormState } from "../payloadBuilders";
+import { collectCareerTexts } from "./collectCareerTexts";
+
+/** 必要なフィールドだけ上書きした職歴を作る。 */
+function makeExperience(overrides: Partial): CareerExperienceForm {
+ return { ...blankCareerExperience, ...overrides };
+}
+
+function makeForm(overrides: Partial): CareerFormState {
+ return {
+ full_name: "",
+ career_summary: "",
+ self_pr: "",
+ experiences: [],
+ qualifications: [],
+ ...overrides,
+ };
+}
+
+describe("collectCareerTexts", () => {
+ it("トップレベルの職務要約・自己PRを収集する(氏名は対象外)", () => {
+ const items = collectCareerTexts(
+ makeForm({ full_name: "山田 太郎", career_summary: "要約です", self_pr: "PRです" }),
+ );
+ const ids = items.map((i) => i.id);
+ expect(ids).toContain("career_summary");
+ expect(ids).toContain("self_pr");
+ expect(ids).not.toContain("full_name");
+ });
+
+ it("空白のみの値は除外する", () => {
+ const items = collectCareerTexts(makeForm({ career_summary: " ", self_pr: "" }));
+ expect(items).toEqual([]);
+ });
+
+ it("非IT企業は description を収集し、clients は辿らない", () => {
+ const exp = makeExperience({
+ company: "非IT社",
+ business_description: "事業",
+ start_date: "2020-01",
+ is_it_company: false,
+ description: "詳細テキスト",
+ clients: [{ ...blankCareerClient, has_client: true, name: "取引先A" }],
+ });
+ const items = collectCareerTexts(makeForm({ experiences: [exp] }));
+ const ids = items.map((i) => i.id);
+ expect(ids).toContain("experiences.0.company");
+ expect(ids).toContain("experiences.0.business_description");
+ expect(ids).toContain("experiences.0.description");
+ // 非IT企業なので取引先配下は収集しない
+ expect(ids.some((id) => id.includes("clients"))).toBe(false);
+ });
+
+ it("IT企業は取引先名・案件の自由記述を辿り、ラベルはパンくずになる", () => {
+ const exp = makeExperience({
+ company: "IT社",
+ business_description: "事業",
+ start_date: "2020-01",
+ is_it_company: true,
+ clients: [
+ {
+ ...blankCareerClient,
+ has_client: true,
+ name: "取引先A",
+ projects: [
+ {
+ ...blankCareerProject,
+ name: "案件X",
+ role: "リーダー",
+ description: "案件の説明",
+ },
+ ],
+ },
+ ],
+ });
+ const items = collectCareerTexts(makeForm({ experiences: [exp] }));
+ const byId = new Map(items.map((i) => [i.id, i]));
+ expect(byId.has("experiences.0.clients.0.name")).toBe(true);
+ expect(byId.has("experiences.0.clients.0.projects.0.name")).toBe(true);
+ expect(byId.has("experiences.0.clients.0.projects.0.role")).toBe(true);
+ expect(byId.has("experiences.0.clients.0.projects.0.description")).toBe(true);
+ // パンくず: 職歴1 > 取引先1 > プロジェクト1 > 案件詳細
+ expect(byId.get("experiences.0.clients.0.projects.0.description")?.label).toContain("職歴1");
+ expect(byId.get("experiences.0.clients.0.projects.0.description")?.label).toContain(
+ "プロジェクト1",
+ );
+ });
+
+ it("休暇の取引先は休暇内容のみ収集する", () => {
+ const exp = makeExperience({
+ company: "IT社",
+ business_description: "事業",
+ start_date: "2020-01",
+ is_it_company: true,
+ clients: [
+ {
+ ...blankCareerClient,
+ is_vacation: true,
+ vacation_start_date: "2021-01",
+ vacation_description: "育児休暇を取得",
+ },
+ ],
+ });
+ const items = collectCareerTexts(makeForm({ experiences: [exp] }));
+ const ids = items.map((i) => i.id);
+ expect(ids).toContain("experiences.0.clients.0.vacation_description");
+ expect(ids.some((id) => id.includes("projects"))).toBe(false);
+ });
+
+ it("資格は名称を収集する", () => {
+ const items = collectCareerTexts(
+ makeForm({ qualifications: [{ acquired_date: "2020-01", name: "基本情報技術者" }] }),
+ );
+ expect(items.map((i) => i.id)).toContain("qualifications.0.name");
+ });
+});
diff --git a/frontend/src/proofread/collectCareerTexts.ts b/frontend/src/proofread/collectCareerTexts.ts
new file mode 100644
index 00000000..3c353cbe
--- /dev/null
+++ b/frontend/src/proofread/collectCareerTexts.ts
@@ -0,0 +1,106 @@
+/**
+ * 職務経歴フォーム(`CareerFormState`)から校正対象のテキスト項目を平坦化する純粋関数。
+ *
+ * ## 方針
+ * - 校正は「保存される自由記述」を対象にする。日付・数値・真偽・選択値(技術スタック等)は除外する。
+ * - 収集条件は `payloadBuilders.ts` の包含判定(`experienceIncluded` / `clientIncluded` /
+ * `projectIncluded`)を再利用し、payload に載らない(=保存されない)行は校正しない。
+ * - `id`(ドット区切りパス)と `label`(パンくず)は `utils/careerDiff.ts` の体系に揃える。
+ * そうすることで、ダイアログのサイドバーで「変更点」と「校正の指摘」が同じラベルで並ぶ。
+ *
+ * 空白のみの値は除外する(指摘の意味がないため)。
+ */
+import { CAREER_DIFF_LABELS as L, DIFF_DIALOG_MESSAGES as D } from "../constants/messages";
+import {
+ clientIncluded,
+ experienceIncluded,
+ projectIncluded,
+ type CareerFormState,
+} from "../payloadBuilders";
+import type { CareerTextItem } from "./types";
+
+/** ラベルセグメントを区切り文字で連結する(careerDiff の joinLabel と同一)。 */
+function joinLabel(segments: string[]): string {
+ return segments.join(D.PATH_SEPARATOR);
+}
+
+/** 値が非空(trim 後)なら 1 項目 push する。 */
+function pushText(
+ items: CareerTextItem[],
+ id: string,
+ labelSegments: string[],
+ value: string,
+): void {
+ if (!value.trim()) return;
+ items.push({ id, label: joinLabel(labelSegments), value });
+}
+
+/**
+ * フォームを走査し、校正対象テキストを順番(フォームの並び)どおりに収集する。
+ */
+export function collectCareerTexts(form: CareerFormState): CareerTextItem[] {
+ const items: CareerTextItem[] = [];
+
+ // 並び順は PDF レイアウト(職務要約 → 職務経歴 → 資格 → 自己PR)に合わせ、
+ // 左右ペイン・変更点リストと校正セクションの縦順を一致させる。
+ pushText(items, "career_summary", [L.CAREER_SUMMARY], form.career_summary);
+
+ form.experiences.forEach((exp, expIndex) => {
+ if (!experienceIncluded(exp)) return;
+ const expSeg = [`${L.EXPERIENCE}${expIndex + 1}`];
+ const expPath = `experiences.${expIndex}`;
+
+ pushText(items, `${expPath}.company`, [...expSeg, L.COMPANY], exp.company);
+ pushText(
+ items,
+ `${expPath}.business_description`,
+ [...expSeg, L.BUSINESS_DESCRIPTION],
+ exp.business_description,
+ );
+
+ if (!exp.is_it_company) {
+ pushText(items, `${expPath}.description`, [...expSeg, L.DESCRIPTION], exp.description);
+ return;
+ }
+
+ exp.clients.forEach((client, clientIndex) => {
+ if (!clientIncluded(client)) return;
+ const clientSeg = [...expSeg, `${L.CLIENT}${clientIndex + 1}`];
+ const clientPath = `${expPath}.clients.${clientIndex}`;
+
+ if (client.is_vacation) {
+ pushText(
+ items,
+ `${clientPath}.vacation_description`,
+ [...clientSeg, L.VACATION_DESCRIPTION],
+ client.vacation_description,
+ );
+ return;
+ }
+
+ if (client.has_client) {
+ pushText(items, `${clientPath}.name`, [...clientSeg, L.CLIENT_NAME], client.name);
+ }
+
+ client.projects.forEach((proj, projIndex) => {
+ if (!projectIncluded(proj)) return;
+ const projSeg = [...clientSeg, `${L.PROJECT}${projIndex + 1}`];
+ const projPath = `${clientPath}.projects.${projIndex}`;
+
+ pushText(items, `${projPath}.name`, [...projSeg, L.PROJECT_NAME], proj.name);
+ pushText(items, `${projPath}.role`, [...projSeg, L.ROLE], proj.role);
+ pushText(items, `${projPath}.description`, [...projSeg, L.PROJECT_DESCRIPTION], proj.description);
+ });
+ });
+ });
+
+ form.qualifications.forEach((qual, index) => {
+ const qualSeg = [`${L.QUALIFICATION}${index + 1}`];
+ pushText(items, `qualifications.${index}.name`, [...qualSeg, L.QUALIFICATION_NAME], qual.name);
+ });
+
+ // 自己PR は PDF 上で最後に来るため末尾に収集する。
+ pushText(items, "self_pr", [L.SELF_PR], form.self_pr);
+
+ return items;
+}
diff --git a/frontend/src/proofread/issueFormat.test.ts b/frontend/src/proofread/issueFormat.test.ts
new file mode 100644
index 00000000..4e8c472e
--- /dev/null
+++ b/frontend/src/proofread/issueFormat.test.ts
@@ -0,0 +1,70 @@
+import { describe, expect, it } from "vitest";
+
+import { buildExcerpt, groupIssuesByField, mapSeverity } from "./issueFormat";
+import type { ProofreadIssue } from "./types";
+
+describe("mapSeverity", () => {
+ it("0=info / 1=warning / 2 以上=error に写像する", () => {
+ expect(mapSeverity(0)).toBe("info");
+ expect(mapSeverity(1)).toBe("warning");
+ expect(mapSeverity(2)).toBe("error");
+ expect(mapSeverity(3)).toBe("error");
+ });
+});
+
+describe("buildExcerpt", () => {
+ it("指摘箇所の前後を切り出す(両端が途切れると省略記号を付ける)", () => {
+ // 40 文字。半径 12 なので index=20 だと前後とも途切れる。
+ const text = "あいうえおかきくけこさしすせそたちつてとアイウエオカキクケコサシスセソタチツテト";
+ const excerpt = buildExcerpt(text, 20, 1);
+ expect(excerpt).toContain("カ");
+ expect(excerpt.startsWith("…")).toBe(true);
+ expect(excerpt.endsWith("…")).toBe(true);
+ });
+
+ it("先頭付近は前側の省略記号を付けない", () => {
+ const excerpt = buildExcerpt("短いテキスト", 0, 1);
+ expect(excerpt.startsWith("…")).toBe(false);
+ expect(excerpt).toContain("短い");
+ });
+
+ it("改行・連続空白は 1 つの空白に潰す", () => {
+ const excerpt = buildExcerpt("行1\n\n 行2", 0, 1);
+ expect(excerpt).not.toContain("\n");
+ expect(excerpt).toBe("行1 行2");
+ });
+
+ it("空文字なら空を返す", () => {
+ expect(buildExcerpt("", 0, 1)).toBe("");
+ });
+});
+
+describe("groupIssuesByField", () => {
+ const makeIssue = (fieldId: string, fieldLabel: string, message: string): ProofreadIssue => ({
+ fieldId,
+ fieldLabel,
+ ruleId: "prh",
+ message,
+ severity: "warning",
+ line: 1,
+ column: 1,
+ index: 0,
+ excerpt: "",
+ });
+
+ it("フィールド単位でグルーピングし、入力順を保つ", () => {
+ const issues = [
+ makeIssue("self_pr", "自己PR", "A"),
+ makeIssue("career_summary", "職務要約", "B"),
+ makeIssue("self_pr", "自己PR", "C"),
+ ];
+ const groups = groupIssuesByField(issues);
+ expect(groups.map((g) => g.fieldId)).toEqual(["self_pr", "career_summary"]);
+ expect(groups[0].issues.map((i) => i.message)).toEqual(["A", "C"]);
+ expect(groups[1].issues.map((i) => i.message)).toEqual(["B"]);
+ });
+
+ it("空配列なら空グループ", () => {
+ expect(groupIssuesByField([])).toEqual([]);
+ });
+});
diff --git a/frontend/src/proofread/issueFormat.ts b/frontend/src/proofread/issueFormat.ts
new file mode 100644
index 00000000..4fbccf4b
--- /dev/null
+++ b/frontend/src/proofread/issueFormat.ts
@@ -0,0 +1,59 @@
+/**
+ * 校正結果(textlint メッセージ)を `ProofreadIssue` へ整形する純粋関数群。
+ *
+ * worker 本体(`proofread.worker.ts`)から呼ばれるが、textlint/kuromoji に依存しないため
+ * 単体テスト可能。worker 経路をモックしても、ここはそのままテストできる。
+ */
+import type { ProofreadIssue, ProofreadSeverity } from "./types";
+
+/** 抜粋に含める指摘箇所前後の文字数。 */
+const EXCERPT_RADIUS = 12;
+
+/** textlint の severity 数値(0=info / 1=warning / 2=error)を文字列へ写像する。 */
+export function mapSeverity(severity: number): ProofreadSeverity {
+ if (severity >= 2) return "error";
+ if (severity === 1) return "warning";
+ return "info";
+}
+
+/**
+ * フィールド本文から指摘箇所の前後を抜き出す。
+ * - index 周辺を `EXCERPT_RADIUS` 文字ずつ切り出し、端が途切れる場合は省略記号を付ける。
+ * - 改行は空白に潰して 1 行で見せる。
+ */
+export function buildExcerpt(text: string, index: number, length = 1): string {
+ if (!text) return "";
+ const safeIndex = Math.max(0, Math.min(index, text.length));
+ const start = Math.max(0, safeIndex - EXCERPT_RADIUS);
+ const end = Math.min(text.length, safeIndex + Math.max(1, length) + EXCERPT_RADIUS);
+ const slice = text.slice(start, end).replace(/\s+/g, " ").trim();
+ const prefix = start > 0 ? "…" : "";
+ const suffix = end < text.length ? "…" : "";
+ return `${prefix}${slice}${suffix}`;
+}
+
+/** フィールド単位にグルーピングした指摘。サイドバー表示で使う。 */
+export type ProofreadGroup = {
+ fieldId: string;
+ fieldLabel: string;
+ issues: ProofreadIssue[];
+};
+
+/**
+ * 指摘をフィールド単位へグルーピングする。
+ * 入力順(= 収集順 = フォームの並び)を保ったままグループ化し、各グループ内も入力順を保つ。
+ */
+export function groupIssuesByField(issues: ProofreadIssue[]): ProofreadGroup[] {
+ const groups: ProofreadGroup[] = [];
+ const indexById = new Map();
+ for (const issue of issues) {
+ let pos = indexById.get(issue.fieldId);
+ if (pos === undefined) {
+ pos = groups.length;
+ indexById.set(issue.fieldId, pos);
+ groups.push({ fieldId: issue.fieldId, fieldLabel: issue.fieldLabel, issues: [] });
+ }
+ groups[pos].issues.push(issue);
+ }
+ return groups;
+}
diff --git a/frontend/src/proofread/prh-it-terms.yml b/frontend/src/proofread/prh-it-terms.yml
new file mode 100644
index 00000000..5e33ce76
--- /dev/null
+++ b/frontend/src/proofread/prh-it-terms.yml
@@ -0,0 +1,98 @@
+# IT 用語の表記ゆれ辞書(prh)。
+# 職務経歴書で頻出する固有名詞・技術用語の正規化に絞る。
+# `expected` が正、`patterns` が誤記(自動マッチ)。誤検出を避けるため過剰なパターンは登録しない。
+version: 1
+rules:
+ # 言語・ランタイム
+ - expected: JavaScript
+ patterns:
+ - javascript
+ - Javascript
+ - java script
+ - expected: TypeScript
+ patterns:
+ - typescript
+ - Typescript
+ - type script
+ - expected: Node.js
+ patterns:
+ - node.js
+ - Nodejs
+ - NodeJS
+ - node js
+ - expected: Python
+ patterns:
+ - python
+ - expected: Ruby
+ patterns:
+ - ruby
+ - expected: PHP
+ patterns:
+ - Php
+ - expected: Golang
+ patterns:
+ - golang
+ # フレームワーク・ライブラリ
+ - expected: React
+ patterns:
+ - react
+ - expected: Vue.js
+ patterns:
+ - vue.js
+ - Vuejs
+ - expected: Next.js
+ patterns:
+ - next.js
+ - Nextjs
+ - expected: Django
+ patterns:
+ - django
+ - expected: FastAPI
+ patterns:
+ - fastapi
+ - Fastapi
+ # インフラ・ツール
+ - expected: Docker
+ patterns:
+ - docker
+ - expected: Kubernetes
+ patterns:
+ - kubernetes
+ - expected: GitHub
+ patterns:
+ - github
+ - Github
+ - git hub
+ - expected: GitLab
+ patterns:
+ - gitlab
+ - Gitlab
+ - expected: MySQL
+ patterns:
+ - mysql
+ - Mysql
+ - expected: PostgreSQL
+ patterns:
+ - postgresql
+ - Postgresql
+ - postgres
+ - expected: Redis
+ patterns:
+ - redis
+ # 一般的な表記ゆれ
+ - expected: ソフトウェア
+ patterns:
+ - ソフトウエア
+ - expected: ハードウェア
+ patterns:
+ - ハードウエア
+ - expected: インターフェース
+ patterns:
+ - インタフェース
+ - インターフェイス
+ - expected: データベース
+ patterns:
+ - データーベース
+ - expected: ディレクトリ
+ patterns:
+ - ディレクトリー
diff --git a/frontend/src/proofread/proofread.worker.ts b/frontend/src/proofread/proofread.worker.ts
new file mode 100644
index 00000000..166cb761
--- /dev/null
+++ b/frontend/src/proofread/proofread.worker.ts
@@ -0,0 +1,190 @@
+///
+/**
+ * 文章校正 Web Worker。textlint kernel + 技術文書プリセット + prh をこの中で組み立て、
+ * メインスレッドから渡されたテキスト項目を校正して `ProofreadIssue[]` を返す。
+ *
+ * ## ブラウザ統合のポイント(ハマりどころ)
+ * - kuromoji(形態素解析)の辞書はブラウザに fs が無いため、`public/kuromoji-dict/` を
+ * 静的配信し、kuromojin が参照する `globalThis.kuromojin.dicPath` に URL を注入する。
+ * kuromojin は `typeof window !== "undefined"` を前提とするため、worker では `window` も補う。
+ * - kuromoji の辞書ロード(数 MB)に失敗しても機能停止させない。辞書を使うルール
+ * (二重助詞・冗長表現など)は preload 成功時のみ登録し、失敗時は prh + 形態素非依存
+ * ルールだけで動作させる(グレースフルデグラデーション)。
+ * - prh ルールはファイル読み込み不可なので、YAML を `?raw` 文字列で読み込み `ruleContents` で渡す。
+ */
+// 最初に import すること(textlint/kuromoji 依存の評価前にグローバルを用意する)。
+import "./worker-env-polyfill";
+
+import { TextlintKernel } from "@textlint/kernel";
+import type { TextlintKernelPlugin, TextlintKernelRule } from "@textlint/kernel";
+
+import prhRule from "textlint-rule-prh";
+
+import { buildExcerpt, mapSeverity } from "./issueFormat";
+import prhYaml from "./prh-it-terms.yml?raw";
+import type {
+ CareerTextItem,
+ ProofreadIssue,
+ ProofreadRequest,
+ ProofreadResponse,
+} from "./types";
+
+/**
+ * textlint ルール / プラグインは CJS↔ESM 相互運用で `default` が多重ラップされることがある。
+ * 本体(関数 もしくは `{ linter }` / `{ create }` を持つオブジェクト)まで掘り下げる。
+ */
+function unwrapModule(mod: unknown): T {
+ let current = mod as Record | unknown;
+ for (let i = 0; i < 5; i += 1) {
+ if (typeof current === "function") return current as T;
+ if (
+ current &&
+ typeof current === "object" &&
+ ("linter" in current || "create" in current || "fixer" in current)
+ ) {
+ return current as T;
+ }
+ if (current && typeof current === "object" && "default" in current) {
+ current = (current as { default: unknown }).default;
+ continue;
+ }
+ break;
+ }
+ return current as T;
+}
+
+const kernel = new TextlintKernel();
+
+/**
+ * 技術文書プリセットのうち kuromoji(形態素解析)に依存するルール ID。
+ * 辞書 preload に失敗した場合、これらを除外して機能停止を避ける。
+ */
+const KUROMOJI_RULE_IDS = new Set([
+ "max-ten",
+ "no-double-negative-ja",
+ "no-doubled-conjunction",
+ "no-doubled-conjunctive-particle-ga",
+ "no-doubled-joshi",
+ "no-dropping-the-ra",
+ "ja-no-weak-phrase",
+ "ja-no-successive-word",
+ "ja-no-abusage",
+ "ja-no-redundant-expression",
+ // 念のため漢数字ルールも辞書依存側に寄せる(誤検出より安全側)。
+ "arabic-kanji-numbers",
+]);
+
+/** 技術文書プリセットの import 形({ rules, rulesConfig })。 */
+type PresetModule = {
+ rules: Record;
+ rulesConfig: Record;
+};
+
+/**
+ * プリセットから kernel 用のルール記述子を組み立てる。
+ * `includeKuromoji=false` のときは形態素解析依存ルールを除外する。
+ * prh(表記ゆれ)はプリセット外なので常に末尾へ足す。
+ */
+function buildRules(preset: PresetModule, includeKuromoji: boolean): TextlintKernelRule[] {
+ const rules: TextlintKernelRule[] = [];
+ for (const [ruleId, rule] of Object.entries(preset.rules)) {
+ if (!includeKuromoji && KUROMOJI_RULE_IDS.has(ruleId)) continue;
+ const options = preset.rulesConfig[ruleId];
+ rules.push({
+ ruleId,
+ rule: unwrapModule(rule),
+ // rulesConfig の値が false/true(無効/デフォルト)の場合は options を渡さない。
+ ...(options && typeof options === "object" ? { options } : {}),
+ });
+ }
+ rules.push({ ruleId: "prh", rule: unwrapModule(prhRule), options: { ruleContents: [prhYaml] } });
+ return rules;
+}
+
+/** kernel.lintText に渡す構築済み設定。 */
+type ProofreadConfig = {
+ plugins: TextlintKernelPlugin[];
+ rules: TextlintKernelRule[];
+};
+
+/** テキストプラグイン(.txt 解析)と全ルールを 1 回だけ構築してキャッシュする。 */
+let setupPromise: Promise | null = null;
+
+async function setup(): Promise {
+ const [textPlugin, presetModule] = await Promise.all([
+ import("@textlint/textlint-plugin-text"),
+ import("textlint-rule-preset-ja-technical-writing"),
+ ]);
+ const preset = (("default" in presetModule ? presetModule.default : presetModule) ??
+ presetModule) as PresetModule;
+ const plugins: TextlintKernelPlugin[] = [
+ { pluginId: "text", plugin: unwrapModule(textPlugin) },
+ ];
+
+ // 辞書を preload。成功時のみ kuromoji 依存ルールを含める。
+ let includeKuromoji = false;
+ try {
+ const kuromojin = await import("kuromojin");
+ await kuromojin.getTokenizer();
+ includeKuromoji = true;
+ } catch {
+ // 辞書ロード失敗時は形態素非依存ルール + prh のみで継続(機能停止させない)。
+ includeKuromoji = false;
+ }
+
+ return { plugins, rules: buildRules(preset, includeKuromoji) };
+}
+
+function ensureSetup() {
+ if (!setupPromise) {
+ // setup 失敗(依存ロード不能)も握りつぶさず、各リクエストで再試行できるよう null に戻す。
+ setupPromise = setup().catch((err) => {
+ setupPromise = null;
+ throw err;
+ });
+ }
+ return setupPromise;
+}
+
+/** 1 テキスト項目を校正し、ProofreadIssue 配列へ整形する。 */
+async function proofreadItem(
+ item: CareerTextItem,
+ config: ProofreadConfig,
+): Promise {
+ const result = await kernel.lintText(item.value, {
+ ext: ".txt",
+ plugins: config.plugins,
+ rules: config.rules,
+ });
+ return result.messages.map((message) => ({
+ fieldId: item.id,
+ fieldLabel: item.label,
+ ruleId: message.ruleId,
+ message: message.message,
+ severity: mapSeverity(message.severity),
+ line: message.line,
+ column: message.column,
+ index: message.index,
+ excerpt: buildExcerpt(item.value, message.index),
+ }));
+}
+
+self.onmessage = async (event: MessageEvent) => {
+ const data = event.data;
+ if (!data || data.type !== "proofread") return;
+ const { requestId, items } = data;
+ try {
+ const config = await ensureSetup();
+ const nested = await Promise.all(items.map((item) => proofreadItem(item, config)));
+ const issues = nested.flat();
+ const response: ProofreadResponse = { type: "result", requestId, issues };
+ self.postMessage(response);
+ } catch (err) {
+ const response: ProofreadResponse = {
+ type: "error",
+ requestId,
+ message: err instanceof Error ? err.message : String(err),
+ };
+ self.postMessage(response);
+ }
+};
diff --git a/frontend/src/proofread/proofreadClient.ts b/frontend/src/proofread/proofreadClient.ts
new file mode 100644
index 00000000..e74cd253
--- /dev/null
+++ b/frontend/src/proofread/proofreadClient.ts
@@ -0,0 +1,58 @@
+/**
+ * 校正 worker のメインスレッド側サービス。
+ *
+ * - worker は初回呼び出し時にのみ遅延生成する(textlint / kuromoji 一式は worker チャンクへ
+ * 分離され、初期バンドル・初回描画には載らない)。
+ * - 各リクエストに連番 `requestId` を振り、応答を id で突合してレースを防ぐ。
+ * - 収集テキストが 0 件なら worker を起動せず空配列を返す。
+ */
+import type { CareerFormState } from "../payloadBuilders";
+import { collectCareerTexts } from "./collectCareerTexts";
+import type { ProofreadIssue, ProofreadRequest, ProofreadResponse } from "./types";
+
+let worker: Worker | null = null;
+let nextRequestId = 1;
+
+/** worker を遅延生成する(テストでは本モジュールごとモックするため、ここは実行されない)。 */
+function getWorker(): Worker {
+ if (!worker) {
+ worker = new Worker(new URL("./proofread.worker.ts", import.meta.url), { type: "module" });
+ }
+ return worker;
+}
+
+/**
+ * 編集中フォームの全テキスト項目を校正する。
+ * 収集 0 件なら即 `[]`。それ以外は worker へ投げ、当該 requestId の応答を待つ。
+ */
+export function proofreadCareerForm(form: CareerFormState): Promise {
+ const items = collectCareerTexts(form);
+ if (items.length === 0) return Promise.resolve([]);
+
+ const activeWorker = getWorker();
+ const requestId = nextRequestId;
+ nextRequestId += 1;
+
+ return new Promise((resolve, reject) => {
+ const cleanup = () => {
+ activeWorker.removeEventListener("message", onMessage);
+ activeWorker.removeEventListener("error", onError);
+ };
+ const onMessage = (event: MessageEvent) => {
+ const data = event.data;
+ if (!data || data.requestId !== requestId) return;
+ cleanup();
+ if (data.type === "result") resolve(data.issues);
+ else reject(new Error(data.message));
+ };
+ const onError = (event: ErrorEvent) => {
+ cleanup();
+ reject(event.error instanceof Error ? event.error : new Error(event.message));
+ };
+ activeWorker.addEventListener("message", onMessage);
+ activeWorker.addEventListener("error", onError);
+
+ const request: ProofreadRequest = { type: "proofread", requestId, items };
+ activeWorker.postMessage(request);
+ });
+}
diff --git a/frontend/src/proofread/textlint-modules.d.ts b/frontend/src/proofread/textlint-modules.d.ts
new file mode 100644
index 00000000..900eab8c
--- /dev/null
+++ b/frontend/src/proofread/textlint-modules.d.ts
@@ -0,0 +1,7 @@
+/**
+ * textlint ルール群の型宣言。これらの npm パッケージは型定義を同梱しておらず、
+ * 校正 worker はルール本体を `unwrapModule` 経由で扱うため、ここで any として宣言する。
+ * (ルールの内部構造に型安全は不要 — kernel に渡すだけ)。
+ */
+// textlint-rule-* 系(プリセット同梱の個別ルール)をまとめてワイルドカード宣言する。
+declare module "textlint-rule-*";
diff --git a/frontend/src/proofread/types.ts b/frontend/src/proofread/types.ts
new file mode 100644
index 00000000..8baa0c37
--- /dev/null
+++ b/frontend/src/proofread/types.ts
@@ -0,0 +1,52 @@
+/**
+ * 文章校正(誤字脱字・表記ゆれ)機能の型 Single Source of Truth。
+ *
+ * メインスレッド(hook / コンポーネント)は textlint や kuromoji を一切知らず、
+ * この `ProofreadIssue` 配列だけを介して worker とやり取りする。エンジンを差し替えても
+ * この型が変わらなければ UI 側は影響を受けない(疎結合の境界)。
+ */
+
+/** 指摘の深刻度。textlint の severity 数値(0=info / 1=warning / 2=error)を文字列へ写像したもの。 */
+export type ProofreadSeverity = "info" | "warning" | "error";
+
+/** 校正対象となる 1 テキスト項目(フォームから平坦化したもの)。 */
+export type CareerTextItem = {
+ /** フォーム上のドット区切りパス(例: "experiences.0.description")。careerDiff の path と揃える。 */
+ id: string;
+ /** 人間可読ラベル(パンくず。例: "職歴1 > 詳細")。 */
+ label: string;
+ /** 校正にかける本文。 */
+ value: string;
+};
+
+/** 1 件の校正指摘。フィールド単位にグルーピングして表示する。 */
+export type ProofreadIssue = {
+ /** 指摘が属するフィールドの id(`CareerTextItem.id`)。 */
+ fieldId: string;
+ /** 指摘が属するフィールドのラベル(`CareerTextItem.label`)。 */
+ fieldLabel: string;
+ /** textlint のルール ID(例: "prh" / "ja-no-mixed-period")。 */
+ ruleId: string;
+ /** 指摘メッセージ(textlint 由来の外部正本。そのまま表示してよい)。 */
+ message: string;
+ severity: ProofreadSeverity;
+ /** フィールド本文内の行・列(1 始まり)。 */
+ line: number;
+ column: number;
+ /** フィールド本文内の文字オフセット(0 始まり)。 */
+ index: number;
+ /** 指摘箇所の前後を抜き出した短い抜粋(UI のコンテキスト表示用)。 */
+ excerpt: string;
+};
+
+/** メインスレッド → worker への校正リクエスト。 */
+export type ProofreadRequest = {
+ type: "proofread";
+ requestId: number;
+ items: CareerTextItem[];
+};
+
+/** worker → メインスレッドへの応答。 */
+export type ProofreadResponse =
+ | { type: "result"; requestId: number; issues: ProofreadIssue[] }
+ | { type: "error"; requestId: number; message: string };
diff --git a/frontend/src/proofread/worker-env-polyfill.ts b/frontend/src/proofread/worker-env-polyfill.ts
new file mode 100644
index 00000000..29b27908
--- /dev/null
+++ b/frontend/src/proofread/worker-env-polyfill.ts
@@ -0,0 +1,46 @@
+/**
+ * 校正 worker 用の最小グローバル補完。worker の **最初** に import して副作用を効かせる
+ * (textlint / kuromoji 系の依存が評価・実行時に参照する node/ブラウザのグローバルを先に用意する)。
+ *
+ * - `process`: async / textlint 依存が `process.env` / `process.nextTick` を参照する。worker には無い。
+ * - `window`: kuromojin は辞書パス解決で `typeof window !== "undefined"` を前提とする。worker には無い。
+ * - `window.kuromojin.dicPath`: 静的配信した辞書(public/kuromoji-dict/)の URL を注入する。
+ */
+type MinimalProcess = {
+ env: Record;
+ nextTick: (cb: (...args: unknown[]) => void, ...args: unknown[]) => void;
+ cwd: () => string;
+ platform: string;
+ version: string;
+ argv: string[];
+};
+
+const g = globalThis as unknown as {
+ process?: Partial;
+ window?: unknown;
+ kuromojin?: { dicPath: string };
+};
+
+if (typeof g.process === "undefined") {
+ g.process = {};
+}
+// 一部の textlint 依存(prh 経由の ja-no-abusage 等)が参照する API を最小実装で補う。
+const proc = g.process as Partial;
+proc.env ??= {};
+proc.nextTick ??= (cb, ...args) => {
+ void Promise.resolve().then(() => cb(...args));
+};
+proc.cwd ??= () => "/";
+proc.platform ??= "browser";
+proc.version ??= "";
+proc.argv ??= [];
+
+if (typeof g.window === "undefined") {
+ g.window = globalThis;
+}
+
+// 辞書の静的配信パスを kuromojin に渡す。
+// 注意: ルート相対パスにする(`http://…` のような絶対 URL を渡すと、kuromoji 内部の
+// path.join(ブラウザでは path-browserify)が `://` を `:/` に潰して壊れる)。
+// XHR はこのルート相対パスを worker の origin 基準で解決する。
+g.kuromojin = { dicPath: "/kuromoji-dict" };
diff --git a/frontend/src/utils/careerDiff.ts b/frontend/src/utils/careerDiff.ts
index 8a32b407..c58e541b 100644
--- a/frontend/src/utils/careerDiff.ts
+++ b/frontend/src/utils/careerDiff.ts
@@ -280,9 +280,10 @@ export function buildCareerChanges(
): CareerChange[] {
const changes: CareerChange[] = [];
+ // 並び順は PDF レイアウト(氏名 → 職務要約 → 職務経歴 → 資格 → 自己PR)に合わせる。
+ // 左右ペインとサイドバー(変更点 / 校正)の縦順が一致し、突合しやすくなる。
pushScalar(changes, [], L.FULL_NAME, ["full_name"], form.full_name, baseline.full_name);
pushScalar(changes, [], L.CAREER_SUMMARY, ["career_summary"], form.career_summary, baseline.career_summary);
- pushScalar(changes, [], L.SELF_PR, ["self_pr"], form.self_pr, baseline.self_pr);
diffArray(
changes, form.experiences, baseline.experiences, ["experiences"], [],
@@ -293,5 +294,7 @@ export function buildCareerChanges(
L.QUALIFICATION, (q) => q.name, diffQualification,
);
+ pushScalar(changes, [], L.SELF_PR, ["self_pr"], form.self_pr, baseline.self_pr);
+
return changes;
}
diff --git a/frontend/src/utils/careerReview.test.ts b/frontend/src/utils/careerReview.test.ts
new file mode 100644
index 00000000..6418a1b6
--- /dev/null
+++ b/frontend/src/utils/careerReview.test.ts
@@ -0,0 +1,78 @@
+import { describe, expect, it } from "vitest";
+
+import { buildReviewEntries, comparePaths } from "./careerReview";
+import type { CareerChange } from "./careerDiff";
+import type { ProofreadIssue } from "../proofread/types";
+
+function change(path: (string | number)[], label: string): CareerChange {
+ return { path, label, kind: "modified", oldValue: "", newValue: "", rollback: (f) => f };
+}
+function issue(fieldId: string, fieldLabel: string, message: string): ProofreadIssue {
+ return {
+ fieldId,
+ fieldLabel,
+ ruleId: "prh",
+ message,
+ severity: "warning",
+ line: 1,
+ column: 1,
+ index: 0,
+ excerpt: "",
+ };
+}
+
+describe("comparePaths", () => {
+ it("トップレベルは PDF 順(自己PR が資格より後)", () => {
+ expect(comparePaths("self_pr", "qualifications.0.name")).toBeGreaterThan(0);
+ expect(comparePaths("career_summary", "experiences.0.company")).toBeLessThan(0);
+ });
+
+ it("親は子より前", () => {
+ expect(comparePaths("experiences.0", "experiences.0.company")).toBeLessThan(0);
+ });
+
+ it("配列 index は数値順", () => {
+ expect(comparePaths("experiences.0.company", "experiences.1.company")).toBeLessThan(0);
+ });
+
+ it("コンテナ内のフィールドは PDF 順(company が business_description より前)", () => {
+ expect(comparePaths("experiences.0.company", "experiences.0.business_description")).toBeLessThan(0);
+ });
+});
+
+describe("buildReviewEntries", () => {
+ it("同一パスの差分と校正を 1 エントリに統合する", () => {
+ const entries = buildReviewEntries(
+ [change(["career_summary"], "職務要約")],
+ [issue("career_summary", "職務要約", "javascript => JavaScript")],
+ );
+ expect(entries).toHaveLength(1);
+ expect(entries[0].changes).toHaveLength(1);
+ expect(entries[0].issues).toHaveLength(1);
+ });
+
+ it("PDF レイアウト順に並ぶ(自己PRが末尾、職歴は資格より前)", () => {
+ const entries = buildReviewEntries(
+ [change(["self_pr"], "自己PR"), change(["full_name"], "氏名")],
+ [
+ issue("self_pr", "自己PR", "x"),
+ issue("qualifications.0.name", "資格1 > 資格名", "y"),
+ issue("experiences.0.company", "職歴1 > 会社名", "z"),
+ ],
+ );
+ const order = entries.map((e) => e.path);
+ expect(order[0]).toBe("full_name");
+ expect(order[order.length - 1]).toBe("self_pr");
+ expect(order.indexOf("experiences.0.company")).toBeLessThan(order.indexOf("qualifications.0.name"));
+ });
+
+ it("差分のみ・校正のみの項目もそれぞれエントリになる", () => {
+ const entries = buildReviewEntries(
+ [change(["full_name"], "氏名")],
+ [issue("experiences.0.description", "職歴1 > 詳細", "冗長")],
+ );
+ expect(entries.map((e) => e.path)).toEqual(["full_name", "experiences.0.description"]);
+ expect(entries[0].issues).toHaveLength(0);
+ expect(entries[1].changes).toHaveLength(0);
+ });
+});
diff --git a/frontend/src/utils/careerReview.ts b/frontend/src/utils/careerReview.ts
new file mode 100644
index 00000000..c65e389a
--- /dev/null
+++ b/frontend/src/utils/careerReview.ts
@@ -0,0 +1,122 @@
+/**
+ * 保存確認ダイアログ右サイドバーの「レビュー項目」を組み立てる純関数。
+ *
+ * 変更点(差分)と校正指摘を**フィールド単位で1本のリストに統合**し、PDF レイアウトと
+ * 同じ縦順(氏名 → 職務要約 → 職務経歴 → 資格 → 自己PR、各コンテナ内も PDF 準拠)に並べる。
+ * これにより左右ペイン(PDF)とサイドバーの並びが一致し、上から順に突合できる。
+ */
+import { groupIssuesByField } from "../proofread/issueFormat";
+import type { ProofreadIssue } from "../proofread/types";
+import type { CareerChange } from "./careerDiff";
+
+/** 1 フィールド分のレビュー項目(差分と校正をまとめて持つ)。 */
+export type ReviewEntry = {
+ /** フィールドのドット区切りパス(スクロール・key 用)。 */
+ path: string;
+ /** 人間可読ラベル(パンくず)。 */
+ label: string;
+ /** このフィールドの差分(通常 0〜1 件)。 */
+ changes: CareerChange[];
+ /** このフィールドの校正指摘。 */
+ issues: ProofreadIssue[];
+};
+
+/** トップレベル項目の並び(PDF レイアウト順)。 */
+const TOP_ORDER = ["full_name", "career_summary", "experiences", "qualifications", "self_pr"];
+
+/** 配列コンテナごとのフィールド並び(careerDiff の走査順=PDF 準拠)。 */
+const CONTAINER_FIELD_ORDER: Record = {
+ experiences: [
+ "company",
+ "business_description",
+ "start_date",
+ "end_date",
+ "is_current",
+ "employee_count",
+ "capital",
+ "capital_unit",
+ "is_it_company",
+ "description",
+ "clients",
+ ],
+ clients: [
+ "name",
+ "has_client",
+ "is_vacation",
+ "vacation_start_date",
+ "vacation_end_date",
+ "vacation_is_current",
+ "vacation_description",
+ "projects",
+ ],
+ projects: ["name", "role", "description", "team", "periods", "technology_stacks", "phases"],
+ qualifications: ["name", "acquired_date"],
+};
+
+/** 未知のセグメントを既知フィールドより後ろへ寄せる基準値(文字コードで安定ソート)。 */
+const UNKNOWN_FIELD_RANK_BASE = 400;
+/** コンテナの並びが特定できない名前付きセグメントのランク(末尾側へ)。 */
+const UNKNOWN_CONTAINER_FIELD_RANK = 500;
+
+/** 既知の並びにあればその index、無ければ末尾側(文字コードで安定ソート)に寄せる。 */
+function orderIndex(list: string[], seg: string): number {
+ const i = list.indexOf(seg);
+ return i >= 0 ? i : UNKNOWN_FIELD_RANK_BASE + (seg.charCodeAt(0) || 0);
+}
+
+/**
+ * パスを「並び順を表す数値タプル」に変換する。
+ * - 先頭セグメント: トップレベル順
+ * - 数値セグメント: 配列 index
+ * - 名前付きセグメント: 直近の配列名(2 つ前)から決まるコンテナのフィールド順
+ */
+function rankTuple(path: string): number[] {
+ const segs = path.split(".");
+ return segs.map((seg, i) => {
+ if (i === 0) return orderIndex(TOP_ORDER, seg);
+ if (/^\d+$/.test(seg)) return Number(seg);
+ const containerName = i >= 2 && /^\d+$/.test(segs[i - 1]) ? segs[i - 2] : null;
+ const order = containerName ? CONTAINER_FIELD_ORDER[containerName] : null;
+ return order ? orderIndex(order, seg) : UNKNOWN_CONTAINER_FIELD_RANK;
+ });
+}
+
+/** 2 つのパスを PDF レイアウト順で比較する(親は子より前)。 */
+export function comparePaths(a: string, b: string): number {
+ const ra = rankTuple(a);
+ const rb = rankTuple(b);
+ const len = Math.min(ra.length, rb.length);
+ for (let i = 0; i < len; i++) {
+ if (ra[i] !== rb[i]) return ra[i] - rb[i];
+ }
+ return ra.length - rb.length;
+}
+
+/**
+ * 差分と校正指摘をフィールド単位に統合し、PDF レイアウト順に並べたレビュー項目を返す。
+ * 同一パスの差分・校正は 1 エントリにまとまる。差分のみ・校正のみの項目もそれぞれ 1 エントリ。
+ */
+export function buildReviewEntries(
+ changes: CareerChange[],
+ issues: ProofreadIssue[],
+): ReviewEntry[] {
+ const byPath = new Map();
+
+ const getOrCreate = (path: string, label: string): ReviewEntry => {
+ let entry = byPath.get(path);
+ if (!entry) {
+ entry = { path, label, changes: [], issues: [] };
+ byPath.set(path, entry);
+ }
+ return entry;
+ };
+
+ for (const change of changes) {
+ getOrCreate(change.path.join("."), change.label).changes.push(change);
+ }
+ for (const group of groupIssuesByField(issues)) {
+ getOrCreate(group.fieldId, group.fieldLabel).issues.push(...group.issues);
+ }
+
+ return [...byPath.values()].sort((a, b) => comparePaths(a.path, b.path));
+}
diff --git a/frontend/src/utils/diffHighlight.test.ts b/frontend/src/utils/diffHighlight.test.ts
index b0051a00..27926121 100644
--- a/frontend/src/utils/diffHighlight.test.ts
+++ b/frontend/src/utils/diffHighlight.test.ts
@@ -144,6 +144,45 @@ describe("foldUnchanged", () => {
const html = 'a
';
expect(foldUnchanged(html, buildPathKindMap([]))).toBe(html);
});
+
+ it("校正指摘のある項目は(差分が無くても)畳まずに残す", () => {
+ const html =
+ 'A
' +
+ 'B
';
+ // 差分は experiences.0 のみ。experiences.1 は校正指摘があるので畳まれない。
+ const map = buildPathKindMap([change(["experiences", 0, "company"], "modified")]);
+ const proofread = new Set(["experiences.1.company"]);
+ const out = foldUnchanged(html, map, proofread);
+ const doc = new DOMParser().parseFromString(out, "text/html");
+ // 校正指摘のある experiences.1 は details の外に残る
+ expect(doc.querySelector('details [data-unit="experiences.1"]')).toBeNull();
+ expect(doc.querySelector('[data-unit="experiences.1"]')).not.toBeNull();
+ });
+});
+
+describe("annotateHtml(校正マーク)", () => {
+ it("校正指摘のある data-fp に diff-proofread を付ける", () => {
+ const html =
+ '要約
PR
';
+ const out = annotateHtml(html, buildPathKindMap([]), new Set(["self_pr"]));
+ const doc = new DOMParser().parseFromString(out, "text/html");
+ expect(doc.querySelector('[data-fp="self_pr"]')?.className).toContain("diff-proofread");
+ // 指摘の無い career_summary には付かない
+ expect(doc.querySelector('[data-fp="career_summary"]')?.className).toBe("");
+ });
+
+ it("差分(黄)と校正(青)は同じノードに併記される", () => {
+ const html = 'PR
';
+ const out = annotateHtml(
+ html,
+ buildPathKindMap([change(["self_pr"], "modified")]),
+ new Set(["self_pr"]),
+ );
+ const cls = new DOMParser().parseFromString(out, "text/html").querySelector('[data-fp="self_pr"]')
+ ?.className;
+ expect(cls).toContain("diff-modified");
+ expect(cls).toContain("diff-proofread");
+ });
});
describe("injectRemovedPlaceholders", () => {
diff --git a/frontend/src/utils/diffHighlight.ts b/frontend/src/utils/diffHighlight.ts
index 2723413e..9a8e07e9 100644
--- a/frontend/src/utils/diffHighlight.ts
+++ b/frontend/src/utils/diffHighlight.ts
@@ -54,9 +54,16 @@ function matchKind(nodePath: string, map: Map): ChangeKind |
*
* 変更が無ければ sanitize のみ行う。`dangerouslySetInnerHTML` には渡さず、
* iframe の `srcDoc` に埋め込む前提(呼び出し側で隔離)。
+ *
+ * `proofreadFieldIds` を渡すと、その data-fp に一致するノードへ校正マーク(青波線)の
+ * クラス `diff-proofread` を付ける。編集中ペインで「校正指摘のあるフィールド」を示す用途。
*/
-export function annotateHtml(html: string, map: Map): string {
- if (map.size === 0) return DOMPurify.sanitize(html);
+export function annotateHtml(
+ html: string,
+ map: Map,
+ proofreadFieldIds: Set = new Set(),
+): string {
+ if (map.size === 0 && proofreadFieldIds.size === 0) return DOMPurify.sanitize(html);
const doc = new DOMParser().parseFromString(html, "text/html");
doc.body.querySelectorAll("[data-fp]").forEach((node) => {
@@ -66,6 +73,10 @@ export function annotateHtml(html: string, map: Map): string
if (kind) {
node.classList.add("diff-mark", KIND_CLASS[kind]);
}
+ // 校正指摘のあるフィールドは青波線(差分の背景色と重ねても潰れない)。
+ if (proofreadFieldIds.has(fp)) {
+ node.classList.add("diff-proofread");
+ }
});
// DOMPurify は既定で data-* 属性・class を保持する(ALLOW_DATA_ATTR=true)。
return DOMPurify.sanitize(doc.body.innerHTML);
@@ -76,6 +87,14 @@ function unitChanged(unitPath: string, map: Map): boolean {
return matchKind(unitPath, map) !== null;
}
+/** 項目(data-unit)配下に校正指摘のあるフィールドが含まれるか。 */
+function unitHasProofread(unitPath: string, proofreadFieldIds: Set): boolean {
+ for (const fp of proofreadFieldIds) {
+ if (fp === unitPath || fp.startsWith(`${unitPath}.`)) return true;
+ }
+ return false;
+}
+
/**
* prefix 直下で「先頭(最小 index)の既存兄弟(data-unit)」を探す。
*
@@ -178,22 +197,31 @@ export function injectRemovedPlaceholders(html: string, changes: CareerChange[])
* - `` はネイティブの開閉なので、スクリプト無効の sandbox iframe 内でも展開できる。
*
* 変更が無ければ(map 空)何もしない。annotateHtml の後段に適用する前提。
+ *
+ * `proofreadFieldIds` を渡すと、校正指摘を含む項目は(差分が無くても)畳まずに残す
+ * (編集中ペインで青マークが折りたたみに隠れないようにする)。
*/
-export function foldUnchanged(html: string, map: Map): string {
+export function foldUnchanged(
+ html: string,
+ map: Map,
+ proofreadFieldIds: Set = new Set(),
+): string {
if (map.size === 0) return html;
const doc = new DOMParser().parseFromString(html, "text/html");
const units = Array.from(doc.body.querySelectorAll("[data-unit]"));
- // 畳み根: 自身が未変更 かつ 最も近い祖先 unit が「変更あり or 不在」のもの。
+ // 畳み根: 自身が未変更 かつ 校正指摘も無い かつ 最も近い祖先 unit が「変更あり or 不在」のもの。
const collapseRoots = new Set();
for (const u of units) {
const path = u.getAttribute("data-unit");
- if (!path || unitChanged(path, map)) continue;
+ if (!path || unitChanged(path, map) || unitHasProofread(path, proofreadFieldIds)) continue;
const parentUnit = u.parentElement?.closest("[data-unit]");
if (parentUnit) {
const parentPath = parentUnit.getAttribute("data-unit");
- if (parentPath && !unitChanged(parentPath, map)) continue; // 祖先ごと畳まれる
+ if (parentPath && !unitChanged(parentPath, map) && !unitHasProofread(parentPath, proofreadFieldIds)) {
+ continue; // 祖先ごと畳まれる
+ }
}
collapseRoots.add(u);
}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index fb44ea1f..d0c6b54e 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -1,10 +1,69 @@
///
-import { defineConfig } from "vite";
+import { createReadStream } from "node:fs";
+import { join, normalize } from "node:path";
+import { defineConfig, type Plugin } from "vite";
import react from "@vitejs/plugin-react";
+/**
+ * kuromoji(校正 worker の形態素解析)辞書を dev サーバーで「生の gzip バイト列」として配信する。
+ *
+ * 既定の静的配信は `.gz` 拡張子を見て `Content-Encoding: gzip` を付けるため、ブラウザが
+ * 自動展開してしまい、kuromoji 側の再 gunzip が「invalid file signature」で失敗する。
+ * ここでは Content-Encoding を付けず application/octet-stream で素のまま返し、
+ * kuromoji が自前で gunzip できるようにする(本番 Cloudflare Pages 用は public/_headers で同等指定)。
+ */
+function kuromojiDictRaw(): Plugin {
+ const publicDir = join(process.cwd(), "public");
+ return {
+ name: "kuromoji-dict-raw",
+ configureServer(server) {
+ server.middlewares.use((req, res, next) => {
+ const url = req.url?.split("?")[0] ?? "";
+ if (!url.startsWith("/kuromoji-dict/") || !url.endsWith(".dat.gz")) {
+ next();
+ return;
+ }
+ // 先頭スラッシュを除いて確実に publicDir 相対で解決する(join の絶対パス扱いを回避)。
+ // パストラバーサル防止のため normalize 後に publicDir 配下であることを担保する。
+ const relativePath = url.replace(/^\/+/, "");
+ const filePath = normalize(join(publicDir, relativePath));
+ if (!filePath.startsWith(publicDir)) {
+ res.statusCode = 403;
+ res.end();
+ return;
+ }
+ res.setHeader("Content-Type", "application/octet-stream");
+ res.setHeader("Cache-Control", "no-cache");
+ createReadStream(filePath)
+ .on("error", () => next())
+ .pipe(res);
+ });
+ },
+ };
+}
+
export default defineConfig({
- plugins: [react()],
+ plugins: [react(), kuromojiDictRaw()],
base: "/",
+ resolve: {
+ alias: {
+ // 校正 worker が使う textlint / kuromoji 依存が参照する node 組み込みのうち、
+ // 実行時に実際に呼ばれる path / os / assert はブラウザ実装へ差し替える。
+ // fs は本機能で経路を踏まない(YAML は ?raw 文字列で渡す)ため、
+ // Vite 既定の空モジュール externalize に任せる(別途エイリアスしない)。
+ path: "path-browserify",
+ "node:path": "path-browserify",
+ os: "os-browserify/browser",
+ "node:os": "os-browserify/browser",
+ assert: "assert",
+ "node:assert": "assert",
+ },
+ },
+ // worker は動的 import でルールを分割ロードする(コード分割)。
+ // iife/umd は code-splitting 非対応なので ES モジュール形式で出力する。
+ worker: {
+ format: "es",
+ },
server: {
host: "0.0.0.0",
port: 5173,