@opentiny/tiny-robot 0.3.1-alpha.6 → 0.3.1-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,1482 @@
1
- import e from "../chat-input/index.js";
2
- import { u as a } from "../index2.js";
3
- const r = e;
4
- r.name = "TrSender";
1
+ var rt = Object.defineProperty;
2
+ var ct = (t, s, a) => s in t ? rt(t, s, { enumerable: !0, configurable: !0, writable: !0, value: a }) : t[s] = a;
3
+ var Pe = (t, s, a) => ct(t, typeof s != "symbol" ? s + "" : s, a);
4
+ import { ref as H, watch as ne, reactive as ut, onUnmounted as tt, computed as B, defineComponent as Ce, isVNode as dt, createElementBlock as E, openBlock as S, createCommentVNode as M, normalizeStyle as ze, createBlock as ee, unref as R, withCtx as ve, createElementVNode as z, createVNode as Y, normalizeClass as oe, resolveDynamicComponent as ft, toDisplayString as de, useAttrs as pt, resolveComponent as ht, mergeProps as Se, Fragment as ye, renderList as xe, mergeModels as Ze, useModel as vt, onMounted as yt, nextTick as j, Transition as Ne, withModifiers as gt, useSlots as mt, renderSlot as ae, isRef as wt, createTextVNode as Qe } from "vue";
5
+ import { TinyTooltip as Me, TinyInput as bt } from "@opentiny/vue";
6
+ import { f as St } from "../index4.js";
7
+ import { IconVoice as xt, IconUpload as Ct, IconRecordingWave as _t, IconClear as kt, IconSend as It, IconStop as Rt, IconAssociate as Tt } from "@opentiny/tiny-robot-svgs";
8
+ import { _ as _e } from "../_plugin-vue_export-helper.js";
9
+ import { t as Et } from "../utils.js";
10
+ function Ot(t, s) {
11
+ const a = H(t.modelValue || t.defaultValue || ""), r = H(null);
12
+ ne(
13
+ () => t.modelValue,
14
+ (m) => {
15
+ m !== void 0 && m !== a.value && (a.value = m);
16
+ }
17
+ ), ne(
18
+ () => a.value,
19
+ (m) => {
20
+ s("update:modelValue", m);
21
+ }
22
+ );
23
+ const f = (m) => {
24
+ a.value = m, s("update:modelValue", m);
25
+ }, I = (m) => {
26
+ m == null || m.preventDefault();
27
+ const k = a.value;
28
+ !t.disabled && !t.loading && k.trim() && s("submit", k);
29
+ }, h = () => {
30
+ a.value = "", s("update:modelValue", ""), s("clear");
31
+ }, v = H(!1);
32
+ return {
33
+ inputValue: a,
34
+ inputWrapper: r,
35
+ isComposing: v,
36
+ handleChange: f,
37
+ handleSubmit: I,
38
+ handleClear: h,
39
+ clearInput: () => {
40
+ h();
41
+ }
42
+ };
43
+ }
44
+ function $t(t, s, a, r, f, I, h, v, g, m, k, w, L, F, V, P) {
45
+ const W = () => {
46
+ w.value && (V != null && V.value && (P == null || P()), s("submit", a.value.trim()));
47
+ }, $ = (p, _) => {
48
+ if (!(p.key === "Enter")) return !1;
49
+ switch (_) {
50
+ case "enter":
51
+ return !p.shiftKey && !p.ctrlKey && !p.metaKey;
52
+ case "ctrlEnter":
53
+ return (p.ctrlKey || p.metaKey) && !p.shiftKey;
54
+ case "shiftEnter":
55
+ return p.shiftKey && !p.ctrlKey && !p.metaKey;
56
+ default:
57
+ return !1;
58
+ }
59
+ }, N = (p) => {
60
+ const _ = p.selectionStart ?? 0, U = p.selectionEnd ?? _, Z = a.value;
61
+ a.value = Z.substring(0, _) + `
62
+ ` + Z.substring(U), setTimeout(() => {
63
+ const D = _ + 1;
64
+ p.selectionStart = p.selectionEnd = D, p.scrollTop = p.scrollHeight;
65
+ }, 0);
66
+ }, C = (p) => {
67
+ if (t.submitType !== "enter" || p.key !== "Enter") return !1;
68
+ const _ = p.ctrlKey && !p.shiftKey, U = p.shiftKey && !p.ctrlKey;
69
+ if (_ || U) {
70
+ p.preventDefault();
71
+ const Z = p.target;
72
+ return (L == null ? void 0 : L.value) === "single" && F && F(), N(Z), !0;
73
+ }
74
+ return !1;
75
+ };
76
+ return {
77
+ handleKeyPress: (p) => {
78
+ if (!r.value && !C(p)) {
79
+ if (I.value) {
80
+ if (p.key === "ArrowDown") {
81
+ p.preventDefault(), m("down");
82
+ return;
83
+ }
84
+ if (p.key === "ArrowUp") {
85
+ p.preventDefault(), m("up");
86
+ return;
87
+ }
88
+ if (h.value && (t.activeSuggestionKeys || ["Enter", "Tab"]).includes(p.key)) {
89
+ p.preventDefault(), v();
90
+ return;
91
+ }
92
+ }
93
+ if (p.key === "Escape") {
94
+ I.value ? (g(), p.preventDefault()) : f.isRecording && (k(), p.preventDefault()), s("escape-press");
95
+ return;
96
+ }
97
+ $(p, t.submitType) && w.value && (p.preventDefault(), W());
98
+ }
99
+ },
100
+ triggerSubmit: W
101
+ };
102
+ }
103
+ class Le {
104
+ constructor(s) {
105
+ Pe(this, "recognition");
106
+ Pe(this, "options");
107
+ this.options = s, this.initialize();
108
+ }
109
+ /**
110
+ * 初始化语音识别实例
111
+ */
112
+ initialize() {
113
+ this.recognition = new (window.webkitSpeechRecognition || window.SpeechRecognition)(), this.recognition.continuous = this.options.continuous ?? !1, this.recognition.interimResults = this.options.interimResults ?? !0, this.recognition.lang = this.options.lang ?? navigator.language;
114
+ }
115
+ /**
116
+ * 检查浏览器是否支持 Web Speech API
117
+ */
118
+ static isSupported() {
119
+ return typeof window < "u" && ("webkitSpeechRecognition" in window || "SpeechRecognition" in window);
120
+ }
121
+ /**
122
+ * 检查浏览器是否支持 Web Speech API(实例方法)
123
+ */
124
+ isSupported() {
125
+ return Le.isSupported();
126
+ }
127
+ /**
128
+ * 设置语音识别事件处理器
129
+ * @param callbacks 语音识别回调函数集合
130
+ */
131
+ setupEventHandlers(s) {
132
+ !this.recognition || !s || (this.recognition.onstart = () => {
133
+ s.onStart();
134
+ }, this.recognition.onend = () => {
135
+ s.onEnd();
136
+ }, this.recognition.onresult = (a) => {
137
+ const r = Array.from(a.results).map((I) => I[0].transcript).join(""), f = a.results[a.resultIndex];
138
+ f != null && f.isFinal ? s.onFinal(r) : s.onInterim(r);
139
+ }, this.recognition.onerror = (a) => {
140
+ s.onError(new Error(a.error)), this.cleanup();
141
+ });
142
+ }
143
+ /**
144
+ * 清理事件监听器
145
+ */
146
+ cleanup() {
147
+ this.recognition && (this.recognition.onstart = null, this.recognition.onend = null, this.recognition.onresult = null, this.recognition.onerror = null);
148
+ }
149
+ /**
150
+ * 开始语音识别
151
+ * @param callbacks 语音识别回调函数集合
152
+ */
153
+ start(s) {
154
+ if (!this.recognition) {
155
+ s.onError(new Error("浏览器不支持语音识别"));
156
+ return;
157
+ }
158
+ this.setupEventHandlers(s);
159
+ try {
160
+ this.recognition.start();
161
+ } catch (a) {
162
+ s.onError(a instanceof Error ? a : new Error("语音识别启动失败"));
163
+ }
164
+ }
165
+ /**
166
+ * 停止语音识别并清理资源
167
+ */
168
+ stop() {
169
+ if (this.recognition) {
170
+ this.cleanup();
171
+ try {
172
+ this.recognition.stop();
173
+ } catch (s) {
174
+ console.warn("停止语音识别时发生错误:", s);
175
+ }
176
+ }
177
+ }
178
+ }
179
+ function Bt(t) {
180
+ const s = ut({
181
+ isRecording: !1,
182
+ isSupported: !1,
183
+ error: void 0
184
+ }), a = {
185
+ onStart: () => {
186
+ var v;
187
+ s.isRecording = !0, s.error = void 0, (v = t.onStart) == null || v.call(t);
188
+ },
189
+ onInterim: (v) => {
190
+ var g;
191
+ (g = t.onInterim) == null || g.call(t, v);
192
+ },
193
+ onFinal: (v) => {
194
+ var g;
195
+ (g = t.onFinal) == null || g.call(t, v);
196
+ },
197
+ onEnd: (v) => {
198
+ var g;
199
+ s.isRecording && (s.isRecording = !1, (g = t.onEnd) == null || g.call(t, v));
200
+ },
201
+ onError: (v) => {
202
+ var g;
203
+ s.error = v, s.isRecording = !1, (g = t.onError) == null || g.call(t, v);
204
+ }
205
+ }, r = Le.isSupported();
206
+ s.isSupported = t.customHandler ? t.customHandler.isSupported() : r;
207
+ const f = t.customHandler ?? (r ? new Le(t) : null), I = () => {
208
+ var v;
209
+ if (!s.isSupported || !f) {
210
+ const g = new Error("语音识别不受支持");
211
+ s.error = g, (v = t.onError) == null || v.call(t, g);
212
+ return;
213
+ }
214
+ if (s.isRecording) {
215
+ f.stop(), s.isRecording = !1, setTimeout(() => {
216
+ f.start(a);
217
+ }, 200);
218
+ return;
219
+ }
220
+ f.start(a);
221
+ }, h = () => {
222
+ !s.isRecording || !f || (f.stop(), a.onEnd());
223
+ };
224
+ return tt(() => {
225
+ s.isRecording && f && (f.stop(), s.isRecording = !1);
226
+ }), {
227
+ speechState: s,
228
+ start: I,
229
+ stop: h
230
+ };
231
+ }
232
+ function Lt(t, s, a, r, f, I) {
233
+ const h = H(!1), v = H(-1), g = H(-1), m = H(null), k = H(""), w = H(!1), L = B(() => {
234
+ var J, q;
235
+ if (!((J = t.value) != null && J.length)) return "";
236
+ const D = m.value === "mouse" ? g.value : v.value;
237
+ return ((q = t.value[D]) == null ? void 0 : q.content) || "";
238
+ }), F = (D) => {
239
+ k.value = D, w.value = !0;
240
+ }, V = () => {
241
+ k.value = "", w.value = !1;
242
+ }, P = (D) => {
243
+ const J = D || L.value;
244
+ if (!J || !s.value) {
245
+ V();
246
+ return;
247
+ }
248
+ const q = J.substring(s.value.length);
249
+ J.toLowerCase().startsWith(s.value.toLowerCase()) && q ? F(q) : V();
250
+ }, W = () => {
251
+ v.value = -1, g.value = -1, m.value = null;
252
+ }, $ = () => {
253
+ h.value = !0, P();
254
+ }, N = () => {
255
+ h.value = !1, W(), V();
256
+ }, C = B(() => {
257
+ var D;
258
+ return a.value ? !0 : !!(s.value && ((D = t.value) == null ? void 0 : D.length) > 0 && !r.value);
259
+ }), x = (D) => {
260
+ N(), s.value = D, f(D), I(D);
261
+ }, p = () => {
262
+ L.value && x(L.value);
263
+ }, _ = (D) => {
264
+ !h.value || !t.value || (m.value = "keyboard", v.value === -1 ? v.value = D === "down" ? 0 : t.value.length - 1 : D === "down" ? v.value = (v.value + 1) % t.value.length : v.value = (v.value - 1 + t.value.length) % t.value.length, P());
265
+ }, U = (D) => {
266
+ t.value && (m.value = "mouse", g.value = D, P());
267
+ }, Z = () => {
268
+ t.value && (g.value = -1, v.value !== -1 ? m.value = "keyboard" : m.value = null, P());
269
+ };
270
+ return ne(C, (D) => {
271
+ D ? h.value || $() : h.value && N();
272
+ }), {
273
+ // 弹窗控制
274
+ isPopupVisible: h,
275
+ openPopup: $,
276
+ closePopup: N,
277
+ // 自动完成占位符
278
+ autoCompleteText: k,
279
+ showTabIndicator: w,
280
+ syncAutoComplete: P,
281
+ // 选中控制层
282
+ activeSuggestion: L,
283
+ activeKeyboardIndex: v,
284
+ activeMouseIndex: g,
285
+ // 交互处理
286
+ navigateWithKeyboard: _,
287
+ handleMouseEnter: U,
288
+ handleMouseLeave: Z,
289
+ // 业务操作
290
+ applySuggestion: x,
291
+ confirmSelection: p
292
+ };
293
+ }
294
+ const Dt = { class: "action-buttons" }, Kt = { class: "action-buttons__submit-content" }, Ht = {
295
+ key: 0,
296
+ class: "action-buttons__cancel-text"
297
+ }, At = /* @__PURE__ */ Ce({
298
+ __name: "ActionButtons",
299
+ props: {
300
+ loading: { type: Boolean, default: !1 },
301
+ disabled: { type: Boolean, default: !1 },
302
+ showClear: { type: Boolean, default: !0 },
303
+ hasContent: { type: Boolean, default: !1 },
304
+ buttonGroup: {},
305
+ allowSpeech: { type: Boolean, default: !1 },
306
+ speechStatus: { default: () => ({
307
+ isRecording: !1,
308
+ isSupported: !1
309
+ }) },
310
+ allowFiles: { type: Boolean, default: !1 },
311
+ submitType: { default: "enter" },
312
+ showShortcuts: { type: Boolean },
313
+ isOverLimit: { type: Boolean, default: !1 },
314
+ stopText: { default: void 0 }
315
+ },
316
+ emits: ["clear", "submit", "cancel", "trigger-select", "voice-button-click"],
317
+ setup(t, { emit: s }) {
318
+ const a = t, r = s, f = B(() => {
319
+ var x, p;
320
+ const C = (p = (x = a.buttonGroup) == null ? void 0 : x.file) == null ? void 0 : p.tooltips;
321
+ if (typeof C == "string" && C)
322
+ return () => C;
323
+ if (typeof C == "function")
324
+ return C;
325
+ }), I = B(() => {
326
+ var x, p;
327
+ const C = (p = (x = a.buttonGroup) == null ? void 0 : x.submit) == null ? void 0 : p.tooltips;
328
+ if (typeof C == "string" && C)
329
+ return () => C;
330
+ if (typeof C == "function")
331
+ return C;
332
+ }), h = B(() => a.allowSpeech), v = B(() => a.speechStatus.isRecording), g = B(() => a.disabled), m = B(() => {
333
+ var C, x;
334
+ return g.value || a.isOverLimit || ((x = (C = a.buttonGroup) == null ? void 0 : C.submit) == null ? void 0 : x.disabled);
335
+ }), k = B(() => a.allowFiles || a.allowSpeech || a.showClear), w = B(() => {
336
+ var x, p;
337
+ const C = (p = (x = a.buttonGroup) == null ? void 0 : x.voice) == null ? void 0 : p.icon;
338
+ return C ? dt(C) ? () => C : C : xt;
339
+ }), L = () => {
340
+ g.value || r("clear");
341
+ }, F = () => {
342
+ g.value || r("voice-button-click");
343
+ }, V = () => {
344
+ m.value || r("submit");
345
+ }, P = () => {
346
+ g.value || r("cancel");
347
+ }, W = B(() => {
348
+ var C, x;
349
+ return g.value || ((x = (C = a.buttonGroup) == null ? void 0 : C.file) == null ? void 0 : x.disabled);
350
+ }), $ = () => {
351
+ W.value || r("trigger-select");
352
+ }, N = B(() => {
353
+ var C, x;
354
+ return ((x = (C = a.buttonGroup) == null ? void 0 : C.file) == null ? void 0 : x.tooltipPlacement) || "top";
355
+ });
356
+ return (C, x) => (S(), E("div", Dt, [
357
+ k.value ? (S(), E("div", {
358
+ key: 0,
359
+ class: "action-buttons__utility",
360
+ style: ze({ "padding-right": t.hasContent || t.loading ? "0" : "6px" })
361
+ }, [
362
+ t.allowFiles && !t.loading ? (S(), ee(R(Me), {
363
+ key: 0,
364
+ effect: "light",
365
+ placement: N.value,
366
+ "render-content": f.value,
367
+ "visible-arrow": !1,
368
+ "popper-class": "tr-sender-actions-upload-button-popper"
369
+ }, {
370
+ default: ve(() => [
371
+ z("div", {
372
+ class: "action-buttons__button",
373
+ onClick: $,
374
+ onFocusCapture: x[0] || (x[0] = (p) => p.stopPropagation())
375
+ }, [
376
+ Y(R(Ct), {
377
+ class: oe(["action-buttons__icon", { "is-disabled": W.value }]),
378
+ alt: "上传文件"
379
+ }, null, 8, ["class"])
380
+ ], 32)
381
+ ]),
382
+ _: 1
383
+ }, 8, ["placement", "render-content"])) : M("", !0),
384
+ h.value && !t.loading ? (S(), E("div", {
385
+ key: 1,
386
+ class: oe(["action-buttons__button", { "is-recording": v.value }]),
387
+ onClick: F
388
+ }, [
389
+ v.value ? (S(), ee(R(_t), {
390
+ key: 1,
391
+ class: "action-buttons__icon",
392
+ alt: "语音中"
393
+ })) : (S(), ee(ft(w.value), {
394
+ key: 0,
395
+ class: "action-buttons__icon",
396
+ alt: "录音"
397
+ }))
398
+ ], 2)) : M("", !0),
399
+ t.showClear && t.hasContent ? (S(), ee(R(Me), {
400
+ key: 2,
401
+ content: "清空内容",
402
+ placement: "top"
403
+ }, {
404
+ default: ve(() => [
405
+ z("div", {
406
+ class: "action-buttons__button",
407
+ onClick: L
408
+ }, [
409
+ Y(R(kt), { class: "action-buttons__icon" })
410
+ ])
411
+ ]),
412
+ _: 1
413
+ })) : M("", !0)
414
+ ], 4)) : M("", !0),
415
+ t.hasContent || t.loading ? (S(), E("div", {
416
+ key: 1,
417
+ class: "action-buttons__button action-buttons__submit",
418
+ onClick: x[1] || (x[1] = (p) => t.loading ? P() : V())
419
+ }, [
420
+ z("div", Kt, [
421
+ t.loading ? (S(), E("div", {
422
+ key: 1,
423
+ class: oe(["action-buttons__cancel", { "action-buttons__cancel--icon-only": !t.stopText }])
424
+ }, [
425
+ Y(R(Rt), {
426
+ class: "action-buttons__icon action-buttons__icon--cancel",
427
+ alt: "停止"
428
+ }),
429
+ t.stopText ? (S(), E("span", Ht, de(t.stopText), 1)) : M("", !0)
430
+ ], 2)) : (S(), ee(R(Me), {
431
+ key: 0,
432
+ effect: "light",
433
+ placement: "top",
434
+ "render-content": I.value,
435
+ "visible-arrow": !1
436
+ }, {
437
+ default: ve(() => [
438
+ Y(R(It), {
439
+ class: oe(["action-buttons__icon", "action-buttons__icon--send", { "is-disabled": m.value }]),
440
+ alt: "发送"
441
+ }, null, 8, ["class"])
442
+ ]),
443
+ _: 1
444
+ }, 8, ["render-content"]))
445
+ ])
446
+ ])) : M("", !0)
447
+ ]));
448
+ }
449
+ }), et = /* @__PURE__ */ _e(At, [["__scopeId", "data-v-f71ebb23"]]);
450
+ function Vt(t, s = {}) {
451
+ let a = [], r = [], f = t;
452
+ return { commit: (k) => {
453
+ var w;
454
+ a.push(f), f = k, r.length && ((w = s.onRemoveHistory) == null || w.call(s, r)), r = [];
455
+ }, undo: () => a.length ? (r.push(f), f = a.pop(), f) : null, redo: () => r.length ? (a.push(f), f = r.pop(), f) : null, clear: () => {
456
+ var k, w;
457
+ a.length && ((k = s.onRemoveHistory) == null || k.call(s, a)), r.length && ((w = s.onRemoveHistory) == null || w.call(s, r)), a = [], r = [];
458
+ }, get: () => f };
459
+ }
460
+ const Ft = ["data-id", "data-type"], Pt = ["data-id", "data-type"], Mt = /* @__PURE__ */ Ce({
461
+ inheritAttrs: !1,
462
+ __name: "Block",
463
+ props: {
464
+ id: {},
465
+ type: {},
466
+ content: {},
467
+ readonly: { type: Boolean },
468
+ asChild: { type: Boolean }
469
+ },
470
+ setup(t) {
471
+ const s = t, a = pt();
472
+ return (r, f) => {
473
+ const I = ht("Block", !0);
474
+ return s.type !== "block" ? (S(), E("span", Se({
475
+ key: 0,
476
+ "data-id": s.id,
477
+ "data-type": s.type
478
+ }, R(a)), de(s.content), 17, Ft)) : (S(), E(ye, { key: 1 }, [
479
+ s.asChild ? (S(!0), E(ye, { key: 0 }, xe(s.content, (h) => (S(), ee(I, Se({
480
+ key: `${h.id}-${h.type}`
481
+ }, { ref_for: !0 }, h), null, 16))), 128)) : (S(), E("span", Se({
482
+ key: 1,
483
+ "data-id": s.id,
484
+ "data-type": s.type
485
+ }, R(a)), [
486
+ (S(!0), E(ye, null, xe(s.content, (h) => (S(), ee(I, Se({
487
+ key: `${h.id}-${h.type}`
488
+ }, { ref_for: !0 }, h), null, 16))), 128))
489
+ ], 16, Pt))
490
+ ], 64));
491
+ };
492
+ }
493
+ }), Wt = /* @__PURE__ */ _e(Mt, [["__scopeId", "data-v-13862606"]]), Nt = { class: "editor-container" }, We = "​", zt = 40, Ut = /* @__PURE__ */ Ce({
494
+ __name: "TemplateEditor",
495
+ props: /* @__PURE__ */ Ze({
496
+ autoSize: { type: [Boolean, Object] }
497
+ }, {
498
+ modelValue: { default: () => [] },
499
+ modelModifiers: {}
500
+ }),
501
+ emits: /* @__PURE__ */ Ze(["submit"], ["update:modelValue"]),
502
+ setup(t, { expose: s, emit: a }) {
503
+ const r = typeof window.ShadowRoot.prototype.getSelection == "function", f = typeof window.Selection.prototype.getComposedRanges == "function";
504
+ function I() {
505
+ const e = navigator.userAgent;
506
+ return e.includes("Safari") && !e.includes("Chrome") && !e.includes("Chromium") && !e.includes("CriOS");
507
+ }
508
+ const h = I(), v = () => Math.random().toString(36).substring(2, 15), g = We, m = We, k = We, w = t, L = vt(t, "modelValue"), F = a, V = H(0), P = (e) => e.map((n) => ({
509
+ id: n.id || v(),
510
+ ...n.type === "template" ? { ...n, prefix: m, suffix: k } : n
511
+ })), W = (e) => e.map((n) => ({ id: n.id, type: n.type, content: n.content })), $ = H(P(L.value || [])), N = (e) => {
512
+ $.value = e;
513
+ }, C = B(() => {
514
+ const e = [], n = [], o = $.value;
515
+ if (o.length >= 2) {
516
+ const l = o[0], d = o[1];
517
+ l.type === "text" && l.content.length === 0 && d.type === "template" && e.push({ ...l, content: g });
518
+ const b = o[o.length - 1], O = o[o.length - 2];
519
+ b.type === "text" && b.content.length === 0 && O.type === "template" && n.push({ ...b, content: g });
520
+ }
521
+ o.length > 0 && o[0].type === "template" && e.push({ type: "text", content: g, id: v() }), o.length > 0 && o[o.length - 1].type === "template" && n.push({ type: "text", content: g, id: v() });
522
+ const c = new RegExp(g, "g");
523
+ return o.length > 0 && (o[0].content !== g && (o[0].content = o[0].content.replace(c, "")), o[o.length - 1].content !== g && (o[o.length - 1].content = o[o.length - 1].content.replace(c, ""))), e.concat(o).concat(n);
524
+ }), x = B(() => $.value.map((e) => e.type === "template" ? [
525
+ { id: e.id, type: "prefix", content: e.prefix },
526
+ { id: e.id, type: "template", content: e.content },
527
+ { id: e.id, type: "suffix", content: e.suffix }
528
+ ] : [e]).flat()), p = B(() => C.value.map((e) => e.type === "text" ? e : h ? {
529
+ id: e.id,
530
+ type: "block",
531
+ asChild: !0,
532
+ content: [
533
+ { id: e.id, type: "prefix", content: e.prefix },
534
+ {
535
+ id: e.id,
536
+ type: "block",
537
+ content: [
538
+ { id: e.id, type: "template", content: e.content },
539
+ { id: e.id, type: "suffix", content: e.suffix }
540
+ ]
541
+ }
542
+ ]
543
+ } : {
544
+ id: e.id,
545
+ type: "block",
546
+ asChild: !0,
547
+ content: [
548
+ {
549
+ id: e.id,
550
+ type: "block",
551
+ content: [
552
+ { id: e.id, type: "prefix", content: e.prefix },
553
+ { id: e.id, type: "template", content: e.content }
554
+ ]
555
+ },
556
+ { id: e.id, type: "suffix", content: e.suffix }
557
+ ]
558
+ })), _ = H(null), U = H(zt), Z = () => {
559
+ if (!_.value) return;
560
+ const e = window.getComputedStyle(_.value), n = parseFloat(e.fontSize), o = parseFloat(e.lineHeight);
561
+ U.value = isNaN(o) ? n * 2.5 : o;
562
+ }, D = B(() => {
563
+ if (!w.autoSize)
564
+ return {};
565
+ const e = typeof w.autoSize == "boolean" ? { minRows: 1, maxRows: 3 } : w.autoSize, n = e.minRows * U.value, o = e.maxRows * U.value;
566
+ return {
567
+ minHeight: `${n}px`,
568
+ maxHeight: `${o}px`,
569
+ overflowY: "auto",
570
+ overflowX: "hidden"
571
+ };
572
+ }), J = () => {
573
+ if (!_.value) return;
574
+ const e = window.getSelection();
575
+ if (!e || e.rangeCount === 0) return;
576
+ const o = e.getRangeAt(0).getBoundingClientRect(), c = _.value.getBoundingClientRect(), l = o.top - c.top, d = o.bottom - c.top, b = _.value.scrollTop, O = _.value.clientHeight;
577
+ d > O ? _.value.scrollTop = b + (d - O) + 10 : l < 0 && (_.value.scrollTop = b + l - 10);
578
+ }, q = (e) => {
579
+ const n = Date.now(), o = JSON.stringify(e);
580
+ return `${n}:${o}`;
581
+ }, ke = (e) => {
582
+ const n = parseInt(e.slice(0, 13)), o = JSON.parse(e.slice(14));
583
+ return {
584
+ timestamp: n,
585
+ data: o
586
+ };
587
+ }, K = /* @__PURE__ */ new Map(), A = Vt(q($.value), {
588
+ onRemoveHistory: (e) => {
589
+ for (const n of e)
590
+ K.delete(n);
591
+ }
592
+ });
593
+ ne(
594
+ () => L.value,
595
+ (e) => {
596
+ const n = P(e || []);
597
+ if (JSON.stringify(n) !== JSON.stringify($.value)) {
598
+ if (_.value) {
599
+ const c = le(_.value);
600
+ c && K.set(A.get(), X(c));
601
+ }
602
+ N(n), A.commit(q($.value));
603
+ }
604
+ },
605
+ { deep: !0 }
606
+ );
607
+ const ge = (e, n = document.body) => n.contains(e) ? e instanceof HTMLElement && e.dataset.id ? e : e.parentElement ? ge(e.parentElement, n) : null : null, fe = (e) => e === _.value, le = (e) => {
608
+ const n = window.getSelection();
609
+ if (!n)
610
+ return null;
611
+ const o = n.rangeCount > 0 ? n.getRangeAt(0) : null, c = e.getRootNode();
612
+ if (!(c instanceof ShadowRoot))
613
+ return o;
614
+ if (f) {
615
+ const l = n.getComposedRanges(h ? c : { shadowRoots: [c] });
616
+ return (l == null ? void 0 : l[0]) ?? null;
617
+ }
618
+ if (r) {
619
+ const l = c.getSelection();
620
+ return l.rangeCount > 0 ? l.getRangeAt(0) : null;
621
+ }
622
+ return o;
623
+ }, me = (e, n) => {
624
+ var c;
625
+ if (!e.firstChild || e.firstChild.nodeType !== Node.TEXT_NODE)
626
+ return { node: e, offset: 0 };
627
+ const o = ((c = e.firstChild.textContent) == null ? void 0 : c.length) ?? 0;
628
+ return { node: e.firstChild, offset: Math.min(n, o) };
629
+ }, te = (e, n, o, c) => {
630
+ const l = window.getSelection();
631
+ if (!l)
632
+ return;
633
+ const { node: d, offset: b } = me(e, n);
634
+ if (!o)
635
+ l.setBaseAndExtent(d, b, d, b);
636
+ else {
637
+ const { node: O, offset: i } = me(o, c ?? 0);
638
+ l.setBaseAndExtent(d, b, O, i);
639
+ }
640
+ j(() => {
641
+ J();
642
+ });
643
+ }, re = (e, n) => {
644
+ const o = v(), c = { id: o, type: "text", content: e };
645
+ if (n) {
646
+ const l = $.value.findIndex((d) => d.id === n);
647
+ l !== -1 ? (N(
648
+ $.value.slice(0, l + 1).concat(c).concat($.value.slice(l + 1))
649
+ ), A.commit(q($.value))) : console.warn(`can not find item with id: ${n}`);
650
+ } else
651
+ N([c].concat($.value)), A.commit(q($.value));
652
+ j(() => {
653
+ var d;
654
+ const l = (d = _.value) == null ? void 0 : d.querySelector(`[data-id="${o}"][data-type="text"]`);
655
+ l && te(l, e.length);
656
+ }), L.value = W($.value);
657
+ }, Q = H({
658
+ hasStarted: !1,
659
+ range: null
660
+ }), Ke = (e) => {
661
+ var O;
662
+ const n = e;
663
+ e.preventDefault();
664
+ const { inputType: o } = n, c = (n.data || ((O = n.dataTransfer) == null ? void 0 : O.getData("text/plain")) || "").replace(m, "").replace(k, ""), l = n.getTargetRanges()[0];
665
+ if (!l) {
666
+ console.warn("range is null", l);
667
+ return;
668
+ }
669
+ const d = [
670
+ "insertText",
671
+ "insertFromPaste",
672
+ "insertReplacementText",
673
+ "deleteContentBackward",
674
+ "deleteContentForward",
675
+ "deleteWordBackward",
676
+ "deleteWordForward",
677
+ "deleteSoftLineBackward",
678
+ "deleteSoftLineForward",
679
+ "deleteByCut"
680
+ ], b = le(_.value);
681
+ if (d.includes(o)) {
682
+ if (c && fe(l.startContainer) && fe(l.endContainer)) {
683
+ b && K.set(A.get(), X(b)), re(c);
684
+ return;
685
+ }
686
+ const i = X(l);
687
+ i.startId && i.endId ? (b && K.set(A.get(), X(b)), we(i, o, c)) : console.warn("range is not valid, range:", i);
688
+ } else o === "insertCompositionText" && Q.value.hasStarted && (Q.value = { hasStarted: !1, range: X(l) });
689
+ }, X = (e) => {
690
+ const n = ge(e.startContainer, _.value), o = ge(e.endContainer, _.value);
691
+ return {
692
+ collapsed: e.collapsed,
693
+ endContainer: e.endContainer,
694
+ endId: o == null ? void 0 : o.dataset.id,
695
+ endEl: o,
696
+ endOffset: e.endOffset,
697
+ endType: o == null ? void 0 : o.dataset.type,
698
+ startContainer: e.startContainer,
699
+ startId: n == null ? void 0 : n.dataset.id,
700
+ startEl: n,
701
+ startOffset: e.startOffset,
702
+ startType: n == null ? void 0 : n.dataset.type
703
+ };
704
+ }, se = (e, n, o, c) => e.slice(0, o) + n + e.slice(c), we = (e, n, o) => {
705
+ const c = Re(e);
706
+ if (!Array.isArray(c) || c.length === 0)
707
+ return;
708
+ const l = Te(c, e, n, o);
709
+ if (l.some((u) => u.tag === "new")) {
710
+ const { afterId: u, content: y } = l[0];
711
+ re(y, u);
712
+ return;
713
+ }
714
+ const d = l, b = [];
715
+ for (const [u, y] of d.entries()) {
716
+ const T = $.value.find((ue) => ue.id === y.id), G = u === 0 ? o : "";
717
+ T ? T.type === "text" ? T.content = se(T.content, G, y.startOffset, y.endOffset) : T.type === "template" ? y.type === "prefix" || y.type === "suffix" ? y.startOffset === 0 && y.endOffset === 1 && G.length === 0 ? T[y.type] = "" : console.warn(`${y.type} can not be inserted text. it only can be deleted`, y) : y.startOffset < 0 || y.endOffset > T.content.length ? b.push(T.id) : T.content = se(T.content, G, y.startOffset, y.endOffset) : console.warn("dataItem.type is not text or template", T) : console.warn("can not find dataItem", y);
718
+ }
719
+ let O = $.value.filter((u) => !b.includes(u.id));
720
+ O = O.filter((u) => !(u.type === "template" && [u.prefix, u.suffix, u.content].join("").length === 0));
721
+ const i = /* @__PURE__ */ new Set();
722
+ O.forEach((u, y, T) => {
723
+ if (T.length >= 2) {
724
+ if (y === 0 || y === 1) {
725
+ const G = T[0], ue = T[1];
726
+ if (G.type === "text" && G.content.length === 0 && ue.type === "template")
727
+ return;
728
+ }
729
+ if (y === T.length - 2 || y === T.length - 1) {
730
+ const G = T[T.length - 1], ue = T[T.length - 2];
731
+ if (G.type === "text" && G.content.length === 0 && ue.type === "template")
732
+ return;
733
+ }
734
+ }
735
+ u.type === "text" && u.content.length === 0 && i.add(u.id);
736
+ }), O = O.filter((u) => !i.has(u.id));
737
+ for (const u of O.filter((y) => y.type === "template"))
738
+ u.prefix.length === 0 && (u.prefix = m), u.suffix.length === 0 && (u.suffix = k);
739
+ N(O), A.commit(q($.value)), d.length > 0 && Ie(d, o), L.value = W($.value), j(() => {
740
+ J();
741
+ });
742
+ }, Ie = (e, n) => {
743
+ const o = e[0], c = `[data-id="${o.id}"][data-type="${o.type}"]`, l = e.slice(1).map((d) => `[data-id="${d.id}"][data-type="${d.type}"]`);
744
+ j(() => {
745
+ var b, O;
746
+ const d = (b = _.value) == null ? void 0 : b.querySelector(c);
747
+ if (d)
748
+ te(d, o.startOffset + n.length);
749
+ else if (n.length === 0)
750
+ for (const i of l) {
751
+ const u = (O = _.value) == null ? void 0 : O.querySelector(i);
752
+ if (u) {
753
+ te(u, 0);
754
+ break;
755
+ }
756
+ }
757
+ else
758
+ console.warn(`can not find el with selector: ${c}`);
759
+ });
760
+ }, Re = (e) => {
761
+ const n = x.value.findIndex((b) => b.id === e.startId && b.type === e.startType), o = x.value.findIndex((b) => b.id === e.endId && b.type === e.endType);
762
+ if (n === -1 || o === -1 || n > o)
763
+ return console.warn("startIndex or endIndex is -1, or startIndex > endIndex. ", { range: e }), null;
764
+ const c = x.value[n], l = x.value[o];
765
+ if (n === o)
766
+ return [
767
+ {
768
+ id: c.id,
769
+ type: c.type,
770
+ startOffset: e.startOffset,
771
+ endOffset: e.endOffset
772
+ }
773
+ ];
774
+ const d = [
775
+ {
776
+ id: c.id,
777
+ type: c.type,
778
+ startOffset: e.startOffset,
779
+ endOffset: c.content.length
780
+ }
781
+ ];
782
+ for (let b = n + 1; b < o; b++) {
783
+ const O = x.value[b];
784
+ d.push({
785
+ id: O.id,
786
+ type: O.type,
787
+ startOffset: 0,
788
+ endOffset: O.content.length
789
+ });
790
+ }
791
+ return d.push({
792
+ id: l.id,
793
+ type: l.type,
794
+ startOffset: 0,
795
+ endOffset: e.endOffset
796
+ }), d;
797
+ }, Te = (e, n, o, c) => {
798
+ const l = e[0];
799
+ if (l.type !== "prefix" && l.type !== "suffix")
800
+ return e;
801
+ if (e.length === 1) {
802
+ if (n.collapsed)
803
+ if (n.startOffset === 0) {
804
+ const d = ie(l, c);
805
+ return d ? [d] : [];
806
+ } else {
807
+ const d = be(l, c);
808
+ return d ? [d] : [];
809
+ }
810
+ if (o.startsWith("insert"))
811
+ if (h) {
812
+ const d = ie(l, c);
813
+ return d ? [d] : [];
814
+ } else {
815
+ const d = be(l, c);
816
+ return d ? [d] : [];
817
+ }
818
+ if (o.startsWith("delete")) {
819
+ if (o.includes("Backward")) {
820
+ const d = ie(l, c, 1);
821
+ return d ? [d] : [];
822
+ } else if (o.includes("Forward")) {
823
+ const d = be(l, c, 1);
824
+ return d ? [d] : [];
825
+ }
826
+ }
827
+ }
828
+ return c.length > 0 ? e.slice(1) : e;
829
+ }, ie = (e, n, o = 0) => {
830
+ const c = x.value.findIndex((l) => l.id === e.id && l.type === e.type);
831
+ if (c > 0) {
832
+ const l = x.value[c - 1], { id: d, type: b, content: O } = l;
833
+ if (b === "text" || b === "template")
834
+ return {
835
+ id: d,
836
+ type: b,
837
+ startOffset: O.length - o,
838
+ endOffset: O.length
839
+ };
840
+ if (n.length > 0)
841
+ return { tag: "new", afterId: d, type: "text", content: n };
842
+ if (console.warn("the previous item is not text or template", { current: e, previous: l }), o === 1)
843
+ return { ...e, endOffset: e.startOffset };
844
+ } else return n.length > 0 ? { tag: "new", type: "text", content: n } : (console.warn("the previous item of current is not found", { current: e }), null);
845
+ return e;
846
+ }, be = (e, n, o = 0) => {
847
+ const c = x.value.findIndex((l) => l.id === e.id && l.type === e.type);
848
+ if (c < x.value.length - 1) {
849
+ const l = x.value[c + 1], { id: d, type: b } = l;
850
+ if (b === "text" || b === "template")
851
+ return {
852
+ id: d,
853
+ type: b,
854
+ startOffset: 0,
855
+ endOffset: 0 + o
856
+ };
857
+ if (n.length > 0)
858
+ return { tag: "new", afterId: e.id, type: "text", content: n };
859
+ if (console.warn("the next item is not text or template", { current: e, next: l }), o === 1)
860
+ return { ...e, startOffset: e.endOffset };
861
+ } else return n.length > 0 ? { tag: "new", afterId: e.id, type: "text", content: n } : (console.warn("the next item of current is not found", { current: e }), null);
862
+ return e;
863
+ }, pe = () => {
864
+ Q.value = { hasStarted: !0, range: null };
865
+ }, He = (e) => {
866
+ const n = Q.value.range;
867
+ n ? (e.data && fe(n.startContainer) && fe(n.endContainer) ? (K.set(A.get(), X(n)), re(e.data)) : n.startId && n.endId ? (K.set(A.get(), X(n)), we(n, "insertCompositionText", e.data)) : console.warn("range is not valid, range:", n), V.value++, j(() => {
868
+ J();
869
+ })) : console.warn("range is null, compositionEnd:", e), Q.value = { hasStarted: !1, range: null };
870
+ }, he = (() => {
871
+ const e = navigator.userAgent.toLowerCase();
872
+ return /macintosh|mac os x|iphone|ipad|ipod/.test(e);
873
+ })(), Ae = (e) => {
874
+ const n = he && e.metaKey && !e.shiftKey && e.key.toLowerCase() === "z" || // Cmd+Z
875
+ !he && e.ctrlKey && !e.shiftKey && e.key.toLowerCase() === "z", o = he && e.metaKey && e.shiftKey && e.key.toLowerCase() === "z" || // Cmd+Shift+z
876
+ !he && e.ctrlKey && (e.key.toLowerCase() === "y" || e.shiftKey && e.key.toLowerCase() === "z"), c = e.key.toLowerCase() === "enter";
877
+ if (n) {
878
+ e.preventDefault();
879
+ const l = le(_.value);
880
+ l && K.set(A.get(), X(l));
881
+ const d = A.undo();
882
+ d && Ee(d);
883
+ }
884
+ if (o) {
885
+ e.preventDefault();
886
+ const l = A.redo();
887
+ l && Ee(l);
888
+ }
889
+ c && (e.preventDefault(), F("submit"));
890
+ }, Ee = (e) => {
891
+ const { data: n } = ke(e);
892
+ if (N(n), K.has(e)) {
893
+ const o = K.get(e);
894
+ j(() => {
895
+ const c = _.value.querySelector(`[data-id="${o.startId}"][data-type="${o.startType}"]`), l = _.value.querySelector(`[data-id="${o.endId}"][data-type="${o.endType}"]`);
896
+ c && te(c, o.startOffset, l, o.endOffset);
897
+ });
898
+ }
899
+ L.value = W($.value);
900
+ }, ce = (e, n) => {
901
+ var l, d;
902
+ const o = (l = _.value) == null ? void 0 : l.querySelector(`[data-id="${e}"][data-type="${n}"]`);
903
+ if (!o) return;
904
+ const c = ((d = o.textContent) == null ? void 0 : d.length) || 0;
905
+ te(o, c);
906
+ }, Ve = () => {
907
+ _.value && j(() => {
908
+ const e = $.value, n = e.find((c) => c.type === "template");
909
+ n && ce(n.id, "template"), e.every((c) => c.type === "text") && e.length === 1 && ce(e[0].id, "text");
910
+ });
911
+ }, Fe = () => {
912
+ A.clear(), K.clear();
913
+ }, Oe = () => {
914
+ if (!_.value || Q.value.range)
915
+ return;
916
+ const e = le(_.value);
917
+ if (e != null && e.collapsed && C.value.length > 0) {
918
+ const n = X(e), o = C.value[0];
919
+ if (n.startEl && n.startId === o.id && n.startOffset === 0 && o.content === g && o.type === "text") {
920
+ te(n.startEl, 1);
921
+ return;
922
+ }
923
+ const c = C.value[C.value.length - 1];
924
+ if (n.endEl && n.endId === c.id && n.endOffset === 1 && c.content === g && c.type === "text") {
925
+ te(n.endEl, 0);
926
+ return;
927
+ }
928
+ }
929
+ };
930
+ return yt(() => {
931
+ document.addEventListener("selectionchange", Oe), j(() => {
932
+ Z();
933
+ });
934
+ }), tt(() => {
935
+ document.removeEventListener("selectionchange", Oe);
936
+ }), s({
937
+ clearHistory: Fe,
938
+ activateFirstField: Ve
939
+ }), (e, n) => (S(), E("div", Nt, [
940
+ (S(), E("div", {
941
+ contenteditable: "true",
942
+ ref_key: "editorRef",
943
+ ref: _,
944
+ key: V.value,
945
+ class: "editor",
946
+ style: ze(D.value),
947
+ onBeforeinput: Ke,
948
+ onCompositionstart: pe,
949
+ onCompositionend: He,
950
+ onKeydown: Ae
951
+ }, [
952
+ (S(!0), E(ye, null, xe(p.value, (o) => (S(), ee(Wt, Se({
953
+ key: `${o.id}-${o.type}`
954
+ }, { ref_for: !0 }, o), null, 16))), 128))
955
+ ], 36))
956
+ ]));
957
+ }
958
+ }), qt = /* @__PURE__ */ _e(Ut, [["__scopeId", "data-v-b5c1a845"]]), nt = (t, s) => {
959
+ if (!s.length)
960
+ return [{ text: t, isMatch: !1 }];
961
+ const a = [];
962
+ for (const h of s) {
963
+ if (!h) continue;
964
+ let v = 0;
965
+ const g = t.toLowerCase(), m = h.toLowerCase();
966
+ for (; ; ) {
967
+ const k = g.indexOf(m, v);
968
+ if (k === -1) break;
969
+ a.push({
970
+ start: k,
971
+ end: k + h.length
972
+ }), v = k + 1;
973
+ }
974
+ }
975
+ if (a.length === 0)
976
+ return [{ text: t, isMatch: !1 }];
977
+ a.sort((h, v) => h.start - v.start);
978
+ const r = [];
979
+ for (const h of a)
980
+ if (r.length === 0)
981
+ r.push(h);
982
+ else {
983
+ const v = r[r.length - 1];
984
+ h.start <= v.end ? v.end = Math.max(v.end, h.end) : r.push(h);
985
+ }
986
+ const f = [];
987
+ let I = 0;
988
+ for (const h of r)
989
+ I < h.start && f.push({
990
+ text: t.substring(I, h.start),
991
+ isMatch: !1
992
+ }), f.push({
993
+ text: t.substring(h.start, h.end),
994
+ isMatch: !0
995
+ }), I = h.end;
996
+ return I < t.length && f.push({
997
+ text: t.substring(I),
998
+ isMatch: !1
999
+ }), f;
1000
+ }, Gt = (t, s) => !s || !t ? [{ text: t, isMatch: !1 }] : nt(t, [s]), jt = (t, s) => {
1001
+ const { content: a, highlights: r } = t;
1002
+ return typeof r == "function" ? r(a, s) : Array.isArray(r) ? nt(a, r) : Gt(a, s);
1003
+ }, Jt = ["onMouseenter", "onMousedown"], Xt = { class: "suggestion-list__text" }, Yt = /* @__PURE__ */ Ce({
1004
+ __name: "SuggestionList",
1005
+ props: {
1006
+ show: { type: Boolean },
1007
+ suggestions: {},
1008
+ popupStyle: {},
1009
+ activeKeyboardIndex: {},
1010
+ activeMouseIndex: {},
1011
+ inputValue: {}
1012
+ },
1013
+ emits: ["select", "mouse-enter", "mouse-leave"],
1014
+ setup(t, { emit: s }) {
1015
+ const a = t, r = s, f = H(null), I = (m) => m === a.activeKeyboardIndex || m === a.activeMouseIndex, h = (m) => {
1016
+ r("mouse-enter", m);
1017
+ }, v = () => {
1018
+ r("mouse-leave");
1019
+ }, g = (m) => {
1020
+ r("select", m);
1021
+ };
1022
+ return ne(
1023
+ () => a.activeKeyboardIndex,
1024
+ (m) => {
1025
+ if (m !== -1 && f.value) {
1026
+ const k = f.value.children[m];
1027
+ k && k.scrollIntoView({ block: "nearest" });
1028
+ }
1029
+ }
1030
+ ), (m, k) => (S(), ee(Ne, { name: "tiny-sender-slide-up" }, {
1031
+ default: ve(() => [
1032
+ a.show && a.suggestions.length ? (S(), E("div", {
1033
+ key: 0,
1034
+ ref_key: "suggestionsListRef",
1035
+ ref: f,
1036
+ class: "suggestion-list",
1037
+ style: ze(a.popupStyle)
1038
+ }, [
1039
+ (S(!0), E(ye, null, xe(a.suggestions, (w, L) => (S(), E("div", {
1040
+ key: L,
1041
+ class: oe(["suggestion-list__item", { highlighted: I(L) }]),
1042
+ onMouseenter: (F) => h(L),
1043
+ onMouseleave: v,
1044
+ onMousedown: gt((F) => g(w.content), ["prevent"])
1045
+ }, [
1046
+ Y(R(Tt), { class: "suggestion-list__icon" }),
1047
+ z("span", Xt, [
1048
+ (S(!0), E(ye, null, xe(R(jt)(w, a.inputValue), (F, V) => (S(), E("span", {
1049
+ key: V,
1050
+ class: oe({
1051
+ "suggestion-list__text--match": F.isMatch,
1052
+ "suggestion-list__text--normal": !F.isMatch
1053
+ })
1054
+ }, de(F.text), 3))), 128))
1055
+ ])
1056
+ ], 42, Jt))), 128))
1057
+ ], 4)) : M("", !0)
1058
+ ]),
1059
+ _: 1
1060
+ }));
1061
+ }
1062
+ }), Zt = /* @__PURE__ */ _e(Yt, [["__scopeId", "data-v-e0ec9fe3"]]), Qt = ["data-theme"], en = { class: "tiny-sender__container" }, tn = {
1063
+ key: 0,
1064
+ class: "tiny-sender__header-slot"
1065
+ }, nn = {
1066
+ key: 0,
1067
+ class: "tiny-sender__prefix-slot"
1068
+ }, on = { class: "tiny-sender__content-area" }, sn = {
1069
+ key: 0,
1070
+ class: "tiny-sender__decorative-content"
1071
+ }, an = {
1072
+ key: 2,
1073
+ class: "tiny-sender__input-field-wrapper"
1074
+ }, ln = {
1075
+ key: 0,
1076
+ class: "tiny-sender__completion-placeholder"
1077
+ }, rn = { class: "user-input-mirror" }, cn = {
1078
+ key: 0,
1079
+ class: "tiny-sender__tab-hint"
1080
+ }, un = {
1081
+ key: 1,
1082
+ class: "tiny-sender__actions-slot"
1083
+ }, dn = {
1084
+ key: 0,
1085
+ class: "tiny-sender__footer-slot tiny-sender__bottom-row"
1086
+ }, fn = { class: "tiny-sender__footer-left" }, pn = { class: "tiny-sender__footer-right" }, hn = { class: "real-word-length" }, vn = {
1087
+ key: 1,
1088
+ class: "tiny-sender__toolbar"
1089
+ }, yn = { class: "tiny-sender__buttons-container" }, gn = {
1090
+ key: 1,
1091
+ class: "tiny-sender__footer-slot"
1092
+ }, mn = /* @__PURE__ */ Ce({
1093
+ __name: "index",
1094
+ props: {
1095
+ autofocus: { type: Boolean, default: !1 },
1096
+ autoSize: { type: [Boolean, Object], default: () => ({ minRows: 1, maxRows: 3 }) },
1097
+ allowSpeech: { type: Boolean, default: !0 },
1098
+ allowFiles: { type: Boolean, default: !1 },
1099
+ clearable: { type: Boolean, default: !1 },
1100
+ disabled: { type: Boolean, default: !1 },
1101
+ defaultValue: {},
1102
+ loading: { type: Boolean, default: !1 },
1103
+ modelValue: { default: "" },
1104
+ mode: { default: "single" },
1105
+ maxLength: { default: 1 / 0 },
1106
+ buttonGroup: {},
1107
+ submitType: { default: "enter" },
1108
+ speech: { type: [Boolean, Object] },
1109
+ placeholder: { default: "请输入内容..." },
1110
+ showWordLimit: { type: Boolean, default: !1 },
1111
+ suggestions: { default: () => [] },
1112
+ suggestionPopupWidth: { default: 400 },
1113
+ activeSuggestionKeys: {},
1114
+ theme: { default: "light" },
1115
+ templateData: { default: () => [] },
1116
+ stopText: { default: "" }
1117
+ },
1118
+ emits: ["update:modelValue", "update:templateData", "submit", "clear", "speech-start", "speech-end", "speech-interim", "speech-error", "suggestion-select", "focus", "blur", "escape-press", "cancel", "reset-template", "files-selected"],
1119
+ setup(t, { expose: s, emit: a }) {
1120
+ var O;
1121
+ const r = t, f = a, I = H(null), h = H(null), v = H(null), g = H(null), m = H(null), k = B(() => r.templateData && r.templateData.length > 0), { inputValue: w, isComposing: L, clearInput: F } = Ot(r, f), V = B(() => !!w.value.trim()), P = B(() => {
1122
+ var i, u;
1123
+ return !(r.disabled || r.loading || !V.value || ie.value || (u = (i = r.buttonGroup) == null ? void 0 : i.submit) != null && u.disabled);
1124
+ }), {
1125
+ isPopupVisible: W,
1126
+ activeSuggestion: $,
1127
+ activeKeyboardIndex: N,
1128
+ activeMouseIndex: C,
1129
+ autoCompleteText: x,
1130
+ showTabIndicator: p,
1131
+ syncAutoComplete: _,
1132
+ closePopup: U,
1133
+ applySuggestion: Z,
1134
+ confirmSelection: D,
1135
+ navigateWithKeyboard: J,
1136
+ handleMouseEnter: q,
1137
+ handleMouseLeave: ke
1138
+ } = Lt(
1139
+ B(() => r.suggestions),
1140
+ w,
1141
+ L,
1142
+ k,
1143
+ (i) => f("update:modelValue", i),
1144
+ (i) => f("suggestion-select", i)
1145
+ ), K = H(r.mode), A = H(!1), ge = () => {
1146
+ K.value === "single" && (K.value = "multiple", j(() => {
1147
+ setTimeout(() => {
1148
+ const i = document.querySelector(".tiny-textarea__inner");
1149
+ if (i) {
1150
+ i.style.whiteSpace = "pre-wrap";
1151
+ const u = w.value.length;
1152
+ i.focus(), i.setSelectionRange(u, u);
1153
+ }
1154
+ }, 50);
1155
+ }));
1156
+ }, fe = (i, u) => {
1157
+ const y = document.createElement("span");
1158
+ y.style.visibility = "hidden", y.style.position = "absolute", y.style.whiteSpace = "nowrap", y.style.font = u, y.textContent = i, document.body.appendChild(y);
1159
+ const T = y.offsetWidth;
1160
+ return document.body.removeChild(y), T;
1161
+ }, le = () => {
1162
+ var $e, je, Je;
1163
+ if (r.mode !== "single" || !I.value || A.value || !h.value || !g.value) return;
1164
+ const i = h.value.querySelector(".tiny-sender__content-area");
1165
+ if (!i) return;
1166
+ const u = ((je = ($e = I.value) == null ? void 0 : $e.querySelector) == null ? void 0 : je.call($e, ".tiny-input__inner")) || i.querySelector(".tiny-input__inner"), y = m.value || h.value.querySelector(".tiny-sender__buttons-container");
1167
+ if (!u) {
1168
+ console.warn("Cannot find input element for overflow check");
1169
+ return;
1170
+ }
1171
+ const T = u.getBoundingClientRect(), G = y == null ? void 0 : y.getBoundingClientRect();
1172
+ if (T.width === 0) {
1173
+ setTimeout(() => le(), 50);
1174
+ return;
1175
+ }
1176
+ const ue = window.getComputedStyle(u).font, ot = fe(w.value, ue), qe = (Je = h.value) == null ? void 0 : Je.classList.contains("tr-sender-compact"), st = qe ? 12 : 20, it = T.width, at = (G == null ? void 0 : G.width) || 0, Ge = it - at - st, lt = qe ? 50 : 80;
1177
+ ot > Ge && Ge > lt && K.value === "single" && (A.value = !0, K.value = "multiple", j(() => {
1178
+ I.value ? setTimeout(() => {
1179
+ var Xe;
1180
+ const Be = (Xe = h.value) == null ? void 0 : Xe.querySelector(".tiny-textarea__inner");
1181
+ if (Be) {
1182
+ Be.style.whiteSpace = "pre-wrap";
1183
+ const Ye = w.value.length;
1184
+ Be.focus(), Be.setSelectionRange(Ye, Ye);
1185
+ }
1186
+ A.value = !1;
1187
+ }, 300) : A.value = !1;
1188
+ }));
1189
+ }, me = () => {
1190
+ if (k.value && v.value)
1191
+ n();
1192
+ else if (I.value)
1193
+ I.value.focus();
1194
+ else {
1195
+ const i = document.querySelector(".tiny-input__inner");
1196
+ i == null || i.focus();
1197
+ }
1198
+ }, te = () => {
1199
+ if (I.value)
1200
+ I.value.blur();
1201
+ else {
1202
+ const i = document.querySelector(".tiny-input__inner");
1203
+ i == null || i.blur();
1204
+ }
1205
+ }, re = () => {
1206
+ var i;
1207
+ f("update:templateData", []), (i = v.value) == null || i.clearHistory(), j(() => {
1208
+ w.value === "" && (K.value = r.mode || "single"), setTimeout(() => {
1209
+ me();
1210
+ }, 50);
1211
+ });
1212
+ }, Q = () => {
1213
+ var i;
1214
+ F(), k.value ? re() : (i = h.value) == null || i.focus(), j(() => {
1215
+ w.value === "" && (K.value = r.mode || "single");
1216
+ });
1217
+ }, Ke = (i) => {
1218
+ const u = (T) => T.type === "text" && T.content === "​";
1219
+ if (i.length === 0 || i.every(u)) {
1220
+ re();
1221
+ return;
1222
+ }
1223
+ f("update:templateData", i);
1224
+ };
1225
+ ne(
1226
+ () => r.templateData,
1227
+ () => {
1228
+ w.value = r.templateData.map((i) => i.content).join("");
1229
+ },
1230
+ { deep: !0 }
1231
+ );
1232
+ const X = B(() => {
1233
+ const i = typeof r.speech == "object" ? r.speech : {};
1234
+ return {
1235
+ ...i,
1236
+ onStart: () => f("speech-start"),
1237
+ onEnd: (u) => f("speech-end", u),
1238
+ onInterim: (u) => f("speech-interim", u),
1239
+ onFinal: (u) => {
1240
+ if (i.autoReplace)
1241
+ w.value = u;
1242
+ else {
1243
+ const y = w.value;
1244
+ y && u && !y.endsWith(" ") && !u.startsWith(" ") && y.length > 0 ? w.value = y + " " + u : w.value = y + u;
1245
+ }
1246
+ f("speech-end", u);
1247
+ },
1248
+ onError: (u) => {
1249
+ f("speech-error", u);
1250
+ }
1251
+ };
1252
+ }), { speechState: se, start: we, stop: Ie } = Bt(X.value), Re = () => {
1253
+ se.isRecording ? Ie() : we();
1254
+ }, Te = async () => {
1255
+ const i = typeof r.speech == "object" ? r.speech : {}, u = se.isRecording;
1256
+ if (i.onVoiceButtonClick) {
1257
+ let y = !1;
1258
+ try {
1259
+ await i.onVoiceButtonClick(u, () => {
1260
+ y = !0;
1261
+ });
1262
+ } catch (T) {
1263
+ console.error("语音按钮点击拦截器执行失败:", T);
1264
+ }
1265
+ if (y)
1266
+ return;
1267
+ }
1268
+ Re();
1269
+ }, ie = B(() => r.maxLength !== 1 / 0 && w.value.length > r.maxLength), { handleKeyPress: be, triggerSubmit: pe } = $t(
1270
+ r,
1271
+ f,
1272
+ w,
1273
+ L,
1274
+ se,
1275
+ W,
1276
+ $,
1277
+ D,
1278
+ U,
1279
+ J,
1280
+ Re,
1281
+ P,
1282
+ K,
1283
+ ge,
1284
+ k,
1285
+ re
1286
+ ), He = (i) => {
1287
+ f("focus", i), w.value && !k.value && (W.value = !0);
1288
+ }, Ue = (i) => {
1289
+ f("blur", i), U();
1290
+ }, he = B(() => K.value === "multiple" ? "textarea" : "text"), Ae = mt(), Ee = B(() => !!Ae.decorativeContent), ce = B(() => r.disabled || Ee.value), Ve = B(() => r.loading), Fe = B(() => ({
1291
+ "is-disabled": ce.value,
1292
+ "is-loading": Ve.value,
1293
+ "is-auto-switching": A.value
1294
+ })), Oe = B(() => ({
1295
+ width: Et(r.suggestionPopupWidth),
1296
+ maxWidth: "100%"
1297
+ // 确保不超出父容器宽度
1298
+ })), e = () => {
1299
+ L.value = !1;
1300
+ };
1301
+ ne(w, () => {
1302
+ j(le), w.value === "" && r.mode === "single" && (K.value = "single"), _();
1303
+ }), ne(
1304
+ () => k.value,
1305
+ (i) => {
1306
+ i && (K.value = "multiple");
1307
+ }
1308
+ );
1309
+ const n = () => {
1310
+ v.value && v.value.activateFirstField();
1311
+ }, { accept: o = "*", multiple: c = !0, reset: l = !0 } = ((O = r.buttonGroup) == null ? void 0 : O.file) || {}, { open: d, files: b } = St({ accept: o, multiple: c, reset: l });
1312
+ return ne(b, (i) => {
1313
+ i && i.length > 0 && f("files-selected", Array.from(i));
1314
+ }), s({
1315
+ focus: me,
1316
+ blur: te,
1317
+ clear: Q,
1318
+ submit: pe,
1319
+ startSpeech: we,
1320
+ stopSpeech: Ie,
1321
+ activateTemplateFirstField: n
1322
+ }), (i, u) => (S(), E("div", {
1323
+ ref_key: "senderRef",
1324
+ ref: h,
1325
+ class: oe(["tiny-sender", [Fe.value, `theme-${t.theme}`, `mode-${K.value}`]]),
1326
+ "data-theme": t.theme
1327
+ }, [
1328
+ z("div", en, [
1329
+ z("div", {
1330
+ class: "tiny-sender__input-wrapper",
1331
+ ref_key: "inputWrapperRef",
1332
+ ref: g
1333
+ }, [
1334
+ Y(Ne, { name: "tiny-sender-slide-down" }, {
1335
+ default: ve(() => [
1336
+ i.$slots.header ? (S(), E("div", tn, [
1337
+ ae(i.$slots, "header", {}, void 0, !0)
1338
+ ])) : M("", !0)
1339
+ ]),
1340
+ _: 3
1341
+ }),
1342
+ z("div", {
1343
+ class: oe(["tiny-sender__input-row", { "has-prefix": i.$slots.prefix, "has-header": i.$slots.header }])
1344
+ }, [
1345
+ i.$slots.prefix ? (S(), E("div", nn, [
1346
+ ae(i.$slots, "prefix", {}, void 0, !0)
1347
+ ])) : M("", !0),
1348
+ z("div", on, [
1349
+ ae(i.$slots, "content", {}, () => [
1350
+ i.$slots.decorativeContent ? (S(), E("div", sn, [
1351
+ ae(i.$slots, "decorativeContent", {}, void 0, !0)
1352
+ ])) : M("", !0),
1353
+ k.value ? (S(), ee(qt, {
1354
+ key: 1,
1355
+ ref_key: "templateEditorRef",
1356
+ ref: v,
1357
+ "model-value": r.templateData,
1358
+ "auto-size": t.autoSize,
1359
+ "onUpdate:modelValue": Ke,
1360
+ onSubmit: R(pe)
1361
+ }, null, 8, ["model-value", "auto-size", "onSubmit"])) : (S(), E("div", an, [
1362
+ Y(R(bt), {
1363
+ ref_key: "inputRef",
1364
+ ref: I,
1365
+ autosize: t.autoSize,
1366
+ type: he.value,
1367
+ resize: "none",
1368
+ modelValue: R(w),
1369
+ "onUpdate:modelValue": u[0] || (u[0] = (y) => wt(w) ? w.value = y : null),
1370
+ disabled: ce.value,
1371
+ placeholder: t.placeholder,
1372
+ autofocus: t.autofocus,
1373
+ onKeydown: R(be),
1374
+ onCompositionstart: u[1] || (u[1] = (y) => L.value = !0),
1375
+ onCompositionend: e,
1376
+ onFocus: He,
1377
+ onBlur: Ue
1378
+ }, null, 8, ["autosize", "type", "modelValue", "disabled", "placeholder", "autofocus", "onKeydown"]),
1379
+ R(x) && !R(L) ? (S(), E("div", ln, [
1380
+ z("span", rn, de(R(w)), 1),
1381
+ Qe(" " + de(R(x)) + " ", 1),
1382
+ R(p) ? (S(), E("div", cn, "TAB")) : M("", !0)
1383
+ ])) : M("", !0)
1384
+ ]))
1385
+ ], !0)
1386
+ ]),
1387
+ K.value === "single" ? (S(), E("div", un, [
1388
+ z("div", {
1389
+ class: "tiny-sender__buttons-container",
1390
+ ref_key: "buttonsContainerRef",
1391
+ ref: m
1392
+ }, [
1393
+ ae(i.$slots, "actions", {}, void 0, !0),
1394
+ Y(et, {
1395
+ "allow-speech": t.allowSpeech,
1396
+ "allow-files": t.allowFiles,
1397
+ loading: t.loading,
1398
+ disabled: ce.value,
1399
+ "show-clear": t.clearable,
1400
+ "has-content": V.value,
1401
+ "speech-status": R(se),
1402
+ "button-group": t.buttonGroup,
1403
+ "submit-type": t.submitType,
1404
+ "is-over-limit": ie.value,
1405
+ "stop-text": t.stopText,
1406
+ onClear: Q,
1407
+ onVoiceButtonClick: Te,
1408
+ onSubmit: R(pe),
1409
+ onCancel: u[2] || (u[2] = (y) => i.$emit("cancel")),
1410
+ onTriggerSelect: R(d)
1411
+ }, null, 8, ["allow-speech", "allow-files", "loading", "disabled", "show-clear", "has-content", "speech-status", "button-group", "submit-type", "is-over-limit", "stop-text", "onSubmit", "onTriggerSelect"])
1412
+ ], 512)
1413
+ ])) : M("", !0)
1414
+ ], 2),
1415
+ Y(Ne, { name: "tiny-sender-slide-up" }, {
1416
+ default: ve(() => [
1417
+ K.value === "multiple" ? (S(), E("div", dn, [
1418
+ z("div", fn, [
1419
+ ae(i.$slots, "footer-left", {}, void 0, !0)
1420
+ ]),
1421
+ z("div", pn, [
1422
+ ae(i.$slots, "footer-right", {}, void 0, !0),
1423
+ t.showWordLimit && t.maxLength !== 1 / 0 ? (S(), E("div", {
1424
+ key: 0,
1425
+ class: oe(["tiny-sender__word-limit", { "is-over-limit": ie.value }])
1426
+ }, [
1427
+ z("span", hn, de(R(w).length), 1),
1428
+ Qe("/" + de(t.maxLength), 1)
1429
+ ], 2)) : M("", !0),
1430
+ K.value === "multiple" ? (S(), E("div", vn, [
1431
+ z("div", yn, [
1432
+ Y(et, {
1433
+ "allow-speech": t.allowSpeech,
1434
+ "allow-files": t.allowFiles,
1435
+ loading: t.loading,
1436
+ disabled: ce.value,
1437
+ "show-clear": t.clearable,
1438
+ "has-content": V.value,
1439
+ "speech-status": R(se),
1440
+ "button-group": t.buttonGroup,
1441
+ "submit-type": t.submitType,
1442
+ "is-over-limit": ie.value,
1443
+ "stop-text": t.stopText,
1444
+ onClear: Q,
1445
+ onVoiceButtonClick: Te,
1446
+ onSubmit: R(pe),
1447
+ onCancel: u[3] || (u[3] = (y) => i.$emit("cancel")),
1448
+ onTriggerSelect: R(d)
1449
+ }, null, 8, ["allow-speech", "allow-files", "loading", "disabled", "show-clear", "has-content", "speech-status", "button-group", "submit-type", "is-over-limit", "stop-text", "onSubmit", "onTriggerSelect"])
1450
+ ])
1451
+ ])) : M("", !0)
1452
+ ])
1453
+ ])) : i.$slots.footer ? (S(), E("div", gn, [
1454
+ ae(i.$slots, "footer", {}, void 0, !0)
1455
+ ])) : M("", !0)
1456
+ ]),
1457
+ _: 3
1458
+ })
1459
+ ], 512)
1460
+ ]),
1461
+ Y(Zt, {
1462
+ show: R(W),
1463
+ suggestions: t.suggestions,
1464
+ "popup-style": Oe.value,
1465
+ "active-keyboard-index": R(N),
1466
+ "active-mouse-index": R(C),
1467
+ "input-value": R(w),
1468
+ onSelect: R(Z),
1469
+ onMouseEnter: R(q),
1470
+ onMouseLeave: R(ke)
1471
+ }, null, 8, ["show", "suggestions", "popup-style", "active-keyboard-index", "active-mouse-index", "input-value", "onSelect", "onMouseEnter", "onMouseLeave"])
1472
+ ], 10, Qt));
1473
+ }
1474
+ }), De = /* @__PURE__ */ _e(mn, [["__scopeId", "data-v-d9951f51"]]);
1475
+ De.name = "TrSender";
1476
+ const wn = function(t) {
1477
+ t.component(De.name, De);
1478
+ };
1479
+ De.install = wn;
5
1480
  export {
6
- r as default,
7
- a as useSenderContext
1481
+ De as default
8
1482
  };