@design.estate/dees-catalog 3.101.0 → 3.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/dist_bundle/bundle.js +1558 -979
  2. package/dist_ts_web/00_commitinfo_data.js +1 -1
  3. package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.d.ts +30 -1
  4. package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +330 -9
  5. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.d.ts +50 -0
  6. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.demo.d.ts +1 -0
  7. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.demo.js +26 -0
  8. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.js +347 -0
  9. package/dist_ts_web/elements/00group-harness/dees-terminal-view/index.d.ts +1 -0
  10. package/dist_ts_web/elements/00group-harness/dees-terminal-view/index.js +2 -0
  11. package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
  12. package/dist_ts_web/elements/00group-harness/index.js +2 -1
  13. package/dist_ts_web/elements/00group-harness/interfaces.d.ts +23 -0
  14. package/package.json +1 -1
  15. package/ts_web/00_commitinfo_data.ts +1 -1
  16. package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +336 -7
  17. package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.demo.ts +26 -0
  18. package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.ts +317 -0
  19. package/ts_web/elements/00group-harness/dees-terminal-view/index.ts +1 -0
  20. package/ts_web/elements/00group-harness/index.ts +1 -0
  21. package/ts_web/elements/00group-harness/interfaces.ts +26 -0
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '3.101.0',
6
+ version: '3.103.0',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsNkJBQTZCO0lBQ25DLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSxzSkFBc0o7Q0FDcEssQ0FBQSJ9
@@ -1,16 +1,28 @@
1
1
  import { DeesElement, type TemplateResult } from '@design.estate/dees-element';
2
- import type { IHarnessSessionMeta } from '../interfaces.js';
2
+ import type { IHarnessSessionGroup, IHarnessSessionMeta } from '../interfaces.js';
3
3
  import '../../00group-utility/dees-icon/dees-icon.js';
4
4
  declare global {
5
5
  interface HTMLElementTagNameMap {
6
6
  'dees-harness-session-list': DeesHarnessSessionList;
7
7
  }
8
8
  }
9
+ interface IDropSlot {
10
+ groupId: string | null;
11
+ index: number;
12
+ }
9
13
  /**
10
14
  * Searchable conversation list, embeddable in a sidebar or a DeesModal.
11
15
  * Emits `harness-session-select` on click, `harness-session-open` on
12
16
  * double-click or Enter, and `harness-session-context` with viewport
13
17
  * pointer coordinates on right-click (the browser menu is suppressed).
18
+ *
19
+ * With `enableGrouping`, sessions render under user-defined `groups` and can
20
+ * be dragged between groups and reordered. The component never mutates its
21
+ * inputs: drops emit `harness-session-move`, the "new group" button emits
22
+ * `harness-group-create-request`, and right-clicking a group header emits
23
+ * `harness-group-context` — the host persists changes and passes fresh
24
+ * `groups` back in. Sessions in no group render in the trailing ungrouped
25
+ * section, recency-sorted. While a search query is active the list is flat.
14
26
  */
15
27
  export declare class DeesHarnessSessionList extends DeesElement {
16
28
  static demo: () => TemplateResult<1>;
@@ -19,11 +31,28 @@ export declare class DeesHarnessSessionList extends DeesElement {
19
31
  accessor selectedSessionId: string;
20
32
  accessor loading: boolean;
21
33
  accessor emptyText: string;
34
+ accessor groups: IHarnessSessionGroup[];
35
+ accessor enableGrouping: boolean;
22
36
  accessor search: string;
37
+ accessor draggingSessionId: string;
38
+ accessor dropSlot: IDropSlot | undefined;
39
+ accessor collapsedGroupIds: ReadonlySet<string>;
23
40
  static styles: import("@design.estate/dees-element").CSSResult[];
41
+ private get sessionsById();
42
+ private get groupedSessionIds();
43
+ /** Ungrouped sessions, most recent first. */
44
+ private get ungroupedSessions();
24
45
  private get filteredSessions();
25
46
  focusSearch(): void;
26
47
  render(): TemplateResult;
48
+ private renderFlatList;
49
+ private renderGroupedList;
50
+ private renderSection;
27
51
  private renderItem;
52
+ private toggleGroupCollapsed;
53
+ private setDropSlot;
54
+ private handleDragOverSlot;
55
+ private handleDrop;
28
56
  private emit;
29
57
  }
58
+ export {};
@@ -42,6 +42,14 @@ import '../../00group-utility/dees-icon/dees-icon.js';
42
42
  * Emits `harness-session-select` on click, `harness-session-open` on
43
43
  * double-click or Enter, and `harness-session-context` with viewport
44
44
  * pointer coordinates on right-click (the browser menu is suppressed).
45
+ *
46
+ * With `enableGrouping`, sessions render under user-defined `groups` and can
47
+ * be dragged between groups and reordered. The component never mutates its
48
+ * inputs: drops emit `harness-session-move`, the "new group" button emits
49
+ * `harness-group-create-request`, and right-clicking a group header emits
50
+ * `harness-group-context` — the host persists changes and passes fresh
51
+ * `groups` back in. Sessions in no group render in the trailing ungrouped
52
+ * section, recency-sorted. While a search query is active the list is flat.
45
53
  */
46
54
  let DeesHarnessSessionList = (() => {
47
55
  let _classDecorators = [customElement('dees-harness-session-list')];
@@ -61,9 +69,24 @@ let DeesHarnessSessionList = (() => {
61
69
  let _emptyText_decorators;
62
70
  let _emptyText_initializers = [];
63
71
  let _emptyText_extraInitializers = [];
72
+ let _groups_decorators;
73
+ let _groups_initializers = [];
74
+ let _groups_extraInitializers = [];
75
+ let _enableGrouping_decorators;
76
+ let _enableGrouping_initializers = [];
77
+ let _enableGrouping_extraInitializers = [];
64
78
  let _search_decorators;
65
79
  let _search_initializers = [];
66
80
  let _search_extraInitializers = [];
81
+ let _draggingSessionId_decorators;
82
+ let _draggingSessionId_initializers = [];
83
+ let _draggingSessionId_extraInitializers = [];
84
+ let _dropSlot_decorators;
85
+ let _dropSlot_initializers = [];
86
+ let _dropSlot_extraInitializers = [];
87
+ let _collapsedGroupIds_decorators;
88
+ let _collapsedGroupIds_initializers = [];
89
+ let _collapsedGroupIds_extraInitializers = [];
67
90
  var DeesHarnessSessionList = class extends _classSuper {
68
91
  static { _classThis = this; }
69
92
  static {
@@ -72,12 +95,22 @@ let DeesHarnessSessionList = (() => {
72
95
  _selectedSessionId_decorators = [property()];
73
96
  _loading_decorators = [property({ type: Boolean })];
74
97
  _emptyText_decorators = [property()];
98
+ _groups_decorators = [property({ attribute: false })];
99
+ _enableGrouping_decorators = [property({ type: Boolean })];
75
100
  _search_decorators = [state()];
101
+ _draggingSessionId_decorators = [state()];
102
+ _dropSlot_decorators = [state()];
103
+ _collapsedGroupIds_decorators = [state()];
76
104
  __esDecorate(this, null, _sessions_decorators, { kind: "accessor", name: "sessions", static: false, private: false, access: { has: obj => "sessions" in obj, get: obj => obj.sessions, set: (obj, value) => { obj.sessions = value; } }, metadata: _metadata }, _sessions_initializers, _sessions_extraInitializers);
77
105
  __esDecorate(this, null, _selectedSessionId_decorators, { kind: "accessor", name: "selectedSessionId", static: false, private: false, access: { has: obj => "selectedSessionId" in obj, get: obj => obj.selectedSessionId, set: (obj, value) => { obj.selectedSessionId = value; } }, metadata: _metadata }, _selectedSessionId_initializers, _selectedSessionId_extraInitializers);
78
106
  __esDecorate(this, null, _loading_decorators, { kind: "accessor", name: "loading", static: false, private: false, access: { has: obj => "loading" in obj, get: obj => obj.loading, set: (obj, value) => { obj.loading = value; } }, metadata: _metadata }, _loading_initializers, _loading_extraInitializers);
79
107
  __esDecorate(this, null, _emptyText_decorators, { kind: "accessor", name: "emptyText", static: false, private: false, access: { has: obj => "emptyText" in obj, get: obj => obj.emptyText, set: (obj, value) => { obj.emptyText = value; } }, metadata: _metadata }, _emptyText_initializers, _emptyText_extraInitializers);
108
+ __esDecorate(this, null, _groups_decorators, { kind: "accessor", name: "groups", static: false, private: false, access: { has: obj => "groups" in obj, get: obj => obj.groups, set: (obj, value) => { obj.groups = value; } }, metadata: _metadata }, _groups_initializers, _groups_extraInitializers);
109
+ __esDecorate(this, null, _enableGrouping_decorators, { kind: "accessor", name: "enableGrouping", static: false, private: false, access: { has: obj => "enableGrouping" in obj, get: obj => obj.enableGrouping, set: (obj, value) => { obj.enableGrouping = value; } }, metadata: _metadata }, _enableGrouping_initializers, _enableGrouping_extraInitializers);
80
110
  __esDecorate(this, null, _search_decorators, { kind: "accessor", name: "search", static: false, private: false, access: { has: obj => "search" in obj, get: obj => obj.search, set: (obj, value) => { obj.search = value; } }, metadata: _metadata }, _search_initializers, _search_extraInitializers);
111
+ __esDecorate(this, null, _draggingSessionId_decorators, { kind: "accessor", name: "draggingSessionId", static: false, private: false, access: { has: obj => "draggingSessionId" in obj, get: obj => obj.draggingSessionId, set: (obj, value) => { obj.draggingSessionId = value; } }, metadata: _metadata }, _draggingSessionId_initializers, _draggingSessionId_extraInitializers);
112
+ __esDecorate(this, null, _dropSlot_decorators, { kind: "accessor", name: "dropSlot", static: false, private: false, access: { has: obj => "dropSlot" in obj, get: obj => obj.dropSlot, set: (obj, value) => { obj.dropSlot = value; } }, metadata: _metadata }, _dropSlot_initializers, _dropSlot_extraInitializers);
113
+ __esDecorate(this, null, _collapsedGroupIds_decorators, { kind: "accessor", name: "collapsedGroupIds", static: false, private: false, access: { has: obj => "collapsedGroupIds" in obj, get: obj => obj.collapsedGroupIds, set: (obj, value) => { obj.collapsedGroupIds = value; } }, metadata: _metadata }, _collapsedGroupIds_initializers, _collapsedGroupIds_extraInitializers);
81
114
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
82
115
  DeesHarnessSessionList = _classThis = _classDescriptor.value;
83
116
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -96,9 +129,24 @@ let DeesHarnessSessionList = (() => {
96
129
  #emptyText_accessor_storage = (__runInitializers(this, _loading_extraInitializers), __runInitializers(this, _emptyText_initializers, 'No conversations yet.'));
97
130
  get emptyText() { return this.#emptyText_accessor_storage; }
98
131
  set emptyText(value) { this.#emptyText_accessor_storage = value; }
99
- #search_accessor_storage = (__runInitializers(this, _emptyText_extraInitializers), __runInitializers(this, _search_initializers, ''));
132
+ #groups_accessor_storage = (__runInitializers(this, _emptyText_extraInitializers), __runInitializers(this, _groups_initializers, []));
133
+ get groups() { return this.#groups_accessor_storage; }
134
+ set groups(value) { this.#groups_accessor_storage = value; }
135
+ #enableGrouping_accessor_storage = (__runInitializers(this, _groups_extraInitializers), __runInitializers(this, _enableGrouping_initializers, false));
136
+ get enableGrouping() { return this.#enableGrouping_accessor_storage; }
137
+ set enableGrouping(value) { this.#enableGrouping_accessor_storage = value; }
138
+ #search_accessor_storage = (__runInitializers(this, _enableGrouping_extraInitializers), __runInitializers(this, _search_initializers, ''));
100
139
  get search() { return this.#search_accessor_storage; }
101
140
  set search(value) { this.#search_accessor_storage = value; }
141
+ #draggingSessionId_accessor_storage = (__runInitializers(this, _search_extraInitializers), __runInitializers(this, _draggingSessionId_initializers, ''));
142
+ get draggingSessionId() { return this.#draggingSessionId_accessor_storage; }
143
+ set draggingSessionId(value) { this.#draggingSessionId_accessor_storage = value; }
144
+ #dropSlot_accessor_storage = (__runInitializers(this, _draggingSessionId_extraInitializers), __runInitializers(this, _dropSlot_initializers, undefined));
145
+ get dropSlot() { return this.#dropSlot_accessor_storage; }
146
+ set dropSlot(value) { this.#dropSlot_accessor_storage = value; }
147
+ #collapsedGroupIds_accessor_storage = (__runInitializers(this, _dropSlot_extraInitializers), __runInitializers(this, _collapsedGroupIds_initializers, new Set()));
148
+ get collapsedGroupIds() { return this.#collapsedGroupIds_accessor_storage; }
149
+ set collapsedGroupIds(value) { this.#collapsedGroupIds_accessor_storage = value; }
102
150
  static styles = [
103
151
  themeDefaultStyles,
104
152
  cssManager.defaultStyles,
@@ -171,6 +219,10 @@ let DeesHarnessSessionList = (() => {
171
219
  box-shadow: inset 2px 0 0 var(--dees-color-accent-primary);
172
220
  }
173
221
 
222
+ .item.dragging {
223
+ opacity: 0.4;
224
+ }
225
+
174
226
  .itemTitle {
175
227
  display: flex;
176
228
  align-items: baseline;
@@ -186,6 +238,12 @@ let DeesHarnessSessionList = (() => {
186
238
  white-space: nowrap;
187
239
  }
188
240
 
241
+ .itemTitle .itemIcon {
242
+ flex: 0 0 auto;
243
+ align-self: center;
244
+ color: var(--dees-color-text-secondary);
245
+ }
246
+
189
247
  .itemTime {
190
248
  margin-left: auto;
191
249
  flex: 0 0 auto;
@@ -208,8 +266,103 @@ let DeesHarnessSessionList = (() => {
208
266
  font-size: var(--dees-font-control-size-sm, 12px);
209
267
  text-align: center;
210
268
  }
269
+
270
+ .groupHeader {
271
+ display: flex;
272
+ align-items: center;
273
+ gap: var(--dees-spacing-xs);
274
+ width: 100%;
275
+ margin-top: var(--dees-spacing-xs);
276
+ padding: 2px var(--dees-spacing-sm);
277
+ border: 0;
278
+ border-radius: var(--dees-radius-md);
279
+ background: transparent;
280
+ color: var(--dees-color-text-secondary);
281
+ cursor: pointer;
282
+ font-family: inherit;
283
+ font-size: var(--dees-font-caption1-size, 11px);
284
+ font-weight: 650;
285
+ text-transform: uppercase;
286
+ letter-spacing: 0.05em;
287
+ text-align: left;
288
+ }
289
+
290
+ .groupHeader:hover {
291
+ background: var(--dees-color-hover);
292
+ }
293
+
294
+ .groupHeader .chevron {
295
+ transition: transform var(--dees-transition-fast) var(--dees-ease-standard);
296
+ }
297
+
298
+ .groupHeader.collapsed .chevron {
299
+ transform: rotate(-90deg);
300
+ }
301
+
302
+ .groupHeader .groupCount {
303
+ margin-left: auto;
304
+ font-weight: 500;
305
+ text-transform: none;
306
+ letter-spacing: normal;
307
+ color: var(--dees-color-text-muted);
308
+ }
309
+
310
+ .groupHeader.dropTarget {
311
+ outline: 1px dashed var(--dees-color-accent-primary);
312
+ outline-offset: -1px;
313
+ }
314
+
315
+ .dropLine {
316
+ height: 2px;
317
+ margin: 0 var(--dees-spacing-sm);
318
+ border-radius: 1px;
319
+ background: var(--dees-color-accent-primary);
320
+ }
321
+
322
+ .newGroupRow {
323
+ flex: 0 0 auto;
324
+ padding: var(--dees-spacing-xs) var(--dees-spacing-sm) var(--dees-spacing-sm);
325
+ }
326
+
327
+ .newGroupButton {
328
+ display: flex;
329
+ align-items: center;
330
+ gap: var(--dees-spacing-xs);
331
+ width: 100%;
332
+ padding: var(--dees-spacing-xs) var(--dees-spacing-sm);
333
+ border: 1px dashed var(--dees-color-border-default);
334
+ border-radius: var(--dees-radius-md);
335
+ background: transparent;
336
+ color: var(--dees-color-text-secondary);
337
+ cursor: pointer;
338
+ font-family: inherit;
339
+ font-size: var(--dees-font-control-size-sm, 12px);
340
+ }
341
+
342
+ .newGroupButton:hover {
343
+ border-color: var(--dees-color-accent-primary);
344
+ color: var(--dees-color-text-primary);
345
+ }
211
346
  `,
212
347
  ];
348
+ get sessionsById() {
349
+ return new Map(this.sessions.map((session) => [session.id, session]));
350
+ }
351
+ get groupedSessionIds() {
352
+ const ids = new Set();
353
+ for (const group of this.groups) {
354
+ for (const id of group.sessionIds)
355
+ ids.add(id);
356
+ }
357
+ return ids;
358
+ }
359
+ /** Ungrouped sessions, most recent first. */
360
+ get ungroupedSessions() {
361
+ const grouped = this.groupedSessionIds;
362
+ return [...this.sessions]
363
+ .filter((session) => !grouped.has(session.id))
364
+ .sort((left, right) => (right.updatedAt ?? right.createdAt ?? 0) - (left.updatedAt ?? left.createdAt ?? 0));
365
+ }
213
366
  get filteredSessions() {
214
367
  const query = this.search.trim().toLowerCase();
215
368
  const sorted = [...this.sessions].sort((left, right) => (right.updatedAt ?? right.createdAt ?? 0) - (left.updatedAt ?? left.createdAt ?? 0));
@@ -221,7 +374,7 @@ let DeesHarnessSessionList = (() => {
221
374
  this.shadowRoot?.querySelector('.searchRow input')?.focus();
222
375
  }
223
376
  render() {
224
- const sessions = this.filteredSessions;
377
+ const groupingActive = this.enableGrouping && !this.search.trim();
225
378
  return html `
226
379
  <div class="searchRow">
227
380
  <input
@@ -235,17 +388,118 @@ let DeesHarnessSessionList = (() => {
235
388
  <div class="list">
236
389
  ${this.loading
237
390
  ? html `<div class="emptyNote">Loading conversations…</div>`
238
- : sessions.length
239
- ? sessions.map((session) => this.renderItem(session))
240
- : html `<div class="emptyNote">${this.sessions.length ? 'No conversations match this search.' : this.emptyText}</div>`}
391
+ : groupingActive
392
+ ? this.renderGroupedList()
393
+ : this.renderFlatList()}
241
394
  </div>
395
+ ${groupingActive
396
+ ? html `
397
+ <div class="newGroupRow">
398
+ <button
399
+ class="newGroupButton"
400
+ type="button"
401
+ @click=${() => {
402
+ this.dispatchEvent(new CustomEvent('harness-group-create-request', {
403
+ bubbles: true,
404
+ composed: true,
405
+ }));
406
+ }}
407
+ >
408
+ <dees-icon icon="lucide:FolderPlus" iconSize="13"></dees-icon>
409
+ New group
410
+ </button>
411
+ </div>
412
+ `
413
+ : ''}
242
414
  `;
243
415
  }
244
- renderItem(session) {
416
+ renderFlatList() {
417
+ const sessions = this.filteredSessions;
418
+ if (!sessions.length) {
419
+ return html `<div class="emptyNote">
420
+ ${this.sessions.length ? 'No conversations match this search.' : this.emptyText}
421
+ </div>`;
422
+ }
423
+ return html `${sessions.map((session) => this.renderItem(session, null, -1))}`;
424
+ }
425
+ renderGroupedList() {
426
+ const byId = this.sessionsById;
427
+ const ungrouped = this.ungroupedSessions;
428
+ if (!this.sessions.length && !this.groups.length) {
429
+ return html `<div class="emptyNote">${this.emptyText}</div>`;
430
+ }
431
+ return html `
432
+ ${this.groups.map((group) => {
433
+ const members = group.sessionIds
434
+ .map((id) => byId.get(id))
435
+ .filter((session) => session !== undefined);
436
+ const collapsed = this.collapsedGroupIds.has(group.id);
437
+ const isHeaderDrop = this.dropSlot?.groupId === group.id && this.dropSlot.index === members.length && collapsed;
438
+ return html `
439
+ <button
440
+ class="groupHeader ${collapsed ? 'collapsed' : ''} ${isHeaderDrop ? 'dropTarget' : ''}"
441
+ type="button"
442
+ @click=${() => this.toggleGroupCollapsed(group.id)}
443
+ @contextmenu=${(event) => {
444
+ event.preventDefault();
445
+ const detail = {
446
+ group,
447
+ clientX: event.clientX,
448
+ clientY: event.clientY,
449
+ originalEvent: event,
450
+ };
451
+ this.dispatchEvent(new CustomEvent('harness-group-context', { detail, bubbles: true, composed: true }));
452
+ }}
453
+ @dragover=${(event) => this.handleDragOverSlot(event, group.id, members.length)}
454
+ @drop=${(event) => this.handleDrop(event, group.id, members.length)}
455
+ >
456
+ <dees-icon class="chevron" icon="lucide:ChevronDown" iconSize="12"></dees-icon>
457
+ <span>${group.name}</span>
458
+ <span class="groupCount">${members.length}</span>
459
+ </button>
460
+ ${collapsed
461
+ ? ''
462
+ : this.renderSection(members, group.id)}
463
+ `;
464
+ })}
465
+ ${this.groups.length && ungrouped.length
466
+ ? html `
467
+ <button
468
+ class="groupHeader"
469
+ type="button"
470
+ tabindex="-1"
471
+ @dragover=${(event) => this.handleDragOverSlot(event, null, 0)}
472
+ @drop=${(event) => this.handleDrop(event, null, 0)}
473
+ >
474
+ <span>Ungrouped</span>
475
+ <span class="groupCount">${ungrouped.length}</span>
476
+ </button>
477
+ `
478
+ : ''}
479
+ ${this.renderSection(ungrouped, null)}
480
+ `;
481
+ }
482
+ renderSection(sessions, groupId) {
483
+ const slot = this.dropSlot;
484
+ return html `
485
+ ${sessions.map((session, index) => html `
486
+ ${slot && slot.groupId === groupId && slot.index === index
487
+ ? html `<div class="dropLine"></div>`
488
+ : ''}
489
+ ${this.renderItem(session, groupId, index)}
490
+ `)}
491
+ ${slot && slot.groupId === groupId && slot.index === sessions.length
492
+ ? html `<div class="dropLine"></div>`
493
+ : ''}
494
+ `;
495
+ }
496
+ renderItem(session, groupId, index) {
497
+ const draggable = this.enableGrouping && index >= 0;
245
498
  return html `
246
499
  <button
247
- class="item ${session.id === this.selectedSessionId ? 'selected' : ''}"
500
+ class="item ${session.id === this.selectedSessionId ? 'selected' : ''} ${this.draggingSessionId === session.id ? 'dragging' : ''}"
248
501
  type="button"
502
+ draggable=${draggable ? 'true' : 'false'}
249
503
  @click=${() => this.emit('harness-session-select', session)}
250
504
  @dblclick=${() => this.emit('harness-session-open', session)}
251
505
  @keydown=${(event) => {
@@ -262,8 +516,38 @@ let DeesHarnessSessionList = (() => {
262
516
  };
263
517
  this.dispatchEvent(new CustomEvent('harness-session-context', { detail, bubbles: true, composed: true }));
264
518
  }}
519
+ @dragstart=${(event) => {
520
+ if (!draggable)
521
+ return;
522
+ this.draggingSessionId = session.id;
523
+ event.dataTransfer?.setData('text/plain', session.id);
524
+ if (event.dataTransfer)
525
+ event.dataTransfer.effectAllowed = 'move';
526
+ }}
527
+ @dragend=${() => {
528
+ this.draggingSessionId = '';
529
+ this.dropSlot = undefined;
530
+ }}
531
+ @dragover=${(event) => {
532
+ if (!this.draggingSessionId || index < 0)
533
+ return;
534
+ event.preventDefault();
535
+ const rect = event.currentTarget.getBoundingClientRect();
536
+ const before = event.clientY < rect.top + rect.height / 2;
537
+ this.setDropSlot(groupId, before ? index : index + 1);
538
+ }}
539
+ @drop=${(event) => {
540
+ if (index < 0)
541
+ return;
542
+ const rect = event.currentTarget.getBoundingClientRect();
543
+ const before = event.clientY < rect.top + rect.height / 2;
544
+ this.handleDrop(event, groupId, before ? index : index + 1);
545
+ }}
265
546
  >
266
547
  <span class="itemTitle">
548
+ ${session.icon
549
+ ? html `<dees-icon class="itemIcon" icon=${session.icon} iconSize="12"></dees-icon>`
550
+ : ''}
267
551
  <span class="titleText">${session.title || session.id}</span>
268
552
  <span class="itemTime">${harnessFormatRelativeTime(session.updatedAt ?? session.createdAt)}</span>
269
553
  </span>
@@ -273,12 +557,49 @@ let DeesHarnessSessionList = (() => {
273
557
  </button>
274
558
  `;
275
559
  }
560
+ toggleGroupCollapsed(groupIdArg) {
561
+ const next = new Set(this.collapsedGroupIds);
562
+ if (next.has(groupIdArg)) {
563
+ next.delete(groupIdArg);
564
+ }
565
+ else {
566
+ next.add(groupIdArg);
567
+ }
568
+ this.collapsedGroupIds = next;
569
+ }
570
+ setDropSlot(groupIdArg, indexArg) {
571
+ const current = this.dropSlot;
572
+ if (current && current.groupId === groupIdArg && current.index === indexArg)
573
+ return;
574
+ this.dropSlot = { groupId: groupIdArg, index: indexArg };
575
+ }
576
+ handleDragOverSlot(event, groupIdArg, indexArg) {
577
+ if (!this.draggingSessionId)
578
+ return;
579
+ event.preventDefault();
580
+ this.setDropSlot(groupIdArg, indexArg);
581
+ }
582
+ handleDrop(event, groupIdArg, indexArg) {
583
+ event.preventDefault();
584
+ event.stopPropagation();
585
+ const sessionId = this.draggingSessionId || event.dataTransfer?.getData('text/plain') || '';
586
+ this.draggingSessionId = '';
587
+ this.dropSlot = undefined;
588
+ if (!sessionId)
589
+ return;
590
+ const detail = {
591
+ sessionId,
592
+ groupId: groupIdArg,
593
+ index: Math.max(0, indexArg),
594
+ };
595
+ this.dispatchEvent(new CustomEvent('harness-session-move', { detail, bubbles: true, composed: true }));
596
+ }
276
597
  emit(name, session) {
277
598
  this.dispatchEvent(new CustomEvent(name, { detail: { session }, bubbles: true, composed: true }));
278
599
  }
279
600
  constructor() {
280
601
  super(...arguments);
281
- __runInitializers(this, _search_extraInitializers);
602
+ __runInitializers(this, _collapsedGroupIds_extraInitializers);
282
603
  }
283
604
  static {
284
605
  __runInitializers(_classThis, _classExtraInitializers);
@@ -287,4 +608,4 @@ let DeesHarnessSessionList = (() => {
287
608
  return DeesHarnessSessionList = _classThis;
288
609
  })();
289
610
  export { DeesHarnessSessionList };
290
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy1oYXJuZXNzLXNlc3Npb24tbGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzX3dlYi9lbGVtZW50cy8wMGdyb3VwLWhhcm5lc3MvZGVlcy1oYXJuZXNzLXNlc3Npb24tbGlzdC9kZWVzLWhhcm5lc3Mtc2Vzc2lvbi1saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDL0QsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osR0FBRyxFQUNILGFBQWEsRUFFYixRQUFRLEVBQ1IsS0FBSyxFQUNMLFVBQVUsR0FDWCxNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXRELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sOENBQThDLENBQUM7QUFRdEQ7Ozs7O0dBS0c7SUFFVSxzQkFBc0I7NEJBRGxDLGFBQWEsQ0FBQywyQkFBMkIsQ0FBQzs7OztzQkFDQyxXQUFXOzs7Ozs7Ozs7Ozs7Ozs7O3NDQUFuQixTQUFRLFdBQVc7Ozs7b0NBSXBELFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQzs2Q0FHOUIsUUFBUSxFQUFFO21DQUdWLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztxQ0FHM0IsUUFBUSxFQUFFO2tDQUdWLEtBQUssRUFBRTtZQVhSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFBNkI7WUFHOUMsd01BQVMsaUJBQWlCLDZCQUFqQixpQkFBaUIsNkdBQWM7WUFHeEMsMEtBQVMsT0FBTyw2QkFBUCxPQUFPLHlGQUFrQjtZQUdsQyxnTEFBUyxTQUFTLDZCQUFULFNBQVMsNkZBQW1DO1lBR3JELHVLQUFTLE1BQU0sNkJBQU4sTUFBTSx1RkFBYztZQWpCL0IsNktBNk1DOzs7O1FBNU1RLE1BQU0sQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUcxQyw2RUFBMkMsRUFBRSxFQUFDO1FBQTlDLElBQVMsUUFBUSw4Q0FBNkI7UUFBOUMsSUFBUyxRQUFRLG9EQUE2QjtRQUc5QyxzSkFBcUMsRUFBRSxHQUFDO1FBQXhDLElBQVMsaUJBQWlCLHVEQUFjO1FBQXhDLElBQVMsaUJBQWlCLDZEQUFjO1FBR3hDLDJJQUE0QixLQUFLLEdBQUM7UUFBbEMsSUFBUyxPQUFPLDZDQUFrQjtRQUFsQyxJQUFTLE9BQU8sbURBQWtCO1FBR2xDLHFJQUE2Qix1QkFBdUIsR0FBQztRQUFyRCxJQUFTLFNBQVMsK0NBQW1DO1FBQXJELElBQVMsU0FBUyxxREFBbUM7UUFHckQsaUlBQTBCLEVBQUUsR0FBQztRQUE3QixJQUFTLE1BQU0sNENBQWM7UUFBN0IsSUFBUyxNQUFNLGtEQUFjO1FBRXRCLE1BQU0sQ0FBQyxNQUFNLEdBQUc7WUFDckIsa0JBQWtCO1lBQ2xCLFVBQVUsQ0FBQyxhQUFhO1lBQ3hCLEdBQUcsQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQTBHRjtTQUNGLENBQUM7UUFFRixJQUFZLGdCQUFnQjtZQUMxQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQy9DLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUNwQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUNyRyxDQUFDO1lBQ0YsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxNQUFNLENBQUM7WUFDMUIsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDL0IsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUNyRyxDQUFDO1FBQ0osQ0FBQztRQUVNLFdBQVc7WUFDaEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQW1CLGtCQUFrQixDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDaEYsQ0FBQztRQUVNLE1BQU07WUFDWCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDdkMsT0FBTyxJQUFJLENBQUE7Ozs7bUJBSUksSUFBSSxDQUFDLE1BQU07bUJBQ1gsQ0FBQyxLQUFZLEVBQUUsRUFBRTtnQkFDeEIsSUFBSSxDQUFDLE1BQU0sR0FBSSxLQUFLLENBQUMsYUFBa0MsQ0FBQyxLQUFLLENBQUM7WUFDaEUsQ0FBQzs7OztVQUlELElBQUksQ0FBQyxPQUFPO2dCQUNaLENBQUMsQ0FBQyxJQUFJLENBQUEscURBQXFEO2dCQUMzRCxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU07b0JBQ2YsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3JELENBQUMsQ0FBQyxJQUFJLENBQUEsMEJBQTBCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsUUFBUTs7S0FFNUgsQ0FBQztRQUNKLENBQUM7UUFFTyxVQUFVLENBQUMsT0FBNEI7WUFDN0MsT0FBTyxJQUFJLENBQUE7O3NCQUVPLE9BQU8sQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7O2lCQUU1RCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLE9BQU8sQ0FBQztvQkFDL0MsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxPQUFPLENBQUM7bUJBQ2pELENBQUMsS0FBb0IsRUFBRSxFQUFFO2dCQUNsQyxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssT0FBTztvQkFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3hFLENBQUM7dUJBQ2MsQ0FBQyxLQUFpQixFQUFFLEVBQUU7Z0JBQ25DLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxNQUFNLEdBQWlDO29CQUMzQyxPQUFPO29CQUNQLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDdEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUN0QixhQUFhLEVBQUUsS0FBSztpQkFDckIsQ0FBQztnQkFDRixJQUFJLENBQUMsYUFBYSxDQUNoQixJQUFJLFdBQVcsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUN0RixDQUFDO1lBQ0osQ0FBQzs7O29DQUcyQixPQUFPLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxFQUFFO21DQUM1Qix5QkFBeUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUM7O1VBRTFGLE9BQU8sQ0FBQyxPQUFPO2dCQUNmLENBQUMsQ0FBQyxJQUFJLENBQUEsNkJBQTZCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsWUFBWSxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUztnQkFDL0gsQ0FBQyxDQUFDLEVBQUU7O0tBRVQsQ0FBQztRQUNKLENBQUM7UUFFTyxJQUFJLENBQUMsSUFBWSxFQUFFLE9BQTRCO1lBQ3JELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BHLENBQUM7Ozs7OztZQTVNVSx1REFBc0I7Ozs7O1NBQXRCLHNCQUFzQiJ9
611
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy1oYXJuZXNzLXNlc3Npb24tbGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzX3dlYi9lbGVtZW50cy8wMGdyb3VwLWhhcm5lc3MvZGVlcy1oYXJuZXNzLXNlc3Npb24tbGlzdC9kZWVzLWhhcm5lc3Mtc2Vzc2lvbi1saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDL0QsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osR0FBRyxFQUNILGFBQWEsRUFFYixRQUFRLEVBQ1IsS0FBSyxFQUNMLFVBQVUsR0FDWCxNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUXRELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sOENBQThDLENBQUM7QUFhdEQ7Ozs7Ozs7Ozs7Ozs7R0FhRztJQUVVLHNCQUFzQjs0QkFEbEMsYUFBYSxDQUFDLDJCQUEyQixDQUFDOzs7O3NCQUNDLFdBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7c0NBQW5CLFNBQVEsV0FBVzs7OztvQ0FJcEQsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDOzZDQUc5QixRQUFRLEVBQUU7bUNBR1YsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO3FDQUczQixRQUFRLEVBQUU7a0NBR1YsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDOzBDQUc5QixRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7a0NBRzNCLEtBQUssRUFBRTs2Q0FHUCxLQUFLLEVBQUU7b0NBR1AsS0FBSyxFQUFFOzZDQUdQLEtB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
@@ -0,0 +1,50 @@
1
+ import { DeesElement, type TemplateResult } from '@design.estate/dees-element';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ 'dees-terminal-view': DeesTerminalView;
5
+ }
6
+ }
7
+ /** Detail of `terminal-input`: bytes the user typed, as a UTF-8 string. */
8
+ export interface ITerminalInputDetail {
9
+ data: string;
10
+ }
11
+ /** Detail of `terminal-resize`, fired after the terminal refits its container. */
12
+ export interface ITerminalResizeDetail {
13
+ rows: number;
14
+ cols: number;
15
+ }
16
+ /**
17
+ * Transport-agnostic xterm.js surface: the host pipes remote PTY output into
18
+ * `write()` and receives keystrokes via `terminal-input` — no process,
19
+ * runtime, or socket coupling. `terminal-resize` reports the grid size after
20
+ * every refit so the host can negotiate a PTY size. xterm loads through
21
+ * DeesServiceLibLoader; CSP-locked hosts can pre-register bundled modules
22
+ * with `provideXtermModules()` to avoid the CDN.
23
+ */
24
+ export declare class DeesTerminalView extends DeesElement {
25
+ static demo: () => TemplateResult<1>;
26
+ static demoGroups: string[];
27
+ /** Font size in px for the terminal grid. */
28
+ accessor fontSize: number;
29
+ accessor disabled: boolean;
30
+ private terminal;
31
+ private fitAddon;
32
+ private resizeObserver;
33
+ private inputDisposable;
34
+ private lastReportedSize;
35
+ private pendingWrites;
36
+ private setupPromise;
37
+ static styles: import("@design.estate/dees-element").CSSResult[];
38
+ render(): TemplateResult;
39
+ firstUpdated(): Promise<void>;
40
+ /** Feed remote output into the terminal; safe to call before setup finishes. */
41
+ write(dataArg: string | Uint8Array): void;
42
+ /** Reset the screen and scrollback, e.g. before a full replay. */
43
+ clear(): void;
44
+ focus(): void;
45
+ /** Current grid size, or undefined while xterm is still loading. */
46
+ get currentSize(): ITerminalResizeDetail | undefined;
47
+ private setupTerminal;
48
+ private refit;
49
+ disconnectedCallback(): Promise<void>;
50
+ }
@@ -0,0 +1 @@
1
+ export declare const demoFunc: () => import("@design.estate/dees-element").TemplateResult<1>;
@@ -0,0 +1,26 @@
1
+ import { html } from '@design.estate/dees-element';
2
+ // A loopback demo: keystrokes echo straight back into the terminal so the
3
+ // component is explorable without a live PTY behind it.
4
+ export const demoFunc = () => html `
5
+ <style>
6
+ .terminalDemo {
7
+ height: 380px;
8
+ border: 1px solid var(--dees-color-border-default);
9
+ border-radius: 8px;
10
+ overflow: hidden;
11
+ }
12
+ </style>
13
+ <div class="terminalDemo">
14
+ <dees-terminal-view
15
+ @terminal-input=${(event) => {
16
+ const view = event.currentTarget;
17
+ const data = event.detail.data;
18
+ view.write(data === '\r' ? '\r\n' : data);
19
+ }}
20
+ @terminal-resize=${(event) => {
21
+ console.log('terminal size', event.detail);
22
+ }}
23
+ ></dees-terminal-view>
24
+ </div>
25
+ `;
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy10ZXJtaW5hbC12aWV3LmRlbW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2RlZXMtdGVybWluYWwtdmlldy9kZWVzLXRlcm1pbmFsLXZpZXcuZGVtby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFbkQsMEVBQTBFO0FBQzFFLHdEQUF3RDtBQUN4RCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFBOzs7Ozs7Ozs7Ozt3QkFXVixDQUFDLEtBQW9DLEVBQUUsRUFBRTtJQUN6RCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsYUFBNEQsQ0FBQztJQUNoRixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUMsQ0FBQzt5QkFDa0IsQ0FBQyxLQUFrRCxFQUFFLEVBQUU7SUFDeEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzdDLENBQUM7OztDQUdOLENBQUMifQ==