@leavepulse/ui 0.45.1 → 0.47.0
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/assets/HighlightText-BwC5xbqn.css +6 -0
- package/dist/assets/{LpCommandPalette-HzAA4gri.css → LpCommandPalette-DmQUsJqA.css} +21 -21
- package/dist/assets/{LpDropzone-i4BdMi1H.css → LpDropzone-Ev6X03zj.css} +12 -12
- package/dist/assets/LpKeys-BxRhfQda.css +36 -0
- package/dist/assets/LpPaletteFacts-B9FdVmIO.css +93 -0
- package/dist/assets/LpPaletteHeader-BVOu1UX5.css +70 -0
- package/dist/assets/LpPalettePreview-CJmAKgYW.css +43 -0
- package/dist/assets/LpPaletteStats-ClE-37MK.css +33 -0
- package/dist/assets/LpPaletteSwatches-CA0B8y2E.css +21 -0
- package/dist/assets/{LpShortcutsDialog-CqYX3yy6.css → LpShortcutsDialog-BUp_BX4s.css} +7 -28
- package/dist/assets/{LpTable-CPwWxTJS.css → LpTable-xWwI4KPZ.css} +17 -17
- package/dist/chunks/HighlightText-BvnYZkhi.js +27 -0
- package/dist/chunks/{LpAddressInput-CJOYGZlI.js → LpAddressInput-iOJhmRzy.js} +1 -1
- package/dist/chunks/{LpAppShell-B07Lf48e.js → LpAppShell-BmMYcEVx.js} +2 -2
- package/dist/chunks/{LpAvatar-C1XStdOo.js → LpAvatar-Cb1jtOVv.js} +22 -4
- package/dist/chunks/{LpCard-C2IvucmX.js → LpCard-BdxkMXjo.js} +1 -1
- package/dist/chunks/{LpColorPicker-zz4VGkG4.js → LpColorPicker-BLqPX5Vw.js} +1 -1
- package/dist/chunks/{LpConfirmDialog-BTVAR4tF.js → LpConfirmDialog-Ca-CTlxT.js} +1 -1
- package/dist/chunks/{LpConfirmHost-Ci_uCHgQ.js → LpConfirmHost-BAaSaT2b.js} +1 -1
- package/dist/chunks/{LpContextMenu-BqkAYa9X.js → LpContextMenu-1cKew_Dc.js} +17 -4
- package/dist/chunks/{LpDrawer-CfRhHwmE.js → LpDrawer-CBFVD624.js} +1 -1
- package/dist/chunks/{LpDropdownMenu-DdJGQzPn.js → LpDropdownMenu-DrpJJBp0.js} +22 -8
- package/dist/chunks/{LpFileTree-CNurOvkV.js → LpFileTree-bk5VjBey.js} +2 -2
- package/dist/chunks/{LpFileTreeNode-D_qRRdsH.js → LpFileTreeNode-BvMSBM7X.js} +1 -1
- package/dist/chunks/{LpLightbox-DSDahF23.js → LpLightbox-EVXzAq62.js} +3 -3
- package/dist/chunks/{LpLogViewer-KypbgOyo.js → LpLogViewer-BDFXzvcl.js} +2 -2
- package/dist/chunks/{LpMediaGallery-YKr-cQPN.js → LpMediaGallery-BnlkN_1f.js} +1 -1
- package/dist/chunks/{LpModal-BzTVeNqe.js → LpModal-JNa3B_Lr.js} +12 -5
- package/dist/chunks/{LpModalNav-CjABSGCu.js → LpModalNav-BAxC9et7.js} +10 -3
- package/dist/chunks/{LpNotificationBell-CCwyJP5C.js → LpNotificationBell-DsqSyMwS.js} +2 -2
- package/dist/chunks/LpPalettePreview-CFav_7co.js +19 -0
- package/dist/chunks/{LpPie-BEJ2SfI6.js → LpPie-BdSnta11.js} +1 -1
- package/dist/chunks/{LpScrollArea-Bry1fdOM.js → LpScrollArea-Hz3-JWUG.js} +23 -5
- package/dist/chunks/{LpSidebar-Bwws_X29.js → LpSidebar-DpEiGi8L.js} +2 -2
- package/dist/chunks/{LpSidebarNav-kx-LdqNU.js → LpSidebarNav-BUuxipX-.js} +2 -2
- package/dist/chunks/{LpThemeSwitcher-B4aVPbNC.js → LpThemeSwitcher-BbYFFT5w.js} +1 -1
- package/dist/chunks/MenuTitle-J3ZDYjpV.js +56 -0
- package/dist/component-names.d.ts +1 -1
- package/dist/components/HighlightText.vue.d.ts +7 -0
- package/dist/components/HighlightText.vue.js +4 -0
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpAvatar.vue.d.ts +12 -0
- package/dist/components/LpAvatar.vue.js +1 -1
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.js +1 -1
- package/dist/components/LpColorPicker.vue.js +1 -1
- package/dist/components/LpCommandPalette.vue.d.ts +152 -15
- package/dist/components/LpCommandPalette.vue.js +181 -92
- package/dist/components/LpConfirmDialog.vue.js +1 -1
- package/dist/components/LpConfirmHost.vue.js +1 -1
- package/dist/components/LpContextMenu.vue.d.ts +11 -0
- package/dist/components/LpContextMenu.vue.js +1 -1
- package/dist/components/LpDrawer.vue.js +1 -1
- package/dist/components/LpDropdownMenu.vue.d.ts +6 -0
- package/dist/components/LpDropdownMenu.vue.js +1 -1
- package/dist/components/LpDropzone.vue.d.ts +14 -0
- package/dist/components/LpDropzone.vue.js +9 -7
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpKeys.vue.d.ts +22 -0
- package/dist/components/LpKeys.vue.js +52 -0
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMediaGallery.vue.js +1 -1
- package/dist/components/LpModal.vue.d.ts +7 -5
- package/dist/components/LpModal.vue.js +1 -1
- package/dist/components/LpModalNav.vue.d.ts +5 -3
- package/dist/components/LpModalNav.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpPaletteFacts.vue.d.ts +25 -0
- package/dist/components/LpPaletteFacts.vue.js +85 -0
- package/dist/components/LpPaletteHeader.vue.d.ts +32 -0
- package/dist/components/LpPaletteHeader.vue.js +103 -0
- package/dist/components/LpPalettePreview.vue.d.ts +19 -0
- package/dist/components/LpPalettePreview.vue.js +4 -0
- package/dist/components/LpPaletteStats.vue.d.ts +11 -0
- package/dist/components/LpPaletteStats.vue.js +47 -0
- package/dist/components/LpPaletteSwatches.vue.d.ts +10 -0
- package/dist/components/LpPaletteSwatches.vue.js +34 -0
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpScrollArea.vue.d.ts +2 -2
- package/dist/components/LpScrollArea.vue.js +1 -1
- package/dist/components/LpShortcutsDialog.vue.js +9 -29
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpTable.vue.js +8 -6
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/components/MenuTitle.vue.d.ts +9 -0
- package/dist/components/MenuTitle.vue.js +4 -0
- package/dist/components/commandPalette.d.ts +157 -0
- package/dist/components/commandPalette.js +103 -0
- package/dist/components/commandSearch.d.ts +32 -0
- package/dist/components/commandSearch.js +48 -0
- package/dist/components/keys.d.ts +2 -0
- package/dist/components/keys.js +11 -0
- package/dist/composables/useClipboard.js +35 -2
- package/dist/index.d.ts +12 -3
- package/dist/index.js +161 -138
- package/package.json +1 -1
- package/src/component-names.ts +6 -0
- package/src/components/HighlightText.vue +28 -0
- package/src/components/LpAvatar.vue +21 -2
- package/src/components/LpCommandPalette.vue +392 -86
- package/src/components/LpContextMenu.vue +19 -1
- package/src/components/LpDropdownMenu.vue +14 -2
- package/src/components/LpDropzone.vue +13 -5
- package/src/components/LpKeys.vue +79 -0
- package/src/components/LpLightbox.vue +4 -1
- package/src/components/LpModal.vue +7 -1
- package/src/components/LpModalNav.vue +4 -0
- package/src/components/LpPaletteFacts.vue +165 -0
- package/src/components/LpPaletteHeader.vue +155 -0
- package/src/components/LpPalettePreview.vue +77 -0
- package/src/components/LpPaletteStats.vue +81 -0
- package/src/components/LpPaletteSwatches.vue +56 -0
- package/src/components/LpScrollArea.vue +30 -2
- package/src/components/LpShortcutsDialog.vue +2 -45
- package/src/components/LpTable.vue +7 -2
- package/src/components/MenuTitle.vue +34 -0
- package/src/components/commandPalette.ts +264 -0
- package/src/components/commandSearch.ts +79 -0
- package/src/components/keys.ts +13 -0
- package/src/composables/useClipboard.ts +49 -7
- package/src/index.ts +12 -3
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { defineComponent, ref, useId, computed, shallowRef, watch, useSlots,
|
|
1
|
+
import { defineComponent, ref, useId, computed, shallowRef, watch, useSlots, onBeforeUnmount, nextTick, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, withModifiers, createTextVNode, toDisplayString, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, withDirectives, withKeys, vModelText, resolveDynamicComponent, Transition, renderSlot } from "vue";
|
|
2
2
|
import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
|
|
3
|
+
import { _ as _sfc_main$3 } from "../chunks/LpAvatar-Cb1jtOVv.js";
|
|
3
4
|
import { _ as _sfc_main$1 } from "../chunks/LpIcon-DYtaid0K.js";
|
|
4
|
-
import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-
|
|
5
|
+
import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-Hz3-JWUG.js";
|
|
5
6
|
import { useAsyncTask } from "../composables/useAsyncTask.js";
|
|
6
7
|
import { useGlass } from "../composables/useGlass.js";
|
|
7
8
|
import { useClipboard } from "../composables/useClipboard.js";
|
|
8
9
|
import { useHotkeys } from "../composables/useHotkeys.js";
|
|
9
10
|
import { useModalLayer } from "./modalDepth.js";
|
|
10
11
|
import { useLabels } from "../composables/useLpConfig.js";
|
|
11
|
-
import { parseCommandQuery, rankCommandItems } from "./commandSearch.js";
|
|
12
|
+
import { parseCommandQuery, rankCommandItems, applyQueryFilters, parsePaletteQuery, highlightParts } from "./commandSearch.js";
|
|
13
|
+
import { fallbackRows, readRecent, resolveRecentItems, recentVisible, commandHasPreview, matchModePrefix, modeChipLabel, toRecentItem, pushRecent } from "./commandPalette.js";
|
|
12
14
|
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
|
|
13
|
-
import '../assets/LpCommandPalette-
|
|
15
|
+
import '../assets/LpCommandPalette-DmQUsJqA.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
|
|
14
16
|
const _hoisted_2 = ["title", "onClick"];
|
|
15
17
|
const _hoisted_3 = ["aria-activedescendant", "placeholder", "onKeydown"];
|
|
16
18
|
const _hoisted_4 = { class: "shrink-0 rounded border border-line px-1.5 py-0.5 text-[10px] text-muted" };
|
|
@@ -39,37 +41,42 @@ const _hoisted_13 = {
|
|
|
39
41
|
class: "rounded-xs bg-brand/20 text-ink"
|
|
40
42
|
};
|
|
41
43
|
const _hoisted_14 = {
|
|
42
|
-
key:
|
|
44
|
+
key: 2,
|
|
43
45
|
class: "shrink-0 text-xs text-muted"
|
|
44
46
|
};
|
|
45
47
|
const _hoisted_15 = {
|
|
48
|
+
key: 3,
|
|
49
|
+
class: "shrink-0 rounded border border-line px-1.5 font-mono text-[11px] whitespace-pre text-muted"
|
|
50
|
+
};
|
|
51
|
+
const _hoisted_16 = {
|
|
46
52
|
key: 0,
|
|
47
53
|
class: "lp-cmd-pane hidden min-h-0 shrink-0 flex-col border-l border-line md:flex"
|
|
48
54
|
};
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
55
|
+
const _hoisted_17 = { class: "lp-cmd-para flex items-center gap-2 text-ink" };
|
|
56
|
+
const _hoisted_18 = { class: "min-w-0 text-base font-semibold" };
|
|
57
|
+
const _hoisted_19 = {
|
|
52
58
|
key: 0,
|
|
53
59
|
class: "lp-cmd-para mt-0.5 text-xs text-muted"
|
|
54
60
|
};
|
|
55
|
-
const
|
|
61
|
+
const _hoisted_20 = {
|
|
56
62
|
key: 0,
|
|
57
63
|
class: "rounded-xs bg-brand/25 text-ink"
|
|
58
64
|
};
|
|
59
|
-
const
|
|
60
|
-
const _hoisted_21 = { class: "flex items-center gap-1" };
|
|
65
|
+
const _hoisted_21 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted [@media(hover:none)_and_(pointer:coarse)]:hidden" };
|
|
61
66
|
const _hoisted_22 = { class: "flex items-center gap-1" };
|
|
62
|
-
const _hoisted_23 = {
|
|
67
|
+
const _hoisted_23 = { class: "flex items-center gap-1" };
|
|
68
|
+
const _hoisted_24 = {
|
|
63
69
|
key: 0,
|
|
64
70
|
class: "flex items-center gap-1"
|
|
65
71
|
};
|
|
66
|
-
const
|
|
72
|
+
const _hoisted_25 = {
|
|
67
73
|
key: 1,
|
|
68
74
|
class: "flex items-center gap-1"
|
|
69
75
|
};
|
|
70
|
-
const
|
|
71
|
-
const
|
|
76
|
+
const _hoisted_26 = { class: "ml-auto flex items-center gap-1" };
|
|
77
|
+
const _hoisted_27 = { class: "rounded border border-line px-1 text-[10px]" };
|
|
72
78
|
const RECENT_KEEP = 20;
|
|
79
|
+
const PANE_LINGER_MS = 160;
|
|
73
80
|
const STAGGER_MS = 45;
|
|
74
81
|
const STAGGER_MAX = 10;
|
|
75
82
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
@@ -85,6 +92,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
85
92
|
minChars: { default: 1 },
|
|
86
93
|
recent: {},
|
|
87
94
|
recentKey: {},
|
|
95
|
+
resolveRecent: {},
|
|
88
96
|
recentLimit: { default: 5 },
|
|
89
97
|
recentLabel: { default: "Recent" },
|
|
90
98
|
resultsLabel: { default: "Results" },
|
|
@@ -92,9 +100,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
92
100
|
excerptLines: { default: 4 },
|
|
93
101
|
groupLimit: { default: 0 },
|
|
94
102
|
previewPane: { type: Boolean, default: false },
|
|
103
|
+
hasPreview: {},
|
|
95
104
|
glass: { type: Boolean, default: void 0 }
|
|
96
105
|
},
|
|
97
|
-
emits: ["update:open", "select", "run"],
|
|
106
|
+
emits: ["update:open", "select", "run", "remember"],
|
|
98
107
|
setup(__props, { emit: __emit }) {
|
|
99
108
|
const props = __props;
|
|
100
109
|
const frosted = useGlass(() => props.glass);
|
|
@@ -165,7 +174,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
165
174
|
if (!c || !actions.length) return;
|
|
166
175
|
event.preventDefault();
|
|
167
176
|
event.stopPropagation();
|
|
168
|
-
|
|
177
|
+
const actionsMode = { id: `${c.id}:actions`, label: c.label, icon: c.icon, children: actions };
|
|
178
|
+
syntheticModes.add(actionsMode);
|
|
179
|
+
enter(actionsMode);
|
|
169
180
|
}
|
|
170
181
|
watch(
|
|
171
182
|
() => props.commands,
|
|
@@ -184,8 +195,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
184
195
|
if (last && Array.isArray(last.children)) modeItems.value = last.children;
|
|
185
196
|
}
|
|
186
197
|
);
|
|
187
|
-
function enter(c) {
|
|
188
|
-
trailState.value = [...trailState.value, { query:
|
|
198
|
+
function enter(c, parentQuery = query.value) {
|
|
199
|
+
trailState.value = [...trailState.value, { query: parentQuery, selectedId: selectedId.value }];
|
|
189
200
|
trail.value = [...trail.value, c];
|
|
190
201
|
query.value = "";
|
|
191
202
|
select(0);
|
|
@@ -234,10 +245,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
234
245
|
failed.value = false;
|
|
235
246
|
const run2 = fetcher();
|
|
236
247
|
if (!run2) return;
|
|
237
|
-
const
|
|
248
|
+
const parsed = parsePaletteQuery(query.value.trim());
|
|
249
|
+
const q = parsed.text;
|
|
238
250
|
const inMode = mode.value !== null;
|
|
239
251
|
if (!inMode && q.length < Math.max(1, props.minChars)) return;
|
|
240
|
-
task.run((signal) => run2(q, signal), {
|
|
252
|
+
task.run((signal) => run2(q, signal, parsed), {
|
|
241
253
|
delay: props.debounce,
|
|
242
254
|
apply: (hits) => found.value = hits,
|
|
243
255
|
fail: () => {
|
|
@@ -249,7 +261,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
249
261
|
const source = computed(() => mode.value ? modeItems.value : props.commands);
|
|
250
262
|
const local = computed(() => {
|
|
251
263
|
const terms = parseCommandQuery(query.value);
|
|
252
|
-
const filtered = query.value.trim() ? source.value : source.value.filter((c) => !c.hidden);
|
|
264
|
+
const filtered = query.value.trim() ? source.value.filter((c) => !c.fallback) : source.value.filter((c) => !c.hidden && !c.fallback);
|
|
253
265
|
if (!terms.include.length && !terms.exclude.length && !terms.groups.length) return { items: filtered, terms: [] };
|
|
254
266
|
const items = rankCommandItems(filtered, terms);
|
|
255
267
|
return { items, terms: terms.include };
|
|
@@ -258,39 +270,63 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
258
270
|
const fetched = computed(() => {
|
|
259
271
|
if (!found.value.length) return [];
|
|
260
272
|
const seen = new Set(ranked.value.map((c) => c.id));
|
|
261
|
-
|
|
273
|
+
const rows = found.value.filter((c) => !seen.has(c.id)).map((c) => c.group ? c : { ...c, group: props.resultsLabel });
|
|
274
|
+
return applyQueryFilters(rows, parseCommandQuery(query.value));
|
|
262
275
|
});
|
|
276
|
+
const fallbackOf = /* @__PURE__ */ new WeakMap();
|
|
277
|
+
const fallbacks = computed(
|
|
278
|
+
() => fallbackRows(source.value, query.value).map(({ command, label }) => {
|
|
279
|
+
const row = { ...command, label };
|
|
280
|
+
fallbackOf.set(row, command);
|
|
281
|
+
return row;
|
|
282
|
+
})
|
|
283
|
+
);
|
|
263
284
|
const ownRecent = ref([]);
|
|
264
285
|
watch(
|
|
265
286
|
() => props.recentKey,
|
|
266
287
|
(key) => {
|
|
267
288
|
if (!key || typeof localStorage === "undefined") return;
|
|
268
289
|
try {
|
|
269
|
-
|
|
270
|
-
ownRecent.value = Array.isArray(stored) ? stored.filter((v) => typeof v === "string") : [];
|
|
290
|
+
ownRecent.value = readRecent(JSON.parse(localStorage.getItem(key) ?? "[]"));
|
|
271
291
|
} catch {
|
|
272
292
|
ownRecent.value = [];
|
|
273
293
|
}
|
|
274
294
|
},
|
|
275
295
|
{ immediate: true }
|
|
276
296
|
);
|
|
277
|
-
|
|
297
|
+
const recentPath = /* @__PURE__ */ new WeakMap();
|
|
298
|
+
const syntheticModes = /* @__PURE__ */ new WeakSet();
|
|
299
|
+
function remember(c) {
|
|
300
|
+
if (c.remember === false || trail.value.some((step) => syntheticModes.has(step))) return;
|
|
301
|
+
const path = recentPath.get(c) ?? trail.value.map((step) => step.id);
|
|
302
|
+
const item = toRecentItem(c, path);
|
|
303
|
+
emit("remember", item, c);
|
|
278
304
|
const key = props.recentKey;
|
|
279
305
|
if (!key || props.recent) return;
|
|
280
|
-
ownRecent.value =
|
|
306
|
+
ownRecent.value = pushRecent(ownRecent.value, item, RECENT_KEEP);
|
|
281
307
|
try {
|
|
282
308
|
localStorage.setItem(key, JSON.stringify(ownRecent.value));
|
|
283
309
|
} catch {
|
|
284
310
|
}
|
|
285
311
|
}
|
|
286
|
-
const
|
|
312
|
+
const recentList = computed(() => props.recent ?? (props.recentKey ? ownRecent.value : []));
|
|
313
|
+
function fromEntry(entry) {
|
|
314
|
+
return { id: entry.id, label: entry.label, description: entry.description, icon: entry.icon, image: entry.image, href: entry.href };
|
|
315
|
+
}
|
|
287
316
|
const recentItems = computed(() => {
|
|
288
|
-
if (mode.value ||
|
|
289
|
-
const
|
|
317
|
+
if (mode.value || !recentList.value.length) return [];
|
|
318
|
+
const terms = parseCommandQuery(query.value);
|
|
319
|
+
if (terms.include.length) return [];
|
|
320
|
+
const found2 = resolveRecentItems(recentList.value, props.commands, {
|
|
321
|
+
limit: Number.POSITIVE_INFINITY,
|
|
322
|
+
resolve: props.resolveRecent,
|
|
323
|
+
fromEntry
|
|
324
|
+
});
|
|
290
325
|
const out = [];
|
|
291
|
-
for (const
|
|
292
|
-
|
|
293
|
-
|
|
326
|
+
for (const { command, path } of found2) {
|
|
327
|
+
if (out.includes(command) || !recentVisible(command, terms, props.recentLabel)) continue;
|
|
328
|
+
recentPath.set(command, path);
|
|
329
|
+
out.push(command);
|
|
294
330
|
if (out.length >= props.recentLimit) break;
|
|
295
331
|
}
|
|
296
332
|
return out;
|
|
@@ -309,10 +345,21 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
309
345
|
for (const c of recent) push(c, props.recentLabel);
|
|
310
346
|
for (const c of ranked.value) if (!recent.includes(c)) push(c, c.group ?? "");
|
|
311
347
|
for (const c of fetched.value) push(c, c.group ?? "");
|
|
348
|
+
const tail = /* @__PURE__ */ new Map();
|
|
349
|
+
for (const c of fallbacks.value) {
|
|
350
|
+
const group = c.group ?? "";
|
|
351
|
+
if (map.has(group)) map.get(group).push(c);
|
|
352
|
+
else tail.set(group, [...tail.get(group) ?? [], c]);
|
|
353
|
+
}
|
|
354
|
+
for (const [group, items] of tail) {
|
|
355
|
+
map.set(group, items);
|
|
356
|
+
order.push(group);
|
|
357
|
+
}
|
|
312
358
|
return order.map((name) => ({ name, items: folded(name, map.get(name)) }));
|
|
313
359
|
});
|
|
314
360
|
const expanded = ref(/* @__PURE__ */ new Set());
|
|
315
361
|
const moreOf = /* @__PURE__ */ new WeakMap();
|
|
362
|
+
const firstHidden = /* @__PURE__ */ new WeakMap();
|
|
316
363
|
function folded(name, items) {
|
|
317
364
|
const limit = props.groupLimit;
|
|
318
365
|
if (!limit || items.length <= limit + 1 || expanded.value.has(name)) return items;
|
|
@@ -323,6 +370,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
323
370
|
keepOpen: true
|
|
324
371
|
};
|
|
325
372
|
moreOf.set(more, name);
|
|
373
|
+
firstHidden.set(more, items[limit].id);
|
|
326
374
|
return [...items.slice(0, limit), more];
|
|
327
375
|
}
|
|
328
376
|
const flat = computed(() => grouped.value.flatMap((g) => g.items));
|
|
@@ -332,20 +380,45 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
332
380
|
return c && !moreOf.has(c) ? c : void 0;
|
|
333
381
|
});
|
|
334
382
|
const previewRef = ref(null);
|
|
335
|
-
const
|
|
336
|
-
() => props.previewPane &&
|
|
383
|
+
const previewable = computed(
|
|
384
|
+
() => props.previewPane && commandHasPreview(active.value, { slot: !!slots.preview, hasPreview: props.hasPreview })
|
|
385
|
+
);
|
|
386
|
+
const paneCommand = shallowRef();
|
|
387
|
+
let lingerTimer;
|
|
388
|
+
watch(
|
|
389
|
+
[active, previewable],
|
|
390
|
+
([command, show]) => {
|
|
391
|
+
clearTimeout(lingerTimer);
|
|
392
|
+
if (show) {
|
|
393
|
+
paneCommand.value = command;
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (!paneCommand.value) return;
|
|
397
|
+
lingerTimer = setTimeout(() => paneCommand.value = void 0, PANE_LINGER_MS);
|
|
398
|
+
},
|
|
399
|
+
{ immediate: true }
|
|
337
400
|
);
|
|
401
|
+
onBeforeUnmount(() => clearTimeout(lingerTimer));
|
|
402
|
+
const paneOpen = computed(() => props.previewPane && !!paneCommand.value);
|
|
403
|
+
function paneHighlight(text2) {
|
|
404
|
+
return highlight(text2, paneBody.value?.highlight);
|
|
405
|
+
}
|
|
406
|
+
const paneQuery = computed(() => parsePaletteQuery(query.value.trim()));
|
|
407
|
+
const paneBody = shallowRef();
|
|
408
|
+
watch(paneCommand, (command) => {
|
|
409
|
+
if (command) paneBody.value = command;
|
|
410
|
+
});
|
|
338
411
|
const paragraphs = computed(
|
|
339
|
-
() => (
|
|
412
|
+
() => (paneBody.value?.preview ?? paneBody.value?.excerpt ?? "").split(/\n{2,}/).map((part) => part.trim()).filter(Boolean)
|
|
340
413
|
);
|
|
341
414
|
const paneDescription = computed(() => {
|
|
342
|
-
const description =
|
|
415
|
+
const description = paneBody.value?.description?.trim();
|
|
343
416
|
if (!description) return void 0;
|
|
344
417
|
const body = paragraphs.value.join(" ");
|
|
345
418
|
return body.startsWith(description) ? void 0 : description;
|
|
346
419
|
});
|
|
347
420
|
watch(
|
|
348
|
-
() =>
|
|
421
|
+
() => paneCommand.value?.id,
|
|
349
422
|
async () => {
|
|
350
423
|
if (!paneOpen.value) return;
|
|
351
424
|
await nextTick();
|
|
@@ -361,37 +434,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
361
434
|
return flatIndex.value.get(c) ?? -1;
|
|
362
435
|
}
|
|
363
436
|
function highlight(value, extra = []) {
|
|
364
|
-
|
|
365
|
-
(a, b) => b.length - a.length
|
|
366
|
-
);
|
|
367
|
-
if (!value || terms.length === 0) return value ? [{ text: value, hit: false }] : [];
|
|
368
|
-
const lower = value.toLowerCase();
|
|
369
|
-
const parts = [];
|
|
370
|
-
let i = 0;
|
|
371
|
-
while (i < value.length) {
|
|
372
|
-
let at = -1;
|
|
373
|
-
let term = "";
|
|
374
|
-
for (const t of terms) {
|
|
375
|
-
const found2 = lower.indexOf(t, i);
|
|
376
|
-
if (found2 !== -1 && (at === -1 || found2 < at || found2 === at && t.length > term.length)) {
|
|
377
|
-
at = found2;
|
|
378
|
-
term = t;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
if (at === -1) {
|
|
382
|
-
parts.push({ text: value.slice(i), hit: false });
|
|
383
|
-
break;
|
|
384
|
-
}
|
|
385
|
-
if (at > i) parts.push({ text: value.slice(i, at), hit: false });
|
|
386
|
-
parts.push({ text: value.slice(at, at + term.length), hit: true });
|
|
387
|
-
i = at + term.length;
|
|
388
|
-
}
|
|
389
|
-
return parts;
|
|
437
|
+
return highlightParts(value, [...local.value.terms, ...extra]);
|
|
390
438
|
}
|
|
391
|
-
|
|
439
|
+
const IMAGE_RADIUS = { circle: "rounded-pill", soft: "rounded-[6px]", square: "rounded-[3px]" };
|
|
440
|
+
function imageOf(c) {
|
|
441
|
+
if (!c.image) return null;
|
|
442
|
+
const image = typeof c.image === "string" ? { src: c.image } : c.image;
|
|
443
|
+
return { ...image, icon: image.icon ?? c.icon };
|
|
444
|
+
}
|
|
445
|
+
watch(query, (value) => {
|
|
446
|
+
if (enterByPrefix(value)) return;
|
|
392
447
|
select(0);
|
|
393
448
|
refresh();
|
|
394
449
|
});
|
|
450
|
+
function enterByPrefix(value) {
|
|
451
|
+
const hit = matchModePrefix(value, source.value);
|
|
452
|
+
if (!hit) return false;
|
|
453
|
+
enter(hit.command, "");
|
|
454
|
+
query.value = hit.rest;
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
395
457
|
watch([query, trail, () => props.open], () => {
|
|
396
458
|
expanded.value = /* @__PURE__ */ new Set();
|
|
397
459
|
});
|
|
@@ -461,6 +523,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
461
523
|
if (!c.href) return;
|
|
462
524
|
window.open(c.href, "_blank", "noopener");
|
|
463
525
|
emit("run", c.id, c);
|
|
526
|
+
remember(c);
|
|
464
527
|
emit("update:open", false);
|
|
465
528
|
}
|
|
466
529
|
function onRowClick(event, c) {
|
|
@@ -468,10 +531,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
468
531
|
event.preventDefault();
|
|
469
532
|
run(c);
|
|
470
533
|
}
|
|
471
|
-
function run(
|
|
472
|
-
if (!
|
|
473
|
-
const
|
|
534
|
+
function run(row) {
|
|
535
|
+
if (!row || row.disabled) return;
|
|
536
|
+
const c = fallbackOf.get(row) ?? row;
|
|
537
|
+
const group = moreOf.get(row);
|
|
474
538
|
if (group !== void 0) {
|
|
539
|
+
selectedId.value = firstHidden.get(row) ?? null;
|
|
475
540
|
expanded.value = /* @__PURE__ */ new Set([...expanded.value, group]);
|
|
476
541
|
inputRef.value?.focus();
|
|
477
542
|
return;
|
|
@@ -480,11 +545,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
480
545
|
c.onSelect?.();
|
|
481
546
|
if (!c.onSelect && c.href && !c.children) window.location.assign(c.href);
|
|
482
547
|
if (c.children) {
|
|
548
|
+
const carried = query.value;
|
|
483
549
|
enter(c);
|
|
550
|
+
if (c.carryQuery) query.value = carried;
|
|
484
551
|
return;
|
|
485
552
|
}
|
|
486
553
|
emit("run", c.id, c);
|
|
487
|
-
|
|
554
|
+
remember(c);
|
|
488
555
|
if (c.keepOpen) {
|
|
489
556
|
query.value = "";
|
|
490
557
|
if (mode.value) void nextTick(() => select(Math.max(0, flat.value.findIndex((x) => x.id === c.id))));
|
|
@@ -599,7 +666,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
599
666
|
name: step.icon,
|
|
600
667
|
size: 13
|
|
601
668
|
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
602
|
-
createTextVNode(" " + toDisplayString(step
|
|
669
|
+
createTextVNode(" " + toDisplayString(unref(modeChipLabel)(step)) + " ", 1),
|
|
603
670
|
createVNode(_sfc_main$1, {
|
|
604
671
|
name: "lucide:x",
|
|
605
672
|
size: 12,
|
|
@@ -677,8 +744,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
677
744
|
onPointerenter: ($event) => onPointerEnter(c)
|
|
678
745
|
}, {
|
|
679
746
|
default: withCtx(() => [
|
|
680
|
-
c
|
|
747
|
+
imageOf(c) ? (openBlock(), createBlock(_sfc_main$3, {
|
|
681
748
|
key: 0,
|
|
749
|
+
src: imageOf(c).src ?? void 0,
|
|
750
|
+
alt: imageOf(c).alt ?? "",
|
|
751
|
+
fallback: imageOf(c).fallback,
|
|
752
|
+
icon: imageOf(c).icon,
|
|
753
|
+
shape: imageOf(c).shape ?? "soft",
|
|
754
|
+
"pixel-size": 20,
|
|
755
|
+
class: normalizeClass(["-my-0.5 -ml-0.5 shrink-0 text-[9px]", IMAGE_RADIUS[imageOf(c).shape ?? "soft"]])
|
|
756
|
+
}, null, 8, ["src", "alt", "fallback", "icon", "shape", "class"])) : c.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
757
|
+
key: 1,
|
|
682
758
|
name: c.icon,
|
|
683
759
|
size: 16,
|
|
684
760
|
class: normalizeClass(["shrink-0", { "mt-0.5": c.excerpt }])
|
|
@@ -722,8 +798,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
722
798
|
}), 128))
|
|
723
799
|
], 4)) : createCommentVNode("", true)
|
|
724
800
|
]),
|
|
725
|
-
c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
|
|
726
|
-
key:
|
|
801
|
+
c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.prefix && c.children ? (openBlock(), createElementBlock("kbd", _hoisted_15, toDisplayString(c.prefix), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
|
|
802
|
+
key: 4,
|
|
727
803
|
name: "lucide:chevron-right",
|
|
728
804
|
size: 14,
|
|
729
805
|
class: "shrink-0 text-muted"
|
|
@@ -760,7 +836,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
760
836
|
}, 512),
|
|
761
837
|
createVNode(Transition, { name: "lp-cmd-pane" }, {
|
|
762
838
|
default: withCtx(() => [
|
|
763
|
-
paneOpen.value ? (openBlock(), createElementBlock("aside",
|
|
839
|
+
paneOpen.value ? (openBlock(), createElementBlock("aside", _hoisted_16, [
|
|
764
840
|
createVNode(_sfc_main$2, {
|
|
765
841
|
ref_key: "previewRef",
|
|
766
842
|
ref: previewRef,
|
|
@@ -768,31 +844,44 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
768
844
|
"content-class": "px-5 py-4"
|
|
769
845
|
}, {
|
|
770
846
|
default: withCtx(() => [
|
|
771
|
-
|
|
772
|
-
key:
|
|
847
|
+
paneBody.value ? (openBlock(), createElementBlock("div", {
|
|
848
|
+
key: paneBody.value.id
|
|
773
849
|
}, [
|
|
774
|
-
renderSlot(_ctx.$slots, "preview", {
|
|
775
|
-
|
|
776
|
-
|
|
850
|
+
renderSlot(_ctx.$slots, "preview", {
|
|
851
|
+
command: paneBody.value,
|
|
852
|
+
highlight: paneHighlight,
|
|
853
|
+
query: paneQuery.value
|
|
854
|
+
}, () => [
|
|
855
|
+
createElementVNode("div", _hoisted_17, [
|
|
856
|
+
imageOf(paneBody.value) ? (openBlock(), createBlock(_sfc_main$3, {
|
|
777
857
|
key: 0,
|
|
778
|
-
|
|
858
|
+
src: imageOf(paneBody.value).src ?? void 0,
|
|
859
|
+
alt: imageOf(paneBody.value).alt ?? "",
|
|
860
|
+
fallback: imageOf(paneBody.value).fallback,
|
|
861
|
+
icon: imageOf(paneBody.value).icon,
|
|
862
|
+
shape: imageOf(paneBody.value).shape ?? "soft",
|
|
863
|
+
"pixel-size": 28,
|
|
864
|
+
class: normalizeClass(["shrink-0", IMAGE_RADIUS[imageOf(paneBody.value).shape ?? "soft"]])
|
|
865
|
+
}, null, 8, ["src", "alt", "fallback", "icon", "shape", "class"])) : paneBody.value.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
866
|
+
key: 1,
|
|
867
|
+
name: paneBody.value.icon,
|
|
779
868
|
size: 16,
|
|
780
869
|
class: "shrink-0 text-muted"
|
|
781
870
|
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
782
|
-
createElementVNode("h3",
|
|
871
|
+
createElementVNode("h3", _hoisted_18, toDisplayString(paneBody.value.label), 1)
|
|
783
872
|
]),
|
|
784
|
-
paneDescription.value ? (openBlock(), createElementBlock("p",
|
|
873
|
+
paneDescription.value ? (openBlock(), createElementBlock("p", _hoisted_19, toDisplayString(paneDescription.value), 1)) : createCommentVNode("", true),
|
|
785
874
|
(openBlock(true), createElementBlock(Fragment, null, renderList(paragraphs.value, (para, i) => {
|
|
786
875
|
return openBlock(), createElementBlock("p", {
|
|
787
876
|
key: i,
|
|
788
877
|
class: "lp-cmd-para mt-3 whitespace-pre-line text-sm leading-relaxed text-ink/90",
|
|
789
878
|
style: normalizeStyle({ animationDelay: `${Math.min(i + 1, STAGGER_MAX) * STAGGER_MS}ms` })
|
|
790
879
|
}, [
|
|
791
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(para,
|
|
880
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(para, paneBody.value.highlight), (p, pi) => {
|
|
792
881
|
return openBlock(), createElementBlock(Fragment, {
|
|
793
882
|
key: `p${pi}`
|
|
794
883
|
}, [
|
|
795
|
-
p.hit ? (openBlock(), createElementBlock("mark",
|
|
884
|
+
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_20, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
796
885
|
createTextVNode(toDisplayString(p.text), 1)
|
|
797
886
|
], 64))
|
|
798
887
|
], 64);
|
|
@@ -809,26 +898,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
809
898
|
_: 3
|
|
810
899
|
})
|
|
811
900
|
], 32),
|
|
812
|
-
createElementVNode("div",
|
|
813
|
-
createElementVNode("span",
|
|
901
|
+
createElementVNode("div", _hoisted_21, [
|
|
902
|
+
createElementVNode("span", _hoisted_22, [
|
|
814
903
|
_cache[4] || (_cache[4] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↑", -1)),
|
|
815
904
|
_cache[5] || (_cache[5] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↓", -1)),
|
|
816
905
|
createTextVNode(" " + toDisplayString(unref(text).navigate), 1)
|
|
817
906
|
]),
|
|
818
|
-
createElementVNode("span",
|
|
907
|
+
createElementVNode("span", _hoisted_23, [
|
|
819
908
|
_cache[6] || (_cache[6] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↵", -1)),
|
|
820
909
|
createTextVNode(" " + toDisplayString(unref(text).select), 1)
|
|
821
910
|
]),
|
|
822
|
-
selectedActions.value.length ? (openBlock(), createElementBlock("span",
|
|
911
|
+
selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_24, [
|
|
823
912
|
_cache[7] || (_cache[7] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "tab", -1)),
|
|
824
913
|
createTextVNode(" " + toDisplayString(unref(text).actions), 1)
|
|
825
914
|
])) : createCommentVNode("", true),
|
|
826
|
-
trail.value.length ? (openBlock(), createElementBlock("span",
|
|
915
|
+
trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_25, [
|
|
827
916
|
_cache[8] || (_cache[8] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "⌫", -1)),
|
|
828
917
|
createTextVNode(" " + toDisplayString(unref(text).back), 1)
|
|
829
918
|
])) : createCommentVNode("", true),
|
|
830
|
-
createElementVNode("span",
|
|
831
|
-
createElementVNode("kbd",
|
|
919
|
+
createElementVNode("span", _hoisted_26, [
|
|
920
|
+
createElementVNode("kbd", _hoisted_27, toDisplayString(unref(text).esc), 1),
|
|
832
921
|
createTextVNode(" " + toDisplayString(unref(text).close), 1)
|
|
833
922
|
])
|
|
834
923
|
])
|
|
@@ -844,7 +933,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
844
933
|
};
|
|
845
934
|
}
|
|
846
935
|
});
|
|
847
|
-
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
936
|
+
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6da7fe88"]]);
|
|
848
937
|
export {
|
|
849
938
|
LpCommandPalette as default
|
|
850
939
|
};
|
|
@@ -26,6 +26,17 @@ type __VLS_Props = {
|
|
|
26
26
|
* native-menu mode on that first click and swallow it.
|
|
27
27
|
*/
|
|
28
28
|
always?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* What the menu acts on, shown as a heading above the items: the row's name
|
|
31
|
+
* in a list of similar rows, so the user sees which one the right-click hit.
|
|
32
|
+
* Also names the menu for assistive tech.
|
|
33
|
+
*/
|
|
34
|
+
title?: string;
|
|
35
|
+
/** A muted second line under `title`, e.g. a version or a path. */
|
|
36
|
+
subtitle?: string;
|
|
37
|
+
/** An icon beside the title, or `titleImage` for a picture (an avatar, a logo). */
|
|
38
|
+
titleIcon?: string;
|
|
39
|
+
titleImage?: string;
|
|
29
40
|
};
|
|
30
41
|
declare var __VLS_16: {};
|
|
31
42
|
type __VLS_Slots = {} & {
|
|
@@ -3,10 +3,16 @@ export interface MenuItem {
|
|
|
3
3
|
icon?: string;
|
|
4
4
|
danger?: boolean;
|
|
5
5
|
separatorBefore?: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
6
7
|
onSelect?: () => void;
|
|
7
8
|
}
|
|
8
9
|
type __VLS_Props = {
|
|
9
10
|
items: MenuItem[];
|
|
11
|
+
/** A heading naming what the menu acts on; see LpContextMenu's `title`. */
|
|
12
|
+
title?: string;
|
|
13
|
+
subtitle?: string;
|
|
14
|
+
titleIcon?: string;
|
|
15
|
+
titleImage?: string;
|
|
10
16
|
};
|
|
11
17
|
declare var __VLS_14: {};
|
|
12
18
|
type __VLS_Slots = {} & {
|
|
@@ -6,6 +6,13 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
6
6
|
/** Take more than one at a time. */
|
|
7
7
|
multiple?: boolean;
|
|
8
8
|
disabled?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* A drag the page itself cannot see is over the zone. Desktop shells
|
|
11
|
+
* (Tauri, Electron) often take file drags natively, and the page then gets
|
|
12
|
+
* no dragenter or dragover at all, only the shell's own events; the app
|
|
13
|
+
* hit-tests those and passes the answer here so the zone lights up the same.
|
|
14
|
+
*/
|
|
15
|
+
dragOver?: boolean;
|
|
9
16
|
/**
|
|
10
17
|
* Also accept a paste anywhere on the page, not only while focused.
|
|
11
18
|
* Off by default: two zones both listening would each take the same
|
|
@@ -42,6 +49,13 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
42
49
|
/** Take more than one at a time. */
|
|
43
50
|
multiple?: boolean;
|
|
44
51
|
disabled?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* A drag the page itself cannot see is over the zone. Desktop shells
|
|
54
|
+
* (Tauri, Electron) often take file drags natively, and the page then gets
|
|
55
|
+
* no dragenter or dragover at all, only the shell's own events; the app
|
|
56
|
+
* hit-tests those and passes the answer here so the zone lights up the same.
|
|
57
|
+
*/
|
|
58
|
+
dragOver?: boolean;
|
|
45
59
|
/**
|
|
46
60
|
* Also accept a paste anywhere on the page, not only while focused.
|
|
47
61
|
* Off by default: two zones both listening would each take the same
|