dsh-notify-yimit 0.1.4 → 0.1.6
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/lib/client.js +5 -13
- package/lib/index.js +108 -34
- package/lib/toast-host.ps1 +782 -560
- package/lib/typert.host.js +1 -0
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -40,8 +40,6 @@ window.__ModuleLoader__.load({
|
|
|
40
40
|
'.dn-seg{display:flex;gap:2px;padding:2px;border-radius:10px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);max-width:520px}',
|
|
41
41
|
'.dn-seg-btn{flex:1;font:inherit;font-size:13px;color:var(--dsw-alias-label-secondary);border:0;border-radius:8px;padding:6px 10px;cursor:pointer;background:transparent;transition:background .15s ease,color .15s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
|
42
42
|
'.dn-seg-btn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}',
|
|
43
|
-
// 选中态用主题主色 + 反色文字:浅色模式下与背景对比也足够清晰(此前浅色下
|
|
44
|
-
// 白底+深灰与容器太接近,深色正常)。
|
|
45
43
|
'.dn-seg-btn[data-on="true"]{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-inverted);box-shadow:var(--dsw-shadow-lv1)}',
|
|
46
44
|
'.dn-seg-btn[data-on="true"]:hover{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-inverted)}',
|
|
47
45
|
'.dn-seg-btn:disabled{opacity:.45;cursor:not-allowed}',
|
|
@@ -52,17 +50,13 @@ window.__ModuleLoader__.load({
|
|
|
52
50
|
'.dn-collapse>.dn-collapse-body>.dn-block{min-width:0}',
|
|
53
51
|
'.dn-kind-list{display:flex;flex-direction:column;gap:8px}',
|
|
54
52
|
'.dn-kind-row{display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-1)}',
|
|
55
|
-
// 每类型的背景/文字/开关项右对齐(预览块留在左侧)
|
|
56
53
|
'.dn-kind-row>.dn-kind-field:first-of-type{margin-left:auto}',
|
|
57
|
-
// 样式预览:纯色块内嵌类型文字,始终用配置的背景/文字色(内联样式,不受主题影响)
|
|
58
54
|
'.dn-kind-preview{flex:none;min-width:72px;text-align:center;font-size:12px;font-weight:600;line-height:22px;padding:2px 10px;border-radius:6px;white-space:nowrap;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}',
|
|
59
55
|
'.dn-kind-field{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--dsw-alias-label-tertiary);flex:none}',
|
|
60
56
|
'.dn-input{font:inherit;font-size:13px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:5px 10px;outline:none;max-width:120px}',
|
|
61
57
|
'.dn-input:focus{border-color:var(--dsw-alias-state-business-primary)}',
|
|
62
58
|
'.dn-input[type=color]{padding:2px 4px;width:48px;height:28px;cursor:pointer;max-width:none}',
|
|
63
59
|
'.dn-input:disabled{opacity:.45;cursor:not-allowed}',
|
|
64
|
-
// 浏览器选择器:原生 select 的展开列表为系统绘制、无法贴合主题,改为自绘下拉,
|
|
65
|
-
// 触发器与弹层都走 --dsw-* 变量,深浅色模式下与设置页风格一致。
|
|
66
60
|
'.dn-bselect{position:relative;width:280px;max-width:100%;flex:none}',
|
|
67
61
|
'.dn-bselect-trigger{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font:inherit;font-size:13px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:5px 10px;cursor:pointer;outline:none}',
|
|
68
62
|
'.dn-bselect-trigger:hover:not(:disabled){border-color:var(--dsw-alias-border-l2)}',
|
|
@@ -577,11 +571,8 @@ window.__ModuleLoader__.load({
|
|
|
577
571
|
}
|
|
578
572
|
|
|
579
573
|
if (config.mode === 'custom') {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
ack();
|
|
583
|
-
return
|
|
584
|
-
}
|
|
574
|
+
ack();
|
|
575
|
+
return
|
|
585
576
|
} else if (config.mode === 'system') {
|
|
586
577
|
if (typeof Notification === 'undefined' || Notification.permission ===
|
|
587
578
|
'denied') {
|
|
@@ -801,7 +792,8 @@ window.__ModuleLoader__.load({
|
|
|
801
792
|
const controlsDisabled = !config.enabled
|
|
802
793
|
|
|
803
794
|
const kindRows = KIND_ORDER.map((kind) => {
|
|
804
|
-
|
|
795
|
+
// 修正:去掉 `?.` 和 `[kind]` 之间的空格
|
|
796
|
+
const entry = config.colors?.[kind] ?? {}
|
|
805
797
|
const bg = entry.bg || config.bgColor || '#20272f'
|
|
806
798
|
const fg = entry.fg || config.textColor || '#e6edf3'
|
|
807
799
|
const enabled = entry.enabled !== false
|
|
@@ -1366,4 +1358,4 @@ window.__ModuleLoader__.load({
|
|
|
1366
1358
|
exports.inject = inject
|
|
1367
1359
|
return module.exports
|
|
1368
1360
|
},
|
|
1369
|
-
})
|
|
1361
|
+
})
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* dsh-notify-yimit-yimit 宿主插件。
|
|
3
|
-
* 优化点:内存LRU控制、队列头指针优化、浏览器探测缓存、宿主崩溃退避、全面多语言支持。
|
|
4
|
-
*/
|
|
5
1
|
import {
|
|
6
2
|
z
|
|
7
3
|
} from 'zod'
|
|
@@ -30,39 +26,42 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
30
26
|
bgColor: '#20272f',
|
|
31
27
|
textColor: '#e6edf3',
|
|
32
28
|
locale: 'en',
|
|
33
|
-
// 通知窗口样式:width 窗口宽度(编辑模式拖拽边缘调整);gap 通知间距(px);
|
|
34
|
-
// position = null 表示默认右下贴边,{left,top} 为任意屏幕位置(工作区相对坐标)。
|
|
35
29
|
toast: {
|
|
36
30
|
width: 340,
|
|
37
31
|
gap: 12,
|
|
38
|
-
position: null
|
|
32
|
+
position: null
|
|
39
33
|
},
|
|
40
34
|
colors: {
|
|
41
35
|
completed: {
|
|
42
36
|
bg: '#1f5138',
|
|
43
37
|
fg: '#e6f4ec',
|
|
38
|
+
accent: '#34d399',
|
|
44
39
|
enabled: true
|
|
45
|
-
},
|
|
40
|
+
}, // 翠绿
|
|
46
41
|
error: {
|
|
47
42
|
bg: '#5c1f24',
|
|
48
43
|
fg: '#fbe9ea',
|
|
44
|
+
accent: '#f87171',
|
|
49
45
|
enabled: true
|
|
50
|
-
},
|
|
46
|
+
}, // 珊瑚红
|
|
51
47
|
running: {
|
|
52
48
|
bg: '#203a5c',
|
|
53
49
|
fg: '#e8f0fb',
|
|
50
|
+
accent: '#60a5fa',
|
|
54
51
|
enabled: true
|
|
55
|
-
},
|
|
52
|
+
}, // 天蓝
|
|
56
53
|
approval: {
|
|
57
54
|
bg: '#4a3a12',
|
|
58
55
|
fg: '#f7efd8',
|
|
56
|
+
accent: '#fbbf24',
|
|
59
57
|
enabled: true
|
|
60
|
-
},
|
|
58
|
+
}, // 琥珀
|
|
61
59
|
question: {
|
|
62
60
|
bg: '#3d2a55',
|
|
63
61
|
fg: '#f0e8fa',
|
|
62
|
+
accent: '#a78bfa',
|
|
64
63
|
enabled: true
|
|
65
|
-
},
|
|
64
|
+
}, // 雾紫
|
|
66
65
|
},
|
|
67
66
|
})
|
|
68
67
|
|
|
@@ -137,7 +136,11 @@ function normalizeConfig(input) {
|
|
|
137
136
|
if (src.locale === 'zh' || src.locale === 'en') out.locale = src.locale
|
|
138
137
|
|
|
139
138
|
// 通知窗口样式:width 260–520;gap 0–60;position 缺省 null(默认右下贴边),合法 {left,top} 才采纳。
|
|
140
|
-
out.toast = {
|
|
139
|
+
out.toast = {
|
|
140
|
+
width: 340,
|
|
141
|
+
gap: 12,
|
|
142
|
+
position: null
|
|
143
|
+
}
|
|
141
144
|
const srcToast = src.toast !== null && typeof src.toast === 'object' && !Array.isArray(src.toast) ? src.toast : {}
|
|
142
145
|
if (typeof srcToast.width === 'number' && Number.isFinite(srcToast.width)) {
|
|
143
146
|
out.toast.width = Math.max(260, Math.min(520, Math.round(srcToast.width)))
|
|
@@ -149,7 +152,10 @@ function normalizeConfig(input) {
|
|
|
149
152
|
if (pos !== null && typeof pos === 'object' && !Array.isArray(pos) &&
|
|
150
153
|
typeof pos.left === 'number' && Number.isFinite(pos.left) &&
|
|
151
154
|
typeof pos.top === 'number' && Number.isFinite(pos.top)) {
|
|
152
|
-
out.toast.position = {
|
|
155
|
+
out.toast.position = {
|
|
156
|
+
left: Math.round(pos.left),
|
|
157
|
+
top: Math.round(pos.top)
|
|
158
|
+
}
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
const srcColors = src.colors !== null && typeof src.colors === 'object' && !Array.isArray(src.colors) ? src.colors :
|
|
@@ -161,6 +167,7 @@ function normalizeConfig(input) {
|
|
|
161
167
|
out.colors[kind] = {
|
|
162
168
|
bg: isHex(entry?.bg) ? entry.bg : def.bg,
|
|
163
169
|
fg: isHex(entry?.fg) ? entry.fg : def.fg,
|
|
170
|
+
accent: isHex(entry?.accent) ? entry.accent : def.accent, // 新增
|
|
164
171
|
enabled: entry?.enabled !== false,
|
|
165
172
|
}
|
|
166
173
|
}
|
|
@@ -201,7 +208,8 @@ function mergeConfigPatch(base, patch) {
|
|
|
201
208
|
if (patch !== null && typeof patch === 'object' && patch.toast !== null && typeof patch.toast === 'object' && !
|
|
202
209
|
Array.isArray(patch.toast)) {
|
|
203
210
|
out.toast = {
|
|
204
|
-
...(base.toast !== null && typeof base.toast === 'object' && !Array.isArray(base.toast) ? base.toast :
|
|
211
|
+
...(base.toast !== null && typeof base.toast === 'object' && !Array.isArray(base.toast) ? base.toast :
|
|
212
|
+
{}),
|
|
205
213
|
...patch.toast
|
|
206
214
|
}
|
|
207
215
|
}
|
|
@@ -258,7 +266,8 @@ function openConfig() {
|
|
|
258
266
|
fs.writeFileSync(tmp, JSON.stringify(config, null, 2), 'utf8')
|
|
259
267
|
fs.renameSync(tmp, file)
|
|
260
268
|
} catch {
|
|
261
|
-
/* 静默 */
|
|
269
|
+
/* 静默 */
|
|
270
|
+
}
|
|
262
271
|
},
|
|
263
272
|
}
|
|
264
273
|
}
|
|
@@ -276,7 +285,11 @@ function clip(text) {
|
|
|
276
285
|
}
|
|
277
286
|
|
|
278
287
|
function titleOf(session) {
|
|
279
|
-
|
|
288
|
+
// 宿主兼容:0.1.2-alpha.4 起 `Session.events` 被 `snapshotEvents()` 取代(旧版仍有 .events)。
|
|
289
|
+
// 优先用 snapshotEvents()(无参返回全量冻结事件数组),旧宿主回退 .events。
|
|
290
|
+
const events = typeof session?.snapshotEvents === 'function'
|
|
291
|
+
? session.snapshotEvents()
|
|
292
|
+
: session?.events
|
|
280
293
|
if (Array.isArray(events)) {
|
|
281
294
|
// 全量扫描:标题事件通常在会话早期(seq 小)生成,长会话/恢复会话里它可能在
|
|
282
295
|
// 最后 50 条之外——只扫尾部会漏掉,导致回退到占位/目录名(恢复会话不会重放
|
|
@@ -489,7 +502,8 @@ export function apply(ctx) {
|
|
|
489
502
|
if (idx !== -1) toastOrder.splice(idx, 1)
|
|
490
503
|
reflowToasts()
|
|
491
504
|
}
|
|
492
|
-
} else if (msg.type === 'geometry' && typeof msg.left === 'number' && typeof msg.top ===
|
|
505
|
+
} else if (msg.type === 'geometry' && typeof msg.left === 'number' && typeof msg.top ===
|
|
506
|
+
'number') {
|
|
493
507
|
// 编辑模式:样板窗拖拽/缩放结束 → 写回配置,并应用到在屏浮窗。
|
|
494
508
|
const width = Math.max(260, Math.min(520, Math.round(Number(msg.width) || 340)))
|
|
495
509
|
const left = Math.round(Number(msg.left))
|
|
@@ -497,11 +511,18 @@ export function apply(ctx) {
|
|
|
497
511
|
store.set({
|
|
498
512
|
toast: {
|
|
499
513
|
width,
|
|
500
|
-
position: {
|
|
514
|
+
position: {
|
|
515
|
+
left,
|
|
516
|
+
top
|
|
517
|
+
}
|
|
501
518
|
}
|
|
502
519
|
})
|
|
503
520
|
for (const rec of activeToasts.values()) {
|
|
504
|
-
sendCmd({
|
|
521
|
+
sendCmd({
|
|
522
|
+
cmd: 'size',
|
|
523
|
+
key: rec.key,
|
|
524
|
+
width
|
|
525
|
+
})
|
|
505
526
|
}
|
|
506
527
|
reflowToasts()
|
|
507
528
|
}
|
|
@@ -585,9 +606,16 @@ export function apply(ctx) {
|
|
|
585
606
|
const needsTop = rec.meta !== null && newTop !== rec.meta.top
|
|
586
607
|
const needsLeft = rec.meta !== null && rec.meta.left !== pos.left
|
|
587
608
|
if (needsTop || needsLeft) {
|
|
588
|
-
const move = {
|
|
609
|
+
const move = {
|
|
610
|
+
cmd: 'move',
|
|
611
|
+
key: rec.key,
|
|
612
|
+
top: newTop
|
|
613
|
+
}
|
|
589
614
|
if (needsTop) rec.meta.top = newTop
|
|
590
|
-
if (needsLeft) {
|
|
615
|
+
if (needsLeft) {
|
|
616
|
+
move.left = pos.left;
|
|
617
|
+
rec.meta.left = pos.left
|
|
618
|
+
}
|
|
591
619
|
sendCmd(move)
|
|
592
620
|
}
|
|
593
621
|
prevTop = newTop
|
|
@@ -626,6 +654,23 @@ export function apply(ctx) {
|
|
|
626
654
|
return `http://127.0.0.1:${ws !== null && ws !== undefined && typeof ws.port === 'number' ? ws.port : 3080}`
|
|
627
655
|
}
|
|
628
656
|
|
|
657
|
+
const KIND_BADGES = {
|
|
658
|
+
zh: {
|
|
659
|
+
completed: '完成',
|
|
660
|
+
error: '出错',
|
|
661
|
+
running: '运行中',
|
|
662
|
+
approval: '待审批',
|
|
663
|
+
question: '待回答'
|
|
664
|
+
},
|
|
665
|
+
en: {
|
|
666
|
+
completed: 'Done',
|
|
667
|
+
error: 'Failed',
|
|
668
|
+
running: 'Running',
|
|
669
|
+
approval: 'Approval',
|
|
670
|
+
question: 'Question'
|
|
671
|
+
},
|
|
672
|
+
}
|
|
673
|
+
|
|
629
674
|
function showDesktopToast(cfg, ev) {
|
|
630
675
|
const maxVisible = Math.max(1, Math.min(20, Math.floor(Number(cfg.maxVisible) || 3)))
|
|
631
676
|
const stickyKind = ev.kind === 'running' || ev.kind === 'approval' || ev.kind === 'question'
|
|
@@ -691,6 +736,8 @@ export function apply(ctx) {
|
|
|
691
736
|
bg: colors?.bg ?? cfg.bgColor ?? '#20272f',
|
|
692
737
|
fg: colors?.fg ?? cfg.textColor ?? '#e6edf3',
|
|
693
738
|
durationSec: Math.max(1, Math.round((Number(cfg.durationMs) || 8000) / 1000)),
|
|
739
|
+
accent: colors?.accent ?? '#60a5fa', // 强调色
|
|
740
|
+
durationSec: Math.max(1, Math.round((Number(cfg.durationMs) || 8000) / 1000)),
|
|
694
741
|
sticky: stickyKind,
|
|
695
742
|
offsetY,
|
|
696
743
|
sessionId: String(ev.sessionId),
|
|
@@ -736,7 +783,11 @@ export function apply(ctx) {
|
|
|
736
783
|
if (typeof title !== 'string' || title.length === 0) return
|
|
737
784
|
for (const rec of activeToasts.values()) {
|
|
738
785
|
if (rec.sessionId === sessionId) {
|
|
739
|
-
sendCmd({
|
|
786
|
+
sendCmd({
|
|
787
|
+
cmd: 'title',
|
|
788
|
+
key: rec.key,
|
|
789
|
+
title
|
|
790
|
+
})
|
|
740
791
|
}
|
|
741
792
|
}
|
|
742
793
|
}
|
|
@@ -748,11 +799,13 @@ export function apply(ctx) {
|
|
|
748
799
|
cmd: 'shutdown'
|
|
749
800
|
})
|
|
750
801
|
} catch {
|
|
751
|
-
/* 忽略 */
|
|
802
|
+
/* 忽略 */
|
|
803
|
+
}
|
|
752
804
|
try {
|
|
753
805
|
host.kill()
|
|
754
806
|
} catch {
|
|
755
|
-
/* 已退出 */
|
|
807
|
+
/* 已退出 */
|
|
808
|
+
}
|
|
756
809
|
}
|
|
757
810
|
activeToasts.clear()
|
|
758
811
|
toastOrder.length = 0
|
|
@@ -768,7 +821,7 @@ export function apply(ctx) {
|
|
|
768
821
|
const at = Date.now()
|
|
769
822
|
const cfg = store.get()
|
|
770
823
|
// 每类型开关:该类型被关闭时完全不产生通知(桌面浮窗与系统通知都不发)。
|
|
771
|
-
if (cfg.colors?.[kind]?.enabled === false) return
|
|
824
|
+
if (cfg.colors?. [kind]?.enabled === false) return
|
|
772
825
|
const desktop = cfg.enabled === true && cfg.mode === 'custom'
|
|
773
826
|
const lang = cfg.locale === 'zh' ? 'zh' : 'en'
|
|
774
827
|
const l = TOAST_LABELS[lang]
|
|
@@ -878,7 +931,8 @@ export function apply(ctx) {
|
|
|
878
931
|
if (typeof event.data?.title === 'string' && event.data.title.length > 0) {
|
|
879
932
|
st.title = event.data.title
|
|
880
933
|
for (let i = queueHead; i < queue.length; i++) {
|
|
881
|
-
if (queue[i].sessionId === id && (queue[i].title.length === 0 || UNTITLED_NAMES.has(
|
|
934
|
+
if (queue[i].sessionId === id && (queue[i].title.length === 0 || UNTITLED_NAMES.has(
|
|
935
|
+
queue[i].title)))
|
|
882
936
|
queue[i].title = st.title
|
|
883
937
|
}
|
|
884
938
|
// 已弹浮窗(运行中/待审批/待回答等)标题原地更新,不再一直顶着占位/旧标题。
|
|
@@ -928,7 +982,8 @@ export function apply(ctx) {
|
|
|
928
982
|
push(id, 'question', first.question)
|
|
929
983
|
}
|
|
930
984
|
} catch {
|
|
931
|
-
/* arguments 非 JSON */
|
|
985
|
+
/* arguments 非 JSON */
|
|
986
|
+
}
|
|
932
987
|
}
|
|
933
988
|
return
|
|
934
989
|
}
|
|
@@ -1015,7 +1070,8 @@ export function apply(ctx) {
|
|
|
1015
1070
|
`${L.approvalPrefix} ${toolName}` : L.approvalFallback))
|
|
1016
1071
|
}
|
|
1017
1072
|
} catch {
|
|
1018
|
-
/* 观察失败不影响审批链路 */
|
|
1073
|
+
/* 观察失败不影响审批链路 */
|
|
1074
|
+
}
|
|
1019
1075
|
return next()
|
|
1020
1076
|
})
|
|
1021
1077
|
|
|
@@ -1032,11 +1088,16 @@ export function apply(ctx) {
|
|
|
1032
1088
|
const prev = store.get()
|
|
1033
1089
|
const next = store.set(patch)
|
|
1034
1090
|
// toast 几何(位置/宽度/间距)变更:立即应用到在屏浮窗,无需等待下一个浮窗。
|
|
1035
|
-
const pToast = patch !== null && typeof patch === 'object' && !Array.isArray(patch) ? patch.toast :
|
|
1091
|
+
const pToast = patch !== null && typeof patch === 'object' && !Array.isArray(patch) ? patch.toast :
|
|
1092
|
+
undefined
|
|
1036
1093
|
if (pToast !== null && typeof pToast === 'object' && !Array.isArray(pToast)) {
|
|
1037
1094
|
if (typeof pToast.width === 'number' && pToast.width !== prev.toast?.width) {
|
|
1038
1095
|
for (const rec of activeToasts.values()) {
|
|
1039
|
-
sendCmd({
|
|
1096
|
+
sendCmd({
|
|
1097
|
+
cmd: 'size',
|
|
1098
|
+
key: rec.key,
|
|
1099
|
+
width: next.toast.width
|
|
1100
|
+
})
|
|
1040
1101
|
}
|
|
1041
1102
|
}
|
|
1042
1103
|
reflowToasts()
|
|
@@ -1072,13 +1133,26 @@ export function apply(ctx) {
|
|
|
1072
1133
|
title: EDIT_TITLES[lang],
|
|
1073
1134
|
width: cfg.toast?.width ?? 340,
|
|
1074
1135
|
position: cfg.toast?.position ?? null,
|
|
1136
|
+
// 新增:类型色卡数组,样板窗内做预览
|
|
1137
|
+
chips: KIND_KEYS.map((k) => ({
|
|
1138
|
+
label: (KIND_BADGES[lang] ?? KIND_BADGES.en)[k],
|
|
1139
|
+
accent: cfg.colors[k].accent,
|
|
1140
|
+
bg: cfg.colors[k].bg,
|
|
1141
|
+
fg: cfg.colors[k].fg,
|
|
1142
|
+
})),
|
|
1075
1143
|
})
|
|
1076
|
-
return {
|
|
1144
|
+
return {
|
|
1145
|
+
ok: true
|
|
1146
|
+
}
|
|
1077
1147
|
},
|
|
1078
1148
|
/** 退出编辑模式:样板窗淡出消失。 */
|
|
1079
1149
|
endEditMode() {
|
|
1080
|
-
sendCmd({
|
|
1081
|
-
|
|
1150
|
+
sendCmd({
|
|
1151
|
+
cmd: 'edit-end'
|
|
1152
|
+
})
|
|
1153
|
+
return {
|
|
1154
|
+
ok: true
|
|
1155
|
+
}
|
|
1082
1156
|
},
|
|
1083
1157
|
}
|
|
1084
1158
|
|