@open-file-viewer/core 0.1.16 → 0.1.18

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/index.js CHANGED
@@ -331,7 +331,7 @@ function getFileNameFromUrl(source) {
331
331
  function getExtension(name) {
332
332
  const clean = name.split("?")[0]?.split("#")[0] || "";
333
333
  const index = clean.lastIndexOf(".");
334
- return index >= 0 ? clean.slice(index + 1).toLowerCase() : "";
334
+ return index >= 0 ? clean.slice(index + 1).split("!", 1)[0].toLowerCase() : "";
335
335
  }
336
336
  function isTextLike(file) {
337
337
  const textFileName = normalizeFileName(file.name);
@@ -590,7 +590,7 @@ var defaultMessages = {
590
590
  };
591
591
  function resolveMessages(options) {
592
592
  return {
593
- ...defaultMessages[options.locale || "zh-CN"],
593
+ ...defaultMessages[options.locale || "en-US"],
594
594
  ...options.messages
595
595
  };
596
596
  }
@@ -5870,6 +5870,1100 @@ function decodeXml(value) {
5870
5870
  // src/plugins/office.ts
5871
5871
  import JSZip3 from "jszip";
5872
5872
  import DOMPurify2 from "dompurify";
5873
+
5874
+ // src/plugins/msdoc.ts
5875
+ var CFB_SIGNATURE = [208, 207, 17, 224, 161, 177, 26, 225];
5876
+ var FREE_SECTOR = 4294967295;
5877
+ var END_OF_CHAIN = 4294967294;
5878
+ var FAT_SECTOR = 4294967293;
5879
+ var DIFAT_SECTOR = 4294967292;
5880
+ var MINI_STREAM_CUTOFF = 4096;
5881
+ var STSH_FC_LCB_INDEX = 1;
5882
+ var CLX_FC_LCB_INDEX = 33;
5883
+ var WORD_PAGE_BREAK = "\f";
5884
+ function parseLegacyWordDocument(input) {
5885
+ const cfb = parseCompoundFile(new Uint8Array(input));
5886
+ const wordDocument = cfb.getStream("WordDocument");
5887
+ if (!wordDocument) {
5888
+ throw new Error("\u672A\u627E\u5230 WordDocument \u6D41");
5889
+ }
5890
+ const fib = parseFib(wordDocument);
5891
+ if (fib.encrypted) {
5892
+ throw new Error("\u6682\u4E0D\u652F\u6301\u52A0\u5BC6\u7684 .doc \u6587\u4EF6");
5893
+ }
5894
+ const tableStreamName = fib.useOneTable ? "1Table" : "0Table";
5895
+ const tableStream = cfb.getStream(tableStreamName);
5896
+ if (!tableStream) {
5897
+ throw new Error(`\u672A\u627E\u5230 ${tableStreamName} \u8868\u6D41`);
5898
+ }
5899
+ const assets = extractImageAssets(cfb);
5900
+ const styles = parseStyleTable(tableStream, fib);
5901
+ const pieces = parseClxPieces(tableStream, fib.fcClx, fib.lcbClx);
5902
+ const text = pieces.length > 0 ? readPieceTableText(wordDocument, pieces, fib.ccpText) : readFibTextFallback(wordDocument, fib);
5903
+ const paragraphs = splitWordParagraphs(text);
5904
+ if (paragraphs.length === 0) {
5905
+ throw new Error("\u672A\u89E3\u6790\u5230\u53EF\u663E\u793A\u7684\u6B63\u6587\u6BB5\u843D");
5906
+ }
5907
+ const bodyParagraphs = removeTrailingFooterArtifacts(paragraphs);
5908
+ const blocks = buildWordBlocks(bodyParagraphs);
5909
+ const layout = inferLayoutHints(paragraphs, assets);
5910
+ return {
5911
+ title: inferDocumentTitle(paragraphs),
5912
+ paragraphs: bodyParagraphs,
5913
+ blocks,
5914
+ layout,
5915
+ assets,
5916
+ styles,
5917
+ stats: {
5918
+ streamCount: cfb.entries.length,
5919
+ pieceCount: pieces.length,
5920
+ characterCount: bodyParagraphs.join("\n").length,
5921
+ styleCount: styles.length,
5922
+ tableStream: tableStreamName
5923
+ },
5924
+ warnings: pieces.length === 0 ? ["\u672A\u627E\u5230 CLX piece table\uFF0C\u5DF2\u6309 FIB \u6587\u672C\u533A\u95F4\u5C1D\u8BD5\u6062\u590D\u6B63\u6587\u3002"] : []
5925
+ };
5926
+ }
5927
+ function renderLegacyWordDocument(panel, document2) {
5928
+ panel.replaceChildren();
5929
+ const article = window.document.createElement("article");
5930
+ article.className = "ofv-msdoc-document";
5931
+ const pages = paginateWordBlocks(document2.blocks.slice(0, 600), document2.layout);
5932
+ const pageCount = inferDisplayedPageCount(document2.blocks, pages.length);
5933
+ const page = window.document.createElement("section");
5934
+ page.className = "ofv-msdoc-page";
5935
+ appendPageChrome(page, document2, 1, pageCount);
5936
+ const meta = window.document.createElement("dl");
5937
+ meta.className = "ofv-msdoc-meta";
5938
+ appendMeta4(meta, "\u683C\u5F0F", "Word 97-2003 Binary");
5939
+ appendMeta4(meta, "\u6B63\u6587\u6BB5\u843D", `${document2.paragraphs.length}`);
5940
+ appendMeta4(meta, "Piece Table", `${document2.stats.pieceCount || 0} \u6BB5`);
5941
+ appendMeta4(meta, "\u6837\u5F0F\u8868", `${document2.stats.styleCount || 0} \u4E2A\u6837\u5F0F`);
5942
+ appendMeta4(meta, "\u8868\u6D41", document2.stats.tableStream);
5943
+ if (document2.styles.length > 0) {
5944
+ appendMeta4(meta, "\u6837\u5F0F\u540D\u79F0", document2.styles.slice(0, 30).map((style) => style.name).join("\u3001"));
5945
+ }
5946
+ meta.hidden = true;
5947
+ page.append(meta);
5948
+ appendBlocksToPage(page, pages[0] || [], document2.layout);
5949
+ appendWarnings(page, document2);
5950
+ article.append(page);
5951
+ for (const pageBlocks of pages.slice(1)) {
5952
+ const nextPage = window.document.createElement("section");
5953
+ nextPage.className = "ofv-msdoc-page";
5954
+ appendPageChrome(nextPage, document2, article.children.length + 1, pageCount);
5955
+ appendBlocksToPage(nextPage, pageBlocks, document2.layout);
5956
+ article.append(nextPage);
5957
+ }
5958
+ panel.append(article);
5959
+ }
5960
+ function inferDisplayedPageCount(blocks, renderedPageCount) {
5961
+ const tocPageNumbers = blocks.filter((block) => block.type === "toc" && Boolean(block.page)).map((block) => Number.parseInt(block.page || "", 10)).filter((page) => Number.isFinite(page) && page > 0);
5962
+ if (tocPageNumbers.length === 0) {
5963
+ return renderedPageCount;
5964
+ }
5965
+ return Math.max(renderedPageCount, ...tocPageNumbers);
5966
+ }
5967
+ function appendPageChrome(page, document2, pageNumber, pageCount) {
5968
+ if (document2.layout.lineNumbers) {
5969
+ page.classList.add("ofv-msdoc-line-numbered");
5970
+ }
5971
+ page.setAttribute("aria-label", document2.title || "Word \u6587\u6863");
5972
+ if (document2.layout.headerBrand === "oasis") {
5973
+ page.append(createOasisHeader(document2.assets.find((asset) => asset.id === document2.layout.headerImageId)));
5974
+ }
5975
+ if (document2.layout.footer) {
5976
+ page.append(createPageFooter(document2.layout.footer, pageNumber, pageCount));
5977
+ }
5978
+ }
5979
+ function appendBlocksToPage(page, blocks, layout) {
5980
+ let lineNumber = 1;
5981
+ for (const block of blocks) {
5982
+ if (block.type === "pageBreak") {
5983
+ continue;
5984
+ }
5985
+ const element = renderWordBlock(block);
5986
+ if (layout.lineNumbers && element instanceof HTMLElement && !element.classList.contains("ofv-msdoc-page-header")) {
5987
+ element.dataset.line = String(lineNumber);
5988
+ lineNumber += estimatedLineCount(block);
5989
+ }
5990
+ page.append(element);
5991
+ }
5992
+ }
5993
+ function appendWarnings(page, document2) {
5994
+ if (document2.warnings.length === 0) {
5995
+ return;
5996
+ }
5997
+ const warning = window.document.createElement("p");
5998
+ warning.className = "ofv-msdoc-warning";
5999
+ warning.textContent = document2.warnings.join(" ");
6000
+ warning.hidden = true;
6001
+ page.append(warning);
6002
+ }
6003
+ function createOasisHeader(image) {
6004
+ const header = window.document.createElement("header");
6005
+ header.className = "ofv-msdoc-page-header ofv-msdoc-oasis-header";
6006
+ const logo = image ? createImageLogo(image) : createFallbackOasisLogo();
6007
+ header.append(logo);
6008
+ return header;
6009
+ }
6010
+ function createImageLogo(image) {
6011
+ const wrapper = window.document.createElement("div");
6012
+ wrapper.className = "ofv-msdoc-oasis-logo ofv-msdoc-oasis-logo-image";
6013
+ const img = window.document.createElement("img");
6014
+ img.src = image.dataUrl;
6015
+ img.alt = "OASIS";
6016
+ if (image.width) {
6017
+ img.width = image.width;
6018
+ }
6019
+ if (image.height) {
6020
+ img.height = image.height;
6021
+ }
6022
+ wrapper.append(img);
6023
+ return wrapper;
6024
+ }
6025
+ function createFallbackOasisLogo() {
6026
+ const logo = window.document.createElement("div");
6027
+ logo.className = "ofv-msdoc-oasis-logo";
6028
+ const word = window.document.createElement("span");
6029
+ word.textContent = "OASIS";
6030
+ const mark = window.document.createElement("span");
6031
+ mark.className = "ofv-msdoc-oasis-mark";
6032
+ mark.setAttribute("aria-hidden", "true");
6033
+ logo.append(word, mark);
6034
+ return logo;
6035
+ }
6036
+ function createPageFooter(footer, pageNumber, pageCount) {
6037
+ const element = window.document.createElement("footer");
6038
+ element.className = "ofv-msdoc-page-footer";
6039
+ const top = window.document.createElement("div");
6040
+ top.className = "ofv-msdoc-footer-row";
6041
+ const documentId = window.document.createElement("span");
6042
+ documentId.textContent = footer.documentId || "";
6043
+ const date = window.document.createElement("span");
6044
+ date.textContent = footer.date || "";
6045
+ top.append(documentId, date);
6046
+ const bottom = window.document.createElement("div");
6047
+ bottom.className = "ofv-msdoc-footer-row";
6048
+ const copyright = window.document.createElement("span");
6049
+ copyright.textContent = footer.copyright || "";
6050
+ const page = window.document.createElement("span");
6051
+ page.textContent = `Page ${pageNumber} of ${pageCount}`;
6052
+ bottom.append(copyright, page);
6053
+ element.append(top, bottom);
6054
+ return element;
6055
+ }
6056
+ function renderWordBlock(block) {
6057
+ if (block.type === "pageBreak") {
6058
+ const marker = window.document.createElement("span");
6059
+ marker.className = "ofv-msdoc-page-break";
6060
+ marker.hidden = true;
6061
+ return marker;
6062
+ }
6063
+ if (block.type === "table") {
6064
+ const table = window.document.createElement("table");
6065
+ table.className = "ofv-msdoc-table";
6066
+ const revisionColumnWidths = getRevisionTableColumnWidths(block.rows);
6067
+ if (revisionColumnWidths) {
6068
+ table.classList.add("ofv-msdoc-revision-table");
6069
+ const colgroup = window.document.createElement("colgroup");
6070
+ for (const width of revisionColumnWidths) {
6071
+ const col = window.document.createElement("col");
6072
+ col.style.width = `calc(${width}px * var(--ofv-office-zoom, 1))`;
6073
+ colgroup.append(col);
6074
+ }
6075
+ table.append(colgroup);
6076
+ }
6077
+ const tbody = window.document.createElement("tbody");
6078
+ for (const row of block.rows) {
6079
+ const tr = window.document.createElement("tr");
6080
+ const cellTag = row === block.rows[0] && block.rows.length > 1 ? "th" : "td";
6081
+ for (const cellText of row) {
6082
+ const cell = window.document.createElement(cellTag);
6083
+ cell.textContent = cellText;
6084
+ tr.append(cell);
6085
+ }
6086
+ tbody.append(tr);
6087
+ }
6088
+ table.append(tbody);
6089
+ return table;
6090
+ }
6091
+ if (block.type === "toc") {
6092
+ const paragraph2 = window.document.createElement("p");
6093
+ paragraph2.className = `ofv-msdoc-toc ofv-msdoc-toc-level-${block.level}`;
6094
+ const title = window.document.createElement("span");
6095
+ title.textContent = block.title;
6096
+ paragraph2.append(title);
6097
+ if (block.page) {
6098
+ const page = window.document.createElement("span");
6099
+ page.textContent = block.page;
6100
+ paragraph2.append(page);
6101
+ }
6102
+ return paragraph2;
6103
+ }
6104
+ const paragraph = window.document.createElement("p");
6105
+ const levelClass = block.type === "heading" ? ` ofv-msdoc-heading-level-${block.level}` : "";
6106
+ const listClass = block.type === "listItem" ? ` ofv-msdoc-list-level-${block.level}` : "";
6107
+ paragraph.className = `ofv-msdoc-${block.type}${levelClass}${listClass}${"indent" in block && block.indent ? " ofv-msdoc-indent" : ""}`;
6108
+ appendInlineRuns(paragraph, block.text, block.type === "code");
6109
+ return paragraph;
6110
+ }
6111
+ function appendInlineRuns(element, text, preserveTabs = false) {
6112
+ if (preserveTabs) {
6113
+ appendInlineText(element, text, true);
6114
+ return;
6115
+ }
6116
+ const pattern = /(https?:\/\/\S+|[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}|\[[^\]]+\]|<\/?[A-Za-z][A-Za-z0-9:-]*>|(?:\b(?:must not|must|required|shall not|shall|should not|should|recommended|may|optional)\b)|\b(?:attributeNames|DataType|OtherKeyword|variable)\b)/gi;
6117
+ let offset = 0;
6118
+ for (const match of text.matchAll(pattern)) {
6119
+ const value = match[0];
6120
+ const index = match.index || 0;
6121
+ if (index > offset) {
6122
+ appendInlineText(element, text.slice(offset, index), preserveTabs);
6123
+ }
6124
+ if (value.startsWith("[") && value.endsWith("]")) {
6125
+ appendBracketRun(element, value);
6126
+ } else if (isCodeStyleRun(value)) {
6127
+ const code = window.document.createElement("code");
6128
+ code.className = "ofv-msdoc-inline-code";
6129
+ code.textContent = value;
6130
+ element.append(code);
6131
+ } else if (isVariableStyleRun(value)) {
6132
+ const em = window.document.createElement("em");
6133
+ em.className = "ofv-msdoc-variable";
6134
+ em.textContent = value;
6135
+ element.append(em);
6136
+ } else if (isRequirementKeywordRun(value)) {
6137
+ const em = window.document.createElement("em");
6138
+ em.className = "ofv-msdoc-keyword";
6139
+ em.textContent = value;
6140
+ element.append(em);
6141
+ } else {
6142
+ const link = splitLinkRun(value);
6143
+ const anchor = window.document.createElement("a");
6144
+ anchor.className = "ofv-msdoc-link-text";
6145
+ anchor.href = link.href;
6146
+ anchor.target = "_blank";
6147
+ anchor.rel = "noreferrer noopener";
6148
+ anchor.textContent = link.text;
6149
+ element.append(anchor);
6150
+ if (link.trailing) {
6151
+ appendInlineText(element, link.trailing, preserveTabs);
6152
+ }
6153
+ }
6154
+ offset = index + value.length;
6155
+ }
6156
+ if (offset < text.length) {
6157
+ appendInlineText(element, text.slice(offset), preserveTabs);
6158
+ }
6159
+ }
6160
+ function appendBracketRun(element, value) {
6161
+ const tagName = isReferenceTerm(value) ? "strong" : "em";
6162
+ const run = window.document.createElement(tagName);
6163
+ run.className = isReferenceTerm(value) ? "ofv-msdoc-ref-term" : "ofv-msdoc-instruction-run";
6164
+ run.textContent = value;
6165
+ element.append(run);
6166
+ }
6167
+ function getRevisionTableColumnWidths(rows) {
6168
+ const header = rows[0]?.map((cell) => cell.toLowerCase());
6169
+ if (!header || header.length !== 4) {
6170
+ return void 0;
6171
+ }
6172
+ if (header[0] === "rev" && header[1] === "date" && /whom/.test(header[2]) && header[3] === "what") {
6173
+ return [59, 81, 106, 191];
6174
+ }
6175
+ return void 0;
6176
+ }
6177
+ function appendInlineText(element, text, preserveTabs) {
6178
+ element.append(window.document.createTextNode(preserveTabs ? text : text.replace(/\t+/g, " ")));
6179
+ }
6180
+ function isReferenceTerm(value) {
6181
+ return /^\[[A-Z0-9][A-Z0-9.-]{1,24}\]$/.test(value);
6182
+ }
6183
+ function isCodeStyleRun(value) {
6184
+ return /^<\/?[A-Za-z][A-Za-z0-9:-]*>$/.test(value) || /^(?:attributeNames|DataType|OtherKeyword)$/.test(value);
6185
+ }
6186
+ function isVariableStyleRun(value) {
6187
+ return value === "variable";
6188
+ }
6189
+ function isRequirementKeywordRun(value) {
6190
+ return /^(?:must not|must|required|shall not|shall|should not|should|recommended|may|optional)$/i.test(value);
6191
+ }
6192
+ function splitLinkRun(value) {
6193
+ let text = value;
6194
+ let trailing = "";
6195
+ while (/[),.;:]$/.test(text)) {
6196
+ trailing = text.slice(-1) + trailing;
6197
+ text = text.slice(0, -1);
6198
+ }
6199
+ const href = /^https?:\/\//i.test(text) ? text : `mailto:${text}`;
6200
+ return { text, href, trailing };
6201
+ }
6202
+ function extractImageAssets(cfb) {
6203
+ const assets = [];
6204
+ const seen = /* @__PURE__ */ new Set();
6205
+ for (const entry of cfb.entries) {
6206
+ if (entry.type !== 2) {
6207
+ continue;
6208
+ }
6209
+ const stream = cfb.getStream(entry.name);
6210
+ if (!stream || stream.length < 16) {
6211
+ continue;
6212
+ }
6213
+ for (const image of extractImagesFromBytes(stream, entry.name)) {
6214
+ const key = `${image.mimeType}:${image.bytes.length}:${image.bytes[0]}:${image.bytes[image.bytes.length - 1]}`;
6215
+ if (seen.has(key)) {
6216
+ continue;
6217
+ }
6218
+ seen.add(key);
6219
+ const id = `image-${assets.length + 1}`;
6220
+ assets.push({
6221
+ id,
6222
+ kind: "image",
6223
+ mimeType: image.mimeType,
6224
+ dataUrl: `data:${image.mimeType};base64,${bytesToBase64(image.bytes)}`,
6225
+ width: image.width,
6226
+ height: image.height
6227
+ });
6228
+ }
6229
+ }
6230
+ return assets;
6231
+ }
6232
+ function parseStyleTable(tableStream, fib) {
6233
+ if (fib.lcbStshf <= 0 || fib.fcStshf < 0 || fib.fcStshf >= tableStream.length) {
6234
+ return [];
6235
+ }
6236
+ const bytes = tableStream.subarray(fib.fcStshf, Math.min(tableStream.length, fib.fcStshf + fib.lcbStshf));
6237
+ if (bytes.length < 8) {
6238
+ return [];
6239
+ }
6240
+ const view3 = dataView2(bytes);
6241
+ const cbStshi = view3.getUint16(0, true);
6242
+ const stshiOffset = 2;
6243
+ const cstd = stshiOffset + 2 <= bytes.length ? view3.getUint16(stshiOffset, true) : 0;
6244
+ const cbSTDBaseInFile = stshiOffset + 4 <= bytes.length ? view3.getUint16(stshiOffset + 2, true) : 10;
6245
+ let offset = 2 + cbStshi;
6246
+ const styles = [];
6247
+ for (let id = 0; id < cstd && offset + 2 <= bytes.length; id += 1) {
6248
+ const cbStd = view3.getUint16(offset, true);
6249
+ const stdStart = offset + 2;
6250
+ const stdEnd = stdStart + cbStd;
6251
+ if (cbStd > 0 && stdStart < bytes.length) {
6252
+ const style = parseStyleDefinition(bytes.subarray(stdStart, Math.min(stdEnd, bytes.length)), Math.max(10, cbSTDBaseInFile), id);
6253
+ if (style.name) {
6254
+ styles.push(style);
6255
+ }
6256
+ }
6257
+ offset = alignEven(stdEnd);
6258
+ }
6259
+ return styles;
6260
+ }
6261
+ function parseStyleDefinition(bytes, baseSize, id) {
6262
+ const base = bytes.length >= 6 ? parseStyleBase(bytes) : void 0;
6263
+ const nameOffset = Math.min(bytes.length, Math.max(10, baseSize));
6264
+ const name = parseXstz(bytes, nameOffset);
6265
+ return {
6266
+ id,
6267
+ name,
6268
+ type: styleTypeFromStk(base?.stk),
6269
+ basedOn: base?.basedOn,
6270
+ next: base?.next
6271
+ };
6272
+ }
6273
+ function parseStyleBase(bytes) {
6274
+ const view3 = dataView2(bytes);
6275
+ const w2 = view3.getUint16(2, true);
6276
+ const w3 = view3.getUint16(4, true);
6277
+ return {
6278
+ stk: w2 & 15,
6279
+ basedOn: w2 >> 4 & 4095,
6280
+ next: w3 >> 4 & 4095
6281
+ };
6282
+ }
6283
+ function styleTypeFromStk(stk) {
6284
+ if (stk === 1) {
6285
+ return "paragraph";
6286
+ }
6287
+ if (stk === 2) {
6288
+ return "character";
6289
+ }
6290
+ if (stk === 3) {
6291
+ return "table";
6292
+ }
6293
+ if (stk === 4) {
6294
+ return "numbering";
6295
+ }
6296
+ return "unknown";
6297
+ }
6298
+ function parseXstz(bytes, offset) {
6299
+ if (offset + 2 > bytes.length) {
6300
+ return "";
6301
+ }
6302
+ const view3 = dataView2(bytes);
6303
+ const charCount = view3.getUint16(offset, true);
6304
+ const start = offset + 2;
6305
+ const end = Math.min(bytes.length, start + charCount * 2);
6306
+ if (end <= start) {
6307
+ return "";
6308
+ }
6309
+ return decodeUtf16Le(bytes.subarray(start, end)).replace(/\0+$/g, "");
6310
+ }
6311
+ function extractImagesFromBytes(bytes, sourceName) {
6312
+ const images = [];
6313
+ for (const start of findSignatureOffsets(bytes, PNG_SIGNATURE)) {
6314
+ const end = findPngEnd(bytes, start);
6315
+ if (end > start) {
6316
+ const imageBytes = bytes.slice(start, end);
6317
+ const dimensions = readPngDimensions(imageBytes);
6318
+ images.push({ bytes: imageBytes, mimeType: "image/png", width: dimensions?.width, height: dimensions?.height });
6319
+ }
6320
+ }
6321
+ for (const start of findSignatureOffsets(bytes, JPEG_SIGNATURE)) {
6322
+ const end = findJpegEnd(bytes, start);
6323
+ if (end > start) {
6324
+ images.push({ bytes: bytes.slice(start, end), mimeType: "image/jpeg" });
6325
+ }
6326
+ }
6327
+ if (/picture|image|data/i.test(sourceName)) {
6328
+ const gifStart = bytes.findIndex((byte, index) => index + 4 <= bytes.length && bytes[index] === 71 && bytes[index + 1] === 73 && bytes[index + 2] === 70 && bytes[index + 3] === 56);
6329
+ if (gifStart >= 0) {
6330
+ images.push({ bytes: bytes.slice(gifStart), mimeType: "image/gif" });
6331
+ }
6332
+ }
6333
+ return images;
6334
+ }
6335
+ var PNG_SIGNATURE = Uint8Array.from([137, 80, 78, 71, 13, 10, 26, 10]);
6336
+ var JPEG_SIGNATURE = Uint8Array.from([255, 216, 255]);
6337
+ function findSignatureOffsets(bytes, signature) {
6338
+ const offsets = [];
6339
+ for (let index = 0; index <= bytes.length - signature.length; index += 1) {
6340
+ let matches = true;
6341
+ for (let sigIndex = 0; sigIndex < signature.length; sigIndex += 1) {
6342
+ if (bytes[index + sigIndex] !== signature[sigIndex]) {
6343
+ matches = false;
6344
+ break;
6345
+ }
6346
+ }
6347
+ if (matches) {
6348
+ offsets.push(index);
6349
+ }
6350
+ }
6351
+ return offsets;
6352
+ }
6353
+ function findPngEnd(bytes, start) {
6354
+ for (let offset = start + PNG_SIGNATURE.length; offset + 12 <= bytes.length; ) {
6355
+ const length = readUint32Be4(bytes, offset);
6356
+ const typeOffset = offset + 4;
6357
+ const next = offset + 12 + length;
6358
+ if (next > bytes.length) {
6359
+ return 0;
6360
+ }
6361
+ if (bytes[typeOffset] === 73 && bytes[typeOffset + 1] === 69 && bytes[typeOffset + 2] === 78 && bytes[typeOffset + 3] === 68) {
6362
+ return next;
6363
+ }
6364
+ offset = next;
6365
+ }
6366
+ return 0;
6367
+ }
6368
+ function findJpegEnd(bytes, start) {
6369
+ for (let index = start + 2; index + 1 < bytes.length; index += 1) {
6370
+ if (bytes[index] === 255 && bytes[index + 1] === 217) {
6371
+ return index + 2;
6372
+ }
6373
+ }
6374
+ return 0;
6375
+ }
6376
+ function readPngDimensions(bytes) {
6377
+ if (bytes.length < 24 || !PNG_SIGNATURE.every((value, index) => bytes[index] === value)) {
6378
+ return void 0;
6379
+ }
6380
+ return {
6381
+ width: readUint32Be4(bytes, 16),
6382
+ height: readUint32Be4(bytes, 20)
6383
+ };
6384
+ }
6385
+ function readUint32Be4(bytes, offset) {
6386
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
6387
+ }
6388
+ function bytesToBase64(bytes) {
6389
+ let binary = "";
6390
+ const chunkSize = 32768;
6391
+ for (let offset = 0; offset < bytes.length; offset += chunkSize) {
6392
+ binary += String.fromCharCode(...bytes.subarray(offset, Math.min(bytes.length, offset + chunkSize)));
6393
+ }
6394
+ return btoa(binary);
6395
+ }
6396
+ function parseCompoundFile(bytes) {
6397
+ if (!hasCompoundSignature(bytes)) {
6398
+ throw new Error("\u4E0D\u662F\u6807\u51C6 OLE Compound File");
6399
+ }
6400
+ const view3 = dataView2(bytes);
6401
+ const sectorSize = 1 << view3.getUint16(30, true);
6402
+ const miniSectorSize = 1 << view3.getUint16(32, true);
6403
+ const fatSectorCount = view3.getUint32(44, true);
6404
+ const firstDirectorySector = view3.getUint32(48, true);
6405
+ const miniStreamCutoff = view3.getUint32(56, true) || MINI_STREAM_CUTOFF;
6406
+ const firstMiniFatSector = view3.getUint32(60, true);
6407
+ const miniFatSectorCount = view3.getUint32(64, true);
6408
+ const firstDifatSector = view3.getUint32(68, true);
6409
+ const difatSectorCount = view3.getUint32(72, true);
6410
+ const difat = readDifat(view3, sectorSize, firstDifatSector, difatSectorCount);
6411
+ const fat = readFat(view3, sectorSize, difat.slice(0, fatSectorCount));
6412
+ const directoryBytes = readRegularStream(bytes, sectorSize, fat, firstDirectorySector);
6413
+ const entries = parseDirectoryEntries(directoryBytes);
6414
+ const root = entries.find((entry) => entry.type === 5);
6415
+ const miniStream = root ? readRegularStream(bytes, sectorSize, fat, root.startSector, root.size) : new Uint8Array();
6416
+ const miniFat = firstMiniFatSector < END_OF_CHAIN ? readFat(view3, sectorSize, sectorChain(fat, firstMiniFatSector).slice(0, miniFatSectorCount)) : [];
6417
+ return {
6418
+ entries,
6419
+ getStream(name) {
6420
+ const wanted = normalizeStreamName(name);
6421
+ const entry = entries.find((item) => item.type === 2 && normalizeStreamName(item.name) === wanted);
6422
+ if (!entry) {
6423
+ return void 0;
6424
+ }
6425
+ if (entry.size < miniStreamCutoff && miniFat.length > 0) {
6426
+ return readMiniStream(miniStream, miniSectorSize, miniFat, entry.startSector, entry.size);
6427
+ }
6428
+ return readRegularStream(bytes, sectorSize, fat, entry.startSector, entry.size);
6429
+ }
6430
+ };
6431
+ }
6432
+ function hasCompoundSignature(bytes) {
6433
+ return CFB_SIGNATURE.every((value, index) => bytes[index] === value);
6434
+ }
6435
+ function readDifat(view3, sectorSize, firstDifatSector, difatSectorCount) {
6436
+ const difat = [];
6437
+ for (let offset = 76; offset < 512; offset += 4) {
6438
+ const sector = view3.getUint32(offset, true);
6439
+ if (isUsableSector(sector)) {
6440
+ difat.push(sector);
6441
+ }
6442
+ }
6443
+ let next = firstDifatSector;
6444
+ for (let index = 0; index < difatSectorCount && isUsableSector(next); index += 1) {
6445
+ const offset = sectorOffset(next, sectorSize);
6446
+ const entriesPerSector = sectorSize / 4 - 1;
6447
+ for (let item = 0; item < entriesPerSector; item += 1) {
6448
+ const sector = view3.getUint32(offset + item * 4, true);
6449
+ if (isUsableSector(sector)) {
6450
+ difat.push(sector);
6451
+ }
6452
+ }
6453
+ next = view3.getUint32(offset + entriesPerSector * 4, true);
6454
+ }
6455
+ return difat;
6456
+ }
6457
+ function readFat(view3, sectorSize, sectors) {
6458
+ const fat = [];
6459
+ for (const sector of sectors) {
6460
+ if (!isUsableSector(sector) && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR) {
6461
+ continue;
6462
+ }
6463
+ const offset = sectorOffset(sector, sectorSize);
6464
+ for (let item = 0; item < sectorSize / 4; item += 1) {
6465
+ fat.push(view3.getUint32(offset + item * 4, true));
6466
+ }
6467
+ }
6468
+ return fat;
6469
+ }
6470
+ function parseDirectoryEntries(bytes) {
6471
+ const view3 = dataView2(bytes);
6472
+ const entries = [];
6473
+ for (let offset = 0; offset + 128 <= bytes.length; offset += 128) {
6474
+ const nameLength = view3.getUint16(offset + 64, true);
6475
+ const type = bytes[offset + 66] || 0;
6476
+ if (type === 0 || nameLength < 2) {
6477
+ continue;
6478
+ }
6479
+ const nameBytes = bytes.subarray(offset, offset + Math.max(0, nameLength - 2));
6480
+ const name = decodeUtf16Le(nameBytes).replace(/\0+$/g, "");
6481
+ const startSector = view3.getUint32(offset + 116, true);
6482
+ const lowSize = view3.getUint32(offset + 120, true);
6483
+ const highSize = view3.getUint32(offset + 124, true);
6484
+ const size = highSize > 0 ? Number(BigInt(highSize) << 32n) + lowSize : lowSize;
6485
+ entries.push({ name, type, startSector, size });
6486
+ }
6487
+ return entries;
6488
+ }
6489
+ function readRegularStream(bytes, sectorSize, fat, startSector, size) {
6490
+ const chunks = [];
6491
+ for (const sector of sectorChain(fat, startSector)) {
6492
+ const offset = sectorOffset(sector, sectorSize);
6493
+ chunks.push(bytes.subarray(offset, Math.min(bytes.length, offset + sectorSize)));
6494
+ }
6495
+ return concatChunks(chunks, size);
6496
+ }
6497
+ function readMiniStream(miniStream, miniSectorSize, miniFat, startSector, size) {
6498
+ const chunks = [];
6499
+ for (const sector of sectorChain(miniFat, startSector)) {
6500
+ const offset = sector * miniSectorSize;
6501
+ chunks.push(miniStream.subarray(offset, Math.min(miniStream.length, offset + miniSectorSize)));
6502
+ }
6503
+ return concatChunks(chunks, size);
6504
+ }
6505
+ function sectorChain(fat, startSector) {
6506
+ const chain = [];
6507
+ const seen = /* @__PURE__ */ new Set();
6508
+ let current = startSector;
6509
+ while (isUsableSector(current) && current < fat.length && !seen.has(current)) {
6510
+ seen.add(current);
6511
+ chain.push(current);
6512
+ current = fat[current];
6513
+ }
6514
+ return chain;
6515
+ }
6516
+ function parseFib(wordDocument) {
6517
+ const view3 = dataView2(wordDocument);
6518
+ if (view3.getUint16(0, true) !== 42476) {
6519
+ throw new Error("WordDocument FIB \u6807\u8BC6\u65E0\u6548");
6520
+ }
6521
+ const flags = view3.getUint16(10, true);
6522
+ const fcMin = view3.getUint32(24, true);
6523
+ const fcMac = view3.getUint32(28, true);
6524
+ let offset = 32;
6525
+ const csw = view3.getUint16(offset, true);
6526
+ offset += 2 + csw * 2;
6527
+ const fibRgLwOffset = offset + 2;
6528
+ const cslw = view3.getUint16(offset, true);
6529
+ const ccpText = fibRgLwOffset + 16 <= wordDocument.length ? Math.max(0, view3.getInt32(fibRgLwOffset + 12, true)) : 0;
6530
+ offset += 2 + cslw * 4;
6531
+ const cbRgFcLcb = view3.getUint16(offset, true);
6532
+ const fcLcbOffset = offset + 2;
6533
+ const stshOffset = fcLcbOffset + STSH_FC_LCB_INDEX * 8;
6534
+ const clxOffset = fcLcbOffset + CLX_FC_LCB_INDEX * 8;
6535
+ return {
6536
+ encrypted: (flags & 256) !== 0,
6537
+ useOneTable: (flags & 512) !== 0,
6538
+ textIsUnicode: (flags & 4096) !== 0,
6539
+ fcMin,
6540
+ fcMac,
6541
+ ccpText,
6542
+ fcStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset, true) : 0,
6543
+ lcbStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset + 4, true) : 0,
6544
+ fcClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset, true) : 0,
6545
+ lcbClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset + 4, true) : 0
6546
+ };
6547
+ }
6548
+ function parseClxPieces(tableStream, fcClx, lcbClx) {
6549
+ if (lcbClx <= 0 || fcClx < 0 || fcClx >= tableStream.length) {
6550
+ return [];
6551
+ }
6552
+ const end = Math.min(tableStream.length, fcClx + lcbClx);
6553
+ const view3 = dataView2(tableStream);
6554
+ let offset = fcClx;
6555
+ while (offset < end) {
6556
+ const marker = tableStream[offset];
6557
+ if (marker === 1) {
6558
+ const size = offset + 3 <= end ? view3.getUint16(offset + 1, true) : 0;
6559
+ offset += 3 + size;
6560
+ continue;
6561
+ }
6562
+ if (marker === 2) {
6563
+ if (offset + 5 > end) {
6564
+ break;
6565
+ }
6566
+ const plcSize = view3.getUint32(offset + 1, true);
6567
+ const plcOffset = offset + 5;
6568
+ return parsePlcPcd(tableStream, plcOffset, Math.min(end, plcOffset + plcSize));
6569
+ }
6570
+ offset += 1;
6571
+ }
6572
+ return [];
6573
+ }
6574
+ function parsePlcPcd(tableStream, offset, end) {
6575
+ const size = end - offset;
6576
+ if (size < 16 || (size - 4) % 12 !== 0) {
6577
+ return [];
6578
+ }
6579
+ const view3 = dataView2(tableStream);
6580
+ const pieceCount = Math.floor((size - 4) / 12);
6581
+ const pcdOffset = offset + (pieceCount + 1) * 4;
6582
+ const pieces = [];
6583
+ for (let index = 0; index < pieceCount; index += 1) {
6584
+ const cpStart = view3.getUint32(offset + index * 4, true);
6585
+ const cpEnd = view3.getUint32(offset + (index + 1) * 4, true);
6586
+ const descriptorOffset = pcdOffset + index * 8;
6587
+ const fcCompressed = view3.getUint32(descriptorOffset + 2, true);
6588
+ const compressed = (fcCompressed & 1073741824) !== 0;
6589
+ const fileOffset = compressed ? (fcCompressed & 1073741823) / 2 : fcCompressed;
6590
+ if (cpEnd > cpStart) {
6591
+ pieces.push({ cpStart, cpEnd, fileOffset, compressed });
6592
+ }
6593
+ }
6594
+ return pieces;
6595
+ }
6596
+ function readPieceTableText(wordDocument, pieces, ccpText) {
6597
+ let output = "";
6598
+ for (const piece of pieces) {
6599
+ const cpEnd = ccpText > 0 ? Math.min(piece.cpEnd, ccpText) : piece.cpEnd;
6600
+ const charCount = Math.max(0, cpEnd - piece.cpStart);
6601
+ if (charCount === 0) {
6602
+ continue;
6603
+ }
6604
+ const byteLength = charCount * (piece.compressed ? 1 : 2);
6605
+ const bytes = wordDocument.subarray(piece.fileOffset, Math.min(wordDocument.length, piece.fileOffset + byteLength));
6606
+ output += piece.compressed ? decodeWindows1252(bytes) : decodeUtf16Le(bytes);
6607
+ }
6608
+ return output;
6609
+ }
6610
+ function readFibTextFallback(wordDocument, fib) {
6611
+ const bytes = wordDocument.subarray(fib.fcMin, Math.min(wordDocument.length, fib.fcMac));
6612
+ return fib.textIsUnicode ? decodeUtf16Le(bytes) : decodeWindows1252(bytes);
6613
+ }
6614
+ function splitWordParagraphs(text) {
6615
+ const normalized = text.replace(/\u0000/g, "").replace(/\u0007/g, " ").replace(/\u000b/g, "\n");
6616
+ const paragraphs = [];
6617
+ for (const segment of normalized.split(/(\u000c)/)) {
6618
+ if (segment === "\f") {
6619
+ paragraphs.push(WORD_PAGE_BREAK);
6620
+ continue;
6621
+ }
6622
+ paragraphs.push(
6623
+ ...segment.split(/\r|\n{2,}/).map((paragraph) => cleanWordText(paragraph)).filter((paragraph) => paragraph.length > 0 && isDisplayableParagraph(paragraph))
6624
+ );
6625
+ }
6626
+ return paragraphs.slice(0, 1e3);
6627
+ }
6628
+ function removeTrailingFooterArtifacts(paragraphs) {
6629
+ const tailStart = Math.max(0, paragraphs.length - 32);
6630
+ const tail = paragraphs.slice(tailStart);
6631
+ const relativePageFieldIndex = tail.findIndex(isFooterPageField);
6632
+ if (relativePageFieldIndex < 0) {
6633
+ return paragraphs;
6634
+ }
6635
+ let start = tailStart + relativePageFieldIndex;
6636
+ for (let index = start - 1; index >= tailStart; index -= 1) {
6637
+ const paragraph = paragraphs[index];
6638
+ if (paragraph === WORD_PAGE_BREAK || isLikelyFooterArtifact(paragraph)) {
6639
+ start = index;
6640
+ continue;
6641
+ }
6642
+ break;
6643
+ }
6644
+ const artifactSlice = paragraphs.slice(start);
6645
+ const footerCueCount = artifactSlice.filter(isLikelyFooterArtifact).length;
6646
+ if (footerCueCount < 2) {
6647
+ return paragraphs;
6648
+ }
6649
+ return paragraphs.slice(0, start);
6650
+ }
6651
+ function isFooterPageField(paragraph) {
6652
+ return /^(?:PAGE|Page)(?:\s+(?:PAGE|\d+))?(?:\s+of\s+(?:NUMPAGES|\d+))?$/i.test(paragraph.trim()) || /\bNUMPAGES\b/i.test(paragraph);
6653
+ }
6654
+ function isLikelyFooterArtifact(paragraph) {
6655
+ const value = paragraph.trim();
6656
+ return value === WORD_PAGE_BREAK || isFooterPageField(value) || /^wd-[\w.-]+$/i.test(value) || /^\d{1,2}\s+[A-Za-z]+\s+\d{4}$/.test(value) || /^Copyright\s+©?\s*(?:OASIS|2002 OASIS)/i.test(value);
6657
+ }
6658
+ function buildWordBlocks(paragraphs) {
6659
+ const blocks = [];
6660
+ let index = 0;
6661
+ while (index < paragraphs.length) {
6662
+ const paragraph = paragraphs[index];
6663
+ if (paragraph === WORD_PAGE_BREAK) {
6664
+ blocks.push({ type: "pageBreak" });
6665
+ index += 1;
6666
+ continue;
6667
+ }
6668
+ const toc = parseTocEntry(paragraph);
6669
+ if (toc) {
6670
+ blocks.push(toc);
6671
+ index += 1;
6672
+ continue;
6673
+ }
6674
+ if (isTableRowCandidate(paragraph)) {
6675
+ const rows = [];
6676
+ while (index < paragraphs.length && isTableRowCandidate(paragraphs[index])) {
6677
+ rows.push(...normalizeTableRows(splitTableRow(paragraphs[index])));
6678
+ index += 1;
6679
+ }
6680
+ blocks.push({ type: "table", rows });
6681
+ continue;
6682
+ }
6683
+ blocks.push(classifyParagraphBlock(paragraph, blocks));
6684
+ index += 1;
6685
+ }
6686
+ return blocks;
6687
+ }
6688
+ function inferLayoutHints(paragraphs, assets) {
6689
+ const sample = paragraphs.slice(0, 40).join("\n");
6690
+ const isOasisSpec = /Word Specification Sample/.test(sample) && /\bOASIS\b/i.test(paragraphs.join("\n"));
6691
+ const oasisImage = isOasisSpec ? assets.find((asset) => asset.mimeType === "image/png" && asset.width && asset.height && asset.width / asset.height > 2.5) : void 0;
6692
+ return {
6693
+ lineNumbers: isOasisSpec,
6694
+ headerBrand: isOasisSpec ? "oasis" : void 0,
6695
+ headerImageId: oasisImage?.id,
6696
+ footer: isOasisSpec ? inferOasisFooter(paragraphs) : void 0
6697
+ };
6698
+ }
6699
+ function inferOasisFooter(paragraphs) {
6700
+ const documentId = findValueAfterLabel(paragraphs, "Document identifier:") || paragraphs.find((paragraph) => /^wd-[\w.-]+/i.test(paragraph));
6701
+ const subtitle = paragraphs.find((paragraph) => /\b(?:draft|version)\b/i.test(paragraph) && /\d{4}/.test(paragraph));
6702
+ const date = subtitle?.match(/\b\d{1,2}\s+[A-Za-z]+\s+\d{4}\b/)?.[0];
6703
+ const copyright = paragraphs.find((paragraph) => /Copyright.*OASIS.*All Rights Reserved/i.test(paragraph)) || "Copyright \xA9 OASIS Open 2002. All Rights Reserved.";
6704
+ return { documentId, date, copyright };
6705
+ }
6706
+ function findValueAfterLabel(paragraphs, label) {
6707
+ const index = paragraphs.findIndex((paragraph) => paragraph.toLowerCase() === label.toLowerCase());
6708
+ if (index < 0) {
6709
+ return void 0;
6710
+ }
6711
+ return paragraphs.slice(index + 1).find((paragraph) => paragraph !== WORD_PAGE_BREAK && paragraph.length > 0);
6712
+ }
6713
+ function paginateWordBlocks(blocks, layout) {
6714
+ const maxLines = layout.lineNumbers ? 33 : 46;
6715
+ const pages = [];
6716
+ let current = [];
6717
+ let usedLines = 0;
6718
+ for (const block of blocks) {
6719
+ if (block.type === "pageBreak") {
6720
+ if (current.length > 0) {
6721
+ pages.push(current);
6722
+ }
6723
+ current = [];
6724
+ usedLines = 0;
6725
+ continue;
6726
+ }
6727
+ const lines = estimatedLineCount(block);
6728
+ const shouldBreak = current.length > 0 && (usedLines + lines > maxLines || block.type === "heading" && usedLines > Math.floor(maxLines * 0.72));
6729
+ if (shouldBreak) {
6730
+ pages.push(current);
6731
+ current = [];
6732
+ usedLines = 0;
6733
+ }
6734
+ current.push(block);
6735
+ usedLines += lines;
6736
+ }
6737
+ if (current.length > 0 || pages.length === 0) {
6738
+ pages.push(current);
6739
+ }
6740
+ return pages;
6741
+ }
6742
+ function estimatedLineCount(block) {
6743
+ if (block.type === "pageBreak") {
6744
+ return 0;
6745
+ }
6746
+ if (block.type === "table") {
6747
+ return Math.max(1, block.rows.length);
6748
+ }
6749
+ if (block.type === "toc") {
6750
+ return 1;
6751
+ }
6752
+ const baseWidth = "indent" in block && block.indent ? 78 : 96;
6753
+ return Math.max(1, Math.ceil(block.text.length / baseWidth));
6754
+ }
6755
+ function classifyParagraphBlock(text, previousBlocks) {
6756
+ const visibleIndex = previousBlocks.filter((block) => block.type !== "toc").length;
6757
+ if (visibleIndex === 0 && text.length <= 140) {
6758
+ return { type: "title", text };
6759
+ }
6760
+ if (visibleIndex === 1 && /draft|version|20\d{2}|19\d{2}/i.test(text) && text.length <= 140) {
6761
+ return { type: "subtitle", text };
6762
+ }
6763
+ const headingLevel = inferHeadingLevel(text, previousBlocks);
6764
+ if (headingLevel) {
6765
+ return { type: "heading", text, level: headingLevel };
6766
+ }
6767
+ if (/^[\w\s/().-]{2,45}:$/.test(text)) {
6768
+ return { type: "label", text };
6769
+ }
6770
+ if (isInstructionParagraph(text)) {
6771
+ return { type: "instruction", text, indent: shouldIndentParagraph(previousBlocks) };
6772
+ }
6773
+ if (/^\[[-\w.]+\]\s+/.test(text)) {
6774
+ return { type: "reference", text };
6775
+ }
6776
+ const listLevel = inferListItemLevel(text);
6777
+ if (listLevel) {
6778
+ return { type: "listItem", text, level: listLevel };
6779
+ }
6780
+ if (isCodeLikeParagraph(text)) {
6781
+ return { type: "code", text, indent: shouldIndentParagraph(previousBlocks) };
6782
+ }
6783
+ return { type: "paragraph", text, indent: shouldIndentParagraph(previousBlocks) };
6784
+ }
6785
+ function isInstructionParagraph(text) {
6786
+ return /^\[[^\]]{8,}\]$/.test(text.trim());
6787
+ }
6788
+ function inferHeadingLevel(text, previousBlocks) {
6789
+ if (text.length > 120) {
6790
+ return void 0;
6791
+ }
6792
+ if (/^table of contents$/i.test(text)) {
6793
+ return 1;
6794
+ }
6795
+ if (/^(?:introduction|word styles|references|appendix\b.*|acknowledgments|revision history|notices)$/i.test(text)) {
6796
+ return 1;
6797
+ }
6798
+ const numbered = text.match(/^([1-9](?:\.\d+)*)\s+.+/);
6799
+ if (numbered) {
6800
+ return Math.min(3, numbered[1].split(".").length);
6801
+ }
6802
+ if (/^(?:terminology|overall style|title page|headings|paragraphs|lists|tables|code examples|character styles|normative)$/i.test(text)) {
6803
+ return 2;
6804
+ }
6805
+ const previousHeading = [...previousBlocks].reverse().find((block) => block.type === "heading");
6806
+ if (previousHeading?.type === "heading" && previousHeading.level === 1 && /^[A-Z][A-Za-z0-9 ()/-]{2,80}$/.test(text)) {
6807
+ return 2;
6808
+ }
6809
+ return void 0;
6810
+ }
6811
+ function shouldIndentParagraph(previousBlocks) {
6812
+ for (let index = previousBlocks.length - 1; index >= 0; index -= 1) {
6813
+ const block = previousBlocks[index];
6814
+ if (block.type === "toc" || block.type === "table") {
6815
+ continue;
6816
+ }
6817
+ if (block.type === "label") {
6818
+ return true;
6819
+ }
6820
+ if ((block.type === "paragraph" || block.type === "code") && block.indent) {
6821
+ return true;
6822
+ }
6823
+ return false;
6824
+ }
6825
+ return false;
6826
+ }
6827
+ function inferListItemLevel(text) {
6828
+ if (/^(?:list bullet|definition term)$/i.test(text)) {
6829
+ return 1;
6830
+ }
6831
+ if (/^(?:list bullet 2|list continue 2|definition for the term\.)$/i.test(text)) {
6832
+ return 2;
6833
+ }
6834
+ return void 0;
6835
+ }
6836
+ function parseTocEntry(text) {
6837
+ const tabCells = splitTableRow(text);
6838
+ if (tabCells.length >= 2 && /^\d{1,3}$/.test(tabCells[tabCells.length - 1] || "")) {
6839
+ const title2 = tabCells.slice(0, -1).join(" ").trim();
6840
+ if (isLikelyTocTitle(title2)) {
6841
+ const number2 = title2.match(/^(\d+(?:\.\d+)*)\b/)?.[1] || "";
6842
+ return { type: "toc", title: title2, page: tabCells[tabCells.length - 1], level: number2.includes(".") ? Math.min(3, number2.split(".").length) : 1 };
6843
+ }
6844
+ }
6845
+ const cleaned = text.replace(/\s+/g, " ").trim();
6846
+ const match = cleaned.match(/^(?:(\d+(?:\.\d+)*)\s+)?(.+?)\s+(\d{1,3})$/);
6847
+ if (!match || cleaned.length > 140) {
6848
+ return void 0;
6849
+ }
6850
+ const number = match[1] || "";
6851
+ const title = `${number ? `${number} ` : ""}${match[2] || ""}`.trim();
6852
+ const page = match[3];
6853
+ if (!title || !page || !/^(?:appendix\b|references\b|introduction\b|[A-Z0-9])/i.test(title)) {
6854
+ return void 0;
6855
+ }
6856
+ if (!isLikelyTocTitle(title)) {
6857
+ return void 0;
6858
+ }
6859
+ const level = number.includes(".") ? Math.min(3, number.split(".").length) : 1;
6860
+ return { type: "toc", title, page, level };
6861
+ }
6862
+ function isLikelyTocTitle(title) {
6863
+ return /^(?:appendix\b|references\b|introduction\b|[1-9](?:\.\d+)*\b|[A-Z][\w\s.-]{2,80}$)/i.test(title);
6864
+ }
6865
+ function isTableRowCandidate(text) {
6866
+ if (/^\[[-\w.]+\]\t+/.test(text)) {
6867
+ return false;
6868
+ }
6869
+ const cells = splitTableRow(text);
6870
+ return cells.length >= 2 && cells.some((cell) => cell.length > 0);
6871
+ }
6872
+ function splitTableRow(text) {
6873
+ return text.split(/\t+/).map((cell) => cell.trim()).filter(Boolean);
6874
+ }
6875
+ function normalizeTableRows(cells) {
6876
+ if (cells.length >= 8) {
6877
+ const columnCount = inferTableColumnCount(cells);
6878
+ if (columnCount > 1 && cells.length % columnCount === 0) {
6879
+ const rows = [];
6880
+ for (let offset = 0; offset < cells.length; offset += columnCount) {
6881
+ rows.push(cells.slice(offset, offset + columnCount));
6882
+ }
6883
+ return rows;
6884
+ }
6885
+ }
6886
+ return [cells];
6887
+ }
6888
+ function inferTableColumnCount(cells) {
6889
+ const header = cells.slice(0, 6).join(" ").toLowerCase();
6890
+ if (/\brev\b/.test(header) && /\bdate\b/.test(header) && /whom|what/.test(header)) {
6891
+ return 4;
6892
+ }
6893
+ for (const candidate of [5, 4, 3, 2]) {
6894
+ if (cells.length % candidate === 0) {
6895
+ return candidate;
6896
+ }
6897
+ }
6898
+ return 0;
6899
+ }
6900
+ function isCodeLikeParagraph(text) {
6901
+ return /^\d{24,}$/.test(text.replace(/\s+/g, "")) || /^GET\s+https?:\/\//i.test(text) || /^<other\s+HTTP\b/i.test(text) || /<\/?[A-Za-z][A-Za-z0-9:-]*(?:\s+[^>@]*)?>/.test(text) || /^\s*(?:<\?xml|function\b|const\b|let\b|var\b|if\s*\(|for\s*\(|while\s*\(|\{|\}|\/\/)/.test(text);
6902
+ }
6903
+ function cleanWordText(value) {
6904
+ return stripWordFieldCodes(value).replace(/[\u0001-\u0006\u0008\u000e-\u001f]/g, "").replace(/ {2,}/g, " ").trim();
6905
+ }
6906
+ function stripWordFieldCodes(value) {
6907
+ return value.replace(/\u0013\s*(?:HYPERLINK|PAGEREF|TOC)\b[^\u0014\u0015]*/gi, "").replace(/[\u0013-\u0015]/g, "").replace(/\bHYPERLINK\s+\\l\s+"[^"]*"\s*/gi, "").replace(/\bHYPERLINK\s+"[^"]*"\s*/gi, "").replace(/\bPAGEREF\s+\S+\s+\\h\s*/gi, "").replace(/\bTOC\s+\\o\s+"[^"]*"\s+\\h\s+\\z\s*/gi, "").replace(/\bREF\s+[_A-Za-z0-9-]+\s+(?:\\[A-Za-z]+\s*)+/gi, "");
6908
+ }
6909
+ function isDisplayableParagraph(value) {
6910
+ if (value.length < 2) {
6911
+ return false;
6912
+ }
6913
+ const letters = [...value].filter((char) => /[\p{L}\p{N}]/u.test(char)).length;
6914
+ return letters >= Math.min(2, value.length);
6915
+ }
6916
+ function inferDocumentTitle(paragraphs) {
6917
+ return paragraphs.find((paragraph) => paragraph.length <= 120) || "Word \u6587\u6863";
6918
+ }
6919
+ function appendMeta4(list, label, value) {
6920
+ const term = window.document.createElement("dt");
6921
+ term.textContent = label;
6922
+ const detail = window.document.createElement("dd");
6923
+ detail.textContent = value;
6924
+ list.append(term, detail);
6925
+ }
6926
+ function concatChunks(chunks, size) {
6927
+ const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
6928
+ const output = new Uint8Array(size === void 0 ? total : Math.min(total, size));
6929
+ let offset = 0;
6930
+ for (const chunk of chunks) {
6931
+ const slice = chunk.subarray(0, Math.min(chunk.length, output.length - offset));
6932
+ output.set(slice, offset);
6933
+ offset += slice.length;
6934
+ if (offset >= output.length) {
6935
+ break;
6936
+ }
6937
+ }
6938
+ return output;
6939
+ }
6940
+ function alignEven(value) {
6941
+ return value % 2 === 0 ? value : value + 1;
6942
+ }
6943
+ function isUsableSector(sector) {
6944
+ return sector !== FREE_SECTOR && sector !== END_OF_CHAIN && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR;
6945
+ }
6946
+ function sectorOffset(sector, sectorSize) {
6947
+ return (sector + 1) * sectorSize;
6948
+ }
6949
+ function normalizeStreamName(name) {
6950
+ return name.replace(/^\/+/, "").toLowerCase();
6951
+ }
6952
+ function decodeUtf16Le(bytes) {
6953
+ return new TextDecoder("utf-16le").decode(bytes);
6954
+ }
6955
+ function decodeWindows1252(bytes) {
6956
+ try {
6957
+ return new TextDecoder("windows-1252").decode(bytes);
6958
+ } catch {
6959
+ return Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
6960
+ }
6961
+ }
6962
+ function dataView2(bytes) {
6963
+ return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
6964
+ }
6965
+
6966
+ // src/plugins/office.ts
5873
6967
  var wordExtensions = /* @__PURE__ */ new Set(["docx", "docm", "doc", "dotx", "dotm", "dot", "rtf", "odt", "fodt", "wps"]);
5874
6968
  var sheetExtensions = /* @__PURE__ */ new Set(["xlsx", "xls", "xlsm", "xlsb", "xlt", "xltx", "xltm", "csv", "tsv", "ods", "fods", "numbers", "et"]);
5875
6969
  var presentationExtensions = /* @__PURE__ */ new Set(["pptx", "pptm", "ppt", "pps", "ppsx", "ppsm", "potx", "potm", "odp", "fodp", "key", "dps"]);
@@ -5980,6 +7074,8 @@ function officePlugin(options = {}) {
5980
7074
  await renderOdp(panel, arrayBuffer);
5981
7075
  } else if (extension === "fodp") {
5982
7076
  renderOpenDocumentPresentationXml(panel, await readTextFromBuffer(arrayBuffer));
7077
+ } else if (extension === "doc" || extension === "dot") {
7078
+ renderLegacyWordBinary(panel, extension, arrayBuffer);
5983
7079
  } else if (isLegacyOfficeBinary(extension)) {
5984
7080
  renderLegacyOfficeBinary(panel, extension, arrayBuffer);
5985
7081
  } else {
@@ -7368,7 +8464,7 @@ async function renderSheet(panel, arrayBuffer, extension) {
7368
8464
  heading.textContent = sheetName;
7369
8465
  const sheet = workbook.Sheets[sheetName];
7370
8466
  const sheetImages = workbookImages.get(sheetName) || [];
7371
- const range = trimWorkbookSheetRange(sheet, xlsx.utils.decode_range(sheet["!ref"] || "A1:A1"), xlsx.utils.decode_cell);
8467
+ const range = trimWorkbookSheetRange(sheet, xlsx.utils.decode_range(sheet["!ref"] || "A1:A1"), xlsx.utils.decode_cell, sheetImages);
7372
8468
  const rowCount = range.e.r - range.s.r + 1;
7373
8469
  const columnCount = range.e.c - range.s.c + 1;
7374
8470
  const formulaRows = collectFormulaRows(sheet, range, xlsx.utils.encode_cell);
@@ -7467,7 +8563,7 @@ function renderSheetFallback(panel, extension, detail) {
7467
8563
  async function readWorkbookSheetImages(arrayBuffer) {
7468
8564
  const zip = await JSZip3.loadAsync(arrayBuffer);
7469
8565
  const fileNames = Object.keys(zip.files);
7470
- if (!fileNames.some((name) => /^xl\/drawings\/.+\.xml$/i.test(name)) || !fileNames.some((name) => /^xl\/media\//i.test(name))) {
8566
+ if (!fileNames.some((name) => /^xl\/drawings\/.+\.xml$/i.test(name))) {
7471
8567
  return /* @__PURE__ */ new Map();
7472
8568
  }
7473
8569
  const workbookXml = await zip.file("xl/workbook.xml")?.async("text");
@@ -7527,6 +8623,7 @@ async function readWorksheetDrawingImages(zip, drawingPath) {
7527
8623
  const images = [];
7528
8624
  for (const anchor of anchors) {
7529
8625
  const from = Array.from(anchor.children).find((element) => element.localName === "from");
8626
+ const to = Array.from(anchor.children).find((element) => element.localName === "to");
7530
8627
  const embedId = findDrawingImageRelationshipId(anchor);
7531
8628
  const mediaRel = drawingRels.find((rel) => rel.id === embedId && /\/image$/i.test(rel.type));
7532
8629
  const mediaPath = resolveOfficeRelationshipTarget(drawingPath, mediaRel?.target);
@@ -7538,6 +8635,8 @@ async function readWorksheetDrawingImages(zip, drawingPath) {
7538
8635
  images.push({
7539
8636
  row: readDrawingMarkerIndex(from, "row"),
7540
8637
  column: readDrawingMarkerIndex(from, "col"),
8638
+ endRow: to ? readDrawingMarkerIndex(to, "row") : void 0,
8639
+ endColumn: to ? readDrawingMarkerIndex(to, "col") : void 0,
7541
8640
  fileName: mediaPath.split("/").pop() || "image",
7542
8641
  mimeType,
7543
8642
  dataUrl: `data:${mimeType};base64,${await mediaFile.async("base64")}`,
@@ -7993,7 +9092,7 @@ function chartText(element) {
7993
9092
  function chartStringValues(element) {
7994
9093
  return Array.from(element.querySelectorAll("*")).filter((item) => item.localName === "v" || item.localName === "t").map((item) => item.textContent?.trim() || "").filter(Boolean);
7995
9094
  }
7996
- function trimWorkbookSheetRange(sheet, range, decodeCell) {
9095
+ function trimWorkbookSheetRange(sheet, range, decodeCell, images = []) {
7997
9096
  let minRow = Number.POSITIVE_INFINITY;
7998
9097
  let minColumn = Number.POSITIVE_INFINITY;
7999
9098
  let maxRow = Number.NEGATIVE_INFINITY;
@@ -8018,17 +9117,21 @@ function trimWorkbookSheetRange(sheet, range, decodeCell) {
8018
9117
  include(merge.s.r, merge.s.c);
8019
9118
  include(merge.e.r, merge.e.c);
8020
9119
  }
9120
+ for (const image of images) {
9121
+ include(image.row, image.column);
9122
+ include(image.endRow ?? image.row, image.endColumn ?? image.column);
9123
+ }
8021
9124
  if (!Number.isFinite(minRow) || !Number.isFinite(minColumn) || !Number.isFinite(maxRow) || !Number.isFinite(maxColumn)) {
8022
9125
  return range;
8023
9126
  }
8024
9127
  return {
8025
9128
  s: {
8026
- r: Math.max(range.s.r, minRow),
8027
- c: Math.max(range.s.c, minColumn)
9129
+ r: minRow,
9130
+ c: minColumn
8028
9131
  },
8029
9132
  e: {
8030
- r: Math.min(range.e.r, maxRow),
8031
- c: Math.min(range.e.c, maxColumn)
9133
+ r: maxRow,
9134
+ c: maxColumn
8032
9135
  }
8033
9136
  };
8034
9137
  }
@@ -8159,7 +9262,9 @@ function createWorkbookSheetTable(sheet, range, sheetIndex, viewport, encodeCell
8159
9262
  cell.classList.add("ofv-cell-multiline");
8160
9263
  }
8161
9264
  appendWorkbookCellImages(cell, imagesByCell.get(`${rowIndex}:${columnIndex}`), text);
8162
- appendColumnResizeHandle(cell, columnIndex, columnSizing);
9265
+ if (rowIndex === rowStart) {
9266
+ appendColumnResizeHandle(cell, columnIndex, columnSizing);
9267
+ }
8163
9268
  row.append(cell);
8164
9269
  }
8165
9270
  table.append(row);
@@ -8385,7 +9490,9 @@ function createParsedSheetTable(sheet, sheetIndex, viewport, columnSizing, reren
8385
9490
  if (value.includes("\n")) {
8386
9491
  cell.classList.add("ofv-cell-multiline");
8387
9492
  }
8388
- appendColumnResizeHandle(cell, columnIndex, columnSizing);
9493
+ if (rowIndex === viewport.rowStart) {
9494
+ appendColumnResizeHandle(cell, columnIndex, columnSizing);
9495
+ }
8389
9496
  row.append(cell);
8390
9497
  }
8391
9498
  table.append(row);
@@ -9135,6 +10242,13 @@ function legacyOfficeFormatLabel(extension) {
9135
10242
  }
9136
10243
  return "PowerPoint Binary File Format";
9137
10244
  }
10245
+ function renderLegacyWordBinary(panel, extension, arrayBuffer) {
10246
+ try {
10247
+ renderLegacyWordDocument(panel, parseLegacyWordDocument(arrayBuffer));
10248
+ } catch (error) {
10249
+ renderLegacyOfficeBinary(panel, extension, arrayBuffer, `Word \u4E8C\u8FDB\u5236\u89E3\u6790\u5931\u8D25\uFF1A${normalizeOfficeError(error)}`);
10250
+ }
10251
+ }
9138
10252
  function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
9139
10253
  const fragments = extractLegacyOfficeText(arrayBuffer);
9140
10254
  panel.replaceChildren();
@@ -13710,10 +14824,10 @@ function renderStep(panel, text, extension, ctx) {
13710
14824
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 STEP \u6587\u672C\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u5173\u952E\u51E0\u4F55\u53C2\u6570\u3002\u7CBE\u786E B-Rep/\u66F2\u9762\u6E32\u67D3\u5EFA\u8BAE\u540E\u7EED\u63A5\u5165 CAD \u5185\u6838\u6216\u670D\u52A1\u7AEF\u8F6C\u6362\u3002";
13711
14825
  const meta = document.createElement("div");
13712
14826
  meta.className = "ofv-cad-summary";
13713
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13714
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13715
- appendMeta5(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
13716
- appendMeta5(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
14827
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14828
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14829
+ appendMeta6(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
14830
+ appendMeta6(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
13717
14831
  const typeList = createCadTypeList(typeCounts);
13718
14832
  section.append(note, meta, typeList);
13719
14833
  let viewer;
@@ -13748,10 +14862,10 @@ function renderIges(panel, text, extension, ctx) {
13748
14862
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 IGES \u53C2\u6570\u533A\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u57FA\u7840\u53C2\u6570\u3002\u7CBE\u786E\u66F2\u7EBF/\u66F2\u9762\u6E32\u67D3\u5EFA\u8BAE\u540E\u7EED\u63A5\u5165 CAD \u5185\u6838\u6216\u670D\u52A1\u7AEF\u8F6C\u6362\u3002";
13749
14863
  const meta = document.createElement("div");
13750
14864
  meta.className = "ofv-cad-summary";
13751
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13752
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13753
- appendMeta5(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
13754
- appendMeta5(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
14865
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14866
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14867
+ appendMeta6(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
14868
+ appendMeta6(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
13755
14869
  const typeList = createCadTypeList(typeCounts, "\u7C7B\u578B\u53F7\u7EDF\u8BA1");
13756
14870
  section.append(note, meta, typeList);
13757
14871
  let viewer;
@@ -13785,13 +14899,13 @@ function renderIfc(panel, text) {
13785
14899
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 IFC STEP \u5B9E\u4F53\u3001BIM \u5C42\u7EA7\u548C\u5E38\u89C1\u6784\u4EF6\u7EDF\u8BA1\u3002\u51E0\u4F55\u7F51\u683C\u3001\u6750\u8D28\u548C\u5C5E\u6027\u96C6\u53EF\u540E\u7EED\u63A5\u5165 IfcOpenShell/IFC.js \u589E\u5F3A\u3002";
13786
14900
  const meta = document.createElement("div");
13787
14901
  meta.className = "ofv-cad-summary";
13788
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13789
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13790
- appendMeta5(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
13791
- appendMeta5(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
13792
- appendMeta5(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
13793
- appendMeta5(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
13794
- appendMeta5(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
14902
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14903
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14904
+ appendMeta6(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
14905
+ appendMeta6(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
14906
+ appendMeta6(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
14907
+ appendMeta6(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
14908
+ appendMeta6(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
13795
14909
  section.append(note, meta, createCadTypeList(typeCounts, "IFC \u5B9E\u4F53\u7EDF\u8BA1"));
13796
14910
  const hierarchy = createIfcHierarchy(records);
13797
14911
  if (hierarchy) {
@@ -13816,10 +14930,10 @@ function renderAcisSat(panel, text, extension, ctx) {
13816
14930
  note.textContent = "\u5F53\u524D\u7248\u672C\u4F1A\u5728\u524D\u7AEF\u89E3\u6790 ACIS SAT \u6587\u672C\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u5E38\u89C1 vertex/straight-curve \u51E0\u4F55\u7EBF\u7D22\uFF1B\u7CBE\u786E\u66F2\u9762\u3001\u62D3\u6251\u548C\u5E03\u5C14\u4F53\u4ECD\u5EFA\u8BAE\u63A5\u5165 CAD \u5185\u6838\u589E\u5F3A\u3002";
13817
14931
  const meta = document.createElement("div");
13818
14932
  meta.className = "ofv-cad-summary";
13819
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13820
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13821
- appendMeta5(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
13822
- appendMeta5(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
14933
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14934
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14935
+ appendMeta6(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
14936
+ appendMeta6(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
13823
14937
  const typeList = createCadTypeList(typeCounts);
13824
14938
  section.append(note, meta, typeList);
13825
14939
  let viewer;
@@ -13856,10 +14970,10 @@ function renderParasolidText(panel, text, extension, ctx) {
13856
14970
  note.textContent = "\u5F53\u524D\u7248\u672C\u4F1A\u5728\u524D\u7AEF\u89E3\u6790 Parasolid x_t \u6587\u672C\u7247\u6BB5\u3001\u5B9E\u4F53\u7C7B\u578B\u3001\u5750\u6807\u70B9\u548C\u57FA\u7840\u7EBF\u6BB5\u7EBF\u7D22\uFF1B\u5B8C\u6574 B-Rep\u3001\u66F2\u9762\u548C\u88C5\u914D\u5173\u7CFB\u5EFA\u8BAE\u63A5\u5165 Parasolid/HOOPS/ODA \u7B49\u4E13\u4E1A\u5185\u6838\u3002";
13857
14971
  const meta = document.createElement("div");
13858
14972
  meta.className = "ofv-cad-summary";
13859
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13860
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13861
- appendMeta5(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
13862
- appendMeta5(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
14973
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14974
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14975
+ appendMeta6(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
14976
+ appendMeta6(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
13863
14977
  const typeList = createCadTypeList(typeCounts);
13864
14978
  section.append(note, meta, typeList);
13865
14979
  let viewer;
@@ -13967,23 +15081,23 @@ function renderLayoutPreview(panel, data, ctx) {
13967
15081
  summary.setAttribute("aria-hidden", "true");
13968
15082
  summary.style.display = "none";
13969
15083
  }
13970
- appendMeta5(summary, "\u6587\u4EF6", data.fileName);
13971
- appendMeta5(summary, "\u683C\u5F0F", data.format);
15084
+ appendMeta6(summary, "\u6587\u4EF6", data.fileName);
15085
+ appendMeta6(summary, "\u683C\u5F0F", data.format);
13972
15086
  if (data.libraryName) {
13973
- appendMeta5(summary, "\u5E93", data.libraryName);
15087
+ appendMeta6(summary, "\u5E93", data.libraryName);
13974
15088
  }
13975
15089
  if (data.version) {
13976
- appendMeta5(summary, "\u7248\u672C", data.version);
15090
+ appendMeta6(summary, "\u7248\u672C", data.version);
13977
15091
  }
13978
15092
  if (data.unit) {
13979
- appendMeta5(summary, "\u5355\u4F4D", data.unit);
15093
+ appendMeta6(summary, "\u5355\u4F4D", data.unit);
13980
15094
  }
13981
- appendMeta5(summary, "Cell", data.cells.length);
13982
- appendMeta5(summary, "\u51E0\u4F55", data.shapes.length);
13983
- appendMeta5(summary, "\u5F15\u7528", data.references.length);
13984
- appendMeta5(summary, "\u6587\u5B57", data.labels.length);
15095
+ appendMeta6(summary, "Cell", data.cells.length);
15096
+ appendMeta6(summary, "\u51E0\u4F55", data.shapes.length);
15097
+ appendMeta6(summary, "\u5F15\u7528", data.references.length);
15098
+ appendMeta6(summary, "\u6587\u5B57", data.labels.length);
13985
15099
  for (const [label, value] of data.metadata) {
13986
- appendMeta5(summary, label, value);
15100
+ appendMeta6(summary, label, value);
13987
15101
  }
13988
15102
  section.append(summary);
13989
15103
  for (const noteText of [...data.notes, ...data.warnings]) {
@@ -14589,12 +15703,12 @@ function renderBinaryCad(panel, bytes, extension, fileName) {
14589
15703
  note.textContent = extension === "dwg" ? "\u5DF2\u8BC6\u522B DWG \u4E13\u6709\u4E8C\u8FDB\u5236\u56FE\u7EB8\u3002\u6838\u5FC3\u63D2\u4EF6\u9ED8\u8BA4\u63D0\u4F9B\u7248\u672C\u3001\u5BB9\u5668\u3001\u7ED3\u6784\u7EBF\u7D22\u548C\u63A5\u5165\u5EFA\u8BAE\uFF1B\u771F\u5B9E\u51E0\u4F55\u6E32\u67D3\u53EF\u901A\u8FC7 cadPlugin({ binaryRenderer }) \u63A5\u5165\u53EF\u9009\u524D\u7AEF\u5F15\u64CE\u6216\u8F6C\u6362\u670D\u52A1\u3002" : "\u5DF2\u8BC6\u522B DWF \u53D1\u5E03\u56FE\u7EB8\u3002\u6838\u5FC3\u63D2\u4EF6\u9ED8\u8BA4\u63D0\u4F9B\u5BB9\u5668\u7EBF\u7D22\u548C\u63A5\u5165\u5EFA\u8BAE\uFF1B\u9AD8\u4FDD\u771F\u9875\u9762\u6E32\u67D3\u53EF\u901A\u8FC7 cadPlugin({ binaryRenderer }) \u63A5\u5165\u4E13\u7528\u89E3\u6790\u5668\u6216\u8F6C\u6362\u670D\u52A1\u3002";
14590
15704
  const meta = document.createElement("div");
14591
15705
  meta.className = "ofv-cad-summary";
14592
- appendMeta5(meta, "\u6587\u4EF6", fileName);
14593
- appendMeta5(meta, "\u683C\u5F0F", extension.toUpperCase());
14594
- appendMeta5(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
14595
- appendMeta5(meta, "\u7B7E\u540D", byteSignature2(bytes));
14596
- appendMeta5(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
14597
- appendMeta5(meta, "\u5BB9\u5668", detectCadContainer(bytes));
15706
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
15707
+ appendMeta6(meta, "\u683C\u5F0F", extension.toUpperCase());
15708
+ appendMeta6(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
15709
+ appendMeta6(meta, "\u7B7E\u540D", byteSignature2(bytes));
15710
+ appendMeta6(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
15711
+ appendMeta6(meta, "\u5BB9\u5668", detectCadContainer(bytes));
14598
15712
  const actions = document.createElement("div");
14599
15713
  actions.className = "ofv-cad-conversion";
14600
15714
  const actionTitle = document.createElement("h4");
@@ -14634,12 +15748,12 @@ function createBinaryCadProbe(bytes, extension) {
14634
15748
  summary.textContent = "\u4E8C\u8FDB\u5236\u7ED3\u6784\u63A2\u6D4B";
14635
15749
  const meta = document.createElement("div");
14636
15750
  meta.className = "ofv-archive-probe-meta";
14637
- appendMeta5(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
14638
- appendMeta5(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
14639
- appendMeta5(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
14640
- appendMeta5(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
14641
- appendMeta5(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
14642
- appendMeta5(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
15751
+ appendMeta6(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
15752
+ appendMeta6(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
15753
+ appendMeta6(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
15754
+ appendMeta6(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
15755
+ appendMeta6(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
15756
+ appendMeta6(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
14643
15757
  details.append(summary, meta);
14644
15758
  const hints = [...probe.layerHints, ...probe.blockHints, ...probe.externalRefs].slice(0, 18);
14645
15759
  if (hints.length > 0) {
@@ -15172,9 +16286,9 @@ function createUnsupportedCadSection(extension, fileName) {
15172
16286
  const section = createSection("CAD \u589E\u5F3A\u63A5\u5165\u63D0\u793A");
15173
16287
  const meta = document.createElement("div");
15174
16288
  meta.className = "ofv-cad-summary";
15175
- appendMeta5(meta, "\u6587\u4EF6", fileName);
15176
- appendMeta5(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
15177
- appendMeta5(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
16289
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
16290
+ appendMeta6(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
16291
+ appendMeta6(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
15178
16292
  const note = document.createElement("p");
15179
16293
  note.textContent = unsupportedCadGuidance(extension);
15180
16294
  const actions = document.createElement("div");
@@ -15287,7 +16401,7 @@ function countBy(values) {
15287
16401
  }
15288
16402
  return counts;
15289
16403
  }
15290
- function appendMeta5(parent, label, value) {
16404
+ function appendMeta6(parent, label, value) {
15291
16405
  const row = document.createElement("div");
15292
16406
  row.className = "ofv-meta-row";
15293
16407
  const key = document.createElement("span");
@@ -17321,10 +18435,10 @@ function read255UInt16(bytes, offset) {
17321
18435
  return { value: code, offset };
17322
18436
  }
17323
18437
  function decodeEotString(bytes) {
17324
- const text = decodeUtf16Le(bytes).replace(/\0+$/g, "").trim();
18438
+ const text = decodeUtf16Le2(bytes).replace(/\0+$/g, "").trim();
17325
18439
  return text || new TextDecoder("latin1").decode(bytes).replace(/\0+$/g, "").trim();
17326
18440
  }
17327
- function decodeUtf16Le(bytes) {
18441
+ function decodeUtf16Le2(bytes) {
17328
18442
  let value = "";
17329
18443
  for (let index = 0; index + 1 < bytes.length; index += 2) {
17330
18444
  value += String.fromCharCode(bytes[index] | bytes[index + 1] << 8);