@burdenoff/microfe-planmagnet 2026.928.2 → 2026.928.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoot.js +102 -84
  3. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  4. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  5. package/dist/planmagnet/PlanMagnetRoutes.js +103 -55
  6. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  7. package/dist/planmagnet/controls/CompetitorControls.d.ts +20 -0
  8. package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -0
  9. package/dist/planmagnet/controls/CompetitorControls.js +172 -0
  10. package/dist/planmagnet/controls/CompetitorControls.js.map +1 -0
  11. package/dist/planmagnet/controls/FeatureControls.js +29 -29
  12. package/dist/planmagnet/controls/FeatureTriage.js +11 -11
  13. package/dist/planmagnet/controls/ObjectiveControls.js +24 -24
  14. package/dist/planmagnet/controls/Pickers.d.ts +17 -2
  15. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  16. package/dist/planmagnet/controls/Pickers.js +100 -9
  17. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  18. package/dist/planmagnet/controls/PortfolioControls.d.ts +13 -0
  19. package/dist/planmagnet/controls/PortfolioControls.d.ts.map +1 -0
  20. package/dist/planmagnet/controls/PortfolioControls.js +114 -0
  21. package/dist/planmagnet/controls/PortfolioControls.js.map +1 -0
  22. package/dist/planmagnet/controls/ProgramControls.d.ts +25 -0
  23. package/dist/planmagnet/controls/ProgramControls.d.ts.map +1 -0
  24. package/dist/planmagnet/controls/ProgramControls.js +187 -0
  25. package/dist/planmagnet/controls/ProgramControls.js.map +1 -0
  26. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts +2 -0
  27. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -0
  28. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +127 -0
  29. package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -0
  30. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts +2 -0
  31. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -0
  32. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +129 -0
  33. package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -0
  34. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts +2 -0
  35. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -0
  36. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +132 -0
  37. package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -0
  38. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts +2 -0
  39. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -0
  40. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +181 -0
  41. package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -0
  42. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts +2 -0
  43. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +1 -0
  44. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +242 -0
  45. package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +1 -0
  46. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts +2 -0
  47. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +1 -0
  48. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +302 -0
  49. package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +1 -0
  50. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts +2 -0
  51. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -0
  52. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +335 -0
  53. package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -0
  54. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts +2 -0
  55. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +1 -0
  56. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +154 -0
  57. package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +1 -0
  58. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  59. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +124 -138
  60. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  61. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts +2 -0
  62. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +1 -0
  63. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +221 -0
  64. package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +1 -0
  65. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts +2 -0
  66. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +1 -0
  67. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +279 -0
  68. package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +1 -0
  69. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts +2 -0
  70. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +1 -0
  71. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +178 -0
  72. package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +1 -0
  73. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts +2 -0
  74. package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +1 -0
  75. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +157 -0
  76. package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +1 -0
  77. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
  78. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +130 -103
  79. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
  80. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  81. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +156 -136
  82. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  83. package/dist/planmagnet/pages/TasksImportPagePage.js +5 -5
  84. package/dist/planmagnet/types/index.d.ts.map +1 -1
  85. package/package.json +1 -1
@@ -0,0 +1,172 @@
1
+ import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
+ import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
3
+ import { detailPath as r } from "../utils/rowNavigation.js";
4
+ import { ConfirmButton as i, ErrorLine as a } from "./ConfirmButton.js";
5
+ import { CompetitorSearchSelect as o } from "./Pickers.js";
6
+ import { useState as s } from "react";
7
+ import { Pencil as c, Plus as l, Trash2 as u, X as d } from "lucide-react";
8
+ import { gql as f } from "@apollo/client";
9
+ import { useMutation as p } from "@apollo/client/react";
10
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
11
+ import { Button as g } from "@burdenoff/fe-libs/ui";
12
+ //#region src/planmagnet/controls/CompetitorControls.tsx
13
+ var _ = [
14
+ "ListCompetitors",
15
+ "GetCompetitor",
16
+ "GetCompetitorForEdit"
17
+ ], v = f`
18
+ mutation CompetitorControlsDelete($id: ID!) {
19
+ planmagnetDeleteCompetitor(id: $id)
20
+ }
21
+ `;
22
+ function y({ competitorId: o, name: l }) {
23
+ let d = e(), [f, y] = p(v, {
24
+ refetchQueries: _.filter((e) => e !== "GetCompetitor"),
25
+ context: t
26
+ }), [b, x] = s(null), S = async () => {
27
+ x(null);
28
+ try {
29
+ await n(f({ variables: { id: o } })), d("/products/competitors-page");
30
+ } catch (e) {
31
+ x(e instanceof Error ? e.message : "The competitor could not be deleted.");
32
+ }
33
+ };
34
+ return /* @__PURE__ */ h("div", {
35
+ className: "flex flex-col items-end gap-2",
36
+ children: [/* @__PURE__ */ h("div", {
37
+ className: "flex flex-wrap items-center justify-end gap-2",
38
+ children: [/* @__PURE__ */ h(g, {
39
+ size: "sm",
40
+ variant: "outline",
41
+ "data-testid": "competitor-edit",
42
+ onClick: () => d(r("/products/edit-competitor-page", o)),
43
+ children: [/* @__PURE__ */ m(c, { className: "mr-1 h-4 w-4" }), "Edit"]
44
+ }), /* @__PURE__ */ m(i, {
45
+ label: "Delete",
46
+ variant: "outline",
47
+ icon: /* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }),
48
+ title: `Delete ${l}?`,
49
+ description: "The competitor is deleted and unlinked from every feature request that referenced it. This cannot be undone here.",
50
+ confirmLabel: "Delete competitor",
51
+ destructive: !0,
52
+ disabled: y.loading,
53
+ onConfirm: () => void S()
54
+ })]
55
+ }), b && /* @__PURE__ */ m(a, { message: b })]
56
+ });
57
+ }
58
+ var b = f`
59
+ mutation CompetitorLinkCardLink($input: PlanmagnetLinkCompetitorInput!) {
60
+ planmagnetLinkCompetitorToFeature(input: $input) {
61
+ id
62
+ competitors {
63
+ id
64
+ name
65
+ description
66
+ website
67
+ }
68
+ }
69
+ }
70
+ `, x = f`
71
+ mutation CompetitorLinkCardUnlink($input: PlanmagnetLinkCompetitorInput!) {
72
+ planmagnetUnlinkCompetitorFromFeature(input: $input) {
73
+ id
74
+ competitors {
75
+ id
76
+ name
77
+ description
78
+ website
79
+ }
80
+ }
81
+ }
82
+ `;
83
+ function S({ featureRequestId: t, competitors: i }) {
84
+ let c = e(), [u, f] = s(""), [_, v] = p(b), [y, S] = p(x), [C, w] = s(null), T = v.loading || S.loading, E = async () => {
85
+ if (u) {
86
+ w(null);
87
+ try {
88
+ await n(_({ variables: { input: {
89
+ featureRequestId: t,
90
+ competitorId: u
91
+ } } })), f("");
92
+ } catch (e) {
93
+ w(e instanceof Error ? e.message : "The competitor could not be linked.");
94
+ }
95
+ }
96
+ }, D = async (e) => {
97
+ w(null);
98
+ try {
99
+ await n(y({ variables: { input: {
100
+ featureRequestId: t,
101
+ competitorId: e
102
+ } } }));
103
+ } catch (e) {
104
+ w(e instanceof Error ? e.message : "The competitor could not be removed.");
105
+ }
106
+ };
107
+ return /* @__PURE__ */ h("div", {
108
+ className: "space-y-3",
109
+ children: [
110
+ i.length === 0 && /* @__PURE__ */ m("p", {
111
+ className: "text-sm text-muted-foreground",
112
+ children: "No competitors linked yet."
113
+ }),
114
+ i.map((e) => /* @__PURE__ */ h("div", {
115
+ className: "flex items-start justify-between gap-2 rounded-md border p-3",
116
+ children: [/* @__PURE__ */ h("button", {
117
+ type: "button",
118
+ className: "flex-1 text-left",
119
+ onClick: () => c(r("/products/competitor-detail-page", e.id)),
120
+ children: [/* @__PURE__ */ h("div", {
121
+ className: "flex items-center gap-2",
122
+ children: [/* @__PURE__ */ m("span", {
123
+ className: "text-sm font-medium hover:underline underline-offset-2",
124
+ children: e.name
125
+ }), e.website && /* @__PURE__ */ m("span", {
126
+ className: "text-xs text-primary",
127
+ children: e.website
128
+ })]
129
+ }), e.description && /* @__PURE__ */ m("p", {
130
+ className: "text-xs text-muted-foreground mt-1",
131
+ children: e.description
132
+ })]
133
+ }), /* @__PURE__ */ m(g, {
134
+ size: "sm",
135
+ variant: "ghost",
136
+ "aria-label": `Remove ${e.name} from this feature`,
137
+ disabled: T,
138
+ onClick: () => void D(e.id),
139
+ children: /* @__PURE__ */ m(d, { className: "h-4 w-4" })
140
+ })]
141
+ }, e.id)),
142
+ /* @__PURE__ */ h("div", {
143
+ className: "flex items-start gap-2 pt-2 border-t",
144
+ children: [/* @__PURE__ */ m("div", {
145
+ className: "flex-1",
146
+ children: /* @__PURE__ */ m(o, {
147
+ id: "feature-add-competitor",
148
+ value: u,
149
+ onChange: f,
150
+ exclude: i.map((e) => e.id)
151
+ })
152
+ }), /* @__PURE__ */ h(g, {
153
+ size: "sm",
154
+ disabled: !u || T,
155
+ onClick: () => void E(),
156
+ children: [/* @__PURE__ */ m(l, { className: "mr-1 h-4 w-4" }), "Add"]
157
+ })]
158
+ }),
159
+ /* @__PURE__ */ h(g, {
160
+ size: "sm",
161
+ variant: "ghost",
162
+ onClick: () => c("/products/create-competitor-page"),
163
+ children: [/* @__PURE__ */ m(l, { className: "mr-1 h-4 w-4" }), "New competitor"]
164
+ }),
165
+ C && /* @__PURE__ */ m(a, { message: C })
166
+ ]
167
+ });
168
+ }
169
+ //#endregion
170
+ export { y as CompetitorHeaderActions, S as CompetitorLinkCard };
171
+
172
+ //# sourceMappingURL=CompetitorControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompetitorControls.js","names":[],"sources":["../../../src/planmagnet/controls/CompetitorControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Pencil, Trash2, X, Plus } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { ConfirmButton, ErrorLine } from './ConfirmButton';\nimport { CompetitorSearchSelect } from './Pickers';\n\n/**\n * Competitor controls (BOFF-8047). Competitors were `api-only` — full CRUD plus link/unlink onto a feature\n * request existed in the service, bundled with `planmagnet-feature` RBAC (CORRECTIONS.md B), but had zero\n * routes and no write UI: the feature request detail page could only ever display what was already linked.\n */\n\nconst COMPETITOR_QUERIES = ['ListCompetitors', 'GetCompetitor', 'GetCompetitorForEdit'];\n\nconst DELETE = gql`\n mutation CompetitorControlsDelete($id: ID!) {\n planmagnetDeleteCompetitor(id: $id)\n }\n`;\n\nexport function CompetitorHeaderActions({\n competitorId,\n name,\n}: {\n competitorId: string;\n name: string;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [remove, removeState] = useMutation(DELETE, {\n refetchQueries: COMPETITOR_QUERIES.filter((q) => q !== 'GetCompetitor'),\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: competitorId } }));\n navigate('/products/competitors-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The competitor could not be deleted.');\n }\n };\n\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"competitor-edit\"\n onClick={() => navigate(detailPath('/products/edit-competitor-page', competitorId))}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete ${name}?`}\n description=\"The competitor is deleted and unlinked from every feature request that referenced it. This cannot be undone here.\"\n confirmLabel=\"Delete competitor\"\n destructive\n disabled={removeState.loading}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\nconst LINK = gql`\n mutation CompetitorLinkCardLink($input: PlanmagnetLinkCompetitorInput!) {\n planmagnetLinkCompetitorToFeature(input: $input) {\n id\n competitors {\n id\n name\n description\n website\n }\n }\n }\n`;\nconst UNLINK = gql`\n mutation CompetitorLinkCardUnlink($input: PlanmagnetLinkCompetitorInput!) {\n planmagnetUnlinkCompetitorFromFeature(input: $input) {\n id\n competitors {\n id\n name\n description\n website\n }\n }\n }\n`;\n\ninterface CompetitorNode {\n id: string;\n name: string;\n description: string | null;\n website: string | null;\n}\n\n/**\n * The feature request detail page's competitor section: list what is linked, remove any of them, and add\n * another from the workspace's competitor directory (or create a new one there).\n */\nexport function CompetitorLinkCard({\n featureRequestId,\n competitors,\n}: {\n featureRequestId: string;\n competitors: CompetitorNode[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [addCompetitorId, setAddCompetitorId] = useState('');\n const [link, linkState] = useMutation(LINK);\n const [unlink, unlinkState] = useMutation(UNLINK);\n const [error, setError] = useState<string | null>(null);\n const busy = linkState.loading || unlinkState.loading;\n\n const onAdd = async () => {\n if (!addCompetitorId) return;\n setError(null);\n try {\n await throwOnError(\n link({\n variables: { input: { featureRequestId, competitorId: addCompetitorId } },\n })\n );\n setAddCompetitorId('');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The competitor could not be linked.');\n }\n };\n const onRemove = async (competitorId: string) => {\n setError(null);\n try {\n await throwOnError(unlink({ variables: { input: { featureRequestId, competitorId } } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The competitor could not be removed.');\n }\n };\n\n return (\n <div className=\"space-y-3\">\n {competitors.length === 0 && (\n <p className=\"text-sm text-muted-foreground\">No competitors linked yet.</p>\n )}\n {competitors.map((comp) => (\n <div key={comp.id} className=\"flex items-start justify-between gap-2 rounded-md border p-3\">\n <button\n type=\"button\"\n className=\"flex-1 text-left\"\n onClick={() => navigate(detailPath('/products/competitor-detail-page', comp.id))}\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium hover:underline underline-offset-2\">\n {comp.name}\n </span>\n {comp.website && <span className=\"text-xs text-primary\">{comp.website}</span>}\n </div>\n {comp.description && (\n <p className=\"text-xs text-muted-foreground mt-1\">{comp.description}</p>\n )}\n </button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Remove ${comp.name} from this feature`}\n disabled={busy}\n onClick={() => void onRemove(comp.id)}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n ))}\n <div className=\"flex items-start gap-2 pt-2 border-t\">\n <div className=\"flex-1\">\n <CompetitorSearchSelect\n id=\"feature-add-competitor\"\n value={addCompetitorId}\n onChange={setAddCompetitorId}\n exclude={competitors.map((c) => c.id)}\n />\n </div>\n <Button size=\"sm\" disabled={!addCompetitorId || busy} onClick={() => void onAdd()}>\n <Plus className=\"mr-1 h-4 w-4\" />\n Add\n </Button>\n </div>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => navigate('/products/create-competitor-page')}\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n New competitor\n </Button>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { LEAVES_PAGE_CONTEXT as t, throwOnError as n } from "../utils/mutationResult.js";
3
3
  import { detailPath as r } from "../utils/rowNavigation.js";
4
- import { ProjectSelect as i, WorkItemSearchSelect as a } from "./Pickers.js";
5
- import { ConfirmButton as o, ErrorLine as s } from "./ConfirmButton.js";
4
+ import { ConfirmButton as i, ErrorLine as a } from "./ConfirmButton.js";
5
+ import { ProjectSelect as o, WorkItemSearchSelect as s } from "./Pickers.js";
6
6
  import { parseIntField as c } from "../utils/formValidation.js";
7
7
  import { enumLabel as l } from "./WorkItemControls.js";
8
8
  import { useState as u } from "react";
@@ -60,10 +60,10 @@ var O = [
60
60
  awaitRefetchQueries: !0
61
61
  };
62
62
  function F({ featureId: e, voted: t }) {
63
- let [r, i] = g(A, P), [a, o] = g(j, P), [c, l] = u(null), d = i.loading || o.loading, f = async () => {
63
+ let [r, i] = g(A, P), [o, s] = g(j, P), [c, l] = u(null), d = i.loading || s.loading, f = async () => {
64
64
  l(null);
65
65
  try {
66
- await n((t ? a : r)({ variables: { id: e } }));
66
+ await n((t ? o : r)({ variables: { id: e } }));
67
67
  } catch (e) {
68
68
  l(e instanceof Error ? e.message : "Your vote could not be saved.");
69
69
  }
@@ -78,18 +78,18 @@ function F({ featureId: e, voted: t }) {
78
78
  disabled: d,
79
79
  onClick: () => void f(),
80
80
  children: [/* @__PURE__ */ _(p, { className: "mr-1 h-4 w-4" }), t ? "Voted" : "Vote"]
81
- }), c && /* @__PURE__ */ _(s, { message: c })]
81
+ }), c && /* @__PURE__ */ _(a, { message: c })]
82
82
  });
83
83
  }
84
- function I({ feature: i }) {
85
- let a = e(), [c, f] = g(M, P), [p, h] = g(N, {
84
+ function I({ feature: o }) {
85
+ let s = e(), [c, f] = g(M, P), [p, h] = g(N, {
86
86
  refetchQueries: k.filter((e) => e !== "GetFeatureRequest"),
87
87
  context: t
88
- }), [b, x] = u(null), S = f.loading || h.loading, C = O.includes(i.status) ? O : [i.status, ...O], w = async (e) => {
88
+ }), [b, x] = u(null), S = f.loading || h.loading, C = O.includes(o.status) ? O : [o.status, ...O], w = async (e) => {
89
89
  x(null);
90
90
  try {
91
91
  await n(c({ variables: {
92
- id: i.id,
92
+ id: o.id,
93
93
  input: { status: e }
94
94
  } }));
95
95
  } catch (e) {
@@ -98,7 +98,7 @@ function I({ feature: i }) {
98
98
  }, T = async () => {
99
99
  x(null);
100
100
  try {
101
- await n(p({ variables: { id: i.id } })), a("/products/features-page");
101
+ await n(p({ variables: { id: o.id } })), s("/products/features-page");
102
102
  } catch (e) {
103
103
  x(e instanceof Error ? e.message : "The request could not be deleted.");
104
104
  }
@@ -112,29 +112,29 @@ function I({ feature: i }) {
112
112
  "aria-label": "Status",
113
113
  "data-testid": "feature-status",
114
114
  className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
115
- value: i.status,
115
+ value: o.status,
116
116
  disabled: S,
117
117
  onChange: (e) => {
118
- e.target.value !== i.status && w(e.target.value);
118
+ e.target.value !== o.status && w(e.target.value);
119
119
  },
120
120
  children: C.map((e) => /* @__PURE__ */ _("option", {
121
121
  value: e,
122
122
  children: l(e)
123
123
  }, e))
124
124
  }),
125
- /* @__PURE__ */ _(L, { feature: i }),
125
+ /* @__PURE__ */ _(L, { feature: o }),
126
126
  /* @__PURE__ */ v(y, {
127
127
  size: "sm",
128
128
  variant: "outline",
129
129
  "data-testid": "feature-analytics",
130
- onClick: () => a(r("/products/feature-analytics-page", i.id)),
130
+ onClick: () => s(r("/products/feature-analytics-page", o.id)),
131
131
  children: [/* @__PURE__ */ _(d, { className: "mr-1 h-4 w-4" }), "Analytics"]
132
132
  }),
133
- /* @__PURE__ */ _(o, {
133
+ /* @__PURE__ */ _(i, {
134
134
  label: "Delete",
135
135
  variant: "outline",
136
136
  icon: /* @__PURE__ */ _(m, { className: "mr-1 h-4 w-4" }),
137
- title: `Delete "${i.title}"?`,
137
+ title: `Delete "${o.title}"?`,
138
138
  description: "The request and its votes are deleted. This cannot be undone here.",
139
139
  confirmLabel: "Delete request",
140
140
  destructive: !0,
@@ -142,7 +142,7 @@ function I({ feature: i }) {
142
142
  onConfirm: () => void T()
143
143
  })
144
144
  ]
145
- }), b && /* @__PURE__ */ _(s, { message: b })]
145
+ }), b && /* @__PURE__ */ _(a, { message: b })]
146
146
  });
147
147
  }
148
148
  function L({ feature: e }) {
@@ -153,35 +153,35 @@ function L({ feature: e }) {
153
153
  effortEstimate: e.effortEstimate ?? "",
154
154
  projectId: e.projectId ?? "",
155
155
  workItemId: e.workItemId ?? ""
156
- }, [r, o] = u(!1), [l, d] = u(t), [p, m] = u(null), [h, O] = g(M, P), k = c(l.businessValue, {
156
+ }, [r, i] = u(!1), [l, d] = u(t), [p, m] = u(null), [h, O] = g(M, P), k = c(l.businessValue, {
157
157
  min: 0,
158
158
  max: 100
159
159
  }), A = l.title.trim() !== "" && !k.invalid && !O.loading, j = async () => {
160
160
  m(null);
161
- let r = (e) => e.trim() ? e.trim() : null, i = {
161
+ let r = (e) => e.trim() ? e.trim() : null, a = {
162
162
  title: l.title.trim(),
163
163
  description: r(l.description),
164
164
  businessValue: k.value ?? null,
165
165
  effortEstimate: r(l.effortEstimate),
166
166
  projectId: l.projectId || null,
167
167
  workItemId: l.workItemId || null
168
- }, a = {
168
+ }, o = {
169
169
  title: t.title,
170
170
  description: r(t.description),
171
171
  businessValue: t.businessValue === "" ? null : Number(t.businessValue),
172
172
  effortEstimate: r(t.effortEstimate),
173
173
  projectId: t.projectId || null,
174
174
  workItemId: t.workItemId || null
175
- }, s = Object.fromEntries(Object.entries(i).filter(([e, t]) => t !== a[e]));
175
+ }, s = Object.fromEntries(Object.entries(a).filter(([e, t]) => t !== o[e]));
176
176
  if (Object.keys(s).length === 0) {
177
- o(!1);
177
+ i(!1);
178
178
  return;
179
179
  }
180
180
  try {
181
181
  await n(h({ variables: {
182
182
  id: e.id,
183
183
  input: s
184
- } })), o(!1);
184
+ } })), i(!1);
185
185
  } catch (e) {
186
186
  m(e instanceof Error ? e.message : "The request could not be saved.");
187
187
  }
@@ -189,7 +189,7 @@ function L({ feature: e }) {
189
189
  return /* @__PURE__ */ v(x, {
190
190
  open: r,
191
191
  onOpenChange: (e) => {
192
- o(e), e ? d(t) : m(null);
192
+ i(e), e ? d(t) : m(null);
193
193
  },
194
194
  children: [/* @__PURE__ */ _(D, {
195
195
  asChild: !0,
@@ -265,14 +265,14 @@ function L({ feature: e }) {
265
265
  })
266
266
  })] })]
267
267
  }),
268
- k.invalid && /* @__PURE__ */ _(s, { message: "Business value is a whole number from 0 to 100." }),
268
+ k.invalid && /* @__PURE__ */ _(a, { message: "Business value is a whole number from 0 to 100." }),
269
269
  /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
270
270
  htmlFor: "feature-edit-project",
271
271
  className: N,
272
272
  children: "Project"
273
273
  }), /* @__PURE__ */ _("div", {
274
274
  className: "mt-1",
275
- children: /* @__PURE__ */ _(i, {
275
+ children: /* @__PURE__ */ _(o, {
276
276
  id: "feature-edit-project",
277
277
  value: l.projectId,
278
278
  noneLabel: "No project",
@@ -289,7 +289,7 @@ function L({ feature: e }) {
289
289
  children: "Delivered by work item"
290
290
  }), /* @__PURE__ */ _("div", {
291
291
  className: "mt-1",
292
- children: /* @__PURE__ */ _(a, {
292
+ children: /* @__PURE__ */ _(s, {
293
293
  id: "feature-edit-workitem",
294
294
  projectId: l.projectId || void 0,
295
295
  value: l.workItemId,
@@ -299,12 +299,12 @@ function L({ feature: e }) {
299
299
  })
300
300
  })
301
301
  })] }),
302
- p && /* @__PURE__ */ _(s, { message: p })
302
+ p && /* @__PURE__ */ _(a, { message: p })
303
303
  ]
304
304
  }),
305
305
  /* @__PURE__ */ v(w, { children: [/* @__PURE__ */ _(y, {
306
306
  variant: "outline",
307
- onClick: () => o(!1),
307
+ onClick: () => i(!1),
308
308
  children: "Cancel"
309
309
  }), /* @__PURE__ */ _(y, {
310
310
  onClick: () => void j(),
@@ -1,7 +1,7 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { throwOnError as t } from "../utils/mutationResult.js";
3
- import { ProjectSelect as n } from "./Pickers.js";
4
- import { ErrorLine as r } from "./ConfirmButton.js";
3
+ import { ErrorLine as n } from "./ConfirmButton.js";
4
+ import { ProjectSelect as r } from "./Pickers.js";
5
5
  import { useDeferredValue as i, useState as a } from "react";
6
6
  import { AlarmClock as o, Check as s, GitMerge as c, Sun as l, X as u } from "lucide-react";
7
7
  import { gql as d } from "@apollo/client";
@@ -66,7 +66,7 @@ var E = {
66
66
  }
67
67
  }
68
68
  `, M = 2e3, N = ["SUBMITTED", "UNDER_REVIEW"], P = (e) => N.includes(e), F = (e, t) => !!e && new Date(e).getTime() > t, I = (e, t) => e instanceof Error ? e.message : t;
69
- function L({ trigger: e, testId: t, title: n, description: i, children: a, confirmLabel: o, canConfirm: s, busy: c, onConfirm: l, error: u, onOpenChange: d, open: f }) {
69
+ function L({ trigger: e, testId: t, title: r, description: i, children: a, confirmLabel: o, canConfirm: s, busy: c, onConfirm: l, error: u, onOpenChange: d, open: f }) {
70
70
  return /* @__PURE__ */ g(y, {
71
71
  open: f,
72
72
  onOpenChange: d,
@@ -83,10 +83,10 @@ function L({ trigger: e, testId: t, title: n, description: i, children: a, confi
83
83
  }), /* @__PURE__ */ g(b, {
84
84
  className: "max-w-lg",
85
85
  children: [
86
- /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(w, { children: n }), /* @__PURE__ */ h(x, { children: i })] }),
86
+ /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(w, { children: r }), /* @__PURE__ */ h(x, { children: i })] }),
87
87
  /* @__PURE__ */ g("div", {
88
88
  className: "space-y-3",
89
- children: [a, u && /* @__PURE__ */ h(r, { message: u })]
89
+ children: [a, u && /* @__PURE__ */ h(n, { message: u })]
90
90
  }),
91
91
  /* @__PURE__ */ g(S, { children: [/* @__PURE__ */ h(_, {
92
92
  variant: "outline",
@@ -102,7 +102,7 @@ function L({ trigger: e, testId: t, title: n, description: i, children: a, confi
102
102
  });
103
103
  }
104
104
  function R({ feature: e }) {
105
- let [r, i] = a(!1), [o, c] = a("PLANNED"), [l, u] = a(e.projectId ?? ""), [d, p] = a(null), [_, v] = f(D, E), y = async () => {
105
+ let [n, i] = a(!1), [o, c] = a("PLANNED"), [l, u] = a(e.projectId ?? ""), [d, p] = a(null), [_, v] = f(D, E), y = async () => {
106
106
  p(null);
107
107
  try {
108
108
  await t(_({ variables: {
@@ -117,7 +117,7 @@ function R({ feature: e }) {
117
117
  }
118
118
  };
119
119
  return /* @__PURE__ */ g(L, {
120
- open: r,
120
+ open: n,
121
121
  onOpenChange: (e) => {
122
122
  i(e), e || p(null);
123
123
  },
@@ -152,7 +152,7 @@ function R({ feature: e }) {
152
152
  children: "Project that will deliver it"
153
153
  }), /* @__PURE__ */ h("div", {
154
154
  className: "mt-1",
155
- children: /* @__PURE__ */ h(n, {
155
+ children: /* @__PURE__ */ h(r, {
156
156
  id: `triage-accept-project-${e.id}`,
157
157
  value: l,
158
158
  noneLabel: "No project yet",
@@ -354,10 +354,10 @@ function H({ feature: n }) {
354
354
  });
355
355
  }
356
356
  function U({ feature: e }) {
357
- let [n, i] = f(k, E), [o, s] = a(null), c = async () => {
357
+ let [r, i] = f(k, E), [o, s] = a(null), c = async () => {
358
358
  s(null);
359
359
  try {
360
- await t(n({ variables: {
360
+ await t(r({ variables: {
361
361
  id: e.id,
362
362
  until: null
363
363
  } }));
@@ -374,7 +374,7 @@ function U({ feature: e }) {
374
374
  e.stopPropagation(), c();
375
375
  },
376
376
  children: [/* @__PURE__ */ h(l, { className: "mr-1 h-4 w-4" }), "Back to triage"]
377
- }), o && /* @__PURE__ */ h(r, { message: o })] });
377
+ }), o && /* @__PURE__ */ h(n, { message: o })] });
378
378
  }
379
379
  function W({ feature: e, now: t }) {
380
380
  if (!P(e.status)) return null;
@@ -1,6 +1,6 @@
1
1
  import { throwOnError as e } from "../utils/mutationResult.js";
2
- import { WorkItemSearchSelect as t } from "./Pickers.js";
3
- import { ErrorLine as n } from "./ConfirmButton.js";
2
+ import { ErrorLine as t } from "./ConfirmButton.js";
3
+ import { WorkItemSearchSelect as n } from "./Pickers.js";
4
4
  import { endBeforeStart as r } from "../utils/formValidation.js";
5
5
  import { enumLabel as i } from "./WorkItemControls.js";
6
6
  import { useState as a } from "react";
@@ -41,13 +41,13 @@ var S = [
41
41
  refetchQueries: C,
42
42
  awaitRefetchQueries: !0
43
43
  };
44
- function O({ objective: t }) {
45
- let [r, o] = u(w, D), [s, c] = a(null), l = S.includes(t.status) ? S : [t.status, ...S], p = async (n) => {
44
+ function O({ objective: n }) {
45
+ let [r, o] = u(w, D), [s, c] = a(null), l = S.includes(n.status) ? S : [n.status, ...S], p = async (t) => {
46
46
  c(null);
47
47
  try {
48
48
  await e(r({ variables: {
49
- id: t.id,
50
- input: { status: n }
49
+ id: n.id,
50
+ input: { status: t }
51
51
  } }));
52
52
  } catch (e) {
53
53
  c(e instanceof Error ? e.message : "The status could not be changed.");
@@ -61,38 +61,38 @@ function O({ objective: t }) {
61
61
  "aria-label": "Objective status",
62
62
  "data-testid": "objective-status",
63
63
  className: "rounded-md border border-input bg-background px-2 py-1 text-sm disabled:opacity-60",
64
- value: t.status,
64
+ value: n.status,
65
65
  disabled: o.loading,
66
66
  onChange: (e) => {
67
- e.target.value !== t.status && p(e.target.value);
67
+ e.target.value !== n.status && p(e.target.value);
68
68
  },
69
69
  children: l.map((e) => /* @__PURE__ */ d("option", {
70
70
  value: e,
71
71
  children: i(e)
72
72
  }, e))
73
- }), /* @__PURE__ */ d(A, { objective: t })]
74
- }), s && /* @__PURE__ */ d(n, { message: s })]
73
+ }), /* @__PURE__ */ d(A, { objective: n })]
74
+ }), s && /* @__PURE__ */ d(t, { message: s })]
75
75
  });
76
76
  }
77
77
  var k = (e) => e ? e.slice(0, 10) : "";
78
- function A({ objective: t }) {
78
+ function A({ objective: n }) {
79
79
  let i = {
80
- title: t.title,
81
- description: t.description ?? "",
82
- periodLabel: t.periodLabel,
83
- startDate: k(t.startDate),
84
- endDate: k(t.endDate)
80
+ title: n.title,
81
+ description: n.description ?? "",
82
+ periodLabel: n.periodLabel,
83
+ startDate: k(n.startDate),
84
+ endDate: k(n.endDate)
85
85
  }, [o, c] = a(!1), [l, S] = a(i), [C, T] = a(null), [E, O] = u(w, D), A = r(l.startDate, l.endDate), j = l.title.trim() !== "" && l.periodLabel.trim() !== "" && !A && !O.loading, M = async () => {
86
86
  T(null);
87
- let n = {};
88
- if (l.title.trim() !== i.title && (n.title = l.title.trim()), l.periodLabel.trim() !== i.periodLabel && (n.periodLabel = l.periodLabel.trim()), l.description.trim() !== i.description.trim() && (n.description = l.description.trim() || null), l.startDate !== i.startDate && (n.startDate = l.startDate || null), l.endDate !== i.endDate && (n.endDate = l.endDate || null), Object.keys(n).length === 0) {
87
+ let t = {};
88
+ if (l.title.trim() !== i.title && (t.title = l.title.trim()), l.periodLabel.trim() !== i.periodLabel && (t.periodLabel = l.periodLabel.trim()), l.description.trim() !== i.description.trim() && (t.description = l.description.trim() || null), l.startDate !== i.startDate && (t.startDate = l.startDate || null), l.endDate !== i.endDate && (t.endDate = l.endDate || null), Object.keys(t).length === 0) {
89
89
  c(!1);
90
90
  return;
91
91
  }
92
92
  try {
93
93
  await e(E({ variables: {
94
- id: t.id,
95
- input: n
94
+ id: n.id,
95
+ input: t
96
96
  } })), c(!1);
97
97
  } catch (e) {
98
98
  T(e instanceof Error ? e.message : "The objective could not be saved.");
@@ -177,7 +177,7 @@ function A({ objective: t }) {
177
177
  })
178
178
  })] })]
179
179
  }),
180
- A && /* @__PURE__ */ d(n, { message: "The end date is before the start date." }),
180
+ A && /* @__PURE__ */ d(t, { message: "The end date is before the start date." }),
181
181
  /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
182
182
  htmlFor: "objective-edit-description",
183
183
  className: N,
@@ -191,7 +191,7 @@ function A({ objective: t }) {
191
191
  description: e.target.value
192
192
  })
193
193
  })] }),
194
- C && /* @__PURE__ */ d(n, { message: C })
194
+ C && /* @__PURE__ */ d(t, { message: C })
195
195
  ]
196
196
  }),
197
197
  /* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(p, {
@@ -259,7 +259,7 @@ function j({ keyResultId: r, keyResultTitle: s, linked: l }) {
259
259
  }),
260
260
  v ? /* @__PURE__ */ f("div", {
261
261
  className: "space-y-2 rounded-md border border-input p-2",
262
- children: [/* @__PURE__ */ d(t, {
262
+ children: [/* @__PURE__ */ d(n, {
263
263
  id: `kr-link-${r}`,
264
264
  value: b,
265
265
  onChange: x,
@@ -286,7 +286,7 @@ function j({ keyResultId: r, keyResultTitle: s, linked: l }) {
286
286
  onClick: () => y(!0),
287
287
  children: [/* @__PURE__ */ d(o, { className: "mr-1 h-4 w-4" }), "Link work item"]
288
288
  }),
289
- S && /* @__PURE__ */ d(n, { message: S })
289
+ S && /* @__PURE__ */ d(t, { message: S })
290
290
  ]
291
291
  });
292
292
  }
@@ -1,9 +1,10 @@
1
- /** A project select. '' means "no project" when `noneLabel` is given. */
2
- export declare function ProjectSelect({ id, value, onChange, noneLabel, }: {
1
+ /** A project select. '' means "no project" when `noneLabel` is given. `exclude` hides ids already spoken for. */
2
+ export declare function ProjectSelect({ id, value, onChange, noneLabel, exclude, }: {
3
3
  id?: string;
4
4
  value: string;
5
5
  onChange: (projectId: string) => void;
6
6
  noneLabel?: string;
7
+ exclude?: string[];
7
8
  }): import("react/jsx-runtime").JSX.Element;
8
9
  /**
9
10
  * Search, then pick one work item. The server matches the key, title and description. `exclude` hides items that are
@@ -23,4 +24,18 @@ export declare function DocSearchSelect({ id, value, onChange, exclude, }: {
23
24
  onChange: (docId: string) => void;
24
25
  exclude?: string[];
25
26
  }): import("react/jsx-runtime").JSX.Element;
27
+ /** A program select. '' means "no program" when `noneLabel` is given. */
28
+ export declare function ProgramSelect({ id, value, onChange, noneLabel, }: {
29
+ id?: string;
30
+ value: string;
31
+ onChange: (programId: string) => void;
32
+ noneLabel?: string;
33
+ }): import("react/jsx-runtime").JSX.Element;
34
+ /** Search, then pick one competitor. `exclude` hides competitors already linked. */
35
+ export declare function CompetitorSearchSelect({ id, value, onChange, exclude, }: {
36
+ id: string;
37
+ value: string;
38
+ onChange: (competitorId: string) => void;
39
+ exclude?: string[];
40
+ }): import("react/jsx-runtime").JSX.Element;
26
41
  //# sourceMappingURL=Pickers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pickers.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/Pickers.tsx"],"names":[],"mappings":"AA2BA,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CA8BA;AAeD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,EAAE,EACF,SAAS,EACT,KAAK,EACL,QAAQ,EACR,OAAY,GACb,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CAqDA;AAcD,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,OAAY,GACb,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CA8CA"}
1
+ {"version":3,"file":"Pickers.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/controls/Pickers.tsx"],"names":[],"mappings":"AA2BA,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,SAAS,EACT,OAAY,GACb,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CA8BA;AAeD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,EAAE,EACF,SAAS,EACT,KAAK,EACL,QAAQ,EACR,OAAY,GACb,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CAqDA;AAcD,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,OAAY,GACb,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CA8CA;AAcD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CA8BA;AAcD,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,EACrC,EAAE,EACF,KAAK,EACL,QAAQ,EACR,OAAY,GACb,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,2CAkDA"}