@eternalheart/react-file-preview 1.3.6 → 1.3.7

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.
Files changed (62) hide show
  1. package/lib/FilePreviewContent.d.ts.map +1 -1
  2. package/lib/FilePreviewEmbed.d.ts.map +1 -1
  3. package/lib/FilePreviewModal.d.ts.map +1 -1
  4. package/lib/ThemeContext.d.ts +18 -0
  5. package/lib/ThemeContext.d.ts.map +1 -0
  6. package/lib/chunks/index--zZy1XpK.mjs +299 -0
  7. package/lib/chunks/index--zZy1XpK.mjs.map +1 -0
  8. package/lib/chunks/index-B5tBeF0g.mjs +51 -0
  9. package/lib/chunks/index-B5tBeF0g.mjs.map +1 -0
  10. package/lib/chunks/index-BEolw_uv.mjs +528 -0
  11. package/lib/chunks/index-BEolw_uv.mjs.map +1 -0
  12. package/lib/chunks/index-BIg3vHQf.mjs +110 -0
  13. package/lib/chunks/index-BIg3vHQf.mjs.map +1 -0
  14. package/lib/chunks/index-BOEtlHD3.mjs +257 -0
  15. package/lib/chunks/index-BOEtlHD3.mjs.map +1 -0
  16. package/lib/chunks/index-BWbuffRN.mjs +152 -0
  17. package/lib/chunks/index-BWbuffRN.mjs.map +1 -0
  18. package/lib/chunks/index-BsSx9pGx.mjs +128 -0
  19. package/lib/chunks/index-BsSx9pGx.mjs.map +1 -0
  20. package/lib/chunks/index-CQABwGVP.mjs +99 -0
  21. package/lib/chunks/index-CQABwGVP.mjs.map +1 -0
  22. package/lib/chunks/index-DOMMMe9f.mjs +96 -0
  23. package/lib/chunks/index-DOMMMe9f.mjs.map +1 -0
  24. package/lib/chunks/index-DTH1IvOG.mjs +239 -0
  25. package/lib/chunks/index-DTH1IvOG.mjs.map +1 -0
  26. package/lib/chunks/index-D_8IHm6o.mjs +98 -0
  27. package/lib/chunks/index-D_8IHm6o.mjs.map +1 -0
  28. package/lib/chunks/index-DinKO2op.mjs +116 -0
  29. package/lib/chunks/index-DinKO2op.mjs.map +1 -0
  30. package/lib/chunks/index-LNXbKjrI.mjs +1900 -0
  31. package/lib/chunks/index-LNXbKjrI.mjs.map +1 -0
  32. package/lib/chunks/index-Yp36heK8.mjs +193 -0
  33. package/lib/chunks/index-Yp36heK8.mjs.map +1 -0
  34. package/lib/chunks/index-qxvk-6P6.mjs +172 -0
  35. package/lib/chunks/index-qxvk-6P6.mjs.map +1 -0
  36. package/lib/chunks/index-w0tt7Myw.mjs +96 -0
  37. package/lib/chunks/index-w0tt7Myw.mjs.map +1 -0
  38. package/lib/chunks/index-xTq9b3vw.mjs +52 -0
  39. package/lib/chunks/index-xTq9b3vw.mjs.map +1 -0
  40. package/lib/chunks/index-zDEwNk3h.mjs +103 -0
  41. package/lib/chunks/index-zDEwNk3h.mjs.map +1 -0
  42. package/lib/chunks/useShikiHighlight-DtWg9b8y.mjs +23 -0
  43. package/lib/chunks/useShikiHighlight-DtWg9b8y.mjs.map +1 -0
  44. package/lib/chunks/xspreadsheet-CyBXARuf.mjs +5215 -0
  45. package/lib/chunks/xspreadsheet-CyBXARuf.mjs.map +1 -0
  46. package/lib/hooks/useShikiHighlight.d.ts +18 -0
  47. package/lib/hooks/useShikiHighlight.d.ts.map +1 -0
  48. package/lib/index.cjs +28 -508
  49. package/lib/index.cjs.map +1 -1
  50. package/lib/index.css +1 -1
  51. package/lib/index.mjs +13 -59160
  52. package/lib/index.mjs.map +1 -1
  53. package/lib/renderers/Audio/index.d.ts.map +1 -1
  54. package/lib/renderers/Json/index.d.ts.map +1 -1
  55. package/lib/renderers/Markdown/index.d.ts.map +1 -1
  56. package/lib/renderers/RendererLoading.d.ts +3 -0
  57. package/lib/renderers/RendererLoading.d.ts.map +1 -0
  58. package/lib/renderers/Text/index.d.ts.map +1 -1
  59. package/lib/renderers/Xml/index.d.ts.map +1 -1
  60. package/lib/renderers/lazy.d.ts +38 -0
  61. package/lib/renderers/lazy.d.ts.map +1 -0
  62. package/package.json +3 -4
@@ -0,0 +1,110 @@
1
+ import { jsx as r, jsxs as s, Fragment as N } from "react/jsx-runtime";
2
+ import { useMemo as j, useState as m, useEffect as v, useCallback as S } from "react";
3
+ import { ChevronDown as L, ChevronRight as $ } from "lucide-react";
4
+ import { u as w, a as C, h as O } from "./index-LNXbKjrI.mjs";
5
+ const E = {
6
+ key: "#9cdcfe",
7
+ string: "#ce9178",
8
+ number: "#b5cea8",
9
+ keyword: "#569cd6",
10
+ bracket: "#d4d4d4",
11
+ colon: "rgb(255 255 255 / 0.6)",
12
+ collapsed: "rgb(255 255 255 / 0.4)",
13
+ arrow: "rgb(255 255 255 / 0.5)"
14
+ }, R = {
15
+ key: "#005cc5",
16
+ string: "#032f62",
17
+ number: "#005cc5",
18
+ keyword: "#d73a49",
19
+ bracket: "#24292e",
20
+ colon: "rgb(23 23 23 / 0.6)",
21
+ collapsed: "rgb(23 23 23 / 0.45)",
22
+ arrow: "rgb(23 23 23 / 0.55)"
23
+ }, b = ({ keyName: e, value: n, depth: l, defaultExpanded: y, colors: t }) => {
24
+ const i = w(), [c, a] = m(y), f = l * 20, d = S(() => a((o) => !o), []);
25
+ if (n == null || typeof n != "object")
26
+ return /* @__PURE__ */ s("div", { className: "rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm", style: { paddingLeft: `${f}px` }, children: [
27
+ /* @__PURE__ */ r("span", { className: "rfp-w-4 rfp-h-5 rfp-flex-shrink-0" }),
28
+ e !== void 0 && /* @__PURE__ */ s("span", { className: "rfp-flex-shrink-0", style: { color: t.key }, children: [
29
+ '"',
30
+ e,
31
+ '"',
32
+ /* @__PURE__ */ r("span", { style: { color: t.colon }, children: ": " })
33
+ ] }),
34
+ J(n, t)
35
+ ] });
36
+ const p = Array.isArray(n), u = (p ? n : Object.entries(n)).length, k = p ? "[" : "{", x = p ? "]" : "}";
37
+ return u === 0 ? /* @__PURE__ */ s("div", { className: "rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm", style: { paddingLeft: `${f}px` }, children: [
38
+ /* @__PURE__ */ r("span", { className: "rfp-w-4 rfp-h-5 rfp-flex-shrink-0" }),
39
+ e !== void 0 && /* @__PURE__ */ s("span", { className: "rfp-flex-shrink-0", style: { color: t.key }, children: [
40
+ '"',
41
+ e,
42
+ '"',
43
+ /* @__PURE__ */ r("span", { style: { color: t.colon }, children: ": " })
44
+ ] }),
45
+ /* @__PURE__ */ s("span", { style: { color: t.bracket }, children: [
46
+ k,
47
+ x
48
+ ] })
49
+ ] }) : /* @__PURE__ */ s("div", { children: [
50
+ /* @__PURE__ */ s(
51
+ "div",
52
+ {
53
+ className: "rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm rfp-cursor-pointer hover:rfp-bg-surface-1 rfp-select-none",
54
+ style: { paddingLeft: `${f}px` },
55
+ onClick: d,
56
+ children: [
57
+ /* @__PURE__ */ r("span", { className: "rfp-w-4 rfp-h-5 rfp-flex-shrink-0 rfp-flex rfp-items-center rfp-justify-center", style: { color: t.arrow }, children: c ? /* @__PURE__ */ r(L, { className: "rfp-w-3.5 rfp-h-3.5" }) : /* @__PURE__ */ r($, { className: "rfp-w-3.5 rfp-h-3.5" }) }),
58
+ e !== void 0 && /* @__PURE__ */ s("span", { className: "rfp-flex-shrink-0", style: { color: t.key }, children: [
59
+ '"',
60
+ e,
61
+ '"',
62
+ /* @__PURE__ */ r("span", { style: { color: t.colon }, children: ": " })
63
+ ] }),
64
+ /* @__PURE__ */ r("span", { style: { color: t.bracket }, children: k }),
65
+ !c && /* @__PURE__ */ s("span", { className: "rfp-ml-1", style: { color: t.collapsed }, children: [
66
+ p ? `${u} ${i("json.items")}` : `${u} ${i("json.keys")}`,
67
+ /* @__PURE__ */ s("span", { style: { color: t.bracket }, children: [
68
+ " ",
69
+ x
70
+ ] })
71
+ ] })
72
+ ]
73
+ }
74
+ ),
75
+ c && /* @__PURE__ */ s(N, { children: [
76
+ p ? n.map((o, g) => /* @__PURE__ */ r(b, { value: o, depth: l + 1, defaultExpanded: l < 1, colors: t }, g)) : Object.entries(n).map(([o, g]) => /* @__PURE__ */ r(b, { keyName: o, value: g, depth: l + 1, defaultExpanded: l < 1, colors: t }, o)),
77
+ /* @__PURE__ */ r("div", { className: "rfp-font-mono rfp-text-sm rfp-py-px", style: { paddingLeft: `${f + 20}px`, color: t.bracket }, children: x })
78
+ ] })
79
+ ] });
80
+ };
81
+ function J(e, n) {
82
+ return e === null ? /* @__PURE__ */ r("span", { style: { color: n.keyword, fontStyle: "italic" }, children: "null" }) : e === void 0 ? /* @__PURE__ */ r("span", { style: { color: n.keyword, fontStyle: "italic" }, children: "undefined" }) : typeof e == "boolean" ? /* @__PURE__ */ r("span", { style: { color: n.keyword }, children: String(e) }) : typeof e == "number" ? /* @__PURE__ */ r("span", { style: { color: n.number }, children: String(e) }) : typeof e == "string" ? /* @__PURE__ */ s("span", { style: { color: n.string }, children: [
83
+ '"',
84
+ e,
85
+ '"'
86
+ ] }) : /* @__PURE__ */ r("span", { style: { color: n.bracket }, children: String(e) });
87
+ }
88
+ function A(e) {
89
+ return e === "light" ? R : E;
90
+ }
91
+ const F = ({ url: e }) => {
92
+ const n = w(), l = C(), y = j(() => A(l), [l]), [t, i] = m(null), [c, a] = m(!0), [f, d] = m(null);
93
+ return v(() => {
94
+ (async () => {
95
+ try {
96
+ a(!0), d(null);
97
+ const h = await O(e);
98
+ i(JSON.parse(h));
99
+ } catch (h) {
100
+ d(n("json.load_failed")), console.error(h);
101
+ } finally {
102
+ a(!1);
103
+ }
104
+ })();
105
+ }, [e]), c ? /* @__PURE__ */ r("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ r("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) }) : f ? /* @__PURE__ */ r("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ r("div", { className: "rfp-text-fg-secondary rfp-text-center", children: /* @__PURE__ */ r("p", { className: "rfp-text-lg", children: f }) }) }) : /* @__PURE__ */ r("div", { className: "rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg rfp-py-3 rfp-pr-4", children: /* @__PURE__ */ r(b, { value: t, depth: 0, defaultExpanded: !0, colors: y }) });
106
+ };
107
+ export {
108
+ F as JsonRenderer
109
+ };
110
+ //# sourceMappingURL=index-BIg3vHQf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BIg3vHQf.mjs","sources":["../../src/renderers/Json/index.tsx"],"sourcesContent":["import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { ChevronRight, ChevronDown } from 'lucide-react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useResolvedTheme, type ResolvedTheme } from '../../ThemeContext';\n\ninterface JsonRendererProps {\n url: string;\n fileName: string;\n}\n\ninterface JsonColors {\n key: string;\n string: string;\n number: string;\n keyword: string;\n bracket: string; // { } [ ]\n colon: string; // :\n collapsed: string; // \"N items / N keys\" 折叠提示\n arrow: string; // 折叠箭头\n}\n\n// VSCode Dark Plus / GitHub Light 两套配色,与 react-syntax-highlighter 的 vscDarkPlus / vs 主题保持一致\nconst DARK_COLORS: JsonColors = {\n key: '#9cdcfe',\n string: '#ce9178',\n number: '#b5cea8',\n keyword: '#569cd6',\n bracket: '#d4d4d4',\n colon: 'rgb(255 255 255 / 0.6)',\n collapsed: 'rgb(255 255 255 / 0.4)',\n arrow: 'rgb(255 255 255 / 0.5)',\n};\n\nconst LIGHT_COLORS: JsonColors = {\n key: '#005cc5',\n string: '#032f62',\n number: '#005cc5',\n keyword: '#d73a49',\n bracket: '#24292e',\n colon: 'rgb(23 23 23 / 0.6)',\n collapsed: 'rgb(23 23 23 / 0.45)',\n arrow: 'rgb(23 23 23 / 0.55)',\n};\n\n// ---------- JSON 树节点 ----------\n\ninterface JsonNodeProps {\n keyName?: string;\n value: unknown;\n depth: number;\n defaultExpanded: boolean;\n colors: JsonColors;\n}\n\nconst JsonNode: React.FC<JsonNodeProps> = ({ keyName, value, depth, defaultExpanded, colors }) => {\n const t = useTranslator();\n const [expanded, setExpanded] = useState(defaultExpanded);\n const indent = depth * 20;\n\n const toggle = useCallback(() => setExpanded(prev => !prev), []);\n\n // 基本类型\n if (value === null || value === undefined || typeof value !== 'object') {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n {renderPrimitive(value, colors)}\n </div>\n );\n }\n\n const isArray = Array.isArray(value);\n const entries = isArray ? (value as unknown[]) : Object.entries(value as Record<string, unknown>);\n const count = entries.length;\n const openBracket = isArray ? '[' : '{';\n const closeBracket = isArray ? ']' : '}';\n\n // 空对象/数组\n if (count === 0) {\n return (\n <div className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm\" style={{ paddingLeft: `${indent}px` }}>\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0\" />\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}{closeBracket}</span>\n </div>\n );\n }\n\n return (\n <div>\n {/* 折叠行 */}\n <div\n className=\"rfp-flex rfp-items-start rfp-py-px rfp-font-mono rfp-text-sm rfp-cursor-pointer hover:rfp-bg-surface-1 rfp-select-none\"\n style={{ paddingLeft: `${indent}px` }}\n onClick={toggle}\n >\n <span className=\"rfp-w-4 rfp-h-5 rfp-flex-shrink-0 rfp-flex rfp-items-center rfp-justify-center\" style={{ color: colors.arrow }}>\n {expanded\n ? <ChevronDown className=\"rfp-w-3.5 rfp-h-3.5\" />\n : <ChevronRight className=\"rfp-w-3.5 rfp-h-3.5\" />\n }\n </span>\n {keyName !== undefined && (\n <span className=\"rfp-flex-shrink-0\" style={{ color: colors.key }}>\n \"{keyName}\"<span style={{ color: colors.colon }}>: </span>\n </span>\n )}\n <span style={{ color: colors.bracket }}>{openBracket}</span>\n {!expanded && (\n <span className=\"rfp-ml-1\" style={{ color: colors.collapsed }}>\n {isArray ? `${count} ${t('json.items')}` : `${count} ${t('json.keys')}`}\n <span style={{ color: colors.bracket }}> {closeBracket}</span>\n </span>\n )}\n </div>\n\n {/* 子节点 */}\n {expanded && (\n <>\n {isArray\n ? (value as unknown[]).map((item, i) => (\n <JsonNode key={i} value={item} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n : Object.entries(value as Record<string, unknown>).map(([k, v]) => (\n <JsonNode key={k} keyName={k} value={v} depth={depth + 1} defaultExpanded={depth < 1} colors={colors} />\n ))\n }\n <div className=\"rfp-font-mono rfp-text-sm rfp-py-px\" style={{ paddingLeft: `${indent + 20}px`, color: colors.bracket }}>\n {closeBracket}\n </div>\n </>\n )}\n </div>\n );\n};\n\nfunction renderPrimitive(value: unknown, colors: JsonColors) {\n if (value === null) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>null</span>;\n if (value === undefined) return <span style={{ color: colors.keyword, fontStyle: 'italic' }}>undefined</span>;\n if (typeof value === 'boolean') return <span style={{ color: colors.keyword }}>{String(value)}</span>;\n if (typeof value === 'number') return <span style={{ color: colors.number }}>{String(value)}</span>;\n if (typeof value === 'string') return <span style={{ color: colors.string }}>\"{value}\"</span>;\n return <span style={{ color: colors.bracket }}>{String(value)}</span>;\n}\n\nfunction pickColors(theme: ResolvedTheme): JsonColors {\n return theme === 'light' ? LIGHT_COLORS : DARK_COLORS;\n}\n\n// ---------- Main ----------\n\nexport const JsonRenderer: React.FC<JsonRendererProps> = ({ url }) => {\n const t = useTranslator();\n const resolvedTheme = useResolvedTheme();\n const colors = useMemo(() => pickColors(resolvedTheme), [resolvedTheme]);\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const loadJson = async () => {\n try {\n setLoading(true);\n setError(null);\n const text = await fetchTextUtf8(url);\n setData(JSON.parse(text));\n } catch (err) {\n setError(t('json.load_failed'));\n console.error(err);\n } finally {\n setLoading(false);\n }\n };\n loadJson();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg rfp-py-3 rfp-pr-4\">\n <JsonNode value={data} depth={0} defaultExpanded colors={colors} />\n </div>\n );\n};\n"],"names":["DARK_COLORS","LIGHT_COLORS","JsonNode","keyName","value","depth","defaultExpanded","colors","t","useTranslator","expanded","setExpanded","useState","indent","toggle","useCallback","prev","jsxs","jsx","renderPrimitive","isArray","count","openBracket","closeBracket","ChevronDown","ChevronRight","Fragment","item","i","k","v","pickColors","theme","JsonRenderer","url","resolvedTheme","useResolvedTheme","useMemo","data","setData","loading","setLoading","error","setError","useEffect","text","fetchTextUtf8","err"],"mappings":"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"}
@@ -0,0 +1,257 @@
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { useState as D, useEffect as X } from "react";
3
+ import J from "@kenjiuno/msgreader";
4
+ import { User as O, Users as E, Calendar as W, Clock as q, Tag as U, Mail as Q, Paperclip as V, Hash as Y } from "lucide-react";
5
+ import { u as Z } from "./index-LNXbKjrI.mjs";
6
+ function P(l, d) {
7
+ return l ? l.filter((o) => o.recipType === d).map((o) => {
8
+ const p = o.name || "", y = o.smtpAddress || o.email || "";
9
+ return p && y && p !== y ? `${p} <${y}>` : p || y;
10
+ }).filter(Boolean).join("; ") : "";
11
+ }
12
+ function S(l) {
13
+ if (!l) return "";
14
+ try {
15
+ const d = new Date(l);
16
+ return isNaN(d.getTime()) ? l : d.toLocaleString();
17
+ } catch {
18
+ return l;
19
+ }
20
+ }
21
+ function ee(l, d) {
22
+ if (l.bodyHtml)
23
+ return l.bodyHtml;
24
+ if (l.html)
25
+ try {
26
+ return new TextDecoder("utf-8").decode(l.html);
27
+ } catch {
28
+ }
29
+ return l.body ? `<pre style="white-space: pre-wrap; word-wrap: break-word; font-family: system-ui, sans-serif;">${l.body.replace(/&/g, "&amp;").replace(/\x3c/g, "&lt;").replace(/>/g, "&gt;")}</pre>` : `<p style="color: #999;">${d}</p>`;
30
+ }
31
+ function te(l) {
32
+ return l ? {
33
+ "IPM.Note": "Email",
34
+ "IPM.Note.SMIME": "Encrypted Email",
35
+ "IPM.Note.SMIME.MultipartSigned": "Signed Email",
36
+ "IPM.Appointment": "Appointment",
37
+ "IPM.Schedule.Meeting.Request": "Meeting Request",
38
+ "IPM.Schedule.Meeting.Canceled": "Meeting Cancellation",
39
+ "IPM.Contact": "Contact",
40
+ "IPM.Task": "Task",
41
+ "IPM.StickyNote": "Sticky Note"
42
+ }[l] || l : "";
43
+ }
44
+ const n = {
45
+ flexShrink: 0,
46
+ color: "#6b7280",
47
+ fontWeight: 500,
48
+ marginRight: "8px",
49
+ whiteSpace: "nowrap"
50
+ }, i = {
51
+ display: "flex",
52
+ alignItems: "flex-start",
53
+ gap: "8px",
54
+ padding: "6px 0"
55
+ }, r = {
56
+ flexShrink: 0,
57
+ display: "flex",
58
+ alignItems: "center",
59
+ height: "1.4em"
60
+ }, a = {
61
+ flexShrink: 0,
62
+ color: "#9ca3af"
63
+ }, c = {
64
+ color: "#111827",
65
+ wordBreak: "break-word",
66
+ flex: 1
67
+ }, ce = ({ url: l }) => {
68
+ const d = Z(), [o, p] = D(!0), [y, H] = D(null), [s, B] = D(null);
69
+ if (X(() => {
70
+ (async () => {
71
+ p(!0), H(null), B(null);
72
+ try {
73
+ const m = await fetch(l);
74
+ if (!m.ok)
75
+ throw new Error("文件加载失败");
76
+ const k = await m.arrayBuffer(), M = new J(k).getFileData();
77
+ B(M);
78
+ } catch (m) {
79
+ console.error("MSG 解析错误:", m), H(d("msg.parse_failed"));
80
+ } finally {
81
+ p(!1);
82
+ }
83
+ })();
84
+ }, [l]), o)
85
+ return /* @__PURE__ */ e("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ e("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) });
86
+ if (y || !s)
87
+ return /* @__PURE__ */ e("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ e("div", { className: "rfp-text-fg-secondary rfp-text-center", children: /* @__PURE__ */ e("p", { className: "rfp-text-lg", children: y || d("msg.parse_failed_short") }) }) });
88
+ const R = P(s.recipients, "to"), C = P(s.recipients, "cc"), L = P(s.recipients, "bcc"), u = s.senderName || "", v = s.senderSmtpAddress || s.senderEmail || "", $ = u && v && u !== v ? `${u} <${v}>` : u || v, x = S(s.clientSubmitTime), g = S(s.messageDeliveryTime), j = S(s.creationTime), b = S(s.lastModificationTime), G = s.subject || "(无主题)", z = (s.attachments || []).filter((h) => !h.attachmentHidden), K = ee(s, d("msg.empty_body")), T = te(s.messageClass), F = s.messageId || "", w = s, I = typeof w.importance == "number" ? w.importance : void 0, A = I === 2 ? "High" : I === 0 ? "Low" : "", N = typeof w.sensitivity == "number" ? w.sensitivity : void 0, _ = N !== void 0 && N !== 0 && {
89
+ 0: "Normal",
90
+ 1: "Personal",
91
+ 2: "Private",
92
+ 3: "Confidential"
93
+ }[N] || "";
94
+ return /* @__PURE__ */ e(
95
+ "div",
96
+ {
97
+ className: "rfp-w-full rfp-h-full rfp-overflow-auto",
98
+ style: { background: "white" },
99
+ children: /* @__PURE__ */ t(
100
+ "div",
101
+ {
102
+ style: {
103
+ width: "100%",
104
+ background: "white",
105
+ minHeight: "100%"
106
+ },
107
+ children: [
108
+ /* @__PURE__ */ t("div", { style: { borderBottom: "1px solid #e5e7eb", padding: "clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)", background: "#f9fafb" }, children: [
109
+ /* @__PURE__ */ e("h2", { style: { margin: "0 0 16px 0", fontSize: "clamp(16px, 2.5vw, 20px)", fontWeight: 600, color: "#111827", lineHeight: 1.4 }, children: G }),
110
+ /* @__PURE__ */ t("div", { style: { display: "flex", flexDirection: "column", fontSize: "clamp(12px, 1.8vw, 14px)", color: "#4b5563" }, children: [
111
+ $ && /* @__PURE__ */ t("div", { style: i, children: [
112
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(O, { size: 16, style: a }) }),
113
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
114
+ /* @__PURE__ */ e("span", { style: n, children: "From" }),
115
+ /* @__PURE__ */ e("span", { style: c, children: $ })
116
+ ] })
117
+ ] }),
118
+ R && /* @__PURE__ */ t("div", { style: i, children: [
119
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(E, { size: 16, style: a }) }),
120
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
121
+ /* @__PURE__ */ e("span", { style: n, children: "To" }),
122
+ /* @__PURE__ */ e("span", { style: c, children: R })
123
+ ] })
124
+ ] }),
125
+ C && /* @__PURE__ */ t("div", { style: i, children: [
126
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(E, { size: 16, style: a }) }),
127
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
128
+ /* @__PURE__ */ e("span", { style: n, children: "Cc" }),
129
+ /* @__PURE__ */ e("span", { style: c, children: C })
130
+ ] })
131
+ ] }),
132
+ L && /* @__PURE__ */ t("div", { style: i, children: [
133
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(E, { size: 16, style: a }) }),
134
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
135
+ /* @__PURE__ */ e("span", { style: n, children: "Bcc" }),
136
+ /* @__PURE__ */ e("span", { style: c, children: L })
137
+ ] })
138
+ ] }),
139
+ x && /* @__PURE__ */ t("div", { style: i, children: [
140
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(W, { size: 16, style: a }) }),
141
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
142
+ /* @__PURE__ */ e("span", { style: n, children: "Sent" }),
143
+ /* @__PURE__ */ e("span", { style: c, children: x })
144
+ ] })
145
+ ] }),
146
+ g && g !== x && /* @__PURE__ */ t("div", { style: i, children: [
147
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(q, { size: 16, style: a }) }),
148
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
149
+ /* @__PURE__ */ e("span", { style: n, children: "Received" }),
150
+ /* @__PURE__ */ e("span", { style: c, children: g })
151
+ ] })
152
+ ] }),
153
+ !x && !g && j && /* @__PURE__ */ t("div", { style: i, children: [
154
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(W, { size: 16, style: a }) }),
155
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
156
+ /* @__PURE__ */ e("span", { style: n, children: "Date" }),
157
+ /* @__PURE__ */ e("span", { style: c, children: j })
158
+ ] })
159
+ ] }),
160
+ A && /* @__PURE__ */ t("div", { style: i, children: [
161
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(U, { size: 16, style: a }) }),
162
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
163
+ /* @__PURE__ */ e("span", { style: n, children: "Importance" }),
164
+ /* @__PURE__ */ e("span", { style: {
165
+ ...c,
166
+ color: I === 2 ? "#dc2626" : "#2563eb",
167
+ fontWeight: 500
168
+ }, children: A })
169
+ ] })
170
+ ] }),
171
+ _ && /* @__PURE__ */ t("div", { style: i, children: [
172
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(U, { size: 16, style: a }) }),
173
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
174
+ /* @__PURE__ */ e("span", { style: n, children: "Sensitivity" }),
175
+ /* @__PURE__ */ e("span", { style: c, children: _ })
176
+ ] })
177
+ ] }),
178
+ T && T !== "Email" && /* @__PURE__ */ t("div", { style: i, children: [
179
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(Q, { size: 16, style: a }) }),
180
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
181
+ /* @__PURE__ */ e("span", { style: n, children: "Type" }),
182
+ /* @__PURE__ */ e("span", { style: c, children: T })
183
+ ] })
184
+ ] }),
185
+ z.length > 0 && /* @__PURE__ */ t("div", { style: { ...i, borderTop: "1px solid #e5e7eb", marginTop: "4px", paddingTop: "10px" }, children: [
186
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(V, { size: 16, style: a }) }),
187
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
188
+ /* @__PURE__ */ e("span", { style: n, children: "Attachments" }),
189
+ /* @__PURE__ */ e("div", { style: { ...c, display: "flex", flexWrap: "wrap", gap: "6px" }, children: z.map((h, m) => {
190
+ const k = h.fileName || h.name || "未知文件", f = h.contentLength, M = f ? f > 1048576 ? `${(f / 1048576).toFixed(1)} MB` : f > 1024 ? `${(f / 1024).toFixed(0)} KB` : `${f} B` : "";
191
+ return /* @__PURE__ */ t(
192
+ "span",
193
+ {
194
+ style: {
195
+ display: "inline-flex",
196
+ alignItems: "center",
197
+ gap: "4px",
198
+ padding: "2px 8px",
199
+ background: "#f3f4f6",
200
+ borderRadius: "4px",
201
+ fontSize: "13px",
202
+ color: "#374151",
203
+ border: "1px solid #e5e7eb"
204
+ },
205
+ children: [
206
+ k,
207
+ M && /* @__PURE__ */ t("span", { style: { color: "#9ca3af", fontSize: "12px" }, children: [
208
+ "(",
209
+ M,
210
+ ")"
211
+ ] })
212
+ ]
213
+ },
214
+ m
215
+ );
216
+ }) })
217
+ ] })
218
+ ] }),
219
+ F && /* @__PURE__ */ t("div", { style: { ...i, borderTop: z.length > 0 ? "none" : "1px solid #e5e7eb", marginTop: "4px", paddingTop: "10px" }, children: [
220
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(Y, { size: 16, style: a }) }),
221
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
222
+ /* @__PURE__ */ e("span", { style: n, children: "Message-ID" }),
223
+ /* @__PURE__ */ e("span", { style: { ...c, fontSize: "12px", color: "#9ca3af", fontFamily: "monospace" }, children: F })
224
+ ] })
225
+ ] }),
226
+ b && b !== x && b !== g && /* @__PURE__ */ t("div", { style: i, children: [
227
+ /* @__PURE__ */ e("span", { style: r, children: /* @__PURE__ */ e(q, { size: 16, style: a }) }),
228
+ /* @__PURE__ */ t("div", { style: { display: "flex", flex: 1 }, children: [
229
+ /* @__PURE__ */ e("span", { style: n, children: "Modified" }),
230
+ /* @__PURE__ */ e("span", { style: { ...c, fontSize: "12px", color: "#9ca3af" }, children: b })
231
+ ] })
232
+ ] })
233
+ ] })
234
+ ] }),
235
+ /* @__PURE__ */ e(
236
+ "div",
237
+ {
238
+ style: {
239
+ padding: "clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)",
240
+ fontFamily: "system-ui, -apple-system, sans-serif",
241
+ lineHeight: "1.6",
242
+ color: "#333",
243
+ overflowX: "auto"
244
+ },
245
+ dangerouslySetInnerHTML: { __html: K }
246
+ }
247
+ )
248
+ ]
249
+ }
250
+ )
251
+ }
252
+ );
253
+ };
254
+ export {
255
+ ce as MsgRenderer
256
+ };
257
+ //# sourceMappingURL=index-BOEtlHD3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BOEtlHD3.mjs","sources":["../../src/renderers/Msg/index.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport MsgReader from '@kenjiuno/msgreader';\nimport type { FieldsData } from '@kenjiuno/msgreader';\nimport { User, Users, Paperclip, Calendar, Mail, Tag, Clock, Hash } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\n\ninterface MsgRendererProps {\n url: string;\n}\n\nfunction formatRecipients(recipients: FieldsData[] | undefined, type: 'to' | 'cc' | 'bcc'): string {\n if (!recipients) return '';\n return recipients\n .filter((r) => r.recipType === type)\n .map((r) => {\n const name = r.name || '';\n const email = r.smtpAddress || r.email || '';\n if (name && email && name !== email) {\n return `${name} <${email}>`;\n }\n return name || email;\n })\n .filter(Boolean)\n .join('; ');\n}\n\nfunction formatDate(dateStr: string | undefined): string {\n if (!dateStr) return '';\n try {\n const date = new Date(dateStr);\n if (isNaN(date.getTime())) return dateStr;\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\nfunction decodeHtmlBody(fields: FieldsData, emptyBodyText: string): string {\n // 优先使用 bodyHtml (string 类型)\n if (fields.bodyHtml) {\n return fields.bodyHtml;\n }\n // 其次尝试 html (Uint8Array 类型)\n if (fields.html) {\n try {\n const decoder = new TextDecoder('utf-8');\n return decoder.decode(fields.html);\n } catch {\n // fallback\n }\n }\n // 最后使用纯文本,转换为简单 HTML\n if (fields.body) {\n return `<pre style=\"white-space: pre-wrap; word-wrap: break-word; font-family: system-ui, sans-serif;\">${fields.body.replace(/&/g, '&amp;').replace(/\\x3c/g, '&lt;').replace(/>/g, '&gt;')\n }</pre>`;\n }\n return `<p style=\"color: #999;\">${emptyBodyText}</p>`;\n}\n\nfunction formatMessageClass(messageClass: string | undefined): string {\n if (!messageClass) return '';\n const classMap: Record<string, string> = {\n 'IPM.Note': 'Email',\n 'IPM.Note.SMIME': 'Encrypted Email',\n 'IPM.Note.SMIME.MultipartSigned': 'Signed Email',\n 'IPM.Appointment': 'Appointment',\n 'IPM.Schedule.Meeting.Request': 'Meeting Request',\n 'IPM.Schedule.Meeting.Canceled': 'Meeting Cancellation',\n 'IPM.Contact': 'Contact',\n 'IPM.Task': 'Task',\n 'IPM.StickyNote': 'Sticky Note',\n };\n return classMap[messageClass] || messageClass;\n}\n\nconst labelStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#6b7280',\n fontWeight: 500,\n marginRight: '8px',\n whiteSpace: 'nowrap',\n};\n\nconst rowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n padding: '6px 0',\n};\n\nconst iconWrapStyle: React.CSSProperties = {\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n height: '1.4em',\n};\n\nconst iconStyle: React.CSSProperties = {\n flexShrink: 0,\n color: '#9ca3af',\n};\n\nconst valueStyle: React.CSSProperties = {\n color: '#111827',\n wordBreak: 'break-word' as const,\n flex: 1,\n};\n\nexport const MsgRenderer: React.FC<MsgRendererProps> = ({ url }) => {\n const t = useTranslator();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [fields, setFields] = useState<FieldsData | null>(null);\n\n useEffect(() => {\n const loadMsg = async () => {\n setLoading(true);\n setError(null);\n setFields(null);\n\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const msgReader = new MsgReader(arrayBuffer);\n const fileData = msgReader.getFileData();\n setFields(fileData);\n } catch (err) {\n console.error('MSG 解析错误:', err);\n setError(t('msg.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadMsg();\n }, [url]);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n );\n }\n\n if (error || !fields) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-fg-secondary rfp-text-center\">\n <p className=\"rfp-text-lg\">{error || t('msg.parse_failed_short')}</p>\n </div>\n </div>\n );\n }\n\n const toStr = formatRecipients(fields.recipients, 'to');\n const ccStr = formatRecipients(fields.recipients, 'cc');\n const bccStr = formatRecipients(fields.recipients, 'bcc');\n const senderName = fields.senderName || '';\n const senderEmail = fields.senderSmtpAddress || fields.senderEmail || '';\n const sender = senderName && senderEmail && senderName !== senderEmail\n ? `${senderName} <${senderEmail}>`\n : senderName || senderEmail;\n const sentDate = formatDate(fields.clientSubmitTime);\n const receivedDate = formatDate(fields.messageDeliveryTime);\n const createdDate = formatDate(fields.creationTime);\n const lastModified = formatDate(fields.lastModificationTime);\n const subject = fields.subject || '(无主题)';\n const attachments = (fields.attachments || []).filter((a) => !a.attachmentHidden);\n const bodyHtml = decodeHtmlBody(fields, t('msg.empty_body'));\n const messageClass = formatMessageClass(fields.messageClass);\n const messageId = fields.messageId || '';\n const fieldsAny = fields as FieldsData & Record<string, unknown>;\n const importance = typeof fieldsAny.importance === 'number' ? fieldsAny.importance : undefined;\n const importanceLabel = importance === 2 ? 'High' : importance === 0 ? 'Low' : '';\n const sensitivity = typeof fieldsAny.sensitivity === 'number' ? fieldsAny.sensitivity : undefined;\n const sensitivityLabels: Record<number, string> = {\n 0: 'Normal',\n 1: 'Personal',\n 2: 'Private',\n 3: 'Confidential',\n };\n const sensitivityLabel = sensitivity !== undefined && sensitivity !== 0 ? sensitivityLabels[sensitivity] || '' : '';\n\n return (\n <div\n className=\"rfp-w-full rfp-h-full rfp-overflow-auto\"\n style={{ background: 'white' }}\n >\n <div\n style={{\n width: '100%',\n background: 'white',\n minHeight: '100%',\n }}\n >\n {/* 邮件头部 */}\n <div style={{ borderBottom: '1px solid #e5e7eb', padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)', background: '#f9fafb' }}>\n {/* 主题 */}\n <h2 style={{ margin: '0 0 16px 0', fontSize: 'clamp(16px, 2.5vw, 20px)', fontWeight: 600, color: '#111827', lineHeight: 1.4 }}>\n {subject}\n </h2>\n\n {/* 元信息 */}\n <div style={{ display: 'flex', flexDirection: 'column', fontSize: 'clamp(12px, 1.8vw, 14px)', color: '#4b5563' }}>\n {sender && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><User size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>From</span>\n <span style={valueStyle}>{sender}</span>\n </div>\n </div>\n )}\n\n {toStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>To</span>\n <span style={valueStyle}>{toStr}</span>\n </div>\n </div>\n )}\n\n {ccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Cc</span>\n <span style={valueStyle}>{ccStr}</span>\n </div>\n </div>\n )}\n\n {bccStr && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Users size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Bcc</span>\n <span style={valueStyle}>{bccStr}</span>\n </div>\n </div>\n )}\n\n {sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sent</span>\n <span style={valueStyle}>{sentDate}</span>\n </div>\n </div>\n )}\n\n {receivedDate && receivedDate !== sentDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Received</span>\n <span style={valueStyle}>{receivedDate}</span>\n </div>\n </div>\n )}\n\n {!sentDate && !receivedDate && createdDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Calendar size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Date</span>\n <span style={valueStyle}>{createdDate}</span>\n </div>\n </div>\n )}\n\n {importanceLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Importance</span>\n <span style={{\n ...valueStyle,\n color: importance === 2 ? '#dc2626' : '#2563eb',\n fontWeight: 500,\n }}>\n {importanceLabel}\n </span>\n </div>\n </div>\n )}\n\n {sensitivityLabel && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Tag size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Sensitivity</span>\n <span style={valueStyle}>{sensitivityLabel}</span>\n </div>\n </div>\n )}\n\n {messageClass && messageClass !== 'Email' && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Mail size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Type</span>\n <span style={valueStyle}>{messageClass}</span>\n </div>\n </div>\n )}\n\n {attachments.length > 0 && (\n <div style={{ ...rowStyle, borderTop: '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Paperclip size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Attachments</span>\n <div style={{ ...valueStyle, display: 'flex', flexWrap: 'wrap', gap: '6px' }}>\n {attachments.map((a, i) => {\n const name = a.fileName || a.name || '未知文件';\n const size = a.contentLength;\n const sizeStr = size\n ? size > 1048576\n ? `${(size / 1048576).toFixed(1)} MB`\n : size > 1024\n ? `${(size / 1024).toFixed(0)} KB`\n : `${size} B`\n : '';\n return (\n <span\n key={i}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n padding: '2px 8px',\n background: '#f3f4f6',\n borderRadius: '4px',\n fontSize: '13px',\n color: '#374151',\n border: '1px solid #e5e7eb',\n }}\n >\n {name}\n {sizeStr && (\n <span style={{ color: '#9ca3af', fontSize: '12px' }}>({sizeStr})</span>\n )}\n </span>\n );\n })}\n </div>\n </div>\n </div>\n )}\n\n {messageId && (\n <div style={{ ...rowStyle, borderTop: attachments.length > 0 ? 'none' : '1px solid #e5e7eb', marginTop: '4px', paddingTop: '10px' }}>\n <span style={iconWrapStyle}><Hash size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Message-ID</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af', fontFamily: 'monospace' }}>{messageId}</span>\n </div>\n </div>\n )}\n\n {lastModified && lastModified !== sentDate && lastModified !== receivedDate && (\n <div style={rowStyle}>\n <span style={iconWrapStyle}><Clock size={16} style={iconStyle} /></span>\n <div style={{ display: 'flex', flex: 1 }}>\n <span style={labelStyle}>Modified</span>\n <span style={{ ...valueStyle, fontSize: '12px', color: '#9ca3af' }}>{lastModified}</span>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* 邮件正文 */}\n <div\n style={{\n padding: 'clamp(12px, 3vw, 24px) clamp(16px, 3vw, 28px)',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.6',\n color: '#333',\n overflowX: 'auto',\n }}\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n </div>\n </div>\n );\n};\n"],"names":["formatRecipients","recipients","type","r","name","email","formatDate","dateStr","date","decodeHtmlBody","fields","emptyBodyText","formatMessageClass","messageClass","labelStyle","rowStyle","iconWrapStyle","iconStyle","valueStyle","MsgRenderer","url","t","useTranslator","loading","setLoading","useState","error","setError","setFields","useEffect","response","arrayBuffer","fileData","MsgReader","err","jsx","toStr","ccStr","bccStr","senderName","senderEmail","sender","sentDate","receivedDate","createdDate","lastModified","subject","attachments","a","bodyHtml","messageId","fieldsAny","importance","importanceLabel","sensitivity","sensitivityLabel","jsxs","User","Users","Calendar","Clock","Tag","Mail","Paperclip","i","size","sizeStr","Hash"],"mappings":";;;;;AAUA,SAASA,EAAiBC,GAAsCC,GAAmC;AACjG,SAAKD,IACEA,EACJ,OAAO,CAACE,MAAMA,EAAE,cAAcD,CAAI,EAClC,IAAI,CAACC,MAAM;AACV,UAAMC,IAAOD,EAAE,QAAQ,IACjBE,IAAQF,EAAE,eAAeA,EAAE,SAAS;AAC1C,WAAIC,KAAQC,KAASD,MAASC,IACrB,GAAGD,CAAI,KAAKC,CAAK,MAEnBD,KAAQC;AAAA,EACjB,CAAC,EACA,OAAO,OAAO,EACd,KAAK,IAAI,IAZY;AAa1B;AAEA,SAASC,EAAWC,GAAqC;AACvD,MAAI,CAACA,EAAS,QAAO;AACrB,MAAI;AACF,UAAMC,IAAO,IAAI,KAAKD,CAAO;AAC7B,WAAI,MAAMC,EAAK,QAAA,CAAS,IAAUD,IAC3BC,EAAK,eAAA;AAAA,EACd,QAAQ;AACN,WAAOD;AAAA,EACT;AACF;AAEA,SAASE,GAAeC,GAAoBC,GAA+B;AAEzE,MAAID,EAAO;AACT,WAAOA,EAAO;AAGhB,MAAIA,EAAO;AACT,QAAI;AAEF,aADgB,IAAI,YAAY,OAAO,EACxB,OAAOA,EAAO,IAAI;AAAA,IACnC,QAAQ;AAAA,IAER;AAGF,SAAIA,EAAO,OACF,kGAAkGA,EAAO,KAAK,QAAQ,MAAM,OAAO,EAAE,QAAQ,SAAS,MAAM,EAAE,QAAQ,MAAM,MAAM,CACvL,WAEG,2BAA2BC,CAAa;AACjD;AAEA,SAASC,GAAmBC,GAA0C;AACpE,SAAKA,IACoC;AAAA,IACvC,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,kCAAkC;AAAA,IAClC,mBAAmB;AAAA,IACnB,gCAAgC;AAAA,IAChC,iCAAiC;AAAA,IACjC,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,kBAAkB;AAAA,EAAA,EAEJA,CAAY,KAAKA,IAZP;AAa5B;AAEA,MAAMC,IAAkC;AAAA,EACtC,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AACd,GAEMC,IAAgC;AAAA,EACpC,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,SAAS;AACX,GAEMC,IAAqC;AAAA,EACzC,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,QAAQ;AACV,GAEMC,IAAiC;AAAA,EACrC,YAAY;AAAA,EACZ,OAAO;AACT,GAEMC,IAAkC;AAAA,EACtC,OAAO;AAAA,EACP,WAAW;AAAA,EACX,MAAM;AACR,GAEaC,KAA0C,CAAC,EAAE,KAAAC,QAAU;AAClE,QAAMC,IAAIC,EAAA,GACJ,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAI,GACrC,CAACC,GAAOC,CAAQ,IAAIF,EAAwB,IAAI,GAChD,CAACf,GAAQkB,CAAS,IAAIH,EAA4B,IAAI;AA6B5D,MA3BAI,EAAU,MAAM;AAwBd,KAvBgB,YAAY;AAC1B,MAAAL,EAAW,EAAI,GACfG,EAAS,IAAI,GACbC,EAAU,IAAI;AAEd,UAAI;AACF,cAAME,IAAW,MAAM,MAAMV,CAAG;AAChC,YAAI,CAACU,EAAS;AACZ,gBAAM,IAAI,MAAM,QAAQ;AAG1B,cAAMC,IAAc,MAAMD,EAAS,YAAA,GAE7BE,IADY,IAAIC,EAAUF,CAAW,EAChB,YAAA;AAC3B,QAAAH,EAAUI,CAAQ;AAAA,MACpB,SAASE,GAAK;AACZ,gBAAQ,MAAM,aAAaA,CAAG,GAC9BP,EAASN,EAAE,kBAAkB,CAAC;AAAA,MAChC,UAAA;AACE,QAAAG,EAAW,EAAK;AAAA,MAClB;AAAA,IACF,GAEA;AAAA,EACF,GAAG,CAACJ,CAAG,CAAC,GAEJG;AACF,WACE,gBAAAY,EAAC,SAAI,WAAU,sEACb,4BAAC,OAAA,EAAI,WAAU,qHAAoH,EAAA,CACrI;AAIJ,MAAIT,KAAS,CAAChB;AACZ,6BACG,OAAA,EAAI,WAAU,sEACb,UAAA,gBAAAyB,EAAC,SAAI,WAAU,yCACb,UAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,eAAe,UAAAT,KAASL,EAAE,wBAAwB,GAAE,GACnE,EAAA,CACF;AAIJ,QAAMe,IAAQpC,EAAiBU,EAAO,YAAY,IAAI,GAChD2B,IAAQrC,EAAiBU,EAAO,YAAY,IAAI,GAChD4B,IAAStC,EAAiBU,EAAO,YAAY,KAAK,GAClD6B,IAAa7B,EAAO,cAAc,IAClC8B,IAAc9B,EAAO,qBAAqBA,EAAO,eAAe,IAChE+B,IAASF,KAAcC,KAAeD,MAAeC,IACvD,GAAGD,CAAU,KAAKC,CAAW,MAC7BD,KAAcC,GACZE,IAAWpC,EAAWI,EAAO,gBAAgB,GAC7CiC,IAAerC,EAAWI,EAAO,mBAAmB,GACpDkC,IAActC,EAAWI,EAAO,YAAY,GAC5CmC,IAAevC,EAAWI,EAAO,oBAAoB,GACrDoC,IAAUpC,EAAO,WAAW,SAC5BqC,KAAerC,EAAO,eAAe,CAAA,GAAI,OAAO,CAACsC,MAAM,CAACA,EAAE,gBAAgB,GAC1EC,IAAWxC,GAAeC,GAAQW,EAAE,gBAAgB,CAAC,GACrDR,IAAeD,GAAmBF,EAAO,YAAY,GACrDwC,IAAYxC,EAAO,aAAa,IAChCyC,IAAYzC,GACZ0C,IAAa,OAAOD,EAAU,cAAe,WAAWA,EAAU,aAAa,QAC/EE,IAAkBD,MAAe,IAAI,SAASA,MAAe,IAAI,QAAQ,IACzEE,IAAc,OAAOH,EAAU,eAAgB,WAAWA,EAAU,cAAc,QAOlFI,IAAmBD,MAAgB,UAAaA,MAAgB,KANpB;AAAA,IAChD,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EAAA,EAEuFA,CAAW,KAAK;AAE5G,SACE,gBAAAnB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,YAAY,QAAA;AAAA,MAErB,UAAA,gBAAAqB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,YACL,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,WAAW;AAAA,UAAA;AAAA,UAIb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,OAAO,EAAE,cAAc,qBAAqB,SAAS,iDAAiD,YAAY,UAAA,GAErH,UAAA;AAAA,cAAA,gBAAArB,EAAC,MAAA,EAAG,OAAO,EAAE,QAAQ,cAAc,UAAU,4BAA4B,YAAY,KAAK,OAAO,WAAW,YAAY,OACrH,UAAAW,GACH;AAAA,cAGA,gBAAAU,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,UAAU,4BAA4B,OAAO,UAAA,GAClG,UAAA;AAAA,gBAAAf,KACC,gBAAAe,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACsB,KAAK,MAAM,IAAI,OAAOxC,EAAA,CAAW,EAAA,CAAE;AAAA,kBAChE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,QAAI;AAAA,oBAC7B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAuB,EAAA,CAAO;AAAA,kBAAA,EAAA,CACnC;AAAA,gBAAA,GACF;AAAA,gBAGDL,KACC,gBAAAoB,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACuB,KAAM,MAAM,IAAI,OAAOzC,EAAA,CAAW,EAAA,CAAE;AAAA,kBACjE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,MAAE;AAAA,oBAC3B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAkB,EAAA,CAAM;AAAA,kBAAA,EAAA,CAClC;AAAA,gBAAA,GACF;AAAA,gBAGDC,KACC,gBAAAmB,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACuB,KAAM,MAAM,IAAI,OAAOzC,EAAA,CAAW,EAAA,CAAE;AAAA,kBACjE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,MAAE;AAAA,oBAC3B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAmB,EAAA,CAAM;AAAA,kBAAA,EAAA,CAClC;AAAA,gBAAA,GACF;AAAA,gBAGDC,KACC,gBAAAkB,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACuB,KAAM,MAAM,IAAI,OAAOzC,EAAA,CAAW,EAAA,CAAE;AAAA,kBACjE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,OAAG;AAAA,oBAC5B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAoB,EAAA,CAAO;AAAA,kBAAA,EAAA,CACnC;AAAA,gBAAA,GACF;AAAA,gBAGDI,KACC,gBAAAc,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACwB,KAAS,MAAM,IAAI,OAAO1C,EAAA,CAAW,EAAA,CAAE;AAAA,kBACpE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,QAAI;AAAA,oBAC7B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAwB,EAAA,CAAS;AAAA,kBAAA,EAAA,CACrC;AAAA,gBAAA,GACF;AAAA,gBAGDC,KAAgBA,MAAiBD,KAChC,gBAAAc,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACyB,KAAM,MAAM,IAAI,OAAO3C,EAAA,CAAW,EAAA,CAAE;AAAA,kBACjE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,YAAQ;AAAA,oBACjC,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAyB,EAAA,CAAa;AAAA,kBAAA,EAAA,CACzC;AAAA,gBAAA,GACF;AAAA,gBAGD,CAACD,KAAY,CAACC,KAAgBC,KAC7B,gBAAAY,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACwB,KAAS,MAAM,IAAI,OAAO1C,EAAA,CAAW,EAAA,CAAE;AAAA,kBACpE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,QAAI;AAAA,oBAC7B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAA0B,EAAA,CAAY;AAAA,kBAAA,EAAA,CACxC;AAAA,gBAAA,GACF;AAAA,gBAGDS,KACC,gBAAAG,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAAC0B,KAAI,MAAM,IAAI,OAAO5C,EAAA,CAAW,EAAA,CAAE;AAAA,kBAC/D,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,cAAU;AAAA,oBACnC,gBAAAqB,EAAC,UAAK,OAAO;AAAA,sBACX,GAAGjB;AAAA,sBACH,OAAOkC,MAAe,IAAI,YAAY;AAAA,sBACtC,YAAY;AAAA,oBAAA,GAEX,UAAAC,EAAA,CACH;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA,GACF;AAAA,gBAGDE,KACC,gBAAAC,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAAC0B,KAAI,MAAM,IAAI,OAAO5C,EAAA,CAAW,EAAA,CAAE;AAAA,kBAC/D,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,eAAW;AAAA,oBACpC,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAqC,EAAA,CAAiB;AAAA,kBAAA,EAAA,CAC7C;AAAA,gBAAA,GACF;AAAA,gBAGD1C,KAAgBA,MAAiB,WAChC,gBAAA2C,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAAC2B,KAAK,MAAM,IAAI,OAAO7C,EAAA,CAAW,EAAA,CAAE;AAAA,kBAChE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,QAAI;AAAA,oBAC7B,gBAAAqB,EAAC,QAAA,EAAK,OAAOjB,GAAa,UAAAL,EAAA,CAAa;AAAA,kBAAA,EAAA,CACzC;AAAA,gBAAA,GACF;AAAA,gBAGDkC,EAAY,SAAS,KACpB,gBAAAS,EAAC,SAAI,OAAO,EAAE,GAAGzC,GAAU,WAAW,qBAAqB,WAAW,OAAO,YAAY,UACvF,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAAC4B,KAAU,MAAM,IAAI,OAAO9C,EAAA,CAAW,EAAA,CAAE;AAAA,kBACrE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,eAAW;AAAA,sCACnC,OAAA,EAAI,OAAO,EAAE,GAAGI,GAAY,SAAS,QAAQ,UAAU,QAAQ,KAAK,MAAA,GAClE,YAAY,IAAI,CAAC8B,GAAGgB,MAAM;AACzB,4BAAM5D,IAAO4C,EAAE,YAAYA,EAAE,QAAQ,QAC/BiB,IAAOjB,EAAE,eACTkB,IAAUD,IACZA,IAAO,UACL,IAAIA,IAAO,SAAS,QAAQ,CAAC,CAAC,QAC9BA,IAAO,OACL,IAAIA,IAAO,MAAM,QAAQ,CAAC,CAAC,QAC3B,GAAGA,CAAI,OACX;AACJ,6BACE,gBAAAT;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BAEC,OAAO;AAAA,4BACL,SAAS;AAAA,4BACT,YAAY;AAAA,4BACZ,KAAK;AAAA,4BACL,SAAS;AAAA,4BACT,YAAY;AAAA,4BACZ,cAAc;AAAA,4BACd,UAAU;AAAA,4BACV,OAAO;AAAA,4BACP,QAAQ;AAAA,0BAAA;AAAA,0BAGT,UAAA;AAAA,4BAAApD;AAAA,4BACA8D,uBACE,QAAA,EAAK,OAAO,EAAE,OAAO,WAAW,UAAU,OAAA,GAAU,UAAA;AAAA,8BAAA;AAAA,8BAAEA;AAAA,8BAAQ;AAAA,4BAAA,EAAA,CAAC;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAf7DF;AAAA,sBAAA;AAAA,oBAmBX,CAAC,EAAA,CACH;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA,GACF;AAAA,gBAGDd,KACC,gBAAAM,EAAC,OAAA,EAAI,OAAO,EAAE,GAAGzC,GAAU,WAAWgC,EAAY,SAAS,IAAI,SAAS,qBAAqB,WAAW,OAAO,YAAY,UACzH,UAAA;AAAA,kBAAA,gBAAAZ,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACgC,KAAK,MAAM,IAAI,OAAOlD,EAAA,CAAW,EAAA,CAAE;AAAA,kBAChE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,cAAU;AAAA,oBACnC,gBAAAqB,EAAC,QAAA,EAAK,OAAO,EAAE,GAAGjB,GAAY,UAAU,QAAQ,OAAO,WAAW,YAAY,YAAA,GAAgB,UAAAgC,EAAA,CAAU;AAAA,kBAAA,EAAA,CAC1G;AAAA,gBAAA,GACF;AAAA,gBAGDL,KAAgBA,MAAiBH,KAAYG,MAAiBF,KAC7D,gBAAAa,EAAC,OAAA,EAAI,OAAOzC,GACV,UAAA;AAAA,kBAAA,gBAAAoB,EAAC,QAAA,EAAK,OAAOnB,GAAe,UAAA,gBAAAmB,EAACyB,KAAM,MAAM,IAAI,OAAO3C,EAAA,CAAW,EAAA,CAAE;AAAA,kBACjE,gBAAAuC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,MAAM,KACnC,UAAA;AAAA,oBAAA,gBAAArB,EAAC,QAAA,EAAK,OAAOrB,GAAY,UAAA,YAAQ;AAAA,oBACjC,gBAAAqB,EAAC,QAAA,EAAK,OAAO,EAAE,GAAGjB,GAAY,UAAU,QAAQ,OAAO,aAAc,UAAA2B,EAAA,CAAa;AAAA,kBAAA,EAAA,CACpF;AAAA,gBAAA,EAAA,CACF;AAAA,cAAA,EAAA,CAEJ;AAAA,YAAA,GACF;AAAA,YAGA,gBAAAV;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,YAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,WAAW;AAAA,gBAAA;AAAA,gBAEb,yBAAyB,EAAE,QAAQc,EAAA;AAAA,cAAS;AAAA,YAAA;AAAA,UAC9C;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;"}
@@ -0,0 +1,152 @@
1
+ import { jsxs as b, jsx as i } from "react/jsx-runtime";
2
+ import { useState as M, useRef as u, useCallback as z, useEffect as L } from "react";
3
+ import { Presentation as _ } from "lucide-react";
4
+ import { init as C } from "pptx-preview";
5
+ import { u as B } from "./index-LNXbKjrI.mjs";
6
+ const I = ({ url: y, tiled: a = !0 }) => {
7
+ const s = B(), [v, w] = M(!0), [N, T] = M(null), [E, P] = M(0), n = u(null), o = u(null), x = u(null), d = u(null), m = u(null), k = u({ width: 0, height: 0 }), c = z(() => {
8
+ var t;
9
+ if (!n.current) return { width: 960, height: 540 };
10
+ const e = n.current.clientWidth, r = ((t = n.current.parentElement) == null ? void 0 : t.clientWidth) || 0, p = e > 100 ? e : r > 100 ? r : 300, l = Math.floor(p * 9 / 16);
11
+ return { width: p, height: l };
12
+ }, []), W = z(async () => {
13
+ if (!(!n.current || !d.current || E === 0))
14
+ try {
15
+ if (o.current)
16
+ try {
17
+ o.current.destroy();
18
+ } catch {
19
+ }
20
+ n.current.innerHTML = "";
21
+ const e = c(), r = C(n.current, {
22
+ width: e.width,
23
+ height: a ? e.height * E : e.height,
24
+ mode: a ? "list" : "slide"
25
+ });
26
+ o.current = r, await r.preview(d.current);
27
+ } catch {
28
+ }
29
+ }, [c, a, E]);
30
+ return L(() => {
31
+ if (!n.current) return;
32
+ let e = !0;
33
+ const r = () => {
34
+ if (e) {
35
+ e = !1, k.current = c();
36
+ return;
37
+ }
38
+ const p = c(), l = k.current, t = Math.abs(l.width - p.width), f = Math.abs(l.height - p.height);
39
+ t < 10 && f < 10 || (k.current = p, m.current && clearTimeout(m.current), m.current = window.setTimeout(() => {
40
+ o.current && d.current && W();
41
+ }, 800));
42
+ };
43
+ return x.current = new ResizeObserver(() => {
44
+ r();
45
+ }), x.current.observe(n.current), () => {
46
+ x.current && x.current.disconnect(), m.current && clearTimeout(m.current);
47
+ };
48
+ }, [c, W]), L(() => {
49
+ let e = !0, r = null;
50
+ const p = async () => {
51
+ if (n.current) {
52
+ w(!0), T(null), r = setTimeout(() => {
53
+ e && (T(s("pptx.timeout")), w(!1));
54
+ }, 3e4);
55
+ try {
56
+ const t = await fetch(y, {
57
+ mode: "cors",
58
+ credentials: "omit",
59
+ redirect: "follow"
60
+ });
61
+ if (!t.ok)
62
+ throw t.status === 404 ? new Error(s("pptx.not_found")) : t.status === 403 ? new Error("无权限访问此文件") : t.status >= 500 ? new Error("服务器错误,请稍后重试") : new Error(`文件加载失败 (${t.status})`);
63
+ const f = await t.arrayBuffer();
64
+ if (f.byteLength === 0)
65
+ throw new Error("文件为空");
66
+ if (d.current = f, !e) return;
67
+ const h = document.createElement("div");
68
+ h.style.cssText = "position:absolute;left:-9999px;top:-9999px;visibility:hidden", document.body.appendChild(h);
69
+ try {
70
+ const R = C(h, {
71
+ width: 100,
72
+ height: 100,
73
+ mode: "slide"
74
+ });
75
+ try {
76
+ await R.preview(f);
77
+ } catch {
78
+ throw new Error(s("pptx.invalid_format"));
79
+ }
80
+ const g = R.slideCount;
81
+ if (!g || g === 0)
82
+ throw new Error(s("pptx.no_pages"));
83
+ if (R.destroy(), !e) return;
84
+ P(g), n.current && (n.current.innerHTML = "");
85
+ const D = c(), j = C(n.current, {
86
+ width: D.width,
87
+ height: a ? D.height * g : D.height,
88
+ mode: a ? "list" : "slide"
89
+ });
90
+ o.current = j, await j.preview(f), r && (clearTimeout(r), r = null), e && w(!1);
91
+ } finally {
92
+ document.body.contains(h) && document.body.removeChild(h);
93
+ }
94
+ } catch (t) {
95
+ if (r && (clearTimeout(r), r = null), e) {
96
+ let f = s("pptx.parse_failed");
97
+ t instanceof Error ? f = t.message : typeof t == "string" && (f = t), T(f), w(!1);
98
+ }
99
+ }
100
+ }
101
+ }, l = setTimeout(() => {
102
+ requestAnimationFrame(() => {
103
+ requestAnimationFrame(() => {
104
+ p();
105
+ });
106
+ });
107
+ }, 150);
108
+ return () => {
109
+ if (e = !1, clearTimeout(l), r && clearTimeout(r), d.current = null, P(0), o.current)
110
+ try {
111
+ o.current.destroy();
112
+ } catch {
113
+ }
114
+ o.current = null;
115
+ };
116
+ }, [y, c, a]), /* @__PURE__ */ b("div", { className: "rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full", children: [
117
+ v && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ b("div", { className: "rfp-text-center", children: [
118
+ /* @__PURE__ */ i("div", { className: "rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }),
119
+ /* @__PURE__ */ i("p", { className: "rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium", children: s("pptx.loading") })
120
+ ] }) }),
121
+ N && !v && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ b("div", { className: "rfp-text-center rfp-max-w-sm md:rfp-max-w-md rfp-px-4", children: [
122
+ /* @__PURE__ */ i("div", { className: "rfp-w-24 rfp-h-24 md:rfp-w-32 md:rfp-h-32 rfp-mx-auto rfp-mb-4 md:rfp-mb-6 rfp-rounded-2xl md:rfp-rounded-3xl rfp-bg-gradient-to-br rfp-from-orange-500 rfp-via-red-500 rfp-to-pink-500 rfp-flex rfp-items-center rfp-justify-center rfp-shadow-2xl", children: /* @__PURE__ */ i(_, { className: "rfp-w-12 rfp-h-12 md:rfp-w-16 md:rfp-h-16 rfp-text-fg-primary" }) }),
123
+ /* @__PURE__ */ i("p", { className: "rfp-text-lg md:rfp-text-xl rfp-text-fg-primary rfp-mb-2 md:rfp-mb-3 rfp-font-medium", children: s("pptx.load_failed") }),
124
+ /* @__PURE__ */ i("p", { className: "rfp-text-xs md:rfp-text-sm rfp-text-fg-tertiary rfp-mb-4 md:rfp-mb-6", children: N }),
125
+ /* @__PURE__ */ b(
126
+ "a",
127
+ {
128
+ href: y,
129
+ download: !0,
130
+ className: "rfp-inline-flex rfp-items-center rfp-gap-2 rfp-px-4 rfp-py-2 md:rfp-px-6 md:rfp-py-3 rfp-bg-gradient-to-r rfp-from-purple-500 rfp-to-pink-500 rfp-text-fg-primary rfp-text-sm md:rfp-text-base rfp-rounded-lg md:rfp-rounded-xl hover:rfp-scale-105 rfp-transition-all rfp-shadow-lg",
131
+ children: [
132
+ /* @__PURE__ */ i("svg", { className: "rfp-w-4 rfp-h-4 md:rfp-w-5 md:rfp-h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ i("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" }) }),
133
+ s("common.download")
134
+ ]
135
+ }
136
+ ),
137
+ /* @__PURE__ */ i("p", { className: "rfp-text-xs rfp-text-fg-muted rfp-mt-3 md:rfp-mt-4", children: "提示:可以使用 Microsoft PowerPoint 或 WPS 打开" })
138
+ ] }) }),
139
+ !N && /* @__PURE__ */ i(
140
+ "div",
141
+ {
142
+ ref: n,
143
+ className: "pptx-wrapper rfp-w-full rfp-max-w-full md:rfp-max-w-6xl",
144
+ style: { opacity: v ? 0 : 1 }
145
+ }
146
+ )
147
+ ] });
148
+ };
149
+ export {
150
+ I as PptxRenderer
151
+ };
152
+ //# sourceMappingURL=index-BWbuffRN.mjs.map