@burojs/ui-shadcn 0.5.0 → 0.7.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.
- package/README.md +9 -0
- package/dist/bulk-summary-BWSAS7k2.js +143 -0
- package/dist/bulk-summary-BWSAS7k2.js.map +1 -0
- package/dist/bulk-summary-CrEij5vq.cjs +143 -0
- package/dist/bulk-summary-CrEij5vq.cjs.map +1 -0
- package/dist/candidates-relation-picker-CS_JZ4Fd.js +31 -0
- package/dist/candidates-relation-picker-CS_JZ4Fd.js.map +1 -0
- package/dist/candidates-relation-picker-y5M6_oe4.cjs +31 -0
- package/dist/candidates-relation-picker-y5M6_oe4.cjs.map +1 -0
- package/dist/{check-confirm-dialog-CkaVTPT9.js → check-confirm-dialog-2j0gOd7x.js} +392 -103
- package/dist/check-confirm-dialog-2j0gOd7x.js.map +1 -0
- package/dist/{check-confirm-dialog-BRByTFpg.cjs → check-confirm-dialog-C-NHgMST.cjs} +476 -102
- package/dist/check-confirm-dialog-C-NHgMST.cjs.map +1 -0
- package/dist/{dialog-B_rt9S1c.js → dialog-C123sVQ8.js} +4 -4
- package/dist/dialog-C123sVQ8.js.map +1 -0
- package/dist/{dialog-DRNUq9EA.cjs → dialog-vmMdfUWs.cjs} +3 -3
- package/dist/dialog-vmMdfUWs.cjs.map +1 -0
- package/dist/{filter-builder-B3mZFL-K.cjs → filter-builder-DFu0JP-1.cjs} +959 -128
- package/dist/filter-builder-DFu0JP-1.cjs.map +1 -0
- package/dist/{filter-builder-DOnaXNfP.js → filter-builder-DaWHUZuV.js} +863 -116
- package/dist/filter-builder-DaWHUZuV.js.map +1 -0
- package/dist/{flow-runtime-B6zOHYqI.cjs → flow-runtime-BpmrIUb6.cjs} +61 -29
- package/dist/flow-runtime-BpmrIUb6.cjs.map +1 -0
- package/dist/{flow-runtime-D8h99FSg.js → flow-runtime-DyqTmK3H.js} +62 -30
- package/dist/flow-runtime-DyqTmK3H.js.map +1 -0
- package/dist/{flow-screen-CX05b3G9.cjs → flow-screen-Bcz9NF2V.cjs} +132 -88
- package/dist/flow-screen-Bcz9NF2V.cjs.map +1 -0
- package/dist/{flow-screen-CmbARSqg.js → flow-screen-DCdli6Ha.js} +132 -88
- package/dist/flow-screen-DCdli6Ha.js.map +1 -0
- package/dist/index.cjs +951 -605
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +618 -332
- package/dist/index.d.ts +618 -332
- package/dist/index.js +863 -522
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-B7U1OJUe.cjs → inline-flow-host-3vw7LzzD.cjs} +5 -5
- package/dist/inline-flow-host-3vw7LzzD.cjs.map +1 -0
- package/dist/{inline-flow-host-C3H2UpSA.js → inline-flow-host-C0rI9B7f.js} +5 -5
- package/dist/inline-flow-host-C0rI9B7f.js.map +1 -0
- package/dist/label-66W1qbke.js.map +1 -1
- package/dist/label-w6JYf2cF.cjs.map +1 -1
- package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs +153 -0
- package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs.map +1 -0
- package/dist/lazy-relation-picker-dialog-CAScLPb2.js +135 -0
- package/dist/lazy-relation-picker-dialog-CAScLPb2.js.map +1 -0
- package/dist/markdown/index.d.cts +2 -3
- package/dist/markdown/index.d.ts +2 -3
- package/dist/{page-flow-route-CyXSvXSE.js → page-flow-route-BHUEpn0I.js} +36 -23
- package/dist/page-flow-route-BHUEpn0I.js.map +1 -0
- package/dist/{page-flow-route-CQ7HsbBm.cjs → page-flow-route-DS8IVTVH.cjs} +41 -28
- package/dist/page-flow-route-DS8IVTVH.cjs.map +1 -0
- package/dist/{place-node-SIp4XYQH.cjs → place-node-CNb3w-c7.cjs} +2227 -999
- package/dist/place-node-CNb3w-c7.cjs.map +1 -0
- package/dist/{place-node--GdsP688.js → place-node-CfzQvh4Y.js} +2164 -984
- package/dist/place-node-CfzQvh4Y.js.map +1 -0
- package/dist/{related-list-cards-B6x9HQQp.js → related-list-cards-BIqqY69Y.js} +9 -4
- package/dist/{related-list-cards-B6x9HQQp.js.map → related-list-cards-BIqqY69Y.js.map} +1 -1
- package/dist/{related-list-cards-nxuODlIA.cjs → related-list-cards-CelMxl4q.cjs} +9 -4
- package/dist/{related-list-cards-nxuODlIA.cjs.map → related-list-cards-CelMxl4q.cjs.map} +1 -1
- package/dist/{related-list-timeline-DEdfd-rr.js → related-list-timeline-CRh7xwLD.js} +6 -7
- package/dist/related-list-timeline-CRh7xwLD.js.map +1 -0
- package/dist/{related-list-timeline-BYJKEbmA.cjs → related-list-timeline-DsLdi8sv.cjs} +5 -6
- package/dist/related-list-timeline-DsLdi8sv.cjs.map +1 -0
- package/dist/{related-rows-B4levHcR.js → related-rows--uP2iKQC.js} +27 -17
- package/dist/related-rows--uP2iKQC.js.map +1 -0
- package/dist/{related-rows-zh5f_4QR.cjs → related-rows-MPnLCmPF.cjs} +32 -22
- package/dist/related-rows-MPnLCmPF.cjs.map +1 -0
- package/dist/{search-access-CURsWn-U.js → relation-create-C43cdPQt.js} +596 -29
- package/dist/relation-create-C43cdPQt.js.map +1 -0
- package/dist/{search-access-B7G5oR8n.cjs → relation-create-DDEYcKfw.cjs} +630 -32
- package/dist/relation-create-DDEYcKfw.cjs.map +1 -0
- package/dist/{relation-many-picker-gdAOD-qK.js → relation-many-picker-BJhaEqxz.js} +210 -107
- package/dist/relation-many-picker-BJhaEqxz.js.map +1 -0
- package/dist/{relation-many-picker-B-NCEUgX.cjs → relation-many-picker-DzuGJpEl.cjs} +218 -115
- package/dist/relation-many-picker-DzuGJpEl.cjs.map +1 -0
- package/dist/{relation-picker-BAY77ivO.js → relation-picker-D-tBBZW_.js} +40 -45
- package/dist/relation-picker-D-tBBZW_.js.map +1 -0
- package/dist/{relation-picker-Da_uhFvA.cjs → relation-picker-DaIMzf2H.cjs} +45 -50
- package/dist/relation-picker-DaIMzf2H.cjs.map +1 -0
- package/dist/{relation-picker-dialog-M0pQaWlp.cjs → relation-picker-dialog-9Vg5vvR1.cjs} +142 -40
- package/dist/relation-picker-dialog-9Vg5vvR1.cjs.map +1 -0
- package/dist/{relation-picker-dialog-hA9rYrZB.js → relation-picker-dialog-DoEY8EkH.js} +143 -41
- package/dist/relation-picker-dialog-DoEY8EkH.js.map +1 -0
- package/dist/relation-select-B8Fq4o-t.js +48 -0
- package/dist/relation-select-B8Fq4o-t.js.map +1 -0
- package/dist/relation-select-Cr3CfNLy.cjs +55 -0
- package/dist/relation-select-Cr3CfNLy.cjs.map +1 -0
- package/dist/{resource-page-router-OSQyRA5b.cjs → resource-page-router-C_kGW2o_.cjs} +552 -303
- package/dist/resource-page-router-C_kGW2o_.cjs.map +1 -0
- package/dist/{resource-page-router-T4vS5gbJ.js → resource-page-router-Diw6S6TK.js} +507 -258
- package/dist/resource-page-router-Diw6S6TK.js.map +1 -0
- package/dist/{rich-text-vTyVjDoa.cjs → rich-text-C_7JCvRo.cjs} +2 -2
- package/dist/{rich-text-vTyVjDoa.cjs.map → rich-text-C_7JCvRo.cjs.map} +1 -1
- package/dist/{rich-text-DFerywgz.js → rich-text-RcPBf6hr.js} +2 -2
- package/dist/{rich-text-DFerywgz.js.map → rich-text-RcPBf6hr.js.map} +1 -1
- package/dist/success-notices-Dl3M1fZP.cjs +46 -0
- package/dist/success-notices-Dl3M1fZP.cjs.map +1 -0
- package/dist/success-notices-LDEgEkc4.js +41 -0
- package/dist/success-notices-LDEgEkc4.js.map +1 -0
- package/dist/{toaster-C7CiYA4Z.cjs → toaster-BbByOytP.cjs} +72 -80
- package/dist/toaster-BbByOytP.cjs.map +1 -0
- package/dist/{toaster-CfCRLgR-.js → toaster-Ct_YHGs6.js} +66 -68
- package/dist/toaster-Ct_YHGs6.js.map +1 -0
- package/dist/{use-dialog-filter-state-BDcgS5Oz.js → use-dialog-filter-state-B_MqzHaT.js} +5 -4
- package/dist/use-dialog-filter-state-B_MqzHaT.js.map +1 -0
- package/dist/{use-dialog-filter-state-BBCC0OEK.cjs → use-dialog-filter-state-tNvqAAjh.cjs} +6 -5
- package/dist/use-dialog-filter-state-tNvqAAjh.cjs.map +1 -0
- package/dist/use-theme-DFlpXils.cjs.map +1 -1
- package/dist/use-theme-dnE3Od3I.js.map +1 -1
- package/package.json +11 -11
- package/dist/bulk-summary-CwSd6Yjb.cjs +0 -108
- package/dist/bulk-summary-CwSd6Yjb.cjs.map +0 -1
- package/dist/bulk-summary-GxMDP4bw.js +0 -108
- package/dist/bulk-summary-GxMDP4bw.js.map +0 -1
- package/dist/candidates-gate-CX2PBu6l.js +0 -63
- package/dist/candidates-gate-CX2PBu6l.js.map +0 -1
- package/dist/candidates-gate-DiFI52r7.cjs +0 -70
- package/dist/candidates-gate-DiFI52r7.cjs.map +0 -1
- package/dist/candidates-relation-picker-CBsVcnPR.js +0 -82
- package/dist/candidates-relation-picker-CBsVcnPR.js.map +0 -1
- package/dist/candidates-relation-picker-Dd_GVLlu.cjs +0 -84
- package/dist/candidates-relation-picker-Dd_GVLlu.cjs.map +0 -1
- package/dist/check-confirm-dialog-BRByTFpg.cjs.map +0 -1
- package/dist/check-confirm-dialog-CkaVTPT9.js.map +0 -1
- package/dist/dialog-B_rt9S1c.js.map +0 -1
- package/dist/dialog-DRNUq9EA.cjs.map +0 -1
- package/dist/filter-builder-B3mZFL-K.cjs.map +0 -1
- package/dist/filter-builder-DOnaXNfP.js.map +0 -1
- package/dist/flow-runtime-B6zOHYqI.cjs.map +0 -1
- package/dist/flow-runtime-D8h99FSg.js.map +0 -1
- package/dist/flow-screen-CX05b3G9.cjs.map +0 -1
- package/dist/flow-screen-CmbARSqg.js.map +0 -1
- package/dist/inline-flow-host-B7U1OJUe.cjs.map +0 -1
- package/dist/inline-flow-host-C3H2UpSA.js.map +0 -1
- package/dist/lazy-relation-picker-dialog-2oxnA6IR.js +0 -14
- package/dist/lazy-relation-picker-dialog-2oxnA6IR.js.map +0 -1
- package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs +0 -19
- package/dist/lazy-relation-picker-dialog-BfAGKzUG.cjs.map +0 -1
- package/dist/page-flow-route-CQ7HsbBm.cjs.map +0 -1
- package/dist/page-flow-route-CyXSvXSE.js.map +0 -1
- package/dist/peek-filter-CnqHwTMU.cjs +0 -51
- package/dist/peek-filter-CnqHwTMU.cjs.map +0 -1
- package/dist/peek-filter-ErLfO153.js +0 -28
- package/dist/peek-filter-ErLfO153.js.map +0 -1
- package/dist/place-node--GdsP688.js.map +0 -1
- package/dist/place-node-SIp4XYQH.cjs.map +0 -1
- package/dist/related-list-timeline-BYJKEbmA.cjs.map +0 -1
- package/dist/related-list-timeline-DEdfd-rr.js.map +0 -1
- package/dist/related-rows-B4levHcR.js.map +0 -1
- package/dist/related-rows-zh5f_4QR.cjs.map +0 -1
- package/dist/relation-create-BOaUe12G.cjs +0 -362
- package/dist/relation-create-BOaUe12G.cjs.map +0 -1
- package/dist/relation-create-Bg-eEJLs.js +0 -337
- package/dist/relation-create-Bg-eEJLs.js.map +0 -1
- package/dist/relation-many-picker-B-NCEUgX.cjs.map +0 -1
- package/dist/relation-many-picker-gdAOD-qK.js.map +0 -1
- package/dist/relation-picker-BAY77ivO.js.map +0 -1
- package/dist/relation-picker-Da_uhFvA.cjs.map +0 -1
- package/dist/relation-picker-dialog-M0pQaWlp.cjs.map +0 -1
- package/dist/relation-picker-dialog-hA9rYrZB.js.map +0 -1
- package/dist/resource-page-router-OSQyRA5b.cjs.map +0 -1
- package/dist/resource-page-router-T4vS5gbJ.js.map +0 -1
- package/dist/search-access-B7G5oR8n.cjs.map +0 -1
- package/dist/search-access-CURsWn-U.js.map +0 -1
- package/dist/shell-BPlk8hEa.js +0 -205
- package/dist/shell-BPlk8hEa.js.map +0 -1
- package/dist/shell-DxhlsPwm.cjs +0 -271
- package/dist/shell-DxhlsPwm.cjs.map +0 -1
- package/dist/toaster-C7CiYA4Z.cjs.map +0 -1
- package/dist/toaster-CfCRLgR-.js.map +0 -1
- package/dist/use-dialog-filter-state-BBCC0OEK.cjs.map +0 -1
- package/dist/use-dialog-filter-state-BDcgS5Oz.js.map +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as OwnTitleHeading, N as OwnTitleContext, _ as reasonText, dt as DocInfo, j as useFocusOnMount } from "./check-confirm-dialog-2j0gOd7x.js";
|
|
2
2
|
import { t as Button } from "./button-MWVeZaqj.js";
|
|
3
|
-
import { n as
|
|
4
|
-
import {
|
|
5
|
-
import { fieldSensitivity, humanizeKey, validatePlacementProps } from "@burojs/core";
|
|
6
|
-
import { ScreenStateProvider, resolveValidationMessage, useDismissPending, useFlowFormCatalog, useFlowOpenImplementation, useFormController, useI18nCaps, useOptionalT, useProjectedTitle, useTestIds, useUIInstance, useUIPresentationRuntime } from "@burojs/react";
|
|
3
|
+
import { H as ScreenTree, J as FormControlProvider, Pt as FieldDisplay, X as useFormControlOf, n as viewOf, t as selectImplementation } from "./place-node-CfzQvh4Y.js";
|
|
4
|
+
import { t as useNoticeSink } from "./success-notices-LDEgEkc4.js";
|
|
5
|
+
import { declaredText, fieldSensitivity, flowRecordOf, humanizeKey, textsValueAt, validatePlacementProps } from "@burojs/core";
|
|
6
|
+
import { BulkSelectionScope, REJECTED_KEYS, ScreenStateProvider, resolveValidationMessage, specificErrorText, useChromeT, useDismissPending, useFlowFormCatalog, useFlowOpenImplementation, useFormController, useI18nCaps, useOptionalT, useProjectedTitle, useTestIds, useUIInstance, useUIPresentationRuntime } from "@burojs/react";
|
|
7
7
|
import { IconLoader2, IconX } from "@tabler/icons-react";
|
|
8
8
|
import { Suspense, createContext, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
11
11
|
import { fieldEntriesToMap } from "@burojs/core/internal";
|
|
12
|
-
import { useFlowForm, useFlowRun } from "@burojs/react/flows";
|
|
12
|
+
import { FlowTextsScope, useFlowForm, useFlowMetaSources, useFlowRun } from "@burojs/react/flows";
|
|
13
13
|
//#region src/flows/review-diff.tsx
|
|
14
14
|
const REVIEW_DIFF_BLOCK = "buro:review-diff";
|
|
15
15
|
function sensitive(definition) {
|
|
@@ -30,11 +30,7 @@ const same = (a, b) => {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
function ReviewDiff({ form, initial, values, i18nPrefix, testid }) {
|
|
33
|
-
const
|
|
34
|
-
const changedText = (() => {
|
|
35
|
-
const value = t("review.changed");
|
|
36
|
-
return value === "review.changed" ? "changed" : value;
|
|
37
|
-
})();
|
|
33
|
+
const changedText = useOptionalT()("review.changed", { defaultValue: "changed" });
|
|
38
34
|
const rows = form.fields.filter((binding) => !same(initial[binding.name], values[binding.name]));
|
|
39
35
|
return jsx("dl", {
|
|
40
36
|
"data-testid": `${testid}:review`,
|
|
@@ -118,32 +114,43 @@ function OverlayBinding({ children }) {
|
|
|
118
114
|
function WithBinding({ children }) {
|
|
119
115
|
return useContext(FlowHostBindingContext) !== null ? jsx(Fragment$1, { children }) : jsx(OverlayBinding, { children });
|
|
120
116
|
}
|
|
121
|
-
function
|
|
122
|
-
|
|
123
|
-
return value === key ? fallback : value;
|
|
124
|
-
}
|
|
125
|
-
const REJECTED_KEYS = {
|
|
126
|
-
validation: "validation",
|
|
127
|
-
conflict: "conflict",
|
|
128
|
-
forbidden: "forbidden",
|
|
129
|
-
"not-found": "notFound"
|
|
130
|
-
};
|
|
131
|
-
function outcomeMessage(snapshot, busy, t) {
|
|
132
|
-
if (busy) return text(t, "flow.busyElsewhere", "This action is running in another tab.");
|
|
117
|
+
function outcomeMessage(snapshot, busy, t, caps, textPrefix, flow, reasonOf) {
|
|
118
|
+
if (busy) return t("flow.busyElsewhere", { defaultValue: "This action is running in another tab." });
|
|
133
119
|
const outcome = snapshot.outcome;
|
|
134
120
|
if (outcome === void 0 || outcome.outcome === "success") {
|
|
135
|
-
if (snapshot.control === "disabled" && snapshot.reason !== void 0) return snapshot.reason;
|
|
121
|
+
if (snapshot.control === "disabled" && snapshot.reason !== void 0) return reasonOf(snapshot.reason);
|
|
136
122
|
return null;
|
|
137
123
|
}
|
|
138
|
-
if (outcome.outcome === "unknown") return [
|
|
124
|
+
if (outcome.outcome === "unknown") return [outcome.applied === "partial" ? t("flow.unknownPartial", { defaultValue: "Part of this may have been applied. Nothing was resent." }) : t("flow.unknown", { defaultValue: "It may have been applied. Nothing was resent." }), ...snapshot.reason === void 0 ? [] : [reasonOf(snapshot.reason)]].join(" ");
|
|
139
125
|
if (outcome.outcome === "rejected") {
|
|
140
|
-
if (snapshot.reason !== void 0) return snapshot.reason;
|
|
141
|
-
const kind = "
|
|
126
|
+
if (snapshot.reason !== void 0) return reasonOf(snapshot.reason);
|
|
127
|
+
const kind = "kind" in outcome ? outcome.kind : void 0;
|
|
128
|
+
const code = "code" in outcome ? outcome.code : void 0;
|
|
129
|
+
if (code !== void 0) {
|
|
130
|
+
const specific = specificErrorText({
|
|
131
|
+
code,
|
|
132
|
+
..."message" in outcome && outcome.message !== void 0 ? { message: outcome.message } : {}
|
|
133
|
+
}, caps, { action: {
|
|
134
|
+
prefix: textPrefix,
|
|
135
|
+
texts: flow?.texts
|
|
136
|
+
} });
|
|
137
|
+
if (specific !== void 0) return specific;
|
|
138
|
+
}
|
|
142
139
|
const key = kind === void 0 ? void 0 : REJECTED_KEYS[kind];
|
|
143
|
-
if (key !== void 0) return
|
|
144
|
-
return
|
|
140
|
+
if (key !== void 0) return t(`${textPrefix}.rejected.${key}`, { defaultValue: textsValueAt(flow?.texts, ["rejected", key]) ?? t(`flow.rejected.${key}`, { defaultValue: "Nothing was saved." }) });
|
|
141
|
+
return t("flow.rejected.precondition", { defaultValue: "The record changed. Nothing was sent." });
|
|
142
|
+
}
|
|
143
|
+
if (outcome.outcome === "failed") {
|
|
144
|
+
if (snapshot.reason !== void 0) return reasonOf(snapshot.reason);
|
|
145
|
+
const code = "code" in outcome ? outcome.code : void 0;
|
|
146
|
+
return (code === void 0 ? void 0 : specificErrorText({
|
|
147
|
+
code,
|
|
148
|
+
..."message" in outcome && outcome.message !== void 0 ? { message: outcome.message } : {}
|
|
149
|
+
}, caps, { action: {
|
|
150
|
+
prefix: textPrefix,
|
|
151
|
+
texts: flow?.texts
|
|
152
|
+
} })) ?? t("flow.failed", { defaultValue: "The request could not be sent. Nothing was saved." });
|
|
145
153
|
}
|
|
146
|
-
if (outcome.outcome === "failed") return snapshot.reason ?? text(t, "flow.failed", "The request could not be sent. Nothing was saved.");
|
|
147
154
|
return null;
|
|
148
155
|
}
|
|
149
156
|
function FlowScreen(props) {
|
|
@@ -158,12 +165,27 @@ function FlowScreen(props) {
|
|
|
158
165
|
});
|
|
159
166
|
return null;
|
|
160
167
|
}
|
|
168
|
+
function SelectionScope(props) {
|
|
169
|
+
if (props.selection === void 0 || props.resource === null) return jsx(Fragment$1, { children: props.children });
|
|
170
|
+
return jsx(BulkSelectionScope, {
|
|
171
|
+
resource: props.resource,
|
|
172
|
+
ids: props.selection.ids,
|
|
173
|
+
children: props.children
|
|
174
|
+
});
|
|
175
|
+
}
|
|
161
176
|
function HeldFlowScreen(props) {
|
|
162
177
|
const [generation, setGeneration] = useState(0);
|
|
163
|
-
return jsx(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
178
|
+
return jsx(FlowTextsScope, {
|
|
179
|
+
compiled: props.compiled,
|
|
180
|
+
children: jsx(WithBinding, { children: jsx(ScreenStateProvider, { children: jsx(SelectionScope, {
|
|
181
|
+
selection: props.selection,
|
|
182
|
+
resource: props.compiled.resource,
|
|
183
|
+
children: jsx(FlowScreenBody, {
|
|
184
|
+
...props,
|
|
185
|
+
onFreshForm: () => setGeneration((value) => value + 1)
|
|
186
|
+
})
|
|
187
|
+
}) }, generation) })
|
|
188
|
+
});
|
|
167
189
|
}
|
|
168
190
|
function OwnedFlowScreen(props) {
|
|
169
191
|
const { start, effects, onSettle } = props;
|
|
@@ -190,6 +212,7 @@ function OwnedFlowScreen(props) {
|
|
|
190
212
|
}, [outcome, onSettle]);
|
|
191
213
|
const instance = useUIInstance();
|
|
192
214
|
const t = useOptionalT();
|
|
215
|
+
const caps = useI18nCaps(compiled?.resource ?? void 0);
|
|
193
216
|
const tid = useTestIds();
|
|
194
217
|
if (run !== null && compiled !== null && (snapshot.history.includes("open") || snapshot.step === "outcome")) return jsx(HeldFlowScreen, {
|
|
195
218
|
...props,
|
|
@@ -208,7 +231,7 @@ function OwnedFlowScreen(props) {
|
|
|
208
231
|
refused ? jsx("p", {
|
|
209
232
|
role: "alert",
|
|
210
233
|
className: "text-sm",
|
|
211
|
-
children: snapshot.reason
|
|
234
|
+
children: snapshot.reason === void 0 ? t("flow.unavailable", { defaultValue: "Not allowed." }) : reasonText(caps, snapshot.reason, compiled?.resource ?? void 0)
|
|
212
235
|
}) : jsx(IconLoader2, {
|
|
213
236
|
className: "h-5 w-5 animate-spin self-center",
|
|
214
237
|
"aria-hidden": "true"
|
|
@@ -219,30 +242,19 @@ function OwnedFlowScreen(props) {
|
|
|
219
242
|
type: "button",
|
|
220
243
|
variant: "ghost",
|
|
221
244
|
onClick: () => instance.dismiss(),
|
|
222
|
-
children:
|
|
245
|
+
children: t("flow.close", { defaultValue: "Close" })
|
|
223
246
|
})
|
|
224
247
|
})
|
|
225
248
|
]
|
|
226
249
|
});
|
|
227
250
|
}
|
|
228
|
-
function
|
|
229
|
-
const
|
|
230
|
-
const heading = jsx("h2", {
|
|
231
|
-
tabIndex: -1,
|
|
232
|
-
"data-buro-overlay-heading": "",
|
|
233
|
-
className: "text-lg font-semibold",
|
|
234
|
-
children: label
|
|
235
|
-
});
|
|
236
|
-
return ownTitle ? jsx(DialogPrimitive.Title, {
|
|
237
|
-
asChild: true,
|
|
238
|
-
children: heading
|
|
239
|
-
}) : heading;
|
|
240
|
-
}
|
|
241
|
-
function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record, args, selection, onFreshForm }) {
|
|
251
|
+
function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record: givenRecord, args, selection, onFreshForm }) {
|
|
252
|
+
const record = flowRecordOf(compiled, givenRecord);
|
|
242
253
|
const snapshot = useSyncSnapshot(run);
|
|
243
254
|
const binding = useContext(FlowHostBindingContext);
|
|
244
255
|
const tid = useTestIds();
|
|
245
256
|
const t = useOptionalT();
|
|
257
|
+
const chromeT = useChromeT();
|
|
246
258
|
const resource = compiled.resource ?? void 0;
|
|
247
259
|
const caps = useI18nCaps(resource);
|
|
248
260
|
const ownTitle = useContext(OwnTitleContext);
|
|
@@ -255,6 +267,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
255
267
|
...args === void 0 ? {} : { args },
|
|
256
268
|
...selection === void 0 ? {} : { selection: selection.ids }
|
|
257
269
|
});
|
|
270
|
+
const formControl = useFormControlOf(form);
|
|
258
271
|
const hasForm = compiled.flow.form !== void 0;
|
|
259
272
|
const [busy, setBusy] = useState(false);
|
|
260
273
|
const [initial] = useState(() => run.getSnapshot().values);
|
|
@@ -266,6 +279,17 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
266
279
|
const succeeded = outcome === "success";
|
|
267
280
|
const finalStep = snapshot.step === "review" || snapshot.step === "accept";
|
|
268
281
|
const openBlock = succeeded ? blockOpen(snapshot.effects?.open) : null;
|
|
282
|
+
const showNotices = useNoticeSink(resource);
|
|
283
|
+
const shownNotices = useRef(null);
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
if (!succeeded || snapshot.notices.length === 0 || shownNotices.current === snapshot.notices) return;
|
|
286
|
+
shownNotices.current = snapshot.notices;
|
|
287
|
+
showNotices(snapshot.notices);
|
|
288
|
+
}, [
|
|
289
|
+
succeeded,
|
|
290
|
+
snapshot.notices,
|
|
291
|
+
showNotices
|
|
292
|
+
]);
|
|
269
293
|
useEffect(() => {
|
|
270
294
|
if (succeeded && !locked && openBlock === null) binding.finish();
|
|
271
295
|
}, [
|
|
@@ -307,8 +331,18 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
307
331
|
};
|
|
308
332
|
const pendingKey = compiled.resource === null ? `appActions.${compiled.name}.pending` : `resources.${compiled.resource}.actions.${compiled.name}.pending`;
|
|
309
333
|
const pendingLabel = caps.has(pendingKey) ? caps.t(pendingKey) : `${label}…`;
|
|
310
|
-
const message = outcomeMessage(snapshot, busy, t);
|
|
311
|
-
const
|
|
334
|
+
const message = outcomeMessage(snapshot, busy, t, caps, compiled.textKeys.prefix, compiled.flow, (reason) => reasonText(caps, reason, resource));
|
|
335
|
+
const formErrorTexts = formErrors.map((issue) => resolveValidationMessage({
|
|
336
|
+
code: issue.code ?? "",
|
|
337
|
+
message: issue.message,
|
|
338
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
339
|
+
}, {
|
|
340
|
+
has: caps.has,
|
|
341
|
+
t: caps.t
|
|
342
|
+
})).filter((text) => text !== message);
|
|
343
|
+
const dismissKey = `${compiled.textKeys.prefix}.dismiss`;
|
|
344
|
+
const cancelWord = (caps.has(dismissKey) ? caps.t(dismissKey) : void 0) ?? declaredText("flow", compiled.flow, "dismiss") ?? chromeT("actions.cancel", { defaultValue: "Cancel" });
|
|
345
|
+
const couldNotCheck = snapshot.control === "disabled" && snapshot.unverified === true;
|
|
312
346
|
const steps = form.steps;
|
|
313
347
|
const lastStep = steps === null || steps.ids.length === 0 || steps.current === steps.ids[steps.ids.length - 1];
|
|
314
348
|
const showSubmit = !unknown && !succeeded && (!hasForm || finalStep || lastStep);
|
|
@@ -323,7 +357,10 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
323
357
|
if (binding.kind === "inline" && hasForm && !unknown) form.draft.discard();
|
|
324
358
|
binding.close();
|
|
325
359
|
};
|
|
360
|
+
const headingRef = useRef(null);
|
|
361
|
+
useFocusOnMount(headingRef);
|
|
326
362
|
const heading = jsxs("h2", {
|
|
363
|
+
ref: headingRef,
|
|
327
364
|
tabIndex: -1,
|
|
328
365
|
"data-buro-overlay-heading": "",
|
|
329
366
|
className: "min-w-0 flex-1 break-words text-lg font-semibold tracking-tight focus-visible:outline-hidden",
|
|
@@ -358,7 +395,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
358
395
|
size: "icon",
|
|
359
396
|
className: "h-8 w-8 shrink-0",
|
|
360
397
|
"data-testid": tid.flowClose(flowId),
|
|
361
|
-
"aria-label":
|
|
398
|
+
"aria-label": t("flow.close", { defaultValue: "Close" }),
|
|
362
399
|
onClick: close,
|
|
363
400
|
children: jsx(IconX, {
|
|
364
401
|
className: "h-4 w-4",
|
|
@@ -379,7 +416,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
379
416
|
variant: "outline",
|
|
380
417
|
"data-testid": tid.flowClose(flowId),
|
|
381
418
|
onClick: close,
|
|
382
|
-
children:
|
|
419
|
+
children: t("flow.done", { defaultValue: "Done" })
|
|
383
420
|
})
|
|
384
421
|
}) : null,
|
|
385
422
|
jsxs("form", {
|
|
@@ -405,7 +442,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
405
442
|
variant: "outline",
|
|
406
443
|
className: "ml-auto",
|
|
407
444
|
onClick: () => run.retryChecks(),
|
|
408
|
-
children:
|
|
445
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
409
446
|
}) : null]
|
|
410
447
|
}),
|
|
411
448
|
hasForm && form.draft.pending !== null && (!unknown || editingNew) ? jsxs("div", {
|
|
@@ -415,7 +452,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
415
452
|
className: "flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm",
|
|
416
453
|
children: [jsx("span", {
|
|
417
454
|
className: "font-medium",
|
|
418
|
-
children:
|
|
455
|
+
children: t("draft.restorePrompt", { defaultValue: "Restore draft?" })
|
|
419
456
|
}), jsxs("div", {
|
|
420
457
|
className: "ml-auto flex gap-2",
|
|
421
458
|
children: [jsx(Button, {
|
|
@@ -424,26 +461,22 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
424
461
|
variant: "outline",
|
|
425
462
|
"data-testid": `${tid.flowDraft(flowId)}:restore`,
|
|
426
463
|
onClick: form.draft.restore,
|
|
427
|
-
children:
|
|
464
|
+
children: t("draft.restore", { defaultValue: "Restore" })
|
|
428
465
|
}), jsx(Button, {
|
|
429
466
|
type: "button",
|
|
430
467
|
size: "sm",
|
|
431
468
|
variant: "ghost",
|
|
432
469
|
"data-testid": `${tid.flowDraft(flowId)}:discard`,
|
|
433
470
|
onClick: form.draft.discard,
|
|
434
|
-
children:
|
|
471
|
+
children: t("draft.discard", { defaultValue: "Discard" })
|
|
435
472
|
})]
|
|
436
473
|
})]
|
|
437
474
|
}) : null,
|
|
438
|
-
|
|
475
|
+
formErrorTexts.length > 0 ? jsx("div", {
|
|
439
476
|
role: "alert",
|
|
440
477
|
"data-testid": `${tid.flowHost(flowId)}:form-errors`,
|
|
441
478
|
className: "flex flex-col gap-1 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
442
|
-
children:
|
|
443
|
-
code: issue.code ?? "",
|
|
444
|
-
message: issue.message,
|
|
445
|
-
...issue.params === void 0 ? {} : { params: issue.params }
|
|
446
|
-
}, { t }) }, index))
|
|
479
|
+
children: formErrorTexts.map((text, index) => jsx("p", { children: text }, index))
|
|
447
480
|
}) : null,
|
|
448
481
|
finalStep && compiled.flow.review === true ? jsx(ReviewDiff, {
|
|
449
482
|
form,
|
|
@@ -455,15 +488,21 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
455
488
|
compiled,
|
|
456
489
|
tree: compiled.flow.review,
|
|
457
490
|
values: snapshot.values,
|
|
458
|
-
prefix
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
491
|
+
prefix,
|
|
492
|
+
run,
|
|
493
|
+
...record === void 0 ? {} : { record },
|
|
494
|
+
...args === void 0 ? {} : { args }
|
|
495
|
+
}) : hasForm ? jsx(FormControlProvider, {
|
|
496
|
+
value: formControl,
|
|
497
|
+
children: jsx(ScreenTree, {
|
|
498
|
+
region: "form-body",
|
|
499
|
+
resource: prefix,
|
|
500
|
+
mode: "create",
|
|
501
|
+
compiled: form.screen,
|
|
502
|
+
controller: form,
|
|
503
|
+
leafIds: "record",
|
|
504
|
+
disabled: locked || unknown && !editingNew || finalStep || succeeded
|
|
505
|
+
})
|
|
467
506
|
}) : null,
|
|
468
507
|
finalStep && snapshot.warnings.length > 0 ? jsx("ul", {
|
|
469
508
|
role: "status",
|
|
@@ -479,14 +518,14 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
479
518
|
unhandled ? jsx("p", {
|
|
480
519
|
"data-testid": `${tid.flowOutcome(flowId)}:unhandled`,
|
|
481
520
|
className: "text-sm",
|
|
482
|
-
children:
|
|
521
|
+
children: t("flow.unknownUnhandled", { defaultValue: "Check the record before trying again." })
|
|
483
522
|
}) : null,
|
|
484
523
|
unknown && confirmingNew ? jsxs("div", {
|
|
485
524
|
role: "alertdialog",
|
|
486
|
-
"aria-label":
|
|
525
|
+
"aria-label": t("flow.sendAsNew", { defaultValue: "Send as new" }),
|
|
487
526
|
"data-testid": `${tid.flowSendAsNew(flowId)}:confirm`,
|
|
488
527
|
className: "flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm",
|
|
489
|
-
children: [jsx("span", { children:
|
|
528
|
+
children: [jsx("span", { children: t("flow.sendAsNewConfirm", { defaultValue: "This may apply the change twice. Send it as a new request?" }) }), jsxs("div", {
|
|
490
529
|
className: "ml-auto flex gap-2",
|
|
491
530
|
children: [jsx(Button, {
|
|
492
531
|
type: "button",
|
|
@@ -494,7 +533,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
494
533
|
variant: "ghost",
|
|
495
534
|
"data-testid": `${tid.flowSendAsNew(flowId)}:cancel`,
|
|
496
535
|
onClick: () => setConfirmingNew(false),
|
|
497
|
-
children:
|
|
536
|
+
children: cancelWord
|
|
498
537
|
}), jsx(Button, {
|
|
499
538
|
type: "button",
|
|
500
539
|
size: "sm",
|
|
@@ -504,7 +543,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
504
543
|
setConfirmingNew(false);
|
|
505
544
|
exit(() => run.sendAsNew({ confirmed: true }))();
|
|
506
545
|
},
|
|
507
|
-
children:
|
|
546
|
+
children: t("flow.sendAsNew", { defaultValue: "Send as new" })
|
|
508
547
|
})]
|
|
509
548
|
})]
|
|
510
549
|
}) : null,
|
|
@@ -518,7 +557,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
518
557
|
"data-testid": tid.flowCheckAgain(flowId),
|
|
519
558
|
disabled: locked,
|
|
520
559
|
onClick: exit(() => run.checkAgain()),
|
|
521
|
-
children:
|
|
560
|
+
children: t("flow.checkAgain", { defaultValue: "Check again" })
|
|
522
561
|
}) : null,
|
|
523
562
|
snapshot.canResend ? jsx(Button, {
|
|
524
563
|
type: "button",
|
|
@@ -526,7 +565,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
526
565
|
"data-testid": tid.flowResend(flowId),
|
|
527
566
|
disabled: locked,
|
|
528
567
|
onClick: exit(() => run.resend()),
|
|
529
|
-
children:
|
|
568
|
+
children: t("flow.resend", { defaultValue: "Resend" })
|
|
530
569
|
}) : null,
|
|
531
570
|
jsx(Button, {
|
|
532
571
|
type: "button",
|
|
@@ -537,7 +576,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
537
576
|
if (hasForm) setEditingNew(true);
|
|
538
577
|
else setConfirmingNew(true);
|
|
539
578
|
},
|
|
540
|
-
children:
|
|
579
|
+
children: t("flow.sendAsNew", { defaultValue: "Send as new" })
|
|
541
580
|
}),
|
|
542
581
|
jsx(Button, {
|
|
543
582
|
type: "button",
|
|
@@ -548,7 +587,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
548
587
|
run.startOver();
|
|
549
588
|
onFreshForm();
|
|
550
589
|
},
|
|
551
|
-
children:
|
|
590
|
+
children: t("flow.startOver", { defaultValue: "I've checked — start over" })
|
|
552
591
|
})
|
|
553
592
|
]
|
|
554
593
|
}) : null,
|
|
@@ -560,7 +599,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
560
599
|
variant: "outline",
|
|
561
600
|
"data-testid": tid.flowBack(flowId),
|
|
562
601
|
onClick: () => run.back(),
|
|
563
|
-
children:
|
|
602
|
+
children: t("flow.back", { defaultValue: "Back" })
|
|
564
603
|
}) : null, jsxs("div", {
|
|
565
604
|
className: "ml-auto flex gap-2",
|
|
566
605
|
children: [
|
|
@@ -570,7 +609,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
570
609
|
"data-testid": tid.flowCancel(flowId),
|
|
571
610
|
disabled: locked,
|
|
572
611
|
onClick: close,
|
|
573
|
-
children: unknown ?
|
|
612
|
+
children: unknown ? t("flow.close", { defaultValue: "Close" }) : binding.kind === "inline" ? t("flow.reset", { defaultValue: "Reset" }) : cancelWord
|
|
574
613
|
}),
|
|
575
614
|
unknown && editingNew ? jsx(Button, {
|
|
576
615
|
type: "submit",
|
|
@@ -578,7 +617,7 @@ function FlowScreenBody({ run, host, label, title: givenTitle, compiled, record,
|
|
|
578
617
|
"data-testid": `${tid.flowSendAsNew(flowId)}:submit`,
|
|
579
618
|
disabled: locked || confirmingNew,
|
|
580
619
|
onMouseDown: (event) => event.preventDefault(),
|
|
581
|
-
children:
|
|
620
|
+
children: t("flow.sendAsNew", { defaultValue: "Send as new" })
|
|
582
621
|
}) : null,
|
|
583
622
|
showSubmit ? jsxs(Button, {
|
|
584
623
|
type: "submit",
|
|
@@ -604,7 +643,7 @@ function useSyncSnapshot(run) {
|
|
|
604
643
|
return useSyncExternalStore(run.subscribe, run.getSnapshot, run.getSnapshot);
|
|
605
644
|
}
|
|
606
645
|
const NO_FIELDS = Object.freeze({});
|
|
607
|
-
function ReviewTree({ compiled, tree, values, prefix }) {
|
|
646
|
+
function ReviewTree({ compiled, tree, values, prefix, run, record, args }) {
|
|
608
647
|
const fields = compiled.flow.form?.fields;
|
|
609
648
|
const map = useState(() => {
|
|
610
649
|
if (fields === void 0) return NO_FIELDS;
|
|
@@ -616,8 +655,13 @@ function ReviewTree({ compiled, tree, values, prefix }) {
|
|
|
616
655
|
})[0];
|
|
617
656
|
const body = useState(() => () => tree)[0];
|
|
618
657
|
const blocks = useFlowFormCatalog();
|
|
658
|
+
const metaSources = useFlowMetaSources(record, args, compiled.resource);
|
|
619
659
|
const review = useFormController({
|
|
620
660
|
blocks,
|
|
661
|
+
flowRun: run,
|
|
662
|
+
formId: compiled.formId,
|
|
663
|
+
metaSources,
|
|
664
|
+
review: true,
|
|
621
665
|
fields: map,
|
|
622
666
|
body,
|
|
623
667
|
mode: "show",
|
|
@@ -681,7 +725,7 @@ function FlowOpenBlock({ open, testid }) {
|
|
|
681
725
|
children: failed ? jsx("p", {
|
|
682
726
|
role: "alert",
|
|
683
727
|
className: "text-sm text-muted-foreground",
|
|
684
|
-
children:
|
|
728
|
+
children: t("block.notImplemented", { defaultValue: "This section is not available." })
|
|
685
729
|
}) : View === null || validation?.status !== "ready" ? null : jsx(Suspense, {
|
|
686
730
|
fallback: null,
|
|
687
731
|
children: jsx(View, {
|
|
@@ -698,4 +742,4 @@ function FlowOpenBlock({ open, testid }) {
|
|
|
698
742
|
//#endregion
|
|
699
743
|
export { FlowHostBindingContext, FlowScreen, HostedFlowScreen };
|
|
700
744
|
|
|
701
|
-
//# sourceMappingURL=flow-screen-
|
|
745
|
+
//# sourceMappingURL=flow-screen-DCdli6Ha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-screen-DCdli6Ha.js","names":[],"sources":["../src/flows/review-diff.tsx","../src/flows/flow-screen.tsx"],"sourcesContent":["'use client';\nimport { fieldSensitivity, humanizeKey, type Row } from '@burojs/core';\nimport { type FormController, useOptionalT } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport { FieldDisplay } from '../forms/field.js';\n\n/** The built-in review block of a flow (`review: true`, P4 spec 4.4). */\nexport const REVIEW_DIFF_BLOCK = 'buro:review-diff';\n\nexport interface ReviewDiffProps {\n /** The flow's form: its active fields, their definitions and labels. */\n readonly form: FormController;\n /** The values the form opened on (`form.initial`): the baseline of the diff. */\n readonly initial: Row;\n /** The values as they will be submitted. */\n readonly values: Row;\n /** Text and doc keys of the form (`<resource>.actions.<name>`). */\n readonly i18nPrefix: string;\n /** The test id base (the flow's host). */\n readonly testid: string;\n}\n\n/** Whether a field is `sensitive` (a mark or a mask). */\nfunction sensitive(definition: unknown): boolean {\n if (fieldSensitivity(definition) !== undefined) return true;\n if (definition === null || typeof definition !== 'object') return false;\n const opts = (definition as { readonly opts?: unknown }).opts;\n const marked =\n opts !== null && typeof opts === 'object'\n ? (opts as { readonly sensitive?: unknown }).sensitive\n : undefined;\n return marked !== undefined && marked !== false && marked !== null;\n}\n\nconst same = (a: unknown, b: unknown): boolean => {\n if (Object.is(a, b)) return true;\n const empty = (value: unknown) => value === undefined || value === null || value === '';\n if (empty(a) && empty(b)) return true;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n};\n\n/**\n * The review of a flow (`review: true`, 4.4): one row per active form field whose value differs\n * from the one the form opened on — its label, the old display value and the new one. A\n * `sensitive` field says \"changed\" and shows no value, old or new.\n */\nexport function ReviewDiff({\n form,\n initial,\n values,\n i18nPrefix,\n testid,\n}: ReviewDiffProps): ReactElement {\n const t = useOptionalT();\n const changedText = t('review.changed', { defaultValue: 'changed' });\n const rows = form.fields.filter((binding) => !same(initial[binding.name], values[binding.name]));\n return (\n <dl data-testid={`${testid}:review`} data-buro-block={REVIEW_DIFF_BLOCK} className=\"grid gap-2\">\n {rows.map((binding) => {\n const definition = binding.field as unknown as { readonly label?: unknown };\n const label =\n typeof definition.label === 'string' ? definition.label : humanizeKey(binding.name);\n const hidden = sensitive(binding.field);\n return (\n <div\n key={binding.name}\n data-testid={`${testid}:review:${binding.name}`}\n className=\"grid grid-cols-[minmax(0,1fr)_minmax(0,2fr)] gap-2 text-sm\"\n >\n <dt className=\"font-medium\">{label}</dt>\n <dd className=\"flex flex-wrap items-center gap-2\">\n {hidden ? (\n <span className=\"text-muted-foreground\">{changedText}</span>\n ) : (\n <>\n <span data-buro-review=\"old\" className=\"text-muted-foreground line-through\">\n <FieldDisplay\n i18nPrefix={i18nPrefix}\n name={binding.name}\n field={binding.field as never}\n value={initial[binding.name]}\n fallback={<span>{display(initial[binding.name])}</span>}\n />\n </span>\n <span aria-hidden=\"true\">→</span>\n <span data-buro-review=\"new\">\n <FieldDisplay\n i18nPrefix={i18nPrefix}\n name={binding.name}\n field={binding.field as never}\n value={values[binding.name]}\n fallback={<span>{display(values[binding.name])}</span>}\n />\n </span>\n </>\n )}\n </dd>\n </div>\n );\n })}\n </dl>\n );\n}\n\nconst display = (value: unknown): string =>\n value === undefined || value === null || value === '' ? '—' : String(value);\n","'use client';\nimport {\n type CompiledFlow,\n type FlowResult,\n type FlowRun,\n declaredText,\n flowRecordOf,\n type FlowSnapshot,\n type PropValidation,\n textsValueAt,\n validatePlacementProps,\n} from '@burojs/core';\nimport {\n BulkSelectionScope,\n type ErrorTextCaps,\n REJECTED_KEYS,\n specificErrorText,\n type FlowScreenProps,\n type FlowStart,\n ScreenStateProvider,\n resolveValidationMessage,\n useFlowOpenImplementation,\n useDismissPending,\n useFlowFormCatalog,\n useFormController,\n useI18nCaps,\n useChromeT,\n useOptionalT,\n useProjectedTitle,\n useTestIds,\n useUIInstance,\n useUIPresentationRuntime,\n} from '@burojs/react';\nimport { fieldEntriesToMap } from '@burojs/core/internal';\nimport { FlowTextsScope, useFlowForm, useFlowMetaSources, useFlowRun } from '@burojs/react/flows';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { IconLoader2, IconX } from '@tabler/icons-react';\nimport {\n type ReactElement,\n type ReactNode,\n Suspense,\n createContext,\n useContext,\n useMemo,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { DocInfo } from '../doc/doc-info.js';\nimport { useNoticeSink } from '../forms/success-notices.js';\nimport { reasonText } from '../lib/reason-text.js';\nimport { Button } from '../primitives/button.js';\nimport { FormControlProvider, useFormControlOf } from '../resource/form-context.js';\nimport { ScreenTree } from '../screen/screen-tree.js';\nimport { selectImplementation, viewOf } from '../blocks/place-node.js';\nimport { ReviewDiff } from './review-diff.js';\nimport { OwnTitleContext } from '../ui-presentations/shell.js';\nimport { OwnTitleHeading, useFocusOnMount } from './overlay-heading.js';\n\n/**\n * Thrown from the form controller's write: the controller validated (and revealed the first\n * failing field), and the run — not the controller — sends. A write that throws leaves the form\n * dirty and its draft in place (the controller re-baselines only on a write that resolves), and\n * an abort-shaped value is no reportable failure.\n */\nconst HELD = Object.freeze({ name: 'AbortError', message: 'The flow run sends the values.' });\n\n/**\n * How the flow screen leaves its host (P6): an overlay dismisses its presentation instance, a\n * page navigates to the record through the guard, an inline placement shows the next form. The\n * screen asks `close()` for Cancel, ✕ and Back, and `finish()` once a success needs nothing more\n * shown (no `then.open: { block }`).\n * @internal\n */\nexport interface FlowHostBinding {\n readonly kind: 'overlay' | 'page' | 'inline';\n close(): void;\n finish(): void;\n}\n\n/** @internal Provided by the page and inline hosts; an overlay builds its own. */\n/** @internal */\nexport function HostedFlowScreen(\n props: FlowScreenProps & { readonly binding: FlowHostBinding },\n): ReactElement | null {\n const { binding, ...rest } = props;\n return (\n <FlowHostBindingContext.Provider value={binding}>\n <FlowScreen {...rest} />\n </FlowHostBindingContext.Provider>\n );\n}\n\nexport const FlowHostBindingContext = createContext<FlowHostBinding | null>(null);\n\n/** Gives the screen below it the overlay's binding: its presentation instance. */\nfunction OverlayBinding({ children }: { readonly children: ReactNode }): ReactElement {\n const instance = useUIInstance();\n const runtime = useUIPresentationRuntime();\n const binding = useMemo<FlowHostBinding>(\n () => ({\n kind: 'overlay',\n close: () => instance.dismiss(),\n finish: () => runtime.dismiss(instance.id),\n }),\n [instance, runtime],\n );\n return (\n <FlowHostBindingContext.Provider value={binding}>{children}</FlowHostBindingContext.Provider>\n );\n}\n\n/** The screen's binding when a page or inline host provided one, else the overlay's. */\nfunction WithBinding({ children }: { readonly children: ReactNode }): ReactElement {\n const provided = useContext(FlowHostBindingContext);\n return provided !== null ? <>{children}</> : <OverlayBinding>{children}</OverlayBinding>;\n}\n\ntype Translate = ReturnType<typeof useOptionalT>;\n\n/**\n * What the outcome area says, or `null` when the screen has nothing to report. A rejection reads\n * the specific text of its code first (spec 4.15 steps 1 to 4: the flow's `<textPrefix>.validation.<code>`\n * and declared `texts.validation`, the provider's reference, the shared code texts). Only when none\n * resolves does a mapped kind read the flow's own `<textPrefix>.rejected.<kind>`, then its declared\n * `texts.rejected.<kind>` (`flow`), before the framework's neutral `flow.rejected.<kind>`;\n * `textPrefix` is the compiled flow's `textKeys.prefix`.\n */\nfunction outcomeMessage(\n snapshot: FlowSnapshot,\n busy: boolean,\n t: Translate,\n caps: ErrorTextCaps,\n textPrefix: string,\n flow: { readonly texts?: unknown } | undefined,\n reasonOf: (reason: string) => string,\n): string | null {\n if (busy)\n return t('flow.busyElsewhere', { defaultValue: 'This action is running in another tab.' });\n const outcome = snapshot.outcome;\n if (outcome === undefined || outcome.outcome === 'success') {\n // A check that could not decide blocks the flow (4.3): its reason, with Retry.\n if (snapshot.control === 'disabled' && snapshot.reason !== undefined)\n return reasonOf(snapshot.reason);\n return null;\n }\n if (outcome.outcome === 'unknown')\n return [\n outcome.applied === 'partial'\n ? t('flow.unknownPartial', {\n defaultValue: 'Part of this may have been applied. Nothing was resent.',\n })\n : t('flow.unknown', {\n defaultValue: 'It may have been applied. Nothing was resent.',\n }),\n ...(snapshot.reason === undefined ? [] : [reasonOf(snapshot.reason)]),\n ].join(' ');\n if (outcome.outcome === 'rejected') {\n if (snapshot.reason !== undefined) return reasonOf(snapshot.reason);\n const kind = 'kind' in outcome ? outcome.kind : undefined;\n const code = 'code' in outcome ? outcome.code : undefined;\n if (code !== undefined) {\n const specific = specificErrorText(\n {\n code,\n ...('message' in outcome && outcome.message !== undefined\n ? { message: outcome.message }\n : {}),\n },\n caps,\n { action: { prefix: textPrefix, texts: flow?.texts } },\n );\n if (specific !== undefined) return specific;\n }\n const key = kind === undefined ? undefined : REJECTED_KEYS[kind];\n if (key !== undefined)\n return t(`${textPrefix}.rejected.${key}`, {\n defaultValue:\n textsValueAt(flow?.texts, ['rejected', key]) ??\n t(`flow.rejected.${key}`, { defaultValue: 'Nothing was saved.' }),\n });\n return t('flow.rejected.precondition', {\n defaultValue: 'The record changed. Nothing was sent.',\n });\n }\n if (outcome.outcome === 'failed') {\n if (snapshot.reason !== undefined) return reasonOf(snapshot.reason);\n // The code's own text first (spec 4.15), as the bulk summary and the record frame read it.\n const code = 'code' in outcome ? outcome.code : undefined;\n const specific =\n code === undefined\n ? undefined\n : specificErrorText(\n {\n code,\n ...('message' in outcome && outcome.message !== undefined\n ? { message: outcome.message }\n : {}),\n },\n caps,\n { action: { prefix: textPrefix, texts: flow?.texts } },\n );\n return (\n specific ??\n t('flow.failed', { defaultValue: 'The request could not be sent. Nothing was saved.' })\n );\n }\n return null;\n}\n\n/**\n * The UI kit's flow host screen (`presentationHosts.screens.flow`, presented under `buro:flow`;\n * P4 spec 4.15, 4.19): the action's label and the record's title with its «i» and ✕; the form\n * (a `steps` body is a wizard), the final screen's warnings and `confirm`, and the outcome\n * screens; a footer of Back, Cancel and the submit button, labelled with the action's label and\n * its pending text while the write runs.\n *\n * The presentation is a dismiss scope (P3-30): Escape, an outside click, ✕ and Cancel close\n * through it, so a dirty form asks first; Back between steps stays in the host and asks nothing.\n * From the re-read to the outcome the screen holds the scope's pending lock — nothing closes it,\n * and the run holds every route change. `success` closes the host without asking; `rejected`\n * and `failed` return to the dirty form; `unknown` closes without asking and keeps the attempt.\n */\nexport function FlowScreen(props: FlowScreenProps): ReactElement | null {\n if (props.run !== undefined && props.compiled !== undefined)\n return <HeldFlowScreen {...props} run={props.run} compiled={props.compiled} />;\n if (props.start !== undefined) return <OwnedFlowScreen {...props} start={props.start} />;\n return null;\n}\n\ntype HeldProps = FlowScreenProps & { readonly run: FlowRun; readonly compiled: CompiledFlow };\n\n/**\n * A bulk run's record frame (read-scope spec 4, rule 1): the form's `'context'` reads take the\n * value every selected row agrees on, else the session's. A run without a selection adds nothing.\n */\nfunction SelectionScope(props: {\n readonly selection: FlowScreenProps['selection'];\n readonly resource: string | null;\n readonly children: ReactNode;\n}): ReactElement {\n if (props.selection === undefined || props.resource === null) return <>{props.children}</>;\n return (\n <BulkSelectionScope resource={props.resource} ids={props.selection.ids}>\n {props.children}\n </BulkSelectionScope>\n );\n}\n\n/** The screen over a run it is given. */\nfunction HeldFlowScreen(props: HeldProps): ReactElement {\n // \"I've checked — start over\" (4.8) opens a fresh form: the body mounts again, so the form\n // takes the run's fresh values as its baseline and offers the stored draft.\n const [generation, setGeneration] = useState(0);\n // An app flow's form reads its texts in its `common.appActions.<name>` entry.\n return (\n <FlowTextsScope compiled={props.compiled}>\n <WithBinding>\n <ScreenStateProvider key={generation}>\n <SelectionScope selection={props.selection} resource={props.compiled.resource}>\n <FlowScreenBody {...props} onFreshForm={() => setGeneration((value) => value + 1)} />\n </SelectionScope>\n </ScreenStateProvider>\n </WithBinding>\n </FlowTextsScope>\n );\n}\n\n/**\n * The host owning its run (P4-C review I1): the run lives as long as the host, not as long as\n * the control that opened it — a row that left the page, a menu item that closed — so a dirty\n * form still asks before it closes and a pending write still holds its lock. `then` waits until\n * the host has gone (its form and its blocker with it), then runs through the opener's\n * dispatcher scope; each outcome is reported to the opener.\n */\nfunction OwnedFlowScreen(props: FlowScreenProps & { readonly start: FlowStart }): ReactElement {\n const { start, effects, onSettle } = props;\n const flow = useFlowRun(start.target, {\n ...(start.record === undefined ? {} : { record: start.record }),\n ...(start.args === undefined ? {} : { args: start.args }),\n ...(start.selection === undefined ? {} : { selection: start.selection }),\n surface: 'host',\n ...(effects === undefined ? {} : { thenEffects: effects }),\n });\n // `then` is the host's to run, after it closed.\n flow.holdThen(true);\n const latest = useRef(flow);\n latest.current = flow;\n useEffect(\n () => () => {\n // After the commit that removed the host: its form's blocker is gone.\n setTimeout(() => {\n latest.current.holdThen(false);\n latest.current.runThen();\n }, 0);\n },\n [],\n );\n const { run, snapshot, compiled } = flow;\n const outcome = snapshot.outcome;\n useEffect(() => {\n if (outcome !== undefined) onSettle?.(outcome);\n }, [outcome, onSettle]);\n const instance = useUIInstance();\n const t = useOptionalT();\n const caps = useI18nCaps(compiled?.resource ?? undefined);\n const tid = useTestIds();\n const opened =\n run !== null &&\n compiled !== null &&\n (snapshot.history.includes('open') || snapshot.step === 'outcome');\n if (opened) return <HeldFlowScreen {...props} run={run} compiled={compiled} />;\n // Not opened yet: its gate, its sources and a stored attempt decide first. A run that\n // decided against opening says why.\n const refused = snapshot.control === 'disabled' || snapshot.control === 'absent';\n return (\n <div\n data-testid={compiled === null ? undefined : `${tid.flowHost(compiled.flowId)}:opening`}\n data-buro-host={props.host}\n data-buro-flow-step={refused ? 'refused' : 'opening'}\n aria-busy={refused ? undefined : 'true'}\n className=\"flex min-h-0 flex-1 flex-col gap-4\"\n >\n <OwnTitleHeading label={props.label} />\n {refused ? (\n <p role=\"alert\" className=\"text-sm\">\n {snapshot.reason === undefined\n ? t('flow.unavailable', { defaultValue: 'Not allowed.' })\n : reasonText(caps, snapshot.reason, compiled?.resource ?? undefined)}\n </p>\n ) : (\n <IconLoader2 className=\"h-5 w-5 animate-spin self-center\" aria-hidden=\"true\" />\n )}\n <div className=\"flex justify-end\">\n <Button type=\"button\" variant=\"ghost\" onClick={() => instance.dismiss()}>\n {t('flow.close', { defaultValue: 'Close' })}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction FlowScreenBody({\n run,\n host,\n label,\n title: givenTitle,\n compiled,\n record: givenRecord,\n args,\n selection,\n onFreshForm,\n}: HeldProps & { readonly onFreshForm: () => void }): ReactElement {\n // A collection-level flow has no record, whoever passed one (spec 5.1): its title, its form and\n // its review read none.\n const record = flowRecordOf(compiled, givenRecord);\n const snapshot = useSyncSnapshot(run);\n const binding = useContext(FlowHostBindingContext) as FlowHostBinding;\n const tid = useTestIds();\n const t = useOptionalT();\n const chromeT = useChromeT();\n const resource = compiled.resource ?? undefined;\n const caps = useI18nCaps(resource);\n const ownTitle = useContext(OwnTitleContext);\n const flowId = compiled.flowId;\n const recordId = record?.[compiled.idField] ?? record?.id;\n const recordTitle = useProjectedTitle(resource, recordId, record);\n const title =\n givenTitle ?? (record === undefined || recordTitle === '' ? undefined : recordTitle);\n const form = useFlowForm(run, compiled, snapshot, {\n ...(record === undefined ? {} : { record }),\n ...(args === undefined ? {} : { args }),\n ...(selection === undefined ? {} : { selection: selection.ids }),\n });\n const formControl = useFormControlOf(form);\n const hasForm = compiled.flow.form !== undefined;\n const [busy, setBusy] = useState(false);\n // The values the form opened on: the review's baseline (4.4). The host opens on an opened run,\n // before anything was typed.\n const [initial] = useState(() => run.getSnapshot().values);\n // Form-level messages: a server's validation refusal on a key no field holds (M14), a\n // resource-level validator's.\n const formErrors = form.errors.filter((issue) => issue.field === '_form');\n\n // The pending lock (4.19): from the re-read to the persisted outcome nothing closes the host.\n const locked = snapshot.control === 'running';\n useDismissPending(locked);\n\n const outcome = snapshot.outcome?.outcome;\n const unknown = outcome === 'unknown';\n const succeeded = outcome === 'success';\n const finalStep = snapshot.step === 'review' || snapshot.step === 'accept';\n\n // `success` closes the host, unasked: nothing unsaved remains (4.19). The run settled the\n // mutation's effects before it answered (4.13).\n // `then.open: { block, props }` keeps the host and draws the block instead (4.13): its close is\n // the block's own button and ✕, and `result` goes with the host.\n const openBlock = succeeded ? blockOpen(snapshot.effects?.open) : null;\n // The write's own notices (spec 4.7), once per success, before the host closes.\n const showNotices = useNoticeSink(resource);\n const shownNotices = useRef<unknown>(null);\n useEffect(() => {\n if (!succeeded || snapshot.notices.length === 0 || shownNotices.current === snapshot.notices)\n return;\n shownNotices.current = snapshot.notices;\n showNotices(snapshot.notices);\n }, [succeeded, snapshot.notices, showNotices]);\n useEffect(() => {\n if (succeeded && !locked && openBlock === null) binding.finish();\n }, [succeeded, locked, openBlock, binding]);\n\n const prefix =\n compiled.resource === null\n ? `appActions.${compiled.name}`\n : `${compiled.resource}.actions.${compiled.name}`;\n\n const settle = (result: FlowResult) => {\n setBusy(result.outcome === 'failed' && 'reason' in result && result.reason === 'busy');\n };\n const submit = async () => {\n if (locked) return;\n setBusy(false);\n if (finalStep) {\n settle(await run.accept());\n return;\n }\n if (unknown && editingNew) {\n // Send as new: the form as filled now, validated, then the confirmation (P4-C review C2).\n let valid = false;\n await form.handleSubmit(() => {\n valid = true;\n throw HELD;\n })();\n if (valid) setConfirmingNew(true);\n return;\n }\n if (unknown) return;\n if (hasForm) {\n // The controller validates the active fields and reveals the first failing one (its step\n // included); the run sends.\n let validated = false;\n await form.handleSubmit(() => {\n validated = true;\n throw HELD;\n })();\n if (!validated) return;\n }\n settle(await run.submit());\n };\n\n const pendingKey =\n compiled.resource === null\n ? `appActions.${compiled.name}.pending`\n : `resources.${compiled.resource}.actions.${compiled.name}.pending`;\n const pendingLabel = caps.has(pendingKey) ? caps.t(pendingKey) : `${label}…`;\n const message = outcomeMessage(\n snapshot,\n busy,\n t,\n caps,\n compiled.textKeys.prefix,\n compiled.flow,\n (reason) => reasonText(caps, reason, resource),\n );\n // The form-level issues, resolved here so a language switch re-renders them; one that says\n // what the outcome heading already says is not shown twice.\n const formErrorTexts = formErrors\n .map((issue) =>\n resolveValidationMessage(\n {\n code: issue.code ?? '',\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n { has: caps.has, t: caps.t },\n ),\n )\n .filter((text) => text !== message);\n // The flow's own word for its cancel buttons (`<prefix>.dismiss`, then its declared\n // `texts.dismiss`), else the kit's.\n const dismissKey = `${compiled.textKeys.prefix}.dismiss`;\n const cancelWord =\n (caps.has(dismissKey) ? caps.t(dismissKey) : undefined) ??\n declaredText('flow', compiled.flow, 'dismiss') ??\n chromeT('actions.cancel', { defaultValue: 'Cancel' });\n // The run flags a check that could not decide; its reason is a translation, never compared.\n const couldNotCheck = snapshot.control === 'disabled' && snapshot.unverified === true;\n const steps = form.steps;\n const lastStep =\n steps === null || steps.ids.length === 0 || steps.current === steps.ids[steps.ids.length - 1];\n const showSubmit = !unknown && !succeeded && (!hasForm || finalStep || lastStep);\n // The unknown screen's exits (4.8).\n const [confirmingNew, setConfirmingNew] = useState(false);\n // Send as new sends the form as it is now (4.8): the user fills it again and it is validated\n // first — after a reload it holds only its initial values (P4-C review C2).\n const [editingNew, setEditingNew] = useState(false);\n const checkable = compiled.flow.submit.onUnknown !== undefined;\n const unhandled = unknown && !checkable && !snapshot.canResend;\n const exit = (action: () => Promise<FlowResult>) => () => {\n if (!locked) void action().then(settle);\n };\n // An overlay's Cancel keeps the draft so it survives the close (4.19); an inline Reset means\n // \"start over\", so the next form must not offer the input it just threw away (REF-51). An\n // unknown outcome's Close keeps it, like every unresolved attempt (4.11).\n const close = () => {\n if (binding.kind === 'inline' && hasForm && !unknown) form.draft.discard();\n binding.close();\n };\n\n const headingRef = useRef<HTMLHeadingElement>(null);\n useFocusOnMount(headingRef);\n const heading = (\n <h2\n ref={headingRef}\n tabIndex={-1}\n data-buro-overlay-heading=\"\"\n className=\"min-w-0 flex-1 break-words text-lg font-semibold tracking-tight focus-visible:outline-hidden\"\n >\n {label}\n {title === undefined ? null : (\n <span className=\"ml-2 font-normal text-muted-foreground\">{title}</span>\n )}\n </h2>\n );\n\n return (\n <div\n data-testid={tid.flowHost(flowId)}\n data-buro-host={host}\n data-buro-flow-step={snapshot.step}\n aria-busy={locked ? 'true' : undefined}\n className=\"flex min-h-0 flex-1 flex-col gap-4\"\n >\n {binding.kind === 'inline' ? null : (\n <div data-buro-region=\"flow-header\" className=\"flex items-center gap-2 pr-1\">\n {ownTitle ? <DialogPrimitive.Title asChild>{heading}</DialogPrimitive.Title> : heading}\n {compiled.resource === null ? null : (\n <DocInfo\n address={`${compiled.resource}/actions/${compiled.name}`}\n name={label}\n testId={`${tid.flowHost(flowId)}:info`}\n />\n )}\n {binding.kind === 'overlay' ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n data-testid={tid.flowClose(flowId)}\n aria-label={t('flow.close', { defaultValue: 'Close' })}\n onClick={close}\n >\n <IconX className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n ) : null}\n </div>\n )}\n {openBlock !== null ? (\n <FlowOpenBlock open={openBlock} prefix={prefix} testid={tid.flowHost(flowId)} />\n ) : null}\n {openBlock !== null && binding.kind !== 'overlay' ? (\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={tid.flowClose(flowId)}\n onClick={close}\n >\n {t('flow.done', { defaultValue: 'Done' })}\n </Button>\n </div>\n ) : null}\n <form\n hidden={openBlock !== null}\n noValidate\n className={openBlock === null ? 'flex min-h-0 flex-1 flex-col gap-4' : 'hidden'}\n onSubmit={(event) => {\n event.preventDefault();\n void submit();\n }}\n >\n <div className=\"-mx-1 flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-1\">\n {message === null ? null : (\n <div\n role={unknown || outcome === 'rejected' || outcome === 'failed' ? 'alert' : 'status'}\n data-testid={tid.flowOutcome(flowId)}\n data-buro-flow-outcome={busy ? 'busy' : (outcome ?? snapshot.control)}\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n >\n <span>{message}</span>\n {couldNotCheck ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"ml-auto\"\n onClick={() => run.retryChecks()}\n >\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n ) : null}\n </div>\n )}\n {hasForm && form.draft.pending !== null && (!unknown || editingNew) ? (\n <div\n data-testid={tid.flowDraft(flowId)}\n role=\"status\"\n aria-live=\"polite\"\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm\"\n >\n <span className=\"font-medium\">\n {t('draft.restorePrompt', { defaultValue: 'Restore draft?' })}\n </span>\n <div className=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n data-testid={`${tid.flowDraft(flowId)}:restore`}\n onClick={form.draft.restore}\n >\n {t('draft.restore', { defaultValue: 'Restore' })}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n data-testid={`${tid.flowDraft(flowId)}:discard`}\n onClick={form.draft.discard}\n >\n {t('draft.discard', { defaultValue: 'Discard' })}\n </Button>\n </div>\n </div>\n ) : null}\n {formErrorTexts.length > 0 ? (\n <div\n role=\"alert\"\n data-testid={`${tid.flowHost(flowId)}:form-errors`}\n className=\"flex flex-col gap-1 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n >\n {formErrorTexts.map((text, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: one failed write's fixed list\n <p key={index}>{text}</p>\n ))}\n </div>\n ) : null}\n {finalStep && compiled.flow.review === true ? (\n <ReviewDiff\n form={form}\n initial={initial}\n values={snapshot.values}\n i18nPrefix={prefix}\n testid={tid.flowHost(flowId)}\n />\n ) : finalStep && Array.isArray(compiled.flow.review) ? (\n <ReviewTree\n compiled={compiled}\n tree={compiled.flow.review}\n values={snapshot.values}\n prefix={prefix}\n run={run}\n {...(record === undefined ? {} : { record })}\n {...(args === undefined ? {} : { args })}\n />\n ) : hasForm ? (\n <FormControlProvider value={formControl}>\n <ScreenTree\n region=\"form-body\"\n resource={prefix}\n mode=\"create\"\n compiled={form.screen}\n controller={form}\n // The record scheme: the leaves carry `form-field-input:<prefix>:create:<name>`\n // test ids, and their texts key as `resources.<prefix>.fields.<name>.…` (4.4).\n leafIds=\"record\"\n disabled={locked || (unknown && !editingNew) || finalStep || succeeded}\n />\n </FormControlProvider>\n ) : null}\n {finalStep && snapshot.warnings.length > 0 ? (\n <ul\n role=\"status\"\n data-buro-region=\"flow-warnings\"\n className=\"flex flex-col gap-1 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm text-warning-emphasis\"\n >\n {snapshot.warnings.map((warning) => (\n <li key={warning.id} data-testid={`${tid.flowHost(flowId)}:warning:${warning.id}`}>\n {warning.message}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n {unhandled ? (\n <p data-testid={`${tid.flowOutcome(flowId)}:unhandled`} className=\"text-sm\">\n {t('flow.unknownUnhandled', { defaultValue: 'Check the record before trying again.' })}\n </p>\n ) : null}\n {unknown && confirmingNew ? (\n <div\n role=\"alertdialog\"\n aria-label={t('flow.sendAsNew', { defaultValue: 'Send as new' })}\n data-testid={`${tid.flowSendAsNew(flowId)}:confirm`}\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm\"\n >\n <span>\n {t('flow.sendAsNewConfirm', {\n defaultValue: 'This may apply the change twice. Send it as a new request?',\n })}\n </span>\n <div className=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n data-testid={`${tid.flowSendAsNew(flowId)}:cancel`}\n onClick={() => setConfirmingNew(false)}\n >\n {cancelWord}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"destructive\"\n data-testid={`${tid.flowSendAsNew(flowId)}:ok`}\n onClick={() => {\n setConfirmingNew(false);\n exit(() => run.sendAsNew({ confirmed: true }))();\n }}\n >\n {t('flow.sendAsNew', { defaultValue: 'Send as new' })}\n </Button>\n </div>\n </div>\n ) : null}\n {unknown ? (\n <div data-buro-region=\"flow-unknown-exits\" className=\"flex flex-wrap gap-2\">\n {checkable ? (\n <Button\n type=\"button\"\n variant=\"default\"\n data-testid={tid.flowCheckAgain(flowId)}\n disabled={locked}\n onClick={exit(() => run.checkAgain())}\n >\n {t('flow.checkAgain', { defaultValue: 'Check again' })}\n </Button>\n ) : null}\n {snapshot.canResend ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={tid.flowResend(flowId)}\n disabled={locked}\n onClick={exit(() => run.resend())}\n >\n {t('flow.resend', { defaultValue: 'Resend' })}\n </Button>\n ) : null}\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={tid.flowSendAsNew(flowId)}\n disabled={locked || confirmingNew || editingNew}\n onClick={() => {\n if (hasForm) setEditingNew(true);\n else setConfirmingNew(true);\n }}\n >\n {t('flow.sendAsNew', { defaultValue: 'Send as new' })}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={tid.flowStartOver(flowId)}\n disabled={locked}\n onClick={() => {\n run.startOver();\n onFreshForm();\n }}\n >\n {t('flow.startOver', { defaultValue: \"I've checked — start over\" })}\n </Button>\n </div>\n ) : null}\n <div data-buro-region=\"flow-footer\" className=\"flex flex-wrap items-center gap-2\">\n {finalStep && hasForm && !locked ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={tid.flowBack(flowId)}\n onClick={() => run.back()}\n >\n {t('flow.back', { defaultValue: 'Back' })}\n </Button>\n ) : null}\n <div className=\"ml-auto flex gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n data-testid={tid.flowCancel(flowId)}\n disabled={locked}\n onClick={close}\n >\n {unknown\n ? t('flow.close', { defaultValue: 'Close' })\n : binding.kind === 'inline'\n ? t('flow.reset', { defaultValue: 'Reset' })\n : cancelWord}\n </Button>\n {unknown && editingNew ? (\n <Button\n type=\"submit\"\n variant=\"destructive\"\n data-testid={`${tid.flowSendAsNew(flowId)}:submit`}\n disabled={locked || confirmingNew}\n onMouseDown={(event) => event.preventDefault()}\n >\n {t('flow.sendAsNew', { defaultValue: 'Send as new' })}\n </Button>\n ) : null}\n {showSubmit ? (\n <Button\n type=\"submit\"\n variant={compiled.flow.variant === 'destructive' ? 'destructive' : 'default'}\n data-testid={tid.flowSubmit(flowId)}\n disabled={locked || couldNotCheck}\n aria-busy={locked ? 'true' : undefined}\n // Without this, focusing out of a field a blur error just inserted moves the\n // button, and the click that lands on its old position is swallowed.\n onMouseDown={(event) => event.preventDefault()}\n >\n {locked ? (\n <IconLoader2 className=\"h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n ) : null}\n {locked ? pendingLabel : label}\n </Button>\n ) : null}\n </div>\n </div>\n </form>\n </div>\n );\n}\n\n/** The run's snapshot, re-rendering on each change. */\nfunction useSyncSnapshot(run: FlowRun): FlowSnapshot {\n return useSyncExternalStore(run.subscribe, run.getSnapshot, run.getSnapshot);\n}\n\nconst NO_FIELDS = Object.freeze({});\n\n/**\n * `review: (l) => [...]` (4.4): a show tree over the flow's values — displays and placements\n * only, no inputs — drawn by a show-mode form over the flow's fields.\n */\nfunction ReviewTree({\n compiled,\n tree,\n values,\n prefix,\n run,\n record,\n args,\n}: {\n readonly compiled: CompiledFlow;\n readonly tree: readonly unknown[];\n readonly values: Readonly<Record<string, unknown>>;\n readonly prefix: string;\n readonly run: FlowRun;\n readonly record?: Row;\n readonly args?: Row;\n}): ReactElement {\n const fields = compiled.flow.form?.fields;\n // A review places what it shows: a field the tree does not place leaves the show mode (its\n // `in`), so a review of blocks alone (spec 3.6) is not refused for the fields it leaves out.\n const map = useState(() => {\n if (fields === undefined) return NO_FIELDS;\n const placed = placedLeaves(tree);\n return fieldEntriesToMap(\n (fields as readonly Readonly<Record<string, unknown>>[]).map((field) =>\n placed.has(String(field.name)) ? field : { ...field, in: ['create'] },\n ) as never,\n );\n })[0];\n const body = useState(() => () => tree as never)[0];\n // The app's blocks: a review tree places them (P4-D, spec 3.6's `l.place(offeringReview)`).\n const blocks = useFlowFormCatalog();\n // The run's record and args, like the form step reads them (G35): the controller honours meta\n // sources only under the run's claim, so the review carries the run and its form id. Compiled\n // as a review, the tree's `values` stay the form's values while `record` is the run's.\n const metaSources = useFlowMetaSources(record, args, compiled.resource);\n const review = useFormController({\n blocks,\n flowRun: run,\n formId: compiled.formId,\n metaSources,\n review: true,\n fields: map as never,\n body,\n mode: 'show',\n i18nPrefix: prefix,\n value: values as never,\n });\n return (\n <ScreenTree\n region=\"form-body\"\n resource={prefix}\n mode=\"show\"\n compiled={review.screen}\n controller={review}\n leafIds=\"record\"\n />\n );\n}\n\n/** The field names a tree places as leaves (a string child of any node). */\nfunction placedLeaves(tree: readonly unknown[]): ReadonlySet<string> {\n const out = new Set<string>();\n const walk = (node: unknown): void => {\n if (typeof node === 'string') {\n out.add(node);\n return;\n }\n if (node === null || typeof node !== 'object') return;\n const children = (node as { readonly children?: unknown }).children;\n if (Array.isArray(children)) for (const child of children) walk(child);\n };\n for (const node of tree) walk(node);\n return out;\n}\n\n/** A `then.open` block target, once resolved (`{ block, props }`); `null` for anything else. */\nfunction blockOpen(open: unknown): { readonly block: EntityRefLike; readonly props: Row } | null {\n if (open === null || typeof open !== 'object' || !Object.hasOwn(open, 'block')) return null;\n const { block, props } = open as { readonly block?: unknown; readonly props?: unknown };\n const ref =\n block !== null && typeof block === 'object' && 'ref' in block\n ? (block as { readonly ref: unknown }).ref\n : block;\n if (\n ref === null ||\n typeof ref !== 'object' ||\n typeof (ref as EntityRefLike).namespace !== 'string' ||\n typeof (ref as EntityRefLike).id !== 'string'\n )\n return null;\n return {\n block: ref as EntityRefLike,\n props: props !== null && typeof props === 'object' ? (props as Row) : {},\n };\n}\n\ninterface EntityRefLike {\n readonly namespace: string;\n readonly id: string;\n}\ntype Row = Readonly<Record<string, unknown>>;\n\n/**\n * The block `then.open` names, drawn in the host after success (4.13): its implementation from\n * the mounted catalog (an app's over the kit's), its props validated against the block's schemas\n * at mount (P1b+P1c decision 35); a failed validation, or a block nothing implements, says so.\n */\nfunction FlowOpenBlock({\n open,\n testid,\n}: {\n readonly open: { readonly block: EntityRefLike; readonly props: Row };\n readonly prefix: string;\n readonly testid: string;\n}): ReactElement {\n const t = useOptionalT();\n const id = `${open.block.namespace}:${open.block.id}`;\n const implementation = selectImplementation(id, useFlowOpenImplementation(id) as never);\n const [validation, setValidation] = useState<PropValidation | null>(() =>\n implementation === undefined\n ? null\n : validatePlacementProps(implementation.definition as never, open.props),\n );\n useEffect(() => {\n if (validation?.status !== 'pending') return;\n let live = true;\n void validation.settled.then((settled) => {\n if (live) setValidation(settled);\n });\n return () => {\n live = false;\n };\n }, [validation]);\n const failed = implementation === undefined || validation?.status === 'failed';\n const View = implementation === undefined ? null : viewOf(implementation);\n return (\n <div\n data-testid={`${testid}:open`}\n data-buro-block={id}\n className=\"min-h-0 flex-1 overflow-y-auto\"\n >\n {failed ? (\n <p role=\"alert\" className=\"text-sm text-muted-foreground\">\n {t('block.notImplemented', { defaultValue: 'This section is not available.' })}\n </p>\n ) : View === null || validation?.status !== 'ready' ? null : (\n <Suspense fallback={null}>\n <View\n props={validation.props as never}\n data={NO_FIELDS as never}\n t={(key, options) =>\n t(`blocks.${id}.${key}`, {\n ...(options?.params === undefined ? {} : { params: options.params }),\n ...(options?.count === undefined ? {} : { count: options.count }),\n })\n }\n />\n </Suspense>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAOA,MAAa,oBAAoB;AAgBjC,SAAS,UAAU,YAA8B;CAC/C,IAAI,iBAAiB,UAAU,MAAM,KAAA,GAAW,OAAO;CACvD,IAAI,eAAe,QAAQ,OAAO,eAAe,UAAU,OAAO;CAClE,MAAM,OAAQ,WAA2C;CACzD,MAAM,SACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAA0C,YAC3C,KAAA;CACN,OAAO,WAAW,KAAA,KAAa,WAAW,SAAS,WAAW;AAChE;AAEA,MAAM,QAAQ,GAAY,MAAwB;CAChD,IAAI,OAAO,GAAG,GAAG,CAAC,GAAG,OAAO;CAC5B,MAAM,SAAS,UAAmB,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU;CACrF,IAAI,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG,OAAO;CACjC,IAAI;EACF,OAAO,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;CAC/C,QAAQ;EACN,OAAO;CACT;AACF;AAOA,SAAgB,WAAW,EACzB,MACA,SACA,QACA,YACA,UACgC;CAEhC,MAAM,cADI,aACU,CAAC,CAAC,kBAAkB,EAAE,cAAc,UAAU,CAAC;CACnE,MAAM,OAAO,KAAK,OAAO,QAAQ,YAAY,CAAC,KAAK,QAAQ,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC;CAC/F,OACE,IAAC,MAAD;EAAI,eAAa,GAAG,OAAO;EAAU,mBAAiB;EAAmB,WAAU;EAChF,UAAA,KAAK,KAAK,YAAY;GACrB,MAAM,aAAa,QAAQ;GAC3B,MAAM,QACJ,OAAO,WAAW,UAAU,WAAW,WAAW,QAAQ,YAAY,QAAQ,IAAI;GACpF,MAAM,SAAS,UAAU,QAAQ,KAAK;GACtC,OACE,KAAC,OAAD;IAEE,eAAa,GAAG,OAAO,UAAU,QAAQ;IACzC,WAAU;IAHZ,UAAA,CAKE,IAAC,MAAD;KAAI,WAAU;KAAe,UAAA;IAAU,CAAA,GACvC,IAAC,MAAD;KAAI,WAAU;KACX,UAAA,SACC,IAAC,QAAD;MAAM,WAAU;MAAyB,UAAA;KAAkB,CAAA,IAE3D,KAAA,YAAA,EAAA,UAAA;MACE,IAAC,QAAD;OAAM,oBAAiB;OAAM,WAAU;OACrC,UAAA,IAAC,cAAD;QACc;QACZ,MAAM,QAAQ;QACd,OAAO,QAAQ;QACf,OAAO,QAAQ,QAAQ;QACvB,UAAU,IAAC,QAAD,EAAA,UAAO,QAAQ,QAAQ,QAAQ,KAAK,EAAQ,CAAA;OACvD,CAAA;MACG,CAAA;MACN,IAAC,QAAD;OAAM,eAAY;OAAO,UAAA;MAAO,CAAA;MAChC,IAAC,QAAD;OAAM,oBAAiB;OACrB,UAAA,IAAC,cAAD;QACc;QACZ,MAAM,QAAQ;QACd,OAAO,QAAQ;QACf,OAAO,OAAO,QAAQ;QACtB,UAAU,IAAC,QAAD,EAAA,UAAO,QAAQ,OAAO,QAAQ,KAAK,EAAQ,CAAA;OACtD,CAAA;MACG,CAAA;KACN,EAAA,CAAA;IAEF,CAAA,CACD;GAhCE,GAAA,QAAQ,IAgCV;EAET,CAAC;CACC,CAAA;AAER;AAEA,MAAM,WAAW,UACf,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,KAAK,MAAM,OAAO,KAAK;;;AC3C5E,MAAM,OAAO,OAAO,OAAO;CAAE,MAAM;CAAc,SAAS;AAAiC,CAAC;AAiB5F,SAAgB,iBACd,OACqB;CACrB,MAAM,EAAE,SAAS,GAAG,SAAS;CAC7B,OACE,IAAC,uBAAuB,UAAxB;EAAiC,OAAO;EACtC,UAAA,IAAC,YAAD,EAAY,GAAI,KAAO,CAAA;CACQ,CAAA;AAErC;AAEA,MAAa,yBAAyB,cAAsC,IAAI;AAGhF,SAAS,eAAe,EAAE,YAA4D;CACpF,MAAM,WAAW,cAAc;CAC/B,MAAM,UAAU,yBAAyB;CACzC,MAAM,UAAU,eACP;EACL,MAAM;EACN,aAAa,SAAS,QAAQ;EAC9B,cAAc,QAAQ,QAAQ,SAAS,EAAE;CAC3C,IACA,CAAC,UAAU,OAAO,CACpB;CACA,OACE,IAAC,uBAAuB,UAAxB;EAAiC,OAAO;EAAU;CAA0C,CAAA;AAEhG;AAGA,SAAS,YAAY,EAAE,YAA4D;CAEjF,OADiB,WAAW,sBACd,MAAM,OAAO,IAAA,YAAA,EAAG,SAAW,CAAA,IAAI,IAAC,gBAAD,EAAiB,SAAyB,CAAA;AACzF;AAYA,SAAS,eACP,UACA,MACA,GACA,MACA,YACA,MACA,UACe;CACf,IAAI,MACF,OAAO,EAAE,sBAAsB,EAAE,cAAc,yCAAyC,CAAC;CAC3F,MAAM,UAAU,SAAS;CACzB,IAAI,YAAY,KAAA,KAAa,QAAQ,YAAY,WAAW;EAE1D,IAAI,SAAS,YAAY,cAAc,SAAS,WAAW,KAAA,GACzD,OAAO,SAAS,SAAS,MAAM;EACjC,OAAO;CACT;CACA,IAAI,QAAQ,YAAY,WACtB,OAAO,CACL,QAAQ,YAAY,YAChB,EAAE,uBAAuB,EACvB,cAAc,0DAChB,CAAC,IACD,EAAE,gBAAgB,EAChB,cAAc,gDAChB,CAAC,GACL,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,SAAS,SAAS,MAAM,CAAC,CACrE,CAAC,CAAC,KAAK,GAAG;CACZ,IAAI,QAAQ,YAAY,YAAY;EAClC,IAAI,SAAS,WAAW,KAAA,GAAW,OAAO,SAAS,SAAS,MAAM;EAClE,MAAM,OAAO,UAAU,UAAU,QAAQ,OAAO,KAAA;EAChD,MAAM,OAAO,UAAU,UAAU,QAAQ,OAAO,KAAA;EAChD,IAAI,SAAS,KAAA,GAAW;GACtB,MAAM,WAAW,kBACf;IACE;IACA,GAAI,aAAa,WAAW,QAAQ,YAAY,KAAA,IAC5C,EAAE,SAAS,QAAQ,QAAQ,IAC3B,CAAC;GACP,GACA,MACA,EAAE,QAAQ;IAAE,QAAQ;IAAY,OAAO,MAAM;GAAM,EAAE,CACvD;GACA,IAAI,aAAa,KAAA,GAAW,OAAO;EACrC;EACA,MAAM,MAAM,SAAS,KAAA,IAAY,KAAA,IAAY,cAAc;EAC3D,IAAI,QAAQ,KAAA,GACV,OAAO,EAAE,GAAG,WAAW,YAAY,OAAO,EACxC,cACE,aAAa,MAAM,OAAO,CAAC,YAAY,GAAG,CAAC,KAC3C,EAAE,iBAAiB,OAAO,EAAE,cAAc,qBAAqB,CAAC,EACpE,CAAC;EACH,OAAO,EAAE,8BAA8B,EACrC,cAAc,wCAChB,CAAC;CACH;CACA,IAAI,QAAQ,YAAY,UAAU;EAChC,IAAI,SAAS,WAAW,KAAA,GAAW,OAAO,SAAS,SAAS,MAAM;EAElE,MAAM,OAAO,UAAU,UAAU,QAAQ,OAAO,KAAA;EAchD,QAZE,SAAS,KAAA,IACL,KAAA,IACA,kBACE;GACE;GACA,GAAI,aAAa,WAAW,QAAQ,YAAY,KAAA,IAC5C,EAAE,SAAS,QAAQ,QAAQ,IAC3B,CAAC;EACP,GACA,MACA,EAAE,QAAQ;GAAE,QAAQ;GAAY,OAAO,MAAM;EAAM,EAAE,CACvD,MAGJ,EAAE,eAAe,EAAE,cAAc,oDAAoD,CAAC;CAE1F;CACA,OAAO;AACT;AAeA,SAAgB,WAAW,OAA6C;CACtE,IAAI,MAAM,QAAQ,KAAA,KAAa,MAAM,aAAa,KAAA,GAChD,OAAO,IAAC,gBAAD;EAAgB,GAAI;EAAO,KAAK,MAAM;EAAK,UAAU,MAAM;CAAW,CAAA;CAC/E,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO,IAAC,iBAAD;EAAiB,GAAI;EAAO,OAAO,MAAM;CAAQ,CAAA;CACvF,OAAO;AACT;AAQA,SAAS,eAAe,OAIP;CACf,IAAI,MAAM,cAAc,KAAA,KAAa,MAAM,aAAa,MAAM,OAAO,IAAA,YAAA,EAAA,UAAG,MAAM,SAAW,CAAA;CACzF,OACE,IAAC,oBAAD;EAAoB,UAAU,MAAM;EAAU,KAAK,MAAM,UAAU;EAChE,UAAA,MAAM;CACW,CAAA;AAExB;AAGA,SAAS,eAAe,OAAgC;CAGtD,MAAM,CAAC,YAAY,iBAAiB,SAAS,CAAC;CAE9C,OACE,IAAC,gBAAD;EAAgB,UAAU,MAAM;EAC9B,UAAA,IAAC,aAAD,EAAA,UACE,IAAC,qBAAD,EAAA,UACE,IAAC,gBAAD;GAAgB,WAAW,MAAM;GAAW,UAAU,MAAM,SAAS;GACnE,UAAA,IAAC,gBAAD;IAAgB,GAAI;IAAO,mBAAmB,eAAe,UAAU,QAAQ,CAAC;GAAI,CAAA;EACtE,CAAA,EACG,GAJK,UAIL,EACV,CAAA;CACC,CAAA;AAEpB;AASA,SAAS,gBAAgB,OAAsE;CAC7F,MAAM,EAAE,OAAO,SAAS,aAAa;CACrC,MAAM,OAAO,WAAW,MAAM,QAAQ;EACpC,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;EAC7D,GAAI,MAAM,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;EACvD,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAU;EACtE,SAAS;EACT,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ;CAC1D,CAAC;CAED,KAAK,SAAS,IAAI;CAClB,MAAM,SAAS,OAAO,IAAI;CAC1B,OAAO,UAAU;CACjB,sBACc;EAEV,iBAAiB;GACf,OAAO,QAAQ,SAAS,KAAK;GAC7B,OAAO,QAAQ,QAAQ;EACzB,GAAG,CAAC;CACN,GACA,CAAC,CACH;CACA,MAAM,EAAE,KAAK,UAAU,aAAa;CACpC,MAAM,UAAU,SAAS;CACzB,gBAAgB;EACd,IAAI,YAAY,KAAA,GAAW,WAAW,OAAO;CAC/C,GAAG,CAAC,SAAS,QAAQ,CAAC;CACtB,MAAM,WAAW,cAAc;CAC/B,MAAM,IAAI,aAAa;CACvB,MAAM,OAAO,YAAY,UAAU,YAAY,KAAA,CAAS;CACxD,MAAM,MAAM,WAAW;CAKvB,IAHE,QAAQ,QACR,aAAa,SACZ,SAAS,QAAQ,SAAS,MAAM,KAAK,SAAS,SAAS,YAC9C,OAAO,IAAC,gBAAD;EAAgB,GAAI;EAAY;EAAe;CAAW,CAAA;CAG7E,MAAM,UAAU,SAAS,YAAY,cAAc,SAAS,YAAY;CACxE,OACE,KAAC,OAAD;EACE,eAAa,aAAa,OAAO,KAAA,IAAY,GAAG,IAAI,SAAS,SAAS,MAAM,EAAE;EAC9E,kBAAgB,MAAM;EACtB,uBAAqB,UAAU,YAAY;EAC3C,aAAW,UAAU,KAAA,IAAY;EACjC,WAAU;EALZ,UAAA;GAOE,IAAC,iBAAD,EAAiB,OAAO,MAAM,MAAQ,CAAA;GACrC,UACC,IAAC,KAAD;IAAG,MAAK;IAAQ,WAAU;IACvB,UAAA,SAAS,WAAW,KAAA,IACjB,EAAE,oBAAoB,EAAE,cAAc,eAAe,CAAC,IACtD,WAAW,MAAM,SAAS,QAAQ,UAAU,YAAY,KAAA,CAAS;GACpE,CAAA,IAEH,IAAC,aAAD;IAAa,WAAU;IAAmC,eAAY;GAAQ,CAAA;GAEhF,IAAC,OAAD;IAAK,WAAU;IACb,UAAA,IAAC,QAAD;KAAQ,MAAK;KAAS,SAAQ;KAAQ,eAAe,SAAS,QAAQ;KACnE,UAAA,EAAE,cAAc,EAAE,cAAc,QAAQ,CAAC;IACpC,CAAA;GACL,CAAA;EACF;;AAET;AAEA,SAAS,eAAe,EACtB,KACA,MACA,OACA,OAAO,YACP,UACA,QAAQ,aACR,MACA,WACA,eACiE;CAGjE,MAAM,SAAS,aAAa,UAAU,WAAW;CACjD,MAAM,WAAW,gBAAgB,GAAG;CACpC,MAAM,UAAU,WAAW,sBAAsB;CACjD,MAAM,MAAM,WAAW;CACvB,MAAM,IAAI,aAAa;CACvB,MAAM,UAAU,WAAW;CAC3B,MAAM,WAAW,SAAS,YAAY,KAAA;CACtC,MAAM,OAAO,YAAY,QAAQ;CACjC,MAAM,WAAW,WAAW,eAAe;CAC3C,MAAM,SAAS,SAAS;CACxB,MAAM,WAAW,SAAS,SAAS,YAAY,QAAQ;CACvD,MAAM,cAAc,kBAAkB,UAAU,UAAU,MAAM;CAChE,MAAM,QACJ,eAAe,WAAW,KAAA,KAAa,gBAAgB,KAAK,KAAA,IAAY;CAC1E,MAAM,OAAO,YAAY,KAAK,UAAU,UAAU;EAChD,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,UAAU,IAAI;CAChE,CAAC;CACD,MAAM,cAAc,iBAAiB,IAAI;CACzC,MAAM,UAAU,SAAS,KAAK,SAAS,KAAA;CACvC,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAGtC,MAAM,CAAC,WAAW,eAAe,IAAI,YAAY,CAAC,CAAC,MAAM;CAGzD,MAAM,aAAa,KAAK,OAAO,QAAQ,UAAU,MAAM,UAAU,OAAO;CAGxE,MAAM,SAAS,SAAS,YAAY;CACpC,kBAAkB,MAAM;CAExB,MAAM,UAAU,SAAS,SAAS;CAClC,MAAM,UAAU,YAAY;CAC5B,MAAM,YAAY,YAAY;CAC9B,MAAM,YAAY,SAAS,SAAS,YAAY,SAAS,SAAS;CAMlE,MAAM,YAAY,YAAY,UAAU,SAAS,SAAS,IAAI,IAAI;CAElE,MAAM,cAAc,cAAc,QAAQ;CAC1C,MAAM,eAAe,OAAgB,IAAI;CACzC,gBAAgB;EACd,IAAI,CAAC,aAAa,SAAS,QAAQ,WAAW,KAAK,aAAa,YAAY,SAAS,SACnF;EACF,aAAa,UAAU,SAAS;EAChC,YAAY,SAAS,OAAO;CAC9B,GAAG;EAAC;EAAW,SAAS;EAAS;CAAW,CAAC;CAC7C,gBAAgB;EACd,IAAI,aAAa,CAAC,UAAU,cAAc,MAAM,QAAQ,OAAO;CACjE,GAAG;EAAC;EAAW;EAAQ;EAAW;CAAO,CAAC;CAE1C,MAAM,SACJ,SAAS,aAAa,OAClB,cAAc,SAAS,SACvB,GAAG,SAAS,SAAS,WAAW,SAAS;CAE/C,MAAM,UAAU,WAAuB;EACrC,QAAQ,OAAO,YAAY,YAAY,YAAY,UAAU,OAAO,WAAW,MAAM;CACvF;CACA,MAAM,SAAS,YAAY;EACzB,IAAI,QAAQ;EACZ,QAAQ,KAAK;EACb,IAAI,WAAW;GACb,OAAO,MAAM,IAAI,OAAO,CAAC;GACzB;EACF;EACA,IAAI,WAAW,YAAY;GAEzB,IAAI,QAAQ;GACZ,MAAM,KAAK,mBAAmB;IAC5B,QAAQ;IACR,MAAM;GACR,CAAC,CAAC,CAAC;GACH,IAAI,OAAO,iBAAiB,IAAI;GAChC;EACF;EACA,IAAI,SAAS;EACb,IAAI,SAAS;GAGX,IAAI,YAAY;GAChB,MAAM,KAAK,mBAAmB;IAC5B,YAAY;IACZ,MAAM;GACR,CAAC,CAAC,CAAC;GACH,IAAI,CAAC,WAAW;EAClB;EACA,OAAO,MAAM,IAAI,OAAO,CAAC;CAC3B;CAEA,MAAM,aACJ,SAAS,aAAa,OAClB,cAAc,SAAS,KAAK,YAC5B,aAAa,SAAS,SAAS,WAAW,SAAS,KAAK;CAC9D,MAAM,eAAe,KAAK,IAAI,UAAU,IAAI,KAAK,EAAE,UAAU,IAAI,GAAG,MAAM;CAC1E,MAAM,UAAU,eACd,UACA,MACA,GACA,MACA,SAAS,SAAS,QAClB,SAAS,OACR,WAAW,WAAW,MAAM,QAAQ,QAAQ,CAC/C;CAGA,MAAM,iBAAiB,WACpB,KAAK,UACJ,yBACE;EACE,MAAM,MAAM,QAAQ;EACpB,SAAS,MAAM;EACf,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;CAC5D,GACA;EAAE,KAAK,KAAK;EAAK,GAAG,KAAK;CAAE,CAC7B,CACF,CAAC,CACA,QAAQ,SAAS,SAAS,OAAO;CAGpC,MAAM,aAAa,GAAG,SAAS,SAAS,OAAO;CAC/C,MAAM,cACH,KAAK,IAAI,UAAU,IAAI,KAAK,EAAE,UAAU,IAAI,KAAA,MAC7C,aAAa,QAAQ,SAAS,MAAM,SAAS,KAC7C,QAAQ,kBAAkB,EAAE,cAAc,SAAS,CAAC;CAEtD,MAAM,gBAAgB,SAAS,YAAY,cAAc,SAAS,eAAe;CACjF,MAAM,QAAQ,KAAK;CACnB,MAAM,WACJ,UAAU,QAAQ,MAAM,IAAI,WAAW,KAAK,MAAM,YAAY,MAAM,IAAI,MAAM,IAAI,SAAS;CAC7F,MAAM,aAAa,CAAC,WAAW,CAAC,cAAc,CAAC,WAAW,aAAa;CAEvE,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CAGxD,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,YAAY,SAAS,KAAK,OAAO,cAAc,KAAA;CACrD,MAAM,YAAY,WAAW,CAAC,aAAa,CAAC,SAAS;CACrD,MAAM,QAAQ,iBAA4C;EACxD,IAAI,CAAC,QAAQ,OAAY,CAAC,CAAC,KAAK,MAAM;CACxC;CAIA,MAAM,cAAc;EAClB,IAAI,QAAQ,SAAS,YAAY,WAAW,CAAC,SAAS,KAAK,MAAM,QAAQ;EACzE,QAAQ,MAAM;CAChB;CAEA,MAAM,aAAa,OAA2B,IAAI;CAClD,gBAAgB,UAAU;CAC1B,MAAM,UACJ,KAAC,MAAD;EACE,KAAK;EACL,UAAU;EACV,6BAA0B;EAC1B,WAAU;EAJZ,UAAA,CAMG,OACA,UAAU,KAAA,IAAY,OACrB,IAAC,QAAD;GAAM,WAAU;GAA0C,UAAA;EAAY,CAAA,CAEtE;;CAGN,OACE,KAAC,OAAD;EACE,eAAa,IAAI,SAAS,MAAM;EAChC,kBAAgB;EAChB,uBAAqB,SAAS;EAC9B,aAAW,SAAS,SAAS,KAAA;EAC7B,WAAU;EALZ,UAAA;GAOG,QAAQ,SAAS,WAAW,OAC3B,KAAC,OAAD;IAAK,oBAAiB;IAAc,WAAU;IAA9C,UAAA;KACG,WAAW,IAAC,gBAAgB,OAAjB;MAAuB,SAAA;MAAS,UAAA;KAA+B,CAAA,IAAI;KAC9E,SAAS,aAAa,OAAO,OAC5B,IAAC,SAAD;MACE,SAAS,GAAG,SAAS,SAAS,WAAW,SAAS;MAClD,MAAM;MACN,QAAQ,GAAG,IAAI,SAAS,MAAM,EAAE;KACjC,CAAA;KAEF,QAAQ,SAAS,YAChB,IAAC,QAAD;MACE,MAAK;MACL,SAAQ;MACR,MAAK;MACL,WAAU;MACV,eAAa,IAAI,UAAU,MAAM;MACjC,cAAY,EAAE,cAAc,EAAE,cAAc,QAAQ,CAAC;MACrD,SAAS;MAET,UAAA,IAAC,OAAD;OAAO,WAAU;OAAU,eAAY;MAAQ,CAAA;KACzC,CAAA,IACN;IACD;;GAEN,cAAc,OACb,IAAC,eAAD;IAAe,MAAM;IAAmB;IAAQ,QAAQ,IAAI,SAAS,MAAM;GAAI,CAAA,IAC7E;GACH,cAAc,QAAQ,QAAQ,SAAS,YACtC,IAAC,OAAD;IAAK,WAAU;IACb,UAAA,IAAC,QAAD;KACE,MAAK;KACL,SAAQ;KACR,eAAa,IAAI,UAAU,MAAM;KACjC,SAAS;KAER,UAAA,EAAE,aAAa,EAAE,cAAc,OAAO,CAAC;IAClC,CAAA;GACL,CAAA,IACH;GACJ,KAAC,QAAD;IACE,QAAQ,cAAc;IACtB,YAAA;IACA,WAAW,cAAc,OAAO,uCAAuC;IACvE,WAAW,UAAU;KACnB,MAAM,eAAe;KACrB,OAAY;IACd;IAPF,UAAA;KASE,KAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACG,YAAY,OAAO,OAClB,KAAC,OAAD;QACE,MAAM,WAAW,YAAY,cAAc,YAAY,WAAW,UAAU;QAC5E,eAAa,IAAI,YAAY,MAAM;QACnC,0BAAwB,OAAO,SAAU,WAAW,SAAS;QAC7D,WAAU;QAJZ,UAAA,CAME,IAAC,QAAD,EAAA,UAAO,QAAc,CAAA,GACpB,gBACC,IAAC,QAAD;SACE,MAAK;SACL,MAAK;SACL,SAAQ;SACR,WAAU;SACV,eAAe,IAAI,YAAY;SAE9B,UAAA,QAAQ,iBAAiB,EAAE,cAAc,QAAQ,CAAC;QAC7C,CAAA,IACN,IACD;;OAEN,WAAW,KAAK,MAAM,YAAY,SAAS,CAAC,WAAW,cACtD,KAAC,OAAD;QACE,eAAa,IAAI,UAAU,MAAM;QACjC,MAAK;QACL,aAAU;QACV,WAAU;QAJZ,UAAA,CAME,IAAC,QAAD;SAAM,WAAU;SACb,UAAA,EAAE,uBAAuB,EAAE,cAAc,iBAAiB,CAAC;QACxD,CAAA,GACN,KAAC,OAAD;SAAK,WAAU;SAAf,UAAA,CACE,IAAC,QAAD;UACE,MAAK;UACL,MAAK;UACL,SAAQ;UACR,eAAa,GAAG,IAAI,UAAU,MAAM,EAAE;UACtC,SAAS,KAAK,MAAM;UAEnB,UAAA,EAAE,iBAAiB,EAAE,cAAc,UAAU,CAAC;SACzC,CAAA,GACR,IAAC,QAAD;UACE,MAAK;UACL,MAAK;UACL,SAAQ;UACR,eAAa,GAAG,IAAI,UAAU,MAAM,EAAE;UACtC,SAAS,KAAK,MAAM;UAEnB,UAAA,EAAE,iBAAiB,EAAE,cAAc,UAAU,CAAC;SACzC,CAAA,CACL;QACF,CAAA,CAAA;OACH,CAAA,IAAA;OACH,eAAe,SAAS,IACvB,IAAC,OAAD;QACE,MAAK;QACL,eAAa,GAAG,IAAI,SAAS,MAAM,EAAE;QACrC,WAAU;QAET,UAAA,eAAe,KAAK,MAAM,UAEzB,IAAC,KAAD,EAAA,UAAgB,KAAQ,GAAhB,KAAgB,CACzB;OACE,CAAA,IACH;OACH,aAAa,SAAS,KAAK,WAAW,OACrC,IAAC,YAAD;QACQ;QACG;QACT,QAAQ,SAAS;QACjB,YAAY;QACZ,QAAQ,IAAI,SAAS,MAAM;OAC5B,CAAA,IACC,aAAa,MAAM,QAAQ,SAAS,KAAK,MAAM,IACjD,IAAC,YAAD;QACY;QACV,MAAM,SAAS,KAAK;QACpB,QAAQ,SAAS;QACT;QACH;QACL,GAAK,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;QAC1C,GAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;OACvC,CAAA,IACC,UACF,IAAC,qBAAD;QAAqB,OAAO;QAC1B,UAAA,IAAC,YAAD;SACE,QAAO;SACP,UAAU;SACV,MAAK;SACL,UAAU,KAAK;SACf,YAAY;SAGZ,SAAQ;SACR,UAAU,UAAW,WAAW,CAAC,cAAe,aAAa;QAC9D,CAAA;OACkB,CAAA,IACnB;OACH,aAAa,SAAS,SAAS,SAAS,IACvC,IAAC,MAAD;QACE,MAAK;QACL,oBAAiB;QACjB,WAAU;QAET,UAAA,SAAS,SAAS,KAAK,YACtB,IAAC,MAAD;SAAqB,eAAa,GAAG,IAAI,SAAS,MAAM,EAAE,WAAW,QAAQ;SAC1E,UAAA,QAAQ;QACP,GAFK,QAAQ,EAEb,CACL;OACC,CAAA,IACF;MACD;;KACJ,YACC,IAAC,KAAD;MAAG,eAAa,GAAG,IAAI,YAAY,MAAM,EAAE;MAAa,WAAU;MAC/D,UAAA,EAAE,yBAAyB,EAAE,cAAc,wCAAwC,CAAC;KACpF,CAAA,IACD;KACH,WAAW,gBACV,KAAC,OAAD;MACE,MAAK;MACL,cAAY,EAAE,kBAAkB,EAAE,cAAc,cAAc,CAAC;MAC/D,eAAa,GAAG,IAAI,cAAc,MAAM,EAAE;MAC1C,WAAU;MAJZ,UAAA,CAME,IAAC,QAAD,EAAA,UACG,EAAE,yBAAyB,EAC1B,cAAc,6DAChB,CAAC,EACG,CAAA,GACN,KAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,IAAC,QAAD;QACE,MAAK;QACL,MAAK;QACL,SAAQ;QACR,eAAa,GAAG,IAAI,cAAc,MAAM,EAAE;QAC1C,eAAe,iBAAiB,KAAK;QAEpC,UAAA;OACK,CAAA,GACR,IAAC,QAAD;QACE,MAAK;QACL,MAAK;QACL,SAAQ;QACR,eAAa,GAAG,IAAI,cAAc,MAAM,EAAE;QAC1C,eAAe;SACb,iBAAiB,KAAK;SACtB,WAAW,IAAI,UAAU,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC;QACjD;QAEC,UAAA,EAAE,kBAAkB,EAAE,cAAc,cAAc,CAAC;OAC9C,CAAA,CACL;MACF,CAAA,CAAA;KACH,CAAA,IAAA;KACH,UACC,KAAC,OAAD;MAAK,oBAAiB;MAAqB,WAAU;MAArD,UAAA;OACG,YACC,IAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,eAAa,IAAI,eAAe,MAAM;QACtC,UAAU;QACV,SAAS,WAAW,IAAI,WAAW,CAAC;QAEnC,UAAA,EAAE,mBAAmB,EAAE,cAAc,cAAc,CAAC;OAC/C,CAAA,IACN;OACH,SAAS,YACR,IAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,eAAa,IAAI,WAAW,MAAM;QAClC,UAAU;QACV,SAAS,WAAW,IAAI,OAAO,CAAC;QAE/B,UAAA,EAAE,eAAe,EAAE,cAAc,SAAS,CAAC;OACtC,CAAA,IACN;OACJ,IAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,eAAa,IAAI,cAAc,MAAM;QACrC,UAAU,UAAU,iBAAiB;QACrC,eAAe;SACb,IAAI,SAAS,cAAc,IAAI;cAC1B,iBAAiB,IAAI;QAC5B;QAEC,UAAA,EAAE,kBAAkB,EAAE,cAAc,cAAc,CAAC;OAC9C,CAAA;OACR,IAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,eAAa,IAAI,cAAc,MAAM;QACrC,UAAU;QACV,eAAe;SACb,IAAI,UAAU;SACd,YAAY;QACd;QAEC,UAAA,EAAE,kBAAkB,EAAE,cAAc,4BAA4B,CAAC;OAC5D,CAAA;MACL;KACH,CAAA,IAAA;KACJ,KAAC,OAAD;MAAK,oBAAiB;MAAc,WAAU;MAA9C,UAAA,CACG,aAAa,WAAW,CAAC,SACxB,IAAC,QAAD;OACE,MAAK;OACL,SAAQ;OACR,eAAa,IAAI,SAAS,MAAM;OAChC,eAAe,IAAI,KAAK;OAEvB,UAAA,EAAE,aAAa,EAAE,cAAc,OAAO,CAAC;MAClC,CAAA,IACN,MACJ,KAAC,OAAD;OAAK,WAAU;OAAf,UAAA;QACE,IAAC,QAAD;SACE,MAAK;SACL,SAAQ;SACR,eAAa,IAAI,WAAW,MAAM;SAClC,UAAU;SACV,SAAS;SAER,UAAA,UACG,EAAE,cAAc,EAAE,cAAc,QAAQ,CAAC,IACzC,QAAQ,SAAS,WACf,EAAE,cAAc,EAAE,cAAc,QAAQ,CAAC,IACzC;QACA,CAAA;QACP,WAAW,aACV,IAAC,QAAD;SACE,MAAK;SACL,SAAQ;SACR,eAAa,GAAG,IAAI,cAAc,MAAM,EAAE;SAC1C,UAAU,UAAU;SACpB,cAAc,UAAU,MAAM,eAAe;SAE5C,UAAA,EAAE,kBAAkB,EAAE,cAAc,cAAc,CAAC;QAC9C,CAAA,IACN;QACH,aACC,KAAC,QAAD;SACE,MAAK;SACL,SAAS,SAAS,KAAK,YAAY,gBAAgB,gBAAgB;SACnE,eAAa,IAAI,WAAW,MAAM;SAClC,UAAU,UAAU;SACpB,aAAW,SAAS,SAAS,KAAA;SAG7B,cAAc,UAAU,MAAM,eAAe;SAR/C,UAAA,CAUG,SACC,IAAC,aAAD;UAAa,WAAU;UAAuB,eAAY;SAAQ,CAAA,IAChE,MACH,SAAS,eAAe,KACnB;QACN,CAAA,IAAA;OACD;MACF,CAAA,CAAA;;IACD;;EACH;;AAET;AAGA,SAAS,gBAAgB,KAA4B;CACnD,OAAO,qBAAqB,IAAI,WAAW,IAAI,aAAa,IAAI,WAAW;AAC7E;AAEA,MAAM,YAAY,OAAO,OAAO,CAAC,CAAC;AAMlC,SAAS,WAAW,EAClB,UACA,MACA,QACA,QACA,KACA,QACA,QASe;CACf,MAAM,SAAS,SAAS,KAAK,MAAM;CAGnC,MAAM,MAAM,eAAe;EACzB,IAAI,WAAW,KAAA,GAAW,OAAO;EACjC,MAAM,SAAS,aAAa,IAAI;EAChC,OAAO,kBACJ,OAAwD,KAAK,UAC5D,OAAO,IAAI,OAAO,MAAM,IAAI,CAAC,IAAI,QAAQ;GAAE,GAAG;GAAO,IAAI,CAAC,QAAQ;EAAE,CACtE,CACF;CACF,CAAC,CAAC,CAAC;CACH,MAAM,OAAO,qBAAqB,IAAa,CAAC,CAAC;CAEjD,MAAM,SAAS,mBAAmB;CAIlC,MAAM,cAAc,mBAAmB,QAAQ,MAAM,SAAS,QAAQ;CACtE,MAAM,SAAS,kBAAkB;EAC/B;EACA,SAAS;EACT,QAAQ,SAAS;EACjB;EACA,QAAQ;EACR,QAAQ;EACR;EACA,MAAM;EACN,YAAY;EACZ,OAAO;CACT,CAAC;CACD,OACE,IAAC,YAAD;EACE,QAAO;EACP,UAAU;EACV,MAAK;EACL,UAAU,OAAO;EACjB,YAAY;EACZ,SAAQ;CACT,CAAA;AAEL;AAGA,SAAS,aAAa,MAA+C;CACnE,MAAM,MAAM,IAAI,IAAY;CAC5B,MAAM,QAAQ,SAAwB;EACpC,IAAI,OAAO,SAAS,UAAU;GAC5B,IAAI,IAAI,IAAI;GACZ;EACF;EACA,IAAI,SAAS,QAAQ,OAAO,SAAS,UAAU;EAC/C,MAAM,WAAY,KAAyC;EAC3D,IAAI,MAAM,QAAQ,QAAQ,GAAG,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK;CACvE;CACA,KAAK,MAAM,QAAQ,MAAM,KAAK,IAAI;CAClC,OAAO;AACT;AAGA,SAAS,UAAU,MAA8E;CAC/F,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO,MAAM,OAAO,GAAG,OAAO;CACvF,MAAM,EAAE,OAAO,UAAU;CACzB,MAAM,MACJ,UAAU,QAAQ,OAAO,UAAU,YAAY,SAAS,QACnD,MAAoC,MACrC;CACN,IACE,QAAQ,QACR,OAAO,QAAQ,YACf,OAAQ,IAAsB,cAAc,YAC5C,OAAQ,IAAsB,OAAO,UAErC,OAAO;CACT,OAAO;EACL,OAAO;EACP,OAAO,UAAU,QAAQ,OAAO,UAAU,WAAY,QAAgB,CAAC;CACzE;AACF;AAaA,SAAS,cAAc,EACrB,MACA,UAKe;CACf,MAAM,IAAI,aAAa;CACvB,MAAM,KAAK,GAAG,KAAK,MAAM,UAAU,GAAG,KAAK,MAAM;CACjD,MAAM,iBAAiB,qBAAqB,IAAI,0BAA0B,EAAE,CAAU;CACtF,MAAM,CAAC,YAAY,iBAAiB,eAClC,mBAAmB,KAAA,IACf,OACA,uBAAuB,eAAe,YAAqB,KAAK,KAAK,CAC3E;CACA,gBAAgB;EACd,IAAI,YAAY,WAAW,WAAW;EACtC,IAAI,OAAO;EACX,WAAgB,QAAQ,MAAM,YAAY;GACxC,IAAI,MAAM,cAAc,OAAO;EACjC,CAAC;EACD,aAAa;GACX,OAAO;EACT;CACF,GAAG,CAAC,UAAU,CAAC;CACf,MAAM,SAAS,mBAAmB,KAAA,KAAa,YAAY,WAAW;CACtE,MAAM,OAAO,mBAAmB,KAAA,IAAY,OAAO,OAAO,cAAc;CACxE,OACE,IAAC,OAAD;EACE,eAAa,GAAG,OAAO;EACvB,mBAAiB;EACjB,WAAU;EAET,UAAA,SACC,IAAC,KAAD;GAAG,MAAK;GAAQ,WAAU;GACvB,UAAA,EAAE,wBAAwB,EAAE,cAAc,iCAAiC,CAAC;EAC5E,CAAA,IACD,SAAS,QAAQ,YAAY,WAAW,UAAU,OACpD,IAAC,UAAD;GAAU,UAAU;GAClB,UAAA,IAAC,MAAD;IACE,OAAO,WAAW;IAClB,MAAM;IACN,IAAI,KAAK,YACP,EAAE,UAAU,GAAG,GAAG,OAAO;KACvB,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;KAClE,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;IACjE,CAAC;GAEJ,CAAA;EACO,CAAA;CAET,CAAA;AAET"}
|