@fristil/designsystem 0.4.0 → 0.5.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 (116) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +22 -7
  3. package/dist/components/frittstaende/connection-status/connection-status.d.ts +28 -0
  4. package/dist/components/frittstaende/connection-status/connection-status.d.ts.map +1 -0
  5. package/dist/components/frittstaende/connection-status/connection-status.js +22 -0
  6. package/dist/components/frittstaende/connection-status/connection-status.js.map +1 -0
  7. package/dist/components/frittstaende/connection-status/fs-connection-status.d.ts +54 -0
  8. package/dist/components/frittstaende/connection-status/fs-connection-status.d.ts.map +1 -0
  9. package/dist/components/frittstaende/connection-status/fs-connection-status.js +123 -0
  10. package/dist/components/frittstaende/connection-status/fs-connection-status.js.map +1 -0
  11. package/dist/components/frittstaende/session-timeout/fs-session-timeout.d.ts +56 -0
  12. package/dist/components/frittstaende/session-timeout/fs-session-timeout.d.ts.map +1 -0
  13. package/dist/components/frittstaende/session-timeout/fs-session-timeout.js +179 -0
  14. package/dist/components/frittstaende/session-timeout/fs-session-timeout.js.map +1 -0
  15. package/dist/components/frittstaende/session-timeout/session-timeout.d.ts +28 -0
  16. package/dist/components/frittstaende/session-timeout/session-timeout.d.ts.map +1 -0
  17. package/dist/components/frittstaende/session-timeout/session-timeout.js +22 -0
  18. package/dist/components/frittstaende/session-timeout/session-timeout.js.map +1 -0
  19. package/dist/components/frittstaende/toast/fs-toast.d.ts +16 -22
  20. package/dist/components/frittstaende/toast/fs-toast.d.ts.map +1 -1
  21. package/dist/components/frittstaende/toast/fs-toast.js +38 -27
  22. package/dist/components/frittstaende/toast/fs-toast.js.map +1 -1
  23. package/dist/components/frittstaende/toast/toast.d.ts +34 -0
  24. package/dist/components/frittstaende/toast/toast.d.ts.map +1 -0
  25. package/dist/components/frittstaende/toast/toast.js +26 -0
  26. package/dist/components/frittstaende/toast/toast.js.map +1 -0
  27. package/dist/components/ramme/error-summary/error-summary.d.ts +39 -0
  28. package/dist/components/ramme/error-summary/error-summary.d.ts.map +1 -0
  29. package/dist/components/ramme/error-summary/error-summary.js +31 -0
  30. package/dist/components/ramme/error-summary/error-summary.js.map +1 -0
  31. package/dist/components/ramme/error-summary/fs-error-summary.d.ts +16 -42
  32. package/dist/components/ramme/error-summary/fs-error-summary.d.ts.map +1 -1
  33. package/dist/components/ramme/error-summary/fs-error-summary.js +57 -92
  34. package/dist/components/ramme/error-summary/fs-error-summary.js.map +1 -1
  35. package/dist/components/ramme/field/field-core.d.ts +31 -0
  36. package/dist/components/ramme/field/field-core.d.ts.map +1 -1
  37. package/dist/components/ramme/field/field-core.js +31 -0
  38. package/dist/components/ramme/field/field-core.js.map +1 -1
  39. package/dist/components/ramme/field/fs-field.d.ts +38 -40
  40. package/dist/components/ramme/field/fs-field.d.ts.map +1 -1
  41. package/dist/components/ramme/field/fs-field.js +127 -54
  42. package/dist/components/ramme/field/fs-field.js.map +1 -1
  43. package/dist/components/ramme/popover/fs-popover.d.ts +20 -27
  44. package/dist/components/ramme/popover/fs-popover.d.ts.map +1 -1
  45. package/dist/components/ramme/popover/fs-popover.js +68 -54
  46. package/dist/components/ramme/popover/fs-popover.js.map +1 -1
  47. package/dist/components/ramme/popover/popover.d.ts +43 -0
  48. package/dist/components/ramme/popover/popover.d.ts.map +1 -0
  49. package/dist/components/ramme/popover/popover.js +49 -0
  50. package/dist/components/ramme/popover/popover.js.map +1 -0
  51. package/dist/components/ramme/suggestion/fs-suggestion.d.ts +75 -0
  52. package/dist/components/ramme/suggestion/fs-suggestion.d.ts.map +1 -0
  53. package/dist/components/ramme/suggestion/fs-suggestion.js +232 -0
  54. package/dist/components/ramme/suggestion/fs-suggestion.js.map +1 -0
  55. package/dist/components/ramme/suggestion/suggestion.d.ts +97 -0
  56. package/dist/components/ramme/suggestion/suggestion.d.ts.map +1 -0
  57. package/dist/components/ramme/suggestion/suggestion.js +79 -0
  58. package/dist/components/ramme/suggestion/suggestion.js.map +1 -0
  59. package/dist/components/ramme/tabs/fs-tabs.d.ts +31 -36
  60. package/dist/components/ramme/tabs/fs-tabs.d.ts.map +1 -1
  61. package/dist/components/ramme/tabs/fs-tabs.js +62 -84
  62. package/dist/components/ramme/tabs/fs-tabs.js.map +1 -1
  63. package/dist/components/ramme/tabs/tabs.d.ts +50 -0
  64. package/dist/components/ramme/tabs/tabs.d.ts.map +1 -0
  65. package/dist/components/ramme/tabs/tabs.js +54 -0
  66. package/dist/components/ramme/tabs/tabs.js.map +1 -0
  67. package/dist/fs.d.ts +94 -0
  68. package/dist/fs.d.ts.map +1 -1
  69. package/dist/fs.js +42 -0
  70. package/dist/fs.js.map +1 -1
  71. package/dist/index.d.ts +10 -3
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +10 -3
  74. package/dist/index.js.map +1 -1
  75. package/dist/jsx/react.d.ts +35 -50
  76. package/dist/jsx/react.d.ts.map +1 -1
  77. package/dist/react.d.ts +142 -1
  78. package/dist/react.d.ts.map +1 -1
  79. package/dist/react.js +71 -2
  80. package/dist/react.js.map +1 -1
  81. package/package.json +15 -18
  82. package/src/components/frittstaende/connection-status/connection-status.css +33 -0
  83. package/src/components/frittstaende/connection-status/connection-status.ts +41 -0
  84. package/src/components/frittstaende/connection-status/fs-connection-status.ts +144 -0
  85. package/src/components/frittstaende/session-timeout/fs-session-timeout.ts +212 -0
  86. package/src/components/frittstaende/session-timeout/session-timeout.css +43 -0
  87. package/src/components/frittstaende/session-timeout/session-timeout.ts +42 -0
  88. package/src/components/frittstaende/toast/fs-toast.ts +39 -30
  89. package/src/components/frittstaende/toast/toast.ts +45 -0
  90. package/src/components/ramme/error-summary/error-summary.ts +55 -0
  91. package/src/components/ramme/error-summary/fs-error-summary.ts +62 -119
  92. package/src/components/ramme/field/field-core.ts +32 -0
  93. package/src/components/ramme/field/fs-field.ts +144 -61
  94. package/src/components/ramme/popover/fs-popover.ts +78 -72
  95. package/src/components/ramme/popover/popover.ts +79 -0
  96. package/src/components/ramme/suggestion/fs-suggestion.ts +265 -0
  97. package/src/components/ramme/suggestion/suggestion.ts +105 -0
  98. package/src/components/ramme/tabs/fs-tabs.ts +67 -98
  99. package/src/components/ramme/tabs/tabs.ts +104 -0
  100. package/dist/components/frittstaende/calendar/fs-calendar.d.ts +0 -52
  101. package/dist/components/frittstaende/calendar/fs-calendar.d.ts.map +0 -1
  102. package/dist/components/frittstaende/calendar/fs-calendar.js +0 -462
  103. package/dist/components/frittstaende/calendar/fs-calendar.js.map +0 -1
  104. package/dist/components/frittstaende/date-field/fs-date-field.d.ts +0 -110
  105. package/dist/components/frittstaende/date-field/fs-date-field.d.ts.map +0 -1
  106. package/dist/components/frittstaende/date-field/fs-date-field.js +0 -264
  107. package/dist/components/frittstaende/date-field/fs-date-field.js.map +0 -1
  108. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts +0 -133
  109. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts.map +0 -1
  110. package/dist/components/frittstaende/suggestion/fs-suggestion.js +0 -280
  111. package/dist/components/frittstaende/suggestion/fs-suggestion.js.map +0 -1
  112. package/src/components/frittstaende/calendar/fs-calendar.ts +0 -525
  113. package/src/components/frittstaende/date-field/date-field.css +0 -54
  114. package/src/components/frittstaende/date-field/fs-date-field.ts +0 -309
  115. package/src/components/frittstaende/suggestion/fs-suggestion.ts +0 -333
  116. /package/src/components/{frittstaende → ramme}/suggestion/suggestion.css +0 -0
@@ -1,129 +1,90 @@
1
- import { html, LitElement } from "lit"
2
-
3
1
  export const FS_TABS_TAG = "fs-tabs" as const
4
2
 
5
- export const TABS_LIST_CLASS = "fs-tabs__list" as const
6
- export const TABS_PANEL_CLASS = "fs-tabs__panel" as const
7
-
8
- function uniqueId(prefix: string): string {
9
- return `${prefix}-${Math.random().toString(36).slice(2, 9)}`
10
- }
11
-
12
3
  /**
13
- * Kobler en rad med knapper til panelene de hører til.
4
+ * Tastaturet i en fanerad.
5
+ *
6
+ * Serveren skriver rollene, `aria-controls` og `hidden` med `fs.tabs()`.
7
+ * Gjorde komponenten det, ville alle panelene vises til skriptet hadde kjørt,
8
+ * og innholdet hoppe når panelene skjulte seg selv. I en Datastar-app ville
9
+ * de dessuten komme tilbake ved hver patch.
14
10
  *
15
- * Du skriver knappene og panelene selv. Komponenten setter rollene, holder
16
- * `aria-selected` og `aria-controls` i synk, skjuler panelene som ikke er
17
- * valgt, og tar piltastene.
11
+ * Det komponenten gjør er det nettleseren ikke gjør selv: Tab hopper forbi
12
+ * hele raden og inn i panelet, mens piltastene flytter mellom fanene. Et sett
13
+ * knapper uten dette gir én tabbestopp per fane, og skjermleseren sier
14
+ * «knapp» der den skulle sagt «fane, 2 av 3, valgt».
18
15
  *
19
- * Tastaturet er hele grunnen til at komponenten finnes. I en faneliste skal
20
- * Tab hoppe forbi hele raden og inn i panelet, mens piltastene flytter mellom
21
- * fanene. Et sett knapper uten denne koblingen gir én tabbestopp per fane, og
22
- * skjermleseren sier «knapp» der den skulle sagt «fane, 2 av 3, valgt».
16
+ * Attributtene som endrer seg når brukeren velger, altså `aria-selected`,
17
+ * `tabindex` og `hidden`, står i `data-preserve-attr` fra byggeren.
23
18
  *
24
19
  * ```html
25
20
  * <fs-tabs>
26
- * <div class="fs-tabs__list">
27
- * <button>Søknaden</button>
28
- * <button>Vedlegg</button>
21
+ * <div class="fs-tabs__list" role="tablist">
22
+ * <button id="sak-tab-0" role="tab" aria-selected="true" aria-controls="sak-panel-0"
23
+ * tabindex="0" data-preserve-attr="aria-selected tabindex">Søknaden</button>
29
24
  * </div>
30
- * <div class="fs-tabs__panel">…</div>
31
- * <div class="fs-tabs__panel">…</div>
25
+ * <div id="sak-panel-0" class="fs-tabs__panel" role="tabpanel"
26
+ * aria-labelledby="sak-tab-0" tabindex="0" data-preserve-attr="hidden">…</div>
32
27
  * </fs-tabs>
33
28
  * ```
34
29
  */
35
- export class FsTabs extends LitElement {
36
- static properties = {
37
- selected: { type: Number, reflect: true },
38
- label: { type: String },
39
- }
40
-
41
- /** Indeksen fanen som er valgt. */
42
- selected = 0
43
- /** Tekst som sier hva fanene velger mellom. Blir `aria-label` på raden. */
44
- label?: string
45
-
46
- createRenderRoot() {
47
- return this
48
- }
49
-
50
- render() {
51
- return html`<slot @slotchange=${this.handleSlotChange}></slot>`
52
- }
53
-
54
- firstUpdated() {
55
- this.sync()
56
- }
57
-
58
- updated() {
59
- this.sync()
30
+ export class FsTabs extends HTMLElement {
31
+ /**
32
+ * Ingen attributter. Hvilken fane som er valgt står i markupen serveren
33
+ * sendte, som `aria-selected` på fanen og `hidden` på panelene, og leses
34
+ * derfra. Et eget `selected` ville vært en parallell utgave av det samme.
35
+ */
36
+ static observedAttributes: string[] = []
37
+
38
+ private readonly bound = new Set<HTMLButtonElement>()
39
+ private observer?: MutationObserver
40
+
41
+ connectedCallback(): void {
42
+ this.observer = new MutationObserver(() => this.bind())
43
+ this.observer.observe(this, { childList: true, subtree: true })
44
+ this.bind()
60
45
  }
61
46
 
62
- private handleSlotChange = () => {
63
- this.sync()
47
+ disconnectedCallback(): void {
48
+ this.observer?.disconnect()
49
+ this.observer = undefined
50
+ for (const tab of this.bound) {
51
+ tab.removeEventListener("click", this.handleClick)
52
+ tab.removeEventListener("keydown", this.handleKeydown)
53
+ }
54
+ this.bound.clear()
64
55
  }
65
56
 
66
57
  private get tabs(): HTMLButtonElement[] {
67
- const list = this.querySelector(`.${TABS_LIST_CLASS}`)
68
- return list ? [...list.querySelectorAll("button")] : []
58
+ return [...this.querySelectorAll<HTMLButtonElement>("[role='tab']")]
69
59
  }
70
60
 
71
61
  private get panels(): HTMLElement[] {
72
- return [...this.querySelectorAll<HTMLElement>(`.${TABS_PANEL_CLASS}`)]
62
+ return [...this.querySelectorAll<HTMLElement>("[role='tabpanel']")]
73
63
  }
74
64
 
75
- private sync() {
76
- const list = this.querySelector(`.${TABS_LIST_CLASS}`)
77
- const tabs = this.tabs
78
- const panels = this.panels
79
-
80
- if (!list || tabs.length === 0) return
81
-
82
- list.setAttribute("role", "tablist")
83
- if (this.label) list.setAttribute("aria-label", this.label)
84
-
85
- // Er `selected` satt utenfor rekkevidde, rettes den her. Ellers ville
86
- // attributtet sagt noe annet enn det brukeren ser.
87
- const valid = Math.min(Math.max(this.selected, 0), tabs.length - 1)
88
- if (valid !== this.selected) this.selected = valid
89
-
90
- tabs.forEach((tab, index) => {
91
- const panel = panels[index]
92
- if (!tab.id) tab.id = uniqueId("fs-tab")
93
- if (panel && !panel.id) panel.id = uniqueId("fs-tabpanel")
94
-
95
- const isSelected = index === valid
96
-
97
- tab.setAttribute("role", "tab")
98
- tab.setAttribute("type", "button")
99
- tab.setAttribute("aria-selected", String(isSelected))
100
- // Roving tabindex: bare den valgte fanen er en tabbestopp, så Tab går
101
- // fra raden og rett inn i panelet.
102
- tab.tabIndex = isSelected ? 0 : -1
103
- if (panel) tab.setAttribute("aria-controls", panel.id)
65
+ /** Indeksen på fanen serveren har markert som valgt. */
66
+ get selected(): number {
67
+ const index = this.tabs.findIndex(
68
+ (tab) => tab.getAttribute("aria-selected") === "true",
69
+ )
70
+ return index < 0 ? 0 : index
71
+ }
104
72
 
105
- tab.removeEventListener("click", this.handleClick)
73
+ private bind(): void {
74
+ for (const tab of this.tabs) {
75
+ if (this.bound.has(tab)) continue
106
76
  tab.addEventListener("click", this.handleClick)
107
- tab.removeEventListener("keydown", this.handleKeydown)
108
77
  tab.addEventListener("keydown", this.handleKeydown)
109
-
110
- if (panel) {
111
- panel.setAttribute("role", "tabpanel")
112
- panel.setAttribute("aria-labelledby", tab.id)
113
- panel.hidden = !isSelected
114
- // Panelet får fokus når det ikke har noe å fokusere på selv, ellers
115
- // hopper Tab rett forbi innholdet som nettopp ble vist.
116
- panel.tabIndex = 0
117
- }
118
- })
78
+ this.bound.add(tab)
79
+ }
119
80
  }
120
81
 
121
- private handleClick = (event: Event) => {
82
+ private handleClick = (event: Event): void => {
122
83
  const index = this.tabs.indexOf(event.currentTarget as HTMLButtonElement)
123
84
  if (index >= 0) this.select(index)
124
85
  }
125
86
 
126
- private handleKeydown = (event: KeyboardEvent) => {
87
+ private handleKeydown = (event: KeyboardEvent): void => {
127
88
  const tabs = this.tabs
128
89
  const current = tabs.indexOf(event.currentTarget as HTMLButtonElement)
129
90
  if (current < 0) return
@@ -153,11 +114,19 @@ export class FsTabs extends LitElement {
153
114
  }
154
115
 
155
116
  /** Velger en fane og melder fra. */
156
- select(index: number) {
117
+ select(index: number): void {
118
+ const tabs = this.tabs
119
+ const panels = this.panels
120
+ if (index < 0 || index >= tabs.length) return
157
121
  if (index === this.selected) return
158
122
 
159
- this.selected = index
160
- this.sync()
123
+ tabs.forEach((tab, i) => {
124
+ const valgt = i === index
125
+ tab.setAttribute("aria-selected", String(valgt))
126
+ tab.tabIndex = valgt ? 0 : -1
127
+ const panel = panels[i]
128
+ if (panel) panel.hidden = !valgt
129
+ })
161
130
 
162
131
  this.dispatchEvent(
163
132
  new CustomEvent("tab-select", {
@@ -0,0 +1,104 @@
1
+ import { attributes } from "../../css/shared.js"
2
+
3
+ export const TABS_LIST_CLASS = "fs-tabs__list" as const
4
+ export const TABS_PANEL_CLASS = "fs-tabs__panel" as const
5
+
6
+ export type TabsOptions = {
7
+ /** Felles id-stamme. Fanene blir `${id}-tab-0`, panelene `${id}-panel-0`. */
8
+ id: string
9
+ /** Antall faner. */
10
+ count: number
11
+ /** Indeksen på fanen som er valgt. Standard: 0. */
12
+ selected?: number
13
+ /** Tekst som sier hva fanene velger mellom. Blir `aria-label` på raden. */
14
+ label?: string
15
+ }
16
+
17
+ export type TabsAttributes = {
18
+ list: {
19
+ class: typeof TABS_LIST_CLASS
20
+ role: "tablist"
21
+ "aria-label"?: string
22
+ }
23
+ tabs: Array<{
24
+ id: string
25
+ role: "tab"
26
+ type: "button"
27
+ "aria-selected": "true" | "false"
28
+ "aria-controls": string
29
+ tabindex: "0" | "-1"
30
+ "data-preserve-attr": "aria-selected tabindex"
31
+ }>
32
+ panels: Array<{
33
+ id: string
34
+ class: typeof TABS_PANEL_CLASS
35
+ role: "tabpanel"
36
+ "aria-labelledby": string
37
+ tabindex: "0"
38
+ hidden?: true
39
+ "data-preserve-attr": "hidden"
40
+ }>
41
+ }
42
+
43
+ /**
44
+ * Attributtene for en fanerad.
45
+ *
46
+ * Serveren skriver rollene og skjuler panelene som ikke er valgt. Gjorde
47
+ * komponenten det, ville alle panelene vises til skriptet hadde kjørt, og
48
+ * innholdet hoppe når det skjulte seg selv.
49
+ *
50
+ * ```ts
51
+ * const faner = fs.tabs({ id: "sak", count: 2, selected: 1, label: "Velg visning" })
52
+ * ```
53
+ */
54
+ export const tabs = ({
55
+ id,
56
+ count,
57
+ selected = 0,
58
+ label,
59
+ }: TabsOptions): TabsAttributes => {
60
+ // Er `selected` utenfor rekkevidde, rettes den her. Ellers ville markupen
61
+ // sagt noe annet enn det brukeren ser.
62
+ const valid = Math.min(Math.max(selected, 0), Math.max(count - 1, 0))
63
+ const tabId = (index: number) => `${id}-tab-${index}`
64
+ const panelId = (index: number) => `${id}-panel-${index}`
65
+ const indices = Array.from({ length: count }, (_, index) => index)
66
+
67
+ return {
68
+ list: attributes({
69
+ class: TABS_LIST_CLASS,
70
+ role: "tablist" as const,
71
+ "aria-label": label,
72
+ }),
73
+ tabs: indices.map((index) =>
74
+ attributes({
75
+ id: tabId(index),
76
+ role: "tab" as const,
77
+ type: "button" as const,
78
+ "aria-selected": (index === valid ? "true" : "false") as
79
+ | "true"
80
+ | "false",
81
+ "aria-controls": panelId(index),
82
+ // Rullerende tabindex: bare den valgte fanen er en tabbestopp, så Tab
83
+ // går fra raden og rett inn i panelet.
84
+ tabindex: (index === valid ? "0" : "-1") as "0" | "-1",
85
+ // Komponenten flytter valget når brukeren klikker. Morfingen ville
86
+ // ellers satt det tilbake til det serveren sendte.
87
+ "data-preserve-attr": "aria-selected tabindex" as const,
88
+ }),
89
+ ),
90
+ panels: indices.map((index) =>
91
+ attributes({
92
+ id: panelId(index),
93
+ class: TABS_PANEL_CLASS,
94
+ role: "tabpanel" as const,
95
+ "aria-labelledby": tabId(index),
96
+ // Panelet får fokus når det ikke har noe å fokusere på selv, ellers
97
+ // hopper Tab rett forbi innholdet som nettopp ble vist.
98
+ tabindex: "0" as const,
99
+ hidden: index === valid ? undefined : (true as const),
100
+ "data-preserve-attr": "hidden" as const,
101
+ }),
102
+ ),
103
+ }
104
+ }
@@ -1,52 +0,0 @@
1
- import { LitElement } from "lit";
2
- export declare const FS_CALENDAR_TAG: "fs-calendar";
3
- export declare class FsCalendar extends LitElement {
4
- static properties: {
5
- open: {
6
- type: BooleanConstructor;
7
- reflect: boolean;
8
- };
9
- disabled: {
10
- type: BooleanConstructor;
11
- reflect: boolean;
12
- };
13
- value: {
14
- type: StringConstructor;
15
- reflect: boolean;
16
- };
17
- triggerHidden: {
18
- type: BooleanConstructor;
19
- reflect: boolean;
20
- attribute: string;
21
- };
22
- };
23
- static styles: import("lit").CSSResult;
24
- /** @attr */
25
- open: boolean;
26
- /** @attr */
27
- disabled: boolean;
28
- /** @attr */
29
- value: string;
30
- /** @attr trigger-hidden */
31
- triggerHidden: boolean;
32
- private viewMonth;
33
- connectedCallback(): void;
34
- disconnectedCallback(): void;
35
- updated(changed: Map<string, unknown>): void;
36
- render(): import("lit").TemplateResult<1>;
37
- openPopup(): void;
38
- closePopup(): void;
39
- private togglePopup;
40
- private goToPreviousMonth;
41
- private goToNextMonth;
42
- private selectCalendarDate;
43
- private handlePopupKeydown;
44
- private handleDocumentClick;
45
- }
46
- declare global {
47
- interface HTMLElementTagNameMap {
48
- "fs-calendar": FsCalendar;
49
- }
50
- }
51
- export declare function defineFsCalendar(tagName?: "fs-calendar"): void;
52
- //# sourceMappingURL=fs-calendar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fs-calendar.d.ts","sourceRoot":"","sources":["../../../../src/components/frittstaende/calendar/fs-calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAA;AAE3C,eAAO,MAAM,eAAe,EAAG,aAAsB,CAAA;AAuHrD,qBAAa,UAAW,SAAQ,UAAU;IACxC,MAAM,CAAC,UAAU;;;;;;;;;;;;;;;;;;MAShB;IAED,MAAM,CAAC,MAAM,0BAqKZ;IAED,YAAY;IACZ,IAAI,UAAQ;IACZ,YAAY;IACZ,QAAQ,UAAQ;IAChB,YAAY;IACZ,KAAK,SAAK;IACV,2BAA2B;IAC3B,aAAa,UAAQ;IAErB,OAAO,CAAC,SAAS,CAAa;IAE9B,iBAAiB;IAKjB,oBAAoB;IAKpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAMrC,MAAM;IAgEN,SAAS;IAaT,UAAU;IAqBV,OAAO,CAAC,WAAW,CAMlB;IAED,OAAO,CAAC,iBAAiB,CAGxB;IAED,OAAO,CAAC,aAAa,CAGpB;IAED,OAAO,CAAC,kBAAkB,CAsBzB;IAED,OAAO,CAAC,kBAAkB,CAqCzB;IAED,OAAO,CAAC,mBAAmB,CAK1B;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAA;KAC1B;CACF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,gBAAkB,GAAG,IAAI,CAIhE"}