@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.esm.js CHANGED
@@ -1,13 +1,19 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import Icon, { MinusCircleOutlined, PlusCircleOutlined, RedoOutlined, FileUnknownOutlined, FileZipOutlined, FileMarkdownOutlined, FileGifOutlined, FileImageOutlined, FileJpgOutlined, NotificationOutlined, VideoCameraOutlined, FilePptOutlined, FileExcelOutlined, FileWordOutlined, FilePdfOutlined, FileTextOutlined, AudioMutedOutlined, AudioOutlined } from '@ant-design/icons';
3
- import { Spin, Flex, Button, Result, message, notification, Modal, Splitter, Empty, Image, Drawer, Tag, Avatar, Alert, Form, Input } from 'antd';
3
+ import { Spin, message, notification, Modal, Flex, Button, Result, Splitter, Empty, Image, Drawer, Tag, Avatar, Alert, Form, Input } from 'antd';
4
4
  import classNames from 'classnames';
5
5
  import { renderAsync } from 'docx-preview';
6
6
  import * as React16 from 'react';
7
7
  import { forwardRef, useState, useMemo, useEffect, useRef, lazy, Suspense, createContext, useCallback, useContext } from 'react';
8
+ import AES from 'crypto-js/aes';
9
+ import encUtf8 from 'crypto-js/enc-utf8';
10
+ import MarkdownIt from 'markdown-it';
11
+ import Decimal from 'decimal.js';
12
+ import dayjs from 'dayjs';
13
+ import relativeTime from 'dayjs/plugin/relativeTime';
14
+ import axios from 'axios';
8
15
  import parse from 'html-react-parser';
9
16
  import { jsonrepair } from 'jsonrepair';
10
- import markdownit from 'markdown-it';
11
17
  import { Worker, Viewer, PasswordStatus } from '@react-pdf-viewer/core';
12
18
  import { pageNavigationPlugin } from '@react-pdf-viewer/page-navigation';
13
19
  import { thumbnailPlugin } from '@react-pdf-viewer/thumbnail';
@@ -15,12 +21,6 @@ import { zoomPlugin } from '@react-pdf-viewer/zoom';
15
21
  import '@react-pdf-viewer/core/lib/styles/index.css';
16
22
  import zh_CN from '@react-pdf-viewer/locales/lib/zh_CN.json';
17
23
  import '@react-pdf-viewer/page-navigation/lib/styles/index.css';
18
- import AES from 'crypto-js/aes';
19
- import encUtf8 from 'crypto-js/enc-utf8';
20
- import Decimal from 'decimal.js';
21
- import dayjs from 'dayjs';
22
- import relativeTime from 'dayjs/plugin/relativeTime';
23
- import axios from 'axios';
24
24
  import '@react-pdf-viewer/thumbnail/lib/styles/index.css';
25
25
  import '@react-pdf-viewer/zoom/lib/styles/index.css';
26
26
  import { getMarkRange, Extension, isNodeSelection, useCurrentEditor, useEditor, EditorContext, BubbleMenu, EditorContent } from '@tiptap/react';
@@ -62,319 +62,32 @@ var AudioPlayer_default = ({ fileUrl }) => {
62
62
  "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E\u3002"
63
63
  ] });
64
64
  };
65
- var DocxPreview_default = ({ fileUrl, scale = 1 }) => {
66
- const containerRef = useRef(null);
67
- const [zoomRatio, setZoomRatio] = useState(scale);
68
- useEffect(() => {
69
- if (!fileUrl || !containerRef.current) return;
70
- containerRef.current.innerHTML = "";
71
- fetch(fileUrl).then((res) => res.arrayBuffer()).then(
72
- (arrayBuffer) => renderAsync(arrayBuffer, containerRef.current, null, {
73
- breakPages: true,
74
- renderHeaders: true,
75
- renderFooters: true,
76
- ignoreWidth: false,
77
- ignoreHeight: false
78
- })
79
- ).catch((err) => {
80
- console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
81
- if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
82
- });
83
- }, [fileUrl]);
84
- const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
85
- const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
86
- const resetZoom = () => {
87
- setZoomRatio(1);
88
- };
89
- return /* @__PURE__ */ jsxs("div", { className: classNames(styles_module_default.nsPreviewDocx, "height-full"), children: [
90
- /* @__PURE__ */ jsxs(Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
91
- /* @__PURE__ */ jsx(Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
92
- /* @__PURE__ */ jsx(Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsx(PlusCircleOutlined, {}), title: "\u653E\u5927" }),
93
- /* @__PURE__ */ jsx(Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsx(RedoOutlined, {}), title: "\u8FD8\u539F" })
94
- ] }),
95
- /* @__PURE__ */ jsx("div", { className: classNames(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsx(
96
- "div",
97
- {
98
- ref: containerRef,
99
- style: {
100
- transform: `scale(${zoomRatio})`,
101
- transformOrigin: "top center"
102
- }
103
- }
104
- ) })
105
- ] });
106
- };
107
- var FileIcon_default = ({ suffix, fontSize = 22 }) => {
108
- const styles = { fontSize, color: "var(--ant-color-primary)" };
109
- const Icon2 = useMemo(() => {
110
- switch (suffix?.toUpperCase()) {
111
- case "TXT":
112
- return /* @__PURE__ */ jsx(FileTextOutlined, {});
113
- case "PDF":
114
- return /* @__PURE__ */ jsx(FilePdfOutlined, {});
115
- case "DOC":
116
- case "DOCX":
117
- return /* @__PURE__ */ jsx(FileWordOutlined, {});
118
- case "XLS":
119
- case "XLSX":
120
- return /* @__PURE__ */ jsx(FileExcelOutlined, {});
121
- case "PPT":
122
- return /* @__PURE__ */ jsx(FilePptOutlined, {});
123
- case "MP4":
124
- case "MOV":
125
- case "MKV":
126
- case "AVI":
127
- case "FLV":
128
- return /* @__PURE__ */ jsx(VideoCameraOutlined, {});
129
- case "MP3":
130
- case "WAV":
131
- case "M4A":
132
- case "ACC":
133
- case "WMA":
134
- return /* @__PURE__ */ jsx(NotificationOutlined, {});
135
- case "JPG":
136
- case "JPEG":
137
- return /* @__PURE__ */ jsx(FileJpgOutlined, {});
138
- case "PNG":
139
- return /* @__PURE__ */ jsx(FileImageOutlined, {});
140
- case "GIF":
141
- return /* @__PURE__ */ jsx(FileGifOutlined, {});
142
- case "MD":
143
- case "MARKDOWN":
144
- return /* @__PURE__ */ jsx(FileMarkdownOutlined, {});
145
- case "ZIP":
146
- case "RAR":
147
- case "7Z":
148
- return /* @__PURE__ */ jsx(FileZipOutlined, {});
149
- case "CATALOG":
150
- return /* @__PURE__ */ jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
151
- // 文件夹图标
152
- default:
153
- return /* @__PURE__ */ jsx(FileUnknownOutlined, {});
154
- }
155
- }, [suffix]);
156
- return /* @__PURE__ */ jsx("span", { style: styles, children: Icon2 });
157
- };
158
- var VideoPlayer_default = ({ fileUrl }) => {
159
- return /* @__PURE__ */ jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
160
- /* @__PURE__ */ jsx("source", { src: fileUrl, type: "video/mp4" }),
161
- "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
162
- ] });
163
- };
164
- var baseComponentMap = {
165
- // renderMarkdown: () => import('@/components/RenderMarkdown')
166
- };
167
- var LazyComponent_default = ({ type, customComponents, ...rest }) => {
168
- const componentMap = useMemo(() => {
169
- return { ...baseComponentMap, ...customComponents };
170
- }, [customComponents]);
171
- const LazyComponent = useMemo(() => {
172
- const loader = componentMap[type];
173
- return loader ? lazy(loader) : null;
174
- }, [type, componentMap]);
175
- if (!LazyComponent) return /* @__PURE__ */ jsxs("div", { children: [
176
- "\u672A\u77E5\u7C7B\u578B\uFF1A",
177
- type
178
- ] });
179
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsx(LazyComponent, { ...rest }) });
180
- };
181
- var md = markdownit({ html: true, breaks: true });
182
- md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
183
- const token = tokens[idx];
184
- token.attrPush(["target", "_blank"]);
185
- return self.renderToken(tokens, idx, options);
186
- };
187
- function parseData(raw) {
188
- let obj = {};
189
- try {
190
- obj = JSON.parse(raw);
191
- } catch {
192
- try {
193
- obj = JSON.parse(jsonrepair(raw));
194
- } catch {
195
- obj = { _raw: raw };
196
- }
197
- }
198
- return obj;
65
+
66
+ // src/utils/is.ts
67
+ var toString = Object.prototype.toString;
68
+ function is(val, type) {
69
+ return toString.call(val) === `[object ${type}]`;
199
70
  }
200
- function highlightKeywords(html, keywords) {
201
- const escaped = keywords.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
202
- const regex = new RegExp(`(${escaped.join("|")})`, "gi");
203
- return html.replace(regex, '<span class="cube-hl">$1</span>');
71
+ function isUnDef(val) {
72
+ return is(val, "Undefined");
204
73
  }
205
- function makePlaceholder(id) {
206
- return `__ALERT_DATA_${id}__`;
74
+ function isDef(val) {
75
+ return !isUnDef(val);
207
76
  }
208
- function alertMarkClean(src) {
209
- let pos = 0;
210
- let id = 0;
211
- let out = "";
212
- const placeholders = /* @__PURE__ */ new Map();
213
- while (pos < src.length) {
214
- const start = src.indexOf(":::alert", pos);
215
- if (start === -1) {
216
- out += src.slice(pos);
217
- break;
218
- }
219
- out += src.slice(pos, start);
220
- const afterStart = src.slice(start);
221
- const relAfter = afterStart.slice(":::alert".length);
222
- const matchLineEnd = relAfter.search(/\s*:::\s*/);
223
- let endIdx = -1;
224
- let isNoEnd = 1;
225
- if (matchLineEnd !== -1) {
226
- endIdx = start + ":::alert".length + matchLineEnd;
227
- isNoEnd = 0;
228
- } else {
229
- endIdx = src.length;
230
- isNoEnd = 1;
231
- }
232
- const inner = src.slice(start + ":::alert".length, endIdx).trim();
233
- const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
234
- const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
235
- const dataIdx = inner.search(/\bdata\s*=/);
236
- let rawData = "";
237
- if (dataIdx !== -1) {
238
- rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
239
- }
240
- const ph = makePlaceholder(id++);
241
- placeholders.set(ph, rawData);
242
- const typeText = type ? `type=${JSON.stringify(type)}` : "";
243
- out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
244
- const realClose = src.indexOf(":::", endIdx);
245
- pos = realClose === -1 ? endIdx : realClose + 3;
77
+ function isObject(val) {
78
+ return is(val, "Object");
79
+ }
80
+ function isEmptyObj(val) {
81
+ if (isObject(val)) {
82
+ return Object.keys(val).length === 0;
246
83
  }
247
- return { text: out, placeholders };
84
+ return false;
248
85
  }
249
- function alertInlinePlugin(md2) {
250
- md2.inline.ruler.before("emphasis", "alert_inline", function(state, silent) {
251
- const pos = state.pos;
252
- const src = state.src;
253
- if (src.slice(pos, pos + 3) !== ":::") return false;
254
- const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
255
- if (!m) return false;
256
- if (silent) return false;
257
- const raw = m[1].trim();
258
- const html = `<lazy-component ${raw}></lazy-component>`;
259
- const token = state.push("html_inline", "", 0);
260
- token.content = html;
261
- state.pos += m[0].length;
262
- return true;
263
- });
86
+ function isDate(val) {
87
+ return is(val, "Date");
264
88
  }
265
- try {
266
- md.use(alertInlinePlugin);
267
- } catch {
268
- }
269
- var filterMarkdown = (content = "") => {
270
- if (!content) return content;
271
- return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
272
- };
273
- var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
274
- const reactContent = useMemo(() => {
275
- if (!content) return null;
276
- const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
277
- let rawHtml = md.render(preprocessed);
278
- rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
279
- let lazyIndex = -1;
280
- return parse(rawHtml, {
281
- replace: (domNode) => {
282
- if (domNode.name === "lazy-component") {
283
- lazyIndex++;
284
- const el = domNode;
285
- const type = el.attribs.type;
286
- const loading = !!Number(el.attribs.loading);
287
- const dataAttr = el.attribs.data || "";
288
- let data = {};
289
- if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
290
- const raw = placeholders.get(dataAttr) ?? "";
291
- data = parseData(raw);
292
- }
293
- return /* @__PURE__ */ jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
294
- }
295
- }
296
- });
297
- }, [content, searchValue]);
298
- return /* @__PURE__ */ jsx("div", { className: "ns-markdown", children: reactContent });
299
- };
300
- var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
301
- const [content, setContent] = useState("");
302
- const [error, setError] = useState("");
303
- const fetchMarkdown = async () => {
304
- const res = await fetch(fileUrl);
305
- if (res.status !== 200) {
306
- throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
307
- }
308
- const markdownText = await res.text();
309
- if (!markdownText) {
310
- throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
311
- }
312
- setContent(markdownText);
313
- };
314
- const init = async () => {
315
- setContent("");
316
- setError("");
317
- if (fileUrl) {
318
- try {
319
- await fetchMarkdown();
320
- } catch (error2) {
321
- setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
322
- }
323
- }
324
- };
325
- useEffect(() => {
326
- init();
327
- }, [fileUrl]);
328
- return error ? /* @__PURE__ */ jsx(Result, { status: "error", title: error }) : /* @__PURE__ */ jsx("div", { className: "height-full", children: /* @__PURE__ */ jsx(RenderMarkdown_default, { content, searchValue }) });
329
- };
330
-
331
- // src/hooks/iframe/iframeRelay.ts
332
- function emit(type, data, to = "top") {
333
- const payload = { type, data, to };
334
- try {
335
- window.parent.postMessage(payload, "*");
336
- } catch (err) {
337
- console.warn("emit parent failed", err);
338
- }
339
- }
340
- function emitToChild(iframeWindow, type, data, origin = "*") {
341
- if (!iframeWindow) {
342
- console.warn("emitToChild failed: iframeWindow is null");
343
- return;
344
- }
345
- const payload = { type, data, to: "child" };
346
- try {
347
- iframeWindow.postMessage(payload, origin);
348
- } catch (err) {
349
- console.warn("emit to child failed", err);
350
- }
351
- }
352
-
353
- // src/utils/is.ts
354
- var toString = Object.prototype.toString;
355
- function is(val, type) {
356
- return toString.call(val) === `[object ${type}]`;
357
- }
358
- function isUnDef(val) {
359
- return is(val, "Undefined");
360
- }
361
- function isDef(val) {
362
- return !isUnDef(val);
363
- }
364
- function isObject(val) {
365
- return is(val, "Object");
366
- }
367
- function isEmptyObj(val) {
368
- if (isObject(val)) {
369
- return Object.keys(val).length === 0;
370
- }
371
- return false;
372
- }
373
- function isDate(val) {
374
- return is(val, "Date");
375
- }
376
- function isNull(val) {
377
- return is(val, "Null");
89
+ function isNull(val) {
90
+ return is(val, "Null");
378
91
  }
379
92
  function isNullOrUnDef(val) {
380
93
  return isUnDef(val) || isNull(val);
@@ -496,143 +209,6 @@ var isJson = (text = "") => {
496
209
  return false;
497
210
  }
498
211
  };
499
-
500
- // src/hooks/iframe/useIframeRelayBridge.ts
501
- var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
502
- const handlers = useRef({});
503
- useEffect(() => {
504
- const onMessage = (evt) => {
505
- const { data, source, origin } = evt;
506
- if (!data || !isObject(data) || !data.type) return;
507
- if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
508
- const { type, data: params, to = "parent" } = data;
509
- const isTop = window.parent === window;
510
- if (to === "top" && !isTop) {
511
- window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
512
- return;
513
- }
514
- const fns = handlers.current[type] || [];
515
- fns.forEach((fn) => fn(params, source, origin));
516
- };
517
- window.addEventListener("message", onMessage);
518
- return () => window.removeEventListener("message", onMessage);
519
- }, [allowedOrigins]);
520
- function on(type, handler) {
521
- handlers.current[type] = handlers.current[type] || [];
522
- handlers.current[type].push(handler);
523
- }
524
- function off(type, handler) {
525
- handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
526
- }
527
- return { on, off };
528
- };
529
- var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
530
- const timerRef = useRef(null);
531
- const shouldRefreshRef = useRef(shouldRefresh);
532
- const callbackRef = useRef(callback);
533
- const [num, setNum] = useState(0);
534
- useEffect(() => {
535
- shouldRefreshRef.current = shouldRefresh;
536
- callbackRef.current = callback;
537
- }, [shouldRefresh, callback]);
538
- useEffect(() => {
539
- if (timerRef.current) {
540
- clearTimeout(timerRef.current);
541
- timerRef.current = null;
542
- }
543
- if (shouldRefreshRef.current(listenValue)) {
544
- timerRef.current = setTimeout(async () => {
545
- await callbackRef.current();
546
- setNum(num + 1);
547
- }, delay);
548
- }
549
- return () => {
550
- if (timerRef.current) {
551
- clearTimeout(timerRef.current);
552
- }
553
- };
554
- }, [listenValue, delay, num]);
555
- };
556
- var useCountDown_default = (callback) => {
557
- const [count, setCount] = useState(0);
558
- const [startCount, setStartCount] = useState(0);
559
- const timer = useRef(null);
560
- const pause = () => {
561
- clearInterval(timer.current);
562
- timer.current = null;
563
- };
564
- const start = (initialValue = 60) => {
565
- pause();
566
- setCount(initialValue);
567
- setStartCount((startCount2) => startCount2 + 1);
568
- timer.current = setInterval(() => {
569
- setCount((count2) => count2 - 1);
570
- }, 1e3);
571
- };
572
- useEffect(() => {
573
- return () => {
574
- pause();
575
- };
576
- }, []);
577
- useEffect(() => {
578
- if (count === 0 && startCount !== 0) {
579
- pause();
580
- callback?.();
581
- }
582
- }, [count]);
583
- return { count, start, pause, startCount };
584
- };
585
- var useCreateValtioContext_default = () => {
586
- const Context = createContext(null);
587
- const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsx(Context.Provider, { value: store, children });
588
- const useValtioStore = () => {
589
- const store = useContext(Context);
590
- if (!store) throw new Error("useStore must be used within Provider");
591
- return store;
592
- };
593
- return {
594
- ValtioProvider,
595
- useValtioStore,
596
- // 导出 Context 以便外部使用
597
- Context
598
- };
599
- };
600
- var useDebounce_default = (func, wait = 400) => {
601
- const { current } = useRef({ func, timeOut: null });
602
- useEffect(() => {
603
- current.func = func;
604
- }, [func]);
605
- let args;
606
- function debounce(..._args) {
607
- args = _args;
608
- if (current.timeOut) {
609
- clearTimeout(current.timeOut);
610
- current.timeOut = null;
611
- }
612
- return new Promise((resolve, reject) => {
613
- current.timeOut = setTimeout(async () => {
614
- try {
615
- const result = await current.func.apply(null, args);
616
- resolve(result);
617
- } catch (e) {
618
- reject(e);
619
- }
620
- }, wait);
621
- });
622
- }
623
- function cancel() {
624
- if (!current.timeOut) return;
625
- clearTimeout(current.timeOut);
626
- current.timeOut = null;
627
- }
628
- function flush() {
629
- cancel();
630
- return current.func.apply(null, args);
631
- }
632
- debounce.flush = flush;
633
- debounce.cancel = cancel;
634
- return useCallback(debounce, []);
635
- };
636
212
  var OperatorToMethodName = {
637
213
  "+": "plus",
638
214
  "-": "minus",
@@ -1193,7 +769,7 @@ function formatSize(value, options = {}) {
1193
769
  return `${toFixed(size, precision2, !trimZero)}${UNIT_LIST[index]}`;
1194
770
  }
1195
771
  var markdownToText = (() => {
1196
- const md2 = new markdownit({
772
+ const md2 = new MarkdownIt({
1197
773
  html: true,
1198
774
  linkify: true,
1199
775
  typographer: false
@@ -1205,174 +781,17 @@ var markdownToText = (() => {
1205
781
  return text;
1206
782
  };
1207
783
  })();
1208
-
1209
- // src/hooks/useDeepEffect.ts
1210
- var useDeepEffect_default = (effect, deps) => {
1211
- const prevDepsRef = useRef();
1212
- const depsChanged = !prevDepsRef.current || deps.length !== prevDepsRef.current.length || deps.some((dep, i) => !deepEqual(dep, prevDepsRef.current[i]));
1213
- useEffect(() => {
1214
- if (depsChanged) {
1215
- prevDepsRef.current = deps;
1216
- return effect();
1217
- }
1218
- }, [depsChanged]);
784
+ dayjs.extend(relativeTime);
785
+ var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
786
+ var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
787
+ var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
788
+ var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
789
+ var DEFAULT_UNIT = "date";
790
+ var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
791
+ return dayjs(date).startOf(unit).valueOf();
1219
792
  };
1220
- var useRefState_default = (init) => {
1221
- const [state, setState] = useState(init);
1222
- const stateRef = useRef(init);
1223
- const setProxy = (newVal) => {
1224
- stateRef.current = newVal;
1225
- setState(newVal);
1226
- };
1227
- const getState = () => stateRef.current;
1228
- return [state, setProxy, getState];
1229
- };
1230
- var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
1231
- const [permission, setPermission] = useState("prompt");
1232
- const [isRecording, setIsRecording] = useState(false);
1233
- const recognitionRef = useRef(null);
1234
- useEffect(() => {
1235
- const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
1236
- if (!SpeechRecognition) {
1237
- setPermission("unsupported");
1238
- return;
1239
- }
1240
- const recognition = new SpeechRecognition();
1241
- recognition.continuous = true;
1242
- recognition.interimResults = false;
1243
- recognition.lang = lang;
1244
- recognition.onresult = (event) => {
1245
- let transcript = "";
1246
- for (let i = event.resultIndex; i < event.results.length; i++) {
1247
- transcript += event.results[i][0].transcript;
1248
- }
1249
- onResult?.(transcript.trim());
1250
- };
1251
- recognition.onend = () => {
1252
- setIsRecording(false);
1253
- };
1254
- recognition.onerror = (error) => {
1255
- setIsRecording(false);
1256
- console.error("Speech recognition error:", error);
1257
- };
1258
- recognitionRef.current = recognition;
1259
- return () => {
1260
- recognition.stop?.();
1261
- recognition.onresult = null;
1262
- recognition.onend = null;
1263
- recognition.onerror = null;
1264
- };
1265
- }, [lang, onResult]);
1266
- useEffect(() => {
1267
- if (!navigator.permissions) return;
1268
- navigator.permissions.query({ name: "microphone" }).then((status) => {
1269
- setPermission(status.state);
1270
- status.onchange = () => setPermission(status.state);
1271
- });
1272
- }, []);
1273
- const requestPermission = useCallback(async () => {
1274
- try {
1275
- await navigator.mediaDevices.getUserMedia({ audio: true });
1276
- setPermission("granted");
1277
- } catch {
1278
- setPermission("denied");
1279
- }
1280
- }, []);
1281
- const start = useCallback(() => {
1282
- if (permission === "prompt") {
1283
- requestPermission();
1284
- return;
1285
- }
1286
- if (permission !== "granted") return;
1287
- if (!isRecording) {
1288
- recognitionRef.current?.start();
1289
- setIsRecording(true);
1290
- }
1291
- }, [permission, isRecording, requestPermission]);
1292
- const stop = useCallback(() => {
1293
- try {
1294
- recognitionRef.current?.stop();
1295
- } finally {
1296
- setIsRecording(false);
1297
- }
1298
- }, []);
1299
- return {
1300
- /**
1301
- * 权限状态
1302
- */
1303
- permission,
1304
- /**
1305
- * 录音状态
1306
- */
1307
- isRecording,
1308
- /** 开始语音识别 */
1309
- start,
1310
- /** 停止语音识别 */
1311
- stop
1312
- };
1313
- };
1314
- var useSyncInput_default = (storeValue, setStoreValue) => {
1315
- const [inputValue, setInputValue] = useState(storeValue);
1316
- useEffect(() => {
1317
- if (storeValue !== inputValue) {
1318
- setInputValue(storeValue);
1319
- }
1320
- }, [storeValue]);
1321
- const handleValueChange = (value) => {
1322
- setStoreValue(value);
1323
- setInputValue(value);
1324
- };
1325
- return {
1326
- inputValue,
1327
- setInputValue: handleValueChange
1328
- };
1329
- };
1330
- var useThrottle_default = (func, wait) => {
1331
- const { current } = useRef({ func, timeOut: null });
1332
- useEffect(() => {
1333
- current.func = func;
1334
- }, [func]);
1335
- let args;
1336
- function throttle(..._args) {
1337
- args = _args;
1338
- return new Promise((resolve, reject) => {
1339
- if (!current.timeOut) {
1340
- try {
1341
- const result = current.func.apply(null, args);
1342
- resolve(result);
1343
- } catch (e) {
1344
- reject(e);
1345
- }
1346
- current.timeOut = setTimeout(() => {
1347
- current.timeOut = null;
1348
- }, wait);
1349
- }
1350
- });
1351
- }
1352
- function cancel() {
1353
- if (!current.timeOut) return;
1354
- clearTimeout(current.timeOut);
1355
- current.timeOut = null;
1356
- }
1357
- function flush() {
1358
- cancel();
1359
- return current.func.apply(null, args);
1360
- }
1361
- throttle.flush = flush;
1362
- throttle.cancel = cancel;
1363
- return useCallback(throttle, []);
1364
- };
1365
- dayjs.extend(relativeTime);
1366
- var DEFAULT_DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
1367
- var DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
1368
- var DEFAULT_YEAR_MONTH_FORMAT = "YYYY\u5E74MM\u6708";
1369
- var DEFAULT_YEAR_MONTH_DAY_FORMAT = "YYYY\u5E74MM\u6708DD\u65E5";
1370
- var DEFAULT_UNIT = "date";
1371
- var getStartOfTimestamp = (date, unit = DEFAULT_UNIT) => {
1372
- return dayjs(date).startOf(unit).valueOf();
1373
- };
1374
- var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
1375
- return dayjs(date).endOf(unit).valueOf();
793
+ var getEndOfTimestamp = (date, unit = DEFAULT_UNIT) => {
794
+ return dayjs(date).endOf(unit).valueOf();
1376
795
  };
1377
796
  var formatDate = (date, fmt = DEFAULT_DATE_TIME_FORMAT) => {
1378
797
  if (date) {
@@ -1662,67 +1081,649 @@ function createRequest(config) {
1662
1081
  return res.data;
1663
1082
  }
1664
1083
  };
1665
- }
1666
-
1667
- // src/utils/storage.ts
1668
- function getDeviceId(DEVICEID_KEY) {
1669
- let deviceId = localStorage.getItem(DEVICEID_KEY);
1670
- if (deviceId) {
1671
- return deviceId;
1084
+ }
1085
+
1086
+ // src/utils/storage.ts
1087
+ function getDeviceId(DEVICEID_KEY) {
1088
+ let deviceId = localStorage.getItem(DEVICEID_KEY);
1089
+ if (deviceId) {
1090
+ return deviceId;
1091
+ }
1092
+ deviceId = genNonDuplicateID();
1093
+ localStorage.setItem(DEVICEID_KEY, deviceId);
1094
+ return deviceId;
1095
+ }
1096
+ function createSecureManager({ key, storage = localStorage, aesKey }) {
1097
+ const set = (data) => {
1098
+ if (isNullOrUnDef(data)) return;
1099
+ storage.setItem(key, aesKey ? aesEncrypt(data, aesKey) : isString(data) ? data : JSON.stringify(data));
1100
+ };
1101
+ const get = () => {
1102
+ const cipher = storage.getItem(key);
1103
+ if (!cipher) {
1104
+ return null;
1105
+ }
1106
+ if (aesKey) {
1107
+ return aesDecrypt(cipher, aesKey);
1108
+ }
1109
+ try {
1110
+ return JSON.parse(cipher);
1111
+ } catch (e) {
1112
+ console.log("Failed to parse stored data:", e);
1113
+ return cipher;
1114
+ }
1115
+ };
1116
+ const clear = () => storage.removeItem(key);
1117
+ return {
1118
+ set,
1119
+ get,
1120
+ clear
1121
+ };
1122
+ }
1123
+ function createTokenManager({ key, storage = localStorage }) {
1124
+ const tokenManager = createSecureManager({ key, storage });
1125
+ const getFromUrl = () => {
1126
+ const searchParams = new URLSearchParams(location.search);
1127
+ return searchParams.get(key);
1128
+ };
1129
+ const get = () => {
1130
+ const urlToken = getFromUrl();
1131
+ if (urlToken) {
1132
+ tokenManager.set(urlToken);
1133
+ return urlToken;
1134
+ }
1135
+ return tokenManager.get();
1136
+ };
1137
+ return {
1138
+ set: tokenManager.set,
1139
+ get,
1140
+ clear: tokenManager.clear
1141
+ };
1142
+ }
1143
+ var DocxPreview_default = ({ fileUrl, scale = 1 }) => {
1144
+ const containerRef = useRef(null);
1145
+ const [zoomRatio, setZoomRatio] = useState(scale);
1146
+ useEffect(() => {
1147
+ if (!fileUrl || !containerRef.current) return;
1148
+ containerRef.current.innerHTML = "";
1149
+ fetch(fileUrl).then((res) => res.arrayBuffer()).then(async (arrayBuffer) => {
1150
+ await renderAsync(arrayBuffer, containerRef.current, null, {
1151
+ breakPages: true,
1152
+ renderHeaders: true,
1153
+ renderFooters: true,
1154
+ ignoreWidth: false,
1155
+ ignoreHeight: false
1156
+ });
1157
+ containerRef.current.querySelectorAll("a[href]").forEach((linkEle) => {
1158
+ const href = linkEle.getAttribute("href");
1159
+ if (href && isExternal(href)) {
1160
+ linkEle.setAttribute("target", "_blank");
1161
+ linkEle.setAttribute("rel", "noopener noreferrer");
1162
+ }
1163
+ });
1164
+ }).catch((err) => {
1165
+ console.error("docx-preview \u6E32\u67D3\u5931\u8D25:", err);
1166
+ if (containerRef.current) containerRef.current.innerHTML = '<p class="text-center">\u6587\u6863\u52A0\u8F7D\u5931\u8D25</p>';
1167
+ });
1168
+ }, [fileUrl]);
1169
+ const zoomIn = () => setZoomRatio((z) => Math.min(z + 0.1, 3));
1170
+ const zoomOut = () => setZoomRatio((z) => Math.max(z - 0.1, 0.3));
1171
+ const resetZoom = () => {
1172
+ setZoomRatio(1);
1173
+ };
1174
+ return /* @__PURE__ */ jsxs("div", { className: classNames(styles_module_default.nsPreviewDocx, "height-full"), children: [
1175
+ /* @__PURE__ */ jsxs(Flex, { gap: 6, align: "center", className: styles_module_default.docxToolbar, children: [
1176
+ /* @__PURE__ */ jsx(Button, { onClick: zoomOut, icon: /* @__PURE__ */ jsx(MinusCircleOutlined, {}), title: "\u7F29\u5C0F" }),
1177
+ /* @__PURE__ */ jsx(Button, { onClick: zoomIn, icon: /* @__PURE__ */ jsx(PlusCircleOutlined, {}), title: "\u653E\u5927" }),
1178
+ /* @__PURE__ */ jsx(Button, { onClick: resetZoom, icon: /* @__PURE__ */ jsx(RedoOutlined, {}), title: "\u8FD8\u539F" })
1179
+ ] }),
1180
+ /* @__PURE__ */ jsx("div", { className: classNames(styles_module_default.docxContent, "height-full", "scroll-fade-in"), children: /* @__PURE__ */ jsx(
1181
+ "div",
1182
+ {
1183
+ ref: containerRef,
1184
+ style: {
1185
+ transform: `scale(${zoomRatio})`,
1186
+ transformOrigin: "top center"
1187
+ }
1188
+ }
1189
+ ) })
1190
+ ] });
1191
+ };
1192
+ var FileIcon_default = ({ suffix, fontSize = 22 }) => {
1193
+ const styles = { fontSize, color: "var(--ant-color-primary)" };
1194
+ const Icon2 = useMemo(() => {
1195
+ switch (suffix?.toUpperCase()) {
1196
+ case "TXT":
1197
+ return /* @__PURE__ */ jsx(FileTextOutlined, {});
1198
+ case "PDF":
1199
+ return /* @__PURE__ */ jsx(FilePdfOutlined, {});
1200
+ case "DOC":
1201
+ case "DOCX":
1202
+ return /* @__PURE__ */ jsx(FileWordOutlined, {});
1203
+ case "XLS":
1204
+ case "XLSX":
1205
+ return /* @__PURE__ */ jsx(FileExcelOutlined, {});
1206
+ case "PPT":
1207
+ return /* @__PURE__ */ jsx(FilePptOutlined, {});
1208
+ case "MP4":
1209
+ case "MOV":
1210
+ case "MKV":
1211
+ case "AVI":
1212
+ case "FLV":
1213
+ return /* @__PURE__ */ jsx(VideoCameraOutlined, {});
1214
+ case "MP3":
1215
+ case "WAV":
1216
+ case "M4A":
1217
+ case "ACC":
1218
+ case "WMA":
1219
+ return /* @__PURE__ */ jsx(NotificationOutlined, {});
1220
+ case "JPG":
1221
+ case "JPEG":
1222
+ return /* @__PURE__ */ jsx(FileJpgOutlined, {});
1223
+ case "PNG":
1224
+ return /* @__PURE__ */ jsx(FileImageOutlined, {});
1225
+ case "GIF":
1226
+ return /* @__PURE__ */ jsx(FileGifOutlined, {});
1227
+ case "MD":
1228
+ case "MARKDOWN":
1229
+ return /* @__PURE__ */ jsx(FileMarkdownOutlined, {});
1230
+ case "ZIP":
1231
+ case "RAR":
1232
+ case "7Z":
1233
+ return /* @__PURE__ */ jsx(FileZipOutlined, {});
1234
+ case "CATALOG":
1235
+ return /* @__PURE__ */ jsx("i", { style: styles, className: "iconfont icon-wenjianjia" });
1236
+ // 文件夹图标
1237
+ default:
1238
+ return /* @__PURE__ */ jsx(FileUnknownOutlined, {});
1239
+ }
1240
+ }, [suffix]);
1241
+ return /* @__PURE__ */ jsx("span", { style: styles, children: Icon2 });
1242
+ };
1243
+ var VideoPlayer_default = ({ fileUrl }) => {
1244
+ return /* @__PURE__ */ jsxs("video", { controls: true, className: styles_module_default.nsPreviewVideo, children: [
1245
+ /* @__PURE__ */ jsx("source", { src: fileUrl, type: "video/mp4" }),
1246
+ "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 video \u6807\u7B7E\u3002"
1247
+ ] });
1248
+ };
1249
+ var baseComponentMap = {
1250
+ // renderMarkdown: () => import('@/components/RenderMarkdown')
1251
+ };
1252
+ var LazyComponent_default = ({ type, customComponents, ...rest }) => {
1253
+ const componentMap = useMemo(() => {
1254
+ return { ...baseComponentMap, ...customComponents };
1255
+ }, [customComponents]);
1256
+ const LazyComponent = useMemo(() => {
1257
+ const loader = componentMap[type];
1258
+ return loader ? lazy(loader) : null;
1259
+ }, [type, componentMap]);
1260
+ if (!LazyComponent) return /* @__PURE__ */ jsxs("div", { children: [
1261
+ "\u672A\u77E5\u7C7B\u578B\uFF1A",
1262
+ type
1263
+ ] });
1264
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { children: "\u52A0\u8F7D\u4E2D..." }), children: /* @__PURE__ */ jsx(LazyComponent, { ...rest }) });
1265
+ };
1266
+ var md = MarkdownIt({ html: true, breaks: true });
1267
+ md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
1268
+ const token = tokens[idx];
1269
+ token.attrPush(["target", "_blank"]);
1270
+ return self.renderToken(tokens, idx, options);
1271
+ };
1272
+ function parseData(raw) {
1273
+ let obj = {};
1274
+ try {
1275
+ obj = JSON.parse(raw);
1276
+ } catch {
1277
+ try {
1278
+ obj = JSON.parse(jsonrepair(raw));
1279
+ } catch {
1280
+ obj = { _raw: raw };
1281
+ }
1282
+ }
1283
+ return obj;
1284
+ }
1285
+ function highlightKeywords(html, keywords) {
1286
+ const escaped = keywords.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
1287
+ const regex = new RegExp(`(${escaped.join("|")})`, "gi");
1288
+ return html.replace(regex, '<span class="cube-hl">$1</span>');
1289
+ }
1290
+ function makePlaceholder(id) {
1291
+ return `__ALERT_DATA_${id}__`;
1292
+ }
1293
+ function alertMarkClean(src) {
1294
+ let pos = 0;
1295
+ let id = 0;
1296
+ let out = "";
1297
+ const placeholders = /* @__PURE__ */ new Map();
1298
+ while (pos < src.length) {
1299
+ const start = src.indexOf(":::alert", pos);
1300
+ if (start === -1) {
1301
+ out += src.slice(pos);
1302
+ break;
1303
+ }
1304
+ out += src.slice(pos, start);
1305
+ const afterStart = src.slice(start);
1306
+ const relAfter = afterStart.slice(":::alert".length);
1307
+ const matchLineEnd = relAfter.search(/\s*:::\s*/);
1308
+ let endIdx = -1;
1309
+ let isNoEnd = 1;
1310
+ if (matchLineEnd !== -1) {
1311
+ endIdx = start + ":::alert".length + matchLineEnd;
1312
+ isNoEnd = 0;
1313
+ } else {
1314
+ endIdx = src.length;
1315
+ isNoEnd = 1;
1316
+ }
1317
+ const inner = src.slice(start + ":::alert".length, endIdx).trim();
1318
+ const typeMatch = inner.match(/type\s*=\s*(?:(['"])(.*?)\1|(\S+))/);
1319
+ const type = typeMatch ? typeMatch[2] ?? typeMatch[3] : void 0;
1320
+ const dataIdx = inner.search(/\bdata\s*=/);
1321
+ let rawData = "";
1322
+ if (dataIdx !== -1) {
1323
+ rawData = inner.slice(dataIdx + inner.slice(dataIdx).match(/\bdata\s*=/)[0].length).trim();
1324
+ }
1325
+ const ph = makePlaceholder(id++);
1326
+ placeholders.set(ph, rawData);
1327
+ const typeText = type ? `type=${JSON.stringify(type)}` : "";
1328
+ out += `:::alert ${typeText} data="${ph}" loading="${isNoEnd}" :::`;
1329
+ const realClose = src.indexOf(":::", endIdx);
1330
+ pos = realClose === -1 ? endIdx : realClose + 3;
1331
+ }
1332
+ return { text: out, placeholders };
1333
+ }
1334
+ function alertInlinePlugin(md2) {
1335
+ md2.inline.ruler.before("emphasis", "alert_inline", function(state, silent) {
1336
+ const pos = state.pos;
1337
+ const src = state.src;
1338
+ if (src.slice(pos, pos + 3) !== ":::") return false;
1339
+ const m = src.slice(pos).match(/^:::alert\b([^\n\r]*?):::/);
1340
+ if (!m) return false;
1341
+ if (silent) return false;
1342
+ const raw = m[1].trim();
1343
+ const html = `<lazy-component ${raw}></lazy-component>`;
1344
+ const token = state.push("html_inline", "", 0);
1345
+ token.content = html;
1346
+ state.pos += m[0].length;
1347
+ return true;
1348
+ });
1349
+ }
1350
+ try {
1351
+ md.use(alertInlinePlugin);
1352
+ } catch {
1353
+ }
1354
+ var filterMarkdown = (content = "") => {
1355
+ if (!content) return content;
1356
+ return content.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
1357
+ };
1358
+ var RenderMarkdown_default = ({ content = "", searchValue, customComponents, ...rest }) => {
1359
+ const reactContent = useMemo(() => {
1360
+ if (!content) return null;
1361
+ const { text: preprocessed, placeholders } = alertMarkClean(filterMarkdown(content));
1362
+ let rawHtml = md.render(preprocessed);
1363
+ rawHtml = searchValue ? highlightKeywords(rawHtml, [searchValue]) : rawHtml;
1364
+ let lazyIndex = -1;
1365
+ return parse(rawHtml, {
1366
+ replace: (domNode) => {
1367
+ if (domNode.name === "lazy-component") {
1368
+ lazyIndex++;
1369
+ const el = domNode;
1370
+ const type = el.attribs.type;
1371
+ const loading = !!Number(el.attribs.loading);
1372
+ const dataAttr = el.attribs.data || "";
1373
+ let data = {};
1374
+ if (/^__ALERT_DATA_\d+__$/.test(dataAttr)) {
1375
+ const raw = placeholders.get(dataAttr) ?? "";
1376
+ data = parseData(raw);
1377
+ }
1378
+ return /* @__PURE__ */ jsx(LazyComponent_default, { customComponents, type, data, loading, ...rest }, `${type}${lazyIndex}`);
1379
+ }
1380
+ }
1381
+ });
1382
+ }, [content, searchValue]);
1383
+ return /* @__PURE__ */ jsx("div", { className: "ns-markdown", children: reactContent });
1384
+ };
1385
+ var MarkdownPreview_default = ({ fileUrl, searchValue }) => {
1386
+ const [content, setContent] = useState("");
1387
+ const [error, setError] = useState("");
1388
+ const fetchMarkdown = async () => {
1389
+ const res = await fetch(fileUrl);
1390
+ if (res.status !== 200) {
1391
+ throw new Error(`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${res.status}`);
1392
+ }
1393
+ const markdownText = await res.text();
1394
+ if (!markdownText) {
1395
+ throw new Error("\u8FD4\u56DE\u5185\u5BB9\u4E3A\u7A7A");
1396
+ }
1397
+ setContent(markdownText);
1398
+ };
1399
+ const init = async () => {
1400
+ setContent("");
1401
+ setError("");
1402
+ if (fileUrl) {
1403
+ try {
1404
+ await fetchMarkdown();
1405
+ } catch (error2) {
1406
+ setError("\u52A0\u8F7D\u6216\u89E3\u6790 Markdown \u5931\u8D25");
1407
+ }
1408
+ }
1409
+ };
1410
+ useEffect(() => {
1411
+ init();
1412
+ }, [fileUrl]);
1413
+ return error ? /* @__PURE__ */ jsx(Result, { status: "error", title: error }) : /* @__PURE__ */ jsx("div", { className: "height-full", children: /* @__PURE__ */ jsx(RenderMarkdown_default, { content, searchValue }) });
1414
+ };
1415
+
1416
+ // src/hooks/iframe/iframeRelay.ts
1417
+ function emit(type, data, to = "top") {
1418
+ const payload = { type, data, to };
1419
+ try {
1420
+ window.parent.postMessage(payload, "*");
1421
+ } catch (err) {
1422
+ console.warn("emit parent failed", err);
1423
+ }
1424
+ }
1425
+ function emitToChild(iframeWindow, type, data, origin = "*") {
1426
+ if (!iframeWindow) {
1427
+ console.warn("emitToChild failed: iframeWindow is null");
1428
+ return;
1429
+ }
1430
+ const payload = { type, data, to: "child" };
1431
+ try {
1432
+ iframeWindow.postMessage(payload, origin);
1433
+ } catch (err) {
1434
+ console.warn("emit to child failed", err);
1435
+ }
1436
+ }
1437
+ var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
1438
+ const handlers = useRef({});
1439
+ useEffect(() => {
1440
+ const onMessage = (evt) => {
1441
+ const { data, source, origin } = evt;
1442
+ if (!data || !isObject(data) || !data.type) return;
1443
+ if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
1444
+ const { type, data: params, to = "parent" } = data;
1445
+ const isTop = window.parent === window;
1446
+ if (to === "top" && !isTop) {
1447
+ window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
1448
+ return;
1449
+ }
1450
+ const fns = handlers.current[type] || [];
1451
+ fns.forEach((fn) => fn(params, source, origin));
1452
+ };
1453
+ window.addEventListener("message", onMessage);
1454
+ return () => window.removeEventListener("message", onMessage);
1455
+ }, [allowedOrigins]);
1456
+ function on(type, handler) {
1457
+ handlers.current[type] = handlers.current[type] || [];
1458
+ handlers.current[type].push(handler);
1459
+ }
1460
+ function off(type, handler) {
1461
+ handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
1462
+ }
1463
+ return { on, off };
1464
+ };
1465
+ var useAutoRefresh_default = (listenValue, shouldRefresh, callback, delay = 1e4) => {
1466
+ const timerRef = useRef(null);
1467
+ const shouldRefreshRef = useRef(shouldRefresh);
1468
+ const callbackRef = useRef(callback);
1469
+ const [num, setNum] = useState(0);
1470
+ useEffect(() => {
1471
+ shouldRefreshRef.current = shouldRefresh;
1472
+ callbackRef.current = callback;
1473
+ }, [shouldRefresh, callback]);
1474
+ useEffect(() => {
1475
+ if (timerRef.current) {
1476
+ clearTimeout(timerRef.current);
1477
+ timerRef.current = null;
1478
+ }
1479
+ if (shouldRefreshRef.current(listenValue)) {
1480
+ timerRef.current = setTimeout(async () => {
1481
+ await callbackRef.current();
1482
+ setNum(num + 1);
1483
+ }, delay);
1484
+ }
1485
+ return () => {
1486
+ if (timerRef.current) {
1487
+ clearTimeout(timerRef.current);
1488
+ }
1489
+ };
1490
+ }, [listenValue, delay, num]);
1491
+ };
1492
+ var useCountDown_default = (callback) => {
1493
+ const [count, setCount] = useState(0);
1494
+ const [startCount, setStartCount] = useState(0);
1495
+ const timer = useRef(null);
1496
+ const pause = () => {
1497
+ clearInterval(timer.current);
1498
+ timer.current = null;
1499
+ };
1500
+ const start = (initialValue = 60) => {
1501
+ pause();
1502
+ setCount(initialValue);
1503
+ setStartCount((startCount2) => startCount2 + 1);
1504
+ timer.current = setInterval(() => {
1505
+ setCount((count2) => count2 - 1);
1506
+ }, 1e3);
1507
+ };
1508
+ useEffect(() => {
1509
+ return () => {
1510
+ pause();
1511
+ };
1512
+ }, []);
1513
+ useEffect(() => {
1514
+ if (count === 0 && startCount !== 0) {
1515
+ pause();
1516
+ callback?.();
1517
+ }
1518
+ }, [count]);
1519
+ return { count, start, pause, startCount };
1520
+ };
1521
+ var useCreateValtioContext_default = () => {
1522
+ const Context = createContext(null);
1523
+ const ValtioProvider = ({ store, children }) => /* @__PURE__ */ jsx(Context.Provider, { value: store, children });
1524
+ const useValtioStore = () => {
1525
+ const store = useContext(Context);
1526
+ if (!store) throw new Error("useStore must be used within Provider");
1527
+ return store;
1528
+ };
1529
+ return {
1530
+ ValtioProvider,
1531
+ useValtioStore,
1532
+ // 导出 Context 以便外部使用
1533
+ Context
1534
+ };
1535
+ };
1536
+ var useDebounce_default = (func, wait = 400) => {
1537
+ const { current } = useRef({ func, timeOut: null });
1538
+ useEffect(() => {
1539
+ current.func = func;
1540
+ }, [func]);
1541
+ let args;
1542
+ function debounce(..._args) {
1543
+ args = _args;
1544
+ if (current.timeOut) {
1545
+ clearTimeout(current.timeOut);
1546
+ current.timeOut = null;
1547
+ }
1548
+ return new Promise((resolve, reject) => {
1549
+ current.timeOut = setTimeout(async () => {
1550
+ try {
1551
+ const result = await current.func.apply(null, args);
1552
+ resolve(result);
1553
+ } catch (e) {
1554
+ reject(e);
1555
+ }
1556
+ }, wait);
1557
+ });
1672
1558
  }
1673
- deviceId = genNonDuplicateID();
1674
- localStorage.setItem(DEVICEID_KEY, deviceId);
1675
- return deviceId;
1676
- }
1677
- function createSecureManager({ key, storage = localStorage, aesKey }) {
1678
- const set = (data) => {
1679
- if (isNullOrUnDef(data)) return;
1680
- storage.setItem(key, aesKey ? aesEncrypt(data, aesKey) : isString(data) ? data : JSON.stringify(data));
1559
+ function cancel() {
1560
+ if (!current.timeOut) return;
1561
+ clearTimeout(current.timeOut);
1562
+ current.timeOut = null;
1563
+ }
1564
+ function flush() {
1565
+ cancel();
1566
+ return current.func.apply(null, args);
1567
+ }
1568
+ debounce.flush = flush;
1569
+ debounce.cancel = cancel;
1570
+ return useCallback(debounce, []);
1571
+ };
1572
+ var useDeepEffect_default = (effect, deps) => {
1573
+ const prevDepsRef = useRef();
1574
+ const depsChanged = !prevDepsRef.current || deps.length !== prevDepsRef.current.length || deps.some((dep, i) => !deepEqual(dep, prevDepsRef.current[i]));
1575
+ useEffect(() => {
1576
+ if (depsChanged) {
1577
+ prevDepsRef.current = deps;
1578
+ return effect();
1579
+ }
1580
+ }, [depsChanged]);
1581
+ };
1582
+ var useRefState_default = (init) => {
1583
+ const [state, setState] = useState(init);
1584
+ const stateRef = useRef(init);
1585
+ const setProxy = (newVal) => {
1586
+ stateRef.current = newVal;
1587
+ setState(newVal);
1681
1588
  };
1682
- const get = () => {
1683
- const cipher = storage.getItem(key);
1684
- if (!cipher) {
1685
- return null;
1589
+ const getState = () => stateRef.current;
1590
+ return [state, setProxy, getState];
1591
+ };
1592
+ var useSpeech_default = ({ onResult, lang = "zh-CN" }) => {
1593
+ const [permission, setPermission] = useState("prompt");
1594
+ const [isRecording, setIsRecording] = useState(false);
1595
+ const recognitionRef = useRef(null);
1596
+ useEffect(() => {
1597
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
1598
+ if (!SpeechRecognition) {
1599
+ setPermission("unsupported");
1600
+ return;
1686
1601
  }
1687
- if (aesKey) {
1688
- return aesDecrypt(cipher, aesKey);
1602
+ const recognition = new SpeechRecognition();
1603
+ recognition.continuous = true;
1604
+ recognition.interimResults = false;
1605
+ recognition.lang = lang;
1606
+ recognition.onresult = (event) => {
1607
+ let transcript = "";
1608
+ for (let i = event.resultIndex; i < event.results.length; i++) {
1609
+ transcript += event.results[i][0].transcript;
1610
+ }
1611
+ onResult?.(transcript.trim());
1612
+ };
1613
+ recognition.onend = () => {
1614
+ setIsRecording(false);
1615
+ };
1616
+ recognition.onerror = (error) => {
1617
+ setIsRecording(false);
1618
+ console.error("Speech recognition error:", error);
1619
+ };
1620
+ recognitionRef.current = recognition;
1621
+ return () => {
1622
+ recognition.stop?.();
1623
+ recognition.onresult = null;
1624
+ recognition.onend = null;
1625
+ recognition.onerror = null;
1626
+ };
1627
+ }, [lang, onResult]);
1628
+ useEffect(() => {
1629
+ if (!navigator.permissions) return;
1630
+ navigator.permissions.query({ name: "microphone" }).then((status) => {
1631
+ setPermission(status.state);
1632
+ status.onchange = () => setPermission(status.state);
1633
+ });
1634
+ }, []);
1635
+ const requestPermission = useCallback(async () => {
1636
+ try {
1637
+ await navigator.mediaDevices.getUserMedia({ audio: true });
1638
+ setPermission("granted");
1639
+ } catch {
1640
+ setPermission("denied");
1641
+ }
1642
+ }, []);
1643
+ const start = useCallback(() => {
1644
+ if (permission === "prompt") {
1645
+ requestPermission();
1646
+ return;
1689
1647
  }
1648
+ if (permission !== "granted") return;
1649
+ if (!isRecording) {
1650
+ recognitionRef.current?.start();
1651
+ setIsRecording(true);
1652
+ }
1653
+ }, [permission, isRecording, requestPermission]);
1654
+ const stop = useCallback(() => {
1690
1655
  try {
1691
- return JSON.parse(cipher);
1692
- } catch (e) {
1693
- console.log("Failed to parse stored data:", e);
1694
- return cipher;
1656
+ recognitionRef.current?.stop();
1657
+ } finally {
1658
+ setIsRecording(false);
1695
1659
  }
1696
- };
1697
- const clear = () => storage.removeItem(key);
1660
+ }, []);
1698
1661
  return {
1699
- set,
1700
- get,
1701
- clear
1702
- };
1703
- }
1704
- function createTokenManager({ key, storage = localStorage }) {
1705
- const tokenManager = createSecureManager({ key, storage });
1706
- const getFromUrl = () => {
1707
- const searchParams = new URLSearchParams(location.search);
1708
- return searchParams.get(key);
1662
+ /**
1663
+ * 权限状态
1664
+ */
1665
+ permission,
1666
+ /**
1667
+ * 录音状态
1668
+ */
1669
+ isRecording,
1670
+ /** 开始语音识别 */
1671
+ start,
1672
+ /** 停止语音识别 */
1673
+ stop
1709
1674
  };
1710
- const get = () => {
1711
- const urlToken = getFromUrl();
1712
- if (urlToken) {
1713
- tokenManager.set(urlToken);
1714
- return urlToken;
1675
+ };
1676
+ var useSyncInput_default = (storeValue, setStoreValue) => {
1677
+ const [inputValue, setInputValue] = useState(storeValue);
1678
+ useEffect(() => {
1679
+ if (storeValue !== inputValue) {
1680
+ setInputValue(storeValue);
1715
1681
  }
1716
- return tokenManager.get();
1682
+ }, [storeValue]);
1683
+ const handleValueChange = (value) => {
1684
+ setStoreValue(value);
1685
+ setInputValue(value);
1717
1686
  };
1718
1687
  return {
1719
- set: tokenManager.set,
1720
- get,
1721
- clear: tokenManager.clear
1688
+ inputValue,
1689
+ setInputValue: handleValueChange
1722
1690
  };
1723
- }
1724
-
1725
- // src/hooks/webSocket/useWebSocket.ts
1691
+ };
1692
+ var useThrottle_default = (func, wait) => {
1693
+ const { current } = useRef({ func, timeOut: null });
1694
+ useEffect(() => {
1695
+ current.func = func;
1696
+ }, [func]);
1697
+ let args;
1698
+ function throttle(..._args) {
1699
+ args = _args;
1700
+ return new Promise((resolve, reject) => {
1701
+ if (!current.timeOut) {
1702
+ try {
1703
+ const result = current.func.apply(null, args);
1704
+ resolve(result);
1705
+ } catch (e) {
1706
+ reject(e);
1707
+ }
1708
+ current.timeOut = setTimeout(() => {
1709
+ current.timeOut = null;
1710
+ }, wait);
1711
+ }
1712
+ });
1713
+ }
1714
+ function cancel() {
1715
+ if (!current.timeOut) return;
1716
+ clearTimeout(current.timeOut);
1717
+ current.timeOut = null;
1718
+ }
1719
+ function flush() {
1720
+ cancel();
1721
+ return current.func.apply(null, args);
1722
+ }
1723
+ throttle.flush = flush;
1724
+ throttle.cancel = cancel;
1725
+ return useCallback(throttle, []);
1726
+ };
1726
1727
  var useWebSocket_default = ({
1727
1728
  url,
1728
1729
  onMessage,
@@ -1882,6 +1883,20 @@ var ProtectedView = ({
1882
1883
  ] })
1883
1884
  ] }) });
1884
1885
  };
1886
+ var openLinksNewTabPlugin = () => {
1887
+ const onAnnotationLayerRender = (e) => {
1888
+ e.container.querySelectorAll(".rpv-core__annotation--link a[href]").forEach((linkEle) => {
1889
+ const href = linkEle.getAttribute("href");
1890
+ if (href && isExternal(href)) {
1891
+ linkEle.setAttribute("target", "_blank");
1892
+ linkEle.setAttribute("rel", "noopener noreferrer");
1893
+ }
1894
+ });
1895
+ };
1896
+ return {
1897
+ onAnnotationLayerRender
1898
+ };
1899
+ };
1885
1900
  var PdfPreview_default = ({ password, fileUrl, pageNo = 1, scale = 1, isHasThumbnails = true, onSetPassword, onSetPageNo }) => {
1886
1901
  const embedRef = useRef(null);
1887
1902
  const [sizes, setSizes] = useState([0]);
@@ -2013,10 +2028,11 @@ var PdfPreview_default = ({ password, fileUrl, pageNo = 1, scale = 1, isHasThumb
2013
2028
  plugins: [
2014
2029
  pageNavigationPluginInstance,
2015
2030
  thumbnailPluginInstance,
2016
- zoomPluginInstance
2031
+ zoomPluginInstance,
2017
2032
  // printPluginInstance,
2018
2033
  // rotatePluginInstance,
2019
2034
  // searchPluginInstance,
2035
+ openLinksNewTabPlugin()
2020
2036
  ],
2021
2037
  onPageChange,
2022
2038
  renderError,