@tatamicks/core 1.0.2 → 1.0.4

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.
Files changed (36) hide show
  1. package/dist/PalettePanel-BTB1LkgU.cjs +9 -0
  2. package/dist/PalettePanel-BTB1LkgU.cjs.map +1 -0
  3. package/dist/{PalettePanel-Cigl9i1N.js → PalettePanel-CrA2BGLq.js} +961 -959
  4. package/dist/PalettePanel-CrA2BGLq.js.map +1 -0
  5. package/dist/PalettePanel.css +1 -1
  6. package/dist/canvas.cjs +1 -1
  7. package/dist/canvas.mjs +4 -4
  8. package/dist/index.cjs +2 -2
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.css +1 -1
  11. package/dist/index.mjs +352 -343
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/{paperSettingsWidget-DvtghSA5.js → paperSettingsWidget-CAIw_Ofm.js} +1582 -1535
  14. package/dist/paperSettingsWidget-CAIw_Ofm.js.map +1 -0
  15. package/dist/paperSettingsWidget-CIRKgnz4.cjs +2 -0
  16. package/dist/paperSettingsWidget-CIRKgnz4.cjs.map +1 -0
  17. package/dist/shell.cjs +1 -1
  18. package/dist/shell.mjs +2 -2
  19. package/dist/sidebarPortal-Bigm11qq.js +880 -0
  20. package/dist/sidebarPortal-Bigm11qq.js.map +1 -0
  21. package/dist/sidebarPortal-Dit8f3sD.cjs +3 -0
  22. package/dist/sidebarPortal-Dit8f3sD.cjs.map +1 -0
  23. package/dist/src/canvas.d.ts +4 -0
  24. package/dist/src/index.d.ts +5 -3
  25. package/dist/src/shell.d.ts +3 -1
  26. package/package.json +1 -1
  27. package/dist/PalettePanel-BMZ6dfI3.cjs +0 -9
  28. package/dist/PalettePanel-BMZ6dfI3.cjs.map +0 -1
  29. package/dist/PalettePanel-Cigl9i1N.js.map +0 -1
  30. package/dist/paperSettingsWidget-7766a5Fe.cjs +0 -2
  31. package/dist/paperSettingsWidget-7766a5Fe.cjs.map +0 -1
  32. package/dist/paperSettingsWidget-DvtghSA5.js.map +0 -1
  33. package/dist/sidebarPortal-BN6FVwaF.js +0 -870
  34. package/dist/sidebarPortal-BN6FVwaF.js.map +0 -1
  35. package/dist/sidebarPortal-Cr-dLvA_.cjs +0 -3
  36. package/dist/sidebarPortal-Cr-dLvA_.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paperSettingsWidget-CIRKgnz4.cjs","sources":["../src/plugin/properties/fontStyle.ts","../src/plugin/properties/padding.ts","../src/plugin/properties/placeholder.ts","../src/plugin/properties/required.ts","../src/types/validation.ts","../src/plugin/validation.ts","../src/utils/block/index.ts","../src/types/schema.ts","../src/utils/zIndex/helpers.ts","../src/utils/book/index.ts","../src/utils/print/index.ts","../src/canvas/blocks/checkbox/renderer.tsx","../src/canvas/blocks/checkbox/plugin.ts","../src/canvas/blocks/select/props.ts","../src/canvas/blocks/select/renderer.tsx","../src/canvas/blocks/select/plugin.ts","../src/canvas/blocks/text/renderer.tsx","../src/canvas/blocks/text/plugin.ts","../src/contexts/action/useBookActionContext.ts","../src/contexts/binding/useBookBindingContext.ts","../src/contexts/history/useBookHistory.ts","../src/canvas/layers/BlockLayer/borderUtils.ts","../src/canvas/layers/BlockLayer/BlockBorder.tsx","../src/canvas/layers/BlockLayer/BlockCanvas.tsx","../src/canvas/layers/BlockLayer/BlockGuideBorder.tsx","../src/canvas/layers/BlockLayer/BlockRenderer.tsx","../src/canvas/layers/BlockLayer/utils/resolveBlockProps.ts","../src/canvas/layers/BlockLayer/ValidationOverlay.tsx","../src/canvas/layers/BlockLayer/BlockContainer.tsx","../src/canvas/layers/BlockLayer/BlockLayer.tsx","../src/canvas/layers/GridLayer/utils/getStrokeDasharray.ts","../src/canvas/layers/GridLayer/BorderOverlay.tsx","../src/canvas/layers/GridLayer/GridCanvas.tsx","../src/canvas/layers/GridLayer/GridDimensionLabel/GridUnitEditor.tsx","../src/canvas/layers/GridLayer/GridDimensionLabel/GridDimensionLabel.tsx","../src/canvas/layers/GridLayer/utils/getGridPathD.ts","../src/canvas/layers/GridLayer/GridOverlay.tsx","../src/canvas/layers/GridLayer/GridResizeHandle/GridResizeHandle.tsx","../src/canvas/layers/GridLayer/MarginOverlay.tsx","../src/canvas/layers/GridLayer/GridLayer.tsx","../src/canvas/layers/InteractionLayer/hooks/useInteractionState.ts","../src/canvas/layers/InteractionLayer/types.ts","../src/canvas/layers/InteractionLayer/utils/calcResize.ts","../src/canvas/layers/InteractionLayer/utils/clampMultipleBlocks.ts","../src/canvas/layers/InteractionLayer/utils/createBlock.ts","../src/canvas/layers/InteractionLayer/DragLayer.tsx","../src/canvas/layers/InteractionLayer/EditingBlock.tsx","../src/canvas/layers/InteractionLayer/InteractionBlock.tsx","../src/canvas/layers/InteractionLayer/SelectionLayer.tsx","../src/canvas/layers/InteractionLayer/utils/clampBlock.ts","../src/canvas/layers/InteractionLayer/utils/duplicateOffset.ts","../src/canvas/layers/InteractionLayer/utils/hitTest.ts","../src/canvas/layers/InteractionLayer/InteractionLayer.tsx","../src/plugin/context.ts","../src/utils/grid/calcGridSize.ts","../src/note/hooks/useNoteLayout.ts","../src/note/NoteEdit/NoteEdit.tsx","../src/note/NoteForm/NoteForm.tsx","../src/note/NoteView/NoteView.tsx","../src/note/Note/Note.tsx","../src/canvas/blocks/button/execute.ts","../src/canvas/blocks/button/props.ts","../src/canvas/blocks/button/renderer.tsx","../src/canvas/blocks/button/plugin.ts","../src/canvas/widgets/primitives/numberInputBlock.ts","../src/canvas/widgets/primitives/unitSelectBlock.ts","../src/canvas/blocks/stepper/props.ts","../src/canvas/blocks/stepper/step.ts","../src/canvas/blocks/stepper/renderer.tsx","../src/canvas/blocks/stepper/plugin.ts","../src/canvas/widgets/grid/gridSettingsWidget.ts","../src/canvas/blocks/note/renderer.tsx","../src/canvas/blocks/note/plugin.ts","../src/canvas/widgets/paper/paperSettingsWidget.ts"],"sourcesContent":["import type { Dimension, FontUnit } from \"../../types\";\nimport type { PropDef } from \"../types\";\n\n/**\n * ブロック内のフォントスタイルを保持する Props。\n */\nexport interface FontStyleProps {\n\t/** フォントファミリー */\n\tfontFamily?: string;\n\n\t/** フォントサイズ */\n\tfontSize?: Dimension<FontUnit>;\n\n\t/** 文字色(CSS カラー値) */\n\tcolor?: string;\n\n\t/** `true` のとき太字 */\n\tfontWeight?: boolean;\n\n\t/** `true` のときイタリック */\n\titalic?: boolean;\n\n\t/** `true` のとき下線 */\n\tunderline?: boolean;\n\n\t/** `true` のとき取り消し線 */\n\tlineThrough?: boolean;\n}\n\n/**\n * フォントスタイルプロパティの `PropDef`。\n *\n * @remarks\n * **Canvas** — ブロックプラグイン実装時に `plugin.props` へ追加する。\n */\nexport const fontStyleProp = {\n\tkind: \"fontStyle\",\n\tdefaultProps: {\n\t\tfontFamily: \"sans-serif\",\n\t\tfontSize: { value: 16, unit: \"px\" },\n\t\tcolor: \"#000000\",\n\t\tfontWeight: false,\n\t\titalic: false,\n\t\tunderline: false,\n\t\tlineThrough: false,\n\t},\n} satisfies PropDef;\n","import type { Dimension, PaddingUnit } from \"../../types\";\nimport type { PropDef } from \"../types\";\n\n/**\n * ブロック内の上下左右の余白を保持する Props。\n */\nexport interface PaddingProps {\n\ttop?: Dimension<PaddingUnit>;\n\tright?: Dimension<PaddingUnit>;\n\tbottom?: Dimension<PaddingUnit>;\n\tleft?: Dimension<PaddingUnit>;\n\n\t/** 全辺一括モード。`true` のとき `all` が全辺に適用される */\n\tbulk?: boolean;\n\n\t/** 全辺共通パディング(`bulk: true` のとき有効) */\n\tall?: Dimension<PaddingUnit>;\n}\n\n/**\n * 余白プロパティの `PropDef`。\n *\n * @remarks\n * **Canvas** — ブロックプラグイン実装時に `plugin.props` へ追加する。\n */\nexport const paddingProp = {\n\tkind: \"padding\",\n\tdefaultProps: {\n\t\ttop: { value: 0, unit: \"px\" },\n\t\tright: { value: 0, unit: \"px\" },\n\t\tbottom: { value: 0, unit: \"px\" },\n\t\tleft: { value: 0, unit: \"px\" },\n\t},\n} satisfies PropDef;\n","import type { PropDef } from \"../types\";\n\n/**\n * ブロックのプレースホルダーテキストを保持する Props。\n */\nexport interface PlaceholderProps {\n\t/** 未入力時に表示するプレースホルダー文字列 */\n\tplaceholder?: string;\n}\n\n/**\n * プレースホルダープロパティの `PropDef`。\n *\n * @remarks\n * **Canvas** — ブロックプラグイン実装時に `plugin.props` へ追加する。\n */\nexport const placeholderProp = {\n\tkind: \"placeholder\",\n\tdefaultProps: {\n\t\tplaceholder: \"テキストを入力\",\n\t},\n} satisfies PropDef;\n","import type { PropDef } from \"../types\";\n\n/**\n * ブロックの必須入力設定を保持する Props。\n */\nexport interface RequiredProps {\n\t/** `true` のとき、値が空の場合にバリデーションエラーとなる */\n\trequired?: boolean;\n}\n\n/**\n * 必須入力プロパティの `PropDef`。\n *\n * @remarks\n * **Canvas** — ブロックプラグイン実装時に `plugin.props` へ追加する。\n */\nexport const requiredProp = {\n\tkind: \"required\",\n\tdefaultProps: {\n\t\trequired: false,\n\t},\n} satisfies PropDef;\n","import type { Value } from \"./value\";\n\n/**\n * バリデーション結果の重大度レベル。\n */\nexport enum ValidationSeverity {\n\t/** 修正が必要なエラー */\n\tERROR = \"error\",\n\n\t/** 推奨される修正があるが続行可能な警告 */\n\tWARNING = \"warning\",\n\n\t/** 参考情報 */\n\tINFO = \"info\",\n}\n\n/**\n * バリデーション結果の1件分。プラグインのバリデーター関数が返す配列の要素型。\n *\n * @remarks\n * `useNoteLayout` が `Record<blockId, ValidationError[]>` として管理する。\n */\nexport interface ValidationError {\n\t/** ユーザーに表示するエラーメッセージ */\n\tmessage: string;\n\n\t/** エラー種別を識別するコード(例: `\"required\"`, `\"min_length\"`) */\n\tcode: string;\n\n\t/** エラーに関連するフィールド名。ブロック内の特定フィールドを示す場合に使用。 */\n\tfield?: string;\n\n\t/** 重大度レベル */\n\tseverity: ValidationSeverity;\n\n\t/** プラグインが付加する任意のメタデータ */\n\tmetadata?: Record<string, Value>;\n}\n","import { ValidationSeverity } from \"../types/validation\";\n\nimport type { ValidationError } from \"../types/validation\";\n\n/**\n * 必須バリデーションのみのスキーマ(Select・Checkbox で使用)。\n */\nexport interface RequiredSchema {\n\t/** `true` のとき、未入力または空値でエラーとなる。省略時はバリデーションしない */\n\trequired?: boolean;\n}\n\n/**\n * バリデーションプロパティのスキーマ(Text で使用)。\n */\nexport interface ValidationSchema extends RequiredSchema {\n\t/** 入力文字数の最小値。省略時はチェックしない */\n\tminLength?: number;\n\n\t/** 入力文字数の最大値。省略時はチェックしない */\n\tmaxLength?: number;\n\n\t/** 入力値にマッチさせる正規表現パターン。省略時はチェックしない */\n\tpattern?: string;\n}\n\n// ReDoS の原因となる危険な正規表現パターン(ネスト量詞子等)を検出する簡易チェック\nfunction isSafePattern(pattern: string): boolean {\n\tif (pattern.length > 200) return false;\n\tif (/\\((?:[^[\\]()*+?\\\\]|\\\\.|\\[[^\\]]*\\])[+*][^()]*\\)[+*{]/.test(pattern))\n\t\treturn false;\n\treturn true;\n}\n\n/**\n * `block.props` がバリデーションルールを持つかどうかを判定する型ガード。\n */\nexport function hasValidationRule(props: unknown): props is ValidationSchema {\n\tif (typeof props !== \"object\" || props === null) return false;\n\tconst p = props as Record<string, unknown>;\n\treturn (\n\t\tp.required !== undefined ||\n\t\tp.minLength !== undefined ||\n\t\tp.maxLength !== undefined ||\n\t\tp.pattern !== undefined\n\t);\n}\n\n/**\n * `ValidationSchema` の設定値と実際の値を照合し、違反しているエラーを返す。\n *\n * エラーがなければ空配列を返す。\n */\nexport function evaluateValidation(\n\tschema: ValidationSchema,\n\tvalue: string | undefined,\n): ValidationError[] {\n\tconst errors: ValidationError[] = [];\n\tconst v = value ?? \"\";\n\n\tif (schema.required && v.length === 0) {\n\t\terrors.push({\n\t\t\tcode: \"REQUIRED\",\n\t\t\tmessage: \"必須項目です\",\n\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t});\n\t}\n\n\tif (schema.minLength !== undefined && v.length < schema.minLength) {\n\t\terrors.push({\n\t\t\tcode: \"MIN_LENGTH\",\n\t\t\tmessage: `${schema.minLength}文字以上入力してください`,\n\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t});\n\t}\n\n\tif (schema.maxLength !== undefined && v.length > schema.maxLength) {\n\t\terrors.push({\n\t\t\tcode: \"MAX_LENGTH\",\n\t\t\tmessage: `${schema.maxLength}文字以内で入力してください`,\n\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t});\n\t}\n\n\tif (schema.pattern) {\n\t\tif (isSafePattern(schema.pattern)) {\n\t\t\ttry {\n\t\t\t\tconst re = new RegExp(schema.pattern);\n\t\t\t\tif (!re.test(v)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"PATTERN\",\n\t\t\t\t\t\tmessage: \"形式が正しくありません\",\n\t\t\t\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// 不正な正規表現は無視する\n\t\t\t}\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * チェックボックス用バリデーション。\n *\n * エラーがなければ空配列を返す。\n */\nexport function evaluateCheckboxValidation(\n\tschema: RequiredSchema,\n\tvalue: boolean | undefined,\n): ValidationError[] {\n\tif (schema.required && value !== true) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tcode: \"REQUIRED\",\n\t\t\t\tmessage: \"必須項目です\",\n\t\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t\t},\n\t\t];\n\t}\n\treturn [];\n}\n","import type { HiddenBinding } from \"../../types/block\";\nimport type { BindingContext } from \"../../types/context\";\n\n/**\n * ブロックの一意 ID を生成する。\n *\n * `kind` をプレフィックスにした UUID 形式(例: `text_xxxxxxxx-...`)。\n */\nexport function createBlockId(kind: string): string {\n\treturn `${kind}_${crypto.randomUUID()}`;\n}\n\n/**\n * `hiddenBinding` の条件を評価し、ブロックを非表示にすべきか返す。\n *\n * - `undefined` / `bindingContext` がない場合は常に `false`(表示)\n * - `string` 形式: `Boolean(get(path))` が truthy → `true`(非表示)\n * - `{ path, eq }` 形式: `get(path) === eq` → `true`(非表示)\n * - `{ path, neq }` 形式: `get(path) !== neq` → `true`(非表示)\n */\nexport function evalHiddenBinding(\n\thidden: HiddenBinding | undefined,\n\tbindingContext: BindingContext | undefined,\n): boolean {\n\tif (hidden == null || bindingContext == null) return false;\n\tif (typeof hidden === \"string\") return Boolean(bindingContext.get(hidden));\n\tconst cur = bindingContext.get(hidden.path);\n\tif (\"eq\" in hidden) return cur === hidden.eq;\n\treturn cur !== hidden.neq;\n}\n","import { DEFAULT_GRID, type Grid } from \"./grid\";\nimport { DEFAULT_PAPER, type Paper } from \"./paper\";\n\nimport type { Block } from \"./block\";\nimport type { Value } from \"./value\";\n\n/**\n * ブロック種別ごとの共通デフォルトプロパティ。\n *\n * @remarks\n * - キー: プラグインの kind(例: `\"text\"`, `\"checkbox\"`)\n * - 値: プロパティの部分辞書。`block.props` にキーが存在しない場合に参照され、\n * それも存在しない場合は `PropDef.defaultProps` にフォールバックする\n *\n * @example\n * ```ts\n * const defaults: BlockDefaults = {\n * text: { fontFamily: \"serif\", verticalAlign: \"center\" },\n * checkbox: { horizontalAlign: \"center\" },\n * };\n * ```\n */\nexport type BlockDefaults = Record<string, Record<string, Value>>;\n\n/**\n * 1ページ分のフォームスキーマ。\n */\nexport interface Page {\n\t/** ページの一意 ID。保存済み Book に ID がない場合は {@link ensurePageIds} で付与できる */\n\tid?: string;\n\n\t/** グリッド設定(スパース形式)。全列・全行が 1fr の場合は colCount / rowCount のみ */\n\tgrid: Grid;\n\n\t/** 配置されているブロック一覧 */\n\tblocks: Block[];\n\n\t/** ブロック種別ごとの共通デフォルト設定。値解決順序は `Block` の @remarks を参照 */\n\tblockDefaults?: BlockDefaults;\n\n\t/** ページ固有のメタデータ(バージョン・タイトルなど) */\n\tmetaData?: Record<string, Value>;\n}\n\n/**\n * デフォルトフォームスキーマ(空ページ)。\n */\nexport const DEFAULT_PAGE: Page = {\n\tgrid: DEFAULT_GRID,\n\tblocks: [],\n};\n\n/**\n * 複数ページのフォームを表すスキーマ(Book)。\n *\n * @remarks\n * - `pages` は最低1ページ必須(タプル型で空配列を禁止)\n * - `Page.id` はオプション。index による識別がベースだが、並び替え・外部同期には `id` を利用する\n * - `block.id` はブック全体でユニークであること\n * - `paper` はブック全体で共通(全ページ同一の用紙設定を維持する)\n */\nexport interface Book {\n\t/** ブック全体の用紙設定。全ページ共通(PDF の慣習に従いページごとの変更は不可) */\n\tpaper: Paper;\n\n\t/** ページ一覧(0-based インデックス順) */\n\tpages: [Page, ...Page[]];\n\n\t/** ブックレベルのメタデータ。例: `{ title: \"月次業務報告書\", version: \"2\" }` */\n\tmetaData?: Record<string, Value>;\n}\n\n/**\n * デフォルト Book(1ページ・空スキーマ)。\n */\nexport const DEFAULT_BOOK: Book = {\n\tpaper: DEFAULT_PAPER,\n\tpages: [DEFAULT_PAGE],\n};\n","import { Z_INDEX } from \"./constants\";\n\n/**\n * ブロックの表示順序インデックスから CSS z-index 値を返す。\n *\n * `index` が範囲上限(`BLOCK_LAYER_MAX`)を超えた場合は `BLOCK_LAYER_MAX` にクランプする。\n */\nexport function getBlockZIndex(index: number): number {\n\tconst zIndex = Z_INDEX.BLOCK_LAYER_MIN + index * Z_INDEX.BLOCK_LAYER_STEP;\n\tif (zIndex >= Z_INDEX.BLOCK_LAYER_MAX) {\n\t\treturn Z_INDEX.BLOCK_LAYER_MAX;\n\t}\n\treturn zIndex;\n}\n\n/**\n * ブロックのベース z-index にサブインデックスオフセットを加えた値を返す。\n *\n * `subIndex` は `0` 以上 `BLOCK_LAYER_STEP - 1` 以下にクランプされる。\n */\nexport function getSubZIndex(baseZIndex: number, subIndex: number): number {\n\tconst clampedOffset = Math.min(\n\t\tMath.max(0, subIndex),\n\t\tZ_INDEX.BLOCK_LAYER_STEP - 1,\n\t);\n\treturn baseZIndex + clampedOffset;\n}\n\n/**\n * z-index 範囲内に配置できる最大ブロック数を返す。\n */\nexport function getMaxBlockCount(): number {\n\treturn Math.floor(\n\t\t(Z_INDEX.BLOCK_LAYER_MAX - Z_INDEX.BLOCK_LAYER_MIN) /\n\t\t\tZ_INDEX.BLOCK_LAYER_STEP,\n\t);\n}\n","import { DEFAULT_PAGE } from \"../../types/schema\";\nimport { ValidationSeverity } from \"../../types/validation\";\nimport { getMaxBlockCount } from \"../zIndex\";\n\nimport type { Book, Page } from \"../../types/schema\";\nimport type { ValidationError } from \"../../types/validation\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * Book 全体の blockId 重複・ページごとのブロック数上限を検証する。\n *\n * 問題があれば `ValidationError[]` を返す。空配列は valid。\n */\nexport function validateBook(book: Book): ValidationError[] {\n\tconst errors: ValidationError[] = [];\n\tconst seen = new Set<string>();\n\tconst duplicates = new Set<string>();\n\tconst maxBlockCount = getMaxBlockCount();\n\n\tfor (const [pageIndex, page] of book.pages.entries()) {\n\t\tfor (const block of page.blocks) {\n\t\t\tif (seen.has(block.id)) {\n\t\t\t\tduplicates.add(block.id);\n\t\t\t} else {\n\t\t\t\tseen.add(block.id);\n\t\t\t}\n\t\t}\n\t\tif (page.blocks.length > maxBlockCount) {\n\t\t\terrors.push({\n\t\t\t\tmessage: `ページ ${pageIndex + 1} のブロック数 (${page.blocks.length}) が上限 (${maxBlockCount}) を超えています`,\n\t\t\t\tcode: \"BLOCK_COUNT_EXCEEDED\",\n\t\t\t\tfield: page.id ?? `page-${pageIndex}`,\n\t\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t\t});\n\t\t}\n\t}\n\n\tfor (const id of duplicates) {\n\t\terrors.push({\n\t\t\tmessage: `blockId \"${id}\" が複数ページに重複して存在します`,\n\t\t\tcode: \"DUPLICATE_BLOCK_ID\",\n\t\t\tfield: id,\n\t\t\tseverity: ValidationSeverity.ERROR,\n\t\t});\n\t}\n\n\treturn errors;\n}\n\nfunction toNonEmptyPages(pages: Page[]): Book[\"pages\"] {\n\tif (pages.length === 0) throw new Error(\"pages must not be empty\");\n\treturn pages as Book[\"pages\"];\n}\n\n/**\n * 末尾に空ページを追加した新しい Book を返す。\n */\nexport function addPage(book: Book): Book {\n\tconst emptyPage: Page = { ...DEFAULT_PAGE, id: crypto.randomUUID() };\n\treturn {\n\t\t...book,\n\t\tpages: toNonEmptyPages([...book.pages, emptyPage]),\n\t};\n}\n\n/**\n * `id` を持たないページに一意 ID を付与した新しい Book を返す。\n *\n * 保存済み Book の migration に使用する。既に `id` があるページは変更しない。\n */\nexport function ensurePageIds(book: Book): Book {\n\tconst pages = toNonEmptyPages(\n\t\tbook.pages.map((page) =>\n\t\t\tpage.id !== undefined ? page : { ...page, id: crypto.randomUUID() },\n\t\t),\n\t);\n\treturn { ...book, pages };\n}\n\n/**\n * 指定インデックスのページを削除した新しい Book を返す。\n *\n * 1ページのみの場合は no-op。\n */\nexport function removePage(book: Book, index: number): Book {\n\tif (book.pages.length <= 1) return book;\n\tconst pages = book.pages.filter((_, i) => i !== index);\n\treturn { ...book, pages: toNonEmptyPages(pages) };\n}\n\n/**\n * ページの順序を変えた新しい Book を返す。\n *\n * `from === to` の場合は no-op。\n */\nexport function movePage(book: Book, from: number, to: number): Book {\n\tif (from === to) return book;\n\tconst pages = [...book.pages];\n\tconst moved = pages.splice(from, 1)[0];\n\tif (!moved) return book;\n\tpages.splice(to, 0, moved);\n\treturn { ...book, pages: toNonEmptyPages(pages) };\n}\n\n/**\n * 指定インデックスのページを置き換えた新しい Book を返す。\n */\nexport function setPage(book: Book, pageIdx: number, page: Page): Book {\n\treturn {\n\t\t...book,\n\t\tpages: toNonEmptyPages(\n\t\t\tbook.pages.map((p, i) => (i === pageIdx ? page : p)),\n\t\t),\n\t};\n}\n\n/**\n * `afterIdx` の直後に新しいページを挿入した新しい Book を返す。\n */\nexport function insertPage(book: Book, afterIdx: number, page: Page): Book {\n\tconst newPages = [\n\t\t...book.pages.slice(0, afterIdx + 1),\n\t\tpage,\n\t\t...book.pages.slice(afterIdx + 1),\n\t];\n\treturn { ...book, pages: toNonEmptyPages(newPages) };\n}\n\n/**\n * Book に存在しない blockId のエントリを `values` から除去して返す。\n */\nexport function cleanValues(\n\tbook: Book,\n\tvalues: Record<string, Value>,\n): Record<string, Value> {\n\tconst existingIds = new Set(\n\t\tbook.pages.flatMap((page) => page.blocks.map((b) => b.id)),\n\t);\n\treturn Object.fromEntries(\n\t\tObject.entries(values).filter(([k]) => existingIds.has(k)),\n\t);\n}\n","import {\n\tDEFAULT_PAPER_SIZES,\n\ttype Paper,\n\ttype PaperSizePreset,\n} from \"../../types/paper\";\nimport { toMm } from \"../convert\";\n\nimport type { PrintMargin, PrintSettings } from \"../../types/print\";\nimport type { Book } from \"../../types/schema\";\n\n/**\n * プリセット用紙サイズの対応寸法を mm 単位で返す。\n *\n * `orientation` が `true` のとき横向き(幅と高さを入れ替え)。\n */\nexport function getPaperSize(\n\tpreset: Exclude<PaperSizePreset, PaperSizePreset.CUSTOM>,\n\torientation: boolean,\n): { width: number; height: number } {\n\tconst size = DEFAULT_PAPER_SIZES[preset];\n\tconst w = toMm.fromDim(size.width);\n\tconst h = toMm.fromDim(size.height);\n\treturn orientation ? { width: h, height: w } : { width: w, height: h };\n}\n\n/**\n * `book.paper` に `printSettings` のサイズ・向きをマージした実効用紙設定を返す。\n *\n * `printSettings` を省略した場合は `book.paper` をそのまま返す。\n */\nexport function resolveEffectivePaper(\n\tbook: Book,\n\tprintSettings?: PrintSettings,\n): Paper {\n\treturn {\n\t\t...book.paper,\n\t\tsize:\n\t\t\tprintSettings?.paperSize != null\n\t\t\t\t? (DEFAULT_PAPER_SIZES[printSettings.paperSize] ?? book.paper.size)\n\t\t\t\t: book.paper.size,\n\t\torientation: printSettings?.orientation ?? book.paper.orientation,\n\t};\n}\n\n/**\n * 用紙設定から `@page` CSS 文字列を生成する。\n *\n * `margin` を省略した場合は `margin:0` になる。\n */\nexport function buildPageCss(paper: Paper, margin?: PrintMargin): string {\n\tconst isLandscape = paper.orientation === true;\n\tconst w = Math.round(\n\t\ttoMm.fromDim(isLandscape ? paper.size.height : paper.size.width),\n\t);\n\tconst h = Math.round(\n\t\ttoMm.fromDim(isLandscape ? paper.size.width : paper.size.height),\n\t);\n\tconst marginCss = margin\n\t\t? `margin-top:${margin.top ?? \"0\"};margin-right:${margin.right ?? \"0\"};margin-bottom:${margin.bottom ?? \"0\"};margin-left:${margin.left ?? \"0\"};`\n\t\t: \"margin:0;\";\n\treturn `@page { size: ${w}mm ${h}mm; ${marginCss} }`;\n}\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n} from \"react\";\n\nimport {\n\tHorizontalAlign,\n\tVerticalAlign,\n} from \"../../../plugin/properties/alignment\";\nimport { dimensionToString, toPx } from \"../../../utils\";\nimport { ClassicCheckboxVisual } from \"./visual\";\n\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { CheckboxBlockProps, CheckboxBlockValue } from \"./types\";\n\n// HorizontalAlign → CSS justifyContent のマッピングテーブル\nconst H_ALIGN_CSS: Record<HorizontalAlign, CSSProperties[\"justifyContent\"]> = {\n\t[HorizontalAlign.left]: \"flex-start\",\n\t[HorizontalAlign.center]: \"center\",\n\t[HorizontalAlign.right]: \"flex-end\",\n};\n\n// VerticalAlign → CSS alignItems のマッピングテーブル\nconst V_ALIGN_CSS: Record<VerticalAlign, CSSProperties[\"alignItems\"]> = {\n\t[VerticalAlign.top]: \"flex-start\",\n\t[VerticalAlign.center]: \"center\",\n\t[VerticalAlign.bottom]: \"flex-end\",\n};\n\n/**\n * チェックボックスブロックのレンダラーコンポーネント。\n *\n * `value`(`boolean`)のトグル操作をし、SVG ビジュアルでチェック状態を表示する。\n */\nexport const CheckboxRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<CheckboxBlockProps, CheckboxBlockValue>\n>(({ id, props, value, onChange, readOnly, ariaLabel }, ref) => {\n\tconst divRef = useRef<HTMLDivElement>(null);\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({ focus: () => divRef.current?.focus() }),\n\t\t[],\n\t);\n\n\tconst isChecked = value ?? false;\n\n\tconst containerStyle = useMemo((): CSSProperties => {\n\t\tconst css: CSSProperties = {\n\t\t\twidth: \"100%\",\n\t\t\theight: \"100%\",\n\t\t\tdisplay: \"flex\",\n\t\t\tboxSizing: \"border-box\",\n\t\t\toverflow: \"hidden\",\n\t\t\tcursor: readOnly ? \"default\" : \"pointer\",\n\t\t};\n\n\t\tcss.justifyContent =\n\t\t\tH_ALIGN_CSS[props.horizontal ?? HorizontalAlign.center];\n\t\tcss.alignItems = V_ALIGN_CSS[props.vertical ?? VerticalAlign.center];\n\n\t\tconst padAll = props.bulk ? props.all : undefined;\n\t\tconst padTop = padAll ?? props.top;\n\t\tconst padRight = padAll ?? props.right;\n\t\tconst padBottom = padAll ?? props.bottom;\n\t\tconst padLeft = padAll ?? props.left;\n\t\tif (padTop) css.paddingTop = dimensionToString(padTop);\n\t\tif (padRight) css.paddingRight = dimensionToString(padRight);\n\t\tif (padBottom) css.paddingBottom = dimensionToString(padBottom);\n\t\tif (padLeft) css.paddingLeft = dimensionToString(padLeft);\n\n\t\treturn css;\n\t}, [props, readOnly]);\n\n\tconst sizePx = props.styleConfig?.checkboxSize\n\t\t? toPx.fromDim(props.styleConfig.checkboxSize)\n\t\t: 16;\n\n\tconst handleClick = () => {\n\t\tif (readOnly) return;\n\t\tonChange(!isChecked);\n\t};\n\n\treturn (\n\t\t<div\n\t\t\tref={divRef}\n\t\t\tstyle={containerStyle}\n\t\t\trole=\"switch\"\n\t\t\taria-checked={isChecked}\n\t\t\taria-label={ariaLabel}\n\t\t\ttabIndex={readOnly ? -1 : 0}\n\t\t\tonClick={handleClick}\n\t\t\tonKeyDown={(e) => {\n\t\t\t\tif (e.key === \" \" || e.key === \"Enter\") {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\thandleClick();\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<input\n\t\t\t\tid={id}\n\t\t\t\ttype=\"checkbox\"\n\t\t\t\tchecked={isChecked}\n\t\t\t\tonChange={() => {}}\n\t\t\t\tstyle={{ display: \"none\" }}\n\t\t\t\ttabIndex={-1}\n\t\t\t\treadOnly\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: sizePx,\n\t\t\t\t\theight: sizePx,\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<ClassicCheckboxVisual\n\t\t\t\t\tchecked={isChecked}\n\t\t\t\t\tstyleConfig={props.styleConfig}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n});\n\nCheckboxRenderer.displayName = \"CheckboxRenderer\";\n","import { alignmentProp, paddingProp, requiredProp } from \"../../../plugin\";\nimport { HorizontalAlign } from \"../../../plugin/properties/alignment\";\nimport { checkboxStyleProp } from \"./props\";\nimport { CheckboxRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin\";\nimport type { CheckboxBlockProps, CheckboxBlockValue } from \"./types\";\n\n// checkboxAlignmentProp: デフォルトを中央寄せにオーバーライドしたチェックボックス専用の alignment prop\nconst checkboxAlignmentProp = {\n\t...alignmentProp,\n\tdefaultProps: {\n\t\t...alignmentProp.defaultProps,\n\t\thorizontal: HorizontalAlign.center,\n\t},\n};\n\n/**\n * チェックボックスブロックのプラグイン定義。\n *\n * `kind: \"checkbox\"` で登録され、チェック・非チェックを `boolean` 値で管理する。\n */\nexport const CheckboxPlugin: BlockPlugin<\n\tCheckboxBlockProps,\n\tCheckboxBlockValue\n> = {\n\tkind: \"checkbox\",\n\n\tmeta: {\n\t\tdisplayName: \"チェックボックス\",\n\t\tdescription: \"チェック/非チェックを選択する入力ブロック\",\n\t\tdefaultSize: { w: 2, h: 2 },\n\t},\n\n\tRenderer: CheckboxRenderer,\n\n\tproperties: [\n\t\tcheckboxAlignmentProp,\n\t\tpaddingProp,\n\t\trequiredProp,\n\t\tcheckboxStyleProp,\n\t],\n\n\tvalidateProps: (props: unknown): CheckboxBlockProps => {\n\t\tconst p = (\n\t\t\ttypeof props === \"object\" && props !== null ? props : {}\n\t\t) as Record<string, unknown>;\n\t\treturn { ...p } as CheckboxBlockProps;\n\t},\n\n\tvalidateValue: (value: unknown): CheckboxBlockValue => {\n\t\tif (typeof value === \"boolean\") return value;\n\t\treturn false;\n\t},\n};\n","import type { PropDef } from \"../../../plugin\";\n\n/**\n * セレクトボックスの個々の選択肢。\n */\nexport interface SelectOption {\n\t/** ユーザーに表示するラベル。 */\n\tlabel: string;\n\n\t/** 選択時にブロック値として記録される内部値。 */\n\tvalue: string;\n\n\t/** ラベルに適用する文字色(任意)。 */\n\tcolor?: string;\n}\n\n/**\n * セレクトボックスの選択肢一覧と機能設定。\n */\nexport interface SelectOptionsConfig {\n\t/** 選択肢の配列。 */\n\toptions: SelectOption[];\n\n\t/** `true` のとき空白選択(未選択)を許可する。 */\n\tallowEmpty?: boolean;\n}\n\n/**\n * セレクトボックスの選択肢設定 props。\n */\nexport interface SelectConfigProps {\n\t/** 選択肢と機能設定。 */\n\tselectConfig: SelectOptionsConfig;\n}\n\n/**\n * `selectConfig` prop 定義。セレクトボックスの選択肢デフォルト値を含む。\n */\nexport const selectConfigProp = {\n\tkind: \"selectConfig\",\n\tdefaultProps: {\n\t\tselectConfig: {\n\t\t\toptions: [\n\t\t\t\t{ label: \"option1\", value: \"option1\" },\n\t\t\t\t{ label: \"option2\", value: \"option2\" },\n\t\t\t],\n\t\t},\n\t},\n} satisfies PropDef;\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n} from \"react\";\n\nimport {\n\tHorizontalAlign,\n\tVerticalAlign,\n} from \"../../../plugin/properties/alignment\";\nimport { NoteMode } from \"../../../types\";\nimport { dimensionToString, toPx } from \"../../../utils\";\n\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { SelectBlockProps, SelectBlockValue } from \"./types\";\n\n// isValidCssColor: 色文字列が CSS background に安全に渡せる形式(# + 16進数)かをチェックする\nfunction isValidCssColor(color: string): boolean {\n\treturn /^#[0-9a-fA-F]{3,8}$/.test(color);\n}\n\n// HorizontalAlign → CSS textAlign のマッピングテーブル\nconst H_ALIGN_TEXT: Record<HorizontalAlign, CSSProperties[\"textAlign\"]> = {\n\t[HorizontalAlign.left]: \"left\",\n\t[HorizontalAlign.center]: \"center\",\n\t[HorizontalAlign.right]: \"right\",\n};\n\n// VerticalAlign → CSS alignItems のマッピングテーブル\nconst V_ALIGN_CSS: Record<VerticalAlign, CSSProperties[\"alignItems\"]> = {\n\t[VerticalAlign.top]: \"flex-start\",\n\t[VerticalAlign.center]: \"center\",\n\t[VerticalAlign.bottom]: \"flex-end\",\n};\n\n/**\n * セレクトボックスブロックのレンダラーコンポーネント。\n *\n * 選択肢一覧からユーザーが 1 つを選択し、`string | null` 値を管理する。\n *\n * `mode === NoteMode.VIEW` のときは選択ラベルをテキストとして表示する。\n */\nexport const SelectRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<SelectBlockProps, SelectBlockValue>\n>(\n\t(\n\t\t{\n\t\t\tid,\n\t\t\tprops,\n\t\t\tvalue,\n\t\t\tonChange,\n\t\t\treadOnly,\n\t\t\tmode,\n\t\t\tariaLabel,\n\t\t\tblockBackgroundColor,\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst selectRef = useRef<HTMLSelectElement>(null);\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({ focus: () => selectRef.current?.focus() }),\n\t\t\t[],\n\t\t);\n\n\t\tconst isDisabled = readOnly || mode === NoteMode.VIEW;\n\n\t\tconst selectedOption = (props.selectConfig?.options ?? []).find(\n\t\t\t(o) => o.value === value,\n\t\t);\n\t\tconst selectedColor = selectedOption?.color;\n\t\tconst bgColor =\n\t\t\tselectedColor && isValidCssColor(selectedColor)\n\t\t\t\t? selectedColor\n\t\t\t\t: undefined;\n\n\t\tconst containerStyle = useMemo((): CSSProperties => {\n\t\t\tconst css: CSSProperties = {\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\tposition: \"relative\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\talignItems: V_ALIGN_CSS[props.vertical ?? VerticalAlign.center],\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t};\n\t\t\tif (bgColor) css.backgroundColor = bgColor;\n\t\t\tconst padAll = props.bulk ? props.all : undefined;\n\t\t\tconst padTop = padAll ?? props.top;\n\t\t\tconst padRight = padAll ?? props.right;\n\t\t\tconst padBottom = padAll ?? props.bottom;\n\t\t\tconst padLeft = padAll ?? props.left;\n\t\t\tif (padTop) css.paddingTop = dimensionToString(padTop);\n\t\t\tif (padRight) css.paddingRight = dimensionToString(padRight);\n\t\t\tif (padBottom) css.paddingBottom = dimensionToString(padBottom);\n\t\t\tif (padLeft) css.paddingLeft = dimensionToString(padLeft);\n\t\t\treturn css;\n\t\t}, [props, bgColor]);\n\n\t\tconst selectStyle = useMemo((): CSSProperties => {\n\t\t\tconst css: CSSProperties = {\n\t\t\t\tappearance: \"none\",\n\t\t\t\tWebkitAppearance: \"none\",\n\t\t\t\tbackground: \"transparent\",\n\t\t\t\tborder: \"none\",\n\t\t\t\toutline: \"none\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"auto\",\n\t\t\t\tpadding: \"0 20px 0 4px\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\tcursor: isDisabled ? \"default\" : \"pointer\",\n\t\t\t\ttextAlign: H_ALIGN_TEXT[props.horizontal ?? HorizontalAlign.left],\n\t\t\t};\n\t\t\tif (props.fontFamily) css.fontFamily = props.fontFamily;\n\t\t\tif (props.fontSize) css.fontSize = `${toPx.fromDim(props.fontSize)}px`;\n\t\t\tif (props.color) css.color = props.color;\n\t\t\tcss.fontWeight = props.fontWeight ? \"bold\" : \"normal\";\n\t\t\tcss.fontStyle = props.italic ? \"italic\" : \"normal\";\n\t\t\tconst dec: string[] = [];\n\t\t\tif (props.underline) dec.push(\"underline\");\n\t\t\tif (props.lineThrough) dec.push(\"line-through\");\n\t\t\tif (dec.length > 0) css.textDecoration = dec.join(\" \");\n\t\t\treturn css;\n\t\t}, [props, isDisabled]);\n\n\t\tconst arrowStyle: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tright: 6,\n\t\t\ttop: \"50%\",\n\t\t\ttransform: \"translateY(-50%)\",\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\tborderLeft: \"5px solid transparent\",\n\t\t\tborderRight: \"5px solid transparent\",\n\t\t\tborderTop: `5px solid ${isDisabled ? \"#aaa\" : \"#555\"}`,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\tconst handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n\t\t\tconst newValue = e.target.value === \"\" ? null : e.target.value;\n\t\t\tonChange(newValue);\n\t\t};\n\n\t\t// パディング領域などのコンテナ空白部分をクリックしたときもドロップダウンを開く\n\t\tconst handleContainerClick = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\t\tif (!isDisabled && e.target !== selectRef.current) {\n\t\t\t\tselectRef.current?.showPicker?.();\n\t\t\t}\n\t\t};\n\n\t\tconst handleContainerKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\tif (!isDisabled && (e.key === \"Enter\" || e.key === \" \")) {\n\t\t\t\te.preventDefault();\n\t\t\t\tselectRef.current?.showPicker?.();\n\t\t\t}\n\t\t};\n\n\t\tif (mode === NoteMode.VIEW) {\n\t\t\tconst label =\n\t\t\t\tselectedOption?.label ??\n\t\t\t\t(value != null ? String(value) : (props.placeholder ?? \"\"));\n\t\t\tconst viewStyle: CSSProperties = {\n\t\t\t\t...selectStyle,\n\t\t\t\theight: \"auto\",\n\t\t\t\tpadding: \"0 4px\",\n\t\t\t};\n\t\t\treturn (\n\t\t\t\t<div style={containerStyle}>\n\t\t\t\t\t<div style={viewStyle}>{label}</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tconst resolveOptionBackground = (color?: string): string | undefined => {\n\t\t\tif (color && isValidCssColor(color)) return color;\n\t\t\treturn blockBackgroundColor;\n\t\t};\n\n\t\t// <label> ラッパーは使わず、コンテナ onClick + showPicker でパディング領域のクリックも対応する\n\t\tconst inner = (\n\t\t\t<>\n\t\t\t\t<select\n\t\t\t\t\tref={selectRef}\n\t\t\t\t\tid={id}\n\t\t\t\t\tvalue={value ?? \"\"}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\tstyle={selectStyle}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t>\n\t\t\t\t\t{props.placeholder !== undefined &&\n\t\t\t\t\t\t!props.required &&\n\t\t\t\t\t\tprops.selectConfig?.allowEmpty !== false && (\n\t\t\t\t\t\t\t<option\n\t\t\t\t\t\t\t\tvalue=\"\"\n\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\tblockBackgroundColor\n\t\t\t\t\t\t\t\t\t\t? { backgroundColor: blockBackgroundColor }\n\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{props.placeholder}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t)}\n\t\t\t\t\t{(props.selectConfig?.options ?? []).map((opt) => {\n\t\t\t\t\t\tconst optBg = resolveOptionBackground(opt.color);\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<option\n\t\t\t\t\t\t\t\tkey={opt.value}\n\t\t\t\t\t\t\t\tvalue={opt.value}\n\t\t\t\t\t\t\t\tstyle={optBg ? { backgroundColor: optBg } : undefined}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{opt.label}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</select>\n\t\t\t\t<div style={arrowStyle} aria-hidden=\"true\" />\n\t\t\t</>\n\t\t);\n\n\t\tif (isDisabled) {\n\t\t\treturn <div style={containerStyle}>{inner}</div>;\n\t\t}\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={containerStyle}\n\t\t\t\trole=\"none\"\n\t\t\t\tonClick={handleContainerClick}\n\t\t\t\tonKeyDown={handleContainerKeyDown}\n\t\t\t>\n\t\t\t\t{inner}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nSelectRenderer.displayName = \"SelectRenderer\";\n","import {\n\talignmentProp,\n\tfontStyleProp,\n\tpaddingProp,\n\tplaceholderProp,\n\trequiredProp,\n} from \"../../../plugin\";\nimport { selectConfigProp } from \"./props\";\nimport { SelectRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin\";\nimport type { SelectOptionsConfig } from \"./props\";\nimport type { SelectBlockProps, SelectBlockValue } from \"./types\";\n\n/**\n * セレクトボックスブロックのプラグイン定義。\n *\n * `kind: \"select\"` で登録され、選択肢設定・必須入力・フォントなどの prop まとまりを提供する。\n */\nexport const SelectPlugin: BlockPlugin<SelectBlockProps, SelectBlockValue> = {\n\tkind: \"select\",\n\n\tmeta: {\n\t\tdisplayName: \"セレクトボックス\",\n\t\tdescription: \"ドロップダウンから選択肢を選ぶ入力ブロック\",\n\t\tdefaultSize: { w: 4, h: 2 },\n\t},\n\n\tRenderer: SelectRenderer,\n\n\tproperties: [\n\t\talignmentProp,\n\t\tpaddingProp,\n\t\tfontStyleProp,\n\t\tplaceholderProp,\n\t\trequiredProp,\n\t\tselectConfigProp,\n\t],\n\n\tvalidateProps: (props: unknown): SelectBlockProps => {\n\t\tif (typeof props !== \"object\" || props === null) {\n\t\t\treturn {} as SelectBlockProps;\n\t\t}\n\n\t\tconst p = props as Record<string, unknown>;\n\n\t\t// selectConfig.options の各要素が { label: string, value: string } であることを確認\n\t\tconst rawCfg = p.selectConfig;\n\t\tconst isValidSelectConfig =\n\t\t\ttypeof rawCfg === \"object\" &&\n\t\t\trawCfg !== null &&\n\t\t\tArray.isArray((rawCfg as Record<string, unknown>).options) &&\n\t\t\t((rawCfg as Record<string, unknown>).options as unknown[]).every(\n\t\t\t\t(opt: unknown) =>\n\t\t\t\t\ttypeof opt === \"object\" &&\n\t\t\t\t\topt !== null &&\n\t\t\t\t\ttypeof (opt as Record<string, unknown>).label === \"string\" &&\n\t\t\t\t\ttypeof (opt as Record<string, unknown>).value === \"string\",\n\t\t\t);\n\n\t\tif (isValidSelectConfig) {\n\t\t\treturn {\n\t\t\t\t...p,\n\t\t\t\tselectConfig: rawCfg as SelectOptionsConfig,\n\t\t\t} as SelectBlockProps;\n\t\t}\n\n\t\tconst { selectConfig: _ignored, ...rest } = p;\n\t\treturn { ...rest, selectConfig: { options: [] } } as SelectBlockProps;\n\t},\n\n\tvalidateValue: (value: unknown): SelectBlockValue => {\n\t\tif (typeof value === \"string\") return value;\n\t\treturn null;\n\t},\n};\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tuseCallback,\n\tuseImperativeHandle,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\n\nimport {\n\tHorizontalAlign,\n\tVerticalAlign,\n} from \"../../../plugin/properties/alignment\";\nimport { NoteMode } from \"../../../types\";\nimport { dimensionToString, toPx } from \"../../../utils\";\n\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { TextBlockProps, TextBlockValue } from \"./types\";\n\n// HorizontalAlign → CSS justifyContent のマッピングテーブル\nconst H_ALIGN_CSS: Record<HorizontalAlign, CSSProperties[\"justifyContent\"]> = {\n\t[HorizontalAlign.left]: \"flex-start\",\n\t[HorizontalAlign.center]: \"center\",\n\t[HorizontalAlign.right]: \"flex-end\",\n};\n\n// VerticalAlign → CSS alignItems のマッピングテーブル\nconst V_ALIGN_CSS: Record<VerticalAlign, CSSProperties[\"alignItems\"]> = {\n\t[VerticalAlign.top]: \"flex-start\",\n\t[VerticalAlign.center]: \"center\",\n\t[VerticalAlign.bottom]: \"flex-end\",\n};\n\n/**\n * テキストブロックのレンダラーコンポーネント。\n *\n * `multiline` prop に応じて `<input>` と `<textarea>` を切り替える。\n *\n * `onMeasureHeight` / `onMeasureWidth` を通じてコンテンツ高さ・幅を外部に通知する。\n */\nexport const TextRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<TextBlockProps, TextBlockValue>\n>(\n\t(\n\t\t{\n\t\t\tprops,\n\t\t\tvalue,\n\t\t\tonChange,\n\t\t\tonBlur,\n\t\t\treadOnly,\n\t\t\tmode,\n\t\t\tonMeasureHeight,\n\t\t\tonMeasureWidth,\n\t\t\tariaLabel,\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\tconst ghostRef = useRef<HTMLDivElement>(null);\n\t\tconst widthSpanRef = useRef<HTMLSpanElement>(null);\n\n\t\tconst [textareaHeight, setTextareaHeight] = useState<number | null>(null);\n\t\tconst lastReportedHeight = useRef<number | null>(null);\n\t\tconst lastReportedWidth = useRef<number | null>(null);\n\n\t\t// value が number など非 string 型で渡された場合の防御的変換\n\t\tconst safeValue = value != null ? String(value) : \"\";\n\n\t\t// multiline: ゴースト要素でコンテンツ高さを計測する\n\t\t// 縦方向配置はコンテナのflexbox (alignItems) に委ねる\n\t\tuseLayoutEffect(() => {\n\t\t\tif (!props.multiline) return;\n\n\t\t\tconst ghost = ghostRef.current;\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!ghost || !container) return;\n\n\t\t\t// ghost の textContent を直接セット(safeValue を effect 内で使うことで正当な依存にする)\n\t\t\tconst displayValue = safeValue + (safeValue.endsWith(\"\\n\") ? \" \" : \"\");\n\t\t\tghost.textContent = displayValue || \"\\u00a0\";\n\n\t\t\tconst cs = window.getComputedStyle(container);\n\t\t\tconst paddingTop = Number.parseFloat(cs.paddingTop);\n\t\t\tconst paddingBottom = Number.parseFloat(cs.paddingBottom);\n\t\t\tconst paddingLeft = Number.parseFloat(cs.paddingLeft);\n\t\t\tconst paddingRight = Number.parseFloat(cs.paddingRight);\n\n\t\t\tconst availableWidth = container.clientWidth - paddingLeft - paddingRight;\n\n\t\t\tghost.style.width = `${availableWidth}px`;\n\t\t\tghost.style.paddingTop = \"0px\";\n\t\t\tghost.style.paddingBottom = \"0px\";\n\n\t\t\tconst contentHeight = ghost.scrollHeight;\n\t\t\t// テキストエリアはコンテンツの自然な高さに設定(スクロールバーが出ない最小値)\n\t\t\tsetTextareaHeight(contentHeight);\n\n\t\t\tif (onMeasureHeight) {\n\t\t\t\tconst neededHeight = contentHeight + paddingTop + paddingBottom;\n\t\t\t\tif (neededHeight !== lastReportedHeight.current) {\n\t\t\t\t\tlastReportedHeight.current = neededHeight;\n\t\t\t\t\tonMeasureHeight(neededHeight);\n\t\t\t\t}\n\t\t\t}\n\t\t}, [props, safeValue, onMeasureHeight]);\n\n\t\t// 幅計測: hidden span で実際のテキスト幅を計測(scrollWidth は循環依存があるため不使用)\n\t\tuseLayoutEffect(() => {\n\t\t\tif (!onMeasureWidth) return;\n\t\t\tconst span = widthSpanRef.current;\n\t\t\tif (!span) return;\n\t\t\tspan.textContent = safeValue;\n\t\t\tconst w = span.offsetWidth + 2; // +2 for cursor/border safety\n\t\t\tif (w !== lastReportedWidth.current) {\n\t\t\t\tlastReportedWidth.current = w;\n\t\t\t\tonMeasureWidth(w);\n\t\t\t}\n\t\t}, [safeValue, onMeasureWidth]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({ focus: () => inputRef.current?.focus() }),\n\t\t\t[],\n\t\t);\n\n\t\tconst isEditable = !readOnly;\n\n\t\tconst containerStyle = useMemo((): CSSProperties => {\n\t\t\tconst css: CSSProperties = {\n\t\t\t\tposition: \"relative\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t\tcursor: isEditable ? \"text\" : \"default\",\n\t\t\t};\n\t\t\tcss.justifyContent =\n\t\t\t\tH_ALIGN_CSS[props.horizontal ?? HorizontalAlign.left];\n\t\t\tcss.alignItems = V_ALIGN_CSS[props.vertical ?? VerticalAlign.center];\n\t\t\tconst padAll = props.bulk ? props.all : undefined;\n\t\t\tconst padTop = padAll ?? props.top;\n\t\t\tconst padRight = padAll ?? props.right;\n\t\t\tconst padBottom = padAll ?? props.bottom;\n\t\t\tconst padLeft = padAll ?? props.left;\n\t\t\tif (padTop) css.paddingTop = dimensionToString(padTop);\n\t\t\tif (padRight) css.paddingRight = dimensionToString(padRight);\n\t\t\tif (padBottom) css.paddingBottom = dimensionToString(padBottom);\n\t\t\tif (padLeft) css.paddingLeft = dimensionToString(padLeft);\n\t\t\treturn css;\n\t\t}, [props, isEditable]);\n\n\t\tconst inputStyle = useMemo((): CSSProperties => {\n\t\t\tconst css: CSSProperties = {\n\t\t\t\tbackground: \"transparent\",\n\t\t\t\tborder: \"none\",\n\t\t\t\toutline: \"none\",\n\t\t\t\tresize: \"none\",\n\t\t\t\tpadding: 0,\n\t\t\t\tmargin: 0,\n\t\t\t\twidth: \"100%\",\n\t\t\t\twhiteSpace: onMeasureWidth\n\t\t\t\t\t? props.multiline\n\t\t\t\t\t\t? \"pre\"\n\t\t\t\t\t\t: \"nowrap\"\n\t\t\t\t\t: undefined,\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\tcolor: \"inherit\",\n\t\t\t};\n\t\t\tif (props.fontSize) css.fontSize = `${toPx.fromDim(props.fontSize)}px`;\n\t\t\tif (props.fontFamily) css.fontFamily = props.fontFamily;\n\t\t\tif (props.color) css.color = props.color;\n\t\t\tcss.fontWeight = props.fontWeight ? \"bold\" : \"normal\";\n\t\t\tcss.fontStyle = props.italic ? \"italic\" : \"normal\";\n\t\t\tconst dec: string[] = [];\n\t\t\tif (props.underline) dec.push(\"underline\");\n\t\t\tif (props.lineThrough) dec.push(\"line-through\");\n\t\t\tcss.textDecoration = dec.length > 0 ? dec.join(\" \") : \"none\";\n\t\t\tif (props.lineHeight) css.lineHeight = props.lineHeight;\n\t\t\tswitch (props.horizontal) {\n\t\t\t\tcase HorizontalAlign.center:\n\t\t\t\t\tcss.textAlign = \"center\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase HorizontalAlign.right:\n\t\t\t\t\tcss.textAlign = \"right\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tcss.textAlign = \"left\";\n\t\t\t}\n\t\t\treturn css;\n\t\t}, [props, onMeasureWidth]);\n\n\t\tconst widthSpanStyle = useMemo(\n\t\t\t(): CSSProperties => ({\n\t\t\t\t...inputStyle,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tvisibility: \"hidden\",\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t\twhiteSpace: \"pre\",\n\t\t\t\twidth: \"auto\",\n\t\t\t\theight: \"auto\",\n\t\t\t\toverflow: \"visible\",\n\t\t\t}),\n\t\t\t[inputStyle],\n\t\t);\n\n\t\tconst ghostStyle = useMemo((): CSSProperties => {\n\t\t\tconst noWrap = !!onMeasureWidth;\n\t\t\treturn {\n\t\t\t\t...inputStyle,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"auto\",\n\t\t\t\tvisibility: \"hidden\",\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t\twhiteSpace: noWrap ? \"pre\" : \"pre-wrap\",\n\t\t\t\twordWrap: noWrap ? \"normal\" : \"break-word\",\n\t\t\t\toverflowWrap: noWrap ? \"normal\" : \"break-word\",\n\t\t\t\tpadding: 0,\n\t\t\t\tborder: \"none\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t};\n\t\t}, [inputStyle, onMeasureWidth]);\n\n\t\tconst handleChange = (\n\t\t\te: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,\n\t\t) => {\n\t\t\tonChange(e.target.value);\n\t\t};\n\n\t\tconst handleBlur = () => {\n\t\t\tonBlur?.(value);\n\t\t};\n\n\t\t// パターンが ^[...]+$ 形式なら1文字単位のフィルタ正規表現を導出する\n\t\t// 例: \"[0-9]+\" → /^[0-9]$/ \"[ぁ-ん]+\" → /^[ぁ-ん]$/\n\t\t// \"[0-9]{3}-[0-9]{4}\" のような複合パターンはフィルタなし(自由入力)\n\t\tconst charFilterRegex = useMemo((): RegExp | null => {\n\t\t\tif (!props.pattern) return null;\n\t\t\tconst m = props.pattern.match(/^(\\[.+?\\])\\+$/);\n\t\t\tif (!m) return null;\n\t\t\ttry {\n\t\t\t\treturn new RegExp(`^${m[1]}$`);\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}, [props.pattern]);\n\n\t\t// inputTypeとパターンから適切な inputMode を導出\n\t\tconst resolvedInputMode = useMemo(() => {\n\t\t\tif (props.inputType === \"number\") return \"numeric\";\n\t\t\tif (props.inputType === \"tel\") return \"tel\";\n\t\t\tif (props.inputType === \"email\") return \"email\";\n\t\t\tif (props.inputType === \"url\") return \"url\";\n\t\t\tif (props.pattern === \"[0-9]+\") return \"numeric\";\n\t\t\treturn \"text\";\n\t\t}, [props.inputType, props.pattern]);\n\n\t\t// 文字フィルタが定義されている場合:1文字ずつ検証し、不許可文字を遮断\n\t\tconst handleBeforeInput = useCallback(\n\t\t\t(e: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n\t\t\t\tif (!charFilterRegex) return;\n\t\t\t\tconst nativeEvent = e.nativeEvent as InputEvent;\n\t\t\t\tif (nativeEvent.data) {\n\t\t\t\t\tfor (const char of nativeEvent.data) {\n\t\t\t\t\t\tif (!charFilterRegex.test(char)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t[charFilterRegex],\n\t\t);\n\n\t\t// IME確定後に許可外文字が混入した場合も除去\n\t\tconst handleCompositionEnd = useCallback(\n\t\t\t(e: React.CompositionEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n\t\t\t\tif (!charFilterRegex) return;\n\t\t\t\tconst el = e.currentTarget;\n\t\t\t\tconst filtered = [...el.value]\n\t\t\t\t\t.filter((c) => charFilterRegex.test(c))\n\t\t\t\t\t.join(\"\");\n\t\t\t\tif (filtered !== el.value) {\n\t\t\t\t\tonChange(filtered);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[charFilterRegex, onChange],\n\t\t);\n\n\t\tconst shouldShowPlaceholder =\n\t\t\tmode === NoteMode.EDIT || mode === NoteMode.FORM;\n\t\tconst placeholder = shouldShowPlaceholder ? props.placeholder : undefined;\n\n\t\tconst handleContainerClick = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\t\t// コンテナ上の余白クリック時でも input/textarea にフォーカスを移す\n\t\t\tif (isEditable && e.target === e.currentTarget) {\n\t\t\t\tinputRef.current?.focus();\n\t\t\t}\n\t\t};\n\n\t\tif (props.multiline) {\n\t\t\tconst textareaStyle: CSSProperties = {\n\t\t\t\t...inputStyle,\n\t\t\t\tresize: \"none\",\n\t\t\t\toverflow: onMeasureWidth\n\t\t\t\t\t? \"hidden\"\n\t\t\t\t\t: mode === NoteMode.VIEW\n\t\t\t\t\t\t? \"hidden\"\n\t\t\t\t\t\t: \"auto\",\n\t\t\t\t// ゴースト計測済みの場合はコンテンツ高さを使用\n\t\t\t\t// これにより flexbox の alignItems で垂直方向の配置が機能する\n\t\t\t\theight: textareaHeight !== null ? `${textareaHeight}px` : \"auto\",\n\t\t\t};\n\n\t\t\tconst setTextareaRefs = (el: HTMLTextAreaElement | null) => {\n\t\t\t\tinputRef.current = el;\n\t\t\t};\n\n\t\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\tref={containerRef}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t\trole=\"none\"\n\t\t\t\t\tonClick={handleContainerClick}\n\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\tif (isEditable && (e.key === \"Enter\" || e.key === \" \"))\n\t\t\t\t\t\t\tinputRef.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<div ref={ghostRef} style={ghostStyle} aria-hidden=\"true\" />\n\t\t\t\t\t<textarea\n\t\t\t\t\t\tref={setTextareaRefs}\n\t\t\t\t\t\tvalue={safeValue}\n\t\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\t\tonBlur={handleBlur}\n\t\t\t\t\t\tonBeforeInput={handleBeforeInput}\n\t\t\t\t\t\tonCompositionEnd={handleCompositionEnd}\n\t\t\t\t\t\tinputMode={resolvedInputMode}\n\t\t\t\t\t\tstyle={textareaStyle}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\treadOnly={!isEditable}\n\t\t\t\t\t\ttabIndex={isEditable ? 0 : -1}\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t/>\n\t\t\t\t\t{onMeasureWidth && (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tref={widthSpanRef}\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tstyle={widthSpanStyle}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={containerStyle}\n\t\t\t\trole=\"none\"\n\t\t\t\tonClick={handleContainerClick}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (isEditable && (e.key === \"Enter\" || e.key === \" \"))\n\t\t\t\t\t\tinputRef.current?.focus();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tref={inputRef as React.RefObject<HTMLInputElement>}\n\t\t\t\t\ttype={props.inputType ?? \"text\"}\n\t\t\t\t\tvalue={safeValue}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tonBlur={handleBlur}\n\t\t\t\t\tonBeforeInput={handleBeforeInput}\n\t\t\t\t\tonCompositionEnd={handleCompositionEnd}\n\t\t\t\t\tinputMode={resolvedInputMode}\n\t\t\t\t\tstyle={inputStyle}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\treadOnly={!isEditable}\n\t\t\t\t\ttabIndex={isEditable ? 0 : -1}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\tmin={props.min}\n\t\t\t\t\tmax={props.max}\n\t\t\t\t\tstep={props.step}\n\t\t\t\t/>\n\t\t\t\t{onMeasureWidth && (\n\t\t\t\t\t<span ref={widthSpanRef} aria-hidden=\"true\" style={widthSpanStyle} />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nTextRenderer.displayName = \"TextRenderer\";\n","import {\n\talignmentProp,\n\tfontStyleProp,\n\tpaddingProp,\n\tplaceholderProp,\n\trequiredProp,\n} from \"../../../plugin\";\nimport { textBehaviorProp, textValidationProp } from \"./props\";\nimport { TextRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin\";\nimport type { TextBlockProps, TextBlockValue } from \"./types\";\n\n/**\n * テキスト入力ブロックのプラグイン定義。\n *\n * `kind: \"text\"` で登録され、フォント・バリデーション・改行・必須入力などの prop まとまりを提供する。\n */\nexport const TextPlugin: BlockPlugin<TextBlockProps, TextBlockValue> = {\n\tkind: \"text\",\n\n\tmeta: {\n\t\tdisplayName: \"テキスト\",\n\t\tdescription: \"テキスト入力用ブロック\",\n\t\tdefaultSize: { w: 3, h: 1 },\n\t},\n\n\tRenderer: TextRenderer,\n\n\tproperties: [\n\t\talignmentProp,\n\t\tpaddingProp,\n\t\tfontStyleProp,\n\t\tplaceholderProp,\n\t\trequiredProp,\n\t\ttextBehaviorProp,\n\t\ttextValidationProp,\n\t],\n\n\tvalidateProps: (props: unknown): TextBlockProps => {\n\t\tconst p = (\n\t\t\ttypeof props === \"object\" && props !== null ? props : {}\n\t\t) as Record<string, unknown>;\n\t\tconst patched: Record<string, unknown> = { ...p };\n\t\tif (typeof patched.minLength !== \"number\") patched.minLength = undefined;\n\t\tif (typeof patched.maxLength !== \"number\") patched.maxLength = undefined;\n\t\tif (typeof patched.pattern !== \"string\") patched.pattern = undefined;\n\t\tconst validInputTypes = [\n\t\t\t\"text\",\n\t\t\t\"number\",\n\t\t\t\"email\",\n\t\t\t\"tel\",\n\t\t\t\"url\",\n\t\t\t\"date\",\n\t\t\t\"password\",\n\t\t];\n\t\tif (!validInputTypes.includes(patched.inputType as string)) {\n\t\t\tpatched.inputType = undefined;\n\t\t}\n\t\tfor (const key of [\"min\", \"max\", \"step\"] as const) {\n\t\t\tif (key in patched && typeof patched[key] !== \"number\") {\n\t\t\t\tpatched[key] = undefined;\n\t\t\t}\n\t\t}\n\t\treturn patched as TextBlockProps;\n\t},\n\n\tvalidateValue: (value: unknown): TextBlockValue | undefined => {\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value === \"number\") return String(value);\n\t\treturn undefined;\n\t},\n};\n","import { useCallback, useMemo, useRef } from \"react\";\n\nimport type { ActionContext, BuiltinActionId } from \"../../types/context\";\n\n/**\n * 個別アクションのハンドラ定義。\n *\n * @internal\n */\ntype ActionHandler = {\n\texecute: (payload?: unknown) => void;\n\tisEnabled: () => boolean;\n\tvalidatePayload?: (payload: unknown) => boolean;\n};\n\n/**\n * アクション ID をキーとしたハンドラマップ。\n *\n * `useBookActionContext` に渡すことで {@link ActionContext} として組み立てられる。\n */\nexport type ActionHandlers = {\n\t[K in BuiltinActionId]?: ActionHandler;\n} & {\n\t[actionId: string]: ActionHandler | undefined;\n};\n\n/**\n * `ActionHandlers` から {@link ActionContext} を組み立てるフック。\n *\n * @remarks\n * **Canvas** — 通常は {@link useNoteContext} 経由で利用してください。\n *\n * 直接使用する場合はアクションの有効/無効判定を自前で実装する必要があります。\n */\nexport function useBookActionContext(handlers: ActionHandlers): ActionContext {\n\tconst handlersRef = useRef(handlers);\n\thandlersRef.current = handlers;\n\n\tconst execute = useCallback((actionId: string, payload?: unknown): void => {\n\t\tconst handler = handlersRef.current[actionId];\n\t\tif (!handler) return;\n\t\tif (\n\t\t\tpayload !== undefined &&\n\t\t\thandler.validatePayload !== undefined &&\n\t\t\t!handler.validatePayload(payload)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\thandler.execute(payload);\n\t}, []);\n\n\tconst isEnabled = useCallback((actionId: string): boolean => {\n\t\treturn handlersRef.current[actionId]?.isEnabled() ?? false;\n\t}, []);\n\n\treturn useMemo(() => ({ execute, isEnabled }), [execute, isEnabled]);\n}\n","import { useCallback, useMemo, useRef } from \"react\";\n\nimport { bindingKey } from \"../history/mergeKeys\";\n\nimport type { OnBookChange } from \"../../types/callbacks\";\nimport type { BindingContext } from \"../../types/context\";\nimport type { Book } from \"../../types/schema\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * ネストしたオブジェクトの指定キーパスに値をセットした新しいオブジェクトを返す。\n *\n * `keys` が空の場合は `value` をそのまま返す。途中のキーが存在しない場合は空オブジェクトとして扱う。\n */\nexport function setNested(obj: unknown, keys: string[], value: Value): unknown {\n\tif (keys.length === 0) return value;\n\tconst [head, ...tail] = keys as [string, ...string[]];\n\tconst current = (\n\t\ttypeof obj === \"object\" && obj !== null ? obj : {}\n\t) as Record<string, unknown>;\n\treturn {\n\t\t...current,\n\t\t[head]: setNested(current[head], tail, value),\n\t};\n}\n\n/**\n * `Book` のドットパス位置に値をセットした新しい `Book` を返す。\n */\nexport function setPath(obj: Book, path: string, value: Value): Book {\n\tconst keys = path.split(\".\");\n\treturn setNested(obj, keys, value) as Book;\n}\n\n/**\n * オブジェクトのドットパスを再帰的にたどり、値を返す。\n *\n * 途中のキーが `null` またはオブジェクト以外の場合は `null` を返す。\n */\nexport function resolvePath(obj: unknown, path: string): Value {\n\tconst keys = path.split(\".\");\n\tlet current: unknown = obj;\n\tfor (const key of keys) {\n\t\tif (current === null || typeof current !== \"object\") return null;\n\t\tcurrent = (current as Record<string, unknown>)[key];\n\t}\n\treturn (current as Value) ?? null;\n}\n\n/**\n * {@link useBookBindingContext} のオプション。\n */\nexport interface BookBindingContextOptions {\n\t/**\n\t * `grid.*` パスの解決対象ページインデックス。デフォルト: 0。\n\t */\n\tpageIdx?: number;\n\n\t/**\n\t * ユーザー定義の追加 BindingContext。\n\t * 組み込みパスより優先して参照される。\n\t * `get` が `undefined` を返した場合 / `set` が処理しなかった場合は組み込みにフォールバックする。\n\t * 注意: `set` のフォールバック判定は `extra.get(path)` が `undefined` かどうかを基準にする。\n\t */\n\textra?: BindingContext;\n}\n\n/**\n * book 全体の読み書きを担う BindingContext を生成するフック。\n *\n * @remarks\n * **Canvas** — 通常は {@link useNoteContext} 経由で自動生成される。\n *\n * 直接呼ぶのは独自の BindingContext レイヤーを構築する場合のみとすること。\n *\n * 以下のパス名前空間を組み込みで処理する:\n * - `paper.*` — `book.paper.*` に対応\n * - `margin.*` — `book.paper.margin.*` に対応(`margin.bulk` / `margin.all.*` も通常パスとして解決)\n * - `grid.*` — `book.pages[pageIdx].grid.*` に対応(`options.pageIdx` で制御)\n * - 上記以外 — `book` のルートから直接解決(後方互換)\n *\n * @example\n * ```tsx\n * const bindingContext = useBookBindingContext(book, onBookChange, { pageIdx });\n *\n * // 全ての widget に同じ bindingContext を渡すだけ\n * <FloatingWidget bindingContext={bindingContext} ... />\n * ```\n */\nexport function useBookBindingContext(\n\tbook: Book,\n\tonBookChange: OnBookChange,\n\toptions?: BookBindingContextOptions,\n): BindingContext {\n\tconst bookRef = useRef(book);\n\tbookRef.current = book;\n\tconst pageIdxRef = useRef(options?.pageIdx ?? 0);\n\tpageIdxRef.current = options?.pageIdx ?? 0;\n\tconst extraRef = useRef(options?.extra);\n\textraRef.current = options?.extra;\n\tconst get = useCallback((path: string): Value => {\n\t\t// extra を先に試みる\n\t\tconst extra = extraRef.current;\n\t\tif (extra) {\n\t\t\tconst v = extra.get(path);\n\t\t\tif (v !== undefined) return v;\n\t\t}\n\n\t\tconst b = bookRef.current;\n\n\t\t// margin.* → paper.margin.*\n\t\tif (path.startsWith(\"margin.\")) {\n\t\t\treturn resolvePath(b.paper.margin, path.slice(7));\n\t\t}\n\n\t\t// grid.* → pages[pageIdx].grid.*\n\t\tif (path.startsWith(\"grid.\")) {\n\t\t\treturn resolvePath(b.pages[pageIdxRef.current]?.grid, path.slice(5));\n\t\t}\n\n\t\t// それ以外はルートから直接解決(paper.* を含む)\n\t\treturn resolvePath(b, path);\n\t}, []);\n\n\tconst set = useCallback(\n\t\t(path: string, value: Value): void => {\n\t\t\t// extra を先に試みる(extra が処理するパスかどうかは get で判定)\n\t\t\tconst extra = extraRef.current;\n\t\t\tif (extra) {\n\t\t\t\tconst v = extra.get(path);\n\t\t\t\tif (v !== undefined) {\n\t\t\t\t\textra.set(path, value);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst b = bookRef.current;\n\n\t\t\t// margin.* → paper.margin.* (純粋エイリアス)\n\t\t\tif (path.startsWith(\"margin.\")) {\n\t\t\t\t// margin.bulk が true に切り替わるとき、margin.all が未設定なら margin.top で初期化する\n\t\t\t\t// (unit なしの中間状態を防ぐ)\n\t\t\t\tif (path === \"margin.bulk\" && value === true) {\n\t\t\t\t\tconst margin = b.paper.margin;\n\t\t\t\t\tconst all = margin.all?.unit ? margin.all : margin.top;\n\t\t\t\t\tonBookChange(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...b,\n\t\t\t\t\t\t\tpaper: { ...b.paper, margin: { ...margin, bulk: true, all } },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ mergeKey: bindingKey(path) },\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst subKey = path.slice(7);\n\t\t\t\tconst newMargin = setNested(\n\t\t\t\t\tb.paper.margin,\n\t\t\t\t\tsubKey.split(\".\"),\n\t\t\t\t\tvalue,\n\t\t\t\t) as typeof b.paper.margin;\n\t\t\t\tonBookChange(\n\t\t\t\t\t{ ...b, paper: { ...b.paper, margin: newMargin } },\n\t\t\t\t\t{ mergeKey: bindingKey(path) },\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// grid.* → pages[pageIdx].grid.*\n\t\t\tif (path.startsWith(\"grid.\")) {\n\t\t\t\tconst pi = pageIdxRef.current;\n\t\t\t\tconst page = b.pages[pi];\n\t\t\t\tif (!page) return;\n\t\t\t\tconst newGrid = setNested(page.grid, path.slice(5).split(\".\"), value);\n\t\t\t\tconst newPages = b.pages.map((p, i) =>\n\t\t\t\t\ti === pi ? { ...p, grid: newGrid } : p,\n\t\t\t\t);\n\t\t\t\tonBookChange(\n\t\t\t\t\t{ ...b, pages: newPages as typeof b.pages },\n\t\t\t\t\t{ mergeKey: bindingKey(path) },\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// それ以外はルートから直接更新(paper.* を含む)\n\t\t\tonBookChange(setPath(b, path, value), { mergeKey: bindingKey(path) });\n\t\t},\n\t\t[onBookChange],\n\t);\n\n\treturn useMemo(() => ({ get, set }), [get, set]);\n}\n","import { useCallback, useReducer } from \"react\";\n\nimport type { Book } from \"../../types/schema\";\nimport type { ActionHandlers } from \"../action/useBookActionContext\";\n\nconst MERGE_WINDOW_MS = 500;\n\n// 履歴の1エントリ(Book + mergeKey + タイムスタンプ)\ninterface HistoryEntry {\n\tbook: Book;\n\tmergeKey?: string;\n\ttimestamp: number;\n}\n\n// 履歴全体の状態(エントリ配列 + 現在インデックス)\ninterface HistState {\n\tentries: HistoryEntry[];\n\tidx: number;\n}\n\n// 履歴 reducer のアクション型\ntype HistAction =\n\t| {\n\t\t\ttype: \"push\";\n\t\t\tbook: Book;\n\t\t\tmergeKey?: string;\n\t\t\t/** true のとき 500ms 時間窓を無視してマージする(セッション型 mergeKey 専用)。 */\n\t\t\tnoTimeWindow?: boolean;\n\t\t\ttimestamp: number;\n\t\t\tmaxHistory: number;\n\t }\n\t| { type: \"undo\" }\n\t| { type: \"redo\" };\n\n// 履歴の追加・戹除(Undo/Redo)を処理する純粋な reducer\nfunction histReducer(state: HistState, action: HistAction): HistState {\n\tswitch (action.type) {\n\t\tcase \"push\": {\n\t\t\tconst last = state.entries[state.idx];\n\t\t\tconst shouldMerge =\n\t\t\t\taction.mergeKey !== undefined &&\n\t\t\t\tlast?.mergeKey === action.mergeKey &&\n\t\t\t\t(action.noTimeWindow === true ||\n\t\t\t\t\taction.timestamp - (last?.timestamp ?? 0) < MERGE_WINDOW_MS);\n\n\t\t\tif (shouldMerge) {\n\t\t\t\treturn {\n\t\t\t\t\tentries: [\n\t\t\t\t\t\t...state.entries.slice(0, state.idx),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbook: action.book,\n\t\t\t\t\t\t\tmergeKey: action.mergeKey,\n\t\t\t\t\t\t\ttimestamp: action.timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tidx: state.idx,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst newEntries = [\n\t\t\t\t...state.entries.slice(0, state.idx + 1),\n\t\t\t\t{\n\t\t\t\t\tbook: action.book,\n\t\t\t\t\tmergeKey: action.mergeKey,\n\t\t\t\t\ttimestamp: action.timestamp,\n\t\t\t\t},\n\t\t\t];\n\t\t\tconst trimmed =\n\t\t\t\tnewEntries.length > action.maxHistory\n\t\t\t\t\t? newEntries.slice(newEntries.length - action.maxHistory)\n\t\t\t\t\t: newEntries;\n\t\t\treturn {\n\t\t\t\tentries: trimmed,\n\t\t\t\tidx: trimmed.length - 1,\n\t\t\t};\n\t\t}\n\t\tcase \"undo\":\n\t\t\treturn { ...state, idx: Math.max(0, state.idx - 1) };\n\t\tcase \"redo\":\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tidx: Math.min(state.entries.length - 1, state.idx + 1),\n\t\t\t};\n\t}\n}\n\nconst DEFAULT_MAX_HISTORY = 100;\n\n/**\n * {@link useBookHistory} のオプション。\n */\nexport interface UseBookHistoryOptions {\n\t/** 履歴の初期 Book。 */\n\tinitialBook: Book;\n\n\t/**\n\t * 保持する最大履歴件数。`null` または省略時は `100` が使われる。\n\t *\n\t * 超過した古いエントリは末尾追加時に先頭から切り捨てられる。\n\t */\n\tmaxHistory?: number | null;\n}\n\n/**\n * {@link useBookHistory} の戻り値。\n */\nexport interface UseBookHistoryResult {\n\t/** 現在の Book(履歴上のカレントポインタ側)。 */\n\tbook: Book;\n\n\t/** Book の変更を履歴に追加するコールバック。`mergeKey` が同じ変更はマージされる(`noTimeWindow: true` で時間窓なし)。 */\n\thandleBookChange: (\n\t\tbook: Book,\n\t\toptions?: { mergeKey?: string; noTimeWindow?: boolean },\n\t) => void;\n\n\t/** Undo 可能かどうか。 */\n\tcanUndo: boolean;\n\n\t/** Redo 可能かどうか。 */\n\tcanRedo: boolean;\n\n\t/** Undo 実行関数。 */\n\tundo: () => void;\n\n\t/** Redo 実行関数。 */\n\tredo: () => void;\n\n\t/** `useBookActionContext` にそのまま渡せる undo/redo の ActionHandlers。 */\n\thistoryActionHandlers: ActionHandlers;\n}\n\n/**\n * `useReducer` ベースの Undo/Redo 履歴管理フック。\n *\n * 同じ `mergeKey` かつ {@link MERGE_WINDOW_MS} ms 以内の変更は履歴エントリをマージする。\n *\n * @remarks\n * **Canvas** — 通常は {@link useNoteContext} から自動利用される。\n *\n * 直接呼ぶのは独自の履歴層を構築する場合のみとすること。\n */\nexport function useBookHistory({\n\tinitialBook,\n\tmaxHistory = DEFAULT_MAX_HISTORY,\n}: UseBookHistoryOptions): UseBookHistoryResult {\n\tconst resolvedMaxHistory = maxHistory ?? DEFAULT_MAX_HISTORY;\n\n\tconst [state, dispatch] = useReducer(histReducer, undefined, () => ({\n\t\tentries: [{ book: initialBook, timestamp: Date.now() }],\n\t\tidx: 0,\n\t}));\n\n\tconst book = state.entries[state.idx]?.book ?? initialBook;\n\n\tconst handleBookChange = useCallback(\n\t\t(\n\t\t\tnewBook: Book,\n\t\t\toptions?: { mergeKey?: string; noTimeWindow?: boolean },\n\t\t) => {\n\t\t\tdispatch({\n\t\t\t\ttype: \"push\",\n\t\t\t\tbook: newBook,\n\t\t\t\tmergeKey: options?.mergeKey,\n\t\t\t\tnoTimeWindow: options?.noTimeWindow,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tmaxHistory: resolvedMaxHistory,\n\t\t\t});\n\t\t},\n\t\t[resolvedMaxHistory],\n\t);\n\n\tconst undo = useCallback(() => dispatch({ type: \"undo\" }), []);\n\tconst redo = useCallback(() => dispatch({ type: \"redo\" }), []);\n\n\treturn {\n\t\tbook,\n\t\thandleBookChange,\n\t\tcanUndo: state.idx > 0,\n\t\tcanRedo: state.idx < state.entries.length - 1,\n\t\tundo,\n\t\tredo,\n\t\thistoryActionHandlers: {\n\t\t\tundo: { execute: undo, isEnabled: () => state.idx > 0 },\n\t\t\tredo: {\n\t\t\t\texecute: redo,\n\t\t\t\tisEnabled: () => state.idx < state.entries.length - 1,\n\t\t\t},\n\t\t},\n\t};\n}\n","// ブロック枠線・ガイド線の SVG 描画ヘルパー\n\nimport { LineType } from \"../../../types/line\";\nimport { toPx } from \"../../../utils/convert\";\n\nimport type { LineStyle } from \"../../../types/line\";\n\n/**\n * 線種とライン幅から SVG の `stroke-dasharray` 値を返します。\n * @param type - 線の種類(実線 / 破線 / 点線)。\n * @param lineWidth - 線幅の数値(単位は px)。\n * @returns DASHED / DOTTED の場合は dasharray 文字列、SOLID の場合は `undefined`。\n */\nexport function getLineDasharray(\n\ttype: LineType,\n\tlineWidth: number,\n): string | undefined {\n\tif (type === LineType.DASHED) return `${lineWidth * 4} ${lineWidth * 2}`;\n\tif (type === LineType.DOTTED) return `${lineWidth * 1} ${lineWidth * 2}`;\n\treturn undefined;\n}\n\n/**\n * `LineStyle` を SVG line 要素の属性オブジェクトに変換します。\n * @param style - ライン設定(色・幅・線種)。\n * @param dpi - DPI 値。幅の単位変換に使用します。\n */\nexport function lineAttrs(style: LineStyle, dpi: number) {\n\treturn {\n\t\tstroke: style.color,\n\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\n\t\tstrokeDasharray: getLineDasharray(style.type, style.width.value),\n\t};\n}\n","import { type FC, memo } from \"react\";\n\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"../../../utils/zIndex\";\nimport { lineAttrs } from \"./borderUtils\";\n\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockSizePx } from \"../types\";\n\n/**\n * `BlockBorder` コンポーネントへの props。\n */\nexport interface BlockBorderProps {\n\t/** ブロックのサイズ(px)。 */\n\tblockSizePx: BlockSizePx;\n\n\t/** ユーザー設定の枠線スタイル。省略時は描画しない。 */\n\tborderStyle?: BorderStyle;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** z-index のサブオフセット(既定値: `BLOCK_SUB_INDEX.BORDER`)。 */\n\tsubZIndex?: number;\n\n\t/** `false` にすると枠線全体を非表示にする(既定値: `true`)。 */\n\tvisible?: boolean;\n\n\t/** DPI 値。線幅の単位変換に使用する(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n}\n\n/**\n * ユーザー設定の枠線を SVG で描画するコンポーネント。\n *\n * 枠線スタイルが未設定、または全辺が空の場合は `null` を返します。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} のブロック枠線描画サブコンポーネント。\n */\nexport const BlockBorder: FC<BlockBorderProps> = memo(\n\t({\n\t\tblockSizePx,\n\t\tborderStyle,\n\t\tblockZIndex,\n\t\tsubZIndex = BLOCK_SUB_INDEX.BORDER,\n\t\tvisible = true,\n\t\tdpi = DEFAULT_DPI,\n\t}) => {\n\t\tif (!visible || !borderStyle) return null;\n\t\tconst { top, right, bottom, left } = borderStyle;\n\t\tif (!top && !right && !bottom && !left) return null;\n\n\t\tconst { width: w, height: h } = blockSizePx;\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\trole=\"presentation\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tinset: 0,\n\t\t\t\t\twidth: `${w}px`,\n\t\t\t\t\theight: `${h}px`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\toverflow: \"visible\",\n\t\t\t\t\tzIndex,\n\t\t\t\t}}\n\t\t\t\twidth={w}\n\t\t\t\theight={h}\n\t\t\t\tdata-testid=\"block-border\"\n\t\t\t>\n\t\t\t\t{top && <line x1={0} y1={0} x2={w} y2={0} {...lineAttrs(top, dpi)} />}\n\t\t\t\t{right && (\n\t\t\t\t\t<line x1={w} y1={0} x2={w} y2={h} {...lineAttrs(right, dpi)} />\n\t\t\t\t)}\n\t\t\t\t{bottom && (\n\t\t\t\t\t<line x1={0} y1={h} x2={w} y2={h} {...lineAttrs(bottom, dpi)} />\n\t\t\t\t)}\n\t\t\t\t{left && <line x1={0} y1={0} x2={0} y2={h} {...lineAttrs(left, dpi)} />}\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nBlockBorder.displayName = \"BlockBorder\";\n","import { type CSSProperties, type FC, memo } from \"react\";\n\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"../../../utils/zIndex\";\n\nimport type { BlockSizePx } from \"../types\";\n\n/**\n * `BlockCanvas` コンポーネントへの props。\n */\nexport interface BlockCanvasProps {\n\t/** ブロックのサイズ(px)。 */\n\tblockSizePx: BlockSizePx;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** z-index のサブオフセット(既定値: `BLOCK_SUB_INDEX.BG`)。 */\n\tsubZIndex?: number;\n\n\t/** 背景色(既定値: `\"transparent\"`)。 */\n\tbackgroundColor?: string;\n}\n\n/**\n * ブロックの背景を描画するコンポーネント。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} のブロック背景描画サブコンポーネント。\n */\nexport const BlockCanvas: FC<BlockCanvasProps> = memo(\n\t({\n\t\tblockSizePx,\n\t\tblockZIndex,\n\t\tsubZIndex = BLOCK_SUB_INDEX.BG,\n\t\tbackgroundColor = \"transparent\",\n\t}) => {\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\n\n\t\tconst style: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tinset: 0,\n\t\t\twidth: `${blockSizePx.width}px`,\n\t\t\theight: `${blockSizePx.height}px`,\n\t\t\tbackgroundColor,\n\t\t\tpointerEvents: \"none\",\n\t\t\tzIndex,\n\t\t};\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={style}\n\t\t\t\trole=\"presentation\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tdata-testid=\"block-canvas\"\n\t\t\t/>\n\t\t);\n\t},\n);\n\nBlockCanvas.displayName = \"BlockCanvas\";\n","import { type FC, memo } from \"react\";\n\nimport { LineType } from \"../../../types/line\";\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"../../../utils/zIndex\";\n\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockSizePx } from \"../types\";\n\n// 線種・ストローク幅から SVG ダッシュパターン文字列を生成するヘルパー\nfunction toDashArray(type: LineType, strokeWidth: number): string | undefined {\n\tif (type === LineType.DASHED) return `${strokeWidth * 3} ${strokeWidth * 2}`;\n\tif (type === LineType.DOTTED) return `${strokeWidth} ${strokeWidth * 2}`;\n\treturn undefined;\n}\n\n/**\n * ユーザー設定枠線が未設定のブロックに適用するデフォルトのガイド枠線スタイル。\n *\n * @remarks\n * **Canvas** — {@link BlockGuideBorder} のデフォルト枠線スタイル。\n */\nexport const DEFAULT_GUIDE_BORDER: BorderStyle = {\n\ttop: {\n\t\tcolor: \"#cccccc\",\n\t\twidth: { value: 1, unit: \"px\" },\n\t\ttype: LineType.SOLID,\n\t},\n\tright: {\n\t\tcolor: \"#cccccc\",\n\t\twidth: { value: 1, unit: \"px\" },\n\t\ttype: LineType.SOLID,\n\t},\n\tbottom: {\n\t\tcolor: \"#cccccc\",\n\t\twidth: { value: 1, unit: \"px\" },\n\t\ttype: LineType.SOLID,\n\t},\n\tleft: {\n\t\tcolor: \"#cccccc\",\n\t\twidth: { value: 1, unit: \"px\" },\n\t\ttype: LineType.SOLID,\n\t},\n};\n\n/**\n * `BlockGuideBorder` コンポーネントへの props。\n */\nexport interface BlockGuideBorderProps {\n\t/** ブロックのサイズ(px)。 */\n\tblockSizePx: BlockSizePx;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** z-index のサブオフセット(既定値: `BLOCK_SUB_INDEX.GUIDE`)。 */\n\tsubZIndex?: number;\n\n\t/** 表示するガイド枠線スタイル(既定値: `DEFAULT_GUIDE_BORDER`)。 */\n\tborderStyle?: BorderStyle;\n\n\t/** `false` にするとガイド枠線全体を非表示にする(既定値: `true`)。 */\n\tvisible?: boolean;\n}\n\n/**\n * 編集ガイド用の薄い枠線を SVG で描画するコンポーネント。\n *\n * ユーザー設定枠線がない場合にレイアウト確認用として表示します。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} のガイド枠線描画サブコンポーネント。\n */\nexport const BlockGuideBorder: FC<BlockGuideBorderProps> = memo(\n\t({\n\t\tblockSizePx,\n\t\tblockZIndex,\n\t\tsubZIndex = BLOCK_SUB_INDEX.GUIDE,\n\t\tborderStyle = DEFAULT_GUIDE_BORDER,\n\t\tvisible = true,\n\t}) => {\n\t\tif (!visible || !borderStyle) return null;\n\t\tconst { top, right, bottom, left } = borderStyle;\n\t\tif (!top && !right && !bottom && !left) return null;\n\n\t\tconst { width: w, height: h } = blockSizePx;\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\n\n\t\t// ガイド枠線:borderStyleの太さ・タイプを反映して描画\n\t\treturn (\n\t\t\t<svg\n\t\t\t\trole=\"presentation\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tinset: 0,\n\t\t\t\t\twidth: `${w}px`,\n\t\t\t\t\theight: `${h}px`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\toverflow: \"visible\",\n\t\t\t\t\tzIndex,\n\t\t\t\t}}\n\t\t\t\twidth={w}\n\t\t\t\theight={h}\n\t\t\t\tdata-testid=\"block-guide-border\"\n\t\t\t>\n\t\t\t\t{top && (\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1={0}\n\t\t\t\t\t\ty1={0}\n\t\t\t\t\t\tx2={w}\n\t\t\t\t\t\ty2={0}\n\t\t\t\t\t\tstroke={top.color}\n\t\t\t\t\t\tstrokeWidth={top.width.value}\n\t\t\t\t\t\tstrokeDasharray={toDashArray(top.type, top.width.value)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{right && (\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1={w}\n\t\t\t\t\t\ty1={0}\n\t\t\t\t\t\tx2={w}\n\t\t\t\t\t\ty2={h}\n\t\t\t\t\t\tstroke={right.color}\n\t\t\t\t\t\tstrokeWidth={right.width.value}\n\t\t\t\t\t\tstrokeDasharray={toDashArray(right.type, right.width.value)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{bottom && (\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1={0}\n\t\t\t\t\t\ty1={h}\n\t\t\t\t\t\tx2={w}\n\t\t\t\t\t\ty2={h}\n\t\t\t\t\t\tstroke={bottom.color}\n\t\t\t\t\t\tstrokeWidth={bottom.width.value}\n\t\t\t\t\t\tstrokeDasharray={toDashArray(bottom.type, bottom.width.value)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{left && (\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1={0}\n\t\t\t\t\t\ty1={0}\n\t\t\t\t\t\tx2={0}\n\t\t\t\t\t\ty2={h}\n\t\t\t\t\t\tstroke={left.color}\n\t\t\t\t\t\tstrokeWidth={left.width.value}\n\t\t\t\t\t\tstrokeDasharray={toDashArray(left.type, left.width.value)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nBlockGuideBorder.displayName = \"BlockGuideBorder\";\n","import {\n\ttype CSSProperties,\n\ttype ForwardedRef,\n\tforwardRef,\n\tmemo,\n\tuseImperativeHandle,\n\tuseRef,\n} from \"react\";\n\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"../../../utils/zIndex\";\n\nimport type { ResolvedPlugin } from \"../../../plugin/registry\";\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { NoteMode } from \"../../../types/mode\";\nimport type { Value } from \"../../../types/value\";\nimport type { BlockSizePx } from \"../types\";\n\n/**\n * `BlockRenderer` コンポーネントへの props。\n */\nexport interface BlockRendererProps {\n\t/** ブロックの ID。 */\n\tid: string;\n\n\t/** 解決済みプラグイン。 */\n\tresolvedPlugin: ResolvedPlugin;\n\n\t/** プロパティマップ(プラグインデフォルトとユーザー値をマージ済み)。 */\n\tprops: Record<string, Value>;\n\n\t/** ブロックの現在値。 */\n\tvalue: Value;\n\n\t/** 値変更時のコールバック。読み取り専用の場合は不要。 */\n\tonChange?: (value: Value) => void;\n\n\t/** `true` の場合、レンダラーは読み取り専用で入力を受け付けない。 */\n\treadOnly: boolean;\n\n\t/** 表示モード。 */\n\tmode: NoteMode;\n\n\t/** ブロックのサイズ(px)。 */\n\tblockSizePx: BlockSizePx;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** z-index のサブオフセット(既定値: `BLOCK_SUB_INDEX.CONTENT`)。 */\n\tsubZIndex?: number;\n\n\t/** 高さが動的に測定された際のコールバック。 */\n\tonMeasureHeight?: (heightPx: number) => void;\n\n\t/** 幅が動的に測定された際のコールバック。 */\n\tonMeasureWidth?: (widthPx: number) => void;\n\n\t/** フォーカス離脱時の値確定通知コールバック。 */\n\tonBlur?: (value: Value) => void;\n\n\t/** 値バインディング用コンテキスト。 */\n\tbindingContext?: BindingContext;\n\n\t/** アクション実行用コンテキスト。 */\n\tactionContext?: ActionContext;\n\n\t/** ブロックに設定されたベース背景色。 */\n\tblockBackgroundColor?: string;\n}\n\n// forwardRef でラップする前の内部実装関数\nconst BlockRendererInner = (\n\t{\n\t\tid,\n\t\tresolvedPlugin,\n\t\tprops,\n\t\tvalue,\n\t\tonChange,\n\t\tonBlur,\n\t\treadOnly,\n\t\tmode,\n\t\tblockSizePx,\n\t\tblockZIndex,\n\t\tsubZIndex = BLOCK_SUB_INDEX.CONTENT,\n\t\tonMeasureHeight,\n\t\tonMeasureWidth,\n\t\tbindingContext,\n\t\tactionContext,\n\t\tblockBackgroundColor,\n\t}: BlockRendererProps,\n\tref: ForwardedRef<BlockRef>,\n) => {\n\tconst innerRef = useRef<BlockRef>(null);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({ focus: () => innerRef.current?.focus() }),\n\t\t[],\n\t);\n\n\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\n\n\tconst containerStyle: CSSProperties = {\n\t\tposition: \"absolute\",\n\t\tinset: 0,\n\t\twidth: `${blockSizePx.width}px`,\n\t\theight: `${blockSizePx.height}px`,\n\t\tzIndex,\n\t\tpointerEvents: \"auto\",\n\t};\n\n\tconst rendererProps: RendererProps<Record<string, Value>, Value> = {\n\t\tid,\n\t\tprops,\n\t\tvalue,\n\t\tonChange: onChange ?? (() => {}),\n\t\tonBlur,\n\t\treadOnly,\n\t\tmode,\n\t\tdimensions: { widthPx: blockSizePx.width, heightPx: blockSizePx.height },\n\t\tonMeasureHeight,\n\t\tonMeasureWidth,\n\t\tariaLabel: resolvedPlugin.meta.displayName,\n\t\tbindingContext,\n\t\tactionContext,\n\t\tblockBackgroundColor,\n\t};\n\n\tconst { Renderer } = resolvedPlugin;\n\n\treturn (\n\t\t<div\n\t\t\tstyle={containerStyle}\n\t\t\tdata-testid=\"block-renderer\"\n\t\t\tdata-block-id={id}\n\t\t\tdata-plugin-kind={resolvedPlugin.kind}\n\t\t>\n\t\t\t<Renderer ref={innerRef} {...rendererProps} />\n\t\t</div>\n\t);\n};\n\n/**\n * プラグインの `Renderer` を実行し、コンテナ内にマウントするコンポーネント。\n *\n * `ref` で {@link BlockRef} を取得できます。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} 内でプラグインレンダラーを実行するサブコンポーネント。\n */\nexport const BlockRenderer = memo(\n\tforwardRef<BlockRef, BlockRendererProps>(BlockRendererInner),\n);\n\nBlockRenderer.displayName = \"BlockRenderer\";\n","// BlockLayer のみで使用するユーティリティ。\n// block.props + plugin のデフォルト props + page-level blockDefaults を合成して\n// 完全な props オブジェクトを返す。\n\nimport type { ResolvedPlugin } from \"../../../../plugin\";\nimport type { Block, BlockDefaults, Value } from \"../../../../types\";\n\n/**\n * ブロックの完全な props を解決する。\n *\n * 優先順位(高→低): block.props > blockDefaults[kind] > plugin.defaultProps\n */\nexport function resolveBlockProps(\n\tblock: Block,\n\tresolvedPlugin: ResolvedPlugin,\n\tblockDefaults?: BlockDefaults,\n): Record<string, Value> {\n\tconst kindDefaults = blockDefaults?.[block.kind] ?? {};\n\treturn {\n\t\t...resolvedPlugin.defaultProps,\n\t\t...kindDefaults,\n\t\t...block.props,\n\t};\n}\n","import { type CSSProperties, type FC, memo, useState } from \"react\";\n\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"../../../utils/zIndex\";\n\nimport type { ValidationError } from \"../../../types/validation\";\nimport type { BlockSizePx } from \"../types\";\n\n/**\n * `ValidationOverlay` コンポーネントへの props。\n */\nexport interface ValidationOverlayProps {\n\t/** ブロックのサイズ(px)。 */\n\tblockSizePx: BlockSizePx;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** 表示するバリデーションエラー一覧。空配列の場合は描画しない。 */\n\terrors: ValidationError[];\n}\n\n/**\n * バリデーションエラーを示すオーバーレイコンポーネント。\n *\n * エラーがある場合は黒黄の縞模様を表示し、ホバー時にエラーメッセージをツールチップが示します。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} のバリデーションオーバーレイサブコンポーネント。\n *\n * 通常は {@link BlockLayer} の `showValidation` prop で制御する。\n */\nexport const ValidationOverlay: FC<ValidationOverlayProps> = memo(\n\t({ blockSizePx, blockZIndex, errors }) => {\n\t\tconst [hovered, setHovered] = useState(false);\n\n\t\tif (errors.length === 0) return null;\n\n\t\tconst zIndex = getSubZIndex(blockZIndex, BLOCK_SUB_INDEX.VALIDATION);\n\t\tconst BORDER_WIDTH = 3;\n\t\tconst stripe =\n\t\t\t\"repeating-linear-gradient(45deg, #1a1a1a 0px, #1a1a1a 4px, #FFD700 4px, #FFD700 8px)\";\n\n\t\tconst containerStyle: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\ttop: -BORDER_WIDTH,\n\t\t\tleft: -BORDER_WIDTH,\n\t\t\twidth: `${blockSizePx.width + BORDER_WIDTH * 2}px`,\n\t\t\theight: `${blockSizePx.height + BORDER_WIDTH * 2}px`,\n\t\t\tzIndex,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\tconst edgeStyle = (side: CSSProperties): CSSProperties => ({\n\t\t\tposition: \"absolute\",\n\t\t\tbackground: stripe,\n\t\t\t...side,\n\t\t});\n\n\t\treturn (\n\t\t\t<div style={containerStyle} data-testid=\"validation-overlay\">\n\t\t\t\t<div\n\t\t\t\t\tstyle={edgeStyle({\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\theight: BORDER_WIDTH,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t<div\n\t\t\t\t\tstyle={edgeStyle({\n\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\theight: BORDER_WIDTH,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t<div\n\t\t\t\t\tstyle={edgeStyle({\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\twidth: BORDER_WIDTH,\n\t\t\t\t\t\theight: \"100%\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t<div\n\t\t\t\t\tstyle={edgeStyle({\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\twidth: BORDER_WIDTH,\n\t\t\t\t\t\theight: \"100%\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\ttop: -8,\n\t\t\t\t\t\tright: -8,\n\t\t\t\t\t\twidth: 16,\n\t\t\t\t\t\theight: 16,\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tjustifyContent: \"center\",\n\t\t\t\t\t\tfontSize: 11,\n\t\t\t\t\t\tlineHeight: 1,\n\t\t\t\t\t\tcursor: \"default\",\n\t\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\t\tuserSelect: \"none\",\n\t\t\t\t\t\tbackground: \"none\",\n\t\t\t\t\t\tborder: \"none\",\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t}}\n\t\t\t\t\tonMouseEnter={() => setHovered(true)}\n\t\t\t\t\tonMouseLeave={() => setHovered(false)}\n\t\t\t\t\taria-label={errors.map((e) => e.message).join(\" / \")}\n\t\t\t\t>\n\t\t\t\t\t⚠\n\t\t\t\t\t{hovered && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\ttop: \"calc(100% + 4px)\",\n\t\t\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t\t\tminWidth: 160,\n\t\t\t\t\t\t\t\tmaxWidth: 240,\n\t\t\t\t\t\t\t\tbackgroundColor: \"rgba(30,30,30,0.92)\",\n\t\t\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\t\t\tfontSize: 11,\n\t\t\t\t\t\t\t\tlineHeight: 1.5,\n\t\t\t\t\t\t\t\tpadding: \"6px 8px\",\n\t\t\t\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\t\t\t\tboxShadow: \"0 2px 6px rgba(0,0,0,0.4)\",\n\t\t\t\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\t\t\t\twhiteSpace: \"pre-wrap\",\n\t\t\t\t\t\t\t\twordBreak: \"break-all\",\n\t\t\t\t\t\t\t\tzIndex: zIndex + 1,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{errors.map((e) => (\n\t\t\t\t\t\t\t\t<div key={e.code}>{e.message}</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t\t<style>{`@media print { [data-testid=\"validation-overlay\"] { display: none !important; } }`}</style>\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nValidationOverlay.displayName = \"ValidationOverlay\";\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tmemo,\n\tuseCallback,\n\tuseMemo,\n\tuseState,\n} from \"react\";\n\nimport { NoteMode } from \"../../../types/mode\";\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { BLOCK_SUB_INDEX, Z_INDEX } from \"../../../utils/zIndex\";\nimport { BlockBorder } from \"./BlockBorder\";\nimport { BlockCanvas } from \"./BlockCanvas\";\nimport { BlockGuideBorder, DEFAULT_GUIDE_BORDER } from \"./BlockGuideBorder\";\nimport { BlockRenderer } from \"./BlockRenderer\";\nimport { resolveBlockProps } from \"./utils/resolveBlockProps\";\nimport { ValidationOverlay } from \"./ValidationOverlay\";\n\nimport type { ResolvedPlugin } from \"../../../plugin/registry\";\nimport type { BlockRef } from \"../../../plugin/types\";\nimport type { Block } from \"../../../types/block\";\nimport type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockDefaults } from \"../../../types/schema\";\nimport type { ValidationError } from \"../../../types/validation\";\nimport type { Value } from \"../../../types/value\";\nimport type { BlockRectPx, BlockSizePx } from \"../types\";\n\n/**\n * 1ブロック全体(背景・レンダラー・枠線・ガイド・バリデーション)をまとめるコンテナコンポーネント。\n */\nexport interface BlockContainerProps {\n\t/** 対象ブロックデータ。 */\n\tblock: Block;\n\n\t/** 解決済みプラグイン。 */\n\tresolvedPlugin: ResolvedPlugin;\n\n\t/** ブロックの位置とサイズ(px)。 */\n\tblockRectPx: BlockRectPx;\n\n\t/** z-index のベース値。 */\n\tblockZIndex: number;\n\n\t/** 表示モード(ビュー / フォーム / 編集)。 */\n\tmode: NoteMode;\n\n\t/** ブロックの現在値。 */\n\tvalue: Value;\n\n\t/** ブロックのデフォルト値設定。 */\n\tblockDefaults?: BlockDefaults;\n\n\t/** 値変更時のコールバック。 */\n\tonValueChange?: (val: Value) => void;\n\n\t/** フォーカス離脱時の値確定通知コールバック。 */\n\tonBlur?: (value: Value) => void;\n\n\t/** ガイド枠線を表示するか(既定値: `true`)。 */\n\tshowGuides?: boolean;\n\n\t/** ユーザー設定枠線を表示するか(既定値: `true`)。 */\n\tshowBorder?: boolean;\n\n\t/** デフォルトのガイド枠線スタイル。 */\n\tdefaultGuideBorder?: BorderStyle;\n\n\t/** DPI 値(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n\n\t/** ポインターイベントの通過設定(既定値: `\"none\"`)。 */\n\tpointerEvents?: \"auto\" | \"none\";\n\n\t/** バリデーションオーバーレイを表示するか(既定値: `false`)。 */\n\tshowValidation?: boolean;\n\n\t/** バリデーションエラー一覧。 */\n\tvalidationErrors?: ValidationError[];\n\n\t/** ブロックの高さが動的に測定された際のコールバック。 */\n\tonMeasureHeight?: (blockId: string, heightPx: number) => void;\n\n\t/** ブロックの幅が動的に測定された際のコールバック。 */\n\tonMeasureWidth?: (blockId: string, widthPx: number) => void;\n\n\t/** フォーカス中のブロック ID。 */\n\tfocusedBlockId?: string;\n\n\t/** 値バインディング用コンテキスト。 */\n\tbindingContext?: BindingContext;\n\n\t/** アクション実行用コンテキスト。 */\n\tactionContext?: ActionContext;\n}\n\n/**\n * ブロックの全構成要素を統合するコンテナコンポーネント。\n *\n * `ref` で {@link BlockRef} を取得できます。\n *\n * @remarks\n * **Canvas** — {@link BlockLayer} の1ブロック統合コンテナ。\n */\nexport const BlockContainer = memo(\n\tforwardRef<BlockRef, BlockContainerProps>(\n\t\t(\n\t\t\t{\n\t\t\t\tblock,\n\t\t\t\tresolvedPlugin,\n\t\t\t\tblockRectPx,\n\t\t\t\tblockZIndex,\n\t\t\t\tmode,\n\t\t\t\tvalue,\n\t\t\t\tblockDefaults,\n\t\t\t\tonValueChange,\n\t\t\t\tonBlur,\n\t\t\t\tshowGuides = true,\n\t\t\t\tshowBorder = true,\n\t\t\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\n\t\t\t\tdpi = DEFAULT_DPI,\n\t\t\t\tpointerEvents = \"none\",\n\t\t\t\tshowValidation = false,\n\t\t\t\tvalidationErrors,\n\t\t\t\tonMeasureHeight,\n\t\t\t\tonMeasureWidth,\n\t\t\t\tfocusedBlockId,\n\t\t\t\tbindingContext,\n\t\t\t\tactionContext,\n\t\t\t},\n\t\t\tref,\n\t\t) => {\n\t\t\tconst [localHeight, setLocalHeight] = useState<number | null>(null);\n\t\t\tconst [localWidth, setLocalWidth] = useState<number | null>(null);\n\n\t\t\tconst handleContentHeight = useCallback(\n\t\t\t\t(heightPx: number) => {\n\t\t\t\t\tsetLocalHeight(heightPx);\n\t\t\t\t\tonMeasureHeight?.(block.id, heightPx);\n\t\t\t\t},\n\t\t\t\t[block.id, onMeasureHeight],\n\t\t\t);\n\n\t\t\tconst handleContentWidth = useCallback(\n\t\t\t\t(widthPx: number) => {\n\t\t\t\t\tsetLocalWidth(widthPx);\n\t\t\t\t\tonMeasureWidth?.(block.id, widthPx);\n\t\t\t\t},\n\t\t\t\t[block.id, onMeasureWidth],\n\t\t\t);\n\n\t\t\tconst effectiveHeight = onMeasureHeight\n\t\t\t\t? Math.max(blockRectPx.height, localHeight ?? 0)\n\t\t\t\t: blockRectPx.height;\n\n\t\t\tconst effectiveWidth = onMeasureWidth\n\t\t\t\t? Math.max(blockRectPx.width, localWidth ?? 0)\n\t\t\t\t: blockRectPx.width;\n\n\t\t\tconst containerStyle: CSSProperties = {\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: `${blockRectPx.left}px`,\n\t\t\t\ttop: `${blockRectPx.top}px`,\n\t\t\t\twidth: `${effectiveWidth}px`,\n\t\t\t\theight: `${effectiveHeight}px`,\n\t\t\t\tzIndex: blockZIndex,\n\t\t\t\tpointerEvents,\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t};\n\n\t\t\tconst effectiveBlockSizePx: BlockSizePx = useMemo(\n\t\t\t\t() => ({ width: effectiveWidth, height: effectiveHeight }),\n\t\t\t\t[effectiveWidth, effectiveHeight],\n\t\t\t);\n\n\t\t\tconst resolvedProps = resolveBlockProps(\n\t\t\t\tblock,\n\t\t\t\tresolvedPlugin,\n\t\t\t\tblockDefaults,\n\t\t\t);\n\t\t\tconst validatedProps = resolvedPlugin.validateProps\n\t\t\t\t? resolvedPlugin.validateProps(resolvedProps)\n\t\t\t\t: resolvedProps;\n\t\t\tconst validatedValue = resolvedPlugin.validateValue\n\t\t\t\t? (resolvedPlugin.validateValue(value, validatedProps) ??\n\t\t\t\t\tblock.initValue ??\n\t\t\t\t\tvalue)\n\t\t\t\t: value;\n\n\t\t\tconst hasErrors = validationErrors && validationErrors.length > 0;\n\t\t\tconst errorDescId = hasErrors ? `error-${block.id}` : undefined;\n\t\t\tconst isFocused = focusedBlockId === block.id;\n\n\t\t\treturn (\n\t\t\t\t<section\n\t\t\t\t\taria-label={resolvedPlugin.meta.displayName}\n\t\t\t\t\taria-invalid={hasErrors || undefined}\n\t\t\t\t\taria-describedby={errorDescId}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t\tdata-testid={`block-${block.id}`}\n\t\t\t\t\tdata-block-id={block.id}\n\t\t\t\t>\n\t\t\t\t\t{/* 背景 */}\n\t\t\t\t\t<BlockCanvas\n\t\t\t\t\t\tblockSizePx={effectiveBlockSizePx}\n\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\tbackgroundColor={block.style?.backgroundColor}\n\t\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BG}\n\t\t\t\t\t/>\n\t\t\t\t\t{/* ガイド枠線(編集モードで enumBorder なし) */}\n\t\t\t\t\t{showGuides && !block.style?.border && (\n\t\t\t\t\t\t<BlockGuideBorder\n\t\t\t\t\t\t\tblockSizePx={effectiveBlockSizePx}\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.GUIDE}\n\t\t\t\t\t\t\tborderStyle={defaultGuideBorder}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* コンテンツ(Renderer) */}\n\t\t\t\t\t<BlockRenderer\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tid={block.id}\n\t\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\t\tprops={validatedProps}\n\t\t\t\t\t\tvalue={validatedValue}\n\t\t\t\t\t\tonChange={onValueChange}\n\t\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\t\treadOnly={\n\t\t\t\t\t\t\tmode === NoteMode.EDIT\n\t\t\t\t\t\t\t\t? (block.behavior?.readOnly ?? false)\n\t\t\t\t\t\t\t\t: true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmode={mode}\n\t\t\t\t\t\tblockSizePx={effectiveBlockSizePx}\n\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.CONTENT}\n\t\t\t\t\t\tonMeasureHeight={onMeasureHeight ? handleContentHeight : undefined}\n\t\t\t\t\t\tonMeasureWidth={onMeasureWidth ? handleContentWidth : undefined}\n\t\t\t\t\t\tbindingContext={bindingContext}\n\t\t\t\t\t\tactionContext={actionContext}\n\t\t\t\t\t\tblockBackgroundColor={block.style?.backgroundColor}\n\t\t\t\t\t/>\n\t\t\t\t\t{/* ユーザー設定枠線 */}\n\t\t\t\t\t<BlockBorder\n\t\t\t\t\t\tblockSizePx={effectiveBlockSizePx}\n\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\tborderStyle={block.style?.border}\n\t\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BORDER}\n\t\t\t\t\t\tvisible={showBorder}\n\t\t\t\t\t\tdpi={dpi}\n\t\t\t\t\t/>\n\t\t\t\t\t{/* バリデーションオーバーレイ */}\n\t\t\t\t\t{showValidation && hasErrors && (\n\t\t\t\t\t\t<ValidationOverlay\n\t\t\t\t\t\t\tblockSizePx={effectiveBlockSizePx}\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\t\terrors={validationErrors}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* a11y: エラー記述 */}\n\t\t\t\t\t{hasErrors && (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tid={errorDescId}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\twidth: \"1px\",\n\t\t\t\t\t\t\t\theight: \"1px\",\n\t\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\t\tmargin: \"-1px\",\n\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\tclip: \"rect(0,0,0,0)\",\n\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{validationErrors.map((e) => e.message).join(\", \")}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* フォーカスリング */}\n\t\t\t\t\t{isFocused && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\tinset: 0,\n\t\t\t\t\t\t\t\tboxShadow: \"0 0 0 2px #3b82f6, 0 0 0 4px rgba(59,130,246,0.15)\",\n\t\t\t\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\t\t\t\tzIndex: Z_INDEX.HOVER_OUTLINE,\n\t\t\t\t\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</section>\n\t\t\t);\n\t\t},\n\t),\n\t// blockRectPx は毎回新規オブジェクトが渡されるため、数値比較で再レンダリングを抑制する\n\t(prev, next) =>\n\t\tprev.block === next.block &&\n\t\tprev.resolvedPlugin === next.resolvedPlugin &&\n\t\tprev.blockRectPx.left === next.blockRectPx.left &&\n\t\tprev.blockRectPx.top === next.blockRectPx.top &&\n\t\tprev.blockRectPx.width === next.blockRectPx.width &&\n\t\tprev.blockRectPx.height === next.blockRectPx.height &&\n\t\tprev.blockZIndex === next.blockZIndex &&\n\t\tprev.mode === next.mode &&\n\t\tprev.value === next.value &&\n\t\tprev.blockDefaults === next.blockDefaults &&\n\t\t// onValueChange は BlockLayer 内でブロックごとに毎回新しいクロージャが生成されるため比較しない。\n\t\t// onBlur も同様に BlockLayer 内で毎回新しいクロージャが生成されるため比較しない。\n\t\t// 外側のコールバックは useCallback で安定しており、block.id は prev.block === next.block で担保済み。\n\t\tprev.showGuides === next.showGuides &&\n\t\tprev.showBorder === next.showBorder &&\n\t\tprev.defaultGuideBorder === next.defaultGuideBorder &&\n\t\tprev.dpi === next.dpi &&\n\t\tprev.pointerEvents === next.pointerEvents &&\n\t\tprev.showValidation === next.showValidation &&\n\t\tprev.validationErrors === next.validationErrors &&\n\t\tprev.onMeasureHeight === next.onMeasureHeight &&\n\t\tprev.onMeasureWidth === next.onMeasureWidth &&\n\t\tprev.focusedBlockId === next.focusedBlockId &&\n\t\tprev.bindingContext === next.bindingContext &&\n\t\tprev.actionContext === next.actionContext,\n);\n\nBlockContainer.displayName = \"BlockContainer\";\n","import { type CSSProperties, Fragment, memo, useRef } from \"react\";\n\nimport { evalHiddenBinding } from \"../../../utils/block\";\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { getBlockZIndex, Z_INDEX } from \"../../../utils/zIndex\";\nimport { BlockContainer } from \"./BlockContainer\";\nimport { DEFAULT_GUIDE_BORDER } from \"./BlockGuideBorder\";\n\nimport type { PluginRegistry } from \"../../../plugin/registry\";\nimport type { BlockRef } from \"../../../plugin/types\";\nimport type { Block } from \"../../../types/block\";\nimport type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { NoteMode } from \"../../../types/mode\";\nimport type { BlockDefaults } from \"../../../types/schema\";\nimport type { ValidationError } from \"../../../types/validation\";\nimport type { Value } from \"../../../types/value\";\nimport type { BlockRectPx } from \"../types\";\n\n// ブロック個別 fit 用の no-op コールバック(安定参照)\nconst NOOP_MEASURE_HEIGHT = (_id: string, _h: number) => {};\nconst NOOP_MEASURE_WIDTH = (_id: string, _w: number) => {};\n\n/**\n * `BlockLayer` コンポーネントへの props。\n */\nexport interface BlockLayerProps {\n\t/** 描画対象のブロック一覧。 */\n\tblocks: Block[];\n\n\t/** プラグインレジストリ。 */\n\tpluginRegistry: PluginRegistry;\n\n\t/** 表示モード。 */\n\tmode: NoteMode;\n\n\t/** ブロック ID → 現在値のマップ。 */\n\tvalues: Record<string, Value>;\n\n\t/** ブロックのデフォルト値設定。 */\n\tblockDefaults?: BlockDefaults;\n\n\t/** 選択中のブロック ID 一覧(既定値: `[]`)。 */\n\tselectedBlockIds?: string[];\n\n\t/** ブロックからキャンバス上の矩形座標(px)を返す関数。 */\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\n\n\t/** ブロックの値が変更されたときのコールバック。 */\n\tonValueChange?: (blockId: string, value: Value) => void;\n\n\t/** フォーカス離脱時の値確定通知コールバック。 */\n\tonBlur?: (blockId: string, value: Value) => void;\n\n\t/** ガイド枠線を表示するか(既定値: `true`)。 */\n\tshowGuides?: boolean;\n\n\t/** ユーザー設定枠線を表示するか(既定値: `true`)。 */\n\tshowBorder?: boolean;\n\n\t/** デフォルトのガイド枠線スタイル。 */\n\tdefaultGuideBorder?: BorderStyle;\n\n\t/** DPI 値(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n\n\t/** バリデーションオーバーレイを表示するか(既定値: `false`)。 */\n\tshowValidation?: boolean;\n\n\t/** ブロック ID → バリデーションエラー一覧のマップ。 */\n\tvalidationErrors?: Record<string, ValidationError[]>;\n\n\t/** ブロックの高さが測定された際のコールバック。 */\n\tonMeasureHeight?: (blockId: string, heightPx: number) => void;\n\n\t/** ブロックの幅が測定された際のコールバック。 */\n\tonMeasureWidth?: (blockId: string, widthPx: number) => void;\n\n\t/** フォーカス中のブロック ID。 */\n\tfocusedBlockId?: string;\n\n\t/** 値バインディング用コンテキスト。 */\n\tbindingContext?: BindingContext;\n\n\t/** アクション実行用コンテキスト。 */\n\tactionContext?: ActionContext;\n}\n\n/**\n * ブロック一覧を描画するレイヤーコンポーネント。\n *\n * @remarks\n * **Canvas** — {@link Note} 実装を担う低レベルブロックレンダリングレイヤー。\n *\n * 通常は {@link Note} を使用する。\n */\nexport const BlockLayer = memo(\n\t({\n\t\tblocks,\n\t\tpluginRegistry,\n\t\tmode,\n\t\tvalues,\n\t\tblockDefaults,\n\t\tselectedBlockIds = [],\n\t\tgetBlockRectPx,\n\t\tonValueChange,\n\t\tonBlur,\n\t\tshowGuides = true,\n\t\tshowBorder = true,\n\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\n\t\tdpi = DEFAULT_DPI,\n\t\tshowValidation = false,\n\t\tvalidationErrors,\n\t\tonMeasureHeight,\n\t\tonMeasureWidth,\n\t\tfocusedBlockId,\n\t\tbindingContext,\n\t\tactionContext,\n\t}: BlockLayerProps) => {\n\t\tconst blockRefs = useRef<Map<string, BlockRef>>(new Map());\n\n\t\tconst layerStyle: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tinset: 0,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\treturn (\n\t\t\t<div style={layerStyle} data-testid=\"block-layer\">\n\t\t\t\t{blocks.map((block, index) => {\n\t\t\t\t\tconst resolvedPlugin = pluginRegistry[block.kind];\n\t\t\t\t\tif (!resolvedPlugin) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[tatamicks] Block kind \"${block.kind}\" is not registered. Add the plugin to createPluginRegistry.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst isHidden = evalHiddenBinding(\n\t\t\t\t\t\tblock.hiddenBinding,\n\t\t\t\t\t\tbindingContext,\n\t\t\t\t\t);\n\t\t\t\t\tif (isHidden) return null;\n\n\t\t\t\t\tconst blockRectPx = getBlockRectPx(block);\n\t\t\t\t\tconst isSelected = selectedBlockIds.includes(block.id);\n\t\t\t\t\tconst blockZIndex = isSelected\n\t\t\t\t\t\t? Z_INDEX.SELECT_BLOCK\n\t\t\t\t\t\t: getBlockZIndex(index);\n\n\t\t\t\t\t// binding 経由の値解決\n\t\t\t\t\tconst binding =\n\t\t\t\t\t\tblock.props !== null &&\n\t\t\t\t\t\ttypeof block.props === \"object\" &&\n\t\t\t\t\t\t\"binding\" in block.props\n\t\t\t\t\t\t\t? (block.props as { binding?: string }).binding\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\tconst value =\n\t\t\t\t\t\tbinding && bindingContext\n\t\t\t\t\t\t\t? (bindingContext.get(binding) ?? null)\n\t\t\t\t\t\t\t: block.id in values\n\t\t\t\t\t\t\t\t? values[block.id]\n\t\t\t\t\t\t\t\t: (block.initValue ?? null);\n\n\t\t\t\t\tconst handleValueChange: ((val: Value) => void) | undefined =\n\t\t\t\t\t\tbinding && bindingContext\n\t\t\t\t\t\t\t? (val) => bindingContext.set(binding, val)\n\t\t\t\t\t\t\t: onValueChange\n\t\t\t\t\t\t\t\t? (val) => onValueChange(block.id, val)\n\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\tconst blockMeasureHeight = block.behavior?.heightFit\n\t\t\t\t\t\t? (onMeasureHeight ?? NOOP_MEASURE_HEIGHT)\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tconst blockMeasureWidth = block.behavior?.widthFit\n\t\t\t\t\t\t? (onMeasureWidth ?? NOOP_MEASURE_WIDTH)\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Fragment key={block.id}>\n\t\t\t\t\t\t\t<BlockContainer\n\t\t\t\t\t\t\t\tref={(r) => {\n\t\t\t\t\t\t\t\t\tif (r) blockRefs.current.set(block.id, r);\n\t\t\t\t\t\t\t\t\telse blockRefs.current.delete(block.id);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tblock={block}\n\t\t\t\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\t\t\t\tblockRectPx={blockRectPx}\n\t\t\t\t\t\t\t\tblockZIndex={blockZIndex}\n\t\t\t\t\t\t\t\tmode={mode}\n\t\t\t\t\t\t\t\tvalue={value ?? null}\n\t\t\t\t\t\t\t\tblockDefaults={blockDefaults}\n\t\t\t\t\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\t\t\t\t\tonBlur={onBlur ? (val) => onBlur(block.id, val) : undefined}\n\t\t\t\t\t\t\t\tshowGuides={showGuides}\n\t\t\t\t\t\t\t\tshowBorder={showBorder}\n\t\t\t\t\t\t\t\tdefaultGuideBorder={defaultGuideBorder}\n\t\t\t\t\t\t\t\tdpi={dpi}\n\t\t\t\t\t\t\t\tpointerEvents=\"none\"\n\t\t\t\t\t\t\t\tshowValidation={showValidation}\n\t\t\t\t\t\t\t\tvalidationErrors={validationErrors?.[block.id]}\n\t\t\t\t\t\t\t\tonMeasureHeight={blockMeasureHeight}\n\t\t\t\t\t\t\t\tonMeasureWidth={blockMeasureWidth}\n\t\t\t\t\t\t\t\tfocusedBlockId={focusedBlockId}\n\t\t\t\t\t\t\t\tbindingContext={bindingContext}\n\t\t\t\t\t\t\t\tactionContext={actionContext}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Fragment>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nBlockLayer.displayName = \"BlockLayer\";\n","import { LineType } from \"../../../../types/line\";\n\nimport type { LineStyle } from \"../../../../types/line\";\n\n/**\n * `LineStyle` から SVG の `stroke-dasharray` 値を返します。\n * @param lineStyle - 線スタイル。`undefined` または SOLID の場合は `undefined` を返します。\n */\nexport function getStrokeDasharray(lineStyle?: LineStyle): string | undefined {\n\tif (!lineStyle?.width || !lineStyle?.type) return undefined;\n\tconst w = lineStyle.width.value;\n\tif (w === 0) return undefined;\n\tif (lineStyle.type === LineType.DASHED) return `${w * 4} ${w * 2}`;\n\tif (lineStyle.type === LineType.DOTTED) return `${w * 1} ${w * 2}`;\n\treturn undefined;\n}\n","import { memo } from \"react\";\n\nimport { DEFAULT_DPI, toPx } from \"../../../utils/convert\";\nimport { Z_INDEX } from \"../../../utils/zIndex\";\nimport { getStrokeDasharray } from \"./utils/getStrokeDasharray\";\n\nimport type { BorderStyle, LineStyle } from \"../../../types/line\";\nimport type { PaperContentPx } from \"./types\";\n\n/**\n * `BorderOverlay` コンポーネントへの props。\n */\nexport interface BorderOverlayProps {\n\t/** コンテンツ領域のサイズ(px)。 */\n\tcontentPx: PaperContentPx;\n\n\t/** 左マージン(px)。SVG の配置基点として使用。 */\n\tmarginLeftPx: number;\n\n\t/** 上マージン(px)。SVG の配置基点として使用。 */\n\tmarginTopPx: number;\n\n\t/** 用紙枠線のスタイル。省略時は描画しない。 */\n\tborderStyle?: BorderStyle;\n\n\t/** DPI 値(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n\n\t/** z-index (既定値: `Z_INDEX.BORDER_OVERLAY`)。 */\n\tzIndex?: number;\n}\n\n// LineStyle を SVG 属性オブジェクトに変換するヘルパー\nfunction lineAttrs(style: LineStyle, dpi: number) {\n\treturn {\n\t\tstroke: style.color,\n\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\n\t\tstrokeDasharray: getStrokeDasharray(style),\n\t};\n}\n\n/**\n * コンテンツ領域の四辺に SVG 線で用紙枠線を描画するコンポーネント。\n */\nexport const BorderOverlay: React.FC<BorderOverlayProps> = memo(\n\t({\n\t\tcontentPx,\n\t\tmarginLeftPx,\n\t\tmarginTopPx,\n\t\tborderStyle,\n\t\tdpi = DEFAULT_DPI,\n\t\tzIndex = Z_INDEX.BORDER_OVERLAY,\n\t}) => {\n\t\tif (!borderStyle) return null;\n\n\t\tconst { top, right, bottom, left } = borderStyle;\n\t\tif (!top && !right && !bottom && !left) return null;\n\n\t\tconst w = contentPx.width;\n\t\tconst h = contentPx.height;\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\trole=\"presentation\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tleft: `${marginLeftPx}px`,\n\t\t\t\t\ttop: `${marginTopPx}px`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\toverflow: \"visible\",\n\t\t\t\t\tzIndex,\n\t\t\t\t}}\n\t\t\t\twidth={w}\n\t\t\t\theight={h}\n\t\t\t\tdata-testid=\"border-overlay\"\n\t\t\t>\n\t\t\t\t{top && <line x1={0} y1={0} x2={w} y2={0} {...lineAttrs(top, dpi)} />}\n\t\t\t\t{right && (\n\t\t\t\t\t<line x1={w} y1={0} x2={w} y2={h} {...lineAttrs(right, dpi)} />\n\t\t\t\t)}\n\t\t\t\t{bottom && (\n\t\t\t\t\t<line x1={0} y1={h} x2={w} y2={h} {...lineAttrs(bottom, dpi)} />\n\t\t\t\t)}\n\t\t\t\t{left && <line x1={0} y1={0} x2={0} y2={h} {...lineAttrs(left, dpi)} />}\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nBorderOverlay.displayName = \"BorderOverlay\";\n","import { memo } from \"react\";\n\nimport { Z_INDEX } from \"../../../utils/zIndex\";\n\nimport type { PaperCanvasPx } from \"./types\";\n\n/**\n * `GridCanvas` コンポーネントへの props。\n */\nexport interface GridCanvasProps {\n\t/** キャンバス全体のサイズ(px)。 */\n\tcanvasPx: PaperCanvasPx;\n\n\t/** 用紙背景色(既定値: `\"#ffffff\"`)。 */\n\tbackgroundColor?: string;\n\n\t/** `box-shadow` CSS 値(既定値: 軽い影)。 */\n\tboxShadow?: string;\n\n\t/** z-index(既定値: `Z_INDEX.GRID_CANVAS`)。 */\n\tzIndex?: number;\n}\n\n/**\n * 用紙キャンバス背景(白矩形 + 影)を描画するコンポーネント。\n */\nexport const GridCanvas: React.FC<GridCanvasProps> = memo(\n\t({\n\t\tcanvasPx,\n\t\tbackgroundColor = \"#ffffff\",\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\n\t\tzIndex = Z_INDEX.GRID_CANVAS,\n\t}) => (\n\t\t<div\n\t\t\trole=\"presentation\"\n\t\t\taria-label=\"Paper background\"\n\t\t\tdata-testid=\"grid-canvas\"\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tinset: 0,\n\t\t\t\twidth: `${canvasPx.width}px`,\n\t\t\t\theight: `${canvasPx.height}px`,\n\t\t\t\tbackgroundColor,\n\t\t\t\tboxShadow,\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t\tzIndex,\n\t\t\t}}\n\t\t/>\n\t),\n);\n\nGridCanvas.displayName = \"GridCanvas\";\n","import { memo, useEffect, useRef, useState } from \"react\";\n\nimport { toMm } from \"../../../../utils/convert\";\nimport styles from \"./GridUnitEditor.module.css\";\n\nimport type { Dimension, GridUnit } from \"../../../../types/unit\";\n\n/**\n * `GridUnitEditor` コンポーネントへの props。\n */\nexport interface GridUnitEditorProps {\n\t/** 列・行のどちらのエディターか。 */\n\tdirection: \"column\" | \"row\";\n\n\t/** 現在編集中の寸法。 */\n\tdimension: Dimension<GridUnit>;\n\n\t/** 列・行の現在サイズ(px)。局所単位変換に使用。 */\n\tcurrentPxSize: number;\n\n\t/** エディターを表示する座標(px)。 */\n\tposition: number;\n\n\t/** 左マージン(px)。絶対配置の基点。 */\n\tmarginLeftPx: number;\n\n\t/** 上マージン(px)。絶対配置の基点。 */\n\tmarginTopPx: number;\n\n\t/** 寸法変更を確定した際のコールバック。 */\n\tonChange: (dimension: Dimension<GridUnit>) => void;\n\n\t/** 編集をキャンセルした際のコールバック。 */\n\tonCancel: () => void;\n}\n\n// サポートする全単位の一覧\nconst SUPPORTED_UNITS: GridUnit[] = [\"fr\", \"px\", \"mm\", \"cm\", \"pt\", \"inch\"];\n\n// px を指定単位に変換するローカルヘルパー(fr 単位を除き各単位へ変換)\nfunction convertPxToUnit(pxSize: number, targetUnit: GridUnit): number {\n\tif (targetUnit === \"fr\") return 1;\n\tswitch (targetUnit) {\n\t\tcase \"px\":\n\t\t\treturn pxSize;\n\t\tcase \"mm\":\n\t\t\treturn Math.round(toMm.fromPx(pxSize) * 10) / 10;\n\t\tcase \"cm\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 10) * 100) / 100;\n\t\tcase \"inch\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 25.4) * 100) / 100;\n\t\tcase \"pt\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 25.4) * 72 * 10) / 10;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = targetUnit;\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * グリッド列・行の寸法を入力するインラインエディターコンポーネント。\n *\n * 単位切り替え時に値を局所変換する。\n */\nexport const GridUnitEditor = memo(\n\t({\n\t\tdirection,\n\t\tdimension,\n\t\tcurrentPxSize,\n\t\tposition,\n\t\tmarginLeftPx,\n\t\tmarginTopPx,\n\t\tonChange,\n\t\tonCancel,\n\t}: GridUnitEditorProps) => {\n\t\tconst [value, setValue] = useState(dimension.value.toString());\n\t\tconst [unit, setUnit] = useState<GridUnit>(dimension.unit as GridUnit);\n\t\tconst inputRef = useRef<HTMLInputElement>(null);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\n\t\tconst editorStyle: React.CSSProperties =\n\t\t\tdirection === \"column\"\n\t\t\t\t? {\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\n\t\t\t\t\t\ttop: `${marginTopPx + 24}px`,\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tleft: `${marginLeftPx + 24}px`,\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\n\t\t\t\t\t};\n\n\t\tuseEffect(() => {\n\t\t\tinputRef.current?.focus();\n\t\t\tinputRef.current?.select();\n\t\t}, []);\n\n\t\tuseEffect(() => {\n\t\t\tconst handleClickOutside = (event: MouseEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tcontainerRef.current &&\n\t\t\t\t\t!containerRef.current.contains(event.target as Node)\n\t\t\t\t) {\n\t\t\t\t\tonCancel();\n\t\t\t\t}\n\t\t\t};\n\t\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\n\t\t\treturn () =>\n\t\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\n\t\t}, [onCancel]);\n\n\t\tconst handleSubmit = () => {\n\t\t\tconst numValue = Number.parseFloat(value);\n\t\t\tif (!Number.isNaN(numValue) && numValue >= 0.1) {\n\t\t\t\tonChange({ unit, value: numValue });\n\t\t\t} else {\n\t\t\t\tonCancel();\n\t\t\t}\n\t\t};\n\n\t\tconst handleKeyDown = (e: React.KeyboardEvent) => {\n\t\t\tif (e.key === \"Enter\") {\n\t\t\t\te.preventDefault();\n\t\t\t\thandleSubmit();\n\t\t\t} else if (e.key === \"Escape\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tonCancel();\n\t\t\t}\n\t\t};\n\n\t\tconst handleUnitChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n\t\t\tconst newUnit = e.target.value as GridUnit;\n\t\t\tsetUnit(newUnit);\n\t\t\tsetValue(convertPxToUnit(currentPxSize, newUnit).toString());\n\t\t};\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={styles.editor}\n\t\t\t\tstyle={editorStyle}\n\t\t\t\tdata-testid={`grid-unit-editor-${direction}`}\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tref={inputRef}\n\t\t\t\t\ttype=\"number\"\n\t\t\t\t\tclassName={styles.input}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tonChange={(e) => setValue(e.target.value)}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\tmin=\"0.1\"\n\t\t\t\t\tstep={unit === \"fr\" ? \"0.1\" : \"1\"}\n\t\t\t\t/>\n\t\t\t\t<select\n\t\t\t\t\tclassName={styles.select}\n\t\t\t\t\tvalue={unit}\n\t\t\t\t\tonChange={handleUnitChange}\n\t\t\t\t>\n\t\t\t\t\t{SUPPORTED_UNITS.map((u) => (\n\t\t\t\t\t\t<option key={u} value={u}>\n\t\t\t\t\t\t\t{u}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</select>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={styles.button}\n\t\t\t\t\tonClick={handleSubmit}\n\t\t\t\t\ttitle=\"確定\"\n\t\t\t\t>\n\t\t\t\t\t✓\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nGridUnitEditor.displayName = \"GridUnitEditor\";\n","import { memo, useState } from \"react\";\n\nimport { toMm } from \"../../../../utils/convert\";\nimport styles from \"./GridDimensionLabel.module.css\";\nimport { GridUnitEditor } from \"./GridUnitEditor\";\n\nimport type { Dimension, GridUnit } from \"../../../../types/unit\";\n\n/**\n * `GridDimensionLabel` コンポーネントへの props。\n */\nexport interface GridDimensionLabelProps {\n\t/** 列・行のどちらのラベルを描画するか。 */\n\tdirection: \"column\" | \"row\";\n\n\t/** グリッド内のインデックス。 */\n\tindex: number;\n\n\t/** 現在の対象グリッド列・行の寸法。 */\n\tdimension: Dimension<GridUnit>;\n\n\t/** ラベルを表示する座標(px)。 */\n\tposition: number;\n\n\t/** 現在のグリッド列・行のサイズ(px)。局所单位変換に使用。 */\n\tcurrentPxSize: number;\n\n\t/** 左マージン(px)。絶対配置の基点。 */\n\tmarginLeftPx: number;\n\n\t/** 上マージン(px)。絶対配置の基点。 */\n\tmarginTopPx: number;\n\n\t/** `true` の場合はカーソルが近くにあるとみなしラベルを表示する。 */\n\tisNearCursor: boolean;\n\n\t/** リサイズ中の最新サイズ(px)。提供時は変化後の寸法をライブ表示する。 */\n\tresizingPxSize?: number;\n\n\t/** 寸法変更時のコールバック。 */\n\tonDimensionChange?: (\n\t\tdirection: \"column\" | \"row\",\n\t\tindex: number,\n\t\tdimension: Dimension<GridUnit>,\n\t) => void;\n}\n\n// px を指定単位に変換するヘルパー(fr は元値の比率で計算)\nfunction convertPxToUnit(\n\tpxSize: number,\n\ttargetUnit: GridUnit,\n\toriginalValue?: number,\n\toriginalPxSize?: number,\n): number {\n\tif (targetUnit === \"fr\") {\n\t\tif (\n\t\t\toriginalValue !== undefined &&\n\t\t\toriginalPxSize !== undefined &&\n\t\t\toriginalPxSize > 0\n\t\t) {\n\t\t\treturn Math.round(originalValue * (pxSize / originalPxSize) * 100) / 100;\n\t\t}\n\t\treturn 1;\n\t}\n\tswitch (targetUnit) {\n\t\tcase \"px\":\n\t\t\treturn Math.round(pxSize);\n\t\tcase \"mm\":\n\t\t\treturn Math.round(toMm.fromPx(pxSize) * 10) / 10;\n\t\tcase \"cm\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 10) * 100) / 100;\n\t\tcase \"inch\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 25.4) * 100) / 100;\n\t\tcase \"pt\":\n\t\t\treturn Math.round((toMm.fromPx(pxSize) / 25.4) * 72 * 10) / 10;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = targetUnit;\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n/**\n * グリッド列・行の寸法をラベル表示し、クリックで寸法編集を起動するコンポーネント。\n */\nexport const GridDimensionLabel = memo(\n\t({\n\t\tdirection,\n\t\tindex,\n\t\tdimension,\n\t\tposition,\n\t\tcurrentPxSize,\n\t\tmarginLeftPx,\n\t\tmarginTopPx,\n\t\tisNearCursor,\n\t\tresizingPxSize,\n\t\tonDimensionChange,\n\t}: GridDimensionLabelProps) => {\n\t\tconst [isEditing, setIsEditing] = useState(false);\n\n\t\tif (!isNearCursor && !isEditing) return null;\n\n\t\tconst labelStyle: React.CSSProperties =\n\t\t\tdirection === \"column\"\n\t\t\t\t? {\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\n\t\t\t\t\t\ttop: `${marginTopPx - 20}px`,\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tleft: `${marginLeftPx - 20}px`,\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\n\t\t\t\t\t\twritingMode: \"vertical-rl\",\n\t\t\t\t\t};\n\n\t\tconst formatDimension = (dim: Dimension<GridUnit>): string =>\n\t\t\tdim.unit === \"fr\" ? `${dim.value}fr` : `${dim.value}${dim.unit}`;\n\n\t\tconst displayText = resizingPxSize\n\t\t\t? (() => {\n\t\t\t\t\tconst v = convertPxToUnit(\n\t\t\t\t\t\tresizingPxSize,\n\t\t\t\t\t\tdimension.unit,\n\t\t\t\t\t\tdimension.value,\n\t\t\t\t\t\tcurrentPxSize,\n\t\t\t\t\t);\n\t\t\t\t\treturn dimension.unit === \"fr\" ? `${v}fr` : `${v}${dimension.unit}`;\n\t\t\t\t})()\n\t\t\t: formatDimension(dimension);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={styles.label}\n\t\t\t\t\tstyle={labelStyle}\n\t\t\t\t\tonDoubleClick={() => setIsEditing(true)}\n\t\t\t\t\tdata-testid={`grid-dimension-${direction}-${index}`}\n\t\t\t\t\taria-label={`グリッド寸法: ${displayText}`}\n\t\t\t\t>\n\t\t\t\t\t{displayText}\n\t\t\t\t</button>\n\t\t\t\t{isEditing && (\n\t\t\t\t\t<GridUnitEditor\n\t\t\t\t\t\tdirection={direction}\n\t\t\t\t\t\tdimension={dimension}\n\t\t\t\t\t\tcurrentPxSize={currentPxSize}\n\t\t\t\t\t\tposition={position}\n\t\t\t\t\t\tmarginLeftPx={marginLeftPx}\n\t\t\t\t\t\tmarginTopPx={marginTopPx}\n\t\t\t\t\t\tonChange={(newDim) => {\n\t\t\t\t\t\t\tonDimensionChange?.(direction, index, newDim);\n\t\t\t\t\t\t\tsetIsEditing(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCancel={() => setIsEditing(false)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t},\n);\n\nGridDimensionLabel.displayName = \"GridDimensionLabel\";\n","/**\n * 内側の列・行境界 px 座標配列から SVG グリッドライン用の `path d` 文字列を生成します。\n * @param colPxs - 内側列境界の x 座標配列(先頭・末尾の境界を除く)。\n * @param rowPxs - 内側行境界の y 座標配列(先頭・末尾の境界を除く)。\n * @param width - コンテンツ領域の幅(px)。\n * @param height - コンテンツ領域の高さ(px)。\n * @returns SVG `path` 要素の `d` 属性値。\n */\nexport function getGridPathD(\n\tcolPxs: number[],\n\trowPxs: number[],\n\twidth: number,\n\theight: number,\n): string {\n\tlet d = \"\";\n\tfor (const x of colPxs) d += `M ${x} 0 L ${x} ${height} `;\n\tfor (const y of rowPxs) d += `M 0 ${y} L ${width} ${y} `;\n\treturn d;\n}\n","import { type FC, memo, useMemo } from \"react\";\n\nimport { DEFAULT_DPI, toPx } from \"../../../utils/convert\";\nimport { Z_INDEX } from \"../../../utils/zIndex\";\nimport { getGridPathD } from \"./utils/getGridPathD\";\nimport { getStrokeDasharray } from \"./utils/getStrokeDasharray\";\n\nimport type { LineStyle } from \"../../../types/line\";\nimport type { GridPosPx, PaperContentPx } from \"./types\";\n\n/**\n * `GridOverlay` コンポーネントへの props。\n */\nexport interface GridOverlayProps {\n\t/** グリッド境界の px 座標配列。 */\n\tgridPosPx: GridPosPx;\n\n\t/** コンテンツ領域のサイズ(px)。 */\n\tcontentPx: PaperContentPx;\n\n\t/** 左マージン(px)。SVG の配置基点。 */\n\tmarginLeftPx: number;\n\n\t/** 上マージン(px)。SVG の配置基点。 */\n\tmarginTopPx: number;\n\n\t/** グリッド線のスタイル。省略時は描画しない。 */\n\tlineStyle?: LineStyle;\n\n\t/** z-index(既定値: `Z_INDEX.GRID_OVERLAY`)。 */\n\tzIndex?: number;\n\n\t/** DPI 値(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n}\n\n/**\n * グリッド線を SVG パスで描画するコンポーネント。\n *\n * `lineStyle` が未設定の場合は `null` を返します。\n */\nexport const GridOverlay: FC<GridOverlayProps> = memo(\n\t({\n\t\tgridPosPx,\n\t\tcontentPx,\n\t\tmarginLeftPx,\n\t\tmarginTopPx,\n\t\tlineStyle,\n\t\tzIndex = Z_INDEX.GRID_OVERLAY,\n\t\tdpi = DEFAULT_DPI,\n\t}) => {\n\t\tconst pathData = useMemo(\n\t\t\t() =>\n\t\t\t\tgetGridPathD(\n\t\t\t\t\tgridPosPx.cols.slice(1, -1),\n\t\t\t\t\tgridPosPx.rows.slice(1, -1),\n\t\t\t\t\tcontentPx.width,\n\t\t\t\t\tcontentPx.height,\n\t\t\t\t),\n\t\t\t[gridPosPx, contentPx],\n\t\t);\n\n\t\tif (!lineStyle) return null;\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tleft: `${marginLeftPx}px`,\n\t\t\t\t\ttop: `${marginTopPx}px`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\tzIndex,\n\t\t\t\t}}\n\t\t\t\twidth={contentPx.width}\n\t\t\t\theight={contentPx.height}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label=\"Grid overlay lines\"\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td={pathData}\n\t\t\t\t\tstroke={lineStyle.color}\n\t\t\t\t\tstrokeWidth={toPx.fromDim(lineStyle.width, dpi)}\n\t\t\t\t\tstrokeDasharray={getStrokeDasharray(lineStyle)}\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nGridOverlay.displayName = \"GridOverlay\";\n","import { type CSSProperties, memo, useCallback, useState } from \"react\";\n\nimport styles from \"./GridResizeHandle.module.css\";\n\n/**\n * `GridResizeHandle` コンポーネントへの props。\n */\nexport interface GridResizeHandleProps {\n\t/** リサイズ対象の方向。 */\n\tdirection: \"column\" | \"row\";\n\n\t/** グリッド内のインデックス。 */\n\tindex: number;\n\n\t/** ハンドルを表示する座標(px)。 */\n\tposition: number;\n\n\t/** 左マージン(px)。絶対配置の基点。 */\n\tmarginLeftPx: number;\n\n\t/** 上マージン(px)。絶対配置の基点。 */\n\tmarginTopPx: number;\n\n\t/** ドラッグ開始時に呼び出されるコールバック。 */\n\tonResizeStart?: (direction: \"column\" | \"row\", index: number) => void;\n\n\t/** ドラッグ中に呼び出されるコールバック。 */\n\tonResize?: (\n\t\tdirection: \"column\" | \"row\",\n\t\tindex: number,\n\t\tdelta: number,\n\t) => void;\n\n\t/** ドラッグ終了時に呼び出されるコールバック。 */\n\tonResizeEnd?: (\n\t\tdirection: \"column\" | \"row\",\n\t\tindex: number,\n\t\tdelta: number,\n\t) => void;\n}\n\n/**\n * グリッド列・行のリサイズ操作ハンドルコンポーネント。\n *\n * ポインターイベントを直接受け取り、デルタ値を親に通知します。\n */\nexport const GridResizeHandle = memo(\n\t({\n\t\tdirection,\n\t\tindex,\n\t\tposition,\n\t\tmarginLeftPx,\n\t\tmarginTopPx,\n\t\tonResizeStart,\n\t\tonResize,\n\t\tonResizeEnd,\n\t}: GridResizeHandleProps) => {\n\t\tconst [isDragging, setIsDragging] = useState(false);\n\n\t\tconst HANDLE_SIZE = 12;\n\t\tconst HANDLE_OFFSET = HANDLE_SIZE / 2;\n\n\t\tconst handleStyle: CSSProperties =\n\t\t\tdirection === \"column\"\n\t\t\t\t? {\n\t\t\t\t\t\tleft: `${marginLeftPx + position - HANDLE_OFFSET}px`,\n\t\t\t\t\t\ttop: `${marginTopPx - HANDLE_OFFSET}px`,\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\tcursor: \"col-resize\",\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tleft: `${marginLeftPx - HANDLE_OFFSET}px`,\n\t\t\t\t\t\ttop: `${marginTopPx + position - HANDLE_OFFSET}px`,\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\tcursor: \"row-resize\",\n\t\t\t\t\t};\n\n\t\tconst handlePointerDown = useCallback(\n\t\t\t(e: React.PointerEvent) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\te.preventDefault();\n\n\t\t\t\tconst initialPos = direction === \"column\" ? e.clientX : e.clientY;\n\t\t\t\tsetIsDragging(true);\n\t\t\t\tonResizeStart?.(direction, index);\n\n\t\t\t\tconst handlePointerMove = (moveEvent: PointerEvent) => {\n\t\t\t\t\tconst currentPos =\n\t\t\t\t\t\tdirection === \"column\" ? moveEvent.clientX : moveEvent.clientY;\n\t\t\t\t\tonResize?.(direction, index, currentPos - initialPos);\n\t\t\t\t};\n\n\t\t\t\tconst handlePointerUp = (upEvent: PointerEvent) => {\n\t\t\t\t\tconst currentPos =\n\t\t\t\t\t\tdirection === \"column\" ? upEvent.clientX : upEvent.clientY;\n\t\t\t\t\tsetIsDragging(false);\n\t\t\t\t\tonResizeEnd?.(direction, index, currentPos - initialPos);\n\t\t\t\t\twindow.removeEventListener(\"pointermove\", handlePointerMove);\n\t\t\t\t\twindow.removeEventListener(\"pointerup\", handlePointerUp);\n\t\t\t\t};\n\n\t\t\t\twindow.addEventListener(\"pointermove\", handlePointerMove);\n\t\t\t\twindow.addEventListener(\"pointerup\", handlePointerUp);\n\t\t\t},\n\t\t\t[direction, index, onResizeStart, onResize, onResizeEnd],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={`${styles.handle} ${isDragging ? styles.dragging : \"\"}`}\n\t\t\t\tstyle={handleStyle}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tdata-testid={`grid-resize-handle-${direction}-${index}`}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nGridResizeHandle.displayName = \"GridResizeHandle\";\n","import { type CSSProperties, type FC, memo } from \"react\";\n\nimport { Z_INDEX } from \"../../../utils/zIndex\";\n\nimport type { PaperPx } from \"./types\";\n\n/**\n * `MarginOverlay` コンポーネントへの props。\n */\nexport interface MarginOverlayProps {\n\t/** 用紙全体のサイズ・マージン・コンテンツ領域情報(px)。 */\n\tpaperPx: PaperPx;\n\n\t/** マージン領域背景色(既定値: 半透明の黒)。 */\n\tmarginColor?: string;\n\n\t/** z-index(既定値: `Z_INDEX.MARGIN_OVERLAY`)。 */\n\tzIndex?: number;\n}\n\n/**\n * 用紙四辺のマージン領域に半透明のオーバーレイを描画するコンポーネント。\n */\nexport const MarginOverlay: FC<MarginOverlayProps> = memo(\n\t({\n\t\tpaperPx,\n\t\tmarginColor = \"rgba(0, 0, 0, 0.05)\",\n\t\tzIndex = Z_INDEX.MARGIN_OVERLAY,\n\t}) => {\n\t\tconst side: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tbackgroundColor: marginColor,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\trole=\"presentation\"\n\t\t\t\taria-label=\"Printable area margin\"\n\t\t\t\tdata-testid=\"margin-overlay\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tinset: 0,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\twidth: `${paperPx.canvas.width}px`,\n\t\t\t\t\theight: `${paperPx.canvas.height}px`,\n\t\t\t\t\tzIndex,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{paperPx.margin.top > 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"margin-top\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t...side,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\theight: `${paperPx.margin.top}px`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{paperPx.margin.bottom > 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"margin-bottom\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t...side,\n\t\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\theight: `${paperPx.margin.bottom}px`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{paperPx.margin.left > 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"margin-left\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t...side,\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\n\t\t\t\t\t\t\twidth: `${paperPx.margin.left}px`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{paperPx.margin.right > 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"margin-right\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t...side,\n\t\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\n\t\t\t\t\t\t\twidth: `${paperPx.margin.right}px`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nMarginOverlay.displayName = \"MarginOverlay\";\n","import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { Z_INDEX } from \"../../../utils/zIndex\";\nimport { BorderOverlay } from \"./BorderOverlay\";\nimport { GridCanvas } from \"./GridCanvas\";\nimport { GridDimensionLabel } from \"./GridDimensionLabel/GridDimensionLabel\";\nimport { GridOverlay } from \"./GridOverlay\";\nimport { GridResizeHandle } from \"./GridResizeHandle/GridResizeHandle\";\nimport { MarginOverlay } from \"./MarginOverlay\";\n\nimport type { BorderStyle, LineStyle } from \"../../../types/line\";\nimport type { Dimension, GridUnit } from \"../../../types/unit\";\nimport type { GridPosPx, PaperPx } from \"./types\";\n\n/**\n * `GridLayer` コンポーネントへの props。\n *\n * @remarks\n * **Advanced use only.** `Note` キャンバスの低レベルビルディングブロックです。通常の利用では {@link Note} を使用してください。\n */\nexport interface GridLayerProps {\n\t/** 用紙全体の px サイズ情報(キャンバス・マージン・コンテンツ)。 */\n\tpaperPx: PaperPx;\n\n\t/** グリッド境界の px 座標配列。 */\n\tgridPosPx: GridPosPx;\n\n\t/** グリッド各列・行の寸法定義。省略時は寸法ラベルを非表示にする。 */\n\tgridDimensions?: {\n\t\tcols: Array<Dimension<GridUnit>>;\n\t\trows: Array<Dimension<GridUnit>>;\n\t};\n\n\t/** グリッド線のスタイル。省略時は描画しない。 */\n\tgridLineStyle?: LineStyle;\n\n\t/** 用紙枠線のスタイル。省略時は描画しない。 */\n\tborderStyle?: BorderStyle;\n\n\t/** 用紙背景色(既定値: `\"#ffffff\"`)。 */\n\tbackgroundColor?: string;\n\n\t/** 用紙の `box-shadow` CSS 値。 */\n\tboxShadow?: string;\n\n\t/** マージン領域の背景色。 */\n\tmarginFillColor?: string;\n\n\t/** グリッド線を表示するか。 */\n\tshowGridLines?: boolean;\n\n\t/** マージン領域のオーバーレイを表示するか。 */\n\tshowMargins?: boolean;\n\n\t/** 用紙枠線を表示するか。 */\n\tshowBorder?: boolean;\n\n\t/** リサイズハンドルを表示するか。 */\n\tshowResizeHandles?: boolean;\n\n\t/** 寸法ラベルを表示するか。 */\n\tshowDimensionLabels?: boolean;\n\n\t/** DPI 値(既定値: `DEFAULT_DPI`)。 */\n\tdpi?: number;\n\n\t/** グリッドのリサイズ操作時のコールバック。 */\n\tonGridResize?: (\n\t\tdirection: \"column\" | \"row\",\n\t\tindex: number,\n\t\tdelta: number,\n\t) => void;\n\n\t/** 寸法単位変更時のコールバック。 */\n\tonDimensionChange?: (\n\t\tdirection: \"column\" | \"row\",\n\t\tindex: number,\n\t\tdimension: Dimension<GridUnit>,\n\t) => void;\n\n\t/** ルート要素の CSS クラス名。 */\n\tclassName?: string;\n\n\t/** 各子コンポーネントの z-index 上書き。 */\n\tzIndex?: {\n\t\tcanvas?: number;\n\t\tmargin?: number;\n\t\tgrid?: number;\n\t\tborder?: number;\n\t};\n}\n\n/**\n * グリッド・用紙枠線・マージンおよびリサイズ UI をまとめて描画するレイヤーコンポーネント。\n *\n * @remarks\n * **Advanced use only.** `Note` キャンバスの低レベルビルディングブロックです。通常の利用では {@link Note} を使用してください。\n */\nexport const GridLayer: React.FC<GridLayerProps> = memo(\n\t({\n\t\tpaperPx,\n\t\tgridPosPx,\n\t\tgridDimensions,\n\t\tgridLineStyle,\n\t\tborderStyle,\n\t\tbackgroundColor = \"#ffffff\",\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\n\t\tmarginFillColor,\n\t\tshowGridLines = true,\n\t\tshowMargins = true,\n\t\tshowBorder = true,\n\t\tshowResizeHandles = false,\n\t\tshowDimensionLabels = false,\n\t\tdpi = DEFAULT_DPI,\n\t\tonGridResize,\n\t\tonDimensionChange,\n\t\tclassName = \"\",\n\t\tzIndex = {},\n\t}) => {\n\t\tconst [ghostLine, setGhostLine] = useState<{\n\t\t\tdirection: \"column\" | \"row\";\n\t\t\tposition: number;\n\t\t} | null>(null);\n\t\tconst [draggingHandle, setDraggingHandle] = useState<{\n\t\t\tdirection: \"column\" | \"row\";\n\t\t\tindex: number;\n\t\t} | null>(null);\n\t\tconst [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\n\t\tuseEffect(() => {\n\t\t\tconst handleMouseMove = (e: MouseEvent) => {\n\t\t\t\tif (!containerRef.current) return;\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\n\t\t\t\tsetMousePos({ x: e.clientX - rect.left, y: e.clientY - rect.top });\n\t\t\t};\n\t\t\tconst handleMouseLeave = (e: MouseEvent) => {\n\t\t\t\tif (!containerRef.current) return;\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\n\t\t\t\tif (\n\t\t\t\t\te.clientX < rect.left ||\n\t\t\t\t\te.clientX > rect.right ||\n\t\t\t\t\te.clientY < rect.top ||\n\t\t\t\t\te.clientY > rect.bottom\n\t\t\t\t) {\n\t\t\t\t\tsetMousePos(null);\n\t\t\t\t}\n\t\t\t};\n\t\t\twindow.addEventListener(\"mousemove\", handleMouseMove);\n\t\t\twindow.addEventListener(\"mouseleave\", handleMouseLeave);\n\t\t\treturn () => {\n\t\t\t\twindow.removeEventListener(\"mousemove\", handleMouseMove);\n\t\t\t\twindow.removeEventListener(\"mouseleave\", handleMouseLeave);\n\t\t\t};\n\t\t}, []);\n\n\t\tconst shouldShowDimensionLabels = useMemo(() => {\n\t\t\tif (!mousePos) return false;\n\t\t\tconst isInsideCanvas =\n\t\t\t\tmousePos.x >= paperPx.margin.left &&\n\t\t\t\tmousePos.x <= paperPx.margin.left + paperPx.content.width &&\n\t\t\t\tmousePos.y >= paperPx.margin.top &&\n\t\t\t\tmousePos.y <= paperPx.margin.top + paperPx.content.height;\n\t\t\treturn !isInsideCanvas;\n\t\t}, [mousePos, paperPx]);\n\n\t\tconst resizingPreviewSizes = useMemo(() => {\n\t\t\tif (!ghostLine || !draggingHandle) return null;\n\t\t\tconst gridLines =\n\t\t\t\tdraggingHandle.direction === \"column\" ? gridPosPx.cols : gridPosPx.rows;\n\t\t\tconst index = draggingHandle.index;\n\t\t\tconst prevStart = gridLines[index - 1];\n\t\t\tconst nextEnd = gridLines[index + 1];\n\t\t\treturn {\n\t\t\t\tdirection: draggingHandle.direction,\n\t\t\t\tprevIndex: index - 1,\n\t\t\t\tprevSize: prevStart !== undefined ? ghostLine.position - prevStart : 0,\n\t\t\t\tnextIndex: index,\n\t\t\t\tnextSize: nextEnd !== undefined ? nextEnd - ghostLine.position : 0,\n\t\t\t};\n\t\t}, [ghostLine, draggingHandle, gridPosPx]);\n\n\t\tconst clampDelta = useCallback(\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number): number => {\n\t\t\t\tconst MIN_GAP = 10;\n\t\t\t\tconst gridLines =\n\t\t\t\t\tdirection === \"column\" ? gridPosPx.cols : gridPosPx.rows;\n\t\t\t\tconst originalPos = gridLines[index];\n\t\t\t\tif (originalPos === undefined) return delta;\n\t\t\t\tconst prevLinePos = gridLines[index - 1];\n\t\t\t\tconst nextLinePos = gridLines[index + 1];\n\t\t\t\tlet clamped = delta;\n\t\t\t\tif (prevLinePos !== undefined)\n\t\t\t\t\tclamped = Math.max(clamped, prevLinePos + MIN_GAP - originalPos);\n\t\t\t\tif (nextLinePos !== undefined)\n\t\t\t\t\tclamped = Math.min(clamped, nextLinePos - MIN_GAP - originalPos);\n\t\t\t\treturn clamped;\n\t\t\t},\n\t\t\t[gridPosPx],\n\t\t);\n\n\t\tconst handleResizeStart = useCallback(\n\t\t\t(direction: \"column\" | \"row\", index: number) => {\n\t\t\t\tsetDraggingHandle({ direction, index });\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst handleResize = useCallback(\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\n\t\t\t\tconst gridLines =\n\t\t\t\t\tdirection === \"column\" ? gridPosPx.cols : gridPosPx.rows;\n\t\t\t\tconst originalPos = gridLines[index];\n\t\t\t\tif (originalPos === undefined) return;\n\t\t\t\tsetGhostLine({\n\t\t\t\t\tdirection,\n\t\t\t\t\tposition: originalPos + clampDelta(direction, index, delta),\n\t\t\t\t});\n\t\t\t},\n\t\t\t[gridPosPx, clampDelta],\n\t\t);\n\n\t\tconst handleResizeEnd = useCallback(\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\n\t\t\t\tsetGhostLine(null);\n\t\t\t\tsetDraggingHandle(null);\n\t\t\t\tonGridResize?.(direction, index, clampDelta(direction, index, delta));\n\t\t\t},\n\t\t\t[clampDelta, onGridResize],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{ position: \"relative\", width: \"100%\", height: \"100%\" }}\n\t\t\t>\n\t\t\t\t<GridCanvas\n\t\t\t\t\tcanvasPx={paperPx.canvas}\n\t\t\t\t\tbackgroundColor={backgroundColor}\n\t\t\t\t\tboxShadow={boxShadow}\n\t\t\t\t\tzIndex={zIndex.canvas ?? Z_INDEX.GRID_CANVAS}\n\t\t\t\t/>\n\n\t\t\t\t{showMargins && (\n\t\t\t\t\t<MarginOverlay\n\t\t\t\t\t\tpaperPx={paperPx}\n\t\t\t\t\t\tmarginColor={marginFillColor}\n\t\t\t\t\t\tzIndex={zIndex.margin ?? Z_INDEX.MARGIN_OVERLAY}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t\t{showGridLines && (\n\t\t\t\t\t<GridOverlay\n\t\t\t\t\t\tgridPosPx={gridPosPx}\n\t\t\t\t\t\tcontentPx={paperPx.content}\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\tlineStyle={gridLineStyle}\n\t\t\t\t\t\tdpi={dpi}\n\t\t\t\t\t\tzIndex={zIndex.grid ?? Z_INDEX.GRID_OVERLAY}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t\t{showBorder && (\n\t\t\t\t\t<BorderOverlay\n\t\t\t\t\t\tcontentPx={paperPx.content}\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\tborderStyle={borderStyle}\n\t\t\t\t\t\tdpi={dpi}\n\t\t\t\t\t\tzIndex={zIndex.border ?? Z_INDEX.BORDER_OVERLAY}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\n\t\t\t\t{showResizeHandles && onGridResize && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{gridPosPx.cols.map((colPos, index) => {\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPx.cols.length - 1)\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<GridResizeHandle\n\t\t\t\t\t\t\t\t\tkey={`col-${colPos}`}\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\tposition={colPos}\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{gridPosPx.rows.map((rowPos, index) => {\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPx.rows.length - 1)\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<GridResizeHandle\n\t\t\t\t\t\t\t\t\tkey={`row-${rowPos}`}\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\tposition={rowPos}\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\n\t\t\t\t{showDimensionLabels && gridDimensions && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{gridDimensions.cols.map((dimension, index) => {\n\t\t\t\t\t\t\tconst startPos = gridPosPx.cols[index];\n\t\t\t\t\t\t\tconst endPos = gridPosPx.cols[index + 1];\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\n\t\t\t\t\t\t\tconst isDraggingAdjacent =\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"column\" &&\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\n\t\t\t\t\t\t\tlet resizingPxSize: number | undefined;\n\t\t\t\t\t\t\tif (resizingPreviewSizes?.direction === \"column\") {\n\t\t\t\t\t\t\t\tif (resizingPreviewSizes.prevIndex === index)\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.prevSize;\n\t\t\t\t\t\t\t\telse if (resizingPreviewSizes.nextIndex === index)\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.nextSize;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<GridDimensionLabel\n\t\t\t\t\t\t\t\t\tkey={`col-dim-${startPos}`}\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\tdimension={dimension}\n\t\t\t\t\t\t\t\t\tposition={(startPos + endPos) / 2}\n\t\t\t\t\t\t\t\t\tcurrentPxSize={endPos - startPos}\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\t\t\t\tisNearCursor={shouldShowDimensionLabels || isDraggingAdjacent}\n\t\t\t\t\t\t\t\t\tresizingPxSize={resizingPxSize}\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{gridDimensions.rows.map((dimension, index) => {\n\t\t\t\t\t\t\tconst startPos = gridPosPx.rows[index];\n\t\t\t\t\t\t\tconst endPos = gridPosPx.rows[index + 1];\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\n\t\t\t\t\t\t\tconst isDraggingAdjacent =\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"row\" &&\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\n\t\t\t\t\t\t\tlet resizingPxSize: number | undefined;\n\t\t\t\t\t\t\tif (resizingPreviewSizes?.direction === \"row\") {\n\t\t\t\t\t\t\t\tif (resizingPreviewSizes.prevIndex === index)\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.prevSize;\n\t\t\t\t\t\t\t\telse if (resizingPreviewSizes.nextIndex === index)\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.nextSize;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<GridDimensionLabel\n\t\t\t\t\t\t\t\t\tkey={`row-dim-${startPos}`}\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\tdimension={dimension}\n\t\t\t\t\t\t\t\t\tposition={(startPos + endPos) / 2}\n\t\t\t\t\t\t\t\t\tcurrentPxSize={endPos - startPos}\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\n\t\t\t\t\t\t\t\t\tisNearCursor={shouldShowDimensionLabels || isDraggingAdjacent}\n\t\t\t\t\t\t\t\t\tresizingPxSize={resizingPxSize}\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\n\t\t\t\t{ghostLine && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\tleft:\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\n\t\t\t\t\t\t\t\t\t? paperPx.margin.left + ghostLine.position\n\t\t\t\t\t\t\t\t\t: paperPx.margin.left,\n\t\t\t\t\t\t\ttop:\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\"\n\t\t\t\t\t\t\t\t\t? paperPx.margin.top + ghostLine.position\n\t\t\t\t\t\t\t\t\t: paperPx.margin.top,\n\t\t\t\t\t\t\twidth:\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\n\t\t\t\t\t\t\t\t\t? \"2px\"\n\t\t\t\t\t\t\t\t\t: paperPx.content.width,\n\t\t\t\t\t\t\theight:\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\" ? \"2px\" : paperPx.content.height,\n\t\t\t\t\t\t\tbackgroundColor: \"#3b82f6\",\n\t\t\t\t\t\t\topacity: 0.5,\n\t\t\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\t\t\tzIndex: Z_INDEX.GRID_GHOST,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nGridLayer.displayName = \"GridLayer\";\n","import { useState } from \"react\";\n\nimport type { InteractionState } from \"../types\";\n\n/**\n * `InteractionLayer` に渡す `state` と `onStateChange` を提供する。\n *\n * @example\n * ```tsx\n * const [state, onStateChange] = useInteractionState();\n * return <InteractionLayer state={state} onStateChange={onStateChange} ... />;\n * ```\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} の `state` / `onStateChange` を提供するシンプルなフック。\n */\nexport function useInteractionState(initialState?: Partial<InteractionState>) {\n\treturn useState<InteractionState>({\n\t\teditingBlockId: null,\n\t\t...initialState,\n\t});\n}\n","/**\n * インタラクションモード(dragging/editingBlockId から導出)\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} の動作モード列挙型。\n */\nexport enum InteractionMode {\n\tIDLE = \"idle\",\n\tPRESSING = \"pressing\",\n\tDRAGGING = \"dragging\",\n\tINSERT = \"insert\",\n\tEDITING = \"editing\",\n}\n\n/**\n * リサイズハンドル方向(8方向)\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} のリサイズハンドル方向。\n */\nexport enum ResizeHandle {\n\tN = \"n\",\n\tNE = \"ne\",\n\tE = \"e\",\n\tSE = \"se\",\n\tS = \"s\",\n\tSW = \"sw\",\n\tW = \"w\",\n\tNW = \"nw\",\n}\n\n/**\n * ドラッグ種別\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} のドラッグ種別。\n */\nexport enum DragType {\n\tMOVE = \"move\",\n\tRESIZE = \"resize\",\n\tINSERT = \"insert\",\n}\n\n/**\n * ドラッグ中の詳細状態\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} のドラッグ中状態型。\n */\nexport interface DraggingState {\n\ttype: DragType;\n\tblockIds: string[];\n\tstartGrid: { col: number; row: number };\n\tcurrentGrid: { col: number; row: number };\n\t/** マウスの現在座標 (px, キャンバス相対)。キャンバス外ゴースト表示用 */\n\tcurrentMousePx?: { x: number; y: number };\n\t/** リサイズ用ハンドル方向 */\n\thandle?: ResizeHandle;\n\t/** 挿入用: プラグイン種別 */\n\tpluginKind?: string;\n\t/** 挿入用: デフォルトサイズ */\n\tdefaultSize?: { w: number; h: number };\n\t/** キャンバス外フラグ */\n\tisOutside?: boolean;\n}\n\n/**\n * インタラクション状態(外部で管理する controlled state)\n *\n * - 選択状態 (`selectedBlockIds`) は外部で管理されるため含まない\n * - モード (`InteractionMode`) は `editingBlockId` と `dragging` から導出する\n *\n * @remarks\n * **Canvas** — {@link InteractionLayer} に渡す制御状態型。\n */\nexport interface InteractionState {\n\t/** 編集中ブロックID。null = 非編集 */\n\teditingBlockId: string | null;\n\t/** ドラッグ中状態 */\n\tdragging?: DraggingState;\n}\n\n/**\n * `InteractionState` から現在モードを導出する\n *\n * @remarks\n * **Canvas** — {@link InteractionState} から動作モードを導出するユーティリティ。\n */\nexport function getInteractionMode(state: InteractionState): InteractionMode {\n\tif (state.editingBlockId !== null) return InteractionMode.EDITING;\n\tif (state.dragging) {\n\t\tif (state.dragging.type === DragType.INSERT) return InteractionMode.INSERT;\n\t\tif (state.dragging.type === DragType.RESIZE)\n\t\t\treturn InteractionMode.DRAGGING;\n\t\tconst gridChanged =\n\t\t\tstate.dragging.currentGrid.col !== state.dragging.startGrid.col ||\n\t\t\tstate.dragging.currentGrid.row !== state.dragging.startGrid.row;\n\t\treturn gridChanged ? InteractionMode.DRAGGING : InteractionMode.PRESSING;\n\t}\n\treturn InteractionMode.IDLE;\n}\n","// リサイズ後レイアウト計算\n\nimport { ResizeHandle } from \"../types\";\n\n/**\n * リサイズ計算に必要なブロックのレイアウト情報(グリッド単位)。\n */\nexport interface BlockLayout {\n\t/** 左端の列インデックス。 */\n\tx: number;\n\n\t/** 上端の行インデックス。 */\n\ty: number;\n\n\t/** 幅(グリッド列数)。 */\n\tw: number;\n\n\t/** 高さ(グリッド行数)。 */\n\th: number;\n}\n\n/**\n * `calculateResizedLayout` への入力パラメータ。\n */\nexport interface ResizeParams {\n\t/** リサイズ前のブロックレイアウト。 */\n\tlayout: BlockLayout;\n\n\t/** 操作したリサイズハンドルの方向。 */\n\thandle: ResizeHandle;\n\n\t/** 列方向のドラッグデルタ(グリッド列数)。 */\n\tdeltaCol: number;\n\n\t/** 行方向のドラッグデルタ(グリッド行数)。 */\n\tdeltaRow: number;\n\n\t/** グリッドの列数。境界クランプに使用。 */\n\tgridCols: number;\n\n\t/** グリッドの行数。境界クランプに使用。 */\n\tgridRows: number;\n}\n\n/**\n * リサイズ後のレイアウトを計算する(最小 1x1、グリッド範囲内にクランプ)。\n */\nexport function calculateResizedLayout({\n\tlayout,\n\thandle,\n\tdeltaCol,\n\tdeltaRow,\n\tgridCols,\n\tgridRows,\n}: ResizeParams): BlockLayout {\n\tconst newLayout = { ...layout };\n\n\t// --- 横方向 ---\n\tif (\n\t\thandle === ResizeHandle.E ||\n\t\thandle === ResizeHandle.NE ||\n\t\thandle === ResizeHandle.SE\n\t) {\n\t\tconst maxW = gridCols - layout.x;\n\t\tnewLayout.w = Math.max(1, Math.min(layout.w + deltaCol, maxW));\n\t} else if (\n\t\thandle === ResizeHandle.W ||\n\t\thandle === ResizeHandle.NW ||\n\t\thandle === ResizeHandle.SW\n\t) {\n\t\tconst maxShrink = layout.w - 1;\n\t\tconst validDCol = deltaCol > 0 ? Math.min(deltaCol, maxShrink) : deltaCol;\n\t\tif (layout.x + validDCol >= 0) {\n\t\t\tnewLayout.x = layout.x + validDCol;\n\t\t\tnewLayout.w = layout.w - validDCol;\n\t\t} else {\n\t\t\tnewLayout.x = 0;\n\t\t\tnewLayout.w = layout.w + layout.x;\n\t\t}\n\t}\n\n\t// --- 縦方向 ---\n\tif (\n\t\thandle === ResizeHandle.S ||\n\t\thandle === ResizeHandle.SE ||\n\t\thandle === ResizeHandle.SW\n\t) {\n\t\tconst maxH = gridRows - layout.y;\n\t\tnewLayout.h = Math.max(1, Math.min(layout.h + deltaRow, maxH));\n\t} else if (\n\t\thandle === ResizeHandle.N ||\n\t\thandle === ResizeHandle.NE ||\n\t\thandle === ResizeHandle.NW\n\t) {\n\t\tconst maxShrink = layout.h - 1;\n\t\tconst validDRow = deltaRow > 0 ? Math.min(deltaRow, maxShrink) : deltaRow;\n\t\tif (layout.y + validDRow >= 0) {\n\t\t\tnewLayout.y = layout.y + validDRow;\n\t\t\tnewLayout.h = layout.h - validDRow;\n\t\t} else {\n\t\t\tnewLayout.y = 0;\n\t\t\tnewLayout.h = layout.h + layout.y;\n\t\t}\n\t}\n\n\treturn newLayout;\n}\n","import type { Block } from \"../../../../types/block\";\n\n/**\n * 複数ブロックの移動クランプ結果。\n */\nexport interface ClampedBlockPosition {\n\t/** 対象ブロックの ID。 */\n\tblockId: string;\n\n\t/** クランプ後の列インデックス。 */\n\tx: number;\n\n\t/** クランプ後の行インデックス。 */\n\ty: number;\n}\n\n/**\n * 複数ブロックの移動をグリッド範囲内にクランプする。\n *\n * バウンディングボックス全体を基準にクランプするため、相対位置関係が保たれる。\n */\nexport function clampMultipleBlocks(\n\tblocks: Block[],\n\tdeltaCol: number,\n\tdeltaRow: number,\n\tgridCols: number,\n\tgridRows: number,\n): ClampedBlockPosition[] {\n\tif (blocks.length === 0) return [];\n\n\tif (blocks.length === 1) {\n\t\tconst block = blocks[0];\n\t\tif (!block) return [];\n\t\tconst maxX = gridCols - block.layout.w;\n\t\tconst maxY = gridRows - block.layout.h;\n\t\treturn [\n\t\t\t{\n\t\t\t\tblockId: block.id,\n\t\t\t\tx: Math.max(0, Math.min(block.layout.x + deltaCol, maxX)),\n\t\t\t\ty: Math.max(0, Math.min(block.layout.y + deltaRow, maxY)),\n\t\t\t},\n\t\t];\n\t}\n\n\t// バウンディングボックスで一括クランプ\n\tconst minX = Math.min(...blocks.map((b) => b.layout.x));\n\tconst minY = Math.min(...blocks.map((b) => b.layout.y));\n\tconst maxBoundX = Math.max(...blocks.map((b) => b.layout.x + b.layout.w));\n\tconst maxBoundY = Math.max(...blocks.map((b) => b.layout.y + b.layout.h));\n\n\tconst boundW = maxBoundX - minX;\n\tconst boundH = maxBoundY - minY;\n\n\tconst clampedMinX = Math.max(0, Math.min(minX + deltaCol, gridCols - boundW));\n\tconst clampedMinY = Math.max(0, Math.min(minY + deltaRow, gridRows - boundH));\n\n\tconst actualDeltaCol = clampedMinX - minX;\n\tconst actualDeltaRow = clampedMinY - minY;\n\n\treturn blocks.map((block) => ({\n\t\tblockId: block.id,\n\t\tx: block.layout.x + actualDeltaCol,\n\t\ty: block.layout.y + actualDeltaRow,\n\t}));\n}\n","import { createBlockId } from \"../../../../utils/block\";\n\nimport type { Block, BlockPos, BlockSize } from \"../../../../types/block\";\n\ninterface BlockFactoryPlugin {\n\tkind: string;\n\tmeta: {\n\t\tdisplayName?: string;\n\t\tdefaultSize?: BlockSize;\n\t};\n}\n\n/**\n * プラグインとグリッド位置から新規 `Block` を生成する。\n *\n * - `w/h` は `plugin.meta.defaultSize` から取得(未設定なら 1x1)\n * - `props` は空オブジェクト(resolveBlockProps が後でデフォルトを補完する)\n */\nexport function createBlock(\n\tplugin: BlockFactoryPlugin,\n\tposition: BlockPos,\n): Block {\n\treturn {\n\t\tid: createBlockId(plugin.kind),\n\t\tkind: plugin.kind,\n\t\tlayout: {\n\t\t\tx: position.x,\n\t\t\ty: position.y,\n\t\t\tw: plugin.meta.defaultSize?.w ?? 1,\n\t\t\th: plugin.meta.defaultSize?.h ?? 1,\n\t\t},\n\t\tprops: {},\n\t};\n}\n","import { type CSSProperties, memo } from \"react\";\n\nimport { LineType } from \"../../../types/line\";\nimport { NoteMode } from \"../../../types/mode\";\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { BLOCK_SUB_INDEX, Z_INDEX } from \"../../../utils/zIndex\";\nimport { BlockBorder } from \"../BlockLayer/BlockBorder\";\nimport { BlockCanvas } from \"../BlockLayer/BlockCanvas\";\nimport { BlockGuideBorder } from \"../BlockLayer/BlockGuideBorder\";\nimport { BlockRenderer } from \"../BlockLayer/BlockRenderer\";\nimport { resolveBlockProps } from \"../BlockLayer/utils/resolveBlockProps\";\nimport { DragType as DT } from \"./types\";\nimport { calculateResizedLayout } from \"./utils/calcResize\";\nimport { clampMultipleBlocks } from \"./utils/clampMultipleBlocks\";\nimport { createBlock } from \"./utils/createBlock\";\n\nimport type { PluginRegistry, ResolvedPlugin } from \"../../../plugin/registry\";\nimport type { Block } from \"../../../types/block\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockDefaults } from \"../../../types/schema\";\nimport type { BlockRectPx } from \"../types\";\nimport type { DraggingState, ResizeHandle } from \"./types\";\n\n// ゴーストブロック用のガイド枠線(破線・太め)\nconst GHOST_GUIDE_BORDER: BorderStyle = {\n\ttop: {\n\t\tcolor: \"#888888\",\n\t\twidth: { value: 3, unit: \"px\" },\n\t\ttype: LineType.DASHED,\n\t},\n\tright: {\n\t\tcolor: \"#888888\",\n\t\twidth: { value: 3, unit: \"px\" },\n\t\ttype: LineType.DASHED,\n\t},\n\tbottom: {\n\t\tcolor: \"#888888\",\n\t\twidth: { value: 3, unit: \"px\" },\n\t\ttype: LineType.DASHED,\n\t},\n\tleft: {\n\t\tcolor: \"#888888\",\n\t\twidth: { value: 3, unit: \"px\" },\n\t\ttype: LineType.DASHED,\n\t},\n};\n\n/**\n * `DragLayer` コンポーネントへの props。\n */\nexport interface DragLayerProps {\n\t/** 全ブロックのデータ一覧。ゴースト描画の元データとして使用。 */\n\tblocks: Block[];\n\n\t/** プラグインレジストリ。 */\n\tpluginRegistry: PluginRegistry;\n\n\t/** グリッドの列数・行数。 */\n\tgridLength: { cols: number; rows: number };\n\n\t/** ドラッグ中の状態。`undefined` の場合は描画しない。 */\n\tdraggingState: DraggingState | undefined;\n\n\t/** ブロックからキャンバス上の矩形座標(px)を返す関数。 */\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\n\n\t/** ブロックのデフォルト値設定。 */\n\tblockDefaults?: BlockDefaults;\n\n\t/** 選択枠線スタイル。 */\n\tselectionStyle?: BorderStyle;\n\n\t/** ゴーストの z-index(既定値: `Z_INDEX.BLOCK_GHOST`)。 */\n\tghostZIndex?: number;\n\n\t/** 選択枠線の z-index。 */\n\tselectBorderZIndex?: number;\n\n\t/** リサイズハンドルの z-index。 */\n\tblockHandlesZIndex?: number;\n}\n\n// ゴーストブロック1つを描画するヘルパー\nconst GhostBlock = memo(\n\t({\n\t\tblock,\n\t\tresolvedPlugin,\n\t\tblockDefaults,\n\t\trect,\n\t\topacity,\n\t\tghostZIndex,\n\t}: {\n\t\tblock: Block;\n\t\tresolvedPlugin: ResolvedPlugin;\n\t\tblockDefaults?: BlockDefaults;\n\t\trect: BlockRectPx;\n\t\topacity: number;\n\t\tghostZIndex: number;\n\t}) => {\n\t\tconst props = resolveBlockProps(block, resolvedPlugin, blockDefaults);\n\t\tconst sizePx = { width: rect.width, height: rect.height };\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tleft: `${rect.left}px`,\n\t\t\t\t\ttop: `${rect.top}px`,\n\t\t\t\t\twidth: `${rect.width}px`,\n\t\t\t\t\theight: `${rect.height}px`,\n\t\t\t\t\topacity,\n\t\t\t\t\tzIndex: ghostZIndex,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<BlockCanvas\n\t\t\t\t\tblockSizePx={sizePx}\n\t\t\t\t\tblockZIndex={0}\n\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BG}\n\t\t\t\t\tbackgroundColor={block.style?.backgroundColor}\n\t\t\t\t/>\n\t\t\t\t<BlockRenderer\n\t\t\t\t\tid={block.id}\n\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\tprops={props}\n\t\t\t\t\tvalue={block.initValue ?? null}\n\t\t\t\t\treadOnly={true}\n\t\t\t\t\tmode={NoteMode.FORM}\n\t\t\t\t\tblockSizePx={sizePx}\n\t\t\t\t\tblockZIndex={0}\n\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.CONTENT}\n\t\t\t\t/>\n\t\t\t\t{/* ガイド枠線(ブロックに枠線なしの場合)*/}\n\t\t\t\t{!block.style?.border && (\n\t\t\t\t\t<BlockGuideBorder\n\t\t\t\t\t\tblockSizePx={sizePx}\n\t\t\t\t\t\tblockZIndex={0}\n\t\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.GUIDE}\n\t\t\t\t\t\tborderStyle={GHOST_GUIDE_BORDER}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<BlockBorder\n\t\t\t\t\tblockSizePx={sizePx}\n\t\t\t\t\tborderStyle={block.style?.border}\n\t\t\t\t\tblockZIndex={0}\n\t\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BORDER}\n\t\t\t\t\tdpi={DEFAULT_DPI}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t},\n);\nGhostBlock.displayName = \"GhostBlock\";\n\n/**\n * 移動・リサイズ・挿入ドラッグ中のゴースト UI を描画するコンポーネント。\n *\n * `draggingState` が `undefined` の場合は `null` を返します。\n */\nexport const DragLayer = memo(\n\t({\n\t\tblocks,\n\t\tpluginRegistry,\n\t\tgridLength,\n\t\tdraggingState,\n\t\tgetBlockRectPx,\n\t\tblockDefaults,\n\t\tghostZIndex = Z_INDEX.BLOCK_GHOST,\n\t}: DragLayerProps) => {\n\t\tif (!draggingState) return null;\n\n\t\tconst deltaCol =\n\t\t\tdraggingState.currentGrid.col - draggingState.startGrid.col;\n\t\tconst deltaRow =\n\t\t\tdraggingState.currentGrid.row - draggingState.startGrid.row;\n\n\t\tconst wrapper: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tinset: 0,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\t// --- 移動ゴースト ---\n\t\tif (draggingState.type === DT.MOVE) {\n\t\t\tconst dragTargets = draggingState.blockIds\n\t\t\t\t.map((id) => blocks.find((b) => b.id === id))\n\t\t\t\t.filter(Boolean) as Block[];\n\n\t\t\tconst clampedPositions = clampMultipleBlocks(\n\t\t\t\tdragTargets,\n\t\t\t\tdeltaCol,\n\t\t\t\tdeltaRow,\n\t\t\t\tgridLength.cols,\n\t\t\t\tgridLength.rows,\n\t\t\t);\n\n\t\t\treturn (\n\t\t\t\t<div style={wrapper} data-testid=\"drag-layer-move\">\n\t\t\t\t\t{dragTargets.map((block) => {\n\t\t\t\t\t\tconst resolvedPlugin = pluginRegistry[block.kind];\n\t\t\t\t\t\tif (!resolvedPlugin) return null;\n\n\t\t\t\t\t\tlet ghostRect: BlockRectPx;\n\t\t\t\t\t\tconst isOutside = draggingState.isOutside ?? false;\n\t\t\t\t\t\tconst currentMousePx = draggingState.currentMousePx;\n\n\t\t\t\t\t\tif (isOutside && currentMousePx) {\n\t\t\t\t\t\t\tconst origRect = getBlockRectPx(block);\n\t\t\t\t\t\t\tghostRect = {\n\t\t\t\t\t\t\t\tleft: currentMousePx.x - origRect.width / 2,\n\t\t\t\t\t\t\t\ttop: currentMousePx.y - origRect.height / 2,\n\t\t\t\t\t\t\t\twidth: origRect.width,\n\t\t\t\t\t\t\t\theight: origRect.height,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst clampedPos = clampedPositions.find(\n\t\t\t\t\t\t\t\t(p) => p.blockId === block.id,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (!clampedPos) return null;\n\t\t\t\t\t\t\tconst ghostBlock: Block = {\n\t\t\t\t\t\t\t\t...block,\n\t\t\t\t\t\t\t\tlayout: {\n\t\t\t\t\t\t\t\t\t...block.layout,\n\t\t\t\t\t\t\t\t\tx: clampedPos.x,\n\t\t\t\t\t\t\t\t\ty: clampedPos.y,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tghostRect = getBlockRectPx(ghostBlock);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<GhostBlock\n\t\t\t\t\t\t\t\tkey={block.id}\n\t\t\t\t\t\t\t\tblock={block}\n\t\t\t\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\t\t\t\tblockDefaults={blockDefaults}\n\t\t\t\t\t\t\t\trect={ghostRect}\n\t\t\t\t\t\t\t\topacity={isOutside ? 0.3 : 0.5}\n\t\t\t\t\t\t\t\tghostZIndex={ghostZIndex}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\t// --- リサイズゴースト ---\n\t\tif (draggingState.type === DT.RESIZE) {\n\t\t\tconst blockId = draggingState.blockIds[0];\n\t\t\tconst handle = draggingState.handle as ResizeHandle;\n\t\t\tif (!blockId || !handle) return null;\n\n\t\t\tconst block = blocks.find((b) => b.id === blockId);\n\t\t\tconst resolvedPlugin = block ? pluginRegistry[block.kind] : undefined;\n\t\t\tif (!block || !resolvedPlugin) return null;\n\n\t\t\tconst newLayout = calculateResizedLayout({\n\t\t\t\tlayout: block.layout,\n\t\t\t\thandle,\n\t\t\t\tdeltaCol,\n\t\t\t\tdeltaRow,\n\t\t\t\tgridCols: gridLength.cols,\n\t\t\t\tgridRows: gridLength.rows,\n\t\t\t});\n\n\t\t\tconst ghostBlock: Block = { ...block, layout: newLayout };\n\t\t\tconst ghostRect = getBlockRectPx(ghostBlock);\n\n\t\t\treturn (\n\t\t\t\t<div style={wrapper} data-testid=\"drag-layer-resize\">\n\t\t\t\t\t<GhostBlock\n\t\t\t\t\t\tblock={block}\n\t\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\t\tblockDefaults={blockDefaults}\n\t\t\t\t\t\trect={ghostRect}\n\t\t\t\t\t\topacity={draggingState.isOutside ? 0.3 : 0.5}\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\t// --- 挿入ゴースト ---\n\t\tif (draggingState.type === DT.INSERT) {\n\t\t\tconst { pluginKind, defaultSize, currentGrid, currentMousePx } =\n\t\t\t\tdraggingState;\n\t\t\tif (!pluginKind || !defaultSize) return null;\n\n\t\t\tconst resolvedPlugin = pluginRegistry[pluginKind];\n\t\t\tif (!resolvedPlugin) return null;\n\n\t\t\tconst isOutside = draggingState.isOutside ?? false;\n\n\t\t\tlet ghostRect: BlockRectPx;\n\n\t\t\tif (isOutside && currentMousePx) {\n\t\t\t\t// クランプなし仮ブロックでサイズを取得\n\t\t\t\tconst tempBlock = createBlock(resolvedPlugin, { x: 0, y: 0 });\n\t\t\t\tconst tempRect = getBlockRectPx({\n\t\t\t\t\t...tempBlock,\n\t\t\t\t\tlayout: { ...tempBlock.layout, w: defaultSize.w, h: defaultSize.h },\n\t\t\t\t});\n\t\t\t\tghostRect = {\n\t\t\t\t\tleft: currentMousePx.x - tempRect.width / 2,\n\t\t\t\t\ttop: currentMousePx.y - tempRect.height / 2,\n\t\t\t\t\twidth: tempRect.width,\n\t\t\t\t\theight: tempRect.height,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst maxX = gridLength.cols - defaultSize.w;\n\t\t\t\tconst maxY = gridLength.rows - defaultSize.h;\n\t\t\t\tconst x = Math.max(0, Math.min(currentGrid.col, maxX));\n\t\t\t\tconst y = Math.max(0, Math.min(currentGrid.row, maxY));\n\t\t\t\tconst ghostBlock = createBlock(resolvedPlugin, { x, y });\n\t\t\t\tconst blockWithSize: Block = {\n\t\t\t\t\t...ghostBlock,\n\t\t\t\t\tlayout: { ...ghostBlock.layout, w: defaultSize.w, h: defaultSize.h },\n\t\t\t\t};\n\t\t\t\tghostRect = getBlockRectPx(blockWithSize);\n\t\t\t}\n\n\t\t\tconst displayBlock: Block = {\n\t\t\t\t...createBlock(resolvedPlugin, { x: 0, y: 0 }),\n\t\t\t\tlayout: {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0,\n\t\t\t\t\tw: defaultSize.w,\n\t\t\t\t\th: defaultSize.h,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\treturn (\n\t\t\t\t<div style={wrapper} data-testid=\"drag-layer-insert\">\n\t\t\t\t\t<GhostBlock\n\t\t\t\t\t\tblock={displayBlock}\n\t\t\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\t\t\tblockDefaults={blockDefaults}\n\t\t\t\t\t\trect={ghostRect}\n\t\t\t\t\t\topacity={isOutside ? 0.3 : 0.5}\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\treturn null;\n\t},\n);\n\nDragLayer.displayName = \"DragLayer\";\n","import {\n\ttype ForwardedRef,\n\tforwardRef,\n\tmemo,\n\tuseImperativeHandle,\n\tuseRef,\n} from \"react\";\n\nimport { NoteMode } from \"../../../types/mode\";\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { BLOCK_SUB_INDEX, Z_INDEX } from \"../../../utils/zIndex\";\nimport { BlockBorder } from \"../BlockLayer/BlockBorder\";\nimport { BlockCanvas } from \"../BlockLayer/BlockCanvas\";\nimport { BlockRenderer } from \"../BlockLayer/BlockRenderer\";\n\nimport type { ResolvedPlugin } from \"../../../plugin/registry\";\nimport type { BlockRef } from \"../../../plugin/types\";\nimport type { Block } from \"../../../types/block\";\nimport type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { Value } from \"../../../types/value\";\nimport type { BlockRectPx } from \"../types\";\n\n/**\n * `EditingBlock` コンポーネントへの props。\n */\nexport interface EditingBlockProps {\n\t/** ブロックの ID。 */\n\tid: string;\n\n\t/** 解決済みプラグイン。 */\n\tresolvedPlugin: ResolvedPlugin;\n\n\t/** プロパティマップ。 */\n\tprops: Record<string, Value>;\n\n\t/** 編集中のブロックの値。 */\n\tvalue: Value;\n\n\t/** 値変更時のコールバック。 */\n\tonChange: (value: Value) => void;\n\n\t/** ブロックの位置とサイズ(px)。 */\n\tblockRectPx: BlockRectPx;\n\n\t/** ブロックデータ(スタイル参照用)。 */\n\tblock: Block;\n\n\t/** z-index(既定値: `Z_INDEX.EDIT_BLOCK`)。 */\n\tzIndex?: number;\n\n\t/** 値バインディング用コンテキスト。 */\n\tbindingContext?: BindingContext;\n\n\t/** アクション実行用コンテキスト。 */\n\tactionContext?: ActionContext;\n}\n\n// forwardRef でラップする前の内部実装関数\nconst EditingBlockInner = (\n\t{\n\t\tid,\n\t\tresolvedPlugin,\n\t\tprops,\n\t\tvalue,\n\t\tonChange,\n\t\tblockRectPx,\n\t\tblock,\n\t\tzIndex = Z_INDEX.EDIT_BLOCK,\n\t\tbindingContext,\n\t\tactionContext,\n\t}: EditingBlockProps,\n\tref: ForwardedRef<BlockRef>,\n) => {\n\tconst innerRef = useRef<BlockRef>(null);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({ focus: () => innerRef.current?.focus() }),\n\t\t[],\n\t);\n\n\tconst sizePx = { width: blockRectPx.width, height: blockRectPx.height };\n\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: `${blockRectPx.left}px`,\n\t\t\t\ttop: `${blockRectPx.top}px`,\n\t\t\t\twidth: `${sizePx.width}px`,\n\t\t\t\theight: `${sizePx.height}px`,\n\t\t\t\tzIndex,\n\t\t\t\tpointerEvents: \"auto\",\n\t\t\t}}\n\t\t\tdata-testid=\"editing-block\"\n\t\t>\n\t\t\t<BlockCanvas\n\t\t\t\tblockSizePx={sizePx}\n\t\t\t\tblockZIndex={0}\n\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BG}\n\t\t\t\tbackgroundColor={block.style?.backgroundColor}\n\t\t\t/>\n\t\t\t<BlockRenderer\n\t\t\t\tref={innerRef}\n\t\t\t\tid={id}\n\t\t\t\tresolvedPlugin={resolvedPlugin}\n\t\t\t\tprops={props}\n\t\t\t\tvalue={value}\n\t\t\t\tonChange={onChange}\n\t\t\t\treadOnly={false}\n\t\t\t\tmode={NoteMode.EDIT}\n\t\t\t\tblockSizePx={sizePx}\n\t\t\t\tblockZIndex={0}\n\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.CONTENT}\n\t\t\t\tbindingContext={bindingContext}\n\t\t\t\tactionContext={actionContext}\n\t\t\t/>\n\t\t\t<BlockBorder\n\t\t\t\tblockSizePx={sizePx}\n\t\t\t\tborderStyle={block.style?.border}\n\t\t\t\tblockZIndex={0}\n\t\t\t\tsubZIndex={BLOCK_SUB_INDEX.BORDER}\n\t\t\t\tdpi={DEFAULT_DPI}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\n/**\n * 編集中ブロックの Renderer を InteractionLayer 上に表示するコンポーネント。\n *\n * `ref` で {@link BlockRef} を取得できます。\n */\nexport const EditingBlock = memo(forwardRef(EditingBlockInner));\nEditingBlock.displayName = \"EditingBlock\";\n","import { type CSSProperties, memo } from \"react\";\n\nimport { LineType } from \"../../../types/line\";\nimport { DEFAULT_DPI } from \"../../../utils/convert\";\nimport { Z_INDEX } from \"../../../utils/zIndex\";\nimport { BlockBorder } from \"../BlockLayer/BlockBorder\";\nimport { ResizeHandle } from \"./types\";\n\nimport type { Block } from \"../../../types/block\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockRectPx } from \"../types\";\n\n// 選択枠線の各辺スタイル(青半透明の実線 4px)\nconst SELECTION_LINE = {\n\tcolor: \"#3b82f688\",\n\twidth: { value: 4, unit: \"px\" as const },\n\ttype: LineType.SOLID,\n};\n\n/**\n * 選択中ブロックに重ねる枠線スタイル(青半透明の実線 4px)。\n */\nexport const SELECTION_STYLE: BorderStyle = {\n\ttop: SELECTION_LINE,\n\tright: SELECTION_LINE,\n\tbottom: SELECTION_LINE,\n\tleft: SELECTION_LINE,\n};\n\n// リサイズハンドルのサイズ(px)\nconst HANDLE_SIZE = 12;\n// ハンドルを枠線に半分かかるようにするオフセット\nconst HANDLE_OFFSET = HANDLE_SIZE / 2;\n\n// 8 方向リサイズハンドルの位置・カーソル定義\nconst HANDLES = [\n\t{ id: ResizeHandle.NW, cursor: \"nwse-resize\", x: 0, y: 0 },\n\t{ id: ResizeHandle.N, cursor: \"ns-resize\", x: 50, y: 0 },\n\t{ id: ResizeHandle.NE, cursor: \"nesw-resize\", x: 100, y: 0 },\n\t{ id: ResizeHandle.W, cursor: \"ew-resize\", x: 0, y: 50 },\n\t{ id: ResizeHandle.E, cursor: \"ew-resize\", x: 100, y: 50 },\n\t{ id: ResizeHandle.SW, cursor: \"nesw-resize\", x: 0, y: 100 },\n\t{ id: ResizeHandle.S, cursor: \"ns-resize\", x: 50, y: 100 },\n\t{ id: ResizeHandle.SE, cursor: \"nwse-resize\", x: 100, y: 100 },\n] as const;\n\n/**\n * `InteractionBlock` コンポーネントへの props。\n */\nexport interface InteractionBlockProps {\n\t/** 対象ブロックデータ。 */\n\tblock: Block;\n\n\t/** ブロックの位置とサイズ(px)。 */\n\trect: BlockRectPx;\n\n\t/** `true` の場合はリサイズハンドル(8方向)を表示する(既定値: `false`)。 */\n\tshowHandles?: boolean;\n\n\t/** リサイズ開始時のコールバック。 */\n\tonResizeStart?: (e: React.PointerEvent, handle: ResizeHandle) => void;\n\n\t/** 現在操作中のハンドル方向。ハイライト表示に使用。 */\n\tactiveHandle?: ResizeHandle | null;\n\n\t/** 選択枠線のスタイル(既定値: `SELECTION_STYLE`)。 */\n\tselectionStyle?: BorderStyle;\n\n\t/** 選択枠線の z-index(既定値: `Z_INDEX.BLOCK_SELECT_BORDER`)。 */\n\tselectBorderZIndex?: number;\n\n\t/** リサイズハンドルの z-index(既定値: `Z_INDEX.BLOCK_HANDLES`)。 */\n\tblockHandlesZIndex?: number;\n}\n\n/**\n * ブロックの選択枠線とリサイズハンドル(8方向)を描画する単一コンポーネント。\n */\nexport const InteractionBlock = memo(\n\t({\n\t\tblock,\n\t\trect,\n\t\tshowHandles = false,\n\t\tonResizeStart,\n\t\tactiveHandle,\n\t\tselectionStyle = SELECTION_STYLE,\n\t\tselectBorderZIndex = Z_INDEX.BLOCK_SELECT_BORDER,\n\t\tblockHandlesZIndex = Z_INDEX.BLOCK_HANDLES,\n\t}: InteractionBlockProps) => {\n\t\tconst containerStyle: CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: `${rect.left}px`,\n\t\t\ttop: `${rect.top}px`,\n\t\t\twidth: `${rect.width}px`,\n\t\t\theight: `${rect.height}px`,\n\t\t\tpointerEvents: \"none\",\n\t\t};\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={containerStyle}\n\t\t\t\tdata-testid=\"interaction-block\"\n\t\t\t\tdata-block-id={block.id}\n\t\t\t>\n\t\t\t\t{/* 選択枠 */}\n\t\t\t\t<BlockBorder\n\t\t\t\t\tblockSizePx={{ width: rect.width, height: rect.height }}\n\t\t\t\t\tborderStyle={selectionStyle}\n\t\t\t\t\tblockZIndex={selectBorderZIndex}\n\t\t\t\t\tsubZIndex={0}\n\t\t\t\t\tdpi={DEFAULT_DPI}\n\t\t\t\t/>\n\n\t\t\t\t{/* リサイズハンドル(8方向) */}\n\t\t\t\t{showHandles &&\n\t\t\t\t\tonResizeStart &&\n\t\t\t\t\tHANDLES.map(({ id, cursor, x, y }) => {\n\t\t\t\t\t\tconst left =\n\t\t\t\t\t\t\tx === 50\n\t\t\t\t\t\t\t\t? `calc(50% - ${HANDLE_OFFSET}px)`\n\t\t\t\t\t\t\t\t: x === 100\n\t\t\t\t\t\t\t\t\t? `calc(100% - ${HANDLE_OFFSET}px)`\n\t\t\t\t\t\t\t\t\t: `-${HANDLE_OFFSET}px`;\n\t\t\t\t\t\tconst top =\n\t\t\t\t\t\t\ty === 50\n\t\t\t\t\t\t\t\t? `calc(50% - ${HANDLE_OFFSET}px)`\n\t\t\t\t\t\t\t\t: y === 100\n\t\t\t\t\t\t\t\t\t? `calc(100% - ${HANDLE_OFFSET}px)`\n\t\t\t\t\t\t\t\t\t: `-${HANDLE_OFFSET}px`;\n\n\t\t\t\t\t\tconst isActive = activeHandle === id;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={id}\n\t\t\t\t\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tonResizeStart(e, id);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\t\tleft,\n\t\t\t\t\t\t\t\t\ttop,\n\t\t\t\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\n\t\t\t\t\t\t\t\t\tbackgroundColor: isActive ? \"#3b82f6\" : \"#ffffff\",\n\t\t\t\t\t\t\t\t\tborder: \"1px solid #3b82f6\",\n\t\t\t\t\t\t\t\t\tborderRadius: \"50%\",\n\t\t\t\t\t\t\t\t\tcursor,\n\t\t\t\t\t\t\t\t\tzIndex: blockHandlesZIndex,\n\t\t\t\t\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\t\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\t\t\t\t\t\ttransform: isActive ? \"scale(1.2)\" : undefined,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tdata-testid={`resize-handle-${id}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nInteractionBlock.displayName = \"InteractionBlock\";\n","import { memo } from \"react\";\n\nimport { InteractionBlock, SELECTION_STYLE } from \"./InteractionBlock\";\nimport { DragType } from \"./types\";\n\nimport type { Block } from \"../../../types/block\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockRectPx } from \"../types\";\nimport type { DraggingState, ResizeHandle } from \"./types\";\n\n/**\n * `SelectionLayer` コンポーネントへの props。\n */\nexport interface SelectionLayerProps {\n\t/** 全ブロックデータ一覧。 */\n\tblocks: Block[];\n\n\t/** 選択されているブロック ID 一覧。 */\n\tselectedBlockIds: string[];\n\n\t/** ドラッグ中かどうか。移動・挿入中は選択枠線を非表示にする。 */\n\tisDragging: boolean;\n\n\t/** 現在のドラッグ状態。リサイズ履歴の参照に使用。 */\n\tdraggingState?: DraggingState;\n\n\t/** ブロックからキャンバス上の矩形座標(px)を返す関数。 */\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\n\n\t/** リサイズ開始時のコールバック。 */\n\tonResizeStart: (\n\t\te: React.PointerEvent,\n\t\thandle: ResizeHandle,\n\t\tblockId: string,\n\t) => void;\n\n\t/** 選択枠線のスタイル(既定値: `SELECTION_STYLE`)。 */\n\tselectionStyle?: BorderStyle;\n\n\t/** 選択枠線の z-index。 */\n\tselectBorderZIndex?: number;\n\n\t/** リサイズハンドルの z-index。 */\n\tblockHandlesZIndex?: number;\n}\n\n/**\n * 選択中ブロックに `InteractionBlock`(選択枠線 + リサイズハンドル)を重ねて描画するレイヤー。\n *\n * 移動中・挿入中は選択枠線を非表示にします。\n */\nexport const SelectionLayer = memo(\n\t({\n\t\tblocks,\n\t\tselectedBlockIds,\n\t\tisDragging,\n\t\tdraggingState,\n\t\tgetBlockRectPx,\n\t\tonResizeStart,\n\t\tselectionStyle = SELECTION_STYLE,\n\t\tselectBorderZIndex,\n\t\tblockHandlesZIndex,\n\t}: SelectionLayerProps) => {\n\t\t// 移動中・挿入中は枠を非表示(リサイズ中は表示を維持)\n\t\tconst isMoving = isDragging && draggingState?.type !== DragType.RESIZE;\n\t\tif (isMoving) return null;\n\n\t\tconst uniqueIds = Array.from(new Set(selectedBlockIds));\n\n\t\treturn (\n\t\t\t<div style={{ position: \"absolute\", inset: 0, pointerEvents: \"none\" }}>\n\t\t\t\t{uniqueIds.map((id) => {\n\t\t\t\t\tconst block = blocks.find((b) => b.id === id);\n\t\t\t\t\tif (!block) return null;\n\n\t\t\t\t\tconst isResizing =\n\t\t\t\t\t\tdraggingState?.type === DragType.RESIZE &&\n\t\t\t\t\t\tdraggingState.blockIds.includes(id);\n\t\t\t\t\tconst activeHandle = isResizing ? draggingState?.handle : null;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<InteractionBlock\n\t\t\t\t\t\t\tkey={block.id}\n\t\t\t\t\t\t\tblock={block}\n\t\t\t\t\t\t\trect={getBlockRectPx(block)}\n\t\t\t\t\t\t\tshowHandles={true}\n\t\t\t\t\t\t\tonResizeStart={(e, handle) => onResizeStart(e, handle, id)}\n\t\t\t\t\t\t\tactiveHandle={activeHandle ?? null}\n\t\t\t\t\t\t\tselectionStyle={selectionStyle}\n\t\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\n\t\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nSelectionLayer.displayName = \"SelectionLayer\";\n","/**\n * ブロックの位置をグリッド範囲内にクランプする。\n *\n * - x: 0 〜 (gridCols - w)\n * - y: 0 〜 (gridRows - h)\n */\nexport function clampBlockToGrid(\n\tposition: { x: number; y: number },\n\tsize: { w: number; h: number },\n\tgridCols: number,\n\tgridRows: number,\n): { x: number; y: number } {\n\tconst maxX = gridCols - size.w;\n\tconst maxY = gridRows - size.h;\n\treturn {\n\t\tx: Math.max(0, Math.min(position.x, maxX)),\n\t\ty: Math.max(0, Math.min(position.y, maxY)),\n\t};\n}\n","import type { BlockRect } from \"../../../../types/block\";\n\n/**\n * 複製・貼り付け先の位置を計算する。\n *\n * - グリッド右端・下端でなければ +1(右・下)方向へオフセット\n * - 右端・下端に達している場合は -1(左・上)方向へオフセット\n */\nexport function calcDuplicatePosition(\n\tlayout: BlockRect,\n\tgridCols: number,\n\tgridRows: number,\n): { x: number; y: number } {\n\tconst newX =\n\t\tlayout.x + layout.w < gridCols ? layout.x + 1 : Math.max(0, layout.x - 1);\n\tconst newY =\n\t\tlayout.y + layout.h < gridRows ? layout.y + 1 : Math.max(0, layout.y - 1);\n\treturn { x: newX, y: newY };\n}\n","import type { Block } from \"../../../../types/block\";\nimport type { BlockRectPx } from \"../../types\";\n\n/**\n * 指定座標にあるブロックIDを返す(キャンバス相対座標)。\n *\n * 描画順(Z順)を考慮し、配列後方(手前のブロック)から走査する。\n */\nexport function findBlockAtPoint(\n\tpoint: { x: number; y: number },\n\tblocks: Block[],\n\tgetBlockRectPx: (block: Block) => BlockRectPx,\n): string | null {\n\tconst { x, y } = point;\n\tfor (let i = blocks.length - 1; i >= 0; i--) {\n\t\tconst block = blocks[i];\n\t\tif (!block) continue;\n\t\tconst rect = getBlockRectPx(block);\n\t\tif (\n\t\t\tx >= rect.left &&\n\t\t\tx <= rect.left + rect.width &&\n\t\t\ty >= rect.top &&\n\t\t\ty <= rect.top + rect.height\n\t\t) {\n\t\t\treturn block.id;\n\t\t}\n\t}\n\treturn null;\n}\n","import { memo, useCallback, useEffect, useRef } from \"react\";\n\nimport {\n\tarrowMoveKey,\n\tinitValueKey,\n\tkeyboardResizeKey,\n} from \"../../../contexts/history/mergeKeys\";\nimport { createBlockId } from \"../../../utils/block\";\nimport { Z_INDEX } from \"../../../utils/zIndex\";\nimport { resolveBlockProps } from \"../BlockLayer/utils/resolveBlockProps\";\nimport { DragLayer } from \"./DragLayer\";\nimport { EditingBlock } from \"./EditingBlock\";\nimport { SelectionLayer } from \"./SelectionLayer\";\nimport {\n\tDragType,\n\tgetInteractionMode,\n\tInteractionMode,\n\tResizeHandle,\n} from \"./types\";\nimport { calculateResizedLayout } from \"./utils/calcResize\";\nimport { clampBlockToGrid } from \"./utils/clampBlock\";\nimport { clampMultipleBlocks } from \"./utils/clampMultipleBlocks\";\nimport { createBlock } from \"./utils/createBlock\";\nimport { calcDuplicatePosition } from \"./utils/duplicateOffset\";\nimport { findBlockAtPoint } from \"./utils/hitTest\";\n\nimport type { PluginRegistry } from \"../../../plugin/registry\";\nimport type { BlockRef } from \"../../../plugin/types\";\nimport type { Block } from \"../../../types/block\";\nimport type { OnSelectionChange } from \"../../../types/callbacks\";\nimport type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { BorderStyle } from \"../../../types/line\";\nimport type { BlockDefaults, Page } from \"../../../types/schema\";\nimport type { BlockRectPx } from \"../types\";\nimport type { InteractionState } from \"./types\";\n\n/**\n * `InteractionLayer` コンポーネントへの props。\n */\nexport interface InteractionLayerProps {\n\t/** 描画対象のページデータ。 */\n\tpage: Page;\n\n\t/** プラグインレジストリ。 */\n\tpluginRegistry: PluginRegistry;\n\n\t/** グリッドの列数・行数。 */\n\tgridLength: { cols: number; rows: number };\n\n\t/** ブロックのデフォルト値設定。 */\n\tblockDefaults?: BlockDefaults;\n\n\t/** ブロックからキャンバス上の矩形座標(px)を返す関数。 */\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\n\n\t/** x 座標(px)からグリッド列インデックスを返す関数。 */\n\tgetColIndex: (px: number) => number;\n\n\t/** y 座標(px)からグリッド行インデックスを返す関数。 */\n\tgetRowIndex: (px: number) => number;\n\n\t/** インタラクション状態(controlled)。 */\n\tstate: InteractionState;\n\n\t/** 状態変更時のコールバック。 */\n\tonStateChange: (state: InteractionState) => void;\n\n\t/** 選択中のブロック ID 一覧(controlled)。 */\n\tselectedBlockIds: string[];\n\n\t/** 選択変更時のコールバック。 */\n\tonSelectionChange: OnSelectionChange;\n\n\t/** ページ変更(ブロック追加・削除・移動など)時のコールバック。 */\n\tonPageChange: (\n\t\tpage: Page,\n\t\toptions?: { mergeKey?: string; noTimeWindow?: boolean },\n\t) => void;\n\n\t/** アクション実行用コンテキスト(undo/redo など)。 */\n\tactionContext: ActionContext;\n\n\t/** 値バインディング用コンテキスト。 */\n\tbindingContext?: BindingContext;\n\n\t/** キャンバスのスケール倍率(既定値: `1.0`)。 */\n\tscale?: number;\n\n\t/** ルート要素の CSS クラス名。 */\n\tclassName?: string;\n\n\t/** 選択枠線のスタイル。 */\n\tselectionStyle?: BorderStyle;\n}\n\n/**\n * ブロックの移動・リサイズ・挿入・編集のインタラクションを集約した全体制御レイヤーコンポーネント。\n *\n * @remarks\n * **Canvas** — {@link Note} 実装を担う低レベルインタラクションレイヤー。\n *\n * 通常は {@link Note} を使用する。\n */\nexport const InteractionLayer = memo(\n\t({\n\t\tpage,\n\t\tpluginRegistry,\n\t\tgridLength,\n\t\tblockDefaults,\n\t\tgetBlockRectPx,\n\t\tgetColIndex,\n\t\tgetRowIndex,\n\t\tstate,\n\t\tonStateChange,\n\t\tselectedBlockIds,\n\t\tonSelectionChange,\n\t\tonPageChange,\n\t\tactionContext,\n\t\tbindingContext,\n\t\tscale = 1.0,\n\t\tclassName = \"\",\n\t\tselectionStyle,\n\t}: InteractionLayerProps) => {\n\t\tconst blocks = page.blocks;\n\t\tconst layerRef = useRef<HTMLDivElement>(null);\n\t\tconst editingBlockRef = useRef<BlockRef>(null);\n\t\tconst focusTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\t\t// アンマウント時に残存フォーカスタイマーをキャンセル\n\t\tuseEffect(() => {\n\t\t\treturn () => {\n\t\t\t\tif (focusTimerRef.current !== null) {\n\t\t\t\t\tclearTimeout(focusTimerRef.current);\n\t\t\t\t}\n\t\t\t};\n\t\t}, []);\n\n\t\tconst mode = getInteractionMode(state);\n\n\t\t// 矢印キー移動セッション管理(方向・ブロック選択が変わるかキーアップで新セッション)\n\t\tconst arrowSessionRef = useRef<{\n\t\t\tdirection: string;\n\t\t\tblockIds: string;\n\t\t\tid: number;\n\t\t} | null>(null);\n\t\tconst arrowSessionCounterRef = useRef(0);\n\n\t\t// Shift+矢印キーリサイズセッション管理(移動セッションと同じ切り替ルール)\n\t\tconst resizeSessionRef = useRef<{\n\t\t\tdirection: string;\n\t\t\tblockIds: string;\n\t\t\tid: number;\n\t\t} | null>(null);\n\t\tconst resizeSessionCounterRef = useRef(0);\n\n\t\t// INSERT モード時: カーソルがレイヤー外でリリースされたらキャンセル\n\t\tconst stateRef = useRef(state);\n\t\tstateRef.current = state;\n\t\tconst onStateChangeRef = useRef(onStateChange);\n\t\tonStateChangeRef.current = onStateChange;\n\t\tuseEffect(() => {\n\t\t\tif (mode !== InteractionMode.INSERT) return;\n\t\t\tconst handleWindowPointerUp = (e: PointerEvent) => {\n\t\t\t\tconst layer = layerRef.current;\n\t\t\t\tif (layer && (e.target === layer || layer.contains(e.target as Node))) {\n\t\t\t\t\t// レイヤー内リリース → React の onPointerUp ハンドラに任せる\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// レイヤー外リリース → INSERT モードをキャンセル\n\t\t\t\tonStateChangeRef.current({ ...stateRef.current, dragging: undefined });\n\t\t\t};\n\t\t\twindow.addEventListener(\"pointerup\", handleWindowPointerUp);\n\t\t\treturn () =>\n\t\t\t\twindow.removeEventListener(\"pointerup\", handleWindowPointerUp);\n\t\t}, [mode]);\n\n\t\t// 編集モード時のフォーカス処理\n\t\tuseEffect(() => {\n\t\t\tif (mode === InteractionMode.EDITING && state.editingBlockId) {\n\t\t\t\tconst id = setTimeout(() => {\n\t\t\t\t\teditingBlockRef.current?.focus();\n\t\t\t\t}, 0);\n\t\t\t\treturn () => clearTimeout(id);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}, [mode, state.editingBlockId]);\n\n\t\t// 削除されたブロックIDを選択から除外\n\t\tuseEffect(() => {\n\t\t\tconst blockIds = new Set(blocks.map((b) => b.id));\n\t\t\tconst validIds = selectedBlockIds.filter((id) => blockIds.has(id));\n\t\t\tif (validIds.length !== selectedBlockIds.length) {\n\t\t\t\tonSelectionChange(validIds);\n\t\t\t}\n\t\t}, [blocks, selectedBlockIds, onSelectionChange]);\n\n\t\t// --- PointerDown ---\n\t\tconst handlePointerDown = useCallback(\n\t\t\t(e: React.PointerEvent) => {\n\t\t\t\tif (e.button !== 0) return;\n\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\n\t\t\t\tif (!rect) return;\n\t\t\t\tconst sf = scale;\n\t\t\t\tconst px = {\n\t\t\t\t\tx: (e.clientX - rect.left) / sf,\n\t\t\t\t\ty: (e.clientY - rect.top) / sf,\n\t\t\t\t};\n\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\n\n\t\t\t\t// 編集モード中\n\t\t\t\tif (mode === InteractionMode.EDITING) {\n\t\t\t\t\tif (targetId !== state.editingBlockId) {\n\t\t\t\t\t\tonStateChange({ ...state, editingBlockId: null });\n\t\t\t\t\t\tif (!targetId) onSelectionChange([]);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst gridCol = getColIndex(px.x);\n\t\t\t\tconst gridRow = getRowIndex(px.y);\n\n\t\t\t\tif (targetId) {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tconst isSelected = selectedBlockIds.includes(targetId);\n\n\t\t\t\t\tif (isSelected && e.shiftKey) {\n\t\t\t\t\t\tonSelectionChange(selectedBlockIds.filter((id) => id !== targetId));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\n\n\t\t\t\t\tif (isSelected) {\n\t\t\t\t\t\tonStateChange({\n\t\t\t\t\t\t\t...state,\n\t\t\t\t\t\t\tdragging: {\n\t\t\t\t\t\t\t\ttype: DragType.MOVE,\n\t\t\t\t\t\t\t\tblockIds: selectedBlockIds,\n\t\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\n\t\t\t\t\t\t\t\tcurrentGrid: { col: gridCol, row: gridRow },\n\t\t\t\t\t\t\t\tisOutside: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\t\t\tonSelectionChange([...selectedBlockIds, targetId]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonSelectionChange([targetId]);\n\t\t\t\t\t\t\tonStateChange({\n\t\t\t\t\t\t\t\t...state,\n\t\t\t\t\t\t\t\tdragging: {\n\t\t\t\t\t\t\t\t\ttype: DragType.MOVE,\n\t\t\t\t\t\t\t\t\tblockIds: [targetId],\n\t\t\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\n\t\t\t\t\t\t\t\t\tcurrentGrid: { col: gridCol, row: gridRow },\n\t\t\t\t\t\t\t\t\tisOutside: false,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[\n\t\t\t\tblocks,\n\t\t\t\tgetBlockRectPx,\n\t\t\t\tgetColIndex,\n\t\t\t\tgetRowIndex,\n\t\t\t\tmode,\n\t\t\t\tselectedBlockIds,\n\t\t\t\tonSelectionChange,\n\t\t\t\tonStateChange,\n\t\t\t\tscale,\n\t\t\t\tstate,\n\t\t\t],\n\t\t);\n\n\t\t// --- PointerMove ---\n\t\tconst handlePointerMove = useCallback(\n\t\t\t(e: React.PointerEvent) => {\n\t\t\t\tif (\n\t\t\t\t\tmode !== InteractionMode.PRESSING &&\n\t\t\t\t\tmode !== InteractionMode.DRAGGING &&\n\t\t\t\t\tmode !== InteractionMode.INSERT\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\tif (!state.dragging) return;\n\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\n\t\t\t\tif (!rect) return;\n\t\t\t\tconst sf = scale;\n\t\t\t\tconst canvasW = rect.width / sf;\n\t\t\t\tconst canvasH = rect.height / sf;\n\t\t\t\tconst rawX = (e.clientX - rect.left) / sf;\n\t\t\t\tconst rawY = (e.clientY - rect.top) / sf;\n\n\t\t\t\tconst isOutside =\n\t\t\t\t\tstate.dragging.type !== DragType.RESIZE &&\n\t\t\t\t\t(rawX < 0 || rawX > canvasW || rawY < 0 || rawY > canvasH);\n\n\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasW));\n\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasH));\n\n\t\t\t\tlet currentCol = getColIndex(clampedX);\n\t\t\t\tlet currentRow = getRowIndex(clampedY);\n\n\t\t\t\t// リサイズ: 境界グリッドインデックスに補正\n\t\t\t\tif (state.dragging.type === DragType.RESIZE && state.dragging.handle) {\n\t\t\t\t\tconst h = state.dragging.handle;\n\t\t\t\t\tif (\n\t\t\t\t\t\th === ResizeHandle.E ||\n\t\t\t\t\t\th === ResizeHandle.NE ||\n\t\t\t\t\t\th === ResizeHandle.SE\n\t\t\t\t\t) {\n\t\t\t\t\t\tcurrentCol = getColIndex(clampedX) + 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\th === ResizeHandle.S ||\n\t\t\t\t\t\th === ResizeHandle.SE ||\n\t\t\t\t\t\th === ResizeHandle.SW\n\t\t\t\t\t) {\n\t\t\t\t\t\tcurrentRow = getRowIndex(clampedY) + 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tonStateChange({\n\t\t\t\t\t...state,\n\t\t\t\t\tdragging: {\n\t\t\t\t\t\t...state.dragging,\n\t\t\t\t\t\tcurrentGrid: { col: currentCol, row: currentRow },\n\t\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\n\t\t\t\t\t\tisOutside,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t},\n\t\t\t[mode, state, getColIndex, getRowIndex, onStateChange, scale],\n\t\t);\n\n\t\t// --- PointerUp ---\n\t\tconst handlePointerUp = useCallback(\n\t\t\t(e: React.PointerEvent) => {\n\t\t\t\tif (\n\t\t\t\t\t(mode === InteractionMode.DRAGGING ||\n\t\t\t\t\t\tmode === InteractionMode.INSERT) &&\n\t\t\t\t\tstate.dragging\n\t\t\t\t) {\n\t\t\t\t\t// キャンバス外 → 削除(MOVE のみ)\n\t\t\t\t\tif (state.dragging.isOutside) {\n\t\t\t\t\t\tif (state.dragging.type === DragType.MOVE) {\n\t\t\t\t\t\t\tconst deletedIds = new Set(state.dragging.blockIds);\n\t\t\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\t\tblocks: blocks.filter((b) => !deletedIds.has(b.id)),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonStateChange({ ...state, dragging: undefined });\n\t\t\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst deltaCol =\n\t\t\t\t\t\tstate.dragging.currentGrid.col - state.dragging.startGrid.col;\n\t\t\t\t\tconst deltaRow =\n\t\t\t\t\t\tstate.dragging.currentGrid.row - state.dragging.startGrid.row;\n\n\t\t\t\t\t// 移動確定\n\t\t\t\t\tif (\n\t\t\t\t\t\tstate.dragging.type === DragType.MOVE &&\n\t\t\t\t\t\t(deltaCol !== 0 || deltaRow !== 0)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst dragTargets = state.dragging.blockIds\n\t\t\t\t\t\t\t.map((id) => blocks.find((b) => b.id === id))\n\t\t\t\t\t\t\t.filter(Boolean) as Block[];\n\n\t\t\t\t\t\tif (dragTargets.length > 0) {\n\t\t\t\t\t\t\tconst clampedPositions = clampMultipleBlocks(\n\t\t\t\t\t\t\t\tdragTargets,\n\t\t\t\t\t\t\t\tdeltaCol,\n\t\t\t\t\t\t\t\tdeltaRow,\n\t\t\t\t\t\t\t\tgridLength.cols,\n\t\t\t\t\t\t\t\tgridLength.rows,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\t\tblocks: blocks.map((b) => {\n\t\t\t\t\t\t\t\t\tconst pos = clampedPositions.find((p) => p.blockId === b.id);\n\t\t\t\t\t\t\t\t\tif (!pos) return b;\n\t\t\t\t\t\t\t\t\treturn { ...b, layout: { ...b.layout, x: pos.x, y: pos.y } };\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// 挿入確定\n\t\t\t\t\telse if (state.dragging.type === DragType.INSERT) {\n\t\t\t\t\t\tconst { pluginKind, currentGrid, defaultSize } = state.dragging;\n\t\t\t\t\t\tif (pluginKind && defaultSize) {\n\t\t\t\t\t\t\tconst resolved = pluginRegistry[pluginKind];\n\t\t\t\t\t\t\tif (resolved) {\n\t\t\t\t\t\t\t\tconst { x, y } = clampBlockToGrid(\n\t\t\t\t\t\t\t\t\t{ x: currentGrid.col, y: currentGrid.row },\n\t\t\t\t\t\t\t\t\t{ w: defaultSize.w, h: defaultSize.h },\n\t\t\t\t\t\t\t\t\tgridLength.cols,\n\t\t\t\t\t\t\t\t\tgridLength.rows,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst newBlock: Block = {\n\t\t\t\t\t\t\t\t\t...createBlock(resolved, { x, y }),\n\t\t\t\t\t\t\t\t\tlayout: {\n\t\t\t\t\t\t\t\t\t\tx,\n\t\t\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\t\t\tw: defaultSize.w,\n\t\t\t\t\t\t\t\t\t\th: defaultSize.h,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tonPageChange({ ...page, blocks: [...blocks, newBlock] });\n\t\t\t\t\t\t\t\tonSelectionChange([newBlock.id]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// リサイズ確定\n\t\t\t\t\telse if (state.dragging.type === DragType.RESIZE) {\n\t\t\t\t\t\tconst targetId = state.dragging.blockIds[0];\n\t\t\t\t\t\tconst block = blocks.find((b) => b.id === targetId);\n\t\t\t\t\t\tconst handle = state.dragging.handle;\n\n\t\t\t\t\t\tif (block && handle && (deltaCol !== 0 || deltaRow !== 0)) {\n\t\t\t\t\t\t\tconst newLayout = calculateResizedLayout({\n\t\t\t\t\t\t\t\tlayout: block.layout,\n\t\t\t\t\t\t\t\thandle,\n\t\t\t\t\t\t\t\tdeltaCol,\n\t\t\t\t\t\t\t\tdeltaRow,\n\t\t\t\t\t\t\t\tgridCols: gridLength.cols,\n\t\t\t\t\t\t\t\tgridRows: gridLength.rows,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnewLayout.x !== block.layout.x ||\n\t\t\t\t\t\t\t\tnewLayout.y !== block.layout.y ||\n\t\t\t\t\t\t\t\tnewLayout.w !== block.layout.w ||\n\t\t\t\t\t\t\t\tnewLayout.h !== block.layout.h\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\t\t\tblocks: blocks.map((b) =>\n\t\t\t\t\t\t\t\t\t\tb.id === block.id ? { ...b, layout: newLayout } : b,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tonStateChange({ ...state, dragging: undefined });\n\t\t\t\t} else if (mode === InteractionMode.PRESSING && state.dragging) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tstate.dragging.isOutside &&\n\t\t\t\t\t\tstate.dragging.type === DragType.MOVE\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst deletedIds = new Set(state.dragging.blockIds);\n\t\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\tblocks: blocks.filter((b) => !deletedIds.has(b.id)),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\t}\n\t\t\t\t\tonStateChange({ ...state, dragging: undefined });\n\t\t\t\t}\n\n\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\n\t\t\t},\n\t\t\t[\n\t\t\t\tmode,\n\t\t\t\tstate,\n\t\t\t\tblocks,\n\t\t\t\tpage,\n\t\t\t\tgridLength,\n\t\t\t\tpluginRegistry,\n\t\t\t\tonPageChange,\n\t\t\t\tonStateChange,\n\t\t\t\tonSelectionChange,\n\t\t\t],\n\t\t);\n\n\t\t// --- DoubleClick (編集開始) ---\n\t\tconst handleDoubleClick = useCallback(\n\t\t\t(e: React.MouseEvent) => {\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\n\t\t\t\tif (!rect) return;\n\t\t\t\tconst sf = scale;\n\t\t\t\tconst px = {\n\t\t\t\t\tx: (e.clientX - rect.left) / sf,\n\t\t\t\t\ty: (e.clientY - rect.top) / sf,\n\t\t\t\t};\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\n\t\t\t\tif (targetId) {\n\t\t\t\t\tif (!selectedBlockIds.includes(targetId)) {\n\t\t\t\t\t\tonSelectionChange([targetId]);\n\t\t\t\t\t}\n\t\t\t\t\tonStateChange({ ...state, editingBlockId: targetId });\n\t\t\t\t}\n\t\t\t},\n\t\t\t[\n\t\t\t\tblocks,\n\t\t\t\tgetBlockRectPx,\n\t\t\t\tonSelectionChange,\n\t\t\t\tonStateChange,\n\t\t\t\tscale,\n\t\t\t\tselectedBlockIds,\n\t\t\t\tstate,\n\t\t\t],\n\t\t);\n\n\t\t// --- PointerLeave ---\n\t\tconst handlePointerLeave = useCallback(\n\t\t\t(e: React.PointerEvent) => {\n\t\t\t\tif (\n\t\t\t\t\t(mode === InteractionMode.PRESSING ||\n\t\t\t\t\t\tmode === InteractionMode.DRAGGING ||\n\t\t\t\t\t\tmode === InteractionMode.INSERT) &&\n\t\t\t\t\tstate.dragging\n\t\t\t\t) {\n\t\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\n\t\t\t\t\tif (!rect) return;\n\t\t\t\t\tconst sf = scale;\n\t\t\t\t\tconst rawX = (e.clientX - rect.left) / sf;\n\t\t\t\t\tconst rawY = (e.clientY - rect.top) / sf;\n\t\t\t\t\tconst canvasW = rect.width / sf;\n\t\t\t\t\tconst canvasH = rect.height / sf;\n\t\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasW));\n\t\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasH));\n\n\t\t\t\t\tonStateChange({\n\t\t\t\t\t\t...state,\n\t\t\t\t\t\tdragging: {\n\t\t\t\t\t\t\t...state.dragging,\n\t\t\t\t\t\t\tcurrentGrid: {\n\t\t\t\t\t\t\t\tcol: getColIndex(clampedX),\n\t\t\t\t\t\t\t\trow: getRowIndex(clampedY),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\n\t\t\t\t\t\t\tisOutside: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t[mode, state, scale, getColIndex, getRowIndex, onStateChange],\n\t\t);\n\n\t\t// --- KeyDown ---\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(e: React.KeyboardEvent) => {\n\t\t\t\tconst isEditing = mode === InteractionMode.EDITING;\n\n\t\t\t\t// Escape\n\t\t\t\tif (e.key === \"Escape\") {\n\t\t\t\t\tif (isEditing) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tonStateChange({ ...state, editingBlockId: null });\n\t\t\t\t\t\tfocusTimerRef.current = setTimeout(\n\t\t\t\t\t\t\t() => layerRef.current?.focus(),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (selectedBlockIds.length > 0) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (isEditing) return;\n\n\t\t\t\t// Ctrl+Z: Undo\n\t\t\t\tif (\n\t\t\t\t\te.key.toLowerCase() === \"z\" &&\n\t\t\t\t\t(e.ctrlKey || e.metaKey) &&\n\t\t\t\t\t!e.shiftKey\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tactionContext?.execute(\"undo\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+Y / Ctrl+Shift+Z: Redo\n\t\t\t\tif (\n\t\t\t\t\t(e.key.toLowerCase() === \"y\" && (e.ctrlKey || e.metaKey)) ||\n\t\t\t\t\t(e.key.toLowerCase() === \"z\" &&\n\t\t\t\t\t\t(e.ctrlKey || e.metaKey) &&\n\t\t\t\t\t\te.shiftKey)\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tactionContext?.execute(\"redo\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+C: コピー\n\t\t\t\tif (\n\t\t\t\t\te.key === \"c\" &&\n\t\t\t\t\t(e.ctrlKey || e.metaKey) &&\n\t\t\t\t\tselectedBlockIds.length > 0\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tactionContext.execute(\"copy\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+X: カット(コピー → 削除)\n\t\t\t\tif (\n\t\t\t\t\te.key === \"x\" &&\n\t\t\t\t\t(e.ctrlKey || e.metaKey) &&\n\t\t\t\t\tselectedBlockIds.length > 0\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tactionContext.execute(\"copy\");\n\t\t\t\t\tconst deletedIds = new Set(selectedBlockIds);\n\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t...page,\n\t\t\t\t\t\tblocks: blocks.filter((b) => !deletedIds.has(b.id)),\n\t\t\t\t\t});\n\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+V: ペースト\n\t\t\t\tif (e.key === \"v\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\tif (actionContext.isEnabled(\"paste\")) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tactionContext.execute(\"paste\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+D: 複製\n\t\t\t\tif (\n\t\t\t\t\te.key === \"d\" &&\n\t\t\t\t\t(e.ctrlKey || e.metaKey) &&\n\t\t\t\t\tselectedBlockIds.length > 0\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tconst selected = blocks.filter((b) =>\n\t\t\t\t\t\tselectedBlockIds.includes(b.id),\n\t\t\t\t\t);\n\t\t\t\t\tconst newBlocks = selected.map((b) => {\n\t\t\t\t\t\tconst { x, y } = calcDuplicatePosition(\n\t\t\t\t\t\t\tb.layout,\n\t\t\t\t\t\t\tgridLength.cols,\n\t\t\t\t\t\t\tgridLength.rows,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...b,\n\t\t\t\t\t\t\tid: createBlockId(b.kind),\n\t\t\t\t\t\t\tlayout: { ...b.layout, x, y },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tonPageChange({ ...page, blocks: [...blocks, ...newBlocks] });\n\t\t\t\t\tonSelectionChange(newBlocks.map((b) => b.id));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Delete / Backspace: 削除\n\t\t\t\tif (\n\t\t\t\t\t(e.key === \"Delete\" || e.key === \"Backspace\") &&\n\t\t\t\t\tselectedBlockIds.length > 0\n\t\t\t\t) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tconst deletedIds = new Set(selectedBlockIds);\n\t\t\t\t\tonPageChange({\n\t\t\t\t\t\t...page,\n\t\t\t\t\t\tblocks: blocks.filter((b) => !deletedIds.has(b.id)),\n\t\t\t\t\t});\n\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Ctrl+A: 全選択\n\t\t\t\tif (e.key === \"a\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\tif (blocks.length === 0) return;\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tonSelectionChange(blocks.map((b) => b.id));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Tab: ブロック間巡回\n\t\t\t\tif (e.key === \"Tab\") {\n\t\t\t\t\tif (blocks.length === 0) return;\n\t\t\t\t\tconst sorted = [...blocks].sort((a, b) =>\n\t\t\t\t\t\ta.layout.y !== b.layout.y\n\t\t\t\t\t\t\t? a.layout.y - b.layout.y\n\t\t\t\t\t\t\t: a.layout.x - b.layout.x,\n\t\t\t\t\t);\n\t\t\t\t\tconst selectedId =\n\t\t\t\t\t\tselectedBlockIds.length === 1 ? selectedBlockIds[0] : null;\n\t\t\t\t\tconst curIdx =\n\t\t\t\t\t\tselectedId !== null\n\t\t\t\t\t\t\t? sorted.findIndex((b) => b.id === selectedId)\n\t\t\t\t\t\t\t: -1;\n\n\t\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\t\tif (curIdx <= 0) {\n\t\t\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst prev = sorted[curIdx - 1];\n\t\t\t\t\t\tif (!prev) return;\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tonSelectionChange([prev.id]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (curIdx === -1) {\n\t\t\t\t\t\t\tconst first = sorted[0];\n\t\t\t\t\t\t\tif (!first) return;\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tonSelectionChange([first.id]);\n\t\t\t\t\t\t} else if (curIdx >= sorted.length - 1) {\n\t\t\t\t\t\t\tonSelectionChange([]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst next = sorted[curIdx + 1];\n\t\t\t\t\t\t\tif (!next) return;\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tonSelectionChange([next.id]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// 矢印キー: 1グリッド移動\n\t\t\t\tif (selectedBlockIds.length === 0) return;\n\n\t\t\t\t// Shift+矢印キー: 1グリッドリサイズ\n\t\t\t\tif (e.shiftKey) {\n\t\t\t\t\tconst resizeDeltas: Record<string, { dw: number; dh: number }> = {\n\t\t\t\t\t\tArrowRight: { dw: 1, dh: 0 },\n\t\t\t\t\t\tArrowLeft: { dw: -1, dh: 0 },\n\t\t\t\t\t\tArrowDown: { dw: 0, dh: 1 },\n\t\t\t\t\t\tArrowUp: { dw: 0, dh: -1 },\n\t\t\t\t\t};\n\t\t\t\t\tconst resizeDelta = resizeDeltas[e.key];\n\t\t\t\t\tif (!resizeDelta) return;\n\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\t// セッション判定: 方向またはブロック選択が変わったら新セッション\n\t\t\t\t\tconst sortedResizeIds = [...selectedBlockIds].sort().join(\",\");\n\t\t\t\t\tconst prevResize = resizeSessionRef.current;\n\t\t\t\t\tif (\n\t\t\t\t\t\tprevResize === null ||\n\t\t\t\t\t\tprevResize.direction !== e.key ||\n\t\t\t\t\t\tprevResize.blockIds !== sortedResizeIds\n\t\t\t\t\t) {\n\t\t\t\t\t\tresizeSessionCounterRef.current += 1;\n\t\t\t\t\t\tresizeSessionRef.current = {\n\t\t\t\t\t\t\tdirection: e.key,\n\t\t\t\t\t\t\tblockIds: sortedResizeIds,\n\t\t\t\t\t\t\tid: resizeSessionCounterRef.current,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst resizeSession = resizeSessionRef.current;\n\t\t\t\t\tif (!resizeSession) return;\n\n\t\t\t\t\tonPageChange(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\tblocks: blocks.map((b) => {\n\t\t\t\t\t\t\t\tif (!selectedBlockIds.includes(b.id)) return b;\n\t\t\t\t\t\t\t\tconst w = Math.max(\n\t\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\t\t\tb.layout.w + resizeDelta.dw,\n\t\t\t\t\t\t\t\t\t\tgridLength.cols - b.layout.x,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst h = Math.max(\n\t\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\t\t\tb.layout.h + resizeDelta.dh,\n\t\t\t\t\t\t\t\t\t\tgridLength.rows - b.layout.y,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn { ...b, layout: { ...b.layout, w, h } };\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmergeKey: keyboardResizeKey(String(resizeSession.id)),\n\t\t\t\t\t\t\tnoTimeWindow: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst arrowDeltas: Record<\n\t\t\t\t\tstring,\n\t\t\t\t\t{ deltaCol: number; deltaRow: number }\n\t\t\t\t> = {\n\t\t\t\t\tArrowLeft: { deltaCol: -1, deltaRow: 0 },\n\t\t\t\t\tArrowRight: { deltaCol: 1, deltaRow: 0 },\n\t\t\t\t\tArrowUp: { deltaCol: 0, deltaRow: -1 },\n\t\t\t\t\tArrowDown: { deltaCol: 0, deltaRow: 1 },\n\t\t\t\t};\n\t\t\t\tconst delta = arrowDeltas[e.key];\n\t\t\t\tif (!delta) return;\n\n\t\t\t\te.preventDefault();\n\t\t\t\tconst selected = blocks.filter((b) => selectedBlockIds.includes(b.id));\n\t\t\t\tconst canMove = selected.every((b) => {\n\t\t\t\t\tconst nx = b.layout.x + delta.deltaCol;\n\t\t\t\t\tconst ny = b.layout.y + delta.deltaRow;\n\t\t\t\t\treturn (\n\t\t\t\t\t\tnx >= 0 &&\n\t\t\t\t\t\tnx + b.layout.w <= gridLength.cols &&\n\t\t\t\t\t\tny >= 0 &&\n\t\t\t\t\t\tny + b.layout.h <= gridLength.rows\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t\tif (!canMove) return;\n\n\t\t\t\t// セッション判定: 方向またはブロック選択が変わったら新セッション\n\t\t\t\tconst sortedIds = [...selectedBlockIds].sort().join(\",\");\n\t\t\t\tconst prev = arrowSessionRef.current;\n\t\t\t\tif (\n\t\t\t\t\tprev === null ||\n\t\t\t\t\tprev.direction !== e.key ||\n\t\t\t\t\tprev.blockIds !== sortedIds\n\t\t\t\t) {\n\t\t\t\t\tarrowSessionCounterRef.current += 1;\n\t\t\t\t\tarrowSessionRef.current = {\n\t\t\t\t\t\tdirection: e.key,\n\t\t\t\t\t\tblockIds: sortedIds,\n\t\t\t\t\t\tid: arrowSessionCounterRef.current,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// arrowSessionRef.current は上のブロックで必ず設定される\n\t\t\t\tconst session = arrowSessionRef.current;\n\t\t\t\tif (!session) return;\n\t\t\t\tconst sessionId = String(session.id);\n\n\t\t\t\tonPageChange(\n\t\t\t\t\t{\n\t\t\t\t\t\t...page,\n\t\t\t\t\t\tblocks: blocks.map((b) =>\n\t\t\t\t\t\t\tselectedBlockIds.includes(b.id)\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t...b,\n\t\t\t\t\t\t\t\t\t\tlayout: {\n\t\t\t\t\t\t\t\t\t\t\t...b.layout,\n\t\t\t\t\t\t\t\t\t\t\tx: b.layout.x + delta.deltaCol,\n\t\t\t\t\t\t\t\t\t\t\ty: b.layout.y + delta.deltaRow,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: b,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\t{ mergeKey: arrowMoveKey(sessionId), noTimeWindow: true },\n\t\t\t\t);\n\t\t\t},\n\t\t\t[\n\t\t\t\tmode,\n\t\t\t\tselectedBlockIds,\n\t\t\t\tblocks,\n\t\t\t\tpage,\n\t\t\t\tgridLength,\n\t\t\t\tstate,\n\t\t\t\tonStateChange,\n\t\t\t\tonSelectionChange,\n\t\t\t\tonPageChange,\n\t\t\t\tactionContext,\n\t\t\t],\n\t\t);\n\n\t\t// keyUp ではセッションをリセットしない。\n\t\t// セッションは「方向変更」または「ブロック選択変更」でのみ切り替わる。\n\t\t// これにより、同じ方向へ複数回押した場合もすべて同一セッション(同一 mergeKey)に入り、\n\t\t// Ctrl+Z 1 回で一括 Undo できる。\n\n\t\t// リサイズハンドルのポインターダウン処理\n\t\tconst handleResizeStart = useCallback(\n\t\t\t(e: React.PointerEvent, handle: ResizeHandle, blockId: string) => {\n\t\t\t\tif (mode === InteractionMode.EDITING) {\n\t\t\t\t\tonStateChange({ ...state, editingBlockId: null });\n\t\t\t\t}\n\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\n\n\t\t\t\tconst block = blocks.find((b) => b.id === blockId);\n\t\t\t\tif (!block) return;\n\n\t\t\t\tconst startCol = (() => {\n\t\t\t\t\tswitch (handle) {\n\t\t\t\t\t\tcase ResizeHandle.E:\n\t\t\t\t\t\tcase ResizeHandle.NE:\n\t\t\t\t\t\tcase ResizeHandle.SE:\n\t\t\t\t\t\t\treturn block.layout.x + block.layout.w;\n\t\t\t\t\t\tcase ResizeHandle.W:\n\t\t\t\t\t\tcase ResizeHandle.NW:\n\t\t\t\t\t\tcase ResizeHandle.SW:\n\t\t\t\t\t\t\treturn block.layout.x;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\tconst startRow = (() => {\n\t\t\t\t\tswitch (handle) {\n\t\t\t\t\t\tcase ResizeHandle.S:\n\t\t\t\t\t\tcase ResizeHandle.SE:\n\t\t\t\t\t\tcase ResizeHandle.SW:\n\t\t\t\t\t\t\treturn block.layout.y + block.layout.h;\n\t\t\t\t\t\tcase ResizeHandle.N:\n\t\t\t\t\t\tcase ResizeHandle.NE:\n\t\t\t\t\t\tcase ResizeHandle.NW:\n\t\t\t\t\t\t\treturn block.layout.y;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t})();\n\n\t\t\t\tonStateChange({\n\t\t\t\t\t...state,\n\t\t\t\t\tdragging: {\n\t\t\t\t\t\ttype: DragType.RESIZE,\n\t\t\t\t\t\tblockIds: [blockId],\n\t\t\t\t\t\tstartGrid: { col: startCol, row: startRow },\n\t\t\t\t\t\tcurrentGrid: { col: startCol, row: startRow },\n\t\t\t\t\t\thandle,\n\t\t\t\t\t\tisOutside: false,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t},\n\t\t\t[mode, state, blocks, onStateChange],\n\t\t);\n\n\t\t// 編集中ブロックのレンダリング\n\t\tconst editingContent = (() => {\n\t\t\tif (!state.editingBlockId) return null;\n\t\t\tconst editingBlock = blocks.find((b) => b.id === state.editingBlockId);\n\t\t\tconst resolved = editingBlock ? pluginRegistry[editingBlock.kind] : null;\n\t\t\tif (!editingBlock || !resolved) return null;\n\n\t\t\tconst props = resolveBlockProps(editingBlock, resolved, blockDefaults);\n\n\t\t\treturn (\n\t\t\t\t<EditingBlock\n\t\t\t\t\tref={editingBlockRef}\n\t\t\t\t\tid={editingBlock.id}\n\t\t\t\t\tresolvedPlugin={resolved}\n\t\t\t\t\tprops={props}\n\t\t\t\t\tvalue={editingBlock.initValue ?? null}\n\t\t\t\t\tonChange={(val) => {\n\t\t\t\t\t\tonPageChange(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...page,\n\t\t\t\t\t\t\t\tblocks: blocks.map((b) =>\n\t\t\t\t\t\t\t\t\tb.id === editingBlock.id ? { ...b, initValue: val } : b,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ mergeKey: initValueKey(editingBlock.id) },\n\t\t\t\t\t\t);\n\t\t\t\t\t}}\n\t\t\t\t\tblockRectPx={getBlockRectPx(editingBlock)}\n\t\t\t\t\tblock={editingBlock}\n\t\t\t\t\tbindingContext={bindingContext}\n\t\t\t\t\tactionContext={actionContext}\n\t\t\t\t/>\n\t\t\t);\n\t\t})();\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={layerRef}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tinset: 0,\n\t\t\t\t\tzIndex: Z_INDEX.INTERACTION_LAYER_BASE,\n\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\ttouchAction: \"none\",\n\t\t\t\t}}\n\t\t\t\trole=\"application\"\n\t\t\t\taria-label=\"Interactive canvas layer\"\n\t\t\t\ttabIndex={-1}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\tonPointerLeave={handlePointerLeave}\n\t\t\t\tonDoubleClick={handleDoubleClick}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tdata-testid=\"interaction-layer\"\n\t\t\t>\n\t\t\t\t{/* 編集中ブロック */}\n\t\t\t\t{editingContent}\n\n\t\t\t\t{/* 選択枠 + リサイズハンドル */}\n\t\t\t\t<SelectionLayer\n\t\t\t\t\tblocks={blocks}\n\t\t\t\t\tselectedBlockIds={selectedBlockIds}\n\t\t\t\t\tisDragging={mode === InteractionMode.DRAGGING}\n\t\t\t\t\tdraggingState={state.dragging}\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\n\t\t\t\t\tonResizeStart={handleResizeStart}\n\t\t\t\t\tselectionStyle={selectionStyle}\n\t\t\t\t/>\n\n\t\t\t\t{/* ドラッグゴースト */}\n\t\t\t\t<DragLayer\n\t\t\t\t\tblocks={blocks}\n\t\t\t\t\tpluginRegistry={pluginRegistry}\n\t\t\t\t\tgridLength={gridLength}\n\t\t\t\t\tdraggingState={state.dragging}\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\n\t\t\t\t\tblockDefaults={blockDefaults}\n\t\t\t\t\tselectionStyle={selectionStyle}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nInteractionLayer.displayName = \"InteractionLayer\";\n","import { createContext } from \"react\";\n\nimport type { PluginRegistry } from \"./registry\";\n\n/**\n * `createPluginRegistry` で生成したプラグインレジストリを React ツリーに注入するコンテキスト。\n *\n * `null` はプロバイダーが未設定であることを示す。\n */\nexport const PluginRegistryContext = createContext<PluginRegistry | null>(null);\n","import { toMm, toPx } from \"../convert\";\n\nimport type { Dimension, GridUnit } from \"../../types\";\n\n// px 値を指定された単位に変換する関数\nfunction convertPxToUnit(pxValue: number, unit: GridUnit): number {\n\tswitch (unit) {\n\t\tcase \"px\":\n\t\t\treturn Math.round(pxValue);\n\t\tcase \"mm\":\n\t\t\treturn Math.round(toMm.fromPx(pxValue) * 10) / 10;\n\t\tcase \"cm\":\n\t\t\treturn Math.round((toMm.fromPx(pxValue) / 10) * 100) / 100;\n\t\tcase \"inch\":\n\t\t\treturn Math.round((toMm.fromPx(pxValue) / 25.4) * 100) / 100;\n\t\tcase \"pt\":\n\t\t\treturn Math.round((toMm.fromPx(pxValue) / 25.4) * 72 * 10) / 10;\n\t\tcase \"fr\":\n\t\t\treturn 1;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = unit;\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\n// fr と固定単位をリサイズする関数\nfunction resizeFrAndFixed(\n\tdimensions: Dimension<GridUnit>[],\n\tindex: number,\n\tdeltaPx: number,\n\tfixedSide: \"current\" | \"next\",\n\ttotalContentPx: number,\n): Dimension<GridUnit>[] {\n\tconst current = dimensions[index];\n\tconst next = dimensions[index + 1];\n\tif (!current || !next) return dimensions;\n\n\tlet totalFr = 0;\n\tlet totalFixedPx = 0;\n\tfor (const dim of dimensions) {\n\t\tif (dim.unit === \"fr\") totalFr += dim.value;\n\t\telse totalFixedPx += toPx.fromDim(dim);\n\t}\n\n\tconst availableForFrPx = totalContentPx - totalFixedPx;\n\tconst currentFrToPx = totalFr > 0 ? availableForFrPx / totalFr : 0;\n\n\tif (fixedSide === \"next\") {\n\t\tconst nextPx = toPx.fromDim(next);\n\t\tconst newNextPx = Math.max(10, nextPx - deltaPx);\n\t\tdimensions[index + 1] = {\n\t\t\t...next,\n\t\t\tvalue: convertPxToUnit(newNextPx, next.unit),\n\t\t};\n\t\tconst newAvailableForFrPx = availableForFrPx - (newNextPx - nextPx);\n\t\tconst newCurrentPx = Math.max(10, current.value * currentFrToPx + deltaPx);\n\t\tconst newCurrentFr =\n\t\t\ttotalFr > 0 ? (newCurrentPx / newAvailableForFrPx) * totalFr : 1;\n\t\tdimensions[index] = {\n\t\t\t...current,\n\t\t\tvalue: Math.round(newCurrentFr * 100) / 100,\n\t\t};\n\t} else {\n\t\tconst currentPx = toPx.fromDim(current);\n\t\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\n\t\tdimensions[index] = {\n\t\t\t...current,\n\t\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\n\t\t};\n\t\tconst newAvailableForFrPx = availableForFrPx - (newCurrentPx - currentPx);\n\t\tconst newNextPx = Math.max(10, next.value * currentFrToPx - deltaPx);\n\t\tconst newNextFr =\n\t\t\ttotalFr > 0 ? (newNextPx / newAvailableForFrPx) * totalFr : 1;\n\t\tdimensions[index + 1] = {\n\t\t\t...next,\n\t\t\tvalue: Math.round(newNextFr * 100) / 100,\n\t\t};\n\t}\n\treturn dimensions;\n}\n\n// 固定単位同士をリサイズする関数\nfunction resizeFixedPair(\n\tdimensions: Dimension<GridUnit>[],\n\tindex: number,\n\tdeltaPx: number,\n): Dimension<GridUnit>[] {\n\tconst current = dimensions[index];\n\tconst next = dimensions[index + 1];\n\tif (!current || !next) return dimensions;\n\n\tconst newCurrentPx = Math.max(10, toPx.fromDim(current) + deltaPx);\n\tconst newNextPx = Math.max(10, toPx.fromDim(next) - deltaPx);\n\n\tdimensions[index] = {\n\t\t...current,\n\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\n\t};\n\tdimensions[index + 1] = {\n\t\t...next,\n\t\tvalue: convertPxToUnit(newNextPx, next.unit),\n\t};\n\treturn dimensions;\n}\n\n// fr 同士をリサイズする関数\nfunction resizeFrPair(\n\tdimensions: Dimension<GridUnit>[],\n\tindex: number,\n\tdeltaPx: number,\n\ttotalContentPx: number,\n): Dimension<GridUnit>[] {\n\tconst current = dimensions[index];\n\tconst next = dimensions[index + 1];\n\tif (!current || !next) return dimensions;\n\n\tconst totalFr = dimensions.reduce(\n\t\t(sum, dim) => (dim.unit === \"fr\" ? sum + dim.value : sum),\n\t\t0,\n\t);\n\tconst frToPx = totalContentPx / totalFr;\n\tconst newCurrentFr = Math.max(10, current.value * frToPx + deltaPx) / frToPx;\n\tconst newNextFr = Math.max(10, next.value * frToPx - deltaPx) / frToPx;\n\n\tdimensions[index] = {\n\t\t...current,\n\t\tvalue: Math.round(newCurrentFr * 100) / 100,\n\t};\n\tdimensions[index + 1] = { ...next, value: Math.round(newNextFr * 100) / 100 };\n\treturn dimensions;\n}\n\n/**\n * グリッドの列または行をドラッグリサイズしたときの新しいサイズ配列を計算する。\n *\n * `index` 番目と `index + 1` 番目を隣接ペアとして扱い、\n * `fr` / 固定 / 混在の組み合わせに応じて適切な計算を行う。最小サイズは 10px に固定される。\n *\n * @param dimensions リサイズ前のサイズ配列\n * @param index リサイズ起点となる列/行のインデックス\n * @param deltaPx ドラッグ量uff08pxuff09。正値で右/下に拡大\n * @param totalContentPx コンテンツ領域の合計幅/高さuff08pxuff09。`fr` 計算に使用\n */\nexport function calcGridResize(\n\tdimensions: Dimension<GridUnit>[],\n\tindex: number,\n\tdeltaPx: number,\n\ttotalContentPx: number,\n): Dimension<GridUnit>[] {\n\tif (index < 0 || index >= dimensions.length) return dimensions;\n\n\tconst newDimensions = [...dimensions];\n\tconst current = newDimensions[index];\n\tconst next = newDimensions[index + 1];\n\tif (!current || !next) return dimensions;\n\n\tif (current.unit === \"fr\" && next.unit === \"fr\") {\n\t\treturn resizeFrPair(newDimensions, index, deltaPx, totalContentPx);\n\t}\n\tif (current.unit !== \"fr\" && next.unit !== \"fr\") {\n\t\treturn resizeFixedPair(newDimensions, index, deltaPx);\n\t}\n\tif (current.unit === \"fr\" && next.unit !== \"fr\") {\n\t\treturn resizeFrAndFixed(\n\t\t\tnewDimensions,\n\t\t\tindex,\n\t\t\tdeltaPx,\n\t\t\t\"next\",\n\t\t\ttotalContentPx,\n\t\t);\n\t}\n\treturn resizeFrAndFixed(\n\t\tnewDimensions,\n\t\tindex,\n\t\tdeltaPx,\n\t\t\"current\",\n\t\ttotalContentPx,\n\t);\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { useGridCalc } from \"../../canvas/layers/GridLayer/hooks\";\nimport { evaluateValidation, hasValidationRule } from \"../../plugin\";\nimport { evalHiddenBinding } from \"../../utils/block\";\nimport { DEFAULT_DPI } from \"../../utils/convert\";\n\nimport type { BindingContext } from \"../../types/context\";\nimport type { Book } from \"../../types/schema\";\nimport type { ValidationError } from \"../../types/validation\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * `useNoteLayout` の入力パラメータ。\n *\n * @internal\n */\ninterface UseNoteLayoutParams {\n\t/** 表示対象の Book。 */\n\tbook: Book;\n\n\t/** 表示するページのインデックス。 */\n\tpageIdx: number;\n\n\t/** `true` のときバリデーションエラーを計算する。 */\n\tshowValidation: boolean;\n\n\t/** 入力コントロールの現在値マップ(バリデーション評価に使用)。 */\n\tvalues: Record<string, Value>;\n\n\t/** hidden バインディング解決に使用する BindingContext。 */\n\tbindingContext?: BindingContext;\n}\n\n/**\n * `NoteEdit` / `NoteView` で共通する寸法計算・バリデーション計算ロジック。\n *\n * グリッド座標 → px 変換、autoHeight / autoWidth 対応の canvas サイズ計算、\n * バリデーションエラーの集約を行い、各描画コンポーネントに渡す値を返す。\n *\n * @remarks\n * `NoteEdit` / `NoteView` の内部フック。\n * 独自レイアウトが必要な場合のみ直接利用すること。\n */\nexport function useNoteLayout({\n\tbook,\n\tpageIdx,\n\tshowValidation,\n\tvalues,\n\tbindingContext,\n}: UseNoteLayoutParams) {\n\tconst page = book.pages[pageIdx] ?? book.pages[0];\n\tconst paper = book.paper;\n\n\tconst { paperPx, gridPosPx, getBlockRectPx } = useGridCalc(\n\t\tpaper,\n\t\tpage.grid,\n\t\tDEFAULT_DPI,\n\t);\n\n\tconst isFit = paper.autoHeight === true;\n\tconst isWidthFit = paper.autoWidth === true;\n\n\tconst [measuredHeights, setMeasuredHeights] = useState<Map<string, number>>(\n\t\tnew Map(),\n\t);\n\tconst [measuredWidths, setMeasuredWidths] = useState<Map<string, number>>(\n\t\tnew Map(),\n\t);\n\n\tconst handleMeasureHeight = useCallback(\n\t\t(blockId: string, heightPx: number) => {\n\t\t\tsetMeasuredHeights((prev) => {\n\t\t\t\tif (prev.get(blockId) === heightPx) return prev;\n\t\t\t\tconst next = new Map(prev);\n\t\t\t\tnext.set(blockId, heightPx);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\tconst handleMeasureWidth = useCallback((blockId: string, widthPx: number) => {\n\t\tsetMeasuredWidths((prev) => {\n\t\t\tif (prev.get(blockId) === widthPx) return prev;\n\t\t\tconst next = new Map(prev);\n\t\t\tnext.set(blockId, widthPx);\n\t\t\treturn next;\n\t\t});\n\t}, []);\n\n\tconst measuredContentBottomPx = useMemo(() => {\n\t\tif (!isFit || measuredHeights.size === 0) return 0;\n\t\tlet maxBottom = 0;\n\t\tfor (const block of page.blocks) {\n\t\t\tconst isHidden = evalHiddenBinding(block.hiddenBinding, bindingContext);\n\t\t\tif (isHidden) continue;\n\t\t\tconst rect = getBlockRectPx(block);\n\t\t\tconst blockH = measuredHeights.get(block.id) ?? rect.height;\n\t\t\tmaxBottom = Math.max(maxBottom, rect.top - paperPx.margin.top + blockH);\n\t\t}\n\t\treturn maxBottom;\n\t}, [\n\t\tisFit,\n\t\tmeasuredHeights,\n\t\tpage.blocks,\n\t\tgetBlockRectPx,\n\t\tpaperPx.margin.top,\n\t\tbindingContext,\n\t]);\n\n\tconst measuredContentRightPx = useMemo(() => {\n\t\tif (!isWidthFit || measuredWidths.size === 0) return 0;\n\t\tlet maxRight = 0;\n\t\tfor (const block of page.blocks) {\n\t\t\tconst isHidden = evalHiddenBinding(block.hiddenBinding, bindingContext);\n\t\t\tif (isHidden) continue;\n\t\t\tconst rect = getBlockRectPx(block);\n\t\t\tconst blockW = measuredWidths.get(block.id) ?? rect.width;\n\t\t\tmaxRight = Math.max(maxRight, rect.left - paperPx.margin.left + blockW);\n\t\t}\n\t\treturn maxRight;\n\t}, [\n\t\tisWidthFit,\n\t\tmeasuredWidths,\n\t\tpage.blocks,\n\t\tgetBlockRectPx,\n\t\tpaperPx.margin.left,\n\t\tbindingContext,\n\t]);\n\n\tconst canvasHeightPx = useMemo(() => {\n\t\tif (!isFit) return paperPx.canvas.height;\n\t\tif (measuredContentBottomPx === 0 && measuredHeights.size === 0) {\n\t\t\treturn paperPx.canvas.height;\n\t\t}\n\t\treturn (\n\t\t\tpaperPx.margin.top +\n\t\t\tMath.max(0, measuredContentBottomPx) +\n\t\t\tpaperPx.margin.bottom\n\t\t);\n\t}, [isFit, paperPx, measuredContentBottomPx, measuredHeights.size]);\n\n\tconst canvasWidthPx = useMemo(() => {\n\t\tconst gridTotalWidth =\n\t\t\t(gridPosPx.cols[gridPosPx.cols.length - 1] ?? 0) +\n\t\t\tpaperPx.margin.left +\n\t\t\tpaperPx.margin.right;\n\t\tif (!isWidthFit) return gridTotalWidth;\n\t\tif (measuredContentRightPx === 0 && measuredWidths.size === 0) {\n\t\t\treturn gridTotalWidth;\n\t\t}\n\t\tconst fitWidth =\n\t\t\tpaperPx.margin.left +\n\t\t\tMath.max(0, measuredContentRightPx) +\n\t\t\tpaperPx.margin.right;\n\t\treturn Math.max(gridTotalWidth, fitWidth);\n\t}, [\n\t\tisWidthFit,\n\t\tpaperPx,\n\t\tgridPosPx.cols,\n\t\tmeasuredContentRightPx,\n\t\tmeasuredWidths.size,\n\t]);\n\n\tconst effectivePaperPx = useMemo(\n\t\t() => ({\n\t\t\t...paperPx,\n\t\t\tcanvas: {\n\t\t\t\t...paperPx.canvas,\n\t\t\t\theight: canvasHeightPx,\n\t\t\t\twidth: canvasWidthPx,\n\t\t\t},\n\t\t}),\n\t\t[paperPx, canvasHeightPx, canvasWidthPx],\n\t);\n\n\tconst validationErrors = useMemo(():\n\t\t| Record<string, ValidationError[]>\n\t\t| undefined => {\n\t\tif (!showValidation) return undefined;\n\t\tconst result: Record<string, ValidationError[]> = {};\n\t\tfor (const block of page.blocks) {\n\t\t\tif (!hasValidationRule(block.props)) continue;\n\t\t\tconst raw = values[block.id];\n\t\t\tconst strVal =\n\t\t\t\traw === null || raw === undefined ? undefined : String(raw);\n\t\t\tconst errors = evaluateValidation(block.props, strVal);\n\t\t\tif (errors.length > 0) result[block.id] = errors;\n\t\t}\n\t\treturn result;\n\t}, [showValidation, page.blocks, values]);\n\n\treturn {\n\t\tpage,\n\t\tisFit,\n\t\tisWidthFit,\n\t\tpaperPx,\n\t\tgridPosPx,\n\t\tgetBlockRectPx,\n\t\tmeasuredHeights,\n\t\tmeasuredWidths,\n\t\thandleMeasureHeight,\n\t\thandleMeasureWidth,\n\t\tcanvasHeightPx,\n\t\tcanvasWidthPx,\n\t\teffectivePaperPx,\n\t\tvalidationErrors,\n\t};\n}\n","import { memo, useCallback, useMemo, useState } from \"react\";\n\nimport { BlockLayer, GridLayer } from \"../../canvas/layers\";\nimport { PluginRegistryContext } from \"../../plugin/context\";\nimport { NoteMode } from \"../../types/mode\";\nimport { STACKING_ISOLATION_STYLE } from \"../../utils/zIndex\";\nimport { useNoteLayout } from \"../hooks/useNoteLayout\";\n\nimport type { NoteContext } from \"../../contexts/useNoteContext\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * {@link NoteEdit} の props。\n */\nexport interface NoteEditProps {\n\t/** `useNoteContext` が返すコンテキスト。 */\n\tcontext: NoteContext;\n\n\t/** `true` のときバリデーションエラーを表示する(デフォルト: false)。 */\n\tshowValidation?: boolean;\n\n\t/** 表示倍率(デフォルト: 1)。 */\n\tscale?: number;\n\n\t/** ルート要素に追加する className。 */\n\tclassName?: string;\n}\n\n/**\n * 値入力モード(EDIT モード)専用コンポーネント。\n *\n * ブロックの配置・サイズ変更は不可。直接 value を編集できる。\n * `useNoteContext` で生成した `context` を渡して使用する。\n *\n * @remarks 通常は {@link Note} を `mode={NoteMode.EDIT}` で使用する。\n */\nexport const NoteEdit = memo(function NoteEdit({\n\tcontext,\n\tshowValidation = false,\n\tscale = 1.0,\n\tclassName,\n}: NoteEditProps) {\n\tconst { book, pluginRegistry } = context;\n\n\tconst values = context.values;\n\tconst onValuesChange = context.onValuesChange;\n\tconst onValueChange = useCallback(\n\t\t(id: string, value: Value) => onValuesChange?.([{ id, value }]),\n\t\t[onValuesChange],\n\t);\n\n\tconst {\n\t\tpage,\n\t\tisFit,\n\t\tisWidthFit,\n\t\tgridPosPx,\n\t\tgetBlockRectPx,\n\t\thandleMeasureHeight,\n\t\thandleMeasureWidth,\n\t\tcanvasHeightPx,\n\t\tcanvasWidthPx,\n\t\teffectivePaperPx,\n\t\tvalidationErrors,\n\t} = useNoteLayout({\n\t\tbook,\n\t\tpageIdx: context.editorState.pageIdx,\n\t\tshowValidation,\n\t\tvalues,\n\t\tbindingContext: context.bindingContext,\n\t});\n\n\tconst [focusedBlockId, setFocusedBlockId] = useState<string | null>(null);\n\n\t// Tab キーで視覚的な順序(上→下、左→右)にフォーカスが移るようグリッド順でソート\n\tconst sortedBlocks = useMemo(\n\t\t() =>\n\t\t\t[...page.blocks].sort((a, b) =>\n\t\t\t\ta.layout.y !== b.layout.y\n\t\t\t\t\t? a.layout.y - b.layout.y\n\t\t\t\t\t: a.layout.x - b.layout.x,\n\t\t\t),\n\t\t[page.blocks],\n\t);\n\n\tconst handleFocusCapture = useCallback((e: React.FocusEvent<HTMLElement>) => {\n\t\tconst blockEl = (e.target as Element).closest(\"[data-block-id]\");\n\t\tsetFocusedBlockId(blockEl?.getAttribute(\"data-block-id\") ?? null);\n\t}, []);\n\n\tconst handleBlurCapture = useCallback((e: React.FocusEvent<HTMLElement>) => {\n\t\tif (!e.currentTarget.contains(e.relatedTarget as Node)) {\n\t\t\tsetFocusedBlockId(null);\n\t\t}\n\t}, []);\n\n\treturn (\n\t\t<PluginRegistryContext.Provider value={pluginRegistry}>\n\t\t\t<form\n\t\t\t\tdata-testid=\"note-container\"\n\t\t\t\taria-label=\"フォーム\"\n\t\t\t\tclassName={className}\n\t\t\t\tonSubmit={(e) => e.preventDefault()}\n\t\t\t\tonFocusCapture={handleFocusCapture}\n\t\t\t\tonBlurCapture={handleBlurCapture}\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\twidth: `${canvasWidthPx}px`,\n\t\t\t\t\theight: `${canvasHeightPx}px`,\n\t\t\t\t\tmargin: \"0 auto\",\n\t\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\n\t\t\t\t\tbackgroundColor: \"#fff\",\n\t\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\n\t\t\t\t\ttransformOrigin: \"top center\",\n\t\t\t\t\t...STACKING_ISOLATION_STYLE,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<GridLayer\n\t\t\t\t\tpaperPx={effectivePaperPx}\n\t\t\t\t\tgridPosPx={gridPosPx}\n\t\t\t\t\tshowGridLines={false}\n\t\t\t\t\tshowMargins={false}\n\t\t\t\t\tshowBorder={false}\n\t\t\t\t/>\n\t\t\t\t<BlockLayer\n\t\t\t\t\tblocks={sortedBlocks}\n\t\t\t\t\tpluginRegistry={pluginRegistry}\n\t\t\t\t\tmode={NoteMode.EDIT}\n\t\t\t\t\tvalues={values}\n\t\t\t\t\tblockDefaults={page.blockDefaults}\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\n\t\t\t\t\tonMeasureHeight={isFit ? handleMeasureHeight : undefined}\n\t\t\t\t\tonMeasureWidth={isWidthFit ? handleMeasureWidth : undefined}\n\t\t\t\t\tonValueChange={onValuesChange ? onValueChange : undefined}\n\t\t\t\t\tshowGuides={true}\n\t\t\t\t\tshowBorder={true}\n\t\t\t\t\tshowValidation={showValidation}\n\t\t\t\t\tvalidationErrors={validationErrors}\n\t\t\t\t\tfocusedBlockId={focusedBlockId ?? undefined}\n\t\t\t\t\tbindingContext={context.bindingContext}\n\t\t\t\t\tactionContext={context.actionContext}\n\t\t\t\t/>\n\t\t\t</form>\n\t\t</PluginRegistryContext.Provider>\n\t);\n});\n","import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n\tBlockLayer,\n\tGridLayer,\n\tInteractionLayer,\n\tuseInteractionState,\n} from \"../../canvas/layers\";\nimport {\n\tuseExpandedGrid,\n\tuseGridCalc,\n} from \"../../canvas/layers/GridLayer/hooks\";\nimport { DragType } from \"../../canvas/layers/InteractionLayer/types\";\nimport { clampBlockToGrid } from \"../../canvas/layers/InteractionLayer/utils/clampBlock\";\nimport { createBlock } from \"../../canvas/layers/InteractionLayer/utils/createBlock\";\nimport { initValueKey } from \"../../contexts/history/mergeKeys\";\nimport { PluginRegistryContext } from \"../../plugin/context\";\nimport { SIDEBAR_PORTAL_SELECTOR } from \"../../shell/bars/Sidebar/sidebarPortal\";\nimport { LineType } from \"../../types/line\";\nimport { NoteMode } from \"../../types/mode\";\nimport { evalHiddenBinding } from \"../../utils/block\";\nimport {\n\tBLOCK_DRAG_MIME,\n\tgetBlockDragData,\n\tgetBlockDragKind,\n} from \"../../utils/blockDrag\";\nimport { setPage } from \"../../utils/book\";\nimport { DEFAULT_DPI } from \"../../utils/convert\";\nimport { calcGridResize, colsToSparse, rowsToSparse } from \"../../utils/grid\";\nimport { STACKING_ISOLATION_STYLE } from \"../../utils/zIndex\";\n\nimport type React from \"react\";\nimport type { BlockRectPx } from \"../../canvas/layers/types\";\nimport type { NoteContext } from \"../../contexts/useNoteContext\";\nimport type { Block } from \"../../types/block\";\nimport type { Page } from \"../../types/schema\";\nimport type { Dimension, GridUnit } from \"../../types/unit\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * {@link NoteForm} の props。\n *\n * テンプレートデザインモード専用。`context` は必須。\n * `useNoteContext` を使って context を生成し、ActionBar / Sidebar と共に使用する。\n */\nexport interface NoteFormProps {\n\t/** `useNoteContext` が返すコンテキスト(必須)。 */\n\tcontext: NoteContext;\n\n\t/** 表示倍率(デフォルト: 1)。 */\n\tscale?: number;\n\n\t/** ルート要素に追加する className。 */\n\tclassName?: string;\n}\n\n/**\n * テンプレート作成モード(FORM モード)専用コンポーネント。\n *\n * ブロックの配置・サイズ変更が可能。ダブルクリックで initValue を編集できる。\n * `useNoteContext` で生成した `context` を渡す。ActionBar / Sidebar と組み合わせて使用する。\n *\n * @remarks 通常は {@link Note} を `mode={NoteMode.FORM}` で使用する。\n */\nexport const NoteForm = memo(function NoteForm({\n\tcontext,\n\tscale = 1.0,\n\tclassName,\n}: NoteFormProps) {\n\tconst { book, onBookChange, pluginRegistry } = context;\n\tconst pageIdx = context.editorState.pageIdx;\n\tconst selectedBlockIds = context.editorState.selectedBlockIds;\n\tconst actionContext = context.actionContext;\n\n\tconst page = book.pages[pageIdx] ?? book.pages[0];\n\n\t// stale closure 回避: onPageChange の deps から book/pageIdx を除去するために ref を使う\n\tconst bookRef = useRef(book);\n\tbookRef.current = book;\n\tconst pageIdxRef = useRef(pageIdx);\n\tpageIdxRef.current = pageIdx;\n\n\tconst onPageChange = useCallback(\n\t\t(\n\t\t\tnewPage: Page,\n\t\t\toptions?: { mergeKey?: string; noTimeWindow?: boolean },\n\t\t) => {\n\t\t\tif (onBookChange) {\n\t\t\t\tonBookChange(\n\t\t\t\t\tsetPage(bookRef.current, pageIdxRef.current, newPage),\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[onBookChange],\n\t);\n\n\t// --- インタラクション状態管理\n\tconst [interactionState, onStateChange] = useInteractionState();\n\n\tconst onStateChangeRef = useRef(onStateChange);\n\tonStateChangeRef.current = onStateChange;\n\n\tconst onSelectionChange = useCallback(\n\t\t(ids: string[]) => actionContext.execute(\"selectBlocks\", ids),\n\t\t[actionContext],\n\t);\n\n\t// 用紙要素への参照\n\tconst paperRef = useRef<HTMLElement>(null);\n\n\tconst { expandedCols, expandedRows } = useExpandedGrid(page.grid);\n\n\tconst { paperPx, gridPosPx, getBlockRectPx, getColIndex, getRowIndex } =\n\t\tuseGridCalc(book.paper, page.grid, DEFAULT_DPI);\n\n\t// --- ドロップゾーンハンドラ(ブロック DnD 挿入)\n\tconst handleDragEnter = useCallback(\n\t\t(e: React.DragEvent<HTMLDivElement>) => {\n\t\t\tconst kind = getBlockDragKind(e);\n\t\t\tif (!kind) return;\n\t\t\te.preventDefault();\n\t\t\tconst plugin = pluginRegistry[kind];\n\t\t\tconst defaultSize = plugin?.meta.defaultSize ?? { w: 1, h: 1 };\n\t\t\tconst rect = paperRef.current?.getBoundingClientRect();\n\t\t\tconst col = rect ? getColIndex(e.clientX - rect.left) : 0;\n\t\t\tconst row = rect ? getRowIndex(e.clientY - rect.top) : 0;\n\t\t\tonStateChangeRef.current({\n\t\t\t\teditingBlockId: null,\n\t\t\t\tdragging: {\n\t\t\t\t\ttype: DragType.INSERT,\n\t\t\t\t\tblockIds: [],\n\t\t\t\t\tpluginKind: kind,\n\t\t\t\t\tdefaultSize,\n\t\t\t\t\tstartGrid: { col, row },\n\t\t\t\t\tcurrentGrid: { col, row },\n\t\t\t\t\tcurrentMousePx: { x: e.clientX, y: e.clientY },\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\t[pluginRegistry, getColIndex, getRowIndex],\n\t);\n\n\tconst handleDragOver = useCallback(\n\t\t(e: React.DragEvent<HTMLDivElement>) => {\n\t\t\tif (!e.dataTransfer.types.includes(BLOCK_DRAG_MIME)) return;\n\t\t\te.preventDefault();\n\t\t\te.dataTransfer.dropEffect = \"copy\";\n\t\t\tconst rect = paperRef.current?.getBoundingClientRect();\n\t\t\tif (!rect) return;\n\t\t\tconst col = getColIndex(e.clientX - rect.left);\n\t\t\tconst row = getRowIndex(e.clientY - rect.top);\n\t\t\tonStateChangeRef.current((prev) => {\n\t\t\t\tif (prev.dragging?.type !== DragType.INSERT) return prev;\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tdragging: {\n\t\t\t\t\t\t...prev.dragging,\n\t\t\t\t\t\tcurrentGrid: { col, row },\n\t\t\t\t\t\tcurrentMousePx: { x: e.clientX, y: e.clientY },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[getColIndex, getRowIndex],\n\t);\n\n\tconst handleDragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n\t\tif (!e.dataTransfer.types.includes(BLOCK_DRAG_MIME)) return;\n\t\t// paper div の子孫への移動は無視(子要素へ入っても dragleave が発火するため)\n\t\tif (paperRef.current?.contains(e.relatedTarget as Node)) return;\n\t\tonStateChangeRef.current({ editingBlockId: null, dragging: undefined });\n\t}, []);\n\n\tconst handleDrop = useCallback(\n\t\t(e: React.DragEvent<HTMLDivElement>) => {\n\t\t\te.preventDefault();\n\t\t\tconst data = getBlockDragData(e);\n\t\t\tif (!data) return;\n\t\t\tconst rect = paperRef.current?.getBoundingClientRect();\n\t\t\tif (!rect) return;\n\t\t\tconst col = getColIndex(e.clientX - rect.left);\n\t\t\tconst row = getRowIndex(e.clientY - rect.top);\n\t\t\tconst defaultSize = data.defaultSize ?? { w: 1, h: 1 };\n\t\t\tconst resolved = pluginRegistry[data.kind];\n\t\t\tif (!resolved) return;\n\t\t\tconst { x, y } = clampBlockToGrid(\n\t\t\t\t{ x: col, y: row },\n\t\t\t\tdefaultSize,\n\t\t\t\tpage.grid.colCount,\n\t\t\t\tpage.grid.rowCount,\n\t\t\t);\n\t\t\tconst newBlock: Block = {\n\t\t\t\t...createBlock(resolved, { x, y }),\n\t\t\t\tlayout: { x, y, w: defaultSize.w, h: defaultSize.h },\n\t\t\t};\n\t\t\tonPageChange({ ...page, blocks: [...page.blocks, newBlock] });\n\t\t\tonSelectionChange([newBlock.id]);\n\t\t\tonStateChangeRef.current({ editingBlockId: null, dragging: undefined });\n\t\t},\n\t\t[\n\t\t\tpage,\n\t\t\tpluginRegistry,\n\t\t\tgetColIndex,\n\t\t\tgetRowIndex,\n\t\t\tonPageChange,\n\t\t\tonSelectionChange,\n\t\t],\n\t);\n\n\t// heightFit/widthFit ブロックの計測値を追跡する\n\tconst [measuredHeights, setMeasuredHeights] = useState<Map<string, number>>(\n\t\tnew Map(),\n\t);\n\tconst [measuredWidths, setMeasuredWidths] = useState<Map<string, number>>(\n\t\tnew Map(),\n\t);\n\n\tconst handleMeasureHeight = useCallback((blockId: string, h: number) => {\n\t\tsetMeasuredHeights((prev) => {\n\t\t\tif (prev.get(blockId) === h) return prev;\n\t\t\tconst next = new Map(prev);\n\t\t\tnext.set(blockId, h);\n\t\t\treturn next;\n\t\t});\n\t}, []);\n\n\tconst handleMeasureWidth = useCallback((blockId: string, w: number) => {\n\t\tsetMeasuredWidths((prev) => {\n\t\t\tif (prev.get(blockId) === w) return prev;\n\t\t\tconst next = new Map(prev);\n\t\t\tnext.set(blockId, w);\n\t\t\treturn next;\n\t\t});\n\t}, []);\n\n\tconst getAdjustedBlockRectPx = useCallback(\n\t\t(block: Block): BlockRectPx => {\n\t\t\tconst rect = getBlockRectPx(block);\n\t\t\tconst h = measuredHeights.get(block.id);\n\t\t\tconst w = measuredWidths.get(block.id);\n\t\t\treturn {\n\t\t\t\t...rect,\n\t\t\t\theight: h !== undefined ? Math.max(rect.height, h) : rect.height,\n\t\t\t\twidth: w !== undefined ? Math.max(rect.width, w) : rect.width,\n\t\t\t};\n\t\t},\n\t\t[getBlockRectPx, measuredHeights, measuredWidths],\n\t);\n\n\t// initValue 変更ハンドラ(ダブルクリックで編集)\n\tconst handleInitValueChange = useCallback(\n\t\t(id: string, val: Value) => {\n\t\t\tconst nextBlocks = page.blocks.map((block: Block) => {\n\t\t\t\tif (block.id === id) {\n\t\t\t\t\treturn { ...block, initValue: val };\n\t\t\t\t}\n\t\t\t\treturn block;\n\t\t\t});\n\t\t\tonPageChange(\n\t\t\t\t{ ...page, blocks: nextBlocks },\n\t\t\t\t{ mergeKey: initValueKey(id) },\n\t\t\t);\n\t\t},\n\t\t[page, onPageChange],\n\t);\n\n\t// 用紙外のクリックを検知して選択を解除\n\tuseEffect(() => {\n\t\tconst handleClickOutside = (event: MouseEvent) => {\n\t\t\tif (selectedBlockIds.length === 0) return;\n\n\t\t\tconst target = event.target as Node;\n\n\t\t\t// SVGElement は HTMLElement のサブクラスではないため Element で判定する\n\t\t\tif (target instanceof Element) {\n\t\t\t\tconst isSidebar = target.closest(SIDEBAR_PORTAL_SELECTOR);\n\t\t\t\tconst isActionBar = target.closest(\n\t\t\t\t\t'[data-selection-action-bar=\"true\"]',\n\t\t\t\t);\n\t\t\t\tif (isSidebar || isActionBar) return;\n\t\t\t}\n\n\t\t\tif (paperRef.current && !paperRef.current.contains(target)) {\n\t\t\t\tonSelectionChange([]);\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\n\t\t};\n\t}, [selectedBlockIds, onSelectionChange]);\n\n\t// グリッドリサイズハンドラ\n\tconst handleGridResize = useCallback(\n\t\t(direction: \"column\" | \"row\", index: number, deltaPx: number) => {\n\t\t\t// グリッド線 index=1 → dimension[0] と dimension[1] の間\n\t\t\tconst dimensionIndex = index - 1;\n\n\t\t\tif (direction === \"column\") {\n\t\t\t\tconst newCols = calcGridResize(\n\t\t\t\t\texpandedCols,\n\t\t\t\t\tdimensionIndex,\n\t\t\t\t\tdeltaPx,\n\t\t\t\t\tpaperPx.content.width,\n\t\t\t\t);\n\t\t\t\tonPageChange({\n\t\t\t\t\t...page,\n\t\t\t\t\tgrid: { ...page.grid, ...colsToSparse(newCols) },\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst newRows = calcGridResize(\n\t\t\t\t\texpandedRows,\n\t\t\t\t\tdimensionIndex,\n\t\t\t\t\tdeltaPx,\n\t\t\t\t\tpaperPx.content.height,\n\t\t\t\t);\n\t\t\t\tonPageChange({\n\t\t\t\t\t...page,\n\t\t\t\t\tgrid: { ...page.grid, ...rowsToSparse(newRows) },\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[page, paperPx, expandedCols, expandedRows, onPageChange],\n\t);\n\n\t// グリッド寸法の単位値を変更した際のハンドラ\n\tconst handleDimensionChange = useCallback(\n\t\t(\n\t\t\tdirection: \"column\" | \"row\",\n\t\t\tindex: number,\n\t\t\tdimension: Dimension<GridUnit>,\n\t\t) => {\n\t\t\tif (direction === \"column\") {\n\t\t\t\tconst newCols = [...expandedCols];\n\t\t\t\tnewCols[index] = dimension;\n\t\t\t\tonPageChange({\n\t\t\t\t\t...page,\n\t\t\t\t\tgrid: { ...page.grid, ...colsToSparse(newCols) },\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst newRows = [...expandedRows];\n\t\t\t\tnewRows[index] = dimension;\n\t\t\t\tonPageChange({\n\t\t\t\t\t...page,\n\t\t\t\t\tgrid: { ...page.grid, ...rowsToSparse(newRows) },\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onPageChange, page, expandedCols, expandedRows],\n\t);\n\n\t// hiddenBinding を評価して非表示ブロックを除外した値(FORM モードは bindingContext なし)\n\tconst visibleValues = useMemo(() => {\n\t\tconst result: Record<string, Value> = {};\n\t\tfor (const block of page.blocks) {\n\t\t\tconst isHidden = evalHiddenBinding(block.hiddenBinding, undefined);\n\t\t\tif (!isHidden && block.initValue !== undefined) {\n\t\t\t\tresult[block.id] = block.initValue;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}, [page.blocks]);\n\n\treturn (\n\t\t<PluginRegistryContext.Provider value={pluginRegistry}>\n\t\t\t<section\n\t\t\t\tref={paperRef}\n\t\t\t\tdata-testid=\"note-container\"\n\t\t\t\tclassName={className}\n\t\t\t\taria-label=\"用紙\"\n\t\t\t\tonDragEnter={handleDragEnter}\n\t\t\t\tonDragOver={handleDragOver}\n\t\t\t\tonDragLeave={handleDragLeave}\n\t\t\t\tonDrop={handleDrop}\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\twidth: `${paperPx.canvas.width}px`,\n\t\t\t\t\theight: `${paperPx.canvas.height}px`,\n\t\t\t\t\tmargin: \"0 auto\",\n\t\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\n\t\t\t\t\tbackgroundColor: \"#fff\",\n\t\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\n\t\t\t\t\ttransformOrigin: \"top center\",\n\t\t\t\t\t...STACKING_ISOLATION_STYLE,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<GridLayer\n\t\t\t\t\tpaperPx={paperPx}\n\t\t\t\t\tgridPosPx={gridPosPx}\n\t\t\t\t\tgridDimensions={{\n\t\t\t\t\t\tcols: expandedCols,\n\t\t\t\t\t\trows: expandedRows,\n\t\t\t\t\t}}\n\t\t\t\t\tshowGridLines={true}\n\t\t\t\t\tshowMargins={true}\n\t\t\t\t\tshowBorder={true}\n\t\t\t\t\tshowResizeHandles={true}\n\t\t\t\t\tshowDimensionLabels={true}\n\t\t\t\t\tonGridResize={handleGridResize}\n\t\t\t\t\tonDimensionChange={handleDimensionChange}\n\t\t\t\t\tgridLineStyle={{\n\t\t\t\t\t\tcolor: \"#e5e7eb\",\n\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\n\t\t\t\t\t\ttype: LineType.SOLID,\n\t\t\t\t\t}}\n\t\t\t\t\tborderStyle={{\n\t\t\t\t\t\ttop: {\n\t\t\t\t\t\t\tcolor: \"#000000\",\n\t\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\n\t\t\t\t\t\t\ttype: LineType.SOLID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tright: {\n\t\t\t\t\t\t\tcolor: \"#000000\",\n\t\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\n\t\t\t\t\t\t\ttype: LineType.SOLID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbottom: {\n\t\t\t\t\t\t\tcolor: \"#000000\",\n\t\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\n\t\t\t\t\t\t\ttype: LineType.SOLID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tleft: {\n\t\t\t\t\t\t\tcolor: \"#000000\",\n\t\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\n\t\t\t\t\t\t\ttype: LineType.SOLID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<BlockLayer\n\t\t\t\t\tblocks={page.blocks}\n\t\t\t\t\tpluginRegistry={pluginRegistry}\n\t\t\t\t\tmode={NoteMode.FORM}\n\t\t\t\t\tvalues={visibleValues}\n\t\t\t\t\tselectedBlockIds={selectedBlockIds}\n\t\t\t\t\tblockDefaults={page.blockDefaults}\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\n\t\t\t\t\tonValueChange={handleInitValueChange}\n\t\t\t\t\tonMeasureHeight={handleMeasureHeight}\n\t\t\t\t\tonMeasureWidth={handleMeasureWidth}\n\t\t\t\t\tshowGuides={true}\n\t\t\t\t\tshowBorder={true}\n\t\t\t\t/>\n\t\t\t\t<InteractionLayer\n\t\t\t\t\tpage={page}\n\t\t\t\t\tgridLength={{\n\t\t\t\t\t\tcols: page.grid.colCount,\n\t\t\t\t\t\trows: page.grid.rowCount,\n\t\t\t\t\t}}\n\t\t\t\t\tpluginRegistry={pluginRegistry}\n\t\t\t\t\tblockDefaults={page.blockDefaults}\n\t\t\t\t\tgetBlockRectPx={getAdjustedBlockRectPx}\n\t\t\t\t\tgetColIndex={getColIndex}\n\t\t\t\t\tgetRowIndex={getRowIndex}\n\t\t\t\t\tselectedBlockIds={selectedBlockIds}\n\t\t\t\t\tonSelectionChange={onSelectionChange}\n\t\t\t\t\tstate={interactionState}\n\t\t\t\t\tonStateChange={onStateChange}\n\t\t\t\t\tonPageChange={onPageChange}\n\t\t\t\t\tactionContext={actionContext}\n\t\t\t\t\tscale={scale}\n\t\t\t\t/>\n\t\t\t</section>\n\t\t</PluginRegistryContext.Provider>\n\t);\n});\n","import { memo } from \"react\";\n\nimport { BlockLayer, GridLayer } from \"../../canvas/layers\";\nimport { PluginRegistryContext } from \"../../plugin/context\";\nimport { NoteMode } from \"../../types/mode\";\nimport { STACKING_ISOLATION_STYLE } from \"../../utils/zIndex\";\nimport { useNoteLayout } from \"../hooks/useNoteLayout\";\n\nimport type { NoteContext } from \"../../contexts/useNoteContext\";\nimport type { PluginRegistry } from \"../../plugin/registry\";\nimport type { Book } from \"../../types/schema\";\nimport type { Value } from \"../../types/value\";\n\n/**\n * {@link NoteViewProps} の共通フィールド\n *\n * @internal\n */\ninterface NoteViewPropsBase {\n\t/** `true` のときバリデーションエラーを表示する(デフォルト: false)。 */\n\tshowValidation?: boolean;\n\n\t/** 表示倍率(デフォルト: 1)。 */\n\tscale?: number;\n\n\t/** ルート要素に追加する className。 */\n\tclassName?: string;\n}\n\n/**\n * `context` ありの場合の props。`book` / `pluginRegistry` は `context` から取得する。\n *\n * @internal\n */\ninterface NoteViewPropsWithContext extends NoteViewPropsBase {\n\t/** `useNoteContext` が返すコンテキスト。バインディング・アクション・ページ選択が有効になる。 */\n\tcontext: NoteContext;\n\n\t/** `context` がある場合は渡せない(型は `never`)。値は `context.values` から取得される。 */\n\tvalues?: never;\n}\n\n/**\n * `book` ありの場合の props。`context` は渡せない。\n *\n * @internal\n */\ninterface NoteViewPropsWithBook extends NoteViewPropsBase {\n\tcontext?: never;\n\n\t/** Book(用紙設定・ページを含む)。 */\n\tbook: Book;\n\n\t/** ブロックプラグインのレジストリ(`createPluginRegistry` で生成)。 */\n\tpluginRegistry: PluginRegistry;\n\n\t/** ブロックの入力値。省略時は `initValue` のみが表示される。 */\n\tvalues?: Record<string, Value>;\n\n\t/** 表示するページインデックス(デフォルト: 0)。複数ページ Book の特定ページを静的表示する場合に指定する。 */\n\tpageIdx?: number;\n}\n\n/**\n * {@link NoteView} の props。`context` か `book` のどちらか一方が必須。\n */\nexport type NoteViewProps = NoteViewPropsWithContext | NoteViewPropsWithBook;\n\n/**\n * 閲覧モード(VIEW モード)専用コンポーネント。\n *\n * すべて読み取り専用。ブロックの配置変更・値の編集は不可。\n *\n * `context` は省略可能。省略した場合、`book` と `values` を渡すだけで静的表示できる。\n * `context` を渡した場合はバインディング・アクション・ページ選択が有効になる。\n *\n * @remarks 通常は {@link Note} を `mode={NoteMode.VIEW}` で使用する。\n */\nexport const NoteView = memo(function NoteView(props: NoteViewProps) {\n\tconst book = props.context !== undefined ? props.context.book : props.book;\n\tconst pluginRegistry =\n\t\tprops.context !== undefined\n\t\t\t? props.context.pluginRegistry\n\t\t\t: props.pluginRegistry;\n\tconst values = props.context?.values ?? props.values ?? {};\n\tconst showValidation = props.showValidation ?? false;\n\tconst scale = props.scale ?? 1.0;\n\tconst { className } = props;\n\tconst bindingContext = props.context?.bindingContext;\n\tconst actionContext = props.context?.actionContext;\n\n\tconst {\n\t\tpage,\n\t\tisFit,\n\t\tisWidthFit,\n\t\tgridPosPx,\n\t\tgetBlockRectPx,\n\t\thandleMeasureHeight,\n\t\thandleMeasureWidth,\n\t\tcanvasHeightPx,\n\t\tcanvasWidthPx,\n\t\teffectivePaperPx,\n\t\tvalidationErrors,\n\t} = useNoteLayout({\n\t\tbook,\n\t\tpageIdx:\n\t\t\tprops.context !== undefined\n\t\t\t\t? props.context.editorState.pageIdx\n\t\t\t\t: (props.pageIdx ?? 0),\n\t\tshowValidation,\n\t\tvalues,\n\t\tbindingContext,\n\t});\n\n\treturn (\n\t\t<PluginRegistryContext.Provider value={pluginRegistry}>\n\t\t\t<div\n\t\t\t\tdata-testid=\"note-container\"\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\twidth: `${canvasWidthPx}px`,\n\t\t\t\t\theight: `${canvasHeightPx}px`,\n\t\t\t\t\tmargin: \"0 auto\",\n\t\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\n\t\t\t\t\tbackgroundColor: \"#fff\",\n\t\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\n\t\t\t\t\ttransformOrigin: \"top center\",\n\t\t\t\t\t...STACKING_ISOLATION_STYLE,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<GridLayer\n\t\t\t\t\tpaperPx={effectivePaperPx}\n\t\t\t\t\tgridPosPx={gridPosPx}\n\t\t\t\t\tshowGridLines={false}\n\t\t\t\t\tshowMargins={false}\n\t\t\t\t\tshowBorder={false}\n\t\t\t\t/>\n\t\t\t\t<BlockLayer\n\t\t\t\t\tblocks={page.blocks}\n\t\t\t\t\tpluginRegistry={pluginRegistry}\n\t\t\t\t\tmode={NoteMode.VIEW}\n\t\t\t\t\tvalues={values}\n\t\t\t\t\tblockDefaults={page.blockDefaults}\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\n\t\t\t\t\tonMeasureHeight={isFit ? handleMeasureHeight : undefined}\n\t\t\t\t\tonMeasureWidth={isWidthFit ? handleMeasureWidth : undefined}\n\t\t\t\t\tshowGuides={false}\n\t\t\t\t\tshowBorder={true}\n\t\t\t\t\tshowValidation={showValidation}\n\t\t\t\t\tvalidationErrors={validationErrors}\n\t\t\t\t\tbindingContext={bindingContext}\n\t\t\t\t\tactionContext={actionContext}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</PluginRegistryContext.Provider>\n\t);\n});\n","import { NoteMode } from \"../../types/mode\";\nimport { STACKING_ISOLATION_STYLE } from \"../../utils/zIndex\";\nimport { NoteEdit } from \"../NoteEdit\";\nimport { NoteForm } from \"../NoteForm\";\nimport { NoteView } from \"../NoteView\";\n\nimport type { NoteProps } from \"../types\";\n\n/**\n * `mode` prop で FORM / EDIT / VIEW を切り替えられる統一 Note コンポーネント。\n *\n * 内部で `NoteForm` / `NoteEdit` / `NoteView` への薄いラッパーとして機能する。\n * 印刷は `printNote(context)` で起動できる。\n */\nexport function Note({\n\tcontext,\n\tmode,\n\tclassName,\n\tstyle,\n\tshowValidation,\n\tscale,\n}: NoteProps) {\n\tif (mode === NoteMode.FORM) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{ ...style, ...STACKING_ISOLATION_STYLE }}\n\t\t\t\tclassName={className}\n\t\t\t>\n\t\t\t\t<NoteForm scale={scale} context={context} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (mode === NoteMode.VIEW) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{ ...style, ...STACKING_ISOLATION_STYLE }}\n\t\t\t\tclassName={className}\n\t\t\t>\n\t\t\t\t<NoteView\n\t\t\t\t\tshowValidation={showValidation}\n\t\t\t\t\tscale={scale}\n\t\t\t\t\tcontext={context}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// NoteMode.EDIT (デフォルト)\n\treturn (\n\t\t<div\n\t\t\tstyle={{ ...style, ...STACKING_ISOLATION_STYLE }}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<NoteEdit\n\t\t\t\tshowValidation={showValidation}\n\t\t\t\tscale={scale}\n\t\t\t\tcontext={context}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import type { ActionContext, BindingContext } from \"../../../types/context\";\nimport type { ButtonActionProps } from \"./props\";\n\n/**\n * @internal\n * ButtonActionProps から取得したアクション指定の型エイリアス\n */\ntype ButtonAction = ButtonActionProps[\"action\"];\n\n/**\n * @internal\n * executeButtonAction / isButtonActionEnabled に渡す実行コンテキスト\n */\ninterface ExecuteContext {\n\tactionContext?: ActionContext;\n\tbindingContext?: BindingContext;\n\tonChange: (value: null) => void;\n}\n\n/**\n * ボタンの `action` 設定に応じてクリック時の処理を実行する。\n *\n * - 文字列 action: `actionContext.execute` を呼び出す\n * - オブジェクト action: `bindingContext.set` で指定パスに値をセットする\n * - どちらでもない場合: `onChange(null)` を呼び出す\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装者向け\n */\nexport function executeButtonAction(\n\taction: ButtonAction,\n\t{ actionContext, bindingContext, onChange }: ExecuteContext,\n): void {\n\tif (typeof action === \"string\") {\n\t\tif (action && actionContext) {\n\t\t\tactionContext.execute(action);\n\t\t} else {\n\t\t\tonChange(null);\n\t\t}\n\t\treturn;\n\t}\n\tif (action != null && bindingContext != null) {\n\t\tbindingContext.set(action.path, action.value);\n\t\treturn;\n\t}\n\tonChange(null);\n}\n\n/**\n * ボタンの `action` が現在有効か(クリック可能状態か)を返す。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装者向け\n */\nexport function isButtonActionEnabled(\n\taction: ButtonAction,\n\tactionContext: ActionContext | undefined,\n): boolean {\n\tif (typeof action !== \"string\") return true;\n\tif (!action || !actionContext) return true;\n\treturn actionContext.isEnabled(action);\n}\n\n/**\n * ボタンの `action` がアクティブ状態か(トグル選択中か)を返す。\n *\n * オブジェクト形式の action でバインディング値と一致する場合に `true` を返す。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装者向け\n */\nexport function getButtonActionActive(\n\taction: ButtonAction,\n\tbindingContext: BindingContext | undefined,\n): boolean {\n\tif (action == null || typeof action !== \"object\" || bindingContext == null) {\n\t\treturn false;\n\t}\n\treturn bindingContext.get(action.path) === action.value;\n}\n","import type { PropDef } from \"../../../plugin\";\nimport type { Value } from \"../../../types/value\";\n\n/**\n * ボタンの表示内容(ラベル・アイコン)props。\n */\nexport interface ButtonContentProps {\n\t/** ボタンに表示するテキスト。 */\n\tlabel?: string;\n\n\t/** アイコン文字列(Unicode 絵文字等を `<span>` テキストとして表示)。 */\n\ticon?: string;\n\n\t/** SVG パスデータ。`icon` より優先される。 */\n\ticonPath?: string;\n\n\t/** ツールチップに表示するテキスト。 */\n\ttitle?: string;\n}\n\n/**\n * `buttonContent` prop 定義。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン専用。\n */\nexport const buttonContentProp = {\n\tkind: \"buttonContent\",\n\tdefaultProps: {\n\t\tlabel: \"ボタン\",\n\t\ticon: \"\",\n\t\ticonPath: \"\",\n\t\ttitle: \"\",\n\t},\n} satisfies PropDef;\n\n/**\n * ボタンクリック時のアクション設定 props。\n */\nexport interface ButtonActionProps {\n\t/** クリック時のアクション。文字列の場合はパス評価、オブジェクトの場合は指定パスへ値をセットする。 */\n\taction?: string | { path: string; value: Value };\n}\n\n/**\n * `buttonAction` prop 定義。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン専用。\n */\nexport const buttonActionProp = {\n\tkind: \"buttonAction\",\n\tdefaultProps: {\n\t\taction: \"\",\n\t},\n} satisfies PropDef;\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tuseCallback,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\n\nimport {\n\tHorizontalAlign,\n\tVerticalAlign,\n} from \"../../../plugin/properties/alignment\";\nimport { dimensionToString } from \"../../../utils\";\nimport {\n\texecuteButtonAction,\n\tgetButtonActionActive,\n\tisButtonActionEnabled,\n} from \"./execute\";\n\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { ButtonBlockProps, ButtonBlockValue } from \"./types\";\n\n/**\n * @internal\n * HorizontalAlign → CSS justifyContent のマッピングテーブル\n */\nconst H_ALIGN_CSS: Record<HorizontalAlign, CSSProperties[\"justifyContent\"]> = {\n\t[HorizontalAlign.left]: \"flex-start\",\n\t[HorizontalAlign.center]: \"center\",\n\t[HorizontalAlign.right]: \"flex-end\",\n};\n\n/**\n * @internal\n * VerticalAlign → CSS alignItems のマッピングテーブル\n */\nconst V_ALIGN_CSS: Record<VerticalAlign, CSSProperties[\"alignItems\"]> = {\n\t[VerticalAlign.top]: \"flex-start\",\n\t[VerticalAlign.center]: \"center\",\n\t[VerticalAlign.bottom]: \"flex-end\",\n};\n\n/**\n * ボタンブロックのレンダラーコンポーネント。\n *\n * `action` props に応じてクリック時にバインディング操作またはアクション実行を行う。\n *\n * @remarks\n * **Canvas** — ButtonPlugin と組み合わせて使用する実装コンポーネント。\n */\nexport const ButtonRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<ButtonBlockProps, ButtonBlockValue>\n>(\n\t(\n\t\t{ props, readOnly, onChange, ariaLabel, actionContext, bindingContext },\n\t\tref,\n\t) => {\n\t\tconst buttonRef = useRef<HTMLButtonElement>(null);\n\t\tconst [pressed, setPressed] = useState(false);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ({ focus: () => buttonRef.current?.focus() }),\n\t\t\t[],\n\t\t);\n\n\t\tconst isActionEnabled = isButtonActionEnabled(props.action, actionContext);\n\t\tconst isDisabled = readOnly || !isActionEnabled;\n\t\tconst isActive = getButtonActionActive(props.action, bindingContext);\n\n\t\tconst handleClick = useCallback(() => {\n\t\t\tif (isDisabled) return;\n\t\t\texecuteButtonAction(props.action, {\n\t\t\t\tactionContext,\n\t\t\t\tbindingContext,\n\t\t\t\tonChange,\n\t\t\t});\n\t\t}, [isDisabled, props.action, actionContext, bindingContext, onChange]);\n\n\t\tconst handlePointerDown = useCallback(() => {\n\t\t\tif (!isDisabled) setPressed(true);\n\t\t}, [isDisabled]);\n\n\t\tconst handlePointerUp = useCallback(() => setPressed(false), []);\n\n\t\tconst containerStyle = useMemo((): CSSProperties => {\n\t\t\tconst css: CSSProperties = {\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t\tcursor: isDisabled ? \"default\" : \"pointer\",\n\t\t\t\tuserSelect: \"none\",\n\t\t\t\toutline: \"none\",\n\t\t\t\tappearance: \"none\",\n\t\t\t\tborder: \"none\",\n\t\t\t\tbackground: \"none\",\n\t\t\t\topacity: isDisabled ? 0.4 : pressed ? 0.7 : isActive ? 0.85 : 1,\n\t\t\t\ttransform: pressed ? \"scale(0.97)\" : \"scale(1)\",\n\t\t\t\ttransition: pressed\n\t\t\t\t\t? \"none\"\n\t\t\t\t\t: \"opacity 150ms ease, transform 150ms ease\",\n\t\t\t};\n\n\t\t\tif (props.iconPath) {\n\t\t\t\tcss.display = \"flex\";\n\t\t\t\tcss.alignItems = V_ALIGN_CSS[props.vertical ?? VerticalAlign.center];\n\t\t\t\tcss.justifyContent =\n\t\t\t\t\tH_ALIGN_CSS[props.horizontal ?? HorizontalAlign.center];\n\t\t\t\tcss.containerType = \"size\";\n\t\t\t\tcss.color = \"inherit\";\n\t\t\t} else if (props.icon && !props.label) {\n\t\t\t\tcss.display = \"flex\";\n\t\t\t\tcss.alignItems = V_ALIGN_CSS[props.vertical ?? VerticalAlign.center];\n\t\t\t\tcss.justifyContent =\n\t\t\t\t\tH_ALIGN_CSS[props.horizontal ?? HorizontalAlign.center];\n\t\t\t\tcss.containerType = \"size\";\n\t\t\t\tcss.fontFamily = \"inherit\";\n\t\t\t\tcss.color = \"inherit\";\n\t\t\t} else {\n\t\t\t\tcss.display = \"flex\";\n\t\t\t\tcss.alignItems = V_ALIGN_CSS[props.vertical ?? VerticalAlign.center];\n\t\t\t\tcss.justifyContent =\n\t\t\t\t\tH_ALIGN_CSS[props.horizontal ?? HorizontalAlign.center];\n\t\t\t\tcss.gap = \"4px\";\n\t\t\t\tcss.fontFamily = \"inherit\";\n\t\t\t\tcss.fontSize = \"inherit\";\n\t\t\t\tcss.color = \"inherit\";\n\t\t\t}\n\n\t\t\tconst padAll = props.bulk ? props.all : undefined;\n\t\t\tconst padTop = padAll ?? props.top;\n\t\t\tconst padRight = padAll ?? props.right;\n\t\t\tconst padBottom = padAll ?? props.bottom;\n\t\t\tconst padLeft = padAll ?? props.left;\n\t\t\tif (padTop) css.paddingTop = dimensionToString(padTop);\n\t\t\tif (padRight) css.paddingRight = dimensionToString(padRight);\n\t\t\tif (padBottom) css.paddingBottom = dimensionToString(padBottom);\n\t\t\tif (padLeft) css.paddingLeft = dimensionToString(padLeft);\n\n\t\t\treturn css;\n\t\t}, [props, isDisabled, pressed, isActive]);\n\n\t\treturn (\n\t\t\t<button\n\t\t\t\tref={buttonRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={isDisabled}\n\t\t\t\taria-pressed={isActive ? true : undefined}\n\t\t\t\taria-label={ariaLabel ?? props.label ?? \"ボタン\"}\n\t\t\t\ttitle={props.title}\n\t\t\t\tstyle={containerStyle}\n\t\t\t\tonClick={handleClick}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\tonPointerLeave={handlePointerUp}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === \"Enter\" || e.key === \" \") {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\thandleClick();\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{props.iconPath ? (\n\t\t\t\t\t<svg\n\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tdisplay: \"block\",\n\t\t\t\t\t\t\tmargin: \"auto\",\n\t\t\t\t\t\t\twidth: \"min(55cqi, 55cqb)\",\n\t\t\t\t\t\t\theight: \"min(55cqi, 55cqb)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<path d={props.iconPath} fill=\"currentColor\" />\n\t\t\t\t\t</svg>\n\t\t\t\t) : props.icon ? (\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t!props.label\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tdisplay: \"block\",\n\t\t\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\t\t\ttextAlign: \"center\",\n\t\t\t\t\t\t\t\t\t\tfontSize: \"min(55cqi, 55cqb)\",\n\t\t\t\t\t\t\t\t\t\tlineHeight: \"1\",\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{props.icon}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t\t{!props.iconPath && (props.label || !props.icon) && (\n\t\t\t\t\t<span>{props.label ?? \"ボタン\"}</span>\n\t\t\t\t)}\n\t\t\t</button>\n\t\t);\n\t},\n);\n\nButtonRenderer.displayName = \"ButtonRenderer\";\n","import { alignmentProp } from \"../../../plugin/properties/alignment\";\nimport { paddingProp } from \"../../../plugin/properties/padding\";\nimport { buttonActionProp, buttonContentProp } from \"./props\";\nimport { ButtonRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin/types\";\nimport type { ButtonBlockProps, ButtonBlockValue } from \"./types\";\n\n/**\n * ボタンブロックのプラグイン定義。\n *\n * `kind: \"button\"` で登録され、クリックで `action` prop に定義したバインディング操作を実行する。\n *\n * @remarks\n * **Canvas** — カスタムプラグインの実装例。\n *\n * 標準フォーム構築では `createPluginRegistry` に渡すだけで使用できる。\n */\nexport const ButtonPlugin: BlockPlugin<ButtonBlockProps, ButtonBlockValue> = {\n\tkind: \"button\",\n\tmeta: {\n\t\tdisplayName: \"ボタン\",\n\t\tdescription: \"クリックでアクションを実行するボタンブロック\",\n\t\tdefaultSize: { w: 2, h: 1 },\n\t},\n\tRenderer: ButtonRenderer,\n\tproperties: [alignmentProp, paddingProp, buttonContentProp, buttonActionProp],\n\tvalidateProps: (props: unknown): ButtonBlockProps => {\n\t\tif (typeof props !== \"object\" || props === null)\n\t\t\treturn {} as ButtonBlockProps;\n\t\treturn props as ButtonBlockProps;\n\t},\n\tvalidateValue: (): ButtonBlockValue => null,\n};\n","import type { Block } from \"../../../types/block\";\n\n/**\n * TextBlock を数値入力専用設定にしたブロック定義ヘルパー。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築向レイアウトヘルパー。\n *\n * binding には数値を保持するパス(例: \"paper.size.width.value\")を渡す。\n *\n * 返り値のレイアウトはデフォルト `{ x:0, y:0, w:1, h:1 }` のため、\n * 複合 widget 内で spread して上書きすること。\n *\n * @example\n * ```ts\n * {\n * ...numberInputBlock(\"width-value\", \"paper.size.width.value\"),\n * layout: { x: 0, y: 0, w: 2, h: 1 },\n * }\n * ```\n */\nexport function numberInputBlock(id: string, binding: string): Block {\n\treturn {\n\t\tid,\n\t\tkind: \"text\",\n\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\tprops: {\n\t\t\tbinding,\n\t\t\tplaceholder: \"0\",\n\t\t\t// 整数・小数のみ許可(マイナス不可)\n\t\t\tpattern: \"^[0-9]*\\\\.?[0-9]*$\",\n\t\t\tmultiline: false,\n\t\t\thorizontal: \"right\",\n\t\t\tvertical: \"center\",\n\t\t\ttop: { value: 2, unit: \"px\" },\n\t\t\tright: { value: 5, unit: \"px\" },\n\t\t},\n\t};\n}\n","import type { Block } from \"../../../types/block\";\n\n// mm / cm / inch の選択肢\nconst UNIT_OPTIONS = [\n\t{ label: \"mm\", value: \"mm\" },\n\t{ label: \"cm\", value: \"cm\" },\n\t{ label: \"inch\", value: \"inch\" },\n];\n\n/**\n * SelectBlock を PaperUnit (mm / cm / inch) 選択専用設定にしたブロック定義ヘルパー。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築向レイアウトヘルパー。\n *\n * binding には単位を保持するパス(例: \"paper.size.width.unit\")を渡す。\n *\n * 返り値のレイアウトはデフォルト `{ x:0, y:0, w:1, h:1 }` のため、\n * 複合 widget 内で spread して上書きすること。\n *\n * @example\n * ```ts\n * {\n * ...unitSelectBlock(\"width-unit\", \"paper.size.width.unit\"),\n * layout: { x: 2, y: 0, w: 1, h: 1 },\n * }\n * ```\n */\nexport function unitSelectBlock(id: string, binding: string): Block {\n\treturn {\n\t\tid,\n\t\tkind: \"select\",\n\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\tprops: {\n\t\t\tbinding,\n\t\t\tselectConfig: {\n\t\t\t\toptions: UNIT_OPTIONS,\n\t\t\t\tallowEmpty: false,\n\t\t\t\tdefaultValue: \"mm\",\n\t\t\t},\n\t\t\thorizontal: \"left\",\n\t\t\tleft: { value: 2, unit: \"px\" },\n\t\t},\n\t};\n}\n","import type { PropDef } from \"../../../plugin/types\";\n\n/**\n * ステッパーの矢印外観カスタマイズ設定。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用すること。\n */\nexport interface StepperStyleConfig {\n\t/** 矢印の色(CSS 値 / `currentColor` も可)。 */\n\tarrowColor?: string;\n\n\t/** 矢印の幅(px)。 */\n\tarrowWidth?: number;\n\n\t/** 矢印の高さ(px)。 */\n\tarrowHeight?: number;\n\n\t/** 矢印と値表示領域の間距(px)。 */\n\tarrowGap?: number;\n}\n\n/**\n * ステッパーの数値範囲・ステップ幅の振る舞い props。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用する。\n */\nexport interface StepperBehaviorProps {\n\t/** 1ステップ当たりの増減幅。デフォルト: 1。 */\n\tstep?: number;\n\n\t/** 入力可能な最小値。 */\n\tmin?: number;\n\n\t/** 入力可能な最大値。 */\n\tmax?: number;\n}\n\n/**\n * `stepperBehavior` prop 定義。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用する。\n */\nexport const stepperBehaviorProp = {\n\tkind: \"stepperBehavior\",\n\tdefaultProps: {\n\t\tstep: 1,\n\t},\n} satisfies PropDef;\n\n/**\n * ステッパーブロックの外観カスタマイズ props。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用する。\n */\nexport interface StepperStyleProps {\n\t/** 矢印外観カスタマイズ設定。 */\n\tstyleConfig?: StepperStyleConfig;\n}\n\n/**\n * `stepperStyle` prop 定義。\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用する。\n */\nexport const stepperStyleProp = {\n\tkind: \"stepperStyle\",\n\tdefaultProps: {\n\t\tstyleConfig: {\n\t\t\tarrowWidth: 50,\n\t\t\tarrowHeight: 25,\n\t\t\tarrowColor: \"currentColor\",\n\t\t\tarrowGap: 20,\n\t\t},\n\t},\n} satisfies PropDef;\n","/**\n * ステッパーの増減ロジック(純粋関数)\n *\n * @remarks\n * **Canvas** — カスタムプラグイン実装時に利用する純粹関数。\n *\n * 現在値に delta を加算し、min/max でクランプした結果を返す。\n */\nexport function clampStep(\n\tcurrent: number,\n\tdelta: number,\n\tmin?: number,\n\tmax?: number,\n): number {\n\tlet next = current + delta;\n\tif (max !== undefined) next = Math.min(max, next);\n\tif (min !== undefined) next = Math.max(min, next);\n\treturn next;\n}\n","import {\n\ttype CSSProperties,\n\tforwardRef,\n\tuseCallback,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from \"react\";\n\nimport { clampStep } from \"./step\";\n\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type { StepperBlockProps, StepperBlockValue } from \"./types\";\n\n// UP_PATH: 上向き三角矢印の SVG パスデータ\nconst UP_PATH = \"M 10,0 L 20,10 L 0,10 Z\";\n// DOWN_PATH: 下向き三角矢印の SVG パスデータ\nconst DOWN_PATH = \"M 0,0 L 20,0 L 10,10 Z\";\n\n// buttonOverlayStyle: ステッパーの上・下ボタン共通のオーバーレイスタイルを生成する\nconst buttonOverlayStyle = (disabled: boolean): CSSProperties => ({\n\tposition: \"absolute\",\n\tleft: 0,\n\twidth: \"100%\",\n\theight: \"50%\",\n\tpadding: 0,\n\tborder: \"none\",\n\tbackground: \"none\",\n\tappearance: \"none\",\n\tcursor: disabled ? \"default\" : \"pointer\",\n\tboxSizing: \"border-box\",\n});\n\n/**\n * ステッパーブロックのレンダラーコンポーネント。\n *\n * 上下のボタンで数値を `step` 幅分増減し、`min`/`max` でクランプする。\n *\n * @remarks\n * **Canvas** — `StepperPlugin` と組み合わせて使用する実装コンポーネント。\n */\nexport const StepperRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<StepperBlockProps, StepperBlockValue>\n>(({ props, value, onChange, readOnly }, ref) => {\n\tconst divRef = useRef<HTMLDivElement>(null);\n\tconst [pressedUp, setPressedUp] = useState(false);\n\tconst [pressedDown, setPressedDown] = useState(false);\n\n\tconst isDisabled = readOnly;\n\tconst step = props.step ?? 1;\n\tconst arrowColor = props.styleConfig?.arrowColor ?? \"currentColor\";\n\tconst arrowWidth = props.styleConfig?.arrowWidth ?? 50;\n\tconst arrowHeight = props.styleConfig?.arrowHeight ?? 25;\n\tconst arrowGap = props.styleConfig?.arrowGap ?? 20;\n\tconst arrowLeft = (100 - arrowWidth) / 2;\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tfocus: () => divRef.current?.querySelector(\"button\")?.focus(),\n\t\t}),\n\t\t[],\n\t);\n\n\tconst apply = useCallback(\n\t\t(delta: number) => {\n\t\t\tif (isDisabled) return;\n\t\t\tconst cur = Number(value ?? 0);\n\t\t\tconst next = clampStep(cur, delta, props.min, props.max);\n\t\t\tonChange(next);\n\t\t},\n\t\t[isDisabled, value, onChange, props.min, props.max],\n\t);\n\n\tconst handleUp = useCallback(() => apply(step), [apply, step]);\n\tconst handleDown = useCallback(() => apply(-step), [apply, step]);\n\n\tconst svgFeedback = (pressed: boolean): CSSProperties => ({\n\t\topacity: isDisabled ? 0.4 : pressed ? 0.6 : 1,\n\t\ttransform: pressed ? \"scale(0.9)\" : \"scale(1)\",\n\t\ttransition: pressed ? \"none\" : \"opacity 150ms ease, transform 150ms ease\",\n\t});\n\n\treturn (\n\t\t<div\n\t\t\tref={divRef}\n\t\t\tstyle={{\n\t\t\t\tposition: \"relative\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\toverflow: \"visible\",\n\t\t\t\tcolor: arrowColor,\n\t\t\t}}\n\t\t>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={isDisabled}\n\t\t\t\taria-label=\"増やす\"\n\t\t\t\tstyle={{ ...buttonOverlayStyle(isDisabled), top: 0 }}\n\t\t\t\tonClick={handleUp}\n\t\t\t\tonPointerDown={() => {\n\t\t\t\t\tif (!isDisabled) setPressedUp(true);\n\t\t\t\t}}\n\t\t\t\tonPointerUp={() => setPressedUp(false)}\n\t\t\t\tonPointerLeave={() => setPressedUp(false)}\n\t\t\t/>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={isDisabled}\n\t\t\t\taria-label=\"減らす\"\n\t\t\t\tstyle={{ ...buttonOverlayStyle(isDisabled), bottom: 0 }}\n\t\t\t\tonClick={handleDown}\n\t\t\t\tonPointerDown={() => {\n\t\t\t\t\tif (!isDisabled) setPressedDown(true);\n\t\t\t\t}}\n\t\t\t\tonPointerUp={() => setPressedDown(false)}\n\t\t\t\tonPointerLeave={() => setPressedDown(false)}\n\t\t\t/>\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 20 10\"\n\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tleft: `${arrowLeft}%`,\n\t\t\t\t\tbottom: `calc(50% + ${arrowGap / 2}%)`,\n\t\t\t\t\twidth: `${arrowWidth}%`,\n\t\t\t\t\theight: `${arrowHeight}%`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\ttransformOrigin: \"center bottom\",\n\t\t\t\t\t...svgFeedback(pressedUp),\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<path d={UP_PATH} fill=\"currentColor\" />\n\t\t\t</svg>\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 20 10\"\n\t\t\t\tpreserveAspectRatio=\"none\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tleft: `${arrowLeft}%`,\n\t\t\t\t\ttop: `calc(50% + ${arrowGap / 2}%)`,\n\t\t\t\t\twidth: `${arrowWidth}%`,\n\t\t\t\t\theight: `${arrowHeight}%`,\n\t\t\t\t\tpointerEvents: \"none\",\n\t\t\t\t\ttransformOrigin: \"center top\",\n\t\t\t\t\t...svgFeedback(pressedDown),\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<path d={DOWN_PATH} fill=\"currentColor\" />\n\t\t\t</svg>\n\t\t</div>\n\t);\n});\n\nStepperRenderer.displayName = \"StepperRenderer\";\n","import { alignmentProp } from \"../../../plugin/properties/alignment\";\nimport { stepperBehaviorProp, stepperStyleProp } from \"./props\";\nimport { StepperRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin/types\";\nimport type { StepperBlockProps, StepperBlockValue } from \"./types\";\n\n/**\n * ステッパーブロックのプラグイン定義。\n *\n * `kind: \"stepper\"` で登録され、数値を±ボタンで増減する UI ブロック。\n *\n * @remarks\n * **Canvas** — カスタムプラグインの実装例。\n *\n * ステッパー機能が必要なフォームに `createPluginRegistry` に渡す。\n *\n * 標準フォーム構築では `createPluginRegistry` に渡すだけで使用できる。\n */\nexport const StepperPlugin: BlockPlugin<StepperBlockProps, StepperBlockValue> =\n\t{\n\t\tkind: \"stepper\",\n\t\tmeta: {\n\t\t\tdisplayName: \"ステッパー\",\n\t\t\tdescription: \"数値を増減するステッパーブロック\",\n\t\t\tdefaultSize: { w: 1, h: 1 },\n\t\t},\n\t\tRenderer: StepperRenderer,\n\t\tproperties: [alignmentProp, stepperBehaviorProp, stepperStyleProp],\n\t\tvalidateProps: (props: unknown): StepperBlockProps => {\n\t\t\tif (typeof props !== \"object\" || props === null)\n\t\t\t\treturn {} as StepperBlockProps;\n\t\t\tconst p = props as Record<string, unknown>;\n\t\t\tif (\n\t\t\t\t\"styleConfig\" in p &&\n\t\t\t\t(typeof p.styleConfig !== \"object\" || p.styleConfig === null)\n\t\t\t) {\n\t\t\t\treturn { ...p, styleConfig: {} } as StepperBlockProps;\n\t\t\t}\n\t\t\treturn props as StepperBlockProps;\n\t\t},\n\t\tvalidateValue: (value: unknown): StepperBlockValue =>\n\t\t\ttypeof value === \"number\" ? value : null,\n\t};\n","import { PaperSizePreset } from \"../../../types/paper\";\nimport { StepperPlugin } from \"../../blocks/stepper\";\nimport { TextPlugin } from \"../../blocks/text\";\nimport { numberInputBlock } from \"../primitives/numberInputBlock\";\n\nimport type { WidgetDef } from \"../types\";\n\n// atom widget 共通のペーパー設定(高さ 8mm・余白なし・ autoFit)\nconst ATOM_PAPER = {\n\tsize: {\n\t\tpreset: PaperSizePreset.CUSTOM,\n\t\twidth: { value: 100, unit: \"mm\" as const },\n\t\theight: { value: 8, unit: \"mm\" as const },\n\t},\n\tmargin: {\n\t\ttop: { value: 0, unit: \"mm\" as const },\n\t\tright: { value: 0, unit: \"mm\" as const },\n\t\tbottom: { value: 0, unit: \"mm\" as const },\n\t\tleft: { value: 0, unit: \"mm\" as const },\n\t},\n\tautoHeight: true,\n\tautoWidth: true,\n};\n\n// atom widget 共通の 3 列グリッド設定\n// - 列 0 (1fr): ラベル\n// - 列 1 (1fr): numberInput\n// - 列 2 (8mm): stepper\nconst ATOM_GRID = {\n\tcolCount: 3,\n\trowCount: 1,\n\tcols: { 2: { value: 8, unit: \"mm\" as const } },\n} as const;\n\n/**\n * グリッド行数 atom widget。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * 3 列 × 1 行: [行数ラベル][数値入力][stepper]\n *\n * binding: `grid.rowCount`\n */\nexport const gridRowCountWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: ATOM_PAPER,\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: ATOM_GRID,\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-row-count-label\",\n\t\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tinitValue: \"行数\",\n\t\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...numberInputBlock(\"grid-row-count-value\", \"grid.rowCount\"),\n\t\t\t\t\t\t\tlayout: { x: 1, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-row-count-stepper\",\n\t\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\t\tlayout: { x: 2, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: { binding: \"grid.rowCount\", step: 1, min: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [TextPlugin, StepperPlugin],\n};\n\n/**\n * グリッド列数 atom widget。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * 3 列 × 1 行: [列数ラベル][数値入力][stepper]\n *\n * binding: `grid.colCount`\n */\nexport const gridColCountWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: ATOM_PAPER,\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: ATOM_GRID,\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-col-count-label\",\n\t\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tinitValue: \"列数\",\n\t\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...numberInputBlock(\"grid-col-count-value\", \"grid.colCount\"),\n\t\t\t\t\t\t\tlayout: { x: 1, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-col-count-stepper\",\n\t\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\t\tlayout: { x: 2, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: { binding: \"grid.colCount\", step: 1, min: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [TextPlugin, StepperPlugin],\n};\n\n/**\n * グリッド設定 compound widget。\n *\n * @remarks\n * カスタムシェル構築専用。\n *\n * gridRowCountWidget(行数)と gridColCountWidget(列数)を横並びにした\n *\n * 1 行 × 6 列構成。\n *\n * 列構成:\n * - 列 0 (1fr): 行数ラベル\n * - 列 1 (1fr): 行数 numberInput → `grid.rowCount`\n * - 列 2 (8mm): 行数 stepper → `grid.rowCount`\n * - 列 3 (1fr): 列数ラベル\n * - 列 4 (1fr): 列数 numberInput → `grid.colCount`\n * - 列 5 (8mm): 列数 stepper → `grid.colCount`\n */\nexport const gridSettingsWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: ATOM_PAPER,\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: {\n\t\t\t\t\t\tcolCount: 6,\n\t\t\t\t\t\trowCount: 1,\n\t\t\t\t\t\tcols: {\n\t\t\t\t\t\t\t2: { value: 8, unit: \"mm\" },\n\t\t\t\t\t\t\t5: { value: 8, unit: \"mm\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-row-count-label\",\n\t\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tinitValue: \"行数\",\n\t\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...numberInputBlock(\"grid-row-count-value\", \"grid.rowCount\"),\n\t\t\t\t\t\t\tlayout: { x: 1, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-row-count-stepper\",\n\t\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\t\tlayout: { x: 2, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: { binding: \"grid.rowCount\", step: 1, min: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-col-count-label\",\n\t\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\t\tlayout: { x: 3, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tinitValue: \"列数\",\n\t\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...numberInputBlock(\"grid-col-count-value\", \"grid.colCount\"),\n\t\t\t\t\t\t\tlayout: { x: 4, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"grid-col-count-stepper\",\n\t\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\t\tlayout: { x: 5, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: { binding: \"grid.colCount\", step: 1, min: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [TextPlugin, StepperPlugin],\n};\n","import {\n\tforwardRef,\n\tuseContext,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n} from \"react\";\n\nimport { Note } from \"../../../note/Note\";\nimport { PluginRegistryContext } from \"../../../plugin/context\";\nimport { NoteMode } from \"../../../types/mode\";\nimport { DEFAULT_DPI, toPx } from \"../../../utils/convert\";\n\nimport type { NoteContext } from \"../../../contexts/useNoteContext\";\nimport type { BlockRef, RendererProps } from \"../../../plugin/types\";\nimport type {\n\tActionContext,\n\tBindingContext,\n\tEditorState,\n} from \"../../../types/context\";\nimport type { NoteBlockProps, NoteBlockValue } from \"./types\";\n\n/** @internal バインディング機能なしのデフォルト BindingContext(`bindingContext` 未指定時のフォールバック用) */\nconst NOOP_BINDING_CONTEXT: BindingContext = {\n\tget: () => null,\n\tset: () => {},\n};\n\n/** @internal アクション機能なしのデフォルト ActionContext(`actionContext` 未指定時のフォールバック用) */\nconst NOOP_ACTION_CONTEXT: ActionContext = {\n\texecute: () => {},\n\tisEnabled: () => false,\n};\n\n/** @internal 選択・ページ管理なしのデフォルト EditorState(スタンドアロン表示時のフォールバック用) */\nconst NOOP_EDITOR_STATE: EditorState = {\n\tselectedBlockIds: [],\n\tpageIdx: 0,\n};\n\n/**\n * ノートブロックのレンダラーコンポーネント。\n *\n * Book を内包し、ブロックのサイズに合わせてスケールしてグリッドをレンダリングする。\n *\n * @remarks\n * **Canvas** — `NoteBlockPlugin` と組み合わせて使用する実装コンポーネント。\n */\nexport const NoteBlockRenderer = forwardRef<\n\tBlockRef,\n\tRendererProps<NoteBlockProps, NoteBlockValue>\n>(\n\t(\n\t\t{\n\t\t\tprops,\n\t\t\tdimensions,\n\t\t\tbindingContext,\n\t\t\tactionContext,\n\t\t\tonMeasureHeight,\n\t\t\tonMeasureWidth,\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst pluginRegistry = useContext(PluginRegistryContext);\n\t\tuseImperativeHandle(ref, () => ({ focus: () => {} }), []);\n\n\t\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\n\t\tconst { naturalWidth, naturalHeight, scale } = useMemo(() => {\n\t\t\tconst nw = toPx.fromDim(props.book.paper.size.width, DEFAULT_DPI);\n\t\t\tconst nh = toPx.fromDim(props.book.paper.size.height, DEFAULT_DPI);\n\t\t\tconst s =\n\t\t\t\tdimensions && nw > 0 && nh > 0\n\t\t\t\t\t? Math.min(\n\t\t\t\t\t\t\tdimensions.widthPx / nw,\n\t\t\t\t\t\t\tdimensions.heightPx / nh < 1 && nh - dimensions.heightPx < 1\n\t\t\t\t\t\t\t\t? 1\n\t\t\t\t\t\t\t\t: dimensions.heightPx / nh,\n\t\t\t\t\t\t)\n\t\t\t\t\t: 1;\n\t\t\treturn { naturalWidth: nw, naturalHeight: nh, scale: s };\n\t\t}, [props.book.paper, dimensions]);\n\n\t\tuseEffect(() => {\n\t\t\tonMeasureHeight?.(naturalHeight * scale);\n\t\t}, [onMeasureHeight, naturalHeight, scale]);\n\n\t\tuseEffect(() => {\n\t\t\tonMeasureWidth?.(naturalWidth * scale);\n\t\t}, [onMeasureWidth, naturalWidth, scale]);\n\n\t\tconst noteContext = useMemo<NoteContext | null>(() => {\n\t\t\tif (!pluginRegistry) return null;\n\t\t\treturn {\n\t\t\t\tbook: props.book,\n\t\t\t\tonBookChange: () => {},\n\t\t\t\tpluginRegistry,\n\t\t\t\tcontainerRef,\n\t\t\t\tbindingContext: bindingContext ?? NOOP_BINDING_CONTEXT,\n\t\t\t\tactionContext: actionContext ?? NOOP_ACTION_CONTEXT,\n\t\t\t\teditorState: NOOP_EDITOR_STATE,\n\t\t\t\tvalues: {},\n\t\t\t};\n\t\t}, [props.book, pluginRegistry, bindingContext, actionContext]);\n\n\t\tif (!noteContext) return null;\n\n\t\treturn (\n\t\t\t<div style={{ width: \"100%\", height: \"100%\", overflow: \"hidden\" }}>\n\t\t\t\t<Note\n\t\t\t\t\tmode={NoteMode.EDIT}\n\t\t\t\t\tcontext={noteContext}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: naturalWidth,\n\t\t\t\t\t\theight: naturalHeight,\n\t\t\t\t\t\ttransform: `scale(${scale})`,\n\t\t\t\t\t\ttransformOrigin: \"top left\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nNoteBlockRenderer.displayName = \"NoteBlockRenderer\";\n","import { DEFAULT_BOOK } from \"../../../types/schema\";\nimport { NoteBlockRenderer } from \"./renderer\";\n\nimport type { BlockPlugin } from \"../../../plugin/types\";\nimport type { NoteBlockProps, NoteBlockValue } from \"./types\";\n\n/**\n * ノートブロックのプラグイン定義。\n *\n * `kind: \"note\"` で登録され、Book を内包して別のグリッドをブロック内にレンダリングする。\n *\n * @remarks\n * **Canvas** — 入れ子グリッドユースケース向けのプラグイン。\n *\n * 標準フォーム構築では `createPluginRegistry` に渡すだけで使用できる。\n */\nexport const NoteBlockPlugin: BlockPlugin<NoteBlockProps, NoteBlockValue> = {\n\tkind: \"note\",\n\tmeta: {\n\t\tdisplayName: \"ノートブロック\",\n\t\tdescription: \"ブロックとして振る舞う Note(入れ子グリッド)\",\n\t\tdefaultSize: { w: 6, h: 4 },\n\t},\n\tRenderer: NoteBlockRenderer,\n\tproperties: [],\n\tvalidateProps: (props: unknown): NoteBlockProps => {\n\t\tif (\n\t\t\ttypeof props === \"object\" &&\n\t\t\tprops !== null &&\n\t\t\t\"book\" in props &&\n\t\t\ttypeof (props as { book: unknown }).book === \"object\" &&\n\t\t\t(props as { book: unknown }).book !== null\n\t\t) {\n\t\t\treturn props as NoteBlockProps;\n\t\t}\n\t\treturn { book: DEFAULT_BOOK };\n\t},\n\tvalidateValue: (): NoteBlockValue => null,\n};\n","import { PaperSizePreset } from \"../../../types/paper\";\nimport { CheckboxPlugin } from \"../../blocks/checkbox\";\nimport { NoteBlockPlugin } from \"../../blocks/note\";\nimport { SelectPlugin } from \"../../blocks/select\";\nimport { StepperPlugin } from \"../../blocks/stepper\";\nimport { TextPlugin } from \"../../blocks/text\";\nimport { numberInputBlock } from \"../primitives/numberInputBlock\";\nimport { unitSelectBlock } from \"../primitives/unitSelectBlock\";\n\nimport type { Block } from \"../../../types/block\";\nimport type { Value } from \"../../../types/value\";\nimport type { NoteBlockProps } from \"../../blocks/note\";\nimport type { WidgetDef } from \"../types\";\n\n// NoteBlockProps はランタイムには JSON 互換だが、TS が再帰型の静的証明をできないため\n// このヘルパー経由で単一箇所にキャストを限定する。\nfunction notePropsAsRecord(props: NoteBlockProps): Record<string, Value> {\n\t// NoteBlockProps は JSON 互換だが TS が再帰型の静的証明をできないため as unknown as が必要\n\treturn props as unknown as Record<string, Value>;\n}\n\n// Custom 選択時のみ行 2 を表示するための hiddenBinding。\n// `paper.size.preset` が \"Custom\" でない(neq)ときに非表示。\nconst HIDDEN_WHEN_NOT_CUSTOM = {\n\tpath: \"paper.size.preset\",\n\tneq: PaperSizePreset.CUSTOM,\n} as const;\n\n// 行 widget 共通のペーパー設定\nconst ROW_PAPER = {\n\tsize: {\n\t\tpreset: PaperSizePreset.CUSTOM,\n\t\twidth: { value: 160, unit: \"mm\" as const },\n\t\theight: { value: 10, unit: \"mm\" as const },\n\t},\n\tmargin: {\n\t\ttop: { value: 0, unit: \"mm\" as const },\n\t\tright: { value: 0, unit: \"mm\" as const },\n\t\tbottom: { value: 0, unit: \"mm\" as const },\n\t\tleft: { value: 0, unit: \"mm\" as const },\n\t},\n\tautoHeight: true,\n\tautoWidth: true,\n};\n\n// 行 0: プリセット選択 + 向き checkbox の 1 行 widget(内部用)\n// 8 列 × 1 行。col 7 のみ 15mm 固定(checkbox 用)。\n// [用紙サイズ ×2][preset select ×3][横向き ×2][checkbox ×1]\nconst PRESET_ORIENTATION_ROW: NoteBlockProps = {\n\tbook: {\n\t\tpaper: ROW_PAPER,\n\t\tpages: [\n\t\t\t{\n\t\t\t\tgrid: {\n\t\t\t\t\tcolCount: 8,\n\t\t\t\t\trowCount: 1,\n\t\t\t\t\tcols: { 7: { value: 15, unit: \"mm\" } },\n\t\t\t\t},\n\t\t\t\tblocks: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-size-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 2, h: 1 },\n\t\t\t\t\t\tinitValue: \"用紙サイズ\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-preset\",\n\t\t\t\t\t\tkind: \"select\",\n\t\t\t\t\t\tlayout: { x: 2, y: 0, w: 3, h: 1 },\n\t\t\t\t\t\tinitValue: PaperSizePreset.A4,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tbinding: \"paper.size.preset\",\n\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\tleft: { value: 2, unit: \"px\" },\n\t\t\t\t\t\t\tselectConfig: {\n\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t{ label: \"A4 (210×297mm)\", value: PaperSizePreset.A4 },\n\t\t\t\t\t\t\t\t\t{ label: \"A3 (297×420mm)\", value: PaperSizePreset.A3 },\n\t\t\t\t\t\t\t\t\t{ label: \"B5 (182×257mm)\", value: PaperSizePreset.B5 },\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Letter (8.5×11inch)\",\n\t\t\t\t\t\t\t\t\t\tvalue: PaperSizePreset.LETTER,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Legal (8.5×14inch)\",\n\t\t\t\t\t\t\t\t\t\tvalue: PaperSizePreset.LEGAL,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{ label: \"カスタム\", value: PaperSizePreset.CUSTOM },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-orientation-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 5, y: 0, w: 2, h: 1 },\n\t\t\t\t\t\tinitValue: \"横向き\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-orientation\",\n\t\t\t\t\t\tkind: \"checkbox\",\n\t\t\t\t\t\tlayout: { x: 7, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tprops: { binding: \"paper.orientation\" },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n};\n\n// 行 1: 幅自動・高さ自動 checkbox の 1 行 widget(内部用)\n// 8 列 × 1 行。列 3・列 7 のみ 15mm 固定(checkbox 用)。\n// [幅自動 ×3][checkbox ×1][高さ自動 ×3][checkbox ×1]\nconst AUTO_RESIZE_ROW: NoteBlockProps = {\n\tbook: {\n\t\tpaper: ROW_PAPER,\n\t\tpages: [\n\t\t\t{\n\t\t\t\tgrid: {\n\t\t\t\t\tcolCount: 8,\n\t\t\t\t\trowCount: 1,\n\t\t\t\t\tcols: {\n\t\t\t\t\t\t3: { value: 15, unit: \"mm\" },\n\t\t\t\t\t\t7: { value: 15, unit: \"mm\" },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tblocks: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-width-auto-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 3, h: 1 },\n\t\t\t\t\t\tinitValue: \"幅自動\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-width-auto\",\n\t\t\t\t\t\tkind: \"checkbox\",\n\t\t\t\t\t\tlayout: { x: 3, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tprops: { binding: \"paper.autoWidth\" },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-height-auto-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 4, y: 0, w: 3, h: 1 },\n\t\t\t\t\t\tinitValue: \"高さ自動\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-height-auto\",\n\t\t\t\t\t\tkind: \"checkbox\",\n\t\t\t\t\t\tlayout: { x: 7, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tprops: { binding: \"paper.autoHeight\" },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n};\n\n// 行 2(末尾): カスタム幅・高さ入力の 1 行 widget(内部用)\n// 8 列 × 1 行。stepper/unit 列は固定幅。\n// [幅/最低幅 ×1][幅数値 ×1][幅stepper(8mm)][幅単位(15mm)][高さ/最低高さ ×1][高さ数値 ×1][高さstepper(8mm)][高さ単位(15mm)]\n// 幅自動 ON 時はラベルが「幅」→「最低幅」に切り替わる(hiddenBinding 2 ブロック)。\nconst DIMENSION_ROW: NoteBlockProps = {\n\tbook: {\n\t\tpaper: ROW_PAPER,\n\t\tpages: [\n\t\t\t{\n\t\t\t\tgrid: {\n\t\t\t\t\tcolCount: 8,\n\t\t\t\t\trowCount: 1,\n\t\t\t\t\tcols: {\n\t\t\t\t\t\t2: { value: 8, unit: \"mm\" },\n\t\t\t\t\t\t3: { value: 15, unit: \"mm\" },\n\t\t\t\t\t\t6: { value: 8, unit: \"mm\" },\n\t\t\t\t\t\t7: { value: 15, unit: \"mm\" },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tblocks: [\n\t\t\t\t\t// 幅ラベル(幅自動 OFF のとき表示)\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-width-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tinitValue: \"幅\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\thiddenBinding: \"paper.autoWidth\",\n\t\t\t\t\t},\n\t\t\t\t\t// 最低幅ラベル(幅自動 ON のとき表示)\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-width-label-min\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tinitValue: \"最低幅\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\thiddenBinding: { path: \"paper.autoWidth\", neq: true },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...numberInputBlock(\"paper-width-value\", \"paper.size.width.value\"),\n\t\t\t\t\t\tlayout: { x: 1, y: 0, w: 1, h: 1 },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-width-stepper\",\n\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\tlayout: { x: 2, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tprops: { binding: \"paper.size.width.value\", step: 1, min: 0 },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...unitSelectBlock(\"paper-width-unit\", \"paper.size.width.unit\"),\n\t\t\t\t\t\tlayout: { x: 3, y: 0, w: 1, h: 1 },\n\t\t\t\t\t},\n\t\t\t\t\t// 高さラベル(高さ自動 OFF のとき表示)\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-height-label\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 4, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tinitValue: \"高さ\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\thiddenBinding: \"paper.autoHeight\",\n\t\t\t\t\t},\n\t\t\t\t\t// 最低高さラベル(高さ自動 ON のとき表示)\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-height-label-min\",\n\t\t\t\t\t\tkind: \"text\",\n\t\t\t\t\t\tlayout: { x: 4, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tinitValue: \"最低高さ\",\n\t\t\t\t\t\tbehavior: { readOnly: true },\n\t\t\t\t\t\tprops: { horizontal: \"center\", vertical: \"center\" },\n\t\t\t\t\t\thiddenBinding: { path: \"paper.autoHeight\", neq: true },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...numberInputBlock(\n\t\t\t\t\t\t\t\"paper-height-value\",\n\t\t\t\t\t\t\t\"paper.size.height.value\",\n\t\t\t\t\t\t),\n\t\t\t\t\t\tlayout: { x: 5, y: 0, w: 1, h: 1 },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"paper-height-stepper\",\n\t\t\t\t\t\tkind: \"stepper\",\n\t\t\t\t\t\tlayout: { x: 6, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\tprops: { binding: \"paper.size.height.value\", step: 1, min: 0 },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...unitSelectBlock(\"paper-height-unit\", \"paper.size.height.unit\"),\n\t\t\t\t\t\tlayout: { x: 7, y: 0, w: 1, h: 1 },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n};\n\n/**\n * 用紙設定 compound widget。\n * @remarks\n * カスタムシェル構築専用。\n *\n * * 3 つの行 widget を NoteBlock として縦に並べた外偵コンテナ。\n *\n * - 行 0(常に表示): PRESET_ORIENTATION_ROW\n * - 行 1(常に表示): AUTO_RESIZE_ROW\n * - 行 2(Custom 選択時のみ): DIMENSION_ROW ← 末尾・hiddenBinding で縮小\n *\n * binding:\n * - `paper.size.preset` / `paper.orientation`\n * - `paper.autoWidth` / `paper.autoHeight`\n * - `paper.size.width.value` / `.unit` / `paper.size.height.value` / `.unit`\n */\nexport const paperSettingsWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: {\n\t\t\t\tsize: {\n\t\t\t\t\tpreset: PaperSizePreset.CUSTOM,\n\t\t\t\t\twidth: { value: 160, unit: \"mm\" },\n\t\t\t\t\theight: { value: 30, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tmargin: {\n\t\t\t\t\ttop: { value: 0, unit: \"mm\" },\n\t\t\t\t\tright: { value: 0, unit: \"mm\" },\n\t\t\t\t\tbottom: { value: 0, unit: \"mm\" },\n\t\t\t\t\tleft: { value: 0, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tautoHeight: true,\n\t\t\t\tautoWidth: true,\n\t\t\t},\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: {\n\t\t\t\t\t\tcolCount: 1,\n\t\t\t\t\t\trowCount: 3,\n\t\t\t\t\t\trows: {\n\t\t\t\t\t\t\t0: { value: 10, unit: \"mm\" },\n\t\t\t\t\t\t\t1: { value: 10, unit: \"mm\" },\n\t\t\t\t\t\t\t2: { value: 10, unit: \"mm\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"row-preset-orientation\",\n\t\t\t\t\t\t\tkind: \"note\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tbehavior: { heightFit: true },\n\t\t\t\t\t\t\tprops: notePropsAsRecord(PRESET_ORIENTATION_ROW),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"row-auto-resize\",\n\t\t\t\t\t\t\tkind: \"note\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 1, w: 1, h: 1 },\n\t\t\t\t\t\t\tbehavior: { heightFit: true },\n\t\t\t\t\t\t\tprops: notePropsAsRecord(AUTO_RESIZE_ROW),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"row-dimension\",\n\t\t\t\t\t\t\tkind: \"note\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 2, w: 1, h: 1 },\n\t\t\t\t\t\t\tbehavior: { heightFit: true },\n\t\t\t\t\t\t\tprops: notePropsAsRecord(DIMENSION_ROW),\n\t\t\t\t\t\t\thiddenBinding: HIDDEN_WHEN_NOT_CUSTOM,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [\n\t\tCheckboxPlugin,\n\t\tNoteBlockPlugin,\n\t\tSelectPlugin,\n\t\tStepperPlugin,\n\t\tTextPlugin,\n\t],\n};\n\n// ============================================================================\n// Atom / 部品 widget\n// ============================================================================\n\n/**\n * 横向き checkbox atom widget。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * binding: `paper.orientation`(true = landscape, false = portrait)\n */\nexport const paperOrientationWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: {\n\t\t\t\tsize: {\n\t\t\t\t\tpreset: PaperSizePreset.CUSTOM,\n\t\t\t\t\twidth: { value: 20, unit: \"mm\" },\n\t\t\t\t\theight: { value: 15, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tmargin: {\n\t\t\t\t\ttop: { value: 0, unit: \"mm\" },\n\t\t\t\t\tright: { value: 0, unit: \"mm\" },\n\t\t\t\t\tbottom: { value: 0, unit: \"mm\" },\n\t\t\t\t\tleft: { value: 0, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tautoHeight: true,\n\t\t\t\tautoWidth: true,\n\t\t\t},\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: { colCount: 1, rowCount: 1 },\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"paper-orientation\",\n\t\t\t\t\t\t\tkind: \"checkbox\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: { binding: \"paper.orientation\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [CheckboxPlugin],\n};\n\n/**\n * 用紙プリセット選択 atom widget。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * binding: `paper.size.preset`\n */\nexport const paperPresetSelectWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: {\n\t\t\t\tsize: {\n\t\t\t\t\tpreset: PaperSizePreset.CUSTOM,\n\t\t\t\t\twidth: { value: 60, unit: \"mm\" },\n\t\t\t\t\theight: { value: 10, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tmargin: {\n\t\t\t\t\ttop: { value: 0, unit: \"mm\" },\n\t\t\t\t\tright: { value: 0, unit: \"mm\" },\n\t\t\t\t\tbottom: { value: 0, unit: \"mm\" },\n\t\t\t\t\tleft: { value: 0, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tautoHeight: true,\n\t\t\t\tautoWidth: true,\n\t\t\t},\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: { colCount: 1, rowCount: 1 },\n\t\t\t\t\tblocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"paper-preset\",\n\t\t\t\t\t\t\tkind: \"select\",\n\t\t\t\t\t\t\tlayout: { x: 0, y: 0, w: 1, h: 1 },\n\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\tbinding: \"paper.size.preset\",\n\t\t\t\t\t\t\t\tselectConfig: {\n\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t{ label: \"A4 (210×297mm)\", value: PaperSizePreset.A4 },\n\t\t\t\t\t\t\t\t\t\t{ label: \"A3 (297×420mm)\", value: PaperSizePreset.A3 },\n\t\t\t\t\t\t\t\t\t\t{ label: \"B5 (182×257mm)\", value: PaperSizePreset.B5 },\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Letter (8.5×11inch)\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: PaperSizePreset.LETTER,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Legal (8.5×14inch)\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: PaperSizePreset.LEGAL,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ label: \"カスタム\", value: PaperSizePreset.CUSTOM },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [SelectPlugin],\n};\n\n/**\n * `paperSizeWidget` 内のブロック定義(再利用可能)。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * 4列×2行グリッド想定:\n * - 行 0: プリセット select(colspan: 4)\n * - 行 1: 幅value / 幅unit / 高さvalue / 高さunit(Custom 選択時のみ)\n */\nexport const PAPER_SIZE_BLOCKS: Block[] = [\n\t// 行 0: プリセット選択\n\t{\n\t\tid: \"paper-preset\",\n\t\tkind: \"select\",\n\t\tlayout: { x: 0, y: 0, w: 4, h: 1 },\n\t\tprops: {\n\t\t\tbinding: \"paper.size.preset\",\n\t\t\tselectConfig: {\n\t\t\t\toptions: [\n\t\t\t\t\t{ label: \"A4 (210×297mm)\", value: PaperSizePreset.A4 },\n\t\t\t\t\t{ label: \"A3 (297×420mm)\", value: PaperSizePreset.A3 },\n\t\t\t\t\t{ label: \"B5 (182×257mm)\", value: PaperSizePreset.B5 },\n\t\t\t\t\t{ label: \"Letter (8.5×11inch)\", value: PaperSizePreset.LETTER },\n\t\t\t\t\t{ label: \"Legal (8.5×14inch)\", value: PaperSizePreset.LEGAL },\n\t\t\t\t\t{ label: \"カスタム\", value: PaperSizePreset.CUSTOM },\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t},\n\t// 行 1: 幅・高さ dimension 入力(Custom 選択時のみ表示)\n\t{\n\t\t...numberInputBlock(\"paper-width-value\", \"paper.size.width.value\"),\n\t\tlayout: { x: 0, y: 1, w: 1, h: 1 },\n\t\thiddenBinding: HIDDEN_WHEN_NOT_CUSTOM,\n\t},\n\t{\n\t\t...unitSelectBlock(\"paper-width-unit\", \"paper.size.width.unit\"),\n\t\tlayout: { x: 1, y: 1, w: 1, h: 1 },\n\t\thiddenBinding: HIDDEN_WHEN_NOT_CUSTOM,\n\t},\n\t{\n\t\t...numberInputBlock(\"paper-height-value\", \"paper.size.height.value\"),\n\t\tlayout: { x: 2, y: 1, w: 1, h: 1 },\n\t\thiddenBinding: HIDDEN_WHEN_NOT_CUSTOM,\n\t},\n\t{\n\t\t...unitSelectBlock(\"paper-height-unit\", \"paper.size.height.unit\"),\n\t\tlayout: { x: 3, y: 1, w: 1, h: 1 },\n\t\thiddenBinding: HIDDEN_WHEN_NOT_CUSTOM,\n\t},\n];\n\n/**\n * 用紙サイズ設定 compound widget。\n *\n * @remarks\n * **Canvas** — カスタムシェル構築専用。\n *\n * グリッド: 4列×2行\n * - 列 1 (15mm): 幅単位 select\n * - 列 3 (15mm): 高さ単位 select\n * - その他: 1fr\n *\n * 行 0: プリセット select(常に表示)\n *\n * 行 1: 幅・高さ dimension 入力(Custom 選択時のみ表示)\n */\nexport const paperSizeWidget: WidgetDef = {\n\tprops: {\n\t\tbook: {\n\t\t\tpaper: {\n\t\t\t\tsize: {\n\t\t\t\t\tpreset: PaperSizePreset.CUSTOM,\n\t\t\t\t\twidth: { value: 80, unit: \"mm\" },\n\t\t\t\t\theight: { value: 30, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tmargin: {\n\t\t\t\t\ttop: { value: 0, unit: \"mm\" },\n\t\t\t\t\tright: { value: 0, unit: \"mm\" },\n\t\t\t\t\tbottom: { value: 0, unit: \"mm\" },\n\t\t\t\t\tleft: { value: 0, unit: \"mm\" },\n\t\t\t\t},\n\t\t\t\tautoHeight: true,\n\t\t\t\tautoWidth: true,\n\t\t\t},\n\t\t\tpages: [\n\t\t\t\t{\n\t\t\t\t\tgrid: {\n\t\t\t\t\t\tcolCount: 4,\n\t\t\t\t\t\trowCount: 2,\n\t\t\t\t\t\tcols: {\n\t\t\t\t\t\t\t1: { value: 15, unit: \"mm\" },\n\t\t\t\t\t\t\t3: { value: 15, unit: \"mm\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tblocks: PAPER_SIZE_BLOCKS,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\tplugins: [NoteBlockPlugin, SelectPlugin, StepperPlugin, TextPlugin],\n};\n"],"names":["fontStyleProp","paddingProp","placeholderProp","requiredProp","ValidationSeverity","isSafePattern","pattern","hasValidationRule","props","p","evaluateValidation","schema","value","errors","v","evaluateCheckboxValidation","createBlockId","kind","evalHiddenBinding","hidden","bindingContext","cur","DEFAULT_PAGE","DEFAULT_GRID","DEFAULT_BOOK","DEFAULT_PAPER","getBlockZIndex","index","zIndex","Z_INDEX","getSubZIndex","baseZIndex","subIndex","clampedOffset","getMaxBlockCount","validateBook","book","seen","duplicates","maxBlockCount","pageIndex","page","block","id","toNonEmptyPages","pages","addPage","emptyPage","ensurePageIds","removePage","_","i","movePage","from","to","moved","setPage","pageIdx","insertPage","afterIdx","newPages","cleanValues","values","existingIds","b","k","getPaperSize","preset","orientation","size","DEFAULT_PAPER_SIZES","w","toMm","h","resolveEffectivePaper","printSettings","buildPageCss","paper","margin","isLandscape","marginCss","H_ALIGN_CSS","HorizontalAlign","V_ALIGN_CSS","VerticalAlign","CheckboxRenderer","forwardRef","onChange","readOnly","ariaLabel","ref","divRef","useRef","useImperativeHandle","_a","isChecked","containerStyle","useMemo","css","padAll","padTop","padRight","padBottom","padLeft","dimensionToString","sizePx","toPx","handleClick","jsxs","e","jsx","ClassicCheckboxVisual","checkboxAlignmentProp","alignmentProp","CheckboxPlugin","checkboxStyleProp","selectConfigProp","isValidCssColor","color","H_ALIGN_TEXT","SelectRenderer","mode","blockBackgroundColor","selectRef","isDisabled","NoteMode","selectedOption","o","selectedColor","bgColor","selectStyle","dec","arrowStyle","handleChange","newValue","handleContainerClick","_b","handleContainerKeyDown","label","viewStyle","resolveOptionBackground","inner","Fragment","_c","opt","optBg","SelectPlugin","rawCfg","_ignored","rest","TextRenderer","onBlur","onMeasureHeight","onMeasureWidth","inputRef","containerRef","ghostRef","widthSpanRef","textareaHeight","setTextareaHeight","useState","lastReportedHeight","lastReportedWidth","safeValue","useLayoutEffect","ghost","container","displayValue","cs","paddingTop","paddingBottom","paddingLeft","paddingRight","availableWidth","contentHeight","neededHeight","span","isEditable","inputStyle","widthSpanStyle","ghostStyle","noWrap","handleBlur","charFilterRegex","m","resolvedInputMode","handleBeforeInput","useCallback","nativeEvent","char","handleCompositionEnd","el","filtered","c","placeholder","textareaStyle","setTextareaRefs","TextPlugin","textBehaviorProp","textValidationProp","patched","key","useBookActionContext","handlers","handlersRef","execute","actionId","payload","handler","isEnabled","setNested","obj","keys","head","tail","current","setPath","path","resolvePath","useBookBindingContext","onBookChange","options","bookRef","pageIdxRef","extraRef","get","extra","set","all","bindingKey","subKey","newMargin","pi","newGrid","MERGE_WINDOW_MS","histReducer","state","action","last","newEntries","trimmed","DEFAULT_MAX_HISTORY","useBookHistory","initialBook","maxHistory","resolvedMaxHistory","dispatch","useReducer","handleBookChange","newBook","undo","redo","getLineDasharray","type","lineWidth","LineType","lineAttrs","style","dpi","BlockBorder","memo","blockSizePx","borderStyle","blockZIndex","subZIndex","BLOCK_SUB_INDEX","visible","DEFAULT_DPI","top","right","bottom","left","BlockCanvas","backgroundColor","toDashArray","strokeWidth","DEFAULT_GUIDE_BORDER","BlockGuideBorder","BlockRendererInner","resolvedPlugin","actionContext","innerRef","rendererProps","Renderer","BlockRenderer","resolveBlockProps","blockDefaults","kindDefaults","ValidationOverlay","hovered","setHovered","BORDER_WIDTH","stripe","edgeStyle","side","BlockContainer","blockRectPx","onValueChange","showGuides","showBorder","defaultGuideBorder","pointerEvents","showValidation","validationErrors","focusedBlockId","localHeight","setLocalHeight","localWidth","setLocalWidth","handleContentHeight","heightPx","handleContentWidth","widthPx","effectiveHeight","effectiveWidth","effectiveBlockSizePx","resolvedProps","validatedProps","validatedValue","hasErrors","errorDescId","isFocused","_d","_e","prev","next","NOOP_MEASURE_HEIGHT","_id","_h","NOOP_MEASURE_WIDTH","_w","BlockLayer","blocks","pluginRegistry","selectedBlockIds","getBlockRectPx","blockRefs","layerStyle","binding","handleValueChange","val","blockMeasureHeight","blockMeasureWidth","r","getStrokeDasharray","lineStyle","BorderOverlay","contentPx","marginLeftPx","marginTopPx","GridCanvas","canvasPx","boxShadow","SUPPORTED_UNITS","convertPxToUnit","pxSize","targetUnit","_exhaustive","GridUnitEditor","direction","dimension","currentPxSize","position","onCancel","setValue","unit","setUnit","editorStyle","useEffect","handleClickOutside","event","handleSubmit","numValue","handleKeyDown","handleUnitChange","newUnit","styles","u","originalValue","originalPxSize","GridDimensionLabel","isNearCursor","resizingPxSize","onDimensionChange","isEditing","setIsEditing","labelStyle","displayText","dim","newDim","getGridPathD","colPxs","rowPxs","width","height","d","x","y","GridOverlay","gridPosPx","pathData","GridResizeHandle","onResizeStart","onResize","onResizeEnd","isDragging","setIsDragging","HANDLE_SIZE","HANDLE_OFFSET","handleStyle","handlePointerDown","initialPos","handlePointerMove","moveEvent","currentPos","handlePointerUp","upEvent","MarginOverlay","paperPx","marginColor","GridLayer","gridDimensions","gridLineStyle","marginFillColor","showGridLines","showMargins","showResizeHandles","showDimensionLabels","onGridResize","className","ghostLine","setGhostLine","draggingHandle","setDraggingHandle","mousePos","setMousePos","handleMouseMove","rect","handleMouseLeave","shouldShowDimensionLabels","resizingPreviewSizes","gridLines","prevStart","nextEnd","clampDelta","delta","originalPos","prevLinePos","nextLinePos","clamped","handleResizeStart","handleResize","handleResizeEnd","colPos","rowPos","startPos","endPos","isDraggingAdjacent","useInteractionState","initialState","InteractionMode","ResizeHandle","DragType","getInteractionMode","calculateResizedLayout","layout","handle","deltaCol","deltaRow","gridCols","gridRows","newLayout","maxW","maxShrink","validDCol","maxH","validDRow","clampMultipleBlocks","maxX","maxY","minX","minY","maxBoundX","maxBoundY","boundW","boundH","clampedMinX","clampedMinY","actualDeltaCol","actualDeltaRow","createBlock","plugin","GHOST_GUIDE_BORDER","GhostBlock","opacity","ghostZIndex","DragLayer","gridLength","draggingState","wrapper","DT","dragTargets","clampedPositions","ghostRect","isOutside","currentMousePx","origRect","clampedPos","ghostBlock","blockId","pluginKind","defaultSize","currentGrid","tempBlock","tempRect","blockWithSize","displayBlock","EditingBlockInner","EditingBlock","SELECTION_LINE","SELECTION_STYLE","HANDLES","InteractionBlock","showHandles","activeHandle","selectionStyle","selectBorderZIndex","blockHandlesZIndex","cursor","isActive","SelectionLayer","uniqueIds","clampBlockToGrid","calcDuplicatePosition","newX","newY","findBlockAtPoint","point","InteractionLayer","getColIndex","getRowIndex","onStateChange","onSelectionChange","onPageChange","scale","layerRef","editingBlockRef","focusTimerRef","arrowSessionRef","arrowSessionCounterRef","resizeSessionRef","resizeSessionCounterRef","stateRef","onStateChangeRef","handleWindowPointerUp","layer","blockIds","validIds","sf","px","targetId","gridCol","gridRow","isSelected","canvasW","canvasH","rawX","rawY","clampedX","clampedY","currentCol","currentRow","deletedIds","pos","resolved","newBlock","handleDoubleClick","handlePointerLeave","newBlocks","sorted","a","selectedId","curIdx","first","resizeDelta","sortedResizeIds","prevResize","resizeSession","keyboardResizeKey","nx","ny","sortedIds","session","sessionId","arrowMoveKey","startCol","startRow","editingContent","editingBlock","initValueKey","PluginRegistryContext","createContext","pxValue","resizeFrAndFixed","dimensions","deltaPx","fixedSide","totalContentPx","totalFr","totalFixedPx","availableForFrPx","currentFrToPx","nextPx","newNextPx","newAvailableForFrPx","newCurrentPx","newCurrentFr","currentPx","newNextFr","resizeFixedPair","resizeFrPair","sum","frToPx","calcGridResize","newDimensions","useNoteLayout","useGridCalc","isFit","isWidthFit","measuredHeights","setMeasuredHeights","measuredWidths","setMeasuredWidths","handleMeasureHeight","handleMeasureWidth","measuredContentBottomPx","maxBottom","blockH","measuredContentRightPx","maxRight","blockW","canvasHeightPx","canvasWidthPx","gridTotalWidth","fitWidth","effectivePaperPx","result","raw","strVal","NoteEdit","context","onValuesChange","setFocusedBlockId","sortedBlocks","handleFocusCapture","blockEl","handleBlurCapture","STACKING_ISOLATION_STYLE","NoteForm","newPage","interactionState","ids","paperRef","expandedCols","expandedRows","useExpandedGrid","handleDragEnter","getBlockDragKind","col","row","handleDragOver","BLOCK_DRAG_MIME","handleDragLeave","handleDrop","data","getBlockDragData","getAdjustedBlockRectPx","handleInitValueChange","nextBlocks","target","isSidebar","SIDEBAR_PORTAL_SELECTOR","isActionBar","handleGridResize","dimensionIndex","newCols","colsToSparse","newRows","rowsToSparse","handleDimensionChange","visibleValues","NoteView","Note","executeButtonAction","isButtonActionEnabled","getButtonActionActive","buttonContentProp","buttonActionProp","ButtonRenderer","buttonRef","pressed","setPressed","isActionEnabled","ButtonPlugin","numberInputBlock","UNIT_OPTIONS","unitSelectBlock","stepperBehaviorProp","stepperStyleProp","clampStep","min","max","UP_PATH","DOWN_PATH","buttonOverlayStyle","disabled","StepperRenderer","pressedUp","setPressedUp","pressedDown","setPressedDown","step","arrowColor","arrowWidth","arrowHeight","arrowGap","arrowLeft","apply","handleUp","handleDown","svgFeedback","StepperPlugin","ATOM_PAPER","PaperSizePreset","ATOM_GRID","gridRowCountWidget","gridColCountWidget","gridSettingsWidget","NOOP_BINDING_CONTEXT","NOOP_ACTION_CONTEXT","NOOP_EDITOR_STATE","NoteBlockRenderer","useContext","naturalWidth","naturalHeight","nw","nh","s","noteContext","NoteBlockPlugin","HIDDEN_WHEN_NOT_CUSTOM","ROW_PAPER","PRESET_ORIENTATION_ROW","AUTO_RESIZE_ROW","DIMENSION_ROW","paperSettingsWidget","paperOrientationWidget","paperPresetSelectWidget","PAPER_SIZE_BLOCKS","paperSizeWidget"],"mappings":"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"}