@fayz-ai/admin 0.62.0 → 0.65.2
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/dist/{CommandPalette-B5PMQFDG.js → CommandPalette-XDJJ5E3O.js} +3 -3
- package/dist/{CommandPalette-B5PMQFDG.js.map → CommandPalette-XDJJ5E3O.js.map} +1 -1
- package/dist/ConnectedBrandingSettings-43ZM3HCI.js +680 -0
- package/dist/ConnectedBrandingSettings-43ZM3HCI.js.map +1 -0
- package/dist/ConnectedCompanySettings-I4MALI2Q.js +197 -0
- package/dist/ConnectedCompanySettings-I4MALI2Q.js.map +1 -0
- package/dist/ConnectedModulesSettings-A2VJ5BMJ.js +563 -0
- package/dist/ConnectedModulesSettings-A2VJ5BMJ.js.map +1 -0
- package/dist/ConnectedSecuritySettings-25AHA4HJ.js +189 -0
- package/dist/ConnectedSecuritySettings-25AHA4HJ.js.map +1 -0
- package/dist/ConnectedUserProfile-E7USJRUE.js +424 -0
- package/dist/ConnectedUserProfile-E7USJRUE.js.map +1 -0
- package/dist/FieldRulesEditor-YGIPKI5T.js +129 -0
- package/dist/FieldRulesEditor-YGIPKI5T.js.map +1 -0
- package/dist/GettingStartedWidget-HMIJ3Y24.js +12 -0
- package/dist/GettingStartedWidget-HMIJ3Y24.js.map +1 -0
- package/dist/PermissionProfilesTab-3ZPRCHMZ.js +548 -0
- package/dist/PermissionProfilesTab-3ZPRCHMZ.js.map +1 -0
- package/dist/PersonTimeline-HQZT527S.js +3 -0
- package/dist/{PersonTimeline-X7JTPUWJ.js.map → PersonTimeline-HQZT527S.js.map} +1 -1
- package/dist/ProjectsSettings-7O2F27MD.js +5 -0
- package/dist/ProjectsSettings-7O2F27MD.js.map +1 -0
- package/dist/ScheduleEditor-54ELWR45.js +8 -0
- package/dist/{ScheduleEditor-L2UJXKMY.js.map → ScheduleEditor-54ELWR45.js.map} +1 -1
- package/dist/SeuSiteWidget-QLSUVC63.js +6 -0
- package/dist/SeuSiteWidget-QLSUVC63.js.map +1 -0
- package/dist/SubscriptionPage-5GE5HFJK.js +17 -0
- package/dist/{SubscriptionPage-IDVEFLZ5.js.map → SubscriptionPage-5GE5HFJK.js.map} +1 -1
- package/dist/TeamTab-6RAULFLW.js +502 -0
- package/dist/TeamTab-6RAULFLW.js.map +1 -0
- package/dist/TrialWidget-Z6CLUCU3.js +7 -0
- package/dist/TrialWidget-Z6CLUCU3.js.map +1 -0
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/app/config.d.ts +14 -0
- package/dist/app/config.d.ts.map +1 -1
- package/dist/app/routing.d.ts +6 -0
- package/dist/app/routing.d.ts.map +1 -1
- package/dist/app/scaffold.d.ts.map +1 -1
- package/dist/billing/index.js +9 -4
- package/dist/chunk-2H46WDG5.js +53 -0
- package/dist/chunk-2H46WDG5.js.map +1 -0
- package/dist/chunk-3HLX7YB2.js +94 -0
- package/dist/chunk-3HLX7YB2.js.map +1 -0
- package/dist/chunk-3OUD4XBK.js +3 -0
- package/dist/chunk-3OUD4XBK.js.map +1 -0
- package/dist/{chunk-IXSY4GPK.js → chunk-5D5QLMOQ.js} +5 -3
- package/dist/chunk-5D5QLMOQ.js.map +1 -0
- package/dist/chunk-5WR62X2R.js +1081 -0
- package/dist/chunk-5WR62X2R.js.map +1 -0
- package/dist/{chunk-KPYRTOCK.js → chunk-6CQFGMEO.js} +4 -140
- package/dist/chunk-6CQFGMEO.js.map +1 -0
- package/dist/chunk-6MMSYC2I.js +116 -0
- package/dist/chunk-6MMSYC2I.js.map +1 -0
- package/dist/chunk-6QFOE3UD.js +1466 -0
- package/dist/chunk-6QFOE3UD.js.map +1 -0
- package/dist/chunk-6UUFVQ2E.js +283 -0
- package/dist/chunk-6UUFVQ2E.js.map +1 -0
- package/dist/chunk-7WNLL3F6.js +7889 -0
- package/dist/chunk-7WNLL3F6.js.map +1 -0
- package/dist/chunk-A74IHAQE.js +439 -0
- package/dist/chunk-A74IHAQE.js.map +1 -0
- package/dist/{chunk-JOBRLBIQ.js → chunk-AFA6IO23.js} +4 -3
- package/dist/chunk-AFA6IO23.js.map +1 -0
- package/dist/{chunk-P5UIGQFY.js → chunk-ALCSIN3Z.js} +5 -5
- package/dist/chunk-ALCSIN3Z.js.map +1 -0
- package/dist/chunk-AWM4AMBS.js +39 -0
- package/dist/chunk-AWM4AMBS.js.map +1 -0
- package/dist/{chunk-OQARLKZN.js → chunk-BG5Z6KLN.js} +6 -18
- package/dist/chunk-BG5Z6KLN.js.map +1 -0
- package/dist/chunk-DPNFZONC.js +19 -0
- package/dist/chunk-DPNFZONC.js.map +1 -0
- package/dist/chunk-DRCV643L.js +193 -0
- package/dist/chunk-DRCV643L.js.map +1 -0
- package/dist/chunk-E6DF3VR6.js +206 -0
- package/dist/chunk-E6DF3VR6.js.map +1 -0
- package/dist/chunk-ENHCVGXZ.js +120 -0
- package/dist/chunk-ENHCVGXZ.js.map +1 -0
- package/dist/chunk-FK6RHGI7.js +56 -0
- package/dist/chunk-FK6RHGI7.js.map +1 -0
- package/dist/chunk-G5HNA5QK.js +233 -0
- package/dist/chunk-G5HNA5QK.js.map +1 -0
- package/dist/chunk-HCFO4Z6A.js +53 -0
- package/dist/chunk-HCFO4Z6A.js.map +1 -0
- package/dist/chunk-JFIU6NQP.js +51 -0
- package/dist/chunk-JFIU6NQP.js.map +1 -0
- package/dist/chunk-JRZJBMOY.js +3 -0
- package/dist/chunk-JRZJBMOY.js.map +1 -0
- package/dist/{chunk-3YP7KW47.js → chunk-JVVOL4BB.js} +41 -512
- package/dist/chunk-JVVOL4BB.js.map +1 -0
- package/dist/chunk-KAQ3UIAA.js +415 -0
- package/dist/chunk-KAQ3UIAA.js.map +1 -0
- package/dist/{chunk-P6XUDT2P.js → chunk-KJELMULA.js} +4 -51
- package/dist/chunk-KJELMULA.js.map +1 -0
- package/dist/chunk-KLO7DKXX.js +1651 -0
- package/dist/chunk-KLO7DKXX.js.map +1 -0
- package/dist/chunk-M2CMDWUI.js +75 -0
- package/dist/chunk-M2CMDWUI.js.map +1 -0
- package/dist/chunk-PQ47MLTH.js +255 -0
- package/dist/chunk-PQ47MLTH.js.map +1 -0
- package/dist/{chunk-VX3WJLKK.js → chunk-QD7BMUDF.js} +17 -8
- package/dist/chunk-QD7BMUDF.js.map +1 -0
- package/dist/{chunk-E4MESMNR.js → chunk-QTSKCPSW.js} +7 -10
- package/dist/chunk-QTSKCPSW.js.map +1 -0
- package/dist/chunk-S56FQKPL.js +186 -0
- package/dist/chunk-S56FQKPL.js.map +1 -0
- package/dist/chunk-SGAFPNMA.js +75 -0
- package/dist/chunk-SGAFPNMA.js.map +1 -0
- package/dist/{chunk-OD7P4L3D.js → chunk-SOKCLVM4.js} +3 -3
- package/dist/{chunk-OD7P4L3D.js.map → chunk-SOKCLVM4.js.map} +1 -1
- package/dist/chunk-TL42NKTH.js +3 -0
- package/dist/chunk-TL42NKTH.js.map +1 -0
- package/dist/chunk-U6ZCO2PS.js +2964 -0
- package/dist/chunk-U6ZCO2PS.js.map +1 -0
- package/dist/chunk-VSXNROYH.js +16 -0
- package/dist/chunk-VSXNROYH.js.map +1 -0
- package/dist/chunk-WPFZCYZL.js +619 -0
- package/dist/chunk-WPFZCYZL.js.map +1 -0
- package/dist/chunk-XFTNIBDW.js +23 -0
- package/dist/chunk-XFTNIBDW.js.map +1 -0
- package/dist/chunk-Y66JDL6I.js +1020 -0
- package/dist/chunk-Y66JDL6I.js.map +1 -0
- package/dist/chunk-YEHIBPIX.js +137 -0
- package/dist/chunk-YEHIBPIX.js.map +1 -0
- package/dist/chunk-YKPPCV2Z.js +53 -0
- package/dist/chunk-YKPPCV2Z.js.map +1 -0
- package/dist/components/chat/markdown.d.ts.map +1 -1
- package/dist/components/plugins/PluginSettingsPanel.d.ts.map +1 -1
- package/dist/components/settings/SettingsPage.d.ts.map +1 -1
- package/dist/connect-XKQJOWR7.js +18 -0
- package/dist/connect-XKQJOWR7.js.map +1 -0
- package/dist/crud/CrudDetailPage.d.ts.map +1 -1
- package/dist/crud/CrudListView.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/RelatedListTab.d.ts.map +1 -1
- package/dist/crud/archetypes/EntityLink.d.ts +1 -1
- package/dist/crud/archetypes/EntityLink.d.ts.map +1 -1
- package/dist/crud/record-chrome.d.ts.map +1 -1
- package/dist/entity-routes-PGU7EHAD.js +4 -0
- package/dist/{entity-routes-LXOBW5IB.js.map → entity-routes-PGU7EHAD.js.map} +1 -1
- package/dist/hooks/useModuleNavigation.d.ts.map +1 -1
- package/dist/impersonation/ImpersonateDialog.d.ts.map +1 -1
- package/dist/impersonation/session.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11951 -33576
- package/dist/index.js.map +1 -1
- package/dist/lib/attention.d.ts +6 -0
- package/dist/lib/attention.d.ts.map +1 -1
- package/dist/lib/entity-routes.d.ts.map +1 -1
- package/dist/org/index.js +4 -2
- package/dist/plugins/PluginRegistryManager.d.ts.map +1 -1
- package/dist/settings/MessageTemplateRow.d.ts.map +1 -1
- package/dist/timeline/PersonTimeline.d.ts.map +1 -1
- package/dist/timeline/TimelineList.d.ts.map +1 -1
- package/dist/units/UnitRailPage.d.ts.map +1 -1
- package/dist/units/useUnitFilter.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/PersonTimeline-X7JTPUWJ.js +0 -3
- package/dist/ScheduleEditor-L2UJXKMY.js +0 -6
- package/dist/SubscriptionPage-IDVEFLZ5.js +0 -8
- package/dist/chunk-3YP7KW47.js.map +0 -1
- package/dist/chunk-E4MESMNR.js.map +0 -1
- package/dist/chunk-IXSY4GPK.js.map +0 -1
- package/dist/chunk-JOBRLBIQ.js.map +0 -1
- package/dist/chunk-KPYRTOCK.js.map +0 -1
- package/dist/chunk-OQARLKZN.js.map +0 -1
- package/dist/chunk-P5UIGQFY.js.map +0 -1
- package/dist/chunk-P6XUDT2P.js.map +0 -1
- package/dist/chunk-VX3WJLKK.js.map +0 -1
- package/dist/entity-routes-LXOBW5IB.js +0 -4
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import { useMemberAccessPanel, MemberUnitsCell, startImpersonation } from './chunk-5WR62X2R.js';
|
|
2
|
+
import './chunk-JFIU6NQP.js';
|
|
3
|
+
import './chunk-YEHIBPIX.js';
|
|
4
|
+
import { useInviteStore, useSystemPermission } from './chunk-7WNLL3F6.js';
|
|
5
|
+
import './chunk-AWM4AMBS.js';
|
|
6
|
+
import './chunk-6QFOE3UD.js';
|
|
7
|
+
import './chunk-FK6RHGI7.js';
|
|
8
|
+
import { PageActions } from './chunk-PQ47MLTH.js';
|
|
9
|
+
import { useUnitBootstrap } from './chunk-DPNFZONC.js';
|
|
10
|
+
import './chunk-E6DF3VR6.js';
|
|
11
|
+
import './chunk-HCFO4Z6A.js';
|
|
12
|
+
import { useLimitGuard, invalidateLimit } from './chunk-S56FQKPL.js';
|
|
13
|
+
import { useTranslation } from './chunk-YUHCC7JY.js';
|
|
14
|
+
import { toast } from './chunk-3OUD4XBK.js';
|
|
15
|
+
import './chunk-VSXNROYH.js';
|
|
16
|
+
import './chunk-M2CMDWUI.js';
|
|
17
|
+
import './chunk-6CQFGMEO.js';
|
|
18
|
+
import { openEntity, entityRouteHasDetail } from './chunk-ALCSIN3Z.js';
|
|
19
|
+
import './chunk-BG5Z6KLN.js';
|
|
20
|
+
import './chunk-SGAFPNMA.js';
|
|
21
|
+
import './chunk-KLO7DKXX.js';
|
|
22
|
+
import './chunk-TL42NKTH.js';
|
|
23
|
+
import { dedup, useUnitStore, useOrgAdapterOptional } from './chunk-5D5QLMOQ.js';
|
|
24
|
+
import { usePermissionsStore } from './chunk-UQ2NTFQC.js';
|
|
25
|
+
import './chunk-KJELMULA.js';
|
|
26
|
+
import './chunk-JRZJBMOY.js';
|
|
27
|
+
import { useOrganizationStore } from './chunk-YKPPCV2Z.js';
|
|
28
|
+
import './chunk-QD7BMUDF.js';
|
|
29
|
+
import * as React3 from 'react';
|
|
30
|
+
import { UserPlus, Contact, Building2, Eye, UserMinus, Mail, Clock, Send, Ban, X, Plus } from 'lucide-react';
|
|
31
|
+
import { Avatar, AvatarImage, AvatarFallback, Badge, Button, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, RowActions, PageHeaderActions, Card, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, Input, ModalFooter } from '@fayz-ai/ui';
|
|
32
|
+
import { useAuthStore } from '@fayz-ai/auth';
|
|
33
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
34
|
+
import { currentAppPath } from '@fayz-ai/core';
|
|
35
|
+
|
|
36
|
+
var useOrgAdapterOptional2 = () => useOrgAdapterOptional();
|
|
37
|
+
function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
38
|
+
const { t } = useTranslation();
|
|
39
|
+
const adapter = useOrgAdapterOptional2();
|
|
40
|
+
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
41
|
+
const profiles = usePermissionsStore((s) => s.profiles);
|
|
42
|
+
const setInvites = useInviteStore((s) => s.setInvites);
|
|
43
|
+
const { user } = useAuthStore();
|
|
44
|
+
const [emails, setEmails] = React3.useState([defaultEmail ?? ""]);
|
|
45
|
+
const [profileId, setProfileId] = React3.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
46
|
+
const [sending, setSending] = React3.useState(false);
|
|
47
|
+
const [sent, setSent] = React3.useState(false);
|
|
48
|
+
React3.useEffect(() => {
|
|
49
|
+
if (open) setEmails([defaultEmail ?? ""]);
|
|
50
|
+
}, [open, defaultEmail]);
|
|
51
|
+
React3.useEffect(() => {
|
|
52
|
+
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
53
|
+
}, [profiles, profileId]);
|
|
54
|
+
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
55
|
+
const updateEmail = (idx, value) => {
|
|
56
|
+
setEmails((prev) => {
|
|
57
|
+
const next = [...prev];
|
|
58
|
+
next[idx] = value;
|
|
59
|
+
return next;
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const removeEmail = (idx) => {
|
|
63
|
+
setEmails((prev) => prev.filter((_, i) => i !== idx));
|
|
64
|
+
};
|
|
65
|
+
const handleSend = async () => {
|
|
66
|
+
if (!adapter || !currentOrg || !user) return;
|
|
67
|
+
const validEmails = emails.filter((e) => e.trim() && e.includes("@"));
|
|
68
|
+
if (validEmails.length === 0) return;
|
|
69
|
+
setSending(true);
|
|
70
|
+
try {
|
|
71
|
+
if (validEmails.length === 1) {
|
|
72
|
+
await adapter.createInvite(currentOrg.id, validEmails[0].trim(), profileId, user.id);
|
|
73
|
+
} else {
|
|
74
|
+
await adapter.bulkInvite(currentOrg.id, validEmails.map((e) => e.trim()), profileId, user.id);
|
|
75
|
+
}
|
|
76
|
+
const invites = await adapter.listInvites(currentOrg.id);
|
|
77
|
+
setInvites(invites);
|
|
78
|
+
setSent(true);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
toast.error("Failed to send invites", { description: err?.message });
|
|
81
|
+
} finally {
|
|
82
|
+
setSending(false);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const handleClose = () => {
|
|
86
|
+
onOpenChange(false);
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
setEmails([""]);
|
|
89
|
+
setProfileId(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
90
|
+
setSent(false);
|
|
91
|
+
}, 200);
|
|
92
|
+
};
|
|
93
|
+
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(ModalContent, { children: [
|
|
94
|
+
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
95
|
+
/* @__PURE__ */ jsx(ModalTitle, { children: t("organization.invite.title") }),
|
|
96
|
+
/* @__PURE__ */ jsx(ModalDescription, { children: t("organization.invite.description") })
|
|
97
|
+
] }),
|
|
98
|
+
sent ? /* @__PURE__ */ jsxs("div", { className: "py-8 text-center", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("div", { className: "mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-success/10", children: /* @__PURE__ */ jsx("svg", { className: "h-6 w-6 text-success", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 12.75l6 6 9-13.5" }) }) }),
|
|
100
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: t("organization.invite.sent") }),
|
|
101
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: t("organization.invite.sentDescription") })
|
|
102
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "space-y-4 py-4", children: [
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
104
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("organization.invite.emailLabel") }),
|
|
105
|
+
emails.map((email, idx) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
106
|
+
/* @__PURE__ */ jsx(
|
|
107
|
+
Input,
|
|
108
|
+
{
|
|
109
|
+
type: "email",
|
|
110
|
+
placeholder: "team@example.com",
|
|
111
|
+
value: email,
|
|
112
|
+
onChange: (e) => updateEmail(idx, e.target.value)
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
emails.length > 1 && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => removeEmail(idx), children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }) })
|
|
116
|
+
] }, idx)),
|
|
117
|
+
/* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: addEmail, className: "text-xs", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5 mr-1" }),
|
|
119
|
+
t("organization.invite.addAnother")
|
|
120
|
+
] })
|
|
121
|
+
] }),
|
|
122
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
123
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("organization.invite.roleLabel") }),
|
|
124
|
+
/* @__PURE__ */ jsxs(Select, { value: profileId, onValueChange: setProfileId, children: [
|
|
125
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("organization.invite.rolePlaceholder") }) }),
|
|
126
|
+
/* @__PURE__ */ jsx(SelectContent, { children: profiles.map((p) => /* @__PURE__ */ jsx(SelectItem, { value: p.id, children: p.name }, p.id)) })
|
|
127
|
+
] })
|
|
128
|
+
] })
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsx(ModalFooter, { children: sent ? /* @__PURE__ */ jsx(Button, { onClick: handleClose, children: t("common.done") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
131
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleClose, children: t("common.cancel") }),
|
|
132
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleSend, disabled: sending || emails.every((e) => !e.trim()), children: sending ? t("organization.invite.sending") : t("organization.invite.sendInvites") })
|
|
133
|
+
] }) })
|
|
134
|
+
] }) });
|
|
135
|
+
}
|
|
136
|
+
function ImpersonateDialog({ tenantId, target, onClose }) {
|
|
137
|
+
const { t } = useTranslation();
|
|
138
|
+
const [reason, setReason] = React3.useState("");
|
|
139
|
+
const [busy, setBusy] = React3.useState(false);
|
|
140
|
+
const [error, setError] = React3.useState(null);
|
|
141
|
+
React3.useEffect(() => {
|
|
142
|
+
if (target) {
|
|
143
|
+
setReason("");
|
|
144
|
+
setError(null);
|
|
145
|
+
setBusy(false);
|
|
146
|
+
}
|
|
147
|
+
}, [target]);
|
|
148
|
+
async function enter() {
|
|
149
|
+
if (!target) return;
|
|
150
|
+
setBusy(true);
|
|
151
|
+
setError(null);
|
|
152
|
+
try {
|
|
153
|
+
await startImpersonation({
|
|
154
|
+
tenantId,
|
|
155
|
+
userId: target.userId,
|
|
156
|
+
reason: reason.trim() || void 0,
|
|
157
|
+
returnTo: currentAppPath()
|
|
158
|
+
});
|
|
159
|
+
} catch (err) {
|
|
160
|
+
setError(err.message || t("impersonation.failed"));
|
|
161
|
+
setBusy(false);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return /* @__PURE__ */ jsx(Modal, { open: !!target, onOpenChange: (open) => {
|
|
165
|
+
if (!open && !busy) onClose();
|
|
166
|
+
}, children: /* @__PURE__ */ jsxs(ModalContent, { children: [
|
|
167
|
+
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
168
|
+
/* @__PURE__ */ jsx(ModalTitle, { children: t("impersonation.confirmTitle", { name: target?.name ?? "" }) }),
|
|
169
|
+
/* @__PURE__ */ jsx(ModalDescription, { children: t("impersonation.confirmBody") })
|
|
170
|
+
] }),
|
|
171
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
172
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("impersonation.reasonLabel") }),
|
|
173
|
+
/* @__PURE__ */ jsx(Input, { value: reason, onChange: (e) => setReason(e.target.value), disabled: busy }),
|
|
174
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error })
|
|
175
|
+
] }),
|
|
176
|
+
/* @__PURE__ */ jsxs(ModalFooter, { children: [
|
|
177
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onClose, disabled: busy, children: t("common.cancel") }),
|
|
178
|
+
/* @__PURE__ */ jsxs(Button, { onClick: () => {
|
|
179
|
+
void enter();
|
|
180
|
+
}, disabled: busy, children: [
|
|
181
|
+
/* @__PURE__ */ jsx(Eye, { className: "mr-2 h-4 w-4" }),
|
|
182
|
+
t("impersonation.confirm")
|
|
183
|
+
] })
|
|
184
|
+
] })
|
|
185
|
+
] }) });
|
|
186
|
+
}
|
|
187
|
+
var useOrgAdapterOptional3 = () => useOrgAdapterOptional();
|
|
188
|
+
var capitalize = (s) => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
|
|
189
|
+
function TeamTab() {
|
|
190
|
+
const adapter = useOrgAdapterOptional3();
|
|
191
|
+
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
192
|
+
const members = useOrganizationStore((s) => s.members);
|
|
193
|
+
const setMembers = useOrganizationStore((s) => s.setMembers);
|
|
194
|
+
const teamPersonKinds = useOrganizationStore((s) => s.teamPersonKinds);
|
|
195
|
+
const profiles = usePermissionsStore((s) => s.profiles);
|
|
196
|
+
const invites = useInviteStore((s) => s.invites);
|
|
197
|
+
const setInvites = useInviteStore((s) => s.setInvites);
|
|
198
|
+
const { user } = useAuthStore();
|
|
199
|
+
const hasSystemPermission = useSystemPermission();
|
|
200
|
+
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
201
|
+
const [team, setTeam] = React3.useState(null);
|
|
202
|
+
const [inviteOpen, setInviteOpen] = React3.useState(false);
|
|
203
|
+
const guardSeats = useLimitGuard("users");
|
|
204
|
+
const [inviteEmail, setInviteEmail] = React3.useState(void 0);
|
|
205
|
+
const handleOpenInvite = async (row) => {
|
|
206
|
+
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
207
|
+
openEntity(row.personId, "person", row.kind, "access");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (await guardSeats(1) === "blocked") return;
|
|
211
|
+
setInviteEmail(row?.email || void 0);
|
|
212
|
+
setInviteOpen(true);
|
|
213
|
+
};
|
|
214
|
+
const reloadTeam = React3.useCallback(async () => {
|
|
215
|
+
if (!adapter || !currentOrg) return;
|
|
216
|
+
if (personMode && adapter.listTeam) {
|
|
217
|
+
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
218
|
+
} else {
|
|
219
|
+
setMembers(await adapter.listMembers(currentOrg.id));
|
|
220
|
+
}
|
|
221
|
+
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
222
|
+
React3.useEffect(() => {
|
|
223
|
+
if (personMode && adapter?.listTeam && currentOrg) {
|
|
224
|
+
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
225
|
+
}
|
|
226
|
+
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
227
|
+
React3.useEffect(() => {
|
|
228
|
+
if (adapter && currentOrg) {
|
|
229
|
+
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}, [adapter, currentOrg?.id]);
|
|
233
|
+
const handleChangeProfile = async (memberId, profileId) => {
|
|
234
|
+
if (!adapter || !currentOrg) return;
|
|
235
|
+
try {
|
|
236
|
+
await adapter.updateMemberProfile(currentOrg.id, memberId, profileId);
|
|
237
|
+
await reloadTeam();
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const handleRemoveMember = async (memberId) => {
|
|
242
|
+
if (!adapter || !currentOrg) return;
|
|
243
|
+
try {
|
|
244
|
+
await adapter.removeMember(currentOrg.id, memberId);
|
|
245
|
+
await reloadTeam();
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
useUnitBootstrap();
|
|
250
|
+
const unitMode = useUnitStore((st) => st.unitMode);
|
|
251
|
+
const openMemberAccess = useMemberAccessPanel((st) => st.openMember);
|
|
252
|
+
const rows = personMode ? (team ?? []).map((p) => ({
|
|
253
|
+
// Login-only rows carry no personId — key off the membership instead.
|
|
254
|
+
key: p.personId ?? p.membership?.memberId ?? p.name,
|
|
255
|
+
personId: p.personId,
|
|
256
|
+
kind: p.kind,
|
|
257
|
+
name: p.name,
|
|
258
|
+
email: p.email ?? "",
|
|
259
|
+
avatarUrl: p.avatarUrl,
|
|
260
|
+
subtitle: p.kind ? capitalize(p.kind) : void 0,
|
|
261
|
+
roleId: p.membership?.profileId,
|
|
262
|
+
roleName: p.membership?.profileName,
|
|
263
|
+
memberId: p.membership?.memberId,
|
|
264
|
+
userId: p.membership?.userId,
|
|
265
|
+
hasAccess: !!p.membership,
|
|
266
|
+
joinedAt: p.membership?.joinedAt,
|
|
267
|
+
isCurrentUser: p.membership?.userId === user?.id
|
|
268
|
+
})) : members.map((m) => ({
|
|
269
|
+
key: m.id,
|
|
270
|
+
personId: m.personId,
|
|
271
|
+
kind: m.personKind,
|
|
272
|
+
name: m.user.fullName,
|
|
273
|
+
email: m.user.email,
|
|
274
|
+
avatarUrl: m.user.avatarUrl,
|
|
275
|
+
roleId: m.profileId,
|
|
276
|
+
roleName: m.profileName,
|
|
277
|
+
memberId: m.id,
|
|
278
|
+
userId: m.userId,
|
|
279
|
+
hasAccess: true,
|
|
280
|
+
joinedAt: m.joinedAt,
|
|
281
|
+
isCurrentUser: m.userId === user?.id
|
|
282
|
+
}));
|
|
283
|
+
const rowsLoading = personMode ? team === null : members.length === 0;
|
|
284
|
+
const handleRevokeInvite = async (inviteId) => {
|
|
285
|
+
if (!adapter || !currentOrg) return;
|
|
286
|
+
try {
|
|
287
|
+
await adapter.revokeInvite(currentOrg.id, inviteId);
|
|
288
|
+
const updated = await adapter.listInvites(currentOrg.id);
|
|
289
|
+
setInvites(updated);
|
|
290
|
+
toast.success(t("organization.team.inviteRevoked"));
|
|
291
|
+
} catch (err) {
|
|
292
|
+
toast.error(t("organization.team.inviteActionFailed"), { description: err?.message });
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const handleResendInvite = async (inviteId) => {
|
|
296
|
+
if (!adapter || !currentOrg) return;
|
|
297
|
+
try {
|
|
298
|
+
await adapter.resendInvite(currentOrg.id, inviteId);
|
|
299
|
+
const updated = await adapter.listInvites(currentOrg.id);
|
|
300
|
+
setInvites(updated);
|
|
301
|
+
toast.success(t("organization.team.inviteResent"));
|
|
302
|
+
} catch (err) {
|
|
303
|
+
toast.error(t("organization.team.inviteActionFailed"), { description: err?.message });
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
const { t } = useTranslation();
|
|
307
|
+
const canManageTeam = hasSystemPermission("manage_team");
|
|
308
|
+
const [viewAs, setViewAs] = React3.useState(null);
|
|
309
|
+
const inviteActions = React3.useMemo(() => [{
|
|
310
|
+
id: "invite",
|
|
311
|
+
label: t("organization.team.invite"),
|
|
312
|
+
icon: UserPlus,
|
|
313
|
+
intent: "primary",
|
|
314
|
+
// Inviting IS how a person gets added here, so the phone's circle is a "+".
|
|
315
|
+
creates: true,
|
|
316
|
+
onSelect: () => {
|
|
317
|
+
void handleOpenInvite();
|
|
318
|
+
}
|
|
319
|
+
}], [t]);
|
|
320
|
+
const pendingInvites = invites.filter((i) => i.status === "pending");
|
|
321
|
+
const columns = [
|
|
322
|
+
{
|
|
323
|
+
id: "member",
|
|
324
|
+
header: t("organization.team.member"),
|
|
325
|
+
cell: ({ row: { original: row } }) => {
|
|
326
|
+
const initials = (row.name || "?").split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
327
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
328
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8", children: [
|
|
329
|
+
row.avatarUrl && /* @__PURE__ */ jsx(AvatarImage, { src: row.avatarUrl }),
|
|
330
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "text-xs", children: initials })
|
|
331
|
+
] }),
|
|
332
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
333
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm font-medium", children: [
|
|
334
|
+
row.name,
|
|
335
|
+
row.isCurrentUser && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground ml-1", children: t("organization.team.you") }),
|
|
336
|
+
row.subtitle && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "ml-2 text-[10px] font-normal", children: row.subtitle })
|
|
337
|
+
] }),
|
|
338
|
+
row.email && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: row.email })
|
|
339
|
+
] })
|
|
340
|
+
] });
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
id: "role",
|
|
345
|
+
header: t("organization.team.role"),
|
|
346
|
+
cell: ({ row: { original: row } }) => !row.hasAccess ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
347
|
+
/* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs text-muted-foreground", children: t("organization.team.noAccess") }),
|
|
348
|
+
canManageTeam && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "h-7 text-xs", onClick: () => {
|
|
349
|
+
void handleOpenInvite(row);
|
|
350
|
+
}, children: [
|
|
351
|
+
/* @__PURE__ */ jsx(UserPlus, { className: "h-3 w-3 mr-1" }),
|
|
352
|
+
t("organization.team.invite")
|
|
353
|
+
] })
|
|
354
|
+
] }) : canManageTeam && !row.isCurrentUser && row.memberId ? /* @__PURE__ */ jsxs(
|
|
355
|
+
Select,
|
|
356
|
+
{
|
|
357
|
+
value: row.roleId,
|
|
358
|
+
onValueChange: (val) => handleChangeProfile(row.memberId, val),
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-36 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
361
|
+
/* @__PURE__ */ jsx(SelectContent, { children: profiles.map((p) => /* @__PURE__ */ jsx(SelectItem, { value: p.id, children: p.name }, p.id)) })
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
) : /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: profiles.find((p) => p.id === row.roleId)?.name ?? row.roleName })
|
|
365
|
+
},
|
|
366
|
+
...unitMode ? [{
|
|
367
|
+
id: "units",
|
|
368
|
+
header: "Unidades",
|
|
369
|
+
cell: ({ row: { original: row } }) => /* @__PURE__ */ jsx(
|
|
370
|
+
MemberUnitsCell,
|
|
371
|
+
{
|
|
372
|
+
userId: row.userId,
|
|
373
|
+
onManage: canManageTeam && row.userId ? () => openMemberAccess({ userId: row.userId, name: row.name, email: row.email }) : void 0
|
|
374
|
+
}
|
|
375
|
+
)
|
|
376
|
+
}] : [],
|
|
377
|
+
{
|
|
378
|
+
id: "joined",
|
|
379
|
+
header: t("organization.team.joined"),
|
|
380
|
+
cell: ({ row: { original: row } }) => /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: row.joinedAt ? new Date(row.joinedAt).toLocaleDateString() : "\u2014" })
|
|
381
|
+
},
|
|
382
|
+
...canManageTeam ? [{
|
|
383
|
+
id: "actions",
|
|
384
|
+
header: "",
|
|
385
|
+
meta: { className: "w-12 text-right" },
|
|
386
|
+
cell: ({ row: { original: row } }) => /* @__PURE__ */ jsx(
|
|
387
|
+
RowActions,
|
|
388
|
+
{
|
|
389
|
+
actions: [
|
|
390
|
+
// A ficha é onde acesso, unidades, escala e
|
|
391
|
+
// histórico da pessoa moram juntos — esta tela é
|
|
392
|
+
// a lista, não o lugar de editar cada um deles.
|
|
393
|
+
{
|
|
394
|
+
id: "record",
|
|
395
|
+
label: t("organization.team.openRecord"),
|
|
396
|
+
icon: Contact,
|
|
397
|
+
hidden: !row.personId || !entityRouteHasDetail("person", row.kind),
|
|
398
|
+
onSelect: () => openEntity(row.personId, "person", row.kind, "access")
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
id: "units",
|
|
402
|
+
label: t("organization.team.unitAccess"),
|
|
403
|
+
icon: Building2,
|
|
404
|
+
hidden: !unitMode || !row.userId || !row.hasAccess,
|
|
405
|
+
onSelect: () => openMemberAccess({ userId: row.userId, name: row.name, email: row.email })
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: "impersonate",
|
|
409
|
+
label: t("impersonation.action"),
|
|
410
|
+
icon: Eye,
|
|
411
|
+
// The owner is out of reach on the server too.
|
|
412
|
+
hidden: !row.hasAccess || row.isCurrentUser || !row.userId || row.roleId === "owner",
|
|
413
|
+
onSelect: () => setViewAs({ userId: row.userId, name: row.name })
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
id: "remove",
|
|
417
|
+
label: t("organization.team.removeMember"),
|
|
418
|
+
icon: UserMinus,
|
|
419
|
+
intent: "danger",
|
|
420
|
+
hidden: !row.hasAccess || row.isCurrentUser || !row.memberId,
|
|
421
|
+
onSelect: () => handleRemoveMember(row.memberId)
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
)
|
|
426
|
+
}] : []
|
|
427
|
+
];
|
|
428
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
429
|
+
currentOrg && /* @__PURE__ */ jsx(ImpersonateDialog, { tenantId: currentOrg.id, target: viewAs, onClose: () => setViewAs(null) }),
|
|
430
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
431
|
+
canManageTeam && /* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx(PageActions, { actions: inviteActions }) }),
|
|
432
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: t("organization.team.memberCount", { count: String(rows.length), plural: rows.length !== 1 ? "s" : "" }) }),
|
|
433
|
+
/* @__PURE__ */ jsx(Card, { className: "overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
434
|
+
DataTable,
|
|
435
|
+
{
|
|
436
|
+
variant: "bare",
|
|
437
|
+
columns,
|
|
438
|
+
data: rows,
|
|
439
|
+
loading: rowsLoading,
|
|
440
|
+
getRowId: (row) => row.key,
|
|
441
|
+
emptyMessage: t("organization.team.empty")
|
|
442
|
+
}
|
|
443
|
+
) })
|
|
444
|
+
] }),
|
|
445
|
+
pendingInvites.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
446
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-3", children: t("organization.team.pendingInvites") }),
|
|
447
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: pendingInvites.map((invite) => /* @__PURE__ */ jsx(Card, { className: "p-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
448
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(Mail, { className: "h-4 w-4 text-muted-foreground" }) }),
|
|
449
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
450
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: invite.email }),
|
|
451
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
452
|
+
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: invite.profileName }),
|
|
453
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
454
|
+
/* @__PURE__ */ jsx(Clock, { className: "h-3 w-3" }),
|
|
455
|
+
"Sent ",
|
|
456
|
+
new Date(invite.createdAt).toLocaleDateString()
|
|
457
|
+
] })
|
|
458
|
+
] })
|
|
459
|
+
] }),
|
|
460
|
+
canManageTeam && /* @__PURE__ */ jsx(
|
|
461
|
+
RowActions,
|
|
462
|
+
{
|
|
463
|
+
actions: [
|
|
464
|
+
{
|
|
465
|
+
id: "resend",
|
|
466
|
+
label: t("organization.team.resend"),
|
|
467
|
+
icon: Send,
|
|
468
|
+
onSelect: () => handleResendInvite(invite.id)
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
id: "revoke",
|
|
472
|
+
label: t("organization.team.revoke"),
|
|
473
|
+
icon: Ban,
|
|
474
|
+
intent: "danger",
|
|
475
|
+
onSelect: () => handleRevokeInvite(invite.id)
|
|
476
|
+
}
|
|
477
|
+
]
|
|
478
|
+
}
|
|
479
|
+
)
|
|
480
|
+
] }) }, invite.id)) })
|
|
481
|
+
] }),
|
|
482
|
+
/* @__PURE__ */ jsx(
|
|
483
|
+
InviteMemberDialog,
|
|
484
|
+
{
|
|
485
|
+
open: inviteOpen,
|
|
486
|
+
defaultEmail: inviteEmail,
|
|
487
|
+
onOpenChange: (open) => {
|
|
488
|
+
setInviteOpen(open);
|
|
489
|
+
if (!open) {
|
|
490
|
+
invalidateLimit("users");
|
|
491
|
+
setInviteEmail(void 0);
|
|
492
|
+
void reloadTeam();
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
] });
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export { TeamTab };
|
|
501
|
+
//# sourceMappingURL=TeamTab-6RAULFLW.js.map
|
|
502
|
+
//# sourceMappingURL=TeamTab-6RAULFLW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/organization/InviteMemberDialog.tsx","../src/impersonation/ImpersonateDialog.tsx","../src/components/organization/TeamTab.tsx"],"names":["useOrgAdapterOptional","React","React2","jsx","Modal","jsxs","ModalContent","ModalHeader","ModalTitle","ModalDescription","Input","ModalFooter","Button","useAuthStore","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Eye"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAMA,sBAAAA,GAAwB,MAAM,qBAAA,EAAoB;AAcjD,SAAS,kBAAA,CAAmB,EAAE,IAAA,EAAM,YAAA,EAAc,cAAa,EAA4B;AAChG,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,UAAUA,sBAAAA,EAAsB;AACtC,EAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC3D,EAAA,MAAM,QAAA,GAAW,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AACrD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,YAAA,EAAa;AAE9B,EAAA,MAAM,CAAC,QAAQ,SAAS,CAAA,GAAUC,gBAAmB,CAAC,YAAA,IAAgB,EAAE,CAAC,CAAA;AACzE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAUA,MAAA,CAAA,QAAA,CAAS,QAAA,CAAS,CAAC,CAAA,EAAG,EAAA,IAAM,QAAA,CAAS,CAAC,CAAA,EAAG,MAAM,EAAE,CAAA;AACzF,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAUA,gBAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,gBAAS,KAAK,CAAA;AAM5C,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,IAAA,EAAM,SAAA,CAAU,CAAC,YAAA,IAAgB,EAAE,CAAC,CAAA;AAAA,EAC1C,CAAA,EAAG,CAAC,IAAA,EAAM,YAAY,CAAC,CAAA;AAIvB,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,SAAA,IAAa,QAAA,CAAS,MAAA,EAAQ,YAAA,CAAa,QAAA,CAAS,CAAC,CAAA,EAAG,EAAA,IAAM,QAAA,CAAS,CAAC,CAAA,CAAG,EAAE,CAAA;AAAA,EACpF,CAAA,EAAG,CAAC,QAAA,EAAU,SAAS,CAAC,CAAA;AAExB,EAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,CAAC,SAAS,CAAC,GAAG,IAAA,EAAM,EAAE,CAAC,CAAA;AAExD,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,EAAa,KAAA,KAAkB;AAClD,IAAA,SAAA,CAAU,CAAC,IAAA,KAAS;AAClB,MAAA,MAAM,IAAA,GAAO,CAAC,GAAG,IAAI,CAAA;AACrB,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AACZ,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,KAAgB;AACnC,IAAA,SAAA,CAAU,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,GAAG,CAAC,CAAA;AAAA,EACtD,CAAA;AAEA,EAAA,MAAM,aAAa,YAAY;AAC7B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,IAAc,CAAC,IAAA,EAAM;AACtC,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,IAAK,CAAA,CAAE,QAAA,CAAS,GAAG,CAAC,CAAA;AACpE,IAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAE9B,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,QAAA,MAAM,OAAA,CAAQ,YAAA,CAAa,UAAA,CAAW,EAAA,EAAI,WAAA,CAAY,CAAC,CAAA,CAAE,IAAA,EAAK,EAAG,SAAA,EAAW,IAAA,CAAK,EAAE,CAAA;AAAA,MACrF,CAAA,MAAO;AACL,QAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,UAAA,CAAW,EAAA,EAAI,YAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,EAAG,SAAA,EAAW,KAAK,EAAE,CAAA;AAAA,MAC9F;AACA,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,WAAA,CAAY,WAAW,EAAE,CAAA;AACvD,MAAA,UAAA,CAAW,OAAO,CAAA;AAClB,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,SAAS,GAAA,EAAU;AACjB,MAAA,KAAA,CAAM,MAAM,wBAAA,EAA0B,EAAE,WAAA,EAAa,GAAA,EAAK,SAAS,CAAA;AAAA,IACrE,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,YAAA,CAAa,KAAK,CAAA;AAElB,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,SAAA,CAAU,CAAC,EAAE,CAAC,CAAA;AACd,MAAA,YAAA,CAAa,QAAA,CAAS,CAAC,CAAA,EAAG,EAAA,IAAM,SAAS,CAAC,CAAA,EAAG,MAAM,EAAE,CAAA;AACrD,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,GAAG,GAAG,CAAA;AAAA,EACR,CAAA;AAEA,EAAA,2BACG,KAAA,EAAA,EAAM,IAAA,EAAY,YAAA,EAAc,WAAA,EAC/B,+BAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAY,QAAA,EAAA,CAAA,CAAE,2BAA2B,CAAA,EAAE,CAAA;AAAA,sBAC5C,GAAA,CAAC,gBAAA,EAAA,EAAkB,QAAA,EAAA,CAAA,CAAE,iCAAiC,CAAA,EAAE;AAAA,KAAA,EAC1D,CAAA;AAAA,IAEC,IAAA,mBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oFAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sBAAA,EAAuB,IAAA,EAAK,MAAA,EAAO,OAAA,EAAQ,WAAA,EAAY,WAAA,EAAa,GAAG,MAAA,EAAO,cAAA,EAAe,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,CAAA,EAAE,uBAAA,EAAwB,CAAA,EAAE,CAAA,EAC7L,CAAA;AAAA,0BACC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,CAAA,CAAE,0BAA0B,CAAA,EAAE,CAAA;AAAA,0BACjE,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAsC,QAAA,EAAA,CAAA,CAAE,qCAAqC,CAAA,EAAE;AAAA,KAAA,EAC9F,CAAA,mBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,CAAA,CAAE,gCAAgC,CAAA,EAAE,CAAA;AAAA,QAC3E,MAAA,CAAO,IAAI,CAAC,KAAA,EAAO,wBAClB,IAAA,CAAC,KAAA,EAAA,EAAc,WAAU,yBAAA,EACvB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,OAAA;AAAA,cACL,WAAA,EAAY,kBAAA;AAAA,cACZ,KAAA,EAAO,KAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,YAAY,GAAA,EAAK,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA,WAClD;AAAA,UACC,OAAO,MAAA,GAAS,CAAA,wBACd,MAAA,EAAA,EAAO,OAAA,EAAQ,SAAQ,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,MAAM,YAAY,GAAG,CAAA,EAC9D,8BAAC,CAAA,EAAA,EAAE,SAAA,EAAU,WAAU,CAAA,EACzB;AAAA,SAAA,EAAA,EAVM,GAYV,CACD,CAAA;AAAA,wBACD,IAAA,CAAC,UAAO,OAAA,EAAQ,OAAA,EAAQ,MAAK,IAAA,EAAK,OAAA,EAAS,QAAA,EAAU,SAAA,EAAU,SAAA,EAC7D,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,kBAAA,EAAmB,CAAA;AAAA,UAClC,EAAE,gCAAgC;AAAA,SAAA,EACrC;AAAA,OAAA,EACF,CAAA;AAAA,2BAEC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,CAAA,CAAE,+BAA+B,CAAA,EAAE,CAAA;AAAA,wBAC3E,IAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,SAAA,EAAW,eAAe,YAAA,EACvC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,aAAA,EAAA,EAAc,WAAU,MAAA,EACvB,QAAA,kBAAA,GAAA,CAAC,eAAY,WAAA,EAAa,CAAA,CAAE,qCAAqC,CAAA,EAAG,CAAA,EACtE,CAAA;AAAA,8BACC,aAAA,EAAA,EACE,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,sBACb,GAAA,CAAC,UAAA,EAAA,EAAsB,KAAA,EAAO,CAAA,CAAE,IAAK,QAAA,EAAA,CAAA,CAAE,IAAA,EAAA,EAAtB,CAAA,CAAE,EAAyB,CAC7C,CAAA,EACH;AAAA,SAAA,EACF;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAGF,GAAA,CAAC,WAAA,EAAA,EACE,QAAA,EAAA,IAAA,mBACC,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAS,WAAA,EAAc,QAAA,EAAA,CAAA,CAAE,aAAa,CAAA,EAAE,CAAA,mBAEhD,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,SAAS,WAAA,EAAc,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,EAAE,CAAA;AAAA,sBACpE,GAAA,CAAC,UAAO,OAAA,EAAS,UAAA,EAAY,UAAU,OAAA,IAAW,MAAA,CAAO,MAAM,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,EAC5E,QAAA,EAAA,OAAA,GAAU,EAAE,6BAA6B,CAAA,GAAI,CAAA,CAAE,iCAAiC,CAAA,EACnF;AAAA,KAAA,EACF,CAAA,EAEJ;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;AC7KO,SAAS,iBAAA,CAAkB,EAAE,QAAA,EAAU,MAAA,EAAQ,SAAQ,EAI3D;AACD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUC,gBAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,gBAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,gBAAwB,IAAI,CAAA;AAE5D,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,MAAA,EAAQ;AAAE,MAAA,SAAA,CAAU,EAAE,CAAA;AAAG,MAAA,QAAA,CAAS,IAAI,CAAA;AAAG,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IAAE;AAAA,EAC9D,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,eAAe,KAAA,GAAQ;AACrB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,kBAAA,CAAmB;AAAA,QACvB,QAAA;AAAA,QACA,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAK,IAAK,KAAA,CAAA;AAAA,QACzB,UAAU,cAAA;AAAe,OAC1B,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAU,GAAA,CAAc,OAAA,IAAW,CAAA,CAAE,sBAAsB,CAAC,CAAA;AAC5D,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,uBACEC,GAAAA,CAACC,KAAAA,EAAA,EAAM,IAAA,EAAM,CAAC,CAAC,MAAA,EAAQ,YAAA,EAAc,CAAC,IAAA,KAAS;AAAE,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,IAAA,EAAM,OAAA,EAAQ;AAAA,EAAE,CAAA,EAC7E,QAAA,kBAAAC,IAAAA,CAACC,YAAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAD,IAAAA,CAACE,aAAA,EACC,QAAA,EAAA;AAAA,sBAAAJ,GAAAA,CAACK,UAAAA,EAAA,EAAY,QAAA,EAAA,CAAA,CAAE,4BAAA,EAA8B,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,IAAQ,EAAA,EAAI,CAAA,EAAE,CAAA;AAAA,sBAC3EL,GAAAA,CAACM,gBAAAA,EAAA,EAAkB,QAAA,EAAA,CAAA,CAAE,2BAA2B,CAAA,EAAE;AAAA,KAAA,EACpD,CAAA;AAAA,oBACAJ,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,sBAAAF,IAAC,OAAA,EAAA,EAAM,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAA,CAAA,CAAE,2BAA2B,CAAA,EAAE,CAAA;AAAA,sBACvEA,GAAAA,CAACO,KAAAA,EAAA,EAAM,OAAO,MAAA,EAAQ,QAAA,EAAU,CAAC,CAAA,KAAM,UAAU,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,EAAG,UAAU,IAAA,EAAM,CAAA;AAAA,MACjF,yBAASP,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4BAA4B,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EAC3D,CAAA;AAAA,oBACAE,IAAAA,CAACM,WAAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAR,GAAAA,CAACS,MAAAA,EAAA,EAAO,OAAA,EAAQ,SAAA,EAAU,OAAA,EAAS,OAAA,EAAS,QAAA,EAAU,IAAA,EAAO,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,EAAE,CAAA;AAAA,sBAChFP,IAAAA,CAACO,MAAAA,EAAA,EAAO,SAAS,MAAM;AAAE,QAAA,KAAK,KAAA,EAAM;AAAA,MAAE,CAAA,EAAG,UAAU,IAAA,EACjD,QAAA,EAAA;AAAA,wBAAAT,GAAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,QAC7B,EAAE,uBAAuB;AAAA,OAAA,EAC5B;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;AC7CA,IAAMH,sBAAAA,GAAwB,MAAM,qBAAA,EAAoB;AAiCxD,IAAM,UAAA,GAAa,CAAC,CAAA,KAAe,CAAA,GAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,GAAI,CAAA;AAEzE,SAAS,OAAA,GAAU;AACxB,EAAA,MAAM,UAAUA,sBAAAA,EAAsB;AACtC,EAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AACrD,EAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC3D,EAAA,MAAM,eAAA,GAAkB,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,eAAe,CAAA;AACrE,EAAA,MAAM,QAAA,GAAW,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AACtD,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAC/C,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AACrD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAIa,YAAAA,EAAa;AAC9B,EAAA,MAAM,sBAAsB,mBAAA,EAAoB;AAIhD,EAAA,MAAM,aAAa,eAAA,CAAgB,MAAA,GAAS,CAAA,IAAK,OAAO,SAAS,QAAA,KAAa,UAAA;AAC9E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAU,gBAA0E,IAAI,CAAA;AAE5G,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAU,gBAAS,KAAK,CAAA;AAGxD,EAAA,MAAM,UAAA,GAAa,cAAc,OAAO,CAAA;AAMxC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAU,gBAA6B,MAAS,CAAA;AAElF,EAAA,MAAM,gBAAA,GAAmB,OAAO,GAAA,KAAkB;AAGhD,IAAA,IAAI,GAAA,IAAO,CAAC,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,YAAY,oBAAA,CAAqB,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACjF,MAAA,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,QAAA,EAAU,GAAA,CAAI,MAAM,QAAQ,CAAA;AACrD,MAAA;AAAA,IACF;AACA,IAAA,IAAK,MAAM,UAAA,CAAW,CAAC,CAAA,KAAO,SAAA,EAAW;AACzC,IAAA,cAAA,CAAe,GAAA,EAAK,SAAS,MAAS,CAAA;AACtC,IAAA,aAAA,CAAc,IAAI,CAAA;AAAA,EACpB,CAAA;AAEA,EAAA,MAAM,UAAA,GAAmB,mBAAY,YAAY;AAC/C,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,EAAY;AAC7B,IAAA,IAAI,UAAA,IAAc,QAAQ,QAAA,EAAU;AAClC,MAAA,OAAA,CAAQ,MAAM,OAAA,CAAQ,QAAA,CAAS,UAAA,CAAW,EAAA,EAAI,eAAe,CAAC,CAAA;AAAA,IAChE,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,MAAM,OAAA,CAAQ,WAAA,CAAY,UAAA,CAAW,EAAE,CAAC,CAAA;AAAA,IACrD;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,UAAA,EAAY,IAAI,UAAA,EAAY,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGrE,EAAM,iBAAU,MAAM;AACpB,IAAA,IAAI,UAAA,IAAc,OAAA,EAAS,QAAA,IAAY,UAAA,EAAY;AACjD,MAAA,KAAA,CAAM,iBAAiB,UAAA,CAAW,EAAA,EAAI,MAAM,OAAA,CAAQ,QAAA,CAAU,WAAW,EAAA,EAAI,eAAe,CAAC,CAAA,CAC1F,IAAA,CAAK,OAAO,CAAA,CACZ,KAAA,CAAM,MAAM,OAAA,CAAQ,EAAE,CAAC,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,OAAA,EAAS,UAAA,EAAY,IAAI,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAGnE,EAAM,iBAAU,MAAM;AACpB,IAAA,IAAI,WAAW,UAAA,EAAY;AACzB,MAAA,KAAA,CAAM,eAAA,GAAkB,UAAA,CAAW,EAAA,EAAI,MAAM,QAAQ,WAAA,CAAY,UAAA,CAAW,EAAE,CAAC,CAAA,CAAE,IAAA,CAAK,UAAU,CAAA,CAAE,MAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IAClH;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,UAAA,EAAY,EAAE,CAAC,CAAA;AAE5B,EAAA,MAAM,mBAAA,GAAsB,OAAO,QAAA,EAAkB,SAAA,KAAsB;AACzE,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,EAAY;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,mBAAA,CAAoB,UAAA,CAAW,EAAA,EAAI,UAAU,SAAS,CAAA;AACpE,MAAA,MAAM,UAAA,EAAW;AAAA,IACnB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,KAAqB;AACrD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,EAAY;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,YAAA,CAAa,UAAA,CAAW,EAAA,EAAI,QAAQ,CAAA;AAClD,MAAA,MAAM,UAAA,EAAW;AAAA,IACnB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AAIA,EAAA,gBAAA,EAAiB;AACjB,EAAA,MAAM,QAAA,GAAW,YAAA,CAAa,CAAC,EAAA,KAAO,GAAG,QAAQ,CAAA;AAGjD,EAAA,MAAM,gBAAA,GAAmB,oBAAA,CAAqB,CAAC,EAAA,KAAO,GAAG,UAAU,CAAA;AAGnE,EAAA,MAAM,OAAkB,UAAA,GAAA,CACnB,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA;AAAA,IAEvB,KAAK,CAAA,CAAE,QAAA,IAAY,CAAA,CAAE,UAAA,EAAY,YAAY,CAAA,CAAE,IAAA;AAAA,IAC/C,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,KAAA,EAAO,EAAE,KAAA,IAAS,EAAA;AAAA,IAClB,WAAW,CAAA,CAAE,SAAA;AAAA,IACb,UAAU,CAAA,CAAE,IAAA,GAAO,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,GAAI,MAAA;AAAA,IACxC,MAAA,EAAQ,EAAE,UAAA,EAAY,SAAA;AAAA,IACtB,QAAA,EAAU,EAAE,UAAA,EAAY,WAAA;AAAA,IACxB,QAAA,EAAU,EAAE,UAAA,EAAY,QAAA;AAAA,IACxB,MAAA,EAAQ,EAAE,UAAA,EAAY,MAAA;AAAA,IACtB,SAAA,EAAW,CAAC,CAAC,CAAA,CAAE,UAAA;AAAA,IACf,QAAA,EAAU,EAAE,UAAA,EAAY,QAAA;AAAA,IACxB,aAAA,EAAe,CAAA,CAAE,UAAA,EAAY,MAAA,KAAW,IAAA,EAAM;AAAA,GAChD,CAAE,CAAA,GACF,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IAClB,KAAK,CAAA,CAAE,EAAA;AAAA,IACP,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,MAAM,CAAA,CAAE,UAAA;AAAA,IACR,IAAA,EAAM,EAAE,IAAA,CAAK,QAAA;AAAA,IACb,KAAA,EAAO,EAAE,IAAA,CAAK,KAAA;AAAA,IACd,SAAA,EAAW,EAAE,IAAA,CAAK,SAAA;AAAA,IAClB,QAAQ,CAAA,CAAE,SAAA;AAAA,IACV,UAAU,CAAA,CAAE,WAAA;AAAA,IACZ,UAAU,CAAA,CAAE,EAAA;AAAA,IACZ,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,SAAA,EAAW,IAAA;AAAA,IACX,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,aAAA,EAAe,CAAA,CAAE,MAAA,KAAW,IAAA,EAAM;AAAA,GACpC,CAAE,CAAA;AACN,EAAA,MAAM,WAAA,GAAc,UAAA,GAAa,IAAA,KAAS,IAAA,GAAO,QAAQ,MAAA,KAAW,CAAA;AAEpE,EAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,KAAqB;AACrD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,EAAY;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,YAAA,CAAa,UAAA,CAAW,EAAA,EAAI,QAAQ,CAAA;AAClD,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,WAAA,CAAY,WAAW,EAAE,CAAA;AACvD,MAAA,UAAA,CAAW,OAAO,CAAA;AAClB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,iCAAiC,CAAC,CAAA;AAAA,IACpD,SAAS,GAAA,EAAU;AACjB,MAAA,KAAA,CAAM,KAAA,CAAM,EAAE,sCAAsC,CAAA,EAAG,EAAE,WAAA,EAAa,GAAA,EAAK,SAAS,CAAA;AAAA,IACtF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,OAAO,QAAA,KAAqB;AACrD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,UAAA,EAAY;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,YAAA,CAAa,UAAA,CAAW,EAAA,EAAI,QAAQ,CAAA;AAClD,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,WAAA,CAAY,WAAW,EAAE,CAAA;AACvD,MAAA,UAAA,CAAW,OAAO,CAAA;AAClB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,gCAAgC,CAAC,CAAA;AAAA,IACnD,SAAS,GAAA,EAAU;AACjB,MAAA,KAAA,CAAM,KAAA,CAAM,EAAE,sCAAsC,CAAA,EAAG,EAAE,WAAA,EAAa,GAAA,EAAK,SAAS,CAAA;AAAA,IACtF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,aAAA,GAAgB,oBAAoB,aAAa,CAAA;AACvD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAU,gBAAmC,IAAI,CAAA;AACzE,EAAA,MAAM,aAAA,GAAsB,MAAA,CAAA,OAAA,CAAsB,MAAM,CAAC;AAAA,IACvD,EAAA,EAAI,QAAA;AAAA,IACJ,KAAA,EAAO,EAAE,0BAA0B,CAAA;AAAA,IACnC,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA;AAAA,IAER,OAAA,EAAS,IAAA;AAAA,IACT,UAAU,MAAM;AAAE,MAAA,KAAK,gBAAA,EAAiB;AAAA,IAAE;AAAA,GAC3C,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AACP,EAAA,MAAM,iBAAiB,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AAEnE,EAAA,MAAM,OAAA,GAAgC;AAAA,IACpC;AAAA,MACE,EAAA,EAAI,QAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,0BAA0B,CAAA;AAAA,MACpC,IAAA,EAAM,CAAC,EAAE,GAAA,EAAK,EAAE,QAAA,EAAU,GAAA,IAAM,KAAM;AACpC,QAAA,MAAM,QAAA,GAAA,CAAY,IAAI,IAAA,IAAQ,GAAA,EAC3B,MAAM,GAAG,CAAA,CACT,IAAI,CAAC,CAAA,KAAM,EAAE,CAAC,CAAC,EACf,IAAA,CAAK,EAAE,EACP,WAAA,EAAY,CACZ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AACb,QAAA,uBACER,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,SAAA,EACf,QAAA,EAAA;AAAA,YAAA,GAAA,CAAI,6BAAaF,GAAAA,CAAC,WAAA,EAAA,EAAY,GAAA,EAAK,IAAI,SAAA,EAAW,CAAA;AAAA,4BACnDA,GAAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,WAAW,QAAA,EAAA,QAAA,EAAS;AAAA,WAAA,EAChD,CAAA;AAAA,0BACAE,KAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAAA,IAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAA,EACV,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA;AAAA,cACJ,GAAA,CAAI,iCAAiBF,GAAAA,CAAC,UAAK,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAA,CAAA,CAAE,uBAAuB,CAAA,EAAE,CAAA;AAAA,cAC9F,GAAA,CAAI,QAAA,oBAAYA,GAAAA,CAAC,KAAA,EAAA,EAAM,SAAQ,SAAA,EAAU,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,GAAA,CAAI,QAAA,EAAS;AAAA,aAAA,EACnG,CAAA;AAAA,YACC,GAAA,CAAI,yBAASA,GAAAA,CAAC,OAAE,SAAA,EAAU,+BAAA,EAAiC,cAAI,KAAA,EAAM;AAAA,WAAA,EACxE;AAAA,SAAA,EACF,CAAA;AAAA,MAEJ;AAAA,KACF;AAAA,IACA;AAAA,MACE,EAAA,EAAI,MAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,wBAAwB,CAAA;AAAA,MAClC,MAAM,CAAC,EAAE,GAAA,EAAK,EAAE,UAAU,GAAA,EAAI,EAAE,KAC9B,CAAC,IAAI,SAAA,mBACHE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAAC,SAAM,OAAA,EAAQ,SAAA,EAAU,WAAU,+BAAA,EAAiC,QAAA,EAAA,CAAA,CAAE,4BAA4B,CAAA,EAAE,CAAA;AAAA,QACnG,aAAA,oBACCE,IAAAA,CAACO,MAAAA,EAAA,EAAO,OAAA,EAAQ,OAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,SAAA,EAAU,aAAA,EAAc,OAAA,EAAS,MAAM;AAAE,UAAA,KAAK,iBAAiB,GAAG,CAAA;AAAA,QAAE,CAAA,EACpG,QAAA,EAAA;AAAA,0BAAAT,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,UAClC,EAAE,0BAA0B;AAAA,SAAA,EAC/B;AAAA,OAAA,EAEJ,IACE,aAAA,IAAiB,CAAC,IAAI,aAAA,IAAiB,GAAA,CAAI,2BAC7CE,IAAAA;AAAA,QAACS,MAAAA;AAAA,QAAA;AAAA,UACC,OAAO,GAAA,CAAI,MAAA;AAAA,UACX,eAAe,CAAC,GAAA,KAAQ,mBAAA,CAAoB,GAAA,CAAI,UAAW,GAAG,CAAA;AAAA,UAE9D,QAAA,EAAA;AAAA,4BAAAX,GAAAA,CAACY,eAAA,EAAc,SAAA,EAAU,oBACvB,QAAA,kBAAAZ,GAAAA,CAACa,WAAAA,EAAA,EAAY,CAAA,EACf,CAAA;AAAA,4BACAb,IAACc,aAAAA,EAAA,EACE,mBAAS,GAAA,CAAI,CAAC,sBACbd,GAAAA,CAACe,YAAA,EAAsB,KAAA,EAAO,EAAE,EAAA,EAAK,QAAA,EAAA,CAAA,CAAE,QAAtB,CAAA,CAAE,EAAyB,CAC7C,CAAA,EACH;AAAA;AAAA;AAAA,0BAGFf,GAAAA,CAAC,SAAM,OAAA,EAAQ,WAAA,EAAY,WAAU,SAAA,EAClC,QAAA,EAAA,QAAA,CAAS,KAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA,IAAQ,IAAI,QAAA,EAC1D;AAAA,KAEN;AAAA,IACA,GAAI,WAAW,CAAC;AAAA,MACd,EAAA,EAAI,OAAA;AAAA,MACJ,MAAA,EAAQ,UAAA;AAAA,MACR,IAAA,EAAM,CAAC,EAAE,GAAA,EAAK,EAAE,QAAA,EAAU,GAAA,EAAI,EAAE,qBAC9BA,GAAAA;AAAA,QAAC,eAAA;AAAA,QAAA;AAAA,UACC,QAAQ,GAAA,CAAI,MAAA;AAAA,UACZ,UAAU,aAAA,IAAiB,GAAA,CAAI,MAAA,GAC3B,MAAM,iBAAiB,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAS,MAAM,GAAA,CAAI,IAAA,EAAM,OAAO,GAAA,CAAI,KAAA,EAAO,CAAA,GAChF;AAAA;AAAA;AACN,KAE0B,IAAI,EAAC;AAAA,IACnC;AAAA,MACE,EAAA,EAAI,QAAA;AAAA,MACJ,MAAA,EAAQ,EAAE,0BAA0B,CAAA;AAAA,MACpC,IAAA,EAAM,CAAC,EAAE,GAAA,EAAK,EAAE,QAAA,EAAU,GAAA,EAAI,EAAE,qBAC9BA,GAAAA,CAAC,UAAK,SAAA,EAAU,+BAAA,EACb,QAAA,EAAA,GAAA,CAAI,QAAA,GAAW,IAAI,IAAA,CAAK,IAAI,QAAQ,CAAA,CAAE,kBAAA,EAAmB,GAAI,QAAA,EAChE;AAAA,KAEJ;AAAA,IACA,GAAI,gBAAgB,CAAC;AAAA,MACnB,EAAA,EAAI,SAAA;AAAA,MACJ,MAAA,EAAQ,EAAA;AAAA,MACR,IAAA,EAAM,EAAE,SAAA,EAAW,iBAAA,EAAkB;AAAA,MACrC,IAAA,EAAM,CAAC,EAAE,GAAA,EAAK,EAAE,QAAA,EAAU,GAAA,EAAI,EAAE,qBAC9BA,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS;AAAA;AAAA;AAAA;AAAA,YAIP;AAAA,cACE,EAAA,EAAI,QAAA;AAAA,cACJ,KAAA,EAAO,EAAE,8BAA8B,CAAA;AAAA,cACvC,IAAA,EAAM,OAAA;AAAA,cACN,MAAA,EAAQ,CAAC,GAAA,CAAI,QAAA,IAAY,CAAC,oBAAA,CAAqB,QAAA,EAAU,IAAI,IAAI,CAAA;AAAA,cACjE,QAAA,EAAU,MAAM,UAAA,CAAW,GAAA,CAAI,UAAW,QAAA,EAAU,GAAA,CAAI,MAAM,QAAQ;AAAA,aACxE;AAAA,YACA;AAAA,cACE,EAAA,EAAI,OAAA;AAAA,cACJ,KAAA,EAAO,EAAE,8BAA8B,CAAA;AAAA,cACvC,IAAA,EAAM,SAAA;AAAA,cACN,QAAQ,CAAC,QAAA,IAAY,CAAC,GAAA,CAAI,MAAA,IAAU,CAAC,GAAA,CAAI,SAAA;AAAA,cACzC,QAAA,EAAU,MAAM,gBAAA,CAAiB,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,KAAA,EAAO,GAAA,CAAI,OAAO;AAAA,aAC5F;AAAA,YACA;AAAA,cACE,EAAA,EAAI,aAAA;AAAA,cACJ,KAAA,EAAO,EAAE,sBAAsB,CAAA;AAAA,cAC/B,IAAA,EAAMgB,GAAAA;AAAA;AAAA,cAEN,MAAA,EAAQ,CAAC,GAAA,CAAI,SAAA,IAAa,GAAA,CAAI,iBAAiB,CAAC,GAAA,CAAI,MAAA,IAAU,GAAA,CAAI,MAAA,KAAW,OAAA;AAAA,cAC7E,QAAA,EAAU,MAAM,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAI,MAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM;AAAA,aACnE;AAAA,YACA;AAAA,cACE,EAAA,EAAI,QAAA;AAAA,cACJ,KAAA,EAAO,EAAE,gCAAgC,CAAA;AAAA,cACzC,IAAA,EAAM,SAAA;AAAA,cACN,MAAA,EAAQ,QAAA;AAAA,cACR,QAAQ,CAAC,GAAA,CAAI,aAAa,GAAA,CAAI,aAAA,IAAiB,CAAC,GAAA,CAAI,QAAA;AAAA,cACpD,QAAA,EAAU,MAAM,kBAAA,CAAmB,GAAA,CAAI,QAAS;AAAA;AAClD;AACF;AAAA;AACF,KAE0B,IAAI;AAAC,GACrC;AAEA,EAAA,uBACEd,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACZ,QAAA,EAAA;AAAA,IAAA,UAAA,oBAAcF,GAAAA,CAAC,iBAAA,EAAA,EAAkB,QAAA,EAAU,UAAA,CAAW,EAAA,EAAI,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,MAAM,SAAA,CAAU,IAAI,CAAA,EAAG,CAAA;AAAA,oBAE3GE,KAAC,KAAA,EAAA,EAGE,QAAA,EAAA;AAAA,MAAA,aAAA,oBACCF,IAAC,iBAAA,EAAA,EAKC,QAAA,kBAAAA,IAAC,WAAA,EAAA,EAAY,OAAA,EAAS,eAAe,CAAA,EACvC,CAAA;AAAA,sBAEFA,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCACV,QAAA,EAAA,CAAA,CAAE,+BAAA,EAAiC,EAAE,KAAA,EAAO,MAAA,CAAO,KAAK,MAAM,CAAA,EAAG,QAAQ,IAAA,CAAK,MAAA,KAAW,IAAI,GAAA,GAAM,EAAA,EAAI,CAAA,EAC1G,CAAA;AAAA,sBAEAA,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,mBACd,QAAA,kBAAAA,GAAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,MAAA;AAAA,UACR,OAAA;AAAA,UACA,IAAA,EAAM,IAAA;AAAA,UACN,OAAA,EAAS,WAAA;AAAA,UACT,QAAA,EAAU,CAAC,GAAA,KAAQ,GAAA,CAAI,GAAA;AAAA,UACvB,YAAA,EAAc,EAAE,yBAAyB;AAAA;AAAA,OAC3C,EACF;AAAA,KAAA,EACF,CAAA;AAAA,IAIC,cAAA,CAAe,MAAA,GAAS,CAAA,oBACvBE,KAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAF,IAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAA,CAAA,CAAE,kCAAkC,CAAA,EAAE,CAAA;AAAA,sBAClFA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACZ,QAAA,EAAA,cAAA,CAAe,IAAI,CAAC,MAAA,qBACnBA,GAAAA,CAAC,QAAqB,SAAA,EAAU,KAAA,EAC9B,0BAAAE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAAC,SAAI,SAAA,EAAU,gEAAA,EACb,0BAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,+BAAA,EAAgC,CAAA,EAClD,CAAA;AAAA,wBACAE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,0BAAAF,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAA,EAAuB,iBAAO,KAAA,EAAM,CAAA;AAAA,0BACjDE,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uDAAA,EACb,QAAA,EAAA;AAAA,4BAAAF,IAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,aAAY,SAAA,EAAU,SAAA,EAAW,iBAAO,WAAA,EAAY,CAAA;AAAA,4BACnEE,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EACd,QAAA,EAAA;AAAA,8BAAAF,GAAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,cAAE,OAAA;AAAA,cACvB,IAAI,IAAA,CAAK,MAAA,CAAO,SAAS,EAAE,kBAAA;AAAmB,aAAA,EACtD;AAAA,WAAA,EACF;AAAA,SAAA,EACF,CAAA;AAAA,QACC,iCACCA,GAAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,EAAA,EAAI,QAAA;AAAA,gBACJ,KAAA,EAAO,EAAE,0BAA0B,CAAA;AAAA,gBACnC,IAAA,EAAM,IAAA;AAAA,gBACN,QAAA,EAAU,MAAM,kBAAA,CAAmB,MAAA,CAAO,EAAE;AAAA,eAC9C;AAAA,cACA;AAAA,gBACE,EAAA,EAAI,QAAA;AAAA,gBACJ,KAAA,EAAO,EAAE,0BAA0B,CAAA;AAAA,gBACnC,IAAA,EAAM,GAAA;AAAA,gBACN,MAAA,EAAQ,QAAA;AAAA,gBACR,QAAA,EAAU,MAAM,kBAAA,CAAmB,MAAA,CAAO,EAAE;AAAA;AAC9C;AACF;AAAA;AACF,OAAA,EAEJ,CAAA,EAAA,EAlCS,MAAA,CAAO,EAmClB,CACD,CAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,oBAGFA,GAAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,UAAA;AAAA,QACN,YAAA,EAAc,WAAA;AAAA,QACd,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,UAAA,aAAA,CAAc,IAAI,CAAA;AAGlB,UAAA,IAAI,CAAC,IAAA,EAAM;AACT,YAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,YAAA,cAAA,CAAe,MAAS,CAAA;AACxB,YAAA,KAAK,UAAA,EAAW;AAAA,UAClB;AAAA,QACF;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ","file":"TeamTab-6RAULFLW.js","sourcesContent":["import * as React from 'react'\nimport { Plus, X } from 'lucide-react'\nimport { toast } from '../notifications/ToastProvider'\nimport {\n Modal,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n} from '@fayz-ai/ui'\nimport { Button } from '@fayz-ai/ui'\nimport { Input } from '@fayz-ai/ui'\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@fayz-ai/ui'\nimport { Badge } from '@fayz-ai/ui'\nimport { usePermissionsStore } from '../../permissions'\nimport { useOrganizationStore } from '../../stores/organization.store'\nimport { useInviteStore } from '../../stores/invite.store'\n// Native org adapter (the one the app actually provides). The shell lib/org-context\n// is a separate, un-provided context that returns null here — which made the submit\n// button a no-op (handleSend bailed on `!adapter`).\nimport { useOrgAdapterOptional as useNativeOrgAdapter } from '../../org'\nimport type { OrgAdapter } from '../../types/org-adapter'\n\n// The native adapter is the same runtime object; its Invite/Location types differ\n// from the shell's only in fields these components don't read, so a cast is safe.\nconst useOrgAdapterOptional = () => useNativeOrgAdapter() as unknown as OrgAdapter | null\n// The signed-in user lives in @fayz-ai/auth's store (what OrgProvider reads). The\n// shell stores/auth.store is a separate, unpopulated store — reading `user` from\n// it left `user` null, so handleSend bailed on `!user` (silent no-op).\nimport { useAuthStore } from '@fayz-ai/auth'\nimport { useTranslation } from '../../hooks/useTranslation'\n\ninterface InviteMemberDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** Pre-fill the first email (e.g. from person detail Access tab) */\n defaultEmail?: string\n}\n\nexport function InviteMemberDialog({ open, onOpenChange, defaultEmail }: InviteMemberDialogProps) {\n const { t } = useTranslation()\n const adapter = useOrgAdapterOptional()\n const currentOrg = useOrganizationStore((s) => s.currentOrg)\n const profiles = usePermissionsStore((s) => s.profiles)\n const setInvites = useInviteStore((s) => s.setInvites)\n const { user } = useAuthStore()\n\n const [emails, setEmails] = React.useState<string[]>([defaultEmail ?? ''])\n const [profileId, setProfileId] = React.useState(profiles[1]?.id ?? profiles[0]?.id ?? '')\n const [sending, setSending] = React.useState(false)\n const [sent, setSent] = React.useState(false)\n\n // O prefill só chegava no PRIMEIRO render, e o diálogo fica montado o tempo\n // todo — abrir a partir da linha de alguém trazia o e-mail de quem foi\n // convidado antes, ou nada. O e-mail é a coisa que este diálogo não pode\n // errar: é ele que liga o convite aceito à ficha certa.\n React.useEffect(() => {\n if (open) setEmails([defaultEmail ?? ''])\n }, [open, defaultEmail])\n\n // A lista de papéis chega depois do primeiro render (vem do adaptador), e\n // sem isto o seletor abria vazio e o Enviar mandava um papel em branco.\n React.useEffect(() => {\n if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0]!.id)\n }, [profiles, profileId])\n\n const addEmail = () => setEmails((prev) => [...prev, ''])\n\n const updateEmail = (idx: number, value: string) => {\n setEmails((prev) => {\n const next = [...prev]\n next[idx] = value\n return next\n })\n }\n\n const removeEmail = (idx: number) => {\n setEmails((prev) => prev.filter((_, i) => i !== idx))\n }\n\n const handleSend = async () => {\n if (!adapter || !currentOrg || !user) return\n const validEmails = emails.filter((e) => e.trim() && e.includes('@'))\n if (validEmails.length === 0) return\n\n setSending(true)\n try {\n if (validEmails.length === 1) {\n await adapter.createInvite(currentOrg.id, validEmails[0].trim(), profileId, user.id)\n } else {\n await adapter.bulkInvite(currentOrg.id, validEmails.map((e) => e.trim()), profileId, user.id)\n }\n const invites = await adapter.listInvites(currentOrg.id)\n setInvites(invites)\n setSent(true)\n } catch (err: any) {\n toast.error('Failed to send invites', { description: err?.message })\n } finally {\n setSending(false)\n }\n }\n\n const handleClose = () => {\n onOpenChange(false)\n // Reset after animation\n setTimeout(() => {\n setEmails([''])\n setProfileId(profiles[1]?.id ?? profiles[0]?.id ?? '')\n setSent(false)\n }, 200)\n }\n\n return (\n <Modal open={open} onOpenChange={handleClose}>\n <ModalContent>\n <ModalHeader>\n <ModalTitle>{t('organization.invite.title')}</ModalTitle>\n <ModalDescription>{t('organization.invite.description')}</ModalDescription>\n </ModalHeader>\n\n {sent ? (\n <div className=\"py-8 text-center\">\n <div className=\"mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-success/10\">\n <svg className=\"h-6 w-6 text-success\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth={2} stroke=\"currentColor\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg>\n </div>\n <p className=\"text-sm font-medium\">{t('organization.invite.sent')}</p>\n <p className=\"text-xs text-muted-foreground mt-1\">{t('organization.invite.sentDescription')}</p>\n </div>\n ) : (\n <div className=\"space-y-4 py-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{t('organization.invite.emailLabel')}</label>\n {emails.map((email, idx) => (\n <div key={idx} className=\"flex items-center gap-2\">\n <Input\n type=\"email\"\n placeholder=\"team@example.com\"\n value={email}\n onChange={(e) => updateEmail(idx, e.target.value)}\n />\n {emails.length > 1 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => removeEmail(idx)}>\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n ))}\n <Button variant=\"ghost\" size=\"sm\" onClick={addEmail} className=\"text-xs\">\n <Plus className=\"h-3.5 w-3.5 mr-1\" />\n {t('organization.invite.addAnother')}\n </Button>\n </div>\n\n <div>\n <label className=\"text-sm font-medium\">{t('organization.invite.roleLabel')}</label>\n <Select value={profileId} onValueChange={setProfileId}>\n <SelectTrigger className=\"mt-1\">\n <SelectValue placeholder={t('organization.invite.rolePlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n {profiles.map((p) => (\n <SelectItem key={p.id} value={p.id}>{p.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n )}\n\n <ModalFooter>\n {sent ? (\n <Button onClick={handleClose}>{t('common.done')}</Button>\n ) : (\n <>\n <Button variant=\"outline\" onClick={handleClose}>{t('common.cancel')}</Button>\n <Button onClick={handleSend} disabled={sending || emails.every((e) => !e.trim())}>\n {sending ? t('organization.invite.sending') : t('organization.invite.sendInvites')}\n </Button>\n </>\n )}\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n","import * as React from 'react'\nimport { Eye } from 'lucide-react'\nimport { Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Button, Input } from '@fayz-ai/ui'\nimport { useTranslation } from '../hooks/useTranslation'\nimport { startImpersonation } from './session'\nimport { currentAppPath } from '@fayz-ai/core'\n\nexport interface ImpersonateTarget {\n userId: string\n name: string\n}\n\nexport function ImpersonateDialog({ tenantId, target, onClose }: {\n tenantId: string\n target: ImpersonateTarget | null\n onClose: () => void\n}) {\n const { t } = useTranslation()\n const [reason, setReason] = React.useState('')\n const [busy, setBusy] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n\n React.useEffect(() => {\n if (target) { setReason(''); setError(null); setBusy(false) }\n }, [target])\n\n async function enter() {\n if (!target) return\n setBusy(true)\n setError(null)\n try {\n await startImpersonation({\n tenantId,\n userId: target.userId,\n reason: reason.trim() || undefined,\n returnTo: currentAppPath(),\n })\n } catch (err) {\n setError((err as Error).message || t('impersonation.failed'))\n setBusy(false)\n }\n }\n\n return (\n <Modal open={!!target} onOpenChange={(open) => { if (!open && !busy) onClose() }}>\n <ModalContent>\n <ModalHeader>\n <ModalTitle>{t('impersonation.confirmTitle', { name: target?.name ?? '' })}</ModalTitle>\n <ModalDescription>{t('impersonation.confirmBody')}</ModalDescription>\n </ModalHeader>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">{t('impersonation.reasonLabel')}</label>\n <Input value={reason} onChange={(e) => setReason(e.target.value)} disabled={busy} />\n {error && <p className=\"text-sm text-destructive\">{error}</p>}\n </div>\n <ModalFooter>\n <Button variant=\"outline\" onClick={onClose} disabled={busy}>{t('common.cancel')}</Button>\n <Button onClick={() => { void enter() }} disabled={busy}>\n <Eye className=\"mr-2 h-4 w-4\" />\n {t('impersonation.confirm')}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n","import * as React from 'react'\nimport { UserPlus, UserMinus, Mail, Clock, Building2, Send, Ban, Contact, Eye } from 'lucide-react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Card, DataTable } from '@fayz-ai/ui'\nimport { Button } from '@fayz-ai/ui'\nimport { PageHeaderActions } from '@fayz-ai/ui'\nimport { RowActions } from '@fayz-ai/ui'\nimport { Badge } from '@fayz-ai/ui'\nimport { Avatar, AvatarFallback, AvatarImage } from '@fayz-ai/ui'\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@fayz-ai/ui'\nimport { PageActions, type PageAction } from '../../plugins/PageActions'\nimport { InviteMemberDialog } from './InviteMemberDialog'\nimport { toast } from '../notifications/ToastProvider'\nimport { useOrganizationStore } from '../../stores/organization.store'\nimport { usePermissionsStore } from '../../permissions/store'\nimport { useInviteStore } from '../../stores/invite.store'\nimport { useMemberAccessPanel, MemberUnitsCell, useUnitStore, useUnitBootstrap } from '../../units'\n// Native org adapter (see InviteMemberDialog) — the shell context is un-provided.\nimport { useOrgAdapterOptional as useNativeOrgAdapter } from '../../org'\nimport type { OrgAdapter } from '../../types/org-adapter'\nconst useOrgAdapterOptional = () => useNativeOrgAdapter() as unknown as OrgAdapter | null\nimport { useAuthStore } from '@fayz-ai/auth'\nimport { useSystemPermission } from '../../hooks/useSystemPermission'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { dedup } from '../../lib/dedup'\nimport { useLimitGuard } from '../../access/context'\nimport { invalidateLimit } from '../../access/limits-registry'\nimport { entityRouteHasDetail, openEntity } from '../../lib/entity-routes'\nimport { ImpersonateDialog, type ImpersonateTarget } from '../../impersonation/ImpersonateDialog'\n\n// A normalized team row: either a person (person-first mode) with an optional\n// access overlay, or a legacy tenant_members row. `memberId` present ⇒ has login+role.\ninterface TeamRow {\n key: string\n /** The person record behind the row, when there is one. Login-only rows\n * (the owner who never staffed herself) carry none. */\n personId?: string\n kind?: string\n name: string\n email: string\n avatarUrl?: string\n /** kind label shown next to the name in person mode (e.g. \"Staff\"). */\n subtitle?: string\n roleId?: string\n roleName?: string\n memberId?: string\n /** The auth user behind the row — what a unit binding is keyed by. */\n userId?: string\n hasAccess: boolean\n joinedAt?: string\n isCurrentUser: boolean\n}\n\nconst capitalize = (s: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s)\n\nexport function TeamTab() {\n const adapter = useOrgAdapterOptional()\n const currentOrg = useOrganizationStore((s) => s.currentOrg)\n const members = useOrganizationStore((s) => s.members)\n const setMembers = useOrganizationStore((s) => s.setMembers)\n const teamPersonKinds = useOrganizationStore((s) => s.teamPersonKinds)\n const profiles = usePermissionsStore((s) => s.profiles)\n const invites = useInviteStore((s) => s.invites)\n const setInvites = useInviteStore((s) => s.setInvites)\n const { user } = useAuthStore()\n const hasSystemPermission = useSystemPermission()\n\n // Person-first mode: drive the list from people of the configured kinds when\n // the adapter supports it. Otherwise fall back to the legacy members list.\n const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === 'function'\n const [team, setTeam] = React.useState<Awaited<ReturnType<NonNullable<OrgAdapter['listTeam']>>> | null>(null)\n\n const [inviteOpen, setInviteOpen] = React.useState(false)\n // Seat cap ('users' limit → tenant_members count). Guarded before opening the\n // invite dialog; the guard opens the global UpgradeModal when at the cap.\n const guardSeats = useLimitGuard('users')\n\n // Quem o convite está convidando. Um diálogo em branco aberto a partir da\n // LINHA de alguém fazia digitar de memória o e-mail de quem já estava na\n // tela — e o e-mail digitado ali é o que decide se o convite aceito vira a\n // mesma pessoa ou uma segunda ficha (ver a aba Acesso).\n const [inviteEmail, setInviteEmail] = React.useState<string | undefined>(undefined)\n\n const handleOpenInvite = async (row?: TeamRow) => {\n // Sem e-mail na ficha não há o que preencher, e adivinhar é justamente o\n // erro: a ficha da pessoa é onde o e-mail se resolve e se GRAVA.\n if (row && !row.email && row.personId && entityRouteHasDetail('person', row.kind)) {\n openEntity(row.personId, 'person', row.kind, 'access')\n return\n }\n if ((await guardSeats(1)) === 'blocked') return\n setInviteEmail(row?.email || undefined)\n setInviteOpen(true)\n }\n\n const reloadTeam = React.useCallback(async () => {\n if (!adapter || !currentOrg) return\n if (personMode && adapter.listTeam) {\n setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds))\n } else {\n setMembers(await adapter.listMembers(currentOrg.id))\n }\n }, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers])\n\n // Load the person-first team list when in person mode (deduped).\n React.useEffect(() => {\n if (personMode && adapter?.listTeam && currentOrg) {\n dedup('team:people:' + currentOrg.id, () => adapter.listTeam!(currentOrg.id, teamPersonKinds))\n .then(setTeam)\n .catch(() => setTeam([]))\n }\n }, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(',')])\n\n // Load invites on mount (deduped to avoid strict mode double-fetch)\n React.useEffect(() => {\n if (adapter && currentOrg) {\n dedup('team:invites:' + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {})\n }\n }, [adapter, currentOrg?.id])\n\n const handleChangeProfile = async (memberId: string, profileId: string) => {\n if (!adapter || !currentOrg) return\n try {\n await adapter.updateMemberProfile(currentOrg.id, memberId, profileId)\n await reloadTeam()\n } catch {\n // ignore\n }\n }\n\n const handleRemoveMember = async (memberId: string) => {\n if (!adapter || !currentOrg) return\n try {\n await adapter.removeMember(currentOrg.id, memberId)\n await reloadTeam()\n } catch {\n // ignore\n }\n }\n\n // Which units a person works in — only offered once the org actually works\n // with units, so a single-site business never sees the concept.\n useUnitBootstrap()\n const unitMode = useUnitStore((st) => st.unitMode)\n // Abre na coluna da direita, ao lado da lista, e não numa gaveta por cima\n // dela: ver as unidades de alguém é consulta, não destino.\n const openMemberAccess = useMemberAccessPanel((st) => st.openMember)\n\n // Normalized rows for the table — person-first or legacy members.\n const rows: TeamRow[] = personMode\n ? (team ?? []).map((p) => ({\n // Login-only rows carry no personId — key off the membership instead.\n key: p.personId ?? p.membership?.memberId ?? p.name,\n personId: p.personId,\n kind: p.kind,\n name: p.name,\n email: p.email ?? '',\n avatarUrl: p.avatarUrl,\n subtitle: p.kind ? capitalize(p.kind) : undefined,\n roleId: p.membership?.profileId,\n roleName: p.membership?.profileName,\n memberId: p.membership?.memberId,\n userId: p.membership?.userId,\n hasAccess: !!p.membership,\n joinedAt: p.membership?.joinedAt,\n isCurrentUser: p.membership?.userId === user?.id,\n }))\n : members.map((m) => ({\n key: m.id,\n personId: m.personId,\n kind: m.personKind,\n name: m.user.fullName,\n email: m.user.email,\n avatarUrl: m.user.avatarUrl,\n roleId: m.profileId,\n roleName: m.profileName,\n memberId: m.id,\n userId: m.userId,\n hasAccess: true,\n joinedAt: m.joinedAt,\n isCurrentUser: m.userId === user?.id,\n }))\n const rowsLoading = personMode ? team === null : members.length === 0\n\n const handleRevokeInvite = async (inviteId: string) => {\n if (!adapter || !currentOrg) return\n try {\n await adapter.revokeInvite(currentOrg.id, inviteId)\n const updated = await adapter.listInvites(currentOrg.id)\n setInvites(updated)\n toast.success(t('organization.team.inviteRevoked'))\n } catch (err: any) {\n toast.error(t('organization.team.inviteActionFailed'), { description: err?.message })\n }\n }\n\n const handleResendInvite = async (inviteId: string) => {\n if (!adapter || !currentOrg) return\n try {\n await adapter.resendInvite(currentOrg.id, inviteId)\n const updated = await adapter.listInvites(currentOrg.id)\n setInvites(updated)\n toast.success(t('organization.team.inviteResent'))\n } catch (err: any) {\n toast.error(t('organization.team.inviteActionFailed'), { description: err?.message })\n }\n }\n\n const { t } = useTranslation()\n const canManageTeam = hasSystemPermission('manage_team')\n const [viewAs, setViewAs] = React.useState<ImpersonateTarget | null>(null)\n const inviteActions = React.useMemo<PageAction[]>(() => [{\n id: 'invite',\n label: t('organization.team.invite'),\n icon: UserPlus,\n intent: 'primary',\n // Inviting IS how a person gets added here, so the phone's circle is a \"+\".\n creates: true,\n onSelect: () => { void handleOpenInvite() },\n }], [t])\n const pendingInvites = invites.filter((i) => i.status === 'pending')\n\n const columns: ColumnDef<TeamRow>[] = [\n {\n id: 'member',\n header: t('organization.team.member'),\n cell: ({ row: { original: row } }) => {\n const initials = (row.name || '?')\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2)\n return (\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"h-8 w-8\">\n {row.avatarUrl && <AvatarImage src={row.avatarUrl} />}\n <AvatarFallback className=\"text-xs\">{initials}</AvatarFallback>\n </Avatar>\n <div>\n <p className=\"text-sm font-medium\">\n {row.name}\n {row.isCurrentUser && <span className=\"text-muted-foreground ml-1\">{t('organization.team.you')}</span>}\n {row.subtitle && <Badge variant=\"outline\" className=\"ml-2 text-[10px] font-normal\">{row.subtitle}</Badge>}\n </p>\n {row.email && <p className=\"text-xs text-muted-foreground\">{row.email}</p>}\n </div>\n </div>\n )\n },\n },\n {\n id: 'role',\n header: t('organization.team.role'),\n cell: ({ row: { original: row } }) =>\n !row.hasAccess ? (\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\" className=\"text-xs text-muted-foreground\">{t('organization.team.noAccess')}</Badge>\n {canManageTeam && (\n <Button variant=\"ghost\" size=\"sm\" className=\"h-7 text-xs\" onClick={() => { void handleOpenInvite(row) }}>\n <UserPlus className=\"h-3 w-3 mr-1\" />\n {t('organization.team.invite')}\n </Button>\n )}\n </div>\n ) : canManageTeam && !row.isCurrentUser && row.memberId ? (\n <Select\n value={row.roleId}\n onValueChange={(val) => handleChangeProfile(row.memberId!, val)}\n >\n <SelectTrigger className=\"h-8 w-36 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {profiles.map((p) => (\n <SelectItem key={p.id} value={p.id}>{p.name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {profiles.find((p) => p.id === row.roleId)?.name ?? row.roleName}\n </Badge>\n ),\n },\n ...(unitMode ? [{\n id: 'units',\n header: 'Unidades',\n cell: ({ row: { original: row } }) => (\n <MemberUnitsCell\n userId={row.userId}\n onManage={canManageTeam && row.userId\n ? () => openMemberAccess({ userId: row.userId!, name: row.name, email: row.email })\n : undefined}\n />\n ),\n } satisfies ColumnDef<TeamRow>] : []),\n {\n id: 'joined',\n header: t('organization.team.joined'),\n cell: ({ row: { original: row } }) => (\n <span className=\"text-sm text-muted-foreground\">\n {row.joinedAt ? new Date(row.joinedAt).toLocaleDateString() : '—'}\n </span>\n ),\n },\n ...(canManageTeam ? [{\n id: 'actions',\n header: '',\n meta: { className: 'w-12 text-right' },\n cell: ({ row: { original: row } }) => (\n <RowActions\n actions={[\n // A ficha é onde acesso, unidades, escala e\n // histórico da pessoa moram juntos — esta tela é\n // a lista, não o lugar de editar cada um deles.\n {\n id: 'record',\n label: t('organization.team.openRecord'),\n icon: Contact,\n hidden: !row.personId || !entityRouteHasDetail('person', row.kind),\n onSelect: () => openEntity(row.personId!, 'person', row.kind, 'access'),\n },\n {\n id: 'units',\n label: t('organization.team.unitAccess'),\n icon: Building2,\n hidden: !unitMode || !row.userId || !row.hasAccess,\n onSelect: () => openMemberAccess({ userId: row.userId!, name: row.name, email: row.email }),\n },\n {\n id: 'impersonate',\n label: t('impersonation.action'),\n icon: Eye,\n // The owner is out of reach on the server too.\n hidden: !row.hasAccess || row.isCurrentUser || !row.userId || row.roleId === 'owner',\n onSelect: () => setViewAs({ userId: row.userId!, name: row.name }),\n },\n {\n id: 'remove',\n label: t('organization.team.removeMember'),\n icon: UserMinus,\n intent: 'danger',\n hidden: !row.hasAccess || row.isCurrentUser || !row.memberId,\n onSelect: () => handleRemoveMember(row.memberId!),\n },\n ]}\n />\n ),\n } satisfies ColumnDef<TeamRow>] : []),\n ]\n\n return (\n <div className=\"space-y-6\">\n {currentOrg && <ImpersonateDialog tenantId={currentOrg.id} target={viewAs} onClose={() => setViewAs(null)} />}\n {/* Members */}\n <div>\n {/* O nome da tela é da barra (\"Equipe\"); aqui fica só a contagem, e o\n convidar sobe para a direita da barra como toda ação de página. */}\n {canManageTeam && (\n <PageHeaderActions>\n {/* Declared, not drawn: the shell renders it in the header bar on a\n desktop and as the circle in the thumb's corner on a phone. The\n seat cap is already guarded inside handleOpenInvite, so this\n does NOT repeat it as a limitKey. */}\n <PageActions actions={inviteActions} />\n </PageHeaderActions>\n )}\n <p className=\"mb-4 text-sm text-muted-foreground\">\n {t('organization.team.memberCount', { count: String(rows.length), plural: rows.length !== 1 ? 's' : '' })}\n </p>\n\n <Card className=\"overflow-hidden\">\n <DataTable\n variant=\"bare\"\n columns={columns}\n data={rows}\n loading={rowsLoading}\n getRowId={(row) => row.key}\n emptyMessage={t('organization.team.empty')}\n />\n </Card>\n </div>\n\n\n {/* Pending Invites */}\n {pendingInvites.length > 0 && (\n <div>\n <h3 className=\"text-lg font-semibold mb-3\">{t('organization.team.pendingInvites')}</h3>\n <div className=\"space-y-2\">\n {pendingInvites.map((invite) => (\n <Card key={invite.id} className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-muted\">\n <Mail className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium\">{invite.email}</p>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <Badge variant=\"secondary\" className=\"text-xs\">{invite.profileName}</Badge>\n <span className=\"flex items-center gap-1\">\n <Clock className=\"h-3 w-3\" />\n Sent {new Date(invite.createdAt).toLocaleDateString()}\n </span>\n </div>\n </div>\n {canManageTeam && (\n <RowActions\n actions={[\n {\n id: 'resend',\n label: t('organization.team.resend'),\n icon: Send,\n onSelect: () => handleResendInvite(invite.id),\n },\n {\n id: 'revoke',\n label: t('organization.team.revoke'),\n icon: Ban,\n intent: 'danger',\n onSelect: () => handleRevokeInvite(invite.id),\n },\n ]}\n />\n )}\n </div>\n </Card>\n ))}\n </div>\n </div>\n )}\n\n <InviteMemberDialog\n open={inviteOpen}\n defaultEmail={inviteEmail}\n onOpenChange={(open) => {\n setInviteOpen(open)\n // On close (after a successful invite the dialog closes itself),\n // refresh the seat count so the guard/banner reflect the new member.\n if (!open) {\n invalidateLimit('users')\n setInviteEmail(undefined)\n void reloadTeam()\n }\n }}\n />\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { TrialWidget } from './chunk-BG5Z6KLN.js';
|
|
2
|
+
import './chunk-SGAFPNMA.js';
|
|
3
|
+
import './chunk-JRZJBMOY.js';
|
|
4
|
+
import './chunk-YKPPCV2Z.js';
|
|
5
|
+
import './chunk-QD7BMUDF.js';
|
|
6
|
+
//# sourceMappingURL=TrialWidget-Z6CLUCU3.js.map
|
|
7
|
+
//# sourceMappingURL=TrialWidget-Z6CLUCU3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"TrialWidget-Z6CLUCU3.js"}
|