@stackone/malachite 2.50.0 → 2.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,221 +1,196 @@
1
- import { jsxs as x, jsx as i } from "react/jsx-runtime";
2
- import { useState as k, useId as I, useEffect as Y } from "react";
1
+ import { jsxs as d, jsx as r } from "react/jsx-runtime";
2
+ import { useState as w, useId as g } from "react";
3
3
  import { Alert as H } from "./Alert.js";
4
- import { Button as z } from "./Button.js";
4
+ import { Button as N } from "./Button.js";
5
5
  import Z from "./CustomIcons/CheckCircleFilled.js";
6
- import J from "./CustomIcons/CheckIcon.js";
7
- import P from "./CustomIcons/CopyIcon.js";
6
+ import J from "./CustomIcons/CheckmarkIcon.js";
7
+ import K from "./CustomIcons/CopyIcon.js";
8
8
  import Q from "./CustomIcons/ErrorCircleFilled.js";
9
9
  import U from "./CustomIcons/InfoCircleFilled.js";
10
10
  import X from "./CustomIcons/WarningCircleFilled.js";
11
- import { FieldMessage as ee } from "./FieldMessage.js";
12
- import { Modal as te } from "./Modal.js";
11
+ import { FieldMessage as P } from "./FieldMessage.js";
12
+ import { Modal as ee } from "./Modal.js";
13
13
  import { Typography as S } from "./Typography/index.js";
14
- import { CONFIRMATION_DIALOG_VARIANTS as ie } from "./confirmationDialogVariants.js";
14
+ import { useClipboardCopy as ie } from "./useClipboardCopy.js";
15
+ import { CONFIRMATION_DIALOG_VARIANTS as re } from "./confirmationDialogVariants.js";
15
16
  import oe from "./Input/Input.js";
16
- const v = 12, re = 1200, C = (e) => e.replace(/\s+/g, " "), ae = (e, t) => {
17
- const r = e.trim();
18
- if (!(!t || r === "" || r === t) && C(r).toLowerCase() === C(t).toLowerCase())
19
- return C(r) === C(t) ? "The spacing has to match exactly." : "This is case-sensitive.";
20
- }, le = "Could not copy. Enter the phrase manually.", se = (e, t) => {
21
- const r = typeof e == "object" && e !== null ? e : void 0;
22
- return r ? { parts: r, text: [r.prefix, t, r.suffix].filter(Boolean).join(" ") } : { text: typeof e == "string" ? e : `Type ${t} to confirm` };
23
- }, ne = (e, t) => e === "copied" ? `${t} copied to clipboard` : "", ce = (e, t, r, u) => {
24
- var o;
25
- const f = `${t}|${e}`, [a, l] = k({ key: f, generation: 0, outcome: "idle" });
26
- a.key !== f && l((c) => ({
27
- key: f,
28
- generation: c.generation + 1,
29
- outcome: "idle"
30
- })), Y(() => {
31
- if (a.outcome !== "copied")
32
- return;
33
- const c = setTimeout(
34
- () => l((d) => ({ ...d, outcome: "idle" })),
35
- re
36
- );
37
- return () => clearTimeout(c);
38
- }, [a.outcome]);
39
- const s = typeof navigator < "u" && !!((o = navigator.clipboard) != null && o.writeText), n = async () => {
40
- if (!e || !s)
41
- return;
42
- const c = a.generation, d = (y) => l(
43
- (m) => m.generation === c ? { ...m, outcome: y } : m
44
- );
45
- try {
46
- await navigator.clipboard.writeText(e);
47
- } catch {
48
- d("failed");
49
- return;
50
- }
51
- d("copied"), queueMicrotask(() => u == null ? void 0 : u(e));
17
+ const v = 12, C = (e) => e.replace(/\s+/g, " "), te = (e, i) => {
18
+ const o = e.trim();
19
+ if (!(!i || o === "" || o === i) && C(o).toLowerCase() === C(i).toLowerCase())
20
+ return C(o) === C(i) ? "The spacing has to match exactly." : "This is case-sensitive.";
21
+ }, ae = "Could not copy. Enter the phrase manually.", le = (e, i) => {
22
+ const o = typeof e == "object" && e !== null ? e : void 0;
23
+ return o ? { parts: o, text: [o.prefix, i, o.suffix].filter(Boolean).join(" ") } : { text: typeof e == "string" ? e : `Type ${i} to confirm` };
24
+ }, se = (e, i) => e === "copied" ? `${i} copied to clipboard` : "", ne = (e, i, o, s) => {
25
+ const { outcome: p, canCopy: m, copy: n } = ie(`${i}|${e}`), l = async () => {
26
+ e && await n(e) && queueMicrotask(() => s == null ? void 0 : s(e));
52
27
  };
53
- return { outcome: a.outcome, canCopy: s && !r, copy: () => void n() };
54
- }, L = ({ children: e }) => /* @__PURE__ */ i(S.Text, { size: "xsmall", color: "primary", fontWeight: "semi-bold", children: e }), de = ({
28
+ return { outcome: p, canCopy: m && !o, copy: () => void l() };
29
+ }, j = ({ children: e }) => /* @__PURE__ */ r(S.Text, { size: "xsmall", color: "primary", fontWeight: "semi-bold", children: e }), ce = ({
55
30
  phrase: e,
56
- parts: t,
57
- plainLabel: r,
58
- placeholder: u,
59
- value: f,
60
- onChange: a,
61
- disabled: l,
62
- copyLabel: s,
63
- copyOutcome: n,
64
- canCopy: o,
65
- onCopy: c,
66
- nearMissMessage: d
31
+ parts: i,
32
+ plainLabel: o,
33
+ placeholder: s,
34
+ value: p,
35
+ onChange: m,
36
+ disabled: n,
37
+ copyLabel: l,
38
+ copyOutcome: c,
39
+ canCopy: t,
40
+ onCopy: I,
41
+ nearMissMessage: f
67
42
  }) => {
68
- const y = I(), m = I(), b = I(), g = [d, n === "failed" ? le : void 0].filter(Boolean).join(" ") || void 0, p = t ? [y, t.suffix ? m : void 0].filter(Boolean).join(" ") : void 0;
69
- return /* @__PURE__ */ x("div", { className: "flex flex-col gap-[6px]", children: [
70
- t ? /* @__PURE__ */ x("div", { className: "flex flex-wrap items-center gap-[6px] px-2", children: [
71
- /* @__PURE__ */ x("span", { id: y, children: [
72
- /* @__PURE__ */ i(L, { children: t.prefix }),
43
+ const u = g(), y = g(), b = g(), x = [f, c === "failed" ? ae : void 0].filter(Boolean).join(" ") || void 0, a = i ? [u, i.suffix ? y : void 0].filter(Boolean).join(" ") : void 0;
44
+ return /* @__PURE__ */ d("div", { className: "flex flex-col gap-[6px]", children: [
45
+ i ? /* @__PURE__ */ d("div", { className: "flex flex-wrap items-center gap-[6px] px-2", children: [
46
+ /* @__PURE__ */ d("span", { id: u, children: [
47
+ /* @__PURE__ */ r(j, { children: i.prefix }),
73
48
  " ",
74
- /* @__PURE__ */ i(S.CodeText, { variant: "inline", size: "small", children: e })
49
+ /* @__PURE__ */ r(S.CodeText, { variant: "inline", size: "small", children: e })
75
50
  ] }),
76
- /* @__PURE__ */ i(
77
- z,
51
+ /* @__PURE__ */ r(
52
+ N,
78
53
  {
79
54
  variant: "ghost",
80
55
  size: "small",
81
56
  iconOnly: !0,
82
- "aria-label": `${s} ${e}`,
83
- icon: n === "copied" ? /* @__PURE__ */ i(J, { size: 13 }) : /* @__PURE__ */ i(P, { size: 13 }),
84
- onClick: c,
85
- disabled: !o
57
+ "aria-label": `${l} ${e}`,
58
+ icon: c === "copied" ? /* @__PURE__ */ r(J, { size: 13 }) : /* @__PURE__ */ r(K, { size: 13 }),
59
+ onClick: I,
60
+ disabled: !t
86
61
  }
87
62
  ),
88
- t.suffix ? /* @__PURE__ */ i("span", { id: m, children: /* @__PURE__ */ i(L, { children: t.suffix }) }) : null
63
+ i.suffix ? /* @__PURE__ */ r("span", { id: y, children: /* @__PURE__ */ r(j, { children: i.suffix }) }) : null
89
64
  ] }) : null,
90
- /* @__PURE__ */ i(
65
+ /* @__PURE__ */ r(
91
66
  oe,
92
67
  {
93
68
  name: "confirmation-phrase",
94
69
  size: "large",
95
- value: f,
96
- onChange: a,
97
- label: t ? void 0 : r,
98
- "aria-labelledby": p,
99
- placeholder: u,
70
+ value: p,
71
+ onChange: m,
72
+ label: i ? void 0 : o,
73
+ "aria-labelledby": a,
74
+ placeholder: s,
100
75
  requiredIndicator: "none",
101
- error: !!d,
102
- "aria-describedby": g ? b : void 0,
103
- disabled: l
76
+ error: !!f,
77
+ "aria-describedby": x ? b : void 0,
78
+ disabled: n
104
79
  }
105
80
  ),
106
- /* @__PURE__ */ i(ee, { id: b, message: g }),
107
- t ? /* @__PURE__ */ i("span", { role: "status", className: "sr-only", children: ne(n, e) }) : null
81
+ /* @__PURE__ */ r(P, { id: b, message: x }),
82
+ i ? /* @__PURE__ */ r("span", { role: "status", className: "sr-only", children: se(c, e) }) : null
108
83
  ] });
109
- }, pe = {
110
- default: /* @__PURE__ */ i(U, { size: v }),
111
- warning: /* @__PURE__ */ i(X, { size: v }),
112
- destructive: /* @__PURE__ */ i(Q, { size: v }),
113
- success: /* @__PURE__ */ i(Z, { size: v })
114
- }, Ne = ({
84
+ }, de = {
85
+ default: /* @__PURE__ */ r(U, { size: v }),
86
+ warning: /* @__PURE__ */ r(X, { size: v }),
87
+ destructive: /* @__PURE__ */ r(Q, { size: v }),
88
+ success: /* @__PURE__ */ r(Z, { size: v })
89
+ }, ke = ({
115
90
  open: e,
116
- onClose: t,
117
- onConfirm: r,
118
- title: u,
119
- titleAdornment: f,
120
- badgeIcon: a,
121
- description: l,
122
- variant: s = "default",
123
- callout: n,
124
- confirmPhrase: o,
125
- confirmPhraseLabel: c,
126
- confirmPhraseCopyLabel: d = "Copy",
127
- onPhraseCopied: y,
128
- confirmPhrasePlaceholder: m,
91
+ onClose: i,
92
+ onConfirm: o,
93
+ title: s,
94
+ titleAdornment: p,
95
+ badgeIcon: m,
96
+ description: n,
97
+ variant: l = "default",
98
+ callout: c,
99
+ confirmPhrase: t,
100
+ confirmPhraseLabel: I,
101
+ confirmPhraseCopyLabel: f = "Copy",
102
+ onPhraseCopied: u,
103
+ confirmPhrasePlaceholder: y,
129
104
  confirmLabel: b = "Confirm",
130
- cancelLabel: g = "Cancel",
131
- loading: p = !1,
132
- tip: _,
133
- size: j = "medium",
134
- "aria-label": D,
135
- "aria-labelledby": M,
136
- children: O
105
+ cancelLabel: x = "Cancel",
106
+ loading: a = !1,
107
+ tip: E,
108
+ size: M = "medium",
109
+ "aria-label": O,
110
+ "aria-labelledby": _,
111
+ children: B
137
112
  }) => {
138
- const [T, A] = k(""), N = I(), h = ie[s], [F, B] = k({ open: e, confirmPhrase: o });
139
- (F.open !== e || F.confirmPhrase !== o) && (B({ open: e, confirmPhrase: o }), e && A(""));
140
- const { parts: $, text: w } = se(
141
- c,
142
- o
113
+ const [z, A] = w(""), T = g(), h = re[l], [k, D] = w({ open: e, confirmPhrase: t });
114
+ (k.open !== e || k.confirmPhrase !== t) && (D({ open: e, confirmPhrase: t }), e && A(""));
115
+ const { parts: $, text: F } = le(
116
+ I,
117
+ t
143
118
  ), {
144
119
  outcome: G,
145
120
  canCopy: R,
146
121
  copy: V
147
- } = ce(o, e, p, y), E = !o || T.trim() === o, q = ae(T, o), K = p || !E, W = /* @__PURE__ */ x("div", { className: "flex w-full flex-wrap items-center justify-end gap-[8px]", children: [
148
- /* @__PURE__ */ i(z, { variant: "outline", size: "small", onClick: t, disabled: p, children: g }),
149
- /* @__PURE__ */ i(
150
- z,
122
+ } = ne(t, e, a, u), L = !t || z.trim() === t, q = te(z, t), W = a || !L, Y = /* @__PURE__ */ d("div", { className: "flex w-full flex-wrap items-center justify-end gap-[8px]", children: [
123
+ /* @__PURE__ */ r(N, { variant: "outline", size: "small", onClick: i, disabled: a, children: x }),
124
+ /* @__PURE__ */ r(
125
+ N,
151
126
  {
152
127
  variant: h.confirmVariant,
153
128
  size: "small",
154
- onClick: r,
155
- disabled: K,
156
- loading: p,
157
- tooltip: !p && !E ? w : void 0,
129
+ onClick: o,
130
+ disabled: W,
131
+ loading: a,
132
+ tooltip: !a && !L ? F : void 0,
158
133
  children: b
159
134
  }
160
135
  )
161
136
  ] });
162
- return /* @__PURE__ */ x(
163
- te,
137
+ return /* @__PURE__ */ d(
138
+ ee,
164
139
  {
165
140
  open: e,
166
- onClose: t,
167
- title: u,
168
- size: j,
169
- footer: W,
170
- busy: p,
171
- role: s === "destructive" ? "alertdialog" : "dialog",
172
- "aria-label": D,
173
- "aria-labelledby": M,
174
- "aria-describedby": l ? N : void 0,
175
- closeOnOverlayClick: s !== "destructive" && !o,
141
+ onClose: i,
142
+ title: s,
143
+ size: M,
144
+ footer: Y,
145
+ busy: a,
146
+ role: l === "destructive" ? "alertdialog" : "dialog",
147
+ "aria-label": O,
148
+ "aria-labelledby": _,
149
+ "aria-describedby": n ? T : void 0,
150
+ closeOnOverlayClick: l !== "destructive" && !t,
176
151
  headerDivider: !0,
177
- titleAdornment: f,
152
+ titleAdornment: p,
178
153
  bodyPadding: !1,
179
- tray: { tone: h.tray, caption: _ },
180
- icon: /* @__PURE__ */ i(
154
+ tray: { tone: h.tray, caption: E },
155
+ icon: /* @__PURE__ */ r(
181
156
  "span",
182
157
  {
183
158
  "aria-hidden": "true",
184
159
  className: "confirmation-badge flex size-[18px] shrink-0 items-center justify-center rounded-[7px] text-[var(--malachite-card-background)]",
185
160
  style: { backgroundColor: h.badge },
186
- children: a ?? pe[s]
161
+ children: m ?? de[l]
187
162
  }
188
163
  ),
189
164
  children: [
190
- n ? /* @__PURE__ */ i("div", { className: "border-0 border-b border-solid border-[var(--malachite-card-subtle-divider,var(--malachite-card-border))] p-[10px]", children: /* @__PURE__ */ i(
165
+ c ? /* @__PURE__ */ r("div", { className: "border-0 border-b border-solid border-[var(--malachite-card-subtle-divider,var(--malachite-card-border))] p-[10px]", children: /* @__PURE__ */ r(
191
166
  H,
192
167
  {
193
- type: n.type ?? h.calloutType,
194
- message: n.message,
168
+ type: c.type ?? h.calloutType,
169
+ message: c.message,
195
170
  hasMargin: !1
196
171
  }
197
172
  ) }) : null,
198
- /* @__PURE__ */ x("div", { className: "flex flex-col gap-[12px] p-[28px]", children: [
199
- l ? /* @__PURE__ */ i(
173
+ /* @__PURE__ */ d("div", { className: "flex flex-col gap-[12px] p-[28px]", children: [
174
+ n ? /* @__PURE__ */ r(
200
175
  "div",
201
176
  {
202
- id: N,
177
+ id: T,
203
178
  className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]",
204
- children: l
179
+ children: n
205
180
  }
206
181
  ) : null,
207
- O,
208
- o ? /* @__PURE__ */ i(
209
- de,
182
+ B,
183
+ t ? /* @__PURE__ */ r(
184
+ ce,
210
185
  {
211
- phrase: o,
186
+ phrase: t,
212
187
  parts: $,
213
- plainLabel: w,
214
- placeholder: m,
215
- value: T,
188
+ plainLabel: F,
189
+ placeholder: y,
190
+ value: z,
216
191
  onChange: A,
217
- disabled: p,
218
- copyLabel: d,
192
+ disabled: a,
193
+ copyLabel: f,
219
194
  copyOutcome: G,
220
195
  canCopy: R,
221
196
  onCopy: V,
@@ -228,7 +203,7 @@ const v = 12, re = 1200, C = (e) => e.replace(/\s+/g, " "), ae = (e, t) => {
228
203
  );
229
204
  };
230
205
  export {
231
- Ne as ConfirmationDialog,
232
- Ne as default
206
+ ke as ConfirmationDialog,
207
+ ke as default
233
208
  };
234
209
  //# sourceMappingURL=ConfirmationDialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmationDialog.js","sources":["../../src/components/ConfirmationDialog.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useId, useState } from 'react';\nimport Alert, { type AlertType } from './Alert';\nimport Button from './Button';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport CheckIcon from './CustomIcons/CheckIcon';\nimport CopyIcon from './CustomIcons/CopyIcon';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport FieldMessage from './FieldMessage';\nimport { Input } from './Input';\nimport Modal, { type ModalSize } from './Modal';\nimport Typography from './Typography';\nimport {\n CONFIRMATION_DIALOG_VARIANTS,\n type ConfirmationDialogVariant,\n} from './confirmationDialogVariants';\n\n/** Kept beside the component: an icon is a node, not a value the variant table can hold. */\nconst BADGE_GLYPH_SIZE = 12;\n\nconst COPIED_FEEDBACK_MS = 1200;\n\nconst collapseSpaces = (value: string) => value.replace(/\\s+/g, ' ');\n\nconst nearMissAgainst = (typedPhrase: string, confirmPhrase?: string): string | undefined => {\n const typed = typedPhrase.trim();\n if (!confirmPhrase || typed === '' || typed === confirmPhrase) {\n return undefined;\n }\n if (collapseSpaces(typed).toLowerCase() !== collapseSpaces(confirmPhrase).toLowerCase()) {\n return undefined;\n }\n return collapseSpaces(typed) === collapseSpaces(confirmPhrase)\n ? 'The spacing has to match exactly.'\n : 'This is case-sensitive.';\n};\n\ntype PhraseLabel = string | { prefix: string; suffix?: string };\n\ntype CopyOutcome = 'idle' | 'copied' | 'failed';\n\nconst COPY_FAILED_MESSAGE = 'Could not copy. Enter the phrase manually.';\n\nconst resolvePhraseLabel = (\n label: PhraseLabel | undefined,\n phrase?: string,\n): { parts?: { prefix: string; suffix?: string }; text: string } => {\n const parts = typeof label === 'object' && label !== null ? label : undefined;\n if (parts) {\n return { parts, text: [parts.prefix, phrase, parts.suffix].filter(Boolean).join(' ') };\n }\n return { text: typeof label === 'string' ? label : `Type ${phrase} to confirm` };\n};\n\nconst copyStatusFor = (outcome: CopyOutcome, phrase: string): string =>\n outcome === 'copied' ? `${phrase} copied to clipboard` : '';\n\nconst usePhraseCopy = (\n phrase: string | undefined,\n open: boolean,\n disabled: boolean,\n onCopied?: (phrase: string) => void,\n): { outcome: CopyOutcome; canCopy: boolean; copy: () => void } => {\n const decisionKey = `${open}|${phrase}`;\n const [state, setState] = useState<{\n key: string;\n generation: number;\n outcome: CopyOutcome;\n }>({ key: decisionKey, generation: 0, outcome: 'idle' });\n if (state.key !== decisionKey) {\n setState((previous) => ({\n key: decisionKey,\n generation: previous.generation + 1,\n outcome: 'idle',\n }));\n }\n\n useEffect(() => {\n if (state.outcome !== 'copied') {\n return;\n }\n const timer = setTimeout(\n () => setState((previous) => ({ ...previous, outcome: 'idle' })),\n COPIED_FEEDBACK_MS,\n );\n return () => clearTimeout(timer);\n }, [state.outcome]);\n\n const canCopy = typeof navigator !== 'undefined' && !!navigator.clipboard?.writeText;\n\n const run = async () => {\n if (!phrase || !canCopy) {\n return;\n }\n const generation = state.generation;\n const settle = (outcome: CopyOutcome) =>\n setState((previous) =>\n previous.generation === generation ? { ...previous, outcome } : previous,\n );\n try {\n await navigator.clipboard.writeText(phrase);\n } catch {\n settle('failed');\n return;\n }\n settle('copied');\n queueMicrotask(() => onCopied?.(phrase));\n };\n\n return { outcome: state.outcome, canCopy: canCopy && !disabled, copy: () => void run() };\n};\n\nconst LabelText: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Typography.Text size=\"xsmall\" color=\"primary\" fontWeight=\"semi-bold\">\n {children}\n </Typography.Text>\n);\n\ninterface PhraseFieldProps {\n phrase: string;\n parts?: { prefix: string; suffix?: string };\n plainLabel: string;\n placeholder?: string;\n value: string;\n onChange: (value: string) => void;\n disabled: boolean;\n copyLabel: string;\n copyOutcome: CopyOutcome;\n canCopy: boolean;\n onCopy: () => void;\n nearMissMessage?: string;\n}\n\nconst PhraseField: React.FC<PhraseFieldProps> = ({\n phrase,\n parts,\n plainLabel,\n placeholder,\n value,\n onChange,\n disabled,\n copyLabel,\n copyOutcome,\n canCopy,\n onCopy,\n nearMissMessage,\n}) => {\n const beforeId = useId();\n const afterId = useId();\n const messageId = useId();\n const message =\n [nearMissMessage, copyOutcome === 'failed' ? COPY_FAILED_MESSAGE : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n const labelledBy = parts\n ? [beforeId, parts.suffix ? afterId : undefined].filter(Boolean).join(' ')\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-[6px]\">\n {parts ? (\n <div className=\"flex flex-wrap items-center gap-[6px] px-2\">\n <span id={beforeId}>\n <LabelText>{parts.prefix}</LabelText>{' '}\n <Typography.CodeText variant=\"inline\" size=\"small\">\n {phrase}\n </Typography.CodeText>\n </span>\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly\n aria-label={`${copyLabel} ${phrase}`}\n icon={\n copyOutcome === 'copied' ? (\n <CheckIcon size={13} />\n ) : (\n <CopyIcon size={13} />\n )\n }\n onClick={onCopy}\n disabled={!canCopy}\n />\n {parts.suffix ? (\n <span id={afterId}>\n <LabelText>{parts.suffix}</LabelText>\n </span>\n ) : null}\n </div>\n ) : null}\n <Input\n name=\"confirmation-phrase\"\n size=\"large\"\n value={value}\n onChange={onChange}\n label={parts ? undefined : plainLabel}\n aria-labelledby={labelledBy}\n placeholder={placeholder}\n requiredIndicator=\"none\"\n error={!!nearMissMessage}\n aria-describedby={message ? messageId : undefined}\n disabled={disabled}\n />\n <FieldMessage id={messageId} message={message} />\n {parts ? (\n <span role=\"status\" className=\"sr-only\">\n {copyStatusFor(copyOutcome, phrase)}\n </span>\n ) : null}\n </div>\n );\n};\n\nconst VARIANT_ICON: Record<ConfirmationDialogVariant, React.ReactNode> = {\n default: <InfoCircleFilled size={BADGE_GLYPH_SIZE} />,\n warning: <WarningCircleFilled size={BADGE_GLYPH_SIZE} />,\n destructive: <ErrorCircleFilled size={BADGE_GLYPH_SIZE} />,\n success: <CheckCircleFilled size={BADGE_GLYPH_SIZE} />,\n};\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n /** Dismiss handler — cancel, close button, ESC or scrim. `loading` suppresses every\n * route except ESC, which always reaches this so a keyboard user is never stranded. */\n onClose: () => void;\n /** Runs when the confirm action is taken. Closing is left to the consumer. */\n onConfirm: () => void;\n title: React.ReactNode;\n titleAdornment?: React.ReactNode;\n badgeIcon?: React.ReactNode;\n /** The sentence saying what is about to happen. */\n description?: React.ReactNode;\n variant?: ConfirmationDialogVariant;\n /** Coloured callout below the body. Defaults to the variant's own type. */\n callout?: { type?: AlertType; message: string };\n /**\n * Requires this exact phrase to be typed before the confirm action enables — for a\n * consequence severe enough that a single click should not be able to cause it.\n */\n confirmPhrase?: string;\n /** Label above the type-to-confirm field. `{ prefix, suffix }` makes the phrase copyable. */\n confirmPhraseLabel?: PhraseLabel;\n /** Names the copy control, e.g. `Copy profile name`. Default: `Copy`. */\n confirmPhraseCopyLabel?: string;\n /** Runs after the phrase reaches the clipboard, with what was copied. */\n onPhraseCopied?: (phrase: string) => void;\n confirmPhrasePlaceholder?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n /**\n * Disables the actions, spins the confirm button and suppresses the pointer dismissal\n * routes — but never ESC, which always reaches `onClose`.\n */\n loading?: boolean;\n tip?: { label?: string; message: string };\n size?: ModalSize;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Extra body content between the description and the callout, e.g. an entity chip. */\n children?: React.ReactNode;\n}\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({\n open,\n onClose,\n onConfirm,\n title,\n titleAdornment,\n badgeIcon,\n description,\n variant = 'default',\n callout,\n confirmPhrase,\n confirmPhraseLabel,\n confirmPhraseCopyLabel = 'Copy',\n onPhraseCopied,\n confirmPhrasePlaceholder,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n loading = false,\n tip,\n size = 'medium',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n children,\n}) => {\n const [typedPhrase, setTypedPhrase] = useState('');\n const descriptionId = useId();\n const base = CONFIRMATION_DIALOG_VARIANTS[variant];\n\n // On open, not close: the dialog outlives `open` by its exit transition, so resetting on\n // close empties the field in front of the user. Adjusted during render rather than from an\n // effect, or a reopen paints the previous answer once with confirm already enabled.\n const [answeredFor, setAnsweredFor] = useState({ open, confirmPhrase });\n if (answeredFor.open !== open || answeredFor.confirmPhrase !== confirmPhrase) {\n setAnsweredFor({ open, confirmPhrase });\n if (open) {\n setTypedPhrase('');\n }\n }\n\n const { parts: phraseParts, text: phraseLabel } = resolvePhraseLabel(\n confirmPhraseLabel,\n confirmPhrase,\n );\n const {\n outcome: copyOutcome,\n canCopy: canCopyPhrase,\n copy: handleCopyPhrase,\n } = usePhraseCopy(confirmPhrase, open, loading, onPhraseCopied);\n // Trimmed because copying an entity name commonly picks up a trailing space; the gate is\n // still exact, and deliberately case-sensitive.\n const phraseSatisfied = !confirmPhrase || typedPhrase.trim() === confirmPhrase;\n const nearMissMessage = nearMissAgainst(typedPhrase, confirmPhrase);\n const confirmDisabled = loading || !phraseSatisfied;\n\n const footer = (\n <div className=\"flex w-full flex-wrap items-center justify-end gap-[8px]\">\n <Button variant=\"outline\" size=\"small\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n variant={base.confirmVariant}\n size=\"small\"\n onClick={onConfirm}\n disabled={confirmDisabled}\n loading={loading}\n // A disabled control emits no hover, so the tooltip explains the gate from the\n // wrapper Button renders for exactly this case.\n tooltip={!loading && !phraseSatisfied ? phraseLabel : undefined}\n >\n {confirmLabel}\n </Button>\n </div>\n );\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size={size}\n footer={footer}\n busy={loading}\n // A consequential choice is an alertdialog: it asks assistive tech to announce the\n // body, which is where the consequence is written.\n role={variant === 'destructive' ? 'alertdialog' : 'dialog'}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={description ? descriptionId : undefined}\n // A choice this deliberate should not be undone by a stray click, and a scrim\n // click must not discard a phrase the customer has already typed.\n closeOnOverlayClick={variant !== 'destructive' && !confirmPhrase}\n headerDivider\n titleAdornment={titleAdornment}\n bodyPadding={false}\n tray={{ tone: base.tray, caption: tip }}\n icon={\n <span\n aria-hidden=\"true\"\n className=\"confirmation-badge flex size-[18px] shrink-0 items-center justify-center rounded-[7px] text-[var(--malachite-card-background)]\"\n style={{ backgroundColor: base.badge }}\n >\n {badgeIcon ?? VARIANT_ICON[variant]}\n </span>\n }\n >\n {callout ? (\n <div className=\"border-0 border-b border-solid border-[var(--malachite-card-subtle-divider,var(--malachite-card-border))] p-[10px]\">\n <Alert\n type={callout.type ?? base.calloutType}\n message={callout.message}\n hasMargin={false}\n />\n </div>\n ) : null}\n <div className=\"flex flex-col gap-[12px] p-[28px]\">\n {description ? (\n <div\n id={descriptionId}\n className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\"\n >\n {description}\n </div>\n ) : null}\n {children}\n {confirmPhrase ? (\n <PhraseField\n phrase={confirmPhrase}\n parts={phraseParts}\n plainLabel={phraseLabel}\n placeholder={confirmPhrasePlaceholder}\n value={typedPhrase}\n onChange={setTypedPhrase}\n disabled={loading}\n copyLabel={confirmPhraseCopyLabel}\n copyOutcome={copyOutcome}\n canCopy={canCopyPhrase}\n onCopy={handleCopyPhrase}\n nearMissMessage={nearMissMessage}\n />\n ) : null}\n </div>\n </Modal>\n );\n};\n\nexport default ConfirmationDialog;\nexport { ConfirmationDialog };\nexport type { ConfirmationDialogVariant };\n"],"names":["BADGE_GLYPH_SIZE","COPIED_FEEDBACK_MS","collapseSpaces","value","nearMissAgainst","typedPhrase","confirmPhrase","typed","COPY_FAILED_MESSAGE","resolvePhraseLabel","label","phrase","parts","copyStatusFor","outcome","usePhraseCopy","open","disabled","onCopied","decisionKey","state","setState","useState","previous","useEffect","timer","canCopy","_a","run","generation","settle","LabelText","children","jsx","Typography","PhraseField","plainLabel","placeholder","onChange","copyLabel","copyOutcome","onCopy","nearMissMessage","beforeId","useId","afterId","messageId","message","labelledBy","jsxs","Button","CheckIcon","CopyIcon","Input","FieldMessage","VARIANT_ICON","InfoCircleFilled","WarningCircleFilled","ErrorCircleFilled","CheckCircleFilled","ConfirmationDialog","onClose","onConfirm","title","titleAdornment","badgeIcon","description","variant","callout","confirmPhraseLabel","confirmPhraseCopyLabel","onPhraseCopied","confirmPhrasePlaceholder","confirmLabel","cancelLabel","loading","tip","size","ariaLabel","ariaLabelledBy","setTypedPhrase","descriptionId","base","CONFIRMATION_DIALOG_VARIANTS","answeredFor","setAnsweredFor","phraseParts","phraseLabel","canCopyPhrase","handleCopyPhrase","phraseSatisfied","confirmDisabled","footer","Modal","Alert"],"mappings":"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"}
1
+ {"version":3,"file":"ConfirmationDialog.js","sources":["../../src/components/ConfirmationDialog.tsx"],"sourcesContent":["import type React from 'react';\nimport { useId, useState } from 'react';\nimport Alert, { type AlertType } from './Alert';\nimport Button from './Button';\nimport CheckCircleFilled from './CustomIcons/CheckCircleFilled';\nimport CheckmarkIcon from './CustomIcons/CheckmarkIcon';\nimport CopyIcon from './CustomIcons/CopyIcon';\nimport ErrorCircleFilled from './CustomIcons/ErrorCircleFilled';\nimport InfoCircleFilled from './CustomIcons/InfoCircleFilled';\nimport WarningCircleFilled from './CustomIcons/WarningCircleFilled';\nimport FieldMessage from './FieldMessage';\nimport { Input } from './Input';\nimport Modal, { type ModalSize } from './Modal';\nimport Typography from './Typography';\nimport { type CopyOutcome, useClipboardCopy } from './useClipboardCopy';\nimport {\n CONFIRMATION_DIALOG_VARIANTS,\n type ConfirmationDialogVariant,\n} from './confirmationDialogVariants';\n\n/** Kept beside the component: an icon is a node, not a value the variant table can hold. */\nconst BADGE_GLYPH_SIZE = 12;\n\nconst collapseSpaces = (value: string) => value.replace(/\\s+/g, ' ');\n\nconst nearMissAgainst = (typedPhrase: string, confirmPhrase?: string): string | undefined => {\n const typed = typedPhrase.trim();\n if (!confirmPhrase || typed === '' || typed === confirmPhrase) {\n return undefined;\n }\n if (collapseSpaces(typed).toLowerCase() !== collapseSpaces(confirmPhrase).toLowerCase()) {\n return undefined;\n }\n return collapseSpaces(typed) === collapseSpaces(confirmPhrase)\n ? 'The spacing has to match exactly.'\n : 'This is case-sensitive.';\n};\n\ntype PhraseLabel = string | { prefix: string; suffix?: string };\n\nconst COPY_FAILED_MESSAGE = 'Could not copy. Enter the phrase manually.';\n\nconst resolvePhraseLabel = (\n label: PhraseLabel | undefined,\n phrase?: string,\n): { parts?: { prefix: string; suffix?: string }; text: string } => {\n const parts = typeof label === 'object' && label !== null ? label : undefined;\n if (parts) {\n return { parts, text: [parts.prefix, phrase, parts.suffix].filter(Boolean).join(' ') };\n }\n return { text: typeof label === 'string' ? label : `Type ${phrase} to confirm` };\n};\n\nconst copyStatusFor = (outcome: CopyOutcome, phrase: string): string =>\n outcome === 'copied' ? `${phrase} copied to clipboard` : '';\n\nconst usePhraseCopy = (\n phrase: string | undefined,\n open: boolean,\n disabled: boolean,\n onCopied?: (phrase: string) => void,\n): { outcome: CopyOutcome; canCopy: boolean; copy: () => void } => {\n const { outcome, canCopy, copy } = useClipboardCopy(`${open}|${phrase}`);\n\n const run = async () => {\n if (phrase && (await copy(phrase))) {\n queueMicrotask(() => onCopied?.(phrase));\n }\n };\n\n return { outcome, canCopy: canCopy && !disabled, copy: () => void run() };\n};\n\nconst LabelText: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Typography.Text size=\"xsmall\" color=\"primary\" fontWeight=\"semi-bold\">\n {children}\n </Typography.Text>\n);\n\ninterface PhraseFieldProps {\n phrase: string;\n parts?: { prefix: string; suffix?: string };\n plainLabel: string;\n placeholder?: string;\n value: string;\n onChange: (value: string) => void;\n disabled: boolean;\n copyLabel: string;\n copyOutcome: CopyOutcome;\n canCopy: boolean;\n onCopy: () => void;\n nearMissMessage?: string;\n}\n\nconst PhraseField: React.FC<PhraseFieldProps> = ({\n phrase,\n parts,\n plainLabel,\n placeholder,\n value,\n onChange,\n disabled,\n copyLabel,\n copyOutcome,\n canCopy,\n onCopy,\n nearMissMessage,\n}) => {\n const beforeId = useId();\n const afterId = useId();\n const messageId = useId();\n const message =\n [nearMissMessage, copyOutcome === 'failed' ? COPY_FAILED_MESSAGE : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n const labelledBy = parts\n ? [beforeId, parts.suffix ? afterId : undefined].filter(Boolean).join(' ')\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-[6px]\">\n {parts ? (\n <div className=\"flex flex-wrap items-center gap-[6px] px-2\">\n <span id={beforeId}>\n <LabelText>{parts.prefix}</LabelText>{' '}\n <Typography.CodeText variant=\"inline\" size=\"small\">\n {phrase}\n </Typography.CodeText>\n </span>\n <Button\n variant=\"ghost\"\n size=\"small\"\n iconOnly\n aria-label={`${copyLabel} ${phrase}`}\n icon={\n copyOutcome === 'copied' ? (\n <CheckmarkIcon size={13} />\n ) : (\n <CopyIcon size={13} />\n )\n }\n onClick={onCopy}\n disabled={!canCopy}\n />\n {parts.suffix ? (\n <span id={afterId}>\n <LabelText>{parts.suffix}</LabelText>\n </span>\n ) : null}\n </div>\n ) : null}\n <Input\n name=\"confirmation-phrase\"\n size=\"large\"\n value={value}\n onChange={onChange}\n label={parts ? undefined : plainLabel}\n aria-labelledby={labelledBy}\n placeholder={placeholder}\n requiredIndicator=\"none\"\n error={!!nearMissMessage}\n aria-describedby={message ? messageId : undefined}\n disabled={disabled}\n />\n <FieldMessage id={messageId} message={message} />\n {parts ? (\n <span role=\"status\" className=\"sr-only\">\n {copyStatusFor(copyOutcome, phrase)}\n </span>\n ) : null}\n </div>\n );\n};\n\nconst VARIANT_ICON: Record<ConfirmationDialogVariant, React.ReactNode> = {\n default: <InfoCircleFilled size={BADGE_GLYPH_SIZE} />,\n warning: <WarningCircleFilled size={BADGE_GLYPH_SIZE} />,\n destructive: <ErrorCircleFilled size={BADGE_GLYPH_SIZE} />,\n success: <CheckCircleFilled size={BADGE_GLYPH_SIZE} />,\n};\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n /** Dismiss handler — cancel, close button, ESC or scrim. `loading` suppresses every\n * route except ESC, which always reaches this so a keyboard user is never stranded. */\n onClose: () => void;\n /** Runs when the confirm action is taken. Closing is left to the consumer. */\n onConfirm: () => void;\n title: React.ReactNode;\n titleAdornment?: React.ReactNode;\n badgeIcon?: React.ReactNode;\n /** The sentence saying what is about to happen. */\n description?: React.ReactNode;\n variant?: ConfirmationDialogVariant;\n /** Coloured callout below the body. Defaults to the variant's own type. */\n callout?: { type?: AlertType; message: string };\n /**\n * Requires this exact phrase to be typed before the confirm action enables — for a\n * consequence severe enough that a single click should not be able to cause it.\n */\n confirmPhrase?: string;\n /** Label above the type-to-confirm field. `{ prefix, suffix }` makes the phrase copyable. */\n confirmPhraseLabel?: PhraseLabel;\n /** Names the copy control, e.g. `Copy profile name`. Default: `Copy`. */\n confirmPhraseCopyLabel?: string;\n /** Runs after the phrase reaches the clipboard, with what was copied. */\n onPhraseCopied?: (phrase: string) => void;\n confirmPhrasePlaceholder?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n /**\n * Disables the actions, spins the confirm button and suppresses the pointer dismissal\n * routes — but never ESC, which always reaches `onClose`.\n */\n loading?: boolean;\n tip?: { label?: string; message: string };\n size?: ModalSize;\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** Extra body content between the description and the callout, e.g. an entity chip. */\n children?: React.ReactNode;\n}\n\nconst ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({\n open,\n onClose,\n onConfirm,\n title,\n titleAdornment,\n badgeIcon,\n description,\n variant = 'default',\n callout,\n confirmPhrase,\n confirmPhraseLabel,\n confirmPhraseCopyLabel = 'Copy',\n onPhraseCopied,\n confirmPhrasePlaceholder,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n loading = false,\n tip,\n size = 'medium',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n children,\n}) => {\n const [typedPhrase, setTypedPhrase] = useState('');\n const descriptionId = useId();\n const base = CONFIRMATION_DIALOG_VARIANTS[variant];\n\n // On open, not close: the dialog outlives `open` by its exit transition, so resetting on\n // close empties the field in front of the user. Adjusted during render rather than from an\n // effect, or a reopen paints the previous answer once with confirm already enabled.\n const [answeredFor, setAnsweredFor] = useState({ open, confirmPhrase });\n if (answeredFor.open !== open || answeredFor.confirmPhrase !== confirmPhrase) {\n setAnsweredFor({ open, confirmPhrase });\n if (open) {\n setTypedPhrase('');\n }\n }\n\n const { parts: phraseParts, text: phraseLabel } = resolvePhraseLabel(\n confirmPhraseLabel,\n confirmPhrase,\n );\n const {\n outcome: copyOutcome,\n canCopy: canCopyPhrase,\n copy: handleCopyPhrase,\n } = usePhraseCopy(confirmPhrase, open, loading, onPhraseCopied);\n // Trimmed because copying an entity name commonly picks up a trailing space; the gate is\n // still exact, and deliberately case-sensitive.\n const phraseSatisfied = !confirmPhrase || typedPhrase.trim() === confirmPhrase;\n const nearMissMessage = nearMissAgainst(typedPhrase, confirmPhrase);\n const confirmDisabled = loading || !phraseSatisfied;\n\n const footer = (\n <div className=\"flex w-full flex-wrap items-center justify-end gap-[8px]\">\n <Button variant=\"outline\" size=\"small\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n variant={base.confirmVariant}\n size=\"small\"\n onClick={onConfirm}\n disabled={confirmDisabled}\n loading={loading}\n // A disabled control emits no hover, so the tooltip explains the gate from the\n // wrapper Button renders for exactly this case.\n tooltip={!loading && !phraseSatisfied ? phraseLabel : undefined}\n >\n {confirmLabel}\n </Button>\n </div>\n );\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n size={size}\n footer={footer}\n busy={loading}\n // A consequential choice is an alertdialog: it asks assistive tech to announce the\n // body, which is where the consequence is written.\n role={variant === 'destructive' ? 'alertdialog' : 'dialog'}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={description ? descriptionId : undefined}\n // A choice this deliberate should not be undone by a stray click, and a scrim\n // click must not discard a phrase the customer has already typed.\n closeOnOverlayClick={variant !== 'destructive' && !confirmPhrase}\n headerDivider\n titleAdornment={titleAdornment}\n bodyPadding={false}\n tray={{ tone: base.tray, caption: tip }}\n icon={\n <span\n aria-hidden=\"true\"\n className=\"confirmation-badge flex size-[18px] shrink-0 items-center justify-center rounded-[7px] text-[var(--malachite-card-background)]\"\n style={{ backgroundColor: base.badge }}\n >\n {badgeIcon ?? VARIANT_ICON[variant]}\n </span>\n }\n >\n {callout ? (\n <div className=\"border-0 border-b border-solid border-[var(--malachite-card-subtle-divider,var(--malachite-card-border))] p-[10px]\">\n <Alert\n type={callout.type ?? base.calloutType}\n message={callout.message}\n hasMargin={false}\n />\n </div>\n ) : null}\n <div className=\"flex flex-col gap-[12px] p-[28px]\">\n {description ? (\n <div\n id={descriptionId}\n className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\"\n >\n {description}\n </div>\n ) : null}\n {children}\n {confirmPhrase ? (\n <PhraseField\n phrase={confirmPhrase}\n parts={phraseParts}\n plainLabel={phraseLabel}\n placeholder={confirmPhrasePlaceholder}\n value={typedPhrase}\n onChange={setTypedPhrase}\n disabled={loading}\n copyLabel={confirmPhraseCopyLabel}\n copyOutcome={copyOutcome}\n canCopy={canCopyPhrase}\n onCopy={handleCopyPhrase}\n nearMissMessage={nearMissMessage}\n />\n ) : null}\n </div>\n </Modal>\n );\n};\n\nexport default ConfirmationDialog;\nexport { ConfirmationDialog };\nexport type { ConfirmationDialogVariant };\n"],"names":["BADGE_GLYPH_SIZE","collapseSpaces","value","nearMissAgainst","typedPhrase","confirmPhrase","typed","COPY_FAILED_MESSAGE","resolvePhraseLabel","label","phrase","parts","copyStatusFor","outcome","usePhraseCopy","open","disabled","onCopied","canCopy","copy","useClipboardCopy","run","LabelText","children","jsx","Typography","PhraseField","plainLabel","placeholder","onChange","copyLabel","copyOutcome","onCopy","nearMissMessage","beforeId","useId","afterId","messageId","message","labelledBy","jsxs","Button","CheckmarkIcon","CopyIcon","Input","FieldMessage","VARIANT_ICON","InfoCircleFilled","WarningCircleFilled","ErrorCircleFilled","CheckCircleFilled","ConfirmationDialog","onClose","onConfirm","title","titleAdornment","badgeIcon","description","variant","callout","confirmPhraseLabel","confirmPhraseCopyLabel","onPhraseCopied","confirmPhrasePlaceholder","confirmLabel","cancelLabel","loading","tip","size","ariaLabel","ariaLabelledBy","setTypedPhrase","useState","descriptionId","base","CONFIRMATION_DIALOG_VARIANTS","answeredFor","setAnsweredFor","phraseParts","phraseLabel","canCopyPhrase","handleCopyPhrase","phraseSatisfied","confirmDisabled","footer","Modal","Alert"],"mappings":";;;;;;;;;;;;;;;;AAqBA,MAAMA,IAAmB,IAEnBC,IAAiB,CAACC,MAAkBA,EAAM,QAAQ,QAAQ,GAAG,GAE7DC,KAAkB,CAACC,GAAqBC,MAA+C;AACzF,QAAMC,IAAQF,EAAY,KAAA;AAC1B,MAAI,GAACC,KAAiBC,MAAU,MAAMA,MAAUD,MAG5CJ,EAAeK,CAAK,EAAE,YAAA,MAAkBL,EAAeI,CAAa,EAAE;AAG1E,WAAOJ,EAAeK,CAAK,MAAML,EAAeI,CAAa,IACvD,sCACA;AACV,GAIME,KAAsB,8CAEtBC,KAAqB,CACvBC,GACAC,MACgE;AAChE,QAAMC,IAAQ,OAAOF,KAAU,YAAYA,MAAU,OAAOA,IAAQ;AACpE,SAAIE,IACO,EAAE,OAAAA,GAAO,MAAM,CAACA,EAAM,QAAQD,GAAQC,EAAM,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAA,IAEhF,EAAE,MAAM,OAAOF,KAAU,WAAWA,IAAQ,QAAQC,CAAM,cAAA;AACrE,GAEME,KAAgB,CAACC,GAAsBH,MACzCG,MAAY,WAAW,GAAGH,CAAM,yBAAyB,IAEvDI,KAAgB,CAClBJ,GACAK,GACAC,GACAC,MAC+D;AAC/D,QAAM,EAAE,SAAAJ,GAAS,SAAAK,GAAS,MAAAC,MAASC,GAAiB,GAAGL,CAAI,IAAIL,CAAM,EAAE,GAEjEW,IAAM,YAAY;AACpB,IAAIX,KAAW,MAAMS,EAAKT,CAAM,KAC5B,eAAe,MAAMO,KAAA,gBAAAA,EAAWP,EAAO;AAAA,EAE/C;AAEA,SAAO,EAAE,SAAAG,GAAS,SAASK,KAAW,CAACF,GAAU,MAAM,MAAM,KAAKK,IAAI;AAC1E,GAEMC,IAAqD,CAAC,EAAE,UAAAC,EAAA,MAC1D,gBAAAC,EAACC,EAAW,MAAX,EAAgB,MAAK,UAAS,OAAM,WAAU,YAAW,aACrD,UAAAF,EAAA,CACL,GAkBEG,KAA0C,CAAC;AAAA,EAC7C,QAAAhB;AAAA,EACA,OAAAC;AAAA,EACA,YAAAgB;AAAA,EACA,aAAAC;AAAA,EACA,OAAA1B;AAAA,EACA,UAAA2B;AAAA,EACA,UAAAb;AAAA,EACA,WAAAc;AAAA,EACA,aAAAC;AAAA,EACA,SAAAb;AAAA,EACA,QAAAc;AAAA,EACA,iBAAAC;AACJ,MAAM;AACF,QAAMC,IAAWC,EAAA,GACXC,IAAUD,EAAA,GACVE,IAAYF,EAAA,GACZG,IACF,CAACL,GAAiBF,MAAgB,WAAWxB,KAAsB,MAAS,EACvE,OAAO,OAAO,EACd,KAAK,GAAG,KAAK,QAChBgC,IAAa5B,IACb,CAACuB,GAAUvB,EAAM,SAASyB,IAAU,MAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,IACvE;AAEN,SACI,gBAAAI,EAAC,OAAA,EAAI,WAAU,2BACV,UAAA;AAAA,IAAA7B,IACG,gBAAA6B,EAAC,OAAA,EAAI,WAAU,8CACX,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EAAK,IAAIN,GACN,UAAA;AAAA,QAAA,gBAAAV,EAACF,GAAA,EAAW,YAAM,OAAA,CAAO;AAAA,QAAa;AAAA,QACtC,gBAAAE,EAACC,EAAW,UAAX,EAAoB,SAAQ,UAAS,MAAK,SACtC,UAAAf,EAAA,CACL;AAAA,MAAA,GACJ;AAAA,MACA,gBAAAc;AAAA,QAACiB;AAAA,QAAA;AAAA,UACG,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,UAAQ;AAAA,UACR,cAAY,GAAGX,CAAS,IAAIpB,CAAM;AAAA,UAClC,MACIqB,MAAgB,WACZ,gBAAAP,EAACkB,GAAA,EAAc,MAAM,GAAA,CAAI,IAEzB,gBAAAlB,EAACmB,GAAA,EAAS,MAAM,GAAA,CAAI;AAAA,UAG5B,SAASX;AAAA,UACT,UAAU,CAACd;AAAA,QAAA;AAAA,MAAA;AAAA,MAEdP,EAAM,SACH,gBAAAa,EAAC,QAAA,EAAK,IAAIY,GACN,UAAA,gBAAAZ,EAACF,GAAA,EAAW,UAAAX,EAAM,OAAA,CAAO,EAAA,CAC7B,IACA;AAAA,IAAA,EAAA,CACR,IACA;AAAA,IACJ,gBAAAa;AAAA,MAACoB;AAAA,MAAA;AAAA,QACG,MAAK;AAAA,QACL,MAAK;AAAA,QACL,OAAA1C;AAAA,QACA,UAAA2B;AAAA,QACA,OAAOlB,IAAQ,SAAYgB;AAAA,QAC3B,mBAAiBY;AAAA,QACjB,aAAAX;AAAA,QACA,mBAAkB;AAAA,QAClB,OAAO,CAAC,CAACK;AAAA,QACT,oBAAkBK,IAAUD,IAAY;AAAA,QACxC,UAAArB;AAAA,MAAA;AAAA,IAAA;AAAA,IAEJ,gBAAAQ,EAACqB,GAAA,EAAa,IAAIR,GAAW,SAAAC,EAAA,CAAkB;AAAA,IAC9C3B,IACG,gBAAAa,EAAC,QAAA,EAAK,MAAK,UAAS,WAAU,WACzB,UAAAZ,GAAcmB,GAAarB,CAAM,EAAA,CACtC,IACA;AAAA,EAAA,GACR;AAER,GAEMoC,KAAmE;AAAA,EACrE,SAAS,gBAAAtB,EAACuB,GAAA,EAAiB,MAAM/C,EAAA,CAAkB;AAAA,EACnD,SAAS,gBAAAwB,EAACwB,GAAA,EAAoB,MAAMhD,EAAA,CAAkB;AAAA,EACtD,aAAa,gBAAAwB,EAACyB,GAAA,EAAkB,MAAMjD,EAAA,CAAkB;AAAA,EACxD,SAAS,gBAAAwB,EAAC0B,GAAA,EAAkB,MAAMlD,EAAA,CAAkB;AACxD,GA8CMmD,KAAwD,CAAC;AAAA,EAC3D,MAAApC;AAAA,EACA,SAAAqC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,SAAAC;AAAA,EACA,eAAAtD;AAAA,EACA,oBAAAuD;AAAA,EACA,wBAAAC,IAAyB;AAAA,EACzB,gBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,aAAAC,IAAc;AAAA,EACd,SAAAC,IAAU;AAAA,EACV,KAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,cAAcC;AAAA,EACd,mBAAmBC;AAAA,EACnB,UAAA/C;AACJ,MAAM;AACF,QAAM,CAACnB,GAAamE,CAAc,IAAIC,EAAS,EAAE,GAC3CC,IAAgBtC,EAAA,GAChBuC,IAAOC,GAA6BjB,CAAO,GAK3C,CAACkB,GAAaC,CAAc,IAAIL,EAAS,EAAE,MAAAzD,GAAM,eAAAV,GAAe;AACtE,GAAIuE,EAAY,SAAS7D,KAAQ6D,EAAY,kBAAkBvE,OAC3DwE,EAAe,EAAE,MAAA9D,GAAM,eAAAV,GAAe,GAClCU,KACAwD,EAAe,EAAE;AAIzB,QAAM,EAAE,OAAOO,GAAa,MAAMC,MAAgBvE;AAAA,IAC9CoD;AAAA,IACAvD;AAAA,EAAA,GAEE;AAAA,IACF,SAAS0B;AAAA,IACT,SAASiD;AAAA,IACT,MAAMC;AAAA,EAAA,IACNnE,GAAcT,GAAeU,GAAMmD,GAASJ,CAAc,GAGxDoB,IAAkB,CAAC7E,KAAiBD,EAAY,WAAWC,GAC3D4B,IAAkB9B,GAAgBC,GAAaC,CAAa,GAC5D8E,IAAkBjB,KAAW,CAACgB,GAE9BE,IACF,gBAAA5C,EAAC,OAAA,EAAI,WAAU,4DACX,UAAA;AAAA,IAAA,gBAAAhB,EAACiB,GAAA,EAAO,SAAQ,WAAU,MAAK,SAAQ,SAASW,GAAS,UAAUc,GAC9D,UAAAD,EAAA,CACL;AAAA,IACA,gBAAAzC;AAAA,MAACiB;AAAA,MAAA;AAAA,QACG,SAASiC,EAAK;AAAA,QACd,MAAK;AAAA,QACL,SAASrB;AAAA,QACT,UAAU8B;AAAA,QACV,SAAAjB;AAAA,QAGA,SAAS,CAACA,KAAW,CAACgB,IAAkBH,IAAc;AAAA,QAErD,UAAAf;AAAA,MAAA;AAAA,IAAA;AAAA,EACL,GACJ;AAGJ,SACI,gBAAAxB;AAAA,IAAC6C;AAAA,IAAA;AAAA,MACG,MAAAtE;AAAA,MACA,SAAAqC;AAAA,MACA,OAAAE;AAAA,MACA,MAAAc;AAAA,MACA,QAAAgB;AAAA,MACA,MAAMlB;AAAA,MAGN,MAAMR,MAAY,gBAAgB,gBAAgB;AAAA,MAClD,cAAYW;AAAA,MACZ,mBAAiBC;AAAA,MACjB,oBAAkBb,IAAcgB,IAAgB;AAAA,MAGhD,qBAAqBf,MAAY,iBAAiB,CAACrD;AAAA,MACnD,eAAa;AAAA,MACb,gBAAAkD;AAAA,MACA,aAAa;AAAA,MACb,MAAM,EAAE,MAAMmB,EAAK,MAAM,SAASP,EAAA;AAAA,MAClC,MACI,gBAAA3C;AAAA,QAAC;AAAA,QAAA;AAAA,UACG,eAAY;AAAA,UACZ,WAAU;AAAA,UACV,OAAO,EAAE,iBAAiBkD,EAAK,MAAA;AAAA,UAE9B,UAAAlB,KAAaV,GAAaY,CAAO;AAAA,QAAA;AAAA,MAAA;AAAA,MAIzC,UAAA;AAAA,QAAAC,IACG,gBAAAnC,EAAC,OAAA,EAAI,WAAU,sHACX,UAAA,gBAAAA;AAAA,UAAC8D;AAAA,UAAA;AAAA,YACG,MAAM3B,EAAQ,QAAQe,EAAK;AAAA,YAC3B,SAASf,EAAQ;AAAA,YACjB,WAAW;AAAA,UAAA;AAAA,QAAA,GAEnB,IACA;AAAA,QACJ,gBAAAnB,EAAC,OAAA,EAAI,WAAU,qCACV,UAAA;AAAA,UAAAiB,IACG,gBAAAjC;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,IAAIiD;AAAA,cACJ,WAAU;AAAA,cAET,UAAAhB;AAAA,YAAA;AAAA,UAAA,IAEL;AAAA,UACHlC;AAAA,UACAlB,IACG,gBAAAmB;AAAA,YAACE;AAAA,YAAA;AAAA,cACG,QAAQrB;AAAA,cACR,OAAOyE;AAAA,cACP,YAAYC;AAAA,cACZ,aAAahB;AAAA,cACb,OAAO3D;AAAA,cACP,UAAUmE;AAAA,cACV,UAAUL;AAAA,cACV,WAAWL;AAAA,cACX,aAAA9B;AAAA,cACA,SAASiD;AAAA,cACT,QAAQC;AAAA,cACR,iBAAAhD;AAAA,YAAA;AAAA,UAAA,IAEJ;AAAA,QAAA,EAAA,CACR;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGZ;"}