@zero-library/common 2.2.6 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -6,9 +6,15 @@ var antd = require('antd');
6
6
  var classNames = require('classnames');
7
7
  var docxPreview = require('docx-preview');
8
8
  var React16 = require('react');
9
+ var AES = require('crypto-js/aes');
10
+ var encUtf8 = require('crypto-js/enc-utf8');
11
+ var MarkdownIt = require('markdown-it');
12
+ var Decimal = require('decimal.js');
13
+ var dayjs = require('dayjs');
14
+ var relativeTime = require('dayjs/plugin/relativeTime');
15
+ var axios = require('axios');
9
16
  var parse = require('html-react-parser');
10
17
  var jsonrepair = require('jsonrepair');
11
- var markdownit = require('markdown-it');
12
18
  var core$1 = require('@react-pdf-viewer/core');
13
19
  var pageNavigation = require('@react-pdf-viewer/page-navigation');
14
20
  var thumbnail = require('@react-pdf-viewer/thumbnail');
@@ -16,12 +22,6 @@ var zoom = require('@react-pdf-viewer/zoom');
16
22
  require('@react-pdf-viewer/core/lib/styles/index.css');
17
23
  var zh_CN = require('@react-pdf-viewer/locales/lib/zh_CN.json');
18
24
  require('@react-pdf-viewer/page-navigation/lib/styles/index.css');
19
- var AES = require('crypto-js/aes');
20
- var encUtf8 = require('crypto-js/enc-utf8');
21
- var Decimal = require('decimal.js');
22
- var dayjs = require('dayjs');
23
- var relativeTime = require('dayjs/plugin/relativeTime');
24
- var axios = require('axios');
25
25
  require('@react-pdf-viewer/thumbnail/lib/styles/index.css');
26
26
  require('@react-pdf-viewer/zoom/lib/styles/index.css');
27
27
  var react = require('@tiptap/react');
@@ -69,15 +69,15 @@ function _interopNamespace(e) {
69
69
  var Icon__default = /*#__PURE__*/_interopDefault(Icon);
70
70
  var classNames__default = /*#__PURE__*/_interopDefault(classNames);
71
71
  var React16__namespace = /*#__PURE__*/_interopNamespace(React16);
72
- var parse__default = /*#__PURE__*/_interopDefault(parse);
73
- var markdownit__default = /*#__PURE__*/_interopDefault(markdownit);
74
- var zh_CN__default = /*#__PURE__*/_interopDefault(zh_CN);
75
72
  var AES__default = /*#__PURE__*/_interopDefault(AES);
76
73
  var encUtf8__default = /*#__PURE__*/_interopDefault(encUtf8);
74
+ var MarkdownIt__default = /*#__PURE__*/_interopDefault(MarkdownIt);
77
75
  var Decimal__default = /*#__PURE__*/_interopDefault(Decimal);
78
76
  var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
79
77
  var relativeTime__default = /*#__PURE__*/_interopDefault(relativeTime);
80
78
  var axios__default = /*#__PURE__*/_interopDefault(axios);
79
+ var parse__default = /*#__PURE__*/_interopDefault(parse);
80
+ var zh_CN__default = /*#__PURE__*/_interopDefault(zh_CN);
81
81
  var Table__default = /*#__PURE__*/_interopDefault(Table);
82
82
  var TableCell__default = /*#__PURE__*/_interopDefault(TableCell);
83
83
  var TableHeader__default = /*#__PURE__*/_interopDefault(TableHeader);
@@ -101,319 +101,32 @@ var AudioPlayer_default = ({ fileUrl }) => {
101
101
  "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E\u3002"
102
102
  ] });
103
103
  };
104
- var DocxPreview_default = ({ fileUrl, scale = 1 }) => {
105
- const containerRef = React16.useRef(null);
106
- const [zoomRatio, setZoomRatio] = React16.useState(scale);
107
- React16.useEffect(() => {
108
- if (!fileUrl || !containerRef.current) return;
109
- containerRef.current.innerHTML = "";
110
- fetch(fileUrl).then((res) => res.arrayBuffer()).then(
111
- (arrayBuffer) => docxPreview.renderAsync(arrayBuffer, containerRef.current, null, {
112
- breakPages: true,
113
- renderHeaders: true,
114
- renderFooters: true,
115
- ignoreWidth: false,
116
- ignoreHeight: false
117
- })
118
- ).catch((err) => {
119
- console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
120
- if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
121
- });
122
- }, [fileUrl]);
123
- const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
124
- const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
125
- const resetZoom = () => {
126
- setZoomRatio(1);
127
- };
128
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames__default.default(styles_module_default.nsPreviewDocx, "height-full"), children: [
129
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
130
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
131
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.PlusCircleOutlined, {}), title: "\u653E\u5927" }),
132
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.RedoOutlined, {}), title: "\u8FD8\u539F" })
133
- ] }),
134
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames__default.default(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
135
- "div",
136
- {
137
- ref: containerRef,
138
- style: {
139
- transform: `scale(${zoomRatio})`,
140
- transformOrigin: "top center"
141
- }
142
- }
143
- ) })
144
- ] });
145
- };
146
- var FileIcon_default = ({ suffix, fontSize = 22 }) => {
147
- const styles = { fontSize, color: "var(--ant-color-primary)" };
148
- const Icon2 = React16.useMemo(() => {
149
- switch (suffix?.toUpperCase()) {
150
- case "TXT":
151
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileTextOutlined, {});
152
- case "PDF":
153
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePdfOutlined, {});
154
- case "DOC":
155
- case "DOCX":
156
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileWordOutlined, {});
157
- case "XLS":
158
- case "XLSX":
159
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileExcelOutlined, {});
160
- case "PPT":
161
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePptOutlined, {});
162
- case "MP4":
163
- case "MOV":
164
- case "MKV":
165
- case "AVI":
166
- case "FLV":
167
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.VideoCameraOutlined, {});
168
- case "MP3":
169
- case "WAV":
170
- case "M4A":
171
- case "ACC":
172
- case "WMA":
173
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.NotificationOutlined, {});
174
- case "JPG":
175
- case "JPEG":
176
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileJpgOutlined, {});
177
- case "PNG":
178
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileImageOutlined, {});
179
- case "GIF":
180
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileGifOutlined, {});
181
- case "MD":
182
- case "MARKDOWN":
183
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileMarkdownOutlined, {});
184
- case "ZIP":
185
- case "RAR":
186
- case "7Z":
187
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileZipOutlined, {});
188
- case "CATALOG":
189
- return /* @__PURE__ */ jsxRuntime.jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
190
- // 文件夹图标
191
- default:
192
- return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileUnknownOutlined, {});
193
- }
194
- }, [suffix]);
195
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles, children: Icon2 });
196
- };
197
- var VideoPlayer_default = ({ fileUrl }) => {
198
- return /* @__PURE__ */ jsxRuntime.jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
199
- /* @__PURE__ */ jsxRuntime.jsx("source", { src: fileUrl, type: "video/mp4" }),
200
- "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
201
- ] });
202
- };
203
- var baseComponentMap = {
204
- // renderMarkdown: () => import('@/components/RenderMarkdown')
205
- };
206
- var LazyComponent_default = ({ type, customComponents, ...rest }) => {
207
- const componentMap = React16.useMemo(() => {
208
- return { ...baseComponentMap, ...customComponents };
209
- }, [customComponents]);
210
- const LazyComponent = React16.useMemo(() => {
211
- const loader = componentMap[type];
212
- return loader ? React16.lazy(loader) : null;
213
- }, [type, componentMap]);
214
- if (!LazyComponent) return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
215
- "\u672A\u77E5\u7C7B\u578B\uFF1A",
216
- type
217
- ] });
218
- return /* @__PURE__ */ jsxRuntime.jsx(React16.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsxRuntime.jsx(LazyComponent, { ...rest }) });
219
- };
220
- var md = markdownit__default.default({ html: true, breaks: true });
221
- md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
222
- const token = tokens[idx];
223
- token.attrPush(["target", "_blank"]);
224
- return self.renderToken(tokens, idx, options);
225
- };
226
- function parseData(raw) {
227
- let obj = {};
228
- try {
229
- obj = JSON.parse(raw);
230
- } catch {
231
- try {
232
- obj = JSON.parse(jsonrepair.jsonrepair(raw));
233
- } catch {
234
- obj = { _raw: raw };
235
- }
236
- }
237
- return obj;
104
+
105
+ // src/utils/is.ts
106
+ var toString = Object.prototype.toString;
107
+ function is(val, type) {
108
+ return toString.call(val) === `[object ${type}]`;
238
109
  }
239
- function highlightKeywords(html, keywords) {
240
- const escaped = keywords.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
241
- const regex = new RegExp(`(${escaped.join("|")})`, "gi");
242
- return html.replace(regex, '<span class="cube-hl">$1</span>');
110
+ function isUnDef(val) {
111
+ return is(val, "Undefined");
243
112
  }
244
- function makePlaceholder(id) {
245
- return `__ALERT_DATA_${id}__`;
113
+ function isDef(val) {
114
+ return !isUnDef(val);
246
115
  }
247
- function alertMarkClean(src) {
248
- let pos = 0;
249
- let id = 0;
250
- let out = "";
251
- const placeholders = /* @__PURE__ */ new Map();
252
- while (pos < src.length) {
253
- const start = src.indexOf(":::alert", pos);
254
- if (start === -1) {
255
- out += src.slice(pos);
256
- break;
257
- }
258
- out += src.slice(pos, start);
259
- const afterStart = src.slice(start);
260
- const relAfter = afterStart.slice(":::alert".length);
261
- const matchLineEnd = relAfter.search(/\s*:::\s*/);
262
- let endIdx = -1;
263
- let isNoEnd = 1;
264
- if (matchLineEnd !== -1) {
265
- endIdx = start + ":::alert".length + matchLineEnd;
266
- isNoEnd = 0;
267
- } else {
268
- endIdx = src.length;
269
- isNoEnd = 1;
270
- }
271
- const inner = src.slice(start + ":::alert".length, endIdx).trim();
272
- const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
273
- const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
274
- const dataIdx = inner.search(/\bdata\s*=/);
275
- let rawData = "";
276
- if (dataIdx !== -1) {
277
- rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
278
- }
279
- const ph = makePlaceholder(id++);
280
- placeholders.set(ph, rawData);
281
- const typeText = type ? `type=${JSON.stringify(type)}` : "";
282
- out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
283
- const realClose = src.indexOf(":::", endIdx);
284
- pos = realClose === -1 ? endIdx : realClose + 3;
116
+ function isObject(val) {
117
+ return is(val, "Object");
118
+ }
119
+ function isEmptyObj(val) {
120
+ if (isObject(val)) {
121
+ return Object.keys(val).length === 0;
285
122
  }
286
- return { text: out, placeholders };
123
+ return false;
287
124
  }
288
- function alertInlinePlugin(md2) {
289
- md2.inline.ruler.before("emphasis", "alert_inline", function(state, silent) {
290
- const pos = state.pos;
291
- const src = state.src;
292
- if (src.slice(pos, pos + 3) !== ":::") return false;
293
- const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
294
- if (!m) return false;
295
- if (silent) return false;
296
- const raw = m[1].trim();
297
- const html = `<lazy-component ${raw}></lazy-component>`;
298
- const token = state.push("html_inline", "", 0);
299
- token.content = html;
300
- state.pos += m[0].length;
301
- return true;
302
- });
125
+ function isDate(val) {
126
+ return is(val, "Date");
303
127
  }
304
- try {
305
- md.use(alertInlinePlugin);
306
- } catch {
307
- }
308
- var filterMarkdown = (content = "") => {
309
- if (!content) return content;
310
- return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
311
- };
312
- var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
313
- const reactContent = React16.useMemo(() => {
314
- if (!content) return null;
315
- const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
316
- let rawHtml = md.render(preprocessed);
317
- rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
318
- let lazyIndex = -1;
319
- return parse__default.default(rawHtml, {
320
- replace: (domNode) => {
321
- if (domNode.name === "lazy-component") {
322
- lazyIndex++;
323
- const el = domNode;
324
- const type = el.attribs.type;
325
- const loading = !!Number(el.attribs.loading);
326
- const dataAttr = el.attribs.data || "";
327
- let data = {};
328
- if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
329
- const raw = placeholders.get(dataAttr) ?? "";
330
- data = parseData(raw);
331
- }
332
- return /* @__PURE__ */ jsxRuntime.jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
333
- }
334
- }
335
- });
336
- }, [content, searchValue]);
337
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ns-markdown", children: reactContent });
338
- };
339
- var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
340
- const [content, setContent] = React16.useState("");
341
- const [error, setError] = React16.useState("");
342
- const fetchMarkdown = async () => {
343
- const res = await fetch(fileUrl);
344
- if (res.status !== 200) {
345
- throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
346
- }
347
- const markdownText = await res.text();
348
- if (!markdownText) {
349
- throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
350
- }
351
- setContent(markdownText);
352
- };
353
- const init = async () => {
354
- setContent("");
355
- setError("");
356
- if (fileUrl) {
357
- try {
358
- await fetchMarkdown();
359
- } catch (error2) {
360
- setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
361
- }
362
- }
363
- };
364
- React16.useEffect(() => {
365
- init();
366
- }, [fileUrl]);
367
- return error ? /* @__PURE__ */ jsxRuntime.jsx(antd.Result, { status: "error", title: error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full", children: /* @__PURE__ */ jsxRuntime.jsx(RenderMarkdown_default, { content, searchValue }) });
368
- };
369
-
370
- // src/hooks/iframe/iframeRelay.ts
371
- function emit(type, data, to = "top") {
372
- const payload = { type, data, to };
373
- try {
374
- window.parent.postMessage(payload, "*");
375
- } catch (err) {
376
- console.warn("emit parent failed", err);
377
- }
378
- }
379
- function emitToChild(iframeWindow, type, data, origin = "*") {
380
- if (!iframeWindow) {
381
- console.warn("emitToChild failed: iframeWindow is null");
382
- return;
383
- }
384
- const payload = { type, data, to: "child" };
385
- try {
386
- iframeWindow.postMessage(payload, origin);
387
- } catch (err) {
388
- console.warn("emit to child failed", err);
389
- }
390
- }
391
-
392
- // src/utils/is.ts
393
- var toString = Object.prototype.toString;
394
- function is(val, type) {
395
- return toString.call(val) === `[object ${type}]`;
396
- }
397
- function isUnDef(val) {
398
- return is(val, "Undefined");
399
- }
400
- function isDef(val) {
401
- return !isUnDef(val);
402
- }
403
- function isObject(val) {
404
- return is(val, "Object");
405
- }
406
- function isEmptyObj(val) {
407
- if (isObject(val)) {
408
- return Object.keys(val).length === 0;
409
- }
410
- return false;
411
- }
412
- function isDate(val) {
413
- return is(val, "Date");
414
- }
415
- function isNull(val) {
416
- return is(val, "Null");
128
+ function isNull(val) {
129
+ return is(val, "Null");
417
130
  }
418
131
  function isNullOrUnDef(val) {
419
132
  return isUnDef(val) || isNull(val);
@@ -535,143 +248,6 @@ var isJson = (text = "") => {
535
248
  return false;
536
249
  }
537
250
  };
538
-
539
- // src/hooks/iframe/useIframeRelayBridge.ts
540
- var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
541
- const handlers = React16.useRef({});
542
- React16.useEffect(() => {
543
- const onMessage = (evt) => {
544
- const { data, source, origin } = evt;
545
- if (!data || !isObject(data) || !data.type) return;
546
- if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
547
- const { type, data: params, to = "parent" } = data;
548
- const isTop = window.parent === window;
549
- if (to === "top" && !isTop) {
550
- window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
551
- return;
552
- }
553
- const fns = handlers.current[type] || [];
554
- fns.forEach((fn) => fn(params, source, origin));
555
- };
556
- window.addEventListener("message", onMessage);
557
- return () => window.removeEventListener("message", onMessage);
558
- }, [allowedOrigins]);
559
- function on(type, handler) {
560
- handlers.current[type] = handlers.current[type] || [];
561
- handlers.current[type].push(handler);
562
- }
563
- function off(type, handler) {
564
- handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
565
- }
566
- return { on, off };
567
- };
568
- var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
569
- const timerRef = React16.useRef(null);
570
- const shouldRefreshRef = React16.useRef(shouldRefresh);
571
- const callbackRef = React16.useRef(callback);
572
- const [num, setNum] = React16.useState(0);
573
- React16.useEffect(() => {
574
- shouldRefreshRef.current = shouldRefresh;
575
- callbackRef.current = callback;
576
- }, [shouldRefresh, callback]);
577
- React16.useEffect(() => {
578
- if (timerRef.current) {
579
- clearTimeout(timerRef.current);
580
- timerRef.current = null;
581
- }
582
- if (shouldRefreshRef.current(listenValue)) {
583
- timerRef.current = setTimeout(async () => {
584
- await callbackRef.current();
585
- setNum(num + 1);
586
- }, delay);
587
- }
588
- return () => {
589
- if (timerRef.current) {
590
- clearTimeout(timerRef.current);
591
- }
592
- };
593
- }, [listenValue, delay, num]);
594
- };
595
- var useCountDown_default = (callback) => {
596
- const [count, setCount] = React16.useState(0);
597
- const [startCount, setStartCount] = React16.useState(0);
598
- const timer = React16.useRef(null);
599
- const pause = () => {
600
- clearInterval(timer.current);
601
- timer.current = null;
602
- };
603
- const start = (initialValue = 60) => {
604
- pause();
605
- setCount(initialValue);
606
- setStartCount((startCount2) => startCount2 + 1);
607
- timer.current = setInterval(() => {
608
- setCount((count2) => count2 - 1);
609
- }, 1e3);
610
- };
611
- React16.useEffect(() => {
612
- return () => {
613
- pause();
614
- };
615
- }, []);
616
- React16.useEffect(() => {
617
- if (count === 0 && startCount !== 0) {
618
- pause();
619
- callback?.();
620
- }
621
- }, [count]);
622
- return { count, start, pause, startCount };
623
- };
624
- var useCreateValtioContext_default = () => {
625
- const Context = React16.createContext(null);
626
- const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value: store, children });
627
- const useValtioStore = () => {
628
- const store = React16.useContext(Context);
629
- if (!store) throw new Error("useStore must be used within Provider");
630
- return store;
631
- };
632
- return {
633
- ValtioProvider,
634
- useValtioStore,
635
- // 导出 Context 以便外部使用
636
- Context
637
- };
638
- };
639
- var useDebounce_default = (func, wait = 400) => {
640
- const { current } = React16.useRef({ func, timeOut: null });
641
- React16.useEffect(() => {
642
- current.func = func;
643
- }, [func]);
644
- let args;
645
- function debounce(..._args) {
646
- args = _args;
647
- if (current.timeOut) {
648
- clearTimeout(current.timeOut);
649
- current.timeOut = null;
650
- }
651
- return new Promise((resolve, reject) => {
652
- current.timeOut = setTimeout(async () => {
653
- try {
654
- const result = await current.func.apply(null, args);
655
- resolve(result);
656
- } catch (e) {
657
- reject(e);
658
- }
659
- }, wait);
660
- });
661
- }
662
- function cancel() {
663
- if (!current.timeOut) return;
664
- clearTimeout(current.timeOut);
665
- current.timeOut = null;
666
- }
667
- function flush() {
668
- cancel();
669
- return current.func.apply(null, args);
670
- }
671
- debounce.flush = flush;
672
- debounce.cancel = cancel;
673
- return React16.useCallback(debounce, []);
674
- };
675
251
  var OperatorToMethodName = {
676
252
  "+": "plus",
677
253
  "-": "minus",
@@ -1232,7 +808,7 @@ function formatSize(value, options = {}) {
1232
808
  return `${toFixed(size, precision2, !trimZero)}${UNIT_LIST[index]}`;
1233
809
  }
1234
810
  var markdownToText = (() => {
1235
- const md2 = new markdownit__default.default({
811
+ const md2 = new MarkdownIt__default.default({
1236
812
  html: true,
1237
813
  linkify: true,
1238
814
  typographer: false
@@ -1244,174 +820,17 @@ var markdownToText = (() => {
1244
820
  return text;
1245
821
  };
1246
822
  })();
1247
-
1248
- // src/hooks/useDeepEffect.ts
1249
- var useDeepEffect_default = (effect, deps) => {
1250
- const prevDepsRef = React16.useRef();
1251
- const depsChanged = !prevDepsRef.current || deps.length !== prevDepsRef.current.length || deps.some((dep, i) => !deepEqual(dep, prevDepsRef.current[i]));
1252
- React16.useEffect(() => {
1253
- if (depsChanged) {
1254
- prevDepsRef.current = deps;
1255
- return effect();
1256
- }
1257
- }, [depsChanged]);
823
+ dayjs__default.default.extend(relativeTime__default.default);
824
+ var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
825
+ var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
826
+ var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
827
+ var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
828
+ var DEFAULT_UNIT = "date";
829
+ var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
830
+ return dayjs__default.default(date).startOf(unit).valueOf();
1258
831
  };
1259
- var useRefState_default = (init) => {
1260
- const [state, setState] = React16.useState(init);
1261
- const stateRef = React16.useRef(init);
1262
- const setProxy = (newVal) => {
1263
- stateRef.current = newVal;
1264
- setState(newVal);
1265
- };
1266
- const getState = () => stateRef.current;
1267
- return [state, setProxy, getState];
1268
- };
1269
- var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
1270
- const [permission, setPermission] = React16.useState("prompt");
1271
- const [isRecording, setIsRecording] = React16.useState(false);
1272
- const recognitionRef = React16.useRef(null);
1273
- React16.useEffect(() => {
1274
- const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
1275
- if (!SpeechRecognition) {
1276
- setPermission("unsupported");
1277
- return;
1278
- }
1279
- const recognition = new SpeechRecognition();
1280
- recognition.continuous = true;
1281
- recognition.interimResults = false;
1282
- recognition.lang = lang;
1283
- recognition.onresult = (event) => {
1284
- let transcript = "";
1285
- for (let i = event.resultIndex; i < event.results.length; i++) {
1286
- transcript += event.results[i][0].transcript;
1287
- }
1288
- onResult?.(transcript.trim());
1289
- };
1290
- recognition.onend = () => {
1291
- setIsRecording(false);
1292
- };
1293
- recognition.onerror = (error) => {
1294
- setIsRecording(false);
1295
- console.error("Speech recognition error:", error);
1296
- };
1297
- recognitionRef.current = recognition;
1298
- return () => {
1299
- recognition.stop?.();
1300
- recognition.onresult = null;
1301
- recognition.onend = null;
1302
- recognition.onerror = null;
1303
- };
1304
- }, [lang, onResult]);
1305
- React16.useEffect(() => {
1306
- if (!navigator.permissions) return;
1307
- navigator.permissions.query({ name: "microphone" }).then((status) => {
1308
- setPermission(status.state);
1309
- status.onchange = () => setPermission(status.state);
1310
- });
1311
- }, []);
1312
- const requestPermission = React16.useCallback(async () => {
1313
- try {
1314
- await navigator.mediaDevices.getUserMedia({ audio: true });
1315
- setPermission("granted");
1316
- } catch {
1317
- setPermission("denied");
1318
- }
1319
- }, []);
1320
- const start = React16.useCallback(() => {
1321
- if (permission === "prompt") {
1322
- requestPermission();
1323
- return;
1324
- }
1325
- if (permission !== "granted") return;
1326
- if (!isRecording) {
1327
- recognitionRef.current?.start();
1328
- setIsRecording(true);
1329
- }
1330
- }, [permission, isRecording, requestPermission]);
1331
- const stop = React16.useCallback(() => {
1332
- try {
1333
- recognitionRef.current?.stop();
1334
- } finally {
1335
- setIsRecording(false);
1336
- }
1337
- }, []);
1338
- return {
1339
- /**
1340
- * 权限状态
1341
- */
1342
- permission,
1343
- /**
1344
- * 录音状态
1345
- */
1346
- isRecording,
1347
- /** 开始语音识别 */
1348
- start,
1349
- /** 停止语音识别 */
1350
- stop
1351
- };
1352
- };
1353
- var useSyncInput_default = (storeValue, setStoreValue) => {
1354
- const [inputValue, setInputValue] = React16.useState(storeValue);
1355
- React16.useEffect(() => {
1356
- if (storeValue !== inputValue) {
1357
- setInputValue(storeValue);
1358
- }
1359
- }, [storeValue]);
1360
- const handleValueChange = (value) => {
1361
- setStoreValue(value);
1362
- setInputValue(value);
1363
- };
1364
- return {
1365
- inputValue,
1366
- setInputValue: handleValueChange
1367
- };
1368
- };
1369
- var useThrottle_default = (func, wait) => {
1370
- const { current } = React16.useRef({ func, timeOut: null });
1371
- React16.useEffect(() => {
1372
- current.func = func;
1373
- }, [func]);
1374
- let args;
1375
- function throttle(..._args) {
1376
- args = _args;
1377
- return new Promise((resolve, reject) => {
1378
- if (!current.timeOut) {
1379
- try {
1380
- const result = current.func.apply(null, args);
1381
- resolve(result);
1382
- } catch (e) {
1383
- reject(e);
1384
- }
1385
- current.timeOut = setTimeout(() => {
1386
- current.timeOut = null;
1387
- }, wait);
1388
- }
1389
- });
1390
- }
1391
- function cancel() {
1392
- if (!current.timeOut) return;
1393
- clearTimeout(current.timeOut);
1394
- current.timeOut = null;
1395
- }
1396
- function flush() {
1397
- cancel();
1398
- return current.func.apply(null, args);
1399
- }
1400
- throttle.flush = flush;
1401
- throttle.cancel = cancel;
1402
- return React16.useCallback(throttle, []);
1403
- };
1404
- dayjs__default.default.extend(relativeTime__default.default);
1405
- var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
1406
- var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
1407
- var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
1408
- var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
1409
- var DEFAULT_UNIT = "date";
1410
- var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
1411
- return dayjs__default.default(date).startOf(unit).valueOf();
1412
- };
1413
- var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
1414
- return dayjs__default.default(date).endOf(unit).valueOf();
832
+ var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
833
+ return dayjs__default.default(date).endOf(unit).valueOf();
1415
834
  };
1416
835
  var formatDate = (date, fmt = DEFAULT_DATE_TIME_FORMAT) => {
1417
836
  if (date) {
@@ -1701,67 +1120,649 @@ function createRequest(config) {
1701
1120
  return res.data;
1702
1121
  }
1703
1122
  };
1704
- }
1705
-
1706
- // src/utils/storage.ts
1707
- function getDeviceId(DEVICEID_KEY) {
1708
- let deviceId = localStorage.getItem(DEVICEID_KEY);
1709
- if (deviceId) {
1710
- return deviceId;
1123
+ }
1124
+
1125
+ // src/utils/storage.ts
1126
+ function getDeviceId(DEVICEID_KEY) {
1127
+ let deviceId = localStorage.getItem(DEVICEID_KEY);
1128
+ if (deviceId) {
1129
+ return deviceId;
1130
+ }
1131
+ deviceId = genNonDuplicateID();
1132
+ localStorage.setItem(DEVICEID_KEY, deviceId);
1133
+ return deviceId;
1134
+ }
1135
+ function createSecureManager({ key, storage = localStorage, aesKey }) {
1136
+ const set = (data) => {
1137
+ if (isNullOrUnDef(data)) return;
1138
+ storage.setItem(key, aesKey ? aesEncrypt(data, aesKey) : isString(data) ? data : JSON.stringify(data));
1139
+ };
1140
+ const get = () => {
1141
+ const cipher = storage.getItem(key);
1142
+ if (!cipher) {
1143
+ return null;
1144
+ }
1145
+ if (aesKey) {
1146
+ return aesDecrypt(cipher, aesKey);
1147
+ }
1148
+ try {
1149
+ return JSON.parse(cipher);
1150
+ } catch (e) {
1151
+ console.log("Failed to parse stored data:", e);
1152
+ return cipher;
1153
+ }
1154
+ };
1155
+ const clear = () => storage.removeItem(key);
1156
+ return {
1157
+ set,
1158
+ get,
1159
+ clear
1160
+ };
1161
+ }
1162
+ function createTokenManager({ key, storage = localStorage }) {
1163
+ const tokenManager = createSecureManager({ key, storage });
1164
+ const getFromUrl = () => {
1165
+ const searchParams = new URLSearchParams(location.search);
1166
+ return searchParams.get(key);
1167
+ };
1168
+ const get = () => {
1169
+ const urlToken = getFromUrl();
1170
+ if (urlToken) {
1171
+ tokenManager.set(urlToken);
1172
+ return urlToken;
1173
+ }
1174
+ return tokenManager.get();
1175
+ };
1176
+ return {
1177
+ set: tokenManager.set,
1178
+ get,
1179
+ clear: tokenManager.clear
1180
+ };
1181
+ }
1182
+ var DocxPreview_default = ({ fileUrl, scale = 1 }) => {
1183
+ const containerRef = React16.useRef(null);
1184
+ const [zoomRatio, setZoomRatio] = React16.useState(scale);
1185
+ React16.useEffect(() => {
1186
+ if (!fileUrl || !containerRef.current) return;
1187
+ containerRef.current.innerHTML = "";
1188
+ fetch(fileUrl).then((res) => res.arrayBuffer()).then(async (arrayBuffer) => {
1189
+ await docxPreview.renderAsync(arrayBuffer, containerRef.current, null, {
1190
+ breakPages: true,
1191
+ renderHeaders: true,
1192
+ renderFooters: true,
1193
+ ignoreWidth: false,
1194
+ ignoreHeight: false
1195
+ });
1196
+ containerRef.current.querySelectorAll("a[href]").forEach((linkEle) => {
1197
+ const href = linkEle.getAttribute("href");
1198
+ if (href && isExternal(href)) {
1199
+ linkEle.setAttribute("target", "_blank");
1200
+ linkEle.setAttribute("rel", "noopener noreferrer");
1201
+ }
1202
+ });
1203
+ }).catch((err) => {
1204
+ console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
1205
+ if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
1206
+ });
1207
+ }, [fileUrl]);
1208
+ const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
1209
+ const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
1210
+ const resetZoom = () => {
1211
+ setZoomRatio(1);
1212
+ };
1213
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classNames__default.default(styles_module_default.nsPreviewDocx, "height-full"), children: [
1214
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
1215
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
1216
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.PlusCircleOutlined, {}), title: "\u653E\u5927" }),
1217
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.RedoOutlined, {}), title: "\u8FD8\u539F" })
1218
+ ] }),
1219
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames__default.default(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
1220
+ "div",
1221
+ {
1222
+ ref: containerRef,
1223
+ style: {
1224
+ transform: `scale(${zoomRatio})`,
1225
+ transformOrigin: "top center"
1226
+ }
1227
+ }
1228
+ ) })
1229
+ ] });
1230
+ };
1231
+ var FileIcon_default = ({ suffix, fontSize = 22 }) => {
1232
+ const styles = { fontSize, color: "var(--ant-color-primary)" };
1233
+ const Icon2 = React16.useMemo(() => {
1234
+ switch (suffix?.toUpperCase()) {
1235
+ case "TXT":
1236
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileTextOutlined, {});
1237
+ case "PDF":
1238
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePdfOutlined, {});
1239
+ case "DOC":
1240
+ case "DOCX":
1241
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileWordOutlined, {});
1242
+ case "XLS":
1243
+ case "XLSX":
1244
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileExcelOutlined, {});
1245
+ case "PPT":
1246
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FilePptOutlined, {});
1247
+ case "MP4":
1248
+ case "MOV":
1249
+ case "MKV":
1250
+ case "AVI":
1251
+ case "FLV":
1252
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.VideoCameraOutlined, {});
1253
+ case "MP3":
1254
+ case "WAV":
1255
+ case "M4A":
1256
+ case "ACC":
1257
+ case "WMA":
1258
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.NotificationOutlined, {});
1259
+ case "JPG":
1260
+ case "JPEG":
1261
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileJpgOutlined, {});
1262
+ case "PNG":
1263
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileImageOutlined, {});
1264
+ case "GIF":
1265
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileGifOutlined, {});
1266
+ case "MD":
1267
+ case "MARKDOWN":
1268
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileMarkdownOutlined, {});
1269
+ case "ZIP":
1270
+ case "RAR":
1271
+ case "7Z":
1272
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileZipOutlined, {});
1273
+ case "CATALOG":
1274
+ return /* @__PURE__ */ jsxRuntime.jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
1275
+ // 文件夹图标
1276
+ default:
1277
+ return /* @__PURE__ */ jsxRuntime.jsx(Icon.FileUnknownOutlined, {});
1278
+ }
1279
+ }, [suffix]);
1280
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles, children: Icon2 });
1281
+ };
1282
+ var VideoPlayer_default = ({ fileUrl }) => {
1283
+ return /* @__PURE__ */ jsxRuntime.jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
1284
+ /* @__PURE__ */ jsxRuntime.jsx("source", { src: fileUrl, type: "video/mp4" }),
1285
+ "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
1286
+ ] });
1287
+ };
1288
+ var baseComponentMap = {
1289
+ // renderMarkdown: () => import('@/components/RenderMarkdown')
1290
+ };
1291
+ var LazyComponent_default = ({ type, customComponents, ...rest }) => {
1292
+ const componentMap = React16.useMemo(() => {
1293
+ return { ...baseComponentMap, ...customComponents };
1294
+ }, [customComponents]);
1295
+ const LazyComponent = React16.useMemo(() => {
1296
+ const loader = componentMap[type];
1297
+ return loader ? React16.lazy(loader) : null;
1298
+ }, [type, componentMap]);
1299
+ if (!LazyComponent) return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1300
+ "\u672A\u77E5\u7C7B\u578B\uFF1A",
1301
+ type
1302
+ ] });
1303
+ return /* @__PURE__ */ jsxRuntime.jsx(React16.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsxRuntime.jsx(LazyComponent, { ...rest }) });
1304
+ };
1305
+ var md = MarkdownIt__default.default({ html: true, breaks: true });
1306
+ md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
1307
+ const token = tokens[idx];
1308
+ token.attrPush(["target", "_blank"]);
1309
+ return self.renderToken(tokens, idx, options);
1310
+ };
1311
+ function parseData(raw) {
1312
+ let obj = {};
1313
+ try {
1314
+ obj = JSON.parse(raw);
1315
+ } catch {
1316
+ try {
1317
+ obj = JSON.parse(jsonrepair.jsonrepair(raw));
1318
+ } catch {
1319
+ obj = { _raw: raw };
1320
+ }
1321
+ }
1322
+ return obj;
1323
+ }
1324
+ function highlightKeywords(html, keywords) {
1325
+ const escaped = keywords.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
1326
+ const regex = new RegExp(`(${escaped.join("|")})`, "gi");
1327
+ return html.replace(regex, '<span class="cube-hl">$1</span>');
1328
+ }
1329
+ function makePlaceholder(id) {
1330
+ return `__ALERT_DATA_${id}__`;
1331
+ }
1332
+ function alertMarkClean(src) {
1333
+ let pos = 0;
1334
+ let id = 0;
1335
+ let out = "";
1336
+ const placeholders = /* @__PURE__ */ new Map();
1337
+ while (pos < src.length) {
1338
+ const start = src.indexOf(":::alert", pos);
1339
+ if (start === -1) {
1340
+ out += src.slice(pos);
1341
+ break;
1342
+ }
1343
+ out += src.slice(pos, start);
1344
+ const afterStart = src.slice(start);
1345
+ const relAfter = afterStart.slice(":::alert".length);
1346
+ const matchLineEnd = relAfter.search(/\s*:::\s*/);
1347
+ let endIdx = -1;
1348
+ let isNoEnd = 1;
1349
+ if (matchLineEnd !== -1) {
1350
+ endIdx = start + ":::alert".length + matchLineEnd;
1351
+ isNoEnd = 0;
1352
+ } else {
1353
+ endIdx = src.length;
1354
+ isNoEnd = 1;
1355
+ }
1356
+ const inner = src.slice(start + ":::alert".length, endIdx).trim();
1357
+ const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
1358
+ const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
1359
+ const dataIdx = inner.search(/\bdata\s*=/);
1360
+ let rawData = "";
1361
+ if (dataIdx !== -1) {
1362
+ rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
1363
+ }
1364
+ const ph = makePlaceholder(id++);
1365
+ placeholders.set(ph, rawData);
1366
+ const typeText = type ? `type=${JSON.stringify(type)}` : "";
1367
+ out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
1368
+ const realClose = src.indexOf(":::", endIdx);
1369
+ pos = realClose === -1 ? endIdx : realClose + 3;
1370
+ }
1371
+ return { text: out, placeholders };
1372
+ }
1373
+ function alertInlinePlugin(md2) {
1374
+ md2.inline.ruler.before("emphasis", "alert_inline", function(state, silent) {
1375
+ const pos = state.pos;
1376
+ const src = state.src;
1377
+ if (src.slice(pos, pos + 3) !== ":::") return false;
1378
+ const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
1379
+ if (!m) return false;
1380
+ if (silent) return false;
1381
+ const raw = m[1].trim();
1382
+ const html = `<lazy-component ${raw}></lazy-component>`;
1383
+ const token = state.push("html_inline", "", 0);
1384
+ token.content = html;
1385
+ state.pos += m[0].length;
1386
+ return true;
1387
+ });
1388
+ }
1389
+ try {
1390
+ md.use(alertInlinePlugin);
1391
+ } catch {
1392
+ }
1393
+ var filterMarkdown = (content = "") => {
1394
+ if (!content) return content;
1395
+ return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
1396
+ };
1397
+ var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
1398
+ const reactContent = React16.useMemo(() => {
1399
+ if (!content) return null;
1400
+ const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
1401
+ let rawHtml = md.render(preprocessed);
1402
+ rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
1403
+ let lazyIndex = -1;
1404
+ return parse__default.default(rawHtml, {
1405
+ replace: (domNode) => {
1406
+ if (domNode.name === "lazy-component") {
1407
+ lazyIndex++;
1408
+ const el = domNode;
1409
+ const type = el.attribs.type;
1410
+ const loading = !!Number(el.attribs.loading);
1411
+ const dataAttr = el.attribs.data || "";
1412
+ let data = {};
1413
+ if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
1414
+ const raw = placeholders.get(dataAttr) ?? "";
1415
+ data = parseData(raw);
1416
+ }
1417
+ return /* @__PURE__ */ jsxRuntime.jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
1418
+ }
1419
+ }
1420
+ });
1421
+ }, [content, searchValue]);
1422
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ns-markdown", children: reactContent });
1423
+ };
1424
+ var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
1425
+ const [content, setContent] = React16.useState("");
1426
+ const [error, setError] = React16.useState("");
1427
+ const fetchMarkdown = async () => {
1428
+ const res = await fetch(fileUrl);
1429
+ if (res.status !== 200) {
1430
+ throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
1431
+ }
1432
+ const markdownText = await res.text();
1433
+ if (!markdownText) {
1434
+ throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
1435
+ }
1436
+ setContent(markdownText);
1437
+ };
1438
+ const init = async () => {
1439
+ setContent("");
1440
+ setError("");
1441
+ if (fileUrl) {
1442
+ try {
1443
+ await fetchMarkdown();
1444
+ } catch (error2) {
1445
+ setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
1446
+ }
1447
+ }
1448
+ };
1449
+ React16.useEffect(() => {
1450
+ init();
1451
+ }, [fileUrl]);
1452
+ return error ? /* @__PURE__ */ jsxRuntime.jsx(antd.Result, { status: "error", title: error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full", children: /* @__PURE__ */ jsxRuntime.jsx(RenderMarkdown_default, { content, searchValue }) });
1453
+ };
1454
+
1455
+ // src/hooks/iframe/iframeRelay.ts
1456
+ function emit(type, data, to = "top") {
1457
+ const payload = { type, data, to };
1458
+ try {
1459
+ window.parent.postMessage(payload, "*");
1460
+ } catch (err) {
1461
+ console.warn("emit parent failed", err);
1462
+ }
1463
+ }
1464
+ function emitToChild(iframeWindow, type, data, origin = "*") {
1465
+ if (!iframeWindow) {
1466
+ console.warn("emitToChild failed: iframeWindow is null");
1467
+ return;
1468
+ }
1469
+ const payload = { type, data, to: "child" };
1470
+ try {
1471
+ iframeWindow.postMessage(payload, origin);
1472
+ } catch (err) {
1473
+ console.warn("emit to child failed", err);
1474
+ }
1475
+ }
1476
+ var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
1477
+ const handlers = React16.useRef({});
1478
+ React16.useEffect(() => {
1479
+ const onMessage = (evt) => {
1480
+ const { data, source, origin } = evt;
1481
+ if (!data || !isObject(data) || !data.type) return;
1482
+ if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
1483
+ const { type, data: params, to = "parent" } = data;
1484
+ const isTop = window.parent === window;
1485
+ if (to === "top" && !isTop) {
1486
+ window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
1487
+ return;
1488
+ }
1489
+ const fns = handlers.current[type] || [];
1490
+ fns.forEach((fn) => fn(params, source, origin));
1491
+ };
1492
+ window.addEventListener("message", onMessage);
1493
+ return () => window.removeEventListener("message", onMessage);
1494
+ }, [allowedOrigins]);
1495
+ function on(type, handler) {
1496
+ handlers.current[type] = handlers.current[type] || [];
1497
+ handlers.current[type].push(handler);
1498
+ }
1499
+ function off(type, handler) {
1500
+ handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
1501
+ }
1502
+ return { on, off };
1503
+ };
1504
+ var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
1505
+ const timerRef = React16.useRef(null);
1506
+ const shouldRefreshRef = React16.useRef(shouldRefresh);
1507
+ const callbackRef = React16.useRef(callback);
1508
+ const [num, setNum] = React16.useState(0);
1509
+ React16.useEffect(() => {
1510
+ shouldRefreshRef.current = shouldRefresh;
1511
+ callbackRef.current = callback;
1512
+ }, [shouldRefresh, callback]);
1513
+ React16.useEffect(() => {
1514
+ if (timerRef.current) {
1515
+ clearTimeout(timerRef.current);
1516
+ timerRef.current = null;
1517
+ }
1518
+ if (shouldRefreshRef.current(listenValue)) {
1519
+ timerRef.current = setTimeout(async () => {
1520
+ await callbackRef.current();
1521
+ setNum(num + 1);
1522
+ }, delay);
1523
+ }
1524
+ return () => {
1525
+ if (timerRef.current) {
1526
+ clearTimeout(timerRef.current);
1527
+ }
1528
+ };
1529
+ }, [listenValue, delay, num]);
1530
+ };
1531
+ var useCountDown_default = (callback) => {
1532
+ const [count, setCount] = React16.useState(0);
1533
+ const [startCount, setStartCount] = React16.useState(0);
1534
+ const timer = React16.useRef(null);
1535
+ const pause = () => {
1536
+ clearInterval(timer.current);
1537
+ timer.current = null;
1538
+ };
1539
+ const start = (initialValue = 60) => {
1540
+ pause();
1541
+ setCount(initialValue);
1542
+ setStartCount((startCount2) => startCount2 + 1);
1543
+ timer.current = setInterval(() => {
1544
+ setCount((count2) => count2 - 1);
1545
+ }, 1e3);
1546
+ };
1547
+ React16.useEffect(() => {
1548
+ return () => {
1549
+ pause();
1550
+ };
1551
+ }, []);
1552
+ React16.useEffect(() => {
1553
+ if (count === 0 && startCount !== 0) {
1554
+ pause();
1555
+ callback?.();
1556
+ }
1557
+ }, [count]);
1558
+ return { count, start, pause, startCount };
1559
+ };
1560
+ var useCreateValtioContext_default = () => {
1561
+ const Context = React16.createContext(null);
1562
+ const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value: store, children });
1563
+ const useValtioStore = () => {
1564
+ const store = React16.useContext(Context);
1565
+ if (!store) throw new Error("useStore must be used within Provider");
1566
+ return store;
1567
+ };
1568
+ return {
1569
+ ValtioProvider,
1570
+ useValtioStore,
1571
+ // 导出 Context 以便外部使用
1572
+ Context
1573
+ };
1574
+ };
1575
+ var useDebounce_default = (func, wait = 400) => {
1576
+ const { current } = React16.useRef({ func, timeOut: null });
1577
+ React16.useEffect(() => {
1578
+ current.func = func;
1579
+ }, [func]);
1580
+ let args;
1581
+ function debounce(..._args) {
1582
+ args = _args;
1583
+ if (current.timeOut) {
1584
+ clearTimeout(current.timeOut);
1585
+ current.timeOut = null;
1586
+ }
1587
+ return new Promise((resolve, reject) => {
1588
+ current.timeOut = setTimeout(async () => {
1589
+ try {
1590
+ const result = await current.func.apply(null, args);
1591
+ resolve(result);
1592
+ } catch (e) {
1593
+ reject(e);
1594
+ }
1595
+ }, wait);
1596
+ });
1711
1597
  }
1712
- deviceId = genNonDuplicateID();
1713
- localStorage.setItem(DEVICEID_KEY, deviceId);
1714
- return deviceId;
1715
- }
1716
- function createSecureManager({ key, storage = localStorage, aesKey }) {
1717
- const set = (data) => {
1718
- if (isNullOrUnDef(data)) return;
1719
- storage.setItem(key, aesKey ? aesEncrypt(data, aesKey) : isString(data) ? data : JSON.stringify(data));
1598
+ function cancel() {
1599
+ if (!current.timeOut) return;
1600
+ clearTimeout(current.timeOut);
1601
+ current.timeOut = null;
1602
+ }
1603
+ function flush() {
1604
+ cancel();
1605
+ return current.func.apply(null, args);
1606
+ }
1607
+ debounce.flush = flush;
1608
+ debounce.cancel = cancel;
1609
+ return React16.useCallback(debounce, []);
1610
+ };
1611
+ var useDeepEffect_default = (effect, deps) => {
1612
+ const prevDepsRef = React16.useRef();
1613
+ const depsChanged = !prevDepsRef.current || deps.length !== prevDepsRef.current.length || deps.some((dep, i) => !deepEqual(dep, prevDepsRef.current[i]));
1614
+ React16.useEffect(() => {
1615
+ if (depsChanged) {
1616
+ prevDepsRef.current = deps;
1617
+ return effect();
1618
+ }
1619
+ }, [depsChanged]);
1620
+ };
1621
+ var useRefState_default = (init) => {
1622
+ const [state, setState] = React16.useState(init);
1623
+ const stateRef = React16.useRef(init);
1624
+ const setProxy = (newVal) => {
1625
+ stateRef.current = newVal;
1626
+ setState(newVal);
1720
1627
  };
1721
- const get = () => {
1722
- const cipher = storage.getItem(key);
1723
- if (!cipher) {
1724
- return null;
1628
+ const getState = () => stateRef.current;
1629
+ return [state, setProxy, getState];
1630
+ };
1631
+ var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
1632
+ const [permission, setPermission] = React16.useState("prompt");
1633
+ const [isRecording, setIsRecording] = React16.useState(false);
1634
+ const recognitionRef = React16.useRef(null);
1635
+ React16.useEffect(() => {
1636
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
1637
+ if (!SpeechRecognition) {
1638
+ setPermission("unsupported");
1639
+ return;
1725
1640
  }
1726
- if (aesKey) {
1727
- return aesDecrypt(cipher, aesKey);
1641
+ const recognition = new SpeechRecognition();
1642
+ recognition.continuous = true;
1643
+ recognition.interimResults = false;
1644
+ recognition.lang = lang;
1645
+ recognition.onresult = (event) => {
1646
+ let transcript = "";
1647
+ for (let i = event.resultIndex; i < event.results.length; i++) {
1648
+ transcript += event.results[i][0].transcript;
1649
+ }
1650
+ onResult?.(transcript.trim());
1651
+ };
1652
+ recognition.onend = () => {
1653
+ setIsRecording(false);
1654
+ };
1655
+ recognition.onerror = (error) => {
1656
+ setIsRecording(false);
1657
+ console.error("Speech recognition error:", error);
1658
+ };
1659
+ recognitionRef.current = recognition;
1660
+ return () => {
1661
+ recognition.stop?.();
1662
+ recognition.onresult = null;
1663
+ recognition.onend = null;
1664
+ recognition.onerror = null;
1665
+ };
1666
+ }, [lang, onResult]);
1667
+ React16.useEffect(() => {
1668
+ if (!navigator.permissions) return;
1669
+ navigator.permissions.query({ name: "microphone" }).then((status) => {
1670
+ setPermission(status.state);
1671
+ status.onchange = () => setPermission(status.state);
1672
+ });
1673
+ }, []);
1674
+ const requestPermission = React16.useCallback(async () => {
1675
+ try {
1676
+ await navigator.mediaDevices.getUserMedia({ audio: true });
1677
+ setPermission("granted");
1678
+ } catch {
1679
+ setPermission("denied");
1680
+ }
1681
+ }, []);
1682
+ const start = React16.useCallback(() => {
1683
+ if (permission === "prompt") {
1684
+ requestPermission();
1685
+ return;
1728
1686
  }
1687
+ if (permission !== "granted") return;
1688
+ if (!isRecording) {
1689
+ recognitionRef.current?.start();
1690
+ setIsRecording(true);
1691
+ }
1692
+ }, [permission, isRecording, requestPermission]);
1693
+ const stop = React16.useCallback(() => {
1729
1694
  try {
1730
- return JSON.parse(cipher);
1731
- } catch (e) {
1732
- console.log("Failed to parse stored data:", e);
1733
- return cipher;
1695
+ recognitionRef.current?.stop();
1696
+ } finally {
1697
+ setIsRecording(false);
1734
1698
  }
1735
- };
1736
- const clear = () => storage.removeItem(key);
1699
+ }, []);
1737
1700
  return {
1738
- set,
1739
- get,
1740
- clear
1741
- };
1742
- }
1743
- function createTokenManager({ key, storage = localStorage }) {
1744
- const tokenManager = createSecureManager({ key, storage });
1745
- const getFromUrl = () => {
1746
- const searchParams = new URLSearchParams(location.search);
1747
- return searchParams.get(key);
1701
+ /**
1702
+ * 权限状态
1703
+ */
1704
+ permission,
1705
+ /**
1706
+ * 录音状态
1707
+ */
1708
+ isRecording,
1709
+ /** 开始语音识别 */
1710
+ start,
1711
+ /** 停止语音识别 */
1712
+ stop
1748
1713
  };
1749
- const get = () => {
1750
- const urlToken = getFromUrl();
1751
- if (urlToken) {
1752
- tokenManager.set(urlToken);
1753
- return urlToken;
1714
+ };
1715
+ var useSyncInput_default = (storeValue, setStoreValue) => {
1716
+ const [inputValue, setInputValue] = React16.useState(storeValue);
1717
+ React16.useEffect(() => {
1718
+ if (storeValue !== inputValue) {
1719
+ setInputValue(storeValue);
1754
1720
  }
1755
- return tokenManager.get();
1721
+ }, [storeValue]);
1722
+ const handleValueChange = (value) => {
1723
+ setStoreValue(value);
1724
+ setInputValue(value);
1756
1725
  };
1757
1726
  return {
1758
- set: tokenManager.set,
1759
- get,
1760
- clear: tokenManager.clear
1727
+ inputValue,
1728
+ setInputValue: handleValueChange
1761
1729
  };
1762
- }
1763
-
1764
- // src/hooks/webSocket/useWebSocket.ts
1730
+ };
1731
+ var useThrottle_default = (func, wait) => {
1732
+ const { current } = React16.useRef({ func, timeOut: null });
1733
+ React16.useEffect(() => {
1734
+ current.func = func;
1735
+ }, [func]);
1736
+ let args;
1737
+ function throttle(..._args) {
1738
+ args = _args;
1739
+ return new Promise((resolve, reject) => {
1740
+ if (!current.timeOut) {
1741
+ try {
1742
+ const result = current.func.apply(null, args);
1743
+ resolve(result);
1744
+ } catch (e) {
1745
+ reject(e);
1746
+ }
1747
+ current.timeOut = setTimeout(() => {
1748
+ current.timeOut = null;
1749
+ }, wait);
1750
+ }
1751
+ });
1752
+ }
1753
+ function cancel() {
1754
+ if (!current.timeOut) return;
1755
+ clearTimeout(current.timeOut);
1756
+ current.timeOut = null;
1757
+ }
1758
+ function flush() {
1759
+ cancel();
1760
+ return current.func.apply(null, args);
1761
+ }
1762
+ throttle.flush = flush;
1763
+ throttle.cancel = cancel;
1764
+ return React16.useCallback(throttle, []);
1765
+ };
1765
1766
  var useWebSocket_default = ({
1766
1767
  url,
1767
1768
  onMessage,
@@ -1921,6 +1922,20 @@ var ProtectedView = ({
1921
1922
  ] })
1922
1923
  ] }) });
1923
1924
  };
1925
+ var openLinksNewTabPlugin = () => {
1926
+ const onAnnotationLayerRender = (e) => {
1927
+ e.container.querySelectorAll(".rpv-core__annotation--link a[href]").forEach((linkEle) => {
1928
+ const href = linkEle.getAttribute("href");
1929
+ if (href && isExternal(href)) {
1930
+ linkEle.setAttribute("target", "_blank");
1931
+ linkEle.setAttribute("rel", "noopener noreferrer");
1932
+ }
1933
+ });
1934
+ };
1935
+ return {
1936
+ onAnnotationLayerRender
1937
+ };
1938
+ };
1924
1939
  var PdfPreview_default = ({ password, fileUrl, pageNo = 1, scale = 1, isHasThumbnails = true, onSetPassword, onSetPageNo }) => {
1925
1940
  const embedRef = React16.useRef(null);
1926
1941
  const [sizes, setSizes] = React16.useState([0]);
@@ -2052,10 +2067,11 @@ var PdfPreview_default = ({ password, fileUrl, pageNo = 1, scale = 1, isHasThumb
2052
2067
  plugins: [
2053
2068
  pageNavigationPluginInstance,
2054
2069
  thumbnailPluginInstance,
2055
- zoomPluginInstance
2070
+ zoomPluginInstance,
2056
2071
  // printPluginInstance,
2057
2072
  // rotatePluginInstance,
2058
2073
  // searchPluginInstance,
2074
+ openLinksNewTabPlugin()
2059
2075
  ],
2060
2076
  onPageChange,
2061
2077
  renderError,