@burdenoff/microfe-channel 2026.526.1 → 2026.530.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/channel/ChannelRoutes.js +5 -6
  2. package/dist/channel/ChannelRoutes.js.map +1 -1
  3. package/dist/channel/components/AdapterCredentialsForm.js +14 -2
  4. package/dist/channel/components/AdapterCredentialsForm.js.map +1 -1
  5. package/dist/channel/components/FeatureNotEnabled.js +1 -1
  6. package/dist/channel/components/FeatureNotEnabled.js.map +1 -1
  7. package/dist/channel/components/PermissionGuard.js +1 -1
  8. package/dist/channel/components/PermissionGuard.js.map +1 -1
  9. package/dist/channel/config/adapterCredentials.js +19 -11
  10. package/dist/channel/config/adapterCredentials.js.map +1 -1
  11. package/dist/channel/constants/permissions.js +3 -0
  12. package/dist/channel/constants/permissions.js.map +1 -1
  13. package/dist/channel/hooks/useChannelSubscription.js.map +1 -1
  14. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +244 -220
  15. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -1
  16. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +416 -390
  17. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -1
  18. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +30 -15
  19. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
  20. package/dist/channel/modules/channels/pages/ChannelUsersPage.js +8 -2
  21. package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
  22. package/dist/channel/modules/channels/pages/ChannelsListPage.js +241 -213
  23. package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -1
  24. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +107 -98
  25. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
  26. package/dist/channel/modules/channels/pages/ConnectionsListPage.js +160 -140
  27. package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
  28. package/dist/channel/modules/channels/pages/CreateChannelPage.js +47 -50
  29. package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -1
  30. package/dist/channel/modules/channels/pages/CreateConnectionPage.js +16 -5
  31. package/dist/channel/modules/channels/pages/CreateConnectionPage.js.map +1 -1
  32. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +11 -4
  33. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
  34. package/dist/channel/modules/channels/pages/EditChannelPage.js +17 -8
  35. package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
  36. package/dist/channel/modules/channels/pages/EditConnectionPage.js +11 -6
  37. package/dist/channel/modules/channels/pages/EditConnectionPage.js.map +1 -1
  38. package/dist/channel/modules/channels/pages/SendMessagePage.js +21 -9
  39. package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
  40. package/dist/channel/modules/channels/pages/WebhookEventsPage.js +8 -1
  41. package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
  42. package/dist/channel/pages/ChannelLandingPage.js +50 -35
  43. package/dist/channel/pages/ChannelLandingPage.js.map +1 -1
  44. package/dist/channel/providers/ChannelProvider.js +1 -1
  45. package/dist/channel/providers/ChannelProvider.js.map +1 -1
  46. package/package.json +2 -2
  47. package/dist/channel/modules/channels/pages/index.js +0 -14
@@ -1 +1 @@
1
- {"version":3,"file":"useChannelSubscription.js","names":[],"sources":["../../../src/channel/hooks/useChannelSubscription.ts"],"sourcesContent":["/**\n * useChannelSubscription\n *\n * Defensive subscription wrapper. Probes the shell-provided graphql-ws client\n * (`globalThis.__burdenoffShell.graphqlWsClient`); if present, opens a\n * subscription and dispatches each payload to `onData`. If absent — or if the\n * subscription errors with a clear \"unknown field\" / \"not implemented\" signal\n * (the operation isn't on the gateway yet) — silently falls back to a polling\n * loop driven by the caller's `pollFn` at `pollIntervalMs`.\n *\n * Per task 5: backends may grow `webhookReceived`, `connectionStatusChanged`\n * etc. independently; this hook lets the FE wire all four pages without\n * crashing when a subscription isn't yet on the federated schema.\n */\n\nimport { useEffect, useMemo, useRef } from 'react';\nimport { getGraphqlWsClient } from '../utils/shellBridge';\nimport { reportShellError } from '../utils/shellBridge';\n\nexport interface UseChannelSubscriptionArgs<TData> {\n /** GraphQL subscription document (string SDL). */\n query: string;\n /** Variables for the subscription. */\n variables?: Record<string, unknown>;\n /** Stable identifier for this subscription, used in error context. */\n operationName: string;\n /** Called for each payload received from the subscription. */\n onData: (data: TData) => void;\n /** Polling fallback invoked when subscription is unavailable / failed. */\n pollFn: () => Promise<void> | void;\n /** Polling interval in ms (default 15s). */\n pollIntervalMs?: number;\n /** Whether to enable the hook at all. */\n enabled?: boolean;\n}\n\n/** Best-effort detector for \"subscription field not found\" errors. */\nfunction isUnknownFieldError(err: unknown): boolean {\n const msg =\n err instanceof Error\n ? err.message\n : typeof err === 'string'\n ? err\n : ((err as { message?: string } | null)?.message ?? '');\n const lower = msg.toLowerCase();\n return (\n lower.includes('cannot query field') ||\n lower.includes('unknown field') ||\n lower.includes('subscription not supported') ||\n lower.includes('not implemented')\n );\n}\n\nexport function useChannelSubscription<TData = unknown>({\n query,\n variables,\n operationName,\n onData,\n pollFn,\n pollIntervalMs = 15_000,\n enabled = true,\n}: UseChannelSubscriptionArgs<TData>) {\n // Refs to onData / pollFn / variables so we don't re-subscribe on every\n // render. Updates happen inside an effect (not during render) per\n // react-hooks/refs.\n const onDataRef = useRef(onData);\n const pollFnRef = useRef(pollFn);\n const variablesRef = useRef(variables);\n useEffect(() => {\n onDataRef.current = onData;\n pollFnRef.current = pollFn;\n variablesRef.current = variables;\n }, [onData, pollFn, variables]);\n\n // Stable JSON of variables for the dependency array — avoids re-subscribing\n // when callers pass a new object literal each render with the same shape.\n const variablesKey = useMemo(() => JSON.stringify(variables ?? {}), [variables]);\n\n useEffect(() => {\n if (!enabled) return;\n\n const wsClient = getGraphqlWsClient();\n let pollTimer: ReturnType<typeof setInterval> | null = null;\n let unsubSub: (() => void) | null = null;\n let cancelled = false;\n\n const startPolling = () => {\n if (pollTimer) return;\n // Kick once immediately, then on interval.\n void Promise.resolve(pollFnRef.current()).catch(() => {});\n pollTimer = setInterval(() => {\n if (cancelled) return;\n void Promise.resolve(pollFnRef.current()).catch(() => {});\n }, pollIntervalMs);\n };\n\n if (!wsClient) {\n // No graphql-ws on the shell yet — fall back to polling.\n startPolling();\n return () => {\n cancelled = true;\n if (pollTimer) clearInterval(pollTimer);\n };\n }\n\n try {\n unsubSub = wsClient.subscribe(\n { query, variables: variablesRef.current, operationName },\n {\n next: (msg) => {\n if (cancelled) return;\n if (msg?.errors && msg.errors.length > 0) {\n // Probe error: if the field doesn't exist, fall back to polling.\n if (msg.errors.some(isUnknownFieldError)) {\n if (unsubSub) {\n try {\n unsubSub();\n } catch {\n /* noop */\n }\n unsubSub = null;\n }\n startPolling();\n return;\n }\n // Other errors — surface to SRE but keep the subscription open.\n reportShellError(\n new Error(`Subscription ${operationName} returned errors`),\n { module: 'channel', context: { operationName, errors: msg.errors } },\n `[channel] subscription ${operationName} errors`\n );\n return;\n }\n if (msg?.data) {\n try {\n onDataRef.current(msg.data as TData);\n } catch (handlerErr) {\n reportShellError(\n handlerErr,\n { module: 'channel', context: { operationName, phase: 'handler' } },\n `[channel] subscription ${operationName} handler threw`\n );\n }\n }\n },\n error: (err) => {\n // Subscription couldn't be opened (closed/unknown-field/etc).\n if (isUnknownFieldError(err)) {\n startPolling();\n return;\n }\n // Real transport error — log and fall back to polling defensively.\n reportShellError(\n err,\n { module: 'channel', context: { operationName, phase: 'transport' } },\n `[channel] subscription ${operationName} transport error`\n );\n startPolling();\n },\n complete: () => {\n // Server closed the stream cleanly — keep data fresh via polling.\n if (!cancelled) startPolling();\n },\n }\n );\n } catch (err) {\n // Defensive: client.subscribe threw synchronously — fall back.\n reportShellError(\n err,\n { module: 'channel', context: { operationName, phase: 'subscribe' } },\n `[channel] subscription ${operationName} subscribe threw`\n );\n startPolling();\n }\n\n return () => {\n cancelled = true;\n if (unsubSub) {\n try {\n unsubSub();\n } catch {\n /* noop */\n }\n }\n if (pollTimer) clearInterval(pollTimer);\n };\n // Only re-create when key inputs change. variablesKey is the stable\n // JSON projection of variables.\n }, [enabled, query, operationName, variablesKey, pollIntervalMs]);\n}\n\n// Subscription documents — kept inline as strings to avoid coupling codegen\n// to subscriptions that aren't always on the gateway. The defensive hook\n// detects \"unknown field\" responses and falls back to polling automatically.\n\nexport const CHANNEL_HEALTH_CHANGED_SUBSCRIPTION = /* GraphQL */ `\n subscription ChannelHealthChanged($organizationId: ID!) {\n channelHealthChanged(organizationId: $organizationId) {\n channelId\n previousHealth\n newHealth\n changedAt\n reason\n }\n }\n`;\n\nexport const DELIVERY_STATUS_UPDATE_SUBSCRIPTION = /* GraphQL */ `\n subscription OnDeliveryStatusUpdate($notificationId: ID!, $organizationId: ID!) {\n onDeliveryStatusUpdate(notificationId: $notificationId, organizationId: $organizationId) {\n notificationId\n messageId\n status\n timestamp\n }\n }\n`;\n\nexport const WEBHOOK_RECEIVED_SUBSCRIPTION = /* GraphQL */ `\n subscription WebhookReceived($channelId: ID!) {\n webhookReceived(channelId: $channelId) {\n channelId\n organizationId\n webhookEventId\n receivedAt\n platform\n processingStatus\n }\n }\n`;\n\nexport const CONNECTION_STATUS_CHANGED_SUBSCRIPTION = /* GraphQL */ `\n subscription ConnectionStatusChanged($channelId: ID!) {\n connectionStatusChanged(channelId: $channelId) {\n channelId\n organizationId\n connectionId\n isActive\n isHealthy\n changedAt\n reason\n }\n }\n`;\n"],"mappings":";;;AAqCA,SAAS,EAAoB,GAAuB;CAOlD,IAAM,KALJ,aAAe,QACX,EAAI,UACJ,OAAO,KAAQ,WACb,IACE,GAAqC,WAAW,IACxC,aAAa;AAC/B,QACE,EAAM,SAAS,qBAAqB,IACpC,EAAM,SAAS,gBAAgB,IAC/B,EAAM,SAAS,6BAA6B,IAC5C,EAAM,SAAS,kBAAkB;;AAIrC,SAAgB,EAAwC,EACtD,UACA,cACA,kBACA,WACA,WACA,oBAAiB,MACjB,aAAU,MAC0B;CAIpC,IAAM,IAAY,EAAO,EAAO,EAC1B,IAAY,EAAO,EAAO,EAC1B,IAAe,EAAO,EAAU;AAWtC,CAVA,QAAgB;AAGd,EAFA,EAAU,UAAU,GACpB,EAAU,UAAU,GACpB,EAAa,UAAU;IACtB;EAAC;EAAQ;EAAQ;EAAU,CAAC,EAM/B,QAAgB;AACd,MAAI,CAAC,EAAS;EAEd,IAAM,IAAW,GAAoB,EACjC,IAAmD,MACnD,IAAgC,MAChC,IAAY,IAEV,UAAqB;AACrB,GAGJ,OADK,QAAQ,QAAQ,EAAU,SAAS,CAAC,CAAC,YAAY,GAAG,EAC7C,kBAAkB;AACxB,SACC,QAAQ,QAAQ,EAAU,SAAS,CAAC,CAAC,YAAY,GAAG;MACxD,EAAe;;AAGpB,MAAI,CAAC,EAGH,QADA,GAAc,QACD;AAEX,GADA,IAAY,IACR,KAAW,cAAc,EAAU;;AAI3C,MAAI;AACF,OAAW,EAAS,UAClB;IAAE;IAAO,WAAW,EAAa;IAAS;IAAe,EACzD;IACE,OAAO,MAAQ;AACT,aACJ;UAAI,GAAK,UAAU,EAAI,OAAO,SAAS,GAAG;AAExC,WAAI,EAAI,OAAO,KAAK,EAAoB,EAAE;AACxC,YAAI,GAAU;AACZ,aAAI;AACF,aAAU;iBACJ;AAGR,aAAW;;AAEb,WAAc;AACd;;AAGF,SACE,gBAAI,MAAM,gBAAgB,EAAc,kBAAkB,EAC1D;QAAE,QAAQ;QAAW,SAAS;SAAE;SAAe,QAAQ,EAAI;SAAQ;QAAE,EACrE,0BAA0B,EAAc,SACzC;AACD;;AAEF,UAAI,GAAK,KACP,KAAI;AACF,SAAU,QAAQ,EAAI,KAAc;eAC7B,GAAY;AACnB,SACE,GACA;QAAE,QAAQ;QAAW,SAAS;SAAE;SAAe,OAAO;SAAW;QAAE,EACnE,0BAA0B,EAAc,gBACzC;;;;IAIP,QAAQ,MAAQ;AAEd,SAAI,EAAoB,EAAI,EAAE;AAC5B,SAAc;AACd;;AAQF,KALA,EACE,GACA;MAAE,QAAQ;MAAW,SAAS;OAAE;OAAe,OAAO;OAAa;MAAE,EACrE,0BAA0B,EAAc,kBACzC,EACD,GAAc;;IAEhB,gBAAgB;AAEd,KAAK,KAAW,GAAc;;IAEjC,CACF;WACM,GAAK;AAOZ,GALA,EACE,GACA;IAAE,QAAQ;IAAW,SAAS;KAAE;KAAe,OAAO;KAAa;IAAE,EACrE,0BAA0B,EAAc,kBACzC,EACD,GAAc;;AAGhB,eAAa;AAEX,OADA,IAAY,IACR,EACF,KAAI;AACF,OAAU;WACJ;AAIV,GAAI,KAAW,cAAc,EAAU;;IAIxC;EAAC;EAAS;EAAO;EAhHC,QAAc,KAAK,UAAU,KAAa,EAAE,CAAC,EAAE,CAAC,EAAU,CAAC;EAgH/B;EAAe,CAAC;;AAOnE,IAAa,IAAoD,mOAuBpD,IAA8C"}
1
+ {"version":3,"file":"useChannelSubscription.js","names":[],"sources":["../../../src/channel/hooks/useChannelSubscription.ts"],"sourcesContent":["/**\n * useChannelSubscription\n *\n * Defensive subscription wrapper. Probes the shell-provided graphql-ws client\n * (`globalThis.__burdenoffShell.graphqlWsClient`); if present, opens a\n * subscription and dispatches each payload to `onData`. If absent — or if the\n * subscription errors with a clear \"unknown field\" / \"not implemented\" signal\n * (the operation isn't on the gateway yet) — silently falls back to a polling\n * loop driven by the caller's `pollFn` at `pollIntervalMs`.\n *\n * Per task 5: backends may grow `webhookReceived`, `connectionStatusChanged`\n * etc. independently; this hook lets the FE wire all four pages without\n * crashing when a subscription isn't yet on the federated schema.\n */\n\nimport { useEffect, useMemo, useRef } from 'react';\nimport { getGraphqlWsClient } from '../utils/shellBridge';\nimport { reportShellError } from '../utils/shellBridge';\n\nexport interface UseChannelSubscriptionArgs<TData> {\n /** GraphQL subscription document (string SDL). */\n query: string;\n /** Variables for the subscription. */\n variables?: Record<string, unknown>;\n /** Stable identifier for this subscription, used in error context. */\n operationName: string;\n /** Called for each payload received from the subscription. */\n onData: (data: TData) => void;\n /** Polling fallback invoked when subscription is unavailable / failed. */\n pollFn: () => Promise<void> | void;\n /** Polling interval in ms (default 15s). */\n pollIntervalMs?: number;\n /** Whether to enable the hook at all. */\n enabled?: boolean;\n}\n\n/** Best-effort detector for \"subscription field not found\" errors. */\nfunction isUnknownFieldError(err: unknown): boolean {\n const msg =\n err instanceof Error\n ? err.message\n : typeof err === 'string'\n ? err\n : ((err as { message?: string } | null)?.message ?? '');\n const lower = msg.toLowerCase();\n return (\n lower.includes('cannot query field') ||\n lower.includes('unknown field') ||\n lower.includes('subscription not supported') ||\n lower.includes('not implemented')\n );\n}\n\nexport function useChannelSubscription<TData = unknown>({\n query,\n variables,\n operationName,\n onData,\n pollFn,\n pollIntervalMs = 15_000,\n enabled = true,\n}: UseChannelSubscriptionArgs<TData>) {\n // Refs to onData / pollFn / variables so we don't re-subscribe on every\n // render. Updates happen inside an effect (not during render) per\n // react-hooks/refs.\n const onDataRef = useRef(onData);\n const pollFnRef = useRef(pollFn);\n const variablesRef = useRef(variables);\n useEffect(() => {\n onDataRef.current = onData;\n pollFnRef.current = pollFn;\n variablesRef.current = variables;\n }, [onData, pollFn, variables]);\n\n // Stable JSON of variables for the dependency array — avoids re-subscribing\n // when callers pass a new object literal each render with the same shape.\n const variablesKey = useMemo(() => JSON.stringify(variables ?? {}), [variables]);\n\n useEffect(() => {\n if (!enabled) return;\n\n const wsClient = getGraphqlWsClient();\n let pollTimer: ReturnType<typeof setInterval> | null = null;\n let unsubSub: (() => void) | null = null;\n let cancelled = false;\n\n const startPolling = () => {\n if (pollTimer) return;\n // Kick once immediately, then on interval.\n void Promise.resolve(pollFnRef.current()).catch(() => {});\n pollTimer = setInterval(() => {\n if (cancelled) return;\n void Promise.resolve(pollFnRef.current()).catch(() => {});\n }, pollIntervalMs);\n };\n\n if (!wsClient) {\n // No graphql-ws on the shell yet — fall back to polling.\n startPolling();\n return () => {\n cancelled = true;\n if (pollTimer) clearInterval(pollTimer);\n };\n }\n\n try {\n unsubSub = wsClient.subscribe(\n { query, variables: variablesRef.current, operationName },\n {\n next: (msg) => {\n if (cancelled) return;\n if (msg?.errors && msg.errors.length > 0) {\n // Probe error: if the field doesn't exist, fall back to polling.\n if (msg.errors.some(isUnknownFieldError)) {\n if (unsubSub) {\n try {\n unsubSub();\n } catch {\n /* noop */\n }\n unsubSub = null;\n }\n startPolling();\n return;\n }\n // Other errors — surface to SRE but keep the subscription open.\n reportShellError(\n new Error(`Subscription ${operationName} returned errors`),\n { module: 'channel', context: { operationName, errors: msg.errors } },\n `[channel] subscription ${operationName} errors`\n );\n return;\n }\n if (msg?.data) {\n try {\n onDataRef.current(msg.data as TData);\n } catch (handlerErr) {\n reportShellError(\n handlerErr,\n { module: 'channel', context: { operationName, phase: 'handler' } },\n `[channel] subscription ${operationName} handler threw`\n );\n }\n }\n },\n error: (err) => {\n // Subscription couldn't be opened (closed/unknown-field/etc).\n if (isUnknownFieldError(err)) {\n startPolling();\n return;\n }\n // Real transport error — log and fall back to polling defensively.\n reportShellError(\n err,\n { module: 'channel', context: { operationName, phase: 'transport' } },\n `[channel] subscription ${operationName} transport error`\n );\n startPolling();\n },\n complete: () => {\n // Server closed the stream cleanly — keep data fresh via polling.\n if (!cancelled) startPolling();\n },\n }\n );\n } catch (err) {\n // Defensive: client.subscribe threw synchronously — fall back.\n reportShellError(\n err,\n { module: 'channel', context: { operationName, phase: 'subscribe' } },\n `[channel] subscription ${operationName} subscribe threw`\n );\n startPolling();\n }\n\n return () => {\n cancelled = true;\n if (unsubSub) {\n try {\n unsubSub();\n } catch {\n /* noop */\n }\n }\n if (pollTimer) clearInterval(pollTimer);\n };\n // Only re-create when key inputs change. variablesKey is the stable\n // JSON projection of variables.\n }, [enabled, query, operationName, variablesKey, pollIntervalMs]);\n}\n\n// Subscription documents — kept inline as strings to avoid coupling codegen\n// to subscriptions that aren't always on the gateway. The defensive hook\n// detects \"unknown field\" responses and falls back to polling automatically.\n\nexport const CHANNEL_HEALTH_CHANGED_SUBSCRIPTION = /* GraphQL */ `\n subscription ChannelHealthChanged($organizationId: ID!) {\n channelHealthChanged(organizationId: $organizationId) {\n channelId\n previousHealth\n newHealth\n changedAt\n reason\n }\n }\n`;\n\nexport const WEBHOOK_RECEIVED_SUBSCRIPTION = /* GraphQL */ `\n subscription WebhookReceived($channelId: ID!) {\n webhookReceived(channelId: $channelId) {\n channelId\n organizationId\n webhookEventId\n receivedAt\n platform\n processingStatus\n }\n }\n`;\n"],"mappings":";;;AAqCA,SAAS,EAAoB,GAAuB;CAOlD,IAAM,KALJ,aAAe,QACX,EAAI,UACJ,OAAO,KAAQ,WACb,IACE,GAAqC,WAAW,IACxC,aAAa;AAC/B,QACE,EAAM,SAAS,qBAAqB,IACpC,EAAM,SAAS,gBAAgB,IAC/B,EAAM,SAAS,6BAA6B,IAC5C,EAAM,SAAS,kBAAkB;;AAIrC,SAAgB,EAAwC,EACtD,UACA,cACA,kBACA,WACA,WACA,oBAAiB,MACjB,aAAU,MAC0B;CAIpC,IAAM,IAAY,EAAO,EAAO,EAC1B,IAAY,EAAO,EAAO,EAC1B,IAAe,EAAO,EAAU;AAWtC,CAVA,QAAgB;AAGd,EAFA,EAAU,UAAU,GACpB,EAAU,UAAU,GACpB,EAAa,UAAU;IACtB;EAAC;EAAQ;EAAQ;EAAU,CAAC,EAM/B,QAAgB;AACd,MAAI,CAAC,EAAS;EAEd,IAAM,IAAW,GAAoB,EACjC,IAAmD,MACnD,IAAgC,MAChC,IAAY,IAEV,UAAqB;AACrB,GAGJ,OADK,QAAQ,QAAQ,EAAU,SAAS,CAAC,CAAC,YAAY,GAAG,EAC7C,kBAAkB;AACxB,SACC,QAAQ,QAAQ,EAAU,SAAS,CAAC,CAAC,YAAY,GAAG;MACxD,EAAe;;AAGpB,MAAI,CAAC,EAGH,QADA,GAAc,QACD;AAEX,GADA,IAAY,IACR,KAAW,cAAc,EAAU;;AAI3C,MAAI;AACF,OAAW,EAAS,UAClB;IAAE;IAAO,WAAW,EAAa;IAAS;IAAe,EACzD;IACE,OAAO,MAAQ;AACT,aACJ;UAAI,GAAK,UAAU,EAAI,OAAO,SAAS,GAAG;AAExC,WAAI,EAAI,OAAO,KAAK,EAAoB,EAAE;AACxC,YAAI,GAAU;AACZ,aAAI;AACF,aAAU;iBACJ;AAGR,aAAW;;AAEb,WAAc;AACd;;AAGF,SACE,gBAAI,MAAM,gBAAgB,EAAc,kBAAkB,EAC1D;QAAE,QAAQ;QAAW,SAAS;SAAE;SAAe,QAAQ,EAAI;SAAQ;QAAE,EACrE,0BAA0B,EAAc,SACzC;AACD;;AAEF,UAAI,GAAK,KACP,KAAI;AACF,SAAU,QAAQ,EAAI,KAAc;eAC7B,GAAY;AACnB,SACE,GACA;QAAE,QAAQ;QAAW,SAAS;SAAE;SAAe,OAAO;SAAW;QAAE,EACnE,0BAA0B,EAAc,gBACzC;;;;IAIP,QAAQ,MAAQ;AAEd,SAAI,EAAoB,EAAI,EAAE;AAC5B,SAAc;AACd;;AAQF,KALA,EACE,GACA;MAAE,QAAQ;MAAW,SAAS;OAAE;OAAe,OAAO;OAAa;MAAE,EACrE,0BAA0B,EAAc,kBACzC,EACD,GAAc;;IAEhB,gBAAgB;AAEd,KAAK,KAAW,GAAc;;IAEjC,CACF;WACM,GAAK;AAOZ,GALA,EACE,GACA;IAAE,QAAQ;IAAW,SAAS;KAAE;KAAe,OAAO;KAAa;IAAE,EACrE,0BAA0B,EAAc,kBACzC,EACD,GAAc;;AAGhB,eAAa;AAEX,OADA,IAAY,IACR,EACF,KAAI;AACF,OAAU;WACJ;AAIV,GAAI,KAAW,cAAc,EAAU;;IAIxC;EAAC;EAAS;EAAO;EAhHC,QAAc,KAAK,UAAU,KAAa,EAAE,CAAC,EAAE,CAAC,EAAU,CAAC;EAgH/B;EAAe,CAAC;;AAOnE,IAAa,IAAoD,mOAYpD,IAA8C"}