@camunda/design-system 0.32.1 → 0.33.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 (42) hide show
  1. package/dist/carbon-compat/c3-cluster-tag.d.ts.map +1 -1
  2. package/dist/carbon-compat/c3-cluster-tag.js +10 -4
  3. package/dist/carbon-compat/c3-cluster-tag.js.map +1 -1
  4. package/dist/src/components/ui/alert-dialog.d.ts +9 -1
  5. package/dist/src/components/ui/alert-dialog.d.ts.map +1 -1
  6. package/dist/src/components/ui/alert-dialog.js +11 -2
  7. package/dist/src/components/ui/alert-dialog.js.map +1 -1
  8. package/dist/src/components/ui/button.js +1 -1
  9. package/dist/src/components/ui/button.js.map +1 -1
  10. package/dist/src/components/ui/c4-provider.d.ts.map +1 -1
  11. package/dist/src/components/ui/c4-provider.js +6 -0
  12. package/dist/src/components/ui/c4-provider.js.map +1 -1
  13. package/dist/src/components/ui/dialog.d.ts +9 -1
  14. package/dist/src/components/ui/dialog.d.ts.map +1 -1
  15. package/dist/src/components/ui/dialog.js +16 -2
  16. package/dist/src/components/ui/dialog.js.map +1 -1
  17. package/dist/src/components/ui/dropdown.d.ts +11 -1
  18. package/dist/src/components/ui/dropdown.d.ts.map +1 -1
  19. package/dist/src/components/ui/dropdown.js +10 -2
  20. package/dist/src/components/ui/dropdown.js.map +1 -1
  21. package/dist/src/components/ui/popover.d.ts +9 -1
  22. package/dist/src/components/ui/popover.d.ts.map +1 -1
  23. package/dist/src/components/ui/popover.js +11 -2
  24. package/dist/src/components/ui/popover.js.map +1 -1
  25. package/dist/src/components/ui/select.d.ts +10 -1
  26. package/dist/src/components/ui/select.d.ts.map +1 -1
  27. package/dist/src/components/ui/select.js +12 -4
  28. package/dist/src/components/ui/select.js.map +1 -1
  29. package/dist/src/components/ui/sheet.d.ts +8 -1
  30. package/dist/src/components/ui/sheet.d.ts.map +1 -1
  31. package/dist/src/components/ui/sheet.js +11 -2
  32. package/dist/src/components/ui/sheet.js.map +1 -1
  33. package/dist/src/lib/focus-visible-on-close.d.ts +69 -0
  34. package/dist/src/lib/focus-visible-on-close.d.ts.map +1 -0
  35. package/dist/src/lib/focus-visible-on-close.js +129 -0
  36. package/dist/src/lib/focus-visible-on-close.js.map +1 -0
  37. package/dist/src/lib/inert-aria-hidden.d.ts +34 -0
  38. package/dist/src/lib/inert-aria-hidden.d.ts.map +1 -0
  39. package/dist/src/lib/inert-aria-hidden.js +76 -0
  40. package/dist/src/lib/inert-aria-hidden.js.map +1 -0
  41. package/dist/styles.css +790 -1625
  42. package/package.json +12 -12
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Makes the focus ring visible when a modal overlay restores focus to its
4
+ * trigger on close (#259 follow-up).
5
+ *
6
+ * Why: Radix restores focus with a programmatic `.focus()`. The browser's
7
+ * `:focus-visible` heuristic shows a ring only when the last input was a
8
+ * keyboard, so closing an overlay by mouse (clicking the X or the backdrop)
9
+ * returns focus to the trigger with no visible ring — a keyboard user who
10
+ * happened to click cannot see where focus landed. We stamp a transient marker
11
+ * on the restored element so the DS `Button` shows its ring regardless of the
12
+ * input modality that closed the overlay.
13
+ *
14
+ * The marker is self-clearing: it is removed on the next `pointerdown` anywhere
15
+ * and when the element loses focus. Without that, a sticky attribute would show
16
+ * a ring on every ordinary mouse click of that Button — a worse regression than
17
+ * the missing ring it fixes.
18
+ *
19
+ * Styling target: the marker lands on the element Radix focuses — the trigger,
20
+ * a DS `Button` in every DS overlay. A non-`Button` custom trigger would carry
21
+ * the attribute but has no matching ring style; same known-scope caveat as the
22
+ * inert body-child mirror in `inert-aria-hidden.ts`.
23
+ */
24
+ export declare const FOCUS_VISIBLE_RESTORE_ATTR = "data-focus-visible-restore";
25
+ /**
26
+ * Use as a Radix overlay `Content`'s `onCloseAutoFocus`. Does not
27
+ * `preventDefault`, so Radix still restores focus to the trigger; on the next
28
+ * frame the restored element (`document.activeElement`) is stamped with the
29
+ * self-clearing marker. No-ops if a prior handler already prevented the default
30
+ * restore.
31
+ */
32
+ export declare function markFocusVisibleOnClose(event: Event): void;
33
+ /**
34
+ * Wraps a Radix overlay `Content`'s `onCloseAutoFocus`: runs the consumer's
35
+ * handler first (so it can `preventDefault`), then runs `defaultHandler`
36
+ * (default: the #259 focus-visible marker). Every DS overlay composes its
37
+ * default focus-RETURN handling (`useDialogFocusReturn`) through the second
38
+ * parameter instead of calling `markFocusVisibleOnClose` directly, since that
39
+ * handler already stamps the marker itself once it settles on a final target.
40
+ */
41
+ export declare function composeCloseAutoFocus(handler?: (event: Event) => void, defaultHandler?: (event: Event) => void): (event: Event) => void;
42
+ /** Same composition shape as {@link composeCloseAutoFocus}, for `onOpenAutoFocus`. */
43
+ export declare function composeOpenAutoFocus(handler: ((event: Event) => void) | undefined, defaultHandler: (event: Event) => void): (event: Event) => void;
44
+ /**
45
+ * Default focus-RETURN for DS overlay `Content` components (issue #26413).
46
+ *
47
+ * Radix's own close-restore only works when it owns the element that opened
48
+ * the overlay (a `<...Trigger>` still mounted at close time). It fails for the
49
+ * common controlled-`open` usage with no `Trigger` — e.g. a persistent
50
+ * `<Button onClick={() => setOpen(true)}>` — where focus falls back to
51
+ * `<body>` on close (a WCAG 2.4.3 regression).
52
+ *
53
+ * `onOpenAutoFocus` fires before Radix moves focus into the overlay, so
54
+ * `document.activeElement` at that point is still whatever launched it. We
55
+ * capture it (without `preventDefault` — Radix must still move focus in) and
56
+ * refocus it in `onCloseAutoFocus`.
57
+ *
58
+ * That auto-capture cannot recover a launcher that has already unmounted by
59
+ * open time — a `DropdownMenuItem` opening a dialog: the menu (and the item)
60
+ * closes and unmounts before `onOpenAutoFocus` runs, so `activeElement` is
61
+ * already `<body>`. Consumers in that shape must pass `restoreFocusRef`
62
+ * pointing at a still-mounted element (typically the menu's own trigger);
63
+ * `restoreFocusRef` always takes precedence over the auto-captured element.
64
+ */
65
+ export declare function useDialogFocusReturn(restoreFocusRef?: React.RefObject<HTMLElement | null>): {
66
+ onOpenAutoFocus: (event: Event) => void;
67
+ onCloseAutoFocus: (event: Event) => void;
68
+ };
69
+ //# sourceMappingURL=focus-visible-on-close.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible-on-close.d.ts","sourceRoot":"","sources":["../../../src/lib/focus-visible-on-close.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AA8BvE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAM1D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAChC,cAAc,GAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAA8B,GAC/D,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAKxB;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,EAC7C,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GACrC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAKxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GACpD;IACD,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C,CA6BA"}
@@ -0,0 +1,129 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Makes the focus ring visible when a modal overlay restores focus to its
4
+ * trigger on close (#259 follow-up).
5
+ *
6
+ * Why: Radix restores focus with a programmatic `.focus()`. The browser's
7
+ * `:focus-visible` heuristic shows a ring only when the last input was a
8
+ * keyboard, so closing an overlay by mouse (clicking the X or the backdrop)
9
+ * returns focus to the trigger with no visible ring — a keyboard user who
10
+ * happened to click cannot see where focus landed. We stamp a transient marker
11
+ * on the restored element so the DS `Button` shows its ring regardless of the
12
+ * input modality that closed the overlay.
13
+ *
14
+ * The marker is self-clearing: it is removed on the next `pointerdown` anywhere
15
+ * and when the element loses focus. Without that, a sticky attribute would show
16
+ * a ring on every ordinary mouse click of that Button — a worse regression than
17
+ * the missing ring it fixes.
18
+ *
19
+ * Styling target: the marker lands on the element Radix focuses — the trigger,
20
+ * a DS `Button` in every DS overlay. A non-`Button` custom trigger would carry
21
+ * the attribute but has no matching ring style; same known-scope caveat as the
22
+ * inert body-child mirror in `inert-aria-hidden.ts`.
23
+ */
24
+ export const FOCUS_VISIBLE_RESTORE_ATTR = "data-focus-visible-restore";
25
+ function applyFocusVisibleMarker(el) {
26
+ el.setAttribute(FOCUS_VISIBLE_RESTORE_ATTR, "");
27
+ const clear = () => {
28
+ el.removeAttribute(FOCUS_VISIBLE_RESTORE_ATTR);
29
+ el.removeEventListener("blur", clear);
30
+ document.removeEventListener("pointerdown", clear, true);
31
+ };
32
+ el.addEventListener("blur", clear);
33
+ document.addEventListener("pointerdown", clear, true);
34
+ }
35
+ /**
36
+ * Stamps the marker on whatever `getElement()` resolves to, one frame later —
37
+ * late enough that a synchronous `.focus()` call earlier in the same tick has
38
+ * already committed, so `getElement` can sanity-check against
39
+ * `document.activeElement` before stamping.
40
+ */
41
+ function scheduleFocusVisibleMarker(getElement) {
42
+ if (typeof requestAnimationFrame === "undefined")
43
+ return;
44
+ requestAnimationFrame(() => {
45
+ const el = getElement();
46
+ if (el == null)
47
+ return;
48
+ applyFocusVisibleMarker(el);
49
+ });
50
+ }
51
+ /**
52
+ * Use as a Radix overlay `Content`'s `onCloseAutoFocus`. Does not
53
+ * `preventDefault`, so Radix still restores focus to the trigger; on the next
54
+ * frame the restored element (`document.activeElement`) is stamped with the
55
+ * self-clearing marker. No-ops if a prior handler already prevented the default
56
+ * restore.
57
+ */
58
+ export function markFocusVisibleOnClose(event) {
59
+ if (event.defaultPrevented)
60
+ return;
61
+ scheduleFocusVisibleMarker(() => {
62
+ const el = document.activeElement;
63
+ return el instanceof HTMLElement && el !== document.body ? el : null;
64
+ });
65
+ }
66
+ /**
67
+ * Wraps a Radix overlay `Content`'s `onCloseAutoFocus`: runs the consumer's
68
+ * handler first (so it can `preventDefault`), then runs `defaultHandler`
69
+ * (default: the #259 focus-visible marker). Every DS overlay composes its
70
+ * default focus-RETURN handling (`useDialogFocusReturn`) through the second
71
+ * parameter instead of calling `markFocusVisibleOnClose` directly, since that
72
+ * handler already stamps the marker itself once it settles on a final target.
73
+ */
74
+ export function composeCloseAutoFocus(handler, defaultHandler = markFocusVisibleOnClose) {
75
+ return (event) => {
76
+ handler?.(event);
77
+ defaultHandler(event);
78
+ };
79
+ }
80
+ /** Same composition shape as {@link composeCloseAutoFocus}, for `onOpenAutoFocus`. */
81
+ export function composeOpenAutoFocus(handler, defaultHandler) {
82
+ return (event) => {
83
+ handler?.(event);
84
+ defaultHandler(event);
85
+ };
86
+ }
87
+ /**
88
+ * Default focus-RETURN for DS overlay `Content` components (issue #26413).
89
+ *
90
+ * Radix's own close-restore only works when it owns the element that opened
91
+ * the overlay (a `<...Trigger>` still mounted at close time). It fails for the
92
+ * common controlled-`open` usage with no `Trigger` — e.g. a persistent
93
+ * `<Button onClick={() => setOpen(true)}>` — where focus falls back to
94
+ * `<body>` on close (a WCAG 2.4.3 regression).
95
+ *
96
+ * `onOpenAutoFocus` fires before Radix moves focus into the overlay, so
97
+ * `document.activeElement` at that point is still whatever launched it. We
98
+ * capture it (without `preventDefault` — Radix must still move focus in) and
99
+ * refocus it in `onCloseAutoFocus`.
100
+ *
101
+ * That auto-capture cannot recover a launcher that has already unmounted by
102
+ * open time — a `DropdownMenuItem` opening a dialog: the menu (and the item)
103
+ * closes and unmounts before `onOpenAutoFocus` runs, so `activeElement` is
104
+ * already `<body>`. Consumers in that shape must pass `restoreFocusRef`
105
+ * pointing at a still-mounted element (typically the menu's own trigger);
106
+ * `restoreFocusRef` always takes precedence over the auto-captured element.
107
+ */
108
+ export function useDialogFocusReturn(restoreFocusRef) {
109
+ const capturedFocusRef = React.useRef(null);
110
+ const onOpenAutoFocus = React.useCallback(() => {
111
+ const active = document.activeElement;
112
+ capturedFocusRef.current =
113
+ active instanceof HTMLElement && active !== document.body ? active : null;
114
+ }, []);
115
+ const onCloseAutoFocus = React.useCallback((event) => {
116
+ if (event.defaultPrevented)
117
+ return;
118
+ const target = restoreFocusRef?.current ?? capturedFocusRef.current;
119
+ if (target != null && target.isConnected) {
120
+ event.preventDefault();
121
+ target.focus();
122
+ scheduleFocusVisibleMarker(() => document.activeElement === target ? target : null);
123
+ return;
124
+ }
125
+ markFocusVisibleOnClose(event);
126
+ }, [restoreFocusRef]);
127
+ return { onOpenAutoFocus, onCloseAutoFocus };
128
+ }
129
+ //# sourceMappingURL=focus-visible-on-close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible-on-close.js","sourceRoot":"","sources":["../../../src/lib/focus-visible-on-close.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Mirrors native `inert` onto the page background while a modal Radix overlay
3
+ * (Dialog, AlertDialog, DropdownMenu, Select, Sheet, modal Popover) is open.
4
+ *
5
+ * Why this exists (#259): those primitives call the `aria-hidden` package's
6
+ * `hideOthers()` on open, which marks every background sibling
7
+ * `aria-hidden="true"` (plus a `data-aria-hidden` counter) but leaves it
8
+ * keyboard-focusable. That trips axe's `aria-hidden-focus` rule
9
+ * (WCAG 4.1.2 / 2.4.3) on every consuming app. Radix's pinned version uses
10
+ * `hideOthers()`, not `inertOthers()`, so we add `inert` ourselves.
11
+ *
12
+ * Scope: only direct children of `document.body` are inerted — those are the
13
+ * real page-background roots (app root, portal-less content). This matches
14
+ * Radix's default body-level portals: `hideOthers()` marks the portal's
15
+ * body-level siblings (the background) plus the overlay's in-portal sibling
16
+ * (the backdrop). The backdrop lives *inside* the portal (not a body child), so
17
+ * it is left untouched — inerting it would block click-outside-to-close.
18
+ *
19
+ * Known limitation: an app that both mounts into a non-body container AND
20
+ * configures Radix to portal inside that same container would have its
21
+ * background marked at a nested level, not as a body child, and would fall
22
+ * outside this scope. DS overlays use the default (body) portal, so this does
23
+ * not affect them.
24
+ *
25
+ * We only ever clear `inert` on elements we set it on (tracked in a WeakSet), so
26
+ * a consumer's own `inert` is never clobbered.
27
+ */
28
+ /**
29
+ * Installs a single document-wide observer that keeps `inert` in sync with the
30
+ * `data-aria-hidden` marker Radix applies. Idempotent — safe to call from every
31
+ * C4Provider mount; only the first call installs anything.
32
+ */
33
+ export declare function installAriaHiddenInert(): void;
34
+ //# sourceMappingURL=inert-aria-hidden.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert-aria-hidden.d.ts","sourceRoot":"","sources":["../../../src/lib/inert-aria-hidden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAUH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAqC7C"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Mirrors native `inert` onto the page background while a modal Radix overlay
3
+ * (Dialog, AlertDialog, DropdownMenu, Select, Sheet, modal Popover) is open.
4
+ *
5
+ * Why this exists (#259): those primitives call the `aria-hidden` package's
6
+ * `hideOthers()` on open, which marks every background sibling
7
+ * `aria-hidden="true"` (plus a `data-aria-hidden` counter) but leaves it
8
+ * keyboard-focusable. That trips axe's `aria-hidden-focus` rule
9
+ * (WCAG 4.1.2 / 2.4.3) on every consuming app. Radix's pinned version uses
10
+ * `hideOthers()`, not `inertOthers()`, so we add `inert` ourselves.
11
+ *
12
+ * Scope: only direct children of `document.body` are inerted — those are the
13
+ * real page-background roots (app root, portal-less content). This matches
14
+ * Radix's default body-level portals: `hideOthers()` marks the portal's
15
+ * body-level siblings (the background) plus the overlay's in-portal sibling
16
+ * (the backdrop). The backdrop lives *inside* the portal (not a body child), so
17
+ * it is left untouched — inerting it would block click-outside-to-close.
18
+ *
19
+ * Known limitation: an app that both mounts into a non-body container AND
20
+ * configures Radix to portal inside that same container would have its
21
+ * background marked at a nested level, not as a body child, and would fall
22
+ * outside this scope. DS overlays use the default (body) portal, so this does
23
+ * not affect them.
24
+ *
25
+ * We only ever clear `inert` on elements we set it on (tracked in a WeakSet), so
26
+ * a consumer's own `inert` is never clobbered.
27
+ */
28
+ const HIDDEN_SELECTOR = '[data-aria-hidden][aria-hidden="true"]';
29
+ let installed = false;
30
+ function isBackgroundRoot(el) {
31
+ return el.parentElement === document.body && el instanceof HTMLElement;
32
+ }
33
+ /**
34
+ * Installs a single document-wide observer that keeps `inert` in sync with the
35
+ * `data-aria-hidden` marker Radix applies. Idempotent — safe to call from every
36
+ * C4Provider mount; only the first call installs anything.
37
+ */
38
+ export function installAriaHiddenInert() {
39
+ if (typeof document === "undefined" || installed)
40
+ return;
41
+ installed = true;
42
+ const owned = new WeakSet();
43
+ const sync = (el) => {
44
+ if (!isBackgroundRoot(el))
45
+ return;
46
+ const shouldInert = el.matches(HIDDEN_SELECTOR);
47
+ if (shouldInert && !el.inert) {
48
+ el.inert = true;
49
+ owned.add(el);
50
+ }
51
+ else if (!shouldInert && owned.has(el)) {
52
+ el.inert = false;
53
+ owned.delete(el);
54
+ }
55
+ };
56
+ // Cover state that already exists at install time (an overlay may open before
57
+ // the first provider mounts, or the provider itself lives inside the overlay).
58
+ document.body.querySelectorAll(HIDDEN_SELECTOR).forEach(sync);
59
+ const observer = new MutationObserver((records) => {
60
+ for (const record of records)
61
+ sync(record.target);
62
+ });
63
+ // Watch only the marker attributes anywhere under body (cheap — the filter
64
+ // scopes callbacks to two attributes). This is the primary path: Radix
65
+ // toggles `aria-hidden`/`data-aria-hidden` on the background *after* the
66
+ // portal is inserted, so the attribute mutation always fires. Any background
67
+ // already marked at install time is handled by the scan above. Clearing the
68
+ // marker on close removes `inert` here; the FocusRestoredOnClose regression
69
+ // story guards that this lands before Radix restores focus to the trigger.
70
+ observer.observe(document.body, {
71
+ subtree: true,
72
+ attributes: true,
73
+ attributeFilter: ["aria-hidden", "data-aria-hidden"],
74
+ });
75
+ }
76
+ //# sourceMappingURL=inert-aria-hidden.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert-aria-hidden.js","sourceRoot":"","sources":["../../../src/lib/inert-aria-hidden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,eAAe,GAAG,wCAAwC,CAAC;AAEjE,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,gBAAgB,CAAC,EAAW;IACnC,OAAO,EAAE,CAAC,aAAa,KAAK,QAAQ,CAAC,IAAI,IAAI,EAAE,YAAY,WAAW,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,SAAS;QAAE,OAAO;IACzD,SAAS,GAAG,IAAI,CAAC;IAEjB,MAAM,KAAK,GAAG,IAAI,OAAO,EAAe,CAAC;IAEzC,MAAM,IAAI,GAAG,CAAC,EAAW,EAAE,EAAE;QAC3B,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAAE,OAAO;QAClC,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAChD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAC7B,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC;YACjB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,8EAA8E;IAC9E,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE;QAChD,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,MAAiB,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,2EAA2E;IAC3E,uEAAuE;IACvE,yEAAyE;IACzE,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC9B,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,CAAC,aAAa,EAAE,kBAAkB,CAAC;KACrD,CAAC,CAAC;AACL,CAAC"}