@hirokisakabe/pom 8.3.0 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -23
- package/dist/autoFit/autoFit.js +1 -1
- package/dist/autoFit/autoFit.js.map +1 -1
- package/dist/autoFit/strategies/reduceFontSize.js +16 -14
- package/dist/autoFit/strategies/reduceFontSize.js.map +1 -1
- package/dist/autoFit/strategies/reduceGapAndPadding.js +13 -20
- package/dist/autoFit/strategies/reduceGapAndPadding.js.map +1 -1
- package/dist/autoFit/strategies/reduceTableRowHeight.js +8 -2
- package/dist/autoFit/strategies/reduceTableRowHeight.js.map +1 -1
- package/dist/autoFit/strategies/uniformScale.js +19 -20
- package/dist/autoFit/strategies/uniformScale.js.map +1 -1
- package/dist/autoFit/strategyResult.js +15 -0
- package/dist/autoFit/strategyResult.js.map +1 -0
- package/dist/buildPptx.js +1 -1
- package/dist/calcYogaLayout/calcYogaLayout.js +16 -27
- package/dist/calcYogaLayout/calcYogaLayout.js.map +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/parseXml/coercionRules.js +43 -8
- package/dist/parseXml/coercionRules.js.map +1 -1
- package/dist/parseXml/parseXml.d.ts +8 -3
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js +192 -212
- package/dist/parseXml/parseXml.js.map +1 -1
- package/dist/parseXml/serializeXml.d.ts.map +1 -1
- package/dist/parseXml/serializeXml.js +12 -17
- package/dist/parseXml/serializeXml.js.map +1 -1
- package/dist/registry/definitions/arrow.js +2 -2
- package/dist/registry/definitions/arrow.js.map +1 -1
- package/dist/registry/definitions/chart.js +2 -2
- package/dist/registry/definitions/chart.js.map +1 -1
- package/dist/registry/definitions/compositeNodes.js +7 -12
- package/dist/registry/definitions/compositeNodes.js.map +1 -1
- package/dist/registry/definitions/icon.js +2 -2
- package/dist/registry/definitions/icon.js.map +1 -1
- package/dist/registry/definitions/image.js +2 -2
- package/dist/registry/definitions/image.js.map +1 -1
- package/dist/registry/definitions/layer.js +4 -5
- package/dist/registry/definitions/layer.js.map +1 -1
- package/dist/registry/definitions/line.js +2 -2
- package/dist/registry/definitions/line.js.map +1 -1
- package/dist/registry/definitions/list.js +3 -4
- package/dist/registry/definitions/list.js.map +1 -1
- package/dist/registry/definitions/shape.js +2 -2
- package/dist/registry/definitions/shape.js.map +1 -1
- package/dist/registry/definitions/stack.js +3 -4
- package/dist/registry/definitions/stack.js.map +1 -1
- package/dist/registry/definitions/svg.js +2 -2
- package/dist/registry/definitions/svg.js.map +1 -1
- package/dist/registry/definitions/table.js +2 -2
- package/dist/registry/definitions/table.js.map +1 -1
- package/dist/registry/definitions/text.js +2 -2
- package/dist/registry/definitions/text.js.map +1 -1
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/nodeMetadata.js +208 -0
- package/dist/registry/nodeMetadata.js.map +1 -0
- package/dist/registry/nodeRegistry.js +3 -0
- package/dist/registry/nodeRegistry.js.map +1 -1
- package/dist/registry/xmlChildRules.js +55 -0
- package/dist/registry/xmlChildRules.js.map +1 -0
- package/dist/renderPptx/nodes/arrow.js +7 -28
- package/dist/renderPptx/nodes/arrow.js.map +1 -1
- package/dist/renderPptx/nodes/chart.js +2 -7
- package/dist/renderPptx/nodes/chart.js.map +1 -1
- package/dist/renderPptx/nodes/flow.js +6 -13
- package/dist/renderPptx/nodes/flow.js.map +1 -1
- package/dist/renderPptx/nodes/icon.js +4 -2
- package/dist/renderPptx/nodes/icon.js.map +1 -1
- package/dist/renderPptx/nodes/image.js +5 -13
- package/dist/renderPptx/nodes/image.js.map +1 -1
- package/dist/renderPptx/nodes/line.js +9 -33
- package/dist/renderPptx/nodes/line.js.map +1 -1
- package/dist/renderPptx/nodes/list.js +8 -20
- package/dist/renderPptx/nodes/list.js.map +1 -1
- package/dist/renderPptx/nodes/matrix.js +10 -11
- package/dist/renderPptx/nodes/matrix.js.map +1 -1
- package/dist/renderPptx/nodes/processArrow.js +9 -16
- package/dist/renderPptx/nodes/processArrow.js.map +1 -1
- package/dist/renderPptx/nodes/pyramid.js +5 -7
- package/dist/renderPptx/nodes/pyramid.js.map +1 -1
- package/dist/renderPptx/nodes/shape.js +7 -20
- package/dist/renderPptx/nodes/shape.js.map +1 -1
- package/dist/renderPptx/nodes/svg.js +2 -5
- package/dist/renderPptx/nodes/svg.js.map +1 -1
- package/dist/renderPptx/nodes/table.js +2 -5
- package/dist/renderPptx/nodes/table.js.map +1 -1
- package/dist/renderPptx/nodes/text.js +4 -1
- package/dist/renderPptx/nodes/text.js.map +1 -1
- package/dist/renderPptx/nodes/timeline.js +20 -22
- package/dist/renderPptx/nodes/timeline.js.map +1 -1
- package/dist/renderPptx/nodes/tree.js +5 -5
- package/dist/renderPptx/nodes/tree.js.map +1 -1
- package/dist/renderPptx/renderPptx.js +13 -29
- package/dist/renderPptx/renderPptx.js.map +1 -1
- package/dist/renderPptx/textOptions.js +32 -8
- package/dist/renderPptx/textOptions.js.map +1 -1
- package/dist/renderPptx/units.js +11 -1
- package/dist/renderPptx/units.js.map +1 -1
- package/dist/renderPptx/utils/backgroundBorder.js +103 -57
- package/dist/renderPptx/utils/backgroundBorder.js.map +1 -1
- package/dist/renderPptx/utils/contentArea.js +26 -9
- package/dist/renderPptx/utils/contentArea.js.map +1 -1
- package/dist/renderPptx/utils/scaleToFit.js +17 -1
- package/dist/renderPptx/utils/scaleToFit.js.map +1 -1
- package/dist/renderPptx/utils/straightLine.js +41 -0
- package/dist/renderPptx/utils/straightLine.js.map +1 -0
- package/dist/renderPptx/utils/visualStyle.js +113 -0
- package/dist/renderPptx/utils/visualStyle.js.map +1 -0
- package/dist/shared/boxSpacing.js +63 -0
- package/dist/shared/boxSpacing.js.map +1 -0
- package/dist/shared/walkTree.js +1 -7
- package/dist/shared/walkTree.js.map +1 -1
- package/dist/toPositioned/toPositioned.js +1 -1
- package/dist/toPositioned/toPositioned.js.map +1 -1
- package/dist/types.d.ts +1127 -95
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +47 -17
- package/dist/types.js.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calcYogaLayout.js","names":[],"sources":["../../src/calcYogaLayout/calcYogaLayout.ts"],"sourcesContent":["import type { POMNode, AlignItems } from \"../types.ts\";\nimport type { BuildContext } from \"../buildContext.ts\";\nimport type { YogaNodeMap } from \"./types.ts\";\nimport { Node as YogaNode } from \"yoga-layout\";\nimport { loadYoga } from \"yoga-layout/load\";\nimport { prefetchImageSize } from \"../shared/measureImage.ts\";\nimport { freeYogaTree } from \"../shared/freeYogaTree.ts\";\nimport { getNodeDef } from \"../registry/index.ts\";\n\n/**\n * POMNode ツリーを Yoga でレイアウト計算する\n * POMNode と YogaNode の対応を YogaNodeMap として返す\n *\n * @param root 入力 POMNode ツリーのルート\n * @param slideSize スライド全体のサイズ(px)\n * @param ctx BuildContext\n * @returns YogaNodeMap(POMNode → YogaNode のマッピング)\n */\nexport async function calcYogaLayout(\n root: POMNode,\n slideSize: { w: number; h: number },\n ctx: BuildContext,\n): Promise<YogaNodeMap> {\n const Yoga = await getYoga();\n\n // 事前に全画像のサイズを取得(HTTPS対応のため)\n await prefetchAllImageSizes(root, ctx);\n\n const map: YogaNodeMap = new Map();\n\n try {\n const rootYoga = Yoga.Node.create();\n map.set(root, rootYoga);\n\n await buildPomWithYogaTree(root, rootYoga, ctx, map);\n\n // スライド全体サイズを指定\n rootYoga.setWidth(slideSize.w);\n rootYoga.setHeight(slideSize.h);\n\n rootYoga.calculateLayout(slideSize.w, slideSize.h, Yoga.DIRECTION_LTR);\n } catch (e) {\n // 途中で失敗した場合、作成済みの YogaNode を解放してから再 throw\n freeYogaTree(map);\n throw e;\n }\n\n return map;\n}\n\n/**\n * POMNode ツリー内のすべての画像のサイズを事前取得する\n */\nasync function prefetchAllImageSizes(\n node: POMNode,\n ctx: BuildContext,\n): Promise<void> {\n const imageSources = collectImageSources(node);\n await Promise.all(\n imageSources.map((src) =>\n prefetchImageSize(\n src,\n ctx.imageSizeCache,\n ctx.imageDataCache,\n ctx.diagnostics,\n ),\n ),\n );\n}\n\n/**\n * POMNode ツリー内のすべての画像のsrcを収集する\n */\nfunction collectImageSources(node: POMNode): string[] {\n const sources: string[] = [];\n\n function traverse(n: POMNode) {\n // backgroundImage の src を収集(全ノード共通)\n if (n.backgroundImage) {\n sources.push(n.backgroundImage.src);\n }\n\n const def = getNodeDef(n.type);\n\n // ノード固有の画像ソース収集\n if (def.collectImageSources) {\n sources.push(...def.collectImageSources(n));\n }\n\n // 子要素の再帰\n switch (def.category) {\n case \"multi-child\":\n case \"absolute-child\": {\n const containerNode = n as Extract<\n POMNode,\n { type: \"vstack\" | \"hstack\" | \"layer\" }\n >;\n for (const child of containerNode.children) {\n traverse(child);\n }\n break;\n }\n }\n }\n\n traverse(node);\n return sources;\n}\n\n/**\n * Yogaシングルトン\n */\nlet yogaP: Promise<Yoga> | null = null;\ntype Yoga = Awaited<ReturnType<typeof loadYoga>>;\nasync function getYoga(): Promise<Yoga> {\n if (yogaP === null) yogaP = loadYoga();\n return yogaP;\n}\n\n/**\n * ノードが交差軸方向(幅)で確定サイズを持つかを判定する\n * - 明示的な w がある場合は確定\n * - alignSelf で stretch 以外が指定されている場合は不確定\n * - 親の alignItems で stretch(デフォルト)以外が指定されている場合は不確定\n */\nfunction nodeHasDefiniteWidth(node: POMNode, parentNode?: POMNode): boolean {\n // 明示的な幅がある\n if (node.w !== undefined) return true;\n\n // alignSelf で stretch 以外が明示されている場合は不確定\n if (\n node.alignSelf !== undefined &&\n node.alignSelf !== \"stretch\" &&\n node.alignSelf !== \"auto\"\n ) {\n return false;\n }\n\n // 親がいない場合(ルートノード)は確定\n if (!parentNode) return true;\n\n // 親の alignItems を取得(VStack/HStack のみ持つ)\n let parentAlignItems: AlignItems | undefined;\n if (parentNode.type === \"vstack\") {\n parentAlignItems = parentNode.alignItems;\n } else if (parentNode.type === \"hstack\") {\n parentAlignItems = parentNode.alignItems;\n }\n\n // VStack(column 方向)の子の場合、交差軸は水平方向\n // alignItems が stretch(デフォルト)なら子は親幅に伸長される\n if (parentNode.type === \"vstack\" || parentNode.type === \"layer\") {\n return parentAlignItems === undefined || parentAlignItems === \"stretch\";\n }\n\n // HStack の子の場合、幅は主軸方向で flex により決まるため確定とみなす\n if (parentNode.type === \"hstack\") {\n return true;\n }\n\n return true;\n}\n\n/**\n * POMNode ツリーを再帰的に走査し、YogaNode ツリーを構築する\n */\nasync function buildPomWithYogaTree(\n node: POMNode,\n parentYoga: YogaNode,\n ctx: BuildContext,\n map: YogaNodeMap,\n parentNode?: POMNode,\n grandparentNode?: POMNode,\n) {\n const yoga = await getYoga();\n\n const yn = yoga.Node.create();\n map.set(node, yn); // 対応する YogaNode をマップに登録\n\n await applyStyleToYogaNode(node, yn, ctx);\n\n // HStack/VStack の子要素に flexShrink=1 をデフォルト設定(CSS Flexbox と同じ挙動)\n // 主軸方向で %サイズ + gap がある場合の overflow を防ぐ\n // アイコンは固定サイズのコンテンツなので shrink させない\n if (parentNode?.type === \"hstack\" || parentNode?.type === \"vstack\") {\n yn.setFlexShrink(node.type === \"icon\" ? 0 : 1);\n }\n\n // HStack の子要素で幅が指定されていない場合、grow の比率で余白を配分\n // (grow 未指定は 1 として扱い均等分割)\n // テーブルは setMeasureFunc でカラム幅合計を返すため除外\n // アイコンは固定サイズのコンテンツなので除外\n if (\n parentNode?.type === \"hstack\" &&\n node.w === undefined &&\n node.type !== \"table\" &&\n node.type !== \"icon\"\n ) {\n yn.setFlexGrow(node.grow ?? 1);\n // HStack が確定幅を持つ場合のみ flexBasis=0 で均等分割\n // HStack が auto-sized(親の alignItems が center/start/end 等)の場合、\n // flexBasis=0 だと子要素の自然な幅が失われてレイアウトが崩れるため、\n // flexBasis=auto(デフォルト)のまま維持する\n if (nodeHasDefiniteWidth(parentNode, grandparentNode)) {\n yn.setFlexBasis(0);\n }\n }\n\n parentYoga.insertChild(yn, parentYoga.getChildCount());\n\n const def = getNodeDef(node.type);\n\n switch (def.category) {\n case \"multi-child\":\n case \"absolute-child\": {\n const containerNode = node as Extract<\n POMNode,\n { type: \"vstack\" | \"hstack\" | \"layer\" }\n >;\n for (const child of containerNode.children) {\n await buildPomWithYogaTree(child, yn, ctx, map, node, parentNode);\n }\n break;\n }\n case \"leaf\":\n // 子要素なし\n break;\n }\n}\n\n/**\n * node のスタイルを YogaNode に適用する\n */\nasync function applyStyleToYogaNode(\n node: POMNode,\n yn: YogaNode,\n ctx: BuildContext,\n) {\n const yoga = await getYoga();\n\n // デフォルト: 縦並び\n yn.setFlexDirection(yoga.FLEX_DIRECTION_COLUMN);\n\n // width\n if (node.w !== undefined) {\n if (typeof node.w === \"number\") {\n yn.setWidth(node.w);\n } else if (node.w === \"max\") {\n yn.setFlexGrow(1);\n } else if (node.w.endsWith(\"%\")) {\n const percent = parseFloat(node.w);\n yn.setWidthPercent(percent);\n }\n }\n\n // height\n if (node.h !== undefined) {\n if (typeof node.h === \"number\") {\n yn.setHeight(node.h);\n } else if (node.h === \"max\") {\n yn.setFlexGrow(1);\n } else if (node.h.endsWith(\"%\")) {\n const percent = parseFloat(node.h);\n yn.setHeightPercent(percent);\n }\n }\n\n // flex-grow(w=\"max\" / h=\"max\" の setFlexGrow(1) より優先)\n if (node.grow !== undefined) {\n yn.setFlexGrow(node.grow);\n }\n\n // min/max constraints\n if (node.minW !== undefined) {\n yn.setMinWidth(node.minW);\n }\n if (node.maxW !== undefined) {\n yn.setMaxWidth(node.maxW);\n }\n if (node.minH !== undefined) {\n yn.setMinHeight(node.minH);\n }\n if (node.maxH !== undefined) {\n yn.setMaxHeight(node.maxH);\n }\n\n // padding\n if (node.padding !== undefined) {\n if (typeof node.padding === \"number\") {\n yn.setPadding(yoga.EDGE_TOP, node.padding);\n yn.setPadding(yoga.EDGE_RIGHT, node.padding);\n yn.setPadding(yoga.EDGE_BOTTOM, node.padding);\n yn.setPadding(yoga.EDGE_LEFT, node.padding);\n } else {\n if (node.padding.top !== undefined) {\n yn.setPadding(yoga.EDGE_TOP, node.padding.top);\n }\n if (node.padding.right !== undefined) {\n yn.setPadding(yoga.EDGE_RIGHT, node.padding.right);\n }\n if (node.padding.bottom !== undefined) {\n yn.setPadding(yoga.EDGE_BOTTOM, node.padding.bottom);\n }\n if (node.padding.left !== undefined) {\n yn.setPadding(yoga.EDGE_LEFT, node.padding.left);\n }\n }\n }\n\n // margin\n if (node.margin !== undefined) {\n if (typeof node.margin === \"number\") {\n yn.setMargin(yoga.EDGE_TOP, node.margin);\n yn.setMargin(yoga.EDGE_RIGHT, node.margin);\n yn.setMargin(yoga.EDGE_BOTTOM, node.margin);\n yn.setMargin(yoga.EDGE_LEFT, node.margin);\n } else {\n if (node.margin.top !== undefined) {\n yn.setMargin(yoga.EDGE_TOP, node.margin.top);\n }\n if (node.margin.right !== undefined) {\n yn.setMargin(yoga.EDGE_RIGHT, node.margin.right);\n }\n if (node.margin.bottom !== undefined) {\n yn.setMargin(yoga.EDGE_BOTTOM, node.margin.bottom);\n }\n if (node.margin.left !== undefined) {\n yn.setMargin(yoga.EDGE_LEFT, node.margin.left);\n }\n }\n }\n\n // position\n if (node.position === \"absolute\") {\n yn.setPositionType(yoga.POSITION_TYPE_ABSOLUTE);\n }\n if (node.top !== undefined) {\n yn.setPosition(yoga.EDGE_TOP, node.top);\n }\n if (node.right !== undefined) {\n yn.setPosition(yoga.EDGE_RIGHT, node.right);\n }\n if (node.bottom !== undefined) {\n yn.setPosition(yoga.EDGE_BOTTOM, node.bottom);\n }\n if (node.left !== undefined) {\n yn.setPosition(yoga.EDGE_LEFT, node.left);\n }\n\n // alignSelf\n if (node.alignSelf !== undefined) {\n switch (node.alignSelf) {\n case \"auto\":\n yn.setAlignSelf(yoga.ALIGN_AUTO);\n break;\n case \"start\":\n yn.setAlignSelf(yoga.ALIGN_FLEX_START);\n break;\n case \"center\":\n yn.setAlignSelf(yoga.ALIGN_CENTER);\n break;\n case \"end\":\n yn.setAlignSelf(yoga.ALIGN_FLEX_END);\n break;\n case \"stretch\":\n yn.setAlignSelf(yoga.ALIGN_STRETCH);\n break;\n }\n }\n\n // ノード固有のスタイル適用(measureFunc 等)\n const def = getNodeDef(node.type);\n if (def.applyYogaStyle) {\n await def.applyYogaStyle(node, yn, yoga, ctx);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calcYogaLayout.js","names":[],"sources":["../../src/calcYogaLayout/calcYogaLayout.ts"],"sourcesContent":["import type { POMNode, AlignItems } from \"../types.ts\";\nimport type { BuildContext } from \"../buildContext.ts\";\nimport type { YogaNodeMap } from \"./types.ts\";\nimport { Node as YogaNode } from \"yoga-layout\";\nimport { loadYoga } from \"yoga-layout/load\";\nimport { prefetchImageSize } from \"../shared/measureImage.ts\";\nimport { freeYogaTree } from \"../shared/freeYogaTree.ts\";\nimport { resolveBoxSpacing } from \"../shared/boxSpacing.ts\";\nimport { getNodeDef } from \"../registry/index.ts\";\n\n/**\n * POMNode ツリーを Yoga でレイアウト計算する\n * POMNode と YogaNode の対応を YogaNodeMap として返す\n *\n * @param root 入力 POMNode ツリーのルート\n * @param slideSize スライド全体のサイズ(px)\n * @param ctx BuildContext\n * @returns YogaNodeMap(POMNode → YogaNode のマッピング)\n */\nexport async function calcYogaLayout(\n root: POMNode,\n slideSize: { w: number; h: number },\n ctx: BuildContext,\n): Promise<YogaNodeMap> {\n const Yoga = await getYoga();\n\n // 事前に全画像のサイズを取得(HTTPS対応のため)\n await prefetchAllImageSizes(root, ctx);\n\n const map: YogaNodeMap = new Map();\n\n try {\n const rootYoga = Yoga.Node.create();\n map.set(root, rootYoga);\n\n await buildPomWithYogaTree(root, rootYoga, ctx, map);\n\n // スライド全体サイズを指定\n rootYoga.setWidth(slideSize.w);\n rootYoga.setHeight(slideSize.h);\n\n rootYoga.calculateLayout(slideSize.w, slideSize.h, Yoga.DIRECTION_LTR);\n } catch (e) {\n // 途中で失敗した場合、作成済みの YogaNode を解放してから再 throw\n freeYogaTree(map);\n throw e;\n }\n\n return map;\n}\n\n/**\n * POMNode ツリー内のすべての画像のサイズを事前取得する\n */\nasync function prefetchAllImageSizes(\n node: POMNode,\n ctx: BuildContext,\n): Promise<void> {\n const imageSources = collectImageSources(node);\n await Promise.all(\n imageSources.map((src) =>\n prefetchImageSize(\n src,\n ctx.imageSizeCache,\n ctx.imageDataCache,\n ctx.diagnostics,\n ),\n ),\n );\n}\n\n/**\n * POMNode ツリー内のすべての画像のsrcを収集する\n */\nfunction collectImageSources(node: POMNode): string[] {\n const sources: string[] = [];\n\n function traverse(n: POMNode) {\n // backgroundImage の src を収集(全ノード共通)\n if (n.backgroundImage) {\n sources.push(n.backgroundImage.src);\n }\n\n const def = getNodeDef(n.type);\n\n // ノード固有の画像ソース収集\n if (def.collectImageSources) {\n sources.push(...def.collectImageSources(n));\n }\n\n // 子要素の再帰\n if (def.category === \"multi-child\" || def.category === \"absolute-child\") {\n const containerNode = n as Extract<\n POMNode,\n { type: \"vstack\" | \"hstack\" | \"layer\" }\n >;\n for (const child of containerNode.children) {\n traverse(child);\n }\n }\n }\n\n traverse(node);\n return sources;\n}\n\n/**\n * Yogaシングルトン\n */\nlet yogaP: Promise<Yoga> | null = null;\ntype Yoga = Awaited<ReturnType<typeof loadYoga>>;\nasync function getYoga(): Promise<Yoga> {\n if (yogaP === null) yogaP = loadYoga();\n return yogaP;\n}\n\n/**\n * ノードが交差軸方向(幅)で確定サイズを持つかを判定する\n * - 明示的な w がある場合は確定\n * - alignSelf で stretch 以外が指定されている場合は不確定\n * - 親の alignItems で stretch(デフォルト)以外が指定されている場合は不確定\n */\nfunction nodeHasDefiniteWidth(node: POMNode, parentNode?: POMNode): boolean {\n // 明示的な幅がある\n if (node.w !== undefined) return true;\n\n // alignSelf で stretch 以外が明示されている場合は不確定\n if (\n node.alignSelf !== undefined &&\n node.alignSelf !== \"stretch\" &&\n node.alignSelf !== \"auto\"\n ) {\n return false;\n }\n\n // 親がいない場合(ルートノード)は確定\n if (!parentNode) return true;\n\n // 親の alignItems を取得(VStack/HStack のみ持つ)\n let parentAlignItems: AlignItems | undefined;\n if (parentNode.type === \"vstack\") {\n parentAlignItems = parentNode.alignItems;\n } else if (parentNode.type === \"hstack\") {\n parentAlignItems = parentNode.alignItems;\n }\n\n // VStack(column 方向)の子の場合、交差軸は水平方向\n // alignItems が stretch(デフォルト)なら子は親幅に伸長される\n if (parentNode.type === \"vstack\" || parentNode.type === \"layer\") {\n return parentAlignItems === undefined || parentAlignItems === \"stretch\";\n }\n\n // HStack の子の場合、幅は主軸方向で flex により決まるため確定とみなす\n if (parentNode.type === \"hstack\") {\n return true;\n }\n\n return true;\n}\n\n/**\n * POMNode ツリーを再帰的に走査し、YogaNode ツリーを構築する\n */\nasync function buildPomWithYogaTree(\n node: POMNode,\n parentYoga: YogaNode,\n ctx: BuildContext,\n map: YogaNodeMap,\n parentNode?: POMNode,\n grandparentNode?: POMNode,\n) {\n const yoga = await getYoga();\n\n const yn = yoga.Node.create();\n map.set(node, yn); // 対応する YogaNode をマップに登録\n\n await applyStyleToYogaNode(node, yn, ctx);\n\n // HStack/VStack の子要素に flexShrink=1 をデフォルト設定(CSS Flexbox と同じ挙動)\n // 主軸方向で %サイズ + gap がある場合の overflow を防ぐ\n // アイコンは固定サイズのコンテンツなので shrink させない\n if (parentNode?.type === \"hstack\" || parentNode?.type === \"vstack\") {\n yn.setFlexShrink(node.type === \"icon\" ? 0 : 1);\n }\n\n // HStack の子要素で幅が指定されていない場合、grow の比率で余白を配分\n // (grow 未指定は 1 として扱い均等分割)\n // テーブルは setMeasureFunc でカラム幅合計を返すため除外\n // アイコンは固定サイズのコンテンツなので除外\n if (\n parentNode?.type === \"hstack\" &&\n node.w === undefined &&\n node.type !== \"table\" &&\n node.type !== \"icon\"\n ) {\n yn.setFlexGrow(node.grow ?? 1);\n // HStack が確定幅を持つ場合のみ flexBasis=0 で均等分割\n // HStack が auto-sized(親の alignItems が center/start/end 等)の場合、\n // flexBasis=0 だと子要素の自然な幅が失われてレイアウトが崩れるため、\n // flexBasis=auto(デフォルト)のまま維持する\n if (nodeHasDefiniteWidth(parentNode, grandparentNode)) {\n yn.setFlexBasis(0);\n }\n }\n\n parentYoga.insertChild(yn, parentYoga.getChildCount());\n\n const def = getNodeDef(node.type);\n\n switch (def.category) {\n case \"multi-child\":\n case \"absolute-child\": {\n const containerNode = node as Extract<\n POMNode,\n { type: \"vstack\" | \"hstack\" | \"layer\" }\n >;\n for (const child of containerNode.children) {\n await buildPomWithYogaTree(child, yn, ctx, map, node, parentNode);\n }\n break;\n }\n case \"leaf\":\n // 子要素なし\n break;\n }\n}\n\n/**\n * node のスタイルを YogaNode に適用する\n */\nasync function applyStyleToYogaNode(\n node: POMNode,\n yn: YogaNode,\n ctx: BuildContext,\n) {\n const yoga = await getYoga();\n\n // デフォルト: 縦並び\n yn.setFlexDirection(yoga.FLEX_DIRECTION_COLUMN);\n\n // width\n if (node.w !== undefined) {\n if (typeof node.w === \"number\") {\n yn.setWidth(node.w);\n } else if (node.w === \"max\") {\n yn.setFlexGrow(1);\n } else if (node.w.endsWith(\"%\")) {\n const percent = parseFloat(node.w);\n yn.setWidthPercent(percent);\n }\n }\n\n // height\n if (node.h !== undefined) {\n if (typeof node.h === \"number\") {\n yn.setHeight(node.h);\n } else if (node.h === \"max\") {\n yn.setFlexGrow(1);\n } else if (node.h.endsWith(\"%\")) {\n const percent = parseFloat(node.h);\n yn.setHeightPercent(percent);\n }\n }\n\n // flex-grow(w=\"max\" / h=\"max\" の setFlexGrow(1) より優先)\n if (node.grow !== undefined) {\n yn.setFlexGrow(node.grow);\n }\n\n // min/max constraints\n if (node.minW !== undefined) {\n yn.setMinWidth(node.minW);\n }\n if (node.maxW !== undefined) {\n yn.setMaxWidth(node.maxW);\n }\n if (node.minH !== undefined) {\n yn.setMinHeight(node.minH);\n }\n if (node.maxH !== undefined) {\n yn.setMaxHeight(node.maxH);\n }\n\n // padding(yoga の未設定 edge は 0 扱いのため、解決済みの 0 を明示設定しても等価)\n if (node.padding !== undefined) {\n const padding = resolveBoxSpacing(node.padding);\n yn.setPadding(yoga.EDGE_TOP, padding.top);\n yn.setPadding(yoga.EDGE_RIGHT, padding.right);\n yn.setPadding(yoga.EDGE_BOTTOM, padding.bottom);\n yn.setPadding(yoga.EDGE_LEFT, padding.left);\n }\n\n // margin\n if (node.margin !== undefined) {\n const margin = resolveBoxSpacing(node.margin);\n yn.setMargin(yoga.EDGE_TOP, margin.top);\n yn.setMargin(yoga.EDGE_RIGHT, margin.right);\n yn.setMargin(yoga.EDGE_BOTTOM, margin.bottom);\n yn.setMargin(yoga.EDGE_LEFT, margin.left);\n }\n\n // position\n if (node.position === \"absolute\") {\n yn.setPositionType(yoga.POSITION_TYPE_ABSOLUTE);\n }\n if (node.top !== undefined) {\n yn.setPosition(yoga.EDGE_TOP, node.top);\n }\n if (node.right !== undefined) {\n yn.setPosition(yoga.EDGE_RIGHT, node.right);\n }\n if (node.bottom !== undefined) {\n yn.setPosition(yoga.EDGE_BOTTOM, node.bottom);\n }\n if (node.left !== undefined) {\n yn.setPosition(yoga.EDGE_LEFT, node.left);\n }\n\n // alignSelf\n if (node.alignSelf !== undefined) {\n switch (node.alignSelf) {\n case \"auto\":\n yn.setAlignSelf(yoga.ALIGN_AUTO);\n break;\n case \"start\":\n yn.setAlignSelf(yoga.ALIGN_FLEX_START);\n break;\n case \"center\":\n yn.setAlignSelf(yoga.ALIGN_CENTER);\n break;\n case \"end\":\n yn.setAlignSelf(yoga.ALIGN_FLEX_END);\n break;\n case \"stretch\":\n yn.setAlignSelf(yoga.ALIGN_STRETCH);\n break;\n }\n }\n\n // ノード固有のスタイル適用(measureFunc 等)\n const def = getNodeDef(node.type);\n if (def.applyYogaStyle) {\n await def.applyYogaStyle(node, yn, yoga, ctx);\n }\n}\n"],"mappings":"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"}
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/diagnostics.d.ts
|
|
2
|
-
type DiagnosticCode = "IMAGE_MEASURE_FAILED" | "IMAGE_NOT_PREFETCHED" | "AUTOFIT_OVERFLOW" | "SCALE_BELOW_THRESHOLD" | "MASTER_PPTX_PARSE_FAILED" | "ARROW_REF_NOT_FOUND" | "DUPLICATE_NODE_ID";
|
|
2
|
+
type DiagnosticCode = "IMAGE_MEASURE_FAILED" | "IMAGE_NOT_PREFETCHED" | "AUTOFIT_OVERFLOW" | "SCALE_BELOW_THRESHOLD" | "MASTER_PPTX_PARSE_FAILED" | "ARROW_REF_NOT_FOUND" | "DUPLICATE_NODE_ID" | "PER_SIDE_BORDER_WITH_RADIUS";
|
|
3
3
|
interface Diagnostic {
|
|
4
4
|
code: DiagnosticCode;
|
|
5
5
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","names":[],"sources":["../src/diagnostics.ts"],"mappings":";KAAY,cAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","names":[],"sources":["../src/diagnostics.ts"],"mappings":";KAAY,cAAA;AAAA,UAUK,UAAA;EACf,IAAA,EAAM,cAAc;EACpB,OAAA;AAAA;AAAA,cAWW,gBAAA,SAAyB,KAAA;EAAA,SACR,WAAA,EAAa,UAAA;cAAb,WAAA,EAAa,UAAA;AAAA"}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","names":[],"sources":["../src/diagnostics.ts"],"sourcesContent":["export type DiagnosticCode =\n | \"IMAGE_MEASURE_FAILED\"\n | \"IMAGE_NOT_PREFETCHED\"\n | \"AUTOFIT_OVERFLOW\"\n | \"SCALE_BELOW_THRESHOLD\"\n | \"MASTER_PPTX_PARSE_FAILED\"\n | \"ARROW_REF_NOT_FOUND\"\n | \"DUPLICATE_NODE_ID\";\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n message: string;\n}\n\nexport class DiagnosticCollector {\n readonly items: Diagnostic[] = [];\n\n add(code: DiagnosticCode, message: string): void {\n this.items.push({ code, message });\n }\n}\n\nexport class DiagnosticsError extends Error {\n constructor(public readonly diagnostics: Diagnostic[]) {\n const summary = diagnostics\n .map((d) => `[${d.code}] ${d.message}`)\n .join(\"\\n\");\n super(`Build completed with diagnostics:\\n${summary}`);\n this.name = \"DiagnosticsError\";\n }\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"diagnostics.js","names":[],"sources":["../src/diagnostics.ts"],"sourcesContent":["export type DiagnosticCode =\n | \"IMAGE_MEASURE_FAILED\"\n | \"IMAGE_NOT_PREFETCHED\"\n | \"AUTOFIT_OVERFLOW\"\n | \"SCALE_BELOW_THRESHOLD\"\n | \"MASTER_PPTX_PARSE_FAILED\"\n | \"ARROW_REF_NOT_FOUND\"\n | \"DUPLICATE_NODE_ID\"\n | \"PER_SIDE_BORDER_WITH_RADIUS\";\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n message: string;\n}\n\nexport class DiagnosticCollector {\n readonly items: Diagnostic[] = [];\n\n add(code: DiagnosticCode, message: string): void {\n this.items.push({ code, message });\n }\n}\n\nexport class DiagnosticsError extends Error {\n constructor(public readonly diagnostics: Diagnostic[]) {\n const summary = diagnostics\n .map((d) => `[${d.code}] ${d.message}`)\n .join(\"\\n\");\n super(`Build completed with diagnostics:\\n${summary}`);\n this.name = \"DiagnosticsError\";\n }\n}\n"],"mappings":";AAeA,IAAa,sBAAb,MAAiC;CAC/B,QAA+B,CAAC;CAEhC,IAAI,MAAsB,SAAuB;EAC/C,KAAK,MAAM,KAAK;GAAE;GAAM;EAAQ,CAAC;CACnC;AACF;AAEA,IAAa,mBAAb,cAAsC,MAAM;CACd;CAA5B,YAAY,aAA2C;EACrD,MAAM,UAAU,YACb,KAAK,MAAM,IAAI,EAAE,KAAK,IAAI,EAAE,SAAS,CAAC,CACtC,KAAK,IAAI;EACZ,MAAM,sCAAsC,SAAS;EAJ3B,KAAA,cAAA;EAK1B,KAAK,OAAO;CACd;AACF"}
|
|
@@ -204,6 +204,21 @@ const UNDERLINE_RULE = {
|
|
|
204
204
|
}
|
|
205
205
|
}]
|
|
206
206
|
};
|
|
207
|
+
const TEXT_GLOW_RULE = {
|
|
208
|
+
type: "object",
|
|
209
|
+
shape: {
|
|
210
|
+
size: "number",
|
|
211
|
+
opacity: "number",
|
|
212
|
+
color: "string"
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const TEXT_OUTLINE_RULE = {
|
|
216
|
+
type: "object",
|
|
217
|
+
shape: {
|
|
218
|
+
size: "number",
|
|
219
|
+
color: "string"
|
|
220
|
+
}
|
|
221
|
+
};
|
|
207
222
|
const LINE_ARROW_RULE = {
|
|
208
223
|
type: "union",
|
|
209
224
|
options: ["boolean", {
|
|
@@ -230,7 +245,8 @@ const FLOW_CONNECTOR_STYLE_RULE = {
|
|
|
230
245
|
shape: {
|
|
231
246
|
color: "string",
|
|
232
247
|
width: "number",
|
|
233
|
-
arrowType: "string"
|
|
248
|
+
arrowType: "string",
|
|
249
|
+
labelColor: "string"
|
|
234
250
|
}
|
|
235
251
|
};
|
|
236
252
|
const IMAGE_SIZING_RULE = {
|
|
@@ -258,6 +274,10 @@ const BASE_RULES = {
|
|
|
258
274
|
backgroundGradient: "string",
|
|
259
275
|
backgroundImage: BACKGROUND_IMAGE_RULE,
|
|
260
276
|
border: BORDER_STYLE_RULE,
|
|
277
|
+
borderTop: BORDER_STYLE_RULE,
|
|
278
|
+
borderRight: BORDER_STYLE_RULE,
|
|
279
|
+
borderBottom: BORDER_STYLE_RULE,
|
|
280
|
+
borderLeft: BORDER_STYLE_RULE,
|
|
261
281
|
borderRadius: "number",
|
|
262
282
|
opacity: "number",
|
|
263
283
|
zIndex: "number",
|
|
@@ -285,8 +305,11 @@ const NODE_COERCION_MAP = {
|
|
|
285
305
|
text: {
|
|
286
306
|
...BASE_RULES,
|
|
287
307
|
text: "string",
|
|
308
|
+
rotate: "number",
|
|
288
309
|
...TEXT_STYLE_RULES,
|
|
289
|
-
letterSpacing: "number"
|
|
310
|
+
letterSpacing: "number",
|
|
311
|
+
glow: TEXT_GLOW_RULE,
|
|
312
|
+
outline: TEXT_OUTLINE_RULE
|
|
290
313
|
},
|
|
291
314
|
ul: {
|
|
292
315
|
...BASE_RULES,
|
|
@@ -303,7 +326,8 @@ const NODE_COERCION_MAP = {
|
|
|
303
326
|
image: {
|
|
304
327
|
...BASE_RULES,
|
|
305
328
|
src: "string",
|
|
306
|
-
sizing: IMAGE_SIZING_RULE
|
|
329
|
+
sizing: IMAGE_SIZING_RULE,
|
|
330
|
+
rotate: "number"
|
|
307
331
|
},
|
|
308
332
|
icon: {
|
|
309
333
|
...BASE_RULES,
|
|
@@ -311,7 +335,8 @@ const NODE_COERCION_MAP = {
|
|
|
311
335
|
size: "number",
|
|
312
336
|
color: "string",
|
|
313
337
|
variant: "string",
|
|
314
|
-
bgColor: "string"
|
|
338
|
+
bgColor: "string",
|
|
339
|
+
rotate: "number"
|
|
315
340
|
},
|
|
316
341
|
svg: {
|
|
317
342
|
...BASE_RULES,
|
|
@@ -328,6 +353,7 @@ const NODE_COERCION_MAP = {
|
|
|
328
353
|
...BASE_RULES,
|
|
329
354
|
shapeType: "string",
|
|
330
355
|
text: "string",
|
|
356
|
+
rotate: "number",
|
|
331
357
|
fill: FILL_STYLE_RULE,
|
|
332
358
|
line: BORDER_STYLE_RULE,
|
|
333
359
|
...TEXT_STYLE_RULES
|
|
@@ -345,19 +371,26 @@ const NODE_COERCION_MAP = {
|
|
|
345
371
|
timeline: {
|
|
346
372
|
...BASE_RULES,
|
|
347
373
|
direction: "string",
|
|
348
|
-
items: "json"
|
|
374
|
+
items: "json",
|
|
375
|
+
dateColor: "string",
|
|
376
|
+
titleColor: "string",
|
|
377
|
+
descriptionColor: "string"
|
|
349
378
|
},
|
|
350
379
|
matrix: {
|
|
351
380
|
...BASE_RULES,
|
|
352
381
|
axes: "json",
|
|
353
382
|
quadrants: "json",
|
|
354
|
-
items: "json"
|
|
383
|
+
items: "json",
|
|
384
|
+
axisLabelColor: "string",
|
|
385
|
+
quadrantLabelColor: "string",
|
|
386
|
+
itemLabelColor: "string"
|
|
355
387
|
},
|
|
356
388
|
tree: {
|
|
357
389
|
...BASE_RULES,
|
|
358
390
|
layout: "string",
|
|
359
391
|
nodeShape: "string",
|
|
360
392
|
data: "json",
|
|
393
|
+
textColor: "string",
|
|
361
394
|
connectorStyle: TREE_CONNECTOR_STYLE_RULE,
|
|
362
395
|
nodeWidth: "number",
|
|
363
396
|
nodeHeight: "number",
|
|
@@ -466,7 +499,8 @@ const CHILD_ELEMENT_COERCION_MAP = {
|
|
|
466
499
|
label: "string",
|
|
467
500
|
x: "number",
|
|
468
501
|
y: "number",
|
|
469
|
-
color: "string"
|
|
502
|
+
color: "string",
|
|
503
|
+
textColor: "string"
|
|
470
504
|
},
|
|
471
505
|
FlowNode: {
|
|
472
506
|
id: "string",
|
|
@@ -481,7 +515,8 @@ const CHILD_ELEMENT_COERCION_MAP = {
|
|
|
481
515
|
from: "string",
|
|
482
516
|
to: "string",
|
|
483
517
|
label: "string",
|
|
484
|
-
color: "string"
|
|
518
|
+
color: "string",
|
|
519
|
+
labelColor: "string"
|
|
485
520
|
},
|
|
486
521
|
Col: { width: "number" },
|
|
487
522
|
Td: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", arrowType: \"string\" },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n ...TEXT_STYLE_RULES,\n letterSpacing: \"number\",\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: { color: \"string\", fontFamily: \"string\", letterSpacing: \"number\" },\n};\n"],"mappings":";AAmBA,SAAgB,eACd,OACA,MAC0C;CAC1C,IAAI,SAAS,UAAU;EACrB,IAAI,UAAU,IACZ,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,MAAM,MAAM,OAAO,KAAK;EACxB,IAAI,MAAM,GAAG,GACX,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,OAAO;GAAE,OAAO;GAAK,OAAO;EAAK;CACnC;CACA,IAAI,SAAS,WAAW;EACtB,IAAI,UAAU,UAAU,UAAU,SAChC,OAAO;GACL,OAAO,KAAA;GACP,OAAO,mBAAmB,MAAM;EAClC;EAEF,OAAO;GAAE,OAAO,UAAU;GAAQ,OAAO;EAAK;CAChD;CACA,IAAI,SAAS,UACX,OAAO;EAAE;EAAO,OAAO;CAAK;CAE9B,IAAI,SAAS,QACX,IAAI;EACF,OAAO;GAAE,OAAO,KAAK,MAAM,KAAK;GAAG,OAAO;EAAK;CACjD,QAAQ;EACN,OAAO;GACL,OAAO,KAAA;GACP,OAAO,6BAA6B,MAAM;EAC5C;CACF;CAGF,IAAI,KAAK,SAAS,WAChB,OAAO;EAAE,OAAO,KAAK;EAAO,OAAO;CAAK;CAE1C,IAAI,KAAK,SAAS,SAChB,OAAO;EAAE,OAAO,qBAAqB,OAAO,KAAK,OAAO;EAAG,OAAO;CAAK;CAEzE,IAAI,KAAK,SAAS,UAChB,IAAI;EACF,OAAO;GAAE,OAAO,KAAK,MAAM,KAAK;GAAG,OAAO;EAAK;CACjD,QAAQ;EACN,OAAO;GACL,OAAO,KAAA;GACP,OAAO,6BAA6B,MAAM;EAC5C;CACF;CAEF,OAAO;EAAE,OAAO,eAAe,KAAK;EAAG,OAAO;CAAK;AACrD;AAEA,SAAgB,qBACd,OACA,SACS;CAET,KAAK,UAAU,UAAU,UAAU,YAAY,QAAQ,SAAS,SAAS,GACvE,OAAO,UAAU;CAInB,IAAI,QAAQ,SAAS,QAAQ,GAAG;EAC9B,MAAM,MAAM,OAAO,KAAK;EACxB,IAAI,CAAC,MAAM,GAAG,KAAK,UAAU,IAC3B,OAAO;CAEX;CAGA,KAAK,MAAM,OAAO,SAChB,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS;MACtC,GAAG,IAAI,YAA+B,OAAO,OAAO,IAAI;CAAA;CAKhE,IACE,QAAQ,MACL,QACC,QAAQ,UAAW,OAAO,QAAQ,YAAY,IAAI,SAAS,QAC/D;MAEI,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,GAC/C,IAAI;GACF,OAAO,KAAK,MAAM,KAAK;EACzB,QAAQ,CAER;;CAKJ,OAAO;AACT;AAEA,SAAgB,eAAe,OAAwB;CACrD,IAAI,UAAU,QAAQ,OAAO;CAC7B,IAAI,UAAU,SAAS,OAAO;CAC9B,MAAM,MAAM,OAAO,KAAK;CACxB,IAAI,UAAU,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO;CACxC,IAAI,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,GAC/C,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ,CAER;CAEF,OAAO;AACT;;;;;AAMA,SAAgB,uBACd,MAC0C;CAC1C,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,UAC5C,OAAO,KAAK;CAEd,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,SAK5C,OAJkB,KAAK,QAAQ,MAC5B,QACC,OAAO,QAAQ,YAAY,IAAI,SAAS,QAE7B,CAAC,EAAE;AAGtB;;;;;AAMA,SAAgB,yBAAyB,MAA6B;CACpE,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,IAAI,KAAK,SAAS,SAAS,OAAO;CAClC,MAAM,aAAa,KAAK,QAAQ,SAAS,SAAS;CAClD,MAAM,YAAY,KAAK,QAAQ,MAC5B,QAAQ,OAAO,QAAQ,YAAY,IAAI,SAAS,QACnD;CACA,OAAO,cAAc;AACvB;AAOA,SAAS,cAAc,OAAkD;CACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,sBAAsB,OAA8C;CAC3E,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK;CACrC,OACE,KAAK,WAAW,KAChB,KAAK,OAAO,YACZ,KAAK,OAAO,UACZ,KAAK,OAAO,WACZ,KAAK,OAAO;AAEhB;;;;;;;;;AAUA,SAAgB,8BACd,OACA,MACgC;CAChC,MAAM,cAAc,uBAAuB,IAAI;CAC/C,IAAI,CAAC,aAAa,OAAO,EAAE,MAAM,WAAW;CAE5C,IACE,yBAAyB,IAAI,MAC5B,UAAU,UAAU,UAAU,UAE/B,OAAO,EAAE,MAAM,SAAS;CAG1B,MAAM,UAAU,eAAe,OAAO,IAAI;CAC1C,IAAI,QAAQ,UAAU,MAAM,OAAO,EAAE,MAAM,WAAW;CAEtD,IAAI,cAAc,QAAQ,KAAK,GAC7B,OAAO;EAAE,MAAM;EAAS,OAAO,QAAQ;CAAM;CAG/C,IAAI,OAAO,QAAQ,UAAU,YAAY,sBAAsB,WAAW,GACxE,OAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,QAAQ;GACb,OAAO,QAAQ;GACf,QAAQ,QAAQ;GAChB,MAAM,QAAQ;EAChB;CACF;CAGF,OAAO,EAAE,MAAM,WAAW;AAC5B;AAIA,MAAM,cAA4B;CAChC,MAAM;CACN,SAAS;EAAC;EAAU;GAAE,MAAM;GAAW,OAAO;EAAM;EAAG;CAAQ;AACjE;AAEA,MAAM,eAA6B;CACjC,MAAM;CACN,SAAS,CACP,UACA;EACE,MAAM;EACN,OAAO;GACL,KAAK;GACL,OAAO;GACP,QAAQ;GACR,MAAM;EACR;CACF,CACF;AACF;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,OAAO;EAAU,UAAU;CAAS;AAChE;AAEA,MAAM,kBAAgC;CACpC,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,cAAc;CAAS;AACnD;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM;EACN,OAAO;EACP,QAAQ;EACR,OAAO;CACT;AACF;AAEA,MAAM,iBAA+B;CACnC,MAAM;CACN,SAAS,CACP,WACA;EAAE,MAAM;EAAU,OAAO;GAAE,OAAO;GAAU,OAAO;EAAS;CAAE,CAChE;AACF;AAEA,MAAM,kBAAgC;CACpC,MAAM;CACN,SAAS,CAAC,WAAW;EAAE,MAAM;EAAU,OAAO,EAAE,MAAM,SAAS;CAAE,CAAC;AACpE;AAEA,MAAM,wBAAsC;CAC1C,MAAM;CACN,OAAO;EAAE,KAAK;EAAU,QAAQ;CAAS;AAC3C;AAEA,MAAM,4BAA0C;CAC9C,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,OAAO;CAAS;AAC5C;AAEA,MAAM,4BAA0C;CAC9C,MAAM;CACN,OAAO;EAAE,OAAO;EAAU,OAAO;EAAU,WAAW;CAAS;AACjE;AAEA,MAAM,oBAAkC;CACtC,MAAM;CACN,OAAO;EACL,MAAM;EACN,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;CACL;AACF;AAGA,MAAM,aAA2C;CAC/C,IAAI;CACJ,GAAG;CACH,GAAG;CACH,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,SAAS;CACT,QAAQ;CACR,iBAAiB;CACjB,oBAAoB;CACpB,iBAAiB;CACjB,QAAQ;CACR,cAAc;CACd,SAAS;CACT,QAAQ;CACR,UAAU;CACV,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;CACN,WAAW;CACX,QAAQ;AACV;AAGA,MAAM,mBAAiD;CACrD,UAAU;CACV,OAAO;CACP,WAAW;CACX,MAAM;CACN,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,YAAY;AACd;AAGA,MAAa,oBAAkE;CAC7E,MAAM;EACJ,GAAG;EACH,MAAM;EACN,GAAG;EACH,eAAe;CACjB;CACA,IAAI;EACF,GAAG;EACH,OAAO;EACP,GAAG;CACL;CACA,IAAI;EACF,GAAG;EACH,OAAO;EACP,GAAG;EACH,YAAY;EACZ,eAAe;CACjB;CACA,OAAO;EACL,GAAG;EACH,KAAK;EACL,QAAQ;CACV;CACA,MAAM;EACJ,GAAG;EACH,MAAM;EACN,MAAM;EACN,OAAO;EACP,SAAS;EACT,SAAS;CACX;CACA,KAAK;EACH,GAAG;EACH,OAAO;CACT;CACA,OAAO;EACL,GAAG;EACH,SAAS;EACT,MAAM;EACN,kBAAkB;EAClB,YAAY;CACd;CACA,OAAO;EACL,GAAG;EACH,WAAW;EACX,MAAM;EACN,MAAM;EACN,MAAM;EACN,GAAG;CACL;CACA,OAAO;EACL,GAAG;EACH,WAAW;EACX,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,aAAa;EACb,YAAY;CACd;CACA,UAAU;EACR,GAAG;EACH,WAAW;EACX,OAAO;CACT;CACA,QAAQ;EACN,GAAG;EACH,MAAM;EACN,WAAW;EACX,OAAO;CACT;CACA,MAAM;EACJ,GAAG;EACH,QAAQ;EACR,WAAW;EACX,MAAM;EACN,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,UAAU;EACV,YAAY;CACd;CACA,MAAM;EACJ,GAAG;EACH,WAAW;EACX,OAAO;EACP,aAAa;EACb,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,SAAS;CACX;CACA,cAAc;EACZ,GAAG;EACH,WAAW;EACX,OAAO;EACP,WAAW;EACX,YAAY;EACZ,KAAK;EACL,UAAU;EACV,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,YAAY;CACd;CACA,SAAS;EACP,GAAG;EACH,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM;EACN,YAAY;CACd;CACA,MAAM;EACJ,GAAG;EACH,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,OAAO;EACP,WAAW;EACX,UAAU;EACV,YAAY;EACZ,UAAU;CACZ;CACA,OAAO;EACL,GAAG;EACH,MAAM;EACN,IAAI;EACJ,OAAO;EACP,WAAW;EACX,UAAU;EACV,YAAY;EACZ,UAAU;CACZ;CAEA,QAAQ;EACN,GAAG;EACH,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,UAAU;CACZ;CACA,QAAQ;EACN,GAAG;EACH,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,UAAU;CACZ;CACA,OAAO,EACL,GAAG,WACL;AACF;AAGA,MAAa,6BAGT;CACF,kBAAkB;EAChB,OAAO;EACP,OAAO;EACP,WAAW;CACb;CACA,cAAc;EACZ,OAAO;EACP,OAAO;EACP,WAAW;CACb;CACA,cAAc;EACZ,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;CACT;CACA,YAAY;EACV,GAAG;EACH,GAAG;CACL;CACA,iBAAiB;EACf,SAAS;EACT,UAAU;EACV,YAAY;EACZ,aAAa;CACf;CACA,YAAY;EACV,OAAO;EACP,GAAG;EACH,GAAG;EACH,OAAO;CACT;CACA,UAAU;EACR,IAAI;EACJ,OAAO;EACP,MAAM;EACN,OAAO;EACP,WAAW;EACX,OAAO;EACP,QAAQ;CACV;CACA,gBAAgB;EACd,MAAM;EACN,IAAI;EACJ,OAAO;EACP,OAAO;CACT;CACA,KAAK,EACH,OAAO,SACT;CACA,IAAI;EACF,MAAM;EACN,UAAU;EACV,OAAO;EACP,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,YAAY;EACZ,WAAW;EACX,iBAAiB;EACjB,SAAS;EACT,SAAS;CACX;CACA,IAAI;EACF,MAAM;EACN,MAAM;EACN,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,WAAW;EACX,OAAO;EACP,UAAU;EACV,YAAY;CACd;CACA,GAAG,CAAC;CACJ,GAAG,CAAC;CACJ,MAAM;EAAE,OAAO;EAAU,YAAY;EAAU,eAAe;CAAS;AACzE"}
|
|
1
|
+
{"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst TEXT_GLOW_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", opacity: \"number\", color: \"string\" },\n};\n\nconst TEXT_OUTLINE_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", color: \"string\" },\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n color: \"string\",\n width: \"number\",\n arrowType: \"string\",\n labelColor: \"string\",\n },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderTop: BORDER_STYLE_RULE,\n borderRight: BORDER_STYLE_RULE,\n borderBottom: BORDER_STYLE_RULE,\n borderLeft: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n rotate: \"number\",\n ...TEXT_STYLE_RULES,\n letterSpacing: \"number\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n rotate: \"number\",\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n rotate: \"number\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n rotate: \"number\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n dateColor: \"string\",\n titleColor: \"string\",\n descriptionColor: \"string\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n axisLabelColor: \"string\",\n quadrantLabelColor: \"string\",\n itemLabelColor: \"string\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n textColor: \"string\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n textColor: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n labelColor: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: { color: \"string\", fontFamily: \"string\", letterSpacing: \"number\" },\n};\n"],"mappings":"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"}
|
|
@@ -8,9 +8,14 @@ declare class ParseXmlError extends Error {
|
|
|
8
8
|
/**
|
|
9
9
|
* XML 文字列を POMNode 配列に変換する。
|
|
10
10
|
*
|
|
11
|
-
* 最上位は `<Slide>` 要素のみが許容される。各 `<Slide>` が
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* 最上位は `<Slide>` 要素と `<Theme>` 要素のみが許容される。各 `<Slide>` が
|
|
12
|
+
* 1 つのスライドに対応し、その子要素がスライドのルート POMNode となる。
|
|
13
|
+
* 子要素が複数ある場合は暗黙的に VStack でラップされる。
|
|
14
|
+
*
|
|
15
|
+
* `<Theme>` は文書全体に適用されるデザイントークン(配色)の宣言で、最大 1 つ
|
|
16
|
+
* 置ける。属性名がトークン名、属性値が 6 桁 hex の色値となり、各ノードの色属性
|
|
17
|
+
* から `$トークン名` で参照できる。参照は parse 時に解決されるため、返される
|
|
18
|
+
* POMNode には解決済みの hex 値が入る(`<Theme>` 自体はノードにならない)。
|
|
14
19
|
*
|
|
15
20
|
* XML タグは POM ノードタイプにマッピングされ、属性値は Zod スキーマを参照して
|
|
16
21
|
* 適切な型(number, boolean, array, object)に変換される。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":";;;cAiCa,aAAA,SAAsB,KAAK;EAAA,SACtB,MAAA;cACJ,MAAA;AAAA;;;;;;;AAAgB;AA2sC9B;;;;AAAoD;;;;;;;;;;;;;;;;;;;;;iBAApC,QAAA,CAAS,SAAA,WAAoB,OAAO"}
|