@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1028.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/BotlitRoutes.js +142 -132
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/components/AgentApprovalPanel.js +144 -126
- package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
- package/dist/botlit/components/RetentionStatusPanel.js +95 -0
- package/dist/botlit/components/RetentionStatusPanel.js.map +1 -0
- package/dist/botlit/components/VersionHistoryPanel.js +92 -83
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/hooks/index.js +1 -0
- package/dist/botlit/hooks/useRetention.js +31 -0
- package/dist/botlit/hooks/useRetention.js.map +1 -0
- package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.js +129 -117
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
- package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.js +18 -18
- package/dist/botlit/pages/AgentDetailPage.js +298 -273
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +145 -121
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js +238 -226
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.js +307 -288
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +125 -116
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +159 -144
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +279 -258
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +346 -328
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
- package/dist/botlit/pages/ChannelsPage.js +163 -148
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/DashboardPage.js +129 -114
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +14 -14
- package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +170 -155
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.js +115 -104
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/PolicyDetailPage.js +368 -324
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptStudioPage.js +106 -97
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +264 -252
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.js +235 -226
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.js +115 -106
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +161 -155
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/permissions/PermissionRequired.js +45 -0
- package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
- package/dist/botlit/permissions/botmanorPermissions.js +72 -0
- package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
- package/dist/botlit/permissions/index.js +3 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
- package/dist/botlit/utils/policyConfig.js +67 -42
- package/dist/botlit/utils/policyConfig.js.map +1 -1
- package/dist/generated/global-types.js.map +1 -1
- package/dist/generated/wspace-operations.js +90 -54
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,41 +1,44 @@
|
|
|
1
1
|
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
2
|
import { useBotlit as t } from "../providers/BotlitProvider.js";
|
|
3
3
|
import { formatRelativeTime as n } from "../utils/formatters.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
4
|
+
import { BOTMANOR_PERMISSIONS as r } from "../permissions/botmanorPermissions.js";
|
|
5
|
+
import { BotmanorPermissionGate as i } from "../permissions/useBotmanorPermissions.js";
|
|
6
|
+
import { PageLayout as a } from "../components/PageLayout.js";
|
|
7
|
+
import { Button as o } from "../components/Button.js";
|
|
8
|
+
import "../permissions/index.js";
|
|
9
|
+
import { Card as s, CardContent as c, CardDescription as l, CardHeader as u, CardTitle as d } from "../components/Card.js";
|
|
10
|
+
import { Badge as f } from "../components/Badge.js";
|
|
11
|
+
import { EmptyState as p } from "../components/EmptyState.js";
|
|
12
|
+
import { Input as m } from "../components/Input.js";
|
|
13
|
+
import { ErrorState as h } from "../components/ErrorState.js";
|
|
14
|
+
import { storePackageDescription as g, storePackageName as _, useInstallPackage as v, useInstalledPackages as y, useStorePackages as b } from "../hooks/useStore.js";
|
|
12
15
|
import "../hooks/index.js";
|
|
13
|
-
import { InstallMode as
|
|
14
|
-
import { useMemo as
|
|
15
|
-
import { GlassCard as
|
|
16
|
-
import { jsx as
|
|
17
|
-
import { Link as
|
|
18
|
-
import { Bot as
|
|
19
|
-
import { toast as
|
|
16
|
+
import { InstallMode as x, PackageKind as S } from "../../generated/wspace-types.js";
|
|
17
|
+
import { useMemo as C, useState as w } from "react";
|
|
18
|
+
import { GlassCard as T, PagePurpose as E } from "@burdenoff/fe-libs/ui";
|
|
19
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
20
|
+
import { Link as k } from "react-router";
|
|
21
|
+
import { Bot as A, Check as j, Database as M, ExternalLink as ee, FileText as N, Package as P, Search as F, Shield as I, Sparkles as L, Store as R, Wrench as z } from "lucide-react";
|
|
22
|
+
import { toast as B } from "sonner";
|
|
20
23
|
//#region src/botlit/pages/StorePage.tsx
|
|
21
|
-
var
|
|
24
|
+
var V = ({ kind: e, className: t }) => {
|
|
22
25
|
switch (e) {
|
|
23
|
-
case "APP": return /* @__PURE__ */
|
|
26
|
+
case "APP": return /* @__PURE__ */ D(P, { className: t });
|
|
24
27
|
case "AGENT":
|
|
25
|
-
case "A2A_AGENT": return /* @__PURE__ */
|
|
28
|
+
case "A2A_AGENT": return /* @__PURE__ */ D(A, { className: t });
|
|
26
29
|
case "MCP_PACK":
|
|
27
|
-
case "TOOL": return /* @__PURE__ */
|
|
30
|
+
case "TOOL": return /* @__PURE__ */ D(z, { className: t });
|
|
28
31
|
case "PROMPT_TEMPLATE":
|
|
29
|
-
case "PROMPT": return /* @__PURE__ */
|
|
30
|
-
case "SKILL": return /* @__PURE__ */
|
|
32
|
+
case "PROMPT": return /* @__PURE__ */ D(N, { className: t });
|
|
33
|
+
case "SKILL": return /* @__PURE__ */ D(L, { className: t });
|
|
31
34
|
case "RETRIEVAL_PROFILE":
|
|
32
35
|
case "KNOWLEDGE_BASE":
|
|
33
|
-
case "KB_TEMPLATE": return /* @__PURE__ */
|
|
34
|
-
case "POLICY_BUNDLE": return /* @__PURE__ */
|
|
35
|
-
default: return /* @__PURE__ */
|
|
36
|
+
case "KB_TEMPLATE": return /* @__PURE__ */ D(M, { className: t });
|
|
37
|
+
case "POLICY_BUNDLE": return /* @__PURE__ */ D(I, { className: t });
|
|
38
|
+
default: return /* @__PURE__ */ D(P, { className: t });
|
|
36
39
|
}
|
|
37
40
|
};
|
|
38
|
-
function
|
|
41
|
+
function H(e) {
|
|
39
42
|
return {
|
|
40
43
|
APP: e("botlit.store.kindLabel.APP", "Bot"),
|
|
41
44
|
AGENT: e("botlit.store.kindLabel.AGENT", "Agent"),
|
|
@@ -55,185 +58,188 @@ function V(e) {
|
|
|
55
58
|
WORKFLOW: e("botlit.store.kindLabel.WORKFLOW", "Workflow")
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
|
-
var
|
|
59
|
-
let
|
|
60
|
-
search:
|
|
61
|
-
kind:
|
|
62
|
-
sortBy:
|
|
61
|
+
var U = () => {
|
|
62
|
+
let A = e(), { getPath: M } = t(), N = H(A), [P, I] = w(""), [L, z] = w(null), [U, W] = w("recent"), [G, K] = w(null), { data: q, loading: J, error: Y, refetch: X } = b(C(() => ({
|
|
63
|
+
search: P,
|
|
64
|
+
kind: L ? [L] : void 0,
|
|
65
|
+
sortBy: U
|
|
63
66
|
}), [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
])), { data:
|
|
68
|
-
t.preventDefault(), t.stopPropagation(),
|
|
67
|
+
P,
|
|
68
|
+
L,
|
|
69
|
+
U
|
|
70
|
+
])), { data: Z, refetch: Q } = y(), { install: te } = v(), $ = C(() => new Set(Z.map((e) => e.package?.slug).filter((e) => typeof e == "string")), [Z]), ne = async (e, t) => {
|
|
71
|
+
t.preventDefault(), t.stopPropagation(), K(e.slug);
|
|
69
72
|
try {
|
|
70
|
-
await
|
|
73
|
+
await te({
|
|
71
74
|
packageId: e.id,
|
|
72
|
-
mode:
|
|
73
|
-
}),
|
|
75
|
+
mode: x.Linked
|
|
76
|
+
}), B.success(A("botlit.store.install.success", "Installed \"{{name}}\"", { name: _(e) })), Q();
|
|
74
77
|
} catch (e) {
|
|
75
|
-
|
|
78
|
+
B.error(e instanceof Error ? e.message : A("botlit.store.install.error", "Failed to install package"));
|
|
76
79
|
} finally {
|
|
77
|
-
|
|
80
|
+
K(null);
|
|
78
81
|
}
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
}, re = [
|
|
83
|
+
S.Agent,
|
|
84
|
+
S.McpPack,
|
|
85
|
+
S.Skill,
|
|
86
|
+
S.PromptTemplate,
|
|
87
|
+
S.PolicyBundle
|
|
85
88
|
];
|
|
86
|
-
return /* @__PURE__ */
|
|
87
|
-
title:
|
|
88
|
-
description:
|
|
89
|
-
actions: /* @__PURE__ */
|
|
89
|
+
return /* @__PURE__ */ D(a, {
|
|
90
|
+
title: A("botlit.store.title", "BotManor Store"),
|
|
91
|
+
description: A("botlit.store.description", "Discover and install pre-built agents, tools, and configurations"),
|
|
92
|
+
actions: /* @__PURE__ */ O("div", {
|
|
90
93
|
className: "flex gap-2",
|
|
91
|
-
children: [/* @__PURE__ */
|
|
94
|
+
children: [/* @__PURE__ */ D(o, {
|
|
92
95
|
variant: "outline",
|
|
93
|
-
children: /* @__PURE__ */
|
|
94
|
-
to:
|
|
95
|
-
children:
|
|
96
|
+
children: /* @__PURE__ */ D(k, {
|
|
97
|
+
to: M("store/installed"),
|
|
98
|
+
children: A("botlit.store.actions.viewInstalled", "View Installed ({{count}})", { count: Z.length })
|
|
96
99
|
})
|
|
97
|
-
}), /* @__PURE__ */
|
|
100
|
+
}), /* @__PURE__ */ D(o, {
|
|
98
101
|
variant: "outline",
|
|
99
|
-
leftIcon: /* @__PURE__ */
|
|
100
|
-
children:
|
|
102
|
+
leftIcon: /* @__PURE__ */ D(ee, { size: 16 }),
|
|
103
|
+
children: A("botlit.store.actions.publishPackage", "Publish Package")
|
|
101
104
|
})]
|
|
102
105
|
}),
|
|
103
|
-
children: /* @__PURE__ */
|
|
106
|
+
children: /* @__PURE__ */ O("div", {
|
|
104
107
|
className: "space-y-6",
|
|
105
108
|
children: [
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
icon: /* @__PURE__ */
|
|
108
|
-
children:
|
|
109
|
+
/* @__PURE__ */ D(E, {
|
|
110
|
+
icon: /* @__PURE__ */ D(R, { size: 18 }),
|
|
111
|
+
children: A("botlit.store.purpose", "The store is a marketplace of ready-made building blocks — full bots, agents, MCP tool packs, prompt templates and policy bundles published by the BotManor team and the community. Browse and install a package to skip the setup and start from a working example, then customise it for your own use case instead of building everything from scratch.")
|
|
109
112
|
}),
|
|
110
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ O("div", {
|
|
111
114
|
className: "flex flex-wrap items-center gap-4",
|
|
112
115
|
children: [
|
|
113
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ O("div", {
|
|
114
117
|
className: "relative flex-1 max-w-md",
|
|
115
|
-
children: [/* @__PURE__ */
|
|
116
|
-
placeholder:
|
|
117
|
-
value:
|
|
118
|
-
onChange: (e) =>
|
|
118
|
+
children: [/* @__PURE__ */ D(F, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ D(m, {
|
|
119
|
+
placeholder: A("botlit.store.searchPlaceholder", "Search packages..."),
|
|
120
|
+
value: P,
|
|
121
|
+
onChange: (e) => I(e.target.value),
|
|
119
122
|
className: "pl-9"
|
|
120
123
|
})]
|
|
121
124
|
}),
|
|
122
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ O("div", {
|
|
123
126
|
className: "flex gap-2",
|
|
124
|
-
children: [/* @__PURE__ */
|
|
125
|
-
variant:
|
|
127
|
+
children: [/* @__PURE__ */ D(o, {
|
|
128
|
+
variant: L === null ? "default" : "outline",
|
|
126
129
|
size: "sm",
|
|
127
|
-
onClick: () =>
|
|
128
|
-
children:
|
|
129
|
-
}),
|
|
130
|
-
variant:
|
|
130
|
+
onClick: () => z(null),
|
|
131
|
+
children: A("botlit.store.filters.all", "All")
|
|
132
|
+
}), re.map((e) => /* @__PURE__ */ D(o, {
|
|
133
|
+
variant: L === e ? "default" : "outline",
|
|
131
134
|
size: "sm",
|
|
132
|
-
onClick: () =>
|
|
133
|
-
leftIcon: /* @__PURE__ */
|
|
135
|
+
onClick: () => z(e),
|
|
136
|
+
leftIcon: /* @__PURE__ */ D(V, {
|
|
134
137
|
kind: e,
|
|
135
138
|
className: "h-4 w-4"
|
|
136
139
|
}),
|
|
137
|
-
children:
|
|
140
|
+
children: N[e]
|
|
138
141
|
}, e))]
|
|
139
142
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
-
"aria-label":
|
|
143
|
+
/* @__PURE__ */ O("select", {
|
|
144
|
+
"aria-label": A("botlit.store.filters.sortLabel", "Sort packages"),
|
|
142
145
|
className: "h-9 px-3 border border-border-default rounded-md bg-bg-surface text-sm",
|
|
143
|
-
value:
|
|
144
|
-
onChange: (e) =>
|
|
145
|
-
children: [/* @__PURE__ */
|
|
146
|
+
value: U,
|
|
147
|
+
onChange: (e) => W(e.target.value),
|
|
148
|
+
children: [/* @__PURE__ */ D("option", {
|
|
146
149
|
value: "recent",
|
|
147
|
-
children:
|
|
148
|
-
}), /* @__PURE__ */
|
|
150
|
+
children: A("botlit.store.sort.recent", "Recently Published")
|
|
151
|
+
}), /* @__PURE__ */ D("option", {
|
|
149
152
|
value: "name",
|
|
150
|
-
children:
|
|
153
|
+
children: A("botlit.store.sort.name", "Name (A–Z)")
|
|
151
154
|
})]
|
|
152
155
|
})
|
|
153
156
|
]
|
|
154
157
|
}),
|
|
155
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ O("div", {
|
|
156
159
|
className: "grid grid-cols-1 md:grid-cols-3 gap-4",
|
|
157
|
-
children: [/* @__PURE__ */ T
|
|
160
|
+
children: [/* @__PURE__ */ D(T, {
|
|
158
161
|
treatment: "glass",
|
|
159
162
|
glow: !0,
|
|
160
163
|
className: "md:col-span-2 p-6",
|
|
161
|
-
children: /* @__PURE__ */
|
|
164
|
+
children: /* @__PURE__ */ O("div", {
|
|
162
165
|
className: "flex items-start gap-4",
|
|
163
|
-
children: [/* @__PURE__ */
|
|
166
|
+
children: [/* @__PURE__ */ D("div", {
|
|
164
167
|
className: "p-3 bg-action-primary-bg/20 rounded-lg",
|
|
165
|
-
children: /* @__PURE__ */
|
|
166
|
-
}), /* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
+
children: /* @__PURE__ */ D(R, { className: "h-8 w-8 text-primary" })
|
|
169
|
+
}), /* @__PURE__ */ O("div", { children: [
|
|
170
|
+
/* @__PURE__ */ D("h3", {
|
|
168
171
|
className: "text-lg font-semibold text-text-primary",
|
|
169
|
-
children:
|
|
172
|
+
children: A("botlit.store.featured.title", "Welcome to the BotManor Store")
|
|
170
173
|
}),
|
|
171
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ D("p", {
|
|
172
175
|
className: "text-sm text-text-secondary mt-1",
|
|
173
|
-
children:
|
|
176
|
+
children: A("botlit.store.featured.description", "Discover production-ready agents, tool packs, and configurations built by the community and BotManor team. Install packages to jumpstart your AI applications.")
|
|
174
177
|
}),
|
|
175
|
-
/* @__PURE__ */
|
|
178
|
+
/* @__PURE__ */ O("div", {
|
|
176
179
|
className: "flex gap-4 mt-4",
|
|
177
|
-
children: [/* @__PURE__ */
|
|
180
|
+
children: [/* @__PURE__ */ O("div", {
|
|
178
181
|
className: "text-center",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
182
|
+
children: [/* @__PURE__ */ D("p", {
|
|
180
183
|
className: "text-2xl font-bold tabular-nums",
|
|
181
|
-
children:
|
|
182
|
-
}), /* @__PURE__ */
|
|
184
|
+
children: q.length
|
|
185
|
+
}), /* @__PURE__ */ D("p", {
|
|
183
186
|
className: "text-xs text-text-secondary",
|
|
184
|
-
children:
|
|
187
|
+
children: A("botlit.store.featured.packages", "Packages")
|
|
185
188
|
})]
|
|
186
|
-
}), /* @__PURE__ */
|
|
189
|
+
}), /* @__PURE__ */ O("div", {
|
|
187
190
|
className: "text-center",
|
|
188
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ D("p", {
|
|
189
192
|
className: "text-2xl font-bold tabular-nums",
|
|
190
|
-
children:
|
|
191
|
-
}), /* @__PURE__ */
|
|
193
|
+
children: Z.length
|
|
194
|
+
}), /* @__PURE__ */ D("p", {
|
|
192
195
|
className: "text-xs text-text-secondary",
|
|
193
|
-
children:
|
|
196
|
+
children: A("botlit.store.featured.installed", "Installed")
|
|
194
197
|
})]
|
|
195
198
|
})]
|
|
196
199
|
})
|
|
197
200
|
] })]
|
|
198
201
|
})
|
|
199
|
-
}), /* @__PURE__ */
|
|
202
|
+
}), /* @__PURE__ */ O(s, { children: [/* @__PURE__ */ D(u, {
|
|
200
203
|
className: "pb-2",
|
|
201
|
-
children: /* @__PURE__ */
|
|
204
|
+
children: /* @__PURE__ */ D(d, {
|
|
202
205
|
className: "text-sm",
|
|
203
|
-
children:
|
|
206
|
+
children: A("botlit.store.featured.quickInstall", "Quick Install")
|
|
204
207
|
})
|
|
205
|
-
}), /* @__PURE__ */
|
|
208
|
+
}), /* @__PURE__ */ D(c, {
|
|
206
209
|
className: "space-y-2",
|
|
207
|
-
children:
|
|
210
|
+
children: q.slice(0, 3).map((e) => /* @__PURE__ */ O("div", {
|
|
208
211
|
className: "flex items-center justify-between p-2 bg-bg-sunken rounded",
|
|
209
|
-
children: [/* @__PURE__ */
|
|
212
|
+
children: [/* @__PURE__ */ O("div", {
|
|
210
213
|
className: "flex items-center gap-2",
|
|
211
|
-
children: [/* @__PURE__ */
|
|
214
|
+
children: [/* @__PURE__ */ D(V, {
|
|
212
215
|
kind: e.kind,
|
|
213
216
|
className: "h-4 w-4 text-text-secondary"
|
|
214
|
-
}), /* @__PURE__ */
|
|
217
|
+
}), /* @__PURE__ */ D("span", {
|
|
215
218
|
className: "text-sm truncate max-w-[150px]",
|
|
216
|
-
children:
|
|
219
|
+
children: _(e)
|
|
217
220
|
})]
|
|
218
|
-
}), $.has(e.slug) ? /* @__PURE__ */
|
|
221
|
+
}), $.has(e.slug) ? /* @__PURE__ */ O(f, {
|
|
219
222
|
variant: "success",
|
|
220
223
|
className: "text-xs",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
224
|
+
children: [/* @__PURE__ */ D(j, {
|
|
222
225
|
size: 12,
|
|
223
226
|
className: "mr-1"
|
|
224
|
-
}),
|
|
225
|
-
}) : /* @__PURE__ */
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
227
|
+
}), A("botlit.store.install.installedBadge", "Installed")]
|
|
228
|
+
}) : /* @__PURE__ */ D(i, {
|
|
229
|
+
permission: r.STORE_CREATE,
|
|
230
|
+
children: /* @__PURE__ */ D(o, {
|
|
231
|
+
size: "sm",
|
|
232
|
+
variant: "ghost",
|
|
233
|
+
className: "h-6 text-xs",
|
|
234
|
+
onClick: (t) => void ne(e, t),
|
|
235
|
+
isLoading: G === e.slug,
|
|
236
|
+
children: A("botlit.store.install.action", "Install")
|
|
237
|
+
})
|
|
232
238
|
})]
|
|
233
239
|
}, e.id))
|
|
234
240
|
})] })]
|
|
235
241
|
}),
|
|
236
|
-
|
|
242
|
+
J ? /* @__PURE__ */ D("div", {
|
|
237
243
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
238
244
|
children: [
|
|
239
245
|
1,
|
|
@@ -242,31 +248,31 @@ var H = () => {
|
|
|
242
248
|
4,
|
|
243
249
|
5,
|
|
244
250
|
6
|
|
245
|
-
].map((e) => /* @__PURE__ */
|
|
246
|
-
}) :
|
|
251
|
+
].map((e) => /* @__PURE__ */ D("div", { className: "h-56 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
|
|
252
|
+
}) : Y ? /* @__PURE__ */ D(h, {
|
|
247
253
|
resource: "store packages",
|
|
248
|
-
error:
|
|
249
|
-
onRetry: () => void
|
|
250
|
-
}) :
|
|
254
|
+
error: Y,
|
|
255
|
+
onRetry: () => void X()
|
|
256
|
+
}) : q.length > 0 ? /* @__PURE__ */ D("div", {
|
|
251
257
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
252
|
-
children:
|
|
253
|
-
to:
|
|
254
|
-
children: /* @__PURE__ */
|
|
258
|
+
children: q.map((e) => /* @__PURE__ */ D(k, {
|
|
259
|
+
to: M(`store/package/${e.slug}`),
|
|
260
|
+
children: /* @__PURE__ */ O(s, {
|
|
255
261
|
className: "h-full hover:border-primary/50 transition-colors cursor-pointer",
|
|
256
|
-
children: [/* @__PURE__ */
|
|
262
|
+
children: [/* @__PURE__ */ D(u, { children: /* @__PURE__ */ O("div", {
|
|
257
263
|
className: "flex items-start justify-between",
|
|
258
|
-
children: [/* @__PURE__ */
|
|
264
|
+
children: [/* @__PURE__ */ O("div", {
|
|
259
265
|
className: "flex items-center gap-3",
|
|
260
|
-
children: [/* @__PURE__ */
|
|
266
|
+
children: [/* @__PURE__ */ D("div", {
|
|
261
267
|
className: "p-2 bg-action-primary-bg/10 rounded-lg",
|
|
262
|
-
children: /* @__PURE__ */
|
|
268
|
+
children: /* @__PURE__ */ D(V, {
|
|
263
269
|
kind: e.kind,
|
|
264
270
|
className: "h-5 w-5 text-primary"
|
|
265
271
|
})
|
|
266
|
-
}), /* @__PURE__ */
|
|
272
|
+
}), /* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D(d, {
|
|
267
273
|
className: "text-base",
|
|
268
|
-
children:
|
|
269
|
-
}), /* @__PURE__ */
|
|
274
|
+
children: _(e)
|
|
275
|
+
}), /* @__PURE__ */ O(l, {
|
|
270
276
|
className: "text-xs",
|
|
271
277
|
children: [
|
|
272
278
|
e.slug,
|
|
@@ -274,26 +280,26 @@ var H = () => {
|
|
|
274
280
|
e.version
|
|
275
281
|
]
|
|
276
282
|
})] })]
|
|
277
|
-
}), $.has(e.slug) && /* @__PURE__ */
|
|
283
|
+
}), $.has(e.slug) && /* @__PURE__ */ O(f, {
|
|
278
284
|
variant: "success",
|
|
279
285
|
className: "text-xs",
|
|
280
|
-
children: [/* @__PURE__ */
|
|
286
|
+
children: [/* @__PURE__ */ D(j, {
|
|
281
287
|
size: 10,
|
|
282
288
|
className: "mr-1"
|
|
283
|
-
}),
|
|
289
|
+
}), A("botlit.store.install.installedBadge", "Installed")]
|
|
284
290
|
})]
|
|
285
|
-
}) }), /* @__PURE__ */
|
|
291
|
+
}) }), /* @__PURE__ */ D(c, { children: /* @__PURE__ */ O("div", {
|
|
286
292
|
className: "space-y-3",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
293
|
+
children: [/* @__PURE__ */ D("p", {
|
|
288
294
|
className: "text-sm text-text-secondary line-clamp-2",
|
|
289
|
-
children:
|
|
290
|
-
}), /* @__PURE__ */
|
|
295
|
+
children: g(e)
|
|
296
|
+
}), /* @__PURE__ */ O("div", {
|
|
291
297
|
className: "pt-3 border-t border-border-subtle flex items-center justify-between",
|
|
292
|
-
children: [/* @__PURE__ */
|
|
298
|
+
children: [/* @__PURE__ */ D(f, {
|
|
293
299
|
variant: "outline",
|
|
294
300
|
className: "text-xs",
|
|
295
|
-
children:
|
|
296
|
-
}), /* @__PURE__ */
|
|
301
|
+
children: N[e.kind] ?? e.kind
|
|
302
|
+
}), /* @__PURE__ */ D("span", {
|
|
297
303
|
className: "text-xs text-text-secondary",
|
|
298
304
|
children: n(e.publishedAt)
|
|
299
305
|
})]
|
|
@@ -301,16 +307,16 @@ var H = () => {
|
|
|
301
307
|
}) })]
|
|
302
308
|
})
|
|
303
309
|
}, e.id))
|
|
304
|
-
}) : /* @__PURE__ */
|
|
310
|
+
}) : /* @__PURE__ */ D(p, {
|
|
305
311
|
illustration: "empty-search",
|
|
306
|
-
title:
|
|
307
|
-
description:
|
|
312
|
+
title: A("botlit.store.empty.title", "No packages found"),
|
|
313
|
+
description: P || L ? A("botlit.store.empty.descriptionFiltered", "Try adjusting your search or filters.") : A("botlit.store.empty.descriptionNoPackages", "No packages available in the store yet.")
|
|
308
314
|
})
|
|
309
315
|
]
|
|
310
316
|
})
|
|
311
317
|
});
|
|
312
318
|
};
|
|
313
319
|
//#endregion
|
|
314
|
-
export {
|
|
320
|
+
export { U as StorePage };
|
|
315
321
|
|
|
316
322
|
//# sourceMappingURL=StorePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorePage.js","names":[],"sources":["../../../src/botlit/pages/StorePage.tsx"],"sourcesContent":["/**\n * Store Page\n * @module botlit/pages\n */\n\nimport type { FC, MouseEvent } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Search as SearchIcon,\n Store,\n Package,\n Bot,\n Wrench,\n FileText,\n Sparkles,\n Database,\n Shield,\n Check,\n ExternalLink,\n} from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useStorePackages,\n useInstalledPackages,\n useInstallPackage,\n storePackageName,\n storePackageDescription,\n type StorePackageRecord,\n type StoreSortBy,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport {\n InstallMode as GqlInstallMode,\n PackageKind as GqlPackageKind,\n} from '../../generated/wspace-types';\nimport type { PackageKind } from '../types';\n\nconst KindIcon: FC<{ kind: string; className?: string }> = ({ kind, className }) => {\n switch (kind) {\n case 'APP':\n return <Package className={className} />;\n case 'AGENT':\n case 'A2A_AGENT':\n return <Bot className={className} />;\n case 'MCP_PACK':\n case 'TOOL':\n return <Wrench className={className} />;\n case 'PROMPT_TEMPLATE':\n case 'PROMPT':\n return <FileText className={className} />;\n case 'SKILL':\n return <Sparkles className={className} />;\n case 'RETRIEVAL_PROFILE':\n case 'KNOWLEDGE_BASE':\n case 'KB_TEMPLATE':\n return <Database className={className} />;\n case 'POLICY_BUNDLE':\n return <Shield className={className} />;\n default:\n return <Package className={className} />;\n }\n};\n\nfunction useKindLabel(t: ReturnType<typeof useTr>): Record<string, string> {\n return {\n APP: t('botlit.store.kindLabel.APP', 'Bot'),\n AGENT: t('botlit.store.kindLabel.AGENT', 'Agent'),\n MCP_PACK: t('botlit.store.kindLabel.MCP_PACK', 'MCP Pack'),\n PROMPT_TEMPLATE: t('botlit.store.kindLabel.PROMPT_TEMPLATE', 'Prompt Template'),\n PROMPT: t('botlit.store.kindLabel.PROMPT', 'Prompt'),\n SKILL: t('botlit.store.kindLabel.SKILL', 'Skill'),\n RETRIEVAL_PROFILE: t('botlit.store.kindLabel.RETRIEVAL_PROFILE', 'Retrieval Profile'),\n POLICY_BUNDLE: t('botlit.store.kindLabel.POLICY_BUNDLE', 'Policy Bundle'),\n CHANNEL_TEMPLATE: t('botlit.store.kindLabel.CHANNEL_TEMPLATE', 'Channel Template'),\n A2A_AGENT: t('botlit.store.kindLabel.A2A_AGENT', 'A2A Agent'),\n KB_TEMPLATE: t('botlit.store.kindLabel.KB_TEMPLATE', 'KB Template'),\n KNOWLEDGE_BASE: t('botlit.store.kindLabel.KNOWLEDGE_BASE', 'Knowledge Base'),\n INTEGRATION: t('botlit.store.kindLabel.INTEGRATION', 'Integration'),\n TEMPLATE: t('botlit.store.kindLabel.TEMPLATE', 'Template'),\n TOOL: t('botlit.store.kindLabel.TOOL', 'Tool'),\n WORKFLOW: t('botlit.store.kindLabel.WORKFLOW', 'Workflow'),\n };\n}\n\nexport const StorePage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const kindLabel = useKindLabel(t);\n const [search, setSearch] = useState('');\n const [selectedKind, setSelectedKind] = useState<PackageKind | null>(null);\n const [sortBy, setSortBy] = useState<StoreSortBy>('recent');\n const [installingSlug, setInstallingSlug] = useState<string | null>(null);\n\n const storeFilter = useMemo(\n () => ({ search, kind: selectedKind ? [selectedKind] : undefined, sortBy }),\n [search, selectedKind, sortBy]\n );\n const { data: packages, loading, error, refetch } = useStorePackages(storeFilter);\n const { data: installed, refetch: refetchInstalled } = useInstalledPackages();\n const { install } = useInstallPackage();\n\n const installedSlugs = useMemo(\n () =>\n new Set(\n installed\n .map((entry) => entry.package?.slug)\n .filter((slug): slug is string => typeof slug === 'string')\n ),\n [installed]\n );\n\n const handleInstall = async (pkg: StorePackageRecord, e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setInstallingSlug(pkg.slug);\n try {\n await install({ packageId: pkg.id, mode: GqlInstallMode.Linked });\n toast.success(\n t('botlit.store.install.success', 'Installed \"{{name}}\"', {\n name: storePackageName(pkg),\n })\n );\n void refetchInstalled();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.store.install.error', 'Failed to install package')\n );\n } finally {\n setInstallingSlug(null);\n }\n };\n\n const kinds: PackageKind[] = [\n GqlPackageKind.Agent,\n GqlPackageKind.McpPack,\n GqlPackageKind.Skill,\n GqlPackageKind.PromptTemplate,\n GqlPackageKind.PolicyBundle,\n ];\n\n return (\n <PageLayout\n title={t('botlit.store.title', 'BotManor Store')}\n description={t(\n 'botlit.store.description',\n 'Discover and install pre-built agents, tools, and configurations'\n )}\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\">\n <Link to={getPath('store/installed')}>\n {t('botlit.store.actions.viewInstalled', 'View Installed ({{count}})', {\n count: installed.length,\n })}\n </Link>\n </Button>\n <Button variant=\"outline\" leftIcon={<ExternalLink size={16} />}>\n {t('botlit.store.actions.publishPackage', 'Publish Package')}\n </Button>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Store size={18} />}>\n {t(\n 'botlit.store.purpose',\n 'The store is a marketplace of ready-made building blocks — full bots, agents, MCP tool packs, prompt templates and policy bundles published by the BotManor team and the community. Browse and install a package to skip the setup and start from a working example, then customise it for your own use case instead of building everything from scratch.'\n )}\n </PagePurpose>\n\n {/* Search and Filters */}\n <div className=\"flex flex-wrap items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.store.searchPlaceholder', 'Search packages...')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n\n {/* Kind Filters */}\n <div className=\"flex gap-2\">\n <Button\n variant={selectedKind === null ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedKind(null)}\n >\n {t('botlit.store.filters.all', 'All')}\n </Button>\n {kinds.map((kind) => (\n <Button\n key={kind}\n variant={selectedKind === kind ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedKind(kind)}\n leftIcon={<KindIcon kind={kind} className=\"h-4 w-4\" />}\n >\n {kindLabel[kind]}\n </Button>\n ))}\n </div>\n\n {/* Sort */}\n <select\n aria-label={t('botlit.store.filters.sortLabel', 'Sort packages')}\n className=\"h-9 px-3 border border-border-default rounded-md bg-bg-surface text-sm\"\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value as StoreSortBy)}\n >\n <option value=\"recent\">{t('botlit.store.sort.recent', 'Recently Published')}</option>\n <option value=\"name\">{t('botlit.store.sort.name', 'Name (A–Z)')}</option>\n </select>\n </div>\n\n {/* Featured Section */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <GlassCard treatment=\"glass\" glow className=\"md:col-span-2 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"p-3 bg-action-primary-bg/20 rounded-lg\">\n <Store className=\"h-8 w-8 text-primary\" />\n </div>\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {t('botlit.store.featured.title', 'Welcome to the BotManor Store')}\n </h3>\n <p className=\"text-sm text-text-secondary mt-1\">\n {t(\n 'botlit.store.featured.description',\n 'Discover production-ready agents, tool packs, and configurations built by the community and BotManor team. Install packages to jumpstart your AI applications.'\n )}\n </p>\n <div className=\"flex gap-4 mt-4\">\n <div className=\"text-center\">\n <p className=\"text-2xl font-bold tabular-nums\">{packages.length}</p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.store.featured.packages', 'Packages')}\n </p>\n </div>\n <div className=\"text-center\">\n <p className=\"text-2xl font-bold tabular-nums\">{installed.length}</p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.store.featured.installed', 'Installed')}\n </p>\n </div>\n </div>\n </div>\n </div>\n </GlassCard>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">\n {t('botlit.store.featured.quickInstall', 'Quick Install')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {packages.slice(0, 3).map((pkg: StorePackageRecord) => (\n <div\n key={pkg.id}\n className=\"flex items-center justify-between p-2 bg-bg-sunken rounded\"\n >\n <div className=\"flex items-center gap-2\">\n <KindIcon kind={pkg.kind} className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm truncate max-w-[150px]\">{storePackageName(pkg)}</span>\n </div>\n {installedSlugs.has(pkg.slug) ? (\n <Badge variant=\"success\" className=\"text-xs\">\n <Check size={12} className=\"mr-1\" />\n {t('botlit.store.install.installedBadge', 'Installed')}\n </Badge>\n ) : (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 text-xs\"\n onClick={(e) => void handleInstall(pkg, e)}\n isLoading={installingSlug === pkg.slug}\n >\n {t('botlit.store.install.action', 'Install')}\n </Button>\n )}\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n {/* Packages Grid */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-56 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"store packages\" error={error} onRetry={() => void refetch()} />\n ) : packages.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {packages.map((pkg: StorePackageRecord) => (\n <Link key={pkg.id} to={getPath(`store/package/${pkg.slug}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <KindIcon kind={pkg.kind} className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{storePackageName(pkg)}</CardTitle>\n <CardDescription className=\"text-xs\">\n {pkg.slug} v{pkg.version}\n </CardDescription>\n </div>\n </div>\n {installedSlugs.has(pkg.slug) && (\n <Badge variant=\"success\" className=\"text-xs\">\n <Check size={10} className=\"mr-1\" />\n {t('botlit.store.install.installedBadge', 'Installed')}\n </Badge>\n )}\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {storePackageDescription(pkg)}\n </p>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {kindLabel[pkg.kind] ?? pkg.kind}\n </Badge>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(pkg.publishedAt)}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title={t('botlit.store.empty.title', 'No packages found')}\n description={\n search || selectedKind\n ? t(\n 'botlit.store.empty.descriptionFiltered',\n 'Try adjusting your search or filters.'\n )\n : t(\n 'botlit.store.empty.descriptionNoPackages',\n 'No packages available in the store yet.'\n )\n }\n />\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StorePage.js","names":[],"sources":["../../../src/botlit/pages/StorePage.tsx"],"sourcesContent":["/**\n * Store Page\n * @module botlit/pages\n */\n\nimport type { FC, MouseEvent } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Search as SearchIcon,\n Store,\n Package,\n Bot,\n Wrench,\n FileText,\n Sparkles,\n Database,\n Shield,\n Check,\n ExternalLink,\n} from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useStorePackages,\n useInstalledPackages,\n useInstallPackage,\n storePackageName,\n storePackageDescription,\n type StorePackageRecord,\n type StoreSortBy,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport {\n InstallMode as GqlInstallMode,\n PackageKind as GqlPackageKind,\n} from '../../generated/wspace-types';\nimport type { PackageKind } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nconst KindIcon: FC<{ kind: string; className?: string }> = ({ kind, className }) => {\n switch (kind) {\n case 'APP':\n return <Package className={className} />;\n case 'AGENT':\n case 'A2A_AGENT':\n return <Bot className={className} />;\n case 'MCP_PACK':\n case 'TOOL':\n return <Wrench className={className} />;\n case 'PROMPT_TEMPLATE':\n case 'PROMPT':\n return <FileText className={className} />;\n case 'SKILL':\n return <Sparkles className={className} />;\n case 'RETRIEVAL_PROFILE':\n case 'KNOWLEDGE_BASE':\n case 'KB_TEMPLATE':\n return <Database className={className} />;\n case 'POLICY_BUNDLE':\n return <Shield className={className} />;\n default:\n return <Package className={className} />;\n }\n};\n\nfunction useKindLabel(t: ReturnType<typeof useTr>): Record<string, string> {\n return {\n APP: t('botlit.store.kindLabel.APP', 'Bot'),\n AGENT: t('botlit.store.kindLabel.AGENT', 'Agent'),\n MCP_PACK: t('botlit.store.kindLabel.MCP_PACK', 'MCP Pack'),\n PROMPT_TEMPLATE: t('botlit.store.kindLabel.PROMPT_TEMPLATE', 'Prompt Template'),\n PROMPT: t('botlit.store.kindLabel.PROMPT', 'Prompt'),\n SKILL: t('botlit.store.kindLabel.SKILL', 'Skill'),\n RETRIEVAL_PROFILE: t('botlit.store.kindLabel.RETRIEVAL_PROFILE', 'Retrieval Profile'),\n POLICY_BUNDLE: t('botlit.store.kindLabel.POLICY_BUNDLE', 'Policy Bundle'),\n CHANNEL_TEMPLATE: t('botlit.store.kindLabel.CHANNEL_TEMPLATE', 'Channel Template'),\n A2A_AGENT: t('botlit.store.kindLabel.A2A_AGENT', 'A2A Agent'),\n KB_TEMPLATE: t('botlit.store.kindLabel.KB_TEMPLATE', 'KB Template'),\n KNOWLEDGE_BASE: t('botlit.store.kindLabel.KNOWLEDGE_BASE', 'Knowledge Base'),\n INTEGRATION: t('botlit.store.kindLabel.INTEGRATION', 'Integration'),\n TEMPLATE: t('botlit.store.kindLabel.TEMPLATE', 'Template'),\n TOOL: t('botlit.store.kindLabel.TOOL', 'Tool'),\n WORKFLOW: t('botlit.store.kindLabel.WORKFLOW', 'Workflow'),\n };\n}\n\nexport const StorePage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const kindLabel = useKindLabel(t);\n const [search, setSearch] = useState('');\n const [selectedKind, setSelectedKind] = useState<PackageKind | null>(null);\n const [sortBy, setSortBy] = useState<StoreSortBy>('recent');\n const [installingSlug, setInstallingSlug] = useState<string | null>(null);\n\n const storeFilter = useMemo(\n () => ({ search, kind: selectedKind ? [selectedKind] : undefined, sortBy }),\n [search, selectedKind, sortBy]\n );\n const { data: packages, loading, error, refetch } = useStorePackages(storeFilter);\n const { data: installed, refetch: refetchInstalled } = useInstalledPackages();\n const { install } = useInstallPackage();\n\n const installedSlugs = useMemo(\n () =>\n new Set(\n installed\n .map((entry) => entry.package?.slug)\n .filter((slug): slug is string => typeof slug === 'string')\n ),\n [installed]\n );\n\n const handleInstall = async (pkg: StorePackageRecord, e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setInstallingSlug(pkg.slug);\n try {\n await install({ packageId: pkg.id, mode: GqlInstallMode.Linked });\n toast.success(\n t('botlit.store.install.success', 'Installed \"{{name}}\"', {\n name: storePackageName(pkg),\n })\n );\n void refetchInstalled();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.store.install.error', 'Failed to install package')\n );\n } finally {\n setInstallingSlug(null);\n }\n };\n\n const kinds: PackageKind[] = [\n GqlPackageKind.Agent,\n GqlPackageKind.McpPack,\n GqlPackageKind.Skill,\n GqlPackageKind.PromptTemplate,\n GqlPackageKind.PolicyBundle,\n ];\n\n return (\n <PageLayout\n title={t('botlit.store.title', 'BotManor Store')}\n description={t(\n 'botlit.store.description',\n 'Discover and install pre-built agents, tools, and configurations'\n )}\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\">\n <Link to={getPath('store/installed')}>\n {t('botlit.store.actions.viewInstalled', 'View Installed ({{count}})', {\n count: installed.length,\n })}\n </Link>\n </Button>\n <Button variant=\"outline\" leftIcon={<ExternalLink size={16} />}>\n {t('botlit.store.actions.publishPackage', 'Publish Package')}\n </Button>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Store size={18} />}>\n {t(\n 'botlit.store.purpose',\n 'The store is a marketplace of ready-made building blocks — full bots, agents, MCP tool packs, prompt templates and policy bundles published by the BotManor team and the community. Browse and install a package to skip the setup and start from a working example, then customise it for your own use case instead of building everything from scratch.'\n )}\n </PagePurpose>\n\n {/* Search and Filters */}\n <div className=\"flex flex-wrap items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.store.searchPlaceholder', 'Search packages...')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n\n {/* Kind Filters */}\n <div className=\"flex gap-2\">\n <Button\n variant={selectedKind === null ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedKind(null)}\n >\n {t('botlit.store.filters.all', 'All')}\n </Button>\n {kinds.map((kind) => (\n <Button\n key={kind}\n variant={selectedKind === kind ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedKind(kind)}\n leftIcon={<KindIcon kind={kind} className=\"h-4 w-4\" />}\n >\n {kindLabel[kind]}\n </Button>\n ))}\n </div>\n\n {/* Sort */}\n <select\n aria-label={t('botlit.store.filters.sortLabel', 'Sort packages')}\n className=\"h-9 px-3 border border-border-default rounded-md bg-bg-surface text-sm\"\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value as StoreSortBy)}\n >\n <option value=\"recent\">{t('botlit.store.sort.recent', 'Recently Published')}</option>\n <option value=\"name\">{t('botlit.store.sort.name', 'Name (A–Z)')}</option>\n </select>\n </div>\n\n {/* Featured Section */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <GlassCard treatment=\"glass\" glow className=\"md:col-span-2 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"p-3 bg-action-primary-bg/20 rounded-lg\">\n <Store className=\"h-8 w-8 text-primary\" />\n </div>\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {t('botlit.store.featured.title', 'Welcome to the BotManor Store')}\n </h3>\n <p className=\"text-sm text-text-secondary mt-1\">\n {t(\n 'botlit.store.featured.description',\n 'Discover production-ready agents, tool packs, and configurations built by the community and BotManor team. Install packages to jumpstart your AI applications.'\n )}\n </p>\n <div className=\"flex gap-4 mt-4\">\n <div className=\"text-center\">\n <p className=\"text-2xl font-bold tabular-nums\">{packages.length}</p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.store.featured.packages', 'Packages')}\n </p>\n </div>\n <div className=\"text-center\">\n <p className=\"text-2xl font-bold tabular-nums\">{installed.length}</p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.store.featured.installed', 'Installed')}\n </p>\n </div>\n </div>\n </div>\n </div>\n </GlassCard>\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">\n {t('botlit.store.featured.quickInstall', 'Quick Install')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {packages.slice(0, 3).map((pkg: StorePackageRecord) => (\n <div\n key={pkg.id}\n className=\"flex items-center justify-between p-2 bg-bg-sunken rounded\"\n >\n <div className=\"flex items-center gap-2\">\n <KindIcon kind={pkg.kind} className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"text-sm truncate max-w-[150px]\">{storePackageName(pkg)}</span>\n </div>\n {installedSlugs.has(pkg.slug) ? (\n <Badge variant=\"success\" className=\"text-xs\">\n <Check size={12} className=\"mr-1\" />\n {t('botlit.store.install.installedBadge', 'Installed')}\n </Badge>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_CREATE}>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 text-xs\"\n onClick={(e) => void handleInstall(pkg, e)}\n isLoading={installingSlug === pkg.slug}\n >\n {t('botlit.store.install.action', 'Install')}\n </Button>\n </BotmanorPermissionGate>\n )}\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n\n {/* Packages Grid */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-56 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"store packages\" error={error} onRetry={() => void refetch()} />\n ) : packages.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {packages.map((pkg: StorePackageRecord) => (\n <Link key={pkg.id} to={getPath(`store/package/${pkg.slug}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <KindIcon kind={pkg.kind} className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{storePackageName(pkg)}</CardTitle>\n <CardDescription className=\"text-xs\">\n {pkg.slug} v{pkg.version}\n </CardDescription>\n </div>\n </div>\n {installedSlugs.has(pkg.slug) && (\n <Badge variant=\"success\" className=\"text-xs\">\n <Check size={10} className=\"mr-1\" />\n {t('botlit.store.install.installedBadge', 'Installed')}\n </Badge>\n )}\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {storePackageDescription(pkg)}\n </p>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {kindLabel[pkg.kind] ?? pkg.kind}\n </Badge>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(pkg.publishedAt)}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title={t('botlit.store.empty.title', 'No packages found')}\n description={\n search || selectedKind\n ? t(\n 'botlit.store.empty.descriptionFiltered',\n 'Try adjusting your search or filters.'\n )\n : t(\n 'botlit.store.empty.descriptionNoPackages',\n 'No packages available in the store yet.'\n )\n }\n />\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAM,KAAsD,EAAE,SAAM,mBAAgB;AAClF,SAAQ,GAAR;EACE,KAAK,MACH,QAAO,kBAAC,GAAD,EAAoB,cAAa,CAAA;EAC1C,KAAK;EACL,KAAK,YACH,QAAO,kBAAC,GAAD,EAAgB,cAAa,CAAA;EACtC,KAAK;EACL,KAAK,OACH,QAAO,kBAAC,GAAD,EAAmB,cAAa,CAAA;EACzC,KAAK;EACL,KAAK,SACH,QAAO,kBAAC,GAAD,EAAqB,cAAa,CAAA;EAC3C,KAAK,QACH,QAAO,kBAAC,GAAD,EAAqB,cAAa,CAAA;EAC3C,KAAK;EACL,KAAK;EACL,KAAK,cACH,QAAO,kBAAC,GAAD,EAAqB,cAAa,CAAA;EAC3C,KAAK,gBACH,QAAO,kBAAC,GAAD,EAAmB,cAAa,CAAA;EACzC,QACE,QAAO,kBAAC,GAAD,EAAoB,cAAa,CAAA;;;AAI9C,SAAS,EAAa,GAAqD;AACzE,QAAO;EACL,KAAK,EAAE,8BAA8B,MAAM;EAC3C,OAAO,EAAE,gCAAgC,QAAQ;EACjD,UAAU,EAAE,mCAAmC,WAAW;EAC1D,iBAAiB,EAAE,0CAA0C,kBAAkB;EAC/E,QAAQ,EAAE,iCAAiC,SAAS;EACpD,OAAO,EAAE,gCAAgC,QAAQ;EACjD,mBAAmB,EAAE,4CAA4C,oBAAoB;EACrF,eAAe,EAAE,wCAAwC,gBAAgB;EACzE,kBAAkB,EAAE,2CAA2C,mBAAmB;EAClF,WAAW,EAAE,oCAAoC,YAAY;EAC7D,aAAa,EAAE,sCAAsC,cAAc;EACnE,gBAAgB,EAAE,yCAAyC,iBAAiB;EAC5E,aAAa,EAAE,sCAAsC,cAAc;EACnE,UAAU,EAAE,mCAAmC,WAAW;EAC1D,MAAM,EAAE,+BAA+B,OAAO;EAC9C,UAAU,EAAE,mCAAmC,WAAW;EAC3D;;AAGH,IAAa,UAAsB;CACjC,IAAM,IAAI,GAAO,EACX,EAAE,eAAY,GAAW,EACzB,IAAY,EAAa,EAAE,EAC3B,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,CAAC,GAAc,KAAmB,EAA6B,KAAK,EACpE,CAAC,GAAQ,KAAa,EAAsB,SAAS,EACrD,CAAC,GAAgB,KAAqB,EAAwB,KAAK,EAMnE,EAAE,MAAM,GAAU,YAAS,UAAO,eAAY,EAJhC,SACX;EAAE;EAAQ,MAAM,IAAe,CAAC,EAAa,GAAG,KAAA;EAAW;EAAQ,GAC1E;EAAC;EAAQ;EAAc;EAAO,CAC/B,CACgF,EAC3E,EAAE,MAAM,GAAW,SAAS,MAAqB,GAAsB,EACvE,EAAE,gBAAY,GAAmB,EAEjC,IAAiB,QAEnB,IAAI,IACF,EACG,KAAK,MAAU,EAAM,SAAS,KAAK,CACnC,QAAQ,MAAyB,OAAO,KAAS,SAAS,CAC9D,EACH,CAAC,EAAU,CACZ,EAEK,KAAgB,OAAO,GAAyB,MAAkB;AAGtE,EAFA,EAAE,gBAAgB,EAClB,EAAE,iBAAiB,EACnB,EAAkB,EAAI,KAAK;AAC3B,MAAI;AAOG,GANL,MAAM,GAAQ;IAAE,WAAW,EAAI;IAAI,MAAM,EAAe;IAAQ,CAAC,EACjE,EAAM,QACJ,EAAE,gCAAgC,0BAAwB,EACxD,MAAM,EAAiB,EAAI,EAC5B,CAAC,CACH,EACI,GAAkB;WAChB,GAAK;AACZ,KAAM,MACJ,aAAe,QACX,EAAI,UACJ,EAAE,8BAA8B,4BAA4B,CACjE;YACO;AACR,KAAkB,KAAK;;IAIrB,KAAuB;EAC3B,EAAe;EACf,EAAe;EACf,EAAe;EACf,EAAe;EACf,EAAe;EAChB;AAED,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,sBAAsB,iBAAiB;EAChD,aAAa,EACX,4BACA,mEACD;EACD,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAQ,SAAQ;cACd,kBAAC,GAAD;KAAM,IAAI,EAAQ,kBAAkB;eACjC,EAAE,sCAAsC,8BAA8B,EACrE,OAAO,EAAU,QAClB,CAAC;KACG,CAAA;IACA,CAAA,EACT,kBAAC,GAAD;IAAQ,SAAQ;IAAU,UAAU,kBAAC,IAAD,EAAc,MAAM,IAAM,CAAA;cAC3D,EAAE,uCAAuC,kBAAkB;IACrD,CAAA,CACL;;YAGR,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAAa,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;eACnC,EACC,wBACA,4VACD;KACW,CAAA;IAGd,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,wEAAyE,CAAA,EAC/F,kBAAC,GAAD;QACE,aAAa,EAAE,kCAAkC,qBAAqB;QACtE,OAAO;QACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;QAC1C,WAAU;QACV,CAAA,CACE;;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,SAAS,MAAiB,OAAO,YAAY;QAC7C,MAAK;QACL,eAAe,EAAgB,KAAK;kBAEnC,EAAE,4BAA4B,MAAM;QAC9B,CAAA,EACR,GAAM,KAAK,MACV,kBAAC,GAAD;QAEE,SAAS,MAAiB,IAAO,YAAY;QAC7C,MAAK;QACL,eAAe,EAAgB,EAAK;QACpC,UAAU,kBAAC,GAAD;SAAgB;SAAM,WAAU;SAAY,CAAA;kBAErD,EAAU;QACJ,EAPF,EAOE,CACT,CACE;;MAGN,kBAAC,UAAD;OACE,cAAY,EAAE,kCAAkC,gBAAgB;OAChE,WAAU;OACV,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAqB;iBAJ3D,CAME,kBAAC,UAAD;QAAQ,OAAM;kBAAU,EAAE,4BAA4B,qBAAqB;QAAU,CAAA,EACrF,kBAAC,UAAD;QAAQ,OAAM;kBAAQ,EAAE,0BAA0B,aAAa;QAAU,CAAA,CAClE;;MACL;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAC1C,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAO,WAAU,wBAAyB,CAAA;QACtC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,+BAA+B,gCAAgC;SAC/D,CAAA;QACL,kBAAC,KAAD;SAAG,WAAU;mBACV,EACC,qCACA,iKACD;SACC,CAAA;QACJ,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAmC,EAAS;WAAW,CAAA,EACpE,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAE,kCAAkC,WAAW;WAC9C,CAAA,CACA;aACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAmC,EAAU;WAAW,CAAA,EACrE,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAE,mCAAmC,YAAY;WAChD,CAAA,CACA;YACF;;QACF,EAAA,CAAA,CACF;;MACI,CAAA,EACZ,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBACpB,kBAAC,GAAD;OAAW,WAAU;iBAClB,EAAE,sCAAsC,gBAAgB;OAC/C,CAAA;MACD,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAS,MAAM,GAAG,EAAE,CAAC,KAAK,MACzB,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAU,MAAM,EAAI;SAAM,WAAU;SAAgC,CAAA,EACpE,kBAAC,QAAD;SAAM,WAAU;mBAAkC,EAAiB,EAAI;SAAQ,CAAA,CAC3E;WACL,EAAe,IAAI,EAAI,KAAK,GAC3B,kBAAC,GAAD;QAAO,SAAQ;QAAU,WAAU;kBAAnC,CACE,kBAAC,GAAD;SAAO,MAAM;SAAI,WAAU;SAAS,CAAA,EACnC,EAAE,uCAAuC,YAAY,CAChD;YAER,kBAAC,GAAD;QAAwB,YAAY,EAAqB;kBACvD,kBAAC,GAAD;SACE,MAAK;SACL,SAAQ;SACR,WAAU;SACV,UAAU,MAAM,KAAK,GAAc,GAAK,EAAE;SAC1C,WAAW,MAAmB,EAAI;mBAEjC,EAAE,+BAA+B,UAAU;SACrC,CAAA;QACc,CAAA,CAEvB;SAzBC,EAAI,GAyBL,CACN;MACU,CAAA,CACT,EAAA,CAAA,CACH;;IAGL,IACC,kBAAC,OAAD;KAAK,WAAU;eACZ;MAAC;MAAG;MAAG;MAAG;MAAG;MAAG;MAAE,CAAC,KAAK,MACvB,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;KACE,CAAA,GACJ,IACF,kBAAC,GAAD;KAAY,UAAS;KAAwB;KAAO,eAAe,KAAK,GAAS;KAAI,CAAA,GACnF,EAAS,SAAS,IACpB,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAS,KAAK,MACb,kBAAC,GAAD;MAAmB,IAAI,EAAQ,iBAAiB,EAAI,OAAO;gBACzD,kBAAC,GAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBACb,kBAAC,GAAD;WAAU,MAAM,EAAI;WAAM,WAAU;WAAyB,CAAA;UACzD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAa,EAAiB,EAAI;UAAa,CAAA,EACpE,kBAAC,GAAD;UAAiB,WAAU;oBAA3B;WACG,EAAI;WAAK;WAAG,EAAI;WACD;YACd,EAAA,CAAA,CACF;YACL,EAAe,IAAI,EAAI,KAAK,IAC3B,kBAAC,GAAD;SAAO,SAAQ;SAAU,WAAU;mBAAnC,CACE,kBAAC,GAAD;UAAO,MAAM;UAAI,WAAU;UAAS,CAAA,EACnC,EAAE,uCAAuC,YAAY,CAChD;WAEN;WACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAwB,EAAI;SAC3B,CAAA,EAGJ,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;UAAU,WAAU;oBAChC,EAAU,EAAI,SAAS,EAAI;UACtB,CAAA,EACR,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAmB,EAAI,YAAY;UAC/B,CAAA,CACH;WACF;WACM,CAAA,CACT;;MACF,EAzCI,EAAI,GAyCR,CACP;KACE,CAAA,GAEN,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EAAE,4BAA4B,oBAAoB;KACzD,aACE,KAAU,IACN,EACE,0CACA,wCACD,GACD,EACE,4CACA,0CACD;KAEP,CAAA;IAEA;;EACK,CAAA"}
|