@burdenoff/microfe-botmanor 2026.1109.2 → 2026.1110.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/botlit/components/Badge.js +2 -2
  2. package/dist/botlit/components/Badge.js.map +1 -1
  3. package/dist/botlit/components/ChannelSelectorSheet.js +4 -4
  4. package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -1
  5. package/dist/botlit/components/LoadMore.d.ts +9 -0
  6. package/dist/botlit/components/LoadMore.js +22 -0
  7. package/dist/botlit/components/LoadMore.js.map +1 -0
  8. package/dist/botlit/components/index.d.ts +1 -0
  9. package/dist/botlit/hooks/internal/workspaceGateway.d.ts +47 -0
  10. package/dist/botlit/hooks/internal/workspaceGateway.js +59 -1
  11. package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
  12. package/dist/botlit/hooks/useAgents.d.ts +2 -6
  13. package/dist/botlit/hooks/useAgents.js +71 -95
  14. package/dist/botlit/hooks/useAgents.js.map +1 -1
  15. package/dist/botlit/hooks/useBots.d.ts +2 -6
  16. package/dist/botlit/hooks/useBots.js +51 -75
  17. package/dist/botlit/hooks/useBots.js.map +1 -1
  18. package/dist/botlit/hooks/useExecutions.d.ts +2 -2
  19. package/dist/botlit/hooks/useExecutions.js +30 -34
  20. package/dist/botlit/hooks/useExecutions.js.map +1 -1
  21. package/dist/botlit/hooks/useStore.d.ts +3 -3
  22. package/dist/botlit/hooks/useStore.js +41 -50
  23. package/dist/botlit/hooks/useStore.js.map +1 -1
  24. package/dist/botlit/pages/A2AAgentDetailPage.js +1 -1
  25. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  26. package/dist/botlit/pages/AgentDetailPage.js +1 -1
  27. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  28. package/dist/botlit/pages/AgentsListPage.js +157 -156
  29. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  30. package/dist/botlit/pages/BotChannelsTab.js +24 -24
  31. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  32. package/dist/botlit/pages/BotsListPage.js +147 -146
  33. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  34. package/dist/botlit/pages/BucketsPage.js +3 -3
  35. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  36. package/dist/botlit/pages/ChannelDetailPage.js +2 -2
  37. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  38. package/dist/botlit/pages/ExecutionsPage.js +141 -134
  39. package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
  40. package/dist/botlit/pages/InstalledPackagesPage.js +43 -36
  41. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  42. package/dist/botlit/pages/MCPServersPage.js +1 -1
  43. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  44. package/dist/botlit/pages/SettingsPage.js +2 -2
  45. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  46. package/dist/botlit/pages/SkillDetailPage.js +1 -1
  47. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  48. package/dist/botlit/pages/StorePackageDetailPage.js +1 -1
  49. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  50. package/dist/botlit/pages/StorePage.js +150 -143
  51. package/dist/botlit/pages/StorePage.js.map +1 -1
  52. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BucketsPage.js","names":["SearchIcon","_Fragment","Textarea","Textarea$1","BucketTreeItem","isExpanded","expanded","bucket","hasChildren","isMenuOpen","activeMenu","can","useBotmanorCan","hasActions","BOTMANOR_PERMISSIONS","Link","getPath","level","e","onToggle","jsx","ChevronDown","ChevronRight","FolderOpen","Folder","Button","setActiveMenu","MoreHorizontal","BotmanorPermissionGate","onCreateChild","Plus","onEdit","Edit","onDelete","Trash2","child","BucketsPage","useBotlit","search","setSearch","useState","viewMode","setViewMode","setExpanded","showCreateModal","setShowCreateModal","showDeleteConfirm","setShowDeleteConfirm","editingBucket","setEditingBucket","actionMenuBucket","setActionMenuBucket","formData","setFormData","buckets","loadingBuckets","bucketsError","refetchBuckets","useBuckets","bucketTree","loadingTree","treeError","refetchTree","useBucketTree","createBucket","createBucketResult","useCreateBucket","updateBucket","updateBucketResult","useUpdateBucket","deleteBucket","deleteBucketResult","useDeleteBucket","handleToggle","next","prev","id","expandAll","allIds","collectIds","node","nodes","collapseAll","isLoading","loadError","retryLoad","handleCreate","err","toast","handleUpdate","handleDelete","bucketId","isNative","nativeNotify","startEditing","openCreateModal","parentId","PageLayout","PagePurpose","FolderTree","GlassCard","Search","Input","Settings","Card","CardContent","i","ErrorState","EmptyState","Fragment","CardHeader","CardTitle","CardDescription","formatRelativeTime","X","FormField","Save","nativeImpact"],"sources":["../../../src/botlit/pages/BucketsPage.tsx"],"sourcesContent":["/**\n * Buckets Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { toast } from 'sonner';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n Plus,\n Search as SearchIcon,\n FolderTree,\n Folder,\n FolderOpen,\n ChevronRight,\n ChevronDown,\n MoreHorizontal,\n Settings,\n Edit,\n Trash2,\n X,\n Save,\n} from 'lucide-react';\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, Textarea, FormField } from '../components/Input';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useBuckets,\n useBucketTree,\n useCreateBucket,\n useDeleteBucket,\n useUpdateBucket,\n type BucketRecord,\n type BucketTreeNode,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { Visibility } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate, useBotmanorCan } from '../permissions';\n\ntype BucketNode = BucketTreeNode;\n\nconst BucketTreeItem: FC<{\n bucket: BucketNode;\n level: number;\n expanded: Set<string>;\n onToggle: (id: string) => void;\n getPath: (path: string) => string;\n onEdit: (bucket: BucketNode) => void;\n onDelete: (bucketId: string) => void;\n onCreateChild: (parentId: string) => void;\n activeMenu: string | null;\n setActiveMenu: (id: string | null) => void;\n}> = ({\n bucket,\n level,\n expanded,\n onToggle,\n getPath,\n onEdit,\n onDelete,\n onCreateChild,\n activeMenu,\n setActiveMenu,\n}) => {\n const isExpanded = expanded.has(bucket.id);\n const hasChildren = bucket.children.length > 0;\n const isMenuOpen = activeMenu === bucket.id;\n const can = useBotmanorCan();\n const hasActions =\n can(BOTMANOR_PERMISSIONS.BUCKET_CREATE) ||\n can(BOTMANOR_PERMISSIONS.BUCKET_UPDATE) ||\n can(BOTMANOR_PERMISSIONS.BUCKET_DELETE);\n\n return (\n <div>\n <Link to={getPath(`buckets/${bucket.id}`)}>\n <div\n className=\"flex items-center gap-2 px-3 py-2 hover:bg-accent rounded-md transition-colors cursor-pointer group\"\n style={{ paddingLeft: `${level * 24 + 12}px` }}\n >\n {hasChildren ? (\n <button\n onClick={(e) => {\n e.preventDefault();\n onToggle(bucket.id);\n }}\n className=\"p-0.5 hover:bg-bg-sunken rounded\"\n >\n {isExpanded ? (\n <ChevronDown size={16} className=\"text-text-secondary\" />\n ) : (\n <ChevronRight size={16} className=\"text-text-secondary\" />\n )}\n </button>\n ) : (\n <div className=\"w-5\" />\n )}\n\n {isExpanded ? (\n <FolderOpen size={18} className=\"text-primary\" />\n ) : (\n <Folder size={18} className=\"text-text-secondary\" />\n )}\n\n <span className=\"flex-1 font-medium\">{bucket.name}</span>\n\n {hasActions && (\n <div className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setActiveMenu(isMenuOpen ? null : bucket.id);\n }}\n >\n <MoreHorizontal size={14} />\n </Button>\n {isMenuOpen && (\n <div className=\"absolute right-0 top-8 bg-popover border rounded-md shadow-lg z-50 py-1 min-w-[160px]\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onCreateChild(bucket.id);\n }}\n >\n <Plus size={14} />\n Add Sub-Bucket\n </button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_UPDATE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onEdit(bucket);\n }}\n >\n <Edit size={14} />\n Edit\n </button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_DELETE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-status-error-text text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onDelete(bucket.id);\n }}\n >\n <Trash2 size={14} />\n Delete\n </button>\n </BotmanorPermissionGate>\n </div>\n )}\n </div>\n )}\n </div>\n </Link>\n\n {isExpanded &&\n bucket.children.map((child) => (\n <BucketTreeItem\n key={child.id}\n bucket={child}\n level={level + 1}\n expanded={expanded}\n onToggle={onToggle}\n getPath={getPath}\n onEdit={onEdit}\n onDelete={onDelete}\n onCreateChild={onCreateChild}\n activeMenu={activeMenu}\n setActiveMenu={setActiveMenu}\n />\n ))}\n </div>\n );\n};\n\nexport const BucketsPage: FC = () => {\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [viewMode, setViewMode] = useState<'tree' | 'list'>('tree');\n const [expanded, setExpanded] = useState<Set<string>>(new Set(['bucket-1']));\n\n // Modal states\n const [showCreateModal, setShowCreateModal] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);\n const [editingBucket, setEditingBucket] = useState<BucketNode | null>(null);\n const [actionMenuBucket, setActionMenuBucket] = useState<string | null>(null);\n\n // Form state\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n visibility: 'PRIVATE' as Visibility,\n parentBucketId: undefined as string | undefined,\n });\n\n const {\n data: buckets,\n loading: loadingBuckets,\n error: bucketsError,\n refetch: refetchBuckets,\n } = useBuckets({ search });\n const {\n data: bucketTree,\n loading: loadingTree,\n error: treeError,\n refetch: refetchTree,\n } = useBucketTree();\n const [createBucket, createBucketResult] = useCreateBucket();\n const [updateBucket, updateBucketResult] = useUpdateBucket();\n const [deleteBucket, deleteBucketResult] = useDeleteBucket();\n\n const handleToggle = (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n };\n\n const expandAll = () => {\n if (bucketTree) {\n const allIds = new Set<string>();\n const collectIds = (nodes: BucketNode[]) => {\n for (const node of nodes) {\n allIds.add(node.id);\n if (node.children) collectIds(node.children);\n }\n };\n collectIds(bucketTree);\n setExpanded(allIds);\n }\n };\n\n const collapseAll = () => {\n setExpanded(new Set());\n };\n\n const isLoading = viewMode === 'tree' ? loadingTree : loadingBuckets;\n const loadError = viewMode === 'tree' ? treeError : bucketsError;\n const retryLoad = viewMode === 'tree' ? refetchTree : refetchBuckets;\n\n const handleCreate = async () => {\n if (!formData.name) return;\n try {\n await createBucket({\n name: formData.name,\n slug: formData.name.toLowerCase().replace(/\\s+/g, '-'),\n description: formData.description,\n parentBucketId: formData.parentBucketId,\n metadata: { visibility: formData.visibility },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create bucket');\n return;\n }\n toast.success(`Bucket \"${formData.name}\" created`);\n void refetchBuckets();\n void refetchTree();\n setShowCreateModal(false);\n setFormData({ name: '', description: '', visibility: 'PRIVATE', parentBucketId: undefined });\n };\n\n const handleUpdate = async () => {\n if (!editingBucket || !formData.name) return;\n try {\n await updateBucket({\n bucketId: editingBucket.id,\n input: {\n name: formData.name,\n description: formData.description,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update bucket');\n return;\n }\n toast.success('Bucket updated');\n void refetchBuckets();\n void refetchTree();\n setEditingBucket(null);\n };\n\n const handleDelete = async (bucketId: string) => {\n try {\n await deleteBucket(bucketId);\n if (isNative()) void nativeNotify('success');\n toast.success('Bucket deleted');\n void refetchBuckets();\n void refetchTree();\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n toast.error(err instanceof Error ? err.message : 'Failed to delete bucket');\n return;\n }\n setShowDeleteConfirm(null);\n };\n\n const startEditing = (bucket: BucketNode) => {\n setFormData({\n name: bucket.name,\n description: bucket.description ?? '',\n visibility: 'PRIVATE' as Visibility,\n parentBucketId: undefined,\n });\n setEditingBucket(bucket);\n setActionMenuBucket(null);\n };\n\n const openCreateModal = (parentId?: string) => {\n setFormData({\n name: '',\n description: '',\n visibility: 'PRIVATE',\n parentBucketId: parentId,\n });\n setShowCreateModal(true);\n };\n\n return (\n <PageLayout\n title=\"Buckets\"\n description=\"Organize your agents, apps, and resources into hierarchical folders\"\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<FolderTree size={18} />}>\n Buckets are folders for everything you build in BotManor — agents, bots, skills, knowledge\n and more — arranged in a hierarchy that mirrors how your team works. Group resources by\n team, project or environment so they stay organised, easy to find and simple to share as\n your account grows. Browse the tree or list view to manage that structure.\n </PagePurpose>\n\n {/* Summary */}\n {buckets.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-2\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total buckets</p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {buckets.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Top-level buckets</p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {bucketTree.length}\n </p>\n </GlassCard>\n </div>\n ) : null}\n\n {/* Controls */}\n <div className=\"flex items-center justify-between 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=\"Search buckets...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={expandAll}>\n Expand All\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={collapseAll}>\n Collapse All\n </Button>\n <div className=\"flex border border-border-subtle rounded-md overflow-hidden\">\n <Button\n variant={viewMode === 'tree' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"rounded-none\"\n onClick={() => setViewMode('tree')}\n >\n <FolderTree size={16} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"rounded-none\"\n onClick={() => setViewMode('list')}\n >\n <Settings size={16} />\n </Button>\n </div>\n </div>\n </div>\n\n {/* Tree View */}\n {viewMode === 'tree' && (\n <Card>\n <CardContent className=\"p-2\">\n {isLoading ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3, 4].map((i) => (\n <div\n key={i}\n className=\"h-10 bg-bg-sunken motion-safe:animate-vc-shimmer rounded\"\n />\n ))}\n </div>\n ) : loadError ? (\n <ErrorState resource=\"buckets\" error={loadError} onRetry={() => void retryLoad()} />\n ) : bucketTree.length > 0 ? (\n <div className=\"py-2\" onClick={() => setActionMenuBucket(null)}>\n {bucketTree.map((bucket) => (\n <BucketTreeItem\n key={bucket.id}\n bucket={bucket}\n level={0}\n expanded={expanded}\n onToggle={handleToggle}\n getPath={getPath}\n onEdit={startEditing}\n onDelete={(id) => setShowDeleteConfirm(id)}\n onCreateChild={(parentId) => openCreateModal(parentId)}\n activeMenu={actionMenuBucket}\n setActiveMenu={setActionMenuBucket}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-files\"\n title=\"No buckets created\"\n description=\"Create buckets to organize your BotManor resources.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </CardContent>\n </Card>\n )}\n\n {/* List View */}\n {viewMode === 'list' && (\n <>\n {isLoading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-32 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : loadError ? (\n <ErrorState resource=\"buckets\" error={loadError} onRetry={() => void retryLoad()} />\n ) : buckets.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {buckets.map((bucket: BucketRecord) => (\n <Link key={bucket.id} to={getPath(`buckets/${bucket.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <Folder className=\"h-5 w-5 text-primary\" />\n <div>\n <CardTitle className=\"text-base\">{bucket.name}</CardTitle>\n <CardDescription className=\"text-xs\">{bucket.path}</CardDescription>\n </div>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">{bucket.slug}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(bucket.createdAt)}\n </span>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title=\"No buckets found\"\n description=\"Create buckets to organize your BotManor resources.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </>\n )}\n\n {/* Info Card */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FolderTree size={18} />\n Organizing with Buckets\n </CardTitle>\n <CardDescription>\n Buckets help you organize and manage permissions for your resources\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Hierarchical Organization</h4>\n <p className=\"text-sm text-text-secondary\">\n Create nested folder structures to organize apps, agents, and other resources by\n team, project, or domain.\n </p>\n </div>\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Inherited Permissions</h4>\n <p className=\"text-sm text-text-secondary\">\n Set owners, editors, and viewers at the bucket level. Permissions cascade to all\n items within.\n </p>\n </div>\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Default Policies</h4>\n <p className=\"text-sm text-text-secondary\">\n Configure default policy bindings for buckets. All new items inherit these\n policies automatically.\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Create Bucket Modal */}\n {showCreateModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between\">\n <span>Create Bucket</span>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setShowCreateModal(false)}>\n <X size={16} />\n </Button>\n </CardTitle>\n <CardDescription>\n {formData.parentBucketId ? 'Create a new sub-bucket' : 'Create a new root bucket'}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Bucket Name\" required>\n <Input\n placeholder=\"e.g., Marketing Team\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this bucket for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setShowCreateModal(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleCreate}\n isLoading={createBucketResult.loading}\n disabled={!formData.name}\n leftIcon={<Save size={16} />}\n >\n Create Bucket\n </Button>\n </div>\n </Card>\n </div>\n )}\n\n {/* Edit Bucket Modal */}\n {editingBucket && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between\">\n <span>Edit Bucket</span>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setEditingBucket(null)}>\n <X size={16} />\n </Button>\n </CardTitle>\n <CardDescription>Update bucket details</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Bucket Name\" required>\n <Input\n placeholder=\"e.g., Marketing Team\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this bucket for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setEditingBucket(null)}>\n Cancel\n </Button>\n <Button\n onClick={handleUpdate}\n isLoading={updateBucketResult.loading}\n disabled={!formData.name}\n leftIcon={<Save size={16} />}\n >\n Save Changes\n </Button>\n </div>\n </Card>\n </div>\n )}\n\n {/* Delete Confirmation Modal */}\n {showDeleteConfirm && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-status-error-text\">\n <Trash2 size={18} />\n Delete Bucket\n </CardTitle>\n <CardDescription>\n Are you sure you want to delete this bucket? This action cannot be undone.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">\n Note: Buckets with children or items cannot be deleted. You must delete or move\n all contents first.\n </p>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setShowDeleteConfirm(null)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete(showDeleteConfirm);\n }}\n isLoading={deleteBucketResult.loading}\n leftIcon={<Trash2 size={16} />}\n >\n Delete Bucket\n </Button>\n </div>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"BucketsPage.js","names":["SearchIcon","_Fragment","Textarea","Textarea$1","BucketTreeItem","isExpanded","expanded","bucket","hasChildren","isMenuOpen","activeMenu","can","useBotmanorCan","hasActions","BOTMANOR_PERMISSIONS","Link","getPath","level","e","onToggle","jsx","ChevronDown","ChevronRight","FolderOpen","Folder","Button","setActiveMenu","MoreHorizontal","BotmanorPermissionGate","onCreateChild","Plus","onEdit","Edit","onDelete","Trash2","child","BucketsPage","useBotlit","search","setSearch","useState","viewMode","setViewMode","setExpanded","showCreateModal","setShowCreateModal","showDeleteConfirm","setShowDeleteConfirm","editingBucket","setEditingBucket","actionMenuBucket","setActionMenuBucket","formData","setFormData","buckets","loadingBuckets","bucketsError","refetchBuckets","useBuckets","bucketTree","loadingTree","treeError","refetchTree","useBucketTree","createBucket","createBucketResult","useCreateBucket","updateBucket","updateBucketResult","useUpdateBucket","deleteBucket","deleteBucketResult","useDeleteBucket","handleToggle","next","prev","id","expandAll","allIds","collectIds","node","nodes","collapseAll","isLoading","loadError","retryLoad","handleCreate","err","toast","handleUpdate","handleDelete","bucketId","isNative","nativeNotify","startEditing","openCreateModal","parentId","PageLayout","PagePurpose","FolderTree","GlassCard","Search","Input","Settings","Card","CardContent","i","ErrorState","EmptyState","Fragment","CardHeader","CardTitle","CardDescription","formatRelativeTime","X","FormField","Save","nativeImpact"],"sources":["../../../src/botlit/pages/BucketsPage.tsx"],"sourcesContent":["/**\n * Buckets Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { toast } from 'sonner';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n Plus,\n Search as SearchIcon,\n FolderTree,\n Folder,\n FolderOpen,\n ChevronRight,\n ChevronDown,\n MoreHorizontal,\n Settings,\n Edit,\n Trash2,\n X,\n Save,\n} from 'lucide-react';\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, Textarea, FormField } from '../components/Input';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useBuckets,\n useBucketTree,\n useCreateBucket,\n useDeleteBucket,\n useUpdateBucket,\n type BucketRecord,\n type BucketTreeNode,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { Visibility } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate, useBotmanorCan } from '../permissions';\n\ntype BucketNode = BucketTreeNode;\n\nconst BucketTreeItem: FC<{\n bucket: BucketNode;\n level: number;\n expanded: Set<string>;\n onToggle: (id: string) => void;\n getPath: (path: string) => string;\n onEdit: (bucket: BucketNode) => void;\n onDelete: (bucketId: string) => void;\n onCreateChild: (parentId: string) => void;\n activeMenu: string | null;\n setActiveMenu: (id: string | null) => void;\n}> = ({\n bucket,\n level,\n expanded,\n onToggle,\n getPath,\n onEdit,\n onDelete,\n onCreateChild,\n activeMenu,\n setActiveMenu,\n}) => {\n const isExpanded = expanded.has(bucket.id);\n const hasChildren = bucket.children.length > 0;\n const isMenuOpen = activeMenu === bucket.id;\n const can = useBotmanorCan();\n const hasActions =\n can(BOTMANOR_PERMISSIONS.BUCKET_CREATE) ||\n can(BOTMANOR_PERMISSIONS.BUCKET_UPDATE) ||\n can(BOTMANOR_PERMISSIONS.BUCKET_DELETE);\n\n return (\n <div>\n <Link to={getPath(`buckets/${bucket.id}`)}>\n <div\n className=\"flex items-center gap-2 px-3 py-2 hover:bg-accent rounded-md transition-colors cursor-pointer group\"\n style={{ paddingLeft: `${level * 24 + 12}px` }}\n >\n {hasChildren ? (\n <button\n onClick={(e) => {\n e.preventDefault();\n onToggle(bucket.id);\n }}\n className=\"p-0.5 hover:bg-bg-sunken rounded\"\n >\n {isExpanded ? (\n <ChevronDown size={16} className=\"text-text-secondary\" />\n ) : (\n <ChevronRight size={16} className=\"text-text-secondary\" />\n )}\n </button>\n ) : (\n <div className=\"w-5\" />\n )}\n\n {isExpanded ? (\n <FolderOpen size={18} className=\"text-primary\" />\n ) : (\n <Folder size={18} className=\"text-text-secondary\" />\n )}\n\n <span className=\"flex-1 font-medium\">{bucket.name}</span>\n\n {hasActions && (\n <div className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setActiveMenu(isMenuOpen ? null : bucket.id);\n }}\n >\n <MoreHorizontal size={14} />\n </Button>\n {isMenuOpen && (\n <div className=\"absolute right-0 top-8 bg-popover border rounded-md shadow-lg z-50 py-1 min-w-[160px]\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onCreateChild(bucket.id);\n }}\n >\n <Plus size={14} />\n Add Sub-Bucket\n </button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_UPDATE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onEdit(bucket);\n }}\n >\n <Edit size={14} />\n Edit\n </button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_DELETE}>\n <button\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent text-status-error-text text-left\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onDelete(bucket.id);\n }}\n >\n <Trash2 size={14} />\n Delete\n </button>\n </BotmanorPermissionGate>\n </div>\n )}\n </div>\n )}\n </div>\n </Link>\n\n {isExpanded &&\n bucket.children.map((child) => (\n <BucketTreeItem\n key={child.id}\n bucket={child}\n level={level + 1}\n expanded={expanded}\n onToggle={onToggle}\n getPath={getPath}\n onEdit={onEdit}\n onDelete={onDelete}\n onCreateChild={onCreateChild}\n activeMenu={activeMenu}\n setActiveMenu={setActiveMenu}\n />\n ))}\n </div>\n );\n};\n\nexport const BucketsPage: FC = () => {\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [viewMode, setViewMode] = useState<'tree' | 'list'>('tree');\n const [expanded, setExpanded] = useState<Set<string>>(new Set(['bucket-1']));\n\n // Modal states\n const [showCreateModal, setShowCreateModal] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);\n const [editingBucket, setEditingBucket] = useState<BucketNode | null>(null);\n const [actionMenuBucket, setActionMenuBucket] = useState<string | null>(null);\n\n // Form state\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n visibility: 'PRIVATE' as Visibility,\n parentBucketId: undefined as string | undefined,\n });\n\n const {\n data: buckets,\n loading: loadingBuckets,\n error: bucketsError,\n refetch: refetchBuckets,\n } = useBuckets({ search });\n const {\n data: bucketTree,\n loading: loadingTree,\n error: treeError,\n refetch: refetchTree,\n } = useBucketTree();\n const [createBucket, createBucketResult] = useCreateBucket();\n const [updateBucket, updateBucketResult] = useUpdateBucket();\n const [deleteBucket, deleteBucketResult] = useDeleteBucket();\n\n const handleToggle = (id: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n };\n\n const expandAll = () => {\n if (bucketTree) {\n const allIds = new Set<string>();\n const collectIds = (nodes: BucketNode[]) => {\n for (const node of nodes) {\n allIds.add(node.id);\n if (node.children) collectIds(node.children);\n }\n };\n collectIds(bucketTree);\n setExpanded(allIds);\n }\n };\n\n const collapseAll = () => {\n setExpanded(new Set());\n };\n\n const isLoading = viewMode === 'tree' ? loadingTree : loadingBuckets;\n const loadError = viewMode === 'tree' ? treeError : bucketsError;\n const retryLoad = viewMode === 'tree' ? refetchTree : refetchBuckets;\n\n const handleCreate = async () => {\n if (!formData.name) return;\n try {\n await createBucket({\n name: formData.name,\n slug: formData.name.toLowerCase().replace(/\\s+/g, '-'),\n description: formData.description,\n parentBucketId: formData.parentBucketId,\n metadata: { visibility: formData.visibility },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create bucket');\n return;\n }\n toast.success(`Bucket \"${formData.name}\" created`);\n void refetchBuckets();\n void refetchTree();\n setShowCreateModal(false);\n setFormData({ name: '', description: '', visibility: 'PRIVATE', parentBucketId: undefined });\n };\n\n const handleUpdate = async () => {\n if (!editingBucket || !formData.name) return;\n try {\n await updateBucket({\n bucketId: editingBucket.id,\n input: {\n name: formData.name,\n description: formData.description,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update bucket');\n return;\n }\n toast.success('Bucket updated');\n void refetchBuckets();\n void refetchTree();\n setEditingBucket(null);\n };\n\n const handleDelete = async (bucketId: string) => {\n try {\n await deleteBucket(bucketId);\n if (isNative()) void nativeNotify('success');\n toast.success('Bucket deleted');\n void refetchBuckets();\n void refetchTree();\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n toast.error(err instanceof Error ? err.message : 'Failed to delete bucket');\n return;\n }\n setShowDeleteConfirm(null);\n };\n\n const startEditing = (bucket: BucketNode) => {\n setFormData({\n name: bucket.name,\n description: bucket.description ?? '',\n visibility: 'PRIVATE' as Visibility,\n parentBucketId: undefined,\n });\n setEditingBucket(bucket);\n setActionMenuBucket(null);\n };\n\n const openCreateModal = (parentId?: string) => {\n setFormData({\n name: '',\n description: '',\n visibility: 'PRIVATE',\n parentBucketId: parentId,\n });\n setShowCreateModal(true);\n };\n\n return (\n <PageLayout\n title=\"Buckets\"\n description=\"Organize your agents, apps, and resources into hierarchical folders\"\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<FolderTree size={18} />}>\n Buckets are folders for everything you build in BotManor — agents, bots, skills, knowledge\n and more — arranged in a hierarchy that mirrors how your team works. Group resources by\n team, project or environment so they stay organised, easy to find and simple to share as\n your account grows. Browse the tree or list view to manage that structure.\n </PagePurpose>\n\n {/* Summary */}\n {buckets.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-2\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total buckets</p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {buckets.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Top-level buckets</p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {bucketTree.length}\n </p>\n </GlassCard>\n </div>\n ) : null}\n\n {/* Controls */}\n <div className=\"flex items-center justify-between 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=\"Search buckets...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={expandAll}>\n Expand All\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={collapseAll}>\n Collapse All\n </Button>\n <div className=\"flex border border-border-subtle rounded-md overflow-hidden\">\n <Button\n variant={viewMode === 'tree' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"rounded-none\"\n onClick={() => setViewMode('tree')}\n >\n <FolderTree size={16} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"rounded-none\"\n onClick={() => setViewMode('list')}\n >\n <Settings size={16} />\n </Button>\n </div>\n </div>\n </div>\n\n {/* Tree View */}\n {viewMode === 'tree' && (\n <Card>\n <CardContent className=\"p-2\">\n {isLoading ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3, 4].map((i) => (\n <div\n key={i}\n className=\"h-10 bg-bg-sunken motion-safe:animate-vc-shimmer rounded\"\n />\n ))}\n </div>\n ) : loadError ? (\n <ErrorState resource=\"buckets\" error={loadError} onRetry={() => void retryLoad()} />\n ) : bucketTree.length > 0 ? (\n <div className=\"py-2\" onClick={() => setActionMenuBucket(null)}>\n {bucketTree.map((bucket) => (\n <BucketTreeItem\n key={bucket.id}\n bucket={bucket}\n level={0}\n expanded={expanded}\n onToggle={handleToggle}\n getPath={getPath}\n onEdit={startEditing}\n onDelete={(id) => setShowDeleteConfirm(id)}\n onCreateChild={(parentId) => openCreateModal(parentId)}\n activeMenu={actionMenuBucket}\n setActiveMenu={setActionMenuBucket}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-files\"\n title=\"No buckets created\"\n description=\"Create buckets to organize your BotManor resources.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </CardContent>\n </Card>\n )}\n\n {/* List View */}\n {viewMode === 'list' && (\n <>\n {isLoading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-32 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : loadError ? (\n <ErrorState resource=\"buckets\" error={loadError} onRetry={() => void retryLoad()} />\n ) : buckets.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {buckets.map((bucket: BucketRecord) => (\n <Link key={bucket.id} to={getPath(`buckets/${bucket.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <Folder className=\"h-5 w-5 text-primary\" />\n <div>\n <CardTitle className=\"text-base\">{bucket.name}</CardTitle>\n <CardDescription className=\"text-xs\">{bucket.path}</CardDescription>\n </div>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">{bucket.slug}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(bucket.createdAt)}\n </span>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title=\"No buckets found\"\n description=\"Create buckets to organize your BotManor resources.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.BUCKET_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => openCreateModal()}>\n Create Bucket\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </>\n )}\n\n {/* Info Card */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FolderTree size={18} />\n Organizing with Buckets\n </CardTitle>\n <CardDescription>\n Buckets help you organize and manage permissions for your resources\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Hierarchical Organization</h4>\n <p className=\"text-sm text-text-secondary\">\n Create nested folder structures to organize apps, agents, and other resources by\n team, project, or domain.\n </p>\n </div>\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Inherited Permissions</h4>\n <p className=\"text-sm text-text-secondary\">\n Set owners, editors, and viewers at the bucket level. Permissions cascade to all\n items within.\n </p>\n </div>\n <div className=\"space-y-2\">\n <h4 className=\"font-medium\">Default Policies</h4>\n <p className=\"text-sm text-text-secondary\">\n Configure default policy bindings for buckets. All new items inherit these\n policies automatically.\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Create Bucket Modal */}\n {showCreateModal && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between\">\n <span>Create Bucket</span>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setShowCreateModal(false)}>\n <X size={16} />\n </Button>\n </CardTitle>\n <CardDescription>\n {formData.parentBucketId ? 'Create a new sub-bucket' : 'Create a new root bucket'}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Bucket Name\" required>\n <Input\n placeholder=\"e.g., Marketing Team\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this bucket for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setShowCreateModal(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleCreate}\n isLoading={createBucketResult.loading}\n disabled={!formData.name}\n leftIcon={<Save size={16} />}\n >\n Create Bucket\n </Button>\n </div>\n </Card>\n </div>\n )}\n\n {/* Edit Bucket Modal */}\n {editingBucket && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between\">\n <span>Edit Bucket</span>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setEditingBucket(null)}>\n <X size={16} />\n </Button>\n </CardTitle>\n <CardDescription>Update bucket details</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Bucket Name\" required>\n <Input\n placeholder=\"e.g., Marketing Team\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this bucket for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setEditingBucket(null)}>\n Cancel\n </Button>\n <Button\n onClick={handleUpdate}\n isLoading={updateBucketResult.loading}\n disabled={!formData.name}\n leftIcon={<Save size={16} />}\n >\n Save Changes\n </Button>\n </div>\n </Card>\n </div>\n )}\n\n {/* Delete Confirmation Modal */}\n {showDeleteConfirm && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-md mx-4\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-status-error-text\">\n <Trash2 size={18} />\n Delete Bucket\n </CardTitle>\n <CardDescription>\n Are you sure you want to delete this bucket? This action cannot be undone.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-text-secondary\">\n Note: Buckets with children or items cannot be deleted. You must delete or move\n all contents first.\n </p>\n </CardContent>\n <div className=\"flex justify-end gap-2 p-4 border-t\">\n <Button variant=\"outline\" onClick={() => setShowDeleteConfirm(null)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete(showDeleteConfirm);\n }}\n isLoading={deleteBucketResult.loading}\n leftIcon={<Trash2 size={16} />}\n >\n Delete Bucket\n </Button>\n </div>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -810,7 +810,7 @@ var Ie = ({ type: e }) => {
810
810
  children: [
811
811
  /* @__PURE__ */ b(Oe, {
812
812
  size: 20,
813
- className: "text-green-600 shrink-0"
813
+ className: "text-status-success-text shrink-0"
814
814
  }),
815
815
  /* @__PURE__ */ x("div", {
816
816
  className: "min-w-0 flex-1",
@@ -833,7 +833,7 @@ var Ie = ({ type: e }) => {
833
833
  className: "flex items-center gap-1",
834
834
  children: z.isTokenExpired && /* @__PURE__ */ b(h, {
835
835
  variant: "outline",
836
- className: "text-xs text-amber-600 border-amber-400",
836
+ className: "text-xs text-status-warning-text border-status-warning-border",
837
837
  children: "Token expired"
838
838
  })
839
839
  })
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelDetailPage.js","names":["Textarea","_Fragment","Textarea$1","CHANNEL_TYPES","VISIBILITIES","splitList","value","entry","ChannelIcon","type","Hash","Globe","MessageSquare","Radio","ChannelDetailPage","useParams","useBotlit","searchParams","setSearchParams","useSearchParams","connector","useChannelConnector","isNew","connectorId","routes","refetchRoutes","useChannelRoutes","bots","useBots","createConnector","createConnectorResult","useCreateChannelConnector","updateConnector","updateConnectorResult","useUpdateChannelConnector","deleteConnector","deleteConnectorResult","useDeleteChannelConnector","createRoute","createRouteResult","useCreateChannelRoute","slackChannelId","slackConnection","slackConnectionLoading","refetchSlackConnection","useMyUserPlatformConnection","initiateSlack","useInitiateSlackConnect","linkIntegration","linking","useLinkIntegrationConnection","toggleNotifications","togglingNotifications","useToggleSlackNotifications","revokeConnection","revoking","useRevokeSlackConnection","oauthError","setOauthError","useState","oauthLinkConsumed","useRef","integrationConnectionId","channelId","cleaned","connection","handleSlackConnect","redirectUri","handleToggleNotifications","handleRevokeSlack","isEditing","setIsEditing","showDeleteConfirm","setShowDeleteConfirm","showAddRoute","setShowAddRoute","newRoute","setNewRoute","formData","setFormData","widgetConfig","setWidgetConfig","buildWidgetMetadata","WIDGET_METADATA_KEY","handleCreate","created","toast","navigateTo","err","handleUpdate","handleDelete","isNative","nativeNotify","handleAddRoute","selectedBot","a","startEditing","toUnion","saved","readWidgetConfig","PageLayout","Button","Save","Card","CardHeader","CardTitle","CardContent","FormField","Input","Palette","loading","EmptyState","connectorRoutes","r","connectorType","savedWidgetConfig","ArrowLeft","StatusBadge","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Plus","Fragment","Edit","nativeImpact","Trash2","PagePurpose","NextSteps","Settings","X","bot","GlassCard","Badge","origin","prompt","i","CardDescription","routeMetadataString","route","ExternalLink","Slack","Loader2","CheckCircle2","Bell","BellOff","Unlink","Shield","key","formatRelativeTime","tag"],"sources":["../../../src/botlit/pages/ChannelDetailPage.tsx"],"sourcesContent":["/**\n * Channel Detail Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { useParams, useSearchParams } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Radio,\n MessageSquare,\n Globe,\n Hash,\n Shield,\n Settings,\n Save,\n Plus,\n ExternalLink,\n Palette,\n Edit,\n Trash2,\n X,\n Slack,\n Bell,\n BellOff,\n CheckCircle2,\n Unlink,\n Loader2,\n} from 'lucide-react';\nimport { PagePurpose, NextSteps, 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, Textarea, FormField } from '../components/Input';\nimport { StatusBadge, Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport {\n useChannelConnector,\n useChannelRoutes,\n useCreateChannelConnector,\n useUpdateChannelConnector,\n useDeleteChannelConnector,\n useCreateChannelRoute,\n routeMetadataString,\n useBots,\n useMyUserPlatformConnection,\n useInitiateSlackConnect,\n useLinkIntegrationConnection,\n useToggleSlackNotifications,\n useRevokeSlackConnection,\n} from '../hooks';\nimport { readWidgetConfig, WIDGET_METADATA_KEY } from '../hooks/useChannels';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { toUnion } from '../utils/unions';\nimport type { ChannelType, Visibility } from '../types';\n\n/** Channel types the UI can render icons/labels for. */\nconst CHANNEL_TYPES: ChannelType[] = [\n 'WEB_WIDGET',\n 'SLACK',\n 'TEAMS',\n 'DISCORD',\n 'WHATSAPP',\n 'WEBHOOK',\n 'CUSTOM',\n];\n\nconst VISIBILITIES: Visibility[] = ['PRIVATE', 'WORKSPACE', 'PUBLIC'];\n\n/** Splits a comma-separated form field into a trimmed, non-empty list. */\nfunction splitList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\nimport { toast } from 'sonner';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\ninterface ChannelDetailPageProps {\n isNew?: boolean;\n}\n\nconst ChannelIcon: FC<{ type: ChannelType }> = ({ type }) => {\n switch (type) {\n case 'SLACK':\n return <Hash size={18} />;\n case 'WEB_WIDGET':\n return <Globe size={18} />;\n case 'TEAMS':\n return <MessageSquare size={18} />;\n default:\n return <Radio size={18} />;\n }\n};\n\nexport const ChannelDetailPage: FC<ChannelDetailPageProps> = ({ isNew }) => {\n const { connectorId } = useParams();\n const { navigateTo } = useBotlit();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: connector, loading } = useChannelConnector(isNew ? undefined : connectorId);\n const { data: routes, refetch: refetchRoutes } = useChannelRoutes(connectorId);\n const { data: bots } = useBots();\n const [createConnector, createConnectorResult] = useCreateChannelConnector();\n const [updateConnector, updateConnectorResult] = useUpdateChannelConnector();\n const [deleteConnector, deleteConnectorResult] = useDeleteChannelConnector();\n const [createRoute, createRouteResult] = useCreateChannelRoute();\n\n // Phase 7: Slack personal account connect\n const slackChannelId =\n connector?.type === 'SLACK' && connector?.credentialsRefId\n ? connector.credentialsRefId\n : undefined;\n const {\n data: slackConnection,\n loading: slackConnectionLoading,\n refetch: refetchSlackConnection,\n } = useMyUserPlatformConnection(slackChannelId);\n const { initiate: initiateSlack } = useInitiateSlackConnect();\n const { link: linkIntegration, loading: linking } = useLinkIntegrationConnection();\n const { toggle: toggleNotifications, loading: togglingNotifications } =\n useToggleSlackNotifications();\n const { revoke: revokeConnection, loading: revoking } = useRevokeSlackConnection();\n const [oauthError, setOauthError] = useState<string | null>(null);\n\n // After integrations OAuth flow: link integration connection to channel\n // URL params: ?integrationConnectionId=<id>&channelId=<id>\n //\n // The ref — not an empty dependency list — is what makes this run once: the\n // params are consumed exactly once per visit, while the effect still declares\n // everything it reads.\n const oauthLinkConsumed = useRef(false);\n useEffect(() => {\n if (oauthLinkConsumed.current) return;\n\n const integrationConnectionId = searchParams.get('integrationConnectionId');\n const channelId = searchParams.get('channelId');\n if (!integrationConnectionId || !channelId) return;\n\n oauthLinkConsumed.current = true;\n\n // Clean the URL immediately so a refresh doesn't re-trigger\n const cleaned = new URLSearchParams(searchParams);\n cleaned.delete('integrationConnectionId');\n cleaned.delete('channelId');\n setSearchParams(cleaned, { replace: true });\n\n setOauthError(null);\n void linkIntegration(integrationConnectionId, channelId).then((connection) => {\n if (connection) {\n void refetchSlackConnection();\n } else {\n setOauthError('Failed to link Slack connection. Please try again.');\n }\n });\n }, [searchParams, setSearchParams, linkIntegration, refetchSlackConnection]);\n\n const handleSlackConnect = () => {\n if (!slackChannelId) return;\n // Slack appends ?code=...&state=... to the redirect_uri we supply\n const redirectUri = `${window.location.origin}${window.location.pathname}`;\n initiateSlack(slackChannelId, redirectUri);\n };\n\n const handleToggleNotifications = async () => {\n if (!slackConnection) return;\n const updated = await toggleNotifications(\n slackConnection.id,\n !slackConnection.notificationsEnabled\n );\n if (updated) {\n await refetchSlackConnection();\n }\n };\n\n const handleRevokeSlack = async () => {\n if (!slackConnection) return;\n const ok = await revokeConnection(slackConnection.id);\n if (ok) {\n await refetchSlackConnection();\n }\n };\n\n const [isEditing, setIsEditing] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [showAddRoute, setShowAddRoute] = useState(false);\n const [newRoute, setNewRoute] = useState({ locationId: '', locationName: '', botId: '' });\n\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n type: 'WEB_WIDGET' as ChannelType,\n visibility: 'PRIVATE' as Visibility,\n credentialsRefId: '',\n });\n\n const [widgetConfig, setWidgetConfig] = useState({\n allowedOrigins: '',\n primaryColor: '#3b82f6',\n fontFamily: 'Inter, sans-serif',\n starterPrompts: '',\n });\n\n /**\n * The connector has no widget column — the appearance settings are stored\n * under `metadata.webWidget`, which is where the detail view reads them back.\n */\n const buildWidgetMetadata = (): Record<string, unknown> | undefined => {\n if (formData.type !== 'WEB_WIDGET') return undefined;\n return {\n [WIDGET_METADATA_KEY]: {\n allowedOrigins: splitList(widgetConfig.allowedOrigins),\n primaryColor: widgetConfig.primaryColor,\n fontFamily: widgetConfig.fontFamily,\n starterPrompts: splitList(widgetConfig.starterPrompts),\n },\n };\n };\n\n const handleCreate = async () => {\n if (!formData.name) return;\n try {\n const created = await createConnector({\n name: formData.name,\n type: formData.type,\n description: formData.description || undefined,\n visibility: formData.visibility,\n credentialsRefId: formData.credentialsRefId || undefined,\n metadata: buildWidgetMetadata(),\n });\n toast.success(`Channel \"${created.name}\" created`);\n navigateTo(`channels/${created.id}`);\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create channel connector');\n }\n };\n\n const handleUpdate = async () => {\n if (!connectorId || !formData.name) return;\n try {\n await updateConnector({\n connectorId,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n visibility: formData.visibility,\n credentialsRefId: formData.credentialsRefId || undefined,\n metadata: buildWidgetMetadata(),\n },\n });\n toast.success('Channel updated');\n setIsEditing(false);\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update channel connector');\n }\n };\n\n const handleDelete = async () => {\n if (!connectorId) return;\n try {\n await deleteConnector(connectorId);\n if (isNative()) void nativeNotify('success');\n navigateTo('channels');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n };\n\n const handleAddRoute = async () => {\n if (!connectorId || !newRoute.locationId || !newRoute.botId) return;\n const selectedBot = bots?.find((a: { id: string; name: string }) => a.id === newRoute.botId);\n try {\n await createRoute({\n connectorId,\n locationId: newRoute.locationId,\n appId: newRoute.botId,\n metadata: {\n locationName: newRoute.locationName || newRoute.locationId,\n appName: selectedBot?.name,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create route');\n return;\n }\n toast.success('Route created');\n void refetchRoutes();\n setNewRoute({ locationId: '', locationName: '', botId: '' });\n setShowAddRoute(false);\n };\n\n const startEditing = () => {\n if (!connector) return;\n setFormData({\n name: connector.name,\n description: connector.description || '',\n type: toUnion(connector.type, CHANNEL_TYPES, 'CUSTOM'),\n visibility: toUnion(connector.visibility, VISIBILITIES, 'PRIVATE'),\n credentialsRefId: connector.credentialsRefId || '',\n });\n const saved = readWidgetConfig(connector);\n if (saved) {\n setWidgetConfig({\n allowedOrigins: saved.allowedOrigins.join(', '),\n primaryColor: saved.primaryColor,\n fontFamily: saved.fontFamily,\n starterPrompts: saved.starterPrompts.join(', '),\n });\n }\n setIsEditing(true);\n };\n\n if (isNew) {\n return (\n <PageLayout\n title=\"Create Channel Connector\"\n description=\"Set up a new channel for your AI agents\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => navigateTo('channels')}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleCreate}\n isLoading={createConnectorResult.loading || updateConnectorResult.loading}\n disabled={!formData.name}\n >\n Create\n </Button>\n </div>\n }\n >\n <div className=\"max-w-2xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Connector Name\" required>\n <Input\n placeholder=\"e.g., Production Web Widget\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this channel connector for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Channel Type\" required>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.type}\n onChange={(e) =>\n setFormData({ ...formData, type: e.target.value as ChannelType })\n }\n >\n <option value=\"WEB_WIDGET\">Web Widget</option>\n <option value=\"SLACK\">Slack</option>\n <option value=\"TEAMS\">Microsoft Teams</option>\n <option value=\"DISCORD\">Discord</option>\n <option value=\"WHATSAPP\">WhatsApp</option>\n <option value=\"WEBHOOK\">Webhook</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </div>\n\n {formData.type !== 'WEB_WIDGET' && (\n <FormField label=\"Credentials Reference\">\n <Input\n placeholder=\"e.g., secret-slack-token\"\n value={formData.credentialsRefId}\n onChange={(e) => setFormData({ ...formData, credentialsRefId: e.target.value })}\n />\n </FormField>\n )}\n </CardContent>\n </Card>\n\n {formData.type === 'WEB_WIDGET' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Palette size={18} />\n Widget Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Allowed Origins\" description=\"Comma-separated list of domains\">\n <Input\n placeholder=\"e.g., https://example.com, https://app.example.com\"\n value={widgetConfig.allowedOrigins}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, allowedOrigins: e.target.value })\n }\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Primary Color\">\n <div className=\"flex gap-2\">\n <input\n type=\"color\"\n value={widgetConfig.primaryColor}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, primaryColor: e.target.value })\n }\n className=\"h-10 w-16 rounded border border-border-default\"\n />\n <Input\n value={widgetConfig.primaryColor}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, primaryColor: e.target.value })\n }\n />\n </div>\n </FormField>\n\n <FormField label=\"Font Family\">\n <Input\n value={widgetConfig.fontFamily}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, fontFamily: e.target.value })\n }\n />\n </FormField>\n </div>\n\n <FormField label=\"Starter Prompts\" description=\"One per line\">\n <Textarea\n placeholder=\"What can you help me with?\"\n value={widgetConfig.starterPrompts}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, starterPrompts: e.target.value })\n }\n rows={3}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n </div>\n </PageLayout>\n );\n }\n\n if (loading) {\n return (\n <PageLayout title=\"Loading...\">\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!connector) {\n return (\n <PageLayout title=\"Connector Not Found\">\n <EmptyState\n illustration=\"empty-notifications\"\n title=\"Connector Not Found\"\n description=\"This channel connector doesn't exist.\"\n action={<Button onClick={() => navigateTo('channels')}>Back to Channels</Button>}\n />\n </PageLayout>\n );\n }\n\n const connectorRoutes =\n routes?.filter((r: { connectorId: string }) => r.connectorId === connector.id) || [];\n const connectorType = toUnion(connector.type, CHANNEL_TYPES, 'CUSTOM');\n const savedWidgetConfig = readWidgetConfig(connector);\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('channels')}>\n <ArrowLeft size={20} />\n </Button>\n <div className=\"p-2 rounded-lg bg-action-primary-bg/10\">\n <ChannelIcon type={connectorType} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{connector.name}</span>\n <StatusBadge status={connector.status} />\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{connector.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button\n variant=\"outline\"\n leftIcon={<Plus size={16} />}\n onClick={() => setShowAddRoute(true)}\n >\n Add Route\n </Button>\n </BotmanorPermissionGate>\n {isEditing ? (\n <>\n <Button variant=\"outline\" onClick={() => setIsEditing(false)}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleUpdate}\n isLoading={updateConnectorResult.loading}\n >\n Save\n </Button>\n </>\n ) : (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_UPDATE}>\n <Button variant=\"outline\" leftIcon={<Edit size={16} />} onClick={startEditing}>\n Edit\n </Button>\n </BotmanorPermissionGate>\n {showDeleteConfirm ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n isLoading={deleteConnectorResult.loading}\n >\n Confirm\n </Button>\n </div>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n onClick={() => setShowDeleteConfirm(true)}\n >\n Delete\n </Button>\n </BotmanorPermissionGate>\n )}\n </>\n )}\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Radio size={18} />}>\n This connector links BotManor to one messaging platform. From here you add routes — each\n mapping a specific location on the channel (a Slack channel, a widget, a number) to the\n bot that should answer there — tweak the connector&rsquo;s settings, and manage its\n connection. Set up at least one route so messages on this channel reach a bot.\n </PagePurpose>\n\n <NextSteps\n storageKey={`botlit-channel-${connector.id}`}\n steps={[\n {\n id: 'route',\n label: 'Add a route',\n description: 'Point an incoming location on this channel at one of your bots.',\n icon: <Plus size={16} />,\n onClick: () => setShowAddRoute(true),\n done: connectorRoutes.length > 0,\n },\n {\n id: 'edit',\n label: 'Review connector settings',\n description: 'Confirm the name, visibility and channel-specific configuration.',\n icon: <Settings size={16} />,\n onClick: startEditing,\n },\n {\n id: 'bots',\n label: 'Check your bots',\n description: 'Make sure the bot you are routing to is active and configured.',\n icon: <MessageSquare size={16} />,\n onClick: () => navigateTo('bots'),\n },\n ]}\n />\n\n {/* Add Route Modal */}\n {showAddRoute && (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle>Add Route</CardTitle>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setShowAddRoute(false)}>\n <X size={16} />\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Location ID\" required>\n <Input\n placeholder=\"e.g., #general or channel ID\"\n value={newRoute.locationId}\n onChange={(e) => setNewRoute({ ...newRoute, locationId: e.target.value })}\n />\n </FormField>\n <FormField label=\"Location Name\">\n <Input\n placeholder=\"Friendly name (optional)\"\n value={newRoute.locationName}\n onChange={(e) => setNewRoute({ ...newRoute, locationName: e.target.value })}\n />\n </FormField>\n </div>\n <FormField label=\"Connect to Bot\" required>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newRoute.botId}\n onChange={(e) => setNewRoute({ ...newRoute, botId: e.target.value })}\n >\n <option value=\"\">Select a bot...</option>\n {bots?.map((bot: { id: string; name: string }) => (\n <option key={bot.id} value={bot.id}>\n {bot.name}\n </option>\n ))}\n </select>\n </FormField>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"outline\" onClick={() => setShowAddRoute(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleAddRoute}\n isLoading={createRouteResult.loading}\n disabled={!newRoute.locationId || !newRoute.botId}\n >\n Add Route\n </Button>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Edit Form */}\n {isEditing && (\n <Card>\n <CardHeader>\n <CardTitle>Edit Channel</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Connector Name\" required>\n <Input\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {/* Overview Cards */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <div className=\"p-3 rounded-full bg-action-primary-bg/10 w-fit mx-auto mb-2\">\n <ChannelIcon type={connectorType} />\n </div>\n <p className=\"text-lg font-bold capitalize\">\n {connector.type.toLowerCase().replace('_', ' ')}\n </p>\n <p className=\"text-sm text-text-secondary\">Channel Type</p>\n </CardContent>\n </Card>\n <GlassCard treatment=\"glass\" glow className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {connectorRoutes.length}\n </p>\n <p className=\"text-sm text-text-secondary\">Active Routes</p>\n </GlassCard>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary capitalize\">\n {connector.visibility.toLowerCase()}\n </p>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{connector.revision}</p>\n <p className=\"text-sm text-text-secondary\">Revision</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Web Widget Configuration */}\n {savedWidgetConfig && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Palette size={18} />\n Widget Configuration\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Allowed Origins</p>\n {savedWidgetConfig.allowedOrigins.length > 0 ? (\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {savedWidgetConfig.allowedOrigins.map((origin) => (\n <Badge key={origin} variant=\"outline\" className=\"font-mono text-xs\">\n {origin}\n </Badge>\n ))}\n </div>\n ) : (\n <p className=\"font-medium\">Any origin</p>\n )}\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Theme</p>\n <div className=\"flex items-center gap-2 mt-1\">\n <div\n className=\"w-6 h-6 rounded border border-border-subtle\"\n style={{ backgroundColor: savedWidgetConfig.primaryColor }}\n />\n <span className=\"font-mono text-sm\">{savedWidgetConfig.primaryColor}</span>\n </div>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Font Family</p>\n <p className=\"font-medium\">{savedWidgetConfig.fontFamily}</p>\n </div>\n </div>\n {savedWidgetConfig.starterPrompts.length > 0 && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <p className=\"text-sm text-text-secondary mb-2\">Starter Prompts</p>\n <div className=\"flex flex-wrap gap-2\">\n {savedWidgetConfig.starterPrompts.map((prompt, i) => (\n <Badge key={i} variant=\"secondary\">\n {prompt}\n </Badge>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Routes */}\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>Routes</CardTitle>\n <CardDescription>Routes connect this channel to your bots</CardDescription>\n </div>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Plus size={14} />}\n onClick={() => setShowAddRoute(true)}\n >\n Add Route\n </Button>\n </BotmanorPermissionGate>\n </CardHeader>\n <CardContent>\n {connectorRoutes.length > 0 ? (\n <div className=\"space-y-3\">\n {connectorRoutes.map(\n (route: {\n id: string;\n locationId: string;\n appId: string;\n revision: number;\n metadata?: Record<string, unknown> | null;\n }) => (\n <div\n key={route.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 rounded-lg bg-bg-sunken\">\n <MessageSquare size={18} className=\"text-text-secondary\" />\n </div>\n <div>\n <p className=\"font-medium\">\n {routeMetadataString(route, 'locationName') ?? route.locationId}\n </p>\n <p className=\"text-sm text-text-secondary\">\n Connected to: {routeMetadataString(route, 'appName') ?? route.appId}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">Rev {route.revision}</Badge>\n <Button variant=\"ghost\" size=\"sm\">\n <ExternalLink size={14} />\n </Button>\n </div>\n </div>\n )\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No routes configured\"\n description=\"Add a route to connect this channel to a bot.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddRoute(true)}>\n Add Route\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </CardContent>\n </Card>\n\n {/* Slack Personal Account Connect (Phase 7) */}\n {connector.type === 'SLACK' && connector.credentialsRefId && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Slack size={18} />\n Your Slack Account\n </CardTitle>\n <CardDescription>\n Connect your personal Slack account to receive direct messages from this bot\n </CardDescription>\n </CardHeader>\n <CardContent>\n {/* OAuth error banner */}\n {oauthError && (\n <div className=\"mb-4 flex items-start gap-2 rounded-lg border border-status-error-border/40 bg-status-error-bg/10 px-3 py-2 text-sm text-status-error-text\">\n <span>{oauthError}</span>\n <button\n onClick={() => setOauthError(null)}\n className=\"ml-auto cursor-pointer text-status-error-text/70 hover:text-status-error-text\"\n >\n <X size={14} />\n </button>\n </div>\n )}\n\n {/* Linking integration connection */}\n {linking ? (\n <div className=\"flex items-center gap-2 py-4 text-text-secondary\">\n <Loader2 size={16} className=\"animate-spin\" />\n <span className=\"text-sm\">Linking Slack connection...</span>\n </div>\n ) : slackConnectionLoading ? (\n <div className=\"flex items-center gap-2 py-4 text-text-secondary\">\n <Loader2 size={16} className=\"animate-spin\" />\n <span className=\"text-sm\">Checking connection...</span>\n </div>\n ) : slackConnection && slackConnection.dmAllowed ? (\n <div className=\"space-y-4\">\n {/* Connected state */}\n <div className=\"flex items-center gap-3 p-3 rounded-lg bg-bg-sunken\">\n <CheckCircle2 size={20} className=\"text-green-600 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-medium text-sm\">\n {slackConnection.externalDisplayName ||\n slackConnection.externalUsername ||\n slackConnection.externalUserId}\n </p>\n {slackConnection.externalUsername && slackConnection.externalDisplayName && (\n <p className=\"text-xs text-text-secondary\">\n @{slackConnection.externalUsername}\n </p>\n )}\n {slackConnection.connectedAt && (\n <p className=\"text-xs text-text-secondary\">\n Connected {new Date(slackConnection.connectedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n {slackConnection.isTokenExpired && (\n <Badge\n variant=\"outline\"\n className=\"text-xs text-amber-600 border-amber-400\"\n >\n Token expired\n </Badge>\n )}\n </div>\n </div>\n\n {/* Notification toggle */}\n <div className=\"flex items-center justify-between p-3 border border-border-subtle rounded-lg\">\n <div className=\"flex items-center gap-2\">\n {slackConnection.notificationsEnabled ? (\n <Bell size={16} className=\"text-primary\" />\n ) : (\n <BellOff size={16} className=\"text-text-secondary\" />\n )}\n <div>\n <p className=\"text-sm font-medium\">DM Notifications</p>\n <p className=\"text-xs text-text-secondary\">\n {slackConnection.notificationsEnabled\n ? 'You will receive bot DMs'\n : 'DM notifications are paused'}\n </p>\n </div>\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleToggleNotifications}\n isLoading={togglingNotifications}\n >\n {slackConnection.notificationsEnabled ? 'Disable' : 'Enable'}\n </Button>\n </div>\n\n {/* Reconnect (if token expired) or Disconnect */}\n <div className=\"flex gap-2 justify-end pt-2\">\n {slackConnection.isTokenExpired && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Slack size={14} />}\n onClick={handleSlackConnect}\n >\n Reconnect\n </Button>\n )}\n <Button\n variant=\"destructive\"\n size=\"sm\"\n leftIcon={<Unlink size={14} />}\n onClick={handleRevokeSlack}\n isLoading={revoking}\n >\n Disconnect\n </Button>\n </div>\n </div>\n ) : (\n /* Not connected state */\n <div className=\"flex flex-col items-center gap-4 py-8 text-center\">\n <div className=\"p-4 rounded-full bg-bg-sunken\">\n <Slack size={32} className=\"text-text-secondary\" />\n </div>\n <div>\n <p className=\"font-medium\">No personal account connected</p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Connect your Slack account so the bot can send you direct messages\n </p>\n </div>\n <Button leftIcon={<Slack size={16} />} onClick={handleSlackConnect}>\n Connect with Slack\n </Button>\n </div>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Policy Bindings */}\n {connector.defaultPolicyBindings && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Shield size={18} />\n Default Policy Bindings\n </CardTitle>\n <CardDescription>\n Default policies applied to all routes on this connector\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n {Object.entries(connector.defaultPolicyBindings).map(([key, value]) =>\n value ? (\n <div key={key} className=\"p-3 bg-bg-sunken rounded-lg\">\n <p className=\"text-xs text-text-secondary capitalize\">\n {key.replace('PolicyId', '').replace(/([A-Z])/g, ' $1')}\n </p>\n <p className=\"font-medium text-sm truncate\">{String(value)}</p>\n </div>\n ) : null\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Metadata\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(connector.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(connector.updatedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Credentials</p>\n <p className=\"font-medium\">{connector.credentialsRefId || 'Not configured'}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Tags</p>\n <div className=\"flex gap-1\">\n {connector.tags.length > 0 ? (\n connector.tags.map((tag: string) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n ) : (\n <span className=\"text-text-secondary\">None</span>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ChannelDetailPage.js","names":["Textarea","_Fragment","Textarea$1","CHANNEL_TYPES","VISIBILITIES","splitList","value","entry","ChannelIcon","type","Hash","Globe","MessageSquare","Radio","ChannelDetailPage","useParams","useBotlit","searchParams","setSearchParams","useSearchParams","connector","useChannelConnector","isNew","connectorId","routes","refetchRoutes","useChannelRoutes","bots","useBots","createConnector","createConnectorResult","useCreateChannelConnector","updateConnector","updateConnectorResult","useUpdateChannelConnector","deleteConnector","deleteConnectorResult","useDeleteChannelConnector","createRoute","createRouteResult","useCreateChannelRoute","slackChannelId","slackConnection","slackConnectionLoading","refetchSlackConnection","useMyUserPlatformConnection","initiateSlack","useInitiateSlackConnect","linkIntegration","linking","useLinkIntegrationConnection","toggleNotifications","togglingNotifications","useToggleSlackNotifications","revokeConnection","revoking","useRevokeSlackConnection","oauthError","setOauthError","useState","oauthLinkConsumed","useRef","integrationConnectionId","channelId","cleaned","connection","handleSlackConnect","redirectUri","handleToggleNotifications","handleRevokeSlack","isEditing","setIsEditing","showDeleteConfirm","setShowDeleteConfirm","showAddRoute","setShowAddRoute","newRoute","setNewRoute","formData","setFormData","widgetConfig","setWidgetConfig","buildWidgetMetadata","WIDGET_METADATA_KEY","handleCreate","created","toast","navigateTo","err","handleUpdate","handleDelete","isNative","nativeNotify","handleAddRoute","selectedBot","a","startEditing","toUnion","saved","readWidgetConfig","PageLayout","Button","Save","Card","CardHeader","CardTitle","CardContent","FormField","Input","Palette","loading","EmptyState","connectorRoutes","r","connectorType","savedWidgetConfig","ArrowLeft","StatusBadge","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Plus","Fragment","Edit","nativeImpact","Trash2","PagePurpose","NextSteps","Settings","X","bot","GlassCard","Badge","origin","prompt","i","CardDescription","routeMetadataString","route","ExternalLink","Slack","Loader2","CheckCircle2","Bell","BellOff","Unlink","Shield","key","formatRelativeTime","tag"],"sources":["../../../src/botlit/pages/ChannelDetailPage.tsx"],"sourcesContent":["/**\n * Channel Detail Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { useParams, useSearchParams } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Radio,\n MessageSquare,\n Globe,\n Hash,\n Shield,\n Settings,\n Save,\n Plus,\n ExternalLink,\n Palette,\n Edit,\n Trash2,\n X,\n Slack,\n Bell,\n BellOff,\n CheckCircle2,\n Unlink,\n Loader2,\n} from 'lucide-react';\nimport { PagePurpose, NextSteps, 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, Textarea, FormField } from '../components/Input';\nimport { StatusBadge, Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport {\n useChannelConnector,\n useChannelRoutes,\n useCreateChannelConnector,\n useUpdateChannelConnector,\n useDeleteChannelConnector,\n useCreateChannelRoute,\n routeMetadataString,\n useBots,\n useMyUserPlatformConnection,\n useInitiateSlackConnect,\n useLinkIntegrationConnection,\n useToggleSlackNotifications,\n useRevokeSlackConnection,\n} from '../hooks';\nimport { readWidgetConfig, WIDGET_METADATA_KEY } from '../hooks/useChannels';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { toUnion } from '../utils/unions';\nimport type { ChannelType, Visibility } from '../types';\n\n/** Channel types the UI can render icons/labels for. */\nconst CHANNEL_TYPES: ChannelType[] = [\n 'WEB_WIDGET',\n 'SLACK',\n 'TEAMS',\n 'DISCORD',\n 'WHATSAPP',\n 'WEBHOOK',\n 'CUSTOM',\n];\n\nconst VISIBILITIES: Visibility[] = ['PRIVATE', 'WORKSPACE', 'PUBLIC'];\n\n/** Splits a comma-separated form field into a trimmed, non-empty list. */\nfunction splitList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\nimport { toast } from 'sonner';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\ninterface ChannelDetailPageProps {\n isNew?: boolean;\n}\n\nconst ChannelIcon: FC<{ type: ChannelType }> = ({ type }) => {\n switch (type) {\n case 'SLACK':\n return <Hash size={18} />;\n case 'WEB_WIDGET':\n return <Globe size={18} />;\n case 'TEAMS':\n return <MessageSquare size={18} />;\n default:\n return <Radio size={18} />;\n }\n};\n\nexport const ChannelDetailPage: FC<ChannelDetailPageProps> = ({ isNew }) => {\n const { connectorId } = useParams();\n const { navigateTo } = useBotlit();\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: connector, loading } = useChannelConnector(isNew ? undefined : connectorId);\n const { data: routes, refetch: refetchRoutes } = useChannelRoutes(connectorId);\n const { data: bots } = useBots();\n const [createConnector, createConnectorResult] = useCreateChannelConnector();\n const [updateConnector, updateConnectorResult] = useUpdateChannelConnector();\n const [deleteConnector, deleteConnectorResult] = useDeleteChannelConnector();\n const [createRoute, createRouteResult] = useCreateChannelRoute();\n\n // Phase 7: Slack personal account connect\n const slackChannelId =\n connector?.type === 'SLACK' && connector?.credentialsRefId\n ? connector.credentialsRefId\n : undefined;\n const {\n data: slackConnection,\n loading: slackConnectionLoading,\n refetch: refetchSlackConnection,\n } = useMyUserPlatformConnection(slackChannelId);\n const { initiate: initiateSlack } = useInitiateSlackConnect();\n const { link: linkIntegration, loading: linking } = useLinkIntegrationConnection();\n const { toggle: toggleNotifications, loading: togglingNotifications } =\n useToggleSlackNotifications();\n const { revoke: revokeConnection, loading: revoking } = useRevokeSlackConnection();\n const [oauthError, setOauthError] = useState<string | null>(null);\n\n // After integrations OAuth flow: link integration connection to channel\n // URL params: ?integrationConnectionId=<id>&channelId=<id>\n //\n // The ref — not an empty dependency list — is what makes this run once: the\n // params are consumed exactly once per visit, while the effect still declares\n // everything it reads.\n const oauthLinkConsumed = useRef(false);\n useEffect(() => {\n if (oauthLinkConsumed.current) return;\n\n const integrationConnectionId = searchParams.get('integrationConnectionId');\n const channelId = searchParams.get('channelId');\n if (!integrationConnectionId || !channelId) return;\n\n oauthLinkConsumed.current = true;\n\n // Clean the URL immediately so a refresh doesn't re-trigger\n const cleaned = new URLSearchParams(searchParams);\n cleaned.delete('integrationConnectionId');\n cleaned.delete('channelId');\n setSearchParams(cleaned, { replace: true });\n\n setOauthError(null);\n void linkIntegration(integrationConnectionId, channelId).then((connection) => {\n if (connection) {\n void refetchSlackConnection();\n } else {\n setOauthError('Failed to link Slack connection. Please try again.');\n }\n });\n }, [searchParams, setSearchParams, linkIntegration, refetchSlackConnection]);\n\n const handleSlackConnect = () => {\n if (!slackChannelId) return;\n // Slack appends ?code=...&state=... to the redirect_uri we supply\n const redirectUri = `${window.location.origin}${window.location.pathname}`;\n initiateSlack(slackChannelId, redirectUri);\n };\n\n const handleToggleNotifications = async () => {\n if (!slackConnection) return;\n const updated = await toggleNotifications(\n slackConnection.id,\n !slackConnection.notificationsEnabled\n );\n if (updated) {\n await refetchSlackConnection();\n }\n };\n\n const handleRevokeSlack = async () => {\n if (!slackConnection) return;\n const ok = await revokeConnection(slackConnection.id);\n if (ok) {\n await refetchSlackConnection();\n }\n };\n\n const [isEditing, setIsEditing] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [showAddRoute, setShowAddRoute] = useState(false);\n const [newRoute, setNewRoute] = useState({ locationId: '', locationName: '', botId: '' });\n\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n type: 'WEB_WIDGET' as ChannelType,\n visibility: 'PRIVATE' as Visibility,\n credentialsRefId: '',\n });\n\n const [widgetConfig, setWidgetConfig] = useState({\n allowedOrigins: '',\n primaryColor: '#3b82f6',\n fontFamily: 'Inter, sans-serif',\n starterPrompts: '',\n });\n\n /**\n * The connector has no widget column — the appearance settings are stored\n * under `metadata.webWidget`, which is where the detail view reads them back.\n */\n const buildWidgetMetadata = (): Record<string, unknown> | undefined => {\n if (formData.type !== 'WEB_WIDGET') return undefined;\n return {\n [WIDGET_METADATA_KEY]: {\n allowedOrigins: splitList(widgetConfig.allowedOrigins),\n primaryColor: widgetConfig.primaryColor,\n fontFamily: widgetConfig.fontFamily,\n starterPrompts: splitList(widgetConfig.starterPrompts),\n },\n };\n };\n\n const handleCreate = async () => {\n if (!formData.name) return;\n try {\n const created = await createConnector({\n name: formData.name,\n type: formData.type,\n description: formData.description || undefined,\n visibility: formData.visibility,\n credentialsRefId: formData.credentialsRefId || undefined,\n metadata: buildWidgetMetadata(),\n });\n toast.success(`Channel \"${created.name}\" created`);\n navigateTo(`channels/${created.id}`);\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create channel connector');\n }\n };\n\n const handleUpdate = async () => {\n if (!connectorId || !formData.name) return;\n try {\n await updateConnector({\n connectorId,\n input: {\n name: formData.name,\n description: formData.description || undefined,\n visibility: formData.visibility,\n credentialsRefId: formData.credentialsRefId || undefined,\n metadata: buildWidgetMetadata(),\n },\n });\n toast.success('Channel updated');\n setIsEditing(false);\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update channel connector');\n }\n };\n\n const handleDelete = async () => {\n if (!connectorId) return;\n try {\n await deleteConnector(connectorId);\n if (isNative()) void nativeNotify('success');\n navigateTo('channels');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n };\n\n const handleAddRoute = async () => {\n if (!connectorId || !newRoute.locationId || !newRoute.botId) return;\n const selectedBot = bots?.find((a: { id: string; name: string }) => a.id === newRoute.botId);\n try {\n await createRoute({\n connectorId,\n locationId: newRoute.locationId,\n appId: newRoute.botId,\n metadata: {\n locationName: newRoute.locationName || newRoute.locationId,\n appName: selectedBot?.name,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create route');\n return;\n }\n toast.success('Route created');\n void refetchRoutes();\n setNewRoute({ locationId: '', locationName: '', botId: '' });\n setShowAddRoute(false);\n };\n\n const startEditing = () => {\n if (!connector) return;\n setFormData({\n name: connector.name,\n description: connector.description || '',\n type: toUnion(connector.type, CHANNEL_TYPES, 'CUSTOM'),\n visibility: toUnion(connector.visibility, VISIBILITIES, 'PRIVATE'),\n credentialsRefId: connector.credentialsRefId || '',\n });\n const saved = readWidgetConfig(connector);\n if (saved) {\n setWidgetConfig({\n allowedOrigins: saved.allowedOrigins.join(', '),\n primaryColor: saved.primaryColor,\n fontFamily: saved.fontFamily,\n starterPrompts: saved.starterPrompts.join(', '),\n });\n }\n setIsEditing(true);\n };\n\n if (isNew) {\n return (\n <PageLayout\n title=\"Create Channel Connector\"\n description=\"Set up a new channel for your AI agents\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => navigateTo('channels')}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleCreate}\n isLoading={createConnectorResult.loading || updateConnectorResult.loading}\n disabled={!formData.name}\n >\n Create\n </Button>\n </div>\n }\n >\n <div className=\"max-w-2xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Connector Name\" required>\n <Input\n placeholder=\"e.g., Production Web Widget\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What is this channel connector for?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Channel Type\" required>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.type}\n onChange={(e) =>\n setFormData({ ...formData, type: e.target.value as ChannelType })\n }\n >\n <option value=\"WEB_WIDGET\">Web Widget</option>\n <option value=\"SLACK\">Slack</option>\n <option value=\"TEAMS\">Microsoft Teams</option>\n <option value=\"DISCORD\">Discord</option>\n <option value=\"WHATSAPP\">WhatsApp</option>\n <option value=\"WEBHOOK\">Webhook</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </div>\n\n {formData.type !== 'WEB_WIDGET' && (\n <FormField label=\"Credentials Reference\">\n <Input\n placeholder=\"e.g., secret-slack-token\"\n value={formData.credentialsRefId}\n onChange={(e) => setFormData({ ...formData, credentialsRefId: e.target.value })}\n />\n </FormField>\n )}\n </CardContent>\n </Card>\n\n {formData.type === 'WEB_WIDGET' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Palette size={18} />\n Widget Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Allowed Origins\" description=\"Comma-separated list of domains\">\n <Input\n placeholder=\"e.g., https://example.com, https://app.example.com\"\n value={widgetConfig.allowedOrigins}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, allowedOrigins: e.target.value })\n }\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Primary Color\">\n <div className=\"flex gap-2\">\n <input\n type=\"color\"\n value={widgetConfig.primaryColor}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, primaryColor: e.target.value })\n }\n className=\"h-10 w-16 rounded border border-border-default\"\n />\n <Input\n value={widgetConfig.primaryColor}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, primaryColor: e.target.value })\n }\n />\n </div>\n </FormField>\n\n <FormField label=\"Font Family\">\n <Input\n value={widgetConfig.fontFamily}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, fontFamily: e.target.value })\n }\n />\n </FormField>\n </div>\n\n <FormField label=\"Starter Prompts\" description=\"One per line\">\n <Textarea\n placeholder=\"What can you help me with?\"\n value={widgetConfig.starterPrompts}\n onChange={(e) =>\n setWidgetConfig({ ...widgetConfig, starterPrompts: e.target.value })\n }\n rows={3}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n </div>\n </PageLayout>\n );\n }\n\n if (loading) {\n return (\n <PageLayout title=\"Loading...\">\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!connector) {\n return (\n <PageLayout title=\"Connector Not Found\">\n <EmptyState\n illustration=\"empty-notifications\"\n title=\"Connector Not Found\"\n description=\"This channel connector doesn't exist.\"\n action={<Button onClick={() => navigateTo('channels')}>Back to Channels</Button>}\n />\n </PageLayout>\n );\n }\n\n const connectorRoutes =\n routes?.filter((r: { connectorId: string }) => r.connectorId === connector.id) || [];\n const connectorType = toUnion(connector.type, CHANNEL_TYPES, 'CUSTOM');\n const savedWidgetConfig = readWidgetConfig(connector);\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('channels')}>\n <ArrowLeft size={20} />\n </Button>\n <div className=\"p-2 rounded-lg bg-action-primary-bg/10\">\n <ChannelIcon type={connectorType} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{connector.name}</span>\n <StatusBadge status={connector.status} />\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{connector.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button\n variant=\"outline\"\n leftIcon={<Plus size={16} />}\n onClick={() => setShowAddRoute(true)}\n >\n Add Route\n </Button>\n </BotmanorPermissionGate>\n {isEditing ? (\n <>\n <Button variant=\"outline\" onClick={() => setIsEditing(false)}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleUpdate}\n isLoading={updateConnectorResult.loading}\n >\n Save\n </Button>\n </>\n ) : (\n <>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_UPDATE}>\n <Button variant=\"outline\" leftIcon={<Edit size={16} />} onClick={startEditing}>\n Edit\n </Button>\n </BotmanorPermissionGate>\n {showDeleteConfirm ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n isLoading={deleteConnectorResult.loading}\n >\n Confirm\n </Button>\n </div>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n onClick={() => setShowDeleteConfirm(true)}\n >\n Delete\n </Button>\n </BotmanorPermissionGate>\n )}\n </>\n )}\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Radio size={18} />}>\n This connector links BotManor to one messaging platform. From here you add routes — each\n mapping a specific location on the channel (a Slack channel, a widget, a number) to the\n bot that should answer there — tweak the connector&rsquo;s settings, and manage its\n connection. Set up at least one route so messages on this channel reach a bot.\n </PagePurpose>\n\n <NextSteps\n storageKey={`botlit-channel-${connector.id}`}\n steps={[\n {\n id: 'route',\n label: 'Add a route',\n description: 'Point an incoming location on this channel at one of your bots.',\n icon: <Plus size={16} />,\n onClick: () => setShowAddRoute(true),\n done: connectorRoutes.length > 0,\n },\n {\n id: 'edit',\n label: 'Review connector settings',\n description: 'Confirm the name, visibility and channel-specific configuration.',\n icon: <Settings size={16} />,\n onClick: startEditing,\n },\n {\n id: 'bots',\n label: 'Check your bots',\n description: 'Make sure the bot you are routing to is active and configured.',\n icon: <MessageSquare size={16} />,\n onClick: () => navigateTo('bots'),\n },\n ]}\n />\n\n {/* Add Route Modal */}\n {showAddRoute && (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle>Add Route</CardTitle>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setShowAddRoute(false)}>\n <X size={16} />\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Location ID\" required>\n <Input\n placeholder=\"e.g., #general or channel ID\"\n value={newRoute.locationId}\n onChange={(e) => setNewRoute({ ...newRoute, locationId: e.target.value })}\n />\n </FormField>\n <FormField label=\"Location Name\">\n <Input\n placeholder=\"Friendly name (optional)\"\n value={newRoute.locationName}\n onChange={(e) => setNewRoute({ ...newRoute, locationName: e.target.value })}\n />\n </FormField>\n </div>\n <FormField label=\"Connect to Bot\" required>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newRoute.botId}\n onChange={(e) => setNewRoute({ ...newRoute, botId: e.target.value })}\n >\n <option value=\"\">Select a bot...</option>\n {bots?.map((bot: { id: string; name: string }) => (\n <option key={bot.id} value={bot.id}>\n {bot.name}\n </option>\n ))}\n </select>\n </FormField>\n <div className=\"flex justify-end gap-2\">\n <Button variant=\"outline\" onClick={() => setShowAddRoute(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleAddRoute}\n isLoading={createRouteResult.loading}\n disabled={!newRoute.locationId || !newRoute.botId}\n >\n Add Route\n </Button>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Edit Form */}\n {isEditing && (\n <Card>\n <CardHeader>\n <CardTitle>Edit Channel</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Connector Name\" required>\n <Input\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={2}\n />\n </FormField>\n <FormField label=\"Visibility\">\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {/* Overview Cards */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <div className=\"p-3 rounded-full bg-action-primary-bg/10 w-fit mx-auto mb-2\">\n <ChannelIcon type={connectorType} />\n </div>\n <p className=\"text-lg font-bold capitalize\">\n {connector.type.toLowerCase().replace('_', ' ')}\n </p>\n <p className=\"text-sm text-text-secondary\">Channel Type</p>\n </CardContent>\n </Card>\n <GlassCard treatment=\"glass\" glow className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {connectorRoutes.length}\n </p>\n <p className=\"text-sm text-text-secondary\">Active Routes</p>\n </GlassCard>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary capitalize\">\n {connector.visibility.toLowerCase()}\n </p>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{connector.revision}</p>\n <p className=\"text-sm text-text-secondary\">Revision</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Web Widget Configuration */}\n {savedWidgetConfig && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Palette size={18} />\n Widget Configuration\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-6\">\n <div>\n <p className=\"text-sm text-text-secondary\">Allowed Origins</p>\n {savedWidgetConfig.allowedOrigins.length > 0 ? (\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {savedWidgetConfig.allowedOrigins.map((origin) => (\n <Badge key={origin} variant=\"outline\" className=\"font-mono text-xs\">\n {origin}\n </Badge>\n ))}\n </div>\n ) : (\n <p className=\"font-medium\">Any origin</p>\n )}\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Theme</p>\n <div className=\"flex items-center gap-2 mt-1\">\n <div\n className=\"w-6 h-6 rounded border border-border-subtle\"\n style={{ backgroundColor: savedWidgetConfig.primaryColor }}\n />\n <span className=\"font-mono text-sm\">{savedWidgetConfig.primaryColor}</span>\n </div>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Font Family</p>\n <p className=\"font-medium\">{savedWidgetConfig.fontFamily}</p>\n </div>\n </div>\n {savedWidgetConfig.starterPrompts.length > 0 && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <p className=\"text-sm text-text-secondary mb-2\">Starter Prompts</p>\n <div className=\"flex flex-wrap gap-2\">\n {savedWidgetConfig.starterPrompts.map((prompt, i) => (\n <Badge key={i} variant=\"secondary\">\n {prompt}\n </Badge>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Routes */}\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>Routes</CardTitle>\n <CardDescription>Routes connect this channel to your bots</CardDescription>\n </div>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Plus size={14} />}\n onClick={() => setShowAddRoute(true)}\n >\n Add Route\n </Button>\n </BotmanorPermissionGate>\n </CardHeader>\n <CardContent>\n {connectorRoutes.length > 0 ? (\n <div className=\"space-y-3\">\n {connectorRoutes.map(\n (route: {\n id: string;\n locationId: string;\n appId: string;\n revision: number;\n metadata?: Record<string, unknown> | null;\n }) => (\n <div\n key={route.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 rounded-lg bg-bg-sunken\">\n <MessageSquare size={18} className=\"text-text-secondary\" />\n </div>\n <div>\n <p className=\"font-medium\">\n {routeMetadataString(route, 'locationName') ?? route.locationId}\n </p>\n <p className=\"text-sm text-text-secondary\">\n Connected to: {routeMetadataString(route, 'appName') ?? route.appId}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">Rev {route.revision}</Badge>\n <Button variant=\"ghost\" size=\"sm\">\n <ExternalLink size={14} />\n </Button>\n </div>\n </div>\n )\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No routes configured\"\n description=\"Add a route to connect this channel to a bot.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddRoute(true)}>\n Add Route\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </CardContent>\n </Card>\n\n {/* Slack Personal Account Connect (Phase 7) */}\n {connector.type === 'SLACK' && connector.credentialsRefId && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Slack size={18} />\n Your Slack Account\n </CardTitle>\n <CardDescription>\n Connect your personal Slack account to receive direct messages from this bot\n </CardDescription>\n </CardHeader>\n <CardContent>\n {/* OAuth error banner */}\n {oauthError && (\n <div className=\"mb-4 flex items-start gap-2 rounded-lg border border-status-error-border/40 bg-status-error-bg/10 px-3 py-2 text-sm text-status-error-text\">\n <span>{oauthError}</span>\n <button\n onClick={() => setOauthError(null)}\n className=\"ml-auto cursor-pointer text-status-error-text/70 hover:text-status-error-text\"\n >\n <X size={14} />\n </button>\n </div>\n )}\n\n {/* Linking integration connection */}\n {linking ? (\n <div className=\"flex items-center gap-2 py-4 text-text-secondary\">\n <Loader2 size={16} className=\"animate-spin\" />\n <span className=\"text-sm\">Linking Slack connection...</span>\n </div>\n ) : slackConnectionLoading ? (\n <div className=\"flex items-center gap-2 py-4 text-text-secondary\">\n <Loader2 size={16} className=\"animate-spin\" />\n <span className=\"text-sm\">Checking connection...</span>\n </div>\n ) : slackConnection && slackConnection.dmAllowed ? (\n <div className=\"space-y-4\">\n {/* Connected state */}\n <div className=\"flex items-center gap-3 p-3 rounded-lg bg-bg-sunken\">\n <CheckCircle2 size={20} className=\"text-status-success-text shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-medium text-sm\">\n {slackConnection.externalDisplayName ||\n slackConnection.externalUsername ||\n slackConnection.externalUserId}\n </p>\n {slackConnection.externalUsername && slackConnection.externalDisplayName && (\n <p className=\"text-xs text-text-secondary\">\n @{slackConnection.externalUsername}\n </p>\n )}\n {slackConnection.connectedAt && (\n <p className=\"text-xs text-text-secondary\">\n Connected {new Date(slackConnection.connectedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n {slackConnection.isTokenExpired && (\n <Badge\n variant=\"outline\"\n className=\"text-xs text-status-warning-text border-status-warning-border\"\n >\n Token expired\n </Badge>\n )}\n </div>\n </div>\n\n {/* Notification toggle */}\n <div className=\"flex items-center justify-between p-3 border border-border-subtle rounded-lg\">\n <div className=\"flex items-center gap-2\">\n {slackConnection.notificationsEnabled ? (\n <Bell size={16} className=\"text-primary\" />\n ) : (\n <BellOff size={16} className=\"text-text-secondary\" />\n )}\n <div>\n <p className=\"text-sm font-medium\">DM Notifications</p>\n <p className=\"text-xs text-text-secondary\">\n {slackConnection.notificationsEnabled\n ? 'You will receive bot DMs'\n : 'DM notifications are paused'}\n </p>\n </div>\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleToggleNotifications}\n isLoading={togglingNotifications}\n >\n {slackConnection.notificationsEnabled ? 'Disable' : 'Enable'}\n </Button>\n </div>\n\n {/* Reconnect (if token expired) or Disconnect */}\n <div className=\"flex gap-2 justify-end pt-2\">\n {slackConnection.isTokenExpired && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n leftIcon={<Slack size={14} />}\n onClick={handleSlackConnect}\n >\n Reconnect\n </Button>\n )}\n <Button\n variant=\"destructive\"\n size=\"sm\"\n leftIcon={<Unlink size={14} />}\n onClick={handleRevokeSlack}\n isLoading={revoking}\n >\n Disconnect\n </Button>\n </div>\n </div>\n ) : (\n /* Not connected state */\n <div className=\"flex flex-col items-center gap-4 py-8 text-center\">\n <div className=\"p-4 rounded-full bg-bg-sunken\">\n <Slack size={32} className=\"text-text-secondary\" />\n </div>\n <div>\n <p className=\"font-medium\">No personal account connected</p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Connect your Slack account so the bot can send you direct messages\n </p>\n </div>\n <Button leftIcon={<Slack size={16} />} onClick={handleSlackConnect}>\n Connect with Slack\n </Button>\n </div>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Policy Bindings */}\n {connector.defaultPolicyBindings && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Shield size={18} />\n Default Policy Bindings\n </CardTitle>\n <CardDescription>\n Default policies applied to all routes on this connector\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n {Object.entries(connector.defaultPolicyBindings).map(([key, value]) =>\n value ? (\n <div key={key} className=\"p-3 bg-bg-sunken rounded-lg\">\n <p className=\"text-xs text-text-secondary capitalize\">\n {key.replace('PolicyId', '').replace(/([A-Z])/g, ' $1')}\n </p>\n <p className=\"font-medium text-sm truncate\">{String(value)}</p>\n </div>\n ) : null\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Metadata\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(connector.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(connector.updatedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Credentials</p>\n <p className=\"font-medium\">{connector.credentialsRefId || 'Not configured'}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Tags</p>\n <div className=\"flex gap-1\">\n {connector.tags.length > 0 ? (\n connector.tags.map((tag: string) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n ) : (\n <span className=\"text-text-secondary\">None</span>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA4DA,IAAMG,IAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEMC,KAA6B;CAAC;CAAW;CAAa;AAAQ;AAGpE,SAASC,GAAU,GAAyB;CAC1C,OAAOC,EACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAUC,EAAM,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;AACnB;AAQA,IAAMC,MAA0C,EAAE,cAAW;CAC3D,QAAQC,GAAR;EACE,KAAK,SACH,OAAO,kBAACC,GAAD,EAAM,MAAM,GAAK,CAAA;EAC1B,KAAK,cACH,OAAO,kBAACC,GAAD,EAAO,MAAM,GAAK,CAAA;EAC3B,KAAK,SACH,OAAO,kBAACC,GAAD,EAAe,MAAM,GAAK,CAAA;EACnC,SACE,OAAO,kBAACC,GAAD,EAAO,MAAM,GAAK,CAAA;CAC7B;AACF,GAEaC,KAAiD,EAAE,eAAY;CAC1E,IAAM,EAAE,mBAAgBC,GAAU,GAC5B,EAAE,kBAAeC,EAAU,GAC3B,CAACC,GAAcC,MAAmBC,GAAgB,GAClD,EAAE,MAAMC,GAAW,gBAAYC,GAAoBC,IAAQ,KAAA,IAAYC,CAAW,GAClF,EAAE,MAAMC,IAAQ,SAASC,OAAkBC,GAAiBH,CAAW,GACvE,EAAE,MAAMI,OAASC,EAAQ,GACzB,CAACC,IAAiBC,MAAyBC,GAA0B,GACrE,CAACC,IAAiBC,MAAyBC,GAA0B,GACrE,CAACC,IAAiBC,MAAyBC,GAA0B,GACrE,CAACC,IAAaC,MAAqBC,GAAsB,GAGzDC,IACJrB,GAAW,SAAS,WAAWA,GAAW,mBACtCA,EAAU,mBACV,KAAA,GACA,EACJ,MAAMsB,GACN,SAASC,IACT,SAASC,MACPC,GAA4BJ,CAAc,GACxC,EAAE,UAAUK,OAAkBC,GAAwB,GACtD,EAAE,MAAMC,IAAiB,SAASC,OAAYC,GAA6B,GAC3E,EAAE,QAAQC,IAAqB,SAASC,OAC5CC,GAA4B,GACxB,EAAE,QAAQC,IAAkB,SAASC,OAAaC,GAAyB,GAC3E,CAACC,IAAYC,KAAiBC,EAAwB,IAAI,GAQ1DC,KAAoBC,GAAO,EAAK;CACtC,SAAgB;EACd,IAAID,GAAkB,SAAS;EAE/B,IAAME,IAA0B7C,EAAa,IAAI,yBAAyB,GACpE8C,IAAY9C,EAAa,IAAI,WAAW;EAC9C,IAAI,CAAC6C,KAA2B,CAACC,GAAW;EAE5C,GAAkB,UAAU;EAG5B,IAAMC,IAAU,IAAI,gBAAgB/C,CAAY;EAMhD,AALA+C,EAAQ,OAAO,yBAAyB,GACxCA,EAAQ,OAAO,WAAW,GAC1B9C,GAAgB8C,GAAS,EAAE,SAAS,GAAK,CAAC,GAE1CN,EAAc,IAAI,GAClBV,GAAqBc,GAAyBC,CAAS,CAAC,CAAC,MAAM,MAAe;GAC5E,AAAIE,IACFrB,EAA4B,IAE5Bc,EAAc,oDAAoD;EAEtE,CAAC;CACH,GAAG;EAACzC;EAAcC;EAAiB8B;EAAiBJ;CAAsB,CAAC;CAE3E,IAAMsB,WAA2B;EAC/B,IAAI,CAACzB,GAAgB;EAErB,IAAM0B,IAAc,GAAG,OAAO,SAAS,SAAS,OAAO,SAAS;EAChE,GAAc1B,GAAgB0B,CAAW;CAC3C,GAEMC,KAA4B,YAAY;EAC5C,AAAK1B,KAKD,MAJkBS,GACpBT,EAAgB,IAChB,CAACA,EAAgB,oBACnB,KAEE,MAAME,EAAuB;CAEjC,GAEMyB,KAAoB,YAAY;EACpC,AAAK3B,KAED,MADaY,GAAiBZ,EAAgB,EAAE,KAElD,MAAME,EAAuB;CAEjC,GAEM,CAAC0B,GAAWC,KAAgBZ,EAAS,EAAK,GAC1C,CAACa,IAAmBC,MAAwBd,EAAS,EAAK,GAC1D,CAACe,IAAcC,KAAmBhB,EAAS,EAAK,GAChD,CAACiB,GAAUC,KAAelB,EAAS;EAAE,YAAY;EAAI,cAAc;EAAI,OAAO;CAAG,CAAC,GAElF,CAACmB,GAAUC,KAAepB,EAAS;EACvC,MAAM;EACN,aAAa;EACb,MAAM;EACN,YAAY;EACZ,kBAAkB;CACpB,CAAC,GAEK,CAACqB,GAAcC,KAAmBtB,EAAS;EAC/C,gBAAgB;EAChB,cAAc;EACd,YAAY;EACZ,gBAAgB;CAClB,CAAC,GAMKuB,WAAiE;EACrE,IAAIJ,EAAS,SAAS,cACtB,OAAO,GACJK,KAAsB;GACrB,gBAAgB9E,GAAU2E,EAAa,cAAc;GACrD,cAAcA,EAAa;GAC3B,YAAYA,EAAa;GACzB,gBAAgB3E,GAAU2E,EAAa,cAAc;EACvD,EACF;CACF,GAEMI,KAAe,YAAY;EAC/B,IAAKN,EAAS,MACd,IAAI;GACF,IAAMO,IAAU,MAAMxD,GAAgB;IACpC,MAAMiD,EAAS;IACf,MAAMA,EAAS;IACf,aAAaA,EAAS,eAAe,KAAA;IACrC,YAAYA,EAAS;IACrB,kBAAkBA,EAAS,oBAAoB,KAAA;IAC/C,UAAUI,GAAoB;GAChC,CAAC;GAED,AADAI,EAAM,QAAQ,YAAYD,EAAQ,KAAK,UAAU,GACjDE,EAAW,YAAYF,EAAQ,IAAI;EACrC,SAASG,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,oCAAoC;EACvF;CACF,GAEMC,KAAe,YAAY;EAC/B,IAAKlE,KAAgBuD,EAAS,MAC9B,IAAI;GAYF,AAXA,MAAM9C,GAAgB;IACpB;IACA,OAAO;KACL,MAAM8C,EAAS;KACf,aAAaA,EAAS,eAAe,KAAA;KACrC,YAAYA,EAAS;KACrB,kBAAkBA,EAAS,oBAAoB,KAAA;KAC/C,UAAUI,GAAoB;IAChC;GACF,CAAC,GACDI,EAAM,QAAQ,iBAAiB,GAC/Bf,EAAa,EAAK;EACpB,SAASiB,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,oCAAoC;EACvF;CACF,GAEME,KAAe,YAAY;EAC/B,IAAKnE,GACL,IAAI;GAGF,AAFA,MAAMY,GAAgBZ,CAAW,GAC7BoE,EAAS,KAAGC,GAAkB,SAAS,GAC3CL,EAAW,UAAU;EACvB,SAASC,GAAK;GAEZ,MADIG,EAAS,KAAGC,GAAkB,OAAO,GACnCJ;EACR;CACF,GAEMK,KAAiB,YAAY;EACjC,IAAI,CAACtE,KAAe,CAACqD,EAAS,cAAc,CAACA,EAAS,OAAO;EAC7D,IAAMkB,IAAcnE,IAAM,MAAM,MAAoCoE,EAAE,OAAOnB,EAAS,KAAK;EAC3F,IAAI;GACF,MAAMtC,GAAY;IAChB;IACA,YAAYsC,EAAS;IACrB,OAAOA,EAAS;IAChB,UAAU;KACR,cAAcA,EAAS,gBAAgBA,EAAS;KAChD,SAASkB,GAAa;IACxB;GACF,CAAC;EACH,SAASN,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,wBAAwB;GACzE;EACF;EAIA,AAHAF,EAAM,QAAQ,eAAe,GAC7B7D,GAAmB,GACnBoD,EAAY;GAAE,YAAY;GAAI,cAAc;GAAI,OAAO;EAAG,CAAC,GAC3DF,EAAgB,EAAK;CACvB,GAEMqB,WAAqB;EACzB,IAAI,CAAC5E,GAAW;EAChB,EAAY;GACV,MAAMA,EAAU;GAChB,aAAaA,EAAU,eAAe;GACtC,MAAM6E,EAAQ7E,EAAU,MAAMjB,GAAe,QAAQ;GACrD,YAAY8F,EAAQ7E,EAAU,YAAYhB,IAAc,SAAS;GACjE,kBAAkBgB,EAAU,oBAAoB;EAClD,CAAC;EACD,IAAM8E,IAAQC,EAAiB/E,CAAS;EASxC,AARI8E,KACFjB,EAAgB;GACd,gBAAgBiB,EAAM,eAAe,KAAK,IAAI;GAC9C,cAAcA,EAAM;GACpB,YAAYA,EAAM;GAClB,gBAAgBA,EAAM,eAAe,KAAK,IAAI;EAChD,CAAC,GAEH3B,EAAa,EAAI;CACnB;CAEA,IAAIjD,GACF,OACE,kBAAC8E,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAACC,GAAD;IAAQ,SAAQ;IAAU,eAAed,EAAW,UAAU;IAAG,UAAA;GAEzD,CAAA,GACR,kBAACc,GAAD;IACE,UAAU,kBAACC,GAAD,EAAM,MAAM,GAAK,CAAA;IAC3B,SAASlB;IACT,WAAWtD,GAAsB,WAAWG,GAAsB;IAClE,UAAU,CAAC6C,EAAS;IACrB,UAAA;GAEO,CAAA,CACL;;EAGP,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAACyB,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD,EAAA,UAAW,oBAA4B,CAAA,EAC7B,CAAA,GACZ,kBAACC,GAAD;IAAa,WAAU;IAAvB,UAAA;KACE,kBAACC,GAAD;MAAW,OAAM;MAAiB,UAAA;MAChC,UAAA,kBAACC,GAAD;OACE,aAAY;OACZ,OAAO9B,EAAS;OAChB,WAAW,MAAMC,EAAY;QAAE,GAAGD;QAAU,MAAM,EAAE,OAAO;OAAM,CAAC;MACnE,CAAA;KACQ,CAAA;KAEX,kBAAC6B,GAAD;MAAW,OAAM;MACf,UAAA,kBAAC3G,GAAD;OACE,aAAY;OACZ,OAAO8E,EAAS;OAChB,WAAW,MAAMC,EAAY;QAAE,GAAGD;QAAU,aAAa,EAAE,OAAO;OAAM,CAAC;OACzE,MAAM;MACP,CAAA;KACQ,CAAA;KAEX,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC6B,GAAD;OAAW,OAAM;OAAe,UAAA;OAC9B,UAAA,kBAAC,UAAD;QACE,WAAU;QACV,OAAO7B,EAAS;QAChB,WAAW,MACTC,EAAY;SAAE,GAAGD;SAAU,MAAM,EAAE,OAAO;QAAqB,CAAC;QAJpE,UAAA;SAOE,kBAAC,UAAD;UAAQ,OAAM;UAAa,UAAA;SAAkB,CAAA;SAC7C,kBAAC,UAAD;UAAQ,OAAM;UAAQ,UAAA;SAAa,CAAA;SACnC,kBAAC,UAAD;UAAQ,OAAM;UAAQ,UAAA;SAAuB,CAAA;SAC7C,kBAAC,UAAD;UAAQ,OAAM;UAAU,UAAA;SAAe,CAAA;SACvC,kBAAC,UAAD;UAAQ,OAAM;UAAW,UAAA;SAAgB,CAAA;SACzC,kBAAC,UAAD;UAAQ,OAAM;UAAU,UAAA;SAAe,CAAA;SACvC,kBAAC,UAAD;UAAQ,OAAM;UAAS,UAAA;SAAc,CAAA;QAC/B;;MACC,CAAA,GAEX,kBAAC6B,GAAD;OAAW,OAAM;OACf,UAAA,kBAAC,UAAD;QACE,WAAU;QACV,OAAO7B,EAAS;QAChB,WAAW,MACTC,EAAY;SAAE,GAAGD;SAAU,YAAY,EAAE,OAAO;QAAoB,CAAC;QAJzE,UAAA;SAOE,kBAAC,UAAD;UAAQ,OAAM;UAAU,UAAA;SAAe,CAAA;SACvC,kBAAC,UAAD;UAAQ,OAAM;UAAY,UAAA;SAAiB,CAAA;SAC3C,kBAAC,UAAD;UAAQ,OAAM;UAAS,UAAA;SAAc,CAAA;QAC/B;;MACC,CAAA,CACR;;KAEJA,EAAS,SAAS,gBACjB,kBAAC6B,GAAD;MAAW,OAAM;MACf,UAAA,kBAACC,GAAD;OACE,aAAY;OACZ,OAAO9B,EAAS;OAChB,WAAW,MAAMC,EAAY;QAAE,GAAGD;QAAU,kBAAkB,EAAE,OAAO;OAAM,CAAC;MAC/E,CAAA;KACQ,CAAA;IAEF;GACT,CAAA,CAAA,EAAA,CAAA,GAELA,EAAS,SAAS,gBACjB,kBAACyB,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD;IAAW,WAAU;IAArB,UAAA,CACE,kBAACI,GAAD,EAAS,MAAM,GAAK,CAAA,GAAC,sBAEZ;GACD,CAAA,EAAA,CAAA,GACZ,kBAACH,GAAD;IAAa,WAAU;IAAvB,UAAA;KACE,kBAACC,GAAD;MAAW,OAAM;MAAkB,aAAY;MAC7C,UAAA,kBAACC,GAAD;OACE,aAAY;OACZ,OAAO5B,EAAa;OACpB,WAAW,MACTC,EAAgB;QAAE,GAAGD;QAAc,gBAAgB,EAAE,OAAO;OAAM,CAAC;MAEtE,CAAA;KACQ,CAAA;KAEX,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC2B,GAAD;OAAW,OAAM;OACf,UAAA,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAAC,SAAD;SACE,MAAK;SACL,OAAO3B,EAAa;SACpB,WAAW,MACTC,EAAgB;UAAE,GAAGD;UAAc,cAAc,EAAE,OAAO;SAAM,CAAC;SAEnE,WAAU;QACX,CAAA,GACD,kBAAC4B,GAAD;SACE,OAAO5B,EAAa;SACpB,WAAW,MACTC,EAAgB;UAAE,GAAGD;UAAc,cAAc,EAAE,OAAO;SAAM,CAAC;QAEpE,CAAA,CACE;;MACI,CAAA,GAEX,kBAAC2B,GAAD;OAAW,OAAM;OACf,UAAA,kBAACC,GAAD;QACE,OAAO5B,EAAa;QACpB,WAAW,MACTC,EAAgB;SAAE,GAAGD;SAAc,YAAY,EAAE,OAAO;QAAM,CAAC;OAElE,CAAA;MACQ,CAAA,CACR;;KAEL,kBAAC2B,GAAD;MAAW,OAAM;MAAkB,aAAY;MAC7C,UAAA,kBAAC3G,GAAD;OACE,aAAY;OACZ,OAAOgF,EAAa;OACpB,WAAW,MACTC,EAAgB;QAAE,GAAGD;QAAc,gBAAgB,EAAE,OAAO;OAAM,CAAC;OAErE,MAAM;MACP,CAAA;KACQ,CAAA;IACA;GACT,CAAA,CAAA,EAAA,CAAA,CAEL;;CACK,CAAA;CAIhB,IAAI8B,IACF,OACE,kBAACV,GAAD;EAAY,OAAM;EAChB,UAAA,kBAAC,OAAD,EAAK,WAAU,8DAA+D,CAAA;CACpE,CAAA;CAIhB,IAAI,CAAChF,GACH,OACE,kBAACgF,GAAD;EAAY,OAAM;EAChB,UAAA,kBAACW,IAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,QAAQ,kBAACV,GAAD;IAAQ,eAAed,EAAW,UAAU;IAAG,UAAA;GAAwB,CAAA;EAChF,CAAA;CACS,CAAA;CAIhB,IAAMyB,IACJxF,IAAQ,QAAQ,MAA+ByF,EAAE,gBAAgB7F,EAAU,EAAE,KAAK,CAAC,GAC/E8F,IAAgBjB,EAAQ7E,EAAU,MAAMjB,GAAe,QAAQ,GAC/DgH,IAAoBhB,EAAiB/E,CAAS;CAEpD,OACE,kBAACgF,GAAD;EACE,OACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAACC,GAAD;KAAQ,SAAQ;KAAQ,MAAK;KAAO,eAAed,EAAW,UAAU;KACtE,UAAA,kBAAC6B,IAAD,EAAW,MAAM,GAAK,CAAA;IAChB,CAAA;IACR,kBAAC,OAAD;KAAK,WAAU;KACb,UAAA,kBAAC5G,IAAD,EAAa,MAAM0G,EAAgB,CAAA;IAChC,CAAA;IACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,QAAD,EAAA,UAAO9F,EAAU,KAAW,CAAA,GAC5B,kBAACiG,IAAD,EAAa,QAAQjG,EAAU,OAAS,CAAA,CACrC;IACL,CAAA,GAAA,kBAAC,KAAD;KAAG,WAAU;KAA2C,UAAAA,EAAU;IAAe,CAAA,CAC9E,EAAA,CAAA;GACF;;EAEP,SACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAACkG,GAAD;IAAwB,YAAYC,EAAqB;IACvD,UAAA,kBAAClB,GAAD;KACE,SAAQ;KACR,UAAU,kBAACmB,GAAD,EAAM,MAAM,GAAK,CAAA;KAC3B,eAAe7C,EAAgB,EAAI;KACpC,UAAA;IAEO,CAAA;GACc,CAAA,GACvBL,IACC,kBAAArE,IAAA,EAAA,UAAA,CACE,kBAACoG,GAAD;IAAQ,SAAQ;IAAU,eAAe9B,EAAa,EAAK;IAAG,UAAA;GAEtD,CAAA,GACR,kBAAC8B,GAAD;IACE,UAAU,kBAACC,GAAD,EAAM,MAAM,GAAK,CAAA;IAC3B,SAASb;IACT,WAAWxD,GAAsB;IAClC,UAAA;GAEO,CAAA,CACR,EAAA,CAAA,IAEF,kBAAAhC,IAAA,EAAA,UAAA,CACE,kBAACqH,GAAD;IAAwB,YAAYC,EAAqB;IACvD,UAAA,kBAAClB,GAAD;KAAQ,SAAQ;KAAU,UAAU,kBAACqB,IAAD,EAAM,MAAM,GAAK,CAAA;KAAG,SAAS1B;KAAc,UAAA;IAEvE,CAAA;GACc,CAAA,GACvBxB,KACC,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC6B,GAAD;KAAQ,SAAQ;KAAU,MAAK;KAAK,eAAe5B,GAAqB,EAAK;KAAG,UAAA;IAExE,CAAA,GACR,kBAAC4B,GAAD;KACE,SAAQ;KACR,MAAK;KACL,eAAe;MAEb,AADAsB,GAAa,QAAQ,GACrBjC,GAAkB;KACpB;KACA,WAAWtD,GAAsB;KAClC,UAAA;IAEO,CAAA,CACL;GAEL,CAAA,IAAA,kBAACkF,GAAD;IAAwB,YAAYC,EAAqB;IACvD,UAAA,kBAAClB,GAAD;KACE,SAAQ;KACR,UAAU,kBAACuB,IAAD,EAAQ,MAAM,GAAK,CAAA;KAC7B,eAAenD,GAAqB,EAAI;KACzC,UAAA;IAEO,CAAA;GACc,CAAA,CAE1B,EAAA,CAAA,CAED;;EAGP,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAACoD,IAAD;KAAa,MAAM,kBAAChH,GAAD,EAAO,MAAM,GAAK,CAAA;KAAG,UAAA;IAK3B,CAAA;IAEb,kBAACiH,IAAD;KACE,YAAY,kBAAkB1G,EAAU;KACxC,OAAO;MACL;OACE,IAAI;OACJ,OAAO;OACP,aAAa;OACb,MAAM,kBAACoG,GAAD,EAAM,MAAM,GAAK,CAAA;OACvB,eAAe7C,EAAgB,EAAI;OACnC,MAAMqC,EAAgB,SAAS;MACjC;MACA;OACE,IAAI;OACJ,OAAO;OACP,aAAa;OACb,MAAM,kBAACe,GAAD,EAAU,MAAM,GAAK,CAAA;OAC3B,SAAS/B;MACX;MACA;OACE,IAAI;OACJ,OAAO;OACP,aAAa;OACb,MAAM,kBAACpF,GAAD,EAAe,MAAM,GAAK,CAAA;OAChC,eAAe2E,EAAW,MAAM;MAClC;KACF;IACD,CAAA;IAGAb,MACC,kBAAC6B,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;KAAY,WAAU;KAAtB,UAAA,CACE,kBAACC,GAAD,EAAA,UAAW,YAAoB,CAAA,GAC/B,kBAACJ,GAAD;MAAQ,SAAQ;MAAQ,MAAK;MAAO,eAAe1B,EAAgB,EAAK;MACtE,UAAA,kBAACqD,GAAD,EAAG,MAAM,GAAK,CAAA;KACR,CAAA,CACE;IACZ,CAAA,GAAA,kBAACtB,GAAD;KAAa,WAAU;KAAvB,UAAA;MACE,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAACC,GAAD;QAAW,OAAM;QAAc,UAAA;QAC7B,UAAA,kBAACC,GAAD;SACE,aAAY;SACZ,OAAOhC,EAAS;SAChB,WAAW,MAAMC,EAAY;UAAE,GAAGD;UAAU,YAAY,EAAE,OAAO;SAAM,CAAC;QACzE,CAAA;OACQ,CAAA,GACX,kBAAC+B,GAAD;QAAW,OAAM;QACf,UAAA,kBAACC,GAAD;SACE,aAAY;SACZ,OAAOhC,EAAS;SAChB,WAAW,MAAMC,EAAY;UAAE,GAAGD;UAAU,cAAc,EAAE,OAAO;SAAM,CAAC;QAC3E,CAAA;OACQ,CAAA,CACR;;MACL,kBAAC+B,GAAD;OAAW,OAAM;OAAiB,UAAA;OAChC,UAAA,kBAAC,UAAD;QACE,WAAU;QACV,OAAO/B,EAAS;QAChB,WAAW,MAAMC,EAAY;SAAE,GAAGD;SAAU,OAAO,EAAE,OAAO;QAAM,CAAC;QAHrE,UAAA,CAKE,kBAAC,UAAD;SAAQ,OAAM;SAAG,UAAA;QAAuB,CAAA,GACvCjD,IAAM,KAAK,MACV,kBAAC,UAAD;SAAqB,OAAOsG,EAAI;SAC7B,UAAAA,EAAI;QACC,GAFKA,EAAI,EAET,CACT,CACK;;MACC,CAAA;MACX,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC5B,GAAD;QAAQ,SAAQ;QAAU,eAAe1B,EAAgB,EAAK;QAAG,UAAA;OAEzD,CAAA,GACR,kBAAC0B,GAAD;QACE,SAASR;QACT,WAAWtD,GAAkB;QAC7B,UAAU,CAACqC,EAAS,cAAc,CAACA,EAAS;QAC7C,UAAA;OAEO,CAAA,CACL;;KACM;IACT,CAAA,CAAA,EAAA,CAAA;IAIPN,KACC,kBAACiC,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD,EAAA,UAAW,eAAuB,CAAA,EACxB,CAAA,GACZ,kBAACC,GAAD;KAAa,WAAU;KAAvB,UAAA;MACE,kBAACC,GAAD;OAAW,OAAM;OAAiB,UAAA;OAChC,UAAA,kBAACC,GAAD;QACE,OAAO9B,EAAS;QAChB,WAAW,MAAMC,EAAY;SAAE,GAAGD;SAAU,MAAM,EAAE,OAAO;QAAM,CAAC;OACnE,CAAA;MACQ,CAAA;MACX,kBAAC6B,GAAD;OAAW,OAAM;OACf,UAAA,kBAAC3G,GAAD;QACE,OAAO8E,EAAS;QAChB,WAAW,MAAMC,EAAY;SAAE,GAAGD;SAAU,aAAa,EAAE,OAAO;QAAM,CAAC;QACzE,MAAM;OACP,CAAA;MACQ,CAAA;MACX,kBAAC6B,GAAD;OAAW,OAAM;OACf,UAAA,kBAAC,UAAD;QACE,WAAU;QACV,OAAO7B,EAAS;QAChB,WAAW,MACTC,EAAY;SAAE,GAAGD;SAAU,YAAY,EAAE,OAAO;QAAoB,CAAC;QAJzE,UAAA;SAOE,kBAAC,UAAD;UAAQ,OAAM;UAAU,UAAA;SAAe,CAAA;SACvC,kBAAC,UAAD;UAAQ,OAAM;UAAY,UAAA;SAAiB,CAAA;SAC3C,kBAAC,UAAD;UAAQ,OAAM;UAAS,UAAA;SAAc,CAAA;QAC/B;;MACC,CAAA;KACA;IACT,CAAA,CAAA,EAAA,CAAA;IAIR,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAACyB,GAAD,EAAA,UACE,kBAACG,GAAD;OAAa,WAAU;OAAvB,UAAA;QACE,kBAAC,OAAD;SAAK,WAAU;SACb,UAAA,kBAAClG,IAAD,EAAa,MAAM0G,EAAgB,CAAA;QAChC,CAAA;QACL,kBAAC,KAAD;SAAG,WAAU;SACV,UAAA9F,EAAU,KAAK,YAAY,CAAC,CAAC,QAAQ,KAAK,GAAG;QAC7C,CAAA;QACH,kBAAC,KAAD;SAAG,WAAU;SAA8B,UAAA;QAAe,CAAA;OAC/C;MACT,CAAA,EAAA,CAAA;MACN,kBAAC8G,IAAD;OAAW,WAAU;OAAQ,MAAA;OAAK,WAAU;OAA5C,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAAlB,EAAgB;OAChB,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAgB,CAAA,CAClD;;MACX,kBAACT,GAAD,EAAA,UACE,kBAACG,GAAD;OAAa,WAAU;OAAvB,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAAtF,EAAU,WAAW,YAAY;OACjC,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAa,CAAA,CAC7C;MACT,CAAA,EAAA,CAAA;MACN,kBAACmF,GAAD,EAAA,UACE,kBAACG,GAAD;OAAa,WAAU;OAAvB,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QAAwC,UAAAtF,EAAU;OAAY,CAAA,GAC3E,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAW,CAAA,CAC3C;MACT,CAAA,EAAA,CAAA;KACH;;IAGJ+F,KACC,kBAACZ,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD;KAAW,WAAU;KAArB,UAAA,CACE,kBAACI,GAAD,EAAS,MAAM,GAAK,CAAA,GAAC,sBAEZ;IACD,CAAA,EAAA,CAAA,GACZ,kBAACH,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAA8B,UAAA;MAAkB,CAAA,GAC5DS,EAAkB,eAAe,SAAS,IACzC,kBAAC,OAAD;OAAK,WAAU;OACZ,UAAAA,EAAkB,eAAe,KAAK,MACrC,kBAACgB,GAAD;QAAoB,SAAQ;QAAU,WAAU;QAC7C,UAAAC;OACI,GAFKA,CAEL,CACR;MACE,CAAA,IAEL,kBAAC,KAAD;OAAG,WAAU;OAAc,UAAA;MAAa,CAAA,CAEvC,EAAA,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAA8B,UAAA;MAAQ,CAAA,GACnD,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC,OAAD;QACE,WAAU;QACV,OAAO,EAAE,iBAAiBjB,EAAkB,aAAa;OAC1D,CAAA,GACD,kBAAC,QAAD;QAAM,WAAU;QAAqB,UAAAA,EAAkB;OAAmB,CAAA,CACvE;MACF,CAAA,CAAA,EAAA,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAA8B,UAAA;MAAc,CAAA,GACzD,kBAAC,KAAD;OAAG,WAAU;OAAe,UAAAA,EAAkB;MAAc,CAAA,CACzD,EAAA,CAAA;KACF;IACJ,CAAA,GAAAA,EAAkB,eAAe,SAAS,KACzC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;MAAmC,UAAA;KAAkB,CAAA,GAClE,kBAAC,OAAD;MAAK,WAAU;MACZ,UAAAA,EAAkB,eAAe,KAAK,GAAQ,MAC7C,kBAACgB,GAAD;OAAe,SAAQ;OACpB,UAAAE;MACI,GAFKC,CAEL,CACR;KACE,CAAA,CACF;IAEI,CAAA,CAAA,EAAA,CAAA,CACT,EAAA,CAAA;IAIR,kBAAC/B,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;KAAY,WAAU;KAAtB,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UAAW,SAAiB,CAAA,GAC5B,kBAAC8B,GAAD,EAAA,UAAiB,2CAAyD,CAAA,CACvE,EAAA,CAAA,GACL,kBAACjB,GAAD;MAAwB,YAAYC,EAAqB;MACvD,UAAA,kBAAClB,GAAD;OACE,SAAQ;OACR,MAAK;OACL,UAAU,kBAACmB,GAAD,EAAM,MAAM,GAAK,CAAA;OAC3B,eAAe7C,EAAgB,EAAI;OACpC,UAAA;MAEO,CAAA;KACc,CAAA,CACd;IACZ,CAAA,GAAA,kBAAC+B,GAAD,EAAA,UACGM,EAAgB,SAAS,IACxB,kBAAC,OAAD;KAAK,WAAU;KACZ,UAAAA,EAAgB,KACd,MAOC,kBAAC,OAAD;MAEE,WAAU;MAFZ,UAAA,CAIE,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;QACb,UAAA,kBAACpG,GAAD;SAAe,MAAM;SAAI,WAAU;QAAuB,CAAA;OACvD,CAAA,GACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAA4H,EAAoBC,GAAO,cAAc,KAAKA,EAAM;OACpD,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAAb,UAAA,CAA2C,kBAC1BD,EAAoBC,GAAO,SAAS,KAAKA,EAAM,KAC7D;OACA,CAAA,CAAA,EAAA,CAAA,CACF;MACL,CAAA,GAAA,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAACN,GAAD;QAAO,SAAQ;QAAf,UAAA,CAAyB,QAAKM,EAAM,QAAgB;OACpD,CAAA,GAAA,kBAACpC,GAAD;QAAQ,SAAQ;QAAQ,MAAK;QAC3B,UAAA,kBAACqC,IAAD,EAAc,MAAM,GAAK,CAAA;OACnB,CAAA,CACL;MACF,CAAA,CAAA;KAtBE,GAAAD,EAAM,EAsBR,CAET;IACG,CAAA,IAEL,kBAAC1B,IAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,QACE,kBAACO,GAAD;MAAwB,YAAYC,EAAqB;MACvD,UAAA,kBAAClB,GAAD;OAAQ,UAAU,kBAACmB,GAAD,EAAM,MAAM,GAAK,CAAA;OAAG,eAAe7C,EAAgB,EAAI;OAAG,UAAA;MAEpE,CAAA;KACc,CAAA;IAE3B,CAAA,EAEQ,CAAA,CACT,EAAA,CAAA;IAGLvD,EAAU,SAAS,WAAWA,EAAU,oBACvC,kBAACmF,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;KAAW,WAAU;KAArB,UAAA,CACE,kBAACkC,GAAD,EAAO,MAAM,GAAK,CAAA,GAAC,oBAEV;IACX,CAAA,GAAA,kBAACJ,GAAD,EAAA,UAAiB,+EAEA,CAAA,CACP,EAAA,CAAA,GACZ,kBAAC7B,GAAD,EAAA,UAAA,CAEGjD,MACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,QAAD,EAAA,UAAOA,GAAiB,CAAA,GACxB,kBAAC,UAAD;MACE,eAAeC,EAAc,IAAI;MACjC,WAAU;MAEV,UAAA,kBAACsE,GAAD,EAAG,MAAM,GAAK,CAAA;KACR,CAAA,CACL;IAIN,CAAA,GAAA/E,KACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC2F,GAAD;MAAS,MAAM;MAAI,WAAU;KAAgB,CAAA,GAC7C,kBAAC,QAAD;MAAM,WAAU;MAAU,UAAA;KAAiC,CAAA,CACxD;IACH,CAAA,IAAAjG,KACF,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAACiG,GAAD;MAAS,MAAM;MAAI,WAAU;KAAgB,CAAA,GAC7C,kBAAC,QAAD;MAAM,WAAU;MAAU,UAAA;KAA4B,CAAA,CACnD;IACH,CAAA,IAAAlG,KAAmBA,EAAgB,YACrC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MAEE,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA;QACE,kBAACmG,IAAD;SAAc,MAAM;SAAI,WAAU;QAAqC,CAAA;QACvE,kBAAC,OAAD;SAAK,WAAU;SAAf,UAAA;UACE,kBAAC,KAAD;WAAG,WAAU;WACV,UAAAnG,EAAgB,uBACfA,EAAgB,oBAChBA,EAAgB;UACjB,CAAA;UACFA,EAAgB,oBAAoBA,EAAgB,uBACnD,kBAAC,KAAD;WAAG,WAAU;WAAb,UAAA,CAA2C,KACvCA,EAAgB,gBACjB;;UAEJA,EAAgB,eACf,kBAAC,KAAD;WAAG,WAAU;WAAb,UAAA,CAA2C,cAC9B,IAAI,KAAKA,EAAgB,WAAW,CAAC,CAAC,mBAAmB,CACnE;;SAEF;;QACL,kBAAC,OAAD;SAAK,WAAU;SACZ,UAAAA,EAAgB,kBACf,kBAACyF,GAAD;UACE,SAAQ;UACR,WAAU;UACX,UAAA;SAEM,CAAA;QAEN,CAAA;OACF;;MAGL,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACGzF,EAAgB,uBACf,kBAACoG,IAAD;SAAM,MAAM;SAAI,WAAU;QAAgB,CAAA,IAE1C,kBAACC,IAAD;SAAS,MAAM;SAAI,WAAU;QAAuB,CAAA,GAEtD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;SAAsB,UAAA;QAAmB,CAAA,GACtD,kBAAC,KAAD;SAAG,WAAU;SACV,UAAArG,EAAgB,uBACb,6BACA;QACH,CAAA,CACA,EAAA,CAAA,CACF;OACL,CAAA,GAAA,kBAAC2D,GAAD;QACE,SAAQ;QACR,MAAK;QACL,SAASjC;QACT,WAAWhB;QAEV,UAAAV,EAAgB,uBAAuB,YAAY;OAC9C,CAAA,CACL;;MAGL,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACGA,EAAgB,kBACf,kBAAC2D,GAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU,kBAACsC,GAAD,EAAO,MAAM,GAAK,CAAA;QAC5B,SAASzE;QACV,UAAA;OAEO,CAAA,GAEV,kBAACmC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU,kBAAC2C,IAAD,EAAQ,MAAM,GAAK,CAAA;QAC7B,SAAS3E;QACT,WAAWd;QACZ,UAAA;OAEO,CAAA,CACL;;KACF;IAGL,CAAA,IAAA,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,OAAD;OAAK,WAAU;OACb,UAAA,kBAACoF,GAAD;QAAO,MAAM;QAAI,WAAU;OAAuB,CAAA;MAC/C,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAc,UAAA;MAAgC,CAAA,GAC3D,kBAAC,KAAD;OAAG,WAAU;OAAmC,UAAA;MAE7C,CAAA,CACA,EAAA,CAAA;MACL,kBAACtC,GAAD;OAAQ,UAAU,kBAACsC,GAAD,EAAO,MAAM,GAAK,CAAA;OAAG,SAASzE;OAAoB,UAAA;MAE5D,CAAA;KACL;IAEI,CAAA,CAAA,EAAA,CAAA,CACT,EAAA,CAAA;IAIP9C,EAAU,yBACT,kBAACmF,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;KAAW,WAAU;KAArB,UAAA,CACE,kBAACwC,IAAD,EAAQ,MAAM,GAAK,CAAA,GAAC,yBAEX;IACX,CAAA,GAAA,kBAACV,GAAD,EAAA,UAAiB,2DAEA,CAAA,CACP,EAAA,CAAA,GACZ,kBAAC7B,GAAD,EAAA,UACE,kBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,OAAO,QAAQtF,EAAU,qBAAqB,CAAC,CAAC,KAAK,CAAC8H,GAAK5I,OAC1DA,IACE,kBAAC,OAAD;MAAe,WAAU;MAAzB,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OACV,UAAA4I,EAAI,QAAQ,YAAY,EAAE,CAAC,CAAC,QAAQ,YAAY,KAAK;MACrD,CAAA,GACH,kBAAC,KAAD;OAAG,WAAU;OAAgC,UAAA,OAAO5I,CAAK;MAAK,CAAA,CAC3D;KALK,GAAA4I,CAKL,IACH,IACN;IACG,CAAA,EACM,CAAA,CACT,EAAA,CAAA;IAIR,kBAAC3C,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAACC,GAAD;KAAW,WAAU;KAArB,UAAA,CACE,kBAACsB,GAAD,EAAU,MAAM,GAAK,CAAA,GAAC,UAEb;IACD,CAAA,EAAA,CAAA,GACZ,kBAACrB,GAAD,EAAA,UACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAsB,UAAA;MAAU,CAAA,GAC7C,kBAAC,KAAD;OAAG,WAAU;OAAe,UAAAyC,GAAmB/H,EAAU,SAAS;MAAK,CAAA,CACpE,EAAA,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAsB,UAAA;MAAU,CAAA,GAC7C,kBAAC,KAAD;OAAG,WAAU;OAAe,UAAA+H,GAAmB/H,EAAU,SAAS;MAAK,CAAA,CACpE,EAAA,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAsB,UAAA;MAAc,CAAA,GACjD,kBAAC,KAAD;OAAG,WAAU;OAAe,UAAAA,EAAU,oBAAoB;MAAoB,CAAA,CAC3E,EAAA,CAAA;MACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAsB,UAAA;MAAO,CAAA,GAC1C,kBAAC,OAAD;OAAK,WAAU;OACZ,UAAAA,EAAU,KAAK,SAAS,IACvBA,EAAU,KAAK,KAAK,MAClB,kBAAC+G,GAAD;QAAiB,SAAQ;QAAY,WAAU;QAC5C,UAAAiB;OACI,GAFKA,CAEL,CACR,IAED,kBAAC,QAAD;QAAM,WAAU;QAAsB,UAAA;OAAU,CAAA;MAE/C,CAAA,CACF,EAAA,CAAA;KACF;IACM,CAAA,EAAA,CAAA,CACT,EAAA,CAAA;GACH;;CACK,CAAA;AAEhB"}