@mew-lab/a11y-cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,16 +1,18 @@
1
1
  import {
2
+ A11yError,
3
+ API_VERSION,
4
+ ERROR_CODES,
2
5
  checklist,
3
6
  humanLog,
4
7
  isJsonMode,
5
8
  jsonOut,
6
9
  patternDetail,
7
10
  patternList,
8
- reportError,
9
11
  search,
10
12
  setJsonMode,
11
13
  wcagDetail,
12
14
  wcagList
13
- } from "./chunk-Y6KJQSVY.js";
15
+ } from "./chunk-Q5KNFZTF.js";
14
16
 
15
17
  // src/index.ts
16
18
  import { createRequire } from "module";
@@ -161,9 +163,7 @@ function formatWcagDetail(d) {
161
163
  if (d.relatedPatterns.length > 0) {
162
164
  out.push("");
163
165
  out.push(heading("\u95A2\u9023\u3059\u308B APG \u30D1\u30BF\u30FC\u30F3"));
164
- for (const line of table(
165
- d.relatedPatterns.map((p) => [` ${pc.green(p.slug)}`, p.ja])
166
- )) {
166
+ for (const line of table(d.relatedPatterns.map((p) => [` ${pc.green(p.slug)}`, p.ja]))) {
167
167
  out.push(line);
168
168
  }
169
169
  }
@@ -377,6 +377,39 @@ function formatDoctor(data) {
377
377
  ` \u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0: ${data.platform} / ${data.arch}`
378
378
  ].join("\n");
379
379
  }
380
+ function reportError(err) {
381
+ let message;
382
+ let code = ERROR_CODES.ERR_UNKNOWN;
383
+ let suggestions;
384
+ if (err instanceof A11yError) {
385
+ message = err.message;
386
+ code = err.code;
387
+ suggestions = err.suggestions;
388
+ } else if (err instanceof Error) {
389
+ message = err.message;
390
+ } else {
391
+ message = String(err);
392
+ }
393
+ if (isJsonMode()) {
394
+ console.log(
395
+ JSON.stringify(
396
+ { apiVersion: API_VERSION, error: message, code, suggestions: suggestions ?? void 0 },
397
+ null,
398
+ 2
399
+ )
400
+ );
401
+ } else {
402
+ console.error(pc2.red(`\u30A8\u30E9\u30FC: ${message}`));
403
+ if (suggestions && suggestions.length > 0) {
404
+ console.error("");
405
+ console.error("\u3082\u3057\u304B\u3057\u3066:");
406
+ for (const s of suggestions) {
407
+ console.error(` ${pc2.cyan(s.slug)} \u2014 ${s.reason}`);
408
+ }
409
+ }
410
+ }
411
+ process.exit(1);
412
+ }
380
413
  async function run(argv) {
381
414
  const program = buildProgram();
382
415
  if (argv.length <= 2) {
@@ -390,4 +423,3 @@ export {
390
423
  buildProgram,
391
424
  run
392
425
  };
393
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mew-lab/a11y-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "WAI-ARIA APG パターンと WCAG 2.2 のアクセシビリティ観点を CLI/JSON で引けるツール(AI エージェント対応)",
6
6
  "license": "MIT",
@@ -14,6 +14,14 @@
14
14
  "japanese"
15
15
  ],
16
16
  "homepage": "https://a11y.mew-lab.com",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/wataryooou/a11y.git",
20
+ "directory": "packages/cli"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/wataryooou/a11y/issues"
24
+ },
17
25
  "bin": {
18
26
  "a11y": "./bin/a11y.mjs"
19
27
  },
@@ -48,7 +56,7 @@
48
56
  "@types/node": "^22.10.5",
49
57
  "tsup": "^8.3.5",
50
58
  "typescript": "^5.7.3",
51
- "vitest": "^2.1.8"
59
+ "vitest": "^4.1.9"
52
60
  },
53
61
  "publishConfig": {
54
62
  "access": "public"
package/dist/api.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../core/src/schema.ts","../../core/src/patterns/index.ts","../../core/src/wcag.ts","../../core/src/patterns/viewpoints/accordion.ts","../../core/src/patterns/viewpoints/disclosure.ts","../../core/src/patterns/viewpoints/alert.ts","../../core/src/patterns/viewpoints/dialog-modal.ts","../../core/src/patterns/viewpoints/alertdialog.ts","../../core/src/patterns/viewpoints/breadcrumb.ts","../../core/src/patterns/viewpoints/menu-menubar.ts","../../core/src/patterns/viewpoints/menu-button.ts","../../core/src/patterns/viewpoints/link.ts","../../core/src/patterns/viewpoints/landmarks.ts","../../core/src/patterns/viewpoints/button.ts","../../core/src/patterns/viewpoints/checkbox.ts","../../core/src/patterns/viewpoints/radio-group.ts","../../core/src/patterns/viewpoints/switch.ts","../../core/src/patterns/viewpoints/combobox.ts","../../core/src/patterns/viewpoints/listbox.ts","../../core/src/patterns/viewpoints/slider.ts","../../core/src/patterns/viewpoints/slider-multithumb.ts","../../core/src/patterns/viewpoints/spinbutton.ts","../../core/src/patterns/viewpoints/meter.ts","../../core/src/patterns/viewpoints/tabs.ts","../../core/src/patterns/viewpoints/toolbar.ts","../../core/src/patterns/viewpoints/table.ts","../../core/src/patterns/viewpoints/grid.ts","../../core/src/patterns/viewpoints/treegrid.ts","../../core/src/patterns/viewpoints/tree-view.ts","../../core/src/patterns/viewpoints/feed.ts","../../core/src/patterns/viewpoints/carousel.ts","../../core/src/patterns/viewpoints/tooltip.ts","../../core/src/patterns/viewpoints/window-splitter.ts","../../core/src/patterns/viewpoints.ts","../../core/src/index.ts","../src/output.ts","../src/api.ts"],"sourcesContent":["// アクセシビリティ観点データの zod スキーマ(型は zod から推論する)。\n// core は唯一の真実なので、データ投入時にここで定義したスキーマで検証する。\nimport { z } from 'zod';\n\n// ───────────────────────────── パターン(メタ) ─────────────────────────────\n\n/** カテゴリの表示順(ナビ・一覧のグルーピング用) */\nexport const categories = [\n '開閉・展開',\n '通知・ダイアログ',\n 'ナビゲーション',\n 'フォーム・入力',\n 'タブ・ツールバー',\n 'データ表示',\n 'その他',\n] as const;\nexport type Category = (typeof categories)[number];\n\nexport const patternStatusSchema = z.enum(['ready', 'planned']);\nexport type PatternStatus = z.infer<typeof patternStatusSchema>;\n\nexport const patternSchema = z.object({\n /** URL に使う識別子 */\n slug: z.string().min(1),\n /** 日本語タイトル */\n ja: z.string().min(1),\n /** 英語タイトル(APG 原文) */\n en: z.string().min(1),\n /** カテゴリ(一覧のグルーピング用) */\n category: z.enum(categories),\n /** 一覧カードに出す1〜2文の要約 */\n summary: z.string().min(1),\n status: patternStatusSchema,\n});\nexport type Pattern = z.infer<typeof patternSchema>;\n\n// ───────────────────────────── WCAG 達成基準 ─────────────────────────────\n\nexport const levelSchema = z.enum(['A', 'AA', 'AAA']);\nexport type Level = z.infer<typeof levelSchema>;\n\nexport const principles = ['知覚可能', '操作可能', '理解可能', '堅牢'] as const;\nexport type Principle = (typeof principles)[number];\nexport const principleSchema = z.enum(principles);\n\nexport const criterionSchema = z.object({\n /** 達成基準番号(例: \"2.1.1\")。表示・並び替えのキー */\n num: z.string().min(1),\n /** URL に使う識別子(例: \"2-1-1\") */\n slug: z.string().min(1),\n /** 日本語の名称(waic.jp 訳に準拠) */\n ja: z.string().min(1),\n /** 英語の名称(WCAG 原文) */\n en: z.string().min(1),\n /** 適合レベル */\n level: levelSchema,\n /** 4つの原則 */\n principle: principleSchema,\n /** 所属ガイドライン(例: \"2.1 キーボード操作可能\") */\n guideline: z.string().min(1),\n /** WCAG 2.2 で新設された達成基準なら true */\n isNew22: z.boolean().optional(),\n /** 学習者向けのやさしい日本語要約(1〜2文・自作) */\n summary: z.string().min(1),\n /** waic.jp 日本語訳の該当アンカー */\n waicUrl: z.string().url(),\n /** Understanding(英語・公式解説)の URL */\n understandingUrl: z.string().url(),\n /** 関連する APG パターンの slug(patterns と一致) */\n patterns: z.array(z.string()),\n});\nexport type Criterion = z.infer<typeof criterionSchema>;\n\n// ───────────────────────────── パターン観点(CLI/Web 共通) ─────────────────────────────\n\n/** 操作の必須度 */\nexport const requirementSchema = z.enum(['required', 'recommended', 'optional']);\nexport type Requirement = z.infer<typeof requirementSchema>;\n\nexport const keyboardRowSchema = z.object({\n /** 例: \"Enter / Space\" */\n keys: z.string().min(1),\n /** その操作で起きること */\n action: z.string().min(1),\n requirement: requirementSchema,\n});\nexport type KeyboardRow = z.infer<typeof keyboardRowSchema>;\n\nexport const ariaRowSchema = z.object({\n /** 付ける場所(例: \"見出しのボタン\") */\n target: z.string().min(1),\n /** 属性 / ロール(例: 'aria-expanded=\"true | false\"') */\n attr: z.string().min(1),\n /** 意味・狙い */\n meaning: z.string().min(1),\n});\nexport type AriaRow = z.infer<typeof ariaRowSchema>;\n\nexport const antipatternSchema = z.object({\n /** アンチパターンの要点(例: \"div + onclick で作る\") */\n title: z.string().min(1),\n /** なぜダメか */\n why: z.string().min(1),\n});\nexport type Antipattern = z.infer<typeof antipatternSchema>;\n\nexport const patternViewpointSchema = z.object({\n /** patterns(メタ)の slug と一致 */\n slug: z.string().min(1),\n /** キーボード操作 */\n keyboard: z.array(keyboardRowSchema),\n /** 必要な WAI-ARIA / ロール */\n aria: z.array(ariaRowSchema),\n /** 実装チェックリスト */\n checklist: z.array(z.string().min(1)),\n /** アンチパターン(Bad の要点) */\n antipatterns: z.array(antipatternSchema),\n /** 補足メモ(任意) */\n notes: z.array(z.string().min(1)).optional(),\n});\nexport type PatternViewpoint = z.infer<typeof patternViewpointSchema>;\n\n// ───────────────────────────── 合成型 ─────────────────────────────\n\n/** パターン詳細 = メタ + 観点 + 関連 WCAG */\nexport interface PatternDetail extends Pattern {\n viewpoint: PatternViewpoint | null;\n criteria: Criterion[];\n}\n\n/** WCAG 詳細 = 達成基準 + 関連パターン(メタ) */\nexport interface CriterionDetail extends Criterion {\n relatedPatterns: Pattern[];\n}\n","// WAI-ARIA APG の Patterns 一覧(日本語メタデータ)\n// 出典: https://www.w3.org/WAI/ARIA/apg/patterns/\n//\n// status:\n// 'ready' … 解説・デモ・Good/Bad まで完成\n// 'planned' … これから作成(一覧には出すが詳細は「準備中」表示)\nimport { categories, patternSchema, type Pattern } from '../schema';\n\nconst rawPatterns: Pattern[] = [\n // ── 開閉・展開 ──────────────────────────────\n {\n slug: 'accordion',\n ja: 'アコーディオン',\n en: 'Accordion',\n category: '開閉・展開',\n summary:\n '見出しを押すとパネルが開閉する UI。ボタンと aria-expanded で「今開いているか」を支援技術へ正しく伝えます。',\n status: 'ready',\n },\n {\n slug: 'disclosure',\n ja: 'ディスクロージャー(開閉)',\n en: 'Disclosure',\n category: '開閉・展開',\n summary: '「もっと見る」のように1つの領域を表示/非表示するもっともシンプルな開閉パターン。',\n status: 'ready',\n },\n\n // ── 通知・ダイアログ ────────────────────────\n {\n slug: 'alert',\n ja: 'アラート(通知)',\n en: 'Alert',\n category: '通知・ダイアログ',\n summary: 'フォーカスを奪わずに重要メッセージを即座に読み上げる、live region を使った通知。',\n status: 'ready',\n },\n {\n slug: 'dialog-modal',\n ja: 'モーダルダイアログ',\n en: 'Dialog (Modal)',\n category: '通知・ダイアログ',\n summary: '背面を操作不能にして前面に出すダイアログ。フォーカストラップと Esc 閉じが要。',\n status: 'ready',\n },\n {\n slug: 'alertdialog',\n ja: 'アラートダイアログ',\n en: 'Alert and Message Dialogs',\n category: '通知・ダイアログ',\n summary: '「本当に削除しますか?」など、ユーザーの確認・応答を求めるダイアログ。',\n status: 'ready',\n },\n\n // ── ナビゲーション ─────────────────────────\n {\n slug: 'breadcrumb',\n ja: 'パンくずリスト',\n en: 'Breadcrumb',\n category: 'ナビゲーション',\n summary: 'サイト内の現在位置を示すナビ。nav とリスト、現在地の aria-current が肝。',\n status: 'ready',\n },\n {\n slug: 'menu-menubar',\n ja: 'メニュー / メニューバー',\n en: 'Menu and Menubar',\n category: 'ナビゲーション',\n summary: 'アプリ的なメニュー。矢印キー操作と role=\"menu\" 系のロールで構成します。',\n status: 'ready',\n },\n {\n slug: 'menu-button',\n ja: 'メニューボタン',\n en: 'Menu Button',\n category: 'ナビゲーション',\n summary: '押すとメニューを開くボタン。aria-haspopup と aria-expanded で関係を伝えます。',\n status: 'ready',\n },\n {\n slug: 'link',\n ja: 'リンク',\n en: 'Link',\n category: 'ナビゲーション',\n summary: '基本にして奥深いリンク。div の onclick ではなく a 要素を使う理由を解説。',\n status: 'ready',\n },\n {\n slug: 'landmarks',\n ja: 'ランドマーク',\n en: 'Landmarks',\n category: 'ナビゲーション',\n summary: 'header / nav / main / footer などでページを領域分けし、素早い移動を可能に。',\n status: 'ready',\n },\n\n // ── フォーム・入力 ─────────────────────────\n {\n slug: 'button',\n ja: 'ボタン',\n en: 'Button',\n category: 'フォーム・入力',\n summary: 'すべての基本。button 要素を使えば得られるアクセシビリティと、自作の落とし穴。',\n status: 'ready',\n },\n {\n slug: 'checkbox',\n ja: 'チェックボックス',\n en: 'Checkbox',\n category: 'フォーム・入力',\n summary: 'オン/オフの選択。中間状態(mixed)を含むチェックボックスの扱いも。',\n status: 'ready',\n },\n {\n slug: 'radio-group',\n ja: 'ラジオグループ',\n en: 'Radio Group',\n category: 'フォーム・入力',\n summary: '複数から1つを選ぶ。矢印キー移動と roving tabindex の代表例。',\n status: 'ready',\n },\n {\n slug: 'switch',\n ja: 'スイッチ',\n en: 'Switch',\n category: 'フォーム・入力',\n summary: 'オン/オフのトグル。チェックボックスとの違いと role=\"switch\" の使い方。',\n status: 'ready',\n },\n {\n slug: 'combobox',\n ja: 'コンボボックス',\n en: 'Combobox',\n category: 'フォーム・入力',\n summary: '入力+候補リスト(オートコンプリート)。APG でも最難関の1つ。',\n status: 'ready',\n },\n {\n slug: 'listbox',\n ja: 'リストボックス',\n en: 'Listbox',\n category: 'フォーム・入力',\n summary: '選択肢のリストから選ぶ。単一/複数選択と矢印キー操作。',\n status: 'ready',\n },\n {\n slug: 'slider',\n ja: 'スライダー',\n en: 'Slider',\n category: 'フォーム・入力',\n summary: '値を範囲から選ぶ。aria-valuenow/min/max とキーボード操作。',\n status: 'ready',\n },\n {\n slug: 'slider-multithumb',\n ja: 'スライダー(複数つまみ)',\n en: 'Slider (Multi-Thumb)',\n category: 'フォーム・入力',\n summary: '価格帯などの範囲選択。つまみ同士の干渉とラベリングが論点。',\n status: 'ready',\n },\n {\n slug: 'spinbutton',\n ja: 'スピンボタン',\n en: 'Spinbutton',\n category: 'フォーム・入力',\n summary: '数値の増減入力。上下キーとボタンでの増減、範囲の通知。',\n status: 'ready',\n },\n {\n slug: 'meter',\n ja: 'メーター',\n en: 'Meter',\n category: 'フォーム・入力',\n summary: '既知の範囲内の量(ディスク使用率など)を示す表示専用の指標。',\n status: 'ready',\n },\n\n // ── タブ・ツールバー ───────────────────────\n {\n slug: 'tabs',\n ja: 'タブ',\n en: 'Tabs',\n category: 'タブ・ツールバー',\n summary: '同じ領域で内容を切り替える。矢印キー移動・aria-selected・roving tabindex。',\n status: 'ready',\n },\n {\n slug: 'toolbar',\n ja: 'ツールバー',\n en: 'Toolbar',\n category: 'タブ・ツールバー',\n summary: 'ボタン群をまとめ、Tab 1回で入って矢印で移動できるようにするパターン。',\n status: 'ready',\n },\n\n // ── データ表示 ─────────────────────────────\n {\n slug: 'table',\n ja: 'テーブル',\n en: 'Table',\n category: 'データ表示',\n summary: '表データ。table 要素と見出しセルの関連付けが読み上げの鍵。',\n status: 'ready',\n },\n {\n slug: 'grid',\n ja: 'グリッド',\n en: 'Grid',\n category: 'データ表示',\n summary: 'セル単位でキーボード操作できる対話的な表(データグリッド)。',\n status: 'ready',\n },\n {\n slug: 'treegrid',\n ja: 'ツリーグリッド',\n en: 'Treegrid',\n category: 'データ表示',\n summary: '行を展開/折りたたみできるグリッド。ツリーとグリッドの複合。',\n status: 'ready',\n },\n {\n slug: 'tree-view',\n ja: 'ツリービュー',\n en: 'Tree View',\n category: 'データ表示',\n summary: '階層構造の表示。フォルダツリーのような展開・移動操作。',\n status: 'ready',\n },\n {\n slug: 'feed',\n ja: 'フィード',\n en: 'Feed',\n category: 'データ表示',\n summary: '無限スクロールの記事一覧を、支援技術でも読み進められるようにする。',\n status: 'ready',\n },\n\n // ── その他 ─────────────────────────────────\n {\n slug: 'carousel',\n ja: 'カルーセル',\n en: 'Carousel',\n category: 'その他',\n summary: '自動で切り替わるスライド。再生/停止と読み上げ配慮が重要。',\n status: 'ready',\n },\n {\n slug: 'tooltip',\n ja: 'ツールチップ',\n en: 'Tooltip',\n category: 'その他',\n summary: 'フォーカス/ホバーで出る補足。aria-describedby とキーボード対応。',\n status: 'ready',\n },\n {\n slug: 'window-splitter',\n ja: 'ウィンドウスプリッター',\n en: 'Window Splitter',\n category: 'その他',\n summary: '2つの領域の境界をドラッグ/キーで動かすリサイズ用のハンドル。',\n status: 'ready',\n },\n];\n\n/** メタ一覧(投入時に zod 検証する) */\nexport const patterns: Pattern[] = patternSchema.array().parse(rawPatterns);\n\n/** slug で1件取得 */\nexport function getPattern(slug: string): Pattern | undefined {\n return patterns.find((p) => p.slug === slug);\n}\n\n/** カテゴリ順にグルーピングして返す */\nexport function patternsByCategory(): { category: string; items: Pattern[] }[] {\n return categories.map((category) => ({\n category,\n items: patterns.filter((p) => p.category === category),\n }));\n}\n","// WCAG 2.2 達成基準(日本語メタデータ)\n// 規範訳の出典: https://waic.jp/translations/WCAG22/ (ウェブアクセシビリティ基盤委員会 WAIC)\n// Understanding(英語・公式): https://www.w3.org/WAI/WCAG22/Understanding/\n//\n// 方針:\n// - 規範本文は再掲せず、waic.jp 訳 / Understanding へリンクする。\n// - summary は学習者向けの「やさしい日本語」要約(自作)。\n// - patterns は関連する APG パターンの slug(patterns/index.ts と一致させる)。\n// マッピングはこの達成基準側に集約し、パターン側はヘルパで逆引きする\n// (= パターンメタを無改造に保つための単一の真実の源)。\nimport { principles, criterionSchema, type Criterion, type Principle } from './schema';\n\n// waic.jp / Understanding の URL を英語アンカー(ケバブケース)から組み立てる\nconst waic = (anchor: string) => `https://waic.jp/translations/WCAG22/#${anchor}`;\nconst understanding = (anchor: string) =>\n `https://www.w3.org/WAI/WCAG22/Understanding/${anchor}.html`;\n\nconst rawCriteria: Criterion[] = [\n // ───────────────────────────────────────── 知覚可能 ─────\n {\n num: '1.1.1',\n slug: '1-1-1',\n ja: '非テキストコンテンツ',\n en: 'Non-text Content',\n level: 'A',\n principle: '知覚可能',\n guideline: '1.1 テキストによる代替',\n summary:\n '画像・アイコン・図など文字でないコンテンツには、同じ意味を伝える代替テキストを用意する。装飾だけのものは支援技術から隠す。',\n waicUrl: waic('non-text-content'),\n understandingUrl: understanding('non-text-content'),\n patterns: ['meter', 'table'],\n },\n {\n num: '1.3.1',\n slug: '1-3-1',\n ja: '情報及び関係性',\n en: 'Info and Relationships',\n level: 'A',\n principle: '知覚可能',\n guideline: '1.3 適応可能',\n summary:\n '見た目で伝えている構造や関係(見出し・リスト・表の対応・ラベルと入力欄の結びつき)を、HTML のマークアップや ARIA でプログラムにも伝わる形にする。',\n waicUrl: waic('info-and-relationships'),\n understandingUrl: understanding('info-and-relationships'),\n patterns: [\n 'accordion',\n 'disclosure',\n 'alert',\n 'dialog-modal',\n 'alertdialog',\n 'breadcrumb',\n 'menu-menubar',\n 'menu-button',\n 'link',\n 'landmarks',\n 'checkbox',\n 'radio-group',\n 'switch',\n 'combobox',\n 'listbox',\n 'meter',\n 'tabs',\n 'table',\n 'grid',\n 'treegrid',\n 'tree-view',\n 'feed',\n 'carousel',\n 'tooltip',\n ],\n },\n {\n num: '1.4.3',\n slug: '1-4-3',\n ja: 'コントラスト(最低限)',\n en: 'Contrast (Minimum)',\n level: 'AA',\n principle: '知覚可能',\n guideline: '1.4 判別可能',\n summary:\n '文字と背景の明暗の差(コントラスト比)を、通常の文字で 4.5:1 以上、大きな文字で 3:1 以上にする。',\n waicUrl: waic('contrast-minimum'),\n understandingUrl: understanding('contrast-minimum'),\n patterns: [],\n },\n {\n num: '1.4.11',\n slug: '1-4-11',\n ja: '非テキストのコントラスト',\n en: 'Non-text Contrast',\n level: 'AA',\n principle: '知覚可能',\n guideline: '1.4 判別可能',\n summary:\n 'ボタンの境界やフォーム部品、状態を示すアイコンなど、操作に必要な見た目の要素も背景と 3:1 以上のコントラストを確保する。',\n waicUrl: waic('non-text-contrast'),\n understandingUrl: understanding('non-text-contrast'),\n patterns: ['button', 'slider', 'slider-multithumb'],\n },\n {\n num: '1.4.13',\n slug: '1-4-13',\n ja: 'ホバー又はフォーカスで表示されるコンテンツ',\n en: 'Content on Hover or Focus',\n level: 'AA',\n principle: '知覚可能',\n guideline: '1.4 判別可能',\n summary:\n 'ホバーやフォーカスで出る追加表示(ツールチップ等)は、消さずに読める・ポインタを重ねられる・Esc などで消せる、の3つを満たす。',\n waicUrl: waic('content-on-hover-or-focus'),\n understandingUrl: understanding('content-on-hover-or-focus'),\n patterns: ['tooltip'],\n },\n\n // ───────────────────────────────────────── 操作可能 ─────\n {\n num: '2.1.1',\n slug: '2-1-1',\n ja: 'キーボード',\n en: 'Keyboard',\n level: 'A',\n principle: '操作可能',\n guideline: '2.1 キーボード操作可能',\n summary:\n 'すべての機能をキーボードだけで操作できるようにする。マウス前提の独自部品でも、Tab で到達し Enter/Space/矢印などで操作できること。',\n waicUrl: waic('keyboard'),\n understandingUrl: understanding('keyboard'),\n patterns: [\n 'accordion',\n 'disclosure',\n 'menu-menubar',\n 'menu-button',\n 'link',\n 'button',\n 'checkbox',\n 'radio-group',\n 'switch',\n 'combobox',\n 'listbox',\n 'slider',\n 'slider-multithumb',\n 'spinbutton',\n 'tabs',\n 'toolbar',\n 'grid',\n 'treegrid',\n 'tree-view',\n 'carousel',\n 'window-splitter',\n ],\n },\n {\n num: '2.1.2',\n slug: '2-1-2',\n ja: 'キーボードトラップなし',\n en: 'No Keyboard Trap',\n level: 'A',\n principle: '操作可能',\n guideline: '2.1 キーボード操作可能',\n summary:\n 'キーボードで入った場所からキーボードだけで抜け出せるようにする。モーダル内でフォーカスが閉じ込められたまま戻れない状態を作らない。',\n waicUrl: waic('no-keyboard-trap'),\n understandingUrl: understanding('no-keyboard-trap'),\n patterns: ['dialog-modal', 'alertdialog'],\n },\n {\n num: '2.2.2',\n slug: '2-2-2',\n ja: '一時停止、停止、非表示',\n en: 'Pause, Stop, Hide',\n level: 'A',\n principle: '操作可能',\n guideline: '2.2 十分な時間',\n summary:\n '自動で動く・点滅する・スクロールするコンテンツ(カルーセル等)は、ユーザーが一時停止・停止・非表示にできるようにする。',\n waicUrl: waic('pause-stop-hide'),\n understandingUrl: understanding('pause-stop-hide'),\n patterns: ['carousel'],\n },\n {\n num: '2.4.3',\n slug: '2-4-3',\n ja: 'フォーカス順序',\n en: 'Focus Order',\n level: 'A',\n principle: '操作可能',\n guideline: '2.4 ナビゲーション可能',\n summary:\n 'フォーカスが移る順番を、意味と操作が通じる自然な順序にする。ダイアログを開いたら中へ、閉じたら元の位置へ、といった移動も含む。',\n waicUrl: waic('focus-order'),\n understandingUrl: understanding('focus-order'),\n patterns: [\n 'accordion',\n 'dialog-modal',\n 'alertdialog',\n 'breadcrumb',\n 'menu-menubar',\n 'landmarks',\n 'radio-group',\n 'tabs',\n 'toolbar',\n 'grid',\n ],\n },\n {\n num: '2.4.7',\n slug: '2-4-7',\n ja: 'フォーカスの可視化',\n en: 'Focus Visible',\n level: 'AA',\n principle: '操作可能',\n guideline: '2.4 ナビゲーション可能',\n summary:\n 'キーボードで操作している今どこにフォーカスがあるかが、見て分かるようにする。フォーカスリングを消したままにしない。',\n waicUrl: waic('focus-visible'),\n understandingUrl: understanding('focus-visible'),\n patterns: ['accordion', 'disclosure', 'dialog-modal', 'menu-menubar', 'link', 'button', 'tabs'],\n },\n {\n num: '2.4.11',\n slug: '2-4-11',\n ja: '隠されないフォーカス(最低限)',\n en: 'Focus Not Obscured (Minimum)',\n level: 'AA',\n principle: '操作可能',\n guideline: '2.4 ナビゲーション可能',\n isNew22: true,\n summary:\n 'キーボードでフォーカスした要素が、固定ヘッダーやダイアログなどに完全に隠れて見えなくならないようにする。',\n waicUrl: waic('focus-not-obscured-minimum'),\n understandingUrl: understanding('focus-not-obscured-minimum'),\n patterns: ['dialog-modal'],\n },\n {\n num: '2.5.7',\n slug: '2-5-7',\n ja: 'ドラッグ動作',\n en: 'Dragging Movements',\n level: 'AA',\n principle: '操作可能',\n guideline: '2.5 入力モダリティ',\n isNew22: true,\n summary:\n 'ドラッグで行う操作(スライダー・並べ替え・境界の移動など)には、ドラッグを使わない代替手段(クリックやボタン)も用意する。',\n waicUrl: waic('dragging-movements'),\n understandingUrl: understanding('dragging-movements'),\n patterns: ['slider', 'slider-multithumb', 'window-splitter'],\n },\n {\n num: '2.5.8',\n slug: '2-5-8',\n ja: 'ターゲットのサイズ(最小)',\n en: 'Target Size (Minimum)',\n level: 'AA',\n principle: '操作可能',\n guideline: '2.5 入力モダリティ',\n isNew22: true,\n summary:\n 'クリック・タップできる対象は原則 24×24 CSSピクセル以上にするか、十分な間隔を空ける。小さすぎる操作対象を避ける。',\n waicUrl: waic('target-size-minimum'),\n understandingUrl: understanding('target-size-minimum'),\n patterns: ['menu-button', 'link', 'button', 'checkbox', 'switch', 'spinbutton'],\n },\n\n // ───────────────────────────────────────── 理解可能 ─────\n {\n num: '3.2.1',\n slug: '3-2-1',\n ja: 'フォーカス時',\n en: 'On Focus',\n level: 'A',\n principle: '理解可能',\n guideline: '3.2 予測可能',\n summary:\n '要素にフォーカスしただけで、ページ遷移やモーダル表示など文脈が勝手に変わることのないようにする。',\n waicUrl: waic('on-focus'),\n understandingUrl: understanding('on-focus'),\n patterns: [],\n },\n {\n num: '3.2.2',\n slug: '3-2-2',\n ja: '入力時',\n en: 'On Input',\n level: 'A',\n principle: '理解可能',\n guideline: '3.2 予測可能',\n summary:\n '値を選んだり入力しただけで予期せず文脈が変わらないようにする。変える場合は事前に知らせる。',\n waicUrl: waic('on-input'),\n understandingUrl: understanding('on-input'),\n patterns: [],\n },\n {\n num: '3.2.6',\n slug: '3-2-6',\n ja: '一貫したヘルプ',\n en: 'Consistent Help',\n level: 'A',\n principle: '理解可能',\n guideline: '3.2 予測可能',\n isNew22: true,\n summary:\n '問い合わせ先やヘルプへの導線を複数ページで提供する場合、各ページで同じ相対的な位置・順序に置く。',\n waicUrl: waic('consistent-help'),\n understandingUrl: understanding('consistent-help'),\n patterns: [],\n },\n {\n num: '3.3.1',\n slug: '3-3-1',\n ja: 'エラーの特定',\n en: 'Error Identification',\n level: 'A',\n principle: '理解可能',\n guideline: '3.3 入力支援',\n summary:\n '入力エラーを自動検出したら、どこが・何が間違っているかをテキストで具体的に伝える。',\n waicUrl: waic('error-identification'),\n understandingUrl: understanding('error-identification'),\n patterns: [],\n },\n {\n num: '3.3.2',\n slug: '3-3-2',\n ja: 'ラベル又は説明',\n en: 'Labels or Instructions',\n level: 'A',\n principle: '理解可能',\n guideline: '3.3 入力支援',\n summary:\n 'フォーム部品には、何を入力すればよいか分かるラベルや説明を付ける。プレースホルダーだけに頼らない。',\n waicUrl: waic('labels-or-instructions'),\n understandingUrl: understanding('labels-or-instructions'),\n patterns: ['checkbox', 'radio-group', 'combobox', 'listbox', 'slider', 'spinbutton'],\n },\n {\n num: '3.3.7',\n slug: '3-3-7',\n ja: '冗長な入力',\n en: 'Redundant Entry',\n level: 'A',\n principle: '理解可能',\n guideline: '3.3 入力支援',\n isNew22: true,\n summary:\n '同じ手続きの中で一度入力した情報を再入力させない。自動入力するか、前に入力した値から選べるようにする。',\n waicUrl: waic('redundant-entry'),\n understandingUrl: understanding('redundant-entry'),\n patterns: [],\n },\n {\n num: '3.3.8',\n slug: '3-3-8',\n ja: 'アクセシブルな認証(最低限)',\n en: 'Accessible Authentication (Minimum)',\n level: 'AA',\n principle: '理解可能',\n guideline: '3.3 入力支援',\n isNew22: true,\n summary:\n 'ログイン認証で、記憶やパズルのような認知機能テストだけに頼らせない。パスワード管理やコピペ等の代替を妨げない。',\n waicUrl: waic('accessible-authentication-minimum'),\n understandingUrl: understanding('accessible-authentication-minimum'),\n patterns: [],\n },\n\n // ───────────────────────────────────────── 堅牢 ─────────\n {\n num: '4.1.2',\n slug: '4-1-2',\n ja: '名前(name)・役割(role)及び値(value)',\n en: 'Name, Role, Value',\n level: 'A',\n principle: '堅牢',\n guideline: '4.1 互換性',\n summary:\n 'すべての UI 部品について、名前(何か)・役割(種類)・状態や値(今どうなっているか)が支援技術に伝わるようにする。自作部品では ARIA で補う。',\n waicUrl: waic('name-role-value'),\n understandingUrl: understanding('name-role-value'),\n patterns: [\n 'accordion',\n 'disclosure',\n 'dialog-modal',\n 'alertdialog',\n 'breadcrumb',\n 'menu-menubar',\n 'menu-button',\n 'link',\n 'button',\n 'checkbox',\n 'radio-group',\n 'switch',\n 'combobox',\n 'listbox',\n 'slider',\n 'slider-multithumb',\n 'spinbutton',\n 'meter',\n 'tabs',\n 'toolbar',\n 'grid',\n 'treegrid',\n 'tree-view',\n 'feed',\n 'carousel',\n 'tooltip',\n 'window-splitter',\n ],\n },\n {\n num: '4.1.3',\n slug: '4-1-3',\n ja: 'ステータスメッセージ',\n en: 'Status Messages',\n level: 'AA',\n principle: '堅牢',\n guideline: '4.1 互換性',\n summary:\n '「保存しました」「3件ヒット」などの状態通知を、フォーカスを移さずに支援技術へ伝える。live region(aria-live / role=\"status\" 等)を使う。',\n waicUrl: waic('status-messages'),\n understandingUrl: understanding('status-messages'),\n patterns: ['alert', 'alertdialog', 'combobox', 'feed'],\n },\n];\n\n/** 達成基準一覧(投入時に zod 検証する) */\nexport const criteria: Criterion[] = criterionSchema.array().parse(rawCriteria);\n\n/** slug で1件取得 */\nexport function getCriterion(slug: string): Criterion | undefined {\n return criteria.find((c) => c.slug === slug);\n}\n\n/** num(\"2.1.1\")を数値比較できるよう [major, mid, minor] に分解 */\nfunction numKey(num: string): number[] {\n return num.split('.').map((n) => parseInt(n, 10));\n}\n\nfunction compareByNum(a: Criterion, b: Criterion): number {\n const ka = numKey(a.num);\n const kb = numKey(b.num);\n for (let i = 0; i < 3; i++) {\n const va = ka[i] ?? 0;\n const vb = kb[i] ?? 0;\n if (va !== vb) return va - vb;\n }\n return 0;\n}\n\n/** 原則順 → 番号順にグルーピングして返す */\nexport function criteriaByPrinciple(): { principle: Principle; items: Criterion[] }[] {\n return principles.map((principle) => ({\n principle,\n items: criteria.filter((c) => c.principle === principle).sort(compareByNum),\n }));\n}\n\n/** あるパターンに関連する達成基準を番号順で逆引きする */\nexport function criteriaForPattern(patternSlug: string): Criterion[] {\n return criteria.filter((c) => c.patterns.includes(patternSlug)).sort(compareByNum);\n}\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Accordion パターン。\nexport const accordion: PatternViewpoint = {\n slug: 'accordion',\n keyboard: [\n {\n keys: 'Enter / Space',\n action: 'フォーカスしている見出しのパネルを開く/閉じる',\n requirement: 'required',\n },\n {\n keys: 'Tab',\n action: '次のフォーカス可能要素(次の見出しなど)へ移動',\n requirement: 'required',\n },\n {\n keys: '↓ / ↑',\n action: '次 / 前の見出しへフォーカス移動',\n requirement: 'recommended',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の見出しへフォーカス移動',\n requirement: 'optional',\n },\n ],\n aria: [\n {\n target: '見出しのボタン',\n attr: 'aria-expanded=\"true | false\"',\n meaning: '対応するパネルが開いているか。状態の変化に合わせて必ず更新する。',\n },\n {\n target: '見出しのボタン',\n attr: 'aria-controls=\"パネルのid\"',\n meaning: 'どのパネルを制御するボタンかを示す。',\n },\n {\n target: '見出しの外側',\n attr: '<h2>〜<h4>',\n meaning:\n 'ページの構造に合った見出しレベルで囲む。スクリーンリーダーの見出しジャンプに役立つ。',\n },\n {\n target: 'パネル',\n attr: 'role=\"region\" + aria-labelledby=\"見出しのid\"',\n meaning:\n 'パネルを名前付きの領域にする(任意だが推奨。領域が多すぎると逆効果なので数が多いときは省略可)。',\n },\n {\n target: '閉じているパネル',\n attr: 'hidden',\n meaning: '閉じている間は DOM から隠し、キーボード/読み上げの対象外にする。',\n },\n ],\n checklist: [\n '見出しのトリガーは <button type=\"button\"> である',\n 'ボタンは見出し要素(<h2>〜<h4>)で囲まれている',\n 'aria-expanded が開閉と常に一致している',\n 'aria-controls でパネルの id を指している',\n '閉じているパネルは hidden でキーボード/読み上げから外れている',\n 'パネルに role=\"region\" + aria-labelledby(任意・推奨)',\n 'キーボードだけで開閉でき、フォーカスが見える(フォーカスリングを消していない)',\n '(任意)↑ ↓ Home End で見出し間を移動できる',\n ],\n antipatterns: [\n {\n title: 'div + onclick で見出しを作る',\n why: 'div はフォーカスを受け取れず、キーボードで一切操作できない。',\n },\n {\n title: '役割(role)を伝えない',\n why: 'スクリーンリーダーには「ただのテキスト」に聞こえ、押せることが伝わらない。',\n },\n {\n title: '状態を伝えない',\n why: 'aria-expanded がなく、開いているか閉じているかを判別できない。',\n },\n {\n title: 'display:none 頼みで隠す',\n why: 'hidden 属性や適切な状態管理がなく、インライン style 頼みになっている。',\n },\n ],\n notes: [\n 'Enter / Space での開閉は、見出しを <button> にするだけで自動的に得られる(自前のキー処理は不要)。',\n '「同時に1つだけ開く」挙動でも、すべて閉じられるようにしておくのが親切(APG 推奨)。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Disclosure パターン。\nexport const disclosure: PatternViewpoint = {\n slug: 'disclosure',\n keyboard: [\n {\n keys: 'Enter / Space',\n action: '領域を開く / 閉じる',\n requirement: 'required',\n },\n {\n keys: 'Tab',\n action: '次 / 前のフォーカス可能要素へ移動',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'トリガー',\n attr: '<button type=\"button\">',\n meaning: '押せる要素にする。フォーカス・Enter/Space・「ボタン」ロールが自動で付く。',\n },\n {\n target: 'トリガー',\n attr: 'aria-expanded=\"true | false\"',\n meaning: '領域が開いているか。状態の変化に合わせて必ず更新する。',\n },\n {\n target: 'トリガー',\n attr: 'aria-controls=\"領域のid\"',\n meaning: 'どの領域を制御するボタンかを示す。',\n },\n {\n target: '閉じている領域',\n attr: 'hidden',\n meaning: '閉じている間は DOM から隠し、キーボード/読み上げの対象外にする。',\n },\n ],\n checklist: [\n 'トリガーは <button type=\"button\"> である',\n 'aria-expanded が開閉と常に一致している',\n 'aria-controls で領域の id を指している',\n '閉じている領域は hidden でキーボード/読み上げから外れている',\n 'キーボードだけで開閉でき、フォーカスが見える(フォーカスリングを消していない)',\n '(任意)ボタンのラベルが開閉に合わせて切り替わる',\n ],\n antipatterns: [\n {\n title: 'div + onclick でトリガーを作る',\n why: 'div はフォーカスを受け取れず、キーボードで一切操作できない。',\n },\n {\n title: '役割を伝えない',\n why: 'スクリーンリーダーには「ただのテキスト」に聞こえ、押せると分からない。',\n },\n {\n title: '状態を伝えない',\n why: 'aria-expanded がなく、開/閉が判別できない。',\n },\n {\n title: 'display:none のインラインスタイル頼みにする',\n why: 'hidden 属性や状態管理が無く、支援技術に隠れているかどうかが伝わらない。',\n },\n ],\n notes: [\n 'Enter / Space での開閉は、トリガーを <button> にするだけで自動的に得られます(自前のキー処理は不要)。',\n 'ボタンのラベルを「もっと見る」⇄「閉じる」のように切り替えると、晴眼のユーザーにも次の動作が伝わって親切です。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Alert パターン。\nexport const alert: PatternViewpoint = {\n slug: 'alert',\n keyboard: [\n {\n keys: '(専用キーなし)',\n action: 'アラート自体に特別なキー操作はない。フォーカスを移さないのが正しい挙動。',\n requirement: 'required',\n },\n {\n keys: 'Tab',\n action: 'メッセージを表示させるトリガー(ボタンなど)へは通常どおり移動できる。',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: '通知領域のコンテナ',\n attr: 'role=\"alert\"',\n meaning: '緊急の読み上げ領域にする。aria-live=\"assertive\" 相当の挙動になる。',\n },\n {\n target: '通知領域のコンテナ',\n attr: 'aria-atomic=\"true\"(任意)',\n meaning: '内容が変わったとき、領域全体をまとめて読み上げる。',\n },\n {\n target: 'コンテナの設置タイミング',\n attr: '(属性ではなく実装)',\n meaning:\n '最初から空で DOM に置いておく。あとから文字を差し込むと読み上げられる。後から領域ごと挿入すると読まれないことがある。',\n },\n ],\n checklist: [\n 'role=\"alert\" の領域を最初から空で DOM に置いている',\n 'メッセージは領域のテキストを差し替える形で挿入している',\n 'アラート表示時にフォーカスを奪っていない',\n '緊急でない通知は role=\"status\"(polite)を使い分けている',\n '同じ文言の再通知は内容を変化させて確実に読み上げさせている',\n '閉じるボタンを付ける場合はキーボードで操作でき、フォーカスが見える',\n ],\n antipatterns: [\n {\n title: '読み上げられない',\n why: 'role=\"alert\" も aria-live も無いので、変化が通知されない。',\n },\n {\n title: '気づけない',\n why: '画面の別の場所を読んでいるスクリーンリーダー利用者には存在自体が分からない。',\n },\n {\n title: 'フォーカスを奪う',\n why: '「読み上げさせたいから」とフォーカスを奪うのも誤り。操作位置を見失わせる。',\n },\n ],\n notes: [\n '緊急でない通知(例:「自動保存しました」)は role=\"status\"(=aria-live=\"polite\")を使い、割り込まず読み上げるのが親切。',\n '同じ文言を続けて入れると読み上げが繰り返されないことがある。回数表示を加えるか、一度空にしてから入れ直すと確実。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Dialog (Modal) パターン。\nexport const dialogModal: PatternViewpoint = {\n slug: 'dialog-modal',\n keyboard: [\n {\n keys: 'Esc',\n action: 'ダイアログを閉じる(showModal() なら標準で対応)',\n requirement: 'required',\n },\n {\n keys: 'Tab / Shift+Tab',\n action: 'フォーカスがダイアログ内だけを循環する(外に漏れない)',\n requirement: 'required',\n },\n {\n keys: 'Enter / Space',\n action: 'フォーカス中のボタンを実行',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'ダイアログ本体',\n attr: '<dialog> 要素',\n meaning: '暗黙の role=\"dialog\" を持つ。showModal() でモーダルとして開く。',\n },\n {\n target: 'ダイアログ本体',\n attr: 'aria-labelledby=\"見出しのid\" または aria-label',\n meaning: 'ダイアログに名前を付ける(中の見出しを指すのが定番)。',\n },\n {\n target: 'ダイアログ本体',\n attr: 'aria-describedby(任意)',\n meaning: '補足の説明文を関連付ける。',\n },\n {\n target: '背面のコンテンツ',\n attr: '(自動)inert 相当',\n meaning:\n 'showModal() なら背面が自動で操作不可・読み上げ対象外になる。手動なら inert を付ける。',\n },\n ],\n checklist: [\n 'ネイティブ <dialog> を showModal() で開いている',\n 'ダイアログに aria-labelledby(または aria-label)で名前がある',\n '開くとフォーカスがダイアログ内へ移る',\n 'Tab がダイアログ内だけを循環する(背面に漏れない)',\n 'Esc で閉じる',\n '閉じると開いたトリガーへフォーカスが戻る',\n '背面が inert(操作・読み上げ不可)になっている',\n 'フォーカスリングを消していない',\n ],\n antipatterns: [\n {\n title: 'Tab が背面に漏れる',\n why: 'フォーカストラップが無く、見えない要素に移動できてしまう。',\n },\n {\n title: 'Esc で閉じない',\n why: 'キー処理を自分で書いていない。',\n },\n {\n title: '背面が inert でない',\n why: 'スクリーンリーダーで背面まで読めてしまう。',\n },\n {\n title: '閉じるのが <span>',\n why: 'フォーカスできず、キーボードでは閉じられない。',\n },\n {\n title: 'フォーカスの移動/復帰が無い',\n why: '開いてもダイアログに入らず、閉じても元へ戻らない。',\n },\n ],\n notes: [\n '<dialog aria-labelledby=\"title\"> のように中の見出しの id を指しておくと、スクリーンリーダーが「表示設定, ダイアログ」と読み上げてくれる。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Alert and Message Dialogs パターン。\nexport const alertdialog: PatternViewpoint = {\n slug: 'alertdialog',\n keyboard: [\n {\n keys: 'Esc',\n action: 'ダイアログを閉じる(=キャンセル扱い。showModal() なら標準対応)',\n requirement: 'required',\n },\n {\n keys: 'Tab / Shift+Tab',\n action: 'ボタン間を循環移動(ダイアログ内に閉じ込められる)',\n requirement: 'required',\n },\n {\n keys: 'Enter / Space',\n action: 'フォーカス中のボタンを実行',\n requirement: 'required',\n },\n {\n keys: '(開いた直後)',\n action: '初期フォーカスは安全側(キャンセル)のボタンに置く',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'ダイアログ本体',\n attr: 'role=\"alertdialog\"',\n meaning: '「重要な確認・警告のダイアログ」であることを伝える。',\n },\n {\n target: 'ダイアログ本体',\n attr: 'aria-modal=\"true\"',\n meaning: '背面が操作不可のモーダルであることを明示(role を上書きしたため明示する)。',\n },\n {\n target: 'ダイアログ本体',\n attr: 'aria-labelledby=\"タイトルのid\"',\n meaning: 'ダイアログの名前(質問文)を指す。',\n },\n {\n target: 'ダイアログ本体',\n attr: 'aria-describedby=\"説明のid\"',\n meaning: '結果の重大さを説明する本文を関連付け、開いた瞬間に読み上げさせる。',\n },\n {\n target: 'キャンセルボタン',\n attr: 'autofocus',\n meaning: '初期フォーカスを安全側に置く。',\n },\n ],\n checklist: [\n 'ネイティブ <dialog> + showModal() を使っている',\n 'role=\"alertdialog\" と aria-modal=\"true\" を付けている',\n 'aria-labelledby で質問文、aria-describedby で結果の説明を関連付けている',\n '初期フォーカスを安全側(キャンセル)に置いている',\n 'Tab がダイアログ内を循環し、背面に漏れない',\n 'Esc で閉じられる',\n '閉じると開いたトリガーへフォーカスが戻る',\n 'フォーカスリングを消していない',\n ],\n antipatterns: [\n {\n title: '読み上げられない',\n why: 'role=\"alertdialog\" も aria-describedby も無く、何の確認か伝わらない。',\n },\n {\n title: 'フォーカスが移らない',\n why: '開いてもボックスに入らず、背面に Tab で抜けてしまう。',\n },\n {\n title: 'Esc で閉じない',\n why: '安全な離脱手段が無い。',\n },\n {\n title: '選択肢が <span>',\n why: 'フォーカスできず、キーボードで「はい/いいえ」を選べない。',\n },\n {\n title: '危険な操作の防御が無い',\n why: '初期フォーカスや安全側の配慮がない。',\n },\n ],\n notes: [\n 'role=\"alertdialog\" を付けると <dialog> 既定の role=\"dialog\" を上書きするため、aria-modal=\"true\" も合わせて明示しておくのが安全。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Breadcrumb パターン。\nexport const breadcrumb: PatternViewpoint = {\n slug: 'breadcrumb',\n keyboard: [\n {\n keys: 'Tab / Shift+Tab',\n action: '前後のリンクへ移動(普通のリンクと同じ)',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: 'フォーカス中のリンク先へ移動',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: '外側のコンテナ',\n attr: '<nav aria-label=\"パンくずリスト\">',\n meaning: 'ナビゲーションのランドマークにし、名前で区別する。',\n },\n {\n target: 'リンクの並び',\n attr: '<ol> > <li>',\n meaning: '順序のあるリストにして、階層の数と順番を伝える。',\n },\n {\n target: '現在地の項目',\n attr: 'aria-current=\"page\"',\n meaning: '「現在のページ」であることを示す。リンクにはしない。',\n },\n {\n target: '区切り文字',\n attr: '(CSS の ::before)',\n meaning: '「/」「>」は装飾。テキストにせず擬似要素で描き、読み上げ対象外にする。',\n },\n ],\n checklist: [\n '外側を <nav aria-label=\"…\"> で囲んでいる',\n '中身は <ol> > <li> の順序付きリスト',\n '各階層は <a href>(キーボードで移動できる)',\n '現在地は aria-current=\"page\" を付け、リンクにしていない',\n '区切り文字は CSS の擬似要素で描き、テキストにしていない',\n 'フォーカスリングを消していない',\n ],\n antipatterns: [\n {\n title: 'ランドマークが無い',\n why: '<nav> でないので、パンくずへ一発で移動できない。',\n },\n {\n title: 'リスト構造が無い',\n why: '<ol>/<li> でないので「何項目あるか」が伝わらない。',\n },\n {\n title: '現在地が伝わらない',\n why: 'aria-current=\"page\" が無く、いまどこにいるか分からない。',\n },\n {\n title: '区切りが読み上げられる',\n why: 'テキストの「>」が一つずつ読まれ、耳障りになる。',\n },\n ],\n notes: [\n 'パンくずはただのリンクの並びです。<a href> を使えばキーボード操作は自動で得られます。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Menu and Menubar パターン。\nexport const menuMenubar: PatternViewpoint = {\n slug: 'menu-menubar',\n keyboard: [\n {\n keys: 'Tab',\n action: 'メニューバーに入る/出る(バー全体で1タブストップ)',\n requirement: 'required',\n },\n {\n keys: '← / →(バー上)',\n action: '前 / 次のメニューへ移動',\n requirement: 'required',\n },\n {\n keys: '↓ / Enter / Space(バー上)',\n action: 'サブメニューを開き、最初の項目へ',\n requirement: 'required',\n },\n {\n keys: '↑ / ↓(サブメニュー内)',\n action: '前 / 次の項目へ移動',\n requirement: 'required',\n },\n {\n keys: '← / →(サブメニュー内)',\n action: '現在のメニューを閉じ、隣のメニューを開く',\n requirement: 'recommended',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の項目へ移動',\n requirement: 'optional',\n },\n {\n keys: 'Enter / Space(項目上)',\n action: 'コマンドを実行して閉じる',\n requirement: 'required',\n },\n {\n keys: 'Esc',\n action: 'サブメニューを閉じ、親のメニュー項目へ戻る',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'バーの箱',\n attr: 'role=\"menubar\" + aria-label',\n meaning: '水平のメニューバーであることと名前を伝える。',\n },\n {\n target: 'バーの各項目',\n attr: 'role=\"menuitem\" + aria-haspopup=\"menu\"',\n meaning: 'サブメニューを開くメニュー項目であることを伝える。',\n },\n {\n target: 'バーの各項目',\n attr: 'aria-expanded + tabindex=\"0 | -1\"',\n meaning: '開閉状態と roving tabindex(1つだけ 0)。',\n },\n {\n target: 'サブメニュー',\n attr: 'role=\"menu\" + aria-label',\n meaning: 'サブメニューであることと名前を伝える。',\n },\n {\n target: 'サブメニューの項目',\n attr: 'role=\"menuitem\" + tabindex=\"-1\"',\n meaning: 'コマンド項目。フォーカスは JS で管理(roving)。',\n },\n {\n target: '閉じたサブメニュー',\n attr: 'hidden',\n meaning: '閉じている間は読み上げ/操作の対象外にする。',\n },\n ],\n checklist: [\n '用途がアプリのコマンドであることを確認した(サイトナビには使わない)',\n 'バーは role=\"menubar\" + aria-label、項目は role=\"menuitem\"',\n 'サブメニューを持つ項目に aria-haspopup=\"menu\" + aria-expanded',\n 'バーは roving tabindex で1タブストップ、← → で移動',\n 'サブメニューは role=\"menu\"、項目は tabindex=\"-1\"',\n '↓/Enter で開き先頭へ、↑↓ で移動、Home/End で端へ',\n 'Esc で閉じて親項目へ戻す、← → で隣のメニューへ移れる',\n 'hover 依存にせず、フォーカスが見える',\n ],\n antipatterns: [\n {\n title: 'サイトナビに role=\"menubar\" を使う',\n why: 'ページ移動のリンク集に menubar/menu を付けると、支援技術の案内(矢印で操作するコマンド)と実体(リンク)が食い違い利用者が混乱する。',\n },\n {\n title: 'hover 依存のサブメニュー',\n why: 'サブメニューがマウスでしか開かず、キーボード/タッチ環境で破綻する。',\n },\n {\n title: 'キーボード操作の実装なし',\n why: '←→/↑↓/Esc も roving tabindex もなく、キーボードで操作できない。',\n },\n ],\n notes: [\n 'サイト内リンクのナビゲーションに role=\"menubar\" を使うのが最もよくある誤り。ページへ移動する「リンク集」は <nav> + <ul> + <a> で作る。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Menu Button パターン。\nexport const menuButton: PatternViewpoint = {\n slug: 'menu-button',\n keyboard: [\n {\n keys: 'Enter / Space / ↓(ボタン上)',\n action: 'メニューを開き、最初の項目へフォーカス',\n requirement: 'required',\n },\n {\n keys: '↑(ボタン上)',\n action: 'メニューを開き、最後の項目へフォーカス',\n requirement: 'optional',\n },\n {\n keys: '↑ / ↓(メニュー内)',\n action: '前 / 次の項目へフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の項目へ移動',\n requirement: 'recommended',\n },\n {\n keys: 'Enter / Space(項目上)',\n action: '項目を実行し、メニューを閉じてボタンへ戻る',\n requirement: 'required',\n },\n {\n keys: 'Esc',\n action: 'メニューを閉じてボタンへフォーカスを戻す',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'トリガー',\n attr: '<button> + aria-haspopup=\"menu\"',\n meaning: '押すとメニューが開くボタンであることを伝える。',\n },\n {\n target: 'トリガー',\n attr: 'aria-expanded=\"true | false\"',\n meaning: 'メニューが開いているか。開閉に合わせ必ず更新する。',\n },\n {\n target: 'トリガー',\n attr: 'aria-controls=\"メニューのid\"',\n meaning: 'どのメニューを開くボタンかを示す。',\n },\n {\n target: 'メニューの箱',\n attr: 'role=\"menu\" + aria-labelledby',\n meaning: 'メニューであることと、トリガーを名前として持つことを伝える。',\n },\n {\n target: '各項目',\n attr: 'role=\"menuitem\" + tabindex=\"-1\"',\n meaning: 'メニュー項目であることを伝える。フォーカスは JS で管理(roving)。',\n },\n {\n target: '閉じたメニュー',\n attr: 'hidden',\n meaning: '閉じている間は読み上げ/操作の対象外にする。',\n },\n ],\n checklist: [\n 'トリガーは <button> で aria-haspopup=\"menu\" + aria-expanded + aria-controls',\n 'メニューは role=\"menu\"、項目は role=\"menuitem\" + tabindex=\"-1\"',\n 'クリック / Enter / Space / ↓ で開き、最初の項目へフォーカスする',\n 'メニュー内は ↑↓ で移動、Home/End で端へ',\n 'Enter/Space で項目を実行し、閉じてトリガーへ戻る',\n 'Esc で閉じてトリガーへフォーカスを戻す',\n 'メニューの外をクリックしたら閉じる',\n 'aria-expanded が開閉と常に一致し、フォーカスが見える',\n ],\n antipatterns: [\n {\n title: 'キーボードで開けない',\n why: 'div トリガーはフォーカス不可。↓/Enter も効かない。',\n },\n {\n title: 'hover 依存',\n why: 'マウスが使えない人・タッチ環境で破綻し、マウスを外すと閉じてしまう。',\n },\n {\n title: '役割と状態が伝わらない',\n why: 'aria-haspopup/aria-expanded/role=\"menu\" がない。',\n },\n {\n title: 'フォーカス管理がない',\n why: 'Esc で閉じられず、キーボード利用者がどこにいるか見失う。',\n },\n ],\n notes: [\n '開いたら最初の項目へ、Esc で閉じたらボタンへフォーカスを戻すことで、キーボード利用者が「今どこにいるか」を見失わない。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Link パターン。\nexport const link: PatternViewpoint = {\n slug: 'link',\n keyboard: [\n {\n keys: 'Tab',\n action: '次 / 前のリンクへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: 'リンク先へ移動する',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'リンク(推奨)',\n attr: '<a href=\"...\">',\n meaning: '「リンク」ロール・フォーカス・Enter 活性化がすべて自動。ARIA は基本不要。',\n },\n {\n target: '新規タブで開く',\n attr: 'target=\"_blank\" + rel=\"noopener noreferrer\"',\n meaning: '別タブで開く。rel でセキュリティ上の問題を防ぐ。リンク文言で「新しいタブ」と明示する。',\n },\n {\n target: 'span 等で代用する場合のみ',\n attr: 'role=\"link\" + tabindex=\"0\" + キー処理',\n meaning: '本来不要。<a> なら何も足さなくてよいので使わないのが正解。',\n },\n {\n target: 'アイコンのみのリンク',\n attr: 'aria-label=\"...\"',\n meaning: '文字が無いリンクに、行き先の分かる名前を付ける。',\n },\n ],\n checklist: [\n '移動の部品は <a href=\"...\"> を使っている',\n 'リンク文言だけで行き先が分かる(「こちら」を避ける)',\n '新しいタブで開くときは文言で明示し rel=\"noopener noreferrer\" を付ける',\n 'アイコンのみのリンクには aria-label を付けている',\n 'Tab でフォーカスでき、フォーカスが見える',\n '「操作の実行」にはリンクではなく <button> を使っている',\n ],\n antipatterns: [\n {\n title: 'キーボードでフォーカスできない',\n why: 'span は Tab の対象外で、リンクとして到達できない。',\n },\n {\n title: 'リンクと認識されない',\n why: 'スクリーンリーダーのリンク一覧に出てこない。',\n },\n {\n title: '右クリック / 新しいタブ / ブックマークができない',\n why: 'href が無いためブラウザ標準の便利機能が全滅する。',\n },\n {\n title: '操作の実行にリンクを使う',\n why: '移動=<a href>、操作=<button> と役割で選ばないと利用者が混乱する。',\n },\n ],\n notes: [\n 'リンクは Enter でのみ活性化し、Space では移動しません(これが正しい挙動です)。<a href> を使えば、この動作はコードを書かずに自動的に得られます。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Landmarks パターン。\nexport const landmarks: PatternViewpoint = {\n slug: 'landmarks',\n keyboard: [\n {\n keys: 'Tab(ページ先頭で)',\n action: '最初にスキップリンクが現れ、Enter で本文へ飛べる',\n requirement: 'recommended',\n },\n {\n keys: 'SR のランドマーク移動',\n action: '領域(banner/nav/main/…)単位でジャンプ(支援技術側の操作)',\n requirement: 'required',\n },\n {\n keys: 'SR の見出しジャンプ',\n action: 'h1〜h6 を辿ってページ構造を把握(支援技術側の操作)',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: '<header>(最上位)',\n attr: 'banner',\n meaning: 'サイト共通の上部。ページに1つ。',\n },\n {\n target: '<nav>',\n attr: 'navigation',\n meaning: '複数あるなら aria-label / aria-labelledby で区別する。',\n },\n {\n target: '<main>',\n attr: 'main',\n meaning: '本文。1ページに1つだけ。<h1> も1つ。',\n },\n {\n target: '<aside>',\n attr: 'complementary',\n meaning: '本文の補足(関連情報・広告など)。',\n },\n {\n target: '<footer>(最上位)',\n attr: 'contentinfo',\n meaning: '著作権・運営者情報など。ページに1つ。',\n },\n ],\n checklist: [\n '<header> / <nav> / <main> / <footer> で領域を区切っている',\n '<main> はページに1つだけ',\n '<h1> はページに1つだけ、見出しレベルが飛んでいない',\n '<nav> が複数あるとき aria-label で区別している',\n '本文の補足は <aside> にしている',\n '先頭にスキップリンクがあり、フォーカス時に見える',\n 'ページ内の主要コンテンツがどれかのランドマークに含まれている',\n ],\n antipatterns: [\n {\n title: 'ランドマークが無い',\n why: 'main/nav/banner などへ領域移動できない。',\n },\n {\n title: '見出しが無い',\n why: '<h1> 等が無く、見出しジャンプで構造を把握できない。',\n },\n {\n title: 'スキップリンクが無い',\n why: '本文まで毎回 Tab で辿る必要がある。',\n },\n {\n title: '意味が見た目頼み',\n why: 'CSS が外れると、ただの文字列の羅列になる。',\n },\n ],\n notes: [\n 'ランドマーク自体に特別なキー操作を実装する必要はありません。正しい要素を使うだけで、支援技術側の移動機能が自動的に効きます。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Button パターン。\nexport const button: PatternViewpoint = {\n slug: 'button',\n keyboard: [\n {\n keys: 'Tab',\n action: '次 / 前のボタンへフォーカス移動(無効なボタンは飛ばされる)',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: 'フォーカス中のボタンを押す',\n requirement: 'required',\n },\n {\n keys: 'Space',\n action: 'フォーカス中のボタンを押す',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'ボタン(推奨)',\n attr: '<button type=\"button\">',\n meaning: 'ロール・フォーカス・キー操作がすべて自動。ARIA は基本不要。',\n },\n {\n target: 'フォーム送信',\n attr: 'type=\"submit\" / type=\"button\"',\n meaning: '意図しない送信を避けるため、送信でないボタンには type=\"button\" を付ける。',\n },\n {\n target: '無効化',\n attr: 'disabled',\n meaning: '操作不可にし、フォーカスからも外す。支援技術にも伝わる。',\n },\n {\n target: 'div で代用する場合のみ',\n attr: 'role=\"button\" + tabindex=\"0\"',\n meaning: '「ボタン」と認識させ、フォーカス可能にする。さらにキー処理の自作が必須。',\n },\n ],\n checklist: [\n '操作(実行)の部品は <button> を使っている',\n '送信でないボタンには type=\"button\" を付けている',\n 'マウス・Enter・Space のすべてで動く',\n '無効にしたいときは disabled を使っている',\n 'フォーカスが見える(フォーカスリングを消していない)',\n '(div 代用時のみ)role=\"button\"・tabindex=\"0\"・キー処理をすべて足している',\n ],\n antipatterns: [\n {\n title: 'キーボードでフォーカスできない',\n why: 'div は Tab の対象外。そもそも到達できない。',\n },\n {\n title: 'Space / Enter で動かない',\n why: 'div にはキー処理がなく、自分で書かなければ反応しない。',\n },\n {\n title: '役割が伝わらない',\n why: 'スクリーンリーダーに「ボタン」と認識されず、押せることが分からない。',\n },\n {\n title: '無効化できない',\n why: 'div には disabled の概念がなく、押せない状態を支援技術に伝えられない。',\n },\n ],\n notes: [\n '<button> なら、キーボード操作(Tab / Enter / Space)と支援技術への通知がコードを書かずに動きます。',\n 'その場で何かを実行するなら <button>、別の場所へ移動するなら <a href> と役割で選びましょう。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Checkbox パターン。\nexport const checkbox: PatternViewpoint = {\n slug: 'checkbox',\n keyboard: [\n {\n keys: 'Tab',\n action: '次のチェックボックスへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Space',\n action: 'フォーカス中のチェックボックスをオン/オフ',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: '入力欄',\n attr: '<input type=\"checkbox\">',\n meaning: 'ネイティブの checkbox ロール・状態・キーボード操作がすべて自動で付く。',\n },\n {\n target: 'ラベル',\n attr: '<label>(input を内包 or for で関連付け)',\n meaning: 'チェックボックスの「名前」になる。ラベルのクリックでもトグルできる。',\n },\n {\n target: '親(すべて選択)',\n attr: 'indeterminate = true(JS プロパティ)',\n meaning: '一部だけ選択の中間状態。aria-checked=\"mixed\" として自動で伝わる。',\n },\n {\n target: 'グループ',\n attr: '<fieldset> + <legend>',\n meaning: '関連するチェックボックスをまとめ、グループ名を与える(任意・推奨)。',\n },\n ],\n checklist: [\n 'チェックボックスは <input type=\"checkbox\"> である',\n '<label> と関連付いている(内包 or for/id)',\n 'Space でトグルでき、フォーカスが見える',\n '「すべて選択」の一部選択は indeterminate = true で表す',\n '親 ↔ 子の状態が change で常に同期している',\n '関連グループは <fieldset> + <legend> でまとめる(任意・推奨)',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスを受け取れず、Space でのトグルも効かない。',\n },\n {\n title: '役割が伝わらない',\n why: '「チェックボックス」だと認識されず、オン/オフの概念も存在しない。',\n },\n {\n title: '状態が伝わらない',\n why: 'オン/オフ(や中間状態)が読み上げられず、スクリーンリーダーに判別できない。',\n },\n {\n title: 'ラベル未関連',\n why: '文字をクリックしても切り替わらず、何のチェックかという名前も結びつかない。',\n },\n ],\n notes: [\n 'Space での切り替えは <input type=\"checkbox\"> を使うだけで自動的に得られます。自分でキー処理を書く必要はありません。',\n 'indeterminate は HTML 属性ではなく JavaScript のプロパティです(el.indeterminate = true)。送信値の扱いに注意します。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Radio Group パターン。\nexport const radioGroup: PatternViewpoint = {\n slug: 'radio-group',\n keyboard: [\n {\n keys: 'Tab',\n action: 'グループに入る / グループから出る(選択中の項目にフォーカス)',\n requirement: 'required',\n },\n {\n keys: '↓ / →',\n action: '次の選択肢へ移動して選択する',\n requirement: 'required',\n },\n {\n keys: '↑ / ←',\n action: '前の選択肢へ移動して選択する',\n requirement: 'required',\n },\n {\n keys: 'Space',\n action: 'フォーカス中の選択肢を選択する',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: '各選択肢',\n attr: '<input type=\"radio\"> + 同じ name',\n meaning: 'radio ロール・「1つだけ選択」・矢印キー操作が自動で付く。',\n },\n {\n target: 'ラベル',\n attr: '<label>',\n meaning: '各選択肢の名前。クリックでも選択できる。',\n },\n {\n target: 'グループ',\n attr: '<fieldset> + <legend>',\n meaning: '選択肢をまとめ、グループ名(質問文)を与える。',\n },\n ],\n checklist: [\n '各選択肢は <input type=\"radio\"> である',\n 'グループ内のラジオは同じ name を共有している',\n '<label> と関連付いている(内包 or for/id)',\n '<fieldset> + <legend> でグループ名を与えている',\n 'Tab でグループに入り、矢印キーで移動&選択できる',\n 'フォーカスが見える(フォーカスリングを消していない)',\n '自作する場合のみ role=\"radiogroup\" / role=\"radio\" / aria-checked / ロービングタブインデックスを実装',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスできず、矢印キーも効かない。',\n },\n {\n title: 'グループだと伝わらない',\n why: 'role=\"radiogroup\" も <fieldset> もなく、選択肢の集まりだと認識されない。',\n },\n {\n title: '「1つだけ選択」が伝わらない',\n why: 'role=\"radio\" / aria-checked がなく、状態も位置も読み上げられない。',\n },\n {\n title: 'チェックボックスをラジオ代わりに使う',\n why: '複数選べてしまい、「1つだけ」という意味が逆になる。',\n },\n ],\n notes: [\n 'ラジオグループでは Tab はグループ全体で1回だけ止まります(選択肢ごとには止まらない)。グループ内の移動は矢印キーの役割です。',\n '<input type=\"radio\"> を同じ name でまとめるだけで、矢印キー移動・1つだけ選択・Tab ナビゲーションがすべて自動で得られます。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Switch パターン。\n// 変数名: switch は予約語のため switchPattern とする。\nexport const switchPattern: PatternViewpoint = {\n slug: 'switch',\n keyboard: [\n {\n keys: 'Tab',\n action: '次 / 前のスイッチへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Space',\n action: 'オン / オフを切り替える',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: 'オン / オフを切り替える',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'スイッチ本体',\n attr: '<button> + role=\"switch\"',\n meaning: '「スイッチ」として認識させる。ベースが button なのでフォーカス・キー操作が自動。',\n },\n {\n target: 'スイッチ本体',\n attr: 'aria-checked=\"true | false\"',\n meaning: 'オン / オフの状態。切り替えるたびに必ず更新する。',\n },\n {\n target: 'スイッチ本体',\n attr: 'aria-labelledby または aria-label',\n meaning: '「何の」スイッチかという名前を与える。',\n },\n {\n target: '飾りの丸(thumb)',\n attr: 'aria-hidden=\"true\"',\n meaning: '見た目だけの要素を読み上げから除外する。',\n },\n ],\n checklist: [\n 'スイッチ本体は <button> ベース(または <input type=\"checkbox\">)',\n 'role=\"switch\" が付いている(button ベースの場合)',\n 'aria-checked がオン/オフと常に一致している',\n 'aria-labelledby / aria-label で名前を与えている',\n '飾りのつまみは aria-hidden=\"true\"',\n 'Enter / Space で切り替えられ、フォーカスが見える',\n '状態を色だけでなく位置・ラベルでも区別できる',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスを受け取れず、切り替えられない。',\n },\n {\n title: '役割が伝わらない',\n why: 'role=\"switch\" が無く「スイッチ」と認識されない。',\n },\n {\n title: '状態が伝わらない',\n why: 'aria-checked が無く、オン/オフが支援技術に判別できない。',\n },\n {\n title: '名前が無い',\n why: '何のスイッチかが aria-labelledby / aria-label で関連付けられていない。',\n },\n ],\n notes: [\n '<button> をベースにすると Enter と Space の両方が自動で効きます。click ハンドラで aria-checked を反転するだけです。',\n '状態を色だけで示すのも避けましょう。つまみの位置や ON/OFF のラベルなど、色以外の手がかりも併用します。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Combobox パターン。\nexport const combobox: PatternViewpoint = {\n slug: 'combobox',\n keyboard: [\n {\n keys: '文字入力',\n action: '候補を絞り込み、ポップアップを開く',\n requirement: 'required',\n },\n {\n keys: '↓',\n action: 'ポップアップを開く / 次の候補へハイライト移動',\n requirement: 'required',\n },\n {\n keys: '↑',\n action: '前の候補へハイライト移動',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: 'ハイライト中の候補を確定して閉じる',\n requirement: 'required',\n },\n {\n keys: 'Esc',\n action: 'ポップアップを閉じる(開いていなければ入力をクリア)',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '入力欄内のカーソル移動(テキスト操作はそのまま)',\n requirement: 'optional',\n },\n ],\n aria: [\n {\n target: '入力欄',\n attr: 'role=\"combobox\"',\n meaning: 'テキスト入力+ポップアップを持つ複合ウィジェットだと示す。',\n },\n {\n target: '入力欄',\n attr: 'aria-expanded=\"true | false\"',\n meaning: 'ポップアップが開いているか。開閉に合わせて必ず更新する。',\n },\n {\n target: '入力欄',\n attr: 'aria-controls=\"リストのid\"',\n meaning: 'どのポップアップ(listbox)を制御するかを示す。',\n },\n {\n target: '入力欄',\n attr: 'aria-activedescendant=\"候補のid\"',\n meaning: 'いまハイライト中の option を指す。移動のたびに更新、閉じたら外す。',\n },\n {\n target: '入力欄',\n attr: 'aria-autocomplete=\"list\"',\n meaning: '入力に応じてリストで補完されることを示す。',\n },\n {\n target: 'ポップアップ',\n attr: 'role=\"listbox\" + 名前',\n meaning: '候補の集まり。aria-labelledby 等で名前を付ける。',\n },\n {\n target: '各候補',\n attr: 'role=\"option\" + 一意の id + aria-selected',\n meaning: '1つの候補。ハイライト中は aria-selected=\"true\"。',\n },\n {\n target: 'ライブ領域',\n attr: 'aria-live=\"polite\"',\n meaning: '「○件の候補」など件数の変化を読み上げる(任意・推奨)。',\n },\n ],\n checklist: [\n '入力欄に role=\"combobox\" + aria-expanded + aria-controls がある',\n 'ポップアップは role=\"listbox\" > role=\"option\"(option に一意の id)',\n 'ハイライトは aria-activedescendant + aria-selected で表し、移動のたびに更新',\n 'aria-expanded が開閉と常に一致している',\n '↓ で候補へ、↑↓ で移動、Enter 確定、Esc で閉じる',\n '入力で候補が絞り込まれ、件数を aria-live で読み上げる(推奨)',\n 'フォーカスは入力欄に保持し、フォーカスリングを消していない',\n ],\n antipatterns: [\n {\n title: 'キーボードで候補を選べない',\n why: '候補が div で、矢印キーやフォーカスが効かない。',\n },\n {\n title: 'ロール・状態が無い',\n why: 'role=\"combobox\" / aria-expanded / aria-controls がなく、開閉も関係も伝わらない。',\n },\n {\n title: 'ハイライトが伝わらない',\n why: 'aria-activedescendant / aria-selected がなく、どれを指しているか分からない。',\n },\n {\n title: '件数が伝わらない',\n why: 'aria-live がなく、「○件の候補」が読み上げられない。',\n },\n ],\n notes: [\n 'フォーカスは入力欄に置いたまま動かしません。aria-activedescendant で「いまどの候補をハイライトしているか」だけを伝えます。こうすると、入力を続けながら候補を選べます。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Listbox パターン。\nexport const listbox: PatternViewpoint = {\n slug: 'listbox',\n keyboard: [\n {\n keys: 'Tab',\n action: 'リストボックスにフォーカスを当てる / 外す',\n requirement: 'required',\n },\n {\n keys: '↓ / ↑',\n action: '次 / 前の選択肢へ移動(移動に合わせて選択を更新)',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の選択肢へ移動',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: 'コンテナ',\n attr: 'role=\"listbox\"',\n meaning: '「選べる項目の集まり」であることを示す。',\n },\n {\n target: 'コンテナ',\n attr: 'aria-labelledby(または aria-label)',\n meaning: 'リストボックスの名前を与える。',\n },\n {\n target: 'コンテナ',\n attr: 'tabindex=\"0\" + aria-activedescendant',\n meaning: 'リストにフォーカスを置き、現在位置の option id を指す(activedescendant 方式)。',\n },\n {\n target: '各項目',\n attr: 'role=\"option\" + 一意の id',\n meaning: '1つの選択肢。id は aria-activedescendant から参照される。',\n },\n {\n target: '各項目',\n attr: 'aria-selected=\"true | false\"',\n meaning: '選択状態。選択の変化に合わせて必ず更新する。',\n },\n ],\n checklist: [\n 'コンテナに role=\"listbox\" と名前(aria-labelledby 等)がある',\n '各項目は role=\"option\" + 一意の id を持つ',\n 'aria-selected が選択状態と常に一致している',\n 'フォーカス管理がある(aria-activedescendant またはロービングタブインデックス)',\n '↑↓ で移動でき、Home / End も使える(推奨)',\n 'クリックでも選択でき、フォーカスが見える',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスを受け取れず、矢印キーも効かない。',\n },\n {\n title: '役割が伝わらない',\n why: 'role=\"listbox\"/role=\"option\" がなく「選べる一覧」だと認識されない。',\n },\n {\n title: '選択状態が伝わらない',\n why: 'aria-selected がなく、どれが選ばれているか分からない。',\n },\n {\n title: '名前も位置もない',\n why: 'グループ名や「何個中何個目」が読み上げられない。',\n },\n ],\n notes: [\n 'フォーカスはリスト(ul)に置いたまま、「いまどの option を指しているか」だけを aria-activedescendant 属性で伝える方式(activedescendant 方式)と、各 option に tabindex を配るロービングタブインデックス方式の2通りで実装できる。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Slider パターン。\nexport const slider: PatternViewpoint = {\n slug: 'slider',\n keyboard: [\n {\n keys: '→ / ↑',\n action: '値を1ステップ増やす',\n requirement: 'required',\n },\n {\n keys: '← / ↓',\n action: '値を1ステップ減らす',\n requirement: 'required',\n },\n {\n keys: 'Home',\n action: '最小値にする',\n requirement: 'required',\n },\n {\n keys: 'End',\n action: '最大値にする',\n requirement: 'required',\n },\n {\n keys: 'Page Up / Page Down',\n action: '値を大きいステップで増減する',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: 'ネイティブ range',\n attr: '<label for> で関連付け',\n meaning: 'つまみに名前(ラベル)を与える。これだけで role・値・範囲は自動。',\n },\n {\n target: '自作のつまみ',\n attr: 'role=\"slider\"',\n meaning: '「スライダーである」と支援技術へ伝える。',\n },\n {\n target: '自作のつまみ',\n attr: 'tabindex=\"0\"',\n meaning: 'div をキーボードでフォーカス可能にする。',\n },\n {\n target: '自作のつまみ',\n attr: 'aria-valuemin / aria-valuemax',\n meaning: '動かせる範囲(最小・最大)。',\n },\n {\n target: '自作のつまみ',\n attr: 'aria-valuenow',\n meaning: '現在値。動かすたびに必ず更新する。',\n },\n {\n target: '自作のつまみ',\n attr: 'aria-valuetext',\n meaning: '数値だけでは意味が伝わらないとき(「40%」「中」など)に人にわかる表現を補う(任意)。',\n },\n {\n target: '自作のつまみ',\n attr: 'aria-label / aria-labelledby',\n meaning: 'つまみの名前。可視ラベルがあれば aria-labelledby で結ぶ。',\n },\n ],\n checklist: [\n 'まず <input type=\"range\"> を検討した(最優先)',\n 'つまみに名前がある(<label for> または aria-label(ledby))',\n 'キーボードでフォーカスでき、← → で値を変えられる',\n 'Home / End で最小・最大へ動く',\n '自作時は role=\"slider\" + aria-valuemin/max/now がある',\n '値を動かすたびに aria-valuenow を更新している',\n '数値だけで意味が伝わらないときは aria-valuetext を添える',\n 'フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスを受け取れず、矢印キーで動かせない。',\n },\n {\n title: '役割が伝わらない',\n why: 'role=\"slider\" が無く、スライダーだと認識されない。',\n },\n {\n title: '値・範囲が伝わらない',\n why: 'aria-valuenow / valuemin / valuemax が無く、いま何%かも分からない。',\n },\n {\n title: '名前が無い',\n why: '何を調整するスライダーなのか(明るさ?)が伝わらない。',\n },\n ],\n notes: [\n '<input type=\"range\"> を使えば、→ ← Home End Page Up/Down の操作と読み上げはすべてブラウザが自動で提供する。自作(role=\"slider\")する場合は keydown で自前実装が必要。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Slider(Multithumb)パターン。\nexport const sliderMultithumb: PatternViewpoint = {\n slug: 'slider-multithumb',\n keyboard: [\n {\n keys: 'Tab',\n action: 'つまみ間(最小価格 ↔ 最大価格)を移動',\n requirement: 'required',\n },\n {\n keys: '→ / ↑',\n action: 'フォーカス中のつまみを1ステップ増やす',\n requirement: 'required',\n },\n {\n keys: '← / ↓',\n action: 'フォーカス中のつまみを1ステップ減らす',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: 'そのつまみが動ける端まで移動',\n requirement: 'required',\n },\n {\n keys: 'Page Up / Page Down',\n action: '大きいステップで増減',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: '各つまみ',\n attr: 'role=\"slider\"',\n meaning: 'つまみ1つ1つを「スライダー」にする(2つあるなら2つとも)。',\n },\n {\n target: '各つまみ',\n attr: 'tabindex=\"0\"',\n meaning: 'つまみを個別にキーボードフォーカス可能にする。',\n },\n {\n target: '各つまみ',\n attr: 'aria-label(個別に)',\n meaning: '「最小価格」「最大価格」のように区別できる名前を付ける。',\n },\n {\n target: '各つまみ',\n attr: 'aria-valuenow',\n meaning: 'そのつまみの現在値。動かすたびに更新。',\n },\n {\n target: '下限つまみ',\n attr: 'aria-valuemax = 上限の現在値',\n meaning: '下限が上限を越えないよう、可動範囲を動的に締める。',\n },\n {\n target: '上限つまみ',\n attr: 'aria-valuemin = 下限の現在値',\n meaning: '上限が下限を下回らないよう、可動範囲を動的に締める。',\n },\n {\n target: '各つまみ',\n attr: 'aria-valuetext',\n meaning: '「2000円」など単位付きで読み上げさせる(任意・推奨)。',\n },\n ],\n checklist: [\n 'つまみ2つにそれぞれ role=\"slider\" を付けた',\n 'つまみごとに区別できる aria-label(「最小価格」「最大価格」)がある',\n '各つまみが tabindex=\"0\" で個別にフォーカスできる',\n '矢印・Home・End・PageUp/Down で動かせる',\n '下限が上限を越えない(可動範囲を相手の値で動的に締めている)',\n '動かすたびに aria-valuenow を更新している',\n 'フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'どちらのつまみか分からない',\n why: 'aria-label が無く「最小」「最大」を区別できない。',\n },\n {\n title: 'キーボードで操作できない',\n why: 'tabindex が無く、矢印キーも効かない。',\n },\n {\n title: '値・範囲が伝わらない',\n why: 'role=\"slider\" や aria-valuenow が無い。',\n },\n {\n title: '制約が無い',\n why: '下限が上限を追い越しても止まらず、値が壊れる。',\n },\n ],\n notes: [\n 'ネイティブの <input type=\"range\"> は1つまみ専用なので、2つまみは role=\"slider\" を持つ要素を2つ並べて自作する必要がある。',\n '各つまみの aria-valuemax(下限側)と aria-valuemin(上限側)を相手の現在値で動的に更新することで、互いを追い越さない制約を実装する。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Spinbutton パターン。\nexport const spinbutton: PatternViewpoint = {\n slug: 'spinbutton',\n keyboard: [\n {\n keys: '↑',\n action: '値を1ステップ増やす',\n requirement: 'required',\n },\n {\n keys: '↓',\n action: '値を1ステップ減らす',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最小値 / 最大値にする',\n requirement: 'recommended',\n },\n {\n keys: '数字キー',\n action: '値を直接入力する',\n requirement: 'optional',\n },\n ],\n aria: [\n {\n target: 'ネイティブ number',\n attr: '<label for> で関連付け',\n meaning: '入力欄に名前を与える。role・値・範囲・増減は自動。',\n },\n {\n target: '自作の本体',\n attr: 'role=\"spinbutton\"',\n meaning: '「スピンボタンである」と支援技術へ伝える。',\n },\n {\n target: '自作の本体',\n attr: 'tabindex=\"0\"',\n meaning: 'キーボードでフォーカス可能にし、↑↓ を受け取れるようにする。',\n },\n {\n target: '自作の本体',\n attr: 'aria-valuemin / aria-valuemax',\n meaning: '選べる範囲(最小・最大)。',\n },\n {\n target: '自作の本体',\n attr: 'aria-valuenow',\n meaning: '現在値。増減のたびに必ず更新する。',\n },\n {\n target: '自作の本体',\n attr: 'aria-label / aria-labelledby',\n meaning: '何の数を選ぶスピンボタンかの名前。',\n },\n {\n target: '増減ボタン',\n attr: '<button> + aria-label=\"増やす/減らす\"',\n meaning: '+ − は本物の button にし、記号だけの場合は名前を補う。',\n },\n ],\n checklist: [\n 'まず <input type=\"number\"> を検討した(最優先)',\n '入力欄/本体に名前がある(<label for> または aria-label(ledby))',\n '+ − は本物の <button> で、キーボードで押せる',\n '↑ ↓ で値を増減できる',\n '自作時は role=\"spinbutton\" + aria-valuemin/max/now がある',\n '増減のたびに aria-valuenow を更新している',\n '範囲外に増減しない(最小・最大で止まる)',\n 'フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'キーボードで増減できない',\n why: '+ − が div でフォーカスも押下もできない。',\n },\n {\n title: '役割が伝わらない',\n why: 'role=\"spinbutton\" が無く、スピンボタンと認識されない。',\n },\n {\n title: '値・範囲が伝わらない',\n why: 'aria-valuenow / valuemin / valuemax が無い。',\n },\n {\n title: '名前が無い',\n why: 'label 未関連付けで、何の数か分からない。',\n },\n ],\n notes: [\n '<input type=\"number\"> を使えば、↑↓ での増減・直接入力・読み上げはすべてブラウザが自動で提供する。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Meter パターン。\nexport const meter: PatternViewpoint = {\n slug: 'meter',\n // 表示専用(非インタラクティブ)なのでキーボード操作なし。\n keyboard: [],\n aria: [\n {\n target: 'ネイティブ meter',\n attr: '<meter min max value> + <label for>',\n meaning: 'role・値・範囲は自動。label で名前を付ける。',\n },\n {\n target: '自作の本体',\n attr: 'role=\"meter\"',\n meaning: '「計測値の表示である」と支援技術へ伝える。',\n },\n {\n target: '自作の本体',\n attr: 'aria-valuemin / aria-valuemax',\n meaning: '範囲(最小・最大)。既知の範囲であることが meter の前提。',\n },\n {\n target: '自作の本体',\n attr: 'aria-valuenow',\n meaning: '現在値。値が変わったら更新する(ユーザー操作ではなくプログラムから)。',\n },\n {\n target: '自作の本体',\n attr: 'aria-valuetext',\n meaning: '「72%」「残り 28%」など人にわかる表現を補う(任意・推奨)。',\n },\n {\n target: '自作の本体',\n attr: 'aria-label / aria-labelledby',\n meaning: '何のメーターか(「ディスク使用率」)の名前。',\n },\n {\n target: '自作の本体',\n attr: 'tabindex なし',\n meaning: '表示専用なのでフォーカス不要。role=\"slider\" とも混同しない。',\n },\n ],\n checklist: [\n '「進捗」ではなく「既知の範囲の現在量」だと確認した(progressbar と取り違えていない)',\n 'まずネイティブ <meter> を検討した(最優先)',\n 'メーターに名前がある(<label for> または aria-label(ledby))',\n '自作時は role=\"meter\" + aria-valuemin/max/now がある',\n '値が変わったら aria-valuenow(と aria-valuetext)を更新している',\n '表示専用なので tabindex を付けていない(キーボード操作は無い)',\n '状態を色だけに頼らず、数値やテキストでも伝えている',\n ],\n antipatterns: [\n {\n title: '役割が無い',\n why: 'role=\"meter\" も <meter> も無く、計測値だと認識されない。',\n },\n {\n title: '値・範囲が伝わらない',\n why: 'aria-valuenow / valuemin / valuemax が無く「72%」が読まれない。',\n },\n {\n title: '名前が結びついていない',\n why: 'バーと「ディスク使用率」が関連付けられていない。',\n },\n {\n title: '色だけに依存',\n why: '数値やテキストの併記が無く、色が見えない人に伝わらない。',\n },\n ],\n notes: [\n 'メーターは表示専用・非インタラクティブ。フォーカスも tabindex も不要で、値が変わったら aria-valuenow と aria-valuetext を更新するだけでよい。',\n 'progressbar との使い分け:meter は「既知の範囲の現在量(例:ディスク 72%)」、progressbar は「完了に向かって進む進捗(例:ダウンロード中)」。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Tabs パターン。\nexport const tabs: PatternViewpoint = {\n slug: 'tabs',\n keyboard: [\n {\n keys: 'Tab',\n action: 'タブリストに入る/出る(リスト全体で1タブストップ)',\n requirement: 'required',\n },\n {\n keys: '← / →',\n action: '前 / 次のタブへ移動(自動アクティベーションでは同時に選択)',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後のタブへ移動',\n requirement: 'recommended',\n },\n {\n keys: 'Enter / Space',\n action: '手動アクティベーション時にフォーカス中のタブを選択',\n requirement: 'optional',\n },\n ],\n aria: [\n {\n target: 'タブを囲む箱',\n attr: 'role=\"tablist\" + aria-label',\n meaning: 'タブの集まりであることと、その名前を伝える。',\n },\n {\n target: '各タブ',\n attr: 'role=\"tab\"',\n meaning: 'タブであることを伝える。中身は <button> 推奨。',\n },\n {\n target: '各タブ',\n attr: 'aria-selected=\"true | false\"',\n meaning: 'いま選ばれているタブはどれか。切替時に必ず更新する。',\n },\n {\n target: '各タブ',\n attr: 'aria-controls=\"パネルのid\"',\n meaning: 'そのタブが制御するパネルを示す。',\n },\n {\n target: '各タブ',\n attr: 'tabindex=\"0 | -1\"',\n meaning: '選択タブだけ 0、他は -1(roving tabindex)。',\n },\n {\n target: '各パネル',\n attr: 'role=\"tabpanel\" + aria-labelledby=\"タブのid\"',\n meaning: '対応するタブを名前として持つパネル。',\n },\n {\n target: '各パネル',\n attr: 'tabindex=\"0\"',\n meaning: 'パネル内にフォーカス可能要素がない場合でも、パネル自体に Tab で入れるようにする。',\n },\n {\n target: '非表示パネル',\n attr: 'hidden',\n meaning: '選ばれていないパネルは隠し、読み上げ/操作の対象外にする。',\n },\n ],\n checklist: [\n 'タブを role=\"tablist\" + aria-label で囲んでいる',\n '各タブは <button role=\"tab\"> である',\n 'aria-selected が選択状態と常に一致している',\n '選択タブだけ tabindex=\"0\"、他は -1(roving tabindex でタブ全体が1タブストップ)',\n '← → でタブ移動、Home/End で端へ移動できる',\n '各タブ aria-controls、各パネル role=\"tabpanel\" + aria-labelledby + tabindex=\"0\"',\n '非表示パネルは hidden で読み上げ/操作から外れている',\n 'フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'div + onclick でタブを作る',\n why: 'div はフォーカスを受け取れず、矢印キーも効かない。',\n },\n {\n title: 'role=\"tablist\" / role=\"tab\" がない',\n why: 'スクリーンリーダーにはただのテキストに聞こえ、タブだと伝わらない。',\n },\n {\n title: 'aria-selected がない',\n why: 'いまどれが選択中か判別できない。',\n },\n {\n title: 'aria-controls / aria-labelledby がない',\n why: 'タブとパネルが関連付いておらず、支援技術が対応関係を把握できない。',\n },\n ],\n notes: [\n 'パネルの中身がすぐ表示できる軽い内容なら、矢印キーで移動と同時に選択する「自動アクティベーション」が快適。表示に通信や重い処理が伴う場合は Enter/Space で確定する「手動アクティベーション」にする。',\n 'スクリーンリーダーでタブにフォーカスすると「プロフィール, タブ, 選択済み, 3個中1個目」のように役割・選択状態・位置が読み上げられる。これが role=\"tab\" と aria-selected の効果。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Toolbar パターン。\nexport const toolbar: PatternViewpoint = {\n slug: 'toolbar',\n keyboard: [\n {\n keys: 'Tab',\n action: 'ツールバーに入る/出る(ツールバー全体で1タブストップ)',\n requirement: 'required',\n },\n {\n keys: '← / →',\n action: '前 / 次のボタンへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後のボタンへ移動',\n requirement: 'recommended',\n },\n {\n keys: 'Enter / Space',\n action: 'フォーカス中のボタンを実行/切替',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'ツールバーの箱',\n attr: 'role=\"toolbar\"',\n meaning: '操作ボタンの集まりであることを伝える。',\n },\n {\n target: 'ツールバーの箱',\n attr: 'aria-label(または aria-labelledby)',\n meaning: '「文字の書式」などツールバーの名前を付ける。',\n },\n {\n target: '各ボタン',\n attr: 'tabindex=\"0 | -1\"',\n meaning: 'フォーカス中の1つだけ 0、他は -1(roving tabindex)。',\n },\n {\n target: 'トグルボタン',\n attr: 'aria-pressed=\"true | false\"',\n meaning: 'オン/オフが切り替わるボタンの状態を伝える。',\n },\n {\n target: '区切り線',\n attr: 'role=\"separator\" + aria-orientation',\n meaning: 'ボタンのグループを視覚的・意味的に区切る(任意)。',\n },\n ],\n checklist: [\n 'ボタン群を role=\"toolbar\" + aria-label で囲んでいる',\n 'ツールバー全体が1タブストップ(Tab 1回で入る)',\n 'roving tabindex:フォーカス中の1つだけ tabindex=\"0\"、他は -1',\n '← → でボタン移動、Home/End で端へ移動できる',\n '各ボタンはネイティブの <button>(div を使わない)',\n 'トグルボタンに aria-pressed を付け、状態を更新している',\n '抜けて戻ると最後にフォーカスしていたボタンに戻る',\n 'フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: '1ボタン=1タブストップにする',\n why: '道具が増えるほど Tab 連打が必要になり、APG 非準拠。',\n },\n {\n title: '矢印キーで移動できない',\n why: 'roving tabindex も role=\"toolbar\" もなく、キーボード操作の約束事が守られていない。',\n },\n {\n title: 'div ボタンを使う',\n why: 'tabindex も role もない div はキーボードでフォーカスできない。',\n },\n {\n title: 'role=\"toolbar\" / aria-label がない',\n why: 'スクリーンリーダーにはただのボタンの羅列に聞こえ、まとまりが伝わらない。',\n },\n ],\n notes: [\n 'オン/オフが切り替わるボタン(太字など)には aria-pressed を付ける。スクリーンリーダーは「太字, 切り替えボタン, オン」のように押下状態を読み上げる。',\n 'ツールバーから Tab で出ると、次に戻ってきたときは最後にフォーカスしていたボタンに戻る(roving tabindex で tabindex=\"0\" の位置が保持されるため)。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Table パターン。\n// keyboard: [] — 静的な表に実装者が提供するキー処理は無い。\n// 表ナビゲーション(⌃⌥ + 矢印等)はスクリーンリーダー側の機能であり、\n// 正しい <table> マークアップさえあれば自動で利用可能になる。\nexport const table: PatternViewpoint = {\n slug: 'table',\n keyboard: [],\n aria: [\n {\n target: '表全体',\n attr: '<table>',\n meaning: '表であることを伝える。role=\"table\" 等は自動で付くので書かない。',\n },\n {\n target: '表の見出し',\n attr: '<caption>',\n meaning: '表に名前(タイトル)を付ける。スクリーンリーダーが「〜の表」と読み、表一覧でも識別できる。',\n },\n {\n target: '列の見出しセル',\n attr: '<th scope=\"col\">',\n meaning: 'その列に属するセルの見出しだと示す。同じ列のセルに関連付けられる。',\n },\n {\n target: '行の見出しセル',\n attr: '<th scope=\"row\">',\n meaning: 'その行に属するセルの見出しだと示す。同じ行のセルに関連付けられる。',\n },\n {\n target: '見出し / 本体',\n attr: '<thead> / <tbody>',\n meaning: '見出し行とデータ行を構造的に区別する。',\n },\n {\n target: 'データセル',\n attr: '<td>',\n meaning: '実データの値。<th> と書き分けることが関連付けの前提。',\n },\n ],\n checklist: [\n 'データの表はネイティブの <table> で組んでいる(<div> の格子ではない)',\n '<caption> で表に名前(タイトル)を付けている',\n '列の見出しセルは <th scope=\"col\"> である',\n '行の見出しセルは <th scope=\"row\"> である',\n '見出し行は <thead>、データ行は <tbody> で構造化している',\n 'レイアウト目的では <table> を使っていない(表は「データ」のときだけ)',\n '対話的にセル間を操作する必要があるなら、これではなく grid パターンを使う',\n ],\n antipatterns: [\n {\n title: '見出しとセルが関連付かない',\n why: '<th>/scope が無いので、「120」がどの店舗・どの四半期かが伝わらない。',\n },\n {\n title: '名前(タイトル)が無い',\n why: '<caption> が無く、何の表かが分からない。',\n },\n {\n title: '表ナビゲーションが効かない',\n why: '<table> ではないので、スクリーンリーダーの表移動コマンドが使えない。',\n },\n {\n title: 'ただの数字の羅列に聞こえる',\n why: '構造が無く、上から平坦に読み上げられるだけで意味を再構成できない。',\n },\n ],\n notes: [\n '正しい <table> マークアップさえあれば、スクリーンリーダーの表ナビゲーションが自動的に使えるようになる。実装者がキー処理を書く必要はない。',\n '複雑な表(見出しが複数段になる等)では、<th id> と <td headers> で明示的にひも付けできる。まずはシンプルな表を scope で正しく書くことを優先する。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Data Grid パターン。\nexport const grid: PatternViewpoint = {\n slug: 'grid',\n keyboard: [\n {\n keys: 'Tab',\n action: 'グリッド全体に出入りする(中は1タブストップ)',\n requirement: 'required',\n },\n {\n keys: '→ / ←',\n action: '右 / 左のセルへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: '↓ / ↑',\n action: '下 / 上のセルへフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: 'その行の先頭 / 末尾のセルへ',\n requirement: 'required',\n },\n {\n keys: 'Ctrl+Home / Ctrl+End',\n action: 'グリッドの先頭 / 末尾のセルへ',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: '外枠',\n attr: 'role=\"grid\"',\n meaning: '対話的なグリッドであることを宣言する。',\n },\n {\n target: '外枠',\n attr: 'aria-label / aria-labelledby',\n meaning: 'グリッドに名前を付ける(何の表かを伝える)。',\n },\n {\n target: '各行',\n attr: 'role=\"row\"',\n meaning: '行のまとまりを示す。',\n },\n {\n target: '見出しセル',\n attr: 'role=\"columnheader\"',\n meaning: '列の見出し。各列のセルと関連付けて読まれる。',\n },\n {\n target: 'データセル',\n attr: 'role=\"gridcell\"',\n meaning: '1つ1つのセル。',\n },\n {\n target: 'フォーカスするセル',\n attr: 'tabindex=\"0\"(1つだけ)/ \"-1\"(残り全部)',\n meaning: 'ローミング tabindex。グリッドを1タブストップにし、移動時に付け替える。',\n },\n ],\n checklist: [\n '外枠に role=\"grid\" と名前(aria-label / aria-labelledby)がある',\n '行は role=\"row\"、見出しは role=\"columnheader\"、セルは role=\"gridcell\"',\n '常に1つのセルだけ tabindex=\"0\"、残りは \"-1\"(ローミング tabindex)',\n '矢印キーでセル移動でき、Home/End で行の端へ移動できる',\n '(推奨)Ctrl+Home/End でグリッドの端へ移動できる',\n 'Tab はセル移動ではなく「グリッドの外へ出る」キーになっている',\n 'キーボードだけで操作でき、フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'セルに tabindex もキー処理も無く、矢印で動けない。',\n },\n {\n title: 'グリッドと認識されない',\n why: 'role=\"grid\" が無く、支援技術には「ただの表」に聞こえる。',\n },\n {\n title: '1タブストップになっていない',\n why: 'ローミング tabindex の設計が無い。',\n },\n {\n title: '現在位置が伝わらない',\n why: '何行目・何列目にいるのか、選択状態も読み上げられない。',\n },\n ],\n notes: [\n 'Tab はグリッドの外へ出るためのキーにし、セル移動は矢印キーに任せる。ネイティブな <table> との大きな違い。',\n 'セル内にボタン/リンクを置く場合は Enter や F2 で「セル内操作モード」に入る拡張を検討する。まず 1セル=1フォーカスの基本形を確実に動かすことが先決。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Treegrid パターン。\nexport const treegrid: PatternViewpoint = {\n slug: 'treegrid',\n keyboard: [\n {\n keys: 'Tab',\n action: 'グリッド全体に入る / 出る(中は1つのタブストップ)',\n requirement: 'required',\n },\n {\n keys: '↓ / ↑',\n action: '次 / 前の(見えている)行へフォーカス移動',\n requirement: 'required',\n },\n {\n keys: '→',\n action: '閉じている親行を展開する',\n requirement: 'required',\n },\n {\n keys: '←',\n action: '開いている親行を折りたたむ',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の(見えている)行へ移動',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: '外枠',\n attr: 'role=\"treegrid\" + aria-label',\n meaning: '「開閉できる表」だと伝える。名前(ラベル)も付ける。',\n },\n {\n target: '各行',\n attr: 'role=\"row\"',\n meaning: '表の1行であることを示す。',\n },\n {\n target: '見出しセル',\n attr: 'role=\"columnheader\"',\n meaning: '列の見出し。各セルがどの列の値かを関連付ける。',\n },\n {\n target: 'データセル',\n attr: 'role=\"gridcell\"',\n meaning: '行の中の1つのセル。',\n },\n {\n target: '展開できる親行',\n attr: 'aria-expanded=\"true | false\"',\n meaning: 'その行が開いているか。開閉に合わせて必ず更新する。',\n },\n {\n target: '各行',\n attr: 'aria-level / aria-posinset / aria-setsize',\n meaning: '階層の深さと、同階層での位置(任意・推奨)。',\n },\n {\n target: '行(フォーカス管理)',\n attr: 'tabindex=\"0 | -1\"',\n meaning: 'roving tabindex。今いる行だけ 0、ほかは -1。',\n },\n {\n target: '閉じている子行',\n attr: 'hidden',\n meaning: '閉じている間はDOMから隠し、キーボード/読み上げの対象外にする。',\n },\n ],\n checklist: [\n '外枠に role=\"treegrid\" と aria-label(名前)が付いている',\n '行は role=\"row\"、セルは role=\"gridcell\" / role=\"columnheader\"',\n '展開できる親行に aria-expanded があり、開閉と常に一致している',\n '閉じている子行は hidden でキーボード/読み上げから外れている',\n 'グリッド内は1タブストップで、↑↓ で行移動できる(roving tabindex)',\n '→ で展開、← で折りたたみができる',\n '(任意)Home / End で最初・最後の行へ移動できる',\n '(任意)aria-level / aria-posinset / aria-setsize で階層と位置を伝える',\n 'キーボードだけで操作でき、フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: '表・行・セルの意味が無い',\n why: 'role=\"treegrid\" 等が無く、スクリーンリーダーには「ただのテキストの塊」に聞こえる。どのセルがどの列かも関連付かない。',\n },\n {\n title: '開閉状態が伝わらない',\n why: 'aria-expanded が無く、開いているのか閉じているのか分からない。',\n },\n {\n title: 'キーボードで操作できない',\n why: 'div はフォーカスを受け取れず、矢印での移動・展開・折りたたみができない。',\n },\n {\n title: 'roving tabindex が無い',\n why: 'そもそもフォーカスの管理が存在しない。',\n },\n {\n title: 'display:none のインラインスタイル頼み',\n why: 'hidden 属性や状態管理が無い。',\n },\n ],\n notes: [\n 'ツリーグリッドの中は1つのタブストップ。Tab を連打しても各行に止まらず、矢印キーで行を移動する(roving tabindex)。',\n '矢印で移動する行は「見えている行」だけに絞る。開閉時は aria-expanded と子行の hidden を必ず一致させること。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Tree View パターン。\nexport const treeView: PatternViewpoint = {\n slug: 'tree-view',\n keyboard: [\n {\n keys: 'Tab',\n action: 'ツリーに入る / ツリーから出る(ツリー全体で1か所だけ止まる)',\n requirement: 'required',\n },\n {\n keys: '↓ / ↑',\n action: '表示中の次 / 前の項目へフォーカス移動',\n requirement: 'required',\n },\n {\n keys: '→',\n action: '閉じた枝なら展開。開いた枝なら最初の子へ。末端なら何もしない',\n requirement: 'required',\n },\n {\n keys: '←',\n action: '開いた枝なら折りたたみ。それ以外なら親の項目へ移動',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の表示中の項目へ移動',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: 'コンテナ',\n attr: 'role=\"tree\" + aria-label',\n meaning: '階層リスト全体。名前(ラベル)も付ける。',\n },\n {\n target: '各行',\n attr: 'role=\"treeitem\"',\n meaning: 'ツリーの1項目(フォルダ/ファイル)。',\n },\n {\n target: '開閉できる枝',\n attr: 'aria-expanded=\"true | false\"',\n meaning: '子を開いているか。開閉に合わせて必ず更新する。末端(子なし)には付けない。',\n },\n {\n target: '子のまとまり',\n attr: 'role=\"group\"',\n meaning: 'ある項目の子 treeitem を入れる入れ物。',\n },\n {\n target: '各行(任意)',\n attr: 'aria-level / aria-setsize / aria-posinset',\n meaning: '階層の深さ・同階層の総数・その中の位置。入れ子から自動推測されるが明示も可。',\n },\n {\n target: '各行',\n attr: 'tabindex=\"0 | -1\"',\n meaning: 'フォーカスを受け取る1つだけ 0、他は -1(roving tabindex)。',\n },\n ],\n checklist: [\n 'コンテナに role=\"tree\" と aria-label(名前)がある',\n '各行が role=\"treeitem\"、子のまとまりが role=\"group\" である',\n '開閉できる枝に aria-expanded があり、開閉と常に一致している',\n 'ツリー全体で Tab は1か所だけ止まる(roving tabindex:tabindex が1つだけ 0)',\n '↓↑ で表示中の項目を移動、→ で展開/子へ、← で折りたたみ/親へ',\n '(任意)Home/End で最初・最後へ移動できる',\n '折りたたまれた枝の中はキーボード/読み上げから外れている(hidden)',\n 'キーボードだけで操作でき、フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: 'キーボードで操作できない',\n why: 'span/li はフォーカスを受け取れず、矢印キーでの移動も無い。',\n },\n {\n title: 'ツリーだと伝わらない',\n why: 'role=\"tree\" が無く、スクリーンリーダーには「ただのリスト」に聞こえる。',\n },\n {\n title: '開閉状態が伝わらない',\n why: 'aria-expanded が無く、開いているか閉じているか分からない。',\n },\n {\n title: '階層・位置が伝わらない',\n why: '何階層目か、全何件中の何番目かが読み上げられない。',\n },\n ],\n notes: [\n 'ツリーはツリー全体でTab1回が原則。常に1つだけ tabindex=\"0\" にし、矢印キーで移動先を切り替える(roving tabindex)。',\n '矢印キーの移動先は「表示中(祖先がすべて展開済み)の項目」だけ。hidden な group 内の項目は候補から外す。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Feed パターン。\nexport const feed: PatternViewpoint = {\n slug: 'feed',\n keyboard: [\n {\n keys: 'PageDown',\n action: '次の記事へフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'PageUp',\n action: '前の記事へフォーカス移動',\n requirement: 'required',\n },\n {\n keys: 'Tab',\n action: '記事内のリンクなど、次のフォーカス可能要素へ移動',\n requirement: 'required',\n },\n {\n keys: 'Home / End',\n action: '最初 / 最後の記事へフォーカス移動',\n requirement: 'recommended',\n },\n ],\n aria: [\n {\n target: 'コンテナ',\n attr: 'role=\"feed\"',\n meaning: '動的に増えるスクロール可能な記事一覧であることを示す。',\n },\n {\n target: 'コンテナ',\n attr: 'aria-busy=\"true | false\"',\n meaning: '追加読み込み中は true。読み込み完了後は必ず false に戻す。',\n },\n {\n target: 'コンテナ',\n attr: 'aria-label / aria-labelledby',\n meaning: 'フィード自体に名前を付ける(「新着記事」など)。',\n },\n {\n target: '各記事',\n attr: 'role=\"article\" + tabindex=\"0\"',\n meaning: '1件の記事として認識させ、フォーカス可能にする。',\n },\n {\n target: '各記事',\n attr: 'aria-labelledby=\"タイトルのid\"',\n meaning: '記事の名前(見出し)を関連付ける。フォーカス時に読み上げられる。',\n },\n {\n target: '各記事',\n attr: 'aria-posinset + aria-setsize',\n meaning: '「全○件中の△番目」を示す。件数が増えたら全記事で更新する。',\n },\n ],\n checklist: [\n 'コンテナが role=\"feed\" で、aria-label 等で名前が付いている',\n '各記事が role=\"article\" + tabindex=\"0\" でフォーカスできる',\n '各記事に aria-labelledby で見出しが関連付いている',\n 'aria-posinset / aria-setsize が現在の位置・総数と常に一致している',\n '追加読み込み中は aria-busy=\"true\"、完了後に false へ戻る',\n 'PageDown / PageUp で記事間を移動できる(既定スクロールは preventDefault)',\n '追加読み込み後もフォーカスを失わない(新着の先頭などへ移す)',\n 'キーボードだけで読み進められ、フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: '一覧の構造が伝わらない',\n why: 'role=\"feed\" / role=\"article\" が無く、ただのテキストの塊に聞こえる。',\n },\n {\n title: '現在地が分からない',\n why: 'aria-posinset / aria-setsize が無く、「全何件の何番目か」を案内できない。',\n },\n {\n title: '読み込み中が伝わらない',\n why: 'aria-busy が無く、追加読み込みが起きても支援技術には無言のまま。',\n },\n {\n title: '記事間を移動できない',\n why: 'フォーカスできず、PageDown / PageUp での記事ジャンプも不可。',\n },\n {\n title: 'フォーカスが迷子になる',\n why: '追加読み込み後のフォーカス管理が無く、現在地を見失う。',\n },\n ],\n notes: [\n '記事間の移動に PageDown / PageUp を使うのは、Tab を記事内のリンク移動のために空けておくため。ハンドラ内で preventDefault() でブラウザ既定のスクロールを止める。',\n '追加読み込み後は新しく追加した記事の先頭にフォーカスを移す。aria-setsize も全記事で新しい総数に更新する。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Carousel パターン。\nexport const carousel: PatternViewpoint = {\n slug: 'carousel',\n keyboard: [\n {\n keys: 'Tab → Enter / Space(再生停止ボタン)',\n action: '自動回転の再生 / 停止を切り替える',\n requirement: 'required',\n },\n {\n keys: 'Enter / Space(前/次ボタン)',\n action: '前 / 次のスライドへ手動移動(移動すると自動回転は停止)',\n requirement: 'required',\n },\n {\n keys: 'フォーカス / ホバー',\n action: 'カルーセル内にフォーカス・マウスがある間は自動回転を一時停止',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'カルーセル全体',\n attr: 'aria-roledescription=\"carousel\" + aria-label',\n meaning: 'カルーセルであることと名前を伝える(任意・推奨)。',\n },\n {\n target: '再生/停止ボタン',\n attr: '<button> + 状態に応じた aria-label',\n meaning: '自動回転を止め/再開できるようにする(自動回転時は必須)。',\n },\n {\n target: '前/次ボタン',\n attr: '<button> + aria-label',\n meaning: 'アイコンだけでも目的が伝わるようラベルを付ける。',\n },\n {\n target: '各スライド',\n attr: 'role=\"group\" + aria-roledescription=\"スライド\" + aria-label=\"3枚中1枚目\"',\n meaning: '全体の枚数と現在位置を伝える。',\n },\n {\n target: 'スライドの箱',\n attr: 'aria-live=\"off | polite\"',\n meaning: '自動回転中は off、停止/手動中は polite に切り替える。',\n },\n {\n target: '非表示スライド',\n attr: 'hidden',\n meaning: '表示中以外は読み上げ/操作の対象外にする。',\n },\n ],\n checklist: [\n '自動回転するなら再生/停止ボタンを必須で用意している',\n 'フォーカス/ホバーの間は自動回転が一時停止する',\n '前/次/再生停止はすべてネイティブの <button>(div を使わない)',\n 'アイコンボタンに aria-label、停止/開始でラベルを切り替えている',\n '各スライドに role=\"group\" + 「○枚中○枚目」のラベルがある',\n '自動回転中は aria-live=\"off\"、停止/手動時は polite',\n '表示中以外のスライドは hidden',\n 'aria-roledescription=\"carousel\"(任意)、フォーカスが見える',\n ],\n antipatterns: [\n {\n title: '停止できない',\n why: '再生/停止ボタンがなく、WCAG 2.2.2 違反。動きに弱い人が読めない。',\n },\n {\n title: 'フォーカス/ホバーでも止まらない',\n why: '操作中も勝手に切り替わる。',\n },\n {\n title: '矢印がフォーカス不可',\n why: 'div + onclick でキーボードから操作できない。',\n },\n {\n title: '位置が伝わらない',\n why: 'スライドに role=\"group\" も「○枚中○枚目」ラベルもない。',\n },\n ],\n notes: [\n 'aria-roledescription を付けると、スクリーンリーダーが領域を「おすすめ特集, カルーセル」、各スライドを「3枚中1枚目, スライド」のように案内します(任意ですが分かりやすくなります)。',\n '「再生/停止ボタン」は、スライドより前(DOM 上で先)に置くのが推奨です。キーボード利用者が動きに気づいたとき、すぐ止められるようにするためです。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Tooltip パターン。\nexport const tooltip: PatternViewpoint = {\n slug: 'tooltip',\n keyboard: [\n {\n keys: 'Tab',\n action: 'トリガーにフォーカス → ツールチップが表示される',\n requirement: 'required',\n },\n {\n keys: 'Esc',\n action: '表示中のツールチップを閉じる(フォーカスはトリガーに残す)',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'トリガー',\n attr: 'aria-describedby=\"ツールチップのid\"',\n meaning: 'ツールチップを「説明」として関連付ける。フォーカス時に読み上げられる。',\n },\n {\n target: 'ツールチップ本体',\n attr: 'role=\"tooltip\"',\n meaning: 'これがツールチップであることを示す。',\n },\n {\n target: 'ツールチップ本体',\n attr: 'hidden(非表示時)',\n meaning: '出ていない間は読み上げ・表示の対象外にする。',\n },\n {\n target: 'トリガー',\n attr: 'フォーカス可能な要素(<button> 等)',\n meaning: 'キーボードでも到達できるようにする。<div> 等にしない。',\n },\n ],\n checklist: [\n 'トリガーはフォーカス可能な要素(<button> 等)',\n 'トリガーに aria-describedby でツールチップを関連付けている',\n 'ツールチップ本体に role=\"tooltip\" を付けている',\n 'フォーカスでもホバーでも表示される',\n 'Esc で閉じられる(フォーカスはトリガーに残す)',\n 'ツールチップ自身はフォーカスを受け取らない/操作要素を入れない',\n '操作に必須の情報をツールチップ「だけ」に入れていない',\n ],\n antipatterns: [\n {\n title: 'キーボードで出ない',\n why: 'title もホバー専用CSSも、Tab フォーカスでは表示されない。',\n },\n {\n title: 'タッチで出ない',\n why: 'ホバーの無い端末では永遠に表示されない。',\n },\n {\n title: '関連付けが無い',\n why: 'aria-describedby が無く、説明とトリガーが結びついていない。',\n },\n {\n title: '閉じられない',\n why: 'Esc で閉じる手段がない(WCAG 1.4.13 違反)。',\n },\n ],\n notes: [\n 'ツールチップ自身はフォーカスを受け取りません(Tab の対象にしない)。あくまでトリガーの補足なので、中にリンクやボタンを入れるのも避けます(操作要素を入れたいなら、それはツールチップではなくポップオーバー/ダイアログです)。',\n ],\n};\n","import type { PatternViewpoint } from '../../schema';\n\n// 観点データ(散文・デモは web の .astro に残す。ここは構造化できる観点のみ)。\n// 出典: APG Window Splitter パターン。\nexport const windowSplitter: PatternViewpoint = {\n slug: 'window-splitter',\n keyboard: [\n {\n keys: '← / →',\n action: 'ペインを狭く / 広くする(縦の境界の場合。横なら ↑ / ↓)',\n requirement: 'required',\n },\n {\n keys: 'Home',\n action: '最小サイズにする',\n requirement: 'required',\n },\n {\n keys: 'End',\n action: '最大サイズにする',\n requirement: 'required',\n },\n {\n keys: 'Enter',\n action: '折りたたむ/元のサイズに戻す(任意・推奨)',\n requirement: 'optional',\n },\n {\n keys: 'Tab',\n action: '次 / 前のフォーカス可能要素へ移動',\n requirement: 'required',\n },\n ],\n aria: [\n {\n target: 'ハンドル',\n attr: 'role=\"separator\"',\n meaning: '「大きさを変えられる区切り」だと支援技術へ伝える。',\n },\n {\n target: 'ハンドル',\n attr: 'tabindex=\"0\"',\n meaning: 'div をフォーカス可能にし、Tab で到達できるようにする。',\n },\n {\n target: 'ハンドル',\n attr: 'aria-valuenow=\"30\"',\n meaning: '現在の割合(やサイズ)。操作のたびに必ず更新する。',\n },\n {\n target: 'ハンドル',\n attr: 'aria-valuemin / aria-valuemax',\n meaning: '動かせる範囲の最小・最大。値はこの範囲にクランプする。',\n },\n {\n target: 'ハンドル',\n attr: 'aria-controls=\"ペインのid\"',\n meaning: 'どのペインの大きさを操作するかを示す。',\n },\n {\n target: 'ハンドル',\n attr: 'aria-label または aria-labelledby',\n meaning: '「何の幅か」を表す名前。フォーカス可能なので名前は必須。',\n },\n {\n target: 'ハンドル',\n attr: 'aria-orientation=\"vertical\"',\n meaning: '境界線の向き。縦線なら vertical(既定は horizontal)。',\n },\n ],\n checklist: [\n 'ハンドルに role=\"separator\" が付いている',\n 'ハンドルが tabindex=\"0\" でフォーカスできる',\n 'aria-label / aria-labelledby で名前が付いている',\n 'aria-valuenow が操作と常に一致し、見た目の幅と同期している',\n 'aria-valuemin / aria-valuemax があり、値が範囲内にクランプされる',\n 'aria-controls で操作対象のペインを指している',\n '矢印キーでリサイズ、Home / End で最小・最大にできる',\n '(任意)Enter で折りたたみ/元のサイズに復帰できる',\n 'キーボードだけで操作でき、フォーカスが見える(フォーカスリングを消していない)',\n ],\n antipatterns: [\n {\n title: '区切りだと伝わらない',\n why: 'role=\"separator\" が無く、操作対象に見えない。',\n },\n {\n title: '現在値・範囲が伝わらない',\n why: 'aria-valuenow / valuemin / valuemax が無く、いま何%かも限界も分からない。',\n },\n {\n title: 'フォーカスできない',\n why: 'tabindex が無く、Tab で到達できない。',\n },\n {\n title: 'キーボードでリサイズできない',\n why: '矢印・Home / End 処理が無く、マウス専用。',\n },\n {\n title: '折りたたみできない',\n why: 'Enter 等の代替手段が無い。',\n },\n ],\n notes: [\n '境界が縦線(左右のペインを区切る)なら左右矢印、横線(上下のペインを区切る)なら上下矢印を使います。aria-orientation は境界線そのものの向きを表し、縦線なら vertical です。',\n ],\n};\n","// 各パターンの「観点」データ(キーボード/ARIA/チェックリスト/アンチパターン)の登録。\n// 唯一の真実。web の表と cli の出力はどちらもここを参照する。\n// 個々のデータは ./viewpoints/<slug>.ts に置き、ここで集約・検証する。\nimport { patternViewpointSchema, type PatternViewpoint } from '../schema';\nimport { accordion } from './viewpoints/accordion';\nimport { disclosure } from './viewpoints/disclosure';\nimport { alert } from './viewpoints/alert';\nimport { dialogModal } from './viewpoints/dialog-modal';\nimport { alertdialog } from './viewpoints/alertdialog';\nimport { breadcrumb } from './viewpoints/breadcrumb';\nimport { menuMenubar } from './viewpoints/menu-menubar';\nimport { menuButton } from './viewpoints/menu-button';\nimport { link } from './viewpoints/link';\nimport { landmarks } from './viewpoints/landmarks';\nimport { button } from './viewpoints/button';\nimport { checkbox } from './viewpoints/checkbox';\nimport { radioGroup } from './viewpoints/radio-group';\nimport { switchPattern } from './viewpoints/switch';\nimport { combobox } from './viewpoints/combobox';\nimport { listbox } from './viewpoints/listbox';\nimport { slider } from './viewpoints/slider';\nimport { sliderMultithumb } from './viewpoints/slider-multithumb';\nimport { spinbutton } from './viewpoints/spinbutton';\nimport { meter } from './viewpoints/meter';\nimport { tabs } from './viewpoints/tabs';\nimport { toolbar } from './viewpoints/toolbar';\nimport { table } from './viewpoints/table';\nimport { grid } from './viewpoints/grid';\nimport { treegrid } from './viewpoints/treegrid';\nimport { treeView } from './viewpoints/tree-view';\nimport { feed } from './viewpoints/feed';\nimport { carousel } from './viewpoints/carousel';\nimport { tooltip } from './viewpoints/tooltip';\nimport { windowSplitter } from './viewpoints/window-splitter';\n\nconst allViewpoints: PatternViewpoint[] = [\n accordion,\n disclosure,\n alert,\n dialogModal,\n alertdialog,\n breadcrumb,\n menuMenubar,\n menuButton,\n link,\n landmarks,\n button,\n checkbox,\n radioGroup,\n switchPattern,\n combobox,\n listbox,\n slider,\n sliderMultithumb,\n spinbutton,\n meter,\n tabs,\n toolbar,\n table,\n grid,\n treegrid,\n treeView,\n feed,\n carousel,\n tooltip,\n windowSplitter,\n];\n\n/** slug → 観点(投入時に zod 検証する) */\nexport const viewpoints: Map<string, PatternViewpoint> = new Map(\n patternViewpointSchema\n .array()\n .parse(allViewpoints)\n .map((v) => [v.slug, v] as const),\n);\n\n/** slug で観点を1件取得 */\nexport function getPatternViewpoint(slug: string): PatternViewpoint | undefined {\n return viewpoints.get(slug);\n}\n","// @mew-lab/a11y-core — 公開 API\n// アクセシビリティ観点の唯一の真実。web(Astro)と cli が参照する。\nexport * from './schema';\nexport { patterns, getPattern, patternsByCategory } from './patterns/index';\nexport { criteria, getCriterion, criteriaByPrinciple, criteriaForPattern } from './wcag';\nexport { viewpoints, getPatternViewpoint } from './patterns/viewpoints';\n\nimport { getPattern, patterns } from './patterns/index';\nimport { getPatternViewpoint } from './patterns/viewpoints';\nimport { criteria, criteriaForPattern, getCriterion } from './wcag';\nimport type { Criterion, CriterionDetail, Pattern, PatternDetail } from './schema';\n\n/** パターン詳細(メタ + 観点 + 関連 WCAG)を取得 */\nexport function getPatternDetail(slug: string): PatternDetail | undefined {\n const pattern = getPattern(slug);\n if (!pattern) return undefined;\n return {\n ...pattern,\n viewpoint: getPatternViewpoint(slug) ?? null,\n criteria: criteriaForPattern(slug),\n };\n}\n\n/** WCAG 詳細(達成基準 + 関連パターンのメタ)を取得 */\nexport function getCriterionDetail(slug: string): CriterionDetail | undefined {\n const criterion = getCriterion(slug);\n if (!criterion) return undefined;\n const relatedPatterns = criterion.patterns\n .map((s) => getPattern(s))\n .filter((p): p is Pattern => p !== undefined);\n return { ...criterion, relatedPatterns };\n}\n\nexport interface SearchHit {\n kind: 'pattern' | 'wcag';\n slug: string;\n title: string;\n subtitle: string;\n}\n\n/** パターン + WCAG を横断検索(slug/番号/和名/英名/要約が対象) */\nexport function search(query: string): SearchHit[] {\n const q = query.trim().toLowerCase();\n if (q === '') return [];\n const hits: SearchHit[] = [];\n for (const p of patterns) {\n const haystack = [p.slug, p.ja, p.en, p.summary];\n if (haystack.some((f) => f.toLowerCase().includes(q))) {\n hits.push({ kind: 'pattern', slug: p.slug, title: `${p.ja}(${p.en})`, subtitle: p.summary });\n }\n }\n for (const c of criteria) {\n const haystack = [c.slug, c.num, c.ja, c.en, c.summary];\n if (haystack.some((f) => f.toLowerCase().includes(q))) {\n hits.push({\n kind: 'wcag',\n slug: c.slug,\n title: `${c.num} ${c.ja}(${c.en})`,\n subtitle: c.summary,\n });\n }\n }\n return hits;\n}\n","// 出力モード(human / json)の管理と JSON Contract(astryx 流)。\nimport pc from 'picocolors';\n\nexport const API_VERSION = 1;\n\n// 機械が分岐するための安定エラーコード(append-only。値は変えない)。\nexport const ERROR_CODES = {\n ERR_UNKNOWN: 'ERR_UNKNOWN',\n ERR_UNKNOWN_PATTERN: 'ERR_UNKNOWN_PATTERN',\n ERR_UNKNOWN_CRITERION: 'ERR_UNKNOWN_CRITERION',\n ERR_INVALID_OPTION: 'ERR_INVALID_OPTION',\n ERR_EMPTY_QUERY: 'ERR_EMPTY_QUERY',\n ERR_NODE_VERSION: 'ERR_NODE_VERSION',\n} as const;\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport interface Suggestion {\n slug: string;\n reason: string;\n}\n\n/** API 層が投げる構造化エラー。code と候補を機械可読に保つ。 */\nexport class A11yError extends Error {\n readonly code: ErrorCode;\n readonly suggestions: Suggestion[] | undefined;\n constructor(message: string, code: ErrorCode, suggestions?: Suggestion[]) {\n super(message);\n this.name = 'A11yError';\n this.code = code;\n this.suggestions = suggestions;\n }\n}\n\nlet jsonMode = false;\nexport function setJsonMode(on: boolean): void {\n jsonMode = on;\n}\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\n/** JSON モードでは無音。人間向けの装飾ログ専用。 */\nexport function humanLog(...args: unknown[]): void {\n if (!jsonMode) console.log(...args);\n}\n\n/** JSON モードの成功出力(type で機械判別できる封筒)。 */\nexport function jsonOut(type: string, data: unknown): void {\n console.log(JSON.stringify({ apiVersion: API_VERSION, type, data }, null, 2));\n}\n\n/** エラーを human / json で出力し、終了コード1で抜ける。 */\nexport function reportError(err: unknown): never {\n let message: string;\n let code: ErrorCode = ERROR_CODES.ERR_UNKNOWN;\n let suggestions: Suggestion[] | undefined;\n\n if (err instanceof A11yError) {\n message = err.message;\n code = err.code;\n suggestions = err.suggestions;\n } else if (err instanceof Error) {\n message = err.message;\n } else {\n message = String(err);\n }\n\n if (jsonMode) {\n console.log(\n JSON.stringify(\n { apiVersion: API_VERSION, error: message, code, suggestions: suggestions ?? undefined },\n null,\n 2,\n ),\n );\n } else {\n console.error(pc.red(`エラー: ${message}`));\n if (suggestions && suggestions.length > 0) {\n console.error('');\n console.error('もしかして:');\n for (const s of suggestions) {\n console.error(` ${pc.cyan(s.slug)} — ${s.reason}`);\n }\n }\n }\n process.exit(1);\n}\n","// プログラム利用向けの公開 API。CLI ハンドラも内部でこれを呼ぶ(ロジックを一本化)。\n// すべて { type, data } を返すか、A11yError を投げる。\nimport {\n criteria,\n criteriaByPrinciple,\n getCriterionDetail,\n getPatternDetail,\n patterns,\n patternsByCategory,\n search as coreSearch,\n type CriterionDetail,\n type PatternDetail,\n type SearchHit,\n} from '@mew-lab/a11y-core';\nimport { A11yError, ERROR_CODES, type Suggestion } from './output';\n\nexport interface ApiResult<T extends string, D> {\n type: T;\n data: D;\n}\n\n// ─────────────────────────── 候補提案(typo 救済) ───────────────────────────\n\nfunction bigrams(s: string): Set<string> {\n const g = new Set<string>();\n const t = s.toLowerCase();\n for (let i = 0; i < t.length - 1; i++) g.add(t.slice(i, i + 2));\n return g;\n}\n\n/** Dice 係数で近さを測る(0〜1)。 */\nfunction similarity(a: string, b: string): number {\n const ga = bigrams(a);\n const gb = bigrams(b);\n if (ga.size === 0 || gb.size === 0) return a === b ? 1 : 0;\n let inter = 0;\n for (const g of ga) if (gb.has(g)) inter++;\n return (2 * inter) / (ga.size + gb.size);\n}\n\nfunction suggestPatterns(slug: string): Suggestion[] {\n return patterns\n .map((p) => ({ slug: p.slug, score: similarity(slug, p.slug), ja: p.ja }))\n .filter((c) => c.score > 0.2)\n .sort((a, b) => b.score - a.score)\n .slice(0, 3)\n .map((c) => ({ slug: c.slug, reason: `${c.ja}(似た名前)` }));\n}\n\nfunction suggestCriteria(slug: string): Suggestion[] {\n return criteria\n .map((c) => ({ slug: c.slug, score: similarity(slug, c.slug), ja: c.ja, num: c.num }))\n .filter((c) => c.score > 0.2)\n .sort((a, b) => b.score - a.score)\n .slice(0, 3)\n .map((c) => ({ slug: c.slug, reason: `${c.num} ${c.ja}(似た番号)` }));\n}\n\n// ─────────────────────────── pattern ───────────────────────────\n\nexport interface PatternListData {\n total: number;\n categories: { category: string; items: { slug: string; ja: string; en: string; summary: string }[] }[];\n}\n\nexport function patternList(): ApiResult<'pattern.list', PatternListData> {\n const grouped = patternsByCategory().map((g) => ({\n category: g.category,\n items: g.items.map((p) => ({ slug: p.slug, ja: p.ja, en: p.en, summary: p.summary })),\n }));\n return { type: 'pattern.list', data: { total: patterns.length, categories: grouped } };\n}\n\nexport function patternDetail(slug: string): ApiResult<'pattern.detail', PatternDetail> {\n const detail = getPatternDetail(slug);\n if (!detail) {\n throw new A11yError(\n `'${slug}' というパターンはありません`,\n ERROR_CODES.ERR_UNKNOWN_PATTERN,\n suggestPatterns(slug),\n );\n }\n return { type: 'pattern.detail', data: detail };\n}\n\n// ─────────────────────────── wcag ───────────────────────────\n\nexport interface WcagListData {\n total: number;\n principles: {\n principle: string;\n items: { slug: string; num: string; ja: string; en: string; level: string; summary: string }[];\n }[];\n}\n\nexport function wcagList(): ApiResult<'wcag.list', WcagListData> {\n const grouped = criteriaByPrinciple().map((g) => ({\n principle: g.principle,\n items: g.items.map((c) => ({\n slug: c.slug,\n num: c.num,\n ja: c.ja,\n en: c.en,\n level: c.level,\n summary: c.summary,\n })),\n }));\n return { type: 'wcag.list', data: { total: criteria.length, principles: grouped } };\n}\n\nexport function wcagDetail(slug: string): ApiResult<'wcag.detail', CriterionDetail> {\n const detail = getCriterionDetail(slug);\n if (!detail) {\n throw new A11yError(\n `'${slug}' という達成基準はありません`,\n ERROR_CODES.ERR_UNKNOWN_CRITERION,\n suggestCriteria(slug),\n );\n }\n return { type: 'wcag.detail', data: detail };\n}\n\n// ─────────────────────────── search ───────────────────────────\n\nexport interface SearchData {\n query: string;\n total: number;\n hits: SearchHit[];\n}\n\nexport function search(query: string): ApiResult<'search.results', SearchData> {\n const q = query.trim();\n if (q === '') {\n throw new A11yError('検索キーワードを指定してください', ERROR_CODES.ERR_EMPTY_QUERY);\n }\n const hits = coreSearch(q);\n return { type: 'search.results', data: { query: q, total: hits.length, hits } };\n}\n\n// ─────────────────────────── checklist ───────────────────────────\n\nexport interface ChecklistData {\n slug: string;\n ja: string;\n checklist: string[];\n}\n\nexport function checklist(slug: string): ApiResult<'pattern.checklist', ChecklistData> {\n const detail = getPatternDetail(slug);\n if (!detail) {\n throw new A11yError(\n `'${slug}' というパターンはありません`,\n ERROR_CODES.ERR_UNKNOWN_PATTERN,\n suggestPatterns(slug),\n );\n }\n return {\n type: 'pattern.checklist',\n data: { slug: detail.slug, ja: detail.ja, checklist: detail.viewpoint?.checklist ?? [] },\n };\n}\n"],"mappings":"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CN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AClEO,IAAM,QAA0B;EACrC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SACE;IACJ;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AC1DO,IAAM,cAAgC;EAC3C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SACE;IACJ;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AC7EO,IAAM,cAAgC;EAC3C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACtFO,IAAM,aAA+B;EAC1C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACjEO,IAAM,cAAgC;EAC3C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACvGO,IAAM,aAA+B;EAC1C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACjGO,IAAM,OAAyB;EACpC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACjEO,IAAM,YAA8B;EACzC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AC5EO,IAAM,SAA2B;EACtC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACvEO,IAAM,WAA6B;EACxC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AClEO,IAAM,aAA+B;EAC1C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACvEO,IAAM,gBAAkC;EAC7C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACzEO,IAAM,WAA6B;EACxC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AC1GO,IAAM,UAA4B;EACvC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AC3EO,IAAM,SAA2B;EACtC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;ACjGO,IAAM,mBAAqC;EAChD,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACjGO,IAAM,aAA+B;EAC1C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AC5FO,IAAM,QAA0B;EACrC,MAAM;;EAEN,UAAU,CAAC;EACX,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACxEO,IAAM,OAAyB;EACpC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AClGO,IAAM,UAA4B;EACvC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AChFO,IAAM,QAA0B;EACrC,MAAM;EACN,UAAU,CAAC;EACX,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACrEO,IAAM,OAAyB;EACpC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AC5FO,IAAM,WAA6B;EACxC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AC5GO,IAAM,WAA6B;EACxC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AC7FO,IAAM,OAAyB;EACpC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;AC5FO,IAAM,WAA6B;EACxC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;IACA;EACF;AACF;ACnFO,IAAM,UAA4B;EACvC,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;EACF;EACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;EACF;EACA,cAAc;IACZ;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;IACA;MACE,OAAO;MACP,KAAK;IACP;EACF;EACA,OAAO;IACL;EACF;AACF;AClEO,IAAM,iBAAmC;EAC9C,MAAM;EACN,UAAU;IACR;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;IACA;MACE,MAAM;MACN,QAAQ;MACR,aAAa;IACf;EACF;EACA,MAAM;IACJ;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN,SAAS;IACX;IACA;MACE,QAAQ;MACR,MAAM;MACN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","names":["search"]}