@deepseek-ai/dsh-client-ui-sidebar-right 0.1.5-alpha.1

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 ADDED
@@ -0,0 +1,3614 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "@deepseek-ai/dsh-client-ui-sidebar-right",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ //#region \0rolldown/runtime.js
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
17
+ key = keys[i];
18
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: ((k) => from[k]).bind(null, key),
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
+ value: mod,
27
+ enumerable: true
28
+ }) : target, mod));
29
+ //#endregion
30
+ let react_jsx_runtime = require("react/jsx-runtime");
31
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
32
+ let react = require("react");
33
+ let react_dom = require("react-dom");
34
+ let _deepseek_ai_dsh_client_ui_dockkit = require("@deepseek-ai/dsh-client-ui-dockkit");
35
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
36
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-right/src/client/tabs/guide/GuideBody.module.css.mjs
37
+ const css$2 = ".geFEbW_guide{text-align:center;flex-direction:column;align-items:center;gap:8px;padding-top:24px;display:flex}.geFEbW_guideTitle{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size,14px);margin:0;font-weight:500;line-height:1.6}.geFEbW_guideBody{color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);margin:0;line-height:1.6}.geFEbW_entries{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;width:100%;max-width:480px;margin-top:16px;display:grid}.geFEbW_entry{color:inherit;font:inherit;text-align:left;border:.5px solid var(--dsw-alias-border-l1);cursor:pointer;background:0 0;border-radius:8px;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.geFEbW_entry:hover{background:var(--dsw-alias-interactive-bg-hover)}.geFEbW_entryIcon{color:var(--dsw-alias-label-secondary);flex:none;margin-top:1px;display:flex}.geFEbW_entryText{flex-direction:column;gap:2px;min-width:0;display:flex}.geFEbW_entryTitle{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size,14px);line-height:1.4}.geFEbW_entryDescription{color:var(--dsw-alias-label-secondary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:1.4}";
38
+ const tagId$2 = "@deepseek-ai/dsh-client-ui-sidebar-right/GuideBody.module.css";
39
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
40
+ const tag = document.createElement("style");
41
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-sidebar-right";
42
+ tag.dataset.pluginCss = tagId$2;
43
+ tag.textContent = css$2;
44
+ document.head.appendChild(tag);
45
+ }
46
+ var GuideBody_module_css_default = {
47
+ "entries": "geFEbW_entries",
48
+ "entry": "geFEbW_entry",
49
+ "entryDescription": "geFEbW_entryDescription",
50
+ "entryIcon": "geFEbW_entryIcon",
51
+ "entryText": "geFEbW_entryText",
52
+ "entryTitle": "geFEbW_entryTitle",
53
+ "guide": "geFEbW_guide",
54
+ "guideBody": "geFEbW_guideBody",
55
+ "guideTitle": "geFEbW_guideTitle"
56
+ };
57
+ //#endregion
58
+ //#region lib/types/client/tabs/guide/GuideBody.js
59
+ /** One entry box: the contributing type's glyph, heading, and line. */
60
+ function EntryBox({ entry, onPick }) {
61
+ const Icon = entry.icon;
62
+ return (0, react_jsx_runtime.jsxs)("button", {
63
+ type: "button",
64
+ className: GuideBody_module_css_default.entry,
65
+ "data-sidebar-right-guide-entry": entry.kind,
66
+ onClick: () => {
67
+ onPick(entry);
68
+ },
69
+ children: [Icon !== void 0 && (0, react_jsx_runtime.jsx)("span", {
70
+ className: GuideBody_module_css_default.entryIcon,
71
+ children: (0, react_jsx_runtime.jsx)(Icon, { size: 16 })
72
+ }), (0, react_jsx_runtime.jsxs)("span", {
73
+ className: GuideBody_module_css_default.entryText,
74
+ children: [(0, react_jsx_runtime.jsx)("span", {
75
+ className: GuideBody_module_css_default.entryTitle,
76
+ children: entry.title()
77
+ }), (0, react_jsx_runtime.jsx)("span", {
78
+ className: GuideBody_module_css_default.entryDescription,
79
+ children: entry.description()
80
+ })]
81
+ })]
82
+ });
83
+ }
84
+ /** The shipped guide: what the column is for, and the doors out of it. */
85
+ function ShippedGuide({ entries, onPick, t }) {
86
+ return (0, react_jsx_runtime.jsxs)("div", {
87
+ className: GuideBody_module_css_default.guide,
88
+ "data-sidebar-right-guide": true,
89
+ children: [
90
+ (0, react_jsx_runtime.jsx)("p", {
91
+ className: GuideBody_module_css_default.guideTitle,
92
+ children: t("guide.lead")
93
+ }),
94
+ (0, react_jsx_runtime.jsx)("p", {
95
+ className: GuideBody_module_css_default.guideBody,
96
+ children: t("guide.body")
97
+ }),
98
+ entries.length > 0 && (0, react_jsx_runtime.jsx)("div", {
99
+ className: GuideBody_module_css_default.entries,
100
+ children: entries.map((entry, index) => (0, react_jsx_runtime.jsx)(EntryBox, {
101
+ entry,
102
+ onPick
103
+ }, `${entry.kind}:${index}`))
104
+ })
105
+ ]
106
+ });
107
+ }
108
+ /** The guide tab's body, replaceable through its chain child. */
109
+ function GuideBody({ useTabInfo, useGuideEntries, renderSlotChain, t }) {
110
+ const { tab } = useTabInfo();
111
+ return renderSlotChain("sidebar.right.tab.guide", {}, {
112
+ hookContext: useTabInfo,
113
+ fallback: (0, react_jsx_runtime.jsx)(ShippedGuide, {
114
+ entries: useGuideEntries((entries) => entries),
115
+ onPick: (entry) => {
116
+ tab.actions.openTab(entry.kind, { replaceTab: true });
117
+ },
118
+ t
119
+ })
120
+ });
121
+ }
122
+ //#endregion
123
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-right/src/client/shell/ExpandButton.module.css.mjs
124
+ const css$1 = "._1kL45W_placeholder{flex:none;width:32px;height:32px;display:inline-block}._1kL45W_button{width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}._1kL45W_button:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._1kL45W_icon{transform:scaleX(-1)}";
125
+ const tagId$1 = "@deepseek-ai/dsh-client-ui-sidebar-right/ExpandButton.module.css";
126
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
127
+ const tag = document.createElement("style");
128
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-sidebar-right";
129
+ tag.dataset.pluginCss = tagId$1;
130
+ tag.textContent = css$1;
131
+ document.head.appendChild(tag);
132
+ }
133
+ var ExpandButton_module_css_default = {
134
+ "button": "_1kL45W_button",
135
+ "icon": "_1kL45W_icon",
136
+ "placeholder": "_1kL45W_placeholder"
137
+ };
138
+ //#endregion
139
+ //#region lib/types/client/shell/ExpandButton.js
140
+ /** The expand control while the panel is collapsed; its footprint while it is shown. */
141
+ function ExpandButton({ sessionId, useStore, actions, t }) {
142
+ if (useStore((state) => state.bySession[sessionId]?.layout.expanded ?? false)) return (0, react_jsx_runtime.jsx)("span", {
143
+ className: ExpandButton_module_css_default.placeholder,
144
+ "aria-hidden": true,
145
+ "data-sidebar-right-expand-placeholder": true
146
+ });
147
+ return (0, react_jsx_runtime.jsx)("button", {
148
+ type: "button",
149
+ className: ExpandButton_module_css_default.button,
150
+ "aria-label": t("chrome.expand"),
151
+ title: t("chrome.expand"),
152
+ "data-sidebar-right-expand": true,
153
+ onClick: () => {
154
+ actions.setExpanded(sessionId, true);
155
+ },
156
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { className: ExpandButton_module_css_default.icon })
157
+ });
158
+ }
159
+ //#endregion
160
+ //#region lib/types/client/contract/seed.js
161
+ /** The guide tab's kind. */
162
+ const GUIDE_KIND = "guide";
163
+ /**
164
+ * The address a page tab is recorded under: `sidebar://<kind>`. The scheme is
165
+ * this package's bookkeeping for `openTab`, spelled here and nowhere else; a
166
+ * caller names the kind and never sees or composes the address.
167
+ * @param kind - the page type's kind.
168
+ * @returns the page's address.
169
+ */
170
+ function pageAddress(kind) {
171
+ return `sidebar://${kind}`;
172
+ }
173
+ /**
174
+ * Build the guide tab a new pane is seeded with.
175
+ *
176
+ * The title is captured at mint time because it goes into the surface's
177
+ * operation sequence, which records what happened and must not change meaning
178
+ * later. A language change relabels the type, not tabs already open.
179
+ * @param id - tab id minted by the caller.
180
+ * @param title - the guide type's display name at mint time.
181
+ * @returns the guide tab record.
182
+ */
183
+ function makeGuideTab(id, title) {
184
+ return {
185
+ id,
186
+ kind: GUIDE_KIND,
187
+ contentId: pageAddress(GUIDE_KIND),
188
+ title
189
+ };
190
+ }
191
+ //#endregion
192
+ //#region lib/types/client/labels.js
193
+ /**
194
+ * Project the dictionary into the kit's label contract.
195
+ *
196
+ * Called during render, so a language change reaches the kit with the next one —
197
+ * the kit caches no copy to invalidate.
198
+ * @param t - namespace-bound translate.
199
+ * @returns every string the kit renders.
200
+ */
201
+ function dockLabels(t) {
202
+ return {
203
+ emptyPane: t("dock.emptyPane"),
204
+ splitPane: t("dock.splitPane"),
205
+ splitPaneDisabled: t("dock.splitPaneDisabled"),
206
+ splitPaneNarrow: t("dock.splitPaneNarrow"),
207
+ closeTab: t("dock.closeTab"),
208
+ addTab: t("dock.addTab"),
209
+ dockFloat: t("dock.dockFloat"),
210
+ closeFloat: t("dock.closeFloat")
211
+ };
212
+ }
213
+ //#endregion
214
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-right/src/client/shell/SidebarRight.module.css.mjs
215
+ const css = ".P3OORG_panel{z-index:10;background:var(--dsw-alias-bg-base);border-left:.5px solid var(--dsw-alias-border-l1);visibility:hidden;min-width:0;transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out), visibility 0s linear var(--ds-transition-duration-slow);flex-direction:column;display:flex;position:absolute;top:0;bottom:0;right:0;transform:translate(100%)}.P3OORG_panel[data-sidebar-right-open]{visibility:visible;transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out);transform:none}.P3OORG_panel[data-sidebar-right-panel=fullscreen]{z-index:40;border:none;position:fixed;inset:0}@media (prefers-reduced-motion:reduce){.P3OORG_panel,.P3OORG_panel[data-sidebar-right-open]{transition:none}}.P3OORG_iconButton{width:24px;height:24px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:14px;line-height:1;display:flex}.P3OORG_iconButton:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.P3OORG_panelBody{flex:auto;min-height:0;display:flex}.P3OORG_unavailable{color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);margin:0}.P3OORG_floatHost{z-index:60;pointer-events:none;position:fixed;inset:0}";
216
+ const tagId = "@deepseek-ai/dsh-client-ui-sidebar-right/SidebarRight.module.css";
217
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
218
+ const tag = document.createElement("style");
219
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-sidebar-right";
220
+ tag.dataset.pluginCss = tagId;
221
+ tag.textContent = css;
222
+ document.head.appendChild(tag);
223
+ }
224
+ var SidebarRight_module_css_default = {
225
+ "floatHost": "P3OORG_floatHost",
226
+ "iconButton": "P3OORG_iconButton",
227
+ "panel": "P3OORG_panel",
228
+ "panelBody": "P3OORG_panelBody",
229
+ "unavailable": "P3OORG_unavailable"
230
+ };
231
+ //#endregion
232
+ //#region lib/types/client/shell/SidebarRight.js
233
+ /**
234
+ * The Sidebar's seat in the frame, and the panel it draws.
235
+ *
236
+ * The frame owns the right column's geometry; this package owns one content
237
+ * tree at the column width or fixed across the viewport. A shown wide panel
238
+ * retains its track in fullscreen, preserving the conversation width. Below
239
+ * 768px fullscreen is derived from viewport width, without changing manual mode.
240
+ *
241
+ * The panel stays mounted while collapsed, translated off the frame's right
242
+ * edge, so opening and closing are one gesture in both presentations: a slide
243
+ * from and to that edge. Normal presentation moves the frame's tracks with
244
+ * the panel. A fullscreen opening reserves its underlying track only after
245
+ * the panel covers the frame, without animating those hidden columns.
246
+ *
247
+ * The panel has no header of its own: its two controls — presentation switch
248
+ * and collapse — ride the docking kit's chrome seat at the end of the top-right
249
+ * pane's tab strip, so the strip is the panel's whole top edge. The way back in
250
+ * while collapsed is not here either: it is one button in the conversation
251
+ * header (`ExpandButton.tsx`), because it exists only while this panel is
252
+ * hidden. Floating panels portal out because they must cross the column and the
253
+ * conversation, and the kit already positions them in viewport coordinates.
254
+ *
255
+ * Tab bodies do not live here. Each one is a registration under its type's kind,
256
+ * dispatched through the keyed `sidebar.right.pane.tab` seat (and a live chip
257
+ * title through `sidebar.right.pane.tab.title`), so a new tab type needs no edit
258
+ * to this file. What a body receives beyond the record — navigation, lifetime
259
+ * signal, actions — is read through the slot-owned useTabInfo hook. The Tab
260
+ * domain follows each session's store commits, including sessions off screen.
261
+ */
262
+ /** The guide tab one pane holds, if any: a pane holds at most one. */
263
+ function guideIn(layout, paneId) {
264
+ return (0, _deepseek_ai_dsh_client_ui_dockkit.findPaneContentTab)(layout, paneId, pageAddress(GUIDE_KIND), GUIDE_KIND);
265
+ }
266
+ /**
267
+ * Build the kit's intent face for one session out of the store's actions.
268
+ * @param sessionId - the session the seat draws; every action is bound to it.
269
+ * @param actions - the seat's bound store actions.
270
+ * @param openTab - the navigation face's `openTab`, which the strip's add control asks for a guide through.
271
+ * @returns the intents the kit reports gestures to.
272
+ */
273
+ function intentsFor(sessionId, actions, openTab) {
274
+ return {
275
+ focusTab: (tabId) => {
276
+ actions.focusTab(sessionId, tabId);
277
+ },
278
+ focusPane: (paneId) => {
279
+ actions.focusPane(sessionId, paneId);
280
+ },
281
+ splitPane: (paneId) => {
282
+ actions.splitPane(sessionId, paneId);
283
+ },
284
+ addTab: (paneId) => {
285
+ openTab(GUIDE_KIND, {
286
+ paneId,
287
+ revealIfOpened: false
288
+ });
289
+ },
290
+ closeTab: (tabId) => {
291
+ actions.closeTab(sessionId, tabId);
292
+ },
293
+ duplicateTab: (tabId) => {
294
+ actions.duplicateTab(sessionId, tabId);
295
+ },
296
+ floatTab: (tabId, rect) => {
297
+ actions.floatTab(sessionId, tabId, rect);
298
+ },
299
+ unfloatPane: (paneId) => {
300
+ actions.unfloatPane(sessionId, paneId);
301
+ },
302
+ placeTab: (tabId, toPaneId, index) => {
303
+ actions.placeTab(sessionId, tabId, toPaneId, index);
304
+ },
305
+ dropTab: (tabId, paneId, zone) => {
306
+ actions.dropTab(sessionId, tabId, paneId, zone);
307
+ },
308
+ moveFloat: (paneId, x, y) => {
309
+ actions.moveFloat(sessionId, paneId, x, y);
310
+ },
311
+ resizeFloat: (paneId, rect) => {
312
+ actions.resizeFloat(sessionId, paneId, rect);
313
+ },
314
+ resizeSplit: (splitId, sizes) => {
315
+ actions.resizeSplit(sessionId, splitId, sizes);
316
+ }
317
+ };
318
+ }
319
+ /**
320
+ * Dispatch one tab's body or title with stable framework hooks and record lifetime.
321
+ */
322
+ function TabSlot({ renderSlot, occurrence, useTabTypes, useTabNavigation, useStore, fullscreen, tab, seat, fallback }) {
323
+ const { signal, tabActions } = occurrence(tab);
324
+ const definition = useTabTypes((types) => types.find((definition) => definition.kind === tab.kind));
325
+ const hookContext = (0, react.useMemo)(() => ({
326
+ tabId: tab.id,
327
+ title: seat === "sidebar.right.pane.tab.title",
328
+ fullscreen,
329
+ signal,
330
+ actions: tabActions,
331
+ useStore,
332
+ useTabNavigation
333
+ }), [
334
+ tab.id,
335
+ seat,
336
+ fullscreen,
337
+ signal,
338
+ tabActions,
339
+ useStore,
340
+ useTabNavigation
341
+ ]);
342
+ return renderSlot(seat, {}, {
343
+ entryKey: definition?.id ?? tab.kind,
344
+ fallback,
345
+ hookContext
346
+ });
347
+ }
348
+ /**
349
+ * Dispatch a tab's body to its registered type.
350
+ *
351
+ * A kind with no registrant is a real state, not a defect: a session log can
352
+ * carry a tab whose type shipped in a plugin that is no longer mounted. Saying so
353
+ * is better than an empty pane.
354
+ */
355
+ function bodiesFor(panel) {
356
+ const { t, ...rest } = panel;
357
+ return (tab) => (0, react_jsx_runtime.jsx)(TabSlot, {
358
+ ...rest,
359
+ tab,
360
+ seat: "sidebar.right.pane.tab",
361
+ fallback: (0, react_jsx_runtime.jsx)("p", {
362
+ className: SidebarRight_module_css_default.unavailable,
363
+ "data-sidebar-right-unavailable": true,
364
+ children: t("tab.unavailable")
365
+ })
366
+ }, tab.id);
367
+ }
368
+ /** Dispatch a tab's title to its registered type; without one the chip shows the title captured at open time. */
369
+ function titlesFor(panel) {
370
+ return (tab) => (0, react_jsx_runtime.jsx)(TabSlot, {
371
+ ...panel,
372
+ tab,
373
+ seat: "sidebar.right.pane.tab.title",
374
+ fallback: tab.title
375
+ }, tab.id);
376
+ }
377
+ /** Expand-to-viewport glyph. */
378
+ function FullscreenGlyph() {
379
+ return (0, react_jsx_runtime.jsx)("svg", {
380
+ width: "14",
381
+ height: "14",
382
+ viewBox: "0 0 14 14",
383
+ fill: "none",
384
+ "aria-hidden": "true",
385
+ children: (0, react_jsx_runtime.jsx)("path", {
386
+ d: "M5 1.5H1.5V5M9 1.5h3.5V5M1.5 9v3.5H5M12.5 9v3.5H9",
387
+ stroke: "currentColor",
388
+ strokeLinecap: "round"
389
+ })
390
+ });
391
+ }
392
+ /** Restore-from-fullscreen glyph. */
393
+ function ExitFullscreenGlyph() {
394
+ return (0, react_jsx_runtime.jsx)("svg", {
395
+ width: "14",
396
+ height: "14",
397
+ viewBox: "0 0 14 14",
398
+ fill: "none",
399
+ "aria-hidden": "true",
400
+ children: (0, react_jsx_runtime.jsx)("path", {
401
+ d: "M1.5 5H5V1.5M9 1.5V5h3.5M1.5 9H5v3.5M9 12.5V9h3.5",
402
+ stroke: "currentColor",
403
+ strokeLinecap: "round"
404
+ })
405
+ });
406
+ }
407
+ /** The collapse glyph. */
408
+ function CloseGlyph() {
409
+ return (0, react_jsx_runtime.jsx)("svg", {
410
+ width: "12",
411
+ height: "12",
412
+ viewBox: "0 0 12 12",
413
+ fill: "none",
414
+ "aria-hidden": "true",
415
+ children: (0, react_jsx_runtime.jsx)("path", {
416
+ d: "M2 2l8 8M10 2l-8 8",
417
+ stroke: "currentColor",
418
+ strokeWidth: "1.3",
419
+ strokeLinecap: "round"
420
+ })
421
+ });
422
+ }
423
+ /** The panel's two controls, placed by the kit at the top-right pane's strip end. */
424
+ function PanelChrome({ sessionId, fullscreen, autoFullscreen, actions, t }) {
425
+ const next = fullscreen ? "push" : "fullscreen";
426
+ return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("button", {
427
+ type: "button",
428
+ className: SidebarRight_module_css_default.iconButton,
429
+ "aria-label": fullscreen ? t("chrome.exitFullscreen") : t("chrome.toFullscreen"),
430
+ title: fullscreen ? t("chrome.exitFullscreen") : t("chrome.toFullscreen"),
431
+ "data-sidebar-right-mode": next,
432
+ onClick: () => {
433
+ if (fullscreen && autoFullscreen) actions.setExpanded(sessionId, false);
434
+ actions.setMode(sessionId, next);
435
+ },
436
+ children: fullscreen ? (0, react_jsx_runtime.jsx)(ExitFullscreenGlyph, {}) : (0, react_jsx_runtime.jsx)(FullscreenGlyph, {})
437
+ }), (0, react_jsx_runtime.jsx)("button", {
438
+ type: "button",
439
+ className: SidebarRight_module_css_default.iconButton,
440
+ "aria-label": t("chrome.collapse"),
441
+ title: t("chrome.collapse"),
442
+ "data-sidebar-right-toggle": true,
443
+ onClick: () => {
444
+ actions.toggleExpanded(sessionId);
445
+ },
446
+ children: (0, react_jsx_runtime.jsx)(CloseGlyph, {})
447
+ })] });
448
+ }
449
+ /**
450
+ * The panel: the docked surface with the two controls in its top-right strip,
451
+ * anchored to the frame's right edge and slid off it while collapsed.
452
+ */
453
+ function SidebarPanel(panel) {
454
+ const { sessionId, surface, actions, t, renderSlot, openTab, width, reportRoom, fullscreen, autoFullscreen, panelRef } = panel;
455
+ const { expanded } = surface.layout;
456
+ return (0, react_jsx_runtime.jsx)("div", {
457
+ ref: panelRef,
458
+ className: SidebarRight_module_css_default.panel,
459
+ style: { width: fullscreen ? "100%" : width },
460
+ "data-sidebar-right-panel": fullscreen ? "fullscreen" : "push",
461
+ "data-sidebar-right-open": expanded || void 0,
462
+ "aria-hidden": !expanded || void 0,
463
+ children: (0, react_jsx_runtime.jsx)("div", {
464
+ className: SidebarRight_module_css_default.panelBody,
465
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_dockkit.DockSurface, {
466
+ state: surface.layout,
467
+ canSplit: (0, _deepseek_ai_dsh_client_ui_dockkit.canSplit)(surface.layout) && (0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(surface.layout).length < 2,
468
+ hideSplitAtCapacity: true,
469
+ dropZones: "horizontal",
470
+ minPaneFraction: .2,
471
+ canAddTab: (paneId) => guideIn(surface.layout, paneId) === void 0,
472
+ intents: intentsFor(sessionId, actions, openTab),
473
+ labels: dockLabels(t),
474
+ renderTab: bodiesFor(panel),
475
+ renderTabTitle: titlesFor(panel),
476
+ renderTabMenuItems: (tab, dismiss) => renderSlot("sidebar.right.tab.menu.item", {
477
+ tab,
478
+ dismiss
479
+ }),
480
+ chrome: (0, react_jsx_runtime.jsx)(PanelChrome, {
481
+ sessionId,
482
+ fullscreen,
483
+ autoFullscreen,
484
+ actions,
485
+ t
486
+ }),
487
+ onRoom: reportRoom
488
+ })
489
+ })
490
+ });
491
+ }
492
+ /** Portal the floating layer out of whichever seat rendered it. */
493
+ function Floats(panel) {
494
+ const { sessionId, surface, actions, t, openTab } = panel;
495
+ if (surface.layout.floats.length === 0) return null;
496
+ return (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)("div", {
497
+ className: SidebarRight_module_css_default.floatHost,
498
+ "data-sidebar-right-float-host": true,
499
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_dockkit.FloatLayer, {
500
+ state: surface.layout,
501
+ intents: intentsFor(sessionId, actions, openTab),
502
+ labels: dockLabels(t),
503
+ renderTab: bodiesFor(panel),
504
+ renderTabTitle: titlesFor(panel)
505
+ })
506
+ }), document.body);
507
+ }
508
+ /**
509
+ * The right column's occupant: the panel, anchored to the column's edge and
510
+ * shown or hidden by sliding, plus the floating layer. It is also where the
511
+ * frame learns the panel's presentation, and where `ctx.sidebarRight` learns
512
+ * which session it is acting on, because this is the seat that knows both.
513
+ */
514
+ function RightbarSeat({ sessionId, width, viewportWidth, canShow, useStore, actions, t, renderSlot, syncPresentation, bindService, openTab, useTabTypes, useTabNavigation, occurrence }) {
515
+ const surfaces = useStore((state) => state.bySession);
516
+ const surface = surfaces[sessionId];
517
+ const shown = surface !== void 0 && surface.layout.expanded;
518
+ const autoFullscreen = viewportWidth < 768;
519
+ const fullscreen = autoFullscreen || surface?.layout.mode === "fullscreen";
520
+ const panelRef = (0, react.useRef)(null);
521
+ const room = (0, react.useRef)(/* @__PURE__ */ new Map());
522
+ const reportRoom = (0, react.useCallback)((fits) => {
523
+ room.current = fits;
524
+ }, []);
525
+ const track = shown && !autoFullscreen;
526
+ (0, react.useEffect)(() => {
527
+ if (surface === void 0) actions.open(sessionId);
528
+ }, [
529
+ actions,
530
+ sessionId,
531
+ surface
532
+ ]);
533
+ (0, react.useLayoutEffect)(() => {
534
+ if (shown && !fullscreen && !canShow) actions.setExpanded(sessionId, false);
535
+ }, [
536
+ actions,
537
+ sessionId,
538
+ shown,
539
+ fullscreen,
540
+ canShow
541
+ ]);
542
+ (0, react.useLayoutEffect)(() => {
543
+ let disposed = false;
544
+ const reportWhenCovered = () => {
545
+ if (disposed) return;
546
+ const entering = shown && fullscreen ? panelRef.current.getAnimations().filter((animation) => "transitionProperty" in animation && animation.transitionProperty === "transform" && animation.playState !== "finished" && animation.playState !== "idle") : [];
547
+ if (entering.length === 0) {
548
+ syncPresentation({
549
+ shown,
550
+ track,
551
+ fullscreen
552
+ });
553
+ return;
554
+ }
555
+ Promise.allSettled(entering.map((animation) => animation.finished)).then(reportWhenCovered);
556
+ };
557
+ reportWhenCovered();
558
+ return () => {
559
+ disposed = true;
560
+ };
561
+ }, [
562
+ sessionId,
563
+ shown,
564
+ track,
565
+ fullscreen,
566
+ syncPresentation
567
+ ]);
568
+ (0, react.useLayoutEffect)(() => () => {
569
+ syncPresentation({
570
+ shown: false,
571
+ track: false,
572
+ fullscreen: false
573
+ });
574
+ }, [syncPresentation]);
575
+ (0, react.useEffect)(() => bindService({
576
+ sessionId,
577
+ actions,
578
+ surfaces,
579
+ canSplitPane: (paneId) => room.current.get(paneId)?.row !== false
580
+ }), [
581
+ bindService,
582
+ sessionId,
583
+ actions,
584
+ surfaces
585
+ ]);
586
+ if (surface === void 0) return null;
587
+ const panel = {
588
+ sessionId,
589
+ actions,
590
+ t,
591
+ renderSlot,
592
+ surface,
593
+ openTab,
594
+ useTabTypes,
595
+ useTabNavigation,
596
+ useStore,
597
+ occurrence,
598
+ fullscreen,
599
+ autoFullscreen,
600
+ reportRoom
601
+ };
602
+ return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(SidebarPanel, {
603
+ ...panel,
604
+ width,
605
+ panelRef
606
+ }), (0, react_jsx_runtime.jsx)(Floats, { ...panel })] });
607
+ }
608
+ //#endregion
609
+ //#region lib/types/client/tab-domain.js
610
+ /** Every session's occurrences. */
611
+ var TabDomain = class {
612
+ navigator;
613
+ pin;
614
+ bySession = /* @__PURE__ */ new Map();
615
+ /**
616
+ * @param navigator - where tab actions go, aimed at the tab's session; the navigation controller.
617
+ * @param pin - `ctx.resources.pin`, called once per occurrence at its first sync.
618
+ */
619
+ constructor(navigator, pin) {
620
+ this.navigator = navigator;
621
+ this.pin = pin;
622
+ }
623
+ /**
624
+ * Reconcile one session's occurrences with its committed layout.
625
+ *
626
+ * Called by the seat after every commit, and only then: aborting a vanished
627
+ * record runs the types' cleanup, which writes their stores.
628
+ * @param sessionId - the session whose layout committed.
629
+ * @param layout - that session's layout as committed.
630
+ */
631
+ sync(sessionId, layout) {
632
+ const held = this.session(sessionId);
633
+ for (const [tabId, occurrence] of held) {
634
+ if (layout.tabs[tabId] !== void 0) continue;
635
+ held.delete(tabId);
636
+ occurrence.controller.abort();
637
+ }
638
+ for (const tab of Object.values(layout.tabs)) {
639
+ const occurrence = held.get(tab.id) ?? this.hold(sessionId, tab.id, {
640
+ address: tab.contentId,
641
+ params: void 0,
642
+ revision: 0
643
+ });
644
+ const pane = (0, _deepseek_ai_dsh_client_ui_dockkit.findTabPane)(layout, tab.id);
645
+ occurrence.paneId = pane.host === "dock" ? pane.id : void 0;
646
+ if (occurrence.pinned) continue;
647
+ occurrence.pinned = true;
648
+ this.pin(occurrence.navigation.getSnapshot().address, occurrence.signal);
649
+ }
650
+ }
651
+ /**
652
+ * Read an occurrence created by navigation or committed-store reconciliation.
653
+ * @param sessionId - the session the record is in.
654
+ * @param tab - the record being drawn.
655
+ * @returns its occurrence.
656
+ * @throws when the record has not been reconciled or has disappeared.
657
+ */
658
+ occurrence(sessionId, tab) {
659
+ const occurrence = this.bySession.get(sessionId)?.get(tab.id);
660
+ if (occurrence === void 0) throw new Error(`sidebarRight: tab "${tab.id}" has no committed occurrence in session "${sessionId}"`);
661
+ return occurrence;
662
+ }
663
+ /**
664
+ * Record that an `open` settled on a tab.
665
+ *
666
+ * A record the layout has not yet shown the seat gets its occurrence here, so
667
+ * the body's first render already carries the opener's `params`.
668
+ * @param sessionId - the session opened into.
669
+ * @param tabId - the tab the open settled on.
670
+ * @param target - the address and the opener's params.
671
+ */
672
+ navigate(sessionId, tabId, target) {
673
+ const existing = this.session(sessionId).get(tabId);
674
+ if (existing === void 0) {
675
+ this.hold(sessionId, tabId, {
676
+ ...target,
677
+ revision: 1
678
+ });
679
+ return;
680
+ }
681
+ existing.navigation.set({
682
+ ...target,
683
+ revision: existing.navigation.getSnapshot().revision + 1
684
+ });
685
+ }
686
+ /** Abort every occurrence of every session; the package is unloading. */
687
+ dispose() {
688
+ for (const held of this.bySession.values()) for (const occurrence of held.values()) occurrence.controller.abort();
689
+ this.bySession.clear();
690
+ }
691
+ session(sessionId) {
692
+ let held = this.bySession.get(sessionId);
693
+ if (held === void 0) {
694
+ held = /* @__PURE__ */ new Map();
695
+ this.bySession.set(sessionId, held);
696
+ }
697
+ return held;
698
+ }
699
+ hold(sessionId, tabId, navigation) {
700
+ const controller = new AbortController();
701
+ const { navigator } = this;
702
+ const place = (placement) => ({
703
+ ...placement.replaceTab === true ? { replaceTab: tabId } : held.paneId === void 0 ? {} : { paneId: held.paneId },
704
+ ...placement.paneId === void 0 ? {} : { paneId: placement.paneId },
705
+ ...placement.revealIfOpened === void 0 ? {} : { revealIfOpened: placement.revealIfOpened }
706
+ });
707
+ const held = {
708
+ sessionId,
709
+ tabId,
710
+ controller,
711
+ signal: controller.signal,
712
+ navigation: (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(navigation),
713
+ paneId: void 0,
714
+ pinned: false,
715
+ tabActions: {
716
+ openResource: (address, options = {}) => {
717
+ navigator.openResourceIn(sessionId, address, {
718
+ ...place(options),
719
+ params: options.params
720
+ });
721
+ },
722
+ openTab: (kind, options = {}) => {
723
+ navigator.openTabIn(sessionId, kind, {
724
+ ...place(options),
725
+ params: options.params
726
+ });
727
+ },
728
+ close: () => {
729
+ navigator.closeIn(sessionId, tabId);
730
+ }
731
+ }
732
+ };
733
+ this.session(sessionId).set(tabId, held);
734
+ return held;
735
+ }
736
+ };
737
+ //#endregion
738
+ //#region lib/types/client/service.js
739
+ /**
740
+ * Create the public controller and the plugin-private store adoption callback.
741
+ * Adoption subscribes without reconciling; the first store commit creates occurrences.
742
+ * @param tabs - registered tab types.
743
+ * @param pin - resource retention for an occurrence's lifetime.
744
+ * @returns the controller and a callback releasing exactly its own adoption.
745
+ */
746
+ function createSidebarRightController(tabs, pin) {
747
+ const adopted = /* @__PURE__ */ new Map();
748
+ const controller = new SidebarRightController(tabs, pin, adopted);
749
+ return {
750
+ controller,
751
+ adopt(sessionId, store) {
752
+ adopted.get(sessionId)?.unsubscribe();
753
+ const sync = () => {
754
+ const surface = store.getSnapshot().bySession[sessionId];
755
+ if (surface !== void 0) controller.tabDomain.sync(sessionId, surface.layout);
756
+ };
757
+ const adoption = {
758
+ store,
759
+ unsubscribe: store.subscribe(sync)
760
+ };
761
+ adopted.set(sessionId, adoption);
762
+ return () => {
763
+ adoption.unsubscribe();
764
+ if (adopted.get(sessionId) === adoption) adopted.delete(sessionId);
765
+ };
766
+ }
767
+ };
768
+ }
769
+ /** The scheme every resource address carries; anything else is not a resource this face opens. */
770
+ const RESOURCE_SCHEME = "dsh-resource://";
771
+ /** Cross-plugin right-Sidebar face (ctx.sidebarRight). */
772
+ var SidebarRightController = class {
773
+ tabs;
774
+ adopted;
775
+ binding;
776
+ /**
777
+ * The Tab domain this controller navigates into; synced from each adopted
778
+ * store's commits, read by the seat for each body's owner share.
779
+ */
780
+ tabDomain;
781
+ /**
782
+ * @param tabs - the tab-type registry consulted to claim an address.
783
+ * @param pin - `ctx.resources.pin`, which the Tab domain holds addresses with.
784
+ * @param adopted - plugin-owned session stores used by occurrence actions.
785
+ */
786
+ constructor(tabs, pin, adopted = /* @__PURE__ */ new Map()) {
787
+ this.tabs = tabs;
788
+ this.adopted = adopted;
789
+ this.tabDomain = new TabDomain(this, pin);
790
+ }
791
+ /**
792
+ * Adopt the mounted seat's binding, replacing any previous one.
793
+ *
794
+ * Called from the seat while it is mounted, and released when it leaves.
795
+ * @param binding - the mounted seat's session, actions, and the store's surfaces.
796
+ * @returns a release callback that clears exactly this binding.
797
+ */
798
+ bind(binding) {
799
+ this.binding = binding;
800
+ return () => {
801
+ if (this.binding === binding) this.binding = void 0;
802
+ };
803
+ }
804
+ /**
805
+ * Open a resource: claim it, place it, reveal the column, record the navigation.
806
+ * @param address - a `dsh-resource://<type>/…` address.
807
+ * @param options - placement, the opening type, and navigation parameters.
808
+ */
809
+ openResource(address, options = {}) {
810
+ const { sessionId, actions } = this.require();
811
+ this.placeResource(sessionId, actions, address, options);
812
+ }
813
+ /**
814
+ * Open a page type by kind at the address this package records pages under.
815
+ * @param kind - the page type's kind.
816
+ * @param options - placement and that kind's navigation parameters.
817
+ */
818
+ openTab(kind, options = {}) {
819
+ const { sessionId, actions } = this.require();
820
+ this.placeTab(sessionId, actions, kind, options);
821
+ }
822
+ /**
823
+ * Open a resource in one session, for a tab's own action; nothing happens
824
+ * for a session whose store was never adopted or whose adoption was released.
825
+ * Not part of `ISidebarRight`: the Tab domain's path.
826
+ * @param sessionId - the session the acting tab is in.
827
+ * @param address - a `dsh-resource://<type>/…` address.
828
+ * @param options - placement, the opening type, and navigation parameters.
829
+ */
830
+ openResourceIn(sessionId, address, options = {}) {
831
+ const actions = this.actionsFor(sessionId);
832
+ if (actions !== void 0) this.placeResource(sessionId, actions, address, options);
833
+ }
834
+ /**
835
+ * Open a page type in one session, for a tab's own action; nothing happens
836
+ * for a session whose store was never adopted or whose adoption was released.
837
+ * Not part of `ISidebarRight`: the Tab domain's path.
838
+ * @param sessionId - the session the acting tab is in.
839
+ * @param kind - the page type's kind.
840
+ * @param options - placement and that kind's navigation parameters.
841
+ */
842
+ openTabIn(sessionId, kind, options = {}) {
843
+ const actions = this.actionsFor(sessionId);
844
+ if (actions !== void 0) this.placeTab(sessionId, actions, kind, options);
845
+ }
846
+ /**
847
+ * Close a tab of one session, for the tab's own action; nothing happens
848
+ * for a session whose store was never adopted or whose adoption was released.
849
+ * Not part of `ISidebarRight`: the Tab domain's path.
850
+ * @param sessionId - the session the tab is in.
851
+ * @param tabId - the tab to close.
852
+ */
853
+ closeIn(sessionId, tabId) {
854
+ const actions = this.actionsFor(sessionId);
855
+ if (actions !== void 0) actions.closeTab(sessionId, tabId);
856
+ }
857
+ /** Claim a resource and place it in one session; an address outside the scheme or one no type claims throws. */
858
+ placeResource(sessionId, actions, address, options) {
859
+ if (!address.startsWith(RESOURCE_SCHEME)) throw new Error(`sidebarRight: no registered tab type claims "${address}"`);
860
+ this.place(sessionId, actions, this.tabs.claim(address, options.kind), address, options, options.params);
861
+ }
862
+ /** Place a page type in one session at the address pages are recorded under; an unregistered kind throws. */
863
+ placeTab(sessionId, actions, kind, options) {
864
+ const definition = this.tabs.get(kind);
865
+ if (definition === void 0) throw new Error(`sidebarRight: no tab type is registered as "${kind}"`);
866
+ const address = pageAddress(kind);
867
+ this.place(sessionId, actions, {
868
+ kind,
869
+ contentId: address,
870
+ title: definition.title(address)
871
+ }, address, options, options.params);
872
+ }
873
+ /** The steps both opens share: one store intent, and the navigation record for the tab it settles on. */
874
+ place(sessionId, actions, claim, address, placement, params) {
875
+ actions.openContent(sessionId, {
876
+ kind: claim.kind,
877
+ contentId: claim.contentId,
878
+ title: claim.title,
879
+ ...placement.paneId === void 0 ? {} : { paneId: placement.paneId },
880
+ ...placement.replaceTab === void 0 ? {} : { replaceTab: placement.replaceTab },
881
+ ...placement.revealIfOpened === void 0 ? {} : { revealIfOpened: placement.revealIfOpened }
882
+ }, (tabId) => {
883
+ this.tabDomain.navigate(sessionId, tabId, {
884
+ address,
885
+ params
886
+ });
887
+ });
888
+ }
889
+ /**
890
+ * Close one tab of the mounted session.
891
+ * @param tabId - the tab to close.
892
+ */
893
+ close(tabId) {
894
+ const { sessionId, actions } = this.require();
895
+ actions.closeTab(sessionId, tabId);
896
+ }
897
+ /**
898
+ * The active tab of the active pane.
899
+ * @returns the record, or `undefined` with no mounted surface.
900
+ */
901
+ active() {
902
+ const layout = this.mounted()?.layout;
903
+ if (layout === void 0) return void 0;
904
+ const { activeTabId } = (0, _deepseek_ai_dsh_client_ui_dockkit.getPane)(layout, layout.activePaneId);
905
+ return Object.values(layout.tabs).find((tab) => tab.id === activeTabId);
906
+ }
907
+ /**
908
+ * Whether the column is currently showing its panel.
909
+ * @returns `true` while expanded; `false` while collapsed or with no mounted surface.
910
+ */
911
+ isExpanded() {
912
+ return this.mounted()?.layout.expanded ?? false;
913
+ }
914
+ /** Collapse an expanded column, or expand a collapsed one. */
915
+ toggleExpanded() {
916
+ const { sessionId, actions } = this.require();
917
+ actions.toggleExpanded(sessionId);
918
+ }
919
+ /**
920
+ * Focus a tab and the pane holding it; a missing tab is left alone.
921
+ * @param tabId - the tab to focus.
922
+ */
923
+ focus(tabId) {
924
+ const { sessionId, actions } = this.require();
925
+ if (this.mounted()?.layout.tabs[tabId] === void 0) return;
926
+ actions.focusTab(sessionId, tabId);
927
+ }
928
+ /**
929
+ * Split a docked pane to its right when the budget and the room rule allow.
930
+ * @param paneId - the pane to split; defaults to the active docked pane.
931
+ * @returns the new pane's id, or `undefined` when nothing was split.
932
+ */
933
+ split(paneId) {
934
+ const { sessionId, actions, canSplitPane } = this.require();
935
+ const layout = this.mounted()?.layout;
936
+ if (layout === void 0) return void 0;
937
+ const target = paneId ?? (0, _deepseek_ai_dsh_client_ui_dockkit.activeDockPaneId)(layout);
938
+ const node = layout.nodes[target];
939
+ if (node === void 0 || node.kind !== "pane" || node.host !== "dock") return void 0;
940
+ if (!(0, _deepseek_ai_dsh_client_ui_dockkit.canSplit)(layout) || (0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(layout).length >= 2 || !canSplitPane(target)) return void 0;
941
+ let created;
942
+ actions.splitPane(sessionId, target, (id) => {
943
+ created = id;
944
+ });
945
+ return created;
946
+ }
947
+ /**
948
+ * Take a docked tab out into a floating panel; a missing or floating tab is left alone.
949
+ * @param tabId - the tab to float.
950
+ * @param rect - the panel's rectangle; defaults to the cascade from the last panel.
951
+ */
952
+ float(tabId, rect) {
953
+ const { sessionId, actions } = this.require();
954
+ const layout = this.mounted()?.layout;
955
+ if (layout === void 0 || layout.tabs[tabId] === void 0) return;
956
+ if ((0, _deepseek_ai_dsh_client_ui_dockkit.findTabPane)(layout, tabId).host !== "dock") return;
957
+ actions.floatTab(sessionId, tabId, rect);
958
+ }
959
+ /**
960
+ * Return a floating panel's tab to the active docked pane; a missing or docked pane is left alone.
961
+ * @param paneId - the floating pane.
962
+ */
963
+ dock(paneId) {
964
+ const { sessionId, actions } = this.require();
965
+ const node = this.mounted()?.layout.nodes[paneId];
966
+ if (node === void 0 || node.kind !== "pane" || node.host !== "float") return;
967
+ actions.unfloatPane(sessionId, paneId);
968
+ }
969
+ /**
970
+ * Step the mounted session's surface back one intent.
971
+ *
972
+ * @internal Not part of the product: the sequence is an architectural fact
973
+ * with no user-facing control yet. Kept reachable for tests.
974
+ */
975
+ _undo() {
976
+ const { sessionId, actions } = this.require();
977
+ actions.undo(sessionId);
978
+ }
979
+ /**
980
+ * Step the mounted session's surface forward one intent.
981
+ *
982
+ * @internal See `_undo`.
983
+ */
984
+ _redo() {
985
+ const { sessionId, actions } = this.require();
986
+ actions.redo(sessionId);
987
+ }
988
+ /** The mounted session's surface; `undefined` without a seat or before its first open. */
989
+ mounted() {
990
+ const { binding } = this;
991
+ return binding === void 0 ? void 0 : binding.surfaces[binding.sessionId];
992
+ }
993
+ /**
994
+ * The store actions a tab's own action on `sessionId` runs through: that
995
+ * session's adopted store. `undefined` — nothing to act on — for a session
996
+ * whose store was never minted or whose adoption was released.
997
+ */
998
+ actionsFor(sessionId) {
999
+ return this.adopted.get(sessionId)?.store.actions;
1000
+ }
1001
+ require() {
1002
+ if (this.binding === void 0) throw new Error("sidebarRight: no session surface is mounted");
1003
+ return this.binding;
1004
+ }
1005
+ };
1006
+ //#endregion
1007
+ //#region ../../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
1008
+ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1009
+ const WIN_SLASH = "\\\\/";
1010
+ const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
1011
+ const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
1012
+ /**
1013
+ * Posix glob regex
1014
+ */
1015
+ const DOT_LITERAL = "\\.";
1016
+ const PLUS_LITERAL = "\\+";
1017
+ const QMARK_LITERAL = "\\?";
1018
+ const SLASH_LITERAL = "\\/";
1019
+ const ONE_CHAR = "(?=.)";
1020
+ const QMARK = "[^/]";
1021
+ const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
1022
+ const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
1023
+ const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
1024
+ const POSIX_CHARS = {
1025
+ DOT_LITERAL,
1026
+ PLUS_LITERAL,
1027
+ QMARK_LITERAL,
1028
+ SLASH_LITERAL,
1029
+ ONE_CHAR,
1030
+ QMARK,
1031
+ END_ANCHOR,
1032
+ DOTS_SLASH,
1033
+ NO_DOT: `(?!${DOT_LITERAL})`,
1034
+ NO_DOTS: `(?!${START_ANCHOR}${DOTS_SLASH})`,
1035
+ NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`,
1036
+ NO_DOTS_SLASH: `(?!${DOTS_SLASH})`,
1037
+ QMARK_NO_DOT: `[^.${SLASH_LITERAL}]`,
1038
+ STAR: `${QMARK}*?`,
1039
+ START_ANCHOR,
1040
+ SEP: "/"
1041
+ };
1042
+ /**
1043
+ * Windows glob regex
1044
+ */
1045
+ const WINDOWS_CHARS = {
1046
+ ...POSIX_CHARS,
1047
+ SLASH_LITERAL: `[${WIN_SLASH}]`,
1048
+ QMARK: WIN_NO_SLASH,
1049
+ STAR: `${WIN_NO_SLASH}*?`,
1050
+ DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
1051
+ NO_DOT: `(?!${DOT_LITERAL})`,
1052
+ NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
1053
+ NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
1054
+ NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
1055
+ QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
1056
+ START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
1057
+ END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
1058
+ SEP: "\\"
1059
+ };
1060
+ module.exports = {
1061
+ DEFAULT_MAX_EXTGLOB_RECURSION,
1062
+ MAX_LENGTH: 1024 * 64,
1063
+ POSIX_REGEX_SOURCE: {
1064
+ __proto__: null,
1065
+ alnum: "a-zA-Z0-9",
1066
+ alpha: "a-zA-Z",
1067
+ ascii: "\\x00-\\x7F",
1068
+ blank: " \\t",
1069
+ cntrl: "\\x00-\\x1F\\x7F",
1070
+ digit: "0-9",
1071
+ graph: "\\x21-\\x7E",
1072
+ lower: "a-z",
1073
+ print: "\\x20-\\x7E ",
1074
+ punct: "\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",
1075
+ space: " \\t\\r\\n\\v\\f",
1076
+ upper: "A-Z",
1077
+ word: "A-Za-z0-9_",
1078
+ xdigit: "A-Fa-f0-9"
1079
+ },
1080
+ REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
1081
+ REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
1082
+ REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
1083
+ REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
1084
+ REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
1085
+ REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
1086
+ REPLACEMENTS: {
1087
+ __proto__: null,
1088
+ "***": "*",
1089
+ "**/**": "**",
1090
+ "**/**/**": "**"
1091
+ },
1092
+ CHAR_0: 48,
1093
+ CHAR_9: 57,
1094
+ CHAR_UPPERCASE_A: 65,
1095
+ CHAR_LOWERCASE_A: 97,
1096
+ CHAR_UPPERCASE_Z: 90,
1097
+ CHAR_LOWERCASE_Z: 122,
1098
+ CHAR_LEFT_PARENTHESES: 40,
1099
+ CHAR_RIGHT_PARENTHESES: 41,
1100
+ CHAR_ASTERISK: 42,
1101
+ CHAR_AMPERSAND: 38,
1102
+ CHAR_AT: 64,
1103
+ CHAR_BACKWARD_SLASH: 92,
1104
+ CHAR_CARRIAGE_RETURN: 13,
1105
+ CHAR_CIRCUMFLEX_ACCENT: 94,
1106
+ CHAR_COLON: 58,
1107
+ CHAR_COMMA: 44,
1108
+ CHAR_DOT: 46,
1109
+ CHAR_DOUBLE_QUOTE: 34,
1110
+ CHAR_EQUAL: 61,
1111
+ CHAR_EXCLAMATION_MARK: 33,
1112
+ CHAR_FORM_FEED: 12,
1113
+ CHAR_FORWARD_SLASH: 47,
1114
+ CHAR_GRAVE_ACCENT: 96,
1115
+ CHAR_HASH: 35,
1116
+ CHAR_HYPHEN_MINUS: 45,
1117
+ CHAR_LEFT_ANGLE_BRACKET: 60,
1118
+ CHAR_LEFT_CURLY_BRACE: 123,
1119
+ CHAR_LEFT_SQUARE_BRACKET: 91,
1120
+ CHAR_LINE_FEED: 10,
1121
+ CHAR_NO_BREAK_SPACE: 160,
1122
+ CHAR_PERCENT: 37,
1123
+ CHAR_PLUS: 43,
1124
+ CHAR_QUESTION_MARK: 63,
1125
+ CHAR_RIGHT_ANGLE_BRACKET: 62,
1126
+ CHAR_RIGHT_CURLY_BRACE: 125,
1127
+ CHAR_RIGHT_SQUARE_BRACKET: 93,
1128
+ CHAR_SEMICOLON: 59,
1129
+ CHAR_SINGLE_QUOTE: 39,
1130
+ CHAR_SPACE: 32,
1131
+ CHAR_TAB: 9,
1132
+ CHAR_UNDERSCORE: 95,
1133
+ CHAR_VERTICAL_LINE: 124,
1134
+ CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
1135
+ /**
1136
+ * Create EXTGLOB_CHARS
1137
+ */
1138
+ extglobChars(chars) {
1139
+ return {
1140
+ "!": {
1141
+ type: "negate",
1142
+ open: "(?:(?!(?:",
1143
+ close: `))${chars.STAR})`
1144
+ },
1145
+ "?": {
1146
+ type: "qmark",
1147
+ open: "(?:",
1148
+ close: ")?"
1149
+ },
1150
+ "+": {
1151
+ type: "plus",
1152
+ open: "(?:",
1153
+ close: ")+"
1154
+ },
1155
+ "*": {
1156
+ type: "star",
1157
+ open: "(?:",
1158
+ close: ")*"
1159
+ },
1160
+ "@": {
1161
+ type: "at",
1162
+ open: "(?:",
1163
+ close: ")"
1164
+ }
1165
+ };
1166
+ },
1167
+ /**
1168
+ * Create GLOB_CHARS
1169
+ */
1170
+ globChars(win32) {
1171
+ return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
1172
+ }
1173
+ };
1174
+ }));
1175
+ //#endregion
1176
+ //#region ../../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/utils.js
1177
+ var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => {
1178
+ const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
1179
+ exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
1180
+ exports.hasRegexChars = (str) => REGEX_SPECIAL_CHARS.test(str);
1181
+ exports.isRegexChar = (str) => str.length === 1 && exports.hasRegexChars(str);
1182
+ exports.escapeRegex = (str) => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
1183
+ exports.toPosixSlashes = (str) => str.replace(REGEX_BACKSLASH, "/");
1184
+ exports.isWindows = () => {
1185
+ if (typeof navigator !== "undefined" && navigator.platform) {
1186
+ const platform = navigator.platform.toLowerCase();
1187
+ return platform === "win32" || platform === "windows";
1188
+ }
1189
+ if (typeof process !== "undefined" && process.platform) return process.platform === "win32";
1190
+ return false;
1191
+ };
1192
+ exports.removeBackslashes = (str) => {
1193
+ return str.replace(REGEX_REMOVE_BACKSLASH, (match) => {
1194
+ return match === "\\" ? "" : match;
1195
+ });
1196
+ };
1197
+ exports.escapeLast = (input, char, lastIdx) => {
1198
+ const idx = input.lastIndexOf(char, lastIdx);
1199
+ if (idx === -1) return input;
1200
+ if (input[idx - 1] === "\\") return exports.escapeLast(input, char, idx - 1);
1201
+ return `${input.slice(0, idx)}\\${input.slice(idx)}`;
1202
+ };
1203
+ exports.removePrefix = (input, state = {}) => {
1204
+ let output = input;
1205
+ if (output.startsWith("./")) {
1206
+ output = output.slice(2);
1207
+ state.prefix = "./";
1208
+ }
1209
+ return output;
1210
+ };
1211
+ exports.wrapOutput = (input, state = {}, options = {}) => {
1212
+ let output = `${options.contains ? "" : "^"}(?:${input})${options.contains ? "" : "$"}`;
1213
+ if (state.negated === true) output = `(?:^(?!${output}).*$)`;
1214
+ return output;
1215
+ };
1216
+ exports.basename = (path, { windows } = {}) => {
1217
+ const segs = path.split(windows ? /[\\/]/ : "/");
1218
+ const last = segs[segs.length - 1];
1219
+ if (last === "") return segs[segs.length - 2];
1220
+ return last;
1221
+ };
1222
+ }));
1223
+ //#endregion
1224
+ //#region ../../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/scan.js
1225
+ var require_scan = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1226
+ const utils = require_utils();
1227
+ const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
1228
+ const isPathSeparator = (code) => {
1229
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
1230
+ };
1231
+ const depth = (token) => {
1232
+ if (token.isPrefix !== true) token.depth = token.isGlobstar ? Infinity : 1;
1233
+ };
1234
+ /**
1235
+ * Quickly scans a glob pattern and returns an object with a handful of
1236
+ * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
1237
+ * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
1238
+ * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
1239
+ *
1240
+ * ```js
1241
+ * const pm = require('picomatch');
1242
+ * console.log(pm.scan('foo/bar/*.js'));
1243
+ * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
1244
+ * ```
1245
+ * @param {String} `str`
1246
+ * @param {Object} `options`
1247
+ * @return {Object} Returns an object with tokens and regex source string.
1248
+ * @api public
1249
+ */
1250
+ const scan = (input, options) => {
1251
+ const opts = options || {};
1252
+ const length = input.length - 1;
1253
+ const scanToEnd = opts.parts === true || opts.scanToEnd === true;
1254
+ const slashes = [];
1255
+ const tokens = [];
1256
+ const parts = [];
1257
+ let str = input;
1258
+ let index = -1;
1259
+ let start = 0;
1260
+ let lastIndex = 0;
1261
+ let isBrace = false;
1262
+ let isBracket = false;
1263
+ let isGlob = false;
1264
+ let isExtglob = false;
1265
+ let isGlobstar = false;
1266
+ let braceEscaped = false;
1267
+ let backslashes = false;
1268
+ let negated = false;
1269
+ let negatedExtglob = false;
1270
+ let finished = false;
1271
+ let braces = 0;
1272
+ let prev;
1273
+ let code;
1274
+ let token = {
1275
+ value: "",
1276
+ depth: 0,
1277
+ isGlob: false
1278
+ };
1279
+ const eos = () => index >= length;
1280
+ const peek = () => str.charCodeAt(index + 1);
1281
+ const advance = () => {
1282
+ prev = code;
1283
+ return str.charCodeAt(++index);
1284
+ };
1285
+ while (index < length) {
1286
+ code = advance();
1287
+ let next;
1288
+ if (code === CHAR_BACKWARD_SLASH) {
1289
+ backslashes = token.backslashes = true;
1290
+ code = advance();
1291
+ if (code === CHAR_LEFT_CURLY_BRACE) braceEscaped = true;
1292
+ continue;
1293
+ }
1294
+ if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
1295
+ braces++;
1296
+ while (eos() !== true && (code = advance())) {
1297
+ if (code === CHAR_BACKWARD_SLASH) {
1298
+ backslashes = token.backslashes = true;
1299
+ advance();
1300
+ continue;
1301
+ }
1302
+ if (code === CHAR_LEFT_CURLY_BRACE) {
1303
+ braces++;
1304
+ continue;
1305
+ }
1306
+ if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
1307
+ isBrace = token.isBrace = true;
1308
+ isGlob = token.isGlob = true;
1309
+ finished = true;
1310
+ if (scanToEnd === true) continue;
1311
+ break;
1312
+ }
1313
+ if (braceEscaped !== true && code === CHAR_COMMA) {
1314
+ isBrace = token.isBrace = true;
1315
+ isGlob = token.isGlob = true;
1316
+ finished = true;
1317
+ if (scanToEnd === true) continue;
1318
+ break;
1319
+ }
1320
+ if (code === CHAR_RIGHT_CURLY_BRACE) {
1321
+ braces--;
1322
+ if (braces === 0) {
1323
+ braceEscaped = false;
1324
+ isBrace = token.isBrace = true;
1325
+ finished = true;
1326
+ break;
1327
+ }
1328
+ }
1329
+ }
1330
+ if (scanToEnd === true) continue;
1331
+ break;
1332
+ }
1333
+ if (code === CHAR_FORWARD_SLASH) {
1334
+ slashes.push(index);
1335
+ tokens.push(token);
1336
+ token = {
1337
+ value: "",
1338
+ depth: 0,
1339
+ isGlob: false
1340
+ };
1341
+ if (finished === true) continue;
1342
+ if (prev === CHAR_DOT && index === start + 1) {
1343
+ start += 2;
1344
+ continue;
1345
+ }
1346
+ lastIndex = index + 1;
1347
+ continue;
1348
+ }
1349
+ if (opts.noext !== true) {
1350
+ if ((code === CHAR_PLUS || code === CHAR_AT || code === CHAR_ASTERISK || code === CHAR_QUESTION_MARK || code === CHAR_EXCLAMATION_MARK) === true && peek() === CHAR_LEFT_PARENTHESES) {
1351
+ isGlob = token.isGlob = true;
1352
+ isExtglob = token.isExtglob = true;
1353
+ finished = true;
1354
+ if (code === CHAR_EXCLAMATION_MARK && index === start) negatedExtglob = true;
1355
+ if (scanToEnd === true) {
1356
+ while (eos() !== true && (code = advance())) {
1357
+ if (code === CHAR_BACKWARD_SLASH) {
1358
+ backslashes = token.backslashes = true;
1359
+ code = advance();
1360
+ continue;
1361
+ }
1362
+ if (code === CHAR_RIGHT_PARENTHESES) {
1363
+ isGlob = token.isGlob = true;
1364
+ finished = true;
1365
+ break;
1366
+ }
1367
+ }
1368
+ continue;
1369
+ }
1370
+ break;
1371
+ }
1372
+ }
1373
+ if (code === CHAR_ASTERISK) {
1374
+ if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
1375
+ isGlob = token.isGlob = true;
1376
+ finished = true;
1377
+ if (scanToEnd === true) continue;
1378
+ break;
1379
+ }
1380
+ if (code === CHAR_QUESTION_MARK) {
1381
+ isGlob = token.isGlob = true;
1382
+ finished = true;
1383
+ if (scanToEnd === true) continue;
1384
+ break;
1385
+ }
1386
+ if (code === CHAR_LEFT_SQUARE_BRACKET) {
1387
+ while (eos() !== true && (next = advance())) {
1388
+ if (next === CHAR_BACKWARD_SLASH) {
1389
+ backslashes = token.backslashes = true;
1390
+ advance();
1391
+ continue;
1392
+ }
1393
+ if (next === CHAR_RIGHT_SQUARE_BRACKET) {
1394
+ isBracket = token.isBracket = true;
1395
+ isGlob = token.isGlob = true;
1396
+ finished = true;
1397
+ break;
1398
+ }
1399
+ }
1400
+ if (scanToEnd === true) continue;
1401
+ break;
1402
+ }
1403
+ if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
1404
+ negated = token.negated = true;
1405
+ start++;
1406
+ continue;
1407
+ }
1408
+ if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
1409
+ isGlob = token.isGlob = true;
1410
+ if (scanToEnd === true) {
1411
+ while (eos() !== true && (code = advance())) {
1412
+ if (code === CHAR_LEFT_PARENTHESES) {
1413
+ backslashes = token.backslashes = true;
1414
+ code = advance();
1415
+ continue;
1416
+ }
1417
+ if (code === CHAR_RIGHT_PARENTHESES) {
1418
+ finished = true;
1419
+ break;
1420
+ }
1421
+ }
1422
+ continue;
1423
+ }
1424
+ break;
1425
+ }
1426
+ if (isGlob === true) {
1427
+ finished = true;
1428
+ if (scanToEnd === true) continue;
1429
+ break;
1430
+ }
1431
+ }
1432
+ if (opts.noext === true) {
1433
+ isExtglob = false;
1434
+ isGlob = false;
1435
+ }
1436
+ let base = str;
1437
+ let prefix = "";
1438
+ let glob = "";
1439
+ if (start > 0) {
1440
+ prefix = str.slice(0, start);
1441
+ str = str.slice(start);
1442
+ lastIndex -= start;
1443
+ }
1444
+ if (base && isGlob === true && lastIndex > 0) {
1445
+ base = str.slice(0, lastIndex);
1446
+ glob = str.slice(lastIndex);
1447
+ } else if (isGlob === true) {
1448
+ base = "";
1449
+ glob = str;
1450
+ } else base = str;
1451
+ if (base && base !== "" && base !== "/" && base !== str) {
1452
+ if (isPathSeparator(base.charCodeAt(base.length - 1))) base = base.slice(0, -1);
1453
+ }
1454
+ if (opts.unescape === true) {
1455
+ if (glob) glob = utils.removeBackslashes(glob);
1456
+ if (base && backslashes === true) base = utils.removeBackslashes(base);
1457
+ }
1458
+ const state = {
1459
+ prefix,
1460
+ input,
1461
+ start,
1462
+ base,
1463
+ glob,
1464
+ isBrace,
1465
+ isBracket,
1466
+ isGlob,
1467
+ isExtglob,
1468
+ isGlobstar,
1469
+ negated,
1470
+ negatedExtglob
1471
+ };
1472
+ if (opts.tokens === true) {
1473
+ state.maxDepth = 0;
1474
+ if (!isPathSeparator(code)) tokens.push(token);
1475
+ state.tokens = tokens;
1476
+ }
1477
+ if (opts.parts === true || opts.tokens === true) {
1478
+ let prevIndex;
1479
+ for (let idx = 0; idx < slashes.length; idx++) {
1480
+ const n = prevIndex ? prevIndex + 1 : start;
1481
+ const i = slashes[idx];
1482
+ const value = input.slice(n, i);
1483
+ if (opts.tokens) {
1484
+ if (idx === 0 && start !== 0) {
1485
+ tokens[idx].isPrefix = true;
1486
+ tokens[idx].value = prefix;
1487
+ } else tokens[idx].value = value;
1488
+ depth(tokens[idx]);
1489
+ state.maxDepth += tokens[idx].depth;
1490
+ }
1491
+ if (idx !== 0 || value !== "") parts.push(value);
1492
+ prevIndex = i;
1493
+ }
1494
+ if (prevIndex && prevIndex + 1 < input.length) {
1495
+ const value = input.slice(prevIndex + 1);
1496
+ parts.push(value);
1497
+ if (opts.tokens) {
1498
+ tokens[tokens.length - 1].value = value;
1499
+ depth(tokens[tokens.length - 1]);
1500
+ state.maxDepth += tokens[tokens.length - 1].depth;
1501
+ }
1502
+ }
1503
+ state.slashes = slashes;
1504
+ state.parts = parts;
1505
+ }
1506
+ return state;
1507
+ };
1508
+ module.exports = scan;
1509
+ }));
1510
+ //#endregion
1511
+ //#region ../../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js
1512
+ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1513
+ const constants = require_constants();
1514
+ const utils = require_utils();
1515
+ /**
1516
+ * Constants
1517
+ */
1518
+ const { MAX_LENGTH, POSIX_REGEX_SOURCE, REGEX_NON_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_BACKREF, REPLACEMENTS } = constants;
1519
+ /**
1520
+ * Helpers
1521
+ */
1522
+ const expandRange = (args, options) => {
1523
+ if (typeof options.expandRange === "function") return options.expandRange(...args, options);
1524
+ args.sort();
1525
+ const value = `[${args.join("-")}]`;
1526
+ try {
1527
+ new RegExp(value);
1528
+ } catch (ex) {
1529
+ return args.map((v) => utils.escapeRegex(v)).join("..");
1530
+ }
1531
+ return value;
1532
+ };
1533
+ /**
1534
+ * Create the message for a syntax error
1535
+ */
1536
+ const syntaxError = (type, char) => {
1537
+ return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
1538
+ };
1539
+ const splitTopLevel = (input) => {
1540
+ const parts = [];
1541
+ let bracket = 0;
1542
+ let paren = 0;
1543
+ let quote = 0;
1544
+ let value = "";
1545
+ let escaped = false;
1546
+ for (const ch of input) {
1547
+ if (escaped === true) {
1548
+ value += ch;
1549
+ escaped = false;
1550
+ continue;
1551
+ }
1552
+ if (ch === "\\") {
1553
+ value += ch;
1554
+ escaped = true;
1555
+ continue;
1556
+ }
1557
+ if (ch === "\"") {
1558
+ quote = quote === 1 ? 0 : 1;
1559
+ value += ch;
1560
+ continue;
1561
+ }
1562
+ if (quote === 0) {
1563
+ if (ch === "[") bracket++;
1564
+ else if (ch === "]" && bracket > 0) bracket--;
1565
+ else if (bracket === 0) {
1566
+ if (ch === "(") paren++;
1567
+ else if (ch === ")" && paren > 0) paren--;
1568
+ else if (ch === "|" && paren === 0) {
1569
+ parts.push(value);
1570
+ value = "";
1571
+ continue;
1572
+ }
1573
+ }
1574
+ }
1575
+ value += ch;
1576
+ }
1577
+ parts.push(value);
1578
+ return parts;
1579
+ };
1580
+ const isPlainBranch = (branch) => {
1581
+ let escaped = false;
1582
+ for (const ch of branch) {
1583
+ if (escaped === true) {
1584
+ escaped = false;
1585
+ continue;
1586
+ }
1587
+ if (ch === "\\") {
1588
+ escaped = true;
1589
+ continue;
1590
+ }
1591
+ if (/[?*+@!()[\]{}]/.test(ch)) return false;
1592
+ }
1593
+ return true;
1594
+ };
1595
+ const normalizeSimpleBranch = (branch) => {
1596
+ let value = branch.trim();
1597
+ let changed = true;
1598
+ while (changed === true) {
1599
+ changed = false;
1600
+ if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
1601
+ value = value.slice(2, -1);
1602
+ changed = true;
1603
+ }
1604
+ }
1605
+ if (!isPlainBranch(value)) return;
1606
+ return value.replace(/\\(.)/g, "$1");
1607
+ };
1608
+ const hasRepeatedCharPrefixOverlap = (branches) => {
1609
+ const values = branches.map(normalizeSimpleBranch).filter(Boolean);
1610
+ for (let i = 0; i < values.length; i++) for (let j = i + 1; j < values.length; j++) {
1611
+ const a = values[i];
1612
+ const b = values[j];
1613
+ const char = a[0];
1614
+ if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) continue;
1615
+ if (a === b || a.startsWith(b) || b.startsWith(a)) return true;
1616
+ }
1617
+ return false;
1618
+ };
1619
+ const parseRepeatedExtglob = (pattern, requireEnd = true) => {
1620
+ if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") return;
1621
+ let bracket = 0;
1622
+ let paren = 0;
1623
+ let quote = 0;
1624
+ let escaped = false;
1625
+ for (let i = 1; i < pattern.length; i++) {
1626
+ const ch = pattern[i];
1627
+ if (escaped === true) {
1628
+ escaped = false;
1629
+ continue;
1630
+ }
1631
+ if (ch === "\\") {
1632
+ escaped = true;
1633
+ continue;
1634
+ }
1635
+ if (ch === "\"") {
1636
+ quote = quote === 1 ? 0 : 1;
1637
+ continue;
1638
+ }
1639
+ if (quote === 1) continue;
1640
+ if (ch === "[") {
1641
+ bracket++;
1642
+ continue;
1643
+ }
1644
+ if (ch === "]" && bracket > 0) {
1645
+ bracket--;
1646
+ continue;
1647
+ }
1648
+ if (bracket > 0) continue;
1649
+ if (ch === "(") {
1650
+ paren++;
1651
+ continue;
1652
+ }
1653
+ if (ch === ")") {
1654
+ paren--;
1655
+ if (paren === 0) {
1656
+ if (requireEnd === true && i !== pattern.length - 1) return;
1657
+ return {
1658
+ type: pattern[0],
1659
+ body: pattern.slice(2, i),
1660
+ end: i
1661
+ };
1662
+ }
1663
+ }
1664
+ }
1665
+ };
1666
+ const getStarExtglobSequenceOutput = (pattern) => {
1667
+ let index = 0;
1668
+ const chars = [];
1669
+ while (index < pattern.length) {
1670
+ const match = parseRepeatedExtglob(pattern.slice(index), false);
1671
+ if (!match || match.type !== "*") return;
1672
+ const branches = splitTopLevel(match.body).map((branch) => branch.trim());
1673
+ if (branches.length !== 1) return;
1674
+ const branch = normalizeSimpleBranch(branches[0]);
1675
+ if (!branch || branch.length !== 1) return;
1676
+ chars.push(branch);
1677
+ index += match.end + 1;
1678
+ }
1679
+ if (chars.length < 1) return;
1680
+ return `${chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`}*`;
1681
+ };
1682
+ const repeatedExtglobRecursion = (pattern) => {
1683
+ let depth = 0;
1684
+ let value = pattern.trim();
1685
+ let match = parseRepeatedExtglob(value);
1686
+ while (match) {
1687
+ depth++;
1688
+ value = match.body.trim();
1689
+ match = parseRepeatedExtglob(value);
1690
+ }
1691
+ return depth;
1692
+ };
1693
+ const analyzeRepeatedExtglob = (body, options) => {
1694
+ if (options.maxExtglobRecursion === false) return { risky: false };
1695
+ const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
1696
+ const branches = splitTopLevel(body).map((branch) => branch.trim());
1697
+ if (branches.length > 1) {
1698
+ if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) return { risky: true };
1699
+ }
1700
+ for (const branch of branches) {
1701
+ const safeOutput = getStarExtglobSequenceOutput(branch);
1702
+ if (safeOutput) return {
1703
+ risky: true,
1704
+ safeOutput
1705
+ };
1706
+ if (repeatedExtglobRecursion(branch) > max) return { risky: true };
1707
+ }
1708
+ return { risky: false };
1709
+ };
1710
+ /**
1711
+ * Parse the given input string.
1712
+ * @param {String} input
1713
+ * @param {Object} options
1714
+ * @return {Object}
1715
+ */
1716
+ const parse = (input, options) => {
1717
+ if (typeof input !== "string") throw new TypeError("Expected a string");
1718
+ input = REPLACEMENTS[input] || input;
1719
+ const opts = { ...options };
1720
+ const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
1721
+ let len = input.length;
1722
+ if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
1723
+ const bos = {
1724
+ type: "bos",
1725
+ value: "",
1726
+ output: opts.prepend || ""
1727
+ };
1728
+ const tokens = [bos];
1729
+ const capture = opts.capture ? "" : "?:";
1730
+ const PLATFORM_CHARS = constants.globChars(opts.windows);
1731
+ const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
1732
+ const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS;
1733
+ const globstar = (opts) => {
1734
+ return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
1735
+ };
1736
+ const nodot = opts.dot ? "" : NO_DOT;
1737
+ const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
1738
+ let star = opts.bash === true ? globstar(opts) : STAR;
1739
+ if (opts.capture) star = `(${star})`;
1740
+ if (typeof opts.noext === "boolean") opts.noextglob = opts.noext;
1741
+ const state = {
1742
+ input,
1743
+ index: -1,
1744
+ start: 0,
1745
+ dot: opts.dot === true,
1746
+ consumed: "",
1747
+ output: "",
1748
+ prefix: "",
1749
+ backtrack: false,
1750
+ negated: false,
1751
+ brackets: 0,
1752
+ braces: 0,
1753
+ parens: 0,
1754
+ quotes: 0,
1755
+ globstar: false,
1756
+ tokens
1757
+ };
1758
+ input = utils.removePrefix(input, state);
1759
+ len = input.length;
1760
+ const extglobs = [];
1761
+ const braces = [];
1762
+ const stack = [];
1763
+ let prev = bos;
1764
+ let value;
1765
+ /**
1766
+ * Tokenizing helpers
1767
+ */
1768
+ const eos = () => state.index === len - 1;
1769
+ const peek = state.peek = (n = 1) => input[state.index + n];
1770
+ const advance = state.advance = () => input[++state.index] || "";
1771
+ const remaining = () => input.slice(state.index + 1);
1772
+ const consume = (value = "", num = 0) => {
1773
+ state.consumed += value;
1774
+ state.index += num;
1775
+ };
1776
+ const append = (token) => {
1777
+ state.output += token.output != null ? token.output : token.value;
1778
+ consume(token.value);
1779
+ };
1780
+ const negate = () => {
1781
+ let count = 1;
1782
+ while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) {
1783
+ advance();
1784
+ state.start++;
1785
+ count++;
1786
+ }
1787
+ if (count % 2 === 0) return false;
1788
+ state.negated = true;
1789
+ state.start++;
1790
+ return true;
1791
+ };
1792
+ const increment = (type) => {
1793
+ state[type]++;
1794
+ stack.push(type);
1795
+ };
1796
+ const decrement = (type) => {
1797
+ state[type]--;
1798
+ stack.pop();
1799
+ };
1800
+ /**
1801
+ * Push tokens onto the tokens array. This helper speeds up
1802
+ * tokenizing by 1) helping us avoid backtracking as much as possible,
1803
+ * and 2) helping us avoid creating extra tokens when consecutive
1804
+ * characters are plain text. This improves performance and simplifies
1805
+ * lookbehinds.
1806
+ */
1807
+ const push = (tok) => {
1808
+ if (prev.type === "globstar") {
1809
+ const isBrace = state.braces > 0 && (tok.type === "comma" || tok.type === "brace");
1810
+ const isExtglob = tok.extglob === true || extglobs.length && (tok.type === "pipe" || tok.type === "paren");
1811
+ if (tok.type !== "slash" && tok.type !== "paren" && !isBrace && !isExtglob) {
1812
+ state.output = state.output.slice(0, -prev.output.length);
1813
+ prev.type = "star";
1814
+ prev.value = "*";
1815
+ prev.output = star;
1816
+ state.output += prev.output;
1817
+ }
1818
+ }
1819
+ if (extglobs.length && tok.type !== "paren") extglobs[extglobs.length - 1].inner += tok.value;
1820
+ if (tok.value || tok.output) append(tok);
1821
+ if (prev && prev.type === "text" && tok.type === "text") {
1822
+ prev.output = (prev.output || prev.value) + tok.value;
1823
+ prev.value += tok.value;
1824
+ return;
1825
+ }
1826
+ tok.prev = prev;
1827
+ tokens.push(tok);
1828
+ prev = tok;
1829
+ };
1830
+ const extglobOpen = (type, value) => {
1831
+ const token = {
1832
+ ...EXTGLOB_CHARS[value],
1833
+ conditions: 1,
1834
+ inner: ""
1835
+ };
1836
+ token.prev = prev;
1837
+ token.parens = state.parens;
1838
+ token.output = state.output;
1839
+ token.startIndex = state.index;
1840
+ token.tokensIndex = tokens.length;
1841
+ const output = (opts.capture ? "(" : "") + token.open;
1842
+ increment("parens");
1843
+ push({
1844
+ type,
1845
+ value,
1846
+ output: state.output ? "" : ONE_CHAR
1847
+ });
1848
+ push({
1849
+ type: "paren",
1850
+ extglob: true,
1851
+ value: advance(),
1852
+ output
1853
+ });
1854
+ extglobs.push(token);
1855
+ };
1856
+ const extglobClose = (token) => {
1857
+ const literal = input.slice(token.startIndex, state.index + 1);
1858
+ const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
1859
+ if ((token.type === "plus" || token.type === "star") && analysis.risky) {
1860
+ const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
1861
+ const open = tokens[token.tokensIndex];
1862
+ open.type = "text";
1863
+ open.value = literal;
1864
+ open.output = safeOutput || utils.escapeRegex(literal);
1865
+ for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
1866
+ tokens[i].value = "";
1867
+ tokens[i].output = "";
1868
+ delete tokens[i].suffix;
1869
+ }
1870
+ state.output = token.output + open.output;
1871
+ state.backtrack = true;
1872
+ push({
1873
+ type: "paren",
1874
+ extglob: true,
1875
+ value,
1876
+ output: ""
1877
+ });
1878
+ decrement("parens");
1879
+ return;
1880
+ }
1881
+ let output = token.close + (opts.capture ? ")" : "");
1882
+ let rest;
1883
+ if (token.type === "negate") {
1884
+ let extglobStar = star;
1885
+ if (token.inner && token.inner.length > 1 && token.inner.includes("/")) extglobStar = globstar(opts);
1886
+ if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) output = token.close = `)$))${extglobStar}`;
1887
+ if (token.inner.includes("*") && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) output = token.close = `)${parse(rest, {
1888
+ ...options,
1889
+ fastpaths: false
1890
+ }).output})${extglobStar})`;
1891
+ if (token.prev.type === "bos") state.negatedExtglob = true;
1892
+ }
1893
+ push({
1894
+ type: "paren",
1895
+ extglob: true,
1896
+ value,
1897
+ output
1898
+ });
1899
+ decrement("parens");
1900
+ };
1901
+ /**
1902
+ * Fast paths
1903
+ */
1904
+ if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
1905
+ let backslashes = false;
1906
+ let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
1907
+ if (first === "\\") {
1908
+ backslashes = true;
1909
+ return m;
1910
+ }
1911
+ if (first === "?") {
1912
+ if (esc) return esc + first + (rest ? QMARK.repeat(rest.length) : "");
1913
+ if (index === 0) return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : "");
1914
+ return QMARK.repeat(chars.length);
1915
+ }
1916
+ if (first === ".") return DOT_LITERAL.repeat(chars.length);
1917
+ if (first === "*") {
1918
+ if (esc) return esc + first + (rest ? star : "");
1919
+ return star;
1920
+ }
1921
+ return esc ? m : `\\${m}`;
1922
+ });
1923
+ if (backslashes === true) if (opts.unescape === true) output = output.replace(/\\/g, "");
1924
+ else output = output.replace(/\\+/g, (m) => {
1925
+ return m.length % 2 === 0 ? "\\\\" : m ? "\\" : "";
1926
+ });
1927
+ if (output === input && opts.contains === true) {
1928
+ state.output = input;
1929
+ return state;
1930
+ }
1931
+ state.output = utils.wrapOutput(output, state, options);
1932
+ return state;
1933
+ }
1934
+ /**
1935
+ * Tokenize input until we reach end-of-string
1936
+ */
1937
+ while (!eos()) {
1938
+ value = advance();
1939
+ if (value === "\0") continue;
1940
+ /**
1941
+ * Escaped characters
1942
+ */
1943
+ if (value === "\\") {
1944
+ const next = peek();
1945
+ if (next === "/" && opts.bash !== true) continue;
1946
+ if (next === "." || next === ";") continue;
1947
+ if (!next) {
1948
+ value += "\\";
1949
+ push({
1950
+ type: "text",
1951
+ value
1952
+ });
1953
+ continue;
1954
+ }
1955
+ const match = /^\\+/.exec(remaining());
1956
+ let slashes = 0;
1957
+ if (match && match[0].length > 2) {
1958
+ slashes = match[0].length;
1959
+ state.index += slashes;
1960
+ if (slashes % 2 !== 0) value += "\\";
1961
+ }
1962
+ if (opts.unescape === true) value = advance();
1963
+ else value += advance();
1964
+ if (state.brackets === 0) {
1965
+ push({
1966
+ type: "text",
1967
+ value
1968
+ });
1969
+ continue;
1970
+ }
1971
+ }
1972
+ /**
1973
+ * If we're inside a regex character class, continue
1974
+ * until we reach the closing bracket.
1975
+ */
1976
+ if (state.brackets > 0 && (value !== "]" || prev.value === "[" || prev.value === "[^")) {
1977
+ if (opts.posix !== false && value === ":") {
1978
+ const inner = prev.value.slice(1);
1979
+ if (inner.includes("[")) {
1980
+ prev.posix = true;
1981
+ if (inner.includes(":")) {
1982
+ const idx = prev.value.lastIndexOf("[");
1983
+ const pre = prev.value.slice(0, idx);
1984
+ const posix = POSIX_REGEX_SOURCE[prev.value.slice(idx + 2)];
1985
+ if (posix) {
1986
+ prev.value = pre + posix;
1987
+ state.backtrack = true;
1988
+ advance();
1989
+ if (!bos.output && tokens.indexOf(prev) === 1) bos.output = ONE_CHAR;
1990
+ continue;
1991
+ }
1992
+ }
1993
+ }
1994
+ }
1995
+ if (value === "[" && peek() !== ":" || value === "-" && peek() === "]") value = `\\${value}`;
1996
+ if (value === "]" && (prev.value === "[" || prev.value === "[^")) value = `\\${value}`;
1997
+ if (opts.posix === true && value === "!" && prev.value === "[") value = "^";
1998
+ prev.value += value;
1999
+ append({ value });
2000
+ continue;
2001
+ }
2002
+ /**
2003
+ * If we're inside a quoted string, continue
2004
+ * until we reach the closing double quote.
2005
+ */
2006
+ if (state.quotes === 1 && value !== "\"") {
2007
+ value = utils.escapeRegex(value);
2008
+ prev.value += value;
2009
+ append({ value });
2010
+ continue;
2011
+ }
2012
+ /**
2013
+ * Double quotes
2014
+ */
2015
+ if (value === "\"") {
2016
+ state.quotes = state.quotes === 1 ? 0 : 1;
2017
+ if (opts.keepQuotes === true) push({
2018
+ type: "text",
2019
+ value
2020
+ });
2021
+ continue;
2022
+ }
2023
+ /**
2024
+ * Parentheses
2025
+ */
2026
+ if (value === "(") {
2027
+ increment("parens");
2028
+ push({
2029
+ type: "paren",
2030
+ value
2031
+ });
2032
+ continue;
2033
+ }
2034
+ if (value === ")") {
2035
+ if (state.parens === 0 && opts.strictBrackets === true) throw new SyntaxError(syntaxError("opening", "("));
2036
+ const extglob = extglobs[extglobs.length - 1];
2037
+ if (extglob && state.parens === extglob.parens + 1) {
2038
+ extglobClose(extglobs.pop());
2039
+ continue;
2040
+ }
2041
+ push({
2042
+ type: "paren",
2043
+ value,
2044
+ output: state.parens ? ")" : "\\)"
2045
+ });
2046
+ decrement("parens");
2047
+ continue;
2048
+ }
2049
+ /**
2050
+ * Square brackets
2051
+ */
2052
+ if (value === "[") {
2053
+ if (opts.nobracket === true || !remaining().includes("]")) {
2054
+ if (opts.nobracket !== true && opts.strictBrackets === true) throw new SyntaxError(syntaxError("closing", "]"));
2055
+ value = `\\${value}`;
2056
+ } else increment("brackets");
2057
+ push({
2058
+ type: "bracket",
2059
+ value
2060
+ });
2061
+ continue;
2062
+ }
2063
+ if (value === "]") {
2064
+ if (opts.nobracket === true || prev && prev.type === "bracket" && prev.value.length === 1) {
2065
+ push({
2066
+ type: "text",
2067
+ value,
2068
+ output: `\\${value}`
2069
+ });
2070
+ continue;
2071
+ }
2072
+ if (state.brackets === 0) {
2073
+ if (opts.strictBrackets === true) throw new SyntaxError(syntaxError("opening", "["));
2074
+ push({
2075
+ type: "text",
2076
+ value,
2077
+ output: `\\${value}`
2078
+ });
2079
+ continue;
2080
+ }
2081
+ decrement("brackets");
2082
+ const prevValue = prev.value.slice(1);
2083
+ if (prev.posix !== true && prevValue[0] === "^" && !prevValue.includes("/")) value = `/${value}`;
2084
+ prev.value += value;
2085
+ append({ value });
2086
+ if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) continue;
2087
+ const escaped = utils.escapeRegex(prev.value);
2088
+ state.output = state.output.slice(0, -prev.value.length);
2089
+ if (opts.literalBrackets === true) {
2090
+ state.output += escaped;
2091
+ prev.value = escaped;
2092
+ continue;
2093
+ }
2094
+ prev.value = `(${capture}${escaped}|${prev.value})`;
2095
+ state.output += prev.value;
2096
+ continue;
2097
+ }
2098
+ /**
2099
+ * Braces
2100
+ */
2101
+ if (value === "{" && opts.nobrace !== true) {
2102
+ increment("braces");
2103
+ const open = {
2104
+ type: "brace",
2105
+ value,
2106
+ output: "(",
2107
+ outputIndex: state.output.length,
2108
+ tokensIndex: state.tokens.length
2109
+ };
2110
+ braces.push(open);
2111
+ push(open);
2112
+ continue;
2113
+ }
2114
+ if (value === "}") {
2115
+ const brace = braces[braces.length - 1];
2116
+ if (opts.nobrace === true || !brace) {
2117
+ push({
2118
+ type: "text",
2119
+ value,
2120
+ output: value
2121
+ });
2122
+ continue;
2123
+ }
2124
+ let output = ")";
2125
+ if (brace.dots === true) {
2126
+ const arr = tokens.slice();
2127
+ const range = [];
2128
+ for (let i = arr.length - 1; i >= 0; i--) {
2129
+ tokens.pop();
2130
+ if (arr[i].type === "brace") break;
2131
+ if (arr[i].type !== "dots") range.unshift(arr[i].value);
2132
+ }
2133
+ output = expandRange(range, opts);
2134
+ state.backtrack = true;
2135
+ }
2136
+ if (brace.comma !== true && brace.dots !== true) {
2137
+ const out = state.output.slice(0, brace.outputIndex);
2138
+ const toks = state.tokens.slice(brace.tokensIndex);
2139
+ brace.value = brace.output = "\\{";
2140
+ value = output = "\\}";
2141
+ state.output = out;
2142
+ for (const t of toks) state.output += t.output || t.value;
2143
+ }
2144
+ push({
2145
+ type: "brace",
2146
+ value,
2147
+ output
2148
+ });
2149
+ decrement("braces");
2150
+ braces.pop();
2151
+ continue;
2152
+ }
2153
+ /**
2154
+ * Pipes
2155
+ */
2156
+ if (value === "|") {
2157
+ if (extglobs.length > 0) extglobs[extglobs.length - 1].conditions++;
2158
+ push({
2159
+ type: "text",
2160
+ value
2161
+ });
2162
+ continue;
2163
+ }
2164
+ /**
2165
+ * Commas
2166
+ */
2167
+ if (value === ",") {
2168
+ let output = value;
2169
+ const brace = braces[braces.length - 1];
2170
+ if (brace && stack[stack.length - 1] === "braces") {
2171
+ brace.comma = true;
2172
+ output = "|";
2173
+ }
2174
+ push({
2175
+ type: "comma",
2176
+ value,
2177
+ output
2178
+ });
2179
+ continue;
2180
+ }
2181
+ /**
2182
+ * Slashes
2183
+ */
2184
+ if (value === "/") {
2185
+ if (prev.type === "dot" && state.index === state.start + 1) {
2186
+ state.start = state.index + 1;
2187
+ state.consumed = "";
2188
+ state.output = "";
2189
+ tokens.pop();
2190
+ prev = bos;
2191
+ continue;
2192
+ }
2193
+ push({
2194
+ type: "slash",
2195
+ value,
2196
+ output: SLASH_LITERAL
2197
+ });
2198
+ continue;
2199
+ }
2200
+ /**
2201
+ * Dots
2202
+ */
2203
+ if (value === ".") {
2204
+ if (state.braces > 0 && prev.type === "dot") {
2205
+ if (prev.value === ".") prev.output = DOT_LITERAL;
2206
+ const brace = braces[braces.length - 1];
2207
+ prev.type = "dots";
2208
+ prev.output += value;
2209
+ prev.value += value;
2210
+ brace.dots = true;
2211
+ continue;
2212
+ }
2213
+ if (state.braces + state.parens === 0 && prev.type !== "bos" && prev.type !== "slash") {
2214
+ push({
2215
+ type: "text",
2216
+ value,
2217
+ output: DOT_LITERAL
2218
+ });
2219
+ continue;
2220
+ }
2221
+ push({
2222
+ type: "dot",
2223
+ value,
2224
+ output: DOT_LITERAL
2225
+ });
2226
+ continue;
2227
+ }
2228
+ /**
2229
+ * Question marks
2230
+ */
2231
+ if (value === "?") {
2232
+ if (!(prev && prev.value === "(") && opts.noextglob !== true && peek() === "(" && peek(2) !== "?") {
2233
+ extglobOpen("qmark", value);
2234
+ continue;
2235
+ }
2236
+ if (prev && prev.type === "paren") {
2237
+ const next = peek();
2238
+ let output = value;
2239
+ if (prev.value === "(" && !/[!=<:]/.test(next) || next === "<" && !/<([!=]|\w+>)/.test(remaining())) output = `\\${value}`;
2240
+ push({
2241
+ type: "text",
2242
+ value,
2243
+ output
2244
+ });
2245
+ continue;
2246
+ }
2247
+ if (opts.dot !== true && (prev.type === "slash" || prev.type === "bos")) {
2248
+ push({
2249
+ type: "qmark",
2250
+ value,
2251
+ output: QMARK_NO_DOT
2252
+ });
2253
+ continue;
2254
+ }
2255
+ push({
2256
+ type: "qmark",
2257
+ value,
2258
+ output: QMARK
2259
+ });
2260
+ continue;
2261
+ }
2262
+ /**
2263
+ * Exclamation
2264
+ */
2265
+ if (value === "!") {
2266
+ if (opts.noextglob !== true && peek() === "(") {
2267
+ if (peek(2) !== "?" || !/[!=<:]/.test(peek(3))) {
2268
+ extglobOpen("negate", value);
2269
+ continue;
2270
+ }
2271
+ }
2272
+ if (opts.nonegate !== true && state.index === 0) {
2273
+ negate();
2274
+ continue;
2275
+ }
2276
+ }
2277
+ /**
2278
+ * Plus
2279
+ */
2280
+ if (value === "+") {
2281
+ if (opts.noextglob !== true && peek() === "(" && peek(2) !== "?") {
2282
+ extglobOpen("plus", value);
2283
+ continue;
2284
+ }
2285
+ if (prev && prev.value === "(" || opts.regex === false) {
2286
+ push({
2287
+ type: "plus",
2288
+ value,
2289
+ output: PLUS_LITERAL
2290
+ });
2291
+ continue;
2292
+ }
2293
+ if (prev && (prev.type === "bracket" || prev.type === "paren" || prev.type === "brace") || state.parens > 0) {
2294
+ push({
2295
+ type: "plus",
2296
+ value
2297
+ });
2298
+ continue;
2299
+ }
2300
+ push({
2301
+ type: "plus",
2302
+ value: PLUS_LITERAL
2303
+ });
2304
+ continue;
2305
+ }
2306
+ /**
2307
+ * Plain text
2308
+ */
2309
+ if (value === "@") {
2310
+ if (opts.noextglob !== true && peek() === "(" && peek(2) !== "?") {
2311
+ push({
2312
+ type: "at",
2313
+ extglob: true,
2314
+ value,
2315
+ output: ""
2316
+ });
2317
+ continue;
2318
+ }
2319
+ push({
2320
+ type: "text",
2321
+ value
2322
+ });
2323
+ continue;
2324
+ }
2325
+ /**
2326
+ * Plain text
2327
+ */
2328
+ if (value !== "*") {
2329
+ if (value === "$" || value === "^") value = `\\${value}`;
2330
+ const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
2331
+ if (match) {
2332
+ value += match[0];
2333
+ state.index += match[0].length;
2334
+ }
2335
+ push({
2336
+ type: "text",
2337
+ value
2338
+ });
2339
+ continue;
2340
+ }
2341
+ /**
2342
+ * Stars
2343
+ */
2344
+ if (prev && (prev.type === "globstar" || prev.star === true)) {
2345
+ prev.type = "star";
2346
+ prev.star = true;
2347
+ prev.value += value;
2348
+ prev.output = star;
2349
+ state.backtrack = true;
2350
+ state.globstar = true;
2351
+ consume(value);
2352
+ continue;
2353
+ }
2354
+ let rest = remaining();
2355
+ if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
2356
+ extglobOpen("star", value);
2357
+ continue;
2358
+ }
2359
+ if (prev.type === "star") {
2360
+ if (opts.noglobstar === true) {
2361
+ consume(value);
2362
+ continue;
2363
+ }
2364
+ const prior = prev.prev;
2365
+ const before = prior.prev;
2366
+ const isStart = prior.type === "slash" || prior.type === "bos";
2367
+ const afterStar = before && (before.type === "star" || before.type === "globstar");
2368
+ if (opts.bash === true && (!isStart || rest[0] && rest[0] !== "/")) {
2369
+ push({
2370
+ type: "star",
2371
+ value,
2372
+ output: ""
2373
+ });
2374
+ continue;
2375
+ }
2376
+ const isBrace = state.braces > 0 && (prior.type === "comma" || prior.type === "brace");
2377
+ const isExtglob = extglobs.length && (prior.type === "pipe" || prior.type === "paren");
2378
+ if (!isStart && prior.type !== "paren" && !isBrace && !isExtglob) {
2379
+ push({
2380
+ type: "star",
2381
+ value,
2382
+ output: ""
2383
+ });
2384
+ continue;
2385
+ }
2386
+ while (rest.slice(0, 3) === "/**") {
2387
+ const after = input[state.index + 4];
2388
+ if (after && after !== "/") break;
2389
+ rest = rest.slice(3);
2390
+ consume("/**", 3);
2391
+ }
2392
+ if (prior.type === "bos" && eos()) {
2393
+ prev.type = "globstar";
2394
+ prev.value += value;
2395
+ prev.output = globstar(opts);
2396
+ state.output = prev.output;
2397
+ state.globstar = true;
2398
+ consume(value);
2399
+ continue;
2400
+ }
2401
+ if (prior.type === "slash" && prior.prev.type !== "bos" && !afterStar && eos()) {
2402
+ state.output = state.output.slice(0, -(prior.output + prev.output).length);
2403
+ prior.output = `(?:${prior.output}`;
2404
+ prev.type = "globstar";
2405
+ prev.output = globstar(opts) + (opts.strictSlashes ? ")" : "|$)");
2406
+ prev.value += value;
2407
+ state.globstar = true;
2408
+ state.output += prior.output + prev.output;
2409
+ consume(value);
2410
+ continue;
2411
+ }
2412
+ if (prior.type === "slash" && prior.prev.type !== "bos" && rest[0] === "/") {
2413
+ const end = rest[1] !== void 0 ? "|$" : "";
2414
+ state.output = state.output.slice(0, -(prior.output + prev.output).length);
2415
+ prior.output = `(?:${prior.output}`;
2416
+ prev.type = "globstar";
2417
+ prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
2418
+ prev.value += value;
2419
+ state.output += prior.output + prev.output;
2420
+ state.globstar = true;
2421
+ consume(value + advance());
2422
+ push({
2423
+ type: "slash",
2424
+ value: "/",
2425
+ output: ""
2426
+ });
2427
+ continue;
2428
+ }
2429
+ if (prior.type === "bos" && rest[0] === "/") {
2430
+ prev.type = "globstar";
2431
+ prev.value += value;
2432
+ prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
2433
+ state.output = prev.output;
2434
+ state.globstar = true;
2435
+ consume(value + advance());
2436
+ push({
2437
+ type: "slash",
2438
+ value: "/",
2439
+ output: ""
2440
+ });
2441
+ continue;
2442
+ }
2443
+ state.output = state.output.slice(0, -prev.output.length);
2444
+ prev.type = "globstar";
2445
+ prev.output = globstar(opts);
2446
+ prev.value += value;
2447
+ state.output += prev.output;
2448
+ state.globstar = true;
2449
+ consume(value);
2450
+ continue;
2451
+ }
2452
+ const token = {
2453
+ type: "star",
2454
+ value,
2455
+ output: star
2456
+ };
2457
+ if (opts.bash === true) {
2458
+ token.output = ".*?";
2459
+ if (prev.type === "bos" || prev.type === "slash") token.output = nodot + token.output;
2460
+ push(token);
2461
+ continue;
2462
+ }
2463
+ if (prev && (prev.type === "bracket" || prev.type === "paren") && opts.regex === true) {
2464
+ token.output = value;
2465
+ push(token);
2466
+ continue;
2467
+ }
2468
+ if (state.index === state.start || prev.type === "slash" || prev.type === "dot") {
2469
+ if (prev.type === "dot") {
2470
+ state.output += NO_DOT_SLASH;
2471
+ prev.output += NO_DOT_SLASH;
2472
+ } else if (opts.dot === true) {
2473
+ state.output += NO_DOTS_SLASH;
2474
+ prev.output += NO_DOTS_SLASH;
2475
+ } else {
2476
+ state.output += nodot;
2477
+ prev.output += nodot;
2478
+ }
2479
+ if (peek() !== "*") {
2480
+ state.output += ONE_CHAR;
2481
+ prev.output += ONE_CHAR;
2482
+ }
2483
+ }
2484
+ push(token);
2485
+ }
2486
+ while (state.brackets > 0) {
2487
+ if (opts.strictBrackets === true) throw new SyntaxError(syntaxError("closing", "]"));
2488
+ state.output = utils.escapeLast(state.output, "[");
2489
+ decrement("brackets");
2490
+ }
2491
+ while (state.parens > 0) {
2492
+ if (opts.strictBrackets === true) throw new SyntaxError(syntaxError("closing", ")"));
2493
+ state.output = utils.escapeLast(state.output, "(");
2494
+ decrement("parens");
2495
+ }
2496
+ while (state.braces > 0) {
2497
+ if (opts.strictBrackets === true) throw new SyntaxError(syntaxError("closing", "}"));
2498
+ state.output = utils.escapeLast(state.output, "{");
2499
+ decrement("braces");
2500
+ }
2501
+ if (opts.strictSlashes !== true && (prev.type === "star" || prev.type === "bracket")) push({
2502
+ type: "maybe_slash",
2503
+ value: "",
2504
+ output: `${SLASH_LITERAL}?`
2505
+ });
2506
+ if (state.backtrack === true) {
2507
+ state.output = "";
2508
+ for (const token of state.tokens) {
2509
+ state.output += token.output != null ? token.output : token.value;
2510
+ if (token.suffix) state.output += token.suffix;
2511
+ }
2512
+ }
2513
+ return state;
2514
+ };
2515
+ /**
2516
+ * Fast paths for creating regular expressions for common glob patterns.
2517
+ * This can significantly speed up processing and has very little downside
2518
+ * impact when none of the fast paths match.
2519
+ */
2520
+ parse.fastpaths = (input, options) => {
2521
+ const opts = { ...options };
2522
+ const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
2523
+ const len = input.length;
2524
+ if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
2525
+ input = REPLACEMENTS[input] || input;
2526
+ const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants.globChars(opts.windows);
2527
+ const nodot = opts.dot ? NO_DOTS : NO_DOT;
2528
+ const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
2529
+ const capture = opts.capture ? "" : "?:";
2530
+ const state = {
2531
+ negated: false,
2532
+ prefix: ""
2533
+ };
2534
+ let star = opts.bash === true ? ".*?" : STAR;
2535
+ if (opts.capture) star = `(${star})`;
2536
+ const globstar = (opts) => {
2537
+ if (opts.noglobstar === true) return star;
2538
+ return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
2539
+ };
2540
+ const create = (str) => {
2541
+ switch (str) {
2542
+ case "*": return `${nodot}${ONE_CHAR}${star}`;
2543
+ case ".*": return `${DOT_LITERAL}${ONE_CHAR}${star}`;
2544
+ case "*.*": return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
2545
+ case "*/*": return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
2546
+ case "**": return nodot + globstar(opts);
2547
+ case "**/*": return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
2548
+ case "**/*.*": return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
2549
+ case "**/.*": return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
2550
+ default: {
2551
+ const match = /^(.*?)\.(\w+)$/.exec(str);
2552
+ if (!match) return;
2553
+ const source = create(match[1]);
2554
+ if (!source) return;
2555
+ return source + DOT_LITERAL + match[2];
2556
+ }
2557
+ }
2558
+ };
2559
+ let source = create(utils.removePrefix(input, state));
2560
+ if (source && opts.strictSlashes !== true) source += `${SLASH_LITERAL}?`;
2561
+ return source;
2562
+ };
2563
+ module.exports = parse;
2564
+ }));
2565
+ //#endregion
2566
+ //#region ../../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/picomatch.js
2567
+ var require_picomatch = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2568
+ const scan = require_scan();
2569
+ const parse = require_parse();
2570
+ const utils = require_utils();
2571
+ const constants = require_constants();
2572
+ const isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
2573
+ /**
2574
+ * Creates a matcher function from one or more glob patterns. The
2575
+ * returned function takes a string to match as its first argument,
2576
+ * and returns true if the string is a match. The returned matcher
2577
+ * function also takes a boolean as the second argument that, when true,
2578
+ * returns an object with additional information.
2579
+ *
2580
+ * ```js
2581
+ * const picomatch = require('picomatch');
2582
+ * // picomatch(glob[, options]);
2583
+ *
2584
+ * const isMatch = picomatch('*.!(*a)');
2585
+ * console.log(isMatch('a.a')); //=> false
2586
+ * console.log(isMatch('a.b')); //=> true
2587
+ * ```
2588
+ * @name picomatch
2589
+ * @param {String|Array} `globs` One or more glob patterns.
2590
+ * @param {Object=} `options`
2591
+ * @return {Function=} Returns a matcher function.
2592
+ * @api public
2593
+ */
2594
+ const picomatch = (glob, options, returnState = false) => {
2595
+ if (Array.isArray(glob)) {
2596
+ const fns = glob.map((input) => picomatch(input, options, returnState));
2597
+ const arrayMatcher = (str) => {
2598
+ for (const isMatch of fns) {
2599
+ const state = isMatch(str);
2600
+ if (state) return state;
2601
+ }
2602
+ return false;
2603
+ };
2604
+ return arrayMatcher;
2605
+ }
2606
+ const isState = isObject(glob) && glob.tokens && glob.input;
2607
+ if (glob === "" || typeof glob !== "string" && !isState) throw new TypeError("Expected pattern to be a non-empty string");
2608
+ const opts = options || {};
2609
+ const posix = opts.windows;
2610
+ const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
2611
+ const state = regex.state;
2612
+ delete regex.state;
2613
+ let isIgnored = () => false;
2614
+ if (opts.ignore) {
2615
+ const ignoreOpts = {
2616
+ ...options,
2617
+ ignore: null,
2618
+ onMatch: null,
2619
+ onResult: null
2620
+ };
2621
+ isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
2622
+ }
2623
+ const matcher = (input, returnObject = false) => {
2624
+ const { isMatch, match, output } = picomatch.test(input, regex, options, {
2625
+ glob,
2626
+ posix
2627
+ });
2628
+ const result = {
2629
+ glob,
2630
+ state,
2631
+ regex,
2632
+ posix,
2633
+ input,
2634
+ output,
2635
+ match,
2636
+ isMatch
2637
+ };
2638
+ if (typeof opts.onResult === "function") opts.onResult(result);
2639
+ if (isMatch === false) {
2640
+ result.isMatch = false;
2641
+ return returnObject ? result : false;
2642
+ }
2643
+ if (isIgnored(input)) {
2644
+ if (typeof opts.onIgnore === "function") opts.onIgnore(result);
2645
+ result.isMatch = false;
2646
+ return returnObject ? result : false;
2647
+ }
2648
+ if (typeof opts.onMatch === "function") opts.onMatch(result);
2649
+ return returnObject ? result : true;
2650
+ };
2651
+ if (returnState) matcher.state = state;
2652
+ return matcher;
2653
+ };
2654
+ /**
2655
+ * Test `input` with the given `regex`. This is used by the main
2656
+ * `picomatch()` function to test the input string.
2657
+ *
2658
+ * ```js
2659
+ * const picomatch = require('picomatch');
2660
+ * // picomatch.test(input, regex[, options]);
2661
+ *
2662
+ * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
2663
+ * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
2664
+ * ```
2665
+ * @param {String} `input` String to test.
2666
+ * @param {RegExp} `regex`
2667
+ * @return {Object} Returns an object with matching info.
2668
+ * @api public
2669
+ */
2670
+ picomatch.test = (input, regex, options, { glob, posix } = {}) => {
2671
+ if (typeof input !== "string") throw new TypeError("Expected input to be a string");
2672
+ if (input === "") return {
2673
+ isMatch: false,
2674
+ output: ""
2675
+ };
2676
+ const opts = options || {};
2677
+ const format = opts.format || (posix ? utils.toPosixSlashes : null);
2678
+ let match = input === glob;
2679
+ let output = match && format ? format(input) : input;
2680
+ if (match === false) {
2681
+ output = format ? format(input) : input;
2682
+ match = output === glob;
2683
+ }
2684
+ if (match === false || opts.capture === true) if (opts.matchBase === true || opts.basename === true) match = picomatch.matchBase(input, regex, options, posix);
2685
+ else match = regex.exec(output);
2686
+ return {
2687
+ isMatch: Boolean(match),
2688
+ match,
2689
+ output
2690
+ };
2691
+ };
2692
+ /**
2693
+ * Match the basename of a filepath.
2694
+ *
2695
+ * ```js
2696
+ * const picomatch = require('picomatch');
2697
+ * // picomatch.matchBase(input, glob[, options]);
2698
+ * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
2699
+ * ```
2700
+ * @param {String} `input` String to test.
2701
+ * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
2702
+ * @return {Boolean}
2703
+ * @api public
2704
+ */
2705
+ picomatch.matchBase = (input, glob, options) => {
2706
+ return (glob instanceof RegExp ? glob : picomatch.makeRe(glob, options)).test(utils.basename(input));
2707
+ };
2708
+ /**
2709
+ * Returns true if **any** of the given glob `patterns` match the specified `string`.
2710
+ *
2711
+ * ```js
2712
+ * const picomatch = require('picomatch');
2713
+ * // picomatch.isMatch(string, patterns[, options]);
2714
+ *
2715
+ * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
2716
+ * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
2717
+ * ```
2718
+ * @param {String|Array} str The string to test.
2719
+ * @param {String|Array} patterns One or more glob patterns to use for matching.
2720
+ * @param {Object} [options] See available [options](#options).
2721
+ * @return {Boolean} Returns true if any patterns match `str`
2722
+ * @api public
2723
+ */
2724
+ picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
2725
+ /**
2726
+ * Parse a glob pattern to create the source string for a regular
2727
+ * expression.
2728
+ *
2729
+ * ```js
2730
+ * const picomatch = require('picomatch');
2731
+ * const result = picomatch.parse(pattern[, options]);
2732
+ * ```
2733
+ * @param {String} `pattern`
2734
+ * @param {Object} `options`
2735
+ * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
2736
+ * @api public
2737
+ */
2738
+ picomatch.parse = (pattern, options) => {
2739
+ if (Array.isArray(pattern)) return pattern.map((p) => picomatch.parse(p, options));
2740
+ return parse(pattern, {
2741
+ ...options,
2742
+ fastpaths: false
2743
+ });
2744
+ };
2745
+ /**
2746
+ * Scan a glob pattern to separate the pattern into segments.
2747
+ *
2748
+ * ```js
2749
+ * const picomatch = require('picomatch');
2750
+ * // picomatch.scan(input[, options]);
2751
+ *
2752
+ * const result = picomatch.scan('!./foo/*.js');
2753
+ * console.log(result);
2754
+ * { prefix: '!./',
2755
+ * input: '!./foo/*.js',
2756
+ * start: 3,
2757
+ * base: 'foo',
2758
+ * glob: '*.js',
2759
+ * isBrace: false,
2760
+ * isBracket: false,
2761
+ * isGlob: true,
2762
+ * isExtglob: false,
2763
+ * isGlobstar: false,
2764
+ * negated: true }
2765
+ * ```
2766
+ * @param {String} `input` Glob pattern to scan.
2767
+ * @param {Object} `options`
2768
+ * @return {Object} Returns an object with
2769
+ * @api public
2770
+ */
2771
+ picomatch.scan = (input, options) => scan(input, options);
2772
+ /**
2773
+ * Compile a regular expression from the `state` object returned by the
2774
+ * [parse()](#parse) method.
2775
+ *
2776
+ * ```js
2777
+ * const picomatch = require('picomatch');
2778
+ * const state = picomatch.parse('*.js');
2779
+ * // picomatch.compileRe(state[, options]);
2780
+ *
2781
+ * console.log(picomatch.compileRe(state));
2782
+ * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2783
+ * ```
2784
+ * @param {Object} `state`
2785
+ * @param {Object} `options`
2786
+ * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
2787
+ * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
2788
+ * @return {RegExp}
2789
+ * @api public
2790
+ */
2791
+ picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
2792
+ if (returnOutput === true) return state.output;
2793
+ const opts = options || {};
2794
+ const prepend = opts.contains ? "" : "^";
2795
+ const append = opts.contains ? "" : "$";
2796
+ let source = `${prepend}(?:${state.output})${append}`;
2797
+ if (state && state.negated === true) source = `^(?!${source}).*$`;
2798
+ const regex = picomatch.toRegex(source, options);
2799
+ if (returnState === true) regex.state = state;
2800
+ return regex;
2801
+ };
2802
+ /**
2803
+ * Create a regular expression from a parsed glob pattern.
2804
+ *
2805
+ * ```js
2806
+ * const picomatch = require('picomatch');
2807
+ * // picomatch.makeRe(state[, options]);
2808
+ *
2809
+ * const result = picomatch.makeRe('*.js');
2810
+ * console.log(result);
2811
+ * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2812
+ * ```
2813
+ * @param {String} `state` The object returned from the `.parse` method.
2814
+ * @param {Object} `options`
2815
+ * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
2816
+ * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
2817
+ * @return {RegExp} Returns a regex created from the given pattern.
2818
+ * @api public
2819
+ */
2820
+ picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
2821
+ if (!input || typeof input !== "string") throw new TypeError("Expected a non-empty string");
2822
+ let parsed = {
2823
+ negated: false,
2824
+ fastpaths: true
2825
+ };
2826
+ if (options.fastpaths !== false && (input[0] === "." || input[0] === "*")) parsed.output = parse.fastpaths(input, options);
2827
+ if (!parsed.output) parsed = parse(input, options);
2828
+ return picomatch.compileRe(parsed, options, returnOutput, returnState);
2829
+ };
2830
+ /**
2831
+ * Create a regular expression from the given regex source string.
2832
+ *
2833
+ * ```js
2834
+ * const picomatch = require('picomatch');
2835
+ * // picomatch.toRegex(source[, options]);
2836
+ *
2837
+ * const { output } = picomatch.parse('*.js');
2838
+ * console.log(picomatch.toRegex(output));
2839
+ * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2840
+ * ```
2841
+ * @param {String} `source` Regular expression source string.
2842
+ * @param {Object} `options`
2843
+ * @return {RegExp}
2844
+ * @api public
2845
+ */
2846
+ picomatch.toRegex = (source, options) => {
2847
+ try {
2848
+ const opts = options || {};
2849
+ return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
2850
+ } catch (err) {
2851
+ if (options && options.debug === true) throw err;
2852
+ return /$^/;
2853
+ }
2854
+ };
2855
+ /**
2856
+ * Picomatch constants.
2857
+ * @return {Object}
2858
+ */
2859
+ picomatch.constants = constants;
2860
+ /**
2861
+ * Expose "picomatch"
2862
+ */
2863
+ module.exports = picomatch;
2864
+ }));
2865
+ //#endregion
2866
+ //#region lib/types/client/tab-registry.js
2867
+ var import_posix = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
2868
+ module.exports = require_picomatch();
2869
+ })))(), 1);
2870
+ /** Rank of each band, highest first. */
2871
+ const RANKS = {
2872
+ extension: 3,
2873
+ builtin: 2,
2874
+ fallback: 1
2875
+ };
2876
+ /** The band a definition that names none is in. */
2877
+ const DEFAULT_BAND = "extension";
2878
+ /**
2879
+ * Whether a band may join a held kind: an `extension` and a `builtin` pair up
2880
+ * once, and a `fallback` shares its kind with nothing.
2881
+ */
2882
+ function coexists(slot, band) {
2883
+ return band !== "fallback" && slot.inForce.band !== "fallback" && slot.inForce.band !== band && slot.shadowed === void 0;
2884
+ }
2885
+ /**
2886
+ * The address's URI path: what a pattern with no scheme separator matches
2887
+ * against. `dsh-resource://file/session/s1/home/me/b.md` gives `/session/s1/home/me/b.md`;
2888
+ * `sidebar://guide` gives `''`; an address that is not a URI gives nothing.
2889
+ */
2890
+ function pathOf(address) {
2891
+ try {
2892
+ return new URL(address).pathname;
2893
+ } catch {
2894
+ return;
2895
+ }
2896
+ }
2897
+ /** Compile one declared pattern into the test the router runs. */
2898
+ function matcherFor(pattern) {
2899
+ const whole = pattern.includes(":");
2900
+ const match = (0, import_posix.default)(pattern, {
2901
+ nocase: true,
2902
+ dot: true,
2903
+ ...whole ? {} : { basename: true }
2904
+ });
2905
+ return (address) => {
2906
+ if (whole) return match(address);
2907
+ const path = pathOf(address);
2908
+ return path !== void 0 && match(path);
2909
+ };
2910
+ }
2911
+ /**
2912
+ * The registered tab types.
2913
+ *
2914
+ * Registration order is part of the contract: it breaks ties between types that
2915
+ * recognize an address equally well.
2916
+ */
2917
+ var SidebarRightTabRegistry = class {
2918
+ ctx;
2919
+ kinds = /* @__PURE__ */ new Map();
2920
+ ids = /* @__PURE__ */ new Set();
2921
+ listeners = /* @__PURE__ */ new Set();
2922
+ registrations = 0;
2923
+ cached = [];
2924
+ guideEntries = [];
2925
+ /** @param ctx - Context whose effects own the contributed types. */
2926
+ constructor(ctx) {
2927
+ this.ctx = ctx;
2928
+ }
2929
+ /**
2930
+ * Register one tab type for the caller's lifetime.
2931
+ *
2932
+ * The caller holds the returned disposer inside its own `ctx.effect`, so a
2933
+ * type's registration lives exactly as long as the plugin that contributed it.
2934
+ * An `extension` may register a kind a `builtin` already holds and takes it
2935
+ * over until it unregisters; a second registration in the same band, or any
2936
+ * registration meeting a `fallback` of the same kind, is a wiring mistake, and
2937
+ * so is an `id` already in use.
2938
+ * @param definition - the contributed type.
2939
+ * @returns idempotent disposer.
2940
+ * @throws when the id is taken, or the kind is already registered in a way this one cannot coexist with.
2941
+ */
2942
+ register(definition) {
2943
+ const { id, kind } = definition;
2944
+ const band = definition.priority ?? DEFAULT_BAND;
2945
+ if (this.ids.has(id)) throw new Error(`sidebarRight: tab type id "${id}" is already registered`);
2946
+ const held = this.kinds.get(kind);
2947
+ if (held !== void 0 && !coexists(held, band)) throw new Error(`sidebarRight: tab kind "${kind}" is already registered (${held.inForce.band})`);
2948
+ this.registrations += 1;
2949
+ const entry = {
2950
+ definition,
2951
+ band,
2952
+ matchers: (definition.patterns ?? []).map((pattern) => ({
2953
+ pattern,
2954
+ test: matcherFor(pattern)
2955
+ })),
2956
+ order: this.registrations
2957
+ };
2958
+ const dispose = this.ctx.effect(() => {
2959
+ this.ids.add(id);
2960
+ const slot = this.enter(kind, entry);
2961
+ this.refresh();
2962
+ return () => {
2963
+ this.ids.delete(id);
2964
+ this.leave(kind, slot, entry);
2965
+ this.refresh();
2966
+ };
2967
+ }, `sidebarRight.tabs.register(${JSON.stringify(id)})`);
2968
+ return () => {
2969
+ dispose();
2970
+ };
2971
+ }
2972
+ /** Add a registration to its kind's slot, the higher band in force; `coexists` has already admitted it. */
2973
+ enter(kind, entry) {
2974
+ const held = this.kinds.get(kind);
2975
+ if (held === void 0) {
2976
+ const slot = {
2977
+ inForce: entry,
2978
+ shadowed: void 0
2979
+ };
2980
+ this.kinds.set(kind, slot);
2981
+ return slot;
2982
+ }
2983
+ if (RANKS[entry.band] > RANKS[held.inForce.band]) {
2984
+ held.shadowed = held.inForce;
2985
+ held.inForce = entry;
2986
+ } else held.shadowed = entry;
2987
+ return held;
2988
+ }
2989
+ /** Remove a registration from its kind's slot: a shadowed builtin resumes, and an emptied kind is freed. */
2990
+ leave(kind, slot, entry) {
2991
+ if (slot.inForce !== entry) slot.shadowed = void 0;
2992
+ else if (slot.shadowed === void 0) this.kinds.delete(kind);
2993
+ else {
2994
+ slot.inForce = slot.shadowed;
2995
+ slot.shadowed = void 0;
2996
+ }
2997
+ }
2998
+ /** Every kind's registration in force, in registration order. */
2999
+ active() {
3000
+ return [...this.kinds.values()].map((slot) => slot.inForce).sort((left, right) => left.order - right.order);
3001
+ }
3002
+ /**
3003
+ * Registered types in registration order.
3004
+ * @returns reference-stable entries.
3005
+ */
3006
+ entries() {
3007
+ return this.cached;
3008
+ }
3009
+ /**
3010
+ * Every type in force's guide entries, in `order`, each naming the kind it opens.
3011
+ * @returns reference-stable entries.
3012
+ */
3013
+ guide() {
3014
+ return this.guideEntries;
3015
+ }
3016
+ /**
3017
+ * The type in force for a kind.
3018
+ * @param kind - the type discriminator.
3019
+ * @returns the type, or `undefined` when nothing registered it.
3020
+ */
3021
+ get(kind) {
3022
+ return this.kinds.get(kind)?.inForce.definition;
3023
+ }
3024
+ /**
3025
+ * Every type that would open an address, best first.
3026
+ *
3027
+ * Ranked by priority band, then by the length of the pattern that matched,
3028
+ * then by registration order. Types whose `canOpen` vetoes are absent.
3029
+ * @param address - the address a caller wants opened.
3030
+ * @returns the ranked types; empty when nothing recognizes the address.
3031
+ */
3032
+ candidates(address) {
3033
+ const ranked = [];
3034
+ for (const { definition, band, matchers, order } of this.active()) {
3035
+ let length = -1;
3036
+ for (const matcher of matchers) if (matcher.test(address) && matcher.pattern.length > length) length = matcher.pattern.length;
3037
+ if (length < 0) continue;
3038
+ if (definition.canOpen !== void 0 && !definition.canOpen(address)) continue;
3039
+ ranked.push({
3040
+ definition,
3041
+ rank: RANKS[band],
3042
+ length,
3043
+ order
3044
+ });
3045
+ }
3046
+ ranked.sort((left, right) => right.rank - left.rank || right.length - left.length || left.order - right.order);
3047
+ return ranked.map((entry) => entry.definition);
3048
+ }
3049
+ /**
3050
+ * Decide which type opens an address, and as what.
3051
+ *
3052
+ * Without `kind`, the best candidate wins. With `kind`, that type opens the
3053
+ * address if its `canOpen` agrees — its globs are not consulted, because
3054
+ * naming the type IS the decision.
3055
+ *
3056
+ * An address no type will open is a wiring mistake, not a user error, so this
3057
+ * throws rather than reporting absence.
3058
+ * @param address - the address a caller wants opened.
3059
+ * @param kind - a type named by the caller, overriding the ranking.
3060
+ * @returns the claiming type and the record to open.
3061
+ */
3062
+ claim(address, kind) {
3063
+ if (kind !== void 0) {
3064
+ const definition = this.get(kind);
3065
+ if (definition === void 0) throw new Error(`sidebarRight: no tab type is registered as "${kind}"`);
3066
+ if (definition.canOpen !== void 0 && !definition.canOpen(address)) throw new Error(`sidebarRight: tab type "${kind}" refuses "${address}"`);
3067
+ return {
3068
+ kind,
3069
+ contentId: address,
3070
+ title: definition.title(address)
3071
+ };
3072
+ }
3073
+ const [chosen] = this.candidates(address);
3074
+ if (chosen === void 0) throw new Error(`sidebarRight: no registered tab type claims "${address}"`);
3075
+ return {
3076
+ kind: chosen.kind,
3077
+ contentId: address,
3078
+ title: chosen.title(address)
3079
+ };
3080
+ }
3081
+ /**
3082
+ * Observe low-frequency registry changes.
3083
+ * @param listener - synchronous invalidation callback.
3084
+ * @returns unsubscribe callback.
3085
+ */
3086
+ subscribe(listener) {
3087
+ this.listeners.add(listener);
3088
+ return () => {
3089
+ this.listeners.delete(listener);
3090
+ };
3091
+ }
3092
+ refresh() {
3093
+ this.cached = this.active().map((entry) => entry.definition);
3094
+ this.guideEntries = this.cached.flatMap((definition) => (definition.guide ?? []).map((entry) => ({
3095
+ ...entry,
3096
+ kind: definition.kind
3097
+ }))).sort((left, right) => left.order - right.order);
3098
+ (0, _deepseek_ai_dsh_client_store.notifySubscribers)(this.listeners, "[ui-sidebar-right] tab registry");
3099
+ }
3100
+ };
3101
+ //#endregion
3102
+ //#region lib/types/client/stores.js
3103
+ /**
3104
+ * The store shell over the docking kit: one surface per session, held as plain
3105
+ * data so the kit's pure functions are the only thing that ever computes a
3106
+ * layout.
3107
+ *
3108
+ * Every action follows the same steps — mint the ids the intent needs, ask the
3109
+ * kit's planner what operations carry it out, let the settle planner keep every
3110
+ * pane populated, record it all as one history entry — and then assigns the
3111
+ * session's whole surface back in one go. Nothing here reaches into a draft to
3112
+ * edit a layout in place, which is what keeps the kit testable without a store
3113
+ * and keeps snapshot identity honest.
3114
+ *
3115
+ * The settle step is this product's rule, not the kit's: a docked pane never
3116
+ * stays empty, and the last pane reseeds the guide tab, so there is always at
3117
+ * least one tab to look at.
3118
+ *
3119
+ * A focus that changes nothing — a tab already active in its already-active
3120
+ * pane, a pane already active — plans nothing and records nothing, whoever
3121
+ * asks: the kit's chip click and `ctx.sidebarRight.focus` alike.
3122
+ *
3123
+ * So is the guide's uniqueness: a pane holds at most one guide tab. Opening the
3124
+ * guide into a pane that has one focuses it, and a guide dragged, dropped, or
3125
+ * docked into such a pane merges into it — the arriving guide closes and the
3126
+ * pane's own is focused. The kit plans none of this; it is decided here before
3127
+ * its planners run.
3128
+ */
3129
+ /** A mint that counts, so the surface can carry its position forward. */
3130
+ function counting(from) {
3131
+ let counter = from;
3132
+ const mint = ((prefix) => {
3133
+ counter += 1;
3134
+ return `${prefix}${counter}`;
3135
+ });
3136
+ return {
3137
+ mint,
3138
+ used: () => counter
3139
+ };
3140
+ }
3141
+ /**
3142
+ * The surface a session starts with: collapsed, one pane, one guide tab.
3143
+ * @param seedTitle - the guide type's display name at mint time.
3144
+ * @returns the initial surface.
3145
+ */
3146
+ function createSurface(seedTitle) {
3147
+ const counter = counting(0);
3148
+ return {
3149
+ layout: (0, _deepseek_ai_dsh_client_ui_dockkit.createInitialState)({ next: counter.mint }, (id) => makeGuideTab(id, seedTitle())),
3150
+ history: _deepseek_ai_dsh_client_ui_dockkit.EMPTY_HISTORY,
3151
+ minted: counter.used()
3152
+ };
3153
+ }
3154
+ /** The guide tab a pane holds, if any. */
3155
+ function paneGuide(state, paneId) {
3156
+ return (0, _deepseek_ai_dsh_client_ui_dockkit.findPaneContentTab)(state, paneId, pageAddress(GUIDE_KIND), GUIDE_KIND);
3157
+ }
3158
+ /** Whether a tab is the guide, which a pane holds at most once and which is therefore never copied. */
3159
+ function isGuide(state, tabId) {
3160
+ return state.tabs[tabId]?.kind === GUIDE_KIND;
3161
+ }
3162
+ /** Focus a tab: nothing to plan while it is its pane's active tab and its pane is the active one. */
3163
+ function planFocusTab(state, tabId) {
3164
+ const pane = (0, _deepseek_ai_dsh_client_ui_dockkit.findTabPane)(state, tabId);
3165
+ return pane.activeTabId === tabId && state.activePaneId === pane.id ? [] : [{
3166
+ type: "focusTab",
3167
+ tabId
3168
+ }];
3169
+ }
3170
+ /** Focus a pane: nothing to plan while it is the active one. */
3171
+ function planFocusPane(state, paneId) {
3172
+ return state.activePaneId === paneId ? [] : [{
3173
+ type: "focusPane",
3174
+ paneId
3175
+ }];
3176
+ }
3177
+ /**
3178
+ * Plan a tab's arrival in a docked pane: a guide arriving where one already is
3179
+ * merges into it, anything else plans as the kit does.
3180
+ * @param state - current layout.
3181
+ * @param tabId - the arriving tab.
3182
+ * @param toPaneId - the pane it arrives in.
3183
+ * @param otherwise - the kit's plan for the move.
3184
+ * @returns the operations.
3185
+ */
3186
+ function arriving(state, tabId, toPaneId, otherwise) {
3187
+ if (!isGuide(state, tabId)) return otherwise();
3188
+ const existing = paneGuide(state, toPaneId);
3189
+ if (existing === void 0 || existing === tabId) return otherwise();
3190
+ return [{
3191
+ type: "closeTab",
3192
+ tabId
3193
+ }, {
3194
+ type: "focusTab",
3195
+ tabId: existing
3196
+ }];
3197
+ }
3198
+ /**
3199
+ * Run one planner against a surface, settle what it left behind, and record the
3200
+ * whole intent as one history entry.
3201
+ * @param surface - the session's current surface.
3202
+ * @param plan - the kit planner to consult.
3203
+ * @param seedTitle - the guide type's display name, for a reseeded root pane.
3204
+ * @returns the next surface, or the same one when the intent changes nothing.
3205
+ */
3206
+ function advance(surface, plan, seedTitle) {
3207
+ const counter = counting(surface.minted);
3208
+ const planned = plan(surface.layout, counter.mint);
3209
+ if (planned.length === 0) return surface;
3210
+ const settled = (0, _deepseek_ai_dsh_client_ui_dockkit.planSettle)((0, _deepseek_ai_dsh_client_ui_dockkit.replay)(surface.layout, planned), counter.mint, (id) => makeGuideTab(id, seedTitle()));
3211
+ const stepped = (0, _deepseek_ai_dsh_client_ui_dockkit.record)(surface.history, surface.layout, [...planned, ...settled]);
3212
+ return {
3213
+ layout: stepped.state,
3214
+ history: stepped.history,
3215
+ minted: counter.used()
3216
+ };
3217
+ }
3218
+ /**
3219
+ * Replace one session's surface, leaving every other session by reference.
3220
+ *
3221
+ * A session with no surface yet gets its initial one even when the intent
3222
+ * changes nothing: materializing is itself the change.
3223
+ */
3224
+ function seat(state, sessionId, seedTitle, next) {
3225
+ const existing = state.bySession[sessionId];
3226
+ const updated = next(existing ?? createSurface(seedTitle));
3227
+ return updated === existing ? state.bySession : {
3228
+ ...state.bySession,
3229
+ [sessionId]: updated
3230
+ };
3231
+ }
3232
+ /** Step a surface through the history in one direction. */
3233
+ function stepped(surface, step) {
3234
+ const moved = step(surface.history, surface.layout);
3235
+ return moved === void 0 ? surface : {
3236
+ ...surface,
3237
+ layout: moved.state,
3238
+ history: moved.history
3239
+ };
3240
+ }
3241
+ /**
3242
+ * Create the Sidebar store handle.
3243
+ *
3244
+ * The seed title arrives as a thunk rather than a string: a pane is seeded
3245
+ * whenever one is created, which can be long after the store was built and in a
3246
+ * language the user has since changed to.
3247
+ * @param seedTitle - the guide type's display name, read at each mint.
3248
+ * @returns the handle (spec, type, identity, and factory in one).
3249
+ */
3250
+ function createSidebarRightStore(seedTitle) {
3251
+ return (0, _deepseek_ai_dsh_client_store.defineStore)({
3252
+ init: () => ({ bySession: {} }),
3253
+ actions: {
3254
+ open: (d, sessionId) => {
3255
+ d.bySession = seat(d, sessionId, seedTitle, (surface) => surface);
3256
+ },
3257
+ setExpanded: (d, sessionId, expanded) => {
3258
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => (0, _deepseek_ai_dsh_client_ui_dockkit.planSetExpanded)(state, expanded), seedTitle));
3259
+ },
3260
+ toggleExpanded: (d, sessionId) => {
3261
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => (0, _deepseek_ai_dsh_client_ui_dockkit.planSetExpanded)(state, !state.expanded), seedTitle));
3262
+ },
3263
+ setMode: (d, sessionId, mode) => {
3264
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => (0, _deepseek_ai_dsh_client_ui_dockkit.planSetMode)(state, mode), seedTitle));
3265
+ },
3266
+ splitPane: (d, sessionId, paneId, settled) => {
3267
+ d.bySession = seat(d, sessionId, seedTitle, (s) => {
3268
+ const next = advance(s, (state, mint) => (0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(state).length >= 2 ? [] : (0, _deepseek_ai_dsh_client_ui_dockkit.planSplitPane)(state, mint, paneId, (id) => makeGuideTab(id, seedTitle())), seedTitle);
3269
+ if (settled !== void 0 && next !== s) {
3270
+ const before = new Set((0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(s.layout));
3271
+ for (const id of (0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(next.layout)) if (!before.has(id)) settled(id);
3272
+ }
3273
+ return next;
3274
+ });
3275
+ },
3276
+ openContent: (d, sessionId, intent, settled) => {
3277
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state, mint) => {
3278
+ const { kind, contentId, title, replaceTab: replace } = intent;
3279
+ const ops = [...(0, _deepseek_ai_dsh_client_ui_dockkit.planSetExpanded)(state, true)];
3280
+ const replaced = replace === void 0 ? void 0 : (0, _deepseek_ai_dsh_client_ui_dockkit.findTabPane)(state, replace);
3281
+ const lent = replace !== void 0 && replaced !== void 0 && replaced.host === "dock" ? replaced : void 0;
3282
+ const paneId = lent?.id ?? intent.paneId;
3283
+ const index = lent === void 0 || replace === void 0 ? void 0 : lent.tabs.indexOf(replace);
3284
+ const held = kind === "guide" ? paneGuide(state, paneId ?? (0, _deepseek_ai_dsh_client_ui_dockkit.activeDockPaneId)(state)) : void 0;
3285
+ const planned = held !== void 0 ? {
3286
+ ops: [{
3287
+ type: "focusTab",
3288
+ tabId: held
3289
+ }],
3290
+ tabId: held
3291
+ } : (0, _deepseek_ai_dsh_client_ui_dockkit.planOpenContent)(state, mint, {
3292
+ kind,
3293
+ contentId,
3294
+ title,
3295
+ ...paneId === void 0 ? {} : { paneId },
3296
+ ...index === void 0 ? {} : { index },
3297
+ ...intent.revealIfOpened === void 0 ? {} : { revealIfOpened: intent.revealIfOpened }
3298
+ });
3299
+ ops.push(...planned.ops);
3300
+ if (replace !== void 0 && replace !== planned.tabId) ops.push({
3301
+ type: "closeTab",
3302
+ tabId: replace
3303
+ });
3304
+ settled(planned.tabId);
3305
+ return ops;
3306
+ }, seedTitle));
3307
+ },
3308
+ duplicateTab: (d, sessionId, tabId) => {
3309
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state, mint) => isGuide(state, tabId) ? [] : (0, _deepseek_ai_dsh_client_ui_dockkit.planDuplicateTab)(state, mint, tabId).ops, seedTitle));
3310
+ },
3311
+ closeTab: (d, sessionId, tabId) => {
3312
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => state.tabs[tabId] === void 0 ? [] : [{
3313
+ type: "closeTab",
3314
+ tabId
3315
+ }], seedTitle));
3316
+ },
3317
+ focusTab: (d, sessionId, tabId) => {
3318
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => planFocusTab(state, tabId), seedTitle));
3319
+ },
3320
+ focusPane: (d, sessionId, paneId) => {
3321
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => planFocusPane(state, paneId), seedTitle));
3322
+ },
3323
+ placeTab: (d, sessionId, tabId, toPaneId, index) => {
3324
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => arriving(state, tabId, toPaneId, () => (0, _deepseek_ai_dsh_client_ui_dockkit.planPlaceTab)(state, tabId, toPaneId, index)), seedTitle));
3325
+ },
3326
+ dropTab: (d, sessionId, tabId, paneId, zone) => {
3327
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state, mint) => {
3328
+ if (zone === "top" || zone === "bottom") return [];
3329
+ if (zone !== "center" && (0, _deepseek_ai_dsh_client_ui_dockkit.dockPaneIds)(state).length >= 2) return [];
3330
+ const plan = () => (0, _deepseek_ai_dsh_client_ui_dockkit.planDropTab)(state, mint, tabId, paneId, zone);
3331
+ return zone === "center" ? arriving(state, tabId, paneId, plan) : plan();
3332
+ }, seedTitle));
3333
+ },
3334
+ floatTab: (d, sessionId, tabId, rect) => {
3335
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state, mint) => (0, _deepseek_ai_dsh_client_ui_dockkit.planFloatTab)(state, mint, tabId, rect).ops, seedTitle));
3336
+ },
3337
+ unfloatPane: (d, sessionId, paneId) => {
3338
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, (state) => {
3339
+ const guide = paneGuide(state, paneId);
3340
+ const plan = () => (0, _deepseek_ai_dsh_client_ui_dockkit.planUnfloatPane)(state, paneId);
3341
+ return guide === void 0 ? plan() : arriving(state, guide, (0, _deepseek_ai_dsh_client_ui_dockkit.activeDockPaneId)(state), plan);
3342
+ }, seedTitle));
3343
+ },
3344
+ moveFloat: (d, sessionId, paneId, x, y) => {
3345
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, () => [{
3346
+ type: "moveFloat",
3347
+ paneId,
3348
+ x,
3349
+ y
3350
+ }], seedTitle));
3351
+ },
3352
+ resizeFloat: (d, sessionId, paneId, rect) => {
3353
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, () => [{
3354
+ type: "resizeFloat",
3355
+ paneId,
3356
+ rect
3357
+ }], seedTitle));
3358
+ },
3359
+ resizeSplit: (d, sessionId, splitId, sizes) => {
3360
+ d.bySession = seat(d, sessionId, seedTitle, (s) => advance(s, () => (0, _deepseek_ai_dsh_client_ui_dockkit.planResizeSplit)(splitId, sizes, .2), seedTitle));
3361
+ },
3362
+ undo: (d, sessionId) => {
3363
+ d.bySession = seat(d, sessionId, seedTitle, (s) => stepped(s, _deepseek_ai_dsh_client_ui_dockkit.stepBack));
3364
+ },
3365
+ redo: (d, sessionId) => {
3366
+ d.bySession = seat(d, sessionId, seedTitle, (s) => stepped(s, _deepseek_ai_dsh_client_ui_dockkit.stepForward));
3367
+ }
3368
+ }
3369
+ });
3370
+ }
3371
+ //#endregion
3372
+ //#region lib/types/client/locales.js
3373
+ /**
3374
+ * `sidebarRight` namespace dictionaries.
3375
+ *
3376
+ * Everything a user reads in this column is here, including the strings handed
3377
+ * to the docking kit — the kit renders no copy of its own, so its whole
3378
+ * vocabulary is this package's to own and translate.
3379
+ */
3380
+ /** Simplified Chinese dictionary and key-set source of truth. */
3381
+ const zh = {
3382
+ "chrome.expand": "展开侧栏",
3383
+ "chrome.collapse": "收起侧栏",
3384
+ "chrome.toFullscreen": "全屏显示侧栏",
3385
+ "chrome.exitFullscreen": "退出侧栏全屏",
3386
+ "dock.emptyPane": "空面板",
3387
+ "dock.splitPane": "向右分栏",
3388
+ "dock.splitPaneDisabled": "已达两格上限",
3389
+ "dock.splitPaneNarrow": "栏宽不足,拖宽侧栏后再分栏",
3390
+ "dock.closeTab": "关闭",
3391
+ "dock.addTab": "新标签页",
3392
+ "dock.dockFloat": "收回到侧栏",
3393
+ "dock.closeFloat": "关闭",
3394
+ "tab.guide.title": "开始",
3395
+ "tab.unavailable": "这类内容还没有可用的查看方式。",
3396
+ "guide.lead": "侧栏用来放你想一直看着的东西。",
3397
+ "guide.body": "会话里的文件和产物会开在这一栏,也可以从下面的入口打开。"
3398
+ };
3399
+ /** English dictionary, checked against the Chinese key set. */
3400
+ const en = {
3401
+ "chrome.expand": "Open the sidebar",
3402
+ "chrome.collapse": "Close the sidebar",
3403
+ "chrome.toFullscreen": "Show the sidebar fullscreen",
3404
+ "chrome.exitFullscreen": "Exit sidebar fullscreen",
3405
+ "dock.emptyPane": "Empty pane",
3406
+ "dock.splitPane": "Split to the right",
3407
+ "dock.splitPaneDisabled": "Two panes is the limit",
3408
+ "dock.splitPaneNarrow": "Not enough width to split; widen the sidebar",
3409
+ "dock.closeTab": "Close",
3410
+ "dock.addTab": "New tab",
3411
+ "dock.dockFloat": "Send back to the sidebar",
3412
+ "dock.closeFloat": "Close",
3413
+ "tab.guide.title": "Start",
3414
+ "tab.unavailable": "Nothing here can view this kind of content yet.",
3415
+ "guide.lead": "The sidebar holds what you want to keep looking at.",
3416
+ "guide.body": "Files and artifacts from the conversation open in this column; the entries below open more."
3417
+ };
3418
+ //#endregion
3419
+ //#region lib/types/client/tabs/guide/definition.js
3420
+ /** The shipped guide implementation's identity: the key its body registers under. */
3421
+ const GUIDE_ID = "@deepseek-ai/dsh-client-ui-sidebar-right/guide";
3422
+ /**
3423
+ * The guide type's registry definition.
3424
+ *
3425
+ * A page type: it recognizes no resource address, because a guide views
3426
+ * nothing, and is opened by kind; `builtin` is the ordinary band for a type
3427
+ * shipped here.
3428
+ * @param t - namespace-bound translate, read fresh on every title call.
3429
+ * @returns the definition to register.
3430
+ */
3431
+ function guideDefinition(t) {
3432
+ return {
3433
+ id: GUIDE_ID,
3434
+ kind: GUIDE_KIND,
3435
+ priority: "builtin",
3436
+ title: () => t("tab.guide.title")
3437
+ };
3438
+ }
3439
+ //#endregion
3440
+ //#region lib/types/client/tab-info.js
3441
+ /** Slot-owned tab information derived from framework-bound store and navigation hooks. */
3442
+ /**
3443
+ * Bind a tab occurrence without subscribing or creating records during factory evaluation.
3444
+ * @param standard - framework session identity.
3445
+ * @param context - stable record lifetime and framework-bound readers.
3446
+ * @returns the tab information hook.
3447
+ */
3448
+ const tabInfoFactory = (standard, context) => {
3449
+ const { sessionId } = standard;
3450
+ const { tabId, title, fullscreen, signal, actions, useStore, useTabNavigation } = context;
3451
+ return function useTabInfo() {
3452
+ const layout = useStore((state) => state.bySession[sessionId]?.layout);
3453
+ const navigation = useTabNavigation(tabId);
3454
+ return (0, react.useMemo)(() => {
3455
+ const tab = layout?.tabs[tabId];
3456
+ if (layout === void 0 || tab === void 0 || navigation === void 0) throw new Error(`sidebarRight: tab "${tabId}" is not committed in session "${sessionId}"`);
3457
+ const pane = (0, _deepseek_ai_dsh_client_ui_dockkit.findTabPane)(layout, tabId);
3458
+ return {
3459
+ sidebar: {
3460
+ expanded: layout.expanded,
3461
+ fullscreen
3462
+ },
3463
+ panel: { id: pane.id },
3464
+ tab: {
3465
+ ...tab,
3466
+ visible: pane.host === "float" || layout.expanded && (title || pane.activeTabId === tabId),
3467
+ navigation,
3468
+ signal,
3469
+ actions
3470
+ }
3471
+ };
3472
+ }, [
3473
+ layout,
3474
+ navigation,
3475
+ tabId,
3476
+ title,
3477
+ fullscreen,
3478
+ signal,
3479
+ actions
3480
+ ]);
3481
+ };
3482
+ };
3483
+ /**
3484
+ * Forward the framework-bound tab hook to a guide replacement.
3485
+ * @param _standard - the guide's framework standard props.
3486
+ * @param useTabInfo - the enclosing tab's framework-bound reader.
3487
+ * @returns the same reader for the replacement.
3488
+ */
3489
+ const guideTabInfoFactory = (_standard, useTabInfo) => useTabInfo;
3490
+ //#endregion
3491
+ //#region lib/types/client/index.js
3492
+ /** This package's copy namespace. */
3493
+ const NS = "sidebarRight";
3494
+ /** Required browser services: the slot registry, the frame's panel actions, copy, and the resource model. */
3495
+ const inject = [
3496
+ "slots",
3497
+ "layout",
3498
+ "locale",
3499
+ "resources"
3500
+ ];
3501
+ /**
3502
+ * Client plugin body: provide the registry and the navigation face, register the
3503
+ * panel seat and the rail seat over one store with their extension children, and
3504
+ * register the guide type through the same public two-stage path any other type
3505
+ * uses.
3506
+ * @param ctx - client root context carrying the slot registry, the frame's face, and copy.
3507
+ */
3508
+ function apply(ctx) {
3509
+ const t = ctx.locale.bind(NS);
3510
+ const tabs = new SidebarRightTabRegistry(ctx);
3511
+ const { controller, adopt } = createSidebarRightController(tabs, (address, signal) => {
3512
+ ctx.resources.pin(address, signal);
3513
+ });
3514
+ const disposeRegistry = ctx.reflect.provide("sidebarRightTabs", tabs);
3515
+ const disposeService = ctx.reflect.provide("sidebarRight", controller);
3516
+ ctx.effect(() => () => {
3517
+ controller.tabDomain.dispose();
3518
+ disposeService();
3519
+ disposeRegistry();
3520
+ }, "ui-sidebar-right: service faces");
3521
+ ctx.effect(() => ctx.locale.register(NS, {
3522
+ zh,
3523
+ en
3524
+ }), "ui-sidebar-right: dictionaries");
3525
+ ctx.effect(() => {
3526
+ const handle = createSidebarRightStore(() => t("tab.guide.title"));
3527
+ const adoptions = [];
3528
+ const store = {
3529
+ ...handle,
3530
+ create: (scopeKey) => {
3531
+ const instance = handle.create(scopeKey);
3532
+ if (scopeKey !== void 0) adoptions.push(adopt(scopeKey, instance));
3533
+ return instance;
3534
+ }
3535
+ };
3536
+ const layout = ctx.layout;
3537
+ const injected = {
3538
+ syncPresentation({ shown, track, fullscreen }) {
3539
+ if (shown) layout.openRightbar(track, fullscreen);
3540
+ else layout.closeRightbar();
3541
+ },
3542
+ bindService: (binding) => controller.bind(binding),
3543
+ openTab: (kind, options) => {
3544
+ controller.openTab(kind, options);
3545
+ },
3546
+ hooks: { tabTypes: {
3547
+ subscribe: (listener) => tabs.subscribe(listener),
3548
+ getSnapshot: () => tabs.entries()
3549
+ } }
3550
+ };
3551
+ const disposeTypes = [tabs.register(guideDefinition(t))];
3552
+ const disposeSeat = ctx.slots.inject("rightbar", () => ctx.slots.register({
3553
+ name: "rightbar",
3554
+ locale: NS,
3555
+ children: {
3556
+ "sidebar.right.pane.tab": {
3557
+ kind: "keyed",
3558
+ scope: "session",
3559
+ inject: { hooks: { tabInfo: tabInfoFactory } }
3560
+ },
3561
+ "sidebar.right.pane.tab.title": {
3562
+ kind: "keyed",
3563
+ scope: "session",
3564
+ inject: { hooks: { tabInfo: tabInfoFactory } }
3565
+ },
3566
+ "sidebar.right.tab.menu.item": {
3567
+ kind: "list",
3568
+ scope: "session"
3569
+ }
3570
+ },
3571
+ store,
3572
+ inject: (sessionId) => ({
3573
+ ...injected,
3574
+ keyedHooks: { tabNavigation: (key) => controller.tabDomain.occurrence(sessionId, { id: key }).navigation },
3575
+ occurrence: (tab) => controller.tabDomain.occurrence(sessionId, tab)
3576
+ })
3577
+ }, RightbarSeat));
3578
+ const disposeExpand = ctx.slots.inject("conversation.session.header.corner", () => ctx.slots.register({
3579
+ name: "conversation.session.header.corner",
3580
+ locale: NS,
3581
+ store
3582
+ }, ExpandButton));
3583
+ const guideInjected = { hooks: { guideEntries: {
3584
+ subscribe: (listener) => tabs.subscribe(listener),
3585
+ getSnapshot: () => tabs.guide()
3586
+ } } };
3587
+ const disposeGuide = ctx.slots.inject("sidebar.right.pane.tab", () => ctx.slots.register({
3588
+ name: "sidebar.right.pane.tab",
3589
+ key: GUIDE_ID,
3590
+ locale: NS,
3591
+ children: { "sidebar.right.tab.guide": {
3592
+ kind: "chain",
3593
+ scope: "session",
3594
+ inject: { hooks: { tabInfo: guideTabInfoFactory } }
3595
+ } },
3596
+ inject: () => guideInjected
3597
+ }, GuideBody));
3598
+ return () => {
3599
+ disposeGuide();
3600
+ disposeExpand();
3601
+ disposeSeat();
3602
+ for (const dispose of disposeTypes.reverse()) dispose();
3603
+ for (const release of adoptions) release();
3604
+ };
3605
+ }, "ui-sidebar-right: seats and shipped tab type");
3606
+ }
3607
+ //#endregion
3608
+ exports.apply = apply;
3609
+ exports.inject = inject;
3610
+ return module.exports;
3611
+ }
3612
+ });
3613
+
3614
+ //# sourceMappingURL=client.js.map