@files-preview-app/preview-file 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.cjs CHANGED
@@ -465,7 +465,8 @@ function createElement(tag, attrs, ...children) {
465
465
  }
466
466
  var ICON_ZOOM_IN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
467
467
  var ICON_ZOOM_OUT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
468
- var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>`;
468
+ var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><polyline points="11 9 8 12 11 15"></polyline><polyline points="13 9 16 12 13 15"></polyline></svg>`;
469
+ var ICON_FIT_WIDTH = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="2" y1="12" x2="22" y2="12"></line><polyline points="5 9 2 12 5 15"></polyline><polyline points="19 9 22 12 19 15"></polyline><line x1="2" y1="5" x2="2" y2="19"></line><line x1="22" y1="5" x2="22" y2="19"></line></svg>`;
469
470
  var ICON_ROTATE_CW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>`;
470
471
  var ICON_ROTATE_CCW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>`;
471
472
  var ICON_DOWNLOAD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`;
@@ -485,6 +486,7 @@ var ICON_MAP = {
485
486
  "zoom-in": ICON_ZOOM_IN,
486
487
  "zoom-out": ICON_ZOOM_OUT,
487
488
  "fit-page": ICON_FIT_PAGE,
489
+ "fit-width": ICON_FIT_WIDTH,
488
490
  "fit-slide": ICON_FIT_PAGE,
489
491
  "rotate-cw": ICON_ROTATE_CW,
490
492
  "rotate-ccw": ICON_ROTATE_CCW,
@@ -1431,6 +1433,7 @@ var PdfPlugin = class {
1431
1433
  let currentPage = 1;
1432
1434
  let zoomScale = 1;
1433
1435
  let rotation = 0;
1436
+ let fitMode = "width";
1434
1437
  let currentRenderTask = null;
1435
1438
  const renderPage = async (pageNum) => {
1436
1439
  if (currentRenderTask) {
@@ -1450,11 +1453,16 @@ var PdfPlugin = class {
1450
1453
  const containerWidth = container.clientWidth || 900;
1451
1454
  const containerHeight = container.clientHeight || 700;
1452
1455
  const unscaledVp = page.getViewport({ scale: 1, rotation });
1453
- const availWidth = Math.max(100, containerWidth - 48);
1454
- const availHeight = Math.max(100, containerHeight - 88);
1456
+ const availWidth = Math.max(280, containerWidth - 48);
1457
+ const availHeight = Math.max(280, containerHeight - 88);
1455
1458
  const scaleW = availWidth / unscaledVp.width;
1456
1459
  const scaleH = availHeight / unscaledVp.height;
1457
- const fitScale = Math.min(scaleW, scaleH);
1460
+ let fitScale;
1461
+ if (fitMode === "page") {
1462
+ fitScale = Math.max(0.5, Math.min(scaleW, scaleH));
1463
+ } else {
1464
+ fitScale = Math.max(0.65, Math.min(1.15, scaleW));
1465
+ }
1458
1466
  const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
1459
1467
  const pixelRatio = window.devicePixelRatio || 1;
1460
1468
  const viewport = page.getViewport({ scale: effectiveScale, rotation });
@@ -1523,6 +1531,7 @@ var PdfPlugin = class {
1523
1531
  renderPage(currentPage);
1524
1532
  },
1525
1533
  fitToPage: () => {
1534
+ fitMode = fitMode === "width" ? "page" : "width";
1526
1535
  zoomScale = 1;
1527
1536
  rotation = 0;
1528
1537
  renderPage(currentPage);
@@ -1539,6 +1548,7 @@ var PdfPlugin = class {
1539
1548
  getPageCount: () => totalPages,
1540
1549
  getCurrentPage: () => currentPage,
1541
1550
  goToPage: (page) => {
1551
+ container.scrollTop = 0;
1542
1552
  renderPage(page);
1543
1553
  },
1544
1554
  download: () => {
@@ -2043,7 +2053,14 @@ var DocxPlugin = class {
2043
2053
  ignoreFonts: true,
2044
2054
  // Avoid crashes on embedded obfuscated fonts
2045
2055
  breakPages: true,
2046
- experimental: true
2056
+ experimental: true,
2057
+ ignoreLastRenderedPageBreak: false,
2058
+ // Honor Word's exact page breaks!
2059
+ renderHeaders: true,
2060
+ renderFooters: true,
2061
+ renderFootnotes: true,
2062
+ renderEndnotes: true,
2063
+ useBase64URL: true
2047
2064
  });
2048
2065
  if (!ctx.container.contains(wrapper)) {
2049
2066
  ctx.container.appendChild(wrapper);
@@ -2064,11 +2081,14 @@ var DocxPlugin = class {
2064
2081
  renderedSuccessfully = true;
2065
2082
  } catch (fallbackErr) {
2066
2083
  console.error("[DocxPlugin] Native fallback failed:", fallbackErr);
2084
+ const isCorrupt = fallbackErr?.message?.includes("invalid zip") || fallbackErr?.message?.includes("corrupted");
2067
2085
  wrapper.innerHTML = `
2068
- <div style="text-align:center; padding: 48px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06);">
2069
- <div style="font-size:48px; margin-bottom: 16px;">\u{1F4C4}</div>
2070
- <h3 style="margin: 0 0 8px; color: #1e293b;">${ctx.metadata.name || "Word Document"}</h3>
2071
- <p style="color: #64748b; margin: 0;">Could not parse document content</p>
2086
+ <div style="text-align:center; padding: 48px 32px; background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.06); max-width: 600px; margin: 40px auto;">
2087
+ <div style="font-size:48px; margin-bottom: 16px;">${isCorrupt ? "\u26A0\uFE0F" : "\u{1F4C4}"}</div>
2088
+ <h3 style="margin: 0 0 8px; color: #1e293b; font-size: 18px;">${ctx.metadata.name || "Word Document"}</h3>
2089
+ <p style="color: #64748b; margin: 0 0 16px; font-size: 14px; line-height: 1.5;">
2090
+ ${isCorrupt ? "This document appears to be corrupted or contains invalid archive data and cannot be opened (matches Microsoft Word on Windows)." : "Could not render document content. The file structure may be damaged."}
2091
+ </p>
2072
2092
  </div>
2073
2093
  `;
2074
2094
  if (!ctx.container.contains(wrapper)) {
@@ -2076,8 +2096,67 @@ var DocxPlugin = class {
2076
2096
  }
2077
2097
  }
2078
2098
  }
2079
- const sections = wrapper.querySelectorAll("section.docx");
2080
- const cards = wrapper.querySelectorAll(".fp-docx-page-card");
2099
+ let sections = Array.from(wrapper.querySelectorAll("section.docx"));
2100
+ const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
2101
+ if (sections.length === 1 && cards.length === 0) {
2102
+ const singleSec = sections[0];
2103
+ const contentContainer = singleSec.querySelector("article") || singleSec;
2104
+ const children = Array.from(contentContainer.children);
2105
+ const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
2106
+ const secH = singleSec.offsetHeight || singleSec.scrollHeight;
2107
+ if (secH > pageH * 1.25 && children.length > 1) {
2108
+ const childHeights = children.map((c) => {
2109
+ const rectH = c.getBoundingClientRect().height;
2110
+ const offH = c.offsetHeight;
2111
+ const textLen = c.textContent?.trim().length || 0;
2112
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
2113
+ return Math.max(rectH, offH, estH);
2114
+ });
2115
+ const parent = singleSec.parentElement || wrapper;
2116
+ const newSections = [singleSec];
2117
+ const headerEl = singleSec.querySelector("header");
2118
+ const footerEl = singleSec.querySelector("footer");
2119
+ contentContainer.innerHTML = "";
2120
+ singleSec.style.minHeight = `${pageH}px`;
2121
+ singleSec.style.boxSizing = "border-box";
2122
+ let curContent = contentContainer;
2123
+ let curH = 0;
2124
+ const maxH = pageH - 140;
2125
+ for (let i = 0; i < children.length; i++) {
2126
+ const child = children[i];
2127
+ const chH = childHeights[i];
2128
+ curContent.appendChild(child);
2129
+ curH += chH;
2130
+ if (curH >= maxH && i < children.length - 1) {
2131
+ const nextSec = document.createElement("section");
2132
+ nextSec.className = singleSec.className;
2133
+ nextSec.style.cssText = singleSec.style.cssText;
2134
+ nextSec.style.minHeight = `${pageH}px`;
2135
+ nextSec.style.boxSizing = "border-box";
2136
+ nextSec.style.backgroundColor = "#ffffff";
2137
+ nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
2138
+ nextSec.style.borderRadius = "4px";
2139
+ nextSec.style.marginBottom = "24px";
2140
+ if (headerEl) {
2141
+ nextSec.appendChild(headerEl.cloneNode(true));
2142
+ }
2143
+ const nextArticle = document.createElement("article");
2144
+ if (contentContainer.tagName.toLowerCase() === "article") {
2145
+ nextArticle.style.cssText = contentContainer.style.cssText;
2146
+ }
2147
+ nextSec.appendChild(nextArticle);
2148
+ if (footerEl) {
2149
+ nextSec.appendChild(footerEl.cloneNode(true));
2150
+ }
2151
+ parent.appendChild(nextSec);
2152
+ newSections.push(nextSec);
2153
+ curContent = nextArticle;
2154
+ curH = 0;
2155
+ }
2156
+ }
2157
+ sections = newSections;
2158
+ }
2159
+ }
2081
2160
  const pageElements = sections.length > 0 ? sections : cards;
2082
2161
  const totalPages = Math.max(1, pageElements.length);
2083
2162
  let currentPage = 1;
@@ -2114,6 +2193,7 @@ var DocxPlugin = class {
2114
2193
  if (indicator) {
2115
2194
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
2116
2195
  }
2196
+ ctx.container.scrollTop = 0;
2117
2197
  ctx.emit("page-change", { page: currentPage, total: totalPages });
2118
2198
  };
2119
2199
  if (totalPages > 1) {
@@ -2121,22 +2201,27 @@ var DocxPlugin = class {
2121
2201
  }
2122
2202
  scale = 1;
2123
2203
  let rotation = 0;
2124
- const calculateFitScale = () => {
2204
+ let fitMode = "width";
2205
+ const calculateFitScale = (mode = fitMode) => {
2125
2206
  const activeEl = pageElements[currentPage - 1] || wrapper.firstElementChild || wrapper;
2126
2207
  const elW = activeEl.offsetWidth || 816;
2127
- const elH = activeEl.offsetHeight || 1056;
2128
- const availW = Math.max(200, ctx.container.clientWidth - 48);
2129
- const availH = Math.max(200, ctx.container.clientHeight - 80);
2208
+ const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
2209
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
2210
+ const availH = Math.max(280, ctx.container.clientHeight - 80);
2130
2211
  const sW = availW / elW;
2131
- const sH = availH / elH;
2132
- return Math.min(1.1, Math.min(sW, sH));
2212
+ const sH = availH / singlePageH;
2213
+ if (mode === "page") {
2214
+ return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
2215
+ }
2216
+ return Math.max(0.65, Math.min(1.05, sW));
2133
2217
  };
2134
2218
  const applyTransform = () => {
2135
2219
  wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
2136
2220
  wrapper.style.transformOrigin = "top center";
2137
2221
  };
2138
2222
  setTimeout(() => {
2139
- scale = calculateFitScale();
2223
+ fitMode = "width";
2224
+ scale = calculateFitScale("width");
2140
2225
  applyTransform();
2141
2226
  }, 60);
2142
2227
  const cleanup = () => {
@@ -2170,7 +2255,8 @@ var DocxPlugin = class {
2170
2255
  applyTransform();
2171
2256
  },
2172
2257
  fitToPage: () => {
2173
- scale = calculateFitScale();
2258
+ fitMode = fitMode === "width" ? "page" : "width";
2259
+ scale = calculateFitScale(fitMode);
2174
2260
  rotation = 0;
2175
2261
  applyTransform();
2176
2262
  },
@@ -2614,11 +2700,9 @@ var ExcelPlugin = class {
2614
2700
  const calculateFitScale = () => {
2615
2701
  const table = contentArea.querySelector("table");
2616
2702
  if (!table) return 1;
2617
- const availW = Math.max(200, container.clientWidth - 48);
2618
- const availH = Math.max(200, container.clientHeight - 80);
2703
+ const availW = Math.max(280, container.clientWidth - 48);
2619
2704
  const tW = table.offsetWidth || 800;
2620
- const tH = table.offsetHeight || 600;
2621
- return Math.min(1, Math.min(availW / tW, availH / tH));
2705
+ return Math.max(0.65, Math.min(1, availW / tW));
2622
2706
  };
2623
2707
  try {
2624
2708
  wb = XLSX__namespace.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
@@ -3042,17 +3126,39 @@ var CodePlugin = class {
3042
3126
  let rawPages = [];
3043
3127
  if (isTxt) {
3044
3128
  const explicitPages = fullText.split(/(?:\f|\x0C)/);
3129
+ const charsPerLine = 85;
3130
+ const maxVisualLines = 45;
3131
+ const charsPerPage = charsPerLine * maxVisualLines;
3045
3132
  for (const ep of explicitPages) {
3046
3133
  const lines = ep.split(/\r?\n/);
3047
3134
  let currentChunk = [];
3135
+ let currentLines = 0;
3048
3136
  for (let i = 0; i < lines.length; i++) {
3049
- currentChunk.push(lines[i]);
3050
- if (currentChunk.length >= 46) {
3137
+ const line = lines[i];
3138
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
3139
+ if (currentLines + vLines > maxVisualLines && currentChunk.length > 0) {
3051
3140
  rawPages.push(currentChunk.join("\n"));
3052
3141
  currentChunk = [];
3142
+ currentLines = 0;
3143
+ }
3144
+ if (vLines > maxVisualLines) {
3145
+ let remaining = line;
3146
+ while (remaining.length > charsPerPage) {
3147
+ let splitIdx = remaining.lastIndexOf(" ", charsPerPage);
3148
+ if (splitIdx < charsPerPage * 0.75) splitIdx = charsPerPage;
3149
+ rawPages.push(remaining.slice(0, splitIdx));
3150
+ remaining = remaining.slice(splitIdx).trimStart();
3151
+ }
3152
+ if (remaining.length > 0) {
3153
+ currentChunk.push(remaining);
3154
+ currentLines = Math.ceil(remaining.length / charsPerLine);
3155
+ }
3156
+ } else {
3157
+ currentChunk.push(line);
3158
+ currentLines += vLines;
3053
3159
  }
3054
3160
  }
3055
- if (currentChunk.length > 0 || lines.length === 0) {
3161
+ if (currentChunk.length > 0) {
3056
3162
  rawPages.push(currentChunk.join("\n"));
3057
3163
  }
3058
3164
  }
@@ -3162,6 +3268,7 @@ var CodePlugin = class {
3162
3268
  if (indicator) {
3163
3269
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
3164
3270
  }
3271
+ container.scrollTop = 0;
3165
3272
  ctx.emit("page-change", { page: currentPage, total: totalPages });
3166
3273
  };
3167
3274
  if (totalPages > 1) {
@@ -3215,7 +3322,7 @@ var CodePlugin = class {
3215
3322
  fitToPage: () => {
3216
3323
  fontSize = 13;
3217
3324
  rotation = 0;
3218
- zoomLevel = 1;
3325
+ zoomLevel = isTxt ? Math.max(0.65, Math.min(1.05, (container.clientWidth - 48) / 816)) : 1;
3219
3326
  updateTransform();
3220
3327
  },
3221
3328
  rotateCW: () => {
@@ -4197,20 +4304,27 @@ var RtfPlugin = class {
4197
4304
  let scale = 1;
4198
4305
  let rotation = 0;
4199
4306
  let pageElements = [];
4200
- const calculateFitScale = () => {
4307
+ let fitMode = "width";
4308
+ const calculateFitScale = (mode = fitMode) => {
4201
4309
  const activeEl = pageElements[currentPage - 1] || wrapper;
4202
4310
  const elW = activeEl.offsetWidth || 850;
4203
- const elH = activeEl.offsetHeight || 1e3;
4204
- const availW = Math.max(200, ctx.container.clientWidth - 48);
4205
- const availH = Math.max(200, ctx.container.clientHeight - 80);
4206
- return Math.min(1.1, Math.min(availW / elW, availH / elH));
4311
+ const singlePageH = Math.min(activeEl.offsetHeight || 1056, Math.round(elW * 1.32));
4312
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
4313
+ const availH = Math.max(280, ctx.container.clientHeight - 80);
4314
+ const sW = availW / elW;
4315
+ const sH = availH / singlePageH;
4316
+ if (mode === "page") {
4317
+ return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
4318
+ }
4319
+ return Math.max(0.65, Math.min(1.05, sW));
4207
4320
  };
4208
4321
  const applyTransform = () => {
4209
4322
  wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
4210
4323
  wrapper.style.transformOrigin = "top center";
4211
4324
  };
4212
4325
  setTimeout(() => {
4213
- scale = calculateFitScale();
4326
+ fitMode = "width";
4327
+ scale = calculateFitScale("width");
4214
4328
  applyTransform();
4215
4329
  }, 60);
4216
4330
  try {
@@ -4219,11 +4333,60 @@ var RtfPlugin = class {
4219
4333
  }
4220
4334
  const doc = new RTFJS__namespace.Document(ctx.buffer, {});
4221
4335
  const htmlElements = await doc.render();
4222
- pageElements = htmlElements;
4223
- for (let i = 0; i < htmlElements.length; i++) {
4224
- const el = htmlElements[i];
4225
- el.style.display = i === 0 ? "block" : "none";
4226
- wrapper.appendChild(el);
4336
+ if (htmlElements.length === 1) {
4337
+ const singleEl = htmlElements[0];
4338
+ wrapper.appendChild(singleEl);
4339
+ const children = Array.from(singleEl.children);
4340
+ const secH = singleEl.offsetHeight || singleEl.scrollHeight;
4341
+ if (secH > 1300 && children.length > 1) {
4342
+ const childHeights = children.map((c) => {
4343
+ const rectH = c.getBoundingClientRect().height;
4344
+ const offH = c.offsetHeight;
4345
+ const textLen = c.textContent?.trim().length || 0;
4346
+ const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
4347
+ return Math.max(rectH, offH, estH);
4348
+ });
4349
+ wrapper.innerHTML = "";
4350
+ const createRtfCard = () => {
4351
+ const card = document.createElement("div");
4352
+ card.className = "fp-rtf-page-card";
4353
+ card.style.backgroundColor = "#ffffff";
4354
+ card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
4355
+ card.style.borderRadius = "4px";
4356
+ card.style.padding = "72px 56px";
4357
+ card.style.width = "816px";
4358
+ card.style.minHeight = "1056px";
4359
+ card.style.boxSizing = "border-box";
4360
+ card.style.marginBottom = "24px";
4361
+ return card;
4362
+ };
4363
+ let curCard = createRtfCard();
4364
+ wrapper.appendChild(curCard);
4365
+ pageElements = [curCard];
4366
+ let curH = 0;
4367
+ const maxH = 920;
4368
+ for (let i = 0; i < children.length; i++) {
4369
+ const child = children[i];
4370
+ const chH = childHeights[i];
4371
+ curCard.appendChild(child);
4372
+ curH += chH;
4373
+ if (curH >= maxH && i < children.length - 1) {
4374
+ curCard = createRtfCard();
4375
+ wrapper.appendChild(curCard);
4376
+ pageElements.push(curCard);
4377
+ curH = 0;
4378
+ }
4379
+ }
4380
+ } else {
4381
+ pageElements = [singleEl];
4382
+ }
4383
+ } else {
4384
+ pageElements = htmlElements;
4385
+ for (let i = 0; i < htmlElements.length; i++) {
4386
+ const el = htmlElements[i];
4387
+ el.style.display = i === 0 ? "block" : "none";
4388
+ wrapper.appendChild(el);
4389
+ }
4227
4390
  }
4228
4391
  } catch (err) {
4229
4392
  console.warn("[RtfPlugin] RTF render error, fallback text:", err);
@@ -4289,6 +4452,7 @@ var RtfPlugin = class {
4289
4452
  if (indicator) {
4290
4453
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4291
4454
  }
4455
+ ctx.container.scrollTop = 0;
4292
4456
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4293
4457
  };
4294
4458
  if (totalPages > 1) {
@@ -4319,7 +4483,8 @@ var RtfPlugin = class {
4319
4483
  applyTransform();
4320
4484
  },
4321
4485
  fitToPage: () => {
4322
- scale = calculateFitScale();
4486
+ fitMode = fitMode === "width" ? "page" : "width";
4487
+ scale = calculateFitScale(fitMode);
4323
4488
  rotation = 0;
4324
4489
  applyTransform();
4325
4490
  },
@@ -4638,19 +4803,29 @@ var OpenDocumentPlugin = class {
4638
4803
  ctx.container.appendChild(container);
4639
4804
  let scale = 1;
4640
4805
  let rotation = 0;
4641
- const calculateFitScale = () => {
4806
+ let fitMode = "width";
4807
+ const calculateFitScale = (mode = fitMode) => {
4642
4808
  const elW = wrapper.offsetWidth || 850;
4643
- const elH = wrapper.offsetHeight || (isPresentation ? 540 : 1e3);
4644
- const availW = Math.max(200, ctx.container.clientWidth - 48);
4645
- const availH = Math.max(200, ctx.container.clientHeight - 80);
4646
- return Math.min(1, Math.min(availW / elW, availH / elH));
4809
+ const singlePageH = Math.min(wrapper.offsetHeight || 1056, Math.round(elW * 1.32));
4810
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
4811
+ const availH = Math.max(280, ctx.container.clientHeight - 80);
4812
+ const sW = availW / elW;
4813
+ const sH = availH / (isPresentation ? 540 : singlePageH);
4814
+ if (isPresentation) {
4815
+ return Math.min(1, Math.min(sW, sH));
4816
+ }
4817
+ if (mode === "page") {
4818
+ return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
4819
+ }
4820
+ return Math.max(0.65, Math.min(1.05, sW));
4647
4821
  };
4648
4822
  const applyTransform = () => {
4649
4823
  wrapper.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
4650
4824
  wrapper.style.transformOrigin = "top center";
4651
4825
  };
4652
4826
  setTimeout(() => {
4653
- scale = calculateFitScale();
4827
+ fitMode = "width";
4828
+ scale = calculateFitScale("width");
4654
4829
  applyTransform();
4655
4830
  }, 60);
4656
4831
  let currentPage = 1;
@@ -4749,12 +4924,9 @@ var OpenDocumentPlugin = class {
4749
4924
  page.style.backgroundColor = "#ffffff";
4750
4925
  page.style.boxShadow = "0 2px 10px rgba(0,0,0,0.08)";
4751
4926
  page.style.borderRadius = "4px";
4752
- page.style.boxSizing = "border-box";
4753
4927
  page.style.display = idx === 0 ? "block" : "none";
4754
- page.style.position = "absolute";
4755
- page.style.top = "0";
4756
- page.style.left = "50%";
4757
- page.style.transform = "translateX(-50%)";
4928
+ page.style.margin = "0 auto 24px";
4929
+ page.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
4758
4930
  elements.forEach((el) => page.appendChild(el));
4759
4931
  wrapper.appendChild(page);
4760
4932
  slides.push(page);
@@ -4792,6 +4964,7 @@ var OpenDocumentPlugin = class {
4792
4964
  if (indicator) {
4793
4965
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
4794
4966
  }
4967
+ container.scrollTop = 0;
4795
4968
  ctx.emit("page-change", { page: currentPage, total: totalPages });
4796
4969
  };
4797
4970
  return {
@@ -4811,7 +4984,8 @@ var OpenDocumentPlugin = class {
4811
4984
  applyTransform();
4812
4985
  },
4813
4986
  fitToPage: () => {
4814
- scale = calculateFitScale();
4987
+ fitMode = fitMode === "width" ? "page" : "width";
4988
+ scale = calculateFitScale(fitMode);
4815
4989
  rotation = 0;
4816
4990
  applyTransform();
4817
4991
  },
@@ -5283,20 +5457,28 @@ var DocPlugin = class {
5283
5457
  if (indicator) {
5284
5458
  indicator.textContent = `Page ${currentPage} of ${totalPages}`;
5285
5459
  }
5460
+ container.scrollTop = 0;
5286
5461
  ctx.emit("page-change", { page: currentPage, total: totalPages });
5287
5462
  };
5288
5463
  if (totalPages > 1) {
5289
5464
  showPage(1);
5290
5465
  }
5291
- const calculateFitScale = () => {
5466
+ let fitMode = "width";
5467
+ const calculateFitScale = (mode = fitMode) => {
5292
5468
  const elW = 816;
5293
5469
  const elH = 1056;
5294
- const availW = Math.max(200, ctx.container.clientWidth - 48);
5295
- const availH = Math.max(200, ctx.container.clientHeight - 80);
5296
- return Math.min(1.1, Math.min(availW / elW, availH / elH));
5470
+ const availW = Math.max(280, ctx.container.clientWidth - 48);
5471
+ const availH = Math.max(280, ctx.container.clientHeight - 80);
5472
+ const sW = availW / elW;
5473
+ const sH = availH / elH;
5474
+ if (mode === "page") {
5475
+ return Math.max(0.55, Math.min(1.15, Math.min(sW, sH)));
5476
+ }
5477
+ return Math.max(0.65, Math.min(1.05, sW));
5297
5478
  };
5298
5479
  setTimeout(() => {
5299
- scale = calculateFitScale();
5480
+ fitMode = "width";
5481
+ scale = calculateFitScale("width");
5300
5482
  applyTransform();
5301
5483
  }, 60);
5302
5484
  const cleanup = () => {
@@ -5324,7 +5506,8 @@ var DocPlugin = class {
5324
5506
  applyTransform();
5325
5507
  },
5326
5508
  fitToPage: () => {
5327
- scale = calculateFitScale();
5509
+ fitMode = fitMode === "width" ? "page" : "width";
5510
+ scale = calculateFitScale(fitMode);
5328
5511
  rotation = 0;
5329
5512
  applyTransform();
5330
5513
  },
@@ -5452,45 +5635,50 @@ var DocPlugin = class {
5452
5635
  }
5453
5636
  splitIntoPages(text) {
5454
5637
  if (!text) return [""];
5455
- const explicitParts = text.split(/[\x0C\f]|\r?\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\r?\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
5456
- if (explicitParts.length === 0) explicitParts.push(text);
5457
- const maxLinesPerPage = 48;
5638
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
5639
+ const explicitParts = normalized.split(/[\x0C\f]|\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
5640
+ if (explicitParts.length === 0) explicitParts.push(normalized);
5641
+ const maxLinesPerPage = 32;
5642
+ const charsPerLine = 80;
5458
5643
  const finalPages = [];
5459
5644
  for (const part of explicitParts) {
5460
- const lines = part.split(/\r?\n/);
5645
+ const lines = part.split("\n");
5461
5646
  let currentLines = [];
5462
5647
  let count = 0;
5463
5648
  for (const line of lines) {
5464
- currentLines.push(line);
5465
- count++;
5466
- if (count >= maxLinesPerPage) {
5649
+ const vLines = Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
5650
+ if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
5467
5651
  finalPages.push(currentLines.join("\n"));
5468
5652
  currentLines = [];
5469
5653
  count = 0;
5470
5654
  }
5655
+ currentLines.push(line);
5656
+ count += vLines;
5471
5657
  }
5472
5658
  if (currentLines.length > 0) {
5473
5659
  finalPages.push(currentLines.join("\n"));
5474
5660
  }
5475
5661
  }
5476
- return finalPages.length > 0 ? finalPages : [text];
5662
+ return finalPages.length > 0 ? finalPages : [normalized];
5477
5663
  }
5478
5664
  /**
5479
5665
  * Format cleaned extracted text into attractive HTML paragraphs, headings, and lists
5480
5666
  */
5481
5667
  formatDocToHtml(text, filename) {
5482
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").split("\n");
5668
+ const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ").split("\n");
5483
5669
  let html = "";
5484
5670
  let inList = false;
5485
5671
  let tableLines = [];
5486
5672
  const flushTable = () => {
5487
5673
  if (tableLines.length > 0) {
5488
- html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12px;">';
5489
- for (const tLine of tableLines) {
5490
- html += "<tr>";
5491
- const cols = tLine.split(" ");
5674
+ html += '<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 13px; font-family: Calibri, sans-serif;">';
5675
+ for (let rIdx = 0; rIdx < tableLines.length; rIdx++) {
5676
+ const tLine = tableLines[rIdx];
5677
+ const isHeader = rIdx === 0;
5678
+ html += `<tr style="${isHeader ? "background-color: #f8fafc; font-weight: 600;" : ""}">`;
5679
+ const cols = tLine.split(" ").filter((c) => c.trim().length > 0);
5492
5680
  for (const col of cols) {
5493
- html += `<td style="border: 1px solid #cbd5e1; padding: 6px 8px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5681
+ html += `<td style="border: 1px solid #cbd5e1; padding: 8px 12px;">${DOMPurify6__default.default.sanitize(col.trim())}</td>`;
5494
5682
  }
5495
5683
  html += "</tr>";
5496
5684
  }
@@ -5503,27 +5691,18 @@ var DocPlugin = class {
5503
5691
  let line = lines[i];
5504
5692
  let tabCount = (line.match(/\t/g) || []).length;
5505
5693
  if (tabCount > 0) {
5506
- let consecutiveTableLines = 1;
5507
- let j = i + 1;
5508
- while (j < lines.length) {
5509
- const nextTabCount = (lines[j].match(/\t/g) || []).length;
5510
- if (nextTabCount === tabCount) {
5511
- consecutiveTableLines++;
5512
- j++;
5513
- } else {
5514
- break;
5515
- }
5694
+ let j = i;
5695
+ while (j < lines.length && (lines[j].match(/\t/g) || []).length > 0) {
5696
+ j++;
5516
5697
  }
5517
- if (consecutiveTableLines >= 3) {
5518
- if (inList) {
5519
- html += "</ul>";
5520
- inList = false;
5521
- }
5522
- tableLines = lines.slice(i, j);
5523
- flushTable();
5524
- i = j;
5525
- continue;
5698
+ if (inList) {
5699
+ html += "</ul>";
5700
+ inList = false;
5526
5701
  }
5702
+ tableLines = lines.slice(i, j);
5703
+ flushTable();
5704
+ i = j;
5705
+ continue;
5527
5706
  }
5528
5707
  line = line.trim();
5529
5708
  if (!line) {