@ubermensch1218/hwpxeditor 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/components/editor/Editor.tsx","../src/lib/store.ts","../src/lib/view-model.ts","../src/lib/hwp-units.ts","../src/lib/image-extractor.ts","../src/lib/format-bridge.ts","../src/lib/skeleton-loader.ts","../src/components/toolbar/ClipboardGroup.tsx","../src/components/toolbar/ToolbarButton.tsx","../src/components/toolbar/RibbonGroup.tsx","../src/components/toolbar/InsertGroup.tsx","../src/components/toolbar/RibbonToolbar.tsx","../src/lib/constants.ts","../src/components/toolbar/ToolbarDropdown.tsx","../src/components/toolbar/StyleSelector.tsx","../src/components/toolbar/FontSelector.tsx","../src/components/toolbar/FontSizeInput.tsx","../src/components/toolbar/CharFormatButtons.tsx","../src/components/toolbar/ColorPicker.tsx","../src/components/toolbar/AlignmentButtons.tsx","../src/components/toolbar/LineSpacingControl.tsx","../src/components/toolbar/ToolbarDivider.tsx","../src/components/toolbar/SecondaryToolbar.tsx","../src/components/ruler/HorizontalRuler.tsx","../src/components/sidebar/SidebarSection.tsx","../src/components/sidebar/SidebarField.tsx","../src/components/sidebar/BorderSettings.tsx","../src/components/sidebar/BackgroundSettings.tsx","../src/components/sidebar/CharFormatPanel.tsx","../src/components/sidebar/ParaFormatPanel.tsx","../src/components/sidebar/FormatSidebar.tsx","../src/components/editor/ParagraphBlock.tsx","../src/components/editor/RunSpan.tsx","../src/components/editor/TableCell.tsx","../src/components/editor/TableBlock.tsx","../src/components/editor/ImageBlock.tsx","../src/components/editor/Page.tsx","../src/components/editor/PageView.tsx","../src/components/upload/FileUpload.tsx","../src/components/upload/NewDocumentButton.tsx"],"sourcesContent":["/**\n * @hwpx/editor — React editor components for HWPX documents.\n *\n * Provides a Korean word processor-style UI with ribbon toolbar,\n * format sidebar, ruler, and full page editing.\n */\n\n// ── Editor components ─────────────────────────────────────────────────────\nexport { Editor } from \"./components/editor/Editor\";\nexport { PageView } from \"./components/editor/PageView\";\nexport { Page } from \"./components/editor/Page\";\nexport { ParagraphBlock } from \"./components/editor/ParagraphBlock\";\nexport { RunSpan } from \"./components/editor/RunSpan\";\nexport { ImageBlock } from \"./components/editor/ImageBlock\";\nexport { TableBlock } from \"./components/editor/TableBlock\";\nexport { TableCell } from \"./components/editor/TableCell\";\n\n// ── Toolbar components ────────────────────────────────────────────────────\nexport { RibbonToolbar } from \"./components/toolbar/RibbonToolbar\";\nexport { SecondaryToolbar } from \"./components/toolbar/SecondaryToolbar\";\nexport { ToolbarButton } from \"./components/toolbar/ToolbarButton\";\nexport { ToolbarDropdown } from \"./components/toolbar/ToolbarDropdown\";\nexport { ToolbarDivider } from \"./components/toolbar/ToolbarDivider\";\nexport { ColorPicker } from \"./components/toolbar/ColorPicker\";\nexport { RibbonGroup } from \"./components/toolbar/RibbonGroup\";\nexport { ClipboardGroup } from \"./components/toolbar/ClipboardGroup\";\nexport { InsertGroup } from \"./components/toolbar/InsertGroup\";\nexport { StyleSelector } from \"./components/toolbar/StyleSelector\";\nexport { FontSelector } from \"./components/toolbar/FontSelector\";\nexport { FontSizeInput } from \"./components/toolbar/FontSizeInput\";\nexport { CharFormatButtons } from \"./components/toolbar/CharFormatButtons\";\nexport { AlignmentButtons } from \"./components/toolbar/AlignmentButtons\";\nexport { LineSpacingControl } from \"./components/toolbar/LineSpacingControl\";\n\n// ── Sidebar components ────────────────────────────────────────────────────\nexport { FormatSidebar } from \"./components/sidebar/FormatSidebar\";\nexport { SidebarSection } from \"./components/sidebar/SidebarSection\";\nexport { SidebarField } from \"./components/sidebar/SidebarField\";\nexport { CharFormatPanel } from \"./components/sidebar/CharFormatPanel\";\nexport { ParaFormatPanel } from \"./components/sidebar/ParaFormatPanel\";\nexport { BorderSettings } from \"./components/sidebar/BorderSettings\";\nexport { BackgroundSettings } from \"./components/sidebar/BackgroundSettings\";\n\n// ── Ruler ─────────────────────────────────────────────────────────────────\nexport { HorizontalRuler } from \"./components/ruler/HorizontalRuler\";\n\n// ── Upload components ─────────────────────────────────────────────────────\nexport { FileUpload } from \"./components/upload/FileUpload\";\nexport { NewDocumentButton } from \"./components/upload/NewDocumentButton\";\n\n// ── Store ─────────────────────────────────────────────────────────────────\nexport { useEditorStore } from \"./lib/store\";\nexport type {\n SelectionState,\n ActiveFormat,\n ExtendedFormat,\n UIState,\n EditorStore,\n} from \"./lib/store\";\n\n// ── Constants ─────────────────────────────────────────────────────────────\nexport {\n FONT_FAMILIES,\n FONT_SIZES,\n STYLE_PRESETS,\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n UNDERLINE_TYPES,\n COLOR_PRESETS,\n HIGHLIGHT_COLORS,\n} from \"./lib/constants\";\nexport type {\n FontFamily,\n StylePreset,\n AlignmentType,\n AlignmentOption,\n LineSpacingOption,\n SidebarTab,\n} from \"./lib/constants\";\n\n// ── Format bridge ─────────────────────────────────────────────────────────\nexport {\n readCharFormat,\n readParaFormat,\n readStyleInfo,\n getDocumentStyles,\n readFormatFromSelection,\n} from \"./lib/format-bridge\";\nexport type { CharFormat, ParaFormat } from \"./lib/format-bridge\";\n\n// ── View model ────────────────────────────────────────────────────────────\nexport { buildViewModel } from \"./lib/view-model\";\nexport type {\n RunVM,\n TableCellVM,\n TableVM,\n ImageVM,\n ParagraphVM,\n SectionVM,\n EditorViewModel,\n} from \"./lib/view-model\";\n\n// ── Utilities ─────────────────────────────────────────────────────────────\nexport { hwpToPx, pxToHwp, hwpToMm, mmToHwp } from \"./lib/hwp-units\";\nexport { extractImages } from \"./lib/image-extractor\";\nexport { ensureSkeletonLoaded, createNewDocument } from \"./lib/skeleton-loader\";\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ensureSkeletonLoaded } from \"@/lib/skeleton-loader\";\nimport { RibbonToolbar } from \"../toolbar/RibbonToolbar\";\nimport { SecondaryToolbar } from \"../toolbar/SecondaryToolbar\";\nimport { HorizontalRuler } from \"../ruler/HorizontalRuler\";\nimport { FormatSidebar } from \"../sidebar/FormatSidebar\";\nimport { PageView } from \"./PageView\";\nimport { FileUpload } from \"../upload/FileUpload\";\nimport { NewDocumentButton } from \"../upload/NewDocumentButton\";\nimport { PanelRight } from \"lucide-react\";\n\nexport function Editor() {\n const doc = useEditorStore((s) => s.doc);\n const loading = useEditorStore((s) => s.loading);\n const error = useEditorStore((s) => s.error);\n const uiState = useEditorStore((s) => s.uiState);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n\n // Pre-load skeleton on mount\n useEffect(() => {\n ensureSkeletonLoaded().catch(console.error);\n }, []);\n\n // Global keyboard shortcuts\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n const store = useEditorStore.getState();\n if (!store.doc || !store.selection) return;\n\n if ((e.ctrlKey || e.metaKey) && e.key === \"b\") {\n e.preventDefault();\n store.toggleBold();\n } else if ((e.ctrlKey || e.metaKey) && e.key === \"i\") {\n e.preventDefault();\n store.toggleItalic();\n } else if ((e.ctrlKey || e.metaKey) && e.key === \"u\") {\n e.preventDefault();\n store.toggleUnderline();\n } else if ((e.ctrlKey || e.metaKey) && e.key === \"s\") {\n e.preventDefault();\n store.saveDocument();\n }\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-screen items-center justify-center\">\n <div className=\"text-gray-500\">로딩 중...</div>\n </div>\n );\n }\n\n if (!doc) {\n return (\n <div className=\"flex h-screen flex-col items-center justify-center gap-6 bg-gray-100 p-8\">\n <h1 className=\"text-2xl font-bold text-gray-800\">HWPX Editor</h1>\n <p className=\"text-gray-500 max-w-md text-center\">\n HWPX 문서를 열거나 새 문서를 만들어 편집하세요.\n </p>\n <div className=\"w-full max-w-md\">\n <FileUpload />\n </div>\n <div className=\"flex gap-3\">\n <NewDocumentButton />\n </div>\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 rounded-lg text-sm\">\n {error}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"flex h-screen flex-col\">\n {/* Ribbon toolbar */}\n <RibbonToolbar />\n {/* Secondary toolbar (formatting bar) */}\n <SecondaryToolbar />\n {/* Horizontal ruler */}\n <HorizontalRuler />\n {/* Error banner */}\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 text-sm border-b border-red-200\">\n {error}\n </div>\n )}\n {/* Main content area: Page + Sidebar */}\n <div className=\"flex flex-1 overflow-hidden\">\n <PageView />\n <FormatSidebar />\n {/* Sidebar toggle when closed */}\n {!uiState.sidebarOpen && (\n <button\n onClick={toggleSidebar}\n className=\"absolute right-2 top-[140px] z-10 p-1.5 bg-white border border-gray-200 rounded shadow-sm text-gray-400 hover:text-gray-600 hover:bg-gray-50\"\n title=\"서식 사이드바 열기\"\n >\n <PanelRight className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n","/**\n * Zustand store — manages HwpxDocument + EditorViewModel + actions.\n */\n\nimport { create } from \"zustand\";\nimport type { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { buildViewModel, type EditorViewModel } from \"./view-model\";\nimport {\n readFormatFromSelection,\n type CharFormat,\n type ParaFormat,\n} from \"./format-bridge\";\nimport type { AlignmentType, SidebarTab } from \"./constants\";\n\nexport interface SelectionState {\n sectionIndex: number;\n paragraphIndex: number;\n type: \"paragraph\" | \"cell\";\n // For cell selection\n tableIndex?: number;\n row?: number;\n col?: number;\n}\n\nexport interface ActiveFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n}\n\nexport interface ExtendedFormat {\n char: CharFormat;\n para: ParaFormat;\n}\n\nexport interface UIState {\n sidebarOpen: boolean;\n sidebarTab: SidebarTab;\n}\n\nexport interface EditorStore {\n doc: HwpxDocument | null;\n viewModel: EditorViewModel | null;\n revision: number;\n selection: SelectionState | null;\n activeFormat: ActiveFormat;\n extendedFormat: ExtendedFormat;\n uiState: UIState;\n loading: boolean;\n error: string | null;\n\n // Actions\n setDocument: (doc: HwpxDocument) => void;\n rebuild: () => void;\n setSelection: (sel: SelectionState | null) => void;\n setActiveFormat: (fmt: Partial<ActiveFormat>) => void;\n refreshExtendedFormat: () => void;\n\n // UI actions\n toggleSidebar: () => void;\n setSidebarTab: (tab: SidebarTab) => void;\n\n // Text editing\n updateParagraphText: (\n sectionIndex: number,\n paragraphIndex: number,\n text: string,\n ) => void;\n updateCellText: (\n sectionIndex: number,\n paragraphIndex: number,\n tableIndex: number,\n row: number,\n col: number,\n text: string,\n ) => void;\n\n // Formatting\n toggleBold: () => void;\n toggleItalic: () => void;\n toggleUnderline: () => void;\n\n // Content insertion\n addParagraph: (text?: string) => void;\n addTable: (\n sectionIndex: number,\n paragraphIndex: number,\n rows: number,\n cols: number,\n ) => void;\n insertImage: (\n data: Uint8Array,\n mediaType: string,\n widthMm: number,\n heightMm: number,\n ) => void;\n\n // File operations\n saveDocument: () => Promise<void>;\n setLoading: (loading: boolean) => void;\n setError: (error: string | null) => void;\n}\n\nconst defaultCharFormat: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n};\n\nconst defaultParaFormat: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n};\n\nexport const useEditorStore = create<EditorStore>((set, get) => ({\n doc: null,\n viewModel: null,\n revision: 0,\n selection: null,\n activeFormat: { bold: false, italic: false, underline: false },\n extendedFormat: { char: defaultCharFormat, para: defaultParaFormat },\n uiState: { sidebarOpen: true, sidebarTab: \"char\" },\n loading: false,\n error: null,\n\n setDocument: (doc) => {\n const viewModel = buildViewModel(doc);\n set({ doc, viewModel, revision: get().revision + 1, error: null });\n },\n\n rebuild: () => {\n const { doc } = get();\n if (!doc) return;\n const viewModel = buildViewModel(doc);\n set({ viewModel, revision: get().revision + 1 });\n },\n\n setSelection: (selection) => {\n set({ selection });\n // Auto-refresh extended format when selection changes\n if (selection) {\n // Use setTimeout to avoid synchronous read during render\n setTimeout(() => get().refreshExtendedFormat(), 0);\n }\n },\n\n setActiveFormat: (fmt) =>\n set((s) => ({ activeFormat: { ...s.activeFormat, ...fmt } })),\n\n refreshExtendedFormat: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const fmt = readFormatFromSelection(\n doc,\n selection.sectionIndex,\n selection.paragraphIndex,\n );\n set({\n extendedFormat: fmt,\n activeFormat: {\n bold: fmt.char.bold,\n italic: fmt.char.italic,\n underline: fmt.char.underline,\n },\n });\n } catch (e) {\n console.error(\"refreshExtendedFormat failed:\", e);\n }\n },\n\n // UI actions\n toggleSidebar: () =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarOpen: !s.uiState.sidebarOpen },\n })),\n\n setSidebarTab: (tab) =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarTab: tab },\n })),\n\n setLoading: (loading) => set({ loading }),\n setError: (error) => set({ error }),\n\n updateParagraphText: (sectionIndex, paragraphIndex, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n para.text = text;\n get().rebuild();\n } catch (e) {\n console.error(\"updateParagraphText failed:\", e);\n }\n },\n\n updateCellText: (sectionIndex, paragraphIndex, tableIndex, row, col, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n const table = para.tables[tableIndex];\n if (!table) return;\n table.setCellText(row, col, text);\n get().rebuild();\n } catch (e) {\n console.error(\"updateCellText failed:\", e);\n }\n },\n\n toggleBold: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newBold = !activeFormat.bold;\n try {\n const charPrIdRef = doc.ensureRunStyle({\n bold: newBold,\n italic: activeFormat.italic,\n underline: activeFormat.underline,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, bold: newBold } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleBold failed:\", e);\n }\n },\n\n toggleItalic: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newItalic = !activeFormat.italic;\n try {\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: newItalic,\n underline: activeFormat.underline,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, italic: newItalic } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleItalic failed:\", e);\n }\n },\n\n toggleUnderline: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newUnderline = !activeFormat.underline;\n try {\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: activeFormat.italic,\n underline: newUnderline,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, underline: newUnderline } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleUnderline failed:\", e);\n }\n },\n\n addParagraph: (text = \"\") => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addParagraph(text);\n get().rebuild();\n } catch (e) {\n console.error(\"addParagraph failed:\", e);\n }\n },\n\n addTable: (sectionIndex, paragraphIndex, rows, cols) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const para = section.paragraphs[paragraphIndex];\n if (!para) return;\n para.addTable(rows, cols);\n get().rebuild();\n } catch (e) {\n console.error(\"addTable failed:\", e);\n }\n },\n\n insertImage: (data, mediaType, widthMm, heightMm) => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addImage(data, { mediaType, widthMm, heightMm });\n get().rebuild();\n } catch (e) {\n console.error(\"insertImage failed:\", e);\n }\n },\n\n saveDocument: async () => {\n const { doc } = get();\n if (!doc) return;\n try {\n set({ loading: true });\n const bytes = await doc.save();\n const blob = new Blob([bytes as unknown as BlobPart], {\n type: \"application/vnd.hancom.hwpx\",\n });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = \"document.hwpx\";\n a.click();\n URL.revokeObjectURL(url);\n } catch (e) {\n console.error(\"save failed:\", e);\n set({ error: \"문서 저장에 실패했습니다.\" });\n } finally {\n set({ loading: false });\n }\n },\n}));\n","/**\n * EditorViewModel — pure data structures derived from HwpxDocument for rendering.\n */\n\nimport type {\n HwpxDocument,\n RunStyle,\n HwpxTableGridPosition,\n} from \"@ubermensch1218/hwpxcore\";\nimport { parseHeaderXml, serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { Header, ParagraphProperty } from \"@ubermensch1218/hwpxcore\";\nimport { hwpToPx } from \"./hwp-units\";\nimport { extractImages } from \"./image-extractor\";\n\n// ── ViewModel types ────────────────────────────────────────────────────────\n\nexport interface RunVM {\n text: string;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n charPrIdRef: string | null;\n}\n\nexport interface TableCellVM {\n row: number;\n col: number;\n rowSpan: number;\n colSpan: number;\n widthPx: number;\n heightPx: number;\n text: string;\n isAnchor: boolean; // true if this is the top-left of a merged region\n}\n\nexport interface TableVM {\n rowCount: number;\n colCount: number;\n cells: TableCellVM[][]; // 2D grid [row][col], non-anchor cells have isAnchor=false\n tableIndex: number; // index within the paragraph\n}\n\nexport interface ImageVM {\n dataUrl: string;\n widthPx: number;\n heightPx: number;\n binaryItemIdRef: string;\n}\n\nexport interface ParagraphVM {\n runs: RunVM[];\n tables: TableVM[];\n images: ImageVM[];\n alignment: string;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n firstLineIndent: number;\n marginLeftPx: number;\n marginRightPx: number;\n paragraphIndex: number; // global index across all sections\n}\n\nexport interface SectionVM {\n pageWidthPx: number;\n pageHeightPx: number;\n marginTopPx: number;\n marginBottomPx: number;\n marginLeftPx: number;\n marginRightPx: number;\n paragraphs: ParagraphVM[];\n sectionIndex: number;\n}\n\nexport interface EditorViewModel {\n sections: SectionVM[];\n}\n\n// ── Builder ────────────────────────────────────────────────────────────────\n\nfunction extractRunStyle(\n style: RunStyle | null,\n): {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n} {\n if (!style) {\n return {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n color: null,\n fontFamily: null,\n fontSize: null,\n highlightColor: null,\n letterSpacing: null,\n };\n }\n\n const bold = style.attributes[\"bold\"] === \"1\";\n const italic = style.attributes[\"italic\"] === \"1\";\n\n // Check underline child element\n const underlineChild = style.childAttributes[\"underline\"];\n const underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n const strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n const color = style.attributes[\"textColor\"] ?? null;\n\n // Highlight\n const highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Font family\n let fontFamily: string | null = null;\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n fontFamily = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n }\n\n // Font size (height in hwpUnits / 100 = pt)\n let fontSize: number | null = null;\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) fontSize = hwpVal / 100;\n }\n\n // Letter spacing\n let letterSpacing: number | null = null;\n const spacingStr = style.attributes[\"spacing\"];\n if (spacingStr) {\n const val = parseInt(spacingStr, 10);\n if (!isNaN(val) && val !== 0) letterSpacing = val;\n }\n\n return { bold, italic, underline, strikethrough, color, fontFamily, fontSize, highlightColor, letterSpacing };\n}\n\n/** Find binaryItemIDRef from a picture element inside a run. */\nfunction findPictureRefs(\n runElement: Element,\n): { binaryItemIdRef: string; width: number; height: number }[] {\n const results: { binaryItemIdRef: string; width: number; height: number }[] = [];\n\n // Look for <pic> elements inside the run\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"pic\") continue;\n\n // Get size from curSz\n let width = 0;\n let height = 0;\n const picChildren = el.childNodes;\n for (let j = 0; j < picChildren.length; j++) {\n const pc = picChildren.item(j);\n if (!pc || pc.nodeType !== 1) continue;\n const pel = pc as Element;\n const pName = pel.localName || pel.nodeName.split(\":\").pop() || \"\";\n\n if (pName === \"curSz\") {\n width = parseInt(pel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(pel.getAttribute(\"height\") ?? \"0\", 10);\n }\n\n // Find img element inside pic (possibly nested in renderingInfo or directly)\n if (pName === \"img\") {\n const ref = pel.getAttribute(\"binaryItemIDRef\");\n if (ref) results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n\n // Also search deeper for img (might be in a sub-element)\n const allDescendants = el.getElementsByTagName(\"*\");\n for (let k = 0; k < allDescendants.length; k++) {\n const desc = allDescendants.item(k);\n if (!desc) continue;\n const dName = desc.localName || desc.nodeName.split(\":\").pop() || \"\";\n if (dName === \"img\") {\n const ref = desc.getAttribute(\"binaryItemIDRef\");\n if (ref && !results.some((r) => r.binaryItemIdRef === ref)) {\n results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n }\n }\n\n return results;\n}\n\n/** Parse the header element to get ParagraphProperty lookup. */\nfunction buildParaPrLookup(doc: HwpxDocument): Map<string, ParagraphProperty> {\n const lookup = new Map<string, ParagraphProperty>();\n try {\n const headers = doc.headers;\n if (headers.length === 0) return lookup;\n const headerEl = headers[0]!.element;\n const xml = serializeXml(headerEl);\n const parsed: Header = parseHeaderXml(xml);\n if (!parsed.refList?.paraProperties) return lookup;\n for (const prop of parsed.refList.paraProperties.properties) {\n if (prop.rawId) lookup.set(prop.rawId, prop);\n if (prop.id != null) lookup.set(String(prop.id), prop);\n }\n } catch {\n // ignore parse errors\n }\n return lookup;\n}\n\nexport function buildViewModel(doc: HwpxDocument): EditorViewModel {\n const imageMap = extractImages(doc.package);\n const paraPrLookup = buildParaPrLookup(doc);\n const sections: SectionVM[] = [];\n\n let globalParaIndex = 0;\n\n for (let sIdx = 0; sIdx < doc.sections.length; sIdx++) {\n const section = doc.sections[sIdx]!;\n const props = section.properties;\n const pageSize = props.pageSize;\n const pageMargins = props.pageMargins;\n\n const sectionVM: SectionVM = {\n pageWidthPx: hwpToPx(pageSize.width),\n pageHeightPx: hwpToPx(pageSize.height),\n marginTopPx: hwpToPx(pageMargins.top),\n marginBottomPx: hwpToPx(pageMargins.bottom),\n marginLeftPx: hwpToPx(pageMargins.left),\n marginRightPx: hwpToPx(pageMargins.right),\n paragraphs: [],\n sectionIndex: sIdx,\n };\n\n const paragraphs = section.paragraphs;\n for (const para of paragraphs) {\n const runs: RunVM[] = [];\n const images: ImageVM[] = [];\n\n for (const run of para.runs) {\n const style = run.style;\n const {\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n } = extractRunStyle(style);\n const text = run.text;\n\n if (text) {\n runs.push({\n text,\n bold,\n italic,\n underline,\n strikethrough,\n color,\n fontFamily,\n fontSize,\n highlightColor,\n letterSpacing,\n charPrIdRef: run.charPrIdRef,\n });\n }\n\n // Check for images inside this run\n const picRefs = findPictureRefs(run.element);\n for (const ref of picRefs) {\n const dataUrl = imageMap.get(ref.binaryItemIdRef);\n if (dataUrl) {\n images.push({\n dataUrl,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n binaryItemIdRef: ref.binaryItemIdRef,\n });\n }\n }\n }\n\n // Tables\n const tables: TableVM[] = [];\n const paraTables = para.tables;\n for (let tIdx = 0; tIdx < paraTables.length; tIdx++) {\n const table = paraTables[tIdx]!;\n const rowCount = table.rowCount;\n const colCount = table.columnCount;\n\n let cellGrid: HwpxTableGridPosition[][] = [];\n try {\n cellGrid = table.getCellMap();\n } catch {\n // If grid building fails, skip\n continue;\n }\n\n const cellsVM: TableCellVM[][] = [];\n for (let r = 0; r < rowCount; r++) {\n const row: TableCellVM[] = [];\n for (let c = 0; c < colCount; c++) {\n const pos = cellGrid[r]?.[c];\n if (!pos) {\n row.push({\n row: r,\n col: c,\n rowSpan: 1,\n colSpan: 1,\n widthPx: 0,\n heightPx: 0,\n text: \"\",\n isAnchor: false,\n });\n continue;\n }\n\n const isAnchor = pos.anchor[0] === r && pos.anchor[1] === c;\n row.push({\n row: r,\n col: c,\n rowSpan: pos.span[0],\n colSpan: pos.span[1],\n widthPx: hwpToPx(pos.cell.width),\n heightPx: hwpToPx(pos.cell.height),\n text: isAnchor ? pos.cell.text : \"\",\n isAnchor,\n });\n }\n cellsVM.push(row);\n }\n\n tables.push({\n rowCount,\n colCount,\n cells: cellsVM,\n tableIndex: tIdx,\n });\n }\n\n // Extract paragraph formatting from paraPrIdRef\n let alignment = \"LEFT\";\n let lineSpacing = 1.6;\n let spacingBefore = 0;\n let spacingAfter = 0;\n let firstLineIndent = 0;\n let marginLeftPx = 0;\n let marginRightPx = 0;\n\n const paraPrIdRef = para.paraPrIdRef;\n if (paraPrIdRef) {\n const paraPr = paraPrLookup.get(paraPrIdRef);\n if (paraPr) {\n // Alignment\n if (paraPr.align?.horizontal) {\n alignment = paraPr.align.horizontal.toUpperCase();\n }\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n lineSpacing = paraPr.lineSpacing.value / 100;\n }\n // Margins and spacing\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n marginLeftPx = hwpToPx(parseInt(paraPr.margin.left, 10) || 0);\n }\n if (paraPr.margin.right) {\n marginRightPx = hwpToPx(parseInt(paraPr.margin.right, 10) || 0);\n }\n if (paraPr.margin.intent) {\n firstLineIndent = hwpToPx(parseInt(paraPr.margin.intent, 10) || 0);\n }\n if (paraPr.margin.prev) {\n spacingBefore = hwpToPx(parseInt(paraPr.margin.prev, 10) || 0);\n }\n if (paraPr.margin.next) {\n spacingAfter = hwpToPx(parseInt(paraPr.margin.next, 10) || 0);\n }\n }\n }\n }\n\n sectionVM.paragraphs.push({\n runs,\n tables,\n images,\n alignment,\n lineSpacing,\n spacingBefore,\n spacingAfter,\n firstLineIndent,\n marginLeftPx,\n marginRightPx,\n paragraphIndex: globalParaIndex,\n });\n\n globalParaIndex++;\n }\n\n sections.push(sectionVM);\n }\n\n return { sections };\n}\n","/**\n * HWPX unit conversion utilities.\n *\n * HWPX uses hwpUnit where 7200 hwpUnit = 1 inch = 25.4 mm.\n * Screen rendering at 96 DPI: 1 hwpUnit = 96/7200 px ≈ 0.01333 px.\n */\n\nconst HWP_UNITS_PER_INCH = 7200;\nconst PX_PER_INCH = 96;\nconst MM_PER_INCH = 25.4;\n\n/** Convert hwpUnit to pixels at 96 DPI. */\nexport function hwpToPx(hwpUnit: number): number {\n return (hwpUnit * PX_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert pixels (96 DPI) to hwpUnit. */\nexport function pxToHwp(px: number): number {\n return Math.round((px * HWP_UNITS_PER_INCH) / PX_PER_INCH);\n}\n\n/** Convert hwpUnit to millimeters. */\nexport function hwpToMm(hwpUnit: number): number {\n return (hwpUnit * MM_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert millimeters to hwpUnit. */\nexport function mmToHwp(mm: number): number {\n return Math.round((mm * HWP_UNITS_PER_INCH) / MM_PER_INCH);\n}\n","/**\n * Extract binary image data from an HwpxDocument package as data URLs.\n */\n\nimport type { HwpxPackage } from \"@ubermensch1218/hwpxcore\";\n\n/** Map of binaryItemIdRef → data:... URL for all images in the package. */\nexport function extractImages(pkg: HwpxPackage): Map<string, string> {\n const images = new Map<string, string>();\n const partNames = pkg.partNames();\n\n for (const name of partNames) {\n if (!name.startsWith(\"BinData/\")) continue;\n\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\";\n let mediaType = \"application/octet-stream\";\n if (ext === \"png\") mediaType = \"image/png\";\n else if (ext === \"jpg\" || ext === \"jpeg\") mediaType = \"image/jpeg\";\n else if (ext === \"gif\") mediaType = \"image/gif\";\n else if (ext === \"bmp\") mediaType = \"image/bmp\";\n else if (ext === \"svg\") mediaType = \"image/svg+xml\";\n else if (ext === \"webp\") mediaType = \"image/webp\";\n else if (ext === \"tif\" || ext === \"tiff\") mediaType = \"image/tiff\";\n else if (ext === \"emf\") mediaType = \"image/x-emf\";\n else if (ext === \"wmf\") mediaType = \"image/x-wmf\";\n\n try {\n const data = pkg.getPart(name);\n const base64 = uint8ToBase64(data);\n const dataUrl = `data:${mediaType};base64,${base64}`;\n\n // Store with the filename (e.g. \"image1.png\")\n const fileName = name.replace(\"BinData/\", \"\");\n images.set(fileName, dataUrl);\n } catch {\n // Skip parts that can't be read\n }\n }\n\n return images;\n}\n\nfunction uint8ToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!);\n }\n return btoa(binary);\n}\n","/**\n * format-bridge.ts — Bridge between UI and @ubermensch1218/hwpxcore formatting APIs.\n *\n * Reads charPr / paraPr from the document and converts to UI-friendly formats.\n * Also provides methods to apply format changes back to the document.\n */\n\nimport type {\n HwpxDocument,\n HwpxOxmlParagraph,\n RunStyle,\n ParagraphProperty,\n Header,\n Style,\n} from \"@ubermensch1218/hwpxcore\";\nimport {\n parseHeaderXml,\n} from \"@ubermensch1218/hwpxcore\";\nimport { serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { AlignmentType } from \"./constants\";\n\n// ── Read format types ──────────────────────────────────────────────────────\n\nexport interface CharFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n fontFamily: string | null;\n fontSize: number | null;\n textColor: string | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n}\n\nexport interface ParaFormat {\n alignment: AlignmentType;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n indentLeft: number;\n indentRight: number;\n firstLineIndent: number;\n}\n\n// ── Parse header to get paragraph properties ───────────────────────────────\n\nfunction getParsedHeader(doc: HwpxDocument): Header | null {\n const headers = doc.headers;\n if (headers.length === 0) return null;\n const headerEl = headers[0]!.element;\n try {\n const xml = serializeXml(headerEl);\n return parseHeaderXml(xml);\n } catch {\n return null;\n }\n}\n\n// ── Read character formatting from a run style ─────────────────────────────\n\nexport function readCharFormat(style: RunStyle | null): CharFormat {\n const result: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n };\n\n if (!style) return result;\n\n result.bold = style.attributes[\"bold\"] === \"1\";\n result.italic = style.attributes[\"italic\"] === \"1\";\n\n // Underline\n const underlineChild = style.childAttributes[\"underline\"];\n result.underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n result.strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n // Text color\n result.textColor = style.attributes[\"textColor\"] ?? null;\n\n // Highlight color\n result.highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Letter spacing\n const spacing = style.attributes[\"spacing\"];\n if (spacing) {\n const val = parseInt(spacing, 10);\n if (!isNaN(val)) result.letterSpacing = val;\n }\n\n // Font family — look in fontRef child\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n // Korean font is in hangul attribute\n result.fontFamily = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n }\n\n // Font size\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n // Height is in hwp units (1/7200 inch), convert to pt: hwpUnit / 100\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) result.fontSize = hwpVal / 100;\n }\n\n return result;\n}\n\n// ── Read paragraph formatting ──────────────────────────────────────────────\n\nexport function readParaFormat(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): ParaFormat {\n const result: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n };\n\n const paraPrIdRef = paragraph.paraPrIdRef;\n if (!paraPrIdRef) return result;\n\n const header = getParsedHeader(doc);\n if (!header) return result;\n\n // Look up the paragraph property\n const paraPr = findParaPr(header, paraPrIdRef);\n if (!paraPr) return result;\n\n // Alignment\n if (paraPr.align?.horizontal) {\n const h = paraPr.align.horizontal.toUpperCase();\n if (\n h === \"LEFT\" || h === \"CENTER\" || h === \"RIGHT\" ||\n h === \"JUSTIFY\" || h === \"DISTRIBUTE\"\n ) {\n result.alignment = h as AlignmentType;\n }\n }\n\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n const spacingType = paraPr.lineSpacing.spacingType?.toUpperCase();\n if (spacingType === \"PERCENT\" || spacingType === \"PROPORTIONAL\") {\n // Value is in percent (e.g., 160 = 1.6x)\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n } else {\n // Fixed value in hwp units\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n }\n }\n\n // Margins / indentation\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n result.indentLeft = parseInt(paraPr.margin.left, 10) || 0;\n }\n if (paraPr.margin.right) {\n result.indentRight = parseInt(paraPr.margin.right, 10) || 0;\n }\n if (paraPr.margin.intent) {\n result.firstLineIndent = parseInt(paraPr.margin.intent, 10) || 0;\n }\n if (paraPr.margin.prev) {\n result.spacingBefore = parseInt(paraPr.margin.prev, 10) || 0;\n }\n if (paraPr.margin.next) {\n result.spacingAfter = parseInt(paraPr.margin.next, 10) || 0;\n }\n }\n\n return result;\n}\n\n// ── Helper: find paragraph property by ID ──────────────────────────────────\n\nfunction findParaPr(header: Header, paraPrIdRef: string): ParagraphProperty | null {\n if (!header.refList?.paraProperties) return null;\n for (const prop of header.refList.paraProperties.properties) {\n if (prop.rawId === paraPrIdRef) return prop;\n if (prop.id != null && String(prop.id) === paraPrIdRef) return prop;\n }\n return null;\n}\n\n// ── Read style info ────────────────────────────────────────────────────────\n\nexport function readStyleInfo(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): { styleName: string | null; styleId: string | null } {\n const styleIdRef = paragraph.styleIdRef;\n if (!styleIdRef) return { styleName: null, styleId: null };\n\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return { styleName: null, styleId: null };\n\n for (const style of header.refList.styles.styles) {\n if (style.rawId === styleIdRef || (style.id != null && String(style.id) === styleIdRef)) {\n return { styleName: style.name, styleId: styleIdRef };\n }\n }\n\n return { styleName: null, styleId: styleIdRef };\n}\n\n// ── Get available styles from document ─────────────────────────────────────\n\nexport function getDocumentStyles(doc: HwpxDocument): Style[] {\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return [];\n return header.refList.styles.styles;\n}\n\n// ── Read format from current selection ─────────────────────────────────────\n\nexport function readFormatFromSelection(\n doc: HwpxDocument,\n sectionIndex: number,\n paragraphIndex: number,\n): { char: CharFormat; para: ParaFormat } {\n const section = doc.sections[sectionIndex];\n if (!section) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n // Character format: use the first run's style or the paragraph's charPrIdRef\n const runs = para.runs;\n let charStyle: RunStyle | null = null;\n if (runs.length > 0) {\n charStyle = runs[0]!.style;\n } else {\n const charPrIdRef = para.charPrIdRef;\n if (charPrIdRef) {\n charStyle = doc.charProperty(charPrIdRef);\n }\n }\n\n return {\n char: readCharFormat(charStyle),\n para: readParaFormat(doc, para),\n };\n}\n","/**\n * Browser-side Skeleton.hwpx loader.\n * Fetches from /Skeleton.hwpx and calls setSkeletonHwpx() to register it.\n */\n\nimport { setSkeletonHwpx, HwpxDocument } from \"@ubermensch1218/hwpxcore\";\n\nlet loaded = false;\n\n/** Fetch Skeleton.hwpx from the public folder and register it with @ubermensch1218/hwpxcore. */\nexport async function ensureSkeletonLoaded(): Promise<void> {\n if (loaded) return;\n const res = await fetch(\"/Skeleton.hwpx\");\n if (!res.ok) throw new Error(`Failed to fetch Skeleton.hwpx: ${res.status}`);\n const buf = await res.arrayBuffer();\n setSkeletonHwpx(new Uint8Array(buf));\n loaded = true;\n}\n\n/** Create a new empty HwpxDocument from the skeleton template. */\nexport async function createNewDocument(): Promise<HwpxDocument> {\n await ensureSkeletonLoaded();\n const res = await fetch(\"/Skeleton.hwpx\");\n const buf = await res.arrayBuffer();\n return HwpxDocument.open(buf);\n}\n","\"use client\";\n\nimport { Clipboard, Copy, ClipboardPaste, Paintbrush } from \"lucide-react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function ClipboardGroup() {\n return (\n <RibbonGroup label=\"클립보드\">\n <ToolbarButton\n icon={<Clipboard className=\"w-4 h-4\" />}\n title=\"오려두기 (Ctrl+X)\"\n onClick={() => document.execCommand(\"cut\")}\n />\n <ToolbarButton\n icon={<Copy className=\"w-4 h-4\" />}\n title=\"복사 (Ctrl+C)\"\n onClick={() => document.execCommand(\"copy\")}\n />\n <ToolbarButton\n icon={<ClipboardPaste className=\"w-4 h-4\" />}\n title=\"붙이기 (Ctrl+V)\"\n onClick={() => document.execCommand(\"paste\")}\n />\n <ToolbarButton\n icon={<Paintbrush className=\"w-4 h-4\" />}\n title=\"모양 복사\"\n disabled\n />\n </RibbonGroup>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface ToolbarButtonProps {\n icon: ReactNode;\n label?: string;\n active?: boolean;\n disabled?: boolean;\n onClick?: () => void;\n title?: string;\n size?: \"sm\" | \"md\";\n className?: string;\n}\n\nexport function ToolbarButton({\n icon,\n label,\n active,\n disabled,\n onClick,\n title,\n size = \"sm\",\n className = \"\",\n}: ToolbarButtonProps) {\n const sizeClass = size === \"md\" ? \"p-2\" : \"p-1.5\";\n return (\n <button\n disabled={disabled}\n onClick={onClick}\n title={title}\n className={`${sizeClass} rounded transition-colors flex items-center gap-1 ${\n active\n ? \"bg-blue-100 text-blue-700\"\n : \"text-gray-600 hover:bg-gray-100\"\n } disabled:opacity-40 disabled:cursor-not-allowed ${className}`}\n >\n {icon}\n {label && <span className=\"text-xs\">{label}</span>}\n </button>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface RibbonGroupProps {\n label: string;\n children: ReactNode;\n}\n\nexport function RibbonGroup({ label, children }: RibbonGroupProps) {\n return (\n <div className=\"flex flex-col items-center border-r border-gray-200 px-2 last:border-r-0\">\n <div className=\"flex items-center gap-0.5 py-1\">{children}</div>\n <span className=\"text-[10px] text-gray-400 pb-0.5\">{label}</span>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { Table, BarChart3, Shapes, ImageIcon, Save } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function InsertGroup() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const addTable = useEditorStore((s) => s.addTable);\n const insertImage = useEditorStore((s) => s.insertImage);\n const saveDocument = useEditorStore((s) => s.saveDocument);\n const loading = useEditorStore((s) => s.loading);\n\n const [showTableDialog, setShowTableDialog] = useState(false);\n const [tableRows, setTableRows] = useState(3);\n const [tableCols, setTableCols] = useState(3);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const disabled = !doc;\n\n const handleAddTable = useCallback(() => {\n if (!selection) return;\n addTable(selection.sectionIndex, selection.paragraphIndex, tableRows, tableCols);\n setShowTableDialog(false);\n }, [selection, tableRows, tableCols, addTable]);\n\n const handleImageSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n const img = new window.Image();\n const url = URL.createObjectURL(file);\n img.onload = () => {\n const widthMm = (img.naturalWidth / 96) * 25.4;\n const heightMm = (img.naturalHeight / 96) * 25.4;\n insertImage(data, file.type, widthMm, heightMm);\n URL.revokeObjectURL(url);\n };\n img.src = url;\n e.target.value = \"\";\n },\n [insertImage],\n );\n\n return (\n <>\n <RibbonGroup label=\"삽입\">\n <ToolbarButton\n icon={<Table className=\"w-4 h-4\" />}\n title=\"표 삽입\"\n disabled={disabled || !selection}\n onClick={() => setShowTableDialog(true)}\n />\n <ToolbarButton\n icon={<BarChart3 className=\"w-4 h-4\" />}\n title=\"차트 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<Shapes className=\"w-4 h-4\" />}\n title=\"도형 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<ImageIcon className=\"w-4 h-4\" />}\n title=\"그림 삽입\"\n disabled={disabled}\n onClick={() => imageInputRef.current?.click()}\n />\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleImageSelect}\n />\n </RibbonGroup>\n\n <RibbonGroup label=\"파일\">\n <ToolbarButton\n icon={<Save className=\"w-4 h-4\" />}\n title=\"저장 (Ctrl+S)\"\n disabled={disabled || loading}\n onClick={() => saveDocument()}\n />\n </RibbonGroup>\n\n {/* Table dialog */}\n {showTableDialog && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/30\">\n <div className=\"bg-white rounded-lg shadow-xl p-6 min-w-[280px]\">\n <h3 className=\"font-semibold mb-4\">표 삽입</h3>\n <div className=\"flex gap-4 mb-4\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">행</span>\n <input\n type=\"number\"\n min={1}\n max={50}\n value={tableRows}\n onChange={(e) => setTableRows(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">열</span>\n <input\n type=\"number\"\n min={1}\n max={20}\n value={tableCols}\n onChange={(e) => setTableCols(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n onClick={() => setShowTableDialog(false)}\n className=\"px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded\"\n >\n 취소\n </button>\n <button\n onClick={handleAddTable}\n className=\"px-4 py-2 text-sm bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n 삽입\n </button>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { ClipboardGroup } from \"./ClipboardGroup\";\nimport { InsertGroup } from \"./InsertGroup\";\n\nexport function RibbonToolbar() {\n return (\n <div className=\"flex items-stretch bg-white border-b border-gray-200 px-1 min-h-[52px]\">\n <ClipboardGroup />\n <InsertGroup />\n </div>\n );\n}\n","/**\n * Constants for the HWPX editor UI — font lists, style presets, alignment/spacing options.\n */\n\n// ── Korean font families ───────────────────────────────────────────────────\n\nexport const FONT_FAMILIES = [\n \"맑은 고딕\",\n \"함초롬돋움\",\n \"함초롬바탕\",\n \"나눔고딕\",\n \"나눔명조\",\n \"나눔바른고딕\",\n \"바탕\",\n \"돋움\",\n \"굴림\",\n \"궁서\",\n \"Arial\",\n \"Times New Roman\",\n \"Courier New\",\n \"Verdana\",\n \"Georgia\",\n] as const;\n\nexport type FontFamily = (typeof FONT_FAMILIES)[number];\n\n// ── Font sizes ─────────────────────────────────────────────────────────────\n\nexport const FONT_SIZES = [\n 8, 9, 10, 10.5, 11, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 48, 72,\n] as const;\n\n// ── Paragraph styles ───────────────────────────────────────────────────────\n\nexport interface StylePreset {\n id: string;\n name: string;\n engName: string;\n}\n\nexport const STYLE_PRESETS: StylePreset[] = [\n { id: \"0\", name: \"바탕글\", engName: \"Normal\" },\n { id: \"1\", name: \"본문\", engName: \"Body\" },\n { id: \"2\", name: \"개요 1\", engName: \"Outline 1\" },\n { id: \"3\", name: \"개요 2\", engName: \"Outline 2\" },\n { id: \"4\", name: \"개요 3\", engName: \"Outline 3\" },\n { id: \"5\", name: \"쪽 번호\", engName: \"Page Number\" },\n { id: \"6\", name: \"머리말\", engName: \"Header\" },\n { id: \"7\", name: \"꼬리말\", engName: \"Footer\" },\n { id: \"8\", name: \"각주\", engName: \"Footnote\" },\n { id: \"9\", name: \"미주\", engName: \"Endnote\" },\n];\n\n// ── Alignment ──────────────────────────────────────────────────────────────\n\nexport type AlignmentType = \"LEFT\" | \"CENTER\" | \"RIGHT\" | \"JUSTIFY\" | \"DISTRIBUTE\";\n\nexport interface AlignmentOption {\n value: AlignmentType;\n label: string;\n shortcut?: string;\n}\n\nexport const ALIGNMENT_OPTIONS: AlignmentOption[] = [\n { value: \"LEFT\", label: \"왼쪽 정렬\", shortcut: \"Ctrl+L\" },\n { value: \"CENTER\", label: \"가운데 정렬\", shortcut: \"Ctrl+E\" },\n { value: \"RIGHT\", label: \"오른쪽 정렬\", shortcut: \"Ctrl+R\" },\n { value: \"JUSTIFY\", label: \"양쪽 정렬\", shortcut: \"Ctrl+J\" },\n { value: \"DISTRIBUTE\", label: \"배분 정렬\" },\n];\n\n// ── Line spacing ───────────────────────────────────────────────────────────\n\nexport interface LineSpacingOption {\n value: number;\n label: string;\n}\n\nexport const LINE_SPACING_OPTIONS: LineSpacingOption[] = [\n { value: 1.0, label: \"1.0\" },\n { value: 1.15, label: \"1.15\" },\n { value: 1.5, label: \"1.5\" },\n { value: 1.6, label: \"1.6\" },\n { value: 2.0, label: \"2.0\" },\n { value: 2.5, label: \"2.5\" },\n { value: 3.0, label: \"3.0\" },\n];\n\n// ── Underline types ────────────────────────────────────────────────────────\n\nexport const UNDERLINE_TYPES = [\n \"NONE\",\n \"SOLID\",\n \"DASH\",\n \"DOT\",\n \"DASH_DOT\",\n \"DASH_DOT_DOT\",\n \"LONG_DASH\",\n \"DOUBLE\",\n \"WAVE\",\n \"HEAVY_WAVE\",\n \"DOUBLE_WAVE\",\n] as const;\n\n// ── Color presets ──────────────────────────────────────────────────────────\n\nexport const COLOR_PRESETS = [\n // Row 1: Primary colors\n \"#000000\", \"#333333\", \"#555555\", \"#777777\", \"#999999\", \"#BBBBBB\", \"#DDDDDD\", \"#FFFFFF\",\n // Row 2: Vivid colors\n \"#FF0000\", \"#FF6600\", \"#FFCC00\", \"#33CC33\", \"#0099FF\", \"#3366FF\", \"#6633CC\", \"#CC33CC\",\n // Row 3: Pastel colors\n \"#FF9999\", \"#FFCC99\", \"#FFFF99\", \"#CCFFCC\", \"#99CCFF\", \"#9999FF\", \"#CC99FF\", \"#FF99CC\",\n // Row 4: Dark colors\n \"#CC0000\", \"#CC6600\", \"#CC9900\", \"#009900\", \"#006699\", \"#003399\", \"#330099\", \"#990066\",\n] as const;\n\n// ── Highlight colors ───────────────────────────────────────────────────────\n\nexport const HIGHLIGHT_COLORS = [\n { value: \"#FFFF00\", label: \"노랑\" },\n { value: \"#00FF00\", label: \"연두\" },\n { value: \"#00FFFF\", label: \"하늘\" },\n { value: \"#FF00FF\", label: \"분홍\" },\n { value: \"#0000FF\", label: \"파랑\" },\n { value: \"#FF0000\", label: \"빨강\" },\n { value: \"#008000\", label: \"초록\" },\n { value: \"#800080\", label: \"보라\" },\n { value: \"#808080\", label: \"회색\" },\n { value: \"none\", label: \"없음\" },\n] as const;\n\n// ── Sidebar tabs ───────────────────────────────────────────────────────────\n\nexport type SidebarTab = \"char\" | \"para\";\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\n\ninterface ToolbarDropdownProps {\n value: string;\n options: { value: string; label: string }[];\n onChange: (value: string) => void;\n disabled?: boolean;\n title?: string;\n className?: string;\n width?: string;\n icon?: ReactNode;\n}\n\nexport function ToolbarDropdown({\n value,\n options,\n onChange,\n disabled,\n title,\n className = \"\",\n width = \"w-28\",\n icon,\n}: ToolbarDropdownProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n const selectedLabel = options.find((o) => o.value === value)?.label ?? value;\n\n return (\n <div ref={ref} className={`relative ${className}`} title={title}>\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n className={`flex items-center gap-1 ${width} h-7 px-2 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-left disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {icon}\n <span className=\"flex-1 truncate\">{selectedLabel}</span>\n <svg className=\"w-3 h-3 text-gray-400 flex-shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded shadow-lg max-h-64 overflow-auto min-w-full\">\n {options.map((opt) => (\n <button\n key={opt.value}\n onClick={() => {\n onChange(opt.value);\n setOpen(false);\n }}\n className={`block w-full text-left px-3 py-1.5 text-xs hover:bg-blue-50 ${\n opt.value === value ? \"bg-blue-50 text-blue-700 font-medium\" : \"text-gray-700\"\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { STYLE_PRESETS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface StyleSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function StyleSelector({ value, onChange, disabled }: StyleSelectorProps) {\n const options = STYLE_PRESETS.map((s) => ({\n value: s.id,\n label: s.name,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"스타일\"\n width=\"w-24\"\n />\n );\n}\n","\"use client\";\n\nimport { FONT_FAMILIES } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface FontSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function FontSelector({ value, onChange, disabled }: FontSelectorProps) {\n const options = FONT_FAMILIES.map((f) => ({\n value: f,\n label: f,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"글꼴\"\n width=\"w-32\"\n />\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { FONT_SIZES } from \"@/lib/constants\";\n\ninterface FontSizeInputProps {\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n}\n\nexport function FontSizeInput({ value, onChange, disabled }: FontSizeInputProps) {\n const [editing, setEditing] = useState(false);\n const [inputValue, setInputValue] = useState(String(value));\n\n const handleBlur = useCallback(() => {\n setEditing(false);\n const num = parseFloat(inputValue);\n if (!isNaN(num) && num > 0 && num <= 200) {\n onChange(num);\n } else {\n setInputValue(String(value));\n }\n }, [inputValue, value, onChange]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLInputElement).blur();\n } else if (e.key === \"Escape\") {\n setInputValue(String(value));\n setEditing(false);\n }\n },\n [value],\n );\n\n if (editing) {\n return (\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n autoFocus\n className=\"w-14 h-7 px-2 text-xs border border-blue-400 rounded text-center focus:outline-none\"\n />\n );\n }\n\n return (\n <div className=\"relative\">\n <select\n value={String(value)}\n onChange={(e) => {\n const num = parseFloat(e.target.value);\n if (!isNaN(num)) onChange(num);\n }}\n disabled={disabled}\n className=\"w-14 h-7 px-1 text-xs border border-gray-300 rounded bg-white text-center appearance-none cursor-pointer disabled:opacity-40\"\n title=\"글자 크기\"\n onDoubleClick={() => {\n setInputValue(String(value));\n setEditing(true);\n }}\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}\n </option>\n ))}\n {!FONT_SIZES.includes(value as any) && (\n <option value={String(value)}>{value}</option>\n )}\n </select>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Highlighter,\n Type,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { ColorPicker } from \"./ColorPicker\";\n\nexport function CharFormatButtons() {\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const selection = useEditorStore((s) => s.selection);\n const doc = useEditorStore((s) => s.doc);\n const toggleBold = useEditorStore((s) => s.toggleBold);\n const toggleItalic = useEditorStore((s) => s.toggleItalic);\n const toggleUnderline = useEditorStore((s) => s.toggleUnderline);\n\n const disabled = !doc || !selection;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <ColorPicker\n color={extendedFormat.char.textColor || \"#000000\"}\n onChange={() => {\n // Text color change — placeholder for future implementation\n }}\n icon={<Type className=\"w-3.5 h-3.5\" />}\n title=\"글자색\"\n disabled={disabled}\n />\n <ColorPicker\n color={extendedFormat.char.highlightColor || \"#FFFF00\"}\n onChange={() => {\n // Highlight color change — placeholder for future implementation\n }}\n icon={<Highlighter className=\"w-3.5 h-3.5\" />}\n title=\"형광펜\"\n disabled={disabled}\n />\n <ToolbarButton\n icon={<Bold className=\"w-3.5 h-3.5\" />}\n active={activeFormat.bold}\n disabled={disabled}\n onClick={toggleBold}\n title=\"굵게 (Ctrl+B)\"\n />\n <ToolbarButton\n icon={<Italic className=\"w-3.5 h-3.5\" />}\n active={activeFormat.italic}\n disabled={disabled}\n onClick={toggleItalic}\n title=\"기울임 (Ctrl+I)\"\n />\n <ToolbarButton\n icon={<Underline className=\"w-3.5 h-3.5\" />}\n active={activeFormat.underline}\n disabled={disabled}\n onClick={toggleUnderline}\n title=\"밑줄 (Ctrl+U)\"\n />\n <ToolbarButton\n icon={<Strikethrough className=\"w-3.5 h-3.5\" />}\n active={extendedFormat.char.strikethrough}\n disabled={disabled}\n title=\"취소선\"\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\nimport { COLOR_PRESETS } from \"@/lib/constants\";\n\ninterface ColorPickerProps {\n color: string;\n onChange: (color: string) => void;\n icon: ReactNode;\n title?: string;\n disabled?: boolean;\n}\n\nexport function ColorPicker({\n color,\n onChange,\n icon,\n title,\n disabled,\n}: ColorPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n title={title}\n className=\"p-1.5 rounded transition-colors text-gray-600 hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed flex flex-col items-center\"\n >\n {icon}\n <div\n className=\"w-4 h-0.5 mt-0.5 rounded-sm\"\n style={{ backgroundColor: color || \"#000000\" }}\n />\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg p-2\">\n <div className=\"grid grid-cols-8 gap-1\">\n {COLOR_PRESETS.map((c) => (\n <button\n key={c}\n onClick={() => {\n onChange(c);\n setOpen(false);\n }}\n className={`w-5 h-5 rounded border ${\n c === color ? \"border-blue-500 ring-1 ring-blue-300\" : \"border-gray-300\"\n } hover:scale-110 transition-transform`}\n style={{ backgroundColor: c }}\n title={c}\n />\n ))}\n </div>\n <div className=\"mt-2 pt-2 border-t border-gray-100 flex items-center gap-2\">\n <label className=\"text-xs text-gray-500\">커스텀:</label>\n <input\n type=\"color\"\n value={color || \"#000000\"}\n onChange={(e) => {\n onChange(e.target.value);\n setOpen(false);\n }}\n className=\"w-6 h-6 cursor-pointer border-0\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport {\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n Columns2,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport type { AlignmentType } from \"@/lib/constants\";\n\nconst ALIGNMENT_ICONS: Record<AlignmentType, React.ReactNode> = {\n LEFT: <AlignLeft className=\"w-3.5 h-3.5\" />,\n CENTER: <AlignCenter className=\"w-3.5 h-3.5\" />,\n RIGHT: <AlignRight className=\"w-3.5 h-3.5\" />,\n JUSTIFY: <AlignJustify className=\"w-3.5 h-3.5\" />,\n DISTRIBUTE: <Columns2 className=\"w-3.5 h-3.5\" />,\n};\n\nconst ALIGNMENT_LABELS: Record<AlignmentType, string> = {\n LEFT: \"왼쪽 정렬 (Ctrl+L)\",\n CENTER: \"가운데 정렬 (Ctrl+E)\",\n RIGHT: \"오른쪽 정렬 (Ctrl+R)\",\n JUSTIFY: \"양쪽 정렬 (Ctrl+J)\",\n DISTRIBUTE: \"배분 정렬\",\n};\n\nexport function AlignmentButtons() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n\n const disabled = !doc || !selection;\n const currentAlignment = extendedFormat.para.alignment;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n {(Object.keys(ALIGNMENT_ICONS) as AlignmentType[]).map((align) => (\n <ToolbarButton\n key={align}\n icon={ALIGNMENT_ICONS[align]}\n active={currentAlignment === align}\n disabled={disabled}\n title={ALIGNMENT_LABELS[align]}\n />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { LINE_SPACING_OPTIONS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\nexport function LineSpacingControl() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n\n const disabled = !doc || !selection;\n const currentSpacing = extendedFormat.para.lineSpacing;\n\n // Find closest matching option\n const closestValue = LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - currentSpacing) < Math.abs(prev.value - currentSpacing)\n ? curr\n : prev,\n ).value;\n\n const options = LINE_SPACING_OPTIONS.map((o) => ({\n value: String(o.value),\n label: o.label,\n }));\n\n return (\n <ToolbarDropdown\n value={String(closestValue)}\n options={options}\n onChange={() => {\n // Line spacing change — placeholder for future implementation\n }}\n disabled={disabled}\n title=\"줄 간격\"\n width=\"w-14\"\n />\n );\n}\n","\"use client\";\n\nexport function ToolbarDivider() {\n return <div className=\"h-6 w-px bg-gray-200 mx-1 self-center\" />;\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { StyleSelector } from \"./StyleSelector\";\nimport { FontSelector } from \"./FontSelector\";\nimport { FontSizeInput } from \"./FontSizeInput\";\nimport { CharFormatButtons } from \"./CharFormatButtons\";\nimport { AlignmentButtons } from \"./AlignmentButtons\";\nimport { LineSpacingControl } from \"./LineSpacingControl\";\nimport { ToolbarDivider } from \"./ToolbarDivider\";\nimport { Plus } from \"lucide-react\";\n\nexport function SecondaryToolbar() {\n const doc = useEditorStore((s) => s.doc);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const addParagraph = useEditorStore((s) => s.addParagraph);\n\n const disabled = !doc;\n\n return (\n <div className=\"flex items-center gap-1 bg-gray-50 border-b border-gray-200 px-3 py-1 flex-wrap min-h-[36px]\">\n {/* Style selector */}\n <StyleSelector\n value=\"0\"\n onChange={() => {\n // Style change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Font selector */}\n <FontSelector\n value={extendedFormat.char.fontFamily || \"맑은 고딕\"}\n onChange={() => {\n // Font change — placeholder\n }}\n disabled={disabled}\n />\n\n {/* Font size */}\n <FontSizeInput\n value={extendedFormat.char.fontSize || 10}\n onChange={() => {\n // Font size change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Character format buttons */}\n <CharFormatButtons />\n\n <ToolbarDivider />\n\n {/* Alignment buttons */}\n <AlignmentButtons />\n\n <ToolbarDivider />\n\n {/* Line spacing */}\n <LineSpacingControl />\n\n {/* Spacer */}\n <div className=\"flex-1\" />\n\n {/* Add paragraph */}\n <button\n disabled={disabled}\n onClick={() => addParagraph(\"\")}\n className=\"flex items-center gap-1 px-2.5 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n <Plus className=\"w-3 h-3\" />\n 문단 추가\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function HorizontalRuler() {\n const viewModel = useEditorStore((s) => s.viewModel);\n\n if (!viewModel || viewModel.sections.length === 0) return null;\n\n const section = viewModel.sections[0]!;\n const pageWidthPx = section.pageWidthPx;\n const marginLeftPx = section.marginLeftPx;\n const marginRightPx = section.marginRightPx;\n const contentWidthPx = pageWidthPx - marginLeftPx - marginRightPx;\n\n // Generate tick marks in cm\n const cmPerPx = 25.4 / 96 / 10; // px to cm\n const totalCm = contentWidthPx * cmPerPx;\n const ticks: { position: number; label: string; major: boolean }[] = [];\n\n for (let cm = 0; cm <= totalCm + 0.5; cm += 0.5) {\n const px = cm / cmPerPx;\n const major = cm % 1 === 0;\n ticks.push({\n position: px,\n label: major ? String(Math.round(cm)) : \"\",\n major,\n });\n }\n\n return (\n <div className=\"bg-white border-b border-gray-200 overflow-hidden flex-shrink-0\">\n <div className=\"flex justify-center\">\n <div\n className=\"relative h-6\"\n style={{ width: pageWidthPx }}\n >\n {/* Left margin area */}\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{ width: marginLeftPx }}\n />\n {/* Right margin area */}\n <div\n className=\"absolute top-0 right-0 h-full bg-gray-100\"\n style={{ width: marginRightPx }}\n />\n {/* Ruler content area */}\n <div\n className=\"absolute top-0 h-full\"\n style={{ left: marginLeftPx, width: contentWidthPx }}\n >\n {ticks.map((tick, i) => (\n <div\n key={i}\n className=\"absolute bottom-0\"\n style={{ left: tick.position }}\n >\n <div\n className={`w-px ${\n tick.major ? \"h-3 bg-gray-500\" : \"h-1.5 bg-gray-300\"\n }`}\n />\n {tick.label && (\n <span className=\"absolute -top-0.5 left-1/2 -translate-x-1/2 text-[8px] text-gray-400 leading-none\">\n {tick.label}\n </span>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\n\ninterface SidebarSectionProps {\n title: string;\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\nexport function SidebarSection({\n title,\n children,\n defaultOpen = true,\n}: SidebarSectionProps) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <div className=\"border-b border-gray-100\">\n <button\n onClick={() => setOpen(!open)}\n className=\"flex items-center gap-1 w-full px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-50\"\n >\n {open ? (\n <ChevronDown className=\"w-3.5 h-3.5 text-gray-400\" />\n ) : (\n <ChevronRight className=\"w-3.5 h-3.5 text-gray-400\" />\n )}\n {title}\n </button>\n {open && <div className=\"px-3 pb-3\">{children}</div>}\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface SidebarFieldProps {\n label: string;\n children: ReactNode;\n}\n\nexport function SidebarField({ label, children }: SidebarFieldProps) {\n return (\n <div className=\"flex items-center gap-2 mb-2\">\n <span className=\"text-[11px] text-gray-500 w-14 flex-shrink-0\">{label}</span>\n <div className=\"flex-1\">{children}</div>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BorderSettingsProps {\n disabled?: boolean;\n}\n\nexport function BorderSettings({ disabled }: BorderSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"종류\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"solid\">실선</option>\n <option value=\"dashed\">점선</option>\n <option value=\"double\">이중선</option>\n </select>\n </SidebarField>\n <SidebarField label=\"두께\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"0.1mm\">0.1mm</option>\n <option value=\"0.12mm\">0.12mm</option>\n <option value=\"0.3mm\">0.3mm</option>\n <option value=\"0.4mm\">0.4mm</option>\n <option value=\"0.5mm\">0.5mm</option>\n <option value=\"1.0mm\">1.0mm</option>\n </select>\n </SidebarField>\n <SidebarField label=\"색\">\n <input\n type=\"color\"\n defaultValue=\"#000000\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BackgroundSettingsProps {\n disabled?: boolean;\n}\n\nexport function BackgroundSettings({ disabled }: BackgroundSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"채우기\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"color\">색 채우기</option>\n <option value=\"gradient\">그라데이션</option>\n <option value=\"pattern\">무늬</option>\n </select>\n </SidebarField>\n <SidebarField label=\"배경색\">\n <input\n type=\"color\"\n defaultValue=\"#ffffff\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { FONT_FAMILIES, FONT_SIZES } from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function CharFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n\n const disabled = !doc || !selection;\n const cf = extendedFormat.char;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"기본\">\n <SidebarField label=\"스타일\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n defaultValue=\"0\"\n >\n <option value=\"0\">바탕글</option>\n <option value=\"1\">본문</option>\n <option value=\"2\">개요 1</option>\n <option value=\"3\">개요 2</option>\n </select>\n </SidebarField>\n <SidebarField label=\"글꼴\">\n <select\n disabled={disabled}\n value={cf.fontFamily || \"맑은 고딕\"}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_FAMILIES.map((f) => (\n <option key={f} value={f}>\n {f}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"크기\">\n <select\n disabled={disabled}\n value={String(cf.fontSize || 10)}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}pt\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.textColor || \"#000000\"}\n onChange={() => {}}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.textColor || \"#000000\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"꾸밈\">\n <div className=\"flex flex-wrap gap-1 mb-2\">\n <FormatTag label=\"굵게\" active={activeFormat.bold} />\n <FormatTag label=\"기울임\" active={activeFormat.italic} />\n <FormatTag label=\"밑줄\" active={activeFormat.underline} />\n <FormatTag label=\"취소선\" active={cf.strikethrough} />\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"형광펜\">\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.highlightColor && cf.highlightColor !== \"none\" ? cf.highlightColor : \"#FFFF00\"}\n onChange={() => {}}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.highlightColor || \"없음\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n\nfunction FormatTag({ label, active }: { label: string; active: boolean }) {\n return (\n <span\n className={`px-2 py-0.5 rounded text-[10px] border ${\n active\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-gray-50 border-gray-200 text-gray-400\"\n }`}\n >\n {label}\n </span>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport {\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n type AlignmentType,\n} from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function ParaFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n\n const disabled = !doc || !selection;\n const pf = extendedFormat.para;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"정렬\">\n <div className=\"flex gap-1 mb-2\">\n {ALIGNMENT_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n disabled={disabled}\n className={`flex-1 py-1 rounded text-[10px] border transition-colors ${\n pf.alignment === opt.value\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n title={opt.label}\n >\n {opt.value === \"LEFT\" && \"왼\"}\n {opt.value === \"CENTER\" && \"중\"}\n {opt.value === \"RIGHT\" && \"오\"}\n {opt.value === \"JUSTIFY\" && \"양\"}\n {opt.value === \"DISTRIBUTE\" && \"배\"}\n </button>\n ))}\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"여백\">\n <SidebarField label=\"왼쪽\">\n <input\n type=\"number\"\n value={pf.indentLeft}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <input\n type=\"number\"\n value={pf.indentRight}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"첫줄\">\n <input\n type=\"number\"\n value={pf.firstLineIndent}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"간격\">\n <SidebarField label=\"줄 간격\">\n <select\n disabled={disabled}\n value={String(\n LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - pf.lineSpacing) <\n Math.abs(prev.value - pf.lineSpacing)\n ? curr\n : prev,\n ).value,\n )}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {LINE_SPACING_OPTIONS.map((o) => (\n <option key={o.value} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"문단 앞\">\n <input\n type=\"number\"\n value={pf.spacingBefore}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"문단 뒤\">\n <input\n type=\"number\"\n value={pf.spacingAfter}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"줄 나눔\" defaultOpen={false}>\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 한글 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 영어 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 외톨이줄 방지\n </label>\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { CharFormatPanel } from \"./CharFormatPanel\";\nimport { ParaFormatPanel } from \"./ParaFormatPanel\";\nimport { PanelRightClose } from \"lucide-react\";\n\nexport function FormatSidebar() {\n const uiState = useEditorStore((s) => s.uiState);\n const setSidebarTab = useEditorStore((s) => s.setSidebarTab);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n\n if (!uiState.sidebarOpen) return null;\n\n return (\n <div className=\"w-72 border-l border-gray-200 bg-white flex flex-col overflow-hidden flex-shrink-0\">\n {/* Tab header */}\n <div className=\"flex items-center border-b border-gray-200\">\n <button\n onClick={() => setSidebarTab(\"char\")}\n className={`flex-1 py-2 text-xs font-medium text-center transition-colors ${\n uiState.sidebarTab === \"char\"\n ? \"text-blue-600 border-b-2 border-blue-600 bg-blue-50/50\"\n : \"text-gray-500 hover:text-gray-700 hover:bg-gray-50\"\n }`}\n >\n 글자 모양\n </button>\n <button\n onClick={() => setSidebarTab(\"para\")}\n className={`flex-1 py-2 text-xs font-medium text-center transition-colors ${\n uiState.sidebarTab === \"para\"\n ? \"text-blue-600 border-b-2 border-blue-600 bg-blue-50/50\"\n : \"text-gray-500 hover:text-gray-700 hover:bg-gray-50\"\n }`}\n >\n 문단 모양\n </button>\n <button\n onClick={toggleSidebar}\n className=\"p-1.5 mr-1 rounded text-gray-400 hover:text-gray-600 hover:bg-gray-100\"\n title=\"사이드바 닫기\"\n >\n <PanelRightClose className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Tab content */}\n <div className=\"flex-1 overflow-auto\">\n {uiState.sidebarTab === \"char\" ? (\n <CharFormatPanel />\n ) : (\n <ParaFormatPanel />\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback } from \"react\";\nimport type { ParagraphVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { RunSpan } from \"./RunSpan\";\nimport { TableBlock } from \"./TableBlock\";\nimport { ImageBlock } from \"./ImageBlock\";\n\ninterface ParagraphBlockProps {\n paragraph: ParagraphVM;\n sectionIndex: number;\n /** Index of this paragraph within the section's paragraphs array */\n localIndex: number;\n}\n\nfunction alignmentToCSS(alignment: string): React.CSSProperties[\"textAlign\"] {\n switch (alignment.toUpperCase()) {\n case \"CENTER\":\n return \"center\";\n case \"RIGHT\":\n return \"right\";\n case \"JUSTIFY\":\n case \"DISTRIBUTE\":\n return \"justify\";\n default:\n return \"left\";\n }\n}\n\nexport function ParagraphBlock({\n paragraph,\n sectionIndex,\n localIndex,\n}: ParagraphBlockProps) {\n const updateParagraphText = useEditorStore((s) => s.updateParagraphText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const ref = useRef<HTMLDivElement>(null);\n\n const hasTables = paragraph.tables.length > 0;\n const hasImages = paragraph.images.length > 0;\n const hasText = paragraph.runs.length > 0;\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n // Only sync text paragraphs (no tables/images)\n if (!hasTables && !hasImages) {\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (newText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, newText);\n }\n }\n }, [paragraph, sectionIndex, localIndex, hasTables, hasImages, updateParagraphText]);\n\n const handleFocus = useCallback(() => {\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n });\n }, [sectionIndex, localIndex, setSelection]);\n\n // Common paragraph styles\n const paraStyle: React.CSSProperties = {\n textAlign: alignmentToCSS(paragraph.alignment),\n lineHeight: paragraph.lineSpacing,\n marginLeft: paragraph.marginLeftPx || undefined,\n marginRight: paragraph.marginRightPx || undefined,\n textIndent: paragraph.firstLineIndent || undefined,\n paddingTop: paragraph.spacingBefore || undefined,\n paddingBottom: paragraph.spacingAfter || undefined,\n };\n\n // If paragraph has tables, render them\n if (hasTables) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.tables.map((table) => (\n <TableBlock\n key={table.tableIndex}\n table={table}\n sectionIndex={sectionIndex}\n paragraphIndex={localIndex}\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has images, render them\n if (hasImages) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {paragraph.images.map((img, i) => (\n <ImageBlock key={i} image={img} />\n ))}\n </div>\n );\n }\n\n // Normal text paragraph\n return (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none min-h-[1.5em]\"\n style={paraStyle}\n >\n {paragraph.runs.length > 0 ? (\n paragraph.runs.map((run, i) => <RunSpan key={i} run={run} />)\n ) : (\n <br />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport type { RunVM } from \"@/lib/view-model\";\n\ninterface RunSpanProps {\n run: RunVM;\n}\n\nexport function RunSpan({ run }: RunSpanProps) {\n const style: React.CSSProperties = {};\n\n if (run.bold) style.fontWeight = \"bold\";\n if (run.italic) style.fontStyle = \"italic\";\n\n // Text decoration (underline + strikethrough)\n const decorations: string[] = [];\n if (run.underline) decorations.push(\"underline\");\n if (run.strikethrough) decorations.push(\"line-through\");\n if (decorations.length > 0) style.textDecoration = decorations.join(\" \");\n\n if (run.color && run.color !== \"#000000\") style.color = run.color;\n if (run.fontFamily) style.fontFamily = run.fontFamily;\n if (run.fontSize) style.fontSize = `${run.fontSize}pt`;\n if (run.highlightColor) style.backgroundColor = run.highlightColor;\n if (run.letterSpacing) {\n // hwp letter spacing units -> px approximation\n style.letterSpacing = `${run.letterSpacing / 100}px`;\n }\n\n return <span style={style}>{run.text}</span>;\n}\n","\"use client\";\n\nimport { useRef, useCallback } from \"react\";\nimport type { TableCellVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\n\ninterface TableCellProps {\n cell: TableCellVM;\n sectionIndex: number;\n paragraphIndex: number;\n tableIndex: number;\n}\n\nexport function TableCell({\n cell,\n sectionIndex,\n paragraphIndex,\n tableIndex,\n}: TableCellProps) {\n const updateCellText = useEditorStore((s) => s.updateCellText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const ref = useRef<HTMLTableCellElement>(null);\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n if (newText !== cell.text) {\n updateCellText(\n sectionIndex,\n paragraphIndex,\n tableIndex,\n cell.row,\n cell.col,\n newText,\n );\n }\n }, [cell, sectionIndex, paragraphIndex, tableIndex, updateCellText]);\n\n const handleFocus = useCallback(() => {\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"cell\",\n tableIndex,\n row: cell.row,\n col: cell.col,\n });\n }, [sectionIndex, paragraphIndex, tableIndex, cell.row, cell.col, setSelection]);\n\n if (!cell.isAnchor) return null;\n\n return (\n <td\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n colSpan={cell.colSpan > 1 ? cell.colSpan : undefined}\n rowSpan={cell.rowSpan > 1 ? cell.rowSpan : undefined}\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"border border-gray-300 px-2 py-1 text-sm outline-none focus:bg-blue-50\"\n style={{\n minWidth: cell.widthPx > 0 ? cell.widthPx : 40,\n minHeight: cell.heightPx > 0 ? cell.heightPx : 24,\n }}\n >\n {cell.text}\n </td>\n );\n}\n","\"use client\";\n\nimport type { TableVM } from \"@/lib/view-model\";\nimport { TableCell } from \"./TableCell\";\n\ninterface TableBlockProps {\n table: TableVM;\n sectionIndex: number;\n paragraphIndex: number;\n}\n\nexport function TableBlock({ table, sectionIndex, paragraphIndex }: TableBlockProps) {\n return (\n <div className=\"my-2 overflow-x-auto\">\n <table className=\"border-collapse border border-gray-400\">\n <tbody>\n {table.cells.map((row, rIdx) => (\n <tr key={rIdx}>\n {row.map((cell) =>\n cell.isAnchor ? (\n <TableCell\n key={`${cell.row}-${cell.col}`}\n cell={cell}\n sectionIndex={sectionIndex}\n paragraphIndex={paragraphIndex}\n tableIndex={table.tableIndex}\n />\n ) : null,\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n","\"use client\";\n\nimport type { ImageVM } from \"@/lib/view-model\";\n\ninterface ImageBlockProps {\n image: ImageVM;\n}\n\nexport function ImageBlock({ image }: ImageBlockProps) {\n return (\n <div className=\"my-2 flex justify-center\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={image.dataUrl}\n alt=\"\"\n style={{\n width: image.widthPx > 0 ? image.widthPx : undefined,\n height: image.heightPx > 0 ? image.heightPx : undefined,\n maxWidth: \"100%\",\n }}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport type { SectionVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ParagraphBlock } from \"./ParagraphBlock\";\n\ninterface PageProps {\n section: SectionVM;\n}\n\nexport function Page({ section }: PageProps) {\n const addParagraph = useEditorStore((s) => s.addParagraph);\n const revision = useEditorStore((s) => s.revision);\n\n /** Clicking empty area of the page focuses or creates a paragraph */\n const handlePageClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Only react to clicks directly on the page container (not on child elements)\n if (e.target !== e.currentTarget) return;\n // If no paragraphs exist, create one\n if (section.paragraphs.length === 0) {\n addParagraph(\"\");\n return;\n }\n // Otherwise, focus the last paragraph's contenteditable\n const container = e.currentTarget;\n const editables = container.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const last = editables[editables.length - 1];\n if (last) {\n last.focus();\n // Place cursor at end\n const sel = window.getSelection();\n if (sel) {\n sel.selectAllChildren(last);\n sel.collapseToEnd();\n }\n }\n };\n\n return (\n <div\n className=\"bg-white shadow-lg mx-auto mb-8 cursor-text\"\n onClick={handlePageClick}\n style={{\n width: section.pageWidthPx,\n minHeight: section.pageHeightPx,\n paddingTop: section.marginTopPx,\n paddingBottom: section.marginBottomPx,\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n }}\n >\n {section.paragraphs.map((para, idx) => (\n <ParagraphBlock\n key={`${section.sectionIndex}-${idx}-r${revision}`}\n paragraph={para}\n sectionIndex={section.sectionIndex}\n localIndex={idx}\n />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { Page } from \"./Page\";\n\nexport function PageView() {\n const viewModel = useEditorStore((s) => s.viewModel);\n // Subscribe to revision to trigger re-render\n useEditorStore((s) => s.revision);\n\n if (!viewModel) {\n return (\n <div className=\"flex-1 flex items-center justify-center text-gray-400\">\n 문서를 열거나 새 문서를 만드세요.\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-auto bg-gray-200 py-8\">\n {viewModel.sections.map((section) => (\n <Page key={section.sectionIndex} section={section} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useState, useRef } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function FileUpload() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const openFile = useCallback(\n async (file: File) => {\n setLoading(true);\n setError(null);\n try {\n const buffer = await file.arrayBuffer();\n const doc = await HwpxDocument.open(buffer);\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to open file:\", e);\n setError(\"파일을 열 수 없습니다. HWPX 파일인지 확인하세요.\");\n } finally {\n setLoading(false);\n }\n },\n [setDocument, setLoading, setError],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const file = e.dataTransfer.files[0];\n if (file) openFile(file);\n },\n [openFile],\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setDragging(true);\n }, []);\n\n const handleDragLeave = useCallback(() => {\n setDragging(false);\n }, []);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) openFile(file);\n e.target.value = \"\";\n },\n [openFile],\n );\n\n return (\n <div\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onClick={() => inputRef.current?.click()}\n className={`cursor-pointer border-2 border-dashed rounded-lg p-8 text-center transition-colors ${\n dragging\n ? \"border-blue-400 bg-blue-50\"\n : \"border-gray-300 hover:border-gray-400\"\n }`}\n >\n <Upload className=\"w-10 h-10 mx-auto mb-3 text-gray-400\" />\n <p className=\"text-gray-600 font-medium\">\n HWPX 파일을 드래그하거나 클릭하여 선택\n </p>\n <p className=\"text-sm text-gray-400 mt-1\">.hwpx 파일만 지원</p>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\".hwpx\"\n className=\"hidden\"\n onChange={handleChange}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { FilePlus } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { createNewDocument } from \"@/lib/skeleton-loader\";\n\nexport function NewDocumentButton() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const handleClick = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const doc = await createNewDocument();\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to create new document:\", e);\n setError(\"새 문서를 만들 수 없습니다.\");\n } finally {\n setLoading(false);\n }\n }, [setDocument, setLoading, setError]);\n\n return (\n <button\n onClick={handleClick}\n className=\"flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors\"\n >\n <FilePlus className=\"w-5 h-5\" />\n 새 문서\n </button>\n );\n}\n"],"mappings":"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","names":["import_react","import_hwpxcore","import_hwpxcore","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_lucide_react","import_hwpxcore","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime"]}