@countermeasure-platform/web-components 1.3.3-dev.33.1 → 1.3.4

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 (64) hide show
  1. package/README.md +31 -0
  2. package/dist/component-D5sRm1fq.js +389 -0
  3. package/dist/component-D5sRm1fq.js.map +1 -0
  4. package/dist/components/index.js +27 -27
  5. package/dist/icons/index.d.ts +12 -0
  6. package/dist/icons/index.d.ts.map +1 -1
  7. package/dist/icons/index.js +12 -0
  8. package/dist/icons/index.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +127 -126
  12. package/dist/layout/app-shell.d.ts +50 -3
  13. package/dist/layout/app-shell.d.ts.map +1 -1
  14. package/dist/layout/app-shell.js +142 -13
  15. package/dist/layout/app-shell.js.map +1 -1
  16. package/dist/layout/core-app-chrome.d.ts +81 -0
  17. package/dist/layout/core-app-chrome.d.ts.map +1 -0
  18. package/dist/layout/core-app-chrome.js +349 -0
  19. package/dist/layout/core-app-chrome.js.map +1 -0
  20. package/dist/layout/index.d.ts +4 -2
  21. package/dist/layout/index.d.ts.map +1 -1
  22. package/dist/layout/index.js +88 -87
  23. package/dist/layout/index.js.map +1 -1
  24. package/dist/react/primitives/badge.d.ts +1 -1
  25. package/dist/react/primitives/button.d.ts +2 -2
  26. package/dist/react/primitives/copy-button.d.ts +1 -1
  27. package/dist/react/primitives/stat-card.d.ts +1 -1
  28. package/dist/react/primitives/toggle.d.ts +1 -1
  29. package/dist/react/sidebar.d.ts +4 -4
  30. package/dist/react/sidebar.d.ts.map +1 -1
  31. package/dist/react/sidebar.js +18 -16
  32. package/dist/react/sidebar.js.map +1 -1
  33. package/dist/sidebar/component.d.ts +24 -2
  34. package/dist/sidebar/component.d.ts.map +1 -1
  35. package/dist/sidebar/enhance.d.ts +8 -0
  36. package/dist/sidebar/enhance.d.ts.map +1 -1
  37. package/dist/sidebar/index.d.ts +3 -0
  38. package/dist/sidebar/index.d.ts.map +1 -1
  39. package/dist/sidebar/index.js +81 -28
  40. package/dist/sidebar/index.js.map +1 -1
  41. package/dist/sidebar/types.d.ts +126 -4
  42. package/dist/sidebar/types.d.ts.map +1 -1
  43. package/dist/styles/layout.css +252 -0
  44. package/dist/styles/sidebar.css +313 -5
  45. package/package.json +6 -1
  46. package/src/icons/icons.test.ts +9 -0
  47. package/src/icons/index.ts +12 -0
  48. package/src/index.ts +11 -0
  49. package/src/layout/app-shell.test.ts +204 -0
  50. package/src/layout/app-shell.ts +362 -3
  51. package/src/layout/core-app-chrome.test.ts +507 -0
  52. package/src/layout/core-app-chrome.ts +662 -0
  53. package/src/layout/index.ts +36 -2
  54. package/src/react/sidebar.test.tsx +104 -3
  55. package/src/react/sidebar.tsx +26 -4
  56. package/src/sidebar/component.test.ts +395 -1
  57. package/src/sidebar/component.ts +661 -86
  58. package/src/sidebar/enhance.ts +118 -0
  59. package/src/sidebar/index.ts +144 -0
  60. package/src/sidebar/types.ts +143 -4
  61. package/src/styles/layout.css +252 -0
  62. package/src/styles/sidebar.css +313 -5
  63. package/dist/component-Bxhxf21c.js +0 -167
  64. package/dist/component-Bxhxf21c.js.map +0 -1
package/README.md CHANGED
@@ -47,6 +47,37 @@ import { PageHeader } from '@countermeasure-platform/web-components/layout/page-
47
47
  import { MitreMatrix } from '@countermeasure-platform/web-components/security/mitre-matrix'
48
48
  ```
49
49
 
50
+ ### Native Product Chrome
51
+
52
+ Rust-native and other non-React product surfaces should use the vanilla chrome
53
+ helpers instead of mounting a React app for shared navigation. The core `/app`
54
+ preset ships the Threat Library visual treatment with a CounterMeasure Core
55
+ topbar identity:
56
+
57
+ ```typescript
58
+ import '@countermeasure-platform/web-components/styles/layout.css'
59
+ import '@countermeasure-platform/web-components/styles/sidebar.css'
60
+ import { mountCoreAppChromeFromDom } from '@countermeasure-platform/web-components/layout/core-app-chrome'
61
+
62
+ mountCoreAppChromeFromDom({
63
+ root: document,
64
+ preserveTopbarActions: true,
65
+ })
66
+ ```
67
+
68
+ Server-rendered pages provide placeholders and keep legacy markup as a fallback:
69
+
70
+ ```html
71
+ <div data-core-app-sidebar data-base-path="/app" data-pathname="/app"></div>
72
+ <div
73
+ data-core-app-topbar
74
+ data-base-path="/app"
75
+ data-pathname="/app"
76
+ data-product="CounterMeasure Core"
77
+ data-current="Platform Overview"
78
+ ></div>
79
+ ```
80
+
50
81
  ### React
51
82
 
52
83
  ```tsx
@@ -0,0 +1,389 @@
1
+ import { getIconSvgInner as e } from "./icons/index.js";
2
+ import { o as t } from "./sanitize-uWpY18N9.js";
3
+ import { t as n } from "./utils-CSEWuKHo.js";
4
+ import { createBrandLockupElement as r } from "./components/brand/index.js";
5
+ //#region src/sidebar/component.ts
6
+ var i = 900, a = "http://localhost/";
7
+ function o(e) {
8
+ return `sidebar--${e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "app"}`;
9
+ }
10
+ function s(e) {
11
+ let t = e.trim().split(/\s+/).filter(Boolean);
12
+ return t.length >= 2 ? `${t[0]?.charAt(0) ?? ""}${t[t.length - 1]?.charAt(0) ?? ""}`.toUpperCase() : e.slice(0, 2).toUpperCase();
13
+ }
14
+ function c() {
15
+ try {
16
+ return typeof window < "u" && window.localStorage !== void 0;
17
+ } catch {
18
+ return !1;
19
+ }
20
+ }
21
+ function l(e) {
22
+ try {
23
+ return new URL(e, a).pathname;
24
+ } catch {
25
+ return e.split(/[?#]/, 1)[0] ?? e;
26
+ }
27
+ }
28
+ function u(e) {
29
+ return typeof window < "u" && window.innerWidth <= e;
30
+ }
31
+ function d(e, t) {
32
+ if (e === void 0) return null;
33
+ if (typeof e == "number") return {
34
+ label: e > 0 ? String(e) : "",
35
+ tone: t ?? "primary",
36
+ visible: e > 0,
37
+ dot: e > 0
38
+ };
39
+ let n = e.label, r = {
40
+ label: n,
41
+ tone: e.tone ?? t ?? "primary",
42
+ visible: n.length > 0 || e.dot === !0,
43
+ dot: e.dot ?? n.length > 0
44
+ };
45
+ return e.title !== void 0 && (r.title = e.title), r;
46
+ }
47
+ function f(n, r, i = "sidebar__item-icon") {
48
+ let a = "http://www.w3.org/2000/svg", o = document.createElementNS(a, "svg");
49
+ o.setAttribute("xmlns", a), o.setAttribute("width", "16"), o.setAttribute("height", "16"), o.setAttribute("viewBox", "0 0 24 24"), o.setAttribute("fill", "none"), o.setAttribute("stroke", "currentColor"), o.setAttribute("stroke-width", "2"), o.setAttribute("stroke-linecap", "round"), o.setAttribute("stroke-linejoin", "round"), o.classList.add(i), o.setAttribute("data-icon", r), o.setAttribute("aria-hidden", "true");
50
+ let s = e(n, r);
51
+ return s && t(o, s), o;
52
+ }
53
+ function p(e, t) {
54
+ if (t === void 0) return;
55
+ let n = Array.isArray(t) ? t : [t];
56
+ for (let t of n) e.appendChild(t);
57
+ }
58
+ var m = class {
59
+ container;
60
+ aside;
61
+ config;
62
+ iconSet;
63
+ variant;
64
+ cleanupFns = [];
65
+ collapseButton = null;
66
+ backdrop = null;
67
+ constructor(e) {
68
+ this.config = e, this.container = n(e.container), this.iconSet = e.iconSet ?? "lucide", this.variant = e.variant ?? "app", this.aside = document.createElement("aside"), this.aside.classList.add("sidebar", o(this.variant)), (this.variant === "threat-library" || this.variant === "cm") && this.aside.classList.add("sidebar--product"), this.aside.setAttribute("data-sidebar", this.variant), this.aside.setAttribute("data-open", String(e.open === !0)), this.aside.setAttribute("aria-label", "Primary navigation"), this.resolveInitialCollapsed() && this.aside.classList.add("sidebar--collapsed"), this.render(), this.container.appendChild(this.aside), e.mobileBackdrop === !0 && this.renderBackdrop(), this.setupBehavior();
69
+ }
70
+ render() {
71
+ this.config.collapsible === !0 && this.renderCollapseButton(), this.renderHeader(), this.renderScope();
72
+ let e = document.createElement("nav");
73
+ e.classList.add("sidebar__body"), e.setAttribute("aria-label", "Primary"), p(e, this.config.beforeNav);
74
+ for (let t of this.config.sections) e.appendChild(this.buildSection(t));
75
+ p(e, this.config.afterNav), this.aside.appendChild(e), this.renderFooter(), this.config.activeItemId !== void 0 && this.setActive(this.config.activeItemId);
76
+ }
77
+ buildSection(e) {
78
+ let t = document.createElement("div");
79
+ t.classList.add("sidebar__section"), t.setAttribute("data-section-id", e.id);
80
+ let n = e.collapsible === !0, r = e.defaultExpanded !== !1;
81
+ if (n && e.label) {
82
+ t.classList.add("sidebar__section--collapsible"), r && t.classList.add("sidebar__section--expanded");
83
+ let n = document.createElement("button");
84
+ n.type = "button", n.classList.add("sidebar__group-header"), n.setAttribute("aria-expanded", String(r)), n.setAttribute("aria-controls", `sidebar-group-${e.id}`), e.icon && n.appendChild(f(this.iconSet, e.icon));
85
+ let i = document.createElement("span");
86
+ i.classList.add("sidebar__group-label"), i.textContent = e.label, n.appendChild(i);
87
+ let a = document.createElementNS("http://www.w3.org/2000/svg", "svg");
88
+ a.setAttribute("class", "sidebar__group-chevron"), a.setAttribute("viewBox", "0 0 24 24"), a.setAttribute("width", "14"), a.setAttribute("height", "14"), a.setAttribute("fill", "none"), a.setAttribute("stroke", "currentColor"), a.setAttribute("stroke-width", "2"), a.setAttribute("stroke-linecap", "round"), a.setAttribute("stroke-linejoin", "round"), a.setAttribute("aria-hidden", "true");
89
+ let o = document.createElementNS("http://www.w3.org/2000/svg", "path");
90
+ o.setAttribute("d", "m6 9 6 6 6-6"), a.appendChild(o), n.appendChild(a), n.addEventListener("click", () => {
91
+ let e = t.classList.toggle("sidebar__section--expanded");
92
+ n.setAttribute("aria-expanded", String(e));
93
+ }), t.appendChild(n);
94
+ } else if (e.label) {
95
+ let n = document.createElement("div");
96
+ n.classList.add("sidebar__section-label"), n.textContent = e.label, t.appendChild(n);
97
+ }
98
+ let i = document.createElement("div");
99
+ i.classList.add("sidebar__items"), i.id = `sidebar-group-${e.id}`;
100
+ for (let t of e.items) i.appendChild(this.buildItem(t));
101
+ return t.appendChild(i), t;
102
+ }
103
+ buildItem(e) {
104
+ let t = e.disabled === !0, n = e.href !== void 0 && !t ? document.createElement("a") : t ? document.createElement("span") : document.createElement("button");
105
+ n.classList.add("sidebar__item"), n.setAttribute("data-item-id", e.id), n.setAttribute("data-nav-item", ""), n.setAttribute("title", e.tooltip ?? e.label), e.ariaLabel !== void 0 && n.setAttribute("aria-label", e.ariaLabel), t ? (n.setAttribute("aria-disabled", "true"), n.setAttribute("role", "link"), n.setAttribute("tabindex", "-1"), n.classList.add("sidebar__item--disabled")) : n instanceof HTMLAnchorElement ? (n.href = e.href ?? "#", e.target !== void 0 && (n.target = e.target), e.rel === void 0 ? e.target === "_blank" && (n.rel = "noreferrer noopener") : n.rel = e.rel) : n instanceof HTMLButtonElement && (n.type = "button"), this.isItemActive(e) && (n.classList.add("sidebar__item--active"), n.setAttribute("aria-current", "page")), e.icon && n.appendChild(f(this.iconSet, e.icon));
106
+ let r = document.createElement("span");
107
+ if (r.classList.add("sidebar__item-label"), r.textContent = e.label, n.appendChild(r), e.tag !== void 0) {
108
+ let t = document.createElement("span");
109
+ t.classList.add("sidebar__tag"), t.textContent = e.tag, n.appendChild(t);
110
+ }
111
+ let i = d(e.badge, e.badgeTone);
112
+ return i?.visible === !0 && this.applyBadge(n, e.id, i), t || n.addEventListener("click", (t) => {
113
+ this.config.onNavigate?.(e), e.onClick?.(t), this.config.closeOnNavigate !== !1 && this.isOpen() && this.setOpen(!1);
114
+ }), n;
115
+ }
116
+ renderHeader() {
117
+ let e = this.config.brand;
118
+ if (e === void 0) return;
119
+ let t = document.createElement("div");
120
+ t.classList.add("sidebar__header");
121
+ let n = document.createElement("div");
122
+ n.classList.add("sidebar__header-row");
123
+ let i = e.href === void 0 ? e.onClick === void 0 ? document.createElement("span") : document.createElement("button") : document.createElement("a");
124
+ i.classList.add("sidebar__brand"), i instanceof HTMLAnchorElement && (i.href = e.href ?? "#", i.setAttribute("aria-label", e.label ?? "CounterMeasure")), i instanceof HTMLButtonElement && (i.type = "button", i.setAttribute("aria-label", e.label ?? "CounterMeasure")), e.onClick !== void 0 && i.addEventListener("click", e.onClick), i.appendChild(r({
125
+ label: e.label ?? "CounterMeasure",
126
+ markSize: e.markSize ?? 22,
127
+ showWordmark: e.showWordmark ?? !0,
128
+ decorative: e.decorative ?? !1
129
+ })), n.appendChild(i), t.appendChild(n), this.aside.appendChild(t);
130
+ }
131
+ renderScope() {
132
+ let e = this.config.scope;
133
+ if (e === void 0 || e.options.length === 0) return;
134
+ let t = e.options.find((t) => t.id === e.value) ?? e.options[0] ?? null, n = document.createElement("div");
135
+ n.classList.add("sidebar__scope");
136
+ let r = document.createElement("button");
137
+ r.type = "button", r.classList.add("sidebar__scope-trigger"), r.setAttribute("aria-haspopup", "listbox"), r.setAttribute("aria-expanded", "false"), r.setAttribute("title", t?.label ?? e.placeholder ?? "Select scope"), e.icon !== void 0 && r.appendChild(f(this.iconSet, e.icon, "sidebar__scope-icon"));
138
+ let i = document.createElement("span");
139
+ if (i.classList.add("sidebar__scope-copy"), e.label !== void 0) {
140
+ let t = document.createElement("span");
141
+ t.classList.add("sidebar__scope-label"), t.textContent = e.label, i.appendChild(t);
142
+ }
143
+ let a = document.createElement("span");
144
+ a.classList.add("sidebar__scope-current"), a.textContent = t?.label ?? e.placeholder ?? "Select scope", i.appendChild(a), r.appendChild(i);
145
+ let o = f(this.iconSet, "chevron-down", "sidebar__scope-chevron");
146
+ r.appendChild(o);
147
+ let s = document.createElement("div");
148
+ s.classList.add("sidebar__scope-menu"), s.setAttribute("role", "listbox"), s.hidden = !0;
149
+ let c = (e) => {
150
+ r.setAttribute("aria-expanded", String(e)), s.hidden = !e;
151
+ };
152
+ for (let n of e.options) {
153
+ let i = document.createElement("button");
154
+ if (i.type = "button", i.classList.add("sidebar__scope-option"), i.setAttribute("role", "option"), i.setAttribute("data-option-id", n.id), i.setAttribute("aria-selected", String(n.id === t?.id)), n.disabled === !0 && (i.disabled = !0), n.status !== void 0) {
155
+ let e = document.createElement("span");
156
+ e.classList.add("sidebar__scope-dot", `sidebar__scope-dot--${n.status}`), i.appendChild(e);
157
+ }
158
+ let o = document.createElement("span");
159
+ o.classList.add("sidebar__scope-option-label"), o.textContent = n.label, i.appendChild(o);
160
+ let l = f(this.iconSet, "check", "sidebar__scope-check");
161
+ i.appendChild(l), i.addEventListener("click", () => {
162
+ a.textContent = n.label, r.setAttribute("title", n.label), s.querySelectorAll("[role=\"option\"]").forEach((e) => {
163
+ e.setAttribute("aria-selected", String(e.getAttribute("data-option-id") === n.id));
164
+ }), c(!1), e.onChange?.(n);
165
+ }), s.appendChild(i);
166
+ }
167
+ r.addEventListener("click", () => {
168
+ c(s.hidden === !0);
169
+ });
170
+ let l = (e) => {
171
+ n.contains(e.target) || c(!1);
172
+ };
173
+ document.addEventListener("pointerdown", l), this.cleanupFns.push(() => {
174
+ document.removeEventListener("pointerdown", l);
175
+ }), n.appendChild(r), n.appendChild(s), this.aside.appendChild(n);
176
+ }
177
+ renderCollapseButton() {
178
+ let e = document.createElement("button");
179
+ e.type = "button", e.classList.add("sidebar__collapse-btn", "sidebar__collapse-btn--edge"), e.setAttribute("data-sidebar-toggle", ""), this.config.collapseButtonVisible === !0 && e.setAttribute("data-visible", "true");
180
+ let t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
181
+ t.setAttribute("aria-hidden", "true"), t.setAttribute("viewBox", "0 0 24 24"), t.setAttribute("fill", "none"), t.setAttribute("stroke", "currentColor"), t.setAttribute("stroke-width", "2"), t.setAttribute("stroke-linecap", "round"), t.setAttribute("stroke-linejoin", "round");
182
+ let n = document.createElementNS("http://www.w3.org/2000/svg", "path");
183
+ t.appendChild(n), e.appendChild(t), e.addEventListener("click", () => {
184
+ this.toggleCollapse();
185
+ }), this.collapseButton = e, this.updateCollapseButton(), this.aside.appendChild(e);
186
+ }
187
+ renderFooter() {
188
+ let e = this.config.user !== void 0, t = this.config.footerActions !== void 0 && this.config.footerActions.length > 0;
189
+ if (!e && !t) return;
190
+ let n = document.createElement("div");
191
+ n.classList.add("sidebar__footer");
192
+ let r = document.createElement("div");
193
+ if (r.classList.add("sidebar__footer-bar"), e && this.config.user) {
194
+ let e = this.config.user, t = e.onClick === void 0 ? document.createElement("span") : document.createElement("button");
195
+ t.classList.add("sidebar__user-trigger", "sidebar__footer-user");
196
+ let n = e.onClick;
197
+ t instanceof HTMLButtonElement && n !== void 0 && (t.type = "button", t.setAttribute("aria-label", e.label ?? `User menu for ${e.name}`), t.addEventListener("click", n));
198
+ let i = document.createElement("span");
199
+ if (i.classList.add("sidebar__avatar", "sidebar__footer-avatar"), e.avatarUrl !== void 0) {
200
+ let t = document.createElement("img");
201
+ t.src = e.avatarUrl, t.alt = "", i.appendChild(t);
202
+ } else i.textContent = e.initials ?? s(e.name);
203
+ if (e.presence !== void 0 && e.presence !== "offline") {
204
+ let t = document.createElement("span");
205
+ t.classList.add("sidebar__presence", `sidebar__presence--${e.presence}`), t.setAttribute("aria-hidden", "true"), i.appendChild(t);
206
+ }
207
+ let a = document.createElement("span");
208
+ a.classList.add("sidebar__user-details");
209
+ let o = document.createElement("span");
210
+ if (o.classList.add("sidebar__user-name", "sidebar__footer-name"), o.textContent = e.name, a.appendChild(o), e.detail !== void 0) {
211
+ let t = document.createElement("span");
212
+ t.classList.add("sidebar__user-status"), t.textContent = e.detail, a.appendChild(t);
213
+ }
214
+ t.appendChild(i), t.appendChild(a), r.appendChild(t);
215
+ }
216
+ if (t && this.config.footerActions) {
217
+ let e = document.createElement("span");
218
+ e.classList.add("sidebar__footer-icons");
219
+ for (let t of this.config.footerActions) {
220
+ let n = document.createElement("button");
221
+ n.type = "button", n.classList.add("sidebar__footer-icon"), t.danger === !0 && n.classList.add("sidebar__footer-icon--danger"), n.setAttribute("aria-label", t.label), n.setAttribute("title", t.label);
222
+ let r = f(this.iconSet, t.icon);
223
+ if (n.appendChild(r), t.onClick) {
224
+ let e = t.onClick;
225
+ n.addEventListener("click", () => {
226
+ e();
227
+ });
228
+ }
229
+ e.appendChild(n);
230
+ }
231
+ r.appendChild(e);
232
+ }
233
+ n.appendChild(r), this.aside.appendChild(n);
234
+ }
235
+ renderBackdrop() {
236
+ let e = document.createElement("button");
237
+ e.type = "button", e.classList.add("sidebar__backdrop"), e.setAttribute("data-sidebar-backdrop", this.variant), e.setAttribute("data-visible", String(this.isOpen())), e.setAttribute("aria-label", "Close sidebar"), e.addEventListener("click", () => {
238
+ this.setOpen(!1);
239
+ }), this.backdrop = e, this.container.appendChild(e);
240
+ }
241
+ setupBehavior() {
242
+ this.setupKeyboardNavigation(), this.setupMobileToggles();
243
+ let e = (e) => {
244
+ e.key === "Escape" && (this.isOpen() && this.setOpen(!1), this.closeScopeMenus());
245
+ };
246
+ document.addEventListener("keydown", e), this.cleanupFns.push(() => {
247
+ document.removeEventListener("keydown", e);
248
+ });
249
+ let t = () => {
250
+ u(this.getMobileBreakpoint()) && this.setOpen(!1);
251
+ };
252
+ window.addEventListener("resize", t), this.cleanupFns.push(() => {
253
+ window.removeEventListener("resize", t);
254
+ });
255
+ }
256
+ setupKeyboardNavigation() {
257
+ let e = (e) => {
258
+ if (e.key !== "ArrowDown" && e.key !== "ArrowUp") return;
259
+ let t = Array.from(this.aside.querySelectorAll("[data-nav-item]:not([aria-disabled=\"true\"])")).filter((e) => !e.hidden && e.offsetParent !== null);
260
+ if (t.length === 0) return;
261
+ let n = t.indexOf(document.activeElement);
262
+ n !== -1 && (e.preventDefault(), t[e.key === "ArrowDown" ? (n + 1) % t.length : (n - 1 + t.length) % t.length]?.focus());
263
+ };
264
+ this.aside.addEventListener("keydown", e), this.cleanupFns.push(() => {
265
+ this.aside.removeEventListener("keydown", e);
266
+ });
267
+ }
268
+ setupMobileToggles() {
269
+ let e = Array.from(document.querySelectorAll("[data-sidebar-mobile-toggle]")).filter((e) => {
270
+ let t = e.getAttribute("data-sidebar-mobile-toggle");
271
+ return t === null || t === "" || t === this.variant;
272
+ });
273
+ for (let t of e) {
274
+ let e = () => {
275
+ this.setOpen(!this.isOpen());
276
+ };
277
+ t.addEventListener("click", e), this.cleanupFns.push(() => {
278
+ t.removeEventListener("click", e);
279
+ });
280
+ }
281
+ }
282
+ setActive(e) {
283
+ this.config.activeItemId = e, this.aside.querySelectorAll(".sidebar__item").forEach((e) => {
284
+ e.classList.remove("sidebar__item--active"), e.removeAttribute("aria-current");
285
+ });
286
+ let t = Array.from(this.aside.querySelectorAll("[data-item-id]")).find((t) => t.getAttribute("data-item-id") === e);
287
+ t && (t.classList.add("sidebar__item--active"), t.setAttribute("aria-current", "page"));
288
+ }
289
+ setPathname(e) {
290
+ e === void 0 ? delete this.config.pathname : this.config.pathname = e, delete this.config.activeItemId, this.syncActiveRouteState();
291
+ }
292
+ updateBadge(e, t, n) {
293
+ let r = Array.from(this.aside.querySelectorAll("[data-item-id]")).find((t) => t.getAttribute("data-item-id") === e);
294
+ r && this.applyBadge(r, e, d(t, n ?? r.getAttribute("data-badge-tone") ?? void 0));
295
+ }
296
+ toggleCollapse() {
297
+ this.setCollapsed(!this.isCollapsed());
298
+ }
299
+ collapse() {
300
+ this.setCollapsed(!0);
301
+ }
302
+ expand() {
303
+ this.setCollapsed(!1);
304
+ }
305
+ setOpen(e) {
306
+ let t = this.isOpen();
307
+ this.aside.setAttribute("data-open", String(e)), this.backdrop?.setAttribute("data-visible", String(e)), t !== e && this.config.onOpenChange?.(e);
308
+ }
309
+ destroy() {
310
+ for (let e of this.cleanupFns.splice(0)) e();
311
+ this.backdrop?.remove(), this.aside.remove();
312
+ }
313
+ applyBadge(e, t, n) {
314
+ if (n === null) return;
315
+ let r = e.querySelector(`[data-badge="${t}"]`);
316
+ r === null && (r = document.createElement("span"), r.classList.add("sidebar__badge"), r.setAttribute("data-badge", t), e.appendChild(r)), r.className = `sidebar__badge sidebar__badge--${n.tone}`, r.textContent = n.label, n.title === void 0 ? r.removeAttribute("title") : r.setAttribute("title", n.title), e.setAttribute("data-badge-visible", String(n.visible)), e.setAttribute("data-badge-dot", String(n.dot)), e.setAttribute("data-badge-tone", n.tone);
317
+ }
318
+ setCollapsed(e) {
319
+ let t = this.isCollapsed();
320
+ this.aside.classList.toggle("sidebar--collapsed", e), this.persistCollapsed(e), this.updateCollapseButton(), t !== e && this.config.onCollapse?.(e);
321
+ }
322
+ isCollapsed() {
323
+ return this.aside.classList.contains("sidebar--collapsed");
324
+ }
325
+ isOpen() {
326
+ return this.aside.getAttribute("data-open") === "true";
327
+ }
328
+ getMobileBreakpoint() {
329
+ return this.config.mobileBreakpoint ?? i;
330
+ }
331
+ resolveInitialCollapsed() {
332
+ if (this.config.storageKey && this.config.persistCollapsed !== !1 && c()) try {
333
+ if (!u(this.getMobileBreakpoint())) return window.localStorage.getItem(this.config.storageKey) === "true";
334
+ } catch {
335
+ return this.config.collapsed === !0;
336
+ }
337
+ return this.config.collapsed === !0;
338
+ }
339
+ persistCollapsed(e) {
340
+ if (!(!this.config.storageKey || this.config.persistCollapsed === !1 || !c())) try {
341
+ window.localStorage.setItem(this.config.storageKey, String(e));
342
+ } catch {}
343
+ }
344
+ getCurrentPathname() {
345
+ return this.config.pathname === void 0 ? typeof window > "u" ? null : window.location.pathname : l(this.config.pathname);
346
+ }
347
+ isItemActive(e) {
348
+ if (e.active === !0 || e.id === this.config.activeItemId) return !0;
349
+ let t = this.getCurrentPathname();
350
+ if (t === null) return !1;
351
+ let n = e.activeMatch;
352
+ if (typeof n == "function") return n(t, e);
353
+ if (n instanceof RegExp) return n.test(t);
354
+ if (typeof n == "string" && n !== "exact" && n !== "prefix") return t === n || t.startsWith(`${n.replace(/\/$/, "")}/`);
355
+ if (e.href === void 0) return !1;
356
+ try {
357
+ let r = typeof window > "u" ? a : window.location.href, i = new URL(e.href, r).pathname;
358
+ return n === "exact" || e.end === !0 ? t === i : t === i || t.startsWith(`${i.replace(/\/$/, "")}/`);
359
+ } catch {
360
+ return !1;
361
+ }
362
+ }
363
+ syncActiveRouteState() {
364
+ this.aside.querySelectorAll(".sidebar__item").forEach((e) => {
365
+ e.classList.remove("sidebar__item--active"), e.removeAttribute("aria-current");
366
+ });
367
+ let e = Array.from(this.aside.querySelectorAll("[data-item-id]")).find((e) => {
368
+ let t = e.getAttribute("data-item-id"), n = this.config.sections.flatMap((e) => e.items).find((e) => e.id === t);
369
+ return n === void 0 ? !1 : this.isItemActive(n);
370
+ });
371
+ e !== void 0 && (e.classList.add("sidebar__item--active"), e.setAttribute("aria-current", "page"));
372
+ }
373
+ closeScopeMenus() {
374
+ this.aside.querySelectorAll(".sidebar__scope-menu").forEach((e) => {
375
+ e.hidden = !0;
376
+ }), this.aside.querySelectorAll(".sidebar__scope-trigger").forEach((e) => {
377
+ e.setAttribute("aria-expanded", "false");
378
+ });
379
+ }
380
+ updateCollapseButton() {
381
+ if (this.collapseButton === null) return;
382
+ let e = this.isCollapsed(), t = e ? "Expand sidebar" : "Collapse sidebar";
383
+ this.collapseButton.setAttribute("aria-label", t), this.collapseButton.setAttribute("aria-expanded", String(!e)), this.collapseButton.setAttribute("title", t), this.collapseButton.setAttribute("data-collapsed", String(e)), this.collapseButton.querySelector("path")?.setAttribute("d", e ? "m9 18 6-6-6-6" : "m15 18-6-6 6-6");
384
+ }
385
+ };
386
+ //#endregion
387
+ export { m as t };
388
+
389
+ //# sourceMappingURL=component-D5sRm1fq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-D5sRm1fq.js","names":[],"sources":["../src/sidebar/component.ts"],"sourcesContent":["/**\n * SidebarComponent - Programmatic sidebar with sections, badges, and footer\n * @countermeasure/web-components/sidebar/component\n *\n * Builds the sidebar DOM from a config object and owns the common app-shell\n * behavior expected by CounterMeasure product surfaces: active route state,\n * persisted collapse, mobile drawer state, keyboard navigation, tenant/scope\n * selection, badges, and footer account chrome.\n */\n\nimport { createBrandLockupElement } from '../components/brand'\nimport { getIconSvgInner, type IconSet } from '../icons/index'\nimport { resolveContainer } from '../primitives/utils'\nimport { setSafeIconHtml } from '../utils/sanitize'\nimport {\n type SidebarBadgeConfig,\n type SidebarBadgeTone,\n type SidebarComponentConfig,\n type SidebarNavItem,\n type SidebarSection,\n} from './types'\n\nconst DEFAULT_MOBILE_BREAKPOINT = 900\nconst FALLBACK_URL_BASE = 'http://localhost/'\n\ninterface NormalizedBadge {\n label: string\n title?: string\n tone: SidebarBadgeTone\n visible: boolean\n dot: boolean\n}\n\nfunction toSidebarVariantClassName(variant: string): string {\n const normalized = variant\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n return `sidebar--${normalized || 'app'}`\n}\n\nfunction toInitials(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n\n if (words.length >= 2) {\n return `${words[0]?.charAt(0) ?? ''}${words[words.length - 1]?.charAt(0) ?? ''}`.toUpperCase()\n }\n\n return name.slice(0, 2).toUpperCase()\n}\n\nfunction canUseStorage(): boolean {\n try {\n return typeof window !== 'undefined' && window.localStorage !== undefined\n } catch {\n return false\n }\n}\n\nfunction toPathname(value: string): string {\n try {\n return new URL(value, FALLBACK_URL_BASE).pathname\n } catch {\n return value.split(/[?#]/, 1)[0] ?? value\n }\n}\n\nfunction isMobileViewport(breakpoint: number): boolean {\n return typeof window !== 'undefined' && window.innerWidth <= breakpoint\n}\n\nfunction normalizeBadge(\n badge: number | SidebarBadgeConfig | undefined,\n fallbackTone: SidebarBadgeTone | undefined\n): NormalizedBadge | null {\n if (badge === undefined) {\n return null\n }\n\n if (typeof badge === 'number') {\n return {\n label: badge > 0 ? String(badge) : '',\n tone: fallbackTone ?? 'primary',\n visible: badge > 0,\n dot: badge > 0,\n }\n }\n\n const label = badge.label\n const normalized: NormalizedBadge = {\n label,\n tone: badge.tone ?? fallbackTone ?? 'primary',\n visible: label.length > 0 || badge.dot === true,\n dot: badge.dot ?? label.length > 0,\n }\n if (badge.title !== undefined) {\n normalized.title = badge.title\n }\n return normalized\n}\n\n/** Create an SVG element populated with icon content from the registry. */\nfunction createIconSvg(\n iconSet: IconSet,\n name: string,\n className = 'sidebar__item-icon'\n): SVGElement {\n const svgNs = 'http://www.w3.org/2000/svg'\n const svg = document.createElementNS(svgNs, 'svg')\n svg.setAttribute('xmlns', svgNs)\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('stroke-linecap', 'round')\n svg.setAttribute('stroke-linejoin', 'round')\n svg.classList.add(className)\n svg.setAttribute('data-icon', name)\n svg.setAttribute('aria-hidden', 'true')\n\n const inner = getIconSvgInner(iconSet, name)\n if (inner) {\n setSafeIconHtml(svg, inner)\n }\n\n return svg\n}\n\nfunction appendElements(\n parent: HTMLElement,\n elementOrElements?: HTMLElement | HTMLElement[]\n): void {\n if (elementOrElements === undefined) {\n return\n }\n\n const elements = Array.isArray(elementOrElements) ? elementOrElements : [elementOrElements]\n for (const element of elements) {\n parent.appendChild(element)\n }\n}\n\nexport class SidebarComponent {\n private readonly container: HTMLElement\n private readonly aside: HTMLElement\n private readonly config: SidebarComponentConfig\n private readonly iconSet: IconSet\n private readonly variant: string\n private readonly cleanupFns: (() => void)[] = []\n private collapseButton: HTMLButtonElement | null = null\n private backdrop: HTMLElement | null = null\n\n constructor(config: SidebarComponentConfig) {\n this.config = config\n this.container = resolveContainer(config.container)\n this.iconSet = config.iconSet ?? 'lucide'\n this.variant = config.variant ?? 'app'\n\n this.aside = document.createElement('aside')\n this.aside.classList.add('sidebar', toSidebarVariantClassName(this.variant))\n if (this.variant === 'threat-library' || this.variant === 'cm') {\n this.aside.classList.add('sidebar--product')\n }\n this.aside.setAttribute('data-sidebar', this.variant)\n this.aside.setAttribute('data-open', String(config.open === true))\n this.aside.setAttribute('aria-label', 'Primary navigation')\n\n if (this.resolveInitialCollapsed()) {\n this.aside.classList.add('sidebar--collapsed')\n }\n\n this.render()\n this.container.appendChild(this.aside)\n\n if (config.mobileBackdrop === true) {\n this.renderBackdrop()\n }\n\n this.setupBehavior()\n }\n\n private render(): void {\n if (this.config.collapsible === true) {\n this.renderCollapseButton()\n }\n\n this.renderHeader()\n this.renderScope()\n\n const body = document.createElement('nav')\n body.classList.add('sidebar__body')\n body.setAttribute('aria-label', 'Primary')\n\n appendElements(body, this.config.beforeNav)\n\n for (const section of this.config.sections) {\n body.appendChild(this.buildSection(section))\n }\n\n appendElements(body, this.config.afterNav)\n\n this.aside.appendChild(body)\n this.renderFooter()\n\n if (this.config.activeItemId !== undefined) {\n this.setActive(this.config.activeItemId)\n }\n }\n\n private buildSection(section: SidebarSection): HTMLElement {\n const sectionEl = document.createElement('div')\n sectionEl.classList.add('sidebar__section')\n sectionEl.setAttribute('data-section-id', section.id)\n\n const collapsible = section.collapsible === true\n const expanded = section.defaultExpanded !== false\n\n if (collapsible && section.label) {\n sectionEl.classList.add('sidebar__section--collapsible')\n if (expanded) sectionEl.classList.add('sidebar__section--expanded')\n\n const header = document.createElement('button')\n header.type = 'button'\n header.classList.add('sidebar__group-header')\n header.setAttribute('aria-expanded', String(expanded))\n header.setAttribute('aria-controls', `sidebar-group-${section.id}`)\n\n if (section.icon) {\n header.appendChild(createIconSvg(this.iconSet, section.icon))\n }\n\n const labelSpan = document.createElement('span')\n labelSpan.classList.add('sidebar__group-label')\n labelSpan.textContent = section.label\n header.appendChild(labelSpan)\n\n const chevron = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n chevron.setAttribute('class', 'sidebar__group-chevron')\n chevron.setAttribute('viewBox', '0 0 24 24')\n chevron.setAttribute('width', '14')\n chevron.setAttribute('height', '14')\n chevron.setAttribute('fill', 'none')\n chevron.setAttribute('stroke', 'currentColor')\n chevron.setAttribute('stroke-width', '2')\n chevron.setAttribute('stroke-linecap', 'round')\n chevron.setAttribute('stroke-linejoin', 'round')\n chevron.setAttribute('aria-hidden', 'true')\n const chevronPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n chevronPath.setAttribute('d', 'm6 9 6 6 6-6')\n chevron.appendChild(chevronPath)\n header.appendChild(chevron)\n\n header.addEventListener('click', () => {\n const nowExpanded = sectionEl.classList.toggle('sidebar__section--expanded')\n header.setAttribute('aria-expanded', String(nowExpanded))\n })\n\n sectionEl.appendChild(header)\n } else if (section.label) {\n const labelEl = document.createElement('div')\n labelEl.classList.add('sidebar__section-label')\n labelEl.textContent = section.label\n sectionEl.appendChild(labelEl)\n }\n\n const itemsWrap = document.createElement('div')\n itemsWrap.classList.add('sidebar__items')\n itemsWrap.id = `sidebar-group-${section.id}`\n\n for (const item of section.items) {\n itemsWrap.appendChild(this.buildItem(item))\n }\n\n sectionEl.appendChild(itemsWrap)\n return sectionEl\n }\n\n private buildItem(item: SidebarNavItem): HTMLElement {\n const disabled = item.disabled === true\n const element =\n item.href !== undefined && !disabled\n ? document.createElement('a')\n : disabled\n ? document.createElement('span')\n : document.createElement('button')\n\n element.classList.add('sidebar__item')\n element.setAttribute('data-item-id', item.id)\n element.setAttribute('data-nav-item', '')\n element.setAttribute('title', item.tooltip ?? item.label)\n\n if (item.ariaLabel !== undefined) {\n element.setAttribute('aria-label', item.ariaLabel)\n }\n\n if (disabled) {\n element.setAttribute('aria-disabled', 'true')\n element.setAttribute('role', 'link')\n element.setAttribute('tabindex', '-1')\n element.classList.add('sidebar__item--disabled')\n } else if (element instanceof HTMLAnchorElement) {\n element.href = item.href ?? '#'\n if (item.target !== undefined) {\n element.target = item.target\n }\n if (item.rel !== undefined) {\n element.rel = item.rel\n } else if (item.target === '_blank') {\n element.rel = 'noreferrer noopener'\n }\n } else if (element instanceof HTMLButtonElement) {\n element.type = 'button'\n }\n\n if (this.isItemActive(item)) {\n element.classList.add('sidebar__item--active')\n element.setAttribute('aria-current', 'page')\n }\n\n if (item.icon) {\n element.appendChild(createIconSvg(this.iconSet, item.icon))\n }\n\n const label = document.createElement('span')\n label.classList.add('sidebar__item-label')\n label.textContent = item.label\n element.appendChild(label)\n\n if (item.tag !== undefined) {\n const tag = document.createElement('span')\n tag.classList.add('sidebar__tag')\n tag.textContent = item.tag\n element.appendChild(tag)\n }\n\n const badge = normalizeBadge(item.badge, item.badgeTone)\n if (badge?.visible === true) {\n this.applyBadge(element, item.id, badge)\n }\n\n if (!disabled) {\n element.addEventListener('click', event => {\n this.config.onNavigate?.(item)\n item.onClick?.(event)\n\n if (this.config.closeOnNavigate !== false && this.isOpen()) {\n this.setOpen(false)\n }\n })\n }\n\n return element\n }\n\n private renderHeader(): void {\n const brand = this.config.brand\n if (brand === undefined) {\n return\n }\n\n const header = document.createElement('div')\n header.classList.add('sidebar__header')\n\n const row = document.createElement('div')\n row.classList.add('sidebar__header-row')\n\n const brandEl =\n brand.href !== undefined\n ? document.createElement('a')\n : brand.onClick !== undefined\n ? document.createElement('button')\n : document.createElement('span')\n\n brandEl.classList.add('sidebar__brand')\n\n if (brandEl instanceof HTMLAnchorElement) {\n brandEl.href = brand.href ?? '#'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brandEl instanceof HTMLButtonElement) {\n brandEl.type = 'button'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brand.onClick !== undefined) {\n brandEl.addEventListener('click', brand.onClick)\n }\n\n brandEl.appendChild(\n createBrandLockupElement({\n label: brand.label ?? 'CounterMeasure',\n markSize: brand.markSize ?? 22,\n showWordmark: brand.showWordmark ?? true,\n decorative: brand.decorative ?? false,\n })\n )\n\n row.appendChild(brandEl)\n header.appendChild(row)\n this.aside.appendChild(header)\n }\n\n private renderScope(): void {\n const scope = this.config.scope\n if (scope === undefined || scope.options.length === 0) {\n return\n }\n\n const activeOption =\n scope.options.find(option => option.id === scope.value) ?? scope.options[0] ?? null\n const root = document.createElement('div')\n root.classList.add('sidebar__scope')\n\n const trigger = document.createElement('button')\n trigger.type = 'button'\n trigger.classList.add('sidebar__scope-trigger')\n trigger.setAttribute('aria-haspopup', 'listbox')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.setAttribute('title', activeOption?.label ?? scope.placeholder ?? 'Select scope')\n\n if (scope.icon !== undefined) {\n trigger.appendChild(createIconSvg(this.iconSet, scope.icon, 'sidebar__scope-icon'))\n }\n\n const copy = document.createElement('span')\n copy.classList.add('sidebar__scope-copy')\n\n if (scope.label !== undefined) {\n const eyebrow = document.createElement('span')\n eyebrow.classList.add('sidebar__scope-label')\n eyebrow.textContent = scope.label\n copy.appendChild(eyebrow)\n }\n\n const current = document.createElement('span')\n current.classList.add('sidebar__scope-current')\n current.textContent = activeOption?.label ?? scope.placeholder ?? 'Select scope'\n copy.appendChild(current)\n trigger.appendChild(copy)\n\n const chevron = createIconSvg(this.iconSet, 'chevron-down', 'sidebar__scope-chevron')\n trigger.appendChild(chevron)\n\n const menu = document.createElement('div')\n menu.classList.add('sidebar__scope-menu')\n menu.setAttribute('role', 'listbox')\n menu.hidden = true\n\n const setOpen = (open: boolean): void => {\n trigger.setAttribute('aria-expanded', String(open))\n menu.hidden = !open\n }\n\n for (const option of scope.options) {\n const optionButton = document.createElement('button')\n optionButton.type = 'button'\n optionButton.classList.add('sidebar__scope-option')\n optionButton.setAttribute('role', 'option')\n optionButton.setAttribute('data-option-id', option.id)\n optionButton.setAttribute('aria-selected', String(option.id === activeOption?.id))\n\n if (option.disabled === true) {\n optionButton.disabled = true\n }\n\n if (option.status !== undefined) {\n const dot = document.createElement('span')\n dot.classList.add('sidebar__scope-dot', `sidebar__scope-dot--${option.status}`)\n optionButton.appendChild(dot)\n }\n\n const label = document.createElement('span')\n label.classList.add('sidebar__scope-option-label')\n label.textContent = option.label\n optionButton.appendChild(label)\n\n const check = createIconSvg(this.iconSet, 'check', 'sidebar__scope-check')\n optionButton.appendChild(check)\n\n optionButton.addEventListener('click', () => {\n current.textContent = option.label\n trigger.setAttribute('title', option.label)\n menu.querySelectorAll<HTMLElement>('[role=\"option\"]').forEach(item => {\n item.setAttribute(\n 'aria-selected',\n String(item.getAttribute('data-option-id') === option.id)\n )\n })\n setOpen(false)\n scope.onChange?.(option)\n })\n\n menu.appendChild(optionButton)\n }\n\n trigger.addEventListener('click', () => {\n setOpen(menu.hidden === true)\n })\n\n const closeOnOutsidePointer = (event: PointerEvent): void => {\n if (!root.contains(event.target as Node)) {\n setOpen(false)\n }\n }\n document.addEventListener('pointerdown', closeOnOutsidePointer)\n this.cleanupFns.push(() => {\n document.removeEventListener('pointerdown', closeOnOutsidePointer)\n })\n\n root.appendChild(trigger)\n root.appendChild(menu)\n this.aside.appendChild(root)\n }\n\n private renderCollapseButton(): void {\n const button = document.createElement('button')\n button.type = 'button'\n button.classList.add('sidebar__collapse-btn', 'sidebar__collapse-btn--edge')\n button.setAttribute('data-sidebar-toggle', '')\n\n if (this.config.collapseButtonVisible === true) {\n button.setAttribute('data-visible', 'true')\n }\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('aria-hidden', 'true')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('stroke-linecap', 'round')\n svg.setAttribute('stroke-linejoin', 'round')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n svg.appendChild(path)\n button.appendChild(svg)\n\n button.addEventListener('click', () => {\n this.toggleCollapse()\n })\n\n this.collapseButton = button\n this.updateCollapseButton()\n this.aside.appendChild(button)\n }\n\n private renderFooter(): void {\n const hasUser = this.config.user !== undefined\n const hasActions =\n this.config.footerActions !== undefined && this.config.footerActions.length > 0\n\n if (!hasUser && !hasActions) {\n return\n }\n\n const footer = document.createElement('div')\n footer.classList.add('sidebar__footer')\n\n const footerBar = document.createElement('div')\n footerBar.classList.add('sidebar__footer-bar')\n\n if (hasUser && this.config.user) {\n const user = this.config.user\n const userEl =\n user.onClick !== undefined\n ? document.createElement('button')\n : document.createElement('span')\n userEl.classList.add('sidebar__user-trigger', 'sidebar__footer-user')\n\n const userClick = user.onClick\n if (userEl instanceof HTMLButtonElement && userClick !== undefined) {\n userEl.type = 'button'\n userEl.setAttribute('aria-label', user.label ?? `User menu for ${user.name}`)\n userEl.addEventListener('click', userClick)\n }\n\n const avatar = document.createElement('span')\n avatar.classList.add('sidebar__avatar', 'sidebar__footer-avatar')\n\n if (user.avatarUrl !== undefined) {\n const image = document.createElement('img')\n image.src = user.avatarUrl\n image.alt = ''\n avatar.appendChild(image)\n } else {\n avatar.textContent = user.initials ?? toInitials(user.name)\n }\n\n if (user.presence !== undefined && user.presence !== 'offline') {\n const presence = document.createElement('span')\n presence.classList.add('sidebar__presence', `sidebar__presence--${user.presence}`)\n presence.setAttribute('aria-hidden', 'true')\n avatar.appendChild(presence)\n }\n\n const details = document.createElement('span')\n details.classList.add('sidebar__user-details')\n\n const nameSpan = document.createElement('span')\n nameSpan.classList.add('sidebar__user-name', 'sidebar__footer-name')\n nameSpan.textContent = user.name\n details.appendChild(nameSpan)\n\n if (user.detail !== undefined) {\n const detail = document.createElement('span')\n detail.classList.add('sidebar__user-status')\n detail.textContent = user.detail\n details.appendChild(detail)\n }\n\n userEl.appendChild(avatar)\n userEl.appendChild(details)\n footerBar.appendChild(userEl)\n }\n\n if (hasActions && this.config.footerActions) {\n const iconsSpan = document.createElement('span')\n iconsSpan.classList.add('sidebar__footer-icons')\n\n for (const action of this.config.footerActions) {\n const button = document.createElement('button')\n button.type = 'button'\n button.classList.add('sidebar__footer-icon')\n if (action.danger === true) {\n button.classList.add('sidebar__footer-icon--danger')\n }\n button.setAttribute('aria-label', action.label)\n button.setAttribute('title', action.label)\n\n const icon = createIconSvg(this.iconSet, action.icon)\n button.appendChild(icon)\n\n if (action.onClick) {\n const handler = action.onClick\n button.addEventListener('click', () => {\n handler()\n })\n }\n\n iconsSpan.appendChild(button)\n }\n\n footerBar.appendChild(iconsSpan)\n }\n\n footer.appendChild(footerBar)\n this.aside.appendChild(footer)\n }\n\n private renderBackdrop(): void {\n const backdrop = document.createElement('button')\n backdrop.type = 'button'\n backdrop.classList.add('sidebar__backdrop')\n backdrop.setAttribute('data-sidebar-backdrop', this.variant)\n backdrop.setAttribute('data-visible', String(this.isOpen()))\n backdrop.setAttribute('aria-label', 'Close sidebar')\n backdrop.addEventListener('click', () => {\n this.setOpen(false)\n })\n this.backdrop = backdrop\n this.container.appendChild(backdrop)\n }\n\n private setupBehavior(): void {\n this.setupKeyboardNavigation()\n this.setupMobileToggles()\n\n const handleEscape = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') {\n if (this.isOpen()) {\n this.setOpen(false)\n }\n this.closeScopeMenus()\n }\n }\n document.addEventListener('keydown', handleEscape)\n this.cleanupFns.push(() => {\n document.removeEventListener('keydown', handleEscape)\n })\n\n const handleResize = (): void => {\n if (isMobileViewport(this.getMobileBreakpoint())) {\n this.setOpen(false)\n }\n }\n window.addEventListener('resize', handleResize)\n this.cleanupFns.push(() => {\n window.removeEventListener('resize', handleResize)\n })\n }\n\n private setupKeyboardNavigation(): void {\n const handler = (event: KeyboardEvent): void => {\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return\n\n const items = Array.from(\n this.aside.querySelectorAll<HTMLElement>('[data-nav-item]:not([aria-disabled=\"true\"])')\n ).filter(item => !item.hidden && item.offsetParent !== null)\n\n if (items.length === 0) return\n\n const currentIndex = items.indexOf(document.activeElement as HTMLElement)\n if (currentIndex === -1) return\n\n event.preventDefault()\n const nextIndex =\n event.key === 'ArrowDown'\n ? (currentIndex + 1) % items.length\n : (currentIndex - 1 + items.length) % items.length\n items[nextIndex]?.focus()\n }\n\n this.aside.addEventListener('keydown', handler)\n this.cleanupFns.push(() => {\n this.aside.removeEventListener('keydown', handler)\n })\n }\n\n private setupMobileToggles(): void {\n const toggles = Array.from(\n document.querySelectorAll<HTMLButtonElement>('[data-sidebar-mobile-toggle]')\n ).filter(toggle => {\n const target = toggle.getAttribute('data-sidebar-mobile-toggle')\n return target === null || target === '' || target === this.variant\n })\n\n for (const toggle of toggles) {\n const handler = (): void => {\n this.setOpen(!this.isOpen())\n }\n toggle.addEventListener('click', handler)\n this.cleanupFns.push(() => {\n toggle.removeEventListener('click', handler)\n })\n }\n }\n\n /** Mark a nav item as active, removing active state from all others. */\n setActive(itemId: string): void {\n this.config.activeItemId = itemId\n this.aside.querySelectorAll<HTMLElement>('.sidebar__item').forEach(el => {\n el.classList.remove('sidebar__item--active')\n el.removeAttribute('aria-current')\n })\n\n const target = Array.from(this.aside.querySelectorAll<HTMLElement>('[data-item-id]')).find(\n item => item.getAttribute('data-item-id') === itemId\n )\n if (target) {\n target.classList.add('sidebar__item--active')\n target.setAttribute('aria-current', 'page')\n }\n }\n\n /** Recompute active route state from a supplied pathname or the current location. */\n setPathname(pathname: string | undefined): void {\n if (pathname === undefined) {\n delete this.config.pathname\n } else {\n this.config.pathname = pathname\n }\n delete this.config.activeItemId\n this.syncActiveRouteState()\n }\n\n /** Update the badge count for a nav item (empty string when count is 0). */\n updateBadge(itemId: string, count: number, tone?: SidebarBadgeTone): void {\n const item = Array.from(this.aside.querySelectorAll<HTMLElement>('[data-item-id]')).find(\n element => element.getAttribute('data-item-id') === itemId\n )\n\n if (!item) {\n return\n }\n\n this.applyBadge(\n item,\n itemId,\n normalizeBadge(\n count,\n tone ?? (item.getAttribute('data-badge-tone') as SidebarBadgeTone | null) ?? undefined\n )\n )\n }\n\n /** Toggle the sidebar between collapsed and expanded states. */\n toggleCollapse(): void {\n this.setCollapsed(!this.isCollapsed())\n }\n\n /** Collapse the sidebar. */\n collapse(): void {\n this.setCollapsed(true)\n }\n\n /** Expand the sidebar. */\n expand(): void {\n this.setCollapsed(false)\n }\n\n /** Set the mobile open state reflected by the shared CSS contract. */\n setOpen(open: boolean): void {\n const wasOpen = this.isOpen()\n this.aside.setAttribute('data-open', String(open))\n this.backdrop?.setAttribute('data-visible', String(open))\n\n if (wasOpen !== open) {\n this.config.onOpenChange?.(open)\n }\n }\n\n /** Remove the sidebar from the DOM. */\n destroy(): void {\n for (const cleanup of this.cleanupFns.splice(0)) {\n cleanup()\n }\n this.backdrop?.remove()\n this.aside.remove()\n }\n\n private applyBadge(item: HTMLElement, itemId: string, badge: NormalizedBadge | null): void {\n if (badge === null) {\n return\n }\n\n let badgeEl = item.querySelector<HTMLElement>(`[data-badge=\"${itemId}\"]`)\n if (badgeEl === null) {\n badgeEl = document.createElement('span')\n badgeEl.classList.add('sidebar__badge')\n badgeEl.setAttribute('data-badge', itemId)\n item.appendChild(badgeEl)\n }\n\n badgeEl.className = `sidebar__badge sidebar__badge--${badge.tone}`\n badgeEl.textContent = badge.label\n if (badge.title !== undefined) {\n badgeEl.setAttribute('title', badge.title)\n } else {\n badgeEl.removeAttribute('title')\n }\n\n item.setAttribute('data-badge-visible', String(badge.visible))\n item.setAttribute('data-badge-dot', String(badge.dot))\n item.setAttribute('data-badge-tone', badge.tone)\n }\n\n private setCollapsed(collapsed: boolean): void {\n const wasCollapsed = this.isCollapsed()\n this.aside.classList.toggle('sidebar--collapsed', collapsed)\n this.persistCollapsed(collapsed)\n this.updateCollapseButton()\n\n if (wasCollapsed !== collapsed) {\n this.config.onCollapse?.(collapsed)\n }\n }\n\n private isCollapsed(): boolean {\n return this.aside.classList.contains('sidebar--collapsed')\n }\n\n private isOpen(): boolean {\n return this.aside.getAttribute('data-open') === 'true'\n }\n\n private getMobileBreakpoint(): number {\n return this.config.mobileBreakpoint ?? DEFAULT_MOBILE_BREAKPOINT\n }\n\n private resolveInitialCollapsed(): boolean {\n if (this.config.storageKey && this.config.persistCollapsed !== false && canUseStorage()) {\n try {\n if (!isMobileViewport(this.getMobileBreakpoint())) {\n return window.localStorage.getItem(this.config.storageKey) === 'true'\n }\n } catch {\n return this.config.collapsed === true\n }\n }\n\n return this.config.collapsed === true\n }\n\n private persistCollapsed(collapsed: boolean): void {\n if (!this.config.storageKey || this.config.persistCollapsed === false || !canUseStorage()) {\n return\n }\n\n try {\n window.localStorage.setItem(this.config.storageKey, String(collapsed))\n } catch {\n // Collapse state remains applied in memory when storage is unavailable.\n }\n }\n\n private getCurrentPathname(): string | null {\n if (this.config.pathname !== undefined) {\n return toPathname(this.config.pathname)\n }\n\n if (typeof window === 'undefined') {\n return null\n }\n\n return window.location.pathname\n }\n\n private isItemActive(item: SidebarNavItem): boolean {\n if (item.active === true || item.id === this.config.activeItemId) {\n return true\n }\n\n const pathname = this.getCurrentPathname()\n if (pathname === null) {\n return false\n }\n\n const matcher = item.activeMatch\n\n if (typeof matcher === 'function') {\n return matcher(pathname, item)\n }\n\n if (matcher instanceof RegExp) {\n return matcher.test(pathname)\n }\n\n if (typeof matcher === 'string' && matcher !== 'exact' && matcher !== 'prefix') {\n return pathname === matcher || pathname.startsWith(`${matcher.replace(/\\/$/, '')}/`)\n }\n\n if (item.href === undefined) {\n return false\n }\n\n try {\n const baseUrl = typeof window === 'undefined' ? FALLBACK_URL_BASE : window.location.href\n const hrefPathname = new URL(item.href, baseUrl).pathname\n if (matcher === 'exact' || item.end === true) {\n return pathname === hrefPathname\n }\n return pathname === hrefPathname || pathname.startsWith(`${hrefPathname.replace(/\\/$/, '')}/`)\n } catch {\n return false\n }\n }\n\n private syncActiveRouteState(): void {\n this.aside.querySelectorAll<HTMLElement>('.sidebar__item').forEach(el => {\n el.classList.remove('sidebar__item--active')\n el.removeAttribute('aria-current')\n })\n\n const active = Array.from(this.aside.querySelectorAll<HTMLElement>('[data-item-id]')).find(\n element => {\n const itemId = element.getAttribute('data-item-id')\n const item = this.config.sections\n .flatMap(section => section.items)\n .find(candidate => candidate.id === itemId)\n return item === undefined ? false : this.isItemActive(item)\n }\n )\n\n if (active !== undefined) {\n active.classList.add('sidebar__item--active')\n active.setAttribute('aria-current', 'page')\n }\n }\n\n private closeScopeMenus(): void {\n this.aside.querySelectorAll<HTMLElement>('.sidebar__scope-menu').forEach(menu => {\n menu.hidden = true\n })\n this.aside.querySelectorAll<HTMLElement>('.sidebar__scope-trigger').forEach(trigger => {\n trigger.setAttribute('aria-expanded', 'false')\n })\n }\n\n private updateCollapseButton(): void {\n if (this.collapseButton === null) {\n return\n }\n\n const isCollapsed = this.isCollapsed()\n const label = isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'\n this.collapseButton.setAttribute('aria-label', label)\n this.collapseButton.setAttribute('aria-expanded', String(!isCollapsed))\n this.collapseButton.setAttribute('title', label)\n this.collapseButton.setAttribute('data-collapsed', String(isCollapsed))\n this.collapseButton\n .querySelector('path')\n ?.setAttribute('d', isCollapsed ? 'm9 18 6-6-6-6' : 'm15 18-6-6 6-6')\n }\n}\n"],"mappings":";;;;;AAsBA,IAAM,IAA4B,KAC5B,IAAoB;AAU1B,SAAS,EAA0B,GAAyB;CAK1D,OAAO,YAJY,EAChB,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,UAAU,EACF,KAAc;AACnC;AAEA,SAAS,EAAW,GAAsB;CACxC,IAAM,IAAQ,EAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;CAMrD,OAJI,EAAM,UAAU,IACX,GAAG,EAAM,IAAI,OAAO,CAAC,KAAK,KAAK,EAAM,EAAM,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY,IAGxF,EAAK,MAAM,GAAG,CAAC,EAAE,YAAY;AACtC;AAEA,SAAS,IAAyB;CAChC,IAAI;EACF,OAAO,OAAO,SAAW,OAAe,OAAO,iBAAiB,KAAA;CAClE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,EAAW,GAAuB;CACzC,IAAI;EACF,OAAO,IAAI,IAAI,GAAO,CAAiB,EAAE;CAC3C,QAAQ;EACN,OAAO,EAAM,MAAM,QAAQ,CAAC,EAAE,MAAM;CACtC;AACF;AAEA,SAAS,EAAiB,GAA6B;CACrD,OAAO,OAAO,SAAW,OAAe,OAAO,cAAc;AAC/D;AAEA,SAAS,EACP,GACA,GACwB;CACxB,IAAI,MAAU,KAAA,GACZ,OAAO;CAGT,IAAI,OAAO,KAAU,UACnB,OAAO;EACL,OAAO,IAAQ,IAAI,OAAO,CAAK,IAAI;EACnC,MAAM,KAAgB;EACtB,SAAS,IAAQ;EACjB,KAAK,IAAQ;CACf;CAGF,IAAM,IAAQ,EAAM,OACd,IAA8B;EAClC;EACA,MAAM,EAAM,QAAQ,KAAgB;EACpC,SAAS,EAAM,SAAS,KAAK,EAAM,QAAQ;EAC3C,KAAK,EAAM,OAAO,EAAM,SAAS;CACnC;CAIA,OAHI,EAAM,UAAU,KAAA,MAClB,EAAW,QAAQ,EAAM,QAEpB;AACT;AAGA,SAAS,EACP,GACA,GACA,IAAY,sBACA;CACZ,IAAM,IAAQ,8BACR,IAAM,SAAS,gBAAgB,GAAO,KAAK;CAYjD,AAXA,EAAI,aAAa,SAAS,CAAK,GAC/B,EAAI,aAAa,SAAS,IAAI,GAC9B,EAAI,aAAa,UAAU,IAAI,GAC/B,EAAI,aAAa,WAAW,WAAW,GACvC,EAAI,aAAa,QAAQ,MAAM,GAC/B,EAAI,aAAa,UAAU,cAAc,GACzC,EAAI,aAAa,gBAAgB,GAAG,GACpC,EAAI,aAAa,kBAAkB,OAAO,GAC1C,EAAI,aAAa,mBAAmB,OAAO,GAC3C,EAAI,UAAU,IAAI,CAAS,GAC3B,EAAI,aAAa,aAAa,CAAI,GAClC,EAAI,aAAa,eAAe,MAAM;CAEtC,IAAM,IAAQ,EAAgB,GAAS,CAAI;CAK3C,OAJI,KACF,EAAgB,GAAK,CAAK,GAGrB;AACT;AAEA,SAAS,EACP,GACA,GACM;CACN,IAAI,MAAsB,KAAA,GACxB;CAGF,IAAM,IAAW,MAAM,QAAQ,CAAiB,IAAI,IAAoB,CAAC,CAAiB;CAC1F,KAAK,IAAM,KAAW,GACpB,EAAO,YAAY,CAAO;AAE9B;AAEA,IAAa,IAAb,MAA8B;CAC5B;CACA;CACA;CACA;CACA;CACA,aAA8C,CAAC;CAC/C,iBAAmD;CACnD,WAAuC;CAEvC,YAAY,GAAgC;EA0B1C,AAzBA,KAAK,SAAS,GACd,KAAK,YAAY,EAAiB,EAAO,SAAS,GAClD,KAAK,UAAU,EAAO,WAAW,UACjC,KAAK,UAAU,EAAO,WAAW,OAEjC,KAAK,QAAQ,SAAS,cAAc,OAAO,GAC3C,KAAK,MAAM,UAAU,IAAI,WAAW,EAA0B,KAAK,OAAO,CAAC,IACvE,KAAK,YAAY,oBAAoB,KAAK,YAAY,SACxD,KAAK,MAAM,UAAU,IAAI,kBAAkB,GAE7C,KAAK,MAAM,aAAa,gBAAgB,KAAK,OAAO,GACpD,KAAK,MAAM,aAAa,aAAa,OAAO,EAAO,SAAS,EAAI,CAAC,GACjE,KAAK,MAAM,aAAa,cAAc,oBAAoB,GAEtD,KAAK,wBAAwB,KAC/B,KAAK,MAAM,UAAU,IAAI,oBAAoB,GAG/C,KAAK,OAAO,GACZ,KAAK,UAAU,YAAY,KAAK,KAAK,GAEjC,EAAO,mBAAmB,MAC5B,KAAK,eAAe,GAGtB,KAAK,cAAc;CACrB;CAEA,SAAuB;EAMrB,AALI,KAAK,OAAO,gBAAgB,MAC9B,KAAK,qBAAqB,GAG5B,KAAK,aAAa,GAClB,KAAK,YAAY;EAEjB,IAAM,IAAO,SAAS,cAAc,KAAK;EAIzC,AAHA,EAAK,UAAU,IAAI,eAAe,GAClC,EAAK,aAAa,cAAc,SAAS,GAEzC,EAAe,GAAM,KAAK,OAAO,SAAS;EAE1C,KAAK,IAAM,KAAW,KAAK,OAAO,UAChC,EAAK,YAAY,KAAK,aAAa,CAAO,CAAC;EAQ7C,AALA,EAAe,GAAM,KAAK,OAAO,QAAQ,GAEzC,KAAK,MAAM,YAAY,CAAI,GAC3B,KAAK,aAAa,GAEd,KAAK,OAAO,iBAAiB,KAAA,KAC/B,KAAK,UAAU,KAAK,OAAO,YAAY;CAE3C;CAEA,aAAqB,GAAsC;EACzD,IAAM,IAAY,SAAS,cAAc,KAAK;EAE9C,AADA,EAAU,UAAU,IAAI,kBAAkB,GAC1C,EAAU,aAAa,mBAAmB,EAAQ,EAAE;EAEpD,IAAM,IAAc,EAAQ,gBAAgB,IACtC,IAAW,EAAQ,oBAAoB;EAE7C,IAAI,KAAe,EAAQ,OAAO;GAEhC,AADA,EAAU,UAAU,IAAI,+BAA+B,GACnD,KAAU,EAAU,UAAU,IAAI,4BAA4B;GAElE,IAAM,IAAS,SAAS,cAAc,QAAQ;GAM9C,AALA,EAAO,OAAO,UACd,EAAO,UAAU,IAAI,uBAAuB,GAC5C,EAAO,aAAa,iBAAiB,OAAO,CAAQ,CAAC,GACrD,EAAO,aAAa,iBAAiB,iBAAiB,EAAQ,IAAI,GAE9D,EAAQ,QACV,EAAO,YAAY,EAAc,KAAK,SAAS,EAAQ,IAAI,CAAC;GAG9D,IAAM,IAAY,SAAS,cAAc,MAAM;GAG/C,AAFA,EAAU,UAAU,IAAI,sBAAsB,GAC9C,EAAU,cAAc,EAAQ,OAChC,EAAO,YAAY,CAAS;GAE5B,IAAM,IAAU,SAAS,gBAAgB,8BAA8B,KAAK;GAU5E,AATA,EAAQ,aAAa,SAAS,wBAAwB,GACtD,EAAQ,aAAa,WAAW,WAAW,GAC3C,EAAQ,aAAa,SAAS,IAAI,GAClC,EAAQ,aAAa,UAAU,IAAI,GACnC,EAAQ,aAAa,QAAQ,MAAM,GACnC,EAAQ,aAAa,UAAU,cAAc,GAC7C,EAAQ,aAAa,gBAAgB,GAAG,GACxC,EAAQ,aAAa,kBAAkB,OAAO,GAC9C,EAAQ,aAAa,mBAAmB,OAAO,GAC/C,EAAQ,aAAa,eAAe,MAAM;GAC1C,IAAM,IAAc,SAAS,gBAAgB,8BAA8B,MAAM;GAUjF,AATA,EAAY,aAAa,KAAK,cAAc,GAC5C,EAAQ,YAAY,CAAW,GAC/B,EAAO,YAAY,CAAO,GAE1B,EAAO,iBAAiB,eAAe;IACrC,IAAM,IAAc,EAAU,UAAU,OAAO,4BAA4B;IAC3E,EAAO,aAAa,iBAAiB,OAAO,CAAW,CAAC;GAC1D,CAAC,GAED,EAAU,YAAY,CAAM;EAC9B,OAAO,IAAI,EAAQ,OAAO;GACxB,IAAM,IAAU,SAAS,cAAc,KAAK;GAG5C,AAFA,EAAQ,UAAU,IAAI,wBAAwB,GAC9C,EAAQ,cAAc,EAAQ,OAC9B,EAAU,YAAY,CAAO;EAC/B;EAEA,IAAM,IAAY,SAAS,cAAc,KAAK;EAE9C,AADA,EAAU,UAAU,IAAI,gBAAgB,GACxC,EAAU,KAAK,iBAAiB,EAAQ;EAExC,KAAK,IAAM,KAAQ,EAAQ,OACzB,EAAU,YAAY,KAAK,UAAU,CAAI,CAAC;EAI5C,OADA,EAAU,YAAY,CAAS,GACxB;CACT;CAEA,UAAkB,GAAmC;EACnD,IAAM,IAAW,EAAK,aAAa,IAC7B,IACJ,EAAK,SAAS,KAAA,KAAa,CAAC,IACxB,SAAS,cAAc,GAAG,IAC1B,IACE,SAAS,cAAc,MAAM,IAC7B,SAAS,cAAc,QAAQ;EAmCvC,AAjCA,EAAQ,UAAU,IAAI,eAAe,GACrC,EAAQ,aAAa,gBAAgB,EAAK,EAAE,GAC5C,EAAQ,aAAa,iBAAiB,EAAE,GACxC,EAAQ,aAAa,SAAS,EAAK,WAAW,EAAK,KAAK,GAEpD,EAAK,cAAc,KAAA,KACrB,EAAQ,aAAa,cAAc,EAAK,SAAS,GAG/C,KACF,EAAQ,aAAa,iBAAiB,MAAM,GAC5C,EAAQ,aAAa,QAAQ,MAAM,GACnC,EAAQ,aAAa,YAAY,IAAI,GACrC,EAAQ,UAAU,IAAI,yBAAyB,KACtC,aAAmB,qBAC5B,EAAQ,OAAO,EAAK,QAAQ,KACxB,EAAK,WAAW,KAAA,MAClB,EAAQ,SAAS,EAAK,SAEpB,EAAK,QAAQ,KAAA,IAEN,EAAK,WAAW,aACzB,EAAQ,MAAM,yBAFd,EAAQ,MAAM,EAAK,OAIZ,aAAmB,sBAC5B,EAAQ,OAAO,WAGb,KAAK,aAAa,CAAI,MACxB,EAAQ,UAAU,IAAI,uBAAuB,GAC7C,EAAQ,aAAa,gBAAgB,MAAM,IAGzC,EAAK,QACP,EAAQ,YAAY,EAAc,KAAK,SAAS,EAAK,IAAI,CAAC;EAG5D,IAAM,IAAQ,SAAS,cAAc,MAAM;EAK3C,IAJA,EAAM,UAAU,IAAI,qBAAqB,GACzC,EAAM,cAAc,EAAK,OACzB,EAAQ,YAAY,CAAK,GAErB,EAAK,QAAQ,KAAA,GAAW;GAC1B,IAAM,IAAM,SAAS,cAAc,MAAM;GAGzC,AAFA,EAAI,UAAU,IAAI,cAAc,GAChC,EAAI,cAAc,EAAK,KACvB,EAAQ,YAAY,CAAG;EACzB;EAEA,IAAM,IAAQ,EAAe,EAAK,OAAO,EAAK,SAAS;EAgBvD,OAfI,GAAO,YAAY,MACrB,KAAK,WAAW,GAAS,EAAK,IAAI,CAAK,GAGpC,KACH,EAAQ,iBAAiB,UAAS,MAAS;GAIzC,AAHA,KAAK,OAAO,aAAa,CAAI,GAC7B,EAAK,UAAU,CAAK,GAEhB,KAAK,OAAO,oBAAoB,MAAS,KAAK,OAAO,KACvD,KAAK,QAAQ,EAAK;EAEtB,CAAC,GAGI;CACT;CAEA,eAA6B;EAC3B,IAAM,IAAQ,KAAK,OAAO;EAC1B,IAAI,MAAU,KAAA,GACZ;EAGF,IAAM,IAAS,SAAS,cAAc,KAAK;EAC3C,EAAO,UAAU,IAAI,iBAAiB;EAEtC,IAAM,IAAM,SAAS,cAAc,KAAK;EACxC,EAAI,UAAU,IAAI,qBAAqB;EAEvC,IAAM,IACJ,EAAM,SAAS,KAAA,IAEX,EAAM,YAAY,KAAA,IAEhB,SAAS,cAAc,MAAM,IAD7B,SAAS,cAAc,QAAQ,IAFjC,SAAS,cAAc,GAAG;EAgChC,AA3BA,EAAQ,UAAU,IAAI,gBAAgB,GAElC,aAAmB,sBACrB,EAAQ,OAAO,EAAM,QAAQ,KAC7B,EAAQ,aAAa,cAAc,EAAM,SAAS,gBAAgB,IAGhE,aAAmB,sBACrB,EAAQ,OAAO,UACf,EAAQ,aAAa,cAAc,EAAM,SAAS,gBAAgB,IAGhE,EAAM,YAAY,KAAA,KACpB,EAAQ,iBAAiB,SAAS,EAAM,OAAO,GAGjD,EAAQ,YACN,EAAyB;GACvB,OAAO,EAAM,SAAS;GACtB,UAAU,EAAM,YAAY;GAC5B,cAAc,EAAM,gBAAgB;GACpC,YAAY,EAAM,cAAc;EAClC,CAAC,CACH,GAEA,EAAI,YAAY,CAAO,GACvB,EAAO,YAAY,CAAG,GACtB,KAAK,MAAM,YAAY,CAAM;CAC/B;CAEA,cAA4B;EAC1B,IAAM,IAAQ,KAAK,OAAO;EAC1B,IAAI,MAAU,KAAA,KAAa,EAAM,QAAQ,WAAW,GAClD;EAGF,IAAM,IACJ,EAAM,QAAQ,MAAK,MAAU,EAAO,OAAO,EAAM,KAAK,KAAK,EAAM,QAAQ,MAAM,MAC3E,IAAO,SAAS,cAAc,KAAK;EACzC,EAAK,UAAU,IAAI,gBAAgB;EAEnC,IAAM,IAAU,SAAS,cAAc,QAAQ;EAO/C,AANA,EAAQ,OAAO,UACf,EAAQ,UAAU,IAAI,wBAAwB,GAC9C,EAAQ,aAAa,iBAAiB,SAAS,GAC/C,EAAQ,aAAa,iBAAiB,OAAO,GAC7C,EAAQ,aAAa,SAAS,GAAc,SAAS,EAAM,eAAe,cAAc,GAEpF,EAAM,SAAS,KAAA,KACjB,EAAQ,YAAY,EAAc,KAAK,SAAS,EAAM,MAAM,qBAAqB,CAAC;EAGpF,IAAM,IAAO,SAAS,cAAc,MAAM;EAG1C,IAFA,EAAK,UAAU,IAAI,qBAAqB,GAEpC,EAAM,UAAU,KAAA,GAAW;GAC7B,IAAM,IAAU,SAAS,cAAc,MAAM;GAG7C,AAFA,EAAQ,UAAU,IAAI,sBAAsB,GAC5C,EAAQ,cAAc,EAAM,OAC5B,EAAK,YAAY,CAAO;EAC1B;EAEA,IAAM,IAAU,SAAS,cAAc,MAAM;EAI7C,AAHA,EAAQ,UAAU,IAAI,wBAAwB,GAC9C,EAAQ,cAAc,GAAc,SAAS,EAAM,eAAe,gBAClE,EAAK,YAAY,CAAO,GACxB,EAAQ,YAAY,CAAI;EAExB,IAAM,IAAU,EAAc,KAAK,SAAS,gBAAgB,wBAAwB;EACpF,EAAQ,YAAY,CAAO;EAE3B,IAAM,IAAO,SAAS,cAAc,KAAK;EAGzC,AAFA,EAAK,UAAU,IAAI,qBAAqB,GACxC,EAAK,aAAa,QAAQ,SAAS,GACnC,EAAK,SAAS;EAEd,IAAM,KAAW,MAAwB;GAEvC,AADA,EAAQ,aAAa,iBAAiB,OAAO,CAAI,CAAC,GAClD,EAAK,SAAS,CAAC;EACjB;EAEA,KAAK,IAAM,KAAU,EAAM,SAAS;GAClC,IAAM,IAAe,SAAS,cAAc,QAAQ;GAWpD,IAVA,EAAa,OAAO,UACpB,EAAa,UAAU,IAAI,uBAAuB,GAClD,EAAa,aAAa,QAAQ,QAAQ,GAC1C,EAAa,aAAa,kBAAkB,EAAO,EAAE,GACrD,EAAa,aAAa,iBAAiB,OAAO,EAAO,OAAO,GAAc,EAAE,CAAC,GAE7E,EAAO,aAAa,OACtB,EAAa,WAAW,KAGtB,EAAO,WAAW,KAAA,GAAW;IAC/B,IAAM,IAAM,SAAS,cAAc,MAAM;IAEzC,AADA,EAAI,UAAU,IAAI,sBAAsB,uBAAuB,EAAO,QAAQ,GAC9E,EAAa,YAAY,CAAG;GAC9B;GAEA,IAAM,IAAQ,SAAS,cAAc,MAAM;GAG3C,AAFA,EAAM,UAAU,IAAI,6BAA6B,GACjD,EAAM,cAAc,EAAO,OAC3B,EAAa,YAAY,CAAK;GAE9B,IAAM,IAAQ,EAAc,KAAK,SAAS,SAAS,sBAAsB;GAgBzE,AAfA,EAAa,YAAY,CAAK,GAE9B,EAAa,iBAAiB,eAAe;IAU3C,AATA,EAAQ,cAAc,EAAO,OAC7B,EAAQ,aAAa,SAAS,EAAO,KAAK,GAC1C,EAAK,iBAA8B,mBAAiB,EAAE,SAAQ,MAAQ;KACpE,EAAK,aACH,iBACA,OAAO,EAAK,aAAa,gBAAgB,MAAM,EAAO,EAAE,CAC1D;IACF,CAAC,GACD,EAAQ,EAAK,GACb,EAAM,WAAW,CAAM;GACzB,CAAC,GAED,EAAK,YAAY,CAAY;EAC/B;EAEA,EAAQ,iBAAiB,eAAe;GACtC,EAAQ,EAAK,WAAW,EAAI;EAC9B,CAAC;EAED,IAAM,KAAyB,MAA8B;GAC3D,AAAK,EAAK,SAAS,EAAM,MAAc,KACrC,EAAQ,EAAK;EAEjB;EAQA,AAPA,SAAS,iBAAiB,eAAe,CAAqB,GAC9D,KAAK,WAAW,WAAW;GACzB,SAAS,oBAAoB,eAAe,CAAqB;EACnE,CAAC,GAED,EAAK,YAAY,CAAO,GACxB,EAAK,YAAY,CAAI,GACrB,KAAK,MAAM,YAAY,CAAI;CAC7B;CAEA,uBAAqC;EACnC,IAAM,IAAS,SAAS,cAAc,QAAQ;EAK9C,AAJA,EAAO,OAAO,UACd,EAAO,UAAU,IAAI,yBAAyB,6BAA6B,GAC3E,EAAO,aAAa,uBAAuB,EAAE,GAEzC,KAAK,OAAO,0BAA0B,MACxC,EAAO,aAAa,gBAAgB,MAAM;EAG5C,IAAM,IAAM,SAAS,gBAAgB,8BAA8B,KAAK;EAOxE,AANA,EAAI,aAAa,eAAe,MAAM,GACtC,EAAI,aAAa,WAAW,WAAW,GACvC,EAAI,aAAa,QAAQ,MAAM,GAC/B,EAAI,aAAa,UAAU,cAAc,GACzC,EAAI,aAAa,gBAAgB,GAAG,GACpC,EAAI,aAAa,kBAAkB,OAAO,GAC1C,EAAI,aAAa,mBAAmB,OAAO;EAE3C,IAAM,IAAO,SAAS,gBAAgB,8BAA8B,MAAM;EAU1E,AATA,EAAI,YAAY,CAAI,GACpB,EAAO,YAAY,CAAG,GAEtB,EAAO,iBAAiB,eAAe;GACrC,KAAK,eAAe;EACtB,CAAC,GAED,KAAK,iBAAiB,GACtB,KAAK,qBAAqB,GAC1B,KAAK,MAAM,YAAY,CAAM;CAC/B;CAEA,eAA6B;EAC3B,IAAM,IAAU,KAAK,OAAO,SAAS,KAAA,GAC/B,IACJ,KAAK,OAAO,kBAAkB,KAAA,KAAa,KAAK,OAAO,cAAc,SAAS;EAEhF,IAAI,CAAC,KAAW,CAAC,GACf;EAGF,IAAM,IAAS,SAAS,cAAc,KAAK;EAC3C,EAAO,UAAU,IAAI,iBAAiB;EAEtC,IAAM,IAAY,SAAS,cAAc,KAAK;EAG9C,IAFA,EAAU,UAAU,IAAI,qBAAqB,GAEzC,KAAW,KAAK,OAAO,MAAM;GAC/B,IAAM,IAAO,KAAK,OAAO,MACnB,IACJ,EAAK,YAAY,KAAA,IAEb,SAAS,cAAc,MAAM,IAD7B,SAAS,cAAc,QAAQ;GAErC,EAAO,UAAU,IAAI,yBAAyB,sBAAsB;GAEpE,IAAM,IAAY,EAAK;GACvB,AAAI,aAAkB,qBAAqB,MAAc,KAAA,MACvD,EAAO,OAAO,UACd,EAAO,aAAa,cAAc,EAAK,SAAS,iBAAiB,EAAK,MAAM,GAC5E,EAAO,iBAAiB,SAAS,CAAS;GAG5C,IAAM,IAAS,SAAS,cAAc,MAAM;GAG5C,IAFA,EAAO,UAAU,IAAI,mBAAmB,wBAAwB,GAE5D,EAAK,cAAc,KAAA,GAAW;IAChC,IAAM,IAAQ,SAAS,cAAc,KAAK;IAG1C,AAFA,EAAM,MAAM,EAAK,WACjB,EAAM,MAAM,IACZ,EAAO,YAAY,CAAK;GAC1B,OACE,EAAO,cAAc,EAAK,YAAY,EAAW,EAAK,IAAI;GAG5D,IAAI,EAAK,aAAa,KAAA,KAAa,EAAK,aAAa,WAAW;IAC9D,IAAM,IAAW,SAAS,cAAc,MAAM;IAG9C,AAFA,EAAS,UAAU,IAAI,qBAAqB,sBAAsB,EAAK,UAAU,GACjF,EAAS,aAAa,eAAe,MAAM,GAC3C,EAAO,YAAY,CAAQ;GAC7B;GAEA,IAAM,IAAU,SAAS,cAAc,MAAM;GAC7C,EAAQ,UAAU,IAAI,uBAAuB;GAE7C,IAAM,IAAW,SAAS,cAAc,MAAM;GAK9C,IAJA,EAAS,UAAU,IAAI,sBAAsB,sBAAsB,GACnE,EAAS,cAAc,EAAK,MAC5B,EAAQ,YAAY,CAAQ,GAExB,EAAK,WAAW,KAAA,GAAW;IAC7B,IAAM,IAAS,SAAS,cAAc,MAAM;IAG5C,AAFA,EAAO,UAAU,IAAI,sBAAsB,GAC3C,EAAO,cAAc,EAAK,QAC1B,EAAQ,YAAY,CAAM;GAC5B;GAIA,AAFA,EAAO,YAAY,CAAM,GACzB,EAAO,YAAY,CAAO,GAC1B,EAAU,YAAY,CAAM;EAC9B;EAEA,IAAI,KAAc,KAAK,OAAO,eAAe;GAC3C,IAAM,IAAY,SAAS,cAAc,MAAM;GAC/C,EAAU,UAAU,IAAI,uBAAuB;GAE/C,KAAK,IAAM,KAAU,KAAK,OAAO,eAAe;IAC9C,IAAM,IAAS,SAAS,cAAc,QAAQ;IAO9C,AANA,EAAO,OAAO,UACd,EAAO,UAAU,IAAI,sBAAsB,GACvC,EAAO,WAAW,MACpB,EAAO,UAAU,IAAI,8BAA8B,GAErD,EAAO,aAAa,cAAc,EAAO,KAAK,GAC9C,EAAO,aAAa,SAAS,EAAO,KAAK;IAEzC,IAAM,IAAO,EAAc,KAAK,SAAS,EAAO,IAAI;IAGpD,IAFA,EAAO,YAAY,CAAI,GAEnB,EAAO,SAAS;KAClB,IAAM,IAAU,EAAO;KACvB,EAAO,iBAAiB,eAAe;MACrC,EAAQ;KACV,CAAC;IACH;IAEA,EAAU,YAAY,CAAM;GAC9B;GAEA,EAAU,YAAY,CAAS;EACjC;EAGA,AADA,EAAO,YAAY,CAAS,GAC5B,KAAK,MAAM,YAAY,CAAM;CAC/B;CAEA,iBAA+B;EAC7B,IAAM,IAAW,SAAS,cAAc,QAAQ;EAUhD,AATA,EAAS,OAAO,UAChB,EAAS,UAAU,IAAI,mBAAmB,GAC1C,EAAS,aAAa,yBAAyB,KAAK,OAAO,GAC3D,EAAS,aAAa,gBAAgB,OAAO,KAAK,OAAO,CAAC,CAAC,GAC3D,EAAS,aAAa,cAAc,eAAe,GACnD,EAAS,iBAAiB,eAAe;GACvC,KAAK,QAAQ,EAAK;EACpB,CAAC,GACD,KAAK,WAAW,GAChB,KAAK,UAAU,YAAY,CAAQ;CACrC;CAEA,gBAA8B;EAE5B,AADA,KAAK,wBAAwB,GAC7B,KAAK,mBAAmB;EAExB,IAAM,KAAgB,MAA+B;GACnD,AAAI,EAAM,QAAQ,aACZ,KAAK,OAAO,KACd,KAAK,QAAQ,EAAK,GAEpB,KAAK,gBAAgB;EAEzB;EAEA,AADA,SAAS,iBAAiB,WAAW,CAAY,GACjD,KAAK,WAAW,WAAW;GACzB,SAAS,oBAAoB,WAAW,CAAY;EACtD,CAAC;EAED,IAAM,UAA2B;GAC/B,AAAI,EAAiB,KAAK,oBAAoB,CAAC,KAC7C,KAAK,QAAQ,EAAK;EAEtB;EAEA,AADA,OAAO,iBAAiB,UAAU,CAAY,GAC9C,KAAK,WAAW,WAAW;GACzB,OAAO,oBAAoB,UAAU,CAAY;EACnD,CAAC;CACH;CAEA,0BAAwC;EACtC,IAAM,KAAW,MAA+B;GAC9C,IAAI,EAAM,QAAQ,eAAe,EAAM,QAAQ,WAAW;GAE1D,IAAM,IAAQ,MAAM,KAClB,KAAK,MAAM,iBAA8B,+CAA6C,CACxF,EAAE,QAAO,MAAQ,CAAC,EAAK,UAAU,EAAK,iBAAiB,IAAI;GAE3D,IAAI,EAAM,WAAW,GAAG;GAExB,IAAM,IAAe,EAAM,QAAQ,SAAS,aAA4B;GACpE,MAAiB,OAErB,EAAM,eAAe,GAKrB,EAHE,EAAM,QAAQ,eACT,IAAe,KAAK,EAAM,UAC1B,IAAe,IAAI,EAAM,UAAU,EAAM,SAC9B,MAAM;EAC1B;EAGA,AADA,KAAK,MAAM,iBAAiB,WAAW,CAAO,GAC9C,KAAK,WAAW,WAAW;GACzB,KAAK,MAAM,oBAAoB,WAAW,CAAO;EACnD,CAAC;CACH;CAEA,qBAAmC;EACjC,IAAM,IAAU,MAAM,KACpB,SAAS,iBAAoC,8BAA8B,CAC7E,EAAE,QAAO,MAAU;GACjB,IAAM,IAAS,EAAO,aAAa,4BAA4B;GAC/D,OAAO,MAAW,QAAQ,MAAW,MAAM,MAAW,KAAK;EAC7D,CAAC;EAED,KAAK,IAAM,KAAU,GAAS;GAC5B,IAAM,UAAsB;IAC1B,KAAK,QAAQ,CAAC,KAAK,OAAO,CAAC;GAC7B;GAEA,AADA,EAAO,iBAAiB,SAAS,CAAO,GACxC,KAAK,WAAW,WAAW;IACzB,EAAO,oBAAoB,SAAS,CAAO;GAC7C,CAAC;EACH;CACF;CAGA,UAAU,GAAsB;EAE9B,AADA,KAAK,OAAO,eAAe,GAC3B,KAAK,MAAM,iBAA8B,gBAAgB,EAAE,SAAQ,MAAM;GAEvE,AADA,EAAG,UAAU,OAAO,uBAAuB,GAC3C,EAAG,gBAAgB,cAAc;EACnC,CAAC;EAED,IAAM,IAAS,MAAM,KAAK,KAAK,MAAM,iBAA8B,gBAAgB,CAAC,EAAE,MACpF,MAAQ,EAAK,aAAa,cAAc,MAAM,CAChD;EACA,AAAI,MACF,EAAO,UAAU,IAAI,uBAAuB,GAC5C,EAAO,aAAa,gBAAgB,MAAM;CAE9C;CAGA,YAAY,GAAoC;EAO9C,AANI,MAAa,KAAA,IACf,OAAO,KAAK,OAAO,WAEnB,KAAK,OAAO,WAAW,GAEzB,OAAO,KAAK,OAAO,cACnB,KAAK,qBAAqB;CAC5B;CAGA,YAAY,GAAgB,GAAe,GAA+B;EACxE,IAAM,IAAO,MAAM,KAAK,KAAK,MAAM,iBAA8B,gBAAgB,CAAC,EAAE,MAClF,MAAW,EAAQ,aAAa,cAAc,MAAM,CACtD;EAEK,KAIL,KAAK,WACH,GACA,GACA,EACE,GACA,KAAS,EAAK,aAAa,iBAAiB,KAAiC,KAAA,CAC/E,CACF;CACF;CAGA,iBAAuB;EACrB,KAAK,aAAa,CAAC,KAAK,YAAY,CAAC;CACvC;CAGA,WAAiB;EACf,KAAK,aAAa,EAAI;CACxB;CAGA,SAAe;EACb,KAAK,aAAa,EAAK;CACzB;CAGA,QAAQ,GAAqB;EAC3B,IAAM,IAAU,KAAK,OAAO;EAI5B,AAHA,KAAK,MAAM,aAAa,aAAa,OAAO,CAAI,CAAC,GACjD,KAAK,UAAU,aAAa,gBAAgB,OAAO,CAAI,CAAC,GAEpD,MAAY,KACd,KAAK,OAAO,eAAe,CAAI;CAEnC;CAGA,UAAgB;EACd,KAAK,IAAM,KAAW,KAAK,WAAW,OAAO,CAAC,GAC5C,EAAQ;EAGV,AADA,KAAK,UAAU,OAAO,GACtB,KAAK,MAAM,OAAO;CACpB;CAEA,WAAmB,GAAmB,GAAgB,GAAqC;EACzF,IAAI,MAAU,MACZ;EAGF,IAAI,IAAU,EAAK,cAA2B,gBAAgB,EAAO,GAAG;EAkBxE,AAjBI,MAAY,SACd,IAAU,SAAS,cAAc,MAAM,GACvC,EAAQ,UAAU,IAAI,gBAAgB,GACtC,EAAQ,aAAa,cAAc,CAAM,GACzC,EAAK,YAAY,CAAO,IAG1B,EAAQ,YAAY,kCAAkC,EAAM,QAC5D,EAAQ,cAAc,EAAM,OACxB,EAAM,UAAU,KAAA,IAGlB,EAAQ,gBAAgB,OAAO,IAF/B,EAAQ,aAAa,SAAS,EAAM,KAAK,GAK3C,EAAK,aAAa,sBAAsB,OAAO,EAAM,OAAO,CAAC,GAC7D,EAAK,aAAa,kBAAkB,OAAO,EAAM,GAAG,CAAC,GACrD,EAAK,aAAa,mBAAmB,EAAM,IAAI;CACjD;CAEA,aAAqB,GAA0B;EAC7C,IAAM,IAAe,KAAK,YAAY;EAKtC,AAJA,KAAK,MAAM,UAAU,OAAO,sBAAsB,CAAS,GAC3D,KAAK,iBAAiB,CAAS,GAC/B,KAAK,qBAAqB,GAEtB,MAAiB,KACnB,KAAK,OAAO,aAAa,CAAS;CAEtC;CAEA,cAA+B;EAC7B,OAAO,KAAK,MAAM,UAAU,SAAS,oBAAoB;CAC3D;CAEA,SAA0B;EACxB,OAAO,KAAK,MAAM,aAAa,WAAW,MAAM;CAClD;CAEA,sBAAsC;EACpC,OAAO,KAAK,OAAO,oBAAoB;CACzC;CAEA,0BAA2C;EACzC,IAAI,KAAK,OAAO,cAAc,KAAK,OAAO,qBAAqB,MAAS,EAAc,GACpF,IAAI;GACF,IAAI,CAAC,EAAiB,KAAK,oBAAoB,CAAC,GAC9C,OAAO,OAAO,aAAa,QAAQ,KAAK,OAAO,UAAU,MAAM;EAEnE,QAAQ;GACN,OAAO,KAAK,OAAO,cAAc;EACnC;EAGF,OAAO,KAAK,OAAO,cAAc;CACnC;CAEA,iBAAyB,GAA0B;EAC7C,OAAC,KAAK,OAAO,cAAc,KAAK,OAAO,qBAAqB,MAAS,CAAC,EAAc,IAIxF,IAAI;GACF,OAAO,aAAa,QAAQ,KAAK,OAAO,YAAY,OAAO,CAAS,CAAC;EACvE,QAAQ,CAER;CACF;CAEA,qBAA4C;EAS1C,OARI,KAAK,OAAO,aAAa,KAAA,IAIzB,OAAO,SAAW,MACb,OAGF,OAAO,SAAS,WAPd,EAAW,KAAK,OAAO,QAAQ;CAQ1C;CAEA,aAAqB,GAA+B;EAClD,IAAI,EAAK,WAAW,MAAQ,EAAK,OAAO,KAAK,OAAO,cAClD,OAAO;EAGT,IAAM,IAAW,KAAK,mBAAmB;EACzC,IAAI,MAAa,MACf,OAAO;EAGT,IAAM,IAAU,EAAK;EAErB,IAAI,OAAO,KAAY,YACrB,OAAO,EAAQ,GAAU,CAAI;EAG/B,IAAI,aAAmB,QACrB,OAAO,EAAQ,KAAK,CAAQ;EAG9B,IAAI,OAAO,KAAY,YAAY,MAAY,WAAW,MAAY,UACpE,OAAO,MAAa,KAAW,EAAS,WAAW,GAAG,EAAQ,QAAQ,OAAO,EAAE,EAAE,EAAE;EAGrF,IAAI,EAAK,SAAS,KAAA,GAChB,OAAO;EAGT,IAAI;GACF,IAAM,IAAU,OAAO,SAAW,MAAc,IAAoB,OAAO,SAAS,MAC9E,IAAe,IAAI,IAAI,EAAK,MAAM,CAAO,EAAE;GAIjD,OAHI,MAAY,WAAW,EAAK,QAAQ,KAC/B,MAAa,IAEf,MAAa,KAAgB,EAAS,WAAW,GAAG,EAAa,QAAQ,OAAO,EAAE,EAAE,EAAE;EAC/F,QAAQ;GACN,OAAO;EACT;CACF;CAEA,uBAAqC;EACnC,KAAK,MAAM,iBAA8B,gBAAgB,EAAE,SAAQ,MAAM;GAEvE,AADA,EAAG,UAAU,OAAO,uBAAuB,GAC3C,EAAG,gBAAgB,cAAc;EACnC,CAAC;EAED,IAAM,IAAS,MAAM,KAAK,KAAK,MAAM,iBAA8B,gBAAgB,CAAC,EAAE,MACpF,MAAW;GACT,IAAM,IAAS,EAAQ,aAAa,cAAc,GAC5C,IAAO,KAAK,OAAO,SACtB,SAAQ,MAAW,EAAQ,KAAK,EAChC,MAAK,MAAa,EAAU,OAAO,CAAM;GAC5C,OAAO,MAAS,KAAA,IAAY,KAAQ,KAAK,aAAa,CAAI;EAC5D,CACF;EAEA,AAAI,MAAW,KAAA,MACb,EAAO,UAAU,IAAI,uBAAuB,GAC5C,EAAO,aAAa,gBAAgB,MAAM;CAE9C;CAEA,kBAAgC;EAI9B,AAHA,KAAK,MAAM,iBAA8B,sBAAsB,EAAE,SAAQ,MAAQ;GAC/E,EAAK,SAAS;EAChB,CAAC,GACD,KAAK,MAAM,iBAA8B,yBAAyB,EAAE,SAAQ,MAAW;GACrF,EAAQ,aAAa,iBAAiB,OAAO;EAC/C,CAAC;CACH;CAEA,uBAAqC;EACnC,IAAI,KAAK,mBAAmB,MAC1B;EAGF,IAAM,IAAc,KAAK,YAAY,GAC/B,IAAQ,IAAc,mBAAmB;EAK/C,AAJA,KAAK,eAAe,aAAa,cAAc,CAAK,GACpD,KAAK,eAAe,aAAa,iBAAiB,OAAO,CAAC,CAAW,CAAC,GACtE,KAAK,eAAe,aAAa,SAAS,CAAK,GAC/C,KAAK,eAAe,aAAa,kBAAkB,OAAO,CAAW,CAAC,GACtE,KAAK,eACF,cAAc,MAAM,GACnB,aAAa,KAAK,IAAc,kBAAkB,gBAAgB;CACxE;AACF"}
@@ -1,27 +1,27 @@
1
- import { t as e } from "../data-table-DcgJjvnu.js";
2
- import { t } from "../tree-view-CmCxQjBA.js";
3
- import { TabPanel as n } from "./tabs/index.js";
4
- import { SplitPane as r } from "./split-pane/index.js";
5
- import { Modal as i } from "./modal/index.js";
6
- import { ToastManager as a } from "./toast/index.js";
7
- import { CommandPalette as o } from "./search/command-palette.js";
8
- import { SearchInput as s } from "./search/index.js";
9
- import { Pagination as c } from "./pagination/index.js";
10
- import { CopyButton as l } from "./copy-button/index.js";
11
- import { StatusBar as u } from "./status-bar/index.js";
12
- import { ContextMenu as d } from "./context-menu/index.js";
13
- import { LogToolbar as f } from "./log-toolbar/index.js";
14
- import { DetailHeader as p } from "./detail-header/index.js";
15
- import { AccentSwitcher as m, applyAccentFromUrl as h, getCurrentAccent as g, setPreviewAccent as _ } from "./theme/accent-switcher.js";
16
- import { DensitySwitcher as v } from "./theme/density-switcher.js";
17
- import { FontStackPicker as y } from "./theme/font-stack-picker.js";
18
- import { GlassSlider as b } from "./theme/glass-slider.js";
19
- import { IconSetPicker as x } from "./theme/icon-set-picker.js";
20
- import { IconUsageMatrix as S } from "./theme/icon-usage-matrix.js";
21
- import { RadiusSlider as C } from "./theme/radius-slider.js";
22
- import { ThemePresetGrid as w } from "./theme/theme-preset-grid.js";
23
- import { ThemePreviewTile as T } from "./theme/theme-preview-tile.js";
24
- import { n as E, t as D } from "../theme-studio-DKw0d82w.js";
25
- import { ThemeSwitcher as O } from "./theme/theme-switcher.js";
26
- import { CONNECTOR_LOGO_PALETTE as k, ConnectorLogo as A, Diamond as j, Wordmark as M, createDiamondSvg as N, createWordmarkSvg as P, getBrandSizeClass as F, getConnectorLogoColor as I, getConnectorLogoInitial as L, getConnectorLogoSizeClass as R, getConnectorLogoTone as z } from "./brand/index.js";
27
- export { m as AccentSwitcher, k as CONNECTOR_LOGO_PALETTE, o as CommandPalette, A as ConnectorLogo, d as ContextMenu, l as CopyButton, e as DataTable, v as DensitySwitcher, p as DetailHeader, j as Diamond, y as FontStackPicker, b as GlassSlider, x as IconSetPicker, S as IconUsageMatrix, f as LogToolbar, i as Modal, c as Pagination, C as RadiusSlider, s as SearchInput, r as SplitPane, u as StatusBar, n as TabPanel, w as ThemePresetGrid, T as ThemePreviewTile, D as ThemeStudio, O as ThemeSwitcher, a as ToastManager, t as TreeView, M as Wordmark, h as applyAccentFromUrl, N as createDiamondSvg, P as createWordmarkSvg, F as getBrandSizeClass, I as getConnectorLogoColor, L as getConnectorLogoInitial, R as getConnectorLogoSizeClass, z as getConnectorLogoTone, g as getCurrentAccent, E as renderThemeStudio, _ as setPreviewAccent };
1
+ import { CONNECTOR_LOGO_PALETTE as e, ConnectorLogo as t, Diamond as n, Wordmark as r, createDiamondSvg as i, createWordmarkSvg as a, getBrandSizeClass as o, getConnectorLogoColor as s, getConnectorLogoInitial as c, getConnectorLogoSizeClass as l, getConnectorLogoTone as u } from "./brand/index.js";
2
+ import { t as d } from "../data-table-DcgJjvnu.js";
3
+ import { t as f } from "../tree-view-CmCxQjBA.js";
4
+ import { TabPanel as p } from "./tabs/index.js";
5
+ import { SplitPane as m } from "./split-pane/index.js";
6
+ import { Modal as h } from "./modal/index.js";
7
+ import { ToastManager as g } from "./toast/index.js";
8
+ import { CommandPalette as _ } from "./search/command-palette.js";
9
+ import { SearchInput as v } from "./search/index.js";
10
+ import { Pagination as y } from "./pagination/index.js";
11
+ import { CopyButton as b } from "./copy-button/index.js";
12
+ import { StatusBar as x } from "./status-bar/index.js";
13
+ import { ContextMenu as S } from "./context-menu/index.js";
14
+ import { LogToolbar as C } from "./log-toolbar/index.js";
15
+ import { DetailHeader as w } from "./detail-header/index.js";
16
+ import { AccentSwitcher as T, applyAccentFromUrl as E, getCurrentAccent as D, setPreviewAccent as O } from "./theme/accent-switcher.js";
17
+ import { DensitySwitcher as k } from "./theme/density-switcher.js";
18
+ import { FontStackPicker as A } from "./theme/font-stack-picker.js";
19
+ import { GlassSlider as j } from "./theme/glass-slider.js";
20
+ import { IconSetPicker as M } from "./theme/icon-set-picker.js";
21
+ import { IconUsageMatrix as N } from "./theme/icon-usage-matrix.js";
22
+ import { RadiusSlider as P } from "./theme/radius-slider.js";
23
+ import { ThemePresetGrid as F } from "./theme/theme-preset-grid.js";
24
+ import { ThemePreviewTile as I } from "./theme/theme-preview-tile.js";
25
+ import { n as L, t as R } from "../theme-studio-DKw0d82w.js";
26
+ import { ThemeSwitcher as z } from "./theme/theme-switcher.js";
27
+ export { T as AccentSwitcher, e as CONNECTOR_LOGO_PALETTE, _ as CommandPalette, t as ConnectorLogo, S as ContextMenu, b as CopyButton, d as DataTable, k as DensitySwitcher, w as DetailHeader, n as Diamond, A as FontStackPicker, j as GlassSlider, M as IconSetPicker, N as IconUsageMatrix, C as LogToolbar, h as Modal, y as Pagination, P as RadiusSlider, v as SearchInput, m as SplitPane, x as StatusBar, p as TabPanel, F as ThemePresetGrid, I as ThemePreviewTile, R as ThemeStudio, z as ThemeSwitcher, g as ToastManager, f as TreeView, r as Wordmark, E as applyAccentFromUrl, i as createDiamondSvg, a as createWordmarkSvg, o as getBrandSizeClass, s as getConnectorLogoColor, c as getConnectorLogoInitial, l as getConnectorLogoSizeClass, u as getConnectorLogoTone, D as getCurrentAccent, L as renderThemeStudio, O as setPreviewAccent };