@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/README.md +6 -6
- package/dist/index.cjs +1176 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1176 -62
- package/dist/index.js.map +1 -1
- package/dist/style.css +313 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -384,7 +384,7 @@ function getFileNameFromUrl(source) {
|
|
|
384
384
|
function getExtension(name) {
|
|
385
385
|
const clean = name.split("?")[0]?.split("#")[0] || "";
|
|
386
386
|
const index = clean.lastIndexOf(".");
|
|
387
|
-
return index >= 0 ? clean.slice(index + 1).toLowerCase() : "";
|
|
387
|
+
return index >= 0 ? clean.slice(index + 1).split("!", 1)[0].toLowerCase() : "";
|
|
388
388
|
}
|
|
389
389
|
function isTextLike(file) {
|
|
390
390
|
const textFileName = normalizeFileName(file.name);
|
|
@@ -643,7 +643,7 @@ var defaultMessages = {
|
|
|
643
643
|
};
|
|
644
644
|
function resolveMessages(options) {
|
|
645
645
|
return {
|
|
646
|
-
...defaultMessages[options.locale || "
|
|
646
|
+
...defaultMessages[options.locale || "en-US"],
|
|
647
647
|
...options.messages
|
|
648
648
|
};
|
|
649
649
|
}
|
|
@@ -5923,6 +5923,1100 @@ function decodeXml(value) {
|
|
|
5923
5923
|
// src/plugins/office.ts
|
|
5924
5924
|
var import_jszip3 = __toESM(require("jszip"), 1);
|
|
5925
5925
|
var import_dompurify2 = __toESM(require("dompurify"), 1);
|
|
5926
|
+
|
|
5927
|
+
// src/plugins/msdoc.ts
|
|
5928
|
+
var CFB_SIGNATURE = [208, 207, 17, 224, 161, 177, 26, 225];
|
|
5929
|
+
var FREE_SECTOR = 4294967295;
|
|
5930
|
+
var END_OF_CHAIN = 4294967294;
|
|
5931
|
+
var FAT_SECTOR = 4294967293;
|
|
5932
|
+
var DIFAT_SECTOR = 4294967292;
|
|
5933
|
+
var MINI_STREAM_CUTOFF = 4096;
|
|
5934
|
+
var STSH_FC_LCB_INDEX = 1;
|
|
5935
|
+
var CLX_FC_LCB_INDEX = 33;
|
|
5936
|
+
var WORD_PAGE_BREAK = "\f";
|
|
5937
|
+
function parseLegacyWordDocument(input) {
|
|
5938
|
+
const cfb = parseCompoundFile(new Uint8Array(input));
|
|
5939
|
+
const wordDocument = cfb.getStream("WordDocument");
|
|
5940
|
+
if (!wordDocument) {
|
|
5941
|
+
throw new Error("\u672A\u627E\u5230 WordDocument \u6D41");
|
|
5942
|
+
}
|
|
5943
|
+
const fib = parseFib(wordDocument);
|
|
5944
|
+
if (fib.encrypted) {
|
|
5945
|
+
throw new Error("\u6682\u4E0D\u652F\u6301\u52A0\u5BC6\u7684 .doc \u6587\u4EF6");
|
|
5946
|
+
}
|
|
5947
|
+
const tableStreamName = fib.useOneTable ? "1Table" : "0Table";
|
|
5948
|
+
const tableStream = cfb.getStream(tableStreamName);
|
|
5949
|
+
if (!tableStream) {
|
|
5950
|
+
throw new Error(`\u672A\u627E\u5230 ${tableStreamName} \u8868\u6D41`);
|
|
5951
|
+
}
|
|
5952
|
+
const assets = extractImageAssets(cfb);
|
|
5953
|
+
const styles = parseStyleTable(tableStream, fib);
|
|
5954
|
+
const pieces = parseClxPieces(tableStream, fib.fcClx, fib.lcbClx);
|
|
5955
|
+
const text = pieces.length > 0 ? readPieceTableText(wordDocument, pieces, fib.ccpText) : readFibTextFallback(wordDocument, fib);
|
|
5956
|
+
const paragraphs = splitWordParagraphs(text);
|
|
5957
|
+
if (paragraphs.length === 0) {
|
|
5958
|
+
throw new Error("\u672A\u89E3\u6790\u5230\u53EF\u663E\u793A\u7684\u6B63\u6587\u6BB5\u843D");
|
|
5959
|
+
}
|
|
5960
|
+
const bodyParagraphs = removeTrailingFooterArtifacts(paragraphs);
|
|
5961
|
+
const blocks = buildWordBlocks(bodyParagraphs);
|
|
5962
|
+
const layout = inferLayoutHints(paragraphs, assets);
|
|
5963
|
+
return {
|
|
5964
|
+
title: inferDocumentTitle(paragraphs),
|
|
5965
|
+
paragraphs: bodyParagraphs,
|
|
5966
|
+
blocks,
|
|
5967
|
+
layout,
|
|
5968
|
+
assets,
|
|
5969
|
+
styles,
|
|
5970
|
+
stats: {
|
|
5971
|
+
streamCount: cfb.entries.length,
|
|
5972
|
+
pieceCount: pieces.length,
|
|
5973
|
+
characterCount: bodyParagraphs.join("\n").length,
|
|
5974
|
+
styleCount: styles.length,
|
|
5975
|
+
tableStream: tableStreamName
|
|
5976
|
+
},
|
|
5977
|
+
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"] : []
|
|
5978
|
+
};
|
|
5979
|
+
}
|
|
5980
|
+
function renderLegacyWordDocument(panel, document2) {
|
|
5981
|
+
panel.replaceChildren();
|
|
5982
|
+
const article = window.document.createElement("article");
|
|
5983
|
+
article.className = "ofv-msdoc-document";
|
|
5984
|
+
const pages = paginateWordBlocks(document2.blocks.slice(0, 600), document2.layout);
|
|
5985
|
+
const pageCount = inferDisplayedPageCount(document2.blocks, pages.length);
|
|
5986
|
+
const page = window.document.createElement("section");
|
|
5987
|
+
page.className = "ofv-msdoc-page";
|
|
5988
|
+
appendPageChrome(page, document2, 1, pageCount);
|
|
5989
|
+
const meta = window.document.createElement("dl");
|
|
5990
|
+
meta.className = "ofv-msdoc-meta";
|
|
5991
|
+
appendMeta4(meta, "\u683C\u5F0F", "Word 97-2003 Binary");
|
|
5992
|
+
appendMeta4(meta, "\u6B63\u6587\u6BB5\u843D", `${document2.paragraphs.length}`);
|
|
5993
|
+
appendMeta4(meta, "Piece Table", `${document2.stats.pieceCount || 0} \u6BB5`);
|
|
5994
|
+
appendMeta4(meta, "\u6837\u5F0F\u8868", `${document2.stats.styleCount || 0} \u4E2A\u6837\u5F0F`);
|
|
5995
|
+
appendMeta4(meta, "\u8868\u6D41", document2.stats.tableStream);
|
|
5996
|
+
if (document2.styles.length > 0) {
|
|
5997
|
+
appendMeta4(meta, "\u6837\u5F0F\u540D\u79F0", document2.styles.slice(0, 30).map((style) => style.name).join("\u3001"));
|
|
5998
|
+
}
|
|
5999
|
+
meta.hidden = true;
|
|
6000
|
+
page.append(meta);
|
|
6001
|
+
appendBlocksToPage(page, pages[0] || [], document2.layout);
|
|
6002
|
+
appendWarnings(page, document2);
|
|
6003
|
+
article.append(page);
|
|
6004
|
+
for (const pageBlocks of pages.slice(1)) {
|
|
6005
|
+
const nextPage = window.document.createElement("section");
|
|
6006
|
+
nextPage.className = "ofv-msdoc-page";
|
|
6007
|
+
appendPageChrome(nextPage, document2, article.children.length + 1, pageCount);
|
|
6008
|
+
appendBlocksToPage(nextPage, pageBlocks, document2.layout);
|
|
6009
|
+
article.append(nextPage);
|
|
6010
|
+
}
|
|
6011
|
+
panel.append(article);
|
|
6012
|
+
}
|
|
6013
|
+
function inferDisplayedPageCount(blocks, renderedPageCount) {
|
|
6014
|
+
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);
|
|
6015
|
+
if (tocPageNumbers.length === 0) {
|
|
6016
|
+
return renderedPageCount;
|
|
6017
|
+
}
|
|
6018
|
+
return Math.max(renderedPageCount, ...tocPageNumbers);
|
|
6019
|
+
}
|
|
6020
|
+
function appendPageChrome(page, document2, pageNumber, pageCount) {
|
|
6021
|
+
if (document2.layout.lineNumbers) {
|
|
6022
|
+
page.classList.add("ofv-msdoc-line-numbered");
|
|
6023
|
+
}
|
|
6024
|
+
page.setAttribute("aria-label", document2.title || "Word \u6587\u6863");
|
|
6025
|
+
if (document2.layout.headerBrand === "oasis") {
|
|
6026
|
+
page.append(createOasisHeader(document2.assets.find((asset) => asset.id === document2.layout.headerImageId)));
|
|
6027
|
+
}
|
|
6028
|
+
if (document2.layout.footer) {
|
|
6029
|
+
page.append(createPageFooter(document2.layout.footer, pageNumber, pageCount));
|
|
6030
|
+
}
|
|
6031
|
+
}
|
|
6032
|
+
function appendBlocksToPage(page, blocks, layout) {
|
|
6033
|
+
let lineNumber = 1;
|
|
6034
|
+
for (const block of blocks) {
|
|
6035
|
+
if (block.type === "pageBreak") {
|
|
6036
|
+
continue;
|
|
6037
|
+
}
|
|
6038
|
+
const element = renderWordBlock(block);
|
|
6039
|
+
if (layout.lineNumbers && element instanceof HTMLElement && !element.classList.contains("ofv-msdoc-page-header")) {
|
|
6040
|
+
element.dataset.line = String(lineNumber);
|
|
6041
|
+
lineNumber += estimatedLineCount(block);
|
|
6042
|
+
}
|
|
6043
|
+
page.append(element);
|
|
6044
|
+
}
|
|
6045
|
+
}
|
|
6046
|
+
function appendWarnings(page, document2) {
|
|
6047
|
+
if (document2.warnings.length === 0) {
|
|
6048
|
+
return;
|
|
6049
|
+
}
|
|
6050
|
+
const warning = window.document.createElement("p");
|
|
6051
|
+
warning.className = "ofv-msdoc-warning";
|
|
6052
|
+
warning.textContent = document2.warnings.join(" ");
|
|
6053
|
+
warning.hidden = true;
|
|
6054
|
+
page.append(warning);
|
|
6055
|
+
}
|
|
6056
|
+
function createOasisHeader(image) {
|
|
6057
|
+
const header = window.document.createElement("header");
|
|
6058
|
+
header.className = "ofv-msdoc-page-header ofv-msdoc-oasis-header";
|
|
6059
|
+
const logo = image ? createImageLogo(image) : createFallbackOasisLogo();
|
|
6060
|
+
header.append(logo);
|
|
6061
|
+
return header;
|
|
6062
|
+
}
|
|
6063
|
+
function createImageLogo(image) {
|
|
6064
|
+
const wrapper = window.document.createElement("div");
|
|
6065
|
+
wrapper.className = "ofv-msdoc-oasis-logo ofv-msdoc-oasis-logo-image";
|
|
6066
|
+
const img = window.document.createElement("img");
|
|
6067
|
+
img.src = image.dataUrl;
|
|
6068
|
+
img.alt = "OASIS";
|
|
6069
|
+
if (image.width) {
|
|
6070
|
+
img.width = image.width;
|
|
6071
|
+
}
|
|
6072
|
+
if (image.height) {
|
|
6073
|
+
img.height = image.height;
|
|
6074
|
+
}
|
|
6075
|
+
wrapper.append(img);
|
|
6076
|
+
return wrapper;
|
|
6077
|
+
}
|
|
6078
|
+
function createFallbackOasisLogo() {
|
|
6079
|
+
const logo = window.document.createElement("div");
|
|
6080
|
+
logo.className = "ofv-msdoc-oasis-logo";
|
|
6081
|
+
const word = window.document.createElement("span");
|
|
6082
|
+
word.textContent = "OASIS";
|
|
6083
|
+
const mark = window.document.createElement("span");
|
|
6084
|
+
mark.className = "ofv-msdoc-oasis-mark";
|
|
6085
|
+
mark.setAttribute("aria-hidden", "true");
|
|
6086
|
+
logo.append(word, mark);
|
|
6087
|
+
return logo;
|
|
6088
|
+
}
|
|
6089
|
+
function createPageFooter(footer, pageNumber, pageCount) {
|
|
6090
|
+
const element = window.document.createElement("footer");
|
|
6091
|
+
element.className = "ofv-msdoc-page-footer";
|
|
6092
|
+
const top = window.document.createElement("div");
|
|
6093
|
+
top.className = "ofv-msdoc-footer-row";
|
|
6094
|
+
const documentId = window.document.createElement("span");
|
|
6095
|
+
documentId.textContent = footer.documentId || "";
|
|
6096
|
+
const date = window.document.createElement("span");
|
|
6097
|
+
date.textContent = footer.date || "";
|
|
6098
|
+
top.append(documentId, date);
|
|
6099
|
+
const bottom = window.document.createElement("div");
|
|
6100
|
+
bottom.className = "ofv-msdoc-footer-row";
|
|
6101
|
+
const copyright = window.document.createElement("span");
|
|
6102
|
+
copyright.textContent = footer.copyright || "";
|
|
6103
|
+
const page = window.document.createElement("span");
|
|
6104
|
+
page.textContent = `Page ${pageNumber} of ${pageCount}`;
|
|
6105
|
+
bottom.append(copyright, page);
|
|
6106
|
+
element.append(top, bottom);
|
|
6107
|
+
return element;
|
|
6108
|
+
}
|
|
6109
|
+
function renderWordBlock(block) {
|
|
6110
|
+
if (block.type === "pageBreak") {
|
|
6111
|
+
const marker = window.document.createElement("span");
|
|
6112
|
+
marker.className = "ofv-msdoc-page-break";
|
|
6113
|
+
marker.hidden = true;
|
|
6114
|
+
return marker;
|
|
6115
|
+
}
|
|
6116
|
+
if (block.type === "table") {
|
|
6117
|
+
const table = window.document.createElement("table");
|
|
6118
|
+
table.className = "ofv-msdoc-table";
|
|
6119
|
+
const revisionColumnWidths = getRevisionTableColumnWidths(block.rows);
|
|
6120
|
+
if (revisionColumnWidths) {
|
|
6121
|
+
table.classList.add("ofv-msdoc-revision-table");
|
|
6122
|
+
const colgroup = window.document.createElement("colgroup");
|
|
6123
|
+
for (const width of revisionColumnWidths) {
|
|
6124
|
+
const col = window.document.createElement("col");
|
|
6125
|
+
col.style.width = `calc(${width}px * var(--ofv-office-zoom, 1))`;
|
|
6126
|
+
colgroup.append(col);
|
|
6127
|
+
}
|
|
6128
|
+
table.append(colgroup);
|
|
6129
|
+
}
|
|
6130
|
+
const tbody = window.document.createElement("tbody");
|
|
6131
|
+
for (const row of block.rows) {
|
|
6132
|
+
const tr = window.document.createElement("tr");
|
|
6133
|
+
const cellTag = row === block.rows[0] && block.rows.length > 1 ? "th" : "td";
|
|
6134
|
+
for (const cellText of row) {
|
|
6135
|
+
const cell = window.document.createElement(cellTag);
|
|
6136
|
+
cell.textContent = cellText;
|
|
6137
|
+
tr.append(cell);
|
|
6138
|
+
}
|
|
6139
|
+
tbody.append(tr);
|
|
6140
|
+
}
|
|
6141
|
+
table.append(tbody);
|
|
6142
|
+
return table;
|
|
6143
|
+
}
|
|
6144
|
+
if (block.type === "toc") {
|
|
6145
|
+
const paragraph2 = window.document.createElement("p");
|
|
6146
|
+
paragraph2.className = `ofv-msdoc-toc ofv-msdoc-toc-level-${block.level}`;
|
|
6147
|
+
const title = window.document.createElement("span");
|
|
6148
|
+
title.textContent = block.title;
|
|
6149
|
+
paragraph2.append(title);
|
|
6150
|
+
if (block.page) {
|
|
6151
|
+
const page = window.document.createElement("span");
|
|
6152
|
+
page.textContent = block.page;
|
|
6153
|
+
paragraph2.append(page);
|
|
6154
|
+
}
|
|
6155
|
+
return paragraph2;
|
|
6156
|
+
}
|
|
6157
|
+
const paragraph = window.document.createElement("p");
|
|
6158
|
+
const levelClass = block.type === "heading" ? ` ofv-msdoc-heading-level-${block.level}` : "";
|
|
6159
|
+
const listClass = block.type === "listItem" ? ` ofv-msdoc-list-level-${block.level}` : "";
|
|
6160
|
+
paragraph.className = `ofv-msdoc-${block.type}${levelClass}${listClass}${"indent" in block && block.indent ? " ofv-msdoc-indent" : ""}`;
|
|
6161
|
+
appendInlineRuns(paragraph, block.text, block.type === "code");
|
|
6162
|
+
return paragraph;
|
|
6163
|
+
}
|
|
6164
|
+
function appendInlineRuns(element, text, preserveTabs = false) {
|
|
6165
|
+
if (preserveTabs) {
|
|
6166
|
+
appendInlineText(element, text, true);
|
|
6167
|
+
return;
|
|
6168
|
+
}
|
|
6169
|
+
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;
|
|
6170
|
+
let offset = 0;
|
|
6171
|
+
for (const match of text.matchAll(pattern)) {
|
|
6172
|
+
const value = match[0];
|
|
6173
|
+
const index = match.index || 0;
|
|
6174
|
+
if (index > offset) {
|
|
6175
|
+
appendInlineText(element, text.slice(offset, index), preserveTabs);
|
|
6176
|
+
}
|
|
6177
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
6178
|
+
appendBracketRun(element, value);
|
|
6179
|
+
} else if (isCodeStyleRun(value)) {
|
|
6180
|
+
const code = window.document.createElement("code");
|
|
6181
|
+
code.className = "ofv-msdoc-inline-code";
|
|
6182
|
+
code.textContent = value;
|
|
6183
|
+
element.append(code);
|
|
6184
|
+
} else if (isVariableStyleRun(value)) {
|
|
6185
|
+
const em = window.document.createElement("em");
|
|
6186
|
+
em.className = "ofv-msdoc-variable";
|
|
6187
|
+
em.textContent = value;
|
|
6188
|
+
element.append(em);
|
|
6189
|
+
} else if (isRequirementKeywordRun(value)) {
|
|
6190
|
+
const em = window.document.createElement("em");
|
|
6191
|
+
em.className = "ofv-msdoc-keyword";
|
|
6192
|
+
em.textContent = value;
|
|
6193
|
+
element.append(em);
|
|
6194
|
+
} else {
|
|
6195
|
+
const link = splitLinkRun(value);
|
|
6196
|
+
const anchor = window.document.createElement("a");
|
|
6197
|
+
anchor.className = "ofv-msdoc-link-text";
|
|
6198
|
+
anchor.href = link.href;
|
|
6199
|
+
anchor.target = "_blank";
|
|
6200
|
+
anchor.rel = "noreferrer noopener";
|
|
6201
|
+
anchor.textContent = link.text;
|
|
6202
|
+
element.append(anchor);
|
|
6203
|
+
if (link.trailing) {
|
|
6204
|
+
appendInlineText(element, link.trailing, preserveTabs);
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
offset = index + value.length;
|
|
6208
|
+
}
|
|
6209
|
+
if (offset < text.length) {
|
|
6210
|
+
appendInlineText(element, text.slice(offset), preserveTabs);
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
function appendBracketRun(element, value) {
|
|
6214
|
+
const tagName = isReferenceTerm(value) ? "strong" : "em";
|
|
6215
|
+
const run = window.document.createElement(tagName);
|
|
6216
|
+
run.className = isReferenceTerm(value) ? "ofv-msdoc-ref-term" : "ofv-msdoc-instruction-run";
|
|
6217
|
+
run.textContent = value;
|
|
6218
|
+
element.append(run);
|
|
6219
|
+
}
|
|
6220
|
+
function getRevisionTableColumnWidths(rows) {
|
|
6221
|
+
const header = rows[0]?.map((cell) => cell.toLowerCase());
|
|
6222
|
+
if (!header || header.length !== 4) {
|
|
6223
|
+
return void 0;
|
|
6224
|
+
}
|
|
6225
|
+
if (header[0] === "rev" && header[1] === "date" && /whom/.test(header[2]) && header[3] === "what") {
|
|
6226
|
+
return [59, 81, 106, 191];
|
|
6227
|
+
}
|
|
6228
|
+
return void 0;
|
|
6229
|
+
}
|
|
6230
|
+
function appendInlineText(element, text, preserveTabs) {
|
|
6231
|
+
element.append(window.document.createTextNode(preserveTabs ? text : text.replace(/\t+/g, " ")));
|
|
6232
|
+
}
|
|
6233
|
+
function isReferenceTerm(value) {
|
|
6234
|
+
return /^\[[A-Z0-9][A-Z0-9.-]{1,24}\]$/.test(value);
|
|
6235
|
+
}
|
|
6236
|
+
function isCodeStyleRun(value) {
|
|
6237
|
+
return /^<\/?[A-Za-z][A-Za-z0-9:-]*>$/.test(value) || /^(?:attributeNames|DataType|OtherKeyword)$/.test(value);
|
|
6238
|
+
}
|
|
6239
|
+
function isVariableStyleRun(value) {
|
|
6240
|
+
return value === "variable";
|
|
6241
|
+
}
|
|
6242
|
+
function isRequirementKeywordRun(value) {
|
|
6243
|
+
return /^(?:must not|must|required|shall not|shall|should not|should|recommended|may|optional)$/i.test(value);
|
|
6244
|
+
}
|
|
6245
|
+
function splitLinkRun(value) {
|
|
6246
|
+
let text = value;
|
|
6247
|
+
let trailing = "";
|
|
6248
|
+
while (/[),.;:]$/.test(text)) {
|
|
6249
|
+
trailing = text.slice(-1) + trailing;
|
|
6250
|
+
text = text.slice(0, -1);
|
|
6251
|
+
}
|
|
6252
|
+
const href = /^https?:\/\//i.test(text) ? text : `mailto:${text}`;
|
|
6253
|
+
return { text, href, trailing };
|
|
6254
|
+
}
|
|
6255
|
+
function extractImageAssets(cfb) {
|
|
6256
|
+
const assets = [];
|
|
6257
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6258
|
+
for (const entry of cfb.entries) {
|
|
6259
|
+
if (entry.type !== 2) {
|
|
6260
|
+
continue;
|
|
6261
|
+
}
|
|
6262
|
+
const stream = cfb.getStream(entry.name);
|
|
6263
|
+
if (!stream || stream.length < 16) {
|
|
6264
|
+
continue;
|
|
6265
|
+
}
|
|
6266
|
+
for (const image of extractImagesFromBytes(stream, entry.name)) {
|
|
6267
|
+
const key = `${image.mimeType}:${image.bytes.length}:${image.bytes[0]}:${image.bytes[image.bytes.length - 1]}`;
|
|
6268
|
+
if (seen.has(key)) {
|
|
6269
|
+
continue;
|
|
6270
|
+
}
|
|
6271
|
+
seen.add(key);
|
|
6272
|
+
const id = `image-${assets.length + 1}`;
|
|
6273
|
+
assets.push({
|
|
6274
|
+
id,
|
|
6275
|
+
kind: "image",
|
|
6276
|
+
mimeType: image.mimeType,
|
|
6277
|
+
dataUrl: `data:${image.mimeType};base64,${bytesToBase64(image.bytes)}`,
|
|
6278
|
+
width: image.width,
|
|
6279
|
+
height: image.height
|
|
6280
|
+
});
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
return assets;
|
|
6284
|
+
}
|
|
6285
|
+
function parseStyleTable(tableStream, fib) {
|
|
6286
|
+
if (fib.lcbStshf <= 0 || fib.fcStshf < 0 || fib.fcStshf >= tableStream.length) {
|
|
6287
|
+
return [];
|
|
6288
|
+
}
|
|
6289
|
+
const bytes = tableStream.subarray(fib.fcStshf, Math.min(tableStream.length, fib.fcStshf + fib.lcbStshf));
|
|
6290
|
+
if (bytes.length < 8) {
|
|
6291
|
+
return [];
|
|
6292
|
+
}
|
|
6293
|
+
const view3 = dataView2(bytes);
|
|
6294
|
+
const cbStshi = view3.getUint16(0, true);
|
|
6295
|
+
const stshiOffset = 2;
|
|
6296
|
+
const cstd = stshiOffset + 2 <= bytes.length ? view3.getUint16(stshiOffset, true) : 0;
|
|
6297
|
+
const cbSTDBaseInFile = stshiOffset + 4 <= bytes.length ? view3.getUint16(stshiOffset + 2, true) : 10;
|
|
6298
|
+
let offset = 2 + cbStshi;
|
|
6299
|
+
const styles = [];
|
|
6300
|
+
for (let id = 0; id < cstd && offset + 2 <= bytes.length; id += 1) {
|
|
6301
|
+
const cbStd = view3.getUint16(offset, true);
|
|
6302
|
+
const stdStart = offset + 2;
|
|
6303
|
+
const stdEnd = stdStart + cbStd;
|
|
6304
|
+
if (cbStd > 0 && stdStart < bytes.length) {
|
|
6305
|
+
const style = parseStyleDefinition(bytes.subarray(stdStart, Math.min(stdEnd, bytes.length)), Math.max(10, cbSTDBaseInFile), id);
|
|
6306
|
+
if (style.name) {
|
|
6307
|
+
styles.push(style);
|
|
6308
|
+
}
|
|
6309
|
+
}
|
|
6310
|
+
offset = alignEven(stdEnd);
|
|
6311
|
+
}
|
|
6312
|
+
return styles;
|
|
6313
|
+
}
|
|
6314
|
+
function parseStyleDefinition(bytes, baseSize, id) {
|
|
6315
|
+
const base = bytes.length >= 6 ? parseStyleBase(bytes) : void 0;
|
|
6316
|
+
const nameOffset = Math.min(bytes.length, Math.max(10, baseSize));
|
|
6317
|
+
const name = parseXstz(bytes, nameOffset);
|
|
6318
|
+
return {
|
|
6319
|
+
id,
|
|
6320
|
+
name,
|
|
6321
|
+
type: styleTypeFromStk(base?.stk),
|
|
6322
|
+
basedOn: base?.basedOn,
|
|
6323
|
+
next: base?.next
|
|
6324
|
+
};
|
|
6325
|
+
}
|
|
6326
|
+
function parseStyleBase(bytes) {
|
|
6327
|
+
const view3 = dataView2(bytes);
|
|
6328
|
+
const w2 = view3.getUint16(2, true);
|
|
6329
|
+
const w3 = view3.getUint16(4, true);
|
|
6330
|
+
return {
|
|
6331
|
+
stk: w2 & 15,
|
|
6332
|
+
basedOn: w2 >> 4 & 4095,
|
|
6333
|
+
next: w3 >> 4 & 4095
|
|
6334
|
+
};
|
|
6335
|
+
}
|
|
6336
|
+
function styleTypeFromStk(stk) {
|
|
6337
|
+
if (stk === 1) {
|
|
6338
|
+
return "paragraph";
|
|
6339
|
+
}
|
|
6340
|
+
if (stk === 2) {
|
|
6341
|
+
return "character";
|
|
6342
|
+
}
|
|
6343
|
+
if (stk === 3) {
|
|
6344
|
+
return "table";
|
|
6345
|
+
}
|
|
6346
|
+
if (stk === 4) {
|
|
6347
|
+
return "numbering";
|
|
6348
|
+
}
|
|
6349
|
+
return "unknown";
|
|
6350
|
+
}
|
|
6351
|
+
function parseXstz(bytes, offset) {
|
|
6352
|
+
if (offset + 2 > bytes.length) {
|
|
6353
|
+
return "";
|
|
6354
|
+
}
|
|
6355
|
+
const view3 = dataView2(bytes);
|
|
6356
|
+
const charCount = view3.getUint16(offset, true);
|
|
6357
|
+
const start = offset + 2;
|
|
6358
|
+
const end = Math.min(bytes.length, start + charCount * 2);
|
|
6359
|
+
if (end <= start) {
|
|
6360
|
+
return "";
|
|
6361
|
+
}
|
|
6362
|
+
return decodeUtf16Le(bytes.subarray(start, end)).replace(/\0+$/g, "");
|
|
6363
|
+
}
|
|
6364
|
+
function extractImagesFromBytes(bytes, sourceName) {
|
|
6365
|
+
const images = [];
|
|
6366
|
+
for (const start of findSignatureOffsets(bytes, PNG_SIGNATURE)) {
|
|
6367
|
+
const end = findPngEnd(bytes, start);
|
|
6368
|
+
if (end > start) {
|
|
6369
|
+
const imageBytes = bytes.slice(start, end);
|
|
6370
|
+
const dimensions = readPngDimensions(imageBytes);
|
|
6371
|
+
images.push({ bytes: imageBytes, mimeType: "image/png", width: dimensions?.width, height: dimensions?.height });
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
for (const start of findSignatureOffsets(bytes, JPEG_SIGNATURE)) {
|
|
6375
|
+
const end = findJpegEnd(bytes, start);
|
|
6376
|
+
if (end > start) {
|
|
6377
|
+
images.push({ bytes: bytes.slice(start, end), mimeType: "image/jpeg" });
|
|
6378
|
+
}
|
|
6379
|
+
}
|
|
6380
|
+
if (/picture|image|data/i.test(sourceName)) {
|
|
6381
|
+
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);
|
|
6382
|
+
if (gifStart >= 0) {
|
|
6383
|
+
images.push({ bytes: bytes.slice(gifStart), mimeType: "image/gif" });
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
return images;
|
|
6387
|
+
}
|
|
6388
|
+
var PNG_SIGNATURE = Uint8Array.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
6389
|
+
var JPEG_SIGNATURE = Uint8Array.from([255, 216, 255]);
|
|
6390
|
+
function findSignatureOffsets(bytes, signature) {
|
|
6391
|
+
const offsets = [];
|
|
6392
|
+
for (let index = 0; index <= bytes.length - signature.length; index += 1) {
|
|
6393
|
+
let matches = true;
|
|
6394
|
+
for (let sigIndex = 0; sigIndex < signature.length; sigIndex += 1) {
|
|
6395
|
+
if (bytes[index + sigIndex] !== signature[sigIndex]) {
|
|
6396
|
+
matches = false;
|
|
6397
|
+
break;
|
|
6398
|
+
}
|
|
6399
|
+
}
|
|
6400
|
+
if (matches) {
|
|
6401
|
+
offsets.push(index);
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
return offsets;
|
|
6405
|
+
}
|
|
6406
|
+
function findPngEnd(bytes, start) {
|
|
6407
|
+
for (let offset = start + PNG_SIGNATURE.length; offset + 12 <= bytes.length; ) {
|
|
6408
|
+
const length = readUint32Be4(bytes, offset);
|
|
6409
|
+
const typeOffset = offset + 4;
|
|
6410
|
+
const next = offset + 12 + length;
|
|
6411
|
+
if (next > bytes.length) {
|
|
6412
|
+
return 0;
|
|
6413
|
+
}
|
|
6414
|
+
if (bytes[typeOffset] === 73 && bytes[typeOffset + 1] === 69 && bytes[typeOffset + 2] === 78 && bytes[typeOffset + 3] === 68) {
|
|
6415
|
+
return next;
|
|
6416
|
+
}
|
|
6417
|
+
offset = next;
|
|
6418
|
+
}
|
|
6419
|
+
return 0;
|
|
6420
|
+
}
|
|
6421
|
+
function findJpegEnd(bytes, start) {
|
|
6422
|
+
for (let index = start + 2; index + 1 < bytes.length; index += 1) {
|
|
6423
|
+
if (bytes[index] === 255 && bytes[index + 1] === 217) {
|
|
6424
|
+
return index + 2;
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6427
|
+
return 0;
|
|
6428
|
+
}
|
|
6429
|
+
function readPngDimensions(bytes) {
|
|
6430
|
+
if (bytes.length < 24 || !PNG_SIGNATURE.every((value, index) => bytes[index] === value)) {
|
|
6431
|
+
return void 0;
|
|
6432
|
+
}
|
|
6433
|
+
return {
|
|
6434
|
+
width: readUint32Be4(bytes, 16),
|
|
6435
|
+
height: readUint32Be4(bytes, 20)
|
|
6436
|
+
};
|
|
6437
|
+
}
|
|
6438
|
+
function readUint32Be4(bytes, offset) {
|
|
6439
|
+
return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
|
|
6440
|
+
}
|
|
6441
|
+
function bytesToBase64(bytes) {
|
|
6442
|
+
let binary = "";
|
|
6443
|
+
const chunkSize = 32768;
|
|
6444
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) {
|
|
6445
|
+
binary += String.fromCharCode(...bytes.subarray(offset, Math.min(bytes.length, offset + chunkSize)));
|
|
6446
|
+
}
|
|
6447
|
+
return btoa(binary);
|
|
6448
|
+
}
|
|
6449
|
+
function parseCompoundFile(bytes) {
|
|
6450
|
+
if (!hasCompoundSignature(bytes)) {
|
|
6451
|
+
throw new Error("\u4E0D\u662F\u6807\u51C6 OLE Compound File");
|
|
6452
|
+
}
|
|
6453
|
+
const view3 = dataView2(bytes);
|
|
6454
|
+
const sectorSize = 1 << view3.getUint16(30, true);
|
|
6455
|
+
const miniSectorSize = 1 << view3.getUint16(32, true);
|
|
6456
|
+
const fatSectorCount = view3.getUint32(44, true);
|
|
6457
|
+
const firstDirectorySector = view3.getUint32(48, true);
|
|
6458
|
+
const miniStreamCutoff = view3.getUint32(56, true) || MINI_STREAM_CUTOFF;
|
|
6459
|
+
const firstMiniFatSector = view3.getUint32(60, true);
|
|
6460
|
+
const miniFatSectorCount = view3.getUint32(64, true);
|
|
6461
|
+
const firstDifatSector = view3.getUint32(68, true);
|
|
6462
|
+
const difatSectorCount = view3.getUint32(72, true);
|
|
6463
|
+
const difat = readDifat(view3, sectorSize, firstDifatSector, difatSectorCount);
|
|
6464
|
+
const fat = readFat(view3, sectorSize, difat.slice(0, fatSectorCount));
|
|
6465
|
+
const directoryBytes = readRegularStream(bytes, sectorSize, fat, firstDirectorySector);
|
|
6466
|
+
const entries = parseDirectoryEntries(directoryBytes);
|
|
6467
|
+
const root = entries.find((entry) => entry.type === 5);
|
|
6468
|
+
const miniStream = root ? readRegularStream(bytes, sectorSize, fat, root.startSector, root.size) : new Uint8Array();
|
|
6469
|
+
const miniFat = firstMiniFatSector < END_OF_CHAIN ? readFat(view3, sectorSize, sectorChain(fat, firstMiniFatSector).slice(0, miniFatSectorCount)) : [];
|
|
6470
|
+
return {
|
|
6471
|
+
entries,
|
|
6472
|
+
getStream(name) {
|
|
6473
|
+
const wanted = normalizeStreamName(name);
|
|
6474
|
+
const entry = entries.find((item) => item.type === 2 && normalizeStreamName(item.name) === wanted);
|
|
6475
|
+
if (!entry) {
|
|
6476
|
+
return void 0;
|
|
6477
|
+
}
|
|
6478
|
+
if (entry.size < miniStreamCutoff && miniFat.length > 0) {
|
|
6479
|
+
return readMiniStream(miniStream, miniSectorSize, miniFat, entry.startSector, entry.size);
|
|
6480
|
+
}
|
|
6481
|
+
return readRegularStream(bytes, sectorSize, fat, entry.startSector, entry.size);
|
|
6482
|
+
}
|
|
6483
|
+
};
|
|
6484
|
+
}
|
|
6485
|
+
function hasCompoundSignature(bytes) {
|
|
6486
|
+
return CFB_SIGNATURE.every((value, index) => bytes[index] === value);
|
|
6487
|
+
}
|
|
6488
|
+
function readDifat(view3, sectorSize, firstDifatSector, difatSectorCount) {
|
|
6489
|
+
const difat = [];
|
|
6490
|
+
for (let offset = 76; offset < 512; offset += 4) {
|
|
6491
|
+
const sector = view3.getUint32(offset, true);
|
|
6492
|
+
if (isUsableSector(sector)) {
|
|
6493
|
+
difat.push(sector);
|
|
6494
|
+
}
|
|
6495
|
+
}
|
|
6496
|
+
let next = firstDifatSector;
|
|
6497
|
+
for (let index = 0; index < difatSectorCount && isUsableSector(next); index += 1) {
|
|
6498
|
+
const offset = sectorOffset(next, sectorSize);
|
|
6499
|
+
const entriesPerSector = sectorSize / 4 - 1;
|
|
6500
|
+
for (let item = 0; item < entriesPerSector; item += 1) {
|
|
6501
|
+
const sector = view3.getUint32(offset + item * 4, true);
|
|
6502
|
+
if (isUsableSector(sector)) {
|
|
6503
|
+
difat.push(sector);
|
|
6504
|
+
}
|
|
6505
|
+
}
|
|
6506
|
+
next = view3.getUint32(offset + entriesPerSector * 4, true);
|
|
6507
|
+
}
|
|
6508
|
+
return difat;
|
|
6509
|
+
}
|
|
6510
|
+
function readFat(view3, sectorSize, sectors) {
|
|
6511
|
+
const fat = [];
|
|
6512
|
+
for (const sector of sectors) {
|
|
6513
|
+
if (!isUsableSector(sector) && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR) {
|
|
6514
|
+
continue;
|
|
6515
|
+
}
|
|
6516
|
+
const offset = sectorOffset(sector, sectorSize);
|
|
6517
|
+
for (let item = 0; item < sectorSize / 4; item += 1) {
|
|
6518
|
+
fat.push(view3.getUint32(offset + item * 4, true));
|
|
6519
|
+
}
|
|
6520
|
+
}
|
|
6521
|
+
return fat;
|
|
6522
|
+
}
|
|
6523
|
+
function parseDirectoryEntries(bytes) {
|
|
6524
|
+
const view3 = dataView2(bytes);
|
|
6525
|
+
const entries = [];
|
|
6526
|
+
for (let offset = 0; offset + 128 <= bytes.length; offset += 128) {
|
|
6527
|
+
const nameLength = view3.getUint16(offset + 64, true);
|
|
6528
|
+
const type = bytes[offset + 66] || 0;
|
|
6529
|
+
if (type === 0 || nameLength < 2) {
|
|
6530
|
+
continue;
|
|
6531
|
+
}
|
|
6532
|
+
const nameBytes = bytes.subarray(offset, offset + Math.max(0, nameLength - 2));
|
|
6533
|
+
const name = decodeUtf16Le(nameBytes).replace(/\0+$/g, "");
|
|
6534
|
+
const startSector = view3.getUint32(offset + 116, true);
|
|
6535
|
+
const lowSize = view3.getUint32(offset + 120, true);
|
|
6536
|
+
const highSize = view3.getUint32(offset + 124, true);
|
|
6537
|
+
const size = highSize > 0 ? Number(BigInt(highSize) << 32n) + lowSize : lowSize;
|
|
6538
|
+
entries.push({ name, type, startSector, size });
|
|
6539
|
+
}
|
|
6540
|
+
return entries;
|
|
6541
|
+
}
|
|
6542
|
+
function readRegularStream(bytes, sectorSize, fat, startSector, size) {
|
|
6543
|
+
const chunks = [];
|
|
6544
|
+
for (const sector of sectorChain(fat, startSector)) {
|
|
6545
|
+
const offset = sectorOffset(sector, sectorSize);
|
|
6546
|
+
chunks.push(bytes.subarray(offset, Math.min(bytes.length, offset + sectorSize)));
|
|
6547
|
+
}
|
|
6548
|
+
return concatChunks(chunks, size);
|
|
6549
|
+
}
|
|
6550
|
+
function readMiniStream(miniStream, miniSectorSize, miniFat, startSector, size) {
|
|
6551
|
+
const chunks = [];
|
|
6552
|
+
for (const sector of sectorChain(miniFat, startSector)) {
|
|
6553
|
+
const offset = sector * miniSectorSize;
|
|
6554
|
+
chunks.push(miniStream.subarray(offset, Math.min(miniStream.length, offset + miniSectorSize)));
|
|
6555
|
+
}
|
|
6556
|
+
return concatChunks(chunks, size);
|
|
6557
|
+
}
|
|
6558
|
+
function sectorChain(fat, startSector) {
|
|
6559
|
+
const chain = [];
|
|
6560
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6561
|
+
let current = startSector;
|
|
6562
|
+
while (isUsableSector(current) && current < fat.length && !seen.has(current)) {
|
|
6563
|
+
seen.add(current);
|
|
6564
|
+
chain.push(current);
|
|
6565
|
+
current = fat[current];
|
|
6566
|
+
}
|
|
6567
|
+
return chain;
|
|
6568
|
+
}
|
|
6569
|
+
function parseFib(wordDocument) {
|
|
6570
|
+
const view3 = dataView2(wordDocument);
|
|
6571
|
+
if (view3.getUint16(0, true) !== 42476) {
|
|
6572
|
+
throw new Error("WordDocument FIB \u6807\u8BC6\u65E0\u6548");
|
|
6573
|
+
}
|
|
6574
|
+
const flags = view3.getUint16(10, true);
|
|
6575
|
+
const fcMin = view3.getUint32(24, true);
|
|
6576
|
+
const fcMac = view3.getUint32(28, true);
|
|
6577
|
+
let offset = 32;
|
|
6578
|
+
const csw = view3.getUint16(offset, true);
|
|
6579
|
+
offset += 2 + csw * 2;
|
|
6580
|
+
const fibRgLwOffset = offset + 2;
|
|
6581
|
+
const cslw = view3.getUint16(offset, true);
|
|
6582
|
+
const ccpText = fibRgLwOffset + 16 <= wordDocument.length ? Math.max(0, view3.getInt32(fibRgLwOffset + 12, true)) : 0;
|
|
6583
|
+
offset += 2 + cslw * 4;
|
|
6584
|
+
const cbRgFcLcb = view3.getUint16(offset, true);
|
|
6585
|
+
const fcLcbOffset = offset + 2;
|
|
6586
|
+
const stshOffset = fcLcbOffset + STSH_FC_LCB_INDEX * 8;
|
|
6587
|
+
const clxOffset = fcLcbOffset + CLX_FC_LCB_INDEX * 8;
|
|
6588
|
+
return {
|
|
6589
|
+
encrypted: (flags & 256) !== 0,
|
|
6590
|
+
useOneTable: (flags & 512) !== 0,
|
|
6591
|
+
textIsUnicode: (flags & 4096) !== 0,
|
|
6592
|
+
fcMin,
|
|
6593
|
+
fcMac,
|
|
6594
|
+
ccpText,
|
|
6595
|
+
fcStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset, true) : 0,
|
|
6596
|
+
lcbStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset + 4, true) : 0,
|
|
6597
|
+
fcClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset, true) : 0,
|
|
6598
|
+
lcbClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset + 4, true) : 0
|
|
6599
|
+
};
|
|
6600
|
+
}
|
|
6601
|
+
function parseClxPieces(tableStream, fcClx, lcbClx) {
|
|
6602
|
+
if (lcbClx <= 0 || fcClx < 0 || fcClx >= tableStream.length) {
|
|
6603
|
+
return [];
|
|
6604
|
+
}
|
|
6605
|
+
const end = Math.min(tableStream.length, fcClx + lcbClx);
|
|
6606
|
+
const view3 = dataView2(tableStream);
|
|
6607
|
+
let offset = fcClx;
|
|
6608
|
+
while (offset < end) {
|
|
6609
|
+
const marker = tableStream[offset];
|
|
6610
|
+
if (marker === 1) {
|
|
6611
|
+
const size = offset + 3 <= end ? view3.getUint16(offset + 1, true) : 0;
|
|
6612
|
+
offset += 3 + size;
|
|
6613
|
+
continue;
|
|
6614
|
+
}
|
|
6615
|
+
if (marker === 2) {
|
|
6616
|
+
if (offset + 5 > end) {
|
|
6617
|
+
break;
|
|
6618
|
+
}
|
|
6619
|
+
const plcSize = view3.getUint32(offset + 1, true);
|
|
6620
|
+
const plcOffset = offset + 5;
|
|
6621
|
+
return parsePlcPcd(tableStream, plcOffset, Math.min(end, plcOffset + plcSize));
|
|
6622
|
+
}
|
|
6623
|
+
offset += 1;
|
|
6624
|
+
}
|
|
6625
|
+
return [];
|
|
6626
|
+
}
|
|
6627
|
+
function parsePlcPcd(tableStream, offset, end) {
|
|
6628
|
+
const size = end - offset;
|
|
6629
|
+
if (size < 16 || (size - 4) % 12 !== 0) {
|
|
6630
|
+
return [];
|
|
6631
|
+
}
|
|
6632
|
+
const view3 = dataView2(tableStream);
|
|
6633
|
+
const pieceCount = Math.floor((size - 4) / 12);
|
|
6634
|
+
const pcdOffset = offset + (pieceCount + 1) * 4;
|
|
6635
|
+
const pieces = [];
|
|
6636
|
+
for (let index = 0; index < pieceCount; index += 1) {
|
|
6637
|
+
const cpStart = view3.getUint32(offset + index * 4, true);
|
|
6638
|
+
const cpEnd = view3.getUint32(offset + (index + 1) * 4, true);
|
|
6639
|
+
const descriptorOffset = pcdOffset + index * 8;
|
|
6640
|
+
const fcCompressed = view3.getUint32(descriptorOffset + 2, true);
|
|
6641
|
+
const compressed = (fcCompressed & 1073741824) !== 0;
|
|
6642
|
+
const fileOffset = compressed ? (fcCompressed & 1073741823) / 2 : fcCompressed;
|
|
6643
|
+
if (cpEnd > cpStart) {
|
|
6644
|
+
pieces.push({ cpStart, cpEnd, fileOffset, compressed });
|
|
6645
|
+
}
|
|
6646
|
+
}
|
|
6647
|
+
return pieces;
|
|
6648
|
+
}
|
|
6649
|
+
function readPieceTableText(wordDocument, pieces, ccpText) {
|
|
6650
|
+
let output = "";
|
|
6651
|
+
for (const piece of pieces) {
|
|
6652
|
+
const cpEnd = ccpText > 0 ? Math.min(piece.cpEnd, ccpText) : piece.cpEnd;
|
|
6653
|
+
const charCount = Math.max(0, cpEnd - piece.cpStart);
|
|
6654
|
+
if (charCount === 0) {
|
|
6655
|
+
continue;
|
|
6656
|
+
}
|
|
6657
|
+
const byteLength = charCount * (piece.compressed ? 1 : 2);
|
|
6658
|
+
const bytes = wordDocument.subarray(piece.fileOffset, Math.min(wordDocument.length, piece.fileOffset + byteLength));
|
|
6659
|
+
output += piece.compressed ? decodeWindows1252(bytes) : decodeUtf16Le(bytes);
|
|
6660
|
+
}
|
|
6661
|
+
return output;
|
|
6662
|
+
}
|
|
6663
|
+
function readFibTextFallback(wordDocument, fib) {
|
|
6664
|
+
const bytes = wordDocument.subarray(fib.fcMin, Math.min(wordDocument.length, fib.fcMac));
|
|
6665
|
+
return fib.textIsUnicode ? decodeUtf16Le(bytes) : decodeWindows1252(bytes);
|
|
6666
|
+
}
|
|
6667
|
+
function splitWordParagraphs(text) {
|
|
6668
|
+
const normalized = text.replace(/\u0000/g, "").replace(/\u0007/g, " ").replace(/\u000b/g, "\n");
|
|
6669
|
+
const paragraphs = [];
|
|
6670
|
+
for (const segment of normalized.split(/(\u000c)/)) {
|
|
6671
|
+
if (segment === "\f") {
|
|
6672
|
+
paragraphs.push(WORD_PAGE_BREAK);
|
|
6673
|
+
continue;
|
|
6674
|
+
}
|
|
6675
|
+
paragraphs.push(
|
|
6676
|
+
...segment.split(/\r|\n{2,}/).map((paragraph) => cleanWordText(paragraph)).filter((paragraph) => paragraph.length > 0 && isDisplayableParagraph(paragraph))
|
|
6677
|
+
);
|
|
6678
|
+
}
|
|
6679
|
+
return paragraphs.slice(0, 1e3);
|
|
6680
|
+
}
|
|
6681
|
+
function removeTrailingFooterArtifacts(paragraphs) {
|
|
6682
|
+
const tailStart = Math.max(0, paragraphs.length - 32);
|
|
6683
|
+
const tail = paragraphs.slice(tailStart);
|
|
6684
|
+
const relativePageFieldIndex = tail.findIndex(isFooterPageField);
|
|
6685
|
+
if (relativePageFieldIndex < 0) {
|
|
6686
|
+
return paragraphs;
|
|
6687
|
+
}
|
|
6688
|
+
let start = tailStart + relativePageFieldIndex;
|
|
6689
|
+
for (let index = start - 1; index >= tailStart; index -= 1) {
|
|
6690
|
+
const paragraph = paragraphs[index];
|
|
6691
|
+
if (paragraph === WORD_PAGE_BREAK || isLikelyFooterArtifact(paragraph)) {
|
|
6692
|
+
start = index;
|
|
6693
|
+
continue;
|
|
6694
|
+
}
|
|
6695
|
+
break;
|
|
6696
|
+
}
|
|
6697
|
+
const artifactSlice = paragraphs.slice(start);
|
|
6698
|
+
const footerCueCount = artifactSlice.filter(isLikelyFooterArtifact).length;
|
|
6699
|
+
if (footerCueCount < 2) {
|
|
6700
|
+
return paragraphs;
|
|
6701
|
+
}
|
|
6702
|
+
return paragraphs.slice(0, start);
|
|
6703
|
+
}
|
|
6704
|
+
function isFooterPageField(paragraph) {
|
|
6705
|
+
return /^(?:PAGE|Page)(?:\s+(?:PAGE|\d+))?(?:\s+of\s+(?:NUMPAGES|\d+))?$/i.test(paragraph.trim()) || /\bNUMPAGES\b/i.test(paragraph);
|
|
6706
|
+
}
|
|
6707
|
+
function isLikelyFooterArtifact(paragraph) {
|
|
6708
|
+
const value = paragraph.trim();
|
|
6709
|
+
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);
|
|
6710
|
+
}
|
|
6711
|
+
function buildWordBlocks(paragraphs) {
|
|
6712
|
+
const blocks = [];
|
|
6713
|
+
let index = 0;
|
|
6714
|
+
while (index < paragraphs.length) {
|
|
6715
|
+
const paragraph = paragraphs[index];
|
|
6716
|
+
if (paragraph === WORD_PAGE_BREAK) {
|
|
6717
|
+
blocks.push({ type: "pageBreak" });
|
|
6718
|
+
index += 1;
|
|
6719
|
+
continue;
|
|
6720
|
+
}
|
|
6721
|
+
const toc = parseTocEntry(paragraph);
|
|
6722
|
+
if (toc) {
|
|
6723
|
+
blocks.push(toc);
|
|
6724
|
+
index += 1;
|
|
6725
|
+
continue;
|
|
6726
|
+
}
|
|
6727
|
+
if (isTableRowCandidate(paragraph)) {
|
|
6728
|
+
const rows = [];
|
|
6729
|
+
while (index < paragraphs.length && isTableRowCandidate(paragraphs[index])) {
|
|
6730
|
+
rows.push(...normalizeTableRows(splitTableRow(paragraphs[index])));
|
|
6731
|
+
index += 1;
|
|
6732
|
+
}
|
|
6733
|
+
blocks.push({ type: "table", rows });
|
|
6734
|
+
continue;
|
|
6735
|
+
}
|
|
6736
|
+
blocks.push(classifyParagraphBlock(paragraph, blocks));
|
|
6737
|
+
index += 1;
|
|
6738
|
+
}
|
|
6739
|
+
return blocks;
|
|
6740
|
+
}
|
|
6741
|
+
function inferLayoutHints(paragraphs, assets) {
|
|
6742
|
+
const sample = paragraphs.slice(0, 40).join("\n");
|
|
6743
|
+
const isOasisSpec = /Word Specification Sample/.test(sample) && /\bOASIS\b/i.test(paragraphs.join("\n"));
|
|
6744
|
+
const oasisImage = isOasisSpec ? assets.find((asset) => asset.mimeType === "image/png" && asset.width && asset.height && asset.width / asset.height > 2.5) : void 0;
|
|
6745
|
+
return {
|
|
6746
|
+
lineNumbers: isOasisSpec,
|
|
6747
|
+
headerBrand: isOasisSpec ? "oasis" : void 0,
|
|
6748
|
+
headerImageId: oasisImage?.id,
|
|
6749
|
+
footer: isOasisSpec ? inferOasisFooter(paragraphs) : void 0
|
|
6750
|
+
};
|
|
6751
|
+
}
|
|
6752
|
+
function inferOasisFooter(paragraphs) {
|
|
6753
|
+
const documentId = findValueAfterLabel(paragraphs, "Document identifier:") || paragraphs.find((paragraph) => /^wd-[\w.-]+/i.test(paragraph));
|
|
6754
|
+
const subtitle = paragraphs.find((paragraph) => /\b(?:draft|version)\b/i.test(paragraph) && /\d{4}/.test(paragraph));
|
|
6755
|
+
const date = subtitle?.match(/\b\d{1,2}\s+[A-Za-z]+\s+\d{4}\b/)?.[0];
|
|
6756
|
+
const copyright = paragraphs.find((paragraph) => /Copyright.*OASIS.*All Rights Reserved/i.test(paragraph)) || "Copyright \xA9 OASIS Open 2002. All Rights Reserved.";
|
|
6757
|
+
return { documentId, date, copyright };
|
|
6758
|
+
}
|
|
6759
|
+
function findValueAfterLabel(paragraphs, label) {
|
|
6760
|
+
const index = paragraphs.findIndex((paragraph) => paragraph.toLowerCase() === label.toLowerCase());
|
|
6761
|
+
if (index < 0) {
|
|
6762
|
+
return void 0;
|
|
6763
|
+
}
|
|
6764
|
+
return paragraphs.slice(index + 1).find((paragraph) => paragraph !== WORD_PAGE_BREAK && paragraph.length > 0);
|
|
6765
|
+
}
|
|
6766
|
+
function paginateWordBlocks(blocks, layout) {
|
|
6767
|
+
const maxLines = layout.lineNumbers ? 33 : 46;
|
|
6768
|
+
const pages = [];
|
|
6769
|
+
let current = [];
|
|
6770
|
+
let usedLines = 0;
|
|
6771
|
+
for (const block of blocks) {
|
|
6772
|
+
if (block.type === "pageBreak") {
|
|
6773
|
+
if (current.length > 0) {
|
|
6774
|
+
pages.push(current);
|
|
6775
|
+
}
|
|
6776
|
+
current = [];
|
|
6777
|
+
usedLines = 0;
|
|
6778
|
+
continue;
|
|
6779
|
+
}
|
|
6780
|
+
const lines = estimatedLineCount(block);
|
|
6781
|
+
const shouldBreak = current.length > 0 && (usedLines + lines > maxLines || block.type === "heading" && usedLines > Math.floor(maxLines * 0.72));
|
|
6782
|
+
if (shouldBreak) {
|
|
6783
|
+
pages.push(current);
|
|
6784
|
+
current = [];
|
|
6785
|
+
usedLines = 0;
|
|
6786
|
+
}
|
|
6787
|
+
current.push(block);
|
|
6788
|
+
usedLines += lines;
|
|
6789
|
+
}
|
|
6790
|
+
if (current.length > 0 || pages.length === 0) {
|
|
6791
|
+
pages.push(current);
|
|
6792
|
+
}
|
|
6793
|
+
return pages;
|
|
6794
|
+
}
|
|
6795
|
+
function estimatedLineCount(block) {
|
|
6796
|
+
if (block.type === "pageBreak") {
|
|
6797
|
+
return 0;
|
|
6798
|
+
}
|
|
6799
|
+
if (block.type === "table") {
|
|
6800
|
+
return Math.max(1, block.rows.length);
|
|
6801
|
+
}
|
|
6802
|
+
if (block.type === "toc") {
|
|
6803
|
+
return 1;
|
|
6804
|
+
}
|
|
6805
|
+
const baseWidth = "indent" in block && block.indent ? 78 : 96;
|
|
6806
|
+
return Math.max(1, Math.ceil(block.text.length / baseWidth));
|
|
6807
|
+
}
|
|
6808
|
+
function classifyParagraphBlock(text, previousBlocks) {
|
|
6809
|
+
const visibleIndex = previousBlocks.filter((block) => block.type !== "toc").length;
|
|
6810
|
+
if (visibleIndex === 0 && text.length <= 140) {
|
|
6811
|
+
return { type: "title", text };
|
|
6812
|
+
}
|
|
6813
|
+
if (visibleIndex === 1 && /draft|version|20\d{2}|19\d{2}/i.test(text) && text.length <= 140) {
|
|
6814
|
+
return { type: "subtitle", text };
|
|
6815
|
+
}
|
|
6816
|
+
const headingLevel = inferHeadingLevel(text, previousBlocks);
|
|
6817
|
+
if (headingLevel) {
|
|
6818
|
+
return { type: "heading", text, level: headingLevel };
|
|
6819
|
+
}
|
|
6820
|
+
if (/^[\w\s/().-]{2,45}:$/.test(text)) {
|
|
6821
|
+
return { type: "label", text };
|
|
6822
|
+
}
|
|
6823
|
+
if (isInstructionParagraph(text)) {
|
|
6824
|
+
return { type: "instruction", text, indent: shouldIndentParagraph(previousBlocks) };
|
|
6825
|
+
}
|
|
6826
|
+
if (/^\[[-\w.]+\]\s+/.test(text)) {
|
|
6827
|
+
return { type: "reference", text };
|
|
6828
|
+
}
|
|
6829
|
+
const listLevel = inferListItemLevel(text);
|
|
6830
|
+
if (listLevel) {
|
|
6831
|
+
return { type: "listItem", text, level: listLevel };
|
|
6832
|
+
}
|
|
6833
|
+
if (isCodeLikeParagraph(text)) {
|
|
6834
|
+
return { type: "code", text, indent: shouldIndentParagraph(previousBlocks) };
|
|
6835
|
+
}
|
|
6836
|
+
return { type: "paragraph", text, indent: shouldIndentParagraph(previousBlocks) };
|
|
6837
|
+
}
|
|
6838
|
+
function isInstructionParagraph(text) {
|
|
6839
|
+
return /^\[[^\]]{8,}\]$/.test(text.trim());
|
|
6840
|
+
}
|
|
6841
|
+
function inferHeadingLevel(text, previousBlocks) {
|
|
6842
|
+
if (text.length > 120) {
|
|
6843
|
+
return void 0;
|
|
6844
|
+
}
|
|
6845
|
+
if (/^table of contents$/i.test(text)) {
|
|
6846
|
+
return 1;
|
|
6847
|
+
}
|
|
6848
|
+
if (/^(?:introduction|word styles|references|appendix\b.*|acknowledgments|revision history|notices)$/i.test(text)) {
|
|
6849
|
+
return 1;
|
|
6850
|
+
}
|
|
6851
|
+
const numbered = text.match(/^([1-9](?:\.\d+)*)\s+.+/);
|
|
6852
|
+
if (numbered) {
|
|
6853
|
+
return Math.min(3, numbered[1].split(".").length);
|
|
6854
|
+
}
|
|
6855
|
+
if (/^(?:terminology|overall style|title page|headings|paragraphs|lists|tables|code examples|character styles|normative)$/i.test(text)) {
|
|
6856
|
+
return 2;
|
|
6857
|
+
}
|
|
6858
|
+
const previousHeading = [...previousBlocks].reverse().find((block) => block.type === "heading");
|
|
6859
|
+
if (previousHeading?.type === "heading" && previousHeading.level === 1 && /^[A-Z][A-Za-z0-9 ()/-]{2,80}$/.test(text)) {
|
|
6860
|
+
return 2;
|
|
6861
|
+
}
|
|
6862
|
+
return void 0;
|
|
6863
|
+
}
|
|
6864
|
+
function shouldIndentParagraph(previousBlocks) {
|
|
6865
|
+
for (let index = previousBlocks.length - 1; index >= 0; index -= 1) {
|
|
6866
|
+
const block = previousBlocks[index];
|
|
6867
|
+
if (block.type === "toc" || block.type === "table") {
|
|
6868
|
+
continue;
|
|
6869
|
+
}
|
|
6870
|
+
if (block.type === "label") {
|
|
6871
|
+
return true;
|
|
6872
|
+
}
|
|
6873
|
+
if ((block.type === "paragraph" || block.type === "code") && block.indent) {
|
|
6874
|
+
return true;
|
|
6875
|
+
}
|
|
6876
|
+
return false;
|
|
6877
|
+
}
|
|
6878
|
+
return false;
|
|
6879
|
+
}
|
|
6880
|
+
function inferListItemLevel(text) {
|
|
6881
|
+
if (/^(?:list bullet|definition term)$/i.test(text)) {
|
|
6882
|
+
return 1;
|
|
6883
|
+
}
|
|
6884
|
+
if (/^(?:list bullet 2|list continue 2|definition for the term\.)$/i.test(text)) {
|
|
6885
|
+
return 2;
|
|
6886
|
+
}
|
|
6887
|
+
return void 0;
|
|
6888
|
+
}
|
|
6889
|
+
function parseTocEntry(text) {
|
|
6890
|
+
const tabCells = splitTableRow(text);
|
|
6891
|
+
if (tabCells.length >= 2 && /^\d{1,3}$/.test(tabCells[tabCells.length - 1] || "")) {
|
|
6892
|
+
const title2 = tabCells.slice(0, -1).join(" ").trim();
|
|
6893
|
+
if (isLikelyTocTitle(title2)) {
|
|
6894
|
+
const number2 = title2.match(/^(\d+(?:\.\d+)*)\b/)?.[1] || "";
|
|
6895
|
+
return { type: "toc", title: title2, page: tabCells[tabCells.length - 1], level: number2.includes(".") ? Math.min(3, number2.split(".").length) : 1 };
|
|
6896
|
+
}
|
|
6897
|
+
}
|
|
6898
|
+
const cleaned = text.replace(/\s+/g, " ").trim();
|
|
6899
|
+
const match = cleaned.match(/^(?:(\d+(?:\.\d+)*)\s+)?(.+?)\s+(\d{1,3})$/);
|
|
6900
|
+
if (!match || cleaned.length > 140) {
|
|
6901
|
+
return void 0;
|
|
6902
|
+
}
|
|
6903
|
+
const number = match[1] || "";
|
|
6904
|
+
const title = `${number ? `${number} ` : ""}${match[2] || ""}`.trim();
|
|
6905
|
+
const page = match[3];
|
|
6906
|
+
if (!title || !page || !/^(?:appendix\b|references\b|introduction\b|[A-Z0-9])/i.test(title)) {
|
|
6907
|
+
return void 0;
|
|
6908
|
+
}
|
|
6909
|
+
if (!isLikelyTocTitle(title)) {
|
|
6910
|
+
return void 0;
|
|
6911
|
+
}
|
|
6912
|
+
const level = number.includes(".") ? Math.min(3, number.split(".").length) : 1;
|
|
6913
|
+
return { type: "toc", title, page, level };
|
|
6914
|
+
}
|
|
6915
|
+
function isLikelyTocTitle(title) {
|
|
6916
|
+
return /^(?:appendix\b|references\b|introduction\b|[1-9](?:\.\d+)*\b|[A-Z][\w\s.-]{2,80}$)/i.test(title);
|
|
6917
|
+
}
|
|
6918
|
+
function isTableRowCandidate(text) {
|
|
6919
|
+
if (/^\[[-\w.]+\]\t+/.test(text)) {
|
|
6920
|
+
return false;
|
|
6921
|
+
}
|
|
6922
|
+
const cells = splitTableRow(text);
|
|
6923
|
+
return cells.length >= 2 && cells.some((cell) => cell.length > 0);
|
|
6924
|
+
}
|
|
6925
|
+
function splitTableRow(text) {
|
|
6926
|
+
return text.split(/\t+/).map((cell) => cell.trim()).filter(Boolean);
|
|
6927
|
+
}
|
|
6928
|
+
function normalizeTableRows(cells) {
|
|
6929
|
+
if (cells.length >= 8) {
|
|
6930
|
+
const columnCount = inferTableColumnCount(cells);
|
|
6931
|
+
if (columnCount > 1 && cells.length % columnCount === 0) {
|
|
6932
|
+
const rows = [];
|
|
6933
|
+
for (let offset = 0; offset < cells.length; offset += columnCount) {
|
|
6934
|
+
rows.push(cells.slice(offset, offset + columnCount));
|
|
6935
|
+
}
|
|
6936
|
+
return rows;
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
return [cells];
|
|
6940
|
+
}
|
|
6941
|
+
function inferTableColumnCount(cells) {
|
|
6942
|
+
const header = cells.slice(0, 6).join(" ").toLowerCase();
|
|
6943
|
+
if (/\brev\b/.test(header) && /\bdate\b/.test(header) && /whom|what/.test(header)) {
|
|
6944
|
+
return 4;
|
|
6945
|
+
}
|
|
6946
|
+
for (const candidate of [5, 4, 3, 2]) {
|
|
6947
|
+
if (cells.length % candidate === 0) {
|
|
6948
|
+
return candidate;
|
|
6949
|
+
}
|
|
6950
|
+
}
|
|
6951
|
+
return 0;
|
|
6952
|
+
}
|
|
6953
|
+
function isCodeLikeParagraph(text) {
|
|
6954
|
+
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);
|
|
6955
|
+
}
|
|
6956
|
+
function cleanWordText(value) {
|
|
6957
|
+
return stripWordFieldCodes(value).replace(/[\u0001-\u0006\u0008\u000e-\u001f]/g, "").replace(/ {2,}/g, " ").trim();
|
|
6958
|
+
}
|
|
6959
|
+
function stripWordFieldCodes(value) {
|
|
6960
|
+
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, "");
|
|
6961
|
+
}
|
|
6962
|
+
function isDisplayableParagraph(value) {
|
|
6963
|
+
if (value.length < 2) {
|
|
6964
|
+
return false;
|
|
6965
|
+
}
|
|
6966
|
+
const letters = [...value].filter((char) => /[\p{L}\p{N}]/u.test(char)).length;
|
|
6967
|
+
return letters >= Math.min(2, value.length);
|
|
6968
|
+
}
|
|
6969
|
+
function inferDocumentTitle(paragraphs) {
|
|
6970
|
+
return paragraphs.find((paragraph) => paragraph.length <= 120) || "Word \u6587\u6863";
|
|
6971
|
+
}
|
|
6972
|
+
function appendMeta4(list, label, value) {
|
|
6973
|
+
const term = window.document.createElement("dt");
|
|
6974
|
+
term.textContent = label;
|
|
6975
|
+
const detail = window.document.createElement("dd");
|
|
6976
|
+
detail.textContent = value;
|
|
6977
|
+
list.append(term, detail);
|
|
6978
|
+
}
|
|
6979
|
+
function concatChunks(chunks, size) {
|
|
6980
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
6981
|
+
const output = new Uint8Array(size === void 0 ? total : Math.min(total, size));
|
|
6982
|
+
let offset = 0;
|
|
6983
|
+
for (const chunk of chunks) {
|
|
6984
|
+
const slice = chunk.subarray(0, Math.min(chunk.length, output.length - offset));
|
|
6985
|
+
output.set(slice, offset);
|
|
6986
|
+
offset += slice.length;
|
|
6987
|
+
if (offset >= output.length) {
|
|
6988
|
+
break;
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6991
|
+
return output;
|
|
6992
|
+
}
|
|
6993
|
+
function alignEven(value) {
|
|
6994
|
+
return value % 2 === 0 ? value : value + 1;
|
|
6995
|
+
}
|
|
6996
|
+
function isUsableSector(sector) {
|
|
6997
|
+
return sector !== FREE_SECTOR && sector !== END_OF_CHAIN && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR;
|
|
6998
|
+
}
|
|
6999
|
+
function sectorOffset(sector, sectorSize) {
|
|
7000
|
+
return (sector + 1) * sectorSize;
|
|
7001
|
+
}
|
|
7002
|
+
function normalizeStreamName(name) {
|
|
7003
|
+
return name.replace(/^\/+/, "").toLowerCase();
|
|
7004
|
+
}
|
|
7005
|
+
function decodeUtf16Le(bytes) {
|
|
7006
|
+
return new TextDecoder("utf-16le").decode(bytes);
|
|
7007
|
+
}
|
|
7008
|
+
function decodeWindows1252(bytes) {
|
|
7009
|
+
try {
|
|
7010
|
+
return new TextDecoder("windows-1252").decode(bytes);
|
|
7011
|
+
} catch {
|
|
7012
|
+
return Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
function dataView2(bytes) {
|
|
7016
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
7017
|
+
}
|
|
7018
|
+
|
|
7019
|
+
// src/plugins/office.ts
|
|
5926
7020
|
var wordExtensions = /* @__PURE__ */ new Set(["docx", "docm", "doc", "dotx", "dotm", "dot", "rtf", "odt", "fodt", "wps"]);
|
|
5927
7021
|
var sheetExtensions = /* @__PURE__ */ new Set(["xlsx", "xls", "xlsm", "xlsb", "xlt", "xltx", "xltm", "csv", "tsv", "ods", "fods", "numbers", "et"]);
|
|
5928
7022
|
var presentationExtensions = /* @__PURE__ */ new Set(["pptx", "pptm", "ppt", "pps", "ppsx", "ppsm", "potx", "potm", "odp", "fodp", "key", "dps"]);
|
|
@@ -6033,6 +7127,8 @@ function officePlugin(options = {}) {
|
|
|
6033
7127
|
await renderOdp(panel, arrayBuffer);
|
|
6034
7128
|
} else if (extension === "fodp") {
|
|
6035
7129
|
renderOpenDocumentPresentationXml(panel, await readTextFromBuffer(arrayBuffer));
|
|
7130
|
+
} else if (extension === "doc" || extension === "dot") {
|
|
7131
|
+
renderLegacyWordBinary(panel, extension, arrayBuffer);
|
|
6036
7132
|
} else if (isLegacyOfficeBinary(extension)) {
|
|
6037
7133
|
renderLegacyOfficeBinary(panel, extension, arrayBuffer);
|
|
6038
7134
|
} else {
|
|
@@ -7421,7 +8517,7 @@ async function renderSheet(panel, arrayBuffer, extension) {
|
|
|
7421
8517
|
heading.textContent = sheetName;
|
|
7422
8518
|
const sheet = workbook.Sheets[sheetName];
|
|
7423
8519
|
const sheetImages = workbookImages.get(sheetName) || [];
|
|
7424
|
-
const range = trimWorkbookSheetRange(sheet, xlsx.utils.decode_range(sheet["!ref"] || "A1:A1"), xlsx.utils.decode_cell);
|
|
8520
|
+
const range = trimWorkbookSheetRange(sheet, xlsx.utils.decode_range(sheet["!ref"] || "A1:A1"), xlsx.utils.decode_cell, sheetImages);
|
|
7425
8521
|
const rowCount = range.e.r - range.s.r + 1;
|
|
7426
8522
|
const columnCount = range.e.c - range.s.c + 1;
|
|
7427
8523
|
const formulaRows = collectFormulaRows(sheet, range, xlsx.utils.encode_cell);
|
|
@@ -7520,7 +8616,7 @@ function renderSheetFallback(panel, extension, detail) {
|
|
|
7520
8616
|
async function readWorkbookSheetImages(arrayBuffer) {
|
|
7521
8617
|
const zip = await import_jszip3.default.loadAsync(arrayBuffer);
|
|
7522
8618
|
const fileNames = Object.keys(zip.files);
|
|
7523
|
-
if (!fileNames.some((name) => /^xl\/drawings\/.+\.xml$/i.test(name))
|
|
8619
|
+
if (!fileNames.some((name) => /^xl\/drawings\/.+\.xml$/i.test(name))) {
|
|
7524
8620
|
return /* @__PURE__ */ new Map();
|
|
7525
8621
|
}
|
|
7526
8622
|
const workbookXml = await zip.file("xl/workbook.xml")?.async("text");
|
|
@@ -7580,6 +8676,7 @@ async function readWorksheetDrawingImages(zip, drawingPath) {
|
|
|
7580
8676
|
const images = [];
|
|
7581
8677
|
for (const anchor of anchors) {
|
|
7582
8678
|
const from = Array.from(anchor.children).find((element) => element.localName === "from");
|
|
8679
|
+
const to = Array.from(anchor.children).find((element) => element.localName === "to");
|
|
7583
8680
|
const embedId = findDrawingImageRelationshipId(anchor);
|
|
7584
8681
|
const mediaRel = drawingRels.find((rel) => rel.id === embedId && /\/image$/i.test(rel.type));
|
|
7585
8682
|
const mediaPath = resolveOfficeRelationshipTarget(drawingPath, mediaRel?.target);
|
|
@@ -7591,6 +8688,8 @@ async function readWorksheetDrawingImages(zip, drawingPath) {
|
|
|
7591
8688
|
images.push({
|
|
7592
8689
|
row: readDrawingMarkerIndex(from, "row"),
|
|
7593
8690
|
column: readDrawingMarkerIndex(from, "col"),
|
|
8691
|
+
endRow: to ? readDrawingMarkerIndex(to, "row") : void 0,
|
|
8692
|
+
endColumn: to ? readDrawingMarkerIndex(to, "col") : void 0,
|
|
7594
8693
|
fileName: mediaPath.split("/").pop() || "image",
|
|
7595
8694
|
mimeType,
|
|
7596
8695
|
dataUrl: `data:${mimeType};base64,${await mediaFile.async("base64")}`,
|
|
@@ -8046,7 +9145,7 @@ function chartText(element) {
|
|
|
8046
9145
|
function chartStringValues(element) {
|
|
8047
9146
|
return Array.from(element.querySelectorAll("*")).filter((item) => item.localName === "v" || item.localName === "t").map((item) => item.textContent?.trim() || "").filter(Boolean);
|
|
8048
9147
|
}
|
|
8049
|
-
function trimWorkbookSheetRange(sheet, range, decodeCell) {
|
|
9148
|
+
function trimWorkbookSheetRange(sheet, range, decodeCell, images = []) {
|
|
8050
9149
|
let minRow = Number.POSITIVE_INFINITY;
|
|
8051
9150
|
let minColumn = Number.POSITIVE_INFINITY;
|
|
8052
9151
|
let maxRow = Number.NEGATIVE_INFINITY;
|
|
@@ -8071,17 +9170,21 @@ function trimWorkbookSheetRange(sheet, range, decodeCell) {
|
|
|
8071
9170
|
include(merge.s.r, merge.s.c);
|
|
8072
9171
|
include(merge.e.r, merge.e.c);
|
|
8073
9172
|
}
|
|
9173
|
+
for (const image of images) {
|
|
9174
|
+
include(image.row, image.column);
|
|
9175
|
+
include(image.endRow ?? image.row, image.endColumn ?? image.column);
|
|
9176
|
+
}
|
|
8074
9177
|
if (!Number.isFinite(minRow) || !Number.isFinite(minColumn) || !Number.isFinite(maxRow) || !Number.isFinite(maxColumn)) {
|
|
8075
9178
|
return range;
|
|
8076
9179
|
}
|
|
8077
9180
|
return {
|
|
8078
9181
|
s: {
|
|
8079
|
-
r:
|
|
8080
|
-
c:
|
|
9182
|
+
r: minRow,
|
|
9183
|
+
c: minColumn
|
|
8081
9184
|
},
|
|
8082
9185
|
e: {
|
|
8083
|
-
r:
|
|
8084
|
-
c:
|
|
9186
|
+
r: maxRow,
|
|
9187
|
+
c: maxColumn
|
|
8085
9188
|
}
|
|
8086
9189
|
};
|
|
8087
9190
|
}
|
|
@@ -8212,7 +9315,9 @@ function createWorkbookSheetTable(sheet, range, sheetIndex, viewport, encodeCell
|
|
|
8212
9315
|
cell.classList.add("ofv-cell-multiline");
|
|
8213
9316
|
}
|
|
8214
9317
|
appendWorkbookCellImages(cell, imagesByCell.get(`${rowIndex}:${columnIndex}`), text);
|
|
8215
|
-
|
|
9318
|
+
if (rowIndex === rowStart) {
|
|
9319
|
+
appendColumnResizeHandle(cell, columnIndex, columnSizing);
|
|
9320
|
+
}
|
|
8216
9321
|
row.append(cell);
|
|
8217
9322
|
}
|
|
8218
9323
|
table.append(row);
|
|
@@ -8438,7 +9543,9 @@ function createParsedSheetTable(sheet, sheetIndex, viewport, columnSizing, reren
|
|
|
8438
9543
|
if (value.includes("\n")) {
|
|
8439
9544
|
cell.classList.add("ofv-cell-multiline");
|
|
8440
9545
|
}
|
|
8441
|
-
|
|
9546
|
+
if (rowIndex === viewport.rowStart) {
|
|
9547
|
+
appendColumnResizeHandle(cell, columnIndex, columnSizing);
|
|
9548
|
+
}
|
|
8442
9549
|
row.append(cell);
|
|
8443
9550
|
}
|
|
8444
9551
|
table.append(row);
|
|
@@ -9188,6 +10295,13 @@ function legacyOfficeFormatLabel(extension) {
|
|
|
9188
10295
|
}
|
|
9189
10296
|
return "PowerPoint Binary File Format";
|
|
9190
10297
|
}
|
|
10298
|
+
function renderLegacyWordBinary(panel, extension, arrayBuffer) {
|
|
10299
|
+
try {
|
|
10300
|
+
renderLegacyWordDocument(panel, parseLegacyWordDocument(arrayBuffer));
|
|
10301
|
+
} catch (error) {
|
|
10302
|
+
renderLegacyOfficeBinary(panel, extension, arrayBuffer, `Word \u4E8C\u8FDB\u5236\u89E3\u6790\u5931\u8D25\uFF1A${normalizeOfficeError(error)}`);
|
|
10303
|
+
}
|
|
10304
|
+
}
|
|
9191
10305
|
function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
|
|
9192
10306
|
const fragments = extractLegacyOfficeText(arrayBuffer);
|
|
9193
10307
|
panel.replaceChildren();
|
|
@@ -13763,10 +14877,10 @@ function renderStep(panel, text, extension, ctx) {
|
|
|
13763
14877
|
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";
|
|
13764
14878
|
const meta = document.createElement("div");
|
|
13765
14879
|
meta.className = "ofv-cad-summary";
|
|
13766
|
-
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
14880
|
+
appendMeta6(meta, "\u5B9E\u4F53", records.length);
|
|
14881
|
+
appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
|
|
14882
|
+
appendMeta6(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
|
|
14883
|
+
appendMeta6(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
|
|
13770
14884
|
const typeList = createCadTypeList(typeCounts);
|
|
13771
14885
|
section.append(note, meta, typeList);
|
|
13772
14886
|
let viewer;
|
|
@@ -13801,10 +14915,10 @@ function renderIges(panel, text, extension, ctx) {
|
|
|
13801
14915
|
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";
|
|
13802
14916
|
const meta = document.createElement("div");
|
|
13803
14917
|
meta.className = "ofv-cad-summary";
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
14918
|
+
appendMeta6(meta, "\u5B9E\u4F53", records.length);
|
|
14919
|
+
appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
|
|
14920
|
+
appendMeta6(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
|
|
14921
|
+
appendMeta6(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
|
|
13808
14922
|
const typeList = createCadTypeList(typeCounts, "\u7C7B\u578B\u53F7\u7EDF\u8BA1");
|
|
13809
14923
|
section.append(note, meta, typeList);
|
|
13810
14924
|
let viewer;
|
|
@@ -13838,13 +14952,13 @@ function renderIfc(panel, text) {
|
|
|
13838
14952
|
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";
|
|
13839
14953
|
const meta = document.createElement("div");
|
|
13840
14954
|
meta.className = "ofv-cad-summary";
|
|
13841
|
-
|
|
13842
|
-
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
14955
|
+
appendMeta6(meta, "\u5B9E\u4F53", records.length);
|
|
14956
|
+
appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
|
|
14957
|
+
appendMeta6(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
|
|
14958
|
+
appendMeta6(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
|
|
14959
|
+
appendMeta6(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
|
|
14960
|
+
appendMeta6(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
|
|
14961
|
+
appendMeta6(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
|
|
13848
14962
|
section.append(note, meta, createCadTypeList(typeCounts, "IFC \u5B9E\u4F53\u7EDF\u8BA1"));
|
|
13849
14963
|
const hierarchy = createIfcHierarchy(records);
|
|
13850
14964
|
if (hierarchy) {
|
|
@@ -13869,10 +14983,10 @@ function renderAcisSat(panel, text, extension, ctx) {
|
|
|
13869
14983
|
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";
|
|
13870
14984
|
const meta = document.createElement("div");
|
|
13871
14985
|
meta.className = "ofv-cad-summary";
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
14986
|
+
appendMeta6(meta, "\u5B9E\u4F53", records.length);
|
|
14987
|
+
appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
|
|
14988
|
+
appendMeta6(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
|
|
14989
|
+
appendMeta6(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
|
|
13876
14990
|
const typeList = createCadTypeList(typeCounts);
|
|
13877
14991
|
section.append(note, meta, typeList);
|
|
13878
14992
|
let viewer;
|
|
@@ -13909,10 +15023,10 @@ function renderParasolidText(panel, text, extension, ctx) {
|
|
|
13909
15023
|
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";
|
|
13910
15024
|
const meta = document.createElement("div");
|
|
13911
15025
|
meta.className = "ofv-cad-summary";
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
|
|
15026
|
+
appendMeta6(meta, "\u5B9E\u4F53", records.length);
|
|
15027
|
+
appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
|
|
15028
|
+
appendMeta6(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
|
|
15029
|
+
appendMeta6(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
|
|
13916
15030
|
const typeList = createCadTypeList(typeCounts);
|
|
13917
15031
|
section.append(note, meta, typeList);
|
|
13918
15032
|
let viewer;
|
|
@@ -14020,23 +15134,23 @@ function renderLayoutPreview(panel, data, ctx) {
|
|
|
14020
15134
|
summary.setAttribute("aria-hidden", "true");
|
|
14021
15135
|
summary.style.display = "none";
|
|
14022
15136
|
}
|
|
14023
|
-
|
|
14024
|
-
|
|
15137
|
+
appendMeta6(summary, "\u6587\u4EF6", data.fileName);
|
|
15138
|
+
appendMeta6(summary, "\u683C\u5F0F", data.format);
|
|
14025
15139
|
if (data.libraryName) {
|
|
14026
|
-
|
|
15140
|
+
appendMeta6(summary, "\u5E93", data.libraryName);
|
|
14027
15141
|
}
|
|
14028
15142
|
if (data.version) {
|
|
14029
|
-
|
|
15143
|
+
appendMeta6(summary, "\u7248\u672C", data.version);
|
|
14030
15144
|
}
|
|
14031
15145
|
if (data.unit) {
|
|
14032
|
-
|
|
15146
|
+
appendMeta6(summary, "\u5355\u4F4D", data.unit);
|
|
14033
15147
|
}
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
|
|
15148
|
+
appendMeta6(summary, "Cell", data.cells.length);
|
|
15149
|
+
appendMeta6(summary, "\u51E0\u4F55", data.shapes.length);
|
|
15150
|
+
appendMeta6(summary, "\u5F15\u7528", data.references.length);
|
|
15151
|
+
appendMeta6(summary, "\u6587\u5B57", data.labels.length);
|
|
14038
15152
|
for (const [label, value] of data.metadata) {
|
|
14039
|
-
|
|
15153
|
+
appendMeta6(summary, label, value);
|
|
14040
15154
|
}
|
|
14041
15155
|
section.append(summary);
|
|
14042
15156
|
for (const noteText of [...data.notes, ...data.warnings]) {
|
|
@@ -14642,12 +15756,12 @@ function renderBinaryCad(panel, bytes, extension, fileName) {
|
|
|
14642
15756
|
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";
|
|
14643
15757
|
const meta = document.createElement("div");
|
|
14644
15758
|
meta.className = "ofv-cad-summary";
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
15759
|
+
appendMeta6(meta, "\u6587\u4EF6", fileName);
|
|
15760
|
+
appendMeta6(meta, "\u683C\u5F0F", extension.toUpperCase());
|
|
15761
|
+
appendMeta6(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
|
|
15762
|
+
appendMeta6(meta, "\u7B7E\u540D", byteSignature2(bytes));
|
|
15763
|
+
appendMeta6(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
|
|
15764
|
+
appendMeta6(meta, "\u5BB9\u5668", detectCadContainer(bytes));
|
|
14651
15765
|
const actions = document.createElement("div");
|
|
14652
15766
|
actions.className = "ofv-cad-conversion";
|
|
14653
15767
|
const actionTitle = document.createElement("h4");
|
|
@@ -14687,12 +15801,12 @@ function createBinaryCadProbe(bytes, extension) {
|
|
|
14687
15801
|
summary.textContent = "\u4E8C\u8FDB\u5236\u7ED3\u6784\u63A2\u6D4B";
|
|
14688
15802
|
const meta = document.createElement("div");
|
|
14689
15803
|
meta.className = "ofv-archive-probe-meta";
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
|
|
15804
|
+
appendMeta6(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
|
|
15805
|
+
appendMeta6(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
|
|
15806
|
+
appendMeta6(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
|
|
15807
|
+
appendMeta6(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
|
|
15808
|
+
appendMeta6(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
|
|
15809
|
+
appendMeta6(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
|
|
14696
15810
|
details.append(summary, meta);
|
|
14697
15811
|
const hints = [...probe.layerHints, ...probe.blockHints, ...probe.externalRefs].slice(0, 18);
|
|
14698
15812
|
if (hints.length > 0) {
|
|
@@ -15225,9 +16339,9 @@ function createUnsupportedCadSection(extension, fileName) {
|
|
|
15225
16339
|
const section = createSection("CAD \u589E\u5F3A\u63A5\u5165\u63D0\u793A");
|
|
15226
16340
|
const meta = document.createElement("div");
|
|
15227
16341
|
meta.className = "ofv-cad-summary";
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
16342
|
+
appendMeta6(meta, "\u6587\u4EF6", fileName);
|
|
16343
|
+
appendMeta6(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
|
|
16344
|
+
appendMeta6(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
|
|
15231
16345
|
const note = document.createElement("p");
|
|
15232
16346
|
note.textContent = unsupportedCadGuidance(extension);
|
|
15233
16347
|
const actions = document.createElement("div");
|
|
@@ -15340,7 +16454,7 @@ function countBy(values) {
|
|
|
15340
16454
|
}
|
|
15341
16455
|
return counts;
|
|
15342
16456
|
}
|
|
15343
|
-
function
|
|
16457
|
+
function appendMeta6(parent, label, value) {
|
|
15344
16458
|
const row = document.createElement("div");
|
|
15345
16459
|
row.className = "ofv-meta-row";
|
|
15346
16460
|
const key = document.createElement("span");
|
|
@@ -17374,10 +18488,10 @@ function read255UInt16(bytes, offset) {
|
|
|
17374
18488
|
return { value: code, offset };
|
|
17375
18489
|
}
|
|
17376
18490
|
function decodeEotString(bytes) {
|
|
17377
|
-
const text =
|
|
18491
|
+
const text = decodeUtf16Le2(bytes).replace(/\0+$/g, "").trim();
|
|
17378
18492
|
return text || new TextDecoder("latin1").decode(bytes).replace(/\0+$/g, "").trim();
|
|
17379
18493
|
}
|
|
17380
|
-
function
|
|
18494
|
+
function decodeUtf16Le2(bytes) {
|
|
17381
18495
|
let value = "";
|
|
17382
18496
|
for (let index = 0; index + 1 < bytes.length; index += 2) {
|
|
17383
18497
|
value += String.fromCharCode(bytes[index] | bytes[index + 1] << 8);
|