@ganttloom/gantt-export 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/chunk-JB7HLLAI.js +113 -0
- package/dist/chunk-JB7HLLAI.js.map +1 -0
- package/dist/chunk-PXURNZ6Y.js +272 -0
- package/dist/chunk-PXURNZ6Y.js.map +1 -0
- package/dist/chunk-QPE3ABUG.js +229 -0
- package/dist/chunk-QPE3ABUG.js.map +1 -0
- package/dist/chunk-TYNGUB4V.js +434 -0
- package/dist/chunk-TYNGUB4V.js.map +1 -0
- package/dist/chunk-X5RULSWH.js +125 -0
- package/dist/chunk-X5RULSWH.js.map +1 -0
- package/dist/index.cjs +1167 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/paginate-Z2RycLzz.d.cts +73 -0
- package/dist/paginate-Z2RycLzz.d.ts +73 -0
- package/dist/pdf.cjs +671 -0
- package/dist/pdf.cjs.map +1 -0
- package/dist/pdf.d.cts +13 -0
- package/dist/pdf.d.ts +13 -0
- package/dist/pdf.js +11 -0
- package/dist/pdf.js.map +1 -0
- package/dist/pptx.cjs +827 -0
- package/dist/pptx.cjs.map +1 -0
- package/dist/pptx.d.cts +15 -0
- package/dist/pptx.d.ts +15 -0
- package/dist/pptx.js +12 -0
- package/dist/pptx.js.map +1 -0
- package/dist/xlsx.cjs +256 -0
- package/dist/xlsx.cjs.map +1 -0
- package/dist/xlsx.d.cts +22 -0
- package/dist/xlsx.d.ts +22 -0
- package/dist/xlsx.js +8 -0
- package/dist/xlsx.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pptx.ts","../src/paginate.ts","../src/geom.ts","../src/layout.ts","../src/zip.ts","../src/color.ts","../src/pptx/xml.ts","../src/pptx/shapes.ts","../src/pptx/render.ts","../src/pptx/parts.ts","../src/pptx/index.ts"],"sourcesContent":["export * from \"./pptx/index.js\";\n","import type { GanttRenderModel } from \"@ganttloom/gantt-core\";\n\n/**\n * Shared pagination math used by both the PDF and PPTX writers.\n *\n * A GanttRenderModel can be far taller (many rows) and wider (long date\n * range) than a single printed page/slide. We tile the full model into a\n * grid of (rowBand, colBand) pages: the grid panel (task list columns) is\n * repeated on every page, while the timeline (bars/links/ticks) is sliced\n * into vertical/horizontal bands so nothing is dropped or duplicated.\n */\n\nexport type PageSizeName = \"A4\" | \"Letter\" | \"A3\";\nexport type Orientation = \"portrait\" | \"landscape\";\n\nconst PAGE_SIZES_PT: Record<PageSizeName, { width: number; height: number }> = {\n // Values are the portrait (short-edge width x long-edge height) dimensions\n // in PDF/typographic points (72pt = 1in).\n A4: { width: 595.28, height: 841.89 },\n Letter: { width: 612, height: 792 },\n A3: { width: 841.89, height: 1190.55 },\n};\n\nexport interface Margins {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport interface PageSizeOption {\n name?: PageSizeName;\n orientation?: Orientation;\n /** escape hatch: exact page dimensions in points, overrides name/orientation */\n custom?: { widthPt: number; heightPt: number };\n}\n\nexport interface PaginationOptions {\n pageSize?: PageSizeOption;\n margins?: Partial<Margins>;\n /** px -> pt scale factor. Default 0.75 (96 CSS px/in -> 72pt/in). */\n scale?: number;\n /** override the auto-computed (sum of column widths) grid panel width, in px */\n gridPanelWidthPx?: number;\n}\n\nexport interface Band {\n start: number;\n end: number;\n}\n\nexport interface PageBand {\n rowBand: number;\n colBand: number;\n /** row slice bounds, in model px coordinates (model.rows[].y space) */\n rowStartY: number;\n rowEndY: number;\n /** timeline slice bounds, in model px coordinates (model.bars[].x space) */\n colStartX: number;\n colEndX: number;\n}\n\nexport interface PaginationLayout {\n pageWidthPt: number;\n pageHeightPt: number;\n margins: Margins;\n /** px -> pt scale factor in effect */\n scale: number;\n gridPanelWidthPx: number;\n gridPanelWidthPt: number;\n headerHeightPx: number;\n headerHeightPt: number;\n /** width of the timeline area available per page, in px (model space) */\n timelineWidthPxPerPage: number;\n /** height of the rows area available per page, in px (model space) */\n rowsHeightPxPerPage: number;\n rowBands: Band[];\n colBands: Band[];\n pages: PageBand[];\n rowCount: number;\n colCount: number;\n}\n\nconst DEFAULT_MARGIN_PT = 36; // 0.5in\nconst DEFAULT_SCALE = 0.75; // 96 css px/in -> 72pt/in\nconst MIN_TIMELINE_WIDTH_PT = 50;\nconst MIN_ROWS_HEIGHT_PT = 20;\n\nexport function resolvePageSize(opt?: PageSizeOption): { width: number; height: number } {\n if (opt?.custom) {\n return { width: opt.custom.widthPt, height: opt.custom.heightPt };\n }\n const name = opt?.name ?? \"A4\";\n const base = PAGE_SIZES_PT[name];\n const orientation = opt?.orientation ?? \"landscape\";\n const short = Math.min(base.width, base.height);\n const long = Math.max(base.width, base.height);\n return orientation === \"landscape\" ? { width: long, height: short } : { width: short, height: long };\n}\n\nfunction defaultGridPanelWidthPx(model: GanttRenderModel): number {\n const cols = model.columns ?? [];\n if (cols.length === 0) return 160; // fallback single \"task name\" column\n return cols.reduce((sum, c) => sum + (c.width ?? 120), 0);\n}\n\nexport function computePagination(\n model: GanttRenderModel,\n options: PaginationOptions = {},\n): PaginationLayout {\n const { width: pageWidthPt, height: pageHeightPt } = resolvePageSize(options.pageSize);\n const margins: Margins = {\n top: options.margins?.top ?? DEFAULT_MARGIN_PT,\n right: options.margins?.right ?? DEFAULT_MARGIN_PT,\n bottom: options.margins?.bottom ?? DEFAULT_MARGIN_PT,\n left: options.margins?.left ?? DEFAULT_MARGIN_PT,\n };\n const scale = options.scale ?? DEFAULT_SCALE;\n const gridPanelWidthPx = options.gridPanelWidthPx ?? defaultGridPanelWidthPx(model);\n const gridPanelWidthPt = gridPanelWidthPx * scale;\n const headerHeightPx = model.headerHeight;\n const headerHeightPt = headerHeightPx * scale;\n\n const contentWidthPt = pageWidthPt - margins.left - margins.right;\n const contentHeightPt = pageHeightPt - margins.top - margins.bottom;\n\n const timelineWidthPtPerPage = Math.max(contentWidthPt - gridPanelWidthPt, MIN_TIMELINE_WIDTH_PT);\n const rowsHeightPtPerPage = Math.max(contentHeightPt - headerHeightPt, MIN_ROWS_HEIGHT_PT);\n\n const timelineWidthPxPerPage = timelineWidthPtPerPage / scale;\n const rowsHeightPxPerPage = rowsHeightPtPerPage / scale;\n\n const totalHeightPx = Math.max(model.height, 1);\n const totalWidthPx = Math.max(model.width, 1);\n\n const rowCount = Math.max(1, Math.ceil(totalHeightPx / rowsHeightPxPerPage));\n const colCount = Math.max(1, Math.ceil(totalWidthPx / timelineWidthPxPerPage));\n\n const rowBands: Band[] = [];\n for (let i = 0; i < rowCount; i++) {\n rowBands.push({\n start: i * rowsHeightPxPerPage,\n end: Math.min(totalHeightPx, (i + 1) * rowsHeightPxPerPage),\n });\n }\n const colBands: Band[] = [];\n for (let i = 0; i < colCount; i++) {\n colBands.push({\n start: i * timelineWidthPxPerPage,\n end: Math.min(totalWidthPx, (i + 1) * timelineWidthPxPerPage),\n });\n }\n\n const pages: PageBand[] = [];\n for (let r = 0; r < rowCount; r++) {\n const rowBand = rowBands[r]!;\n for (let c = 0; c < colCount; c++) {\n const colBand = colBands[c]!;\n pages.push({\n rowBand: r,\n colBand: c,\n rowStartY: rowBand.start,\n rowEndY: rowBand.end,\n colStartX: colBand.start,\n colEndX: colBand.end,\n });\n }\n }\n\n return {\n pageWidthPt,\n pageHeightPt,\n margins,\n scale,\n gridPanelWidthPx,\n gridPanelWidthPt,\n headerHeightPx,\n headerHeightPt,\n timelineWidthPxPerPage,\n rowsHeightPxPerPage,\n rowBands,\n colBands,\n pages,\n rowCount,\n colCount,\n };\n}\n\nexport interface ClipRect {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n}\n\n/** Liang-Barsky line-segment clipping against an axis-aligned rectangle. */\nexport function clipSegment(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n rect: ClipRect,\n): { x0: number; y0: number; x1: number; y1: number } | null {\n let t0 = 0;\n let t1 = 1;\n const dx = x1 - x0;\n const dy = y1 - y0;\n const checks: Array<[number, number]> = [\n [-dx, x0 - rect.x0],\n [dx, rect.x1 - x0],\n [-dy, y0 - rect.y0],\n [dy, rect.y1 - y0],\n ];\n for (const [p, q] of checks) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const r = q / p;\n if (p < 0) {\n if (r > t1) return null;\n if (r > t0) t0 = r;\n } else {\n if (r < t0) return null;\n if (r < t1) t1 = r;\n }\n }\n }\n return { x0: x0 + t0 * dx, y0: y0 + t0 * dy, x1: x0 + t1 * dx, y1: y0 + t1 * dy };\n}\n\n/** Clip an axis-aligned rectangle against a band; null if fully outside. */\nexport function clipRect(\n x: number,\n y: number,\n w: number,\n h: number,\n rect: ClipRect,\n): { x: number; y: number; w: number; h: number } | null {\n const x0 = Math.max(x, rect.x0);\n const y0 = Math.max(y, rect.y0);\n const x1 = Math.min(x + w, rect.x1);\n const y1 = Math.min(y + h, rect.y1);\n if (x1 <= x0 || y1 <= y0) return null;\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };\n}\n","import type { GanttRenderBar } from \"@ganttloom/gantt-core\";\nimport { clipSegment, type ClipRect } from \"./paginate.js\";\n\n/**\n * Dependency-link geometry.\n *\n * NOTE on design choice: GanttRenderLink.path is an SVG path \"d\" string\n * produced by gantt-core for on-screen rendering. Rather than writing an SVG\n * path parser (and a bezier-vs-page-boundary clipper) we recompute a simple\n * orthogonal \"elbow\" polyline directly from the two bars' resolved geometry\n * (GanttRenderBar.x/y/width/height, looked up by taskId). This is simpler,\n * avoids a dependency-free SVG parser, and is trivial to clip correctly at\n * page/slide boundaries using straight-line (Liang-Barsky) clipping.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport function computeLinkPolyline(fromBar: GanttRenderBar, toBar: GanttRenderBar): Point[] {\n const x0 = fromBar.x + fromBar.width;\n const y0 = fromBar.y + fromBar.height / 2;\n const x1 = toBar.x;\n const y1 = toBar.y + toBar.height / 2;\n if (Math.abs(y1 - y0) < 0.01) {\n return [{ x: x0, y: y0 }, { x: x1, y: y1 }];\n }\n const midX = x0 + (x1 - x0) / 2;\n return [\n { x: x0, y: y0 },\n { x: midX, y: y0 },\n { x: midX, y: y1 },\n { x: x1, y: y1 },\n ];\n}\n\n/**\n * Clip a polyline against a rectangle, returning zero or more visible\n * sub-polylines (a link that dips outside the band and back in produces\n * multiple disjoint pieces; a fully-outside link produces none).\n */\nexport function clipPolylineToRect(points: Point[], rect: ClipRect): Point[][] {\n const segments: Point[][] = [];\n let current: Point[] = [];\n for (let i = 0; i < points.length - 1; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n const clipped = clipSegment(a.x, a.y, b.x, b.y, rect);\n if (!clipped) {\n if (current.length > 1) segments.push(current);\n current = [];\n continue;\n }\n if (current.length === 0) {\n current.push({ x: clipped.x0, y: clipped.y0 });\n } else {\n const last = current[current.length - 1]!;\n if (Math.abs(last.x - clipped.x0) > 0.01 || Math.abs(last.y - clipped.y0) > 0.01) {\n if (current.length > 1) segments.push(current);\n current = [{ x: clipped.x0, y: clipped.y0 }];\n }\n }\n current.push({ x: clipped.x1, y: clipped.y1 });\n }\n if (current.length > 1) segments.push(current);\n return segments;\n}\n","import type { GanttColumn, GanttRenderModel, GanttTask } from \"@ganttloom/gantt-core\";\nimport type { PageBand, PaginationLayout } from \"./paginate.js\";\nimport { clipRect, type ClipRect } from \"./paginate.js\";\nimport { computeLinkPolyline, clipPolylineToRect, type Point } from \"./geom.js\";\n\n/**\n * Format-agnostic draw commands for one page/slide, in top-down point\n * coordinates relative to the full page (origin at the page's top-left\n * corner, y increasing downward — margins already baked in). Both the PDF\n * writer (which flips y to PDF's bottom-up space) and the PPTX writer\n * (which uses top-down EMUs natively) consume the same list, so the\n * row/column/link walking and clipping logic is written exactly once.\n */\n\nexport interface DrawRect {\n kind: \"rect\";\n x: number;\n y: number;\n w: number;\n h: number;\n fill?: string;\n stroke?: string;\n}\n\nexport interface DrawDiamond {\n kind: \"diamond\";\n cx: number;\n cy: number;\n r: number;\n fill?: string;\n stroke?: string;\n}\n\nexport interface DrawLine {\n kind: \"line\";\n points: Point[];\n stroke: string;\n}\n\nexport interface DrawText {\n kind: \"text\";\n x: number;\n y: number;\n w?: number;\n text: string;\n size: number;\n color: string;\n bold?: boolean;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport type DrawCommand = DrawRect | DrawDiamond | DrawLine | DrawText;\n\nexport interface PageContent {\n widthPt: number;\n heightPt: number;\n commands: DrawCommand[];\n}\n\nfunction columnWidthsPt(model: GanttRenderModel, layout: PaginationLayout): { column: GanttColumn; widthPt: number }[] {\n const columns: GanttColumn[] =\n model.columns.length > 0 ? model.columns : [{ id: \"name\", title: \"Task\" }];\n const naturalTotal = columns.reduce((sum, c) => sum + (c.width ?? 120), 0) || 1;\n return columns.map((column) => ({\n column,\n widthPt: ((column.width ?? 120) / naturalTotal) * layout.gridPanelWidthPt,\n }));\n}\n\nfunction cellText(column: GanttColumn, task: GanttTask | undefined, depth: number): string {\n if (!task) return \"\";\n if (column.accessor) {\n const v = column.accessor(task);\n return v === null || v === undefined ? \"\" : String(v);\n }\n const indent = \" \".repeat(Math.max(0, depth));\n return `${indent}${task.name}`;\n}\n\nexport function buildPageContent(\n model: GanttRenderModel,\n tasks: GanttTask[],\n layout: PaginationLayout,\n page: PageBand,\n): PageContent {\n const { scale, gridPanelWidthPt, headerHeightPt, pageWidthPt, pageHeightPt, margins } = layout;\n const theme = model.theme;\n const tasksById = new Map(tasks.map((t) => [t.id, t]));\n const barsByTaskId = new Map(model.bars.map((b) => [b.taskId, b]));\n const rowsByTaskId = new Map(model.rows.map((r) => [r.taskId, r]));\n\n const commands: DrawCommand[] = [];\n const contentX0 = margins.left;\n const contentY0 = margins.top;\n\n const timelineRect: ClipRect = {\n x0: page.colStartX,\n y0: page.rowStartY,\n x1: page.colEndX,\n y1: page.rowEndY,\n };\n\n // page background\n commands.push({ kind: \"rect\", x: 0, y: 0, w: pageWidthPt, h: pageHeightPt, fill: theme.backgroundColor });\n\n const cols = columnWidthsPt(model, layout);\n\n // -- header row: grid panel column titles + timeline ticks --\n let colCursor = contentX0;\n for (const { column, widthPt } of cols) {\n commands.push({\n kind: \"text\",\n x: colCursor + 4,\n y: contentY0 + headerHeightPt / 2 - 5,\n w: widthPt - 8,\n text: column.title,\n size: 9,\n color: theme.textColor,\n bold: true,\n align: column.align ?? \"left\",\n });\n colCursor += widthPt;\n }\n commands.push({\n kind: \"rect\",\n x: contentX0,\n y: contentY0,\n w: gridPanelWidthPt + (page.colEndX - page.colStartX) * scale,\n h: headerHeightPt,\n stroke: theme.gridColor,\n });\n\n const timelineOriginX = contentX0 + gridPanelWidthPt;\n for (const tick of model.ticks) {\n if (tick.x < page.colStartX || tick.x > page.colEndX) continue;\n const px = timelineOriginX + (tick.x - page.colStartX) * scale;\n if (tick.isWeekend) {\n // faint full-height band is drawn by the caller per-row below; header tick line only here\n }\n commands.push({\n kind: \"line\",\n points: [\n { x: px, y: contentY0 },\n { x: px, y: pageHeightPt - margins.bottom },\n ],\n stroke: tick.isToday ? theme.todayColor : theme.gridColor,\n });\n commands.push({\n kind: \"text\",\n x: px + 2,\n y: contentY0 + headerHeightPt / 2 - 5,\n text: tick.label,\n size: 7,\n color: theme.textColor,\n align: \"left\",\n });\n }\n\n // -- rows: grid panel cells + timeline bars, clipped to this page's row band --\n const rowTop = (y: number) => contentY0 + headerHeightPt + (y - page.rowStartY) * scale;\n\n for (const row of model.rows) {\n if (row.y + row.height <= page.rowStartY || row.y >= page.rowEndY) continue;\n // clip the row's [y, y+height) span to this page's row band (1-D clip)\n const clippedRowY0 = Math.max(row.y, page.rowStartY);\n const clippedRowY1 = Math.min(row.y + row.height, page.rowEndY);\n const rowYTop = rowTop(clippedRowY0);\n const rowHPt = (clippedRowY1 - clippedRowY0) * scale;\n const task = tasksById.get(row.taskId);\n\n // grid panel row cells\n let cx = contentX0;\n for (const { column, widthPt } of cols) {\n commands.push({\n kind: \"text\",\n x: cx + 4,\n y: rowYTop + rowHPt / 2 - 4,\n w: widthPt - 8,\n text: cellText(column, task, row.depth),\n size: 8,\n color: theme.textColor,\n align: column.align ?? \"left\",\n });\n cx += widthPt;\n }\n commands.push({\n kind: \"rect\",\n x: contentX0,\n y: rowYTop,\n w: gridPanelWidthPt + (page.colEndX - page.colStartX) * scale,\n h: rowHPt,\n stroke: theme.gridColor,\n });\n\n // timeline bar for this row\n const bar = barsByTaskId.get(row.taskId);\n if (bar) {\n const clippedBar = clipRect(bar.x, bar.y, bar.width, bar.height, timelineRect);\n if (clippedBar) {\n const bx = timelineOriginX + (clippedBar.x - page.colStartX) * scale;\n const by = rowTop(clippedBar.y);\n const bw = clippedBar.w * scale;\n const bh = clippedBar.h * scale;\n\n if (bar.baseline) {\n const clippedBaseline = clipRect(bar.baseline.x, bar.y, bar.baseline.width, bar.height, timelineRect);\n if (clippedBaseline) {\n commands.push({\n kind: \"rect\",\n x: timelineOriginX + (clippedBaseline.x - page.colStartX) * scale,\n y: rowTop(clippedBaseline.y),\n w: clippedBaseline.w * scale,\n h: clippedBaseline.h * scale,\n fill: theme.baselineColor,\n });\n }\n }\n\n if (bar.isMilestone) {\n const r = bh / 2;\n commands.push({\n kind: \"diamond\",\n cx: bx + r,\n cy: by + r,\n r,\n fill: bar.isCritical ? theme.criticalColor : bar.color,\n stroke: theme.textColor,\n });\n if (bar.label) {\n commands.push({\n kind: \"text\",\n x: bx + bh + 4,\n y: by + bh / 2 - 4,\n text: bar.label,\n size: 8,\n color: theme.textColor,\n });\n }\n } else {\n commands.push({\n kind: \"rect\",\n x: bx,\n y: by,\n w: bw,\n h: bh,\n fill: bar.isCritical ? theme.criticalColor : bar.color,\n });\n if (bar.progressWidth > 0) {\n const clippedProgress = clipRect(bar.x, bar.y, bar.progressWidth, bar.height, timelineRect);\n if (clippedProgress) {\n commands.push({\n kind: \"rect\",\n x: timelineOriginX + (clippedProgress.x - page.colStartX) * scale,\n y: rowTop(clippedProgress.y),\n w: clippedProgress.w * scale,\n h: clippedProgress.h * scale,\n fill: bar.progressColor,\n });\n }\n }\n commands.push({\n kind: \"text\",\n x: bx + 3,\n y: by + bh / 2 - 4,\n text: bar.label,\n size: 8,\n color: theme.textColor,\n });\n }\n }\n }\n }\n\n // -- dependency links, recomputed & clipped per band --\n for (const link of model.links) {\n const fromBar = barsByTaskId.get(link.fromId);\n const toBar = barsByTaskId.get(link.toId);\n if (!fromBar || !toBar) continue;\n // skip entirely if neither endpoint's row is visible on this page at all\n const fromRow = rowsByTaskId.get(link.fromId);\n const toRow = rowsByTaskId.get(link.toId);\n if (!fromRow || !toRow) continue;\n const polyline = computeLinkPolyline(fromBar, toBar);\n const pieces = clipPolylineToRect(polyline, timelineRect);\n for (const piece of pieces) {\n commands.push({\n kind: \"line\",\n points: piece.map((p) => ({\n x: timelineOriginX + (p.x - page.colStartX) * scale,\n y: rowTop(p.y),\n })),\n stroke: link.isCritical ? theme.criticalColor : theme.linkColor,\n });\n }\n }\n\n return { widthPt: pageWidthPt, heightPt: pageHeightPt, commands };\n}\n","/**\n * Minimal from-scratch ZIP writer (no external library).\n *\n * Deliberate simplification: all entries are written STORED (compression\n * method 0, i.e. uncompressed) rather than DEFLATE-compressed. Implementing\n * a correct DEFLATE compressor from scratch is a large undertaking for a\n * low payoff here — PPTX consumers (PowerPoint, Google Slides, LibreOffice\n * Impress) all accept uncompressed/stored zip entries without complaint.\n * The only cost is a somewhat larger file, which is an acceptable trade-off\n * for a dependency-free implementation.\n */\n\nconst encoder = new TextEncoder();\n\n// Standard reflected CRC-32 (polynomial 0xEDB88320), table-based.\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? (0xedb88320 ^ (c >>> 1)) >>> 0 : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i++) {\n crc = (CRC_TABLE[(crc ^ data[i]!) & 0xff]! ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport interface ZipEntryInput {\n name: string;\n data: Uint8Array;\n}\n\nclass ByteWriter {\n private chunks: Uint8Array[] = [];\n private len = 0;\n get length(): number {\n return this.len;\n }\n push(bytes: Uint8Array): void {\n this.chunks.push(bytes);\n this.len += bytes.length;\n }\n pushU16(v: number): void {\n this.push(new Uint8Array([v & 0xff, (v >>> 8) & 0xff]));\n }\n pushU32(v: number): void {\n this.push(new Uint8Array([v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff]));\n }\n pushStr(s: string): void {\n this.push(encoder.encode(s));\n }\n toUint8Array(): Uint8Array {\n const out = new Uint8Array(this.len);\n let o = 0;\n for (const c of this.chunks) {\n out.set(c, o);\n o += c.length;\n }\n return out;\n }\n}\n\nconst DOS_TIME = 0; // 00:00:00\nconst DOS_DATE = (1980 - 1980) << 9; // 1980-01-01, the ZIP epoch\n\nexport function buildZip(entries: ZipEntryInput[]): Uint8Array {\n const w = new ByteWriter();\n const central: { offset: number; entry: ZipEntryInput; crc: number }[] = [];\n\n for (const entry of entries) {\n const nameBytes = encoder.encode(entry.name);\n const crc = crc32(entry.data);\n const offset = w.length;\n\n w.pushU32(0x04034b50); // local file header signature\n w.pushU16(20); // version needed to extract\n w.pushU16(0); // general purpose bit flag\n w.pushU16(0); // compression method: 0 = stored\n w.pushU16(DOS_TIME);\n w.pushU16(DOS_DATE);\n w.pushU32(crc);\n w.pushU32(entry.data.length); // compressed size == uncompressed size (stored)\n w.pushU32(entry.data.length);\n w.pushU16(nameBytes.length);\n w.pushU16(0); // extra field length\n w.push(nameBytes);\n w.push(entry.data);\n\n central.push({ offset, entry, crc });\n }\n\n const centralStart = w.length;\n for (const { offset, entry, crc } of central) {\n const nameBytes = encoder.encode(entry.name);\n w.pushU32(0x02014b50); // central directory file header signature\n w.pushU16(20); // version made by\n w.pushU16(20); // version needed to extract\n w.pushU16(0); // general purpose bit flag\n w.pushU16(0); // compression method: stored\n w.pushU16(DOS_TIME);\n w.pushU16(DOS_DATE);\n w.pushU32(crc);\n w.pushU32(entry.data.length);\n w.pushU32(entry.data.length);\n w.pushU16(nameBytes.length);\n w.pushU16(0); // extra field length\n w.pushU16(0); // file comment length\n w.pushU16(0); // disk number start\n w.pushU16(0); // internal file attributes\n w.pushU32(0); // external file attributes\n w.pushU32(offset); // relative offset of local header\n w.push(nameBytes);\n }\n const centralSize = w.length - centralStart;\n\n // end of central directory record\n w.pushU32(0x06054b50);\n w.pushU16(0); // disk number\n w.pushU16(0); // disk with central directory\n w.pushU16(central.length); // entries on this disk\n w.pushU16(central.length); // total entries\n w.pushU32(centralSize);\n w.pushU32(centralStart);\n w.pushU16(0); // comment length\n\n return w.toUint8Array();\n}\n","/** Parse a CSS-ish color string into 0-1 RGB components. Falls back to black. */\nexport function parseColor(input: string | undefined | null): [number, number, number] {\n if (!input) return [0, 0, 0];\n const s = input.trim();\n const hex = s.match(/^#?([0-9a-fA-F]{6})$/) ?? s.match(/^#?([0-9a-fA-F]{3})$/);\n if (hex) {\n let h = hex[1]!;\n if (h.length === 3) {\n h = h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n const r = parseInt(h.slice(0, 2), 16) / 255;\n const g = parseInt(h.slice(2, 4), 16) / 255;\n const b = parseInt(h.slice(4, 6), 16) / 255;\n return [r, g, b];\n }\n const rgb = s.match(/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i);\n if (rgb) {\n return [Number(rgb[1]) / 255, Number(rgb[2]) / 255, Number(rgb[3]) / 255];\n }\n const named: Record<string, [number, number, number]> = {\n black: [0, 0, 0],\n white: [1, 1, 1],\n red: [1, 0, 0],\n green: [0, 0.5, 0],\n blue: [0, 0, 1],\n gray: [0.5, 0.5, 0.5],\n grey: [0.5, 0.5, 0.5],\n transparent: [1, 1, 1],\n };\n return named[s.toLowerCase()] ?? [0, 0, 0];\n}\n\nfunction toHexByte(v: number): string {\n return Math.round(Math.max(0, Math.min(1, v)) * 255)\n .toString(16)\n .padStart(2, \"0\");\n}\n\n/** Normalize any supported CSS-ish color string to a bare \"RRGGBB\" hex (for OOXML srgbClr). */\nexport function toHexRRGGBB(input: string | undefined | null): string {\n const [r, g, b] = parseColor(input);\n return `${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}`.toUpperCase();\n}\n","/** Escape text for safe inclusion inside XML element content. */\nexport function xmlEscape(input: string): string {\n return input\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import type { DrawCommand, DrawDiamond, DrawLine, DrawRect, DrawText } from \"../layout.js\";\nimport { toHexRRGGBB } from \"../color.js\";\nimport { xmlEscape } from \"./xml.js\";\n\n/** EMU (English Metric Units): 914400 per inch, 12700 per point. */\nconst EMU_PER_PT = 12700;\nconst ptToEmu = (pt: number): number => Math.round(pt * EMU_PER_PT);\n\nfunction alignAttr(align?: \"left\" | \"center\" | \"right\"): string {\n if (align === \"center\") return ' algn=\"ctr\"';\n if (align === \"right\") return ' algn=\"r\"';\n return \"\";\n}\n\nfunction rectShape(id: number, cmd: DrawRect): string {\n const x = ptToEmu(cmd.x);\n const y = ptToEmu(cmd.y);\n const cx = Math.max(ptToEmu(cmd.w), 1);\n const cy = Math.max(ptToEmu(cmd.h), 1);\n const fill = cmd.fill ? `<a:solidFill><a:srgbClr val=\"${toHexRRGGBB(cmd.fill)}\"/></a:solidFill>` : `<a:noFill/>`;\n const line = cmd.stroke\n ? `<a:ln w=\"3175\"><a:solidFill><a:srgbClr val=\"${toHexRRGGBB(cmd.stroke)}\"/></a:solidFill></a:ln>`\n : `<a:ln><a:noFill/></a:ln>`;\n return (\n `<p:sp><p:nvSpPr><p:cNvPr id=\"${id}\" name=\"Rect${id}\"/><p:cNvSpPr/><p:nvPr/></p:nvSpPr>` +\n `<p:spPr><a:xfrm><a:off x=\"${x}\" y=\"${y}\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm>` +\n `<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom>${fill}${line}</p:spPr></p:sp>`\n );\n}\n\nfunction diamondShape(id: number, cmd: DrawDiamond): string {\n const x = ptToEmu(cmd.cx - cmd.r);\n const y = ptToEmu(cmd.cy - cmd.r);\n const size = Math.max(ptToEmu(cmd.r * 2), 1);\n const fill = cmd.fill ? `<a:solidFill><a:srgbClr val=\"${toHexRRGGBB(cmd.fill)}\"/></a:solidFill>` : `<a:noFill/>`;\n const line = cmd.stroke\n ? `<a:ln w=\"3175\"><a:solidFill><a:srgbClr val=\"${toHexRRGGBB(cmd.stroke)}\"/></a:solidFill></a:ln>`\n : `<a:ln><a:noFill/></a:ln>`;\n return (\n `<p:sp><p:nvSpPr><p:cNvPr id=\"${id}\" name=\"Milestone${id}\"/><p:cNvSpPr/><p:nvPr/></p:nvSpPr>` +\n `<p:spPr><a:xfrm><a:off x=\"${x}\" y=\"${y}\"/><a:ext cx=\"${size}\" cy=\"${size}\"/></a:xfrm>` +\n `<a:prstGeom prst=\"diamond\"><a:avLst/></a:prstGeom>${fill}${line}</p:spPr></p:sp>`\n );\n}\n\nfunction textShape(id: number, cmd: DrawText): string {\n const x = ptToEmu(cmd.x);\n const y = ptToEmu(Math.max(cmd.y - 2, 0));\n const cx = Math.max(ptToEmu(cmd.w ?? 300), 1);\n const cy = Math.max(ptToEmu(cmd.size * 1.6), 1);\n const sizeHundredths = Math.round(cmd.size * 100);\n const color = toHexRRGGBB(cmd.color);\n const bold = cmd.bold ? ' b=\"1\"' : \"\";\n return (\n `<p:sp><p:nvSpPr><p:cNvPr id=\"${id}\" name=\"Text${id}\"/><p:cNvSpPr txBox=\"1\"/><p:nvPr/></p:nvSpPr>` +\n `<p:spPr><a:xfrm><a:off x=\"${x}\" y=\"${y}\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm>` +\n `<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/></p:spPr>` +\n `<p:txBody><a:bodyPr wrap=\"none\" lIns=\"0\" tIns=\"0\" rIns=\"0\" bIns=\"0\" anchor=\"t\"/><a:lstStyle/>` +\n `<a:p><a:pPr${alignAttr(cmd.align)}/><a:r><a:rPr lang=\"en-US\" sz=\"${sizeHundredths}\"${bold} dirty=\"0\">` +\n `<a:solidFill><a:srgbClr val=\"${color}\"/></a:solidFill></a:rPr><a:t>${xmlEscape(cmd.text)}</a:t></a:r></a:p>` +\n `</p:txBody></p:sp>`\n );\n}\n\nfunction lineShape(id: number, cmd: DrawLine): string | null {\n if (cmd.points.length < 2) return null;\n const xs = cmd.points.map((p) => ptToEmu(p.x));\n const ys = cmd.points.map((p) => ptToEmu(p.y));\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n const w = Math.max(Math.max(...xs) - minX, 1);\n const h = Math.max(Math.max(...ys) - minY, 1);\n const pathPts = cmd.points\n .map((p, i) => {\n const px = ptToEmu(p.x) - minX;\n const py = ptToEmu(p.y) - minY;\n return i === 0 ? `<a:moveTo><a:pt x=\"${px}\" y=\"${py}\"/></a:moveTo>` : `<a:lnTo><a:pt x=\"${px}\" y=\"${py}\"/></a:lnTo>`;\n })\n .join(\"\");\n const color = toHexRRGGBB(cmd.stroke);\n return (\n `<p:sp><p:nvSpPr><p:cNvPr id=\"${id}\" name=\"Link${id}\"/><p:cNvSpPr/><p:nvPr/></p:nvSpPr>` +\n `<p:spPr><a:xfrm><a:off x=\"${minX}\" y=\"${minY}\"/><a:ext cx=\"${w}\" cy=\"${h}\"/></a:xfrm>` +\n `<a:custGeom><a:avLst/><a:gdLst/><a:ahLst/><a:cxnLst/><a:rect l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>` +\n `<a:pathLst><a:path w=\"${w}\" h=\"${h}\">${pathPts}</a:path></a:pathLst></a:custGeom>` +\n `<a:noFill/><a:ln w=\"9525\"><a:solidFill><a:srgbClr val=\"${color}\"/></a:solidFill></a:ln></p:spPr></p:sp>`\n );\n}\n\n/** Build the `<p:spTree>` shape XML for one slide's draw commands. */\nexport function buildSlideShapesXml(commands: DrawCommand[]): string {\n let id = 2; // id 1 is reserved for the group shape properties element\n const shapes: string[] = [];\n for (const cmd of commands) {\n if (cmd.kind === \"rect\") shapes.push(rectShape(id++, cmd));\n else if (cmd.kind === \"diamond\") shapes.push(diamondShape(id++, cmd));\n else if (cmd.kind === \"text\") shapes.push(textShape(id++, cmd));\n else if (cmd.kind === \"line\") {\n const s = lineShape(id++, cmd);\n if (s) shapes.push(s);\n }\n }\n return shapes.join(\"\");\n}\n","import type { DrawCommand } from \"../layout.js\";\nimport { buildSlideShapesXml } from \"./shapes.js\";\n\nexport function buildSlideXml(commands: DrawCommand[]): string {\n const shapesXml = buildSlideShapesXml(commands);\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n<p:cSld>\n<p:spTree>\n<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>\n<p:grpSpPr/>\n${shapesXml}\n</p:spTree>\n</p:cSld>\n<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>\n</p:sld>`;\n}\n","/**\n * Minimal, hand-written OOXML parts needed for a valid .pptx: content types,\n * package relationships, presentation.xml + its rels, one slide master, one\n * slide layout, a minimal theme, and per-slide XML + rels. Kept as small as\n * PowerPoint/Google Slides/LibreOffice Impress will tolerate — getting the\n * relationship ids and content-type declarations exactly right here is what\n * keeps the file from triggering a \"repair\" prompt.\n */\n\nexport function contentTypesXml(slideCount: number): string {\n const slideOverrides = Array.from(\n { length: slideCount },\n (_, i) =>\n `<Override PartName=\"/ppt/slides/slide${i + 1}.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\"/>`,\n ).join(\"\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n<Default Extension=\"xml\" ContentType=\"application/xml\"/>\n<Override PartName=\"/ppt/presentation.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml\"/>\n<Override PartName=\"/ppt/slideMasters/slideMaster1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml\"/>\n<Override PartName=\"/ppt/slideLayouts/slideLayout1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml\"/>\n<Override PartName=\"/ppt/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/>\n${slideOverrides}\n</Types>`;\n}\n\nexport function rootRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"ppt/presentation.xml\"/>\n</Relationships>`;\n}\n\nexport function presentationXml(slideCount: number, widthEmu: number, heightEmu: number): string {\n const sldIds = Array.from(\n { length: slideCount },\n (_, i) => `<p:sldId id=\"${256 + i}\" r:id=\"rId${i + 2}\"/>`,\n ).join(\"\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<p:presentation xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n<p:sldMasterIdLst><p:sldMasterId id=\"2147483648\" r:id=\"rId1\"/></p:sldMasterIdLst>\n<p:sldIdLst>${sldIds}</p:sldIdLst>\n<p:sldSz cx=\"${Math.round(widthEmu)}\" cy=\"${Math.round(heightEmu)}\"/>\n<p:notesSz cx=\"${Math.round(heightEmu)}\" cy=\"${Math.round(widthEmu)}\"/>\n</p:presentation>`;\n}\n\nexport function presentationRelsXml(slideCount: number): string {\n const slideRels = Array.from(\n { length: slideCount },\n (_, i) =>\n `<Relationship Id=\"rId${i + 2}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"slides/slide${i + 1}.xml\"/>`,\n ).join(\"\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster\" Target=\"slideMasters/slideMaster1.xml\"/>\n${slideRels}\n</Relationships>`;\n}\n\nexport function slideMasterXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<p:sldMaster xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n<p:cSld>\n<p:bg><p:bgRef idx=\"1001\"><a:schemeClr val=\"bg1\"/></p:bgRef></p:bg>\n<p:spTree>\n<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>\n<p:grpSpPr/>\n</p:spTree>\n</p:cSld>\n<p:clrMap bg1=\"lt1\" tx1=\"dk1\" bg2=\"lt2\" tx2=\"dk2\" accent1=\"accent1\" accent2=\"accent2\" accent3=\"accent3\" accent4=\"accent4\" accent5=\"accent5\" accent6=\"accent6\" hlink=\"hlink\" folHlink=\"folHlink\"/>\n<p:sldLayoutIdLst><p:sldLayoutId id=\"2147483649\" r:id=\"rId1\"/></p:sldLayoutIdLst>\n</p:sldMaster>`;\n}\n\nexport function slideMasterRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/slideLayout1.xml\"/>\n<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme1.xml\"/>\n</Relationships>`;\n}\n\nexport function slideLayoutXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<p:sldLayout xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" type=\"blank\" preserve=\"1\">\n<p:cSld name=\"Blank\">\n<p:spTree>\n<p:nvGrpSpPr><p:cNvPr id=\"1\" name=\"\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr>\n<p:grpSpPr/>\n</p:spTree>\n</p:cSld>\n<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>\n</p:sldLayout>`;\n}\n\nexport function slideLayoutRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster\" Target=\"../slideMasters/slideMaster1.xml\"/>\n</Relationships>`;\n}\n\nexport function themeXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"GanttloomExportTheme\">\n<a:themeElements>\n<a:clrScheme name=\"Gantt\">\n<a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1>\n<a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1>\n<a:dk2><a:srgbClr val=\"44546A\"/></a:dk2>\n<a:lt2><a:srgbClr val=\"E7E6E6\"/></a:lt2>\n<a:accent1><a:srgbClr val=\"4472C4\"/></a:accent1>\n<a:accent2><a:srgbClr val=\"ED7D31\"/></a:accent2>\n<a:accent3><a:srgbClr val=\"A5A5A5\"/></a:accent3>\n<a:accent4><a:srgbClr val=\"FFC000\"/></a:accent4>\n<a:accent5><a:srgbClr val=\"5B9BD5\"/></a:accent5>\n<a:accent6><a:srgbClr val=\"70AD47\"/></a:accent6>\n<a:hlink><a:srgbClr val=\"0563C1\"/></a:hlink>\n<a:folHlink><a:srgbClr val=\"954F72\"/></a:folHlink>\n</a:clrScheme>\n<a:fontScheme name=\"Gantt\">\n<a:majorFont><a:latin typeface=\"Calibri\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/></a:majorFont>\n<a:minorFont><a:latin typeface=\"Calibri\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/></a:minorFont>\n</a:fontScheme>\n<a:fmtScheme name=\"Gantt\">\n<a:fillStyleLst>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n</a:fillStyleLst>\n<a:lnStyleLst>\n<a:ln w=\"6350\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln>\n<a:ln w=\"12700\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln>\n<a:ln w=\"19050\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln>\n</a:lnStyleLst>\n<a:effectStyleLst>\n<a:effectStyle><a:effectLst/></a:effectStyle>\n<a:effectStyle><a:effectLst/></a:effectStyle>\n<a:effectStyle><a:effectLst/></a:effectStyle>\n</a:effectStyleLst>\n<a:bgFillStyleLst>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n<a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill>\n</a:bgFillStyleLst>\n</a:fmtScheme>\n</a:themeElements>\n</a:theme>`;\n}\n\nexport function slideRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/slideLayout1.xml\"/>\n</Relationships>`;\n}\n","import type { GanttRenderModel, GanttTask } from \"@ganttloom/gantt-core\";\nimport { computePagination, type PaginationOptions } from \"../paginate.js\";\nimport { buildPageContent } from \"../layout.js\";\nimport { buildZip, type ZipEntryInput } from \"../zip.js\";\nimport { buildSlideXml } from \"./render.js\";\nimport {\n contentTypesXml,\n presentationRelsXml,\n presentationXml,\n rootRelsXml,\n slideLayoutRelsXml,\n slideLayoutXml,\n slideMasterRelsXml,\n slideMasterXml,\n slideRelsXml,\n themeXml,\n} from \"./parts.js\";\n\nexport type PptxExportOptions = PaginationOptions;\n\nconst EMU_PER_PT = 12700;\n\nconst encoder = new TextEncoder();\nfunction textEntry(name: string, xml: string): ZipEntryInput {\n return { name, data: encoder.encode(xml) };\n}\n\n/**\n * Render a GanttRenderModel to a native PPTX (PowerPoint) file, built from\n * scratch: a hand-rolled ZIP container (see ./zip.ts) around hand-written\n * OOXML parts (see ./parts.ts, ./shapes.ts) — no external PPTX/OOXML/zip\n * library. Automatically paginates large charts across multiple slides per\n * `computePagination`.\n */\nexport function renderToPPTX(\n model: GanttRenderModel,\n tasks: GanttTask[],\n options: PptxExportOptions = {},\n): Uint8Array {\n const layout = computePagination(model, options);\n const widthEmu = layout.pageWidthPt * EMU_PER_PT;\n const heightEmu = layout.pageHeightPt * EMU_PER_PT;\n\n const slideXmls = layout.pages.map((page) => {\n const content = buildPageContent(model, tasks, layout, page);\n return buildSlideXml(content.commands);\n });\n\n const entries: ZipEntryInput[] = [\n textEntry(\"[Content_Types].xml\", contentTypesXml(slideXmls.length)),\n textEntry(\"_rels/.rels\", rootRelsXml()),\n textEntry(\"ppt/presentation.xml\", presentationXml(slideXmls.length, widthEmu, heightEmu)),\n textEntry(\"ppt/_rels/presentation.xml.rels\", presentationRelsXml(slideXmls.length)),\n textEntry(\"ppt/slideMasters/slideMaster1.xml\", slideMasterXml()),\n textEntry(\"ppt/slideMasters/_rels/slideMaster1.xml.rels\", slideMasterRelsXml()),\n textEntry(\"ppt/slideLayouts/slideLayout1.xml\", slideLayoutXml()),\n textEntry(\"ppt/slideLayouts/_rels/slideLayout1.xml.rels\", slideLayoutRelsXml()),\n textEntry(\"ppt/theme/theme1.xml\", themeXml()),\n ];\n\n slideXmls.forEach((xml, i) => {\n entries.push(textEntry(`ppt/slides/slide${i + 1}.xml`, xml));\n entries.push(textEntry(`ppt/slides/_rels/slide${i + 1}.xml.rels`, slideRelsXml()));\n });\n\n return buildZip(entries);\n}\n\nexport { computePagination } from \"../paginate.js\";\nexport type { PaginationLayout, PageBand, PageSizeName, Orientation, Margins } from \"../paginate.js\";\n"],"mappings":"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","names":["EMU_PER_PT","encoder"]}
|
package/dist/pptx.d.cts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GanttRenderModel, GanttTask } from '@ganttloom/gantt-core';
|
|
2
|
+
import { c as PaginationOptions } from './paginate-Z2RycLzz.cjs';
|
|
3
|
+
export { M as Margins, O as Orientation, P as PageBand, a as PageSizeName, b as PaginationLayout, d as computePagination } from './paginate-Z2RycLzz.cjs';
|
|
4
|
+
|
|
5
|
+
type PptxExportOptions = PaginationOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Render a GanttRenderModel to a native PPTX (PowerPoint) file, built from
|
|
8
|
+
* scratch: a hand-rolled ZIP container (see ./zip.ts) around hand-written
|
|
9
|
+
* OOXML parts (see ./parts.ts, ./shapes.ts) — no external PPTX/OOXML/zip
|
|
10
|
+
* library. Automatically paginates large charts across multiple slides per
|
|
11
|
+
* `computePagination`.
|
|
12
|
+
*/
|
|
13
|
+
declare function renderToPPTX(model: GanttRenderModel, tasks: GanttTask[], options?: PptxExportOptions): Uint8Array;
|
|
14
|
+
|
|
15
|
+
export { type PptxExportOptions, renderToPPTX };
|
package/dist/pptx.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GanttRenderModel, GanttTask } from '@ganttloom/gantt-core';
|
|
2
|
+
import { c as PaginationOptions } from './paginate-Z2RycLzz.js';
|
|
3
|
+
export { M as Margins, O as Orientation, P as PageBand, a as PageSizeName, b as PaginationLayout, d as computePagination } from './paginate-Z2RycLzz.js';
|
|
4
|
+
|
|
5
|
+
type PptxExportOptions = PaginationOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Render a GanttRenderModel to a native PPTX (PowerPoint) file, built from
|
|
8
|
+
* scratch: a hand-rolled ZIP container (see ./zip.ts) around hand-written
|
|
9
|
+
* OOXML parts (see ./parts.ts, ./shapes.ts) — no external PPTX/OOXML/zip
|
|
10
|
+
* library. Automatically paginates large charts across multiple slides per
|
|
11
|
+
* `computePagination`.
|
|
12
|
+
*/
|
|
13
|
+
declare function renderToPPTX(model: GanttRenderModel, tasks: GanttTask[], options?: PptxExportOptions): Uint8Array;
|
|
14
|
+
|
|
15
|
+
export { type PptxExportOptions, renderToPPTX };
|
package/dist/pptx.js
ADDED
package/dist/pptx.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/xlsx.cjs
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/xlsx.ts
|
|
21
|
+
var xlsx_exports = {};
|
|
22
|
+
__export(xlsx_exports, {
|
|
23
|
+
renderToXLSX: () => renderToXLSX
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(xlsx_exports);
|
|
26
|
+
|
|
27
|
+
// src/zip.ts
|
|
28
|
+
var encoder = new TextEncoder();
|
|
29
|
+
var CRC_TABLE = (() => {
|
|
30
|
+
const table = new Uint32Array(256);
|
|
31
|
+
for (let n = 0; n < 256; n++) {
|
|
32
|
+
let c = n;
|
|
33
|
+
for (let k = 0; k < 8; k++) {
|
|
34
|
+
c = c & 1 ? (3988292384 ^ c >>> 1) >>> 0 : c >>> 1;
|
|
35
|
+
}
|
|
36
|
+
table[n] = c >>> 0;
|
|
37
|
+
}
|
|
38
|
+
return table;
|
|
39
|
+
})();
|
|
40
|
+
function crc32(data) {
|
|
41
|
+
let crc = 4294967295;
|
|
42
|
+
for (let i = 0; i < data.length; i++) {
|
|
43
|
+
crc = (CRC_TABLE[(crc ^ data[i]) & 255] ^ crc >>> 8) >>> 0;
|
|
44
|
+
}
|
|
45
|
+
return (crc ^ 4294967295) >>> 0;
|
|
46
|
+
}
|
|
47
|
+
var ByteWriter = class {
|
|
48
|
+
constructor() {
|
|
49
|
+
this.chunks = [];
|
|
50
|
+
this.len = 0;
|
|
51
|
+
}
|
|
52
|
+
get length() {
|
|
53
|
+
return this.len;
|
|
54
|
+
}
|
|
55
|
+
push(bytes) {
|
|
56
|
+
this.chunks.push(bytes);
|
|
57
|
+
this.len += bytes.length;
|
|
58
|
+
}
|
|
59
|
+
pushU16(v) {
|
|
60
|
+
this.push(new Uint8Array([v & 255, v >>> 8 & 255]));
|
|
61
|
+
}
|
|
62
|
+
pushU32(v) {
|
|
63
|
+
this.push(new Uint8Array([v & 255, v >>> 8 & 255, v >>> 16 & 255, v >>> 24 & 255]));
|
|
64
|
+
}
|
|
65
|
+
pushStr(s) {
|
|
66
|
+
this.push(encoder.encode(s));
|
|
67
|
+
}
|
|
68
|
+
toUint8Array() {
|
|
69
|
+
const out = new Uint8Array(this.len);
|
|
70
|
+
let o = 0;
|
|
71
|
+
for (const c of this.chunks) {
|
|
72
|
+
out.set(c, o);
|
|
73
|
+
o += c.length;
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
var DOS_TIME = 0;
|
|
79
|
+
var DOS_DATE = 1980 - 1980 << 9;
|
|
80
|
+
function buildZip(entries) {
|
|
81
|
+
const w = new ByteWriter();
|
|
82
|
+
const central = [];
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const nameBytes = encoder.encode(entry.name);
|
|
85
|
+
const crc = crc32(entry.data);
|
|
86
|
+
const offset = w.length;
|
|
87
|
+
w.pushU32(67324752);
|
|
88
|
+
w.pushU16(20);
|
|
89
|
+
w.pushU16(0);
|
|
90
|
+
w.pushU16(0);
|
|
91
|
+
w.pushU16(DOS_TIME);
|
|
92
|
+
w.pushU16(DOS_DATE);
|
|
93
|
+
w.pushU32(crc);
|
|
94
|
+
w.pushU32(entry.data.length);
|
|
95
|
+
w.pushU32(entry.data.length);
|
|
96
|
+
w.pushU16(nameBytes.length);
|
|
97
|
+
w.pushU16(0);
|
|
98
|
+
w.push(nameBytes);
|
|
99
|
+
w.push(entry.data);
|
|
100
|
+
central.push({ offset, entry, crc });
|
|
101
|
+
}
|
|
102
|
+
const centralStart = w.length;
|
|
103
|
+
for (const { offset, entry, crc } of central) {
|
|
104
|
+
const nameBytes = encoder.encode(entry.name);
|
|
105
|
+
w.pushU32(33639248);
|
|
106
|
+
w.pushU16(20);
|
|
107
|
+
w.pushU16(20);
|
|
108
|
+
w.pushU16(0);
|
|
109
|
+
w.pushU16(0);
|
|
110
|
+
w.pushU16(DOS_TIME);
|
|
111
|
+
w.pushU16(DOS_DATE);
|
|
112
|
+
w.pushU32(crc);
|
|
113
|
+
w.pushU32(entry.data.length);
|
|
114
|
+
w.pushU32(entry.data.length);
|
|
115
|
+
w.pushU16(nameBytes.length);
|
|
116
|
+
w.pushU16(0);
|
|
117
|
+
w.pushU16(0);
|
|
118
|
+
w.pushU16(0);
|
|
119
|
+
w.pushU16(0);
|
|
120
|
+
w.pushU32(0);
|
|
121
|
+
w.pushU32(offset);
|
|
122
|
+
w.push(nameBytes);
|
|
123
|
+
}
|
|
124
|
+
const centralSize = w.length - centralStart;
|
|
125
|
+
w.pushU32(101010256);
|
|
126
|
+
w.pushU16(0);
|
|
127
|
+
w.pushU16(0);
|
|
128
|
+
w.pushU16(central.length);
|
|
129
|
+
w.pushU16(central.length);
|
|
130
|
+
w.pushU32(centralSize);
|
|
131
|
+
w.pushU32(centralStart);
|
|
132
|
+
w.pushU16(0);
|
|
133
|
+
return w.toUint8Array();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/xlsx/parts.ts
|
|
137
|
+
function contentTypesXml() {
|
|
138
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
139
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
140
|
+
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
|
141
|
+
<Default Extension="xml" ContentType="application/xml"/>
|
|
142
|
+
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
|
143
|
+
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
|
|
144
|
+
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
|
145
|
+
</Types>`;
|
|
146
|
+
}
|
|
147
|
+
function rootRelsXml() {
|
|
148
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
149
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
150
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
|
|
151
|
+
</Relationships>`;
|
|
152
|
+
}
|
|
153
|
+
function workbookXml(sheetName) {
|
|
154
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
155
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
156
|
+
<sheets>
|
|
157
|
+
<sheet name="${escapeXmlAttr(sheetName)}" sheetId="1" r:id="rId1"/>
|
|
158
|
+
</sheets>
|
|
159
|
+
</workbook>`;
|
|
160
|
+
}
|
|
161
|
+
function workbookRelsXml() {
|
|
162
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
163
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
164
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
|
|
165
|
+
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
|
|
166
|
+
</Relationships>`;
|
|
167
|
+
}
|
|
168
|
+
function stylesXml() {
|
|
169
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
170
|
+
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
|
171
|
+
<fonts count="2">
|
|
172
|
+
<font><sz val="11"/><name val="Calibri"/></font>
|
|
173
|
+
<font><sz val="11"/><name val="Calibri"/><b/></font>
|
|
174
|
+
</fonts>
|
|
175
|
+
<fills count="1"><fill><patternFill patternType="none"/></fill></fills>
|
|
176
|
+
<borders count="1"><border/></borders>
|
|
177
|
+
<cellStyleXfs count="1"><xf numFmtId="0" fontId="0"/></cellStyleXfs>
|
|
178
|
+
<cellXfs count="2">
|
|
179
|
+
<xf numFmtId="0" fontId="0" xfId="0"/>
|
|
180
|
+
<xf numFmtId="0" fontId="1" xfId="0" applyFont="1"/>
|
|
181
|
+
</cellXfs>
|
|
182
|
+
</styleSheet>`;
|
|
183
|
+
}
|
|
184
|
+
function escapeXmlText(text) {
|
|
185
|
+
return text.replace(/[&<>]/g, (c) => c === "&" ? "&" : c === "<" ? "<" : ">");
|
|
186
|
+
}
|
|
187
|
+
function escapeXmlAttr(text) {
|
|
188
|
+
return escapeXmlText(text).replace(/"/g, """);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/xlsx/worksheet.ts
|
|
192
|
+
function colLetter(index) {
|
|
193
|
+
let n = index;
|
|
194
|
+
let s = "";
|
|
195
|
+
do {
|
|
196
|
+
s = String.fromCharCode(65 + n % 26) + s;
|
|
197
|
+
n = Math.floor(n / 26) - 1;
|
|
198
|
+
} while (n >= 0);
|
|
199
|
+
return s;
|
|
200
|
+
}
|
|
201
|
+
function buildSheetXml(headerRow, rows) {
|
|
202
|
+
const allRows = [headerRow, ...rows];
|
|
203
|
+
let rowsXml = "";
|
|
204
|
+
allRows.forEach((row, rIdx) => {
|
|
205
|
+
const rowNum = rIdx + 1;
|
|
206
|
+
const styleAttr = rIdx === 0 ? ' s="1"' : "";
|
|
207
|
+
const cellsXml = row.map((val, cIdx) => {
|
|
208
|
+
const ref = `${colLetter(cIdx)}${rowNum}`;
|
|
209
|
+
if (typeof val === "number" && Number.isFinite(val)) {
|
|
210
|
+
return `<c r="${ref}"${styleAttr}><v>${val}</v></c>`;
|
|
211
|
+
}
|
|
212
|
+
const text = escapeXmlText(String(val ?? ""));
|
|
213
|
+
return `<c r="${ref}"${styleAttr} t="inlineStr"><is><t xml:space="preserve">${text}</t></is></c>`;
|
|
214
|
+
}).join("");
|
|
215
|
+
rowsXml += `<row r="${rowNum}">${cellsXml}</row>`;
|
|
216
|
+
});
|
|
217
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
218
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${rowsXml}</sheetData></worksheet>`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/xlsx/index.ts
|
|
222
|
+
var encoder2 = new TextEncoder();
|
|
223
|
+
function textEntry(name, xml) {
|
|
224
|
+
return { name, data: encoder2.encode(xml) };
|
|
225
|
+
}
|
|
226
|
+
var DEFAULT_COLUMNS = [
|
|
227
|
+
{ id: "name", title: "Name" },
|
|
228
|
+
{ id: "start", title: "Start", accessor: (t) => t.start.toISOString().slice(0, 10) },
|
|
229
|
+
{ id: "end", title: "End", accessor: (t) => t.end.toISOString().slice(0, 10) },
|
|
230
|
+
{ id: "progress", title: "Progress %", accessor: (t) => t.progress ?? 0 }
|
|
231
|
+
];
|
|
232
|
+
function renderToXLSX(tasks, options = {}) {
|
|
233
|
+
const columns = options.columns ?? DEFAULT_COLUMNS;
|
|
234
|
+
const headerRow = columns.map((c) => c.title);
|
|
235
|
+
const rows = tasks.map(
|
|
236
|
+
(task) => columns.map((col, colIndex) => {
|
|
237
|
+
const raw = col.accessor ? col.accessor(task) : colIndex === 0 ? task.name : "";
|
|
238
|
+
return raw === null || raw === void 0 ? "" : raw;
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
const sheetName = (options.sheetName ?? "Tasks").slice(0, 31);
|
|
242
|
+
const entries = [
|
|
243
|
+
textEntry("[Content_Types].xml", contentTypesXml()),
|
|
244
|
+
textEntry("_rels/.rels", rootRelsXml()),
|
|
245
|
+
textEntry("xl/workbook.xml", workbookXml(sheetName)),
|
|
246
|
+
textEntry("xl/_rels/workbook.xml.rels", workbookRelsXml()),
|
|
247
|
+
textEntry("xl/styles.xml", stylesXml()),
|
|
248
|
+
textEntry("xl/worksheets/sheet1.xml", buildSheetXml(headerRow, rows))
|
|
249
|
+
];
|
|
250
|
+
return buildZip(entries);
|
|
251
|
+
}
|
|
252
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
253
|
+
0 && (module.exports = {
|
|
254
|
+
renderToXLSX
|
|
255
|
+
});
|
|
256
|
+
//# sourceMappingURL=xlsx.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xlsx.ts","../src/zip.ts","../src/xlsx/parts.ts","../src/xlsx/worksheet.ts","../src/xlsx/index.ts"],"sourcesContent":["export * from \"./xlsx/index.js\";\n","/**\n * Minimal from-scratch ZIP writer (no external library).\n *\n * Deliberate simplification: all entries are written STORED (compression\n * method 0, i.e. uncompressed) rather than DEFLATE-compressed. Implementing\n * a correct DEFLATE compressor from scratch is a large undertaking for a\n * low payoff here — PPTX consumers (PowerPoint, Google Slides, LibreOffice\n * Impress) all accept uncompressed/stored zip entries without complaint.\n * The only cost is a somewhat larger file, which is an acceptable trade-off\n * for a dependency-free implementation.\n */\n\nconst encoder = new TextEncoder();\n\n// Standard reflected CRC-32 (polynomial 0xEDB88320), table-based.\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? (0xedb88320 ^ (c >>> 1)) >>> 0 : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (let i = 0; i < data.length; i++) {\n crc = (CRC_TABLE[(crc ^ data[i]!) & 0xff]! ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nexport interface ZipEntryInput {\n name: string;\n data: Uint8Array;\n}\n\nclass ByteWriter {\n private chunks: Uint8Array[] = [];\n private len = 0;\n get length(): number {\n return this.len;\n }\n push(bytes: Uint8Array): void {\n this.chunks.push(bytes);\n this.len += bytes.length;\n }\n pushU16(v: number): void {\n this.push(new Uint8Array([v & 0xff, (v >>> 8) & 0xff]));\n }\n pushU32(v: number): void {\n this.push(new Uint8Array([v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff]));\n }\n pushStr(s: string): void {\n this.push(encoder.encode(s));\n }\n toUint8Array(): Uint8Array {\n const out = new Uint8Array(this.len);\n let o = 0;\n for (const c of this.chunks) {\n out.set(c, o);\n o += c.length;\n }\n return out;\n }\n}\n\nconst DOS_TIME = 0; // 00:00:00\nconst DOS_DATE = (1980 - 1980) << 9; // 1980-01-01, the ZIP epoch\n\nexport function buildZip(entries: ZipEntryInput[]): Uint8Array {\n const w = new ByteWriter();\n const central: { offset: number; entry: ZipEntryInput; crc: number }[] = [];\n\n for (const entry of entries) {\n const nameBytes = encoder.encode(entry.name);\n const crc = crc32(entry.data);\n const offset = w.length;\n\n w.pushU32(0x04034b50); // local file header signature\n w.pushU16(20); // version needed to extract\n w.pushU16(0); // general purpose bit flag\n w.pushU16(0); // compression method: 0 = stored\n w.pushU16(DOS_TIME);\n w.pushU16(DOS_DATE);\n w.pushU32(crc);\n w.pushU32(entry.data.length); // compressed size == uncompressed size (stored)\n w.pushU32(entry.data.length);\n w.pushU16(nameBytes.length);\n w.pushU16(0); // extra field length\n w.push(nameBytes);\n w.push(entry.data);\n\n central.push({ offset, entry, crc });\n }\n\n const centralStart = w.length;\n for (const { offset, entry, crc } of central) {\n const nameBytes = encoder.encode(entry.name);\n w.pushU32(0x02014b50); // central directory file header signature\n w.pushU16(20); // version made by\n w.pushU16(20); // version needed to extract\n w.pushU16(0); // general purpose bit flag\n w.pushU16(0); // compression method: stored\n w.pushU16(DOS_TIME);\n w.pushU16(DOS_DATE);\n w.pushU32(crc);\n w.pushU32(entry.data.length);\n w.pushU32(entry.data.length);\n w.pushU16(nameBytes.length);\n w.pushU16(0); // extra field length\n w.pushU16(0); // file comment length\n w.pushU16(0); // disk number start\n w.pushU16(0); // internal file attributes\n w.pushU32(0); // external file attributes\n w.pushU32(offset); // relative offset of local header\n w.push(nameBytes);\n }\n const centralSize = w.length - centralStart;\n\n // end of central directory record\n w.pushU32(0x06054b50);\n w.pushU16(0); // disk number\n w.pushU16(0); // disk with central directory\n w.pushU16(central.length); // entries on this disk\n w.pushU16(central.length); // total entries\n w.pushU32(centralSize);\n w.pushU32(centralStart);\n w.pushU16(0); // comment length\n\n return w.toUint8Array();\n}\n","/** Hand-written OOXML parts for a minimal single-sheet .xlsx workbook. */\n\nexport function contentTypesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n</Types>`;\n}\n\nexport function rootRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>`;\n}\n\nexport function workbookXml(sheetName: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets>\n <sheet name=\"${escapeXmlAttr(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/>\n </sheets>\n</workbook>`;\n}\n\nexport function workbookRelsXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>`;\n}\n\n/** Style index 0 = default; index 1 = bold (used for the header row). */\nexport function stylesXml(): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><name val=\"Calibri\"/><b/></font>\n </fonts>\n <fills count=\"1\"><fill><patternFill patternType=\"none\"/></fill></fills>\n <borders count=\"1\"><border/></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"2\">\n <xf numFmtId=\"0\" fontId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"0\" fontId=\"1\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>`;\n}\n\nexport function escapeXmlText(text: string): string {\n return text.replace(/[&<>]/g, (c) => (c === \"&\" ? \"&\" : c === \"<\" ? \"<\" : \">\"));\n}\n\nfunction escapeXmlAttr(text: string): string {\n return escapeXmlText(text).replace(/\"/g, \""\");\n}\n","import { escapeXmlText } from \"./parts.js\";\n\nfunction colLetter(index: number): string {\n let n = index;\n let s = \"\";\n do {\n s = String.fromCharCode(65 + (n % 26)) + s;\n n = Math.floor(n / 26) - 1;\n } while (n >= 0);\n return s;\n}\n\n/** Builds a minimal sheetData: inline strings for text cells, plain <v> for finite numbers, header row styled bold. */\nexport function buildSheetXml(headerRow: string[], rows: (string | number)[][]): string {\n const allRows = [headerRow as (string | number)[], ...rows];\n let rowsXml = \"\";\n allRows.forEach((row, rIdx) => {\n const rowNum = rIdx + 1;\n const styleAttr = rIdx === 0 ? ' s=\"1\"' : \"\";\n const cellsXml = row\n .map((val, cIdx) => {\n const ref = `${colLetter(cIdx)}${rowNum}`;\n if (typeof val === \"number\" && Number.isFinite(val)) {\n return `<c r=\"${ref}\"${styleAttr}><v>${val}</v></c>`;\n }\n const text = escapeXmlText(String(val ?? \"\"));\n return `<c r=\"${ref}\"${styleAttr} t=\"inlineStr\"><is><t xml:space=\"preserve\">${text}</t></is></c>`;\n })\n .join(\"\");\n rowsXml += `<row r=\"${rowNum}\">${cellsXml}</row>`;\n });\n return `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"><sheetData>${rowsXml}</sheetData></worksheet>`;\n}\n","import type { GanttColumn, GanttTask } from \"@ganttloom/gantt-core\";\nimport { buildZip, type ZipEntryInput } from \"../zip.js\";\nimport { buildSheetXml } from \"./worksheet.js\";\nimport { contentTypesXml, rootRelsXml, stylesXml, workbookRelsXml, workbookXml } from \"./parts.js\";\n\nexport interface XlsxExportOptions {\n /** defaults to Name / Start / End / Progress %, using each column's `accessor` like the grid panel does */\n columns?: GanttColumn[];\n /** truncated to 31 chars - the xlsx sheet-name limit. Default \"Tasks\". */\n sheetName?: string;\n}\n\nconst encoder = new TextEncoder();\nfunction textEntry(name: string, xml: string): ZipEntryInput {\n return { name, data: encoder.encode(xml) };\n}\n\nconst DEFAULT_COLUMNS: GanttColumn[] = [\n { id: \"name\", title: \"Name\" },\n { id: \"start\", title: \"Start\", accessor: (t) => t.start.toISOString().slice(0, 10) },\n { id: \"end\", title: \"End\", accessor: (t) => t.end.toISOString().slice(0, 10) },\n { id: \"progress\", title: \"Progress %\", accessor: (t) => t.progress ?? 0 },\n];\n\n/**\n * Export a task list to a native .xlsx spreadsheet, built from scratch: a\n * hand-rolled ZIP container (shared with the PPTX writer) around\n * hand-written OOXML spreadsheet parts. No external xlsx/OOXML library.\n *\n * Unlike renderToPDF/renderToPPTX, this exports the plain task data (via\n * `columns`, same accessor pattern as the grid panel) rather than the\n * rendered chart geometry - a spreadsheet has no use for bar/link\n * coordinates. Dates are written as \"YYYY-MM-DD\" text, not Excel's serial\n * date numbers, to avoid needing number-format/date-system bookkeeping.\n */\nexport function renderToXLSX(tasks: GanttTask[], options: XlsxExportOptions = {}): Uint8Array {\n const columns = options.columns ?? DEFAULT_COLUMNS;\n const headerRow = columns.map((c) => c.title);\n const rows = tasks.map((task) =>\n columns.map((col, colIndex) => {\n const raw = col.accessor ? col.accessor(task) : colIndex === 0 ? task.name : \"\";\n return raw === null || raw === undefined ? \"\" : raw;\n })\n );\n\n const sheetName = (options.sheetName ?? \"Tasks\").slice(0, 31);\n const entries: ZipEntryInput[] = [\n textEntry(\"[Content_Types].xml\", contentTypesXml()),\n textEntry(\"_rels/.rels\", rootRelsXml()),\n textEntry(\"xl/workbook.xml\", workbookXml(sheetName)),\n textEntry(\"xl/_rels/workbook.xml.rels\", workbookRelsXml()),\n textEntry(\"xl/styles.xml\", stylesXml()),\n textEntry(\"xl/worksheets/sheet1.xml\", buildSheetXml(headerRow, rows)),\n ];\n return buildZip(entries);\n}\n"],"mappings":"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","names":["encoder"]}
|
package/dist/xlsx.d.cts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GanttColumn, GanttTask } from '@ganttloom/gantt-core';
|
|
2
|
+
|
|
3
|
+
interface XlsxExportOptions {
|
|
4
|
+
/** defaults to Name / Start / End / Progress %, using each column's `accessor` like the grid panel does */
|
|
5
|
+
columns?: GanttColumn[];
|
|
6
|
+
/** truncated to 31 chars - the xlsx sheet-name limit. Default "Tasks". */
|
|
7
|
+
sheetName?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Export a task list to a native .xlsx spreadsheet, built from scratch: a
|
|
11
|
+
* hand-rolled ZIP container (shared with the PPTX writer) around
|
|
12
|
+
* hand-written OOXML spreadsheet parts. No external xlsx/OOXML library.
|
|
13
|
+
*
|
|
14
|
+
* Unlike renderToPDF/renderToPPTX, this exports the plain task data (via
|
|
15
|
+
* `columns`, same accessor pattern as the grid panel) rather than the
|
|
16
|
+
* rendered chart geometry - a spreadsheet has no use for bar/link
|
|
17
|
+
* coordinates. Dates are written as "YYYY-MM-DD" text, not Excel's serial
|
|
18
|
+
* date numbers, to avoid needing number-format/date-system bookkeeping.
|
|
19
|
+
*/
|
|
20
|
+
declare function renderToXLSX(tasks: GanttTask[], options?: XlsxExportOptions): Uint8Array;
|
|
21
|
+
|
|
22
|
+
export { type XlsxExportOptions, renderToXLSX };
|
package/dist/xlsx.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GanttColumn, GanttTask } from '@ganttloom/gantt-core';
|
|
2
|
+
|
|
3
|
+
interface XlsxExportOptions {
|
|
4
|
+
/** defaults to Name / Start / End / Progress %, using each column's `accessor` like the grid panel does */
|
|
5
|
+
columns?: GanttColumn[];
|
|
6
|
+
/** truncated to 31 chars - the xlsx sheet-name limit. Default "Tasks". */
|
|
7
|
+
sheetName?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Export a task list to a native .xlsx spreadsheet, built from scratch: a
|
|
11
|
+
* hand-rolled ZIP container (shared with the PPTX writer) around
|
|
12
|
+
* hand-written OOXML spreadsheet parts. No external xlsx/OOXML library.
|
|
13
|
+
*
|
|
14
|
+
* Unlike renderToPDF/renderToPPTX, this exports the plain task data (via
|
|
15
|
+
* `columns`, same accessor pattern as the grid panel) rather than the
|
|
16
|
+
* rendered chart geometry - a spreadsheet has no use for bar/link
|
|
17
|
+
* coordinates. Dates are written as "YYYY-MM-DD" text, not Excel's serial
|
|
18
|
+
* date numbers, to avoid needing number-format/date-system bookkeeping.
|
|
19
|
+
*/
|
|
20
|
+
declare function renderToXLSX(tasks: GanttTask[], options?: XlsxExportOptions): Uint8Array;
|
|
21
|
+
|
|
22
|
+
export { type XlsxExportOptions, renderToXLSX };
|
package/dist/xlsx.js
ADDED
package/dist/xlsx.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ganttloom/gantt-export",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Export a @ganttloom/gantt-core chart to native PDF, PPTX, and XLSX files, generated from scratch with zero external PDF/OOXML libraries.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./pdf": {
|
|
16
|
+
"types": "./dist/pdf.d.ts",
|
|
17
|
+
"import": "./dist/pdf.js",
|
|
18
|
+
"require": "./dist/pdf.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./pptx": {
|
|
21
|
+
"types": "./dist/pptx.d.ts",
|
|
22
|
+
"import": "./dist/pptx.js",
|
|
23
|
+
"require": "./dist/pptx.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./xlsx": {
|
|
26
|
+
"types": "./dist/xlsx.d.ts",
|
|
27
|
+
"import": "./dist/xlsx.js",
|
|
28
|
+
"require": "./dist/xlsx.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"keywords": [
|
|
35
|
+
"gantt",
|
|
36
|
+
"export",
|
|
37
|
+
"pdf",
|
|
38
|
+
"pptx",
|
|
39
|
+
"powerpoint",
|
|
40
|
+
"xlsx",
|
|
41
|
+
"excel"
|
|
42
|
+
],
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"author": "Santhoshkumar Hariharan",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/santhoshkumarhari/ganttLoom.git",
|
|
48
|
+
"directory": "packages/gantt-export"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/santhoshkumarhari/ganttLoom/tree/master/packages/gantt-export#readme",
|
|
51
|
+
"bugs": "https://github.com/santhoshkumarhari/ganttLoom/issues",
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@ganttloom/gantt-core": "0.2.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"tsup": "^8.3.5",
|
|
60
|
+
"typescript": "^5.7.2",
|
|
61
|
+
"vitest": "^2.1.8"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsup src/index.ts src/pdf.ts src/pptx.ts src/xlsx.ts --format esm,cjs --dts --sourcemap --clean",
|
|
65
|
+
"dev": "tsup src/index.ts src/pdf.ts src/pptx.ts src/xlsx.ts --format esm,cjs --dts --watch",
|
|
66
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
67
|
+
"test": "vitest run"
|
|
68
|
+
}
|
|
69
|
+
}
|