@open-file-viewer/core 0.1.16 → 0.1.17

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
@@ -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 {
@@ -9135,6 +10231,13 @@ function legacyOfficeFormatLabel(extension) {
9135
10231
  }
9136
10232
  return "PowerPoint Binary File Format";
9137
10233
  }
10234
+ function renderLegacyWordBinary(panel, extension, arrayBuffer) {
10235
+ try {
10236
+ renderLegacyWordDocument(panel, parseLegacyWordDocument(arrayBuffer));
10237
+ } catch (error) {
10238
+ renderLegacyOfficeBinary(panel, extension, arrayBuffer, `Word \u4E8C\u8FDB\u5236\u89E3\u6790\u5931\u8D25\uFF1A${normalizeOfficeError(error)}`);
10239
+ }
10240
+ }
9138
10241
  function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
9139
10242
  const fragments = extractLegacyOfficeText(arrayBuffer);
9140
10243
  panel.replaceChildren();
@@ -13710,10 +14813,10 @@ function renderStep(panel, text, extension, ctx) {
13710
14813
  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
14814
  const meta = document.createElement("div");
13712
14815
  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);
14816
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14817
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14818
+ appendMeta6(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
14819
+ appendMeta6(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
13717
14820
  const typeList = createCadTypeList(typeCounts);
13718
14821
  section.append(note, meta, typeList);
13719
14822
  let viewer;
@@ -13748,10 +14851,10 @@ function renderIges(panel, text, extension, ctx) {
13748
14851
  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
14852
  const meta = document.createElement("div");
13750
14853
  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);
14854
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14855
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14856
+ appendMeta6(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
14857
+ appendMeta6(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
13755
14858
  const typeList = createCadTypeList(typeCounts, "\u7C7B\u578B\u53F7\u7EDF\u8BA1");
13756
14859
  section.append(note, meta, typeList);
13757
14860
  let viewer;
@@ -13785,13 +14888,13 @@ function renderIfc(panel, text) {
13785
14888
  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
14889
  const meta = document.createElement("div");
13787
14890
  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));
14891
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14892
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14893
+ appendMeta6(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
14894
+ appendMeta6(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
14895
+ appendMeta6(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
14896
+ appendMeta6(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
14897
+ appendMeta6(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
13795
14898
  section.append(note, meta, createCadTypeList(typeCounts, "IFC \u5B9E\u4F53\u7EDF\u8BA1"));
13796
14899
  const hierarchy = createIfcHierarchy(records);
13797
14900
  if (hierarchy) {
@@ -13816,10 +14919,10 @@ function renderAcisSat(panel, text, extension, ctx) {
13816
14919
  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
14920
  const meta = document.createElement("div");
13818
14921
  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);
14922
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14923
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14924
+ appendMeta6(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
14925
+ appendMeta6(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
13823
14926
  const typeList = createCadTypeList(typeCounts);
13824
14927
  section.append(note, meta, typeList);
13825
14928
  let viewer;
@@ -13856,10 +14959,10 @@ function renderParasolidText(panel, text, extension, ctx) {
13856
14959
  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
14960
  const meta = document.createElement("div");
13858
14961
  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));
14962
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14963
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14964
+ appendMeta6(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
14965
+ appendMeta6(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
13863
14966
  const typeList = createCadTypeList(typeCounts);
13864
14967
  section.append(note, meta, typeList);
13865
14968
  let viewer;
@@ -13967,23 +15070,23 @@ function renderLayoutPreview(panel, data, ctx) {
13967
15070
  summary.setAttribute("aria-hidden", "true");
13968
15071
  summary.style.display = "none";
13969
15072
  }
13970
- appendMeta5(summary, "\u6587\u4EF6", data.fileName);
13971
- appendMeta5(summary, "\u683C\u5F0F", data.format);
15073
+ appendMeta6(summary, "\u6587\u4EF6", data.fileName);
15074
+ appendMeta6(summary, "\u683C\u5F0F", data.format);
13972
15075
  if (data.libraryName) {
13973
- appendMeta5(summary, "\u5E93", data.libraryName);
15076
+ appendMeta6(summary, "\u5E93", data.libraryName);
13974
15077
  }
13975
15078
  if (data.version) {
13976
- appendMeta5(summary, "\u7248\u672C", data.version);
15079
+ appendMeta6(summary, "\u7248\u672C", data.version);
13977
15080
  }
13978
15081
  if (data.unit) {
13979
- appendMeta5(summary, "\u5355\u4F4D", data.unit);
15082
+ appendMeta6(summary, "\u5355\u4F4D", data.unit);
13980
15083
  }
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);
15084
+ appendMeta6(summary, "Cell", data.cells.length);
15085
+ appendMeta6(summary, "\u51E0\u4F55", data.shapes.length);
15086
+ appendMeta6(summary, "\u5F15\u7528", data.references.length);
15087
+ appendMeta6(summary, "\u6587\u5B57", data.labels.length);
13985
15088
  for (const [label, value] of data.metadata) {
13986
- appendMeta5(summary, label, value);
15089
+ appendMeta6(summary, label, value);
13987
15090
  }
13988
15091
  section.append(summary);
13989
15092
  for (const noteText of [...data.notes, ...data.warnings]) {
@@ -14589,12 +15692,12 @@ function renderBinaryCad(panel, bytes, extension, fileName) {
14589
15692
  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
15693
  const meta = document.createElement("div");
14591
15694
  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));
15695
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
15696
+ appendMeta6(meta, "\u683C\u5F0F", extension.toUpperCase());
15697
+ appendMeta6(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
15698
+ appendMeta6(meta, "\u7B7E\u540D", byteSignature2(bytes));
15699
+ appendMeta6(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
15700
+ appendMeta6(meta, "\u5BB9\u5668", detectCadContainer(bytes));
14598
15701
  const actions = document.createElement("div");
14599
15702
  actions.className = "ofv-cad-conversion";
14600
15703
  const actionTitle = document.createElement("h4");
@@ -14634,12 +15737,12 @@ function createBinaryCadProbe(bytes, extension) {
14634
15737
  summary.textContent = "\u4E8C\u8FDB\u5236\u7ED3\u6784\u63A2\u6D4B";
14635
15738
  const meta = document.createElement("div");
14636
15739
  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");
15740
+ appendMeta6(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
15741
+ appendMeta6(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
15742
+ appendMeta6(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
15743
+ appendMeta6(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
15744
+ appendMeta6(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
15745
+ appendMeta6(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
14643
15746
  details.append(summary, meta);
14644
15747
  const hints = [...probe.layerHints, ...probe.blockHints, ...probe.externalRefs].slice(0, 18);
14645
15748
  if (hints.length > 0) {
@@ -15172,9 +16275,9 @@ function createUnsupportedCadSection(extension, fileName) {
15172
16275
  const section = createSection("CAD \u589E\u5F3A\u63A5\u5165\u63D0\u793A");
15173
16276
  const meta = document.createElement("div");
15174
16277
  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));
16278
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
16279
+ appendMeta6(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
16280
+ appendMeta6(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
15178
16281
  const note = document.createElement("p");
15179
16282
  note.textContent = unsupportedCadGuidance(extension);
15180
16283
  const actions = document.createElement("div");
@@ -15287,7 +16390,7 @@ function countBy(values) {
15287
16390
  }
15288
16391
  return counts;
15289
16392
  }
15290
- function appendMeta5(parent, label, value) {
16393
+ function appendMeta6(parent, label, value) {
15291
16394
  const row = document.createElement("div");
15292
16395
  row.className = "ofv-meta-row";
15293
16396
  const key = document.createElement("span");
@@ -17321,10 +18424,10 @@ function read255UInt16(bytes, offset) {
17321
18424
  return { value: code, offset };
17322
18425
  }
17323
18426
  function decodeEotString(bytes) {
17324
- const text = decodeUtf16Le(bytes).replace(/\0+$/g, "").trim();
18427
+ const text = decodeUtf16Le2(bytes).replace(/\0+$/g, "").trim();
17325
18428
  return text || new TextDecoder("latin1").decode(bytes).replace(/\0+$/g, "").trim();
17326
18429
  }
17327
- function decodeUtf16Le(bytes) {
18430
+ function decodeUtf16Le2(bytes) {
17328
18431
  let value = "";
17329
18432
  for (let index = 0; index + 1 < bytes.length; index += 2) {
17330
18433
  value += String.fromCharCode(bytes[index] | bytes[index + 1] << 8);